commit c91b3c50068224929cd4d3ddf36c5a10254cbd9c Author: Justine Tunney Date: Mon Jun 15 07:18:57 2020 -0700 Initial import diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..68a1584f --- /dev/null +++ b/.clang-format @@ -0,0 +1,12 @@ +--- +BasedOnStyle: Google +StatementMacros: + - INITIALIZER +AlignConsecutiveMacros: true +AlignConsecutiveDeclarations: false +AlwaysBreakBeforeMultilineStrings: false +AllowShortFunctionsOnASingleLine: false +KeepEmptyLinesAtTheStartOfBlocks: true +--- +Language: Proto +... diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..844d010c --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +/o + +*.tmp +/.bochs.log +/HTAGS +/TAGS +/bx_enh_dbg.ini +/tool/emacs/*.elc diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..c49192ae --- /dev/null +++ b/Makefile @@ -0,0 +1,259 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ +# +# SYNOPSIS +# +# Freestanding Hermetically-Sealed Monolithic Repository +# +# REQUIREMENTS +# +# You can run your programs on any operating system, but you have +# to build them on Linux 2.6+ (or WSL) using GNU Make. A modern C +# compiler that's statically-linked comes included as a courtesy. +# +# EXAMPLES +# +# # build and run everything +# make -j8 -O +# make -j8 -O MODE=dbg +# make -j8 -O MODE=opt +# make -j8 -O MODE=rel +# make -j8 -O MODE=tiny +# +# # build individual target +# make -j8 -O o//examples/hello.com +# o//examples/hello.com +# +# # view source +# less examples/hello.c +# +# # view binary +# o//tool/viz/bing.com o//examples/hello.com | +# o//tool/viz/fold.com +# +# # view transitive closure of legalese +# o//tool/viz/bing.com -n o//examples/hello.com | +# o//tool/viz/fold.com +# +# # basic debugging +# make -j8 -O MODE=dbg o/dbg/examples/crashreport.com +# o/dbg/examples/crashreport.com +# less examples/crashreport.c +# +# # extremely tiny binaries +# make -j8 -O MODE=tiny \ +# LDFLAGS=-s \ +# CPPFLAGS=-DSUPPORT_VECTOR=0b00000001 \ +# o/tiny/examples/hello4.elf +# ls -hal o/tiny/examples/hello4.elf +# o/tiny/examples/hello4.elf +# +# TROUBLESHOOTING +# +# make -j8 -O SILENT=0 o//examples/hello.com +# make o//examples/life.elf -pn |& less +# etc. +# +# SEE ALSO +# +# build/config.mk + +SHELL = dash +HOSTS ?= freebsd openbsd alpine + +.SUFFIXES: +.DELETE_ON_ERROR: +.FEATURES: output-sync +.PHONY: all o bins check test depend tags + +all: o +o: o/libc \ + o/$(MODE)/ape \ + o/$(MODE)/dsp \ + o/$(MODE)/net \ + o/$(MODE)/libc \ + o/$(MODE)/test \ + o/$(MODE)/tool \ + o/$(MODE)/examples \ + o/$(MODE)/third_party + +PKGS = + +include build/functions.mk #─┐ +include build/definitions.mk # ├──meta +include build/config.mk # │ +include build/rules.mk # │ +include build/online.mk # │ +include libc/stubs/stubs.mk #─┘ +include libc/nexgen32e/nexgen32e.mk #─┐ +include libc/intrin/intrin.mk # │ +include libc/math/math.mk # ├──metal +include libc/tinymath/tinymath.mk # │ +include third_party/compiler_rt/compiler_rt.mk # │ +include libc/bits/bits.mk # │ +include libc/str/str.mk # │ +include third_party/xed/xed.mk # │ +include third_party/zlib/zlib.mk # │ +include libc/elf/elf.mk # │ +include ape/lib/apelib.mk # │ +include ape/ape.mk #─┘ +include libc/sysv/sysv.mk #─┐ +include libc/nt/nt.mk # ├──system +include libc/conv/conv.mk # │ +include libc/fmt/fmt.mk # │ +include libc/rand/rand.mk #─┘ +include libc/calls/calls.mk #─┐ +include libc/runtime/runtime.mk # ├──systems +include libc/unicode/unicode.mk # │ +include third_party/dlmalloc/dlmalloc.mk # │ +include libc/mem/mem.mk # │ +include libc/zipos/zipos.mk # │ +include third_party/dtoa/dtoa.mk # │ +include libc/time/time.mk # │ +include libc/escape/escape.mk # │ +include libc/alg/alg.mk # │ +include libc/calls/hefty/hefty.mk # │ +include libc/stdio/stdio.mk # │ +include third_party/f2c/f2c.mk # │ +include third_party/blas/blas.mk # │ +include net/net.mk # │ +include libc/log/log.mk # │ +include dsp/core/core.mk # │ +include libc/x/x.mk # │ +include third_party/stb/stb.mk # │ +include dsp/scale/scale.mk # │ +include dsp/mpeg/mpeg.mk # │ +include dsp/dsp.mk # │ +include third_party/musl/musl.mk # │ +include third_party/getopt/getopt.mk # │ +include libc/libc.mk #─┘ +include libc/sock/sock.mk #─┐ +include dsp/tty/tty.mk # ├──online +include libc/dns/dns.mk # │ +include libc/crypto/crypto.mk # │ +include net/http/http.mk #─┘ +include third_party/linenoise/linenoise.mk +include third_party/editline/editline.mk +include third_party/duktape/duktape.mk +include third_party/regex/regex.mk +include third_party/avir/avir.mk +include third_party/third_party.mk +include libc/testlib/testlib.mk +include libc/crt/crt.mk +include tool/viz/lib/vizlib.mk +include examples/examples.mk +include third_party/lex/lex.mk +include third_party/m4/m4.mk +include third_party/lz4cli/lz4cli.mk +include third_party/bzip2/bzip2.mk +include tool/build/lib/buildlib.mk +include tool/build/build.mk +include tool/debug/debug.mk +include tool/decode/lib/decodelib.mk +include tool/decode/decode.mk +include tool/hash/hash.mk +include tool/net/net.mk +include tool/viz/viz.mk +include tool/cc/cc.mk +include tool/tool.mk +include test/libc/alg/test.mk +include test/libc/tinymath/test.mk +include test/libc/math/test.mk +include test/libc/intrin/test.mk +include test/libc/mem/test.mk +include test/libc/nexgen32e/test.mk +include test/libc/runtime/test.mk +include test/libc/sock/test.mk +include test/libc/bits/test.mk +include test/libc/crypto/test.mk +include test/libc/str/test.mk +include test/libc/unicode/test.mk +include test/libc/calls/test.mk +include test/libc/x/test.mk +include test/libc/xed/test.mk +include test/libc/fmt/test.mk +include test/libc/dns/test.mk +include test/libc/rand/test.mk +include test/libc/time/test.mk +include test/libc/stdio/test.mk +include test/libc/conv/test.mk +include test/libc/test.mk +include test/ape/lib/test.mk +include test/ape/test.mk +include test/net/http/test.mk +include test/net/test.mk +include test/tool/build/lib/test.mk +include test/tool/build/test.mk +include test/tool/viz/lib/test.mk +include test/tool/viz/test.mk +include test/tool/test.mk +include test/test.mk +include test/dsp/core/test.mk +include test/dsp/scale/test.mk +include test/dsp/tty/test.mk +include test/dsp/test.mk + +OBJS = $(foreach x,$(PKGS),$($(x)_OBJS)) +SRCS = $(foreach x,$(PKGS),$($(x)_SRCS)) +HDRS = $(foreach x,$(PKGS),$($(x)_HDRS)) +BINS = $(foreach x,$(PKGS),$($(x)_BINS)) +TESTS = $(foreach x,$(PKGS),$($(x)_TESTS)) +CHECKS = $(foreach x,$(PKGS),$($(x)_CHECKS)) + +bins: $(BINS) +check: $(CHECKS) +test: $(TESTS) +depend: o/$(MODE)/depend +tags: TAGS HTAGS + +o/$(MODE)/.x: + @mkdir -p $(dir $@) && touch $@ + +o/$(MODE)/srcs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(SRCS),$(dir $(x)))) + $(file >$@) $(foreach x,$(SRCS),$(file >>$@,$(x))) + +o/$(MODE)/hdrs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS),$(dir $(x)))) + $(file >$@) $(foreach x,$(HDRS),$(file >>$@,$(x))) + +o/$(MODE)/depend: o/$(MODE)/.x o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt $(SRCS) $(HDRS) + @build/mkdeps -o $@ -r o/$(MODE)/ o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt + +TAGS: o/$(MODE)/srcs.txt $(SRCS) + @rm -f $@ + @ACTION=TAGS TARGET=$@ build/do $(TAGS) $(TAGSFLAGS) -L $< -o $@ + +HTAGS: o/$(MODE)/hdrs.txt $(HDRS) + @rm -f $@ + @ACTION=TAGS TARGET=$@ build/do build/htags -L $< -o $@ + +loc:; find -name \*.h -or -name \*.c -or -name \*.S | \ + $(XARGS) wc -l | grep total | awk '{print $$1}' | summy + +# UNSPECIFIED PREREQUISITES TUTORIAL +# +# A build rule must exist for all files that make needs to consider in +# order to build the requested goal. That includes input source files, +# even if the rule is empty and does nothing. Otherwise, the .DEFAULT +# rule gets triggered. +# +# This is a normal and neecssary behavior when source files get deleted. +# The build reacts automatically to this happening, by simply deleting +# and regenerating the dependency graph; so we can safely use wildcard. +# +# This is abnormal if it needs to keep doing that repeatedly. That can +# only mean the build config is broken. +# +# Also note that a suboptimal in-between state may exist, where running +# `make -pn` reveals rules being generated with the .DEFAULT target, but +# never get executed since they're not members of the transitive closure +# of `make all`. In that case the build config could be improved. +%.mk: +$(SRCS): +$(HDRS): +.DEFAULT: + @echo >&2 + @echo NOTE: deleting o/$(MODE)/depend due to unspecified prerequisite: $@ >&2 + @echo >&2 + rm -f o/$(MODE)/depend + +-include o/$(MODE)/depend diff --git a/NOTICE b/NOTICE new file mode 100644 index 00000000..5b1b10d7 --- /dev/null +++ b/NOTICE @@ -0,0 +1,354 @@ +Cosmopolitan is Free Software licensed under the GPLv2. The build config +**will embed all linked sources inside your binaries** so the compliance +is easy while facilitating trust and transparency similar to JavaScript. +You can audit your source filesystem using ZIP GUIs e.g. WIN10, InfoZip. + +If you want to be able to distribute binaries in binary form only, then +please send $1,000 to jtunney@gmail.com on PayPal for a license lasting +1 year. Please be sure to provide your contact information, and details +on whether or not the license is for an individual or a corporation. If +you want your license to last 5 years, send $10,000 to the author above +who is Justine Tunney . Reach out, for more details. + +──────────────────────────────────────────────────────────────────────── + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/README.md b/README.md new file mode 100644 index 00000000..0c304d87 --- /dev/null +++ b/README.md @@ -0,0 +1,51 @@ +# Cosmopolitan + +Cosmopolitan builds run natively on most platforms without dependencies, +because it implements the subset of the C library, compiler runtimes and +system call interfaces that've achieved near universal consensus amongst +all major platforms, e.g. Linux/BSD/XNU/NT. Containerization is achieved +by having binaries also be ZIP files. Modern static stock GNU toolchains +are provided in a hermetic mono repo for maximum historical determinism. + +Here's how you can get started by printing cat videos inside a terminal: + + make -j8 o//tool/viz/printvideo.com + wget https://justine.storage.googleapis.com/cats.mpg + o//tool/viz/printvideo.com cats.mpg + unzip -vl o//tool/viz/printvideo.com + +Cosmopolitan provides a native development environment similar to those +currently being offered by RedHat, Google, Apple, Microsoft, etc. We're +different in two ways: (1) we're not a platform therefore we don't have +any commercial interest in making our tooling work better on one rather +than another; and (2) we're only focused on catering towards interfaces +all platforms agree upon. Goal is software that stands the test of time +without the costs and restrictions cross-platform distribution entails. +That makes Cosmopolitan an excellent fit for writing small CLI programs +that do things like heavyweight numerical computations as a subprocess. + +## Licensing + +Cosmopolitan is Free Software licensed under the GPLv2. The build config +**will embed all linked sources inside your binaries** so the compliance +is easy while facilitating trust and transparency similar to JavaScript. +You can audit your source filesystem using ZIP GUIs e.g. WIN10, InfoZip. + +### Commercial Support + +If you want to be able to distribute binaries in binary form only, then +please send $1,000 to jtunney@gmail.com on PayPal for a license lasting +1 year. Please be sure to provide your contact information, and details +on whether or not the license is for an individual or a corporation. If +you want your license to last 5 years, send $10,000 to the author above +who is Justine Tunney . This README will be updated, +if pricing and other details should change. Reach out for more details. + +## Contributing + +We'd love to accept your patches! Before we can take them, we have to +jump through one legal hurdle. Please write an email to Justine Tunney + saying you agree to give her copyright ownership to +any changes you contribute to Cosmopolitan. We need to do that in order +to dual license Cosmopolitan. Otherwise we can't tax corporations that +don't want to share their code with the community. diff --git a/ape/ape.S b/ape/ape.S new file mode 100644 index 00000000..3a27df99 --- /dev/null +++ b/ape/ape.S @@ -0,0 +1,1935 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╠──────────────────────────────────────────────────────────────────────────────╣ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█▀█░▀█▀░█░█░█▀█░█░░░█░░░█░█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█░▄░░█░░█░█░█▀█░█░░░█░░░▀█▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░▀░▀░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀░░▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█▀█░█▀█░▀█▀░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀▀░█ █░██▀░░█░░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░▀░░░▀▀▀░▀░▀░░▀░░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀▀░█░█░█▀▀░█▀█░█░█░▀█▀░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░▄▄░░░▐█░░│ +│░░░░░░░█▀▀░▄▀▄░█▀▀░█░▄░█░█░░█░░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░▄▄▄░░░▄██▄░░█▀░░░█░▄░│ +│░░░░░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░▀░░▀░▀░▀▀▀░▀▀░▀▀▀░░░░░░░░░░▄██▀█▌░██▄▄░░▐█▀▄░▐█▀░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▐█▀▀▌░░░▄▀▌░▌░█░▌░░▌░▌░░│ +╠──────────────────────────────────────────────────────▌▀▄─▐──▀▄─▐▄─▐▄▐▄─▐▄─▐▄─│ +│ αcτµαlly pδrταblε εxεcµταblε § program header │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/config.h" +#include "ape/lib/apm.h" +#include "ape/lib/pc.h" +#include "ape/macros.h" +#include "ape/notice.inc" +#include "ape/relocations.h" +#include "libc/elf/def.h" +#include "libc/macho.h" +#include "libc/nexgen32e/uart.h" +#include "libc/nexgen32e/vidya.h" +#include "libc/nt/pedef.h" +#include "libc/sysv/consts/prot.h" +.yoink __FILE__ +.yoink "NOTICE" +.section .head,"ax",@progbits + +/ Common Sections. + .section .text,"ax",@progbits + .align __SIZEOF_POINTER__ + .previous + .section .rodata,"a",@progbits + .align __SIZEOF_POINTER__ +__ro: .endobj __ro,globl,hidden # ←for gdb readibility + .previous + .section .data,"aw",@progbits + .align __SIZEOF_POINTER__ + .previous + .section .bss,"aw",@nobits + .align __SIZEOF_POINTER__ + .previous + .section .rodata.str1.1,"aMS",@progbits +cstr: .endobj cstr,globl,hidden # ←for gdb readibility + .previous + .section .sort.rodata.real.str1.1,"aMS",@progbits +rlstr: .endobj rlstr,globl,hidden # ←for gdb readibility + .previous + +/* ████████ ████████ ███████████ + ██░░░░▒▒██ ██░░░░▒▒██ ████░░░░░░░░░▒▒████ + ██░░░░░░██ ██░░░░▒▒██ ██░░░░▒▒███████░░░░▒▒██ + ██░░░░░░▒▒██ ░██░░░░░░▒▒██ ██░░▒▒██ ██░░▒▒██ + ██░░▒▒░░░░██ ░██░░░░░░▒▒██ ██░░▒▒██ ████████ + ██░░▒▒▒▒░░▒▒██ ██▓░░░░▒▒░░▒▒██ ██░░▒▒▒▒███████ + ██░░▒▒██░░░░██ ██▓░░░░██░░▒▒██ ████░░░░░░░▒▒████ + ██░░▒▒████░░▒▒██░░░░░████░░▒▒██ ███████░░░░▒▒██ + ██░░▒▒████░░░░██░░░░░████░░▒▒██ ██████ ██░░░░▒▒██ + ██░░▒▒██ ██░░▒▒░░▒██ ██░░▒▒██ ██░░░░██ ██░░▒▒██ + ██░░▒▒██ ██░░░░░░▒██ ██░░▒▒██ ██░░░░█████████░░░░▒▒██ + ██░░▒▒██ ▓▓▒▒░░▒▒▒▓▓ ██░░▒▒██ ▓▓▒▒░░▓▓▓▓▓▓▓▓▓░░░░▓▓▓▓ + ██░░▒▒██ ██░░██▓ ██░░▒▒██ ██░░░░░░░░░░░░░▒▒██ + ████████████████████▓ ██████████████ ███████████████ + ██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█████▓▓░░▓▓░░▓▓░░████░░░░░░░░░░░░░░░████ + ██▓▓▓▓▓▓▓▓▓▓▓▓▓▓█████▓▓░░▓▓░░▓▓░░████░░░░░░░░░░░░░░░░░░░░░██ + ██▓▓▓▓▓▓▓▓▓▓▓▓▓▓██▓▓▒░░▓▓░░▓▓░░▓▓██░░░░░░░░░░░░░░░░░░░░░░░░░██ + ██▓▓▓▓▓▓██████████░░▒▓▓▓▓██████▓▓██░░░░░░███████████▓▓░░░░▓▓██ + ██▓▓▓▓▓▓████████░░▓▓▓▓▓██▓▓▓▓██████░░░░████░░▒▓▓██ ██▓▓▓▓▓▓██ + ██▓▓▓▓▓▓████████▓▓░░▒████▓▓▓▓██████░░░░██▓▓▓▓▒░░██ ██████ + ██▓▓▓▓▓▓██ ██░░▓▓▓▓▓██▓▓▓▓██ ██▓▓░░████░░▒▓▓██████ + ██▓▓▓▓▓▓██ ██▓▓░░▒████▓▓▓▓██ ██▓▓██▓▓▓▓▒░░██░░░░████ + ██▓▓▓▓▓▓██ ██░░▓▓▓▓▓██▓▓▓▓██ ██████░░▒▓▓██░░░░░░░░██ + ██▓▓▓▓▓▓██ ██▓▓░░▒████▓▓▓▓██ ██▓▓▓▓▒░░██▓▓░░░░░░░░██ + ██▓▓▓▓▓▓██ ██░░▓▓▓████▓▓▓▓██ ████████░░▒▓▓████▓▓░░░░░░██ + ██▓▓▓▓▓▓██ ██░░▒██▓▓▓▓████ ██░░░░░░██▓▓███ ██░░░░░░██ + ██▓▓▓▓▓▓█████████████▓▓▓▓██████████▓▓░░░░░░█████████░░░░░░░░██ + ██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓████▓▓░░██▓▓░░░░░░░░░░░░░░░░░░░░░▓▓██ + ██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓████▓▓░░▓▓██▓▓▓▓░░░░░░░░░░░░░░░░░▓▓▓▓██ + ██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓████▓▓░░▓▓░░▓▓██▓▓▓▓▓▓░░░░░░░░░░░▓▓▓▓▓▓██ + ██▓▓█████████████████████▓▓██▓▓██▓▓████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓██ + ███████████████████████████▓▓██▓▓██▓▓████▓▓▓▓▓▓▓▓▓▓▓▓▓████ + ██████████████████▓ ██████████████ █████████████ +╔──────────────────────────────────────────────────────────────────────────────╗ +│ αcτµαlly pδrταblε εxεcµταblε § the old technology │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +/ MZ Literally Executable Header +/ +/ This is the beginning of the program file and it can serve as an +/ entrypoint too. It shouldn't matter if the program is running on +/ Linux, Windows, etc. Please note if the underlying machine isn't +/ a machine, this header may need to morph itself to say the magic +/ words, e.g. ⌂ELF, which also works fine as a generic entrypoint. +/ +/ @see www.delorie.com/djgpp/doc/exe/ +/ @noreturn +ape.mz: .ascii "MZ" # Mark 'Zibo' Joseph Zbikowski + jno 2f # MZ: bytes on last page + jo 2f # MZ: 512-byte pages in file + .ascii "='" # MZ: reloc table entry count + .ascii "\n\0" # MZ: data segment file offset / 16 + .short 0x1000 # MZ: lowers upper bound load / 16 + .short 0xf800 # MZ: roll greed on bss + .short 0 # MZ: lower bound on stack segment + .short 0 # MZ: initialize stack pointer + .short 0 # MZ: ∑bₙ checksum don't bother + .short 0x0100 # MZ: initial ip value + .short 0x0800 # MZ: increases cs load lower bound + .short 0x0040 # MZ: reloc table offset + .short 0 # MZ: overlay number + .org 0x24 # MZ: bytes reserved for you + .ascii "JT" # MZ: OEM identifier + .short 0 # MZ: OEM information + .org 0x40-4 # MZ: bytes reserved for you + .long RVA(ape.pe) # PE: the new technology + .endobj ape.mz,globl,hidden + +/ Disk Operating System Stub +/ @noreturn + .org 0x40 # mz/elf header length +stub: mov $0x40,%dl # *literally* dos + jmp 1f # good bios skips here +1: jmp pc + nop # system five bootpoint + .org 0x48,0x90 # ⌂ELF → JNLE 47 + jmp 3f +2: push %rdx # don't move or shell script breaks + xor %edx,%edx # Z in MZ ate BIOS drive letter :( +3: .byte 0xbd,0,0 # mov $0x????0000,%[e]bp + jmp pc + jmp ape.hop # already in userspace + .endfn stub + +/ Mitigate incidental quotation marks. + .real +ape.hop:pop %rdx + push %r10 # MZ → pop %r10 w/ NexGen32e + .weak __imp_GetStartupInfoW + ezlea __imp_GetStartupInfoW,ax + test %rax,%rax + jz 0f + .weak KernelBase.GetStartupInfo + test %rax,%rax +/ TODO(jart) +/ cmpq $RVA(KernelBase.GetStartupInfo),(%rax) + jz 0f + jmp WinMain +0: .weak _start + jmp _start + .endfn ape.hop + .previous + +/*─────────────────────────────────────────────────────────────────────────────╗ +│ αcτµαlly pδrταblε εxεcµταblε § ibm personal computer │ +╚──────────────────────────────────────────────────────────────────────────────┘ + IBM designed BIOS to run programs by handing over the computer + to a program as soon as its first sector is loaded. That gives + us control over user-facing latency, even though the next step + will generally be asking the BIOS to load more. + + The process is trivial enough that this entrypoint can support + handoffs from alternative program-loaders e.g. Grub and MS-DOS + so long as they either load our full program, or implement the + PC BIOS disk service API. + + Since so many different implementations of these APIs have been + built the last forty years these routines also canonicalize the + cpu and program state, as it is written in the System V ABI. */ + +/ Initializes program and jumps to long mode loader. +/ +/ @param dl drive number (use 0x40 to skip bios disk load) +/ @mode real +/ @noreturn + .code16 +pc: cld + mov $REAL_STACK_FRAME>>4,%di # we need a stack + xor %cx,%cx + rlstack %di,%cx + movpp %cs,%ax # memcpy() [relocate this page] + call 1f +1: pop %si + sub $RVA(1b),%si + mov $4,%cl +1: shr %si + loop 1b + mov $512,%cx + mov $IMAGE_BASE_REAL>>4,%di + mov %si,%ds + mov %di,%es + xor %si,%si + xor %di,%di + rep + movsb %ds:(%si),%es:(%di) + ljmp $0,$REAL(1f) # longjmp() +1: mov $-512,%cx # memcpy() [relocate this frame] + rep + movsb %ds:(%si),%es:(%di) + xor %bp,%bp + mov %bp,%ds # %ds and %cs are now zero + call 1f # setup frame pointers +1: push %bp + mov %sp,%bp + mov $XLM_SIZE,%cx # memset() [clear real bss] + mov $XLM_BASE_REAL>>4,%ax + mov %ax,%es + xor %ax,%ax + xor %di,%di + rep + stosb %al,%es:(%di) + cmp $0x40,%dl # statfs() [disk geometry] + je 6f + call dsknfo + mov $IMAGE_BASE_REAL>>4,%ax + mov %ax,%es + mov $v_ape_realsectors,%di # total sectors to read + xor %dh,%dh # current head state + xor %cx,%cx # current cylinder state +3: mov %di,%ax + call pcread + mov %es,%si +4: add $512>>4,%si + dec %di + jz 6f + dec %ax + jnz 4b + mov %si,%es + jmp 3b +6: mov %cx,XLM(LOADSTATE)+0 + mov %dx,XLM(LOADSTATE)+2 + ljmp $0,$REAL(realmodeloader) + .endfn pc,globl,hidden + +/ Be gentler on Unix line buffer impls. + .byte 0x0a + +/ Determines disk geometry. +/ +/ We use imperial measurements for storage systems so the software +/ can have an understanding of physical locality, which deeply +/ impacts the latency of operations. +/ +/ - 160KB: 1 head × 40 cylinders × 8 sectors × 512 = 163,840 +/ - 180KB: 1 head × 40 cylinders × 9 sectors × 512 = 184,320 +/ - 320KB: 2 heads × 40 cylinders × 8 sectors × 512 = 327,680 +/ - 360KB: 2 heads × 40 cylinders × 9 sectors × 512 = 368,640 +/ - 720KB: 2 heads × 80 cylinders × 9 sectors × 512 = 737,280 +/ - 1.2MB: 2 heads × 80 cylinders × 15 sectors × 512 = 1,228,800 +/ - 1.44MB: 2 heads × 80 cylinders × 18 sectors × 512 = 1,474,560 +/ +/ Terminology +/ +/ - Cylinder / Tracks should mean the same thing +/ - Heads / Sides / Spindles should mean the same thing +/ +/ Disk Base Table +/ +/ 0: specify byte 1, step-rate time, head unload time +/ 1: specify byte 2, head load time, DMA mode +/ 2: timer ticks to wait before disk motor shutoff +/ 3: bytes per sector code +/ 0: 128 bytes 2: 512 bytes +/ 1: 256 bytes 3: 1024 bytes +/ 4: sectors per track (last sector number) +/ 5: inter-block gap length/gap between sectors +/ 6: data length, if sector length not specified +/ 7: gap length between sectors for format +/ 8: fill byte for formatted sectors +/ 9: head settle time in milliseconds +/ 10: motor startup time in eighths of a second +/ +/ @param dl drive number +/ @return dl = pc_drive (corrected if clobbered by header) +/ pc_drive +/ pc_drive_type +/ pc_drive_heads +/ pc_drive_last_cylinder +/ pc_drive_last_sector +/ @clob ax, cx, dx, di, si, es, flags +/ @since IBM Personal Computer XT +dsknfo: push %bx +1: push %dx + mov $0x08,%ah # get disk params + int $0x13 + jc 9f + mov %cl,%bh + and $0b00111111,%bh + and $0b11000000,%cl + rol %cl + rol %cl + xchg %cl,%ch + push %ds # disk base table in es:di + movpp %es,%ds + xor %si,%si + mov %si,%es + mov $XLM(DRIVE_BASE_TABLE),%si + xchg %si,%di + movsw #→ headunloadtime, headloadtime + movsw #→ shutofftime, bytespersector + movsw #→ sectorspertrack, sectorgap + movsw #→ datalength, formatgap + movsw #→ formatfill, settletime + movsb #→ startuptime + pop %ds + xchg %bx,%ax + stosw #→ pc_drive_type, pc_drive_last_sector + xchg %cx,%ax + stosw #→ pc_drive_last_cylinder + xchg %dx,%ax + stosw #→ pc_drives_attached, pc_drive_last_head + pop %ax + stosb #→ pc_drive + xchg %ax,%dx + pop %bx + ret +9: pop %dx +8: xor $0x80,%dl # try cycling drive a/c + xor %ax,%ax # reset disk + int $0x13 + jc 8b + jmp 1b + .endfn dsknfo + +/ Reads disk sectors via BIOS. +/ +/ Each call to this function performs a single read. It has a +/ special ABI, where its parameters are preserved, and rolled +/ forward accordingly across calls. BIOS requirements on read +/ parameter validity are abstracted. If the requested size is +/ too large for one read, then it's tuned down appropriately. +/ +/ Please note that dskinfo() must be called beforehand. +/ +/ @param ax number sectors to read +/ @param es destination memory address >> 4 +/ @param cx cylinder number +/ @param dh head number +/ @param dl drive number +/ @return number of sectors actually read +pcread: push %bx + xor %bx,%bx + mov XLM(DRIVE_LAST_SECTOR),%bl + cmp %ax,%bx # ax = min(ax, pertrack) + ja 1f + mov %bx,%ax +1: push %cx # how many sectors until 64k + push %ax # boundary reads can't cross + mov $0x1000,%bx # canonicalizing the segment + mov %es,%ax # register is not sufficient + sub %ax,%bx + and $0x0fff,%bx + mov $5,%cx +0: shr %bx + loop 0b + pop %ax + pop %cx + test %bx,%bx # %es 64k-aligned edge case + jz 1f + cmp %ax,%bx # ax = min(ax, remain64k) + ja 1f + mov %bx,%ax +1: push %ax # setup int-13-2() params + push %cx + xchg %cl,%ch + ror %cl + ror %cl + or $1,%cl # one cylinder at a time + xor %bx,%bx # es:bx is destination addr + mov $0x02,%ah # read disk sectors ordinal + int $0x13 + pop %cx + pop %bx + jc 9f + mov $0,%ah + cmp %ax,%bx + jl 9f + inc %cx + cmp XLM(DRIVE_LAST_CYLINDER),%cx + jle 2f + xor %cx,%cx + inc %dh +2: pop %bx + ret +9: push %ax + xor %ax,%ax # try disk reset on error + int $0x13 + pop %ax + jmp 1b + .endfn pcread + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ αcτµαlly pδrταblε εxεcµταblε § partition table ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +/ Partition Table. +.Lape.mbrpad: + .org 0x1b4 + .endobj .Lape.mbrpad +ape_disk: + .stub .Lape.diskid,quad + .org 0x1be,0x00 + .macro .partn x + .stub .Lape.part\x\().status,byte # 0=absent / 0x80=present + .stub .Lape.part\x\().first.head,byte # in low 6 bits + .stub .Lape.part\x\().first.cylinder,byte + .stub .Lape.part\x\().first.sector,byte + .stub .Lape.part\x\().filesystem,byte + .stub .Lape.part\x\().last.head,byte + .stub .Lape.part\x\().last.cylinder,byte + .stub .Lape.part\x\().last.sector,byte + .stub .Lape.part\x\().lba,long # c₀*Cₙ + h₀*Hₙ + s₀*Sₙ + .stub .Lape.part\x\().sector.count,long # sectors are 512 bytes + .endm + .partn 1 + .partn 2 + .partn 3 + .partn 4 + .org 0x1fe + .short BOOTSIG + .endobj ape_disk + +/* ▄▄▄ + ▄▄▄ ▀▓▓▒▄ + ▄▓▒▒░ ▀▓▒▒▒▄ + ▄▓▓▓▒▀ ▄▄▄▄ ▒▓▒▒░▒▄ + ▄▓▓▓▒▓ ▄▄▓██▓▓▓▓▒▒▒▒▓▓▄▄▓▓▒▒▒░░▒ + ▓▓▓▓▒▒▒▄▄ ░▒█▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▓▒░░▒░ + ██▓▓▓▒▒░░▒▒▒▒▓▓▓▓▓▓▒▓▒░▒▒░▀▒▒▒▒░▀░▒▒▒░▒ + ▓▓▓▓▓▓▓▒▒▒▒▒▒▓▓▒▓▓▒▒▒░▒▒░░ ░▒▒░ ░▒▒▒▒ + ▀▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░▒░░ ░▒▒ ░ ▀▒▒ + ▀▓▓█▓▓▓▓▓▓▓▓▓▓▒▒░░▒▒░░ ░░░▓░ ▓░░░▒ + ▀▀█▓███▓▓▓▓▓▒▒░░░▒░░ ░█▓░█▓░█▓▓▄▒░ + ░▓██▓▓▓▓▓▒▒░░░▒░░ ░████▓▒▓█▓▀░▀▄ + ░▓██▓▓▓▓▓▒▒▒░░░▒░░ ▒██▓▒▒▒▒▒▒░░░▒ + ████▓▓▓▓▓▒▒▒▒▒▒▒▒▒░░▒▓▓▒░░░░▒░░░▒░ ░░░░░ + ░▓███▓▓▓▓▓▒▒░░░░░░░▒▒▒▒▒▒▒▒▒▒▒░░░ ░░░░░ ░ + ▓███▓▓▓▓▓▒▓▒▒▒▒░░░░░░░░░▒▓▒▒░▀ ░░░ ░░░░░ + ▀▒██▓▓▓▓▒▒▒▓▓▓▓▒▒▒▒▒▒▒▓▀▀░ ░░░░░░░░░ ░ + ▓▓▓▓▓▓▓▒▓▒▒▒▒▓▓▓▒▀░ ░░░░░▄░░░ ░░░ ░░░░░░ + ▓▓▓▒▒▒▒▒▒▒▒▒▒▒▓ █▓▒░░▒░░░░ ░░░░░░░░ + ▄▓▓▓▒▒▒▒▒░░░░░░░▒▄▄▄░▒▓▓▒▒░▀░ + ░▓█▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▒░░░▒ besiyata + ▓▓█▓▓▒▓▓▓▒▒▒░░░░░░▒▓▓▓▓▒▒▒▒▒░ dishmaya + ▓▓█▓▓▓▓▓▓▒▒▒░░░░░░░▒▓▓▒▀▀▀ + ▓▓██▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▀ + █▓▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀ + ▒▓▓▓▓▀░░▒▓▓▓▓▓▓▓▓▒▒░░▒ + ▄▓▓▀░░░▄▓▓▓▓▒▒▒▒▒░░░░▄░ + ▄███▄▄▓▓▓▓▓▓▓▒▒▒▒▒░░▒▒░ + ▄▓▓▓█▓█▓▓███▓▓▓▓▓▓▓▓▓▓▓░ + ▄░▓▓▓▓▓▓▀▒▓▓▓▒▒▓▒░░░▒▓▒░░░▓ + ▄▄▄░▒▓▓▓▓▓▓░▀▀ ▓▓▒░▓▒▒▒▒▒▒▒▒▒▒▄░░▀▀░░ ▄▄▄▄ + ▄▄▄▒▒▓▓█▓▓▓▓▓▀▀▀▀▀ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▀░░▀░░▒▒▒░░░ ░░░░░ + ▄▓▓▓▒▀▀ ▓▒▓▓▓▓▓▒▒▒▒▒▒▒▒▓░░░ ▒▒▒░░░░░░░░▒ + █▓▓▒ ▄▄▄ ▀▓▒▓▒▒▒▓▓▓▓▓▓▒▒▒░░░░░░░░░▒▒░░░░░░░ + ▀▓▓▓▓▒▄▄▒▒▒▒▒▒▄▄ ▀▀▀▀░░▒▒▒▒░░░░░░ + ▀▀▀▓▓▓▓▒▒▒▒▒▓▓▄▄ +╔────────────────────────────────────────────────────────────────────────────│─╗ +│ αcτµαlly pδrταblε εxεcµταblε § bell system five ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + the bourne executable & linkable format */ + +apesh: .ascii "'\n#'\"\n" # sixth edition shebang + .ascii "o=\"$(command -v \"$0\")\"\n" + .ascii "set -- \"$o\" \"$@\"\n" + .ascii "if [ -d /Applications ]; then\n" + .ascii "dd if=\"$o\"" + .ascii " of=\"$o\"" + .ascii " bs=8" + .ascii " skip=\"" + .shstub .Lape.macho.dd.skip,2 + .ascii "\" count=\"" + .shstub .Lape.macho.dd.count,2 + .ascii "\" conv=notrunc 2>/dev/null\n" + .ascii "elif exec 7<> \"$o\"; then\n" + .ascii "printf '" + .ascii "\\177ELF" # 0x0: ⌂ELF + .ascii "\\2" # 4: long mode + .ascii "\\1" # 5: little endian + .ascii "\\1" # 6: elf v1.o + .ascii "\\011" # 7: FreeBSD + .ascii "\\0" # 8: os/abi ver. + .ascii "\\0\\0\\0" # 9: padding 3/7 + .ascii "\\0\\0\\0\\0" # padding 4/7 + .ascii "\\2\\0" # 10: εxεcµταblε + .ascii "\\076\\0" # 12: NexGen32e + .ascii "\\1\\0\\0\\0" # 14: elf v1.o + .shstub .Lape.elf.entry,8 # 18: e_entry + .shstub .Lape.elf.phoff,8 # 20: e_phoff + .shstub .Lape.elf.shoff,8 # 28: e_shoff + .ascii "\\0\\0\\0\\0" # 30: e_flags + .ascii "\\100\\0" # 34: e_ehsize + .ascii "\\070\\0" # 36: e_phentsize + .shstub .Lape.elf.phnum,2 # 38: e_phnum + .ascii "\\0\\0" # 3a: e_shentsize + .shstub .Lape.elf.shnum,2 # 3c: e_shnum + .shstub .Lape.elf.shstrndx,2 # 3e: e_shstrndx + .ascii "' >&7\n" + .ascii "exec 7<&-\n" + .ascii "fi\n" + .ascii "exec \"$@\"\n" # etxtbsy tail recursion + .ascii "R=$?\n" # architecture optimistic + .ascii "if [ $R -eq 126 ] && [ \"$(uname -m)\" != x86_64 ]; then\n" + .ascii "if Q=\"$(command -v qemu-x86_64)\"; then\n" + .ascii "exec \"$Q\" \"$@\"\n" + .ascii "else\n" + .ascii "echo error: need qemu-x86_64 >&2\n" + .ascii "fi\n" + .ascii "fi\n" + .ascii "exit $R\n" + .endobj apesh + + .section .elf.phdrs,"a",@progbits + .align __SIZEOF_POINTER__ + .type ape.phdrs,@object + .globl ape.phdrs +ape.phdrs: + .long PT_LOAD # text segment + .long PF_R|PF_X + .stub .Lape.rom.offset,quad + .stub .Lape.rom.vaddr,quad + .stub .Lape.rom.paddr,quad + .stub .Lape.rom.filesz,quad + .stub .Lape.rom.memsz,quad + .stub .Lape.rom.align,quad + .align __SIZEOF_POINTER__ + .long PT_LOAD # data segment + .long PF_R|PF_W + .stub .Lape.ram.offset,quad + .stub .Lape.ram.vaddr,quad + .stub .Lape.ram.paddr,quad + .stub .Lape.ram.filesz,quad + .stub .Lape.ram.memsz,quad + .stub .Lape.ram.align,quad +/ Linux ignores mprotect() and returns 0 without this lool +/ It has nothing to do with the stack, which is still exec + .align __SIZEOF_POINTER__ + .long PT_GNU_STACK # p_type + .long PF_R|PF_W # p_flags + .quad 0 # p_offset + .quad 0 # p_vaddr + .quad 0 # p_paddr + .quad 0 # p_filesz + .quad 0 # p_memsz + .quad 16 # p_align + .align __SIZEOF_POINTER__ + .long PT_NOTE # openbsd note + .long PF_R + .stub .Lape.note.offset,quad + .stub .Lape.note.vaddr,quad + .stub .Lape.note.paddr,quad + .stub .Lape.note.filesz,quad + .stub .Lape.note.memsz,quad + .stub .Lape.note.align,quad + .previous + + .section .note.openbsd.ident,"a",@progbits +.Lopenbsd.ident: + .long 8 + .long 4 + .long 0x1 + .asciz "OpenBSD" + .long 0 + .size .Lopenbsd.ident,.-.Lopenbsd.ident + .type .Lopenbsd.ident,@object + .previous + +/* ▄▄███▄ + ▄▄████████▄ + ▄█████████████▄ + ▄▄███▓▓▓▓▓▓▓▓▓▓▓███▄ + ▄▄█████▓▓▓█████████▓▓▓██▄ + ▄▄████████▓▓▓███████▓▓▓▓▓████▄ + ▄█████░░░████▓▓█████▓▓▓▓█████████▄ + ▄▄█████████░░░███▓▓█▓▓▓▓▒███████▓▓▒███▄ + ▄██████████████░░░██▓▓▓▓███████████▓▓█████▄ + ██████████████████░░░██▓▓▓█████████▓▓▓███████▄ + ███░░░░░░█████████▓░░███▓▓▓▓▓▓▓▓▓▓▓█████▒▒▒██▄ + █░███░░░██░░░░░░░░░██░░██████████████▒▒▒▒██████▄ + ███████░░░█████████░░░░░░█████████▒▒▒▒▒██████████▄ + █████ ██░░░███████████████████▒▒▒▒▒██░▒▒██████████▄ + ██████ ██░░░██████████████░███▒████████▒▒██████████▄ + ████████ ███░░█████████████░░████████████▒▒███████████ + █████████ ███░░███████████░░██████████████▒▒███████████ + ▄██████████ ██████████████ ░░███████████████▒▒███████████ + ████████████ ███░░░░░█████░░█████████████████▒▒██████ █ + █████████████ ██████░░░░░░░▒█████████████████████ ████▀ + █████████████ ██████████░░░░░░░░░███████████ ████████ + █████████████ ████████░░███████░░░██████ ▓██████████ + █████████████ ██████░░░████████████ █████████████ +╔────────────────────────────────────────────────────────────────────────────│─╗ +│ αcτµαlly pδrταblε εxεcµταblε § nexstep carnegie melon mach object format ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + @note hey xnu before we get upx'd email feedback jtunney@gmail.com + @see OS X ABI Mach-O File Format Reference, Apple Inc. 2009-02-04 + @see System V Application Binary Interface NexGen32e Architecture + Processor Supplement, Version 1.0, December 5th, 2018 */ + +.section .macho,"a",@progbits +.align __SIZEOF_POINTER__ + +ape.macho: + .long 0xFEEDFACE+1 + .long MAC_CPU_NEXGEN32E + .long MAC_CPU_NEXGEN32E_ALL + .long MAC_EXECUTE + .long 5 # number of load commands + .long 60f-10f # size of all load commands + .long MAC_NOUNDEFS # flags + .long 0 # reserved +10: .long MAC_LC_SEGMENT_64 + .long 20f-10b # unmaps first page dir + .ascin "__PAGEZERO",16 # consistent with linux + .quad 0,0x200000,0,0 # which forbids mem <2m + .long 0,0,0,0 +20: .long MAC_LC_SEGMENT_64 + .long 30f-20b + .ascin "__TEXT",16 + .stub .Lape.rom.vaddr,quad + .stub .Lape.rom.memsz,quad + .stub .Lape.rom.offset,quad + .stub .Lape.rom.filesz,quad + .long PROT_EXEC|PROT_READ|PROT_WRITE # maxprot + .long PROT_EXEC|PROT_READ # initprot + .long 1 # segment section count + .long 0 # flags +210: .ascin "__text",16 # section name (.text) + .ascin "__TEXT",16 + .stub .Lape.text.vaddr,quad + .stub .Lape.text.memsz,quad + .stub .Lape.text.offset,long + .long 12 # align 2**12 = 4096 + .long 0 # reloc table offset + .long 0 # relocation count + .long MAC_S_ATTR_SOME_INSTRUCTIONS # section type & attributes + .long 0,0,0 # reserved +30: .long MAC_LC_SEGMENT_64 + .long 40f-30b + .ascin "__DATA",16 + .stub .Lape.ram.vaddr,quad + .stub .Lape.ram.memsz,quad + .stub .Lape.ram.offset,quad + .stub .Lape.ram.filesz,quad + .long PROT_EXEC|PROT_READ|PROT_WRITE # maxprot + .long PROT_READ|PROT_WRITE # initprot + .long 2 # segment section count + .long 0 # flags +310: .ascin "__data",16 # section name (.data) + .ascin "__DATA",16 + .stub .Lape.data.vaddr,quad + .stub .Lape.data.memsz,quad + .stub .Lape.data.offset,long + .long 12 # align 2**12 = 4096 + .long 0 # reloc table offset + .long 0 # relocation count + .long 0 # section type & attributes + .long 0,0,0 # reserved +320: .ascin "__bss",16 # section name (.bss) + .ascin "__DATA",16 + .stub .Lape.bss.vaddr,quad # virtual address + .stub .Lape.bss.memsz,quad # memory size + .long 0 # file offset + .long 12 # align 2**12 = 4096 + .long 0 # reloc table offset + .long 0 # relocation count + .long MAC_S_ZEROFILL # section type & attributes + .long 0,0,0 # reserved +40: .long MAC_LC_UUID + .long 50f-40b + .stub uuid1_,quad + .stub uuid2_,quad +50: .long MAC_LC_UNIXTHREAD + .long 60f-50b # cmdsize + .long MAC_THREAD_NEXGEN32E # flavaflav + .long (520f-510f)/4 # count +510: .quad 0 # rax + .quad IMAGE_BASE_VIRTUAL # rbx + .quad 0 # rcx + .quad 0 # rdx + .quad 0 # rdi + .quad 0 # rsi + .quad 0 # rbp + .quad 0 # rsp + .quad 0 # r8 + .quad 0 # r9 + .quad 0 # r10 + .quad 0 # r11 + .quad 0 # r12 + .quad 0 # r13 + .quad 0 # r14 + .quad 0 # r15 + .quad _start_xnu # rip + .quad 0 # rflags + .quad 0 # cs + .quad 0 # fs + .quad 0 # gs +520: +60: + +.endobj ape.macho,globl,hidden +.previous /* .macho */ + +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔─────────────────────────────────────────────────────────────────▀▀▀────────│─╗ +│ αcτµαlly pδrταblε εxεcµταblε § the new technology ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + The Portable Executable Format + + @see https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format + @see "The Portable Executable File Format from Top to Bottom", + Randy Kath, Microsoft Developer Network Technology Group. */ + +/ ┌14:Uniprocessor Machine ┌─────────────────────────┐ +/ │┌13:DLL │ PE File Characteristics │ +/ ││┌12:System ├─────────────────────────┤ +/ │││┌11:If Net Run From Swap │ r │ reserved │ +/ ││││┌10:If Removable Run From Swap │ d │ deprecated │ +/ │││││┌9:Debug Stripped │ D │ deprecated with │ +/ ││││││┌8:32bit Machine │ │ extreme prejudice │ +/ │││││││ ┌5:Large Address Aware └───┴─────────────────────┘ +/ │││││││ │ ┌1:Executable +/ │││││││ │ │┌0:Relocs Stripped +/ d│││││││dr│Ddd││ +.LPEEXE = 0b0000001000100011 + +/ ┌15:TERMINAL_SERVER_AWARE ┌─────────────────────────┐ +/ │┌14:GUARD_CF │ PE DLL Characteristics │ +/ ││┌13:WDM_DRIVER ├─────────────────────────┤ +/ │││┌12:APPCONTAINER │ r │ reserved │ +/ ││││┌11:NO_BIND └───┴─────────────────────┘ +/ │││││┌10:NO_SEH +/ ││││││┌9:NO_ISOLATION +/ │││││││┌8:NX_COMPAT +/ ││││││││┌7:FORCE_INTEGRITY +/ │││││││││┌6:DYNAMIC_BASE +/ ││││││││││┌5:HIGH_ENTROPY_VA +/ │││││││││││rrrrr +.LDLLSTD = 0b0000000100100000 +.LDLLPIE = 0b0000000001000000 +.LDLLEXE = .LDLLSTD + +/ ┌31:Writeable ┌─────────────────────────┐ +/ │┌30:Readable │ PE Section Flags │ +/ ││┌29:Executable ├─────────────────────────┤ +/ │││┌28:Shareable │ o │ for object files │ +/ ││││┌27:Unpageable │ r │ reserved │ +/ │││││┌26:Uncacheable └───┴─────────────────────┘ +/ ││││││┌25:Discardable +/ │││││││┌24:Contains Extended Relocations +/ ││││││││ ┌15:Contains Global Pointer (GP) Relative Data +/ ││││││││ │ ┌7:Contains Uninitialized Data +/ ││││││││ │ │┌6:Contains Initialized Data +/ ││││││││ o │ ││┌5:Contains Code +/ ││││││││┌┴─┐rrrr│ ooror│││rorrr +.LPETEXT = 0b01110000000000000000000001100000 +.LPEDATA = 0b11000000000000000000000011000000 +.LPEIMPS = 0b11000000000000000000000001000000 + + .section .pe.header,"a",@progbits + .align __SIZEOF_POINTER__ +ape.pe: .ascin "PE",4 + .short kNtImageFileMachineNexgen32e + .stub .Lape.pe.shnum,short # NumberOfSections + .long 0x5c64126b # TimeDateStamp + .long 0 # PointerToSymbolTable + .long 0 # NumberOfSymbols + .stub .Lape.pe.optsz,short # SizeOfOptionalHeader + .short .LPEEXE # Characteristics + .short kNtPe64bit # Optional Header Magic + .byte 14 # MajorLinkerVersion + .byte 15 # MinorLinkerVersion + .long 0 # SizeOfCode + .long 0 # SizeOfInitializedData + .long 0 # SizeOfUninitializedData + .long RVA(WinMain) # EntryPoint + .long 0 # BaseOfCode + .quad IMAGE_BASE_VIRTUAL # ImageBase + .long 4096 # SectionAlignment + .long 4096 # FileAlignment + .short 6 # MajorOperatingSystemVersion + .short 0 # MinorOperatingSystemVersion + .short 0 # MajorImageVersion + .short 0 # MinorImageVersion + .short 6 # MajorSubsystemVersion + .short 0 # MinorSubsystemVersion + .long 0 # Win32VersionValue + .long RVA(_end) # SizeOfImage + .long RVA(_ehead) # SizeOfHeaders + .long 0 # Checksum + .short v_ntsubsystem # Subsystem: 0=Neutral,2=GUI,3=Console + .short .LDLLEXE # DllCharacteristics + .quad 0x0000000000100000 # StackReserve + .quad 0x0000000000030000 # StackCommit (64kb [goog] + arg + env) + .quad 0x0000000000080000 # HeapReserve + .quad 0x0000000000001000 # HeapCommit (we make our own heap) + .long 0x00000000 # LoaderFlags + .long 16 # NumberOfDirectoryEntries + .long 0,0 # ExportsDirectory + .long RVA(idata.idt) # ImportsDirectory + .stub .Lidata.idtsize,long # ImportsDirectorySize + .long 0,0 # ResourcesDirectory + .long 0,0 # ExceptionsDirectory + .long 0,0 # SecurityDirectory + .long 0,0 # BaseRelocationTable + .long 0,0 # DebugDirectory + .long 0,0 # DescriptionString + .long 0,0 # MachineSpecific + .long 0,0 # ThreadLocalStorage + .long 0,0 # LoadConfigurationDirectory + .long 0,0 # BoundImportDirectory + .long RVA(idata.iat) # ImportAddressDirectory + .stub .Lidata.iatsize,long # ImportAddressDirectorySize + .long 0,0 # DelayImportDescriptor + .long 0,0 # ComPlusRuntimeHeader + .long 0,0 # Reserved + .endobj ape.pe,globl + .previous + + .section .pe.sections,"a",@progbits + .ascin ".text",8 # Section Name + .stub .Lape.text.memsz,long # Virtual Size or Physical Address + .stub .Lape.text.rva,long # Relative Virtual Address + .stub .Lape.text.filesz,long # Physical Size + .stub .Lape.text.offset,long # Physical Offset + .long 0x00000000 # Relocation Table Offset + .long 0x00000000 # Line Number Table Offset + .short 0x0000 # Relocation Count + .short 0x0000 # Line Number Count + .long .LPETEXT # Flags + .previous + + .section .pe.sections,"a",@progbits + .ascin ".data",8 # Section Name + .stub .Lape.ram.memsz,long # Virtual Size or Physical Address + .stub .Lape.ram.rva,long # Relative Virtual Address + .stub .Lape.ram.filesz,long # Physical Size + .stub .Lape.ram.offset,long # Physical Offset + .long 0x00000000 # Relocation Table Offset + .long 0x00000000 # Line Number Table Offset + .short 0x0000 # Relocation Count + .short 0x0000 # Line Number Count + .long .LPEDATA # Flags + .previous + + .section .idata.ro.idt.1,"a",@progbits + .type idata.idtend,@object + .type idata.idt,@object + .globl idata.idt,idata.idtend + .hidden idata.idt,idata.idtend +idata.idt: + .previous/* + ... + decentralized content + ... + */.section .idata.ro.idt.3,"a",@progbits + .long 0,0,0,0,0 +idata.idtend: + .previous + + .section .piro.data.sort.iat.1,"aw",@progbits + .type idata.iatend,@object + .type idata.iat,@object + .globl idata.iat,idata.iatend + .hidden idata.iat,idata.iatend +idata.iat: + .previous/* + ... + decentralized content + ... + */.section .piro.data.sort.iat.3,"aw",@progbits +idata.iatend: + .previous + +/*─────────────────────────────────────────────────────────────────────────────╗ +│ αcτµαlly pδrταblε εxεcµταblε § early-stage read-only data │ +╚──────────────────────────────────────────────────────────────────────────────╝ + better code/data separation (.head is rwx[real] rx[long]) */ + +/ NUL-Terminated Strings. +ape.str: +.Lstr.ape: + .byte 0xe0,0x63,0xe7,0xe6,0xe0,0x6c,0x6c,0x79 #αcτµαlly + .byte 0x20,0x70,0xeb,0x72,0xe7,0xe0,0x62,0x6c # pδrταbl + .byte 0xee,0x20,0xee,0x78,0xee,0x63,0xe6,0xe7 #ε εxεcµτ + .byte 0xe0,0x62,0x6c,0xee,0x0d,0x0a,0x00 #αblε. + .endobj .Lstr.ape +.Lstr.error: + .asciz "error: " + .endobj .Lstr.error +.Lstr.crlf: + .asciz "\r\n" + .endobj .Lstr.crlf +.Lstr.cpuid: + .asciz "cpuid" + .endobj .Lstr.cpuid +.Lstr.oldskool: + .asciz "oldskool" + .endobj .Lstr.oldskool +.Lstr.dsknfo: + .asciz "dsknfo" + .endobj .Lstr.dsknfo +.Lstr.e820: + .asciz "e820" + .endobj .Lstr.e820 +.Lstr.memory: + .asciz "nomem" + .endobj .Lstr.memory +.Lstr.long: + .asciz "nolong" + .endobj .Lstr.long +.Lstr.hello: + .asciz "hello\n" + .endobj .Lstr.hello + .endobj ape.str + +/ Serial Line Configuration (8250 UART 16550) +/ If it's hacked, it'll at least get hacked very slowly. +sconf: .short 1843200/*hz*/ / 16/*wut*/ / 9600/*baud*/ +/ +/ ┌interrupt trigger level {1,4,8,14} +/ │ ┌enable 64 byte fifo (UART 16750+) +/ │ │ ┌select dma mode +/ │ │ │┌clear transmit fifo +/ │ │ ││┌clear receive fifo +/ ├┐│ │││┌enable fifos + .byte 0b00000000 +/ +/ ┌dlab: flips configuration mode state +/ │┌enable break signal +/ ││ ┌parity {none,odd,even,high,low} +/ ││ │ ┌extra stop bit +/ ││ │ │┌data word length (bits+5) +/ ││┌┴┐│├┐ + .byte 0b01000011 + .endobj sconf,global,hidden + +/ Global Descriptor Table +/ +/ @note address portion only concern legacy modes + .align 8 +gdt: .short 2f-1f # table byte length + .long REAL(1f),0 # table address + .align 8 +1: +/ ┌G:granularity (1 → limit *= 0x1000) +/ │┌D/B:default operation size (0 = 16|64bit, 1 = 32-bit) +/ ││┌L:long mode +/ │││┌AVL:this bit is thine (1<<52) +/ ││││ ┌P:present +/ ││││ │┌DPL:privilege +/ ││││ ││ ┌─────────data/code(1) +/ ││││ ││ │┌────data(0)──────code(1) +/ ││││ ││ ││┌───conforming───expand-down +/ ││││ ││ │││┌──writeable────readable +/ ││││ ││ ││││┌─accessed─────accessed +/ ││││ ││ │││││ +/ ││││ ┌──││─│││││───────────────────────────────┐ +/ ┌───││││─│──││─│││││───────────┐ │ +/ ┌───┴──┐││││┌┴─┐│├┐│││││┌──────────┴───────────┐┌──────┴───────┐ +/ │ ││││││ ││││││││││ base address││ segment limit│ +/ │ ││││││ ││││││││││ 32 bits││ 20 bits│ +/ │ ││││││ ││││││││││ ││ │ +/ 6666555555555544444444443333333333222222222211111111110000000000 +/ 3210987654321098765432109876543210987654321098765432109876543210 +/ │ ││││││ ││││││││││ ││ │ +.quad 0b0000000000000000000000000000000000000000000000000000000000000000 # 0 +.quad 0b0000000000001111100110100000000000000000000000001111111111111111 # 8 +.quad 0b0000000000001111100100100000000000000000000000001111111111111111 #16 +.quad 0b0000000011001111100110100000000000000000000000001111111111111111 #24 +.quad 0b0000000011001111100100100000000000000000000000001111111111111111 #32 +.quad 0b0000000010101111100110110000000000000000000000001111111111111111 #40 +.quad 0b0000000010101111100100110000000000000000000000001111111111111111 #48 +2: .endobj gdt,global,hidden + +/*─────────────────────────────────────────────────────────────────────────────╗ +│ αcτµαlly pδrταblε εxεcµταblε § multiboot stub │ +╚──────────────────────────────────────────────────────────────────────────────╝ + boot modernized for the nineties */ + +#define GRUB_MAGIC 0x1BADB002 +#define GRUB_EAX 0x2BADB002 +#define GRUB_AOUT (1 << 16) +#define GRUB_CHECKSUM(FLAGS) (-(GRUB_MAGIC + (FLAGS)) & 0xffffffff) + +/ Grub Header. + .align 4 +ape.grub: + .long GRUB_MAGIC # Magic + .long GRUB_AOUT # Flags + .long GRUB_CHECKSUM(GRUB_AOUT) # Checksum + .long RVA(ape.grub) # HeaderPhysicalAddress + .long IMAGE_BASE_PHYSICAL # TextPhysicalAddress + .long PHYSICAL(_edata) # LoadEndPhysicalAddress + .long PHYSICAL(_end) # BssEndPhysicalAddress + .long RVA(ape.grub.entry) # EntryPhysicalAddress + .endobj ape.grub,globl,hidden + +/ Grub Entrypoint. +/ Takes CPU out of legacy mode and jumps to normal entrypoint. +/ @noreturn + .align 4 +ape.grub.entry: + .code32 + cmp $GRUB_EAX,%eax + jne triplf + push $0 + popf + mov $0x40,%dl + mov %cr0,%eax + and $~CR0_PE,%eax + mov %eax,%cr0 + ljmpw $0,$REAL(pc) + .code16 + .endfn ape.grub.entry + +/*─────────────────────────────────────────────────────────────────────────────╗ +│ αcτµαlly pδrταblε εxεcµταblε § real mode │ +╚──────────────────────────────────────────────────────────────────────────────╝ + the default mode of operation on modern cpus */ + + nop + nop + nop + nop +realmodeloader: + push %bp + mov %sp,%bp + call rlinit + call sinit4 + mov $VIDYA_MODE,%di + mov %es,XLM(VIDEO_POSITION_FAR_POINTER) + mov %ax,XLM(VIDEO_POSITION_FAR_POINTER)+2 + call vinit + mov $REAL(.Lstr.ape),%di + call rvputs + .optfn _start16 + call _start16 + call longmodeloader + .endfn realmodeloader,globl,hidden + + .section .sort.text.real.init.1,"ax",@progbits + .type rrinit,@function +rlinit: push %bp + mov %sp,%bp + .previous/* + ... + decentralized function + ... + */.section .sort.text.real.init.3,"ax",@progbits + pop %bp + ret + .previous + +/ Initializes present PC serial lines. +sinit4: push %bp + mov %sp,%bp + movw $4,%cx + movw $kBiosDataAreaXlm+COM1,%si +0: lodsb + mov %al,%dl + lodsb + mov %al,%dh + test %dx,%dx + jz 1f + push %cx + push %si + mov %dx,%di + movw $REAL(sconf),%si + call sinit + pop %si + pop %cx +1: loop 0b + pop %bp + ret + .endfn sinit4,global,hidden + +/ Initializes Serial Line Communications 8250 UART 16550A +/ +/ @param word di tty port +/ @param char (*{es:,e,r}si)[4] register initial values +/ @mode long,legacy,real +/ @see www.lammertbies.nl/comm/info/serial-uart.html +sinit: push %bp + mov %sp,%bp + mov %di,%dx + test %dx,%dx + jz 2f + push %dx + push %si + xorw %cx,%cx + mov $UART_LCR,%cl + add %cx,%dx + lodsb %ds:(%si),%al + pop %si + or $UART_DLAB,%al + out %al,%dx + pop %dx +1: lodsb %ds:(%si),%al + out %al,%dx + add $1,%dx + sub $1,%cx + jns 1b +2: pop %bp + ret + .endfn sinit,global,hidden + +/ Abnormally exits program. +/ +/ @param di message +/ @mode real +/ @noreturn +rldie: push %bp + mov %sp,%bp + call rlpute + call rloff + .endfn rldie,globl,hidden + +/ Shuts down machine. +/ +/ @mode real +/ @noreturn +rloff: push %bp + mov %sp,%bp + mov $kBiosDataAreaXlm+COM1,%di + mov $4,%si + call sflush + call apmoff + .endfn rloff,globl,hidden + +/ Prints error message. +/ +/ @param di message +/ @mode real +rlpute: push %bp + mov %sp,%bp + mov kBiosDataAreaXlm+METAL_STDERR(%bx),%si + test %si,%si + jnz 1f + mov kBiosDataAreaXlm+METAL_STDOUT,%si +1: xor %ax,%ax + push %ax + push %si + mov $REAL(.Lstr.crlf),%ax + push %ax + push %si + push %di + push %si + mov $REAL(.Lstr.error),%ax + push %ax +1: pop %di + test %di,%di + jz 2f + pop %si + call rlput2 + jmp 1b +2: pop %bp + ret + .endfn rlpute,globl,hidden + +/ Prints string to both video and serial. +/ +/ @param di NUL-terminated string +/ @param si serial port +/ @mode real +rlput2: push %bp + mov %sp,%bp + push %di + push %si + call rvputs + pop %si + pop %di + test %si,%si + jz 1f + call sputs +1: pop %bp + ret + .endfn rlput2,globl,hidden + +/ Video put string. +/ +/ @param di is the string +/ @mode real +rvputs: push %bp + mov %sp,%bp + mov %di,%si + les XLM(VIDEO_POSITION_FAR_POINTER),%di + call vputs + mov %es,XLM(VIDEO_POSITION_FAR_POINTER) + mov %ax,XLM(VIDEO_POSITION_FAR_POINTER)+2 + pop %bp + ret + .endfn rvputs,globl,hidden + +/ Writes string to serial line. +/ +/ @param di NUL-terminated string +/ @param si serial port +/ @mode long,legacy,real +sputs: push %bp + mov %sp,%bp + push %bx + mov %di,%bx +1: xchg %bx,%si + lodsb + xchg %bx,%si + test %al,%al + jz 2f + mov %ax,%di + push %si + rlcall sputc + pop %si + jmp 1b +2: pop %bx + pop %bp + ret + .endfn sputs,globl + +/ Waits for serial lines to become idle. +/ +/ @param di short array of serial ports (0 means not present) +/ @param si number of items in array +/ @mode long,legacy,real +sflush: mov %si,%cx + mov %di,%si + xor %dx,%dx +0: lodsb + mov %al,%dl + lodsb + mov %al,%dh + test %ax,%ax + jz 2f + add $UART_LSR,%dx + mov $UART_TTYIDL,%ah +1: in %dx,%al + and %ah,%al + rep nop # todo(jart): interrupts are better + jz 1b + loop 0b +2: ret + .endfn sflush,globl + +/ Transmits byte over serial line. +/ +/ This is both blocking and asynchronous. +/ +/ @param di character to send +/ @param si serial port +/ @mode long,legacy,real +/ @see ttytxr +sputc: push %ax + push %cx + push %dx + mov %si,%dx + add $UART_LSR,%dx + mov $UART_TTYTXR,%ah +1: in %dx,%al + and %ah,%al + jnz 2f + rep nop # todo(jart): interrupts are better + jmp 1b +2: mov %di,%ax + mov %si,%dx + out %al,%dx + pop %dx + pop %cx + pop %ax + ret + .endfn sputc,globl + +/ Asks BIOS to initialize MDA/CGA display w/o cursor/blinking. +/ +/ @param dil video mode +/ @return es:ax start of video page +/ @mode real +vinit: push %bp + mov %sp,%bp + push %bx + bbmov VIDYA_ADDR_CGA>>4,%ax,%ah,%al + mov %ax,%es + mov %di,%ax + cmp $VIDYA_MODE_CGA,%al + je 1f + xor %ch,%ch # aka movesdi VIDYA_ADDR_MDA +1: xor %di,%di + bbmov VIDYA_SET_MODE,%ax,%ah,%al + int $VIDYA_SERVICE + bbmov VIDYA_SET_CURSOR,,%ah,%al + bbmov VIDYA_SET_CURSOR_NONE,,%ch,%cl # since we don't support it + int $VIDYA_SERVICE + bbmov VIDYA_SET_BLINKING,,%ah,%al # ← cargo culting (ega?) + bbmov VIDYA_SET_BLINKING_NONE,,%bh,%bl + int $VIDYA_SERVICE + xor %ax,%ax + pop %bx + pop %bp + ret + .endfn vinit,globl + +/ Prints byte to display w/ teletype emulation. +/ +/ @param es:di screen position +/ @param sil byte +/ @return es:ax new screen position +/ @mode long,legacy,real +vputc: push %bp + mov %sp,%bp + sub $16,%sp # goal is to turn sil into a buffer + xchg %si,%ax # modrm sooo different in real mode + mov %di,%cx + mov %sp,%si + mov %sp,%di + stosb + mov %cx,%di + pushpop 1,%dx + jmp 23f + +/ Prints string to display w/ teletype emulation. +/ +/ @param es:di screen position +/ @param si NUL-terminated string +/ @return es:ax new screen position +/ @mode long,legacy,real +vputs: push %si # inlined strlen +1: lodsb + test %al,%al + jnz 1b + mov %si,%dx + pop %si + sub %si,%dx +/ fallthrough + +/ Prints data to display w/ teletype emulation. +/ +/ @param es:di screen position +/ @param si data address +/ @param dx data size in bytes +/ @return es:ax new screen position +/ @mode long,legacy,real +vtput: push %bp + mov %sp,%bp +23: push %bx + mov %dx,%cx + mov %di,%dx + bband VIDYA_REWIND,%dh,%dl + bbadd VIDYA_SIZE,%dh,%dl + bbmov VIDYA_COLUMNS*2,%bx,%bh,%bl +0: cmp %di,%dx + je 6f + ja 3f + lodsb # todo: utf8 → cp437 + cmp $'\n,%al + je 4f + cmp $'\r,%al + je 5f +1: stosb + mov $VIDYA_ATTR_NORMAL,%al # todo: ansi color + stosb +2: loop 0b +3: mov %di,%ax + pop %bx + pop %bp + ret +4: add %bx,%di # line feed + jmp 2b +5: mov %di,%ax # carriage return + push %dx + xor %dx,%dx + idiv %bx # todo: division is deprecated + sub %dx,%di + pop %dx + jmp 2b +6: push %ax + push %cx + push %dx + push %si + mov %bx,%si + rlcall vscroll + mov %ax,%di + pop %si + pop %dx + pop %cx + pop %ax + jmp 2b + .endfn vtput,globl + .endfn vputs,globl + .endfn vputc,globl + +/ Scrolls up content in display page. +/ +/ @param es:di cursor address (bytes after aren't moved) +/ @param si byte difference, e.g. VIDYA_COLUMNS*2 +/ @return es:ax new cursor address (which is es:di-si) +/ @mode long,legacy,real +vscroll:not %dx + mov %di,%cx + bband VIDYA_REWIND,%ch,%cl + xchg %cx,%di # di is now page addr, i.e. top-left + sub %si,%cx # cx is now future cursor address + push %cx + sub %di,%cx # cx is now memcpy size + mov %di,%si + add %cx,%si + mov $0,%ax + movpp %ds,%es + rep movsb + pop %ax + ret + .endfn vscroll,globl + +/ Shuts down personal computer. +/ +/ @mode real +/ @noreturn +apmoff: push %bp + mov %sp,%bp + mov $0x5300,%ax # apm installation check + xor %bx,%bx # for the apm bios itself + int $APM_SERVICE + jc 1f + cmp $'P<<8|'M,%bx # did apm bios service interrupt? + jne 1f + mov $0x5301,%ax # real mode interface connect + xor %bx,%bx # to apm bios device + int $APM_SERVICE # ignore errors e.g. already connected + xor %bx,%bx + xor %cx,%cx + mov $0x5307,%ax # set power state + mov $1,%bl # for all devices within my dominion + mov $3,%cl # to off + int $APM_SERVICE +1: call panic + .endfn apmoff,globl + +/* █ █▒ + █ █ + █▓▄ █ █ + ▒▓ ░█░ ░▒▓▓███░ █▒ + ▒▓ ▒▓███▓▒░ ░▓ + █ ▓░ + ▄██░ █ + ▓▓ ▓██░ ▓█░▓█ ▒▓ + ▒█ ░█ █ ░▓ █ █ + █░ █ ░▓ ▀▒ █░ █ + █▒ ▀▒░ ▓▓ + ▄▄▄▓████▓▓▒░ █ ▄▄▄▄▓▓▓█▓▓▓▓▒░ ▒█ + ▄▓▓▀ ▒ ░█ ▄▓▀ ░███▒ + ▓▀ ░░ ▀▓▄▄▄▒▒ █ + █ ░░█▒ ▒█ ▒▓ █ + ▀█ ▄▄▄▄▄▄▄▄▄▄ ▀▀░▓██▓ █ + ▀■▄▄▄■▀ ▀▀█▄ █ + ▀▀█▄ █ + ▀█▄ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ + █▌ █ +╔──────────────────────────────────────────────────────────────────────────▀─│─╗ +│ αcτµαlly pδrταblε εxεcµταblε § long mode loader ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + long mode is long */ + +longmodeloader: + push %bp + mov %sp,%bp + call lcheck + call a20 + mov $XLM(E820),%di + mov $XLM_E820_SIZE,%si + call e820 + jc 9f + call unreal + call hiload + call golong +9: mov $REAL(.Lstr.e820),%ax + call rldie + .endfn longmodeloader,globl,hidden + +/ Long Mode Hardware Check +lcheck: push %bp + mov %sp,%bp + pushfw # check for i8086 / i8088 / i80186 + pop %ax + and $0b111<<12,%ax # see intel manual volume 1 §19.1.2 + jnz 9f + pushfl # now check for later model of 80486 + pop %eax # test ability to *change* cpuid bit + mov %eax,%ecx + mov $1<<21,%ebx + xor %ebx,%eax + push %eax + popfl + pushfl + pop %eax + cmp %eax,%ecx + je 12f + and %ebx,%eax # puts cpuid bit in the on position + push %eax + popfl + mov $0x80000000,%edi # get amd ext cpuid thingy length + mov %edi,%eax + inc %edi + cpuid # clobbers eax, ebx, ecx, and edx + cmp %edi,%eax + jl 10f + mov %edi,%eax + cpuid + mov $1<<29/*LM*/,%edi # check for nexgen32e support + and %edi,%edx + cmp %edi,%edx + jne 10f + xor %ax,%ax +1: pop %bp + ret +9: mov $REAL(.Lstr.oldskool),%ax + jmp 20f +10: mov $REAL(.Lstr.long),%ax + jmp 20f +12: mov $REAL(.Lstr.cpuid),%ax + jmp 20f +20: call rldie + .endfn lcheck + +/ Gets memory map from BIOS. +/ +/ @param di paragraph aligned buffer +/ @param si bytes in buffer to fill +/ @return number of bytes written or CF on error +/ @mode real +e820: push %bp + mov %sp,%bp + pushl $'S<<24|'M<<16|'A<<8|'P # magic @ -4(%bp) + push %bx + shr $4,%di + mov %di,%es + xor %edi,%edi # es:di is destination buffer + xor %ebx,%ebx # ebx is an api state tracker +1: mov $0xE820,%eax # magic + mov $8+8+4+4,%ecx # sizeof(struct SmapEntry) + mov -4(%bp),%edx # magic + int $0x15 # ax,bx,cx,dx,di → ax,bx,cx + jc 9f # cf = unsupported or abuse + cmp -4(%bp),%eax # more magic means success + jne 9f + test %cx,%cx # discard empty results + jz 5f + cmp $8+8+4+1,%cx # discard if ignore flag + jb 4f + testb $1/*ignore*/,8+8+4/*SmapEntry::__acpi3*/(%di) + jnz 5f +4: add $8+8+4+4,%di # keep entry +5: test %ebx,%ebx # last entry? + jz 7f + cmp %si,%di # out of buf? + jb 1b +7: mov %di,%ax +8: pop %bx + leave + ret +9: stc + jmp 8b + .endfn e820,globl,hidden + +/ Unreal Mode. +/ Makes 4gb of real memory accessible via %fs segment. +unreal: push %bp + mov %sp,%bp + cli + lgdt REAL(gdt) + mov %cr0,%eax + or $CR0_PE,%al + mov %eax,%cr0 + jmp 1f +1: mov $GDT_LEGACY_DATA,%cx + mov %cx,%fs + and $~CR0_PE,%al + mov %eax,%cr0 + ljmpl $0,$REAL(1f) +1: sti + pop %bp + ret + .endfn unreal + +/ Loads remainder of executable off disk. +hiload: push %bp + mov %sp,%bp + push %bx + mov $IMAGE_BASE_REAL,%esi # relocate, again + mov $IMAGE_BASE_PHYSICAL,%ebx + mov $v_ape_realsectors,%ecx + shl $9,%ecx + or $-4,%edx +0: add $4,%edx + cmp %edx,%ecx + je 1f + mov %fs:(%esi,%edx),%eax + mov %eax,%fs:(%ebx,%edx) + jmp 0b +1: lea (%ebx,%edx),%ebx + mov $v_ape_highsectors,%di # then copy rest off disk + mov $REAL_SCRATCH_AREA>>4,%ax # to real memory buffer + mov %ax,%es + mov XLM(LOADSTATE)+0,%cx + mov XLM(LOADSTATE)+2,%dx +0: test %di,%di + jz 9f + mov %di,%ax + push %bx + xor %bx,%bx + call pcread + pop %bx + sub %ax,%di + push %cx + mov %ax,%cx # copy real buffer to high + shl $9,%cx # no way bios loaded >64k + xor %si,%si +1: mov %es:(%si),%eax + mov %eax,%fs:(%ebx) + add $4,%ebx + add $4,%si + sub $4,%cx + jnz 1b + pop %cx + jmp 0b +9: pop %bx + pop %bp + ret + .endfn hiload + +/ Asks keyboard to grant system 65,519 more bytes of memory. +/ +/ Yup. +/ +/ @assume realmode && df=0 +/ @clob ax,di,si,es,flags +/ @mode real +/ @see wiki.osdev.org/A20_Line +a20: cli + push %ds + xor %ax,%ax + mov %ax,%es + dec %ax + mov %ax,%ds + mov $0x0500,%di + mov $0x0510,%si + mov %es:(%di),%al + push %ax + mov %ds:(%si),%al + push %ax + movb $0x00,%es:(%di) + movb $0xff,%ds:(%si) + cmpb $0xff,%es:(%di) + pop %ax + mov %al,%ds:(%si) + pop %ax + mov %al,%es:(%di) + pop %ds + jne 3f + mov $1,%ax + call 1f + mov $0xad,%al + out %al,$0x64 + call 1f + mov $0xd0,%al + out %al,$0x64 + call 2f + in $0x60,%al + push %ax + call 1f + mov $0xd1,%al + out %al,$0x64 + call 1f + pop %ax + or $2,%al + out %al,$0x60 + call 1f + mov $0xae,%al + out %al,$0x64 + call 1f + jmp a20 +1: in $0x64,%al + test $2,%al + jnz 1b + ret +2: in $0x64,%al + test $1,%al + jz 2b + ret +3: sti +5: ret + .endfn a20,globl,hidden # obj since waste of objdump space + +/ Initializes long mode paging. +/ +/ Modern computers access memory via four levels of indirection: +/ +/ register char (*(*(*(*ram)[512])[512])[512])[4096] asm(cr3) +/ +/ Your page tables grow down in memory, starting from the real +/ stack segment base. This function only defines enough tables +/ to get us started. +#define TIP REAL_STACK_FRAME +pinit: push %bp + mov %sp,%bp + push %ds + mov $(TIP-0x4000)>>4,%ax + mov %ax,%ds + movl $TIP-0x2000+PAGE_V+PAGE_RW,%ds:0x3000 # PML4T→PDPT + movl $TIP-0x3000+PAGE_V+PAGE_RW,%ds:0x2000 # PDPT→PDT + movl $TIP-0x4000+PAGE_V+PAGE_RW,%ds:0x1000 # PDT→PD + mov $0x100000/0x1000,%cx # PD→512kb + mov $PAGE_V+PAGE_RW,%eax + xor %si,%si +0: mov %eax,%ds:(%si) + add $0x1000,%eax + add $8,%si + loop 0b + pop %ds + movl $TIP-0x4000,XLM(PAGE_TABLE_STACK_POINTER) # STACK→XLM + mov $TIP-0x1000,%eax # PML4T→CR3 + mov %eax,%cr3 + pop %bp + ret + .endfn pinit,globl,hidden + +/ Switch from Real Mode → Long Mode +/ +/ @see Intel Manual V3A §4.1.2 +golong: cli + lidt XLM(BADIDT) + call pinit + mov %cr4,%eax + or $CR4_PAE|CR4_PGE|CR4_OSFXSR,%eax + mov %eax,%cr4 + movl $EFER,%ecx + rdmsr + or $EFER_LME|EFER_SCE,%eax + wrmsr + lgdt REAL(gdt) + mov %cr0,%eax + or $CR0_PE|CR0_PG|CR0_MP,%eax + and $~CR0_EM,%eax + mov %eax,%cr0 + ljmp $GDT_LONG_CODE,$REAL(1f) + .code64 +1: mov $GDT_LONG_DATA,%eax + mov %ax,%ds + mov %ax,%fs + mov %ax,%gs + xor %edx,%edx + jmp long + .endfn golong + +/ Long mode is long. +/ +/ @noreturn +long: .frame0 + xor %edi,%edi + call pageunmap + + mov $e820map_xlm,%edi + call smapsort + + mov $e820map_xlm,%edi + mov $g_pml4t,%esi + mov $g_ptsp_xlm,%edx + call flattenhighmemory + + mov $REAL(.Lstr.hello),%edi + mov kBiosDataAreaXlm+METAL_STDOUT,%esi + call sputs + mov $kBiosDataAreaXlm+METAL_STDOUT,%edi + mov $4,%esi + call sflush + + jmp triplf + lea triplf(%rip),%rdx + call _start + jmp triplf + .endfn long + +/ Avoid linker script variables appearing as code in objdump. + .macro .ldsvar name:req + .type \name,@object + .weak \name + .endm + .ldsvar _end + .ldsvar _etext + .ldsvar v_ape_realsectors + .ldsvar v_ape_highsectors + .ldsvar idata.ro + .ldsvar ape.pad.rodata + .ldsvar ape.piro + .ldsvar ape.piro.end + .type .Lape.macho.end,@object + .type .Lape.note,@object + .type .Lape.note.end,@object + .type .Lape.note.vaddr,@object + .type .Lape.pe.sections,@object + .type .Lape.pe.sections_end,@object + .type .Lape.text.nops,@object + .type __test_end,@object + + .section .commentprologue,"a",@progbits + .type kLegalNotices,@object + .hidden kLegalNotices +kLegalNotices:/* + ... + decentralized content + ... + */.previous + .section .commentepilogue,"a",@progbits + .byte 0 + .previous + + .section .ape.pad.head,"a",@progbits + .type ape.pad.head,@object + .hidden ape.pad.head +ape.pad.head: + .previous + + .section .ape.pad.text,"a",@progbits + .type ape.pad.text,@object + .hidden ape.pad.text +ape.pad.text: + .previous + + .section .ape.pad.privileged,"a",@progbits + .type ape.pad.privileged,@object + .hidden ape.pad.privileged +ape.pad.privileged: + .previous + + .section .ape.pad.test,"a",@progbits + .type ape.pad.test,@object + .hidden ape.pad.test +ape.pad.test: + .previous + + .section .ape.pad.test,"a",@progbits + .type ape.pad.test,@object + .hidden ape.pad.test +ape.pad.test: + .previous + + .section .ape.pad.rodata,"a",@progbits + .type ape.pad.rodata,@object + .hidden ape.pad.rodata +ape.pad.rodata: + .previous + + .section .ape.pad.data,"a",@progbits + .type ape.pad.data,@object + .hidden ape.pad.data +ape.pad.data: + .previous + + .section .idata.ro,"a",@progbits + .type idata.ro,@object + .hidden idata.ro +idata.ro: + .previous + + .section .dataprologue,"aw",@progbits + .type __data_start,@object + .globl __data_start + .hidden __data_start +__data_start: + .previous + + .type __piro_start,@object + .hidden __piro_start + +.end + \ No newline at end of file diff --git a/ape/ape.lds b/ape/ape.lds new file mode 100644 index 00000000..27bf5718 --- /dev/null +++ b/ape/ape.lds @@ -0,0 +1,660 @@ +/*-*- mode: ld-script; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-│ +│vi: set et sts=2 tw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╠──────────────────────────────────────────────────────────────────────────────╣ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█▀█░▀█▀░█░█░█▀█░█░░░█░░░█░█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█░▄░░█░░█░█░█▀█░█░░░█░░░▀█▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░▀░▀░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀░░▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█▀█░█▀█░▀█▀░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀▀░█ █░██▀░░█░░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░▀░░░▀▀▀░▀░▀░░▀░░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀▀░█░█░█▀▀░█▀█░█░█░▀█▀░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░▄▄░░░▐█░░│ +│░░░░░░░█▀▀░▄▀▄░█▀▀░█░▄░█░█░░█░░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░▄▄▄░░░▄██▄░░█▀░░░█░▄░│ +│░░░░░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░▀░░▀░▀░▀▀▀░▀▀░▀▀▀░░░░░░░░░░▄██▀█▌░██▄▄░░▐█▀▄░▐█▀░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▐█▀▀▌░░░▄▀▌░▌░█░▌░░▌░▌░░│ +╠──────────────────────────────────────────────────────▌▀▄─▐──▀▄─▐▄─▐▄▐▄─▐▄─▐▄─│ +│ αcτµαlly pδrταblε εxεcµταblε § linker │ +╚──────────────────────────────────────────────────────────────────────────────╝ + Having an executable run natively on stock Windows / Mac / Linux / BSD + entails two steps: (1) create a .com.dbg binary w/ Linux toolchain and + then (2) unwrap the .com binary embedded within: + + objcopy -SO binary input.com.dbg output.com + + Both executables will work fine, but only the .com format is portable. + + ───BUILDING───────────────────────────────────────────────────────────── + + LC_ALL=C ld -T ape/ape.lds ... + + ───RUNNING────────────────────────────────────────────────────────────── + + ./foo.com.dbg # works on host machine + ./foo.com # works on any os / arch + qemu-system-x86_64 -s foo.com # works on any os / arch + + ───BACKGROUND─────────────────────────────────────────────────────────── + + The purpose of this software is to help native programs have the same + level of consistency, in terms of user experience, that we enjoy with + web applications. It's basically like MeteorJS, except primarily CLI, + bootable, and more on the order of a few kilobytes than hundred megs. + + Rather than Isomorphic JavaScript it's built using Isomorphic Binary, + since it grants the fastest possible performance and can be trivially + emulated in the browser. System resource utilization is also a few kb + and GUIs are possible too since Cosmopolitan exports the Windows API, + but we recommend doing it with a CLI web server instead and embedding + files in your αcτµαlly pδrταblε εxεcµταblε as it's isomorphic to zip. + + Isomorphic Binary principles state that most platform differences are + just numbers, which we integrate easily into a unified business logic + through the use of a sufficiently powerful linker. System numbers are + otherwise known as ABIs and they're usually the most stable canonical + interfaces that platforms provide. This is how we are able to support + more versions of Linux than most Linux-only software, e.g. glibc FTMP + + ───DEBUGGING──────────────────────────────────────────────────────────── + + Can be done in a few ways: + + gdb --tui foo.com.dbg + gdb --tui foo.com -ex 'add-symbol-file foo.com.dbg 0x200000' + gdb --tui -ex 'add-symbol-file foo.com.dbg 0x7c00' \ + -ex 'add-symbol-file foo.com.dbg 0x200000' \ + -ex -target remote localhost:1234' + + ───TRANSPARENCY───────────────────────────────────────────────────────── + + αcτµαlly pδrταblε εxεcµταblε is designed to facilitate maximum + transparency to engender trust in this linker process. + + The headers and symbols can be viewed using readelf or objdump: + + readelf -Wa input.com.dbg # maximum transparency + objdump -wxd input.com.dbg # maximum transparency + + The disassembly can be viewed using objdump: + + readelf -Wa input.com.dbg # maximum transparency + objdump -d input.com.dbg # maximum transparency + objdump -dj.text input.com.dbg # skip αpε boilerplate + objdump -j.load -dMi8086 input.com.dbg # fixes real mode code + + Some commands for controlling the verbosity of binaries: + + strip -X input.com.dbg # remove ".L" symbols + strip input.com.dbg # remove all symbols + strip -S input.com.dbg # remove debug info only + make CPPFLAGS=-DNDEBUG # remove asserts (prod) + make CPPFLAGS=-DIM_FEELING_NAUGHTY # remove legal notices + + The Makefile build is also configured to always produce a .map file + when building each program, which provides further details. + + ───HACKABILITY────────────────────────────────────────────────────────── + + Your linker and assemblies were designed provide extensibility through + the use of link-time data structures we call "decentralized sections". + They allow functions like _init() to be comprised of many small pieces + defined throughout the codebase. The same applies to ELF / PE headers. + + Extending that content usually entails writing a .S file. The process + has more in common with JavaScript programming than contemporary C++ + development practices. It's the reason Cosmopolitan is able to build + the fast tiny multiplatform autonomous binaries that indie developers + love using a scalable development model that big businesses respect. + + ───SECURITY───────────────────────────────────────────────────────────── + + αcτµαlly pδrταblε εxεcµταblε is designed to be secure in untrustworthy + computing environments. Code and data are separated. Data structures + initialized at startup are automatically memory protected afterwards. + Code intended for platforms you don't use is automatically unmapped + too, minimizing any possible chance of impacting your system, while + still being there in case you ever need it. + + ───CONFIDENTIALITY────────────────────────────────────────────────────── + + αcτµαlly pδrταblε εxεcµταblε is also designed to not leak confidential + information by default. Details relating to the host build environment + such as system/library versions, user ids, home folder locations, etc. + are not taken into consideration at build time since it's hermetic. We + can't make speak for debug information, which is why it's put in other + files. We also provide the bing and fold programs for auditing binary. + + ───DESIGN─DETAILS─────────────────────────────────────────────────────── + + αcτµαlly pδrταblε εxεcµταblε is a non-reflective (a.k.a. flat) binary + format that includes ELF, PE, and Macho-O headers only to respect the + initialization rituals that supported platforms require. + + Binaries are sparse because Intel's six thousand page manual says: + + “Always put code and data on separate pages. [...] If code is + to be modified, try to do it all at once and make sure the + code that performs the modifications and the code being + modified are on separate 4KByte pages or on separate aligned + 1-KByte subpages. [...] If (hopefully read-only) data must + occur on the same page as code, avoid placing it immediately + after an indirect jump [...] or inserting an illegal opcode + [...] after the indirect branch [which] may degrade perf in + some circumstances.” ──Intel V.O §3.6.9 + + Support for linking dynamic shared objects is only implemented on + Windows NT for the reasons described by Ulrich Drepper in his DSO + tutorial. We've implemented this independently of the ld codebase + because authentic GNU tooling is powerful enough to generalize to + arbitrary formats without needing to add features to its codebase. + + Cosmopolitan core library functions may be converted to the COFF or + Mach-O object formats using objconv. That gives you some freedom to + choose to use the Microsoft or Apple linker instead of this one. We + otherwise can't use those formats, due to how they heavily restrict + naming, which basically makes everything we're doing impossible. In + the future an authentic GNU toolchain will be made available on the + Windows and Apple platforms, using canonical formats and behaviors. + Until then, we can build for those platforms using Linux or WSL. */ + +#ifdef __LINKER__ +#include "ape/macros.h" +#include "ape/config.h" +#include "libc/nt/pedef.h" +#include "libc/zip.h" + +ENTRY(_start) + +/* Plans real memory solution at linktime. */ +MEMORY { + PageZero : org = 0x0000000000000000, len = 0x0000000000001000 + RealBss : org = XLM_BASE_REAL, len = XLM_SIZE + RealProgram : org = IMAGE_BASE_REAL, len = 0x0000000000010000 - IMAGE_BASE_REAL + RealScratch : org = REAL_SCRATCH_AREA, len = REAL_STACK_FRAME - REAL_SCRATCH_AREA + RealStack : org = REAL_STACK_FRAME, len = 0x0000000000010000 + EbdaMemory : org = 0x0000000000080000, len = 0x0000000000020000 + VideoMemory : org = 0x00000000000a0000, len = 0x0000000000020000 + Romz : org = 0x00000000000c0000, len = 0x0000000000030000 + BiosMemory : org = 0x00000000000f0000, len = 0x0000000000010000 + SmallCode : org = IMAGE_BASE_PHYSICAL, len = 0x0000000040000000 - IMAGE_BASE_PHYSICAL + ZipData : org = 0x0000000040000000, len = 0x0000000040000000 +} + +PHDRS { + Head PT_LOAD FLAGS(5); + Rom PT_LOAD FLAGS(5); + Ram PT_LOAD FLAGS(6); + stack PT_GNU_STACK FLAGS(6); +} + +SECTIONS { + +/*BEGIN: realmode addressability guarantee */ +/*BEGIN: xnu addressability guarantee */ +/*BEGIN: linux addressability guarantee */ +/*BEGIN: bsd addressability guarantee */ + + .head SEGMENT_START("text-segment", IMAGE_BASE_VIRTUAL) : { + HIDDEN(_base = .); + + /* Real Mode */ + KEEP(*(.head)) + . += 1; + + /* Executable & Linkable Format */ + . = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 1); + KEEP(*(.elf.phdrs)) + HIDDEN(.Lape.phdrs.end = .); + . += 1; + + /* OpenBSD */ + . = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 1); + HIDDEN(.Lape.note = .); + KEEP(*(.note.openbsd.ident)) + HIDDEN(.Lape.note.end = .); + . += 1; + + /* Portable Executable */ + KEEP(*(.pe.header)) + HIDDEN(.Lape.pe.sections = .); + KEEP(*(.pe.sections)) + HIDDEN(.Lape.pe.sections_end = .); + . += 1; + + /* Mach-O */ + KEEP(*(.macho)) + . = ALIGN(__SIZEOF_POINTER__); + HIDDEN(.Lape.macho.end = .); + . += 1; + + KEEP(*(.ape.pad.head)) + . = ALIGN(4096); /* alignments only mandatory when impossible otherwise */ + HIDDEN(_ehead = .); + } AT>SmallCode :Head + +/*BEGIN: nt addressability guarantee */ + + .text . : { + /* Code that needs to be addressable in Real Mode */ + *(.text.real) + KEEP(*(SORT_BY_NAME(.sort.text.real.*))) + *(.rodata.real) + KEEP(*(SORT_BY_NAME(.sort.rodata.real.*))) + HIDDEN(_ereal = .); + +/*END: realmode addressability guarantee */ + + /* Normal Code */ + *(.start) + KEEP(*(.initprologue)) + KEEP(*(SORT_BY_NAME(.init.*))) + KEEP(*(SORT_NONE(.init))) + KEEP(*(.initepilogue)) + KEEP(*(.pltprologue)) + *(.plt) + KEEP(*(.pltepilogue)) + KEEP(*(.pltgotprologue)) + *(.plt.got) + KEEP(*(.pltgotepilogue)) + *(.text.startup .text.startup.*) + *(.text.exit .text.exit.*) + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(SORT_BY_ALIGNMENT(.text.antiquity)) + *(SORT_BY_ALIGNMENT(.text.antiquity.*)) + KEEP(*(.textwindowsprologue)) + *(.text.windows) + KEEP(*(.textwindowsepilogue)) + *(SORT_BY_ALIGNMENT(.text.modernity)) + *(SORT_BY_ALIGNMENT(.text.modernity.*)) + *(SORT_BY_ALIGNMENT(.text.hot)) + *(SORT_BY_ALIGNMENT(.text.hot.*)) + KEEP(*(.keep.text)) + *(.text .stub .text.*) + KEEP(*(SORT_BY_NAME(.sort.text.*))) + + /* Won't support NX bit DRM for tiny executables */ + HIDDEN(.Lape.piro.align = ABSOLUTE(. > APE_PIRO_THRESHOLD ? 0x1000 : 8)); + + /* Code that musn't be mapped in production */ + KEEP(*(.ape.pad.test)); + . = ALIGN(.Lape.piro.align); + HIDDEN(__test_start = .); + *(.test.unlikely) + *(.test .test.*) + + /* Privileged code invulnerable to magic */ + KEEP(*(.ape.pad.privileged)); + . = ALIGN(.Lape.piro.align); + HIDDEN(__privileged_start = .); + HIDDEN(__test_end = .); + . += 1; + *(.privileged) + +/*BEGIN: Read Only Data */ + + KEEP(*(.ape.pad.rodata)); + . = ALIGN(.Lape.piro.align); + . += 1; + + /* Nonspecific Read-Only Data */ + *(.rodata .rodata.*) + . += 1; + + /* Undefined Behavior Sanitizer Types */ + HIDDEN(__ubsan_types_start = .); + *(.ubsan.types) + HIDDEN(__ubsan_types_end = .); + . += 1; + + /* Undefined Behavior Sanitizer Data */ + HIDDEN(__ubsan_data_start = .); + *(.ubsan.data) + HIDDEN(__ubsan_data_end = .); + + /* Unit Test & Fixture Registry */ + +/*BEGIN: Read only data that needn't be mapped after initialization */ + + /* Legal Notices */ + KEEP(*(.commentprologue)) + KEEP(*(.comment)) + KEEP(*(.commentepilogue)) + + /* Windows DLL Import Directory */ + KEEP(*(.idata.ro)); + KEEP(*(SORT_BY_NAME(.idata.ro.*))) + . += 1; + + /* Encoded Data Structures w/ Linear Initialization Order */ + KEEP(*(.initroprologue)) + KEEP(*(SORT_BY_NAME(.initro.*))) + KEEP(*(.initroepilogue)) + KEEP(*(SORT_BY_NAME(.sort.rodata.*))) + + KEEP(*(.ape.pad.text)) + HIDDEN(.Lape.data.align = ABSOLUTE(PAGESIZE)); + . = ALIGN(.Lape.data.align); + HIDDEN(_etext = .); + PROVIDE_HIDDEN(etext = .); +/*END: Read Only Data (only needed for initialization) */ +/*END: Read Only Data */ + } AT>SmallCode :Rom + + .data . : { +/*BEGIN: Read/Write Data */ + KEEP(*(.dataprologue)) + *(.data .data.*) + KEEP(*(SORT_BY_NAME(.sort.data.*))) + . += . > 0 ? 1 : 0; + + KEEP(*(.gotprologue)) + *(.got) + KEEP(*(.gotepilogue)) + + KEEP(*(.gotpltprologue)) + *(.got.plt) + KEEP(*(.gotpltepilogue)) + +/*BEGIN: Post-Initialization Read-Only */ + . = ALIGN(.Lape.piro.align); + HIDDEN(__piro_start = .); + + QUAD(IMAGE_BASE_VIRTUAL); + + PROVIDE_HIDDEN(__init_array_start = .); + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) + SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP(*(SORT_NONE(.ctors))) + KEEP(*(SORT_NONE(.init_array))) + KEEP(*(SORT_NONE(.preinit_array))) + PROVIDE_HIDDEN(__init_array_end = .); + + . += 1; + . = ALIGN(__SIZEOF_POINTER__); + PROVIDE_HIDDEN(__fini_array_start = .); + KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*) + SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP(*(SORT_NONE(.dtors))) + PROVIDE_HIDDEN(__fini_array_end = .); + + KEEP(*(SORT_BY_NAME(.piro.relo.sort.*))) + PROVIDE_HIDDEN(__relo_end = .); + KEEP(*(SORT_BY_NAME(.piro.data.sort.*))) + KEEP(*(.piro.pad.data)) + . = ALIGN(.Lape.data.align); + HIDDEN(_edata = .); + PROVIDE_HIDDEN(edata = .); + } AT>SmallCode :Ram + + .bss . : { + KEEP(*(SORT_BY_NAME(.piro.bss.init.*))) + *(.piro.bss) + KEEP(*(SORT_BY_NAME(.piro.bss.sort.*))) + . += 1; + . = ALIGN(.Lape.piro.align); + HIDDEN(__piro_end = .); +/*END: Post-Initialization Read-Only */ + + /* Statically Allocated Empty Space */ + *(SORT_BY_ALIGNMENT(.bss)) + *(SORT_BY_ALIGNMENT(.bss.*)) + *(COMMON) + + KEEP(*(SORT_BY_NAME(.sort.bss.*))) + + /* eXtreme Low Memory w/ Userspace Remapping */ + . = ALIGN(0x1000); + *(.xlm) + . = ALIGN(0x1000); + + HIDDEN(_end = .); + PROVIDE_HIDDEN(end = .); + } AT>SmallCode :Ram + +/*END: nt addressability guarantee */ +/*END: bsd addressability guarantee */ +/*END: linux addressability guarantee */ +/*END: xnu addressability guarantee */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + .debug_macro 0 : { *(.debug_macro) } + .debug_addr 0 : { *(.debug_addr) } + .gnu.attributes 0 : { KEEP(*(.gnu.attributes)) } + .GCC.command.line 0 : { *(.GCC.command.line) } + + /DISCARD/ : { + *(.discard) + *(.yoink) + *(.*) + } +} + +PFSTUB8(.Lape.elf.entry, _start); +PFSTUB8(.Lape.elf.phoff, RVA(ape.phdrs)); +PFSTUB8(.Lape.elf.shoff, 0); +PFSTUB4(.Lape.elf.phnum, (.Lape.phdrs.end - ape.phdrs) / 56); +PFSTUB4(.Lape.elf.shnum, 0); +PFSTUB4(.Lape.elf.shstrndx, 0); +SHSTUB2(.Lape.macho.dd.skip, RVA(ape.macho) / 8); +SHSTUB2(.Lape.macho.dd.count, (.Lape.macho.end - ape.macho) / 8); +PFSTUB4(.Lape.pe.offset, ape.pe - ape.mz); + +HIDDEN(.Lape.pe.optsz = .Lape.pe.sections - (ape.pe + 24)); +HIDDEN(.Lape.pe.shnum = (.Lape.pe.sections_end - .Lape.pe.sections) / 40); +HIDDEN(.Lidata.idtsize = idata.idtend - idata.idt); +HIDDEN(.Lidata.iatsize = idata.iatend - idata.iat); + +HIDDEN(.Lape.rom.offset = 0); +HIDDEN(.Lape.rom.vaddr = ADDR(.head)); +HIDDEN(.Lape.rom.paddr = LOADADDR(.head)); +HIDDEN(.Lape.rom.filesz = LOADADDR(.data) - .Lape.rom.paddr); +HIDDEN(.Lape.rom.memsz = ADDR(.data) - ADDR(.head)); +HIDDEN(.Lape.rom.align = 0x1000); +HIDDEN(.Lape.rom.rva = RVA(.Lape.rom.vaddr)); + +HIDDEN(.Lape.ram.offset = .Lape.rom.offset + .Lape.rom.filesz); +HIDDEN(.Lape.ram.vaddr = ADDR(.data)); +HIDDEN(.Lape.ram.paddr = LOADADDR(.data)); +HIDDEN(.Lape.ram.filesz = LOADADDR(.bss) - LOADADDR(.data)); +HIDDEN(.Lape.ram.memsz = ADDR(.bss) + SIZEOF(.bss) - .Lape.ram.vaddr); +HIDDEN(.Lape.ram.align = 0x1000); +HIDDEN(.Lape.ram.rva = RVA(.Lape.ram.vaddr)); + +HIDDEN(.Lape.note.offset = .Lape.rom.offset + (.Lape.note - .Lape.rom.vaddr)); +HIDDEN(.Lape.note.vaddr = .Lape.note); +HIDDEN(.Lape.note.paddr = .Lape.rom.paddr + .Lape.note.offset); +HIDDEN(.Lape.note.filesz = .Lape.note.end - .Lape.note); +HIDDEN(.Lape.note.memsz = .Lape.note.filesz); +HIDDEN(.Lape.note.align = __SIZEOF_POINTER__); + +HIDDEN(.Lape.text.offset = .Lape.rom.offset + LOADADDR(.text) - .Lape.rom.paddr); +HIDDEN(.Lape.text.paddr = LOADADDR(.text)); +HIDDEN(.Lape.text.vaddr = ADDR(.text)); +HIDDEN(.Lape.text.filesz = SIZEOF(.text)); +HIDDEN(.Lape.text.memsz = SIZEOF(.text)); +HIDDEN(.Lape.text.align = 4096); +HIDDEN(.Lape.text.rva = RVA(.Lape.text.vaddr)); + +HIDDEN(.Lape.data.offset = .Lape.ram.offset + LOADADDR(.data) - .Lape.ram.paddr); +HIDDEN(.Lape.data.paddr = LOADADDR(.data)); +HIDDEN(.Lape.data.vaddr = ADDR(.data)); +HIDDEN(.Lape.data.filesz = SIZEOF(.data)); +HIDDEN(.Lape.data.memsz = SIZEOF(.data)); +HIDDEN(.Lape.data.align = 0x1000); +HIDDEN(.Lape.data.rva = RVA(.Lape.data.vaddr)); + +HIDDEN(.Lape.bss.offset = .Lape.ram.offset + LOADADDR(.bss) - .Lape.ram.paddr); +HIDDEN(.Lape.bss.paddr = LOADADDR(.bss)); +HIDDEN(.Lape.bss.vaddr = ADDR(.bss)); +HIDDEN(.Lape.bss.filesz = 0); +HIDDEN(.Lape.bss.memsz = SIZEOF(.bss)); +HIDDEN(.Lape.bss.align = .Lape.data.align); + +/* Program Loader Auto-Tune */ +HIDDEN(v_ape_realsectors = + MIN(REAL_SCRATCH_AREA - IMAGE_BASE_REAL, + ROUNDUP(RVA(_edata), 512)) / 512); +HIDDEN(v_ape_highsectors = + (ROUNDUP(RVA(_edata), 512) / 512) - v_ape_realsectors); + +/* Windows NT Auto-Subsystem Embedding */ +HIDDEN(v_ntsubsystem = (DEFINED(GetMessage) + ? kNtImageSubsystemWindowsGui + : kNtImageSubsystemWindowsCui)); + +/* ZIP End of Central Directory header */ +#define ZIPCONST(NAME, VAL) HIDDEN(NAME = DEFINED(__zip_start) ? VAL : 0); +ZIPCONST(v_zip_cdoffset, __zip_start - IMAGE_BASE_VIRTUAL); +ZIPCONST(v_zip_cdirsize, __zip_end - __zip_start); +ZIPCONST(v_zip_records, v_zip_cdirsize / kZipCdirHdrLinkableSize); +ZIPCONST(v_zip_commentsize, _edata - __zip_end - kZipCdirHdrMinSize); + +/* Generates deterministic ID for Mach-O. */ +#define PHI 0x9e3779b9925d4c17 +#define XOR(X,Y) ((X | Y) - (X & Y)) +#define XORSHIFT(X,Y) \ + X = XOR(X, (Y >> 12)); \ + X = XOR(X, (Y << 25)); \ + X = XOR(X, (Y >> 27)) +#define KMH(X,Y) \ + X = (X + (Y >> 000) & 0xFF) * PHI; \ + X = (X + (Y >> 010) & 0xFF) * PHI; \ + X = (X + (Y >> 020) & 0xFF) * PHI; \ + X = (X + (Y >> 030) & 0xFF) * PHI +#define BOOP(X) \ + XORSHIFT(uuid1_, X); \ + KMH(uuid1_, X); \ + XORSHIFT(uuid2_, X); \ + KMH(uuid2_, X) + +HIDDEN(uuid1_ = 88172645463325252); +HIDDEN(uuid2_ = 88172645463325252); + +BOOP(.Lape.bss.align); +BOOP(.Lape.bss.filesz); +BOOP(.Lape.bss.memsz); +BOOP(.Lape.bss.offset); +BOOP(.Lape.bss.paddr); +BOOP(.Lape.data.align); +BOOP(.Lape.data.filesz); +BOOP(.Lape.data.memsz); +BOOP(.Lape.data.offset); +BOOP(.Lape.data.paddr); +BOOP(.Lape.data.rva); +BOOP(.Lape.data.vaddr); +BOOP(.Lape.elf.entry); +BOOP(.Lape.elf.phnum); +BOOP(.Lape.elf.phoff); +BOOP(.Lape.elf.shnum); +BOOP(.Lape.elf.shoff); +BOOP(.Lape.elf.shstrndx); +BOOP(.Lape.macho.end); +BOOP(.Lape.note); +BOOP(.Lape.note.align); +BOOP(.Lape.note.end); +BOOP(.Lape.note.filesz); +BOOP(.Lape.note.memsz); +BOOP(.Lape.note.offset); +BOOP(.Lape.note.paddr); +BOOP(.Lape.note.vaddr); +BOOP(.Lape.pe.offset); +BOOP(.Lape.pe.optsz); +BOOP(.Lape.pe.sections); +BOOP(.Lape.pe.sections_end); +BOOP(.Lape.pe.shnum); +BOOP(.Lape.phdrs.end); +BOOP(.Lape.ram.align); +BOOP(.Lape.ram.filesz); +BOOP(.Lape.ram.memsz); +BOOP(.Lape.ram.offset); +BOOP(.Lape.ram.paddr); +BOOP(.Lape.ram.rva); +BOOP(.Lape.ram.vaddr); +BOOP(.Lape.rom.align); +BOOP(.Lape.rom.filesz); +BOOP(.Lape.rom.memsz); +BOOP(.Lape.rom.offset); +BOOP(.Lape.rom.paddr); +BOOP(.Lape.rom.rva); +BOOP(.Lape.rom.vaddr); +BOOP(.Lape.text.align); +BOOP(.Lape.text.filesz); +BOOP(.Lape.text.memsz); +BOOP(.Lape.text.offset); +BOOP(.Lape.text.paddr); +BOOP(.Lape.text.rva); +BOOP(.Lape.text.vaddr); +BOOP(ADDR(.bss)); +BOOP(WinMain); +BOOP(_start); +BOOP(ape.macho); +BOOP(ape.mz); +BOOP(ape.pe); +BOOP(ape.phdrs); +BOOP(v_ape_realsectors); + +ASSERT(ape.mz == IMAGE_BASE_VIRTUAL, "linker panic"); +ASSERT((DEFINED(__init_bss_end) ? __init_bss_end : 0) % __SIZEOF_POINTER__ == 0, + "__init_bss misalign"); +ASSERT(((DEFINED(__init_rodata_end) ? __init_rodata_end : 0) % + __SIZEOF_POINTER__ == 0), + "__init_rodata misalign"); + +ASSERT((!DEFINED(ape.grub) ? 1 : RVA(ape.grub) < 8192), + "grub stub needs to be in first 8kb of image"); + +ASSERT(DEFINED(_start) || DEFINED(_start16), + "please link a _start() or _start16() entrypoint"); + +ASSERT(!DEFINED(_start16) || REAL(_end) < 65536, + "ape won't support non-tiny real mode programs"); + +/* Let's not be like Knight Capital. */ +/* NOCROSSREFS_TO(.test .text) */ + +/* ASSERT(ape_sysv_start == .Lape.text.vaddr, */ +/* "ape_sysv_start() must be first in .text"); */ + +#endif /* __LINKER__ */ diff --git a/ape/ape.mk b/ape/ape.mk new file mode 100644 index 00000000..8f18dc80 --- /dev/null +++ b/ape/ape.mk @@ -0,0 +1,57 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ +# +# OVERVIEW +# +# αcτµαlly pδrταblε εxεcµταblε +# +# DESCRIPTION +# +# This file defines the libraries, runtimes, and build rules needed to +# create executables from your Linux workstation that'll run anywhere. +# Loading this package will make certain systemic modifications to the +# build like turning off the System V "Red Zone" optimization, because +# αcτµαlly pδrταblε εxεcµταblεs need to be able to run in kernelspace. + +PKGS += APE + +DEFAULT_COPTS += -mno-red-zone +DEFAULT_LDFLAGS += -z max-page-size=0x1000 + +APELINK = ACTION=LINK.ape $(LINK) $(LINKARGS) $(OUTPUT_OPTION) && $(STRIP) -X $@ && $(GZ) $(ZFLAGS) -f $@.map + +APE = $(APE_DEPS) \ + $(APE_OBJS) \ + o/$(MODE)/ape/ape.lds + +APE_FILES := \ + $(wildcard ape/*.*) + +APE_HDRS = \ + $(filter %.h,$(APE_FILES)) + +APE_SRCS = \ + $(filter %.S,$(APE_FILES)) + +APE_OBJS = \ + $(APE_SRCS:%=o/$(MODE)/%.zip.o) \ + $(APE_SRCS:%.S=o/$(MODE)/%.o) + +APE_DEPS = \ + $(APE_LIB) + +APE_CHECKS = \ + $(APE_HDRS:%=o/%.ok) + +o/%.com: o/%.com.dbg + @ACTION=OBJCOPY.ape TARGET=$@ build/do $(OBJCOPY) -SO binary $< $@ + +o/ape/idata.inc: ape/idata.h ape/relocations.h + +$(APE_OBJS): $(BUILD_FILES) \ + ape/ape.mk + +.PHONY: o/$(MODE)/ape +o/$(MODE)/ape: $(APE) \ + $(APE_CHECKS) \ + o/$(MODE)/ape/lib diff --git a/ape/config.h b/ape/config.h new file mode 100644 index 00000000..12e0eb5c --- /dev/null +++ b/ape/config.h @@ -0,0 +1,137 @@ +#ifndef APE_CONFIG_H_ +#define APE_CONFIG_H_ +#include "ape/relocations.h" +#include "libc/macros.h" + +/** + * @fileverview αcτµαlly pδrταblε εxεcµταblε configuration. + */ + +/** + * Post-Initialization Read-Only Code Size Threshold. + * + * An executable needs to have at least this much code, before the + * linker adds non-mandatory 4kb alignments. The benefit is better + * memory protection. The tradeoff is sparser binaries. + */ +#ifndef APE_PIRO_THRESHOLD +#ifdef CONFIG_DBG +#define APE_PIRO_THRESHOLD 0x1000 +#else +#define APE_PIRO_THRESHOLD 0x10000 +#endif +#endif + +/** + * PC Standard I/O Configuration. + */ +#ifndef METAL_STDIN +#define METAL_STDIN COM1 +#endif +#ifndef METAL_STDOUT +#define METAL_STDOUT COM1 +#endif +#ifndef METAL_STDERR +#define METAL_STDERR COM2 /* will fallback to stdout if COM2 not present */ +#endif + +/** + * PC Display Configuration (MDA/CGA) + * @see www.lammertbies.nl/comm/info/serial-uart.html + * @see ape/lib/vidya.h + */ +#ifndef VIDYA_MODE +#define VIDYA_MODE VIDYA_MODE_MDA +#endif + +/* FPU Control Word (x87) Exception Masks + @see Intel Manual V1 §8.1.5 + + IM: Invalid Operation ───────────────┐ + DM: Denormal Operand ───────────────┐│ + ZM: Zero Divide ───────────────────┐││ + OM: Overflow ─────────────────────┐│││ + UM: Underflow ───────────────────┐││││ + PM: Precision ──────────────────┐│││││ + PC: Precision Control ────────┐ ││││││ + {float,∅,double,long double} │ ││││││ + RC: Rounding Control ───────┐ │ ││││││ + {even, →-∞, →+∞, →0} │┌┤ ││││││ + ┌┤││ ││││││ + d││││rr││││││*/ +#define X87_NORMAL 0b000000000001101111111 +#define X87_DTOA 0b000000000001000000000 +#define X87_DTOA_MASK 0b000000000001100000000 +#ifndef X87_DEFAULT +#define X87_DEFAULT X87_NORMAL +#endif + +/** + * Serial Line Configuration (8250 UART 16550) + * @see ape/lib/uart.h + */ +#ifndef UART_BAUD_RATE +#define UART_BAUD_RATE 9600 /* bits per second ∈ [50,115200] */ +#endif +#define UART_CONF_DLR (1843200 /*hz*/ / 16 /*wut*/ / (UART_BAUD_RATE)) +#ifndef UART_CONF_IIR +/* ┌interrupt trigger level {1,4,8,14} + │ ┌enable 64 byte fifo (UART 16750+) + │ │ ┌select dma mode + │ │ │┌clear transmit fifo + │ │ ││┌clear receive fifo + ├┐│ │││┌enable fifos*/ +#define UART_CONF_IIR 0b00000000 +#endif +#ifndef UART_CONF_LCR +/* ┌dlab: flips configuration mode state + │┌enable break signal + ││ ┌parity {none,odd,even,high,low} + ││ │ ┌extra stop bit + ││ │ │┌data word length (bits+5) + ││┌┴┐│├┐*/ +#define UART_CONF_LCR 0b01000011 +#endif + +/** + * eXtreme Low Memory. + */ +#define XLM(VAR) (XLM_BASE_REAL + XLM_##VAR) +#define XLMV(VAR) (__xlm + XLM_##VAR) +#define XLM_BASE_REAL 0x1000 +#define XLM_E820 0 +#define XLM_E820_SIZE 0x2000 +#define XLM_BIOS_DATA_AREA 0x2000 +#define XLM_BIOS_DATA_AREA_SIZE 256 +#define XLM_DRIVE_BASE_TABLE 0x2200 /* drive values are contiguous */ +#define XLM_DRIVE_BASE_TABLE_SIZE 11 +#define XLM_DRIVE_TYPE 0x220b +#define XLM_DRIVE_TYPE_SIZE 1 +#define XLM_DRIVE_LAST_SECTOR 0x220c /* 1-based inclusive, e.g. 18 */ +#define XLM_DRIVE_LAST_SECTOR_SIZE 1 +#define XLM_DRIVE_LAST_CYLINDER 0x220d /* 0-based incl, e.g. 79 */ +#define XLM_DRIVE_LAST_CYLINDER_SIZE 2 +#define XLM_DRIVE_ATTACHED 0x220f +#define XLM_DRIVE_ATTACHED_SIZE 1 +#define XLM_DRIVE_LAST_HEAD 0x2210 /* 0-based inclusive, e.g. 1 */ +#define XLM_DRIVE_LAST_HEAD_SIZE 1 +#define XLM_DRIVE 0x2211 +#define XLM_DRIVE_SIZE 1 +#define XLM_HAVEEXTMEMKB 0x2212 +#define XLM_HAVEEXTMEMKB_SIZE 4 +#define XLM_VIDEO_POSITION_FAR_POINTER 0x2216 /* video cursor far pointer */ +#define XLM_VIDEO_POSITION_FAR_POINTER_SIZE 4 +#define XLM_PAGE_TABLE_STACK_POINTER 0x2220 +#define XLM_PAGE_TABLE_STACK_POINTER_SIZE 8 +#define XLM_BADIDT 0x2230 +#define XLM_BADIDT_SIZE 6 +#define XLM_LOADSTATE 0x2240 +#define XLM_LOADSTATE_SIZE 4 +#define XLM_SIZE ROUNDUP(XLM_LOADSTATE + XLM_LOADSTATE_SIZE, 0x1000) +#define IMAGE_BASE_REAL (XLM_BASE_REAL + XLM_SIZE) + +#if !defined(__LINKER__) && !defined(__ASSEMBLER__) +extern char __xlm[XLM_SIZE]; +#endif /* !defined(__LINKER__) && !defined(__ASSEMBLER__) */ + +#endif /* APE_CONFIG_H_ */ diff --git a/ape/etc/bochsrc.dbg b/ape/etc/bochsrc.dbg new file mode 100644 index 00000000..28a8d271 --- /dev/null +++ b/ape/etc/bochsrc.dbg @@ -0,0 +1,1279 @@ +# make boot.com +# bochs -q -f .bochsrc.dbg floppya:1_44=win64.exe,status=inserted + +#======================================================================= +# PLUGIN_CTRL: +# Controls the presence of optional device plugins. These plugins are loaded +# directly with this option and some of them install a config option that is +# only available when the plugin device is loaded. The value "1" means to load +# the plugin and "0" will unload it (if loaded before). +# +# These plugins will be loaded by default (if present): 'biosdev', 'extfpuirq', +# 'gameport', 'iodebug','parallel', 'serial', 'speaker' and 'unmapped'. +# +# These plugins are also supported, but they are usually loaded directly with +# their bochsrc option: 'e1000', 'es1370', 'ne2k', 'pcidev', 'pcipnic', 'sb16', +# 'usb_ehci', 'usb_ohci', 'usb_uhci', 'usb_xhci' and 'voodoo'. +#======================================================================= +#plugin_ctrl: unmapped=0, e1000=1 # unload 'unmapped' and load 'e1000' + +#======================================================================= +# CONFIG_INTERFACE +# +# The configuration interface is a series of menus or dialog boxes that +# allows you to change all the settings that control Bochs's behavior. +# Depending on the platform there are up to 3 choices of configuration +# interface: a text mode version called "textconfig" and two graphical versions +# called "win32config" and "wx". The text mode version uses stdin/stdout and +# is always compiled in, unless Bochs is compiled for wx only. The choice +# "win32config" is only available on win32 and it is the default there. +# The choice "wx" is only available when you use "--with-wx" on the configure +# command. If you do not write a config_interface line, Bochs will +# choose a default for you. +# +# NOTE: if you use the "wx" configuration interface, you must also use +# the "wx" display library. +#======================================================================= +#config_interface: textconfig +#config_interface: win32config +#config_interface: wx + +#======================================================================= +# DISPLAY_LIBRARY +# +# The display library is the code that displays the Bochs VGA screen. Bochs +# has a selection of about 10 different display library implementations for +# different platforms. If you run configure with multiple --with-* options, +# the display_library command lets you choose which one you want to run with. +# If you do not write a display_library line, Bochs will choose a default for +# you. +# +# The choices are: +# x use X windows interface, cross platform +# win32 use native win32 libraries +# carbon use Carbon library (for MacOS X) +# macintosh use MacOS pre-10 +# amigaos use native AmigaOS libraries +# sdl use SDL 1.2.x library, cross platform +# sdl2 use SDL 2.x library, cross platform +# svga use SVGALIB library for Linux, allows graphics without X11 +# term text only, uses curses/ncurses library, cross platform +# rfb provides an interface to AT&T's VNC viewer, cross platform +# vncsrv use LibVNCServer for extended RFB(VNC) support +# wx use wxWidgets library, cross platform +# nogui no display at all +# +# NOTE: if you use the "wx" configuration interface, you must also use +# the "wx" display library. +# +# Specific options: +# Some display libraries now support specific options to control their +# behaviour. These options are supported by more than one display library: +# +# "gui_debug" - use GTK debugger gui (sdl, sdl2, x) / Win32 debugger gui (sdl, +# sdl2, win32) +# "hideIPS" - disable IPS output in status bar (rfb, sdl, sdl2, vncsrv, +# win32, wx, x) +# "nokeyrepeat" - turn off host keyboard repeat (sdl, sdl2, win32, x) +# "timeout" - time (in seconds) to wait for client (rfb, vncsrv) +# +# See the examples below for other currently supported options. +#======================================================================= +#display_library: amigaos +#display_library: carbon +#display_library: macintosh +#display_library: nogui +#display_library: rfb +#display_library: sdl, options="fullscreen" # startup in fullscreen mode +#display_library: sdl2, options="fullscreen" # startup in fullscreen mode +#display_library: term +#display_library: vncsrv +# "traphotkeys" - system hotkeys not handled by host OS, but sent to guest +# (win32 in mouse capture and fullscreen mode: alt-tab, win, +# alt-space, alt-esc, ctrl-esc) +#display_library: win32, options="traphotkeys" +#display_library: wx +#display_library: x, gui_debug=1 +display_library: x, options="gui_debug" + +#======================================================================= +# CPU: +# This defines cpu-related parameters inside Bochs: +# +# MODEL: +# Selects CPU configuration to emulate from pre-defined list of all +# supported configurations. When this option is used and the value +# is different from 'bx_generic', the parameters of the CPUID option +# have no effect anymore. +# +# CPU configurations that can be selected: +# ----------------------------------------------------------------- +# pentium Intel Pentium (P54C) +# pentium_mmx Intel Pentium MMX +# amd_k6_2_chomper AMD-K6(tm) 3D processor (Chomper) +# p2_klamath Intel Pentium II (Klamath) +# p3_katmai Intel Pentium III (Katmai) +# p4_willamette Intel(R) Pentium(R) 4 (Willamette) +# core_duo_t2400_yonah Intel(R) Core(TM) Duo CPU T2400 (Yonah) +# atom_n270 Intel(R) Atom(TM) CPU N270 +# p4_prescott_celeron_336 Intel(R) Celeron(R) 336 (Prescott) +# athlon64_clawhammer AMD Athlon(tm) 64 Processor 2800+ (Clawhammer) +# athlon64_venice AMD Athlon(tm) 64 Processor 3000+ (Venice) +# turion64_tyler AMD Turion(tm) 64 X2 Mobile TL-60 (Tyler) +# phenom_8650_toliman AMD Phenom X3 8650 (Toliman) +# core2_penryn_t9600 Intel Mobile Core 2 Duo T9600 (Penryn) +# corei5_lynnfield_750 Intel(R) Core(TM) i5 750 (Lynnfield) +# corei5_arrandale_m520 Intel(R) Core(TM) i5 M 520 (Arrandale) +# corei7_sandy_bridge_2600k Intel(R) Core(TM) i7-2600K (Sandy Bridge) +# zambezi AMD FX(tm)-4100 Quad-Core Processor (Zambezi) +# trinity_apu AMD A8-5600K APU (Trinity) +# ryzen AMD Ryzen 7 1700 +# corei7_ivy_bridge_3770k Intel(R) Core(TM) i7-3770K CPU (Ivy Bridge) +# corei7_haswell_4770 Intel(R) Core(TM) i7-4770 CPU (Haswell) +# broadwell_ult Intel(R) Processor 5Y70 CPU (Broadwell) +# +# COUNT: +# Set the number of processors:cores per processor:threads per core when +# Bochs is compiled for SMP emulation. Bochs currently supports up to +# 14 threads (legacy APIC) or 254 threads (xAPIC or higher) running +# simultaniosly. If Bochs is compiled without SMP support, it won't accept +# values different from 1. +# +# QUANTUM: +# Maximum amount of instructions allowed to execute by processor before +# returning control to another cpu. This option exists only in Bochs +# binary compiled with SMP support. +# +# RESET_ON_TRIPLE_FAULT: +# Reset the CPU when triple fault occur (highly recommended) rather than +# PANIC. Remember that if you trying to continue after triple fault the +# simulation will be completely bogus ! +# +# CPUID_LIMIT_WINNT: +# Determine whether to limit maximum CPUID function to 2. This mode is +# required to workaround WinNT installation and boot issues. +# +# MSRS: +# Define path to user CPU Model Specific Registers (MSRs) specification. +# See example in msrs.def. +# +# IGNORE_BAD_MSRS: +# Ignore MSR references that Bochs does not understand; print a warning +# message instead of generating #GP exception. This option is enabled +# by default but will not be avaiable if configurable MSRs are enabled. +# +# MWAIT_IS_NOP: +# When this option is enabled MWAIT will not put the CPU into a sleep state. +# This option exists only if Bochs compiled with --enable-monitor-mwait. +# +# IPS: +# Emulated Instructions Per Second. This is the number of IPS that bochs +# is capable of running on your machine. You can recompile Bochs with +# --enable-show-ips option enabled, to find your host's capability. +# Measured IPS value will then be logged into your log file or shown +# in the status bar (if supported by the gui). +# +# IPS is used to calibrate many time-dependent events within the bochs +# simulation. For example, changing IPS affects the frequency of VGA +# updates, the duration of time before a key starts to autorepeat, and +# the measurement of BogoMips and other benchmarks. +# +# Examples: +# +# Bochs Machine/Compiler Mips +# ______________________________________________________________________ +# 2.4.6 3.4Ghz Intel Core i7 2600 with Win7x64/g++ 4.5.2 85 to 95 Mips +# 2.3.7 3.2Ghz Intel Core 2 Q9770 with WinXP/g++ 3.4 50 to 55 Mips +# 2.3.7 2.6Ghz Intel Core 2 Duo with WinXP/g++ 3.4 38 to 43 Mips +# 2.2.6 2.6Ghz Intel Core 2 Duo with WinXP/g++ 3.4 21 to 25 Mips +# 2.2.6 2.1Ghz Athlon XP with Linux 2.6/g++ 3.4 12 to 15 Mips +#======================================================================= +#cpu: model=core2_penryn_t9600, count=1, ips=50000000, reset_on_triple_fault=1, ignore_bad_msrs=1, msrs="msrs.def" +#cpu: cpuid_limit_winnt=0 +cpu: model=corei7_haswell_4770 + +#======================================================================= +# CPUID: +# +# This defines features and functionality supported by Bochs emulated CPU. +# The option has no offect if CPU model was selected in CPU option. +# +# MMX: +# Select MMX instruction set support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 5. +# +# APIC: +# Select APIC configuration (LEGACY/XAPIC/XAPIC_EXT/X2APIC). +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 5. +# +# SEP: +# Select SYSENTER/SYSEXIT instruction set support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# SIMD: +# Select SIMD instructions support. +# Any of NONE/SSE/SSE2/SSE3/SSSE3/SSE4_1/SSE4_2/AVX/AVX2/AVX512 +# could be selected. +# +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# The AVX choises exists only if Bochs compiled with --enable-avx option. +# +# SSE4A: +# Select AMD SSE4A instructions support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# MISALIGNED_SSE: +# Select AMD Misaligned SSE mode support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# AES: +# Select AES instruction set support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# SHA: +# Select SHA instruction set support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# MOVBE: +# Select MOVBE Intel(R) Atom instruction support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# ADX: +# Select ADCX/ADOX instructions support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# XSAVE: +# Select XSAVE extensions support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# XSAVEOPT: +# Select XSAVEOPT instruction support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# AVX_F16C: +# Select AVX float16 convert instructions support. +# This option exists only if Bochs compiled with --enable-avx option. +# +# AVX_FMA: +# Select AVX fused multiply add (FMA) instructions support. +# This option exists only if Bochs compiled with --enable-avx option. +# +# BMI: +# Select BMI1/BMI2 instructions support. +# This option exists only if Bochs compiled with --enable-avx option. +# +# XOP: +# Select AMD XOP instructions support. +# This option exists only if Bochs compiled with --enable-avx option. +# +# FMA4: +# Select AMD four operand FMA instructions support. +# This option exists only if Bochs compiled with --enable-avx option. +# +# TBM: +# Select AMD Trailing Bit Manipulation (TBM) instructions support. +# This option exists only if Bochs compiled with --enable-avx option. +# +# X86-64: +# Enable x86-64 and long mode support. +# This option exists only if Bochs compiled with x86-64 support. +# +# 1G_PAGES: +# Enable 1G page size support in long mode. +# This option exists only if Bochs compiled with x86-64 support. +# +# PCID: +# Enable Process-Context Identifiers (PCID) support in long mode. +# This option exists only if Bochs compiled with x86-64 support. +# +# FSGSBASE: +# Enable GS/GS BASE access instructions support in long mode. +# This option exists only if Bochs compiled with x86-64 support. +# +# SMEP: +# Enable Supervisor Mode Execution Protection (SMEP) support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# SMAP: +# Enable Supervisor Mode Access Prevention (SMAP) support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# MWAIT: +# Select MONITOR/MWAIT instructions support. +# This option exists only if Bochs compiled with --enable-monitor-mwait. +# +# VMX: +# Select VMX extensions emulation support. +# This option exists only if Bochs compiled with --enable-vmx option. +# +# SVM: +# Select AMD SVM (Secure Virtual Machine) extensions emulation support. +# This option exists only if Bochs compiled with --enable-svm option. +# +# VENDOR_STRING: +# Set the CPUID vendor string returned by CPUID(0x0). This should be a +# twelve-character ASCII string. +# +# BRAND_STRING: +# Set the CPUID vendor string returned by CPUID(0x80000002 .. 0x80000004). +# This should be at most a forty-eight-character ASCII string. +# +# LEVEL: +# Set emulated CPU level information returned by CPUID. Default value is +# determined by configure option --enable-cpu-level. Currently supported +# values are 5 (for Pentium and similar processors) and 6 (for P6 and +# later processors). +# +# FAMILY: +# Set model information returned by CPUID. Default family value determined +# by configure option --enable-cpu-level. +# +# MODEL: +# Set model information returned by CPUID. Default model value is 3. +# +# STEPPING: +# Set stepping information returned by CPUID. Default stepping value is 3. +#======================================================================= +#cpuid: x86_64=1, mmx=1, sep=1, simd=sse4_2, apic=xapic, aes=1, movbe=1, xsave=1 +#cpuid: family=6, model=0x1a, stepping=5 + +#======================================================================= +# MEMORY +# Set the amount of physical memory you want to emulate. +# +# GUEST: +# Set amount of guest physical memory to emulate. The default is 32MB, +# the maximum amount limited only by physical address space limitations. +# +# HOST: +# Set amount of host memory you want to allocate for guest RAM emulation. +# It is possible to allocate less memory than you want to emulate in guest +# system. This will fake guest to see the non-existing memory. Once guest +# system touches new memory block it will be dynamically taken from the +# memory pool. You will be warned (by FATAL PANIC) in case guest already +# used all allocated host memory and wants more. +# +#======================================================================= +#memory: guest=512, host=256 + +#======================================================================= +# ROMIMAGE: +# The ROM BIOS controls what the PC does when it first powers on. +# Normally, you can use a precompiled BIOS in the source or binary +# distribution called BIOS-bochs-latest. The default ROM BIOS is usually loaded +# starting at address 0xfffe0000, and it is exactly 128k long. The legacy +# version of the Bochs BIOS is usually loaded starting at address 0xffff0000, +# and it is exactly 64k long. +# You can use the environment variable $BXSHARE to specify the location +# of the BIOS. +# The usage of external large BIOS images (up to 512k) at memory top is +# now supported, but we still recommend to use the BIOS distributed with Bochs. +# The start address is optional, since it can be calculated from image size. +# The Bochs BIOS currently supports only the option "fastboot" to skip the +# boot menu delay. +#======================================================================= +romimage: file=$BXSHARE/BIOS-bochs-latest, options=fastboot +#romimage: file=$BXSHARE/bios.bin-1.7.5 # http://www.seabios.org/SeaBIOS +#romimage: file=mybios.bin, address=0xfff80000 # 512k at memory top +#romimage: file=BIOS-bochs-latest, options=fastboot + +#======================================================================= +# VGAROMIMAGE +# You now need to load a VGA ROM BIOS into C0000. +#======================================================================= +#vgaromimage: file=$BXSHARE/VGABIOS-elpin-2.40 +vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest +#vgaromimage: file=bios/VGABIOS-lgpl-latest-cirrus + +#======================================================================= +# OPTROMIMAGE[1-4]: +# You may now load up to 4 optional ROM images. Be sure to use a +# read-only area, typically between C8000 and EFFFF. These optional +# ROM images should not overwrite the rombios (located at +# F0000-FFFFF) and the videobios (located at C0000-C7FFF). +# Those ROM images will be initialized by the bios if they contain +# the right signature (0x55AA) and a valid checksum. +# It can also be a convenient way to upload some arbitrary code/data +# in the simulation, that can be retrieved by the boot loader +#======================================================================= +#optromimage1: file=optionalrom.bin, address=0xd0000 +#optromimage2: file=optionalrom.bin, address=0xd1000 +#optromimage3: file=optionalrom.bin, address=0xd2000 +#optromimage4: file=optionalrom.bin, address=0xd3000 + +#optramimage1: file=/path/file1.img, address=0x0010000 +#optramimage2: file=/path/file2.img, address=0x0020000 +#optramimage3: file=/path/file3.img, address=0x0030000 +#optramimage4: file=/path/file4.img, address=0x0040000 + +#======================================================================= +# VGA: +# This defines parameters related to the VGA display +# +# EXTENSION +# Here you can specify the display extension to be used. With the value +# 'none' you can use standard VGA with no extension. Other supported +# values are 'vbe' for Bochs VBE, 'cirrus' for Cirrus SVGA support and +# 'voodoo' for Voodoo Graphics support (see 'voodoo' option). +# +# UPDATE_FREQ +# This parameter specifies the number of display updates per second. +# The VGA update timer by default uses the realtime engine with a value +# of 5. This parameter can be changed at runtime. +# +# REALTIME +# If set to 1 (default), the VGA timer is based on realtime, otherwise it +# is driven by the cpu and depends on the ips setting. If the host is slow +# (low ips, update_freq) and the guest uses HLT appropriately, setting this +# to 0 and "clock: sync=none" may improve the responsiveness of the guest +# GUI when the guest is otherwise idle. +# +# Examples: +# vga: extension=cirrus, update_freq=10 +#======================================================================= +vga: extension=vbe, update_freq=5, realtime=1 + +#======================================================================= +# VOODOO: +# This defines the Voodoo Graphics emulation (experimental). Currently +# supported models are 'voodoo1', 'voodoo2', 'banshee' and 'voodoo3'. The +# Voodoo2 support is not yet complete, but almost usable. The Banshee and +# Voodoo3 support is under construction, but basicly usable. The 2D/3D cards +# require an external VGA BIOS the vga extension option to be set to 'voodoo'. +# If the i440BX PCI chipset is selected, they can be assigned to AGP (slot #5). +# The gui screen update timing for all models is controlled by the related 'vga' +# options. +# +# Examples: +# voodoo: enabled=1, model=voodoo2 +#======================================================================= +#voodoo: enabled=1, model=voodoo1 + +#======================================================================= +# KEYBOARD: +# This defines parameters related to the emulated keyboard +# +# TYPE: +# Type of keyboard return by a "identify keyboard" command to the +# keyboard controller. It must be one of "xt", "at" or "mf". +# Defaults to "mf". It should be ok for almost everybody. A known +# exception is french macs, that do have a "at"-like keyboard. +# +# SERIAL_DELAY: +# Approximate time in microseconds that it takes one character to +# be transferred from the keyboard to controller over the serial path. +# +# PASTE_DELAY: +# Approximate time in microseconds between attempts to paste +# characters to the keyboard controller. This leaves time for the +# guest os to deal with the flow of characters. The ideal setting +# depends on how your operating system processes characters. The +# default of 100000 usec (.1 seconds) was chosen because it works +# consistently in Windows. +# If your OS is losing characters during a paste, increase the paste +# delay until it stops losing characters. +# +# KEYMAP: +# This enables a remap of a physical localized keyboard to a +# virtualized us keyboard, as the PC architecture expects. +# +# USER_SHORTCUT: +# This defines the keyboard shortcut to be sent when you press the "user" +# button in the headerbar. The shortcut string is a combination of maximum +# 3 key names (listed below) separated with a '-' character. +# Valid key names: +# "alt", "bksl", "bksp", "ctrl", "del", "down", "end", "enter", "esc", +# "f1", ... "f12", "home", "ins", "left", "menu", "minus", "pgdwn", "pgup", +# "plus", "power", "print", "right", "scrlck", "shift", "space", "tab", "up" +# and "win". + +# Examples: +# keyboard: type=mf, serial_delay=200, paste_delay=100000 +# keyboard: keymap=gui/keymaps/x11-pc-de.map +# keyboard: user_shortcut=ctrl-alt-del +#======================================================================= +keyboard: type=mf, serial_delay=250 + +#======================================================================= +# MOUSE: +# This defines parameters for the emulated mouse type, the initial status +# of the mouse capture and the runtime method to toggle it. +# +# TYPE: +# With the mouse type option you can select the type of mouse to emulate. +# The default value is 'ps2'. The other choices are 'imps2' (wheel mouse +# on PS/2), 'serial', 'serial_wheel', 'serial_msys' (one com port requires +# setting 'mode=mouse') 'inport' and 'bus' (if present). To connect a mouse +# to a USB port, see the 'usb_uhci', 'usb_ohci', 'usb_ehci' or 'usb_xhci' +# options (requires PCI and USB support). +# +# ENABLED: +# The Bochs gui creates mouse "events" unless the 'enabled' option is +# set to 0. The hardware emulation itself is not disabled by this. +# Unless you have a particular reason for enabling the mouse by default, +# it is recommended that you leave it off. You can also toggle the mouse +# usage at runtime (RFB, SDL, Win32, wxWidgets and X11 - see below). +# +# TOGGLE: +# The default method to toggle the mouse capture at runtime is to press the +# CTRL key and the middle mouse button ('ctrl+mbutton'). This option allows +# to change the method to 'ctrl+f10' (like DOSBox), 'ctrl+alt' (like QEMU) +# or 'f12'. +# +# Examples: +# mouse: enabled=1 +# mouse: type=imps2, enabled=1 +# mouse: type=serial, enabled=1 +# mouse: enabled=0, toggle=ctrl+f10 +#======================================================================= +mouse: enabled=1 + +#======================================================================= +# PCI: +# This option controls the presence of a PCI chipset in Bochs. Currently it +# supports the i430FX, i440FX and i440BX chipsets. You can also specify the +# devices connected to PCI slots. Up to 5 slots are available. For these +# combined PCI/ISA devices assigning to slot is mandatory if you want to emulate +# the PCI model: cirrus, ne2k and pcivga. These PCI-only devices are also +# supported, but they are auto-assigned if you don't use the slot configuration: +# e1000, es1370, pcidev, pcipnic, usb_ehci, usb_ohci, usb_xhci and voodoo. +# In case of the i440BX chipset, slot #5 is the AGP slot. Currently only the +# 'voodoo' device can be assigned to AGP. +# +# Example: +# pci: enabled=1, chipset=i440fx, slot1=pcivga, slot2=ne2k +#======================================================================= +pci: enabled=1, chipset=i440fx + +#======================================================================= +# CLOCK: +# This defines the parameters of the clock inside Bochs: +# +# SYNC: +# This defines the method how to synchronize the Bochs internal time +# with realtime. With the value 'none' the Bochs time relies on the IPS +# value and no host time synchronization is used. The 'slowdown' method +# sacrifices performance to preserve reproducibility while allowing host +# time correlation. The 'realtime' method sacrifices reproducibility to +# preserve performance and host-time correlation. +# It is possible to enable both synchronization methods. +# +# RTC_SYNC: +# If this option is enabled together with the realtime synchronization, +# the RTC runs at realtime speed. This feature is disabled by default. +# +# TIME0: +# Specifies the start (boot) time of the virtual machine. Use a time +# value as returned by the time(2) system call or a string as returned +# by the ctime(3) system call. If no time0 value is set or if time0 +# equal to 1 (special case) or if time0 equal 'local', the simulation +# will be started at the current local host time. If time0 equal to 2 +# (special case) or if time0 equal 'utc', the simulation will be started +# at the current utc time. +# +# Syntax: +# clock: sync=[none|slowdown|realtime|both], time0=[timeValue|local|utc] +# +# Example: +# clock: sync=none, time0=local # Now (localtime) +# clock: sync=slowdown, time0=315529200 # Tue Jan 1 00:00:00 1980 +# clock: sync=none, time0="Mon Jan 1 00:00:00 1990" # 631148400 +# clock: sync=realtime, time0=938581955 # Wed Sep 29 07:12:35 1999 +# clock: sync=realtime, time0="Sat Jan 1 00:00:00 2000" # 946681200 +# clock: sync=none, time0=1 # Now (localtime) +# clock: sync=none, time0=utc # Now (utc/gmt) +# +# Default value are sync=none, rtc_sync=0, time0=local +#======================================================================= +clock: sync=slowdown, time0=315529200 + +#======================================================================= +# CMOSIMAGE: +# This defines a binary image file with size 128 bytes that can be loaded into +# the CMOS RAM at startup. The rtc_init parameter controls whether initialize +# the RTC with values stored in the image. By default the time0 argument given +# to the clock option is used. With 'rtc_init=image' the image is the source +# for the initial time. +# +# Example: +# cmosimage: file=cmos.img, rtc_init=image +#======================================================================= +#cmosimage: file=cmos.img, rtc_init=time0 + +#======================================================================= +# private_colormap: Request that the GUI create and use it's own +# non-shared colormap. This colormap will be used +# when in the bochs window. If not enabled, a +# shared colormap scheme may be used. Not implemented +# on all GUI's. +# +# Examples: +# private_colormap: enabled=1 +# private_colormap: enabled=0 +#======================================================================= +private_colormap: enabled=0 + +#======================================================================= +# FLOPPYA: +# Point this to pathname of floppy image file or device +# This should be of a bootable floppy(image/device) if you're +# booting from 'a' (or 'floppy'). +# +# You can set the initial status of the media to 'ejected' or 'inserted'. +# floppya: 2_88=path, status=ejected (2.88M 3.5" media) +# floppya: 1_44=path, status=inserted (1.44M 3.5" media) +# floppya: 1_2=path, status=ejected (1.2M 5.25" media) +# floppya: 720k=path, status=inserted (720K 3.5" media) +# floppya: 360k=path, status=inserted (360K 5.25" media) +# floppya: 320k=path, status=inserted (320K 5.25" media) +# floppya: 180k=path, status=inserted (180K 5.25" media) +# floppya: 160k=path, status=inserted (160K 5.25" media) +# floppya: image=path, status=inserted (guess media type from image size) +# floppya: 1_44=vvfat:path, status=inserted (use directory as VFAT media) +# floppya: type=1_44 (1.44M 3.5" floppy drive, no media) +# +# The path should be the name of a disk image file. On Unix, you can use a raw +# device name such as /dev/fd0 on Linux. On win32 platforms, use drive letters +# such as a: or b: as the path. The parameter 'image' works with image files +# only. In that case the size must match one of the supported types. +# The parameter 'type' can be used to enable the floppy drive without media +# and status specified. Usually the drive type is set up based on the media type. +# The optional parameter 'write_protected' can be used to control the media +# write protect switch. By default it is turned off. +#======================================================================= +#floppya: 1_44=, status=inserted +#floppya: image=../1.44, status=inserted +#floppya: 1_44=/dev/fd0H1440, status=inserted +#floppya: 1_2=../1_2, status=inserted +#floppya: 1_44=a:, status=inserted +#floppya: 1_44=a.img, status=inserted, write_protected=1 +#floppya: 1_44=/dev/rfd0a, status=inserted +#floppya: 1_44=boot.img, status=inserted, write_protected=1 + +#======================================================================= +# FLOPPYB: +# See FLOPPYA above for syntax +#======================================================================= +#floppyb: 1_44=b:, status=inserted +#floppyb: 1_44=b.img, status=inserted + +#======================================================================= +# ATA0, ATA1, ATA2, ATA3 +# ATA controller for hard disks and cdroms +# +# ata[0-3]: enabled=[0|1], ioaddr1=addr, ioaddr2=addr, irq=number +# +# These options enables up to 4 ata channels. For each channel +# the two base io addresses and the irq must be specified. +# +# ata0 and ata1 are enabled by default with the values shown below +# +# Examples: +# ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 +# ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15 +# ata2: enabled=1, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11 +# ata3: enabled=1, ioaddr1=0x168, ioaddr2=0x360, irq=9 +#======================================================================= +ata0: enabled=0, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 +ata1: enabled=0, ioaddr1=0x170, ioaddr2=0x370, irq=15 +ata2: enabled=0, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11 +ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x360, irq=9 + +#======================================================================= +# ATA[0-3]-MASTER, ATA[0-3]-SLAVE +# +# This defines the type and characteristics of all attached ata devices: +# type= type of attached device [disk|cdrom] +# mode= only valid for disks [flat|concat|external|dll|sparse|vmware3] +# [vmware4|undoable|growing|volatile|vpc] +# [vbox|vvfat] +# path= path of the image / directory +# cylinders= only valid for disks +# heads= only valid for disks +# spt= only valid for disks +# status= only valid for cdroms [inserted|ejected] +# biosdetect= type of biosdetection [auto|cmos|none] +# translation=type of translation of the bios, only for disks [none|lba|large|rechs|auto] +# model= string returned by identify device command +# journal= optional filename of the redolog for undoable, volatile and vvfat disks +# +# Point this at a hard disk image file, cdrom iso file, or physical cdrom +# device. To create a hard disk image, try running bximage. It will help you +# choose the size and then suggest a line that works with it. +# +# In UNIX it may be possible to use a raw device as a Bochs hard disk, +# but WE DON'T RECOMMEND IT. In Windows there is no easy way. +# +# In windows, the drive letter + colon notation should be used for cdroms. +# Depending on versions of windows and drivers, you may only be able to +# access the "first" cdrom in the system. On MacOSX, use path="drive" +# to access the physical drive. +# +# The path is mandatory for hard disks. Disk geometry autodetection works with +# images created by bximage if CHS is set to 0/0/0 (cylinders are calculated +# using heads=16 and spt=63). For other hard disk images and modes the +# cylinders, heads, and spt are mandatory. In all cases the disk size reported +# from the image must be exactly C*H*S*512. +# +# Default values are: +# mode=flat, biosdetect=auto, translation=auto, model="Generic 1234" +# +# The biosdetect option has currently no effect on the bios +# +# Examples: +# ata0-master: type=disk, mode=flat, path=10M.sample, cylinders=306, heads=4, spt=17 +# ata0-slave: type=disk, mode=flat, path=20M.sample, cylinders=615, heads=4, spt=17 +# ata1-master: type=disk, mode=flat, path=30M.sample, cylinders=615, heads=6, spt=17 +# ata1-slave: type=disk, mode=flat, path=46M.sample, cylinders=940, heads=6, spt=17 +# ata2-master: type=disk, mode=flat, path=62M.sample, cylinders=940, heads=8, spt=17 +# ata2-slave: type=disk, mode=flat, path=112M.sample, cylinders=900, heads=15, spt=17 +# ata3-master: type=disk, mode=flat, path=483M.sample, cylinders=1024, heads=15, spt=63 +# ata3-slave: type=cdrom, path=iso.sample, status=inserted +#======================================================================= +#ata0-master: type=disk, mode=flat, path="30M.sample" +#ata0-master: type=disk, mode=flat, path="30M.sample", cylinders=615, heads=6, spt=17 +#ata0-master: type=disk, mode=flat, path="c.img", cylinders=0 # autodetect +#ata0-slave: type=disk, mode=vvfat, path=/bochs/images/vvfat, journal=vvfat.redolog +#ata0-slave: type=cdrom, path=D:, status=inserted +#ata0-slave: type=cdrom, path=/dev/cdrom, status=inserted +#ata0-slave: type=cdrom, path="drive", status=inserted +#ata0-slave: type=cdrom, path=/dev/rcd0d, status=inserted + +#======================================================================= +# BOOT: +# This defines the boot sequence. Now you can specify up to 3 boot drives, +# which can be 'floppy', 'disk', 'cdrom' or 'network' (boot ROM). +# Legacy 'a' and 'c' are also supported. +# Examples: +# boot: floppy +# boot: cdrom, disk +# boot: network, disk +# boot: cdrom, floppy, disk +#======================================================================= +boot: floppy +#boot: disk + +#======================================================================= +# FLOPPY_BOOTSIG_CHECK: disabled=[0|1] +# Enables or disables the 0xaa55 signature check on boot floppies +# Defaults to disabled=0 +# Examples: +# floppy_bootsig_check: disabled=0 +# floppy_bootsig_check: disabled=1 +#======================================================================= +floppy_bootsig_check: disabled=0 + +#======================================================================= +# LOG: +# Give the path of the log file you'd like Bochs debug and misc. verbiage +# to be written to. If you don't use this option or set the filename to +# '-' the output is written to the console. If you really don't want it, +# make it "/dev/null" (Unix) or "nul" (win32). :^( +# +# Examples: +# log: ./bochs.out +# log: /dev/tty +#======================================================================= +#log: /dev/null +log: .bochs.log + +#======================================================================= +# LOGPREFIX: +# This handles the format of the string prepended to each log line. +# You may use those special tokens : +# %t : 11 decimal digits timer tick +# %i : 8 hexadecimal digits of cpu current eip (ignored in SMP configuration) +# %e : 1 character event type ('i'nfo, 'd'ebug, 'p'anic, 'e'rror) +# %d : 5 characters string of the device, between brackets +# +# Default : %t%e%d +# Examples: +# logprefix: %t-%e-@%i-%d +# logprefix: %i%e%d +#======================================================================= +logprefix: %t%e%d + +#======================================================================= +# LOG CONTROLS +# +# Bochs has four severity levels for event logging. +# panic: cannot proceed. If you choose to continue after a panic, +# don't be surprised if you get strange behavior or crashes. +# error: something went wrong, but it is probably safe to continue the +# simulation. +# info: interesting or useful messages. +# debug: messages useful only when debugging the code. This may +# spit out thousands per second. +# +# For events of each level, you can choose to exit Bochs ('fatal'), 'ask', +# 'warn', 'report' or 'ignore'. The choices 'ask' and 'warn' are not supported +# by all guis, since they should bring up a dialog box. The 'warn' dialog is +# designed to confirm errors and the 'ask' dialog is usually used for panics +# and asks the user how to proceed. +# +# It is also possible to specify the 'action' to do for each Bochs facility +# separately (e.g. crash on panics from everything except the cdrom, and only +# report those). See the 'log function' module list in the user documentation. +# +# If you are experiencing many panics, it can be helpful to change +# the panic action to report instead of fatal. However, be aware +# that anything executed after a panic is uncharted territory and can +# cause bochs to become unstable. The panic is a "graceful exit," so +# if you disable it you may get a spectacular disaster instead. +#======================================================================= +panic: action=ask +error: action=report +info: action=report +debug: action=ignore #, pci=report # report BX_DEBUG from module 'pci' + +#======================================================================= +# DEBUGGER_LOG: +# Give the path of the log file you'd like Bochs to log debugger output. +# If you really don't want it, make it /dev/null or '-'. :^( +# +# Examples: +# debugger_log: ./debugger.out +#======================================================================= +#debugger_log: /dev/null +#debugger_log: debugger.out +debugger_log: - + +#======================================================================= +# COM1, COM2, COM3, COM4: +# This defines a serial port (UART type 16550A). In the 'term' mode you can +# specify a device to use as com1. This can be a real serial line, or a pty. +# To use a pty (under X/Unix), create two windows (xterms, usually). One of +# them will run bochs, and the other will act as com1. Find out the tty the com1 +# window using the `tty' command, and use that as the `dev' parameter. +# Then do `sleep 1000000' in the com1 window to keep the shell from +# messing with things, and run bochs in the other window. Serial I/O to +# com1 (port 0x3f8) will all go to the other window. +# In socket* and pipe* (win32 only) modes Bochs becomes either socket/named pipe +# client or server. In client mode it connects to an already running server (if +# connection fails Bochs treats com port as not connected). In server mode it +# opens socket/named pipe and waits until a client application connects to it +# before starting simulation. This mode is useful for remote debugging (e.g. +# with gdb's "target remote host:port" command or windbg's command line option +# -k com:pipe,port=\\.\pipe\pipename). Socket modes use simple TCP communication, +# pipe modes use duplex byte mode pipes. +# Other serial modes are 'null' (no input/output), 'file' (output to a file +# specified as the 'dev' parameter and changeable at runtime), 'raw' (use the +# real serial port - partly implemented on win32), 'mouse' (standard serial +# mouse - requires mouse option setting 'type=serial', 'type=serial_wheel' or +# 'type=serial_msys'). +# +# Examples: +# com1: enabled=1, mode=null +# com1: enabled=1, mode=mouse +# com2: enabled=1, mode=file, dev=serial.out +# com3: enabled=1, mode=raw, dev=com1 +# com3: enabled=1, mode=socket-client, dev=localhost:8888 +# com3: enabled=1, mode=socket-server, dev=localhost:8888 +# com4: enabled=1, mode=pipe-client, dev=\\.\pipe\mypipe +# com4: enabled=1, mode=pipe-server, dev=\\.\pipe\mypipe +#======================================================================= +com1: enabled=1, mode=file, dev=/dev/stdout + +#======================================================================= +# PARPORT1, PARPORT2: +# This defines a parallel (printer) port. When turned on and an output file is +# defined the emulated printer port sends characters printed by the guest OS +# into the output file. On some platforms a device filename can be used to +# send the data to the real parallel port (e.g. "/dev/lp0" on Linux, "lpt1" on +# win32 platforms). The output file can be changed at runtime. +# +# Examples: +# parport1: enabled=1, file="parport.out" +# parport2: enabled=1, file="/dev/lp0" +# parport1: enabled=0 +#======================================================================= +#parport1: enabled=1, file="parport.out" + +#======================================================================= +# SOUND: +# This defines the lowlevel sound driver(s) for the wave (PCM) input / output +# and the MIDI output feature and (if necessary) the devices to be used. +# It can have several of the following properties. +# All properties are in the format sound: property=value +# +# waveoutdrv: +# This defines the driver to be used for the waveout feature. +# Possible values are 'file' (all wave data sent to file), 'dummy' (no +# output) and the platform-dependant drivers 'alsa', 'oss', 'osx', 'sdl' +# and 'win'. +# waveout: +# This defines the device to be used for wave output (if necessary) or +# the output file for the 'file' driver. +# waveindrv: +# This defines the driver to be used for the wavein feature. +# Possible values are 'dummy' (recording silence) and platform-dependent +# drivers 'alsa', 'oss', 'sdl' and 'win'. +# wavein: +# This defines the device to be used for wave input (if necessary). +# midioutdrv: +# This defines the driver to be used for the MIDI output feature. +# Possible values are 'file' (all MIDI data sent to file), 'dummy' (no +# output) and platform-dependent drivers 'alsa', 'oss', 'osx' and 'win'. +# midiout: +# This defines the device to be used for MIDI output (if necessary). +# driver: +# This defines the driver to be used for all sound features with one +# property. Possible values are 'default' (platform default) and all +# other choices described above. Overriding one or more settings with +# the specific driver parameter is possible. +# +# Example for different drivers: +# sound: waveoutdrv=sdl, waveindrv=alsa, midioutdrv=dummy +#======================================================================= +#sound: driver=default, waveout=/dev/dsp. wavein=, midiout= + +#======================================================================= +# SPEAKER: +# This defines the PC speaker output mode. In the 'sound' mode the beep +# is generated by the square wave generator which is a part of the +# lowlevel sound support. The 'system' mode is only available on Linux +# and Windows. On Linux /dev/console is used for output and on Windows +# the Beep() function. The 'gui' mode forwards the beep to the related +# gui methods (currently only used by the Carbon gui). +#======================================================================= +#speaker: enabled=0, mode=sound + +#======================================================================= +# SB16: +# This defines the SB16 sound emulation. It can have several of the +# following properties. +# All properties are in the format sb16: property=value +# +# enabled: +# This optional property controls the presence of the SB16 emulation. +# The emulation is turned on unless this property is used and set to 0. +# midimode: This parameter specifies what to do with the MIDI output. +# 0 = no output +# 1 = output to device specified with the sound option (system dependent) +# 2 = MIDI or raw data output to file (depends on file name extension) +# 3 = dual output (mode 1 and 2 at the same time) +# midifile: This is the file where the midi output is stored (midimode 2 or 3). +# wavemode: This parameter specifies what to do with the PCM output. +# 0 = no output +# 1 = output to device specified with the sound option (system dependent) +# 2 = VOC, WAV or raw data output to file (depends on file name extension) +# 3 = dual output (mode 1 and 2 at the same time) +# wavefile: This is the file where the wave output is stored (wavemode 2 or 3). +# loglevel: +# 0=no log +# 1=resource changes, midi program and bank changes +# 2=severe errors +# 3=all errors +# 4=all errors plus all port accesses +# 5=all errors and port accesses plus a lot of extra info +# log: The file to write the sb16 emulator messages to. +# dmatimer: +# microseconds per second for a DMA cycle. Make it smaller to fix +# non-continuous sound. 750000 is usually a good value. This needs a +# reasonably correct setting for the IPS parameter of the CPU option. +# +# Examples for output modes: +# sb16: midimode=2, midifile="output.mid", wavemode=1 # MIDI to file +# sb16: midimode=1, wavemode=3, wavefile="output.wav" # wave to file and device +#======================================================================= +#sb16: midimode=1, wavemode=1, loglevel=2, log=sb16.log, dmatimer=600000 + +#======================================================================= +# ES1370: +# This defines the ES1370 sound emulation (recording and playback - except +# DAC1+DAC2 output at the same time). The parameter 'enabled' controls the +# presence of the device. The wave and MIDI output can be sent to device, file +# or both using the parameters 'wavemode', 'wavefile', 'midimode' and +# 'midifile'. See the description of these parameters at the SB16 directive. +# +# Examples: +# es1370: enabled=1, wavemode=1 # use 'sound' parameters +# es1370: enabled=1, wavemode=2, wavefile=output.voc # send output to file +#======================================================================= +#es1370: enabled=1, wavemode=1 + +#======================================================================= +# ne2k: NE2000 compatible ethernet adapter +# +# Format: +# ne2k: enabled=1, ioaddr=IOADDR, irq=IRQ, mac=MACADDR, ethmod=MODULE, +# ethdev=DEVICE, script=SCRIPT, bootrom=BOOTROM +# +# IOADDR, IRQ: You probably won't need to change ioaddr and irq, unless there +# are IRQ conflicts. These arguments are ignored when assign the ne2k to a +# PCI slot. +# +# MAC: The MAC address MUST NOT match the address of any machine on the net. +# Also, the first byte must be an even number (bit 0 set means a multicast +# address), and you cannot use ff:ff:ff:ff:ff:ff because that's the broadcast +# address. For the ethertap module, you must use fe:fd:00:00:00:01. There may +# be other restrictions too. To be safe, just use the b0:c4... address. +# +# ETHDEV: The ethdev value is the name of the network interface on your host +# platform. On UNIX machines, you can get the name by running ifconfig. On +# Windows machines, you must run niclist to get the name of the ethdev. +# Niclist source code is in misc/niclist.c and it is included in Windows +# binary releases. +# The 'socket' module uses this parameter to specify the UDP port for +# receiving packets and (optional) the host to connect. +# +# SCRIPT: The script value is optional, and is the name of a script that +# is executed after bochs initialize the network interface. You can use +# this script to configure this network interface, or enable masquerading. +# This is mainly useful for the tun/tap devices that only exist during +# Bochs execution. The network interface name is supplied to the script +# as first parameter. +# The 'slirp' module uses this parameter to specify a config file for +# setting up an alternative IP configuration or additional features. +# The 'vnet' module uses this parameter to specify an alternative +# log file name. +# +# BOOTROM: The bootrom value is optional, and is the name of the ROM image +# to load. Note that this feature is only implemented for the PCI version of +# the NE2000. +# +# If you don't want to make connections to any physical networks, +# you can use the following 'ethmod's to simulate a virtual network. +# null: All packets are discarded, but logged to a few files. +# vde: Virtual Distributed Ethernet +# vnet: ARP, ICMP-echo(ping), DHCP and read/write TFTP are simulated. +# The virtual host uses 192.168.10.1. +# DHCP assigns 192.168.10.2 to the guest. +# TFTP uses the 'ethdev' value for the root directory and doesn't +# overwrite files. +# socket: Connect up to 6 Bochs instances with external program 'bxhub' +# (simulating an ethernet hub). It provides the same services as the +# 'vnet' module and assigns IP addresses like 'slirp' (10.0.2.x). +# +#======================================================================= +# ne2k: ioaddr=0x300, irq=9, mac=fe:fd:00:00:00:01, ethmod=fbsd, ethdev=en0 #macosx +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:00, ethmod=fbsd, ethdev=xl0 +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:00, ethmod=linux, ethdev=eth0 +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=win32, ethdev=MYCARD +# ne2k: ioaddr=0x300, irq=9, mac=fe:fd:00:00:00:01, ethmod=tap, ethdev=tap0 +# ne2k: ioaddr=0x300, irq=9, mac=fe:fd:00:00:00:01, ethmod=tuntap, ethdev=/dev/net/tun0, script=./tunconfig +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=null, ethdev=eth0 +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=vde, ethdev="/tmp/vde.ctl" +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=vnet, ethdev="c:/temp" +# ne2k: mac=b0:c4:20:00:00:01, ethmod=socket, ethdev=40000 # use localhost +# ne2k: mac=b0:c4:20:00:00:01, ethmod=socket, ethdev=mymachine:40000 +# ne2k: mac=b0:c4:20:00:00:01, ethmod=slirp, script=slirp.conf, bootrom=ne2k_pci.rom + +#======================================================================= +# pcipnic: Bochs/Etherboot pseudo-NIC +# +# Format: +# pcipnic: enabled=1, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE, script=SCRIPT, +# bootrom=BOOTROM +# +# The pseudo-NIC accepts the same syntax (for mac, ethmod, ethdev, script, +# bootrom) and supports the same networking modules as the NE2000 adapter. +#======================================================================= +#pcipnic: enabled=1, mac=b0:c4:20:00:00:00, ethmod=vnet + +#======================================================================= +# e1000: Intel(R) 82540EM Gigabit Ethernet adapter +# +# Format: +# e1000: enabled=1, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE, script=SCRIPT +# bootrom=BOOTROM +# +# The E1000 accepts the same syntax (for mac, ethmod, ethdev, script, bootrom) +# and supports the same networking modules as the NE2000 adapter. +#======================================================================= +#e1000: enabled=1, mac=52:54:00:12:34:56, ethmod=slirp, script=slirp.conf + +#======================================================================= +# USB_UHCI: +# This option controls the presence of the USB root hub which is a part +# of the i440FX PCI chipset. With the portX parameter you can connect devices +# to the hub (currently supported: 'mouse', 'tablet', 'keypad', 'disk', 'cdrom', +# 'floppy', 'hub' and 'printer'). +# +# If you connect the mouse or tablet to one of the ports, Bochs forwards the +# mouse movement data to the USB device instead of the selected mouse type. +# When connecting the keypad to one of the ports, Bochs forwards the input of +# the numeric keypad to the USB device instead of the PS/2 keyboard. +# +# To connect a 'flat' mode image as a USB hardisk you can use the 'disk' device +# with the path to the image separated with a colon. To use other disk image modes +# similar to ATA disks the syntax 'disk:mode:filename' must be used (see below). +# +# To emulate a USB cdrom you can use the 'cdrom' device name and the path to +# an ISO image or raw device name also separated with a colon. An option to +# insert/eject media is available in the runtime configuration. +# +# To emulate a USB floppy you can use the 'floppy' device with the path to the +# image separated with a colon. To use the VVFAT image mode similar to the +# legacy floppy the syntax 'floppy:vvfat:directory' must be used (see below). +# An option to insert/eject media is available in the runtime configuration. +# +# The device name 'hub' connects an external hub with max. 8 ports (default: 4) +# to the root hub. To specify the number of ports you have to add the value +# separated with a colon. Connecting devices to the external hub ports is only +# available in the runtime configuration. +# +# The device 'printer' emulates the HP Deskjet 920C printer. The PCL data is +# sent to a file specified in bochsrc.txt. The current code appends the PCL +# code to the file if the file already existed. The output file can be +# changed at runtime. +# +# The optionsX parameter can be used to assign specific options to the device +# connected to the corresponding USB port. Currently this feature is used to +# set the speed reported by device ('low', 'full', 'high' or 'super'). The +# availabe speed choices depend on both HC and device. The option 'debug' turns +# on debug output for the device at connection time. +# For the USB 'disk' device the optionsX parameter can be used to specify an +# alternative redolog file (journal) of some image modes. For 'vvfat' mode USB +# disks the optionsX parameter can be used to specify the disk size (range +# 128M ... 128G). If the size is not specified, it defaults to 504M. +# For the USB 'floppy' device the optionsX parameter can be used to specify an +# alternative device ID to be reported. Currently only the model "teac" is +# supported (can fix hw detection in some guest OS). The USB floppy also +# accepts the parameter "write_protected" with valid values 0 and 1 to select +# the access mode (default is 0). +#======================================================================= +#usb_uhci: enabled=1 +#usb_uhci: enabled=1, port1=mouse, port2=disk:usbstick.img +#usb_uhci: enabled=1, port1=hub:7, port2=disk:growing:usbdisk.img +#usb_uhci: enabled=1, port2=disk:undoable:usbdisk.img, options2=journal:redo.log +#usb_uhci: enabled=1, port2=disk:usbdisk2.img, options2=sect_size:1024 +#usb_uhci: enabled=1, port2=disk:vvfat:vvfat, options2="debug,speed:full" +#usb_uhci: enabled=1, port1=printer:printdata.bin, port2=cdrom:image.iso +#usb_uhci: enabled=1, port2=floppy:vvfat:diskette, options2="model:teac" + +#======================================================================= +# USB_OHCI: +# This option controls the presence of the USB OHCI host controller with a +# 2-port hub. The portX parameter accepts the same device types with the same +# syntax as the UHCI controller (see above). The optionsX parameter is also +# available on OHCI. +#======================================================================= +#usb_ohci: enabled=1 +#usb_ohci: enabled=1, port1=printer:usbprinter.bin + +#======================================================================= +# USB_EHCI: +# This option controls the presence of the USB EHCI host controller with a +# 6-port hub. The portX parameter accepts the same device types with the +# same syntax as the UHCI controller (see above). The optionsX parameter is +# also available on EHCI. +#======================================================================= +#usb_ehci: enabled=1 + +#======================================================================= +# USB_XHCI: +# This option controls the presence of the USB xHCI host controller with a +# 4-port hub. The portX parameter accepts the same device types with the +# same syntax as the UHCI controller (see above). The optionsX parameter is +# also available on xHCI. NOTE: port 1 and 2 are USB3 and only support +# super-speed devices, but port 3 and 4 are USB2 and support speed settings +# low, full and high. +#======================================================================= +#usb_xhci: enabled=1 + +#======================================================================= +# PCIDEV: +# PCI host device mapping +# WARNING: This Bochs feature is not maintained yet and may fail. +#======================================================================= +#pcidev: vendor=0x1234, device=0x5678 + +#======================================================================= +# GDBSTUB: +# Enable GDB stub. See user documentation for details. +# Default value is enabled=0. +# WARNING: This Bochs feature is not maintained yet and may fail. +#======================================================================= +#gdbstub: enabled=0, port=1234, text_base=0, data_base=0, bss_base=0 + +#======================================================================= +# MAGIC_BREAK: +# This enables the "magic breakpoint" feature when using the debugger. +# The useless cpu instruction XCHG BX, BX causes Bochs to enter the +# debugger mode. This might be useful for software development. +# +# Example: +# magic_break: enabled=1 +#======================================================================= +magic_break: enabled=1 + +#======================================================================= +# DEBUG_SYMBOLS: +# This loads symbols from the specified file for use in Bochs' internal +# debugger. Symbols are loaded into global context. This is equivalent to +# issuing ldsym debugger command at start up. +# +# Example: +# debug_symbols: file="kernel.sym" +# debug_symbols: file="kernel.sym", offset=0x80000000 +#======================================================================= +#debug_symbols: file="kernel.sym" + +#print_timestamps: enabled=1 + +#======================================================================= +# PORT_E9_HACK: +# The 0xE9 port doesn't exists in normal ISA architecture. However, we +# define a convention here, to display on the console of the system running +# Bochs anything that is written to it. The idea is to provide debug output +# very early when writing BIOS or OS code for example, without having to +# bother with setting up a serial port or etc. Reading from port 0xE9 will +# will return 0xe9 to let you know if the feature is available. +# Leave this 0 unless you have a reason to use it. +# +# Example: +# port_e9_hack: enabled=1 +#======================================================================= +#port_e9_hack: enabled=1 + +#======================================================================= +# other stuff +#======================================================================= +# WARNING: This Bochs feature is not maintained yet. Is it still used ? +# To use it, set BX_LOAD32BITOSHACK in config.h to 1 and recompile Bochs. +#load32bitOSImage: os=nullkernel, path=../kernel.img, iolog=../vga_io.log +#load32bitOSImage: os=linux, path=../linux.img, iolog=../vga_io.log, initrd=../initrd.img + +#======================================================================= +# fullscreen: ONLY IMPLEMENTED ON AMIGA +# Request that Bochs occupy the entire screen instead of a +# window. +# +# Examples: +# fullscreen: enabled=0 +# fullscreen: enabled=1 +#======================================================================= +#fullscreen: enabled=0 +#screenmode: name="sample" + +#======================================================================= +# USER_PLUGIN: +# Load user-defined plugin. This option is available only if Bochs is +# compiled with plugin support. Maximum 8 different plugins are supported. +# See the example in the Bochs sources how to write a plugin device. +#======================================================================= +#user_plugin: name=testdev + +#======================================================================= +# for Macintosh, use the style of pathnames in the following +# examples. +# +# vgaromimage: :bios:VGABIOS-elpin-2.40 +# romimage: file=:bios:BIOS-bochs-latest, address=0xf0000 +# floppya: 1_44=[fd:], status=inserted +#======================================================================= + +#======================================================================= +# MEGS +# Set the number of Megabytes of physical memory you want to emulate. +# The default is 32MB, most OS's won't need more than that. +# The maximum amount of memory supported is 2048Mb. +# The 'MEGS' option is deprecated. Use 'MEMORY' option instead. +#======================================================================= +#megs: 256 +#megs: 128 +#megs: 64 +#megs: 32 +#megs: 16 +#megs: 8 diff --git a/ape/etc/bochsrc.ffs b/ape/etc/bochsrc.ffs new file mode 100644 index 00000000..3467144e --- /dev/null +++ b/ape/etc/bochsrc.ffs @@ -0,0 +1,1294 @@ +# The default state is the unsafest state with Bochs, which makes it nearly +# impossible to script. Here we'll attempt to turn off as much of its +# functionality as possible, so we can have a non-interactive mode. + +#======================================================================= +# PLUGIN_CTRL: +# Controls the presence of optional device plugins. These plugins are loaded +# directly with this option and some of them install a config option that is +# only available when the plugin device is loaded. The value "1" means to load +# the plugin and "0" will unload it (if loaded before). +# +# These plugins will be loaded by default (if present): 'biosdev', 'extfpuirq', +# 'gameport', 'iodebug','parallel', 'serial', 'speaker' and 'unmapped'. +# +# These plugins are also supported, but they are usually loaded directly with +# their bochsrc option: 'e1000', 'es1370', 'ne2k', 'pcidev', 'pcipnic', 'sb16', +# 'usb_ehci', 'usb_ohci', 'usb_uhci', 'usb_xhci' and 'voodoo'. +#======================================================================= +#plugin_ctrl: unmapped=0, e1000=1 # unload 'unmapped' and load 'e1000' +plugin_ctrl: biosdev=0, iodebug=0 + +#======================================================================= +# CONFIG_INTERFACE +# +# The configuration interface is a series of menus or dialog boxes that +# allows you to change all the settings that control Bochs's behavior. +# Depending on the platform there are up to 3 choices of configuration +# interface: a text mode version called "textconfig" and two graphical versions +# called "win32config" and "wx". The text mode version uses stdin/stdout and +# is always compiled in, unless Bochs is compiled for wx only. The choice +# "win32config" is only available on win32 and it is the default there. +# The choice "wx" is only available when you use "--with-wx" on the configure +# command. If you do not write a config_interface line, Bochs will +# choose a default for you. +# +# NOTE: if you use the "wx" configuration interface, you must also use +# the "wx" display library. +#======================================================================= +#config_interface: textconfig +#config_interface: win32config +#config_interface: wx + +#======================================================================= +# DISPLAY_LIBRARY +# +# The display library is the code that displays the Bochs VGA screen. Bochs +# has a selection of about 10 different display library implementations for +# different platforms. If you run configure with multiple --with-* options, +# the display_library command lets you choose which one you want to run with. +# If you do not write a display_library line, Bochs will choose a default for +# you. +# +# The choices are: +# x use X windows interface, cross platform +# win32 use native win32 libraries +# carbon use Carbon library (for MacOS X) +# macintosh use MacOS pre-10 +# amigaos use native AmigaOS libraries +# sdl use SDL 1.2.x library, cross platform +# sdl2 use SDL 2.x library, cross platform +# svga use SVGALIB library for Linux, allows graphics without X11 +# term text only, uses curses/ncurses library, cross platform +# rfb provides an interface to AT&T's VNC viewer, cross platform +# vncsrv use LibVNCServer for extended RFB(VNC) support +# wx use wxWidgets library, cross platform +# nogui no display at all +# +# NOTE: if you use the "wx" configuration interface, you must also use +# the "wx" display library. +# +# Specific options: +# Some display libraries now support specific options to control their +# behaviour. These options are supported by more than one display library: +# +# "gui_debug" - use GTK debugger gui (sdl, sdl2, x) / Win32 debugger gui (sdl, +# sdl2, win32) +# "hideIPS" - disable IPS output in status bar (rfb, sdl, sdl2, vncsrv, +# win32, wx, x) +# "nokeyrepeat" - turn off host keyboard repeat (sdl, sdl2, win32, x) +# "timeout" - time (in seconds) to wait for client (rfb, vncsrv) +# +# See the examples below for other currently supported options. +#======================================================================= +#display_library: amigaos +#display_library: carbon +#display_library: macintosh +display_library: nogui +#display_library: rfb +#display_library: sdl, options="fullscreen" # startup in fullscreen mode +#display_library: sdl2, options="fullscreen" # startup in fullscreen mode +#display_library: term +#display_library: vncsrv +# "traphotkeys" - system hotkeys not handled by host OS, but sent to guest +# (win32 in mouse capture and fullscreen mode: alt-tab, win, +# alt-space, alt-esc, ctrl-esc) +#display_library: win32, options="traphotkeys" +#display_library: wx +#display_library: x, gui_debug=1 +#display_library: x, options="gui_debug" + +#======================================================================= +# CPU: +# This defines cpu-related parameters inside Bochs: +# +# MODEL: +# Selects CPU configuration to emulate from pre-defined list of all +# supported configurations. When this option is used and the value +# is different from 'bx_generic', the parameters of the CPUID option +# have no effect anymore. +# +# CPU configurations that can be selected: +# ----------------------------------------------------------------- +# pentium Intel Pentium (P54C) +# pentium_mmx Intel Pentium MMX +# amd_k6_2_chomper AMD-K6(tm) 3D processor (Chomper) +# p2_klamath Intel Pentium II (Klamath) +# p3_katmai Intel Pentium III (Katmai) +# p4_willamette Intel(R) Pentium(R) 4 (Willamette) +# core_duo_t2400_yonah Intel(R) Core(TM) Duo CPU T2400 (Yonah) +# atom_n270 Intel(R) Atom(TM) CPU N270 +# p4_prescott_celeron_336 Intel(R) Celeron(R) 336 (Prescott) +# athlon64_clawhammer AMD Athlon(tm) 64 Processor 2800+ (Clawhammer) +# athlon64_venice AMD Athlon(tm) 64 Processor 3000+ (Venice) +# turion64_tyler AMD Turion(tm) 64 X2 Mobile TL-60 (Tyler) +# phenom_8650_toliman AMD Phenom X3 8650 (Toliman) +# core2_penryn_t9600 Intel Mobile Core 2 Duo T9600 (Penryn) +# corei5_lynnfield_750 Intel(R) Core(TM) i5 750 (Lynnfield) +# corei5_arrandale_m520 Intel(R) Core(TM) i5 M 520 (Arrandale) +# corei7_sandy_bridge_2600k Intel(R) Core(TM) i7-2600K (Sandy Bridge) +# zambezi AMD FX(tm)-4100 Quad-Core Processor (Zambezi) +# trinity_apu AMD A8-5600K APU (Trinity) +# ryzen AMD Ryzen 7 1700 +# corei7_ivy_bridge_3770k Intel(R) Core(TM) i7-3770K CPU (Ivy Bridge) +# corei7_haswell_4770 Intel(R) Core(TM) i7-4770 CPU (Haswell) +# broadwell_ult Intel(R) Processor 5Y70 CPU (Broadwell) +# +# COUNT: +# Set the number of processors:cores per processor:threads per core when +# Bochs is compiled for SMP emulation. Bochs currently supports up to +# 14 threads (legacy APIC) or 254 threads (xAPIC or higher) running +# simultaniosly. If Bochs is compiled without SMP support, it won't accept +# values different from 1. +# +# QUANTUM: +# Maximum amount of instructions allowed to execute by processor before +# returning control to another cpu. This option exists only in Bochs +# binary compiled with SMP support. +# +# RESET_ON_TRIPLE_FAULT: +# Reset the CPU when triple fault occur (highly recommended) rather than +# PANIC. Remember that if you trying to continue after triple fault the +# simulation will be completely bogus ! +# +# CPUID_LIMIT_WINNT: +# Determine whether to limit maximum CPUID function to 2. This mode is +# required to workaround WinNT installation and boot issues. +# +# MSRS: +# Define path to user CPU Model Specific Registers (MSRs) specification. +# See example in msrs.def. +# +# IGNORE_BAD_MSRS: +# Ignore MSR references that Bochs does not understand; print a warning +# message instead of generating #GP exception. This option is enabled +# by default but will not be avaiable if configurable MSRs are enabled. +# +# MWAIT_IS_NOP: +# When this option is enabled MWAIT will not put the CPU into a sleep state. +# This option exists only if Bochs compiled with --enable-monitor-mwait. +# +# IPS: +# Emulated Instructions Per Second. This is the number of IPS that bochs +# is capable of running on your machine. You can recompile Bochs with +# --enable-show-ips option enabled, to find your host's capability. +# Measured IPS value will then be logged into your log file or shown +# in the status bar (if supported by the gui). +# +# IPS is used to calibrate many time-dependent events within the bochs +# simulation. For example, changing IPS affects the frequency of VGA +# updates, the duration of time before a key starts to autorepeat, and +# the measurement of BogoMips and other benchmarks. +# +# Examples: +# +# Bochs Machine/Compiler Mips +# ______________________________________________________________________ +# 2.4.6 3.4Ghz Intel Core i7 2600 with Win7x64/g++ 4.5.2 85 to 95 Mips +# 2.3.7 3.2Ghz Intel Core 2 Q9770 with WinXP/g++ 3.4 50 to 55 Mips +# 2.3.7 2.6Ghz Intel Core 2 Duo with WinXP/g++ 3.4 38 to 43 Mips +# 2.2.6 2.6Ghz Intel Core 2 Duo with WinXP/g++ 3.4 21 to 25 Mips +# 2.2.6 2.1Ghz Athlon XP with Linux 2.6/g++ 3.4 12 to 15 Mips +#======================================================================= +#cpu: model=core2_penryn_t9600, count=1, ips=50000000, reset_on_triple_fault=1, ignore_bad_msrs=1, msrs="msrs.def" +#cpu: model=core2_penryn_t9600, count=1, ips=50000000, reset_on_triple_fault=0 cpuid_limit_winnt=1 +#cpu: model=corei7_haswell_4770, count=1, ips=50000000, reset_on_triple_fault=0 +#cpu: model=broadwell_ult, count=1, ips=50000000, reset_on_triple_fault=0 +#cpu: model=corei7_ivy_bridge_3770k, count=1, ips=50000000, reset_on_triple_fault=0 +#cpu: model=corei5_lynnfield_750, count=1, ips=50000000, reset_on_triple_fault=0 + +#======================================================================= +# CPUID: +# +# This defines features and functionality supported by Bochs emulated CPU. +# The option has no offect if CPU model was selected in CPU option. +# +# MMX: +# Select MMX instruction set support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 5. +# +# APIC: +# Select APIC configuration (LEGACY/XAPIC/XAPIC_EXT/X2APIC). +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 5. +# +# SEP: +# Select SYSENTER/SYSEXIT instruction set support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# SIMD: +# Select SIMD instructions support. +# Any of NONE/SSE/SSE2/SSE3/SSSE3/SSE4_1/SSE4_2/AVX/AVX2/AVX512 +# could be selected. +# +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# The AVX choises exists only if Bochs compiled with --enable-avx option. +# +# SSE4A: +# Select AMD SSE4A instructions support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# MISALIGNED_SSE: +# Select AMD Misaligned SSE mode support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# AES: +# Select AES instruction set support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# SHA: +# Select SHA instruction set support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# MOVBE: +# Select MOVBE Intel(R) Atom instruction support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# ADX: +# Select ADCX/ADOX instructions support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# XSAVE: +# Select XSAVE extensions support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# XSAVEOPT: +# Select XSAVEOPT instruction support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# AVX_F16C: +# Select AVX float16 convert instructions support. +# This option exists only if Bochs compiled with --enable-avx option. +# +# AVX_FMA: +# Select AVX fused multiply add (FMA) instructions support. +# This option exists only if Bochs compiled with --enable-avx option. +# +# BMI: +# Select BMI1/BMI2 instructions support. +# This option exists only if Bochs compiled with --enable-avx option. +# +# XOP: +# Select AMD XOP instructions support. +# This option exists only if Bochs compiled with --enable-avx option. +# +# FMA4: +# Select AMD four operand FMA instructions support. +# This option exists only if Bochs compiled with --enable-avx option. +# +# TBM: +# Select AMD Trailing Bit Manipulation (TBM) instructions support. +# This option exists only if Bochs compiled with --enable-avx option. +# +# X86-64: +# Enable x86-64 and long mode support. +# This option exists only if Bochs compiled with x86-64 support. +# +# 1G_PAGES: +# Enable 1G page size support in long mode. +# This option exists only if Bochs compiled with x86-64 support. +# +# PCID: +# Enable Process-Context Identifiers (PCID) support in long mode. +# This option exists only if Bochs compiled with x86-64 support. +# +# FSGSBASE: +# Enable GS/GS BASE access instructions support in long mode. +# This option exists only if Bochs compiled with x86-64 support. +# +# SMEP: +# Enable Supervisor Mode Execution Protection (SMEP) support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# SMAP: +# Enable Supervisor Mode Access Prevention (SMAP) support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# MWAIT: +# Select MONITOR/MWAIT instructions support. +# This option exists only if Bochs compiled with --enable-monitor-mwait. +# +# VMX: +# Select VMX extensions emulation support. +# This option exists only if Bochs compiled with --enable-vmx option. +# +# SVM: +# Select AMD SVM (Secure Virtual Machine) extensions emulation support. +# This option exists only if Bochs compiled with --enable-svm option. +# +# VENDOR_STRING: +# Set the CPUID vendor string returned by CPUID(0x0). This should be a +# twelve-character ASCII string. +# +# BRAND_STRING: +# Set the CPUID vendor string returned by CPUID(0x80000002 .. 0x80000004). +# This should be at most a forty-eight-character ASCII string. +# +# LEVEL: +# Set emulated CPU level information returned by CPUID. Default value is +# determined by configure option --enable-cpu-level. Currently supported +# values are 5 (for Pentium and similar processors) and 6 (for P6 and +# later processors). +# +# FAMILY: +# Set model information returned by CPUID. Default family value determined +# by configure option --enable-cpu-level. +# +# MODEL: +# Set model information returned by CPUID. Default model value is 3. +# +# STEPPING: +# Set stepping information returned by CPUID. Default stepping value is 3. +#======================================================================= +#cpuid: x86_64=1, mmx=1, sep=1, simd=sse4_2, apic=xapic, aes=1, movbe=1, xsave=1 +#cpuid: family=6, model=0x1a, stepping=5 + +#======================================================================= +# MEMORY +# Set the amount of physical memory you want to emulate. +# +# GUEST: +# Set amount of guest physical memory to emulate. The default is 32MB, +# the maximum amount limited only by physical address space limitations. +# +# HOST: +# Set amount of host memory you want to allocate for guest RAM emulation. +# It is possible to allocate less memory than you want to emulate in guest +# system. This will fake guest to see the non-existing memory. Once guest +# system touches new memory block it will be dynamically taken from the +# memory pool. You will be warned (by FATAL PANIC) in case guest already +# used all allocated host memory and wants more. +# +#======================================================================= +memory: guest=32, host=32 + +#======================================================================= +# ROMIMAGE: +# The ROM BIOS controls what the PC does when it first powers on. +# Normally, you can use a precompiled BIOS in the source or binary +# distribution called BIOS-bochs-latest. The default ROM BIOS is usually loaded +# starting at address 0xfffe0000, and it is exactly 128k long. The legacy +# version of the Bochs BIOS is usually loaded starting at address 0xffff0000, +# and it is exactly 64k long. +# You can use the environment variable $BXSHARE to specify the location +# of the BIOS. +# The usage of external large BIOS images (up to 512k) at memory top is +# now supported, but we still recommend to use the BIOS distributed with Bochs. +# The start address is optional, since it can be calculated from image size. +# The Bochs BIOS currently supports only the option "fastboot" to skip the +# boot menu delay. +#======================================================================= +#romimage: file=$BXSHARE/BIOS-bochs-latest, options=fastboot +romimage: file=$BXSHARE/BIOS-bochs-legacy, options=fastboot +#romimage: file=$BXSHARE/bios.bin-1.7.5 # http://www.seabios.org/SeaBIOS +#romimage: file=mybios.bin, address=0xfff80000 # 512k at memory top +#romimage: file=BIOS-bochs-latest, options=fastboot + +#======================================================================= +# VGAROMIMAGE +# You now need to load a VGA ROM BIOS into C0000. +#======================================================================= +#vgaromimage: file=$BXSHARE/VGABIOS-elpin-2.40 +#vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest +#vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest-cirrus +#vgaromimage: file=/usr/local/share/qemu/sgabios.bin + +#======================================================================= +# OPTROMIMAGE[1-4]: +# You may now load up to 4 optional ROM images. Be sure to use a +# read-only area, typically between C8000 and EFFFF. These optional +# ROM images should not overwrite the rombios (located at +# F0000-FFFFF) and the videobios (located at C0000-C7FFF). +# Those ROM images will be initialized by the bios if they contain +# the right signature (0x55AA) and a valid checksum. +# It can also be a convenient way to upload some arbitrary code/data +# in the simulation, that can be retrieved by the boot loader +#======================================================================= +#optromimage1: file=optionalrom.bin, address=0xd0000 +#optromimage2: file=optionalrom.bin, address=0xd1000 +#optromimage3: file=optionalrom.bin, address=0xd2000 +#optromimage4: file=optionalrom.bin, address=0xd3000 + +#optramimage1: file=/path/file1.img, address=0x0010000 +#optramimage2: file=/path/file2.img, address=0x0020000 +#optramimage3: file=/path/file3.img, address=0x0030000 +#optramimage4: file=/path/file4.img, address=0x0040000 + +#======================================================================= +# VGA: +# This defines parameters related to the VGA display +# +# EXTENSION +# Here you can specify the display extension to be used. With the value +# 'none' you can use standard VGA with no extension. Other supported +# values are 'vbe' for Bochs VBE, 'cirrus' for Cirrus SVGA support and +# 'voodoo' for Voodoo Graphics support (see 'voodoo' option). +# +# UPDATE_FREQ +# This parameter specifies the number of display updates per second. +# The VGA update timer by default uses the realtime engine with a value +# of 5. This parameter can be changed at runtime. +# +# REALTIME +# If set to 1 (default), the VGA timer is based on realtime, otherwise it +# is driven by the cpu and depends on the ips setting. If the host is slow +# (low ips, update_freq) and the guest uses HLT appropriately, setting this +# to 0 and "clock: sync=none" may improve the responsiveness of the guest +# GUI when the guest is otherwise idle. +# +# Examples: +# vga: extension=cirrus, update_freq=10 +#======================================================================= +vga: extension=none, update_freq=5, realtime=1 + +#======================================================================= +# VOODOO: +# This defines the Voodoo Graphics emulation (experimental). Currently +# supported models are 'voodoo1', 'voodoo2', 'banshee' and 'voodoo3'. The +# Voodoo2 support is not yet complete, but almost usable. The Banshee and +# Voodoo3 support is under construction, but basicly usable. The 2D/3D cards +# require an external VGA BIOS the vga extension option to be set to 'voodoo'. +# If the i440BX PCI chipset is selected, they can be assigned to AGP (slot #5). +# The gui screen update timing for all models is controlled by the related 'vga' +# options. +# +# Examples: +# voodoo: enabled=1, model=voodoo2 +#======================================================================= +#voodoo: enabled=1, model=voodoo1 + +#======================================================================= +# KEYBOARD: +# This defines parameters related to the emulated keyboard +# +# TYPE: +# Type of keyboard return by a "identify keyboard" command to the +# keyboard controller. It must be one of "xt", "at" or "mf". +# Defaults to "mf". It should be ok for almost everybody. A known +# exception is french macs, that do have a "at"-like keyboard. +# +# SERIAL_DELAY: +# Approximate time in microseconds that it takes one character to +# be transferred from the keyboard to controller over the serial path. +# +# PASTE_DELAY: +# Approximate time in microseconds between attempts to paste +# characters to the keyboard controller. This leaves time for the +# guest os to deal with the flow of characters. The ideal setting +# depends on how your operating system processes characters. The +# default of 100000 usec (.1 seconds) was chosen because it works +# consistently in Windows. +# If your OS is losing characters during a paste, increase the paste +# delay until it stops losing characters. +# +# KEYMAP: +# This enables a remap of a physical localized keyboard to a +# virtualized us keyboard, as the PC architecture expects. +# +# USER_SHORTCUT: +# This defines the keyboard shortcut to be sent when you press the "user" +# button in the headerbar. The shortcut string is a combination of maximum +# 3 key names (listed below) separated with a '-' character. +# Valid key names: +# "alt", "bksl", "bksp", "ctrl", "del", "down", "end", "enter", "esc", +# "f1", ... "f12", "home", "ins", "left", "menu", "minus", "pgdwn", "pgup", +# "plus", "power", "print", "right", "scrlck", "shift", "space", "tab", "up" +# and "win". +# +# Examples: +# keyboard: type=mf, serial_delay=200, paste_delay=100000 +# keyboard: keymap=gui/keymaps/x11-pc-de.map +# keyboard: user_shortcut=ctrl-alt-del +#======================================================================= +keyboard: type=mf, serial_delay=250 + +#======================================================================= +# MOUSE: +# This defines parameters for the emulated mouse type, the initial status +# of the mouse capture and the runtime method to toggle it. +# +# TYPE: +# With the mouse type option you can select the type of mouse to emulate. +# The default value is 'ps2'. The other choices are 'imps2' (wheel mouse +# on PS/2), 'serial', 'serial_wheel', 'serial_msys' (one com port requires +# setting 'mode=mouse') 'inport' and 'bus' (if present). To connect a mouse +# to a USB port, see the 'usb_uhci', 'usb_ohci', 'usb_ehci' or 'usb_xhci' +# options (requires PCI and USB support). +# +# ENABLED: +# The Bochs gui creates mouse "events" unless the 'enabled' option is +# set to 0. The hardware emulation itself is not disabled by this. +# Unless you have a particular reason for enabling the mouse by default, +# it is recommended that you leave it off. You can also toggle the mouse +# usage at runtime (RFB, SDL, Win32, wxWidgets and X11 - see below). +# +# TOGGLE: +# The default method to toggle the mouse capture at runtime is to press the +# CTRL key and the middle mouse button ('ctrl+mbutton'). This option allows +# to change the method to 'ctrl+f10' (like DOSBox), 'ctrl+alt' (like QEMU) +# or 'f12'. +# +# Examples: +# mouse: enabled=1 +# mouse: type=imps2, enabled=1 +# mouse: type=serial, enabled=1 +# mouse: enabled=0, toggle=ctrl+f10 +#======================================================================= +mouse: enabled=0 + +#======================================================================= +# PCI: +# This option controls the presence of a PCI chipset in Bochs. Currently it +# supports the i430FX, i440FX and i440BX chipsets. You can also specify the +# devices connected to PCI slots. Up to 5 slots are available. For these +# combined PCI/ISA devices assigning to slot is mandatory if you want to emulate +# the PCI model: cirrus, ne2k and pcivga. These PCI-only devices are also +# supported, but they are auto-assigned if you don't use the slot configuration: +# e1000, es1370, pcidev, pcipnic, usb_ehci, usb_ohci, usb_xhci and voodoo. +# In case of the i440BX chipset, slot #5 is the AGP slot. Currently only the +# 'voodoo' device can be assigned to AGP. +# +# Example: +# pci: enabled=1, chipset=i440fx, slot1=pcivga, slot2=ne2k +#======================================================================= +pci: enabled=1, chipset=i440fx + +#======================================================================= +# CLOCK: +# This defines the parameters of the clock inside Bochs: +# +# SYNC: +# This defines the method how to synchronize the Bochs internal time +# with realtime. With the value 'none' the Bochs time relies on the IPS +# value and no host time synchronization is used. The 'slowdown' method +# sacrifices performance to preserve reproducibility while allowing host +# time correlation. The 'realtime' method sacrifices reproducibility to +# preserve performance and host-time correlation. +# It is possible to enable both synchronization methods. +# +# RTC_SYNC: +# If this option is enabled together with the realtime synchronization, +# the RTC runs at realtime speed. This feature is disabled by default. +# +# TIME0: +# Specifies the start (boot) time of the virtual machine. Use a time +# value as returned by the time(2) system call or a string as returned +# by the ctime(3) system call. If no time0 value is set or if time0 +# equal to 1 (special case) or if time0 equal 'local', the simulation +# will be started at the current local host time. If time0 equal to 2 +# (special case) or if time0 equal 'utc', the simulation will be started +# at the current utc time. +# +# Syntax: +# clock: sync=[none|slowdown|realtime|both], time0=[timeValue|local|utc] +# +# Example: +# clock: sync=none, time0=local # Now (localtime) +# clock: sync=slowdown, time0=315529200 # Tue Jan 1 00:00:00 1980 +# clock: sync=none, time0="Mon Jan 1 00:00:00 1990" # 631148400 +# clock: sync=realtime, time0=938581955 # Wed Sep 29 07:12:35 1999 +# clock: sync=realtime, time0="Sat Jan 1 00:00:00 2000" # 946681200 +# clock: sync=none, time0=1 # Now (localtime) +# clock: sync=none, time0=utc # Now (utc/gmt) +# +# Default value are sync=none, rtc_sync=0, time0=local +#======================================================================= +clock: sync=none, time0=local + +#======================================================================= +# CMOSIMAGE: +# This defines a binary image file with size 128 bytes that can be loaded into +# the CMOS RAM at startup. The rtc_init parameter controls whether initialize +# the RTC with values stored in the image. By default the time0 argument given +# to the clock option is used. With 'rtc_init=image' the image is the source +# for the initial time. +# +# Example: +# cmosimage: file=cmos.img, rtc_init=image +#======================================================================= +#cmosimage: file=cmos.img, rtc_init=time0 + +#======================================================================= +# private_colormap: Request that the GUI create and use it's own +# non-shared colormap. This colormap will be used +# when in the bochs window. If not enabled, a +# shared colormap scheme may be used. Not implemented +# on all GUI's. +# +# Examples: +# private_colormap: enabled=1 +# private_colormap: enabled=0 +#======================================================================= +private_colormap: enabled=0 + +#======================================================================= +# FLOPPYA: +# Point this to pathname of floppy image file or device +# This should be of a bootable floppy(image/device) if you're +# booting from 'a' (or 'floppy'). +# +# You can set the initial status of the media to 'ejected' or 'inserted'. +# floppya: 2_88=path, status=ejected (2.88M 3.5" media) +# floppya: 1_44=path, status=inserted (1.44M 3.5" media) +# floppya: 1_2=path, status=ejected (1.2M 5.25" media) +# floppya: 720k=path, status=inserted (720K 3.5" media) +# floppya: 360k=path, status=inserted (360K 5.25" media) +# floppya: 320k=path, status=inserted (320K 5.25" media) +# floppya: 180k=path, status=inserted (180K 5.25" media) +# floppya: 160k=path, status=inserted (160K 5.25" media) +# floppya: image=path, status=inserted (guess media type from image size) +# floppya: 1_44=vvfat:path, status=inserted (use directory as VFAT media) +# floppya: type=1_44 (1.44M 3.5" floppy drive, no media) +# +# The path should be the name of a disk image file. On Unix, you can use a raw +# device name such as /dev/fd0 on Linux. On win32 platforms, use drive letters +# such as a: or b: as the path. The parameter 'image' works with image files +# only. In that case the size must match one of the supported types. +# The parameter 'type' can be used to enable the floppy drive without media +# and status specified. Usually the drive type is set up based on the media type. +# The optional parameter 'write_protected' can be used to control the media +# write protect switch. By default it is turned off. +#======================================================================= +#floppya: 1_44=, status=inserted +#floppya: image=../1.44, status=inserted +#floppya: 1_44=/dev/fd0H1440, status=inserted +#floppya: 1_2=../1_2, status=inserted +#floppya: 1_44=a:, status=inserted +#floppya: 1_44=a.img, status=inserted, write_protected=1 +#floppya: 1_44=/dev/rfd0a, status=inserted +#floppya: 1_44=boot.img, status=inserted, write_protected=1 + +#======================================================================= +# FLOPPYB: +# See FLOPPYA above for syntax +#======================================================================= +#floppyb: 1_44=b:, status=inserted +#floppyb: 1_44=b.img, status=inserted + +#======================================================================= +# ATA0, ATA1, ATA2, ATA3 +# ATA controller for hard disks and cdroms +# +# ata[0-3]: enabled=[0|1], ioaddr1=addr, ioaddr2=addr, irq=number +# +# These options enables up to 4 ata channels. For each channel +# the two base io addresses and the irq must be specified. +# +# ata0 and ata1 are enabled by default with the values shown below +# +# Examples: +# ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 +# ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15 +# ata2: enabled=1, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11 +# ata3: enabled=1, ioaddr1=0x168, ioaddr2=0x360, irq=9 +#======================================================================= +ata0: enabled=0, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 +ata1: enabled=0, ioaddr1=0x170, ioaddr2=0x370, irq=15 +ata2: enabled=0, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11 +ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x360, irq=9 + +#======================================================================= +# ATA[0-3]-MASTER, ATA[0-3]-SLAVE +# +# This defines the type and characteristics of all attached ata devices: +# type= type of attached device [disk|cdrom] +# mode= only valid for disks [flat|concat|external|dll|sparse|vmware3] +# [vmware4|undoable|growing|volatile|vpc] +# [vbox|vvfat] +# path= path of the image / directory +# cylinders= only valid for disks +# heads= only valid for disks +# spt= only valid for disks +# status= only valid for cdroms [inserted|ejected] +# biosdetect= type of biosdetection [auto|cmos|none] +# translation=type of translation of the bios, only for disks [none|lba|large|rechs|auto] +# model= string returned by identify device command +# journal= optional filename of the redolog for undoable, volatile and vvfat disks +# +# Point this at a hard disk image file, cdrom iso file, or physical cdrom +# device. To create a hard disk image, try running bximage. It will help you +# choose the size and then suggest a line that works with it. +# +# In UNIX it may be possible to use a raw device as a Bochs hard disk, +# but WE DON'T RECOMMEND IT. In Windows there is no easy way. +# +# In windows, the drive letter + colon notation should be used for cdroms. +# Depending on versions of windows and drivers, you may only be able to +# access the "first" cdrom in the system. On MacOSX, use path="drive" +# to access the physical drive. +# +# The path is mandatory for hard disks. Disk geometry autodetection works with +# images created by bximage if CHS is set to 0/0/0 (cylinders are calculated +# using heads=16 and spt=63). For other hard disk images and modes the +# cylinders, heads, and spt are mandatory. In all cases the disk size reported +# from the image must be exactly C*H*S*512. +# +# Default values are: +# mode=flat, biosdetect=auto, translation=auto, model="Generic 1234" +# +# The biosdetect option has currently no effect on the bios +# +# Examples: +# ata0-master: type=disk, mode=flat, path=10M.sample, cylinders=306, heads=4, spt=17 +# ata0-slave: type=disk, mode=flat, path=20M.sample, cylinders=615, heads=4, spt=17 +# ata1-master: type=disk, mode=flat, path=30M.sample, cylinders=615, heads=6, spt=17 +# ata1-slave: type=disk, mode=flat, path=46M.sample, cylinders=940, heads=6, spt=17 +# ata2-master: type=disk, mode=flat, path=62M.sample, cylinders=940, heads=8, spt=17 +# ata2-slave: type=disk, mode=flat, path=112M.sample, cylinders=900, heads=15, spt=17 +# ata3-master: type=disk, mode=flat, path=483M.sample, cylinders=1024, heads=15, spt=63 +# ata3-slave: type=cdrom, path=iso.sample, status=inserted +#======================================================================= +#ata0-master: type=disk, mode=flat, path="30M.sample" +#ata0-master: type=disk, mode=flat, path="30M.sample", cylinders=615, heads=6, spt=17 +#ata0-master: type=disk, mode=flat, path="c.img", cylinders=0 # autodetect +#ata0-slave: type=disk, mode=vvfat, path=/bochs/images/vvfat, journal=vvfat.redolog +#ata0-slave: type=cdrom, path=D:, status=inserted +#ata0-slave: type=cdrom, path=/dev/cdrom, status=inserted +#ata0-slave: type=cdrom, path="drive", status=inserted +#ata0-slave: type=cdrom, path=/dev/rcd0d, status=inserted + +#======================================================================= +# BOOT: +# This defines the boot sequence. Now you can specify up to 3 boot drives, +# which can be 'floppy', 'disk', 'cdrom' or 'network' (boot ROM). +# Legacy 'a' and 'c' are also supported. +# Examples: +# boot: floppy +# boot: cdrom, disk +# boot: network, disk +# boot: cdrom, floppy, disk +#======================================================================= +boot: floppy +#boot: disk + +#======================================================================= +# FLOPPY_BOOTSIG_CHECK: disabled=[0|1] +# Enables or disables the 0xaa55 signature check on boot floppies +# Defaults to disabled=0 +# Examples: +# floppy_bootsig_check: disabled=0 +# floppy_bootsig_check: disabled=1 +#======================================================================= +floppy_bootsig_check: disabled=0 + +#======================================================================= +# LOG: +# Give the path of the log file you'd like Bochs debug and misc. verbiage +# to be written to. If you don't use this option or set the filename to +# '-' the output is written to the console. If you really don't want it, +# make it "/dev/null" (Unix) or "nul" (win32). :^( +# +# Examples: +# log: ./bochs.out +# log: /dev/tty +#======================================================================= +#log: /dev/null +#log: .bochs.log +#log: - +log: /dev/stderr + +#======================================================================= +# LOGPREFIX: +# This handles the format of the string prepended to each log line. +# You may use those special tokens : +# %t : 11 decimal digits timer tick +# %i : 8 hexadecimal digits of cpu current eip (ignored in SMP configuration) +# %e : 1 character event type ('i'nfo, 'd'ebug, 'p'anic, 'e'rror) +# %d : 5 characters string of the device, between brackets +# +# Default : %t%e%d +# Examples: +# logprefix: %t-%e-@%i-%d +# logprefix: %i%e%d +#======================================================================= +logprefix: %t%e%d + +#======================================================================= +# LOG CONTROLS +# +# Bochs has four severity levels for event logging. +# panic: cannot proceed. If you choose to continue after a panic, +# don't be surprised if you get strange behavior or crashes. +# error: something went wrong, but it is probably safe to continue the +# simulation. +# info: interesting or useful messages. +# debug: messages useful only when debugging the code. This may +# spit out thousands per second. +# +# For events of each level, you can choose to exit Bochs ('fatal'), 'ask', +# 'warn', 'report' or 'ignore'. The choices 'ask' and 'warn' are not supported +# by all guis, since they should bring up a dialog box. The 'warn' dialog is +# designed to confirm errors and the 'ask' dialog is usually used for panics +# and asks the user how to proceed. +# +# It is also possible to specify the 'action' to do for each Bochs facility +# separately (e.g. crash on panics from everything except the cdrom, and only +# report those). See the 'log function' module list in the user documentation. +# +# If you are experiencing many panics, it can be helpful to change +# the panic action to report instead of fatal. However, be aware +# that anything executed after a panic is uncharted territory and can +# cause bochs to become unstable. The panic is a "graceful exit," so +# if you disable it you may get a spectacular disaster instead. +#======================================================================= +panic: action=fatal +error: action=ignore +info: action=ignore +debug: action=ignore #, pci=report # report BX_DEBUG from module 'pci' + +#======================================================================= +# DEBUGGER_LOG: +# Give the path of the log file you'd like Bochs to log debugger output. +# If you really don't want it, make it /dev/null or '-'. :^( +# +# Examples: +# debugger_log: ./debugger.out +#======================================================================= +#debugger_log: /dev/null +#debugger_log: debugger.out +#debugger_log: - +debugger_log: /dev/null + +#======================================================================= +# COM1, COM2, COM3, COM4: +# This defines a serial port (UART type 16550A). In the 'term' mode you can +# specify a device to use as com1. This can be a real serial line, or a pty. +# To use a pty (under X/Unix), create two windows (xterms, usually). One of +# them will run bochs, and the other will act as com1. Find out the tty the com1 +# window using the `tty' command, and use that as the `dev' parameter. +# Then do `sleep 1000000' in the com1 window to keep the shell from +# messing with things, and run bochs in the other window. Serial I/O to +# com1 (port 0x3f8) will all go to the other window. +# In socket* and pipe* (win32 only) modes Bochs becomes either socket/named pipe +# client or server. In client mode it connects to an already running server (if +# connection fails Bochs treats com port as not connected). In server mode it +# opens socket/named pipe and waits until a client application connects to it +# before starting simulation. This mode is useful for remote debugging (e.g. +# with gdb's "target remote host:port" command or windbg's command line option +# -k com:pipe,port=\\.\pipe\pipename). Socket modes use simple TCP communication, +# pipe modes use duplex byte mode pipes. +# Other serial modes are 'null' (no input/output), 'file' (output to a file +# specified as the 'dev' parameter and changeable at runtime), 'raw' (use the +# real serial port - partly implemented on win32), 'mouse' (standard serial +# mouse - requires mouse option setting 'type=serial', 'type=serial_wheel' or +# 'type=serial_msys'). +# +# Examples: +# com1: enabled=1, mode=null +# com1: enabled=1, mode=mouse +# com2: enabled=1, mode=file, dev=serial.out +# com3: enabled=1, mode=raw, dev=com1 +# com3: enabled=1, mode=socket-client, dev=localhost:8888 +# com3: enabled=1, mode=socket-server, dev=localhost:8888 +# com4: enabled=1, mode=pipe-client, dev=\\.\pipe\mypipe +# com4: enabled=1, mode=pipe-server, dev=\\.\pipe\mypipe +#======================================================================= +com1: enabled=1, mode=file, dev=/proc/self/fd/4 + +#======================================================================= +# PARPORT1, PARPORT2: +# This defines a parallel (printer) port. When turned on and an output file is +# defined the emulated printer port sends characters printed by the guest OS +# into the output file. On some platforms a device filename can be used to +# send the data to the real parallel port (e.g. "/dev/lp0" on Linux, "lpt1" on +# win32 platforms). The output file can be changed at runtime. +# +# Examples: +# parport1: enabled=1, file="parport.out" +# parport2: enabled=1, file="/dev/lp0" +# parport1: enabled=0 +#======================================================================= +#parport1: enabled=1, file="parport.out" +parport1: enabled=0 + +#======================================================================= +# SOUND: +# This defines the lowlevel sound driver(s) for the wave (PCM) input / output +# and the MIDI output feature and (if necessary) the devices to be used. +# It can have several of the following properties. +# All properties are in the format sound: property=value +# +# waveoutdrv: +# This defines the driver to be used for the waveout feature. +# Possible values are 'file' (all wave data sent to file), 'dummy' (no +# output) and the platform-dependant drivers 'alsa', 'oss', 'osx', 'sdl' +# and 'win'. +# waveout: +# This defines the device to be used for wave output (if necessary) or +# the output file for the 'file' driver. +# waveindrv: +# This defines the driver to be used for the wavein feature. +# Possible values are 'dummy' (recording silence) and platform-dependent +# drivers 'alsa', 'oss', 'sdl' and 'win'. +# wavein: +# This defines the device to be used for wave input (if necessary). +# midioutdrv: +# This defines the driver to be used for the MIDI output feature. +# Possible values are 'file' (all MIDI data sent to file), 'dummy' (no +# output) and platform-dependent drivers 'alsa', 'oss', 'osx' and 'win'. +# midiout: +# This defines the device to be used for MIDI output (if necessary). +# driver: +# This defines the driver to be used for all sound features with one +# property. Possible values are 'default' (platform default) and all +# other choices described above. Overriding one or more settings with +# the specific driver parameter is possible. +# +# Example for different drivers: +# sound: waveoutdrv=sdl, waveindrv=alsa, midioutdrv=dummy +#======================================================================= +#sound: driver=default, waveout=/dev/dsp. wavein=, midiout= + +#======================================================================= +# SPEAKER: +# This defines the PC speaker output mode. In the 'sound' mode the beep +# is generated by the square wave generator which is a part of the +# lowlevel sound support. The 'system' mode is only available on Linux +# and Windows. On Linux /dev/console is used for output and on Windows +# the Beep() function. The 'gui' mode forwards the beep to the related +# gui methods (currently only used by the Carbon gui). +#======================================================================= +#speaker: enabled=0, mode=sound +speaker: enabled=0 + +#======================================================================= +# SB16: +# This defines the SB16 sound emulation. It can have several of the +# following properties. +# All properties are in the format sb16: property=value +# +# enabled: +# This optional property controls the presence of the SB16 emulation. +# The emulation is turned on unless this property is used and set to 0. +# midimode: This parameter specifies what to do with the MIDI output. +# 0 = no output +# 1 = output to device specified with the sound option (system dependent) +# 2 = MIDI or raw data output to file (depends on file name extension) +# 3 = dual output (mode 1 and 2 at the same time) +# midifile: This is the file where the midi output is stored (midimode 2 or 3). +# wavemode: This parameter specifies what to do with the PCM output. +# 0 = no output +# 1 = output to device specified with the sound option (system dependent) +# 2 = VOC, WAV or raw data output to file (depends on file name extension) +# 3 = dual output (mode 1 and 2 at the same time) +# wavefile: This is the file where the wave output is stored (wavemode 2 or 3). +# loglevel: +# 0=no log +# 1=resource changes, midi program and bank changes +# 2=severe errors +# 3=all errors +# 4=all errors plus all port accesses +# 5=all errors and port accesses plus a lot of extra info +# log: The file to write the sb16 emulator messages to. +# dmatimer: +# microseconds per second for a DMA cycle. Make it smaller to fix +# non-continuous sound. 750000 is usually a good value. This needs a +# reasonably correct setting for the IPS parameter of the CPU option. +# +# Examples for output modes: +# sb16: midimode=2, midifile="output.mid", wavemode=1 # MIDI to file +# sb16: midimode=1, wavemode=3, wavefile="output.wav" # wave to file and device +#======================================================================= +#sb16: midimode=1, wavemode=1, loglevel=2, log=sb16.log, dmatimer=600000 +#sb16: enabled=0 + +#======================================================================= +# ES1370: +# This defines the ES1370 sound emulation (recording and playback - except +# DAC1+DAC2 output at the same time). The parameter 'enabled' controls the +# presence of the device. The wave and MIDI output can be sent to device, file +# or both using the parameters 'wavemode', 'wavefile', 'midimode' and +# 'midifile'. See the description of these parameters at the SB16 directive. +# +# Examples: +# es1370: enabled=1, wavemode=1 # use 'sound' parameters +# es1370: enabled=1, wavemode=2, wavefile=output.voc # send output to file +#======================================================================= +#es1370: enabled=1, wavemode=1 +#es1370: enabled=0 + +#======================================================================= +# ne2k: NE2000 compatible ethernet adapter +# +# Format: +# ne2k: enabled=1, ioaddr=IOADDR, irq=IRQ, mac=MACADDR, ethmod=MODULE, +# ethdev=DEVICE, script=SCRIPT, bootrom=BOOTROM +# +# IOADDR, IRQ: You probably won't need to change ioaddr and irq, unless there +# are IRQ conflicts. These arguments are ignored when assign the ne2k to a +# PCI slot. +# +# MAC: The MAC address MUST NOT match the address of any machine on the net. +# Also, the first byte must be an even number (bit 0 set means a multicast +# address), and you cannot use ff:ff:ff:ff:ff:ff because that's the broadcast +# address. For the ethertap module, you must use fe:fd:00:00:00:01. There may +# be other restrictions too. To be safe, just use the b0:c4... address. +# +# ETHDEV: The ethdev value is the name of the network interface on your host +# platform. On UNIX machines, you can get the name by running ifconfig. On +# Windows machines, you must run niclist to get the name of the ethdev. +# Niclist source code is in misc/niclist.c and it is included in Windows +# binary releases. +# The 'socket' module uses this parameter to specify the UDP port for +# receiving packets and (optional) the host to connect. +# +# SCRIPT: The script value is optional, and is the name of a script that +# is executed after bochs initialize the network interface. You can use +# this script to configure this network interface, or enable masquerading. +# This is mainly useful for the tun/tap devices that only exist during +# Bochs execution. The network interface name is supplied to the script +# as first parameter. +# The 'slirp' module uses this parameter to specify a config file for +# setting up an alternative IP configuration or additional features. +# The 'vnet' module uses this parameter to specify an alternative +# log file name. +# +# BOOTROM: The bootrom value is optional, and is the name of the ROM image +# to load. Note that this feature is only implemented for the PCI version of +# the NE2000. +# +# If you don't want to make connections to any physical networks, +# you can use the following 'ethmod's to simulate a virtual network. +# null: All packets are discarded, but logged to a few files. +# vde: Virtual Distributed Ethernet +# vnet: ARP, ICMP-echo(ping), DHCP and read/write TFTP are simulated. +# The virtual host uses 192.168.10.1. +# DHCP assigns 192.168.10.2 to the guest. +# TFTP uses the 'ethdev' value for the root directory and doesn't +# overwrite files. +# socket: Connect up to 6 Bochs instances with external program 'bxhub' +# (simulating an ethernet hub). It provides the same services as the +# 'vnet' module and assigns IP addresses like 'slirp' (10.0.2.x). +# +#======================================================================= +# ne2k: ioaddr=0x300, irq=9, mac=fe:fd:00:00:00:01, ethmod=fbsd, ethdev=en0 #macosx +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:00, ethmod=fbsd, ethdev=xl0 +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:00, ethmod=linux, ethdev=eth0 +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=win32, ethdev=MYCARD +# ne2k: ioaddr=0x300, irq=9, mac=fe:fd:00:00:00:01, ethmod=tap, ethdev=tap0 +# ne2k: ioaddr=0x300, irq=9, mac=fe:fd:00:00:00:01, ethmod=tuntap, ethdev=/dev/net/tun0, script=./tunconfig +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=null, ethdev=eth0 +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=vde, ethdev="/tmp/vde.ctl" +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=vnet, ethdev="c:/temp" +# ne2k: mac=b0:c4:20:00:00:01, ethmod=socket, ethdev=40000 # use localhost +# ne2k: mac=b0:c4:20:00:00:01, ethmod=socket, ethdev=mymachine:40000 +# ne2k: mac=b0:c4:20:00:00:01, ethmod=slirp, script=slirp.conf, bootrom=ne2k_pci.rom + +#======================================================================= +# pcipnic: Bochs/Etherboot pseudo-NIC +# +# Format: +# pcipnic: enabled=1, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE, script=SCRIPT, +# bootrom=BOOTROM +# +# The pseudo-NIC accepts the same syntax (for mac, ethmod, ethdev, script, +# bootrom) and supports the same networking modules as the NE2000 adapter. +#======================================================================= +#pcipnic: enabled=1, mac=b0:c4:20:00:00:00, ethmod=vnet + +#======================================================================= +# e1000: Intel(R) 82540EM Gigabit Ethernet adapter +# +# Format: +# e1000: enabled=1, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE, script=SCRIPT +# bootrom=BOOTROM +# +# The E1000 accepts the same syntax (for mac, ethmod, ethdev, script, bootrom) +# and supports the same networking modules as the NE2000 adapter. +#======================================================================= +#e1000: enabled=1, mac=52:54:00:12:34:56, ethmod=slirp, script=slirp.conf + +#======================================================================= +# USB_UHCI: +# This option controls the presence of the USB root hub which is a part +# of the i440FX PCI chipset. With the portX parameter you can connect devices +# to the hub (currently supported: 'mouse', 'tablet', 'keypad', 'disk', 'cdrom', +# 'floppy', 'hub' and 'printer'). +# +# If you connect the mouse or tablet to one of the ports, Bochs forwards the +# mouse movement data to the USB device instead of the selected mouse type. +# When connecting the keypad to one of the ports, Bochs forwards the input of +# the numeric keypad to the USB device instead of the PS/2 keyboard. +# +# To connect a 'flat' mode image as a USB hardisk you can use the 'disk' device +# with the path to the image separated with a colon. To use other disk image modes +# similar to ATA disks the syntax 'disk:mode:filename' must be used (see below). +# +# To emulate a USB cdrom you can use the 'cdrom' device name and the path to +# an ISO image or raw device name also separated with a colon. An option to +# insert/eject media is available in the runtime configuration. +# +# To emulate a USB floppy you can use the 'floppy' device with the path to the +# image separated with a colon. To use the VVFAT image mode similar to the +# legacy floppy the syntax 'floppy:vvfat:directory' must be used (see below). +# An option to insert/eject media is available in the runtime configuration. +# +# The device name 'hub' connects an external hub with max. 8 ports (default: 4) +# to the root hub. To specify the number of ports you have to add the value +# separated with a colon. Connecting devices to the external hub ports is only +# available in the runtime configuration. +# +# The device 'printer' emulates the HP Deskjet 920C printer. The PCL data is +# sent to a file specified in bochsrc.txt. The current code appends the PCL +# code to the file if the file already existed. The output file can be +# changed at runtime. +# +# The optionsX parameter can be used to assign specific options to the device +# connected to the corresponding USB port. Currently this feature is used to +# set the speed reported by device ('low', 'full', 'high' or 'super'). The +# availabe speed choices depend on both HC and device. The option 'debug' turns +# on debug output for the device at connection time. +# For the USB 'disk' device the optionsX parameter can be used to specify an +# alternative redolog file (journal) of some image modes. For 'vvfat' mode USB +# disks the optionsX parameter can be used to specify the disk size (range +# 128M ... 128G). If the size is not specified, it defaults to 504M. +# For the USB 'floppy' device the optionsX parameter can be used to specify an +# alternative device ID to be reported. Currently only the model "teac" is +# supported (can fix hw detection in some guest OS). The USB floppy also +# accepts the parameter "write_protected" with valid values 0 and 1 to select +# the access mode (default is 0). +#======================================================================= +#usb_uhci: enabled=1 +#usb_uhci: enabled=1, port1=mouse, port2=disk:usbstick.img +#usb_uhci: enabled=1, port1=hub:7, port2=disk:growing:usbdisk.img +#usb_uhci: enabled=1, port2=disk:undoable:usbdisk.img, options2=journal:redo.log +#usb_uhci: enabled=1, port2=disk:usbdisk2.img, options2=sect_size:1024 +#usb_uhci: enabled=1, port2=disk:vvfat:vvfat, options2="debug,speed:full" +#usb_uhci: enabled=1, port1=printer:printdata.bin, port2=cdrom:image.iso +#usb_uhci: enabled=1, port2=floppy:vvfat:diskette, options2="model:teac" + +#======================================================================= +# USB_OHCI: +# This option controls the presence of the USB OHCI host controller with a +# 2-port hub. The portX parameter accepts the same device types with the same +# syntax as the UHCI controller (see above). The optionsX parameter is also +# available on OHCI. +#======================================================================= +#usb_ohci: enabled=1 +#usb_ohci: enabled=1, port1=printer:usbprinter.bin + +#======================================================================= +# USB_EHCI: +# This option controls the presence of the USB EHCI host controller with a +# 6-port hub. The portX parameter accepts the same device types with the +# same syntax as the UHCI controller (see above). The optionsX parameter is +# also available on EHCI. +#======================================================================= +#usb_ehci: enabled=1 + +#======================================================================= +# USB_XHCI: +# This option controls the presence of the USB xHCI host controller with a +# 4-port hub. The portX parameter accepts the same device types with the +# same syntax as the UHCI controller (see above). The optionsX parameter is +# also available on xHCI. NOTE: port 1 and 2 are USB3 and only support +# super-speed devices, but port 3 and 4 are USB2 and support speed settings +# low, full and high. +#======================================================================= +#usb_xhci: enabled=1 + +#======================================================================= +# PCIDEV: +# PCI host device mapping +# WARNING: This Bochs feature is not maintained yet and may fail. +#======================================================================= +#pcidev: vendor=0x1234, device=0x5678 + +#======================================================================= +# GDBSTUB: +# Enable GDB stub. See user documentation for details. +# Default value is enabled=0. +# WARNING: This Bochs feature is not maintained yet and may fail. +#======================================================================= +#gdbstub: enabled=0, port=1234, text_base=0, data_base=0, bss_base=0 + +#======================================================================= +# MAGIC_BREAK: +# This enables the "magic breakpoint" feature when using the debugger. +# The useless cpu instruction XCHG BX, BX causes Bochs to enter the +# debugger mode. This might be useful for software development. +# +# Example: +# magic_break: enabled=1 +#======================================================================= +magic_break: enabled=0 + +#======================================================================= +# DEBUG_SYMBOLS: +# This loads symbols from the specified file for use in Bochs' internal +# debugger. Symbols are loaded into global context. This is equivalent to +# issuing ldsym debugger command at start up. +# +# Example: +# debug_symbols: file="kernel.sym" +# debug_symbols: file="kernel.sym", offset=0x80000000 +#======================================================================= +#debug_symbols: file="kernel.sym" + +print_timestamps: enabled=1 + +#======================================================================= +# PORT_E9_HACK: +# The 0xE9 port doesn't exists in normal ISA architecture. However, we +# define a convention here, to display on the console of the system running +# Bochs anything that is written to it. The idea is to provide debug output +# very early when writing BIOS or OS code for example, without having to +# bother with setting up a serial port or etc. Reading from port 0xE9 will +# will return 0xe9 to let you know if the feature is available. +# Leave this 0 unless you have a reason to use it. +# +# Example: +# port_e9_hack: enabled=1 +#======================================================================= +#port_e9_hack: enabled=1 + +#======================================================================= +# other stuff +#======================================================================= +# WARNING: This Bochs feature is not maintained yet. Is it still used ? +# To use it, set BX_LOAD32BITOSHACK in config.h to 1 and recompile Bochs. +#load32bitOSImage: os=nullkernel, path=../kernel.img, iolog=../vga_io.log +#load32bitOSImage: os=linux, path=../linux.img, iolog=../vga_io.log, initrd=../initrd.img + +#======================================================================= +# fullscreen: ONLY IMPLEMENTED ON AMIGA +# Request that Bochs occupy the entire screen instead of a +# window. +# +# Examples: +# fullscreen: enabled=0 +# fullscreen: enabled=1 +#======================================================================= +#fullscreen: enabled=0 +#screenmode: name="sample" + +#======================================================================= +# USER_PLUGIN: +# Load user-defined plugin. This option is available only if Bochs is +# compiled with plugin support. Maximum 8 different plugins are supported. +# See the example in the Bochs sources how to write a plugin device. +#======================================================================= +#user_plugin: name=testdev + +#======================================================================= +# for Macintosh, use the style of pathnames in the following +# examples. +# +# vgaromimage: :bios:VGABIOS-elpin-2.40 +# romimage: file=:bios:BIOS-bochs-latest, address=0xf0000 +# floppya: 1_44=[fd:], status=inserted +#======================================================================= +#:bios:VGABIOS-elpin-2.40 + +#======================================================================= +# MEGS +# Set the number of Megabytes of physical memory you want to emulate. +# The default is 32MB, most OS's won't need more than that. +# The maximum amount of memory supported is 2048Mb. +# The 'MEGS' option is deprecated. Use 'MEMORY' option instead. +#======================================================================= +#megs: 256 +#megs: 128 +#megs: 64 +#megs: 32 +#megs: 16 +#megs: 8 diff --git a/ape/idata.h b/ape/idata.h new file mode 100644 index 00000000..e69a6c79 --- /dev/null +++ b/ape/idata.h @@ -0,0 +1,119 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#ifndef APE_IDATA_H_ +#define APE_IDATA_H_ +#ifdef __ASSEMBLER__ +#include "ape/relocations.h" +/* clang-format off */ + +/ Links function from external DLL. +/ +/ This embeds a function pointer in the binary. The NT Executive +/ fills its value before control is handed off to the program. +/ +/ @note only ELF toolchains are powerful enough to use this +/ @see libc/nt/master.sh +/ @see ape/ape.lds +/ @see winimp +.macro .imp dll:req fn:req actual hint + .dll \dll + .section .piro.data.sort.iat.2.\dll\().2.\fn,"aw",@progbits + .type \fn,@object + .align __SIZEOF_POINTER__ +\fn: .quad RVA((.L\dll\().\fn)) + .size \fn,.-\fn + .globl \fn + .hidden \fn + .previous + .section .idata.ro.ilt.\dll\().2.\fn,"a",@progbits +.Lidata.ilt.\dll\().\fn: + .quad RVA((.L\dll\().\fn)) + .type .Lidata.ilt..L\dll\().\fn,@object + .size .Lidata.ilt..L\dll\().\fn,.-.Lidata.ilt.\dll\().\fn + .previous + .section .idata.ro.hnt.\dll\().2.\fn,"a",@progbits +.L\dll\().\fn: + .ifnb \hint # hint i.e. guess function ordinal + .short \hint + .else + .short 0 + .endif + .ifnb \actual # name + .asciz "\actual" + .else + .asciz "\fn" + .endif + .align 2 # documented requirement +/ .globl .L\dll\().\fn +/ .hidden .L\dll\().\fn + .type .L\dll\().\fn,@object + .size .L\dll\().\fn,.-.L\dll\().\fn + .previous +.endm + +/ Defines DLL import. +/ @note this is an implementation detail of .imp +.macro .dll name:req + .section .idata.ro.idt.2.\name,"aG",\name,comdat + .equ .Lidata.idt.\name,. + .long RVA(idata.ilt.\name) # ImportLookupTable + .long 0 # TimeDateStamp + .long 0 # ForwarderChain + .long RVA(.Lidata.str.\name) # DllNameRva + .long RVA(idata.iat.\name) # ImportAddressTable + .type .Lidata.idt.\name,@object + .size .Lidata.idt.\name,.-.Lidata.idt.\name + .previous + .section .idata.ro.ilt.\name\().1,"aG",\name,comdat + .align __SIZEOF_POINTER__ + .type idata.ilt.\name,@object +idata.ilt.\name: + .previous/* + ... + decentralized content + ... + */.section .idata.ro.ilt.\name\().3,"aG",\name,comdat + .quad 0 + .previous + .section .idata.ro.hnt.\name\().1,"aG",\name,comdat + .align __SIZEOF_POINTER__ + .type idata.hnt.\name,@object + .equ idata.hnt.\name,. + .previous + .section .piro.data.sort.iat.2.\name\().1,"awG",\name,comdat + .align __SIZEOF_POINTER__ + .type idata.iat.\name,@object +idata.iat.\name: + .previous/* + ... + decentralized content + ... + */.section .piro.data.sort.iat.2.\name\().3,"awG",\name,comdat + .quad 0 + .previous + .pushsection .rodata.str1.1,"aSM",@progbits,1 +.Lidata.str.\name: + .asciz "\name\().dll" + .popsection +.endm + +/* clang-format on */ +#endif /* __ASSEMBLER__ */ +#endif /* APE_IDATA_H_ */ diff --git a/ape/lib/apelib.mk b/ape/lib/apelib.mk new file mode 100644 index 00000000..1b885dfc --- /dev/null +++ b/ape/lib/apelib.mk @@ -0,0 +1,42 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += APE_LIB + +APE_LIB_ARTIFACTS += APE_LIB_A +APE_LIB = $(APE_LIB_A_DEPS) $(APE_LIB_A) +APE_LIB_A = o/$(MODE)/ape/lib/apelib.a +APE_LIB_A_FILES := $(wildcard ape/lib/*) +APE_LIB_A_HDRS = $(filter %.h,$(APE_LIB_A_FILES)) +APE_LIB_A_SRCS_S = $(filter %.S,$(APE_LIB_A_FILES)) +APE_LIB_A_SRCS_C = $(filter %.c,$(APE_LIB_A_FILES)) + +APE_LIB_A_SRCS = \ + $(APE_LIB_A_SRCS_S) \ + $(APE_LIB_A_SRCS_C) + +APE_LIB_A_OBJS = \ + $(APE_LIB_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(APE_LIB_A_SRCS_C:%.c=o/$(MODE)/%.o) \ + $(APE_LIB_A_SRCS:%=o/$(MODE)/%.zip.o) \ + o/$(MODE)/NOTICE.zip.o + +APE_LIB_A_CHECKS = $(APE_LIB_A_HDRS:%=o/$(MODE)/%.ok) +APE_LIB_A_DIRECTDEPS = LIBC_STR LIBC_STUBS +APE_LIB_A_DEPS = $(call uniq,$(foreach x,$(APE_LIB_A_DIRECTDEPS),$($(x)))) + +$(APE_LIB_A): ape/lib/ $(APE_LIB_A).pkg $(APE_LIB_A_OBJS) +$(APE_LIB_A).pkg: $(APE_LIB_A_OBJS) $(foreach x,$(APE_LIB_A_DIRECTDEPS),$($(x)_A).pkg) + +APE_LIB_LIBS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x))) +APE_LIB_SRCS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x)_SRCS)) +APE_LIB_HDRS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x)_HDRS)) +APE_LIB_BINS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x)_BINS)) +APE_LIB_CHECKS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x)_CHECKS)) +APE_LIB_OBJS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x)_OBJS)) +$(APE_LIB_OBJS): $(BUILD_FILES) libc/str/str.mk + +.PHONY: o/$(MODE)/ape/lib +o/$(MODE)/ape/lib: \ + $(APE_LIB_CHECKS) \ + $(APE_LIB_A) diff --git a/ape/lib/apm.h b/ape/lib/apm.h new file mode 100644 index 00000000..544e23b2 --- /dev/null +++ b/ape/lib/apm.h @@ -0,0 +1,59 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╠──────────────────────────────────────────────────────────────────────────────╣ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█▀█░▀█▀░█░█░█▀█░█░░░█░░░█░█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█░▄░░█░░█░█░█▀█░█░░░█░░░▀█▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░▀░▀░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀░░▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█▀█░█▀█░▀█▀░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀▀░█ █░██▀░░█░░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░▀░░░▀▀▀░▀░▀░░▀░░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀▀░█░█░█▀▀░█▀█░█░█░▀█▀░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░▄▄░░░▐█░░│ +│░░░░░░░█▀▀░▄▀▄░█▀▀░█░▄░█░█░░█░░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░▄▄▄░░░▄██▄░░█▀░░░█░▄░│ +│░░░░░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░▀░░▀░▀░▀▀▀░▀▀░▀▀▀░░░░░░░░░░▄██▀█▌░██▄▄░░▐█▀▄░▐█▀░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▐█▀▀▌░░░▄▀▌░▌░█░▌░░▌░▌░░│ +╠──────────────────────────────────────────────────────▌▀▄─▐──▀▄─▐▄─▐▄▐▄─▐▄─▐▄─│ +│ αcτµαlly pδrταblε εxεcµταblε § green energy │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#ifndef APE_LIB_APM_H_ +#define APE_LIB_APM_H_ + +/** + * @fileoverview Advanced Power Management. + * + *

APM is useful for exiting programs, without needing to ask the + * human to flip a physical switch or pass QEMU's -no-reboot flag. + * + *

Implementation Detail: Supporting ACPI would literally + * require implementing a programming language. + * + * @see APM BIOS Interface Specification v1.2 + * @since IBM PC/AT + */ + +#define APM_SERVICE 0x15 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +void apmoff(void) noreturn; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* APE_LIB_APM_H_ */ diff --git a/ape/lib/bootdr.S b/ape/lib/bootdr.S new file mode 100644 index 00000000..eecd59ae --- /dev/null +++ b/ape/lib/bootdr.S @@ -0,0 +1,36 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/macros.h" +#include "ape/notice.inc" +.section .real,"ax",@progbits +.yoink __FILE__ +.code16 + +/ Resets personal computer. +/ +/ @param di drive number, e.g. A:\ is 0x00, C:\ is 0x80 +/ @mode real +/ @noreturn +bootdr: push %bp + mov %sp,%bp + mov %di,%dx + int $0x19 + ljmp $0xf000,$0xfff0 + .endfn bootdr,globl diff --git a/ape/lib/e820map.S b/ape/lib/e820map.S new file mode 100644 index 00000000..c3990965 --- /dev/null +++ b/ape/lib/e820map.S @@ -0,0 +1,38 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" +#include "ape/config.h" +#include "ape/macros.h" +#include "ape/notice.inc" +.section .real,"ax",@progbits +.yoink __FILE__ +.code16 + + .globl e820map + .hidden e820map + .type e820map,@object + .size e820map,XLM_E820_SIZE + e820map = ape.xlm + XLM_E820 + + .globl e820map_xlm + .hidden e820map_xlm + .type e820map_xlm,@object + .size e820map_xlm,XLM_E820_SIZE + e820map_xlm = XLM(E820) diff --git a/ape/lib/flattenhighmemory.c b/ape/lib/flattenhighmemory.c new file mode 100644 index 00000000..8c0d8416 --- /dev/null +++ b/ape/lib/flattenhighmemory.c @@ -0,0 +1,59 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/config.h" +#include "ape/lib/pc.h" +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" + +/** + * Virtualizes physical memory. + * + * This function removes memory holes (discovered by e820() earlier) and + * creates the illusion of flat contiguous memory for as much RAM as the + * BIOS reports usable. Memory is safe to use and remap afterwards. + * + * @see ape/ape.S + */ +textreal void flattenhighmemory(struct SmapEntry *e820, struct PageTable *pml4t, + uint64_t *ptsp) { + struct SmapEntry *smap = e820; + struct SmapEntry *hole = e820; + uint64_t paddr = IMAGE_BASE_PHYSICAL; + uint64_t vaddr = IMAGE_BASE_VIRTUAL; + while (smap->size) { + while (smap->size && smap->type != kMemoryUsable) smap++; + paddr = roundup(max(paddr, smap->addr), PAGESIZE); + while (paddr < rounddown(smap->addr + smap->size, PAGESIZE)) { + while (hole->size && + (hole->type == kMemoryUsable || hole->addr + hole->size < paddr)) { + hole++; + } + if (paddr >= hole->addr && paddr < hole->addr + hole->size) { + paddr = roundup(hole->addr + hole->size, PAGESIZE); + } else { + uint64_t *entry = getpagetableentry(vaddr, 3, pml4t, ptsp); + *entry = paddr | PAGE_V | PAGE_RW; + vaddr += 0x1000; + paddr += 0x1000; + } + } + smap++; + } +} diff --git a/ape/lib/g_pml4t.S b/ape/lib/g_pml4t.S new file mode 100644 index 00000000..7c9d8e83 --- /dev/null +++ b/ape/lib/g_pml4t.S @@ -0,0 +1,32 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" +#include "ape/config.h" +#include "ape/macros.h" +#include "ape/notice.inc" +.section .real,"ax",@progbits +.yoink __FILE__ +.code16 + + .globl g_pml4t + .hidden g_pml4t + .type g_pml4t,@object + .size g_pml4t,0x1000 + g_pml4t = REAL_STACK_FRAME - 0x1000 diff --git a/ape/lib/g_ptsp.S b/ape/lib/g_ptsp.S new file mode 100644 index 00000000..b7cc8db1 --- /dev/null +++ b/ape/lib/g_ptsp.S @@ -0,0 +1,38 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" +#include "ape/config.h" +#include "ape/macros.h" +#include "ape/notice.inc" +.section .real,"ax",@progbits +.yoink __FILE__ +.code16 + + .globl g_ptsp + .hidden g_ptsp + .type g_ptsp,@object + .size g_ptsp,XLM_PAGE_TABLE_STACK_POINTER_SIZE + g_ptsp = ape.xlm + XLM_PAGE_TABLE_STACK_POINTER + + .globl g_ptsp_xlm + .hidden g_ptsp_xlm + .type g_ptsp_xlm,@object + .size g_ptsp_xlm,XLM_PAGE_TABLE_STACK_POINTER_SIZE + g_ptsp_xlm = XLM(PAGE_TABLE_STACK_POINTER) diff --git a/ape/lib/getpagetableentry.c b/ape/lib/getpagetableentry.c new file mode 100644 index 00000000..1e3b6438 --- /dev/null +++ b/ape/lib/getpagetableentry.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" +#include "libc/assert.h" + +textreal static uint64_t pushpagetable(uint64_t *ptsp) { + return (*ptsp -= PAGESIZE) | PAGE_V | PAGE_RW; +} + +textreal uint64_t *getpagetableentry(uint64_t vaddr, unsigned depth, + struct PageTable *pml4t, uint64_t *ptsp) { + assert(depth <= 3); + assert(*ptsp % PAGESIZE == 0); + assert((intptr_t)pml4t % PAGESIZE == 0); + unsigned char shift = 39; + for (;;) { + uint64_t *entry = &pml4t->p[(vaddr >> shift) & 511]; + if (!depth--) return entry; + shift -= 9; + if (!*entry) *entry = pushpagetable(ptsp); + pml4t = (void *)(*entry & PAGE_TA); + } +} diff --git a/ape/lib/kbiosdataarea.S b/ape/lib/kbiosdataarea.S new file mode 100644 index 00000000..4088616e --- /dev/null +++ b/ape/lib/kbiosdataarea.S @@ -0,0 +1,46 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" +#include "ape/config.h" +#include "ape/macros.h" +#include "ape/notice.inc" +.section .real,"ax",@progbits +.yoink __FILE__ +.code16 + + .globl kBiosDataArea + .hidden kBiosDataArea + .type kBiosDataArea,@object + .size kBiosDataArea,XLM_BIOS_DATA_AREA_SIZE + kBiosDataArea = ape.xlm + XLM_BIOS_DATA_AREA + + .globl kBiosDataAreaXlm + .hidden kBiosDataAreaXlm + .type kBiosDataAreaXlm,@object + .size kBiosDataAreaXlm,XLM_BIOS_DATA_AREA_SIZE + kBiosDataAreaXlm = XLM(BIOS_DATA_AREA) + + .section .sort.real.init.2.kBiosDataArea,"ax",@progbits + movpp %ds,%es # copy bios data to valid page + mov $PC_BIOS_DATA_AREA,%si + mov $XLM(BIOS_DATA_AREA),%di + mov $XLM_BIOS_DATA_AREA_SIZE,%cx + rep movsb + .previous diff --git a/ape/lib/pageunmap.c b/ape/lib/pageunmap.c new file mode 100644 index 00000000..d09bf2c8 --- /dev/null +++ b/ape/lib/pageunmap.c @@ -0,0 +1,27 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" +#include "libc/bits/bits.h" + +textreal void pageunmap(uint64_t vaddr) { + uint64_t *entry = getpagetableentry(vaddr, 3, &g_pml4t, &g_ptsp_xlm); + *entry &= ~PAGE_V; + invlpg(vaddr); +} diff --git a/ape/lib/pc.h b/ape/lib/pc.h new file mode 100644 index 00000000..fd1adeaa --- /dev/null +++ b/ape/lib/pc.h @@ -0,0 +1,239 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╠──────────────────────────────────────────────────────────────────────────────╣ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█▀█░▀█▀░█░█░█▀█░█░░░█░░░█░█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█░▄░░█░░█░█░█▀█░█░░░█░░░▀█▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░▀░▀░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀░░▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█▀█░█▀█░▀█▀░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀▀░█ █░██▀░░█░░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░▀░░░▀▀▀░▀░▀░░▀░░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀▀░█░█░█▀▀░█▀█░█░█░▀█▀░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░▄▄░░░▐█░░│ +│░░░░░░░█▀▀░▄▀▄░█▀▀░█░▄░█░█░░█░░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░▄▄▄░░░▄██▄░░█▀░░░█░▄░│ +│░░░░░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░▀░░▀░▀░▀▀▀░▀▀░▀▀▀░░░░░░░░░░▄██▀█▌░██▄▄░░▐█▀▄░▐█▀░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▐█▀▀▌░░░▄▀▌░▌░█░▌░░▌░▌░░│ +╠──────────────────────────────────────────────────────▌▀▄─▐──▀▄─▐▄─▐▄▐▄─▐▄─▐▄─│ +│ αcτµαlly pδrταblε εxεcµταblε § ibm personal computer │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#ifndef APE_LIB_PC_H_ +#define APE_LIB_PC_H_ + +#define BOOTSIG 0xaa55 /* master boot record signature */ +#define PC_BIOS_DATA_AREA 0x400 + +#define kInterruptFlag (1u << 9) + +/* FPU Status Word (x87) + @see Intel Manual V1 §8.1.3 + IE: Invalid Operation ────────────────┐ + DE: Denormalized Operand ────────────┐│ + ZE: Zero Divide ────────────────────┐││ + OE: Overflow Flag ─────────────────┐│││ + UE: Underflow Flag ───────────────┐││││ + PE: Precision Flag ──────────────┐│││││ + SF: Stack Fault ────────────────┐││││││ + ES: Exception Summary Status ──┐│││││││ + C0-3: Condition Codes ──┬────┐ ││││││││ + Top of Stack Pointer ─────┐ │ ││││││││ + B: FPU Busy ───────────┐│ │ │ ││││││││ + ││┌┴┐┌┼┐││││││││ + │↓│ │↓↓↓││││││││*/ +#define FPU_ZE 0b0000000000100000000000100 +#define FPU_C0 0b0000000000000000100000000 +#define FPU_C1 0b0000000000000001000000000 +#define FPU_C2 0b0000000000000010000000000 +#define FPU_C3 0b0000000000100000000000000 + +#define CR0_PE (1u << 0) /* protected mode enabled */ +#define CR0_MP (1u << 1) /* monitor coprocessor */ +#define CR0_EM (1u << 2) /* no x87 fpu present if set */ +#define CR0_TS (1u << 3) /* task switched x87 */ +#define CR0_ET (1u << 4) /* extension type 287 or 387 */ +#define CR0_NE (1u << 5) /* enable x87 error reporting */ +#define CR0_WP (1u << 16) /* write protect read-only pages @pl0 */ +#define CR0_AM (1u << 18) /* alignment mask */ +#define CR0_NW (1u << 29) /* global write-through cache disable */ +#define CR0_CD (1u << 30) /* global cache disable */ +#define CR0_PG (1u << 31) /* paging enabled */ + +#define CR4_VME (1u << 0) /* virtual 8086 mode extension */ +#define CR4_PVI (1u << 1) /* protected mode virtual interrupts */ +#define CR4_TSD (1u << 2) /* time stamp disable (rdtsc) */ +#define CR4_DE (1u << 3) /* debugging extensions */ +#define CR4_PSE (1u << 4) /* page size extension */ +#define CR4_PAE (1u << 5) /* physical address extension */ +#define CR4_MCE (1u << 6) /* machine check exception */ +#define CR4_PGE (1u << 7) /* page global enabled */ +#define CR4_OSFXSR (1u << 9) /* enable SSE and fxsave/fxrestor */ +#define CR4_OSXMMEXCPT (1u << 10) /* enable unmasked SSE exceptions */ +#define CR4_LA57 (1u << 12) /* enable level-5 paging */ +#define CR4_VMXE (1u << 13) /* enable VMX operations */ +#define CR4_SMXE (1u << 14) /* enable SMX operations */ +#define CR4_FSGSBASE (1u << 16) /* enable *FSBASE and *GSBASE instructions */ +#define CR4_PCIDE (1u << 17) /* enable process-context identifiers */ +#define CR4_OSXSAVE (1u << 18) /* enable XSAVE */ + +#define XCR0_X87 (1u << 0) +#define XCR0_SSE (1u << 1) +#define XCR0_AVX (1u << 2) +#define XCR0_BNDREG (1u << 3) +#define XCR0_BNDCSR (1u << 4) +#define XCR0_OPMASK (1u << 5) +#define XCR0_ZMM_HI256 (1u << 6) +#define XCR0_HI16_ZMM (1u << 7) + +#define EFER 0xC0000080 /* extended feature enable register */ +#define EFER_SCE (1u << 0) /* system call extensions */ +#define EFER_LME (1u << 8) /* long mode enable */ +#define EFER_LMA (1u << 10) /* long mode active */ +#define EFER_NXE (1u << 11) /* no-execute enable */ + +#define GDT_REAL_CODE 8 +#define GDT_REAL_DATA 16 +#define GDT_LEGACY_CODE 24 +#define GDT_LEGACY_DATA 32 +#define GDT_LONG_CODE 40 +#define GDT_LONG_DATA 48 + +#define PIC1 0x20 /* IO base address for master PIC */ +#define PIC2 0xA0 /* IO base address for slave PIC */ +#define PIC1_CMD PIC1 +#define PIC1_DATA (PIC1 + 1) +#define PIC2_CMD PIC2 +#define PIC2_DATA (PIC2 + 1) +#define PIC_EOI 0x20 /* End-of-interrupt command code */ +#define PIC_READ_IRR 0x0a /* OCW3 irq ready next CMD read */ +#define PIC_READ_ISR 0x0b /* OCW3 irq service next CMD read */ + +/* Long Mode Paging + @see Intel Manual V.3A §4.1 §4.5 + IsValid (ignored on CR3) V┐ + ┌Block Instr. Fetches (if NXE) IsWritable (ignored on CR3) RW┐│ + │ Permit User-Mode Access - u┐││ + │ Page-level Write-Through - PWT┐│││ + │ Page-level Cache Disable - PCD┐││││ + │ Set if has been read - Accessed┐│││││ + │ Set if has been written - Dirty┐││││││ + │ IsPage (if PDPTE/PDE) or PAT (if PT)┐│││││││ + │ (If this maps 2MB/1GB page and CR4.PGE) Global┐││││││││ + │ (If IsPage 2MB/1GB, see Intel V3A § 11.12) PAT │││││││││ + │ │ │││││││││ + │ ┌────────────────────────────────────┤ │││││││││ + │ Must Be 0┐│ Next Page Table Address (!IsPage) │ │││││││││ + │ │├────────────────────────────────────┤ │││││││││ + │ ││ Physical Address 4KB │ │││││││││ + │┌───┐┌─────┐│├───────────────────────────┐ │ign│││││││││ + ││PKE││ ign │││ Physical Address 2MB │ │┌┴┐│││││││││ + ││ ││ ││├──────────────────┐ │ ││ ││││││││││ + ││ ││ │││ Phys. Addr. 1GB │ │ ││ ││││││││││ + ││ ││ │││ │ │ ││ ││││││││││ + 0b00000000000011111111111111111111111111111111111111000000000000 + 6666555555555544444444443333333333222222222211111111110000000000 + 3210987654321098765432109876543210987654321098765432109876543210*/ +#define PAGE_V /* */ 0b000000001 +#define PAGE_RW /* */ 0b000000010 +#define PAGE_U /* */ 0b000000100 +#define PAGE_2MB /* */ 0b110000000 +#define PAGE_1GB /* */ 0b110000000 +#define PAGE_TA 0b011111111111111111111111111111111111111000000000000 +#define PAGE_PA2 0b11111111111111111111111111111000000000000000000000 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +#include "ape/config.h" + +struct thatispacked GlobalDescriptorTable { + uint16_t size; + uint64_t *entries; +}; + +/** + * Memory hole map. + * @see wiki.osdev.org/Detecting_Memory_(x86) + * @since 2002 + */ +struct SmapEntry { + uint64_t addr; + uint64_t size; + enum { + kMemoryUsable = 1, + kMemoryUnusable = 2, + kMemoryAcpiReclaimable = 3, + kMemoryAcpiNvs = 4, + kMemoryBad = 5 + } type; + uint32_t __acpi3; /* is abstracted */ +}; + +struct IdtDescriptor { + uint16_t offset_1; /* offset bits 0..15 */ + uint16_t selector; /* a code segment selector in GDT or LDT */ + uint8_t ist; /* bits 0..2 hold stack table offset, rest are zero */ + uint8_t type_attr; /* type and attributes */ + uint16_t offset_2; /* offset bits 16..31 */ + uint32_t offset_3; /* offset bits 32..63 */ + uint32_t zero; /* reserved */ +}; + +struct thatispacked PageTable { + uint64_t p[512]; +} aligned(PAGESIZE); + +extern struct PageTable g_pml4t; +extern struct GlobalDescriptorTable gdt; + +extern const unsigned char kBiosDataArea[256]; +extern const unsigned char kBiosDataAreaXlm[256]; + +extern struct SmapEntry e820map[XLM_E820_SIZE / sizeof(struct SmapEntry)]; +extern struct SmapEntry e820map_xlm[XLM_E820_SIZE / sizeof(struct SmapEntry)]; + +extern uint64_t g_ptsp; +extern uint64_t g_ptsp_xlm; + +void bootdr(char drive) noreturn; + +void smapsort(struct SmapEntry *); +uint64_t *getpagetableentry(uint64_t, unsigned, struct PageTable *, uint64_t *); +void flattenhighmemory(struct SmapEntry *, struct PageTable *, uint64_t *); +void pageunmap(uint64_t); + +forceinline unsigned long eflags(void) { + unsigned long res; + asm("pushf\n\t" + "pop\t%0" + : "=rm"(res)); + return res; +} + +forceinline unsigned char inb(unsigned short port) { + unsigned char al; + asm volatile("inb\t%1,%0" : "=a"(al) : "dN"(port)); + return al; +} + +forceinline void outb(unsigned short port, unsigned char byte) { + asm volatile("outb\t%0,%1" + : /* no inputs */ + : "a"(byte), "dN"(port)); +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* APE_LIB_PC_H_ */ diff --git a/ape/lib/pic.c b/ape/lib/pic.c new file mode 100644 index 00000000..2ca33fdb --- /dev/null +++ b/ape/lib/pic.c @@ -0,0 +1,140 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" + +#define ICW1_ICW4 0x01 /* ICW4 (not) needed */ +#define ICW1_SINGLE 0x02 /* Single (cascade) mode */ +#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */ +#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */ +#define ICW1_INIT 0x10 /* Initialization - required! */ + +#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */ +#define ICW4_AUTO 0x02 /* Auto (normal) EOI */ +#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */ +#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */ +#define ICW4_SFNM 0x10 /* Special fully nested (not) */ + +static inline void io_wait(void) { + /* Magic technique from Linux, according to: + * wiki.osdev.org/index.php?title=Inline_Assembly/Examples&oldid=23541 + */ + outb(0x80, 0); +} + +void PIC_sendEOI(unsigned char irq) { + if (irq >= 8) outb(PIC2_CMD, PIC_EOI); + outb(PIC1_CMD, PIC_EOI); +} + +bool AreInterruptsEnabled() { + return (eflags() & kInterruptFlag) == kInterruptFlag; +} + +nodiscard forceinline unsigned long irqdisable(void) { + unsigned long eflags; + asm("pushf\n\t" + "cli\n\t" + "pop\t%0" + : "=r"(eflags) + : /* no inputs */ + : "cc"); + return eflags; +} + +forceinline void irqrestore(unsigned long eflags) { + asm volatile( + "push\t%0\n\t" + "popf" + : /* no outputs */ + : "rm"(eflags) + : "cc"); +} + +/** + * @param offset1 is vector offset for master PIC + * vectors on the master become offset1..offset1+7 + * @param offset2 is same for slave PIC: offset2..offset2+7 + **/ +void PIC_remap(int offset1, int offset2) { + unsigned char a1, a2; + a1 = inb(PIC1_DATA); // save masks + a2 = inb(PIC2_DATA); + outb(PIC1_CMD, + ICW1_INIT | + ICW1_ICW4); // starts the initialization sequence (in cascade mode) + io_wait(); + outb(PIC2_CMD, ICW1_INIT | ICW1_ICW4); + io_wait(); + outb(PIC1_DATA, offset1); // ICW2: Master PIC vector offset + io_wait(); + outb(PIC2_DATA, offset2); // ICW2: Slave PIC vector offset + io_wait(); + outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at + // IRQ2 (0000 0100) + io_wait(); + outb(PIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010) + io_wait(); + outb(PIC1_DATA, ICW4_8086); + io_wait(); + outb(PIC2_DATA, ICW4_8086); + io_wait(); + outb(PIC1_DATA, a1); // restore saved masks. + outb(PIC2_DATA, a2); +} + +void IRQ_set_mask(unsigned char IRQline) { + uint16_t port; + uint8_t value; + if (IRQline < 8) { + port = PIC1_DATA; + } else { + port = PIC2_DATA; + IRQline -= 8; + } + value = inb(port) | (1 << IRQline); + outb(port, value); +} + +void IRQ_clear_mask(unsigned char IRQline) { + uint16_t port; + uint8_t value; + if (IRQline < 8) { + port = PIC1_DATA; + } else { + port = PIC2_DATA; + IRQline -= 8; + } + value = inb(port) & ~(1 << IRQline); + outb(port, value); +} + +static uint16_t __pic_get_irq_reg(int ocw3) { + /* OCW3 to PIC CMD to get the register values. PIC2 is chained, and + * represents IRQs 8-15. PIC1 is IRQs 0-7, with 2 being the chain */ + outb(PIC1_CMD, ocw3); + outb(PIC2_CMD, ocw3); + return (inb(PIC2_CMD) << 8) | inb(PIC1_CMD); +} + +/* Returns the combined value of the cascaded PICs irq request register */ +uint16_t pic_get_irr(void) { return __pic_get_irq_reg(PIC_READ_IRR); } + +/* Returns the combined value of the cascaded PICs in-service register */ +uint16_t pic_get_isr(void) { return __pic_get_irq_reg(PIC_READ_ISR); } diff --git a/ape/lib/smapsort.c b/ape/lib/smapsort.c new file mode 100644 index 00000000..c8b160ad --- /dev/null +++ b/ape/lib/smapsort.c @@ -0,0 +1,47 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" + +textreal static unsigned smapcount(const struct SmapEntry *se) { + unsigned i = 0; + while (se[i].size) ++i; + return i; +} + +textreal static void smapsorter(size_t n, struct SmapEntry a[n]) { + struct SmapEntry t; + unsigned i, j; + for (i = 1; i < n; ++i) { + j = i; + t = a[i]; + while (j > 0 && (intptr_t)t.addr - (intptr_t)a[j - 1].addr) { + a[j] = a[j - 1]; + --j; + } + a[j] = t; + } +} + +/** + * Sorts BIOS e820 memory map. + */ +textreal void smapsort(struct SmapEntry *smap) { + smapsorter(smapcount(smap), smap); +} diff --git a/ape/macros.h b/ape/macros.h new file mode 100644 index 00000000..1439fe29 --- /dev/null +++ b/ape/macros.h @@ -0,0 +1,281 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╠──────────────────────────────────────────────────────────────────────────────╣ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█▀█░▀█▀░█░█░█▀█░█░░░█░░░█░█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█░▄░░█░░█░█░█▀█░█░░░█░░░▀█▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░▀░▀░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀░░▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█▀█░█▀█░▀█▀░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀▀░█ █░██▀░░█░░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░▀░░░▀▀▀░▀░▀░░▀░░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀▀░█░█░█▀▀░█▀█░█░█░▀█▀░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░▄▄░░░▐█░░│ +│░░░░░░░█▀▀░▄▀▄░█▀▀░█░▄░█░█░░█░░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░▄▄▄░░░▄██▄░░█▀░░░█░▄░│ +│░░░░░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░▀░░▀░▀░▀▀▀░▀▀░▀▀▀░░░░░░░░░░▄██▀█▌░██▄▄░░▐█▀▄░▐█▀░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▐█▀▀▌░░░▄▀▌░▌░█░▌░░▌░▌░░│ +╠──────────────────────────────────────────────────────▌▀▄─▐──▀▄─▐▄─▐▄▐▄─▐▄─▐▄─│ +│ αcτµαlly pδrταblε εxεcµταblε § macros │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#ifndef APE_MACROS_H_ +#define APE_MACROS_H_ +#include "libc/macros.h" +#ifdef __ASSEMBLER__ +/* clang-format off */ + +/** + * @fileoverview Macros relevant to αcτµαlly pδrταblε εxεcµταblε. + */ + +/ Calls near (i.e. pc+pcrel<64kB) FUNCTION. +/ @mode long,legacy,real +/ @cost 9 bytes overhead +.macro rlcall function:req + .byte 0x50 # push %[er]ax + .byte 0xb8,0,0 # mov $?,%[e]ax + jmp 911f + .byte 0x58 # pop %[er]ax + .byte 0xe8 # call Jvds + .long \function\()-.-4 + jmp 912f +911: .byte 0x58 # pop %[er]ax + .byte 0xe8 # call Jvds + .short \function\()-.-2 +912: +.endm + +/ Loads far (i.e. <1mb) abs constexpr ADDRESS into ES:DI+EDX+RDX. +/ @mode long,legacy,real +.macro movesdi address:req + .byte 0xbf # mov $0x????xxxx,%[e]di + .short \address>>4 + .byte 0x8e,0xc7 # mov %di,%es + .byte 0xbf # mov $0x????xxxx,%[e]di + .short \address&0xf + jmp 297f + .byte 0xbf # mov $0x????xxxx,%edi + .long \address +297: +.endm + +/ Loads 16-bit CONSTEXPR into Qw-register w/ optional zero-extend. +/ @mode long,legacy,real +.macro bbmov constexpr:req abcd abcd.hi:req abcd.lo:req + .ifnb \abcd + .if (\constexpr)<128 && (\constexpr)>=0 + pushpop \constexpr,\abcd + .exitm + .endif + .endif + movb $(\constexpr)>>8&0xff,\abcd.hi + movb $(\constexpr)&0xff,\abcd.lo +.endm + +/ Compares 16-bit CONSTEXPR with Qw-register. +/ @mode long,legacy,real +.macro bbcmp constexpr:req abcd.hi:req abcd.lo:req + cmpb $(\constexpr)>>8&0xff,\abcd.hi + jnz 387f + cmpb $(\constexpr)&0xff,\abcd.lo +387: +.endm + +/ Adds 16-bit CONSTEXPR to Qw-register. +/ @mode long,legacy,real +.macro bbadd constexpr:req abcd.hi:req abcd.lo:req + addb $(\constexpr)&0xff,\abcd.lo + .if (\constexpr) != 0 + adcb $(\constexpr)>>8&0xff,\abcd.hi + .endif +.endm + +/ Subtracts 16-bit CONSTEXPR from Qw-register. +/ @mode long,legacy,real +.macro bbsub constexpr:req abcd.hi:req abcd.lo:req + subb $(\constexpr)&0xff,\abcd.lo + .if (\constexpr) != 0 + sbbb $(\constexpr)>>8&0xff,\abcd.hi + .endif +.endm + +/ Ands Qw-register with 16-bit CONSTEXPR. +/ @mode long,legacy,real +.macro bband constexpr:req abcd.hi:req abcd.lo:req + .if ((\constexpr)&0xff) != 0xff || ((\constexpr)>>8&0xff) == 0xff + andb $(\constexpr)&0xff,\abcd.lo + .endif + .if ((\constexpr)>>8&0xff) != 0xff + andb $(\constexpr)>>8&0xff,\abcd.hi + .endif +.endm + +/ Ors Qw-register with 16-bit CONSTEXPR. +/ @mode long,legacy,real +.macro bbor constexpr:req abcd.hi:req abcd.lo:req + .if ((\constexpr)&0xff) != 0 || ((\constexpr)>>8&0xff) != 0 + orb $(\constexpr)&0xff,\abcd.lo + .endif + .if ((\constexpr)>>8&0xff) != 0 + orb $(\constexpr)>>8&0xff,\abcd.hi + .endif +.endm + +/ Performs ACTION only if in real mode. +/ @mode long,legacy,real +.macro rlo clobber:req action:vararg +990: mov $0,\clobber + .if .-990b!=3 + .error "bad clobber or assembler mode" + .endif +991: \action + .rept 2-(.-991b) + nop + .endr + .if .-991b!=2 + .error "ACTION must be 1-2 bytes" + .endif +.endm + +/ Initializes real mode stack. +/ The most holiest of holy code. +/ @mode real +/ @see www.pcjs.org/pubs/pc/reference/intel/8086/ +.macro rlstack seg:req addr:req + cli + mov \seg,%ss + mov \addr,%sp + sti +.endm + +/ Symbolic Linker-Defined Binary Content. +.macro .stub name:req kind:req default type=@object + .ifnb \default + .equ \name,\default + .endif + .\kind \name + .type \name,\type + .weak \name +.hidden \name +.endm + +/ Symbolic Linker-Defined Binary-Encoded-Bourne Content. +/ @param units is the number of encoded 32-bit values to insert, +/ e.g. \000 can be encoded as 0x3030305c. +.macro .shstub name:req units:req + ss \name,0 + .if \units>1 + ss \name,1 + .if \units>2 + ss \name,2 + ss \name,3 + .if \units>4 + ss \name,4 + ss \name,5 + ss \name,6 + ss \name,7 + .endif + .endif + .endif +.endm +.macro ss name n + .stub \name\()_bcs\n,long +.endm + +/* clang-format on */ +#elif defined(__LINKER__) + +#define BCX_NIBBLE(X) ((((X)&0xf) > 0x9) ? ((X)&0xf) + 0x37 : ((X)&0xf) + 0x30) +#define BCX_OCTET(X) ((BCX_NIBBLE((X) >> 4) << 8) | (BCX_NIBBLE((X) >> 0) << 0)) +#define BCX_INT16(X) ((BCX_OCTET((X) >> 8) << 16) | (BCX_OCTET((X) >> 0) << 0)) +#define BCXSTUB(SYM, X) \ + HIDDEN(SYM##_bcx0 = BCX_INT16((X) >> 48)); \ + HIDDEN(SYM##_bcx1 = BCX_INT16((X) >> 32)); \ + HIDDEN(SYM##_bcx2 = BCX_INT16((X) >> 16)); \ + HIDDEN(SYM##_bcx3 = BCX_INT16((X) >> 0)) + +/** + * Binary coded backslash octet support. + * + *

This allows linker scripts to generate printf commands. + */ +#define BCO_OCTET(X) (((X)&0x7) + 0x30) +#define BCOB_UNIT(X) \ + ((BCO_OCTET((X) >> 0) << 24) | (BCO_OCTET((X) >> 3) << 16) | \ + (BCO_OCTET(((X)&0xff) >> 6) << 8) | 0x5c) + +#define PFBYTE(SYM, X, I) HIDDEN(SYM##_bcs##I = BCOB_UNIT((X) >> ((I)*8))) +#define PFSTUB2(SYM, X) \ + HIDDEN(SYM = (X)); \ + PFBYTE(SYM, X, 0); \ + PFBYTE(SYM, X, 1) +#define PFSTUB4(SYM, X) \ + PFSTUB2(SYM, X); \ + PFBYTE(SYM, X, 2); \ + PFBYTE(SYM, X, 3) +#define PFSTUB8(SYM, X) \ + PFSTUB4(SYM, X); \ + PFBYTE(SYM, X, 4); \ + PFBYTE(SYM, X, 5); \ + PFBYTE(SYM, X, 6); \ + PFBYTE(SYM, X, 7) + +/** + * Binary coded decimal support. + * + *

This allows linker scripts to generate dd commands. Leading spaces + * need to be inserted so Mac doesn't consider them octal; therefore, + * parameters must be quoted; and eight digits should be good enough. + */ +#define SHSTUB2(SYM, X) \ + HIDDEN(SYM##_bcs0 = BCD10K(X)); \ + HIDDEN(SYM##_bcs1 = BCD(X)) +#define BCD(X) \ + ((X) == 0 \ + ? 0x20202030 \ + : (X) < 10 ? 0x30202020 + (((X) % 10) << 24) \ + : (X) < 100 ? 0x30302020 + (((X) % 10) << 24) + \ + (((X) / 10 % 10) << 16) \ + : (X) < 1000 ? 0x30303020 + (((X) % 10) << 24) + \ + (((X) / 10 % 10) << 16) + \ + (((X) / 100 % 10) << 8) \ + : 0x30303030 + (((X) % 10) << 24) + \ + (((X) / 10 % 10) << 16) + \ + (((X) / 100 % 10) << 8) + \ + (((X) / 1000 % 10) << 0)) +#define BCD10K(X) \ + ((X) < 10000 \ + ? 0x20202020 \ + : (X) < 100000 \ + ? 0x30202020 + (((X) / 10000 % 10) << 24) \ + : (X) < 1000000 \ + ? 0x30302020 + (((X) / 10000 % 10) << 24) + \ + (((X) / 100000 % 10) << 16) \ + : (X) < 10000000 \ + ? 0x30303020 + (((X) / 10000 % 10) << 24) + \ + (((X) / 100000 % 10) << 16) + \ + (((X) / 1000000 % 10) << 8) \ + : (X) < 100000000 \ + ? 0x30303030 + (((X) / 10000 % 10) << 24) + \ + (((X) / 100000 % 10) << 16) + \ + (((X) / 1000000 % 10) << 8) + \ + (((X) / 10000000 % 10) << 0) \ + : 0xffffffffffffffff) + +#endif /* __ASSEMBLER__ */ +#endif /* APE_MACROS_H_ */ diff --git a/ape/mtime.h b/ape/mtime.h new file mode 100644 index 00000000..181a2e0c --- /dev/null +++ b/ape/mtime.h @@ -0,0 +1,41 @@ +#ifndef COSMOPOLITAN_APE_MTIME_H_ +#define COSMOPOLITAN_APE_MTIME_H_ +#include "libc/dos.h" + +/** + * @fileoverview Deterministic last modified timestamp embedding. + */ + +#ifndef MTIME_YEAR +#define MTIME_YEAR 2019 +#endif + +#ifndef MTIME_MONTH +#define MTIME_MONTH 1 +#endif + +#ifndef MTIME_DAY +#define MTIME_DAY 1 +#endif + +#ifndef MTIME_HOUR +#define MTIME_HOUR 0 +#endif + +#ifndef MTIME_MINUTES +#define MTIME_MINUTES 0 +#endif + +#ifndef MTIME_SECONDS +#define MTIME_SECONDS 0 +#endif + +#ifndef ZIP_MTIME_DATE +#define ZIP_MTIME_DATE DOS_DATE(MTIME_YEAR, MTIME_MONTH, MTIME_DAY) +#endif + +#ifndef ZIP_MTIME_TIME +#define ZIP_MTIME_TIME DOS_TIME(MTIME_HOUR, MTIME_MINUTES, MTIME_SECONDS) +#endif + +#endif /* COSMOPOLITAN_APE_MTIME_H_ */ diff --git a/ape/mz.ansi b/ape/mz.ansi new file mode 100644 index 00000000..29efb1d0 --- /dev/null +++ b/ape/mz.ansi @@ -0,0 +1,69 @@ +ProTip: cat ape/mz.ansi + +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ + +The αcτµαlly pδrταblε εxεcµταblε software is dedicated to: + + Mark "Zibo" Joseph Zbikowski + Architect @ Microsoft Corporation & Early Computer Hacker + Whose Initials Grace Every Executable + diff --git a/ape/notice.inc b/ape/notice.inc new file mode 100644 index 00000000..e69de29b diff --git a/ape/relocations.h b/ape/relocations.h new file mode 100644 index 00000000..6dc3ad38 --- /dev/null +++ b/ape/relocations.h @@ -0,0 +1,67 @@ +#ifndef COSMOPOLITAN_APE_RELOCATIONS_H_ +#define COSMOPOLITAN_APE_RELOCATIONS_H_ +/*─────────────────────────────────────────────────────────────────────────────╗ +│ αcτµαlly pδrταblε εxεcµταblε § relocations │ +╚──────────────────────────────────────────────────────────────────────────────╝ + One of the things αcτµαlly pδrταblε εxεcµταblε does a good job + abstracting, is how a program needs to exist at three addresses + simultaneously during the early stages of the loading process. + + By default, the linker calculates all symbols using virtual addresses. + In some cases it's necessary to use addend macros that change virtual + addresses into the other two types: physical and real. */ + +#ifndef IMAGE_BASE_VIRTUAL +#define IMAGE_BASE_VIRTUAL 0x400000 +#endif + +#ifndef IMAGE_BASE_PHYSICAL +#define IMAGE_BASE_PHYSICAL 0x100000 +#endif + +/** + * Location of anything goes memory for real mode. + * + * The MBR won't load program content beyond this address, so we have + * room for buffers, page tables, etc. before we reach the stack frame. + */ +#ifndef REAL_SCRATCH_AREA +#define REAL_SCRATCH_AREA 0x40000 +#endif + +/** + * Location of real mode 64kb stack frame. + * + * This address was chosen because memory beyond 0x80000 can't be + * accessed safely without consulting e820. + */ +#ifndef REAL_STACK_FRAME +#define REAL_STACK_FRAME 0x70000 +#endif + +/** + * Returns Relative Virtual Address. + */ +#define RVA(x) ((x) - (IMAGE_BASE_VIRTUAL)) + +/** + * Adjusts virtual address so it's relative to load address. + */ +#define PHYSICAL(x) ((x) - (IMAGE_BASE_VIRTUAL - IMAGE_BASE_PHYSICAL)) + +/** + * Makes high-entropy read-only addresses relocatable in real mode. + */ +#define REAL(x) ((x) - (IMAGE_BASE_VIRTUAL - IMAGE_BASE_REAL)) + +#if IMAGE_BASE_VIRTUAL % 0x200000 != 0 +#error "IMAGE_BASE_VIRTUAL must be 2mb aligned" +#endif +#if IMAGE_BASE_PHYSICAL % 0x1000 != 0 +#error "IMAGE_BASE_PHYSICAL must be 4kb aligned" +#endif +#if IMAGE_BASE_REAL % 0x1000 != 0 +#error "IMAGE_BASE_REAL must be 4kb aligned" +#endif + +#endif /* COSMOPOLITAN_APE_RELOCATIONS_H_ */ diff --git a/build/actuallynice b/build/actuallynice new file mode 100755 index 00000000..e68dcc2d --- /dev/null +++ b/build/actuallynice @@ -0,0 +1,28 @@ +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ +# +# SYNOPSIS +# +# Program Deprioritizer +# +# OVERVIEW +# +# This is a drop-in replacement for the traditional Unix `nice` +# command that also invokes `ionice`, which is important, since +# network and traffic is usually what clobber the system. + +if [ -z "$IONICE" ]; then + if IONICE=$(command -v ionice 2>/dev/null); then + IONICE="$IONICE -c3" + fi +fi + +if [ -z "$NICE" ]; then + NICE=$(command -v nice 2>/dev/null) +fi + +if [ -z "$IONICE$NICE" ]; then + echo "error: can't be nice" >&2 +fi + +exec $IONICE $NICE "$@" diff --git a/build/archive b/build/archive new file mode 100755 index 00000000..663b6bf7 --- /dev/null +++ b/build/archive @@ -0,0 +1,80 @@ +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ +# +# OVERVIEW +# +# GNU Archiver Veneer +# +# DESCRIPTION +# +# This script wraps normal archive commands that're transparently +# passed-through. It adds value too, by addressing difficulties +# that would normally cause a developer to need `make clean`. +# +# EXAMPLE +# +# build/archive ar rcsD library.a foo.o ... + +if [ ! -d o/third_party/gcc ]; then + third_party/gcc/unbundle.sh +fi + +export LC_ALL=C +RM=${RM:-$(command -v rm) -f} || exit +MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit + +AR=$1 +ARFLAGS=$2 +OUT=$3 +shift 3 + +# remove directory arguments (having .a targets depend on dirs is what +# lets them be invalidated by deleted files) +FIRST=1 +for x; do + if [ $FIRST -eq 1 ]; then + set -- + FIRST=0 + fi + if [ -d "$x" ]; then + if [ -f "$OUT" ] && [ "$x" -nt "$OUT" ]; then + $RM "$OUT" + fi + continue + fi + if [ "$x" != "${x%.o}" ]; then + set -- "$@" "$x" + fi +done + +set -- "$AR" "$ARFLAGS" "$OUT" "$@" + +OUTDIR="${OUT%/*}" +if [ "$OUTDIR" != "$OUT" ] && [ ! -d "$OUTDIR" ]; then + $MKDIR "$OUTDIR" || exit 2 +fi + +printf "$LOGFMT" "${ACTION:-ARCHIVE.a}" "$OUT" >&2 +# if [ "$SILENT" = "0" ]; then +# # some of these windows nt archives are quite huge +# COLUMNS=${COLUMNS:-80} +# COLUMNS=$((COLUMNS - 4)) +# printf "%s\n" "$*" | +# /usr/bin/fold -s -w $COLUMNS | +# sed -e '1bb' -e 's/^/ /' -e ':b' -e '$b' -e 's/$/ \\/' >&2 +# else +# printf "$LOGFMT" "${ACTION:-ARCHIVE.a}" "$OUT" >&2 +# fi + +REASON=failed +trap REASON=interrupted INT + +"$@" >/dev/null && exit + +if [ "$TERM" = "dumb" ]; then + f='%s %s\r\n\r\n' +else + f='\033[91m%s\033[39m \033[94m%s\033[39m\r\n\r\n' +fi +printf "$f" "archive $REASON:" "$*" >&2 +exit 1 diff --git a/build/assemble b/build/assemble new file mode 100755 index 00000000..27e92a3b --- /dev/null +++ b/build/assemble @@ -0,0 +1,49 @@ +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ +# +# OVERVIEW +# +# GNU Assembler Veneer +# +# DESCRIPTION +# +# This script wraps normal assembler commands that're transparently +# passed-through. It adds ephemeral logging and directory creation. +# +# EXAMPLE +# +# TARGET=program build/assemble as -o program program.o +# +# SEE ALSO +# +# https://justine.storage.googleapis.com/perm/as.pdf + +if [ ! -d o/third_party/gcc ]; then + third_party/gcc/unbundle.sh +fi + +export LC_ALL=C +MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit + +if [ "$SILENT" = "0" ]; then + printf "%s\n" "$*" >&2 +else + printf "$LOGFMT" "${ACTION:-OBJECTIFY.s}" "$TARGET" >&2 +fi + +if [ "$TARGET" ]; then + TARGETDIR="${TARGET%/*}" + if [ "$TARGETDIR" != "$TARGET" ] && [ ! -d "$TARGETDIR" ]; then + $MKDIR "$TARGETDIR" || exit 2 + fi +fi + +"$@" && exit + +if [ "$TERM" = "dumb" ]; then + f='%s %s\r\n\r\n' +else + f='\033[91m%s\033[39m \033[94m%s\033[39m\r\n\r\n' +fi +printf "$f" "assemble failed:" "$*" >&2 +exit 1 diff --git a/build/bochs-debugger b/build/bochs-debugger new file mode 100755 index 00000000..37c11d8f --- /dev/null +++ b/build/bochs-debugger @@ -0,0 +1,8 @@ +# -*- mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8 -*- +# vi: set net ft=sh ts=2 sts=2 sw=2 fenc=utf-8 :vi + +echo c | + bochs \ + -q \ + -f ape/etc/bochsrc.dbg \ + floppya:1_44=$1,status=inserted diff --git a/build/bochs-scriptable b/build/bochs-scriptable new file mode 100755 index 00000000..6e657500 --- /dev/null +++ b/build/bochs-scriptable @@ -0,0 +1,51 @@ +#!/bin/sh +# -*- mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8 -*- +# vi: set net ft=sh ts=2 sts=2 sw=2 fenc=utf-8 :vi +# +# bochs-scriptable executes a disk with serial uart stdio. +# +# USAGE +# +# build/bochs-scriptable IMAGE... +# +# DESCRIPTION +# +# This script is useful for end-to-end testing metal apps in <100ms. +# +# SEE ALSO +# +# build/boot(1) + +while getopts h X; do + case $X in + h) exec less "$0" ;; + \?) echo "$0: bad arg" >&2; exit 1 ;; + esac +done +shift $((OPTIND - 1)) + +trap '' INT + +IMG=$1 +OUT=/tmp/$USER.$$.bochs.stdout +ERR=/tmp/$USER.$$.bochs.stderr + +mkfifo $OUT || exit + +cat <$OUT & +CAT=$! +exec 4>$OUT +rm -f $OUT + +echo c | + bochs \ + -q \ + -f ape/etc/bochsrc.ffs \ + display_library:nogui \ + floppya:1_44=$1,status=inserted \ + >>$ERR 2>>$ERR +RC=$? + +kill $CAT +exec 4>&- +rm -f $ERR diff --git a/build/bootstrap/mkdeps.com b/build/bootstrap/mkdeps.com new file mode 100755 index 00000000..00b8bc39 Binary files /dev/null and b/build/bootstrap/mkdeps.com differ diff --git a/build/bootstrap/net/http/uricspn.c.gz b/build/bootstrap/net/http/uricspn.c.gz new file mode 100644 index 00000000..75e0fb90 Binary files /dev/null and b/build/bootstrap/net/http/uricspn.c.gz differ diff --git a/build/bootstrap/net/http/uriparse.c.gz b/build/bootstrap/net/http/uriparse.c.gz new file mode 100644 index 00000000..9234d6b6 Binary files /dev/null and b/build/bootstrap/net/http/uriparse.c.gz differ diff --git a/build/bootstrap/package.com b/build/bootstrap/package.com new file mode 100755 index 00000000..bf8771aa Binary files /dev/null and b/build/bootstrap/package.com differ diff --git a/build/bootstrap/zipobj.com b/build/bootstrap/zipobj.com new file mode 100755 index 00000000..954167aa Binary files /dev/null and b/build/bootstrap/zipobj.com differ diff --git a/build/catcode b/build/catcode new file mode 100755 index 00000000..e957f841 --- /dev/null +++ b/build/catcode @@ -0,0 +1,20 @@ +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ +# +# OVERVIEW +# +# Source File Concatenation Tool +# +# DESCRIPTION +# +# This program is the same as cat, but inserts preprocessor directives +# that allow compiler errors to point back to the original lines. + +if [ $# -eq 0 ]; then + cat +else + for x; do + printf '# 1 "%s"\n' "$x" + cat "$x" + done +fi diff --git a/build/compile b/build/compile new file mode 100755 index 00000000..a40cf8f5 --- /dev/null +++ b/build/compile @@ -0,0 +1,279 @@ +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ +# +# OVERVIEW +# +# GNU/LLVM Compiler Frontend Frontend +# +# DESCRIPTION +# +# This wrapper script filters out certain flags so the compiler won't +# whine, and passes extra information to the preprocessor. +# +# EXAMPLE +# +# build/compile cc -o program program.c + +if [ ! -d o/third_party/gcc ]; then + third_party/gcc/unbundle.sh +fi + +if [ "$1" = "clang-10" ]; then + if ! command -v clang-10 >/dev/null; then + shift + set -- o/third_party/gcc/bin/x86_64-linux-musl-gcc "$@" + fi +fi + +if [ "$1" = "clang++-10" ]; then + if ! command -v clang++-10 >/dev/null; then + shift + set -- o/third_party/gcc/bin/x86_64-linux-musl-g++ "$@" + fi +fi + +export LC_ALL=C +MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit + +GZME= +PLAT="${1%% *}" +FDIAGNOSTIC_COLOR= +CCNAME=${CCNAME:-gcc} +CCVERSION=${CCVERSION:-4} +COUNTERMAND= + +# The GNU Compiler Collection passes a lot of CFLAGS to the preprocessor +# (which we call CCFLAGS) but it should pass more; and we do just that. +FIRST=1 +OUTARG=0 +INVISIBLE=0 +for x; do + if [ $FIRST -eq 1 ]; then + set -- + FIRST=0 + fi + if [ $OUTARG -eq 1 ]; then + OUTARG=0 + OUT="$x" + fi + case "$x" in + -o) + set -- "$@" "$x" + OUTARG=1 + ;; + -w) + set -- "$@" "$x" -D__W__ + ;; + -pg) + if [ $INVISIBLE -eq 0 ]; then + set -- "$@" "$x" -D__PG__ # @see libc/macros.h + fi + ;; + -mfentry) + if [ $INVISIBLE -eq 0 ]; then + set -- "$@" "$x" -D__MFENTRY__ + fi + ;; + -fomit-frame-pointer) + INVISIBLE=1 + set -- "$@" "$x" + ;; + -mno-vzeroupper) + set -- "$@" "$x" -Wa,-msse2avx -D__MNO_VZEROUPPER__ + ;; + -fsanitize=undefined) + set -- "$@" "$x" -D__FSANITIZE_UNDEFINED__ + COUNTERMAND="$COUNTERMAND -fno-data-sections" # sqlite.o + ;; + -mnop-mcount) + if [ "$CCNAME" = "gcc" ] && [ "$CCVERSION" -ge 6 ]; then + set -- "$@" "$x" -D__MNOP_MCOUNT__ + fi + ;; + -mrecord-mcount) + if [ "$CCNAME" = "gcc" ] && [ "$CCVERSION" -ge 6 ]; then + set -- "$@" "$x" -D__MRECORD_MCOUNT__ + fi + ;; + -fsanitize=implicit*integer*) + if ! [ "$CCNAME" = "gcc" ]; then + set -- "$@" "$x" + fi + ;; + -f*sanitize*|-gz*|-*stack-protector*|-fvect-cost*|-mstringop*) + if [ "$CCNAME" = "gcc" ] && [ "$CCVERSION" -ge 6 ]; then + set -- "$@" "$x" + fi + ;; + -freorder-blocks-and-partition|-fstack-clash-protection) + if [ "$CCNAME" = "gcc" ] && [ "$CCVERSION" -ge 8 ]; then + set -- "$@" "$x" + fi + ;; + -fdiagnostic-color=*) + FDIAGNOSTIC_COLOR=$x + ;; + -fopt-info*=*.optinfo) + if [ "$CCNAME" = "gcc" ] && [ "$CCVERSION" -ge 9 ]; then + GZME="$GZME ${x##*=}" + set -- "$@" "$x" + fi + ;; + -R*) # e.g. clang's -Rpass-missed=all + if [ "${PLAT#*clang}" != "${PLAT}" ]; then + set -- "$@" "$x" + fi + ;; + -fsave-optimization-record) # clang only + if [ "${PLAT#*clang}" != "${PLAT}" ]; then + set -- "$@" "$x" + fi + ;; + *) + set -- "$@" "$x" + ;; + esac +done +if [ -z "$FDIAGNOSTIC_COLOR" ] && [ "$TERM" != "dumb" ]; then + FDIAGNOSTIC_COLOR=-fdiagnostics-color=always +fi + +if [ "${PLAT#*clang}" != "${PLAT}" ]; then + FIRST=1 + for x; do + # clang's assembler isn't complete yet + if [ $FIRST -eq 1 ]; then + set -- \ + "$x" \ + -fno-integrated-as \ + -Wno-unused-command-line-argument \ + -Wno-incompatible-pointer-types-discards-qualifiers + FIRST=0 + continue + fi + # removes flags clang whines about + case "$x" in + -gstabs) ;; + -ffixed-*) ;; + -fcall-saved*) ;; + -fsignaling-nans) ;; + -fcx-limited-range) ;; + -fno-fp-int-builtin-inexact) ;; + -Wno-unused-but-set-variable) ;; + -Wunsafe-loop-optimizations) ;; + -ftracer) ;; + -frounding-math) ;; + -fmerge-constants) ;; + -fmodulo-sched) ;; + -msse2avx) + set -- "$@" -Wa,-msse2avx + ;; + -fopt-info-vec) ;; + -fopt-info-vec-missed) ;; + -fmodulo-sched-allow-regmoves) ;; + -fgcse-*) ;; + -freschedule-modulo-scheduled-loops) ;; + -freschedule-modulo-scheduled-loops) ;; + -fipa-pta) ;; + -fsched2-use-superblocks) ;; + -fbranch-target-load-optimize) ;; + -fdelete-dead-exceptions) ;; + -funsafe-loop-optimizations) ;; + -fcall-used*) ;; + -mmitigate-rop) ;; + -mnop-mcount) ;; + -fno-align-jumps) ;; + -fno-align-labels) ;; + -fno-align-loops) ;; + -fivopts) ;; + -fschedule-insns) ;; + -fno-semantic-interposition) ;; + -mno-fentry) ;; + -f*schedule-insns2) ;; + -fvect-cost-model=*) ;; + -fsimd-cost-model=*) ;; + -fversion-loops-for-strides) ;; + -fopt-info*) ;; + -f*var-tracking-assignments) ;; + -femit-struct-debug-baseonly) ;; + -ftree-loop-vectorize) ;; + -gdescribe-dies) ;; + -flimit-function-alignment) ;; + -ftree-loop-im) ;; + -fno-instrument-functions) ;; + -fstack-clash-protection) ;; + -mstringop-strategy=*) ;; + -mpreferred-stack-boundary=*) ;; + -*stack-protector*) ;; # clang requires segmented memory for this + -f*gnu-unique) ;; + -Wframe-larger-than=*) ;; + -f*whole-program) ;; + -Wa,--size-check=*) ;; + -Wa,--listing*) ;; + -mfpmath=sse+387) ;; + -Wa,--noexecstack) ;; + -freg-struct-return) ;; + -mcall-ms2sysv-xlogues) ;; + -mno-vzeroupper) + set -- "$@" -mllvm -x86-use-vzeroupper=0 + ;; + -Wa,-a*) + x="${x#*=}" + if [ "$x" ] && [ -p "$x" ]; then + printf '' >"$x" + fi + ;; + *) + set -- "$@" "$x" + ;; + esac + done +else + # removes flags only clang supports + FIRST=1 + for x; do + if [ $FIRST -eq 1 ]; then + set -- + FIRST=0 + fi + case "$x" in + -Oz) set -- "$@" -Os ;; + *) set -- "$@" "$x" ;; + esac + done +fi + +set -- "$@" -no-canonical-prefixes $FDIAGNOSTIC_COLOR $COUNTERMAND + +if [ "$SILENT" = "0" ]; then + printf "%s\n" "$*" >&2 +else + printf "$LOGFMT" "${ACTION:-COMPILE}" "${TARGET:-$OUT}" >&2 +fi + +OUTDIR="${OUT%/*}" +if [ "$OUTDIR" != "$OUT" ] && [ ! -d "$OUTDIR" ]; then + $MKDIR "$OUTDIR" || exit 2 +fi + +REASON=failed +trap REASON=interrupted INT + +if "$@"; then + for f in $GZME; do + if GZ=${GZ:-$(command -v gzip)}; then + if [ -f "$f" ]; then + build/actuallynice $GZ $ZFLAGS -qf $f & + fi + fi + done + exit 0 +fi + +if [ "$TERM" = "dumb" ]; then + f='%s %s\r\n\r\n' +else + f='\033[91m%s\033[39m \033[94m%s\033[39m\r\n\r\n' +fi +printf "$f" "$CCNAME $CCVERSION: compile $REASON:" "$*" >&2 +exit 1 diff --git a/build/config.mk b/build/config.mk new file mode 100644 index 00000000..d1603ce0 --- /dev/null +++ b/build/config.mk @@ -0,0 +1,152 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +# Default Mode +# +# - `make` +# - Backtraces +# - Function tracing +# - Reasonably small +# - Reasonably optimized +# - Reasonably debuggable + +ifeq ($(MODE),) + +CONFIG_CCFLAGS += \ + $(BACKTRACES) \ + $(FTRACE) \ + -Og + +TARGET_ARCH ?= \ + -msse3 + +RAGELFLAGS ?= -G2 + +endif + +# Optimized Mode +# +# - `make MODE=opt` +# - Backtraces +# - More optimized +# - Reasonably small +# - No memory corruption detection +# - assert() / CHECK_xx() may leak code into binary for debuggability +# - GCC 8+ hoists check fails into .text.cold, thus minimizing impact + +ifeq ($(MODE), opt) + +CONFIG_CPPFLAGS += \ + -DNDEBUG \ + -msse2avx \ + -Wa,-msse2avx + +CONFIG_CCFLAGS += \ + $(BACKTRACES) \ + -O3 + +TARGET_ARCH ?= \ + -march=native + +RAGELFLAGS ?= -G2 + +endif + +# Release Mode +# +# - `make MODE=rel` +# - More optimized +# - Reasonably small +# - Numeric backtraces +# - Toilsome debuggability +# - assert() statements removed +# - DCHECK_xx() statements removed +# - No memory corruption detection +# - CHECK_xx() won't leak strings into binary + +ifeq ($(MODE), rel) + +CONFIG_CPPFLAGS += \ + -DNDEBUG + +CONFIG_CCFLAGS += \ + $(BACKTRACES) \ + -O3 + +#TARGET_ARCH ?= \ + -msse3 + +RAGELFLAGS = -G2 + +endif + +# Debug Mode +# +# - `make MODE=dbg` +# - Backtraces +# - Zero optimization +# - Enables sanitization +# - Enables stack canaries +# - Enormous binaries (b/c ubsan suboptimalities) + +ifeq ($(MODE), dbg) + +CONFIG_CPPFLAGS += \ + -DMODE_DBG + +CONFIG_CCFLAGS += \ + $(BACKTRACES) \ + $(FTRACE) \ + -fno-inline + +CONFIG_COPTS += \ + $(SECURITY_BLANKETS) \ + $(SANITIZER) + +OVERRIDE_CCFLAGS += \ + -fno-pie + +endif + +# Tiny Mode +# +# - `make MODE=tiny` +# - No checks +# - No asserts +# - No canaries +# - No paranoia +# - No avx hooks +# - No backtraces +# - No algorithmics +# - YOLO + +ifeq ($(MODE), tiny) + +CONFIG_CPPFLAGS += \ + -DTINY \ + -DNDEBUG \ + -DTRUSTWORTHY + +CONFIG_CCFLAGS += \ + -Os \ + -fno-align-functions \ + -fno-align-jumps \ + -fno-align-labels \ + -fno-align-loops + +TARGET_ARCH ?= \ + -msse3 + +endif + +# ANSI Mode +# +# Folks who want it deserve to get it, good and hard. + +ifeq ($(MODE), ansi) + +CONFIG_CCFLAGS += \ + -std=c11 \ + -Og + +endif diff --git a/build/definitions.mk b/build/definitions.mk new file mode 100644 index 00000000..3e6f875d --- /dev/null +++ b/build/definitions.mk @@ -0,0 +1,357 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ +# +# SYNOPSIS +# +# Cosmopolitan Core Build Definitions +# +# DESCRIPTION +# +# Nearly all compiler flag tuning is done within this one file. Flags +# may be customized with environment variables. We also use this file +# to compute expensive values once per build. +# +# When tuning the variables below, please note they're interpreted in +# the strictest sense. For example, we don't pass CFLAGS to gcc if we +# know it's compiling a .S file. This allows our `make SILENT=0` logs +# to be succinct and informative, at the cost of being less forgiving. +# +# Further note that link order is equally unforgiving in repositories +# of this scale. We approach that by over-specifying dependencies, in +# packages that're broken down usually on a per-directory basis. This +# is aided by the checkdeps and functional programming tools which in +# most cases should be able to deduce correct ordering automatically. +# +# Concerning our approach to flag tuning, most of it is non-essential +# and largely serves to turn features off. Particularly features that +# would otherwise lock us in to a particular platform or legal terms. +# Other flags will usually be the ones that provide us marginal gains +# in terms of performance and code size, but the world won't end when +# they aren't used. Flags that play a critical role in source working +# correctly will usually be specified on a target-by-target basis, in +# their respective packages. +# +# NOTE might have gotten the per-target override flag flow wrong since +# flags defined that way might flow quadratically opposite blaze. +# +# VARIABLES +# +# CCFLAGS gcc frontend flags (.i, .c, .cc, .f, .S, .lds, etc.) +# CPPFLAGS preprocessor flags (.h, .c, .cc, .S, .inc, .lds, etc.) +# CFLAGS c flags (.c only) +# CXXFLAGS c++ flags (.cc only) +# COPTS c/c++ flags (.c, .cc) +# LDFLAGS linker flags (don't use -Wl, frontend prefix) +# ASFLAGS assembler flags (don't use -Wa, frontend prefix) +# TARGET_ARCH microarchitecture flags (e.g. -march=native) + +SHELL = /bin/sh +DD ?= /bin/dd +CP ?= /bin/cp -f +RM ?= /bin/rm -f +SED ?= /bin/sed +MKDIR ?= /bin/mkdir -p +TAGS ?= ctags +ARFLAGS = rcsD +TAGSFLAGS ?= -e -a --if0=no --langmap=c:.c.h.i --line-directives=yes +SILENT ?= 1 +ZFLAGS ?= -4 --rsyncable +XARGS ?= xargs -P4 -rs8000 +NICE ?= build/actuallynice +RAGEL ?= ragel +DOT ?= dot +GZ ?= gzip +CLANG = clang-11 +FC = gfortran #/opt/cross9f/bin/x86_64-linux-musl-gfortran + +# see build/compile, etc. which run third_party/gcc/unbundle.sh +AS = o/third_party/gcc/bin/x86_64-linux-musl-as +CC = o/third_party/gcc/bin/x86_64-linux-musl-gcc +CXX = o/third_party/gcc/bin/x86_64-linux-musl-g++ +LD = o/third_party/gcc/bin/x86_64-linux-musl-ld.bfd +AR = o/third_party/gcc/bin/x86_64-linux-musl-ar +NM = o/third_party/gcc/bin/x86_64-linux-musl-nm +GCC = o/third_party/gcc/bin/x86_64-linux-musl-gcc +STRIP = o/third_party/gcc/bin/x86_64-linux-musl-strip +OBJCOPY = o/third_party/gcc/bin/x86_64-linux-musl-objcopy +ADDR2LINE = o/third_party/gcc/bin/x86_64-linux-musl-addr2line + +COMMA := , +PWD := $(shell pwd) +IMAGE_BASE_VIRTUAL ?= 0x400000 +TMPDIR := $(shell build/findtmp) +LOGFMT := $(shell build/getlogfmt) +CCNAME := $(shell build/getccname $(CC)) +CCVERSION := $(shell build/getccversion $(CC)) +BLAH1 := $(shell build/zipobj 2>/dev/null) +BLAH2 := $(shell build/package 2>/dev/null) + +export ADDR2LINE +export CCNAME +export CCVERSION +export CP +export DD +export GZ +export IMAGE_BASE_VIRTUAL +export LOGFMT +export MKDIR +export MODE +export RM +export SED +export SILENT +export TMPDIR +export ZFLAGS + +FTRACE = \ + -pg + +SANITIZER = \ + -fsanitize=undefined \ + -fsanitize=leak \ + -fsanitize=implicit-signed-integer-truncation \ + -fsanitize=implicit-integer-sign-change + +NO_MAGIC = \ + -mno-fentry \ + -fno-stack-protector \ + -fno-sanitize=all + +OLD_CODE = \ + -fno-strict-aliasing \ + -fno-strict-overflow + +TRADITIONAL = \ + -Wno-implicit-int \ + -Wno-return-type \ + -Wno-pointer-sign + +DEFAULT_CCFLAGS = \ + -Wall \ + -Werror \ + -fmerge-all-constants \ + -fdebug-prefix-map="$(PWD)"= \ + -frecord-gcc-switches + +DEFAULT_OFLAGS = \ + -g \ + -gdescribe-dies + +DEFAULT_COPTS = \ + -fno-math-errno \ + -fno-trapping-math \ + -fno-fp-int-builtin-inexact \ + -fno-ident \ + -fno-common \ + -fno-gnu-unique \ + -fmerge-constants \ + -fstrict-aliasing \ + -fstrict-overflow \ + -fno-omit-frame-pointer \ + -fno-optimize-sibling-calls \ + -mno-omit-leaf-frame-pointer + +DEFAULT_CPPFLAGS = \ + -DIMAGE_BASE_VIRTUAL=$(IMAGE_BASE_VIRTUAL) \ + -nostdinc \ + -iquote . \ + -include libc/integral/normalize.inc + +DEFAULT_CFLAGS = \ + -std=gnu2x + +DEFAULT_CXXFLAGS = \ + -std=gnu++11 \ + -fno-rtti \ + -fno-exceptions \ + -fuse-cxa-atexit \ + -fno-threadsafe-statics + +DEFAULT_ASFLAGS = \ + -W \ + -I. \ + --noexecstack + +DEFAULT_LDFLAGS = \ + -h \ + -static \ + --relax \ + -nostdlib \ + -m elf_x86_64 \ + --gc-sections \ + --build-id=none \ + --cref -Map=$@.map \ + --no-dynamic-linker \ + -Ttext-segment=$(IMAGE_BASE_VIRTUAL) + +ASONLYFLAGS = \ + -g \ + --debug-prefix-map="$(PWD)"= + +DEFAULT_LDLIBS = + +MCA = llvm-mca-10 \ + -mtriple=x86_64-pc-linux-gnu \ + -iterations=3 \ + -instruction-info \ + -iterations=3 \ + -all-stats \ + -all-views \ + -timeline + +cc.flags = \ + $(DEFAULT_CCFLAGS) \ + $(CONFIG_CCFLAGS) \ + $(CCFLAGS) \ + $(OVERRIDE_CCFLAGS) \ + -D__SAUCE__=\"$<\" + +o.flags = \ + $(DEFAULT_OFLAGS) \ + $(CONFIG_OFLAGS) \ + $(OFLAGS) \ + $(OVERRIDE_OFLAGS) + +cpp.flags = \ + $(DEFAULT_CPPFLAGS) \ + $(CONFIG_CPPFLAGS) \ + $(CPPFLAGS) \ + $(OVERRIDE_CPPFLAGS) + +copt.flags = \ + $(TARGET_ARCH) \ + $(DEFAULT_COPTS) \ + $(CONFIG_COPTS) \ + $(COPTS) \ + $(OVERRIDE_COPTS) + +f.flags = \ + $(DEFAULT_FFLAGS) \ + $(CONFIG_FFLAGS) \ + $(FFLAGS) \ + $(OVERRIDE_FFLAGS) + +c.flags = \ + $(DEFAULT_CFLAGS) \ + $(CONFIG_CFLAGS) \ + $(CFLAGS) \ + $(OVERRIDE_CFLAGS) + +cxx.flags = \ + $(DEFAULT_CXXFLAGS) \ + $(CONFIG_CXXFLAGS) \ + $(CXXFLAGS) \ + $(OVERRIDE_CXXFLAGS) + +s.flags = \ + $(DEFAULT_ASFLAGS) \ + $(CONFIG_ASFLAGS) \ + $(ASFLAGS) \ + $(OVERRIDE_ASFLAGS) + +S.flags = $(addprefix -Wa$(COMMA),$(s.flags)) + +LD.libs = \ + $(LDLIBS) \ + $(LOADLIBES) \ + $(DEFAULT_LDLIBS) \ + $(CONFIG_LDLIBS) \ + $(LDLIBS) \ + $(DEFAULT_LIBS) \ + $(CONFIG_LIBS) \ + $(LIBS) + +COMPILE.c.flags = $(cc.flags) $(cpp.flags) $(copt.flags) $(c.flags) +COMPILE.cxx.flags = $(cc.flags) $(cpp.flags) $(copt.flags) $(cxx.flags) +COMPILE.f.flags = $(cc.flags) $(copt.flags) $(f.flags) +COMPILE.F.flags = $(cc.flags) $(cpp.flags) $(copt.flags) $(f.flags) +COMPILE.i.flags = $(cc.flags) $(copt.flags) $(c.flags) +COMPILE.ii.flags = $(cc.flags) $(copt.flags) $(cxx.flags) +LINK.flags = $(DEFAULT_LDFLAGS) $(CONFIG_LDFLAGS) $(LDFLAGS) +OBJECTIFY.c.flags = $(OBJECTIFY.S.flags) $(copt.flags) $(c.flags) +OBJECTIFY.cxx.flags = $(OBJECTIFY.S.flags) $(copt.flags) $(cxx.flags) +OBJECTIFY.s.flags = $(ASONLYFLAGS) $(s.flags) +OBJECTIFY.S.flags = $(copt.flags) $(cc.flags) $(o.flags) $(cpp.flags) $(S.flags) +OBJECTIFY.f.flags = $(copt.flags) $(cc.flags) $(o.flags) $(copt.flags) $(S.flags) $(f.flags) +OBJECTIFY.F.flags = $(OBJECTIFY.f.flags) $(cpp.flags) +PREPROCESS.flags = -E $(copt.flags) $(cc.flags) $(cpp.flags) +PREPROCESS.lds.flags = -D__LINKER__ $(filter-out -g%,$(PREPROCESS.flags)) -P -xc + +COMPILE.c = $(CC) -S $(COMPILE.c.flags) +COMPILE.i = $(CC) -S $(COMPILE.i.flags) +COMPILE.f = $(FC) -S $(COMPILE.f.flags) +COMPILE.F = $(FC) -S $(COMPILE.F.flags) +OBJECTIFY.s = $(AS) $(OBJECTIFY.s.flags) +OBJECTIFY.S = $(CC) $(OBJECTIFY.S.flags) -c +OBJECTIFY.f = $(FC) $(OBJECTIFY.f.flags) -c +OBJECTIFY.F = $(FC) $(OBJECTIFY.F.flags) -c +OBJECTIFY.c = $(CC) $(OBJECTIFY.c.flags) -c +OBJECTIFY.cxx = $(CXX) $(OBJECTIFY.cxx.flags) -c +PREPROCESS = $(CC) $(PREPROCESS.flags) +PREPROCESS.lds = $(CC) $(PREPROCESS.lds.flags) +LINK = build/link $(LD) $(LINK.flags) +ELF = o/libc/elf/elf.lds +ELFLINK = ACTION=LINK.elf $(LINK) $(LINKARGS) $(OUTPUT_OPTION) +ARCHIVE = build/archive $(AR) $(ARFLAGS) +LINKARGS = $(patsubst %.lds,-T %.lds,$(call uniqr,$(LD.libs) $(filter-out %.pkg,$^))) +LOLSAN = build/lolsan -b $(IMAGE_BASE_VIRTUAL) + +# The compiler won't generate %xmm code for sources extensioned .greg.c, +# which is needed for C modules wanting to run at the executive level or +# during privileged runtime states, e.g. code morphing. +OBJECTIFY.greg.c = \ + $(CC) \ + $(filter-out -pg,$(OBJECTIFY.c.flags)) \ + -D__MGENERAL_REGS_ONLY__ \ + -mgeneral-regs-only \ + -fno-stack-protector \ + -fno-instrument-functions \ + -fno-optimize-sibling-calls \ + -fno-sanitize=all \ + -c + +OBJECTIFY.ansi.c = $(CC) $(OBJECTIFY.c.flags) -ansi -Wextra -Werror -pedantic-errors -c +OBJECTIFY.c99.c = $(CC) $(OBJECTIFY.c.flags) -std=c99 -Wextra -Werror -pedantic-errors -c +OBJECTIFY.c11.c = $(CC) $(OBJECTIFY.c.flags) -std=c11 -Wextra -Werror -pedantic-errors -c +OBJECTIFY.c2x.c = $(CC) $(OBJECTIFY.c.flags) -std=c2x -Wextra -Werror -pedantic-errors -c + +# No-Clobber ABI (clobbers nothing, except rax and flags) +# +# This ABI is intended for core library functions that're frequently +# called by just about everything, e.g. memcpy, malloc, etc. By offering +# this guarantee, callers can optionally call these functions via asm(), +# which reduces register allocator pressure at call sites. +# +# This makes unrelated caller code faster, but the NCABI functions +# themselves a tiny bit slower. That's OK, since modern NexGen-32e CPUs +# seem to have one fifth of their execution engines devoted to pushing +# and popping, probably so legacy IA-32 code keeps going fast; so we use +# it to our advantage. +OBJECTIFY.ncabi.c = \ + $(GCC) \ + $(OBJECTIFY.c.flags) \ + -mno-sse \ + -mfpmath=387 \ + -mno-fentry \ + -fno-stack-protector \ + -fno-instrument-functions \ + -fno-optimize-sibling-calls \ + -mpreferred-stack-boundary=3 \ + -fno-sanitize=all \ + -fcall-saved-rcx \ + -fcall-saved-rdx \ + -fcall-saved-rdi \ + -fcall-saved-rsi \ + -fcall-saved-r8 \ + -fcall-saved-r9 \ + -fcall-saved-r10 \ + -fcall-saved-r11 \ + -c \ + -xc + +BUILD_SRCS = \ + build/definitions.mk \ + build/rules.mk \ + build/compile \ + build/link \ + build/lolsan \ + build/remote diff --git a/build/do b/build/do new file mode 100755 index 00000000..30b79fe9 --- /dev/null +++ b/build/do @@ -0,0 +1,54 @@ +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ +# +# OVERVIEW +# +# Generic Command Runner +# +# DESCRIPTION +# +# This does auto mkdir and ephemeral logging. +# +# EXAMPLE +# +# build/do PROG [ARGS...] + +MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit + +# Ensure directory creation if -o PATH flag is passed. +OUT= +FIRST=1 +OUTARG=0 +for x; do + if [ $FIRST -eq 1 ]; then + set -- + FIRST=0 + elif [ $OUTARG -eq 1 ]; then + OUTARG=0 + OUT="$x" + fi + case "$x" in + -o) + OUTARG=1 + ;; + -o*) + OUT=${x#-o} + ;; + esac + set -- "$@" "$x" +done +if [ "$OUT" ]; then + OUTDIR="${OUT%/*}" + if [ "$OUTDIR" != "$OUT" ] && [ ! -d "$OUTDIR" ]; then + $MKDIR "$OUTDIR" || exit 2 + fi +fi + +# Log command. +if [ "$SILENT" = "0" ]; then + printf "%s\n" "$*" >&2 +else + printf "$LOGFMT" "${ACTION:-BUILD}" "$TARGET" >&2 +fi + +exec "$@" diff --git a/build/findtmp b/build/findtmp new file mode 100755 index 00000000..60218326 --- /dev/null +++ b/build/findtmp @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ +# +# OVERVIEW +# +# Temporary Directory Discovery +# +# DESCRIPTION +# +# We call this script once per build to ideally find a folder that's +# backed by an in-memory file system. We then export it to the TMPDIR +# environment variable. Many programs use it under the hood, e.g. gcc, +# so it grants many small performance improvements. + +MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit + +$MKDIR o/tmp +echo o/tmp diff --git a/build/functions.mk b/build/functions.mk new file mode 100644 index 00000000..6196802e --- /dev/null +++ b/build/functions.mk @@ -0,0 +1,16 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ +# +# SYNOPSIS +# +# Cosmopolitan Functional Programming Build System +# +# OVERVIEW +# +# It's basically Blaze except a few lines of code, made possible due +# to the power and the glory of variables that're secretly lambdas. + +tail = $(wordlist 2,$(words $1),$1) +reverse = $(if $1,$(call reverse,$(call tail,$1)) $(firstword $1)) +uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1))) +uniqr = $(if $1,$(call uniqr,$(filter-out $(firstword $1),$1)) $(firstword $1)) diff --git a/build/getccname b/build/getccname new file mode 100755 index 00000000..83f6210e --- /dev/null +++ b/build/getccname @@ -0,0 +1,40 @@ +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ +# +# OVERVIEW +# +# Compiler Name Discovery +# +# DESCRIPTION +# +# Cosmopolitan itself may be built using either GCC and Clang, and our +# build irons out many of the differences between the two. This script +# determines which one's in play, which is nontrivial, since they tend +# to call themselves so many different names. + +if [ ! -d o/third_party/gcc ]; then + third_party/gcc/unbundle.sh +fi + +set -e + +SPECIAL_TEXT=$( + $1 --version | + sed -n ' + /Free Software/ { + i\ +gcc + q + } + /clang/ { + i\ +clang + q + } + ') + +if [ -z "$SPECIAL_TEXT" ]; then + echo gcc +else + printf '%s\n' "$SPECIAL_TEXT" +fi diff --git a/build/getccversion b/build/getccversion new file mode 100755 index 00000000..0024e3db --- /dev/null +++ b/build/getccversion @@ -0,0 +1,38 @@ +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ +# +# OVERVIEW +# +# Compiler Version Discovery +# +# DESCRIPTION +# +# Cosmopolitan itself may be built using either GCC and Clang, and our +# build irons out many of the differences between the two. This script +# is used by build/definitions.mk alongside build/getccname to support +# the different versions folks use. +# +# Our aim is to support GCC 4.2.1+ since that's the last GPLv2 version +# with any sort of industry consensus. Please note, Cosmopolitan never +# links GCC runtimes when using later versions, so some concerns might +# not apply. + +if [ ! -d o/third_party/gcc ]; then + third_party/gcc/unbundle.sh +fi + +set -e + +MAJOR_VERSION=$( + $1 --version | + head -n1 | + sed -n ' + s!^[^(]*([^)]*) \([[:digit:]][[:digit:]]*\).*!\1!p + s!^.*clang.*version \([[:digit:]][[:digit:]]*\).*!\1!p + ') + +if [ -z "$MAJOR_VERSION" ]; then + echo 6 +else + printf '%s\n' "$MAJOR_VERSION" +fi diff --git a/build/getlogfmt b/build/getlogfmt new file mode 100755 index 00000000..d168d42b --- /dev/null +++ b/build/getlogfmt @@ -0,0 +1,32 @@ +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ +# +# OVERVIEW +# +# Printf Logger Initializer +# +# DESCRIPTION +# +# This program is invoked once by build/definitions.mk to choose the +# most appropriate format string when logging command invocations. + +if [ "$SILENT" = "0" ]; then + printf "''" +else + W1=15 + if [ "$TERM" = "dumb" ]; then # e.g. emacs' dismal tty + if [ "$COLUMNS" = "" ]; then + if TPUT=$(command -v tput); then + COLUMNS=$("$TPUT" cols) + else + COLUMNS=80 + fi + fi + COLUMNS=$((COLUMNS - 1)) + W2=$((COLUMNS - W1)) + printf '%%-%ds%%-%ds\\r' "$W1" "$W2" + else + echo ♥cosmo >&2 + printf '\\033[F\\033[K%%-%ds%%s\\r\\n' "$W1" + fi +fi diff --git a/build/htags b/build/htags new file mode 100755 index 00000000..8b68d613 --- /dev/null +++ b/build/htags @@ -0,0 +1,57 @@ +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ +# +# OVERVIEW +# +# Header Symbol Index Generator +# +# DESCRIPTION +# +# This is a static source analyzer that lets us configure Emacs +# keybindings to insert #include lines. +# +# EXAMPLES +# +# build/htags -o HTAGS $(find . -name \*.h) +# +# (defun jart-add-include () +# (interactive) +# (let* ((tag-file "HTAGS") +# (case-fold-search nil) +# (search (thing-at-point 'symbol)) +# (buffer (find-file-noselect (format "%s/%s" +# (locate-dominating-file +# (buffer-name) tag-file) +# tag-file))) +# (header (with-current-buffer buffer +# (save-excursion +# (goto-char 0) +# (when (re-search-forward +# (concat "\177" search "\001") nil t) +# (when (re-search-backward "\f\n\\([^,]*\\)," nil t) +# (match-string 1))))))) +# (when header +# (save-excursion +# (goto-char 0) +# (re-search-forward "#include") +# (re-search-forward "^$") +# (insert (concat "#include \"" header "\"\n")))))) +# (defun jart-c-mode-common-hook () +# (define-key c-mode-base-map (kbd "C-c C-h") 'jart-add-include)) +# (eval-after-load 'markdown-mode +# '(progn +# (add-hook 'c-mode-common-hook 'jart-c-mode-common-hook))) + +# ctags doesn't understand variable prototypes, e.g. +# extern char **environ; +set -- --regex-c='/^\(\(hidden\|extern\|const\) \)*[_[:alpha:]][_[:alnum:]]*[ *][ *]*\([_[:alpha:]][_[:alnum:]]*[ *][ *]*\)*\([_[:alpha:]][_$[:alnum:]]*\)/\4/b' "$@" + +# ctags doesn't understand function prototypes, e.g. +# bool isheap(void *p) nothrow nocallback; +set -- --regex-c='/^[_[:alpha:]][_[:alnum:]]*[ *][ *]*\([_[:alpha:]][_[:alnum:]]*[ *][ *]*\)*\([_[:alpha:]][_$[:alnum:]]*\)(.*/\2/b' "$@" + +# ctags doesn't understand function pointers, e.g. +# extern int32_t (*const SetEvent)(int64_t hEvent) wincall; +set -- --regex-c='/^extern [^(]*(\*const \([^)]*\))(/\1/b' "$@" + +exec ${TAGS:-ctags} -e --langmap=c:.c.h "$@" diff --git a/build/includeall b/build/includeall new file mode 100755 index 00000000..c9882a7e --- /dev/null +++ b/build/includeall @@ -0,0 +1,6 @@ +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ + +for x; do + printf '#include "%s"\n' "$x" +done diff --git a/build/link b/build/link new file mode 100755 index 00000000..42e50cb9 --- /dev/null +++ b/build/link @@ -0,0 +1,65 @@ +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ +# +# OVERVIEW +# +# GNU Linker Veneer +# +# DESCRIPTION +# +# This script wraps normal linker commands that're transparently +# passed-through. It adds ephemeral logging and directory creation. +# +# EXAMPLE +# +# build/linker ld -o program program.o + +if [ ! -d o/third_party/gcc ]; then + third_party/gcc/unbundle.sh +fi + +export LC_ALL=C # very important for ld +MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit + +OUT= +FIRST=1 +OUTARG=0 +for x; do + if [ $FIRST -eq 1 ]; then + set -- + FIRST=0 + elif [ $OUTARG -eq 1 ]; then + OUTARG=0 + OUT="$x" + fi + case "$x" in + -o) + OUTARG=1 + ;; + esac + set -- "$@" "$x" +done + +if [ "$SILENT" = "0" ]; then + printf "%s\n" "$*" >&2 +else + printf "$LOGFMT" "${ACTION:-LINK.elf}" "$OUT" >&2 +fi + +OUTDIR="${OUT%/*}" +if [ "$OUTDIR" != "$OUT" ] && [ ! -d "$OUTDIR" ]; then + $MKDIR "$OUTDIR" || exit 2 +fi + +REASON=failed +trap REASON=interrupted INT + +"$@" && exit + +if [ "$TERM" = "dumb" ]; then + f='%s %s\r\n\r\n' +else + f='\033[91m%s\033[39m \033[94m%s\033[39m\r\n\r\n' +fi +printf "$f" "link $REASON:" "$*" >&2 +exit 1 diff --git a/build/mkdeps b/build/mkdeps new file mode 100755 index 00000000..28be7065 --- /dev/null +++ b/build/mkdeps @@ -0,0 +1,21 @@ +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ + +if [ -x "o/$MODE/tool/build/mkdeps.com" ]; then + set -- "o/$MODE/tool/build/mkdeps.com" "$@" +else + if [ ! -x o/build/bootstrap/mkdeps.com ]; then + mkdir -p o/build/bootstrap && + cp -a build/bootstrap/mkdeps.com \ + o/build/bootstrap/mkdeps.com || exit + fi + set -- o/build/bootstrap/mkdeps.com "$@" +fi + +if [ "$SILENT" = "0" ]; then + printf "%s\n" "$*" >&2 +else + printf "$LOGFMT" "${ACTION:-MKDEPS}" "$3" >&2 +fi + +exec "$@" diff --git a/build/online.mk b/build/online.mk new file mode 100644 index 00000000..6e891771 --- /dev/null +++ b/build/online.mk @@ -0,0 +1,31 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ +# +# SYNOPSIS +# +# Cosmopolitan Online Testing +# +# OVERVIEW +# +# make test HOSTS="rhel5 windows mac freebsd openbsd wsl" +# +# DESCRIPTION +# +# This code deploys and spawns testing infrastructure to a fleet of +# virtual machines running the various supported platforms. This is +# super trivial since αcτµαlly pδrταblε εxεcµταblε is an autonomous +# format requiring one simple file copy. Latencies are outstanding. +# Configuration is trivial using /etc/hosts and ~/.ssh/config. +# +# SEE ALSO +# +# - tool/build/runit.c +# - tool/build/runitd.c + +.PRECIOUS: o/$(MODE)/%.com.ok +o/$(MODE)/%.com.ok: \ + o/$(MODE)/tool/build/runit.com.dbg \ + o/$(MODE)/tool/build/runitd.com \ + o/$(MODE)/%.com + @ACTION=TEST TARGET=$@ build/do $^ $(HOSTS) + @touch $@ diff --git a/build/package b/build/package new file mode 100755 index 00000000..dcbcf95b --- /dev/null +++ b/build/package @@ -0,0 +1,31 @@ +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ + +if [ "$TOOL_BUILD_PACKAGE" ]; then + set -- "$TOOL_BUILD_PACKAGE" "$@" +else + if [ -x "o/tool/build/package.com" ]; then + set -- "o/tool/build/package.com" "$@" + else + MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit + CP=${CP:-$(command -v cp) -f} || exit + if [ ! -x o/build/bootstrap/package.com ]; then + $MKDIR o/build/bootstrap && + $CP -a build/bootstrap/package.com \ + o/build/bootstrap/package.com || exit + fi + set -- o/build/bootstrap/package.com "$@" + fi +fi + +if [ "$SILENT" = "0" ]; then + COLUMNS=${COLUMNS:-80} + COLUMNS=$((COLUMNS - 4)) + printf "%s\n" "$*" | + /usr/bin/fold -s -w $COLUMNS | + sed -e '1bb' -e 's/^/ /' -e ':b' -e '$b' -e 's/$/ \\/' >&2 +else + printf "$LOGFMT" "${ACTION:-PACKAGE}" "$3" >&2 +fi + +exec "$@" diff --git a/build/rle.py b/build/rle.py new file mode 100644 index 00000000..5c484886 --- /dev/null +++ b/build/rle.py @@ -0,0 +1,2186 @@ +# OVERVIEW +# +# Run Length Decoder Scratch Pad +# +# DESCRIPTION +# +# The Cosmopolitan library includes many compressed lookup tables that +# are easy to edit by hand. The toilsome part is usually just creating +# them. This script should provide some insight on how it can be done. + +C = ['\xe2\x88\x85', '\xe2\x98\xba', '\xe2\x98\xbb', '\xe2\x99\xa5', + '\xe2\x99\xa6', '\xe2\x99\xa3', '\xe2\x99\xa0', '\xe2\x80\xa2', + '\xe2\x97\x98', '\xe2\x97\x8b', '\xe2\x97\x99', '\xe2\x99\x82', + '\xe2\x99\x80', '\xe2\x99\xaa', '\xe2\x99\xab', '\xe2\x98\xbc', + '\xe2\x96\xba', '\xe2\x97\x84', '\xe2\x86\x95', '\xe2\x80\xbc', + '\xc2\xb6', '\xc2\xa7', '\xe2\x96\xac', '\xe2\x86\xa8', + '\xe2\x86\x91', '\xe2\x86\x93', '\xe2\x86\x92', '\xe2\x86\x90', + '\xe2\x88\x9f', '\xe2\x86\x94', '\xe2\x96\xb2', '\xe2\x96\xbc', + ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', + ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', + 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', + '\xE2\x88\x96', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', + 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', + '|', '}', '~', '\xe2\x8c\x82', + '\xc3\x87', '\xc3\xbc', '\xc3\xa9', '\xc3\xa2', + '\xc3\xa4', '\xc3\xa0', '\xc3\xa5', '\xc3\xa7', + '\xc3\xaa', '\xc3\xab', '\xc3\xa8', '\xc3\xaf', + '\xc3\xae', '\xc3\xac', '\xc3\x84', '\xc3\x85', + '\xc3\x89', '\xc3\xa6', '\xc3\x86', '\xc3\xb4', + '\xc3\xb6', '\xc3\xb2', '\xc3\xbb', '\xc3\xb9', + '\xc3\xbf', '\xc3\x96', '\xc3\x9c', '\xc2\xa2', + '\xc2\xa3', '\xc2\xa5', '\xe2\x82\xac', '\xc6\x92', + '\xc3\xa1', '\xc2\xa1', '\xc3\xb3', '\xc3\xba', + '\xc3\xb1', '\xc3\x91', '\xc2\xaa', '\xc2\xba', + '\xc2\xbf', '\xe2\x8c\x90', '\xc2\xac', '\xc2\xbd', + '\xc2\xbc', '\xc2\xa1', '\xc2\xab', '\xc2\xbb', + '\xe2\x96\x91', '\xe2\x96\x92', '\xe2\x96\x93', '\xe2\x94\x82', + '\xe2\x94\xa4', '\xe2\x95\xa1', '\xe2\x95\xa2', '\xe2\x95\x96', + '\xe2\x95\x95', '\xe2\x95\xa3', '\xe2\x95\x91', '\xe2\x95\x97', + '\xe2\x95\x9d', '\xe2\x95\x9c', '\xe2\x95\x9b', '\xe2\x94\x90', + '\xe2\x94\x94', '\xe2\x94\xb4', '\xe2\x94\xac', '\xe2\x94\x9c', + '\xe2\x94\x80', '\xe2\x94\xbc', '\xe2\x95\x9e', '\xe2\x95\x9f', + '\xe2\x95\x9a', '\xe2\x95\x94', '\xe2\x95\xa9', '\xe2\x95\xa6', + '\xe2\x95\xa0', '\xe2\x95\x90', '\xe2\x95\xac', '\xe2\x95\xa7', + '\xe2\x95\xa8', '\xe2\x95\xa4', '\xe2\x95\xa5', '\xe2\x95\x99', + '\xe2\x95\x98', '\xe2\x95\x92', '\xe2\x95\x93', '\xe2\x95\xab', + '\xe2\x95\xaa', '\xe2\x94\x98', '\xe2\x94\x8c', '\xe2\x96\x88', + '\xe2\x96\x84', '\xe2\x96\x8c', '\xe2\x96\x90', '\xe2\x96\x80', + '\xce\xb1', '\xc3\x9f', '\xce\x93', '\xcf\x80', + '\xce\xa3', '\xcf\x83', '\xce\xbc', '\xcf\x84', + '\xce\xa6', '\xce\x98', '\xce\xa9', '\xce\xb4', + '\xe2\x88\x9e', '\xcf\x86', '\xce\xb5', '\xe2\x88\xa9', + '\xe2\x89\xa1', '\xc2\xb1', '\xe2\x89\xa5', '\xe2\x89\xa4', + '\xe2\x8c\xa0', '\xe2\x8c\xa1', '\xc3\xb7', '\xe2\x89\x88', + '\xc2\xb0', '\xe2\x88\x99', '\xc2\xb7', '\xe2\x88\x9a', + '\xe2\x81\xbf', '\xc2\xb2', '\xe2\x96\xa0', '\xce\xbb'] + +A = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x00,0x80,0x00,0x40,0x00,0x00,0x80, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, + 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x02, + 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x02,0x02,0x02,0x80,0x00,0x00,0x00,0x40, + 0x80,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x00,0x00,0x00,0x00,0x00, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40] + +xed_prefix_table_bit = [ + 0x00, 0x00, 0x00, 0x00, + 0x40, 0x40, 0x40, 0x40, + 0xff, 0xff, 0x00, 0x00, + 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0x00, +] + +# please rise for the x86 national flag +xed_has_modrm_2d = [ +# 0x00 + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 3, + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 3, 0, 1, 1, 1, 1, 0, 0, 3, 0, + 1, 1, 1, 1, 0, 0, 3, 0, 1, 1, 1, 1, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 3, 3, 3, 3, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 3, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, +# 0x0f + 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 3, 0, 3, 1, 0, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 1, 1, 1, 3, 3, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +] + +def tabify(s): + res = [] + for line in s.split("\n"): + if not line: + continue + directive, number = line.split() + number = int(number) + if directive == ".zero": + res = res + [0] * number + elif directive == ".byte": + res.append(number) + else: + assert False + return res + +kHasSib = tabify("""\ + .zero 32 + .zero 4 + .byte 1 + .zero 3 + .zero 4 + .byte 1 + .zero 3 + .zero 4 + .byte 1 + .zero 3 + .zero 8 + .zero 4 + .byte 1 + .zero 3 + .zero 4 + .byte 1 + .zero 3 + .zero 4 + .byte 1 + .zero 3 + .zero 8 +""") +assert len(kHasSib) == 96, len(kHasSib) + +kHasDisp = tabify("""\ + .zero 6 + .byte 2 + .zero 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 2 + .byte 2 + .byte 2 + .byte 2 + .byte 2 + .byte 2 + .byte 2 + .byte 2 + .zero 8 + .zero 5 + .byte 4 + .zero 2 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .zero 8 + .zero 5 + .byte 4 + .zero 2 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .zero 8 +""") +assert len(kHasDisp) == 96, len(kHasDisp) + +xed_disp_bits_2d = tabify("""\ + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 0 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 0 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 0 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 0 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 0 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 2 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 6 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 3 + .byte 3 + .byte 2 + .byte 1 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 0 + .byte 4 + .byte 0 + .byte 0 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 0 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 0 + .byte 4 + .byte 0 + .byte 4 + .byte 4 + .byte 0 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 0 + .byte 4 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 0 + .byte 0 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 + .byte 4 +""") +assert len(xed_disp_bits_2d) == 512 + +xed_imm_bits_2d = tabify("""\ + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 5 + .byte 7 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 9 + .byte 7 + .byte 1 + .byte 0 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 5 + .byte 7 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 5 + .byte 7 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 5 + .byte 7 + .byte 0 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 5 + .byte 7 + .byte 0 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 9 + .byte 7 + .byte 0 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 5 + .byte 7 + .byte 0 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 6 + .byte 7 + .byte 5 + .byte 5 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 5 + .byte 7 + .byte 5 + .byte 5 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 8 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 5 + .byte 7 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 9 + .byte 9 + .byte 9 + .byte 9 + .byte 9 + .byte 9 + .byte 9 + .byte 9 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 9 + .byte 9 + .byte 8 + .byte 1 + .byte 1 + .byte 1 + .byte 9 + .byte 2 + .byte 11 + .byte 1 + .byte 8 + .byte 1 + .byte 1 + .byte 9 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 9 + .byte 9 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 9 + .byte 9 + .byte 9 + .byte 9 + .byte 1 + .byte 1 + .byte 8 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 0 + .byte 1 + .byte 0 + .byte 0 + .byte 1 + .byte 1 + .byte 3 + .byte 4 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 0 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 0 + .byte 1 + .byte 0 + .byte 1 + .byte 1 + .byte 0 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 0 + .byte 1 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 9 + .byte 9 + .byte 9 + .byte 9 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 12 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 9 + .byte 1 + .byte 0 + .byte 0 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 9 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 9 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 9 + .byte 1 + .byte 9 + .byte 9 + .byte 9 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1""") + +tables = [('xed_prefix_table_bit', xed_prefix_table_bit), + ('xed_has_modrm_2d', xed_has_modrm_2d), + ('xed_has_disp_regular', kHasDisp), + ('xed_has_sib_table', kHasSib), + ('xed_disp_bits_2d', xed_disp_bits_2d), + ('xed_imm_bits_2d', xed_imm_bits_2d)] + +# int main(int argc, char *argv[]) { +# int l = 0; +# for (unsigned i = 0; i < 256; ++i) { +# int t = 0; +# if (isspace(i)) t |= 0x01; +# if (isalpha(i)) t |= 0x02; +# if (isdigit(i)) t |= 0x04; +# if (isxdigit(i)) t |= 0x08; +# if (isprint(i)) t |= 0x10; +# if (islower(i)) t |= 0x20; +# if (isupper(i)) t |= 0x40; +# if (isblank(i)) t |= 0x80; +# printf("0x%02x,", t); +# if (++l % 8 == 0) printf("\n"); +# } +# return 0; +# } + +kCtype = [ +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x81,0x01,0x01,0x01,0x01,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x91,0x10,0x10,0x10,0x10,0x10,0x10,0x10, +0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, +0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, +0x1c,0x1c,0x10,0x10,0x10,0x10,0x10,0x10, +0x10,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x52, +0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, +0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, +0x52,0x52,0x52,0x10,0x10,0x10,0x10,0x10, +0x10,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x32, +0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32, +0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32, +0x32,0x32,0x32,0x10,0x10,0x10,0x10,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +] +tables = [('kCtype', kCtype)] + + +kWidthTab1 = [ + 16, 16, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 16, 16, 32, 16, 16, 16, 33, 34, 35, 36, 37, 38, 39, + 16, 16, 40, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 41, + 42, 16, 16, 43, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 44, 16, 45, 46, 47, 48, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 49, 16, 16, 50, + 51, 16, 52, 53, 54, 16, 16, 16, 16, 16, 16, 55, 16, 16, 16, + 16, 16, 56, 57, 58, 59, 60, 61, 62, 63, 16, 16, 64, 16, 65, + 66, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 67, 68, 16, 16, 16, 69, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 70, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 71, 72, 16, 16, 16, 16, 16, 16, 16, 73, 16, 16, 16, 16, 16, + 74, 16, 16, 16, 16, 16, 16, 16, 75, 76, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 255, + 255, 255, 255, 191, 182, 0, 0, 0, 0, 0, 0, 0, 63, 0, 255, + 23, 0, 0, 0, 0, 0, 248, 255, 255, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 192, 191, 159, 61, 0, 0, 0, + 128, 2, 0, 0, 0, 255, 255, 255, 7, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 192, 255, 1, 0, 0, 0, 0, 0, 0, 248, 15, + 0, 0, 0, 192, 251, 239, 62, 0, 0, 0, 0, 0, 14, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 255, + 255, 255, 255, 7, 0, 0, 0, 0, 0, 0, 20, 254, 33, 254, 0, + 12, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 16, 30, 32, 0, + 0, 12, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 16, 134, 57, + 2, 0, 0, 0, 35, 0, 6, 0, 0, 0, 0, 0, 0, 16, 190, + 33, 0, 0, 12, 0, 0, 252, 2, 0, 0, 0, 0, 0, 0, 144, + 30, 32, 64, 0, 12, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 1, 32, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 192, 193, 61, 96, 0, 12, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 144, 64, 48, 0, 0, 12, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 24, 30, 32, 0, 0, 12, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 92, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 242, 7, 128, 127, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 242, 27, 0, 63, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 160, 2, 0, 0, 0, 0, 0, 0, 254, + 127, 223, 224, 255, 254, 255, 255, 255, 31, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 224, 253, 102, 0, 0, 0, 195, 1, + 0, 30, 0, 100, 32, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, + 0, 12, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 176, 63, + 64, 254, 15, 32, 0, 0, 0, 0, 0, 120, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, + 1, 4, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, + 9, 0, 0, 0, 0, 0, 0, 64, 127, 229, 31, 248, 159, 0, 0, + 0, 0, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 0, 0, 15, + 0, 0, 0, 0, 0, 208, 23, 4, 0, 0, 0, 0, 248, 15, 0, + 3, 0, 0, 0, 60, 59, 0, 0, 0, 0, 0, 0, 64, 163, 3, + 0, 0, 0, 0, 0, 0, 240, 207, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 247, 255, 253, + 33, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 255, 255, 255, 251, 0, 248, 0, 0, 0, 124, 0, 0, 0, 0, + 0, 0, 223, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 128, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 247, 63, 0, + 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 68, 8, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 255, 255, + 3, 0, 0, 0, 0, 0, 192, 63, 0, 0, 128, 255, 3, 0, 0, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 200, 19, 0, 0, 0, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 126, 102, 0, 8, 16, 0, + 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 157, 193, 2, 0, + 0, 0, 0, 48, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 32, 33, 0, 0, 0, 0, 0, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 192, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 110, 240, 0, 0, 0, 0, 0, 135, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 96, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 255, + 127, 0, 0, 0, 0, 0, 0, 128, 3, 0, 0, 0, 0, 0, 120, + 38, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 128, 239, + 31, 0, 0, 0, 0, 0, 0, 0, 8, 0, 3, 0, 0, 0, 0, + 0, 192, 127, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 128, 211, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 128, 248, 7, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 16, 1, 0, 0, 0, 192, 31, 31, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 255, 92, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 248, 133, 13, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 176, 1, 0, 0, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 167, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 191, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 188, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 126, 6, 0, 0, 0, 0, 248, + 121, 128, 0, 126, 14, 0, 0, 0, 0, 0, 252, 127, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 127, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 255, + 255, 252, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 126, 180, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, + 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 128, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 15, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 3, 248, 255, 231, 15, 0, 0, 0, 60, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 255, 255, 127, 248, 255, 255, 255, 255, 255, 31, 32, 0, 16, 0, 0, + 248, 254, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 255, + 255, 249, 219, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, +] +kWidthTab2 = [ + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 18, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 19, 16, 20, 21, 22, 16, 16, 16, 23, 16, + 16, 24, 25, 26, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 29, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 30, + 16, 16, 16, 16, 31, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 32, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 16, 16, 16, 33, + 34, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 35, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 36, 17, 17, 37, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 38, 39, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 40, 41, 42, 43, 44, 45, 46, 16, 16, 47, 16, 16, 16, 16, + 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 30, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 48, + 0, 0, 0, 0, 0, 0, 255, 15, 0, 0, 0, 0, 128, 0, 0, + 8, 0, 2, 12, 0, 96, 48, 64, 16, 0, 0, 4, 44, 36, 32, + 12, 0, 0, 0, 1, 0, 0, 0, 80, 184, 0, 0, 0, 0, 0, + 0, 0, 224, 0, 0, 0, 1, 128, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 251, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 15, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 63, 0, 0, 0, 255, 15, 255, 255, 255, 255, 255, 255, 255, 127, + 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127, 254, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 224, 255, 255, 255, 255, 127, + 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127, 255, 255, 255, + 255, 255, 7, 255, 255, 255, 255, 15, 0, 255, 255, 255, 255, 255, 127, + 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 31, 255, 255, 255, 255, 255, 255, 127, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, + 255, 255, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 15, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 255, 255, 255, + 255, 247, 255, 127, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 31, 0, 0, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 7, + 0, 255, 255, 255, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 254, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 255, 255, 255, 255, + 255, 15, 255, 1, 3, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + 1, 224, 191, 255, 255, 255, 255, 255, 255, 255, 255, 223, 255, 255, 15, + 0, 255, 255, 255, 255, 255, 135, 15, 0, 255, 255, 17, 255, 255, 255, + 255, 255, 255, 255, 255, 127, 253, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 159, + 255, 255, 255, 255, 255, 255, 255, 63, 0, 120, 255, 255, 255, 0, 0, + 4, 0, 0, 96, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, + 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 63, 16, 7, 0, + 0, 24, 240, 1, 0, 0, 255, 255, 255, 255, 255, 127, 255, 31, 255, + 255, 255, 15, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 1, 0, + 255, 255, 127, 0, 0, 0, +] + +kZlibDistCode = [ + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 18, 18, 19, 19, 20, 20, + 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, + 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29] + +# kZlibLengthCode = [ +# 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, +# 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, +# 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, +# 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +# 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, +# 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, +# 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, +# 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +# 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +# 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +# 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +# 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, +# 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +# 27, 27, 27, 27, 27, 27, 27, 27, 28] + +# duk_hex_dectab = [ +# 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, # 0x00-0x0f */ +# 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, # 0x10-0x1f */ +# 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, # 0x20-0x2f */ +# 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,0xff,0xff,0xff,0xff,0xff,0xff, # 0x30-0x3f */ +# 0xff, 10, 11, 12, 13, 14, 15,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, # 0x40-0x4f */ +# 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, # 0x50-0x5f */ +# 0xff, 10, 11, 12, 13, 14, 15,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, # 0x60-0x6f */ +# 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, # 0x70-0x7f */ +# 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, # 0x80-0x8f */ +# 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, # 0x90-0x9f */ +# 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, # 0xa0-0xaf */ +# 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, # 0xb0-0xbf */ +# 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, # 0xc0-0xcf */ +# 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, # 0xd0-0xdf */ +# 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, # 0xe0-0xef */ +# 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff # 0xf0-0xff */ +# ] + +# tables = [('duk__base64_dectab_fast', duk__base64_dectab_fast)] + +def kXtermXlat1(c): + if c >= 3: + return (c - 3) / 10 + return 0 +def kXtermXlat2(c): + if c <= 52: return 0 + if c <= 115: return 1 + if c <= 155: return 2 + if c <= 195: return 3 + if c <= 235: return 4 + return 5 +tables = [('kXtermXlat', ([kXtermXlat1(i) for i in range(256)] + + [kXtermXlat2(i) for i in range(256)]))] + +kBoop = [int(s,16) for s in """ + 00 00 00 00 00 00 00 00 00 00 01 01 01 01 01 01 + 01 00 00 00 00 00 00 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 00 00 00 00 00 00 01 02 02 02 02 02 02 02 02 + 02 02 01 01 01 01 01 01 01 02 02 02 02 02 02 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 02 02 02 02 02 02 01 + 03 03 03 03 03 03 03 03 03 03 01 01 01 01 01 01 + 01 03 03 03 03 03 03 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 03 03 03 03 03 03 01 04 04 04 04 04 04 04 04 + 04 04 01 01 01 01 01 01 01 04 04 04 04 04 04 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 04 04 04 04 04 04 01 + 05 05 05 05 05 05 05 05 05 05 01 01 01 01 01 01 + 01 05 05 05 05 05 05 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 05 05 05 05 05 05 01 06 06 06 06 06 06 06 06 + 06 06 01 01 01 01 01 01 01 06 06 06 06 06 06 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 06 06 06 06 06 06 01 + 07 01 01 07 08 07 07 07 07 07 07 01 07 07 01 07 + 07 07 07 07 07 07 07 07 07 07 01 01 01 01 01 01 + 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 + 07 07 07 07 07 07 07 07 07 07 07 01 07 01 07 01 + 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 + 07 07 07 07 07 07 07 07 07 07 01 01 01 07 01 09 + 09 09 09 09 09 09 09 09 09 01 01 01 01 01 01 01 + 09 09 09 09 09 09 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 09 09 09 09 09 09 01 0a 0a 0a 0a 0a 0a 0a 0a 0a + 0a 01 01 01 01 01 01 01 0a 0a 0a 0a 0a 0a 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 0a 0a 0a 0a 0a 0a 01 0b + 01 01 0b 0c 0b 0b 0b 0b 0b 0b 01 0b 0b 01 0b 0b + 0b 0b 0b 0b 0b 0b 0b 0b 0b 01 01 01 01 01 01 0b + 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b + 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 01 0b 01 0b 01 0b + 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b + 0b 0b 0b 0b 0b 0b 0b 0b 0b 01 01 01 0b 01 0d 0d + 0d 0d 0d 0d 0d 0d 0d 0d 01 01 01 01 01 01 01 0d + 0d 0d 0d 0d 0d 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 0d + 0d 0d 0d 0d 0d 01 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e + 01 01 01 01 01 01 01 0e 0e 0e 0e 0e 0e 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 0e 0e 0e 0e 0e 0e 01 0f 01 + 01 0f 10 01 0f 0f 0f 0f 0f 01 0f 0f 0f 0f 0f 0f + 0f 0f 0f 0f 0f 0f 0f 0f 01 01 01 01 0f 01 0f 0f + 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f + 0f 0f 0f 0f 0f 0f 0f 0f 0f 01 0f 01 0f 01 0f 0f + 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f + 0f 0f 0f 0f 0f 0f 0f 0f 01 01 01 0f 01 11 11 11 + 11 11 11 11 11 11 11 01 01 01 01 01 01 01 11 11 + 11 11 11 11 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 11 11 + 11 11 11 11 01 12 12 12 12 12 12 12 12 12 12 01 + 01 01 01 01 01 01 12 12 12 12 12 12 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 12 12 12 12 12 12 01 13 01 01 + 13 14 01 13 13 13 13 13 01 13 13 13 13 13 13 13 + 13 13 13 13 13 13 13 01 01 01 01 13 01 13 13 13 + 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 + 13 13 13 13 13 13 13 13 01 13 01 13 01 13 13 13 + 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 + 13 13 13 13 13 13 13 01 01 01 13 01 15 15 15 15 + 15 15 15 15 15 15 01 01 01 01 01 01 01 15 15 15 + 15 15 15 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 15 15 15 + 15 15 15 01 16 16 16 16 16 16 16 16 16 16 01 01 + 01 01 01 01 01 16 16 16 16 16 16 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 16 16 16 16 16 16 01 17 17 17 17 + 17 17 17 17 17 17 01 01 01 01 01 01 01 17 17 17 + 17 17 17 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 17 17 17 + 17 17 17 01 18 18 18 18 18 18 18 18 18 18 01 01 + 01 01 01 01 01 18 18 18 18 18 18 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 18 18 18 18 18 18 01 19 01 01 19 + 1a 1b 19 19 19 19 19 1b 19 19 0f 19 19 19 19 19 + 19 19 19 19 19 19 01 01 1b 01 19 1c 19 19 19 19 + 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 + 19 19 19 19 19 19 0f 01 0f 01 19 01 19 19 19 19 + 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 + 19 19 19 19 19 19 01 01 01 19 01 1d 1d 1d 1d 1d + 1d 1d 1d 1d 1d 01 01 01 01 01 01 01 1d 1d 1d 1d + 1d 1d 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 1d 1d 1d 1d + 1d 1d 01 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 01 01 01 + 01 01 01 01 1e 1e 1e 1e 1e 1e 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 1e 1e 1e 1e 1e 1e 01 1b 01 01 1b 1f + 1b 1b 1b 1b 1b 1b 1b 1b 1b 01 1b 1b 1b 1b 1b 1b + 1b 1b 1b 1b 1b 01 01 1b 01 1b 1c 1b 1b 1b 1b 1b + 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b + 1b 1b 1b 1b 1b 01 01 01 01 1b 01 1b 1b 1b 1b 1b + 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b + 1b 1b 1b 1b 1b 01 01 01 1b 01 20 20 20 20 20 20 + 20 20 20 20 01 01 01 01 01 01 01 20 20 20 20 20 + 20 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 20 20 20 20 20 + 20 01 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 01 01 01 01 + 01 01 01 1b 1b 1b 1b 1b 1b 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 1b 1b 1b 1b 1b 1b 01 21 01 21 21 01 21 + 21 21 21 21 21 21 21 21 21 01 01 01 01 01 01 01 + 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 + 21 21 21 21 21 21 21 21 21 21 22 01 01 01 01 01 + 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 + 21 21 21 21 21 21 21 21 21 21 01 23 23 23 23 23 + 23 23 23 23 23 01 24 01 24 24 24 24 24 24 24 24 + 24 24 24 01 01 01 01 01 01 24 24 24 24 24 24 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 24 24 24 24 24 24 01 + 25 01 25 25 25 25 25 25 25 25 25 25 25 01 01 01 + 01 01 01 25 25 25 25 25 25 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 26 + 01 01 01 25 25 25 25 25 25 01 27 01 01 27 28 1b + 27 27 27 27 27 1b 27 27 13 27 27 27 27 27 27 27 + 27 27 27 27 01 01 1b 01 27 1c 27 27 27 27 27 27 + 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 + 27 27 27 27 13 01 13 01 27 01 27 27 27 27 27 27 + 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 + 27 27 27 27 01 01 01 27 01 29 29 29 29 29 29 29 + 29 29 29 01 01 01 01 01 01 01 29 29 29 29 29 29 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 29 29 29 29 29 29 + 01 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 01 01 01 01 01 + 01 01 2a 2a 2a 2a 2a 2a 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 2a 2a 2a 2a 2a 2a 01 2b 01 01 2b 2c 2b 2b + 2b 2b 2b 2d 2b 2d 2d 2e 2d 2d 2d 2d 2d 2d 2d 2d + 2d 2d 2b 2f 01 2b 01 2b 2f 2d 2d 2d 2d 2d 2d 2d + 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d + 2d 2d 2d 30 01 01 01 2b 01 2d 2d 2d 2d 2d 2d 2d + 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d + 2d 2d 2d 01 01 01 2b 01 31 31 31 31 31 31 31 31 + 31 31 01 01 01 01 01 01 01 31 31 31 31 31 31 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 31 31 31 31 31 31 01 + 32 32 32 32 32 32 32 32 32 32 01 01 01 01 01 01 + 01 32 32 32 32 32 32 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 32 32 32 32 32 32 01 33 33 33 33 33 33 33 33 + 33 33 01 01 01 01 01 01 01 33 33 33 33 33 33 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 33 33 33 33 33 33 01 + 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 01 01 01 01 01 01 + 01 2f 2f 2f 2f 2f 2f 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 2f 2f 2f 2f 2f 2f 01 34 34 34 34 34 34 34 34 + 34 34 01 01 01 01 01 01 01 34 34 34 34 34 34 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 34 34 34 34 34 34 01 + 35 35 35 35 35 35 35 35 35 35 01 01 01 01 01 01 + 01 35 35 35 35 35 35 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 35 35 35 35 35 35 01 36 36 36 36 36 36 36 36 + 36 36 01 01 01 01 01 01 01 36 36 36 36 36 36 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 36 36 36 36 36 36 01 + 37 37 37 37 37 37 37 37 37 37 01 01 01 01 01 01 + 01 37 37 37 37 37 37 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 37 37 37 37 37 37 01 38 38 38 38 38 38 38 38 + 38 38 01 01 01 01 01 01 01 38 38 38 38 38 38 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 38 38 38 38 38 38 01 + 39 39 39 39 39 39 39 39 39 39 01 01 01 01 01 01 + 01 39 39 39 39 39 39 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 39 39 39 39 39 39 01 3a 01 01 3a 3b 3a 3a 3a + 3a 3a 3a 01 3a 3a 01 3a 3a 3a 3a 3a 3a 3a 3a 3a + 3a 3a 01 01 01 01 01 01 3a 3a 3a 3a 3a 3a 3a 3a + 3a 3a 3a 3a 3a 3a 3a 3a 3a 3a 3a 3a 3a 3a 3a 3a + 3a 3a 3a 01 3a 01 3a 01 3a 3a 3a 3a 3a 3a 3a 3a + 3a 3a 3a 3a 3a 3a 3a 3a 3a 3a 3a 3a 3a 3a 3a 3a + 3a 3a 01 01 01 3a 01 3c 3c 3c 3c 3c 3c 3c 3c 3c + 3c 01 01 01 01 01 01 01 3c 3c 3c 3c 3c 3c 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 3c 3c 3c 3c 3c 3c 01 3d + 3d 3d 3d 3d 3d 3d 3d 3d 3d 01 01 01 01 01 01 01 + 3d 3d 3d 3d 3d 3d 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 3d 3d 3d 3d 3d 3d 01 3e 01 01 3e 3f 3e 3e 3e 3e + 3e 3e 01 3e 3e 01 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e + 3e 01 01 01 01 01 01 3e 3e 3e 3e 3e 3e 3e 3e 3e + 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e + 3e 3e 01 3e 01 3e 01 3e 3e 3e 3e 3e 3e 3e 3e 3e + 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e + 3e 01 01 01 3e 01 40 01 40 40 40 40 40 40 40 40 + 40 40 40 01 01 01 01 01 01 40 40 40 40 40 40 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 40 40 40 40 40 40 01 + 41 01 41 41 41 41 41 41 41 41 41 41 41 01 01 01 + 01 01 01 41 41 41 41 41 41 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 42 + 01 01 01 41 41 41 41 41 41 01 43 43 43 43 43 43 + 43 43 43 43 01 44 01 45 44 46 44 44 44 44 44 44 + 44 44 44 2e 44 44 44 44 44 44 44 44 44 44 01 44 + 01 44 01 01 44 47 47 47 47 47 47 47 47 47 47 47 + 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 01 + 01 01 01 44 01 47 47 47 47 47 47 47 47 47 47 47 + 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 01 + 01 01 44 01 04 01 48 04 49 04 04 04 04 04 04 04 + 04 04 4a 04 04 04 04 04 04 04 04 04 04 01 04 01 + 04 01 4b 04 04 04 04 04 04 04 04 04 04 04 04 04 + 04 04 04 04 04 04 04 04 04 04 04 04 04 04 01 01 + 01 01 04 01 04 04 04 04 04 04 04 04 04 04 04 04 + 04 04 04 04 04 04 04 04 04 04 04 04 04 04 01 01 + 01 04 01 4c 01 01 4c 4d 4c 4c 4c 4c 4c 4c 4c 4c + 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 01 4c + 01 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c + 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 01 01 01 + 01 4c 01 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c + 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 4c 01 01 01 + 4c 01 02 01 01 02 4e 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 01 02 01 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 02 01 01 01 01 + 02 01 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 02 01 01 01 02 + 01 06 01 48 06 4f 06 06 06 06 06 06 06 06 06 4a + 06 06 06 06 06 06 06 06 06 06 06 50 01 06 01 4b + 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 + 06 06 06 06 06 06 06 06 06 06 06 01 01 01 01 06 + 01 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 + 06 06 06 06 06 06 06 06 06 06 06 01 01 01 06 01 + 0a 01 51 0a 52 0a 0a 0a 0a 0a 0a 01 0a 0a 53 0a + 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 54 01 55 01 56 01 + 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a + 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 01 0a 01 0a 01 + 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a + 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 01 01 01 0a 01 0e + 01 57 0e 58 0e 0e 0e 0e 0e 0e 01 0e 0e 59 0e 0e + 0e 0e 0e 0e 0e 0e 0e 0e 0e 5a 01 01 01 5b 01 0e + 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e + 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 01 0e 01 0e 01 0e + 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e + 0e 0e 0e 0e 0e 0e 0e 0e 0e 01 01 01 0e 01 12 01 + 5c 12 5d 5e 12 12 12 12 12 01 12 12 12 12 12 12 + 12 12 12 12 12 12 12 12 01 01 5f 01 12 01 12 12 + 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 + 12 12 12 12 12 12 12 12 12 01 12 01 12 01 12 12 + 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 + 12 12 12 12 12 12 12 12 01 01 01 12 01 16 01 60 + 16 61 62 16 16 16 16 16 01 16 16 16 16 16 16 16 + 16 16 16 16 16 16 16 01 01 01 01 16 01 16 16 16 + 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 + 16 16 16 16 16 16 16 16 01 16 01 16 01 16 16 16 + 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 + 16 16 16 16 16 16 16 01 01 01 16 01 06 01 48 06 + 4f 06 06 06 06 06 06 06 06 06 63 06 06 06 06 06 + 06 06 06 06 06 06 50 01 06 01 4b 06 06 06 06 06 + 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 + 06 06 06 06 06 06 01 01 01 01 06 01 06 06 06 06 + 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 + 06 06 06 06 06 06 01 01 01 06 01 64 01 48 64 65 + 64 64 64 64 64 66 64 66 66 4a 66 66 66 66 66 66 + 66 66 66 66 64 50 01 64 01 67 06 66 66 66 66 66 + 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 + 66 66 66 66 66 22 01 01 01 64 01 66 66 66 66 66 + 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 + 66 66 66 66 66 01 01 01 64 01 18 01 48 18 68 18 + 18 18 18 18 18 18 18 18 4a 18 18 18 18 18 18 18 + 18 18 18 18 50 01 18 01 69 6a 18 18 18 18 18 18 + 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 + 18 18 18 18 01 01 01 01 18 01 18 18 18 18 18 18 + 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 + 18 18 18 18 01 01 01 18 01 1e 01 5c 1e 6b 6c 1e + 1e 1e 1e 1e 1b 1e 1e 12 1e 1e 1e 1e 1e 1e 1e 1e + 1e 1e 1e 01 01 6d 01 1e 1c 1e 1e 1e 1e 1e 1e 1e + 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e + 1e 1e 1e 12 01 12 01 1e 01 1e 1e 1e 1e 1e 1e 1e + 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e 1e + 1e 1e 1e 01 01 01 1e 01 6e 01 01 01 01 01 01 01 + 6f 01 6f 6f 70 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 71 + 01 01 01 01 72 01 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f + 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f + 01 01 01 01 01 01 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f + 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f 6f + 01 73 01 01 01 01 01 01 01 01 01 01 01 74 75 75 + 75 75 75 75 75 75 75 75 01 01 01 01 01 76 01 45 + 01 01 01 01 01 01 01 01 01 01 01 77 01 01 01 01 + 01 01 01 01 01 01 78 01 01 01 01 79 01 2a 01 60 + 2a 7a 7b 2a 2a 2a 2a 2a 1b 2a 2a 16 2a 2a 2a 2a + 2a 2a 2a 2a 2a 2a 2a 01 01 1b 01 2a 1c 2a 2a 2a + 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a + 2a 2a 2a 2a 2a 2a 2a 16 01 16 01 2a 01 2a 2a 2a + 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a + 2a 2a 2a 2a 2a 2a 2a 01 01 01 2a 01 06 01 48 06 + 4f 06 06 06 06 06 7c 06 7c 7c 4a 7c 7c 7c 7c 7c + 7c 7c 7c 7c 7c 06 50 01 06 01 4b 06 7c 7c 7c 7c + 7c 7c 7c 7c 7c 7c 7c 7c 7c 7c 7c 7c 7c 7c 7c 7c + 7c 7c 7c 7c 7c 7c 22 01 01 01 06 01 7c 7c 7c 7c + 7c 7c 7c 7c 7c 7c 7c 7c 7c 7c 7c 7c 7c 7c 7c 7c + 7c 7c 7c 7c 7c 7c 01 01 01 06 01 06 01 7d 06 4f + 06 06 06 06 06 7e 06 7e 7e 7f 7e 7e 7e 7e 7e 7e + 7e 7e 7e 7e 80 50 01 06 01 81 06 7e 7e 7e 7e 7e + 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e + 7e 7e 7e 7e 7e 01 01 01 01 06 01 7e 7e 7e 7e 7e + 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e + 7e 7e 7e 7e 7e 01 01 01 06 01 06 01 48 06 4f 06 + 06 06 06 06 06 06 06 06 4a 82 82 82 82 82 82 82 + 82 82 82 06 50 01 06 01 4b 06 06 06 06 06 06 06 + 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 + 06 06 06 06 01 01 01 01 06 01 06 06 06 06 06 06 + 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 + 06 06 06 06 01 01 01 06 01 06 01 83 06 4f 06 06 + 06 06 06 06 06 06 06 84 85 85 85 85 85 85 85 85 + 85 85 06 50 01 06 01 86 06 06 06 06 06 06 06 06 + 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 + 06 06 06 01 01 01 01 06 01 06 06 06 06 06 06 06 + 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 + 06 06 06 01 01 01 06 01 18 01 7d 18 68 18 18 18 + 18 18 87 18 87 87 7f 87 87 87 87 87 87 87 87 87 + 87 88 50 01 18 01 89 6a 87 87 87 87 87 87 87 87 + 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 + 87 87 01 01 01 01 18 01 87 87 87 87 87 87 87 87 + 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 + 87 87 01 01 01 18 01 18 01 48 18 68 18 18 18 18 + 18 18 18 18 18 4a 8a 8a 8a 8a 8a 8a 8a 8a 8a 8a + 18 50 01 18 01 69 6a 18 18 18 18 18 18 18 18 18 + 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 + 18 01 01 01 01 18 01 18 18 18 18 18 18 18 18 18 + 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 + 18 01 01 01 18 01 18 01 83 18 68 18 18 18 18 18 + 18 18 18 18 84 8b 8b 8b 8b 8b 8b 8b 8b 8b 8b 18 + 50 01 18 01 8c 6a 18 18 18 18 18 18 18 18 18 18 + 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 + 01 01 01 01 18 01 18 18 18 18 18 18 18 18 18 18 + 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 + 01 01 01 18 01 04 01 48 04 49 04 04 04 04 04 8d + 04 8d 8d 4a 8d 8d 8d 8d 8d 8d 8d 8d 8d 8d 8e 04 + 01 04 01 4b 04 8d 8d 8d 8d 8d 8d 8d 8d 8d 8d 8d + 8d 8d 8d 8d 8d 8d 8d 8d 8d 8d 8d 8d 8d 8d 8d 01 + 01 01 01 04 01 8d 8d 8d 8d 8d 8d 8d 8d 8d 8d 8d + 8d 8d 8d 8d 8d 8d 8d 8d 8d 8d 8d 8d 8d 8d 8d 01 + 01 01 04 01 32 01 45 32 8f 32 32 32 32 32 32 32 + 32 32 90 32 32 32 32 32 32 32 32 32 32 32 2f 01 + 32 01 32 91 32 32 32 32 32 32 32 32 32 32 32 32 + 32 32 32 32 32 32 32 32 32 32 32 32 32 32 01 01 + 01 01 32 01 32 32 32 32 32 32 32 32 32 32 32 32 + 32 32 32 32 32 32 32 32 32 32 32 32 32 32 01 01 + 01 32 01 45 01 2f 01 45 2f 92 2f 2f 2f 2f 2f 2f + 2f 2f 2f 90 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f + 01 2f 01 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f + 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 01 + 01 01 01 2f 01 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f + 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 01 + 01 01 2f 01 2f 01 45 2f 92 2f 2f 2f 2f 2f 93 2f + 93 93 90 93 93 93 93 93 93 93 93 93 93 2f 2f 01 + 2f 01 2f 2f 93 93 93 93 93 93 93 93 93 93 93 93 + 93 93 93 93 93 93 93 93 93 93 93 93 93 93 30 01 + 01 01 2f 01 93 93 93 93 93 93 93 93 93 93 93 93 + 93 93 93 93 93 93 93 93 93 93 93 93 93 93 01 01 + 01 2f 01 2f 01 6e 2f 92 2f 2f 2f 2f 2f 94 2f 94 + 94 90 94 94 94 94 94 94 94 94 94 94 95 96 01 2f + 01 2f 2f 94 94 94 94 94 94 94 94 94 94 94 94 94 + 94 94 94 94 94 94 94 94 94 94 94 94 94 01 01 01 + 01 2f 01 94 94 94 94 94 94 94 94 94 94 94 94 94 + 94 94 94 94 94 94 94 94 94 94 94 94 94 01 01 01 + 2f 01 2f 01 45 2f 92 2f 2f 2f 2f 2f 2f 2f 2f 2f + 90 97 97 97 97 97 97 97 97 97 97 2f 2f 01 2f 01 + 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f + 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 01 01 01 01 + 2f 01 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f + 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 01 01 01 2f + 01 2f 01 73 2f 92 2f 2f 2f 2f 2f 2f 2f 2f 2f 90 + 98 98 98 98 98 98 98 98 98 98 2f 99 01 2f 01 2f + 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f + 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 01 01 01 01 2f + 01 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f + 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 01 01 01 2f 01 + 9a 01 45 9a 9b 9a 9a 9a 9a 9a 9a 2f 9a 9a 90 9a + 9a 9a 9a 9a 9a 9a 9a 9a 9a 9a 2f 01 2f 01 2f 2f + 9a 9a 9a 9a 9a 9a 9a 9a 9a 9a 9a 9a 9a 9a 9a 9a + 9a 9a 9a 9a 9a 9a 9a 9a 9a 9a 3a 01 3a 01 9a 01 + 9a 9a 9a 9a 9a 9a 9a 9a 9a 9a 9a 9a 9a 9a 9a 9a + 9a 9a 9a 9a 9a 9a 9a 9a 9a 9a 01 01 01 9a 01 35 + 01 51 35 9c 35 35 35 35 35 35 2f 35 35 90 35 35 + 35 35 35 35 35 35 35 35 35 9d 01 9e 01 2f 2f 35 + 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 + 35 35 35 35 35 35 35 35 35 3d 01 3d 01 35 01 35 + 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 + 35 35 35 35 35 35 35 35 35 01 01 01 35 01 9f 01 + 45 9f a0 9f 9f 9f 9f 9f 9f 2f 9f 9f 90 9f 9f 9f + 9f 9f 9f 9f 9f 9f 9f 9f 2f 01 2f 01 2f 2f 9f 9f + 9f 9f 9f 9f 9f 9f 9f 9f 9f 9f 9f 9f 9f 9f 9f 9f + 9f 9f 9f 9f 9f 9f 9f 9f 3e 01 3e 01 9f 01 9f 9f + 9f 9f 9f 9f 9f 9f 9f 9f 9f 9f 9f 9f 9f 9f 9f 9f + 9f 9f 9f 9f 9f 9f 9f 9f 01 01 01 9f 01 37 01 57 + 37 a1 37 37 37 37 37 37 2f 37 37 90 37 37 37 37 + 37 37 37 37 37 37 37 a2 01 2f 01 2f 2f 37 37 37 + 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 + 37 37 37 37 37 37 37 39 01 39 01 37 01 37 37 37 + 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 + 37 37 37 37 37 37 37 01 01 01 37 01 39 01 57 39 + a3 39 39 39 39 39 39 01 39 39 01 39 39 39 39 39 + 39 39 39 39 39 39 a4 01 01 01 01 01 39 39 39 39 + 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 + 39 39 39 39 39 39 39 01 39 01 39 01 39 39 39 39 + 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 39 + 39 39 39 39 39 39 01 01 01 39 01 3d 01 51 3d a5 + 3d 3d 3d 3d 3d 3d 01 3d 3d 01 3d 3d 3d 3d 3d 3d + 3d 3d 3d 3d 3d a6 01 a7 01 01 01 3d 3d 3d 3d 3d + 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d + 3d 3d 3d 3d 3d 3d 01 3d 01 3d 01 3d 3d 3d 3d 3d + 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d 3d + 3d 3d 3d 3d 3d 01 01 01 3d 01 45 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 a8 a9 01 73 01 01 01 01 01 01 01 01 01 01 01 + 01 aa aa aa aa aa aa aa aa aa aa 01 ab 01 32 01 + 6e 32 8f 32 32 32 32 32 ac 32 ac ac 90 ac ac ac + ac ac ac ac ac ac ac ad 96 01 32 01 32 91 ac ac + ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac + ac ac ac ac ac ac ac ac 01 01 01 01 32 01 ac ac + ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac ac + ac ac ac ac ac ac ac ac 01 01 01 32 01 32 01 45 + 32 8f 32 32 32 32 32 32 32 32 32 90 ae ae ae ae + ae ae ae ae ae ae 32 2f 01 32 01 32 91 32 32 32 + 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 + 32 32 32 32 32 32 32 01 01 01 01 32 01 32 32 32 + 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 + 32 32 32 32 32 32 32 01 01 01 32 01 32 01 73 32 + 8f 32 32 32 32 32 32 32 32 32 90 af af af af af + af af af af af 32 99 01 32 01 32 91 32 32 32 32 + 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 + 32 32 32 32 32 32 01 01 01 01 32 01 32 32 32 32 + 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 + 32 32 32 32 32 32 01 01 01 32 01 00 +""".split()] + +tables = [('kBoop', kBoop)] + + +lines = [] +def put(l): + lines.append(l) +oc = 0 +toto = 0 +for name, table in tables: + toto += len(table) + it = iter(table) + c2 = next(it) + i2 = 0 + put(".L%s.rodata:" % (name)) + while c2 is not None: + c1, i1, run = c2, i2, 0 + while c1 == c2: + run += 1 + i2 += 1 + c2 = next(it, None) + s = ' ' + if 0 <= i1 < 256 and 0 <= i2 <= 256: + s = "%s " % C[i1] if i2 - i1 == 1 else "%s-%s" % (C[i1], C[i2-1]) + put("\t.byte\t%d,0x%02x\t\t# %02x-%02x %s" % (run, c1, i1, i2-1, s)) + oc += 2 + put("\t.endobj\t.L%s.rodata" % (name)) +put("\t.byte\t0,0\t\t# terminator") +oc += 2 +align = 8 +pad = align - oc % align +if pad != align: + put("\t.byte\t%s\t\t# padding" % (",".join(["0"] * pad))) + oc += pad + +print "\t.initbss 300,_init_%s" % (name) +for name, table in tables: + print "%s:" % (name) + print "\t.zero\t%d" % (len(table)) + print "\t.endobj\t%s,globl,hidden" % (name) +print "\t.previous" +print + +print "\t.initro 300,_init_%s\t# %d bytes (%d%%)" % ( + name, oc, int(round((oc / float(toto)) * 100))) +print "\n".join(lines) +print "\t.previous" +print + +print "\t.init.start 300,_init_%s" % tables[0][0] +print "\tcall\trldecode" +if pad != align: + while pad: + for op, add in (("lodsq", 8), + ("lodsl", 4), + ("lodsw", 2), + ("lodsb", 1)): + if pad >= add: + print "\t%s" % (op) + pad -= add +print "\t.init.end 300,_init_%s" % tables[0][0] diff --git a/build/rules.mk b/build/rules.mk new file mode 100644 index 00000000..84c74bce --- /dev/null +++ b/build/rules.mk @@ -0,0 +1,99 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ +# +# SYNOPSIS +# +# Cosmopolitan Core Build Rules +# +# DESCRIPTION +# +# This file shows GNU Make how to convert between file types, based on +# their extensions. We use everyday, ordinary, boring, and ubiquitous +# system commands for everything, e.g. as, cc, ld, etc. with plain and +# simple shell-script wrappers, e.g. build/assemble and build/compile. +# Those veneers abstract away most of the boring trivialities, to keep +# our makefiles pristine and readable. + +MAKEFLAGS += --no-builtin-rules + +o/%.a:; @$(ARCHIVE) $@ $^ +o/%.o: %.s; @TARGET=$@ build/assemble $(OBJECTIFY.s) $(OUTPUT_OPTION) $< +o/%.o: o/%.s; @TARGET=$@ build/assemble $(OBJECTIFY.s) $(OUTPUT_OPTION) $< +o/%.s: %.S; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< +o/%.s: o/%.S; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< +o/%.i: %.S; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< +o/%.o: %.S; @ACTION=OBJECTIFY.S build/compile $(OBJECTIFY.S) $(OUTPUT_OPTION) $< +o/%.o: o/%.S; @ACTION=OBJECTIFY.S build/compile $(OBJECTIFY.S) $(OUTPUT_OPTION) $< +o/%.s: %.i; @ACTION=COMPILE.i build/compile $(COMPILE.i) $(OUTPUT_OPTION) $< +o/%.s: o/%.i; @ACTION=COMPILE.i build/compile $(COMPILE.i) $(OUTPUT_OPTION) $< +o/%.o: %.cc; @ACTION=OBJECTIFY.cxx build/compile $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< +o/%.o: o/%.cc; @ACTION=OBJECTIFY.cxx build/compile $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< +o/%.lds: %.lds; @ACTION=PREPROCESS build/compile $(PREPROCESS.lds) $(OUTPUT_OPTION) $< +o/%.inc: %.h; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) -D__ASSEMBLER__ -P $< +o/%.pkg:; @build/package $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) $(filter %.o,$^) +o/%.h.ok: %.h; @ACTION=CHECK.h build/compile $(COMPILE.c) -x c -g0 -o $@ $< +o/%.greg.o: %.greg.c; @ACTION=OBJECTIFY.greg build/compile $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $< +o/%.zip.o: %; @build/zipobj $(OUTPUT_OPTION) $< + +o/$(MODE)/%.a:; @$(ARCHIVE) $@ $^ +o/$(MODE)/%.o: %.s; @TARGET=$@ build/assemble $(OBJECTIFY.s) $(OUTPUT_OPTION) $< +o/$(MODE)/%.o: o/$(MODE)/%.s; @TARGET=$@ build/assemble $(OBJECTIFY.s) $(OUTPUT_OPTION) $< +o/$(MODE)/%.s: %.S; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< +o/$(MODE)/%.s: o/$(MODE)/%.S; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< +o/$(MODE)/%.o: %.c; @ACTION=OBJECTIFY.c build/compile $(OBJECTIFY.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.o: %.f; @ACTION=OBJECTIFY.f build/compile $(OBJECTIFY.f) $(OUTPUT_OPTION) $< +o/$(MODE)/%.o: %.F; @ACTION=OBJECTIFY.F build/compile $(OBJECTIFY.F) $(OUTPUT_OPTION) $< +o/$(MODE)/%.o: o/$(MODE)/%.c; @ACTION=OBJECTIFY.c build/compile $(OBJECTIFY.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.ss: %.c; @ACTION=COMPILE.c build/compile $(COMPILE.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.ss: o/$(MODE)/%.c; @ACTION=OBJECTIFY.s build/compile $(COMPILE.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.i: %.S; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< +o/$(MODE)/%.i: %.c; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< +o/$(MODE)/%.i: %.cc; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< +o/$(MODE)/%.i: o/$(MODE)/%.c; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< +o/$(MODE)/%.h: %.c; @ACTION=AMALGAMATE build/compile $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $< +o/$(MODE)/%.h: o/$(MODE)/%.c; @ACTION=AMALGAMATE build/compile $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $< +o/$(MODE)/%.o: %.S; @ACTION=OBJECTIFY.S build/compile $(OBJECTIFY.S) $(OUTPUT_OPTION) $< +o/$(MODE)/%.o: o/$(MODE)/%.S; @ACTION=OBJECTIFY.S build/compile $(OBJECTIFY.S) $(OUTPUT_OPTION) $< +o/$(MODE)/%.s: %.i; @ACTION=COMPILE.i build/compile $(COMPILE.i) $(OUTPUT_OPTION) $< +o/$(MODE)/%.s: o/$(MODE)/%.i; @ACTION=COMPILE.i build/compile $(COMPILE.i) $(OUTPUT_OPTION) $< +o/$(MODE)/%.o: %.cc; @ACTION=OBJECTIFY.cxx build/compile $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< +o/$(MODE)/%.o: o/$(MODE)/%.cc; @ACTION=OBJECTIFY.cxx build/compile $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< +o/$(MODE)/%.lds: %.lds; @ACTION=PREPROCESS build/compile $(PREPROCESS.lds) $(OUTPUT_OPTION) $< +o/$(MODE)/%.h.ok: %.h; @ACTION=CHECK.h build/compile $(COMPILE.c) -x c -g0 -o $@ $< +o/$(MODE)/%.o: %.greg.c; @ACTION=OBJECTIFY.greg build/compile $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.greg.o: %.greg.c; @ACTION=OBJECTIFY.greg build/compile $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.ansi.o: %.ansi.c; @ACTION=OBJECTIFY.ansi build/compile $(OBJECTIFY.ansi.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.ansi.o: %.c; @ACTION=OBJECTIFY.ansi build/compile $(OBJECTIFY.ansi.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.c99.o: %.c99.c; @ACTION=OBJECTIFY.c99 build/compile $(OBJECTIFY.c99.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.c11.o: %.c11.c; @ACTION=OBJECTIFY.c11 build/compile $(OBJECTIFY.c11.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.c2x.o: %.c2x.c; @ACTION=OBJECTIFY.c2x build/compile $(OBJECTIFY.c2x.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.initabi.o: %.initabi.c; @ACTION=OBJECTIFY.init build/compile $(OBJECTIFY.initabi.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.ncabi.o: %.ncabi.c; @ACTION=OBJECTIFY.nc build/compile $(OBJECTIFY.ncabi.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.runs: o/$(MODE)/%; @ACTION=CHECK.runs TARGET=$< build/runcom $< $(TESTARGS) && touch $@ +o/$(MODE)/%.pkg:; @build/package $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) $(filter %.o,$^) +o/$(MODE)/%.zip.o: %; @build/zipobj $(OUTPUT_OPTION) $< + +o/$(MODE)/%-gcc.asm: %.c; @ACTION=COMPILE.c build/compile $(COMPILE.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%-clang.asm: CC = $(CLANG) +o/$(MODE)/%-clang.asm: %.c; @ACTION=COMPILE.c build/compile $(COMPILE.c) $(OUTPUT_OPTION) $< || echo / need $(CLANG) >$@ +o/$(MODE)/%-gcc.asm: %.f; @ACTION=COMPILE.f build/compile $(COMPILE.f) $(OUTPUT_OPTION) $< +o/$(MODE)/%-clang.asm: CC = $(CLANG) +o/$(MODE)/%-clang.asm: %.f; @ACTION=COMPILE.f build/compile $(COMPILE.f) $(OUTPUT_OPTION) $< || echo / need $(CLANG) >$@ +o/$(MODE)/%-gcc.asm: %.F; @ACTION=COMPILE.F build/compile $(COMPILE.F) $(OUTPUT_OPTION) $< +o/$(MODE)/%-clang.asm: CC = $(CLANG) +o/$(MODE)/%-clang.asm: %.F; @ACTION=COMPILE.F build/compile $(COMPILE.F) $(OUTPUT_OPTION) $< || echo / need $(CLANG) >$@ + +# ragel state machine compiler +.PRECIOUS: build/bootstrap/%.c.gz +o/$(MODE)/%.c: %.rl build/bootstrap/%.c.gz + @mkdir -p $(dir $@) + @$(GZ) $(ZFLAGS) -dc $(<:%.rl=build/bootstrap/%.c.gz) >$@ + -@ACTION=RAGEL build/do $(RAGEL) $(RAGELFLAGS) $(OUTPUT_OPTION) $< +build/bootstrap/%.c.gz: %.rl + @mkdir -p $(dir $@) + @$(RAGEL) -o $(@:%.gz=%) $< + @$(GZ) $(ZFLAGS) -f $(@:%.gz=%) +%.svgz: %.rl + @$(RAGEL) -V -p $< | $(DOT) -Tsvg | $(GZ) $(ZFLAGS) >$@ + + $(LIBC__A_SRCS:%=o/$(MODE)/%.zip.o) \ diff --git a/build/runcom b/build/runcom new file mode 100755 index 00000000..71ea44ff --- /dev/null +++ b/build/runcom @@ -0,0 +1,9 @@ +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ + +DD=${DD:-$(command -v dd)} || exit +$DD if="$1" of="$1.bak" bs=4096 count=1 conv=notrunc 2>/dev/null +"$@" +rc=$? +$DD if="$1.bak" of="$1" bs=4096 count=1 conv=notrunc 2>/dev/null +exit $rc diff --git a/build/ssh b/build/ssh new file mode 100755 index 00000000..17a09fb6 --- /dev/null +++ b/build/ssh @@ -0,0 +1,13 @@ +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ +# +# OVERVIEW +# +# SSH Command Wrapper +# +# DESCRIPTION +# +# This script, like most of our wrappers, asks the tooling to whine +# less often. + +exec ${SSH:-ssh} -o LogLevel=QUIET "$@" diff --git a/build/zipobj b/build/zipobj new file mode 100755 index 00000000..54f9b200 --- /dev/null +++ b/build/zipobj @@ -0,0 +1,54 @@ +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ + +MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit +CP=${CP:-$(command -v cp) -f} || exit +SED=${SED:-$(command -v sed)} || exit + +MODE= + +OUT= +FIRST=1 +OUTARG=0 +for x; do + if [ $FIRST -eq 1 ]; then + set -- + FIRST=0 + elif [ $OUTARG -eq 1 ]; then + OUTARG=0 + OUT="$x" + fi + case "$x" in + -o) + OUTARG=1 + ;; + esac + set -- "$@" "$x" +done +OUTDIR="${OUT%/*}" +if [ "$OUTDIR" != "$OUT" ] && [ ! -d "$OUTDIR" ]; then + $MKDIR "$OUTDIR" || exit 2 +fi + +if [ -x "o/$MODE/tool/build/zipobj.com.dbg" ]; then + set -- "o/$MODE/tool/build/zipobj.com.dbg" "$@" +else + if [ ! -x o/build/bootstrap/zipobj.com ]; then + $MKDIR o/build/bootstrap && + $CP -a build/bootstrap/zipobj.com \ + o/build/bootstrap/zipobj.com || exit + fi + set -- o/build/bootstrap/zipobj.com "$@" +fi + +if [ "$SILENT" = "0" ]; then + COLUMNS=${COLUMNS:-80} + COLUMNS=$((COLUMNS - 4)) + printf "%s\n" "$*" | + /usr/bin/fold -s -w $COLUMNS | + $SED -e '1bb' -e 's/^/ /' -e ':b' -e '$b' -e 's/$/ \\/' >&2 +else + printf "$LOGFMT" "${ACTION:-ZIPOBJ}" "$3" >&2 +fi + +exec "$@" diff --git a/dsp/bmp/bmp.mk b/dsp/bmp/bmp.mk new file mode 100644 index 00000000..600bca60 --- /dev/null +++ b/dsp/bmp/bmp.mk @@ -0,0 +1,60 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += DSP_BMP + +DSP_BMP_ARTIFACTS += DSP_BMP_A +DSP_BMP = $(DSP_BMP_A_DEPS) $(DSP_BMP_A) +DSP_BMP_A = o/$(MODE)/dsp/bmp/bmp.a +DSP_BMP_A_FILES := $(wildcard dsp/bmp/*) +DSP_BMP_A_HDRS = $(filter %.h,$(DSP_BMP_A_FILES)) +DSP_BMP_A_SRCS_S = $(filter %.S,$(DSP_BMP_A_FILES)) +DSP_BMP_A_SRCS_C = $(filter %.c,$(DSP_BMP_A_FILES)) + +DSP_BMP_A_SRCS = \ + $(DSP_BMP_A_SRCS_S) \ + $(DSP_BMP_A_SRCS_C) + +DSP_BMP_A_OBJS = \ + $(DSP_BMP_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(DSP_BMP_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(DSP_BMP_A_SRCS_C:%.c=o/$(MODE)/%.o) + +DSP_BMP_A_CHECKS = \ + $(DSP_BMP_A).pkg \ + $(DSP_BMP_A_HDRS:%=o/$(MODE)/%.ok) + +DSP_BMP_A_DIRECTDEPS = \ + LIBC_NEXGEN32E \ + LIBC_TINYMATH \ + LIBC_STUBS + +DSP_BMP_A_DEPS := \ + $(call uniq,$(foreach x,$(DSP_BMP_A_DIRECTDEPS),$($(x)))) + +$(DSP_BMP_A): dsp/bmp/ \ + $(DSP_BMP_A).pkg \ + $(DSP_BMP_A_OBJS) + +$(DSP_BMP_A).pkg: \ + $(DSP_BMP_A_OBJS) \ + $(foreach x,$(DSP_BMP_A_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/dsp/bmp/float2short.o \ +o/$(MODE)/dsp/bmp/scalevolume.o: \ + OVERRIDE_CFLAGS += \ + $(MATHEMATICAL) + +o/tiny/dsp/bmp/scalevolume.o: \ + OVERRIDE_CFLAGS += \ + -Os + +DSP_BMP_LIBS = $(foreach x,$(DSP_BMP_ARTIFACTS),$($(x))) +DSP_BMP_SRCS = $(foreach x,$(DSP_BMP_ARTIFACTS),$($(x)_SRCS)) +DSP_BMP_HDRS = $(foreach x,$(DSP_BMP_ARTIFACTS),$($(x)_HDRS)) +DSP_BMP_CHECKS = $(foreach x,$(DSP_BMP_ARTIFACTS),$($(x)_CHECKS)) +DSP_BMP_OBJS = $(foreach x,$(DSP_BMP_ARTIFACTS),$($(x)_OBJS)) +$(DSP_BMP_OBJS): $(BUILD_FILES) dsp/bmp/bmp.mk + +.PHONY: o/$(MODE)/dsp/bmp +o/$(MODE)/dsp/bmp: $(DSP_BMP_CHECKS) diff --git a/dsp/core/byte2double.c b/dsp/core/byte2double.c new file mode 100644 index 00000000..7be44e0f --- /dev/null +++ b/dsp/core/byte2double.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "libc/mem/mem.h" + +void *byte2double(long n, const void *p, double weight, double bias) { + long i; + double f, *dst; + unsigned char *src; + if ((dst = valloc(n * sizeof(double)))) { + for (src = p, i = 0; i < n; ++i) { + f = src[i]; + f -= bias; + f *= 1 / weight; + dst[i] = f; + } + } + return dst; +} diff --git a/dsp/core/c11.h b/dsp/core/c11.h new file mode 100644 index 00000000..ee83867f --- /dev/null +++ b/dsp/core/c11.h @@ -0,0 +1,22 @@ +#ifndef COSMOPOLITAN_DSP_CORE_C11_H_ +#define COSMOPOLITAN_DSP_CORE_C11_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * Fixed-point 8-bit rounded mean kernel. + * + * @define (a + b) / 2 + */ +static inline pureconst artificial unsigned char C11(unsigned char al, + unsigned char bl) { + short ax; + ax = al; + ax += bl; + ax += 1; + ax /= 2; + al = ax; + return al; +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_CORE_C11_H_ */ diff --git a/dsp/core/c121.h b/dsp/core/c121.h new file mode 100644 index 00000000..71ef3cd4 --- /dev/null +++ b/dsp/core/c121.h @@ -0,0 +1,21 @@ +#ifndef COSMOPOLITAN_DSP_CORE_C121_H_ +#define COSMOPOLITAN_DSP_CORE_C121_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +forceinline pureconst artificial unsigned char C121(unsigned char al, + unsigned char bl, + unsigned char cl) { + unsigned short ax, bx; + ax = al; + ax += bl; + ax += bl; + ax += cl; + ax += 2; + ax >>= 2; + return ax; +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_CORE_C121_H_ */ diff --git a/dsp/core/c121s.h b/dsp/core/c121s.h new file mode 100644 index 00000000..d7f036e6 --- /dev/null +++ b/dsp/core/c121s.h @@ -0,0 +1,19 @@ +#ifndef COSMOPOLITAN_DSP_CORE_C121S_H_ +#define COSMOPOLITAN_DSP_CORE_C121S_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +forceinline pureconst artificial signed char C121S(signed char al, + signed char bl, + signed char cl) { + short ax, bx; + ax = al; + ax += bl; + ax += bl; + ax += cl; + ax += 2; + ax >>= 2; + return ax; +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_CORE_C121S_H_ */ diff --git a/dsp/core/c1331.h b/dsp/core/c1331.h new file mode 100644 index 00000000..f1f8d115 --- /dev/null +++ b/dsp/core/c1331.h @@ -0,0 +1,30 @@ +#ifndef COSMOPOLITAN_DSP_CORE_C1331_H_ +#define COSMOPOLITAN_DSP_CORE_C1331_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * Byte sized kernel for resampling memory in half. + * + * @define (1*𝑎 + 3*𝑏 + 3*𝑐 + 1*𝑑) / (1 + 3 + 3 + 1) + * @see C161() afterward for superior sin(𝑥)/𝑥 + * @limit [0,255] → [0..2,044] → [0..255] + */ +forceinline pureconst artificial unsigned char C1331(unsigned char al, + unsigned char bl, + unsigned char cl, + unsigned char dl) { + short ax, bx; + bx = bl; + bx += cl; + bx *= 3; + ax = al; + ax += dl; + ax += bx; + ax += 4; + ax >>= 3; + al = ax; + return al; +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_CORE_C1331_H_ */ diff --git a/dsp/core/c1331s.h b/dsp/core/c1331s.h new file mode 100644 index 00000000..ef5a37f1 --- /dev/null +++ b/dsp/core/c1331s.h @@ -0,0 +1,28 @@ +#ifndef COSMOPOLITAN_DSP_CORE_C1331S_H_ +#define COSMOPOLITAN_DSP_CORE_C1331S_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * Byte sized kernel for resampling difference samples in half. + * + * @define (1*(a-128)+3*(a-128)+3*(a-128)+1*(a-128))/(1+3+3+1)+128 + * @see C1331(), Y420CbCr2RgbScale() + */ +forceinline pureconst artificial signed char C1331S(signed char al, + signed char bl, + signed char cl, + signed char dl) { + short ax, bx; + bx = bl; + bx += cl; + bx *= 3; + ax = al; + ax += dl; + ax += bx; + ax += 4; + ax >>= 3; + return ax; +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_CORE_C1331S_H_ */ diff --git a/dsp/core/c161.h b/dsp/core/c161.h new file mode 100644 index 00000000..b6ea6097 --- /dev/null +++ b/dsp/core/c161.h @@ -0,0 +1,33 @@ +#ifndef COSMOPOLITAN_DSP_CORE_C161_H_ +#define COSMOPOLITAN_DSP_CORE_C161_H_ +#include "libc/macros.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define EXTRA_SHARP 2 + +/** + * Byte sized kernel for restoring sharpness of resampled memory. + * + * @define CLAMP[(-1*𝑎 + 6*𝑏 + -1*𝑐) / (-1 + 6 + -1)] + * @limit [0..255] → [-510..1,532] → [-127..383] → [0..255] + * @see C1331() + */ +forceinline pureconst artificial unsigned char C161(unsigned char al, + unsigned char bl, + unsigned char cl) { + short ax, bx, cx; + ax = al; + bx = bl; + cx = cl; + ax *= -1; + bx *= +6; + cx *= -1; + ax += bx; + ax += cx; + ax += 2; + ax >>= 2; + return MIN(255, MAX(0, ax)); +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_CORE_C161_H_ */ diff --git a/dsp/core/c161s.h b/dsp/core/c161s.h new file mode 100644 index 00000000..201b4544 --- /dev/null +++ b/dsp/core/c161s.h @@ -0,0 +1,26 @@ +#ifndef COSMOPOLITAN_DSP_CORE_C161S_H_ +#define COSMOPOLITAN_DSP_CORE_C161S_H_ +#include "dsp/core/c161.h" +#include "libc/macros.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +forceinline pureconst artificial signed char C161S(signed char al, + signed char bl, + signed char cl) { + short ax, bx, cx; + ax = al; + bx = bl; + cx = cl; + ax *= -1 * EXTRA_SHARP; + bx *= 6 * EXTRA_SHARP; + cx *= -1 * EXTRA_SHARP; + ax += bx; + ax += cx; + ax += 2 * EXTRA_SHARP; + ax /= 4 * EXTRA_SHARP; + al = MIN(112, MAX(-112, ax)); + return al; +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_CORE_C161S_H_ */ diff --git a/dsp/core/c331.h b/dsp/core/c331.h new file mode 100644 index 00000000..5b537d21 --- /dev/null +++ b/dsp/core/c331.h @@ -0,0 +1,30 @@ +#ifndef COSMOPOLITAN_DSP_CORE_C331_H_ +#define COSMOPOLITAN_DSP_CORE_C331_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * Fixed-point 8-bit magic edge resampling kernel. + * + * @define (3*a + 3*b + 1*c) / 7 + * @see C1331() + */ +static inline pureconst artificial unsigned char C331(unsigned char al, + unsigned char bl, + unsigned char cl) { + unsigned eax, ebx, ecx; + eax = al; + ebx = bl; + ecx = cl; + eax += ebx; + eax *= 3 * 2350; + ecx *= 1 * 2350; + eax += ecx; + eax >>= 14; + al = eax; + return al; +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_CORE_C331_H_ */ diff --git a/dsp/core/core.h b/dsp/core/core.h new file mode 100644 index 00000000..5c43547e --- /dev/null +++ b/dsp/core/core.h @@ -0,0 +1,37 @@ +#ifndef COSMOPOLITAN_DSP_CORE_CORE_H_ +#define COSMOPOLITAN_DSP_CORE_CORE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * @fileoverview Cosmopolitan Digital Signal Processing. + */ + +int mulaw(int); +void *double2byte(long, const void *, double, double) vallocesque; +void *byte2double(long, const void *, double, double) vallocesque; + +void *dct(float[8][8], float, float, float, float, float); +void *dctjpeg(float[8][8]); + +double det3(const double[3][3]) nosideeffect; +void *inv3(double[restrict 3][3], const double[restrict 3][3], double); +void *matmul3(double[restrict 3][3], const double[3][3], const double[3][3]); +void *vmatmul3(double[restrict 3], const double[3], const double[3][3]); +void *matvmul3(double[restrict 3], const double[3][3], const double[3]); + +double rgb2stdtv(double) pureconst; +double rgb2lintv(double) pureconst; +double rgb2stdpc(double, double) pureconst; +double rgb2linpc(double, double) pureconst; +double tv2pcgamma(double, double) pureconst; + +#ifndef __cplusplus +void sad16x8n(size_t n, short[n][8], const short[n][8]); +void float2short(size_t n, short[n][8], const float[n][8]); +void scalevolume(size_t n, int16_t[n][8], int); +#endif + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_CORE_CORE_H_ */ diff --git a/dsp/core/core.mk b/dsp/core/core.mk new file mode 100644 index 00000000..10872e75 --- /dev/null +++ b/dsp/core/core.mk @@ -0,0 +1,69 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += DSP_CORE + +DSP_CORE_ARTIFACTS += DSP_CORE_A +DSP_CORE = $(DSP_CORE_A_DEPS) $(DSP_CORE_A) +DSP_CORE_A = o/$(MODE)/dsp/core/core.a +DSP_CORE_A_FILES := $(wildcard dsp/core/*) +DSP_CORE_A_HDRS = $(filter %.h,$(DSP_CORE_A_FILES)) +DSP_CORE_A_SRCS_S = $(filter %.S,$(DSP_CORE_A_FILES)) +DSP_CORE_A_SRCS_C = $(filter %.c,$(DSP_CORE_A_FILES)) + +DSP_CORE_A_SRCS = \ + $(DSP_CORE_A_SRCS_S) \ + $(DSP_CORE_A_SRCS_C) + +DSP_CORE_A_OBJS = \ + $(DSP_CORE_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(DSP_CORE_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(DSP_CORE_A_SRCS_C:%.c=o/$(MODE)/%.o) + +DSP_CORE_A_CHECKS = \ + $(DSP_CORE_A).pkg \ + $(DSP_CORE_A_HDRS:%=o/$(MODE)/%.ok) + +DSP_CORE_A_DIRECTDEPS = \ + LIBC_NEXGEN32E \ + LIBC_MEM \ + LIBC_TINYMATH \ + LIBC_STUBS + +DSP_CORE_A_DEPS := \ + $(call uniq,$(foreach x,$(DSP_CORE_A_DIRECTDEPS),$($(x)))) + +$(DSP_CORE_A): dsp/core/ \ + $(DSP_CORE_A).pkg \ + $(DSP_CORE_A_OBJS) + +$(DSP_CORE_A).pkg: \ + $(DSP_CORE_A_OBJS) \ + $(foreach x,$(DSP_CORE_A_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/dsp/core/dct.o \ +o/$(MODE)/dsp/core/c1331.o \ +o/$(MODE)/dsp/core/magikarp.o \ +o/$(MODE)/dsp/core/c93654369.o \ +o/$(MODE)/dsp/core/float2short.o \ +o/$(MODE)/dsp/core/scalevolume.o: \ + OVERRIDE_CFLAGS += \ + $(MATHEMATICAL) + +o/tiny/dsp/core/scalevolume.o: \ + OVERRIDE_CFLAGS += \ + -Os + +o/$(MODE)/dsp/core/det3.o: \ + OVERRIDE_CFLAGS += \ + -ffast-math + +DSP_CORE_LIBS = $(foreach x,$(DSP_CORE_ARTIFACTS),$($(x))) +DSP_CORE_SRCS = $(foreach x,$(DSP_CORE_ARTIFACTS),$($(x)_SRCS)) +DSP_CORE_HDRS = $(foreach x,$(DSP_CORE_ARTIFACTS),$($(x)_HDRS)) +DSP_CORE_CHECKS = $(foreach x,$(DSP_CORE_ARTIFACTS),$($(x)_CHECKS)) +DSP_CORE_OBJS = $(foreach x,$(DSP_CORE_ARTIFACTS),$($(x)_OBJS)) +$(DSP_CORE_OBJS): $(BUILD_FILES) dsp/core/core.mk + +.PHONY: o/$(MODE)/dsp/core +o/$(MODE)/dsp/core: $(DSP_CORE_CHECKS) diff --git a/dsp/core/dct.c b/dsp/core/dct.c new file mode 100644 index 00000000..43231757 --- /dev/null +++ b/dsp/core/dct.c @@ -0,0 +1,85 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" + +#define DCT(A, B, C, D, E, F, G, H, T, C0, C1, C2, C3, C4) \ + do { \ + T z1, z2, z3, z4, z5, z11, z13; \ + T t0, t1, t2, t3, t4, t5, t6, t7, t8, t10, t11, t12, t13; \ + t0 = A + H; \ + t7 = A - H; \ + t1 = B + G; \ + t6 = B - G; \ + t2 = C + F; \ + t5 = C - F; \ + t3 = D + E; \ + t4 = D - E; \ + t10 = t0 + t3; \ + t13 = t0 - t3; \ + t11 = t1 + t2; \ + t12 = t1 - t2; \ + A = t10 + t11; \ + E = t10 - t11; \ + z1 = (t12 + t13) * C0; \ + C = t13 + z1; \ + G = t13 - z1; \ + t10 = t4 + t5; \ + t11 = t5 + t6; \ + t12 = t6 + t7; \ + z5 = (t10 - t12) * C1; \ + z2 = t10 * C2 + z5; \ + z4 = t12 * C3 + z5; \ + z3 = t11 * C4; \ + z11 = t7 + z3; \ + z13 = t7 - z3; \ + F = z13 + z2; \ + D = z13 - z2; \ + B = z11 + z4; \ + H = z11 - z4; \ + } while (0) + +/** + * Performs float forward discrete cosine transform. + * + * This takes a tiny block of image data and shoves the information it + * represents into the top left corner. It can be reversed using idct(). + * It matters because iterating the result in a serpentine pattern makes + * run-length delta encoding super effective. Furthermore, data downward + * rightly may be divided away for lossy compression. + * + * @cost ~100ns + */ +void *dct(float M[8][8], float c0, float c1, float c2, float c3, float c4) { + unsigned y, x; + for (y = 0; y < 8; ++y) { + DCT(M[y][0], M[y][1], M[y][2], M[y][3], M[y][4], M[y][5], M[y][6], M[y][7], + float, c0, c1, c2, c3, c4); + } + for (x = 0; x < 8; ++x) { + DCT(M[0][x], M[1][x], M[2][x], M[3][x], M[4][x], M[5][x], M[6][x], M[7][x], + float, c0, c1, c2, c3, c4); + } + return M; +} + +void *dctjpeg(float M[8][8]) { + return dct(M, .707106781f, .382683433f, .541196100f, 1.306562965f, + .707106781f); +} diff --git a/dsp/core/det3.c b/dsp/core/det3.c new file mode 100644 index 00000000..5db5b159 --- /dev/null +++ b/dsp/core/det3.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" + +#define LEIBNIZ_FORMULA(a, b, c, d, e, f, g, h, i) \ + (a * e * i + b * f * g + c * d * h - c * e * g - b * d * i - a * f * h) + +/** + * Computes determinant of 3×3 matrix. + * i.e. how much space is inside the cube + * + * @param 𝐀 is input matrix + * @param 𝑑 is det(𝐀) + * @return |𝐀| or 0 if degenerate + */ +double det3(const double A[3][3]) { + return LEIBNIZ_FORMULA(A[0][0], A[0][1], A[0][2], A[1][0], A[1][1], A[1][2], + A[2][0], A[2][1], A[2][2]); +} diff --git a/dsp/core/differsumsq.c b/dsp/core/differsumsq.c new file mode 100644 index 00000000..bac10d57 --- /dev/null +++ b/dsp/core/differsumsq.c @@ -0,0 +1,67 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" + +/** + * Computes Σ𝑥ᵢΣ𝑥ⱼΣ𝑥ₖΣ𝑥ₗΣ𝑥ₘΣ𝑥ₙ(δ₁𝑥ᵢ+δ₂𝑥ⱼ+δ₃𝑥ₖ+δ₄𝑥ₗ+δ₅𝑥ₘ+δ₆𝑥ₙ)² over 𝐿..𝐻 + * + * “As soon as an Analytical Engine exists, it will necessarily + * guide the future course of the science. Whenever any result + * is sought by its aid, the question will then arise — by what + * course of calculation can these results be arrived at by the + * machine in the shortest time? + * + * — Charles Babbage (Life of a Philosopher, 1864) + * + * @see itu.int/rec/R-REC-BT.601/ + */ +double DifferSumSq(const double D[static 6], double L, double H) { + double T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T2, T20, T21, T22, + T23, T24, T25, T26, T27, T3, T4, T5, T6, T7, T8, T9; + T2 = H * H, T3 = (H * H * H), T4 = (H * H * H * H), T5 = (H * H * H * H * H), + T6 = (H * H * H * H * H * H), T7 = -10 * H, T8 = (H * H * H * H * H * H * H), + T9 = (L * L * L * L * L * L * L * L), T10 = (L * L * L * L * L * L * L), + T11 = (L * L * L * L * L * L), T12 = (L * L * L * L * L), T13 = -45 * T2, + T14 = (L * L * L * L), T15 = 180 * T3, T16 = 120 * T2, T17 = (L * L * L), + T18 = L * L, T19 = 18 * T2, T20 = (H * H * H * H * H * H * H * H); + T21 = 45 * T4; + T22 = 3 * T9 + (-12 * H - 18) * T10 + (12 * T2 + 54 * H + 45) * T11 + + (12 * T3 - T19 - 90 * H - 60) * T12 + + (-30 * T4 - 90 * T3 + T13 + 60 * H + 45) * T14 + + (12 * T5 + 90 * T4 + T15 + T16 - 18) * T17 + + (12 * T6 + 18 * T5 - T21 - 120 * T3 - 90 * T2 - 18 * H + 3) * T18 + + (-12 * T8 - 54 * T6 - 90 * T5 - 60 * T4 + T19 + 6 * H) * L + 3 * T20 + + 18 * T8 + 45 * T6 + 60 * T5 + T21 + 18 * T3 + 3 * T2; + T23 = + 2 * T9 + (T7 - 13) * T10 + (20 * T2 + 55 * H + 36) * T11 + + (-22 * T3 - 93 * T2 - 126 * H - 55) * T12 + + (20 * T4 + 95 * T3 + 180 * T2 + 155 * H + 50) * T14 + + (-22 * T5 - 95 * T4 - T15 - 190 * T2 - 110 * H - 27) * T17 + + (20 * T6 + 93 * T5 + 180 * T4 + 190 * T3 + T16 + 45 * H + 8) * T18 + + (-10 * T8 - 55 * T6 - 126 * T5 - 155 * T4 - 110 * T3 + T13 + T7 - 1) * L + + 2 * T20 + 13 * T8 + 36 * T6 + 55 * T5 + 50 * T4 + 27 * T3 + 8 * T2 + H; + T24 = T22 * D[3], T25 = T22 * D[2], T26 = T22 * D[1], T27 = T22 * D[0]; + return (T23 * D[5] * D[5] + (T22 * D[4] + T24 + T25 + T26 + T27) * D[5] + + T23 * D[4] * D[4] + (T24 + T25 + T26 + T27) * D[4] + + T23 * D[3] * D[3] + (T25 + T26 + T27) * D[3] + T23 * D[2] * D[2] + + (T26 + T27) * D[2] + T23 * D[1] * D[1] + T22 * D[0] * D[1] + + T23 * D[0] * D[0]) / + 6; +} diff --git a/dsp/core/differsumsq8.c b/dsp/core/differsumsq8.c new file mode 100644 index 00000000..92fb8c6e --- /dev/null +++ b/dsp/core/differsumsq8.c @@ -0,0 +1,463 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "dsp/core/q.h" + +/** + * Computes Σ𝑥ᵢΣ𝑥ⱼΣ𝑥ₖΣ𝑥ₗΣ𝑥ₘΣ𝑥ₙΣ𝑥ₚΣ𝑥ₛ(δ₁𝑥ᵢ+δ₂𝑥ⱼ+δ₃𝑥ₖ+δ₄𝑥ₗ+δ₅𝑥ₘ+δ₆𝑥ₙ+δₚ𝑥ₚ+δₛ𝑥ₛ)² + * + * “As soon as an Analytical Engine exists, it will necessarily + * guide the future course of the science. Whenever any result + * is sought by its aid, the question will then arise — by what + * course of calculation can these results be arrived at by the + * machine in the shortest time? + * + * — Charles Babbage (Life of a Philosopher, 1864) + * + */ +double DifferSumSq8(const double D[static 8], double L, double H) { + double T10, T100, T101, T102, T103, T104, T105, T106, T107, T108, T109, T11; + double T110, T111, T112, T113, T114, T115, T116, T117, T118, T119, T12, T120; + double T121, T122, T123, T124, T125, T126, T127, T128, T129, T13, T130, T131; + double T132, T133, T134, T135, T136, T137, T138, T139, T14, T140, T141, T142; + double T143, T144, T145, T146, T147, T148, T149, T15, T150, T151, T152, T153; + double T154, T155, T156, T157, T158, T159, T16, T160, T161, T162, T163, T164; + double T165, T166, T167, T168, T169, T17, T170, T171, T172, T173, T174, T175; + double T176, T177, T178, T179, T18, T180, T181, T182, T183, T184, T185, T186; + double T187, T188, T189, T19, T190, T191, T192, T193, T194, T195, T196, T197; + double T198, T199, T2, T20, T200, T201, T202, T203, T204, T205, T206, T207; + double T208, T209, T21, T210, T211, T212, T213, T214, T215, T216, T217, T218; + double T219, T22, T220, T221, T222, T223, T224, T225, T226, T227, T228, T229; + double T230, T231, T232, T233, T234, T235, T236, T237, T238, T239, T24, T240; + double T241, T242, T243, T244, T245, T246, T247, T248, T249, T25, T250, T251; + double T252, T253, T254, T255, T256, T257, T258, T259, T26, T260, T261, T262; + double T263, T264, T265, T266, T267, T268, T269, T27, T270, T271, T272, T273; + double T274, T275, T276, T277, T278, T279, T28, T280, T281, T282, T283, T284; + double T285, T286, T287, T288, T289, T29, T290, T291, T292, T293, T294, T295; + double T296, T297, T298, T299, T3, T30, T300, T301, T302, T303, T304, T305; + double T307, T308, T309, T31, T310, T311, T312, T313, T314, T315, T316, T317; + double T318, T319, T32, T320, T321, T322, T323, T324, T325, T326, T327, T328; + double T329, T33, T330, T331, T332, T333, T334, T335, T336, T337, T338, T339; + double T34, T340, T341, T342, T343, T344, T345, T346, T347, T348, T349, T35; + double T350, T351, T352, T353, T354, T355, T356, T357, T358, T359, T36, T360; + double T361, T362, T363, T364, T365, T366, T367, T368, T369, T37, T370, T371; + double T372, T373, T374, T375, T376, T377, T378, T379, T38, T380, T381, T382; + double T383, T384, T385, T386, T387, T388, T389, T39, T390, T391, T392, T393; + double T394, T395, T396, T397, T398, T399, T4, T40, T400, T401, T402, T403; + double T405, T406, T407, T41, T42, T43, T44, T45, T46, T47, T48, T49, T5, T50; + double T51, T52, T53, T54, T55, T56, T57, T58, T59, T6, T60, T61, T62, T63; + double T65, T66, T67, T68, T69, T7, T70, T71, T72, T73, T74, T75, T76, T77; + double T79, T8, T80, T81, T82, T83, T84, T85, T86, T87, T88, T89, T9, T90; + double T92, T93, T94, T95, T96, T97, T98, T99, T23, T306, T91, T78, T64, T404; + T2 = 4 * D[5], T3 = 3 * D[4], T4 = 3 * D[3], T5 = 3 * D[2], T6 = 3 * D[1], + T7 = 3 * D[0], T8 = D[7] * D[7], T9 = D[6] * D[6], T10 = -28 * D[5], + T11 = -18 * D[4], T12 = -18 * D[3], T13 = -18 * D[2], T14 = -18 * D[1], + T15 = -18 * D[0], T16 = D[5] * D[5], T17 = D[4] * D[4], T18 = D[3] * D[3], + T19 = D[2] * D[2], T20 = D[1] * D[1], T21 = D[0] * D[0], T22 = -34 * D[5], + T23 = -24 * D[4], T24 = -24 * D[3], T25 = -24 * D[2], T26 = -24 * D[1], + T27 = -24 * D[0], T28 = 84 * D[5], T29 = 39 * D[4], T30 = 39 * D[3], + T31 = 39 * D[2], T32 = 39 * D[1], T33 = 39 * D[0], T34 = 210 * D[5], + T35 = 120 * D[4], T36 = 120 * D[3], T37 = 120 * D[2], T38 = 120 * D[1], + T39 = 120 * D[0], T40 = 128 * D[5], T41 = 84 * D[4], T42 = 84 * D[3], + T43 = 84 * D[2], T44 = 84 * D[1], T45 = 84 * D[0]; + T46 = -144 * D[5], T47 = (T23 + T24 + T25 + T26 + T27) * D[5], + T48 = (T24 + T25 + T26 + T27) * D[4], T49 = (T25 + T26 + T27) * D[3], + T50 = (T26 + T27) * D[2], T51 = -24 * D[0] * D[1], T52 = -552 * D[5], + T53 = -192 * D[4], T54 = -192 * D[3], T55 = -192 * D[2], T56 = -192 * D[1], + T57 = -192 * D[0], T58 = H * H, T59 = -688 * D[5], T60 = -336 * D[4], + T61 = -336 * D[3], T62 = -336 * D[2], T63 = -336 * D[1], T64 = -336 * D[0], + T65 = -280 * D[5], T66 = -168 * D[4], T67 = -168 * D[3], T68 = -168 * D[2], + T69 = -168 * D[1], T70 = -168 * D[0], T71 = 168 * D[5], T72 = -42 * D[4], + T73 = -42 * D[3], T74 = -42 * D[2], T75 = -42 * D[1], T76 = -42 * D[0], + T77 = (H * H * H), T78 = 336 * D[4], T79 = 336 * D[3], T80 = 336 * D[2], + T81 = 336 * D[1], T82 = 336 * D[0], T83 = 1568 * D[5], + T84 = 336 * D[0] * D[1], T85 = 1288 * D[5], T86 = 504 * D[4], + T87 = 504 * D[3], T88 = 504 * D[2], T89 = 504 * D[1], T90 = 504 * D[0], + T91 = 392 * D[5], T92 = 210 * D[4], T93 = 210 * D[3], T94 = 210 * D[2], + T95 = 210 * D[1], T96 = 210 * D[0], T97 = 84 * T8, T98 = 168 * D[6], + T99 = 84 * T9, T100 = 84 * T16, T101 = (T41 + T42 + T43 + T44 + T45) * D[5], + T102 = 84 * T17, T103 = (T42 + T43 + T44 + T45) * D[4], T104 = 84 * T18, + T105 = (T43 + T44 + T45) * D[3], T106 = 84 * T19, T107 = (T44 + T45) * D[2], + T108 = 84 * T20, T109 = 84 * D[0] * D[1], T110 = 84 * T21, T111 = -924 * D[5], + T112 = (T78 + T79 + T80 + T81 + T82) * D[5], + T113 = (T79 + T80 + T81 + T82) * D[4], T114 = (T80 + T81 + T82) * D[3], + T115 = (T81 + T82) * D[2], T116 = (H * H * H * H), T117 = -2128 * D[5], + T118 = -2520 * D[5], T119 = (T66 + T67 + T68 + T69 + T70) * D[5], + T120 = (T67 + T68 + T69 + T70) * D[4], T121 = (T68 + T69 + T70) * D[3], + T122 = (T69 + T70) * D[2], T123 = -168 * D[0] * D[1], T124 = -1512 * D[5], + T125 = -420 * D[4], T126 = -420 * D[3], T127 = -420 * D[2], + T128 = -420 * D[1], T129 = -420 * D[0], T130 = -364 * D[5]; + T131 = T97 + (T98 + T71 + T72 + T73 + T74 + T75 + T76) * D[7] + T99 + + (T71 + T72 + T73 + T74 + T75 + T76) * D[6] + T100 + + (T72 + T73 + T74 + T75 + T76) * D[5] + T102 + + (T73 + T74 + T75 + T76) * D[4] + T104 + (T74 + T75 + T76) * D[3] + + T106 + (T75 + T76) * D[2] + T108 - 42 * D[0] * D[1] + T110; + T132 = 462 * T8, T133 = 924 * D[6], T134 = 924 * D[5], T135 = 462 * T9, + T136 = 462 * T16, T137 = (T60 + T61 + T62 + T63 + T64) * D[5], + T138 = 462 * T17, T139 = (T61 + T62 + T63 + T64) * D[4], T140 = 462 * T18, + T141 = (T62 + T63 + T64) * D[3], T142 = 462 * T19, T143 = (T63 + T64) * D[2], + T144 = 462 * T20, T145 = 462 * T21, T146 = (H * H * H * H * H), + T147 = 2240 * D[5], T148 = -840 * D[4], T149 = -840 * D[3], + T150 = -840 * D[2], T151 = -840 * D[1], T152 = -840 * D[0], + T153 = 3080 * D[5], T154 = (T148 + T149 + T150 + T151 + T152) * D[5], + T155 = (T149 + T150 + T151 + T152) * D[4], T156 = (T150 + T151 + T152) * D[3], + T157 = (T151 + T152) * D[2], T158 = -840 * D[0] * D[1], T159 = 1260 * T8, + T160 = 2520 * D[6], T161 = 2520 * D[5], T162 = 1260 * T9, T163 = 1260 * T16, + T164 = 1260 * T17, T165 = 1260 * T18, T166 = 1260 * T19, T167 = 1260 * T20, + T168 = 210 * D[0] * D[1], T169 = 1260 * T21, T170 = 168 * D[4], + T171 = 168 * D[3], T172 = 168 * D[2], T173 = 168 * D[1], T174 = 168 * D[0], + T175 = 1148 * D[5], T176 = 168 * D[0] * D[1], T177 = 224 * D[5]; + T178 = -72 * T8 + (-144 * D[6] + T46 + T23 + T24 + T25 + T26 + T27) * D[7] - + 72 * T9 + (T46 + T23 + T24 + T25 + T26 + T27) * D[6] - 72 * T16 + T47 - + 72 * T17 + T48 - 72 * T18 + T49 - 72 * T19 + T50 - 72 * T20 + T51 - + 72 * T21; + T179 = 420 * T8, T180 = 840 * D[6], T181 = 840 * D[5], T182 = 420 * T9, + T183 = 840 * D[5] * D[6], T184 = 420 * T16, T185 = 420 * T17, + T186 = 420 * T18, T187 = 420 * T19, T188 = 420 * T20, T189 = 420 * T21, + T190 = (H * H * H * H * H * H); + T191 = -1064 * T8 + + (-2128 * D[6] + T117 + T78 + T79 + T80 + T81 + T82) * D[7] - + 1064 * T9 + (T117 + T78 + T79 + T80 + T81 + T82) * D[6] - 1064 * T16 + + T112 - 1064 * T17 + T113 - 1064 * T18 + T114 - 1064 * T19 + T115 - + 1064 * T20 + T84 - 1064 * T21; + T192 = 1540 * T8, T193 = 3080 * D[6], T194 = 840 * D[4], T195 = 840 * D[3], + T196 = 840 * D[2], T197 = 840 * D[1], T198 = 840 * D[0], T199 = 1540 * T9, + T200 = 1540 * T16, T201 = 1540 * T17, T202 = 1540 * T18, T203 = 1540 * T19, + T204 = 1540 * T20, T205 = 840 * D[0] * D[1], T206 = 1540 * T21, + T207 = -2800 * D[5], T208 = (T194 + T195 + T196 + T197 + T198) * D[5], + T209 = (T195 + T196 + T197 + T198) * D[4], T210 = (T196 + T197 + T198) * D[3], + T211 = (T197 + T198) * D[2], T212 = -1624 * D[5], T213 = -88 * D[5]; + T214 = 42 * T8 + (84 * D[6] + T28 + T29 + T30 + T31 + T32 + T33) * D[7] + + 42 * T9 + (T28 + T29 + T30 + T31 + T32 + T33) * D[6] + 42 * T16 + + (T29 + T30 + T31 + T32 + T33) * D[5] + 42 * T17 + + (T30 + T31 + T32 + T33) * D[4] + 42 * T18 + (T31 + T32 + T33) * D[3] + + 42 * T19 + (T32 + T33) * D[2] + 42 * T20 + 39 * D[0] * D[1] + 42 * T21; + T215 = 276 * T8, T216 = 552 * D[6], T217 = 552 * D[5], T218 = 192 * D[4], + T219 = 192 * D[3], T220 = 192 * D[2], T221 = 192 * D[1], T222 = 192 * D[0], + T223 = 276 * T9, T224 = 276 * T16, T225 = 276 * T17, T226 = 276 * T18, + T227 = 276 * T19, T228 = 276 * T20, T229 = 192 * D[0] * D[1], + T230 = 276 * T21, T231 = (H * H * H * H * H * H * H); + T232 = 784 * T8 + (1568 * D[6] + T83 + T78 + T79 + T80 + T81 + T82) * D[7] + + 784 * T9 + (T83 + T78 + T79 + T80 + T81 + T82) * D[6] + 784 * T16 + + T112 + 784 * T17 + T113 + 784 * T18 + T114 + 784 * T19 + T115 + + 784 * T20 + T84 + 784 * T21; + T233 = (T170 + T171 + T172 + T173 + T174) * D[5]; + T234 = (T171 + T172 + T173 + T174) * D[4]; + T235 = (T172 + T173 + T174) * D[3]; + T236 = (T173 + T174) * D[2]; + T237 = T159 + (T160 + T161 - T92 - T93 - T94 - T95 - T96) * D[7] + T162 + + (T161 - T92 - T93 - T94 - T95 - T96) * D[6] + T163 + + (-T92 - T93 - T94 - T95 - T96) * D[5] + T164 + + (-T93 - T94 - T95 - T96) * D[4] + T165 + (-T94 - T95 - T96) * D[3] + + T166 + (-T95 - T96) * D[2] + T167 - T168 + T169; + T238 = 812 * T8, T239 = 1624 * D[6], T240 = 1624 * D[5], T241 = 812 * T9, + T242 = 812 * T16, T243 = 812 * T17, T244 = 812 * T18, T245 = 812 * T19, + T246 = 812 * T20, T247 = 812 * T21, T248 = 672 * D[5], T249 = 20 * D[5], + T250 = (T3 + T4 + T5 + T6 + T7) * D[5], T251 = (T4 + T5 + T6 + T7) * D[4], + T252 = (T5 + T6 + T7) * D[3], T253 = (T6 + T7) * D[2], T254 = 3 * D[0] * D[1]; + T255 = -14 * T8 + (-28 * D[6] + T10 + T11 + T12 + T13 + T14 + T15) * D[7] - + 14 * T9 + (T10 + T11 + T12 + T13 + T14 + T15) * D[6] - 14 * T16 + + (T11 + T12 + T13 + T14 + T15) * D[5] - 14 * T17 + + (T12 + T13 + T14 + T15) * D[4] - 14 * T18 + (T13 + T14 + T15) * D[3] - + 14 * T19 + (T14 + T15) * D[2] - 14 * T20 - 18 * D[0] * D[1] - 14 * T21; + T256 = 105 * T8, T257 = 210 * D[6], T258 = 105 * T9, T259 = 105 * T16, + T260 = 105 * T17, T261 = 105 * T18, T262 = 105 * T19, T263 = 105 * T20, + T264 = 120 * D[0] * D[1], T265 = 105 * T21, + T266 = (H * H * H * H * H * H * H * H); + T267 = -344 * T8 + (-688 * D[6] + T59 + T60 + T61 + T62 + T63 + T64) * D[7] - + 344 * T9 + (T59 + T60 + T61 + T62 + T63 + T64) * D[6] - 344 * T16 + + T137 - 344 * T17 + T139 - 344 * T18 + T141 - 344 * T19 + T143 - + 344 * T20 - T84 - 344 * T21; + T268 = 644 * T8, T269 = 1288 * D[6], T270 = 644 * T9, T271 = 644 * T16, + T272 = 644 * T17, T273 = 644 * T18, T274 = 644 * T19, T275 = 644 * T20, + T276 = 504 * D[0] * D[1], T277 = 644 * T21; + T278 = -756 * T8 + + (-1512 * D[6] + T124 + T125 + T126 + T127 + T128 + T129) * D[7] - + 756 * T9 + (T124 + T125 + T126 + T127 + T128 + T129) * D[6] - + 756 * T16 + (T125 + T126 + T127 + T128 + T129) * D[5] - 756 * T17 + + (T126 + T127 + T128 + T129) * D[4] - 756 * T18 + + (T127 + T128 + T129) * D[3] - 756 * T19 + (T128 + T129) * D[2] - + 756 * T20 - 420 * D[0] * D[1] - 756 * T21; + T279 = 574 * T8, T280 = 1148 * D[6], T281 = 574 * T9, T282 = 574 * T16, + T283 = 574 * T17, T284 = 574 * T18, T285 = 574 * T19, T286 = 574 * T20, + T287 = 574 * T21; + T288 = -280 * T8 + (-560 * D[6] - 560 * D[5]) * D[7] - 280 * T9 - + 560 * D[5] * D[6] - 280 * T16 - 280 * T17 - 280 * T18 - 280 * T19 - + 280 * T20 - 280 * T21; + T289 = 24 * D[4], T290 = 24 * D[3], T291 = 24 * D[2], T292 = 24 * D[1], + T293 = 24 * D[0], T294 = 24 * D[0] * D[1], T295 = -14 * T8, T296 = -28 * D[6], + T297 = -14 * T9, T298 = 6 * D[4], T299 = 6 * D[3], T300 = 6 * D[2], + T301 = 6 * D[1], T302 = 6 * D[0], T303 = -14 * T16, T304 = -14 * T17, + T305 = -14 * T18, T306 = -14 * T19, T307 = -14 * T20, T308 = -14 * T21; + T309 = 2 * T8 + (4 * D[6] + T2 + T3 + T4 + T5 + T6 + T7) * D[7] + 2 * T9 + + (T2 + T3 + T4 + T5 + T6 + T7) * D[6] + 2 * T16 + T250 + 2 * T17 + + T251 + 2 * T18 + T252 + 2 * T19 + T253 + 2 * T20 + T254 + 2 * T21; + T310 = 17 * T8, T311 = 34 * D[6], T312 = 34 * D[5], T313 = 17 * T9, + T314 = 17 * T16, T315 = (T289 + T290 + T291 + T292 + T293) * D[5]; + T316 = 17 * T17, T317 = (T290 + T291 + T292 + T293) * D[4]; + T318 = 17 * T18, T319 = (T291 + T292 + T293) * D[3]; + T320 = 17 * T19, T321 = (T292 + T293) * D[2]; + T322 = 17 * T20, T323 = 17 * T21, T324 = (H * H * H * H * H * H * H * H * H); + T325 = 64 * T8, + T326 = (128 * D[6] + T40 + T41 + T42 + T43 + T44 + T45) * D[7]; + T327 = 64 * T9, T328 = (T40 + T41 + T42 + T43 + T44 + T45) * D[6]; + T329 = 64 * T16, T330 = 64 * T17, T331 = 64 * T18, T332 = 64 * T19, + T333 = 64 * T20, T334 = 64 * T21, T335 = 140 * T8, T336 = 280 * D[6], + T337 = 280 * D[5], T338 = 140 * T9, T339 = 140 * T16, T340 = 140 * T17, + T341 = 140 * T18, T342 = 140 * T19, T343 = 140 * T20, T344 = 140 * T21, + T345 = 196 * T8; + T346 = (392 * D[6] + T91 + T92 + T93 + T94 + T95 + T96) * D[7]; + T347 = 196 * T9; + T348 = (T91 + T92 + T93 + T94 + T95 + T96) * D[6]; + T349 = 196 * T16; + T350 = (T92 + T93 + T94 + T95 + T96) * D[5]; + T351 = 196 * T17; + T352 = (T93 + T94 + T95 + T96) * D[4]; + T353 = 196 * T18; + T354 = (T94 + T95 + T96) * D[3]; + T355 = 196 * T19; + T356 = (T95 + T96) * D[2]; + T357 = 196 * T20, T358 = 196 * T21, T359 = 182 * T8, T360 = 364 * D[6], + T361 = 364 * D[5], T362 = 182 * T9, T363 = 182 * T16, T364 = 182 * T17, + T365 = 182 * T18, T366 = 182 * T19, T367 = 182 * T20, T368 = 182 * T21, + T369 = 112 * T8; + T370 = (224 * D[6] + T177 + T41 + T42 + T43 + T44 + T45) * D[7]; + T371 = 112 * T9; + T372 = (T177 + T41 + T42 + T43 + T44 + T45) * D[6]; + T373 = 112 * T16, T374 = 112 * T17, T375 = 112 * T18, T376 = 112 * T19, + T377 = 112 * T20, T378 = 112 * T21, T379 = 44 * T8, T380 = 88 * D[6], + T381 = 88 * D[5], T382 = 44 * T9, T383 = 44 * T16, T384 = 44 * T17, + T385 = 44 * T18, T386 = 44 * T19, T387 = 44 * T20, T388 = 44 * T21, + T389 = 10 * T8, T390 = (20 * D[6] + T249 + T3 + T4 + T5 + T6 + T7) * D[7]; + T391 = 10 * T9, T392 = (T249 + T3 + T4 + T5 + T6 + T7) * D[6]; + T393 = 10 * T16, T394 = 10 * T17, T395 = 10 * T18, T396 = 10 * T19, + T397 = 10 * T20, T398 = 10 * T21, T399 = 2 * D[6], T400 = 2 * D[5], + T401 = 2 * D[5] * D[6]; + T402 = T309 * (L * L * L * L * L * L * L * L * L * L) + + (T255 * H - T310 + (-T311 + T22 + T23 + T24 + T25 + T26 + T27) * D[7] - + T313 + (T22 + T23 + T24 + T25 + T26 + T27) * D[6] - T314 + T47 - + T316 + T48 - T318 + T49 - T320 + T50 - T322 + T51 - T323) * + (L * L * L * L * L * L * L * L * L) + + (T214 * T58 + + (T256 + (T257 + T34 + T35 + T36 + T37 + T38 + T39) * D[7] + T258 + + (T34 + T35 + T36 + T37 + T38 + T39) * D[6] + T259 + + (T35 + T36 + T37 + T38 + T39) * D[5] + T260 + + (T36 + T37 + T38 + T39) * D[4] + T261 + (T37 + T38 + T39) * D[3] + + T262 + (T38 + T39) * D[2] + T263 + T264 + T265) * + H + + T325 + T326 + T327 + T328 + T329 + T101 + T330 + T103 + T331 + T105 + + T332 + T107 + T333 + T109 + T334) * + (L * L * L * L * L * L * L * L) + + (T178 * T77 + + (-T215 + (-T216 + T52 + T53 + T54 + T55 + T56 + T57) * D[7] - T223 + + (T52 + T53 + T54 + T55 + T56 + T57) * D[6] - T224 + + (T53 + T54 + T55 + T56 + T57) * D[5] - T225 + + (T54 + T55 + T56 + T57) * D[4] - T226 + (T55 + T56 + T57) * D[3] - + T227 + (T56 + T57) * D[2] - T228 - T229 - T230) * + T58 + + T267 * H - T335 + (-T336 + T65 + T66 + T67 + T68 + T69 + T70) * D[7] - + T338 + (T65 + T66 + T67 + T68 + T69 + T70) * D[6] - T339 + T119 - + T340 + T120 - T341 + T121 - T342 + T122 - T343 + T123 - T344) * + (L * L * L * L * L * L * L); + T403 = + T402 + + (T131 * T116 + + (T179 + (T180 + T181) * D[7] + T182 + T183 + T184 + T185 + T186 + T187 + + T188 + T189) * + T77 + + T232 * T58 + + (T268 + (T269 + T85 + T86 + T87 + T88 + T89 + T90) * D[7] + T270 + + (T85 + T86 + T87 + T88 + T89 + T90) * D[6] + T271 + + (T86 + T87 + T88 + T89 + T90) * D[5] + T272 + + (T87 + T88 + T89 + T90) * D[4] + T273 + (T88 + T89 + T90) * D[3] + + T274 + (T89 + T90) * D[2] + T275 + T276 + T277) * + H + + T345 + T346 + T347 + T348 + T349 + T350 + T351 + T352 + T353 + T354 + + T355 + T356 + T357 + T168 + T358) * + (L * L * L * L * L * L) + + ((-T97 + (-T98 - T71 + T41 + T42 + T43 + T44 + T45) * D[7] - T99 + + (-T71 + T41 + T42 + T43 + T44 + T45) * D[6] - T100 + T101 - T102 + + T103 - T104 + T105 - T106 + T107 - T108 + T109 - T110) * + T146 + + (-T132 + (-T133 + T111 + T78 + T79 + T80 + T81 + T82) * D[7] - T135 + + (T111 + T78 + T79 + T80 + T81 + T82) * D[6] - T136 + T112 - T138 + + T113 - T140 + T114 - T142 + T115 - T144 + T84 - T145) * + T116 + + T191 * T77 + + (-T159 + (-T160 + T118 + T66 + T67 + T68 + T69 + T70) * D[7] - T162 + + (T118 + T66 + T67 + T68 + T69 + T70) * D[6] - T163 + T119 - T164 + + T120 - T165 + T121 - T166 + T122 - T167 + T123 - T169) * + T58 + + T278 * H - T359 + (-T360 + T130 + T66 + T67 + T68 + T69 + T70) * D[7] - + T362 + (T130 + T66 + T67 + T68 + T69 + T70) * D[6] - T363 + T119 - T364 + + T120 - T365 + T121 - T366 + T122 - T367 + T123 - T368) * + (L * L * L * L * L); + T404 = + T403 + + (T131 * T190 + + (T132 + (T133 + T134 + T60 + T61 + T62 + T63 + T64) * D[7] + T135 + + (T134 + T60 + T61 + T62 + T63 + T64) * D[6] + T136 + T137 + T138 + + T139 + T140 + T141 + T142 + T143 + T144 - T84 + T145) * + T146 + + (1120 * T8 + + (2240 * D[6] + T147 + T148 + T149 + T150 + T151 + T152) * D[7] + + 1120 * T9 + (T147 + T148 + T149 + T150 + T151 + T152) * D[6] + + 1120 * T16 + T154 + 1120 * T17 + T155 + 1120 * T18 + T156 + 1120 * T19 + + T157 + 1120 * T20 + T158 + 1120 * T21) * + T116 + + (T192 + (T193 + T153 + T148 + T149 + T150 + T151 + T152) * D[7] + T199 + + (T153 + T148 + T149 + T150 + T151 + T152) * D[6] + T200 + T154 + T201 + + T155 + T202 + T156 + T203 + T157 + T204 + T158 + T206) * + T77 + + T237 * T58 + + (T279 + (T280 + T175 + T170 + T171 + T172 + T173 + T174) * D[7] + T281 + + (T175 + T170 + T171 + T172 + T173 + T174) * D[6] + T282 + T233 + T283 + + T234 + T284 + T235 + T285 + T236 + T286 + T176 + T287) * + H + + T369 + T370 + T371 + T372 + T373 + T101 + T374 + T103 + T375 + T105 + + T376 + T107 + T377 + T109 + T378) * + (L * L * L * L) + + (T178 * T231 + + (-T179 + (-T180 - T181) * D[7] - T182 - T183 - T184 - T185 - T186 - + T187 - T188 - T189) * + T190 + + T191 * T146 + + (-T192 + (-T193 - T153 + T194 + T195 + T196 + T197 + T198) * D[7] - + T199 + (-T153 + T194 + T195 + T196 + T197 + T198) * D[6] - T200 + T208 - + T201 + T209 - T202 + T210 - T203 + T211 - T204 + T205 - T206) * + T116 + + (-1400 * T8 + + (-2800 * D[6] + T207 + T194 + T195 + T196 + T197 + T198) * D[7] - + 1400 * T9 + (T207 + T194 + T195 + T196 + T197 + T198) * D[6] - + 1400 * T16 + T208 - 1400 * T17 + T209 - 1400 * T18 + T210 - 1400 * T19 + + T211 - 1400 * T20 + T205 - 1400 * T21) * + T77 + + (-T238 + (-T239 + T212 + T78 + T79 + T80 + T81 + T82) * D[7] - T241 + + (T212 + T78 + T79 + T80 + T81 + T82) * D[6] - T242 + T112 - T243 + + T113 - T244 + T114 - T245 + T115 - T246 + T84 - T247) * + T58 + + T288 * H - T379 + (-T380 + T213 + T23 + T24 + T25 + T26 + T27) * D[7] - + T382 + (T213 + T23 + T24 + T25 + T26 + T27) * D[6] - T383 + T47 - T384 + + T48 - T385 + T49 - T386 + T50 - T387 + T51 - T388) * + (L * L * L); + T405 = + T214 * T266 + + (T215 + (T216 + T217 + T218 + T219 + T220 + T221 + T222) * D[7] + T223 + + (T217 + T218 + T219 + T220 + T221 + T222) * D[6] + T224 + + (T218 + T219 + T220 + T221 + T222) * D[5] + T225 + + (T219 + T220 + T221 + T222) * D[4] + T226 + (T220 + T221 + T222) * D[3] + + T227 + (T221 + T222) * D[2] + T228 + T229 + T230) * + T231 + + T232 * T190 + + (T159 + (T160 + T161 + T170 + T171 + T172 + T173 + T174) * D[7] + T162 + + (T161 + T170 + T171 + T172 + T173 + T174) * D[6] + T163 + T233 + T164 + + T234 + T165 + T235 + T166 + T236 + T167 + T176 + T169) * + T146 + + T237 * T116 + + (T238 + (T239 + T240 + T60 + T61 + T62 + T63 + T64) * D[7] + T241 + + (T240 + T60 + T61 + T62 + T63 + T64) * D[6] + T242 + T137 + T243 + T139 + + T244 + T141 + T245 + T143 + T246 - T84 + T247) * + T77 + + (336 * T8 + (672 * D[6] + T248 + T66 + T67 + T68 + T69 + T70) * D[7] + + 336 * T9 + (T248 + T66 + T67 + T68 + T69 + T70) * D[6] + 336 * T16 + + T119 + 336 * T17 + T120 + 336 * T18 + T121 + 336 * T19 + T122 + + 336 * T20 - T176 + 336 * T21) * + T58 + + (T97 + (T98 + T71 + T23 + T24 + T25 + T26 + T27) * D[7] + T99 + + (T71 + T23 + T24 + T25 + T26 + T27) * D[6] + T100 + T47 + T102 + T48 + + T104 + T49 + T106 + T50 + T108 + T51 + T110) * + H + + T389 + T390 + T391; + T406 = T255 * T324 + + (-T256 + (-T257 - T34 - T35 - T36 - T37 - T38 - T39) * D[7] - T258 + + (-T34 - T35 - T36 - T37 - T38 - T39) * D[6] - T259 + + (-T35 - T36 - T37 - T38 - T39) * D[5] - T260 + + (-T36 - T37 - T38 - T39) * D[4] - T261 + (-T37 - T38 - T39) * D[3] - + T262 + (-T38 - T39) * D[2] - T263 - T264 - T265) * + T266 + + T267 * T231 + + (-T268 + (-T269 - T85 - T86 - T87 - T88 - T89 - T90) * D[7] - T270 + + (-T85 - T86 - T87 - T88 - T89 - T90) * D[6] - T271 + + (-T86 - T87 - T88 - T89 - T90) * D[5] - T272 + + (-T87 - T88 - T89 - T90) * D[4] - T273 + (-T88 - T89 - T90) * D[3] - + T274 + (-T89 - T90) * D[2] - T275 - T276 - T277) * + T190 + + T278 * T146 + + (-T279 + (-T280 - T175 + T66 + T67 + T68 + T69 + T70) * D[7] - T281 + + (-T175 + T66 + T67 + T68 + T69 + T70) * D[6] - T282 + T119 - T283 + + T120 - T284 + T121 - T285 + T122 - T286 - T176 - T287) * + T116 + + T288 * T77 + + (-T97 + (-T98 - T71 + T289 + T290 + T291 + T292 + T293) * D[7] - T99 + + (-T71 + T289 + T290 + T291 + T292 + T293) * D[6] - T100 + T315 - + T102 + T317 - T104 + T319 - T106 + T321 - T108 + T294 - T110) * + T58; + T407 = T404 + + (T405 + T392 + T393 + T250 + T394 + T251 + T395 + T252 + T396 + T253 + + T397 + T254 + T398) * + L * L + + (T406 + + (T295 + (T296 + T10 + T298 + T299 + T300 + T301 + T302) * D[7] + + T297 + (T10 + T298 + T299 + T300 + T301 + T302) * D[6] + T303 + + (T298 + T299 + T300 + T301 + T302) * D[5] + T304 + + (T299 + T300 + T301 + T302) * D[4] + T305 + + (T300 + T301 + T302) * D[3] + T306 + (T301 + T302) * D[2] + T307 + + 6 * D[0] * D[1] + T308) * + H - + T8 + (-T399 - T400) * D[7] - T9 - T401 - T16 - T17 - T18 - T19 - T20 - + T21) * + L + + T309 * (H * H * H * H * H * H * H * H * H * H) + + (T310 + (T311 + T312 + T289 + T290 + T291 + T292 + T293) * D[7] + + T313 + (T312 + T289 + T290 + T291 + T292 + T293) * D[6] + T314 + + T315 + T316 + T317 + T318 + T319 + T320 + T321 + T322 + T294 + T323) * + T324 + + (T325 + T326 + T327 + T328 + T329 + T101 + T330 + T103 + T331 + T105 + + T332 + T107 + T333 + T109 + T334) * + T266 + + (T335 + (T336 + T337 + T170 + T171 + T172 + T173 + T174) * D[7] + + T338 + (T337 + T170 + T171 + T172 + T173 + T174) * D[6] + T339 + + T233 + T340 + T234 + T341 + T235 + T342 + T236 + T343 + T176 + T344) * + T231 + + (T345 + T346 + T347 + T348 + T349 + T350 + T351 + T352 + T353 + T354 + + T355 + T356 + T357 + T168 + T358) * + T190; + return (T407 + + (T359 + (T360 + T361 + T170 + T171 + T172 + T173 + T174) * D[7] + + T362 + (T361 + T170 + T171 + T172 + T173 + T174) * D[6] + T363 + + T233 + T364 + T234 + T365 + T235 + T366 + T236 + T367 + T176 + + T368) * + T146 + + (T369 + T370 + T371 + T372 + T373 + T101 + T374 + T103 + T375 + T105 + + T376 + T107 + T377 + T109 + T378) * + T116 + + (T379 + (T380 + T381 + T289 + T290 + T291 + T292 + T293) * D[7] + + T382 + (T381 + T289 + T290 + T291 + T292 + T293) * D[6] + T383 + + T315 + T384 + T317 + T385 + T319 + T386 + T321 + T387 + T294 + + T388) * + T77 + + (T389 + T390 + T391 + T392 + T393 + T250 + T394 + T251 + T395 + T252 + + T396 + T253 + T397 + T254 + T398) * + T58 + + (T8 + (T399 + T400) * D[7] + T9 + T401 + T16 + T17 + T18 + T19 + T20 + + T21) * + H) / + 6; +} diff --git a/dsp/core/double2byte.c b/dsp/core/double2byte.c new file mode 100644 index 00000000..9e87c1d1 --- /dev/null +++ b/dsp/core/double2byte.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "libc/macros.h" +#include "libc/math.h" +#include "libc/mem/mem.h" + +void *double2byte(long n, const void *p, double weight, double bias) { + long i; + const double *src; + unsigned char *dst; + if ((dst = valloc(n * sizeof(unsigned char)))) { + for (src = p, i = 0; i < n; ++i) { + dst[i] = MIN(255, MAX(0, rint(src[i] * weight + bias))); + } + } + return dst; +} diff --git a/dsp/core/float2short.c b/dsp/core/float2short.c new file mode 100644 index 00000000..2094c2c3 --- /dev/null +++ b/dsp/core/float2short.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/limits.h" +#include "libc/macros.h" +#include "libc/math.h" +#include "libc/str/str.h" + +/** + * Converts floating point audio samples to pulse code modulation. + * + * @param rdi is number of sample chunks + * @param rsi points to aligned pcm [-32k,+32k] output memory + * @param rdx points to aligned float32 [-1,+1] input memory + */ +void float2short(size_t n, short pcm16[n][8], const float binary32[n][8]) { + size_t i, j; + float f[8], w[8]; + for (i = 0; i < n; ++i) { + for (j = 0; j < 8; ++j) { + pcm16[i][j] = + MIN(SHRT_MAX, MAX(SHRT_MIN, floorf(binary32[i][j] * (SHRT_MAX + 1)))); + } + } +} diff --git a/dsp/core/gamma.c b/dsp/core/gamma.c new file mode 100644 index 00000000..a220d931 --- /dev/null +++ b/dsp/core/gamma.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "dsp/core/gamma.h" +#include "libc/math.h" + +double rgb2stdpc(double x, double g) { + return COMPANDLUMA_SRGB(x, g); +} +double rgb2linpc(double x, double g) { + return UNCOMPANDLUMA_SRGB(x, g); +} + +double rgb2stdtv(double x) { + return COMPANDLUMA_BT1886(x); +} +double rgb2lintv(double x) { + return UNCOMPANDLUMA_BT1886(x); +} + +double tv2pcgamma(double x, double g) { + return rgb2stdpc(rgb2lintv(x), g); +} diff --git a/dsp/core/gamma.h b/dsp/core/gamma.h new file mode 100644 index 00000000..05f6202a --- /dev/null +++ b/dsp/core/gamma.h @@ -0,0 +1,23 @@ +#ifndef COSMOPOLITAN_DSP_CORE_GAMMA_H_ +#define COSMOPOLITAN_DSP_CORE_GAMMA_H_ +#include "libc/math.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define COMPANDLUMA(X, ...) COMPANDLUMA_(X, __VA_ARGS__) +#define COMPANDLUMA_(X, K1, K2, K3, K4) \ + ((X) > (K3) / (K4) ? (1 + (K2)) * pow((X), 1 / (K1)) - (K2) : (X) * (K4)) + +#define UNCOMPANDLUMA(X, ...) UNCOMPANDLUMA_(X, __VA_ARGS__) +#define UNCOMPANDLUMA_(X, K1, K2, K3, K4) \ + ((X) > (K3) ? pow(1 / (1 + (K2)) * ((X) + (K2)), K1) : (X) / (K4)) + +#define COMPANDLUMA_SRGB_MAGNUM .055, .04045, 12.92 +#define COMPANDLUMA_SRGB(X, G) COMPANDLUMA(X, G, COMPANDLUMA_SRGB_MAGNUM) +#define UNCOMPANDLUMA_SRGB(X, G) UNCOMPANDLUMA(X, G, COMPANDLUMA_SRGB_MAGNUM) + +#define COMPANDLUMA_BT1886_MAGNUM 1 / .45, .099, .081, 4.5 +#define COMPANDLUMA_BT1886(X) COMPANDLUMA(X, COMPANDLUMA_BT1886_MAGNUM) +#define UNCOMPANDLUMA_BT1886(X) UNCOMPANDLUMA(X, COMPANDLUMA_BT1886_MAGNUM) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_CORE_GAMMA_H_ */ diff --git a/dsp/core/getintegercoefficients.c b/dsp/core/getintegercoefficients.c new file mode 100644 index 00000000..f52f4555 --- /dev/null +++ b/dsp/core/getintegercoefficients.c @@ -0,0 +1,113 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/q.h" +#include "libc/assert.h" +#include "libc/dce.h" +#include "libc/limits.h" +#include "libc/macros.h" +#include "libc/math.h" +#include "libc/str/str.h" + +/** + * Precomputes integers that can replace floating-point operands. + * + * “G-d made the integers, all else is the work of man. + * — Leopold Kronecker + * + * This function shifts the decimal point to the left: + * + * 𝑛ᵢ ← ROUND[𝑐ᵢ × 2ᵐ] + φᵢ + * + * With extra effort to compute φ which is normally all zeroes but gives + * us better rounding when it isn't. It's assumed optimized coefficients + * will be used like this: + * + * (Σᵢ𝑥ᵢ𝑛ᵢ + 2⁽ᵐ⁻¹⁾) / 2ᵐ where 𝑥∈[𝐿,𝐻] and 𝑖∈[0,6) + * + * Intended to compute this + * + * ROUND[Σᵢ𝑥ᵢ𝑐ᵢ] + * + * As accurately or approximately as you want it to be. Popular scaling + * factors are 7, 15, 16, 22, and 31. Building this code under MODE=tiny + * will DCE the math. + * + * @param N receives optimized integers + * @param C provides ideal coefficients + * @param M is log₂ scaling factor, e.g. 7 + * @param L is minimum input data size, e.g. 0 + * @param H is maximum input data size, e.g. 255 + * @return sum of errors for all inputs + * @see en.wikipedia.org/wiki/Binary_scaling + * @see o/tool/build/coefficients.com + * @cost ~300ns + */ +long GetIntegerCoefficients(long N[static 6], const double C[static 6], long M, + long L, long H) { + int i; + int j[6], J[6]; + int O[6] = {0}; + int S[3] = {0, -1, +1}; + double R[6], K[6], D[6], HM, HL, least, error; + least = 1; + HM = 1L << M; + HL = H - L + 1; + assert(H >= L); + assert(HL <= HM); + for (i = 0; i < 6; ++i) { + least *= HL; + if (fabs(C[i]) > DBL_MIN) { + J[i] = ARRAYLEN(S); + R[i] = C[i] * HM; + K[i] = rint(R[i]); + N[i] = K[i]; + } else { + J[i] = 1; + R[i] = 0; + K[i] = 0; + N[i] = 0; + } + } + if (!IsTiny() && least > 1) { + for (j[0] = 0; j[0] < J[0]; ++j[0]) { + for (j[1] = 0; j[1] < J[1]; ++j[1]) { + for (j[2] = 0; j[2] < J[2]; ++j[2]) { + for (j[3] = 0; j[3] < J[3]; ++j[3]) { + for (j[4] = 0; j[4] < J[4]; ++j[4]) { + for (j[5] = 0; j[5] < J[5]; ++j[5]) { + for (i = 0; i < ARRAYLEN(J); ++i) { + D[i] = S[j[i]] + K[i] - R[i]; + } + if ((error = DifferSumSq(D, L, H) / HM) < least) { + least = error; + memcpy(O, j, sizeof(j)); + } + } + } + } + } + } + } + for (i = 0; i < 6; ++i) { + N[i] += S[O[i]]; + } + } + return lround(least); +} diff --git a/dsp/core/getintegercoefficients8.c b/dsp/core/getintegercoefficients8.c new file mode 100644 index 00000000..1aa61a5b --- /dev/null +++ b/dsp/core/getintegercoefficients8.c @@ -0,0 +1,83 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "dsp/core/q.h" +#include "libc/dce.h" +#include "libc/macros.h" +#include "libc/math.h" +#include "libc/str/str.h" + +/** + * Same as GetIntegerCoefficients() but with eight terms. + * @cost ~3ms + */ +long GetIntegerCoefficients8(long N[static 8], const double C[static 8], long M, + long L, long H) { + int i; + int j[8], J[8]; + int O[8] = {0}; + int S[3] = {0, -1, +1}; + double R[8], K[8], D[8], Z, least, error; + least = 1; + Z = 1L << M; + for (i = 0; i < ARRAYLEN(J); ++i) { + least *= H - L; + if (fabs(C[i]) > DBL_MIN) { + J[i] = ARRAYLEN(S); + R[i] = C[i] * Z; + K[i] = rint(R[i]); + N[i] = K[i]; + } else { + J[i] = 1; + R[i] = 0; + K[i] = 0; + N[i] = 0; + } + } + if (least > 1) { + for (j[0] = 0; j[0] < J[0]; ++j[0]) { + for (j[1] = 0; j[1] < J[1]; ++j[1]) { + for (j[2] = 0; j[2] < J[2]; ++j[2]) { + for (j[3] = 0; j[3] < J[3]; ++j[3]) { + for (j[4] = 0; j[4] < J[4]; ++j[4]) { + for (j[5] = 0; j[5] < J[5]; ++j[5]) { + for (j[6] = 0; j[6] < J[6]; ++j[6]) { + for (j[7] = 0; j[7] < J[7]; ++j[7]) { + for (i = 0; i < ARRAYLEN(J); ++i) { + D[i] = S[j[i]] + K[i] - R[i]; + } + if ((error = DifferSumSq8(D, L, H) / Z) < least) { + least = error; + memcpy(O, j, sizeof(j)); + } + } + } + } + } + } + } + } + } + for (i = 0; i < 8; ++i) { + N[i] += S[O[i]]; + } + } + return lround(least); +} diff --git a/dsp/core/half.h b/dsp/core/half.h new file mode 100644 index 00000000..43d94749 --- /dev/null +++ b/dsp/core/half.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_DSP_CORE_HALF_H_ +#define COSMOPOLITAN_DSP_CORE_HALF_H_ +#include "libc/macros.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * Divides integer in half w/ rounding. + */ +#define HALF(X) (((X) + 1) / (2 / TYPE_INTEGRAL(typeof(X)))) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_CORE_HALF_H_ */ diff --git a/dsp/core/illumination.c b/dsp/core/illumination.c new file mode 100644 index 00000000..d9e5586b --- /dev/null +++ b/dsp/core/illumination.c @@ -0,0 +1,79 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "dsp/core/illumination.h" +#include "libc/str/str.h" + +const double kIlluminantA[3] = {1.0985, 1, 0.35585}; +const double kIlluminantAD10[3] = {1.11144, 1, 0.35200}; +const double kIlluminantC[3] = {0.98074, 1, 1.18232}; +const double kIlluminantCD10[3] = {0.97285, 1, 1.16145}; +const double kIlluminantD50[3] = {0.96422, 1, 0.82521}; +const double kIlluminantD50D10[3] = {0.9672, 1, 0.81427}; +const double kIlluminantD55[3] = {0.95682, 1, 0.92149}; +const double kIlluminantD55D10[3] = {0.95799, 1, 0.90926}; +const double kIlluminantD65[3] = {0.95047, 1, 1.08883}; +const double kIlluminantD65D10[3] = {0.94811, 1, 1.07304}; +const double kIlluminantD75[3] = {0.94972, 1, 1.22638}; +const double kIlluminantD75D10[3] = {0.94416, 1, 1.20641}; +const double kIlluminantF2[3] = {0.99187, 1, 0.67395}; +const double kIlluminantF2D10[3] = {1.0328, 1, 0.69026}; +const double kIlluminantF7[3] = {0.95044, 1, 1.08755}; +const double kIlluminantF7D10[3] = {0.95792, 1, 1.07687}; +const double kIlluminantF11[3] = {1.00966, 1, 0.6437}; +const double kIlluminantF11D10[3] = {1.03866, 1, 0.65627}; + +/** + * System of equations used for changing illumination. + * + * @see brucelindbloom.com/Eqn_ChromAdapt.html “The Bradford method is + * the newest of the three methods, and is considered by most + * experts to be the best of them. This is the method used in Adobe + * Photoshop. A related article comparing the chromatic adaptation + * algorithms may be found here.” ─Quoth Bruce Lindbloom + */ +const double kBradford[3][3] = { + {0.8951, 0.2664, -.1614}, + {-.7502, 1.7135, 0.0367}, + {0.0389, -.0685, 1.0296}, +}; + +/** + * Computes lightbulb changing coefficients. + * + * @param R will store result + * @param S has intended input illuminant primaries + * @param D has desired output illuminant primaries + * @return R + * @see brucelindbloom.com/Eqn_ChromAdapt.html + * @see fluxometer.com/rainbow/ + */ +void *GetChromaticAdaptationMatrix(double R[3][3], const double S[3], + const double D[3]) { + double M[3][3], T[3][3], U[3][3], V[3], W[3]; + matvmul3(V, kBradford, S); + matvmul3(W, kBradford, D); + memset(M, 0, sizeof(M)); + M[0][0] = W[0] / V[0]; + M[1][1] = W[1] / V[1]; + M[2][2] = W[2] / V[2]; + return matmul3(R, matmul3(T, kBradford, M), + inv3(U, kBradford, det3(kBradford))); +} diff --git a/dsp/core/illumination.h b/dsp/core/illumination.h new file mode 100644 index 00000000..a50c7794 --- /dev/null +++ b/dsp/core/illumination.h @@ -0,0 +1,31 @@ +#ifndef COSMOPOLITAN_DSP_CORE_ILLUMINANT_H_ +#define COSMOPOLITAN_DSP_CORE_ILLUMINANT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +extern const double kBradford[3][3]; +extern const double kIlluminantA[3]; +extern const double kIlluminantAD10[3]; +extern const double kIlluminantC[3]; +extern const double kIlluminantCD10[3]; +extern const double kIlluminantD50[3]; +extern const double kIlluminantD50D10[3]; +extern const double kIlluminantD55[3]; +extern const double kIlluminantD55D10[3]; +extern const double kIlluminantD65[3]; +extern const double kIlluminantD65D10[3]; +extern const double kIlluminantD75[3]; +extern const double kIlluminantD75D10[3]; +extern const double kIlluminantF2[3]; +extern const double kIlluminantF2D10[3]; +extern const double kIlluminantF7[3]; +extern const double kIlluminantF7D10[3]; +extern const double kIlluminantF11[3]; +extern const double kIlluminantF11D10[3]; + +void *GetChromaticAdaptationMatrix(double[3][3], const double[3], + const double[3]); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_CORE_ILLUMINANT_H_ */ diff --git a/dsp/core/inv3.c b/dsp/core/inv3.c new file mode 100644 index 00000000..a13ba86f --- /dev/null +++ b/dsp/core/inv3.c @@ -0,0 +1,46 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "libc/math.h" +#include "libc/str/str.h" + +/** + * Computes 𝐀⁻¹ inverted 3×3 matrix, if it exists. + * + * @param 𝐁 is destination memory + * @param 𝐀 is input matrix, which can't overlap 𝐁 + * @param 𝑑 is |𝐀| the determinant scalar or 0 if degenerate + * @return 𝐀⁻¹ stored inside 𝐁 or NaNs if 𝑑=0 + * @define 𝐀⁻¹=𝐁 such that 𝐀×𝐁=𝐁×𝐀=𝐈ₙ + * @see det3() + */ +void *inv3(double B[restrict 3][3], const double A[restrict 3][3], double d) { + d = d ? 1 / d : NAN; + B[0][0] = (A[1][1] * A[2][2] - A[2][1] * A[1][2]) * d; + B[0][1] = (A[2][1] * A[0][2] - A[0][1] * A[2][2]) * d; + B[0][2] = (A[0][1] * A[1][2] - A[1][1] * A[0][2]) * d; + B[1][0] = (A[2][0] * A[1][2] - A[1][0] * A[2][2]) * d; + B[1][1] = (A[0][0] * A[2][2] - A[2][0] * A[0][2]) * d; + B[1][2] = (A[1][0] * A[0][2] - A[0][0] * A[1][2]) * d; + B[2][0] = (A[1][0] * A[2][1] - A[2][0] * A[1][1]) * d; + B[2][1] = (A[2][0] * A[0][1] - A[0][0] * A[2][1]) * d; + B[2][2] = (A[0][0] * A[1][1] - A[1][0] * A[0][1]) * d; + return B; +} diff --git a/dsp/core/ituround.h b/dsp/core/ituround.h new file mode 100644 index 00000000..79165794 --- /dev/null +++ b/dsp/core/ituround.h @@ -0,0 +1,23 @@ +#ifndef COSMOPOLITAN_DSP_CORE_ITUROUND_H_ +#define COSMOPOLITAN_DSP_CORE_ITUROUND_H_ +#include "libc/math.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * An ITU recommended rounding function. + * + * 1. Negative numbers round toward zero + * 2. Positive numbers round toward infinity + * + * @see round(), rint() + */ +static inline pureconst artificial long ituround(double x) { + return floor(x + .5); +} + +static inline pureconst artificial int ituroundf(float x) { + return floorf(x + .5f); +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_CORE_ITUROUND_H_ */ diff --git a/dsp/core/ks8.h b/dsp/core/ks8.h new file mode 100644 index 00000000..111480c3 --- /dev/null +++ b/dsp/core/ks8.h @@ -0,0 +1,47 @@ +#ifndef COSMOPOLITAN_DSP_CORE_KS8_H_ +#define COSMOPOLITAN_DSP_CORE_KS8_H_ +#include "libc/macros.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * Performs 16-bit scaled rounded madd w/ eight coefficients or fewer. + * + * (Σᵢ₌₀₋₈𝑘ᵢ𝑥ᵢ + 2ᵐ⁻¹)/2ᵐ + * + * @note intent is avoiding type promotion + */ +#define KS8(M, K1, K2, K3, K4, K5, K6, K7, K8, X1, X2, X3, X4, X5, X6, X7, X8) \ + ({ \ + short x1, x2, x3, x4, x5, x6, x7, x8; \ + x1 = X1; \ + x2 = X2; \ + x3 = X3; \ + x4 = X4; \ + x5 = X5; \ + x6 = X6; \ + x7 = X7; \ + x8 = X8; \ + x1 *= K1; \ + x2 *= K2; \ + x3 *= K3; \ + x4 *= K4; \ + x5 *= K5; \ + x6 *= K6; \ + x7 *= K7; \ + x8 *= K8; \ + x1 += x2; \ + x3 += x4; \ + x5 += x6; \ + x7 += x8; \ + x1 += x3; \ + x5 += x7; \ + x1 += x5; \ + if (M) { \ + x1 += 1 << MAX(0, M - 1); \ + x1 >>= M; \ + } \ + x1; \ + }) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_CORE_KS8_H_ */ diff --git a/dsp/core/kss8.h b/dsp/core/kss8.h new file mode 100644 index 00000000..60f86ff9 --- /dev/null +++ b/dsp/core/kss8.h @@ -0,0 +1,43 @@ +#ifndef COSMOPOLITAN_DSP_CORE_KSS8_H_ +#define COSMOPOLITAN_DSP_CORE_KSS8_H_ +#include "libc/limits.h" +#include "libc/macros.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * Performs 16-bit scaled rounded saturated madd w/ eight coefficients or fewer. + * + * (Σᵢ₌₀₋₈𝑘ᵢ𝑥ᵢ + 2ᵐ⁻¹)/2ᵐ + * + * @note compiler struggles with this + */ +#define KSS8(M, K1, K2, K3, K4, K5, K6, K7, K8, X1, X2, X3, X4, X5, X6, X7, \ + X8) \ + ({ \ + short x1, x2, x3, x4, x5, x6, x7, x8; \ + x1 = X1, x2 = X2, x3 = X3, x4 = X4; \ + x5 = X5, x6 = X6, x7 = X7, x8 = X8; \ + x1 = MIN(SHRT_MAX, MAX(SHRT_MIN, x1 * K1)); \ + x2 = MIN(SHRT_MAX, MAX(SHRT_MIN, x2 * K2)); \ + x3 = MIN(SHRT_MAX, MAX(SHRT_MIN, x3 * K3)); \ + x4 = MIN(SHRT_MAX, MAX(SHRT_MIN, x4 * K4)); \ + x5 = MIN(SHRT_MAX, MAX(SHRT_MIN, x5 * K5)); \ + x6 = MIN(SHRT_MAX, MAX(SHRT_MIN, x6 * K6)); \ + x7 = MIN(SHRT_MAX, MAX(SHRT_MIN, x7 * K7)); \ + x8 = MIN(SHRT_MAX, MAX(SHRT_MIN, x8 * K8)); \ + x1 = MIN(SHRT_MAX, MAX(SHRT_MIN, x1 + x2)); \ + x3 = MIN(SHRT_MAX, MAX(SHRT_MIN, x3 + x4)); \ + x5 = MIN(SHRT_MAX, MAX(SHRT_MIN, x5 + x6)); \ + x7 = MIN(SHRT_MAX, MAX(SHRT_MIN, x7 + x8)); \ + x1 = MIN(SHRT_MAX, MAX(SHRT_MIN, x1 + x3)); \ + x5 = MIN(SHRT_MAX, MAX(SHRT_MIN, x5 + x7)); \ + x1 = MIN(SHRT_MAX, MAX(SHRT_MIN, x1 + x5)); \ + if (M) { \ + x1 += 1 << MAX(0, M - 1); \ + x1 >>= M; \ + } \ + x1; \ + }) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_CORE_KSS8_H_ */ diff --git a/dsp/core/matmul3.c b/dsp/core/matmul3.c new file mode 100644 index 00000000..691251fa --- /dev/null +++ b/dsp/core/matmul3.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "libc/str/str.h" + +/** + * Multiplies 3×3 matrices. + */ +void *matmul3(double R[restrict 3][3], const double A[3][3], + const double B[3][3]) { + int i, j, k; + memset(R, 0, sizeof(double) * 3 * 3); + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + for (k = 0; k < 3; ++k) { + R[i][j] += A[k][j] * B[i][k]; + } + } + } + return R; +} diff --git a/dsp/core/matvmul3.c b/dsp/core/matvmul3.c new file mode 100644 index 00000000..60e8b637 --- /dev/null +++ b/dsp/core/matvmul3.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" + +/** + * Computes M×V. + * + * @see vmatmul3() for noncommutative corollary + */ +void *matvmul3(double R[restrict 3], const double M[3][3], const double V[3]) { + R[0] = V[0] * M[0][0] + V[1] * M[0][1] + V[2] * M[0][2]; + R[1] = V[0] * M[1][0] + V[1] * M[1][1] + V[2] * M[1][2]; + R[2] = V[0] * M[2][0] + V[1] * M[2][1] + V[2] * M[2][2]; + return R; +} diff --git a/dsp/core/mulaw.S b/dsp/core/mulaw.S new file mode 100644 index 00000000..f82d33a4 --- /dev/null +++ b/dsp/core/mulaw.S @@ -0,0 +1,64 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +#define BIAS 0x84 + +/ Encodes audio sample with µ-Law. +/ +/ This is both the highest quality and most widely supported +/ telephony codec, whose use was phased out in the 2000's in +/ favor of cost-saving GSM audio compression that was so bad +/ consumers were willing to pay more cash, for the privilege +/ of saving telcos even more money w/ text messaging. Mu Law +/ reduces PCM data to half its original size, by diminishing +/ audio bands not vocalized by human voice. +/ +/ @param %edi is pcm sample +/ @return %eax is uint8_t encoded sample +mulaw: .leafprologue + .profilable + mov $BIAS,%eax + xor %edx,%edx + test %edi,%edi + js 1f + lea (%edi,%eax),%eax + mov $0xFF,%dl + jmp 2f +1: sub %edi,%eax + mov $0x7F,%dl +2: mov %eax,%esi + or $0xFF,%sil + bsr %esi,%esi + sub $7,%esi + cmp $8,%esi + jge 4f + lea 3(%rdx),%ecx + sar %cl,%eax + and $0xF,%eax + shl $4,%esi + or %esi,%eax + xor %edx,%eax +3: .leafepilogue +4: xor $0x7F,%dl + mov %edx,%eax + jmp 3b + .endfn mulaw,globl + .yoink __FILE__ diff --git a/dsp/core/q.h b/dsp/core/q.h new file mode 100644 index 00000000..5d40c64c --- /dev/null +++ b/dsp/core/q.h @@ -0,0 +1,27 @@ +#ifndef COSMOPOLITAN_DSP_CORE_Q_H_ +#define COSMOPOLITAN_DSP_CORE_Q_H_ +#include "libc/limits.h" +#include "libc/macros.h" +#include "libc/math.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * @fileoverview Fixed point arithmetic macros. + * @see en.wikipedia.org/wiki/Q_(number_format) + */ + +#define F2Q(Q, I) MIN((1 << Q) - 1, roundf((I) * (1.f * ((1 << Q) - 1)))) +#define Q2F(Q, I) ((I) * (1.f / ((1 << Q) - 1))) +#define QRS(Q, X) (((X) + (1 << (Q - 1))) >> Q) +#define LQRS(Q, X) (((X) + (1L << (Q - 1))) >> Q) + +double DifferSumSq(const double[static 6], double, double); +double DifferSumSq8(const double[static 8], double, double); + +long GetIntegerCoefficients(long[static 6], const double[static 6], long, long, + long); +long GetIntegerCoefficients8(long[static 8], const double[static 8], long, long, + long); + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_CORE_Q_H_ */ diff --git a/dsp/core/sad16x8n.S b/dsp/core/sad16x8n.S new file mode 100644 index 00000000..d36a0b0e --- /dev/null +++ b/dsp/core/sad16x8n.S @@ -0,0 +1,41 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.align 16 + +/ Mixes audio. +/ +/ @param rdi is # aligned int16[16] sample chunks to process +/ @param rsi points to aligned pcm s16le input/output memory +/ @param rdx points to aligned pcm s16le [0..1] input memory +sad16x8n: + .leafprologue + .profilable + test %rdi,%rdi + jz 1f + shl $3,%rdi +0: sub $8,%rdi + movdqa (%rsi,%rdi,2),%xmm0 + paddsw (%rdx,%rdi,2),%xmm0 + movdqa %xmm0,(%rsi,%rdi,2) + jnz 0b +1: .leafepilogue + .endfn sad16x8n,globl,hidden + .yoink __FILE__ diff --git a/dsp/core/scalevolume.c b/dsp/core/scalevolume.c new file mode 100644 index 00000000..8dceb97c --- /dev/null +++ b/dsp/core/scalevolume.c @@ -0,0 +1,50 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/limits.h" + +/** + * Increases or decreases audio volume. + * + * @param 𝑝 is two-power w/ effective range [-15,15] + */ +void scalevolume(size_t n, int16_t pcm[n][8], int p) { + /* TODO(jart): This isn't acceptable. */ + size_t i, j; + if (p > 0) { + if (p > 15) p = 15; + for (i = 0; i < n; ++i) { + for (j = 0; j < 8; ++j) { + pcm[i][j] = + MIN(SHRT_MAX, MAX(SHRT_MIN, (int)((unsigned)pcm[i][j] << p))); + } + } + } else if (p < 0) { + p = -p; + if (p > 15) p = 15; + for (i = 0; i < n; ++i) { + for (j = 0; j < 8; ++j) { + pcm[i][j] = SAR(pcm[i][j], p); + } + } + } +} diff --git a/dsp/core/twixt8.h b/dsp/core/twixt8.h new file mode 100644 index 00000000..2f015635 --- /dev/null +++ b/dsp/core/twixt8.h @@ -0,0 +1,24 @@ +#ifndef COSMOPOLITAN_DSP_CORE_TWIXT8_H_ +#define COSMOPOLITAN_DSP_CORE_TWIXT8_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * 8-bit linear interpolation kernel. + */ +static inline pureconst artificial unsigned char twixt8(unsigned char al, + unsigned char bl, + unsigned char p) { + short bx; + bx = bl; + bx -= al; + bx *= p; + bx >>= 8; + bx += al; + al = bx; + return al; +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_CORE_TWIXT8_H_ */ diff --git a/dsp/core/vmatmul3.c b/dsp/core/vmatmul3.c new file mode 100644 index 00000000..afc32257 --- /dev/null +++ b/dsp/core/vmatmul3.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" + +/** + * Computes V×M. + * + * @see matvmul3() for noncommutative corollary + */ +void *vmatmul3(double R[restrict 3], const double V[3], const double M[3][3]) { + R[0] = V[0] * M[0][0] + V[1] * M[1][0] + V[2] * M[2][0]; + R[1] = V[0] * M[0][1] + V[1] * M[1][1] + V[2] * M[2][1]; + R[2] = V[0] * M[0][2] + V[1] * M[1][2] + V[2] * M[2][2]; + return R; +} diff --git a/dsp/dsp.mk b/dsp/dsp.mk new file mode 100644 index 00000000..a5976588 --- /dev/null +++ b/dsp/dsp.mk @@ -0,0 +1,8 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +.PHONY: o/$(MODE)/dsp +o/$(MODE)/dsp: o/$(MODE)/dsp/core \ + o/$(MODE)/dsp/mpeg \ + o/$(MODE)/dsp/scale \ + o/$(MODE)/dsp/tty diff --git a/dsp/mpeg/README.txt b/dsp/mpeg/README.txt new file mode 100644 index 00000000..53703b7f --- /dev/null +++ b/dsp/mpeg/README.txt @@ -0,0 +1,92 @@ +PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer +Dominic Szablewski - https://phoboslab.org + +-- Synopsis + +// This function gets called for each decoded video frame +void my_video_callback(plm_t *plm, plm_frame_t *frame, void *user) { + // Do something with frame->y.data, frame->cr.data, frame->cb.data +} + +// This function gets called for each decoded audio frame +void my_audio_callback(plm_t *plm, plm_samples_t *frame, void *user) { + // Do something with samples->interleaved +} + +// Load a .mpg (MPEG Program Stream) file +plm_t *plm = plm_create_with_filename("some-file.mpg"); + +// Install the video & audio decode callbacks +plm_set_video_decode_callback(plm, my_video_callback, my_data); +plm_set_audio_decode_callback(plm, my_audio_callback, my_data); + + +// Decode +do { + plm_decode(plm, time_since_last_call); +} while (!plm_has_ended(plm)); + +// All done +plm_destroy(plm); + + + +-- Documentation + +This library provides several interfaces to load, demux and decode MPEG video +and audio data. A high-level API combines the demuxer, video & audio decoders +in an easy to use wrapper. + +Lower-level APIs for accessing the demuxer, video decoder and audio decoder, +as well as providing different data sources are also available. + +Interfaces are written in an object orientet style, meaning you create object +instances via various different constructor functions (plm_*create()), +do some work on them and later dispose them via plm_*destroy(). + +plm_* -- the high-level interface, combining demuxer and decoders +plm_buffer_* -- the data source used by all interfaces +plm_demux_* -- the MPEG-PS demuxer +plm_video_* -- the MPEG1 Video ("mpeg1") decoder +plm_audio_* -- the MPEG1 Audio Layer II ("mp2") decoder + + +This library uses malloc(), realloc() and free() to manage memory. Typically +all allocation happens up-front when creating the interface. However, the +default buffer size may be too small for certain inputs. In these cases plmpeg +will realloc() the buffer with a larger size whenever needed. You can configure +the default buffer size by defining PLM_BUFFER_DEFAULT_SIZE *before* +including this library. + +With the high-level interface you have two options to decode video & audio: + +1) Use plm_decode() and just hand over the delta time since the last call. +It will decode everything needed and call your callbacks (specified through +plm_set_{video|audio}_decode_callback()) any number of times. + +2) Use plm_decode_video() and plm_decode_audio() to decode exactly one +frame of video or audio data at a time. How you handle the synchronization of +both streams is up to you. + +If you only want to decode video *or* audio through these functions, you should +disable the other stream (plm_set_{video|audio}_enabled(false)) + + +Video data is decoded into a struct with all 3 planes (Y, Cr, Cb) stored in +separate buffers. You can either convert this to RGB on the CPU (slow) via the +plm_frame_to_rgb() function or do it on the GPU with the following matrix: + +mat4 rec601 = mat4( + 1.16438, 0.00000, 1.59603, -0.87079, + 1.16438, -0.39176, -0.81297, 0.52959, + 1.16438, 2.01723, 0.00000, -1.08139, + 0, 0, 0, 1 +); +gl_FragColor = vec4(y, cb, cr, 1.0) * rec601; + +Audio data is decoded into a struct with either one single float array with the +samples for the left and right channel interleaved, or if the +PLM_AUDIO_SEPARATE_CHANNELS is defined *before* including this library, into +two separate float arrays - one for each channel. + +See below for detailed the API documentation. diff --git a/dsp/mpeg/blockset.h b/dsp/mpeg/blockset.h new file mode 100644 index 00000000..cb33de55 --- /dev/null +++ b/dsp/mpeg/blockset.h @@ -0,0 +1,22 @@ +#ifndef COSMOPOLITAN_DSP_MPEG_BLOCKSET_H_ +#define COSMOPOLITAN_DSP_MPEG_BLOCKSET_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define PLM_BLOCK_SET(DEST, DEST_INDEX, DEST_WIDTH, SOURCE_INDEX, \ + SOURCE_WIDTH, BLOCK_SIZE, OP) \ + do { \ + int dest_scan = DEST_WIDTH - BLOCK_SIZE; \ + int source_scan = SOURCE_WIDTH - BLOCK_SIZE; \ + for (int y = 0; y < BLOCK_SIZE; y++) { \ + for (int x = 0; x < BLOCK_SIZE; x++) { \ + DEST[DEST_INDEX] = OP; \ + SOURCE_INDEX++; \ + DEST_INDEX++; \ + } \ + SOURCE_INDEX += source_scan; \ + DEST_INDEX += dest_scan; \ + } \ + } while (false) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_MPEG_BLOCKSET_H_ */ diff --git a/dsp/mpeg/buffer.c b/dsp/mpeg/buffer.c new file mode 100644 index 00000000..d383de75 --- /dev/null +++ b/dsp/mpeg/buffer.c @@ -0,0 +1,158 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│ +│vi: set et ft=c ts=4 sw=4 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer │ +│ Dominic Szablewski - https://phoboslab.org │ +│ │ +│ The MIT License(MIT) │ +│ Copyright(c) 2019 Dominic Szablewski │ +│ │ +│ Permission is hereby granted, free of charge, to any person obtaining │ +│ a copy of this software and associated documentation files(the │ +│ "Software"), to deal in the Software without restriction, including │ +│ without limitation the rights to use, copy, modify, merge, publish, │ +│ distribute, sublicense, and / or sell copies of the Software, and to │ +│ permit persons to whom the Software is furnished to do so, subject to │ +│ the following conditions: │ +│ │ +│ The above copyright notice and this permission notice shall be │ +│ included in all copies or substantial portions of the Software. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │ +│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │ +│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND │ +│ NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE │ +│ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN │ +│ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN │ +│ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE │ +│ SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/mpeg/buffer.h" +#include "dsp/mpeg/mpeg.h" +#include "libc/calls/calls.h" +#include "libc/log/check.h" +#include "libc/mem/mem.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/madv.h" + +asm(".ident\t\"\\n\\n\ +PL_MPEG (MIT License)\\n\ +Copyright(c) 2019 Dominic Szablewski\\n\ +https://phoboslab.org\""); +asm(".include \"libc/disclaimer.inc\""); + +/* clang-format off */ +// ----------------------------------------------------------------------------- +// plm_buffer implementation + +plm_buffer_t *plm_buffer_create_with_filename(const char *filename) { + FILE *fh = fopen(filename, "rb"); + if (!fh) { + return NULL; + } + fadvise(fileno(fh), 0, 0, MADV_SEQUENTIAL); + return plm_buffer_create_with_file(fh, true); +} + +plm_buffer_t *plm_buffer_create_with_file(FILE *fh, int close_when_done) { + plm_buffer_t *b; + b = plm_buffer_create_with_capacity(PLM_BUFFER_DEFAULT_SIZE); + b->fh = fh; + b->close_when_done = close_when_done; + b->mode = PLM_BUFFER_MODE_FILE; + plm_buffer_set_load_callback(b, plm_buffer_load_file_callback, NULL); + return b; +} + +plm_buffer_t *plm_buffer_create_with_memory(unsigned char *bytes, size_t length, int free_when_done) { + plm_buffer_t *b; + b = memalign(alignof(plm_buffer_t), sizeof(plm_buffer_t)); + memset(b, 0, sizeof(plm_buffer_t)); + b->capacity = length; + b->length = length; + b->free_when_done = free_when_done; + b->bytes = bytes; + b->mode = PLM_BUFFER_MODE_FIXED_MEM; + return b; +} + +plm_buffer_t * plm_buffer_create_with_capacity(size_t capacity) { + plm_buffer_t *b; + b = memalign(alignof(plm_buffer_t), sizeof(plm_buffer_t)); + memset(b, 0, sizeof(plm_buffer_t)); + b->capacity = capacity; + b->free_when_done = true; + b->bytes = (unsigned char *)malloc(capacity); + b->mode = PLM_BUFFER_MODE_DYNAMIC_MEM; + return b; +} + +void plm_buffer_destroy(plm_buffer_t *self) { + if (self->fh && self->close_when_done) { + fclose(self->fh); + } + if (self->free_when_done) { + free(self->bytes); + } + free(self); +} + +size_t plm_buffer_write(plm_buffer_t *self, unsigned char *bytes, size_t length) { + if (self->mode == PLM_BUFFER_MODE_FIXED_MEM) { + return 0; + } + // This should be a ring buffer, but instead it just shifts all unread data + // to the beginning of the buffer and appends new data at the end. Seems + // to be good enough. + plm_buffer_discard_read_bytes(self); + // Do we have to resize to fit the new data? + size_t bytes_available = self->capacity - self->length; + if (bytes_available < length) { + size_t new_size = self->capacity; + do { + new_size *= 2; + } while (new_size - self->length < length); + self->bytes = (unsigned char *)realloc(self->bytes, new_size); + self->capacity = new_size; + } + memcpy(self->bytes + self->length, bytes, length); + self->length += length; + return length; +} + +void plm_buffer_set_load_callback(plm_buffer_t *self, plm_buffer_load_callback fp, void *user) { + self->load_callback = fp; + self->load_callback_user_data = user; +} + +void plm_buffer_rewind(plm_buffer_t *self) { + if (self->fh) { + fseek(self->fh, 0, SEEK_SET); + self->length = 0; + } + if (self->mode != PLM_BUFFER_MODE_FIXED_MEM) { + self->length = 0; + } + self->bit_index = 0; +} + +void plm_buffer_discard_read_bytes(plm_buffer_t *self) { + size_t byte_pos = self->bit_index >> 3; + if (byte_pos == self->length) { + self->bit_index = 0; + self->length = 0; + } + else if (byte_pos > 0) { + memmove(self->bytes, self->bytes + byte_pos, self->length - byte_pos); + self->bit_index -= byte_pos << 3; + self->length -= byte_pos; + } +} + +void plm_buffer_load_file_callback(plm_buffer_t *self, void *user) { + plm_buffer_discard_read_bytes(self); + unsigned bytes_available = self->capacity - self->length; + unsigned bytes_read = fread(self->bytes + self->length, 1, bytes_available, self->fh); + self->length += bytes_read; +} diff --git a/dsp/mpeg/buffer.h b/dsp/mpeg/buffer.h new file mode 100644 index 00000000..93838c6c --- /dev/null +++ b/dsp/mpeg/buffer.h @@ -0,0 +1,163 @@ +#ifndef COSMOPOLITAN_DSP_MPEG_BUFFER_H_ +#define COSMOPOLITAN_DSP_MPEG_BUFFER_H_ +#include "dsp/mpeg/mpeg.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct FILE; + +enum plm_buffer_mode { + PLM_BUFFER_MODE_FILE, + PLM_BUFFER_MODE_FIXED_MEM, + PLM_BUFFER_MODE_DYNAMIC_MEM +}; + +typedef struct plm_buffer_t { + unsigned bit_index; + unsigned capacity; + unsigned length; + int free_when_done; + int close_when_done; + struct FILE *fh; + plm_buffer_load_callback load_callback; + void *load_callback_user_data; + unsigned char *bytes; + enum plm_buffer_mode mode; +} plm_buffer_t; + +typedef struct { + int16_t index; + int16_t value; +} plm_vlc_t; + +typedef struct { + int16_t index; + uint16_t value; +} plm_vlc_uint_t; + +/* bool plm_buffer_has(plm_buffer_t *, size_t); */ +/* int plm_buffer_read(plm_buffer_t *, int); */ +/* void plm_buffer_align(plm_buffer_t *); */ +/* void plm_buffer_skip(plm_buffer_t *, size_t); */ +/* int plm_buffer_skip_bytes(plm_buffer_t *, unsigned char); */ +/* int plm_buffer_next_start_code(plm_buffer_t *); */ +/* int plm_buffer_find_start_code(plm_buffer_t *, int); */ +/* int plm_buffer_no_start_code(plm_buffer_t *); */ +/* int16_t plm_buffer_read_vlc(plm_buffer_t *, const plm_vlc_t *); */ +/* uint16_t plm_buffer_read_vlc_uint(plm_buffer_t *, const plm_vlc_uint_t *); */ + +void plm_buffer_discard_read_bytes(plm_buffer_t *); +relegated void plm_buffer_load_file_callback(plm_buffer_t *, void *); + +forceinline bool plm_buffer_has(plm_buffer_t *b, size_t bits) { + unsigned have; + have = b->length; + have <<= 3; + have -= b->bit_index; + if (bits <= have) { + return true; + } else { + if (b->load_callback) { + b->load_callback(b, b->load_callback_user_data); + return ((b->length << 3) - b->bit_index) >= bits; + } else { + return false; + } + } +} + +forceinline int plm_buffer_read(plm_buffer_t *self, int count) { + if (!plm_buffer_has(self, count)) return 0; + int value = 0; + while (count) { + int current_byte = self->bytes[self->bit_index >> 3]; + int remaining = 8 - (self->bit_index & 7); // Remaining bits in byte + int read = remaining < count ? remaining : count; // Bits in self run + int shift = remaining - read; + int mask = (0xff >> (8 - read)); + value = (value << read) | ((current_byte & (mask << shift)) >> shift); + self->bit_index += read; + count -= read; + } + return value; +} + +forceinline void plm_buffer_align(plm_buffer_t *self) { + self->bit_index = ((self->bit_index + 7) >> 3) << 3; +} + +forceinline void plm_buffer_skip(plm_buffer_t *self, size_t count) { + if (plm_buffer_has(self, count)) { + self->bit_index += count; + } +} + +forceinline int plm_buffer_skip_bytes(plm_buffer_t *self, unsigned char v) { + unsigned skipped; + plm_buffer_align(self); + skipped = 0; + while (plm_buffer_has(self, 8)) { + if (v == self->bytes[self->bit_index >> 3]) { + self->bit_index += 8; + ++skipped; + } else { + break; + } + } + return skipped; +} + +forceinline int plm_buffer_next_start_code(plm_buffer_t *self) { + plm_buffer_align(self); + while (plm_buffer_has(self, (5 << 3))) { + size_t byte_index = (self->bit_index) >> 3; + if (self->bytes[byte_index] == 0x00 && + self->bytes[byte_index + 1] == 0x00 && + self->bytes[byte_index + 2] == 0x01) { + self->bit_index = (byte_index + 4) << 3; + return self->bytes[byte_index + 3]; + } + self->bit_index += 8; + } + self->bit_index = (self->length << 3); + return -1; +} + +forceinline int plm_buffer_find_start_code(plm_buffer_t *self, int code) { + int current = 0; + while (true) { + current = plm_buffer_next_start_code(self); + if (current == code || current == -1) { + return current; + } + } + return -1; +} + +forceinline int plm_buffer_no_start_code(plm_buffer_t *self) { + if (!plm_buffer_has(self, (5 << 3))) { + return false; + } + size_t byte_index = ((self->bit_index + 7) >> 3); + return !(self->bytes[byte_index] == 0x00 && + self->bytes[byte_index + 1] == 0x00 && + self->bytes[byte_index + 2] == 0x01); +} + +forceinline int16_t plm_buffer_read_vlc(plm_buffer_t *self, + const plm_vlc_t *table) { + plm_vlc_t state = {0, 0}; + do { + state = table[state.index + plm_buffer_read(self, 1)]; + } while (state.index > 0); + return state.value; +} + +forceinline uint16_t plm_buffer_read_vlc_uint(plm_buffer_t *self, + const plm_vlc_uint_t *table) { + return (uint16_t)plm_buffer_read_vlc(self, (plm_vlc_t *)table); +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_MPEG_BUFFER_H_ */ diff --git a/dsp/mpeg/clamp4int256-core.S b/dsp/mpeg/clamp4int256-core.S new file mode 100644 index 00000000..a4a8753d --- /dev/null +++ b/dsp/mpeg/clamp4int256-core.S @@ -0,0 +1,32 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +clamp4int256$core: + .leafprologue + pxor %xmm1,%xmm1 + pmaxsd %xmm1,%xmm0 + pminsd 0f(%rip),%xmm0 + .leafepilogue + .endfn clamp4int256$core,globl + + .rodata.cst16 +0: .long 255,255,255,255 diff --git a/dsp/mpeg/demux.c b/dsp/mpeg/demux.c new file mode 100644 index 00000000..d4055118 --- /dev/null +++ b/dsp/mpeg/demux.c @@ -0,0 +1,208 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│ +│vi: set et ft=c ts=4 sw=4 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer │ +│ Dominic Szablewski - https://phoboslab.org │ +│ │ +│ The MIT License(MIT) │ +│ Copyright(c) 2019 Dominic Szablewski │ +│ │ +│ Permission is hereby granted, free of charge, to any person obtaining │ +│ a copy of this software and associated documentation files(the │ +│ "Software"), to deal in the Software without restriction, including │ +│ without limitation the rights to use, copy, modify, merge, publish, │ +│ distribute, sublicense, and / or sell copies of the Software, and to │ +│ permit persons to whom the Software is furnished to do so, subject to │ +│ the following conditions: │ +│ │ +│ The above copyright notice and this permission notice shall be │ +│ included in all copies or substantial portions of the Software. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │ +│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │ +│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND │ +│ NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE │ +│ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN │ +│ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN │ +│ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE │ +│ SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/mpeg/buffer.h" +#include "dsp/mpeg/demux.h" +#include "dsp/mpeg/mpeg.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" + +asm(".ident\t\"\\n\\n\ +PL_MPEG (MIT License)\\n\ +Copyright(c) 2019 Dominic Szablewski\\n\ +https://phoboslab.org\""); +asm(".include \"libc/disclaimer.inc\""); + +/* clang-format off */ +// ---------------------------------------------------------------------------- +// plm_demux implementation + +plm_demux_t *plm_demux_create(plm_buffer_t *buffer, int destroy_when_done) { + plm_demux_t *self = (plm_demux_t *)malloc(sizeof(plm_demux_t)); + memset(self, 0, sizeof(plm_demux_t)); + + self->buffer = buffer; + self->destroy_buffer_when_done = destroy_when_done; + + if (plm_buffer_find_start_code(self->buffer, START_PACK) != -1) { + plm_demux_decode_pack_header(self); + } + if (plm_buffer_find_start_code(self->buffer, START_SYSTEM) != -1) { + plm_demux_decode_system_header(self); + } + return self; +} + +void plm_demux_destroy(plm_demux_t *self) { + if (self->destroy_buffer_when_done) { + plm_buffer_destroy(self->buffer); + } + free(self); +} + +int plm_demux_get_num_video_streams(plm_demux_t *self) { + return self->num_video_streams; +} + +int plm_demux_get_num_audio_streams(plm_demux_t *self) { + return self->num_audio_streams; +} + +void plm_demux_rewind(plm_demux_t *self) { + plm_buffer_rewind(self->buffer); +} + +plm_packet_t *plm_demux_decode(plm_demux_t *self) { + if (self->current_packet.length) { + size_t bits_till_next_packet = self->current_packet.length << 3; + if (!plm_buffer_has(self->buffer, bits_till_next_packet)) { + return NULL; + } + plm_buffer_skip(self->buffer, bits_till_next_packet); + self->current_packet.length = 0; + } + + if (!self->has_pack_header) { + if (plm_buffer_find_start_code(self->buffer, START_PACK) != -1) { + plm_demux_decode_pack_header(self); + } + else { + return NULL; + } + } + + if (!self->has_system_header) { + if (plm_buffer_find_start_code(self->buffer, START_SYSTEM) != -1) { + plm_demux_decode_system_header(self); + } + else { + return NULL; + } + } + + // pending packet just waiting for data? + if (self->next_packet.length) { + return plm_demux_get_packet(self); + } + + int code; + do { + code = plm_buffer_next_start_code(self->buffer); + if ( + code == PLM_DEMUX_PACKET_VIDEO_1 || + code == PLM_DEMUX_PACKET_PRIVATE || + (code >= PLM_DEMUX_PACKET_AUDIO_1 && code <= PLM_DEMUX_PACKET_AUDIO_4) + ) { + return plm_demux_decode_packet(self, code); + } + } while (code != -1); + + return NULL; +} + +double plm_demux_read_time(plm_demux_t *self) { + int64_t clock = plm_buffer_read(self->buffer, 3) << 30; + plm_buffer_skip(self->buffer, 1); + clock |= plm_buffer_read(self->buffer, 15) << 15; + plm_buffer_skip(self->buffer, 1); + clock |= plm_buffer_read(self->buffer, 15); + plm_buffer_skip(self->buffer, 1); + return (double)clock / 90000.0; +} + +void plm_demux_decode_pack_header(plm_demux_t *self) { + if (plm_buffer_read(self->buffer, 4) != 0x02) { + return; // invalid + } + self->system_clock_ref = plm_demux_read_time(self); + plm_buffer_skip(self->buffer, 1); + plm_buffer_skip(self->buffer, 22); // mux_rate * 50 + plm_buffer_skip(self->buffer, 1); + + self->has_pack_header = true; +} + +void plm_demux_decode_system_header(plm_demux_t *self) { + plm_buffer_skip(self->buffer, 16); // header_length + plm_buffer_skip(self->buffer, 24); // rate bound + self->num_audio_streams = plm_buffer_read(self->buffer, 6); + plm_buffer_skip(self->buffer, 5); // misc flags + self->num_video_streams = plm_buffer_read(self->buffer, 5); + + self->has_system_header = true; +} + +plm_packet_t *plm_demux_decode_packet(plm_demux_t *self, int start_code) { + if (!plm_buffer_has(self->buffer, 8 << 3)) { + return NULL; + } + + self->next_packet.type = start_code; + self->next_packet.length = plm_buffer_read(self->buffer, 16); + self->next_packet.length -= plm_buffer_skip_bytes(self->buffer, 0xff); // stuffing + + // skip P-STD + if (plm_buffer_read(self->buffer, 2) == 0x01) { + plm_buffer_skip(self->buffer, 16); + self->next_packet.length -= 2; + } + + int pts_dts_marker = plm_buffer_read(self->buffer, 2); + if (pts_dts_marker == 0x03) { + self->next_packet.pts = plm_demux_read_time(self); + plm_buffer_skip(self->buffer, 40); // skip dts + self->next_packet.length -= 10; + } + else if (pts_dts_marker == 0x02) { + self->next_packet.pts = plm_demux_read_time(self); + self->next_packet.length -= 5; + } + else if (pts_dts_marker == 0x00) { + self->next_packet.pts = 0; + plm_buffer_skip(self->buffer, 4); + self->next_packet.length -= 1; + } + else { + return NULL; // invalid + } + + return plm_demux_get_packet(self); +} + +plm_packet_t *plm_demux_get_packet(plm_demux_t *self) { + if (!plm_buffer_has(self->buffer, self->next_packet.length << 3)) { + return NULL; + } + self->current_packet.data = self->buffer->bytes + (self->buffer->bit_index >> 3); + self->current_packet.length = self->next_packet.length; + self->current_packet.type = self->next_packet.type; + self->current_packet.pts = self->next_packet.pts; + self->next_packet.length = 0; + return &self->current_packet; +} diff --git a/dsp/mpeg/demux.h b/dsp/mpeg/demux.h new file mode 100644 index 00000000..892c5222 --- /dev/null +++ b/dsp/mpeg/demux.h @@ -0,0 +1,31 @@ +#ifndef COSMOPOLITAN_DSP_MPEG_DEMUX_H_ +#define COSMOPOLITAN_DSP_MPEG_DEMUX_H_ +#include "dsp/mpeg/mpeg.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define START_PACK 0xBA +#define START_END 0xB9 +#define START_SYSTEM 0xBB + +typedef struct plm_demux_t { + plm_buffer_t *buffer; + int destroy_buffer_when_done; + double system_clock_ref; + int has_pack_header; + int has_system_header; + int num_audio_streams; + int num_video_streams; + plm_packet_t current_packet; + plm_packet_t next_packet; +} plm_demux_t; + +double plm_demux_read_time(plm_demux_t *self); +void plm_demux_decode_pack_header(plm_demux_t *self); +void plm_demux_decode_system_header(plm_demux_t *self); +plm_packet_t *plm_demux_decode_packet(plm_demux_t *self, int start_code); +plm_packet_t *plm_demux_get_packet(plm_demux_t *self); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_MPEG_DEMUX_H_ */ diff --git a/dsp/mpeg/idct.c b/dsp/mpeg/idct.c new file mode 100644 index 00000000..f8c3858d --- /dev/null +++ b/dsp/mpeg/idct.c @@ -0,0 +1,106 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│ +│vi: set et ft=c ts=4 sw=4 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer │ +│ Dominic Szablewski - https://phoboslab.org │ +│ │ +│ The MIT License(MIT) │ +│ Copyright(c) 2019 Dominic Szablewski │ +│ │ +│ Permission is hereby granted, free of charge, to any person obtaining │ +│ a copy of this software and associated documentation files(the │ +│ "Software"), to deal in the Software without restriction, including │ +│ without limitation the rights to use, copy, modify, merge, publish, │ +│ distribute, sublicense, and / or sell copies of the Software, and to │ +│ permit persons to whom the Software is furnished to do so, subject to │ +│ the following conditions: │ +│ │ +│ The above copyright notice and this permission notice shall be │ +│ included in all copies or substantial portions of the Software. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │ +│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │ +│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND │ +│ NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE │ +│ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN │ +│ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN │ +│ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE │ +│ SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/half.h" + +asm(".ident\t\"\\n\\n\ +PL_MPEG (MIT License)\\n\ +Copyright(c) 2019 Dominic Szablewski\\n\ +https://phoboslab.org\""); +asm(".include \"libc/disclaimer.inc\""); + +/** + * Computes Fixed-Point 8x8 Inverse Discrete Cosine Transform. + * + * @note discovered by Nasir Ahmed + */ +void plm_video_idct(int block[8][8]) { + int i, j, t1, t2, m0; + int b1, b3, b4, b6, b7; + int y3, y4, y5, y6, y7; + int x0, x1, x2, x3, x4; + + for (i = 0; i < 8; ++i) { + b1 = block[4][i]; + b3 = block[2][i] + block[6][i]; + b4 = block[5][i] - block[3][i]; + t1 = block[1][i] + block[7][i]; + t2 = block[3][i] + block[5][i]; + b6 = block[1][i] - block[7][i]; + b7 = t1 + t2; + m0 = block[0][i]; + x4 = ((b6 * 473 - b4 * 196 + 128) >> 8) - b7; + x0 = x4 - (((t1 - t2) * 362 + 128) >> 8); + x1 = m0 - b1; + x2 = (((block[2][i] - block[6][i]) * 362 + 128) >> 8) - b3; + x3 = m0 + b1; + y3 = x1 + x2; + y4 = x3 + b3; + y5 = x1 - x2; + y6 = x3 - b3; + y7 = -x0 - ((b4 * 473 + b6 * 196 + 128) >> 8); + block[0][i] = b7 + y4; + block[1][i] = x4 + y3; + block[2][i] = y5 - x0; + block[3][i] = y6 - y7; + block[4][i] = y6 + y7; + block[5][i] = x0 + y5; + block[6][i] = y3 - x4; + block[7][i] = y4 - b7; + } + + for (i = 0; i < 8; ++i) { + b1 = block[i][4]; + b3 = block[i][2] + block[i][6]; + b4 = block[i][5] - block[i][3]; + t1 = block[i][1] + block[i][7]; + t2 = block[i][3] + block[i][5]; + b6 = block[i][1] - block[i][7]; + b7 = t1 + t2; + m0 = block[i][0]; + x4 = ((b6 * 473 - b4 * 196 + 128) >> 8) - b7; + x0 = x4 - (((t1 - t2) * 362 + 128) >> 8); + x1 = m0 - b1; + x2 = (((block[i][2] - block[i][6]) * 362 + 128) >> 8) - b3; + x3 = m0 + b1; + y3 = x1 + x2; + y4 = x3 + b3; + y5 = x1 - x2; + y6 = x3 - b3; + y7 = -x0 - ((b4 * 473 + b6 * 196 + 128) >> 8); + block[i][0] = (b7 + y4 + 128) >> 8; + block[i][1] = (x4 + y3 + 128) >> 8; + block[i][2] = (y5 - x0 + 128) >> 8; + block[i][3] = (y6 - y7 + 128) >> 8; + block[i][4] = (y6 + y7 + 128) >> 8; + block[i][5] = (x0 + y5 + 128) >> 8; + block[i][6] = (y3 - x4 + 128) >> 8; + block[i][7] = (y4 - b7 + 128) >> 8; + } +} diff --git a/dsp/mpeg/idct.h b/dsp/mpeg/idct.h new file mode 100644 index 00000000..6c64f969 --- /dev/null +++ b/dsp/mpeg/idct.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_DSP_MPEG_IDCT_H_ +#define COSMOPOLITAN_DSP_MPEG_IDCT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +void plm_video_idct(int *); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_MPEG_IDCT_H_ */ diff --git a/dsp/mpeg/macroblock.c b/dsp/mpeg/macroblock.c new file mode 100644 index 00000000..fb49260f --- /dev/null +++ b/dsp/mpeg/macroblock.c @@ -0,0 +1,171 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│ +│vi: set et ft=c ts=4 sw=4 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer │ +│ Dominic Szablewski - https://phoboslab.org │ +│ │ +│ The MIT License(MIT) │ +│ Copyright(c) 2019 Dominic Szablewski │ +│ │ +│ Permission is hereby granted, free of charge, to any person obtaining │ +│ a copy of this software and associated documentation files(the │ +│ "Software"), to deal in the Software without restriction, including │ +│ without limitation the rights to use, copy, modify, merge, publish, │ +│ distribute, sublicense, and / or sell copies of the Software, and to │ +│ permit persons to whom the Software is furnished to do so, subject to │ +│ the following conditions: │ +│ │ +│ The above copyright notice and this permission notice shall be │ +│ included in all copies or substantial portions of the Software. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │ +│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │ +│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND │ +│ NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE │ +│ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN │ +│ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN │ +│ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE │ +│ SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/mpeg/mpeg.h" +#include "dsp/mpeg/video.h" +#include "libc/log/check.h" + +forceinline void plm_video_process_macroblock(plm_video_t *self, + uint8_t *restrict d, + uint8_t *restrict s, int motion_h, + int motion_v, bool interpolate, + unsigned BW) { + unsigned si, di, max_address; + int y, x, dest_scan, source_scan, dw, hp, vp, odd_h, odd_v; + dw = self->mb_width * BW; + hp = motion_h >> 1; + vp = motion_v >> 1; + odd_h = (motion_h & 1) == 1; + odd_v = (motion_v & 1) == 1; + si = ((self->mb_row * BW) + vp) * dw + (self->mb_col * BW) + hp; + di = (self->mb_row * dw + self->mb_col) * BW; + max_address = (dw * (self->mb_height * BW - BW + 1) - BW); + if (si > max_address || di > max_address) return; + d += di; + s += si; + switch (((interpolate << 2) | (odd_h << 1) | (odd_v)) & 7) { + case 0: + dest_scan = dw - BW; + source_scan = dw - BW; + for (y = 0; y < BW; y++) { + for (x = 0; x < BW; x++) { + *d++ = *s++; + } + s += source_scan; + d += dest_scan; + } + break; + case 1: + dest_scan = dw - BW; + source_scan = dw - BW; + for (y = 0; y < BW; y++) { + for (x = 0; x < BW; x++) { + *d++ = (s[0] + s[dw] + 1) >> 1; + s++; + } + s += source_scan; + d += dest_scan; + } + break; + case 2: + dest_scan = dw - BW; + source_scan = dw - BW; + for (y = 0; y < BW; y++) { + for (x = 0; x < BW; x++) { + *d++ = (s[0] + s[1] + 1) >> 1; + s++; + } + s += source_scan; + d += dest_scan; + } + break; + case 3: + dest_scan = dw - BW; + source_scan = dw - BW; + for (y = 0; y < BW; y++) { + for (x = 0; x < BW; x++) { + *d++ = (s[0] + s[1] + s[dw] + s[dw + 1] + 2) >> 2; + s++; + } + s += source_scan; + d += dest_scan; + } + break; + case 4: + dest_scan = dw - BW; + source_scan = dw - BW; + for (y = 0; y < BW; y++) { + for (x = 0; x < BW; x++) { + d[0] = (d[0] + (s[0]) + 1) >> 1; + d++; + s++; + } + s += source_scan; + d += dest_scan; + } + break; + case 5: + dest_scan = dw - BW; + source_scan = dw - BW; + for (y = 0; y < BW; y++) { + for (x = 0; x < BW; x++) { + d[0] = (d[0] + ((s[0] + s[dw] + 1) >> 1) + 1) >> 1; + d++; + s++; + } + s += source_scan; + d += dest_scan; + } + break; + case 6: + dest_scan = dw - BW; + source_scan = dw - BW; + for (y = 0; y < BW; y++) { + for (x = 0; x < BW; x++) { + d[0] = (d[0] + ((s[0] + s[1] + 1) >> 1) + 1) >> 1; + d++; + s++; + } + s += source_scan; + d += dest_scan; + } + break; + case 7: + dest_scan = dw - BW; + source_scan = dw - BW; + for (y = 0; y < BW; y++) { + for (x = 0; x < BW; x++) { + d[0] = (d[0] + ((s[0] + s[1] + s[dw] + s[dw + 1] + 2) >> 2) + 1) >> 1; + d++; + s++; + } + s += source_scan; + d += dest_scan; + } + break; + default: + break; + } +} + +void plm_video_process_macroblock_8(plm_video_t *self, uint8_t *restrict d, + uint8_t *restrict s, int motion_h, + int motion_v, bool interpolate) { + DCHECK_ALIGNED(8, d); + DCHECK_ALIGNED(8, s); + plm_video_process_macroblock(self, d, s, motion_h, motion_v, interpolate, 8); +} + +void plm_video_process_macroblock_16(plm_video_t *self, uint8_t *restrict d, + uint8_t *restrict s, int motion_h, + int motion_v, bool interpolate) { + DCHECK_ALIGNED(16, d); + DCHECK_ALIGNED(16, s); + plm_video_process_macroblock(self, d, s, motion_h, motion_v, interpolate, 16); +} diff --git a/dsp/mpeg/mp2.c b/dsp/mpeg/mp2.c new file mode 100644 index 00000000..d9c8f88e --- /dev/null +++ b/dsp/mpeg/mp2.c @@ -0,0 +1,775 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│ +│vi: set et ft=c ts=4 sw=4 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer │ +│ Dominic Szablewski - https://phoboslab.org │ +│ │ +│ The MIT License(MIT) │ +│ Copyright(c) 2019 Dominic Szablewski │ +│ │ +│ Permission is hereby granted, free of charge, to any person obtaining │ +│ a copy of this software and associated documentation files(the │ +│ "Software"), to deal in the Software without restriction, including │ +│ without limitation the rights to use, copy, modify, merge, publish, │ +│ distribute, sublicense, and / or sell copies of the Software, and to │ +│ permit persons to whom the Software is furnished to do so, subject to │ +│ the following conditions: │ +│ │ +│ The above copyright notice and this permission notice shall be │ +│ included in all copies or substantial portions of the Software. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │ +│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │ +│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND │ +│ NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE │ +│ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN │ +│ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN │ +│ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE │ +│ SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/mpeg/buffer.h" +#include "dsp/mpeg/mpeg.h" +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" + +asm(".ident\t\"\\n\\n\ +PL_MPEG (MIT License)\\n\ +Copyright(c) 2019 Dominic Szablewski\\n\ +https://phoboslab.org\""); +asm(".include \"libc/disclaimer.inc\""); + +/* clang-format off */ +// ----------------------------------------------------------------------------- +// plm_audio implementation + +// Based on kjmp2 by Martin J. Fiedler +// http://keyj.emphy.de/kjmp2/ + +#define PLM_AUDIO_FRAME_SYNC 0x7ff + +#define PLM_AUDIO_MPEG_2_5 0x0 +#define PLM_AUDIO_MPEG_2 0x2 +#define PLM_AUDIO_MPEG_1 0x3 + +#define PLM_AUDIO_LAYER_III 0x1 +#define PLM_AUDIO_LAYER_II 0x2 +#define PLM_AUDIO_LAYER_I 0x3 + +#define PLM_AUDIO_MODE_STEREO 0x0 +#define PLM_AUDIO_MODE_JOINT_STEREO 0x1 +#define PLM_AUDIO_MODE_DUAL_CHANNEL 0x2 +#define PLM_AUDIO_MODE_MONO 0x3 + +static const unsigned short PLM_AUDIO_SAMPLE_RATE[] = { + 44100, 48000, 32000, 0, // MPEG-1 + 22050, 24000, 16000, 0 // MPEG-2 +}; + +static const short PLM_AUDIO_BIT_RATE[] = { + 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, // MPEG-1 + 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 // MPEG-2 +}; + +static const int PLM_AUDIO_SCALEFACTOR_BASE[] = { + 0x02000000, 0x01965FEA, 0x01428A30 +}; + +static const float PLM_AUDIO_SYNTHESIS_WINDOW[] = { + 0.0, -0.5, -0.5, -0.5, -0.5, -0.5, + -0.5, -1.0, -1.0, -1.0, -1.0, -1.5, + -1.5, -2.0, -2.0, -2.5, -2.5, -3.0, + -3.5, -3.5, -4.0, -4.5, -5.0, -5.5, + -6.5, -7.0, -8.0, -8.5, -9.5, -10.5, + -12.0, -13.0, -14.5, -15.5, -17.5, -19.0, + -20.5, -22.5, -24.5, -26.5, -29.0, -31.5, + -34.0, -36.5, -39.5, -42.5, -45.5, -48.5, + -52.0, -55.5, -58.5, -62.5, -66.0, -69.5, + -73.5, -77.0, -80.5, -84.5, -88.0, -91.5, + -95.0, -98.0, -101.0, -104.0, 106.5, 109.0, + 111.0, 112.5, 113.5, 114.0, 114.0, 113.5, + 112.0, 110.5, 107.5, 104.0, 100.0, 94.5, + 88.5, 81.5, 73.0, 63.5, 53.0, 41.5, + 28.5, 14.5, -1.0, -18.0, -36.0, -55.5, + -76.5, -98.5, -122.0, -147.0, -173.5, -200.5, + -229.5, -259.5, -290.5, -322.5, -355.5, -389.5, + -424.0, -459.5, -495.5, -532.0, -568.5, -605.0, + -641.5, -678.0, -714.0, -749.0, -783.5, -817.0, + -849.0, -879.5, -908.5, -935.0, -959.5, -981.0, + -1000.5, -1016.0, -1028.5, -1037.5, -1042.5, -1043.5, + -1040.0, -1031.5, 1018.5, 1000.0, 976.0, 946.5, + 911.0, 869.5, 822.0, 767.5, 707.0, 640.0, + 565.5, 485.0, 397.0, 302.5, 201.0, 92.5, + -22.5, -144.0, -272.5, -407.0, -547.5, -694.0, + -846.0, -1003.0, -1165.0, -1331.5, -1502.0, -1675.5, + -1852.5, -2031.5, -2212.5, -2394.0, -2576.5, -2758.5, + -2939.5, -3118.5, -3294.5, -3467.5, -3635.5, -3798.5, + -3955.0, -4104.5, -4245.5, -4377.5, -4499.0, -4609.5, + -4708.0, -4792.5, -4863.5, -4919.0, -4958.0, -4979.5, + -4983.0, -4967.5, -4931.5, -4875.0, -4796.0, -4694.5, + -4569.5, -4420.0, -4246.0, -4046.0, -3820.0, -3567.0, + 3287.0, 2979.5, 2644.0, 2280.5, 1888.0, 1467.5, + 1018.5, 541.0, 35.0, -499.0, -1061.0, -1650.0, + -2266.5, -2909.0, -3577.0, -4270.0, -4987.5, -5727.5, + -6490.0, -7274.0, -8077.5, -8899.5, -9739.0, -10594.5, + -11464.5, -12347.0, -13241.0, -14144.5, -15056.0, -15973.5, + -16895.5, -17820.0, -18744.5, -19668.0, -20588.0, -21503.0, + -22410.5, -23308.5, -24195.0, -25068.5, -25926.5, -26767.0, + -27589.0, -28389.0, -29166.5, -29919.0, -30644.5, -31342.0, + -32009.5, -32645.0, -33247.0, -33814.5, -34346.0, -34839.5, + -35295.0, -35710.0, -36084.5, -36417.5, -36707.5, -36954.0, + -37156.5, -37315.0, -37428.0, -37496.0, 37519.0, 37496.0, + 37428.0, 37315.0, 37156.5, 36954.0, 36707.5, 36417.5, + 36084.5, 35710.0, 35295.0, 34839.5, 34346.0, 33814.5, + 33247.0, 32645.0, 32009.5, 31342.0, 30644.5, 29919.0, + 29166.5, 28389.0, 27589.0, 26767.0, 25926.5, 25068.5, + 24195.0, 23308.5, 22410.5, 21503.0, 20588.0, 19668.0, + 18744.5, 17820.0, 16895.5, 15973.5, 15056.0, 14144.5, + 13241.0, 12347.0, 11464.5, 10594.5, 9739.0, 8899.5, + 8077.5, 7274.0, 6490.0, 5727.5, 4987.5, 4270.0, + 3577.0, 2909.0, 2266.5, 1650.0, 1061.0, 499.0, + -35.0, -541.0, -1018.5, -1467.5, -1888.0, -2280.5, + -2644.0, -2979.5, 3287.0, 3567.0, 3820.0, 4046.0, + 4246.0, 4420.0, 4569.5, 4694.5, 4796.0, 4875.0, + 4931.5, 4967.5, 4983.0, 4979.5, 4958.0, 4919.0, + 4863.5, 4792.5, 4708.0, 4609.5, 4499.0, 4377.5, + 4245.5, 4104.5, 3955.0, 3798.5, 3635.5, 3467.5, + 3294.5, 3118.5, 2939.5, 2758.5, 2576.5, 2394.0, + 2212.5, 2031.5, 1852.5, 1675.5, 1502.0, 1331.5, + 1165.0, 1003.0, 846.0, 694.0, 547.5, 407.0, + 272.5, 144.0, 22.5, -92.5, -201.0, -302.5, + -397.0, -485.0, -565.5, -640.0, -707.0, -767.5, + -822.0, -869.5, -911.0, -946.5, -976.0, -1000.0, + 1018.5, 1031.5, 1040.0, 1043.5, 1042.5, 1037.5, + 1028.5, 1016.0, 1000.5, 981.0, 959.5, 935.0, + 908.5, 879.5, 849.0, 817.0, 783.5, 749.0, + 714.0, 678.0, 641.5, 605.0, 568.5, 532.0, + 495.5, 459.5, 424.0, 389.5, 355.5, 322.5, + 290.5, 259.5, 229.5, 200.5, 173.5, 147.0, + 122.0, 98.5, 76.5, 55.5, 36.0, 18.0, + 1.0, -14.5, -28.5, -41.5, -53.0, -63.5, + -73.0, -81.5, -88.5, -94.5, -100.0, -104.0, + -107.5, -110.5, -112.0, -113.5, -114.0, -114.0, + -113.5, -112.5, -111.0, -109.0, 106.5, 104.0, + 101.0, 98.0, 95.0, 91.5, 88.0, 84.5, + 80.5, 77.0, 73.5, 69.5, 66.0, 62.5, + 58.5, 55.5, 52.0, 48.5, 45.5, 42.5, + 39.5, 36.5, 34.0, 31.5, 29.0, 26.5, + 24.5, 22.5, 20.5, 19.0, 17.5, 15.5, + 14.5, 13.0, 12.0, 10.5, 9.5, 8.5, + 8.0, 7.0, 6.5, 5.5, 5.0, 4.5, + 4.0, 3.5, 3.5, 3.0, 2.5, 2.5, + 2.0, 2.0, 1.5, 1.5, 1.0, 1.0, + 1.0, 1.0, 0.5, 0.5, 0.5, 0.5, + 0.5, 0.5 +}; + +// Quantizer lookup, step 1: bitrate classes +static const uint8_t PLM_AUDIO_QUANT_LUT_STEP_1[2][16] = { + // 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384 <- bitrate + { 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, // mono + // 16, 24, 28, 32, 40, 48, 56, 64, 80, 96,112,128,160,192 <- bitrate / chan + { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2 } // stereo +}; + +// Quantizer lookup, step 2: bitrate class, sample rate -> B2 table idx, sblimit +static const uint8_t PLM_AUDIO_QUANT_TAB_A = (27 | 64); // Table 3-B.2a: high-rate, sblimit = 27 +static const uint8_t PLM_AUDIO_QUANT_TAB_B = (30 | 64); // Table 3-B.2b: high-rate, sblimit = 30 +static const uint8_t PLM_AUDIO_QUANT_TAB_C = 8; // Table 3-B.2c: low-rate, sblimit = 8 +static const uint8_t PLM_AUDIO_QUANT_TAB_D = 12; // Table 3-B.2d: low-rate, sblimit = 12 + +static const uint8_t QUANT_LUT_STEP_2[3][3] = { + // 44.1 kHz, 48 kHz, 32 kHz + { PLM_AUDIO_QUANT_TAB_C, PLM_AUDIO_QUANT_TAB_C, PLM_AUDIO_QUANT_TAB_D }, // 32 - 48 kbit/sec/ch + { PLM_AUDIO_QUANT_TAB_A, PLM_AUDIO_QUANT_TAB_A, PLM_AUDIO_QUANT_TAB_A }, // 56 - 80 kbit/sec/ch + { PLM_AUDIO_QUANT_TAB_B, PLM_AUDIO_QUANT_TAB_A, PLM_AUDIO_QUANT_TAB_B } // 96+ kbit/sec/ch +}; + +// Quantizer lookup, step 3: B2 table, subband -> nbal, row index +// (upper 4 bits: nbal, lower 4 bits: row index) +static const uint8_t PLM_AUDIO_QUANT_LUT_STEP_3[3][32] = { + // Low-rate table (3-B.2c and 3-B.2d) + { + 0x44,0x44, + 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34 + }, + // High-rate table (3-B.2a and 3-B.2b) + { + 0x43,0x43,0x43, + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42, + 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20 + }, + // MPEG-2 LSR table (B.2 in ISO 13818-3) + { + 0x45,0x45,0x45,0x45, + 0x34,0x34,0x34,0x34,0x34,0x34,0x34, + 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24, + 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24 + } +}; + +// Quantizer lookup, step 4: table row, allocation[] value -> quant table index +static const uint8_t PLM_AUDIO_QUANT_LUT_STEP4[6][16] = { + { 0, 1, 2, 17 }, + { 0, 1, 2, 3, 4, 5, 6, 17 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17 }, + { 0, 1, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }, + { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } +}; + +typedef struct plm_quantizer_spec_t { + unsigned short levels; + unsigned char group; + unsigned char bits; +} plm_quantizer_spec_t; + +static const plm_quantizer_spec_t PLM_AUDIO_QUANT_TAB[] = { + { 3, 1, 5 }, // 1 + { 5, 1, 7 }, // 2 + { 7, 0, 3 }, // 3 + { 9, 1, 10 }, // 4 + { 15, 0, 4 }, // 5 + { 31, 0, 5 }, // 6 + { 63, 0, 6 }, // 7 + { 127, 0, 7 }, // 8 + { 255, 0, 8 }, // 9 + { 511, 0, 9 }, // 10 + { 1023, 0, 10 }, // 11 + { 2047, 0, 11 }, // 12 + { 4095, 0, 12 }, // 13 + { 8191, 0, 13 }, // 14 + { 16383, 0, 14 }, // 15 + { 32767, 0, 15 }, // 16 + { 65535, 0, 16 } // 17 +}; + +struct plm_audio_t { + double time; + int samples_decoded; + int samplerate_index; + int bitrate_index; + int version; + int layer; + int mode; + int bound; + int v_pos; + int next_frame_data_size; + plm_buffer_t *buffer; + int destroy_buffer_when_done; + const plm_quantizer_spec_t *allocation[2][32]; + uint8_t scale_factor_info[2][32]; + int scale_factor[2][32][3]; + int sample[2][32][3]; + plm_samples_t samples; + float D[1024]; + float V[1024]; + float U[32]; +} aligned(64); + +typedef plm_audio_t plm_audio_t; + +int plm_audio_decode_header(plm_audio_t *self); +void plm_audio_decode_frame(plm_audio_t *self); +const plm_quantizer_spec_t *plm_audio_read_allocation(plm_audio_t *self, int sb, int tab3); +void plm_audio_read_samples(plm_audio_t *self, int ch, int sb, int part); +void plm_audio_matrix_transform(int s[32][3], int ss, float *d, int dp); + +plm_audio_t *plm_audio_create_with_buffer(plm_buffer_t *buffer, int destroy_when_done) { + plm_audio_t *self = (plm_audio_t *)memalign(alignof(plm_audio_t), sizeof(plm_audio_t)); + memset(self, 0, sizeof(plm_audio_t)); + + self->samples.count = PLM_AUDIO_SAMPLES_PER_FRAME; + self->buffer = buffer; + self->destroy_buffer_when_done = destroy_when_done; + self->samplerate_index = 3; // indicates 0 samplerate + + memcpy(self->D, PLM_AUDIO_SYNTHESIS_WINDOW, 512 * sizeof(float)); + memcpy(self->D + 512, PLM_AUDIO_SYNTHESIS_WINDOW, 512 * sizeof(float)); + + // Decode first header + if (plm_buffer_has(self->buffer, 48)) { + self->next_frame_data_size = plm_audio_decode_header(self); + } + + return self; +} + +void plm_audio_destroy(plm_audio_t *self) { + if (self->destroy_buffer_when_done) { + plm_buffer_destroy(self->buffer); + } + free(self); +} + +int plm_audio_get_samplerate(plm_audio_t *self) { + return PLM_AUDIO_SAMPLE_RATE[self->samplerate_index]; +} + +double plm_audio_get_time(plm_audio_t *self) { + return self->time; +} + +void plm_audio_rewind(plm_audio_t *self) { + plm_buffer_rewind(self->buffer); + self->time = 0; + self->samples_decoded = 0; + self->next_frame_data_size = 0; + + // TODO: needed? + memset(self->V, 0, sizeof(self->V)); + memset(self->U, 0, sizeof(self->U)); +} + +plm_samples_t *plm_audio_decode(plm_audio_t *self) { + DEBUGF("%s", "plm_audio_decode"); + // Do we have at least enough information to decode the frame header? + if (!self->next_frame_data_size) { + if (!plm_buffer_has(self->buffer, 48)) { + return NULL; + } + self->next_frame_data_size = plm_audio_decode_header(self); + } + + if ( + self->next_frame_data_size == 0 || + !plm_buffer_has(self->buffer, self->next_frame_data_size << 3) + ) { + return NULL; + } + + plm_audio_decode_frame(self); + self->next_frame_data_size = 0; + + self->samples.time = self->time; + + self->samples_decoded += PLM_AUDIO_SAMPLES_PER_FRAME; + self->time = (double)self->samples_decoded / + (double)PLM_AUDIO_SAMPLE_RATE[self->samplerate_index]; + + return &self->samples; +} + +int plm_audio_decode_header(plm_audio_t *self) { + // Check for valid header: syncword OK, MPEG-Audio Layer 2 + plm_buffer_skip_bytes(self->buffer, 0x00); + + int sync = plm_buffer_read(self->buffer, 11); + self->version = plm_buffer_read(self->buffer, 2); + self->layer = plm_buffer_read(self->buffer, 2); + int hasCRC = !plm_buffer_read(self->buffer, 1); + + if ( + sync != PLM_AUDIO_FRAME_SYNC || + self->version != PLM_AUDIO_MPEG_1 || + self->layer != PLM_AUDIO_LAYER_II + ) { + return false; // Invalid header or unsupported version + } + + self->bitrate_index = plm_buffer_read(self->buffer, 4) - 1; + if (self->bitrate_index > 13) { + return false; // Invalid bit rate or 'free format' + } + + self->samplerate_index = plm_buffer_read(self->buffer, 2); + if (self->samplerate_index == 3) { + return false; // Invalid sample rate + } + + if (self->version == PLM_AUDIO_MPEG_2) { + self->samplerate_index += 4; + self->bitrate_index += 14; + } + int padding = plm_buffer_read(self->buffer, 1); + plm_buffer_skip(self->buffer, 1); // f_private + self->mode = plm_buffer_read(self->buffer, 2); + + // Parse the mode_extension, set up the stereo bound + self->bound = 0; + if (self->mode == PLM_AUDIO_MODE_JOINT_STEREO) { + self->bound = (plm_buffer_read(self->buffer, 2) + 1) << 2; + } + else { + plm_buffer_skip(self->buffer, 2); + self->bound = (self->mode == PLM_AUDIO_MODE_MONO) ? 0 : 32; + } + + // Discard the last 4 bits of the header and the CRC value, if present + plm_buffer_skip(self->buffer, 4); + if (hasCRC) { + plm_buffer_skip(self->buffer, 16); + } + + // Compute frame size, check if we have enough data to decode the whole + // frame. + int bitrate = PLM_AUDIO_BIT_RATE[self->bitrate_index]; + int samplerate = PLM_AUDIO_SAMPLE_RATE[self->samplerate_index]; + int frame_size = (144000 * bitrate / samplerate) + padding; + return frame_size - (hasCRC ? 6 : 4); +} + +void plm_audio_decode_frame(plm_audio_t *self) { + // Prepare the quantizer table lookups + int tab3 = 0; + int sblimit = 0; + if (self->version == PLM_AUDIO_MPEG_2) { + // MPEG-2 (LSR) + tab3 = 2; + sblimit = 30; + } + else { + // MPEG-1 + int tab1 = (self->mode == PLM_AUDIO_MODE_MONO) ? 0 : 1; + int tab2 = PLM_AUDIO_QUANT_LUT_STEP_1[tab1][self->bitrate_index]; + tab3 = QUANT_LUT_STEP_2[tab2][self->samplerate_index]; + sblimit = tab3 & 63; + tab3 >>= 6; + } + + if (self->bound > sblimit) { + self->bound = sblimit; + } + + // Read the allocation information + for (int sb = 0; sb < self->bound; sb++) { + self->allocation[0][sb] = plm_audio_read_allocation(self, sb, tab3); + self->allocation[1][sb] = plm_audio_read_allocation(self, sb, tab3); + } + + for (int sb = self->bound; sb < sblimit; sb++) { + self->allocation[0][sb] = + self->allocation[1][sb] = + plm_audio_read_allocation(self, sb, tab3); + } + + // Read scale factor selector information + int channels = (self->mode == PLM_AUDIO_MODE_MONO) ? 1 : 2; + for (int sb = 0; sb < sblimit; sb++) { + for (int ch = 0; ch < channels; ch++) { + if (self->allocation[ch][sb]) { + self->scale_factor_info[ch][sb] = plm_buffer_read(self->buffer, 2); + } + } + if (self->mode == PLM_AUDIO_MODE_MONO) { + self->scale_factor_info[1][sb] = self->scale_factor_info[0][sb]; + } + } + + // Read scale factors + for (int sb = 0; sb < sblimit; sb++) { + for (int ch = 0; ch < channels; ch++) { + if (self->allocation[ch][sb]) { + int *sf = self->scale_factor[ch][sb]; + switch (self->scale_factor_info[ch][sb]) { + case 0: + sf[0] = plm_buffer_read(self->buffer, 6); + sf[1] = plm_buffer_read(self->buffer, 6); + sf[2] = plm_buffer_read(self->buffer, 6); + break; + case 1: + sf[0] = + sf[1] = plm_buffer_read(self->buffer, 6); + sf[2] = plm_buffer_read(self->buffer, 6); + break; + case 2: + sf[0] = + sf[1] = + sf[2] = plm_buffer_read(self->buffer, 6); + break; + case 3: + sf[0] = plm_buffer_read(self->buffer, 6); + sf[1] = + sf[2] = plm_buffer_read(self->buffer, 6); + break; + } + } + } + if (self->mode == PLM_AUDIO_MODE_MONO) { + self->scale_factor[1][sb][0] = self->scale_factor[0][sb][0]; + self->scale_factor[1][sb][1] = self->scale_factor[0][sb][1]; + self->scale_factor[1][sb][2] = self->scale_factor[0][sb][2]; + } + } + + // Coefficient input and reconstruction + int out_pos = 0; + for (int part = 0; part < 3; part++) { + for (int granule = 0; granule < 4; granule++) { + + // Read the samples + for (int sb = 0; sb < self->bound; sb++) { + plm_audio_read_samples(self, 0, sb, part); + plm_audio_read_samples(self, 1, sb, part); + } + for (int sb = self->bound; sb < sblimit; sb++) { + plm_audio_read_samples(self, 0, sb, part); + self->sample[1][sb][0] = self->sample[0][sb][0]; + self->sample[1][sb][1] = self->sample[0][sb][1]; + self->sample[1][sb][2] = self->sample[0][sb][2]; + } + for (int sb = sblimit; sb < 32; sb++) { + self->sample[0][sb][0] = 0; + self->sample[0][sb][1] = 0; + self->sample[0][sb][2] = 0; + self->sample[1][sb][0] = 0; + self->sample[1][sb][1] = 0; + self->sample[1][sb][2] = 0; + } + + // Synthesis loop + for (int p = 0; p < 3; p++) { + // Shifting step + self->v_pos = (self->v_pos - 64) & 1023; + + for (int ch = 0; ch < 2; ch++) { + plm_audio_matrix_transform(self->sample[ch], p, self->V, self->v_pos); + + // Build U, windowing, calculate output + memset(self->U, 0, sizeof(self->U)); + + int d_index = 512 - (self->v_pos >> 1); + int v_index = (self->v_pos % 128) >> 1; + while (v_index < 1024) { + for (int i = 0; i < 32; ++i) { + self->U[i] += self->D[d_index++] * self->V[v_index++]; + } + + v_index += 128 - 32; + d_index += 64 - 32; + } + + d_index -= (512 - 32); + v_index = (128 - 32 + 1024) - v_index; + while (v_index < 1024) { + for (int i = 0; i < 32; ++i) { + self->U[i] += self->D[d_index++] * self->V[v_index++]; + } + + v_index += 128 - 32; + d_index += 64 - 32; + } + + // Output samples + #ifdef PLM_AUDIO_SEPARATE_CHANNELS + float *out_channel = ch == 0 + ? self->samples.left + : self->samples.right; + for (int j = 0; j < 32; j++) { + out_channel[out_pos + j] = self->U[j] / 2147418112.0f; + } + #else + for (int j = 0; j < 32; j++) { + self->samples.interleaved[((out_pos + j) << 1) + ch] = + self->U[j] / 2147418112.0f; + } + #endif + } // End of synthesis channel loop + out_pos += 32; + } // End of synthesis sub-block loop + + } // Decoding of the granule finished + } + + plm_buffer_align(self->buffer); +} + +const plm_quantizer_spec_t *plm_audio_read_allocation(plm_audio_t *self, int sb, int tab3) { + int tab4 = PLM_AUDIO_QUANT_LUT_STEP_3[tab3][sb]; + int qtab = PLM_AUDIO_QUANT_LUT_STEP4[tab4 & 15][plm_buffer_read(self->buffer, tab4 >> 4)]; + return qtab ? (&PLM_AUDIO_QUANT_TAB[qtab - 1]) : 0; +} + +void plm_audio_read_samples(plm_audio_t *self, int ch, int sb, int part) { + const plm_quantizer_spec_t *q = self->allocation[ch][sb]; + int sf = self->scale_factor[ch][sb][part]; + int *sample = self->sample[ch][sb]; + int val = 0; + + if (!q) { + // No bits allocated for this subband + sample[0] = sample[1] = sample[2] = 0; + return; + } + + // Resolve scalefactor + if (sf == 63) { + sf = 0; + } + else { + int shift = (sf / 3) | 0; + sf = (PLM_AUDIO_SCALEFACTOR_BASE[sf % 3] + ((1u << shift) >> 1)) >> shift; + } + + // Decode samples + int adj = q->levels; + if (q->group) { + // Decode grouped samples + val = plm_buffer_read(self->buffer, q->bits); + sample[0] = val % adj; + val /= adj; + sample[1] = val % adj; + sample[2] = val / adj; + } + else { + // Decode direct samples + sample[0] = plm_buffer_read(self->buffer, q->bits); + sample[1] = plm_buffer_read(self->buffer, q->bits); + sample[2] = plm_buffer_read(self->buffer, q->bits); + } + + // Postmultiply samples + int scale = 65536 / (adj + 1); + adj = ((adj + 1) >> 1) - 1; + + val = (adj - sample[0]) * scale; + sample[0] = (val * (sf >> 12) + ((val * (sf & 4095) + 2048) >> 12)) >> 12; + + val = (adj - sample[1]) * scale; + sample[1] = (val * (sf >> 12) + ((val * (sf & 4095) + 2048) >> 12)) >> 12; + + val = (adj - sample[2]) * scale; + sample[2] = (val * (sf >> 12) + ((val * (sf & 4095) + 2048) >> 12)) >> 12; +} + +void plm_audio_matrix_transform(int s[32][3], int ss, float *d, int dp) { + float t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, + t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, + t25, t26, t27, t28, t29, t30, t31, t32, t33; + + t01 = (float)(s[0][ss] + s[31][ss]); t02 = (float)(s[0][ss] - s[31][ss]) * 0.500602998235f; + t03 = (float)(s[1][ss] + s[30][ss]); t04 = (float)(s[1][ss] - s[30][ss]) * 0.505470959898f; + t05 = (float)(s[2][ss] + s[29][ss]); t06 = (float)(s[2][ss] - s[29][ss]) * 0.515447309923f; + t07 = (float)(s[3][ss] + s[28][ss]); t08 = (float)(s[3][ss] - s[28][ss]) * 0.53104259109f; + t09 = (float)(s[4][ss] + s[27][ss]); t10 = (float)(s[4][ss] - s[27][ss]) * 0.553103896034f; + t11 = (float)(s[5][ss] + s[26][ss]); t12 = (float)(s[5][ss] - s[26][ss]) * 0.582934968206f; + t13 = (float)(s[6][ss] + s[25][ss]); t14 = (float)(s[6][ss] - s[25][ss]) * 0.622504123036f; + t15 = (float)(s[7][ss] + s[24][ss]); t16 = (float)(s[7][ss] - s[24][ss]) * 0.674808341455f; + t17 = (float)(s[8][ss] + s[23][ss]); t18 = (float)(s[8][ss] - s[23][ss]) * 0.744536271002f; + t19 = (float)(s[9][ss] + s[22][ss]); t20 = (float)(s[9][ss] - s[22][ss]) * 0.839349645416f; + t21 = (float)(s[10][ss] + s[21][ss]); t22 = (float)(s[10][ss] - s[21][ss]) * 0.972568237862f; + t23 = (float)(s[11][ss] + s[20][ss]); t24 = (float)(s[11][ss] - s[20][ss]) * 1.16943993343f; + t25 = (float)(s[12][ss] + s[19][ss]); t26 = (float)(s[12][ss] - s[19][ss]) * 1.48416461631f; + t27 = (float)(s[13][ss] + s[18][ss]); t28 = (float)(s[13][ss] - s[18][ss]) * 2.05778100995f; + t29 = (float)(s[14][ss] + s[17][ss]); t30 = (float)(s[14][ss] - s[17][ss]) * 3.40760841847f; + t31 = (float)(s[15][ss] + s[16][ss]); t32 = (float)(s[15][ss] - s[16][ss]) * 10.1900081235f; + + t33 = t01 + t31; t31 = (t01 - t31) * 0.502419286188f; + t01 = t03 + t29; t29 = (t03 - t29) * 0.52249861494f; + t03 = t05 + t27; t27 = (t05 - t27) * 0.566944034816f; + t05 = t07 + t25; t25 = (t07 - t25) * 0.64682178336f; + t07 = t09 + t23; t23 = (t09 - t23) * 0.788154623451f; + t09 = t11 + t21; t21 = (t11 - t21) * 1.06067768599f; + t11 = t13 + t19; t19 = (t13 - t19) * 1.72244709824f; + t13 = t15 + t17; t17 = (t15 - t17) * 5.10114861869f; + t15 = t33 + t13; t13 = (t33 - t13) * 0.509795579104f; + t33 = t01 + t11; t01 = (t01 - t11) * 0.601344886935f; + t11 = t03 + t09; t09 = (t03 - t09) * 0.899976223136f; + t03 = t05 + t07; t07 = (t05 - t07) * 2.56291544774f; + t05 = t15 + t03; t15 = (t15 - t03) * 0.541196100146f; + t03 = t33 + t11; t11 = (t33 - t11) * 1.30656296488f; + t33 = t05 + t03; t05 = (t05 - t03) * 0.707106781187f; + t03 = t15 + t11; t15 = (t15 - t11) * 0.707106781187f; + t03 += t15; + t11 = t13 + t07; t13 = (t13 - t07) * 0.541196100146f; + t07 = t01 + t09; t09 = (t01 - t09) * 1.30656296488f; + t01 = t11 + t07; t07 = (t11 - t07) * 0.707106781187f; + t11 = t13 + t09; t13 = (t13 - t09) * 0.707106781187f; + t11 += t13; t01 += t11; + t11 += t07; t07 += t13; + t09 = t31 + t17; t31 = (t31 - t17) * 0.509795579104f; + t17 = t29 + t19; t29 = (t29 - t19) * 0.601344886935f; + t19 = t27 + t21; t21 = (t27 - t21) * 0.899976223136f; + t27 = t25 + t23; t23 = (t25 - t23) * 2.56291544774f; + t25 = t09 + t27; t09 = (t09 - t27) * 0.541196100146f; + t27 = t17 + t19; t19 = (t17 - t19) * 1.30656296488f; + t17 = t25 + t27; t27 = (t25 - t27) * 0.707106781187f; + t25 = t09 + t19; t19 = (t09 - t19) * 0.707106781187f; + t25 += t19; + t09 = t31 + t23; t31 = (t31 - t23) * 0.541196100146f; + t23 = t29 + t21; t21 = (t29 - t21) * 1.30656296488f; + t29 = t09 + t23; t23 = (t09 - t23) * 0.707106781187f; + t09 = t31 + t21; t31 = (t31 - t21) * 0.707106781187f; + t09 += t31; t29 += t09; t09 += t23; t23 += t31; + t17 += t29; t29 += t25; t25 += t09; t09 += t27; + t27 += t23; t23 += t19; t19 += t31; + t21 = t02 + t32; t02 = (t02 - t32) * 0.502419286188f; + t32 = t04 + t30; t04 = (t04 - t30) * 0.52249861494f; + t30 = t06 + t28; t28 = (t06 - t28) * 0.566944034816f; + t06 = t08 + t26; t08 = (t08 - t26) * 0.64682178336f; + t26 = t10 + t24; t10 = (t10 - t24) * 0.788154623451f; + t24 = t12 + t22; t22 = (t12 - t22) * 1.06067768599f; + t12 = t14 + t20; t20 = (t14 - t20) * 1.72244709824f; + t14 = t16 + t18; t16 = (t16 - t18) * 5.10114861869f; + t18 = t21 + t14; t14 = (t21 - t14) * 0.509795579104f; + t21 = t32 + t12; t32 = (t32 - t12) * 0.601344886935f; + t12 = t30 + t24; t24 = (t30 - t24) * 0.899976223136f; + t30 = t06 + t26; t26 = (t06 - t26) * 2.56291544774f; + t06 = t18 + t30; t18 = (t18 - t30) * 0.541196100146f; + t30 = t21 + t12; t12 = (t21 - t12) * 1.30656296488f; + t21 = t06 + t30; t30 = (t06 - t30) * 0.707106781187f; + t06 = t18 + t12; t12 = (t18 - t12) * 0.707106781187f; + t06 += t12; + t18 = t14 + t26; t26 = (t14 - t26) * 0.541196100146f; + t14 = t32 + t24; t24 = (t32 - t24) * 1.30656296488f; + t32 = t18 + t14; t14 = (t18 - t14) * 0.707106781187f; + t18 = t26 + t24; t24 = (t26 - t24) * 0.707106781187f; + t18 += t24; t32 += t18; + t18 += t14; t26 = t14 + t24; + t14 = t02 + t16; t02 = (t02 - t16) * 0.509795579104f; + t16 = t04 + t20; t04 = (t04 - t20) * 0.601344886935f; + t20 = t28 + t22; t22 = (t28 - t22) * 0.899976223136f; + t28 = t08 + t10; t10 = (t08 - t10) * 2.56291544774f; + t08 = t14 + t28; t14 = (t14 - t28) * 0.541196100146f; + t28 = t16 + t20; t20 = (t16 - t20) * 1.30656296488f; + t16 = t08 + t28; t28 = (t08 - t28) * 0.707106781187f; + t08 = t14 + t20; t20 = (t14 - t20) * 0.707106781187f; + t08 += t20; + t14 = t02 + t10; t02 = (t02 - t10) * 0.541196100146f; + t10 = t04 + t22; t22 = (t04 - t22) * 1.30656296488f; + t04 = t14 + t10; t10 = (t14 - t10) * 0.707106781187f; + t14 = t02 + t22; t02 = (t02 - t22) * 0.707106781187f; + t14 += t02; t04 += t14; t14 += t10; t10 += t02; + t16 += t04; t04 += t08; t08 += t14; t14 += t28; + t28 += t10; t10 += t20; t20 += t02; t21 += t16; + t16 += t32; t32 += t04; t04 += t06; t06 += t08; + t08 += t18; t18 += t14; t14 += t30; t30 += t28; + t28 += t26; t26 += t10; t10 += t12; t12 += t20; + t20 += t24; t24 += t02; + + d[dp + 48] = -t33; + d[dp + 49] = d[dp + 47] = -t21; + d[dp + 50] = d[dp + 46] = -t17; + d[dp + 51] = d[dp + 45] = -t16; + d[dp + 52] = d[dp + 44] = -t01; + d[dp + 53] = d[dp + 43] = -t32; + d[dp + 54] = d[dp + 42] = -t29; + d[dp + 55] = d[dp + 41] = -t04; + d[dp + 56] = d[dp + 40] = -t03; + d[dp + 57] = d[dp + 39] = -t06; + d[dp + 58] = d[dp + 38] = -t25; + d[dp + 59] = d[dp + 37] = -t08; + d[dp + 60] = d[dp + 36] = -t11; + d[dp + 61] = d[dp + 35] = -t18; + d[dp + 62] = d[dp + 34] = -t09; + d[dp + 63] = d[dp + 33] = -t14; + d[dp + 32] = -t05; + d[dp + 0] = t05; d[dp + 31] = -t30; + d[dp + 1] = t30; d[dp + 30] = -t27; + d[dp + 2] = t27; d[dp + 29] = -t28; + d[dp + 3] = t28; d[dp + 28] = -t07; + d[dp + 4] = t07; d[dp + 27] = -t26; + d[dp + 5] = t26; d[dp + 26] = -t23; + d[dp + 6] = t23; d[dp + 25] = -t10; + d[dp + 7] = t10; d[dp + 24] = -t15; + d[dp + 8] = t15; d[dp + 23] = -t12; + d[dp + 9] = t12; d[dp + 22] = -t19; + d[dp + 10] = t19; d[dp + 21] = -t20; + d[dp + 11] = t20; d[dp + 20] = -t13; + d[dp + 12] = t13; d[dp + 19] = -t24; + d[dp + 13] = t24; d[dp + 18] = -t31; + d[dp + 14] = t31; d[dp + 17] = -t02; + d[dp + 15] = t02; d[dp + 16] = 0.0; +}; + diff --git a/dsp/mpeg/mpeg.h b/dsp/mpeg/mpeg.h new file mode 100644 index 00000000..e29de64c --- /dev/null +++ b/dsp/mpeg/mpeg.h @@ -0,0 +1,450 @@ +#ifndef COSMOPOLITAN_DSP_MPEG_MPEG_H_ +#define COSMOPOLITAN_DSP_MPEG_MPEG_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct FILE; + +typedef struct plm_t plm_t; +typedef struct plm_buffer_t plm_buffer_t; +typedef struct plm_demux_t plm_demux_t; +typedef struct plm_video_t plm_video_t; +typedef struct plm_audio_t plm_audio_t; + +/** + * Demuxed MPEG PS packet + * + * The type maps directly to the various MPEG-PES start codes. pts is + * the presentation time stamp of the packet in seconds. Not all packets + * have a pts value. + */ +typedef struct plm_packet_t { + int type; + double pts; + size_t length; + uint8_t *data; +} plm_packet_t; + +/** + * Decoded Video Plane + * + * The byte length of the data is width * height. Note that different + * planes have different sizes: the Luma plane (Y) is double the size of + * each of the two Chroma planes (Cr, Cb) - i.e. 4 times the byte + * length. Also note that the size of the plane does *not* denote the + * size of the displayed frame. The sizes of planes are always rounded + * up to the nearest macroblock (16px). + */ +typedef struct plm_plane_t { + unsigned int width; + unsigned int height; + uint8_t *data; +} plm_plane_t; + +/** + * Decoded Video Frame + * + * Width and height denote the desired display size of the frame. This + * may be different from the internal size of the 3 planes. + */ +typedef struct plm_frame_t { + double time; + unsigned int width; + unsigned int height; + plm_plane_t y; + plm_plane_t cr; + plm_plane_t cb; +} plm_frame_t; + +/** + * Callback function type for decoded video frames used by the high-level + * plm_* interface + */ +typedef void (*plm_video_decode_callback)(plm_t *self, plm_frame_t *frame, + void *user); + +/** + * Decoded Audio Samples + * + * Samples are stored as normalized (-1, 1) float either interleaved, or if + * PLM_AUDIO_SEPARATE_CHANNELS is defined, in two separate arrays. + * The `count` is always PLM_AUDIO_SAMPLES_PER_FRAME and just there for + * convenience. + */ +#define PLM_AUDIO_SAMPLES_PER_FRAME 1152 + +struct plm_samples_t { + double time; + unsigned int count; +#ifdef PLM_AUDIO_SEPARATE_CHANNELS + float left[PLM_AUDIO_SAMPLES_PER_FRAME] aligned(32); + float right[PLM_AUDIO_SAMPLES_PER_FRAME] aligned(32); +#else + float interleaved[PLM_AUDIO_SAMPLES_PER_FRAME * 2] aligned(32); +#endif +} aligned(32); + +typedef struct plm_samples_t plm_samples_t; + +/** + * Callback function type for decoded audio samples used by the high-level + * plm_* interface + */ +typedef void (*plm_audio_decode_callback)(plm_t *self, plm_samples_t *samples, + void *user); + +/** + * Callback function for plm_buffer when it needs more data + */ +typedef void (*plm_buffer_load_callback)(plm_buffer_t *self, void *user); + +/** + * ----------------------------------------------------------------------------- + * plm_* public API + * High-Level API for loading/demuxing/decoding MPEG-PS data + * + * Create a plmpeg instance with a filename. Returns NULL if the file could not + * be opened. + */ +plm_t *plm_create_with_filename(const char *filename); + +/** + * Create a plmpeg instance with file handle. Pass true to close_when_done + * to let plmpeg call fclose() on the handle when plm_destroy() is + * called. + */ +plm_t *plm_create_with_file(struct FILE *fh, int close_when_done); + +/** + * Create a plmpeg instance with pointer to memory as source. This assumes the + * whole file is in memory. Pass true to free_when_done to let plmpeg call + * free() on the pointer when plm_destroy() is called. + */ +plm_t *plm_create_with_memory(uint8_t *bytes, size_t length, + int free_when_done); + +/** + * Create a plmpeg instance with a plm_buffer as source. This is also + * called internally by all the above constructor functions. + */ +plm_t *plm_create_with_buffer(plm_buffer_t *buffer, int destroy_when_done); + +/** + * Destroy a plmpeg instance and free all data + */ +void plm_destroy(plm_t *self); + +/** + * Get or set whether video decoding is enabled. + */ +int plm_get_video_enabled(plm_t *self); +void plm_set_video_enabled(plm_t *self, int enabled); + +/** + * Get or set whether audio decoding is enabled. When enabling, you can set the + * desired audio stream (0-3) to decode. + */ +int plm_get_audio_enabled(plm_t *self); +void plm_set_audio_enabled(plm_t *self, int enabled, int stream_index); + +/** + * Get the display width/height of the video stream + */ +int plm_get_width(plm_t *self); +int plm_get_height(plm_t *self); + +double plm_get_pixel_aspect_ratio(plm_t *); + +/** + * Get the framerate of the video stream in frames per second + */ +double plm_get_framerate(plm_t *self); + +/** + * Get the number of available audio streams in the file + */ +int plm_get_num_audio_streams(plm_t *self); + +/** + * Get the samplerate of the audio stream in samples per second + */ +int plm_get_samplerate(plm_t *self); + +/** + * Get or set the audio lead time in seconds - the time in which audio samples + * are decoded in advance (or behind) the video decode time. Default 0. + */ +double plm_get_audio_lead_time(plm_t *self); +void plm_set_audio_lead_time(plm_t *self, double lead_time); + +/** + * Get the current internal time in seconds + */ +double plm_get_time(plm_t *self); + +/** + * Rewind all buffers back to the beginning. + */ +void plm_rewind(plm_t *self); + +/** + * Get or set looping. Default false. + */ +int plm_get_loop(plm_t *self); +void plm_set_loop(plm_t *self, int loop); + +/** + * Get whether the file has ended. If looping is enabled, this will always + * return false. + */ +int plm_has_ended(plm_t *self); + +/** + * Set the callback for decoded video frames used with plm_decode(). If no + * callback is set, video data will be ignored and not be decoded. + */ +void plm_set_video_decode_callback(plm_t *self, plm_video_decode_callback fp, + void *user); + +/** + * Set the callback for decoded audio samples used with plm_decode(). If no + * callback is set, audio data will be ignored and not be decoded. + */ +void plm_set_audio_decode_callback(plm_t *self, plm_audio_decode_callback fp, + void *user); + +/** + * Advance the internal timer by seconds and decode video/audio up to + * this time. Returns true/false whether anything was decoded. + */ +int plm_decode(plm_t *self, double seconds); + +/** + * Decode and return one video frame. Returns NULL if no frame could be decoded + * (either because the source ended or data is corrupt). If you only want to + * decode video, you should disable audio via plm_set_audio_enabled(). + * The returned plm_frame_t is valid until the next call to + * plm_decode_video call or until the plm_destroy is called. + */ +plm_frame_t *plm_decode_video(plm_t *self); + +/** + * Decode and return one audio frame. Returns NULL if no frame could be decoded + * (either because the source ended or data is corrupt). If you only want to + * decode audio, you should disable video via plm_set_video_enabled(). + * The returned plm_samples_t is valid until the next call to + * plm_decode_video or until the plm_destroy is called. + */ +plm_samples_t *plm_decode_audio(plm_t *self); + +/* ----------------------------------------------------------------------------- + * plm_buffer public API + * Provides the data source for all other plm_* interfaces + * + * The default size for buffers created from files or by the high-level API + */ +#ifndef PLM_BUFFER_DEFAULT_SIZE +#define PLM_BUFFER_DEFAULT_SIZE (128 * 1024) +#endif + +/** + * Create a buffer instance with a filename. Returns NULL if the file could not + * be opened. + */ +plm_buffer_t *plm_buffer_create_with_filename(const char *filename); + +/** + * Create a buffer instance with file handle. Pass true to close_when_done + * to let plmpeg call fclose() on the handle when plm_destroy() is + * called. + */ +plm_buffer_t *plm_buffer_create_with_file(struct FILE *fh, int close_when_done); + +/** + * Create a buffer instance with a pointer to memory as source. This assumes + * the whole file is in memory. Pass 1 to free_when_done to let plmpeg call + * free() on the pointer when plm_destroy() is called. + */ +plm_buffer_t *plm_buffer_create_with_memory(uint8_t *bytes, size_t length, + int free_when_done); + +/** + * Create an empty buffer with an initial capacity. The buffer will grow + * as needed. + */ +plm_buffer_t *plm_buffer_create_with_capacity(size_t capacity); + +/** + * Destroy a buffer instance and free all data + */ +void plm_buffer_destroy(plm_buffer_t *self); + +/** + * Copy data into the buffer. If the data to be written is larger than the + * available space, the buffer will realloc() with a larger capacity. + * Returns the number of bytes written. This will always be the same as the + * passed in length, except when the buffer was created _with_memory() for + * which _write() is forbidden. + */ +size_t plm_buffer_write(plm_buffer_t *self, uint8_t *bytes, size_t length); + +/** + * Set a callback that is called whenever the buffer needs more data + */ +void plm_buffer_set_load_callback(plm_buffer_t *self, + plm_buffer_load_callback fp, void *user); + +/** + * Rewind the buffer back to the beginning. When loading from a file handle, + * this also seeks to the beginning of the file. + */ +void plm_buffer_rewind(plm_buffer_t *self); + +/** + * ----------------------------------------------------------------------------- + * plm_demux public API + * Demux an MPEG Program Stream (PS) data into separate packages + * + * Various Packet Types + */ +#define PLM_DEMUX_PACKET_PRIVATE 0xBD +#define PLM_DEMUX_PACKET_AUDIO_1 0xC0 +#define PLM_DEMUX_PACKET_AUDIO_2 0xC1 +#define PLM_DEMUX_PACKET_AUDIO_3 0xC2 +#define PLM_DEMUX_PACKET_AUDIO_4 0xC2 +#define PLM_DEMUX_PACKET_VIDEO_1 0xE0 + +/** + * Create a demuxer with a plm_buffer as source + */ +plm_demux_t *plm_demux_create(plm_buffer_t *buffer, int destroy_when_done); + +/** + * Destroy a demuxer and free all data + */ +void plm_demux_destroy(plm_demux_t *self); + +/** + * Returns the number of video streams found in the system header. + */ +int plm_demux_get_num_video_streams(plm_demux_t *self); + +/** + * Returns the number of audio streams found in the system header. + */ +int plm_demux_get_num_audio_streams(plm_demux_t *self); + +/** + * Rewinds the internal buffer. See plm_buffer_rewind(). + */ +void plm_demux_rewind(plm_demux_t *self); + +/** + * Decode and return the next packet. The returned packet_t is valid until + * the next call to plm_demux_decode() or until the demuxer is destroyed. + */ +plm_packet_t *plm_demux_decode(plm_demux_t *self); + +/* ----------------------------------------------------------------------------- + * plm_video public API + * Decode MPEG1 Video ("mpeg1") data into raw YCrCb frames + */ + +/** + * Create a video decoder with a plm_buffer as source + */ +plm_video_t *plm_video_create_with_buffer(plm_buffer_t *buffer, + int destroy_when_done); + +/** + * Destroy a video decoder and free all data + */ +void plm_video_destroy(plm_video_t *self); + +/** + * Get the framerate in frames per second + */ +double plm_video_get_framerate(plm_video_t *); + +double plm_video_get_pixel_aspect_ratio(plm_video_t *); + +/** + * Get the display width/height + */ +int plm_video_get_width(plm_video_t *); +int plm_video_get_height(plm_video_t *); + +/** + * Set "no delay" mode. When enabled, the decoder assumes that the video does + * *not* contain any B-Frames. This is useful for reducing lag when streaming. + */ +void plm_video_set_no_delay(plm_video_t *self, int no_delay); + +/** + * Get the current internal time in seconds + */ +double plm_video_get_time(plm_video_t *self); + +/** + * Rewinds the internal buffer. See plm_buffer_rewind(). + */ +void plm_video_rewind(plm_video_t *self); + +/** + * Decode and return one frame of video and advance the internal time by + * 1/framerate seconds. The returned frame_t is valid until the next call of + * plm_video_decode() or until the video decoder is destroyed. + */ +plm_frame_t *plm_video_decode(plm_video_t *self); + +/** + * Convert the YCrCb data of a frame into an interleaved RGB buffer. The buffer + * pointed to by *rgb must have a size of (frame->width * frame->height * 3) + * bytes. + */ +void plm_frame_to_rgb(plm_frame_t *frame, uint8_t *rgb); + +/* ----------------------------------------------------------------------------- + * plm_audio public API + * Decode MPEG-1 Audio Layer II ("mp2") data into raw samples + */ + +/** + * Create an audio decoder with a plm_buffer as source. + */ +plm_audio_t *plm_audio_create_with_buffer(plm_buffer_t *buffer, + int destroy_when_done); + +/** + * Destroy an audio decoder and free all data + */ +void plm_audio_destroy(plm_audio_t *self); + +/** + * Get the samplerate in samples per second + */ +int plm_audio_get_samplerate(plm_audio_t *self); + +/** + * Get the current internal time in seconds + */ +double plm_audio_get_time(plm_audio_t *self); + +/** + * Rewinds the internal buffer. See plm_buffer_rewind(). + */ +void plm_audio_rewind(plm_audio_t *self); + +/** + * Decode and return one "frame" of audio and advance the internal time by + * (PLM_AUDIO_SAMPLES_PER_FRAME/samplerate) seconds. The returned samples_t + * is valid until the next call of plm_audio_decode() or until the audio + * decoder is destroyed. + */ +plm_samples_t *plm_audio_decode(plm_audio_t *self); + +extern long plmpegdecode_latency_; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_MPEG_MPEG_H_ */ diff --git a/dsp/mpeg/mpeg.mk b/dsp/mpeg/mpeg.mk new file mode 100644 index 00000000..9d1f6f80 --- /dev/null +++ b/dsp/mpeg/mpeg.mk @@ -0,0 +1,69 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += DSP_MPEG + +DSP_MPEG_ARTIFACTS += DSP_MPEG_A +DSP_MPEG = $(DSP_MPEG_A_DEPS) $(DSP_MPEG_A) +DSP_MPEG_A = o/$(MODE)/dsp/mpeg/mpeg.a +DSP_MPEG_A_FILES := $(wildcard dsp/mpeg/*) +DSP_MPEG_A_HDRS = $(filter %.h,$(DSP_MPEG_A_FILES)) +DSP_MPEG_A_SRCS_S = $(filter %.S,$(DSP_MPEG_A_FILES)) +DSP_MPEG_A_SRCS_C = $(filter %.c,$(DSP_MPEG_A_FILES)) + +DSP_MPEG_A_SRCS = \ + $(DSP_MPEG_A_SRCS_S) \ + $(DSP_MPEG_A_SRCS_C) + +DSP_MPEG_A_OBJS = \ + $(DSP_MPEG_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(DSP_MPEG_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(DSP_MPEG_A_SRCS_C:%.c=o/$(MODE)/%.o) + +DSP_MPEG_A_CHECKS = \ + $(DSP_MPEG_A).pkg \ + $(DSP_MPEG_A_HDRS:%=o/$(MODE)/%.ok) + +DSP_MPEG_A_DIRECTDEPS = \ + LIBC_CALLS \ + LIBC_LOG \ + LIBC_RUNTIME \ + LIBC_TINYMATH \ + LIBC_TIME \ + LIBC_STUBS \ + LIBC_STR \ + LIBC_NEXGEN32E \ + LIBC_STDIO \ + LIBC_SYSV \ + LIBC_MEM \ + LIBC_LOG \ + LIBC_FMT \ + LIBC_UNICODE \ + +DSP_MPEG_A_DEPS := \ + $(call uniq,$(foreach x,$(DSP_MPEG_A_DIRECTDEPS),$($(x)))) + +$(DSP_MPEG_A): dsp/mpeg/ \ + $(DSP_MPEG_A).pkg \ + $(DSP_MPEG_A_OBJS) + +$(DSP_MPEG_A).pkg: \ + $(DSP_MPEG_A_OBJS) \ + $(foreach x,$(DSP_MPEG_A_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/dsp/mpeg/clamp4int256-k8.o: \ + OVERRIDE_CFLAGS += \ + -Os + +#o/$(MODE)/dsp/mpeg/macroblock.o: \ + CC = $(CLANG) + +DSP_MPEG_LIBS = $(foreach x,$(DSP_MPEG_ARTIFACTS),$($(x))) +DSP_MPEG_SRCS = $(foreach x,$(DSP_MPEG_ARTIFACTS),$($(x)_SRCS)) +DSP_MPEG_HDRS = $(foreach x,$(DSP_MPEG_ARTIFACTS),$($(x)_HDRS)) +DSP_MPEG_CHECKS = $(foreach x,$(DSP_MPEG_ARTIFACTS),$($(x)_CHECKS)) +DSP_MPEG_OBJS = $(foreach x,$(DSP_MPEG_ARTIFACTS),$($(x)_OBJS)) +$(DSP_MPEG_OBJS): $(BUILD_FILES) dsp/mpeg/mpeg.mk + +.PHONY: o/$(MODE)/dsp/mpeg +o/$(MODE)/dsp/mpeg: $(DSP_MPEG_CHECKS) diff --git a/dsp/mpeg/mpeg1.c b/dsp/mpeg/mpeg1.c new file mode 100644 index 00000000..fa708c19 --- /dev/null +++ b/dsp/mpeg/mpeg1.c @@ -0,0 +1,1115 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│ +│vi: set et ft=c ts=4 sw=4 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer │ +│ Dominic Szablewski - https://phoboslab.org │ +│ │ +│ The MIT License(MIT) │ +│ Copyright(c) 2019 Dominic Szablewski │ +│ │ +│ Permission is hereby granted, free of charge, to any person obtaining │ +│ a copy of this software and associated documentation files(the │ +│ "Software"), to deal in the Software without restriction, including │ +│ without limitation the rights to use, copy, modify, merge, publish, │ +│ distribute, sublicense, and / or sell copies of the Software, and to │ +│ permit persons to whom the Software is furnished to do so, subject to │ +│ the following conditions: │ +│ │ +│ The above copyright notice and this permission notice shall be │ +│ included in all copies or substantial portions of the Software. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │ +│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │ +│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND │ +│ NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE │ +│ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN │ +│ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN │ +│ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE │ +│ SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/mpeg/blockset.h" +#include "dsp/mpeg/buffer.h" +#include "dsp/mpeg/idct.h" +#include "dsp/mpeg/mpeg.h" +#include "dsp/mpeg/video.h" +#include "libc/conv/conv.h" +#include "libc/log/log.h" +#include "libc/macros.h" +#include "libc/math.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" +#include "libc/time/time.h" +#include "libc/x/x.h" + +asm(".ident\t\"\\n\\n\ +PL_MPEG (MIT License)\\n\ +Copyright(c) 2019 Dominic Szablewski\\n\ +https://phoboslab.org\""); +asm(".include \"libc/disclaimer.inc\""); + +// ----------------------------------------------------------------------------- +// plm_video implementation + +// Inspired by Java MPEG-1 Video Decoder and Player by Zoltan Korandi +// https://sourceforge.net/projects/javampeg1video/ + +#define GETCONST(ARRAY, DEFAULT) + +static const int PLM_VIDEO_PICTURE_TYPE_INTRA = 1; +static const int PLM_VIDEO_PICTURE_TYPE_PREDICTIVE = 2; +static const int PLM_VIDEO_PICTURE_TYPE_B = 3; + +static const int PLM_START_SEQUENCE = 0xB3; +static const int PLM_START_SLICE_FIRST = 0x01; +static const int PLM_START_SLICE_LAST = 0xAF; +static const int PLM_START_PICTURE = 0x00; +static const int PLM_START_EXTENSION = 0xB5; +static const int PLM_START_USER_DATA = 0xB2; + +static const float PLM_VIDEO_PIXEL_ASPECT_RATIO[] = { + 1.0000, /* square pixels */ + 0.6735, /* 3:4? */ + 0.7031, /* MPEG-1 / MPEG-2 video encoding divergence? */ + 0.7615, 0.8055, 0.8437, 0.8935, 0.9157, 0.9815, + 1.0255, 1.0695, 1.0950, 1.1575, 1.2051}; + +static const float PLM_VIDEO_PICTURE_RATE[] = { + 23.976, /* NTSC-Film */ + 24.000, /* NTSC-Film (enriched for foreign nations) */ + 25.000, /* PAL (Britain, Africa, China, etc.) */ + 29.970, /* NTSC */ + 30.000, /* NTSC (enriched for foreign nations) */ + 50.000, /* PAL? */ + 59.940, /* NTSC-Wow */ + 60.000 /* NTSC-Wow (enriched for foreign nations) */ +}; + +static const uint8_t PLM_VIDEO_ZIG_ZAG[] = /* clang-format off */ { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, +} /* clang-format on */; + +static const uint8_t PLM_VIDEO_INTRAQUANT_MATRIX[] = /* clang-format off */ { + 8, 16, 19, 22, 26, 27, 29, 34, + 16, 16, 22, 24, 27, 29, 34, 37, + 19, 22, 26, 27, 29, 34, 34, 38, + 22, 22, 26, 27, 29, 34, 37, 40, + 22, 26, 27, 29, 32, 35, 40, 48, + 26, 27, 29, 32, 35, 40, 48, 58, + 26, 27, 29, 34, 38, 46, 56, 69, + 27, 29, 35, 38, 46, 56, 69, 83, +} /* clang-format on */; + +static const uint8_t PLM_VIDEO_NONINTRAQUANT_MATRIX[] = /* clang-format off */ { + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, +} /* clang-format on */; + +static const uint8_t PLM_VIDEO_PREMULTIPLIER_MATRIX[] = /* clang-format off */ { + 32, 44, 42, 38, 32, 25, 17, 9, + 44, 62, 58, 52, 44, 35, 24, 12, + 42, 58, 55, 49, 42, 33, 23, 12, + 38, 52, 49, 44, 38, 30, 20, 10, + 32, 44, 42, 38, 32, 25, 17, 9, + 25, 35, 33, 30, 25, 20, 14, 7, + 17, 24, 23, 20, 17, 14, 9, 5, + 9, 12, 12, 10, 9, 7, 5, 2, +} /* clang-format on */; + +static const plm_vlc_t PLM_VIDEO_MACROBLOCK_ADDRESS_INCREMENT[] = { + {1 << 1, 0}, {0, 1}, // 0: x + {2 << 1, 0}, {3 << 1, 0}, // 1: 0x + {4 << 1, 0}, {5 << 1, 0}, // 2: 00x + {0, 3}, {0, 2}, // 3: 01x + {6 << 1, 0}, {7 << 1, 0}, // 4: 000x + {0, 5}, {0, 4}, // 5: 001x + {8 << 1, 0}, {9 << 1, 0}, // 6: 0000x + {0, 7}, {0, 6}, // 7: 0001x + {10 << 1, 0}, {11 << 1, 0}, // 8: 0000 0x + {12 << 1, 0}, {13 << 1, 0}, // 9: 0000 1x + {14 << 1, 0}, {15 << 1, 0}, // 10: 0000 00x + {16 << 1, 0}, {17 << 1, 0}, // 11: 0000 01x + {18 << 1, 0}, {19 << 1, 0}, // 12: 0000 10x + {0, 9}, {0, 8}, // 13: 0000 11x + {-1, 0}, {20 << 1, 0}, // 14: 0000 000x + {-1, 0}, {21 << 1, 0}, // 15: 0000 001x + {22 << 1, 0}, {23 << 1, 0}, // 16: 0000 010x + {0, 15}, {0, 14}, // 17: 0000 011x + {0, 13}, {0, 12}, // 18: 0000 100x + {0, 11}, {0, 10}, // 19: 0000 101x + {24 << 1, 0}, {25 << 1, 0}, // 20: 0000 0001x + {26 << 1, 0}, {27 << 1, 0}, // 21: 0000 0011x + {28 << 1, 0}, {29 << 1, 0}, // 22: 0000 0100x + {30 << 1, 0}, {31 << 1, 0}, // 23: 0000 0101x + {32 << 1, 0}, {-1, 0}, // 24: 0000 0001 0x + {-1, 0}, {33 << 1, 0}, // 25: 0000 0001 1x + {34 << 1, 0}, {35 << 1, 0}, // 26: 0000 0011 0x + {36 << 1, 0}, {37 << 1, 0}, // 27: 0000 0011 1x + {38 << 1, 0}, {39 << 1, 0}, // 28: 0000 0100 0x + {0, 21}, {0, 20}, // 29: 0000 0100 1x + {0, 19}, {0, 18}, // 30: 0000 0101 0x + {0, 17}, {0, 16}, // 31: 0000 0101 1x + {0, 35}, {-1, 0}, // 32: 0000 0001 00x + {-1, 0}, {0, 34}, // 33: 0000 0001 11x + {0, 33}, {0, 32}, // 34: 0000 0011 00x + {0, 31}, {0, 30}, // 35: 0000 0011 01x + {0, 29}, {0, 28}, // 36: 0000 0011 10x + {0, 27}, {0, 26}, // 37: 0000 0011 11x + {0, 25}, {0, 24}, // 38: 0000 0100 00x + {0, 23}, {0, 22}, // 39: 0000 0100 01x +}; + +static const plm_vlc_t PLM_VIDEO_MACROBLOCK_TYPE_INTRA[] = { + {1 << 1, 0}, + {0, 0x01}, // 0: x + {-1, 0}, + {0, 0x11}, // 1: 0x +}; + +static const plm_vlc_t PLM_VIDEO_MACROBLOCK_TYPE_PREDICTIVE[] = { + {1 << 1, 0}, {0, 0x0a}, // 0: x + {2 << 1, 0}, {0, 0x02}, // 1: 0x + {3 << 1, 0}, {0, 0x08}, // 2: 00x + {4 << 1, 0}, {5 << 1, 0}, // 3: 000x + {6 << 1, 0}, {0, 0x12}, // 4: 0000x + {0, 0x1a}, {0, 0x01}, // 5: 0001x + {-1, 0}, {0, 0x11}, // 6: 0000 0x +}; + +static const plm_vlc_t PLM_VIDEO_MACROBLOCK_TYPE_B[] = { + {1 << 1, 0}, {2 << 1, 0}, // 0: x + {3 << 1, 0}, {4 << 1, 0}, // 1: 0x + {0, 0x0c}, {0, 0x0e}, // 2: 1x + {5 << 1, 0}, {6 << 1, 0}, // 3: 00x + {0, 0x04}, {0, 0x06}, // 4: 01x + {7 << 1, 0}, {8 << 1, 0}, // 5: 000x + {0, 0x08}, {0, 0x0a}, // 6: 001x + {9 << 1, 0}, {10 << 1, 0}, // 7: 0000x + {0, 0x1e}, {0, 0x01}, // 8: 0001x + {-1, 0}, {0, 0x11}, // 9: 0000 0x + {0, 0x16}, {0, 0x1a}, // 10: 0000 1x +}; + +static const plm_vlc_t PLM_VIDEO_CODE_BLOCK_PATTERN[] = { + {1 << 1, 0}, {2 << 1, 0}, // 0: x + {3 << 1, 0}, {4 << 1, 0}, // 1: 0x + {5 << 1, 0}, {6 << 1, 0}, // 2: 1x + {7 << 1, 0}, {8 << 1, 0}, // 3: 00x + {9 << 1, 0}, {10 << 1, 0}, // 4: 01x + {11 << 1, 0}, {12 << 1, 0}, // 5: 10x + {13 << 1, 0}, {0, 60}, // 6: 11x + {14 << 1, 0}, {15 << 1, 0}, // 7: 000x + {16 << 1, 0}, {17 << 1, 0}, // 8: 001x + {18 << 1, 0}, {19 << 1, 0}, // 9: 010x + {20 << 1, 0}, {21 << 1, 0}, // 10: 011x + {22 << 1, 0}, {23 << 1, 0}, // 11: 100x + {0, 32}, {0, 16}, // 12: 101x + {0, 8}, {0, 4}, // 13: 110x + {24 << 1, 0}, {25 << 1, 0}, // 14: 0000x + {26 << 1, 0}, {27 << 1, 0}, // 15: 0001x + {28 << 1, 0}, {29 << 1, 0}, // 16: 0010x + {30 << 1, 0}, {31 << 1, 0}, // 17: 0011x + {0, 62}, {0, 2}, // 18: 0100x + {0, 61}, {0, 1}, // 19: 0101x + {0, 56}, {0, 52}, // 20: 0110x + {0, 44}, {0, 28}, // 21: 0111x + {0, 40}, {0, 20}, // 22: 1000x + {0, 48}, {0, 12}, // 23: 1001x + {32 << 1, 0}, {33 << 1, 0}, // 24: 0000 0x + {34 << 1, 0}, {35 << 1, 0}, // 25: 0000 1x + {36 << 1, 0}, {37 << 1, 0}, // 26: 0001 0x + {38 << 1, 0}, {39 << 1, 0}, // 27: 0001 1x + {40 << 1, 0}, {41 << 1, 0}, // 28: 0010 0x + {42 << 1, 0}, {43 << 1, 0}, // 29: 0010 1x + {0, 63}, {0, 3}, // 30: 0011 0x + {0, 36}, {0, 24}, // 31: 0011 1x + {44 << 1, 0}, {45 << 1, 0}, // 32: 0000 00x + {46 << 1, 0}, {47 << 1, 0}, // 33: 0000 01x + {48 << 1, 0}, {49 << 1, 0}, // 34: 0000 10x + {50 << 1, 0}, {51 << 1, 0}, // 35: 0000 11x + {52 << 1, 0}, {53 << 1, 0}, // 36: 0001 00x + {54 << 1, 0}, {55 << 1, 0}, // 37: 0001 01x + {56 << 1, 0}, {57 << 1, 0}, // 38: 0001 10x + {58 << 1, 0}, {59 << 1, 0}, // 39: 0001 11x + {0, 34}, {0, 18}, // 40: 0010 00x + {0, 10}, {0, 6}, // 41: 0010 01x + {0, 33}, {0, 17}, // 42: 0010 10x + {0, 9}, {0, 5}, // 43: 0010 11x + {-1, 0}, {60 << 1, 0}, // 44: 0000 000x + {61 << 1, 0}, {62 << 1, 0}, // 45: 0000 001x + {0, 58}, {0, 54}, // 46: 0000 010x + {0, 46}, {0, 30}, // 47: 0000 011x + {0, 57}, {0, 53}, // 48: 0000 100x + {0, 45}, {0, 29}, // 49: 0000 101x + {0, 38}, {0, 26}, // 50: 0000 110x + {0, 37}, {0, 25}, // 51: 0000 111x + {0, 43}, {0, 23}, // 52: 0001 000x + {0, 51}, {0, 15}, // 53: 0001 001x + {0, 42}, {0, 22}, // 54: 0001 010x + {0, 50}, {0, 14}, // 55: 0001 011x + {0, 41}, {0, 21}, // 56: 0001 100x + {0, 49}, {0, 13}, // 57: 0001 101x + {0, 35}, {0, 19}, // 58: 0001 110x + {0, 11}, {0, 7}, // 59: 0001 111x + {0, 39}, {0, 27}, // 60: 0000 0001x + {0, 59}, {0, 55}, // 61: 0000 0010x + {0, 47}, {0, 31}, // 62: 0000 0011x +}; + +static const plm_vlc_t PLM_VIDEO_MOTION[] = { + {1 << 1, 0}, {0, 0}, // 0: x + {2 << 1, 0}, {3 << 1, 0}, // 1: 0x + {4 << 1, 0}, {5 << 1, 0}, // 2: 00x + {0, 1}, {0, -1}, // 3: 01x + {6 << 1, 0}, {7 << 1, 0}, // 4: 000x + {0, 2}, {0, -2}, // 5: 001x + {8 << 1, 0}, {9 << 1, 0}, // 6: 0000x + {0, 3}, {0, -3}, // 7: 0001x + {10 << 1, 0}, {11 << 1, 0}, // 8: 0000 0x + {12 << 1, 0}, {13 << 1, 0}, // 9: 0000 1x + {-1, 0}, {14 << 1, 0}, // 10: 0000 00x + {15 << 1, 0}, {16 << 1, 0}, // 11: 0000 01x + {17 << 1, 0}, {18 << 1, 0}, // 12: 0000 10x + {0, 4}, {0, -4}, // 13: 0000 11x + {-1, 0}, {19 << 1, 0}, // 14: 0000 001x + {20 << 1, 0}, {21 << 1, 0}, // 15: 0000 010x + {0, 7}, {0, -7}, // 16: 0000 011x + {0, 6}, {0, -6}, // 17: 0000 100x + {0, 5}, {0, -5}, // 18: 0000 101x + {22 << 1, 0}, {23 << 1, 0}, // 19: 0000 0011x + {24 << 1, 0}, {25 << 1, 0}, // 20: 0000 0100x + {26 << 1, 0}, {27 << 1, 0}, // 21: 0000 0101x + {28 << 1, 0}, {29 << 1, 0}, // 22: 0000 0011 0x + {30 << 1, 0}, {31 << 1, 0}, // 23: 0000 0011 1x + {32 << 1, 0}, {33 << 1, 0}, // 24: 0000 0100 0x + {0, 10}, {0, -10}, // 25: 0000 0100 1x + {0, 9}, {0, -9}, // 26: 0000 0101 0x + {0, 8}, {0, -8}, // 27: 0000 0101 1x + {0, 16}, {0, -16}, // 28: 0000 0011 00x + {0, 15}, {0, -15}, // 29: 0000 0011 01x + {0, 14}, {0, -14}, // 30: 0000 0011 10x + {0, 13}, {0, -13}, // 31: 0000 0011 11x + {0, 12}, {0, -12}, // 32: 0000 0100 00x + {0, 11}, {0, -11}, // 33: 0000 0100 01x +}; + +static const plm_vlc_t PLM_VIDEO_DCT_SIZE_LUMINANCE[] = { + {1 << 1, 0}, {2 << 1, 0}, // 0: x + {0, 1}, {0, 2}, // 1: 0x + {3 << 1, 0}, {4 << 1, 0}, // 2: 1x + {0, 0}, {0, 3}, // 3: 10x + {0, 4}, {5 << 1, 0}, // 4: 11x + {0, 5}, {6 << 1, 0}, // 5: 111x + {0, 6}, {7 << 1, 0}, // 6: 1111x + {0, 7}, {8 << 1, 0}, // 7: 1111 1x + {0, 8}, {-1, 0}, // 8: 1111 11x +}; + +static const plm_vlc_t PLM_VIDEO_DCT_SIZE_CHROMINANCE[] = { + {1 << 1, 0}, {2 << 1, 0}, // 0: x + {0, 0}, {0, 1}, // 1: 0x + {0, 2}, {3 << 1, 0}, // 2: 1x + {0, 3}, {4 << 1, 0}, // 3: 11x + {0, 4}, {5 << 1, 0}, // 4: 111x + {0, 5}, {6 << 1, 0}, // 5: 1111x + {0, 6}, {7 << 1, 0}, // 6: 1111 1x + {0, 7}, {8 << 1, 0}, // 7: 1111 11x + {0, 8}, {-1, 0}, // 8: 1111 111x +}; + +// dct_coeff bitmap: +// 0xff00 run +// 0x00ff level + +// Decoded values are unsigned. Sign bit follows in the stream. + +static const plm_vlc_uint_t PLM_VIDEO_DCT_COEFF[] = { + {1 << 1, 0}, {0, 0x0001}, // 0: x + {2 << 1, 0}, {3 << 1, 0}, // 1: 0x + {4 << 1, 0}, {5 << 1, 0}, // 2: 00x + {6 << 1, 0}, {0, 0x0101}, // 3: 01x + {7 << 1, 0}, {8 << 1, 0}, // 4: 000x + {9 << 1, 0}, {10 << 1, 0}, // 5: 001x + {0, 0x0002}, {0, 0x0201}, // 6: 010x + {11 << 1, 0}, {12 << 1, 0}, // 7: 0000x + {13 << 1, 0}, {14 << 1, 0}, // 8: 0001x + {15 << 1, 0}, {0, 0x0003}, // 9: 0010x + {0, 0x0401}, {0, 0x0301}, // 10: 0011x + {16 << 1, 0}, {0, 0xffff}, // 11: 0000 0x + {17 << 1, 0}, {18 << 1, 0}, // 12: 0000 1x + {0, 0x0701}, {0, 0x0601}, // 13: 0001 0x + {0, 0x0102}, {0, 0x0501}, // 14: 0001 1x + {19 << 1, 0}, {20 << 1, 0}, // 15: 0010 0x + {21 << 1, 0}, {22 << 1, 0}, // 16: 0000 00x + {0, 0x0202}, {0, 0x0901}, // 17: 0000 10x + {0, 0x0004}, {0, 0x0801}, // 18: 0000 11x + {23 << 1, 0}, {24 << 1, 0}, // 19: 0010 00x + {25 << 1, 0}, {26 << 1, 0}, // 20: 0010 01x + {27 << 1, 0}, {28 << 1, 0}, // 21: 0000 000x + {29 << 1, 0}, {30 << 1, 0}, // 22: 0000 001x + {0, 0x0d01}, {0, 0x0006}, // 23: 0010 000x + {0, 0x0c01}, {0, 0x0b01}, // 24: 0010 001x + {0, 0x0302}, {0, 0x0103}, // 25: 0010 010x + {0, 0x0005}, {0, 0x0a01}, // 26: 0010 011x + {31 << 1, 0}, {32 << 1, 0}, // 27: 0000 0000x + {33 << 1, 0}, {34 << 1, 0}, // 28: 0000 0001x + {35 << 1, 0}, {36 << 1, 0}, // 29: 0000 0010x + {37 << 1, 0}, {38 << 1, 0}, // 30: 0000 0011x + {39 << 1, 0}, {40 << 1, 0}, // 31: 0000 0000 0x + {41 << 1, 0}, {42 << 1, 0}, // 32: 0000 0000 1x + {43 << 1, 0}, {44 << 1, 0}, // 33: 0000 0001 0x + {45 << 1, 0}, {46 << 1, 0}, // 34: 0000 0001 1x + {0, 0x1001}, {0, 0x0502}, // 35: 0000 0010 0x + {0, 0x0007}, {0, 0x0203}, // 36: 0000 0010 1x + {0, 0x0104}, {0, 0x0f01}, // 37: 0000 0011 0x + {0, 0x0e01}, {0, 0x0402}, // 38: 0000 0011 1x + {47 << 1, 0}, {48 << 1, 0}, // 39: 0000 0000 00x + {49 << 1, 0}, {50 << 1, 0}, // 40: 0000 0000 01x + {51 << 1, 0}, {52 << 1, 0}, // 41: 0000 0000 10x + {53 << 1, 0}, {54 << 1, 0}, // 42: 0000 0000 11x + {55 << 1, 0}, {56 << 1, 0}, // 43: 0000 0001 00x + {57 << 1, 0}, {58 << 1, 0}, // 44: 0000 0001 01x + {59 << 1, 0}, {60 << 1, 0}, // 45: 0000 0001 10x + {61 << 1, 0}, {62 << 1, 0}, // 46: 0000 0001 11x + {-1, 0}, {63 << 1, 0}, // 47: 0000 0000 000x + {64 << 1, 0}, {65 << 1, 0}, // 48: 0000 0000 001x + {66 << 1, 0}, {67 << 1, 0}, // 49: 0000 0000 010x + {68 << 1, 0}, {69 << 1, 0}, // 50: 0000 0000 011x + {70 << 1, 0}, {71 << 1, 0}, // 51: 0000 0000 100x + {72 << 1, 0}, {73 << 1, 0}, // 52: 0000 0000 101x + {74 << 1, 0}, {75 << 1, 0}, // 53: 0000 0000 110x + {76 << 1, 0}, {77 << 1, 0}, // 54: 0000 0000 111x + {0, 0x000b}, {0, 0x0802}, // 55: 0000 0001 000x + {0, 0x0403}, {0, 0x000a}, // 56: 0000 0001 001x + {0, 0x0204}, {0, 0x0702}, // 57: 0000 0001 010x + {0, 0x1501}, {0, 0x1401}, // 58: 0000 0001 011x + {0, 0x0009}, {0, 0x1301}, // 59: 0000 0001 100x + {0, 0x1201}, {0, 0x0105}, // 60: 0000 0001 101x + {0, 0x0303}, {0, 0x0008}, // 61: 0000 0001 110x + {0, 0x0602}, {0, 0x1101}, // 62: 0000 0001 111x + {78 << 1, 0}, {79 << 1, 0}, // 63: 0000 0000 0001x + {80 << 1, 0}, {81 << 1, 0}, // 64: 0000 0000 0010x + {82 << 1, 0}, {83 << 1, 0}, // 65: 0000 0000 0011x + {84 << 1, 0}, {85 << 1, 0}, // 66: 0000 0000 0100x + {86 << 1, 0}, {87 << 1, 0}, // 67: 0000 0000 0101x + {88 << 1, 0}, {89 << 1, 0}, // 68: 0000 0000 0110x + {90 << 1, 0}, {91 << 1, 0}, // 69: 0000 0000 0111x + {0, 0x0a02}, {0, 0x0902}, // 70: 0000 0000 1000x + {0, 0x0503}, {0, 0x0304}, // 71: 0000 0000 1001x + {0, 0x0205}, {0, 0x0107}, // 72: 0000 0000 1010x + {0, 0x0106}, {0, 0x000f}, // 73: 0000 0000 1011x + {0, 0x000e}, {0, 0x000d}, // 74: 0000 0000 1100x + {0, 0x000c}, {0, 0x1a01}, // 75: 0000 0000 1101x + {0, 0x1901}, {0, 0x1801}, // 76: 0000 0000 1110x + {0, 0x1701}, {0, 0x1601}, // 77: 0000 0000 1111x + {92 << 1, 0}, {93 << 1, 0}, // 78: 0000 0000 0001 0x + {94 << 1, 0}, {95 << 1, 0}, // 79: 0000 0000 0001 1x + {96 << 1, 0}, {97 << 1, 0}, // 80: 0000 0000 0010 0x + {98 << 1, 0}, {99 << 1, 0}, // 81: 0000 0000 0010 1x + {100 << 1, 0}, {101 << 1, 0}, // 82: 0000 0000 0011 0x + {102 << 1, 0}, {103 << 1, 0}, // 83: 0000 0000 0011 1x + {0, 0x001f}, {0, 0x001e}, // 84: 0000 0000 0100 0x + {0, 0x001d}, {0, 0x001c}, // 85: 0000 0000 0100 1x + {0, 0x001b}, {0, 0x001a}, // 86: 0000 0000 0101 0x + {0, 0x0019}, {0, 0x0018}, // 87: 0000 0000 0101 1x + {0, 0x0017}, {0, 0x0016}, // 88: 0000 0000 0110 0x + {0, 0x0015}, {0, 0x0014}, // 89: 0000 0000 0110 1x + {0, 0x0013}, {0, 0x0012}, // 90: 0000 0000 0111 0x + {0, 0x0011}, {0, 0x0010}, // 91: 0000 0000 0111 1x + {104 << 1, 0}, {105 << 1, 0}, // 92: 0000 0000 0001 00x + {106 << 1, 0}, {107 << 1, 0}, // 93: 0000 0000 0001 01x + {108 << 1, 0}, {109 << 1, 0}, // 94: 0000 0000 0001 10x + {110 << 1, 0}, {111 << 1, 0}, // 95: 0000 0000 0001 11x + {0, 0x0028}, {0, 0x0027}, // 96: 0000 0000 0010 00x + {0, 0x0026}, {0, 0x0025}, // 97: 0000 0000 0010 01x + {0, 0x0024}, {0, 0x0023}, // 98: 0000 0000 0010 10x + {0, 0x0022}, {0, 0x0021}, // 99: 0000 0000 0010 11x + {0, 0x0020}, {0, 0x010e}, // 100: 0000 0000 0011 00x + {0, 0x010d}, {0, 0x010c}, // 101: 0000 0000 0011 01x + {0, 0x010b}, {0, 0x010a}, // 102: 0000 0000 0011 10x + {0, 0x0109}, {0, 0x0108}, // 103: 0000 0000 0011 11x + {0, 0x0112}, {0, 0x0111}, // 104: 0000 0000 0001 000x + {0, 0x0110}, {0, 0x010f}, // 105: 0000 0000 0001 001x + {0, 0x0603}, {0, 0x1002}, // 106: 0000 0000 0001 010x + {0, 0x0f02}, {0, 0x0e02}, // 107: 0000 0000 0001 011x + {0, 0x0d02}, {0, 0x0c02}, // 108: 0000 0000 0001 100x + {0, 0x0b02}, {0, 0x1f01}, // 109: 0000 0000 0001 101x + {0, 0x1e01}, {0, 0x1d01}, // 110: 0000 0000 0001 110x + {0, 0x1c01}, {0, 0x1b01}, // 111: 0000 0000 0001 111x +}; + +long plmpegdecode_latency_; + +static plm_vlc_t *PLM_VIDEO_MACROBLOCK_TYPE[4]; +static plm_vlc_t *PLM_VIDEO_DCT_SIZE[3]; + +static textstartup void __init_mpeg1(void) { + PLM_VIDEO_MACROBLOCK_TYPE[0] = NULL; + PLM_VIDEO_MACROBLOCK_TYPE[1] = PLM_VIDEO_MACROBLOCK_TYPE_INTRA; + PLM_VIDEO_MACROBLOCK_TYPE[2] = PLM_VIDEO_MACROBLOCK_TYPE_PREDICTIVE, + PLM_VIDEO_MACROBLOCK_TYPE[3] = PLM_VIDEO_MACROBLOCK_TYPE_B; + PLM_VIDEO_DCT_SIZE[0] = PLM_VIDEO_DCT_SIZE_LUMINANCE; + PLM_VIDEO_DCT_SIZE[1] = PLM_VIDEO_DCT_SIZE_CHROMINANCE; + PLM_VIDEO_DCT_SIZE[2] = PLM_VIDEO_DCT_SIZE_CHROMINANCE; +} + +INITIALIZER(300, _init_mpeg1, __init_mpeg1()); + +#define plm_clamp(n) MIN(255, MAX(0, n)) + +void plm_video_destroy(plm_video_t *self) { + if (self->destroy_buffer_when_done) { + plm_buffer_destroy(self->buffer); + } + if (self->has_sequence_header) { + free(self->frames_data); + } + free(self); +} + +double plm_video_get_pixel_aspect_ratio(plm_video_t *self) { + return self->pixel_aspect_ratio; +} + +double plm_video_get_framerate(plm_video_t *self) { + return self->framerate; +} + +int plm_video_get_width(plm_video_t *self) { + return self->width; +} + +int plm_video_get_height(plm_video_t *self) { + return self->height; +} + +void plm_video_set_no_delay(plm_video_t *self, int no_delay) { + self->assume_no_b_frames = no_delay; +} + +double plm_video_get_time(plm_video_t *self) { + return self->time; +} + +void plm_video_rewind(plm_video_t *self) { + plm_buffer_rewind(self->buffer); + self->time = 0; + self->frames_decoded = 0; + self->has_reference_frame = false; +} + +void plm_video_init_frame(plm_video_t *self, plm_frame_t *frame, + uint8_t *base) { + size_t plane_size = self->luma_width * self->luma_height; + frame->width = self->width; + frame->height = self->height; + frame->y.width = self->luma_width; + frame->y.height = self->luma_height; + frame->y.data = base; + frame->cr.width = self->chroma_width; + frame->cr.height = self->chroma_height; + frame->cr.data = base + plane_size; + frame->cb.width = self->chroma_width; + frame->cb.height = self->chroma_height; + frame->cb.data = base + plane_size * 2; +} + +void plm_video_decode_sequence_header(plm_video_t *self) { + int previous_width = self->width; + int previous_height = self->height; + + self->width = plm_buffer_read(self->buffer, 12); + self->height = plm_buffer_read(self->buffer, 12); + + int pixel_aspect_ratio_code; + pixel_aspect_ratio_code = plm_buffer_read(self->buffer, 4); + pixel_aspect_ratio_code -= 1; + pixel_aspect_ratio_code = MAX(pixel_aspect_ratio_code, 0); + pixel_aspect_ratio_code = + MIN(pixel_aspect_ratio_code, ARRAYLEN(PLM_VIDEO_PIXEL_ASPECT_RATIO) - 1); + self->pixel_aspect_ratio = + PLM_VIDEO_PIXEL_ASPECT_RATIO[pixel_aspect_ratio_code]; + + int framerate_code; + framerate_code = plm_buffer_read(self->buffer, 4); + framerate_code -= 1; + framerate_code = MAX(framerate_code, 0); + framerate_code = MIN(framerate_code, ARRAYLEN(PLM_VIDEO_PICTURE_RATE) - 1); + self->framerate = PLM_VIDEO_PICTURE_RATE[framerate_code]; + + // skip bitRate, marker, bufferSize and constrained bit + plm_buffer_skip(self->buffer, 18 + 1 + 10 + 1); + + if (plm_buffer_read(self->buffer, 1)) { // load custom intra quant matrix? + for (int i = 0; i < 64; i++) { + int idx = PLM_VIDEO_ZIG_ZAG[i]; + self->intra_quant_matrix[idx] = plm_buffer_read(self->buffer, 8); + } + } else { + memcpy(self->intra_quant_matrix, PLM_VIDEO_INTRAQUANT_MATRIX, 64); + } + + if (plm_buffer_read(self->buffer, + 1)) { // load custom non intra quant matrix? + for (int i = 0; i < 64; i++) { + int idx = PLM_VIDEO_ZIG_ZAG[i]; + self->non_intra_quant_matrix[idx] = plm_buffer_read(self->buffer, 8); + } + } else { + memcpy(self->non_intra_quant_matrix, PLM_VIDEO_NONINTRAQUANT_MATRIX, 64); + } + + if (self->has_sequence_header) { + if (self->width == previous_width && self->height == previous_height) { + // We already had a sequence header with the same width/height; + // nothing else to do here. + return; + } + + // We had a sequence header but with different dimensions; + // delete the previous planes and allocate new. + free(self->frames_data); + } + + self->mb_width = (self->width + 15) >> 4; + self->mb_height = (self->height + 15) >> 4; + self->mb_size = self->mb_width * self->mb_height; + self->luma_width = self->mb_width << 4; + self->luma_height = self->mb_height << 4; + self->chroma_width = self->mb_width << 3; + self->chroma_height = self->mb_height << 3; + + size_t plane_size = self->luma_width * self->luma_height; + self->frames_data = memalign(64, plane_size * 9); + plm_video_init_frame(self, &self->frame_current, + self->frames_data + plane_size * 0); + plm_video_init_frame(self, &self->frame_forward, + self->frames_data + plane_size * 3); + plm_video_init_frame(self, &self->frame_backward, + self->frames_data + plane_size * 6); + + self->has_sequence_header = true; + + LOGF("%s:\n" + "\t%-20s = %15d;\n" + "\t%-20s = %15d;\n" + "\t%-20s = %15f;\n" + "\t%-20s = %15f;\n" + "\t%-20s = %15d;\n" + "\t%-20s = %15d;\n" + "\t%-20s = %15d;\n" + "\t%-20s = %15d;\n" + "\t%-20s = %15d;\n" + "\t%-20s = %15d;\n" + "\t%-20s = %15d;", + "New MPEG Sequence", "width", self->width, "height", self->height, + "framerate", self->framerate, "pixel_aspect_ratio", + self->pixel_aspect_ratio, "mb_size", self->mb_size, "mb_width", + self->mb_width, "mb_height", self->mb_height, "luma_width", + self->luma_width, "luma_height", self->luma_height, "chroma_width", + self->chroma_width, "chroma_height", self->chroma_height); +} + +static void plm_video_copy_macroblock(plm_video_t *self, int motion_h, + int motion_v, plm_frame_t *d) { + plm_frame_t *s = &self->frame_current; + plm_video_process_macroblock_16(self, s->y.data, d->y.data, motion_h, + motion_v, false); + plm_video_process_macroblock_8(self, s->cr.data, d->cr.data, motion_h / 2, + motion_v / 2, false); + plm_video_process_macroblock_8(self, s->cb.data, d->cb.data, motion_h / 2, + motion_v / 2, false); +} + +static void plm_video_interpolate_macroblock(plm_video_t *self, int motion_h, + int motion_v, plm_frame_t *d) { + plm_frame_t *s = &self->frame_current; + plm_video_process_macroblock_16(self, s->y.data, d->y.data, motion_h, + motion_v, true); + plm_video_process_macroblock_8(self, s->cr.data, d->cr.data, motion_h / 2, + motion_v / 2, true); + plm_video_process_macroblock_8(self, s->cb.data, d->cb.data, motion_h / 2, + motion_v / 2, true); +} + +static int plm_video_decode_motion_vector(plm_video_t *self, int r_size, + int motion) { + int fscale = 1u << r_size; + int m_code = plm_buffer_read_vlc(self->buffer, PLM_VIDEO_MOTION); + int r = 0; + int d; + if ((m_code != 0) && (fscale != 1)) { + r = plm_buffer_read(self->buffer, r_size); + d = ((abs(m_code) - 1) << r_size) + r + 1; + if (m_code < 0) { + d = -d; + } + } else { + d = m_code; + } + motion += d; + if (motion > (fscale << 4) - 1) { + motion -= fscale << 5; + } else if (motion < (int)(((unsigned)-fscale) << 4)) { + motion += fscale << 5; + } + return motion; +} + +static void plm_video_decode_motion_vectors(plm_video_t *self) { + // Forward + if (self->motion_forward.is_set) { + int r_size = self->motion_forward.r_size; + self->motion_forward.h = + plm_video_decode_motion_vector(self, r_size, self->motion_forward.h); + self->motion_forward.v = + plm_video_decode_motion_vector(self, r_size, self->motion_forward.v); + } else if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE) { + // No motion information in P-picture, reset vectors + self->motion_forward.h = 0; + self->motion_forward.v = 0; + } + if (self->motion_backward.is_set) { + int r_size = self->motion_backward.r_size; + self->motion_backward.h = + plm_video_decode_motion_vector(self, r_size, self->motion_backward.h); + self->motion_backward.v = + plm_video_decode_motion_vector(self, r_size, self->motion_backward.v); + } +} + +static void plm_video_predict_macroblock(plm_video_t *self) { + int fw_h = self->motion_forward.h; + int fw_v = self->motion_forward.v; + if (self->motion_forward.full_px) { + fw_h <<= 1; + fw_v <<= 1; + } + if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_B) { + int bw_h = self->motion_backward.h; + int bw_v = self->motion_backward.v; + if (self->motion_backward.full_px) { + bw_h <<= 1; + bw_v <<= 1; + } + if (self->motion_forward.is_set) { + plm_video_copy_macroblock(self, fw_h, fw_v, &self->frame_forward); + if (self->motion_backward.is_set) { + plm_video_interpolate_macroblock(self, bw_h, bw_v, + &self->frame_backward); + } + } else { + plm_video_copy_macroblock(self, bw_h, bw_v, &self->frame_backward); + } + } else { + plm_video_copy_macroblock(self, fw_h, fw_v, &self->frame_forward); + } +} + +static void plm_video_decode_block(plm_video_t *self, int block) { + int n = 0; + uint8_t *quant_matrix; + + // Decode DC coefficient of intra-coded blocks + if (self->macroblock_intra) { + int predictor; + int dct_size; + + // DC prediction + int plane_index = block > 3 ? block - 3 : 0; + predictor = self->dc_predictor[plane_index]; + dct_size = + plm_buffer_read_vlc(self->buffer, PLM_VIDEO_DCT_SIZE[plane_index]); + + // Read DC coeff + if (dct_size > 0) { + int differential = plm_buffer_read(self->buffer, dct_size); + if ((differential & (1 << (dct_size - 1))) != 0) { + self->block_data[0] = predictor + differential; + } else { + self->block_data[0] = + predictor + ((-1u << dct_size) | (differential + 1)); + } + } else { + self->block_data[0] = predictor; + } + + // Save predictor value + self->dc_predictor[plane_index] = self->block_data[0]; + + // Dequantize + premultiply + self->block_data[0] <<= (3 + 5); + + quant_matrix = self->intra_quant_matrix; + n = 1; + } else { + quant_matrix = self->non_intra_quant_matrix; + } + + // Decode AC coefficients (+DC for non-intra) + int level = 0; + while (true) { + int run = 0; + uint16_t coeff = + plm_buffer_read_vlc_uint(self->buffer, PLM_VIDEO_DCT_COEFF); + + if ((coeff == 0x0001) && (n > 0) && + (plm_buffer_read(self->buffer, 1) == 0)) { + // end_of_block + break; + } + if (coeff == 0xffff) { + // escape + run = plm_buffer_read(self->buffer, 6); + level = plm_buffer_read(self->buffer, 8); + if (level == 0) { + level = plm_buffer_read(self->buffer, 8); + } else if (level == 128) { + level = plm_buffer_read(self->buffer, 8) - 256; + } else if (level > 128) { + level = level - 256; + } + } else { + run = coeff >> 8; + level = coeff & 0xff; + if (plm_buffer_read(self->buffer, 1)) { + level = -level; + } + } + + n += run; + if (n < 0 || n >= 64) { + return; // invalid + } + + int de_zig_zagged = PLM_VIDEO_ZIG_ZAG[n]; + n++; + + // Dequantize, oddify, clip + level = (unsigned)level << 1; + if (!self->macroblock_intra) { + level += (level < 0 ? -1 : 1); + } + level = (level * self->quantizer_scale * quant_matrix[de_zig_zagged]) >> 4; + if ((level & 1) == 0) { + level -= level > 0 ? 1 : -1; + } + if (level > 2047) { + level = 2047; + } else if (level < -2048) { + level = -2048; + } + + // Save premultiplied coefficient + self->block_data[de_zig_zagged] = + level * PLM_VIDEO_PREMULTIPLIER_MATRIX[de_zig_zagged]; + } + + // Move block to its place + uint8_t *d; + int dw; + int di; + + if (block < 4) { + d = self->frame_current.y.data; + dw = self->luma_width; + di = (self->mb_row * self->luma_width + self->mb_col) << 4; + if ((block & 1) != 0) { + di += 8; + } + if ((block & 2) != 0) { + di += self->luma_width << 3; + } + } else { + d = (block == 4) ? self->frame_current.cb.data + : self->frame_current.cr.data; + dw = self->chroma_width; + di = ((self->mb_row * self->luma_width) << 2) + (self->mb_col << 3); + } + + int *s = self->block_data; + int si = 0; + if (self->macroblock_intra) { + // Overwrite (no prediction) + if (n == 1) { + int clamped = plm_clamp((s[0] + 128) >> 8); + PLM_BLOCK_SET(d, di, dw, si, 8, 8, clamped); + s[0] = 0; + } else { + plm_video_idct(s); + PLM_BLOCK_SET(d, di, dw, si, 8, 8, plm_clamp(s[si])); + memset(self->block_data, 0, sizeof(self->block_data)); + } + } else { + // Add data to the predicted macroblock + if (n == 1) { + int value = (s[0] + 128) >> 8; + PLM_BLOCK_SET(d, di, dw, si, 8, 8, plm_clamp(d[di] + value)); + s[0] = 0; + } else { + plm_video_idct(s); + PLM_BLOCK_SET(d, di, dw, si, 8, 8, plm_clamp(d[di] + s[si])); + memset(self->block_data, 0, sizeof(self->block_data)); + } + } +} + +static void plm_video_decode_macroblock(plm_video_t *self) { + // Decode self->macroblock_address_increment + int increment = 0; + int t = + plm_buffer_read_vlc(self->buffer, PLM_VIDEO_MACROBLOCK_ADDRESS_INCREMENT); + + while (t == 34) { + // macroblock_stuffing + t = plm_buffer_read_vlc(self->buffer, + PLM_VIDEO_MACROBLOCK_ADDRESS_INCREMENT); + } + while (t == 35) { + // macroblock_escape + increment += 33; + t = plm_buffer_read_vlc(self->buffer, + PLM_VIDEO_MACROBLOCK_ADDRESS_INCREMENT); + } + increment += t; + + // Process any skipped macroblocks + if (self->slice_begin) { + // The first self->macroblock_address_increment of each slice is relative + // to beginning of the preverious row, not the preverious macroblock + self->slice_begin = false; + self->macroblock_address += increment; + } else { + if (self->macroblock_address + increment >= self->mb_size) { + return; // invalid + } + if (increment > 1) { + // Skipped macroblocks reset DC predictors + self->dc_predictor[0] = 128; + self->dc_predictor[1] = 128; + self->dc_predictor[2] = 128; + + // Skipped macroblocks in P-pictures reset motion vectors + if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE) { + self->motion_forward.h = 0; + self->motion_forward.v = 0; + } + } + + // Predict skipped macroblocks + while (increment > 1) { + self->macroblock_address++; + self->mb_row = self->macroblock_address / self->mb_width; + self->mb_col = self->macroblock_address % self->mb_width; + + plm_video_predict_macroblock(self); + increment--; + } + self->macroblock_address++; + } + + self->mb_row = self->macroblock_address / self->mb_width; + self->mb_col = self->macroblock_address % self->mb_width; + + if (self->mb_col >= self->mb_width || self->mb_row >= self->mb_height) { + return; // corrupt stream; + } + + // Process the current macroblock + // static const s16 *mbTable = MACROBLOCK_TYPE[self->picture_type]; + // macroblock_type = read_huffman(self->bits, mbTable); + + const plm_vlc_t *table = PLM_VIDEO_MACROBLOCK_TYPE[self->picture_type]; + self->macroblock_type = plm_buffer_read_vlc(self->buffer, table); + + self->macroblock_intra = (self->macroblock_type & 0x01); + self->motion_forward.is_set = (self->macroblock_type & 0x08); + self->motion_backward.is_set = (self->macroblock_type & 0x04); + + // Quantizer scale + if ((self->macroblock_type & 0x10) != 0) { + self->quantizer_scale = plm_buffer_read(self->buffer, 5); + } + + if (self->macroblock_intra) { + // Intra-coded macroblocks reset motion vectors + self->motion_backward.h = self->motion_forward.h = 0; + self->motion_backward.v = self->motion_forward.v = 0; + } else { + // Non-intra macroblocks reset DC predictors + self->dc_predictor[0] = 128; + self->dc_predictor[1] = 128; + self->dc_predictor[2] = 128; + + plm_video_decode_motion_vectors(self); + plm_video_predict_macroblock(self); + } + + // Decode blocks + int cbp = + ((self->macroblock_type & 0x02) != 0) + ? plm_buffer_read_vlc(self->buffer, PLM_VIDEO_CODE_BLOCK_PATTERN) + : (self->macroblock_intra ? 0x3f : 0); + + for (int block = 0, mask = 0x20; block < 6; block++) { + if ((cbp & mask) != 0) { + plm_video_decode_block(self, block); + } + mask >>= 1; + } +} + +static void plm_video_decode_slice(plm_video_t *self, int slice) { + self->slice_begin = true; + self->macroblock_address = (slice - 1) * self->mb_width - 1; + // Reset motion vectors and DC predictors + self->motion_backward.h = self->motion_forward.h = 0; + self->motion_backward.v = self->motion_forward.v = 0; + self->dc_predictor[0] = 128; + self->dc_predictor[1] = 128; + self->dc_predictor[2] = 128; + self->quantizer_scale = plm_buffer_read(self->buffer, 5); + // Skip extra + while (plm_buffer_read(self->buffer, 1)) { + plm_buffer_skip(self->buffer, 8); + } + do { + plm_video_decode_macroblock(self); + } while (self->macroblock_address < self->mb_size - 1 && + plm_buffer_no_start_code(self->buffer)); +} + +static void plm_video_decode_picture(plm_video_t *self) { + plm_buffer_skip(self->buffer, 10); // skip temporalReference + self->picture_type = plm_buffer_read(self->buffer, 3); + plm_buffer_skip(self->buffer, 16); // skip vbv_delay + + // D frames or unknown coding type + if (self->picture_type <= 0 || + self->picture_type > PLM_VIDEO_PICTURE_TYPE_B) { + return; + } + + // forward full_px, f_code + if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE || + self->picture_type == PLM_VIDEO_PICTURE_TYPE_B) { + self->motion_forward.full_px = plm_buffer_read(self->buffer, 1); + int f_code = plm_buffer_read(self->buffer, 3); + if (f_code == 0) { + // Ignore picture with zero f_code + return; + } + self->motion_forward.r_size = f_code - 1; + } + + // backward full_px, f_code + if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_B) { + self->motion_backward.full_px = plm_buffer_read(self->buffer, 1); + int f_code = plm_buffer_read(self->buffer, 3); + if (f_code == 0) { + // Ignore picture with zero f_code + return; + } + self->motion_backward.r_size = f_code - 1; + } + + plm_frame_t frame_temp = self->frame_forward; + + if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_INTRA || + self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE) { + self->frame_forward = self->frame_backward; + } + + // Skip extensions, user data + do { + self->start_code = plm_buffer_next_start_code(self->buffer); + } while (self->start_code == PLM_START_EXTENSION || + self->start_code == PLM_START_USER_DATA); + + while (self->start_code >= PLM_START_SLICE_FIRST && + self->start_code <= PLM_START_SLICE_LAST) { + plm_video_decode_slice(self, self->start_code & 0x000000FF); + if (self->macroblock_address == self->mb_size - 1) { + break; + } + self->start_code = plm_buffer_next_start_code(self->buffer); + } + + // If this is a reference picutre rotate the prediction pointers + if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_INTRA || + self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE) { + self->frame_backward = self->frame_current; + self->frame_current = frame_temp; + } +} + +static plm_frame_t *plm_video_decode_impl(plm_video_t *self) { + plm_frame_t *frame = NULL; + if (!self->has_sequence_header) { + self->start_code = + plm_buffer_find_start_code(self->buffer, PLM_START_SEQUENCE); + if (self->start_code == -1) { + return NULL; + } + plm_video_decode_sequence_header(self); + } + do { + if (self->start_code != PLM_START_PICTURE) { + self->start_code = + plm_buffer_find_start_code(self->buffer, PLM_START_PICTURE); + } + if (self->start_code == -1) { + return NULL; + } + plm_video_decode_picture(self); + if (self->assume_no_b_frames) { + frame = &self->frame_backward; + } else if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_B) { + frame = &self->frame_current; + } else if (self->has_reference_frame) { + frame = &self->frame_forward; + } else { + self->has_reference_frame = true; + } + } while (!frame); + frame->time = self->time; + self->frames_decoded++; + self->time = (double)self->frames_decoded / self->framerate; + return frame; +} + +plm_frame_t *plm_video_decode(plm_video_t *self) { + long double tsc; + plm_frame_t *res; + LOGF("plm_video_decode"); + tsc = nowl(); + res = plm_video_decode_impl(self); + plmpegdecode_latency_ = lroundl((nowl() - tsc) * 1e6l); + return res; +} + +plm_video_t *plm_video_create_with_buffer(plm_buffer_t *buffer, + int destroy_when_done) { + plm_video_t *self = (plm_video_t *)memalign(64, sizeof(plm_video_t)); + memset(self, 0, sizeof(plm_video_t)); + self->buffer = buffer; + self->destroy_buffer_when_done = destroy_when_done; + self->start_code = + plm_buffer_find_start_code(self->buffer, PLM_START_SEQUENCE); + if (self->start_code != -1) { + plm_video_decode_sequence_header(self); + } + return self; +} diff --git a/dsp/mpeg/plm.c b/dsp/mpeg/plm.c new file mode 100644 index 00000000..2745f63f --- /dev/null +++ b/dsp/mpeg/plm.c @@ -0,0 +1,337 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│ +│vi: set et ft=c ts=4 sw=4 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer │ +│ Dominic Szablewski - https://phoboslab.org │ +│ │ +│ The MIT License(MIT) │ +│ Copyright(c) 2019 Dominic Szablewski │ +│ │ +│ Permission is hereby granted, free of charge, to any person obtaining │ +│ a copy of this software and associated documentation files(the │ +│ "Software"), to deal in the Software without restriction, including │ +│ without limitation the rights to use, copy, modify, merge, publish, │ +│ distribute, sublicense, and / or sell copies of the Software, and to │ +│ permit persons to whom the Software is furnished to do so, subject to │ +│ the following conditions: │ +│ │ +│ The above copyright notice and this permission notice shall be │ +│ included in all copies or substantial portions of the Software. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │ +│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │ +│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND │ +│ NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE │ +│ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN │ +│ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN │ +│ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE │ +│ SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/mpeg/mpeg.h" +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" + +asm(".ident\t\"\\n\\n\ +PL_MPEG (MIT License)\\n\ +Copyright(c) 2019 Dominic Szablewski\\n\ +https://phoboslab.org\""); +asm(".include \"libc/disclaimer.inc\""); + +/* clang-format off */ +// ----------------------------------------------------------------------------- +// plm (high-level interface) implementation + +typedef struct plm_t { + plm_demux_t *demux; + double time; + int has_ended; + int loop; + + int video_packet_type; + plm_buffer_t *video_buffer; + plm_video_t *video_decoder; + + int audio_packet_type; + double audio_lead_time; + plm_buffer_t *audio_buffer; + plm_audio_t *audio_decoder; + + plm_video_decode_callback video_decode_callback; + void *video_decode_callback_user_data; + + plm_audio_decode_callback audio_decode_callback; + void *audio_decode_callback_user_data; +} plm_t; + +void plm_handle_end(plm_t *self); +void plm_read_video_packet(plm_buffer_t *buffer, void *user); +void plm_read_audio_packet(plm_buffer_t *buffer, void *user); +void plm_read_packets(plm_t *self, int requested_type); + +plm_t *plm_create_with_filename(const char *filename) { + plm_buffer_t *buffer = plm_buffer_create_with_filename(filename); + if (!buffer) { + return NULL; + } + return plm_create_with_buffer(buffer, true); +} + +plm_t *plm_create_with_file(FILE *fh, int close_when_done) { + plm_buffer_t *buffer = plm_buffer_create_with_file(fh, close_when_done); + return plm_create_with_buffer(buffer, true); +} + +plm_t *plm_create_with_memory(uint8_t *bytes, size_t length, int free_when_done) { + plm_buffer_t *buffer = plm_buffer_create_with_memory(bytes, length, free_when_done); + return plm_create_with_buffer(buffer, true); +} + +plm_t *plm_create_with_buffer(plm_buffer_t *buffer, int destroy_when_done) { + plm_t *self = (plm_t *)malloc(sizeof(plm_t)); + memset(self, 0, sizeof(plm_t)); + + self->demux = plm_demux_create(buffer, destroy_when_done); + + // In theory we should check plm_demux_get_num_video_streams() and + // plm_demux_get_num_audio_streams() here, but older files typically + // do not specify these correcly. So we just assume we have a video and + // audio stream and create the decoders. + + self->video_packet_type = PLM_DEMUX_PACKET_VIDEO_1; + self->video_buffer = plm_buffer_create_with_capacity(PLM_BUFFER_DEFAULT_SIZE); + plm_buffer_set_load_callback(self->video_buffer, plm_read_video_packet, self); + + self->audio_packet_type = PLM_DEMUX_PACKET_AUDIO_1; + self->audio_buffer = plm_buffer_create_with_capacity(PLM_BUFFER_DEFAULT_SIZE); + plm_buffer_set_load_callback(self->audio_buffer, plm_read_audio_packet, self); + + self->video_decoder = plm_video_create_with_buffer(self->video_buffer, true); + self->audio_decoder = plm_audio_create_with_buffer(self->audio_buffer, true); + + return self; +} + +void plm_destroy(plm_t *self) { + plm_video_destroy(self->video_decoder); + plm_audio_destroy(self->audio_decoder); + plm_demux_destroy(self->demux); + free(self); +} + +int plm_get_audio_enabled(plm_t *self) { + return (self->audio_packet_type != 0); +} + +void plm_set_audio_enabled(plm_t *self, int enabled, int stream_index) { + /* int num_streams = plm_demux_get_num_audio_streams(self->demux); */ + self->audio_packet_type = (enabled && stream_index >= 0 && stream_index < 4) + ? PLM_DEMUX_PACKET_AUDIO_1 + stream_index + : 0; +} + +int plm_get_video_enabled(plm_t *self) { + return (self->video_packet_type != 0); +} + +void plm_set_video_enabled(plm_t *self, int enabled) { + self->video_packet_type = (enabled) + ? PLM_DEMUX_PACKET_VIDEO_1 + : 0; +} + +int plm_get_width(plm_t *self) { + return plm_video_get_width(self->video_decoder); +} + +double plm_get_pixel_aspect_ratio(plm_t *self) { + return plm_video_get_pixel_aspect_ratio(self->video_decoder); +} + +int plm_get_height(plm_t *self) { + return plm_video_get_height(self->video_decoder); +} + +double plm_get_framerate(plm_t *self) { + return plm_video_get_framerate(self->video_decoder); +} + +int plm_get_num_audio_streams(plm_t *self) { + // Some files do not specify the number of audio streams in the system header. + // If the reported number of streams is 0, we check if we have a samplerate, + // indicating at least one audio stream. + int num_streams = plm_demux_get_num_audio_streams(self->demux); + return num_streams == 0 && plm_get_samplerate(self) ? 1 : num_streams; +} + +int plm_get_samplerate(plm_t *self) { + return plm_audio_get_samplerate(self->audio_decoder); +} + +double plm_get_audio_lead_time(plm_t *self) { + return self->audio_lead_time; +} + +void plm_set_audio_lead_time(plm_t *self, double lead_time) { + self->audio_lead_time = lead_time; +} + +double plm_get_time(plm_t *self) { + return self->time; +} + +void plm_rewind(plm_t *self) { + plm_video_rewind(self->video_decoder); + plm_audio_rewind(self->audio_decoder); + plm_demux_rewind(self->demux); + self->time = 0; +} + +int plm_get_loop(plm_t *self) { + return self->loop; +} + +void plm_set_loop(plm_t *self, int loop) { + self->loop = loop; +} + +int plm_has_ended(plm_t *self) { + return self->has_ended; +} + +void plm_set_video_decode_callback(plm_t *self, plm_video_decode_callback fp, void *user) { + self->video_decode_callback = fp; + self->video_decode_callback_user_data = user; +} + +void plm_set_audio_decode_callback(plm_t *self, plm_audio_decode_callback fp, void *user) { + self->audio_decode_callback = fp; + self->audio_decode_callback_user_data = user; +} + +int plm_decode(plm_t *self, double tick) { + DEBUGF("%s", "plm_decode"); + + int decode_video = (self->video_decode_callback && self->video_packet_type); + int decode_audio = (self->audio_decode_callback && self->audio_packet_type); + + if (!decode_video && !decode_audio) { + // Nothing to do here + return false; + } + + int did_decode = false; + int video_ended = false; + int audio_ended = false; + + double video_target_time = self->time + tick; + double audio_target_time = self->time + tick; + + if (self->audio_lead_time > 0 && decode_audio) { + video_target_time -= self->audio_lead_time; + } + else { + audio_target_time -= self->audio_lead_time; + } + + do { + did_decode = false; + + if (decode_video && plm_video_get_time(self->video_decoder) < video_target_time) { + plm_frame_t *frame = plm_video_decode(self->video_decoder); + if (frame) { + self->video_decode_callback(self, frame, self->video_decode_callback_user_data); + did_decode = true; + } + else { + video_ended = true; + } + } + + if (decode_audio && plm_audio_get_time(self->audio_decoder) < audio_target_time) { + plm_samples_t *samples = plm_audio_decode(self->audio_decoder); + if (samples) { + self->audio_decode_callback(self, samples, self->audio_decode_callback_user_data); + did_decode = true; + } + else { + audio_ended = true; + } + } + } while (did_decode); + + // We wanted to decode something but failed -> the source must have ended + if ((!decode_video || video_ended) && (!decode_audio || audio_ended)) { + plm_handle_end(self); + } + else { + self->time += tick; + } + + return did_decode ? true : false; +} + +plm_frame_t *plm_decode_video(plm_t *self) { + if (!self->video_packet_type) { + return NULL; + } + + plm_frame_t *frame = plm_video_decode(self->video_decoder); + if (frame) { + self->time = frame->time; + } + else { + plm_handle_end(self); + } + return frame; +} + +plm_samples_t *plm_decode_audio(plm_t *self) { + if (!self->audio_packet_type) { + return NULL; + } + + plm_samples_t *samples = plm_audio_decode(self->audio_decoder); + if (samples) { + self->time = samples->time; + } + else { + plm_handle_end(self); + } + return samples; +} + +void plm_handle_end(plm_t *self) { + if (self->loop) { + plm_rewind(self); + } + else { + self->has_ended = true; + } +} + +void plm_read_video_packet(plm_buffer_t *buffer, void *user) { + plm_t *self = (plm_t *)user; + plm_read_packets(self, self->video_packet_type); +} + +void plm_read_audio_packet(plm_buffer_t *buffer, void *user) { + plm_t *self = (plm_t *)user; + plm_read_packets(self, self->audio_packet_type); +} + +void plm_read_packets(plm_t *self, int requested_type) { + plm_packet_t *packet; + while ((packet = plm_demux_decode(self->demux))) { + if (packet->type == self->video_packet_type) { + plm_buffer_write(self->video_buffer, packet->data, packet->length); + } + else if (packet->type == self->audio_packet_type) { + plm_buffer_write(self->audio_buffer, packet->data, packet->length); + } + if (packet->type == requested_type) { + return; + } + } +} diff --git a/dsp/mpeg/slowrgb.c b/dsp/mpeg/slowrgb.c new file mode 100644 index 00000000..2bfbafd5 --- /dev/null +++ b/dsp/mpeg/slowrgb.c @@ -0,0 +1,88 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│ +│vi: set et ft=c ts=4 sw=4 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer │ +│ Dominic Szablewski - https://phoboslab.org │ +│ │ +│ The MIT License(MIT) │ +│ Copyright(c) 2019 Dominic Szablewski │ +│ │ +│ Permission is hereby granted, free of charge, to any person obtaining │ +│ a copy of this software and associated documentation files(the │ +│ "Software"), to deal in the Software without restriction, including │ +│ without limitation the rights to use, copy, modify, merge, publish, │ +│ distribute, sublicense, and / or sell copies of the Software, and to │ +│ permit persons to whom the Software is furnished to do so, subject to │ +│ the following conditions: │ +│ │ +│ The above copyright notice and this permission notice shall be │ +│ included in all copies or substantial portions of the Software. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │ +│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │ +│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND │ +│ NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE │ +│ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN │ +│ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN │ +│ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE │ +│ SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/mpeg/mpeg.h" +#include "libc/macros.h" + +asm(".ident\t\"\\n\\n\ +PL_MPEG (MIT License)\\n\ +Copyright(c) 2019 Dominic Szablewski\\n\ +https://phoboslab.org\""); +asm(".include \"libc/disclaimer.inc\""); + +/** + * @see YCbCr2RGB() in tool/viz/lib/ycbcr2rgb.c + */ +void plm_frame_to_rgb(plm_frame_t *frame, uint8_t *rgb) { + // Chroma values are the same for each block of 4 pixels, so we proccess + // 2 lines at a time, 2 neighboring pixels each. + int w = frame->y.width, w2 = w >> 1; + int y_index1 = 0, y_index2 = w, y_next_2_lines = w + (w - frame->width); + int c_index = 0, c_next_line = w2 - (frame->width >> 1); + int rgb_index1 = 0, rgb_index2 = frame->width * 3, + rgb_next_2_lines = frame->width * 3; + int cols = frame->width >> 1, rows = frame->height >> 1; + int ccb, ccr, r, g, b; + uint8_t *y = frame->y.data, *cb = frame->cb.data, *cr = frame->cr.data; + for (int row = 0; row < rows; row++) { + for (int col = 0; col < cols; col++) { + ccb = cb[c_index]; + ccr = cr[c_index]; + c_index++; + r = (ccr + ((ccr * 103) >> 8)) - 179; + g = ((ccb * 88) >> 8) - 44 + ((ccr * 183) >> 8) - 91; + b = (ccb + ((ccb * 198) >> 8)) - 227; + // Line 1 + int y1 = y[y_index1++]; + int y2 = y[y_index1++]; + rgb[rgb_index1 + 0] = MAX(0, MIN(255, y1 + r)); + rgb[rgb_index1 + 1] = MAX(0, MIN(255, y1 - g)); + rgb[rgb_index1 + 2] = MAX(0, MIN(255, y1 + b)); + rgb[rgb_index1 + 3] = MAX(0, MIN(255, y2 + r)); + rgb[rgb_index1 + 4] = MAX(0, MIN(255, y2 - g)); + rgb[rgb_index1 + 5] = MAX(0, MIN(255, y2 + b)); + rgb_index1 += 6; + // Line 2 + int y3 = y[y_index2++]; + int y4 = y[y_index2++]; + rgb[rgb_index2 + 0] = MAX(0, MIN(255, y3 + r)); + rgb[rgb_index2 + 1] = MAX(0, MIN(255, y3 - g)); + rgb[rgb_index2 + 2] = MAX(0, MIN(255, y3 + b)); + rgb[rgb_index2 + 3] = MAX(0, MIN(255, y4 + r)); + rgb[rgb_index2 + 4] = MAX(0, MIN(255, y4 - g)); + rgb[rgb_index2 + 5] = MAX(0, MIN(255, y4 + b)); + rgb_index2 += 6; + } + y_index1 += y_next_2_lines; + y_index2 += y_next_2_lines; + rgb_index1 += rgb_next_2_lines; + rgb_index2 += rgb_next_2_lines; + c_index += c_next_line; + } +} diff --git a/dsp/mpeg/video.h b/dsp/mpeg/video.h new file mode 100644 index 00000000..546b7d91 --- /dev/null +++ b/dsp/mpeg/video.h @@ -0,0 +1,62 @@ +#ifndef COSMOPOLITAN_DSP_MPEG_VIDEO_H_ +#define COSMOPOLITAN_DSP_MPEG_VIDEO_H_ +#include "dsp/mpeg/mpeg.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +typedef struct { + int full_px; + int is_set; + int r_size; + int h; + int v; +} plm_video_motion_t; + +typedef struct plm_video_t { + double framerate; + double time; + double pixel_aspect_ratio; + int frames_decoded; + int width; + int height; + int mb_width; + int mb_height; + int mb_size; + int luma_width; + int luma_height; + int chroma_width; + int chroma_height; + int start_code; + int picture_type; + plm_video_motion_t motion_forward; + plm_video_motion_t motion_backward; + int has_sequence_header; + int quantizer_scale; + int slice_begin; + int macroblock_address; + int mb_row; + int mb_col; + int macroblock_type; + int macroblock_intra; + int dc_predictor[3]; + plm_buffer_t *buffer; + int destroy_buffer_when_done; + plm_frame_t frame_current; + plm_frame_t frame_forward; + plm_frame_t frame_backward; + uint8_t *frames_data; + int block_data[64]; + uint8_t intra_quant_matrix[64]; + uint8_t non_intra_quant_matrix[64]; + int has_reference_frame; + int assume_no_b_frames; +} plm_video_t; + +void plm_video_process_macroblock_8(plm_video_t *, uint8_t *restrict, + uint8_t *restrict, int, int, bool); +void plm_video_process_macroblock_16(plm_video_t *, uint8_t *restrict, + uint8_t *restrict, int, int, bool); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_MPEG_VIDEO_H_ */ diff --git a/dsp/mpeg/ycbcrio.c b/dsp/mpeg/ycbcrio.c new file mode 100644 index 00000000..467e1589 --- /dev/null +++ b/dsp/mpeg/ycbcrio.c @@ -0,0 +1,139 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/mpeg/mpeg.h" +#include "dsp/mpeg/ycbcrio.h" +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/calls/struct/stat.h" +#include "libc/log/check.h" +#include "libc/macros.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/prot.h" + +static void CheckPlmFrame(const struct plm_frame_t *frame) { + CHECK_NE(0, frame->width); + CHECK_NE(0, frame->height); + CHECK_GE(frame->y.width, frame->width); + CHECK_GE(frame->y.height, frame->height); + CHECK_EQ(frame->cr.width, frame->cb.width); + CHECK_EQ(frame->cr.height, frame->cb.height); + CHECK_EQ(frame->y.width, frame->cr.width * 2); + CHECK_EQ(frame->y.height, frame->cr.height * 2); + CHECK_NOTNULL(frame->y.data); + CHECK_NOTNULL(frame->cr.data); + CHECK_NOTNULL(frame->cb.data); +} + +static size_t GetHeaderBytes(const struct plm_frame_t *frame) { + return MAX(sizeof(struct Ycbcrio), ROUNDUP(frame->y.width, 16)); +} + +static size_t GetPlaneBytes(const struct plm_plane_t *plane) { + /* + * planes must be 16-byte aligned, but due to their hugeness, and the + * recommendation of intel's 6,000 page manual, it makes sense to have + * planes on isolated 64kb frames for multiprocessing. + */ + return ROUNDUP(ROUNDUP(plane->height, 16) * ROUNDUP(plane->width, 16), + FRAMESIZE); +} + +static size_t CalcMapBytes(const struct plm_frame_t *frame) { + return ROUNDUP(GetHeaderBytes(frame) + GetPlaneBytes(&frame->y) + + GetPlaneBytes(&frame->cb) + GetPlaneBytes(&frame->cb), + FRAMESIZE); +} + +static void FixupPointers(struct Ycbcrio *map) { + map->frame.y.data = (unsigned char *)map + GetHeaderBytes(&map->frame); + map->frame.cr.data = map->frame.y.data + GetPlaneBytes(&map->frame.y); + map->frame.cb.data = map->frame.cr.data + GetPlaneBytes(&map->frame.cr); +} + +static struct Ycbcrio *YcbcrioOpenNew(const char *path, + const struct plm_frame_t *frame) { + int fd; + size_t size; + struct stat st; + struct Ycbcrio *map; + CheckPlmFrame(frame); + size = CalcMapBytes(frame); + CHECK_NE(-1, (fd = open(path, O_CREAT | O_RDWR, 0644))); + CHECK_NE(-1, fstat(fd, &st)); + if (st.st_size < size) { + CHECK_NE(-1, ftruncate(fd, size)); + } + CHECK_NE(MAP_FAILED, + (map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0))); + map->magic = YCBCRIO_MAGIC; + map->fd = fd; + map->size = size; + memcpy(&map->frame, frame, sizeof(map->frame)); + FixupPointers(map); + memcpy(&map->frame.y.data, frame->y.data, GetPlaneBytes(&frame->y)); + memcpy(&map->frame.cb.data, frame->cb.data, GetPlaneBytes(&frame->cb)); + memcpy(&map->frame.cr.data, frame->cr.data, GetPlaneBytes(&frame->cr)); + return map; +} + +static struct Ycbcrio *YcbcrioOpenExisting(const char *path) { + int fd; + struct stat st; + struct Ycbcrio *map; + CHECK_NE(-1, (fd = open(path, O_RDWR))); + CHECK_NE(-1, fstat(fd, &st)); + CHECK_NE(MAP_FAILED, (map = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0))); + CHECK_EQ(YCBCRIO_MAGIC, map->magic); + CHECK_GE(st.st_size, CalcMapBytes(&map->frame)); + FixupPointers(map); + map->fd = fd; + map->size = st.st_size; + return map; +} + +/** + * Opens shareable persistable MPEG video frame memory. + * + * @param path is a file name + * @param frame if NULL means open existing file, otherwise copies new + * @param points to pointer returned by YcbcrioOpen() which is cleared + * @return memory mapping needing YcbcrioClose() + */ +struct Ycbcrio *YcbcrioOpen(const char *path, const struct plm_frame_t *frame) { + if (frame) { + return YcbcrioOpenNew(path, frame); + } else { + return YcbcrioOpenExisting(path); + } +} + +/** + * Closes mapped video frame file. + * + * @param points to pointer returned by YcbcrioOpen() which is cleared + */ +void YcbcrioClose(struct Ycbcrio **map) { + CHECK_NE(-1, close_s(&(*map)->fd)); + CHECK_NE(-1, munmap_s(map, (*map)->size)); +} diff --git a/dsp/mpeg/ycbcrio.h b/dsp/mpeg/ycbcrio.h new file mode 100644 index 00000000..aff70985 --- /dev/null +++ b/dsp/mpeg/ycbcrio.h @@ -0,0 +1,27 @@ +#ifndef COSMOPOLITAN_DSP_MPEG_YCBCRIO_H_ +#define COSMOPOLITAN_DSP_MPEG_YCBCRIO_H_ +#include "dsp/mpeg/mpeg.h" +#include "libc/bits/bits.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define YCBCRIO_MAGIC bswap_32(0xBCCBCCBCu) + +/** + * Mappable persistable MPEG-2 video frame in Y-Cr-Cb colorspace. + */ +struct Ycbcrio { + uint32_t magic; + int32_t fd; + uint64_t size; + plm_frame_t frame; +}; + +struct Ycbcrio *YcbcrioOpen(const char *, const struct plm_frame_t *) + paramsnonnull((1)) vallocesque returnsnonnull; + +void YcbcrioClose(struct Ycbcrio **) paramsnonnull(); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_MPEG_YCBCRIO_H_ */ diff --git a/dsp/scale/cdecimate2xuint8x8.c b/dsp/scale/cdecimate2xuint8x8.c new file mode 100644 index 00000000..e487d69f --- /dev/null +++ b/dsp/scale/cdecimate2xuint8x8.c @@ -0,0 +1,100 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/scale/scale.h" +#include "libc/assert.h" +#include "libc/intrin/packuswb.h" +#include "libc/intrin/paddw.h" +#include "libc/intrin/palignr.h" +#include "libc/intrin/pmaddubsw.h" +#include "libc/intrin/psraw.h" +#include "libc/log/check.h" +#include "libc/log/log.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/str/str.h" + +#define TAPS 8 +#define RATIO 2 +#define OFFSET 3 +#define STRIDE 8 +#define SPREAD (STRIDE * RATIO + TAPS - OFFSET) +#define OVERLAP (SPREAD - STRIDE * RATIO) +#define LOOKBEHIND OFFSET +#define LOOKAHEAD (SPREAD - LOOKBEHIND) +#define SCALE 5 +#define ROUND (1 << (SCALE - 1)) + +/** + * Performs 2D Motion Picture Convolution Acceleration by Leveraging SSSE3. + * + * @note H/T John Costella, Jean-Baptiste Joseph Fourier + * @note RIP Huixiang Chen + */ +void *cDecimate2xUint8x8(unsigned long n, unsigned char A[n], + const signed char K[8]) { + short kRound[8] = {ROUND, ROUND, ROUND, ROUND, ROUND, ROUND, ROUND, ROUND}; + signed char kMadd1[16] = {K[0], K[1], K[0], K[1], K[0], K[1], K[0], K[1], + K[0], K[1], K[0], K[1], K[0], K[1], K[0], K[1]}; + signed char kMadd2[16] = {K[2], K[3], K[2], K[3], K[2], K[3], K[2], K[3], + K[2], K[3], K[2], K[3], K[2], K[3], K[2], K[3]}; + signed char kMadd3[16] = {K[4], K[5], K[4], K[5], K[4], K[5], K[4], K[5], + K[4], K[5], K[4], K[5], K[4], K[5], K[4], K[5]}; + signed char kMadd4[16] = {K[6], K[7], K[6], K[7], K[6], K[7], K[6], K[7], + K[6], K[7], K[6], K[7], K[6], K[7], K[6], K[7]}; + unsigned char in1[16], in2[16], in3[16], in4[32]; + unsigned char bv0[16], bv1[16], bv2[16], bv3[16]; + short wv0[8], wv1[8], wv2[8], wv3[8]; + unsigned long i, j, v, w, o; + if (n >= STRIDE) { + i = 0; + w = (n + RATIO / 2) / RATIO; + memset(in1, A[0], sizeof(in1)); + memset(in2, A[n - 1], 16); + memcpy(in2, A, MIN(16, n)); + for (; i < w; i += STRIDE) { + j = i * RATIO + 16; + if (j + 16 <= n) { + memcpy(in3, &A[j], 16); + } else { + memset(in3, A[n - 1], 16); + if (j < n) { + memcpy(in3, &A[j], n - j); + } + } + palignr(bv0, in2, in1, 13); + palignr(bv1, in2, in1, 15); + palignr(bv2, in3, in2, 1); + palignr(bv3, in3, in2, 3); + pmaddubsw(wv0, bv0, kMadd1); + pmaddubsw(wv1, bv1, kMadd2); + pmaddubsw(wv2, bv2, kMadd3); + pmaddubsw(wv3, bv3, kMadd4); + paddw(wv0, wv0, kRound); + paddw(wv0, wv0, wv1); + paddw(wv0, wv0, wv2); + paddw(wv0, wv0, wv3); + psraw(wv0, wv0, SCALE); + packuswb(bv2, wv0, wv0); + memcpy(&A[i], bv2, STRIDE); + memcpy(in1, in2, 16); + memcpy(in2, in3, 16); + } + } + return A; +} diff --git a/dsp/scale/gyarados.c b/dsp/scale/gyarados.c new file mode 100644 index 00000000..e46ea249 --- /dev/null +++ b/dsp/scale/gyarados.c @@ -0,0 +1,285 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/c161.h" +#include "dsp/core/core.h" +#include "dsp/core/ituround.h" +#include "dsp/core/q.h" +#include "dsp/core/twixt8.h" +#include "dsp/scale/scale.h" +#include "libc/limits.h" +#include "libc/log/check.h" +#include "libc/log/log.h" +#include "libc/macros.h" +#include "libc/math.h" +#include "libc/mem/mem.h" +#include "libc/nexgen32e/bsr.h" +#include "libc/runtime/gc.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" +#include "third_party/dtoa/dtoa.h" +#include "tool/viz/lib/knobs.h" + +/** + * @fileoverview Gyarados resizes graphics. + * @note H/T John Costella, Facebook, Photoshop, Carl Friedrich Gauss + * @note Eric Brasseur has an interesting blog post on tip of iceberg + * @see Magikarp + */ + +#define M 14 +#define SQR(X) ((X) * (X)) + +struct SamplingSolution { + int n, s; + void *weights; + void *indices; +}; + +static double ComputeWeight(double x) { + if (-1.5 < x && x < 1.5) { + if (-.5 < x && x < .5) { + return .75 - SQR(x); + } else if (x < 0) { + return .5 * SQR(x + 1.5); + } else { + return .5 * SQR(x - 1.5); + } + } else { + return 0; + } +} + +static struct SamplingSolution *NewSamplingSolution(long n, long s) { + struct SamplingSolution *ss; + ss = xcalloc(1, sizeof(struct SamplingSolution)); + ss->n = n; + ss->s = s; + ss->weights = xcalloc(n * s, sizeof(short)); + ss->indices = xcalloc(n * s, sizeof(short)); + return ss; +} + +static bool IsNormalized(int n, double A[n]) { + int i; + double x; + for (x = i = 0; i < n; ++i) x += A[i]; + return fabs(x - 1) < 1e-4; +} + +void FreeSamplingSolution(struct SamplingSolution *ss) { + long i; + if (ss) { + free(ss->indices); + free(ss->weights); + free(ss); + } +} + +struct SamplingSolution *ComputeSamplingSolution(long dn, long sn, double dar, + double off, double par) { + double *fweights; + double sum, hw, w, x, f; + short *weights, *indices; + struct SamplingSolution *res; + long j, i, k, n, min, max, s, N[6]; + if (!dar) dar = sn, dar /= dn; + if (!off) off = (dar - 1) / 2; + f = dar < 1 ? 1 / dar : dar; + s = 3 * f + 1; + fweights = gc(xcalloc(s, sizeof(double))); + res = NewSamplingSolution(dn, s); + weights = res->weights; + indices = res->indices; + for (i = 0; i < dn; ++i) { + x = off + i * dar; + hw = 1.5 * f; + min = ceil(x - hw); + max = floor(x + hw); + n = max - min + 1; + CHECK_LE(n, s); + for (k = 0, j = min; j <= max; ++j) { + fweights[k++] = ComputeWeight((j - x) / (f / par)); + } + for (sum = k = 0; k < n; ++k) sum += fweights[k]; + for (j = 0; j < n; ++j) fweights[j] *= 1 / sum; + DCHECK(IsNormalized(n, fweights)); + for (j = 0; j < n; ++j) { + indices[i * s + j] = MIN(sn - 1, MAX(0, min + j)); + } + for (j = 0; j < n; j += 6) { + GetIntegerCoefficients(N, fweights + j, M, 0, 255); + for (k = 0; k < MIN(6, n - j); ++k) { + weights[i * s + j + k] = N[k]; + } + } + } + return res; +} + +static void *ZeroMatrix(long yw, long xw, int p[yw][xw], long yn, long xn) { + long y; + for (y = 0; y < yn; ++y) { + memset(p[y], 0, xn); + } + return p; +} + +static int Sharpen(int ax, int bx, int cx) { + return (-1 * ax + 6 * bx + -1 * cx + 2) / 4; +} + +static void GyaradosImpl(long dyw, long dxw, int dst[dyw][dxw], long syw, + long sxw, const int src[syw][sxw], long dyn, long dxn, + long syn, long sxn, int tmp0[restrict dyn][sxn], + int tmp1[restrict dyn][sxn], + int tmp2[restrict dyn][dxn], long yfn, long xfn, + const short fyi[dyn][yfn], const short fyw[dyn][yfn], + const short fxi[dxn][xfn], const short fxw[dxn][xfn], + bool sharpen) { + long i, j; + int eax, dy, dx, sy, sx; + for (sx = 0; sx < sxn; ++sx) { + for (dy = 0; dy < dyn; ++dy) { + for (eax = i = 0; i < yfn; ++i) { + eax += fyw[dy][i] * src[fyi[dy][i]][sx]; + } + tmp0[dy][sx] = QRS(M, eax); + } + } + for (dy = 0; dy < dyn; ++dy) { + /* TODO: pmulhrsw() would probably make this much faster */ + for (sx = 0; sx < sxn; ++sx) { + tmp1[dy][sx] = sharpen ? Sharpen(tmp0[MIN(dyn - 1, MAX(0, dy - 1))][sx], + tmp0[dy][sx], + tmp0[MIN(dyn - 1, MAX(0, dy + 1))][sx]) + : tmp0[dy][sx]; + } + } + for (dx = 0; dx < dxn; ++dx) { + for (dy = 0; dy < dyn; ++dy) { + for (eax = i = 0; i < xfn; ++i) { + eax += fxw[dx][i] * tmp1[dy][fxi[dx][i]]; + } + tmp2[dy][dx] = QRS(M, eax); + } + } + for (dx = 0; dx < dxn; ++dx) { + for (dy = 0; dy < dyn; ++dy) { + dst[dy][dx] = sharpen ? Sharpen(tmp2[dy][MIN(dxn - 1, MAX(0, dx - 1))], + tmp2[dy][dx], + tmp2[dy][MIN(dxn - 1, MAX(0, dx + 1))]) + : tmp2[dy][dx]; + } + } +} + +/** + * Scales image. + * + * @note gyarados is magikarp in its infinite form + * @see Magikarp2xY(), Magikarp2xX() + */ +void *Gyarados(long dyw, long dxw, int dst[dyw][dxw], long syw, long sxw, + const int src[syw][sxw], long dyn, long dxn, long syn, long sxn, + struct SamplingSolution *cy, struct SamplingSolution *cx, + bool sharpen) { + if (dyn > 0 && dxn > 0) { + if (syn > 0 && sxn > 0) { + CHECK_LE(syn, syw); + CHECK_LE(sxn, sxw); + CHECK_LE(dyn, dyw); + CHECK_LE(dxn, dxw); + CHECK_LT(bsrl(syn) + bsrl(sxn), 32); + CHECK_LT(bsrl(dyn) + bsrl(dxn), 32); + CHECK_LE(dyw, 0x7fff); + CHECK_LE(dxw, 0x7fff); + CHECK_LE(syw, 0x7fff); + CHECK_LE(sxw, 0x7fff); + CHECK_LE(dyn, 0x7fff); + CHECK_LE(dxn, 0x7fff); + CHECK_LE(syn, 0x7fff); + CHECK_LE(sxn, 0x7fff); + GyaradosImpl(dyw, dxw, dst, syw, sxw, src, dyn, dxn, syn, sxn, + gc(xmemalign(64, sizeof(int) * dyn * sxn)), + gc(xmemalign(64, sizeof(int) * dyn * sxn)), + gc(xmemalign(64, sizeof(int) * dyn * dxn)), cy->s, cx->s, + cy->indices, cy->weights, cx->indices, cx->weights, sharpen); + } else { + ZeroMatrix(dyw, dxw, dst, dyn, dxn); + } + } + return dst; +} + +void *GyaradosUint8(long dyw, long dxw, unsigned char dst[dyw][dxw], long syw, + long sxw, const unsigned char src[syw][sxw], long dyn, + long dxn, long syn, long sxn, long lo, long hi, + struct SamplingSolution *cy, struct SamplingSolution *cx, + bool sharpen) { + static bool once; + static int Tin[256]; + static unsigned char Tout[32768]; + long i, y, x; + int(*tmp)[MAX(dyn, syn)][MAX(dxn, sxn)]; + if (!once) { + for (i = 0; i < ARRAYLEN(Tin); ++i) { + Tin[i] = F2Q(15, rgb2linpc(i / 255., 2.4)); + } + for (i = 0; i < ARRAYLEN(Tout); ++i) { + Tout[i] = MIN(255, MAX(0, round(rgb2stdpc(Q2F(15, i), 2.4) * 255.))); + } + once = true; + } + tmp = xmemalign(64, sizeof(int) * MAX(dyn, syn) * MAX(dxn, sxn)); + for (y = 0; y < syn; ++y) { + for (x = 0; x < sxn; ++x) { + (*tmp)[y][x] = Tin[src[y][x]]; + } + } + Gyarados(MAX(dyn, syn), MAX(dxn, sxn), *tmp, MAX(dyn, syn), MAX(dxn, sxn), + *tmp, dyn, dxn, syn, sxn, cy, cx, sharpen); + for (y = 0; y < dyn; ++y) { + for (x = 0; x < dxn; ++x) { + dst[y][x] = Tout[MIN(32767, MAX(0, (*tmp)[y][x]))]; + } + } + free(tmp); + return dst; +} + +void *EzGyarados(long dcw, long dyw, long dxw, unsigned char dst[dcw][dyw][dxw], + long scw, long syw, long sxw, + const unsigned char src[scw][syw][sxw], long c0, long cn, + long dyn, long dxn, long syn, long sxn, double ry, double rx, + double oy, double ox) { + long c; + struct SamplingSolution *cy, *cx; + cy = ComputeSamplingSolution(dyn, syn, ry, oy, 1); + cx = ComputeSamplingSolution(dxn, sxn, rx, ox, 1); + for (c = c0; c < cn; ++c) { + GyaradosUint8(dyw, dxw, dst[c], syw, sxw, src[c], dyn, dxn, syn, sxn, 0, + 255, cy, cx, true); + } + FreeSamplingSolution(cx); + FreeSamplingSolution(cy); + return dst; +} diff --git a/dsp/scale/magikarp.c b/dsp/scale/magikarp.c new file mode 100644 index 00000000..df9a7914 --- /dev/null +++ b/dsp/scale/magikarp.c @@ -0,0 +1,129 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/half.h" +#include "dsp/core/ks8.h" +#include "dsp/core/kss8.h" +#include "dsp/scale/scale.h" +#include "libc/macros.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/str/str.h" +#include "libc/x/x.h" + +/** + * @fileoverview Magikarp resizes graphics in half very fast. + * @note H/T John Costella, Facebook, and Photoshop + * @note sharpening is good for luma but not chroma + * @see Gyarados + */ + +#define CLAMP(X) MIN(255, MAX(0, X)) +#define MAGIKARP(...) \ + CLAMP(KS8(5, K[0], K[1], K[2], K[3], K[4], K[5], K[6], K[7], __VA_ARGS__)) + +signed char g_magikarp[8]; +const signed char kMagikarp[8][8] = { + {-1, -3, 3, 17, 17, 3, -3, -1}, /* 1331+161 derived w/ one off cas */ + {-1, -3, 6, 28, 6, -3, -1, 0}, /* due to the convolution theorem? */ + {0, 0, -11, 53, -11, 0, 0, 0}, /* plus, some random experimenting */ + {-2, -6, 2, 22, 22, 2, -6, -2}, /* one a line please clang-format? */ + {-3, -9, 1, 27, 27, 1, -9, -3}, +}; + +signed char g_magkern[8]; +const signed char kMagkern[8][8] = { + {1, 2, 3, 10, 10, 3, 2, 1}, + {0, 4, 4, 16, 4, 4, 0, 0}, + {0, 1, 2, 6, 14, 6, 2, 1}, + {0, 1, 2, 13, 13, 2, 1, 0}, +}; + +void *Magikarp2xX(long ys, long xs, unsigned char p[ys][xs], long yn, long xn) { + long y; + if (yn && xn > 1) { + for (y = 0; y < yn; ++y) { + /* gcc/clang both struggle with left-to-right matrix ops */ + cDecimate2xUint8x8(xn, p[y], g_magikarp); + } + } + return p; +} + +void *Magikarp2xY(long ys, long xs, unsigned char p[ys][xs], long yn, long xn) { + long y, x, h; + signed char K[8]; + memcpy(K, g_magikarp, sizeof(K)); + for (h = HALF(yn), y = 0; y < h; ++y) { + for (x = 0; x < xn; ++x) { + p[y][x] = /* gcc/clang are good at optimizing top-to-bottom matrix ops */ + MAGIKARP(p[MAX(00 + 0, y * 2 - 3)][x], p[MAX(00 + 0, y * 2 - 2)][x], + p[MAX(00 + 0, y * 2 - 1)][x], p[MIN(yn - 1, y * 2 + 0)][x], + p[MIN(yn - 1, y * 2 + 1)][x], p[MIN(yn - 1, y * 2 + 2)][x], + p[MIN(yn - 1, y * 2 + 3)][x], p[MIN(yn - 1, y * 2 + 4)][x]); + } + } + return p; +} + +void *Magkern2xX(long ys, long xs, unsigned char p[ys][xs], long yn, long xn) { + long y; + if (yn && xn > 1) { + for (y = 0; y < yn; ++y) { + cDecimate2xUint8x8(xn, p[y], g_magkern); + } + } + return p; +} + +void *Magkern2xY(long ys, long xs, unsigned char p[ys][xs], long yn, long xn) { + long y, x, h; + signed char K[8]; + memcpy(K, g_magkern, sizeof(K)); + for (h = HALF(yn), y = 0; y < h; ++y) { + for (x = 0; x < xn; ++x) { + p[y][x] = + MAGIKARP(p[MAX(00 + 0, y * 2 - 3)][x], p[MAX(00 + 0, y * 2 - 2)][x], + p[MAX(00 + 0, y * 2 - 1)][x], p[MIN(yn - 1, y * 2 + 0)][x], + p[MIN(yn - 1, y * 2 + 1)][x], p[MIN(yn - 1, y * 2 + 2)][x], + p[MIN(yn - 1, y * 2 + 3)][x], p[MIN(yn - 1, y * 2 + 4)][x]); + } + } + return p; +} + +void *MagikarpY(long dys, long dxs, unsigned char d[restrict dys][dxs], + long sys, long sxs, const unsigned char s[sys][sxs], long yn, + long xn, const signed char K[8]) { + long y, x; + for (y = 0; y < yn; ++y) { + for (x = 0; x < xn; ++x) { + d[y][x] = MAGIKARP(s[MAX(00 + 0, y - 3)][x], s[MAX(00 + 0, y - 2)][x], + s[MAX(00 + 0, y - 1)][x], s[MIN(yn - 1, y + 0)][x], + s[MIN(yn - 1, y + 1)][x], s[MIN(yn - 1, y + 2)][x], + s[MIN(yn - 1, y + 3)][x], s[MIN(yn - 1, y + 4)][x]); + } + } + return d; +} + +static textstartup void g_magikarp_init() { + memcpy(g_magkern, kMagkern[0], sizeof(g_magkern)); + memcpy(g_magikarp, kMagikarp[0], sizeof(g_magikarp)); +} +const void *const g_magikarp_ctor[] initarray = {g_magikarp_init}; diff --git a/dsp/scale/scale.c b/dsp/scale/scale.c new file mode 100644 index 00000000..a5d38fc0 --- /dev/null +++ b/dsp/scale/scale.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/half.h" +#include "dsp/scale/scale.h" + +void *Scale2xX(long ys, long xs, unsigned char p[ys][xs], long yn, long xn) { + long y, x, w; + for (w = HALF(xn), y = 0; y < yn; ++y) { + for (x = 0; x < w; ++x) { + p[y][x] = p[y][x * 2]; + } + } + return p; +} + +void *Scale2xY(long ys, long xs, unsigned char p[ys][xs], long yn, long xn) { + long y, x, h; + for (h = HALF(yn), y = 0; y < h; ++y) { + for (x = 0; x < xn; ++x) { + p[y][x] = p[y * 2][x]; + } + } + return p; +} diff --git a/dsp/scale/scale.h b/dsp/scale/scale.h new file mode 100644 index 00000000..fa4a78de --- /dev/null +++ b/dsp/scale/scale.h @@ -0,0 +1,49 @@ +#ifndef COSMOPOLITAN_DSP_SCALE_SCALE_H_ +#define COSMOPOLITAN_DSP_SCALE_SCALE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +extern long gyarados_latency_; + +extern signed char g_magikarp[8]; +extern signed char g_magkern[8]; +extern const signed char kMagikarp[8][8]; +extern const signed char kMagkern[8][8]; + +struct SamplingSolution; +void FreeSamplingSolution(struct SamplingSolution *); +struct SamplingSolution *ComputeSamplingSolution(long, long, double, double, + double); + +void *Scale2xX(long ys, long xs, unsigned char[ys][xs], long, long); +void *Scale2xY(long ys, long xs, unsigned char[ys][xs], long, long); +void *Magikarp2xX(long ys, long xs, unsigned char[ys][xs], long, long); +void *Magikarp2xY(long ys, long xs, unsigned char[ys][xs], long, long); +void *Magkern2xX(long ys, long xs, unsigned char[ys][xs], long, long); +void *Magkern2xY(long ys, long xs, unsigned char[ys][xs], long, long); +void *MagikarpY(long dys, long dxs, unsigned char d[restrict dys][dxs], + long sys, long sxs, const unsigned char s[sys][sxs], long yn, + long xn, const signed char K[8]); + +void *GyaradosUint8(long dyw, long dxw, unsigned char dst[dyw][dxw], long syw, + long sxw, const unsigned char src[syw][sxw], long dyn, + long dxn, long syn, long sxn, long lo, long hi, + struct SamplingSolution *cy, struct SamplingSolution *cx, + bool sharpen); +void *EzGyarados(long dcw, long dyw, long dxw, unsigned char dst[dcw][dyw][dxw], + long scw, long syw, long sxw, + const unsigned char src[scw][syw][sxw], long c0, long cn, + long dyn, long dxn, long syn, long sxn, double ry, double rx, + double oy, double ox); + +void Decimate2xUint8x8(unsigned long n, unsigned char[n * 2], + const signed char[static 8]); +void *cDecimate2xUint8x8(unsigned long n, unsigned char[n * 2], + const signed char[8]); + +void *transpose(long yn, long xn, const unsigned char[yn][xn]); +extern void (*const transpose88b)(unsigned char[8][8]); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_SCALE_SCALE_H_ */ diff --git a/dsp/scale/scale.mk b/dsp/scale/scale.mk new file mode 100644 index 00000000..6c9035eb --- /dev/null +++ b/dsp/scale/scale.mk @@ -0,0 +1,58 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += DSP_SCALE + +DSP_SCALE_ARTIFACTS += DSP_SCALE_A +DSP_SCALE = $(DSP_SCALE_A_DEPS) $(DSP_SCALE_A) +DSP_SCALE_A = o/$(MODE)/dsp/scale/scale.a +DSP_SCALE_A_FILES := $(wildcard dsp/scale/*) +DSP_SCALE_A_HDRS = $(filter %.h,$(DSP_SCALE_A_FILES)) +DSP_SCALE_A_SRCS_S = $(filter %.S,$(DSP_SCALE_A_FILES)) +DSP_SCALE_A_SRCS_C = $(filter %.c,$(DSP_SCALE_A_FILES)) + +DSP_SCALE_A_SRCS = \ + $(DSP_SCALE_A_SRCS_S) \ + $(DSP_SCALE_A_SRCS_C) + +DSP_SCALE_A_OBJS = \ + $(DSP_SCALE_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(DSP_SCALE_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(DSP_SCALE_A_SRCS_C:%.c=o/$(MODE)/%.o) + +DSP_SCALE_A_CHECKS = \ + $(DSP_SCALE_A).pkg \ + $(DSP_SCALE_A_HDRS:%=o/$(MODE)/%.ok) + +DSP_SCALE_A_DIRECTDEPS = \ + DSP_CORE \ + LIBC_INTRIN \ + LIBC_NEXGEN32E \ + LIBC_TINYMATH \ + LIBC_TIME \ + LIBC_RUNTIME \ + LIBC_LOG \ + LIBC_MEM \ + LIBC_X \ + LIBC_STUBS + +DSP_SCALE_A_DEPS := \ + $(call uniq,$(foreach x,$(DSP_SCALE_A_DIRECTDEPS),$($(x)))) + +$(DSP_SCALE_A): dsp/scale/ \ + $(DSP_SCALE_A).pkg \ + $(DSP_SCALE_A_OBJS) + +$(DSP_SCALE_A).pkg: \ + $(DSP_SCALE_A_OBJS) \ + $(foreach x,$(DSP_SCALE_A_DIRECTDEPS),$($(x)_A).pkg) + +DSP_SCALE_LIBS = $(foreach x,$(DSP_SCALE_ARTIFACTS),$($(x))) +DSP_SCALE_SRCS = $(foreach x,$(DSP_SCALE_ARTIFACTS),$($(x)_SRCS)) +DSP_SCALE_HDRS = $(foreach x,$(DSP_SCALE_ARTIFACTS),$($(x)_HDRS)) +DSP_SCALE_CHECKS = $(foreach x,$(DSP_SCALE_ARTIFACTS),$($(x)_CHECKS)) +DSP_SCALE_OBJS = $(foreach x,$(DSP_SCALE_ARTIFACTS),$($(x)_OBJS)) +$(DSP_SCALE_OBJS): $(BUILD_FILES) dsp/scale/scale.mk + +.PHONY: o/$(MODE)/dsp/scale +o/$(MODE)/dsp/scale: $(DSP_SCALE_CHECKS) diff --git a/dsp/tty/altbuf.c b/dsp/tty/altbuf.c new file mode 100644 index 00000000..f9950284 --- /dev/null +++ b/dsp/tty/altbuf.c @@ -0,0 +1,33 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" + +/** + * Asks teletypewriter to flip to alternate display page. + * + * The alternate buffer trick lets one restore the console exactly as it + * was, once the program is done running. + */ +int ttyenablealtbuf(int ttyfd) { return ttysend(ttyfd, "\e[?1049h"); } + +/** + * Asks teletypewriter to restore blinking box thing. + */ +int ttydisablealtbuf(int ttyfd) { return ttysend(ttyfd, "\e[?1049l"); } diff --git a/dsp/tty/config.c b/dsp/tty/config.c new file mode 100644 index 00000000..bc8a624e --- /dev/null +++ b/dsp/tty/config.c @@ -0,0 +1,46 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" +#include "libc/assert.h" +#include "libc/calls/termios.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/termios.h" + +/** + * Applies configuration to teletypewriter. + * + * @param opt_out_oldconf is only modified if successful + * @return 0 on success, or -1 w/ errno + * @see ttyconfig(), ttyrestore() + */ +int ttyconfig(int ttyfd, ttyconf_f fn, int64_t arg, + const struct termios *opt_out_oldconf) { + struct termios conf[2]; + if (tcgetattr(ttyfd, &conf[0]) != -1 && + fn(memcpy(&conf[1], &conf[0], sizeof(conf[0])), arg) != -1 && + tcsetattr(ttyfd, TCSAFLUSH, &conf[1]) != -1) { + if (opt_out_oldconf) { + memcpy(opt_out_oldconf, &conf[0], sizeof(conf[0])); + } + return 0; + } else { + return -1; + } +} diff --git a/dsp/tty/describe.c b/dsp/tty/describe.c new file mode 100644 index 00000000..07defd8f --- /dev/null +++ b/dsp/tty/describe.c @@ -0,0 +1,77 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" +#include "libc/fmt/fmt.h" +#include "libc/mem/mem.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/x/x.h" + +#define BUFFY 48 + +static char *ttydescriber(char *b, const struct TtyIdent *ti) { + switch (ti->id) { + case 0: + snprintf(b, BUFFY, "%s %d", "putty", ti->version); + break; + case 1: + if (ti->version > 1000) { + snprintf(b, BUFFY, "%s %d", "gnome terminal", ti->version); + } else { + snprintf(b, BUFFY, "%s %d", "mlterm", ti->version); + } + break; + case kTtyIdScreen: + snprintf(b, BUFFY, "%s %d", "gnu screen", ti->version); + break; + case 77: + snprintf(b, BUFFY, "%s %d", "redhat mintty", ti->version); + break; + case 41: + snprintf(b, BUFFY, "%s %d", "xterm", ti->version); + break; + case 82: + snprintf(b, BUFFY, "%s %d", "rxvt", ti->version); + break; + default: + snprintf(b, BUFFY, "%s %d %d", "unknown teletypewriter no.", ti->id, + ti->version); + break; + } + return b; +} + +/** + * Makes educated guess about name of teletypewriter. + */ +char *ttydescribe(char *out, size_t size, const struct TtyIdent *ti) { + char b1[BUFFY], b2[BUFFY]; + if (ti) { + ttydescriber(b1, ti); + if (ti->next) { + snprintf(out, size, "%s%s%s", ttydescriber(b2, ti->next), " inside ", b1); + } else { + snprintf(out, size, "%s", b1); + } + } else { + snprintf(out, size, "%s", "no tty"); + } + return out; +} diff --git a/dsp/tty/hidecursor.c b/dsp/tty/hidecursor.c new file mode 100644 index 00000000..6e798cfc --- /dev/null +++ b/dsp/tty/hidecursor.c @@ -0,0 +1,53 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" +#include "libc/bits/pushpop.h" +#include "libc/dce.h" +#include "libc/log/log.h" +#include "libc/nt/console.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/consolecursorinfo.h" + +static int ttysetcursor(int fd, bool visible) { + struct NtConsoleCursorInfo ntcursor; + char code[8] = "\e[?25l"; + if (isterminalinarticulate()) return 0; + if (visible) code[5] = 'h'; + if (SupportsWindows()) { + GetConsoleCursorInfo(GetStdHandle(kNtStdOutputHandle), &ntcursor); + ntcursor.bVisible = visible; + SetConsoleCursorInfo(GetStdHandle(kNtStdOutputHandle), &ntcursor); + } + return ttysend(fd, code); +} + +/** + * Asks teletypewriter to hide blinking box. + */ +int ttyhidecursor(int fd) { + return ttysetcursor(fd, false); +} + +/** + * Asks teletypewriter to restore blinking box. + */ +int ttyshowcursor(int fd) { + return ttysetcursor(fd, true); +} diff --git a/dsp/tty/ident.c b/dsp/tty/ident.c new file mode 100644 index 00000000..3560c270 --- /dev/null +++ b/dsp/tty/ident.c @@ -0,0 +1,95 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/calls/termios.h" +#include "libc/fmt/fmt.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/sock/sock.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/poll.h" +#include "libc/sysv/errfuns.h" + +static int ttyident_probe(struct TtyIdent *ti, int ttyinfd, int ttyoutfd, + const char *msg) { + ssize_t rc; + size_t got; + char buf[64]; + int id, version; + if ((rc = write(ttyoutfd, msg, strlen(msg))) != -1) { + TryAgain: + if ((rc = read(ttyinfd, buf, sizeof(buf))) != -1) { + buf[min((got = (size_t)rc), sizeof(buf) - 1)] = '\0'; + if (sscanf(buf, "\e[>%d;%d", &id, &version) >= 1) { + ti->id = id; + ti->version = version; + rc = 0; + } else { + rc = eio(); + } + } else if (errno == EINTR) { + goto TryAgain; + } else if (errno == EAGAIN) { + if (poll((struct pollfd[]){{ttyinfd, POLLIN}}, 1, 100) != 0) { + goto TryAgain; + } else { + rc = etimedout(); + } + } + } + return rc; +} + +/** + * Identifies teletypewriter. + * + * For example, we can tell if process is running in a GNU Screen + * session Gnome Terminal. + * + * @return object if TTY responds, or NULL w/ errno + * @see ttyidentclear() + */ +int ttyident(struct TtyIdent *ti, int ttyinfd, int ttyoutfd) { + int rc; + struct termios old; + struct TtyIdent outer; + rc = -1; + if (!IsWindows()) { + if (ttyconfig(ttyinfd, ttysetrawdeadline, 3, &old) != -1) { + if (ttyident_probe(ti, ttyinfd, ttyoutfd, "\e[>c") != -1) { + rc = 0; + memset(&outer, 0, sizeof(outer)); + if (ti->id == 83 /* GNU Screen */ && (ti->next || weaken(malloc)) && + ttyident_probe(&outer, ttyinfd, ttyoutfd, "\eP\e[>c\e\\") != -1 && + (ti->next = (ti->next ? ti->next + : weaken(malloc)(sizeof(struct TtyIdent))))) { + memcpy(ti->next, &outer, sizeof(outer)); + } else { + free_s(&ti->next); + } + } + ttyrestore(ttyinfd, &old); + } + } + return rc; +} diff --git a/dsp/tty/identclear.c b/dsp/tty/identclear.c new file mode 100644 index 00000000..9eded590 --- /dev/null +++ b/dsp/tty/identclear.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" +#include "libc/assert.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" + +static void ttyidentfree(struct TtyIdent *ti) { + if (ti) { + assert(ti != ti->next); + ttyidentfree(ti->next); + free_s(&ti); + } +} + +/** + * Destroys TtyIdent object. + * + * @see ttyident() + */ +void ttyidentclear(struct TtyIdent *ti) { + assert(ti != ti->next); + ttyidentfree(ti->next); + memset(ti, 0, sizeof(*ti)); +} diff --git a/dsp/tty/internal.h b/dsp/tty/internal.h new file mode 100644 index 00000000..02ea1d1d --- /dev/null +++ b/dsp/tty/internal.h @@ -0,0 +1,33 @@ +#ifndef COSMOPOLITAN_DSP_TTY_INTERNAL_H_ +#define COSMOPOLITAN_DSP_TTY_INTERNAL_H_ +#include "dsp/tty/ttyrgb.h" +#include "libc/bits/xmmintrin.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct TtyRgb rgb2tty24f_(__m128); +struct TtyRgb rgb2ttyf2i_(__m128); +struct TtyRgb rgb2ttyi2f_(int, int, int); +struct TtyRgb rgb2ansi_(int, int, int); +struct TtyRgb rgb2ansihash_(int, int, int); +struct TtyRgb rgb2xterm24_(int, int, int); +struct TtyRgb rgb2xterm256gray_(__m128); +struct TtyRgb tty2rgb_(struct TtyRgb); +struct TtyRgb tty2rgb24_(struct TtyRgb); +__m128 tty2rgbf_(struct TtyRgb); +__m128 tty2rgbf24_(struct TtyRgb); + +char *setbg16_(char *, struct TtyRgb); +char *setfg16_(char *, struct TtyRgb); +char *setbgfg16_(char *, struct TtyRgb, struct TtyRgb); +char *setbg256_(char *, struct TtyRgb); +char *setfg256_(char *, struct TtyRgb); +char *setbgfg256_(char *, struct TtyRgb, struct TtyRgb); +char *setbg24_(char *, struct TtyRgb); +char *setfg24_(char *, struct TtyRgb); +char *setbgfg24_(char *, struct TtyRgb, struct TtyRgb); +struct TtyRgb rgb2ansi8_(int, int, int); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_TTY_INTERNAL_H_ */ diff --git a/dsp/tty/itoa8.c b/dsp/tty/itoa8.c new file mode 100644 index 00000000..c7ecffb1 --- /dev/null +++ b/dsp/tty/itoa8.c @@ -0,0 +1,51 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/itoa8.h" +#include "libc/bits/bits.h" +#include "libc/str/str.h" + +struct Itoa8 kItoa8; + +static nooptimize textstartup void itoa8init(void) { + size_t i; + uint8_t z; + char p[4]; + /*102*/ + for (i = 0; i < 256; ++i) { + memset(p, 0, sizeof(p)); + if (i < 10) { + z = 1; + p[0] = '0' + i; + } else if (i < 100) { + z = 2; + p[0] = '0' + i / 10; + p[1] = '0' + i % 10; + } else { + z = 3; + p[0] = '0' + i / 100; + p[1] = '0' + i % 100 / 10; + p[2] = '0' + i % 100 % 10; + } + kItoa8.size[i] = z; + memcpy(&kItoa8.data[i], p, sizeof(p)); + } +} + +INITIALIZER(301, _init_itoa8, itoa8init()); diff --git a/dsp/tty/itoa8.h b/dsp/tty/itoa8.h new file mode 100644 index 00000000..3c384905 --- /dev/null +++ b/dsp/tty/itoa8.h @@ -0,0 +1,21 @@ +#ifndef COSMOPOLITAN_DSP_TTY_ITOA8_H_ +#define COSMOPOLITAN_DSP_TTY_ITOA8_H_ +#include "libc/str/str.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct Itoa8 { + uint8_t size[256]; + uint32_t data[256]; +}; + +extern struct Itoa8 kItoa8; + +forceinline char *itoa8(char *p, uint8_t c) { + memcpy(p, &kItoa8.data[c], 4); + return p + kItoa8.size[c]; +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_TTY_ITOA8_H_ */ diff --git a/dsp/tty/kcgapalette.c b/dsp/tty/kcgapalette.c new file mode 100644 index 00000000..89fbd05b --- /dev/null +++ b/dsp/tty/kcgapalette.c @@ -0,0 +1,29 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "dsp/tty/quant.h" + +const ttypalette_t kCgaPalette = { + [0][0] = {0, 0, 0, 0}, /* normal black: \e[30m (or \e[38;5;0m) */ + [1][0] = {85, 85, 85, 8}, /* bright black: \e[90m (or \e[38;5;8m) */ + [0][1] = {170, 0, 0, 1}, /* normal red: \e[31m */ + [1][1] = {255, 85, 85, 9}, /* bright red: \e[91m (or \e[1;31m) */ + [0][2] = {0, 170, 0, 2}, /* normal green: \e[32m */ + [1][2] = {85, 255, 85, 10}, /* bright green: \e[92m */ + [0][3] = {170, 85, 0, 3}, /* normal yellow: \e[33m */ + [1][3] = {255, 255, 85, 11}, /* bright yellow: \e[93m */ + [0][4] = {0, 0, 170, 4}, /* normal blue: \e[34m */ + [1][4] = {85, 85, 255, 12}, /* bright blue: \e[94m */ + [0][5] = {170, 0, 170, 5}, /* normal magenta: \e[35m */ + [1][5] = {255, 85, 255, 13}, /* bright magenta: \e[95m */ + [0][6] = {0, 170, 170, 6}, /* normal cyan: \e[36m */ + [1][6] = {85, 255, 255, 14}, /* bright cyan: \e[96m */ + [0][7] = {170, 170, 170, 7}, /* normal white: \e[37m */ + [1][7] = {255, 255, 255, 15}, /* bright white: \e[97m */ +}; diff --git a/dsp/tty/ktangopalette.c b/dsp/tty/ktangopalette.c new file mode 100644 index 00000000..e40e8c04 --- /dev/null +++ b/dsp/tty/ktangopalette.c @@ -0,0 +1,29 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "dsp/tty/quant.h" + +const ttypalette_t kTangoPalette = { + [0][0] = {0x2E, 0x34, 0x36, 0}, /* aluminium1 */ + [1][0] = {0x55, 0x57, 0x53, 8}, + [0][1] = {0xCC, 0x00, 0x00, 1}, /* scarietred */ + [1][1] = {0xEF, 0x29, 0x29, 9}, + [0][2] = {0x4E, 0x9A, 0x06, 2}, /* chameleon */ + [1][2] = {0x8A, 0xE2, 0x34, 10}, + [0][3] = {0xC4, 0xA0, 0x00, 3}, /* butter */ + [1][3] = {0xFC, 0xE9, 0x4F, 11}, + [0][4] = {0x34, 0x65, 0xA4, 4}, /* skyblue */ + [1][4] = {0x72, 0x9F, 0xCF, 12}, + [0][5] = {0x75, 0x50, 0x7B, 5}, /* plum */ + [1][5] = {0xAD, 0x7F, 0xA8, 13}, + [0][6] = {0x06, 0x98, 0x9A, 6}, /* cyan */ + [1][6] = {0x34, 0xE2, 0xE2, 14}, + [0][7] = {0xD3, 0xD7, 0xCF, 7}, /* aluminium2 */ + [1][7] = {0xEE, 0xEE, 0xEC, 15}, +}; diff --git a/dsp/tty/kxtermcubesteps.c b/dsp/tty/kxtermcubesteps.c new file mode 100644 index 00000000..8dc4518e --- /dev/null +++ b/dsp/tty/kxtermcubesteps.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/quant.h" + +const uint8_t kXtermCubeSteps[] = {0, 0137, 0207, 0257, 0327, 0377}; diff --git a/dsp/tty/kxtermpalette.c b/dsp/tty/kxtermpalette.c new file mode 100644 index 00000000..bd1acecb --- /dev/null +++ b/dsp/tty/kxtermpalette.c @@ -0,0 +1,29 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "dsp/tty/quant.h" + +const ttypalette_t kXtermPalette = { + [0][0] = {0, 0, 0, 0}, /* normal black: \e[30m (or \e[38;5;0m) */ + [1][0] = {127, 127, 127, 8}, /* bright black: \e[90m (or \e[38;5;8m) */ + [0][1] = {205, 0, 0, 1}, /* normal red: \e[31m */ + [1][1] = {255, 0, 0, 9}, /* bright red: \e[91m (or \e[1;31m) */ + [0][2] = {0, 205, 0, 2}, /* normal green: \e[32m */ + [1][2] = {0, 255, 0, 10}, /* bright green: \e[92m */ + [0][3] = {205, 205, 0, 3}, /* normal yellow: \e[33m */ + [1][3] = {255, 255, 0, 11}, /* bright yellow: \e[93m */ + [0][4] = {0, 0, 238, 4}, /* normal blue: \e[34m */ + [1][4] = {92, 92, 255, 12}, /* bright blue: \e[94m */ + [0][5] = {205, 0, 205, 5}, /* normal magenta: \e[35m */ + [1][5] = {255, 0, 255, 13}, /* bright magenta: \e[95m */ + [0][6] = {0, 205, 205, 6}, /* normal cyan: \e[36m */ + [1][6] = {0, 255, 255, 14}, /* bright cyan: \e[96m */ + [0][7] = {229, 229, 229, 7}, /* normal white: \e[37m */ + [1][7] = {255, 255, 255, 15}, /* bright white: \e[97m */ +}; diff --git a/dsp/tty/mpsadbw.S b/dsp/tty/mpsadbw.S new file mode 100644 index 00000000..99a0b926 --- /dev/null +++ b/dsp/tty/mpsadbw.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +/ TODO(jart): write me + + movdqa a,%xmm0 + mpsadbw $0,inv,%xmm0 + + .rodata.cst32 +a: .byte 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 +inv: .byte 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 diff --git a/dsp/tty/quant.h b/dsp/tty/quant.h new file mode 100644 index 00000000..93e06ca2 --- /dev/null +++ b/dsp/tty/quant.h @@ -0,0 +1,84 @@ +#ifndef DSP_TTY_QUANT_H_ +#define DSP_TTY_QUANT_H_ +#include "dsp/tty/ttyrgb.h" +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/bits/xmmintrin.h" +#include "libc/limits.h" +#include "libc/str/str.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define TL 0 +#define TR 1 +#define BL 2 +#define BR 3 + +typedef __m128 (*tty2rgbf_f)(struct TtyRgb); +typedef char *(*setbg_f)(char *, struct TtyRgb); +typedef char *(*setbgfg_f)(char *, struct TtyRgb, struct TtyRgb); +typedef char *(*setfg_f)(char *, struct TtyRgb); +typedef struct TtyRgb (*rgb2tty_f)(int, int, int); +typedef struct TtyRgb (*rgb2ttyf_f)(__m128); +typedef struct TtyRgb (*tty2rgb_f)(struct TtyRgb); +typedef struct TtyRgb ttypalette_t[2][8]; + +struct TtyQuant { + enum TtyQuantizationAlgorithm { + kTtyQuantAnsi, + kTtyQuantTrue, + kTtyQuantXterm256, + } alg; + enum TtyBlocksSelection { + kTtyBlocksUnicode, + kTtyBlocksCp437, + } blocks; + enum TtyQuantizationChannels { + kTtyQuantGrayscale = 1, + kTtyQuantRgb = 3, + } chans; + unsigned min; + unsigned max; + setbg_f setbg; + setfg_f setfg; + setbgfg_f setbgfg; + rgb2tty_f rgb2tty; + rgb2ttyf_f rgb2ttyf; + tty2rgb_f tty2rgb; + tty2rgbf_f tty2rgbf; + const ttypalette_t *palette; +}; + +extern const ttypalette_t kCgaPalette; +extern const ttypalette_t kXtermPalette; +extern const ttypalette_t kTangoPalette; + +extern const uint8_t kXtermCubeSteps[6]; +extern double g_xterm256_gamma; +extern struct TtyRgb g_ansi2rgb_[256]; +extern struct TtyQuant g_ttyquant_; +extern const uint8_t kXtermXlat[2][256]; + +void ttyquantinit(enum TtyQuantizationAlgorithm, enum TtyQuantizationChannels, + enum TtyBlocksSelection); + +extern char *ttyraster(char *, const struct TtyRgb *, size_t, size_t, + struct TtyRgb, struct TtyRgb); + +#define ttyquant() (&g_ttyquant_) +#define TTYQUANT() VEIL("r", &g_ttyquant_) +#define rgb2tty(...) (ttyquant()->rgb2tty(__VA_ARGS__)) +#define tty2rgb(...) (ttyquant()->tty2rgb(__VA_ARGS__)) +#define rgb2ttyf(...) (ttyquant()->rgb2ttyf(__VA_ARGS__)) +#define tty2rgbf(...) (ttyquant()->tty2rgbf(__VA_ARGS__)) +#define setbg(...) (ttyquant()->setbg(__VA_ARGS__)) +#define setfg(...) (ttyquant()->setfg(__VA_ARGS__)) +#define setbgfg(...) (ttyquant()->setbgfg(__VA_ARGS__)) + +forceinline bool ttyeq(struct TtyRgb x, struct TtyRgb y) { + return x.r == y.r && x.g == y.g && x.b == y.b; +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* DSP_TTY_QUANT_H_ */ diff --git a/dsp/tty/quantinit.c b/dsp/tty/quantinit.c new file mode 100644 index 00000000..07caa3e1 --- /dev/null +++ b/dsp/tty/quantinit.c @@ -0,0 +1,78 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/internal.h" +#include "dsp/tty/quant.h" +#include "libc/dce.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" + +struct TtyQuant g_ttyquant_; + +/** + * Chooses xterm quantization mode. + */ +optimizesize textstartup void ttyquantinit(enum TtyQuantizationAlgorithm alg, + enum TtyQuantizationChannels chans, + enum TtyBlocksSelection blocks) { + switch (alg) { + case kTtyQuantAnsi: + TTYQUANT()->rgb2tty = rgb2ansi_; + TTYQUANT()->rgb2ttyf = rgb2ttyf2i_; + TTYQUANT()->tty2rgb = tty2rgb_; + TTYQUANT()->tty2rgbf = tty2rgbf_; + TTYQUANT()->setbg = setbg16_; + TTYQUANT()->setfg = setfg16_; + TTYQUANT()->setbgfg = setbgfg16_; + TTYQUANT()->min = 0; + TTYQUANT()->max = 16; + break; + case kTtyQuantTrue: + TTYQUANT()->rgb2tty = rgb2xterm24_; + TTYQUANT()->rgb2ttyf = rgb2tty24f_; + TTYQUANT()->tty2rgb = tty2rgb24_; + TTYQUANT()->tty2rgbf = tty2rgbf24_; + TTYQUANT()->setbg = setbg24_; + TTYQUANT()->setfg = setfg24_; + TTYQUANT()->setbgfg = setbgfg24_; + TTYQUANT()->min = 16; + TTYQUANT()->max = 256; + break; + case kTtyQuantXterm256: + TTYQUANT()->rgb2tty = rgb2ansi_; + TTYQUANT()->rgb2ttyf = rgb2ttyf2i_; + TTYQUANT()->tty2rgb = tty2rgb_; + TTYQUANT()->tty2rgbf = tty2rgbf_; + TTYQUANT()->setbg = setbg256_; + TTYQUANT()->setfg = setfg256_; + TTYQUANT()->setbgfg = setbgfg256_; + TTYQUANT()->min = 16; + TTYQUANT()->max = 256; + break; + default: + abort(); + } + TTYQUANT()->chans = chans; + TTYQUANT()->alg = alg; + TTYQUANT()->blocks = blocks; +} + +INITIALIZER(400, _init_ttyquant, + ttyquantinit(kTtyQuantXterm256, kTtyQuantRgb, kTtyBlocksUnicode)); diff --git a/dsp/tty/restore.c b/dsp/tty/restore.c new file mode 100644 index 00000000..18e4edfc --- /dev/null +++ b/dsp/tty/restore.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" +#include "libc/calls/termios.h" +#include "libc/sysv/consts/termios.h" + +/** + * Puts teletypewriter back into previous configuration. + */ +int ttyrestore(int ttyoutfd, const struct termios *conf) { + return tcsetattr(ttyoutfd, TCSADRAIN, conf); +} diff --git a/dsp/tty/rgb2ansi.c b/dsp/tty/rgb2ansi.c new file mode 100644 index 00000000..f418d0ec --- /dev/null +++ b/dsp/tty/rgb2ansi.c @@ -0,0 +1,129 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "dsp/tty/quant.h" +#include "libc/assert.h" +#include "libc/limits.h" +#include "libc/log/log.h" +#include "libc/macros.h" +#include "libc/math.h" +#include "libc/str/str.h" + +#define CUTOFF_VALUE 200 + +#define DIST(X, Y) ((X) - (Y)) +#define SQR(X) ((X) * (X)) +#define SUM(X, Y, Z) ((X) + (Y) + (Z)) + +static const uint8_t kXtermCube[] = {0, 0137, 0207, 0257, 0327, 0377}; +struct TtyRgb g_ansi2rgb_[256]; +static uint8_t g_quant[256]; +static uint8_t g_rindex[256]; +static uint8_t g_gindex[256]; +static uint8_t g_bindex[256]; +double g_xterm256_gamma; + +struct TtyRgb tty2rgb_(struct TtyRgb rgbxt) { + return g_ansi2rgb_[rgbxt.xt]; +} + +__m128 tty2rgbf_(struct TtyRgb rgbxt) { + rgbxt = g_ansi2rgb_[rgbxt.xt]; + return (__m128){(int)rgbxt.r, (int)rgbxt.g, (int)rgbxt.b} / 255; +} + +static int rgb2xterm256_(int r, int g, int b) { + int cerr, gerr, ir, ig, ib, gray, grai, cr, cg, cb, gv; + gray = round(r * .299 + g * .587 + b * .114); + grai = gray > 238 ? 23 : (gray - 3) / 10; + ir = r < 48 ? 0 : r < 115 ? 1 : (r - 35) / 40; + ig = g < 48 ? 0 : g < 115 ? 1 : (g - 35) / 40; + ib = b < 48 ? 0 : b < 115 ? 1 : (b - 35) / 40; + cr = kXtermCube[ir]; + cg = kXtermCube[ig]; + cb = kXtermCube[ib]; + gv = 8 + 10 * grai; + cerr = SQR(DIST(cr, r)) + SQR(DIST(cg, g)) + SQR(DIST(cb, b)); + gerr = SQR(DIST(gv, r)) + SQR(DIST(gv, g)) + SQR(DIST(gv, b)); + if (cerr <= gerr) { + return 16 + 36 * ir + 6 * ig + ib; + } else { + return 232 + grai; + } +} + +/** + * Quantizes RGB to ANSI w/ euclidean distance in 3D color space. + */ +struct TtyRgb rgb2ansi_(int r, int g, int b) { + uint32_t d, least; + size_t c, best, min, max; + r = MAX(MIN(r, 255), 0); + g = MAX(MIN(g, 255), 0); + b = MAX(MIN(b, 255), 0); + min = ttyquant()->min; + max = ttyquant()->max; + if (min == 16 && max == 256) { + return (struct TtyRgb){r, g, b, rgb2xterm256_(r, g, b)}; + } else { + least = UINT32_MAX; + best = 0; + for (c = min; c < max; c++) { + d = SUM(SQR(DIST(g_ansi2rgb_[c].r, r)), SQR(DIST(g_ansi2rgb_[c].g, g)), + SQR(DIST(g_ansi2rgb_[c].b, b))); + if (d < least) { + least = d; + best = c; + } + } + return (struct TtyRgb){r, g, b, best}; + } +} + +static int uncube(int x) { + return x < 48 ? 0 : x < 115 ? 1 : (x - 35) / 40; +} + +static optimizesize textstartup void xterm2rgbsetup_(void) { + uint8_t c, y; + uint32_t i, j; + memcpy(g_ansi2rgb_, &kCgaPalette, sizeof(kCgaPalette)); + for (i = 0; i < 256; ++i) { + j = uncube(i); + g_quant[i] = kXtermCube[j]; + g_rindex[i] = j * 36; + g_gindex[i] = j * 6; + g_bindex[i] = j + 16; + } + for (i = 16; i < 232; ++i) { + g_ansi2rgb_[i].r = kXtermCube[((i - 020) / 044) % 06]; + g_ansi2rgb_[i].g = kXtermCube[((i - 020) / 06) % 06]; + g_ansi2rgb_[i].b = kXtermCube[(i - 020) % 06]; + g_ansi2rgb_[i].xt = i; + } + for (i = 232, c = 8; i < 256; i++, c += 10) { + g_ansi2rgb_[i].r = c; + g_ansi2rgb_[i].g = c; + g_ansi2rgb_[i].b = c; + g_ansi2rgb_[i].xt = i; + } +} + +INITIALIZER(301, _init_ansi2rgb, xterm2rgbsetup_()); diff --git a/dsp/tty/rgb2ttyf2i.c b/dsp/tty/rgb2ttyf2i.c new file mode 100644 index 00000000..de6cbf20 --- /dev/null +++ b/dsp/tty/rgb2ttyf2i.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/quant.h" +#include "libc/bits/xmmintrin.h" + +struct TtyRgb rgb2ttyf2i_(__m128 rgb) { + __v4si i4; + rgb *= 255; + /* i4 = __builtin_ia32_cvtps2dq(rgb); */ + asm("cvttps2dq\t%0,%1" : "+%x"(rgb), "=x"(i4)); + return rgb2tty(i4[0], i4[1], i4[2]); +} diff --git a/dsp/tty/rgb2ttyi2f.c b/dsp/tty/rgb2ttyi2f.c new file mode 100644 index 00000000..377c9548 --- /dev/null +++ b/dsp/tty/rgb2ttyi2f.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/quant.h" +#include "libc/log/check.h" +#include "libc/macros.h" + +struct TtyRgb rgb2ttyi2f_(int r, int g, int b) { + return rgb2ttyf((__m128){r, g, b} / 255); +} diff --git a/dsp/tty/rgb2xterm24.c b/dsp/tty/rgb2xterm24.c new file mode 100644 index 00000000..5f088890 --- /dev/null +++ b/dsp/tty/rgb2xterm24.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/quant.h" +#include "libc/macros.h" + +struct TtyRgb rgb2xterm24_(int r, int g, int b) { + return (struct TtyRgb){MAX(MIN(r, 255), 0), MAX(MIN(g, 255), 0), + MAX(MIN(b, 255), 0), 0}; +} diff --git a/dsp/tty/rgb2xterm24f.c b/dsp/tty/rgb2xterm24f.c new file mode 100644 index 00000000..8617bc0b --- /dev/null +++ b/dsp/tty/rgb2xterm24f.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/quant.h" +#include "libc/math.h" + +/* +struct TtyRgb rgb2tty24f_(__m128 rgb) { + const __v4si kMax = {255, 255, 255, 255}; + const __v4si kMin = {0, 0, 0, 0}; + struct TtyRgb res; + __v4si rgb255; + rgb255 = _mm_min_ps(_mm_max_ps(_mm_cvtps_epi32(rgb * 255), kMin), kMax); + res = (struct TtyRgb){rgb255[0], rgb255[1], rgb255[2], rgb255[3]}; + return res; +} +*/ + +struct TtyRgb rgb2tty24f_(__m128 rgb) { + const __m128 kMax = {1, 1, 1, 1}; + const __m128 kMin = {0, 0, 0, 0}; + struct TtyRgb res; + rgb = _mm_min_ps(_mm_max_ps(rgb, kMin), kMax) * 255; + res = (struct TtyRgb){rgb[0], rgb[1], rgb[2], rgb[3]}; + return res; +} diff --git a/dsp/tty/rgb2xterm256.c b/dsp/tty/rgb2xterm256.c new file mode 100644 index 00000000..3f37a1f6 --- /dev/null +++ b/dsp/tty/rgb2xterm256.c @@ -0,0 +1,71 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/rgb2xterm256.h" + +/* 1bc */ +forceinline int sqr(int x) { return x * x; } +/* forceinline int dst6(int x) { return x * x; } */ +int rgb2xterm256v2(int r, int g, int b) { + static const int i2cv[] = {0, 0137, 0207, 0257, 0327, 0377, 0377}; +#define v2ci(v) (v < 060 ? 0 : v < 0163 ? 01 : (v - 043) / 050) +#define dst6(A, B, C, a, b, c) (sqr(A - a) + sqr(B - b) + sqr(C - c)) + int ir = v2ci(r); + int ig = v2ci(g); + int ib = v2ci(b); + int avg = (r + g + b) / 3; + int cr = i2cv[ir]; + int cg = i2cv[ig]; + int cb = i2cv[ib]; + int gidx = avg > 238 ? 23 : (avg - 3) / 10; + int gv = 8 + 10 * gidx; + int cerr = dst6(cr, cg, cb, r, g, b); + int gerr = dst6(gv, gv, gv, r, g, b); + return cerr <= gerr ? 16 + (36 * ir + 6 * ig + ib) : 232 + gidx; +#undef dst6 +#undef cidx +#undef v2ci +} + +/* 1e3 */ +// Convert RGB24 to xterm-256 8-bit value +// For simplicity, assume RGB space is perceptually uniform. +// There are 5 places where one of two outputs needs to be chosen when +// input is the exact middle: +// - The r/g/b channels and the gray value: choose higher value output +// - If gray and color have same distance from input - choose color +int rgb2xterm256(uint8_t r, uint8_t g, uint8_t b) { + // Calculate the nearest 0-based color index at 16 .. 231 +#define v2ci(v) (v < 48 ? 0 : v < 115 ? 1 : (v - 35) / 40) + int ir = v2ci(r), ig = v2ci(g), ib = v2ci(b); // 0..5 each +#define color_index() (36 * ir + 6 * ig + ib) /* 0..215, lazy eval */ + // Calculate the nearest 0-based gray index at 232 .. 255 + int average = (r + g + b) / 3; + int gray_index = average > 238 ? 23 : (average - 3) / 10; // 0..23 + // Calculate the represented colors back from the index + static const int i2cv[6] = {0, 0x5f, 0x87, 0xaf, 0xd7, 0xff}; + int cr = i2cv[ir], cg = i2cv[ig], cb = i2cv[ib]; // r/g/b, 0..255 each + int gv = 8 + 10 * gray_index; // same value for r/g/b, 0..255 +// Return the one which is nearer to the original input rgb value +#define dist_square(A, B, C, a, b, c) \ + ((A - a) * (A - a) + (B - b) * (B - b) + (C - c) * (C - c)) + int color_err = dist_square(cr, cg, cb, r, g, b); + int gray_err = dist_square(gv, gv, gv, r, g, b); + return color_err <= gray_err ? 16 + color_index() : 232 + gray_index; +} diff --git a/dsp/tty/rgb2xterm256.h b/dsp/tty/rgb2xterm256.h new file mode 100644 index 00000000..071de016 --- /dev/null +++ b/dsp/tty/rgb2xterm256.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_DSP_TTY_RGB2XTERM256_H_ +#define COSMOPOLITAN_DSP_TTY_RGB2XTERM256_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +int rgb2xterm256(uint8_t, uint8_t, uint8_t); +int rgb2xterm256v2(int, int, int); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_TTY_RGB2XTERM256_H_ */ diff --git a/dsp/tty/savecursor.c b/dsp/tty/savecursor.c new file mode 100644 index 00000000..41d15654 --- /dev/null +++ b/dsp/tty/savecursor.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" + +/** + * Asks teletypewriter to push current position. + */ +int ttysavecursor(int ttyfd) { return ttysend(ttyfd, "\e[s"); } + +/** + * Asks teletypewriter to pop previous position. + */ +int ttyrestorecursor(int ttyfd) { return ttysend(ttyfd, "\e[u"); } diff --git a/dsp/tty/send.c b/dsp/tty/send.c new file mode 100644 index 00000000..55366653 --- /dev/null +++ b/dsp/tty/send.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" +#include "libc/str/str.h" + +/** + * Sends data to teletypewriter. + * + * This function blocks until the full amount is transmitted. + * + * @return 0 on success, or -1 w/ errno + */ +int ttysend(int fd, const char *str) { return ttywrite(fd, str, strlen(str)); } diff --git a/dsp/tty/sendtitle.c b/dsp/tty/sendtitle.c new file mode 100644 index 00000000..499379f3 --- /dev/null +++ b/dsp/tty/sendtitle.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" +#include "libc/alg/arraylist2.h" +#include "libc/runtime/gc.h" +#include "libc/x/x.h" + +/** + * Changes text in title bar of pseudo-teletypewriter window. + * + * @param title is trustworthy text without any BEL characters + * @param ti comes from ttyident() and null means no-op + */ +int ttysendtitle(int ttyfd, const char *title, const struct TtyIdent *ti) { + if (ti) { + if (ti->id == kTtyIdScreen) { + return ttysend(ttyfd, gc(xstrcat("\eP\e]0;", title, "\a\e\\"))); + } else { + return ttysend(ttyfd, gc(xstrcat("\e]0;", title, "\a"))); + } + } else { + return 0; + } +} diff --git a/dsp/tty/setansipalette.c b/dsp/tty/setansipalette.c new file mode 100644 index 00000000..774c1a73 --- /dev/null +++ b/dsp/tty/setansipalette.c @@ -0,0 +1,25 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/quant.h" +#include "libc/str/str.h" + +void setansipalette(ttypalette_t palette) { + memcpy(g_ansi2rgb_, palette, sizeof(struct TtyRgb) * 2 * 8); +} diff --git a/dsp/tty/setbgfg16.c b/dsp/tty/setbgfg16.c new file mode 100644 index 00000000..6adca49d --- /dev/null +++ b/dsp/tty/setbgfg16.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/itoa8.h" +#include "dsp/tty/quant.h" +#include "libc/limits.h" + +static char *ansitoa(char *p, unsigned xt, unsigned base) { + if (xt >= 8) xt -= 8, base += 60; + return itoa8(p, xt + base); +} + +static char *setansibgfg(char *p, unsigned bg, unsigned fg) { + *p++ = '\e'; + *p++ = '['; + if (bg != -1u) p = ansitoa(p, bg, 40); + if (bg != -1u && fg != -1u) *p++ = ';'; + if (fg != -1u) p = ansitoa(p, fg, 30); + *p++ = 'm'; + return p; +} + +char *setbg16_(char *p, struct TtyRgb bg) { return setansibgfg(p, bg.xt, -1u); } +char *setfg16_(char *p, struct TtyRgb fg) { return setansibgfg(p, -1u, fg.xt); } +char *setbgfg16_(char *p, struct TtyRgb bg, struct TtyRgb fg) { + return setansibgfg(p, bg.xt, fg.xt); +} diff --git a/dsp/tty/setbgfg24.c b/dsp/tty/setbgfg24.c new file mode 100644 index 00000000..6425b820 --- /dev/null +++ b/dsp/tty/setbgfg24.c @@ -0,0 +1,54 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/itoa8.h" +#include "dsp/tty/quant.h" +#include "libc/str/str.h" + +static char *rgbcpy(char *p, struct TtyRgb bg) { + memcpy(p, ";2;\0", 4); + p = itoa8(p + 3, bg.r); + *p++ = ';'; + p = itoa8(p, bg.g); + *p++ = ';'; + return itoa8(p, bg.b); +} + +char *setbg24_(char *p, struct TtyRgb bg) { + memcpy(p, "\e[48", 4); + p = rgbcpy(p + 4, bg); + *p++ = 'm'; + return p; +} + +char *setfg24_(char *p, struct TtyRgb fg) { + memcpy(p, "\e[38", 4); + p = rgbcpy(p + 4, fg); + *p++ = 'm'; + return p; +} + +char *setbgfg24_(char *p, struct TtyRgb bg, struct TtyRgb fg) { + memcpy(p, "\e[48", 4); + p = rgbcpy(p + 4, bg); + memcpy(p, ";38\0", 4); + p = rgbcpy(p + 3, fg); + *p++ = 'm'; + return p; +} diff --git a/dsp/tty/setbgfg256.c b/dsp/tty/setbgfg256.c new file mode 100644 index 00000000..6b7ea202 --- /dev/null +++ b/dsp/tty/setbgfg256.c @@ -0,0 +1,48 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/itoa8.h" +#include "dsp/tty/quant.h" + +char *setbg256_(char *p, struct TtyRgb bg) { + memcpy(p, "\e[48", 4); + memcpy(p + 4, ";5;\0", 4); + p = itoa8(p + 7, bg.xt); + *p++ = 'm'; + return p; +} + +char *setfg256_(char *p, struct TtyRgb fg) { + memcpy(p, "\e[38", 4); + memcpy(p + 4, ";5;\0", 4); + p = itoa8(p + 7, fg.xt); + *p++ = 'm'; + return p; +} + +char *setbgfg256_(char *p, struct TtyRgb bg, struct TtyRgb fg) { + memcpy(p, "\e[48", 4); + memcpy(p + 4, ";5;\0", 4); + p = itoa8(p + 7, bg.xt); + memcpy(p, ";38;", 4); + memcpy(p + 4, "5;\0", 4); + p = itoa8(p + 6, fg.xt); + *p++ = 'm'; + return p; +} diff --git a/dsp/tty/setraw.c b/dsp/tty/setraw.c new file mode 100644 index 00000000..c6a5daa4 --- /dev/null +++ b/dsp/tty/setraw.c @@ -0,0 +1,52 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" +#include "libc/calls/termios.h" +#include "libc/sysv/consts/termios.h" + +/** + * Enables direct teletypewriter communication. + * + * @see ttyconfig(), ttyrestore() + */ +int ttysetraw(struct termios *conf, int64_t flags) { + conf->c_iflag &= ~(INPCK | ISTRIP | PARMRK | INLCR | IGNCR | ICRNL | IXON); + conf->c_lflag &= ~(IEXTEN | ICANON); + conf->c_cflag &= ~(CSIZE | PARENB); + conf->c_cflag |= CS8; + conf->c_iflag |= IUTF8; + /* if (flags & kTtyLfToCrLf) { */ + /* /\* conf->c_oflag &= ~(OLCUC | OCRNL | ONLRET | OFILL | OFDEL); *\/ */ + /* /\* conf->c_oflag |= ONLCR | ONOCR; *\/ */ + /* conf->c_oflag |= ONLCR; */ + /* } else { */ + /* conf->c_oflag &= ~OPOST; */ + /* } */ + if (!(flags & kTtySigs)) { + conf->c_iflag &= ~(IGNBRK | BRKINT); + conf->c_lflag &= ~(ISIG); + } + if (flags & kTtyEcho) { + conf->c_lflag |= ECHO | ECHONL; + } else { + conf->c_lflag &= ~(ECHO | ECHONL); + } + return 0; +} diff --git a/dsp/tty/setrawdeadline.c b/dsp/tty/setrawdeadline.c new file mode 100644 index 00000000..3664c3e5 --- /dev/null +++ b/dsp/tty/setrawdeadline.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" +#include "libc/assert.h" +#include "libc/calls/termios.h" +#include "libc/sysv/consts/termios.h" + +/** + * Enables direct teletypewriter communication w/ read timeouts. + * @see ttyconfig(), ttyrestore() + */ +int ttysetrawdeadline(struct termios *conf, int64_t deciseconds) { + assert(0 < deciseconds && deciseconds < 256); + conf->c_cc[VMIN] = 0; + conf->c_cc[VTIME] = deciseconds; + return ttysetraw(conf, 0); +} diff --git a/dsp/tty/setrawmode.c b/dsp/tty/setrawmode.c new file mode 100644 index 00000000..211beae9 --- /dev/null +++ b/dsp/tty/setrawmode.c @@ -0,0 +1,33 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" +#include "libc/assert.h" +#include "libc/calls/termios.h" +#include "libc/sysv/consts/termios.h" + +/** + * Enables blocking raw mode for teletypewriter w/ recommended settings. + * @see ttyconfig(), ttyrestore() + */ +int ttysetrawmode(struct termios *conf, int64_t flags) { + conf->c_cc[VMIN] = 1; + conf->c_cc[VTIME] = 1; + return ttysetraw(conf, flags); +} diff --git a/dsp/tty/tty.h b/dsp/tty/tty.h new file mode 100644 index 00000000..be4f53ac --- /dev/null +++ b/dsp/tty/tty.h @@ -0,0 +1,59 @@ +#ifndef COSMOPOLITAN_DSP_TTY_TTY_H_ +#define COSMOPOLITAN_DSP_TTY_TTY_H_ + +#define kTtyIdScreen 83 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct FILE; +struct termios; + +struct TtyIdent { + int id; /* first number sent back by \e[>c */ + int version; /* second number sent back by \e[>c */ + struct TtyIdent *next; /* yo dawg */ +}; + +struct TtyCursor { + int y; + int x; + int bg; + int fg; +}; + +enum TtyRawFlags { + kTtyEcho = 1 << 0, /* echo input */ + kTtyCursor = 1 << 1, /* show cursor */ + kTtySigs = 1 << 2, /* auto raise() on CTRL+C, CTRL+Z, and CTRL+\ */ + kTtyLfToCrLf = 1 << 3, /* enables unix newline magic */ +}; + +typedef int (*ttyconf_f)(struct termios *, int64_t); + +int ttyraw(enum TtyRawFlags); +int ttyhidecursor(int); +int ttyshowcursor(int); +int ttysavecursor(int); +int ttyrestorecursor(int); +int ttyenablealtbuf(int); +int ttydisablealtbuf(int); +int ttysend(int, const char *); +int ttywrite(int, const void *, size_t); +int ttysendtitle(int, const char *, const struct TtyIdent *); +int ttyident(struct TtyIdent *, int, int); +void ttyidentclear(struct TtyIdent *); +char *ttydescribe(char *, size_t, const struct TtyIdent *); +int ttyconfig(int, ttyconf_f, int64_t, const struct termios *); +int ttyrestore(int, const struct termios *); +int ttysetrawdeadline(struct termios *, int64_t); +int ttysetrawmode(struct termios *, int64_t); +int ttysetraw(struct termios *, int64_t); +char *ttymove(struct TtyCursor *, char *, int, int) + paramsnonnull() returnsnonnull; +void ttyhisto(uint32_t[hasatleast 256], uint8_t[hasatleast 256], + const uint8_t *, const uint8_t *, size_t); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_TTY_TTY_H_ */ diff --git a/dsp/tty/tty.mk b/dsp/tty/tty.mk new file mode 100644 index 00000000..4c9478f6 --- /dev/null +++ b/dsp/tty/tty.mk @@ -0,0 +1,70 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += DSP_TTY + +DSP_TTY_ARTIFACTS += DSP_TTY_A +DSP_TTY = $(DSP_TTY_A_DEPS) $(DSP_TTY_A) +DSP_TTY_A = o/$(MODE)/dsp/tty/tty.a +DSP_TTY_A_FILES := $(wildcard dsp/tty/*) +DSP_TTY_A_HDRS = $(filter %.h,$(DSP_TTY_A_FILES)) +DSP_TTY_A_SRCS_S = $(filter %.S,$(DSP_TTY_A_FILES)) +DSP_TTY_A_SRCS_C = $(filter %.c,$(DSP_TTY_A_FILES)) + +DSP_TTY_A_SRCS = \ + $(DSP_TTY_A_SRCS_S) \ + $(DSP_TTY_A_SRCS_C) + +DSP_TTY_A_OBJS = \ + $(DSP_TTY_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(DSP_TTY_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(DSP_TTY_A_SRCS_C:%.c=o/$(MODE)/%.o) + +DSP_TTY_A_CHECKS = \ + $(DSP_TTY_A).pkg \ + $(DSP_TTY_A_HDRS:%=o/$(MODE)/%.ok) + +DSP_TTY_A_DIRECTDEPS = \ + DSP_CORE \ + LIBC_ALG \ + LIBC_CALLS \ + LIBC_FMT \ + LIBC_LOG \ + LIBC_RUNTIME \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_NT_KERNELBASE \ + LIBC_STR \ + LIBC_STDIO \ + LIBC_STUBS \ + LIBC_SOCK \ + LIBC_SYSV \ + LIBC_TINYMATH \ + LIBC_TIME \ + LIBC_X \ + LIBC_UNICODE + +DSP_TTY_A_DEPS := \ + $(call uniq,$(foreach x,$(DSP_TTY_A_DIRECTDEPS),$($(x)))) + +$(DSP_TTY_A): dsp/tty/ \ + $(DSP_TTY_A).pkg \ + $(DSP_TTY_A_OBJS) + +$(DSP_TTY_A).pkg: \ + $(DSP_TTY_A_OBJS) \ + $(foreach x,$(DSP_TTY_A_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/dsp/tty/ttyraster.o: \ + OVERRIDE_CFLAGS += \ + $(MATHEMATICAL) + +DSP_TTY_LIBS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x))) +DSP_TTY_SRCS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x)_SRCS)) +DSP_TTY_HDRS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x)_HDRS)) +DSP_TTY_CHECKS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x)_CHECKS)) +DSP_TTY_OBJS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x)_OBJS)) +$(DSP_TTY_OBJS): $(BUILD_FILES) dsp/tty/tty.mk + +.PHONY: o/$(MODE)/dsp/tty +o/$(MODE)/dsp/tty: $(DSP_TTY_CHECKS) diff --git a/dsp/tty/tty2rgb24.c b/dsp/tty/tty2rgb24.c new file mode 100644 index 00000000..11d76785 --- /dev/null +++ b/dsp/tty/tty2rgb24.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/quant.h" + +struct TtyRgb tty2rgb24_(struct TtyRgb rgbxt) { + return rgbxt; +} diff --git a/dsp/tty/tty2rgbf24.c b/dsp/tty/tty2rgbf24.c new file mode 100644 index 00000000..b2d6b3c9 --- /dev/null +++ b/dsp/tty/tty2rgbf24.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/quant.h" + +__m128 tty2rgbf24_(struct TtyRgb rgbxt) { + return (__m128){(int)rgbxt.r, (int)rgbxt.g, (int)rgbxt.b} / 255; +} diff --git a/dsp/tty/ttyhisto.c b/dsp/tty/ttyhisto.c new file mode 100644 index 00000000..8e722eaf --- /dev/null +++ b/dsp/tty/ttyhisto.c @@ -0,0 +1,51 @@ + +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" +#include "libc/alg/alg.h" +#include "libc/nexgen32e/nexgen32e.h" +#include "libc/str/str.h" + +static int histcmp(const uint8_t *i1p, const uint8_t *i2p, + uint32_t histogram[hasatleast 256]) { + if (histogram[*i1p] > histogram[*i2p]) { + return -1; + } else if (histogram[*i1p] < histogram[*i2p]) { + return 1; + } else { + return 0; + } +} + +void ttyhisto(uint32_t histogram[hasatleast 256], + uint8_t dominant[hasatleast 256], const uint8_t *xtcolors, + const uint8_t *eqmask, size_t size) { + size_t i; + uint64_t q; + memset(histogram, 0, sizeof(uint32_t) * 256); + for (i = 0; i < size / 8; ++i) { + memcpy(&q, &xtcolors[i * 8], 8); + if (q == (xtcolors[i * 8] & 0xff) * 0x0101010101010101ul) { + histogram[xtcolors[i * 8]]++; + } + } + imapxlatab(dominant); + qsort_r(dominant, 256, 1, (void *)histcmp, histogram); +} diff --git a/dsp/tty/ttymove.c b/dsp/tty/ttymove.c new file mode 100644 index 00000000..d685624b --- /dev/null +++ b/dsp/tty/ttymove.c @@ -0,0 +1,198 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/itoa8.h" +#include "dsp/tty/tty.h" +#include "libc/bits/safemacros.h" +#include "libc/limits.h" +#include "libc/log/check.h" + +/** + * Moves teletypewriter cursor to new coordinate. + * + * This uses codings defined by ANSI X3.4-1967 / X3.64-1979. + * + * @param c [in/out] tracks cursor coordinate + * @param p [out] buffer receives ANSI/VT sequences + * @param y is 0-indexed row + * @param x is 0-indexed column + * @return p + written, like mempcpy() + */ +char *ttymove(struct TtyCursor *c, char *p, int y, int x) { + int d; + DCHECK_GE(y, 0); + DCHECK_GE(x, 0); + DCHECK_LE(y, UINT16_MAX); + DCHECK_LE(x, UINT16_MAX); + if (y != c->y || x != c->x) { + do { + if (y != c->y && x != c->x) { + if (y == c->y + 1 && x == 0) { + p[0] = '\r'; + p[1] = '\n'; + p[2] = '\0'; + p[3] = '\0'; + p += 2; + c->y++; + c->x = 0; + break; + } else if (x < 256 && y < 256) { + if (y == 0 && x == 0) { + if (c->y == 0) { + p[0] = '\r'; + p[1] = '\0'; + p += 1; + c->x = 0; + } else { + p[0] = '\e'; /* CUP(1,1) */ + p[1] = '['; + p[2] = 'H'; + p[3] = '\0'; + p += 3; + c->y = 0; + c->x = 0; + } + } else if (x == 0) { + *p++ = '\e'; /* CUP(y,1) */ + *p++ = '['; + p = itoa8(p, y + 1); + *p++ = 'H'; + *p = '\0'; + c->y = y; + c->x = 0; + } else if (y == 0) { + *p++ = '\e'; /* CUP(1,x) */ + *p++ = '['; + *p++ = ';'; + *p = '\0'; + p = itoa8(p, x + 1); + *p++ = 'H'; + *p = '\0'; + c->y = 0; + c->x = x; + } else { + *p++ = '\e'; /* CUP(y,1) */ + *p++ = '['; + p = itoa8(p, y + 1); + *p++ = ';'; + p = itoa8(p, x + 1); + *p++ = 'H'; + *p = '\0'; + c->y = y; + c->x = x; + } + break; + } + } + if (x != c->x) { + if (!x) { + p[0] = '\r'; /* goto beginning of line */ + p[1] = '\0'; + p += 1; + c->x = 0; + } else if (x > c->x) { + d = min(255, x - c->x); + if (d == 1) { + p[0] = '\e'; + p[1] = '['; + p[2] = 'C'; /* cursor forward (CUF) */ + p[3] = '\0'; + p += 3; + } else { + p[0] = '\e'; + p[1] = '['; + p = itoa8(p + 2, d); + p[0] = 'C'; /* cursor forward (CUF) */ + p[1] = '\0'; + p[2] = '\0'; + p[3] = '\0'; + p += 1; + } + c->x += d; + } else { + d = min(255, c->x - x); + if (d == 1) { + p[0] = '\e'; + p[1] = '['; + p[2] = 'D'; /* cursor backward (CUB) */ + p[3] = '\0'; + p += 3; + } else { + p[0] = '\e'; + p[1] = '['; + p = itoa8(p + 2, d); + p[0] = 'D'; /* cursor backward (CUB) */ + p[1] = '\0'; + p[2] = '\0'; + p[3] = '\0'; + p += 1; + } + c->x -= d; + } + } + if (y != c->y) { + if (y > c->y) { + d = min(255, y - c->y); + if (d == 1) { + p[0] = '\e'; + p[1] = 'D'; /* index down (IND) */ + p[2] = '\0'; + p[3] = '\0'; + p += 2; + } else { + p[0] = '\e'; + p[1] = '['; + p = itoa8(p + 2, d); + p[0] = 'B'; /* cursor down (CUD) */ + p[1] = '\0'; + p[2] = '\0'; + p[3] = '\0'; + p += 1; + } + c->y += d; + } else { + d = min(255, c->y - y); + if (d == 1) { + p[0] = '\e'; + p[1] = 'M'; /* reverse index (RI) */ + p[2] = '\0'; + p[3] = '\0'; + p += 2; + } else { + p[0] = '\e'; + p[1] = '['; + p = itoa8(p + 2, d); + p[0] = 'A'; /* cursor up (CUU) */ + p[1] = '\0'; + p[2] = '\0'; + p[3] = '\0'; + p += 1; + } + c->y -= d; + } + } + } while (x != c->x || y != c->y); + } else { + p[0] = '\0'; + } + DCHECK_EQ(y, c->y); + DCHECK_EQ(x, c->x); + DCHECK_EQ(p[0], '\0'); + return p; +} diff --git a/dsp/tty/ttyraster.c b/dsp/tty/ttyraster.c new file mode 100644 index 00000000..3064f2a0 --- /dev/null +++ b/dsp/tty/ttyraster.c @@ -0,0 +1,799 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/twixt8.h" +#include "dsp/tty/quant.h" +#include "dsp/tty/tty.h" +#include "dsp/tty/ttyrgb.h" +#include "dsp/tty/windex.h" +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/limits.h" +#include "libc/log/check.h" +#include "libc/log/log.h" +#include "libc/macros.h" +#include "libc/math.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" + +#define SQR(X) ((X) * (X)) +#define DIST(X, Y) ((X) - (Y)) +#define QSUB(A, B, C) ABS(DIST(A##C, B##C)) +#define DIFF(A, B) (QSUB(A, B, r) + QSUB(A, B, g) + QSUB(A, B, b)) +#define JUDGE(M) (DIFF(ttl, M) + DIFF(ttr, M) + DIFF(tbl, M) + DIFF(tbr, M)) + +static const struct Glyph { + char c1, c2, c3, len; +} kGlyphs[2][11] = { + {{0x20, 0x00, 0x00, 1}, /* */ + {0xE2, 0x96, 0x84, 3}, /* ▄ */ + {0xE2, 0x96, 0x8C, 3}, /* ▌ */ + {0xE2, 0x96, 0x9D, 3}, /* ▝ */ + {0xE2, 0x96, 0x97, 3}, /* ▗ */ + {0xE2, 0x96, 0x96, 3}, /* ▖ */ + {0xE2, 0x96, 0x9E, 3}, /* ▞ */ + {0xE2, 0x96, 0x98, 3}, /* ▘ */ + {0xE2, 0x96, 0x91, 3}, /* ░ */ + {0xE2, 0x96, 0x93, 3}, /* ▓ */ + {0xE2, 0x96, 0x92, 3}}, /* ▒ */ + {{0xE2, 0x96, 0x88, 3}, /* █ */ + {0xE2, 0x96, 0x80, 3}, /* ▀ */ + {0xE2, 0x96, 0x90, 3}, /* ▐ */ + {0xE2, 0x96, 0x99, 3}, /* ▙ */ + {0xE2, 0x96, 0x9B, 3}, /* ▛ */ + {0xE2, 0x96, 0x9C, 3}, /* ▜ */ + {0xE2, 0x96, 0x9A, 3}, /* ▚ */ + {0xE2, 0x96, 0x9F, 3}, /* ▟ */ + {0xE2, 0x96, 0x93, 3}, /* ▓ */ + {0xE2, 0x96, 0x91, 3}, /* ░ */ + {0xE2, 0x96, 0x92, 3}}, /* ▒ */ +}; + +static const struct Pick { + unsigned char fg, bg, k; +} kPicksUnicode[96] = { + {-1, BL, 0}, /* */ + {BR, BL, 4}, /* ▗ */ + {TL, BL, 4}, /* ▗ */ + {TR, BL, 4}, /* ▗ */ + {BR, BL, 5}, /* ▖ */ + {BR, BL, 1}, /* ▄ */ + {TL, BL, 5}, /* ▖ */ + {TL, BL, 1}, /* ▄ */ + {TR, BL, 5}, /* ▖ */ + {TR, BL, 1}, /* ▄ */ + {BR, BL, 3}, /* ▝ */ + {BL, BR, 2}, /* ▌ */ + {BR, BL, 6}, /* ▞ */ + {BL, BR, 7}, /* ▘ */ + {TL, BL, 3}, /* ▝ */ + {BL, TL, 2}, /* ▌ */ + {TL, BL, 6}, /* ▞ */ + {BL, TL, 7}, /* ▘ */ + {TR, BL, 3}, /* ▝ */ + {BL, TR, 2}, /* ▌ */ + {TR, BL, 6}, /* ▞ */ + {BL, TR, 7}, /* ▘ */ + {BR, BL, 7}, /* ▘ */ + {BL, BR, 6}, /* ▞ */ + {BR, BL, 2}, /* ▌ */ + {BL, BR, 3}, /* ▝ */ + {BL, BR, 1}, /* ▄ */ + {BL, BR, 5}, /* ▖ */ + {BL, BR, 4}, /* ▗ */ + {-1, BR, 0}, /* */ + {TL, BR, 4}, /* ▗ */ + {TR, BR, 4}, /* ▗ */ + {TL, BR, 5}, /* ▖ */ + {TL, BR, 1}, /* ▄ */ + {TR, BR, 5}, /* ▖ */ + {TR, BR, 1}, /* ▄ */ + {TL, BR, 3}, /* ▝ */ + {BR, TL, 2}, /* ▌ */ + {TL, BR, 6}, /* ▞ */ + {BR, TL, 7}, /* ▘ */ + {TR, BR, 3}, /* ▝ */ + {BR, TR, 2}, /* ▌ */ + {TR, BR, 6}, /* ▞ */ + {BR, TR, 7}, /* ▘ */ + {TL, BL, 7}, /* ▘ */ + {BL, TL, 6}, /* ▞ */ + {TL, BL, 2}, /* ▌ */ + {BL, TL, 3}, /* ▝ */ + {TL, BR, 7}, /* ▘ */ + {BR, TL, 6}, /* ▞ */ + {TL, BR, 2}, /* ▌ */ + {BR, TL, 3}, /* ▝ */ + {BL, TL, 1}, /* ▄ */ + {BL, TL, 5}, /* ▖ */ + {BR, TL, 1}, /* ▄ */ + {BR, TL, 5}, /* ▖ */ + {BL, TL, 4}, /* ▗ */ + {BR, TL, 4}, /* ▗ */ + {-1, TL, 0}, /* */ + {TR, TL, 4}, /* ▗ */ + {TR, TL, 5}, /* ▖ */ + {TR, TL, 1}, /* ▄ */ + {TR, TL, 3}, /* ▝ */ + {TL, TR, 2}, /* ▌ */ + {TR, TL, 6}, /* ▞ */ + {TL, TR, 7}, /* ▘ */ + {TR, BL, 7}, /* ▘ */ + {BL, TR, 6}, /* ▞ */ + {TR, BL, 2}, /* ▌ */ + {BL, TR, 3}, /* ▝ */ + {TR, BR, 7}, /* ▘ */ + {BR, TR, 6}, /* ▞ */ + {TR, BR, 2}, /* ▌ */ + {BR, TR, 3}, /* ▝ */ + {TR, TL, 7}, /* ▘ */ + {TL, TR, 6}, /* ▞ */ + {TR, TL, 2}, /* ▌ */ + {TL, TR, 3}, /* ▝ */ + {BL, TR, 1}, /* ▄ */ + {BL, TR, 5}, /* ▖ */ + {BR, TR, 1}, /* ▄ */ + {BR, TR, 5}, /* ▖ */ + {TL, TR, 1}, /* ▄ */ + {TL, TR, 5}, /* ▖ */ + {BL, TR, 4}, /* ▗ */ + {BR, TR, 4}, /* ▗ */ + {TL, TR, 4}, /* ▗ */ + {-1, TR, 0}, /* */ + {-1, -1, -1}, /* X */ + {-1, -1, -1}, /* X */ + {-1, -1, -1}, /* X */ + {-1, -1, -1}, /* X */ + {-1, -1, -1}, /* X */ + {-1, -1, -1}, /* X */ + {-1, -1, -1}, /* X */ + {-1, -1, -1}, /* X */ +}; + +static const struct Pick kPicksCp437[32] = { + {-1, BL, 0}, /* */ + {BR, BL, 1}, /* ▄ */ + {TL, BL, 1}, /* ▄ */ + {TR, BL, 1}, /* ▄ */ + {BL, BR, 1}, /* ▄ */ + {BL, TL, 1}, /* ▄ */ + {BL, TR, 1}, /* ▄ */ + {BL, BR, 2}, /* ▌ */ + {BL, TL, 2}, /* ▌ */ + {BL, TR, 2}, /* ▌ */ + {BR, BL, 2}, /* ▌ */ + {-1, BR, 0}, /* */ + {TL, BR, 1}, /* ▄ */ + {TR, BR, 1}, /* ▄ */ + {BR, TL, 2}, /* ▌ */ + {BR, TR, 2}, /* ▌ */ + {TL, BL, 2}, /* ▌ */ + {TL, BR, 2}, /* ▌ */ + {BR, TL, 1}, /* ▄ */ + {-1, TL, 0}, /* */ + {TR, TL, 1}, /* ▄ */ + {TL, TR, 2}, /* ▌ */ + {TR, BL, 2}, /* ▌ */ + {TR, BR, 2}, /* ▌ */ + {TR, TL, 2}, /* ▌ */ + {BR, TR, 1}, /* ▄ */ + {TL, TR, 1}, /* ▄ */ + {-1, TR, 0}, /* */ + {-1, -1, -1}, /* X */ + {-1, -1, -1}, /* X */ + {-1, -1, -1}, /* X */ + {-1, -1, -1}, /* X */ +}; + +static const struct Pick kPicksMixBlock[32] = { + {BR, BL, 8}, /* ░ */ + {BR, BL, 9}, /* ▓ */ + {TL, BL, 8}, /* ░ */ + {TL, BL, 9}, /* ▓ */ + {TR, BL, 8}, /* ░ */ + {TR, BL, 9}, /* ▓ */ + {TL, BR, 8}, /* ░ */ + {TL, BR, 9}, /* ▓ */ + {TR, BR, 8}, /* ░ */ + {TR, BR, 9}, /* ▓ */ + {BL, TL, 8}, /* ░ */ + {BL, TL, 9}, /* ▓ */ + {BL, TL, 8}, /* ░ */ + {BL, TL, 9}, /* ▓ */ + {TR, TL, 8}, /* ░ */ + {TR, TL, 9}, /* ▓ */ + {BL, TR, 8}, /* ░ */ + {BL, TR, 9}, /* ▓ */ + {BR, TR, 8}, /* ░ */ + {BR, TR, 9}, /* ▓ */ + {TL, TR, 8}, /* ░ */ + {TL, TR, 9}, /* ▓ */ + /**/ + {BL, TL, 8}, /* ░ */ + {BL, TL, 9}, /* ▓ */ + {TR, TL, 8}, /* ░ */ + {TR, TL, 9}, /* ▓ */ + {BL, TR, 8}, /* ░ */ + {BL, TR, 9}, /* ▓ */ + {BR, TR, 8}, /* ░ */ + {BR, TR, 9}, /* ▓ */ + {TL, TR, 8}, /* ░ */ + {TL, TR, 9}, /* ▓ */ +}; + +static unsigned short bdist(struct TtyRgb a, struct TtyRgb b, struct TtyRgb c, + struct TtyRgb d, struct TtyRgb w, struct TtyRgb x, + struct TtyRgb y, struct TtyRgb z) { + unsigned short dist; + dist = 0; + dist += ABS(a.r - w.r); + dist += ABS(a.g - w.g); + dist += ABS(a.b - w.b); + dist += ABS(b.r - x.r); + dist += ABS(b.g - x.g); + dist += ABS(b.b - x.b); + dist += ABS(c.r - y.r); + dist += ABS(c.g - y.g); + dist += ABS(c.b - y.b); + dist += ABS(d.r - z.r); + dist += ABS(d.g - z.g); + dist += ABS(d.b - z.b); + return dist; +} + +static uint16_t *mixblock(uint16_t *p, struct TtyRgb ttl, struct TtyRgb ttr, + struct TtyRgb tbl, struct TtyRgb tbr, + struct TtyRgb qtl, struct TtyRgb qtr, + struct TtyRgb qbl, struct TtyRgb qbr) { + unsigned char ttlr, ttlg, ttlb, qtlr, qtlg, qtlb, ttrr, ttrg, ttrb, qtrr, + qtrg, qtrb, tblr, tblg, tblb, qblr, qblg, qblb, tbrr, tbrg, tbrb, qbrr, + qbrg, qbrb, l00r, l00g, l00b, l01r, l01g, l01b, l02r, l02g, l02b, l03r, + l03g, l03b, l04r, l04g, l04b, l05r, l05g, l05b, l06r, l06g, l06b, l07r, + l07g, l07b, l08r, l08g, l08b, l09r, l09g, l09b, l10r, l10g, l10b, l11r, + l11g, l11b, l12r, l12g, l12b, l13r, l13g, l13b, l14r, l14g, l14b, l15r, + l15g, l15b, l16r, l16g, l16b, l17r, l17g, l17b, l18r, l18g, l18b, l19r, + l19g, l19b, l20r, l20g, l20b, l21r, l21g, l21b, l22r, l22g, l22b, l23r, + l23g, l23b, l24r, l24g, l24b, l25r, l25g, l25b, l26r, l26g, l26b, l27r, + l27g, l27b, l28r, l28g, l28b, l29r, l29g, l29b, l30r, l30g, l30b, l31r, + l31g, l31b; + unsigned short p00, p01, p02, p03, p04, p05, p06, p07, p08, p09, p10, p11, + p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, + p27, p28, p29, p30, p31; + ttlr = ttl.r; + ttlg = ttl.g; + ttlb = ttl.b; + qtlr = qtl.r; + qtlg = qtl.g; + qtlb = qtl.b; + ttrr = ttr.r; + ttrg = ttr.g; + ttrb = ttr.b; + qtrr = qtr.r; + qtrg = qtr.g; + qtrb = qtr.b; + tblr = tbl.r; + tblg = tbl.g; + tblb = tbl.b; + qblr = qbl.r; + qblg = qbl.g; + qblb = qbl.b; + tbrr = tbr.r; + tbrg = tbr.g; + tbrb = tbr.b; + qbrr = qbr.r; + qbrg = qbr.g; + qbrb = qbr.b; + l00r = twixt8(qblr, qbrr, 0100); + l00g = twixt8(qblg, qbrg, 0100); + l00b = twixt8(qblb, qbrb, 0100); + l01r = twixt8(qblr, qbrr, 0300); + l01g = twixt8(qblg, qbrg, 0300); + l01b = twixt8(qblb, qbrb, 0300); + l02r = twixt8(qblr, qbrr, 0200); + l02g = twixt8(qblg, qbrg, 0200); + l02b = twixt8(qblb, qbrb, 0200); + l03r = twixt8(qblr, qtlr, 0100); + l03g = twixt8(qblg, qtlg, 0100); + l03b = twixt8(qblb, qtlb, 0100); + l04r = twixt8(qblr, qtlr, 0300); + l04g = twixt8(qblg, qtlg, 0300); + l04b = twixt8(qblb, qtlb, 0300); + l05r = twixt8(qblr, qtlr, 0200); + l05g = twixt8(qblg, qtlg, 0200); + l05b = twixt8(qblb, qtlb, 0200); + l06r = twixt8(qblr, qtrr, 0100); + l06g = twixt8(qblg, qtrg, 0100); + l06b = twixt8(qblb, qtrb, 0100); + l07r = twixt8(qblr, qtrr, 0300); + l07g = twixt8(qblg, qtrg, 0300); + l07b = twixt8(qblb, qtrb, 0300); + l08r = twixt8(qblr, qtrr, 0200); + l08g = twixt8(qblg, qtrg, 0200); + l08b = twixt8(qblb, qtrb, 0200); + l09r = twixt8(qbrr, qtlr, 0100); + l09g = twixt8(qbrg, qtlg, 0100); + l09b = twixt8(qbrb, qtlb, 0100); + l10r = twixt8(qbrr, qtlr, 0300); + l10g = twixt8(qbrg, qtlg, 0300); + l10b = twixt8(qbrb, qtlb, 0300); + l11r = twixt8(qbrr, qtlr, 0200); + l11g = twixt8(qbrg, qtlg, 0200); + l11b = twixt8(qbrb, qtlb, 0200); + l12r = twixt8(qbrr, qtrr, 0100); + l12g = twixt8(qbrg, qtrg, 0100); + l12b = twixt8(qbrb, qtrb, 0100); + l13r = twixt8(qbrr, qtrr, 0300); + l13g = twixt8(qbrg, qtrg, 0300); + l13b = twixt8(qbrb, qtrb, 0300); + l14r = twixt8(qbrr, qtrr, 0200); + l14g = twixt8(qbrg, qtrg, 0200); + l14b = twixt8(qbrb, qtrb, 0200); + l15r = twixt8(qtlr, qblr, 0100); + l15g = twixt8(qtlg, qblg, 0100); + l15b = twixt8(qtlb, qblb, 0100); + l16r = twixt8(qtlr, qblr, 0300); + l16g = twixt8(qtlg, qblg, 0300); + l16b = twixt8(qtlb, qblb, 0300); + l17r = twixt8(qtlr, qblr, 0200); + l17g = twixt8(qtlg, qblg, 0200); + l17b = twixt8(qtlb, qblb, 0200); + l18r = twixt8(qtlr, qbrr, 0100); + l18g = twixt8(qtlg, qbrg, 0100); + l18b = twixt8(qtlb, qbrb, 0100); + l19r = twixt8(qtlr, qbrr, 0300); + l19g = twixt8(qtlg, qbrg, 0300); + l19b = twixt8(qtlb, qbrb, 0300); + l20r = twixt8(qtlr, qbrr, 0200); + l20g = twixt8(qtlg, qbrg, 0200); + l20b = twixt8(qtlb, qbrb, 0200); + l21r = twixt8(qtlr, qtrr, 0100); + l21g = twixt8(qtlg, qtrg, 0100); + l21b = twixt8(qtlb, qtrb, 0100); + l22r = twixt8(qtlr, qtrr, 0300); + l22g = twixt8(qtlg, qtrg, 0300); + l22b = twixt8(qtlb, qtrb, 0300); + l23r = twixt8(qtlr, qtrr, 0200); + l23g = twixt8(qtlg, qtrg, 0200); + l23b = twixt8(qtlb, qtrb, 0200); + l24r = twixt8(qtrr, qblr, 0100); + l24g = twixt8(qtrg, qblg, 0100); + l24b = twixt8(qtrb, qblb, 0100); + l25r = twixt8(qtrr, qblr, 0300); + l25g = twixt8(qtrg, qblg, 0300); + l25b = twixt8(qtrb, qblb, 0300); + l26r = twixt8(qtrr, qblr, 0200); + l26g = twixt8(qtrg, qblg, 0200); + l26b = twixt8(qtrb, qblb, 0200); + l27r = twixt8(qtrr, qbrr, 0100); + l27g = twixt8(qtrg, qbrg, 0100); + l27b = twixt8(qtrb, qbrb, 0100); + l28r = twixt8(qtrr, qbrr, 0300); + l28g = twixt8(qtrg, qbrg, 0300); + l28b = twixt8(qtrb, qbrb, 0300); + l29r = twixt8(qtrr, qbrr, 0200); + l29g = twixt8(qtrg, qbrg, 0200); + l29b = twixt8(qtrb, qbrb, 0200); + l30r = twixt8(qtrr, qtlr, 0100); + l30g = twixt8(qtrg, qtlg, 0100); + l30b = twixt8(qtrb, qtlb, 0100); + l31r = twixt8(qtrr, qtlr, 0300); + l31g = twixt8(qtrg, qtlg, 0300); + l31b = twixt8(qtrb, qtlb, 0300); + p00 = JUDGE(l00); + p01 = JUDGE(l01); + p02 = JUDGE(l02); + p03 = JUDGE(l03); + p04 = JUDGE(l04); + p05 = JUDGE(l05); + p06 = JUDGE(l06); + p07 = JUDGE(l07); + p08 = JUDGE(l08); + p09 = JUDGE(l09); + p10 = JUDGE(l10); + p11 = JUDGE(l11); + p12 = JUDGE(l12); + p13 = JUDGE(l13); + p14 = JUDGE(l14); + p15 = JUDGE(l15); + p16 = JUDGE(l16); + p17 = JUDGE(l17); + p18 = JUDGE(l18); + p19 = JUDGE(l19); + p20 = JUDGE(l20); + p21 = JUDGE(l21); + p22 = JUDGE(l22); + p23 = JUDGE(l23); + p24 = JUDGE(l24); + p25 = JUDGE(l25); + p26 = JUDGE(l26); + p27 = JUDGE(l27); + p28 = JUDGE(l28); + p29 = JUDGE(l29); + p30 = JUDGE(l30); + p31 = JUDGE(l31); + *p++ = p00; + *p++ = p01; + *p++ = p02; + *p++ = p03; + *p++ = p04; + *p++ = p05; + *p++ = p06; + *p++ = p07; + *p++ = p08; + *p++ = p09; + *p++ = p10; + *p++ = p11; + *p++ = p12; + *p++ = p13; + *p++ = p14; + *p++ = p15; + *p++ = p16; + *p++ = p17; + *p++ = p18; + *p++ = p19; + *p++ = p20; + *p++ = p21; + *p++ = p22; + *p++ = p23; + *p++ = p24; + *p++ = p25; + *p++ = p26; + *p++ = p27; + *p++ = p28; + *p++ = p29; + *p++ = p30; + *p++ = p31; + return p; +} + +static struct TtyRgb getquant(struct TtyRgb rgb) { + return g_ansi2rgb_[rgb.xt]; +} + +static uint16_t *pickunicode(uint16_t *p, struct TtyRgb tl, struct TtyRgb tr, + struct TtyRgb bl, struct TtyRgb br, + struct TtyRgb tl2, struct TtyRgb tr2, + struct TtyRgb bl2, struct TtyRgb br2) { +#define PICK(A, B, C, D) *p++ = bdist(tl, tr, bl, br, A, B, C, D) + PICK(bl2, bl2, bl2, bl2); /* k=0 bg=bl fg=NULL */ + PICK(bl2, bl2, bl2, br2); /* ▗ k=4 bg=bl fg=br */ + PICK(bl2, bl2, bl2, tl2); /* ▗ k=4 bg=bl fg=tl */ + PICK(bl2, bl2, bl2, tr2); /* ▗ k=4 bg=bl fg=tr */ + PICK(bl2, bl2, br2, bl2); /* ▖ k=5 bg=bl fg=br */ + PICK(bl2, bl2, br2, br2); /* ▄ k=1 bg=bl fg=br */ + PICK(bl2, bl2, tl2, bl2); /* ▖ k=5 bg=bl fg=tl */ + PICK(bl2, bl2, tl2, tl2); /* ▄ k=1 bg=bl fg=tl */ + PICK(bl2, bl2, tr2, bl2); /* ▖ k=5 bg=bl fg=tr */ + PICK(bl2, bl2, tr2, tr2); /* ▄ k=1 bg=bl fg=tr */ + PICK(bl2, br2, bl2, bl2); /* ▝ k=3 bg=bl fg=br */ + PICK(bl2, br2, bl2, br2); /* ▌ k=2 bg=br fg=bl */ + PICK(bl2, br2, br2, bl2); /* ▞ k=6 bg=bl fg=br */ + PICK(bl2, br2, br2, br2); /* ▘ k=7 bg=br fg=bl */ + PICK(bl2, tl2, bl2, bl2); /* ▝ k=3 bg=bl fg=tl */ + PICK(bl2, tl2, bl2, tl2); /* ▌ k=2 bg=tl fg=bl */ + PICK(bl2, tl2, tl2, bl2); /* ▞ k=6 bg=bl fg=tl */ + PICK(bl2, tl2, tl2, tl2); /* ▘ k=7 bg=tl fg=bl */ + PICK(bl2, tr2, bl2, bl2); /* ▝ k=3 bg=bl fg=tr */ + PICK(bl2, tr2, bl2, tr2); /* ▌ k=2 bg=tr fg=bl */ + PICK(bl2, tr2, tr2, bl2); /* ▞ k=6 bg=bl fg=tr */ + PICK(bl2, tr2, tr2, tr2); /* ▘ k=7 bg=tr fg=bl */ + PICK(br2, bl2, bl2, bl2); /* ▘ k=7 bg=bl fg=br */ + PICK(br2, bl2, bl2, br2); /* ▞ k=6 bg=br fg=bl */ + PICK(br2, bl2, br2, bl2); /* ▌ k=2 bg=bl fg=br */ + PICK(br2, bl2, br2, br2); /* ▝ k=3 bg=br fg=bl */ + PICK(br2, br2, bl2, bl2); /* ▄ k=1 bg=br fg=bl */ + PICK(br2, br2, bl2, br2); /* ▖ k=5 bg=br fg=bl */ + PICK(br2, br2, br2, bl2); /* ▗ k=4 bg=br fg=bl */ + PICK(br2, br2, br2, br2); /* k=0 bg=br fg=NULL */ + PICK(br2, br2, br2, tl2); /* ▗ k=4 bg=br fg=tl */ + PICK(br2, br2, br2, tr2); /* ▗ k=4 bg=br fg=tr */ + PICK(br2, br2, tl2, br2); /* ▖ k=5 bg=br fg=tl */ + PICK(br2, br2, tl2, tl2); /* ▄ k=1 bg=br fg=tl */ + PICK(br2, br2, tr2, br2); /* ▖ k=5 bg=br fg=tr */ + PICK(br2, br2, tr2, tr2); /* ▄ k=1 bg=br fg=tr */ + PICK(br2, tl2, br2, br2); /* ▝ k=3 bg=br fg=tl */ + PICK(br2, tl2, br2, tl2); /* ▌ k=2 bg=tl fg=br */ + PICK(br2, tl2, tl2, br2); /* ▞ k=6 bg=br fg=tl */ + PICK(br2, tl2, tl2, tl2); /* ▘ k=7 bg=tl fg=br */ + PICK(br2, tr2, br2, br2); /* ▝ k=3 bg=br fg=tr */ + PICK(br2, tr2, br2, tr2); /* ▌ k=2 bg=tr fg=br */ + PICK(br2, tr2, tr2, br2); /* ▞ k=6 bg=br fg=tr */ + PICK(br2, tr2, tr2, tr2); /* ▘ k=7 bg=tr fg=br */ + PICK(tl2, bl2, bl2, bl2); /* ▘ k=7 bg=bl fg=tl */ + PICK(tl2, bl2, bl2, tl2); /* ▞ k=6 bg=tl fg=bl */ + PICK(tl2, bl2, tl2, bl2); /* ▌ k=2 bg=bl fg=tl */ + PICK(tl2, bl2, tl2, tl2); /* ▝ k=3 bg=tl fg=bl */ + PICK(tl2, br2, br2, br2); /* ▘ k=7 bg=br fg=tl */ + PICK(tl2, br2, br2, tl2); /* ▞ k=6 bg=tl fg=br */ + PICK(tl2, br2, tl2, br2); /* ▌ k=2 bg=br fg=tl */ + PICK(tl2, br2, tl2, tl2); /* ▝ k=3 bg=tl fg=br */ + PICK(tl2, tl2, bl2, bl2); /* ▄ k=1 bg=tl fg=bl */ + PICK(tl2, tl2, bl2, tl2); /* ▖ k=5 bg=tl fg=bl */ + PICK(tl2, tl2, br2, br2); /* ▄ k=1 bg=tl fg=br */ + PICK(tl2, tl2, br2, tl2); /* ▖ k=5 bg=tl fg=br */ + PICK(tl2, tl2, tl2, bl2); /* ▗ k=4 bg=tl fg=bl */ + PICK(tl2, tl2, tl2, br2); /* ▗ k=4 bg=tl fg=br */ + PICK(tl2, tl2, tl2, tl2); /* k=0 bg=tl fg=NULL */ + PICK(tl2, tl2, tl2, tr2); /* ▗ k=4 bg=tl fg=tr */ + PICK(tl2, tl2, tr2, tl2); /* ▖ k=5 bg=tl fg=tr */ + PICK(tl2, tl2, tr2, tr2); /* ▄ k=1 bg=tl fg=tr */ + PICK(tl2, tr2, tl2, tl2); /* ▝ k=3 bg=tl fg=tr */ + PICK(tl2, tr2, tl2, tr2); /* ▌ k=2 bg=tr fg=tl */ + PICK(tl2, tr2, tr2, tl2); /* ▞ k=6 bg=tl fg=tr */ + PICK(tl2, tr2, tr2, tr2); /* ▘ k=7 bg=tr fg=tl */ + PICK(tr2, bl2, bl2, bl2); /* ▘ k=7 bg=bl fg=tr */ + PICK(tr2, bl2, bl2, tr2); /* ▞ k=6 bg=tr fg=bl */ + PICK(tr2, bl2, tr2, bl2); /* ▌ k=2 bg=bl fg=tr */ + PICK(tr2, bl2, tr2, tr2); /* ▝ k=3 bg=tr fg=bl */ + PICK(tr2, br2, br2, br2); /* ▘ k=7 bg=br fg=tr */ + PICK(tr2, br2, br2, tr2); /* ▞ k=6 bg=tr fg=br */ + PICK(tr2, br2, tr2, br2); /* ▌ k=2 bg=br fg=tr */ + PICK(tr2, br2, tr2, tr2); /* ▝ k=3 bg=tr fg=br */ + PICK(tr2, tl2, tl2, tl2); /* ▘ k=7 bg=tl fg=tr */ + PICK(tr2, tl2, tl2, tr2); /* ▞ k=6 bg=tr fg=tl */ + PICK(tr2, tl2, tr2, tl2); /* ▌ k=2 bg=tl fg=tr */ + PICK(tr2, tl2, tr2, tr2); /* ▝ k=3 bg=tr fg=tl */ + PICK(tr2, tr2, bl2, bl2); /* ▄ k=1 bg=tr fg=bl */ + PICK(tr2, tr2, bl2, tr2); /* ▖ k=5 bg=tr fg=bl */ + PICK(tr2, tr2, br2, br2); /* ▄ k=1 bg=tr fg=br */ + PICK(tr2, tr2, br2, tr2); /* ▖ k=5 bg=tr fg=br */ + PICK(tr2, tr2, tl2, tl2); /* ▄ k=1 bg=tr fg=tl */ + PICK(tr2, tr2, tl2, tr2); /* ▖ k=5 bg=tr fg=tl */ + PICK(tr2, tr2, tr2, bl2); /* ▗ k=4 bg=tr fg=bl */ + PICK(tr2, tr2, tr2, br2); /* ▗ k=4 bg=tr fg=br */ + PICK(tr2, tr2, tr2, tl2); /* ▗ k=4 bg=tr fg=tl */ + PICK(tr2, tr2, tr2, tr2); /* k=0 bg=tr fg=NULL */ +#undef PICK + return p; +} + +static uint16_t *pickcp437(uint16_t *p, struct TtyRgb tl, struct TtyRgb tr, + struct TtyRgb bl, struct TtyRgb br, + struct TtyRgb tl2, struct TtyRgb tr2, + struct TtyRgb bl2, struct TtyRgb br2) { +#define PICK(A, B, C, D) *p++ = bdist(tl, tr, bl, br, A, B, C, D) + PICK(bl2, bl2, bl2, bl2); /* k=0 bg=bl fg=NULL */ + PICK(bl2, bl2, br2, br2); /* ▄ k=1 bg=bl fg=br */ + PICK(bl2, bl2, tl2, tl2); /* ▄ k=1 bg=bl fg=tl */ + PICK(bl2, bl2, tr2, tr2); /* ▄ k=1 bg=bl fg=tr */ + PICK(br2, br2, bl2, bl2); /* ▄ k=1 bg=br fg=bl */ + PICK(tl2, tl2, bl2, bl2); /* ▄ k=1 bg=tl fg=bl */ + PICK(tr2, tr2, bl2, bl2); /* ▄ k=1 bg=tr fg=bl */ + PICK(bl2, br2, bl2, br2); /* ▌ k=2 bg=br fg=bl */ + PICK(bl2, tl2, bl2, tl2); /* ▌ k=2 bg=tl fg=bl */ + PICK(bl2, tr2, bl2, tr2); /* ▌ k=2 bg=tr fg=bl */ + PICK(br2, bl2, br2, bl2); /* ▌ k=2 bg=bl fg=br */ + PICK(br2, br2, br2, br2); /* k=0 bg=br fg=NULL */ + PICK(br2, br2, tl2, tl2); /* ▄ k=1 bg=br fg=tl */ + PICK(br2, br2, tr2, tr2); /* ▄ k=1 bg=br fg=tr */ + PICK(br2, tl2, br2, tl2); /* ▌ k=2 bg=tl fg=br */ + PICK(br2, tr2, br2, tr2); /* ▌ k=2 bg=tr fg=br */ + PICK(tl2, bl2, tl2, bl2); /* ▌ k=2 bg=bl fg=tl */ + PICK(tl2, br2, tl2, br2); /* ▌ k=2 bg=br fg=tl */ + PICK(tl2, tl2, br2, br2); /* ▄ k=1 bg=tl fg=br */ + PICK(tl2, tl2, tl2, tl2); /* k=0 bg=tl fg=NULL */ + PICK(tl2, tl2, tr2, tr2); /* ▄ k=1 bg=tl fg=tr */ + PICK(tl2, tr2, tl2, tr2); /* ▌ k=2 bg=tr fg=tl */ + PICK(tr2, bl2, tr2, bl2); /* ▌ k=2 bg=bl fg=tr */ + PICK(tr2, br2, tr2, br2); /* ▌ k=2 bg=br fg=tr */ + PICK(tr2, tl2, tr2, tl2); /* ▌ k=2 bg=tl fg=tr */ + PICK(tr2, tr2, br2, br2); /* ▄ k=1 bg=tr fg=br */ + PICK(tr2, tr2, tl2, tl2); /* ▄ k=1 bg=tr fg=tl */ + PICK(tr2, tr2, tr2, tr2); /* k=0 bg=tr fg=NULL */ +#undef PICK + return p; +} + +static struct Pick pickblock_unicode_ansi(struct TtyRgb tl, struct TtyRgb tr, + struct TtyRgb bl, struct TtyRgb br) { + struct TtyRgb tl2 = getquant(tl); + struct TtyRgb tr2 = getquant(tr); + struct TtyRgb bl2 = getquant(bl); + struct TtyRgb br2 = getquant(br); + unsigned i, p1, p2; + uint16_t picks1[96] aligned(32); + uint16_t picks2[32] aligned(32); + memset(picks1, 0x79, sizeof(picks1)); + memset(picks2, 0x79, sizeof(picks2)); + pickunicode(picks1, tl, tr, bl, br, tl2, tr2, bl2, br2); + mixblock(picks2, tl, tr, bl, br, tl2, tr2, bl2, br2); + p1 = windex(picks1, 96); + p2 = windex(picks2, 32); + return picks1[p1] <= picks2[p2] ? kPicksUnicode[p1] : kPicksMixBlock[p2]; +} + +static struct Pick pickblock_unicode_true(struct TtyRgb tl, struct TtyRgb tr, + struct TtyRgb bl, struct TtyRgb br) { + unsigned i; + uint16_t picks[96] aligned(32); + memset(picks, 0x79, sizeof(picks)); + pickunicode(picks, tl, tr, bl, br, tl, tr, bl, br); + i = windex(picks, 96); + if (i >= 88) { + unsigned j; + fprintf(stderr, "uint16_t picks[96] = {"); + for (j = 0; j < 96; ++j) { + fprintf(stderr, "%3d,", picks[j]); + } + fprintf(stderr, "}\n"); + } + CHECK_LT(i, 88); + return kPicksUnicode[i]; +} + +static struct Pick pickblock_cp437_ansi(struct TtyRgb tl, struct TtyRgb tr, + struct TtyRgb bl, struct TtyRgb br) { + struct TtyRgb tl2 = getquant(tl); + struct TtyRgb tr2 = getquant(tr); + struct TtyRgb bl2 = getquant(bl); + struct TtyRgb br2 = getquant(br); + unsigned i, p1, p2; + uint16_t picks1[32] aligned(32); + uint16_t picks2[32] aligned(32); + memset(picks1, 0x79, sizeof(picks1)); + memset(picks2, 0x79, sizeof(picks2)); + pickcp437(picks1, tl, tr, bl, br, tl2, tr2, bl2, br2); + mixblock(picks2, tl, tr, bl, br, tl2, tr2, bl2, br2); + p1 = windex(picks1, 32); + p2 = windex(picks2, 32); + return picks1[p1] <= picks2[p2] ? kPicksCp437[p1] : kPicksMixBlock[p2]; +} + +static struct Pick pickblock_cp437_true(struct TtyRgb tl, struct TtyRgb tr, + struct TtyRgb bl, struct TtyRgb br) { + unsigned i; + uint16_t picks[32] aligned(32); + memset(picks, 0x79, sizeof(picks)); + pickcp437(picks, tl, tr, bl, br, tl, tr, bl, br); + return kPicksCp437[windex(picks, 32)]; +} + +static char *copyglyph(char *v, struct Glyph glyph) { + memcpy(v, &glyph, 4); + return v + glyph.len; +} + +static char *copyblock(char *v, const struct TtyRgb chunk[hasatleast 4], + struct Pick pick, struct TtyRgb *bg, struct TtyRgb *fg, + struct Glyph *glyph) { + unsigned i; + CHECK_LT(pick.bg, 4); + if (pick.fg != 0xff) CHECK_LT(pick.fg, 4); + i = 0; + if (pick.fg == 0xff) { + if (!ttyeq(*bg, chunk[pick.bg])) { + if (ttyeq(*fg, chunk[pick.bg])) { + if (memcmp(glyph, &kGlyphs[1][0], sizeof(*glyph)) == 0) { + v = setbg(v, (*bg = *fg)); + } else { + i = 1; + } + } else { + v = setbg(v, (*bg = chunk[pick.bg])); + } + } + } else if (ttyeq(chunk[pick.bg], chunk[pick.fg])) { + pick.k = 0; + if (!ttyeq(*bg, chunk[pick.bg])) { + if (ttyeq(*fg, chunk[pick.bg])) { + if (memcmp(glyph, &kGlyphs[1][0], sizeof(*glyph)) == 0) { + v = setbg(v, (*bg = *fg)); + } else { + i = 1; + } + } else { + v = setbg(v, (*bg = chunk[pick.bg])); + } + } + } else if (!ttyeq(*fg, chunk[pick.fg])) { + if (!ttyeq(*bg, chunk[pick.bg])) { + if (ttyeq(*fg, chunk[pick.bg]) && ttyeq(*bg, chunk[pick.fg])) { + if (pick.k == 0 && memcmp(glyph, &kGlyphs[1][0], sizeof(*glyph)) == 0) { + v = setbg(v, (*bg = *fg)); + } else { + i = 1; + } + } else { + v = setbgfg(v, (*bg = chunk[pick.bg]), (*fg = chunk[pick.fg])); + } + } else { + v = setfg(v, (*fg = chunk[pick.fg])); + } + } else if (!ttyeq(*bg, chunk[pick.bg])) { + v = setbg(v, (*bg = chunk[pick.bg])); + } + return copyglyph(v, (*glyph = kGlyphs[i][pick.k])); +} + +static bool chunkeq(struct TtyRgb c[hasatleast 4], + struct TtyRgb c2[hasatleast 4]) { + return ttyeq(c[TL], c[TR]) && ttyeq(c[BL], c[BR]) && ttyeq(c2[TL], c2[TR]) && + ttyeq(c2[BL], c2[BR]); +} + +static struct TtyRgb *copychunk(struct TtyRgb chunk[hasatleast 4], + const struct TtyRgb *c, size_t n) { + chunk[TL] = c[0 + 0]; + chunk[TR] = c[0 + 1]; + chunk[BL] = c[n + 0]; + chunk[BR] = c[n + 1]; + return chunk; +} + +static noinline char *copyrun(char *v, size_t n, + struct TtyRgb lastchunk[hasatleast 4], + const struct TtyRgb **c, size_t *x, + struct TtyRgb *bg, struct TtyRgb *fg, + struct Glyph *glyph) { + struct TtyRgb chunk[4]; + if (memcmp(glyph, &kGlyphs[1][0], sizeof(*glyph)) == 0) { + if (!ttyeq(*bg, *fg)) { + v = setbg(v, (*bg = *fg)); + } + *glyph = kGlyphs[0][0]; + } + do { + v = copyglyph(v, *glyph); + *x += 2; + *c += 2; + if (*x >= n) break; + copychunk(chunk, *c, n); + } while (chunkeq(chunk, lastchunk)); + *x -= 2; + *c -= 2; + return v; +} + +/** + * Maps 2×2 pixel chunks onto ANSI UNICODE cells. + * @note h/t Nick Black for his quadrant blitting work on notcurses + */ +char *ttyraster(char *v, const struct TtyRgb *c, size_t yn, size_t n, + struct TtyRgb bg, struct TtyRgb fg) { + unsigned y, x; + struct Pick p; + struct Glyph glyph; + struct TtyRgb chun[4], lastchunk[4]; + for (y = 0; y < yn; y += 2, c += n) { + if (y) *v++ = '\r', *v++ = '\n'; + for (x = 0; x < n; x += 2, c += 2) { + copychunk(chun, c, n); + if (ttyquant()->alg == kTtyQuantTrue) { + if (ttyquant()->blocks == kTtyBlocksCp437) { + p = pickblock_cp437_true(chun[TL], chun[TR], chun[BL], chun[BR]); + } else { + p = pickblock_unicode_true(chun[TL], chun[TR], chun[BL], chun[BR]); + } + } else { + if (ttyquant()->blocks == kTtyBlocksCp437) { + p = pickblock_cp437_ansi(chun[TL], chun[TR], chun[BL], chun[BR]); + } else { + p = pickblock_unicode_ansi(chun[TL], chun[TR], chun[BL], chun[BR]); + } + } + v = copyblock(v, chun, p, &bg, &fg, &glyph); + memcpy(lastchunk, chun, sizeof(chun)); + } + } + *v = '\0'; + return v; +} diff --git a/dsp/tty/ttyraw.c b/dsp/tty/ttyraw.c new file mode 100644 index 00000000..a285cbe9 --- /dev/null +++ b/dsp/tty/ttyraw.c @@ -0,0 +1,155 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" +#include "libc/assert.h" +#include "libc/calls/calls.h" +#include "libc/calls/sigbits.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/calls/struct/siginfo.h" +#include "libc/calls/termios.h" +#include "libc/calls/typedef/sigaction_f.h" +#include "libc/calls/ucontext.h" +#include "libc/log/log.h" +#include "libc/macros.h" +#include "libc/runtime/gc.h" +#include "libc/runtime/rbx.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/sa.h" +#include "libc/sysv/consts/sig.h" +#include "libc/sysv/errfuns.h" +#include "libc/x/x.h" + +#define FD STDOUT_FILENO + +static struct TtyRaw { + bool setup; + bool noreentry; + bool initialized; + enum TtyRawFlags flags; + sigaction_f next[10]; + unsigned char sigs[10]; + struct termios old; +} g_ttyraw; + +static textstartup int ttyraw_setup(void) { + if (isatty(FD) && + ttyconfig(FD, ttysetrawmode, g_ttyraw.flags, &g_ttyraw.old) != -1) { + return 0; + } else { + return -1; + } +} + +static textstartup int ttyraw_enable(void) { + int rc; + g_ttyraw.setup = (rc = ttyraw_setup()) != -1 || g_ttyraw.setup; + return rc; +} + +static textstartup void ttyraw_hidecursor(void) { + if (!g_ttyraw.setup) return; + if (g_ttyraw.flags & kTtyCursor) return; + ttyhidecursor(FD); +} + +static textexit int ttyraw_disable(void) { + if (!g_ttyraw.setup) return 0; + ttyshowcursor(FD); + return ttyrestore(FD, &g_ttyraw.old); +} + +static textexit void ttyraw_onexit(void) { + ttyraw_disable(); +} + +static relegated void ttyraw_onsig(int sig, struct siginfo *info, + struct ucontext *ctx) { + size_t i; + if (g_ttyraw.noreentry) _Exit(128 + sig); + g_ttyraw.noreentry = true; + if (g_ttyraw.flags != -1) { + if (sig == SIGCONT) { + ttyraw_enable(); + } else { + ttyraw_disable(); + } + } + for (i = 0; i < ARRAYLEN(g_ttyraw.sigs); ++i) { + if (g_ttyraw.sigs[i] == sig) { + if (g_ttyraw.next[i] != SIG_IGN) { + if (g_ttyraw.next[i] != SIG_DFL) { + g_ttyraw.next[i](sig, info, ctx); + } else if (sig != SIGCONT) { + _Exit(128 + sig); + } + } + break; + } + } + g_ttyraw.noreentry = false; +} + +static textstartup void ttyraw_initsig(int sig, unsigned flags, unsigned mask) { + static unsigned i; + struct sigaction old; + g_ttyraw.next[i] = xsigaction(sig, ttyraw_onsig, flags, mask, &old) != -1 + ? old.sa_sigaction + : SIG_DFL; + g_ttyraw.sigs[i++] = sig; +} + +static textstartup void ttyraw_init(void) { + unsigned crashmask = ~(SIGILL | SIGBUS | SIGSEGV | SIGABRT); + ttyraw_initsig(SIGILL, SA_SIGINFO | SA_NODEFER | SA_ONSTACK, crashmask); + ttyraw_initsig(SIGSEGV, SA_SIGINFO | SA_NODEFER | SA_ONSTACK, crashmask); + ttyraw_initsig(SIGBUS, SA_SIGINFO | SA_NODEFER | SA_ONSTACK, crashmask); + ttyraw_initsig(SIGABRT, SA_SIGINFO | SA_NODEFER, crashmask); + ttyraw_initsig(SIGFPE, SA_SIGINFO | SA_RESTART, crashmask); + ttyraw_initsig(SIGTRAP, SA_SIGINFO | SA_RESTART, crashmask); + ttyraw_initsig(SIGHUP, SA_SIGINFO | SA_RESTART, crashmask); + ttyraw_initsig(SIGINT, SA_SIGINFO | SA_RESTART, crashmask); + ttyraw_initsig(SIGQUIT, SA_SIGINFO | SA_RESTART, crashmask); + ttyraw_initsig(SIGCONT, SA_SIGINFO | SA_RESTART, crashmask); + atexit(ttyraw_onexit); +} + +/** + * Sets raw mode, safely, the easy way. + * + * This should be called after your signal handlers have been installed. + */ +textstartup int ttyraw(enum TtyRawFlags flags) { + int rc; + if ((g_ttyraw.flags = flags) != -1) { + if (!g_ttyraw.initialized) { + g_ttyraw.initialized = true; + ttyraw_init(); + } + if ((rc = ttyraw_enable()) != -1) { + ttyraw_hidecursor(); + } + } else { + rc = ttyraw_disable(); + } + cancolor(); + return rc; +} diff --git a/dsp/tty/ttyrgb.h b/dsp/tty/ttyrgb.h new file mode 100644 index 00000000..cc1d713d --- /dev/null +++ b/dsp/tty/ttyrgb.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_DSP_TTY_RGB_H_ +#define COSMOPOLITAN_DSP_TTY_RGB_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct TtyRgb { + uint8_t r, g, b, xt; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_TTY_RGB_H_ */ diff --git a/dsp/tty/windex-avx2.S b/dsp/tty/windex-avx2.S new file mode 100644 index 00000000..215e2528 --- /dev/null +++ b/dsp/tty/windex-avx2.S @@ -0,0 +1,72 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns index of minimum uint16 in array. +/ +/ @param rdi points to nonempty array +/ @param rsi is item count divisible by 16 +/ @note needs avx2 (haswell+) +windex$avx2: + push %rbp + mov %rsp,%rbp + .profilable + and $-32,%rsp + sub $32,%rsp + vmovdqa (%rdi),%ymm1 + vmovdqa .Lidx(%rip),%ymm3 + vmovdqa .Linc(%rip),%ymm5 + cmp $16,%esi + jbe 2f + vmovdqa %ymm3,%ymm0 + mov $16,%eax +3: vpaddw %ymm0,%ymm5,%ymm0 + mov %eax,%edx + vmovdqa (%rdi,%rdx,2),%ymm2 + vpcmpgtw %ymm2,%ymm1,%ymm4 + vpblendvb %ymm4,%ymm0,%ymm3,%ymm3 + vpminsw %ymm1,%ymm2,%ymm1 + add $16,%eax + cmp %eax,%esi + ja 3b +2: vphminposuw %xmm1,%xmm0 + vextracti128 $0x1,%ymm1,%xmm1 + vphminposuw %xmm1,%xmm1 + vmovdqa %ymm3,(%rsp) + vmovq %xmm0,%rdx + vmovq %xmm1,%rax + cmp %dx,%ax + jbe 4f + sar $16,%rdx + movzwl %dx,%edx + movzwl (%rsp,%rdx,2),%eax + jmp 5f +4: sar $16,%rax + movzwl %ax,%eax + movzwl 16(%rsp,%rax,2),%eax +5: vzeroupper + leave + ret + .endfn windex$avx2,globl + + .rodata.cst32 +.Lidx: .short 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 +.Linc: .value 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16 diff --git a/dsp/tty/windex-k8.c b/dsp/tty/windex-k8.c new file mode 100644 index 00000000..bae65651 --- /dev/null +++ b/dsp/tty/windex-k8.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" +#include "libc/assert.h" + +unsigned windex$k8(short *a, size_t n) { + unsigned short min, res, i; + res = 0; + min = a[0]; + for (i = 1; i < n; ++i) { + if (a[i] < min) { + min = a[i]; + res = i; + } + } + return res; +} diff --git a/dsp/tty/windex-sse4.S b/dsp/tty/windex-sse4.S new file mode 100644 index 00000000..b90f41be --- /dev/null +++ b/dsp/tty/windex-sse4.S @@ -0,0 +1,62 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns index of minimum positive int16 in array. +/ +/ @param rdi points to nonempty array +/ @param esi is 16-byte aligned 8+ / 8 multiple array item count +/ @note needs sse4 (nehalem+) +windex$sse4: + push %rbp + mov %rsp,%rbp + .profilable + mov $8,%eax + sub $32,%rsp + movdqa (%rdi),%xmm2 + movdqa .Lidx(%rip),%xmm1 + movdqa .Linc(%rip),%xmm6 + movdqa %xmm1,%xmm3 +0: cmp %eax,%esi + je 1f + add $8,%eax + movdqa -16(%rdi,%rax,2),%xmm4 + movdqa %xmm2,%xmm7 + movdqa %xmm3,%xmm5 + paddw %xmm6,%xmm5 + movdqa %xmm5,%xmm3 + pcmpgtw %xmm4,%xmm7 + pminsw %xmm4,%xmm2 + movdqa %xmm7,%xmm0 + pblendvb %xmm0,%xmm5,%xmm1 + jmp 0b +1: phminposuw %xmm2,%xmm0 + movd %xmm0,%eax + movdqa %xmm1,-32(%rbp) + shr $16,%eax + movzwl -32(%rbp,%rax,2),%eax + leave + ret + .endfn windex$sse4,globl + + .rodata.cst16 +.Lidx: .short 0,1,2,3,4,5,6,7 +.Linc: .value 8,8,8,8,8,8,8,8 diff --git a/dsp/tty/windex.S b/dsp/tty/windex.S new file mode 100644 index 00000000..004f98f2 --- /dev/null +++ b/dsp/tty/windex.S @@ -0,0 +1,43 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/nexgen32e/x86feature.h" +#include "libc/macros.h" +.yoink __FILE__ + +/ Dispatches to fastest windex() implementation. + .initbss 300,_init_windex +windex: .quad 0 + .endobj windex,globl + .previous + + .init.start 300,_init_windex + ezlea windex$avx2,ax +#if !X86_NEED(AVX2) + ezlea windex$sse4,dx + testb X86_HAVE(AVX2)+kCpuids(%rip) + cmovz %rdx,%rax +#endif /* AVX */ +#if !X86_NEED(SSE4_2) + ezlea windex$k8,dx + testb X86_HAVE(SSE4_2)+kCpuids(%rip) + cmovz %rdx,%rax +#endif /* SSE4 */ + stosq + .init.end 300,_init_windex diff --git a/dsp/tty/windex.h b/dsp/tty/windex.h new file mode 100644 index 00000000..95b26cd3 --- /dev/null +++ b/dsp/tty/windex.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_DSP_TTY_WINDEX_H_ +#define COSMOPOLITAN_DSP_TTY_WINDEX_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +extern unsigned (*const windex)(uint16_t *, size_t); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_DSP_TTY_WINDEX_H_ */ diff --git a/dsp/tty/write.c b/dsp/tty/write.c new file mode 100644 index 00000000..7e356ddb --- /dev/null +++ b/dsp/tty/write.c @@ -0,0 +1,59 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" +#include "libc/calls/calls.h" +#include "libc/calls/termios.h" +#include "libc/errno.h" +#include "libc/sock/sock.h" +#include "libc/sysv/consts/poll.h" +#include "libc/sysv/consts/termios.h" + +/** + * Sends data to teletypewriter the pain-free way. + * + * This function blocks forever until the full amount is transmitted, + * regardless of whether or not the character device is in non-blocking + * mode, regardless of whether or not it's interrupted by a signal. It + * can still be escaped by longjmp'ing out of a signal handler. + * + * @return 0 on success, or -1 w/ errno + */ +int ttywrite(int fd, const void *data, size_t size) { + char *p; + ssize_t rc; + size_t wrote, n; + p = data; + n = size; + do { + TryAgain: + if ((rc = write(fd, p, n)) != -1) { + wrote = rc; + p += wrote; + n -= wrote; + } else if (errno == EINTR) { + goto TryAgain; + } else if (errno == EAGAIN) { + poll((struct pollfd[]){{fd, POLLOUT}}, 1, -1); + } else { + return -1; + } + } while (n); + return 0; +} diff --git a/examples/backtrace.c b/examples/backtrace.c new file mode 100644 index 00000000..66aae016 --- /dev/null +++ b/examples/backtrace.c @@ -0,0 +1,61 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/calls/calls.h" +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/runtime/gc.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/symbols.h" +#include "libc/stdio/stdio.h" + +/* + + Your executables will try to find the addr2line tool, which is needed + to decrypt gcc debug information, enabling backtraces like this: + + 0x0000000000403a7a: Hello at examples/backtrace.c:31 + 0x0000000000403ac3: World at examples/backtrace.c:38 + 0x0000000000401608: main at examples/backtrace.c:42 + 0x0000000000401379: _start at libc/crt/crt.S:61 + + If that doesn't work, then your αcτµαlly pδrταblε εxεcµταblε will use + its own builtin fallback solution: + + 0000ac2fa7e0 000000403a9b Hello+0x49 + 0000ac2fa7f0 000000403ac4 World+0x22 + 0000ac2fa800 000000401609 main+0x7 + 0000ac2fa810 00000040137a _start+0x63 + + This is guaranteed to work if the .com.dbg file can be found. + Otherwise it'll print numbers: + + 0000268a8390 000000403a90 (null)+0x403a8f + 0000268a83a0 000000403aef (null)+0x403aee + 0000268a83b0 0000004015fe (null)+0x4015fd + 0000268a83c0 00000040137a (null)+0x401379 + +*/ + +void hello(void) { + gc(malloc(1)); + backtrace(stdout); + setenv("ADDR2LINE", "", true); + backtrace(stdout); +} + +void world(void) { + gc(malloc(1)); + hello(); +} + +int main(int argc, char *argv[]) { + world(); + return 0; +} diff --git a/examples/bigmem.c b/examples/bigmem.c new file mode 100644 index 00000000..fd58835c --- /dev/null +++ b/examples/bigmem.c @@ -0,0 +1,101 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/calls/calls.h" +#include "libc/calls/hefty/spawn.h" +#include "libc/calls/struct/stat.h" +#include "libc/log/check.h" +#include "libc/macros.h" +#include "libc/runtime/gc.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/auxv.h" +#include "libc/sysv/consts/clock.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/madv.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/prot.h" +#include "libc/time/time.h" +#include "libc/x/x.h" + +/** + * @fileoverview Overcommit tutorial. + * You can allocate memory like a central banker prints money. + */ + +/* #define kHugeAmount (10LU * 1024LU * 1024LU * 1024LU * 1024LU) */ +#define kHugeAmount (1LU * 1024LU * 1024LU * 1024LU) + +int copyfile2(const char *frompath, const char *topath, bool dontoverwrite) { + struct stat st; + ssize_t transferred; + int rc, fromfd, tofd; + int64_t inoffset, outoffset; + rc = -1; + if ((fromfd = open(frompath, O_RDONLY | O_DIRECT, 0)) != -1) { + if (fstat(fromfd, &st) != -1 && + (tofd = + open(topath, + O_WRONLY | O_CREAT | O_DIRECT | (dontoverwrite ? O_EXCL : 0), + st.st_mode & 0777)) != -1) { + inoffset = 0; + outoffset = 0; + while (st.st_size && + (transferred = copy_file_range(fromfd, &inoffset, tofd, &outoffset, + st.st_size, 0)) != -1) { + st.st_size -= transferred; + } + if (!st.st_size) rc = 0; + rc |= close(tofd); + } + rc |= close(fromfd); + } + return rc; +} + +int main(int argc, char *argv[]) { + int fd, pid; + size_t size; + long double t1, t2; + const char *core, *core2, *core3; + volatile unsigned char *mem; + size = ROUNDUP(kHugeAmount, PAGESIZE); + core = gc(xasprintf("%s.%s", getauxval(AT_EXECFN), "core")); + core2 = gc(xasprintf("%s.%s", getauxval(AT_EXECFN), "core2")); + core3 = gc(xasprintf("%s.%s", getauxval(AT_EXECFN), "core3")); + CHECK_NE(-1, (fd = open(core, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0600))); + CHECK_NE(-1, ftruncate(fd, size)); + CHECK_NE(MAP_FAILED, + (mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0))); + strcpy(&mem[0], "hello\n\n\n\n\n\n\n\n\n\n"); + strcpy(&mem[kHugeAmount / 2], "hello\n\n\n\n\n\n\n\n\n\n"); + CHECK_NE(-1, munmap(mem, size)); + CHECK_NE(-1, + (pid = spawnve( + 0, (int[3]){STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO}, + "o/examples/stat.com", + (char *const[]){"o/examples/stat.com", core, NULL}, environ))); + CHECK_NE(-1, waitpid(pid, NULL, 0)); + CHECK_NE(-1, close(fd)); + + t1 = dtime(CLOCK_REALTIME); + CHECK_NE(-1, copyfile(core, core2, false)); + t2 = dtime(CLOCK_REALTIME); + printf("%.6Lf\n", t2 - t1); + + t1 = dtime(CLOCK_REALTIME); + CHECK_NE(-1, copyfile2(core, core3, false)); + t2 = dtime(CLOCK_REALTIME); + printf("%.6Lf\n", t2 - t1); + + /* CHECK_NE(-1, unlink(core)); */ + return 0; +} diff --git a/examples/breakpoint.c b/examples/breakpoint.c new file mode 100644 index 00000000..8c772f79 --- /dev/null +++ b/examples/breakpoint.c @@ -0,0 +1,23 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/log/log.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" + +int main(int argc, char *argv[]) { + showcrashreports(); + if (IsDebuggerPresent(false)) { + printf("debugger found!\r\n"); + DebugBreak(); + return 0; + } + printf("try running: gdb %s\r\n", argv[0]); + return 1; +} diff --git a/examples/cplusplus.cc b/examples/cplusplus.cc new file mode 100644 index 00000000..a0885b14 --- /dev/null +++ b/examples/cplusplus.cc @@ -0,0 +1,48 @@ +/*-*-mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8-*-│ +│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" + +class Log { + public: + Log(); + ~Log(); + int *x(); + + private: + int *x_; +}; + +Log::Log() { x_ = new int[64]; } +Log::~Log() { delete x_; } +int *Log::x() { return x_; } + +class Log g_log; + +int main(int argc, char *argv[]) { + int *x = new int[64]; + memset(x, 0, 64 * sizeof(int)); + for (int i = 0; i < min(64, argc); ++i) g_log.x()[i] += argc; + printf("%p %d %d %d\n", (void *)(intptr_t)g_log.x(), g_log.x()[0], + g_log.x()[0], g_log.x()[0]); + delete x; + return 0; +} diff --git a/examples/crashreport.c b/examples/crashreport.c new file mode 100644 index 00000000..dc39c2b1 --- /dev/null +++ b/examples/crashreport.c @@ -0,0 +1,89 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/bits/pushpop.h" +#include "libc/calls/ucontext.h" +#include "libc/log/log.h" +#include "libc/math.h" +#include "libc/nt/enum/errormodeflags.h" +#include "libc/nt/signals.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" + +/** + * @fileoverview Demonstrates SEGFAULT via NULL pointer dereference. + * + * In MODE=dbg mode, UBSAN should catch this and display a backtrace. + * In most other modes, e.g. MODE=balanced, the oncrash.c sig handler + * will either launch GDB or display a very fancy report. + * + * make -j8 -O MODE=opt o/opt/examples/crashreportdemo.com + * o/opt/examples/crashreportdemo.com + * + * To prevent the GDB GUI from popping up: + * + * export GDB="" + * make -j8 -O MODE=opt o/opt/examples/crashreportdemo.com + * o/opt/examples/crashreportdemo.com + */ + +int boo; + +void boop(void); + +int main(int argc, char *argv[]) { + int64_t res; + showcrashreports(); + res = 0; + + asm volatile( + "mov\t$0x1111111111111111,%rax\n\t" + "mov\t$0x3333333333333333,%rcx\n\t" + "mov\t$0x4444444444444444,%rdx\n\t" + "mov\t$0x8888888888888888,%r8\n\t" + "mov\t$0x9999999999999999,%r9d\n\t" + "mov\t$0xaaaaaaaaaaaaaaaa,%r10d\n\t" + "mov\t$0xbbbbbbbbbbbbbbbb,%r11d\n\t" + "mov\t$0x0000000000000000,%rax\n\t" + "movd\t%rax,%xmm0\n\t" + "mov\t$0x1111111111111111,%rax\n\t" + "movd\t%rax,%xmm1\n\t" + "mov\t$0x2222222222222222,%rax\n\t" + "movd\t%rax,%xmm2\n\t" + "mov\t$0x3333333333333333,%rax\n\t" + "movd\t%rax,%xmm3\n\t" + "mov\t$0x4444444444444444,%rax\n\t" + "movd\t%rax,%xmm4\n\t" + "mov\t$0x5555555555555555,%rax\n\t" + "movd\t%rax,%xmm5\n\t" + "mov\t$0x6666666666666666,%rax\n\t" + "movd\t%rax,%xmm6\n\t" + "mov\t$0x7777777777777777,%rax\n\t" + "movd\t%rax,%xmm7\n\t" + "mov\t$0x8888888888888888,%rax\n\t" + "movd\t%rax,%xmm8\n\t" + "mov\t$0x9999999999999999,%rax\n\t" + "movd\t%rax,%xmm9\n\t" + "mov\t$0xaaaaaaaaaaaaaaaa,%rax\n\t" + "movd\t%rax,%xmm10\n\t" + "mov\t$0xbbbbbbbbbbbbbbbb,%rax\n\t" + "movd\t%rax,%xmm11\n\t" + "mov\t$0xcccccccccccccccc,%rax\n\t" + "movd\t%rax,%xmm12\n\t" + "mov\t$0xdddddddddddddddd,%rax\n\t" + "movd\t%rax,%xmm13\n\t" + "mov\t$0xeeeeeeeeeeeeeeee,%rax\n\t" + "movd\t%rax,%xmm14\n\t" + "mov\t$0xffffffffffffffff,%rax\n\t" + "movd\t%rax,%xmm15\n\t" + "fldlg2\n\t"); + + res = *(int *)(intptr_t)boo / boo; + return res; +} diff --git a/examples/ctrlc.c b/examples/ctrlc.c new file mode 100644 index 00000000..2bbf4290 --- /dev/null +++ b/examples/ctrlc.c @@ -0,0 +1,66 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/calls/calls.h" +#include "libc/log/check.h" +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/runtime/gc.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/exit.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/sig.h" + +#define kTutorialMessage "This echos stdio until Ctrl+C is pressed.\n" +#define kVictoryMessage "\rGot Ctrl+C and longjmp() ran dtors (>'.')>\n" + +jmp_buf jb; + +void GotCtrlC(int sig) { + gclongjmp(jb, 1); + unreachable; +} + +size_t HowManyBytesOfHeapMemoryAreAllocated(void) { + return mallinfo().uordblks; +} + +void ReadAndPrintLinesLoop(void) { + ssize_t got; + unsigned char *buf; + buf = gc(malloc(BUFSIZ)); + CHECK_NE(0, HowManyBytesOfHeapMemoryAreAllocated()); + for (;;) { + CHECK_NE(-1, (got = read(STDIN_FILENO, buf, BUFSIZ))); + CHECK_EQ(got, write(STDOUT_FILENO, buf, got)); + } +} + +int main(int argc, char *argv[]) { + int rc; + rc = 0; + showcrashreports(); + if (cancolor()) { + CHECK_EQ(0 /* cosmo runtime doesn't link malloc */, + HowManyBytesOfHeapMemoryAreAllocated()); + puts("This echos stdio until Ctrl+C is pressed."); + if (!(rc = setjmp(jb))) { + CHECK_NE(SIG_ERR, signal(SIGINT, GotCtrlC)); + ReadAndPrintLinesLoop(); + unreachable; + } else { + --rc; + } + CHECK_EQ(0, HowManyBytesOfHeapMemoryAreAllocated()); + puts("\rGot Ctrl+C and longjmp() ran dtors (>'.')>"); + } + return rc; +} diff --git a/examples/date.c b/examples/date.c new file mode 100644 index 00000000..5b8c9f91 --- /dev/null +++ b/examples/date.c @@ -0,0 +1,21 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/runtime/gc.h" +#include "libc/stdio/stdio.h" +#include "libc/x/x.h" + +/** + * @fileoverview ISO-8601 international high-precision timestamp printer. + */ + +int main(int argc, char *argv[]) { + puts(gc(xiso8601ts(NULL))); + return 0; +} diff --git a/examples/dinlerp.c b/examples/dinlerp.c new file mode 100644 index 00000000..067f9383 --- /dev/null +++ b/examples/dinlerp.c @@ -0,0 +1,376 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "dsp/core/core.h" +#include "dsp/core/twixt8.h" +#include "dsp/scale/scale.h" +#include "dsp/tty/itoa8.h" +#include "dsp/tty/quant.h" +#include "libc/alg/arraylist2.h" +#include "libc/calls/calls.h" +#include "libc/calls/ioctl.h" +#include "libc/calls/struct/stat.h" +#include "libc/calls/struct/winsize.h" +#include "libc/limits.h" +#include "libc/log/check.h" +#include "libc/log/log.h" +#include "libc/macros.h" +#include "libc/math.h" +#include "libc/mem/mem.h" +#include "libc/runtime/gc.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/prot.h" +#include "libc/sysv/consts/termios.h" +#include "libc/x/x.h" +#include "third_party/stb/stb_image.h" + +/** + * Hat tips go out to Hornet, CRTC, DESiRE, Hans Petter Jansson, Guihua + * Cui, Ming Ronnier Luoand anyone else Mister Rogers would describe as + * the The Helpers Of This World who've helped us learn more about the + * cool yet exceedingly difficult things possible to do with graphics. + */ + +#define DIN99 1 +#define GAMMA 4.1 +#define GAMMA_A .05 +#define GAMMA_B 50. +#define GAMMA_C .055 +#define COLORSPACE_SRC kSrgbD65ToXyzD50 +#define COLORSPACE_TTY kSrgbD65ToXyzD50 + +#define SQR(X) ((X) * (X)) +#define DEG(X) ((X)*M_PI / 180) + +const double kXyzKappa = 24389 / 27.; +const double kXyzEpsilon = 216 / 24389.; + +const double kSrgbD65ToXyzD50[3][3] = { + {.4360747, .3850649, .1430804}, + {.2225045, .7168786, .0606169}, + {.0139322, .0971045, .7141733}, +}; + +const double kCieRgbEToXyz[3][3] = { + {.4887180, .3106803, .2006017}, + {.1762044, .8129847, .0108109}, + {.0000000, .0102048, .9897952}, +}; + +const unsigned char kShadePct[] = {0300, 0200, 0100}; +const unsigned short kShadeRune[] = {u'▓', u'▒', u'░'}; + +const unsigned char kAnsiTango[16][3] = { + {46, 52, 54}, {204, 0, 0}, {78, 154, 6}, {196, 160, 0}, + {52, 101, 164}, {117, 80, 123}, {6, 152, 154}, {211, 215, 207}, + {85, 87, 83}, {239, 41, 41}, {138, 226, 52}, {252, 233, 79}, + {114, 159, 207}, {173, 127, 168}, {52, 226, 226}, {238, 238, 236}, +}; + +const unsigned char kCga[16][3] = { + {0, 0, 0}, {170, 0, 0}, {0, 170, 0}, {170, 85, 0}, + {0, 0, 170}, {170, 0, 170}, {0, 170, 170}, {170, 170, 170}, + {85, 85, 85}, {255, 85, 85}, {85, 255, 85}, {255, 255, 85}, + {85, 85, 255}, {255, 85, 255}, {85, 255, 255}, {255, 255, 255}, +}; + +struct Blends { + size_t i, n; + struct Blend { + unsigned char color[4]; + unsigned char bg, fg; + unsigned short rune; + } * p; +} blends; + +static double Gamma(double x) { + if (x < GAMMA_A) return x / GAMMA_B; + return pow(1 / (1 + GAMMA_C) * (x + GAMMA_C), GAMMA); +} + +static void *LoadRgb(double rgb[3], const unsigned char pix[3]) { + rgb[0] = Gamma(1. / 255 * pix[0]); + rgb[1] = Gamma(1. / 255 * pix[1]); + rgb[2] = Gamma(1. / 255 * pix[2]); + return rgb; +} + +static double Lab(double x) { + return x > kXyzEpsilon ? cbrtf(x) : (kXyzKappa * x + 16) / 116; +} + +static void XyzToLab(double lab[3], const double d50xyz[3]) { + double Y, L, a, b; + Y = Lab(d50xyz[1]); + L = 116 * Y - 16; + a = 500 * (Lab(d50xyz[0]) - Y); + b = 200 * (Y - Lab(d50xyz[2])); + lab[0] = L, lab[1] = a, lab[2] = b; +} + +static void XyzToDin99d(unsigned char din99d[3], const double d50xyz[3]) { + double e, f, G, C, h, xyz[3], lab[3]; + memcpy(xyz, d50xyz, sizeof(xyz)); + xyz[0] = 1.12f * xyz[0] - .12f * xyz[2]; + XyzToLab(lab, xyz); + e = (+lab[1] * cosf(DEG(50)) + lab[2] * sinf(DEG(50))); + f = (-lab[1] * sinf(DEG(50)) + lab[2] + cosf(DEG(50))) * 1.14; + G = sqrtf(SQR(e) + SQR(f)); + C = logf(1 + .06 * G) * 22.5f; + h = atan2f(f, e) + DEG(50); + h = fmodf(h, DEG(360)); + if (h < 0) h += DEG(360); + din99d[0] = MIN(255, MAX(0, 325.22f * logf(1 + .0036 * lab[0]) * 2.5f)); + din99d[1] = MIN(255, MAX(0, C * cos(h) * 2.5f + 128)); + din99d[2] = MIN(255, MAX(0, C * sin(h) * 2.5f + 128)); +} + +static void AddColor(int bg, int fg, int rune, int r, int g, int b, int x) { + int i; + if (blends.i) { + for (i = blends.i; --i;) { + if (blends.p[i].color[0] == r && blends.p[i].color[1] == g && + blends.p[i].color[2] == b) { + return; + } + } + } + CHECK_NE( + -1, + APPEND(&blends.p, &blends.i, &blends.n, + (&(struct Blend){ + .bg = bg, .fg = fg, .rune = rune, .color = {r, g, b, x}}))); +} + +static void AddBlend(int bgxterm, int fgxterm, int rune, int shade, + const unsigned char bgrgb[4], + const unsigned char fgrgb[4]) { + AddColor(bgxterm, fgxterm, rune, twixt8(bgrgb[0], fgrgb[0], shade), + twixt8(bgrgb[1], fgrgb[1], shade), twixt8(bgrgb[2], fgrgb[2], shade), + 0); +} + +static void MakeBlends(const unsigned char palette[16][3]) { + int r, i, j, k; + double rgb[3], xyz[3]; + unsigned char tab[256][4]; + unsigned char cube[6] = {0, 0137, 0207, 0257, 0327, 0377}; + unsigned char seqs[2][2] = {{16, 255}}; + for (i = 0; i < 16; ++i) { + tab[i][0] = palette[i][0]; + tab[i][1] = palette[i][1]; + tab[i][2] = palette[i][2]; + tab[i][3] = i; + } + for (i = 16; i < 232; ++i) { + tab[i][0] = cube[((i - 020) / 044) % 6]; + tab[i][1] = cube[((i - 020) / 6) % 6]; + tab[i][2] = cube[(i - 020) % 6]; + tab[i][3] = i; + } + for (i = 232; i < 256; ++i) { + tab[i][0] = 8 + (i - 232) * 10; + tab[i][1] = 8 + (i - 232) * 10; + tab[i][2] = 8 + (i - 232) * 10; + tab[i][3] = i; + } +#if DIN99 + for (i = 0; i < 256; ++i) { + LoadRgb(rgb, tab[i]); + vmatmul3(xyz, rgb, COLORSPACE_TTY); + XyzToDin99d(tab[i], xyz); + } +#endif + for (r = 0; r < ARRAYLEN(seqs); ++r) { + for (i = seqs[r][0]; i <= seqs[r][1]; ++i) { + for (j = seqs[r][0]; j <= seqs[r][1]; ++j) { + if (i == j) { + AddColor(i, 0, 0, tab[i][0], tab[i][1], tab[i][2], 0); + } else { + for (k = 0; k < ARRAYLEN(kShadeRune); ++k) { + AddBlend(i, j, kShadeRune[k], kShadePct[k], tab[i], tab[j]); + AddBlend(j, i, kShadeRune[k], kShadePct[k], tab[j], tab[i]); + } + } + } + } + } +} + +static int PickColor(unsigned char color[3]) { + int i, best, least, dist; + best = -1; + least = INT_MAX; + for (i = 0; i < blends.i; ++i) { + dist = SQR(blends.p[i].color[0] - color[0]) + + SQR(blends.p[i].color[1] - color[1]) + + SQR(blends.p[i].color[2] - color[2]); + if (dist < least) { + least = dist; + best = i; + } + } + return best; +} + +static void SetBg(int x) { + if (0 <= x && x < 16) { + if (x < 8) { + x += 40; + } else { + x -= 8; + x *= 100; + } + printf("\e[%dm", x); + } else { + /* assert(false); */ + printf("\e[48;5;%dm", x); + } +} + +static void SetFg(int x) { + if (0 <= x && x < 16) { + if (x < 8) { + x += 30; + } else { + x -= 8; + x *= 90; + } + printf("\e[%dm", x); + } else { + /* assert(false); */ + printf("\e[38;5;%dm", x); + } +} + +static void PrintImage(long yn, long xn, unsigned char src[4][yn][xn]) { + int y, x, c; + double rgb[3], xyz[3]; + unsigned char din99d[3]; + for (y = 0; y < yn; ++y) { + printf("\n"); + for (x = 0; x < xn; ++x) { + din99d[0] = src[0][y][x]; + din99d[1] = src[1][y][x]; + din99d[2] = src[2][y][x]; +#if DIN99 + LoadRgb(rgb, din99d); + vmatmul3(xyz, rgb, COLORSPACE_SRC); + XyzToDin99d(din99d, xyz); +#endif + c = PickColor(din99d); + if (blends.p[c].rune) { + SetBg(blends.p[c].bg); + SetFg(blends.p[c].fg); + printf("%hc", blends.p[c].rune); + } else { + SetBg(blends.p[c].bg); + printf(" "); + } + } + printf("\e[0m"); + } + printf("\r"); +} + +static void *Deinterlace(long dcn, long dyn, long dxn, + unsigned char dst[dcn][dyn][dxn], long syw, long sxw, + long scw, const unsigned char src[syw][sxw][scw], + long syn, long sxn, long sy0, long sx0, long sc0) { + long y, x, c; + for (y = 0; y < dyn; ++y) { + for (x = 0; x < dxn; ++x) { + for (c = 0; c < dcn; ++c) { + dst[c][y][x] = src[sy0 + y][sx0 + x][sc0 + c]; + } + } + } + return dst; +} + +static void GetTermSize(int out_rows[1], int out_cols[1]) { + struct winsize ws; + ws.ws_row = 24; + ws.ws_col = 80; + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) { + ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws); + } + out_rows[0] = ws.ws_row; + out_cols[0] = ws.ws_col; +} + +static void ProcessImage(long syn, long sxn, unsigned char img[syn][sxn][4]) { + int dyn, dxn; + double ry, rx; + GetTermSize(&dyn, &dxn); + ry = syn, rx = sxn; + ry /= dyn, rx /= dxn; + PrintImage( + dyn, dxn, + EzGyarados(4, dyn, dxn, gc(xmemalign(32, dyn * dxn * 4)), 4, syn, sxn, + Deinterlace(4, syn, sxn, gc(xmemalign(32, syn * sxn * 4)), syn, + sxn, 4, img, syn, sxn, 0, 0, 0), + 0, 4, dyn, dxn, syn, sxn, ry, rx, 0, 0)); +} + +static void WithImageFile(const char *path, + void fn(long yn, long xn, + unsigned char src[yn][xn][4])) { + struct stat st; + void *map, *data; + int fd, yn, xn, cn; + CHECK_NE(-1, (fd = open(path, O_RDONLY)), "%s", path); + CHECK_NE(-1, fstat(fd, &st)); + CHECK_GT(st.st_size, 0); + CHECK_LE(st.st_size, INT_MAX); + CHECK_NE(MAP_FAILED, + (map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0))); + CHECK_NOTNULL( + (data = stbi_load_from_memory(map, st.st_size, &xn, &yn, NULL, 4)), "%s", + path); + CHECK_NE(-1, munmap(map, st.st_size)); + CHECK_NE(-1, close(fd)); + fn(yn, xn, data); + free(data); +} + +static void PrintData(void) { + int i; + for (i = 0; i < blends.i; ++i) { + printf("%3d %3d %3d %3d %3d %d\n", blends.p[i].color[0], + blends.p[i].color[1], blends.p[i].color[2], blends.p[i].bg, + blends.p[i].fg, blends.p[i].rune); + } +} + +void *OpenRgbMap(const char *path) { + int fd; + void *map; + size_t size; + size = 256 * 256 * 256 * 3; + CHECK_NE(-1, (fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0644))); + CHECK_NE(-1, ftruncate(fd, size)); + CHECK_NE(MAP_FAILED, + (map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0))); + CHECK_NE(-1, close(fd)); + return map; +} + +int main(int argc, char *argv[]) { + int i; + MakeBlends(kCga); + for (i = 1; i < argc; ++i) { + WithImageFile(argv[i], ProcessImage); + } + return 0; +} diff --git a/examples/examples.mk b/examples/examples.mk new file mode 100644 index 00000000..458f13ab --- /dev/null +++ b/examples/examples.mk @@ -0,0 +1,118 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += EXAMPLES + +EXAMPLES_FILES := $(wildcard examples/*) +EXAMPLES_MAINS_S = $(filter %.S,$(EXAMPLES_FILES)) +EXAMPLES_MAINS_C = $(filter %.c,$(EXAMPLES_FILES)) +EXAMPLES_MAINS_CC = $(filter %.cc,$(EXAMPLES_FILES)) + +EXAMPLES_SRCS = \ + $(EXAMPLES_MAINS_S) \ + $(EXAMPLES_MAINS_C) \ + $(EXAMPLES_MAINS_CC) + +EXAMPLES_MAINS = \ + $(EXAMPLES_MAINS_S) \ + $(EXAMPLES_MAINS_C) \ + $(EXAMPLES_MAINS_CC) + +EXAMPLES_OBJS = \ + $(EXAMPLES_SRCS:%=o/$(MODE)/%.zip.o) \ + $(EXAMPLES_MAINS_S:%.S=o/$(MODE)/%.o) \ + $(EXAMPLES_MAINS_C:%.c=o/$(MODE)/%.o) \ + $(EXAMPLES_MAINS_CC:%.cc=o/$(MODE)/%.o) + +EXAMPLES_COMS = \ + $(EXAMPLES_OBJS:%.o=%.com) + +EXAMPLES_ELFS = \ + $(EXAMPLES_OBJS:%.o=%.elf) + +EXAMPLES_BINS = \ + $(EXAMPLES_ELFS) \ + $(EXAMPLES_COMS) \ + $(EXAMPLES_COMS:%=%.dbg) + +EXAMPLES_DIRECTDEPS = \ + APE_LIB \ + DSP_CORE \ + DSP_SCALE \ + DSP_TTY \ + LIBC_ALG \ + LIBC_BITS \ + LIBC_CALLS \ + LIBC_CALLS_HEFTY \ + LIBC_CONV \ + LIBC_FMT \ + LIBC_LOG \ + LIBC_MATH \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_NT_KERNELBASE \ + LIBC_NT_NTDLL \ + LIBC_NT_USER32 \ + LIBC_RAND \ + LIBC_RUNTIME \ + LIBC_SOCK \ + LIBC_STDIO \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_SYSV_CALLS \ + LIBC_TESTLIB \ + LIBC_TIME \ + LIBC_TINYMATH \ + LIBC_UNICODE \ + LIBC_X \ + THIRD_PARTY_COMPILER_RT \ + THIRD_PARTY_DLMALLOC \ + THIRD_PARTY_DTOA \ + THIRD_PARTY_DUKTAPE \ + THIRD_PARTY_GETOPT \ + THIRD_PARTY_MUSL \ + THIRD_PARTY_STB \ + THIRD_PARTY_XED \ + THIRD_PARTY_ZLIB \ + TOOL_VIZ_LIB + +EXAMPLES_DEPS := \ + $(call uniq,$(foreach x,$(EXAMPLES_DIRECTDEPS),$($(x)))) + +o/$(MODE)/examples/examples.pkg: \ + $(EXAMPLES_OBJS) \ + $(foreach x,$(EXAMPLES_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/examples/unbourne.o: \ + OVERRIDE_CPPFLAGS += \ + -DSTACK_FRAME_UNLIMITED + +o/$(MODE)/examples/%.com.dbg: \ + $(EXAMPLES_DEPS) \ + o/$(MODE)/examples/%.o \ + o/$(MODE)/examples/examples.pkg \ + $(CRT) \ + $(APE) + @$(APELINK) + +o/$(MODE)/examples/%.elf: \ + $(EXAMPLES_DEPS) \ + o/$(MODE)/examples/%.o \ + $(CRT) \ + $(ELF) + @$(ELFLINK) + +$(EXAMPLES_OBJS): examples/examples.mk + +o/$(MODE)/examples/hellojs.com.dbg: \ + $(EXAMPLES_DEPS) \ + o/$(MODE)/examples/hellojs.o \ + o/$(MODE)/examples/hello.js.zip.o \ + o/$(MODE)/examples/examples.pkg \ + $(CRT) \ + $(APE) + @$(APELINK) + +.PHONY: o/$(MODE)/examples +o/$(MODE)/examples: $(EXAMPLES_BINS) diff --git a/examples/findprime.c b/examples/findprime.c new file mode 100644 index 00000000..7a7524f5 --- /dev/null +++ b/examples/findprime.c @@ -0,0 +1,64 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/calls/struct/itimerval.h" +#include "libc/conv/conv.h" +#include "libc/limits.h" +#include "libc/log/check.h" +#include "libc/log/log.h" +#include "libc/math.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/itimer.h" +#include "libc/sysv/consts/sig.h" +#include "libc/time/time.h" + +static const struct itimerval kTimer = {{0, 10000}, {0, 10000}}; /* 10ms */ +static volatile bool32 showprogress_; +static const char *magic_; + +void OnInterrupt(int sig) { + showprogress_ = true; +} +void ShowProgress(uintmax_t i, uintmax_t j, uintmax_t n) { + fprintf(stderr, "%s%,40jd%,40jd%,40jd\r\n", magic_, i, j, n); + showprogress_ = false; +} + +static bool IsPrime(uintmax_t i) { + uintmax_t j, n; + for (j = 3, n = (unsigned long)floorl(sqrtl(i)); j <= n; j += 2) { + if (showprogress_) ShowProgress(i, j, n); + if (i % j == 0) return false; + } + return true; +} + +static void TryNumber(uintmax_t x, uintmax_t i) { + if (IsPrime(i)) { + printf("%s%,jd%s%,jd\n", "the prime nearest ", x, " is ", i); + exit(0); + } +} + +int main(int argc, char **argv) { + uintmax_t x, i, j; + CHECK_EQ(2, argc); + signal(SIGALRM, OnInterrupt); + setitimer(ITIMER_REAL, &kTimer, NULL); + magic_ = cancolor() ? "\e[F\e[K" : ""; + if ((x = strtoumax(argv[1], NULL, 0)) % 2 == 0) ++x; + TryNumber(x, x); + for (i = x, j = x;;) { + if (i < UINTMAX_MAX) TryNumber(x, i), i += 2; + if (j > 1) TryNumber(x, j), j -= 2; + } +} diff --git a/examples/fld.c b/examples/fld.c new file mode 100644 index 00000000..fc00cae9 --- /dev/null +++ b/examples/fld.c @@ -0,0 +1,121 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/inttypes.h" +#include "libc/literal.h" +#include "libc/math.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" + +static const char kHeaderBin[] = "\ +/\t┌sign\n\ +/\t│ ┌exponent\n\ +/\t│ │ ┌intpart\n\ +/\t│ │ │ ┌fraction\n\ +/\t│ │ │ │\n\ +/\t│┌┴────────────┐│┌┴────────────────────────────────────────────────────────────┐\n"; + +static const char kHeaderHex[] = "\ +/\t ┌sign/exponent\n\ +/\t │ ┌intpart/fraction\n\ +/\t │ │\n\ +/\t┌┴─┐┌┴─────────────┐\n"; + +void dobin(const char *op, long double x, FILE *f) { + uint16_t hi; + uint64_t lo; + uint8_t buf[16]; + memcpy(buf, &x, sizeof(x)); + memcpy(&lo, &buf[0], sizeof(lo)); + memcpy(&hi, &buf[8], sizeof(hi)); + fprintf(f, "/\t%016" PRIb16 "%064" PRIb64 " %-8s %19.19Lf\n", hi, lo, op, x); +} + +void dohex(const char *op, long double x, FILE *f) { + uint16_t hi; + uint64_t lo; + uint8_t buf[16]; + memcpy(buf, &x, sizeof(x)); + memcpy(&lo, &buf[0], sizeof(lo)); + memcpy(&hi, &buf[8], sizeof(hi)); + fprintf(f, "/\t%04" PRIx16 "%016" PRIx64 " %-8s %19.19Lf\n", hi, lo, op, x); +} + +#define DOBIN(OP) \ + dobin(" " #OP, OP(), stdout); \ + dobin("-" #OP, -OP(), stdout) + +#define DOHEX(OP) \ + dohex(" " #OP, OP(), stdout); \ + dohex("-" #OP, -OP(), stdout) + +int main(int argc, char *argv[]) { + fputs(kHeaderBin, stdout); + DOBIN(fldz); + DOBIN(fld1); + DOBIN(fldpi); + DOBIN(fldl2t); + DOBIN(fldlg2); + DOBIN(fldln2); + DOBIN(fldl2e); + DOBIN(finit); + fputc('\n', stdout); + fputs(kHeaderHex, stdout); + DOHEX(fldz); + DOHEX(fld1); + DOHEX(fldpi); + DOHEX(fldl2t); + DOHEX(fldlg2); + DOHEX(fldln2); + DOHEX(fldl2e); + DOHEX(finit); + return 0; +} + +// clang-format off +// +// ┌sign +// │ ┌exponent +// │ │ ┌intpart +// │ │ │ ┌fraction +// │ │ │ │ +// │┌┴────────────┐│┌┴────────────────────────────────────────────────────────────┐ +// 00000000000000000000000000000000000000000000000000000000000000000000000000000000 fldz 0.0000000000000000000 +// 10000000000000000000000000000000000000000000000000000000000000000000000000000000 -fldz -0.0000000000000000000 +// 00111111111111111000000000000000000000000000000000000000000000000000000000000000 fld1 1.0000000000000000000 +// 10111111111111111000000000000000000000000000000000000000000000000000000000000000 -fld1 -1.0000000000000000000 +// 01000000000000001100100100001111110110101010001000100001011010001100001000110101 fldpi 3.1415926540000000000 +// 11000000000000001100100100001111110110101010001000100001011010001100001000110101 -fldpi -3.1415926540000000000 +// 01000000000000001101010010011010011110000100101111001101000110111000101011111110 fldl2t 3.3219280950000000000 +// 11000000000000001101010010011010011110000100101111001101000110111000101011111110 -fldl2t -3.3219280950000000000 +// 00111111111111011001101000100000100110101000010011111011110011111111011110011001 fldlg2 0.3010299960000000000 +// 10111111111111011001101000100000100110101000010011111011110011111111011110011001 -fldlg2 -0.3010299960000000000 +// 00111111111111101011000101110010000101111111011111010001110011110111100110101100 fldln2 0.6931471810000000000 +// 10111111111111101011000101110010000101111111011111010001110011110111100110101100 -fldln2 -0.6931471810000000000 +// 00111111111111111011100010101010001110110010100101011100000101111111000010111100 fldl2e 1.4426950410000000000 +// 10111111111111111011100010101010001110110010100101011100000101111111000010111100 -fldl2e -1.4426950410000000000 +// +// ┌sign/exponent +// │ ┌intpart/fraction +// │ │ +// ┌┴─┐┌┴─────────────┐ +// 00000000000000000000 fldz 0.0000000000000000000 +// 80000000000000000000 -fldz -0.0000000000000000000 +// 3fff8000000000000000 fld1 1.0000000000000000000 +// bfff8000000000000000 -fld1 -1.0000000000000000000 +// 4000c90fdaa22168c235 fldpi 3.1415926540000000000 +// c000c90fdaa22168c235 -fldpi -3.1415926540000000000 +// 4000d49a784bcd1b8afe fldl2t 3.3219280950000000000 +// c000d49a784bcd1b8afe -fldl2t -3.3219280950000000000 +// 3ffd9a209a84fbcff799 fldlg2 0.3010299960000000000 +// bffd9a209a84fbcff799 -fldlg2 -0.3010299960000000000 +// 3ffeb17217f7d1cf79ac fldln2 0.6931471810000000000 +// bffeb17217f7d1cf79ac -fldln2 -0.6931471810000000000 +// 3fffb8aa3b295c17f0bc fldl2e 1.4426950410000000000 +// bfffb8aa3b295c17f0bc -fldl2e -1.4426950410000000000 diff --git a/examples/forkrand.c b/examples/forkrand.c new file mode 100644 index 00000000..725e7d81 --- /dev/null +++ b/examples/forkrand.c @@ -0,0 +1,44 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/log/log.h" +#include "libc/nt/nt/process.h" +#include "libc/rand/rand.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/calls/calls.h" +#include "libc/time/time.h" + +noinline void dostuff(void) { + srand(rand64()); /* seeds rand() w/ intel rdrnd, auxv, etc. */ + for (unsigned i = 0; i < 5; ++i) { + int us = rand() % 500000; + usleep(us); + printf("%s%u%s%u [%s=%d]\n", "hello no. ", i, " from ", getpid(), "us", us); + fflush(stdout); + } +} + +int main(int argc, char *argv[]) { + fprintf(stderr, "%p\n", RtlCloneUserProcess); + int child; + if ((child = fork()) == -1) perror("fork"), exit(1); + if (!child) { + /* child process */ + dostuff(); + return 0; + } else { + /* parent process */ + dostuff(); + /* note: abandoned children become zombies */ + int rc, wstatus; + if ((rc = wait(&wstatus)) == -1) perror("wait"), exit(1); + return WEXITSTATUS(wstatus); + } +} diff --git a/examples/forky.c b/examples/forky.c new file mode 100644 index 00000000..7863f5c0 --- /dev/null +++ b/examples/forky.c @@ -0,0 +1,51 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/calls/calls.h" +#include "libc/calls/hefty/spawn.h" +#include "libc/calls/internal.h" +#include "libc/conv/conv.h" +#include "libc/log/check.h" +#include "libc/mem/mem.h" +#include "libc/nt/enum/filemapflags.h" +#include "libc/nt/enum/pageflags.h" +#include "libc/nt/memory.h" +#include "libc/runtime/gc.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/x/x.h" + +int main(int argc, char *argv[]) { + int pid; + long *addr; + int64_t fh; + if (argc == 1) { + fh = CreateFileMappingNuma(-1, &kNtIsInheritable, kNtPageReadwrite, 0, + FRAMESIZE, NULL, kNtNumaNoPreferredNode); + addr = MapViewOfFileExNuma(fh, kNtFileMapRead | kNtFileMapWrite, 0, 0, + FRAMESIZE, NULL, kNtNumaNoPreferredNode); + *addr = 0x31337; + CHECK_NE(-1, (pid = spawnve( + 0, (int[3]){STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO}, + "o/examples/forky.com", + (char *const[]){"o/examples/forky.com", + gc(xasprintf("%#lx", (intptr_t)addr)), + gc(xasprintf("%#lx", fh)), NULL}, + environ))); + CHECK_NE(-1, waitpid(pid, NULL, 0)); + } else { + addr = (long *)(intptr_t)strtoul(argv[1], NULL, 0); + fh = strtoul(argv[2], NULL, 0); + addr = MapViewOfFileExNuma(fh, kNtFileMapRead | kNtFileMapWrite, 0, 0, + FRAMESIZE, addr, kNtNumaNoPreferredNode); + printf("%#lx\n", *addr); + } + return 0; +} diff --git a/examples/generalized-automatic-datastructure-printing.c b/examples/generalized-automatic-datastructure-printing.c new file mode 100644 index 00000000..d7f8edbc --- /dev/null +++ b/examples/generalized-automatic-datastructure-printing.c @@ -0,0 +1,52 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/log/gdb.h" +#include "libc/rand/rand.h" +#include "libc/stdio/stdio.h" + +/** + * @fileovierview gdbexec(s) demo + * It basically launches an ephemeral `gdb -p $PID -ex "$s"`. + */ + +int i; +int M[8][8] = { + {772549, 921569, 407843, 352941, 717647, 78431, 666667, 627451}, + {321569, 419608, 227451, 396078, 223529, 882353, 952941, 937255}, + {15686, 545098, 31373, 7843, 15686, 298039, 976471, 352941}, + {70588, 858824, 415686, 184314, 25098, 5098, 141176, 47059}, + {141176, 541176, 658824, 227451, 490196, 301961, 937255, 678431}, + {188235, 823529, 858824, 87451, 545098, 611765, 188235, 576471}, + {580392, 913725, 996078, 592157, 7451, 176471, 862745, 784314}, + {278431, 945098, 843137, 439216, 878431, 529412, 262745, 43137}, +}; + +int main(int argc, char *argv[]) { + int y, x; + for (i = 0;; ++i) { + for (y = 0; y < 8; ++y) { + for (x = 0; x < 8; ++x) { + if (!(M[y][x] % 2)) { + M[y][x] /= 2; + } else { + M[y][x] *= 3; + M[y][x] += 1; + } + } + } + if (rand() % 10000 == 0) { + gdbexec("print i"); + gdbexec("print M"); + break; + } + } + printf("quitting\n"); + return 0; +} diff --git a/examples/gui.c b/examples/gui.c new file mode 100644 index 00000000..291f38fb --- /dev/null +++ b/examples/gui.c @@ -0,0 +1,15 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/nt/enum/messageboxtype.h" +#include "libc/nt/messagebox.h" + +int main(int argc, char *argv[]) { + return MessageBox(0, u"hello world", u"cosmopolitan", kNtMbOk) ? 0 : 1; +} diff --git a/examples/hello.c b/examples/hello.c new file mode 100644 index 00000000..3b2e16d0 --- /dev/null +++ b/examples/hello.c @@ -0,0 +1,23 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/errno.h" +#include "libc/stdio/stdio.h" + +int main() { + /* + * Cosmopolitan's "Hello World" demonstrates a best practice. + * + * Since we conditionally link heavyweight features based on which + * characters are present in the format string, it's a good idea to + * have that string consist solely of directives. + */ + printf("%s\n", "hello world"); + return errno; +} diff --git a/examples/hello.js b/examples/hello.js new file mode 100644 index 00000000..d5058ec8 --- /dev/null +++ b/examples/hello.js @@ -0,0 +1,2 @@ +NativePrint('Hello world!\n'); +NativePrint('2+3=' + NativeAdd(2, 3) + '\n'); diff --git a/examples/hello2.c b/examples/hello2.c new file mode 100644 index 00000000..d1fc18fe --- /dev/null +++ b/examples/hello2.c @@ -0,0 +1,28 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/str/str.h" +#include "libc/calls/calls.h" +#include "libc/sysv/consts/fileno.h" + +#define kMessage "hello world\r\n" + +int main() { + /* + * Cosmopolitan "Hello World" using system calls. + * + * Another Cosmopolitan best practice is to use the standard symbolic + * names for file descriptors 0, 1, and 2. This is a good idea because + * on Windows the numbers are actually different. Because Cosmopolitan + * is a zero-emulation library, we address that problem by turning + * traditional #define's into variables, which the runtime determines + * automatically. + */ + return write(STDOUT_FILENO, kMessage, strlen(kMessage)) != -1 ? 0 : 1; +} diff --git a/examples/hello3.c b/examples/hello3.c new file mode 100644 index 00000000..49896be5 --- /dev/null +++ b/examples/hello3.c @@ -0,0 +1,19 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/errno.h" +#include "libc/runtime/gc.h" +#include "libc/calls/calls.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/x/x.h" + +int main() { + dprintf(STDOUT_FILENO, "%s\n", gc(xasprintf("%'s", "(╯°□°)╯︵' ┻━┻"))); + return errno; +} diff --git a/examples/hello4.c b/examples/hello4.c new file mode 100644 index 00000000..29a69466 --- /dev/null +++ b/examples/hello4.c @@ -0,0 +1,16 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/errno.h" +#include "libc/stdio/stdio.h" + +int main() { + printf("%s \n", "hello world"); + return errno; +} diff --git a/examples/hellojs.c b/examples/hellojs.c new file mode 100644 index 00000000..8afb234d --- /dev/null +++ b/examples/hellojs.c @@ -0,0 +1,56 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/calls/calls.h" +#include "libc/calls/struct/stat.h" +#include "libc/log/check.h" +#include "libc/mem/mem.h" +#include "libc/runtime/gc.h" +#include "libc/sysv/consts/o.h" +#include "third_party/duktape/duktape.h" + +static duk_ret_t NativePrint(duk_context *ctx) { + duk_push_string(ctx, " "); + duk_insert(ctx, 0); + duk_join(ctx, duk_get_top(ctx) - 1); + fputs(duk_safe_to_string(ctx, -1), stdout); + return 0; +} + +static duk_ret_t NativeAdd(duk_context *ctx) { + int i, n; + double r; + n = duk_get_top(ctx); + for (r = i = 0; i < n; i++) r += duk_to_number(ctx, i); + duk_push_number(ctx, r); + return 1; +} + +int main(int argc, char *argv[]) { + int fd; + struct stat st; + const char *code; + duk_context *ctx; + ctx = duk_create_heap_default(); + duk_push_c_function(ctx, NativePrint, DUK_VARARGS); + duk_put_global_string(ctx, "NativePrint"); + duk_push_c_function(ctx, NativeAdd, DUK_VARARGS); + duk_put_global_string(ctx, "NativeAdd"); + + CHECK_NE(-1, (fd = open("zip:examples/hello.js", O_RDONLY))); + CHECK_NE(-1, fstat(fd, &st)); + CHECK_NOTNULL((code = gc(malloc(st.st_size)))); + CHECK_EQ(st.st_size, read(fd, code, st.st_size)); + CHECK_NE(-1, close(fd)); + + duk_eval_string(ctx, code); + duk_pop(ctx); + duk_destroy_heap(ctx); + return 0; +} diff --git a/examples/hidecursor.c b/examples/hidecursor.c new file mode 100644 index 00000000..05bf4c3d --- /dev/null +++ b/examples/hidecursor.c @@ -0,0 +1,26 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/nt/console.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/consolecursorinfo.h" +#include "libc/nt/synchronization.h" + +int main(int argc, char *argv[]) { + struct NtConsoleCursorInfo ntcursor; + SleepEx(1000, false); + GetConsoleCursorInfo(GetStdHandle(kNtStdOutputHandle), &ntcursor); + ntcursor.bVisible = false; + SetConsoleCursorInfo(GetStdHandle(kNtStdOutputHandle), &ntcursor); + SleepEx(1000, false); + ntcursor.bVisible = true; + SetConsoleCursorInfo(GetStdHandle(kNtStdOutputHandle), &ntcursor); + SleepEx(1000, false); + return 0; +} diff --git a/examples/invtsc.c b/examples/invtsc.c new file mode 100644 index 00000000..c4d9b77f --- /dev/null +++ b/examples/invtsc.c @@ -0,0 +1,77 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/bits/bits.h" +#include "libc/dce.h" +#include "libc/log/check.h" +#include "libc/nexgen32e/rdtsc.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/clock.h" +#include "libc/sysv/consts/sig.h" +#include "libc/time/time.h" +#include "libc/x/x.h" +#include "third_party/dtoa/dtoa.h" + +/** + * @fileoverview Measure CPU clock mystery constants. + * @note CPUID EAX=15h/16h is a joke + */ + +const long double kInterval = 0.001L; + +long double start_; +char dtoabuf_[3][32]; +volatile bool isdone_; + +void OnCtrlC(int sig) { + isdone_ = true; +} + +long double now(void) { + return dtime(CLOCK_MONOTONIC); +} + +long double GetSample(void) { + uint64_t tick1, tick2; + long double time1, time2; + time1 = now(); + tick1 = rdtsc(); + nanosleep(&(struct timespec){0, 100000}, NULL); + time2 = now(); + tick2 = rdtsc(); + return ((time2 - time1) * 1e9L) / (long double)(tick2 - tick1); +} + +void MeasureNanosecondsPerAlwaysRunningTimerCycle(void) { + int i; + long double avg, samp; + start_ = now(); + for (i = 1, avg = 1.0L; !isdone_; ++i) { + samp = GetSample(); + avg += (samp - avg) / i; + dsleep(kInterval); + printf("1c = %sns (last=%sns spent=%ss)\n", g_fmt(dtoabuf_[0], (double)avg), + g_fmt(dtoabuf_[1], (double)samp), + g_fmt(dtoabuf_[2], (double)(now() - start_))); + } +} + +int main(int argc, char *argv[]) { + if (!X86_HAVE(INVTSC)) { + fprintf(stderr, "warning: html can reprogram your microcode\n"); + } + if (X86_HAVE(HYPERVISOR)) { + fprintf(stderr, "warning: virtual machine rdtsc isn't great\n"); + } + CHECK_NE(-1, xsigaction(SIGINT, OnCtrlC, 0, 0, NULL)); + MeasureNanosecondsPerAlwaysRunningTimerCycle(); + return 0; +} diff --git a/examples/kilo.c b/examples/kilo.c new file mode 100644 index 00000000..a9607fe9 --- /dev/null +++ b/examples/kilo.c @@ -0,0 +1,1372 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ │ +│ Kilo ── A very simple editor in less than 1-kilo lines of code (as │ +│ counted by "cloc"). Does not depend on libcurses, directly │ +│ emits VT100 escapes on the terminal. │ +│ │ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2016 Salvatore Sanfilippo │ +│ │ +│ Redistribution and use in source and binary forms, with or without │ +│ modification, are permitted provided that the following conditions are │ +│ met: │ +│ │ +│ * Redistributions of source code must retain the above copyright │ +│ notice, this list of conditions and the following disclaimer. │ +│ │ +│ * Redistributions in binary form must reproduce the above copyright │ +│ notice, this list of conditions and the following disclaimer in the │ +│ documentation and/or other materials provided with the distribution. │ +│ │ +│ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS │ +│ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT │ +│ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR │ +│ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT │ +│ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, │ +│ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT │ +│ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, │ +│ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY │ +│ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT │ +│ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE │ +│ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +asm(".ident \"\n\ +Kilo ─ A very simple editor (BSD-2)\n\ +Copyright 2016 Salvatore Sanfilippo\n\ +Contact: antirez@gmail.com\"\n\ +.include \"libc/disclaimer.inc\""); + +/* + * This software has been modified by Justine Tunney to: + * + * 1. Have Emacs keybindings. + * + * 2. Be capable of editing files with ANSI color codes, in such a way + * that the ANSI color codes are displayed 'as is' (since that's + * something no other editor can quite do). The kinda buggy syntax + * highlighting code needed to be commented out, to do this. + */ + +#define KILO_VERSION "0.0.1" + +#ifndef _BSD_SOURCE +#define _BSD_SOURCE +#endif +#define _GNU_SOURCE + +#include "libc/alg/alg.h" +#include "libc/alg/arraylist.h" +#include "libc/calls/calls.h" +#include "libc/calls/termios.h" +#include "libc/calls/weirdtypes.h" +#include "libc/errno.h" +#include "libc/fmt/fmt.h" +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/termios.h" +#include "libc/time/time.h" + +/* Syntax highlight types */ +#define HL_NORMAL 0 +#define HL_NONPRINT 1 +#define HL_COMMENT 2 /* Single line comment. */ +#define HL_MLCOMMENT 3 /* Multi-line comment. */ +#define HL_KEYWORD1 4 +#define HL_KEYWORD2 5 +#define HL_STRING 6 +#define HL_NUMBER 7 +#define HL_MATCH 8 /* Search match. */ + +#define HL_HIGHLIGHT_STRINGS (1 << 0) +#define HL_HIGHLIGHT_NUMBERS (1 << 1) + +struct editorSyntax { + const char *const *filematch; + const char *const *keywords; + char singleline_comment_start[2]; + char multiline_comment_start[3]; + char multiline_comment_end[3]; + int flags; +}; + +/* This structure represents a single line of the file we are editing. */ +typedef struct erow { + int idx; /* Row index in the file, zero-based. */ + int size; /* Size of the row, excluding the null term. */ + int rsize; /* Size of the rendered row. */ + char *chars; /* Row content. */ + char *render; /* Row content "rendered" for screen (for TABs). */ + unsigned char *hl; /* Syntax highlight type for each character in render.*/ + int hl_oc; /* Row had open comment at end in last syntax highlight + check. */ +} erow; + +typedef struct hlcolor { + int r, g, b; +} hlcolor; + +struct editorConfig { + int cx, cy; /* Cursor x and y position in characters */ + int rowoff; /* Offset of row displayed. */ + int coloff; /* Offset of column displayed. */ + int screenrows; /* Number of rows that we can show */ + int screencols; /* Number of cols that we can show */ + int numrows; /* Number of rows */ + int rawmode; /* Is terminal raw mode enabled? */ + erow *row; /* Rows */ + int dirty; /* File modified but not saved. */ + char *filename; /* Currently open filename */ + char statusmsg[80]; + time_t statusmsg_time; + const struct editorSyntax *syntax; /* Current syntax highlight, or NULL. */ +}; + +static struct editorConfig E; + +#define CTRL(C) ((C) ^ 0b01000000) /* where ^W etc. codes come from */ + +enum KEY_ACTION { + ARROW_LEFT = 1000, + ARROW_RIGHT, + ARROW_UP, + ARROW_DOWN, + DEL_KEY, + HOME_KEY, + END_KEY, + PAGE_UP, + PAGE_DOWN +}; + +void editorSetStatusMessage(const char *fmt, ...); + +/* =========================== Syntax highlights DB ========================= + * + * In order to add a new syntax, define two arrays with a list of file name + * matches and keywords. The file name matches are used in order to match + * a given syntax with a given file name: if a match pattern starts with a + * dot, it is matched as the last past of the filename, for example ".c". + * Otherwise the pattern is just searched inside the filenme, like "Makefile"). + * + * The list of keywords to highlight is just a list of words, however if they + * a trailing '|' character is added at the end, they are highlighted in + * a different color, so that you can have two different sets of keywords. + * + * Finally add a stanza in the HLDB global variable with two two arrays + * of strings, and a set of flags in order to enable highlighting of + * comments and numbers. + * + * The characters for single and multi line comments must be exactly two + * and must be provided as well (see the C language example). + * + * There is no support to highlight patterns currently. */ + +/* C / C++ */ +const char *const C_HL_extensions[] = {".c", ".cpp", NULL}; +const char *const C_HL_keywords[] = { + /* A few C / C++ keywords */ + "switch", "if", "while", "for", "break", "continue", "return", "else", + "struct", "union", "typedef", "static", "enum", "class", + /* C types */ + "int|", "long|", "double|", "float|", "char|", "unsigned|", "signed|", + "void|", NULL}; + +/* Here we define an array of syntax highlights by extensions, keywords, + * comments delimiters and flags. */ +const struct editorSyntax HLDB[] = { + {/* C / C++ */ + C_HL_extensions, C_HL_keywords, "//", "/*", "*/", + HL_HIGHLIGHT_STRINGS | HL_HIGHLIGHT_NUMBERS}}; + +#define HLDB_ENTRIES (sizeof(HLDB) / sizeof(HLDB[0])) + +/* ======================= Low level terminal handling ====================== */ + +static struct termios orig_termios; /* In order to restore at exit.*/ + +void disableRawMode(int64_t fd) { + /* Don't even check the return value as it's too late. */ + if (E.rawmode) { + tcsetattr(fd, TCSAFLUSH, &orig_termios); + E.rawmode = 0; + } +} + +/* Called at exit to avoid remaining in raw mode. */ +void editorAtExit(void) { + disableRawMode(STDIN_FILENO); +} + +/* Raw mode: 1960 magic shit. */ +int enableRawMode(int64_t fd) { + struct termios raw; + + if (E.rawmode) return 0; /* Already enabled. */ + if (!isatty(STDIN_FILENO)) goto fatal; + atexit(editorAtExit); + if (tcgetattr(fd, &orig_termios) == -1) goto fatal; + + raw = orig_termios; /* modify the original mode */ + /* input modes: no break, no CR to NL, no parity check, no strip char, + * no start/stop output control. */ + raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); + /* output modes - disable post processing */ + raw.c_oflag &= ~(OPOST); + /* control modes - set 8 bit chars */ + raw.c_cflag |= (CS8); + /* local modes - choing off, canonical off, no extended functions, + * no signal chars (^Z,^C) */ + raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); + /* control chars - set return condition: min number of bytes and timer. */ + raw.c_cc[VMIN] = 0; /* Return each byte, or zero for timeout. */ + raw.c_cc[VTIME] = 1; /* 100 ms timeout (unit is tens of second). */ + + /* put terminal in raw mode after flushing */ + if (tcsetattr(fd, TCSAFLUSH, &raw) < 0) goto fatal; + E.rawmode = 1; + return 0; + +fatal: + errno = ENOTTY; + return -1; +} + +/* Read a key from the terminal put in raw mode, trying to handle + * escape sequences. */ +int editorReadKey(int64_t fd) { + int nread; + char c, seq[3]; + while ((nread = read(fd, &c, 1)) == 0) { + } + if (nread == -1) exit(1); + + while (1) { + switch (c) { + case CTRL('J'): /* newline */ + return CTRL('M'); + case CTRL('['): /* escape sequence */ + /* If this is just an ESC, we'll timeout here. */ + if (read(fd, seq, 1) == 0) return CTRL('['); + if (read(fd, seq + 1, 1) == 0) return CTRL('['); + + /* ESC [ sequences. */ + if (seq[0] == '[') { + if (seq[1] >= '0' && seq[1] <= '9') { + /* Extended escape, read additional byte. */ + if (read(fd, seq + 2, 1) == 0) return CTRL('['); + if (seq[2] == '~') { + switch (seq[1]) { + case '3': + return DEL_KEY; + case '5': + return PAGE_UP; + case '6': + return PAGE_DOWN; + } + } + } else { + /* Arrow Keys + * + * KEY CODE FN SHIFT OPTION + * ───── ────── ────── ────── ────── + * UP ←[A ←[5~ ←[A ←[A + * DOWN ←[B ←[6~ ←[B ←[B + * RIGHT ←[C ←[4~ ←[1;2C ←[f + * LEFT ←[D ←[1~ ←[1;2C ←[b + */ + switch (seq[1]) { + case 'A': + return ARROW_UP; + case 'B': + return ARROW_DOWN; + case 'C': + return ARROW_RIGHT; + case 'D': + return ARROW_LEFT; + case 'H': + return HOME_KEY; + case 'F': + return END_KEY; + } + } + } + + /* ESC O sequences. */ + else if (seq[0] == 'O') { + switch (seq[1]) { + case 'H': + return HOME_KEY; + case 'F': + return END_KEY; + } + } + break; + default: + return c; + } + } +} + +/* Use the ESC [6n escape sequence to query the horizontal cursor position + * and return it. On error -1 is returned, on success the position of the + * cursor is stored at *rows and *cols and 0 is returned. */ +int getCursorPosition(int64_t ifd, int64_t ofd, int *rows, int *cols) { + char buf[32]; + unsigned i = 0; + + /* Report cursor location */ + if (write(ofd, "\e[6n", 4) != 4) return -1; + + /* Read the response: ESC [ rows ; cols R */ + while (i < sizeof(buf) - 1) { + if (read(ifd, buf + i, 1) != 1) break; + if (buf[i] == 'R') break; + i++; + } + buf[i] = '\0'; + + /* Parse it. */ + if (buf[0] != CTRL('[') || buf[1] != '[') return -1; + if (sscanf(buf + 2, "%d;%d", rows, cols) != 2) return -1; + return 0; +} + +/* Try to get the number of columns in the current terminal. If the ioctl() + * call fails the function will try to query the terminal itself. + * Returns 0 on success, -1 on error. */ +int getWindowSize(int64_t ifd, int64_t ofd, int *rows, int *cols) { + struct winsize ws; + if (getttysize(STDOUT_FILENO, &ws) == -1 || ws.ws_col == 0) { + /* ioctl() failed. Try to query the terminal itself. */ + int orig_row, orig_col, retval; + + /* Get the initial position so we can restore it later. */ + retval = getCursorPosition(ifd, ofd, &orig_row, &orig_col); + if (retval == -1) goto failed; + + /* Go to right/bottom margin and get position. */ + if (write(ofd, "\e[999C\e[999B", 12) != 12) goto failed; + retval = getCursorPosition(ifd, ofd, rows, cols); + if (retval == -1) goto failed; + + /* Restore position. */ + char seq[32]; + snprintf(seq, 32, "\e[%d;%dH", orig_row, orig_col); + if (write(ofd, seq, strlen(seq)) == -1) { + /* Can't recover... */ + } + return 0; + } else { + *cols = ws.ws_col; + *rows = ws.ws_row; + return 0; + } + +failed: + return -1; +} + +/* ====================== Syntax highlight color scheme ==================== */ + +int is_separator(int c) { + return c == '\0' || isspace(c) || strchr(",.()+-/*=~%[];", c) != NULL; +} + +/* Return true if the specified row last char is part of a multi line comment + * that starts at this row or at one before, and does not end at the end + * of the row but spawns to the next row. */ +int editorRowHasOpenComment(erow *row) { + if (row->hl && row->rsize && row->hl[row->rsize - 1] == HL_MLCOMMENT && + (row->rsize < 2 || (row->render[row->rsize - 2] != '*' || + row->render[row->rsize - 1] != '/'))) + return 1; + return 0; +} + +/* Set every byte of row->hl (that corresponds to every character in the line) + * to the right syntax highlight type (HL_* defines). */ +void editorUpdateSyntax(erow *row) { + row->hl = realloc(row->hl, row->rsize); + memset(row->hl, HL_NORMAL, row->rsize); + + if (E.syntax == NULL) return; /* No syntax, everything is HL_NORMAL. */ + + int i, prev_sep, in_string, in_comment; + char *p; + const char *const *keywords = E.syntax->keywords; + char *scs = E.syntax->singleline_comment_start; + char *mcs = E.syntax->multiline_comment_start; + char *mce = E.syntax->multiline_comment_end; + + /* Point to the first non-space char. */ + p = row->render; + i = 0; /* Current char offset */ + while (*p && isspace(*p)) { + p++; + i++; + } + prev_sep = 1; /* Tell the parser if 'i' points to start of word. */ + in_string = 0; /* Are we inside "" or '' ? */ + in_comment = 0; /* Are we inside multi-line comment? */ + + /* If the previous line has an open comment, this line starts + * with an open comment state. */ + if (row->idx > 0 && editorRowHasOpenComment(&E.row[row->idx - 1])) + in_comment = 1; + + while (*p) { + /* Handle // comments. */ + if (prev_sep && *p == scs[0] && *(p + 1) == scs[1]) { + /* From here to end is a comment */ + memset(row->hl + i, HL_COMMENT, row->size - i); + return; + } + + /* Handle multi line comments. */ + if (in_comment) { + row->hl[i] = HL_MLCOMMENT; + if (*p == mce[0] && *(p + 1) == mce[1]) { + row->hl[i + 1] = HL_MLCOMMENT; + p += 2; + i += 2; + in_comment = 0; + prev_sep = 1; + continue; + } else { + prev_sep = 0; + p++; + i++; + continue; + } + } else if (*p == mcs[0] && *(p + 1) == mcs[1]) { + row->hl[i] = HL_MLCOMMENT; + row->hl[i + 1] = HL_MLCOMMENT; + p += 2; + i += 2; + in_comment = 1; + prev_sep = 0; + continue; + } + + /* Handle "" and '' */ + if (in_string) { + row->hl[i] = HL_STRING; + if (*p == '\\') { + row->hl[i + 1] = HL_STRING; + p += 2; + i += 2; + prev_sep = 0; + continue; + } + if (*p == in_string) in_string = 0; + p++; + i++; + continue; + } else { + if (*p == '"' || *p == '\'') { + in_string = *p; + row->hl[i] = HL_STRING; + p++; + i++; + prev_sep = 0; + continue; + } + } + + /* Handle non printable chars. */ + if (!isprint(*p)) { + row->hl[i] = HL_NONPRINT; + p++; + i++; + prev_sep = 0; + continue; + } + + /* Handle numbers */ + if ((isdigit(*p) && (prev_sep || row->hl[i - 1] == HL_NUMBER)) || + (*p == '.' && i > 0 && row->hl[i - 1] == HL_NUMBER)) { + row->hl[i] = HL_NUMBER; + p++; + i++; + prev_sep = 0; + continue; + } + + /* Handle keywords and lib calls */ + if (prev_sep) { + int j; + for (j = 0; keywords[j]; j++) { + int klen = strlen(keywords[j]); + int kw2 = keywords[j][klen - 1] == '|'; + if (kw2) klen--; + + if (!memcmp(p, keywords[j], klen) && is_separator(*(p + klen))) { + /* Keyword */ + memset(row->hl + i, kw2 ? HL_KEYWORD2 : HL_KEYWORD1, klen); + p += klen; + i += klen; + break; + } + } + if (keywords[j] != NULL) { + prev_sep = 0; + continue; /* We had a keyword match */ + } + } + + /* Not special chars */ + prev_sep = is_separator(*p); + p++; + i++; + } + + /* Propagate syntax change to the next row if the open commen + * state changed. This may recursively affect all the following rows + * in the file. */ + int oc = editorRowHasOpenComment(row); + /* if (row->hl_oc != oc && row->idx + 1 < E.numrows) */ + /* editorUpdateSyntax(&E.row[row->idx + 1]); */ + row->hl_oc = oc; +} + +/* Maps syntax highlight token types to terminal colors. */ +int editorSyntaxToColor(int hl) { + switch (hl) { + case HL_COMMENT: + case HL_MLCOMMENT: + return 36; /* cyan */ + case HL_KEYWORD1: + return 33; /* yellow */ + case HL_KEYWORD2: + return 32; /* green */ + case HL_STRING: + return 35; /* magenta */ + case HL_NUMBER: + return 31; /* red */ + case HL_MATCH: + return 34; /* blu */ + default: + return 37; /* white */ + } +} + +/* Select the syntax highlight scheme depending on the filename, + * setting it in the global state E.syntax. */ +void editorSelectSyntaxHighlight(char *filename) { + for (unsigned j = 0; j < HLDB_ENTRIES; j++) { + struct editorSyntax *s = HLDB + j; + unsigned i = 0; + while (s->filematch[i]) { + char *p; + int patlen = strlen(s->filematch[i]); + if ((p = strstr(filename, s->filematch[i])) != NULL) { + if (s->filematch[i][0] != '.' || p[patlen] == '\0') { + E.syntax = s; + return; + } + } + i++; + } + } +} + +/* ======================= Editor rows implementation ======================= */ + +/* Update the rendered version and the syntax highlight of a row. */ +void editorUpdateRow(erow *row) { + int tabs = 0, nonprint = 0, j, idx; + + /* Create a version of the row we can directly print on the screen, + * respecting tabs, substituting non printable characters with '?'. */ + free(row->render); + for (j = 0; j < row->size; j++) + if (row->chars[j] == CTRL('I')) tabs++; + + row->render = malloc(row->size + tabs * 8 + nonprint * 9 + 1); + idx = 0; + for (j = 0; j < row->size; j++) { + if (row->chars[j] == CTRL('I')) { + row->render[idx++] = ' '; + while ((idx + 1) % 8 != 0) row->render[idx++] = ' '; + } else { + row->render[idx++] = row->chars[j]; + } + } + row->rsize = idx; + row->render[idx] = '\0'; + + /* Update the syntax highlighting attributes of the row. */ + /* editorUpdateSyntax(row); */ +} + +/* Insert a row at the specified position, shifting the other rows on the bottom + * if required. */ +void editorInsertRow(int at, char *s, size_t len) { + if (at > E.numrows) return; + E.row = realloc(E.row, sizeof(erow) * (E.numrows + 1)); + if (at != E.numrows) { + memmove(E.row + at + 1, E.row + at, sizeof(E.row[0]) * (E.numrows - at)); + for (int j = at + 1; j <= E.numrows; j++) E.row[j].idx++; + } + E.row[at].size = len; + E.row[at].chars = malloc(len + 1); + memcpy(E.row[at].chars, s, len + 1); + E.row[at].hl = NULL; + E.row[at].hl_oc = 0; + E.row[at].render = NULL; + E.row[at].rsize = 0; + E.row[at].idx = at; + editorUpdateRow(E.row + at); + E.numrows++; + E.dirty++; +} + +/* Free row's heap allocated stuff. */ +void editorFreeRow(erow *row) { + free(row->render); + free(row->chars); + free(row->hl); +} + +/* Remove the row at the specified position, shifting the remainign on the + * top. */ +void editorDelRow(int at) { + erow *row; + + if (at >= E.numrows) return; + row = E.row + at; + editorFreeRow(row); + memmove(E.row + at, E.row + at + 1, sizeof(E.row[0]) * (E.numrows - at - 1)); + for (int j = at; j < E.numrows - 1; j++) E.row[j].idx++; + E.numrows--; + E.dirty++; +} + +/* Turn the editor rows into a single heap-allocated string. + * Returns the pointer to the heap-allocated string and populate the + * integer pointed by 'buflen' with the size of the string, escluding + * the final nulterm. */ +char *editorRowsToString(int *buflen) { + char *buf = NULL, *p; + int totlen = 0; + int j; + + /* Compute count of bytes */ + for (j = 0; j < E.numrows; j++) { + totlen += E.row[j].size + 1; /* +1 is for "\n" at end of every row */ + } + *buflen = totlen; + totlen++; /* Also make space for nulterm */ + + p = buf = malloc(totlen); + for (j = 0; j < E.numrows; j++) { + memcpy(p, E.row[j].chars, E.row[j].size); + p += E.row[j].size; + *p = '\n'; + p++; + } + *p = '\0'; + return buf; +} + +/* Insert a character at the specified position in a row, moving the remaining + * chars on the right if needed. */ +void editorRowInsertChar(erow *row, int at, int c) { + if (at > row->size) { + /* Pad the string with spaces if the insert location is outside the + * current length by more than a single character. */ + int padlen = at - row->size; + /* In the next line +2 means: new char and null term. */ + row->chars = realloc(row->chars, row->size + padlen + 2); + memset(row->chars + row->size, ' ', padlen); + row->chars[row->size + padlen + 1] = '\0'; + row->size += padlen + 1; + } else { + /* If we are in the middle of the string just make space for 1 new + * char plus the (already existing) null term. */ + row->chars = realloc(row->chars, row->size + 2); + memmove(row->chars + at + 1, row->chars + at, row->size - at + 1); + row->size++; + } + row->chars[at] = c; + editorUpdateRow(row); + E.dirty++; +} + +/* Append the string 's' at the end of a row */ +void editorRowAppendString(erow *row, char *s, size_t len) { + row->chars = realloc(row->chars, row->size + len + 1); + memcpy(row->chars + row->size, s, len); + row->size += len; + row->chars[row->size] = '\0'; + editorUpdateRow(row); + E.dirty++; +} + +/* Delete the character at offset 'at' from the specified row. */ +void editorRowDelChar(erow *row, int at) { + if (row->size <= at) return; + memmove(row->chars + at, row->chars + at + 1, row->size - at); + editorUpdateRow(row); + row->size--; + E.dirty++; +} + +/* Insert the specified char at the current prompt position. */ +void editorInsertChar(int c) { + int filerow = E.rowoff + E.cy; + int filecol = E.coloff + E.cx; + erow *row = (filerow >= E.numrows) ? NULL : &E.row[filerow]; + + /* If the row where the cursor is currently located does not exist in our + * logical representaion of the file, add enough empty rows as needed. */ + if (!row) { + while (E.numrows <= filerow) editorInsertRow(E.numrows, "", 0); + } + row = &E.row[filerow]; + editorRowInsertChar(row, filecol, c); + if (E.cx == E.screencols - 1) { + E.coloff++; + } else { + E.cx++; + } + E.dirty++; +} + +/* Inserting a newline is slightly complex as we have to handle inserting a + * newline in the middle of a line, splitting the line as needed. */ +void editorInsertNewline(void) { + int filerow = E.rowoff + E.cy; + int filecol = E.coloff + E.cx; + erow *row = (filerow >= E.numrows) ? NULL : &E.row[filerow]; + + if (!row) { + if (filerow == E.numrows) { + editorInsertRow(filerow, "", 0); + goto fixcursor; + } + return; + } + /* If the cursor is over the current line size, we want to conceptually + * think it's just over the last character. */ + if (filecol >= row->size) filecol = row->size; + if (filecol == 0) { + editorInsertRow(filerow, "", 0); + } else { + /* We are in the middle of a line. Split it between two rows. */ + editorInsertRow(filerow + 1, row->chars + filecol, row->size - filecol); + row = &E.row[filerow]; + row->chars[filecol] = '\0'; + row->size = filecol; + editorUpdateRow(row); + } +fixcursor: + if (E.cy == E.screenrows - 1) { + E.rowoff++; + } else { + E.cy++; + } + E.cx = 0; + E.coloff = 0; +} + +/* Delete the char at the current prompt position. */ +void editorDelChar(void) { + int filerow = E.rowoff + E.cy; + int filecol = E.coloff + E.cx; + erow *row = (filerow >= E.numrows) ? NULL : &E.row[filerow]; + + if (!row || (filecol == 0 && filerow == 0)) return; + if (filecol == 0) { + /* Handle the case of column 0, we need to move the current line + * on the right of the previous one. */ + filecol = E.row[filerow - 1].size; + editorRowAppendString(&E.row[filerow - 1], row->chars, row->size); + editorDelRow(filerow); + row = NULL; + if (E.cy == 0) + E.rowoff--; + else + E.cy--; + E.cx = filecol; + if (E.cx >= E.screencols) { + int shift = (E.screencols - E.cx) + 1; + E.cx -= shift; + E.coloff += shift; + } + } else { + editorRowDelChar(row, filecol - 1); + if (E.cx == 0 && E.coloff) + E.coloff--; + else + E.cx--; + } + if (row) editorUpdateRow(row); + E.dirty++; +} + +/* Load the specified program in the editor memory and returns 0 on success + * or 1 on error. */ +int editorOpen(char *filename) { + FILE *fp; + + E.dirty = 0; + free(E.filename); + E.filename = strdup(filename); + + fp = fopen(filename, "r"); + if (!fp) { + if (errno != ENOENT) { + perror("Opening file"); + exit(1); + } + return 1; + } + + char *line = NULL; + size_t linecap = 0; + ssize_t linelen; + while ((linelen = getline(&line, &linecap, fp)) != -1) { + if (linelen && (line[linelen - 1] == '\n' || line[linelen - 1] == '\r')) + line[--linelen] = '\0'; + editorInsertRow(E.numrows, line, linelen); + } + free(line); + fclose(fp); + E.dirty = 0; + return 0; +} + +#define UNSAFE_SAVES 1 + +/* Save the current file on disk. Return 0 on success, 1 on error. */ +int editorSave(void) { + int len; + char *buf = editorRowsToString(&len); + int64_t fd = open(E.filename, O_RDWR | O_CREAT, 0644); + if (fd == -1) goto writeerr; + + /* Use truncate + a single write(2) call in order to make saving + * a bit safer, under the limits of what we can do in a small editor. */ + if (ftruncate(fd, len) == -1) goto writeerr; + if (write(fd, buf, len) != len) goto writeerr; + + close(fd); + free(buf); + E.dirty = 0; + editorSetStatusMessage("%d bytes written on disk", len); + return 0; + +writeerr: + free(buf); + if (fd != -1) close(fd); + editorSetStatusMessage("Can't save! I/O error: %s", strerror(errno)); + return 1; +} + +/* ============================= Terminal update ============================ */ + +struct abuf { + size_t i, n; + char *p; +}; + +static void abAppend(struct abuf *ab, const char *s, int len) { + concat(ab, s, len); +} + +/* This function writes the whole screen using VT100 escape characters + * starting from the logical state of the editor in the global state 'E'. */ +void editorRefreshScreen(void) { + int y; + erow *r; + char buf[32]; + struct abuf ab; + + memset(&ab, 0, sizeof(ab)); + abAppend(&ab, "\e[?25l", 6); /* Hide cursor. */ + abAppend(&ab, "\e[H", 3); /* Go home. */ + for (y = 0; y < E.screenrows; y++) { + int filerow = E.rowoff + y; + + if (filerow >= E.numrows) { + if (E.numrows == 0 && y == E.screenrows / 3) { + char welcome[80]; + int welcomelen = + snprintf(welcome, sizeof(welcome), + "Kilo editor -- verison %s\e[0K\r\n", KILO_VERSION); + int padding = (E.screencols - welcomelen) / 2; + if (padding) { + abAppend(&ab, "~", 1); + padding--; + } + while (padding--) abAppend(&ab, " ", 1); + abAppend(&ab, welcome, welcomelen); + } else { + abAppend(&ab, "~\e[0K\r\n", 7); + } + continue; + } + + r = &E.row[filerow]; + + int len = r->rsize - E.coloff; + /* int current_color = -1; */ + if (len > 0) { + if (len > E.screencols) len = E.screencols; + char *c = r->render + E.coloff; + /* unsigned char *hl = r->hl + E.coloff; */ + int j; + for (j = 0; j < len; j++) { + /* if (hl[j] == HL_NONPRINT) { */ + /* char sym; */ + /* abAppend(&ab, "\e[7m", 4); */ + /* if (c[j] <= 26) */ + /* sym = '@' + c[j]; */ + /* else */ + /* sym = '?'; */ + /* abAppend(&ab, &sym, 1); */ + /* abAppend(&ab, "\e[0m", 4); */ + /* } else if (hl[j] == HL_NORMAL) { */ + /* if (current_color != -1) { */ + /* abAppend(&ab, "\e[39m", 5); */ + /* current_color = -1; */ + /* } */ + abAppend(&ab, c + j, 1); + /* } else { */ + /* int color = editorSyntaxToColor(hl[j]); */ + /* if (color != current_color) { */ + /* char buf_[16]; */ + /* int clen = snprintf(buf_, sizeof(buf_), "\e[%dm", color); */ + /* current_color = color; */ + /* abAppend(&ab, buf_, clen); */ + /* } */ + /* abAppend(&ab, c + j, 1); */ + /* } */ + } + } + abAppend(&ab, "\e[39m", 5); + abAppend(&ab, "\e[0K", 4); + abAppend(&ab, "\r\n", 2); + } + + /* Create a two rows status. First row: */ + abAppend(&ab, "\e[0K", 4); + abAppend(&ab, "\e[7m", 4); + char status[80], rstatus[80]; + int len = snprintf(status, sizeof(status), "%.20s - %d lines %s", E.filename, + E.numrows, E.dirty ? "(modified)" : ""); + int rlen = snprintf(rstatus, sizeof(rstatus), "%d/%d", E.rowoff + E.cy + 1, + E.numrows); + if (len > E.screencols) len = E.screencols; + abAppend(&ab, status, len); + while (len < E.screencols) { + if (E.screencols - len == rlen) { + abAppend(&ab, rstatus, rlen); + break; + } else { + abAppend(&ab, " ", 1); + len++; + } + } + abAppend(&ab, "\e[0m\r\n", 6); + + /* Second row depends on E.statusmsg and the status message update time. */ + abAppend(&ab, "\e[0K", 4); + int msglen = strlen(E.statusmsg); + if (msglen && time(NULL) - E.statusmsg_time < 5) + abAppend(&ab, E.statusmsg, msglen <= E.screencols ? msglen : E.screencols); + + /* Put cursor at its current position. Note that the horizontal position + * at which the cursor is displayed may be different compared to 'E.cx' + * because of TABs. */ + int j; + int cx = 1; + int filerow = E.rowoff + E.cy; + erow *row = (filerow >= E.numrows) ? NULL : &E.row[filerow]; + if (row) { + for (j = E.coloff; j < (E.cx + E.coloff); j++) { + if (j < row->size && row->chars[j] == CTRL('I')) cx += 7 - ((cx) % 8); + cx++; + } + } + snprintf(buf, sizeof(buf), "\e[%d;%dH", E.cy + 1, cx); + abAppend(&ab, buf, strlen(buf)); + abAppend(&ab, "\e[?25h", 6); /* Show cursor. */ + write(STDOUT_FILENO, ab.p, ab.i); + free(ab.p); +} + +/* Set an editor status message for the second line of the status, at the + * end of the screen. */ +void editorSetStatusMessage(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + vsnprintf(E.statusmsg, sizeof(E.statusmsg), fmt, ap); + va_end(ap); + E.statusmsg_time = time(NULL); +} + +/* =============================== Find mode ================================ */ + +#define KILO_QUERY_LEN 256 + +void editorFind(int64_t fd) { + char query[KILO_QUERY_LEN + 1] = {0}; + int qlen = 0; + int last_match = -1; /* Last line where a match was found. -1 for none. */ + int find_next = 0; /* if 1 search next, if -1 search prev. */ + int saved_hl_line = -1; /* No saved HL */ + char *saved_hl = NULL; + +#define FIND_RESTORE_HL \ + do { \ + if (saved_hl) { \ + memcpy(E.row[saved_hl_line].hl, saved_hl, E.row[saved_hl_line].rsize); \ + saved_hl = NULL; \ + } \ + } while (0) + + /* Save the cursor position in order to restore it later. */ + int saved_cx = E.cx, saved_cy = E.cy; + int saved_coloff = E.coloff, saved_rowoff = E.rowoff; + + while (1) { + editorSetStatusMessage("Search: %s (Use ESC/Arrows/Enter)", query); + editorRefreshScreen(); + + int c = editorReadKey(fd); + if (c == DEL_KEY || c == CTRL('H') || c == CTRL('?')) { + if (qlen != 0) query[--qlen] = '\0'; + last_match = -1; + } else if (c == CTRL('G')) { + break; + } else if (c == CTRL('[') || c == CTRL('M')) { + if (c == CTRL('[')) { + E.cx = saved_cx; + E.cy = saved_cy; + E.coloff = saved_coloff; + E.rowoff = saved_rowoff; + } + FIND_RESTORE_HL; + editorSetStatusMessage(""); + return; + } else if (c == ARROW_RIGHT || c == ARROW_DOWN) { + find_next = 1; + } else if (c == ARROW_LEFT || c == ARROW_UP) { + find_next = -1; + } else if (isprint(c)) { + if (qlen < KILO_QUERY_LEN) { + query[qlen++] = c; + query[qlen] = '\0'; + last_match = -1; + } + } + + /* Search occurrence. */ + if (last_match == -1) find_next = 1; + if (find_next) { + char *match = NULL; + int match_offset = 0; + int i, current = last_match; + + for (i = 0; i < E.numrows; i++) { + current += find_next; + if (current == -1) + current = E.numrows - 1; + else if (current == E.numrows) + current = 0; + match = strstr(E.row[current].render, query); + if (match) { + match_offset = match - E.row[current].render; + break; + } + } + find_next = 0; + + /* Highlight */ + FIND_RESTORE_HL; + + if (match) { + erow *row = &E.row[current]; + last_match = current; + if (row->hl) { + saved_hl_line = current; + saved_hl = malloc(row->rsize); + memcpy(saved_hl, row->hl, row->rsize); + memset(row->hl + match_offset, HL_MATCH, qlen); + } + E.cy = 0; + E.cx = match_offset; + E.rowoff = current; + E.coloff = 0; + /* Scroll horizontally as needed. */ + if (E.cx > E.screencols) { + int diff = E.cx - E.screencols; + E.cx -= diff; + E.coloff += diff; + } + } + } + } +} + +/* ========================= Editor events handling ======================== */ + +/* Handle cursor position change because arrow keys were pressed. */ +void editorMoveCursor(int key) { + int filerow = E.rowoff + E.cy; + int filecol = E.coloff + E.cx; + int rowlen; + erow *row = (filerow >= E.numrows) ? NULL : &E.row[filerow]; + + switch (key) { + case ARROW_LEFT: + if (E.cx == 0) { + if (E.coloff) { + E.coloff--; + } else { + if (filerow > 0) { + E.cy--; + E.cx = E.row[filerow - 1].size; + if (E.cx > E.screencols - 1) { + E.coloff = E.cx - E.screencols + 1; + E.cx = E.screencols - 1; + } + } + } + } else { + E.cx -= 1; + } + break; + case ARROW_RIGHT: + if (row && filecol < row->size) { + if (E.cx == E.screencols - 1) { + E.coloff++; + } else { + E.cx += 1; + } + } else if (row && filecol == row->size) { + E.cx = 0; + E.coloff = 0; + if (E.cy == E.screenrows - 1) { + E.rowoff++; + } else { + E.cy += 1; + } + } + break; + case ARROW_UP: + if (E.cy == 0) { + if (E.rowoff) E.rowoff--; + } else { + E.cy -= 1; + } + break; + case ARROW_DOWN: + if (filerow < E.numrows) { + if (E.cy == E.screenrows - 1) { + E.rowoff++; + } else { + E.cy += 1; + } + } + break; + } + /* Fix cx if the current line has not enough chars. */ + filerow = E.rowoff + E.cy; + filecol = E.coloff + E.cx; + row = (filerow >= E.numrows) ? NULL : &E.row[filerow]; + rowlen = row ? row->size : 0; + if (filecol > rowlen) { + E.cx -= filecol - rowlen; + if (E.cx < 0) { + E.coloff += E.cx; + E.cx = 0; + } + } +} + +/* Process events arriving from the standard input, which is, the user + * is typing stuff on the terminal. */ +#define KILO_QUIT_TIMES 3 +void editorProcessKeypress(int64_t fd) { + /* When the file is modified, requires Ctrl-q to be pressed N times + * before actually quitting. */ + static int quit_times; + + int c = editorReadKey(fd); + switch (c) { + case CTRL('M'): /* Enter */ + editorInsertNewline(); + break; + case CTRL('C'): /* Ctrl-c */ + /* We ignore ctrl-c, it can't be so simple to lose the changes + * to the edited file. */ + break; + case CTRL('Q'): /* Ctrl-q */ + /* Quit if the file was already saved. */ + if (E.dirty && quit_times < KILO_QUIT_TIMES) { + editorSetStatusMessage("WARNING!!! File has unsaved changes. " + "Press Ctrl-Q %d more times to quit.", + KILO_QUIT_TIMES - quit_times); + quit_times++; + return; + } + exit(0); + break; + + case CTRL('U'): + case CTRL('X'): { + int c2 = editorReadKey(fd); + switch (c2) { + case CTRL('S'): + editorSave(); + break; + case CTRL('C'): + /* Erase in Display (ED): Clear from cursor to end of screen. */ + write(STDOUT_FILENO, "\r\e[0J", 5); + exit(0); + break; + default: /* ignore */ + break; + } + break; + } + + case CTRL('S'): + editorFind(fd); + break; + case CTRL('D'): /* Delete */ + case DEL_KEY: + editorMoveCursor(ARROW_RIGHT); + case CTRL('?'): /* Backspace */ + case CTRL('H'): + editorDelChar(); + break; + + case CTRL('K'): { /* Kill Line */ + int oldcx = E.cx; + do { + editorMoveCursor(ARROW_RIGHT); + } while (E.cx); + editorMoveCursor(ARROW_LEFT); + if (E.cx) { + /* non-empty line: preserve row */ + while (E.cx > oldcx) { + editorDelChar(); + } + } else { + /* empty line: remove row */ + editorMoveCursor(ARROW_RIGHT); + editorDelChar(); + } + break; + } + + case PAGE_UP: + case PAGE_DOWN: + if (c == PAGE_UP && E.cy != 0) { + E.cy = 0; + } else if (c == PAGE_DOWN && E.cy != E.screenrows - 1) { + E.cy = E.screenrows - 1; + } + { + int times = E.screenrows; + while (times--) editorMoveCursor(c == PAGE_UP ? ARROW_UP : ARROW_DOWN); + } + break; + + case HOME_KEY: + case CTRL('A'): + while (E.cx) editorMoveCursor(ARROW_LEFT); + break; + case END_KEY: + case CTRL('E'): + do { + editorMoveCursor(ARROW_RIGHT); + } while (E.cx); + editorMoveCursor(ARROW_LEFT); + break; + + case CTRL('P'): + editorMoveCursor(ARROW_UP); + break; + case CTRL('N'): + editorMoveCursor(ARROW_DOWN); + break; + case CTRL('B'): + editorMoveCursor(ARROW_LEFT); + break; + case CTRL('F'): + editorMoveCursor(ARROW_RIGHT); + break; + + case ARROW_UP: + case ARROW_DOWN: + case ARROW_LEFT: + case ARROW_RIGHT: + editorMoveCursor(c); + break; + + case CTRL('L'): /* ctrl+l, clear screen */ + /* Just refresht the line as side effect. */ + break; + case CTRL('['): + /* Nothing to do for ESC in this mode. */ + break; + default: + editorInsertChar(c); + break; + } + + quit_times = 0; /* Reset it to the original value. */ +} + +int editorFileWasModified(void) { + return E.dirty; +} + +void initEditor(void) { + E.cx = 0; + E.cy = 0; + E.rowoff = 0; + E.coloff = 0; + E.numrows = 0; + E.row = NULL; + E.dirty = 0; + E.filename = NULL; + E.syntax = NULL; + if (getWindowSize(STDIN_FILENO, STDOUT_FILENO, &E.screenrows, + &E.screencols) == -1) { + perror("Unable to query the screen for size (columns / rows)"); + exit(1); + } + E.screenrows -= 2; /* Get room for status bar. */ +} + +int main(int argc, char **argv) { + showcrashreports(); + if (argc != 2) { + fprintf(stderr, "Usage: kilo \n"); + exit(1); + } + + initEditor(); + editorSelectSyntaxHighlight(argv[1]); + editorOpen(argv[1]); + enableRawMode(STDIN_FILENO); + editorSetStatusMessage("HELP: Ctrl-S = save | Ctrl-Q = quit | Ctrl-F = find"); + while (1) { + editorRefreshScreen(); + editorProcessKeypress(STDIN_FILENO); + } + return 0; +} diff --git a/examples/life.c b/examples/life.c new file mode 100644 index 00000000..5e8dfe9c --- /dev/null +++ b/examples/life.c @@ -0,0 +1,11 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif + +int main() { return 42; } diff --git a/examples/mappy.c b/examples/mappy.c new file mode 100644 index 00000000..25ac396e --- /dev/null +++ b/examples/mappy.c @@ -0,0 +1,49 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/macros.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" + +/* + OpenBSD + 00025ff61000 000000000000 65536 + 00026cf1d000 00000cfbc000 65536 + 000254d83000 ffffe7e66000 65536 + 0002c7bde000 000072e5b000 65536 + 000253ff9000 ffff8c41b000 65536 + 0002e96f3000 0000956fa000 65536 + 000236346000 ffff4cc53000 65536 + 0002ce744000 0000983fe000 65536 + 0002fe0b8000 00002f974000 65536 + 000225cd7000 ffff27c1f000 65536 +*/ + +struct Mapping { + uint8_t *map; + size_t mapsize; +}; + +int main(int argc, char *argv[]) { + size_t i; + struct Mapping m[10]; + for (i = 0; i < ARRAYLEN(m); ++i) { + m[i].mapsize = FRAMESIZE; + m[i].map = mmap(NULL, m[i].mapsize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + } + for (i = 0; i < ARRAYLEN(m); ++i) { + printf("%p %p %zu\n", m[i].map, i ? m[i].map - m[i - 1].map : 0, + m[i].mapsize); + } + return 0; +} diff --git a/examples/now.c b/examples/now.c new file mode 100644 index 00000000..eeaa0022 --- /dev/null +++ b/examples/now.c @@ -0,0 +1,34 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/dce.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/clock.h" +#include "libc/time/time.h" +#include "third_party/dtoa/dtoa.h" + +char dtoabuf_[3][32]; + +static long double avg; + +int main(int argc, char *argv[]) { + long double t2, t1 = nowl(); + dsleep(0.3); + for (;;) { + t2 = nowl(); + printf("%s %s avg=%s\n", g_fmt(dtoabuf_[0], t2), + g_fmt(dtoabuf_[1], t2 - t1), g_fmt(dtoabuf_[2], avg)); + t1 = t2; + dsleep(0.3); + } + return 0; +} diff --git a/examples/ntdll.c b/examples/ntdll.c new file mode 100644 index 00000000..0e71e2d4 --- /dev/null +++ b/examples/ntdll.c @@ -0,0 +1,37 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/dce.h" +#include "libc/nt/dll.h" +#include "libc/nt/nt/process.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/exit.h" + +int main() { + if (IsWindows()) { + /* + * Cosmopolitan imports this automatically if it's referenced the + * normal way. But Microsoft wants us to use loose coupling when + * referencing their internal APIs. Don't think for a moment they + * won't break open source projects that fail to heed the warning. + */ + typeof(NtTerminateProcess) *NtTerminateProcess_ = + GetProcAddress(GetModuleHandle("ntdll.dll"), "NtTerminateProcess"); + printf("%ld\n", GetModuleHandle("ntdll.dll")); + printf("%p\n", NtTerminateProcess_); + if (NtTerminateProcess_) { + fflush(stdout); + for (;;) NtTerminateProcess_(-1, 42); + } + } else { + fprintf(stderr, "error: intended for windows\n"); + } + return EXIT_FAILURE; +} diff --git a/examples/peek.c b/examples/peek.c new file mode 100644 index 00000000..7d368786 --- /dev/null +++ b/examples/peek.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/runtime/interruptiblecall.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/sig.h" + +struct InterruptibleCall icall; + +static intptr_t peek(intptr_t *addr) { return *addr; } + +int main(int argc, char *argv[]) { + int i; + for (i = 1; i < argc; ++i) { + intptr_t addr = strtoul(argv[i], NULL, 0); + icall.sig = SIGSEGV; + printf("%#p → %#lx\n", addr, + interruptiblecall(&icall, (void *)peek, addr, 0, 0, 0)); + } + return 0; +} diff --git a/examples/pipe.c b/examples/pipe.c new file mode 100644 index 00000000..05e08b4f --- /dev/null +++ b/examples/pipe.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/stdio/stdio.h" + +int main(int argc, char *argv[]) { + int pipefds[2] = {-1, -1}; + int rc = pipe(pipefds); + printf("%d → %ld %ld\n", rc, pipefds[0], pipefds[1]); + return 0; +} diff --git a/examples/poll.c b/examples/poll.c new file mode 100644 index 00000000..728dc509 --- /dev/null +++ b/examples/poll.c @@ -0,0 +1,26 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/bits/bits.h" +#include "libc/macros.h" +#include "libc/sock/sock.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/poll.h" + +int main(int argc, char *argv[]) { + int rc; + int pollms = 1; + struct pollfd fds[] = {{-1, 0}, {STDIN_FILENO, POLLIN}}; + if ((rc = poll(fds, ARRAYLEN(fds), pollms)) != -1) { + printf("toto=%d\n", rc); + return 0; + } + return 0; +} diff --git a/examples/printargs.c b/examples/printargs.c new file mode 100644 index 00000000..c3648a01 --- /dev/null +++ b/examples/printargs.c @@ -0,0 +1,73 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/bits/progn.h" +#include "libc/log/log.h" +#include "libc/macros.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/auxv.h" + +const struct AuxiliaryValue { + const char *fmt; + long *id; + const char *name; + const char *description; +} kAuxiliaryValues[] = { + {"%p", &AT_EXECFD, "AT_EXECFD", "file descriptor of program"}, + {"%p", &AT_PHDR, "AT_PHDR", "address of elf program headers"}, + {"%p", &AT_PHENT, "AT_PHENT", "size of program header entry"}, + {"%p", &AT_PHNUM, "AT_PHNUM", "number of program headers"}, + {"%p", &AT_PAGESZ, "AT_PAGESZ", "system page size"}, + {"%p", &AT_BASE, "AT_BASE", "base address of the program interpreter"}, + {"%p", &AT_ENTRY, "AT_ENTRY", "entry address of executable"}, + {"%p", &AT_NOTELF, "AT_NOTELF", "set if not an elf"}, + {"%-12d", &AT_UID, "AT_UID", "real user id of thread"}, + {"%-12d", &AT_EUID, "AT_EUID", "effective user id of thread"}, + {"%-12d", &AT_GID, "AT_GID", "real group id of thread"}, + {"%-12d", &AT_EGID, "AT_EGID", "effective group id of thread"}, + {"%-12d", &AT_CLKTCK, "AT_CLKTCK", "frequency of times() counts"}, + {"%p", &AT_OSRELDATE, "AT_OSRELDATE", + "freebsd release number, e.g. 1200086"}, + {"%p", &AT_PLATFORM, "AT_PLATFORM", "string identifying hardware platform"}, + {"%p", &AT_DCACHEBSIZE, "AT_DCACHEBSIZE", "data cache block size"}, + {"%p", &AT_ICACHEBSIZE, "AT_ICACHEBSIZE", "instruction cache block size"}, + {"%p", &AT_UCACHEBSIZE, "AT_UCACHEBSIZE", "unified cache block size"}, + {"%p", &AT_SECURE, "AT_SECURE", "for set{u,g}id binz & security blankets"}, + {"%-12s", &AT_BASE_PLATFORM, "AT_BASE_PLATFORM", + "string identifying real platform"}, + {"%p", &AT_RANDOM, "AT_RANDOM", "address of sixteen random bytes"}, + {"%-12s", &AT_EXECFN, "AT_EXECFN", "pathname used to execute program"}, + {"%p", &AT_SYSINFO_EHDR, "AT_SYSINFO_EHDR", + "linux virtual dso page address"}, +}; + +int main(int argc, char *argv[], char **envp) { + printf("\nArguments:\n"); + for (unsigned i = 0; i < argc; ++i) { + printf(" ☼ %s\n", argv[i]); + } + printf("\nEnvironment:\n"); + for (char **env = envp; *env; ++env) { + printf(" ☼ %s\n", *env); + } + printf("\nAuxiliary Values:\n"); + for (unsigned i = 0; i < ARRAYLEN(kAuxiliaryValues); ++i) { + long key = *kAuxiliaryValues[i].id; + unsigned long val = getauxval(key); + char fmt[64]; + printf(PROGN(stpcpy(stpcpy(stpcpy(fmt, "%16s[%p] = "), + kAuxiliaryValues[i].fmt), + " # %s\n"), + fmt), + kAuxiliaryValues[i].name, key, val, kAuxiliaryValues[i].description); + } + return 0; +} diff --git a/examples/printmysymbols.c b/examples/printmysymbols.c new file mode 100644 index 00000000..759251d7 --- /dev/null +++ b/examples/printmysymbols.c @@ -0,0 +1,34 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/calls/calls.h" +#include "libc/elf/elf.h" +#include "libc/log/log.h" +#include "libc/runtime/symbols.h" +#include "libc/stdio/stdio.h" + +int main(int argc, char *argv[]) { + int rc = 0; + char *filename; + struct SymbolTable *tab = NULL; + if ((filename = finddebugbinary()) != NULL && + (tab = opensymboltable(filename))) { + for (unsigned i = 0; i < tab->count; ++i) { + printf("%p %s\n", tab->addr_base + tab->symbols[i].addr_rva, + getelfstring(tab->elf, tab->elfsize, tab->name_base, + tab->symbols[i].name_rva)); + } + } else { + perror("printmysymbols"); + backtrace(stderr); + rc = 1; + } + closesymboltable(&tab); + return rc; +} diff --git a/examples/printprimes.c b/examples/printprimes.c new file mode 100644 index 00000000..61fafbf1 --- /dev/null +++ b/examples/printprimes.c @@ -0,0 +1,39 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/conv/itoa.h" +#include "libc/math.h" +#include "libc/stdio/stdio.h" + +int main(int argc, char *argv[]) { + char buf[32]; + bool isprime; + long i, j, k, n, m; + k = 0; + n = pow(2, 32); + printf("2\n"); + for (i = 3; i < n; ++i) { + isprime = true; + for (m = sqrt(i) + 1, j = 2; j < m; ++j) { + if (i % j == 0) { + isprime = false; + break; + } + } + if (isprime) { + int64toarray_radix10(i, buf); + fputs(buf, stdout); + fputc('\n', stdout); + if (k++ % 100 == 0) { + fprintf(stderr, "\r%20d", i); + } + } + } + return 0; +} diff --git a/examples/raw-linux-hello.S b/examples/raw-linux-hello.S new file mode 100644 index 00000000..356a4567 --- /dev/null +++ b/examples/raw-linux-hello.S @@ -0,0 +1,49 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +/ Raw Linux Assembly Binary Tutorial +/ +/ i.e. how to not use cosmopolitan runtimes at all +/ cosmopolitan basically abstracts this +/ except for all major platforms +/ +/ make o//examples/raw-linux-hello.elf +/ o//examples/raw-linux-hello.elf # about 6kb +/ +/ Next consider doing it in C with fancy build tuning +/ +/ make -j8 -O \ +/ MODE=tiny \ +/ LDFLAGS=-s \ +/ CPPFLAGS=-DSUPPORT_VECTOR=0b00000001 \ +/ o/tiny/examples/hello2.elf +/ o/tiny/examples/hello2.elf # about 8kb +/ +/ @noreturn +_start: mov $12,%rdx # arg no. 3 is length + getstr "hello world\n",%rsi,%esi # arg no. 2 is memory + mov $1,%edi # arg no. 1 is stdout + mov $1,%eax # write() + syscall # see libc/sysv/syscalls.sh + mov $0,%edi # arg no. 1 is success status + mov $0xE7,%eax # exit_group() + syscall + .endfn _start,globl diff --git a/examples/rawmode.c b/examples/rawmode.c new file mode 100644 index 00000000..0bfcc799 --- /dev/null +++ b/examples/rawmode.c @@ -0,0 +1,26 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "dsp/tty/tty.h" +#include "libc/log/log.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/time/time.h" + +int main(int argc, char *argv[]) { + setenv("GDB", "nopenopenope", true); + showcrashreports(); + ttyraw(kTtyLfToCrLf | kTtySigs); + printf("hi\n"), sleep(1); + if (argc > 1 && strstr(argv[1], "crash")) abort(); + printf("there\n"), sleep(1); + return 0; +} diff --git a/examples/rusage.c b/examples/rusage.c new file mode 100644 index 00000000..0bc0c181 --- /dev/null +++ b/examples/rusage.c @@ -0,0 +1,60 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/calls/calls.h" +#include "libc/calls/hefty/spawn.h" +#include "libc/calls/struct/rusage.h" +#include "libc/log/check.h" +#include "libc/log/log.h" +#include "libc/math.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/time/time.h" + +void Show(const char *name, long measurement, const char *unit) { + fprintf(stderr, "%-*s%,*d %s\n", 32, name, 32, measurement, unit); +} + +long TvToUs(struct timeval tv) { + return 1000000l * tv.tv_usec + tv.tv_sec; +} + +int main(int argc, char *argv[]) { + const char *exe; + int pid, wstatus; + long double ts1, ts2; + struct rusage rusage; + memset(&rusage, -1, sizeof(rusage)); + CHECK_GT(argc, 1); + CHECK_NOTNULL((exe = commandv(argv[1]))); + ts1 = nowl(); + CHECK_NE(-1, (pid = spawnve(0, NULL, exe, &argv[1], environ))); + CHECK_NE(-1, wait4(pid, &wstatus, 0, &rusage)); + ts2 = nowl(); + Show("wall time", lroundl((ts2 - ts1) * 1e9l), "ns"); + Show("user time", TvToUs(rusage.ru_utime), "µs"); + Show("sys time", TvToUs(rusage.ru_stime), "µs"); + Show("maximum resident set size", rusage.ru_maxrss, ""); + Show("integral shared memory size", rusage.ru_ixrss, ""); + Show("integral unshared data size", rusage.ru_idrss, ""); + Show("integral unshared stack size", rusage.ru_isrss, ""); + Show("minor page faults", rusage.ru_minflt, ""); + Show("major page faults", rusage.ru_majflt, ""); + Show("swaps", rusage.ru_nswap, ""); + Show("block input ops", rusage.ru_inblock, ""); + Show("block output ops", rusage.ru_oublock, ""); + Show("ipc messages sent", rusage.ru_msgsnd, ""); + Show("ipc messages received", rusage.ru_msgrcv, ""); + Show("signals received", rusage.ru_nsignals, ""); + Show("voluntary context switches", rusage.ru_nvcsw, ""); + Show("involuntary context switches", rusage.ru_nivcsw, ""); + return WEXITSTATUS(wstatus); +} diff --git a/examples/stat.c b/examples/stat.c new file mode 100644 index 00000000..17815ccb --- /dev/null +++ b/examples/stat.c @@ -0,0 +1,61 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/calls/calls.h" +#include "libc/calls/struct/stat.h" +#include "libc/errno.h" +#include "libc/fmt/fmt.h" +#include "libc/runtime/gc.h" +#include "libc/stdio/stdio.h" +#include "libc/x/x.h" + +/** + * @fileoverview File metadata viewer. + * + * This demonstrates the more powerful aspects of the printf() DSL. + */ + +void PrintFileMetadata(const char *pathname, struct stat *st) { + printf("\n%s:", pathname); + if (stat(pathname, st) != -1) { + printf( + "\n" + "%-32s%,ld\n" + "%-32s%,ld\n" + "%-32s%#lx\n" + "%-32s%#lx\n" + "%-32s%ld\n" + "%-32s%#o\n" + "%-32s%d\n" + "%-32s%d\n" + "%-32s%d\n" + "%-32s%ld\n" + "%-32s%s\n" + "%-32s%s\n" + "%-32s%s\n", + "bytes in file", st->st_size, "physical bytes", st->st_blocks * 512, + "device id w/ file", st->st_dev, "inode", st->st_ino, "hard link count", + st->st_nlink, "mode / permissions", st->st_mode, "owner id", st->st_uid, + "group id", st->st_gid, "device id (if special)", st->st_rdev, + "block size", st->st_blksize, "access time", gc(xiso8601(&st->st_atim)), + "modified time", gc(xiso8601(&st->st_mtim)), "c[omplicated]time", + gc(xiso8601(&st->st_ctim))); + } else { + printf(" %s\n", strerror(errno)); + } +} + +int main(int argc, char *argv[]) { + size_t i; + struct stat st; + for (i = 1; i < argc; ++i) { + PrintFileMetadata(argv[i], &st); + } + return 0; +} diff --git a/examples/subprocess.c b/examples/subprocess.c new file mode 100644 index 00000000..3696eb46 --- /dev/null +++ b/examples/subprocess.c @@ -0,0 +1,60 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/alg/alg.h" +#include "libc/calls/calls.h" +#include "libc/calls/hefty/spawn.h" +#include "libc/conv/conv.h" +#include "libc/limits.h" +#include "libc/log/check.h" +#include "libc/runtime/gc.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/x/x.h" + +const char kProgram[] = "o/default/examples/hello.com"; + +int main(int argc, char *argv[]) { + /** + * Runs make if hello.com doesn't exist. + * + * 1. gc() automates calling free() on return. + * 2. xasprintf("foo %s", "bar") is our version of "foo %s" % ("bar") + * 3. Demonstrates correct escaping for bourne shell cf. xaescapeshq() + */ + if (!fileexists(kProgram)) { + system(gc(xasprintf("%s '%s'", "make -j4", + gc(replacestr(kProgram, "'", "'\"'\"'"))))); + } + + /** + * Our version of subprocess.Popen + * 1. Doesn't require fork() so pain-free on NT + * 2. Google checks are like assert() but better + */ + ssize_t transferred; + int child, wstatus, procfds[3] = {STDIN_FILENO, -1, STDERR_FILENO}; + CHECK_NE(-1, + (child = spawnve(0, procfds, /* run w/o shell */ kProgram, + (char *const[]){/* argv[0] */ basename(kProgram), + /* argv[1] */ "boop", + /* sentinel */ NULL}, + environ))); + printf("%s %s: ", kProgram, "says"); + fflush(stdout); + for (;;) { + transferred = copyfd(procfds[1], NULL, fileno(stdout), NULL, INT_MAX, 0); + CHECK_NE(-1, transferred); + if (!transferred) break; + } + CHECK_NE(-1, waitpid(child, &wstatus, 0)); + CHECK_EQ(0, WEXITSTATUS(wstatus)); + + return 0; +} diff --git a/examples/ttyinfo.c b/examples/ttyinfo.c new file mode 100644 index 00000000..bbab0dca --- /dev/null +++ b/examples/ttyinfo.c @@ -0,0 +1,108 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "dsp/tty/tty.h" +#include "libc/calls/calls.h" +#include "libc/calls/ioctl.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/calls/termios.h" +#include "libc/errno.h" +#include "libc/fmt/fmt.h" +#include "libc/log/check.h" +#include "libc/log/log.h" +#include "libc/runtime/gc.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/exit.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/sig.h" +#include "libc/sysv/consts/termios.h" +#include "libc/x/x.h" + +/* + "\e[c" → "\e[?1;2c" + "\e[x" → "\e[2;1;1;112;112;1;0x" + "\e[>c" → "\e[>83;40500;0c" + "\e[6n" → "\e[52;1R" +*/ + +#define CTRL(C) ((C) ^ 0b01000000) +#define PROBE_VT100 "\e[c" /* e.g. "\e[?1;2c", "\e[>0c" */ +#define PROBE_SECONDARY "\e[>c" /* "\e[>83;40500;0c" (Screen v4.05.00) */ +#define PROBE_PARAMETERS "\e[x" /* e.g. "\e[2;1;1;112;112;1;0x" */ +#define PROBE_CURSOR_POSITION "\e[6n" /* e.g. "\e[𝑦;𝑥R" */ +#define PROBE_SUN_DTTERM_SIZE "\e[14t" /* e.g. "\e[𝑦;𝑥R" */ + +int fd_; +jmp_buf jb_; +ssize_t got_; +uint8_t buf_[128]; +struct TtyIdent ti_; +struct winsize wsize_; +volatile bool resized_; + +void OnResize(void) { + resized_ = true; +} +void OnKilled(int sig) { + longjmp(jb_, 128 + sig + 1); +} + +void getsome(void) { + if ((got_ = read(fd_, buf_, sizeof(buf_))) == -1 && errno != EINTR) { + printf("%s%s\r\n", "error: ", strerror(errno)); + longjmp(jb_, EXIT_FAILURE + 1); + } + if (got_ >= 0) { + printf("%`'.*s\r\n", got_, buf_); + if (got_ > 0 && buf_[0] == CTRL('C')) { + longjmp(jb_, EXIT_SUCCESS + 1); + } + } + if (resized_) { + CHECK_NE(-1, getttysize(fd_, &wsize_)); + printf("SIGWINCH → %hu×%hu\r\n", wsize_.ws_row, wsize_.ws_col); + resized_ = false; + } +} + +void probe(const char *s) { + printf("%`'s → ", s); + write(fd_, s, strlen(s)); + getsome(); +} + +int main(int argc, char *argv[]) { + int rc; + char ttyname[64]; + struct termios old; + CHECK_NE(-1, (fd_ = open("/dev/tty", O_RDWR))); + CHECK_NE(-1, ttyconfig(fd_, ttysetrawmode, 0, &old)); + if (!(rc = setjmp(jb_))) { + xsigaction(SIGTERM, OnKilled, 0, 0, NULL); + xsigaction(SIGWINCH, OnResize, 0, 0, NULL); + if (ttyident(&ti_, STDIN_FILENO, STDOUT_FILENO) != -1) { + ttysendtitle(fd_, "justine was here", &ti_); + fputs(ttydescribe(ttyname, sizeof(ttyname), &ti_), stdout); + } + fputs("\r\n", stdout); + probe(PROBE_VT100); + probe(PROBE_SECONDARY); + probe(PROBE_PARAMETERS); + probe(PROBE_CURSOR_POSITION); + /* probe(PROBE_SUN_DTTERM_SIZE); */ + getsome(); + for (;;) getsome(); + } + ttyrestore(fd_, &old); + ttyidentclear(&ti_); + return rc - 1; +} diff --git a/examples/uname.c b/examples/uname.c new file mode 100644 index 00000000..6fd32d0e --- /dev/null +++ b/examples/uname.c @@ -0,0 +1,67 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/log/log.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/calls/struct/utsname.h" +#include "libc/calls/calls.h" +#include "libc/sysv/consts/exit.h" +#include "third_party/getopt/getopt.h" + +int main(int argc, char *argv[]) { + unsigned need = 0; + int opt; + while ((opt = getopt(argc, argv, "hasnrvmd")) != -1) { + switch (opt) { + case 'a': + need |= 0b111111; + break; + case 's': + need |= 0b000001; + break; + case 'n': + need |= 0b000010; + break; + case 'r': + need |= 0b000100; + break; + case 'v': + need |= 0b001000; + break; + case 'm': + need |= 0b010000; + break; + case 'd': + need |= 0b100000; + break; + default: /* -? or -h */ + fprintf(stderr, "%s: %s [%s]\n%s", "Usage", argv[0], "FLAGS", + " -a\tprint all\n" + " -s\tprint sysname\n" + " -n\tprint nodename\n" + " -r\tprint release\n" + " -v\tprint version\n" + " -m\tprint machine\n" + " -d\tprint domainname\n"); + exit(EXIT_FAILURE); + } + } + if (!need) need = 0b000001; + struct utsname data; + if (uname(&data) == -1) perror("uname"), exit(EXIT_FAILURE); + if (need & 0b000001) printf("%s ", data.sysname); + if (need & 0b000010) printf("%s ", data.nodename); + if (need & 0b000100) printf("%s ", data.release); + if (need & 0b001000) printf("%s ", data.version); + if (need & 0b010000) printf("%s ", data.machine); + if (need & 0b100000) printf("%s ", data.domainname); + printf("\n"); + return 0; +} diff --git a/examples/unbourne.c b/examples/unbourne.c new file mode 100644 index 00000000..27671dfb --- /dev/null +++ b/examples/unbourne.c @@ -0,0 +1,10822 @@ +/*bin/echo ' #-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;coding:utf-8 -*-┤ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +├──────────────────────────────────────────────────────────────────────────────┤ +│███▒ ▓░░░▒ █▓█▓ ▒▒███████▓█████ ██▓▓▓███▒██▒▓█▓████████ ▓██▓█████▓██ ░ ░▒ ░ │ +│█░ ░ █░▒▒▒ █▓▓▓ ▒▓████▓░███▓█▓▓▓▓█▓▒▓▓███▓▒▒██▓▓█▓█████ ▒██▓█████▓██ ░ ▒░░░ ░│ +│███▓ ▒ ▓██▓ █████▓░█▓▓█▓██░░█░████▓█▓██▒██▒▓▓▓█▓▓█▓█▒██▓█████▓██░▒ ▓░ │ +│████ █▓ ▒███▓██████████████████████████████▓▓█▓█████▓████████▓██ ▒▓▓▓▒░▒ ░│ +│███▓ ▓▓▓▓ ▒███████████▓████████████▓▓██▓▓▓█▓████▓███▓█████▓██ ▒░▓▒░░ ░│ +│███▓ █▒▓▒▒░▓ ▒██▓████████████████████████████▓██▓▓████████▓██ ░░▒▒▓▓▒ ░│ +│███▓ ▓▒▓▓▓ █▓▓ ▒███████████████████████████▓██▓▓░███████▓██ ░ ▒▒░░▓▓░│ +│█▓█▓ █▒░░░ █▓██▓ ██████████████████████████▓█████████▓▓░░░ ▒░ ░░ ▒│ +│█▓█▓░█▓▒▓▒ ██▓█▓ ▓ ▓██████████████████▒██▓████████ ▒░▒▒▒▒▒▒▒ ░│ +│█▓▓▒░▓▓▒▓▓ █▓▓██ ██ ░ ░ ░░░░ ░░░ ░ ███████████████▓██▓██████ ░▒▓▓▒▓▓░▒▓░▒░ │ +│██▓▓░▓▒▒▓▒░▓▓▓▓▓ █▓▓░ ░ ░░ ░ ░ ▓█████████████▒██▓████▒▒▒░░▓▓▒▓▒░▒░░▒░ ░│ +│█▓▓▓░█▒▒▒▒ █▓▓▓▓ ██▓▓ ░ ░ ▒▒ ██████████▒██▓███░░░▒▒▓▓▓▓▒░░ ░ │ +│██▓▓░█░▒▒▒░█▓▓▓▓ █▓▓█ ░ ░ ░░░░▓░ ████████▒██ ░░░▓▒▒▓▓▓▓ ▓▒░▒▒▒▒░░ │ +│▒██▓▒▓░▒▓░░▓▓▓▓▓ ▓▓▓▓ ░░ ▒░░▒░░ ▓███████▒██░ ▒ ▒░░▒▓▒▒░▒▒▓▒ ░ │ +│▒▓▓▓▒█▒▒▒▒░█▒▒▓▓ ▓▓█▓▓▓▓▓ ░▒ ░ ▒ ░▓▓▓░░░ █▒ ▓ ██▓███▒▓░▓▓▒░▓░░░░▒▒░░░ ░│ +│▒█▒▓░▓▓░▓▓░▓▒▓▒▒ █▓████▓███ ░ ░▒░ ▓▓▒▒▒▒░░▓ ░ ░█ ▓ ▒█████░░ ▓▓▒▒░░▒▒▓▒░ ░░│ +│░▓█▓▒▓▓▒▓▒░█▓▒▓▓ █▓████▓███▓▓ ░▒▒▒▓▓▒▒▓▓▒░▒▓░ ▒ ░██ ░ ███▒░▓░ ▓▒▓▒▒░ ░ │ +│░█▓▓▓▓▓▓▒▒▓█▓▒▓▓ █▓▓███▓█████▓ ░▒▒▒▒▒▓▒▒░░▒░▓ ░░▓▒ ▒░▒░ ░▒ ▓░▓▓░░ ▓▓░ ░░░░ ░░ │ +│ ██░ ░ ▒█▓▓▓▓ ██████▓██████▓░▒▒▒▓▓▓▓▓▓▒▒░▓▒░▓▒▒▒▒▓▓▓░▓▒▒░▒▒▓▓▒▒░▒ ░ ░ ░░│ +│ ░░░▒ ▓▓▓▓ █▓▓█▓█▓███████▓░▒▓▒▓▓█▒░▒▓▓▓▒▒▓▓▒▓▓▒█░▒▓▒▒ ░▓▒▓ ▒▒░▒░ ▒ ░░░ │ +│ ▒░░ ░ ▓ ░▓▓▓▓ ████▓█▓████████▒▓▒█░░▓▒▓ ▒▓▓░▒▒▓▒▒▓▒▓▒▒▓▒▓▓█▓▓ ▓░▒ ░░░░░ ░ │ +│ ░▓ ▒░░░░ ▓█▓▓▓ █▓▒███▓█████████▓░░▒▒▓▒▓▒▒▓▓▒▓▓ ▓▒▓▓▒▓▒▓▒▓▓▒▓▓ ▓▒▒░▒ ▓▒ ░ │ +│ ▒░ ░ ░░ ▓▒░░░ █▓▓██▓▓████▓▓▓█▓░░▒▓▓▓▒▒▓░▓▓▓▒▓▒▒▒▓▒▓▓▓▓▒▒▒▒▒░▒▒▒░██ │ +│▒ ▒▒ ▒░░░ ▓▓▓▓▒ ▓▓▓███▒███▓███▓▓▒▒░░▒▒▒▒░▒▒▒▒▒▓▓▒▒░▓▓▓▒▓░▓▓▓▒▒▒▓░▓▓▓ ░ ░ │ +│▒ ░ ▓ ▓▓▓▓▒ ▓▒▓▓▓█▒███▓▓▓█▒▒▓▓███████▓▒▓░▒▓░▓▒▓▒▓▓▒▒▒▓░▒▒░ ░▒▓▒░ │ +│▓ ░░ ░ █ ▓▓▓▓▓ ▓▓▓█▓▓▓███▓█▓█▓████████████░▓▓▓▓▒▓▓▓▓▒▒▓▒▒▒ ▓▓ ▓░ ░▓ ░ │ +│▓ ░ ░ ▒▓▓▓▒▒ ▓▓▓█▓█▒██▓▓▓█▓█▓█▓██████████░▓▒▒▓▓▓▒▓▓▓▒ ▒▓ ▒ ░▒▓▓▓█ ░ │ +│▓▒░░▒▒░▒ ░░▓▓▓▓▓ ▓▓▓███▓██████████████████████░░▓▒░▓▒▒▒▒▒▒▓▓░ ░▒▒░░ │ +│▓ ░▓▒▒ ░░▒▓▒ ░▓▓█▓█▓█████████████████████▒░░ ░ ░ ░▒░ ░ ░ ░▓▒ │ +└──────────────────────────────────────────────────────────────────────────────┘ + unbourne is a gnu/systemd init process »cosmopolitan» + + +╔────────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § the unbourne shell ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + + The UNBOURNE SHELL is BASED off the Almquist Shell──colloquially + known as the Debian Almquist Shell, a.k.a. dash──which perfected + the work of the late Stephen Bourne whose shell set the standard + for decades thanks to a spark of brilliance from Ken Thompson. + + git://git.kernel.org/pub/scm/utils/dash/dash.git + fba95e9e4a5d0f1f1ac9f7d86557e47bc0e2656c + Tue Jun 19 11:27:37 2018 -0400 + + The UNBOURNE SHELL pays HOMAGE to the Stewards of House California: + + Almquist Shell + Derived from software contributed to Berkeley by Kenneth Almquist. + + Copyright 1991,1993 The Regents of the University of California + Copyright 1997-2018 Herbert Xu + Copyright 1997 Christos Zoulas + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + +╔──────────────────────────────────────────────────────────────────────┬───┬───╗ +│ cosmopolitan § the unbourne shell » build / / │ +╚────────────────────────────────────────────────────────────────────'>/dev/null + + cc -Os -o unbourne unbourne.c + exit + +╔────────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § the unbourne shell » macros ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#include "libc/alg/alg.h" +#include "libc/calls/calls.h" +#include "libc/calls/sigbits.h" +#include "libc/calls/struct/dirent.h" +#include "libc/calls/struct/rlimit.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/calls/struct/stat.h" +#include "libc/calls/struct/tms.h" +#include "libc/calls/termios.h" +#include "libc/conv/conv.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/fmt/fmt.h" +#include "libc/limits.h" +#include "libc/log/log.h" +#include "libc/mem/alloca.h" +#include "libc/mem/mem.h" +#include "libc/paths.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/sysconf.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/at.h" +#include "libc/sysv/consts/f.h" +#include "libc/sysv/consts/fd.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/ok.h" +#include "libc/sysv/consts/rlim.h" +#include "libc/sysv/consts/sig.h" +#include "libc/sysv/consts/w.h" +#include "third_party/dtoa/dtoa.h" +#include "third_party/musl/passwd.h" + +#undef CEOF +#undef rflag + +/* + * The follow should be set to reflect the type of system you have: + * JOBS -> 1 if you have Berkeley job control, 0 otherwise. + * SHORTNAMES -> 1 if your linker cannot handle long names. + * define BSD if you are running 4.2 BSD or later. + * define SYSV if you are running under System V. + * define DEBUG=1 to compile in debugging ('set -o debug' to turn on) + * define DEBUG=2 to compile in and turn on debugging. + * define DO_SHAREDVFORK to indicate that vfork(2) shares its address + * with its parent. + * + * When debugging is on, debugging info will be written to ./trace and + * a quit signal will generate a core dump. + */ + +#define ALIASDEAD 2 +#define ALIASINUSE 1 +#define ARITH_MAX_PREC 8 +#define ATABSIZE 39 +#define CMDTABLESIZE 31 +#define JOBS 1 +#define NOPTS 17 +#define OUTPUT_ERR 01 +#define VTABSIZE 39 + +/* exceptions */ +#define EXINT 0 +#define EXERROR 1 +#define EXEXIT 4 + +/* + * The input line number. Input.c just defines this variable, and saves + * and restores it when files are pushed and popped. The user of this + * package must set its value. + */ +#define plinno (parsefile->linno) + +/* Syntax classes */ +#define CWORD 0 +#define CNL 1 +#define CBACK 2 +#define CSQUOTE 3 +#define CDQUOTE 4 +#define CENDQUOTE 5 +#define CBQUOTE 6 +#define CVAR 7 +#define CENDVAR 8 +#define CLP 9 +#define CRP 10 +#define CEOF 11 +#define CCTL 12 +#define CSPCL 13 +#define CIGN 14 + +/* Syntax classes for is_ functions */ +#define ISDIGIT 01 +#define ISUPPER 02 +#define ISLOWER 04 +#define ISUNDER 010 +#define ISSPECL 020 + +#define SYNBASE 130 +#define PEOF -130 + +#define EOF_NLEFT -99 + +#define PEOA -129 + +#define BASESYNTAX (basesyntax + SYNBASE) +#define DQSYNTAX (dqsyntax + SYNBASE) +#define SQSYNTAX (sqsyntax + SYNBASE) +#define ARISYNTAX (arisyntax + SYNBASE) + +#define ARITH_ASS 1 +#define ARITH_OR 2 +#define ARITH_AND 3 +#define ARITH_BAD 4 +#define ARITH_NUM 5 +#define ARITH_VAR 6 +#define ARITH_NOT 7 +#define ARITH_BINOP_MIN 8 +#define ARITH_LE 8 +#define ARITH_GE 9 +#define ARITH_LT 10 +#define ARITH_GT 11 +#define ARITH_EQ 12 +#define ARITH_REM 13 +#define ARITH_BAND 14 +#define ARITH_LSHIFT 15 +#define ARITH_RSHIFT 16 +#define ARITH_MUL 17 +#define ARITH_ADD 18 +#define ARITH_BOR 19 +#define ARITH_SUB 20 +#define ARITH_BXOR 21 +#define ARITH_DIV 22 +#define ARITH_NE 23 +#define ARITH_BINOP_MAX 24 +#define ARITH_ASS_MIN 24 +#define ARITH_REMASS 24 +#define ARITH_BANDASS 25 +#define ARITH_LSHIFTASS 26 +#define ARITH_RSHIFTASS 27 +#define ARITH_MULASS 28 +#define ARITH_ADDASS 29 +#define ARITH_BORASS 30 +#define ARITH_SUBASS 31 +#define ARITH_BXORASS 32 +#define ARITH_DIVASS 33 +#define ARITH_ASS_MAX 34 +#define ARITH_LPAREN 34 +#define ARITH_RPAREN 35 +#define ARITH_BNOT 36 +#define ARITH_QMARK 37 +#define ARITH_COLON 38 + +/* expandarg() flags */ +#define EXP_FULL 0x1 +#define EXP_TILDE 0x2 +#define EXP_VARTILDE 0x4 +#define EXP_REDIR 0x8 +#define EXP_CASE 0x10 +#define EXP_VARTILDE2 0x40 +#define EXP_WORD 0x80 +#define EXP_QUOTED 0x100 +#define EXP_KEEPNUL 0x200 +#define EXP_DISCARD 0x400 + +/* reasons for skipping commands (see comment on breakcmd routine) */ +#define SKIPBREAK (1 << 0) +#define SKIPCONT (1 << 1) +#define SKIPFUNC (1 << 2) +#define SKIPFUNCDEF (1 << 3) + +#define TEOF 0 +#define TNL 1 +#define TSEMI 2 +#define TBACKGND 3 +#define TAND 4 +#define TOR 5 +#define TPIPE 6 +#define TLP 7 +#define TRP 8 +#define TENDCASE 9 +#define TENDBQUOTE 10 +#define TREDIR 11 +#define TWORD 12 +#define TNOT 13 +#define TCASE 14 +#define TDO 15 +#define TDONE 16 +#define TELIF 17 +#define TELSE 18 +#define TESAC 19 +#define TFI 20 +#define TFOR 21 +#define TIF 22 +#define TIN 23 +#define TTHEN 24 +#define TUNTIL 25 +#define TWHILE 26 +#define TBEGIN 27 +#define TEND 28 + +/* control characters in argument strings */ +#define CTL_FIRST -127 +#define CTLESC -127 +#define CTLVAR -126 +#define CTLENDVAR -125 +#define CTLBACKQ -124 +#define CTLARI -122 +#define CTLENDARI -121 +#define CTLQUOTEMARK -120 +#define CTL_LAST -120 + +/* variable substitution byte (follows CTLVAR) */ +#define VSTYPE 0x0f +#define VSNUL 0x10 + +/* values of VSTYPE field */ +#define VSNORMAL 0x1 +#define VSMINUS 0x2 +#define VSPLUS 0x3 +#define VSQUESTION 0x4 +#define VSASSIGN 0x5 +#define VSTRIMRIGHT 0x6 +#define VSTRIMRIGHTMAX 0x7 +#define VSTRIMLEFT 0x8 +#define VSTRIMLEFTMAX 0x9 +#define VSLENGTH 0xa + +/* values of checkkwd variable */ +#define CHKALIAS 0x1 +#define CHKKWD 0x2 +#define CHKNL 0x4 +#define CHKEOFMARK 0x8 + +/* flags in argument to evaltree */ +#define EV_EXIT 01 +#define EV_TESTED 02 + +#define INT_CHARS (sizeof(int) * CHAR_BIT / 3) + +/* + * These macros allow the user to suspend the handling of interrupt + * signals over a period of time. This is similar to SIGHOLD to or + * sigblock, but much more efficient and portable. (But hacking the + * kernel is so much more fun than worrying about efficiency and + * portability. :-)) + */ +#define barrier() ({ asm volatile("" : : : "memory"); }) +#define INTOFF \ + ({ \ + suppressint++; \ + barrier(); \ + 0; \ + }) +#define INTON \ + ({ \ + barrier(); \ + if (--suppressint == 0 && intpending) onint(); \ + 0; \ + }) +#define FORCEINTON \ + ({ \ + barrier(); \ + suppressint = 0; \ + if (intpending) onint(); \ + 0; \ + }) +#define SAVEINT(v) ((v) = suppressint) +#define RESTOREINT(v) \ + ({ \ + barrier(); \ + if ((suppressint = (v)) == 0 && intpending) onint(); \ + 0; \ + }) +#define CLEAR_PENDING_INT intpending = 0 +#define int_pending() intpending + +/* + * Most machines require the value returned from malloc to be aligned + * in some way. The following macro will get this right on many machines. + */ +#define SHELL_SIZE \ + (sizeof(union { \ + int i; \ + char *cp; \ + double d; \ + }) - \ + 1) + +/* + * It appears that grabstackstr() will barf with such alignments + * because stalloc() will return a string allocated in a new stackblock. + */ +#define SHELL_ALIGN(nbytes) (((nbytes) + SHELL_SIZE) & ~SHELL_SIZE) + +/* + * Minimum size of a block + * + * Parse trees for commands are allocated in lifo order, so we use a stack + * to make this more efficient, and also to avoid all sorts of exception + * handling code to handle interrupts in the middle of a parse. + * + * The size 504 was chosen because the Ultrix malloc handles that size + * well. + */ +#define MINSIZE SHELL_ALIGN(504) + +/* flags */ +#define VEXPORT 0x001 +#define VREADONLY 0x002 +#define VSTRFIXED 0x004 +#define VTEXTFIXED 0x008 +#define VSTACK 0x010 +#define VUNSET 0x020 +#define VNOFUNC 0x040 +#define VNOSET 0x080 +#define VNOSAVE 0x100 + +/* + * Evaluate a command. + */ +#define ALIASCMD (builtincmd + 3) +#define BGCMD (builtincmd + 4) +#define BREAKCMD (builtincmd + 5) +#define CDCMD (builtincmd + 6) +#define COMMANDCMD (builtincmd + 8) +#define DOTCMD (builtincmd + 0) +#define ECHOCMD (builtincmd + 10) +#define EVALCMD (builtincmd + 11) +#define EXECCMD (builtincmd + 12) +#define EXITCMD (builtincmd + 13) +#define EXPORTCMD (builtincmd + 14) +#define FALSECMD (builtincmd + 15) +#define FGCMD (builtincmd + 16) +#define GETOPTSCMD (builtincmd + 17) +#define HASHCMD (builtincmd + 18) +#define JOBSCMD (builtincmd + 19) +#define KILLCMD (builtincmd + 20) +#define LOCALCMD (builtincmd + 21) +#define PRINTFCMD (builtincmd + 22) +#define PWDCMD (builtincmd + 23) +#define READCMD (builtincmd + 24) +#define RETURNCMD (builtincmd + 26) +#define SETCMD (builtincmd + 27) +#define SHIFTCMD (builtincmd + 28) +#define TESTCMD (builtincmd + 2) +#define TIMESCMD (builtincmd + 30) +#define TRAPCMD (builtincmd + 31) +#define TRUECMD (builtincmd + 1) +#define TYPECMD (builtincmd + 33) +#define ULIMITCMD (builtincmd + 34) +#define UMASKCMD (builtincmd + 35) +#define UNALIASCMD (builtincmd + 36) +#define UNSETCMD (builtincmd + 37) +#define WAITCMD (builtincmd + 38) + +#define BUILTIN_SPECIAL 0x1 +#define BUILTIN_REGULAR 0x2 +#define BUILTIN_ASSIGN 0x4 + +/* mode flags for set_curjob */ +#define CUR_DELETE 2 +#define CUR_RUNNING 1 +#define CUR_STOPPED 0 + +/* mode flags for dowait */ +#define DOWAIT_NORMAL 0 +#define DOWAIT_BLOCK 1 +#define DOWAIT_WAITCMD 2 + +/* _rmescape() flags */ +#define RMESCAPE_ALLOC 0x01 +#define RMESCAPE_GLOB 0x02 +#define RMESCAPE_GROW 0x08 +#define RMESCAPE_HEAP 0x10 + +/* Add CTLESC when necessary. */ +#define QUOTES_ESC (EXP_FULL | EXP_CASE) + +#define IBUFSIZ (BUFSIZ + 1) +#define OUTBUFSIZ BUFSIZ +#define MEM_OUT -3 + +/* + * Sigmode records the current value of the signal handlers for the + * various modes. A value of zero means that the current handler is not + * known. S_HARD_IGN indicates that the signal was ignored on entry to + * the shell, + */ +#define S_DFL 1 +#define S_CATCH 2 +#define S_IGN 3 +#define S_HARD_IGN 4 +#define S_RESET 5 + +#define NCMD 0 +#define NPIPE 1 +#define NREDIR 2 +#define NBACKGND 3 +#define NSUBSHELL 4 +#define NAND 5 +#define NOR 6 +#define NSEMI 7 +#define NIF 8 +#define NWHILE 9 +#define NUNTIL 10 +#define NFOR 11 +#define NCASE 12 +#define NCLIST 13 +#define NDEFUN 14 +#define NARG 15 +#define NTO 16 +#define NCLOBBER 17 +#define NFROM 18 +#define NFROMTO 19 +#define NAPPEND 20 +#define NTOFD 21 +#define NFROMFD 22 +#define NHERE 23 +#define NXHERE 24 +#define NNOT 25 + +/* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */ +#define FORK_FG 0 +#define FORK_BG 1 +#define FORK_NOJOB 2 + +/* mode flags for showjob(s) */ +#define SHOW_PGID 0x01 +#define SHOW_PID 0x04 +#define SHOW_CHANGED 0x08 + +/* values of cmdtype */ +#define CMDUNKNOWN -1 +#define CMDNORMAL 0 +#define CMDFUNCTION 1 +#define CMDBUILTIN 2 + +/* action to find_command() */ +#define DO_ERR 0x01 +#define DO_ABS 0x02 +#define DO_NOFUNC 0x04 +#define DO_ALTPATH 0x08 +#define DO_REGBLTIN 0x10 + +/* flags passed to redirect */ +#define REDIR_PUSH 01 +#define REDIR_SAVEFD2 03 + +#define CD_PHYSICAL 1 +#define CD_PRINT 2 + +#define REALLY_CLOSED -3 +#define EMPTY -2 +#define CLOSED -1 +#define PIPESIZE 4096 + +#define rootshell (!shlvl) + +#define eflag optlist[0] +#define fflag optlist[1] +#define Iflag optlist[2] +#define iflag optlist[3] +#define mflag optlist[4] +#define nflag optlist[5] +#define sflag optlist[6] +#define xflag optlist[7] +#define vflag optlist[8] +#define Vflag optlist[9] +#define Eflag optlist[10] +#define Cflag optlist[11] +#define aflag optlist[12] +#define bflag optlist[13] +#define uflag optlist[14] +#define nolog optlist[15] +#define debug optlist[16] + +/* Used by expandstr to get here-doc like behaviour. */ +#define FAKEEOFMARK (char *)1 + +/* + * This file is included by programs which are optionally built into the + * shell. If SHELL is defined, we try to map the standard UNIX library + * routines to ash routines using defines. + */ +/* #undef stdout /\* TODO(jart): XXX *\/ */ +/* #undef stderr */ +/* #undef putc */ +/* #undef putchar */ +#undef fileno +/* #define stdout out1 */ +/* #define stderr out2 */ +#undef printf +#define printf out1fmt +/* #define putc(c, file) outc(c, file) */ +/* #define putchar(c) out1c(c) */ +#define FILE struct output +#undef fprintf +#define fprintf outfmt +#define fputs outstr +#define fflush flushout +#define fileno(f) ((f)->fd) +/* #define ferror outerr */ +#define INITARGS(argv) +#define setprogname(s) +#define getprogname() commandname + +#define setlocate(l, s) 0 +#define equal(s1, s2) (strcmp(s1, s2) == 0) +#define getenv(p) bltinlookup((p), 0) +#define isodigit(c) ((c) >= '0' && (c) <= '7') +#define octtobin(c) ((c) - '0') +#define scopy(s1, s2) ((void)strcpy(s2, s1)) + +#define TRACE(param) +/* #define TRACE(param) \ */ +/* do { \ */ +/* printf("TRACE: "); \ */ +/* printf param; \ */ +/* } while (0) */ + +#define TRACEV(param) +#define digit_val(c) ((c) - '0') +#define is_alpha(c) isalpha((unsigned char)(c)) +#define is_digit(c) ((unsigned)((c) - '0') <= 9) +#define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c))) +#define is_name(c) ((c) == '_' || isalpha((unsigned char)(c))) +#define is_special(c) ((is_type + SYNBASE)[(signed char)(c)] & (ISSPECL | ISDIGIT)) +/* #define likely(x) __builtin_expect(!!(x), 1) */ +/* #define unlikely(x) __builtin_expect(!!(x), 0) */ + +#define uninitialized_var(x) x = x /* suppress uninitialized warning w/o code */ + +/* + * Shell variables. + */ +#define vifs varinit[0] +#define vmail (&vifs)[1] +#define vmpath (&vmail)[1] +#define vpath (&vmpath)[1] +#define vps1 (&vpath)[1] +#define vps2 (&vps1)[1] +#define vps4 (&vps2)[1] +#define voptind (&vps4)[1] +#define vlineno (&voptind)[1] +#define defifs (defifsvar + 4) +#define defpath (defpathvar + 36) + +/* + * The following macros access the values of the above variables. They + * have to skip over the name. They return the null string for unset + * variables. + */ +#define ifsval() (vifs.text + 4) +#define ifsset() ((vifs.flags & VUNSET) == 0) +#define mailval() (vmail.text + 5) +#define mpathval() (vmpath.text + 9) +#define pathval() (vpath.text + 5) +#define ps1val() (vps1.text + 4) +#define ps2val() (vps2.text + 4) +#define ps4val() (vps4.text + 4) +#define optindval() (voptind.text + 7) +#define linenoval() (vlineno.text + 7) +#define mpathset() ((vmpath.flags & VUNSET) == 0) +#define environment() listvars(VEXPORT, VUNSET, 0) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § the unbourne shell » data structures ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +typedef void *pointer; + +struct redirtab { + struct redirtab *next; + int renamed[10]; +}; + +/* + * We enclose jmp_buf in a structure so that we can declare pointers to + * jump locations. The global variable handler contains the location to + * jump to when an exception occurs, and the global variable exception + * contains a code identifying the exeception. To implement nested + * exception handlers, the user should save the value of handler on + * entry to an inner scope, set handler to point to a jmploc structure + * for the inner scope, and restore handler on exit from the scope. + */ +struct jmploc { + jmp_buf loc; +}; + +/* PEOF (the end of file marker) is defined in syntax.h */ +enum { + INPUT_PUSH_FILE = 1, + INPUT_NOFILE_OK = 2, +}; + +struct alias { + struct alias *next; + char *name; + char *val; + int flag; +}; + +struct shparam { + int nparam; /* # of positional parameters (without $0) */ + unsigned char malloc; /* if parameter list dynamically allocated */ + char **p; /* parameter list */ + int optind; /* next parameter to be processed by getopts */ + int optoff; /* used by getopts */ +}; + +struct strpush { + struct strpush *prev; /* preceding string on stack */ + char *prevstring; + int prevnleft; + struct alias *ap; /* if push was associated with an alias */ + char *string; /* remember the string since it may change */ + int lastc[2]; /* Remember last two characters for pungetc. */ + int unget; /* Number of outstanding calls to pungetc. */ +}; + +/* + * The parsefile structure pointed to by the global variable parsefile + * contains information about the current file being read. + */ +struct parsefile { + struct parsefile *prev; /* preceding file on stack */ + int linno; /* current line */ + int fd; /* file descriptor (or -1 if string) */ + int nleft; /* number of chars left in this line */ + int lleft; /* number of chars left in this buffer */ + char *nextc; /* next char in buffer */ + char *buf; /* input buffer */ + struct strpush *strpush; /* for pushing strings at this level */ + struct strpush basestrpush; /* so pushing one is fast */ + int lastc[2]; /* Remember last two characters for pungetc. */ + int unget; /* Number of outstanding calls to pungetc. */ +}; + +struct output { + char *nextc; + char *end; + char *buf; + unsigned bufsize; + int fd; + int flags; +}; + +struct heredoc { + struct heredoc *next; /* next here document in list */ + union node *here; /* redirection node */ + char *eofmark; /* string indicating end of input */ + int striptabs; /* if set, strip leading tabs */ +}; + +struct synstack { + const char *syntax; + struct synstack *prev; + struct synstack *next; + int innerdq; + int varpushed; + int dblquote; + int varnest; /* levels of variables expansion */ + int parenlevel; /* levels of parens in arithmetic */ + int dqvarnest; /* levels of variables expansion within double quotes */ +}; + +struct procstat { + int pid; /* process id */ + int status; /* last process status from wait() */ + char *cmd; /* text of command being run */ +}; + +/* + * A job structure contains information about a job. A job is either a + * single process or a set of processes contained in a pipeline. In the + * latter case, pidlist will be non-NULL, and will point to a -1 terminated + * array of pids. + */ +struct job { + struct procstat ps0; /* status of process */ + struct procstat *ps; /* status or processes when more than one */ + int stopstatus; /* status of a stopped job */ + unsigned nprocs : 16, /* number of processes */ + state : 8, +#define JOBRUNNING 0 +#define JOBSTOPPED 1 +#define JOBDONE 2 + sigint : 1, /* job was killed by SIGINT */ + jobctl : 1, /* job running under job control */ + waited : 1, /* true if this entry has been waited for */ + used : 1, /* true if this entry is in used */ + changed : 1; /* true if status has changed */ + struct job *prev_job; /* previous job */ +}; + +struct ncmd { + int type; + int linno; + union node *assign; + union node *args; + union node *redirect; +}; + +struct npipe { + int type; + int backgnd; + struct nodelist *cmdlist; +}; + +struct nredir { + int type; + int linno; + union node *n; + union node *redirect; +}; + +struct nbinary { + int type; + union node *ch1; + union node *ch2; +}; + +struct nif { + int type; + union node *test; + union node *ifpart; + union node *elsepart; +}; + +struct nfor { + int type; + int linno; + union node *args; + union node *body; + char *var_; +}; + +struct ncase { + int type; + int linno; + union node *expr; + union node *cases; +}; + +struct nclist { + int type; + union node *next; + union node *pattern; + union node *body; +}; + +struct ndefun { + int type; + int linno; + char *text; + union node *body; +}; + +struct narg { + int type; + union node *next; + char *text; + struct nodelist *backquote; +}; + +struct nfile { + int type; + union node *next; + int fd; + union node *fname; + char *expfname; +}; + +struct ndup { + int type; + union node *next; + int fd; + int dupfd; + union node *vname; +}; + +struct nhere { + int type; + union node *next; + int fd; + union node *doc; +}; + +struct nnot { + int type; + union node *com; +}; + +union node { + int type; + struct ncmd ncmd; + struct npipe npipe; + struct nredir nredir; + struct nbinary nbinary; + struct nif nif; + struct nfor nfor; + struct ncase ncase; + struct nclist nclist; + struct ndefun ndefun; + struct narg narg; + struct nfile nfile; + struct ndup ndup; + struct nhere nhere; + struct nnot nnot; +}; + +struct nodelist { + struct nodelist *next; + union node *n; +}; + +struct funcnode { + int count; + union node n; +}; + +struct localvar_list { + struct localvar_list *next; + struct localvar *lv; +}; + +struct Var { + struct Var *next; /* next entry in hash list */ + int flags; /* flags are defined above */ + const char *text; /* name=value */ + void (*func)(const char *); + /* function to be called when */ + /* the variable gets set/unset */ +}; + +struct localvar { + struct localvar *next; /* next local variable in list */ + struct Var *vp; /* the variable that was made local */ + int flags; /* saved flags */ + const char *text; /* saved text */ +}; + +union yystype { + int64_t val; + char *name; +}; + +struct strlist { + struct strlist *next; + char *text; +}; + +struct arglist { + struct strlist *list; + struct strlist **lastp; +}; + +/* + * Structure specifying which parts of the string should be searched + * for IFS characters. + */ +struct ifsregion { + struct ifsregion *next; /* next region in list */ + int begoff; /* offset of start of region */ + int endoff; /* offset of end of region */ + int nulonly; /* search for nul bytes only */ +}; + +struct builtincmd { + const char *name; + int (*builtin)(int, char **); + unsigned flags; +}; + +struct cmdentry { + int cmdtype; + union param { + int index; + const struct builtincmd *cmd; + struct funcnode *func; + } u; +}; + +struct tblentry { + struct tblentry *next; /* next entry in hash chain */ + union param param; /* definition of builtin function */ + short cmdtype; /* index identifying command */ + char rehash; /* if set, cd done since entry created */ + char cmdname[]; /* name of command */ +}; + +struct backcmd { /* result of evalbackcmd */ + int fd; /* file descriptor to read from */ + char *buf; /* buffer */ + int nleft; /* number of chars in buffer */ + struct job *jp; /* job structure for command */ +}; + +struct stack_block { + struct stack_block *prev; + char space[MINSIZE]; +}; + +struct stackmark { + struct stack_block *stackp; + char *stacknxt; + unsigned stacknleft; +}; + +struct limits { + const char *name; + int cmd; + int factor; /* multiply by to get rlim_{cur,max} values */ + char option; +}; + +struct t_op { + const char *op_text; + short op_num, op_type; +}; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § the unbourne shell » bss ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +static char **argptr; /* argument list for builtin commands */ +static char **gargv; +static char **t_wp; +static char *arg0; /* value of $0 */ +static char *cmdnextc; +static char *commandname; +static char *expdest; /* output of current string */ +static char *expdir; +static char *funcstring; /* block to allocate strings from */ +static char *minusc; /* argument to -c option */ +static char *optionarg; /* set by nextopt (like getopt) */ +static char *optptr; /* used by nextopt */ +static char *trap[NSIG]; /* trap handler commands */ +static char *wordtext; /* text of last word returned by readtoken */ +static char basebuf[IBUFSIZ]; /* buffer for top level input file */ +static char gotsig[NSIG - 1]; /* indicates specified signal received */ +static char nullstr[1]; /* zero length string */ +static char optlist[NOPTS]; +static char sigmode[NSIG - 1]; /* current value of signal */ +static const char *arith_buf; +static const char *arith_startbuf; +static const char *pathopt; +static int back_exitstatus; /* exit status of backquoted command */ +static int checkkwd; +static int doprompt; /* if set, prompt the user */ +static int errlinno; +static int evalskip; /* set if we are skipping commands */ +static int exception; +static int exitstatus; /* exit status of last command */ +static int funcblocksize; /* size of structures in function */ +static int funcline; /* start line of function, or 0 if not in one */ +static int funcstringsize; /* size of strings in node */ +static int gotsigchld; /* received SIGCHLD */ +static int initialpgrp; /* pgrp of shell on invocation */ +static int job_warning; +static int jobctl; +static int last_token; +static int lasttoken; /* last token read */ +static int lineno; +static int loopnest; /* current loop nesting level */ +static int needprompt; /* true if interactive and at start of line */ +static int quoteflag; /* set if (part of) last token was quoted */ +static int rootpid; +static int rval; +static int shlvl; +static int skipcount; /* number of levels to skip */ +static int suppressint; +static int tokpushback; /* last token pushed back */ +static int trapcnt; /* number of non-null traps */ +static int ttyfd = -1; /* control terminal */ +static int vforked; /* Set if we are in the vforked child */ +static int whichprompt; /* 1 == PS1, 2 == PS2 */ +static int backgndpid; /* pid of last background process */ +static pointer funcblock; /* block to allocate function from */ +static struct arglist exparg; /* holds expanded arg list */ +static struct heredoc *heredoc; +static struct heredoc *heredoclist; /* list of here documents to read */ +static struct ifsregion *ifslastp; /* last struct in list */ +static struct ifsregion ifsfirst; /* first struct in list of ifs regions */ +static struct jmploc *handler; +static struct job *curjob; /* current job */ +static struct job *jobtab; /* array of jobs */ +static struct localvar_list *localvar_stack; +static struct nodelist *argbackq; /* list of back quote expressions */ +static struct nodelist *backquotelist; +static struct output preverrout; +static struct parsefile basepf; /* top level input file */ +static struct redirtab *redirlist; +static struct shparam shellparam; /* current positional parameters */ +static struct stack_block stackbase; +static struct t_op const *t_wp_op; +static struct tblentry **lastcmdentry; +static struct tblentry *cmdtable[CMDTABLESIZE]; +static struct Var *vartab[VTABSIZE]; +static union node *redirnode; +static union yystype yylval; +static unsigned expdir_max; +static unsigned njobs; /* size of array */ +static volatile sig_atomic_t intpending; +static volatile sig_atomic_t pending_sig; /* last pending signal */ +static struct alias *atab[ATABSIZE]; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § the unbourne shell » data ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +static char *curdir = nullstr; /* current working directory */ +static char *physdir = nullstr; /* physical working directory */ +static char *sstrend = stackbase.space + MINSIZE; +static char *stacknxt = stackbase.space; +static char defifsvar[] = "IFS= \t\n"; +static char defoptindvar[] = "OPTIND=1"; +static char linenovar[sizeof("LINENO=") + INT_CHARS + 1] = "LINENO="; +static int builtinloc = -1; /* index in path of %builtin, or -1 */ +static int savestatus = -1; /* exit status of last command outside traps */ +static struct output errout = {0, 0, 0, 0, 2, 0}; +static struct output output = {0, 0, 0, OUTBUFSIZ, 1, 0}; +static struct parsefile *parsefile = &basepf; /* current input file */ +static struct stack_block *stackp = &stackbase; +static unsigned stacknleft = MINSIZE; + +static struct output *out1 = &output; +static struct output *out2 = &errout; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § the unbourne shell » rodata ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +/* Array indicating which tokens mark the end of a list */ +static const char tokendlist[] = { + 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, +}; + +static const char *const tokname[] = { + "end of file", "newline", "\";\"", "\"&\"", "\"&&\"", "\"||\"", + "\"|\"", "\"(\"", "\")\"", "\";;\"", "\"`\"", "redirection", + "word", "\"!\"", "\"case\"", "\"do\"", "\"done\"", "\"elif\"", + "\"else\"", "\"esac\"", "\"fi\"", "\"for\"", "\"if\"", "\"in\"", + "\"then\"", "\"until\"", "\"while\"", "\"{\"", "\"}\"", +}; + +static const char *const parsekwd[] = {"!", "case", "do", "done", "elif", "else", "esac", "fi", + "for", "if", "in", "then", "until", "while", "{", "}"}; + +static const char defpathvar[] = + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"; + +static const char *const optnames[NOPTS] = { + "errexit", "noglob", "ignoreeof", "interactive", "monitor", "noexec", + "stdin", "xtrace", "verbose", "vi", "emacs", "noclobber", + "allexport", "notify", "nounset", "nolog", "debug", +}; + +static const char optletters[NOPTS] = { + 'e', 'f', 'I', 'i', 'm', 'n', 's', 'x', 'v', 'V', 'E', 'C', 'a', 'b', 'u', 0, 0, +}; + +static const char spcstr[] = " "; +static const char snlfmt[] = "%s\n"; +static const char qchars[] = {CTLESC, CTLQUOTEMARK, 0}; +static const char illnum[] = "Illegal number: %s"; +static const char homestr[] = "HOME"; +static const char dolatstr[] = {CTLQUOTEMARK, CTLVAR, VSNORMAL, '@', '=', CTLQUOTEMARK, '\0'}; + +/* TODO(jart): What's wrong with varinit? */ +#if defined(__GNUC__) || defined(__llvm__) +#pragma GCC diagnostic ignored "-Warray-bounds" +#endif + +/* Some macros depend on the order, add new variables to the end. */ +static void changepath(const char *); +static void getoptsreset(const char *); +static struct Var varinit[] = {{0, VSTRFIXED | VTEXTFIXED, defifsvar, 0}, + {0, VSTRFIXED | VTEXTFIXED, defpathvar, changepath}, + {0, VSTRFIXED | VTEXTFIXED, "PS1=$ ", 0}, + {0, VSTRFIXED | VTEXTFIXED, "PS2=> ", 0}, + {0, VSTRFIXED | VTEXTFIXED, "PS4=+ ", 0}, + {0, VSTRFIXED | VTEXTFIXED, defoptindvar, getoptsreset}, + {0, VSTRFIXED | VTEXTFIXED, linenovar, 0}}; + +static const char kPrec[ARITH_BINOP_MAX - ARITH_BINOP_MIN] = { +#define ARITH_PRECEDENCE(OP, PREC) [OP - ARITH_BINOP_MIN] = PREC + ARITH_PRECEDENCE(ARITH_MUL, 0), ARITH_PRECEDENCE(ARITH_DIV, 0), + ARITH_PRECEDENCE(ARITH_REM, 0), ARITH_PRECEDENCE(ARITH_ADD, 1), + ARITH_PRECEDENCE(ARITH_SUB, 1), ARITH_PRECEDENCE(ARITH_LSHIFT, 2), + ARITH_PRECEDENCE(ARITH_RSHIFT, 2), ARITH_PRECEDENCE(ARITH_LT, 3), + ARITH_PRECEDENCE(ARITH_LE, 3), ARITH_PRECEDENCE(ARITH_GT, 3), + ARITH_PRECEDENCE(ARITH_GE, 3), ARITH_PRECEDENCE(ARITH_EQ, 4), + ARITH_PRECEDENCE(ARITH_NE, 4), ARITH_PRECEDENCE(ARITH_BAND, 5), + ARITH_PRECEDENCE(ARITH_BXOR, 6), ARITH_PRECEDENCE(ARITH_BOR, 7), +#undef ARITH_PRECEDENCE +}; + +static const short nodesize[26] /* clang-format off */ = { + SHELL_ALIGN(sizeof(struct ncmd)), SHELL_ALIGN(sizeof(struct npipe)), + SHELL_ALIGN(sizeof(struct nredir)), SHELL_ALIGN(sizeof(struct nredir)), + SHELL_ALIGN(sizeof(struct nredir)), SHELL_ALIGN(sizeof(struct nbinary)), + SHELL_ALIGN(sizeof(struct nbinary)), SHELL_ALIGN(sizeof(struct nbinary)), + SHELL_ALIGN(sizeof(struct nif)), SHELL_ALIGN(sizeof(struct nbinary)), + SHELL_ALIGN(sizeof(struct nbinary)), SHELL_ALIGN(sizeof(struct nfor)), + SHELL_ALIGN(sizeof(struct ncase)), SHELL_ALIGN(sizeof(struct nclist)), + SHELL_ALIGN(sizeof(struct ndefun)), SHELL_ALIGN(sizeof(struct narg)), + SHELL_ALIGN(sizeof(struct nfile)), SHELL_ALIGN(sizeof(struct nfile)), + SHELL_ALIGN(sizeof(struct nfile)), SHELL_ALIGN(sizeof(struct nfile)), + SHELL_ALIGN(sizeof(struct nfile)), SHELL_ALIGN(sizeof(struct ndup)), + SHELL_ALIGN(sizeof(struct ndup)), SHELL_ALIGN(sizeof(struct nhere)), + SHELL_ALIGN(sizeof(struct nhere)), SHELL_ALIGN(sizeof(struct nnot)), +} /* clang-format on */; + +/* syntax table used when not in quotes */ +static const char basesyntax[] /* clang-format off */ = { + CEOF, CSPCL, CWORD, CCTL, CCTL, CCTL, CCTL, CCTL, CCTL, + CCTL, CCTL, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CSPCL, CNL, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CSPCL, CWORD, CDQUOTE, CWORD, CVAR, CWORD, CSPCL, CSQUOTE, CSPCL, + CSPCL, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CSPCL, CSPCL, CWORD, CSPCL, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CBACK, CWORD, CWORD, + CWORD, CBQUOTE, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CSPCL, CENDVAR, CWORD, CWORD +} /* clang-format on */; + +/* syntax table used when in double quotes */ +static const char dqsyntax[] /* clang-format off */ = { + CEOF, CIGN, CWORD, CCTL, CCTL, CCTL, CCTL, CCTL, CCTL, + CCTL, CCTL, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CNL, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CCTL, CENDQUOTE, CWORD, CVAR, CWORD, CWORD, CWORD, CWORD, + CWORD, CCTL, CWORD, CWORD, CCTL, CWORD, CCTL, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CCTL, + CWORD, CWORD, CCTL, CWORD, CCTL, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CCTL, CBACK, CCTL, CWORD, + CWORD, CBQUOTE, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CENDVAR, CCTL, CWORD +} /* clang-format on */; + +/* syntax table used when in single quotes */ +static const char sqsyntax[] = { + CEOF, CIGN, CWORD, CCTL, CCTL, CCTL, CCTL, CCTL, CCTL, CCTL, CCTL, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CNL, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CCTL, CWORD, CWORD, CWORD, CWORD, CWORD, + CENDQUOTE, CWORD, CWORD, CCTL, CWORD, CWORD, CCTL, CWORD, CCTL, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CCTL, CWORD, CWORD, CCTL, CWORD, CCTL, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CCTL, CCTL, CCTL, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CCTL, CWORD}; + +/* syntax table used when in arithmetic */ +static const char arisyntax[] = { + CEOF, CIGN, CWORD, CCTL, CCTL, CCTL, CCTL, CCTL, CCTL, CCTL, CCTL, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CNL, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CVAR, CWORD, CWORD, + CWORD, CLP, CRP, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CBACK, CWORD, CWORD, CWORD, CBQUOTE, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, + CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CENDVAR, CWORD, CWORD}; + +/* character classification table */ +static const char is_type[] /* clang-format off */ = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, ISSPECL, 0, ISSPECL, ISSPECL, 0, + 0, 0, 0, 0, ISSPECL, 0, 0, ISSPECL, + 0, 0, ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT, + ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT, 0, 0, 0, 0, + 0, ISSPECL, ISSPECL, ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, + ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, + ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, + ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, 0, 0, 0, + 0, ISUNDER, 0, ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, + ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, + ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, + ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, 0, 0, 0, + 0, 0 +} /* clang-format on */; + +static int aliascmd(); +static int bgcmd(); +static int breakcmd(); +static int cdcmd(); +static int commandcmd(); +static int dotcmd(); +static int echocmd(); +static int evalcmd(); +static int execcmd(); +static int exitcmd(); +static int exportcmd(); +static int falsecmd(); +static int fgcmd(); +static int getoptscmd(); +static int hashcmd(); +static int jobscmd(); +static int killcmd(); +static int localcmd(); +static int printfcmd(); +static int pwdcmd(); +static int readcmd(); +static int returncmd(); +static int setcmd(); +static int shiftcmd(); +static int testcmd(); +static int timescmd(); +static int trapcmd(); +static int truecmd(); +static int typecmd(); +static int ulimitcmd(); +static int umaskcmd(); +static int unaliascmd(); +static int unsetcmd(); +static int waitcmd(); + +static const struct builtincmd builtincmd[] = { + {".", dotcmd, 3}, {":", truecmd, 3}, {"[", testcmd, 0}, + {"alias", aliascmd, 6}, {"bg", bgcmd, 2}, {"break", breakcmd, 3}, + {"cd", cdcmd, 2}, {"chdir", cdcmd, 0}, {"command", commandcmd, 2}, + {"continue", breakcmd, 3}, {"echo", echocmd, 0}, {"eval", NULL, 3}, + {"exec", execcmd, 3}, {"exit", exitcmd, 3}, {"export", exportcmd, 7}, + {"false", falsecmd, 2}, {"fg", fgcmd, 2}, {"getopts", getoptscmd, 2}, + {"hash", hashcmd, 2}, {"jobs", jobscmd, 2}, {"kill", killcmd, 2}, + {"local", localcmd, 7}, {"printf", printfcmd, 0}, {"pwd", pwdcmd, 2}, + {"read", readcmd, 2}, {"readonly", exportcmd, 7}, {"return", returncmd, 3}, + {"set", setcmd, 3}, {"shift", shiftcmd, 3}, {"test", testcmd, 0}, + {"times", timescmd, 3}, {"trap", trapcmd, 3}, {"true", truecmd, 2}, + {"type", typecmd, 2}, {"ulimit", ulimitcmd, 2}, {"umask", umaskcmd, 2}, + {"unalias", unaliascmd, 2}, {"unset", unsetcmd, 3}, {"wait", waitcmd, 2}}; + +enum token { + EOI, + FILRD, + FILWR, + FILEX, + FILEXIST, + FILREG, + FILDIR, + FILCDEV, + FILBDEV, + FILFIFO, + FILSOCK, + FILSYM, + FILGZ, + FILTT, + FILSUID, + FILSGID, + FILSTCK, + FILNT, + FILOT, + FILEQ, + FILUID, + FILGID, + STREZ, + STRNZ, + STREQ, + STRNE, + STRLT, + STRGT, + INTEQ, + INTNE, + INTGE, + INTGT, + INTLE, + INTLT, + UNOT, + BAND, + BOR, + LPAREN, + RPAREN, + OPERAND +}; + +enum token_types { UNOP, BINOP, BUNOP, BBINOP, PAREN }; + +static struct t_op const ops[] = {{"-r", FILRD, UNOP}, + {"-w", FILWR, UNOP}, + {"-x", FILEX, UNOP}, + {"-e", FILEXIST, UNOP}, + {"-f", FILREG, UNOP}, + {"-d", FILDIR, UNOP}, + {"-c", FILCDEV, UNOP}, + {"-b", FILBDEV, UNOP}, + {"-p", FILFIFO, UNOP}, + {"-u", FILSUID, UNOP}, + {"-g", FILSGID, UNOP}, + {"-k", FILSTCK, UNOP}, + {"-s", FILGZ, UNOP}, + {"-t", FILTT, UNOP}, + {"-z", STREZ, UNOP}, + {"-n", STRNZ, UNOP}, + {"-h", FILSYM, UNOP}, /* for backwards compat */ + {"-O", FILUID, UNOP}, + {"-G", FILGID, UNOP}, + {"-L", FILSYM, UNOP}, + {"-S", FILSOCK, UNOP}, + {"=", STREQ, BINOP}, + {"!=", STRNE, BINOP}, + {"<", STRLT, BINOP}, + {">", STRGT, BINOP}, + {"-eq", INTEQ, BINOP}, + {"-ne", INTNE, BINOP}, + {"-ge", INTGE, BINOP}, + {"-gt", INTGT, BINOP}, + {"-le", INTLE, BINOP}, + {"-lt", INTLT, BINOP}, + {"-nt", FILNT, BINOP}, + {"-ot", FILOT, BINOP}, + {"-ef", FILEQ, BINOP}, + {"!", UNOT, BUNOP}, + {"-a", BAND, BBINOP}, + {"-o", BOR, BBINOP}, + {"(", LPAREN, PAREN}, + {")", RPAREN, PAREN}, + {0, 0, 0}}; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § the unbourne shell » text ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +/* + * Hack to calculate maximum length. + * (length * 8 - 1) * log10(2) + 1 + 1 + 12 + * The second 1 is for the minus sign and the 12 is a safety margin. + */ +static inline int max_int_length(int bytes) { + return (bytes * 8 - 1) * 0.30102999566398119521 + 14; +} + +/* prefix -- see if pfx is a prefix of string. */ +static char *prefix(const char *string, const char *pfx) { + while (*pfx) { + if (*pfx++ != *string++) return 0; + } + return (char *)string; +} + +/* + * Wrapper around strcmp for qsort/bsearch/... + */ +static int pstrcmp(const void *a, const void *b) { + return strcmp(*(const char *const *)a, *(const char *const *)b); +} + +/* + * Find a string is in a sorted array. + */ +static const char *const *findstring(const char *s, const char *const *array, unsigned nmemb) { + return bsearch(&s, array, nmemb, sizeof(const char *), pstrcmp); +} + +/* Types of operations (passed to the errmsg routine). */ +enum ShErrorAction { E_OPEN, E_CREAT, E_EXEC }; + +/* + * Return a string describing an error. The returned string may be a + * pointer to a static buffer that will be overwritten on the next call. + * Action describes the operation that got the error. + */ +static const char *errmsg(int e, enum ShErrorAction action) { + if (e != ENOENT && e != ENOTDIR) return strerror(e); + switch (action) { + case E_OPEN: + return "No such file"; + case E_CREAT: + return "Directory nonexistent"; + default: + return "not found"; + } +} + +static inline void sigclearmask(void) { + sigset_t set; + sigemptyset(&set); + sigprocmask(SIG_SETMASK, &set, 0); +} + +/* + * Called to raise an exception. Since C doesn't include exceptions, we + * just do a longjmp to the exception handler. The type of exception is + * stored in the global variable "exception". + */ +noreturn static void exraise(int e) { + if (vforked) _exit(exitstatus); + INTOFF; + exception = e; + longjmp(handler->loc, 1); + panic(); +} + +/* + * Called from trap.c when a SIGINT is received. (If the user specifies + * that SIGINT is to be trapped or ignored using the trap builtin, then + * this routine is not called.) Suppressint is nonzero when interrupts + * are held using the INTOFF macro. (The test for iflag is just + * defensive programming.) + */ +noreturn static void onint(void) { + intpending = 0; + sigclearmask(); + if (!(rootshell && iflag)) { + signal(SIGINT, SIG_DFL); + raise(SIGINT); + } + exitstatus = SIGINT + 128; + exraise(EXINT); +} + +static pointer ckmalloc(unsigned nbytes) { + pointer p; + if (!(p = malloc(nbytes))) abort(); + return p; +} + +static pointer ckrealloc(pointer p, unsigned nbytes) { + if (!(p = realloc(p, nbytes))) abort(); + return p; +} + +#define stackblock() ((void *)stacknxt) +#define stackblocksize() stacknleft +#define STARTSTACKSTR(p) ((p) = stackblock()) +#define STPUTC(c, p) ((p) = _STPUTC((c), (p))) +#define CHECKSTRSPACE(n, p) \ + ({ \ + char *q = (p); \ + unsigned l = (n); \ + unsigned m = sstrend - q; \ + if (l > m) (p) = makestrspace(l, q); \ + 0; \ + }) +#define USTPUTC(c, p) (*p++ = (c)) +#define STACKSTRNUL(p) ((p) == sstrend ? (p = growstackstr(), *p = '\0') : (*p = '\0')) +#define STUNPUTC(p) (--p) +#define STTOPC(p) p[-1] +#define STADJUST(amount, p) (p += (amount)) +#define grabstackstr(p) stalloc((char *)(p) - (char *)stackblock()) +#define ungrabstackstr(s, p) stunalloc((s)) +#define stackstrend() ((void *)sstrend) +#define ckfree(p) free((pointer)(p)) + +static pointer stalloc(unsigned nbytes) { + char *p; + unsigned aligned; + aligned = SHELL_ALIGN(nbytes); + if (aligned > stacknleft) { + unsigned len; + unsigned blocksize; + struct stack_block *sp; + blocksize = aligned; + if (blocksize < MINSIZE) blocksize = MINSIZE; + len = sizeof(struct stack_block) - MINSIZE + blocksize; + if (len < blocksize) abort(); + INTOFF; + sp = ckmalloc(len); + sp->prev = stackp; + stacknxt = sp->space; + stacknleft = blocksize; + sstrend = stacknxt + blocksize; + stackp = sp; + INTON; + } + p = stacknxt; + stacknxt += aligned; + stacknleft -= aligned; + return p; +} + +static inline void grabstackblock(unsigned len) { + stalloc(len); +} + +static void pushstackmark(struct stackmark *mark, unsigned len) { + mark->stackp = stackp; + mark->stacknxt = stacknxt; + mark->stacknleft = stacknleft; + grabstackblock(len); +} + +static void popstackmark(struct stackmark *mark) { + struct stack_block *sp; + INTOFF; + while (stackp != mark->stackp) { + sp = stackp; + stackp = sp->prev; + ckfree(sp); + } + stacknxt = mark->stacknxt; + stacknleft = mark->stacknleft; + sstrend = mark->stacknxt + mark->stacknleft; + INTON; +} + +static void setstackmark(struct stackmark *mark) { + pushstackmark(mark, stacknxt == stackp->space && stackp != &stackbase); +} + +static void stunalloc(pointer p) { + stacknleft += stacknxt - (char *)p; + stacknxt = p; +} + +/* Like strdup but works with the ash stack. */ +static char *sstrdup(const char *p) { + unsigned len = strlen(p) + 1; + return memcpy(stalloc(len), p, len); +} + +int xwrite(int, const void *, uint64_t); + +static void flushout(struct output *dest) { + unsigned len; + len = dest->nextc - dest->buf; + if (!len || dest->fd < 0) return; + dest->nextc = dest->buf; + if ((xwrite(dest->fd, dest->buf, len))) dest->flags |= OUTPUT_ERR; +} + +static void flushall(void) { + flushout(&output); +} + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § the unbourne shell » output routines ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + When a builtin command is interrupted we have to discard + any pending output. + When a builtin command appears in back quotes, we want to + save the output of the command in a region obtained + via malloc, rather than doing a fork and reading the + output of the command via a pipe. */ + +static int xvsnprintf(char *outbuf, unsigned length, const char *fmt, va_list ap) { + int ret; + INTOFF; + ret = vsnprintf(outbuf, length, fmt, ap); + INTON; + return ret; +} + +static int xvasprintf(char **sp, unsigned size, const char *f, va_list ap) { + char *s; + int len; + va_list ap2; + va_copy(ap2, ap); + len = xvsnprintf(*sp, size, f, ap2); + va_end(ap2); + if (len < 0) abort(); + if (len < size) return len; + s = stalloc((len >= stackblocksize() ? len : stackblocksize()) + 1); + *sp = s; + len = xvsnprintf(s, len + 1, f, ap); + return len; +} + +static void outmem(const char *p, unsigned len, struct output *dest) { + unsigned bufsize; + unsigned offset; + unsigned nleft; + nleft = dest->end - dest->nextc; + if (likely(nleft >= len)) { + buffered: + dest->nextc = mempcpy(dest->nextc, p, len); + return; + } + bufsize = dest->bufsize; + if (!bufsize) { + (void)0; + } else if (dest->buf == NULL) { + offset = 0; + INTOFF; + dest->buf = ckrealloc(dest->buf, bufsize); + dest->bufsize = bufsize; + dest->end = dest->buf + bufsize; + dest->nextc = dest->buf + offset; + INTON; + } else { + flushout(dest); + } + nleft = dest->end - dest->nextc; + if (nleft > len) goto buffered; + if ((xwrite(dest->fd, p, len))) { + dest->flags |= OUTPUT_ERR; + } +} + +static void outstr(const char *p, struct output *file) { + unsigned len; + len = strlen(p); + outmem(p, len, file); +} + +static void outcslow(int c, struct output *dest) { + char buf = c; + outmem(&buf, 1, dest); +} + +printfesque(3) static int fmtstr(char *outbuf, unsigned length, const char *fmt, ...) { + va_list ap; + int ret; + va_start(ap, fmt); + ret = xvsnprintf(outbuf, length, fmt, ap); + va_end(ap); + return ret > (int)length ? length : ret; +} + +printfesque(2) static int xasprintf(char **sp, const char *fmt, ...) { + va_list ap; + int ret; + va_start(ap, fmt); + ret = xvasprintf(sp, 0, fmt, ap); + va_end(ap); + return ret; +} + +static void doformat(struct output *dest, const char *f, va_list ap) { + struct stackmark smark; + char *s; + int len; + int olen; + setstackmark(&smark); + s = dest->nextc; + olen = dest->end - dest->nextc; + len = xvasprintf(&s, olen, f, ap); + if (likely(olen > len)) { + dest->nextc += len; + goto out; + } + outmem(s, len, dest); +out: + popstackmark(&smark); +} + +printfesque(1) static void out1fmt(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + doformat(out1, fmt, ap); + va_end(ap); +} + +printfesque(2) static void outfmt(struct output *file, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + doformat(file, fmt, ap); + va_end(ap); +} + +static void exvwarning(const char *msg, va_list ap) { + struct output *errs; + const char *name; + const char *fmt; + errs = out2; + name = arg0 ? arg0 : "sh"; + if (!commandname) { + fmt = "%s: %d: "; + } else { + fmt = "%s: %d: %s: "; + } + outfmt(errs, fmt, name, errlinno, commandname); + doformat(errs, msg, ap); + outcslow('\n', errs); +} + +/* error/warning routines for external builtins */ +printfesque(1) static void sh_warnx(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + exvwarning(fmt, ap); + va_end(ap); +} + +/* + * Exverror is called to raise the error exception. If the second argument + * is not NULL then error prints an error message using printf style + * formatting. It then raises the error exception. + */ +noreturn static void exverror(int cond, const char *msg, va_list ap) { + exvwarning(msg, ap); + flushall(); + exraise(cond); +} + +noreturn static void exerror(int cond, const char *msg, ...) { + va_list ap; + va_start(ap, msg); + exverror(cond, msg, ap); + va_end(ap); +} + +noreturn static void sh_error(const char *msg, ...) { + va_list ap; + exitstatus = 2; + va_start(ap, msg); + exverror(EXERROR, msg, ap); + va_end(ap); +} + +noreturn static void badnum(const char *s) { + sh_error(illnum, s); +} + +noreturn static void synerror(const char *msg) { + errlinno = plinno; + sh_error("Syntax error: %s", msg); +} + +noreturn static void yyerror(const char *s) { + sh_error("arithmetic expression: %s: \"%s\"", s, arith_startbuf); +} + +/* + * Called when an unexpected token is read during the parse. The + * argument is the token that is expected, or -1 if more than one type + * of token can occur at this point. + */ +noreturn static void synexpect(int token) { + char msg[64]; + if (token >= 0) { + fmtstr(msg, 64, "%s unexpected (expecting %s)", tokname[lasttoken], tokname[token]); + } else { + fmtstr(msg, 64, "%s unexpected", tokname[lasttoken]); + } + synerror(msg); +} + +noreturn static void varunset(const char *end, const char *var_, const char *umsg, int varflags) { + const char *msg; + const char *tail; + tail = nullstr; + msg = "parameter not set"; + if (umsg) { + if (*end == (char)CTLENDVAR) { + if (varflags & VSNUL) tail = " or null"; + } else + msg = umsg; + } + sh_error("%.*s: %s%s", end - var_ - 1, var_, msg, tail); +} + +/* + * Convert a string into an integer of type int64. Alow trailing spaces. + */ +static int64_t atomax(const char *s, int base) { + char *p; + int64_t r; + errno = 0; + r = strtoimax(s, &p, base); + if (errno == ERANGE) badnum(s); + /* + * Disallow completely blank strings in non-arithmetic (base != 0) + * contexts. + */ + if (p == s && base) badnum(s); + while (isspace((unsigned char)*p)) p++; + if (*p) badnum(s); + return r; +} + +static int64_t atomax10(const char *s) { + return atomax(s, 10); +} + +/* + * Convert a string of digits to an integer, printing an error message + * on failure. + */ +static int number(const char *s) { + int64_t n = atomax10(s); + if (n < 0 || n > INT_MAX) badnum(s); + return n; +} + +static inline int64_t getn(const char *s) { + return atomax10(s); +} + +/* + * When the parser reads in a string, it wants to stick the string on + * the stack and only adjust the stack pointer when it knows how big the + * string is. Stackblock (defined in stack.h) returns a pointer to a + * block of space on top of the stack and stackblocklen returns the + * length of this block. Growstackblock will grow this space by at least + * one byte, possibly moving it (like realloc). Grabstackblock actually + * allocates the part of the block that has been used. + */ +static void growstackblock(unsigned min) { + unsigned newlen; + newlen = stacknleft * 2; + if (newlen < stacknleft) sh_error("Out of space"); + min = SHELL_ALIGN(min | 128); + if (newlen < min) newlen += min; + if (stacknxt == stackp->space && stackp != &stackbase) { + struct stack_block *sp; + struct stack_block *prevstackp; + unsigned grosslen; + INTOFF; + sp = stackp; + prevstackp = sp->prev; + grosslen = newlen + sizeof(struct stack_block) - MINSIZE; + sp = ckrealloc((pointer)sp, grosslen); + sp->prev = prevstackp; + stackp = sp; + stacknxt = sp->space; + stacknleft = newlen; + sstrend = sp->space + newlen; + INTON; + } else { + char *oldspace = stacknxt; + int oldlen = stacknleft; + char *p = stalloc(newlen); + /* free the space we just allocated */ + stacknxt = memcpy(p, oldspace, oldlen); + stacknleft += newlen; + } +} + +/* + * The following routines are somewhat easier to use than the above. The + * user declares a variable of type STACKSTR, which may be declared to + * be a register. The macro STARTSTACKSTR initializes things. Then the + * user uses the macro STPUTC to add characters to the string. In + * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is + * grown as necessary. When the user is done, she can just leave the + * string there and refer to it using stackblock(). Or she can allocate + * the space for it using grabstackstr(). If it is necessary to allow + * someone else to use the stack temporarily and then continue to grow + * the string, the user should use grabstack to allocate the space, and + * then call ungrabstr(p) to return to the previous mode of operation. + * + * USTPUTC is like STPUTC except that it doesn't check for overflow. + * CHECKSTACKSPACE can be called before USTPUTC to ensure that there + * is space for at least one character. + */ +static void *growstackstr(void) { + unsigned len = stackblocksize(); + growstackblock(0); + return (char *)stackblock() + len; +} + +static char *growstackto(unsigned len) { + if (stackblocksize() < len) growstackblock(len); + return stackblock(); +} + +/* + * Make a copy of a string in safe storage. + */ +static char *savestr(const char *s) { + char *p = strdup(s); + if (!p) sh_error("Out of space"); + return p; +} + +/* Called from CHECKSTRSPACE. */ +static char *makestrspace(unsigned newlen, char *p) { + unsigned len = p - stacknxt; + return growstackto(len + newlen) + len; +} + +static char *stnputs(const char *s, unsigned n, char *p) { + p = makestrspace(n, p); + p = mempcpy(p, s, n); + return p; +} + +static char *stputs(const char *s, char *p) { + return stnputs(s, strlen(s), p); +} + +static char *nodesavestr(s) char *s; +{ + char *rtn = funcstring; + funcstring = stpcpy(funcstring, s) + 1; + return rtn; +} + +noreturn static void shellexec(char **, const char *, int); +static char **listvars(int, int, char ***); +static char *argstr(char *p, int flag); +static char *conv_escape(char *, int *); +static char *evalvar(char *, int); +static char *expari(char *start, int flag); +static char *exptilde(char *startp, int flag); +static int shlex(void); +static char *lookupvar(const char *); +static char *mklong(const char *, const char *); +static char *rmescapes(char *, int); +static char *scanleft(char *, char *, char *, char *, int, int); +static char *scanright(char *, char *, char *, char *, int, int); +static char *single_quote(const char *); +static const char *const *findkwd(const char *); +static const char *expandstr(const char *); +static const char *getprompt(void *); +static double getdouble(void); +static enum token t_lex(char **); +static int aexpr(enum token); +static int binop0(void); +static int bltincmd(int, char **); +static int conv_escape_str(char *, char **); +static int decode_signal(const char *, int); +static int decode_signum(const char *); +static int describe_command(struct output *, char *, const char *, int); +static int eprintlist(struct output *, struct strlist *, int); +static int equalf(const char *, const char *); +static int evalbltin(const struct builtincmd *, int, char **, int); +static int evalcase(union node *, int); +static int evalcommand(union node *, int); +static int evalfor(union node *, int); +static int evalfun(struct funcnode *, int, char **, int); +static int evalloop(union node *, int); +static int evalpipe(union node *, int); +static int evalsubshell(union node *, int); +static int filstat(char *, enum token); +static int forkshell(struct job *, union node *, int); +static int getopts(char *, char *, char **); +static int isassignment(const char *p); +static int isoperand(char **); +static int newerf(const char *, const char *); +static int nexpr(enum token); +static int nextopt(const char *); +static int oexpr(enum token); +static int olderf(const char *, const char *); +static int64_t openhere(union node *); +static int openredirect(union node *); +static int options(int); +static int padvance_magic(const char **path, const char *name, int magic); +static int patmatch(char *, const char *); +static int peektoken(void); +static int pgetc(void); +static int pgetc2(void); +static int pgetc_eatbnl(); +static int pmatch(const char *, const char *); +static int preadbuffer(void); +static ssize_t preadfd(void); +static int primary1(enum token); +static int procargs(int, char **); +static int readtoken(void); +static int readtoken1(int, char const *, char *, int); +static int redirectsafe(union node *, int); +static int savefd(int, int); +static int setinputfile(const char *, int); +static int showvars(const char *, int, int); +static int stoppedjobs(void); +static int test_file_access(const char *, int); +static int unalias(const char *); +static int waitforjob(struct job *); +static int xxreadtoken(void); +static int64_t arith(const char *); +static int64_t assignment(int var_, int noeval); +static int64_t lookupvarint(const char *); +static long varvalue(char *, int, int, int); +static int64_t setvarint(const char *name, int64_t val, int flags); +static struct Var *setvar(const char *name, const char *val, int flags); +static struct Var *setvareq(char *s, int flags); +static struct alias **__lookupalias(const char *); +static struct alias *freealias(struct alias *); +static struct alias *lookupalias(const char *, int); +static struct funcnode *copyfunc(union node *); +static struct job *makejob(union node *, int); +static struct job *vforkexec(union node *n, char **argv, const char *path, int idx); +static struct localvar_list *pushlocalvars(int push); +static struct nodelist *copynodelist(struct nodelist *); +static struct redirtab *pushredir(union node *redir); +static struct strlist *expsort(struct strlist *); +static struct strlist *msort(struct strlist *, int); +static struct tblentry *cmdlookup(const char *, int); +static uint64_t getuintmax(int); +static union node *andor(void); +static union node *command(void); +static union node *copynode(union node *); +static union node *list(int); +static union node *makename(void); +static union node *parsecmd(int); +static union node *pipeline(void); +static union node *simplecmd(void); +static unsigned esclen(const char *, const char *); +static unsigned memtodest(const char *p, unsigned len, int flags); +static unsigned strtodest(const char *p, int flags); +static void addcmdentry(char *, struct cmdentry *); +static void addfname(char *); +static void check_conversion(const char *, const char *); +static void clear_traps(void); +static void clearcmdentry(void); +static void closescript(void); +static void defun(union node *); +static void delete_cmd_entry(void); +static void dotrap(void); +static void dupredirect(union node *, int); +static void exitreset(void); +static void expandarg(union node *arg, struct arglist *arglist, int flag); +static void expandmeta(struct strlist *, int); +static void expbackq(union node *, int); +static void expmeta(char *, unsigned, unsigned); +static void expredir(union node *); +static void find_command(char *, struct cmdentry *, int, const char *); +static void fixredir(union node *, const char *, int); +static void freeparam(volatile struct shparam *); +static void hashcd(void); +static void ignoresig(int); +static void init(void); +static void minus_o(char *, int); +static void mklocal(char *name, int flags); +static void onsig(int); +static void optschanged(void); +static void parsefname(void); +static void parseheredoc(void); +static void popallfiles(void); +static void popfile(void); +static void poplocalvars(int); +static void popredir(int); +static void popstring(void); +static void prehash(union node *); +static void printalias(const struct alias *); +static void printentry(struct tblentry *); +static void pungetc(void); +static void pushfile(void); +static void pushstring(char *, void *); +static void read_profile(const char *); +static void redirect(union node *, int); +static void reset(void); +static void rmaliases(void); +static void setalias(const char *, const char *); +static void setinputfd(int fd, int push); +static void setinputstring(char *); +static void setinteractive(int); +static void setjobctl(int); +static void setparam(char **); +static void setprompt(int); +static void setsignal(int); +static void showjobs(struct output *, int); +static void sigblockall(sigset_t *oldmask); +static void sizenodelist(struct nodelist *); +static void syntax(const char *, const char *); +static void tryexec(char *, char **, char **); +static void unsetfunc(const char *); +static void unsetvar(const char *); +static void unwindfiles(struct parsefile *); +static void unwindlocalvars(struct localvar_list *stop); +static void unwindredir(struct redirtab *stop); +static unsigned cvtnum(int64_t num, int flags); + +static int getchr(void) { + int val = 0; + if (*gargv) val = **gargv++; + return val; +} + +static char *getstr(void) { + char *val = nullstr; + if (*gargv) val = *gargv++; + return val; +} + +/* + * Check for a valid number. This should be elsewhere. + */ +static int is_number(const char *p) { + do { + if (!is_digit(*p)) return 0; + } while (*++p != '\0'); + return 1; +} + +static inline void freestdout() { + output.nextc = output.buf; + output.flags = 0; +} + +static inline void outc(int ch, struct output *file) { + if (file->nextc == file->end) + outcslow(ch, file); + else { + *file->nextc = ch; + file->nextc++; + } +} + +static inline char *_STPUTC(int c, char *p) { + if (p == sstrend) p = growstackstr(); + *p++ = c; + return p; +} + +static void ifsfree(void) { + struct ifsregion *p = ifsfirst.next; + if (!p) goto out; + INTOFF; + do { + struct ifsregion *ifsp; + ifsp = p->next; + ckfree(p); + p = ifsp; + } while (p); + ifsfirst.next = NULL; + INTON; +out: + ifslastp = NULL; +} + +static void setalias(const char *name, const char *val) { + struct alias *ap, **app; + app = __lookupalias(name); + ap = *app; + INTOFF; + if (ap) { + if (!(ap->flag & ALIASINUSE)) { + ckfree(ap->val); + } + ap->val = savestr(val); + ap->flag &= ~ALIASDEAD; + } else { + /* not found */ + ap = ckmalloc(sizeof(struct alias)); + ap->name = savestr(name); + ap->val = savestr(val); + ap->flag = 0; + ap->next = 0; + *app = ap; + } + INTON; +} + +static int unalias(const char *name) { + struct alias **app; + app = __lookupalias(name); + if (*app) { + INTOFF; + *app = freealias(*app); + INTON; + return (0); + } + return (1); +} + +static void rmaliases(void) { + struct alias *ap, **app; + int i; + INTOFF; + for (i = 0; i < ATABSIZE; i++) { + app = &atab[i]; + for (ap = *app; ap; ap = *app) { + *app = freealias(*app); + if (ap == *app) { + app = &ap->next; + } + } + } + INTON; +} + +struct alias *lookupalias(const char *name, int check) { + struct alias *ap = *__lookupalias(name); + if (check && ap && (ap->flag & ALIASINUSE)) return (NULL); + return (ap); +} + +static int aliascmd(int argc, char **argv) { + /* TODO - sort output */ + char *n, *v; + int ret = 0; + struct alias *ap; + if (argc == 1) { + int i; + for (i = 0; i < ATABSIZE; i++) + for (ap = atab[i]; ap; ap = ap->next) { + printalias(ap); + } + return (0); + } + while ((n = *++argv) != NULL) { + if ((v = strchr(n + 1, '=')) == NULL) { /* n+1: funny ksh stuff */ + if ((ap = *__lookupalias(n)) == NULL) { + outfmt(out2, "%s: %s not found\n", "alias", n); + ret = 1; + } else + printalias(ap); + } else { + *v++ = '\0'; + setalias(n, v); + } + } + return (ret); +} + +static int unaliascmd(int argc, char **argv) { + int i; + while ((i = nextopt("a")) != '\0') { + if (i == 'a') { + rmaliases(); + return (0); + } + } + for (i = 0; *argptr; argptr++) { + if (unalias(*argptr)) { + outfmt(out2, "%s: %s not found\n", "unalias", *argptr); + i = 1; + } + } + return i; +} + +static struct alias *freealias(struct alias *ap) { + struct alias *next; + if (ap->flag & ALIASINUSE) { + ap->flag |= ALIASDEAD; + return ap; + } + next = ap->next; + ckfree(ap->name); + ckfree(ap->val); + ckfree(ap); + return next; +} + +static void printalias(const struct alias *ap) { + out1fmt("%s=%s\n", ap->name, single_quote(ap->val)); +} + +static struct alias **__lookupalias(const char *name) { + unsigned int hashval; + struct alias **app; + const char *p; + unsigned int ch; + p = name; + ch = (unsigned char)*p; + hashval = ch << 4; + while (ch) { + hashval += ch; + ch = (unsigned char)*++p; + } + app = &atab[hashval % ATABSIZE]; + for (; *app; app = &(*app)->next) { + if (equal(name, (*app)->name)) { + break; + } + } + return app; +} + +static int shlex() { + int value; + const char *buf = arith_buf; + const char *p; + for (;;) { + value = *buf; + switch (value) { + case ' ': + case '\t': + case '\n': + buf++; + continue; + default: + return ARITH_BAD; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + yylval.val = strtoimax(buf, (char **)&arith_buf, 0); + return ARITH_NUM; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '_': + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + p = buf; + while (buf++, is_in_name(*buf)) + ; + yylval.name = stalloc(buf - p + 1); + *(char *)mempcpy(yylval.name, p, buf - p) = 0; + value = ARITH_VAR; + goto out; + case '=': + value += ARITH_ASS - '='; + checkeq: + buf++; + checkeqcur: + if (*buf != '=') goto out; + value += 11; + break; + case '>': + switch (*++buf) { + case '=': + value += ARITH_GE - '>'; + break; + case '>': + value += ARITH_RSHIFT - '>'; + goto checkeq; + default: + value += ARITH_GT - '>'; + goto out; + } + break; + case '<': + switch (*++buf) { + case '=': + value += ARITH_LE - '<'; + break; + case '<': + value += ARITH_LSHIFT - '<'; + goto checkeq; + default: + value += ARITH_LT - '<'; + goto out; + } + break; + case '|': + if (*++buf != '|') { + value += ARITH_BOR - '|'; + goto checkeqcur; + } + value += ARITH_OR - '|'; + break; + case '&': + if (*++buf != '&') { + value += ARITH_BAND - '&'; + goto checkeqcur; + } + value += ARITH_AND - '&'; + break; + case '!': + if (*++buf != '=') { + value += ARITH_NOT - '!'; + goto out; + } + value += ARITH_NE - '!'; + break; + case 0: + goto out; + case '(': + value += ARITH_LPAREN - '('; + break; + case ')': + value += ARITH_RPAREN - ')'; + break; + case '*': + value += ARITH_MUL - '*'; + goto checkeq; + case '/': + value += ARITH_DIV - '/'; + goto checkeq; + case '%': + value += ARITH_REM - '%'; + goto checkeq; + case '+': + value += ARITH_ADD - '+'; + goto checkeq; + case '-': + value += ARITH_SUB - '-'; + goto checkeq; + case '~': + value += ARITH_BNOT - '~'; + break; + case '^': + value += ARITH_BXOR - '^'; + goto checkeq; + case '?': + value += ARITH_QMARK - '?'; + break; + case ':': + value += ARITH_COLON - ':'; + break; + } + break; + } + buf++; +out: + arith_buf = buf; + return value; +} + +/* + * Compares two strings up to the first = or '\0'. The first string must + * be terminated by '='; the second may be terminated by either '=' or + * '\0'. + */ +static int varcmp(const char *p, const char *q) { + int c, d; + while ((c = *p) == (d = *q)) { + if (!c || c == '=') goto out; + p++; + q++; + } + if (c == '=') c = 0; + if (d == '=') d = 0; +out: + return c - d; +} + +static inline int varequal(const char *a, const char *b) { + return !varcmp(a, b); +} + +/* + * Search the environment of a builtin command. + */ +static inline char *bltinlookup(const char *name) { + return lookupvar(name); +} + +static inline int arith_prec(int op) { + return kPrec[op - ARITH_BINOP_MIN]; +} + +static inline int higher_prec(int op1, int op2) { + return arith_prec(op1) < arith_prec(op2); +} + +static int64_t do_binop(int op, int64_t a, int64_t b) { + switch (op) { + default: + case ARITH_REM: + case ARITH_DIV: + if (!b) yyerror("division by zero"); + return op == ARITH_REM ? a % b : a / b; + case ARITH_MUL: + return a * b; + case ARITH_ADD: + return a + b; + case ARITH_SUB: + return a - b; + case ARITH_LSHIFT: + return a << b; + case ARITH_RSHIFT: + return a >> b; + case ARITH_LT: + return a < b; + case ARITH_LE: + return a <= b; + case ARITH_GT: + return a > b; + case ARITH_GE: + return a >= b; + case ARITH_EQ: + return a == b; + case ARITH_NE: + return a != b; + case ARITH_BAND: + return a & b; + case ARITH_BXOR: + return a ^ b; + case ARITH_BOR: + return a | b; + } +} + +static int64_t primary(int token, union yystype *val, int op, int noeval) { + int64_t result; +again: + switch (token) { + case ARITH_LPAREN: + result = assignment(op, noeval); + if (last_token != ARITH_RPAREN) yyerror("expecting ')'"); + last_token = shlex(); + return result; + case ARITH_NUM: + last_token = op; + return val->val; + case ARITH_VAR: + last_token = op; + return noeval ? val->val : lookupvarint(val->name); + case ARITH_ADD: + token = op; + *val = yylval; + op = shlex(); + goto again; + case ARITH_SUB: + *val = yylval; + return -primary(op, val, shlex(), noeval); + case ARITH_NOT: + *val = yylval; + return !primary(op, val, shlex(), noeval); + case ARITH_BNOT: + *val = yylval; + return ~primary(op, val, shlex(), noeval); + default: + yyerror("expecting primary"); + } +} + +static int64_t binop2(int64_t a, int op, int prec, int noeval) { + for (;;) { + union yystype val; + int64_t b; + int op2; + int token; + token = shlex(); + val = yylval; + b = primary(token, &val, shlex(), noeval); + op2 = last_token; + if (op2 >= ARITH_BINOP_MIN && op2 < ARITH_BINOP_MAX && higher_prec(op2, op)) { + b = binop2(b, op2, arith_prec(op), noeval); + op2 = last_token; + } + a = noeval ? b : do_binop(op, a, b); + if (op2 < ARITH_BINOP_MIN || op2 >= ARITH_BINOP_MAX || arith_prec(op2) >= prec) { + return a; + } + op = op2; + } +} + +static int64_t binop(int token, union yystype *val, int op, int noeval) { + int64_t a = primary(token, val, op, noeval); + op = last_token; + if (op < ARITH_BINOP_MIN || op >= ARITH_BINOP_MAX) return a; + return binop2(a, op, ARITH_MAX_PREC, noeval); +} + +static int64_t and (int token, union yystype *val, int op, int noeval) { + int64_t a = binop(token, val, op, noeval); + int64_t b; + op = last_token; + if (op != ARITH_AND) return a; + token = shlex(); + *val = yylval; + b = and(token, val, shlex(), noeval | !a); + return a && b; +} + +static int64_t or (int token, union yystype *val, int op, int noeval) { + int64_t a = and(token, val, op, noeval); + int64_t b; + op = last_token; + if (op != ARITH_OR) return a; + token = shlex(); + *val = yylval; + b = or (token, val, shlex(), noeval | !!a); + return a || b; +} + +static int64_t cond(int token, union yystype *val, int op, int noeval) { + int64_t a = or (token, val, op, noeval); + int64_t b; + int64_t c; + if (last_token != ARITH_QMARK) return a; + b = assignment(shlex(), noeval | !a); + if (last_token != ARITH_COLON) yyerror("expecting ':'"); + token = shlex(); + *val = yylval; + c = cond(token, val, shlex(), noeval | !!a); + return a ? b : c; +} + +static int64_t assignment(int var_, int noeval) { + union yystype val = yylval; + int op = shlex(); + int64_t result; + if (var_ != ARITH_VAR) return cond(var_, &val, op, noeval); + if (op != ARITH_ASS && (op < ARITH_ASS_MIN || op >= ARITH_ASS_MAX)) { + return cond(var_, &val, op, noeval); + } + result = assignment(shlex(), noeval); + if (noeval) return result; + return setvarint( + val.name, (op == ARITH_ASS ? result : do_binop(op - 11, lookupvarint(val.name), result)), 0); +} + +static int64_t arith(const char *s) { + int64_t result; + arith_buf = arith_startbuf = s; + result = assignment(shlex(), 0); + if (last_token) yyerror("expecting EOF"); + return result; +} + +/* + * The cd and pwd commands. + */ +static inline int padvance(const char **path, const char *name) { + return padvance_magic(path, name, 1); +} + +static char *getpwd(void); +static const char *updatepwd(const char *); +static int cdopt(void); +static int docd(const char *, int); +static void setpwd(const char *, int); + +static int cdopt() { + int flags = 0; + int i, j; + j = 'L'; + while ((i = nextopt("LP"))) { + if (i != j) { + flags ^= CD_PHYSICAL; + j = i; + } + } + return flags; +} + +static int cdcmd(int argc, char **argv) { + const char *dest; + const char *path; + const char *p; + char c; + struct stat statb; + int flags; + int len; + flags = cdopt(); + dest = *argptr; + if (!dest) + dest = bltinlookup(homestr); + else if (dest[0] == '-' && dest[1] == '\0') { + dest = bltinlookup("OLDPWD"); + flags |= CD_PRINT; + } + if (!dest) dest = nullstr; + if (*dest == '/') goto step6; + if (*dest == '.') { + c = dest[1]; + dotdot: + switch (c) { + case '\0': + case '/': + goto step6; + case '.': + c = dest[2]; + if (c != '.') goto dotdot; + } + } + if (!*dest) dest = "."; + path = bltinlookup("CDPATH"); + while (p = path, (len = padvance_magic(&path, dest, 0)) >= 0) { + c = *p; + p = stalloc(len); + if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) { + if (c && c != ':') flags |= CD_PRINT; + docd: + if (!docd(p, flags)) goto out; + goto err; + } + } +step6: + p = dest; + goto docd; +err: + sh_error("can't cd to %s", dest); + /* NOTREACHED */ +out: + if (flags & CD_PRINT) out1fmt(snlfmt, curdir); + return 0; +} + +/* + * Actually do the chdir. We also call hashcd to let the routines in exec.c + * know that the current directory has changed. + */ +static int docd(const char *dest, int flags) { + const char *dir = 0; + int err; + TRACE(("docd(\"%s\", %d) called\n", dest, flags)); + INTOFF; + if (!(flags & CD_PHYSICAL)) { + dir = updatepwd(dest); + if (dir) dest = dir; + } + err = chdir(dest); + if (err) goto out; + setpwd(dir, 1); + hashcd(); +out: + INTON; + return err; +} + +/* + * Update curdir (the name of the current directory) in response to a + * cd command. + */ +static const char *updatepwd(const char *dir) { + char *new; + char *p; + char *cdcomppath; + const char *lim; + cdcomppath = sstrdup(dir); + STARTSTACKSTR(new); + if (*dir != '/') { + if (curdir == nullstr) return 0; + new = stputs(curdir, new); + } + new = makestrspace(strlen(dir) + 2, new); + lim = (char *)stackblock() + 1; + if (*dir != '/') { + if (new[-1] != '/') USTPUTC('/', new); + if (new > lim &&*lim == '/') lim++; + } else { + USTPUTC('/', new); + cdcomppath++; + if (dir[1] == '/' && dir[2] != '/') { + USTPUTC('/', new); + cdcomppath++; + lim++; + } + } + p = strtok(cdcomppath, "/"); + while (p) { + switch (*p) { + case '.': + if (p[1] == '.' && p[2] == '\0') { + while (new > lim) { + STUNPUTC(new); + if (new[-1] == '/') break; + } + break; + } else if (p[1] == '\0') + break; + /* fall through */ + default: + new = stputs(p, new); + USTPUTC('/', new); + } + p = strtok(0, "/"); + } + if (new > lim) STUNPUTC(new); + *new = 0; + return stackblock(); +} + +/* + * Find out what the current directory is. If we already know the + * current directory, this routine returns immediately. + */ +static inline char *getpwd() { + char buf[PATH_MAX]; + if (getcwd(buf, sizeof(buf))) return savestr(buf); + sh_warnx("getcwd() failed: %s", strerror(errno)); + return nullstr; +} + +static int pwdcmd(int argc, char **argv) { + int flags; + const char *dir = curdir; + flags = cdopt(); + if (flags) { + if (physdir == nullstr) setpwd(dir, 0); + dir = physdir; + } + out1fmt(snlfmt, dir); + return 0; +} + +static void setpwd(const char *val, int setold) { + char *oldcur, *dir; + oldcur = dir = curdir; + if (setold) { + setvar("OLDPWD", oldcur, VEXPORT); + } + INTOFF; + if (physdir != nullstr) { + if (physdir != oldcur) free(physdir); + physdir = nullstr; + } + if (oldcur == val || !val) { + char *s = getpwd(); + physdir = s; + if (!val) dir = s; + } else + dir = savestr(val); + if (oldcur != dir && oldcur != nullstr) { + free(oldcur); + } + curdir = dir; + INTON; + setvar("PWD", dir, VEXPORT); +} + +/* + * Errors and exceptions. + */ + +/* + * NEOF is returned by parsecmd when it encounters an end of file. It + * must be distinct from NULL, so we use the address of a variable that + * happens to be handy. + */ +#define NEOF ((union node *)&tokpushback) + +/* + * Return of a legal variable name (a letter or underscore followed by zero or + * more letters, underscores, and digits). + */ +static char *endofname(const char *name) { + char *p; + p = (char *)name; + if (!is_name(*p)) return p; + while (*++p) { + if (!is_in_name(*p)) break; + } + return p; +} + +static inline int goodname(const char *p) { + return !*endofname(p); +} +static inline int parser_eof(void) { + return tokpushback && lasttoken == TEOF; +} +static inline int have_traps(void) { + return trapcnt; +} + +static const struct builtincmd kBltin = { + .name = nullstr, + .builtin = bltincmd, + .flags = BUILTIN_REGULAR, +}; + +/* + * Evaluate a parse tree. The value is left in the global variable + * exitstatus. + */ +static int evaltree(union node *n, int flags) { + int checkexit = 0; + int (*evalfn)(union node *, int); + unsigned isor; + int status = 0; + if (n == NULL) { + TRACE(("evaltree(NULL) called\n")); + goto out; + } + dotrap(); + TRACE(("pid %d, evaltree(%p: %d, %d) called\n", getpid(), n, n->type, flags)); + switch (n->type) { + default: + case NNOT: + status = !evaltree(n->nnot.com, EV_TESTED); + goto setstatus; + case NREDIR: + errlinno = lineno = n->nredir.linno; + if (funcline) lineno -= funcline - 1; + expredir(n->nredir.redirect); + pushredir(n->nredir.redirect); + status = (redirectsafe(n->nredir.redirect, REDIR_PUSH) + ?: evaltree(n->nredir.n, flags & EV_TESTED)); + if (n->nredir.redirect) popredir(0); + goto setstatus; + case NCMD: + evalfn = evalcommand; + checkexit: + if (eflag && !(flags & EV_TESTED)) checkexit = ~0; + goto calleval; + case NFOR: + evalfn = evalfor; + goto calleval; + case NWHILE: + case NUNTIL: + evalfn = evalloop; + goto calleval; + case NSUBSHELL: + case NBACKGND: + evalfn = evalsubshell; + goto checkexit; + case NPIPE: + evalfn = evalpipe; + goto checkexit; + case NCASE: + evalfn = evalcase; + goto calleval; + case NAND: + case NOR: + case NSEMI: + isor = n->type - NAND; + status = evaltree(n->nbinary.ch1, (flags | ((isor >> 1) - 1)) & EV_TESTED); + /* XXX: -Wlogical-not-parentheses: + if (!status == isor || evalskip) break; */ + if ((!status) == isor || evalskip) break; + n = n->nbinary.ch2; + evaln: + evalfn = evaltree; + calleval: + status = evalfn(n, flags); + goto setstatus; + case NIF: + status = evaltree(n->nif.test, EV_TESTED); + if (evalskip) break; + if (!status) { + n = n->nif.ifpart; + goto evaln; + } else if (n->nif.elsepart) { + n = n->nif.elsepart; + goto evaln; + } + status = 0; + goto setstatus; + case NDEFUN: + defun(n); + setstatus: + exitstatus = status; + break; + } +out: + if (checkexit & status) goto exexit; + dotrap(); + if (flags & EV_EXIT) { + exexit: + exraise(EXEXIT); + } + return exitstatus; +} + +noreturn static void evaltreenr(union node *n, int flags) { + evaltree(n, flags); + abort(); +} + +/* + * Execute a command or commands contained in a string. + */ +static int evalstring(char *s, int flags) { + union node *n; + struct stackmark smark; + int status; + s = sstrdup(s); + setinputstring(s); + setstackmark(&smark); + status = 0; + for (; (n = parsecmd(0)) != NEOF; popstackmark(&smark)) { + int i; + i = evaltree(n, flags & ~(parser_eof() ? 0 : EV_EXIT)); + if (n) status = i; + if (evalskip) break; + } + popstackmark(&smark); + popfile(); + stunalloc(s); + return status; +} + +static int evalcmd(int argc, char **argv, int flags) { + char *p; + char *concat; + char **ap; + if (argc > 1) { + p = argv[1]; + if (argc > 2) { + STARTSTACKSTR(concat); + ap = argv + 2; + for (;;) { + concat = stputs(p, concat); + if ((p = *ap++) == NULL) break; + STPUTC(' ', concat); + } + STPUTC('\0', concat); + p = grabstackstr(concat); + } + return evalstring(p, flags & EV_TESTED); + } + return 0; +} + +static int skiploop(void) { + int skip = evalskip; + switch (skip) { + case 0: + break; + case SKIPBREAK: + case SKIPCONT: + if (likely(--skipcount <= 0)) { + evalskip = 0; + break; + } + skip = SKIPBREAK; + break; + } + return skip; +} + +static int evalloop(union node *n, int flags) { + int skip; + int status; + loopnest++; + status = 0; + flags &= EV_TESTED; + do { + int i; + i = evaltree(n->nbinary.ch1, EV_TESTED); + skip = skiploop(); + if (skip == SKIPFUNC) status = i; + if (skip) continue; + if (n->type != NWHILE) i = !i; + if (i != 0) break; + status = evaltree(n->nbinary.ch2, flags); + skip = skiploop(); + } while (!(skip & ~SKIPCONT)); + loopnest--; + return status; +} + +static int evalfor(union node *n, int flags) { + struct arglist arglist; + union node *argp; + struct strlist *sp; + struct stackmark smark; + int status; + errlinno = lineno = n->nfor.linno; + if (funcline) lineno -= funcline - 1; + setstackmark(&smark); + arglist.lastp = &arglist.list; + for (argp = n->nfor.args; argp; argp = argp->narg.next) { + expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); + } + *arglist.lastp = NULL; + status = 0; + loopnest++; + flags &= EV_TESTED; + for (sp = arglist.list; sp; sp = sp->next) { + setvar(n->nfor.var_, sp->text, 0); + status = evaltree(n->nfor.body, flags); + if (skiploop() & ~SKIPCONT) break; + } + loopnest--; + popstackmark(&smark); + return status; +} + +/* + * See if a pattern matches in a case statement. + */ +static int casematch(union node *pattern, char *val) { + struct stackmark smark; + int result; + setstackmark(&smark); + argbackq = pattern->narg.backquote; + STARTSTACKSTR(expdest); + argstr(pattern->narg.text, EXP_TILDE | EXP_CASE); + ifsfree(); + result = patmatch(stackblock(), val); + popstackmark(&smark); + return result; +} + +static int evalcase(union node *n, int flags) { + union node *cp; + union node *patp; + struct arglist arglist; + struct stackmark smark; + int status = 0; + errlinno = lineno = n->ncase.linno; + if (funcline) lineno -= funcline - 1; + setstackmark(&smark); + arglist.lastp = &arglist.list; + expandarg(n->ncase.expr, &arglist, EXP_TILDE); + for (cp = n->ncase.cases; cp && evalskip == 0; cp = cp->nclist.next) { + for (patp = cp->nclist.pattern; patp; patp = patp->narg.next) { + if (casematch(patp, arglist.list->text)) { + /* Ensure body is non-empty as otherwise + * EV_EXIT may prevent us from setting the + * exit status. + */ + if (evalskip == 0 && cp->nclist.body) { + status = evaltree(cp->nclist.body, flags); + } + goto out; + } + } + } +out: + popstackmark(&smark); + return status; +} + +/* + * Kick off a subshell to evaluate a tree. + */ +static int evalsubshell(union node *n, int flags) { + struct job *jp; + int backgnd = (n->type == NBACKGND); + int status; + errlinno = lineno = n->nredir.linno; + if (funcline) lineno -= funcline - 1; + expredir(n->nredir.redirect); + if (!backgnd && flags & EV_EXIT && !have_traps()) goto nofork; + INTOFF; + jp = makejob(n, 1); + if (forkshell(jp, n, backgnd) == 0) { + INTON; + flags |= EV_EXIT; + if (backgnd) flags &= ~EV_TESTED; + nofork: + redirect(n->nredir.redirect, 0); + evaltreenr(n->nredir.n, flags); + /* never returns */ + } + status = 0; + if (!backgnd) status = waitforjob(jp); + INTON; + return status; +} + +/* + * Compute the names of the files in a redirection list. + */ +static void expredir(union node *n) { + union node *redir; + for (redir = n; redir; redir = redir->nfile.next) { + struct arglist fn; + fn.lastp = &fn.list; + switch (redir->type) { + case NFROMTO: + case NFROM: + case NTO: + case NCLOBBER: + case NAPPEND: + expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); + redir->nfile.expfname = fn.list->text; + break; + case NFROMFD: + case NTOFD: + if (redir->ndup.vname) { + expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE); + fixredir(redir, fn.list->text, 1); + } + break; + } + } +} + +/* + * Evaluate a pipeline. All the processes in the pipeline are children + * of the process creating the pipeline. (This differs from some versions + * of the shell, which make the last process in a pipeline the parent + * of all the rest.) + */ +static int evalpipe(union node *n, int flags) { + struct job *jp; + struct nodelist *lp; + int pipelen; + int prevfd; + int pip[2]; + int status = 0; + TRACE(("evalpipe(0x%lx) called\n", (long)n)); + pipelen = 0; + for (lp = n->npipe.cmdlist; lp; lp = lp->next) pipelen++; + flags |= EV_EXIT; + INTOFF; + jp = makejob(n, pipelen); + prevfd = -1; + for (lp = n->npipe.cmdlist; lp; lp = lp->next) { + prehash(lp->n); + pip[1] = -1; + if (lp->next) { + if (pipe(pip) < 0) { + close(prevfd); + sh_error("Pipe call failed"); + } + } + if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) { + INTON; + if (pip[1] >= 0) { + close(pip[0]); + } + if (prevfd > 0) { + dup2(prevfd, 0); + close(prevfd); + } + if (pip[1] > 1) { + dup2(pip[1], 1); + close(pip[1]); + } + evaltreenr(lp->n, flags); + /* never returns */ + } + if (prevfd >= 0) close(prevfd); + prevfd = pip[0]; + close(pip[1]); + } + if (n->npipe.backgnd == 0) { + status = waitforjob(jp); + TRACE(("evalpipe: job done exit status %d\n", status)); + } + INTON; + return status; +} + +/* + * Execute a command inside back quotes. If it's a builtin command, we + * want to save its output in a block obtained from malloc. Otherwise + * we fork off a subprocess and get the output of the command via a pipe. + * Should be called with interrupts off. + */ +static void evalbackcmd(union node *n, struct backcmd *result) { + int pip[2]; + struct job *jp; + result->fd = -1; + result->buf = NULL; + result->nleft = 0; + result->jp = NULL; + if (n == NULL) { + goto out; + } + if (pipe(pip) < 0) sh_error("Pipe call failed"); + jp = makejob(n, 1); + if (forkshell(jp, n, FORK_NOJOB) == 0) { + FORCEINTON; + close(pip[0]); + if (pip[1] != 1) { + dup2(pip[1], 1); + close(pip[1]); + } + ifsfree(); + evaltreenr(n, EV_EXIT); + /* NOTREACHED */ + } + close(pip[1]); + result->fd = pip[0]; + result->jp = jp; +out: + TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n", result->fd, result->buf, + result->nleft, result->jp)); +} + +static struct strlist *fill_arglist(struct arglist *arglist, union node **argpp) { + struct strlist **lastp = arglist->lastp; + union node *argp; + while ((argp = *argpp)) { + expandarg(argp, arglist, EXP_FULL | EXP_TILDE); + *argpp = argp->narg.next; + if (*lastp) break; + } + return *lastp; +} + +static int parse_command_args(struct arglist *arglist, union node **argpp, const char **path) { + struct strlist *sp = arglist->list; + char *cp, c; + for (;;) { + sp = unlikely(sp->next != NULL) ? sp->next : fill_arglist(arglist, argpp); + if (!sp) return 0; + cp = sp->text; + if (*cp++ != '-') break; + if (!(c = *cp++)) break; + if (c == '-' && !*cp) { + if (likely(!sp->next) && !fill_arglist(arglist, argpp)) return 0; + sp = sp->next; + break; + } + do { + switch (c) { + case 'p': + *path = defpath; + break; + default: + /* run 'typecmd' for other options */ + return 0; + } + } while ((c = *cp++)); + } + arglist->list = sp; + return DO_NOFUNC; +} + +/* + * Execute a simple command. + */ +static int evalcommand(union node *cmd, int flags) { + struct localvar_list *localvar_stop; + struct parsefile *file_stop; + struct redirtab *redir_stop; + struct stackmark smark; + union node *argp; + struct arglist arglist; + struct arglist varlist; + char **argv; + int argc; + struct strlist *osp; + struct strlist *sp; + struct cmdentry cmdentry; + struct job *jp; + char *lastarg; + const char *path; + int spclbltin; + int cmd_flag; + int execcmd; + int status; + char **nargv; + int vflags; + int vlocal; + errlinno = lineno = cmd->ncmd.linno; + if (funcline) lineno -= funcline - 1; + /* First expand the arguments. */ + TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags)); + setstackmark(&smark); + file_stop = parsefile; + back_exitstatus = 0; + cmdentry.cmdtype = CMDBUILTIN; + cmdentry.u.cmd = &kBltin; + varlist.lastp = &varlist.list; + *varlist.lastp = NULL; + arglist.lastp = &arglist.list; + *arglist.lastp = NULL; + cmd_flag = 0; + execcmd = 0; + spclbltin = -1; + vflags = 0; + vlocal = 0; + path = NULL; + argc = 0; + argp = cmd->ncmd.args; + if ((osp = fill_arglist(&arglist, &argp))) { + int pseudovarflag = 0; + for (;;) { + find_command(arglist.list->text, &cmdentry, cmd_flag | DO_REGBLTIN, pathval()); + vlocal++; + /* implement bltin and command here */ + if (cmdentry.cmdtype != CMDBUILTIN) break; + pseudovarflag = cmdentry.u.cmd->flags & BUILTIN_ASSIGN; + if (likely(spclbltin < 0)) { + spclbltin = cmdentry.u.cmd->flags & BUILTIN_SPECIAL; + vlocal = spclbltin ^ BUILTIN_SPECIAL; + } + execcmd = cmdentry.u.cmd == EXECCMD; + if (likely(cmdentry.u.cmd != COMMANDCMD)) break; + cmd_flag = parse_command_args(&arglist, &argp, &path); + if (!cmd_flag) break; + } + for (; argp; argp = argp->narg.next) { + expandarg( + argp, &arglist, + (pseudovarflag && isassignment(argp->narg.text)) ? EXP_VARTILDE : EXP_FULL | EXP_TILDE); + } + for (sp = arglist.list; sp; sp = sp->next) argc++; + if (execcmd && argc > 1) vflags = VEXPORT; + } + localvar_stop = pushlocalvars(vlocal); + /* Reserve one extra spot at the front for shellexec. */ + nargv = stalloc(sizeof(char *) * (argc + 2)); + argv = ++nargv; + for (sp = arglist.list; sp; sp = sp->next) { + TRACE(("evalcommand arg: %s\n", sp->text)); + *nargv++ = sp->text; + } + *nargv = NULL; + lastarg = NULL; + if (iflag && funcline == 0 && argc > 0) lastarg = nargv[-1]; + preverrout.fd = 2; + expredir(cmd->ncmd.redirect); + redir_stop = pushredir(cmd->ncmd.redirect); + status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2); + if (unlikely(status)) { + bail: + exitstatus = status; + /* We have a redirection error. */ + if (spclbltin > 0) exraise(EXERROR); + goto out; + } + for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) { + struct strlist **spp; + spp = varlist.lastp; + expandarg(argp, &varlist, EXP_VARTILDE); + if (vlocal) + mklocal((*spp)->text, VEXPORT); + else + setvareq((*spp)->text, vflags); + } + /* Print the command if xflag is set. */ + if (xflag) { + struct output *out; + int sep; + out = &preverrout; + outstr(expandstr(ps4val()), out); + sep = 0; + sep = eprintlist(out, varlist.list, sep); + eprintlist(out, osp, sep); + outcslow('\n', out); + } + /* Now locate the command. */ + if (cmdentry.cmdtype != CMDBUILTIN || !(cmdentry.u.cmd->flags & BUILTIN_REGULAR)) { + path = unlikely(path != NULL) ? path : pathval(); + find_command(argv[0], &cmdentry, cmd_flag | DO_ERR, path); + } + jp = NULL; + /* Execute the command. */ + switch (cmdentry.cmdtype) { + case CMDUNKNOWN: + status = 127; + goto bail; + default: + /* Fork off a child process if necessary. */ + if (!(flags & EV_EXIT) || have_traps()) { + INTOFF; + jp = vforkexec(cmd, argv, path, cmdentry.u.index); + break; + } + shellexec(argv, path, cmdentry.u.index); + /* NOTREACHED */ + case CMDBUILTIN: + if (evalbltin(cmdentry.u.cmd, argc, argv, flags) && + !(exception == EXERROR && spclbltin <= 0)) { + raise: + longjmp(handler->loc, 1); + } + break; + case CMDFUNCTION: + if (evalfun(cmdentry.u.func, argc, argv, flags)) goto raise; + break; + } + status = waitforjob(jp); + FORCEINTON; +out: + if (cmd->ncmd.redirect) popredir(execcmd); + unwindredir(redir_stop); + unwindfiles(file_stop); + unwindlocalvars(localvar_stop); + if (lastarg) { + /* dsl: I think this is intended to be used to support + * '_' in 'vi' command mode during line editing... + * However I implemented that within libedit itself. + */ + setvar("_", lastarg, 0); + } + popstackmark(&smark); + return status; +} + +static int evalbltin(const struct builtincmd *cmd, int argc, char **argv, int flags) { + char *volatile savecmdname; + struct jmploc *volatile savehandler; + struct jmploc jmploc; + int status; + int i; + + savecmdname = commandname; + savehandler = handler; + if ((i = setjmp(jmploc.loc))) goto cmddone; + handler = &jmploc; + commandname = argv[0]; + argptr = argv + 1; + optptr = NULL; /* initialize nextopt */ + if (cmd == EVALCMD) + status = evalcmd(argc, argv, flags); + else + status = (*cmd->builtin)(argc, argv); + flushall(); + status |= out1->flags; + exitstatus = status; +cmddone: + freestdout(); + commandname = savecmdname; + handler = savehandler; + + return i; +} + +/* + * Free a parse tree. + */ +static void freefunc(struct funcnode *f) { + if (f && --f->count < 0) ckfree(f); +} + +static int evalfun(struct funcnode *func, int argc, char **argv, int flags) { + volatile struct shparam saveparam; + struct jmploc *volatile savehandler; + struct jmploc jmploc; + int e; + int savefuncline; + int saveloopnest; + saveparam = shellparam; + savefuncline = funcline; + saveloopnest = loopnest; + savehandler = handler; + if ((e = setjmp(jmploc.loc))) { + goto funcdone; + } + INTOFF; + handler = &jmploc; + shellparam.malloc = 0; + func->count++; + funcline = func->n.ndefun.linno; + loopnest = 0; + INTON; + shellparam.nparam = argc - 1; + shellparam.p = argv + 1; + shellparam.optind = 1; + shellparam.optoff = -1; + evaltree(func->n.ndefun.body, flags & EV_TESTED); +funcdone: + INTOFF; + loopnest = saveloopnest; + funcline = savefuncline; + freefunc(func); + freeparam(&shellparam); + shellparam = saveparam; + handler = savehandler; + INTON; + evalskip &= ~(SKIPFUNC | SKIPFUNCDEF); + return e; +} + +/* + * Search for a command. This is called before we fork so that the + * location of the command will be available in the parent as well as + * the child. The check for "goodname" is an overly conservative + * check that the name will not be subject to expansion. + */ +static void prehash(union node *n) { + struct cmdentry entry; + if (n->type == NCMD && n->ncmd.args) + if (goodname(n->ncmd.args->narg.text)) + find_command(n->ncmd.args->narg.text, &entry, 0, pathval()); +} + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § the unbourne shell » builtins ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + Builtin commands whose functions are closely tied to evaluation are + implemented here. */ + +static int falsecmd(int argc, char **argv) { + return 1; +} + +static int truecmd(int argc, char **argv) { + return 0; +} + +/* No command given. */ +static int bltincmd(int argc, char **argv) { + /* + * Preserve exitstatus of a previous possible redirection + * as POSIX mandates + */ + return back_exitstatus; +} + +/* + * Handle break and continue commands. Break, continue, and return are + * all handled by setting the evalskip flag. The evaluation routines + * above all check this flag, and if it is set they start skipping + * commands rather than executing them. The variable skipcount is + * the number of loops to break/continue, or the number of function + * levels to return. (The latter is always 1.) It should probably + * be an error to break out of more loops than exist, but it isn't + * in the standard shell so we don't make it one here. + */ +static int breakcmd(int argc, char **argv) { + int n = argc > 1 ? number(argv[1]) : 1; + if (n <= 0) badnum(argv[1]); + if (n > loopnest) n = loopnest; + if (n > 0) { + evalskip = (**argv == 'c') ? SKIPCONT : SKIPBREAK; + skipcount = n; + } + return 0; +} + +/* The return command. */ +static int returncmd(int argc, char **argv) { + int skip; + int status; + /* + * If called outside a function, do what ksh does; + * skip the rest of the file. + */ + if (argv[1]) { + skip = SKIPFUNC; + status = number(argv[1]); + } else { + skip = SKIPFUNCDEF; + status = exitstatus; + } + evalskip = skip; + return status; +} + +static int execcmd(int argc, char **argv) { + if (argc > 1) { + iflag = 0; /* exit on error */ + mflag = 0; + optschanged(); + shellexec(argv + 1, pathval(), 0); + } + return 0; +} + +static int eprintlist(struct output *out, struct strlist *sp, int sep) { + while (sp) { + const char *p; + p = &" %s"[!sep]; /* XXX: -Wstring-plus-int: p = " %s" + (1 - sep); */ + sep |= 1; + outfmt(out, p, sp->text); + sp = sp->next; + } + return sep; +} + +/* + * When commands are first encountered, they are entered in a hash table. + * This ensures that a full path search will not have to be done for them + * on each invocation. + * + * We should investigate converting to a linear search, even though that + * would make the command name "hash" a misnomer. + */ + +/* + * Exec a program. Never returns. If you change this routine, you may + * have to change the find_command routine as well. + */ +noreturn static void shellexec(char **argv, const char *path, int idx) { + char *cmdname; + int e; + char **envp; + int exerrno; + envp = environment(); + if (strchr(argv[0], '/') != NULL) { + tryexec(argv[0], argv, envp); + e = errno; + } else { + e = ENOENT; + while (padvance(&path, argv[0]) >= 0) { + cmdname = stackblock(); + if (--idx < 0 && pathopt == NULL) { + tryexec(cmdname, argv, envp); + if (errno != ENOENT && errno != ENOTDIR) e = errno; + } + } + } + /* Map to POSIX errors */ + exerrno = (e == ELOOP || e == ENAMETOOLONG || e == ENOENT || e == ENOTDIR) ? 127 : 126; + exitstatus = exerrno; + TRACE(("shellexec failed for %s, errno %d, suppressint %d\n", argv[0], e, suppressint)); + exerror(EXEXIT, "%s: %s", argv[0], errmsg(e, E_EXEC)); +} + +static void tryexec(char *cmd, char **argv, char **envp) { + char *const path_bshell = _PATH_BSHELL; +repeat: + execve(cmd, argv, envp); + if (cmd != path_bshell && errno == ENOEXEC) { + *argv-- = cmd; + *argv = cmd = path_bshell; + goto repeat; + } +} + +static const char *legal_pathopt(const char *opt, const char *term, int magic) { + switch (magic) { + case 0: + opt = NULL; + break; + case 1: + opt = prefix(opt, "builtin") ?: prefix(opt, "func"); + break; + default: + opt += strcspn(opt, term); + break; + } + if (opt && *opt == '%') opt++; + return opt; +} + +/* + * Do a path search. The variable path (passed by reference) should be + * set to the start of the path before the first call; padvance will update + * this value as it proceeds. Successive calls to padvance will return + * the possible path expansions in sequence. If an option (indicated by + * a percent sign) appears in the path entry then the global variable + * pathopt will be set to point to it; otherwise pathopt will be set to + * NULL. + * + * If magic is 0 then pathopt recognition will be disabled. If magic is + * 1 we shall recognise %builtin/%func. Otherwise we shall accept any + * pathopt. + */ +static int padvance_magic(const char **path, const char *name, int magic) { + const char *term = "%:"; + const char *lpathopt; + const char *p; + char *q; + const char *start; + unsigned qlen; + unsigned len; + if (*path == NULL) return -1; + lpathopt = NULL; + start = *path; + if (*start == '%' && (p = legal_pathopt(start + 1, term, magic))) { + lpathopt = start + 1; + start = p; + term = ":"; + } + len = strcspn(start, term); + p = start + len; + if (*p == '%') { + unsigned extra = strchrnul(p, ':') - p; + if (legal_pathopt(p + 1, term, magic)) + lpathopt = p + 1; + else + len += extra; + p += extra; + } + pathopt = lpathopt; + *path = *p == ':' ? p + 1 : NULL; + /* "2" is for '/' and '\0' */ + qlen = len + strlen(name) + 2; + q = growstackto(qlen); + if (likely(len)) { + q = mempcpy(q, start, len); + *q++ = '/'; + } + strcpy(q, name); + return qlen; +} + +/*** Command hashing code ***/ +static int hashcmd(int argc, char **argv) { + struct tblentry **pp; + struct tblentry *cmdp; + int c; + struct cmdentry entry; + char *name; + while ((c = nextopt("r")) != '\0') { + clearcmdentry(); + return 0; + } + if (*argptr == NULL) { + for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) { + for (cmdp = *pp; cmdp; cmdp = cmdp->next) { + if (cmdp->cmdtype == CMDNORMAL) { + printentry(cmdp); + } + } + } + return 0; + } + c = 0; + while ((name = *argptr) != NULL) { + if ((cmdp = cmdlookup(name, 0)) && + (cmdp->cmdtype == CMDNORMAL || + (cmdp->cmdtype == CMDBUILTIN && !(cmdp->param.cmd->flags & BUILTIN_REGULAR) && + builtinloc > 0))) { + delete_cmd_entry(); + } + find_command(name, &entry, DO_ERR, pathval()); + if (entry.cmdtype == CMDUNKNOWN) c = 1; + argptr++; + } + return c; +} + +static void printentry(struct tblentry *cmdp) { + int idx; + const char *path; + char *name; + idx = cmdp->param.index; + path = pathval(); + do { + padvance(&path, cmdp->cmdname); + } while (--idx >= 0); + name = stackblock(); + outstr(name, out1); + out1fmt(snlfmt, cmdp->rehash ? "*" : nullstr); +} + +static int cmdloop(int top); + +/* + * Read a file containing shell functions. + */ +static void readcmdfile(char *name) { + setinputfile(name, INPUT_PUSH_FILE); + cmdloop(0); + popfile(); +} + +/* + * Search the table of builtin commands. + */ +static struct builtincmd *find_builtin(const char *name) { + struct builtincmd *bp; + bp = bsearch(&name, builtincmd, sizeof(builtincmd) / sizeof(builtincmd[0]), sizeof(builtincmd[0]), + pstrcmp); + return bp; +} + +/* + * Resolve a command name. If you change this routine, you may have to + * change the shellexec routine as well. + */ +static void find_command(char *name, struct cmdentry *entry, int act, const char *path) { + struct tblentry *cmdp; + int idx; + int prev; + char *fullname; + struct stat statb; + int e; + int updatetbl; + struct builtincmd *bcmd; + int len; + /* If name contains a slash, don't use PATH or hash table */ + if (strchr(name, '/') != NULL) { + entry->u.index = -1; + if (act & DO_ABS) { + while (stat(name, &statb) < 0) { + entry->cmdtype = CMDUNKNOWN; + return; + } + } + entry->cmdtype = CMDNORMAL; + return; + } + updatetbl = (path == pathval()); + if (!updatetbl) act |= DO_ALTPATH; + /* If name is in the table, check answer will be ok */ + if ((cmdp = cmdlookup(name, 0)) != NULL) { + int bit; + switch (cmdp->cmdtype) { + default: + case CMDNORMAL: + bit = DO_ALTPATH | DO_REGBLTIN; + break; + case CMDFUNCTION: + bit = DO_NOFUNC; + break; + case CMDBUILTIN: + bit = cmdp->param.cmd->flags & BUILTIN_REGULAR ? 0 : DO_REGBLTIN; + break; + } + if (act & bit) { + if (act & bit & DO_REGBLTIN) goto fail; + updatetbl = 0; + cmdp = NULL; + } else if (cmdp->rehash == 0) + /* if not invalidated by cd, we're done */ + goto success; + } + /* If %builtin not in path, check for builtin next */ + bcmd = find_builtin(name); + if (bcmd && ((bcmd->flags & BUILTIN_REGULAR) | (act & DO_ALTPATH) | (builtinloc <= 0))) { + goto builtin_success; + } + if (act & DO_REGBLTIN) goto fail; + /* We have to search path. */ + prev = -1; /* where to start */ + if (cmdp && cmdp->rehash) { /* doing a rehash */ + if (cmdp->cmdtype == CMDBUILTIN) + prev = builtinloc; + else + prev = cmdp->param.index; + } + e = ENOENT; + idx = -1; +loop: + while ((len = padvance(&path, name)) >= 0) { + const char *lpathopt = pathopt; + fullname = stackblock(); + idx++; + if (lpathopt) { + if (*lpathopt == 'b') { + if (bcmd) goto builtin_success; + continue; + } else if (!(act & DO_NOFUNC)) { + /* handled below */ + } else { + /* ignore unimplemented options */ + continue; + } + } + /* if rehash, don't redo absolute path names */ + if (fullname[0] == '/' && idx <= prev) { + if (idx < prev) continue; + TRACE(("searchexec \"%s\": no change\n", name)); + goto success; + } + while (stat(fullname, &statb) < 0) { + if (errno != ENOENT && errno != ENOTDIR) e = errno; + goto loop; + } + e = EACCES; /* if we fail, this will be the error */ + if (!S_ISREG(statb.st_mode)) continue; + if (lpathopt) { /* this is a %func directory */ + stalloc(len); + readcmdfile(fullname); + if ((cmdp = cmdlookup(name, 0)) == NULL || cmdp->cmdtype != CMDFUNCTION) { + sh_error("%s not defined in %s", name, fullname); + } + stunalloc(fullname); + goto success; + } + TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname)); + if (!updatetbl) { + entry->cmdtype = CMDNORMAL; + entry->u.index = idx; + return; + } + INTOFF; + cmdp = cmdlookup(name, 1); + cmdp->cmdtype = CMDNORMAL; + cmdp->param.index = idx; + INTON; + goto success; + } + /* We failed. If there was an entry for this command, delete it */ + if (cmdp && updatetbl) delete_cmd_entry(); + if (act & DO_ERR) sh_warnx("%s: %s", name, errmsg(e, E_EXEC)); +fail: + entry->cmdtype = CMDUNKNOWN; + return; +builtin_success: + if (!updatetbl) { + entry->cmdtype = CMDBUILTIN; + entry->u.cmd = bcmd; + return; + } + INTOFF; + cmdp = cmdlookup(name, 1); + cmdp->cmdtype = CMDBUILTIN; + cmdp->param.cmd = bcmd; + INTON; +success: + cmdp->rehash = 0; + entry->cmdtype = cmdp->cmdtype; + entry->u = cmdp->param; +} + +/* + * Called when a cd is done. Marks all commands so the next time they + * are executed they will be rehashed. + */ +static void hashcd(void) { + struct tblentry **pp; + struct tblentry *cmdp; + for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) { + for (cmdp = *pp; cmdp; cmdp = cmdp->next) { + if (cmdp->cmdtype == CMDNORMAL || + (cmdp->cmdtype == CMDBUILTIN && !(cmdp->param.cmd->flags & BUILTIN_REGULAR) && + builtinloc > 0)) { + cmdp->rehash = 1; + } + } + } +} + +/* + * Fix command hash table when PATH changed. + * Called before PATH is changed. The argument is the new value of PATH; + * pathval() still returns the old value at this point. + * Called with interrupts off. + */ +static void changepath(const char *newval) { + const char *new; + int idx; + int bltin; + new = newval; + idx = 0; + bltin = -1; + for (;;) { + if (*new == '%' && prefix(new + 1, "builtin")) { + bltin = idx; + break; + } + new = strchr(new, ':'); + if (!new) break; + idx++; + new ++; + } + builtinloc = bltin; + clearcmdentry(); +} + +/* + * Clear out command entries. The argument specifies the first entry in + * PATH which has changed. + */ +static void clearcmdentry(void) { + struct tblentry **tblp; + struct tblentry **pp; + struct tblentry *cmdp; + INTOFF; + for (tblp = cmdtable; tblp < &cmdtable[CMDTABLESIZE]; tblp++) { + pp = tblp; + while ((cmdp = *pp) != NULL) { + if (cmdp->cmdtype == CMDNORMAL || + (cmdp->cmdtype == CMDBUILTIN && !(cmdp->param.cmd->flags & BUILTIN_REGULAR) && + builtinloc > 0)) { + *pp = cmdp->next; + ckfree(cmdp); + } else { + pp = &cmdp->next; + } + } + } + INTON; +} + +/* + * Locate a command in the command hash table. If "add" is nonzero, + * add the command to the table if it is not already present. The + * variable "lastcmdentry" is set to point to the address of the link + * pointing to the entry, so that delete_cmd_entry can delete the + * entry. + * + * Interrupts must be off if called with add != 0. + */ +static struct tblentry *cmdlookup(const char *name, int add) { + unsigned int hashval; + const char *p; + struct tblentry *cmdp; + struct tblentry **pp; + p = name; + hashval = (unsigned char)*p << 4; + while (*p) hashval += (unsigned char)*p++; + hashval &= 0x7FFF; + pp = &cmdtable[hashval % CMDTABLESIZE]; + for (cmdp = *pp; cmdp; cmdp = cmdp->next) { + if (equal(cmdp->cmdname, name)) break; + pp = &cmdp->next; + } + if (add && cmdp == NULL) { + cmdp = *pp = ckmalloc(sizeof(struct tblentry) + strlen(name) + 1); + cmdp->next = NULL; + cmdp->cmdtype = CMDUNKNOWN; + strcpy(cmdp->cmdname, name); + } + lastcmdentry = pp; + return cmdp; +} + +/* + * Delete the command entry returned on the last lookup. + */ +static void delete_cmd_entry(void) { + struct tblentry *cmdp; + INTOFF; + cmdp = *lastcmdentry; + *lastcmdentry = cmdp->next; + if (cmdp->cmdtype == CMDFUNCTION) freefunc(cmdp->param.func); + ckfree(cmdp); + INTON; +} + +/* + * Add a new command entry, replacing any existing command entry for + * the same name - except special builtins. + */ +static void addcmdentry(char *name, struct cmdentry *entry) { + struct tblentry *cmdp; + cmdp = cmdlookup(name, 1); + if (cmdp->cmdtype == CMDFUNCTION) { + freefunc(cmdp->param.func); + } + cmdp->cmdtype = entry->cmdtype; + cmdp->param = entry->u; + cmdp->rehash = 0; +} + +/* Define a shell function. */ +static void defun(union node *func) { + struct cmdentry entry; + INTOFF; + entry.cmdtype = CMDFUNCTION; + entry.u.func = copyfunc(func); + addcmdentry(func->ndefun.text, &entry); + INTON; +} + +/* Delete a function if it exists. */ +static void unsetfunc(const char *name) { + struct tblentry *cmdp; + if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->cmdtype == CMDFUNCTION) { + delete_cmd_entry(); + } +} + +/* Locate and print what a word is... */ +static int typecmd(int argc, char **argv) { + int i; + int err = 0; + for (i = 1; i < argc; i++) { + err |= describe_command(out1, argv[i], NULL, 1); + } + return err; +} + +static int describe_command(struct output *out, char *command, const char *path, int verbose) { + struct cmdentry entry; + struct tblentry *cmdp; + const struct alias *ap; + if (verbose) { + outstr(command, out); + } + /* First look at the keywords */ + if (findkwd(command)) { + outstr(verbose ? " is a shell keyword" : command, out); + goto out; + } + /* Then look at the aliases */ + if ((ap = lookupalias(command, 0)) != NULL) { + if (verbose) { + outfmt(out, " is an alias for %s", ap->val); + } else { + outstr("alias ", out); + printalias(ap); + return 0; + } + goto out; + } + /* Then if the standard search path is used, check if it is + * a tracked alias. + */ + if (path == NULL) { + path = pathval(); + cmdp = cmdlookup(command, 0); + } else { + cmdp = NULL; + } + if (cmdp != NULL) { + entry.cmdtype = cmdp->cmdtype; + entry.u = cmdp->param; + } else { + /* Finally use brute force */ + find_command(command, &entry, DO_ABS, path); + } + switch (entry.cmdtype) { + case CMDNORMAL: { + int j = entry.u.index; + char *p; + if (j == -1) { + p = command; + } else { + do { + padvance(&path, command); + } while (--j >= 0); + p = stackblock(); + } + if (verbose) { + outfmt(out, " is%s %s", cmdp ? " a tracked alias for" : nullstr, p); + } else { + outstr(p, out); + } + break; + } + case CMDFUNCTION: + if (verbose) { + outstr(" is a shell function", out); + } else { + outstr(command, out); + } + break; + case CMDBUILTIN: + if (verbose) { + outfmt(out, " is a %sshell builtin", + entry.u.cmd->flags & BUILTIN_SPECIAL ? "special " : nullstr); + } else { + outstr(command, out); + } + break; + default: + if (verbose) { + outstr(": not found\n", out); + } + return 127; + } +out: + outc('\n', out); + return 0; +} + +static int commandcmd(argc, argv) int argc; +char **argv; +{ + char *cmd; + int c; + enum { + VERIFY_BRIEF = 1, + VERIFY_VERBOSE = 2, + } verify = 0; + const char *path = NULL; + while ((c = nextopt("pvV")) != '\0') + if (c == 'V') + verify |= VERIFY_VERBOSE; + else if (c == 'v') + verify |= VERIFY_BRIEF; + else + path = defpath; + cmd = *argptr; + if (verify && cmd) { + return describe_command(out1, cmd, path, verify - VERIFY_BRIEF); + } + return 0; +} + +/* + * Prepare a pattern for a glob(3) call. + * + * Returns an stalloced string. + */ +static inline char *preglob(const char *pattern, int flag) { + flag |= RMESCAPE_GLOB; + return rmescapes((char *)pattern, flag); +} + +static unsigned esclen(const char *start, const char *p) { + unsigned esc = 0; + while (p > start && *--p == (char)CTLESC) { + esc++; + } + return esc; +} + +static inline const char *getpwhome(const char *name) { + struct passwd *pw = getpwnam(name); + return pw ? pw->pw_dir : 0; +} + +static void ifsbreakup(char *string, int maxargs, struct arglist *arglist); +static void recordregion(int start, int end, int nulonly); + +/* + * Perform variable substitution and command substitution on an + * argument, placing the resulting list of arguments in arglist. If + * EXP_FULL is true, perform splitting and file name expansion. When + * arglist is NULL, perform here document expansion. + */ +static void expandarg(union node *arg, struct arglist *arglist, int flag) { + struct strlist *sp; + char *p; + argbackq = arg->narg.backquote; + STARTSTACKSTR(expdest); + argstr(arg->narg.text, flag); + if (arglist == NULL) { + /* here document expanded */ + goto out; + } + p = grabstackstr(expdest); + exparg.lastp = &exparg.list; + /* + * TODO - EXP_REDIR + */ + if (flag & EXP_FULL) { + ifsbreakup(p, -1, &exparg); + *exparg.lastp = NULL; + exparg.lastp = &exparg.list; + expandmeta(exparg.list, flag); + } else { + sp = (struct strlist *)stalloc(sizeof(struct strlist)); + sp->text = p; + *exparg.lastp = sp; + exparg.lastp = &sp->next; + } + *exparg.lastp = NULL; + if (exparg.list) { + *arglist->lastp = exparg.list; + arglist->lastp = exparg.lastp; + } +out: + ifsfree(); +} + +/* + * Perform variable and command substitution. If EXP_FULL is set, output + * CTLESC characters to allow for further processing. Otherwise treat $@ + * like $* since no splitting will be performed. + */ +static char *argstr(char *p, int flag) { + static const int DOLATSTRLEN = 6; + static const char spclchars[] = {'=', ':', CTLQUOTEMARK, CTLENDVAR, CTLESC, + CTLVAR, CTLBACKQ, CTLARI, CTLENDARI, 0}; + const char *reject = spclchars; + int c; + int breakall = (flag & (EXP_WORD | EXP_QUOTED)) == EXP_WORD; + int inquotes; + unsigned length; + int startloc; + reject += !!(flag & EXP_VARTILDE2); + reject += flag & EXP_VARTILDE ? 0 : 2; + inquotes = 0; + length = 0; + if (flag & EXP_TILDE) { + flag &= ~EXP_TILDE; + tilde: + if (*p == '~') p = exptilde(p, flag); + } +start: + startloc = expdest - (char *)stackblock(); + for (;;) { + int end; + length += strcspn(p + length, reject); + end = 0; + c = (signed char)p[length]; + if (!(c & 0x80) || c == CTLENDARI || c == CTLENDVAR) { + /* + * c == '=' || c == ':' || c == '\0' || + * c == CTLENDARI || c == CTLENDVAR + */ + length++; + /* c == '\0' || c == CTLENDARI || c == CTLENDVAR */ + end = !!((c - 1) & 0x80); + } + if (length > 0 && !(flag & EXP_DISCARD)) { + int newloc; + char *q; + q = stnputs(p, length, expdest); + q[-1] &= end - 1; + expdest = q - (flag & EXP_WORD ? end : 0); + newloc = expdest - (char *)stackblock() - end; + if (breakall && !inquotes && newloc > startloc) { + recordregion(startloc, newloc, 0); + } + startloc = newloc; + } + p += length + 1; + length = 0; + if (end) break; + switch (c) { + case '=': + flag |= EXP_VARTILDE2; + reject++; + /* fall through */ + case ':': + /* + * sort of a hack - expand tildes in variable + * assignments (after the first '=' and after ':'s). + */ + if (*--p == '~') { + goto tilde; + } + continue; + case CTLQUOTEMARK: + /* "$@" syntax adherence hack */ + if (!inquotes && !memcmp(p, dolatstr + 1, DOLATSTRLEN - 1)) { + p = evalvar(p + 1, flag | EXP_QUOTED) + 1; + goto start; + } + inquotes ^= EXP_QUOTED; + addquote: + if (flag & QUOTES_ESC) { + p--; + length++; + startloc++; + } + break; + case CTLESC: + startloc++; + length++; + goto addquote; + case CTLVAR: + p = evalvar(p, flag | inquotes); + goto start; + case CTLBACKQ: + expbackq(argbackq->n, flag | inquotes); + goto start; + case CTLARI: + p = expari(p, flag | inquotes); + goto start; + } + } + return p - 1; +} + +static char *exptilde(char *startp, int flag) { + signed char c; + char *name; + const char *home; + char *p; + p = startp; + name = p + 1; + while ((c = *++p) != '\0') { + switch (c) { + case CTLESC: + return (startp); + case CTLQUOTEMARK: + return (startp); + case ':': + if (flag & EXP_VARTILDE) goto done; + break; + case '/': + case CTLENDVAR: + goto done; + } + } +done: + if (flag & EXP_DISCARD) goto out; + *p = '\0'; + if (*name == '\0') { + home = lookupvar(homestr); + } else { + home = getpwhome(name); + } + *p = c; + if (!home) goto lose; + strtodest(home, flag | EXP_QUOTED); +out: + return (p); +lose: + return (startp); +} + +static void removerecordregions(int endoff) { + if (ifslastp == NULL) return; + if (ifsfirst.endoff > endoff) { + while (ifsfirst.next != NULL) { + struct ifsregion *ifsp; + INTOFF; + ifsp = ifsfirst.next->next; + ckfree(ifsfirst.next); + ifsfirst.next = ifsp; + INTON; + } + if (ifsfirst.begoff > endoff) + ifslastp = NULL; + else { + ifslastp = &ifsfirst; + ifsfirst.endoff = endoff; + } + return; + } + ifslastp = &ifsfirst; + while (ifslastp->next && ifslastp->next->begoff < endoff) { + ifslastp = ifslastp->next; + } + while (ifslastp->next != NULL) { + struct ifsregion *ifsp; + INTOFF; + ifsp = ifslastp->next->next; + ckfree(ifslastp->next); + ifslastp->next = ifsp; + INTON; + } + if (ifslastp->endoff > endoff) ifslastp->endoff = endoff; +} + +/* + * Expand arithmetic expression. Backup to start of expression, + * evaluate, place result in (backed up) result, adjust string position. + */ +static char *expari(char *start, int flag) { + struct stackmark sm; + int begoff; + int endoff; + int len; + int64_t result; + char *p; + p = stackblock(); + begoff = expdest - p; + p = argstr(start, flag & EXP_DISCARD); + if (flag & EXP_DISCARD) goto out; + start = stackblock(); + endoff = expdest - start; + start += begoff; + STADJUST(start - expdest, expdest); + removerecordregions(begoff); + if (likely(flag & QUOTES_ESC)) rmescapes(start, 0); + pushstackmark(&sm, endoff); + result = arith(start); + popstackmark(&sm); + len = cvtnum(result, flag); + if (likely(!(flag & EXP_QUOTED))) recordregion(begoff, begoff + len, 0); +out: + return p; +} + +/* + * Expand stuff in backwards quotes. + */ +static void expbackq(union node *cmd, int flag) { + struct backcmd in; + int i; + char buf[128]; + char *p; + char *dest; + int startloc; + struct stackmark smark; + if (flag & EXP_DISCARD) goto out; + INTOFF; + startloc = expdest - (char *)stackblock(); + pushstackmark(&smark, startloc); + evalbackcmd(cmd, (struct backcmd *)&in); + popstackmark(&smark); + p = in.buf; + i = in.nleft; + if (i == 0) goto read; + for (;;) { + memtodest(p, i, flag); + read: + if (in.fd < 0) break; + do { + i = read(in.fd, buf, sizeof buf); + } while (i < 0 && errno == EINTR); + TRACE(("expbackq: read returns %d\n", i)); + if (i <= 0) break; + p = buf; + } + if (in.buf) ckfree(in.buf); + if (in.fd >= 0) { + close(in.fd); + back_exitstatus = waitforjob(in.jp); + } + INTON; + /* Eat all trailing newlines */ + dest = expdest; + for (; dest > (char *)stackblock() && dest[-1] == '\n';) { + STUNPUTC(dest); + } + expdest = dest; + if (!(flag & EXP_QUOTED)) { + recordregion(startloc, dest - (char *)stackblock(), 0); + } + TRACE(("evalbackq: size=%d: \"%.*s\"\n", (dest - (char *)stackblock()) - startloc, + (dest - (char *)stackblock()) - startloc, stackblock() + startloc)); +out: + argbackq = argbackq->next; +} + +static char *scanleft(char *startp, char *rmesc, char *rmescend, char *str, int quotes, int zero) { + char *loc; + char *loc2; + char c; + loc = startp; + loc2 = rmesc; + do { + int match; + const char *s = loc2; + c = *loc2; + if (zero) { + *loc2 = '\0'; + s = rmesc; + } + match = pmatch(str, s); + *loc2 = c; + if (match) return loc; + if (quotes && *loc == (char)CTLESC) loc++; + loc++; + loc2++; + } while (c); + return 0; +} + +static char *scanright(char *startp, char *rmesc, char *rmescend, char *str, int quotes, int zero) { + int esc = 0; + char *loc; + char *loc2; + for (loc = str - 1, loc2 = rmescend; loc >= startp; loc2--) { + int match; + char c = *loc2; + const char *s = loc2; + if (zero) { + *loc2 = '\0'; + s = rmesc; + } + match = pmatch(str, s); + *loc2 = c; + if (match) return loc; + loc--; + if (quotes) { + if (--esc < 0) { + esc = esclen(startp, loc); + } + if (esc % 2) { + esc--; + loc--; + } + } + } + return 0; +} + +static char *subevalvar(char *start, char *str, int strloc, int startloc, int varflags, int flag) { + int subtype = varflags & VSTYPE; + int quotes = flag & QUOTES_ESC; + char *startp; + char *loc; + long amount; + char *rmesc, *rmescend; + int zero; + char *(*scan)(char *, char *, char *, char *, int, int); + char *p; + p = argstr(start, (flag & EXP_DISCARD) | EXP_TILDE | (str ? 0 : EXP_CASE)); + if (flag & EXP_DISCARD) return p; + startp = (char *)stackblock() + startloc; + switch (subtype) { + case VSASSIGN: + setvar(str, startp, 0); + loc = startp; + goto out; + case VSQUESTION: + varunset(start, str, startp, varflags); + /* NOTREACHED */ + } + subtype -= VSTRIMRIGHT; + rmesc = startp; + rmescend = (char *)stackblock() + strloc; + if (quotes) { + rmesc = rmescapes(startp, RMESCAPE_ALLOC | RMESCAPE_GROW); + if (rmesc != startp) { + rmescend = expdest; + startp = (char *)stackblock() + startloc; + } + } + rmescend--; + str = (char *)stackblock() + strloc; + preglob(str, 0); + /* zero = subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX */ + zero = subtype >> 1; + /* VSTRIMLEFT/VSTRIMRIGHTMAX -> scanleft */ + scan = (subtype & 1) ^ zero ? scanleft : scanright; + loc = scan(startp, rmesc, rmescend, str, quotes, zero); + if (loc) { + if (zero) { + memmove(startp, loc, str - loc); + loc = startp + (str - loc) - 1; + } + *loc = '\0'; + } else + loc = str - 1; +out: + amount = loc - expdest; + STADJUST(amount, expdest); + /* Remove any recorded regions beyond start of variable */ + removerecordregions(startloc); + return p; +} + +/* + * Expand a variable, and return a pointer to the next character in the + * input string. + */ +static char *evalvar(char *p, int flag) { + int subtype; + int varflags; + char *var_; + int patloc; + int startloc; + long varlen; + int quoted; + varflags = *p++; + subtype = varflags & VSTYPE; + quoted = flag & EXP_QUOTED; + var_ = p; + startloc = expdest - (char *)stackblock(); + p = strchr(p, '=') + 1; +again: + varlen = varvalue(var_, varflags, flag, quoted); + if (varflags & VSNUL) varlen--; + switch (subtype) { + case VSPLUS: + varlen = -1 - varlen; + /* fall through */ + case 0: + case VSMINUS: + p = argstr(p, flag | EXP_TILDE | EXP_WORD); + if (varlen < 0) return p; + goto record; + case VSASSIGN: + case VSQUESTION: + if (varlen >= 0) goto record; + p = subevalvar(p, var_, 0, startloc, varflags, flag & ~QUOTES_ESC); + if (flag & EXP_DISCARD) return p; + varflags &= ~VSNUL; + goto again; + } + if (varlen < 0 && uflag) varunset(p, var_, 0, 0); + if (subtype == VSLENGTH) { + if (flag & EXP_DISCARD) return p; + cvtnum(varlen > 0 ? varlen : 0, flag); + goto record; + } + if (subtype == VSNORMAL) goto record; + flag |= varlen < 0 ? EXP_DISCARD : 0; + if (!(flag & EXP_DISCARD)) { + /* + * Terminate the string and start recording the pattern + * right after it + */ + STPUTC('\0', expdest); + } + patloc = expdest - (char *)stackblock(); + p = subevalvar(p, NULL, patloc, startloc, varflags, flag); +record: + if (flag & EXP_DISCARD) return p; + if (quoted) { + quoted = *var_ == '@' && shellparam.nparam; + if (!quoted) return p; + } + recordregion(startloc, expdest - (char *)stackblock(), quoted); + return p; +} + +/* + * Put a string on the stack. + */ +static unsigned memtodest(const char *p, unsigned len, int flags) { + const char *syntax = flags & EXP_QUOTED ? DQSYNTAX : BASESYNTAX; + char *q; + char *s; + if (unlikely(!len)) return 0; + q = makestrspace(len * 2, expdest); + s = q; + do { + int c = (signed char)*p++; + if (c) { + if ((flags & QUOTES_ESC) && + ((syntax[c] == CCTL) || (flags & EXP_QUOTED && syntax[c] == CBACK))) { + USTPUTC(CTLESC, q); + } + } else if (!(flags & EXP_KEEPNUL)) + continue; + USTPUTC(c, q); + } while (--len); + expdest = q; + return q - s; +} + +static unsigned strtodest(const char *p, int flags) { + unsigned len = strlen(p); + memtodest(p, len, flags); + return len; +} + +/* + * Add the value of a specialized variable to the stack string. + */ +static long varvalue(char *name, int varflags, int flags, int quoted) { + int num; + char *p; + int i; + int sep; + char sepc; + char **ap; + int subtype = varflags & VSTYPE; + int discard = (subtype == VSPLUS || subtype == VSLENGTH) | (flags & EXP_DISCARD); + long len = 0; + char c; + if (!subtype) { + if (discard) return -1; + sh_error("Bad substitution"); + } + flags |= EXP_KEEPNUL; + flags &= discard ? ~QUOTES_ESC : ~0; + sep = (flags & EXP_FULL) << CHAR_BIT; + switch (*name) { + case '$': + num = rootpid; + goto numvar; + case '?': + num = exitstatus; + goto numvar; + case '#': + num = shellparam.nparam; + goto numvar; + case '!': + num = backgndpid; + if (num == 0) return -1; + numvar: + len = cvtnum(num, flags); + break; + case '-': + p = makestrspace(NOPTS, expdest); + for (i = NOPTS - 1; i >= 0; i--) { + if (optlist[i] && optletters[i]) { + USTPUTC(optletters[i], p); + len++; + } + } + expdest = p; + break; + case '@': + if (quoted && sep) goto param; + /* fall through */ + case '*': + /* We will set c to 0 or ~0 depending on whether + * we're doing field splitting. We won't do field + * splitting if either we're quoted or sep is zero. + * + * Instead of testing (quoted || !sep) the following + * trick optimises away any branches by using the + * fact that EXP_QUOTED (which is the only bit that + * can be set in quoted) is the same as EXP_FULL << + * CHAR_BIT (which is the only bit that can be set + * in sep). + */ + /* #if EXP_QUOTED >> CHAR_BIT != EXP_FULL */ + /* #error The following two lines expect EXP_QUOTED == EXP_FULL << + * CHAR_BIT */ + /* #endif */ + c = !((quoted | ~sep) & EXP_QUOTED) - 1; + sep &= ~quoted; + sep |= ifsset() ? (unsigned char)(c & ifsval()[0]) : ' '; + param: + sepc = sep; + if (!(ap = shellparam.p)) return -1; + while ((p = *ap++)) { + len += strtodest(p, flags); + if (*ap && sep) { + len++; + memtodest(&sepc, 1, flags); + } + } + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + num = atoi(name); + if (num < 0 || num > shellparam.nparam) return -1; + p = num ? shellparam.p[num - 1] : arg0; + goto value; + default: + p = lookupvar(name); + value: + if (!p) return -1; + len = strtodest(p, flags); + break; + } + if (discard) STADJUST(-len, expdest); + return len; +} + +/* + * Record the fact that we have to scan this region of the + * string for IFS characters. + */ +static void recordregion(int start, int end, int nulonly) { + struct ifsregion *ifsp; + if (ifslastp == NULL) { + ifsp = &ifsfirst; + } else { + INTOFF; + ifsp = (struct ifsregion *)ckmalloc(sizeof(struct ifsregion)); + ifsp->next = NULL; + ifslastp->next = ifsp; + INTON; + } + ifslastp = ifsp; + ifslastp->begoff = start; + ifslastp->endoff = end; + ifslastp->nulonly = nulonly; +} + +/* + * Break the argument string into pieces based upon IFS and add the + * strings to the argument list. The regions of the string to be + * searched for IFS characters have been stored by recordregion. + * If maxargs is non-negative, at most maxargs arguments will be created, by + * joining together the last arguments. + */ +static void ifsbreakup(char *string, int maxargs, struct arglist *arglist) { + struct ifsregion *ifsp; + struct strlist *sp; + char *start; + char *p; + char *q; + char *r = NULL; + const char *ifs, *realifs; + int ifsspc; + int nulonly; + start = string; + if (ifslastp != NULL) { + ifsspc = 0; + nulonly = 0; + realifs = ifsset() ? ifsval() : defifs; + ifsp = &ifsfirst; + do { + int afternul; + p = string + ifsp->begoff; + afternul = nulonly; + nulonly = ifsp->nulonly; + ifs = nulonly ? nullstr : realifs; + ifsspc = 0; + while (p < string + ifsp->endoff) { + int c; + bool isifs; + bool isdefifs; + q = p; + c = *p++; + if (c == (char)CTLESC) c = *p++; + isifs = !!strchr(ifs, c); + isdefifs = false; + if (isifs) isdefifs = !!strchr(defifs, c); + /* If only reading one more argument: + * If we have exactly one field, + * read that field without its terminator. + * If we have more than one field, + * read all fields including their terminators, + * except for trailing IFS whitespace. + * + * This means that if we have only IFS + * characters left, and at most one + * of them is non-whitespace, we stop + * reading here. + * Otherwise, we read all the remaining + * characters except for trailing + * IFS whitespace. + * + * In any case, r indicates the start + * of the characters to remove, or NULL + * if no characters should be removed. + */ + if (!maxargs) { + if (isdefifs) { + if (!r) r = q; + continue; + } + if (!(isifs && ifsspc)) r = NULL; + ifsspc = 0; + continue; + } + if (ifsspc) { + if (isifs) q = p; + start = q; + if (isdefifs) continue; + isifs = false; + } + if (isifs) { + if (!(afternul || nulonly)) ifsspc = isdefifs; + /* Ignore IFS whitespace at start */ + if (q == start && ifsspc) { + start = p; + ifsspc = 0; + continue; + } + if (maxargs > 0 && !--maxargs) { + r = q; + continue; + } + *q = '\0'; + sp = (struct strlist *)stalloc(sizeof *sp); + sp->text = start; + *arglist->lastp = sp; + arglist->lastp = &sp->next; + start = p; + continue; + } + ifsspc = 0; + } + } while ((ifsp = ifsp->next) != NULL); + if (nulonly) goto add; + } + if (r) *r = '\0'; + if (!*start) return; +add: + sp = (struct strlist *)stalloc(sizeof *sp); + sp->text = start; + *arglist->lastp = sp; + arglist->lastp = &sp->next; +} + +/* + * Expand shell metacharacters. At this point, the only control characters + * should be escapes. The results are stored in the list exparg. + */ +static void expandmeta(struct strlist *str, int flag) { + static const char metachars[] = {'*', '?', '[', 0}; + /* TODO - EXP_REDIR */ + while (str) { + struct strlist **savelastp; + struct strlist *sp; + char *p; + unsigned len; + if (fflag) goto nometa; + if (!strpbrk(str->text, metachars)) goto nometa; + savelastp = exparg.lastp; + INTOFF; + p = preglob(str->text, RMESCAPE_ALLOC | RMESCAPE_HEAP); + len = strlen(p); + expdir_max = len + PATH_MAX; + expdir = ckmalloc(expdir_max); + expmeta(p, len, 0); + ckfree(expdir); + if (p != str->text) ckfree(p); + INTON; + if (exparg.lastp == savelastp) { + /* + * no matches + */ + nometa: + *exparg.lastp = str; + rmescapes(str->text, 0); + exparg.lastp = &str->next; + } else { + *exparg.lastp = NULL; + *savelastp = sp = expsort(*savelastp); + while (sp->next != NULL) sp = sp->next; + exparg.lastp = &sp->next; + } + str = str->next; + } +} + +/* + * Do metacharacter (i.e. *, ?, [...]) expansion. + */ +static void expmeta(char *name, unsigned name_len, unsigned expdir_len) { + char *enddir = expdir + expdir_len; + char *p; + const char *cp; + char *start; + char *endname; + int metaflag; + struct stat statb; + DIR *dirp; + struct dirent *dp; + int atend; + int matchdot; + int esc; + metaflag = 0; + start = name; + for (p = name; esc = 0, *p; p += esc + 1) { + if (*p == '*' || *p == '?') + metaflag = 1; + else if (*p == '[') { + char *q = p + 1; + if (*q == '!') q++; + for (;;) { + if (*q == '\\') q++; + if (*q == '/' || *q == '\0') break; + if (*++q == ']') { + metaflag = 1; + break; + } + } + } else { + if (*p == '\\' && p[1]) esc++; + if (p[esc] == '/') { + if (metaflag) break; + start = p + esc + 1; + } + } + } + if (metaflag == 0) { /* we've reached the end of the file name */ + if (!expdir_len) return; + p = name; + do { + if (*p == '\\' && p[1]) p++; + *enddir++ = *p; + } while (*p++); + if (lstat(expdir, &statb) >= 0) addfname(expdir); + return; + } + endname = p; + if (name < start) { + p = name; + do { + if (*p == '\\' && p[1]) p++; + *enddir++ = *p++; + } while (p < start); + } + *enddir = 0; + cp = expdir; + expdir_len = enddir - cp; + if (!expdir_len) cp = "."; + if ((dirp = opendir(cp)) == NULL) return; + if (*endname == 0) { + atend = 1; + } else { + atend = 0; + *endname = '\0'; + endname += esc + 1; + } + name_len -= endname - name; + matchdot = 0; + p = start; + if (*p == '\\') p++; + if (*p == '.') matchdot++; + while (!int_pending() && (dp = readdir(dirp)) != NULL) { + if (dp->d_name[0] == '.' && !matchdot) continue; + if (pmatch(start, dp->d_name)) { + if (atend) { + scopy(dp->d_name, enddir); + addfname(expdir); + } else { + unsigned offset; + unsigned len; + p = stpcpy(enddir, dp->d_name); + *p = '/'; + offset = p - expdir + 1; + len = offset + name_len + NAME_MAX; + if (len > expdir_max) { + len += PATH_MAX; + expdir = ckrealloc(expdir, len); + expdir_max = len; + } + expmeta(endname, name_len, offset); + enddir = expdir + expdir_len; + } + } + } + closedir(dirp); + if (!atend) endname[-esc - 1] = esc ? '\\' : '/'; +} + +/* + * Add a file name to the list. + */ +static void addfname(char *name) { + struct strlist *sp; + sp = (struct strlist *)stalloc(sizeof *sp); + sp->text = sstrdup(name); + *exparg.lastp = sp; + exparg.lastp = &sp->next; +} + +/* + * Sort the results of file name expansion. It calculates the number of + * strings to sort and then calls msort (short for merge sort) to do the + * work. + */ +static struct strlist *expsort(struct strlist *str) { + int len; + struct strlist *sp; + len = 0; + for (sp = str; sp; sp = sp->next) len++; + return msort(str, len); +} + +static struct strlist *msort(struct strlist *list, int len) { + struct strlist *p, *q = NULL; + struct strlist **lpp; + int half; + int n; + if (len <= 1) return list; + half = len >> 1; + p = list; + for (n = half; --n >= 0;) { + q = p; + p = p->next; + } + q->next = NULL; /* terminate first half of list */ + q = msort(list, half); /* sort first half of list */ + p = msort(p, len - half); /* sort second half */ + lpp = &list; + for (;;) { + if (strcmp(p->text, q->text) < 0) { + *lpp = p; + lpp = &p->next; + if ((p = *lpp) == NULL) { + *lpp = q; + break; + } + } else { + *lpp = q; + lpp = &q->next; + if ((q = *lpp) == NULL) { + *lpp = p; + break; + } + } + } + return list; +} + +/* + * Returns true if the pattern matches the string. + */ +static inline int patmatch(char *pattern, const char *string) { + return pmatch(preglob(pattern, 0), string); +} + +static int ccmatch(const char *p, int chr, const char **r) { + static const struct class { + char name[10]; + int (*fn)(int); + } classes[] = {{.name = ":alnum:]", .fn = isalnum}, {.name = ":cntrl:]", .fn = iscntrl}, + {.name = ":lower:]", .fn = islower}, {.name = ":space:]", .fn = isspace}, + {.name = ":alpha:]", .fn = isalpha}, {.name = ":digit:]", .fn = isdigit}, + {.name = ":print:]", .fn = isprint}, {.name = ":upper:]", .fn = isupper}, + {.name = ":blank:]", .fn = isblank}, {.name = ":graph:]", .fn = isgraph}, + {.name = ":punct:]", .fn = ispunct}, {.name = ":xdigit:]", .fn = isxdigit}}; + const struct class *class, *end; + end = classes + sizeof(classes) / sizeof(classes[0]); + for (class = classes; class < end; class ++) { + const char *q; + q = prefix(p, class->name); + if (!q) continue; + *r = q; + return class->fn(chr); + } + *r = 0; + return 0; +} + +static int pmatch(const char *pattern, const char *string) { + const char *p, *q; + char c; + p = pattern; + q = string; + for (;;) { + switch (c = *p++) { + case '\0': + goto breakloop; + case '\\': + if (*p) { + c = *p++; + } + goto dft; + case '?': + if (*q++ == '\0') return 0; + break; + case '*': + c = *p; + while (c == '*') c = *++p; + if (c != '\\' && c != '?' && c != '*' && c != '[') { + while (*q != c) { + if (*q == '\0') return 0; + q++; + } + } + do { + if (pmatch(p, q)) return 1; + } while (*q++ != '\0'); + return 0; + case '[': { + const char *startp; + int invert, found; + char chr; + startp = p; + invert = 0; + if (*p == '!') { + invert++; + p++; + } + found = 0; + chr = *q; + if (chr == '\0') return 0; + c = *p++; + do { + if (!c) { + p = startp; + c = '['; + goto dft; + } + if (c == '[') { + const char *r; + found |= !!ccmatch(p, chr, &r); + if (r) { + p = r; + continue; + } + } else if (c == '\\') + c = *p++; + if (*p == '-' && p[1] != ']') { + p++; + if (*p == '\\') p++; + if (chr >= c && chr <= *p) found = 1; + p++; + } else { + if (chr == c) found = 1; + } + } while ((c = *p++) != ']'); + if (found == invert) return 0; + q++; + break; + } + dft: + default: + if (*q++ != c) return 0; + break; + } + } +breakloop: + if (*q != '\0') return 0; + return 1; +} + +/* + * Remove any CTLESC characters from a string. + */ +static char *rmescapes(char *str, int flag) { + char *p, *q, *r; + int notescaped; + int globbing; + p = strpbrk(str, qchars); + if (!p) { + return str; + } + q = p; + r = str; + if (flag & RMESCAPE_ALLOC) { + unsigned len = p - str; + unsigned fulllen = len + strlen(p) + 1; + if (flag & RMESCAPE_GROW) { + int strloc = str - (char *)stackblock(); + r = makestrspace(fulllen, expdest); + str = (char *)stackblock() + strloc; + p = str + len; + } else if (flag & RMESCAPE_HEAP) { + r = ckmalloc(fulllen); + } else { + r = stalloc(fulllen); + } + q = r; + if (len > 0) { + q = mempcpy(q, str, len); + } + } + globbing = flag & RMESCAPE_GLOB; + notescaped = globbing; + while (*p) { + if (*p == (char)CTLQUOTEMARK) { + p++; + notescaped = globbing; + continue; + } + if (*p == '\\') { + /* naked back slash */ + notescaped = 0; + goto copy; + } + if (*p == (char)CTLESC) { + p++; + if (notescaped) *q++ = '\\'; + } + notescaped = globbing; + copy: + *q++ = *p++; + } + *q = '\0'; + if (flag & RMESCAPE_GROW) { + expdest = r; + STADJUST(q - r + 1, expdest); + } + return r; +} + +/* + * Our own itoa(). + */ +static unsigned cvtnum(int64_t num, int flags) { + int len = max_int_length(sizeof(num)); + char buf[len]; + len = fmtstr(buf, len, "%ld", num); + return memtodest(buf, len, flags); +} + +/* + * Read a character from the script, returning PEOF on end of file. + * Nul characters in the input are silently discarded. + */ +static int pgetc(void) { + int c; + if (parsefile->unget) return parsefile->lastc[--parsefile->unget]; + if (--parsefile->nleft >= 0) + c = (signed char)*parsefile->nextc++; + else + c = preadbuffer(); + parsefile->lastc[1] = parsefile->lastc[0]; + parsefile->lastc[0] = c; + return c; +} + +/* + * Same as pgetc(), but ignores PEOA. + */ +static int pgetc2() { + int c; + do { + c = pgetc(); + } while (c == PEOA); + return c; +} + +static ssize_t preadfd(void) { + ssize_t nr; + char *buf = parsefile->buf; + parsefile->nextc = buf; +retry: + nr = read(parsefile->fd, buf, IBUFSIZ - 1); + if (nr < 0) { + if (errno == EINTR) goto retry; + if (parsefile->fd == 0 && errno == EAGAIN) { + int flags = fcntl(0, F_GETFL, 0); + if (flags >= 0 && flags & O_NONBLOCK) { + flags &= ~O_NONBLOCK; + if (fcntl(0, F_SETFL, flags) >= 0) { + outstr("sh: turning off NDELAY mode\n", out2); + goto retry; + } + } + } + } + return nr; +} + +/* + * Refill the input buffer and return the next input character: + * + * 1) If a string was pushed back on the input, pop it; + * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading + * from a string so we can't refill the buffer, return EOF. + * 3) If the is more stuff in this buffer, use it else call read to fill it. + * 4) Process input up to the next newline, deleting nul characters. + */ +static int preadbuffer(void) { + char *q; + int more; + char savec; + if (unlikely(parsefile->strpush)) { + if (parsefile->nleft == -1 && parsefile->strpush->ap && parsefile->nextc[-1] != ' ' && + parsefile->nextc[-1] != '\t') { + return PEOA; + } + popstring(); + return pgetc(); + } + if (unlikely(parsefile->nleft == EOF_NLEFT || parsefile->buf == NULL)) return PEOF; + flushall(); + more = parsefile->lleft; + if (more <= 0) { + again: + if ((more = preadfd()) <= 0) { + parsefile->lleft = parsefile->nleft = EOF_NLEFT; + return PEOF; + } + } + q = parsefile->nextc; + /* delete nul characters */ + for (;;) { + int c; + more--; + c = *q; + if (!c) + memmove(q, q + 1, more); + else { + q++; + if (c == '\n') { + parsefile->nleft = q - parsefile->nextc - 1; + break; + } + } + if (more <= 0) { + parsefile->nleft = q - parsefile->nextc - 1; + if (parsefile->nleft < 0) goto again; + break; + } + } + parsefile->lleft = more; + savec = *q; + *q = '\0'; + if (vflag) { + outstr(parsefile->nextc, out2); + } + *q = savec; + return (signed char)*parsefile->nextc++; +} + +/* + * Undo a call to pgetc. Only two characters may be pushed back. + * PEOF may be pushed back. + */ +static void pungetc(void) { + parsefile->unget++; +} + +/* + * Push a string back onto the input at this current parsefile level. + * We handle aliases this way. + */ +static void pushstring(char *s, void *ap) { + struct strpush *sp; + unsigned len; + len = strlen(s); + INTOFF; + /*dprintf("*** calling pushstring: %s, %d\n", s, len);*/ + if (parsefile->strpush) { + sp = ckmalloc(sizeof(struct strpush)); + sp->prev = parsefile->strpush; + parsefile->strpush = sp; + } else + sp = parsefile->strpush = &(parsefile->basestrpush); + sp->prevstring = parsefile->nextc; + sp->prevnleft = parsefile->nleft; + sp->unget = parsefile->unget; + memcpy(sp->lastc, parsefile->lastc, sizeof(sp->lastc)); + sp->ap = (struct alias *)ap; + if (ap) { + ((struct alias *)ap)->flag |= ALIASINUSE; + sp->string = s; + } + parsefile->nextc = s; + parsefile->nleft = len; + parsefile->unget = 0; + INTON; +} + +static void popstring(void) { + struct strpush *sp = parsefile->strpush; + INTOFF; + if (sp->ap) { + if (parsefile->nextc[-1] == ' ' || parsefile->nextc[-1] == '\t') { + checkkwd |= CHKALIAS; + } + if (sp->string != sp->ap->val) { + ckfree(sp->string); + } + sp->ap->flag &= ~ALIASINUSE; + if (sp->ap->flag & ALIASDEAD) { + unalias(sp->ap->name); + } + } + parsefile->nextc = sp->prevstring; + parsefile->nleft = sp->prevnleft; + parsefile->unget = sp->unget; + memcpy(parsefile->lastc, sp->lastc, sizeof(sp->lastc)); + /*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/ + parsefile->strpush = sp->prev; + if (sp != &(parsefile->basestrpush)) ckfree(sp); + INTON; +} + +/* + * Set the input to take input from a file. If push is set, push the + * old input onto the stack first. + */ +static int setinputfile(const char *fname, int flags) { + int fd; + INTOFF; + if ((fd = open(fname, O_RDONLY, 0)) < 0) { + if (flags & INPUT_NOFILE_OK) goto out; + exitstatus = 127; + exerror(EXERROR, "Can't open %s", fname); + } + if (fd < 10) fd = savefd(fd, fd); + setinputfd(fd, flags & INPUT_PUSH_FILE); +out: + INTON; + return fd; +} + +/* + * Like setinputfile, but takes an open file descriptor. Call this with + * interrupts off. + */ +static void setinputfd(int fd, int push) { + if (push) { + pushfile(); + parsefile->buf = 0; + } + parsefile->fd = fd; + if (parsefile->buf == NULL) parsefile->buf = ckmalloc(IBUFSIZ); + parsefile->lleft = parsefile->nleft = 0; + plinno = 1; +} + +/* + * Like setinputfile, but takes input from a string. + */ +static void setinputstring(char *string) { + INTOFF; + pushfile(); + parsefile->nextc = string; + parsefile->nleft = strlen(string); + parsefile->buf = NULL; + plinno = 1; + INTON; +} + +/* + * To handle the "." command, a stack of input files is used. Pushfile + * adds a new entry to the stack and popfile restores the previous level. + */ +static void pushfile(void) { + struct parsefile *pf; + pf = (struct parsefile *)ckmalloc(sizeof(struct parsefile)); + pf->prev = parsefile; + pf->fd = -1; + pf->strpush = NULL; + pf->basestrpush.prev = NULL; + pf->unget = 0; + parsefile = pf; +} + +static void popfile(void) { + struct parsefile *pf = parsefile; + INTOFF; + if (pf->fd >= 0) close(pf->fd); + if (pf->buf) ckfree(pf->buf); + while (pf->strpush) popstring(); + parsefile = pf->prev; + ckfree(pf); + INTON; +} + +static void unwindfiles(struct parsefile *stop) { + while (parsefile != stop) popfile(); +} + +/* + * Return to top level. + */ +static void popallfiles(void) { + unwindfiles(&basepf); +} + +/* + * Close the file(s) that the shell is reading commands from. Called + * after a fork is done. + */ +static void closescript(void) { + popallfiles(); + if (parsefile->fd > 0) { + close(parsefile->fd); + parsefile->fd = 0; + } +} + +static char *commandtext(union node *); +static int dowait(int, struct job *); +static int getstatus(struct job *); +static int jobno(const struct job *); +static int restartjob(struct job *, int); +static int sprint_status(char *, int, int); +static int waitproc(int, int *); +static struct job *getjob(const char *, int); +static struct job *growjobtab(void); +static void cmdlist(union node *, int); +static void cmdputs(const char *); +static void cmdtxt(union node *); +static void forkchild(struct job *, union node *, int); +static void forkparent(struct job *, union node *, int, int); +static void freejob(struct job *); +static void set_curjob(struct job *, unsigned); +static void showpipe(struct job *, struct output *); +static void xtcsetpgrp(int, int); + +static void set_curjob(struct job *jp, unsigned mode) { + struct job *jp1; + struct job **jpp, **curp; + /* first remove from list */ + jpp = curp = &curjob; + do { + jp1 = *jpp; + if (jp1 == jp) break; + jpp = &jp1->prev_job; + } while (1); + *jpp = jp1->prev_job; + /* Then re-insert in correct position */ + jpp = curp; + switch (mode) { + default: + case CUR_DELETE: + /* job being deleted */ + break; + case CUR_RUNNING: + /* newly created job or backgrounded job, + put after all stopped jobs. */ + do { + jp1 = *jpp; + if (!JOBS || !jp1 || jp1->state != JOBSTOPPED) break; + jpp = &jp1->prev_job; + } while (1); + /* FALLTHROUGH */ + case CUR_STOPPED: + /* newly stopped job - becomes curjob */ + jp->prev_job = *jpp; + *jpp = jp; + break; + } +} + +/* + * Turn job control on and off. + * + * Note: This code assumes that the third arg to ioctl is a character + * pointer, which is true on Berkeley systems but not System V. Since + * System V doesn't have job control yet, this isn't a problem now. + * + * Called with interrupts off. + */ +static void setjobctl(int on) { + int fd; + int pgrp; + if (IsWindows()) return; /* TODO(jart) */ + if (on == jobctl || rootshell == 0) return; + if (on) { + int ofd; + ofd = fd = open(_PATH_TTY, O_RDWR, 0); + if (fd < 0) { + fd += 3; + while (!isatty(fd)) + if (--fd < 0) goto out; + } + fd = savefd(fd, ofd); + do { /* while we are in the background */ + if ((pgrp = tcgetpgrp(fd)) < 0) { + out: + sh_warnx("can't access tty; job control turned off"); + mflag = on = 0; + goto close; + } + if (pgrp == getpgrp()) break; + killpg(0, SIGTTIN); + } while (1); + initialpgrp = pgrp; + setsignal(SIGTSTP); + setsignal(SIGTTOU); + setsignal(SIGTTIN); + pgrp = rootpid; + setpgid(0, pgrp); + xtcsetpgrp(fd, pgrp); + } else { + /* turning job control off */ + fd = ttyfd; + pgrp = initialpgrp; + xtcsetpgrp(fd, pgrp); + setpgid(0, pgrp); + setsignal(SIGTSTP); + setsignal(SIGTTOU); + setsignal(SIGTTIN); + close: + close(fd); + fd = -1; + } + ttyfd = fd; + jobctl = on; +} + +static int decode_signum(const char *string) { + int signo = -1; + if (is_number(string)) { + signo = atoi(string); + if (signo >= NSIG) signo = -1; + } + return signo; +} + +static int killcmd(argc, argv) int argc; +char **argv; +{ + int signo = -1; + int list = 0; + int i; + int pid; + struct job *jp; + if (argc <= 1) { + usage: + sh_error("Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n" + "kill -l [exitstatus]"); + } + if (**++argv == '-') { + signo = decode_signal(*argv + 1, 1); + if (signo < 0) { + int c; + while ((c = nextopt("ls:")) != '\0') switch (c) { + default: + case 'l': + list = 1; + break; + case 's': + signo = decode_signal(optionarg, 1); + if (signo < 0) { + sh_error("invalid signal number or name: %s", optionarg); + } + break; + } + argv = argptr; + } else + argv++; + } + if (!list && signo < 0) signo = SIGTERM; + if ((signo < 0 || !*argv) ^ list) { + goto usage; + } + if (list) { + struct output *out; + out = out1; + if (!*argv) { + outstr("0\n", out); + for (i = 1; i < NSIG; i++) { + outfmt(out, snlfmt, strsignal(i)); + } + return 0; + } + signo = number(*argv); + if (signo > 128) signo -= 128; + if (0 < signo && signo < NSIG) + outfmt(out, snlfmt, strsignal(signo)); + else + sh_error("invalid signal number or exit status: %s", *argv); + return 0; + } + i = 0; + do { + if (**argv == '%') { + jp = getjob(*argv, 0); + pid = -jp->ps[0].pid; + } else + pid = **argv == '-' ? -number(*argv + 1) : number(*argv); + if (kill(pid, signo) != 0) { + sh_warnx("%s\n", strerror(errno)); + i = 1; + } + } while (*++argv); + return i; +} + +static int jobno(const struct job *jp) { + return jp - jobtab + 1; +} + +static int fgcmd(int argc, char **argv) { + struct job *jp; + struct output *out; + int mode; + int retval; + mode = (**argv == 'f') ? FORK_FG : FORK_BG; + nextopt(nullstr); + argv = argptr; + out = out1; + do { + jp = getjob(*argv, 1); + if (mode == FORK_BG) { + set_curjob(jp, CUR_RUNNING); + outfmt(out, "[%d] ", jobno(jp)); + } + outstr(jp->ps->cmd, out); + showpipe(jp, out); + retval = restartjob(jp, mode); + } while (*argv && *++argv); + return retval; +} + +static int bgcmd(int argc, char **argv) __attribute__((__alias__("fgcmd"))); + +static int restartjob(struct job *jp, int mode) { + struct procstat *ps; + int i; + int status; + int pgid; + INTOFF; + if (jp->state == JOBDONE) goto out; + jp->state = JOBRUNNING; + pgid = jp->ps->pid; + if (mode == FORK_FG) xtcsetpgrp(ttyfd, pgid); + killpg(pgid, SIGCONT); + ps = jp->ps; + i = jp->nprocs; + do { + if (WIFSTOPPED(ps->status)) { + ps->status = -1; + } + } while (ps++, --i); +out: + status = (mode == FORK_FG) ? waitforjob(jp) : 0; + INTON; + return status; +} + +static int sprint_status(char *os, int status, int sigonly) { + char *s = os; + int st; + st = WEXITSTATUS(status); + if (!WIFEXITED(status)) { + st = WSTOPSIG(status); + if (!WIFSTOPPED(status)) st = WTERMSIG(status); + if (sigonly) { + if (st == SIGINT || st == SIGPIPE) goto out; + if (WIFSTOPPED(status)) goto out; + } + s = stpncpy(s, strsignal(st), 32); + } else if (!sigonly) { + if (st) + s += fmtstr(s, 16, "Done(%d)", st); + else + s = stpcpy(s, "Done"); + } +out: + return s - os; +} + +static void showjob(struct output *out, struct job *jp, int mode) { + struct procstat *ps; + struct procstat *psend; + int col; + int indent; + char s[80]; + ps = jp->ps; + if (mode & SHOW_PGID) { + /* just output process (group) id of pipeline */ + outfmt(out, "%d\n", ps->pid); + return; + } + col = fmtstr(s, 16, "[%d] ", jobno(jp)); + indent = col; + if (jp == curjob) + s[col - 2] = '+'; + else if (curjob && jp == curjob->prev_job) + s[col - 2] = '-'; + if (mode & SHOW_PID) col += fmtstr(s + col, 16, "%d ", ps->pid); + psend = ps + jp->nprocs; + if (jp->state == JOBRUNNING) { + scopy("Running", s + col); + col += strlen("Running"); + } else { + int status = psend[-1].status; + if (jp->state == JOBSTOPPED) status = jp->stopstatus; + col += sprint_status(s + col, status, 0); + } + goto start; + do { + /* for each process */ + col = fmtstr(s, 48, " |\n%*c%d ", indent, ' ', ps->pid) - 3; + start: + outfmt(out, "%s%*c%s", s, 33 - col >= 0 ? 33 - col : 0, ' ', ps->cmd); + if (!(mode & SHOW_PID)) { + showpipe(jp, out); + break; + } + if (++ps == psend) { + outcslow('\n', out); + break; + } + } while (1); + jp->changed = 0; + if (jp->state == JOBDONE) { + TRACE(("showjob: freeing job %d\n", jobno(jp))); + freejob(jp); + } +} + +static int jobscmd(int argc, char **argv) { + int mode, m; + struct output *out; + mode = 0; + while ((m = nextopt("lp"))) + if (m == 'l') + mode = SHOW_PID; + else + mode = SHOW_PGID; + out = out1; + argv = argptr; + if (*argv) do + showjob(out, getjob(*argv, 0), mode); + while (*++argv); + else + showjobs(out, mode); + return 0; +} + +/* + * Print a list of jobs. If "change" is nonzero, only print jobs whose + * statuses have changed since the last call to showjobs. + */ +static void showjobs(struct output *out, int mode) { + struct job *jp; + TRACE(("showjobs(%x) called\n", mode)); + /* If not even one one job changed, there is nothing to do */ + dowait(DOWAIT_NORMAL, NULL); + for (jp = curjob; jp; jp = jp->prev_job) { + if (!(mode & SHOW_CHANGED) || jp->changed) showjob(out, jp, mode); + } +} + +/* + * Mark a job structure as unused. + */ +static void freejob(struct job *jp) { + struct procstat *ps; + int i; + INTOFF; + for (i = jp->nprocs, ps = jp->ps; --i >= 0; ps++) { + if (ps->cmd != nullstr) ckfree(ps->cmd); + } + if (jp->ps != &jp->ps0) ckfree(jp->ps); + jp->used = 0; + set_curjob(jp, CUR_DELETE); + INTON; +} + +static int waitcmd(int argc, char **argv) { + struct job *job; + int retval; + struct job *jp; + nextopt(nullstr); + retval = 0; + argv = argptr; + if (!*argv) { + /* wait for all jobs */ + for (;;) { + jp = curjob; + while (1) { + if (!jp) { + /* no running procs */ + goto out; + } + if (jp->state == JOBRUNNING) break; + jp->waited = 1; + jp = jp->prev_job; + } + if (!dowait(DOWAIT_WAITCMD, 0)) goto sigout; + } + } + retval = 127; + do { + if (**argv != '%') { + int pid = number(*argv); + job = curjob; + goto start; + do { + if (job->ps[job->nprocs - 1].pid == pid) break; + job = job->prev_job; + start: + if (!job) goto repeat; + } while (1); + } else + job = getjob(*argv, 0); + /* loop until process terminated or stopped */ + if (!dowait(DOWAIT_WAITCMD, job)) goto sigout; + job->waited = 1; + retval = getstatus(job); + repeat:; + } while (*++argv); +out: + return retval; +sigout: + retval = 128 + pending_sig; + goto out; +} + +/* + * Convert a job name to a job structure. + */ +static struct job *getjob(const char *name, int getctl) { + struct job *jp; + struct job *found; + const char *err_msg = "No such job: %s"; + unsigned num; + int c; + const char *p; + char *(*match)(const char *, const char *); + jp = curjob; + p = name; + if (!p) goto currentjob; + if (*p != '%') goto err; + c = *++p; + if (!c) goto currentjob; + if (!p[1]) { + if (c == '+' || c == '%') { + currentjob: + err_msg = "No current job"; + goto check; + } else if (c == '-') { + if (jp) jp = jp->prev_job; + err_msg = "No previous job"; + check: + if (!jp) goto err; + goto gotit; + } + } + if (is_number(p)) { + num = atoi(p); + if (num > 0 && num <= njobs) { + jp = jobtab + num - 1; + if (jp->used) goto gotit; + goto err; + } + } + match = prefix; + if (*p == '?') { + match = strstr; + p++; + } + found = 0; + while (jp) { + if (match(jp->ps[0].cmd, p)) { + if (found) goto err; + found = jp; + err_msg = "%s: ambiguous"; + } + jp = jp->prev_job; + } + if (!found) goto err; + jp = found; +gotit: + err_msg = "job %s not created under job control"; + if (getctl && jp->jobctl == 0) goto err; + return jp; +err: + sh_error(err_msg, name); +} + +/* + * Return a new job structure. + * Called with interrupts off. + */ +struct job *makejob(union node *node, int nprocs) { + int i; + struct job *jp; + for (i = njobs, jp = jobtab;; jp++) { + if (--i < 0) { + jp = growjobtab(); + break; + } + if (jp->used == 0) break; + if (jp->state != JOBDONE || !jp->waited) continue; + if (jobctl) continue; + freejob(jp); + break; + } + memset(jp, 0, sizeof(*jp)); + if (jobctl) jp->jobctl = 1; + jp->prev_job = curjob; + curjob = jp; + jp->used = 1; + jp->ps = &jp->ps0; + if (nprocs > 1) { + jp->ps = ckmalloc(nprocs * sizeof(struct procstat)); + } + TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs, jobno(jp))); + return jp; +} + +static struct job *growjobtab(void) { + unsigned len; + long offset; + struct job *jp, *jq; + len = njobs * sizeof(*jp); + jq = jobtab; + jp = ckrealloc(jq, len + 4 * sizeof(*jp)); + offset = (char *)jp - (char *)jq; + if (offset) { + /* Relocate pointers */ + unsigned l = len; + jq = (struct job *)((char *)jq + l); + while (l) { + l -= sizeof(*jp); + jq--; +#define joff(p) ((struct job *)((char *)(p) + l)) +#define jmove(p) (p) = (void *)((char *)(p) + offset) + if (likely(joff(jp)->ps == &jq->ps0)) jmove(joff(jp)->ps); + if (joff(jp)->prev_job) jmove(joff(jp)->prev_job); + } + if (curjob) jmove(curjob); +#undef joff +#undef jmove + } + njobs += 4; + jobtab = jp; + jp = (struct job *)((char *)jp + len); + jq = jp + 3; + do { + jq->used = 0; + } while (--jq >= jp); + return jp; +} + +/* + * Fork off a subshell. If we are doing job control, give the subshell its + * own process group. Jp is a job structure that the job is to be added to. + * N is the command that will be evaluated by the child. Both jp and n may + * be NULL. The mode parameter can be one of the following: + * FORK_FG - Fork off a foreground process. + * FORK_BG - Fork off a background process. + * FORK_NOJOB - Like FORK_FG, but don't give the process its own + * process group even if job control is on. + * + * When job control is turned off, background processes have their standard + * input redirected to /dev/null (except for the second and later processes + * in a pipeline). + * + * Called with interrupts off. + */ +static void forkchild(struct job *jp, union node *n, int mode) { + int lvforked; + int oldlvl; + TRACE(("Child shell %d\n", getpid())); + oldlvl = shlvl; + lvforked = vforked; + if (!lvforked) { + shlvl++; + closescript(); + clear_traps(); + /* do job control only in root shell */ + jobctl = 0; + } + if (mode != FORK_NOJOB && jp->jobctl && !oldlvl) { + int pgrp; + if (jp->nprocs == 0) + pgrp = getpid(); + else + pgrp = jp->ps[0].pid; + /* This can fail because we are doing it in the parent also */ + (void)setpgid(0, pgrp); + if (mode == FORK_FG) xtcsetpgrp(ttyfd, pgrp); + setsignal(SIGTSTP); + setsignal(SIGTTOU); + } else if (mode == FORK_BG) { + ignoresig(SIGINT); + ignoresig(SIGQUIT); + if (jp->nprocs == 0) { + close(0); + if (open(_PATH_DEVNULL, O_RDONLY, 0) != 0) sh_error("Can't open %s", _PATH_DEVNULL); + } + } + if (!oldlvl && iflag) { + if (mode != FORK_BG) { + setsignal(SIGINT); + setsignal(SIGQUIT); + } + setsignal(SIGTERM); + } + if (lvforked) return; + for (jp = curjob; jp; jp = jp->prev_job) freejob(jp); +} + +static void forkparent(struct job *jp, union node *n, int mode, int pid) { + if (pid < 0) { + TRACE(("Fork failed, errno=%d", errno)); + if (jp) freejob(jp); + sh_error("Cannot fork"); + /* NOTREACHED */ + } + TRACE(("In parent shell: child = %d\n", pid)); + if (!jp) return; + if (mode != FORK_NOJOB && jp->jobctl) { + int pgrp; + if (jp->nprocs == 0) + pgrp = pid; + else + pgrp = jp->ps[0].pid; + /* This can fail because we are doing it in the child also */ + (void)setpgid(pid, pgrp); + } + if (mode == FORK_BG) { + backgndpid = pid; /* set $! */ + set_curjob(jp, CUR_RUNNING); + } + if (jp) { + struct procstat *ps = &jp->ps[jp->nprocs++]; + ps->pid = pid; + ps->status = -1; + ps->cmd = nullstr; + if (jobctl && n) ps->cmd = commandtext(n); + } +} + +static int forkshell(struct job *jp, union node *n, int mode) { + int pid; + TRACE(("forkshell(%%%d, %p, %d) called\n", jobno(jp), n, mode)); + pid = fork(); + if (pid == 0) + forkchild(jp, n, mode); + else + forkparent(jp, n, mode, pid); + return pid; +} + +static struct job *vforkexec(union node *n, char **argv, const char *path, int idx) { + struct job *jp; + int pid; + jp = makejob(n, 1); + sigblockall(NULL); + vforked++; + pid = vfork(); + if (!pid) { + forkchild(jp, n, FORK_FG); + sigclearmask(); + shellexec(argv, path, idx); + /* NOTREACHED */ + } + vforked = 0; + sigclearmask(); + forkparent(jp, n, FORK_FG, pid); + return jp; +} + +/* + * Wait for job to finish. + * + * Under job control we have the problem that while a child process is + * running interrupts generated by the user are sent to the child but not + * to the shell. This means that an infinite loop started by an inter- + * active user may be hard to kill. With job control turned off, an + * interactive user may place an interactive program inside a loop. If + * the interactive program catches interrupts, the user doesn't want + * these interrupts to also abort the loop. The approach we take here + * is to have the shell ignore interrupt signals while waiting for a + * forground process to terminate, and then send itself an interrupt + * signal if the child process was terminated by an interrupt signal. + * Unfortunately, some programs want to do a bit of cleanup and then + * exit on interrupt; unless these processes terminate themselves by + * sending a signal to themselves (instead of calling exit) they will + * confuse this approach. + * + * Called with interrupts off. + */ +static int waitforjob(struct job *jp) { + int st; + TRACE(("waitforjob(%%%d) called\n", jp ? jobno(jp) : 0)); + dowait(jp ? DOWAIT_BLOCK : DOWAIT_NORMAL, jp); + if (!jp) return exitstatus; + st = getstatus(jp); + if (jp->jobctl) { + xtcsetpgrp(ttyfd, rootpid); + /* + * This is truly gross. + * If we're doing job control, then we did a TIOCSPGRP which + * caused us (the shell) to no longer be in the controlling + * session -- so we wouldn't have seen any ^C/SIGINT. So, we + * intuit from the subprocess exit status whether a SIGINT + * occurred, and if so interrupt ourselves. Yuck. - mycroft + */ + if (jp->sigint) raise(SIGINT); + } + if (!JOBS || jp->state == JOBDONE) freejob(jp); + return st; +} + +/* + * Wait for a process to terminate. + */ +static int waitone(int block, struct job *job) { + int pid; + int status; + struct job *jp; + struct job *thisjob = NULL; + int state; + INTOFF; + TRACE(("dowait(%d) called\n", block)); + pid = waitproc(block, &status); + TRACE(("wait returns pid %d, status=%d\n", pid, status)); + if (pid <= 0) goto out; + for (jp = curjob; jp; jp = jp->prev_job) { + struct procstat *sp; + struct procstat *spend; + if (jp->state == JOBDONE) continue; + state = JOBDONE; + spend = jp->ps + jp->nprocs; + sp = jp->ps; + do { + if (sp->pid == pid) { + TRACE(("Job %d: changing status of proc %d from 0x%x to 0x%x\n", jobno(jp), pid, sp->status, + status)); + sp->status = status; + thisjob = jp; + } + if (sp->status == -1) state = JOBRUNNING; + if (state == JOBRUNNING) continue; + if (WIFSTOPPED(sp->status)) { + jp->stopstatus = sp->status; + state = JOBSTOPPED; + } + } while (++sp < spend); + if (thisjob) goto gotjob; + } + goto out; +gotjob: + if (state != JOBRUNNING) { + thisjob->changed = 1; + if (thisjob->state != state) { + TRACE(("Job %d: changing state from %d to %d\n", jobno(thisjob), thisjob->state, state)); + thisjob->state = state; + if (state == JOBSTOPPED) { + set_curjob(thisjob, CUR_STOPPED); + } + } + } +out: + INTON; + if (thisjob && thisjob == job) { + char s[48 + 1]; + int len; + len = sprint_status(s, status, 1); + if (len) { + s[len] = '\n'; + s[len + 1] = 0; + outstr(s, out2); + } + } + return pid; +} + +static int dowait(int block, struct job *jp) { + int pid = block == DOWAIT_NORMAL ? gotsigchld : 1; + while (jp ? jp->state == JOBRUNNING : pid > 0) { + if (!jp) gotsigchld = 0; + pid = waitone(block, jp); + } + return pid; +} + +/* + * Do a wait system call. If block is zero, we return -1 rather than + * blocking. If block is DOWAIT_WAITCMD, we return 0 when a signal + * other than SIGCHLD interrupted the wait. + * + * We use sigsuspend in conjunction with a non-blocking wait3 in + * order to ensure that waitcmd exits promptly upon the reception + * of a signal. + * + * For code paths other than waitcmd we either use a blocking wait3 + * or a non-blocking wait3. For the latter case the caller of dowait + * must ensure that it is called over and over again until all dead + * children have been reaped. Otherwise zombies may linger. + */ +static int waitproc(int block, int *status) { + sigset_t oldmask; + int flags = block == DOWAIT_BLOCK ? 0 : WNOHANG; + int err; + if (jobctl) flags |= WUNTRACED; + do { + err = wait3(status, flags, NULL); + if (err || (err = -!block)) break; + sigblockall(&oldmask); + while (!gotsigchld && !pending_sig) sigsuspend(&oldmask); + sigclearmask(); + err = 0; + } while (gotsigchld); + return err; +} + +/* + * return 1 if there are stopped jobs, otherwise 0 + */ +static int stoppedjobs(void) { + struct job *jp; + int retval; + retval = 0; + if (job_warning) goto out; + jp = curjob; + if (jp && jp->state == JOBSTOPPED) { + outstr("You have stopped jobs.\n", out2); + job_warning = 2; + retval++; + } +out: + return retval; +} + +/* + * Return a string identifying a command (to be printed by the + * jobs command). + */ +static char *commandtext(union node *n) { + char *name; + STARTSTACKSTR(cmdnextc); + cmdtxt(n); + name = stackblock(); + TRACE(("commandtext: name %p, end %p\n", name, cmdnextc)); + return savestr(name); +} + +static void cmdtxt(union node *n) { + union node *np; + struct nodelist *lp; + const char *p; + char s[2]; + if (!n) return; + switch (n->type) { + default: + case NPIPE: + lp = n->npipe.cmdlist; + for (;;) { + cmdtxt(lp->n); + lp = lp->next; + if (!lp) break; + cmdputs(" | "); + } + break; + case NSEMI: + p = "; "; + goto binop; + case NAND: + p = " && "; + goto binop; + case NOR: + p = " || "; + binop: + cmdtxt(n->nbinary.ch1); + cmdputs(p); + n = n->nbinary.ch2; + goto donode; + case NREDIR: + case NBACKGND: + n = n->nredir.n; + goto donode; + case NNOT: + cmdputs("!"); + n = n->nnot.com; + donode: + cmdtxt(n); + break; + case NIF: + cmdputs("if "); + cmdtxt(n->nif.test); + cmdputs("; then "); + if (n->nif.elsepart) { + cmdtxt(n->nif.ifpart); + cmdputs("; else "); + n = n->nif.elsepart; + } else { + n = n->nif.ifpart; + } + p = "; fi"; + goto dotail; + case NSUBSHELL: + cmdputs("("); + n = n->nredir.n; + p = ")"; + goto dotail; + case NWHILE: + p = "while "; + goto until; + case NUNTIL: + p = "until "; + until: + cmdputs(p); + cmdtxt(n->nbinary.ch1); + n = n->nbinary.ch2; + p = "; done"; + dodo: + cmdputs("; do "); + dotail: + cmdtxt(n); + goto dotail2; + case NFOR: + cmdputs("for "); + cmdputs(n->nfor.var_); + cmdputs(" in "); + cmdlist(n->nfor.args, 1); + n = n->nfor.body; + p = "; done"; + goto dodo; + case NDEFUN: + cmdputs(n->ndefun.text); + p = "() { ... }"; + goto dotail2; + case NCMD: + cmdlist(n->ncmd.args, 1); + cmdlist(n->ncmd.redirect, 0); + break; + case NARG: + p = n->narg.text; + dotail2: + cmdputs(p); + break; + case NHERE: + case NXHERE: + p = "<<..."; + goto dotail2; + case NCASE: + cmdputs("case "); + cmdputs(n->ncase.expr->narg.text); + cmdputs(" in "); + for (np = n->ncase.cases; np; np = np->nclist.next) { + cmdtxt(np->nclist.pattern); + cmdputs(") "); + cmdtxt(np->nclist.body); + cmdputs(";; "); + } + p = "esac"; + goto dotail2; + case NTO: + p = ">"; + goto redir; + case NCLOBBER: + p = ">|"; + goto redir; + case NAPPEND: + p = ">>"; + goto redir; + case NTOFD: + p = ">&"; + goto redir; + case NFROM: + p = "<"; + goto redir; + case NFROMFD: + p = "<&"; + goto redir; + case NFROMTO: + p = "<>"; + redir: + s[0] = n->nfile.fd + '0'; + s[1] = '\0'; + cmdputs(s); + cmdputs(p); + if (n->type == NTOFD || n->type == NFROMFD) { + s[0] = n->ndup.dupfd + '0'; + p = s; + goto dotail2; + } else { + n = n->nfile.fname; + goto donode; + } + } +} + +static void cmdlist(union node *np, int sep) { + for (; np; np = np->narg.next) { + if (!sep) cmdputs(spcstr); + cmdtxt(np); + if (sep && np->narg.next) cmdputs(spcstr); + } +} + +static void cmdputs(const char *s) { + const char *p, *str; + char cc[2] = " "; + char *nextc; + signed char c; + int subtype = 0; + int quoted = 0; + static const char vstype[VSTYPE + 1][4] = { + "", "}", "-", "+", "?", "=", "%", "%%", "#", "##", + }; + nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc); + p = s; + while ((c = *p++) != 0) { + str = 0; + switch (c) { + case CTLESC: + c = *p++; + break; + case CTLVAR: + subtype = *p++; + if ((subtype & VSTYPE) == VSLENGTH) + str = "${#"; + else + str = "${"; + goto dostr; + case CTLENDVAR: + str = &"\"}"[!quoted]; + quoted >>= 1; + subtype = 0; + goto dostr; + case CTLBACKQ: + str = "$(...)"; + goto dostr; + case CTLARI: + str = "$(("; + goto dostr; + case CTLENDARI: + str = "))"; + goto dostr; + case CTLQUOTEMARK: + quoted ^= 1; + c = '"'; + break; + case '=': + if (subtype == 0) break; + if ((subtype & VSTYPE) != VSNORMAL) quoted <<= 1; + str = vstype[subtype & VSTYPE]; + if (subtype & VSNUL) + c = ':'; + else + goto checkstr; + break; + case '\'': + case '\\': + case '"': + case '$': + /* These can only happen inside quotes */ + cc[0] = c; + str = cc; + c = '\\'; + break; + default: + break; + } + USTPUTC(c, nextc); + checkstr: + if (!str) continue; + dostr: + while ((c = *str++)) { + USTPUTC(c, nextc); + } + } + if (quoted & 1) { + USTPUTC('"', nextc); + } + *nextc = 0; + cmdnextc = nextc; +} + +static void showpipe(struct job *jp, struct output *out) { + struct procstat *sp; + struct procstat *spend; + spend = jp->ps + jp->nprocs; + for (sp = jp->ps + 1; sp < spend; sp++) outfmt(out, " | %s", sp->cmd); + outcslow('\n', out); + flushall(); +} + +static void xtcsetpgrp(int fd, int pgrp) { + if (tcsetpgrp(fd, pgrp)) sh_error("Cannot set tty process group (%s)", strerror(errno)); +} + +static int getstatus(struct job *job) { + int status; + int retval; + status = job->ps[job->nprocs - 1].status; + retval = WEXITSTATUS(status); + if (!WIFEXITED(status)) { + retval = WSTOPSIG(status); + if (!WIFSTOPPED(status)) { + /* XXX: limits number of signals */ + retval = WTERMSIG(status); + if (retval == SIGINT) job->sigint = 1; + } + retval += 128; + } + TRACE(("getstatus: job %d, nproc %d, status %x, retval %x\n", jobno(job), job->nprocs, status, + retval)); + return retval; +} + +/** handle one line of the read command. + * more fields than variables -> remainder shall be part of last variable. + * less fields than variables -> remaining variables unset. + * + * @param line complete line of input + * @param ac argument count + * @param ap argument (variable) list + * @param len length of line including trailing '\0' + */ +static void readcmd_handle_line(char *s, int ac, char **ap) { + struct arglist arglist; + struct strlist *sl; + s = grabstackstr(s); + arglist.lastp = &arglist.list; + ifsbreakup(s, ac, &arglist); + *arglist.lastp = NULL; + ifsfree(); + sl = arglist.list; + do { + if (!sl) { + /* nullify remaining arguments */ + do { + setvar(*ap, nullstr, 0); + } while (*++ap); + return; + } + /* set variable to field */ + rmescapes(sl->text, 0); + setvar(*ap, sl->text, 0); + sl = sl->next; + } while (*++ap); +} + +/* + * The read builtin. The -e option causes backslashes to escape the + * following character. The -p option followed by an argument prompts + * with the argument. + * + * This uses unbuffered input, which may be avoidable in some cases. + */ +static int readcmd(int argc, char **argv) { + char **ap; + char c; + int rflag; + char *prompt; + char *p; + int startloc; + int newloc; + int status; + int i; + rflag = 0; + prompt = NULL; + while ((i = nextopt("p:r")) != '\0') { + if (i == 'p') + prompt = optionarg; + else + rflag = 1; + } + if (prompt && isatty(0)) { + outstr(prompt, out2); + } + if (*(ap = argptr) == NULL) sh_error("arg count"); + status = 0; + STARTSTACKSTR(p); + goto start; + for (;;) { + switch (read(STDIN_FILENO, &c, 1)) { + case 1: + break; + default: + if (errno == EINTR && !pending_sig) continue; + /* fall through */ + case 0: + status = 1; + goto out; + } + if (c == '\0') continue; + if (newloc >= startloc) { + if (c == '\n') goto resetbs; + goto put; + } + if (!rflag && c == '\\') { + newloc = p - (char *)stackblock(); + continue; + } + if (c == '\n') break; + put: + CHECKSTRSPACE(2, p); + if (strchr(qchars, c)) USTPUTC(CTLESC, p); + USTPUTC(c, p); + if (newloc >= startloc) { + resetbs: + recordregion(startloc, newloc, 0); + start: + startloc = p - (char *)stackblock(); + newloc = startloc - 1; + } + } +out: + recordregion(startloc, p - (char *)stackblock(), 0); + STACKSTRNUL(p); + readcmd_handle_line(p + 1, argc - (ap - argv), ap); + return status; +} + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § the unbourne shell » builtins » umask ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + This code was ripped from pdksh 5.2.14 and hacked for use with + dash by Herbert Xu. Public Domain. */ + +static int umaskcmd(int argc, char **argv) { + char *ap; + int mask; + int i; + int symbolic_mode = 0; + while ((i = nextopt("S")) != '\0') { + symbolic_mode = 1; + } + INTOFF; + mask = umask(0); + umask(mask); + INTON; + if ((ap = *argptr) == NULL) { + if (symbolic_mode) { + char buf[18]; + int j; + mask = ~mask; + ap = buf; + for (i = 0; i < 3; i++) { + *ap++ = "ugo"[i]; + *ap++ = '='; + for (j = 0; j < 3; j++) + if (mask & (1u << (8 - (3 * i + j)))) *ap++ = "rwx"[j]; + *ap++ = ','; + } + ap[-1] = '\0'; + out1fmt("%s\n", buf); + } else { + out1fmt("%.4o\n", mask); + } + } else { + int new_mask; + if (isdigit((unsigned char)*ap)) { + new_mask = 0; + do { + if (*ap >= '8' || *ap < '0') sh_error(illnum, *argptr); + new_mask = (new_mask << 3) + (*ap - '0'); + } while (*++ap != '\0'); + } else { + int positions, new_val; + char op; + mask = ~mask; + new_mask = mask; + positions = 0; + while (*ap) { + while (*ap && strchr("augo", *ap)) switch (*ap++) { + case 'a': + positions |= 0111; + break; + case 'u': + positions |= 0100; + break; + case 'g': + positions |= 0010; + break; + case 'o': + positions |= 0001; + break; + } + if (!positions) positions = 0111; /* default is a */ + if (!strchr("=+-", op = *ap)) break; + ap++; + new_val = 0; + while (*ap && strchr("rwxugoXs", *ap)) switch (*ap++) { + case 'r': + new_val |= 04; + break; + case 'w': + new_val |= 02; + break; + case 'x': + new_val |= 01; + break; + case 'u': + new_val |= mask >> 6; + break; + case 'g': + new_val |= mask >> 3; + break; + case 'o': + new_val |= mask >> 0; + break; + case 'X': + if (mask & 0111) new_val |= 01; + break; + case 's': /* ignored */ + break; + } + new_val = (new_val & 07) * positions; + switch (op) { + case '-': + new_mask &= ~new_val; + break; + case '=': + new_mask = new_val | (new_mask & ~(positions * 07)); + break; + case '+': + new_mask |= new_val; + } + if (*ap == ',') { + positions = 0; + ap++; + } else if (!strchr("=+-", *ap)) + break; + } + if (*ap) { + sh_error("Illegal mode: %s", *argptr); + return 1; + } + new_mask = ~new_mask; + } + umask(new_mask); + } + return 0; +} + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § the unbourne shell » builtins » ulimit ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and + Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with + ash by J.T. Conklin. Public Domain. */ + +enum limtype { SOFT = 0x1, HARD = 0x2 }; + +static void printlim(enum limtype how, const struct rlimit *limit, const struct limits *l) { + uint64_t val; + val = limit->rlim_max; + if (how & SOFT) val = limit->rlim_cur; + if (val == RLIM_INFINITY) + out1fmt("unlimited\n"); + else { + val /= l->factor; + out1fmt("%ld\n", (int64_t)val); + } +} + +static int ulimitcmd(int argc, char **argv) { + static const struct limits limits[] = {{(char *)0, 0, 0, '\0'}}; + int c; + uint64_t val = 0; + enum limtype how = SOFT | HARD; + const struct limits *l; + int set, all = 0; + int optc, what; + struct rlimit limit; + what = 'f'; + while ((optc = nextopt("HSa")) != '\0') { + switch (optc) { + case 'H': + how = HARD; + break; + case 'S': + how = SOFT; + break; + case 'a': + all = 1; + break; + default: + what = optc; + } + } + for (l = limits; l->option != what; l++) + ; + set = *argptr ? 1 : 0; + if (set) { + char *p = *argptr; + if (all || argptr[1]) sh_error("too many arguments"); + if (strcmp(p, "unlimited") == 0) + val = RLIM_INFINITY; + else { + val = (uint64_t)0; + while ((c = *p++) >= '0' && c <= '9') { + val = (val * 10) + (long)(c - '0'); + if (val < (uint64_t)0) break; + } + if (c) sh_error("bad number"); + val *= l->factor; + } + } + if (all) { + for (l = limits; l->name; l++) { + getrlimit(l->cmd, &limit); + out1fmt("%-20s ", l->name); + printlim(how, &limit, l); + } + return 0; + } + getrlimit(l->cmd, &limit); + if (set) { + if (how & HARD) limit.rlim_max = val; + if (how & SOFT) limit.rlim_cur = val; + if (setrlimit(l->cmd, &limit) < 0) sh_error("error setting limit (%s)", strerror(errno)); + } else { + printlim(how, &limit, l); + } + return 0; +} + +/* + * Produce a possibly single quoted string suitable as input to the shell. + * The return string is allocated on the stack. + */ +static char *single_quote(const char *s) { + char *p; + STARTSTACKSTR(p); + do { + char *q; + unsigned len; + len = strchrnul(s, '\'') - s; + q = p = makestrspace(len + 3, p); + *q++ = '\''; + q = mempcpy(q, s, len); + *q++ = '\''; + s += len; + STADJUST(q - p, p); + len = strspn(s, "'"); + if (!len) break; + q = p = makestrspace(len + 3, p); + *q++ = '"'; + q = mempcpy(q, s, len); + *q++ = '"'; + s += len; + STADJUST(q - p, p); + } while (*s); + USTPUTC(0, p); + return stackblock(); +} + +/* + * Process the shell command line arguments. + */ +static int procargs(int argc, char **argv) { + int i; + const char *xminusc; + char **xargv; + int login; + xargv = argv; + login = xargv[0] && xargv[0][0] == '-'; + arg0 = xargv[0]; + if (argc > 0) xargv++; + for (i = 0; i < NOPTS; i++) optlist[i] = 2; + argptr = xargv; + login |= options(1); + xargv = argptr; + xminusc = minusc; + if (*xargv == NULL) { + if (xminusc) sh_error("-c requires an argument"); + sflag = 1; + } + /* JART: fuck tty check this is documented behavior w/ no args */ + if (iflag == 2 && sflag == 1 /* && isatty(0) && isatty(1) */) iflag = 1; + if (mflag == 2) mflag = iflag; + for (i = 0; i < NOPTS; i++) + if (optlist[i] == 2) optlist[i] = 0; + /* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */ + if (xminusc) { + minusc = *xargv++; + if (*xargv) goto setarg0; + } else if (!sflag) { + setinputfile(*xargv, 0); + setarg0: + arg0 = *xargv++; + commandname = arg0; + } + shellparam.p = xargv; + shellparam.optind = 1; + shellparam.optoff = -1; + /* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */ + while (*xargv) { + shellparam.nparam++; + xargv++; + } + optschanged(); + return login; +} + +static void optschanged(void) { + setinteractive(iflag); + setjobctl(mflag); +} + +static void setoption(int flag, int val) { + int i; + for (i = 0; i < NOPTS; i++) + if (optletters[i] == flag) { + optlist[i] = val; + if (val) { + /* #%$ hack for ksh semantics */ + if (flag == 'V') + Eflag = 0; + else if (flag == 'E') + Vflag = 0; + } + return; + } + sh_error("Illegal option -%c", flag); + /* NOTREACHED */ +} + +/* + * Process shell options. The global variable argptr contains a pointer + * to the argument list; we advance it past the options. + */ +static int options(int cmdline) { + char *p; + int val; + int c; + int login = 0; + if (cmdline) minusc = NULL; + while ((p = *argptr) != NULL) { + argptr++; + if ((c = *p++) == '-') { + val = 1; + if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) { + if (!cmdline) { + /* "-" means turn off -x and -v */ + if (p[0] == '\0') xflag = vflag = 0; + /* "--" means reset params */ + else if (*argptr == NULL) + setparam(argptr); + } + break; /* "-" or "--" terminates options */ + } + } else if (c == '+') { + val = 0; + } else { + argptr--; + break; + } + while ((c = *p++) != '\0') { + if (c == 'c' && cmdline) { + minusc = p; /* command is after shell args*/ + } else if (c == 'l' && cmdline) { + login = 1; + } else if (c == 'o') { + minus_o(*argptr, val); + if (*argptr) argptr++; + } else { + setoption(c, val); + } + } + } + return login; +} + +static void minus_o(char *name, int val) { + int i; + if (name == NULL) { + if (val) { + outstr("Current option settings\n", out1); + for (i = 0; i < NOPTS; i++) { + out1fmt("%-16s%s\n", optnames[i], optlist[i] ? "on" : "off"); + } + } else { + for (i = 0; i < NOPTS; i++) { + out1fmt("set %s %s\n", optlist[i] ? "-o" : "+o", optnames[i]); + } + } + } else { + for (i = 0; i < NOPTS; i++) + if (equal(name, optnames[i])) { + optlist[i] = val; + return; + } + sh_error("Illegal option -o %s", name); + } +} + +/* + * Set the shell parameters. + */ +static void setparam(char **argv) { + char **newparam; + char **ap; + int nparam; + for (nparam = 0; argv[nparam]; nparam++) + ; + ap = newparam = ckmalloc((nparam + 1) * sizeof *ap); + while (*argv) { + *ap++ = savestr(*argv++); + } + *ap = NULL; + freeparam(&shellparam); + shellparam.malloc = 1; + shellparam.nparam = nparam; + shellparam.p = newparam; + shellparam.optind = 1; + shellparam.optoff = -1; +} + +/* + * Free the list of positional parameters. + */ +static void freeparam(volatile struct shparam *param) { + char **ap; + if (param->malloc) { + for (ap = param->p; *ap; ap++) ckfree(*ap); + ckfree(param->p); + } +} + +/* + * The shift builtin command. + */ +static int shiftcmd(int argc, char **argv) { + int n; + char **ap1, **ap2; + n = 1; + if (argc > 1) n = number(argv[1]); + if (n > shellparam.nparam) sh_error("can't shift that many"); + INTOFF; + shellparam.nparam -= n; + for (ap1 = shellparam.p; --n >= 0; ap1++) { + if (shellparam.malloc) ckfree(*ap1); + } + ap2 = shellparam.p; + while ((*ap2++ = *ap1++) != NULL) + ; + shellparam.optind = 1; + shellparam.optoff = -1; + INTON; + return 0; +} + +/* + * The set command builtin. + */ +static int setcmd(int argc, char **argv) { + if (argc == 1) return showvars(nullstr, 0, VUNSET); + INTOFF; + options(0); + optschanged(); + if (*argptr != NULL) { + setparam(argptr); + } + INTON; + return 0; +} + +static void getoptsreset(value) const char *value; +{ + shellparam.optind = number(value) ?: 1; + shellparam.optoff = -1; +} + +/* + * The getopts builtin. Shellparam.optnext points to the next argument + * to be processed. Shellparam.optptr points to the next character to + * be processed in the current argument. If shellparam.optnext is NULL, + * then it's the first time getopts has been called. + */ +static int getoptscmd(int argc, char **argv) { + char **optbase; + if (argc < 3) + sh_error("Usage: getopts optstring var [arg]"); + else if (argc == 3) { + optbase = shellparam.p; + if ((unsigned)shellparam.optind > shellparam.nparam + 1) { + shellparam.optind = 1; + shellparam.optoff = -1; + } + } else { + optbase = &argv[3]; + if ((unsigned)shellparam.optind > argc - 2) { + shellparam.optind = 1; + shellparam.optoff = -1; + } + } + return getopts(argv[1], argv[2], optbase); +} + +static int getopts(char *optstr, char *optvar, char **optfirst) { + char *p, *q; + char c = '?'; + int done = 0; + char s[2]; + char **optnext; + int ind = shellparam.optind; + int off = shellparam.optoff; + shellparam.optind = -1; + optnext = optfirst + ind - 1; + if (ind <= 1 || off < 0 || strlen(optnext[-1]) < off) + p = NULL; + else + p = optnext[-1] + off; + if (p == NULL || *p == '\0') { + /* Current word is done, advance */ + p = *optnext; + if (p == NULL || *p != '-' || *++p == '\0') { + atend: + p = NULL; + done = 1; + goto out; + } + optnext++; + if (p[0] == '-' && p[1] == '\0') /* check for "--" */ + goto atend; + } + c = *p++; + for (q = optstr; *q != c;) { + if (*q == '\0') { + if (optstr[0] == ':') { + s[0] = c; + s[1] = '\0'; + setvar("OPTARG", s, 0); + } else { + outfmt(&errout, "Illegal option -%c\n", c); + (void)unsetvar("OPTARG"); + } + c = '?'; + goto out; + } + if (*++q == ':') q++; + } + if (*++q == ':') { + if (*p == '\0' && (p = *optnext) == NULL) { + if (optstr[0] == ':') { + s[0] = c; + s[1] = '\0'; + setvar("OPTARG", s, 0); + c = ':'; + } else { + outfmt(&errout, "No arg for -%c option\n", c); + (void)unsetvar("OPTARG"); + c = '?'; + } + goto out; + } + if (p == *optnext) optnext++; + setvar("OPTARG", p, 0); + p = NULL; + } else + setvar("OPTARG", nullstr, 0); +out: + ind = optnext - optfirst + 1; + setvarint("OPTIND", ind, VNOFUNC); + s[0] = c; + s[1] = '\0'; + setvar(optvar, s, 0); + shellparam.optoff = p ? p - *(optnext - 1) : -1; + shellparam.optind = ind; + return done; +} + +/* + * XXX - should get rid of. have all builtins use getopt(3). the + * library getopt must have the BSD extension function variable "optreset" + * otherwise it can't be used within the shell safely. + * + * Standard option processing (a la getopt) for builtin routines. The + * only argument that is passed to nextopt is the option string; the + * other arguments are unnecessary. It return the character, or '\0' on + * end of input. + */ +static int nextopt(const char *optstring) { + char *p; + const char *q; + char c; + if ((p = optptr) == NULL || *p == '\0') { + p = *argptr; + if (p == NULL || *p != '-' || *++p == '\0') return '\0'; + argptr++; + if (p[0] == '-' && p[1] == '\0') /* check for "--" */ + return '\0'; + } + c = *p++; + for (q = optstring; *q != c;) { + if (*q == '\0') sh_error("Illegal option -%c", c); + if (*++q == ':') q++; + } + if (*++q == ':') { + if (*p == '\0' && (p = *argptr++) == NULL) { + sh_error("No arg for -%c option", c); + } + optionarg = p; + p = NULL; + } + optptr = p; + return c; +} + +/* values returned by readtoken */ +static int isassignment(const char *p) { + const char *q = endofname(p); + if (p == q) return 0; + return *q == '='; +} + +static inline int realeofmark(const char *eofmark) { + return eofmark && eofmark != FAKEEOFMARK; +} + +/* + * Read and parse a command. Returns NEOF on end of file. (NULL is a + * valid parse tree indicating a blank line.) + */ +static union node *parsecmd(int interact) { + tokpushback = 0; + checkkwd = 0; + heredoclist = 0; + doprompt = interact; + if (doprompt) setprompt(doprompt); + needprompt = 0; + return list(1); +} + +static union node *list(int nlflag) { + union node *n1, *n2, *n3; + int tok; + n1 = NULL; + for (;;) { + switch (peektoken()) { + case TNL: + if (!(nlflag & 1)) break; + parseheredoc(); + return n1; + case TEOF: + if (!n1 && (nlflag & 1)) n1 = NEOF; + parseheredoc(); + return n1; + } + checkkwd = CHKNL | CHKKWD | CHKALIAS; + if (nlflag == 2 && tokendlist[peektoken()]) return n1; + nlflag |= 2; + n2 = andor(); + tok = readtoken(); + if (tok == TBACKGND) { + if (n2->type == NPIPE) { + n2->npipe.backgnd = 1; + } else { + if (n2->type != NREDIR) { + n3 = stalloc(sizeof(struct nredir)); + n3->nredir.n = n2; + n3->nredir.redirect = NULL; + n2 = n3; + } + n2->type = NBACKGND; + } + } + if (n1 == NULL) { + n1 = n2; + } else { + n3 = (union node *)stalloc(sizeof(struct nbinary)); + n3->type = NSEMI; + n3->nbinary.ch1 = n1; + n3->nbinary.ch2 = n2; + n1 = n3; + } + switch (tok) { + case TNL: + case TEOF: + tokpushback++; + /* fall through */ + case TBACKGND: + case TSEMI: + break; + default: + if ((nlflag & 1)) synexpect(-1); + tokpushback++; + return n1; + } + } +} + +static union node *andor(void) { + union node *n1, *n2, *n3; + int t; + n1 = pipeline(); + for (;;) { + if ((t = readtoken()) == TAND) { + t = NAND; + } else if (t == TOR) { + t = NOR; + } else { + tokpushback++; + return n1; + } + checkkwd = CHKNL | CHKKWD | CHKALIAS; + n2 = pipeline(); + n3 = (union node *)stalloc(sizeof(struct nbinary)); + n3->type = t; + n3->nbinary.ch1 = n1; + n3->nbinary.ch2 = n2; + n1 = n3; + } +} + +static union node *pipeline(void) { + union node *n1, *n2, *pipenode; + struct nodelist *lp, *prev; + int negate; + negate = 0; + TRACE(("pipeline: entered\n")); + if (readtoken() == TNOT) { + negate = !negate; + checkkwd = CHKKWD | CHKALIAS; + } else + tokpushback++; + n1 = command(); + if (readtoken() == TPIPE) { + pipenode = (union node *)stalloc(sizeof(struct npipe)); + pipenode->type = NPIPE; + pipenode->npipe.backgnd = 0; + lp = (struct nodelist *)stalloc(sizeof(struct nodelist)); + pipenode->npipe.cmdlist = lp; + lp->n = n1; + do { + prev = lp; + lp = (struct nodelist *)stalloc(sizeof(struct nodelist)); + checkkwd = CHKNL | CHKKWD | CHKALIAS; + lp->n = command(); + prev->next = lp; + } while (readtoken() == TPIPE); + lp->next = NULL; + n1 = pipenode; + } + tokpushback++; + if (negate) { + n2 = (union node *)stalloc(sizeof(struct nnot)); + n2->type = NNOT; + n2->nnot.com = n1; + return n2; + } else + return n1; +} + +static union node *command(void) { + union node *n1, *n2; + union node *ap, **app; + union node *cp, **cpp; + union node *redir, **rpp; + union node **rpp2; + int t; + int savelinno; + redir = NULL; + rpp2 = &redir; + savelinno = plinno; + switch (readtoken()) { + default: + synexpect(-1); + /* NOTREACHED */ + case TIF: + n1 = (union node *)stalloc(sizeof(struct nif)); + n1->type = NIF; + n1->nif.test = list(0); + if (readtoken() != TTHEN) synexpect(TTHEN); + n1->nif.ifpart = list(0); + n2 = n1; + while (readtoken() == TELIF) { + n2->nif.elsepart = (union node *)stalloc(sizeof(struct nif)); + n2 = n2->nif.elsepart; + n2->type = NIF; + n2->nif.test = list(0); + if (readtoken() != TTHEN) synexpect(TTHEN); + n2->nif.ifpart = list(0); + } + if (lasttoken == TELSE) + n2->nif.elsepart = list(0); + else { + n2->nif.elsepart = NULL; + tokpushback++; + } + t = TFI; + break; + case TWHILE: + case TUNTIL: { + int got; + n1 = (union node *)stalloc(sizeof(struct nbinary)); + n1->type = (lasttoken == TWHILE) ? NWHILE : NUNTIL; + n1->nbinary.ch1 = list(0); + if ((got = readtoken()) != TDO) { + TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : "")); + synexpect(TDO); + } + n1->nbinary.ch2 = list(0); + t = TDONE; + break; + } + case TFOR: + if (readtoken() != TWORD || quoteflag || !goodname(wordtext)) + synerror("Bad for loop variable"); + n1 = (union node *)stalloc(sizeof(struct nfor)); + n1->type = NFOR; + n1->nfor.linno = savelinno; + n1->nfor.var_ = wordtext; + checkkwd = CHKNL | CHKKWD | CHKALIAS; + if (readtoken() == TIN) { + app = ≈ + while (readtoken() == TWORD) { + n2 = (union node *)stalloc(sizeof(struct narg)); + n2->type = NARG; + n2->narg.text = wordtext; + n2->narg.backquote = backquotelist; + *app = n2; + app = &n2->narg.next; + } + *app = NULL; + n1->nfor.args = ap; + if (lasttoken != TNL && lasttoken != TSEMI) synexpect(-1); + } else { + n2 = (union node *)stalloc(sizeof(struct narg)); + n2->type = NARG; + n2->narg.text = (char *)dolatstr; + n2->narg.backquote = NULL; + n2->narg.next = NULL; + n1->nfor.args = n2; + /* + * Newline or semicolon here is optional (but note + * that the original Bourne shell only allowed NL). + */ + if (lasttoken != TSEMI) tokpushback++; + } + checkkwd = CHKNL | CHKKWD | CHKALIAS; + if (readtoken() != TDO) synexpect(TDO); + n1->nfor.body = list(0); + t = TDONE; + break; + case TCASE: + n1 = (union node *)stalloc(sizeof(struct ncase)); + n1->type = NCASE; + n1->ncase.linno = savelinno; + if (readtoken() != TWORD) synexpect(TWORD); + n1->ncase.expr = n2 = (union node *)stalloc(sizeof(struct narg)); + n2->type = NARG; + n2->narg.text = wordtext; + n2->narg.backquote = backquotelist; + n2->narg.next = NULL; + checkkwd = CHKNL | CHKKWD | CHKALIAS; + if (readtoken() != TIN) synexpect(TIN); + cpp = &n1->ncase.cases; + next_case: + checkkwd = CHKNL | CHKKWD; + t = readtoken(); + while (t != TESAC) { + if (lasttoken == TLP) readtoken(); + *cpp = cp = (union node *)stalloc(sizeof(struct nclist)); + cp->type = NCLIST; + app = &cp->nclist.pattern; + for (;;) { + *app = ap = (union node *)stalloc(sizeof(struct narg)); + ap->type = NARG; + ap->narg.text = wordtext; + ap->narg.backquote = backquotelist; + if (readtoken() != TPIPE) break; + app = &ap->narg.next; + readtoken(); + } + ap->narg.next = NULL; + if (lasttoken != TRP) synexpect(TRP); + cp->nclist.body = list(2); + cpp = &cp->nclist.next; + checkkwd = CHKNL | CHKKWD; + if ((t = readtoken()) != TESAC) { + if (t != TENDCASE) + synexpect(TENDCASE); + else + goto next_case; + } + } + *cpp = NULL; + goto redir; + case TLP: + n1 = (union node *)stalloc(sizeof(struct nredir)); + n1->type = NSUBSHELL; + n1->nredir.linno = savelinno; + n1->nredir.n = list(0); + n1->nredir.redirect = NULL; + t = TRP; + break; + case TBEGIN: + n1 = list(0); + t = TEND; + break; + case TWORD: + case TREDIR: + tokpushback++; + return simplecmd(); + } + if (readtoken() != t) synexpect(t); +redir: + /* Now check for redirection which may follow command */ + checkkwd = CHKKWD | CHKALIAS; + rpp = rpp2; + while (readtoken() == TREDIR) { + *rpp = n2 = redirnode; + rpp = &n2->nfile.next; + parsefname(); + } + tokpushback++; + *rpp = NULL; + if (redir) { + if (n1->type != NSUBSHELL) { + n2 = (union node *)stalloc(sizeof(struct nredir)); + n2->type = NREDIR; + n2->nredir.linno = savelinno; + n2->nredir.n = n1; + n1 = n2; + } + n1->nredir.redirect = redir; + } + return n1; +} + +static union node *simplecmd(void) { + union node *args, **app; + union node *n = NULL; + union node *vars, **vpp; + union node **rpp, *redir; + int savecheckkwd; + int savelinno; + args = NULL; + app = &args; + vars = NULL; + vpp = &vars; + redir = NULL; + rpp = &redir; + savecheckkwd = CHKALIAS; + savelinno = plinno; + for (;;) { + checkkwd = savecheckkwd; + switch (readtoken()) { + case TWORD: + n = (union node *)stalloc(sizeof(struct narg)); + n->type = NARG; + n->narg.text = wordtext; + n->narg.backquote = backquotelist; + if (savecheckkwd && isassignment(wordtext)) { + *vpp = n; + vpp = &n->narg.next; + } else { + *app = n; + app = &n->narg.next; + savecheckkwd = 0; + } + break; + case TREDIR: + *rpp = n = redirnode; + rpp = &n->nfile.next; + parsefname(); /* read name of redirection file */ + break; + case TLP: + if (args && app == &args->narg.next && !vars && !redir) { + struct builtincmd *bcmd; + const char *name; + /* We have a function */ + if (readtoken() != TRP) synexpect(TRP); + name = n->narg.text; + if (!goodname(name) || ((bcmd = find_builtin(name)) && bcmd->flags & BUILTIN_SPECIAL)) + synerror("Bad function name"); + n->type = NDEFUN; + checkkwd = CHKNL | CHKKWD | CHKALIAS; + n->ndefun.text = n->narg.text; + n->ndefun.linno = plinno; + n->ndefun.body = command(); + return n; + } + /* fall through */ + default: + tokpushback++; + goto out; + } + } +out: + *app = NULL; + *vpp = NULL; + *rpp = NULL; + n = (union node *)stalloc(sizeof(struct ncmd)); + n->type = NCMD; + n->ncmd.linno = savelinno; + n->ncmd.args = args; + n->ncmd.assign = vars; + n->ncmd.redirect = redir; + return n; +} + +static union node *makename(void) { + union node *n; + n = (union node *)stalloc(sizeof(struct narg)); + n->type = NARG; + n->narg.next = NULL; + n->narg.text = wordtext; + n->narg.backquote = backquotelist; + return n; +} + +static void fixredir(union node *n, const char *text, int err) { + TRACE(("Fix redir %s %d\n", text, err)); + if (!err) n->ndup.vname = NULL; + if (is_digit(text[0]) && text[1] == '\0') + n->ndup.dupfd = digit_val(text[0]); + else if (text[0] == '-' && text[1] == '\0') + n->ndup.dupfd = -1; + else { + if (err) + synerror("Bad fd number"); + else + n->ndup.vname = makename(); + } +} + +static void parsefname(void) { + union node *n = redirnode; + if (n->type == NHERE) checkkwd = CHKEOFMARK; + if (readtoken() != TWORD) synexpect(-1); + if (n->type == NHERE) { + struct heredoc *here = heredoc; + struct heredoc *p; + if (quoteflag == 0) n->type = NXHERE; + TRACE(("Here document %d\n", n->type)); + rmescapes(wordtext, 0); + here->eofmark = wordtext; + here->next = NULL; + if (heredoclist == NULL) + heredoclist = here; + else { + for (p = heredoclist; p->next; p = p->next) + ; + p->next = here; + } + } else if (n->type == NTOFD || n->type == NFROMFD) { + fixredir(n, wordtext, 0); + } else { + n->nfile.fname = makename(); + } +} + +/* + * Input any here documents. + */ +static void parseheredoc(void) { + struct heredoc *here; + union node *n; + here = heredoclist; + heredoclist = 0; + while (here) { + if (needprompt) { + setprompt(2); + } + if (here->here->type == NHERE) + readtoken1(pgetc(), SQSYNTAX, here->eofmark, here->striptabs); + else + readtoken1(pgetc_eatbnl(), DQSYNTAX, here->eofmark, here->striptabs); + n = (union node *)stalloc(sizeof(struct narg)); + n->narg.type = NARG; + n->narg.next = NULL; + n->narg.text = wordtext; + n->narg.backquote = backquotelist; + here->here->nhere.doc = n; + here = here->next; + } +} + +static int peektoken(void) { + int t; + t = readtoken(); + tokpushback++; + return (t); +} + +static int readtoken(void) { + int t; + int kwd = checkkwd; +top: + t = xxreadtoken(); + /* + * eat newlines + */ + if (kwd & CHKNL) { + while (t == TNL) { + parseheredoc(); + t = xxreadtoken(); + } + } + if (t != TWORD || quoteflag) { + goto out; + } + /* + * check for keywords + */ + if (kwd & CHKKWD) { + const char *const *pp; + const int KWDOFFSET = 13; + if ((pp = findkwd(wordtext))) { + lasttoken = t = pp - parsekwd + KWDOFFSET; + TRACE(("keyword %s recognized\n", tokname[t])); + goto out; + } + } + if (checkkwd & CHKALIAS) { + struct alias *ap; + if ((ap = lookupalias(wordtext, 1)) != NULL) { + if (*ap->val) { + pushstring(ap->val, ap); + } + goto top; + } + } +out: + checkkwd = 0; + return (t); +} + +static void nlprompt(void) { + plinno++; + if (doprompt) setprompt(2); +} + +static void nlnoprompt(void) { + plinno++; + needprompt = doprompt; +} + +/* + * Read the next input token. + * If the token is a word, we set backquotelist to the list of cmds in + * backquotes. We set quoteflag to true if any part of the word was + * quoted. + * If the token is TREDIR, then we set redirnode to a structure containing + * the redirection. + * + * [Change comment: here documents and internal procedures] + * [Readtoken shouldn't have any arguments. Perhaps we should make the + * word parsing code into a separate routine. In this case, readtoken + * doesn't need to have any internal procedures, but parseword does. + * We could also make parseoperator in essence the main routine, and + * have parseword (readtoken1?) handle both words and redirection.] + */ +static int xxreadtoken(void) { +#define RETURN(token) return lasttoken = token + int c; + if (tokpushback) { + tokpushback = 0; + return lasttoken; + } + if (needprompt) { + setprompt(2); + } + for (;;) { /* until token or start of word found */ + c = pgetc_eatbnl(); + switch (c) { + case ' ': + case '\t': + case PEOA: + continue; + case '#': + while ((c = pgetc()) != '\n' && c != PEOF) + ; + pungetc(); + continue; + case '\n': + nlnoprompt(); + RETURN(TNL); + case PEOF: + RETURN(TEOF); + case '&': + if (pgetc_eatbnl() == '&') RETURN(TAND); + pungetc(); + RETURN(TBACKGND); + case '|': + if (pgetc_eatbnl() == '|') RETURN(TOR); + pungetc(); + RETURN(TPIPE); + case ';': + if (pgetc_eatbnl() == ';') RETURN(TENDCASE); + pungetc(); + RETURN(TSEMI); + case '(': + RETURN(TLP); + case ')': + RETURN(TRP); + } + break; + } + return readtoken1(c, BASESYNTAX, (char *)NULL, 0); +#undef RETURN +} + +static int pgetc_eatbnl(void) { + int c; + while ((c = pgetc()) == '\\') { + if (pgetc2() != '\n') { + pungetc(); + break; + } + nlprompt(); + } + return c; +} + +static int pgetc_top(struct synstack *stack) { + return stack->syntax == SQSYNTAX ? pgetc() : pgetc_eatbnl(); +} + +static void synstack_push(struct synstack **stack, struct synstack *next, const char *syntax) { + memset(next, 0, sizeof(*next)); + next->syntax = syntax; + next->next = *stack; + (*stack)->prev = next; + *stack = next; +} + +static void synstack_pop(struct synstack **stack) { + *stack = (*stack)->next; +} + +/* + * If eofmark is NULL, read a word or a redirection symbol. If eofmark + * is not NULL, read a here document. In the latter case, eofmark is the + * word which marks the end of the document and striptabs is true if + * leading tabs should be stripped from the document. The argument firstc + * is the first character of the input token or document. + * + * Because C does not have internal subroutines, I have simulated them + * using goto's to implement the subroutine linkage. The following macros + * will run code that appears at the end of readtoken1. + */ + +#define CHECKEND() \ + { \ + goto checkend; \ + checkend_return:; \ + } +#define PARSEREDIR() \ + { \ + goto parseredir; \ + parseredir_return:; \ + } +#define PARSESUB() \ + { \ + goto parsesub; \ + parsesub_return:; \ + } +#define PARSEBACKQOLD() \ + { \ + oldstyle = 1; \ + goto parsebackq; \ + parsebackq_oldreturn:; \ + } +#define PARSEBACKQNEW() \ + { \ + oldstyle = 0; \ + goto parsebackq; \ + parsebackq_newreturn:; \ + } +#define PARSEARITH() \ + { \ + goto parsearith; \ + parsearith_return:; \ + } + +static int readtoken1(int firstc, char const *syntax, char *eofmark, int striptabs) { + int c = firstc; + char *out; + unsigned len; + struct nodelist *bqlist; + int quotef; + int oldstyle; + /* syntax stack */ + struct synstack synbase = {.syntax = syntax}; + struct synstack *synstack = &synbase; + if (syntax == DQSYNTAX) synstack->dblquote = 1; + quotef = 0; + bqlist = NULL; + STARTSTACKSTR(out); +loop : { /* for each line, until end of word */ + CHECKEND(); /* set c to PEOF if at end of here document */ + for (;;) { /* until end of line or end of word */ + CHECKSTRSPACE(4, out); /* permit 4 calls to USTPUTC */ + switch (synstack->syntax[c]) { + case CNL: /* '\n' */ + if (synstack->syntax == BASESYNTAX && !synstack->varnest) + goto endword; /* exit outer loop */ + USTPUTC(c, out); + nlprompt(); + c = pgetc_top(synstack); + goto loop; /* continue outer loop */ + case CWORD: + USTPUTC(c, out); + break; + case CCTL: + if ((!eofmark) | synstack->dblquote | synstack->varnest) USTPUTC(CTLESC, out); + USTPUTC(c, out); + break; + /* backslash */ + case CBACK: + c = pgetc2(); + if (c == PEOF) { + USTPUTC(CTLESC, out); + USTPUTC('\\', out); + pungetc(); + } else { + if (synstack->dblquote && c != '\\' && c != '`' && c != '$' && + (c != '"' || (eofmark != NULL && !synstack->varnest)) && + (c != '}' || !synstack->varnest)) { + USTPUTC(CTLESC, out); + USTPUTC('\\', out); + } + USTPUTC(CTLESC, out); + USTPUTC(c, out); + quotef++; + } + break; + case CSQUOTE: + synstack->syntax = SQSYNTAX; + quotemark: + if (eofmark == NULL) { + USTPUTC(CTLQUOTEMARK, out); + } + break; + case CDQUOTE: + synstack->syntax = DQSYNTAX; + synstack->dblquote = 1; + toggledq: + if (synstack->varnest) synstack->innerdq ^= 1; + goto quotemark; + case CENDQUOTE: + if (eofmark && !synstack->varnest) { + USTPUTC(c, out); + break; + } + if (synstack->dqvarnest == 0) { + synstack->syntax = BASESYNTAX; + synstack->dblquote = 0; + } + quotef++; + if (c == '"') goto toggledq; + goto quotemark; + case CVAR: /* '$' */ + PARSESUB(); /* parse substitution */ + break; + case CENDVAR: /* '}' */ + if (!synstack->innerdq && synstack->varnest > 0) { + if (!--synstack->varnest && synstack->varpushed) + synstack_pop(&synstack); + else if (synstack->dqvarnest > 0) + synstack->dqvarnest--; + USTPUTC(CTLENDVAR, out); + } else { + USTPUTC(c, out); + } + break; + case CLP: /* '(' in arithmetic */ + synstack->parenlevel++; + USTPUTC(c, out); + break; + case CRP: /* ')' in arithmetic */ + if (synstack->parenlevel > 0) { + USTPUTC(c, out); + --synstack->parenlevel; + } else { + if (pgetc_eatbnl() == ')') { + USTPUTC(CTLENDARI, out); + synstack_pop(&synstack); + } else { + /* + * unbalanced parens + * (don't 2nd guess - no error) + */ + pungetc(); + USTPUTC(')', out); + } + } + break; + case CBQUOTE: /* '`' */ + if (checkkwd & CHKEOFMARK) { + USTPUTC('`', out); + break; + } + PARSEBACKQOLD(); + break; + case CEOF: + goto endword; /* exit outer loop */ + case CIGN: + break; + default: + if (synstack->varnest == 0) goto endword; /* exit outer loop */ + if (c != PEOA) { + USTPUTC(c, out); + } + } + c = pgetc_top(synstack); + } +} +endword: + if (synstack->syntax == ARISYNTAX) synerror("Missing '))'"); + if (synstack->syntax != BASESYNTAX && eofmark == NULL) synerror("Unterminated quoted string"); + if (synstack->varnest != 0) { + /* { */ + synerror("Missing '}'"); + } + USTPUTC('\0', out); + len = out - (char *)stackblock(); + out = stackblock(); + if (eofmark == NULL) { + if ((c == '>' || c == '<') && quotef == 0 && len <= 2 && (*out == '\0' || is_digit(*out))) { + PARSEREDIR(); + return lasttoken = TREDIR; + } else { + pungetc(); + } + } + quoteflag = quotef; + backquotelist = bqlist; + grabstackblock(len); + wordtext = out; + return lasttoken = TWORD; + /* end of readtoken routine */ + + /* + * Check to see whether we are at the end of the here document. When this + * is called, c is set to the first character of the next input line. If + * we are at the end of the here document, this routine sets the c to PEOF. + */ +checkend : { + if (realeofmark(eofmark)) { + int markloc; + char *p; + if (c == PEOA) { + c = pgetc2(); + } + if (striptabs) { + while (c == '\t') { + c = pgetc2(); + } + } + markloc = out - (char *)stackblock(); + for (p = eofmark; STPUTC(c, out), *p; p++) { + if (c != *p) goto more_heredoc; + c = pgetc2(); + } + if (c == '\n' || c == PEOF) { + c = PEOF; + nlnoprompt(); + } else { + int len2; + more_heredoc: + p = (char *)stackblock() + markloc + 1; + len2 = out - p; + if (len2) { + len2 -= c < 0; + c = p[-1]; + if (len2) { + char *str; + str = alloca(len2 + 1); + *(char *)mempcpy(str, p, len2) = 0; + pushstring(str, NULL); + } + } + } + STADJUST((char *)stackblock() + markloc - out, out); + } + goto checkend_return; +} + + /* + * Parse a redirection operator. The variable "out" points to a string + * specifying the fd to be redirected. The variable "c" contains the + * first character of the redirection operator. + */ +parseredir : { + char fd = *out; + union node *np; + np = (union node *)stalloc(sizeof(struct nfile)); + if (c == '>') { + np->nfile.fd = 1; + c = pgetc_eatbnl(); + if (c == '>') + np->type = NAPPEND; + else if (c == '|') + np->type = NCLOBBER; + else if (c == '&') + np->type = NTOFD; + else { + np->type = NTO; + pungetc(); + } + } else { /* c == '<' */ + np->nfile.fd = 0; + switch (c = pgetc_eatbnl()) { + case '<': + if (sizeof(struct nfile) != sizeof(struct nhere)) { + np = (union node *)stalloc(sizeof(struct nhere)); + np->nfile.fd = 0; + } + np->type = NHERE; + heredoc = (struct heredoc *)stalloc(sizeof(struct heredoc)); + heredoc->here = np; + if ((c = pgetc_eatbnl()) == '-') { + heredoc->striptabs = 1; + } else { + heredoc->striptabs = 0; + pungetc(); + } + break; + case '&': + np->type = NFROMFD; + break; + case '>': + np->type = NFROMTO; + break; + default: + np->type = NFROM; + pungetc(); + break; + } + } + if (fd != '\0') np->nfile.fd = digit_val(fd); + redirnode = np; + goto parseredir_return; +} + + /* + * Parse a substitution. At this point, we have read the dollar sign + * and nothing else. + */ +parsesub : { + int subtype; + int typeloc; + char *p; + static const char types[] = "}-+?="; + c = pgetc_eatbnl(); + if ((checkkwd & CHKEOFMARK) || c <= PEOA || + (c != '(' && c != '{' && !is_name(c) && !is_special(c))) { + USTPUTC('$', out); + pungetc(); + } else if (c == '(') { /* $(command) or $((arith)) */ + if (pgetc_eatbnl() == '(') { + PARSEARITH(); + } else { + pungetc(); + PARSEBACKQNEW(); + } + } else { + const char *newsyn = synstack->syntax; + USTPUTC(CTLVAR, out); + typeloc = out - (char *)stackblock(); + STADJUST(1, out); + subtype = VSNORMAL; + if (likely(c == '{')) { + c = pgetc_eatbnl(); + subtype = 0; + } + varname: + if (is_name(c)) { + do { + STPUTC(c, out); + c = pgetc_eatbnl(); + } while (is_in_name(c)); + } else if (is_digit(c)) { + do { + STPUTC(c, out); + c = pgetc_eatbnl(); + } while (is_digit(c)); + } else if (c != '}') { + int cc = c; + c = pgetc_eatbnl(); + if (!subtype && cc == '#') { + subtype = VSLENGTH; + if (c == '_' || isalnum(c)) goto varname; + cc = c; + c = pgetc_eatbnl(); + if (cc == '}' || c != '}') { + pungetc(); + subtype = 0; + c = cc; + cc = '#'; + } + } + if (!is_special(cc)) { + if (subtype == VSLENGTH) subtype = 0; + goto badsub; + } + USTPUTC(cc, out); + } else + goto badsub; + if (subtype == 0) { + int cc = c; + switch (c) { + case ':': + subtype = VSNUL; + c = pgetc_eatbnl(); + /*FALLTHROUGH*/ + default: + p = strchr(types, c); + if (p == NULL) break; + subtype |= p - types + VSNORMAL; + break; + case '%': + case '#': + subtype = c == '#' ? VSTRIMLEFT : VSTRIMRIGHT; + c = pgetc_eatbnl(); + if (c == cc) + subtype++; + else + pungetc(); + newsyn = BASESYNTAX; + break; + } + } else { + badsub: + pungetc(); + } + if (newsyn == ARISYNTAX) newsyn = DQSYNTAX; + if ((newsyn != synstack->syntax || synstack->innerdq) && subtype != VSNORMAL) { + synstack_push(&synstack, synstack->prev ?: alloca(sizeof(*synstack)), newsyn); + synstack->varpushed++; + synstack->dblquote = newsyn != BASESYNTAX; + } + *((char *)stackblock() + typeloc) = subtype; + if (subtype != VSNORMAL) { + synstack->varnest++; + if (synstack->dblquote) synstack->dqvarnest++; + } + STPUTC('=', out); + } + goto parsesub_return; +} + + /* + * Called to parse command substitutions. Newstyle is set if the command + * is enclosed inside $(...); nlpp is a pointer to the head of the linked + * list of commands (passed by reference), and savelen is the number of + * characters on the top of the stack which must be preserved. + */ +parsebackq : { + struct nodelist **nlpp; + union node *n; + char *str; + unsigned savelen; + struct heredoc *saveheredoclist; + int uninitialized_var(saveprompt); + str = NULL; + savelen = out - (char *)stackblock(); + if (savelen > 0) { + str = alloca(savelen); + memcpy(str, stackblock(), savelen); + } + if (oldstyle) { + /* We must read until the closing backquote, giving special + treatment to some slashes, and then push the string and + reread it as input, interpreting it normally. */ + char *pout; + int pc; + unsigned psavelen; + char *pstr; + STARTSTACKSTR(pout); + for (;;) { + if (needprompt) { + setprompt(2); + } + switch (pc = pgetc_eatbnl()) { + case '`': + goto done; + case '\\': + pc = pgetc_eatbnl(); + if (pc != '\\' && pc != '`' && pc != '$' && (!synstack->dblquote || pc != '"')) + STPUTC('\\', pout); + if (pc > PEOA) { + break; + } + /* fall through */ + case PEOF: + case PEOA: + synerror("EOF in backquote substitution"); + case '\n': + nlnoprompt(); + break; + default: + break; + } + STPUTC(pc, pout); + } + done: + STPUTC('\0', pout); + psavelen = pout - (char *)stackblock(); + if (psavelen > 0) { + pstr = grabstackstr(pout); + setinputstring(pstr); + } + } + nlpp = &bqlist; + while (*nlpp) nlpp = &(*nlpp)->next; + *nlpp = (struct nodelist *)stalloc(sizeof(struct nodelist)); + (*nlpp)->next = NULL; + saveheredoclist = heredoclist; + heredoclist = NULL; + if (oldstyle) { + saveprompt = doprompt; + doprompt = 0; + } + n = list(2); + if (oldstyle) + doprompt = saveprompt; + else { + if (readtoken() != TRP) synexpect(TRP); + setinputstring(nullstr); + parseheredoc(); + } + heredoclist = saveheredoclist; + (*nlpp)->n = n; + /* Start reading from old file again. */ + popfile(); + /* Ignore any pushed back tokens left from the backquote parsing. */ + if (oldstyle) tokpushback = 0; + out = growstackto(savelen + 1); + if (str) { + memcpy(out, str, savelen); + STADJUST(savelen, out); + } + USTPUTC(CTLBACKQ, out); + if (oldstyle) + goto parsebackq_oldreturn; + else + goto parsebackq_newreturn; +} + +/* + * Parse an arithmetic expansion (indicate start of one and set state) + */ +parsearith : { + synstack_push(&synstack, synstack->prev ?: alloca(sizeof(*synstack)), ARISYNTAX); + synstack->dblquote = 1; + USTPUTC(CTLARI, out); + goto parsearith_return; +} + +} /* end of readtoken */ + +static void setprompt(int which) { + struct stackmark smark; + int show; + needprompt = 0; + whichprompt = which; + show = 1; + if (show) { + pushstackmark(&smark, stackblocksize()); + outstr(getprompt(NULL), out2); + popstackmark(&smark); + } +} + +static const char *expandstr(const char *ps) { + union node n; + int saveprompt; + /* XXX Fix (char *) cast. */ + setinputstring((char *)ps); + saveprompt = doprompt; + doprompt = 0; + readtoken1(pgetc_eatbnl(), DQSYNTAX, FAKEEOFMARK, 0); + doprompt = saveprompt; + popfile(); + n.narg.type = NARG; + n.narg.next = NULL; + n.narg.text = wordtext; + n.narg.backquote = backquotelist; + expandarg(&n, NULL, EXP_QUOTED); + return stackblock(); +} + +/* + * called by editline -- any expansions to the prompt + * should be added here. + */ +static const char *getprompt(void *unused) { + const char *prompt; + switch (whichprompt) { + default: + case 0: + return nullstr; + case 1: + prompt = ps1val(); + break; + case 2: + prompt = ps2val(); + break; + } + return expandstr(prompt); +} + +const char *const *findkwd(const char *s) { + return findstring(s, parsekwd, sizeof(parsekwd) / sizeof(const char *)); +} + +/* + * Process a list of redirection commands. If the REDIR_PUSH flag is set, + * old file descriptors are stashed away so that the redirection can be + * undone by calling popredir. If the REDIR_BACKQ flag is set, then the + * standard output, and the standard error if it becomes a duplicate of + * stdout, is saved in memory. + */ +static void redirect(union node *redir, int flags) { + union node *n; + struct redirtab *sv; + int i; + int fd; + int newfd; + int *p; + if (!redir) return; + sv = NULL; + INTOFF; + if (likely(flags & REDIR_PUSH)) sv = redirlist; + n = redir; + do { + newfd = openredirect(n); + if (newfd < -1) continue; + fd = n->nfile.fd; + if (sv) { + p = &sv->renamed[fd]; + i = *p; + if (likely(i == EMPTY)) { + i = CLOSED; + if (fd != newfd) { + i = savefd(fd, fd); + fd = -1; + } + } + if (i == newfd) /* Can only happen if i == newfd == CLOSED */ + i = REALLY_CLOSED; + *p = i; + } + if (fd == newfd) continue; + dupredirect(n, newfd); + } while ((n = n->nfile.next)); + INTON; + if (flags & REDIR_SAVEFD2 && sv->renamed[2] >= 0) preverrout.fd = sv->renamed[2]; +} + +static int openredirect(union node *redir) { + struct stat sb; + char *fname; + int f; + switch (redir->nfile.type) { + case NFROM: + fname = redir->nfile.expfname; + if ((f = open(fname, O_RDONLY, 0)) < 0) goto eopen; + break; + case NFROMTO: + fname = redir->nfile.expfname; + if ((f = open(fname, O_RDWR | O_CREAT, 0666)) < 0) goto ecreate; + break; + case NTO: + /* Take care of noclobber mode. */ + if (Cflag) { + fname = redir->nfile.expfname; + if (stat(fname, &sb) < 0) { + if ((f = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0666)) < 0) goto ecreate; + } else if (!S_ISREG(sb.st_mode)) { + if ((f = open(fname, O_WRONLY, 0666)) < 0) goto ecreate; + if (!fstat(f, &sb) && S_ISREG(sb.st_mode)) { + close(f); + errno = EEXIST; + goto ecreate; + } + } else { + errno = EEXIST; + goto ecreate; + } + break; + } + /* FALLTHROUGH */ + case NCLOBBER: + fname = redir->nfile.expfname; + if ((f = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) goto ecreate; + break; + case NAPPEND: + fname = redir->nfile.expfname; + if ((f = open(fname, O_WRONLY | O_CREAT | O_APPEND, 0666)) < 0) goto ecreate; + break; + case NTOFD: + case NFROMFD: + f = redir->ndup.dupfd; + if (f == redir->nfile.fd) f = -2; + break; + default: + /* Fall through to eliminate warning. */ + case NHERE: + case NXHERE: + f = openhere(redir); + break; + } + return f; +ecreate: + sh_error("cannot create %s: %s", fname, errmsg(errno, E_CREAT)); +eopen: + sh_error("cannot open %s: %s", fname, errmsg(errno, E_OPEN)); +} + +static void dupredirect(union node *redir, int f) { + int fd = redir->nfile.fd; + int err = 0; + if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) { + /* if not ">&-" */ + if (f >= 0) { + if (dup2(f, fd) < 0) { + err = errno; + goto err; + } + return; + } + f = fd; + } else if (dup2(f, fd) < 0) { + err = errno; + } + close(f); + if (err < 0) goto err; + return; +err: + sh_error("%ld: %s", f, strerror(err)); +} + +/* + * Handle here documents. Normally we fork off a process to write the + * data to a pipe. If the document is short, we can stuff the data in + * the pipe without forking. + */ +static int64_t openhere(union node *redir) { + char *p; + int pip[2]; + unsigned len = 0; + if (pipe(pip) < 0) sh_error("Pipe call failed"); + p = redir->nhere.doc->narg.text; + if (redir->type == NXHERE) { + expandarg(redir->nhere.doc, NULL, EXP_QUOTED); + p = stackblock(); + } + len = strlen(p); + if (len <= PIPESIZE) { + xwrite(pip[1], p, len); + goto out; + } + if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) { + close(pip[0]); + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + signal(SIGHUP, SIG_IGN); + signal(SIGPIPE, SIG_DFL); + xwrite(pip[1], p, len); + _exit(0); + } +out: + close(pip[1]); + return pip[0]; +} + +/* + * Undo the effects of the last redirection. + */ +static void popredir(int drop) { + struct redirtab *rp; + int i; + INTOFF; + rp = redirlist; + for (i = 0; i < 10; i++) { + switch (rp->renamed[i]) { + case CLOSED: + if (!drop) close(i); + break; + case EMPTY: + case REALLY_CLOSED: + break; + default: + if (!drop) dup2(rp->renamed[i], i); + close(rp->renamed[i]); + break; + } + } + redirlist = rp->next; + ckfree(rp); + INTON; +} + +/* + * Move a file descriptor to > 10. Invokes sh_error on error unless + * the original file dscriptor is not open. + */ +static int savefd(int from, int ofd) { + int newfd; + int err; + newfd = fcntl(from, F_DUPFD, 10); + err = newfd < 0 ? errno : 0; + if (err != EBADF) { + close(ofd); + if (err) { + sh_error("%d: %s", from, strerror(err)); + } else { + fcntl(newfd, F_SETFD, FD_CLOEXEC); + } + } + return newfd; +} + +static int redirectsafe(union node *redir, int flags) { + int err; + volatile int saveint; + struct jmploc *volatile savehandler = handler; + struct jmploc jmploc; + SAVEINT(saveint); + if (!(err = setjmp(jmploc.loc) * 2)) { + handler = &jmploc; + redirect(redir, flags); + } + handler = savehandler; + if (err && exception != EXERROR) longjmp(handler->loc, 1); + RESTOREINT(saveint); + return err; +} + +static void unwindredir(struct redirtab *stop) { + while (redirlist != stop) popredir(0); +} + +static struct redirtab *pushredir(union node *redir) { + struct redirtab *sv; + struct redirtab *q; + int i; + q = redirlist; + if (!redir) goto out; + sv = ckmalloc(sizeof(struct redirtab)); + sv->next = q; + redirlist = sv; + for (i = 0; i < 10; i++) sv->renamed[i] = EMPTY; +out: + return q; +} + +/* + * The trap builtin. + */ +static int trapcmd(int argc, char **argv) { + char *action; + char **ap; + int signo; + nextopt(nullstr); + ap = argptr; + if (!*ap) { + for (signo = 0; signo < NSIG; signo++) { + if (trap[signo] != NULL) { + out1fmt("trap -- %s %s\n", single_quote(trap[signo]), strsignal(signo)); + } + } + return 0; + } + if (!ap[1] || decode_signum(*ap) >= 0) + action = NULL; + else + action = *ap++; + while (*ap) { + if ((signo = decode_signal(*ap, 0)) < 0) { + outfmt(out2, "trap: %s: bad trap\n", *ap); + return 1; + } + INTOFF; + if (action) { + if (action[0] == '-' && action[1] == '\0') + action = NULL; + else { + if (*action) trapcnt++; + action = savestr(action); + } + } + if (trap[signo]) { + if (*trap[signo]) trapcnt--; + ckfree(trap[signo]); + } + trap[signo] = action; + if (signo != 0) setsignal(signo); + INTON; + ap++; + } + return 0; +} + +/* + * Clear traps on a fork. + */ +static void clear_traps(void) { + char **tp; + INTOFF; + for (tp = trap; tp < &trap[NSIG]; tp++) { + if (*tp && **tp) { /* trap not NULL or SIG_IGN */ + ckfree(*tp); + *tp = NULL; + if (tp != &trap[0]) setsignal(tp - trap); + } + } + trapcnt = 0; + INTON; +} + +/* + * Set the signal handler for the specified signal. The routine figures + * out what it should be set to. + */ +static void setsignal(int signo) { + int action; + int lvforked; + char *t, tsig; + struct sigaction act; + lvforked = vforked; + if ((t = trap[signo]) == NULL) + action = S_DFL; + else if (*t != '\0') + action = S_CATCH; + else + action = S_IGN; + if (rootshell && action == S_DFL && !lvforked) { + if (signo == SIGINT) { + if (iflag || minusc || sflag == 0) action = S_CATCH; + } else if (signo == SIGQUIT || signo == SIGTERM) { + if (iflag) action = S_IGN; + } else if (signo == SIGTSTP || signo == SIGTTOU) { + if (mflag) action = S_IGN; + } + } + if (signo == SIGCHLD) action = S_CATCH; + t = &sigmode[signo - 1]; + tsig = *t; + if (tsig == 0) { + /* + * current setting unknown + */ + if (sigaction(signo, 0, &act) == -1) { + /* + * Pretend it worked; maybe we should give a warning + * here, but other shells don't. We don't alter + * sigmode, so that we retry every time. + */ + return; + } + if (act.sa_handler == SIG_IGN) { + if (mflag && (signo == SIGTSTP || signo == SIGTTIN || signo == SIGTTOU)) { + tsig = S_IGN; /* don't hard ignore these */ + } else + tsig = S_HARD_IGN; + } else { + tsig = S_RESET; /* force to be set */ + } + } + if (tsig == S_HARD_IGN || tsig == action) return; + switch (action) { + case S_CATCH: + act.sa_handler = onsig; + break; + case S_IGN: + act.sa_handler = SIG_IGN; + break; + default: + act.sa_handler = SIG_DFL; + } + if (!lvforked) *t = action; + act.sa_flags = 0; + sigfillset(&act.sa_mask); + sigaction(signo, &act, 0); +} + +/* + * Ignore a signal. + */ +static void ignoresig(int signo) { + if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) { + signal(signo, SIG_IGN); + } + if (!vforked) sigmode[signo - 1] = S_HARD_IGN; +} + +/* + * Signal handler. + */ +static void onsig(int signo) { + if (vforked) return; + if (signo == SIGCHLD) { + gotsigchld = 1; + if (!trap[SIGCHLD]) return; + } + gotsig[signo - 1] = 1; + pending_sig = signo; + if (signo == SIGINT && !trap[SIGINT]) { + if (!suppressint) onint(); + intpending = 1; + } +} + +/* + * Called to execute a trap. Perhaps we should avoid entering new trap + * handlers while we are executing a trap handler. + */ +static void dotrap(void) { + char *p; + char *q; + int i; + int status, last_status; + if (!pending_sig) return; + status = savestatus; + last_status = status; + if (likely(status < 0)) { + status = exitstatus; + savestatus = status; + } + pending_sig = 0; + barrier(); + for (i = 0, q = gotsig; i < NSIG - 1; i++, q++) { + if (!*q) continue; + if (evalskip) { + pending_sig = i + 1; + break; + } + *q = 0; + p = trap[i + 1]; + if (!p) continue; + evalstring(p, 0); + if (evalskip != SKIPFUNC) exitstatus = status; + } + savestatus = last_status; +} + +/* + * Controls whether the shell is interactive or not. + */ +static void setinteractive(int on) { + static int is_interactive; + if (++on == is_interactive) return; + is_interactive = on; + setsignal(SIGINT); + setsignal(SIGQUIT); + setsignal(SIGTERM); +} + +/* + * Called to exit the shell. + */ +noreturn static void exitshell(void) { + struct jmploc loc; + char *p; + savestatus = exitstatus; + TRACE(("pid %d, exitshell(%d)\n", getpid(), savestatus)); + if (setjmp(loc.loc)) goto out; + handler = &loc; + if ((p = trap[0])) { + trap[0] = NULL; + evalskip = 0; + evalstring(p, 0); + } +out: + /* + * Disable job control so that whoever had the foreground before we + * started can get it back. + */ + if (likely(!setjmp(loc.loc))) setjobctl(0); + flushall(); + _exit(savestatus); +} + +static int decode_signal(const char *string, int minsig) { + int signo; + signo = decode_signum(string); + if (signo >= 0) return signo; + for (signo = minsig; signo < NSIG; signo++) { + if (!strcasecmp(string, strsignal(signo))) { + return signo; + } + } + return -1; +} + +static void sigblockall(sigset_t *oldmask) { + sigset_t mask; + sigfillset(&mask); + sigprocmask(SIG_SETMASK, &mask, oldmask); +} + +#define PF(f, func) \ + { \ + switch ((char *)param - (char *)array) { \ + default: \ + (void)printf(f, array[0], array[1], func); \ + break; \ + case sizeof(*param): \ + (void)printf(f, array[0], func); \ + break; \ + case 0: \ + (void)printf(f, func); \ + break; \ + } \ + } + +#define ASPF(sp, f, func) \ + ({ \ + int ret; \ + switch ((char *)param - (char *)array) { \ + default: \ + ret = xasprintf(sp, f, array[0], array[1], func); \ + break; \ + case sizeof(*param): \ + ret = xasprintf(sp, f, array[0], func); \ + break; \ + case 0: \ + ret = xasprintf(sp, f, func); \ + break; \ + } \ + ret; \ + }) + +static int print_escape_str(const char *f, int *param, int *array, char *s) { + struct stackmark smark; + char *p, *q; + int done; + int len; + int total; + setstackmark(&smark); + done = conv_escape_str(s, &q); + p = stackblock(); + len = q - p; + total = len - 1; + q[-1] = (!!((f[1] - 's') | done) - 1) & f[2]; + total += !!q[-1]; + if (f[1] == 's') goto easy; + p = makestrspace(len, q); + memset(p, 'X', total); + p[total] = 0; + q = stackblock(); + total = ASPF(&p, f, p); + len = strchrnul(p, 'X') - p; + memcpy(p + len, q, strspn(p + len, "X")); +easy: + outmem(p, total, out1); + popstackmark(&smark); + return done; +} + +static int printfcmd(int argc, char *argv[]) { + static const char kSkip1[] = "#-+ 0"; + static const char kSkip2[] = "*0123456789"; + char *fmt; + char *format; + int ch; + rval = 0; + nextopt(nullstr); + argv = argptr; + format = *argv; + if (!format) sh_error("usage: printf format [arg ...]"); + gargv = ++argv; + do { + /* + * Basic algorithm is to scan the format string for conversion + * specifications -- once one is found, find out if the field + * width or precision is a '*'; if it is, gather up value. + * Note, format strings are reused as necessary to use up the + * provided arguments, arguments of zero/null string are + * provided to use up the format string. + */ + /* find next format specification */ + for (fmt = format; (ch = *fmt++);) { + char *start; + char nextch; + int array[2]; + int *param; + if (ch == '\\') { + int c_ch; + fmt = conv_escape(fmt, &c_ch); + ch = c_ch; + goto pc; + } + if (ch != '%' || (*fmt == '%' && (++fmt || 1))) { + pc: + outc(ch, out1); + continue; + } + /* Ok - we've found a format specification, + Save its address for a later printf(). */ + start = fmt - 1; + param = array; + /* skip to field width */ + fmt += strspn(fmt, kSkip1); + if (*fmt == '*') { + ++fmt; + *param++ = getuintmax(1); + } else { + /* skip to possible '.', + * get following precision + */ + fmt += strspn(fmt, kSkip2); + } + if (*fmt == '.') { + ++fmt; + if (*fmt == '*') { + ++fmt; + *param++ = getuintmax(1); + } else + fmt += strspn(fmt, kSkip2); + } + ch = *fmt; + if (!ch) sh_error("missing format character"); + /* null terminate format string to we can use it + as an argument to printf. */ + nextch = fmt[1]; + fmt[1] = 0; + switch (ch) { + case 'b': + *fmt = 's'; + /* escape if a \c was encountered */ + if (print_escape_str(start, param, array, getstr())) goto out; + *fmt = 'b'; + break; + case 'c': { + int p = getchr(); + PF(start, p); + break; + } + case 's': { + char *p = getstr(); + PF(start, p); + break; + } + case 'd': + case 'i': { + uint64_t p = getuintmax(1); + start = mklong(start, fmt); + PF(start, p); + break; + } + case 'o': + case 'u': + case 'x': + case 'X': { + uint64_t p = getuintmax(0); + start = mklong(start, fmt); + PF(start, p); + break; + } + case 'a': + case 'A': + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': { + double p = getdouble(); + PF(start, p); + break; + } + default: + sh_error("%s: invalid directive", start); + } + *++fmt = nextch; + } + } while (gargv != argv && *gargv); +out: + return rval; +} + +/* + * Print SysV echo(1) style escape string + * Halts processing string if a \c escape is encountered. + */ +static int conv_escape_str(char *str, char **sp) { + int c; + int ch; + char *cp; + /* convert string into a temporary buffer... */ + STARTSTACKSTR(cp); + do { + c = ch = *str++; + if (ch != '\\') continue; + c = *str++; + if (c == 'c') { + /* \c as in SYSV echo - abort all processing.... */ + c = ch = 0x100; + continue; + } + /* + * %b string octal constants are not like those in C. + * They start with a \0, and are followed by 0, 1, 2, + * or 3 octal digits. + */ + if (c == '0' && isodigit(*str)) str++; + /* Finally test for sequences valid in the format string */ + str = conv_escape(str - 1, &c); + } while (STPUTC(c, cp), (char)ch); + *sp = cp; + return ch; +} + +/* + * Print "standard" escape characters + */ +static char *conv_escape(char *str, int *conv_ch) { + int value; + int ch; + ch = *str; + switch (ch) { + default: + if (!isodigit(*str)) { + value = '\\'; + goto out; + } + ch = 3; + value = 0; + do { + value <<= 3; + value += octtobin(*str++); + } while (isodigit(*str) && --ch); + goto out; + case '\\': + value = '\\'; + break; /* backslash */ + case 'a': + value = '\a'; + break; /* alert */ + case 'b': + value = '\b'; + break; /* backspace */ + case 'f': + value = '\f'; + break; /* form-feed */ + case 'n': + value = '\n'; + break; /* newline */ + case 'r': + value = '\r'; + break; /* carriage-return */ + case 't': + value = '\t'; + break; /* tab */ + case 'v': + value = '\v'; + break; /* vertical-tab */ + } + str++; +out: + *conv_ch = value; + return str; +} + +#define PRIdMAX "ld" + +static char *mklong(const char *str, const char *ch) { + /* + * Replace a string like "%92.3u" with "%92.3"PRIuMAX. + * + * Although C99 does not guarantee it, we assume PRIiMAX, + * PRIoMAX, PRIuMAX, PRIxMAX, and PRIXMAX are all the same + * as PRIdMAX with the final 'd' replaced by the corresponding + * character. + */ + char *copy; + unsigned len; + len = ch - str + sizeof(PRIdMAX); + STARTSTACKSTR(copy); + copy = makestrspace(len, copy); + memcpy(copy, str, len - sizeof(PRIdMAX)); + memcpy(copy + len - sizeof(PRIdMAX), PRIdMAX, sizeof(PRIdMAX)); + copy[len - 2] = *ch; + return (copy); +} + +static uint64_t getuintmax(int sign) { + uint64_t val = 0; + char *cp, *ep; + cp = *gargv; + if (cp == NULL) goto out; + gargv++; + val = (unsigned char)cp[1]; + if (*cp == '\"' || *cp == '\'') goto out; + errno = 0; + val = sign ? strtoimax(cp, &ep, 0) : strtoumax(cp, &ep, 0); + check_conversion(cp, ep); +out: + return val; +} + +static double getdouble(void) { + double val; + char *cp, *ep; + cp = *gargv; + if (cp == NULL) return 0; + gargv++; + if (*cp == '\"' || *cp == '\'') return (unsigned char)cp[1]; + errno = 0; + val = strtod(cp, &ep); + check_conversion(cp, ep); + return val; +} + +static void check_conversion(const char *s, const char *ep) { + if (*ep) { + if (ep == s) + sh_warnx("%s: expected numeric value", s); + else + sh_warnx("%s: not completely converted", s); + rval = 1; + } else if (errno == ERANGE) { + sh_warnx("%s: %s", s, strerror(ERANGE)); + rval = 1; + } +} + +static int echocmd(int argc, char **argv) { + const char *lastfmt = snlfmt; + int nonl; + if (*++argv && equal(*argv, "-n")) { + argv++; + lastfmt = "%s"; + } + do { + const char *fmt = "%s "; + char *s = *argv; + if (!s || !*++argv) fmt = lastfmt; + nonl = print_escape_str(fmt, NULL, NULL, s ?: nullstr); + } while (!nonl && *argv); + return 0; +} + +/* + * test(1); version 7-like -- author Erik Baalbergen + * modified by Eric Gisin to be used as built-in. + * modified by Arnold Robbins to add SVR3 compatibility + * (-x -c -b -p -u -g -k) plus Korn's -L -nt -ot -ef and new -S (socket). + * modified by J.T. Conklin for NetBSD. + * + * This program is in the Public Domain. + */ + +/* test(1) accepts the following grammar: + oexpr ::= aexpr | aexpr "-o" oexpr ; + aexpr ::= nexpr | nexpr "-a" aexpr ; + nexpr ::= primary | "!" primary + primary ::= unary-operator operand + | operand binary-operator operand + | operand + | "(" oexpr ")" + ; + unary-operator ::= "-r"|"-w"|"-x"|"-f"|"-d"|"-c"|"-b"|"-p"| + "-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-O"|"-G"|"-L"|"-S"; + binary-operator ::= "="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"| + "-nt"|"-ot"|"-ef"; + operand ::= +*/ + +static inline int faccessat_confused_about_superuser(void) { + return 0; +} + +static const struct t_op *getop(const char *s) { + const struct t_op *op; + for (op = ops; op->op_text; op++) { + if (strcmp(s, op->op_text) == 0) return op; + } + return NULL; +} + +static int testcmd(int argc, char **argv) { + const struct t_op *op; + enum token n; + int res = 1; + if (*argv[0] == '[') { + if (*argv[--argc] != ']') sh_error("missing ]"); + argv[argc] = NULL; + } + t_wp_op = NULL; +recheck: + argv++; + argc--; + if (argc < 1) return res; + /* + * POSIX prescriptions: he who wrote this deserves the Nobel + * peace prize. + */ + switch (argc) { + case 3: + op = getop(argv[1]); + if (op && op->op_type == BINOP) { + n = OPERAND; + goto eval; + } + /* fall through */ + case 4: + if (!strcmp(argv[0], "(") && !strcmp(argv[argc - 1], ")")) { + argv[--argc] = NULL; + argv++; + argc--; + } else if (!strcmp(argv[0], "!")) { + res = 0; + goto recheck; + } + } + n = t_lex(argv); +eval: + t_wp = argv; + res ^= oexpr(n); + argv = t_wp; + if (argv[0] != NULL && argv[1] != NULL) syntax(argv[0], "unexpected operator"); + return res; +} + +static void syntax(const char *op, const char *msg) { + if (op && *op) { + sh_error("%s: %s", op, msg); + } else { + sh_error("%s", msg); + } +} + +static int oexpr(enum token n) { + int res = 0; + for (;;) { + res |= aexpr(n); + n = t_lex(t_wp + 1); + if (n != BOR) break; + n = t_lex(t_wp += 2); + } + return res; +} + +static int aexpr(enum token n) { + int res = 1; + for (;;) { + if (!nexpr(n)) res = 0; + n = t_lex(t_wp + 1); + if (n != BAND) break; + n = t_lex(t_wp += 2); + } + return res; +} + +static int nexpr(enum token n) { + if (n != UNOT) return primary1(n); + n = t_lex(t_wp + 1); + if (n != EOI) t_wp++; + return !nexpr(n); +} + +static int primary1(enum token n) { + enum token nn; + int res; + if (n == EOI) return 0; /* missing expression */ + if (n == LPAREN) { + if ((nn = t_lex(++t_wp)) == RPAREN) return 0; /* missing expression */ + res = oexpr(nn); + if (t_lex(++t_wp) != RPAREN) syntax(NULL, "closing paren expected"); + return res; + } + if (t_wp_op && t_wp_op->op_type == UNOP) { + /* unary expression */ + if (*++t_wp == NULL) syntax(t_wp_op->op_text, "argument expected"); + switch (n) { + case STREZ: + return strlen(*t_wp) == 0; + case STRNZ: + return strlen(*t_wp) != 0; + case FILTT: + return isatty(getn(*t_wp)); + case FILRD: + return test_file_access(*t_wp, R_OK); + case FILWR: + return test_file_access(*t_wp, W_OK); + case FILEX: + return test_file_access(*t_wp, X_OK); + default: + return filstat(*t_wp, n); + } + } + if (t_lex(t_wp + 1), t_wp_op && t_wp_op->op_type == BINOP) { + return binop0(); + } + return strlen(*t_wp) > 0; +} + +static int binop0(void) { + const char *opnd1, *opnd2; + struct t_op const *op; + opnd1 = *t_wp; + (void)t_lex(++t_wp); + op = t_wp_op; + if ((opnd2 = *++t_wp) == (char *)0) syntax(op->op_text, "argument expected"); + switch (op->op_num) { + default: + case STREQ: + return strcmp(opnd1, opnd2) == 0; + case STRNE: + return strcmp(opnd1, opnd2) != 0; + case STRLT: + return strcmp(opnd1, opnd2) < 0; + case STRGT: + return strcmp(opnd1, opnd2) > 0; + case INTEQ: + return getn(opnd1) == getn(opnd2); + case INTNE: + return getn(opnd1) != getn(opnd2); + case INTGE: + return getn(opnd1) >= getn(opnd2); + case INTGT: + return getn(opnd1) > getn(opnd2); + case INTLE: + return getn(opnd1) <= getn(opnd2); + case INTLT: + return getn(opnd1) < getn(opnd2); + case FILNT: + return newerf(opnd1, opnd2); + case FILOT: + return olderf(opnd1, opnd2); + case FILEQ: + return equalf(opnd1, opnd2); + } +} + +static int filstat(char *nm, enum token mode) { + struct stat s; + if (mode == FILSYM ? lstat(nm, &s) : stat(nm, &s)) return 0; + switch (mode) { + case FILEXIST: + return 1; + case FILREG: + return S_ISREG(s.st_mode); + case FILDIR: + return S_ISDIR(s.st_mode); + case FILCDEV: + return S_ISCHR(s.st_mode); + case FILBDEV: + return S_ISBLK(s.st_mode); + case FILFIFO: + return S_ISFIFO(s.st_mode); + case FILSOCK: + return S_ISSOCK(s.st_mode); + case FILSYM: + return S_ISLNK(s.st_mode); + case FILSUID: + return (s.st_mode & S_ISUID) != 0; + case FILSGID: + return (s.st_mode & S_ISGID) != 0; + case FILSTCK: + return (s.st_mode & S_ISVTX) != 0; + case FILGZ: + return !!s.st_size; + case FILUID: + return s.st_uid == geteuid(); + case FILGID: + return s.st_gid == getegid(); + default: + return 1; + } +} + +static enum token t_lex(char **tp) { + struct t_op const *op; + char *s = *tp; + if (s == 0) { + t_wp_op = (struct t_op *)0; + return EOI; + } + op = getop(s); + if (op && !(op->op_type == UNOP && isoperand(tp)) && !(op->op_num == LPAREN && !tp[1])) { + t_wp_op = op; + return op->op_num; + } + t_wp_op = (struct t_op *)0; + return OPERAND; +} + +static int isoperand(char **tp) { + struct t_op const *op; + char *s; + if (!(s = tp[1])) return 1; + if (!tp[2]) return 0; + op = getop(s); + return op && op->op_type == BINOP; +} + +static int newerf(const char *f1, const char *f2) { + struct stat b1, b2; + return (stat(f1, &b1) == 0 && stat(f2, &b2) == 0 && + (b1.st_mtim.tv_sec > b2.st_mtim.tv_sec || + (b1.st_mtim.tv_sec == b2.st_mtim.tv_sec && (b1.st_mtim.tv_nsec > b2.st_mtim.tv_nsec)))); +} + +static int olderf(const char *f1, const char *f2) { + struct stat b1, b2; + return (stat(f1, &b1) == 0 && stat(f2, &b2) == 0 && + (b1.st_mtim.tv_sec < b2.st_mtim.tv_sec || + (b1.st_mtim.tv_sec == b2.st_mtim.tv_sec && (b1.st_mtim.tv_nsec < b2.st_mtim.tv_nsec)))); +} + +static int equalf(const char *f1, const char *f2) { + struct stat b1, b2; + return (stat(f1, &b1) == 0 && stat(f2, &b2) == 0 && b1.st_dev == b2.st_dev && + b1.st_ino == b2.st_ino); +} + +static int has_exec_bit_set(const char *path) { + struct stat st; + if (stat(path, &st)) return 0; + return st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH); +} + +static int test_file_access(const char *path, int mode) { + if (faccessat_confused_about_superuser() && mode == X_OK && geteuid() == 0 && + !has_exec_bit_set(path)) { + return 0; + } + return !faccessat(AT_FDCWD, path, mode, AT_EACCESS); +} + +static int timescmd() { + struct tms buf; + long int clk_tck = sysconf(_SC_CLK_TCK); + times(&buf); + printf("%dm%fs %dm%fs\n%dm%fs %dm%fs\n", (int)(buf.tms_utime / clk_tck / 60), + ((double)buf.tms_utime) / clk_tck, (int)(buf.tms_stime / clk_tck / 60), + ((double)buf.tms_stime) / clk_tck, (int)(buf.tms_cutime / clk_tck / 60), + ((double)buf.tms_cutime) / clk_tck, (int)(buf.tms_cstime / clk_tck / 60), + ((double)buf.tms_cstime) / clk_tck); + return 0; +} + +/* + * Find the appropriate entry in the hash table from the name. + */ +static struct Var **hashvar(const char *p) { + unsigned int hashval; + hashval = ((unsigned char)*p) << 4; + while (*p && *p != '=') hashval += (unsigned char)*p++; + return &vartab[hashval % VTABSIZE]; +} + +/* + * This routine initializes the builtin variables. It is called when the + * shell is initialized. + */ +static void initvar(void) { + struct Var *vp; + struct Var *end; + struct Var **vpp; + vp = varinit; + end = vp + sizeof(varinit) / sizeof(varinit[0]); + do { + vpp = hashvar(vp->text); + vp->next = *vpp; + *vpp = vp; + } while (++vp < end); + /* + * PS1 depends on uid + */ + if (!geteuid()) vps1.text = "PS1=# "; +} + +/* + * Set the value of a variable. The flags argument is ored with the + * flags of the variable. If val is NULL, the variable is unset. + */ +static struct Var *setvar(const char *name, const char *val, int flags) { + char *p, *q; + unsigned namelen; + char *nameeq; + unsigned vallen; + struct Var *vp; + q = endofname(name); + p = strchrnul(q, '='); + namelen = p - name; + if (!namelen || p != q) sh_error("%.*s: bad variable name", namelen, name); + vallen = 0; + if (val == NULL) { + flags |= VUNSET; + } else { + vallen = strlen(val); + } + INTOFF; + p = mempcpy(nameeq = ckmalloc(namelen + vallen + 2), name, namelen); + if (val) { + *p++ = '='; + p = mempcpy(p, val, vallen); + } + *p = '\0'; + vp = setvareq(nameeq, flags | VNOSAVE); + INTON; + return vp; +} + +/* + * Set the given integer as the value of a variable. The flags argument is + * ored with the flags of the variable. + */ +static int64_t setvarint(const char *name, int64_t val, int flags) { + int len = max_int_length(sizeof(val)); + char buf[len]; + fmtstr(buf, len, "%ld", val); + setvar(name, buf, flags); + return val; +} + +static struct Var **findvar(struct Var **vpp, const char *name) { + for (; *vpp; vpp = &(*vpp)->next) { + if (varequal((*vpp)->text, name)) { + break; + } + } + return vpp; +} + +/* + * Same as setvar except that the variable and value are passed in + * the first argument as name=value. Since the first argument will + * be actually stored in the table, it should not be a string that + * will go away. + * Called with interrupts off. + */ +static struct Var *setvareq(char *s, int flags) { + struct Var *vp, **vpp; + vpp = hashvar(s); + flags |= (VEXPORT & (((unsigned)(1 - aflag)) - 1)); + vpp = findvar(vpp, s); + vp = *vpp; + if (vp) { + if (vp->flags & VREADONLY) { + const char *n; + if (flags & VNOSAVE) free(s); + n = vp->text; + sh_error("%.*s: is read only", strchrnul(n, '=') - n, n); + } + if (flags & VNOSET) goto out; + if (vp->func && (flags & VNOFUNC) == 0) (*vp->func)(strchrnul(s, '=') + 1); + if ((vp->flags & (VTEXTFIXED | VSTACK)) == 0) ckfree(vp->text); + if (((flags & (VEXPORT | VREADONLY | VSTRFIXED | VUNSET)) | (vp->flags & VSTRFIXED)) == + VUNSET) { + *vpp = vp->next; + ckfree(vp); + out_free: + if ((flags & (VTEXTFIXED | VSTACK | VNOSAVE)) == VNOSAVE) ckfree(s); + goto out; + } + flags |= vp->flags & ~(VTEXTFIXED | VSTACK | VNOSAVE | VUNSET); + } else { + if (flags & VNOSET) goto out; + if ((flags & (VEXPORT | VREADONLY | VSTRFIXED | VUNSET)) == VUNSET) goto out_free; + /* not found */ + vp = ckmalloc(sizeof(*vp)); + vp->next = *vpp; + vp->func = NULL; + *vpp = vp; + } + if (!(flags & (VTEXTFIXED | VSTACK | VNOSAVE))) s = savestr(s); + vp->text = s; + vp->flags = flags; +out: + return vp; +} + +/* + * Find the value of a variable. Returns NULL if not set. + */ +static char *lookupvar(const char *name) { + struct Var *v; + if ((v = *findvar(hashvar(name), name)) && !(v->flags & VUNSET)) { + if (v == &vlineno && v->text == linenovar) { + fmtstr(linenovar + 7, sizeof(linenovar) - 7, "%d", lineno); + } + return strchrnul(v->text, '=') + 1; + } + return NULL; +} + +static int64_t lookupvarint(const char *name) { + return atomax(lookupvar(name) ?: nullstr, 0); +} + +/* + * Generate a list of variables satisfying the given conditions. + */ +static char **listvars(int on, int off, char ***end) { + struct Var **vpp; + struct Var *vp; + char **ep; + int mask; + STARTSTACKSTR(ep); + vpp = vartab; + mask = on | off; + do { + for (vp = *vpp; vp; vp = vp->next) + if ((vp->flags & mask) == on) { + if (ep == stackstrend()) ep = growstackstr(); + *ep++ = (char *)vp->text; + } + } while (++vpp < vartab + VTABSIZE); + if (ep == stackstrend()) ep = growstackstr(); + if (end) *end = ep; + *ep++ = NULL; + return grabstackstr(ep); +} + +static int vpcmp(const void *a, const void *b) { + return varcmp(*(const char **)a, *(const char **)b); +} + +/* + * POSIX requires that 'set' (but not export or readonly) output the + * variables in lexicographic order - by the locale's collating order (sigh). + * Maybe we could keep them in an ordered balanced binary tree + * instead of hashed lists. + * For now just roll 'em through qsort for printing... + */ +static int showvars(const char *prefix, int on, int off) { + const char *sep; + char **ep, **epend; + ep = listvars(on, off, &epend); + qsort(ep, epend - ep, sizeof(char *), vpcmp); + sep = *prefix ? spcstr : prefix; + for (; ep < epend; ep++) { + const char *p; + const char *q; + p = strchrnul(*ep, '='); + q = nullstr; + if (*p) q = single_quote(++p); + out1fmt("%s%s%.*s%s\n", prefix, sep, (int)(p - *ep), *ep, q); + } + return 0; +} + +/* + * The export and readonly commands. + */ +static int exportcmd(int argc, char **argv) { + struct Var *vp; + char *name; + const char *p; + char **aptr; + int flag = argv[0][0] == 'r' ? VREADONLY : VEXPORT; + int notp; + notp = nextopt("p") - 'p'; + if (notp && ((name = *(aptr = argptr)))) { + do { + if ((p = strchr(name, '=')) != NULL) { + p++; + } else { + if ((vp = *findvar(hashvar(name), name))) { + vp->flags |= flag; + continue; + } + } + setvar(name, p, flag); + } while ((name = *++aptr) != NULL); + } else { + showvars(argv[0], flag, 0); + } + return 0; +} + +/* + * The "local" command. + */ +static int localcmd(int argc, char **argv) { + char *name; + if (!localvar_stack) sh_error("not in a function"); + argv = argptr; + while ((name = *argv++) != NULL) { + mklocal(name, 0); + } + return 0; +} + +/* + * Make a variable a local variable. When a variable is made local, it's + * value and flags are saved in a localvar structure. The saved values + * will be restored when the shell function returns. We handle the name + * "-" as a special case. + */ +static void mklocal(char *name, int flags) { + struct localvar *lvp; + struct Var **vpp; + struct Var *vp; + INTOFF; + lvp = ckmalloc(sizeof(struct localvar)); + if (name[0] == '-' && name[1] == '\0') { + char *p; + p = ckmalloc(sizeof(optlist)); + lvp->text = memcpy(p, optlist, sizeof(optlist)); + vp = NULL; + } else { + char *eq; + vpp = hashvar(name); + vp = *findvar(vpp, name); + eq = strchr(name, '='); + if (vp == NULL) { + if (eq) + vp = setvareq(name, VSTRFIXED | flags); + else + vp = setvar(name, NULL, VSTRFIXED | flags); + lvp->flags = VUNSET; + } else { + lvp->text = vp->text; + lvp->flags = vp->flags; + vp->flags |= VSTRFIXED | VTEXTFIXED; + if (eq) setvareq(name, flags); + } + } + lvp->vp = vp; + lvp->next = localvar_stack->lv; + localvar_stack->lv = lvp; + INTON; +} + +/* + * Called after a function returns. + * Interrupts must be off. + */ +static void poplocalvars(int keep) { + struct localvar_list *ll; + struct localvar *lvp, *next; + struct Var *vp; + INTOFF; + ll = localvar_stack; + localvar_stack = ll->next; + next = ll->lv; + ckfree(ll); + while ((lvp = next) != NULL) { + next = lvp->next; + vp = lvp->vp; + TRACE(("poplocalvar %s\n", vp ? vp->text : "-")); + if (keep) { + int bits = VSTRFIXED; + if (lvp->flags != VUNSET) { + if (vp->text == lvp->text) + bits |= VTEXTFIXED; + else if (!(lvp->flags & (VTEXTFIXED | VSTACK))) + ckfree(lvp->text); + } + vp->flags &= ~bits; + vp->flags |= (lvp->flags & bits); + if ((vp->flags & (VEXPORT | VREADONLY | VSTRFIXED | VUNSET)) == VUNSET) unsetvar(vp->text); + } else if (vp == NULL) { /* $- saved */ + memcpy(optlist, lvp->text, sizeof(optlist)); + ckfree(lvp->text); + optschanged(); + } else if (lvp->flags == VUNSET) { + vp->flags &= ~(VSTRFIXED | VREADONLY); + unsetvar(vp->text); + } else { + if (vp->func) (*vp->func)(strchrnul(lvp->text, '=') + 1); + if ((vp->flags & (VTEXTFIXED | VSTACK)) == 0) ckfree(vp->text); + vp->flags = lvp->flags; + vp->text = lvp->text; + } + ckfree(lvp); + } + INTON; +} + +/* + * Create a new localvar environment. + */ +static struct localvar_list *pushlocalvars(int push) { + struct localvar_list *ll; + struct localvar_list *top; + top = localvar_stack; + if (!push) goto out; + INTOFF; + ll = ckmalloc(sizeof(*ll)); + ll->lv = NULL; + ll->next = top; + localvar_stack = ll; + INTON; +out: + return top; +} + +static void unwindlocalvars(struct localvar_list *stop) { + while (localvar_stack != stop) poplocalvars(0); +} + +/* + * The unset builtin command. We unset the function before we unset the + * variable to allow a function to be unset when there is a readonly variable + * with the same name. + */ +static int unsetcmd(int argc, char **argv) { + char **ap; + int i; + int flag = 0; + while ((i = nextopt("vf")) != '\0') { + flag = i; + } + for (ap = argptr; *ap; ap++) { + if (flag != 'f') { + unsetvar(*ap); + continue; + } + if (flag != 'v') unsetfunc(*ap); + } + return 0; +} + +static void unsetvar(const char *s) { + setvar(s, 0, 0); +} + +/* + * Initialization code. + */ +static void init() { + /* from input.c: */ + { + basepf.nextc = basepf.buf = basebuf; + basepf.linno = 1; + } + /* from trap.c: */ + { + sigmode[SIGCHLD - 1] = S_DFL; + setsignal(SIGCHLD); + } + /* from output.c: */ + {} /* from var.c: */ + { + char **envp; + static char ppid[32] = "PPID="; + const char *p; + struct stat st1, st2; + initvar(); + for (envp = environ; *envp; envp++) { + p = endofname(*envp); + if (p != *envp && *p == '=') { + setvareq(*envp, VEXPORT | VTEXTFIXED); + } + } + setvareq(defifsvar, VTEXTFIXED); + setvareq(defoptindvar, VTEXTFIXED); + fmtstr(ppid + 5, sizeof(ppid) - 5, "%ld", (long)getppid()); + setvareq(ppid, VTEXTFIXED); + p = lookupvar("PWD"); + if (p) { + if (*p != '/' || stat(p, &st1) || stat(".", &st2) || st1.st_dev != st2.st_dev || + st1.st_ino != st2.st_ino) { + p = 0; + } + } + setpwd(p, 0); + } +} + +/* + * This routine is called when an error or an interrupt occurs in an + * interactive shell and control is returned to the main command loop + * but prior to exitshell. + */ +static void exitreset() { + /* from eval.c: */ + { + evalskip = 0; + loopnest = 0; + if (savestatus >= 0) { + exitstatus = savestatus; + savestatus = -1; + } + } + /* from expand.c: */ + { ifsfree(); } + /* from redir.c: */ + { + /* + * Discard all saved file descriptors. + */ + unwindredir(0); + } +} + +/* + * This routine is called when an error or an interrupt occurs in an + * interactive shell and control is returned to the main command loop. + */ +static void reset() { + /* from input.c: */ + { + /* clear input buffer */ + basepf.lleft = basepf.nleft = 0; + popallfiles(); + } + /* from output.c: */ + {} /* from var.c: */ + { + unwindlocalvars(0); + } +} + +static void calcsize(union node *n) { + if (n == NULL) return; + funcblocksize += nodesize[n->type]; + switch (n->type) { + case NCMD: + calcsize(n->ncmd.redirect); + calcsize(n->ncmd.args); + calcsize(n->ncmd.assign); + break; + case NPIPE: + sizenodelist(n->npipe.cmdlist); + break; + case NREDIR: + case NBACKGND: + case NSUBSHELL: + calcsize(n->nredir.redirect); + calcsize(n->nredir.n); + break; + case NAND: + case NOR: + case NSEMI: + case NWHILE: + case NUNTIL: + calcsize(n->nbinary.ch2); + calcsize(n->nbinary.ch1); + break; + case NIF: + calcsize(n->nif.elsepart); + calcsize(n->nif.ifpart); + calcsize(n->nif.test); + break; + case NFOR: + funcstringsize += strlen(n->nfor.var_) + 1; + calcsize(n->nfor.body); + calcsize(n->nfor.args); + break; + case NCASE: + calcsize(n->ncase.cases); + calcsize(n->ncase.expr); + break; + case NCLIST: + calcsize(n->nclist.body); + calcsize(n->nclist.pattern); + calcsize(n->nclist.next); + break; + case NDEFUN: + calcsize(n->ndefun.body); + funcstringsize += strlen(n->ndefun.text) + 1; + break; + case NARG: + sizenodelist(n->narg.backquote); + funcstringsize += strlen(n->narg.text) + 1; + calcsize(n->narg.next); + break; + case NTO: + case NCLOBBER: + case NFROM: + case NFROMTO: + case NAPPEND: + calcsize(n->nfile.fname); + calcsize(n->nfile.next); + break; + case NTOFD: + case NFROMFD: + calcsize(n->ndup.vname); + calcsize(n->ndup.next); + break; + case NHERE: + case NXHERE: + calcsize(n->nhere.doc); + calcsize(n->nhere.next); + break; + case NNOT: + calcsize(n->nnot.com); + break; + }; +} + +/* + * Make a copy of a parse tree. + */ +static struct funcnode *copyfunc(union node *n) { + struct funcnode *f; + unsigned blocksize; + funcblocksize = offsetof(struct funcnode, n); + funcstringsize = 0; + calcsize(n); + blocksize = funcblocksize; + f = ckmalloc(blocksize + funcstringsize); + funcblock = (char *)f + offsetof(struct funcnode, n); + funcstring = (char *)f + blocksize; + copynode(n); + f->count = 0; + return f; +} + +static void sizenodelist(struct nodelist *lp) { + while (lp) { + funcblocksize += SHELL_ALIGN(sizeof(struct nodelist)); + calcsize(lp->n); + lp = lp->next; + } +} + +static union node *copynode(union node *n) { + union node *new; + if (n == NULL) return NULL; + new = funcblock; + funcblock = (char *)funcblock + nodesize[n->type]; + switch (n->type) { + case NCMD: + new->ncmd.redirect = copynode(n->ncmd.redirect); + new->ncmd.args = copynode(n->ncmd.args); + new->ncmd.assign = copynode(n->ncmd.assign); + new->ncmd.linno = n->ncmd.linno; + break; + case NPIPE: + new->npipe.cmdlist = copynodelist(n->npipe.cmdlist); + new->npipe.backgnd = n->npipe.backgnd; + break; + case NREDIR: + case NBACKGND: + case NSUBSHELL: + new->nredir.redirect = copynode(n->nredir.redirect); + new->nredir.n = copynode(n->nredir.n); + new->nredir.linno = n->nredir.linno; + break; + case NAND: + case NOR: + case NSEMI: + case NWHILE: + case NUNTIL: + new->nbinary.ch2 = copynode(n->nbinary.ch2); + new->nbinary.ch1 = copynode(n->nbinary.ch1); + break; + case NIF: + new->nif.elsepart = copynode(n->nif.elsepart); + new->nif.ifpart = copynode(n->nif.ifpart); + new->nif.test = copynode(n->nif.test); + break; + case NFOR: + new->nfor.var_ = nodesavestr(n->nfor.var_); + new->nfor.body = copynode(n->nfor.body); + new->nfor.args = copynode(n->nfor.args); + new->nfor.linno = n->nfor.linno; + break; + case NCASE: + new->ncase.cases = copynode(n->ncase.cases); + new->ncase.expr = copynode(n->ncase.expr); + new->ncase.linno = n->ncase.linno; + break; + case NCLIST: + new->nclist.body = copynode(n->nclist.body); + new->nclist.pattern = copynode(n->nclist.pattern); + new->nclist.next = copynode(n->nclist.next); + break; + case NDEFUN: + new->ndefun.body = copynode(n->ndefun.body); + new->ndefun.text = nodesavestr(n->ndefun.text); + new->ndefun.linno = n->ndefun.linno; + break; + case NARG: + new->narg.backquote = copynodelist(n->narg.backquote); + new->narg.text = nodesavestr(n->narg.text); + new->narg.next = copynode(n->narg.next); + break; + case NTO: + case NCLOBBER: + case NFROM: + case NFROMTO: + case NAPPEND: + new->nfile.fname = copynode(n->nfile.fname); + new->nfile.fd = n->nfile.fd; + new->nfile.next = copynode(n->nfile.next); + break; + case NTOFD: + case NFROMFD: + new->ndup.vname = copynode(n->ndup.vname); + new->ndup.dupfd = n->ndup.dupfd; + new->ndup.fd = n->ndup.fd; + new->ndup.next = copynode(n->ndup.next); + break; + case NHERE: + case NXHERE: + new->nhere.doc = copynode(n->nhere.doc); + new->nhere.fd = n->nhere.fd; + new->nhere.next = copynode(n->nhere.next); + break; + case NNOT: + new->nnot.com = copynode(n->nnot.com); + break; + }; + new->type = n->type; + return new; +} + +static struct nodelist *copynodelist(struct nodelist *lp) { + struct nodelist *start; + struct nodelist **lpp; + lpp = &start; + while (lp) { + *lpp = funcblock; + funcblock = (char *)funcblock + SHELL_ALIGN(sizeof(struct nodelist)); + (*lpp)->n = copynode(lp->n); + lp = lp->next; + lpp = &(*lpp)->next; + } + *lpp = NULL; + return start; +} + +/* + * Read and execute commands. "Top" is nonzero for the top level command + * loop; it turns on prompting if the shell is interactive. + */ +static int cmdloop(int top) { + union node *n; + struct stackmark smark; + int inter; + int status = 0; + int numeof = 0; + TRACE(("cmdloop(%d) called\n", top)); + for (;;) { + int skip; + setstackmark(&smark); + if (jobctl) showjobs(out2, SHOW_CHANGED); + inter = 0; + if (iflag && top) { + inter++; + /* chkmail(); */ + } + n = parsecmd(inter); + /* showtree(n); DEBUG */ + if (n == NEOF) { + if (!top || numeof >= 50) break; + if (!stoppedjobs()) { + if (!Iflag) break; + outstr("\nUse \"exit\" to leave shell.\n", out2); + } + numeof++; + } else if (nflag == 0) { + int i; + job_warning = (job_warning == 2) ? 1 : 0; + numeof = 0; + i = evaltree(n, 0); + if (n) status = i; + } + popstackmark(&smark); + skip = evalskip; + if (skip) { + evalskip &= ~(SKIPFUNC | SKIPFUNCDEF); + break; + } + } + return status; +} + +/* + * Read /etc/profile or .profile. Return on error. + */ +static void read_profile(const char *name) { + name = expandstr(name); + if (setinputfile(name, INPUT_PUSH_FILE | INPUT_NOFILE_OK) < 0) return; + cmdloop(0); + popfile(); +} + +/* + * Take commands from a file. To be compatible we should do a path + * search for the file, which is necessary to find sub-commands. + */ +static char *find_dot_file(char *basename) { + char *fullname; + const char *path = pathval(); + struct stat statb; + int len; + /* don't try this for absolute or relative paths */ + if (strchr(basename, '/')) return basename; + while ((len = padvance(&path, basename)) >= 0) { + fullname = stackblock(); + if ((!pathopt || *pathopt == 'f') && !stat(fullname, &statb) && S_ISREG(statb.st_mode)) { + /* This will be freed by the caller. */ + return stalloc(len); + } + } + /* not found in the PATH */ + sh_error("%s: not found", basename); +} + +static int dotcmd(int argc, char **argv) { + int status = 0; + nextopt(nullstr); + argv = argptr; + if (*argv) { + char *fullname; + fullname = find_dot_file(*argv); + setinputfile(fullname, INPUT_PUSH_FILE); + commandname = fullname; + status = cmdloop(0); + popfile(); + } + return status; +} + +static int exitcmd(int argc, char **argv) { + if (stoppedjobs()) return 0; + if (argc > 1) savestatus = number(argv[1]); + exraise(EXEXIT); +} + +/* + * Main routine. We initialize things, parse the arguments, execute + * profiles if we're a login shell, and then call cmdloop to execute + * commands. The setjmp call sets up the location to jump to when an + * exception occurs. When an exception occurs the variable "state" + * is used to figure out how far we had gotten. + */ +int main(int argc, char **argv) { + showcrashreports(); + char *shinit; + volatile int state; + struct jmploc jmploc; + struct stackmark smark; + int login; + state = 0; + if (unlikely(setjmp(jmploc.loc))) { + int e; + int s; + exitreset(); + e = exception; + s = state; + if (e == EXEXIT || s == 0 || iflag == 0 || shlvl) exitshell(); + reset(); + if (e == EXINT) { + outcslow('\n', out2); + } + popstackmark(&smark); + FORCEINTON; /* enable interrupts */ + if (s == 1) { + goto state1; + } else if (s == 2) { + goto state2; + } else if (s == 3) { + goto state3; + } else { + goto state4; + } + } + handler = &jmploc; + rootpid = getpid(); + init(); + setstackmark(&smark); + login = procargs(argc, argv); + if (login) { + state = 1; + read_profile("/etc/profile"); + state1: + state = 2; + read_profile("$HOME/.profile"); + } +state2: + state = 3; + if (iflag) { + if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') { + read_profile(shinit); + } + } + popstackmark(&smark); +state3: + state = 4; + if (minusc) evalstring(minusc, sflag ? 0 : EV_EXIT); + if (sflag || minusc == NULL) { + state4: /* XXX ??? - why isn't this before the "if" statement */ + cmdloop(1); + } + exitshell(); +} diff --git a/examples/x86split.c b/examples/x86split.c new file mode 100644 index 00000000..22122abd --- /dev/null +++ b/examples/x86split.c @@ -0,0 +1,53 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/errno.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "third_party/xed/x86.h" + +/** + * @fileoverview x86 instruction length decoder by way of hex pipe. + */ + +int main(int argc, char *argv[argc]) { + unsigned c, i, j, l; + enum XedError err; + struct XedDecodedInst xedd; + unsigned char buf[XED_MAX_INSTRUCTION_BYTES]; + memset(buf, 0, sizeof(buf)); + for (i = 0;;) { + if (i < XED_MAX_INSTRUCTION_BYTES) { + c = fgethex(stdin); + if (c != -1) { + buf[i++] = c; + continue; + } else if (i == 0) { + break; + } + } + if ((err = xed_instruction_length_decode( + xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64), + buf, i))) { + errno = err; + break; + } + l = xedd.decoded_length; + if (l <= 0 || l > i) abort(); + for (j = 0; j < l; ++j) { + if (fputhex(buf[j], stdout) == -1) { + return errno; + } + } + putchar('\n'); + memcpy(&buf[0], &buf[l], i -= l); + } + return errno; +} diff --git a/libc/README.md b/libc/README.md new file mode 100644 index 00000000..6fc8dd36 --- /dev/null +++ b/libc/README.md @@ -0,0 +1,54 @@ +SYNOPSIS + + Cosmopolitan Standard Library. + +OVERVIEW + + This directory defines static archives defining functions, like + printf(), mmap(), win32, etc. Please note that the Cosmopolitan + build configuration doesn't link any C/C++ library dependencies + by default, so you still have the flexibility to choose the one + provided by your system. If you'd prefer Cosmopolitan, just add + $(LIBC) and $(CRT) to your linker arguments. + + Your library is compromised of many bite-sized static archives. + We use the checkdeps tool to guarantee that the contents of the + archives are organized in a logical way that's easy to use with + or without our makefile infrastructure, since there's no cyclic + dependencies. + + The Cosmopolitan Library exports only the most stable canonical + system calls for all supported operating systems, regardless of + which platform is used for compilation. We polyfill many of the + APIs, e.g. read(), write() so they work consistently everywhere + while other apis, e.g. CreateWindowEx(), might only work on one + platform, in which case they become no-op functions on others. + + Cosmopolitan polyfill wrappers will usually use the dollar sign + naming convention, so they may be bypassed when necessary. This + same convention is used when multiple implementations of string + library and other performance-critical function are provided to + allow Cosmopolitan to go fast on both old and newer computers. + + We take an approach to configuration that relies heavily on the + compiler's dead code elimination pass (libc/dce.h). Most of the + code is written so that, for example, folks not wanting support + for OpenBSD can flip a bit in SUPPORT_VECTOR and that code will + be omitted from the build. The same is true for builds that are + tuned using -march=native which effectively asks the library to + not include runtime support hooks for x86 processors older than + what you use. + + Please note that, unlike Cygwin or MinGW, Cosmopolitan does not + achieve broad support by bolting on a POSIX emulation layer. We + do nothing more than (in most cases) stateless API translations + that get you 90% of the way there in a fast lightweight manner. + We therefore can't address some of the subtle differences, such + as the nuances of absolute paths on Windows. Our approach could + be compared to something more along the lines of, "the Russians + just used a pencil to write in space", versus spending millions + researching a pen like NASA. + + One cost worth noting, concerning stateless API translation, is + file descriptors needed to change from `int` to `int64_t`, thus + requiring a certain degree of added care when porting software. diff --git a/libc/alg/alg.h b/libc/alg/alg.h new file mode 100644 index 00000000..dea4dff4 --- /dev/null +++ b/libc/alg/alg.h @@ -0,0 +1,119 @@ +#ifndef COSMOPOLITAN_LIBC_ALG_ALG_H_ +#define COSMOPOLITAN_LIBC_ALG_ALG_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § algorithms ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +void *bsearch(const void *, const void *, size_t, size_t, + int cmp(const void *, const void *)) + paramsnonnull() nothrow nosideeffect; +void *bsearch_r(const void *, const void *, size_t, size_t, + int cmp(const void *, const void *, void *), void *) + paramsnonnull((1, 2, 5)) nothrow nosideeffect; +void djbsort(size_t n, int32_t[n]); +void qsort(void *items, size_t itemcount, size_t itemsize, + int cmp(const void *, const void *)) paramsnonnull(); +void qsort_r(void *items, size_t itemcount, size_t itemsize, + int cmp(const void *, const void *, void *), void *arg) + paramsnonnull((1, 4)); +int tarjan(uint32_t vertex_count, const uint32_t (*edges)[2], + uint32_t edge_count, uint32_t out_sorted[], + uint32_t out_opt_components[], uint32_t *out_opt_componentcount) + paramsnonnull((2, 4)) nocallback nothrow; +void heapsortcar(int32_t (*A)[2], unsigned n) + paramsnonnull() nocallback nothrow; + +void *memmem(const void *, size_t, const void *, size_t) + paramsnonnull() nothrow nocallback nosideeffect; +void *memmem16(const void *, size_t, const void *, size_t) + paramsnonnull() nothrow nocallback nosideeffect; +void *wmemmem(const void *, size_t, const void *, size_t) + paramsnonnull() nothrow nocallback nosideeffect; + +#define __algalloc returnspointerwithnoaliases nothrow nocallback nodiscard + +char *replacestr(const char *, const char *, const char *) + paramsnonnull() __algalloc; +char16_t *replacestr16(const char16_t *, const char16_t *, const char16_t *) + paramsnonnull() __algalloc; +wchar_t *replacewcs(const wchar_t *, const wchar_t *, const wchar_t *) + paramsnonnull() __algalloc; + +char *concatstr(const char *, ...) nullterminated() paramsnonnull() __algalloc; +char16_t *concatstr16(const char16_t *, ...) nullterminated() + paramsnonnull() __algalloc; +wchar_t *concatwcs(const wchar_t *, ...) nullterminated() + paramsnonnull() __algalloc; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § algorithms » containers ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +struct critbit0 { + void *root; + size_t count; +}; + +bool critbit0_contains(struct critbit0 *t, const char *u) nothrow nosideeffect + paramsnonnull(); +bool critbit0_insert(struct critbit0 *t, const char *u) paramsnonnull(); +bool critbit0_delete(struct critbit0 *t, const char *u) nothrow paramsnonnull(); +void critbit0_clear(struct critbit0 *t) nothrow paramsnonnull(); +char *critbit0_get(struct critbit0 *t, const char *u); +intptr_t critbit0_allprefixed(struct critbit0 *t, const char *prefix, + intptr_t (*callback)(const char *elem, void *arg), + void *arg) paramsnonnull((1, 2, 3)) nothrow; +bool critbit0_emplace(struct critbit0 *t, char *u, size_t ulen) paramsnonnull(); + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § algorithms » comparators ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +int cmpsb(/*const signed char[1]*/ const void *, const void *) + paramsnonnull() nothrow nocallback nosideeffect; +int cmpub(/*const unsigned char[1]*/ const void *, const void *) + paramsnonnull() nothrow nocallback nosideeffect; +int cmpsw(/*const signed short[1]*/ const void *, const void *) + paramsnonnull() nothrow nocallback nosideeffect; +int cmpuw(/*const unsigned short[1]*/ const void *, const void *) + paramsnonnull() nothrow nocallback nosideeffect; +int cmpsl(/*const signed int[1]*/ const void *, const void *) + paramsnonnull() nothrow nocallback nosideeffect; +int cmpul(/*const unsigned int[1]*/ const void *, const void *) + paramsnonnull() nothrow nocallback nosideeffect; +int cmpsq(/*const signed long[1]*/ const void *, const void *) + paramsnonnull() nothrow nocallback nosideeffect; +int cmpuq(/*const unsigned long[1]*/ const void *, const void *) + paramsnonnull() nothrow nocallback nosideeffect; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § algorithms » generics ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#if __STDC_VERSION__ + 0 >= 201112 + +#define memmem(haystack, haystacklen, needle, needlelen) \ + _Generic(*(haystack), wchar_t \ + : wmemmem, char16_t \ + : memmem16, default \ + : memmem)(haystack, haystacklen, needle, needlelen) + +#define replacestr(s, needle, replacement) \ + _Generic(*(s), wchar_t \ + : replacewcs, char16_t \ + : replacestr16, default \ + : replacestr)(s, needle, replacement) + +#define concatstr(s, ...) \ + _Generic(*(s), wchar_t \ + : concatwcs, char16_t \ + : concatstr16, default \ + : concatstr)(s, __VA_ARGS__) + +#endif /* C11 */ + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_ALG_ALG_H_ */ diff --git a/libc/alg/alg.mk b/libc/alg/alg.mk new file mode 100644 index 00000000..93cbf739 --- /dev/null +++ b/libc/alg/alg.mk @@ -0,0 +1,59 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += LIBC_ALG + +LIBC_ALG_ARTIFACTS += LIBC_ALG_A +LIBC_ALG = $(LIBC_ALG_A_DEPS) $(LIBC_ALG_A) +LIBC_ALG_A = o/$(MODE)/libc/alg/alg.a +LIBC_ALG_A_FILES := $(wildcard libc/alg/*) +LIBC_ALG_A_HDRS = $(filter %.h,$(LIBC_ALG_A_FILES)) +LIBC_ALG_A_SRCS_S = $(filter %.S,$(LIBC_ALG_A_FILES)) +LIBC_ALG_A_SRCS_C = $(filter %.c,$(LIBC_ALG_A_FILES)) + +LIBC_ALG_A_SRCS = \ + $(LIBC_ALG_A_SRCS_S) \ + $(LIBC_ALG_A_SRCS_C) + +LIBC_ALG_A_OBJS = \ + $(LIBC_ALG_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_ALG_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_ALG_A_SRCS_C:%.c=o/$(MODE)/%.o) + +LIBC_ALG_A_CHECKS = \ + $(LIBC_ALG_A).pkg \ + $(LIBC_ALG_A_HDRS:%=o/$(MODE)/%.ok) + +LIBC_ALG_A_DIRECTDEPS = \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_SYSV + +LIBC_ALG_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_ALG_A_DIRECTDEPS),$($(x)))) + +$(LIBC_ALG_A): libc/alg/ \ + $(LIBC_ALG_A).pkg \ + $(LIBC_ALG_A_OBJS) + +$(LIBC_ALG_A).pkg: \ + $(LIBC_ALG_A_OBJS) \ + $(foreach x,$(LIBC_ALG_A_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/libc/alg/critbit0.o: \ + DEFAULT_CFLAGS += \ + -ffunction-sections \ + -fdata-sections + +LIBC_ALG_LIBS = $(foreach x,$(LIBC_ALG_ARTIFACTS),$($(x))) +LIBC_ALG_SRCS = $(foreach x,$(LIBC_ALG_ARTIFACTS),$($(x)_SRCS)) +LIBC_ALG_HDRS = $(foreach x,$(LIBC_ALG_ARTIFACTS),$($(x)_HDRS)) +LIBC_ALG_CHECKS = $(foreach x,$(LIBC_ALG_ARTIFACTS),$($(x)_CHECKS)) +LIBC_ALG_OBJS = $(foreach x,$(LIBC_ALG_ARTIFACTS),$($(x)_OBJS)) +$(LIBC_ALG_OBJS): $(BUILD_FILES) libc/alg/alg.mk + +.PHONY: o/$(MODE)/libc/alg +o/$(MODE)/libc/alg: $(LIBC_ALG_CHECKS) diff --git a/libc/alg/arraylist.h b/libc/alg/arraylist.h new file mode 100644 index 00000000..765e257a --- /dev/null +++ b/libc/alg/arraylist.h @@ -0,0 +1,48 @@ +#ifndef COSMOPOLITAN_LIBC_ALG_ARRAYLIST_H_ +#define COSMOPOLITAN_LIBC_ALG_ARRAYLIST_H_ +#include "libc/bits/bits.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +#if 0 +/** + * @fileoverview Cosmopolitan Array List. + * + * This is a generically-typed ArrayList template which follows a + * duck-typing philosophy like Python, exporting an interface paradigm + * similar to Go, that's implicitly defined by way of macros like Lisp. + * + * struct MyArrayList { + * size_t i; // current item count + * size_t n; // current item capacity + * T *p; // pointer to array (initially NULL) + * }; + * + * Any struct with those fields can be used. It's also very important + * that other data structures, which reference items in an arraylist, do + * so using indices rather than pointers, since realloc() can relocate. + * + * @see libc/mem/grow.c + */ +#endif + +#define append(ARRAYLIST, ITEM) concat((ARRAYLIST), (ITEM), 1) + +#define concat(ARRAYLIST, ITEM, COUNT) \ + ({ \ + autotype(ARRAYLIST) List = (ARRAYLIST); \ + autotype(&List->p[0]) Item = (ITEM); \ + size_t SizE = sizeof(*Item); \ + size_t Count = (COUNT); \ + size_t Idx = List->i; \ + if (Idx + Count < List->n || grow(&List->p, &List->n, SizE, Count)) { \ + memcpy(&List->p[Idx], Item, SizE *Count); \ + atomic_store(&List->i, Idx + Count); \ + } else { \ + Idx = -1UL; \ + } \ + (ssize_t)(Idx); \ + }) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_ALG_ARRAYLIST_H_ */ diff --git a/libc/alg/arraylist2.h b/libc/alg/arraylist2.h new file mode 100644 index 00000000..92195f2a --- /dev/null +++ b/libc/alg/arraylist2.h @@ -0,0 +1,32 @@ +#ifndef COSMOPOLITAN_LIBC_ALG_ARRAYLIST2_H_ +#define COSMOPOLITAN_LIBC_ALG_ARRAYLIST2_H_ +#include "libc/mem/mem.h" +#include "libc/str/str.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/* TODO(jart): Fully develop these better macros. */ + +#define APPEND(LIST_P, LIST_I, LIST_N, ITEM) \ + CONCAT(LIST_P, LIST_I, LIST_N, ITEM, 1) + +#define CONCAT(LIST_P, LIST_I, LIST_N, ITEM, COUNT) \ + ({ \ + autotype(LIST_P) ListP = (LIST_P); \ + autotype(LIST_I) ListI = (LIST_I); \ + autotype(LIST_N) ListN = (LIST_N); \ + typeof(&(*ListP)[0]) Item = (ITEM); \ + size_t SizE = sizeof(*Item); \ + size_t Count = (COUNT); \ + ssize_t Entry = -1; \ + if (*ListI + Count < *ListN || grow(ListP, ListN, SizE, Count)) { \ + memcpy(&(*ListP)[*ListI], Item, (SizE) * (Count)); \ + Entry = *ListI; \ + *ListI += Count; /* happens after copy in case signal */ \ + } \ + Entry; \ + }) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_ALG_ARRAYLIST2_H_ */ diff --git a/libc/alg/bisect.h b/libc/alg/bisect.h new file mode 100644 index 00000000..beaa9be7 --- /dev/null +++ b/libc/alg/bisect.h @@ -0,0 +1,29 @@ +#ifndef COSMOPOLITAN_LIBC_ALG_BISECT_H_ +#define COSMOPOLITAN_LIBC_ALG_BISECT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +forceinline void *bisect(const void *k, const void *data, size_t n, size_t size, + int cmp(const void *a, const void *b, void *arg), + void *arg) { + int dir; + const char *p, *pos; + p = data; + while (n > 0) { + pos = p + size * (n / 2); + dir = cmp(k, pos, arg); + if (dir < 0) { + n /= 2; + } else if (dir > 0) { + p = pos + size; + n -= n / 2 + 1; + } else { + return (void *)pos; + } + } + return NULL; +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_ALG_BISECT_H_ */ diff --git a/libc/alg/bisectcarleft.h b/libc/alg/bisectcarleft.h new file mode 100644 index 00000000..9c7627fc --- /dev/null +++ b/libc/alg/bisectcarleft.h @@ -0,0 +1,31 @@ +#ifndef COSMOPOLITAN_LIBC_ALG_BISECTCARLEFT_H_ +#define COSMOPOLITAN_LIBC_ALG_BISECTCARLEFT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * Floor binary search of low 32-bits of 64-bit array items. + * + * This is well-suited to NexGen-32e, requiring less than 32 bytes of + * code. It's particularly useful for frozen maps, requiring less effort + * and memory than a perfect hash table. + */ +forceinline int32_t bisectcarleft(const int32_t (*cons)[2], size_t count, + const int32_t key) { + size_t left = 0; + size_t right = count; + while (left < right) { + size_t m = (left + right) >> 1; + if (cons[m][0] < key) { + left = m + 1; + } else { + right = m; + } + } + if (left && (left == count || cons[left][0] > key)) left--; + return left; +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_ALG_BISECTCARLEFT_H_ */ diff --git a/libc/alg/bisectleft.h b/libc/alg/bisectleft.h new file mode 100644 index 00000000..d59b289f --- /dev/null +++ b/libc/alg/bisectleft.h @@ -0,0 +1,27 @@ +#ifndef COSMOPOLITAN_LIBC_ALG_BISECTLEFT_H_ +#define COSMOPOLITAN_LIBC_ALG_BISECTLEFT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +forceinline size_t bisectleft(const void *key, const void *base, size_t count, + size_t sz, int cmp(const void *, const void *)) { + size_t m, l, r; + l = 0; + r = count; + while (l < r) { + m = (l + r) >> 1; + if (cmp((char *)base + m * sz, key) < 0) { + l = m + 1; + } else { + r = m; + } + } + if (l && (l == count || cmp((char *)base + l * sz, key) > 0)) { + l--; + } + return l; +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_ALG_BISECTLEFT_H_ */ diff --git a/libc/alg/bisectright.h b/libc/alg/bisectright.h new file mode 100644 index 00000000..1f1df38c --- /dev/null +++ b/libc/alg/bisectright.h @@ -0,0 +1,26 @@ +#ifndef COSMOPOLITAN_LIBC_ALG_BISECTRIGHT_H_ +#define COSMOPOLITAN_LIBC_ALG_BISECTRIGHT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +forceinline size_t bisectright(const void *key, const void *base, size_t count, + size_t sz, int cmp(const void *, const void *)) { + size_t left = 0; + size_t right = count; + while (left < right) { + size_t m = (right + right) >> 1; + if (cmp((char *)base + m * sz, key) > 0) { + right = m + 1; + } else { + right = m; + } + } + if (right && (right == count || cmp((char *)base + right * sz, key) > 0)) { + right--; + } + return right; +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_ALG_BISECTRIGHT_H_ */ diff --git a/libc/alg/bsearch.c b/libc/alg/bsearch.c new file mode 100644 index 00000000..b048d485 --- /dev/null +++ b/libc/alg/bsearch.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/alg/bisect.h" + +/** + * Searches sorted array for exact item in logarithmic time. + * @see bsearch_r(), bisectcarleft() + */ +void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, + int cmp(const void *a, const void *b)) { + return bisect(key, base, nmemb, size, (void *)cmp, NULL); +} diff --git a/libc/alg/bsearch_r.c b/libc/alg/bsearch_r.c new file mode 100644 index 00000000..d08be198 --- /dev/null +++ b/libc/alg/bsearch_r.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/alg/bisect.h" + +/** + * Searches sorted array for exact item in logarithmic time. + * @see bsearch(), bisectcarleft() + */ +void *bsearch_r(const void *key, const void *base, size_t nmemb, size_t size, + int cmp(const void *a, const void *b, void *arg), void *arg) { + return bisect(key, base, nmemb, size, cmp, arg); +} diff --git a/libc/alg/critbit0_allprefixed.c b/libc/alg/critbit0_allprefixed.c new file mode 100644 index 00000000..97bbc154 --- /dev/null +++ b/libc/alg/critbit0_allprefixed.c @@ -0,0 +1,65 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/alg/internal.h" +#include "libc/str/str.h" + +static intptr_t allprefixed_traverse(unsigned char *top, + intptr_t (*callback)(const char *, void *), + void *arg) { + if (1 & (intptr_t)top) { + struct CritbitNode *q = (void *)(top - 1); + for (int direction = 0; direction < 2; ++direction) { + intptr_t rc = allprefixed_traverse(q->child[direction], callback, arg); + if (rc) return rc; + } + return 0; + } + return callback((const char *)top, arg); +} + +/** + * Invokes callback for all items with prefix. + * + * @return 0 unless iteration was halted by CALLBACK returning + * nonzero, in which case that value is returned + * @note h/t djb and agl + */ +intptr_t critbit0_allprefixed(struct critbit0 *t, const char *prefix, + intptr_t (*callback)(const char *elem, void *arg), + void *arg) { + const unsigned char *ubytes = (void *)prefix; + const size_t ulen = strlen(prefix); + unsigned char *p = t->root; + unsigned char *top = p; + if (!p) return 0; + while (1 & (intptr_t)p) { + struct CritbitNode *q = (void *)(p - 1); + unsigned char c = 0; + if (q->byte < ulen) c = ubytes[q->byte]; + const int direction = (1 + (q->otherbits | c)) >> 8; + p = q->child[direction]; + if (q->byte < ulen) top = p; + } + for (size_t i = 0; i < ulen; ++i) { + if (p[i] != ubytes[i]) return 0; + } + return allprefixed_traverse(top, callback, arg); +} diff --git a/libc/alg/critbit0_clear.c b/libc/alg/critbit0_clear.c new file mode 100644 index 00000000..ca83f78f --- /dev/null +++ b/libc/alg/critbit0_clear.c @@ -0,0 +1,47 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/alg/internal.h" +#include "libc/mem/mem.h" + +static void critbit0_clear_traverse(void *top) { + unsigned char *p = top; + if (1 & (intptr_t)p) { + struct CritbitNode *q = (void *)(p - 1); + critbit0_clear_traverse(q->child[0]); + critbit0_clear_traverse(q->child[1]); + free(q), q = NULL; + } else { + free(p), p = NULL; + } +} + +/** + * Removes all items from 𝑡. + * @param t tree + * @note h/t djb and agl + */ +void critbit0_clear(struct critbit0 *t) { + if (t->root) { + critbit0_clear_traverse(t->root); + t->root = NULL; + } + t->count = 0; +} diff --git a/libc/alg/critbit0_contains.c b/libc/alg/critbit0_contains.c new file mode 100644 index 00000000..c43b7225 --- /dev/null +++ b/libc/alg/critbit0_contains.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/alg/internal.h" +#include "libc/str/str.h" + +/** + * Returns non-zero iff 𝑢 ∈ 𝑡. + * @param t tree + * @param u NUL-terminated string + * @note h/t djb and agl + */ +bool critbit0_contains(struct critbit0 *t, const char *u) { + const unsigned char *ubytes = (void *)u; + const size_t ulen = strlen(u); + unsigned char *p = t->root; + if (!p) return 0; + while (1 & (intptr_t)p) { + struct CritbitNode *q = (void *)(p - 1); + unsigned char c = 0; + if (q->byte < ulen) c = ubytes[q->byte]; + const int direction = (1 + (q->otherbits | c)) >> 8; + p = q->child[direction]; + } + return 0 == strcmp(u, (const char *)p); +} diff --git a/libc/alg/critbit0_delete.c b/libc/alg/critbit0_delete.c new file mode 100644 index 00000000..d321b167 --- /dev/null +++ b/libc/alg/critbit0_delete.c @@ -0,0 +1,61 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/alg/internal.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" + +/** + * Removes 𝑢 from 𝑡. + * @param t tree + * @param u NUL-terminated string + * @return true if 𝑡 was mutated + * @note h/t djb and agl + */ +bool critbit0_delete(struct critbit0 *t, const char *u) { + const unsigned char *ubytes = (void *)u; + const size_t ulen = strlen(u); + unsigned char *p = t->root; + void **wherep = &t->root; + void **whereq = 0; + struct CritbitNode *q = 0; + int direction = 0; + if (!p) return false; + while (1 & (intptr_t)p) { + whereq = wherep; + q = (void *)(p - 1); + unsigned char c = 0; + if (q->byte < ulen) c = ubytes[q->byte]; + direction = (1 + (q->otherbits | c)) >> 8; + wherep = q->child + direction; + p = *wherep; + } + if (0 != strcmp(u, (const char *)p)) return false; + free(p), p = NULL; + if (!whereq) { + t->root = NULL; + t->count = 0; + return true; + } + *whereq = q->child[1 - direction]; + free(q), q = NULL; + t->count--; + return true; +} diff --git a/libc/alg/critbit0_emplace.c b/libc/alg/critbit0_emplace.c new file mode 100644 index 00000000..6d5f3f99 --- /dev/null +++ b/libc/alg/critbit0_emplace.c @@ -0,0 +1,88 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/alg/internal.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" + +/** + * Inserts 𝑢 into 𝑡 without copying. + * @param t tree + * @param u NUL-terminated string which must be 8+ byte aligned and + * becomes owned by the tree afterwards + * @return true if 𝑡 was mutated + * @note h/t djb and agl + */ +bool critbit0_emplace(struct critbit0 *t, char *u, size_t ulen) { + unsigned char *p = t->root; + if (!p) { + t->root = u; + t->count = 1; + return true; + } + const unsigned char *const ubytes = (void *)u; + while (1 & (intptr_t)p) { + struct CritbitNode *q = (void *)(p - 1); + unsigned char c = 0; + if (q->byte < ulen) c = ubytes[q->byte]; + const int direction = (1 + (q->otherbits | c)) >> 8; + p = q->child[direction]; + } + uint32_t newbyte; + uint32_t newotherbits; + for (newbyte = 0; newbyte < ulen; ++newbyte) { + if (p[newbyte] != ubytes[newbyte]) { + newotherbits = p[newbyte] ^ ubytes[newbyte]; + goto different_byte_found; + } + } + if (p[newbyte] != 0) { + newotherbits = p[newbyte]; + goto different_byte_found; + } + return false; +different_byte_found: + newotherbits |= newotherbits >> 1; + newotherbits |= newotherbits >> 2; + newotherbits |= newotherbits >> 4; + newotherbits = (newotherbits & ~(newotherbits >> 1)) ^ 255; + unsigned char c = p[newbyte]; + int newdirection = (1 + (newotherbits | c)) >> 8; + struct CritbitNode *newnode = malloc(sizeof(struct CritbitNode)); + newnode->byte = newbyte; + newnode->otherbits = newotherbits; + newnode->child[1 - newdirection] = ubytes; + void **wherep = &t->root; + for (;;) { + unsigned char *wp = *wherep; + if (!(1 & (intptr_t)wp)) break; + struct CritbitNode *q = (void *)(wp - 1); + if (q->byte > newbyte) break; + if (q->byte == newbyte && q->otherbits > newotherbits) break; + unsigned char c2 = 0; + if (q->byte < ulen) c2 = ubytes[q->byte]; + const int direction = (1 + (q->otherbits | c2)) >> 8; + wherep = q->child + direction; + } + newnode->child[newdirection] = *wherep; + *wherep = (void *)(1 + (char *)newnode); + t->count++; + return true; +} diff --git a/libc/alg/critbit0_get.c b/libc/alg/critbit0_get.c new file mode 100644 index 00000000..3db2b388 --- /dev/null +++ b/libc/alg/critbit0_get.c @@ -0,0 +1,44 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/alg/internal.h" +#include "libc/str/str.h" + +/** + * Returns first item in 𝑡 with prefix 𝑢. + * @param t tree + * @param u NUL-terminated string + * @return item or NULL if not found + * @note h/t djb and agl + */ +char *critbit0_get(struct critbit0 *t, const char *u) { + const unsigned char *ubytes = (void *)u; + const size_t ulen = strlen(u); + unsigned char *p = t->root; + if (!p) return 0; + while (1 & (intptr_t)p) { + struct CritbitNode *q = (void *)(p - 1); + unsigned char c = 0; + if (q->byte < ulen) c = ubytes[q->byte]; + const int direction = (1 + (q->otherbits | c)) >> 8; + p = q->child[direction]; + } + return strncmp(u, (const char *)p, ulen) == 0 ? (const char *)p : NULL; +} diff --git a/libc/alg/critbit0_insert.c b/libc/alg/critbit0_insert.c new file mode 100644 index 00000000..70fed8e1 --- /dev/null +++ b/libc/alg/critbit0_insert.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/alg/internal.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" + +/** + * Inserts 𝑢 into 𝑡. + * @param t tree + * @param u NUL-terminated string + * @return true if 𝑡 was mutated + * @note h/t djb and agl + */ +bool critbit0_insert(struct critbit0 *t, const char *u) { + size_t ulen = strlen(u); + return critbit0_emplace(t, memcpy(malloc(ulen + 1), u, ulen + 1), ulen); +} diff --git a/libc/alg/djbsort-avx2.S b/libc/alg/djbsort-avx2.S new file mode 100644 index 00000000..6cbe6f96 --- /dev/null +++ b/libc/alg/djbsort-avx2.S @@ -0,0 +1,2327 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + + .p2align 4 +minmax_vector: + cmp $7,%rdx + jle .L27 + test $7,%dl + je .L5 + lea -32(,%rdx,4),%rax + lea (%rdi,%rax),%rcx + add %rsi,%rax + vmovdqu (%rax),%ymm0 + vmovdqu (%rcx),%ymm1 + and $-8,%rdx + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu %ymm2,(%rcx) + vmovdqu %ymm0,(%rax) + .p2align 4,,10 + .p2align 3 +.L5: vmovdqu (%rsi),%ymm1 + vmovdqu (%rdi),%ymm0 + add $32,%rsi + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu %ymm2,(%rdi) + vmovdqu %ymm0,-32(%rsi) + add $32,%rdi + sub $8,%rdx + jne .L5 + vzeroupper +.L25: ret + .p2align 4,,10 + .p2align 3 +.L27: test %rdx,%rdx + jle .L25 + mov (%rdi),%eax + cmp (%rsi),%eax + cmovg (%rsi),%ecx + cmovg %eax,%eax + mov %ecx,(%rdi) + mov %eax,(%rsi) + cmp $1,%rdx + je .L25 + mov 4(%rdi),%eax + cmp 4(%rsi),%eax + cmovg 4(%rsi),%ecx + cmovg %eax,%eax + mov %ecx,4(%rdi) + mov %eax,4(%rsi) + cmp $2,%rdx + je .L25 + mov 8(%rdi),%eax + cmp 8(%rsi),%eax + cmovg 8(%rsi),%ecx + cmovg %eax,%eax + mov %ecx,8(%rdi) + mov %eax,8(%rsi) + cmp $3,%rdx + je .L25 + mov 12(%rdi),%eax + cmp 12(%rsi),%eax + cmovg 12(%rsi),%ecx + cmovg %eax,%eax + mov %ecx,12(%rdi) + mov %eax,12(%rsi) + cmp $4,%rdx + je .L25 + mov 16(%rdi),%eax + cmp 16(%rsi),%eax + cmovg 16(%rsi),%ecx + cmovg %eax,%eax + mov %ecx,16(%rdi) + mov %eax,16(%rsi) + cmp $5,%rdx + je .L25 + mov 20(%rdi),%eax + cmp 20(%rsi),%eax + cmovg 20(%rsi),%ecx + cmovg %eax,%eax + mov %ecx,20(%rdi) + mov %eax,20(%rsi) + cmp $7,%rdx + jne .L25 + mov 24(%rdi),%eax + cmp 24(%rsi),%eax + cmovg 24(%rsi),%edx + cmovg %eax,%eax + mov %edx,24(%rdi) + mov %eax,24(%rsi) + ret + .endfn minmax_vector,globl + + .p2align 4 +int32_twostages_32: + test %rsi,%rsi + jle .L33 + lea -128(%rsi),%rax + dec %rsi + and $-128,%rsi + mov %rax,%rdx + sub %rsi,%rdx + jmp .L30 + .p2align 4,,10 + .p2align 3 +.L34: add $-128,%rax +.L30: vmovdqu 256(%rdi),%ymm1 + vmovdqu (%rdi),%ymm0 + vmovdqu 384(%rdi),%ymm4 + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu 128(%rdi),%ymm1 + add $512,%rdi + vpminsd %ymm4,%ymm1,%ymm3 + vpmaxsd %ymm4,%ymm1,%ymm1 + vpminsd %ymm3,%ymm2,%ymm4 + vpmaxsd %ymm3,%ymm2,%ymm2 + vpminsd %ymm1,%ymm0,%ymm3 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu %ymm0,-128(%rdi) + vmovdqu -224(%rdi),%ymm1 + vmovdqu -480(%rdi),%ymm0 + vmovdqu %ymm4,-512(%rdi) + vmovdqu %ymm2,-384(%rdi) + vmovdqu -96(%rdi),%ymm4 + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu -352(%rdi),%ymm1 + vmovdqu %ymm3,-256(%rdi) + vpminsd %ymm4,%ymm1,%ymm3 + vpmaxsd %ymm4,%ymm1,%ymm1 + vpminsd %ymm3,%ymm2,%ymm4 + vpmaxsd %ymm3,%ymm2,%ymm2 + vpminsd %ymm1,%ymm0,%ymm3 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu %ymm0,-96(%rdi) + vmovdqu -192(%rdi),%ymm1 + vmovdqu -448(%rdi),%ymm0 + vmovdqu %ymm4,-480(%rdi) + vmovdqu %ymm2,-352(%rdi) + vmovdqu -64(%rdi),%ymm4 + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu -320(%rdi),%ymm1 + vmovdqu %ymm3,-224(%rdi) + vpminsd %ymm4,%ymm1,%ymm3 + vpmaxsd %ymm4,%ymm1,%ymm1 + vpminsd %ymm3,%ymm2,%ymm4 + vpmaxsd %ymm3,%ymm2,%ymm2 + vpminsd %ymm1,%ymm0,%ymm3 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu %ymm0,-64(%rdi) + vmovdqu -160(%rdi),%ymm1 + vmovdqu -416(%rdi),%ymm0 + vmovdqu %ymm4,-448(%rdi) + vmovdqu %ymm2,-320(%rdi) + vmovdqu -32(%rdi),%ymm4 + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu -288(%rdi),%ymm1 + vmovdqu %ymm3,-192(%rdi) + vpminsd %ymm4,%ymm1,%ymm3 + vpmaxsd %ymm4,%ymm1,%ymm1 + vpminsd %ymm3,%ymm2,%ymm4 + vpmaxsd %ymm3,%ymm2,%ymm2 + vpminsd %ymm1,%ymm0,%ymm3 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu %ymm4,-416(%rdi) + vmovdqu %ymm2,-288(%rdi) + vmovdqu %ymm3,-160(%rdi) + vmovdqu %ymm0,-32(%rdi) + cmp %rdx,%rax + jne .L34 + vzeroupper +.L33: ret + .endfn int32_twostages_32,globl + + .p2align 4 +int32_threestages: + push %rbp + mov %rsp,%rbp + push %r15 + push %r14 + lea 0(,%rdx,8),%r14 + push %r13 + push %r12 + push %rbx + and $-32,%rsp + sub $32,%rsp + mov %rsi,16(%rsp) + cmp %r14,%rsi + jl .L41 + lea -1(%rdx),%rax + and $-8,%rax + lea (%rdx,%rdx),%r8 + mov %rax,8(%rsp) + lea (%r8,%rdx),%rcx + lea 0(,%rdx,4),%rsi + mov %r14,%r9 + mov %rdi,%r13 + lea (%rsi,%rdx),%r11 + lea (%rcx,%rcx),%r10 + sub %rdx,%r9 + xor %r12d,%r12d + mov %r14,%rbx + lea 32(%rdi),%r15 + .p2align 4,,10 + .p2align 3 +.L37: mov %r12,%rdi + lea (%rdx,%rdi),%rax + mov %rbx,24(%rsp) + mov %rbx,%r12 + cmp %rax,%rdi + jge .L40 + lea 0(%r13,%rdi,4),%rax + add 8(%rsp),%rdi + lea (%r15,%rdi,4),%rdi + .p2align 4,,10 + .p2align 3 +.L38: vmovdqu (%rax,%rsi,4),%ymm0 + vmovdqu (%rax),%ymm6 + vmovdqu (%rax,%rdx,4),%ymm1 + vpminsd %ymm0,%ymm6,%ymm7 + vpmaxsd %ymm0,%ymm6,%ymm6 + vmovdqu (%rax,%r11,4),%ymm0 + vmovdqu (%rax,%r9,4),%ymm8 + vpmaxsd %ymm0,%ymm1,%ymm3 + vpminsd %ymm0,%ymm1,%ymm2 + vmovdqu (%rax,%r10,4),%ymm1 + vmovdqu (%rax,%r8,4),%ymm0 + vpminsd %ymm1,%ymm0,%ymm4 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu (%rax,%rcx,4),%ymm1 + vpminsd %ymm8,%ymm1,%ymm5 + vpmaxsd %ymm8,%ymm1,%ymm1 + vpminsd %ymm4,%ymm7,%ymm8 + vpmaxsd %ymm4,%ymm7,%ymm4 + vpminsd %ymm5,%ymm2,%ymm7 + vpmaxsd %ymm5,%ymm2,%ymm2 + vpminsd %ymm0,%ymm6,%ymm5 + vpmaxsd %ymm0,%ymm6,%ymm0 + vpminsd %ymm1,%ymm3,%ymm6 + vpmaxsd %ymm1,%ymm3,%ymm1 + vpminsd %ymm7,%ymm8,%ymm9 + vpmaxsd %ymm7,%ymm8,%ymm3 + vpminsd %ymm2,%ymm4,%ymm8 + vpminsd %ymm6,%ymm5,%ymm7 + vpmaxsd %ymm2,%ymm4,%ymm2 + vpmaxsd %ymm6,%ymm5,%ymm5 + vpminsd %ymm1,%ymm0,%ymm4 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu %ymm9,(%rax) + vmovdqu %ymm3,(%rax,%rdx,4) + vmovdqu %ymm8,(%rax,%r8,4) + vmovdqu %ymm2,(%rax,%rcx,4) + vmovdqu %ymm7,(%rax,%rsi,4) + vmovdqu %ymm5,(%rax,%r11,4) + vmovdqu %ymm4,(%rax,%r10,4) + vmovdqu %ymm0,(%rax,%r9,4) + add $32,%rax + cmp %rax,%rdi + jne .L38 +.L40: add %r14,%rbx + cmp %rbx,16(%rsp) + jge .L37 + vzeroupper +.L35: mov 24(%rsp),%rax + lea -40(%rbp),%rsp + pop %rbx + pop %r12 + pop %r13 + pop %r14 + pop %r15 + pop %rbp + ret +.L41: movq $0,24(%rsp) + jmp .L35 + .endfn int32_threestages,globl + + .p2align 4 +merge16_finish: + vpminsd %ymm1,%ymm0,%ymm3 + vpmaxsd %ymm1,%ymm0,%ymm0 + vperm2i128 $32,%ymm0,%ymm3,%ymm2 + vperm2i128 $49,%ymm0,%ymm3,%ymm0 + vpminsd %ymm0,%ymm2,%ymm1 + vpmaxsd %ymm0,%ymm2,%ymm0 + vpunpcklqdq %ymm0,%ymm1,%ymm2 + vpunpckhqdq %ymm0,%ymm1,%ymm0 + vpminsd %ymm0,%ymm2,%ymm1 + vpmaxsd %ymm0,%ymm2,%ymm2 + vpunpckldq %ymm2,%ymm1,%ymm0 + vpunpckhdq %ymm2,%ymm1,%ymm1 + vpunpcklqdq %ymm1,%ymm0,%ymm3 + vpunpckhqdq %ymm1,%ymm0,%ymm0 + vpminsd %ymm3,%ymm0,%ymm2 + vpmaxsd %ymm3,%ymm0,%ymm0 + vpunpckldq %ymm0,%ymm2,%ymm1 + vpunpckhdq %ymm0,%ymm2,%ymm0 + vperm2i128 $32,%ymm0,%ymm1,%ymm2 + vperm2i128 $49,%ymm0,%ymm1,%ymm0 + test %esi,%esi + je .L46 + vpcmpeqd %ymm1,%ymm1,%ymm1 + vpxor %ymm1,%ymm2,%ymm2 + vpxor %ymm1,%ymm0,%ymm0 +.L46: vmovdqu %ymm2,(%rdi) + vmovdqu %ymm0,32(%rdi) + ret + .endfn merge16_finish,globl + + .p2align 4 +djbsort$avx2_2power: + push %r13 + mov %rdi,%r11 + lea 16(%rsp),%r13 + and $-32,%rsp + push -8(%r13) + push %rbp + mov %rsp,%rbp + push %r15 + push %r14 + push %r13 + push %r12 + push %rbx + sub $200,%rsp + mov %rsi,-144(%rbp) + mov %edx,-164(%rbp) + cmp $8,%rsi + je .L194 + cmpq $16,-144(%rbp) + je .L195 + cmpq $32,-144(%rbp) + je .L196 + mov %rsi,%r15 + sar $3,%r15 + test %r15,%r15 + jle .L197 + lea -1(%r15),%rbx + mov %rbx,-200(%rbp) + shr $3,%rbx + mov %rbx,%rdx + lea 32(%r11),%rbx + lea (%r15,%r15),%r8 + mov %rbx,-120(%rbp) + lea 0(,%r15,4),%rsi + lea (%r8,%r15),%rdi + lea 0(,%r15,8),%rcx + sal $5,%rdx + lea (%rdi,%rdi),%r10 + lea (%rsi,%r15),%r9 + sub %r15,%rcx + mov %r11,%rax + add %rbx,%rdx +.L61: vmovdqu (%rax),%ymm0 + vmovdqu (%rax,%rsi,4),%ymm2 + vmovdqu (%rax,%r10,4),%ymm3 + vpminsd %ymm2,%ymm0,%ymm4 + vpmaxsd %ymm2,%ymm0,%ymm2 + vmovdqu (%rax,%r8,4),%ymm0 + vpminsd %ymm3,%ymm0,%ymm1 + vpmaxsd %ymm3,%ymm0,%ymm0 + vpminsd %ymm2,%ymm0,%ymm3 + vpmaxsd %ymm2,%ymm0,%ymm0 + vpminsd %ymm4,%ymm1,%ymm2 + vpmaxsd %ymm4,%ymm1,%ymm1 + vpminsd %ymm1,%ymm3,%ymm4 + vpmaxsd %ymm1,%ymm3,%ymm1 + vmovdqu %ymm0,(%rax) + vmovdqu %ymm4,(%rax,%r8,4) + vmovdqu %ymm1,(%rax,%rsi,4) + vmovdqu %ymm2,(%rax,%r10,4) + vmovdqu (%rax,%r15,4),%ymm2 + vmovdqu (%rax,%r9,4),%ymm0 + vmovdqu (%rax,%rdi,4),%ymm4 + vpminsd %ymm2,%ymm0,%ymm1 + vpmaxsd %ymm2,%ymm0,%ymm0 + vmovdqu (%rax,%rcx,4),%ymm2 + vpminsd %ymm4,%ymm2,%ymm3 + vpmaxsd %ymm4,%ymm2,%ymm2 + vpminsd %ymm3,%ymm1,%ymm4 + vpmaxsd %ymm3,%ymm1,%ymm1 + vpminsd %ymm2,%ymm0,%ymm3 + vpmaxsd %ymm2,%ymm0,%ymm0 + vpminsd %ymm1,%ymm3,%ymm2 + vpmaxsd %ymm1,%ymm3,%ymm1 + vmovdqu %ymm4,(%rax,%r15,4) + vmovdqu %ymm1,(%rax,%rdi,4) + vmovdqu %ymm2,(%rax,%r9,4) + vmovdqu %ymm0,(%rax,%rcx,4) + add $32,%rax + cmp %rdx,%rax + jne .L61 +.L62: lea 0(,%r15,8),%rax + sub %r15,%rax + lea (%r15,%r15),%r12 + mov %rax,%r9 + mov -144(%rbp),%rax + lea 0(,%r15,4),%rbx + lea (%r12,%r15),%r13 + lea (%rbx,%r15),%r10 + lea (%r13,%r13),%r14 + cmp $127,%rax + jg .L59 + lea 64(%r11),%rdi + dec %rax + mov %rdi,-192(%rbp) + mov %rax,-176(%rbp) +.L60: mov -144(%rbp),%rdi + mov %r11,-208(%rbp) + lea (%r11,%rdi,4),%rax + mov %rax,-112(%rbp) + mov %rdi,%rax + sar $4,%rax + cmp $32,%rax + sete %dl + cmp $127,%rax + mov %rax,-80(%rbp) + setg %al + or %eax,%edx + mov -176(%rbp),%rax + mov %dl,-152(%rbp) + shr $4,%rax + sal $6,%rax + add -192(%rbp),%rax + mov %rax,-128(%rbp) + mov -200(%rbp),%rax + movl $3,-184(%rbp) + shr $3,%rax + sal $5,%rax + add -120(%rbp),%rax + mov %rax,-160(%rbp) + movq $4,-136(%rbp) + mov %r12,-200(%rbp) + mov %r13,-216(%rbp) + mov %r10,-224(%rbp) + mov %r9,-232(%rbp) + vmovdqa .LC1(%rip),%ymm11 + vmovdqa .LC3(%rip),%ymm10 + vmovdqa .LC2(%rip),%ymm12 + mov %rbx,-192(%rbp) + mov %rdi,%rbx +.L63: cmpq $4,-136(%rbp) + je .L198 + cmpq $2,-136(%rbp) + je .L91 + mov -112(%rbp),%rdx + mov %r11,%rax + cmp -112(%rbp),%r11 + je .L90 +.L92: vpxor 32(%rax),%ymm10,%ymm2 + vpxor (%rax),%ymm10,%ymm1 + add $64,%rax + vperm2i128 $32,%ymm2,%ymm1,%ymm0 + vperm2i128 $49,%ymm2,%ymm1,%ymm1 + vpunpcklqdq %ymm1,%ymm0,%ymm2 + vpunpckhqdq %ymm1,%ymm0,%ymm0 + vpminsd %ymm0,%ymm2,%ymm1 + vpmaxsd %ymm0,%ymm2,%ymm2 + vpunpcklqdq %ymm2,%ymm1,%ymm0 + vpunpckhqdq %ymm2,%ymm1,%ymm1 + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vperm2i128 $32,%ymm0,%ymm2,%ymm1 + vperm2i128 $49,%ymm0,%ymm2,%ymm0 + vmovdqu %ymm1,-64(%rax) + vmovdqu %ymm0,-32(%rax) + cmp %rax,%rdx + jne .L92 +.L90: cmpb $0,-152(%rbp) + mov -80(%rbp),%r12 + je .L89 + mov %rbx,%r13 + mov %r11,%rbx + .p2align 4,,10 + .p2align 3 +.L146: mov %r12,%rdx + sar $2,%rdx + mov %r13,%rsi + mov %rbx,%rdi + vzeroupper + sar $3,%r12 + call int32_threestages + cmp $127,%r12 + vmovdqa .LC1(%rip),%ymm11 + vmovdqa .LC3(%rip),%ymm10 + vmovdqa .LC2(%rip),%ymm12 + jg .L146 + cmp $32,%r12 + je .L146 + mov %rbx,%r11 + mov %r13,%rbx +.L89: cmp $15,%r12 + jle .L94 + mov -120(%rbp),%r13 + .p2align 4,,10 + .p2align 3 +.L100: mov %r12,%rdx + sar %rdx + test %rbx,%rbx + jle .L95 + lea (%rdx,%rdx),%rcx + lea -1(%rdx),%r9 + lea (%rcx,%rdx),%rsi + lea 0(,%rdx,4),%r10 + xor %r8d,%r8d + and $-8,%r9 + .p2align 4,,10 + .p2align 3 +.L96: lea (%rdx,%r8),%rax + cmp %rax,%r8 + jge .L99 + lea (%r9,%r8),%rdi + lea (%r11,%r8,4),%rax + lea 0(%r13,%rdi,4),%rdi + .p2align 4,,10 + .p2align 3 +.L97: vmovdqu (%rax,%rcx,4),%ymm1 + vmovdqu (%rax),%ymm0 + vmovdqu (%rax,%rsi,4),%ymm4 + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu (%rax,%rdx,4),%ymm1 + vpminsd %ymm4,%ymm1,%ymm3 + vpmaxsd %ymm4,%ymm1,%ymm1 + vpminsd %ymm3,%ymm2,%ymm4 + vpmaxsd %ymm3,%ymm2,%ymm2 + vpminsd %ymm1,%ymm0,%ymm3 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu %ymm4,(%rax) + vmovdqu %ymm2,(%rax,%rdx,4) + vmovdqu %ymm3,(%rax,%rcx,4) + vmovdqu %ymm0,(%rax,%rsi,4) + add $32,%rax + cmp %rdi,%rax + jne .L97 +.L99: add %r10,%r8 + cmp %r8,%rbx + jg .L96 +.L95: sar $2,%r12 + cmp $15,%r12 + jg .L100 +.L94: cmp $8,%r12 + je .L101 +.L104: mov %r11,%rax + test %r15,%r15 + jle .L103 + mov -160(%rbp),%r9 + mov -192(%rbp),%rdx + mov -200(%rbp),%rcx + mov -216(%rbp),%rsi + mov -224(%rbp),%rdi + mov -232(%rbp),%r8 + .p2align 4,,10 + .p2align 3 +.L102: vmovdqu (%rax,%r15,4),%ymm0 + vmovdqu (%rax),%ymm1 + vmovdqu (%rax,%rcx,4),%ymm2 + vmovdqu (%rax,%rdi,4),%ymm4 + vmovdqu (%rax,%rdx,4),%ymm7 + vpminsd %ymm0,%ymm1,%ymm5 + vpmaxsd %ymm0,%ymm1,%ymm1 + vmovdqu (%rax,%rsi,4),%ymm0 + vmovdqu (%rax,%r14,4),%ymm8 + vpminsd %ymm0,%ymm2,%ymm3 + vpmaxsd %ymm0,%ymm2,%ymm0 + vpminsd %ymm4,%ymm7,%ymm2 + vpmaxsd %ymm4,%ymm7,%ymm7 + vmovdqu (%rax,%r8,4),%ymm4 + vpminsd %ymm3,%ymm5,%ymm9 + vpminsd %ymm4,%ymm8,%ymm6 + vpmaxsd %ymm4,%ymm8,%ymm4 + vpmaxsd %ymm3,%ymm5,%ymm5 + vpminsd %ymm0,%ymm1,%ymm8 + vpminsd %ymm6,%ymm2,%ymm3 + vpmaxsd %ymm0,%ymm1,%ymm0 + vpmaxsd %ymm6,%ymm2,%ymm1 + vpminsd %ymm4,%ymm7,%ymm2 + vpmaxsd %ymm4,%ymm7,%ymm4 + vpminsd %ymm3,%ymm9,%ymm6 + vpminsd %ymm2,%ymm8,%ymm7 + vpmaxsd %ymm3,%ymm9,%ymm3 + vpmaxsd %ymm2,%ymm8,%ymm2 + vpminsd %ymm1,%ymm5,%ymm8 + vpmaxsd %ymm1,%ymm5,%ymm1 + vpminsd %ymm4,%ymm0,%ymm5 + vpmaxsd %ymm4,%ymm0,%ymm0 + vmovdqu %ymm6,(%rax) + vmovdqu %ymm7,(%rax,%r15,4) + vmovdqu %ymm8,(%rax,%rcx,4) + vmovdqu %ymm5,(%rax,%rsi,4) + vmovdqu %ymm3,(%rax,%rdx,4) + vmovdqu %ymm2,(%rax,%rdi,4) + vmovdqu %ymm1,(%rax,%r14,4) + vmovdqu %ymm0,(%rax,%r8,4) + add $32,%rax + cmp %rax,%r9 + jne .L102 +.L103: sarq -136(%rbp) + decl -184(%rbp) + jne .L63 + cmpq $0,-144(%rbp) + jle .L113 + mov -176(%rbp),%rax + vpcmpeqd %ymm4,%ymm4,%ymm4 + shr $6,%rax + sal $8,%rax + lea 256(%r11,%rax),%rdx + mov %r11,%rax + jmp .L112 +.L199: vpxor %ymm4,%ymm7,%ymm7 + vpxor %ymm4,%ymm2,%ymm2 + vpxor %ymm4,%ymm1,%ymm1 + vpxor %ymm4,%ymm0,%ymm0 +.L111: vperm2i128 $32,%ymm5,%ymm9,%ymm11 + vperm2i128 $32,%ymm6,%ymm10,%ymm3 + vperm2i128 $32,%ymm1,%ymm7,%ymm12 + vperm2i128 $32,%ymm0,%ymm2,%ymm8 + vperm2i128 $49,%ymm6,%ymm10,%ymm6 + vperm2i128 $49,%ymm5,%ymm9,%ymm9 + vperm2i128 $49,%ymm1,%ymm7,%ymm1 + vperm2i128 $49,%ymm0,%ymm2,%ymm0 + vpminsd %ymm3,%ymm12,%ymm7 + vpmaxsd %ymm11,%ymm8,%ymm2 + vpminsd %ymm9,%ymm0,%ymm10 + vpminsd %ymm6,%ymm1,%ymm5 + vpmaxsd %ymm9,%ymm0,%ymm0 + vpmaxsd %ymm3,%ymm12,%ymm3 + vpmaxsd %ymm6,%ymm1,%ymm1 + vpminsd %ymm11,%ymm8,%ymm12 + vpminsd %ymm12,%ymm7,%ymm9 + vpmaxsd %ymm12,%ymm7,%ymm6 + vpminsd %ymm10,%ymm5,%ymm8 + vpminsd %ymm2,%ymm3,%ymm7 + vpmaxsd %ymm10,%ymm5,%ymm5 + vpmaxsd %ymm2,%ymm3,%ymm3 + vpminsd %ymm0,%ymm1,%ymm2 + vpmaxsd %ymm0,%ymm1,%ymm1 + vpminsd %ymm8,%ymm9,%ymm10 + vpmaxsd %ymm5,%ymm6,%ymm0 + vpmaxsd %ymm8,%ymm9,%ymm8 + vpminsd %ymm2,%ymm7,%ymm9 + vpmaxsd %ymm2,%ymm7,%ymm7 + vpminsd %ymm5,%ymm6,%ymm2 + vpminsd %ymm1,%ymm3,%ymm5 + vpmaxsd %ymm1,%ymm3,%ymm3 + vpunpckldq %ymm9,%ymm10,%ymm11 + vpunpckhdq %ymm9,%ymm10,%ymm6 + vpunpckldq %ymm7,%ymm8,%ymm1 + vpunpckldq %ymm5,%ymm2,%ymm9 + vpunpckldq %ymm3,%ymm0,%ymm10 + vpunpckhdq %ymm5,%ymm2,%ymm2 + vpunpckhdq %ymm3,%ymm0,%ymm0 + vpunpckhdq %ymm7,%ymm8,%ymm5 + vpunpcklqdq %ymm9,%ymm11,%ymm3 + vpunpcklqdq %ymm2,%ymm6,%ymm8 + vpunpckhqdq %ymm9,%ymm11,%ymm7 + vpunpckhqdq %ymm2,%ymm6,%ymm6 + vpunpcklqdq %ymm0,%ymm5,%ymm9 + vpunpcklqdq %ymm10,%ymm1,%ymm2 + vpunpckhqdq %ymm0,%ymm5,%ymm0 + vpunpckhqdq %ymm10,%ymm1,%ymm1 + vperm2i128 $32,%ymm2,%ymm3,%ymm12 + vperm2i128 $32,%ymm1,%ymm7,%ymm11 + vperm2i128 $32,%ymm0,%ymm6,%ymm5 + vperm2i128 $49,%ymm2,%ymm3,%ymm3 + vperm2i128 $32,%ymm9,%ymm8,%ymm10 + vperm2i128 $49,%ymm1,%ymm7,%ymm2 + vperm2i128 $49,%ymm0,%ymm6,%ymm0 + vperm2i128 $49,%ymm9,%ymm8,%ymm1 + vmovdqu %ymm12,(%rax) + vmovdqu %ymm11,32(%rax) + vmovdqu %ymm10,64(%rax) + vmovdqu %ymm5,96(%rax) + vmovdqu %ymm3,128(%rax) + vmovdqu %ymm2,160(%rax) + vmovdqu %ymm1,192(%rax) + vmovdqu %ymm0,224(%rax) + add $256,%rax + cmp %rdx,%rax + je .L113 +.L112: vmovdqu 32(%rax),%ymm0 + vmovdqu (%rax),%ymm2 + vmovdqu 128(%rax),%ymm3 + vpunpckhdq %ymm0,%ymm2,%ymm5 + vpunpckldq %ymm0,%ymm2,%ymm7 + vmovdqu 96(%rax),%ymm0 + vmovdqu 64(%rax),%ymm2 + vmovdqu 224(%rax),%ymm9 + vpunpckldq %ymm0,%ymm2,%ymm6 + vpunpckhdq %ymm0,%ymm2,%ymm2 + vmovdqu 160(%rax),%ymm0 + mov -164(%rbp),%ebx + vpunpckldq %ymm0,%ymm3,%ymm1 + vpunpckhdq %ymm0,%ymm3,%ymm0 + vmovdqu 192(%rax),%ymm3 + vpunpcklqdq %ymm6,%ymm7,%ymm10 + vpunpckldq %ymm9,%ymm3,%ymm8 + vpunpckhdq %ymm9,%ymm3,%ymm3 + vpunpckhqdq %ymm6,%ymm7,%ymm7 + vpunpcklqdq %ymm2,%ymm5,%ymm9 + vpunpcklqdq %ymm8,%ymm1,%ymm6 + vpunpckhqdq %ymm2,%ymm5,%ymm2 + vpunpckhqdq %ymm8,%ymm1,%ymm1 + vpunpcklqdq %ymm3,%ymm0,%ymm5 + vpunpckhqdq %ymm3,%ymm0,%ymm0 + test %ebx,%ebx + jne .L199 + vpxor %ymm4,%ymm10,%ymm10 + vpxor %ymm4,%ymm9,%ymm9 + vpxor %ymm4,%ymm6,%ymm6 + vpxor %ymm4,%ymm5,%ymm5 + jmp .L111 +.L91: mov -112(%rbp),%rdx + cmp %rdx,%r11 + je .L90 + mov %r11,%rax +.L93: vpxor 32(%rax),%ymm11,%ymm2 + vpxor (%rax),%ymm11,%ymm1 + add $64,%rax + vperm2i128 $32,%ymm2,%ymm1,%ymm0 + vperm2i128 $49,%ymm2,%ymm1,%ymm1 + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vperm2i128 $32,%ymm0,%ymm2,%ymm1 + vperm2i128 $49,%ymm0,%ymm2,%ymm0 + vmovdqu %ymm1,-64(%rax) + vmovdqu %ymm0,-32(%rax) + cmp %rax,%rdx + jne .L93 + jmp .L90 +.L101: test %rbx,%rbx + jle .L104 + mov %r11,%rax +.L105: vmovdqu 32(%rax),%ymm1 + vmovdqu (%rax),%ymm0 + add $64,%rax + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu %ymm2,-64(%rax) + vmovdqu %ymm0,-32(%rax) + cmp %rax,-128(%rbp) + jne .L105 + jmp .L104 +.L198: mov %r11,%rax + cmp -112(%rbp),%r11 + je .L90 +.L87: vpxor 32(%rax),%ymm12,%ymm0 + vpxor (%rax),%ymm12,%ymm1 + vmovdqu %ymm0,32(%rax) + vmovdqu %ymm1,(%rax) + add $64,%rax + cmp %rax,-112(%rbp) + jne .L87 + jmp .L90 +.L113: cmpb $0,-152(%rbp) + mov -80(%rbp),%r13 + je .L109 + mov %r15,-112(%rbp) + mov -120(%rbp),%r15 +.L145: mov -80(%rbp),%rdx + sar $2,%rdx + cmpq $0,-144(%rbp) + jle .L114 + lea (%rdx,%rdx),%rdi + lea 0(,%rdx,8),%r14 + lea (%rdi,%rdx),%rcx + lea 0(,%rdx,4),%rsi + mov %r14,%r8 + lea -1(%rdx),%r13 + lea (%rsi,%rdx),%r10 + lea (%rcx,%rcx),%r9 + sub %rdx,%r8 + xor %r12d,%r12d + and $-8,%r13 + .p2align 4,,10 + .p2align 3 +.L115: lea (%rdx,%r12),%rax + cmp %rax,%r12 + jge .L118 + lea 0(%r13,%r12),%rbx + lea (%r11,%r12,4),%rax + lea (%r15,%rbx,4),%rbx + .p2align 4,,10 + .p2align 3 +.L116: vmovdqu (%rax,%rsi,4),%ymm0 + vmovdqu (%rax),%ymm6 + vmovdqu (%rax,%rdx,4),%ymm1 + vpminsd %ymm0,%ymm6,%ymm7 + vpmaxsd %ymm0,%ymm6,%ymm6 + vmovdqu (%rax,%r10,4),%ymm0 + vmovdqu (%rax,%r8,4),%ymm8 + vpmaxsd %ymm0,%ymm1,%ymm3 + vpminsd %ymm0,%ymm1,%ymm2 + vmovdqu (%rax,%r9,4),%ymm1 + vmovdqu (%rax,%rdi,4),%ymm0 + vpminsd %ymm1,%ymm0,%ymm4 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu (%rax,%rcx,4),%ymm1 + vpminsd %ymm8,%ymm1,%ymm5 + vpmaxsd %ymm8,%ymm1,%ymm1 + vpminsd %ymm4,%ymm7,%ymm8 + vpmaxsd %ymm4,%ymm7,%ymm4 + vpminsd %ymm5,%ymm2,%ymm7 + vpmaxsd %ymm5,%ymm2,%ymm2 + vpminsd %ymm0,%ymm6,%ymm5 + vpmaxsd %ymm0,%ymm6,%ymm0 + vpminsd %ymm1,%ymm3,%ymm6 + vpmaxsd %ymm1,%ymm3,%ymm1 + vpminsd %ymm7,%ymm8,%ymm9 + vpmaxsd %ymm7,%ymm8,%ymm3 + vpminsd %ymm2,%ymm4,%ymm8 + vpminsd %ymm6,%ymm5,%ymm7 + vpmaxsd %ymm2,%ymm4,%ymm2 + vpmaxsd %ymm6,%ymm5,%ymm5 + vpminsd %ymm1,%ymm0,%ymm4 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu %ymm9,(%rax) + vmovdqu %ymm3,(%rax,%rdx,4) + vmovdqu %ymm8,(%rax,%rdi,4) + vmovdqu %ymm2,(%rax,%rcx,4) + vmovdqu %ymm7,(%rax,%rsi,4) + vmovdqu %ymm5,(%rax,%r10,4) + vmovdqu %ymm4,(%rax,%r9,4) + vmovdqu %ymm0,(%rax,%r8,4) + add $32,%rax + cmp %rbx,%rax + jne .L116 +.L118: add %r14,%r12 + cmp %r12,-144(%rbp) + jg .L115 +.L114: sarq $3,-80(%rbp) + mov -80(%rbp),%rax + cmp $127,%rax + jg .L145 + cmp $32,%rax + je .L145 + mov -112(%rbp),%r15 + mov %rax,%r13 +.L109: cmp $15,%r13 + jle .L119 + mov -144(%rbp),%r10 + mov -120(%rbp),%r12 +.L125: mov %r13,%rdx + sar %rdx + test %r10,%r10 + jle .L120 + lea (%rdx,%rdx),%rcx + lea -1(%rdx),%r9 + lea (%rcx,%rdx),%rsi + lea 0(,%rdx,4),%rbx + xor %r8d,%r8d + and $-8,%r9 + .p2align 4,,10 + .p2align 3 +.L121: lea (%rdx,%r8),%rax + cmp %rax,%r8 + jge .L124 + lea (%r9,%r8),%rdi + lea (%r11,%r8,4),%rax + lea (%r12,%rdi,4),%rdi + .p2align 4,,10 + .p2align 3 +.L122: vmovdqu (%rax,%rcx,4),%ymm1 + vmovdqu (%rax),%ymm0 + vmovdqu (%rax,%rsi,4),%ymm4 + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu (%rax,%rdx,4),%ymm1 + vpminsd %ymm4,%ymm1,%ymm3 + vpmaxsd %ymm4,%ymm1,%ymm1 + vpminsd %ymm3,%ymm2,%ymm4 + vpmaxsd %ymm3,%ymm2,%ymm2 + vpminsd %ymm1,%ymm0,%ymm3 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu %ymm4,(%rax) + vmovdqu %ymm2,(%rax,%rdx,4) + vmovdqu %ymm3,(%rax,%rcx,4) + vmovdqu %ymm0,(%rax,%rsi,4) + add $32,%rax + cmp %rax,%rdi + jne .L122 +.L124: add %rbx,%r8 + cmp %r8,%r10 + jg .L121 +.L120: sar $2,%r13 + cmp $15,%r13 + jg .L125 + mov %r13,-80(%rbp) +.L119: cmpq $8,-80(%rbp) + je .L126 +.L129: test %r15,%r15 + jle .L192 + lea (%r15,%r15),%rsi + lea (%rsi,%r15),%rdx + lea 0(,%r15,4),%rcx + lea 0(,%r15,8),%rax + mov -208(%rbp),%r9 + lea (%rcx,%r15),%r8 + lea (%rdx,%rdx),%rdi + sub %r15,%rax + vpcmpeqd %ymm6,%ymm6,%ymm6 +.L132: vmovdqu (%r9,%r15,4),%ymm1 + vmovdqu (%r9),%ymm0 + vmovdqu (%r9,%r8,4),%ymm8 + vpmaxsd %ymm0,%ymm1,%ymm4 + vpminsd %ymm0,%ymm1,%ymm5 + vmovdqu (%r9,%rdx,4),%ymm0 + vmovdqu (%r9,%rsi,4),%ymm1 + vmovdqu (%r9,%rdi,4),%ymm7 + vpminsd %ymm1,%ymm0,%ymm3 + vpmaxsd %ymm1,%ymm0,%ymm1 + vmovdqu (%r9,%rcx,4),%ymm0 + mov -164(%rbp),%r10d + vpminsd %ymm0,%ymm8,%ymm2 + vpmaxsd %ymm0,%ymm8,%ymm8 + vmovdqu (%r9,%rax,4),%ymm0 + vpminsd %ymm7,%ymm0,%ymm10 + vpmaxsd %ymm7,%ymm0,%ymm0 + vpminsd %ymm10,%ymm2,%ymm9 + vpminsd %ymm3,%ymm5,%ymm7 + vpmaxsd %ymm10,%ymm2,%ymm2 + vpmaxsd %ymm3,%ymm5,%ymm5 + vpminsd %ymm1,%ymm4,%ymm3 + vpmaxsd %ymm1,%ymm4,%ymm1 + vpminsd %ymm0,%ymm8,%ymm4 + vpmaxsd %ymm0,%ymm8,%ymm8 + vpminsd %ymm4,%ymm3,%ymm11 + vpminsd %ymm9,%ymm7,%ymm0 + vpmaxsd %ymm4,%ymm3,%ymm3 + vpmaxsd %ymm9,%ymm7,%ymm7 + vpminsd %ymm8,%ymm1,%ymm4 + vpminsd %ymm2,%ymm5,%ymm9 + vpmaxsd %ymm8,%ymm1,%ymm1 + vpmaxsd %ymm2,%ymm5,%ymm2 + vpunpckldq %ymm3,%ymm11,%ymm10 + vpunpckhdq %ymm2,%ymm9,%ymm5 + vpunpckhdq %ymm3,%ymm11,%ymm3 + vpunpckldq %ymm7,%ymm0,%ymm8 + vpunpckldq %ymm2,%ymm9,%ymm11 + vpunpckhdq %ymm7,%ymm0,%ymm0 + vpunpckldq %ymm1,%ymm4,%ymm9 + vpunpckhdq %ymm1,%ymm4,%ymm4 + vpunpcklqdq %ymm5,%ymm0,%ymm2 + vpunpcklqdq %ymm9,%ymm10,%ymm13 + vpunpcklqdq %ymm4,%ymm3,%ymm12 + vpunpcklqdq %ymm11,%ymm8,%ymm7 + vpunpckhqdq %ymm9,%ymm10,%ymm1 + vpunpckhqdq %ymm11,%ymm8,%ymm8 + vpunpckhqdq %ymm4,%ymm3,%ymm4 + vpunpckhqdq %ymm5,%ymm0,%ymm0 + vperm2i128 $32,%ymm12,%ymm2,%ymm10 + vperm2i128 $32,%ymm1,%ymm8,%ymm9 + vperm2i128 $32,%ymm4,%ymm0,%ymm5 + vperm2i128 $32,%ymm13,%ymm7,%ymm11 + vperm2i128 $49,%ymm13,%ymm7,%ymm3 + vperm2i128 $49,%ymm12,%ymm2,%ymm2 + vperm2i128 $49,%ymm1,%ymm8,%ymm1 + vperm2i128 $49,%ymm4,%ymm0,%ymm0 + test %r10d,%r10d + je .L131 + vpxor %ymm6,%ymm11,%ymm11 + vpxor %ymm6,%ymm10,%ymm10 + vpxor %ymm6,%ymm9,%ymm9 + vpxor %ymm6,%ymm5,%ymm5 + vpxor %ymm6,%ymm3,%ymm3 + vpxor %ymm6,%ymm2,%ymm2 + vpxor %ymm6,%ymm1,%ymm1 + vpxor %ymm6,%ymm0,%ymm0 +.L131: vmovdqu %ymm11,(%r9) + vmovdqu %ymm3,(%r9,%r15,4) + vmovdqu %ymm10,(%r9,%rsi,4) + vmovdqu %ymm2,(%r9,%rdx,4) + vmovdqu %ymm9,(%r9,%rcx,4) + vmovdqu %ymm1,(%r9,%r8,4) + vmovdqu %ymm5,(%r9,%rdi,4) + vmovdqu %ymm0,(%r9,%rax,4) + add $32,%r9 + cmp %r9,-160(%rbp) + jne .L132 +.L192: vzeroupper +.L190: add $200,%rsp + pop %rbx + pop %r12 + pop %r13 + pop %r14 + pop %r15 + pop %rbp + lea -16(%r13),%rsp + pop %r13 + ret +.L59: dec %rax + mov %rax,-176(%rbp) + shr $5,%rax + sal $7,%rax + lea 128(%r11,%rax),%rax + mov %rax,-184(%rbp) + vpcmpeqd %ymm0,%ymm0,%ymm0 + mov %r11,%rax +.L64: vpxor 64(%rax),%ymm0,%ymm1 + vpxor (%rax),%ymm0,%ymm2 + vmovdqu %ymm1,64(%rax) + vmovdqu %ymm2,(%rax) + sub $-128,%rax + cmp -184(%rbp),%rax + jne .L64 + mov -176(%rbp),%rdi + lea 64(%r11),%rsi + mov %rdi,%rax + shr $4,%rax + sal $6,%rax + add %rsi,%rax + mov %rax,-208(%rbp) + mov %rdi,%rax + shr $6,%rax + sal $8,%rax + lea 256(%r11,%rax),%rax + mov $4,%ecx + mov %r14,%r8 + mov %rsi,-192(%rbp) + mov %rax,-216(%rbp) + movq $8,-112(%rbp) + vpcmpeqd %ymm11,%ymm11,%ymm11 + mov %r10,%r14 + cmp $64,%rcx + je .L200 +.L68: cmp $32,%rcx + je .L201 + cmp $16,%rcx + je .L74 + cmp $8,%rcx + je .L202 +.L76: mov -112(%rbp),%rdi + xor %edx,%edx + lea (%rdi,%rdi),%rax + cmp %r15,%rax + mov %rax,-152(%rbp) + setne %al + movzbl %al,%eax + mov %eax,-160(%rbp) + lea -1(%rdi),%rax + sete %dl + and $-8,%rax + movq $0,-136(%rbp) + mov %rax,-128(%rbp) + mov %rdi,%r10 + test %r15,%r15 + jle .L73 +.L78: mov -112(%rbp),%rax + mov -136(%rbp),%rdi + add %r10,%rax + cmp %rdi,%rax + jle .L81 + mov %rdi,%rsi + .p2align 4,,10 + .p2align 3 +.L84: mov %rsi,%rcx + mov %rsi,%rdi + add -112(%rbp),%rsi + cmp %rsi,%rcx + jge .L83 + lea (%r11,%rcx,4),%rax + mov %rax,-80(%rbp) + mov -120(%rbp),%rax + add -128(%rbp),%rcx + lea (%rax,%rcx,4),%rcx + mov -80(%rbp),%rax + .p2align 4,,10 + .p2align 3 +.L80: vmovdqu (%rax),%ymm0 + vmovdqu (%rax,%r15,4),%ymm15 + vmovdqu (%rax,%r13,4),%ymm7 + vpminsd %ymm0,%ymm15,%ymm6 + vpmaxsd %ymm0,%ymm15,%ymm15 + vmovdqu (%rax,%r12,4),%ymm0 + vmovdqu (%rax,%r14,4),%ymm5 + vpminsd %ymm0,%ymm7,%ymm1 + vpmaxsd %ymm0,%ymm7,%ymm7 + vmovdqu (%rax,%rbx,4),%ymm0 + vmovdqu (%rax,%r9,4),%ymm4 + vpminsd %ymm0,%ymm5,%ymm9 + vpmaxsd %ymm0,%ymm5,%ymm5 + vmovdqu (%rax,%r8,4),%ymm0 + vpminsd %ymm1,%ymm6,%ymm8 + vpminsd %ymm0,%ymm4,%ymm3 + vpmaxsd %ymm0,%ymm4,%ymm4 + vpminsd %ymm3,%ymm9,%ymm2 + vpmaxsd %ymm4,%ymm5,%ymm0 + vpmaxsd %ymm3,%ymm9,%ymm3 + vpmaxsd %ymm1,%ymm6,%ymm6 + vpminsd %ymm7,%ymm15,%ymm1 + vpmaxsd %ymm7,%ymm15,%ymm15 + vpminsd %ymm4,%ymm5,%ymm7 + vpminsd %ymm2,%ymm8,%ymm14 + vpminsd %ymm7,%ymm1,%ymm13 + vpminsd %ymm3,%ymm6,%ymm12 + vpminsd %ymm0,%ymm15,%ymm10 + vpmaxsd %ymm3,%ymm6,%ymm6 + vpmaxsd %ymm2,%ymm8,%ymm2 + vpmaxsd %ymm7,%ymm1,%ymm1 + vpmaxsd %ymm0,%ymm15,%ymm0 + vmovdqa %ymm6,-80(%rbp) + vmovdqa %ymm6,%ymm3 + vmovdqa %ymm14,%ymm9 + vmovdqa %ymm2,%ymm5 + vmovdqa %ymm13,%ymm8 + vmovdqa %ymm1,%ymm4 + vmovdqa %ymm12,%ymm7 + vmovdqa %ymm10,%ymm6 + vmovdqa %ymm0,%ymm15 + test %edx,%edx + je .L79 + vpxor -80(%rbp),%ymm11,%ymm3 + vpxor %ymm14,%ymm11,%ymm9 + vpxor %ymm13,%ymm11,%ymm8 + vpxor %ymm12,%ymm11,%ymm7 + vpxor %ymm10,%ymm11,%ymm6 + vpxor %ymm2,%ymm11,%ymm5 + vpxor %ymm1,%ymm11,%ymm4 + vpxor %ymm0,%ymm11,%ymm15 +.L79: vmovdqu %ymm9,(%rax) + vmovdqu %ymm8,(%rax,%r15,4) + vmovdqu %ymm7,(%rax,%r12,4) + vmovdqu %ymm6,(%rax,%r13,4) + vmovdqu %ymm5,(%rax,%rbx,4) + vmovdqu %ymm4,(%rax,%r14,4) + vmovdqu %ymm3,(%rax,%r8,4) + vmovdqu %ymm15,(%rax,%r9,4) + add $32,%rax + cmp %rax,%rcx + jne .L80 +.L83: xor $1,%edx + cmp %rdi,%r10 + jg .L84 +.L81: mov -152(%rbp),%rdi + xor -160(%rbp),%edx + add %rdi,-136(%rbp) + add %rdi,%r10 + mov -136(%rbp),%rax + cmp %rax,%r15 + jg .L78 +.L73: mov -112(%rbp),%rax + sal $4,%rax + cmp -144(%rbp),%rax + je .L203 + mov -152(%rbp),%rax + mov %rax,%rcx + sar %rcx + cmp $254,%rax + jle .L66 + mov %r8,-136(%rbp) + mov %r9,-160(%rbp) + mov %r15,-80(%rbp) + mov -144(%rbp),%r15 + mov %rbx,-112(%rbp) + mov %r12,-128(%rbp) + mov %rcx,%rbx + mov %r11,%r12 +.L67: mov %rbx,%rdx + sar $2,%rdx + mov %r15,%rsi + mov %r12,%rdi + vzeroupper + sar $3,%rbx + call int32_threestages + cmp $127,%rbx + vpcmpeqd %ymm11,%ymm11,%ymm11 + jg .L67 + mov %rbx,%rcx + mov %r12,%r11 + mov -80(%rbp),%r15 + mov -112(%rbp),%rbx + mov -128(%rbp),%r12 + mov -136(%rbp),%r8 + mov -160(%rbp),%r9 +.L66: mov -152(%rbp),%rax + mov %rax,-112(%rbp) + cmp $64,%rcx + jne .L68 +.L200: mov -144(%rbp),%rsi + mov %r11,%rdi + vzeroupper + call int32_twostages_32 + vpcmpeqd %ymm11,%ymm11,%ymm11 +.L74: mov %r11,%rax +.L69: vmovdqu 64(%rax),%ymm1 + vmovdqu (%rax),%ymm0 + vmovdqu 96(%rax),%ymm4 + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu 32(%rax),%ymm1 + sub $-128,%rax + vpminsd %ymm4,%ymm1,%ymm3 + vpmaxsd %ymm4,%ymm1,%ymm1 + vpminsd %ymm3,%ymm2,%ymm4 + vpmaxsd %ymm3,%ymm2,%ymm2 + vpminsd %ymm1,%ymm0,%ymm3 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu %ymm4,-128(%rax) + vmovdqu %ymm2,-96(%rax) + vmovdqu %ymm3,-64(%rax) + vmovdqu %ymm0,-32(%rax) + cmp -184(%rbp),%rax + jne .L69 + jmp .L76 +.L202: mov %r11,%rax +.L77: vmovdqu 32(%rax),%ymm0 + vmovdqu (%rax),%ymm1 + add $64,%rax + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu %ymm2,-64(%rax) + vmovdqu %ymm0,-32(%rax) + cmp %rax,-208(%rbp) + jne .L77 + jmp .L76 +.L203: mov %r14,%r10 + mov %r8,%r14 + jmp .L60 +.L201: mov %r11,%rax +.L71: vmovdqu 128(%rax),%ymm0 + vmovdqu (%rax),%ymm6 + vmovdqu 32(%rax),%ymm1 + vpminsd %ymm0,%ymm6,%ymm7 + vpmaxsd %ymm0,%ymm6,%ymm6 + vmovdqu 160(%rax),%ymm0 + vmovdqu 224(%rax),%ymm8 + vpminsd %ymm0,%ymm1,%ymm5 + vpmaxsd %ymm0,%ymm1,%ymm3 + vmovdqu 192(%rax),%ymm1 + vmovdqu 64(%rax),%ymm0 + add $256,%rax + vpminsd %ymm1,%ymm0,%ymm4 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu -160(%rax),%ymm1 + vpminsd %ymm8,%ymm1,%ymm2 + vpmaxsd %ymm8,%ymm1,%ymm1 + vpminsd %ymm4,%ymm7,%ymm8 + vpmaxsd %ymm4,%ymm7,%ymm4 + vpminsd %ymm2,%ymm5,%ymm7 + vpmaxsd %ymm2,%ymm5,%ymm2 + vpminsd %ymm0,%ymm6,%ymm5 + vpmaxsd %ymm0,%ymm6,%ymm0 + vpminsd %ymm1,%ymm3,%ymm6 + vpmaxsd %ymm1,%ymm3,%ymm1 + vpminsd %ymm7,%ymm8,%ymm9 + vpmaxsd %ymm7,%ymm8,%ymm3 + vpminsd %ymm2,%ymm4,%ymm8 + vpminsd %ymm6,%ymm5,%ymm7 + vpmaxsd %ymm2,%ymm4,%ymm2 + vpmaxsd %ymm6,%ymm5,%ymm5 + vpminsd %ymm1,%ymm0,%ymm4 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu %ymm9,-256(%rax) + vmovdqu %ymm3,-224(%rax) + vmovdqu %ymm8,-192(%rax) + vmovdqu %ymm2,-160(%rax) + vmovdqu %ymm7,-128(%rax) + vmovdqu %ymm5,-96(%rax) + vmovdqu %ymm4,-64(%rax) + vmovdqu %ymm0,-32(%rax) + cmp %rax,-216(%rbp) + jne .L71 + jmp .L76 +.L194: mov 4(%rdi),%eax + mov 12(%rdi),%ebx + cmp (%rdi),%eax + cmovg (%rdi),%ecx + cmovg %eax,%r9d + cmp 8(%rdi),%ebx + cmovg 8(%rdi),%eax + cmovg %ebx,%edi + cmp %ecx,%eax + cmovg %ecx,%r8d + cmovg %eax,%eax + cmp %r9d,%edi + cmovg %r9d,%edx + cmovg %edi,%r9d + cmp %eax,%edx + cmovg %eax,%r12d + cmovg %edx,%r10d + mov 20(%r11),%eax + cmp 16(%r11),%eax + cmovg 16(%r11),%esi + cmovg %eax,%ecx + mov 28(%r11),%eax + cmp 24(%r11),%eax + cmovg 24(%r11),%edx + cmovg %eax,%edi + cmp %ecx,%edi + cmovg %ecx,%eax + cmovg %edi,%edi + cmp %esi,%edx + cmovg %esi,%ecx + cmovg %edx,%edx + cmp %r9d,%edi + cmovg %r9d,%ebx + cmovg %edi,%edi + cmp %edx,%eax + cmovg %edx,%esi + cmovg %eax,%edx + mov %edi,(%r11) + cmp %r12d,%esi + cmovg %r12d,%r9d + cmovg %esi,%esi + cmp %r10d,%edx + cmovg %r10d,%eax + cmovg %edx,%edx + cmp %esi,%ebx + cmovg %esi,%r13d + cmovg %ebx,%ebx + cmp %r8d,%ecx + cmovg %r8d,%esi + cmovg %ecx,%ecx + cmp %ecx,%eax + cmovg %ecx,%r8d + cmovg %eax,%eax + mov %esi,28(%r11) + cmp %edx,%ebx + cmovg %edx,%r12d + cmovg %ebx,%ecx + cmp %eax,%r13d + cmovg %eax,%ebx + cmovg %r13d,%edx + mov %ecx,4(%r11) + cmp %r8d,%r9d + cmovg %r8d,%r10d + cmovg %r9d,%eax + mov %r12d,8(%r11) + mov %edx,12(%r11) + mov %ebx,16(%r11) + mov %eax,20(%r11) + mov %r10d,24(%r11) + jmp .L190 +.L126: cmpq $0,-144(%rbp) + jle .L129 + mov %r11,%rax +.L130: vmovdqu 32(%rax),%ymm1 + vmovdqu (%rax),%ymm0 + add $64,%rax + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu %ymm2,-64(%rax) + vmovdqu %ymm0,-32(%rax) + cmp %rax,-128(%rbp) + jne .L130 + jmp .L129 +.L195: vmovdqa .LC0(%rip),%ymm1 + vmovdqa .LC1(%rip),%ymm3 + vpxor 32(%rdi),%ymm1,%ymm2 + vpxor (%rdi),%ymm1,%ymm1 + mov -164(%rbp),%r14d + vpunpckldq %ymm2,%ymm1,%ymm0 + vpunpckhdq %ymm2,%ymm1,%ymm1 + vpunpcklqdq %ymm1,%ymm0,%ymm2 + vpunpckhqdq %ymm1,%ymm0,%ymm0 + vpminsd %ymm2,%ymm0,%ymm1 + vpmaxsd %ymm2,%ymm0,%ymm0 + vpxor %ymm3,%ymm1,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vpunpckldq %ymm0,%ymm1,%ymm4 + vpunpckhdq %ymm0,%ymm1,%ymm0 + vpmaxsd %ymm0,%ymm4,%ymm1 + vpminsd %ymm0,%ymm4,%ymm2 + vpunpcklqdq %ymm1,%ymm2,%ymm0 + vpunpckhqdq %ymm1,%ymm2,%ymm2 + vpunpckldq %ymm2,%ymm0,%ymm1 + vpunpckhdq %ymm2,%ymm0,%ymm0 + vpunpcklqdq %ymm0,%ymm1,%ymm4 + vpunpckhqdq %ymm0,%ymm1,%ymm1 + vpminsd %ymm4,%ymm1,%ymm2 + vpmaxsd %ymm4,%ymm1,%ymm1 + vpunpckldq %ymm1,%ymm2,%ymm0 + vpunpckhdq %ymm1,%ymm2,%ymm1 + vpxor %ymm3,%ymm1,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vperm2i128 $32,%ymm1,%ymm0,%ymm2 + vperm2i128 $49,%ymm1,%ymm0,%ymm0 + vpminsd %ymm2,%ymm0,%ymm1 + vpmaxsd %ymm2,%ymm0,%ymm0 + vperm2i128 $32,%ymm0,%ymm1,%ymm3 + vperm2i128 $49,%ymm0,%ymm1,%ymm0 + vpminsd %ymm3,%ymm0,%ymm2 + vpmaxsd %ymm3,%ymm0,%ymm0 + vpunpcklqdq %ymm0,%ymm2,%ymm1 + vpunpckhqdq %ymm0,%ymm2,%ymm2 + vpunpckldq %ymm2,%ymm1,%ymm0 + vpunpckhdq %ymm2,%ymm1,%ymm1 + vpunpcklqdq %ymm1,%ymm0,%ymm3 + vpunpckhqdq %ymm1,%ymm0,%ymm0 + vpminsd %ymm3,%ymm0,%ymm2 + vpmaxsd %ymm3,%ymm0,%ymm0 + vpunpckldq %ymm0,%ymm2,%ymm1 + vpunpckhdq %ymm0,%ymm2,%ymm0 + vpunpcklqdq %ymm0,%ymm1,%ymm2 + vpunpckhqdq %ymm0,%ymm1,%ymm1 + vpcmpeqd %ymm0,%ymm0,%ymm0 + test %r14d,%r14d + je .L54 + vpxor %ymm0,%ymm1,%ymm1 + mov %edx,%esi +.L55: vmovdqa %ymm2,%ymm0 + mov %r11,%rdi +.L193: add $200,%rsp + pop %rbx + pop %r12 + pop %r13 + pop %r14 + pop %r15 + pop %rbp + lea -16(%r13),%rsp + pop %r13 + jmp merge16_finish +.L197: lea -1(%r15),%rax + mov %rax,-200(%rbp) + lea 32(%rdi),%rax + mov %rax,-120(%rbp) + jmp .L62 +.L196: mov $1,%edx + mov $16,%esi + mov %rdi,-80(%rbp) + call djbsort$avx2_2power + mov -80(%rbp),%r11 + xor %edx,%edx + lea 64(%r11),%r12 + mov $16,%esi + mov %r12,%rdi + call djbsort$avx2_2power + mov -80(%rbp),%r11 + mov -164(%rbp),%r13d + vmovdqu (%r11),%ymm4 + vmovdqu 32(%r11),%ymm1 + vmovdqu 64(%r11),%ymm2 + vmovdqu 96(%r11),%ymm3 + test %r13d,%r13d + je .L57 + vpcmpeqd %ymm0,%ymm0,%ymm0 + vpxor %ymm0,%ymm4,%ymm4 + vpxor %ymm0,%ymm1,%ymm1 + vpxor %ymm0,%ymm2,%ymm2 + vpxor %ymm0,%ymm3,%ymm3 +.L57: mov -164(%rbp),%esi + vpmaxsd %ymm1,%ymm3,%ymm5 + vpminsd %ymm4,%ymm2,%ymm0 + vpminsd %ymm1,%ymm3,%ymm1 + vpmaxsd %ymm4,%ymm2,%ymm4 + mov %r11,%rdi + vmovdqa %ymm4,-112(%rbp) + vmovdqa %ymm5,-80(%rbp) + call merge16_finish + vmovdqa -80(%rbp),%ymm5 + vmovdqa -112(%rbp),%ymm4 + vmovdqa %ymm5,%ymm1 + vmovdqa %ymm4,%ymm0 + mov %r12,%rdi + jmp .L193 +.L54: vpxor %ymm0,%ymm2,%ymm2 + mov %edx,%esi + jmp .L55 + .endfn djbsort$avx2_2power,globl + + .p2align 4 +djbsort$avx2: + push %rbp + mov %rsp,%rbp + push %r15 + mov %rdi,%r15 + push %r14 + mov %rsi,%r14 + push %r13 + push %r12 + push %rbx + and $-32,%rsp + sub $1056,%rsp + cmp $8,%rsi + jle .L265 + blsr %rsi,%rax + je .L220 + lea -8(%rsi),%rax + mov %rax,8(%rsp) + mov $8,%ebx + cmp $8,%rax + jle .L266 + .p2align 4,,10 + .p2align 3 +.L221: mov %rbx,%rax + mov %r14,%r12 + add %rbx,%rbx + sub %rbx,%r12 + cmp %rbx,%r12 + jg .L221 + cmp $128,%rbx + jle .L267 + mov $1,%edx + mov %rbx,%rsi + mov %r15,%rdi + call djbsort$avx2_2power + lea (%r15,%rbx,4),%rdi + mov %r12,%rsi + call djbsort$avx2 + lea 32(%r15),%rax + mov %rax,16(%rsp) + jmp .L230 + .p2align 4,,10 + .p2align 3 +.L228: lea 0(%r13,%r12),%rdx + add %r11,%r12 + sub %r9,%rdx + lea (%r15,%r12,4),%rsi + mov %r8,%rdi + sar $3,%rbx + call minmax_vector + cmp $63,%rbx + jle .L268 +.L230: mov %rbx,%r12 + sar $2,%r12 + mov %r12,%rdx + mov %r14,%rsi + mov %r15,%rdi + call int32_threestages + lea 0(,%r12,4),%rcx + mov %r14,%rdx + sub %rcx,%rdx + lea (%rcx,%rax),%r13 + lea (%r15,%rax,4),%r8 + lea (%r15,%r13,4),%rsi + sub %rax,%rdx + mov %r8,%rdi + mov %rsi,24(%rsp) + mov %rax,%r9 + mov %rax,%r11 + call minmax_vector + cmp %r14,%r13 + mov 24(%rsp),%rsi + lea (%r12,%r12),%r10 + jle .L269 +.L226: mov %r14,%r13 + sub %r10,%r13 + lea (%r11,%r12,2),%rax + mov %r13,%rdx + sub %r9,%rdx + lea (%r15,%rax,4),%rsi + mov %r8,%rdi + call minmax_vector + add %r9,%r10 + cmp %r14,%r10 + jg .L228 + mov %r10,%rax + sub %r12,%rax + mov %r10,%r11 + lea (%r15,%r10,4),%r8 + cmp %rax,%r9 + jge .L247 + sub %r9,%rax + dec %rax + and $-8,%rax + lea (%r15,%r9,4),%rdx + add %rax,%r9 + mov 16(%rsp),%rax + lea (%rax,%r9,4),%rax + .p2align 4,,10 + .p2align 3 +.L229: vmovdqu (%rdx,%r12,4),%ymm0 + vmovdqu (%rdx),%ymm1 + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu %ymm2,(%rdx) + vmovdqu %ymm0,(%rdx,%r12,4) + add $32,%rdx + cmp %rdx,%rax + jne .L229 + mov %r10,%r9 + vzeroupper + jmp .L228 + .p2align 4,,10 + .p2align 3 +.L267: mov %rbx,%rdx + sar $2,%rdx + sar $3,%rbx + lea 0(,%rax,4),%r12 + lea 32(%rsp),%r13 + cmp %rbx,%rdx + jle .L224 + vmovdqa .LC4(%rip),%ymm0 + .p2align 4,,10 + .p2align 3 +.L225: mov %rbx,%rax + sal $5,%rax + inc %rbx + vmovdqa %ymm0,0(%r13,%rax) + cmp %rdx,%rbx + jl .L225 + vzeroupper +.L224: sal $2,%r14 + mov %r14,%rdx + mov %r15,%rsi + mov %r13,%rdi + call memcpy + xor %edx,%edx + mov %r12,%rsi + mov %r13,%rdi + call djbsort$avx2_2power + mov %r14,%rdx + mov %r13,%rsi + mov %r15,%rdi + call memcpy +.L263: lea -40(%rbp),%rsp + pop %rbx + pop %r12 + pop %r13 + pop %r14 + pop %r15 + pop %rbp + ret + .p2align 4,,10 + .p2align 3 +.L269: lea (%r12,%r9),%rax + cmp %rax,%r9 + jge .L246 + notq %r11 + add %r11,%rax + and $-8,%rax + add %rax,%r9 + mov 16(%rsp),%rax + lea (%r10,%r12),%rdx + mov %r8,%rdi + lea (%rax,%r9,4),%rax + .p2align 4,,10 + .p2align 3 +.L227: vmovdqu (%rdi),%ymm1 + vmovdqu (%rdi,%r10,4),%ymm0 + vmovdqu (%rdi,%r12,4),%ymm4 + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu (%rdi,%rdx,4),%ymm1 + vpminsd %ymm4,%ymm1,%ymm3 + vpmaxsd %ymm4,%ymm1,%ymm1 + vpminsd %ymm3,%ymm2,%ymm4 + vpmaxsd %ymm3,%ymm2,%ymm2 + vpminsd %ymm1,%ymm0,%ymm3 + vpmaxsd %ymm1,%ymm0,%ymm0 + vmovdqu %ymm4,(%rdi) + vmovdqu %ymm2,(%rdi,%r12,4) + vmovdqu %ymm3,(%rdi,%r10,4) + vmovdqu %ymm0,(%rdi,%rdx,4) + add $32,%rdi + cmp %rdi,%rax + jne .L227 + mov %rsi,%r8 + mov %r13,%r11 + mov %r13,%r9 + vzeroupper + jmp .L226 + .p2align 4,,10 + .p2align 3 +.L268: cmp $32,%rbx + je .L270 + mov %r15,%r10 + cmp $16,%rbx + je .L249 + mov $32,%ebx + xor %r11d,%r11d + mov $15,%eax + xor %r9d,%r9d +.L237: cmp %rax,%r14 + jle .L239 + mov %r9,%rax + .p2align 4,,10 + .p2align 3 +.L240: vmovdqu 32(%r15,%rax,4),%ymm0 + vmovdqu (%r15,%rax,4),%ymm2 + mov %rax,%rdx + vpminsd %ymm0,%ymm2,%ymm1 + vpmaxsd %ymm0,%ymm2,%ymm2 + vperm2i128 $32,%ymm2,%ymm1,%ymm0 + vperm2i128 $49,%ymm2,%ymm1,%ymm1 + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vperm2i128 $32,%ymm0,%ymm2,%ymm1 + vperm2i128 $49,%ymm0,%ymm2,%ymm2 + vpunpcklqdq %ymm2,%ymm1,%ymm0 + vpunpckhqdq %ymm2,%ymm1,%ymm1 + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vpunpckldq %ymm0,%ymm2,%ymm1 + vpunpckhdq %ymm0,%ymm2,%ymm2 + vpunpcklqdq %ymm2,%ymm1,%ymm0 + vpunpckhqdq %ymm2,%ymm1,%ymm1 + vpminsd %ymm1,%ymm0,%ymm2 + vpmaxsd %ymm1,%ymm0,%ymm0 + vpunpckldq %ymm0,%ymm2,%ymm1 + add $31,%rdx + vpunpckhdq %ymm0,%ymm2,%ymm0 + vmovdqu %ymm1,(%r15,%rax,4) + vmovdqu %ymm0,32(%r15,%rax,4) + add $16,%rax + cmp %rdx,%r14 + jg .L240 + lea -16(%r14),%rax + sub %r9,%rax + lea 15(%r9),%rdx + and $-16,%rax + cmp %rdx,%r14 + mov $0,%edx + cmovle %rdx,%rax + lea 16(%r9,%rax),%r9 + mov %r9,%r11 + lea 32(,%r9,4),%rbx + lea (%r15,%r9,4),%r10 + vzeroupper +.L239: mov 8(%rsp),%rdx + lea (%r15,%rbx),%rsi + sub %r9,%rdx + mov %r10,%rdi + call minmax_vector + lea 16(,%r11,4),%rax + lea 7(%r9),%rdx + lea (%r15,%rax),%rsi + cmp %r14,%rdx + jge .L241 + mov (%r10),%ebx + cmp (%rsi),%ebx + cmovg (%rsi),%ecx + cmovg %ebx,%edx + mov %ecx,(%r10) + mov %edx,(%rsi) + lea -12(%r15,%rax),%rbx + lea 4(%r15,%rax),%rdi + mov (%rbx),%edx + cmp (%rdi),%edx + cmovg (%rdi),%ecx + cmovg %edx,%edx + mov %ecx,(%rbx) + mov %edx,(%rdi) + lea -8(%r15,%rax),%r11 + lea 8(%r15,%rax),%rdx + mov (%r11),%ecx + cmp (%rdx),%ecx + cmovg (%rdx),%r12d + cmovg %ecx,%ecx + mov %r12d,(%r11) + mov %ecx,(%rdx) + lea -4(%r15,%rax),%rcx + lea 12(%r15,%rax),%rax + mov (%rcx),%r13d + cmp (%rax),%r13d + cmovg (%rax),%r8d + cmovg %r13d,%r13d + mov %r8d,(%rcx) + mov %r13d,(%rax) + cmp %r12d,(%r10) + cmovg %r12d,%r13d + cmovg (%r10),%r12d + mov %r13d,(%r10) + mov %r12d,(%r11) + mov (%rbx),%r8d + cmp (%rcx),%r8d + cmovg (%rcx),%r12d + cmovg %r8d,%r13d + mov %r12d,(%rbx) + mov %r13d,(%rcx) + cmp %r12d,(%r10) + cmovg %r12d,%r13d + cmovg (%r10),%r12d + mov %r13d,(%r10) + mov %r12d,(%rbx) + mov (%r11),%r8d + cmp (%rcx),%r8d + cmovg (%rcx),%ebx + cmovg %r8d,%r10d + mov %ebx,(%r11) + mov %r10d,(%rcx) + lea 8(%r9),%r11 + mov (%rsi),%ecx + cmp (%rdx),%ecx + cmovg (%rdx),%r10d + cmovg %ecx,%ecx + mov %r10d,(%rsi) + mov %ecx,(%rdx) + mov (%rdi),%ebx + cmp (%rax),%ebx + cmovg (%rax),%ecx + cmovg %ebx,%r10d + mov %ecx,(%rdi) + mov %r10d,(%rax) + cmp %ecx,(%rsi) + cmovg %ecx,%r10d + cmovg (%rsi),%ecx + mov %r10d,(%rsi) + mov %ecx,(%rdi) + mov (%rdx),%ecx + cmp (%rax),%ecx + cmovg (%rax),%esi + cmovg %ecx,%ecx + mov %esi,(%rdx) + mov %ecx,(%rax) + lea 48(,%r9,4),%rax + lea (%r15,%rax),%rsi + lea -16(%r15,%rax),%r10 + mov %r11,%r9 +.L241: lea -4(%r14),%rdx + sub %r9,%rdx + mov %r10,%rdi + call minmax_vector + lea 3(%r9),%rax + cmp %r14,%rax + jge .L242 + lea 8(,%r11,4),%rax + lea (%r15,%rax),%rdx + mov (%r10),%ecx + cmp (%rdx),%ecx + cmovg (%rdx),%esi + cmovg %ecx,%ecx + mov %esi,(%r10) + mov %ecx,(%rdx) + lea -4(%r15,%rax),%rsi + lea 4(%r15,%rax),%rax + mov (%rsi),%ebx + cmp (%rax),%ebx + cmovg (%rax),%ecx + cmovg %ebx,%edi + mov %ecx,(%rsi) + mov %edi,(%rax) + cmp %ecx,(%r10) + cmovg %ecx,%edi + cmovg (%r10),%ecx + mov %edi,(%r10) + mov %ecx,(%rsi) + add $4,%r9 + mov (%rdx),%ecx + cmp (%rax),%ecx + cmovg (%rax),%esi + cmovg %ecx,%ecx + mov %esi,(%rdx) + mov %ecx,(%rax) +.L242: lea 2(%r9),%rax + cmp %r14,%rax + jge .L243 + lea 0(,%r9,4),%rax + lea (%r15,%rax),%rdx + lea 8(%r15,%rax),%rax + mov (%rdx),%ecx + cmp (%rax),%ecx + cmovg (%rax),%esi + cmovg %ecx,%ecx + mov %esi,(%rdx) + mov %ecx,(%rax) +.L243: lea 1(%r9),%rax + cmp %r14,%rax + jge .L263 + sal $2,%r9 + lea (%r15,%r9),%rdx + lea 4(%r15,%r9),%rax + mov (%rdx),%ecx + cmp (%rax),%ecx + cmovg (%rax),%esi + cmovg %ecx,%ecx + mov %esi,(%rdx) + mov %ecx,(%rax) + lea -40(%rbp),%rsp + pop %rbx + pop %r12 + pop %r13 + pop %r14 + pop %r15 + pop %rbp + ret + .p2align 4,,10 + .p2align 3 +.L265: je .L271 + cmp $7,%rsi + je .L272 + cmp $6,%rsi + je .L273 + cmp $5,%rsi + je .L274 + cmp $4,%rsi + je .L275 + cmp $3,%rsi + je .L276 + cmp $2,%rsi + jne .L263 + mov (%rdi),%edx + mov 4(%rdi),%ecx + jmp .L217 + .p2align 4,,10 + .p2align 3 +.L271: mov (%rdi),%ecx + cmp 4(%rdi),%ecx + cmovg 4(%rdi),%eax + cmovg %ecx,%ecx + mov %eax,%edx + cmp 8(%rdi),%ecx + cmovg 8(%rdi),%eax + cmovg %ecx,%ecx + mov %eax,%esi + cmp 12(%rdi),%ecx + cmovg 12(%rdi),%eax + cmovg %ecx,%ecx + mov %eax,%r9d + cmp 16(%rdi),%ecx + cmovg 16(%rdi),%eax + cmovg %ecx,%ecx + mov %eax,%edi + cmp 20(%r15),%ecx + cmovg 20(%r15),%eax + cmovg %ecx,%ecx + mov %eax,%r8d + cmp 24(%r15),%ecx + cmovg 24(%r15),%eax + cmovg %ecx,%ecx + mov %eax,%r10d + cmp 28(%r15),%ecx + cmovg 28(%r15),%eax + cmovg %ecx,%ecx + mov %ecx,28(%r15) + mov %eax,%r11d +.L207: cmp %esi,%edx + cmovg %esi,%ecx + cmovg %edx,%eax + cmp %r9d,%eax + cmovg %r9d,%esi + cmovg %eax,%eax + cmp %edi,%eax + cmovg %edi,%r9d + cmovg %eax,%eax + cmp %r8d,%eax + cmovg %r8d,%edi + cmovg %eax,%eax + cmp %r10d,%eax + cmovg %r10d,%r8d + cmovg %eax,%eax + cmp %r11d,%eax + cmovg %r11d,%r10d + cmovg %eax,%eax + mov %eax,24(%r15) + mov %ecx,%edx +.L209: cmp %esi,%edx + cmovg %esi,%ecx + cmovg %edx,%edx + cmp %r9d,%edx + cmovg %r9d,%esi + cmovg %edx,%eax + cmp %edi,%eax + cmovg %edi,%r9d + cmovg %eax,%eax + cmp %r8d,%eax + cmovg %r8d,%edi + cmovg %eax,%eax + cmp %r10d,%eax + cmovg %r10d,%r8d + cmovg %eax,%eax + mov %eax,20(%r15) +.L211: cmp %esi,%ecx + cmovg %esi,%edx + cmovg %ecx,%ecx + cmp %r9d,%ecx + cmovg %r9d,%esi + cmovg %ecx,%eax + mov %esi,%ecx + cmp %edi,%eax + cmovg %edi,%esi + cmovg %eax,%eax + cmp %r8d,%eax + cmovg %r8d,%edi + cmovg %eax,%eax + mov %eax,16(%r15) +.L213: cmp %ecx,%edx + cmovg %ecx,%eax + cmovg %edx,%edx + cmp %esi,%edx + cmovg %esi,%ecx + cmovg %edx,%edx + cmp %edi,%edx + cmovg %edi,%esi + cmovg %edx,%edx + mov %edx,12(%r15) +.L215: cmp %ecx,%eax + cmovg %ecx,%edx + cmovg %eax,%eax + cmp %esi,%eax + cmovg %esi,%ecx + cmovg %eax,%eax + mov %eax,8(%r15) +.L217: cmp %ecx,%edx + cmovg %ecx,%eax + cmovg %edx,%edx + mov %eax,(%r15) + mov %edx,4(%r15) + lea -40(%rbp),%rsp + pop %rbx + pop %r12 + pop %r13 + pop %r14 + pop %r15 + pop %rbp + ret +.L249: mov $64,%r12d + mov $32,%ebx + xor %r11d,%r11d + mov $31,%r8d + xor %r9d,%r9d +.L236: lea (%r15,%r9,4),%rax + mov %r9,%rcx + cmp %r8,%r14 + jle .L235 + .p2align 4,,10 + .p2align 3 +.L238: vmovdqu 64(%rax),%ymm1 + vmovdqu 96(%rax),%ymm3 + vmovdqu (%rax),%ymm0 + vmovdqu 32(%rax),%ymm2 + vpminsd %ymm1,%ymm0,%ymm5 + vpmaxsd %ymm1,%ymm0,%ymm0 + vpminsd %ymm3,%ymm2,%ymm1 + vpmaxsd %ymm3,%ymm2,%ymm2 + vpminsd %ymm2,%ymm0,%ymm4 + vpminsd %ymm1,%ymm5,%ymm3 + vpmaxsd %ymm2,%ymm0,%ymm0 + vpmaxsd %ymm1,%ymm5,%ymm5 + vperm2i128 $32,%ymm0,%ymm4,%ymm2 + vperm2i128 $32,%ymm5,%ymm3,%ymm1 + vperm2i128 $49,%ymm0,%ymm4,%ymm0 + vperm2i128 $49,%ymm5,%ymm3,%ymm3 + vpminsd %ymm3,%ymm1,%ymm5 + vpminsd %ymm0,%ymm2,%ymm4 + vpmaxsd %ymm3,%ymm1,%ymm1 + vpmaxsd %ymm0,%ymm2,%ymm0 + vperm2i128 $32,%ymm1,%ymm5,%ymm3 + vperm2i128 $32,%ymm0,%ymm4,%ymm2 + vperm2i128 $49,%ymm1,%ymm5,%ymm5 + vperm2i128 $49,%ymm0,%ymm4,%ymm4 + vpunpcklqdq %ymm5,%ymm3,%ymm1 + vpunpcklqdq %ymm4,%ymm2,%ymm0 + vpunpckhqdq %ymm5,%ymm3,%ymm3 + vpunpckhqdq %ymm4,%ymm2,%ymm2 + vpminsd %ymm3,%ymm1,%ymm5 + vpminsd %ymm2,%ymm0,%ymm4 + vpmaxsd %ymm3,%ymm1,%ymm1 + vpmaxsd %ymm2,%ymm0,%ymm0 + vpunpckldq %ymm1,%ymm5,%ymm3 + vpunpckldq %ymm0,%ymm4,%ymm2 + vpunpckhdq %ymm1,%ymm5,%ymm5 + vpunpckhdq %ymm0,%ymm4,%ymm4 + vpunpcklqdq %ymm5,%ymm3,%ymm1 + vpunpcklqdq %ymm4,%ymm2,%ymm0 + vpunpckhqdq %ymm5,%ymm3,%ymm3 + vpunpckhqdq %ymm4,%ymm2,%ymm2 + mov %rcx,%rdx + vpminsd %ymm3,%ymm1,%ymm4 + vpmaxsd %ymm3,%ymm1,%ymm1 + vpminsd %ymm2,%ymm0,%ymm3 + vpmaxsd %ymm2,%ymm0,%ymm0 + vpunpckldq %ymm1,%ymm4,%ymm5 + vpunpckldq %ymm0,%ymm3,%ymm2 + vpunpckhdq %ymm1,%ymm4,%ymm1 + vpunpckhdq %ymm0,%ymm3,%ymm0 + add $63,%rdx + vmovdqu %ymm5,(%rax) + vmovdqu %ymm1,32(%rax) + vmovdqu %ymm2,64(%rax) + vmovdqu %ymm0,96(%rax) + add $32,%rcx + sub $-128,%rax + cmp %rdx,%r14 + jg .L238 + lea -32(%r14),%rax + sub %r9,%rax + lea 31(%r9),%rdx + and $-32,%rax + cmp %rdx,%r14 + mov $0,%edx + cmovle %rdx,%rax + lea 32(%r9,%rax),%r9 + lea 64(,%r9,4),%r12 + mov %r9,%r11 + lea (%r15,%r9,4),%r10 + lea -32(%r12),%rbx + vzeroupper +.L235: lea -16(%r14),%rdx + sub %r9,%rdx + lea (%r15,%r12),%rsi + mov %r10,%rdi + call minmax_vector + lea 15(%r9),%rax + jmp .L237 + .p2align 4,,10 + .p2align 3 +.L220: xor %edx,%edx + call djbsort$avx2_2power + lea -40(%rbp),%rsp + pop %rbx + pop %r12 + pop %r13 + pop %r14 + pop %r15 + pop %rbp + ret + .p2align 4,,10 + .p2align 3 +.L246: mov %rsi,%r8 + mov %r13,%r11 + mov %r13,%r9 + jmp .L226 + .p2align 4,,10 + .p2align 3 +.L247: mov %r10,%r9 + jmp .L228 + .p2align 4,,10 + .p2align 3 +.L266: vmovdqa .LC4(%rip),%ymm0 + mov $16,%r12d + lea 32(%rsp),%r13 + vmovdqa %ymm0,64(%rsp) + vzeroupper + jmp .L224 + .p2align 4,,10 + .p2align 3 +.L270: cmp $63,%r14 + jle .L248 + lea -64(%r14),%rcx + shr $6,%rcx + mov %rcx,%rdx + sal $8,%rdx + mov %r15,%rax + lea 256(%r15,%rdx),%rdx + .p2align 4,,10 + .p2align 3 +.L233: vmovdqu 128(%rax),%ymm0 + vmovdqu (%rax),%ymm3 + vmovdqu 32(%rax),%ymm15 + vpminsd %ymm0,%ymm3,%ymm13 + vpmaxsd %ymm0,%ymm3,%ymm3 + vmovdqu 160(%rax),%ymm0 + vmovdqu 224(%rax),%ymm2 + vmovdqu 64(%rax),%ymm6 + vmovdqu 96(%rax),%ymm5 + vpminsd %ymm0,%ymm15,%ymm4 + vpmaxsd %ymm0,%ymm15,%ymm15 + vmovdqu 192(%rax),%ymm0 + add $256,%rax + vpminsd %ymm0,%ymm6,%ymm1 + vpmaxsd %ymm0,%ymm6,%ymm6 + vpminsd %ymm2,%ymm5,%ymm0 + vpmaxsd %ymm2,%ymm5,%ymm5 + vpminsd %ymm0,%ymm4,%ymm11 + vpminsd %ymm1,%ymm13,%ymm14 + vpmaxsd %ymm0,%ymm4,%ymm4 + vpminsd %ymm5,%ymm15,%ymm12 + vpminsd %ymm6,%ymm3,%ymm0 + vpmaxsd %ymm5,%ymm15,%ymm15 + vpmaxsd %ymm6,%ymm3,%ymm3 + vpmaxsd %ymm1,%ymm13,%ymm13 + vpminsd %ymm15,%ymm3,%ymm8 + vpminsd %ymm4,%ymm13,%ymm1 + vpminsd %ymm12,%ymm0,%ymm5 + vpmaxsd %ymm4,%ymm13,%ymm13 + vpminsd %ymm11,%ymm14,%ymm2 + vpmaxsd %ymm12,%ymm0,%ymm12 + vpmaxsd %ymm11,%ymm14,%ymm14 + vpmaxsd %ymm15,%ymm3,%ymm3 + vperm2i128 $32,%ymm14,%ymm2,%ymm11 + vperm2i128 $32,%ymm13,%ymm1,%ymm10 + vperm2i128 $32,%ymm12,%ymm5,%ymm9 + vperm2i128 $49,%ymm12,%ymm5,%ymm0 + vperm2i128 $32,%ymm3,%ymm8,%ymm4 + vperm2i128 $49,%ymm14,%ymm2,%ymm2 + vperm2i128 $49,%ymm13,%ymm1,%ymm1 + vperm2i128 $49,%ymm3,%ymm8,%ymm3 + vpminsd %ymm2,%ymm11,%ymm15 + vpminsd %ymm1,%ymm10,%ymm14 + vpmaxsd %ymm2,%ymm11,%ymm2 + vpmaxsd %ymm1,%ymm10,%ymm1 + vpminsd %ymm0,%ymm9,%ymm13 + vpminsd %ymm3,%ymm4,%ymm12 + vpmaxsd %ymm0,%ymm9,%ymm0 + vpmaxsd %ymm3,%ymm4,%ymm8 + vperm2i128 $49,%ymm2,%ymm15,%ymm11 + vperm2i128 $49,%ymm1,%ymm14,%ymm10 + vperm2i128 $49,%ymm0,%ymm13,%ymm9 + vperm2i128 $32,%ymm2,%ymm15,%ymm7 + vperm2i128 $32,%ymm1,%ymm14,%ymm6 + vperm2i128 $32,%ymm0,%ymm13,%ymm5 + vperm2i128 $32,%ymm8,%ymm12,%ymm4 + vperm2i128 $49,%ymm8,%ymm12,%ymm8 + vpunpcklqdq %ymm11,%ymm7,%ymm3 + vpunpcklqdq %ymm10,%ymm6,%ymm2 + vpunpcklqdq %ymm9,%ymm5,%ymm1 + vpunpcklqdq %ymm8,%ymm4,%ymm0 + vpunpckhqdq %ymm11,%ymm7,%ymm7 + vpunpckhqdq %ymm10,%ymm6,%ymm6 + vpunpckhqdq %ymm9,%ymm5,%ymm5 + vpunpckhqdq %ymm8,%ymm4,%ymm4 + vpminsd %ymm3,%ymm7,%ymm11 + vpminsd %ymm2,%ymm6,%ymm10 + vpminsd %ymm1,%ymm5,%ymm9 + vpminsd %ymm0,%ymm4,%ymm8 + vpmaxsd %ymm3,%ymm7,%ymm7 + vpmaxsd %ymm2,%ymm6,%ymm6 + vpmaxsd %ymm1,%ymm5,%ymm5 + vpmaxsd %ymm0,%ymm4,%ymm4 + vpunpckldq %ymm7,%ymm11,%ymm3 + vpunpckldq %ymm6,%ymm10,%ymm2 + vpunpckhdq %ymm7,%ymm11,%ymm7 + vpunpckhdq %ymm6,%ymm10,%ymm6 + vpunpckldq %ymm5,%ymm9,%ymm1 + vpunpckldq %ymm4,%ymm8,%ymm0 + vpunpckhdq %ymm5,%ymm9,%ymm5 + vpunpckhdq %ymm4,%ymm8,%ymm4 + vpunpcklqdq %ymm7,%ymm3,%ymm10 + vpunpcklqdq %ymm5,%ymm1,%ymm8 + vpunpckhqdq %ymm7,%ymm3,%ymm3 + vpunpcklqdq %ymm6,%ymm2,%ymm9 + vpunpcklqdq %ymm4,%ymm0,%ymm7 + vpunpckhqdq %ymm6,%ymm2,%ymm2 + vpunpckhqdq %ymm5,%ymm1,%ymm1 + vpunpckhqdq %ymm4,%ymm0,%ymm0 + vpminsd %ymm8,%ymm1,%ymm5 + vpminsd %ymm9,%ymm2,%ymm6 + vpminsd %ymm7,%ymm0,%ymm4 + vpminsd %ymm10,%ymm3,%ymm11 + vpmaxsd %ymm8,%ymm1,%ymm1 + vpmaxsd %ymm7,%ymm0,%ymm0 + vpmaxsd %ymm10,%ymm3,%ymm3 + vpmaxsd %ymm9,%ymm2,%ymm2 + vpunpckldq %ymm2,%ymm6,%ymm7 + vpunpckldq %ymm3,%ymm11,%ymm8 + vpunpckhdq %ymm2,%ymm6,%ymm2 + vpunpckhdq %ymm3,%ymm11,%ymm3 + vpunpckldq %ymm1,%ymm5,%ymm6 + vpunpckhdq %ymm1,%ymm5,%ymm1 + vpunpckldq %ymm0,%ymm4,%ymm5 + vpunpckhdq %ymm0,%ymm4,%ymm0 + vmovdqu %ymm8,-256(%rax) + vmovdqu %ymm3,-224(%rax) + vmovdqu %ymm7,-192(%rax) + vmovdqu %ymm2,-160(%rax) + vmovdqu %ymm6,-128(%rax) + vmovdqu %ymm1,-96(%rax) + vmovdqu %ymm5,-64(%rax) + vmovdqu %ymm0,-32(%rax) + cmp %rax,%rdx + jne .L233 + lea 1(%rcx),%rax + mov %rax,%r9 + sal $6,%r9 + lea 128(,%r9,4),%rcx + sal $8,%rax + mov %r9,%r11 + lea (%r15,%rax),%r10 + lea -96(%rcx),%rbx + lea -64(%rcx),%r12 + lea 31(%r9),%r8 + vzeroupper +.L232: lea -32(%r14),%rdx + sub %r9,%rdx + lea (%r15,%rcx),%rsi + mov %r10,%rdi + call minmax_vector + jmp .L236 +.L272: mov (%rdi),%edx + mov 4(%rdi),%esi + mov 8(%rdi),%r9d + mov 16(%r15),%r8d + mov 12(%rdi),%edi + mov 20(%r15),%r10d + mov 24(%r15),%r11d + jmp .L207 +.L248: mov %r15,%r10 + mov $64,%r12d + mov $32,%ebx + mov $31,%r8d + mov $128,%ecx + xor %r11d,%r11d + xor %r9d,%r9d + jmp .L232 +.L276: mov (%rdi),%eax + mov 4(%rdi),%ecx + mov 8(%rdi),%esi + jmp .L215 +.L275: mov (%rdi),%edx + mov 4(%rdi),%ecx + mov 8(%rdi),%esi + mov 12(%rdi),%edi + jmp .L213 +.L274: mov (%rdi),%ecx + mov 4(%rdi),%esi + mov 8(%rdi),%r9d + mov 16(%r15),%r8d + mov 12(%rdi),%edi + jmp .L211 +.L273: mov (%rdi),%edx + mov 4(%rdi),%esi + mov 8(%rdi),%r9d + mov 16(%r15),%r8d + mov 12(%rdi),%edi + mov 20(%r15),%r10d + jmp .L209 + .endfn djbsort$avx2,globl + + .rodata.cst32 +.LC0: .quad -1,0,-1,0 +.LC1: .quad 0,-1,-1,0 +.LC2: .quad -1,-1,0,0 +.LC3: .quad -4294967296,4294967295,-4294967296,4294967295 +.LC4: .quad 0x7fffffff7fffffff,0x7fffffff7fffffff + .quad 0x7fffffff7fffffff,0x7fffffff7fffffff diff --git a/libc/alg/djbsort.c b/libc/alg/djbsort.c new file mode 100644 index 00000000..895b6c7a --- /dev/null +++ b/libc/alg/djbsort.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/nexgen32e/nexgen32e.h" +#include "libc/nexgen32e/x86feature.h" + +void djbsort$avx2(int32_t *, long); + +/** + * D.J. Bernstein's fast integer sorting algorithm. + */ +void djbsort(size_t n, int32_t *a) { + if (X86_HAVE(AVX2)) { + djbsort$avx2(a, n); + } else { + insertionsort(n, a); + } +} diff --git a/libc/alg/insertionsort.h b/libc/alg/insertionsort.h new file mode 100644 index 00000000..97c37bd7 --- /dev/null +++ b/libc/alg/insertionsort.h @@ -0,0 +1,34 @@ +#ifndef COSMOPOLITAN_LIBC_ALG_INSERTIONSORT_H_ +#define COSMOPOLITAN_LIBC_ALG_INSERTIONSORT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define siftbackwards(C, X, V, i) \ + do { \ + autotype(V) V_ = (V); \ + for (autotype(i) j = (i); j && C(&V_[j - 1], &V_[j]) > 0; --j) { \ + X(&V_[j - 1], &V_[j]); \ + } \ + } while (0) + +#if 0 +/** + * Tiny in-place quadratic sorting algorithm. + * + * The only advantage to insertion sort is saving on code size when + * there's a strong level of certainty the array won't have more than + * sixteen items. Sometimes Insertion Sort is favored for sorting data + * that's almost sorted. SmoothSort should be a better choice (see + * qsort()) since it has that advantage and a linearithmic worst-case. + */ +#endif +#define INSERTIONSORT(C, X, A, n) \ + do { \ + autotype(A) A_ = (A); \ + autotype(n) n_ = (n); \ + for (autotype(n) i = 1; i < n_; ++i) { \ + siftbackwards(C, X, A_, i); \ + } \ + } while (0) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_ALG_INSERTIONSORT_H_ */ diff --git a/libc/alg/internal.h b/libc/alg/internal.h new file mode 100644 index 00000000..6a3bab98 --- /dev/null +++ b/libc/alg/internal.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_ALG_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_ALG_INTERNAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct CritbitNode { + void *child[2]; + uint32_t byte; + unsigned otherbits; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_ALG_INTERNAL_H_ */ diff --git a/libc/alg/memmem.c b/libc/alg/memmem.c new file mode 100644 index 00000000..bfa0e7f2 --- /dev/null +++ b/libc/alg/memmem.c @@ -0,0 +1,97 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/macros.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" +/* clang-format off */ + +static void KnuthMorrisPrattInit(m, T, W) + ssize_t m, T[m + 1]; + const char W[m]; +{ + ssize_t i = 2; + ssize_t j = 0; + T[0] = -1; + T[1] = 0; + while (i < m) { + if (W[i - 1] == W[j]) { + T[i++] = j++ + 1; + } else if (j > 0) { + j = T[j]; + } else { + T[i++] = 0; + } + } + T[m] = 0; +} + +static size_t KnuthMorrisPratt(m, T, W, n, S) + const long n, m, T[m + 1]; + const char W[m], S[n]; +{ + long i = 0, j = 0; + while (i + j < n) { + if (W[i] == S[i + j]) { + i++; + if (i == m) break; + } else { + j = j + i - T[i]; + if (i > 0) i = T[i]; + } + } + return j; +} + +/* clang-format on */ + +/** + * Searches for fixed-length substring in memory region. + * + * @param haystack is the region of memory to be searched + * @param haystacklen is its character count + * @param needle contains the memory for which we're searching + * @param needlelen is its character count + * @return pointer to first result or NULL if not found + */ +void *(memmem)(const void *haystack_, size_t haystacklen, const void *needle_, + size_t needlelen) { + const char *haystack, *needle, *h; + haystack = haystack_; + needle = needle_; + if (needlelen > haystacklen) return NULL; + if (!needlelen) return (/*unconst*/ void *)haystack; + h = memchr(haystack, *needle, haystacklen); + if (!h || needlelen == 1) return (/*unconst*/ void *)h; + haystacklen -= h - haystack; + long stacktmp[16]; + void *freeme = NULL; + long *T = (needlelen + 1 < ARRAYLEN(stacktmp)) + ? &stacktmp[0] + : (freeme = malloc((needlelen + 1) * sizeof(long))); + KnuthMorrisPrattInit(needlelen, T, needle); + size_t i = KnuthMorrisPratt(needlelen, T, needle, haystacklen, h); + free(freeme); + if (i < haystacklen) { + return (/*unconst*/ char *)h + i * sizeof(char); + } else { + return NULL; + } +} diff --git a/libc/alg/memmem16.c b/libc/alg/memmem16.c new file mode 100644 index 00000000..b02af623 --- /dev/null +++ b/libc/alg/memmem16.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" + +#undef memmem +#undef memchr +#define char char16_t +#define memmem memmem16 +#define memchr memchr16 + +#include "libc/alg/memmem.c" diff --git a/libc/alg/qsort.c b/libc/alg/qsort.c new file mode 100644 index 00000000..5d1dda34 --- /dev/null +++ b/libc/alg/qsort.c @@ -0,0 +1,243 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╚──────────────────────────────────────────────────────────────────────────────╝ +│ Copyright (C) 2011 by Valentin Ochs │ +│ │ +│ Permission is hereby granted, free of charge, to any person obtaining a copy │ +│ of this software and associated documentation files (the "Software"), to │ +│ deal in the Software without restriction, including without limitation the │ +│ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or │ +│ sell copies of the Software, and to permit persons to whom the Software is │ +│ furnished to do so, subject to the following conditions: │ +│ │ +│ The above copyright notice and this permission notice shall be included in │ +│ all copies or substantial portions of the Software. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR │ +│ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, │ +│ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE │ +│ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER │ +│ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING │ +│ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS │ +│ IN THE SOFTWARE. │ +└─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/assert.h" +#include "libc/nexgen32e/bsf.h" +#include "libc/str/str.h" + +asm(".ident\t\"\\n\\n\ +Smoothsort (MIT License)\\n\ +Copyright 2011 Valentin Ochs\\n\ +Discovered by Edsger Dijkstra\""); +asm(".include \"libc/disclaimer.inc\""); + +typedef int (*cmpfun)(const void *, const void *, void *); + +forceinline unsigned bsfz0(unsigned x) { + if (x) { + return bsf(x); + } else { + return 0; + } +} + +forceinline unsigned pntz(unsigned p[2]) { + unsigned r; + assert(p[0] != 0); + r = bsfz0(p[0] - 1); + if (r != 0 || + (r = 8 * sizeof(unsigned) + bsfz0(p[1])) != 8 * sizeof(unsigned)) { + return r; + } + return 0; +} + +static void cycle(size_t width, unsigned char *ar[], size_t n) { + unsigned i, l; + unsigned char tmp[256]; + if (n < 2) return; + ar[n] = tmp; + while (width) { + l = sizeof(tmp) < width ? sizeof(tmp) : width; + memcpy(ar[n], ar[0], l); + for (i = 0; i < n; i++) { + memcpy(ar[i], ar[i + 1], l); + ar[i] += l; + } + width -= l; + } +} + +forceinline void shl(unsigned p[2], size_t n) { + assert(n > 0); + if (n >= 8 * sizeof(unsigned)) { + n -= 8 * sizeof(unsigned); + p[1] = p[0]; + p[0] = 0; + } + p[1] <<= n; + p[1] |= p[0] >> (sizeof(unsigned) * 8 - n); + p[0] <<= n; +} + +forceinline void shr(unsigned p[2], size_t n) { + assert(n > 0); + if (n >= 8 * sizeof(unsigned)) { + n -= 8 * sizeof(unsigned); + p[0] = p[1]; + p[1] = 0; + } + p[0] >>= n; + p[0] |= p[1] << (sizeof(unsigned) * 8 - n); + p[1] >>= n; +} + +static void sift(unsigned char *head, cmpfun cmp, void *arg, int pshift, + unsigned char *ar[hasatleast 14 * sizeof(unsigned) + 1], + unsigned lp[hasatleast 12 * sizeof(unsigned)], size_t width) { + unsigned i; + unsigned char *rt, *lf; + i = 1; + ar[0] = head; + while (pshift > 1) { + rt = head - width; + lf = head - width - lp[pshift - 2]; + if ((*cmp)(ar[0], lf, arg) >= 0 && (*cmp)(ar[0], rt, arg) >= 0) { + break; + } + if ((*cmp)(lf, rt, arg) >= 0) { + ar[i++] = lf; + head = lf; + pshift -= 1; + } else { + ar[i++] = rt; + head = rt; + pshift -= 2; + } + } + cycle(width, ar, i); +} + +static void trinkle(unsigned char *head, cmpfun cmp, void *arg, unsigned pp[2], + unsigned char *ar[hasatleast 14 * sizeof(unsigned) + 1], + unsigned lp[hasatleast 12 * sizeof(unsigned)], size_t width, + int pshift, int trusty) { + unsigned p[2]; + unsigned i, trail; + unsigned char *stepson, *rt, *lf; + i = 1; + p[0] = pp[0]; + p[1] = pp[1]; + ar[0] = head; + while (p[0] != 1 || p[1] != 0) { + stepson = head - lp[pshift]; + if ((*cmp)(stepson, ar[0], arg) <= 0) { + break; + } + if (!trusty && pshift > 1) { + rt = head - width; + lf = head - width - lp[pshift - 2]; + if ((*cmp)(rt, stepson, arg) >= 0 || (*cmp)(lf, stepson, arg) >= 0) { + break; + } + } + ar[i++] = stepson; + head = stepson; + trail = pntz(p); + shr(p, trail); + pshift += trail; + trusty = 0; + } + if (!trusty) { + cycle(width, ar, i); + sift(head, cmp, arg, pshift, ar, lp, width); + } +} + +/** + * Smoothsort is an adaptive linearithmic sorting algorithm that's + * nearly linear on mostly-sorted data, and consumes constant memory. + */ +static noinline void smoothsort( + void *base, size_t count, size_t width, cmpfun cmp, void *arg, + unsigned lp[hasatleast 12 * sizeof(unsigned)], + unsigned char *ar[hasatleast 14 * sizeof(unsigned) + 1]) { + unsigned i, size = width * count; + unsigned char *head, *high; + unsigned p[2] = {1, 0}; + unsigned pshift = 1; + unsigned trail; + if (!size) return; + head = (unsigned char *)base; + high = head + size - width; + /* Precompute Leonardo numbers, scaled by element width */ + for (lp[0] = lp[1] = width, i = 2; + (lp[i] = lp[i - 2] + lp[i - 1] + width) < size; i++) { + } + while (head < high) { + if ((p[0] & 3) == 3) { + sift(head, cmp, arg, pshift, ar, lp, width); + shr(p, 2); + pshift += 2; + } else { + if (lp[pshift - 1] >= high - head) { + trinkle(head, cmp, arg, p, ar, lp, width, pshift, 0); + } else { + sift(head, cmp, arg, pshift, ar, lp, width); + } + if (pshift == 1) { + shl(p, 1); + pshift = 0; + } else { + shl(p, pshift - 1); + pshift = 1; + } + } + p[0] |= 1; + head += width; + } + trinkle(head, cmp, arg, p, ar, lp, width, pshift, 0); + while (pshift != 1 || p[0] != 1 || p[1] != 0) { + if (pshift <= 1) { + trail = pntz(p); + shr(p, trail); + pshift += trail; + } else { + shl(p, 2); + pshift -= 2; + p[0] ^= 7; + shr(p, 1); + trinkle(head - lp[pshift] - width, cmp, arg, p, ar, lp, width, pshift + 1, + 1); + shl(p, 1); + p[0] |= 1; + trinkle(head - width, cmp, arg, p, ar, lp, width, pshift, 1); + } + head -= width; + } +} + +/** + * Sorts array. + * + * @param base points to an array to sort in-place + * @param count is the item count + * @param width is the size of each item + * @param cmp is a callback returning <0, 0, or >0 + * @param arg will optionally be passed as the third argument to cmp + */ +void qsort_r(void *base, size_t count, size_t width, cmpfun cmp, void *arg) { + unsigned lp[12 * sizeof(unsigned)]; + unsigned char *ar[14 * sizeof(unsigned) + 1]; + smoothsort(base, count, width, (cmpfun)cmp, arg, lp, ar); +} + +/** + * Sorts array. + * @see qsort_r() for further details + */ +void qsort(void *base, size_t count, size_t width, + int cmp(const void *, const void *)) { + qsort_r(base, count, width, (cmpfun)cmp, NULL); +} diff --git a/libc/alg/replacestr.c b/libc/alg/replacestr.c new file mode 100644 index 00000000..cfea0654 --- /dev/null +++ b/libc/alg/replacestr.c @@ -0,0 +1,64 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/alg/arraylist2.h" +#include "libc/bits/safemacros.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +/** + * Replaces all instances of NEEDLE in S with REPLACEMENT. + * + * @param needle can't be empty + * @return newly allocated memory that must be free()'d or NULL w/ errno + * @error ENOMEM, EINVAL + */ +char *(replacestr)(const char *s, const char *needle, const char *replacement) { + char *p1, *p2, *res_p; + size_t left, nlen, rlen, res_i, res_n; + if (*needle) { + p1 = s; + left = strlen(s); + nlen = strlen(needle); + rlen = strlen(replacement); + res_i = 0; + res_n = max(left, 32); + if ((res_p = malloc(res_n * sizeof(char)))) { + do { + if (!(p2 = memmem(p1, left, needle, nlen))) break; + if (CONCAT(&res_p, &res_i, &res_n, p1, p2 - p1) == -1 || + CONCAT(&res_p, &res_i, &res_n, replacement, rlen) == -1) { + goto oom; + } + p2 += nlen; + left -= p2 - p1; + p1 = p2; + } while (left); + if (CONCAT(&res_p, &res_i, &res_n, p1, left + 1) != -1) { + return res_p; + } + } + oom: + free(res_p); + } else { + einval(); + } + return NULL; +} diff --git a/libc/alg/replacestr16.c b/libc/alg/replacestr16.c new file mode 100644 index 00000000..7c5513bf --- /dev/null +++ b/libc/alg/replacestr16.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/alg/arraylist2.h" +#include "libc/bits/safemacros.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +#undef replacestr +#define replacestr replacestr16 +#define char char16_t +#include "libc/alg/replacestr.c" diff --git a/libc/alg/reverse.h b/libc/alg/reverse.h new file mode 100644 index 00000000..84277731 --- /dev/null +++ b/libc/alg/reverse.h @@ -0,0 +1,33 @@ +#ifndef COSMOPOLITAN_LIBC_ALG_REVERSE_H_ +#define COSMOPOLITAN_LIBC_ALG_REVERSE_H_ +#include "libc/bits/xchg.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#if 0 +/** + * Reverses array. + * + * @param ARRAY is a typed array or a pointer to one + * @param COUNT is the number of items + * @return pointer to start of array + * @see ARRAYLEN() + */ +#endif +#define reverse(ARRAY, COUNT) \ + ({ \ + autotype(&(ARRAY)[0]) Array = (ARRAY); \ + size_t Count = (COUNT); \ + if (Count) { \ + size_t Start = 0; \ + size_t End = Count - 1; \ + while (Start < End) { \ + xchg(&Array[Start], &Array[End]); \ + ++Start; \ + --End; \ + } \ + } \ + Array; \ + }) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_ALG_REVERSE_H_ */ diff --git a/libc/alg/shuffle.h b/libc/alg/shuffle.h new file mode 100644 index 00000000..0f68f710 --- /dev/null +++ b/libc/alg/shuffle.h @@ -0,0 +1,25 @@ +#ifndef COSMOPOLITAN_LIBC_RAND_SHUFFLE_H_ +#define COSMOPOLITAN_LIBC_RAND_SHUFFLE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +#include "libc/bits/xchg.h" + +#if 0 +/** + * Fisher-Yates shuffle. + * + * @param R is a function like rand() → ≥0 + * @param A is a typed array + * @param n is the number of items in A + * @see ARRAYLEN() + */ +#endif +#define shuffle(R, A, n) \ + do { \ + autotype(A) Array = (A); \ + for (size_t i = (n)-1; i >= 1; --i) { \ + xchg(&Array[i], &Array[R() % (i + 1)]); \ + } \ + } while (0) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_RAND_SHUFFLE_H_ */ diff --git a/libc/alg/tarjan.c b/libc/alg/tarjan.c new file mode 100644 index 00000000..2c9128db --- /dev/null +++ b/libc/alg/tarjan.c @@ -0,0 +1,183 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/assert.h" +#include "libc/bits/safemacros.h" +#include "libc/limits.h" +#include "libc/mem/mem.h" + +/** + * @fileoverview Tarjan's Strongly Connected Components Algorithm. + * + * “The data structures that [Tarjan] devised for this problem fit + * together in an amazingly beautiful way, so that the quantities + * you need to look at while exploring a directed graph are always + * magically at your fingertips. And his algorithm also does + * topological sorting as a byproduct.” ──D.E. Knuth + */ + +struct Vertex { + uint32_t Vi; + uint32_t Ei; + uint32_t index; + uint32_t lowlink; + bool onstack; + bool selfreferential; +}; + +struct TarjanStack { + size_t i; + size_t n; + uint32_t *p; +}; + +struct Tarjan { + uint32_t Vn; + uint32_t En; + struct Vertex *V; + const uint32_t (*E)[2]; + uint32_t *R; + uint32_t *C; + uint32_t Ci; + uint32_t Ri; + uint32_t index; + struct TarjanStack S; +}; + +static uint32_t TarjanPush(struct TarjanStack *st, uint32_t Vi) { + if (st->i < st->n || grow(&st->p, &st->n, sizeof(uint32_t), 0)) { + return (st->p[st->i++] = Vi); + } else { + return -1; + } +} + +static uint32_t TarjanPop(struct TarjanStack *st) { + assert(st->i != 0); + return st->p[--st->i]; +} + +static int TarjanConnect(struct Tarjan **tj, uint32_t Vi) { + struct Vertex *v = &(*tj)->V[Vi]; + v->index = (*tj)->index; + v->lowlink = (*tj)->index; + v->onstack = true; + (*tj)->index++; + if (TarjanPush(&(*tj)->S, Vi) == -1) return -1; + uint32_t fs = (*tj)->V[Vi].Ei; + if (fs != -1) { + for (uint32_t Ei = fs; Ei < (*tj)->En && Vi == (*tj)->E[Ei][0]; ++Ei) { + struct Vertex *w = &(*tj)->V[(*tj)->E[Ei][1]]; + if (!w->index) { + if (TarjanConnect(tj, w->Vi) == -1) return -1; + v->lowlink = min(v->lowlink, w->lowlink); + } else if (w->onstack) { + v->lowlink = min(v->lowlink, w->index); + } + if (w == v) { + w->selfreferential = true; + } + } + } + if (v->lowlink == v->index) { + struct Vertex *w; + do { + w = &(*tj)->V[TarjanPop(&(*tj)->S)]; + w->onstack = false; + (*tj)->R[(*tj)->Ri++] = w->Vi; + } while (w != v); + if ((*tj)->C) (*tj)->C[(*tj)->Ci++] = (*tj)->Ri; + } + return 0; +} + +/** + * Determines order of things in network and finds tangled clusters too. + * + * @param vertices is an array of vertex values, which isn't passed to + * this function, since the algorithm only needs to consider indices + * @param vertex_count is the number of items in the vertices array + * @param edges are grouped directed links between indices of vertices, + * which can be thought of as "edge[i][0] depends on edge[i][1]" or + * "edge[i][1] must come before edge[i][0]" in topological order + * @param edge_count is the number of items in edges, which may be 0 if + * there aren't any connections between vertices in the graph + * @param out_sorted receives indices into the vertices array in + * topologically sorted order, and must be able to store + * vertex_count items, and that's always how many are stored + * @param out_opt_components receives indices into the out_sorted array, + * indicating where each strongly-connected component ends; must be + * able to store vertex_count items; and it may be NULL + * @param out_opt_componentcount receives the number of cycle indices + * written to out_opt_components, which will be vertex_count if + * there aren't any cycles in the graph; and may be NULL if + * out_opt_components is NULL + * @return 0 on success or -1 w/ errno + * @error ENOMEM + * @note Tarjan's Algorithm is O(|V|+|E|) + */ +int tarjan(uint32_t vertex_count, const uint32_t (*edges)[2], + uint32_t edge_count, uint32_t out_sorted[], + uint32_t out_opt_components[], uint32_t *out_opt_componentcount) { + assert(edge_count <= INT_MAX); + assert(vertex_count <= INT_MAX); + for (unsigned i = 0; i < edge_count; ++i) { + if (i) assert(edges[i - 1][0] <= edges[i][0]); + assert(edges[i][0] < vertex_count); + assert(edges[i][1] < vertex_count); + } + int rc; + struct Tarjan *tj; + if ((tj = calloc(1, (sizeof(struct Tarjan) + + sizeof(struct Vertex) * vertex_count)))) { + tj->V = (struct Vertex *)((char *)tj + sizeof(struct Tarjan)); + tj->Vn = vertex_count; + tj->E = edges; + tj->En = edge_count; + tj->R = out_sorted; + tj->C = out_opt_components; + tj->index = 1; + uint32_t Vi, Ei; + for (Vi = 0; Vi < tj->Vn; ++Vi) { + tj->V[Vi].Vi = Vi; + tj->V[Vi].Ei = -1u; + } + for (Ei = 0, Vi = -1u; Ei < tj->En; ++Ei) { + if (tj->E[Ei][0] == Vi) continue; + Vi = tj->E[Ei][0]; + tj->V[Vi].Ei = Ei; + } + rc = 0; + for (Vi = 0; Vi < tj->Vn; ++Vi) { + if (!tj->V[Vi].index) { + if ((rc = TarjanConnect(&tj, Vi)) == -1) { + break; + } + } + } + free(tj->S.p); + assert(tj->Ri == vertex_count); + if (out_opt_components) *out_opt_componentcount = tj->Ci; + } else { + rc = -1; + } + free(tj); + return rc; +} diff --git a/libc/assert.h b/libc/assert.h new file mode 100644 index 00000000..0d6bcfa6 --- /dev/null +++ b/libc/assert.h @@ -0,0 +1,24 @@ +#ifndef COSMOPOLITAN_LIBC_ASSERT_H_ +#define COSMOPOLITAN_LIBC_ASSERT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +void __assert_fail(const char *, const char *, int) hidden noreturn relegated; + +#ifdef NDEBUG +#define __ASSERT_FAIL(EXPR, FILE, LINE) +#else +#define __ASSERT_FAIL(EXPR, FILE, LINE) __assert_fail(EXPR, FILE, LINE) +#endif + +#define assert(EXPR) \ + do { \ + if (!(EXPR)) { \ + __ASSERT_FAIL(#EXPR, __FILE__, __LINE__); \ + unreachable; \ + } \ + } while (0) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_ASSERT_H_ */ diff --git a/libc/bits/abs.c b/libc/bits/abs.c new file mode 100644 index 00000000..d4ad144c --- /dev/null +++ b/libc/bits/abs.c @@ -0,0 +1,23 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/macros.h" + +int(abs)(int x) { return ABS(x); } diff --git a/libc/bits/atomic.h b/libc/bits/atomic.h new file mode 100644 index 00000000..0c7db3df --- /dev/null +++ b/libc/bits/atomic.h @@ -0,0 +1,52 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_ATOMIC_H_ +#define COSMOPOLITAN_LIBC_BITS_ATOMIC_H_ +#include "libc/bits/bits.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * @fileoverview C11 version of The Cosmopolitan Atomics Library. + * + * - Forty-two different ways to say MOV. + * - Fourteen different ways to say XCHG. + * - Twenty different ways to say LOCK CMPXCHG. + * + * Living proof high-level languages can be lower-level than assembly. + */ + +#define memory_order int +#define memory_order_relaxed 0 +#define memory_order_consume 1 +#define memory_order_acquire 2 +#define memory_order_release 3 +#define memory_order_acq_rel 4 +#define memory_order_seq_cst 5 + +#define atomic_flag struct AtomicFlag +#define atomic_flag_clear(PTR) atomic_store((PTR)->__cacheline, 0) +#define atomic_flag_test_and_set(PTR) \ + ({ \ + uint32_t ax = 0; \ + lockcmpxchg((PTR)->__cacheline, &ax, 1); \ + }) +#define atomic_init(PTR, VAL) atomic_store(PTR, VAL) +#define atomic_exchange(PTR, VAL) lockxchg(PTR, &(VAL)) +#define atomic_compare_exchange_strong(X, Y, Z) lockcmpxchg(X, Y, Z) +#define atomic_compare_exchange_weak(X, Y, Z) lockcmpxchg(X, Y, Z) +#define atomic_load_explicit(PTR, ORDER) atomic_load(PTR) +#define atomic_store_explicit(PTR, VAL, ORDER) atomic_store(PTR, VAL) +#define atomic_flag_clear_explicit(PTR, ORDER) atomic_store(PTR, 0) +#define atomic_exchange_explicit(PTR, VAL, ORDER) lockxchg(PTR, &(VAL)) +#define atomic_flag_test_and_set_explicit(PTR, ORDER) lockcmpxchg(PTR, 0, 1) +#define atomic_compare_exchange_strong_explicit(X, Y, Z, S, F) \ + lockcmpxchg(X, Y, Z) +#define atomic_compare_exchange_weak_explicit(X, Y, Z, S, F) \ + lockcmpxchg(X, Y, Z) + +struct AtomicFlag { + uint32_t __cacheline[16]; /* Intel V.O §9.4.6 */ +} aligned(64); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_ATOMIC_H_ */ diff --git a/libc/bits/avx2intrin.h b/libc/bits/avx2intrin.h new file mode 100644 index 00000000..2d2cb905 --- /dev/null +++ b/libc/bits/avx2intrin.h @@ -0,0 +1,133 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_AVX2INTRIN_H_ +#define COSMOPOLITAN_LIBC_BITS_AVX2INTRIN_H_ +#include "libc/bits/avxintrin.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define _mm256_min_epi16(M256_0, M256_1) \ + ((__m256i)__builtin_ia32_minps((__v16hi)(M256_0), (__v16hi)(M256_1))) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § avx2 » simd ops ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define _mm256_add_ps(M256_0, M256_1) \ + ((__m256)((__v8sf)(M256_0) + (__v8sf)(M256_1))) +#define _mm256_sub_ps(M256_0, M256_1) \ + ((__m256)((__v8sf)(M256_0) - (__v8sf)(M256_1))) +#define _mm256_mul_ps(M256_0, M256_1) \ + ((__m256)((__v8sf)(M256_0) * (__v8sf)(M256_1))) +#define _mm256_div_ps(M256_0, M256_1) \ + ((__m256)((__v8sf)(M256_0) / (__v8sf)(M256_1))) +#define _mm256_and_ps(M256_0, M256_1) \ + ((__m256)((__v8su)(M256_0) & (__v8su)(M256_1))) +#define _mm256_or_ps(M256_0, M256_1) \ + ((__m256)((__v8su)(M256_0) | (__v8su)(M256_1))) +#define _mm256_xor_ps(M256_0, M256_1) /* XORPD [u32 simd xor] */ \ + ((__m256)((__v8su)(M256_0) ^ (__v8su)(M256_1))) +#define _mm256_andnot_ps(M256_0, M256_1) /* ANDNPS [u32 simd nand] */ \ + ((__m256)(~(__v8su)(M256_0) & (__v8su)(M256_1))) +#define _mm256_rcp_ps(M256) __builtin_ia32_rcpps256((__v8sf)(M256)) +#define _mm256_sqrt_ps(M256) __builtin_ia32_sqrtps256((__v8sf)(M256)) +#define _mm256_rsqrt_ps(M256) __builtin_ia32_rsqrtps256((__v8sf)(M256)) +#define _mm256_round_ps(M256, IMM) \ + ((__m256)__builtin_ia32_roundps256((__v8sf)(__m256)(M256), IMM)) + +#define _mm256_add_epi32(M256I_0, M256I_1) \ + ((__m256i)((__v8su)(M256I_0) + (__v8su)(M256I_1))) +#define _mm256_cmpgt_epi32(M256I_0, M256I_1) \ + ((__m256i)((__v8si)(M256I_0) > (__v8si)(M256I_1))) +#define _mm256_min_epi32(M256I_0, M256I_1) \ + ((__m256i)__builtin_ia32_pminsd256((__v8si)(M256I_0), (__v8si)(M256I_1))) +#define _mm256_min_epu32(M256I_0, M256I_1) \ + ((__m256i)__builtin_ia32_pminud256((__v8si)(M256I_0), (__v8si)(M256I_1))) +#define _mm256_max_epi32(M256I_0, M256I_1) \ + ((__m256i)__builtin_ia32_pmaxsd256((__v8si)(M256I_0), (__v8si)(M256I_1))) +#define _mm256_max_epu32(M256I_0, M256I_1) \ + ((__m256i)__builtin_ia32_pmaxud256((__v8si)(M256I_0), (__v8si)(M256I_1))) +#define _mm256_blendv_epi8(M256I_0, M256I_1, M256I_2) \ + ((__m256i)__builtin_ia32_pblendvb256((__v32qi)(M256I_0), (__v32qi)(M256I_1), \ + (__v32qi)(M256I_2))) + +#define _mm256_min_ps(M256_0, M256_1) \ + ((__m256)__builtin_ia32_minps256((__v8sf)(__m256)(M256_0), \ + (__v8sf)(__m256)(M256_1))) +#define _mm256_max_ps(M256_0, M256_1) \ + ((__m256)__builtin_ia32_maxps256((__v8sf)(__m256)(M256_0), \ + (__v8sf)(__m256)(M256_1))) +#define _mm256_cmpneq_ps(M256_0, M256_1) \ + ((__m256)__builtin_ia32_cmpneqps((__v8sf)(__m256)(M256_0), \ + (__v8sf)(__m256)(M256_1))) +#define _mm256_cmplt_ps(M256_0, M256_1) \ + ((__m256)__builtin_ia32_cmpltps((__v8sf)(__m256)(M256_0), \ + (__v8sf)(__m256)(M256_1))) +#define _mm256_cmpnlt_ps(M256_0, M256_1) \ + ((__m256)__builtin_ia32_cmpnltps((__v8sf)(__m256)(M256_0), \ + (__v8sf)(__m256)(M256_1))) +#define _mm256_cmple_ps(M256_0, M256_1) \ + ((__m256)__builtin_ia32_cmpleps((__v8sf)(__m256)(M256_0), \ + (__v8sf)(__m256)(M256_1))) +#define _mm256_cmpnle_ps(M256_0, M256_1) \ + ((__m256)__builtin_ia32_cmpnleps((__v8sf)(__m256)(M256_0), \ + (__v8sf)(__m256)(M256_1))) +#define _mm256_cmpgt_ps(M256_0, M256_1) \ + ((__m256)__builtin_ia32_cmpltps((__v8sf)(__m256)(M256_1), \ + (__v8sf)(__m256)(M256_0))) +#define _mm256_cmpngt_ps(M256_0, M256_1) \ + ((__m256)__builtin_ia32_cmpnltps((__v8sf)(__m256)(M256_1), \ + (__v8sf)(__m256)(M256_0))) +#define _mm256_cmpge_ps(M256_0, M256_1) \ + ((__m256)__builtin_ia32_cmpleps((__v8sf)(__m256)(M256_1), \ + (__v8sf)(__m256)(M256_0))) +#define _mm256_cmpnge_ps(M256_0, M256_1) \ + ((__m256)__builtin_ia32_cmpnleps((__v8sf)(__m256)(M256_1), \ + (__v8sf)(__m256)(M256_0))) +#define _mm256_cmpord_ps(M256_0, M256_1) \ + ((__m256)__builtin_ia32_cmpordps((__v8sf)(__m256)(M256_0), \ + (__v8sf)(__m256)(M256_1))) +#define _mm256_cmpunord_ps(M256_0, M256_1) \ + ((__m256)__builtin_ia32_cmpunordps((__v8sf)(__m256)(M256_0), \ + (__v8sf)(__m256)(M256_1))) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § avx2 » memory ops ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +struct thatispacked PackedMayaliasIntyYmm { + __m256i Ymm; +} mayalias; + +#define _mm256_set_ps(FLT_0, FLT_1, FLT_2, FLT_3, FLT_4, FLT_5, FLT_6, FLT_7) \ + ((__m256)(__v8sf){(float)(FLT_0), (float)(FLT_1), (float)(FLT_2), \ + (float)(FLT_3), (float)(FLT_4), (float)(FLT_5), \ + (float)(FLT_6), (float)(FLT_7)}) +#define _mm256_set1_ps(FLT_0) \ + _mm256_set_ps(FLT_0, FLT_0, FLT_0, FLT_0, FLT_0, FLT_0, FLT_0, FLT_0) +#define _mm256_setr_ps(FLT_0, FLT_1, FLT_2, FLT_3, FLT_4, FLT_5, FLT_6, FLT_7) \ + _mm256_set_ps(FLT_7, FLT_6, FLT_5, FLT_4, FLT_3, FLT_2, FLT_1, FLT_0) + +#define _mm256_set_epi32(INT_0, INT_1, INT_2, INT_3, INT_4, INT_5, INT_6, \ + INT_7) \ + ((__m256i)(__v8si){(int)(INT_0), (int)(INT_1), (int)(INT_2), (int)(INT_3), \ + (int)(INT_4), (int)(INT_5), (int)(INT_6), (int)(INT_7)}) +#define _mm256_set1_epi32(INT_0) \ + _mm256_set_epi32(INT_0, INT_0, INT_0, INT_0, INT_0, INT_0, INT_0, INT_0) +#define _mm256_setr_epi32(INT_0, INT_1, INT_2, INT_3, INT_4, INT_5, INT_6, \ + INT_7) \ + _mm256_set_epi32(INT_7, INT_6, INT_5, INT_4, INT_3, INT_2, INT_1, INT_0) + +#define _mm256_loadu_si256(M256IP_0) \ + ({ \ + const __m256i *Ymm = (M256IP_0); \ + ((struct PackedMayaliasIntyYmm *)Ymm)->Ymm; \ + }) + +#define _mm256_storeu_si256(M256IP_0, M256I_1) \ + ({ \ + __m256i *Ymm = (M256IP_0); \ + ((struct PackedMayaliasIntyYmm *)Ymm)->Ymm = M256I_1; \ + }) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_AVX2INTRIN_H_ */ diff --git a/libc/bits/avxintrin.h b/libc/bits/avxintrin.h new file mode 100644 index 00000000..5071bcdd --- /dev/null +++ b/libc/bits/avxintrin.h @@ -0,0 +1,51 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_AVXINTRIN_H_ +#define COSMOPOLITAN_LIBC_BITS_AVXINTRIN_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +typedef float __m256 _Vector_size(32) mayalias; +typedef double __m256d _Vector_size(32) mayalias; +typedef long long __m256i _Vector_size(32) mayalias; + +typedef float __m256_u _Vector_size(32) aligned(1) mayalias; +typedef double __m256d_u _Vector_size(32) aligned(1) mayalias; +typedef long long __m256i_u _Vector_size(32) aligned(1) mayalias; + +typedef double __v4df _Vector_size(32); +typedef float __v8sf _Vector_size(32); +typedef long long __v4di _Vector_size(32); +typedef unsigned long long __v4du _Vector_size(32); +typedef int __v8si _Vector_size(32); +typedef unsigned __v8su _Vector_size(32); +typedef short __v16hi _Vector_size(32); +typedef unsigned short __v16hu _Vector_size(32); +typedef char __v32qi _Vector_size(32); +typedef unsigned char __v32qu _Vector_size(32); + +#define _mm256_setzero_ps() ((__m256)(__v8sf){0}) +#define _mm256_load_ps(FLOATPTR) (*(__m256 *)(FLOATPTR)) +#define _mm256_loadu_ps(FLOATPTR) (*(__m256_u *)(FLOATPTR)) +#define _mm256_store_ps(FLOATPTR, M256_0) \ + (*(__m256 *)(FLOATPTR) = (__m256)(M256_0)) +#define _mm256_storeu_ps(FLOATPTR, M256_0) \ + (*(__m256_u *)(FLOATPTR) = (__m256)(M256_0)) +#define _mm256_extractf128_ps(M256_0, INT_1) \ + ((__m128)__builtin_ia32_vextractf128_ps256((__v8sf)(__m256)(M256_0), \ + (int)(INT_1))) +#define _mm256_insertf128_ps(M256_0, M128_1, IMM_2) \ + ((__m256)__builtin_ia32_vinsertf128_ps256( \ + (__v8sf)(__m256)(M256_0), (__v4sf)(__m128)(M128_1), (int)(IMM_2))) + +#ifdef __llvm__ +#define _mm256_castps128_ps256(M128_0) \ + ((__m256)__builtin_shufflevector((__v4sf)(__m128)(M128_0), \ + (__v4sf)(__m128)(M128_0), 0, 1, 2, 3, -1, \ + -1, -1, -1)) +#else +#define _mm256_castps128_ps256(M128_0) \ + ((__m256)__builtin_ia32_ps256_ps((__v4sf)(__m128)(M128_0))) +#endif + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_AVXINTRIN_H_ */ diff --git a/libc/bits/bcd2i.S b/libc/bits/bcd2i.S new file mode 100644 index 00000000..d7767b1f --- /dev/null +++ b/libc/bits/bcd2i.S @@ -0,0 +1,42 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +/ Converts binary-coded-decimal to integer. +/ +/ @param rdi is the string copied into a word +bcd2i: .leafprologue + .profilable + test %rdi,%rdi + je 2f + mov $1,%ecx + xor %eax,%eax +1: mov %edi,%edx + and $15,%edx + imul %rcx,%rdx + add %rdx,%rax + add %rcx,%rcx + lea (%rcx,%rcx,4),%rcx + shr $4,%rdi + jne 1b + ret +2: xor %eax,%eax + .leafepilogue + .endfn bcd2i,globl diff --git a/libc/bits/bcdadd.S b/libc/bits/bcdadd.S new file mode 100644 index 00000000..1a9e7e49 --- /dev/null +++ b/libc/bits/bcdadd.S @@ -0,0 +1,38 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +/ Performs addition on binary-coded decimals. +bcdadd: .leafprologue + .profilable + lea 0x6666666(%rdi),%ecx + xor %esi,%ecx + lea (%rdi,%rsi),%eax + add $0x6666666,%eax + xor %eax,%ecx + not %ecx + and $0x11111110,%ecx + mov %ecx,%edx + shr $2,%edx + shr $3,%ecx + orl %edx,%ecx + sub %ecx,%eax + .leafepilogue + .endfn bcdadd,globl diff --git a/libc/bits/bcxcpy.S b/libc/bits/bcxcpy.S new file mode 100644 index 00000000..23ee6aa7 --- /dev/null +++ b/libc/bits/bcxcpy.S @@ -0,0 +1,54 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +bcxcpy: push %rbp + mov %rsp,%rbp + .profilable + push %rbx + xor %ebx,%ebx + lea -64(%rbp),%rdx + sub $24,%rsp +3: lea (,%rbx,4),%ecx + mov %rsi,%rax + shr %cl,%rax + and $15,%eax + cmp $9,%eax + lea 7(%rax),%ecx + cmova %ecx,%eax + add $48,%eax + mov %al,(%rdx,%rbx) + add $1,%rbx + cmp $16,%rbx + jne 3b + mov %rdx,%rax + lea -48(%rbp),%rcx + lea 15(%rdi),%rdx +4: movzbl (%rax),%ebx + add $1,%rax + sub $1,%rdx + mov %bl,1(%rdx) + cmp %rcx,%rax + jne 4b + add $24,%rsp + pop %rbx + pop %rbp + ret + .endfn bcxcpy,globl diff --git a/libc/bits/bigword.h b/libc/bits/bigword.h new file mode 100644 index 00000000..5db6a9a7 --- /dev/null +++ b/libc/bits/bigword.h @@ -0,0 +1,28 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_BIGWORD_H_ +#define COSMOPOLITAN_LIBC_BITS_BIGWORD_H_ + +#if 0 +/** + * Let BIGWORD be the the number of bytes in the largest cpu register + * available within the instruction set architecture requirements chosen + * at compile-time. + * + * In plainer terms, if you tune with flags like -mavx, you're not just + * giving the compiler permission to generate code that's incompatible + * with older computers; you're also asking Cosmopolitan to systemically + * change alignment, vectoring, buffering, ABIs, memory allocation, etc. + */ +#endif +#ifndef BIGWORD +#if __AVX512F__ + 0 +#define BIGWORD 64 +#elif __AVX2__ + 0 +#define BIGWORD 32 +#elif __SSE2__ + 0 +#define BIGWORD 16 +#else +#define BIGWORD __BIGGEST_ALIGNMENT__ +#endif +#endif /*BIGWORD*/ + +#endif /* COSMOPOLITAN_LIBC_BITS_BIGWORD_H_ */ diff --git a/libc/bits/bitreverse16.S b/libc/bits/bitreverse16.S new file mode 100644 index 00000000..abf9c5be --- /dev/null +++ b/libc/bits/bitreverse16.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +bitreverse16: + push %rbx + mov %edi,%eax + mov $kReverseBits,%ebx + xlat + xchg %al,%ah + xlat + pop %rbx + ret + .endfn bitreverse16,globl diff --git a/libc/bits/bitreverse32.c b/libc/bits/bitreverse32.c new file mode 100644 index 00000000..05b1804d --- /dev/null +++ b/libc/bits/bitreverse32.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" + +uint32_t(bitreverse32)(uint32_t x) { + x = bswap_32(x); + x = ((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1); + x = ((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2); + x = ((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4); + return x; +} diff --git a/libc/bits/bitreverse64.c b/libc/bits/bitreverse64.c new file mode 100644 index 00000000..b3864703 --- /dev/null +++ b/libc/bits/bitreverse64.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" + +uint64_t bitreverse64(uint64_t x) { + x = bswap_64(x); + x = ((x & 0xaaaaaaaaaaaaaaaa) >> 1) | ((x & 0x5555555555555555) << 1); + x = ((x & 0xcccccccccccccccc) >> 2) | ((x & 0x3333333333333333) << 2); + x = ((x & 0xf0f0f0f0f0f0f0f0) >> 4) | ((x & 0x0f0f0f0f0f0f0f0f) << 4); + return x; +} diff --git a/libc/bits/bitreverse8.S b/libc/bits/bitreverse8.S new file mode 100644 index 00000000..a7a8db3b --- /dev/null +++ b/libc/bits/bitreverse8.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +bitreverse8: + .leafprologue + .profilable + push %rbx + mov %edi,%eax + mov $kReverseBits,%ebx + xlat + pop %rbx + .leafepilogue + .endfn bitreverse8,globl diff --git a/libc/bits/bits.h b/libc/bits/bits.h new file mode 100644 index 00000000..68e01224 --- /dev/null +++ b/libc/bits/bits.h @@ -0,0 +1,531 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_H_ +#define COSMOPOLITAN_LIBC_BITS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define CheckUnsigned(x) ((x) / !((typeof(x))(-1) < 0)) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § bits ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +extern const bool kTrue; +extern const bool kFalse; +extern const uint8_t kReverseBits[256]; + +uint16_t bswap_16(uint16_t) pureconst; +uint32_t bswap_32(uint32_t) pureconst; +uint32_t bswap_64(uint32_t) pureconst; +unsigned long popcount(unsigned long) pureconst; +uint32_t gray(uint32_t) pureconst; +uint32_t ungray(uint32_t) pureconst; +unsigned bcdadd(unsigned, unsigned) pureconst; +unsigned long bcd2i(unsigned long) pureconst; +unsigned long i2bcd(unsigned long) pureconst; +void bcxcpy(unsigned char (*)[16], unsigned long); +int ffs(int) pureconst; +int ffsl(long int) pureconst; +int ffsll(long long int) pureconst; +int fls(int) pureconst; +int flsl(long int) pureconst; +int flsll(long long int) pureconst; +uint8_t bitreverse8(uint8_t) libcesque pureconst; +uint16_t bitreverse16(uint16_t) libcesque pureconst; +uint32_t bitreverse32(uint32_t) libcesque pureconst; +uint64_t bitreverse64(uint64_t) libcesque pureconst; +unsigned long roundup2pow(unsigned long) libcesque pureconst; +unsigned long roundup2log(unsigned long) libcesque pureconst; +unsigned long rounddown2pow(unsigned long) libcesque pureconst; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § bits » no assembly required ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +/** + * Undocumented incantations for ROR, ROL, and SAR. + */ +#define ROR(w, k) (CheckUnsigned(w) >> (k) | (w) << (sizeof(w) * 8 - (k))) +#define ROL(w, k) ((w) << (k) | CheckUnsigned(w) >> (sizeof(w) * 8 - (k))) +#define SAR(w, k) (((w) & ~(~0u >> (k))) | ((w) >> ((k) & (sizeof(w) * 8 - 1)))) + +#define bitreverse8(X) (kReverseBits[(X)&0xff]) +#define bitreverse16(X) \ + ((uint16_t)kReverseBits[(X)&0xff] << 010 | \ + kReverseBits[((uint16_t)(X) >> 010) & 0xff]) + +#ifndef __GNUC__ +#define READ16LE(P) ((unsigned)(P)[1] << 010 | (unsigned)(P)[0]) +#define READ32LE(P) \ + ((unsigned long)(P)[3] << 030 | (unsigned long)(P)[2] << 020 | \ + (unsigned long)(P)[1] << 010 | (unsigned long)(P)[0]) +#define READ64LE(P) \ + ((unsigned long long)(P)[3] << 030 | (unsigned long)(P)[2] << 020 | \ + (unsigned long long)(P)[1] << 010 | (unsigned long)(P)[0]) +#else +#define READ16LE(P) read16le(P) +#define READ32LE(P) read32le(P) +#define READ64LE(P) read64le(P) +#define read16le(P) \ + ({ \ + const unsigned char *Pu = (const unsigned char *)(P); \ + (uint16_t) Pu[1] << 010 | (uint16_t)Pu[0]; \ + }) +#define read32le(P) \ + ({ \ + const unsigned char *Pu = (const unsigned char *)(P); \ + ((uint32_t)Pu[3] << 030 | (uint32_t)Pu[2] << 020 | \ + (uint32_t)Pu[1] << 010 | (uint32_t)Pu[0] << 000); \ + }) +#define read64le(P) \ + ({ \ + const unsigned char *Pu = (const unsigned char *)(P); \ + ((uint64_t)Pu[7] << 070 | (uint64_t)Pu[6] << 060 | \ + (uint64_t)Pu[5] << 050 | (uint64_t)Pu[4] << 040 | \ + (uint64_t)Pu[3] << 030 | (uint64_t)Pu[2] << 020 | \ + (uint64_t)Pu[1] << 010 | (uint64_t)Pu[0] << 000); \ + }) +#endif + +#define WRITE16LE(P, V) \ + do { \ + uint8_t *Ple = (P); \ + uint16_t Vle = (V); \ + Ple[0] = (uint8_t)(Vle >> 000); \ + Ple[1] = (uint8_t)(Vle >> 010); \ + } while (0) + +#define WRITE32LE(P, V) \ + do { \ + uint8_t *Ple = (P); \ + uint32_t Vle = (V); \ + Ple[0] = (uint8_t)(Vle >> 000); \ + Ple[1] = (uint8_t)(Vle >> 010); \ + Ple[2] = (uint8_t)(Vle >> 020); \ + Ple[3] = (uint8_t)(Vle >> 030); \ + } while (0) + +#define WRITE64LE(P, V) \ + do { \ + uint8_t *Ple = (P); \ + uint64_t Vle = (V); \ + Ple[0] = (uint8_t)(Vle >> 000); \ + Ple[1] = (uint8_t)(Vle >> 010); \ + Ple[2] = (uint8_t)(Vle >> 020); \ + Ple[3] = (uint8_t)(Vle >> 030); \ + Ple[4] = (uint8_t)(Vle >> 040); \ + Ple[5] = (uint8_t)(Vle >> 050); \ + Ple[6] = (uint8_t)(Vle >> 060); \ + Ple[7] = (uint8_t)(Vle >> 070); \ + } while (0) + +/* TODO(jart): these ones aren't coded correctly */ +#define read128le(P) ((uint128_t)read64le((P) + 8) << 0100 | read64le(P)) +#define read16be(P) ((uint16_t)(*(P) << 010) | (uint16_t)(*((P) + 1))) +#define read32be(P) ((uint32_t)read16be(P) << 020 | (uint32_t)read16be((P) + 2)) +#define read64be(P) ((uint64_t)read32be(P) << 040 | read32be((P) + 4)) +#define read128be(P) ((uint128_t)read64be(P) << 0100 | read64be((P) + 8)) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § bits » some assembly required ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +/** + * Constraints for virtual machine flags. + * @note we beseech clang devs for flag constraints + */ +#ifdef __GCC_ASM_FLAG_OUTPUTS__ /* GCC6+ CLANG10+ */ +#define CF "=@ccc" +#define CFLAG(OP) OP +#define ZF "=@ccz" +#define ZFLAG(OP) OP +#define OF "=@cco" +#define OFLAG(OP) OP +#define SF "=@ccs" +#define SFLAG(SP) SP +#define ABOVEF "=@cca" /* i.e. !ZF && !CF */ +#define ABOVEFLAG(OP) OP +#else +#define CF "=q" +#define CFLAG(OP) OP "\n\tsetc\t%b0" +#define ZF "=q" +#define ZFLAG(OP) OP "\n\tsetz\t%b0" +#define OF "=q" +#define OFLAG(OP) OP "\n\tseto\t%b0" +#define SF "=q" +#define SFLAG(SP) OP "\n\tsets\t%b0" +#define ABOVEF "=@cca" +#define ABOVEFLAG(OP) OP "\n\tseta\t%b0" +#endif + +/** + * Reads scalar from memory, offset by segment. + * + * @return *(MEM) relative to segment + * @see arch_prctl() + * @see pushpop() + */ +#define fs(MEM) __peek("fs", MEM) +#define gs(MEM) __peek("gs", MEM) + +/** + * Reads scalar from memory w/ one operation. + * + * @param MEM is alignas(𝑘) uint𝑘_t[hasatleast 1] where 𝑘 ∈ {8,16,32,64} + * @return *(MEM) + * @note defeats compiler load tearing optimizations + * @note alignas(𝑘) is implied if compiler knows type + * @note alignas(𝑘) only avoids multi-core / cross-page edge cases + * @see Intel's Six-Thousand Page Manual V.3A §8.2.3.1 + * @see atomic_store() + */ +#define atomic_load(MEM) \ + ({ \ + autotype(MEM) Mem = (MEM); \ + typeof(*Mem) Reg; \ + asm("mov\t%1,%0" : "=r"(Reg) : "m"(*Mem)); \ + Reg; \ + }) + +/** + * Saves scalar to memory w/ one operation. + * + * This is guaranteed to happen in either one or zero operations, + * depending on whether or not it's possible for *(MEM) to be read + * afterwards. This macro only forbids compiler from using >1 ops. + * + * @param MEM is alignas(𝑘) uint𝑘_t[hasatleast 1] where 𝑘 ∈ {8,16,32,64} + * @param VAL is uint𝑘_t w/ better encoding for immediates (constexpr) + * @return VAL + * @note alignas(𝑘) on nexgen32e only needed for end of page gotcha + * @note alignas(𝑘) is implied if compiler knows type + * @note needed to defeat store tearing optimizations + * @see Intel Six-Thousand Page Manual Manual V.3A §8.2.3.1 + * @see atomic_load() + */ +#define atomic_store(MEM, VAL) \ + ({ \ + autotype(VAL) Val = (VAL); \ + typeof(&Val) Mem = (MEM); \ + asm("mov%z1\t%1,%0" : "=m,m"(*Mem) : "i,r"(Val)); \ + Val; \ + }) + +/** + * Returns true if bit is set in memory. + * + * This is a generically-typed Bitset ∀ RAM. This macro is intended + * to be container-like with optimal machine instruction encoding, cf. + * machine-agnostic container abstractions. Memory accesses are words. + * Register allocation can be avoided if BIT is known. Be careful when + * casting character arrays since that should cause a page fault. + * + * @param MEM is uint𝑘_t[] where 𝑘 ∈ {16,32,64} base address + * @param BIT ∈ [-(2**(𝑘-1)),2**(𝑘-1)) is zero-based index + * @return true if bit is set, otherwise false + * @see Intel's Six Thousand Page Manual V.2A 3-113 + * @see bts(), btr(), btc() + */ +#define bt(MEM, BIT) \ + ({ \ + bool OldBit; \ + if (isconstant(BIT)) { \ + asm(CFLAG("bt%z1\t%2,%1") \ + : CF(OldBit) \ + : "m"((MEM)[(BIT) / (sizeof((MEM)[0]) * CHAR_BIT)]), \ + "J"((BIT) % (sizeof((MEM)[0]) * CHAR_BIT)) \ + : "cc"); \ + } else if (sizeof((MEM)[0]) == 2) { \ + asm(CFLAG("bt\t%w2,%1") : CF(OldBit) : "m"((MEM)[0]), "r"(BIT) : "cc"); \ + } else if (sizeof((MEM)[0]) == 4) { \ + asm(CFLAG("bt\t%k2,%1") : CF(OldBit) : "m"((MEM)[0]), "r"(BIT) : "cc"); \ + } else if (sizeof((MEM)[0]) == 8) { \ + asm(CFLAG("bt\t%q2,%1") : CF(OldBit) : "m"((MEM)[0]), "r"(BIT) : "cc"); \ + } \ + OldBit; \ + }) + +#define bts(MEM, BIT) __BitOp("bts", BIT, MEM) /** bit test and set */ +#define btr(MEM, BIT) __BitOp("btr", BIT, MEM) /** bit test and reset */ +#define btc(MEM, BIT) __BitOp("btc", BIT, MEM) /** bit test and complement */ +#define lockbts(MEM, BIT) __BitOp("lock bts", BIT, MEM) +#define lockbtr(MEM, BIT) __BitOp("lock btr", BIT, MEM) +#define lockbtc(MEM, BIT) __BitOp("lock btc", BIT, MEM) + +#define lockinc(MEM) __ArithmeticOp1("lock inc", MEM) +#define lockdec(MEM) __ArithmeticOp1("lock dec", MEM) +#define locknot(MEM) __ArithmeticOp1("lock not", MEM) +#define lockneg(MEM) __ArithmeticOp1("lock neg", MEM) + +#define lockaddeq(MEM, VAL) __ArithmeticOp2("lock add", VAL, MEM) +#define locksubeq(MEM, VAL) __ArithmeticOp2("lock sub", VAL, MEM) +#define lockxoreq(MEM, VAL) __ArithmeticOp2("lock xor", VAL, MEM) +#define lockandeq(MEM, VAL) __ArithmeticOp2("lock and", VAL, MEM) +#define lockoreq(MEM, VAL) __ArithmeticOp2("lock or", VAL, MEM) + +/** + * Exchanges *MEMORY into *LOCALVAR w/ one operation. + * + * @param MEMORY is uint𝑘_t[hasatleast 1] where 𝑘 ∈ {8,16,32,64} + * @param LOCALVAR is uint𝑘_t[hasatleast 1] + * @return LOCALVAR[0] + * @see xchg() + */ +#define lockxchg(MEMORY, LOCALVAR) \ + ({ \ + static_assert(typescompatible(typeof(*(MEMORY)), typeof(*(LOCALVAR)))); \ + asm("xchg\t%0,%1" : "+%m"(*(MEMORY)), "+r"(*(LOCALVAR))); \ + *(LOCALVAR); \ + }) + +/** + * Compares and exchanges. + * + * @param IFTHING is uint𝑘_t[hasatleast 1] where 𝑘 ∈ {8,16,32,64} + * @return true if value was exchanged, otherwise false + * @see lockcmpxchg() + */ +#define cmpxchg(IFTHING, ISEQUALTOME, REPLACEITWITHME) \ + ({ \ + bool DidIt; \ + asm(ZFLAG("cmpxchg\t%3,%1") \ + : ZF(DidIt), "+m"(*(IFTHING)), "+a"(*(ISEQUALTOME)) \ + : "r"((typeof(*(IFTHING)))(REPLACEITWITHME)) \ + : "cc"); \ + DidIt; \ + }) + +#define ezcmpxchg(IFTHING, ISEQUALTOME, REPLACEITWITHME) \ + ({ \ + bool DidIt; \ + autotype(IFTHING) IfThing = (IFTHING); \ + typeof(*IfThing) IsEqualToMe = (ISEQUALTOME); \ + typeof(*IfThing) ReplaceItWithMe = (REPLACEITWITHME); \ + asm(ZFLAG("cmpxchg\t%3,%1") \ + : ZF(DidIt), "+m"(*IfThing), "+a"(IsEqualToMe) \ + : "r"(ReplaceItWithMe) \ + : "cc"); \ + DidIt; \ + }) + +/** + * Compares and exchanges w/ one operation. + * + * @param IFTHING is uint𝑘_t[hasatleast 1] where 𝑘 ∈ {8,16,32,64} + * @return true if value was exchanged, otherwise false + * @see lockcmpxchg() + */ +#define lockcmpxchg(IFTHING, ISEQUALTOME, REPLACEITWITHME) \ + ({ \ + bool DidIt; \ + asm(ZFLAG("lock cmpxchg\t%3,%1") \ + : ZF(DidIt), "+m"(*(IFTHING)), "+a"(*(ISEQUALTOME)) \ + : "r"((typeof(*(IFTHING)))(REPLACEITWITHME)) \ + : "cc"); \ + DidIt; \ + }) + +/** + * Gets value of extended control register. + */ +#define xgetbv(xcr_register_num) \ + ({ \ + unsigned hi, lo; \ + asm("xgetbv" : "=d"(hi), "=a"(lo) : "c"(cr_register_num)); \ + (uint64_t) hi << 32 | lo; \ + }) + +/** + * Reads model-specific register. + * @note programs running as guests won't have authorization + */ +#define rdmsr(msr) \ + ({ \ + uint32_t lo, hi; \ + asm volatile("rdmsr" : "=a"(lo), "=d"(hi) : "c"(msr)); \ + (uint64_t) hi << 32 | lo; \ + }) + +/** + * Writes model-specific register. + * @note programs running as guests won't have authorization + */ +#define wrmsr(msr, val) \ + do { \ + uint64_t val_ = (val); \ + asm volatile("wrmsr" \ + : /* no outputs */ \ + : "c"(msr), "a"((uint32_t)val_), \ + "d"((uint32_t)(val_ >> 32))); \ + } while (0) + +/** + * Tells CPU page tables changed for virtual address. + * @note programs running as guests won't have authorization + */ +#define invlpg(MEM) \ + asm volatile("invlpg\t(%0)" : /* no outputs */ : "r"(MEM) : "memory") + +/** + * Teleports code fragment inside _init(). + */ +#define INITIALIZER(PRI, NAME, CODE) \ + asm(".pushsection .init." #PRI "." #NAME ",\"ax\",@progbits\n\t" \ + "call\t" #NAME "\n\t" \ + ".popsection"); \ + textstartup optimizesize void NAME(char *rdi, const char *rsi) { \ + CODE; \ + asm volatile("" : /* no outputs */ : "D"(rdi), "S"(rsi)); \ + } + +#ifndef __STRICT_ANSI__ +#if __PIC__ + __code_model_medium__ + __code_model_large__ + 0 > 1 +#define __EZLEA(SYMBOL) "lea\t" SYMBOL "(%%rip),%" +#else +#define __EZLEA(SYMBOL) "mov\t$" SYMBOL ",%k" +#endif +#define weaken(symbol) ((const typeof(&(symbol)))weakaddr(#symbol)) +#define strongaddr(symbolstr) \ + ({ \ + intptr_t waddr; \ + asm(__EZLEA(symbolstr) "0" : "=r"(waddr)); \ + waddr; \ + }) +#define weakaddr(symbolstr) \ + ({ \ + intptr_t waddr; \ + asm(".weak\t" symbolstr "\n\t" __EZLEA(symbolstr) "0" : "=r"(waddr)); \ + waddr; \ + }) +#else +#define weaken(symbol) symbol +#define weakaddr(symbolstr) &(symbolstr) +#endif + +#define slowcall(fn, arg1, arg2, arg3, arg4, arg5, arg6) \ + ({ \ + void *ax; \ + asm volatile("push\t%7\n\t" \ + "push\t%6\n\t" \ + "push\t%5\n\t" \ + "push\t%4\n\t" \ + "push\t%3\n\t" \ + "push\t%2\n\t" \ + "push\t%1\n\t" \ + "call\tslowcall" \ + : "=a"(ax) \ + : "g"(fn), "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), \ + "g"(arg5), "g"(arg6) \ + : "memory"); \ + ax; \ + }) + +#define IsAddressCanonicalForm(P) \ + ({ \ + intptr_t p2 = (intptr_t)(P); \ + (0xffff800000000000l <= p2 && p2 <= 0x00007fffffffffffl); \ + }) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § bits » optimizations ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) + +#define popcount(X) (isconstant(X) ? __builtin_popcount(X) : __popcount(X)) +#define popcount$nehalem(X) \ + ({ \ + typeof(X) BitCount; \ + asm("popcnt\t%1,%0" : "=r,r"(BitCount) : "r,m"(X) : "cc"); \ + BitCount; \ + }) +#ifdef __POPCNT__ +#define __popcount(X) popcount$nehalem(X) +#else +#define __popcount(X) (popcount)(X) +#endif + +#define bswap_16(U16) \ + (isconstant(U16) ? ((((U16)&0xff00) >> 010) | (((U16)&0x00ff) << 010)) : ({ \ + uint16_t Swapped16, Werd16 = (U16); \ + asm("xchg\t%b0,%h0" : "=Q"(Swapped16) : "0"(Werd16)); \ + Swapped16; \ + })) + +#define bswap_32(U32) \ + (isconstant(U32) \ + ? ((((U32)&0xff000000) >> 030) | (((U32)&0x000000ff) << 030) | \ + (((U32)&0x00ff0000) >> 010) | (((U32)&0x0000ff00) << 010)) \ + : ({ \ + uint32_t Swapped32, Werd32 = (U32); \ + asm("bswap\t%0" : "=r"(Swapped32) : "0"(Werd32)); \ + Swapped32; \ + })) + +#define bswap_64(U64) \ + (isconstant(U64) ? ((((U64)&0xff00000000000000ul) >> 070) | \ + (((U64)&0x00000000000000fful) << 070) | \ + (((U64)&0x00ff000000000000ul) >> 050) | \ + (((U64)&0x000000000000ff00ul) << 050) | \ + (((U64)&0x0000ff0000000000ul) >> 030) | \ + (((U64)&0x0000000000ff0000ul) << 030) | \ + (((U64)&0x000000ff00000000ul) >> 010) | \ + (((U64)&0x00000000ff000000ul) << 010)) \ + : ({ \ + uint64_t Swapped64, Werd64 = (U64); \ + asm("bswap\t%0" : "=r"(Swapped64) : "0"(Werd64)); \ + Swapped64; \ + })) + +#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) */ +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § bits » implementation details ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define __peek(SEGMENT, ADDRESS) \ + ({ \ + typeof(*(ADDRESS)) Pk; \ + asm("mov\t%%" SEGMENT ":%1,%0" : "=r"(Pk) : "m"(*(ADDRESS))); \ + Pk; \ + }) + +#define __ArithmeticOp1(OP, MEM) \ + ({ \ + asm(OP "%z0\t%0" : "+m"(*(MEM)) : /* no inputs */ : "cc"); \ + MEM; \ + }) + +#define __ArithmeticOp2(OP, VAL, MEM) \ + ({ \ + asm(OP "%z0\t%1,%0" : "+m,m"(*(MEM)) : "i,r"(VAL) : "cc"); \ + MEM; \ + }) + +#define __BitOp(OP, BIT, MEM) \ + ({ \ + bool OldBit; \ + if (isconstant(BIT)) { \ + asm(CFLAG(OP "%z1\t%2,%1") \ + : CF(OldBit), "+m"((MEM)[(BIT) / (sizeof((MEM)[0]) * CHAR_BIT)]) \ + : "J"((BIT) % (sizeof((MEM)[0]) * CHAR_BIT)) \ + : "cc"); \ + } else if (sizeof((MEM)[0]) == 2) { \ + asm(CFLAG(OP "\t%w2,%1") \ + : CF(OldBit), "+m"((MEM)[0]) \ + : "r"(BIT) \ + : "cc"); \ + } else if (sizeof((MEM)[0]) == 4) { \ + asm(CFLAG(OP "\t%k2,%1") \ + : CF(OldBit), "+m"((MEM)[0]) \ + : "r"(BIT) \ + : "cc"); \ + } else if (sizeof((MEM)[0]) == 8) { \ + asm(CFLAG(OP "\t%q2,%1") \ + : CF(OldBit), "+m"((MEM)[0]) \ + : "r"(BIT) \ + : "cc"); \ + } \ + OldBit; \ + }) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_H_ */ diff --git a/libc/bits/bits.mk b/libc/bits/bits.mk new file mode 100644 index 00000000..8946028f --- /dev/null +++ b/libc/bits/bits.mk @@ -0,0 +1,53 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += LIBC_BITS + +LIBC_BITS_ARTIFACTS += LIBC_BITS_A +LIBC_BITS = $(LIBC_BITS_A_DEPS) $(LIBC_BITS_A) +LIBC_BITS_A = o/$(MODE)/libc/bits/bits.a +LIBC_BITS_A_FILES := $(wildcard libc/bits/*) +LIBC_BITS_A_HDRS = $(filter %.h,$(LIBC_BITS_A_FILES)) +LIBC_BITS_A_SRCS_S = $(filter %.S,$(LIBC_BITS_A_FILES)) +LIBC_BITS_A_SRCS_C = $(filter %.c,$(LIBC_BITS_A_FILES)) + +LIBC_BITS_A_SRCS = \ + $(LIBC_BITS_A_SRCS_S) \ + $(LIBC_BITS_A_SRCS_C) + +LIBC_BITS_A_OBJS = \ + $(LIBC_BITS_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_BITS_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_BITS_A_SRCS_C:%.c=o/$(MODE)/%.o) + +LIBC_BITS_A_CHECKS = \ + $(LIBC_BITS_A).pkg \ + $(LIBC_BITS_A_HDRS:%=o/$(MODE)/%.ok) + +LIBC_BITS_A_DIRECTDEPS = \ + LIBC_STUBS \ + LIBC_NEXGEN32E + +LIBC_BITS_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_BITS_A_DIRECTDEPS),$($(x)))) + +$(LIBC_BITS_A): libc/bits/ \ + $(LIBC_BITS_A).pkg \ + $(LIBC_BITS_A_OBJS) + +$(LIBC_BITS_A).pkg: \ + $(LIBC_BITS_A_OBJS) \ + $(foreach x,$(LIBC_BITS_A_DIRECTDEPS),$($(x)_A).pkg) + +#o/$(MODE)/libc/bits/bsf.o: CC = clang-10 +#o/$(MODE)/libc/bits/bsf.o: CC = /opt/cross9cc/bin/x86_64-linux-musl-cc + +LIBC_BITS_LIBS = $(foreach x,$(LIBC_BITS_ARTIFACTS),$($(x))) +LIBC_BITS_SRCS = $(foreach x,$(LIBC_BITS_ARTIFACTS),$($(x)_SRCS)) +LIBC_BITS_HDRS = $(foreach x,$(LIBC_BITS_ARTIFACTS),$($(x)_HDRS)) +LIBC_BITS_CHECKS = $(foreach x,$(LIBC_BITS_ARTIFACTS),$($(x)_CHECKS)) +LIBC_BITS_OBJS = $(foreach x,$(LIBC_BITS_ARTIFACTS),$($(x)_OBJS)) +$(LIBC_BITS_OBJS): $(BUILD_FILES) libc/bits/bits.mk + +.PHONY: o/$(MODE)/libc/bits +o/$(MODE)/libc/bits: $(LIBC_BITS_CHECKS) diff --git a/libc/bits/emmintrin.h b/libc/bits/emmintrin.h new file mode 100644 index 00000000..d10c6d6f --- /dev/null +++ b/libc/bits/emmintrin.h @@ -0,0 +1,217 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_EMMINTRIN_H_ +#define COSMOPOLITAN_LIBC_BITS_EMMINTRIN_H_ +#include "libc/bits/progn.h" +#include "libc/bits/xmmintrin.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § sse2 ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +typedef char __v16qi _Vector_size(16); +typedef unsigned char __v16qu _Vector_size(16); +typedef signed char __v16qs _Vector_size(16); + +typedef short __v8hi _Vector_size(16); +typedef unsigned short __v8hu _Vector_size(16); + +typedef double __v2df _Vector_size(16); +typedef double __m128d _Vector_size(16) aligned(16); +typedef double __m128d_u _Vector_size(16) aligned(1); + +typedef long long __v2di _Vector_size(16); +typedef long long __m128i _Vector_size(16) aligned(16); +typedef long long __m128i_u _Vector_size(16) aligned(1); +typedef unsigned long long __v2du _Vector_size(16); + +struct thatispacked mayalias __usi128ma { + __m128i_u __v; +}; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § sse2 » memory ops ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define _mm_loadu_si128(M128IP) ((struct __usi128ma *)(M128IP))->__v +#define _mm_storeu_si128(M128IP, M128I) \ + (((struct __usi128ma *)(M128IP))->__v = (M128I)) + +#define _mm_set_epi8(I8_15, I8_14, I8_13, I8_12, I8_11, I8_10, I8_9, I8_8, \ + I8_7, I8_6, I8_5, I8_4, I8_3, I8_2, I8_1, I8_0) \ + ((__m128i)(__v16qi){I8_0, I8_1, I8_2, I8_3, I8_4, I8_5, I8_6, I8_7, I8_8, \ + I8_9, I8_10, I8_11, I8_12, I8_13, I8_14, I8_15}) +#define _mm_set_epi16(I16_7, I16_6, I16_5, I16_4, I16_3, I16_2, I16_1, I16_0) \ + ((__m128i)(__v8hi){I16_0, I16_1, I16_2, I16_3, I16_4, I16_5, I16_6, I16_7}) +#define _mm_set_epi32(I32_3, I32_2, I32_1, I32_0) \ + ((__m128i)(__v4si){I32_0, I32_1, I32_2, I32_3}) +#define _mm_set_epi64x(I64_1, I64_0) ((__m128i)(__v2di){I64_0, I64_1}) + +#define _mm_setr_epi8(I8_15, I8_14, I8_13, I8_12, I8_11, I8_10, I8_9, I8_8, \ + I8_7, I8_6, I8_5, I8_4, I8_3, I8_2, I8_1, I8_0) \ + _mm_set_epi8(I8_0, I8_1, I8_2, I8_3, I8_4, I8_5, I8_6, I8_7, I8_8, I8_9, \ + I8_10, I8_11, I8_12, I8_13, I8_14, I8_15) +#define _mm_setr_epi16(I16_7, I16_6, I16_5, I16_4, I16_3, I16_2, I16_1, I16_0) \ + _mm_set_epi16(I16_0, I16_1, I16_2, I16_3, I16_4, I16_5, I16_6, I16_7) +#define _mm_setr_epi32(I32_3, I32_2, I32_1, I32_0) \ + _mm_set_epi32(I32_0, I32_1, I32_2, I32_3) +#define _mm_setr_epi64x(I64_1, I64_0) _mm_set_epi64x(I64_0, I64_1) + +#define _mm_set1_epi8(I8) \ + _mm_set_epi8(I8, I8, I8, I8, I8, I8, I8, I8, I8, I8, I8, I8, I8, I8, I8, I8) +#define _mm_set1_epi16(I16) \ + _mm_set_epi16(I16, I16, I16, I16, I16, I16, I16, I16) +#define _mm_set1_epi32(I32) _mm_set_epi32(I32, I32, I32, I32) +#define _mm_set1_epi64x(I64) _mm_set_epi64x(I64, I64) + +#define _mm_cvtsi128_si32(M128I) ((__v4si)(M128I))[0] +#define _mm_cvtsi32_si128(I32) ((__m128i)(__v4si){(I32), 0, 0, 0}) +#define _mm_setzero_si128() ((__m128i)(__v2di){0LL, 0LL}) +#define _mm_castsi128_ps(M128I) ((__m128)(M128I)) +#define _mm_castps_si128(M128) ((__m128i)(M128)) +#define _mm_load_si128(M128I) (*(M128I)) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § sse2 » simd ops ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define _mm_and_si128(M128I_0, M128I_1) \ + ((__m128i)((__v2du)(M128I_0) & (__v2du)(M128I_1))) +#define _mm_or_si128(M128I_0, M128I_1) \ + ((__m128i)((__v2du)(M128I_0) | (__v2du)(M128I_1))) +#define _mm_xor_si128(M128I_0, M128I_1) \ + ((__m128i)((__v2du)(M128I_0) ^ (__v2du)(M128I_1))) +#define _mm_andnot_si128(M128I_0, M128I_1) \ + ((__m128i)(~(__v2du)(M128I_0) & (__v2du)(M128I_1))) + +#define _mm_add_pd(M128D_0, M128D_1) \ + (__m128d)((__v2df)(M128D_0) + (__v2df)(M128D_1)) +#define _mm_sub_pd(M128D_0, M128D_1) \ + (__m128d)((__v2df)(M128D_0) - (__v2df)(M128D_1)) +#define _mm_mul_pd(M128D_0, M128D_1) \ + (__m128d)((__v2df)(M128D_0) * (__v2df)(M128D_1)) +#define _mm_div_pd(M128D_0, M128D_1) \ + (__m128d)((__v2df)(M128D_0) / (__v2df)(M128D_1)) +#define _mm_and_pd(M128D_0, M128D_1) \ + (__m128d)((__v2df)(M128D_0) & (__v2df)(M128D_1)) +#define _mm_or_pd(M128D_0, M128D_1) \ + (__m128d)((__v2df)(M128D_0) | (__v2df)(M128D_1)) +#define _mm_xor_pd(M128D_0, M128D_1) \ + (__m128d)((__v2df)(M128D_0) ^ (__v2df)(M128D_1)) +#define _mm_andnot_pd(M128D_0, M128D_1) \ + (__m128d)(~(__v2df)(M128D_0) & (__v2df)(M128D_1)) +#define _mm_sqrt_pd(M128D) __builtin_ia32_sqrtpd((__v2df)(M128D)) + +#define _mm_min_pd(M128D_0, M128D_1) \ + __builtin_ia32_minpd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_max_pd(M128D_0, M128D_1) \ + __builtin_ia32_maxpd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_cmpeq_pd(M128D_0, M128D_1) \ + __builtin_ia32_cmpeqpd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_cmpneq_pd(M128D_0, M128D_1) \ + __builtin_ia32_cmpneqpd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_cmplt_pd(M128D_0, M128D_1) \ + __builtin_ia32_cmpltpd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_cmpnlt_pd(M128D_0, M128D_1) \ + __builtin_ia32_cmpnltpd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_cmple_pd(M128D_0, M128D_1) \ + __builtin_ia32_cmplepd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_cmpnle_pd(M128D_0, M128D_1) \ + __builtin_ia32_cmpnlepd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_cmpgt_pd(M128D_0, M128D_1) \ + __builtin_ia32_cmpltpd((__v2df)(M128D_1), (__v2df)(M128D_0)) +#define _mm_cmpngt_pd(M128D_0, M128D_1) \ + __builtin_ia32_cmpnltpd((__v2df)(M128D_1), (__v2df)(M128D_0)) +#define _mm_cmpge_pd(M128D_0, M128D_1) \ + __builtin_ia32_cmplepd((__v2df)(M128D_1), (__v2df)(M128D_0)) +#define _mm_cmpnge_pd(M128D_0, M128D_1) \ + __builtin_ia32_cmpnlepd((__v2df)(M128D_1), (__v2df)(M128D_0)) +#define _mm_cmpord_pd(M128D_0, M128D_1) \ + __builtin_ia32_cmpordpd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_cmpunord_pd(M128D_0, M128D_1) \ + __builtin_ia32_cmpunordpd((__v2df)(M128D_0), (__v2df)(M128D_1)) + +#define _mm_sad_epu8(M128I_0, M128I_1) \ + __builtin_ia32_psadbw128((__v16qi)(M128I_0), (__v16qi)(M128I_1)) + +#define _mm_subs_epi8(M128I_0, M128I_1) \ + ((__m128i)__builtin_ia32_psubsb128((__v16qi)(M128I_0), (__v16qi)(M128I_1))) +#define _mm_subs_epu8(M128I_0, M128I_1) \ + ((__m128i)__builtin_ia32_psubusw128((__v16qi)(M128I_0), (__v16qi)(M128I_1))) +#define _mm_subs_epi16(M128I_0, M128I_1) \ + ((__m128i)__builtin_ia32_psubsw128((__v8hi)(M128I_0), (__v8hi)(M128I_1))) +#define _mm_subs_epu16(M128I_0, M128I_1) \ + ((__m128i)__builtin_ia32_psubusw128((__v8hi)(M128I_0), (__v8hi)(M128I_1))) + +#define _mm_add_epi32(M128I_0, M128I_1) \ + ((__m128i)((__v4su)(M128I_0) + (__v4su)(M128I_1))) +#define _mm_sub_epi32(M128I_0, M128I_1) \ + ((__m128i)((__v4su)(M128I_0) - (__v4su)(M128I_1))) +#define _mm_madd_epi16(M128I_0, M128I_1) \ + ((__m128i)__builtin_ia32_pmaddwd128((__v8hi)(M128I_0), (__v8hi)(M128I_1))) +#define _mm_shuffle_epi32(V, IMM) \ + ((__m128i)__builtin_ia32_pshufd((__v4si)(__m128i)(V), (int)(IMM))) + +#define _mm_slli_epi32(M128I, COUNT) \ + ((__m128i)__builtin_ia32_pslldi128((__v4si)(M128I), (COUNT))) + +#define _mm_slli_si128(M128I, IMM) \ + ((__m128i)__builtin_ia32_pslldqi128((__v2di)(__m128i)(M128I), (int)(IMM)*8)) +#define _mm_srli_si128(M128I, IMM) \ + ((__m128i)__builtin_ia32_psrldqi128((__v2di)(__m128i)(M128I), (int)(IMM)*8)) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § sse2 » scalar ops ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define _mm_sqrt_sd(M128D_0, M128D_1) \ + ({ \ + __m128d M128d2 = __builtin_ia32_sqrtsd((__v2df)(M128D_1)); \ + (__m128d){M128d2[0], (M128D_0)[1]}; \ + }) + +#define _mm_add_sd(M128D_0, M128D_1) \ + PROGN((M128D_0)[0] += (M128D_1)[0], (M128D_0)) +#define _mm_sub_sd(M128D_0, M128D_1) \ + PROGN((M128D_0)[0] -= (M128D_1)[0], (M128D_0)) +#define _mm_mul_sd(M128D_0, M128D_1) \ + PROGN((M128D_0)[0] *= (M128D_1)[0], (M128D_0)) +#define _mm_div_sd(M128D_0, M128D_1) \ + PROGN((M128D_0)[0] /= (M128D_1)[0], (M128D_0)) + +#define _mm_min_sd(M128D_0, M128D_1) \ + __builtin_ia32_minsd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_max_sd(M128D_0, M128D_1) \ + __builtin_ia32_maxsd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_cmpeq_sd(M128D_0, M128D_1) \ + __builtin_ia32_cmpeqsd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_cmpneq_sd(M128D_0, M128D_1) \ + __builtin_ia32_cmpneqsd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_cmplt_sd(M128D_0, M128D_1) \ + __builtin_ia32_cmpltsd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_cmpnlt_sd(M128D_0, M128D_1) \ + __builtin_ia32_cmpnltsd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_cmple_sd(M128D_0, M128D_1) \ + __builtin_ia32_cmplesd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_cmpnle_sd(M128D_0, M128D_1) \ + __builtin_ia32_cmpnlesd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_cmpgt_sd(M128D_0, M128D_1) \ + __builtin_ia32_cmpltsd((__v2df)(M128D_1), (__v2df)(M128D_0)) +#define _mm_cmpngt_sd(M128D_0, M128D_1) \ + __builtin_ia32_cmpnltsd((__v2df)(M128D_1), (__v2df)(M128D_0)) +#define _mm_cmpge_sd(M128D_0, M128D_1) \ + __builtin_ia32_cmplesd((__v2df)(M128D_1), (__v2df)(M128D_0)) +#define _mm_cmpnge_sd(M128D_0, M128D_1) \ + __builtin_ia32_cmpnlesd((__v2df)(M128D_1), (__v2df)(M128D_0)) +#define _mm_cmpord_sd(M128D_0, M128D_1) \ + __builtin_ia32_cmpordsd((__v2df)(M128D_0), (__v2df)(M128D_1)) +#define _mm_cmpunord_sd(M128D_0, M128D_1) \ + __builtin_ia32_cmpunordsd((__v2df)(M128D_0), (__v2df)(M128D_1)) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § sse2 » miscellaneous ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define _mm_pause() asm("rep nop") + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_EMMINTRIN_H_ */ diff --git a/libc/bits/emptytonull.c b/libc/bits/emptytonull.c new file mode 100644 index 00000000..059f16e6 --- /dev/null +++ b/libc/bits/emptytonull.c @@ -0,0 +1,21 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +const char *emptytonull(const char *s) { return s && !*s ? 0 : s; } diff --git a/libc/bits/firstnonnull.c b/libc/bits/firstnonnull.c new file mode 100644 index 00000000..3bcd6727 --- /dev/null +++ b/libc/bits/firstnonnull.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/runtime.h" + +const char *(firstnonnull)(const char *a, const char *b) { + if (a) return a; + if (b) return b; + abort(); +} diff --git a/libc/bits/gray.c b/libc/bits/gray.c new file mode 100644 index 00000000..cabfb123 --- /dev/null +++ b/libc/bits/gray.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +uint32_t gray(uint32_t x) { return x ^ (x >> 1); } + +uint32_t ungray(uint32_t x) { + x ^= x >> 16; + x ^= x >> 8; + x ^= x >> 4; + x ^= x >> 2; + x ^= x >> 1; + return x; +} diff --git a/libc/bits/hamming.c b/libc/bits/hamming.c new file mode 100644 index 00000000..5f74b472 --- /dev/null +++ b/libc/bits/hamming.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" + +unsigned long(hamming)(unsigned long x, unsigned long y) { + return popcount(x ^ y); +} diff --git a/libc/bits/hilbert.c b/libc/bits/hilbert.c new file mode 100644 index 00000000..c6074d54 --- /dev/null +++ b/libc/bits/hilbert.c @@ -0,0 +1,75 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/hilbert.h" + +static axdx_t RotateQuadrant(long n, long y, long x, long ry, long rx) { + long t; + if (ry == 0) { + if (rx == 1) { + y = n - 1 - y; + x = n - 1 - x; + } + t = x; + x = y; + y = t; + } + return (axdx_t){y, x}; +} + +/** + * Generates Hilbert space-filling curve. + * + * @see morton() + */ +long hilbert(long n, long y, long x) { + axdx_t m; + long d, s, ry, rx; + d = 0; + for (s = n / 2; s > 0; s /= 2) { + rx = (x & s) > 0; + ry = (y & s) > 0; + d += s * s * ((3 * rx) ^ ry); + m = RotateQuadrant(n, y, x, ry, rx); + x = m.dx; + y = m.ax; + } + return d; +} + +/** + * Decodes Hilbert space-filling curve. + * + * @see unmorton() + */ +axdx_t unhilbert(long n, long i) { + axdx_t m; + long s, t, y, x, ry, rx; + t = i; + x = y = 0; + for (s = 1; s < n; s *= 2) { + rx = (t / 2) & 1; + ry = (t ^ rx) & 1; + m = RotateQuadrant(s, y, x, ry, rx); + x = m.dx + s * rx; + y = m.ax + s * ry; + t /= 4; + } + return (axdx_t){y, x}; +} diff --git a/libc/bits/hilbert.h b/libc/bits/hilbert.h new file mode 100644 index 00000000..49ba62a7 --- /dev/null +++ b/libc/bits/hilbert.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_HILBERT_H_ +#define COSMOPOLITAN_LIBC_BITS_HILBERT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +long hilbert(long, long, long) pureconst; +axdx_t unhilbert(long, long) pureconst; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_HILBERT_H_ */ diff --git a/libc/bits/i2bcd.S b/libc/bits/i2bcd.S new file mode 100644 index 00000000..03844289 --- /dev/null +++ b/libc/bits/i2bcd.S @@ -0,0 +1,48 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +/ Converts integer to binary-coded decimal. +i2bcd: .leafprologue + .profilable + test %rdi,%rdi + je 2f + mov %rdi,%rsi + xor %r9d,%r9d + mov $0xcccccccccccccccd,%r8 + xor %ecx,%ecx +1: mov %rsi,%rax + mul %r8 + shr $3,%rdx + lea (%rdx,%rdx),%rax + lea (%rax,%rax,4),%rax + mov %rsi,%rdi + sub %rax,%rdi + shl %cl,%rdi + add %rdi,%r9 + add $4,%rcx + cmp $9,%rsi + mov %rdx,%rsi + ja 1b + jmp 3f +2: xor %r9d,%r9d +3: mov %r9,%rax + .leafepilogue + .endfn i2bcd,globl diff --git a/libc/bits/isempty.c b/libc/bits/isempty.c new file mode 100644 index 00000000..22734db0 --- /dev/null +++ b/libc/bits/isempty.c @@ -0,0 +1,21 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +bool isempty(const char *s) { return !s || !*s; } diff --git a/libc/bits/max.c b/libc/bits/max.c new file mode 100644 index 00000000..6a131824 --- /dev/null +++ b/libc/bits/max.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +long(max)(long x, long y) { return MAX(x, y); } diff --git a/libc/bits/min.c b/libc/bits/min.c new file mode 100644 index 00000000..43130254 --- /dev/null +++ b/libc/bits/min.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +long(min)(long x, long y) { return MIN(x, y); } diff --git a/libc/bits/mmintrin.h b/libc/bits/mmintrin.h new file mode 100644 index 00000000..63fcc4fb --- /dev/null +++ b/libc/bits/mmintrin.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_MMINTRIN_H_ +#define COSMOPOLITAN_LIBC_BITS_MMINTRIN_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +typedef long long __m64 _Vector_size(8); +typedef float __v2sf _Vector_size(8); +typedef int __v2si _Vector_size(8); +typedef short __v4hi _Vector_size(8); +typedef char __v8qi _Vector_size(8); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_MMINTRIN_H_ */ diff --git a/libc/bits/morton.c b/libc/bits/morton.c new file mode 100644 index 00000000..680bf437 --- /dev/null +++ b/libc/bits/morton.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/morton.h" + +/** + * Interleaves bits. + */ +unsigned long(morton)(unsigned long y, unsigned long x) { + x = (x | x << 020) & 0x0000FFFF0000FFFF; + x = (x | x << 010) & 0x00FF00FF00FF00FF; + x = (x | x << 004) & 0x0F0F0F0F0F0F0F0F; + x = (x | x << 002) & 0x3333333333333333; + x = (x | x << 001) & 0x5555555555555555; + y = (y | y << 020) & 0x0000FFFF0000FFFF; + y = (y | y << 010) & 0x00FF00FF00FF00FF; + y = (y | y << 004) & 0x0F0F0F0F0F0F0F0F; + y = (y | y << 002) & 0x3333333333333333; + y = (y | y << 001) & 0x5555555555555555; + return x | y << 1; +} diff --git a/libc/bits/morton.h b/libc/bits/morton.h new file mode 100644 index 00000000..67bf743d --- /dev/null +++ b/libc/bits/morton.h @@ -0,0 +1,25 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_MORTON_H_ +#define COSMOPOLITAN_LIBC_BITS_MORTON_H_ +#include "libc/intrin/pdep.h" +#include "libc/intrin/pext.h" +#include "libc/nexgen32e/x86feature.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +unsigned long morton(unsigned long, unsigned long) libcesque pureconst; +axdx_t unmorton(unsigned long) libcesque pureconst; + +#ifndef __STRICT_ANSI__ +#define morton(Y, X) \ + (X86_NEED(BMI2) \ + ? pdep(X, 0x5555555555555555ul) | pdep(Y, 0xAAAAAAAAAAAAAAAAul) \ + : morton(Y, X)) +#define unmorton(I) \ + (X86_NEED(BMI2) ? (axdx_t){pext(I, 0xAAAAAAAAAAAAAAAAul), \ + pext(I, 0x5555555555555555ul)} \ + : unmorton(I)) +#endif + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_MORTON_H_ */ diff --git a/libc/bits/nulltoempty.c b/libc/bits/nulltoempty.c new file mode 100644 index 00000000..524ba5e9 --- /dev/null +++ b/libc/bits/nulltoempty.c @@ -0,0 +1,21 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +const char *nulltoempty(const char *s) { return s ? s : ""; } diff --git a/libc/bits/pmmintrin.h b/libc/bits/pmmintrin.h new file mode 100644 index 00000000..9f838afc --- /dev/null +++ b/libc/bits/pmmintrin.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_PMMINTRIN_H_ +#define COSMOPOLITAN_LIBC_BITS_PMMINTRIN_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § sse3 ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define _mm_hadd_ps(M128_0, M128_1) \ + ((__m128)__builtin_ia32_haddps((__v4sf)(__m128)(M128_0), \ + (__v4sf)(__m128)(M128_0))) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_PMMINTRIN_H_ */ diff --git a/libc/bits/popcount.c b/libc/bits/popcount.c new file mode 100644 index 00000000..d201846a --- /dev/null +++ b/libc/bits/popcount.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/nexgen32e/x86feature.h" + +static noinline uint32_t popcount$swar32(uint32_t x) { + x -= (x >> 1) & 0x55555555; + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + return (((x + (x >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24; +} + +unsigned long(popcount)(unsigned long x) { + size_t i; + unsigned long r; + if (X86_HAVE(POPCNT)) { + return popcount$nehalem(x); + } else { + r = 0; + for (i = 0; i < sizeof(x); i += 4) { + r |= popcount$swar32(x); + x >>= 32; + } + return r; + } +} diff --git a/libc/bits/progn.h b/libc/bits/progn.h new file mode 100644 index 00000000..1cc51c4d --- /dev/null +++ b/libc/bits/progn.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_PROGN_H_ +#define COSMOPOLITAN_LIBC_BITS_PROGN_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * Evaluates args, returning value of last one. + * + * This API comes from LISP. + */ +#define PROGN(...) ({ __VA_ARGS__; }) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_PROGN_H_ */ diff --git a/libc/bits/pushpop.h b/libc/bits/pushpop.h new file mode 100644 index 00000000..caf26b4e --- /dev/null +++ b/libc/bits/pushpop.h @@ -0,0 +1,53 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_PUSHPOP_H_ +#define COSMOPOLITAN_LIBC_BITS_PUSHPOP_H_ +#include "libc/macros.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * PushPop + * An elegant weapon for a more civilized age. + */ +#if !defined(__GNUC__) || defined(__STRICT_ANSI__) +#define pushpop(x) (x) +#else +#define pushpop(x) \ + ({ \ + typeof(x) Popped; \ + if (isconstant(x) && (TYPE_SIGNED(typeof(x)) ? (intptr_t)(x) + 128 < 256 \ + : (intptr_t)(x) < 128)) { \ + if (x) { \ + asm("push\t%1\n\t" \ + "pop\t%q0" \ + : "=r"(Popped) \ + : "ir"(x)); \ + } else { \ + asm("xor\t%k0,%k0" : "=r"(Popped)); \ + } \ + } else { \ + asm("" : "=r"(Popped) : "0"(x)); \ + } \ + Popped; \ + }) +#endif + +#if !defined(__GNUC__) || defined(__STRICT_ANSI__) +#define pushmov(d, x) ((d) = (x)) +#else +#define pushmov(d, x) \ + ({ \ + typeof(*(d)) Popped = (x); \ + if (isconstant(x) && (TYPE_SIGNED(typeof(x)) ? (intptr_t)(x) + 128 < 256 \ + : (intptr_t)(x) < 128)) { \ + asm("pushq\t%1\n\t" \ + "popq\t%0" \ + : "=m"(*(d)) \ + : "ir"(Popped)); \ + } else { \ + *(d) = Popped; \ + } \ + Popped; \ + }) +#endif + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_PUSHPOP_H_ */ diff --git a/libc/bits/rounddown.c b/libc/bits/rounddown.c new file mode 100644 index 00000000..44b01586 --- /dev/null +++ b/libc/bits/rounddown.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +long(rounddown)(long w, long k) { return ROUNDDOWN(w, k); } diff --git a/libc/bits/rounddown2pow.c b/libc/bits/rounddown2pow.c new file mode 100644 index 00000000..12cb6ad3 --- /dev/null +++ b/libc/bits/rounddown2pow.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/nexgen32e/bsr.h" + +/** + * Returns 𝑥 rounded down to previous two power. + * + * @define (𝑥>0→2^⌊log₂𝑥⌋, x=0→0, 𝑇→⊥) + * @see roundup2pow() + */ +unsigned long rounddown2pow(unsigned long x) { + return x ? 1ul << bsrl(x) : 0; +} diff --git a/libc/bits/roundup.c b/libc/bits/roundup.c new file mode 100644 index 00000000..7328d356 --- /dev/null +++ b/libc/bits/roundup.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +long(roundup)(long w, long k) { return ROUNDUP(w, k); } diff --git a/libc/bits/roundup2log.c b/libc/bits/roundup2log.c new file mode 100644 index 00000000..843e3501 --- /dev/null +++ b/libc/bits/roundup2log.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/nexgen32e/bsr.h" + +/** + * Returns 𝑥 rounded up to next two power and log'd. + * @see roundup2pow + */ +unsigned long roundup2log(unsigned long x) { + return x > 1 ? (bsrl(x - 1) + 1) : x ? 1 : 0; +} diff --git a/libc/bits/roundup2pow.c b/libc/bits/roundup2pow.c new file mode 100644 index 00000000..d4ae7baf --- /dev/null +++ b/libc/bits/roundup2pow.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/nexgen32e/bsr.h" + +/** + * Returns 𝑥 rounded up to next two power. + * + * @define (𝑥>0→2^⌈log₂x⌉, x=0→0, 𝑇→⊥) + * @see rounddown2pow)() + */ +unsigned long roundup2pow(unsigned long x) { + return x > 1 ? 1ul << (bsrl(x - 1) + 1) : x ? 1 : 0; +} diff --git a/libc/bits/safemacros.h b/libc/bits/safemacros.h new file mode 100644 index 00000000..df8c5783 --- /dev/null +++ b/libc/bits/safemacros.h @@ -0,0 +1,86 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_SAFEMACROS_H_ +#define COSMOPOLITAN_LIBC_BITS_SAFEMACROS_H_ +#include "libc/limits.h" +#include "libc/macros.h" +#include "libc/runtime/runtime.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +long min(long x, long y); +long max(long x, long y); +long roundup(long w, long k); +long rounddown(long w, long k); +bool isempty(const char *s); +const char *nulltoempty(const char *s); +const char *emptytonull(const char *s); +const char *firstnonnull(const char *a, const char *b); +uint64_t(unsignedsubtract)(uint64_t x, uint64_t y) pureconst; + +#if !defined(__STRICT_ANSI__) && defined(__GNUC__) + +#define min(x, y) \ + ({ \ + autotype(x) MinX = (x); \ + autotype(y) MinY = (y); \ + MinX < MinY ? MinX : MinY; \ + }) + +#define max(x, y) \ + ({ \ + autotype(x) MaxX = (x); \ + autotype(y) MaxY = (y); \ + MaxX > MaxY ? MaxX : MaxY; \ + }) + +#define roundup(x, k) \ + ({ \ + autotype(x) RoundupX = (x); \ + autotype(k) RoundupK = (k); \ + ROUNDUP(RoundupX, RoundupK); \ + }) + +#define rounddown(x, k) \ + ({ \ + autotype(x) RounddownX = (x); \ + autotype(k) RounddownK = (k); \ + ROUNDDOWN(RounddownX, RounddownK); \ + }) + +#define isempty(s) \ + ({ \ + autotype(s) IsEmptyS = (s); \ + !IsEmptyS || !(*IsEmptyS); \ + }) + +#define nulltoempty(s) \ + ({ \ + autotype(s) NullToEmptyS = (s); \ + NullToEmptyS ? NullToEmptyS : ""; \ + }) + +#define firstnonnull(a, b) \ + ({ \ + autotype(a) FirstNonNullA = (a); \ + autotype(a) FirstNonNullB = (b); \ + if (!FirstNonNullA && !FirstNonNullB) abort(); \ + FirstNonNullA ? FirstNonNullA : FirstNonNullB; \ + }) + +#define emptytonull(s) \ + ({ \ + autotype(s) EmptyToNullS = (s); \ + EmptyToNullS && !(*EmptyToNullS) ? NULL : EmptyToNullS; \ + }) + +#define unsignedsubtract(a, b) \ + ({ \ + uint64_t UnsubA = (a); \ + uint64_t UnsubB = (b); \ + UnsubA >= UnsubB ? UnsubA - UnsubB : ~UnsubB + UnsubA + 1; \ + }) + +#endif /* GNU && !ANSI */ + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_SAFEMACROS_H_ */ diff --git a/libc/bits/shaintrin.h b/libc/bits/shaintrin.h new file mode 100644 index 00000000..785f58d2 --- /dev/null +++ b/libc/bits/shaintrin.h @@ -0,0 +1,37 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_SHAINTRIN_H_ +#define COSMOPOLITAN_LIBC_BITS_SHAINTRIN_H_ +#include "libc/bits/emmintrin.h" +#include "libc/bits/xmmintrin.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define _mm_sha1rnds4_epu32(M128I_0, M128I_1, MEM) \ + __builtin_ia32_sha1rnds4((__v4si)(__m128i)(M128I_0), \ + (__v4si)(__m128i)(M128I_1), (MEM)) + +#define _mm_sha1nexte_epu32(M128I_0, M128I_1) \ + ((__m128i)__builtin_ia32_sha1nexte((__v4si)(__m128i)(M128I_0), \ + (__v4si)(__m128i)(M128I_1))) + +#define _mm_sha1msg1_epu32(M128I_0, M128I_1) \ + ((__m128i)__builtin_ia32_sha1msg1((__v4si)(__m128i)(M128I_0), \ + (__v4si)(__m128i)(M128I_1))) + +#define _mm_sha1msg2_epu32(M128I_0, M128I_1) \ + ((__m128i)__builtin_ia32_sha1msg2((__v4si)(__m128i)(M128I_0), \ + (__v4si)(__m128i)(M128I_1))) + +#define _mm_sha256rnds2_epu32(M128I_0, M128I_1, M128I_2) \ + ((__m128i)__builtin_ia32_sha256rnds2((__v4si)(__m128i)(M128I_0), \ + (__v4si)(__m128i)(M128I_1), \ + (__v4si)(__m128i)(M128I_2))) + +#define _mm_sha256msg1_epu32(M128I_0, M128I_1) \ + ((__m128i)__builtin_ia32_sha256msg1((__v4si)(__m128i)(M128I_0), \ + (__v4si)(__m128i)(M128I_1))) + +#define _mm_sha256msg2_epu32(M128I_0, M128I_1) \ + ((__m128i)__builtin_ia32_sha256msg2((__v4si)(__m128i)(M128I_0), \ + (__v4si)(__m128i)(M128I_1))) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_SHAINTRIN_H_ */ diff --git a/libc/bits/smmintrin.h b/libc/bits/smmintrin.h new file mode 100644 index 00000000..2d470135 --- /dev/null +++ b/libc/bits/smmintrin.h @@ -0,0 +1,31 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_SMMINTRIN_H_ +#define COSMOPOLITAN_LIBC_BITS_SMMINTRIN_H_ + +/** + * @fileoverview SSE4 intrinsics. + */ + +#define _MM_FROUND_CEIL (_MM_FROUND_TO_POS_INF | _MM_FROUND_RAISE_EXC) +#define _MM_FROUND_CUR_DIRECTION 4 +#define _MM_FROUND_FLOOR (_MM_FROUND_TO_NEG_INF | _MM_FROUND_RAISE_EXC) +#define _MM_FROUND_NEARBYINT (_MM_FROUND_CUR_DIRECTION | _MM_FROUND_NO_EXC) +#define _MM_FROUND_NINT (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_RAISE_EXC) +#define _MM_FROUND_NO_EXC 8 +#define _MM_FROUND_RAISE_EXC 0 +#define _MM_FROUND_RINT (_MM_FROUND_CUR_DIRECTION | _MM_FROUND_RAISE_EXC) +#define _MM_FROUND_TO_NEAREST_INT 0 +#define _MM_FROUND_TO_NEG_INF 1 +#define _MM_FROUND_TO_POS_INF 2 +#define _MM_FROUND_TO_ZERO 3 +#define _MM_FROUND_TRUNC (_MM_FROUND_TO_ZERO | _MM_FROUND_RAISE_EXC) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define _mm_extract_epi32(M128I, I32) \ + ((int)__builtin_ia32_vec_ext_v4si((__v4si)(__m128i)(M128I), (int)(I32))) + +#define _mm_minpos_epu16(M128I) \ + ((int)__builtin_ia32_phminposuw128((__v4si)(__m128i)(M128I), (int)(I32))) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_SMMINTRIN_H_ */ diff --git a/libc/bits/tmmintrin.h b/libc/bits/tmmintrin.h new file mode 100644 index 00000000..52a78349 --- /dev/null +++ b/libc/bits/tmmintrin.h @@ -0,0 +1,17 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_TMMINTRIN_H_ +#define COSMOPOLITAN_LIBC_BITS_TMMINTRIN_H_ +#include "libc/bits/emmintrin.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § ssse3 ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define _mm_maddubs_epi16(M128I_0, M128I_1) \ + ((__m128i)__builtin_ia32_pmaddubsw128((__v16qi)(M128I_0), (__v16qi)(M128I_1))) + +#define _mm_shuffle_epi8(M128I_0, M128I_1) \ + ((__m128i)__builtin_ia32_pshufb128((__v16qi)(M128I_0), (__v16qi)(M128I_1))) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_TMMINTRIN_H_ */ diff --git a/libc/bits/typecheck.h b/libc/bits/typecheck.h new file mode 100644 index 00000000..d6a240a7 --- /dev/null +++ b/libc/bits/typecheck.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_TYPECHECK_H_ +#define COSMOPOLITAN_LIBC_BITS_TYPECHECK_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define TYPECHECK(T, X) \ + ({ \ + T Lol1; \ + typeof(X) Lol2; \ + (void)(&Lol1 == &Lol2); \ + X; \ + }) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_TYPECHECK_H_ */ diff --git a/libc/bits/unmorton.c b/libc/bits/unmorton.c new file mode 100644 index 00000000..e54d2d98 --- /dev/null +++ b/libc/bits/unmorton.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/morton.h" + +static unsigned long GetOddBits(unsigned long x) { + x = (x | x >> 000) & 0x5555555555555555; + x = (x | x >> 001) & 0x3333333333333333; + x = (x | x >> 002) & 0x0F0F0F0F0F0F0F0F; + x = (x | x >> 004) & 0x00FF00FF00FF00FF; + x = (x | x >> 010) & 0x0000FFFF0000FFFF; + x = (x | x >> 020) & 0x00000000FFFFFFFF; + return x; +} + +/** + * Deinterleaves bits. + * + * @param 𝑖 is interleaved index + * @return deinterleaved coordinate {ax := 𝑦, dx := 𝑥} + * @see en.wikipedia.org/wiki/Z-order_curve + */ +axdx_t(unmorton)(unsigned long i) { + return (axdx_t){GetOddBits(i >> 1), GetOddBits(i)}; +} diff --git a/libc/bits/unsignedsubtract.c b/libc/bits/unsignedsubtract.c new file mode 100644 index 00000000..e8ae3712 --- /dev/null +++ b/libc/bits/unsignedsubtract.c @@ -0,0 +1,27 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" + +/** + * Subtracts unsigned integers w/ wraparound. + */ +uint64_t(unsignedsubtract)(uint64_t x, uint64_t y) { + return unsignedsubtract(x, y); +} diff --git a/libc/bits/wmmintrin.h b/libc/bits/wmmintrin.h new file mode 100644 index 00000000..f7520618 --- /dev/null +++ b/libc/bits/wmmintrin.h @@ -0,0 +1,29 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_WMMINTRIN_H_ +#define COSMOPOLITAN_LIBC_BITS_WMMINTRIN_H_ +#include "libc/bits/emmintrin.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define _mm_clmulepi64_si128(X, Y, IMM) \ + ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(X), \ + (__v2di)(__m128i)(Y), (char)(IMM))) + +#define _mm_aesenc_si128(M128I_0, M128I_1) \ + ((__m128i)__builtin_ia32_aesenc128((__v2di)(M128I_0), (__v2di)(M128I_1))) +#define _mm_aesenclast_si128(M128I_0, M128I_1) \ + ((__m128i)__builtin_ia32_aesenclast128((__v2di)(M128I_0), (__v2di)(M128I_1))) + +#define _mm_aesdec_si128(M128I_0, M128I_1) \ + ((__m128i)__builtin_ia32_aesdec128((__v2di)(M128I_0), (__v2di)(M128I_1))) +#define _mm_aesdeclast_si128(M128I_0, M128I_1) \ + ((__m128i)__builtin_ia32_aesdeclast128((__v2di)(M128I_0), (__v2di)(M128I_1))) + +#define _mm_aesimc_si128(M128I) \ + ((__m128i)__builtin_ia32_aesimc128((__v2di)(M128I))) +#define _mm_aesimclast_si128(M128I) \ + ((__m128i)__builtin_ia32_aesimclast128((__v2di)(M128I))) + +#define _mm_aeskeygenassist_si128(X, Y) \ + ((__m128i)__builtin_ia32_aeskeygenassist128((__v2di)(__m128i)(X), (int)(Y))) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_WMMINTRIN_H_ */ diff --git a/libc/bits/xchg.h b/libc/bits/xchg.h new file mode 100644 index 00000000..b912306e --- /dev/null +++ b/libc/bits/xchg.h @@ -0,0 +1,25 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_XCHG_H_ +#define COSMOPOLITAN_LIBC_BITS_XCHG_H_ +#include "libc/str/str.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * Exchanges *MEMORY into *LOCALVAR. + * + * @return *MEMORY + * @see lockcmpxchg() + * todo(jart): what's the point of this? + */ +#define xchg(MEMORY, LOCALVAR) \ + ({ \ + autotype(MEMORY) Memory = (MEMORY); \ + typeof(Memory) LocalVar = (LOCALVAR); \ + typeof(*Memory) Temp; \ + memcpy(&Temp, Memory, sizeof(Temp)); \ + memcpy(Memory, LocalVar, sizeof(Temp)); \ + memcpy(LocalVar, &Temp, sizeof(Temp)); \ + Temp; \ + }) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_XCHG_H_ */ diff --git a/libc/bits/xmmintrin.h b/libc/bits/xmmintrin.h new file mode 100644 index 00000000..b44eb070 --- /dev/null +++ b/libc/bits/xmmintrin.h @@ -0,0 +1,233 @@ +#ifndef COSMOPOLITAN_LIBC_BITS_XMMINTRIN_H_ +#define COSMOPOLITAN_LIBC_BITS_XMMINTRIN_H_ +#include "libc/bits/emmintrin.h" +#include "libc/bits/mmintrin.h" +#include "libc/bits/progn.h" +#include "libc/dce.h" + +#define _MM_EXCEPT_MASK 0x003f +#define _MM_EXCEPT_INVALID 0x0001 +#define _MM_EXCEPT_DENORM 0x0002 +#define _MM_EXCEPT_DIV_ZERO 0x0004 +#define _MM_EXCEPT_OVERFLOW 0x0008 +#define _MM_EXCEPT_UNDERFLOW 0x0010 +#define _MM_EXCEPT_INEXACT 0x0020 +#define _MM_MASK_MASK 0x1f80 +#define _MM_MASK_INVALID 0x0080 +#define _MM_MASK_DENORM 0x0100 +#define _MM_MASK_DIV_ZERO 0x0200 +#define _MM_MASK_OVERFLOW 0x0400 +#define _MM_MASK_UNDERFLOW 0x0800 +#define _MM_MASK_INEXACT 0x1000 +#define _MM_ROUND_MASK 0x6000 +#define _MM_ROUND_NEAREST 0x0000 +#define _MM_ROUND_DOWN 0x2000 +#define _MM_ROUND_UP 0x4000 +#define _MM_ROUND_TOWARD_ZERO 0x6000 +#define _MM_FLUSH_ZERO_MASK 0x8000 +#define _MM_FLUSH_ZERO_ON 0x8000 +#define _MM_FLUSH_ZERO_OFF 0x0000 + +#define _MM_SHUFFLE(A, B, C, D) (((A) << 6) | ((B) << 4) | ((C) << 2) | (D)) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +typedef int __v4si _Vector_size(16); +typedef unsigned int __v4su _Vector_size(16); +typedef float __v4sf _Vector_size(16); +typedef float __m128 _Vector_size(16) aligned(16) mayalias; +typedef float __m128_u _Vector_size(16) aligned(1) mayalias; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § sse » simd ops ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define _mm_add_ps(M128_0, M128_1) \ + ((__m128)((__v4sf)(M128_0) + (__v4sf)(M128_1))) +#define _mm_sub_ps(M128_0, M128_1) \ + ((__m128)((__v4sf)(M128_0) - (__v4sf)(M128_1))) +#define _mm_mul_ps(M128_0, M128_1) \ + ((__m128)((__v4sf)(M128_0) * (__v4sf)(M128_1))) +#define _mm_div_ps(M128_0, M128_1) \ + ((__m128)((__v4sf)(M128_0) / (__v4sf)(M128_1))) +#define _mm_and_ps(M128_0, M128_1) \ + ((__m128)((__v4su)(M128_0) & (__v4su)(M128_1))) +#define _mm_or_ps(M128_0, M128_1) \ + ((__m128)((__v4su)(M128_0) | (__v4su)(M128_1))) +#define _mm_xor_ps(M128_0, M128_1) /* XORPD [u32 simd xor] */ \ + ((__m128)((__v4su)(M128_0) ^ (__v4su)(M128_1))) +#define _mm_andnot_ps(M128_0, M128_1) /* ANDNPS [u32 simd nand] */ \ + ((__m128)(~(__v4su)(M128_0) & (__v4su)(M128_1))) +#define _mm_rcp_ps(M128) __builtin_ia32_rcpps((__v4sf)(M128)) +#define _mm_sqrt_ps(M128) __builtin_ia32_sqrtps((__v4sf)(M128)) +#define _mm_rsqrt_ps(M128) __builtin_ia32_rsqrtps((__v4sf)(M128)) + +#define _mm_min_ps(M128_0, M128_1) \ + __builtin_ia32_minps((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_max_ps(M128_0, M128_1) \ + __builtin_ia32_maxps((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_min_ss(M128_0, M128_1) \ + __builtin_ia32_minss((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_max_ss(M128_0, M128_1) \ + __builtin_ia32_maxss((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_cmpeq_ps(M128_0, M128_1) \ + __builtin_ia32_cmpeqps((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_cmpneq_ps(M128_0, M128_1) \ + __builtin_ia32_cmpneqps((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_cmplt_ps(M128_0, M128_1) \ + __builtin_ia32_cmpltps((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_cmpnlt_ps(M128_0, M128_1) \ + __builtin_ia32_cmpnltps((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_cmple_ps(M128_0, M128_1) \ + __builtin_ia32_cmpleps((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_cmpnle_ps(M128_0, M128_1) \ + __builtin_ia32_cmpnleps((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_cmpgt_ps(M128_0, M128_1) \ + __builtin_ia32_cmpltps((__v4sf)(M128_1), (__v4sf)(M128_0)) +#define _mm_cmpngt_ps(M128_0, M128_1) \ + __builtin_ia32_cmpnltps((__v4sf)(M128_1), (__v4sf)(M128_0)) +#define _mm_cmpge_ps(M128_0, M128_1) \ + __builtin_ia32_cmpleps((__v4sf)(M128_1), (__v4sf)(M128_0)) +#define _mm_cmpnge_ps(M128_0, M128_1) \ + __builtin_ia32_cmpnleps((__v4sf)(M128_1), (__v4sf)(M128_0)) +#define _mm_cmpord_ps(M128_0, M128_1) \ + __builtin_ia32_cmpordps((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_cmpunord_ps(M128_0, M128_1) \ + __builtin_ia32_cmpunordps((__v4sf)(M128_0), (__v4sf)(M128_1)) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § sse » scalar ops ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +forceinline __m128 _mm_add_ss(__m128 m128_0, __m128 m128_1) { + m128_0[0] += m128_1[0]; + return m128_0; +} + +forceinline __m128 _mm_sub_ss(__m128 m128_0, __m128 m128_1) { + m128_0[0] -= m128_1[0]; + return m128_0; +} + +forceinline __m128 _mm_mul_ss(__m128 m128_0, __m128 m128_1) { + m128_0[0] *= m128_1[0]; + return m128_0; +} + +forceinline __m128 _mm_div_ss(__m128 m128_0, __m128 m128_1) { + m128_0[0] /= m128_1[0]; + return m128_0; +} + +#define _mm_rcp_ss(M128) __builtin_ia32_rcpss((__v4sf)(M128)) /*~1/x*/ +#define _mm_sqrt_ss(M128) __builtin_ia32_sqrtss((__v4sf)(M128)) /*sqrt𝑥*/ +#define _mm_rsqrt_ss(M128) __builtin_ia32_rsqrtss((__v4sf)(M128)) /*~1/sqrt𝑥*/ + +#define _mm_min_ss(M128_0, M128_1) \ + __builtin_ia32_minss((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_max_ss(M128_0, M128_1) \ + __builtin_ia32_maxss((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_cmpeq_ss(M128_0, M128_1) \ + __builtin_ia32_cmpeqss((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_cmpneq_ss(M128_0, M128_1) \ + __builtin_ia32_cmpneqss((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_cmplt_ss(M128_0, M128_1) \ + __builtin_ia32_cmpltss((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_cmpnlt_ss(M128_0, M128_1) \ + __builtin_ia32_cmpnltss((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_cmple_ss(M128_0, M128_1) \ + __builtin_ia32_cmpless((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_cmpnle_ss(M128_0, M128_1) \ + __builtin_ia32_cmpnless((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_cmpgt_ss(M128_0, M128_1) \ + __builtin_ia32_cmpltss((__v4sf)(M128_1), (__v4sf)(M128_0)) +#define _mm_cmpngt_ss(M128_0, M128_1) \ + __builtin_ia32_cmpnltss((__v4sf)(M128_1), (__v4sf)(M128_0)) +#define _mm_cmpge_ss(M128_0, M128_1) \ + __builtin_ia32_cmpless((__v4sf)(M128_1), (__v4sf)(M128_0)) +#define _mm_cmpnge_ss(M128_0, M128_1) \ + __builtin_ia32_cmpnless((__v4sf)(M128_1), (__v4sf)(M128_0)) +#define _mm_cmpord_ss(M128_0, M128_1) \ + __builtin_ia32_cmpordss((__v4sf)(M128_0), (__v4sf)(M128_1)) +#define _mm_cmpunord_ss(M128_0, M128_1) \ + __builtin_ia32_cmpunordss((__v4sf)(M128_0), (__v4sf)(M128_1)) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § sse » memory ops ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define _mm_set1_ps(M128_0) ((__m128)(__v4sf){M128_0, M128_0, M128_0, M128_0}) +#define _mm_setzero_ps() ((__m128)(__v4sf){0}) +#define _mm_cvtss_f32(M128_0) (((__v4sf)(M128_0))[0]) +#define _mm_load_ps(FLOATPTR) (*(__m128 *)(FLOATPTR)) +#define _mm_loadu_ps(FLOATPTR) (*(__m128_u *)(FLOATPTR)) +#define _mm_set_ps(WHO, DESIGNED, THIS, SHEESH) \ + ((__m128)(__v4sf){SHEESH, THIS, DESIGNED, WHO}) +#define _mm_set_ss(FLOAT) ((__m128)(__v4sf){FLOAT, 0, 0, 0}) +#define _mm_load_ss(FLOATPTR) _mm_set_ss(*(FLOATPTR)) +#define _mm_store_ss(FLOATPTR, M128_0) ((FLOATPTR)[0] = ((__v4sf)(M128_0))[0]) +#define _mm_store_ps(FLOATPTR, M128_0) (*(__m128 *)(FLOATPTR) = (M128_0)) +#define _mm_storeu_ps(FLOATPTR, M128_0) (*(__m128_u *)(FLOATPTR) = (M128_0)) +#define _mm_shuffle_ps(M128_0, M128_1, MASK) \ + ((__m128)__builtin_ia32_shufps((__v4sf)(M128_0), (__v4sf)(M128_1), (MASK))) + +#ifdef __llvm__ +#define _mm_movehl_ps(M128_0, M128_1) \ + ((__m128)__builtin_shufflevector((__v4sf)(__m128)(M128_0), \ + (__v4sf)(__m128)(M128_1), 6, 7, 2, 3)) +/* instrinsics unstable & constantly breaking, consider ansi c or asm. */ +/* each version of llvm has a different incompatible impl for this one */ +#else +#define _mm_movehl_ps(M128_0, M128_1) \ + ((__m128)__builtin_ia32_movhlps((__v4sf)(__m128)(M128_0), \ + (__v4sf)(__m128)(M128_1))) +#define _mm_storel_pi(M64PTR, M128_0) \ + __builtin_ia32_storelps((__v2sf *)(M64PTR), (__v4sf)(M128_0)) +#endif + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § sse » cast ops ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define _mm_cvtps_epi32(M128_0) \ + ((__m128i)__builtin_ia32_cvtps2dq((__v4sf)(M128_0))) + +#ifdef __llvm__ +#define _mm_cvtepi32_ps(M128I_0) \ + ((__m128) __builtin_convertvector((__v4si)(__m128i)(M128I_0), __v4sf)) +#else +#define _mm_cvtepi32_ps(M128I_0) \ + ((__m128)__builtin_ia32_cvtdq2ps((__v4si)(M128I_0))) +#endif + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § sse » misc ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define _mm_getcsr() (__builtin_ia32_stmxcsr()) +#define _mm_setcsr(U32CONF) (__builtin_ia32_ldmxcsr(U32CONF)) + +#define _MM_GET_ROUNDING_MODE() (_mm_getcsr() & _MM_ROUND_MASK) +#define _MM_SET_ROUNDING_MODE(MODE) \ + (_mm_setcsr((_mm_getcsr() & ~_MM_ROUND_MASK) | (MODE))) + +#define XMM_DESTROY(VAR) \ + do { \ + if (!IsTrustworthy()) { \ + asm volatile("xorps\t%1,%0" : "=x"(VAR) : "0"(VAR)); \ + } \ + } while (0) + +/* +** Ternary: +** +** Integer: _mm_or_si128(_mm_and_si128(a, cond), _mm_andnot_si128(cond, b)) +** 32-bit float: _mm_or_ps(_mm_and_ps(a, cond), _mm_andnot_ps(cond, b)) +** 64-bit float: _mm_or_pd(_mm_and_pd(a, cond), _mm_andnot_pd(cond, b)) +** Integer (SSE4.1+): _mm_blendv_epi8(a, b, cond) +** 32-bit float (SSE4.1+): _mm_blendv_ps(a, b, cond) +** 64-bit float (SSE4.1+): _mm_blendv_pd(a, b, cond) +*/ + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BITS_XMMINTRIN_H_ */ diff --git a/libc/calls/atfork.c b/libc/calls/atfork.c new file mode 100644 index 00000000..2c8f8798 --- /dev/null +++ b/libc/calls/atfork.c @@ -0,0 +1,56 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/internal.h" +#include "libc/macros.h" +#include "libc/runtime/internal.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/errfuns.h" + +static struct AtFork { + size_t i; + struct AtForkCallback { + void (*fn)(void *); + void *arg; + } p[ATEXIT_MAX]; +} g_atfork; + +/** + * Registers function to be called when PID changes. + * + * @return 0 on success, or -1 w/ errno + */ +int atfork(void *fn, void *arg) { + if (g_atfork.i == ARRAYLEN(g_atfork.p)) return enomem(); + g_atfork.p[g_atfork.i++] = (struct AtForkCallback){.fn = fn, .arg = arg}; + return 0; +} + +/** + * Triggers atfork() callbacks. + * + * Only fork() should call this. + */ +void __onfork(void) { + size_t i; + for (i = 0; i < g_atfork.i; ++i) { + g_atfork.p[i].fn(g_atfork.p[i].arg); + } +} diff --git a/libc/calls/calls.h b/libc/calls/calls.h new file mode 100644 index 00000000..626f323d --- /dev/null +++ b/libc/calls/calls.h @@ -0,0 +1,292 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_SYSCALLS_H_ +#define COSMOPOLITAN_LIBC_CALLS_SYSCALLS_H_ +#include "libc/calls/struct/timespec.h" +#include "libc/calls/typedef/sighandler_t.h" +#include "libc/dce.h" +#include "libc/fmt/pflink.h" +#include "libc/sysv/consts/s.h" +#include "libc/sysv/consts/sig.h" + +#define EOF -1 /* end of file */ +#define WEOF -1u /* end of file (multibyte) */ +#define _IOFBF 0 /* fully buffered */ +#define _IOLBF 1 /* line buffered */ +#define _IONBF 2 /* no buffering */ +#define SEEK_SET 0 /* relative to beginning */ +#define SEEK_CUR 1 /* relative to current position */ +#define SEEK_END 2 /* relative to end */ + +#define SIG_ERR ((void (*)(int))(-1)) +#define SIG_DFL ((void *)0) +#define SIG_IGN ((void *)1) + +#define MAP_FAILED ((void *)__SIZE_MAX__) + +#define ARCH_SET_GS 0x1001 +#define ARCH_SET_FS 0x1002 +#define ARCH_GET_FS 0x1003 +#define ARCH_GET_GS 0x1004 + +#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT) +#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT) + +#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR) +#define S_ISCHR(mode) (((mode)&S_IFMT) == S_IFCHR) +#define S_ISBLK(mode) (((mode)&S_IFMT) == S_IFBLK) +#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG) +#define S_ISFIFO(mode) (((mode)&S_IFMT) == S_IFIFO) +#define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK) +#define S_ISSOCK(mode) (((mode)&S_IFMT) == S_IFSOCK) + +#define WCOREDUMP(s) ((s)&0x80) +#define WEXITSTATUS(s) (((s)&0xff00) >> 8) +#define WIFCONTINUED(s) ((s) == 0xffff) +#define WIFEXITED(s) (!WTERMSIG(s)) +#define WIFSIGNALED(s) (((s)&0xffff) - 1U < 0xffu) +#define WIFSTOPPED(s) ((short)((((s)&0xffff) * 0x10001) >> 8) > 0x7f00) +#define WSTOPSIG(s) WEXITSTATUS(s) +#define WTERMSIG(s) ((s)&0x7f) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § system calls ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +struct dirstream; +struct iovec; +struct rlimit; +struct rusage; +struct sigaction; +struct siginfo; +struct sigset; +struct stat; +struct sysinfo; +struct tms; +struct ucontext; +struct utsname; + +typedef int sig_atomic_t; +typedef struct dirstream DIR; + +extern const struct sigset kSigsetFull; +extern const struct sigset kSigsetEmpty; + +DIR *fdopendir(int) nodiscard; +DIR *opendir(const char *) nodiscard; +bool fileexists(const char *); +bool isdirectory(const char *); +bool isexecutable(const char *); +bool isregularfile(const char *); +bool32 isatty(int) nosideeffect; +bool32 ischardev(int) nosideeffect; +char *get_current_dir_name(void) nodiscard; +char *getcwd(char *, size_t) paramsnonnull(); +char *realpath(const char *, char *); +char *replaceuser(const char *) nodiscard; +char *slurp(const char *, size_t *) nodiscard; +char *ttyname(int); +const char *commandv(const char *); +int access(const char *, int) nothrow paramsnonnull(); +int arch_prctl(); +int chdir(const char *) paramsnonnull(); +int chmod(const char *, uint32_t); +int chown(const char *, uint32_t, uint32_t) paramsnonnull(); +int close(int); +int closedir(DIR *); +int copyfile(const char *, const char *, bool); +int creat(const char *, uint32_t) nodiscard; +int dirfd(DIR *); +int dup(int) nodiscard; +int dup2(int, int); +int dup3(int, int, int); +int execl(const char *, const char *, ...) nullterminated(); +int execle(const char *, const char *, ...) nullterminated((1)); +int execlp(const char *, const char *, ...) nullterminated(); +int execv(const char *, char *const[]) paramsnonnull(); +int execve(const char *, char *const[], char *const[]) paramsnonnull(); +int execvp(const char *, char *const[]) paramsnonnull(); +int execvpe(const char *, char *const[], char *const[]) paramsnonnull(); +int faccessat(int, const char *, int, uint32_t); +int fadvise(int, uint64_t, uint64_t, int); +int fallocate(int, int32_t, int64_t, int64_t); +int fchmod(int, uint32_t) nothrow; +int fchmodat(int, const char *, uint32_t, uint32_t); +int fchown(int, uint32_t, uint32_t); +int fchownat(int, const char *, uint32_t, uint32_t, uint32_t); +int fcntl(); +int fdatasync(int); +int filecmp(const char *, const char *); +int flock(int, int); +int fork(void); +int fstat(int, struct stat *) paramsnonnull(); +int fstatat(int, const char *, struct stat *, uint32_t); +int fsync(int); +int ftruncate(int, int64_t); +int getppid(void); +int getpriority(int, unsigned); +int getrlimit(int, struct rlimit *); +int getrusage(int, struct rusage *); +int kill(int, int); +int killpg(int, int); +int link(const char *, const char *) nothrow; +int linkat(int, const char *, int, const char *, uint32_t); +int lstat(const char *, struct stat *) paramsnonnull(); +int madvise(void *, uint64_t, int); +int mkdir(const char *, uint32_t); +int mkdirat(int, const char *, uint32_t); +int mkfifo(const char *, uint32_t); +int mknod(const char *, uint32_t, uint64_t); +int mknodat(int, const char *, int32_t, uint64_t); +int mlock(const void *, size_t); +int mlock2(const void *, size_t, int); +int mlockall(int); +int mprotect(void *, uint64_t, int) paramsnonnull() privileged; +int msync(void *, size_t, int); +int munlock(const void *, size_t); +int munlockall(void); +int munmap(void *, uint64_t); +int munmap_s(void *, uint64_t); +int nice(int); +int open(const char *, int, ...) nodiscard; +int openanon(char *, unsigned) nodiscard; +int openat(); +int pause(void); +int personality(uint64_t); +int pipe(int[hasatleast 2]) paramsnonnull() nodiscard; +int pipe2(int[hasatleast 2], int) paramsnonnull() nodiscard; +int posix_fadvise(int, uint64_t, uint64_t, int); +int posix_fallocate(int, int64_t, int64_t); +int posix_madvise(void *, uint64_t, int); +int raise(int); +int readlink(const char *, char *, size_t); +int remove(const char *); +int rename(const char *, const char *); +int renameat(int, const char *, int, const char *); +int renameat2(long, const char *, long, const char *, int); +int rmdir(const char *); +int sched_getaffinity(int, uint64_t, void *); +int sched_setaffinity(int, uint64_t, const void *); +int sched_yield(void); +int setpgid(int, int); +int setpriority(int, unsigned, int); +int setrlimit(int, const struct rlimit *); +int setsid(void); +int setuid(uint32_t); +int setgid(uint32_t); +int seteuid(uint32_t); +int setegid(uint32_t); +int setreuid(uint32_t, uint32_t); +int setregid(uint32_t, uint32_t); +int setresuid(uint32_t, uint32_t, uint32_t); +int setresgid(uint32_t, uint32_t, uint32_t); +int sigaction(int, const struct sigaction *, struct sigaction *); +int sigignore(int); +int sigprocmask(int, const struct sigset *, struct sigset *); +int sigsuspend(const struct sigset *); +int stat(const char *, struct stat *) paramsnonnull(); +int symlink(const char *, const char *); +int symlinkat(const char *, int, const char *); +int sync_file_range(int, int64_t, int64_t, unsigned); +int sysinfo(struct sysinfo *) paramsnonnull(); +int touch(const char *, uint32_t); +int truncate(const char *, uint64_t); +int ttyname_r(int, char *, size_t); +int uname(struct utsname *); +int unlink(const char *); +int unlink_s(const char **); +int unlinkat(int, const char *, int); +int vfork(void); +int wait(int *); +int wait3(int *, int, struct rusage *); +int wait4(int, int *, int, struct rusage *); +int waitpid(int, int *, int); +int64_t lseek(int, int64_t, int); +int64_t pread(int, void *, size_t, int64_t); +int64_t preadv(int, struct iovec *, int, int64_t); +int64_t pwrite(int, const void *, size_t, int64_t); +int64_t pwritev(int, const struct iovec *, int, int64_t); +int64_t syscall(); +long telldir(DIR *); +int getpid(void); +long times(struct tms *); +sighandler_t signal(int, sighandler_t); +size_t GetFileSize(const char *); +size_t getfiledescriptorsize(int); +ssize_t copy_file_range(int, long *, int, long *, size_t, uint32_t); +ssize_t copyfd(int, int64_t *, int, int64_t *, size_t, uint32_t); +ssize_t read(int, void *, size_t); +ssize_t readlinkat(int, const char *, char *, size_t); +ssize_t splice(int, int64_t *, int, int64_t *, size_t, uint32_t); +ssize_t vmsplice(int, const struct iovec *, int64_t, uint32_t); +ssize_t write(int, const void *, size_t); +struct dirent *readdir(DIR *); +uint32_t getegid(void) nosideeffect; +uint32_t geteuid(void) nosideeffect; +uint32_t getgid(void) nosideeffect; +uint32_t getpgrp(void) nosideeffect; +uint32_t getsid(int) nosideeffect; +uint32_t gettid(void) nosideeffect; +uint32_t getuid(void) nosideeffect; +uint32_t umask(int32_t); +void *getprocaddressmodule(const char *, const char *); +void *mmap(void *, uint64_t, int32_t, int32_t, int32_t, int64_t) vallocesque; +void *mremap(void *, uint64_t, uint64_t, int32_t, void *); + +#define getcwd(BUF, SIZE) \ + (isconstant(BUF) && (&(BUF)[0] == NULL) ? get_current_dir_name() \ + : getcwd(BUF, SIZE)) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § system calls » formatting ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +int dprintf(int, const char *, ...) printfesque(2) paramsnonnull((2)); +int vdprintf(int, const char *, va_list) paramsnonnull(); + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § system calls » link-time optimizations ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) + +void _init_onntconsoleevent(void); +void _init_onwincrash(void); + +#define __SIGACTION(FN, SIG, ...) \ + ({ \ + if (SupportsWindows()) { \ + if (isconstant(SIG)) { \ + switch (SIG) { \ + case SIGINT: \ + case SIGQUIT: \ + case SIGHUP: \ + case SIGTERM: \ + YOINK(_init_onntconsoleevent); \ + break; \ + case SIGTRAP: \ + case SIGILL: \ + case SIGSEGV: \ + case SIGABRT: \ + case SIGFPE: \ + YOINK(_init_onwincrash); \ + break; \ + default: \ + break; \ + } \ + } else { \ + YOINK(_init_onntconsoleevent); \ + YOINK(_init_onwincrash); \ + } \ + } \ + (FN)(SIG, __VA_ARGS__); \ + }) + +#define dprintf(FD, FMT, ...) (dprintf)(FD, PFLINK(FMT), ##__VA_ARGS__) +#define sigaction(SIG, ACT, OLD) __SIGACTION(sigaction, SIG, ACT, OLD) +#define signal(SIG, HAND) __SIGACTION(signal, SIG, HAND) +#define vdprintf(FD, FMT, VA) (vdprintf)(FD, PFLINK(FMT), VA) + +#endif /* GNU && !ANSI */ +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_SYSCALLS_H_ */ diff --git a/libc/calls/calls.mk b/libc/calls/calls.mk new file mode 100644 index 00000000..dd4b8d58 --- /dev/null +++ b/libc/calls/calls.mk @@ -0,0 +1,90 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ +# +# SYNOPSIS +# +# System Call Compatibility Layer +# +# DESCRIPTION +# +# This package exports a familiar system call interface that works +# across platforms. + +PKGS += LIBC_CALLS + +LIBC_CALLS_ARTIFACTS += LIBC_CALLS_A +LIBC_CALLS = $(LIBC_CALLS_A_DEPS) $(LIBC_CALLS_A) +LIBC_CALLS_A = o/$(MODE)/libc/calls/syscalls.a +LIBC_CALLS_A_FILES := \ + $(wildcard libc/calls/typedef/*) \ + $(wildcard libc/calls/thunks/*) \ + $(wildcard libc/calls/struct/*) \ + $(wildcard libc/calls/*) +LIBC_CALLS_A_HDRS = $(filter %.h,$(LIBC_CALLS_A_FILES)) +LIBC_CALLS_A_SRCS_S = $(filter %.S,$(LIBC_CALLS_A_FILES)) +LIBC_CALLS_A_SRCS_C = $(filter %.c,$(LIBC_CALLS_A_FILES)) + +LIBC_CALLS_A_SRCS = \ + $(LIBC_CALLS_A_SRCS_S) \ + $(LIBC_CALLS_A_SRCS_C) + +LIBC_CALLS_A_OBJS = \ + $(LIBC_CALLS_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_CALLS_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_CALLS_A_SRCS_C:%.c=o/$(MODE)/%.o) + +LIBC_CALLS_A_CHECKS = \ + $(LIBC_CALLS_A).pkg \ + $(LIBC_CALLS_A_HDRS:%=o/$(MODE)/%.ok) + +LIBC_CALLS_A_DIRECTDEPS = \ + LIBC_FMT \ + LIBC_STR \ + LIBC_RAND \ + LIBC_CONV \ + LIBC_STUBS \ + LIBC_NEXGEN32E \ + LIBC_NT_NTDLL \ + LIBC_NT_ADVAPI32 \ + LIBC_NT_KERNEL32 \ + LIBC_NT_KERNELBASE \ + LIBC_SYSV_CALLS \ + LIBC_SYSV + +LIBC_CALLS_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_CALLS_A_DIRECTDEPS),$($(x)))) + +$(LIBC_CALLS_A): \ + libc/calls/ \ + $(LIBC_CALLS_A).pkg \ + $(LIBC_CALLS_A_OBJS) + +$(LIBC_CALLS_A).pkg: \ + $(LIBC_CALLS_A_OBJS) \ + $(foreach x,$(LIBC_CALLS_A_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/libc/calls/raise.o: \ + OVERRIDE_COPTS += \ + $(NO_MAGIC) + +o/$(MODE)/libc/calls/siggy.o: \ + OVERRIDE_COPTS += \ + -ffunction-sections + +o/$(MODE)/libc/calls/xnutrampoline.o \ +o/$(MODE)/libc/calls/ntcontext2linux.o: \ + OVERRIDE_COPTS += \ + -O3 + +LIBC_CALLS_LIBS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x))) +LIBC_CALLS_SRCS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_SRCS)) +LIBC_CALLS_HDRS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_HDRS)) +LIBC_CALLS_BINS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_BINS)) +LIBC_CALLS_CHECKS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_CHECKS)) +LIBC_CALLS_OBJS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_OBJS)) +LIBC_CALLS_TESTS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_TESTS)) + +.PHONY: o/$(MODE)/libc/calls +o/$(MODE)/libc/calls: \ + o/$(MODE)/libc/calls/hefty \ + $(LIBC_CALLS_CHECKS) diff --git a/libc/calls/chdir-nt.c b/libc/calls/chdir-nt.c new file mode 100644 index 00000000..98d19e37 --- /dev/null +++ b/libc/calls/chdir-nt.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" +#include "libc/sysv/errfuns.h" + +textwindows int chdir$nt(const char *path) { + int len; + char16_t path16[PATH_MAX]; + if ((len = mkntpath(path, path16)) == -1) return -1; + if (path16[len - 1] != u'/' && path16[len - 1] != u'\\') { + path16[len + 0] = u'/'; + path16[len + 1] = u'\0'; + } + if (SetCurrentDirectory(path16)) { + return 0; + } else { + return winerr(); + } +} diff --git a/libc/calls/chdir.c b/libc/calls/chdir.c new file mode 100644 index 00000000..859f71d1 --- /dev/null +++ b/libc/calls/chdir.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" + +/** + * Sets current directory. + * @asyncsignalsafe + */ +int chdir(const char *path) { + if (!IsWindows()) { + return chdir$sysv(path); + } else { + return chdir$nt(path); + } +} diff --git a/libc/calls/chmod.c b/libc/calls/chmod.c new file mode 100644 index 00000000..f8378b86 --- /dev/null +++ b/libc/calls/chmod.c @@ -0,0 +1,49 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sysv/consts/at.h" +#include "libc/sysv/errfuns.h" + +/** + * Changes permissions on file, e.g.: + * + * CHECK_NE(-1, chmod("foo/bar.txt", 0644)); + * CHECK_NE(-1, chmod("o/default/program.com", 0755)); + * CHECK_NE(-1, chmod("privatefolder/", 0700)); + * + * The esoteric bits generally available on System Five are: + * + * CHECK_NE(-1, chmod("/opt/", 01000)); // sticky bit + * CHECK_NE(-1, chmod("/usr/bin/sudo", 04755)); // setuid bit + * CHECK_NE(-1, chmod("/usr/bin/wall", 02755)); // setgid bit + * + * This works on Windows NT if you ignore the error ;-) + * + * @param pathname must exist + * @param mode contains octal flags (base 8) + * @errors ENOENT, ENOTDIR, ENOSYS + * @asyncsignalsafe + * @see fchmod() + */ +int chmod(const char *pathname, uint32_t mode) { + return fchmodat$sysv(AT_FDCWD, pathname, mode, 0); +} diff --git a/libc/calls/chown.c b/libc/calls/chown.c new file mode 100644 index 00000000..023df63d --- /dev/null +++ b/libc/calls/chown.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/sysv/consts/at.h" + +/** + * Changes owner and/or group of pathname. + * + * @param uid is user id, or -1u to not change + * @param gid is group id, or -1u to not change + * @return 0 on success, or -1 w/ errno + * @see fchown() if pathname is already open()'d + * @see lchown() which does not dereference symbolic links + * @see /etc/passwd for user ids + * @see /etc/group for group ids + * @asyncsignalsafe + */ +int chown(const char *pathname, uint32_t uid, uint32_t gid) { + return fchownat$sysv(AT_FDCWD, pathname, uid, gid, 0); +} diff --git a/libc/calls/close-nt.c b/libc/calls/close-nt.c new file mode 100644 index 00000000..eca8cc2d --- /dev/null +++ b/libc/calls/close-nt.c @@ -0,0 +1,45 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" +#include "libc/sysv/errfuns.h" + +textwindows int close$nt(int fd) { + bool32 ok; + if (isfdindex(fd)) { + if (g_fds.p[fd].kind == kFdFile) { + /* + * Like Linux, closing a file on Windows doesn't guarantee it's + * immediately synced to disk. But unlike Linux, this could cause + * subsequent operations, e.g. unlink() to break w/ access error. + */ + FlushFileBuffers(g_fds.p[fd].handle); + } + ok = CloseHandle(g_fds.p[fd].handle); + if (g_fds.p[fd].kind == kFdConsole) { + ok &= CloseHandle(g_fds.p[fd].extra); + } + removefd(fd); + return ok ? 0 : winerr(); + } else { + return ebadf(); + } +} diff --git a/libc/calls/close.c b/libc/calls/close.c new file mode 100644 index 00000000..e0d700ab --- /dev/null +++ b/libc/calls/close.c @@ -0,0 +1,49 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sock/internal.h" +#include "libc/sysv/errfuns.h" +#include "libc/zipos/zipos.h" + +/** + * Closes file descriptor. + * + * @return 0 on success, or -1 w/ errno + * @asyncsignalsafe + */ +int close(int fd) { + int rc; + if (fd == -1) return 0; + if (isfdkind(fd, kFdZip)) { + rc = weaken(__zipos_close)( + (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle); + } else if (!IsWindows()) { + rc = close$sysv(fd); + } else if (isfdkind(fd, kFdSocket)) { + rc = weaken(closesocket$nt)(fd); + } else { + rc = close$nt(fd); + } + removefd(fd); + return rc; +} diff --git a/libc/calls/copyfd.c b/libc/calls/copyfd.c new file mode 100644 index 00000000..c13ecaa2 --- /dev/null +++ b/libc/calls/copyfd.c @@ -0,0 +1,73 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/errno.h" +#include "libc/sysv/errfuns.h" + +/** + * Copies data between file descriptors the slow way. + * + * @return -1 on error/interrupt, 0 on eof, or [1..uptobytes] on success + * @see copy_file_range() for file ↔ file + * @see sendfile() for seekable → socket + * @see splice() for fd ↔ pipe + */ +ssize_t copyfd(int infd, int64_t *inopt_out_inoffset, int to_fd, + int64_t *inopt_out_outoffset, size_t uptobytes, uint32_t flags) { + size_t i; + int64_t offset; + ssize_t got, wrote; + static unsigned char buf[1024 * 64]; + /* unsigned char buf[1024 * 3]; */ + uptobytes = min(sizeof(buf), uptobytes); + if (inopt_out_inoffset) { + got = pread(infd, buf, uptobytes, *inopt_out_inoffset); + } else { + got = read(infd, buf, uptobytes); + } + if (got == -1) return -1; + offset = inopt_out_outoffset ? *inopt_out_outoffset : -1; + for (i = 0; i < got; i += wrote) { + tryagain: + if (inopt_out_outoffset) { + wrote = pwrite(to_fd, buf, got - i, offset + i); + } else { + wrote = write(to_fd, buf, got - i); + } + if (wrote != -1) continue; + if (errno == EINTR) { + if (inopt_out_inoffset != NULL) { + return -1; + } + goto tryagain; + } + if (errno == EWOULDBLOCK) { + assert(inopt_out_inoffset != NULL); /* or caller is nuts */ + } + return -1; + } + if (inopt_out_inoffset) *inopt_out_inoffset += got; + if (inopt_out_outoffset) *inopt_out_outoffset += got; + return got; +} diff --git a/libc/calls/copyfile.c b/libc/calls/copyfile.c new file mode 100644 index 00000000..279eddb3 --- /dev/null +++ b/libc/calls/copyfile.c @@ -0,0 +1,64 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/stat.h" +#include "libc/dce.h" +#include "libc/nt/files.h" +#include "libc/sysv/consts/at.h" +#include "libc/sysv/consts/madv.h" +#include "libc/sysv/consts/o.h" + +int copyfile(const char *frompath, const char *topath, bool dontoverwrite) { + if (IsWindows()) { + char16_t frompath16[PATH_MAX], topath16[PATH_MAX]; + if (mkntpath(frompath, frompath16) == -1) return -1; + if (mkntpath(topath, topath16) == -1) return -1; + if (CopyFile(frompath16, topath16, dontoverwrite)) { + return 0; + } else { + return winerr(); + } + } else { + struct stat st; + ssize_t transferred; + int rc, fromfd, tofd; + int64_t inoffset, outoffset; + rc = -1; + if ((fromfd = openat$sysv(AT_FDCWD, frompath, O_RDONLY, 0)) != -1) { + if (fstat$sysv(fromfd, &st) != -1 && + (tofd = openat$sysv(AT_FDCWD, topath, + O_WRONLY | O_CREAT | (dontoverwrite ? O_EXCL : 0), + st.st_mode & 0777)) != -1) { + inoffset = 0; + outoffset = 0; + while (st.st_size && (transferred = copy_file_range( + fromfd, &inoffset, tofd, &outoffset, + st.st_size, 0)) != -1) { + st.st_size -= transferred; + } + if (!st.st_size) rc = 0; + rc |= close$sysv(tofd); + } + rc |= close$sysv(fromfd); + } + return rc; + } +} diff --git a/libc/calls/creat.c b/libc/calls/creat.c new file mode 100644 index 00000000..ebc5ddec --- /dev/null +++ b/libc/calls/creat.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/sysv/consts/o.h" + +/** + * Creates new file, returning open()'d file descriptor. + * + * @param file is a UTF-8 string, which is truncated if it exists + * @param mode is an octal user/group/other permission, e.g. 0755 + * @return a number registered with the system to track the open file, + * which must be stored using a 64-bit type in order to support both + * System V and Windows, and must be closed later on using close() + * @see touch() + * @asyncsignalsafe + */ +nodiscard int creat(const char *file, uint32_t mode) { + return open(file, O_CREAT | O_WRONLY | O_TRUNC, mode); +} diff --git a/libc/calls/createfd.c b/libc/calls/createfd.c new file mode 100644 index 00000000..c89f1fb7 --- /dev/null +++ b/libc/calls/createfd.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/internal.h" +#include "libc/mem/mem.h" +#include "libc/sysv/errfuns.h" + +/** + * Finds open file descriptor slot. + */ +ssize_t createfd(void) { + size_t fd; + for (;;) { + while (g_fds.f < g_fds.n) { + if (g_fds.p[(fd = g_fds.f++)].kind == kFdEmpty) { + return fd; + } + } + if (growfds() == -1) return -1; + } +} diff --git a/libc/calls/dprintf.c b/libc/calls/dprintf.c new file mode 100644 index 00000000..aa0f4d0f --- /dev/null +++ b/libc/calls/dprintf.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" + +/** + * Formats string directly to system i/o device. + */ +int(dprintf)(int fd, const char *fmt, ...) { + int rc; + va_list va; + va_start(va, fmt); + rc = (vdprintf)(fd, fmt, va); + va_end(va); + return rc; +} diff --git a/libc/calls/dup-nt.c b/libc/calls/dup-nt.c new file mode 100644 index 00000000..5d27e7eb --- /dev/null +++ b/libc/calls/dup-nt.c @@ -0,0 +1,54 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/mem/mem.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/errfuns.h" + +/** + * Implements dup(), dup2(), and dup3() for Windows NT. + */ +textwindows int dup$nt(int oldfd, int newfd, int flags) { + if (!isfdkind(oldfd, kFdFile)) return ebadf(); + if (newfd == -1) { + if ((newfd = createfd()) == -1) return -1; + } else if (isfdindex(newfd)) { + close(newfd); + } else if (isfdlegal(newfd)) { + do { + if (growfds() == -1) return -1; + } while (newfd >= g_fds.n); + } else { + return ebadf(); + } + if (DuplicateHandle(GetCurrentProcess(), g_fds.p[oldfd].handle, + GetCurrentProcess(), &g_fds.p[newfd].handle, 0, + (flags & O_CLOEXEC), kNtDuplicateSameAccess)) { + g_fds.p[newfd].kind = g_fds.p[oldfd].kind; + g_fds.p[newfd].flags = flags; + return newfd; + } else { + return winerr(); + } +} diff --git a/libc/calls/dup.c b/libc/calls/dup.c new file mode 100644 index 00000000..8510d9f4 --- /dev/null +++ b/libc/calls/dup.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" + +/** + * Duplicates file descriptor/handle. + * + * @param fd remains open afterwards + * @return some arbitrary new number for fd + * @asyncsignalsafe + */ +nodiscard int dup(int fd) { + if (!IsWindows()) { + return dup$sysv(fd); + } else { + return dup$nt(fd, -1, 0); + } +} diff --git a/libc/calls/dup2.c b/libc/calls/dup2.c new file mode 100644 index 00000000..6cfc5cf5 --- /dev/null +++ b/libc/calls/dup2.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" + +/** + * Duplicates file descriptor, granting it specific number. + * + * @param oldfd isn't closed afterwards + * @param newfd if already assigned, is silently closed beforehand; + * unless it's equal to oldfd, in which case dup2() is a no-op + * @return new file descriptor, or -1 w/ errno + * @asyncsignalsafe + */ +int dup2(int oldfd, int newfd) { + if (oldfd == newfd) return newfd; + if (!IsWindows()) { + return dup3$sysv(oldfd, newfd, 0); + } else { + return dup$nt(oldfd, newfd, 0); + } +} diff --git a/libc/calls/dup3-sysv.c b/libc/calls/dup3-sysv.c new file mode 100644 index 00000000..c8134163 --- /dev/null +++ b/libc/calls/dup3-sysv.c @@ -0,0 +1,47 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/errno.h" + +#define __NR_dup3_linux 0x0124 /*RHEL5:CVE-2010-3301*/ + +int32_t dup3$sysv(int32_t oldfd, int32_t newfd, int flags) { + static bool once, demodernize; + int olderr, fd; + if (!once) { + once = true; + olderr = errno; + fd = __dup3$sysv(oldfd, newfd, flags); + if ((fd == -1 && errno == ENOSYS) || fd == __NR_dup3_linux) { + demodernize = true; + errno = olderr; + goto OldSkool; + } + } else if (demodernize) { + goto OldSkool; + } else { + fd = __dup3$sysv(oldfd, newfd, flags); + } + return fd; +OldSkool: + fd = dup2$sysv(oldfd, newfd); + if (flags) fd = fixupnewfd$sysv(fd, flags); + return fd; +} diff --git a/libc/calls/dup3.c b/libc/calls/dup3.c new file mode 100644 index 00000000..292d5608 --- /dev/null +++ b/libc/calls/dup3.c @@ -0,0 +1,44 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sysv/errfuns.h" + +/** + * Duplicates file descriptor/handle. + * + * On Windows, we can't guarantee the desired file descriptor is used. + * We can however remap the standard handles (non-atomically) if their + * symbolic names are used. + * + * @param oldfd isn't closed afterwards + * @param newfd if already assigned, is silently closed beforehand; + * unless it's equal to oldfd, in which case dup2() is a no-op + * @flags can have O_CLOEXEC + */ +int dup3(int oldfd, int newfd, int flags) { + if (oldfd == newfd) return einval(); + if (!IsWindows()) { + return dup3$sysv(oldfd, newfd, flags); + } else { + return dup$nt(oldfd, newfd, flags); + } +} diff --git a/libc/calls/fadvise-nt.c b/libc/calls/fadvise-nt.c new file mode 100644 index 00000000..f96afaab --- /dev/null +++ b/libc/calls/fadvise-nt.c @@ -0,0 +1,65 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/enum/fileflagandattributes.h" +#include "libc/nt/enum/filesharemode.h" +#include "libc/nt/enum/status.h" +#include "libc/nt/files.h" +#include "libc/nt/nt/file.h" +#include "libc/nt/ntdll.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/fileaccessinformation.h" +#include "libc/nt/struct/filebasicinformation.h" +#include "libc/nt/struct/iostatusblock.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/errfuns.h" + +textwindows int fadvise$nt(int fd, uint64_t offset, uint64_t len, int advice) { + int64_t h2; + NtStatus status; + uint32_t sharemode; + struct NtIoStatusBlock iostatus; + struct NtFileBasicInformation basicinfo; + struct NtFileAccessInformation accessinfo; + if (!isfdkind(fd, kFdFile)) return ebadf(); + sharemode = /* xxx: no clue how to query this */ + kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete; + /* TODO(jart): can we do it in one call w/ NtQueryObject? */ + if (!NtError(status = NtQueryInformationFile(g_fds.p[fd].handle, &iostatus, + &basicinfo, sizeof(basicinfo), + kNtFileBasicInformation)) && + !NtError(status = NtQueryInformationFile(g_fds.p[fd].handle, &iostatus, + &accessinfo, sizeof(accessinfo), + kNtFileAccessInformation))) { + if ((h2 = ReOpenFile(g_fds.p[fd].handle, accessinfo.AccessFlags, sharemode, + advice | basicinfo.FileAttributes)) != -1) { + if (h2 != g_fds.p[fd].handle) { + CloseHandle(g_fds.p[fd].handle); + g_fds.p[fd].handle = h2; + } + return 0; + } + return winerr(); + } else if (status == kNtStatusDllNotFound) { + return enosys(); + } else { + return ntreturn(status); + } +} diff --git a/libc/calls/fadvise.c b/libc/calls/fadvise.c new file mode 100644 index 00000000..3aa7a8fb --- /dev/null +++ b/libc/calls/fadvise.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" + +/** + * Drops hints to O/S about intended I/O behavior. + * + * It makes a huge difference. For example, when copying a large file, + * it can stop the system from persisting GBs of useless memory content. + * + * @param len 0 means ‘til end of file + * @param advice can be MADV_SEQUENTIAL, MADV_RANDOM, etc. + * @return -1 on error + */ +int fadvise(int fd, uint64_t offset, uint64_t len, int advice) { + if (!IsWindows()) { + return fadvise$sysv(fd, offset, len, advice); /* linux & freebsd */ + } else { + return fadvise$nt(fd, offset, len, advice); + } +} diff --git a/libc/calls/fallocate.c b/libc/calls/fallocate.c new file mode 100644 index 00000000..d2ee5657 --- /dev/null +++ b/libc/calls/fallocate.c @@ -0,0 +1,76 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/nt/enum/fsctl.h" +#include "libc/nt/files.h" +#include "libc/nt/struct/filezerodatainformation.h" +#include "libc/sysv/consts/falloc.h" +#include "libc/sysv/errfuns.h" + +/** + * Manipulates underlying physical medium of file. + * + * This system call generalizes to many powerful use cases on Linux, + * such as creating gigantic sparse files that take up little space. + * This API can polyfill a certain subset of parameters safely, e.g. + * ones identical to ftruncate(), but errs on the side of caution. + * + * @param fd must be open for writing + * @param mode can be 0, FALLOC_xxx + * @param length is how much physical space to reserve / commit + * @return 0 on success, or -1 w/ errno + * @see ftruncate() + */ +int fallocate(int fd, int32_t mode, int64_t offset, int64_t length) { + int rc; + uint32_t br; + if (mode == -1 /* our sysvconsts definition */) return eopnotsupp(); + if (!mode && !length) return ftruncate(fd, offset); + if (IsLinux()) { + rc = fallocate$sysv(fd, mode, offset, length); + if (rc == 0x011d) rc = enosys(); /*RHEL5:CVE-2010-3301*/ + return rc; + } else if (!IsWindows()) { + return posix_fallocate$sysv(fd, offset, length); + } else if (IsWindows()) { + if (!isfdkind(fd, kFdFile)) return ebadf(); + if (mode == FALLOC_FL_ZERO_RANGE) { + if (DeviceIoControl( + g_fds.p[fd].handle, kNtFsctlSetZeroData, + &(struct NtFileZeroDataInformation){offset, offset + length}, + sizeof(struct NtFileZeroDataInformation), NULL, 0, &br, NULL)) { + return 0; + } else { + return winerr(); + } + } else if (!mode && !offset) { + /* + * this should commit physical space + * but not guaranteed zero'd like linux + */ + return ftruncate$nt(fd, length); + } else { + return eopnotsupp(); + } + } else { + return enosys(); + } +} diff --git a/libc/calls/fchmod.c b/libc/calls/fchmod.c new file mode 100644 index 00000000..83988fe7 --- /dev/null +++ b/libc/calls/fchmod.c @@ -0,0 +1,48 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sysv/errfuns.h" + +/** + * Changes file permissions via open()'d file descriptor, e.g.: + * + * CHECK_NE(-1, chmod("foo/bar.txt", 0644)); + * CHECK_NE(-1, chmod("o/default/program.com", 0755)); + * CHECK_NE(-1, chmod("privatefolder/", 0700)); + * + * The esoteric bits generally available on System V are: + * + * CHECK_NE(-1, chmod("/opt/", 01000)); // sticky bit + * CHECK_NE(-1, chmod("/usr/bin/sudo", 04755)); // setuid bit + * CHECK_NE(-1, chmod("/usr/bin/wall", 02755)); // setgid bit + * + * This works on Windows NT if you ignore the error ;-) + * + * @param mode contains octal flags (base 8) + * @errors ENOSYS + * @asyncsignalsafe + * @see chmod() + */ +int fchmod(int fd, uint32_t mode) { + /* TODO(jart): Windows */ + return fchmod$sysv(fd, mode); +} diff --git a/libc/calls/fchown.c b/libc/calls/fchown.c new file mode 100644 index 00000000..728c54a5 --- /dev/null +++ b/libc/calls/fchown.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/sysv/consts/at.h" + +/** + * Changes owner and/or group of file, via open()'d descriptor. + * + * @param uid is user id, or -1u to not change + * @param gid is group id, or -1u to not change + * @return 0 on success, or -1 w/ errno + * @see /etc/passwd for user ids + * @see /etc/group for group ids + */ +int fchown(int fd, uint32_t uid, uint32_t gid) { + /* TODO(jart): Windows? */ + return fchown$sysv(fd, uid, gid); +} diff --git a/libc/calls/fchownat.c b/libc/calls/fchownat.c new file mode 100644 index 00000000..98053649 --- /dev/null +++ b/libc/calls/fchownat.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" + +/** + * Changes owner and/or group of pathname. + * + * @param dirfd is open()'d relative-to directory, or AT_FDCWD, etc. + * @param uid is user id, or -1 to not change + * @param gid is group id, or -1 to not change + * @param flags can have AT_SYMLINK_NOFOLLOW, etc. + * @return 0 on success, or -1 w/ errno + * @see chown(), lchown() for shorthand notation + * @see /etc/passwd for user ids + * @see /etc/group for group ids + * @asyncsignalsafe + */ +int fchownat(int dirfd, const char *pathname, uint32_t uid, uint32_t gid, + uint32_t flags) { + /* TODO(jart): Windows? */ + return fchownat$sysv(dirfd, pathname, uid, gid, flags); +} diff --git a/libc/calls/fcntl-nt.c b/libc/calls/fcntl-nt.c new file mode 100644 index 00000000..051d39a9 --- /dev/null +++ b/libc/calls/fcntl-nt.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/files.h" +#include "libc/sysv/consts/f.h" +#include "libc/sysv/consts/fd.h" +#include "libc/sysv/errfuns.h" + +textwindows int fcntl$nt(int fd, int cmd, unsigned arg) { + if (!isfdindex(fd)) return ebadf(); + switch (cmd) { + case F_GETFD: + return GetHandleInformation(g_fds.p[fd].handle, &arg) ? (arg ^ FD_CLOEXEC) + : -1; + case F_SETFD: + return SetHandleInformation(g_fds.p[fd].handle, FD_CLOEXEC, + arg ^ FD_CLOEXEC) + ? 0 + : -1; + default: + return 0; /* TODO(jart): Implement me. */ + } +} diff --git a/libc/calls/fcntl.c b/libc/calls/fcntl.c new file mode 100644 index 00000000..4ef74e4c --- /dev/null +++ b/libc/calls/fcntl.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" + +/** + * Does things with file descriptor, via re-imagined hourglass api, e.g. + * + * CHECK_NE(-1, fcntl(fd, F_SETFD, FD_CLOEXEC)); + * + * @param cmd can be F_{GET,SET}{FD,FL}, etc. + * @param arg can be FD_CLOEXEC, etc. depending + * @return 0 on success, or -1 w/ errno + * @asyncsignalsafe + */ +int fcntl(int fd, int cmd, int arg) { + if (!IsWindows()) { + return fcntl$sysv(fd, cmd, arg); + } else { + return fcntl$nt(fd, cmd, arg); + } +} diff --git a/libc/calls/fdatasync-nt.c b/libc/calls/fdatasync-nt.c new file mode 100644 index 00000000..1f781a71 --- /dev/null +++ b/libc/calls/fdatasync-nt.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/files.h" +#include "libc/sysv/errfuns.h" + +textwindows int fdatasync$nt(int fd) { + if (!isfdkind(fd, kFdFile)) return ebadf(); + /* + * XXX: On Windows NT this might be more analagous to fflush() and + * Microsoft docs say to do manual block i/o for database-ish + * guarantees on disk persistence. Consider: Really good UPS. + */ + return FlushFileBuffers(g_fds.p[fd].handle) ? 0 : winerr(); +} diff --git a/libc/calls/fdatasync.c b/libc/calls/fdatasync.c new file mode 100644 index 00000000..2e4fc806 --- /dev/null +++ b/libc/calls/fdatasync.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" + +/** + * Blocks until kernel flushes non-metadata buffers for fd to disk. + * + * @return 0 on success, or -1 w/ errno + * @see fsync(), sync_file_range() + * @asyncsignalsafe + */ +int fdatasync(int fd) { + if (!IsWindows()) { + return fdatasync$sysv(fd); + } else { + return fdatasync$nt(fd); + } +} diff --git a/libc/calls/fdkind.c b/libc/calls/fdkind.c new file mode 100644 index 00000000..5587c12b --- /dev/null +++ b/libc/calls/fdkind.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" + +enum FdKind fdkind(int fd) { + if (isfdindex(fd)) { + return g_fds.p[fd].kind; + } else { + return kFdEmpty; + } +} diff --git a/libc/calls/fileexists.c b/libc/calls/fileexists.c new file mode 100644 index 00000000..4ef29df4 --- /dev/null +++ b/libc/calls/fileexists.c @@ -0,0 +1,44 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/struct/stat.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/nt/files.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +/** + * Returns true if file exists at path. + * + * Please note that things which aren't strictly files, e.g. directories + * or sockets, could be considered files for the purposes of this + * function. The stat() function may be used to differentiate them. + */ +bool fileexists(const char *path) { + /* TODO(jart): Use fast path on NT? */ + struct stat st; + int olderr = errno; + int rc = stat(path, &st); + if (rc == -1 && (errno == ENOENT || errno == ENOTDIR)) { + errno = olderr; + } + return rc != -1; +} diff --git a/libc/calls/fixntmagicpath.ncabi.c b/libc/calls/fixntmagicpath.ncabi.c new file mode 100644 index 00000000..9eafb666 --- /dev/null +++ b/libc/calls/fixntmagicpath.ncabi.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/ntmagicpaths.h" +#include "libc/nexgen32e/tinystrcmp.h" +#include "libc/sysv/consts/o.h" + +textwindows const char *(fixntmagicpath)(const char *path, unsigned flags) { + const struct NtMagicPaths *mp = &kNtMagicPaths; + asm("" : "+r"(mp)); + if (path[0] != '/') return path; + if (tinystrcmp(path, mp->devtty) == 0) { + if ((flags & O_ACCMODE) == O_RDONLY) { + return mp->conin; + } else if ((flags & O_ACCMODE) == O_WRONLY) { + return mp->conout; + } + } + if (tinystrcmp(path, mp->devnull) == 0) return mp->nul; + if (tinystrcmp(path, mp->devstdin) == 0) return mp->conin; + if (tinystrcmp(path, mp->devstdout) == 0) return mp->conout; + return path; +} diff --git a/libc/calls/fixupnewfd.c b/libc/calls/fixupnewfd.c new file mode 100644 index 00000000..abecef27 --- /dev/null +++ b/libc/calls/fixupnewfd.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/sysv/consts/f.h" +#include "libc/sysv/consts/fd.h" +#include "libc/sysv/consts/o.h" + +/** + * Applies file descriptor fixups on XNU or old Linux. + * @see fixupnewsockfd$sysv() for socket file descriptors + */ +int fixupnewfd$sysv(int fd, int flags) { + if (fd != -1) { + if (flags & O_CLOEXEC) fcntl$sysv(fd, F_SETFD, FD_CLOEXEC); + fcntl$sysv(fd, F_SETFL, + (fcntl$sysv(fd, F_GETFL, 0) ^ (flags & O_NONBLOCK))); + } + return fd; +} diff --git a/libc/calls/flock-nt.c b/libc/calls/flock-nt.c new file mode 100644 index 00000000..c9418e3e --- /dev/null +++ b/libc/calls/flock-nt.c @@ -0,0 +1,44 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/byhandlefileinformation.h" +#include "libc/nt/struct/overlapped.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/lock.h" +#include "libc/sysv/errfuns.h" + +textwindows int flock$nt(int fd, int op) { + struct NtOverlapped ov; + struct NtByHandleFileInformation info; + if (!isfdkind(fd, kFdFile)) return ebadf(); + memset(&ov, 0, sizeof(ov)); + if (GetFileInformationByHandle(g_fds.p[fd].handle, &info) && + ((!(op & LOCK_UN) && + LockFileEx(g_fds.p[fd].handle, op, 0, info.nFileSizeLow, + info.nFileSizeHigh, &ov)) || + ((op & LOCK_UN) && UnlockFileEx(g_fds.p[fd].handle, 0, info.nFileSizeLow, + info.nFileSizeHigh, &ov)))) { + return 0; + } else { + return winerr(); + } +} diff --git a/libc/calls/flock.c b/libc/calls/flock.c new file mode 100644 index 00000000..4e4b3a65 --- /dev/null +++ b/libc/calls/flock.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" + +/** + * Acquires lock on file. + * + * @param op can have LOCK_{SH,EX,NB,UN} for shared, exclusive, + * non-blocking, and unlocking + * @return 0 on success, or -1 w/ errno + */ +int flock(int fd, int op) { + if (!IsWindows()) { + return flock$sysv(fd, op); + } else { + return flock$nt(fd, op); + } +} diff --git a/libc/calls/fork.c b/libc/calls/fork.c new file mode 100644 index 00000000..f6c9bbe5 --- /dev/null +++ b/libc/calls/fork.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" + +/** + * Creates new process zygote style. + * + * @return 0 to child, child pid to parent, or -1 on error + * @asyncsignalsafe + */ +int fork(void) { + int rc; + rc = fork$sysv(); + if (rc == 0) __onfork(); + return rc; +} diff --git a/libc/calls/fprot2nt.c b/libc/calls/fprot2nt.c new file mode 100644 index 00000000..3c7d9fe6 --- /dev/null +++ b/libc/calls/fprot2nt.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/enum/filemapflags.h" +#include "libc/nt/memory.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" + +#define HAS(X, BITS) (((X) & (BITS)) == (BITS)) + +/** + * Converts System Five memory protection flags to Windows NT, Part 2. + * @see libc/sysv/consts.sh + */ +uint32_t fprot2nt(int prot, int flags) { + return (HAS(prot, PROT_READ) ? kNtFileMapRead : 0) | + (HAS(prot, PROT_WRITE) ? kNtFileMapWrite : 0) | + (HAS(prot, PROT_EXEC) ? kNtFileMapExecute : 0) | + (HAS(flags, MAP_PRIVATE) ? kNtFileMapCopy : 0) | + (HAS(flags, kNtSecLargePages) ? kNtFileMapLargePages : 0) | + (HAS(flags, kNtSecReserve) ? kNtFileMapReserve : 0); +} diff --git a/libc/calls/fstat-nt.c b/libc/calls/fstat-nt.c new file mode 100644 index 00000000..be4a64d3 --- /dev/null +++ b/libc/calls/fstat-nt.c @@ -0,0 +1,71 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/stat.h" +#include "libc/conv/conv.h" +#include "libc/nt/enum/fileflagandattributes.h" +#include "libc/nt/enum/fileinfobyhandleclass.h" +#include "libc/nt/enum/filetype.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/byhandlefileinformation.h" +#include "libc/nt/struct/filecompressioninfo.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/s.h" + +textwindows int fstat$nt(int64_t handle, struct stat *st) { + uint64_t actualsize; + enum NtFileType filetype; + struct NtByHandleFileInformation wst; + struct NtFileCompressionInfo fci; + if (GetFileInformationByHandle(handle, &wst)) { + memset(st, 0, sizeof(*st)); + filetype = GetFileType(handle); + st->st_mode = + (S_IRUSR | S_IXUSR | + (!(wst.dwFileAttributes & kNtFileAttributeReadonly) ? S_IWUSR : 0) | + ((wst.dwFileAttributes & kNtFileAttributeNormal) ? S_IFREG : 0) | + ((wst.dwFileAttributes & kNtFileFlagOpenReparsePoint) ? S_IFLNK : 0) | + ((wst.dwFileAttributes & kNtFileAttributeDirectory) + ? S_IFDIR + : (((filetype == kNtFileTypeDisk) ? S_IFBLK : 0) | + ((filetype == kNtFileTypeChar) ? S_IFCHR : 0) | + ((filetype == kNtFileTypePipe) ? S_IFIFO : 0)))); + filetimetotimespec(&st->st_atim, wst.ftLastAccessFileTime); + filetimetotimespec(&st->st_mtim, wst.ftLastWriteFileTime); + filetimetotimespec(&st->st_ctim, wst.ftCreationFileTime); + st->st_size = (uint64_t)wst.nFileSizeHigh << 32 | wst.nFileSizeLow; + st->st_blksize = PAGESIZE; + st->st_dev = wst.dwVolumeSerialNumber; + st->st_ino = (uint64_t)wst.nFileIndexHigh << 32 | wst.nFileIndexLow; + st->st_nlink = wst.nNumberOfLinks; + if (GetFileInformationByHandleEx(handle, kNtFileCompressionInfo, &fci, + sizeof(fci))) { + actualsize = fci.CompressedFileSize; + } else { + actualsize = st->st_size; + } + st->st_blocks = roundup(actualsize, PAGESIZE) / 512; + return 0; + } else { + return winerr(); + } +} diff --git a/libc/calls/fstat-sysv.c b/libc/calls/fstat-sysv.c new file mode 100644 index 00000000..0931d4f4 --- /dev/null +++ b/libc/calls/fstat-sysv.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" + +/** + * Supports fstat(), etc. implementations. + * @asyncsignalsafe + */ +int32_t fstat$sysv(int32_t fd, struct stat *st) { + int res; + if ((res = __fstat$sysv(fd, st)) != -1) { + stat2linux(st); + } + return res; +} diff --git a/libc/calls/fstat.c b/libc/calls/fstat.c new file mode 100644 index 00000000..aec7e456 --- /dev/null +++ b/libc/calls/fstat.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sysv/errfuns.h" +#include "libc/zipos/zipos.h" + +/** + * Returns information about file, via open()'d descriptor. + * @asyncsignalsafe + */ +int fstat(int fd, struct stat *st) { + if (isfdkind(fd, kFdZip)) { + return weaken(__zipos_fstat)( + (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, st); + } else if (!IsWindows()) { + return fstat$sysv(fd, st); + } else { + if (!isfdkind(fd, kFdFile)) return ebadf(); + return fstat$nt(g_fds.p[fd].handle, st); + } +} diff --git a/libc/calls/fstatat-sysv.c b/libc/calls/fstatat-sysv.c new file mode 100644 index 00000000..f2c1e92f --- /dev/null +++ b/libc/calls/fstatat-sysv.c @@ -0,0 +1,33 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" + +/** + * Supports stat(), lstat(), fstatat(), etc. implementations. + * @asyncsignalsafe + */ +int32_t fstatat$sysv(int32_t dirfd, const char *pathname, struct stat *st, + int32_t flags) { + int32_t rc; + if ((rc = __fstatat$sysv(dirfd, pathname, st, flags)) != -1) { + stat2linux(st); + } + return rc; +} diff --git a/libc/calls/fstatat.c b/libc/calls/fstatat.c new file mode 100644 index 00000000..99fe0ff1 --- /dev/null +++ b/libc/calls/fstatat.c @@ -0,0 +1,49 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/errno.h" +#include "libc/sysv/consts/at.h" + +/** + * Performs stat() w/ features for threaded apps. + * + * @param dirfd can be AT_FDCWD or an open directory descriptor, and is + * ignored if pathname is absolute + * @param flags can have AT_{EMPTY_PATH,NO_AUTOMOUNT,SYMLINK_NOFOLLOW} + * @return 0 on success, or -1 w/ errno + * @asyncsignalsafe + */ +int fstatat(int dirfd, const char *pathname, struct stat *st, uint32_t flags) { + int olderr = errno; + int rc = fstatat$sysv(dirfd, pathname, st, flags); + if (rc != -1) { + stat2linux(st); + } else if (errno == ENOSYS && dirfd == AT_FDCWD) { + if (!flags) { + errno = olderr; + rc = stat(pathname, st); + } else if (flags == AT_SYMLINK_NOFOLLOW) { + errno = olderr; + rc = lstat(pathname, st); + } + } + return rc; +} diff --git a/libc/calls/fsync.c b/libc/calls/fsync.c new file mode 100644 index 00000000..0ca3bb8f --- /dev/null +++ b/libc/calls/fsync.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" + +/** + * Blocks until kernel flushes buffers for fd to disk. + * + * @return 0 on success, or -1 w/ errno + * @see fdatasync(), sync_file_range() + * @asyncsignalsafe + */ +int fsync(int fd) { + if (!IsWindows()) { + return fsync$sysv(fd); + } else { + return fdatasync$nt(fd); + } +} diff --git a/libc/calls/ftruncate-nt.c b/libc/calls/ftruncate-nt.c new file mode 100644 index 00000000..e0dc335a --- /dev/null +++ b/libc/calls/ftruncate-nt.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/enum/filemovemethod.h" +#include "libc/nt/files.h" +#include "libc/sysv/errfuns.h" + +textwindows int ftruncate$nt(int fd, uint64_t length) { + bool32 ok; + int64_t tell; + if (!isfdkind(fd, kFdFile)) return ebadf(); + tell = -1; + if (SetFilePointerEx(g_fds.p[fd].handle, 0, &tell, kNtFileCurrent)) { + ok = SetFilePointerEx(g_fds.p[fd].handle, length, NULL, kNtFileBegin) && + SetEndOfFile(g_fds.p[fd].handle); + SetFilePointerEx(g_fds.p[fd].handle, tell, NULL, kNtFileBegin); + return ok ? 0 : winerr(); + } else { + return winerr(); + } +} diff --git a/libc/calls/ftruncate.c b/libc/calls/ftruncate.c new file mode 100644 index 00000000..749316cd --- /dev/null +++ b/libc/calls/ftruncate.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" + +/** + * Changes size of file. + * + * @param fd must be open for writing + * @param length may be greater than current current file size, in which + * case System V guarantees it'll be zero'd but Windows NT doesn't; + * since the prior extends logically and the latter physically + * @return 0 on success, or -1 w/ errno + * @asyncsignalsafe + * @see fallocate() + */ +int ftruncate(int fd, int64_t length) { + if (!IsWindows()) { + return ftruncate$sysv(fd, length); + } else { + return ftruncate$nt(fd, length); + } +} diff --git a/libc/calls/g_fds.c b/libc/calls/g_fds.c new file mode 100644 index 00000000..17e42925 --- /dev/null +++ b/libc/calls/g_fds.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/pushpop.h" +#include "libc/calls/internal.h" +#include "libc/macros.h" +#include "libc/nt/runtime.h" +#include "libc/sysv/consts/fileno.h" + +struct Fds g_fds; + +INITIALIZER(300, _init_g_fds, { + struct Fds *fds; + fds = VEIL("D", &g_fds); + pushmov(&fds->f, 3ul); + pushmov(&fds->n, ARRAYLEN(fds->__init_p)); + fds->p = fds->__init_p; + fds->__init_p[STDIN_FILENO].kind = pushpop(kFdFile); + fds->__init_p[STDOUT_FILENO].kind = pushpop(kFdFile); + fds->__init_p[STDERR_FILENO].kind = pushpop(kFdFile); + fds->__init_p[STDIN_FILENO].handle = GetStdHandle(pushpop(kNtStdInputHandle)); + fds->__init_p[STDOUT_FILENO].handle = + GetStdHandle(pushpop(kNtStdOutputHandle)); + fds->__init_p[STDERR_FILENO].handle = + GetStdHandle(pushpop(kNtStdErrorHandle)); +}) diff --git a/libc/calls/g_ntstartupinfo.c b/libc/calls/g_ntstartupinfo.c new file mode 100644 index 00000000..eddb6024 --- /dev/null +++ b/libc/calls/g_ntstartupinfo.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/startupinfo.h" +#include "libc/nt/struct/startupinfo.h" + +/** + * GetStartupInfo() singleton. + * @see libc/runtime/winmain.c + */ +struct NtStartupInfo g_ntstartupinfo; + +STATIC_YOINK("_init_g_ntstartupinfo"); diff --git a/libc/calls/g_ntstartupinfo_init.S b/libc/calls/g_ntstartupinfo_init.S new file mode 100644 index 00000000..1ad69406 --- /dev/null +++ b/libc/calls/g_ntstartupinfo_init.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + + .init.start 400,_init_g_ntstartupinfo + ezlea g_ntstartupinfo,cx + mov %rsp,%rbp + ntcall __imp_GetStartupInfoW + .init.end 400,_init_g_ntstartupinfo,globl,hidden diff --git a/libc/calls/g_ntsysteminfo.c b/libc/calls/g_ntsysteminfo.c new file mode 100644 index 00000000..77690a40 --- /dev/null +++ b/libc/calls/g_ntsysteminfo.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/struct/systeminfo.h" +#include "libc/nt/systeminfo.h" + +/** + * GetSystemInfo() singleton. + * @see libc/runtime/winmain.c + */ +struct NtSystemInfo g_ntsysteminfo; + +STATIC_YOINK("_init_g_ntsysteminfo"); diff --git a/libc/calls/g_ntsysteminfo_init.S b/libc/calls/g_ntsysteminfo_init.S new file mode 100644 index 00000000..995305cc --- /dev/null +++ b/libc/calls/g_ntsysteminfo_init.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + + .init.start 400,_init_g_ntsysteminfo + ezlea g_ntsysteminfo,cx + mov %rsp,%rbp + ntcall __imp_GetSystemInfo + .init.end 400,_init_g_ntsysteminfo,globl,hidden diff --git a/libc/calls/g_sighandrvas.c b/libc/calls/g_sighandrvas.c new file mode 100644 index 00000000..fc6f09ee --- /dev/null +++ b/libc/calls/g_sighandrvas.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" + +int g_sighandrvas[NSIG]; diff --git a/libc/calls/getauxval.c b/libc/calls/getauxval.c new file mode 100644 index 00000000..f5be55b2 --- /dev/null +++ b/libc/calls/getauxval.c @@ -0,0 +1,70 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/auxv.h" + +/** + * Returns auxiliary value, or zero if kernel didn't provide it. + * + * This function is typically regarded as a libc implementation detail; + * thus, the source code is the documentation. + * + * @see libc/sysv/consts.sh + * @see System Five Application Binary Interface § 3.4.3 + * @asyncsignalsafe + */ +unsigned long getauxval(unsigned long at) { + unsigned long res = 0; + if (at != -1) { + if (!IsWindows()) { + if (!g_auxv) return 0; + if (IsXnu()) { + if (at) { + const char *name = + at == AT_EXECFN ? "executable_path" : (const char *)at; + const char **auxv = (const char **)g_auxv; + unsigned namelen = strlen(name); + for (int i = 0; auxv[i]; ++i) { + if (strncmp(auxv[i], name, namelen) == 0 && + auxv[i][namelen] == '=') { + res = (intptr_t)&auxv[i][namelen + 1]; + break; + } + } + } + } else { + for (const unsigned long *ap = g_auxv; *ap; ap += 2) { + if (ap[0] == at) { + res = ap[1]; + break; + } + } + } + } else { + /* TODO(jart): GetProcessImageFileName */ + } + if (res == 0 && at == AT_EXECFN) { + res = (uintptr_t)program_invocation_name; + } + } + return res; +} diff --git a/libc/calls/getcwd-nt.c b/libc/calls/getcwd-nt.c new file mode 100644 index 00000000..59a24b8a --- /dev/null +++ b/libc/calls/getcwd-nt.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/files.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +textwindows char *getcwd$nt(char *buf, size_t size) { + uint16_t name16[PATH_MAX]; + if (GetCurrentDirectory(PATH_MAX, name16)) { + if (tprecode16to8(buf, size, name16) < size - 1) { + return buf; + } else { + erange(); + } + } else { + winerr(); + } + return NULL; +} diff --git a/libc/calls/getcwd.c b/libc/calls/getcwd.c new file mode 100644 index 00000000..bf3c21c4 --- /dev/null +++ b/libc/calls/getcwd.c @@ -0,0 +1,57 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/sysv/errfuns.h" + +/** + * Returns current working directory. + * + * @param buf is where UTF-8 NUL-terminated path string gets written, + * which may be NULL to ask this function to malloc a buffer + * @param size is number of bytes available in buf, e.g. PATH_MAX, + * which may be 0 if buf NULL + * @return buf containing system-normative path or NULL w/ errno + * @see get_current_dir_name() which is better + * @error ERANGE, EINVAL + */ +char *(getcwd)(char *buf, size_t size) { + buf[0] = '\0'; + if (!IsWindows()) { + int olderr = errno; + if (getcwd$sysv(buf, size) != NULL) { + return buf; + } else if (IsXnu() && errno == ENOSYS) { + if (size >= 2) { + buf[0] = '.'; /* XXX: could put forth more effort */ + buf[1] = '\0'; + errno = olderr; + return buf; + } else { + erange(); + } + } + return NULL; + } else { + return getcwd$nt(buf, size); + } +} diff --git a/libc/calls/getenv.c b/libc/calls/getenv.c new file mode 100644 index 00000000..df77208b --- /dev/null +++ b/libc/calls/getenv.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" + +/** + * Returns value of environment variable, or NULL if not found. + */ +char *getenv(const char *name) { + char *empty[1] = {NULL}; + char **ep = firstnonnull(environ, empty); + unsigned namelen = strlen(name); + for (int i = 0; ep[i]; ++i) { + if (strncmp(ep[i], name, namelen) == 0 && ep[i][namelen] == '=') { + return &ep[i][namelen + 1]; + } + } + return NULL; +} diff --git a/libc/calls/getfiledescriptorsize.c b/libc/calls/getfiledescriptorsize.c new file mode 100644 index 00000000..c5825110 --- /dev/null +++ b/libc/calls/getfiledescriptorsize.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/struct/stat.h" +#include "libc/dce.h" +#include "libc/limits.h" +#include "libc/nt/files.h" + +/** + * Determines size of open file. + * + * @return file byte length, or -1ul w/ errno + * @asyncsignalsafe + */ +size_t getfiledescriptorsize(int fd) { + struct stat st; + if (fstat(fd, &st) == -1) return SIZE_MAX; + return st.st_size; +} diff --git a/libc/calls/getfilesize.c b/libc/calls/getfilesize.c new file mode 100644 index 00000000..a21df9fe --- /dev/null +++ b/libc/calls/getfilesize.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/stat.h" +#include "libc/dce.h" +#include "libc/limits.h" +#include "libc/nt/files.h" +#include "libc/str/str.h" + +/** + * Returns the byte length of file by path. + * + * @return number of bytes, or -1ul w/ errno + * @see getfiledescriptorsize + */ +size_t GetFileSize(const char *pathname) { + struct stat st; + if (stat(pathname, &st) == -1) return SIZE_MAX; + return st.st_size; +} diff --git a/libc/calls/getntsyspath.S b/libc/calls/getntsyspath.S new file mode 100644 index 00000000..3e534963 --- /dev/null +++ b/libc/calls/getntsyspath.S @@ -0,0 +1,55 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Obtains WIN32 magic path, e.g. GetTempPathA. +/ +/ @param rax is address of ANSI path provider function +/ @param rdi is output buffer +/ @param rdx is output buffer size in bytes that's >0 +/ @return eax is string length w/ NUL that's ≤ edx +/ @return rdi is rdi+edx + .text.startup +__getntsyspath: + push %rbp + mov %rsp,%rbp + push %rdx + movpp %rdi,%rcx # call f=%rax(p1=%rcx,p2=%rdx) + sub $40,%rsp + call *%rax + xor %edx,%edx + mov -8(%rbp),%ecx # restore %edx param as %ecx + cmp %eax,%ecx # use current dir on overflow + cmovbe %edx,%eax + cmp $1,%eax # leave empty strings empty + jbe 1f + cmpb $'\\,-1(%rdi,%rax) # guarantee trailing slash + je 1f + movw $'\\,(%rdi,%rax) + inc %eax +1: inc %rdi # change backslash to slash + cmpb $'\\,-1(%rdi) + jne 2f + movb $'/,-1(%rdi) +2: loop 1b + leave + ret + .endfn __getntsyspath,globl,hidden diff --git a/libc/calls/getpid.c b/libc/calls/getpid.c new file mode 100644 index 00000000..23374355 --- /dev/null +++ b/libc/calls/getpid.c @@ -0,0 +1,54 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/nt/process.h" +#include "libc/runtime/missioncritical.h" +#include "libc/runtime/runtime.h" + +static int g_pid; + +static void __updatepid(void) { + atfork(__updatepid, NULL); + g_pid = __getpid(); +} + +int __getpid(void) { + if (!IsWindows()) { + return GETPID(); + } else { + return NtGetPid(); + } +} + +/** + * Returns process id. + * @asyncsignalsafe + */ +int getpid(void) { + static bool once; + if (!once) { + once = true; + __updatepid(); + } + return g_pid; +} diff --git a/libc/calls/getppid.c b/libc/calls/getppid.c new file mode 100644 index 00000000..168f8905 --- /dev/null +++ b/libc/calls/getppid.c @@ -0,0 +1,53 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/nt/nt/process.h" +#include "libc/nt/ntdll.h" +#include "libc/nt/process.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/processbasicinformation.h" + +static textwindows noinline int32_t getppid$nt(void) { + struct NtProcessBasicInformation ProcessInformation; + uint32_t gotsize = 0; + if (!NtError( + NtQueryInformationProcess(GetCurrentProcess(), 0, &ProcessInformation, + sizeof(ProcessInformation), &gotsize)) && + gotsize >= sizeof(ProcessInformation) && + ProcessInformation.InheritedFromUniqueProcessId) { + /* TODO(jart): Fix type mismatch and do we need to close this? */ + return ProcessInformation.InheritedFromUniqueProcessId; + } + return GetCurrentProcessId(); +} + +/** + * Returns parent process id. + * @asyncsignalsafe + */ +int32_t getppid(void) { + if (!IsWindows()) { + return getppid$sysv(); + } else { + return getppid$nt(); + } +} diff --git a/libc/calls/getpriority-nt.c b/libc/calls/getpriority-nt.c new file mode 100644 index 00000000..15763f80 --- /dev/null +++ b/libc/calls/getpriority-nt.c @@ -0,0 +1,50 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/kntprioritycombos.h" +#include "libc/conv/conv.h" +#include "libc/nt/enum/processcreationflags.h" +#include "libc/nt/enum/threadpriority.h" +#include "libc/nt/process.h" +#include "libc/nt/runtime.h" +#include "libc/nt/thread.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/prio.h" +#include "libc/sysv/errfuns.h" + +textwindows int getpriority$nt(int ignored) { + size_t i; + uint32_t tier, lg2tier, wut; + if ((tier = GetPriorityClass(GetCurrentProcess())) != 0 && + (wut = GetThreadPriority(GetCurrentThread())) != -1u) { + lg2tier = ffs(tier); + for (i = 0; i < kNtPriorityCombosLen; ++i) { + if (kNtPriorityCombos[i].lg2tier == lg2tier && + kNtPriorityCombos[i].wut == wut) { + return kNtPriorityCombos[i].nice; + } + } + abort(); + } else { + return winerr(); + } +} diff --git a/libc/calls/getpriority.c b/libc/calls/getpriority.c new file mode 100644 index 00000000..42c208b4 --- /dev/null +++ b/libc/calls/getpriority.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" + +/** + * Returns nice value of thing. + * + * @param which can be PRIO_PROCESS, PRIO_PGRP, PRIO_USER + * @param who is the pid, pgid, or uid (0 means current) + * @return value ∈ [-NZERO,NZERO) or -1 w/ errno + * @see setpriority(), nice() + */ +int getpriority(int which, unsigned who) { + if (!IsWindows()) { + return getpriority$sysv(which, who) - 20; + } else { + return getsetpriority$nt(which, who, 0, getpriority$nt); + } +} diff --git a/libc/calls/getprocaddressmodule.c b/libc/calls/getprocaddressmodule.c new file mode 100644 index 00000000..1edf4b29 --- /dev/null +++ b/libc/calls/getprocaddressmodule.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/nt/dll.h" +#include "libc/calls/calls.h" + +/** + * Returns address of function in a DLL that's already loaded. + */ +textwindows void *getprocaddressmodule(const char *module, const char *symbol) { + return GetProcAddress(GetModuleHandle(module), symbol); +} diff --git a/libc/calls/getrlimit.c b/libc/calls/getrlimit.c new file mode 100644 index 00000000..1ddb0253 --- /dev/null +++ b/libc/calls/getrlimit.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sysv/errfuns.h" + +/** + * Gets resource limit for current process. + * + * @param resource can be RLIMIT_{CPU,FSIZE,DATA,STACK,CORE,RSS,etc.} + * @param rlim receives result, modified only on success + * @return 0 on success or -1 w/ errno + * @see libc/sysv/consts.sh + */ +int getrlimit(int resource, struct rlimit *rlim) { + /* TODO(jart): Windows */ + if (resource == -1) return einval(); + return getrlimit$sysv(resource, rlim); +} diff --git a/libc/calls/getrusage.c b/libc/calls/getrusage.c new file mode 100644 index 00000000..db4332f6 --- /dev/null +++ b/libc/calls/getrusage.c @@ -0,0 +1,65 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/rusage.h" +#include "libc/conv/conv.h" +#include "libc/dce.h" +#include "libc/nt/accounting.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/filetime.h" +#include "libc/nt/thread.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/rusage.h" +#include "libc/sysv/errfuns.h" + +static textwindows noinline int getrusage$nt(int who, struct rusage *usage) { + struct NtFileTime CreationFileTime; + struct NtFileTime ExitFileTime; + struct NtFileTime KernelFileTime; + struct NtFileTime UserFileTime; + memset(usage, 0, sizeof(*usage)); + if ((who == RUSAGE_SELF ? GetProcessTimes : GetThreadTimes)( + (who == RUSAGE_SELF ? GetCurrentProcess : GetCurrentThread)(), + &CreationFileTime, &ExitFileTime, &KernelFileTime, &UserFileTime)) { + filetimetotimeval(&usage->ru_utime, UserFileTime); + filetimetotimeval(&usage->ru_stime, KernelFileTime); + return 0; + } else { + return winerr(); + } +} + +/** + * Returns resource usage statistics. + * + * @param who can be RUSAGE_{SELF,CHILDREN,THREAD} + * @return 0 on success, or -1 w/ errno + */ +int getrusage(int who, struct rusage *usage) { + if (who == 99) return enosys(); /* @see libc/sysv/consts.sh */ + if (!usage) return efault(); + if (!IsWindows()) { + return getrusage$sysv(who, usage); + } else { + return getrusage$nt(who, usage); + } +} diff --git a/libc/calls/getsetpriority-nt.c b/libc/calls/getsetpriority-nt.c new file mode 100644 index 00000000..9ee54583 --- /dev/null +++ b/libc/calls/getsetpriority-nt.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/conv/conv.h" +#include "libc/sysv/consts/prio.h" +#include "libc/sysv/errfuns.h" + +textwindows int getsetpriority$nt(int which, unsigned who, int value, + int (*impl)(int)) { + if (which != PRIO_PROCESS && which != PRIO_PGRP) return einval(); + if (who && abs(who) != getpid() && abs(who) != gettid()) return eopnotsupp(); + return impl(value); +} diff --git a/libc/calls/gettid.c b/libc/calls/gettid.c new file mode 100644 index 00000000..59de1a75 --- /dev/null +++ b/libc/calls/gettid.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/nt/thread.h" + +/** + * Returns current thread id. + * @asyncsignalsafe + */ +uint32_t gettid(void) { + if (!IsWindows()) { + uint32_t res; + res = gettid$sysv(); + if (res <= 0) { + res = getpid(); + } + return res; + } else { + return GetCurrentThreadId(); + } +} diff --git a/libc/calls/getuid.c b/libc/calls/getuid.c new file mode 100644 index 00000000..c747970b --- /dev/null +++ b/libc/calls/getuid.c @@ -0,0 +1,73 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/macros.h" +#include "libc/nt/accounting.h" +#include "libc/runtime/runtime.h" +#include "libc/str/knuthmultiplicativehash.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/auxv.h" + +static textwindows noinline uint32_t GetUserNameHash(void) { + char16_t buf[257]; + uint32_t size = ARRAYLEN(buf); + GetUserName(&buf, &size); + return KnuthMultiplicativeHash32(buf, size >> 1); +} + +static uint32_t getuidgid(int at, uint32_t impl(void)) { + if (!IsWindows()) { + if (at != -1) { + return getauxval(at); + } else { + return impl(); + } + } else { + return GetUserNameHash(); + } +} + +/** + * Returns real user id of process. + * + * This never fails. On Windows, which doesn't really have this concept, + * we return a deterministic value that's likely to work. On Linux, this + * is fast. + * + * @asyncsignalsafe + */ +uint32_t getuid(void) { + return getuidgid(AT_UID, getuid$sysv); +} + +/** + * Returns real group id of process. + * + * This never fails. On Windows, which doesn't really have this concept, + * we return a deterministic value that's likely to work. On Linux, this + * is fast. + * + * @asyncsignalsafe + */ +uint32_t getgid(void) { + return getuidgid(AT_GID, getgid$sysv); +} diff --git a/libc/calls/grantpt.c b/libc/calls/grantpt.c new file mode 100644 index 00000000..9c4e006c --- /dev/null +++ b/libc/calls/grantpt.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" + +int grantpt(int fd) { return 0; } diff --git a/libc/calls/growfds.c b/libc/calls/growfds.c new file mode 100644 index 00000000..8759fd7f --- /dev/null +++ b/libc/calls/growfds.c @@ -0,0 +1,44 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/calls/internal.h" +#include "libc/mem/mem.h" +#include "libc/sysv/errfuns.h" + +int growfds(void) { + size_t i, n; + struct Fd *p; + if (weaken(realloc)) { + if ((p = weaken(realloc)(g_fds.p != g_fds.__init_p ? g_fds.p : NULL, + (n = ((i = g_fds.n) * 2)) * sizeof(*p)))) { + do { + p[i++].kind = kFdEmpty; + } while (i < n); + g_fds.p = p; + g_fds.n = n; + return 0; + } else { + return enomem(); + } + } else { + return emfile(); + } +} diff --git a/libc/calls/hefty/access.c b/libc/calls/hefty/access.c new file mode 100644 index 00000000..cfa2647e --- /dev/null +++ b/libc/calls/hefty/access.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/calls/internal.h" +#include "libc/calls/calls.h" +#include "libc/sysv/consts/at.h" + +/** + * Checks if effective user can access path in particular ways. + * + * @param path is a filename or directory + * @param mode can be R_OK, W_OK, X_OK, F_OK + * @return 0 if ok, or -1 and sets errno + * @asyncsignalsafe + */ +int access(const char *path, int mode) { + if (!IsWindows()) { + return faccessat$sysv(AT_FDCWD, path, mode, 0); + } else { + char16_t path16[PATH_MAX]; + if (mkntpath(path, path16) == -1) return -1; + return ntaccesscheck(path16, mode); + } +} diff --git a/libc/calls/hefty/commandv.c b/libc/calls/hefty/commandv.c new file mode 100644 index 00000000..abc2157a --- /dev/null +++ b/libc/calls/hefty/commandv.c @@ -0,0 +1,170 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/bits/progn.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/conv/conv.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/mem/mem.h" +#include "libc/nt/ntdll.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/ok.h" +#include "libc/sysv/errfuns.h" + +static struct critbit0 g_commandv; + +textstartup static void g_commandv_init(void) { + __cxa_atexit(critbit0_clear, &g_commandv, NULL); +} + +const void *const g_commandv_ctor[] initarray = {g_commandv_init}; + +static int accessexe(char pathname[hasatleast PATH_MAX], size_t len, + const char *ext) { + len = stpcpy(&pathname[len], ext) - &pathname[0]; + if (access(pathname, X_OK) != -1) { + return len; + } else { + return -1; + } +} + +static int accesscmd(char pathname[hasatleast PATH_MAX], const char *path, + const char *name, size_t namelen) { /* cf. %PATHEXT% */ + int rc; + char *p; + bool hasdot; + size_t pathlen, len; + pathlen = strlen(path); + if (pathlen + 1 + namelen + 1 + 4 + 1 > PATH_MAX) return -1; + p = mempcpy(pathname, path, pathlen); + if (pathlen) *p++ = '/'; + p = mempcpy(p, name, namelen); + len = p - &pathname[0]; + hasdot = !!memchr(basename(name), '.', namelen); + if ((hasdot && (rc = accessexe(pathname, len, "")) != -1) || + (!hasdot && + ((rc = accessexe(pathname, len, ".com")) != -1 || + (IsWindows() && (rc = accessexe(pathname, len, ".exe")) != -1) || + (!IsWindows() && (rc = accessexe(pathname, len, "")) != -1)))) { + return rc; + } else { + return -1; + } +} + +static int searchcmdpath(char pathname[hasatleast PATH_MAX], const char *name, + size_t namelen) { + int rc; + char *ep, *path, *pathtok; + struct critbit0 deduplicate; + rc = -1; + pathtok = ep = + strdup(firstnonnull(getenv("PATH"), "/bin:/usr/local/bin:/usr/bin")); + memset(&deduplicate, 0, sizeof(deduplicate)); + while ((path = strsep(&pathtok, IsWindows() ? ";" : ":"))) { + if (strchr(path, '=')) continue; + if (!critbit0_insert(&deduplicate, path)) continue; + if ((rc = accesscmd(pathname, path, name, namelen)) != -1) { + break; + } + } + critbit0_clear(&deduplicate); + free(ep); + return rc; +} + +static char *mkcmdquery(const char *name, size_t namelen, + char scratch[hasatleast PATH_MAX]) { + char *p; + if (namelen + 1 + 1 > PATH_MAX) return NULL; + p = mempcpy(scratch, name, namelen); + *p++ = '='; + *p++ = '\0'; + if (IsWindows() || IsXnu()) strntolower(scratch, namelen); + return &scratch[0]; +} + +static const char *cachecmd(const char *name, size_t namelen, + const char *pathname, size_t pathnamelen) { + size_t entrylen; + char *res, *entry; + if ((entry = malloc((entrylen = namelen + 1 + pathnamelen) + 1))) { + mkcmdquery(name, namelen, entry); + res = memcpy(&entry[namelen + 1], pathname, pathnamelen + 1); + critbit0_emplace(&g_commandv, entry, entrylen); + } else { + res = NULL; + } + return res; +} + +static const char *getcmdcache(const char *name, size_t namelen, + char scratch[hasatleast PATH_MAX]) { + const char *entry; + if ((entry = critbit0_get(&g_commandv, mkcmdquery(name, namelen, scratch)))) { + return &entry[namelen + 1]; + } + return NULL; +} + +noinline static const char *findcmdpath(const char *name, + char pathname[hasatleast PATH_MAX]) { + char *p; + int rc, olderr; + size_t len; + olderr = errno; + if (!(len = strlen(name))) return PROGN(enoent(), NULL); + if (memchr(name, '=', len)) return PROGN(einval(), NULL); + if ((p = getcmdcache(name, len, pathname)) || + (((IsWindows() && + ((rc = accesscmd(pathname, kNtSystemDirectory, name, len)) != -1 || + (rc = accesscmd(pathname, kNtWindowsDirectory, name, len)) != -1)) || + (rc = accesscmd(pathname, "", name, len)) != -1 || + (!strpbrk(name, "/\\") && + (rc = searchcmdpath(pathname, name, len)) != -1)) && + (p = cachecmd(name, len, pathname, rc)))) { + errno = olderr; + return p; + } else { + return NULL; + } +} + +/** + * Resolves pathname of executable. + * + * This does the same thing as `command -v` in bourne shell. Path + * lookups are cached for the lifetime of the process. Paths with + * multiple components will skip the resolution process. Undotted + * basenames get automatic .com and .exe suffix resolution on all + * platforms. Windows' system directories will always trump PATH. + * + * @return execve()'able path, or NULL w/ errno + * @errno ENOENT, EACCES, ENOMEM + * @see free(), execvpe() + */ +const char *commandv(const char *name) { + char pathname[PATH_MAX]; + return findcmdpath(name, pathname); +} diff --git a/libc/calls/hefty/dirstream.c b/libc/calls/hefty/dirstream.c new file mode 100644 index 00000000..caaed6b3 --- /dev/null +++ b/libc/calls/hefty/dirstream.c @@ -0,0 +1,190 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/progn.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/dirent.h" +#include "libc/dce.h" +#include "libc/mem/mem.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/win32finddata.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/dt.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/errfuns.h" + +struct dirstream { + int64_t tell; + int64_t fd; + union { + struct { + unsigned buf_pos; + unsigned buf_end; + char buf[BUFSIZ]; + }; + struct { + struct dirent winent; + char __d_name[PATH_MAX]; + bool isdone; + struct NtWin32FindData windata; + }; + }; +}; + +static textwindows noinline DIR *opendir$nt(const char *name) { + int len; + DIR *res; + char16_t name16[PATH_MAX]; + if ((len = mkntpath(name, name16)) == -1) return NULL; + if (len + 2 + 1 > PATH_MAX) return PROGN(enametoolong(), NULL); + if (name16[len - 1] == u'/' || name16[len - 1] == u'\\') { + name16[--len] = u'\0'; + } + name16[len++] = u'/'; + name16[len++] = u'*'; + name16[len] = u'\0'; + if (!(res = calloc(1, sizeof(DIR)))) return NULL; + if ((res->fd = FindFirstFile(name16, &res->windata)) != -1) { + return res; + } else { + winerr(); + free(res); + return NULL; + } +} + +/** + * Opens directory so readdir() and closedir() may be called. + * + * @returns newly allocated DIR object, or NULL w/ errno + * @errors ENOENT, ENOTDIR, EACCES, EMFILE, ENFILE, ENOMEM + */ +DIR *opendir(const char *name) { + if (!IsWindows() && !IsXnu()) { + int fd; + DIR *res = NULL; + if ((fd = open(name, O_RDONLY | O_DIRECTORY | O_CLOEXEC, 0)) != -1) { + if (!(res = fdopendir(fd))) close(fd); + } + return res; + } else if (IsWindows()) { + return opendir$nt(name); + } else { + enosys(); /* TODO(jart): Implement me! */ + return NULL; + } +} + +/** + * Creates directory object for file descriptor. + * + * @param fd gets owned by this function, if it succeeds + * @return new directory object, which must be freed by closedir(), + * or NULL w/ errno + * @errors ENOMEM and fd is closed + */ +DIR *fdopendir(int fd) { + if (!IsWindows() && !IsXnu()) { + DIR *dir; + if ((dir = calloc(1, sizeof(*dir)))) { + dir->fd = fd; + return dir; + } + } else { + enosys(); /* TODO(jart): Implement me! */ + } + return NULL; +} + +/** + * Reads next entry from DIR. + * + * This API doesn't define any particular ordering. + * + * @param dir is the object opendir() or fdopendir() returned + * @return next entry or NULL on end or error, which can be + * differentiated by setting errno to 0 beforehand + */ +struct dirent *readdir(DIR *dir) { + if (!IsWindows()) { + if (dir->buf_pos >= dir->buf_end) { + int rc; + if (!(rc = getdents(dir->fd, dir->buf, BUFSIZ)) || rc == -1) { + return NULL; + } + dir->buf_pos = 0; + dir->buf_end = rc; + } + /* TODO(jart): Check FreeBSD and OpenBSD again regarding this */ + char *record = dir->buf + dir->buf_pos; + char *name = record + 8 + 8 + 2; + size_t namelen = strlen(name); + unsigned char dtype = name[namelen + 1]; + memmove(name + 1, name, namelen + 1); /* shove forward one byte */ + *name = dtype; /* is dirent d_type field */ + struct dirent *ent = (void *)record; + dir->buf_pos += ent->d_reclen; + dir->tell = ent->d_off; + return ent; + } else { + if (dir->isdone) return NULL; + struct dirent *ent = &dir->winent; + memset(ent, 0, sizeof(*ent)); + ent->d_reclen = + sizeof(*ent) + + tprecode16to8(ent->d_name, PATH_MAX, dir->windata.cFileName) + 1; + dir->isdone = FindNextFile(dir->fd, &dir->windata); + return ent; + } +} + +/** + * Closes directory object returned by opendir(). + * @return 0 on success or -1 w/ errno + */ +int closedir(DIR *dir) { + int rc; + if (dir) { + if (!IsWindows()) { + rc = close(dir->fd); + } else { + rc = FindClose(dir->fd) ? 0 : winerr(); + } + free(dir); + } else { + rc = 0; + } + return rc; +} + +/** + * Returns current byte offset into directory data. + */ +long telldir(DIR *dir) { + return dir->tell; +} + +/** + * Returns file descriptor associated with DIR object. + */ +int dirfd(DIR *dir) { + return dir->fd; +} diff --git a/libc/calls/hefty/execl.c b/libc/calls/hefty/execl.c new file mode 100644 index 00000000..a01b94ef --- /dev/null +++ b/libc/calls/hefty/execl.c @@ -0,0 +1,47 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/calls/hefty/mkvarargv.h" +#include "libc/calls/calls.h" + +/** + * Executes program, with current environment. + * + * The current process is replaced with the executed one. + * + * @param prog will not be PATH searched, see execlp() + * @param arg[0] is the name of the program to run + * @param arg[1,n-2] optionally specify program arguments + * @param arg[n-1] is NULL + * @return doesn't return on success, otherwise -1 w/ errno + * @notasyncsignalsafe (TODO) + */ +int execl(const char *exe, const char *arg, ... /*, NULL*/) { + va_list va; + void *argv; + va_start(va, arg); + if ((argv = mkvarargv(arg, va))) { + execve(exe, argv, environ); + free(argv); + } + va_end(va); + return -1; +} diff --git a/libc/calls/hefty/execle.c b/libc/calls/hefty/execle.c new file mode 100644 index 00000000..71695b58 --- /dev/null +++ b/libc/calls/hefty/execle.c @@ -0,0 +1,48 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/mem/mem.h" +#include "libc/calls/hefty/mkvarargv.h" +#include "libc/calls/calls.h" + +/** + * Executes program, with custom environment. + * + * The current process is replaced with the executed one. + * + * @param prog will not be PATH searched, see commandv() + * @param arg[0] is the name of the program to run + * @param arg[1,n-3] optionally specify program arguments + * @param arg[n-2] is NULL + * @param arg[n-1] is a pointer to a ["key=val",...,NULL] array + * @return doesn't return on success, otherwise -1 w/ errno + * @notasyncsignalsafe (TODO) + */ +int execle(const char *exe, const char *arg, + ... /*, NULL, char *const envp[] */) { + va_list va; + void *argv; + va_start(va, arg); + if ((argv = mkvarargv(arg, va))) { + execve(exe, argv, va_arg(va, char *const *)); + free(argv); + } + va_end(va); + return -1; +} diff --git a/libc/calls/hefty/execlp.c b/libc/calls/hefty/execlp.c new file mode 100644 index 00000000..86174a49 --- /dev/null +++ b/libc/calls/hefty/execlp.c @@ -0,0 +1,50 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/calls/hefty/mkvarargv.h" +#include "libc/calls/calls.h" + +/** + * Executes program, with PATH search and current environment. + * + * The current process is replaced with the executed one. + * + * @param prog is program to launch (may be PATH searched) + * @param arg[0] is the name of the program to run + * @param arg[1,n-2] optionally specify program arguments + * @param arg[n-1] is NULL + * @return doesn't return on success, otherwise -1 w/ errno + * @notasyncsignalsafe + */ +int execlp(const char *prog, const char *arg, ... /*, NULL*/) { + char *exe; + if ((exe = commandv(prog))) { + va_list va; + void *argv; + va_start(va, arg); + if ((argv = mkvarargv(arg, va))) { + execve(exe, argv, environ); + free(argv); + } + va_end(va); + } + return -1; +} diff --git a/libc/calls/hefty/execv.c b/libc/calls/hefty/execv.c new file mode 100644 index 00000000..aca6ce03 --- /dev/null +++ b/libc/calls/hefty/execv.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/runtime.h" +#include "libc/calls/calls.h" + +/** + * Replaces process with specific program, using default environment. + * @asyncsignalsafe + */ +int execv(const char *exe, char *const argv[]) { + return execve(exe, argv, environ); +} diff --git a/libc/calls/hefty/execve-nt.c b/libc/calls/hefty/execve-nt.c new file mode 100644 index 00000000..b957c561 --- /dev/null +++ b/libc/calls/hefty/execve-nt.c @@ -0,0 +1,55 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/hefty/internal.h" +#include "libc/calls/hefty/ntspawn.h" +#include "libc/calls/internal.h" +#include "libc/nt/enum/startf.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/startupinfo.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/sock.h" + +static textwindows int64_t passstdhand$nt(int fd) { + if (g_fds.p[fd].kind != kFdEmpty && + !(g_fds.p[fd].flags & + (g_fds.p[fd].kind == kFdSocket ? SOCK_CLOEXEC : O_CLOEXEC))) { + return g_fds.p[fd].handle; + } else { + return -1; + } +} + +textwindows int execve$nt(const char *program, char *const argv[], + char *const envp[]) { + struct NtStartupInfo startinfo; + memset(&startinfo, 0, sizeof(startinfo)); + startinfo.cb = sizeof(struct NtStartupInfo); + startinfo.dwFlags = kNtStartfUsestdhandles; + startinfo.hStdInput = passstdhand$nt(STDIN_FILENO); + startinfo.hStdOutput = passstdhand$nt(STDOUT_FILENO); + startinfo.hStdError = passstdhand$nt(STDERR_FILENO); + if (ntspawn(program, argv, envp, NULL, NULL, true, 0, NULL, &startinfo, + NULL) != -1) { + for (;;) TerminateProcess(GetCurrentProcess(), 0); + } + return -1; +} diff --git a/libc/calls/hefty/execve.c b/libc/calls/hefty/execve.c new file mode 100644 index 00000000..dbeaf50f --- /dev/null +++ b/libc/calls/hefty/execve.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/hefty/internal.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" + +/** + * Replaces current process with program. + * + * @param program will not be PATH searched, see commandv() + * @param argv[0] is the name of the program to run + * @param argv[1,n-2] optionally specify program arguments + * @param argv[n-1] is NULL + * @param envp[0,n-2] specifies "foo=bar" environment variables + * @param envp[n-1] is NULL + * @return doesn't return, or -1 w/ errno + * @asyncsignalsafe + */ +int execve(const char *program, char *const argv[], char *const envp[]) { + if (!IsWindows()) { + return execve$sysv(program, argv, envp); + } else { + return execve$nt(program, argv, envp); + } +} diff --git a/libc/calls/hefty/execvp.c b/libc/calls/hefty/execvp.c new file mode 100644 index 00000000..1eb30c48 --- /dev/null +++ b/libc/calls/hefty/execvp.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/runtime.h" +#include "libc/calls/calls.h" + +/** + * Replaces process, with path search, using default environment. + * @notasyncsignalsafe + */ +int execvp(const char *file, char *const argv[]) { + return execvpe(file, argv, environ); +} diff --git a/libc/calls/hefty/execvpe.c b/libc/calls/hefty/execvpe.c new file mode 100644 index 00000000..6ae780d4 --- /dev/null +++ b/libc/calls/hefty/execvpe.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/mem/mem.h" +#include "libc/calls/calls.h" + +/** + * Executes program, with path environment search. + * + * The current process is replaced with the executed one. + * + * @param prog is the program to launch + * @param argv is [file,argv₁..argvₙ₋₁,NULL] + * @param envp is ["key=val",...,NULL] + * @return doesn't return on success, otherwise -1 w/ errno + * @notasyncsignalsafe + */ +int execvpe(const char *prog, char *const argv[], char *const *envp) { + char *exe; + if ((exe = commandv(prog))) { + execve(exe, argv, envp); + } + return -1; +} diff --git a/libc/calls/hefty/faccessat.c b/libc/calls/hefty/faccessat.c new file mode 100644 index 00000000..bd8302ac --- /dev/null +++ b/libc/calls/hefty/faccessat.c @@ -0,0 +1,44 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sysv/consts/at.h" +#include "libc/sysv/errfuns.h" + +/** + * Checks if effective user can access path in particular ways. + * + * @param dirfd is usually AT_FDCWD + * @param path is a filename or directory + * @param flags can be R_OK, W_OK, X_OK, F_OK + * @return 0 if ok, or -1 and sets errno + * @asyncsignalsafe + */ +int faccessat(int dirfd, const char *path, int mode, uint32_t flags) { + if (!IsWindows()) { + return faccessat$sysv(dirfd, path, mode, flags); + } else { + char16_t path16[PATH_MAX]; + if (dirfd != AT_FDCWD || flags) return einval(); + if (mkntpath(path, path16) == -1) return -1; + return ntaccesscheck(path16, mode); + } +} diff --git a/libc/calls/hefty/filecmp.c b/libc/calls/hefty/filecmp.c new file mode 100644 index 00000000..a9282d99 --- /dev/null +++ b/libc/calls/hefty/filecmp.c @@ -0,0 +1,78 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/errno.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/madv.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/prot.h" + +static void *filecmp$mmap(int fd, size_t size) { + return size ? mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0) : NULL; +} + +/** + * Compares contents of files with memcmp(). + * + * @return ≤0, 0, or ≥0 based on comparison; or ≠0 on error, in which + * case we make our best effort to sift failing filenames rightward, + * and errno can be set to 0 beforehand to differentiate errors + */ +int filecmp(const char *pathname1, const char *pathname2) { + int res, olderr; + int fd1 = -1; + int fd2 = -1; + char *addr1 = MAP_FAILED; + char *addr2 = MAP_FAILED; + size_t size1 = 0; + size_t size2 = 0; + if ((fd1 = open(pathname1, O_RDONLY)) != -1 && + (fd2 = open(pathname2, O_RDONLY)) != -1 && + (size1 = getfiledescriptorsize(fd1)) != -1 && + (size2 = getfiledescriptorsize(fd2)) != -1 && + (addr1 = filecmp$mmap(fd1, size1)) != MAP_FAILED && + (addr2 = filecmp$mmap(fd2, size2)) != MAP_FAILED) { + olderr = errno; + madvise(addr1, size1, MADV_WILLNEED | MADV_SEQUENTIAL); + madvise(addr2, size2, MADV_WILLNEED | MADV_SEQUENTIAL); + errno = olderr; + res = memcmp(addr1, addr2, min(size1, size2)); + if (!res && size1 != size2) { + char kNul = '\0'; + if (size1 > size2) { + res = cmpub(addr1 + size2, &kNul); + } else { + res = cmpub(addr2 + size1, &kNul); + } + } + } else { + res = cmpuq(&fd1, &fd2) | 1; + } + olderr = errno; + munmap(addr1, size1); + munmap(addr2, size2); + close(fd1); + close(fd2); + errno = olderr; + return res; +} diff --git a/libc/calls/hefty/get_current_dir_name.c b/libc/calls/hefty/get_current_dir_name.c new file mode 100644 index 00000000..b1eb3d67 --- /dev/null +++ b/libc/calls/hefty/get_current_dir_name.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/calls/calls.h" +#include "libc/sysv/errfuns.h" + +/** + * Returns current working directory. + * + * If the PWD environment variable is set, that'll be returned (since + * it's faster than issuing a system call). + * + * @return pointer that must be free()'d, or NULL w/ errno + */ +nodiscard char *get_current_dir_name(void) { + char *buf, *res; + if ((res = getenv("PWD"))) return strdup(res); + if (!(buf = malloc(PATH_MAX))) return NULL; + if (!(res = (getcwd)(buf, PATH_MAX))) free(buf); + return res; +} diff --git a/libc/calls/hefty/hefty.mk b/libc/calls/hefty/hefty.mk new file mode 100644 index 00000000..5d9ef1b7 --- /dev/null +++ b/libc/calls/hefty/hefty.mk @@ -0,0 +1,73 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ +# +# SYNOPSIS +# +# Cosmopolitan System Call Compatibility Layer +# +# DESCRIPTION +# +# This subpackage exports functions traditionally understood as system +# calls that Cosmopolitan needs to wrap in a nontrivial way, requiring +# things like dynamic memory allocation. + +PKGS += LIBC_CALLS_HEFTY + +LIBC_CALLS_HEFTY_ARTIFACTS += LIBC_CALLS_HEFTY_A +LIBC_CALLS_HEFTY = $(LIBC_CALLS_HEFTY_A_DEPS) $(LIBC_CALLS_HEFTY_A) +LIBC_CALLS_HEFTY_A = o/$(MODE)/libc/calls/hefty/hefty.a +LIBC_CALLS_HEFTY_A_FILES := $(wildcard libc/calls/hefty/*) +LIBC_CALLS_HEFTY_A_HDRS = $(filter %.h,$(LIBC_CALLS_HEFTY_A_FILES)) +LIBC_CALLS_HEFTY_A_SRCS_S = $(filter %.S,$(LIBC_CALLS_HEFTY_A_FILES)) +LIBC_CALLS_HEFTY_A_SRCS_C = $(filter %.c,$(LIBC_CALLS_HEFTY_A_FILES)) + +LIBC_CALLS_HEFTY_A_SRCS = \ + $(LIBC_CALLS_HEFTY_A_SRCS_S) \ + $(LIBC_CALLS_HEFTY_A_SRCS_C) + +LIBC_CALLS_HEFTY_A_OBJS = \ + $(LIBC_CALLS_HEFTY_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_CALLS_HEFTY_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_CALLS_HEFTY_A_SRCS_C:%.c=o/$(MODE)/%.o) + +LIBC_CALLS_HEFTY_A_CHECKS = \ + $(LIBC_CALLS_HEFTY_A).pkg \ + $(LIBC_CALLS_HEFTY_A_HDRS:%=o/$(MODE)/%.ok) + +LIBC_CALLS_HEFTY_A_DIRECTDEPS = \ + LIBC_ALG \ + LIBC_CONV \ + LIBC_FMT \ + LIBC_MEM \ + LIBC_STR \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_CALLS \ + LIBC_STUBS \ + LIBC_NT_KERNELBASE \ + LIBC_SYSV_CALLS \ + LIBC_SYSV + +LIBC_CALLS_HEFTY_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_CALLS_HEFTY_A_DIRECTDEPS),$($(x)))) + +$(LIBC_CALLS_HEFTY_A): \ + libc/calls/hefty/ \ + $(LIBC_CALLS_HEFTY_A).pkg \ + $(LIBC_CALLS_HEFTY_A_OBJS) + +$(LIBC_CALLS_HEFTY_A).pkg: \ + $(LIBC_CALLS_HEFTY_A_OBJS) \ + $(foreach x,$(LIBC_CALLS_HEFTY_A_DIRECTDEPS),$($(x)_A).pkg) + +LIBC_CALLS_HEFTY_LIBS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x))) +LIBC_CALLS_HEFTY_SRCS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_SRCS)) +LIBC_CALLS_HEFTY_HDRS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_HDRS)) +LIBC_CALLS_HEFTY_BINS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_BINS)) +LIBC_CALLS_HEFTY_CHECKS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_CHECKS)) +LIBC_CALLS_HEFTY_OBJS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_OBJS)) +LIBC_CALLS_HEFTY_TESTS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_TESTS)) +$(LIBC_CALLS_HEFTY_OBJS): $(BUILD_FILES) libc/calls/hefty/hefty.mk + +.PHONY: o/$(MODE)/libc/calls/hefty +o/$(MODE)/libc/calls/hefty: $(LIBC_CALLS_HEFTY_CHECKS) diff --git a/libc/calls/hefty/internal.h b/libc/calls/hefty/internal.h new file mode 100644 index 00000000..b56dd330 --- /dev/null +++ b/libc/calls/hefty/internal.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_HEFTY_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_CALLS_HEFTY_INTERNAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +int execve$nt(const char *, char *const[], char *const[]) hidden; +int spawnve$nt(unsigned, int[3], const char *, char *const[], + char *const[]) hidden; +int spawnve$sysv(unsigned, int[3], const char *, char *const[], + char *const[]) hidden; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_HEFTY_INTERNAL_H_ */ diff --git a/libc/calls/hefty/mkntcmdline.c b/libc/calls/hefty/mkntcmdline.c new file mode 100644 index 00000000..335aef3a --- /dev/null +++ b/libc/calls/hefty/mkntcmdline.c @@ -0,0 +1,98 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/arraylist2.h" +#include "libc/calls/calls.h" +#include "libc/calls/hefty/ntspawn.h" +#include "libc/conv/conv.h" +#include "libc/macros.h" +#include "libc/mem/mem.h" +#include "libc/nexgen32e/hascharacter.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/errfuns.h" + +#define APPENDCHAR(C) \ + do { \ + if (mkntcmdline_append(&cmdline_p, &cmdline_i, &cmdline_n, C) == -1) { \ + goto error; \ + } \ + } while (0) + +static int mkntcmdline_append(char16_t **p, size_t *i, size_t *n, char16_t c) { + return APPEND(p, i, n, &c); +} + +/** + * Converts System V argv to Windows-style command line. + * + * Escaping is performed and it's designed to round-trip with + * getdosargv() or getdosargv(). This function does NOT escape + * command interpreter syntax, e.g. $VAR (sh), %VAR% (cmd). + * + * @param argv is an a NULL-terminated array of UTF-8 strings + * @return freshly allocated lpCommandLine or NULL w/ errno + * @kudos Daniel Colascione for teaching how to quote + * @see libc/runtime/dosargv.c + */ +hidden textwindows nodiscard char16_t *mkntcmdline(char *const argv[]) { + wint_t wc; + size_t i, j; + char16_t cbuf[2]; + char16_t *cmdline_p = NULL; + size_t cmdline_i = 0; + size_t cmdline_n = 0; + if (argv[0]) { + for (i = 0; argv[i]; ++i) { + if (i) APPENDCHAR(u' '); + bool needsquote = !argv[i] || !!argv[i][strcspn(argv[i], " \t\n\v\"")]; + if (needsquote) APPENDCHAR(u'"'); + for (j = 0;;) { + if (needsquote) { + int slashes = 0; + while (argv[i][j] && argv[i][j] == u'\\') slashes++, j++; + slashes <<= 1; + if (argv[i][j] == u'"') slashes++; + while (slashes--) APPENDCHAR(u'\\'); + } + if (!argv[i][j]) break; + j += abs(tpdecode(&argv[i][j], &wc)); + if (CONCAT(&cmdline_p, &cmdline_i, &cmdline_n, cbuf, + abs(pututf16(cbuf, ARRAYLEN(cbuf), wc, false))) == -1) { + goto error; + } + } + if (needsquote) APPENDCHAR(u'"'); + } + APPENDCHAR(u'\0'); + if (cmdline_i > CMD_MAX) { + e2big(); + goto error; + } + } else { + einval(); + } + return cmdline_p; +error: + free(cmdline_p); + return NULL; +} + +#undef APPENDCHAR diff --git a/libc/calls/hefty/mkntenvblock.c b/libc/calls/hefty/mkntenvblock.c new file mode 100644 index 00000000..6e061806 --- /dev/null +++ b/libc/calls/hefty/mkntenvblock.c @@ -0,0 +1,69 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/arraylist2.h" +#include "libc/calls/hefty/ntspawn.h" +#include "libc/conv/conv.h" +#include "libc/macros.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +/** + * Copies sorted environment variable block for Windows. + * + * This is designed to meet the requirements of CreateProcess(). + * + * @param envp is an a NULL-terminated array of UTF-8 strings + * @return freshly allocated lpEnvironment or NULL w/ errno + */ +textwindows char16_t *mkntenvblock(char *const envp[]) { + size_t block_i = 0; + size_t block_n = 0; + char16_t *block_p = NULL; + size_t i, j; + if (!(envp = sortenvp(envp))) goto error; + const char16_t kNul = u'\0'; + for (i = 0; envp[i]; ++i) { + unsigned consumed; + for (j = 0;; j += consumed) { + wint_t wc; + char16_t cbuf[2]; + consumed = abs(tpdecode(&envp[i][j], &wc)); + if (CONCAT(&block_p, &block_i, &block_n, cbuf, + abs(pututf16(cbuf, ARRAYLEN(cbuf), wc, false))) == -1) { + goto error; + } + if (!wc) break; + } + } + if (APPEND(&block_p, &block_i, &block_n, &kNul) == -1) { + goto error; + } + if (block_i > ENV_MAX) { + e2big(); + goto error; + } + free(envp); + return block_p; +error: + free(envp); + free(block_p); + return NULL; +} diff --git a/libc/calls/hefty/mkvarargv.h b/libc/calls/hefty/mkvarargv.h new file mode 100644 index 00000000..ede3484d --- /dev/null +++ b/libc/calls/hefty/mkvarargv.h @@ -0,0 +1,32 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_HEFTY_MKVARARGV_H_ +#define COSMOPOLITAN_LIBC_CALLS_HEFTY_MKVARARGV_H_ +#include "libc/alg/arraylist2.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * Turns variadic program arguments into array. + * + * This is a support function for execl(), execlp(), spawnl(), etc. + * + * @note type signatures are fubar for these functions + */ +forceinline void *mkvarargv(const char *arg1, va_list va) { + size_t i, n; + const char **p, *arg; + i = 0; + n = 0; + p = NULL; + arg = arg1; + do { + if (APPEND(&p, &i, &n, &arg) == -1) { + free(p); + return NULL; + } + } while ((arg = va_arg(va, const char *))); + return p; +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_HEFTY_MKVARARGV_H_ */ diff --git a/libc/calls/hefty/ntaccesscheck.c b/libc/calls/hefty/ntaccesscheck.c new file mode 100644 index 00000000..f517feb0 --- /dev/null +++ b/libc/calls/hefty/ntaccesscheck.c @@ -0,0 +1,87 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/mem/mem.h" +#include "libc/nt/enum/accessmask.h" +#include "libc/nt/enum/securityinformation.h" +#include "libc/nt/errors.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/genericmapping.h" +#include "libc/nt/struct/privilegeset.h" +#include "libc/nt/struct/securitydescriptor.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/calls/internal.h" +#include "libc/calls/calls.h" +#include "libc/sysv/consts/ok.h" + +/** + * Checks if current process has access to folder or file. + * + * @param flags can have R_OK, W_OK, X_OK, etc. + * @return 0 if authorized, or -1 w/ errno + * @kudos Aaron Ballman for teaching how to do this + * @see libc/sysv/consts.sh + */ +textwindows int ntaccesscheck(const char16_t *pathname, uint32_t flags) { + int rc; + bool32 result; + int64_t hToken, hImpersonatedToken; + uint32_t secsize, granted, privsize; + struct NtPrivilegeSet privileges; + struct NtGenericMapping mapping; + struct NtSecurityDescriptor security; + struct NtSecurityDescriptor *psecurity; + const uint32_t request = kNtOwnerSecurityInformation | + kNtGroupSecurityInformation | + kNtDaclSecurityInformation; + granted = 0; + result = false; + psecurity = &security; + secsize = sizeof(security); + privsize = sizeof(privileges); + memset(&privileges, 0, sizeof(privileges)); + mapping.GenericRead = kNtFileGenericRead; + mapping.GenericWrite = kNtFileGenericWrite; + mapping.GenericExecute = kNtFileGenericExecute; + mapping.GenericAll = kNtFileAllAccess; + MapGenericMask(&flags, &mapping); + hImpersonatedToken = hToken = -1; + if ((GetFileSecurity(pathname, request, psecurity, 0, &secsize) || + (GetLastError() == kNtErrorInsufficientBuffer && + (psecurity = malloc(secsize)) && + GetFileSecurity(pathname, request, psecurity, secsize, &secsize))) && + OpenProcessToken(GetCurrentProcess(), + kNtTokenImpersonate | kNtTokenQuery | kNtTokenDuplicate | + kNtStandardRightsRead, + &hToken) && + DuplicateToken(hToken, kNtSecurityImpersonation, &hImpersonatedToken) && + AccessCheck(psecurity, hImpersonatedToken, flags, &mapping, &privileges, + &privsize, &granted, &result) && + (result || flags == F_OK)) { + rc = 0; + } else { + rc = winerr(); + } + free_s(&psecurity); + close(hImpersonatedToken); + close(hToken); + return rc; +} diff --git a/libc/calls/hefty/ntspawn.c b/libc/calls/hefty/ntspawn.c new file mode 100644 index 00000000..1d2fc456 --- /dev/null +++ b/libc/calls/hefty/ntspawn.c @@ -0,0 +1,88 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/alg/arraylist.h" +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/calls/hefty/ntspawn.h" +#include "libc/calls/internal.h" +#include "libc/conv/conv.h" +#include "libc/nt/process.h" +#include "libc/nt/runtime.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/errfuns.h" + +/** + * Spawns process on Windows NT. + * + * This function delegates to CreateProcess() with UTF-8 → UTF-16 + * translation and argv escaping. Please note this will NOT escape + * command interpreter syntax. + * + * @param program will not be PATH searched, see commandv() + * @param argv[0] is the name of the program to run + * @param argv[1,n-2] optionally specifies program arguments + * @param argv[n-1] is NULL + * @param envp[𝟶,m-2] specifies "foo=bar" environment variables, which + * don't need to be passed in sorted order; however, this function + * goes faster the closer they are to sorted + * @param envp[m-1] is NULL + * @param bInheritHandles means handles already marked inheritable will + * be inherited; which, assuming the System V wrapper functions are + * being used, should mean (1) all files and sockets that weren't + * opened with O_CLOEXEC; and (2) all memory mappings + * @param opt_out_lpProcessInformation can be used to return process and + * thread IDs to parent, as well as open handles that need close() + * @return 0 on success, or -1 w/ errno + * @see spawnve() which abstracts this function + */ +textwindows int ntspawn( + const char *program, char *const argv[], char *const envp[], + struct NtSecurityAttributes *opt_lpProcessAttributes, + struct NtSecurityAttributes *opt_lpThreadAttributes, bool32 bInheritHandles, + uint32_t dwCreationFlags, const char16_t *opt_lpCurrentDirectory, + /*nodiscard*/ const struct NtStartupInfo *lpStartupInfo, + struct NtProcessInformation *opt_out_lpProcessInformation) { + int rc; + char16_t program16[PATH_MAX], *lpCommandLine, *lpEnvironment; + lpCommandLine = NULL; + lpEnvironment = NULL; + if (mkntpath(program, program16) != -1 && + (lpCommandLine = mkntcmdline(argv)) && + (lpEnvironment = mkntenvblock(envp))) { + if (CreateProcess(program16, lpCommandLine, opt_lpProcessAttributes, + opt_lpThreadAttributes, bInheritHandles, + dwCreationFlags | kNtCreateUnicodeEnvironment, + lpEnvironment, opt_lpCurrentDirectory, lpStartupInfo, + opt_out_lpProcessInformation)) { + rc = 0; + } else { + rc = winerr(); + } + } else { + rc = -1; + } + free(lpCommandLine); + free(lpEnvironment); + return rc; +} diff --git a/libc/calls/hefty/ntspawn.h b/libc/calls/hefty/ntspawn.h new file mode 100644 index 00000000..519f638a --- /dev/null +++ b/libc/calls/hefty/ntspawn.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_HEFTY_NTSPAWN_H_ +#define COSMOPOLITAN_LIBC_CALLS_HEFTY_NTSPAWN_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtProcessInformation; +struct NtSecurityAttributes; +struct NtStartupInfo; + +char **sortenvp(char *const[]) hidden nodiscard paramsnonnull(); +char16_t *mkntcmdline(char *const[]) hidden nodiscard paramsnonnull(); +char16_t *mkntenvblock(char *const[]) hidden nodiscard paramsnonnull(); +int ntspawn(const char *, char *const[], char *const[], + struct NtSecurityAttributes *, struct NtSecurityAttributes *, + bool32, uint32_t, const char16_t *, const struct NtStartupInfo *, + struct NtProcessInformation *) paramsnonnull((1, 2, 3, 9)) hidden; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_HEFTY_NTSPAWN_H_ */ diff --git a/libc/calls/hefty/replaceuser.c b/libc/calls/hefty/replaceuser.c new file mode 100644 index 00000000..97fef978 --- /dev/null +++ b/libc/calls/hefty/replaceuser.c @@ -0,0 +1,49 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/calls/calls.h" + +/** + * Replaces tilde in path w/ user home folder. + * + * @param path is NULL propagating + * @return must be free()'d + */ +char *replaceuser(const char *path) { + char *res, *p; + const char *home; + size_t pathlen, homelen; + res = NULL; + if (path && *path++ == '~' && !isempty((home = getenv("HOME")))) { + while (*path == '/') path++; + pathlen = strlen(path); + homelen = strlen(home); + while (homelen && home[homelen - 1] == '/') homelen--; + if ((p = res = malloc(pathlen + 1 + homelen + 1))) { + p = mempcpy(p, home, homelen); + *p++ = '/'; + memcpy(p, path, pathlen + 1); + } + } + return res; +} diff --git a/libc/calls/hefty/slurp.c b/libc/calls/hefty/slurp.c new file mode 100644 index 00000000..d8e7454f --- /dev/null +++ b/libc/calls/hefty/slurp.c @@ -0,0 +1,89 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/arraylist2.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/calls/struct/stat.h" +#include "libc/errno.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/madv.h" +#include "libc/sysv/consts/o.h" + +static size_t getfilesize(int fd) { + struct stat st; + st.st_size = 0; + fstat(fd, &st); + return st.st_size; +} + +static size_t smudgefilesize(size_t size) { + return roundup(size, PAGESIZE) + PAGESIZE; +} + +/** + * Reads entire file into memory. + * + * This function is fantastic for being lazy. It may waste space if the + * file is large, but it's implemented in a conscientious way that won't + * bomb the systemwide page cache. It means performance too, naturally. + * + * @return contents which must be free()'d or NULL w/ errno + */ +char *slurp(const char *path, size_t *opt_out_readlength) { + int fd; + ssize_t rc; + char *res, *p; + size_t i, n, got, want; + res = NULL; + if ((fd = open(path, O_RDONLY)) == -1) goto Failure; + n = getfilesize(fd); + /* TODO(jart): Fix this, it's totally broken */ + if (!(res = valloc(smudgefilesize(n)))) goto Failure; + if (n > FRAMESIZE) fadvise(fd, 0, n, MADV_SEQUENTIAL); + i = 0; + for (;;) { + want = smudgefilesize(n - i); + TryAgain: + if ((rc = read(fd, &res[i], want)) == -1) { + if (errno == EINTR) goto TryAgain; + goto Failure; + } + got = (size_t)rc; + if (i + 1 >= n) { + if ((p = realloc(res, smudgefilesize((n += n >> 1))))) { + res = p; + } else { + goto Failure; + } + } + i += got; + if (got == 0) break; + if (got > want) abort(); + } + if (opt_out_readlength) *opt_out_readlength = i; + res[i] = '\0'; + close(fd); + return res; +Failure: + free(res); + close(fd); + return NULL; +} diff --git a/libc/calls/hefty/sortenvp.c b/libc/calls/hefty/sortenvp.c new file mode 100644 index 00000000..e20acc8b --- /dev/null +++ b/libc/calls/hefty/sortenvp.c @@ -0,0 +1,68 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/alg/arraylist.h" +#include "libc/calls/hefty/ntspawn.h" +#include "libc/dce.h" +#include "libc/nexgen32e/tinystrcmp.h" +#include "libc/str/str.h" + +static int sortenvpcb(const char **a, const char **b) { return strcmp(*a, *b); } + +static void slowsort(char **a, int n) { + size_t i, j; + const char *t; + for (i = 1; i < n; ++i) { + j = i; + t = a[i]; + while (j > 0 && tinystrcmp(t, a[j - 1]) < 0) { + a[j] = a[j - 1]; + --j; + } + a[j] = t; + } +} + +/** + * Copies environment variable pointers and sorts them. + * + * This is useful for (a) binary searching; and (b) keeping the NT + * Executive happy, which wants strings to be ordered by UNICODE + * codepoint identifiers. That's basically what uint8_t comparisons on + * UTF8-encoded data gives us. + * + * @param envp is a NULL-terminated string array + * @return newly allocated sorted copy of envp pointer array + */ +hidden textwindows nodiscard char **sortenvp(char *const envp[]) { + size_t count = 0; + while (envp[count]) count++; + size_t bytesize = (count + 1) * sizeof(char *); + char **copy = malloc(bytesize); + if (copy) { + memcpy(copy, envp, bytesize); + if (IsTiny()) { + slowsort(copy, count); + } else { + qsort(copy, count, sizeof(char *), (void *)sortenvpcb); + } + } + return copy; +} diff --git a/libc/calls/hefty/spawn.h b/libc/calls/hefty/spawn.h new file mode 100644 index 00000000..da6f460d --- /dev/null +++ b/libc/calls/hefty/spawn.h @@ -0,0 +1,26 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_HEFTY_SPAWN_H_ +#define COSMOPOLITAN_LIBC_CALLS_HEFTY_SPAWN_H_ + +#define SPAWN_DETACH 1 +#define SPAWN_TABULARASA 2 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +int spawnve(unsigned, int[3], const char *, char *const[], char *const[]) + paramsnonnull((3, 4, 5)); +int spawnl(unsigned, int[3], const char *, const char *, ...) nullterminated() + paramsnonnull((3, 4)); +int spawnlp(unsigned, int[3], const char *, const char *, ...) nullterminated() + paramsnonnull((3, 4)); +int spawnle(unsigned, int[3], const char *, const char *, ...) + nullterminated((1)) paramsnonnull((3, 4)); +int spawnv(unsigned, int[3], const char *, char *const[]) paramsnonnull((3, 4)); +int spawnvp(unsigned, int[3], const char *, char *const[]) + paramsnonnull((3, 4)); +int spawnvpe(unsigned, int[3], const char *, char *const[], char *const[]) + paramsnonnull((3, 4, 5)); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_HEFTY_SPAWN_H_ */ diff --git a/libc/calls/hefty/spawnl.c b/libc/calls/hefty/spawnl.c new file mode 100644 index 00000000..0241cd78 --- /dev/null +++ b/libc/calls/hefty/spawnl.c @@ -0,0 +1,49 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/hefty/mkvarargv.h" +#include "libc/calls/hefty/spawn.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" + +/** + * Launches program, with current environment. + * + * @param stdiofds may optionally be passed to customize standard i/o + * @param stdiofds[𝑖] may be -1 to receive a pipe() fd + * @param prog is program to launch (may be PATH searched) + * @param arg[0] is the name of the program to run + * @param arg[1,n-2] optionally specify program arguments + * @param arg[n-1] is NULL + * @return pid of child, or -1 w/ errno + */ +int spawnl(unsigned flags, int stdiofds[3], const char *exe, const char *arg, + ... /*, NULL*/) { + int rc; + va_list va; + void *argv; + rc = -1; + va_start(va, arg); + if ((argv = mkvarargv(arg, va))) { + rc = spawnve(flags, stdiofds, exe, argv, environ); + free(argv); + } + va_end(va); + return rc; +} diff --git a/libc/calls/hefty/spawnlp.c b/libc/calls/hefty/spawnlp.c new file mode 100644 index 00000000..d6f58f6a --- /dev/null +++ b/libc/calls/hefty/spawnlp.c @@ -0,0 +1,53 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/hefty/mkvarargv.h" +#include "libc/calls/hefty/spawn.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" + +/** + * Launches program, with PATH search and current environment. + * + * @param stdiofds may optionally be passed to customize standard i/o + * @param stdiofds[𝑖] may be -1 to receive a pipe() fd + * @param prog is program to launch (may be PATH searched) + * @param arg[0] is the name of the program to run + * @param arg[1,n-2] optionally specify program arguments + * @param arg[n-1] is NULL + * @return pid of child, or -1 w/ errno + */ +nodiscard int spawnlp(unsigned flags, int stdiofds[3], const char *prog, + const char *arg, ... /*, NULL*/) { + int pid; + char *exe; + va_list va; + void *argv; + pid = -1; + if ((exe = commandv(prog))) { + va_start(va, arg); + if ((argv = mkvarargv(arg, va))) { + pid = spawnve(flags, stdiofds, exe, argv, environ); + free(argv); + } + va_end(va); + } + return pid; +} diff --git a/libc/calls/hefty/spawnve-nt.c b/libc/calls/hefty/spawnve-nt.c new file mode 100644 index 00000000..26a500ca --- /dev/null +++ b/libc/calls/hefty/spawnve-nt.c @@ -0,0 +1,98 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/xchg.h" +#include "libc/calls/calls.h" +#include "libc/calls/hefty/internal.h" +#include "libc/calls/hefty/ntspawn.h" +#include "libc/calls/hefty/spawn.h" +#include "libc/calls/internal.h" +#include "libc/nt/enum/startf.h" +#include "libc/nt/files.h" +#include "libc/nt/ipc.h" +#include "libc/nt/process.h" +#include "libc/nt/runtime.h" +#include "libc/nt/startupinfo.h" +#include "libc/nt/struct/processinformation.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/o.h" + +textwindows int spawnve$nt(unsigned flags, int stdiofds[3], const char *program, + char *const argv[], char *const envp[]) { + int pid; + size_t i; + int tubes[3]; + int64_t handle, h, *x, *y; + struct NtStartupInfo sti; + struct NtProcessInformation procinfo; + + handle = 0; + memset(&sti, 0, sizeof(sti)); + sti.cb = sizeof(sti); + sti.dwFlags = kNtStartfUsestdhandles; + + if ((pid = createfd()) == -1) return -1; + + for (i = 0; i < 3; ++i) { + if (stdiofds[i] == -1) { + x = &h; + y = &sti.stdiofds[i]; + if (kIoMotion[i]) xchg(&x, &y); + if ((tubes[i] = createfd()) != -1 && + CreatePipe(x, y, &kNtIsInheritable, 0)) { + g_fds.p[tubes[i]].handle = h; + } else { + handle = -1; + } + } else { + sti.stdiofds[i] = g_fds.p[stdiofds[i]].handle; + } + } + + if (handle != -1 && + ntspawn(program, argv, envp, NULL, NULL, + (flags & SPAWN_TABULARASA) ? false : true, + (flags & SPAWN_DETACH) + ? (kNtCreateNewProcessGroup | kNtDetachedProcess | + kNtCreateBreakawayFromJob) + : 0, + NULL, &sti, &procinfo) != -1) { + CloseHandle(procinfo.hThread); + handle = procinfo.hProcess; + } + + for (i = 0; i < 3; ++i) { + if (stdiofds[i] == -1) { + if (handle != -1) { + stdiofds[i] = tubes[i]; + g_fds.p[tubes[i]].kind = kFdFile; + g_fds.p[tubes[i]].flags = O_CLOEXEC; + CloseHandle(sti.stdiofds[i]); + } else { + CloseHandle(tubes[i]); + } + } + } + + g_fds.p[pid].kind = kFdProcess; + g_fds.p[pid].handle = handle; + g_fds.p[pid].flags = flags; + return pid; +} diff --git a/libc/calls/hefty/spawnve-sysv.c b/libc/calls/hefty/spawnve-sysv.c new file mode 100644 index 00000000..ce273a66 --- /dev/null +++ b/libc/calls/hefty/spawnve-sysv.c @@ -0,0 +1,121 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/calls.h" +#include "libc/calls/hefty/internal.h" +#include "libc/calls/hefty/spawn.h" +#include "libc/calls/internal.h" +#include "libc/conv/conv.h" +#include "libc/dce.h" +#include "libc/mem/mem.h" +#include "libc/paths.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/at.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/o.h" + +int spawnve$sysv(unsigned flags, int stdiofds[3], const char *program, + char *const argv[], char *const envp[]) { + int rc, pid, fd; + size_t i, j, len; + int32_t tubes[3][2]; + char **argv2, MZqFpD[8]; + void *argv3; + + pid = 0; + argv2 = NULL; + argv3 = argv; + + /* + * αcτµαlly pδrταblε εxεcµταblε w/ thompson shell script + * morphology needs to be launched via command interpreter. + */ + if (endswith(program, ".com") || endswith(program, ".exe")) { + memset(MZqFpD, 0, sizeof(MZqFpD)); + fd = openat$sysv(AT_FDCWD, program, O_RDONLY, 0); + read$sysv(fd, MZqFpD, sizeof(MZqFpD)); + close$sysv(fd); + if (memcmp(MZqFpD, "MZqFpD", 6) == 0) { + /* + * If we got this: + * + * spawn(/bin/echo, [echo, hi, there]) + * + * It will become this: + * + * spawn(/bin/sh, [sh, /bin/echo, hi, there]) + */ + len = 1; + while (argv[len]) len++; + if ((argv2 = malloc((2 + len + 1) * sizeof(char *)))) { + i = 0, j = 1; + argv2[i++] = "sh"; + argv2[i++] = program; + while (j < len) argv2[i++] = argv[j++]; + argv2[i] = NULL; + argv3 = argv2; + program = "/bin/sh"; + } + } + } + + for (i = 0; i < 3; ++i) { + if (stdiofds[i] == -1) { + pid |= pipe$sysv(tubes[i]); + } + } + + if (pid != -1) { + if ((pid = fork$sysv()) == 0) { + if (flags & SPAWN_DETACH) { + if (setsid() == -1) abort(); + if ((rc = fork$sysv()) == -1) abort(); + if (rc > 0) _exit(0); + } + for (i = 0; i < 3; ++i) { + if (stdiofds[i] == -1) { + close$sysv(tubes[i][kIoMotion[i]]); + fd = tubes[i][!kIoMotion[i]]; + } else { + fd = stdiofds[i]; + } + dup2$sysv(fd, i); + } + execve$sysv(program, argv3, envp); + abort(); + } + } + + for (i = 0; i < 3; ++i) { + if (stdiofds[i] == -1) { + close$sysv(tubes[i][!kIoMotion[i]]); + fd = tubes[i][kIoMotion[i]]; + if (pid != -1) { + stdiofds[i] = fd; + } else { + close$sysv(fd); + } + } + } + + if (argv2) free(argv2); + return pid; +} diff --git a/libc/calls/hefty/spawnve.c b/libc/calls/hefty/spawnve.c new file mode 100644 index 00000000..31dff906 --- /dev/null +++ b/libc/calls/hefty/spawnve.c @@ -0,0 +1,63 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/pushpop.h" +#include "libc/calls/hefty/internal.h" +#include "libc/calls/hefty/spawn.h" +#include "libc/dce.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/errfuns.h" + +/** + * Launches program, e.g. + * + * char buf[2]; + * int ws, pid, fds[3] = {-1, -1, STDERR_FILENO}; + * CHECK_NE(-1, (pid = spawnve(0, fds, commandv("ssh"), + * (char *const[]){"ssh", hostname, "cat", NULL}, + * environ))); + * CHECK_EQ(+2, write(fds[0], "hi", 2)); + * CHECK_NE(-1, close(fds[0])); + * CHECK_EQ(+2, read(fds[1], buf, 2))); + * CHECK_NE(-1, close(fds[1])); + * CHECK_EQ(+0, memcmp(buf, "hi", 2))); + * CHECK_NE(-1, waitpid(pid, &ws, 0)); + * CHECK_EQ(+0, WEXITSTATUS(ws)); + * + * @param stdiofds may optionally be passed to customize standard i/o + * @param stdiofds[𝑖] may be -1 to receive a pipe() fd + * @param program will not be PATH searched, see commandv() + * @param argv[0] is the name of the program to run + * @param argv[1,n-2] optionally specify program arguments + * @param argv[n-1] is NULL + * @param envp[0,n-2] specifies "foo=bar" environment variables + * @param envp[n-1] is NULL + * @return pid of child, or -1 w/ errno + */ +int spawnve(unsigned flags, int stdiofds[3], const char *program, + char *const argv[], char *const envp[]) { + if (!argv[0]) return einval(); + int defaultfds[3] = {pushpop(STDIN_FILENO), pushpop(STDOUT_FILENO), + pushpop(STDERR_FILENO)}; + if (!IsWindows()) { + return spawnve$sysv(flags, stdiofds ?: defaultfds, program, argv, envp); + } else { + return spawnve$nt(flags, stdiofds ?: defaultfds, program, argv, envp); + } +} diff --git a/libc/calls/hefty/ttyname.c b/libc/calls/hefty/ttyname.c new file mode 100644 index 00000000..207e64ba --- /dev/null +++ b/libc/calls/hefty/ttyname.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/log/log.h" + +static char ttyname_buf[PATH_MAX]; + +char *ttyname(int fd) { + int rc = ttyname_r(fd, ttyname_buf, sizeof(ttyname_buf)); + if (rc != 0) return NULL; + return &ttyname_buf[0]; +} diff --git a/libc/calls/hefty/ttyname_r.c b/libc/calls/hefty/ttyname_r.c new file mode 100644 index 00000000..bb601153 --- /dev/null +++ b/libc/calls/hefty/ttyname_r.c @@ -0,0 +1,86 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/stat.h" +#include "libc/dce.h" +#include "libc/fmt/fmt.h" +#include "libc/log/log.h" +#include "libc/nt/console.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +static textwindows noinline int ttyname$nt(int fd, char *buf, size_t size) { + uint32_t mode; + if (GetConsoleMode(g_fds.p[fd].handle, &mode)) { + if (mode & kNtEnableVirtualTerminalInput) { + strncpy(buf, "CONIN$", size); + return 0; + } else { + strncpy(buf, "CONOUT$", size); + return 0; + } + } else { + return enotty(); + } +} + +static int ttyname$freebsd(int fd, char *buf, size_t size) { + const unsigned FIODGNAME = 2148558456; + struct fiodgname_arg { + int len; + void *buf; + } fg; + fg.buf = buf; + fg.len = size; + if (ioctl$sysv(fd, FIODGNAME, &fg) != -1) return 0; + return enotty(); +} + +static int ttyname$linux(int fd, char *buf, size_t size) { + struct stat st1, st2; + if (!isatty(fd)) return errno; + char name[PATH_MAX]; + snprintf(name, sizeof(name), "/proc/self/fd/%d", fd); + ssize_t got; + got = readlink(name, buf, size); + if (got == -1) return errno; + if ((size_t)got >= size) return erange(); + buf[got] = 0; + if (stat(buf, &st1) || fstat(fd, &st2)) return errno; + if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) return enodev(); + return 0; +} + +int ttyname_r(int fd, char *buf, size_t size) { + if (IsLinux()) { + return ttyname$linux(fd, buf, size); + } else if (IsFreebsd()) { + return ttyname$freebsd(fd, buf, size); + } else if (IsWindows()) { + if (isfdkind(fd, kFdFile)) { + return ttyname$nt(fd, buf, size); + } else { + return ebadf(); + } + } else { + return enosys(); + } +} diff --git a/libc/calls/internal.h b/libc/calls/internal.h new file mode 100644 index 00000000..3e7ed2bb --- /dev/null +++ b/libc/calls/internal.h @@ -0,0 +1,320 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#ifndef COSMOPOLITAN_LIBC_CALLS_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_CALLS_INTERNAL_H_ +#include "libc/calls/calls.h" +#include "libc/dce.h" +#include "libc/limits.h" +#include "libc/macros.h" +#include "libc/nt/struct/securityattributes.h" +#include "libc/nt/struct/startupinfo.h" +#include "libc/runtime/runtime.h" + +#define kSigactionMinRva 8 /* >SIG_{ERR,DFL,IGN,...} */ + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define kIoMotion ((const int8_t[3]){1, 0, 0}) + +struct NtContext; +struct NtWin32FileAttributeData; +struct __darwin_siginfo; +struct __darwin_ucontext; +struct itimerval; +struct rlimit; +struct rusage; +struct sigset; +struct sysinfo; +struct timeval; +struct timezone; +struct ZiposHandle; + +struct IoctlPtmGet { + int theduxfd; + int workerfd; + char theduxname[16]; + char workername[16]; +}; + +/** + * List of open handles on Windows NT. + * + * The array is indexed by the sysv-style file descriptor numbers that + * we assign. It's needed to make file descriptors only require 32bits + * and helps us abstract peculiarities like close() vs. closesocket(). + */ +struct Fds { + size_t f, n; + struct Fd { + int64_t handle; + int64_t extra; + enum FdKind { + kFdEmpty, + kFdFile, + kFdSocket, + kFdProcess, + kFdConsole, + kFdZip, + } kind; + unsigned flags; + } * p; + struct Fd __init_p[OPEN_MAX]; +}; + +extern const struct Fd kEmptyFd; + +hidden extern int g_sighandrvas[NSIG]; +hidden extern struct Fds g_fds; +hidden extern struct NtSystemInfo g_ntsysteminfo; +hidden extern struct NtStartupInfo g_ntstartupinfo; +hidden extern const struct NtSecurityAttributes kNtIsInheritable; + +forceinline bool isfdlegal(int fd) { + if (!IsTrustworthy()) { + return (0 <= fd && fd <= INT_MAX); + } else { + return fd; + } +} + +forceinline bool isfdindex(int fd) { + if (!IsTrustworthy()) { + return (0 <= fd && fd < g_fds.n); + } else { + return fd; + } +} + +ssize_t createfd(void) hidden; +int growfds(void) hidden; +void removefd(int) hidden; +enum FdKind fdkind(int) hidden nosideeffect; +bool isfdkind(int, enum FdKind) hidden nosideeffect; + +forceinline size_t clampio(size_t size) { + if (!IsTrustworthy()) { + return MIN(size, 0x7ffff000); + } else { + return size; + } +} + +#define i32 int32_t +#define i64 int64_t +#define u32 uint32_t +#define u64 uint64_t +#define sigset struct sigset + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § syscalls » system five » synthetic jump slots ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +char *getcwd$sysv(char *, u64) hidden; +i32 __dup3$sysv(i32, i32, i32) hidden; +i32 __fstat$sysv(i32, struct stat *) hidden; +i32 __fstatat$sysv(i32, const char *, struct stat *, i32) hidden; +i32 __pipe2$sysv(i32[hasatleast 2], u32) hidden; +i32 chdir$sysv(const char *) hidden; +i32 clock_gettime$sysv(i32, struct timespec *) hidden; +i32 close$sysv(i32) hidden; +i32 dup$sysv(i32) hidden; +i32 dup2$sysv(i32, i32) hidden; +i32 dup3$sysv(i32, i32, i32) hidden; +i32 execve$sysv(const char *, char *const[], char *const[]) hidden; +i32 faccessat$sysv(i32, const char *, i32, u32) hidden; +i32 fadvise$sysv(i32, i64, i64, i32) hidden; +i32 fallocate$sysv(i64, i32, i64, i64) hidden; +i32 fchmod$sysv(i32, u32) hidden; +i32 fchmodat$sysv(i32, const char *, u32, u32) hidden; +i32 fchown$sysv(i64, u32, u32) hidden; +i32 fchownat$sysv(i32, const char *, u32, u32, u32) hidden; +i32 fcntl$sysv(i32, i32, i32) hidden; +i32 fdatasync$sysv(i32) hidden; +i32 flock$sysv(i32, i32) hidden; +i32 fork$sysv(void) hidden; +i32 fstat$sysv(i32, struct stat *) hidden; +i32 fstatat$sysv(i32, const char *, struct stat *, i32) hidden; +i32 fsync$sysv(i32) hidden; +i32 ftruncate$sysv(i32, i64) hidden; +i32 getdents(i32, char *, u32) hidden; +i32 getppid$sysv(void) hidden; +i32 getpriority$sysv(i32, u32) hidden; +i32 getrlimit$sysv(i32, struct rlimit *) hidden; +i32 getrusage$sysv(i32, struct rusage *) hidden; +i32 gettimeofday$sysv(struct timeval *, struct timezone *) hidden; +i32 ioctl$sysv(i32, u64, void *) hidden; +i32 kill$sysv(i32, i32, i32) hidden; +i32 linkat$sysv(i32, const char *, i32, const char *, i32) hidden; +i32 lseek$sysv(i32, i64, i32) hidden; +i32 madvise$sysv(void *, size_t, i32) hidden; +i32 memfd_create$sysv(const char *, u32) hidden; +i32 mkdirat$sysv(i32, const char *, u32) hidden; +i32 mkfifo$sysv(const char *, u32) hidden; +i32 mknod$sysv(const char *, u32, u64) hidden; +i32 mprotect$sysv(void *, u64, i32) hidden; +i32 msync$sysv(void *, u64, i32) hidden; +i32 munmap$sysv(void *, u64) hidden; +i32 nanosleep$sysv(const struct timespec *, struct timespec *) hidden; +i32 openat$sysv(i32, const char *, i32, i32) hidden; +i32 pause$sysv(void) hidden; +i32 pipe$sysv(i32[hasatleast 2]) hidden; +i32 pipe2$sysv(i32[hasatleast 2], u32) hidden; +i32 posix_fallocate$sysv(i64, i64, i64) hidden; +i32 posix_openpt$sysv(i32) hidden; +i32 renameat$sysv(i32, const char *, i32, const char *) hidden; +i32 sched_setaffinity$sysv(i32, u64, const void *) hidden; +i32 sched_yield$sysv(void) hidden; +i32 setitimer$sysv(i32, const struct itimerval *, struct itimerval *) hidden; +i32 setpriority$sysv(i32, u32, i32) hidden; +i32 setrlimit$sysv(i32, const struct rlimit *) hidden; +i32 sigaction$sysv(i32, const void *, void *, i64) hidden; +i32 sigprocmask$sysv(i32, const sigset *, sigset *, u64) hidden; +i32 sigsuspend$sysv(const sigset *, u64) hidden; +i32 symlinkat$sysv(const char *, i32, const char *) hidden; +i32 sync_file_range$sysv(i32, i64, i64, u32) hidden; +i32 sysinfo$sysv(struct sysinfo *) hidden; +i32 truncate$sysv(const char *, u64) hidden; +i32 uname$sysv(char *) hidden; +i32 unlinkat$sysv(i32, const char *, i32) hidden; +i32 utimes$sysv(const char *, const struct timeval *) hidden; +i32 wait4$sysv(i32, i32 *, i32, struct rusage *) hidden; +i64 copy_file_range$sysv(i32, long *, i32, long *, u64, u32) hidden; +i64 getrandom$sysv(void *, u64, u32) hidden; +i64 pread$sysv(i32, void *, u64, i64) hidden; +i64 preadv$sysv(i32, struct iovec *, i32, i64) hidden; +i64 pwrite$sysv(i32, const void *, u64, i64) hidden; +i64 pwritev$sysv(i32, const struct iovec *, i32, i64) hidden; +i64 read$sysv(i32, void *, u64) hidden; +i64 sendfile$sysv(i32, i32, i64 *, u64) hidden; +i64 splice$sysv(i32, i64 *, i32, i64 *, u64, u32) hidden; +i64 vmsplice$sysv(i32, const struct iovec *, i64, u32) hidden; +i64 write$sysv(i32, const void *, u64) hidden; +u32 getgid$sysv(void) hidden; +u32 getpid$sysv(void) hidden; +u32 gettid$sysv(void) hidden; +u32 getuid$sysv(void) hidden; +int setresuid$sysv(uint32_t, uint32_t, uint32_t) hidden; +int setresgid$sysv(uint32_t, uint32_t, uint32_t) hidden; +void *mmap$sysv(void *, u64, u32, u32, i64, i64) hidden; +void *mremap$sysv(void *, u64, u64, i32, void *) hidden; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § syscalls » system five » support ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +int __getpid(void) hidden; +void __onfork(void) hidden; +bool32 __sigenter(i32, struct siginfo *, struct ucontext *) hidden; +i32 __mprotect(void *, u64, i32) privileged; +i32 fixupnewfd$sysv(i32, i32) hidden; +i32 tunefd$sysv(i32, i32, i32, i32) hidden; +u32 fprot2nt(i32, i32) hidden; +u32 prot2nt(i32, i32) privileged; +void __restore_rt() hidden; +void __sigenter$xnu(void *, i32, i32, void *, void *) hidden noreturn; +void stat2linux(void *) hidden; +void xnutrampoline(void *, i32, i32, const struct __darwin_siginfo *, + const struct __darwin_ucontext *) hidden noreturn; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § syscalls » windows nt » veneers ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +int gettimeofday$nt(struct timeval *, struct timezone *) hidden; +bool32 isatty$nt(int) hidden; +char *getcwd$nt(char *, size_t) hidden; +int chdir$nt(const char *) hidden; +int close$nt(int) hidden; +int dup$nt(int, int, int) hidden; +int fadvise$nt(int, u64, u64, int) hidden; +int fcntl$nt(int, int, unsigned) hidden; +int getpriority$nt(int) hidden; +int setpriority$nt(int) hidden; +int fdatasync$nt(int) hidden; +int flock$nt(int, int) hidden; +int fstat$nt(i64, struct stat *) hidden; +int ftruncate$nt(int, u64) hidden; +int kill$nt(i64, int) hidden; +int link$nt(const char *, const char *) hidden; +int lstat$nt(const char *, struct stat *) hidden; +int madvise$nt(void *, size_t, int) hidden; +int msync$nt(void *, size_t, int) hidden; +ssize_t open$nt(const char *, u32, i32) nodiscard hidden; +int pipe$nt(int[hasatleast 2], unsigned) hidden; +int rename$nt(const char *, const char *) hidden; +int rmdir$nt(const char *) hidden; +int sched_yield$nt(void) hidden; +int stat$nt(const char *, struct stat *) hidden; +int symlink$nt(const char *, const char *) hidden; +int sysinfo$nt(struct sysinfo *) hidden; +int truncate$nt(const char *, u64) hidden; +int unlink$nt(const char *) hidden; +int wait4$nt(int, int *, int, struct rusage *) hidden; +i64 lseek$nt(int, i64, int) hidden; +ssize_t read$nt(struct Fd *, const struct iovec *, size_t, ssize_t) hidden; +ssize_t write$nt(struct Fd *, const struct iovec *, size_t, ssize_t) hidden; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § syscalls » windows nt » support ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +int getsetpriority$nt(int, unsigned, int, int (*)(int)); +void ntcontext2linux(struct ucontext *, const struct NtContext *) hidden; +struct NtOverlapped *offset2overlap(int64_t, struct NtOverlapped *) hidden; +bool32 ntsetprivilege(i64, const char16_t *, u32) hidden; +bool32 onntconsoleevent$nt(u32) hidden; +int ntaccesscheck(const char16_t *, u32) paramsnonnull() hidden; +i64 ntreturn(u32); +i64 winerr(void) nocallback privileged; + +const char *__fixntmagicpath(const char *, unsigned) paramsnonnull() hidden; +int __mkntpath(const char *, unsigned, char16_t[hasatleast PATH_MAX - 16]) + paramsnonnull() hidden; + +#define mkntpath(PATH, PATH16) mkntpath2(PATH, -1u, PATH16) +#define mkntpath2(PATH, FLAGS, PATH16) \ + ({ \ + int Count; \ + asm("call\tmkntpath" \ + : "=a"(Count), "=m"(*PATH16) \ + : "D"(PATH), "S"(FLAGS), "d"(&PATH16[0]), "m"((PATH)[0]) \ + : "cc"); \ + Count; \ + }) + +#define fixntmagicpath(PATH, FLAGS) \ + ({ \ + const char *Path2; \ + asm("call\tfixntmagicpath" \ + : "=a"(Path2) \ + : "D"(PATH), "S"(FLAGS), "m"((PATH)[0]) \ + : "cc"); \ + Path2; \ + }) + +#undef sigset +#undef i32 +#undef i64 +#undef u32 +#undef u64 +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_INTERNAL_H_ */ diff --git a/libc/calls/ioctl-default.c b/libc/calls/ioctl-default.c new file mode 100644 index 00000000..2ec69662 --- /dev/null +++ b/libc/calls/ioctl-default.c @@ -0,0 +1,46 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/internal.h" +#include "libc/calls/ioctl.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sysv/errfuns.h" + +int ioctl$default(int fd, uint64_t request, void *memory) { + int rc; + int64_t handle; + if (!IsWindows()) { + return ioctl$sysv(fd, request, memory); + } else if (isfdindex(fd)) { + if (isfdkind(fd, kFdSocket)) { + handle = g_fds.p[fd].handle; + if ((rc = weaken(__ioctlsocket$nt)(handle, request, memory)) != -1) { + return rc; + } else { + return weaken(winsockerr)(); + } + } else { + return eopnotsupp(); + } + } else { + return ebadf(); + } +} diff --git a/libc/calls/ioctl-tcgets-nt.c b/libc/calls/ioctl-tcgets-nt.c new file mode 100644 index 00000000..609f8cc6 --- /dev/null +++ b/libc/calls/ioctl-tcgets-nt.c @@ -0,0 +1,51 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/termios.h" +#include "libc/nt/console.h" +#include "libc/nt/enum/consolemodeflags.h" +#include "libc/nt/struct/consolescreenbufferinfoex.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/termios.h" +#include "libc/sysv/errfuns.h" + +textwindows int ioctl$tcgets$nt(int ignored, struct termios *tio) { + int64_t in, out; + bool32 inok, outok; + uint32_t inmode, outmode; + inok = GetConsoleMode((in = g_fds.p[0].handle), &inmode); + outok = GetConsoleMode((out = g_fds.p[1].handle), &outmode); + if (inok | outok) { + memset(tio, 0, sizeof(*tio)); + if (inok) { + if (inmode & kNtEnableLineInput) tio->c_lflag |= ICANON; + if (inmode & kNtEnableEchoInput) tio->c_lflag |= ECHO; + if (inmode & kNtEnableProcessedInput) tio->c_lflag |= IEXTEN | ISIG; + } + if (outok) { + if (inmode & kNtEnableProcessedInput) tio->c_lflag |= IEXTEN | ISIG; + } + return 0; + } else { + return enotty(); + } +} diff --git a/libc/calls/ioctl-tcgets.c b/libc/calls/ioctl-tcgets.c new file mode 100644 index 00000000..4d793a59 --- /dev/null +++ b/libc/calls/ioctl-tcgets.c @@ -0,0 +1,49 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/struct/metatermios.h" +#include "libc/calls/termios-internal.h" +#include "libc/sysv/consts/termios.h" + +int ioctl$tcgets$nt(int, struct termios *); + +static int ioctl$tcgets$sysv(int fd, struct termios *tio) { + int rc; + union metatermios t; + if ((rc = ioctl$sysv(fd, TCGETS, &t)) != -1) { + termios2linux(tio, &t); + } + return rc; +} + +/** + * Returns information about terminal. + * + * @see tcgetattr(fd, tio) dispatches here + * @see ioctl(fd, TCGETS, tio) dispatches here + * @see ioctl(fd, TIOCGETA, tio) dispatches here + */ +int ioctl$tcgets(int fd, struct termios *tio) { + if (!IsWindows()) { + return ioctl$tcgets$sysv(fd, tio); + } else { + return ioctl$tcgets$nt(fd, tio); + } +} diff --git a/libc/calls/ioctl-tcsets-nt.c b/libc/calls/ioctl-tcsets-nt.c new file mode 100644 index 00000000..2a0c9e98 --- /dev/null +++ b/libc/calls/ioctl-tcsets-nt.c @@ -0,0 +1,58 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/struct/metatermios.h" +#include "libc/calls/termios-internal.h" +#include "libc/nt/console.h" +#include "libc/nt/enum/version.h" +#include "libc/nt/struct/teb.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/termios.h" +#include "libc/sysv/errfuns.h" + +textwindows int ioctl$tcsets$nt(int ignored, uint64_t request, + const struct termios *tio) { + int64_t in, out; + bool32 inok, outok; + uint32_t inmode, outmode; + inok = GetConsoleMode((in = g_fds.p[0].handle), &inmode); + outok = GetConsoleMode((out = g_fds.p[1].handle), &outmode); + if (inok | outok) { + if (inok) { + if (request == TCSETSF) { + FlushConsoleInputBuffer(in); + } + inmode &= + ~(kNtEnableLineInput | kNtEnableEchoInput | kNtEnableProcessedInput); + if (tio->c_lflag & ECHO) inmode |= kNtEnableEchoInput; + if (tio->c_lflag & (IEXTEN | ISIG)) inmode |= kNtEnableProcessedInput; + SetConsoleMode(in, inmode); + } + if (outok) { + SetConsoleMode(out, outmode | kNtEnableProcessedOutput | + (NtGetVersion() >= kNtVersionWindows10 + ? kNtEnableVirtualTerminalProcessing + : 0)); + } + return 0; + } else { + return enotty(); + } +} diff --git a/libc/calls/ioctl-tcsets.c b/libc/calls/ioctl-tcsets.c new file mode 100644 index 00000000..1d1d3e74 --- /dev/null +++ b/libc/calls/ioctl-tcsets.c @@ -0,0 +1,47 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/struct/metatermios.h" +#include "libc/calls/termios-internal.h" +#include "libc/dce.h" +#include "libc/sysv/consts/termios.h" + +int ioctl$tcsets$nt(int, uint64_t, const struct termios *); + +static int ioctl$tcsets$sysv(int fd, uint64_t request, + const struct termios *tio) { + union metatermios t; + return ioctl$sysv(fd, request, termios2host(&t, tio)); +} + +/** + * Changes terminal behavior. + * + * @see tcsetattr(fd, TCSA{NOW,DRAIN,FLUSH}, tio) dispatches here + * @see ioctl(fd, TCSETS{,W,F}, tio) dispatches here + * @see ioctl(fd, TIOCGETA{,W,F}, tio) dispatches here + */ +int ioctl$tcsets(int fd, uint64_t request, const struct termios *tio) { + if (!IsWindows()) { + return ioctl$tcsets$sysv(fd, request, tio); + } else { + return ioctl$tcsets$nt(fd, request, tio); + } +} diff --git a/libc/calls/ioctl-tiocgwinsz-nt.c b/libc/calls/ioctl-tiocgwinsz-nt.c new file mode 100644 index 00000000..a787a6a1 --- /dev/null +++ b/libc/calls/ioctl-tiocgwinsz-nt.c @@ -0,0 +1,53 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/termios.h" +#include "libc/calls/struct/winsize.h" +#include "libc/nt/console.h" +#include "libc/nt/enum/startf.h" +#include "libc/nt/struct/consolescreenbufferinfoex.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +textwindows int ioctl$tiocgwinsz$nt(int fd, struct winsize *ws) { + uint32_t mode; + struct NtConsoleScreenBufferInfoEx sbinfo; + if (!isfdkind(fd, kFdFile)) return ebadf(); + if (!GetConsoleMode(g_fds.p[fd].handle, &mode)) return enotty(); + if (g_ntstartupinfo.dwFlags & kNtStartfUsecountchars) { + ws->ws_col = g_ntstartupinfo.dwXCountChars; + ws->ws_row = g_ntstartupinfo.dwYCountChars; + ws->ws_xpixel = 0; + ws->ws_ypixel = 0; + return 0; + } + memset(&sbinfo, 0, sizeof(sbinfo)); + sbinfo.cbSize = sizeof(sbinfo); + if (GetConsoleScreenBufferInfoEx(g_fds.p[fd].handle, &sbinfo)) { + ws->ws_col = sbinfo.srWindow.Right; + ws->ws_row = sbinfo.srWindow.Bottom; + ws->ws_xpixel = 0; + ws->ws_ypixel = 0; + return 0; + } else { + return winerr(); + } +} diff --git a/libc/calls/ioctl-tiocgwinsz.c b/libc/calls/ioctl-tiocgwinsz.c new file mode 100644 index 00000000..1f91a837 --- /dev/null +++ b/libc/calls/ioctl-tiocgwinsz.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/struct/winsize.h" +#include "libc/dce.h" +#include "libc/sysv/consts/termios.h" + +int ioctl$tiocgwinsz$nt(int, struct winsize *); + +/** + * Returns width and height of terminal. + * + * @see ioctl(fd, TIOCGWINSZ, ws) dispatches here + */ +int ioctl$tiocgwinsz(int fd, struct winsize *ws) { + if (!IsWindows()) { + return ioctl$sysv(fd, TIOCGWINSZ, ws); + } else { + return ioctl$tiocgwinsz$nt(fd, ws); + } +} diff --git a/libc/calls/ioctl-tiocswinsz-nt.c b/libc/calls/ioctl-tiocswinsz-nt.c new file mode 100644 index 00000000..9a9abdf8 --- /dev/null +++ b/libc/calls/ioctl-tiocswinsz-nt.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/termios.h" +#include "libc/calls/struct/winsize.h" +#include "libc/nt/console.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +textwindows int ioctl$tiocswinsz$nt(int fd, const struct winsize *ws) { + uint32_t mode; + struct NtCoord coord; + if (!ws) return efault(); + if (!isfdkind(fd, kFdFile)) return ebadf(); + if (!GetConsoleMode(g_fds.p[fd].handle, &mode)) return enotty(); + coord.X = ws->ws_col; + coord.Y = ws->ws_row; + if (!SetConsoleScreenBufferSize(g_fds.p[fd].handle, coord)) return winerr(); + return 0; +} diff --git a/libc/calls/ioctl-tiocswinsz.c b/libc/calls/ioctl-tiocswinsz.c new file mode 100644 index 00000000..783083e9 --- /dev/null +++ b/libc/calls/ioctl-tiocswinsz.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/struct/winsize.h" +#include "libc/dce.h" +#include "libc/sysv/consts/termios.h" + +int ioctl$tiocswinsz$nt(int, const struct winsize *); + +/** + * Returns width and height of terminal. + * + * @see ioctl(fd, TIOCSWINSZ, ws) dispatches here + */ +int ioctl$tiocswinsz(int fd, const struct winsize *ws) { + if (!IsWindows()) { + return ioctl$sysv(fd, TIOCSWINSZ, ws); + } else { + return ioctl$tiocswinsz$nt(fd, ws); + } +} diff --git a/libc/calls/ioctl.c b/libc/calls/ioctl.c new file mode 100644 index 00000000..759117b3 --- /dev/null +++ b/libc/calls/ioctl.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/ioctl.h" + +#define EQUAL(X, Y) ((X) == (Y)) + +/** + * Controls settings on device. + */ +int(ioctl)(int fd, uint64_t request, void *memory) { + __IOCTL_DISPATCH(EQUAL, fd, request, memory); + return ioctl$default(fd, request, memory); +} diff --git a/libc/calls/ioctl.h b/libc/calls/ioctl.h new file mode 100644 index 00000000..ed8493b3 --- /dev/null +++ b/libc/calls/ioctl.h @@ -0,0 +1,52 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_IOCTL_H_ +#define COSMOPOLITAN_LIBC_CALLS_IOCTL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § system calls » input output control ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +int ioctl(int, uint64_t, void *); + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § system calls » input output control » undiamonding ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#ifdef __GNUC__ +#include "libc/macros.h" +#include "libc/sysv/consts/termios.h" + +struct termios; +struct winsize; + +#define ioctl(FD, REQUEST, MEMORY) ioctl$dispatch(FD, REQUEST, MEMORY) + +#define __IOCTL_DISPATCH(CMP, FD, REQUEST, MEMORY) \ + do { \ + if (CMP(request, TIOCGWINSZ)) return ioctl$tiocgwinsz(FD, MEMORY); \ + if (CMP(request, TIOCSWINSZ)) return ioctl$tiocswinsz(FD, MEMORY); \ + if (CMP(request, TCGETS)) return ioctl$tcgets(FD, MEMORY); \ + if (CMP(request, TCSETS)) return ioctl$tcsets(FD, REQUEST, MEMORY); \ + if (CMP(request, TCSETSW)) return ioctl$tcsets(FD, REQUEST, MEMORY); \ + if (CMP(request, TCSETSF)) return ioctl$tcsets(FD, REQUEST, MEMORY); \ + } while (0) + +int ioctl$tcgets(int, void *); +int ioctl$tcgets$nt(int, void *); +int ioctl$tcsets(int, uint64_t, void *); +int ioctl$tcsets$nt(int, uint64_t, void *); +int ioctl$tiocgwinsz(int, void *); +int ioctl$tiocgwinsz$nt(int, void *); +int ioctl$tiocswinsz(int, void *); +int ioctl$tiocswinsz$nt(int, void *); +int ioctl$default(int, uint64_t, void *); + +forceinline int ioctl$dispatch(int fd, uint64_t request, void *memory) { + __IOCTL_DISPATCH(EQUIVALENT, fd, request, memory); + return ioctl$default(fd, request, memory); +} + +#endif /* GNUC */ +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_IOCTL_H_ */ diff --git a/libc/calls/isatty-nt.c b/libc/calls/isatty-nt.c new file mode 100644 index 00000000..49f05234 --- /dev/null +++ b/libc/calls/isatty-nt.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/enum/filetype.h" +#include "libc/nt/files.h" +#include "libc/sysv/errfuns.h" + +textwindows bool32 isatty$nt(int fd) { + if (!isfdkind(fd, kFdFile)) return ebadf(); + return GetFileType(g_fds.p[fd].handle) == kNtFileTypeChar; +} diff --git a/libc/calls/isatty.c b/libc/calls/isatty.c new file mode 100644 index 00000000..39dabfa6 --- /dev/null +++ b/libc/calls/isatty.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sysv/consts/termios.h" + +/** + * Returns true if file descriptor is backed by a terminal device. + * @asyncsignalsafe + */ +bool32 isatty(int fd) { + char buf[sizeof(uint16_t) * 4] aligned(2); + if (!IsWindows()) { + return ioctl$sysv(fd, TIOCGWINSZ, &buf) != -1; + } else { + return isatty$nt(fd); + } +} diff --git a/libc/calls/ischardev.c b/libc/calls/ischardev.c new file mode 100644 index 00000000..54585a62 --- /dev/null +++ b/libc/calls/ischardev.c @@ -0,0 +1,46 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/stat.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/nt/enum/filetype.h" +#include "libc/nt/files.h" + +/** + * Returns true if file descriptor is backed by character i/o. + */ +bool32 ischardev(int fd) { + int olderr; + struct stat st; + if (!IsWindows()) { + olderr = errno; + if (fstat$sysv(fd, &st) != -1) { + return S_ISCHR(st.st_mode); + } else { + errno = olderr; + return false; + } + } else { + return isfdkind(fd, kFdFile) && + GetFileType(g_fds.p[fd].handle) == kNtFileTypeChar; + } +} diff --git a/libc/calls/isdebuggerpresent.c b/libc/calls/isdebuggerpresent.c new file mode 100644 index 00000000..802e6a6d --- /dev/null +++ b/libc/calls/isdebuggerpresent.c @@ -0,0 +1,61 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/conv/conv.h" +#include "libc/dce.h" +#include "libc/log/log.h" +#include "libc/nt/struct/teb.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/at.h" +#include "libc/sysv/consts/o.h" + +#define kBufSize 1024 +#define kProcStatus "/proc/self/status" +alignas(16) static const char kGdbPid[] = "TracerPid:\t"; + +/** + * Determines if gdb, strace, windbg, etc. is controlling process. + * @return non-zero if attached, otherwise 0 + */ +int IsDebuggerPresent(bool force) { + int fd, res; + ssize_t got; + char buf[1024]; + res = 0; + if (force || isempty(getenv("HEISENDEBUG"))) { + if (IsWindows()) { + res = NtGetPeb()->BeingDebugged; + } else if (IsLinux()) { + if ((fd = openat$sysv(AT_FDCWD, kProcStatus, O_RDONLY, 0)) != -1) { + if ((got = read$sysv(fd, buf, sizeof(buf) - sizeof(kGdbPid))) != -1) { + buf[got] = '\0'; + res = atoi(firstnonnull(strstr(buf, kGdbPid), kGdbPid) + + strlen(kGdbPid)); + } + close$sysv(fd); + } + } + } + return res; +} diff --git a/libc/calls/isdirectory.c b/libc/calls/isdirectory.c new file mode 100644 index 00000000..05b3ad7e --- /dev/null +++ b/libc/calls/isdirectory.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/errno.h" +#include "libc/calls/struct/stat.h" +#include "libc/calls/calls.h" + +/** + * Returns true if file exists and is a directory + */ +bool isdirectory(const char *path) { + struct stat st; + int rc, olderr; + olderr = errno; + rc = stat(path, &st); + if (rc == -1 && (errno == ENOENT || errno == ENOTDIR)) errno = olderr; + return rc != -1 && S_ISDIR(st.st_mode); +} diff --git a/libc/calls/isexecutable.c b/libc/calls/isexecutable.c new file mode 100644 index 00000000..c4fe25e0 --- /dev/null +++ b/libc/calls/isexecutable.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/struct/stat.h" +#include "libc/calls/calls.h" +#include "libc/sysv/consts/s.h" + +/** + * Returns true if file exists and is executable. + * @see access(exe, X_OK) which is more accurate on NT + */ +bool isexecutable(const char *path) { + struct stat st; + if (stat(path, &st)) return 0; + return st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH); +} diff --git a/libc/calls/isfdkind.c b/libc/calls/isfdkind.c new file mode 100644 index 00000000..fac1ed47 --- /dev/null +++ b/libc/calls/isfdkind.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" + +bool isfdkind(int fd, enum FdKind kind) { + if (isfdindex(fd)) { + return g_fds.p[fd].kind == kind; + } else { + return false; + } +} diff --git a/libc/calls/isregularfile.c b/libc/calls/isregularfile.c new file mode 100644 index 00000000..9f2cd811 --- /dev/null +++ b/libc/calls/isregularfile.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/errno.h" +#include "libc/calls/struct/stat.h" +#include "libc/calls/calls.h" + +/** + * Returns true if file exists and is a regular file + */ +bool isregularfile(const char *path) { + /* TODO(jart): Use fast path on NT? */ + struct stat st; + int olderr = errno; + int rc = stat(path, &st); + if (rc == -1 && (errno == ENOENT || errno == ENOTDIR)) { + errno = olderr; + } + return rc != -1 && S_ISREG(st.st_mode); +} diff --git a/libc/calls/kemptyfd.c b/libc/calls/kemptyfd.c new file mode 100644 index 00000000..0b83e2f0 --- /dev/null +++ b/libc/calls/kemptyfd.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" + +const struct Fd kEmptyFd; diff --git a/libc/calls/kill.c b/libc/calls/kill.c new file mode 100644 index 00000000..3b90f0c3 --- /dev/null +++ b/libc/calls/kill.c @@ -0,0 +1,49 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sysv/errfuns.h" + +/** + * Sends signal to process. + * + * The impact of this action can be terminating the process, or + * interrupting it to request something happen. + * + * @param pid can be: + * >0 signals one process by id + * =0 signals all processes in current process group + * -1 signals all processes possible (except init) + * <-1 signals all processes in -pid process group + * @param sig can be: + * >0 can be SIGINT, SIGTERM, SIGKILL, SIGUSR1, etc. + * =0 is for error checking + * @return 0 if something was accomplished, or -1 w/ errno + * @asyncsignalsafe + */ +int kill(int pid, int sig) { + if (pid == getpid()) return raise(sig); + if (!IsWindows()) { + return kill$sysv(pid, sig, 1); + } else { + return enosys(); + } +} diff --git a/libc/calls/killpg.c b/libc/calls/killpg.c new file mode 100644 index 00000000..c7f65ddf --- /dev/null +++ b/libc/calls/killpg.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/calls/internal.h" +#include "libc/sysv/errfuns.h" + +/** + * Sends signal to process group. + */ +int killpg(int pgrp, int sig) { + if (!(0 < sig && sig < NSIG)) return einval(); + if (pgrp == 1 || pgrp < 0) return esrch(); + return kill(IsWindows() ? pgrp : -pgrp, sig); +} diff --git a/libc/calls/kntprioritycombos.c b/libc/calls/kntprioritycombos.c new file mode 100644 index 00000000..00d28d64 --- /dev/null +++ b/libc/calls/kntprioritycombos.c @@ -0,0 +1,56 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/kntprioritycombos.h" +#include "libc/limits.h" +#include "libc/macros.h" +#include "libc/nt/enum/processcreationflags.h" +#include "libc/nt/enum/threadpriority.h" + +const struct NtPriorityCombo kNtPriorityCombos[] = { + {-20, ffs(kNtHighPriorityClass), kNtThreadPriorityHighest, 15}, + {-18, ffs(kNtHighPriorityClass), kNtThreadPriorityTimeCritical, 15}, + {-17, ffs(kNtNormalPriorityClass), kNtThreadPriorityTimeCritical, 15}, + {-15, ffs(kNtIdlePriorityClass), kNtThreadPriorityTimeCritical, 15}, + {-13, ffs(kNtHighPriorityClass), kNtThreadPriorityAboveNormal, 14}, + {-11, ffs(kNtHighPriorityClass), kNtThreadPriorityNormal, 13}, + {-9, ffs(kNtHighPriorityClass), kNtThreadPriorityBelowNormal, 12}, + {-7, ffs(kNtNormalPriorityClass), kNtThreadPriorityHighest, 11}, + {-5, ffs(kNtHighPriorityClass), kNtThreadPriorityLowest, 11}, + {-3, ffs(kNtNormalPriorityClass), kNtThreadPriorityAboveNormal, 10}, + {-1, ffs(kNtNormalPriorityClass), kNtThreadPriorityHighest, 9}, + {0, ffs(kNtNormalPriorityClass), kNtThreadPriorityNormal, 9}, + {1, ffs(kNtNormalPriorityClass), kNtThreadPriorityAboveNormal, 8}, + {2, ffs(kNtNormalPriorityClass), kNtThreadPriorityBelowNormal, 8}, + {3, ffs(kNtNormalPriorityClass), kNtThreadPriorityNormal, 7}, + {4, ffs(kNtNormalPriorityClass), kNtThreadPriorityLowest, 7}, + {5, ffs(kNtIdlePriorityClass), kNtThreadPriorityHighest, 6}, + {6, ffs(kNtNormalPriorityClass), kNtThreadPriorityBelowNormal, 6}, + {7, ffs(kNtIdlePriorityClass), kNtThreadPriorityAboveNormal, 5}, + {9, ffs(kNtNormalPriorityClass), kNtThreadPriorityLowest, 5}, + {11, ffs(kNtIdlePriorityClass), kNtThreadPriorityNormal, 4}, + {13, ffs(kNtIdlePriorityClass), kNtThreadPriorityBelowNormal, 3}, + {15, ffs(kNtIdlePriorityClass), kNtThreadPriorityLowest, 2}, + {17, ffs(kNtHighPriorityClass), kNtThreadPriorityIdle, 1}, + {18, ffs(kNtNormalPriorityClass), kNtThreadPriorityIdle, 1}, + {19, ffs(kNtIdlePriorityClass), kNtThreadPriorityIdle, 1}, +}; + +const unsigned kNtPriorityCombosLen = ARRAYLEN(kNtPriorityCombos); diff --git a/libc/calls/kntprioritycombos.h b/libc/calls/kntprioritycombos.h new file mode 100644 index 00000000..2658b14b --- /dev/null +++ b/libc/calls/kntprioritycombos.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_KNTPRIORITYCOMBOS_H_ +#define COSMOPOLITAN_LIBC_CALLS_KNTPRIORITYCOMBOS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtPriorityCombo { + int8_t nice; /* sorted by this */ + int8_t lg2tier; + int8_t wut; + int8_t prio; +}; + +extern const unsigned kNtPriorityCombosLen; +extern const struct NtPriorityCombo kNtPriorityCombos[]; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_KNTPRIORITYCOMBOS_H_ */ diff --git a/libc/calls/ktmppath.S b/libc/calls/ktmppath.S new file mode 100644 index 00000000..4b1bf1c9 --- /dev/null +++ b/libc/calls/ktmppath.S @@ -0,0 +1,43 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/runtime.h" +#include "libc/macros.h" + +#define kTmpPathMax 80 + +/ RII constant holding /tmp/ directory. +/ +/ @note on win32 this is firstNonNull($TMP, $TEMP, $PWD) +/ @note guarantees trailing slash if non-empty + .initbss 300,_init_kTmpPath +kTmpPath: + .zero kTmpPathMax + .endobj kTmpPath,globl + .previous + + .init.start 300,_init_kTmpPath + movl $'/|'t<<010|'m<<020|'p<<030,(%rdi) + movw $'/,4(%rdi) + pushpop kTmpPathMax,%rdx + ezlea GetTempPathA$flunk,ax + call __getntsyspath + .init.end 300,_init_kTmpPath + + .yoink __FILE__ diff --git a/libc/calls/lchown.c b/libc/calls/lchown.c new file mode 100644 index 00000000..59601dc8 --- /dev/null +++ b/libc/calls/lchown.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/sysv/consts/at.h" + +/** + * Changes owner and/or group of pathname, w/o dereferencing symlinks. + * + * @param uid is user id, or -1u to not change + * @param gid is group id, or -1u to not change + * @return 0 on success, or -1 w/ errno + * @see chown() which dereferences symbolic links + * @see /etc/passwd for user ids + * @see /etc/group for group ids + */ +int lchown(const char *pathname, uint32_t uid, uint32_t gid) { + /* TODO(jart): Windows? */ + return fchownat$sysv(AT_FDCWD, pathname, uid, gid, AT_SYMLINK_NOFOLLOW); +} diff --git a/libc/calls/link-nt.c b/libc/calls/link-nt.c new file mode 100644 index 00000000..b19e40f6 --- /dev/null +++ b/libc/calls/link-nt.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" +#include "libc/calls/internal.h" +#include "libc/calls/calls.h" + +textwindows int link$nt(const char *existingpath, const char *newpath) { + char16_t newpath16[PATH_MAX]; + char16_t existingpath16[PATH_MAX]; + if (mkntpath(existingpath, existingpath16) != -1 && + mkntpath(newpath, newpath16) != -1) { + if (CreateHardLink(newpath16, existingpath16, NULL)) { + return 0; + } else { + return winerr(); + } + } else { + return -1; + } +} diff --git a/libc/calls/link.c b/libc/calls/link.c new file mode 100644 index 00000000..f435332d --- /dev/null +++ b/libc/calls/link.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/calls/internal.h" +#include "libc/calls/calls.h" +#include "libc/sysv/errfuns.h" +#include "libc/sysv/consts/at.h" + +/** + * Creates hard filesystem link. + * + * This allows two names to point to the same file data on disk. They + * can only be differentiated by examining the inode number. + * + * @return 0 on success, or -1 w/ errno + * @asyncsignalsafe + */ +int link(const char *existingpath, const char *newpath) { + if (!existingpath || !newpath) return efault(); + if (!IsWindows()) { + return linkat$sysv(AT_FDCWD, existingpath, AT_FDCWD, newpath, 0); + } else { + return link$nt(existingpath, newpath); + } +} diff --git a/libc/calls/lseek-nt.c b/libc/calls/lseek-nt.c new file mode 100644 index 00000000..d6b2e98c --- /dev/null +++ b/libc/calls/lseek-nt.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/files.h" +#include "libc/sysv/errfuns.h" + +textwindows int64_t lseek$nt(int fd, int64_t offset, int whence) { + int64_t res; + if (!isfdkind(fd, kFdFile)) return ebadf(); + if (SetFilePointerEx(g_fds.p[fd].handle, offset, &res, whence)) { + return res; + } else { + return winerr(); + } +} diff --git a/libc/calls/lseek.c b/libc/calls/lseek.c new file mode 100644 index 00000000..d4ee2bac --- /dev/null +++ b/libc/calls/lseek.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" + +/** + * Changes current position of file descriptor/handle. + * + * @param fd is a number returned by open() + * @param offset is the relative byte count + * @param whence can be SEEK_SET, SEEK_CUR, or SEEK_END + * @return new position relative to beginning, or -1 on error + * @asyncsignalsafe + */ +int64_t lseek(int fd, int64_t offset, int whence) { + if (!IsWindows()) { + return lseek$sysv(fd, offset, whence); + } else { + return lseek$nt(fd, offset, whence); + } +} diff --git a/libc/calls/lstat-nt.c b/libc/calls/lstat-nt.c new file mode 100644 index 00000000..225382bf --- /dev/null +++ b/libc/calls/lstat-nt.c @@ -0,0 +1,25 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" + +textwindows int lstat$nt(const char *pathname, struct stat *st) { + return stat$nt(pathname, st); /* todo(jart) */ +} diff --git a/libc/calls/lstat.c b/libc/calls/lstat.c new file mode 100644 index 00000000..16b5acb2 --- /dev/null +++ b/libc/calls/lstat.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/calls/internal.h" +#include "libc/calls/calls.h" +#include "libc/sysv/consts/at.h" + +/** + * Returns information about file, w/o traversing symlinks. + * @asyncsignalsafe + */ +int lstat(const char *pathname, struct stat *st) { + if (!IsWindows()) { + return fstatat$sysv(AT_FDCWD, pathname, st, AT_SYMLINK_NOFOLLOW); + } else { + return lstat$nt(pathname, st); + } +} diff --git a/libc/calls/madvise-nt.c b/libc/calls/madvise-nt.c new file mode 100644 index 00000000..9c2b5b38 --- /dev/null +++ b/libc/calls/madvise-nt.c @@ -0,0 +1,82 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/macros.h" +#include "libc/nt/memory.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/memoryrangeentry.h" +#include "libc/sysv/consts/madv.h" +#include "libc/sysv/errfuns.h" + +forceinline typeof(PrefetchVirtualMemory) *GetPrefetchVirtualMemory(void) { + static bool once; + static typeof(PrefetchVirtualMemory) *PrefetchVirtualMemory_; + if (!once) { + once = true; + PrefetchVirtualMemory_ = /* win8.1+ */ + getprocaddressmodule("KernelBase.dll", "PrefetchVirtualMemory"); + } + return PrefetchVirtualMemory_; +} + +forceinline typeof(OfferVirtualMemory) *GetOfferVirtualMemory(void) { + static bool once; + static typeof(OfferVirtualMemory) *OfferVirtualMemory_; + if (!once) { + once = true; + OfferVirtualMemory_ = /* win8.1+ */ + getprocaddressmodule("KernelBase.dll", "OfferVirtualMemory"); + } + return OfferVirtualMemory_; +} + +textwindows int madvise$nt(void *addr, size_t length, int advice) { + uint32_t rangecount; + struct NtMemoryRangeEntry ranges[1]; + if ((advice & (int)MADV_WILLNEED) == (int)MADV_WILLNEED || + (advice & (int)MADV_SEQUENTIAL) == (int)MADV_SEQUENTIAL) { + typeof(PrefetchVirtualMemory) *fn = GetPrefetchVirtualMemory(); + if (fn) { + ranges[0].VirtualAddress = addr; + ranges[0].NumberOfBytes = length; + rangecount = ARRAYLEN(ranges); + if (fn(GetCurrentProcess(), &rangecount, ranges, 0)) { + return 0; + } else { + return winerr(); + } + } else { + return enosys(); + } + } else if ((advice & (int)MADV_FREE) == (int)MADV_FREE) { + typeof(OfferVirtualMemory) *fn = GetOfferVirtualMemory(); + if (fn) { + if (fn(addr, length, kNtVmOfferPriorityNormal)) { + return 0; + } else { + return winerr(); + } + } else { + return enosys(); + } + } else { + return einval(); + } +} diff --git a/libc/calls/madvise.c b/libc/calls/madvise.c new file mode 100644 index 00000000..a0dacef5 --- /dev/null +++ b/libc/calls/madvise.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" + +/** + * Drops hints to O/S about intended access patterns of mmap()'d memory. + * + * @param advice can be MADV_WILLNEED, MADV_SEQUENTIAL, MADV_FREE, etc. + * @return 0 on success, or -1 w/ errno + * @see libc/sysv/consts.sh + * @see fadvise() + */ +int madvise(void *addr, size_t length, int advice) { + if (!IsWindows()) { + return madvise$sysv(addr, length, advice); + } else { + return madvise$nt(addr, length, advice); + } +} diff --git a/libc/calls/mkdir.c b/libc/calls/mkdir.c new file mode 100644 index 00000000..581a6ed3 --- /dev/null +++ b/libc/calls/mkdir.c @@ -0,0 +1,54 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/at.h" +#include "libc/sysv/errfuns.h" + +static textwindows noinline int mkdir$nt(const char *path, uint32_t mode) { + uint16_t path16[PATH_MAX]; + if (mkntpath(path, path16) == -1) return -1; + if (CreateDirectory(path16, NULL)) { + return 0; + } else { + return winerr(); + } +} + +/** + * Creates directory a.k.a. folder. + * + * @param path is a UTF-8 string, preferably relative w/ forward slashes + * @param mode can be, for example, 0755 + * @return 0 on success or -1 w/ errno + * @error EEXIST, ENOTDIR, ENAMETOOLONG, EACCES + * @asyncsignalsafe + */ +int mkdir(const char *path, uint32_t mode) { + if (!path) return efault(); + if (!IsWindows()) { + return mkdirat$sysv(AT_FDCWD, path, mode); + } else { + return mkdir$nt(path, mode); + } +} diff --git a/libc/calls/mkfifo.c b/libc/calls/mkfifo.c new file mode 100644 index 00000000..07c72e24 --- /dev/null +++ b/libc/calls/mkfifo.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/nt/ipc.h" +#include "libc/sysv/consts/s.h" +#include "libc/sysv/errfuns.h" + +#define NT_PIPE_PATH_PREFIX u"\\\\.\\pipe\\" + +/** + * Creates named pipe. + * + * @param mode is octal, e.g. 0600 for owner-only read/write + * @asyncsignalsafe + */ +int mkfifo(const char *pathname, unsigned mode) { + /* TODO(jart): Windows? */ + if (IsLinux()) { + return mknod$sysv(pathname, mode | S_IFIFO, 0); + } else { + return mkfifo$sysv(pathname, mode); + } +} diff --git a/libc/calls/mknod.c b/libc/calls/mknod.c new file mode 100644 index 00000000..cc83eef1 --- /dev/null +++ b/libc/calls/mknod.c @@ -0,0 +1,50 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/calls/internal.h" +#include "libc/calls/calls.h" +#include "libc/sysv/errfuns.h" +#include "libc/sysv/consts/s.h" + +/** + * Creates filesystem inode. + * + * @param mode is octal mode, e.g. 0600; needs to be or'd with one of: + * S_IFDIR: directory + * S_IFIFO: named pipe + * S_IFREG: regular file + * S_IFSOCK: named socket + * S_IFBLK: block device (root has authorization) + * S_IFCHR: character device (root has authorization) + * @param dev it's complicated + * @return 0 on success, or -1 w/ errno + * @asyncsignalsafe + */ +int mknod(const char *path, uint32_t mode, uint64_t dev) { + if (mode & S_IFREG) return creat(path, mode & ~S_IFREG); + if (mode & S_IFDIR) return mkdir(path, mode & ~S_IFDIR); + if (mode & S_IFIFO) return mkfifo(path, mode & ~S_IFIFO); + if (!IsWindows()) { + /* TODO(jart): Whys there code out there w/ S_xxx passed via dev? */ + return mknod$sysv(path, mode, dev); + } else { + return enosys(); + } +} diff --git a/libc/calls/mkntpath.ncabi.c b/libc/calls/mkntpath.ncabi.c new file mode 100644 index 00000000..c44249e3 --- /dev/null +++ b/libc/calls/mkntpath.ncabi.c @@ -0,0 +1,77 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/pushpop.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/hefty/ntspawn.h" +#include "libc/calls/internal.h" +#include "libc/conv/conv.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +/** + * Copies path for Windows NT. + * + * This entails (1) UTF-8 to UTF-16 conversion; (2) replacing + * forward-slashes with backslashes; and (3) remapping several + * well-known paths (e.g. /dev/null → NUL) for convenience. + * + * @param path16 is shortened so caller can prefix, e.g. \\.\pipe\, and + * due to a plethora of special-cases throughout the Win32 API + * @param flags is used by open(), see fixntmagicpath2() + * @return short count excluding NUL on success, or -1 w/ errno + * @error ENAMETOOLONG + */ +textwindows int(mkntpath)(const char *path, unsigned flags, + char16_t path16[hasatleast PATH_MAX - 16]) { + /* + * 1. Reserve +1 for NUL-terminator + * 2. Reserve +1 for UTF-16 overflow + * 3. Reserve ≥2 for SetCurrentDirectory trailing slash requirement + * 4. Reserve ≥10 for CreateNamedPipe "\\.\pipe\" prefix requirement + * 5. Reserve ≥13 for mkdir() i.e. 1+8+3+1, e.g. "\\ffffffff.xxx\0" + */ + int rc; + wint_t wc; + size_t i, j; + path = fixntmagicpath(path, flags); + i = 0; + j = 0; + for (;;) { + if ((rc = tpdecode(&path[i], &wc)) == -1) { + path16[0] = u'\0'; + return -1; + } + if (!wc) break; + i += (size_t)rc; + if (wc == '/') wc = '\\'; + if (j + 1 /* utf-16 */ + 1 /* chdir() */ + 1 /* NUL */ < PATH_MAX - 16) { + if ((rc = pututf16(&path16[j], 2, wc, false)) == -1) { + path16[0] = u'\0'; + return -1; + } + j += (size_t)rc; + } else { + path16[0] = u'\0'; + return enametoolong(); + } + } + path16[j] = u'\0'; + return j; +} diff --git a/libc/calls/mprotect.c b/libc/calls/mprotect.c new file mode 100644 index 00000000..2e23d020 --- /dev/null +++ b/libc/calls/mprotect.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/calls.h" + +/** + * Modifies restrictions on virtual memory address range. + * + * @param prot can have PROT_{NONE,READ,WRITE,EXEC,GROWSDOWN} + * @return 0 on success, or -1 w/ errno + * @see mmap() + */ +int mprotect(void *addr, uint64_t len, int prot) { + return __mprotect(addr, len, prot); +} diff --git a/libc/calls/mprotect.greg.c b/libc/calls/mprotect.greg.c new file mode 100644 index 00000000..1427364c --- /dev/null +++ b/libc/calls/mprotect.greg.c @@ -0,0 +1,54 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#define ShouldUseMsabiAttribute() 1 +#include "libc/bits/bits.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/nt/memory.h" +#include "libc/nt/thunk/msabi.h" +#include "libc/sysv/consts/nr.h" + +privileged int __mprotect(void *addr, uint64_t len, int prot) { + extern __msabi typeof(VirtualProtect) *const __imp_VirtualProtect; + bool cf; + int64_t rc; + uint32_t oldprot; + if (!IsWindows()) { + asm volatile(CFLAG("syscall") + : CF(cf), "=a"(rc) + : "1"(__NR_mprotect), "D"(addr), "S"(len), "d"(prot) + : "rcx", "r11", "memory", "cc"); + if (cf) { + rc = -rc; + rc = -1; + } else if (rc > -4096ul) { + errno = -rc; + rc = -1; + } + return rc; + } else { + if (__imp_VirtualProtect(addr, len, prot2nt(prot, 0), &oldprot)) { + return 0; + } else { + return winerr(); + } + } +} diff --git a/libc/calls/nice.c b/libc/calls/nice.c new file mode 100644 index 00000000..247aa311 --- /dev/null +++ b/libc/calls/nice.c @@ -0,0 +1,46 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/conv/conv.h" +#include "libc/sysv/consts/prio.h" + +static int clamp(int p) { return max(-NZERO, min(NZERO - 1, p)); } + +/** + * Changes process priority. + * + * @param delta is added to current priority w/ clamping + * @return new priority, or -1 w/ errno + * @see Linux claims ioprio_set() is tuned automatically by this + */ +int nice(int delta) { + int p; + if (abs(delta) >= NZERO * 2) { + p = delta; + } else { + delta = clamp(delta); + if ((p = getpriority(PRIO_PROCESS, 0)) == -1) return -1; + p += delta; + } + p = clamp(p); + if (setpriority(PRIO_PROCESS, 0, p) == -1) return -1; + return p; +} diff --git a/libc/calls/ntcontext2linux.c b/libc/calls/ntcontext2linux.c new file mode 100644 index 00000000..c5ce7337 --- /dev/null +++ b/libc/calls/ntcontext2linux.c @@ -0,0 +1,52 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/ucontext.h" +#include "libc/nt/struct/context.h" +#include "libc/str/str.h" + +textwindows void ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) { + if (!cr) return; + ctx->uc_flags = cr->EFlags; + ctx->uc_mcontext.rax = cr->Rax; + ctx->uc_mcontext.rbx = cr->Rbx; + ctx->uc_mcontext.rcx = cr->Rcx; + ctx->uc_mcontext.rdx = cr->Rdx; + ctx->uc_mcontext.rdi = cr->Rdi; + ctx->uc_mcontext.rsi = cr->Rsi; + ctx->uc_mcontext.rbp = cr->Rbp; + ctx->uc_mcontext.rsp = cr->Rsp; + ctx->uc_mcontext.rip = cr->Rip; + ctx->uc_mcontext.cs = cr->SegCs; + ctx->uc_mcontext.gs = cr->SegGs; + ctx->uc_mcontext.fs = cr->SegFs; + ctx->uc_mcontext.fpregs = &ctx->fpustate; + ctx->fpustate.cwd = cr->FltSave.ControlWord; + ctx->fpustate.swd = cr->FltSave.StatusWord; + ctx->fpustate.mxcsr = cr->FltSave.MxCsr; + ctx->fpustate.mxcr_mask = cr->FltSave.MxCsr_Mask; + /* copy r8,r9,r10,r11,r12,r13,r15 */ + memcpy(&ctx->uc_mcontext.r8, &cr->R8, 8 * sizeof(int64_t)); + /* copy st0-st7 as well as xmm0-xmm15 */ + memcpy(ctx->fpustate.st, &cr->FltSave.FloatRegisters, + sizeof(ctx->fpustate.st) + sizeof(ctx->fpustate.xmm)); + memcpy(ctx->fpustate.st, &cr->FltSave.FloatRegisters, + sizeof(ctx->fpustate.st) + sizeof(ctx->fpustate.xmm)); +} diff --git a/libc/calls/ntmagicpaths.c b/libc/calls/ntmagicpaths.c new file mode 100644 index 00000000..666409f1 --- /dev/null +++ b/libc/calls/ntmagicpaths.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/ntmagicpaths.h" + +const struct NtMagicPaths kNtMagicPaths = { +#define TAB(NAME, STRING) STRING, +#include "libc/calls/ntmagicpaths.inc" +#undef TAB +}; diff --git a/libc/calls/ntmagicpaths.h b/libc/calls/ntmagicpaths.h new file mode 100644 index 00000000..20b2be0f --- /dev/null +++ b/libc/calls/ntmagicpaths.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_NTMAGICPATHS_H_ +#define COSMOPOLITAN_LIBC_CALLS_NTMAGICPATHS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtMagicPaths { +#define TAB(NAME, STRING) char NAME[sizeof(STRING)]; +#include "libc/calls/ntmagicpaths.inc" +#undef TAB +}; + +extern const struct NtMagicPaths kNtMagicPaths; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_NTMAGICPATHS_H_ */ diff --git a/libc/calls/ntmagicpaths.inc b/libc/calls/ntmagicpaths.inc new file mode 100644 index 00000000..e052ccf0 --- /dev/null +++ b/libc/calls/ntmagicpaths.inc @@ -0,0 +1,7 @@ +TAB(devtty, "/dev/tty") +TAB(devnull, "/dev/null") +TAB(devstdin, "/dev/stdin") +TAB(devstdout, "/dev/stdout") +TAB(nul, "NUL") +TAB(conin, "CONIN$") +TAB(conout, "CONOUT$") diff --git a/libc/calls/ntreturn.c b/libc/calls/ntreturn.c new file mode 100644 index 00000000..241e27e4 --- /dev/null +++ b/libc/calls/ntreturn.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/errno.h" +#include "libc/nt/errors.h" +#include "libc/nt/ntdll.h" +#include "libc/calls/internal.h" + +/** + * Exitpoint for Windows NT system calls. + */ +textwindows int64_t ntreturn(uint32_t status) { + if (NtSuccess(status)) { + return 0; + } else { + errno = NtFacilityCode(status); + return -1; + } +} diff --git a/libc/calls/ntsetprivilege.c b/libc/calls/ntsetprivilege.c new file mode 100644 index 00000000..ede094ea --- /dev/null +++ b/libc/calls/ntsetprivilege.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/nt/privilege.h" +#include "libc/nt/struct/tokenprivileges.h" +#include "libc/calls/internal.h" + +/** + * Sets NT permission thing, e.g. + * + * int64_t htoken; + * if (OpenProcessToken(GetCurrentProcess(), + * kNtTokenAdjustPrivileges | kNtTokenQuery, &htoken)) { + * ntsetprivilege(htoken, u"SeManageVolumePrivilege", kNtSePrivilegeEnabled); + * CloseHandle(htoken); + * } + */ +textwindows bool32 ntsetprivilege(int64_t token, const char16_t *name, + uint32_t attrs) { + struct NtTokenPrivileges tp; + tp.PrivilegeCount = 1; + tp.Privileges[0].Attributes = attrs; + return LookupPrivilegeValue(NULL, name, &tp.Privileges[0].Luid) && + AdjustTokenPrivileges(token, false, &tp, + sizeof(struct NtTokenPrivileges), NULL, NULL); +} diff --git a/libc/calls/offset2overlap.c b/libc/calls/offset2overlap.c new file mode 100644 index 00000000..96d472b3 --- /dev/null +++ b/libc/calls/offset2overlap.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/struct/overlapped.h" +#include "libc/str/str.h" + +textwindows struct NtOverlapped *offset2overlap(int64_t opt_offset, + struct NtOverlapped *mem) { + if (opt_offset == -1) return NULL; + memset(mem, 0, sizeof(struct NtOverlapped)); + mem->Pointer = (void *)(uintptr_t)opt_offset; + return mem; +} diff --git a/libc/calls/onntconsoleevent.c b/libc/calls/onntconsoleevent.c new file mode 100644 index 00000000..d64cdcc7 --- /dev/null +++ b/libc/calls/onntconsoleevent.c @@ -0,0 +1,50 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/pushpop.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/siginfo.h" +#include "libc/nt/enum/ctrlevent.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/sig.h" + +textwindows bool32 onntconsoleevent(uint32_t CtrlType) { + int sig; + siginfo_t info; + switch (CtrlType) { + case kNtCtrlCEvent: + sig = pushpop(SIGINT); + break; + case kNtCtrlBreakEvent: + sig = pushpop(SIGQUIT); + break; + case kNtCtrlCloseEvent: + sig = pushpop(SIGHUP); + break; + case kNtCtrlLogoffEvent: + case kNtCtrlShutdownEvent: + sig = pushpop(SIGTERM); + break; + default: + return false; + } + memset(&info, 0, sizeof(info)); + info.si_signo = sig; + return __sigenter(sig, &info, NULL); +} diff --git a/libc/calls/onntconsoleevent_init.S b/libc/calls/onntconsoleevent_init.S new file mode 100644 index 00000000..632d1a59 --- /dev/null +++ b/libc/calls/onntconsoleevent_init.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + + .init.start 300,_init_onntconsoleevent + ezlea onntconsoleevent$nt,cx + pushpop 1,%rdx + ntcall __imp_SetConsoleCtrlHandler + .init.end 300,_init_onntconsoleevent,globl,hidden diff --git a/libc/calls/onwincrash.c b/libc/calls/onwincrash.c new file mode 100644 index 00000000..264c8a69 --- /dev/null +++ b/libc/calls/onwincrash.c @@ -0,0 +1,79 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/struct/siginfo.h" +#include "libc/calls/ucontext.h" +#include "libc/nt/enum/exceptionhandleractions.h" +#include "libc/nt/signals.h" +#include "libc/nt/struct/ntexceptionpointers.h" +#include "libc/nt/struct/ntexceptionrecord.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/sig.h" + +textwindows unsigned onwincrash(struct NtExceptionPointers *ep) { + int sig; + struct Goodies { + ucontext_t ctx; + struct siginfo si; + } g; + switch (ep->ExceptionRecord->ExceptionCode) { + case kNtSignalBreakpoint: + sig = SIGTRAP; + break; + case kNtSignalIllegalInstruction: + case kNtSignalPrivInstruction: + sig = SIGILL; + break; + case kNtSignalGuardPage: + case kNtSignalAccessViolation: + case kNtSignalInPageError: + sig = SIGSEGV; + break; + case kNtSignalInvalidHandle: + case kNtSignalInvalidParameter: + case kNtSignalAssertionFailure: + sig = SIGABRT; + break; + case kNtSignalFltDenormalOperand: + case kNtSignalFltDivideByZero: + case kNtSignalFltInexactResult: + case kNtSignalFltInvalidOperation: + case kNtSignalFltOverflow: + case kNtSignalFltStackCheck: + case kNtSignalFltUnderflow: + case kNtSignalIntegerDivideByZero: + case kNtSignalFloatMultipleFaults: + case kNtSignalFloatMultipleTraps: + sig = SIGFPE; + break; + case kNtSignalDllNotFound: + case kNtSignalOrdinalNotFound: + case kNtSignalEntrypointNotFound: + case kNtSignalDllInitFailed: + sig = SIGSYS; + break; + default: + return kNtExceptionContinueSearch; + } + memset(&g, 0, sizeof(g)); + ntcontext2linux(&g.ctx, ep->ContextRecord); + return __sigenter(sig, &g.si, &g.ctx) ? kNtExceptionContinueExecution + : kNtExceptionContinueSearch; +} diff --git a/libc/calls/onwincrash_init.S b/libc/calls/onwincrash_init.S new file mode 100644 index 00000000..f665defe --- /dev/null +++ b/libc/calls/onwincrash_init.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + + .init.start 300,_init_onwincrash + pushpop 1,%rcx + ezlea onwincrash$nt,dx + ntcall __imp_AddVectoredExceptionHandler + .init.end 300,_init_onwincrash,globl,hidden diff --git a/libc/calls/open-nt.c b/libc/calls/open-nt.c new file mode 100644 index 00000000..7107c8a1 --- /dev/null +++ b/libc/calls/open-nt.c @@ -0,0 +1,120 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/internal.h" +#include "libc/calls/ntmagicpaths.h" +#include "libc/nexgen32e/tinystrcmp.h" +#include "libc/nt/createfile.h" +#include "libc/nt/enum/filetype.h" +#include "libc/nt/enum/fsctl.h" +#include "libc/nt/errors.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/errfuns.h" + +static textwindows int64_t open$nt$impl(const char *file, uint32_t flags, + int32_t mode) { + uint32_t br; + int64_t handle; + char16_t file16[PATH_MAX]; + if (mkntpath2(file, flags, file16) == -1) return -1; + if ((handle = CreateFile( + file16, (flags & 0xf000000f), + (flags & O_EXCL) + ? kNtFileShareExclusive + : kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete, + (flags & O_CLOEXEC) ? &kNtIsInheritable : NULL, + (flags & O_CREAT) && (flags & O_EXCL) + ? kNtCreateNew + : (flags & O_CREAT) && (flags & O_TRUNC) + ? kNtCreateAlways + : (flags & O_CREAT) + ? kNtOpenAlways + : (flags & O_TRUNC) ? kNtTruncateExisting + : kNtOpenExisting, + /* TODO(jart): Should we just always set overlapped? */ + (/* note: content indexer demolishes unix-ey i/o performance */ + kNtFileAttributeNotContentIndexed | kNtFileAttributeNormal | + (((flags & ((kNtFileFlagWriteThrough | kNtFileFlagOverlapped | + kNtFileFlagNoBuffering | kNtFileFlagRandomAccess) >> + 8)) + << 8) | + (flags & (kNtFileFlagSequentialScan | kNtFileFlagDeleteOnClose | + kNtFileFlagBackupSemantics | kNtFileFlagPosixSemantics | + kNtFileAttributeTemporary)))), + 0)) != -1) { + if (flags & O_SPARSE) { + /* + * TODO(jart): Can all files be sparse files? That seems to be the + * way Linux behaves out of the box. + * TODO(jart): Wow why does sparse wreak havoc? + */ + DeviceIoControl(handle, kNtFsctlSetSparse, NULL, 0, NULL, 0, &br, NULL); + } + } + return handle; +} + +static textwindows ssize_t open$nt$console(const struct NtMagicPaths *mp, + uint32_t flags, int32_t mode, + size_t fd) { + if (GetFileType(g_fds.p[STDIN_FILENO].handle) == kNtFileTypeChar && + GetFileType(g_fds.p[STDOUT_FILENO].handle) == kNtFileTypeChar) { + g_fds.p[fd].handle = g_fds.p[STDIN_FILENO].handle; + g_fds.p[fd].extra = g_fds.p[STDOUT_FILENO].handle; + } else if ((g_fds.p[fd].handle = open$nt$impl( + mp->conin, (flags & ~O_ACCMODE) | O_RDONLY, mode)) != -1) { + g_fds.p[fd].extra = + open$nt$impl(mp->conout, (flags & ~O_ACCMODE) | O_WRONLY, mode); + assert(g_fds.p[fd].extra != -1); + } else { + return winerr(); + } + g_fds.p[fd].kind = kFdConsole; + g_fds.p[fd].flags = flags; + return fd; +} + +static textwindows ssize_t open$nt$file(const char *file, uint32_t flags, + int32_t mode, size_t fd) { + if ((g_fds.p[fd].handle = open$nt$impl(file, flags, mode)) != -1) { + g_fds.p[fd].kind = kFdFile; + g_fds.p[fd].flags = flags; + return fd; + } else if (GetLastError() == kNtErrorFileExists && + ((flags & O_CREAT) && (flags & O_TRUNC))) { + return eisdir(); + } else { + return winerr(); + } +} + +textwindows ssize_t open$nt(const char *file, uint32_t flags, int32_t mode) { + size_t fd; + if ((fd = createfd()) == -1) return -1; + if ((flags & O_ACCMODE) == O_RDWR && + tinystrcmp(file, kNtMagicPaths.devtty) == 0) { + return open$nt$console(&kNtMagicPaths, flags, mode, fd); + } else { + return open$nt$file(file, flags, mode, fd); + } +} diff --git a/libc/calls/open.c b/libc/calls/open.c new file mode 100644 index 00000000..040c154a --- /dev/null +++ b/libc/calls/open.c @@ -0,0 +1,55 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/at.h" +#include "libc/sysv/errfuns.h" +#include "libc/zipos/zipos.h" + +/** + * Opens file. + * + * @param file is a UTF-8 string, preferably relative w/ forward slashes + * @param flags should be O_RDONLY, O_WRONLY, or O_RDWR, and can be or'd + * with O_CREAT, O_TRUNC, O_APPEND, O_EXCL, O_CLOEXEC, O_TMPFILE + * @param mode is an octal user/group/other permission signifier, that's + * ignored if O_CREAT or O_TMPFILE weren't passed + * @return number needing close(), or -1 w/ errno + * @asyncsignalsafe + */ +nodiscard int open(const char *file, int flags, ...) { + va_list va; + unsigned mode; + struct ZiposUri zipname; + va_start(va, flags); + mode = va_arg(va, unsigned); + va_end(va); + if (!file) return efault(); + if (weaken(__zipos_open) && weaken(__zipos_parseuri)(file, &zipname) != -1) { + return weaken(__zipos_open)(&zipname, flags, mode); + } else if (!IsWindows()) { + return openat$sysv(AT_FDCWD, file, flags, mode); + } else { + return open$nt(file, flags, mode); + } +} diff --git a/libc/calls/openanon.c b/libc/calls/openanon.c new file mode 100644 index 00000000..77ee127e --- /dev/null +++ b/libc/calls/openanon.c @@ -0,0 +1,96 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/conv/conv.h" +#include "libc/conv/isslash.h" +#include "libc/conv/itoa.h" +#include "libc/dce.h" +#include "libc/nt/createfile.h" +#include "libc/nt/enum/creationdisposition.h" +#include "libc/nt/enum/fileflagandattributes.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/at.h" +#include "libc/sysv/consts/o.h" + +static struct OpenAnon { int count; } g_openanon; + +static void openanon$genpath(const char *name, struct OpenAnon *state, + char pathbuf[hasatleast PATH_MAX]) { + char c; + size_t i; + char *p, *pe; + p = stpcpy(pathbuf, kTmpPath); + pe = pathbuf + PATH_MAX - 8 - 10 - 1 - 10 - 1; + if (!name) name = "openanon"; + for (i = 0; p < pe; ++i) { + if (!(c = name[i])) break; + if (isslash(c)) c = '_'; + *p++ = c; + } + *p++ = '.'; + p += uint64toarray_radix10(getpid(), p); + *p++ = '.'; + p += uint64toarray_radix10(++state->count, p); + *p = '\0'; + assert(p < pe); +} + +static int openanon$impl(const char *name, unsigned flags, + struct OpenAnon *state, + char pathbuf[hasatleast PATH_MAX]) { + int fd; + openanon$genpath(name, state, pathbuf); + if (!IsWindows()) { + flags |= O_RDWR | O_CREAT | O_EXCL | O_TRUNC; + if ((fd = openat$sysv(AT_FDCWD, pathbuf, flags, 0600)) != -1) { + unlink(pathbuf); + } + return fd; + } else { + if ((fd = createfd()) != -1 && + (g_fds.p[fd].handle = CreateFileA( + pathbuf, kNtGenericRead | kNtGenericWrite, kNtFileShareExclusive, + (flags & O_CLOEXEC) ? &kNtIsInheritable : NULL, kNtCreateAlways, + (kNtFileAttributeNotContentIndexed | kNtFileAttributeNormal | + kNtFileAttributeTemporary | kNtFileFlagDeleteOnClose), + 0)) != -1) { + g_fds.p[fd].kind = kFdFile; + return fd; + } else { + return winerr(); + } + } +} + +/** + * Creates anonymous file. + * + * @param name is purely informative + * @param flags can have O_CLOEXEC + * @return fd of file with no name, needing close(), or -1 w/ errno + * @see memfd_create() if disk-paranoid + * @see mkostempsm() for named files + */ +int openanon(char *name, unsigned flags) { + char pathbuf[PATH_MAX]; + return openanon$impl(name, flags, &g_openanon, pathbuf); +} diff --git a/libc/calls/openbsd.h b/libc/calls/openbsd.h new file mode 100644 index 00000000..bb8a43aa --- /dev/null +++ b/libc/calls/openbsd.h @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#ifndef COSMOPOLITAN_LIBC_COMPAT_OPENBSD_H_ +#define COSMOPOLITAN_LIBC_COMPAT_OPENBSD_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § system calls » openbsd ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +typedef unsigned char u_char; + +int pledge(const char *promises, const char *execpromises); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_COMPAT_OPENBSD_H_ */ diff --git a/libc/calls/openpty.c b/libc/calls/openpty.c new file mode 100644 index 00000000..cf0a2d25 --- /dev/null +++ b/libc/calls/openpty.c @@ -0,0 +1,50 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/termios.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/pty.h" +#include "libc/sysv/errfuns.h" + +/** + * Opens new pseudo teletypewriter. + * + * @param ilduce receives controlling tty rw fd on success + * @param aworker receives subordinate tty rw fd on success + * @param termp may be passed to tune a century of legacy behaviors + * @param winp may be passed to set terminal display dimensions + * @params flags is usually O_RDWR|O_NOCTTY + * @return file descriptor, or -1 w/ errno + */ +int openpty(int *ilduce, int *aworker, char *name, const struct termios *termp, + const struct winsize *winp) { + return enosys(); + /* TODO(jart) */ + /* int fd, flags; */ + /* flags = O_RDWR | O_NOCTTY; */ + /* if ((fd = posix_openpt(flags)) != -1) { */ + /* if (ioctl(m, TIOCSPTLCK, &n) || ioctl(m, TIOCGPTN, &n)) { */ + /* } else { */ + /* close(fd); */ + /* } */ + /* } else { */ + /* return -1; */ + /* } */ +} diff --git a/libc/calls/pause.c b/libc/calls/pause.c new file mode 100644 index 00000000..5ab9261c --- /dev/null +++ b/libc/calls/pause.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/sigset.h" +#include "libc/errno.h" +#include "libc/sysv/consts/sig.h" + +/** + * Waits for signal. + * + * @return should be -1 w/ EINTR + * @see sigsuspend() + */ +int pause(void) { + int rc, olderr; + sigset_t oldmask; + olderr = errno; + rc = pause$sysv(); + if (rc == -1 && errno == ENOSYS) { + errno = olderr; + if (sigprocmask(SIG_BLOCK, NULL, &oldmask) == -1) return -1; + rc = sigsuspend(&oldmask); + } + return rc; +} diff --git a/libc/calls/pipe-nt.c b/libc/calls/pipe-nt.c new file mode 100644 index 00000000..3c5d9da0 --- /dev/null +++ b/libc/calls/pipe-nt.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/ipc.h" +#include "libc/nt/runtime.h" +#include "libc/sysv/consts/o.h" + +textwindows int pipe$nt(int pipefd[2], unsigned flags) { + int reader, writer; + if ((reader = createfd()) == -1) return -1; + if ((writer = createfd()) == -1) return -1; + if (CreatePipe(&g_fds.p[reader].handle, &g_fds.p[writer].handle, + (flags & O_CLOEXEC) ? NULL : &kNtIsInheritable, + 0 /* let NT pick buffer size */)) { + g_fds.p[reader].kind = kFdFile; + g_fds.p[reader].flags = flags; + g_fds.p[writer].kind = kFdFile; + g_fds.p[writer].flags = flags; + pipefd[0] = reader; + pipefd[1] = writer; + return 0; + } else { + return winerr(); + } +} diff --git a/libc/calls/pipe-sysv.S b/libc/calls/pipe-sysv.S new file mode 100644 index 00000000..ecdb6eda --- /dev/null +++ b/libc/calls/pipe-sysv.S @@ -0,0 +1,47 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/macros.h" +.yoink __FILE__ + +/ Creates file descriptors for IPC. +/ +/ @param rdi points to int3[2] that gets (reader, writer) +/ @return 0 on success or -1 w/ errno +/ @asyncsignalsafe +/ @see libc/sysv/syscalls.sh +/ @see pipe2() +pipe$sysv: + push %rbp + mov %rsp,%rbp + xor %esi,%esi # FreeBSD is pipe2() + call __pipe$sysv +#if SupportsXnu() + testb IsXnu() # XNU has special needs + jz 1f + cmp $-1,%eax + je 1f + mov %eax,(%rdi) + mov %edx,4(%rdi) + xor %eax,%eax +#endif +1: pop %rbp + ret + .endfn pipe$sysv,globl,hidden diff --git a/libc/calls/pipe.c b/libc/calls/pipe.c new file mode 100644 index 00000000..d7e76ab8 --- /dev/null +++ b/libc/calls/pipe.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" + +/** + * Creates file-less file descriptors for inter-process communication. + * + * @param fd is (reader, writer) + * @return 0 on success or -1 w/ errno + * @asyncsignalsafe + * @see pipe2() + */ +int pipe(int pipefd[hasatleast 2]) { + if (!IsWindows()) { + return pipe$sysv(pipefd); + } else { + return pipe$nt(pipefd, 0); + } +} diff --git a/libc/calls/pipe2-sysv.c b/libc/calls/pipe2-sysv.c new file mode 100644 index 00000000..9e12a01d --- /dev/null +++ b/libc/calls/pipe2-sysv.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/errno.h" + +#define __NR_pipe2_linux 0x0125 /*RHEL5:CVE-2010-3301*/ + +int32_t pipe2$sysv(int pipefd[hasatleast 2], unsigned flags) { + int rc, olderr; + if (!flags) goto OldSkool; + olderr = errno; + rc = __pipe2$sysv(pipefd, flags); + if ((rc == -1 && errno == ENOSYS) || + (SupportsLinux() && rc == __NR_pipe2_linux)) { + errno = olderr; + OldSkool: + if ((rc = pipe$sysv(pipefd)) != -1) { + fixupnewfd$sysv(pipefd[0], flags); + fixupnewfd$sysv(pipefd[1], flags); + } + } + return rc; +} diff --git a/libc/calls/pipe2.c b/libc/calls/pipe2.c new file mode 100644 index 00000000..f53f147a --- /dev/null +++ b/libc/calls/pipe2.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" + +/** + * Creates file-less file descriptors for interprocess communication. + * + * @param pipefd is used to return (reader, writer) file descriptors + * @param flags can have O_CLOEXEC, O_NONBLOCK, O_DIRECT + * @return 0 on success, or -1 w/ errno and pipefd isn't modified + */ +int pipe2(int pipefd[hasatleast 2], int flags) { + if (!IsWindows()) { + return pipe2$sysv(pipefd, flags); + } else { + return pipe$nt(pipefd, flags); + } +} diff --git a/libc/calls/posix_fadvise.c b/libc/calls/posix_fadvise.c new file mode 100644 index 00000000..df2e62f2 --- /dev/null +++ b/libc/calls/posix_fadvise.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" + +int(posix_fadvise)(int fd, uint64_t offset, uint64_t len, int advice) { + return fadvise(fd, offset, len, advice); +} diff --git a/libc/calls/posix_fallocate.c b/libc/calls/posix_fallocate.c new file mode 100644 index 00000000..e339b78f --- /dev/null +++ b/libc/calls/posix_fallocate.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/dce.h" +#include "libc/sysv/errfuns.h" + +/** + * Manipulates underlying physical medium of file, the POSIX way. + * + * @param fd must be open for writing + * @param length is how much physical space to reserve + * @return 0 on success, or -1 w/ errno + * @see fallocate(), ftruncate() + */ +int posix_fallocate(int fd, int64_t offset, int64_t length) { + return fallocate(fd, 0, offset, length); +} diff --git a/libc/calls/posix_madvise.c b/libc/calls/posix_madvise.c new file mode 100644 index 00000000..2b8e1f68 --- /dev/null +++ b/libc/calls/posix_madvise.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" + +int posix_madvise(void *addr, uint64_t len, int advice) { + return madvise(addr, len, advice); +} diff --git a/libc/calls/posix_openpt.c b/libc/calls/posix_openpt.c new file mode 100644 index 00000000..34b6c448 --- /dev/null +++ b/libc/calls/posix_openpt.c @@ -0,0 +1,57 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/termios.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/pty.h" +#include "libc/sysv/consts/termios.h" +#include "libc/sysv/errfuns.h" + +/** + * Opens new pseudo teletypewriter. + * + * @params flags is usually O_RDWR|O_NOCTTY + * @return file descriptor, or -1 w/ errno + */ +int posix_openpt(int flags) { + int fd, ilduce; + struct IoctlPtmGet ptm; + if ((flags & O_ACCMODE) != O_RDWR) return einval(); + if (SupportsFreebsd() && + ((fd = posix_openpt$sysv(flags)) != -1 || errno != ENOSYS)) { + return fd; + } else if ((fd = open("/dev/ptmx", flags)) != -1 || errno != ENOENT) { + return fd; + } else if (SupportsOpenbsd() && + ((fd = open("/dev/ptm", flags)) != -1 || errno != ENOENT)) { + if (ioctl(fd, PTMGET, &ptm) != -1) { + close(ptm.workerfd); + ilduce = ptm.theduxfd; + } else { + ilduce = -1; + } + close(fd); + return ilduce; + } else { + return enosys(); + } +} diff --git a/libc/calls/pread.c b/libc/calls/pread.c new file mode 100644 index 00000000..a7b21961 --- /dev/null +++ b/libc/calls/pread.c @@ -0,0 +1,58 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/macros.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/errfuns.h" +#include "libc/zipos/zipos.h" + +/** + * Reads from file at offset, thus avoiding superfluous lseek(). + * + * @param fd is something open()'d earlier, noting pipes might not work + * @param buf is copied into, cf. copy_file_range(), sendfile(), etc. + * @param size in range [1..0x7ffff000] is reasonable + * @param offset is bytes from start of file at which read begins + * @return [1..size] bytes on success, 0 on EOF, or -1 w/ errno; with + * exception of size==0, in which case return zero means no error + * @see pwrite(), write() + */ +ssize_t pread(int fd, void *buf, size_t size, int64_t offset) { + ssize_t rc; + if (fd == -1 || offset < 0) return einval(); + if (isfdkind(fd, kFdZip)) { + rc = weaken(__zipos_read)( + (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, buf, size, offset); + } else if (!IsWindows()) { + rc = pread$sysv(fd, buf, size, offset); + } else if (isfdkind(fd, kFdFile)) { + rc = read$nt(&g_fds.p[fd], buf, size, offset); + } else { + rc = ebadf(); + } + if (!IsTrustworthy() && rc != -1) { + if ((size_t)rc > size) abort(); + } + return rc; +} diff --git a/libc/calls/preadv.c b/libc/calls/preadv.c new file mode 100644 index 00000000..a6366078 --- /dev/null +++ b/libc/calls/preadv.c @@ -0,0 +1,77 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/sysv/consts/iov.h" +#include "libc/sysv/errfuns.h" + +#define __NR_preadv_linux 0x0127 + +/** + * Reads data from multiple buffers from file descriptor at offset. + * + * @param count is recommended to be 16 or fewer; if it exceeds IOV_MAX + * then the extra buffers are simply ignored + * @return number of bytes actually read, or -1 w/ errno + */ +ssize_t preadv(int fd, struct iovec *iovec, int count, int64_t off) { + static bool once, demodernize; + int olderr; + ssize_t rc; + if (!count) return 0; + if ((count = min(count, IOV_MAX)) < 0) return einval(); + + /* + * NT, XNU, and 2007-era Linux don't support this system call. + */ + if (!once) { + once = true; + if (IsLinux() && iovec->iov_len >= __NR_preadv_linux) { + /* + * Read size is too large to detect older kernels safely without + * introducing nontrivial mechanics. We'll try again later. + */ + once = false; + demodernize = true; + } else { + olderr = errno; + rc = preadv$sysv(fd, iovec, count, off); + if (rc == -1 && errno == ENOSYS) { + errno = olderr; + demodernize = true; + } else if (IsLinux() && rc == __NR_preadv_linux /*RHEL5:CVE-2010-3301*/) { + demodernize = true; + } else { + return rc; + } + } + } + + if (!demodernize) { + return preadv$sysv(fd, iovec, count, off); + } else { + return pread(fd, iovec[0].iov_base, iovec[0].iov_len, off); + } +} diff --git a/libc/calls/prot2nt.greg.c b/libc/calls/prot2nt.greg.c new file mode 100644 index 00000000..9ff38b52 --- /dev/null +++ b/libc/calls/prot2nt.greg.c @@ -0,0 +1,50 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/enum/pageflags.h" +#include "libc/nt/memory.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" + +#define HAS(X, BITS) (((X) & (BITS)) == (BITS)) + +/** + * Converts System Five memory protection flags to Windows NT, Part 1. + * @see libc/sysv/consts.sh + */ +privileged uint32_t prot2nt(int prot, int flags) { + return (HAS(prot, PROT_READ | PROT_WRITE | PROT_EXEC) + ? (HAS(flags, MAP_SHARED) || HAS(flags, MAP_ANONYMOUS)) + ? kNtPageExecuteReadwrite + : kNtPageExecuteWritecopy + : HAS(prot, PROT_READ | PROT_WRITE) + ? (HAS(flags, MAP_SHARED) || HAS(flags, MAP_ANONYMOUS)) + ? kNtPageReadwrite + : kNtPageWritecopy + : HAS(prot, PROT_READ | PROT_EXEC) + ? kNtPageExecuteRead + : HAS(prot, PROT_EXEC) + ? kNtPageExecute + : HAS(prot, PROT_READ) ? kNtPageReadonly + : kNtPageNoaccess) | + ((prot | flags) & + (kNtSecReserve | kNtSecCommit | kNtSecImage | kNtSecImageNoExecute | + kNtSecLargePages | kNtSecNocache | kNtSecWritecombine)); +} diff --git a/libc/calls/ptsname.c b/libc/calls/ptsname.c new file mode 100644 index 00000000..04ec0046 --- /dev/null +++ b/libc/calls/ptsname.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/termios.h" + +static char g_ptsname[32]; + +char *ptsname(int fd) { + return ptsname_r(fd, g_ptsname, sizeof(g_ptsname)) ? g_ptsname : NULL; +} diff --git a/libc/calls/ptsname_r.c b/libc/calls/ptsname_r.c new file mode 100644 index 00000000..8a2ec60f --- /dev/null +++ b/libc/calls/ptsname_r.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/termios.h" +#include "libc/errno.h" +#include "libc/fmt/fmt.h" +#include "libc/sysv/consts/termios.h" +#include "libc/sysv/errfuns.h" + +errno_t ptsname_r(int fd, char *buf, size_t size) { + int pty; + if (size) { + if (!buf) return einval(); + if (ioctl(fd, TIOCGPTN, &pty) == -1) return errno; + if (snprintf(buf, size, "/dev/pts/%d", pty) >= size) { + return (errno = ERANGE); + } + /* TODO(jart): OpenBSD OMG */ + } + return 0; +} diff --git a/libc/calls/pwrite.c b/libc/calls/pwrite.c new file mode 100644 index 00000000..bb4923b7 --- /dev/null +++ b/libc/calls/pwrite.c @@ -0,0 +1,60 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/dce.h" +#include "libc/macros.h" +#include "libc/sysv/errfuns.h" + +/** + * Writes to file at offset, thus avoiding superfluous lseek(). + * + * @param fd is something open()'d earlier, noting pipes might not work + * @param buf is copied from, cf. copy_file_range(), sendfile(), etc. + * @param size in range [1..0x7ffff000] is reasonable + * @param offset is bytes from start of file at which write begins + * @return [1..size] bytes on success, or -1 w/ errno; noting zero is + * impossible unless size was passed as zero to do an error check + * @see pread(), write() + */ +ssize_t pwrite(int fd, const void *buf, size_t size, int64_t offset) { + ssize_t rc; + size_t wrote; + if (fd == -1 || offset < 0) return einval(); + size = MIN(size, 0x7ffff000); + if (!IsWindows()) { + rc = pwrite$sysv(fd, buf, size, offset); + } else if (isfdkind(fd, kFdFile)) { + rc = write$nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, offset); + } else { + return ebadf(); + } + if (rc != -1) { + wrote = (size_t)rc; + if (wrote == 0) { + assert(size == 0); + } else { + assert(wrote <= size); + } + } + return rc; +} diff --git a/libc/calls/pwritev.c b/libc/calls/pwritev.c new file mode 100644 index 00000000..8617a553 --- /dev/null +++ b/libc/calls/pwritev.c @@ -0,0 +1,78 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/sysv/consts/iov.h" +#include "libc/sysv/errfuns.h" + +#define __NR_pwritev_linux 0x0128 + +/** + * Writes data from multiple buffers to file descriptor at offset. + * + * @param count is recommended to be 16 or fewer; if it exceeds IOV_MAX + * then the extra buffers are simply ignored + * @return number of bytes actually sent, or -1 w/ errno + */ +ssize_t pwritev(int fd, const struct iovec *iovec, int count, int64_t off) { + static bool once, demodernize; + int olderr; + ssize_t rc; + + if (!count) return 0; + if ((count = min(count, IOV_MAX)) < 0) return einval(); + + /* + * NT, XNU, and 2007-era Linux don't support this system call. + */ + if (!once) { + once = true; + if (IsLinux() && iovec->iov_len >= __NR_pwritev_linux) { + /* + * Write size is too large to detect older kernels safely without + * introducing nontrivial mechanics. We'll try again later. + */ + once = false; + demodernize = true; + } else { + olderr = errno; + rc = pwritev$sysv(fd, iovec, count, off); + if (rc == -1 && errno == ENOSYS) { + errno = olderr; + demodernize = true; + } else if (IsLinux() && + rc == __NR_pwritev_linux /*RHEL5:CVE-2010-3301*/) { + demodernize = true; + } else { + return rc; + } + } + } + + if (!demodernize) { + return pwritev$sysv(fd, iovec, count, off); + } else { + return pwrite(fd, iovec[0].iov_base, iovec[0].iov_len, off); + } +} diff --git a/libc/calls/raise.c b/libc/calls/raise.c new file mode 100644 index 00000000..82606810 --- /dev/null +++ b/libc/calls/raise.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/runtime/missioncritical.h" + +/** + * Sends signal to this process. + * + * @param sig can be SIGALRM, SIGINT, SIGTERM, SIGKILL, etc. + * @return 0 on success or -1 w/ errno + * @asyncsignalsafe + */ +int raise(int sig) { return RAISE(sig); } diff --git a/libc/calls/read-nt.c b/libc/calls/read-nt.c new file mode 100644 index 00000000..ddf9d684 --- /dev/null +++ b/libc/calls/read-nt.c @@ -0,0 +1,45 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/errno.h" +#include "libc/limits.h" +#include "libc/nt/errors.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/overlapped.h" +#include "libc/nt/struct/teb.h" +#include "libc/sysv/errfuns.h" + +textwindows ssize_t read$nt(struct Fd *fd, const struct iovec *iov, + size_t iovlen, ssize_t opt_offset) { + uint32_t got; + struct NtOverlapped overlap; + while (iovlen && !iov[0].iov_len) iov++, iovlen--; + if (ReadFile(fd->handle, iovlen ? iov[0].iov_base : NULL, + iovlen ? clampio(iov[0].iov_len) : 0, &got, + offset2overlap(opt_offset, &overlap))) { + return got; + } else if (NtGetErr() == kNtErrorBrokenPipe) { + return 0; /* read() doesn't EPIPE lool */ + } else { + return winerr(); + } +} diff --git a/libc/calls/read.c b/libc/calls/read.c new file mode 100644 index 00000000..8f7c34e4 --- /dev/null +++ b/libc/calls/read.c @@ -0,0 +1,64 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/dce.h" +#include "libc/macros.h" +#include "libc/runtime/runtime.h" +#include "libc/sock/internal.h" +#include "libc/sysv/errfuns.h" +#include "libc/zipos/zipos.h" + +/** + * Reads data from file descriptor. + * + * @param fd is something open()'d earlier + * @param buf is copied into, cf. copy_file_range(), sendfile(), etc. + * @param size in range [1..0x7ffff000] is reasonable + * @return [1..size] bytes on success, 0 on EOF, or -1 w/ errno; with + * exception of size==0, in which case return zero means no error + * @see write(), pread(), readv() + * @asyncsignalsafe + */ +ssize_t read(int fd, void *buf, size_t size) { + ssize_t rc; + if (fd == -1) return einval(); + if (isfdkind(fd, kFdZip)) { + rc = + weaken(__zipos_read)((struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, + (struct iovec[]){{buf, size}}, 1, -1); + } else if (!IsWindows()) { + rc = read$sysv(fd, buf, size); + } else if (isfdkind(fd, kFdFile) || isfdkind(fd, kFdConsole)) { + rc = read$nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, -1); + } else if (isfdkind(fd, kFdSocket)) { + rc = weaken(recvfrom$nt)(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, 0, + NULL, NULL); + } else { + rc = ebadf(); + } + if (!IsTrustworthy() && rc != -1) { + if ((size_t)rc > size) abort(); + } + return rc; +} diff --git a/libc/calls/readv.c b/libc/calls/readv.c new file mode 100644 index 00000000..da64fd5f --- /dev/null +++ b/libc/calls/readv.c @@ -0,0 +1,50 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/sock/internal.h" +#include "libc/sysv/errfuns.h" +#include "libc/zipos/zipos.h" + +/** + * Reads data to multiple buffers. + * + * @return number of bytes actually read, or -1 w/ errno + */ +ssize_t readv(int fd, const struct iovec *iov, int iovlen) { + if (!IsTrustworthy()) { + if (fd == -1) return einval(); + if (iovlen < 0) return einval(); + } + if (isfdkind(fd, kFdZip)) { + return weaken(__zipos_read)( + (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1); + } + if (!IsWindows()) { + return readv$sysv(fd, iov, iovlen); + } else if (isfdkind(fd, kFdFile) || isfdkind(fd, kFdConsole)) { + return read$nt(&g_fds.p[fd], iov, iovlen, -1); + } else if (isfdkind(fd, kFdSocket)) { + return weaken(recvfrom$nt)(&g_fds.p[fd], iov, iovlen, 0, NULL, 0); + } else { + return ebadf(); + } +} diff --git a/libc/calls/realpath.c b/libc/calls/realpath.c new file mode 100644 index 00000000..eef07a45 --- /dev/null +++ b/libc/calls/realpath.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/sysv/errfuns.h" + +char *realpath(const char *path, char *resolved_path) { + enotsup(); + return NULL; +} diff --git a/libc/calls/remove.c b/libc/calls/remove.c new file mode 100644 index 00000000..ead1d7f8 --- /dev/null +++ b/libc/calls/remove.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/errno.h" +#include "libc/calls/calls.h" + +/** + * Deletes "file" or empty directory associtaed with name. + * + * @return 0 on success or -1 w/ errno + * @see unlink() and rmdir() which this abstracts + */ +int remove(const char *name) { + return unlink(name) != -1 || (errno == EISDIR && rmdir(name) != -1) ? 0 : -1; +} diff --git a/libc/calls/removefd.c b/libc/calls/removefd.c new file mode 100644 index 00000000..988024eb --- /dev/null +++ b/libc/calls/removefd.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/calls/internal.h" + +void removefd(int fd) { + if (isfdindex(fd)) { + g_fds.p[fd].kind = kFdEmpty; + g_fds.f = min(g_fds.f, fd); + } +} diff --git a/libc/calls/rename-nt.c b/libc/calls/rename-nt.c new file mode 100644 index 00000000..12c97f7e --- /dev/null +++ b/libc/calls/rename-nt.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +textwindows int rename$nt(const char *oldpath, const char *newpath) { + char16_t oldpath16[PATH_MAX]; + char16_t newpath16[PATH_MAX]; + if (mkntpath(oldpath, oldpath16) == -1 || + mkntpath(newpath, newpath16) == -1) { + return -1; + } + if (MoveFileEx(oldpath16, newpath16, kNtMovefileReplaceExisting)) { + return 0; + } else { + return winerr(); + } +} diff --git a/libc/calls/rename.c b/libc/calls/rename.c new file mode 100644 index 00000000..003c6917 --- /dev/null +++ b/libc/calls/rename.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/calls/internal.h" +#include "libc/calls/calls.h" +#include "libc/sysv/consts/at.h" + +/** + * Moves file the Unix way. + * @return 0 on success or -1 w/ errno + * @asyncsignalsafe + */ +int rename(const char *oldpathname, const char *newpathname) { + if (!IsWindows()) { + return renameat$sysv(AT_FDCWD, oldpathname, AT_FDCWD, newpathname); + } else { + return rename$nt(oldpathname, newpathname); + } +} diff --git a/libc/calls/rmdir-nt.c b/libc/calls/rmdir-nt.c new file mode 100644 index 00000000..5305ecdc --- /dev/null +++ b/libc/calls/rmdir-nt.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" + +textwindows int rmdir$nt(const char *path) { + uint16_t path16[PATH_MAX]; + if (mkntpath(path, path16) == -1) return -1; + if (RemoveDirectory(path16)) { + return 0; + } else { + return winerr(); + } +} diff --git a/libc/calls/rmdir.c b/libc/calls/rmdir.c new file mode 100644 index 00000000..a3424351 --- /dev/null +++ b/libc/calls/rmdir.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/nt/files.h" +#include "libc/str/str.h" +#include "libc/calls/internal.h" +#include "libc/sysv/errfuns.h" +#include "libc/sysv/consts/at.h" + +/** + * Deletes empty directory. + * + * @return 0 on success or -1 w/ errno on error + */ +int rmdir(const char *path) { + if (!path) return efault(); + if (!IsWindows()) { + return unlinkat$sysv(AT_FDCWD, path, AT_REMOVEDIR); + } else { + return rmdir$nt(path); + } +} diff --git a/libc/calls/sched_setaffinity.c b/libc/calls/sched_setaffinity.c new file mode 100644 index 00000000..e0648127 --- /dev/null +++ b/libc/calls/sched_setaffinity.c @@ -0,0 +1,72 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/limits.h" +#include "libc/nt/process.h" +#include "libc/nt/runtime.h" +#include "libc/nt/thread.h" +#include "libc/str/str.h" + +static textwindows noinline int sched_setaffinity$nt(int pid, + uint64_t bitsetsize, + const void *bitset) { + typeof(SetThreadAffinityMask) *SetAffinityMask = SetThreadAffinityMask; + uintptr_t mask = 0; + memcpy(&mask, bitset, min(bitsetsize, sizeof(uintptr_t))); + int64_t handle = 0; + if (0 < pid && pid <= UINT32_MAX) { + if (pid == GetCurrentProcessId()) { + pid = GetCurrentProcess(); + SetAffinityMask = SetProcessAffinityMask; + } else if (pid == GetCurrentThreadId()) { + pid = GetCurrentThread(); + } else { + handle = OpenThread(kNtThreadSetInformation | kNtThreadQueryInformation, + false, pid); + if (!handle) { + handle = OpenProcess( + kNtProcessSetInformation | kNtProcessQueryInformation, false, pid); + SetAffinityMask = SetProcessAffinityMask; + } + } + } + int rc = SetAffinityMask(handle ? handle : pid, mask) ? 0 : winerr(); + if (handle) CloseHandle(handle); + return rc; +} + +/** + * Asks kernel to only schedule process on particular CPUs. + * + * @param pid is the process or thread id + * @param bitsetsize is byte length of bitset + * @param bitset can be manipulated using bt(), bts(), etc. + * @return 0 on success, or -1 w/ errno + */ +int sched_setaffinity(int pid, uint64_t bitsetsize, const void *bitset) { + if (!IsWindows()) { + return sched_setaffinity$sysv(pid, bitsetsize, bitset); + } else { + return sched_setaffinity$nt(pid, bitsetsize, bitset); + } +} diff --git a/libc/calls/sched_yield-nt.c b/libc/calls/sched_yield-nt.c new file mode 100644 index 00000000..8f8e5626 --- /dev/null +++ b/libc/calls/sched_yield-nt.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/enum/status.h" +#include "libc/nt/ntdll.h" + +textwindows int sched_yield$nt(void) { + size_t i; + if (NtYieldExecution() == kNtStatusDllNotFound) { + for (i = 0; i < 16; ++i) asm("pause"); + } + return 0; +} diff --git a/libc/calls/sched_yield.c b/libc/calls/sched_yield.c new file mode 100644 index 00000000..012eae09 --- /dev/null +++ b/libc/calls/sched_yield.c @@ -0,0 +1,33 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/calls/internal.h" +#include "libc/calls/calls.h" + +/** + * Asks kernel to deschedule thread momentarily. + */ +int sched_yield(void) { + if (!IsWindows()) { + return sched_yield$sysv(); + } else { + return sched_yield$nt(); + } +} diff --git a/libc/calls/setegid.S b/libc/calls/setegid.S new file mode 100644 index 00000000..027f8df6 --- /dev/null +++ b/libc/calls/setegid.S @@ -0,0 +1,34 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Sets effective group ID. +/ +/ @param %edi is group id +/ @see setgid(), getauxval(AT_SECURE) +setegid:push %rbp + mov %rsp,%rbp + mov %edi,%esi + mov $-1,%edi + call setregid + pop %rbp + ret + .endfn setegid,globl diff --git a/libc/calls/seteuid.S b/libc/calls/seteuid.S new file mode 100644 index 00000000..f5fa2220 --- /dev/null +++ b/libc/calls/seteuid.S @@ -0,0 +1,34 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Sets effective user ID. +/ +/ @param %edi is user id +/ @see setuid(), getauxval(AT_SECURE) +seteuid:push %rbp + mov %rsp,%rbp + mov %edi,%esi + mov $-1,%edi + call setreuid + pop %rbp + ret + .endfn seteuid,globl diff --git a/libc/calls/setpriority-nt.c b/libc/calls/setpriority-nt.c new file mode 100644 index 00000000..2779f7e0 --- /dev/null +++ b/libc/calls/setpriority-nt.c @@ -0,0 +1,53 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/calls/internal.h" +#include "libc/calls/kntprioritycombos.h" +#include "libc/nt/process.h" +#include "libc/nt/runtime.h" +#include "libc/nt/thread.h" + +static textwindows struct NtPriorityCombo findntprio(int nice) { + size_t l, r, m; + l = 0; + r = kNtPriorityCombosLen; + while (l < r) { + m = (l + r) >> 1; + if (kNtPriorityCombos[m].nice > nice) { + r = m; + } else { + l = m + 1; + } + } + return kNtPriorityCombos[max(0, l - 1)]; +} + +textwindows int setpriority$nt(int nice) { + uint32_t tier; + struct NtPriorityCombo p; + p = findntprio(nice); + tier = 1 << (p.lg2tier - 1); + if (SetPriorityClass(GetCurrentProcess(), tier) && + SetThreadPriority(GetCurrentThread(), p.wut)) { + return p.nice; + } else { + return winerr(); + } +} diff --git a/libc/calls/setpriority.c b/libc/calls/setpriority.c new file mode 100644 index 00000000..6fdd4c75 --- /dev/null +++ b/libc/calls/setpriority.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" + +/** + * Sets nice value of thing. + * + * @param which can be PRIO_PROCESS, PRIO_PGRP, PRIO_USER + * @param who is the pid, pgid, or uid, 0 meaning current + * @param value ∈ [-NZERO,NZERO) which is clamped automatically + * @return nonzero on success or -1 w/ errno + * @see getpriority(), nice() + */ +int setpriority(int which, unsigned who, int value) { + if (!IsWindows()) { + return setpriority$sysv(which, who, value); /* TODO(jart): -20 */ + } else { + return getsetpriority$nt(which, who, value, setpriority$nt); + } +} diff --git a/libc/calls/setresgid.c b/libc/calls/setresgid.c new file mode 100644 index 00000000..bc27c5b4 --- /dev/null +++ b/libc/calls/setresgid.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" + +/** + * Sets real, effective, and "saved" group ids. + * + * @param real sets real group id or -1 to do nothing + * @param effective sets effective group id or -1 to do nothing + * @param saved sets saved group id or -1 to do nothing + * @see setregid(), getauxval(AT_SECURE) + */ +int setresgid(uint32_t real, uint32_t effective, uint32_t saved) { + if (saved == -1) return setregid(real, effective); + return setresgid$sysv(real, effective, saved); +} diff --git a/libc/calls/setresuid.c b/libc/calls/setresuid.c new file mode 100644 index 00000000..5cbf2cc1 --- /dev/null +++ b/libc/calls/setresuid.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" + +/** + * Sets real, effective, and "saved" user ids. + * + * @param real sets real user id or -1 to do nothing + * @param effective sets effective user id or -1 to do nothing + * @param saved sets saved user id or -1 to do nothing + * @see setreuid(), getauxval(AT_SECURE) + */ +int setresuid(uint32_t real, uint32_t effective, uint32_t saved) { + if (saved == -1) return setreuid(real, effective); + return setresuid$sysv(real, effective, saved); +} diff --git a/libc/calls/setrlimit.c b/libc/calls/setrlimit.c new file mode 100644 index 00000000..a1b378d6 --- /dev/null +++ b/libc/calls/setrlimit.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sysv/errfuns.h" + +/** + * Sets resource limit for current process. + * + * @param resource can be RLIMIT_{CPU,FSIZE,DATA,STACK,CORE,RSS,etc.} + * @param rlim specifies new resource limit + * @return 0 on success or -1 w/ errno + * @see libc/sysv/consts.sh + */ +int setrlimit(int resource, const struct rlimit *rlim) { + if (resource == -1) return einval(); + if (!IsWindows()) { + return setrlimit$sysv(resource, rlim); + } else { + return enosys(); /* TODO(jart): Implement me! */ + } +} diff --git a/libc/calls/sigaction.c b/libc/calls/sigaction.c new file mode 100644 index 00000000..effc4c0c --- /dev/null +++ b/libc/calls/sigaction.c @@ -0,0 +1,222 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/calls/ucontext.h" +#include "libc/dce.h" +#include "libc/limits.h" +#include "libc/macros.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/sa.h" +#include "libc/sysv/consts/sig.h" +#include "libc/sysv/errfuns.h" + +struct siginfo; + +union metasigaction { + struct sigaction cosmo; + + struct sigaction$linux { + intptr_t sa_handler; + uint64_t sa_flags; + void (*sa_restorer)(void); + struct sigset$linux { + uint32_t sig[2]; + } sa_mask; + } linux; + + struct sigaction$freebsd { + intptr_t sa_handler; + uint32_t sa_flags; + struct sigset$freebsd { + uint32_t sig[4]; + } sa_mask; + } freebsd; + + struct sigaction$openbsd { + intptr_t sa_handler; + struct sigset$openbsd { + uint32_t sig[1]; + } sa_mask; + int32_t sa_flags; + } openbsd; + + struct sigaction$xnu_in { + intptr_t sa_handler; + void (*sa_restorer)(void *, int, int, const struct __darwin_siginfo *, + const struct __darwin_ucontext *); + struct sigset$xnu { + uint32_t sig[1]; + } sa_mask; + int32_t sa_flags; + } xnu_in; + + struct sigaction$xnu_out { + intptr_t sa_handler; + struct sigset$xnu sa_mask; + int32_t sa_flags; + } xnu_out; +}; + +#define SWITCHEROO(S1, S2, A, B, C, D) \ + do { \ + autotype((S2).A) a = (typeof((S2).A))(S1).A; \ + autotype((S2).B) b = (typeof((S2).B))(S1).B; \ + autotype((S2).C) c = (typeof((S2).C))(S1).C; \ + typeof((S2).D) d; \ + memset(&d, 0, sizeof(d)); \ + memcpy(&d, &((S1).D), MIN(sizeof(d), sizeof((S1).D))); \ + (S2).A = a; \ + (S2).B = b; \ + (S2).C = c; \ + memset(&((S2).D), 0, sizeof((S2).D)); \ + memcpy(&((S2).D), &d, MIN(sizeof(d), sizeof((S2).D))); \ + } while (0); + +static void sigaction$cosmo2native(union metasigaction *sa) { + if (!sa) return; + switch (hostos) { + case LINUX: + SWITCHEROO(sa->cosmo, sa->linux, sa_handler, sa_flags, sa_restorer, + sa_mask); + break; + case XNU: + SWITCHEROO(sa->cosmo, sa->xnu_in, sa_handler, sa_flags, sa_restorer, + sa_mask); + break; + case FREEBSD: + SWITCHEROO(sa->cosmo, sa->freebsd, sa_handler, sa_flags, sa_flags, + sa_mask); + break; + case OPENBSD: + SWITCHEROO(sa->cosmo, sa->openbsd, sa_handler, sa_flags, sa_flags, + sa_mask); + break; + default: + abort(); + } +} + +static void sigaction$native2cosmo(union metasigaction *sa) { + if (!sa) return; + switch (hostos) { + case LINUX: + SWITCHEROO(sa->linux, sa->cosmo, sa_handler, sa_flags, sa_restorer, + sa_mask); + break; + case XNU: + SWITCHEROO(sa->xnu_out, sa->cosmo, sa_handler, sa_flags, sa_flags, + sa_mask); + break; + case FREEBSD: + SWITCHEROO(sa->freebsd, sa->cosmo, sa_handler, sa_flags, sa_flags, + sa_mask); + break; + case OPENBSD: + SWITCHEROO(sa->openbsd, sa->cosmo, sa_handler, sa_flags, sa_flags, + sa_mask); + break; + default: + abort(); + } +} + +/** + * Installs handler for kernel interrupt, e.g.: + * + * void GotCtrlC(int sig, siginfo_t *si, ucontext_t *ctx); + * struct sigaction sa = {.sa_sigaction = GotCtrlC, + * .sa_flags = SA_RESETHAND|SA_RESTART|SA_SIGINFO}; + * CHECK_NE(-1, sigaction(SIGINT, &sa, NULL)); + * + * @see xsigaction() for a much better api + * @asyncsignalsafe + */ +int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) { + static_assert(sizeof(struct sigaction) > sizeof(struct sigaction$linux) && + sizeof(struct sigaction) > sizeof(struct sigaction$xnu_in) && + sizeof(struct sigaction) > sizeof(struct sigaction$xnu_out) && + sizeof(struct sigaction) > sizeof(struct sigaction$freebsd) && + sizeof(struct sigaction) > sizeof(struct sigaction$openbsd)); + int rc, rva, oldrva; + struct sigaction *ap, copy; + if (!(0 < sig && sig < NSIG) || sig == SIGKILL || sig == SIGSTOP) { + return einval(); + } + if (!act) { + rva = (int32_t)(intptr_t)SIG_DFL; + } else if ((intptr_t)act->sa_handler < kSigactionMinRva) { + rva = (int)(intptr_t)act->sa_handler; + } else if ((intptr_t)act->sa_handler >= (intptr_t)&_base + kSigactionMinRva && + (intptr_t)act->sa_handler < (intptr_t)&_base + INT_MAX) { + rva = (int)((uintptr_t)act->sa_handler - (uintptr_t)&_base); + } else { + return efault(); + } + if (!IsWindows()) { + if (act) { + memcpy(©, act, sizeof(copy)); + ap = © + if (IsXnu()) { + ap->sa_restorer = (void *)&xnutrampoline; + ap->sa_handler = (void *)&xnutrampoline; + } else { + if (IsLinux()) { + if (!(ap->sa_flags & SA_RESTORER)) { + ap->sa_flags |= SA_RESTORER; + ap->sa_restorer = &__restore_rt; + } + } + if (rva >= 0) { + ap->sa_sigaction = (sigaction_f)__sigenter; + } + } + sigaction$cosmo2native((union metasigaction *)ap); + } else { + ap = NULL; + } + rc = sigaction$sysv( + sig, ap, oldact, + (!IsXnu() ? 8 /* or linux whines */ + : (int64_t)(intptr_t)oldact /* from go code */)); + if (rc != -1) sigaction$native2cosmo((union metasigaction *)oldact); + } else { + if (oldact) { + memset(oldact, 0, sizeof(*oldact)); + } + rc = 0; + } + if (rc != -1) { + if (oldact) { + oldrva = g_sighandrvas[sig]; + oldact->sa_sigaction = oldrva < kSigactionMinRva + ? (sigaction_f)(intptr_t)oldrva + : (sigaction_f)((uintptr_t)&_base + oldrva); + } + if (act) { + g_sighandrvas[sig] = rva; + } + } + return rc; +} diff --git a/libc/calls/sigaddset.c b/libc/calls/sigaddset.c new file mode 100644 index 00000000..c8183dcf --- /dev/null +++ b/libc/calls/sigaddset.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/sigbits.h" +#include "libc/calls/calls.h" + +/** + * Adds sig to set. + * + * @return true, false, or -1 w/ errno + * @error EINVAL + * @asyncsignalsafe + */ +int(sigaddset)(sigset_t *set, int sig) { return sigaddset(set, sig); } diff --git a/libc/calls/sigbits.h b/libc/calls/sigbits.h new file mode 100644 index 00000000..a3942400 --- /dev/null +++ b/libc/calls/sigbits.h @@ -0,0 +1,53 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_SIGBITS_H_ +#define COSMOPOLITAN_LIBC_CALLS_SIGBITS_H_ +#include "libc/bits/bits.h" +#include "libc/bits/progn.h" +#include "libc/str/str.h" +#include "libc/calls/struct/sigset.h" +#include "libc/sysv/errfuns.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct sigset; + +int sigaddset(struct sigset *, int) paramsnonnull(); +int sigdelset(struct sigset *, int) paramsnonnull(); +int sigemptyset(struct sigset *) paramsnonnull(); +int sigfillset(struct sigset *) paramsnonnull(); +int sigismember(const struct sigset *, int) paramsnonnull() nosideeffect; + +#define sigemptyset(SET) \ + ({ \ + memset((SET), 0, sizeof(struct sigset)); \ + 0; \ + }) + +#define sigfillset(SET) \ + ({ \ + memset((SET), -1, sizeof(struct sigset)); \ + 0; \ + }) + +#define sigaddset(SET, SIG) \ + ({ \ + int Sig = (SIG); \ + __IsValidSignal(Sig) ? PROGN(bts((SET)->sig, Sig - 1), 0) : einval(); \ + }) + +#define sigdelset(SET, SIG) \ + ({ \ + int Sig = (SIG); \ + __IsValidSignal(Sig) ? PROGN(btr((SET)->sig, Sig - 1), 0) : einval(); \ + }) + +#define sigismember(SET, SIG) \ + ({ \ + int Sig = (SIG); \ + __IsValidSignal(Sig) ? bt((SET)->sig, Sig - 1) : einval(); \ + }) + +#define __IsValidSignal(SIG) (1 <= (SIG) && (SIG) <= NSIG) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_SIGBITS_H_ */ diff --git a/libc/calls/sigdelset.c b/libc/calls/sigdelset.c new file mode 100644 index 00000000..c364ce98 --- /dev/null +++ b/libc/calls/sigdelset.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/sigbits.h" +#include "libc/calls/calls.h" + +/** + * Removes sig from set. + * + * @return 0 on success, or -1 w/ errno + * @error EINVAL + * @asyncsignalsafe + */ +int(sigdelset)(sigset_t *set, int sig) { return sigdelset(set, sig); } diff --git a/libc/calls/sigemptyset.c b/libc/calls/sigemptyset.c new file mode 100644 index 00000000..12d2b75b --- /dev/null +++ b/libc/calls/sigemptyset.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/sigbits.h" +#include "libc/calls/calls.h" + +/** + * Removes all signals from set. + * + * @return 0 on success, or -1 w/ errno + * @error EINVAL + * @asyncsignalsafe + */ +int(sigemptyset)(sigset_t *set) { return sigemptyset(set); } diff --git a/libc/calls/sigenter.S b/libc/calls/sigenter.S new file mode 100644 index 00000000..c41ce624 --- /dev/null +++ b/libc/calls/sigenter.S @@ -0,0 +1,54 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/macros.h" +.yoink __FILE__ + +/ System Five signal handler. +/ +/ This is needed because (1) a signal is allowed to trigger at +/ just about any time, and leaf functions (e.g. memcpy) aren't +/ required to leave Cosmopolitan's image base register alone. +/ +/ @param %edi is the signal number +/ @param %rsi will be passed for sigactions +/ @param %rdx will be passed for sigactions +/ @return true if handler was invoked +__sigenter: + push %rbp + mov %rsp,%rbp + push %rbx + push %rbx + ezlea _base,bx + .profilable + ezlea g_sighandrvas,ax + and $NSIG-1,%edi + mov (%rax,%rdi,4),%eax + cmp $kSigactionMinRva,%eax + jl 2f + add %rbx,%rax + call *%rax + mov $1,%eax +1: pop %rbx + leave + ret +2: xor %eax,%eax + jmp 1b + .endfn __sigenter,globl,hidden diff --git a/libc/calls/sigfillset.c b/libc/calls/sigfillset.c new file mode 100644 index 00000000..f8849d23 --- /dev/null +++ b/libc/calls/sigfillset.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/sigbits.h" +#include "libc/calls/calls.h" + +/** + * Adds all signals to set. + * + * @return 0 on success, or -1 w/ errno + * @asyncsignalsafe + */ +int(sigfillset)(sigset_t *set) { return sigfillset(set); } diff --git a/libc/calls/sigignore.c b/libc/calls/sigignore.c new file mode 100644 index 00000000..083a81c8 --- /dev/null +++ b/libc/calls/sigignore.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/str/str.h" + +int sigignore(int sig) { + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_IGN; + return (sigaction)(sig, &sa, 0); +} diff --git a/libc/calls/sigismember.c b/libc/calls/sigismember.c new file mode 100644 index 00000000..0029db27 --- /dev/null +++ b/libc/calls/sigismember.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/sigbits.h" +#include "libc/calls/calls.h" + +/** + * Returns true if sig ∈ set. + * + * @return true, false, or -1 w/ errno + * @error EINVAL + * @asyncsignalsafe + */ +int(sigismember)(const sigset_t *set, int sig) { return sigismember(set, sig); } diff --git a/libc/calls/signal.c b/libc/calls/signal.c new file mode 100644 index 00000000..200a2771 --- /dev/null +++ b/libc/calls/signal.c @@ -0,0 +1,33 @@ +/*-*- mode:c; indent-tabs-mode:nil; tab-width:2; coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/sysv/consts/sa.h" + +/** + * Installs kernel interrupt handler. + * + * @see sigaction() which has more features + */ +sighandler_t(signal)(int sig, sighandler_t func) { + struct sigaction sa_old, sa = {.sa_handler = func, .sa_flags = SA_RESTART}; + if ((sigaction)(sig, &sa, &sa_old) == -1) return SIG_ERR; + return sa_old.sa_handler; +} diff --git a/libc/calls/sigprocmask.c b/libc/calls/sigprocmask.c new file mode 100644 index 00000000..ac32bfe1 --- /dev/null +++ b/libc/calls/sigprocmask.c @@ -0,0 +1,45 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/sigset.h" +#include "libc/dce.h" +#include "libc/sysv/errfuns.h" + +/** + * Changes program signal blocking state, e.g.: + * + * sigset_t oldmask; + * sigprocmask(SIG_BLOCK, &kSigsetFull, &oldmask); + * sigprocmask(SIG_SETMASK, &oldmask, NULL); + * + * @param how can be SIG_BLOCK (U), SIG_UNBLOCK (/), SIG_SETMASK (=) + * @param set is the new mask content (optional) + * @param oldset will receive the old mask (optional) and can't overlap + * @return 0 on success, or -1 w/ errno + * @asyncsignalsafe + */ +int sigprocmask(int how, const sigset_t *opt_set, sigset_t *opt_out_oldset) { + if (!IsWindows()) { + return sigprocmask$sysv(how, opt_set, opt_out_oldset, 8); + } else { + return enosys(); /* TODO(jart): Implement me! */ + } +} diff --git a/libc/calls/sigsuspend.c b/libc/calls/sigsuspend.c new file mode 100644 index 00000000..65b55a84 --- /dev/null +++ b/libc/calls/sigsuspend.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/sigset.h" +#include "libc/calls/calls.h" +#include "libc/sysv/errfuns.h" + +/** + * Blocks until SIG ∉ MASK is delivered to process. + * + * @param mask is a bitset of signals to block temporarily + * @return -1 w/ EINTR + * @asyncsignalsafe + */ +int sigsuspend(const sigset_t *mask) { + if (!IsWindows()) { + return sigsuspend$sysv(mask, 8); + } else { + return enosys(); /* TODO(jart): Implement me! */ + } +} diff --git a/libc/calls/splice.c b/libc/calls/splice.c new file mode 100644 index 00000000..a5a18a68 --- /dev/null +++ b/libc/calls/splice.c @@ -0,0 +1,73 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/sysv/errfuns.h" + +static ssize_t splicer(int infd, int64_t *inoffset, int outfd, + int64_t *outoffset, size_t uptobytes, uint32_t flags, + int64_t impl(int infd, int64_t *inoffset, int outfd, + int64_t *outoffset, size_t uptobytes, + uint32_t flags)) { + int olderr; + ssize_t transferred; + if (!uptobytes || flags == -1) return einval(); + if (IsModeDbg() && uptobytes > 1) uptobytes >>= 1; + olderr = errno; + if ((transferred = + impl(infd, inoffset, outfd, outoffset, uptobytes, flags)) == -1 && + errno == ENOSYS) { + errno = olderr; + transferred = copyfd(infd, inoffset, outfd, outoffset, uptobytes, flags); + } + return transferred; +} + +/** + * Transfers data to/from pipe. + * + * @param flags can have SPLICE_F_{MOVE,NONBLOCK,MORE,GIFT} + * @return number of bytes transferred, 0 on input end, or -1 w/ errno + * @see copy_file_range() for file ↔ file + * @see sendfile() for seekable → socket + */ +ssize_t splice(int infd, int64_t *inopt_out_inoffset, int outfd, + int64_t *inopt_out_outoffset, size_t uptobytes, uint32_t flags) { + return splicer(infd, inopt_out_inoffset, outfd, inopt_out_outoffset, + uptobytes, flags, splice$sysv); +} + +/** + * Transfers data between files. + * + * @param outfd should be a writable file, but not O_APPEND + * @param flags is reserved for future use + * @return number of bytes actually copied, or -1 w/ errno + * @see sendfile() for seekable → socket + * @see splice() for fd ↔ pipe + */ +ssize_t copy_file_range(int infd, int64_t *inopt_out_inoffset, int outfd, + int64_t *inopt_out_outoffset, size_t uptobytes, + uint32_t flags) { + return splicer(infd, inopt_out_inoffset, outfd, inopt_out_outoffset, + uptobytes, flags, copy_file_range$sysv); +} diff --git a/libc/calls/stat-nt.c b/libc/calls/stat-nt.c new file mode 100644 index 00000000..b64d582d --- /dev/null +++ b/libc/calls/stat-nt.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/createfile.h" +#include "libc/nt/enum/accessmask.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" +#include "libc/runtime/runtime.h" + +textwindows int stat$nt(const char *path, struct stat *st) { + int rc; + int64_t fh; + uint16_t path16[PATH_MAX]; + if (mkntpath(path, path16) == -1) return -1; + if ((fh = CreateFile( + path16, kNtFileReadAttributes, + kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete, NULL, + kNtOpenExisting, kNtFileAttributeNormal | kNtFileFlagBackupSemantics, + 0)) != -1) { + rc = fstat$nt(fh, st); + CloseHandle(fh); + return rc; + } else { + return winerr(); + } +} diff --git a/libc/calls/stat.c b/libc/calls/stat.c new file mode 100644 index 00000000..5b9ef522 --- /dev/null +++ b/libc/calls/stat.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/at.h" +#include "libc/sysv/errfuns.h" +#include "libc/zipos/zipos.h" + +/** + * Returns information about thing. + * @asyncsignalsafe + */ +int stat(const char *pathname, struct stat *st) { + struct ZiposUri zipname; + if (weaken(__zipos_stat) && + weaken(__zipos_parseuri)(pathname, &zipname) != -1) { + return weaken(__zipos_stat)(&zipname, st); + } else if (!IsWindows()) { + return fstatat$sysv(AT_FDCWD, pathname, st, 0); + } else { + return stat$nt(pathname, st); + } +} diff --git a/libc/calls/stat2linux.c b/libc/calls/stat2linux.c new file mode 100644 index 00000000..36ee41c6 --- /dev/null +++ b/libc/calls/stat2linux.c @@ -0,0 +1,86 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/struct/metastat.h" +#include "libc/dce.h" + +#define SWITCHEROO(S1, S2, A, B, C, D, E, F, G, H, I, J, K, L, M) \ + do { \ + autotype((S2).A) a = (typeof((S2).A))(S1).A; \ + autotype((S2).B) b = (typeof((S2).B))(S1).B; \ + autotype((S2).C) c = (typeof((S2).C))(S1).C; \ + autotype((S2).D) d = (typeof((S2).D))(S1).D; \ + autotype((S2).E) e = (typeof((S2).E))(S1).E; \ + autotype((S2).F) f = (typeof((S2).F))(S1).F; \ + autotype((S2).G) g = (typeof((S2).G))(S1).G; \ + autotype((S2).H) h = (typeof((S2).H))(S1).H; \ + autotype((S2).I) i = (typeof((S2).I))(S1).I; \ + autotype((S2).J) j = (typeof((S2).J))(S1).J; \ + autotype((S2).K) k = (typeof((S2).K))(S1).K; \ + autotype((S2).L) l = (typeof((S2).L))(S1).L; \ + autotype((S2).M) m = (typeof((S2).M))(S1).M; \ + (S2).A = a; \ + (S2).B = b; \ + (S2).C = c; \ + (S2).D = d; \ + (S2).E = e; \ + (S2).F = f; \ + (S2).G = g; \ + (S2).H = h; \ + (S2).I = i; \ + (S2).J = j; \ + (S2).K = k; \ + (S2).L = l; \ + (S2).M = m; \ + } while (0); + +forceinline void stat2linux_xnu(union metastat *ms) { + SWITCHEROO(ms->xnu, ms->linux, st_dev, st_ino, st_nlink, st_mode, st_uid, + st_gid, st_rdev, st_size, st_blksize, st_blocks, st_atim, st_mtim, + st_ctim); +} + +forceinline void stat2linux_freebsd(union metastat *ms) { + SWITCHEROO(ms->freebsd, ms->linux, st_dev, st_ino, st_nlink, st_mode, st_uid, + st_gid, st_rdev, st_size, st_blksize, st_blocks, st_atim, st_mtim, + st_ctim); +} + +forceinline void stat2linux_openbsd(union metastat *ms) { + SWITCHEROO(ms->openbsd, ms->linux, st_dev, st_ino, st_nlink, st_mode, st_uid, + st_gid, st_rdev, st_size, st_blksize, st_blocks, st_atim, st_mtim, + st_ctim); +} + +/** + * Transcodes “The Dismal Data Structure” from BSD→Linux ABI. + * @asyncsignalsafe + */ +void stat2linux(void *ms) { + if (ms) { + if (SupportsXnu() && IsXnu()) { + stat2linux_xnu((union metastat *)ms); + } else if (SupportsFreebsd() && IsFreebsd()) { + stat2linux_freebsd((union metastat *)ms); + } else if (SupportsOpenbsd() && IsOpenbsd()) { + stat2linux_openbsd((union metastat *)ms); + } + } +} diff --git a/libc/calls/struct/dirent.h b/libc/calls/struct/dirent.h new file mode 100644 index 00000000..8df45380 --- /dev/null +++ b/libc/calls/struct/dirent.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_DIRENT_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_DIRENT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct dirent { + uint64_t d_ino; /* inode number */ + int64_t d_off; /* implementation-dependent location number */ + uint16_t d_reclen; /* byte length of this whole struct and string */ + uint8_t d_type; /* DT_UNKNOWN, DT_BLK, DT_DIR, etc. it's flaky */ + char d_name[1]; /* NUL-terminated basename */ +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_DIRENT_H_ */ diff --git a/libc/calls/struct/flock.h b/libc/calls/struct/flock.h new file mode 100644 index 00000000..52319ee3 --- /dev/null +++ b/libc/calls/struct/flock.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_FLOCK_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_FLOCK_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct flock { + short l_type; + short l_whence; + int64_t l_start; + int64_t l_len; + int l_pid; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_FLOCK_H_ */ diff --git a/libc/calls/struct/framebufferfixedscreeninfo.h b/libc/calls/struct/framebufferfixedscreeninfo.h new file mode 100644 index 00000000..4e7b9d3a --- /dev/null +++ b/libc/calls/struct/framebufferfixedscreeninfo.h @@ -0,0 +1,24 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_FRAMEBUFFERFIXEDSCREENINFO_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_FRAMEBUFFERFIXEDSCREENINFO_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct FrameBufferFixedScreenInfo { + char id[16]; + uint64_t smem_start; + uint32_t smem_len; + uint32_t type; + uint32_t type_aux; + uint32_t visual; + uint16_t xpanstep; + uint16_t ypanstep; + uint16_t ywrapstep; + uint32_t line_length; + uint64_t mmio_start; + uint32_t mmio_len; + uint32_t accel; + uint16_t capabilities; + uint16_t reserved[2]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_FRAMEBUFFERFIXEDSCREENINFO_H_ */ diff --git a/libc/calls/struct/framebuffervirtualscreeninfo.h b/libc/calls/struct/framebuffervirtualscreeninfo.h new file mode 100644 index 00000000..db3d5a96 --- /dev/null +++ b/libc/calls/struct/framebuffervirtualscreeninfo.h @@ -0,0 +1,44 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_FRAMEBUFFERVIRTUALSCREENINFO_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_FRAMEBUFFERVIRTUALSCREENINFO_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct FrameBufferBitField { + uint32_t offset; + uint32_t length; + uint32_t msb_right; +}; + +struct FrameBufferVirtualScreenInfo { + uint32_t xres; + uint32_t yres; + uint32_t xres_virtual; + uint32_t yres_virtual; + uint32_t xoffset; + uint32_t yoffset; + uint32_t bits_per_pixel; + uint32_t grayscale; + struct FrameBufferBitField red; + struct FrameBufferBitField green; + struct FrameBufferBitField blue; + struct FrameBufferBitField transp; + uint32_t nonstd; + uint32_t activate; + uint32_t height; + uint32_t width; + uint32_t accel_flags; + uint32_t pixclock; + uint32_t left_margin; + uint32_t right_margin; + uint32_t upper_margin; + uint32_t lower_margin; + uint32_t hsync_len; + uint32_t vsync_len; + uint32_t sync; + uint32_t vmode; + uint32_t rotate; + uint32_t colorspace; + uint32_t reserved[4]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_FRAMEBUFFERVIRTUALSCREENINFO_H_ */ diff --git a/libc/calls/struct/iovec.h b/libc/calls/struct/iovec.h new file mode 100644 index 00000000..33c413da --- /dev/null +++ b/libc/calls/struct/iovec.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_IOVEC_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_IOVEC_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct iovec { + void *iov_base; + size_t iov_len; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_IOVEC_H_ */ diff --git a/libc/calls/struct/itimerval.h b/libc/calls/struct/itimerval.h new file mode 100644 index 00000000..61d39611 --- /dev/null +++ b/libc/calls/struct/itimerval.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_ITIMERVAL_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_ITIMERVAL_H_ +#include "libc/calls/struct/timeval.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct itimerval { + struct timeval it_interval; /* {0,0} means singleshot */ + struct timeval it_value; /* {0,0} means disarm */ +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_ITIMERVAL_H_ */ diff --git a/libc/calls/struct/metastat.h b/libc/calls/struct/metastat.h new file mode 100644 index 00000000..1c18a4ee --- /dev/null +++ b/libc/calls/struct/metastat.h @@ -0,0 +1,55 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_METASTAT_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_METASTAT_H_ +#include "libc/calls/struct/stat.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +union metastat { + struct stat linux; + + struct stat$xnu { + int32_t st_dev; + uint16_t st_mode, st_nlink; + uint64_t st_ino; + uint32_t st_uid, st_gid; + int32_t st_rdev; + struct timespec st_atim, st_mtim, st_ctim, st_birthtim; + int64_t st_size, st_blocks; + int32_t st_blksize; + uint32_t st_flags, st_gen; + int32_t st_lspare; + int64_t st_qspare[2]; + } xnu; + + struct stat$freebsd { + uint64_t st_dev, st_ino, st_nlink; + uint16_t st_mode; + int16_t st_padding0; + uint32_t st_uid, st_gid; + int32_t st_padding1; + uint64_t st_rdev; + struct timespec st_atim, st_mtim, st_ctim, st_birthtim; + int64_t st_size, st_blocks; + int32_t st_blksize; + uint32_t st_flags; + uint64_t st_gen; + unsigned long st_spare[10]; + } freebsd; + + struct stat$openbsd { + uint32_t st_mode; + int32_t st_dev; + uint64_t st_ino; + uint32_t st_nlink, st_uid, st_gid; + int32_t st_rdev; + struct timespec st_atim, st_mtim, st_ctim; + int64_t st_size, st_blocks; + int32_t st_blksize; + uint32_t st_flags, st_gen; + struct timespec __st_birthtim; + } openbsd; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_METASTAT_H_ */ diff --git a/libc/calls/struct/metatermios.h b/libc/calls/struct/metatermios.h new file mode 100644 index 00000000..dcde41a4 --- /dev/null +++ b/libc/calls/struct/metatermios.h @@ -0,0 +1,35 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_METATERMIOS_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_METATERMIOS_H_ +#include "libc/calls/struct/termios.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct termios$xnu { + uint64_t c_iflag; + uint64_t c_oflag; + uint64_t c_cflag; + uint64_t c_lflag; + uint8_t c_cc[20]; + uint64_t c_ispeed; + uint64_t c_ospeed; +}; + +struct termios$bsd { + uint32_t c_iflag; + uint32_t c_oflag; + uint32_t c_cflag; + uint32_t c_lflag; + uint8_t c_cc[20]; + uint32_t c_ispeed; + uint32_t c_ospeed; +}; + +union metatermios { + struct termios linux; + struct termios$xnu xnu; + struct termios$bsd bsd; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_METATERMIOS_H_ */ diff --git a/libc/calls/struct/rlimit.h b/libc/calls/struct/rlimit.h new file mode 100644 index 00000000..a52e5cdc --- /dev/null +++ b/libc/calls/struct/rlimit.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_RLIMIT_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_RLIMIT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct rlimit { + int64_t rlim_cur; + int64_t rlim_max; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_RLIMIT_H_ */ diff --git a/libc/calls/struct/rusage.h b/libc/calls/struct/rusage.h new file mode 100644 index 00000000..32d3207c --- /dev/null +++ b/libc/calls/struct/rusage.h @@ -0,0 +1,31 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_RUSAGE_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_RUSAGE_H_ +#include "libc/calls/struct/timeval.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct rusage { + union { + struct { + struct timeval ru_utime; /* user CPU time used */ + struct timeval ru_stime; /* system CPU time used */ + int64_t ru_maxrss; /* maximum resident set size */ + int64_t ru_ixrss; /* integral shared memory size */ + int64_t ru_idrss; /* integral unshared data size */ + int64_t ru_isrss; /* integral unshared stack size */ + int64_t ru_minflt; /* page reclaims (soft page faults) */ + int64_t ru_majflt; /* page faults (hard page faults) */ + int64_t ru_nswap; /* swaps */ + int64_t ru_inblock; /* block input operations */ + int64_t ru_oublock; /* block output operations */ + int64_t ru_msgsnd; /* IPC messages sent */ + int64_t ru_msgrcv; /* IPC messages received */ + int64_t ru_nsignals; /* signals received */ + int64_t ru_nvcsw; /* voluntary context switches */ + int64_t ru_nivcsw; /* involuntary context switches */ + }; + uint8_t __conservatism[1024]; + }; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_RUSAGE_H_ */ diff --git a/libc/calls/struct/sched_param.h b/libc/calls/struct/sched_param.h new file mode 100644 index 00000000..718eb6e8 --- /dev/null +++ b/libc/calls/struct/sched_param.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SCHED_PARAM_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SCHED_PARAM_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct sched_param { + int32_t sched_priority; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SCHED_PARAM_H_ */ diff --git a/libc/calls/struct/sigaction.h b/libc/calls/struct/sigaction.h new file mode 100644 index 00000000..baa84161 --- /dev/null +++ b/libc/calls/struct/sigaction.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_H_ +#include "libc/calls/struct/sigset.h" +#include "libc/calls/typedef/sigaction_f.h" +#include "libc/calls/typedef/sighandler_t.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct sigaction { /* cosmo abi */ + union { + sighandler_t sa_handler; + sigaction_f sa_sigaction; + }; + uint64_t sa_flags; + void (*sa_restorer)(void); + struct sigset sa_mask; + int64_t __pad; +} aligned(8); + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_H_ */ diff --git a/libc/calls/struct/sigaltstack.h b/libc/calls/struct/sigaltstack.h new file mode 100644 index 00000000..fa11f460 --- /dev/null +++ b/libc/calls/struct/sigaltstack.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGALTSTACK_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGALTSTACK_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct sigaltstack { + void *ss_sp; + int ss_flags; + size_t ss_size; +}; + +typedef struct sigaltstack stack_t; + +static_assert(sizeof(stack_t) == 24); + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGALTSTACK_H_ */ diff --git a/libc/calls/struct/siginfo.h b/libc/calls/struct/siginfo.h new file mode 100644 index 00000000..2b35275e --- /dev/null +++ b/libc/calls/struct/siginfo.h @@ -0,0 +1,57 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGINFO_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGINFO_H_ +#include "libc/calls/struct/sigval.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct siginfo { + int32_t si_signo; + int32_t si_errno; + int32_t si_code; + union { + struct { + union { + struct { + int32_t si_pid; + uint32_t si_uid; + }; + struct { + int32_t si_timerid; + int32_t si_overrun; + }; + }; + union { + union sigval si_value; + struct { + int32_t si_status; + int64_t si_utime, si_stime; + }; + }; + }; + struct { + void *si_addr; + int16_t si_addr_lsb; + union { + struct { + void *si_lower; + void *si_upper; + }; + uint32_t si_pkey; + }; + }; + struct { + int64_t si_band; + int32_t si_fd; + }; + struct { + void *si_call_addr; + int32_t si_syscall; + uint32_t si_arch; + }; + char __ignoreme[128 - 2 * sizeof(int32_t) - sizeof(int64_t)]; + }; +} aligned(8); + +typedef struct siginfo siginfo_t; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGINFO_H_ */ diff --git a/libc/calls/struct/sigset.h b/libc/calls/struct/sigset.h new file mode 100644 index 00000000..bd076e48 --- /dev/null +++ b/libc/calls/struct/sigset.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGSET_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGSET_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct sigset { + uint32_t sig[4]; /* ignore sig[2] and sig[3] (for freebsd) */ +} aligned(8); + +typedef struct sigset sigset_t; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGSET_H_ */ diff --git a/libc/calls/struct/sigval.h b/libc/calls/struct/sigval.h new file mode 100644 index 00000000..504e6e5e --- /dev/null +++ b/libc/calls/struct/sigval.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGVAL_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGVAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +union sigval { + int32_t sival_int; + void *sival_ptr; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGVAL_H_ */ diff --git a/libc/calls/struct/stat.h b/libc/calls/struct/stat.h new file mode 100644 index 00000000..98e246f7 --- /dev/null +++ b/libc/calls/struct/stat.h @@ -0,0 +1,28 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_STAT_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_STAT_H_ +#include "libc/calls/struct/timespec.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct stat { + int64_t st_dev; /* 0: id of device with file */ + int64_t st_ino; /* 8: inode number in disk b-tree */ + int64_t st_nlink; /* 16: hard link count */ + int32_t st_mode; /* 24: octal file mask thing */ + int32_t st_uid; /* 28: user id of owner */ + int32_t st_gid; /* group id of owning group */ + int32_t __pad; /* ignore this */ + int64_t st_rdev; /* id of device if a special file */ + int64_t st_size; /* bytes in file */ + int64_t st_blksize; /* preferred chunking for underlying filesystem */ + int64_t st_blocks; /* number of 512-byte pages allocated to file */ + struct timespec st_atim; /* access time (consider noatime) */ + struct timespec st_mtim; /* modified time */ + struct timespec st_ctim; /* complicated time */ + int64_t __future[3 + 10]; /* reserved for future use */ +#define st_atime st_atim.tv_sec +#define st_mtime st_mtim.tv_sec +#define st_ctime st_ctim.tv_sec +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_STAT_H_ */ diff --git a/libc/calls/struct/sysinfo.h b/libc/calls/struct/sysinfo.h new file mode 100644 index 00000000..72a7c3fb --- /dev/null +++ b/libc/calls/struct/sysinfo.h @@ -0,0 +1,22 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SYSINFO_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SYSINFO_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct sysinfo { + int64_t uptime; /* seconds since boot */ + uint64_t loads[3]; /* 1-5-15 min active process averages */ + uint64_t totalram; /* system physical memory */ + uint64_t freeram; /* amount of ram currently going to waste */ + uint64_t sharedram; /* bytes w/ pages mapped into multiple progs */ + uint64_t bufferram; /* lingering disk pages; see fadvise */ + uint64_t totalswap; /* size of emergency memory */ + uint64_t freeswap; /* hopefully equal to totalswap */ + int16_t procs; /* number of processes */ + int16_t __ignore; /* padding */ + uint64_t totalhigh; /* wut */ + uint64_t freehigh; /* wut */ + uint32_t mem_unit; /* ram stuff above is multiples of this */ +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SYSINFO_H_ */ diff --git a/libc/calls/struct/termios.h b/libc/calls/struct/termios.h new file mode 100644 index 00000000..1ef82922 --- /dev/null +++ b/libc/calls/struct/termios.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_TERMIOS_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_TERMIOS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct termios { /* GNU/Systemd ABI */ + uint32_t c_iflag; /* input modes */ + uint32_t c_oflag; /* output modes */ + uint32_t c_cflag; /* control modes */ + uint32_t c_lflag; /* local modes */ + uint8_t c_cc[32]; /* code mappings */ + uint32_t c_ispeed; /* input speed */ + uint32_t c_ospeed; /* output speed */ +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_TERMIOS_H_ */ diff --git a/libc/calls/struct/timespec.h b/libc/calls/struct/timespec.h new file mode 100644 index 00000000..f7b3094b --- /dev/null +++ b/libc/calls/struct/timespec.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMESPEC_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMESPEC_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct timespec { + int64_t tv_sec; + int64_t tv_nsec; /* nanoseconds */ +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMESPEC_H_ */ diff --git a/libc/calls/struct/timeval.h b/libc/calls/struct/timeval.h new file mode 100644 index 00000000..e6dc0606 --- /dev/null +++ b/libc/calls/struct/timeval.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct timeval { + int64_t tv_sec; + int64_t tv_usec; /* microseconds */ +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_H_ */ diff --git a/libc/calls/struct/tms.h b/libc/calls/struct/tms.h new file mode 100644 index 00000000..5ea0f93a --- /dev/null +++ b/libc/calls/struct/tms.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_TMS_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_TMS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct tms { + int64_t tms_utime; /* userspace time */ + int64_t tms_stime; /* kernelspace time */ + int64_t tms_cutime; /* children userspace time */ + int64_t tms_cstime; /* children kernelspace time */ +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_TMS_H_ */ diff --git a/libc/calls/struct/utsname.h b/libc/calls/struct/utsname.h new file mode 100644 index 00000000..e18e72ce --- /dev/null +++ b/libc/calls/struct/utsname.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_UTSNAME_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_UTSNAME_H_ + +#define SYS_NMLN 321 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct utsname { + char sysname[SYS_NMLN]; + char nodename[SYS_NMLN]; + char release[SYS_NMLN]; + char version[SYS_NMLN]; + char machine[SYS_NMLN]; + char domainname[SYS_NMLN]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_UTSNAME_H_ */ diff --git a/libc/calls/struct/winsize.h b/libc/calls/struct/winsize.h new file mode 100644 index 00000000..328b25a6 --- /dev/null +++ b/libc/calls/struct/winsize.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_WINSIZE_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_WINSIZE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct winsize { + uint16_t ws_row; + uint16_t ws_col; + uint16_t ws_xpixel; + uint16_t ws_ypixel; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_WINSIZE_H_ */ diff --git a/libc/calls/symlink-nt.c b/libc/calls/symlink-nt.c new file mode 100644 index 00000000..164eabc2 --- /dev/null +++ b/libc/calls/symlink-nt.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/nt/files.h" + +textwindows int symlink$nt(const char *target, const char *linkpath) { + char16_t linkpath16[PATH_MAX], target16[PATH_MAX]; + uint32_t flags = isdirectory(target) ? kNtSymbolicLinkFlagDirectory : 0; + if (mkntpath(linkpath, linkpath16) == -1) return -1; + if (mkntpath(target, target16) == -1) return -1; + if (CreateSymbolicLink(linkpath16, target16, flags)) { + return 0; + } else { + return winerr(); + } +} diff --git a/libc/calls/symlink.c b/libc/calls/symlink.c new file mode 100644 index 00000000..a6804912 --- /dev/null +++ b/libc/calls/symlink.c @@ -0,0 +1,46 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sysv/consts/at.h" +#include "libc/sysv/errfuns.h" + +/** + * Creates symbolic link. + * + * This is like link() but adds a tiny indirection to make the fact that + * the file is a link obvious. It also enables certain other features, + * like the ability to be broken. + * + * @param target can be relative and needn't exist + * @param linkpath is what gets created + * @return 0 on success, or -1 w/ errno + * @note Windows NT only lets admins do this + * @asyncsignalsafe + */ +int symlink(const char *target, const char *linkpath) { + if (!target || !linkpath) return efault(); + if (!IsWindows()) { + return symlinkat$sysv(target, AT_FDCWD, linkpath); + } else { + return symlink$nt(target, linkpath); + } +} diff --git a/libc/calls/sync_file_range.c b/libc/calls/sync_file_range.c new file mode 100644 index 00000000..85b34e16 --- /dev/null +++ b/libc/calls/sync_file_range.c @@ -0,0 +1,45 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/errno.h" + +/** + * Flushes subset of file to disk. + * + * @param offset is page rounded + * @param bytes is page rounded; 0 means until EOF + * @param flags can have SYNC_FILE_RANGE_{WAIT_BEFORE,WRITE,WAIT_AFTER} + * @note Linux documentation says this call is "dangerous"; for highest + * assurance of data recovery after crash, consider fsync() on both + * file and directory + * @see fsync(), fdatasync(), PAGESIZE + */ +int sync_file_range(int fd, int64_t offset, int64_t bytes, unsigned flags) { + int rc, olderr; + olderr = errno; + if ((rc = sync_file_range$sysv(fd, offset, bytes, flags)) != -1 || + errno != ENOSYS) { + return rc; + } else { + errno = olderr; + return fdatasync(fd); + } +} diff --git a/libc/calls/sysinfo-nt.c b/libc/calls/sysinfo-nt.c new file mode 100644 index 00000000..f8fbc3e9 --- /dev/null +++ b/libc/calls/sysinfo-nt.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/struct/sysinfo.h" +#include "libc/nt/accounting.h" +#include "libc/nt/struct/memorystatusex.h" +#include "libc/nt/struct/systeminfo.h" +#include "libc/nt/systeminfo.h" + +textwindows int sysinfo$nt(struct sysinfo *info) { + struct NtMemoryStatusEx memstat; + memstat.dwLength = sizeof(struct NtMemoryStatusEx); + if (GlobalMemoryStatusEx(&memstat)) { + info->totalram = memstat.ullTotalPhys; + info->freeram = memstat.ullAvailPhys; + info->procs = g_ntsysteminfo.dwNumberOfProcessors; + info->mem_unit = 1; + return 0; + } else { + return winerr(); + } +} diff --git a/libc/calls/sysinfo.c b/libc/calls/sysinfo.c new file mode 100644 index 00000000..74cad971 --- /dev/null +++ b/libc/calls/sysinfo.c @@ -0,0 +1,49 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/sysinfo.h" +#include "libc/dce.h" +#include "libc/nt/accounting.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/memorystatusex.h" +#include "libc/nt/systeminfo.h" +#include "libc/str/str.h" + +/** + * Returns amount of system ram, cores, etc. + * @return 0 on success or -1 w/ errno + * @error ENOSYS, EFAULT + */ +int sysinfo(struct sysinfo *info) { + int rc; + memset(info, 0, sizeof(*info)); + if (!IsWindows()) { + rc = sysinfo$sysv(info); + } else { + rc = sysinfo$nt(info); + } + info->procs = max(1, info->procs); + info->mem_unit = max(1, info->mem_unit); + info->totalram = max((8 * 1024 * 1024) / info->mem_unit, info->totalram); + return rc; +} diff --git a/libc/calls/tcgetattr.c b/libc/calls/tcgetattr.c new file mode 100644 index 00000000..a98e51ce --- /dev/null +++ b/libc/calls/tcgetattr.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/ioctl.h" +#include "libc/calls/termios.h" +#include "libc/sysv/consts/termios.h" + +/** + * Obtains the termios struct. + * + * @param fd open file descriptor that isatty() + * @param tio is where result is stored + * @return -1 w/ errno on error + * @asyncsignalsafe + */ +int(tcgetattr)(int fd, struct termios *tio) { return ioctl(fd, TCGETS, tio); } diff --git a/libc/calls/tcgetpgrp.c b/libc/calls/tcgetpgrp.c new file mode 100644 index 00000000..f5cbe161 --- /dev/null +++ b/libc/calls/tcgetpgrp.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/termios.h" +#include "libc/sysv/consts/termios.h" + +/** + * Returns which process group controls terminal. + * @asyncsignalsafe + */ +int32_t tcgetpgrp(int fd) { + int pgrp; + if (ioctl(fd, TIOCGPGRP, &pgrp) < 0) return -1; + return pgrp; +} diff --git a/libc/calls/tcsetattr.c b/libc/calls/tcsetattr.c new file mode 100644 index 00000000..5e0b361f --- /dev/null +++ b/libc/calls/tcsetattr.c @@ -0,0 +1,47 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/ioctl.h" +#include "libc/calls/termios.h" +#include "libc/sysv/consts/termios.h" +#include "libc/sysv/errfuns.h" + +/** + * Sets struct on teletypewriter w/ drains and flushes. + * + * @param fd open file descriptor that isatty() + * @param opt can be: + * - TCSANOW: sets console settings + * - TCSADRAIN: drains output, and sets console settings + * - TCSAFLUSH: drops input, drains output, and sets console settings + * @return 0 on success, -1 w/ errno + * @asyncsignalsafe + */ +int(tcsetattr)(int fd, int opt, const struct termios *tio) { + switch (opt) { + case TCSANOW: + return ioctl(fd, TCSETS, (void *)tio); + case TCSADRAIN: + return ioctl(fd, TCSETSW, (void *)tio); + case TCSAFLUSH: + return ioctl(fd, TCSETSF, (void *)tio); + default: + return einval(); + } +} diff --git a/libc/calls/tcsetpgrp.c b/libc/calls/tcsetpgrp.c new file mode 100644 index 00000000..c1e913f1 --- /dev/null +++ b/libc/calls/tcsetpgrp.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/termios.h" +#include "libc/sysv/consts/termios.h" + +/** + * Puts process group in control of terminal. + * @asyncsignalsafe + */ +int tcsetpgrp(int fd, int32_t pgrp) { + int pgrp_int = pgrp; + return ioctl(fd, TIOCSPGRP, &pgrp_int); +} diff --git a/libc/calls/termios-internal.h b/libc/calls/termios-internal.h new file mode 100644 index 00000000..6bbb2af5 --- /dev/null +++ b/libc/calls/termios-internal.h @@ -0,0 +1,29 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_TERMIOS_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_CALLS_TERMIOS_INTERNAL_H_ +#include "libc/bits/safemacros.h" +#include "libc/str/str.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct termios; +union metatermios; + +#define COPY_TERMIOS(TO, FROM) \ + do { \ + memset((TO), 0, sizeof(*(TO))); \ + (TO)->c_iflag = (FROM)->c_iflag; \ + (TO)->c_oflag = (FROM)->c_oflag; \ + (TO)->c_cflag = (FROM)->c_cflag; \ + (TO)->c_lflag = (FROM)->c_lflag; \ + memcpy((TO)->c_cc, (FROM)->c_cc, \ + min(sizeof((TO)->c_cc), sizeof((FROM)->c_cc))); \ + (TO)->c_ispeed = (FROM)->c_ispeed; \ + (TO)->c_ospeed = (FROM)->c_ospeed; \ + } while (0) + +void *termios2host(union metatermios *, const struct termios *); +void termios2linux(struct termios *, const union metatermios *); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_TERMIOS_INTERNAL_H_ */ diff --git a/libc/calls/termios.h b/libc/calls/termios.h new file mode 100644 index 00000000..dcc7f935 --- /dev/null +++ b/libc/calls/termios.h @@ -0,0 +1,49 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_TERMIOS_H_ +#define COSMOPOLITAN_LIBC_CALLS_TERMIOS_H_ +#include "libc/calls/ioctl.h" +#include "libc/calls/struct/termios.h" +#include "libc/calls/struct/winsize.h" +#include "libc/macros.h" +#include "libc/sysv/consts/termios.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § teletypewriter control ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +int tcgetattr(int fd, struct termios *tio); +int tcsetattr(int fd, int opt, const struct termios *tio); +int tcsetpgrp(int fd, int32_t pgrp); +int32_t tcgetpgrp(int fd); + +int openpty(int *, int *, char *, const struct termios *, + const struct winsize *) paramsnonnull((1, 2)) nodiscard; +int forkpty(int *, char *, const struct termios *, const struct winsize *) + paramsnonnull((1, 2)) nodiscard; +errno_t ptsname_r(int, char *, size_t); + +int grantpt(int); +int unlockpt(int); +int posix_openpt(int) nodiscard; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § teletypewriter » optimizations ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define tcsetattr(FD, OPT, TIO) tcsetattr$dispatch(FD, OPT, TIO) +forceinline int tcsetattr$dispatch(int fd, int opt, const struct termios *tio) { + if (EQUIVALENT(opt, TCSANOW)) return ioctl(fd, TCSETS, (void *)tio); + if (EQUIVALENT(opt, TCSADRAIN)) return ioctl(fd, TCSETSW, (void *)tio); + if (EQUIVALENT(opt, TCSAFLUSH)) return ioctl(fd, TCSETSF, (void *)tio); + return (tcsetattr)(fd, opt, tio); +} + +#define tcgetattr(FD, TIO) tcgetattr$dispatch(FD, TIO) +forceinline int tcgetattr$dispatch(int fd, const struct termios *tio) { + return ioctl(fd, TCGETS, (void *)tio); +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_TERMIOS_H_ */ diff --git a/libc/calls/termios2host.c b/libc/calls/termios2host.c new file mode 100644 index 00000000..e73ab716 --- /dev/null +++ b/libc/calls/termios2host.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/ioctl.h" +#include "libc/calls/struct/metatermios.h" +#include "libc/calls/termios-internal.h" +#include "libc/calls/termios.h" +#include "libc/dce.h" + +void *termios2host(union metatermios *t, const struct termios *lt) { + if (IsXnu()) { + COPY_TERMIOS(&t->xnu, lt); + return &t->xnu; + } else if (IsFreebsd() || IsOpenbsd()) { + COPY_TERMIOS(&t->bsd, lt); + return &t->bsd; + } else { + return lt; + } +} diff --git a/libc/calls/termios2linux.c b/libc/calls/termios2linux.c new file mode 100644 index 00000000..a95d5157 --- /dev/null +++ b/libc/calls/termios2linux.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/ioctl.h" +#include "libc/calls/struct/metatermios.h" +#include "libc/calls/termios-internal.h" +#include "libc/calls/termios.h" +#include "libc/dce.h" + +void termios2linux(struct termios *lt, const union metatermios *t) { + if (IsXnu()) { + COPY_TERMIOS(lt, &t->xnu); + } else if (IsFreebsd() || IsOpenbsd()) { + COPY_TERMIOS(lt, &t->bsd); + } else { + memcpy(lt, &t->linux, sizeof(*lt)); + } +} diff --git a/libc/calls/thunks/ftruncate-sysv.S b/libc/calls/thunks/ftruncate-sysv.S new file mode 100644 index 00000000..c2d848d7 --- /dev/null +++ b/libc/calls/thunks/ftruncate-sysv.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Directly calls ftruncate() impl on host o/s if available. +ftruncate$sysv: + mov %rsp,%rdx # openbsd:pad + jmp __ftruncate$sysv + .endfn ftruncate$sysv,globl diff --git a/libc/calls/thunks/gettemppatha-flunk.S b/libc/calls/thunks/gettemppatha-flunk.S new file mode 100644 index 00000000..f82cd0f6 --- /dev/null +++ b/libc/calls/thunks/gettemppatha-flunk.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Calls GetTempPathA() w/ different API. +/ +/ @see GetSystemDirectoryA(), GetWindowsDirectoryA() +GetTempPathA$flunk: + xchg %rcx,%rdx + jmp *__imp_GetTempPathA(%rip) + .endfn GetTempPathA$flunk,globl,hidden diff --git a/libc/calls/thunks/lseek-sysv.S b/libc/calls/thunks/lseek-sysv.S new file mode 100644 index 00000000..3204971d --- /dev/null +++ b/libc/calls/thunks/lseek-sysv.S @@ -0,0 +1,38 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/macros.h" +.yoink __FILE__ + +/ Directly calls lseek() impl on host o/s if available. +lseek$sysv: +#if SupportsOpenbsd() + testb IsOpenbsd() # openbsd:evilpad + cmovnz %rdx,%rcx + cmovnz %rsi,%rdx + cmovnz .Lzero(%rip),%rsi +#endif + jmp __lseek$sysv + .endfn lseek$sysv,globl + + .rodata.cst8 +.Lzero: .quad 0 + .endobj .Lzero + .previous diff --git a/libc/calls/thunks/mmap-sysv.S b/libc/calls/thunks/mmap-sysv.S new file mode 100644 index 00000000..ba039ebf --- /dev/null +++ b/libc/calls/thunks/mmap-sysv.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Directly calls mmap() on system five host o/s. +mmap$sysv: + push %rbp + mov %rsp,%rbp + push %r9 # openbsd:pad + call __mmap$sysv + leave + ret + .endfn mmap$sysv,globl diff --git a/libc/calls/thunks/onntconsoleevent.S b/libc/calls/thunks/onntconsoleevent.S new file mode 100644 index 00000000..f14b0806 --- /dev/null +++ b/libc/calls/thunks/onntconsoleevent.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.text.windows +.yoink __FILE__ + +onntconsoleevent$nt: + ezlea onntconsoleevent,ax + jmp nt2sysv + .endfn onntconsoleevent$nt,globl,hidden diff --git a/libc/calls/thunks/onwincrash.S b/libc/calls/thunks/onwincrash.S new file mode 100644 index 00000000..69e0a768 --- /dev/null +++ b/libc/calls/thunks/onwincrash.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.text.windows +.yoink __FILE__ + +onwincrash$nt: + ezlea onwincrash,ax + jmp nt2sysv + .endfn onwincrash$nt,globl diff --git a/libc/calls/thunks/pread-sysv.S b/libc/calls/thunks/pread-sysv.S new file mode 100644 index 00000000..5a76bb72 --- /dev/null +++ b/libc/calls/thunks/pread-sysv.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Directly calls pread() impl on host o/s if available. +pread$sysv: + mov %rcx,%r8 # openbsd:pad + jmp __pread$sysv + .endfn pread$sysv,globl diff --git a/libc/calls/thunks/preadv-sysv.S b/libc/calls/thunks/preadv-sysv.S new file mode 100644 index 00000000..cc4bfcde --- /dev/null +++ b/libc/calls/thunks/preadv-sysv.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Directly calls preadv() impl on host o/s if available. +preadv$sysv: + mov %rcx,%r8 # openbsd:pad + jmp __preadv$sysv + .endfn preadv$sysv,globl diff --git a/libc/calls/thunks/pwrite-sysv.S b/libc/calls/thunks/pwrite-sysv.S new file mode 100644 index 00000000..9a8da3a3 --- /dev/null +++ b/libc/calls/thunks/pwrite-sysv.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Directly calls pwrite() impl on host o/s if available. +pwrite$sysv: + mov %rcx,%r8 # openbsd:pad + jmp __pwrite$sysv + .endfn pwrite$sysv,globl diff --git a/libc/calls/thunks/pwritev-sysv.S b/libc/calls/thunks/pwritev-sysv.S new file mode 100644 index 00000000..b23b476d --- /dev/null +++ b/libc/calls/thunks/pwritev-sysv.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Directly calls pwritev() impl on host o/s if available. +pwritev$sysv: + mov %rcx,%r8 # openbsd:pad + jmp __pwritev$sysv + .endfn pwritev$sysv,globl diff --git a/libc/calls/thunks/truncate-sysv.S b/libc/calls/thunks/truncate-sysv.S new file mode 100644 index 00000000..98ec21aa --- /dev/null +++ b/libc/calls/thunks/truncate-sysv.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Directly calls truncate() impl on host o/s if available. +truncate$sysv: + mov %rsp,%rdx # openbsd:pad + jmp __truncate$sysv + .endfn truncate$sysv,globl diff --git a/libc/calls/touch.c b/libc/calls/touch.c new file mode 100644 index 00000000..a30189bd --- /dev/null +++ b/libc/calls/touch.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/sysv/consts/o.h" + +/** + * Creates new file or changes modified time on existing one. + * + * @param file is a UTF-8 string, which may or may not exist + * @param mode is an octal user/group/other permission, e.g. 0755 + * @return 0 on success, or -1 w/ errno + * @see creat() + */ +int touch(const char *file, uint32_t mode) { + int fd; + if ((fd = open(file, O_CREAT | O_WRONLY, mode)) == -1) return -1; + fsync(fd); /* TODO(jart): do we need it? */ + return close(fd); +} diff --git a/libc/calls/truncate-nt.c b/libc/calls/truncate-nt.c new file mode 100644 index 00000000..cb140f0c --- /dev/null +++ b/libc/calls/truncate-nt.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/createfile.h" +#include "libc/nt/enum/accessmask.h" +#include "libc/nt/enum/creationdisposition.h" +#include "libc/nt/enum/fileflagandattributes.h" +#include "libc/nt/enum/filesharemode.h" +#include "libc/nt/runtime.h" + +textwindows int truncate$nt(const char *path, uint64_t length) { + bool32 ok; + int64_t fh; + uint16_t path16[PATH_MAX]; + if (mkntpath(path, path16) == -1) return -1; + if ((fh = CreateFile(path16, kNtGenericWrite, kNtFileShareRead, NULL, + kNtOpenExisting, kNtFileAttributeNormal, 0)) != -1) { + ok = ftruncate$nt(fh, length); + CloseHandle(fh); + if (ok) return 0; + } + return winerr(); +} diff --git a/libc/calls/truncate.c b/libc/calls/truncate.c new file mode 100644 index 00000000..9f444441 --- /dev/null +++ b/libc/calls/truncate.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" + +/** + * Reduces or extends underlying physical medium of file. + * + * If file was originally larger, content >length is lost. + * + * @param path must exist + * @return 0 on success or -1 w/ errno + * @see ftruncate() + * @error ENOENT + */ +int truncate(const char *path, uint64_t length) { + if (!IsWindows()) { + return truncate$sysv(path, length); + } else { + return truncate$nt(path, length); + } +} diff --git a/libc/calls/tunefd.c b/libc/calls/tunefd.c new file mode 100644 index 00000000..26c5770d --- /dev/null +++ b/libc/calls/tunefd.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" + +/** + * Modifies characteristics of open file descriptor. + */ +int tunefd$sysv(int fd, int getcmd, int setcmd, int addflags) { + int current; + if (fd != -1 && addflags) { + if ((current = fcntl$sysv(fd, getcmd, 0)) == -1 || + fcntl$sysv(fd, setcmd, current | addflags) == -1) { + close$sysv(fd); + return -1; + } + } + return fd; +} diff --git a/libc/calls/typedef/sigaction_f.h b/libc/calls/typedef/sigaction_f.h new file mode 100644 index 00000000..2e955e9d --- /dev/null +++ b/libc/calls/typedef/sigaction_f.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_TYPEDEF_SIGACTION_F_H_ +#define COSMOPOLITAN_LIBC_CALLS_TYPEDEF_SIGACTION_F_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct siginfo; +struct ucontext; + +typedef void (*sigaction_f)(int, struct siginfo *, struct ucontext *); + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_TYPEDEF_SIGACTION_F_H_ */ diff --git a/libc/calls/typedef/sighandler_t.h b/libc/calls/typedef/sighandler_t.h new file mode 100644 index 00000000..3130f190 --- /dev/null +++ b/libc/calls/typedef/sighandler_t.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_TYPEDEF_SIGHANDLER_T_H_ +#define COSMOPOLITAN_LIBC_CALLS_TYPEDEF_SIGHANDLER_T_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +typedef void (*sighandler_t)(int); + +typedef void (*sighandler_t)(int); + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_TYPEDEF_SIGHANDLER_T_H_ */ diff --git a/libc/calls/ucontext.h b/libc/calls/ucontext.h new file mode 100644 index 00000000..8345b09d --- /dev/null +++ b/libc/calls/ucontext.h @@ -0,0 +1,161 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_UCONTEXT_H_ +#define COSMOPOLITAN_LIBC_CALLS_UCONTEXT_H_ +#include "libc/calls/calls.h" +#include "libc/calls/struct/sigaltstack.h" +#include "libc/calls/struct/sigset.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define REG_R8 REG_R8 +#define REG_R9 REG_R9 +#define REG_R10 REG_R10 +#define REG_R11 REG_R11 +#define REG_R12 REG_R12 +#define REG_R13 REG_R13 +#define REG_R14 REG_R14 +#define REG_R15 REG_R15 +#define REG_RDI REG_RDI +#define REG_RSI REG_RSI +#define REG_RBP REG_RBP +#define REG_RBX REG_RBX +#define REG_RDX REG_RDX +#define REG_RAX REG_RAX +#define REG_RCX REG_RCX +#define REG_RSP REG_RSP +#define REG_RIP REG_RIP +#define REG_EFL REG_EFL +#define REG_CSGSFS REG_CSGSFS +#define REG_ERR REG_ERR +#define REG_TRAPNO REG_TRAPNO +#define REG_OLDMASK REG_OLDMASK +#define REG_CR2 REG_CR2 + +enum GeneralRegister { + REG_R8, + REG_R9, + REG_R10, + REG_R11, + REG_R12, + REG_R13, + REG_R14, + REG_R15, + REG_RDI, + REG_RSI, + REG_RBP, + REG_RBX, + REG_RDX, + REG_RAX, + REG_RCX, + REG_RSP, + REG_RIP, + REG_EFL, + REG_CSGSFS, + REG_ERR, + REG_TRAPNO, + REG_OLDMASK, + REG_CR2 +}; + +struct XmmRegister { + uint64_t u64[2]; +}; + +static_assert(sizeof(struct XmmRegister) == 16); + +struct FpuStackEntry { + uint16_t significand[4]; + uint16_t exponent; + uint16_t padding[3]; +}; + +static_assert(sizeof(struct FpuStackEntry) == 16); + +struct FpuState { + uint16_t cwd; + uint16_t swd; + uint16_t ftw; + uint16_t fop; + uint64_t rip; + uint64_t rdp; + uint32_t mxcsr; + uint32_t mxcr_mask; + struct FpuStackEntry st[8]; + struct XmmRegister xmm[16]; + uint32_t __padding[24]; +}; + +typedef uint64_t greg_t; +typedef greg_t gregset_t[23]; +typedef struct FpuState *fpregset_t; + +struct MachineContext { + union { + struct { + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + uint64_t rdi; + uint64_t rsi; + uint64_t rbp; + uint64_t rbx; + uint64_t rdx; + uint64_t rax; + uint64_t rcx; + uint64_t rsp; + uint64_t rip; + uint64_t eflags; + uint16_t cs; + uint16_t gs; + uint16_t fs; + uint16_t __pad0; + uint64_t err; + uint64_t trapno; + uint64_t oldmask; + uint64_t cr2; + }; + gregset_t gregs; + }; + struct FpuState *fpregs; + uint64_t __pad1[8]; +}; + +typedef struct MachineContext mcontext_t; + +struct ucontext { + union { + uint64_t uc_flags; + struct { + unsigned cf : 1; /* bit 0: carry flag */ + unsigned vf : 1; /* bit 1: V flag: was 8085 signed-number overflow */ + unsigned pf : 1; /* bit 2: parity flag */ + unsigned rf : 1; /* bit 3: always zero [undoc] */ + unsigned af : 1; /* bit 4: auxiliary flag */ + unsigned kf : 1; /* bit 5: K flag = V flag ⊕ sgn(result) [undoc] */ + unsigned zf : 1; /* bit 6: zero flag */ + unsigned sf : 1; /* bit 7: sign flag */ + unsigned tf : 1; /* bit 8: trap flag */ + unsigned if_ : 1; /* bit 9: interrupt enable flag */ + unsigned df : 1; /* bit 10: direction flag */ + unsigned of : 1; /* bit 11: overflow flag */ + unsigned pl : 2; /* b12-13: i/o privilege level (80286+) */ + unsigned nt : 1; /* bit 14: nested task flag (80286+) */ + unsigned pc : 1; /* bit 15: oldskool flag */ + }; + }; + struct ucontext *uc_link; + stack_t uc_stack; + mcontext_t uc_mcontext; + uint8_t uc_sigmask[128 + 16]; /* ?!? wut */ + struct FpuState fpustate; +}; + +typedef struct ucontext ucontext_t; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_UCONTEXT_H_ */ diff --git a/libc/calls/uname.c b/libc/calls/uname.c new file mode 100644 index 00000000..7ef8b79e --- /dev/null +++ b/libc/calls/uname.c @@ -0,0 +1,52 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/utsname.h" +#include "libc/str/str.h" + +/** + * Asks kernel to give us the `uname -a` data. + * @return 0 on success, or -1 w/ errno + */ +int uname(struct utsname *lool) { + char *out; + size_t i, j, len; + char tmp[sizeof(struct utsname)]; + memset(tmp, 0, sizeof(tmp)); + if (uname$sysv(tmp) != -1) { + out = (char *)lool; + i = 0; + j = 0; + for (;;) { + len = strlen(&tmp[j]); + if (len >= sizeof(struct utsname) - i) break; + memcpy(&out[i], &tmp[j], len + 1); + i += SYS_NMLN; + j += len; + while (j < sizeof(tmp) && tmp[j] == '\0') ++j; + if (j == sizeof(tmp)) break; + } + return 0; + } else { + memset(lool, 0, sizeof(struct utsname)); + return -1; + } +} diff --git a/libc/calls/unlink-nt.c b/libc/calls/unlink-nt.c new file mode 100644 index 00000000..b3254fdd --- /dev/null +++ b/libc/calls/unlink-nt.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" + +textwindows int unlink$nt(const char *name) { + uint16_t name16[PATH_MAX]; + if (mkntpath(name, name16) == -1) return -1; + if (DeleteFile(name16)) { + return 0; + } else { + return winerr(); + } +} diff --git a/libc/calls/unlink.c b/libc/calls/unlink.c new file mode 100644 index 00000000..1a540998 --- /dev/null +++ b/libc/calls/unlink.c @@ -0,0 +1,45 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/nt/files.h" +#include "libc/str/str.h" +#include "libc/calls/internal.h" +#include "libc/sysv/errfuns.h" +#include "libc/sysv/consts/at.h" + +/** + * Deletes file. + * + * Please note the deletion process has different interesting properties + * on each platform. For example, on System V, if open descriptors exist + * then only the name of the file is removed and it's actually deleted + * later on when appropriate. + * + * @return 0 on success, or -1 w/ errno + * @asyncsignalsafe + */ +int unlink(const char *name) { + if (!name) return 0; + if (!IsWindows()) { + return unlinkat$sysv(AT_FDCWD, name, 0); + } else { + return unlink$nt(name); + } +} diff --git a/libc/calls/unlink_s.c b/libc/calls/unlink_s.c new file mode 100644 index 00000000..406e1a3e --- /dev/null +++ b/libc/calls/unlink_s.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/runtime/mappings.h" + +/** + * Deletes file, the Cosmopolitan way. + * + * The caller's variable is made NULL. Note that we define unlink(NULL) + * as a no-op. + * + * @return 0 on success, or -1 w/ errno + * @asyncsignalsafe + */ +int unlink_s(const char **namep) { + const char *name = NULL; + return unlink(lockxchg(namep, &name)); +} diff --git a/libc/calls/unlockpt.c b/libc/calls/unlockpt.c new file mode 100644 index 00000000..347bca41 --- /dev/null +++ b/libc/calls/unlockpt.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/termios.h" +#include "libc/sysv/consts/pty.h" + +int unlockpt(int fd) { + int unlock = 0; + /* TODO(jart) */ + return ioctl(fd, TIOCSPTLCK, &unlock); +} diff --git a/libc/calls/vdprintf.c b/libc/calls/vdprintf.c new file mode 100644 index 00000000..962034e2 --- /dev/null +++ b/libc/calls/vdprintf.c @@ -0,0 +1,65 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/fmt/fmt.h" +#include "libc/limits.h" +#include "libc/nt/files.h" +#include "libc/sysv/errfuns.h" + +#define DBUFSIZ 1460 /* tcp ethernet frame < -Wframe-larger-than=4096 */ + +struct dfile { + int fd; + unsigned idx; + unsigned toto; + unsigned char buf[DBUFSIZ]; +}; + +static int vdprintf_flush(struct dfile *df) { + ssize_t wrote; + do { + wrote = write(df->fd, &df->buf[0], df->idx); + if (wrote == -1) return -1; + df->toto += (unsigned)wrote; + df->idx -= (unsigned)wrote; + if (df->toto > INT_MAX) return eoverflow(); + } while (df->idx); + return 0; +} + +static int vdprintfputchar(unsigned char c, struct dfile *df) { + df->buf[df->idx++] = c; + if (df->idx == DBUFSIZ && vdprintf_flush(df) == -1) return -1; + return 0; +} + +/** + * Formats string directly to system i/o device. + */ +int(vdprintf)(int fd, const char *fmt, va_list va) { + struct dfile df; + df.fd = fd; + df.idx = 0; + df.toto = 0; + if (palandprintf(vdprintfputchar, &df, fmt, va) == -1) return -1; + if (df.idx && vdprintf_flush(&df) == -1) return -1; + return df.toto; +} diff --git a/libc/calls/vmsplice.c b/libc/calls/vmsplice.c new file mode 100644 index 00000000..774b7b21 --- /dev/null +++ b/libc/calls/vmsplice.c @@ -0,0 +1,45 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/errno.h" + +/** + * Transfers memory to pipe. + * + * @param flags can have SPLICE_F_{MOVE,NONBLOCK,MORE,GIFT} + * @return number of bytes actually transferred, or -1 w/ errno + */ +ssize_t vmsplice(int fd, const struct iovec *chunks, int64_t count, + uint32_t flags) { + int olderr; + ssize_t wrote; + olderr = errno; + if ((wrote = vmsplice$sysv(fd, chunks, count, flags)) == -1) { + errno = olderr; + if (count) { + wrote = write(fd, chunks[0].iov_base, chunks[0].iov_len); + } else { + wrote = write(fd, NULL, 0); + } + } + return wrote; +} diff --git a/libc/calls/wait.c b/libc/calls/wait.c new file mode 100644 index 00000000..0d62216b --- /dev/null +++ b/libc/calls/wait.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sysv/errfuns.h" + +/** + * Waits for status to change on any child process. + * + * @param opt_out_wstatus optionally returns status code, and *wstatus + * may be inspected using WEEXITSTATUS(), etc. + * @return process id of terminated child or -1 w/ errno + * @asyncsignalsafe + */ +int wait(int *opt_out_wstatus) { + if (!IsWindows()) { + return wait4$sysv(-1, opt_out_wstatus, 0, NULL); + } else { + return enosys(); /* TODO(jart) */ + } +} diff --git a/libc/calls/wait3.c b/libc/calls/wait3.c new file mode 100644 index 00000000..888201c1 --- /dev/null +++ b/libc/calls/wait3.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sysv/errfuns.h" + +/** + * Waits for status to change on any child process. + * + * @param opt_out_wstatus optionally returns status code, and *wstatus + * may be inspected using WEEXITSTATUS(), etc. + * @param options can have WNOHANG, WUNTRACED, WCONTINUED, etc. + * @param opt_out_rusage optionally returns accounting data + * @return process id of terminated child or -1 w/ errno + * @asyncsignalsafe + */ +int wait3(int *opt_out_wstatus, int options, struct rusage *opt_out_rusage) { + if (!IsWindows()) { + return wait4$sysv(-1, opt_out_wstatus, options, opt_out_rusage); + } else { + return enosys(); /* TODO(jart) */ + } +} diff --git a/libc/calls/wait4-nt.c b/libc/calls/wait4-nt.c new file mode 100644 index 00000000..1a2fc8ee --- /dev/null +++ b/libc/calls/wait4-nt.c @@ -0,0 +1,66 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/rusage.h" +#include "libc/conv/conv.h" +#include "libc/nt/accounting.h" +#include "libc/nt/enum/status.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/filetime.h" +#include "libc/nt/synchronization.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/w.h" +#include "libc/sysv/errfuns.h" + +textwindows int wait4$nt(int pid, int *opt_out_wstatus, int options, + struct rusage *opt_out_rusage) { + uint32_t dwExitCode; + struct NtFileTime createfiletime, exitfiletime, kernelfiletime, userfiletime; + if (!isfdkind(pid, kFdProcess)) return esrch(); + for (;;) { + dwExitCode = kNtStillActive; + if (!(options & WNOHANG)) { + WaitForSingleObject(g_fds.p[pid].handle, 0xffffffff); + } + if (GetExitCodeProcess(g_fds.p[pid].handle, &dwExitCode)) { + if (dwExitCode != kNtStillActive) { + if (opt_out_wstatus) { /* @see WEXITSTATUS() */ + *opt_out_wstatus = (dwExitCode & 0xff) << 8; + } + if (opt_out_rusage) { + memset(opt_out_rusage, 0, sizeof(*opt_out_rusage)); + GetProcessTimes(GetCurrentProcess(), &createfiletime, &exitfiletime, + &kernelfiletime, &userfiletime); + filetimetotimeval(&opt_out_rusage->ru_utime, userfiletime); + filetimetotimeval(&opt_out_rusage->ru_stime, kernelfiletime); + } + return pid; + } else if (options & WNOHANG) { + return pid; + } else { + continue; + } + } else { + return winerr(); + } + } +} diff --git a/libc/calls/wait4.c b/libc/calls/wait4.c new file mode 100644 index 00000000..3837b864 --- /dev/null +++ b/libc/calls/wait4.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" + +/** + * Waits for status to change on process. + * + * @param pid >0 targets specific process, =0 means any proc in a group, + * -1 means any child process, <-1 means any proc in specific group + * @param opt_out_wstatus optionally returns status code, and *wstatus + * may be inspected using WEEXITSTATUS(), etc. + * @param options can have WNOHANG, WUNTRACED, WCONTINUED, etc. + * @param opt_out_rusage optionally returns accounting data + * @return process id of terminated child or -1 w/ errno + * @asyncsignalsafe + */ +int wait4(int pid, int *opt_out_wstatus, int options, + struct rusage *opt_out_rusage) { + if (!IsWindows()) { + return wait4$sysv(pid, opt_out_wstatus, options, opt_out_rusage); + } else { + return wait4$nt(pid, opt_out_wstatus, options, opt_out_rusage); + } +} diff --git a/libc/calls/waitpid.c b/libc/calls/waitpid.c new file mode 100644 index 00000000..3320309c --- /dev/null +++ b/libc/calls/waitpid.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" + +/** + * Waits for status to change on process. + * + * @param pid >0 targets specific process, =0 means any proc in a group, + * -1 means any child process, <-1 means any proc in specific group + * @param opt_out_wstatus optionally returns status code, and *wstatus + * may be inspected using WEXITSTATUS(), etc. + * @param options can have WNOHANG, WUNTRACED, WCONTINUED, etc. + * @return process id of terminated child or -1 w/ errno + * @asyncsignalsafe + */ +int waitpid(int pid, int *opt_out_wstatus, int options) { + if (!IsWindows()) { + return wait4$sysv(pid, opt_out_wstatus, options, NULL); + } else { + return wait4$nt(pid, opt_out_wstatus, options, NULL); + } +} diff --git a/libc/calls/weirdtypes.h b/libc/calls/weirdtypes.h new file mode 100644 index 00000000..b90f8f25 --- /dev/null +++ b/libc/calls/weirdtypes.h @@ -0,0 +1,112 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_WEIRDTYPES_H_ +#define COSMOPOLITAN_LIBC_CALLS_WEIRDTYPES_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * @fileoverview Types for scoundrels. + */ + +#define blkcnt_t int64_t +#define blksize_t int64_t /* int32_t on xnu */ +#define cc_t uint8_t +#define clock_t int64_t /* uint64_t on xnu */ +#define cpu_set_t uint64_t +#define dev_t uint64_t /* int32_t on xnu */ +#define fsblkcnt_t int64_t +#define fsfilcnt_t int64_t /* uint32_t on xnu */ +#define gid_t uint32_t +#define id_t uint32_t /* int32_t on linux/freebsd/etc. */ +#define in_addr_t uint32_t +#define in_addr_t uint32_t +#define in_port_t uint16_t +#define in_port_t uint16_t +#define ino_t uint64_t +#define key_t int32_t +#define loff_t int64_t +#define mode_t uint32_t /* uint16_t on xnu */ +#define nfds_t uint64_t +#define off_t int64_t +#define pid_t int32_t +#define register_t int64_t +#define sa_family_t uint16_t /* bsd:uint8_t */ +#define socklen_t uint32_t +#define speed_t uint32_t +#define suseconds_t int64_t /* int32_t on xnu */ +#define syscall_arg_t int64_t /* uint64_t on xnu */ +#define tcflag_t uint32_t +#define time_t int64_t +#define timer_t void* +#define uid_t uint32_t + +#define int_fast8_t __INT_FAST8_TYPE__ +#define uint_fast8_t __UINT_FAST8_TYPE__ +#define int_fast16_t __INT_FAST16_TYPE__ +#define uint_fast16_t __UINT_FAST16_TYPE__ +#define int_fast32_t __INT_FAST32_TYPE__ +#define uint_fast32_t __UINT_FAST32_TYPE__ +#define int_fast64_t __INT_FAST64_TYPE__ +#define uint_fast64_t __UINT_FAST64_TYPE__ + +#define atomic_bool _Atomic(_Bool) +#define atomic_bool32 atomic_int_fast32_t +#define atomic_char _Atomic(char) +#define atomic_schar _Atomic(signed char) +#define atomic_uchar _Atomic(unsigned char) +#define atomic_short _Atomic(short) +#define atomic_ushort _Atomic(unsigned short) +#define atomic_int _Atomic(int) +#define atomic_uint _Atomic(unsigned int) +#define atomic_long _Atomic(long) +#define atomic_ulong _Atomic(unsigned long) +#define atomic_llong _Atomic(long long) +#define atomic_ullong _Atomic(unsigned long long) +#define atomic_char16_t _Atomic(char16_t) +#define atomic_char32_t _Atomic(char32_t) +#define atomic_wchar_t _Atomic(wchar_t) +#define atomic_int_least8_t _Atomic(int_least8_t) +#define atomic_uint_least8_t _Atomic(uint_least8_t) +#define atomic_int_least16_t _Atomic(int_least16_t) +#define atomic_uint_least16_t _Atomic(uint_least16_t) +#define atomic_int_least32_t _Atomic(int_least32_t) +#define atomic_uint_least32_t _Atomic(uint_least32_t) +#define atomic_int_least64_t _Atomic(int_least64_t) +#define atomic_uint_least64_t _Atomic(uint_least64_t) +#define atomic_int_fast8_t _Atomic(int_fast8_t) +#define atomic_uint_fast8_t _Atomic(uint_fast8_t) +#define atomic_int_fast16_t _Atomic(int_fast16_t) +#define atomic_uint_fast16_t _Atomic(uint_fast16_t) +#define atomic_int_fast32_t _Atomic(int_fast32_t) +#define atomic_uint_fast32_t _Atomic(uint_fast32_t) +#define atomic_int_fast64_t _Atomic(int_fast64_t) +#define atomic_uint_fast64_t _Atomic(uint_fast64_t) +#define atomic_intptr_t _Atomic(intptr_t) +#define atomic_uintptr_t _Atomic(uintptr_t) +#define atomic_size_t _Atomic(size_t) +#define atomic_ptrdiff_t _Atomic(ptrdiff_t) + +#ifdef __CLANG_ATOMIC_BOOL_LOCK_FREE +#define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE +#define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE +#define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE +#define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE +#define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE +#define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE +#define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE +#define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE +#define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE +#define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE +#else +#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE +#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE +#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE +#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE +#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE +#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE +#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE +#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE +#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE +#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE +#endif + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_WEIRDTYPES_H_ */ diff --git a/libc/calls/winerr.greg.c b/libc/calls/winerr.greg.c new file mode 100644 index 00000000..18589b71 --- /dev/null +++ b/libc/calls/winerr.greg.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/nt/errors.h" +#include "libc/nt/runtime.h" +#include "libc/sysv/errfuns.h" + +/** + * Return path for failed Win32 API calls. + * + * @return -1 w/ few exceptions + * @note this is a code-size saving device + */ +privileged int64_t winerr(void) { + if (IsWindows()) { + errno = GetLastError(); + return -1; + } else { + return enosys(); + } +} diff --git a/libc/calls/write-nt.c b/libc/calls/write-nt.c new file mode 100644 index 00000000..089fda14 --- /dev/null +++ b/libc/calls/write-nt.c @@ -0,0 +1,51 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/limits.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/overlapped.h" +#include "libc/sysv/errfuns.h" + +static size_t SumIovecLen(const struct iovec *v, size_t n) { + size_t i, sum; + for (sum = i = 0; i < n; ++i) { + sum += v[i].iov_len; + } + return sum; +} + +textwindows ssize_t write$nt(struct Fd *fd, const struct iovec *iov, + size_t iovlen, ssize_t opt_offset) { + uint32_t wrote; + struct NtOverlapped overlap; + while (iovlen && !iov[0].iov_len) iov++, iovlen--; + if (WriteFile(fd->handle, iovlen ? iov[0].iov_base : NULL, + iovlen ? clampio(iov[0].iov_len) : 0, &wrote, + offset2overlap(opt_offset, &overlap))) { + if (!wrote) assert(SumIovecLen(iov, iovlen) > 0); + FlushFileBuffers(fd->handle); + return wrote; + } else { + return winerr(); + } +} diff --git a/libc/calls/write.c b/libc/calls/write.c new file mode 100644 index 00000000..5628f1f0 --- /dev/null +++ b/libc/calls/write.c @@ -0,0 +1,72 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/dce.h" +#include "libc/sock/internal.h" +#include "libc/sysv/errfuns.h" +#include "libc/zipos/zipos.h" + +/** + * Writes data to file descriptor. + * + * @param fd is something open()'d earlier + * @param buf is copied from, cf. copy_file_range(), sendfile(), etc. + * @param size in range [1..0x7ffff000] is reasonable + * @return [1..size] bytes on success, or -1 w/ errno; noting zero is + * impossible unless size was passed as zero to do an error check + * @see read(), pwrite(), writev(), SIGPIPE + * @asyncsignalsafe + */ +ssize_t write(int fd, const void *buf, size_t size) { + ssize_t rc; + size_t wrote; + if (fd == -1) return einval(); + if (isfdkind(fd, kFdZip)) { + rc = weaken(__zipos_write)( + (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, + (struct iovec[]){{buf, size}}, 1, -1); + } else if (!IsWindows()) { + rc = write$sysv(fd, buf, size); + } else if (isfdkind(fd, kFdSocket)) { + rc = weaken(sendto$nt)(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, 0, + NULL, 0); + } else if (isfdkind(fd, kFdFile) || isfdkind(fd, kFdConsole)) { + rc = write$nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, -1); + } else { + return ebadf(); + } + if (rc != -1) { + wrote = (size_t)rc; + if (wrote == 0) { + assert(size == 0); + } else { + assert(wrote <= size); + } + } + if (!IsTrustworthy() && rc != -1) { + if (!rc && size) abort(); + if ((size_t)rc > size) abort(); + } + return rc; +} diff --git a/libc/calls/writev.c b/libc/calls/writev.c new file mode 100644 index 00000000..4aceaf31 --- /dev/null +++ b/libc/calls/writev.c @@ -0,0 +1,49 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/sock/internal.h" +#include "libc/sysv/errfuns.h" +#include "libc/zipos/zipos.h" + +/** + * Writes data from multiple buffers. + * + * @return number of bytes actually handed off, or -1 w/ errno + */ +ssize_t writev(int fd, const struct iovec *iov, int iovlen) { + if (!IsTrustworthy()) { + if (fd == -1) return einval(); + if (iovlen < 0) return einval(); + } + if (isfdkind(fd, kFdZip)) { + return weaken(__zipos_write)( + (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1); + } + if (!IsWindows()) { + return writev$sysv(fd, iov, iovlen); + } else if (isfdkind(fd, kFdFile) || isfdkind(fd, kFdConsole)) { + return write$nt(&g_fds.p[fd], iov, iovlen, -1); + } else if (isfdkind(fd, kFdSocket)) { + return weaken(sendto$nt)(&g_fds.p[fd], iov, iovlen, 0, NULL, 0); + } else { + return ebadf(); + } +} diff --git a/libc/calls/xattr.h b/libc/calls/xattr.h new file mode 100644 index 00000000..0b14d2c6 --- /dev/null +++ b/libc/calls/xattr.h @@ -0,0 +1,26 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_XATTR_H_ +#define COSMOPOLITAN_LIBC_CALLS_XATTR_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +ssize_t flistxattr(int filedes, char *list, size_t size); +ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size); +int fsetxattr(int filedes, const char *name, const void *value, size_t size, + int flags); +int fremovexattr(int filedes, const char *name); + +ssize_t listxattr(const char *path, char *list, size_t size); +ssize_t getxattr(const char *path, const char *name, void *value, size_t size); +int setxattr(const char *path, const char *name, const void *value, size_t size, + int flags); +int removexattr(const char *path, const char *name); + +ssize_t llistxattr(const char *path, char *list, size_t size); +ssize_t lgetxattr(const char *path, const char *name, void *value, size_t size); +int lsetxattr(const char *path, const char *name, const void *value, + size_t size, int flags); +int lremovexattr(const char *path, const char *name); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_XATTR_H_ */ diff --git a/libc/calls/xnutrampoline.c b/libc/calls/xnutrampoline.c new file mode 100644 index 00000000..b2ad0125 --- /dev/null +++ b/libc/calls/xnutrampoline.c @@ -0,0 +1,475 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/siginfo.h" +#include "libc/calls/ucontext.h" +#include "libc/str/str.h" + +/** + * @fileoverview XNU kernel callback normalization. + */ + +union __darwin_sigval { + int32_t sival_int; + void *sival_ptr; +}; + +struct __darwin_siginfo { + int32_t si_signo; + int32_t si_errno; + int32_t si_code; + int32_t si_pid; + uint32_t si_uid; + int32_t si_status; + void *si_addr; + union __darwin_sigval si_value; + int64_t si_band; + uint64_t __pad[7]; +}; + +struct __darwin_sigaltstack { + void *ss_sp; + uint64_t ss_size; + int32_t ss_flags; +}; + +struct __darwin_fp_control { + uint16_t __invalid : 1, __denorm : 1, __zdiv : 1, __ovrfl : 1, __undfl : 1, + __precis : 1, : 2, __pc : 2, __rc : 2, : 1, : 3; +}; + +struct __darwin_fp_status { + uint16_t __invalid : 1, __denorm : 1, __zdiv : 1, __ovrfl : 1, __undfl : 1, + __precis : 1, __stkflt : 1, __errsumm : 1, __c0 : 1, __c1 : 1, __c2 : 1, + __tos : 3, __c3 : 1, __busy : 1; +}; + +struct __darwin_mmst_reg { + char __mmst_reg[10]; + char __mmst_rsrv[6]; +}; + +struct __darwin_xmm_reg { + char __xmm_reg[16]; +}; + +struct __darwin_ymm_reg { + char __ymm_reg[32]; +}; + +struct __darwin_zmm_reg { + char __zmm_reg[64]; +}; + +struct __darwin_opmask_reg { + char __opmask_reg[8]; +}; + +struct __darwin_x86_thread_state64 { + uint64_t __rax; + uint64_t __rbx; + uint64_t __rcx; + uint64_t __rdx; + uint64_t __rdi; + uint64_t __rsi; + uint64_t __rbp; + uint64_t __rsp; + uint64_t __r8; + uint64_t __r9; + uint64_t __r10; + uint64_t __r11; + uint64_t __r12; + uint64_t __r13; + uint64_t __r14; + uint64_t __r15; + uint64_t __rip; + uint64_t __rflags; + uint64_t __cs; + uint64_t __fs; + uint64_t __gs; +}; + +struct __darwin_x86_thread_full_state64 { + struct __darwin_x86_thread_state64 ss64; + uint64_t __ds; + uint64_t __es; + uint64_t __ss; + uint64_t __gsbase; +}; + +struct __darwin_x86_float_state64 { + int32_t __fpu_reserved[2]; + struct __darwin_fp_control __fpu_fcw; + struct __darwin_fp_status __fpu_fsw; + uint8_t __fpu_ftw; + uint8_t __fpu_rsrv1; + uint16_t __fpu_fop; + uint32_t __fpu_ip; + uint16_t __fpu_cs; + uint16_t __fpu_rsrv2; + uint32_t __fpu_dp; + uint16_t __fpu_ds; + uint16_t __fpu_rsrv3; + uint32_t __fpu_mxcsr; + uint32_t __fpu_mxcsrmask; + struct __darwin_mmst_reg __fpu_stmm0; + struct __darwin_mmst_reg __fpu_stmm1; + struct __darwin_mmst_reg __fpu_stmm2; + struct __darwin_mmst_reg __fpu_stmm3; + struct __darwin_mmst_reg __fpu_stmm4; + struct __darwin_mmst_reg __fpu_stmm5; + struct __darwin_mmst_reg __fpu_stmm6; + struct __darwin_mmst_reg __fpu_stmm7; + struct __darwin_xmm_reg __fpu_xmm0; + struct __darwin_xmm_reg __fpu_xmm1; + struct __darwin_xmm_reg __fpu_xmm2; + struct __darwin_xmm_reg __fpu_xmm3; + struct __darwin_xmm_reg __fpu_xmm4; + struct __darwin_xmm_reg __fpu_xmm5; + struct __darwin_xmm_reg __fpu_xmm6; + struct __darwin_xmm_reg __fpu_xmm7; + struct __darwin_xmm_reg __fpu_xmm8; + struct __darwin_xmm_reg __fpu_xmm9; + struct __darwin_xmm_reg __fpu_xmm10; + struct __darwin_xmm_reg __fpu_xmm11; + struct __darwin_xmm_reg __fpu_xmm12; + struct __darwin_xmm_reg __fpu_xmm13; + struct __darwin_xmm_reg __fpu_xmm14; + struct __darwin_xmm_reg __fpu_xmm15; + char __fpu_rsrv4[6 * 16]; + int32_t __fpu_reserved1; +}; + +struct __darwin_x86_avx_state64 { + int32_t __fpu_reserved[2]; + struct __darwin_fp_control __fpu_fcw; + struct __darwin_fp_status __fpu_fsw; + uint8_t __fpu_ftw; + uint8_t __fpu_rsrv1; + uint16_t __fpu_fop; + uint32_t __fpu_ip; + uint16_t __fpu_cs; + uint16_t __fpu_rsrv2; + uint32_t __fpu_dp; + uint16_t __fpu_ds; + uint16_t __fpu_rsrv3; + uint32_t __fpu_mxcsr; + uint32_t __fpu_mxcsrmask; + struct __darwin_mmst_reg __fpu_stmm0; + struct __darwin_mmst_reg __fpu_stmm1; + struct __darwin_mmst_reg __fpu_stmm2; + struct __darwin_mmst_reg __fpu_stmm3; + struct __darwin_mmst_reg __fpu_stmm4; + struct __darwin_mmst_reg __fpu_stmm5; + struct __darwin_mmst_reg __fpu_stmm6; + struct __darwin_mmst_reg __fpu_stmm7; + struct __darwin_xmm_reg __fpu_xmm0; + struct __darwin_xmm_reg __fpu_xmm1; + struct __darwin_xmm_reg __fpu_xmm2; + struct __darwin_xmm_reg __fpu_xmm3; + struct __darwin_xmm_reg __fpu_xmm4; + struct __darwin_xmm_reg __fpu_xmm5; + struct __darwin_xmm_reg __fpu_xmm6; + struct __darwin_xmm_reg __fpu_xmm7; + struct __darwin_xmm_reg __fpu_xmm8; + struct __darwin_xmm_reg __fpu_xmm9; + struct __darwin_xmm_reg __fpu_xmm10; + struct __darwin_xmm_reg __fpu_xmm11; + struct __darwin_xmm_reg __fpu_xmm12; + struct __darwin_xmm_reg __fpu_xmm13; + struct __darwin_xmm_reg __fpu_xmm14; + struct __darwin_xmm_reg __fpu_xmm15; + char __fpu_rsrv4[6 * 16]; + int32_t __fpu_reserved1; + char __avx_reserved1[64]; + struct __darwin_xmm_reg __fpu_ymmh0; + struct __darwin_xmm_reg __fpu_ymmh1; + struct __darwin_xmm_reg __fpu_ymmh2; + struct __darwin_xmm_reg __fpu_ymmh3; + struct __darwin_xmm_reg __fpu_ymmh4; + struct __darwin_xmm_reg __fpu_ymmh5; + struct __darwin_xmm_reg __fpu_ymmh6; + struct __darwin_xmm_reg __fpu_ymmh7; + struct __darwin_xmm_reg __fpu_ymmh8; + struct __darwin_xmm_reg __fpu_ymmh9; + struct __darwin_xmm_reg __fpu_ymmh10; + struct __darwin_xmm_reg __fpu_ymmh11; + struct __darwin_xmm_reg __fpu_ymmh12; + struct __darwin_xmm_reg __fpu_ymmh13; + struct __darwin_xmm_reg __fpu_ymmh14; + struct __darwin_xmm_reg __fpu_ymmh15; +}; + +struct __darwin_x86_avx512_state64 { + int32_t __fpu_reserved[2]; + struct __darwin_fp_control __fpu_fcw; + struct __darwin_fp_status __fpu_fsw; + uint8_t __fpu_ftw; + uint8_t __fpu_rsrv1; + uint16_t __fpu_fop; + uint32_t __fpu_ip; + uint16_t __fpu_cs; + uint16_t __fpu_rsrv2; + uint32_t __fpu_dp; + uint16_t __fpu_ds; + uint16_t __fpu_rsrv3; + uint32_t __fpu_mxcsr; + uint32_t __fpu_mxcsrmask; + struct __darwin_mmst_reg __fpu_stmm0; + struct __darwin_mmst_reg __fpu_stmm1; + struct __darwin_mmst_reg __fpu_stmm2; + struct __darwin_mmst_reg __fpu_stmm3; + struct __darwin_mmst_reg __fpu_stmm4; + struct __darwin_mmst_reg __fpu_stmm5; + struct __darwin_mmst_reg __fpu_stmm6; + struct __darwin_mmst_reg __fpu_stmm7; + struct __darwin_xmm_reg __fpu_xmm0; + struct __darwin_xmm_reg __fpu_xmm1; + struct __darwin_xmm_reg __fpu_xmm2; + struct __darwin_xmm_reg __fpu_xmm3; + struct __darwin_xmm_reg __fpu_xmm4; + struct __darwin_xmm_reg __fpu_xmm5; + struct __darwin_xmm_reg __fpu_xmm6; + struct __darwin_xmm_reg __fpu_xmm7; + struct __darwin_xmm_reg __fpu_xmm8; + struct __darwin_xmm_reg __fpu_xmm9; + struct __darwin_xmm_reg __fpu_xmm10; + struct __darwin_xmm_reg __fpu_xmm11; + struct __darwin_xmm_reg __fpu_xmm12; + struct __darwin_xmm_reg __fpu_xmm13; + struct __darwin_xmm_reg __fpu_xmm14; + struct __darwin_xmm_reg __fpu_xmm15; + char __fpu_rsrv4[6 * 16]; + int32_t __fpu_reserved1; + char __avx_reserved1[64]; + struct __darwin_xmm_reg __fpu_ymmh0; + struct __darwin_xmm_reg __fpu_ymmh1; + struct __darwin_xmm_reg __fpu_ymmh2; + struct __darwin_xmm_reg __fpu_ymmh3; + struct __darwin_xmm_reg __fpu_ymmh4; + struct __darwin_xmm_reg __fpu_ymmh5; + struct __darwin_xmm_reg __fpu_ymmh6; + struct __darwin_xmm_reg __fpu_ymmh7; + struct __darwin_xmm_reg __fpu_ymmh8; + struct __darwin_xmm_reg __fpu_ymmh9; + struct __darwin_xmm_reg __fpu_ymmh10; + struct __darwin_xmm_reg __fpu_ymmh11; + struct __darwin_xmm_reg __fpu_ymmh12; + struct __darwin_xmm_reg __fpu_ymmh13; + struct __darwin_xmm_reg __fpu_ymmh14; + struct __darwin_xmm_reg __fpu_ymmh15; + struct __darwin_opmask_reg __fpu_k0; + struct __darwin_opmask_reg __fpu_k1; + struct __darwin_opmask_reg __fpu_k2; + struct __darwin_opmask_reg __fpu_k3; + struct __darwin_opmask_reg __fpu_k4; + struct __darwin_opmask_reg __fpu_k5; + struct __darwin_opmask_reg __fpu_k6; + struct __darwin_opmask_reg __fpu_k7; + struct __darwin_ymm_reg __fpu_zmmh0; + struct __darwin_ymm_reg __fpu_zmmh1; + struct __darwin_ymm_reg __fpu_zmmh2; + struct __darwin_ymm_reg __fpu_zmmh3; + struct __darwin_ymm_reg __fpu_zmmh4; + struct __darwin_ymm_reg __fpu_zmmh5; + struct __darwin_ymm_reg __fpu_zmmh6; + struct __darwin_ymm_reg __fpu_zmmh7; + struct __darwin_ymm_reg __fpu_zmmh8; + struct __darwin_ymm_reg __fpu_zmmh9; + struct __darwin_ymm_reg __fpu_zmmh10; + struct __darwin_ymm_reg __fpu_zmmh11; + struct __darwin_ymm_reg __fpu_zmmh12; + struct __darwin_ymm_reg __fpu_zmmh13; + struct __darwin_ymm_reg __fpu_zmmh14; + struct __darwin_ymm_reg __fpu_zmmh15; + struct __darwin_zmm_reg __fpu_zmm16; + struct __darwin_zmm_reg __fpu_zmm17; + struct __darwin_zmm_reg __fpu_zmm18; + struct __darwin_zmm_reg __fpu_zmm19; + struct __darwin_zmm_reg __fpu_zmm20; + struct __darwin_zmm_reg __fpu_zmm21; + struct __darwin_zmm_reg __fpu_zmm22; + struct __darwin_zmm_reg __fpu_zmm23; + struct __darwin_zmm_reg __fpu_zmm24; + struct __darwin_zmm_reg __fpu_zmm25; + struct __darwin_zmm_reg __fpu_zmm26; + struct __darwin_zmm_reg __fpu_zmm27; + struct __darwin_zmm_reg __fpu_zmm28; + struct __darwin_zmm_reg __fpu_zmm29; + struct __darwin_zmm_reg __fpu_zmm30; + struct __darwin_zmm_reg __fpu_zmm31; +}; + +struct __darwin_x86_exception_state64 { + uint16_t __trapno; + uint16_t __cpu; + uint32_t __err; + uint64_t __faultvaddr; +}; + +struct __darwin_x86_debug_state64 { + uint64_t __dr0; + uint64_t __dr1; + uint64_t __dr2; + uint64_t __dr3; + uint64_t __dr4; + uint64_t __dr5; + uint64_t __dr6; + uint64_t __dr7; +}; + +struct __darwin_x86_cpmu_state64 { + uint64_t __ctrs[16]; +}; + +struct __darwin_mcontext64_full { + struct __darwin_x86_exception_state64 __es; + struct __darwin_x86_thread_full_state64 __ss; + struct __darwin_x86_float_state64 __fs; +}; + +struct __darwin_mcontext_avx64 { + struct __darwin_x86_exception_state64 __es; + struct __darwin_x86_thread_state64 __ss; + struct __darwin_x86_avx_state64 __fs; +}; + +struct __darwin_mcontext_avx64_full { + struct __darwin_x86_exception_state64 __es; + struct __darwin_x86_thread_full_state64 __ss; + struct __darwin_x86_avx_state64 __fs; +}; + +struct __darwin_mcontext_avx512_64 { + struct __darwin_x86_exception_state64 __es; + struct __darwin_x86_thread_state64 __ss; + struct __darwin_x86_avx512_state64 __fs; +}; + +struct __darwin_mcontext_avx512_64_full { + struct __darwin_x86_exception_state64 __es; + struct __darwin_x86_thread_full_state64 __ss; + struct __darwin_x86_avx512_state64 __fs; +}; + +struct __darwin_mcontext64 { + struct __darwin_x86_exception_state64 __es; + struct __darwin_x86_thread_state64 __ss; + struct __darwin_x86_float_state64 __fs; +}; + +struct __darwin_ucontext { + int32_t uc_onstack; + uint32_t uc_sigmask; + struct __darwin_sigaltstack uc_stack; + struct __darwin_ucontext *uc_link; + uint64_t uc_mcsize; + struct __darwin_mcontext64 *uc_mcontext; +}; + +static void xnuexceptionstate2linux( + mcontext_t *mc, struct __darwin_x86_exception_state64 *xnues) { + mc->trapno = xnues->__trapno; + mc->err = xnues->__err; +} + +static void xnuthreadstate2linux(ucontext_t *uc, mcontext_t *mc, + struct __darwin_x86_thread_state64 *xnuss) { + mc->rdi = xnuss->__rdi; + mc->rsi = xnuss->__rsi; + mc->rbp = xnuss->__rbp; + mc->rbx = xnuss->__rbx; + mc->rdx = xnuss->__rdx; + mc->rax = xnuss->__rax; + mc->rcx = xnuss->__rcx; + mc->rsp = xnuss->__rsp; + mc->rip = xnuss->__rip; + /* g.uc.uc_mcontext.rip = xnuctx->uc_mcontext->__es.__faultvaddr; */ + mc->cs = xnuss->__cs; + mc->gs = xnuss->__gs; + mc->fs = xnuss->__fs; + mc->eflags = xnuss->__rflags; + uc->uc_flags = xnuss->__rflags; + memcpy(&mc->r8, &xnuss->__r8, 8 * sizeof(int64_t)); +} + +static void xnussefpustate2linux(struct FpuState *fs, + struct __darwin_x86_float_state64 *xnufs) { + memcpy(&fs->cwd, &xnufs->__fpu_fcw, 2); + memcpy(&fs->swd, &xnufs->__fpu_fsw, 2); + fs->ftw = xnufs->__fpu_ftw; + fs->fop = xnufs->__fpu_fop; + fs->rip = xnufs->__fpu_ip; + fs->rdp = xnufs->__fpu_dp; + fs->mxcsr = xnufs->__fpu_mxcsr; + fs->mxcr_mask = xnufs->__fpu_mxcsrmask; + /* copy st0-st7 as well as xmm0-xmm15 */ + memcpy(fs->st, &xnufs->__fpu_stmm0, (8 + 16) * sizeof(uint128_t)); +} + +noreturn void xnutrampoline(void *fn, int infostyle, int sig, + const struct __darwin_siginfo *xnuinfo, + const struct __darwin_ucontext *xnuctx) { + /* note: this function impl can't access static memory */ + intptr_t ax; + struct Goodies { + ucontext_t uc; + siginfo_t si; + } g; + memset(&g, 0, sizeof(g)); + if (xnuctx) { + /* g.uc.uc_sigmask = xnuctx->uc_sigmask; */ + g.uc.uc_stack.ss_sp = xnuctx->uc_stack.ss_sp; + g.uc.uc_stack.ss_flags = xnuctx->uc_stack.ss_flags; + g.uc.uc_stack.ss_size = xnuctx->uc_stack.ss_size; + if (xnuctx->uc_mcontext) { + if (xnuctx->uc_mcsize >= sizeof(struct __darwin_x86_exception_state64)) { + xnuexceptionstate2linux(&g.uc.uc_mcontext, &xnuctx->uc_mcontext->__es); + } + if (xnuctx->uc_mcsize >= (sizeof(struct __darwin_x86_exception_state64) + + sizeof(struct __darwin_x86_thread_state64))) { + xnuthreadstate2linux(&g.uc, &g.uc.uc_mcontext, + &xnuctx->uc_mcontext->__ss); + } + if (xnuctx->uc_mcsize >= sizeof(struct __darwin_mcontext64)) { + xnussefpustate2linux(&g.uc.fpustate, &xnuctx->uc_mcontext->__fs); + } + } + } + if (xnuinfo) { + g.si.si_signo = xnuinfo->si_signo; + g.si.si_errno = xnuinfo->si_errno; + g.si.si_code = xnuinfo->si_code; + if (xnuinfo->si_pid) { + g.si.si_pid = xnuinfo->si_pid; + g.si.si_uid = xnuinfo->si_uid; + g.si.si_status = xnuinfo->si_status; + } else { + g.si.si_addr = (void *)xnuinfo->si_addr; + } + } + __sigenter(sig, &g.si, &g.uc); + asm volatile("syscall" + : "=a"(ax) + : "0"(0x20000b8 /* sigreturn */), "D"(xnuctx), "S"(infostyle) + : "rcx", "r11", "memory", "cc"); + unreachable; +} diff --git a/libc/calls/zygote.c b/libc/calls/zygote.c new file mode 100644 index 00000000..600fd431 --- /dev/null +++ b/libc/calls/zygote.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/nt/struct/securityattributes.h" +#include "libc/calls/internal.h" + +const struct NtSecurityAttributes kNtIsInheritable = { + sizeof(struct NtSecurityAttributes), NULL, true}; diff --git a/libc/complex.h b/libc/complex.h new file mode 100644 index 00000000..a804cdd2 --- /dev/null +++ b/libc/complex.h @@ -0,0 +1,86 @@ +#ifndef COSMOPOLITAN_LIBC_COMPLEX_H_ +#define COSMOPOLITAN_LIBC_COMPLEX_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define complex _Complex +#define imaginary _Imaginary + +complex double cacos(complex double); +complex double cacosh(complex double); +complex double casin(complex double); +complex double casinh(complex double); +complex double catan(complex double); +complex double catanh(complex double); +complex double ccos(complex double); +complex double ccosh(complex double); +complex double cexp(complex double); +complex double cexp2(complex double); +complex double clog(complex double); +complex double conj(complex double); +complex double cpow(complex double, complex double); +complex double cproj(complex double); +complex double csin(complex double); +complex double csinh(complex double); +complex double csqrt(complex double); +complex double ctan(complex double); +complex double ctanh(complex double); + +complex float cacosf(complex float); +complex float cacoshf(complex float); +complex float casinf(complex float); +complex float casinhf(complex float); +complex float catanf(complex float); +complex float catanhf(complex float); +complex float ccosf(complex float); +complex float ccoshf(complex float); +complex float cexpf(complex float); +complex float cexp2f(complex float); +complex float clogf(complex float); +complex float conjf(complex float); +complex float cpowf(complex float, complex float); +complex float cprojf(complex float); +complex float csinf(complex float); +complex float csinhf(complex float); +complex float csqrtf(complex float); +complex float ctanf(complex float); +complex float ctanhf(complex float); + +double cabs(complex double); +double carg(complex double); +double cimag(complex double); +double creal(complex double); + +float cabsf(complex float); +float cargf(complex float); +float cimagf(complex float); +float crealf(complex float); + +long double cabsl(complex long double); +long double cargl(complex long double); +long double cimagl(complex long double); +long double creall(complex long double); + +complex long double cprojl(complex long double); +complex long double csinhl(complex long double); +complex long double csinl(complex long double); +complex long double csqrtl(complex long double); +complex long double ctanhl(complex long double); +complex long double ctanl(complex long double); +complex long double cacoshl(complex long double); +complex long double cacosl(complex long double); +complex long double casinhl(complex long double); +complex long double casinl(complex long double); +complex long double catanhl(complex long double); +complex long double catanl(complex long double); +complex long double ccoshl(complex long double); +complex long double ccosl(complex long double); +complex long double cexpl(complex long double); +complex long double cexp2l(complex long double); +complex long double clogl(complex long double); +complex long double conjl(complex long double); +complex long double cpowl(complex long double, complex long double); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_COMPLEX_H_ */ diff --git a/libc/conv/abs.c b/libc/conv/abs.c new file mode 100644 index 00000000..553bef67 --- /dev/null +++ b/libc/conv/abs.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" + +int(abs)(int x) { + return 0 < x ? x : -x; +} diff --git a/libc/conv/atoi.c b/libc/conv/atoi.c new file mode 100644 index 00000000..cb650b96 --- /dev/null +++ b/libc/conv/atoi.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/conv/strlol.h" +#include "libc/limits.h" + +/** + * Decodes decimal number from ASCII string. + * + * @param s is a non-null NUL-terminated string + * @return the decoded signed saturated number + * @note calling strtoimax() directly with base 0 permits greater + * flexibility in terms of inputs + */ +int atoi(const char *s) { return STRLOL(s, NULL, 10, INT_MIN, INT_MAX); } diff --git a/libc/conv/atol.c b/libc/conv/atol.c new file mode 100644 index 00000000..1f720edc --- /dev/null +++ b/libc/conv/atol.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/conv/strlol.h" +#include "libc/limits.h" + +long atol(const char *s) { return STRLOL(s, NULL, 10, LONG_MIN, LONG_MAX); } diff --git a/libc/conv/atoll.c b/libc/conv/atoll.c new file mode 100644 index 00000000..77ce43c0 --- /dev/null +++ b/libc/conv/atoll.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/conv/strlol.h" +#include "libc/limits.h" + +long long atoll(const char *s) { + return STRLOL(s, NULL, 10, LONG_LONG_MIN, LONG_LONG_MAX); +} diff --git a/libc/conv/basename.c b/libc/conv/basename.c new file mode 100644 index 00000000..da11e0ca --- /dev/null +++ b/libc/conv/basename.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/conv/isslash.h" +#include "libc/str/str.h" + +/** + * Returns pointer to last filename component in path. + * + * Both / and \ are are considered valid component separators on all + * platforms. Trailing slashes are ignored. We don't grant special + * consideration to things like foo/., c:/, \\?\Volume, etc. + * + * @param path is NUL-terminated UTF-8 path + * @return pointer inside path or path itself + */ +char *basename(const char *path) { return basename_n(path, strlen(path)); } diff --git a/libc/conv/basename_n.c b/libc/conv/basename_n.c new file mode 100644 index 00000000..07266275 --- /dev/null +++ b/libc/conv/basename_n.c @@ -0,0 +1,50 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/conv/isslash.h" + +/** + * Returns pointer to last filename component in path. + * + * Both / and \ are are considered valid component separators on all + * platforms. Trailing slashes are ignored. We don't grant special + * consideration to things like foo/., c:/, \\?\Volume, etc. + * + * @param path is UTF-8 path + * @param size is byte length of path + * @return pointer inside path or path itself + */ +char *basename_n(const char *path, size_t size) { + size_t i, l; + if (size) { + if (isslash(path[size - 1])) { + l = size - 1; + while (isslash(path[l - 1])) --l; + if (!l) return (/*unconst*/ char *)&path[size - 1]; + size = l; + } + for (i = size; i > 0; --i) { + if (isslash(path[i - 1])) { + return (/*unconst*/ char *)&path[i]; + } + } + } + return (/*unconst*/ char *)path; +} diff --git a/libc/conv/conv.h b/libc/conv/conv.h new file mode 100644 index 00000000..353ed022 --- /dev/null +++ b/libc/conv/conv.h @@ -0,0 +1,109 @@ +#ifndef COSMOPOLITAN_LIBC_CONV_CONV_H_ +#define COSMOPOLITAN_LIBC_CONV_CONV_H_ + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § conversion ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +/** + * COBOL timestamp (1601) for UNIX epoch (1970). + * + * It's a well-known fact in the social sciences that the introduction + * of the UNIX operation system signalled the end of modernity. Windows + * timestamps are living proof. + */ +#define MODERNITYSECONDS 11644473600 +#define HECTONANOSECONDS 10000000 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +int abs(int) libcesque pureconst; +long labs(long) libcesque pureconst; +long long llabs(long long) libcesque pureconst; +char *ltpcpy(char *, long) paramsnonnull() libcesque nocallback; +int llog10(unsigned long) libcesque pureconst; +int atoi(const char *) paramsnonnull() libcesque nosideeffect; +long atol(const char *) paramsnonnull() libcesque nosideeffect; +long long atoll(const char *) paramsnonnull() libcesque nosideeffect; +unsigned long strtoul(const char *, char **, int) paramsnonnull((1)); +long long strtoll(const char *, char **, int) paramsnonnull((1)); +unsigned long long strtoull(const char *, char **, int) paramsnonnull((1)); +long long strtonum(const char *, long long, long long, const char **); +intmax_t div10(intmax_t x, unsigned *rem) hidden; +intmax_t strtoimax(const char *, char **, int) paramsnonnull((1)); +uintmax_t strtoumax(const char *, char **, int) paramsnonnull((1)); +intmax_t wcstoimax(const wchar_t *, wchar_t **, int); +long wcstol(const wchar_t *, wchar_t **, int); +long strtol(const char *, char **, int) + paramsnonnull((1)) libcesque nosideeffect; + +intmax_t __imaxabs(intmax_t) asm("imaxabs") libcesque pureconst; +#define imaxabs(x) __imaxabs(x) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § conversion » time ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +struct NtFileTime; +struct timespec; +struct timeval; + +void filetimetotimespec(struct timespec *, struct NtFileTime) paramsnonnull(); +struct NtFileTime timetofiletime(int64_t) nothrow pureconst; +int64_t filetimetotime(struct NtFileTime) nothrow pureconst; +void filetimetotimeval(struct timeval *, struct NtFileTime) nothrow; +struct NtFileTime timevaltofiletime(const struct timeval *) nosideeffect; +long convertmicros(const struct timeval *, long) paramsnonnull() nosideeffect; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § conversion » manipulation ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +char *basename(const char *) nosideeffect; +char *basename_n(const char *, size_t) nosideeffect; +bool isabspath(const char *) paramsnonnull() nosideeffect; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § conversion » computation ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +typedef struct { + int quot; + int rem; +} div_t; + +typedef struct { + long int quot; + long int rem; +} ldiv_t; + +typedef struct { + long long int quot; + long long int rem; +} lldiv_t; + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +div_t div(int, int) pureconst; +ldiv_t ldiv(long, long) pureconst; +lldiv_t lldiv(long long, long long) pureconst; +imaxdiv_t imaxdiv(intmax_t, intmax_t) pureconst; +double RoundDecimalPlaces(double, double, double(double)); + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § conversion » optimizations ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#if __STDC_VERSION__ + 0 >= 199901L +#define div(num, den) ((div_t){(num) / (den), (num) % (den)}) +#define ldiv(num, den) ((ldiv_t){(num) / (den), (num) % (den)}) +#define lldiv(num, den) ((lldiv_t){(num) / (den), (num) % (den)}) +#endif + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CONV_CONV_H_ */ diff --git a/libc/conv/conv.mk b/libc/conv/conv.mk new file mode 100644 index 00000000..9d115526 --- /dev/null +++ b/libc/conv/conv.mk @@ -0,0 +1,75 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ +# +# SYNOPSIS +# +# Cosmopolitan Data Conversions +# +# DESCRIPTION +# +# This package provides functions that convert between data types. +# It's intended to be lower level than the memory and formatting +# libraries. + +PKGS += LIBC_CONV + +LIBC_CONV_ARTIFACTS += LIBC_CONV_A +LIBC_CONV = $(LIBC_CONV_A_DEPS) $(LIBC_CONV_A) +LIBC_CONV_A = o/$(MODE)/libc/conv/conv.a +LIBC_CONV_A_FILES := $(wildcard libc/conv/*) +LIBC_CONV_A_HDRS = $(filter %.h,$(LIBC_CONV_A_FILES)) +LIBC_CONV_A_SRCS_S = $(filter %.S,$(LIBC_CONV_A_FILES)) +LIBC_CONV_A_SRCS_C = $(filter %.c,$(LIBC_CONV_A_FILES)) + +LIBC_CONV_A_SRCS = \ + $(LIBC_CONV_A_SRCS_S) \ + $(LIBC_CONV_A_SRCS_C) + +LIBC_CONV_A_OBJS = \ + $(LIBC_CONV_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_CONV_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_CONV_A_SRCS_C:%.c=o/$(MODE)/%.o) + +LIBC_CONV_A_CHECKS = \ + $(LIBC_CONV_A).pkg \ + $(LIBC_CONV_A_HDRS:%=o/$(MODE)/%.ok) + +LIBC_CONV_A_DIRECTDEPS = \ + LIBC_STUBS \ + LIBC_NEXGEN32E \ + LIBC_TINYMATH \ + LIBC_SYSV + +LIBC_CONV_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_CONV_A_DIRECTDEPS),$($(x)))) + +$(LIBC_CONV_A): libc/conv/ \ + $(LIBC_CONV_A).pkg \ + $(LIBC_CONV_A_OBJS) + +$(LIBC_CONV_A).pkg: \ + $(LIBC_CONV_A_OBJS) \ + $(foreach x,$(LIBC_CONV_A_DIRECTDEPS),$($(x)_A).pkg) + +#o/$(MODE)/libc/conv/strtoimax.o: CC = clang-10 +#o/$(MODE)/libc/conv/strtoumax.o: CC = clang-10 + +o/$(MODE)/libc/conv/itoa64radix10.o \ +o/$(MODE)/libc/conv/timetofiletime.o \ +o/$(MODE)/libc/conv/filetimetotime.o \ +o/$(MODE)/libc/conv/filetimetotimespec.o \ +o/$(MODE)/libc/conv/filetimetotimeval.o: \ + OVERRIDE_COPTS += \ + -O3 + +LIBC_CONV_LIBS = $(foreach x,$(LIBC_CONV_ARTIFACTS),$($(x))) +LIBC_CONV_SRCS = $(foreach x,$(LIBC_CONV_ARTIFACTS),$($(x)_SRCS)) +LIBC_CONV_HDRS = $(foreach x,$(LIBC_CONV_ARTIFACTS),$($(x)_HDRS)) +LIBC_CONV_BINS = $(foreach x,$(LIBC_CONV_ARTIFACTS),$($(x)_BINS)) +LIBC_CONV_CHECKS = $(foreach x,$(LIBC_CONV_ARTIFACTS),$($(x)_CHECKS)) +LIBC_CONV_OBJS = $(foreach x,$(LIBC_CONV_ARTIFACTS),$($(x)_OBJS)) +LIBC_CONV_TESTS = $(foreach x,$(LIBC_CONV_ARTIFACTS),$($(x)_TESTS)) +$(LIBC_CONV_OBJS): $(BUILD_FILES) libc/conv/conv.mk + +.PHONY: o/$(MODE)/libc/conv +o/$(MODE)/libc/conv: $(LIBC_CONV_CHECKS) diff --git a/libc/conv/convertmicros.c b/libc/conv/convertmicros.c new file mode 100644 index 00000000..305782a5 --- /dev/null +++ b/libc/conv/convertmicros.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/struct/timeval.h" +#include "libc/conv/conv.h" +#include "libc/time/time.h" + +long convertmicros(const struct timeval *tv, long tick) { + return tv->tv_sec * tick + tv->tv_usec / (1000000 / tick); +} diff --git a/libc/conv/div.c b/libc/conv/div.c new file mode 100644 index 00000000..9321feb8 --- /dev/null +++ b/libc/conv/div.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" + +div_t(div)(int num, int den) { return div(num, den); } diff --git a/libc/conv/filetimetotime.c b/libc/conv/filetimetotime.c new file mode 100644 index 00000000..de05c401 --- /dev/null +++ b/libc/conv/filetimetotime.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/nt/struct/filetime.h" + +int64_t filetimetotime(struct NtFileTime ft) { + uint64_t t = (uint64_t)ft.dwHighDateTime << 32 | ft.dwLowDateTime; + return (t - MODERNITYSECONDS * HECTONANOSECONDS) / HECTONANOSECONDS; +} diff --git a/libc/conv/filetimetotimespec.c b/libc/conv/filetimetotimespec.c new file mode 100644 index 00000000..c6a7d8a4 --- /dev/null +++ b/libc/conv/filetimetotimespec.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/conv/conv.h" +#include "libc/nt/struct/filetime.h" + +/** + * Converts Windows COBOL timestamp to UNIX epoch in nanoseconds. + */ +void filetimetotimespec(struct timespec *ts, struct NtFileTime ft) { + uint64_t t = (uint64_t)ft.dwHighDateTime << 32 | ft.dwLowDateTime; + uint64_t x = t - MODERNITYSECONDS * HECTONANOSECONDS; + ts->tv_sec = x / HECTONANOSECONDS; + ts->tv_nsec = x % HECTONANOSECONDS * 100; +} diff --git a/libc/conv/filetimetotimeval.c b/libc/conv/filetimetotimeval.c new file mode 100644 index 00000000..d489ab0e --- /dev/null +++ b/libc/conv/filetimetotimeval.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/struct/timeval.h" +#include "libc/conv/conv.h" +#include "libc/nt/struct/filetime.h" + +void filetimetotimeval(struct timeval *tv, struct NtFileTime ft) { + uint64_t t = (uint64_t)ft.dwHighDateTime << 32 | ft.dwLowDateTime; + uint64_t x = t - MODERNITYSECONDS * HECTONANOSECONDS; + tv->tv_sec = x / HECTONANOSECONDS; + tv->tv_usec = x % HECTONANOSECONDS / 10; +} diff --git a/libc/conv/imaxabs.c b/libc/conv/imaxabs.c new file mode 100644 index 00000000..c5f88f34 --- /dev/null +++ b/libc/conv/imaxabs.c @@ -0,0 +1,25 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/macros.h" + +intmax_t imaxabs(intmax_t x) { + return ABS(x); +} diff --git a/libc/conv/isabspath.c b/libc/conv/isabspath.c new file mode 100644 index 00000000..18f7b934 --- /dev/null +++ b/libc/conv/isabspath.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/conv/isslash.h" + +/** + * Returns true if pathname could be absolute on any known platform. + * + * The ones we know about are System V (/foo/bar), DOS (C:\foo\bar), + * Windows NT (\\.\C:\foo\bar), Google Cloud (gs://bucket/foo/bar), etc. + */ +bool isabspath(const char *path) { + if (isslash(*path)) return true; + for (; *path; ++path) { + if (isslash(*path)) return false; + if (*path == ':') { + ++path; + if (isslash(*path)) return true; + } + } + return false; +} diff --git a/libc/conv/isslash.h b/libc/conv/isslash.h new file mode 100644 index 00000000..63f7a15c --- /dev/null +++ b/libc/conv/isslash.h @@ -0,0 +1,8 @@ +#ifndef COSMOPOLITAN_LIBC_CONV_ISSLASH_H_ +#define COSMOPOLITAN_LIBC_CONV_ISSLASH_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +forceinline bool isslash(int c) { return c == '/' || c == '\\'; } + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CONV_ISSLASH_H_ */ diff --git a/libc/conv/itoa.h b/libc/conv/itoa.h new file mode 100644 index 00000000..437c1b57 --- /dev/null +++ b/libc/conv/itoa.h @@ -0,0 +1,36 @@ +#ifndef COSMOPOLITAN_LIBC_CONV_ITOA_H_ +#define COSMOPOLITAN_LIBC_CONV_ITOA_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/* + + FASTEST + TINY + + - uint64toarray_radix10(0x31337, a) l: 68 (20ns) m: 112 (33ns) + - int64toarray_radix10(0x31337, a) l: 69 (20ns) m: 134 (39ns) + + FAST + AWESOME + + - snprintf(a, sizeof(a), "%d", 0x31337) l: 199 (58ns) m: 421 (123ns) + - uint128toarray_radix10(0x31337, a) l: 93 (27ns) m: 141 (41ns) + - int128toarray_radix10(0x31337, a) l: 96 (28ns) m: 173 (51ns) + + SLOWEST + GENERAL + + - int64toarray(0x31337, a, 10) l: 218 (64ns) m: 262 (77ns) + - uint64toarray(0x31337, a, 10) l: 565 (166ns) m: 260 (76ns) + +*/ + +size_t int128toarray_radix10(int128_t, char *); +size_t uint128toarray_radix10(uint128_t, char *); +size_t int64toarray_radix10(int64_t, char *); +size_t uint64toarray_radix10(uint64_t, char *); +size_t int64toarray(int64_t, char *, int); +size_t uint64toarray(uint64_t, char *, int); +size_t uint64toarray_radix16(uint64_t, char[hasatleast 17]); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CONV_ITOA_H_ */ diff --git a/libc/conv/itoa128radix10.greg.c b/libc/conv/itoa128radix10.greg.c new file mode 100644 index 00000000..46033b80 --- /dev/null +++ b/libc/conv/itoa128radix10.greg.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/reverse.h" +#include "libc/conv/conv.h" +#include "libc/conv/itoa.h" + +noinline size_t uint128toarray_radix10(uint128_t i, char *a) { + size_t j; + unsigned rem; + j = 0; + do { + i = div10(i, &rem); + a[j++] = rem + '0'; + } while (i > 0); + a[j] = '\0'; + reverse(a, j); + return j; +} + +size_t int128toarray_radix10(int128_t i, char *a) { + if (i < 0) { + *a++ = '-'; + i = -i; + } + return uint128toarray_radix10(i, a); +} diff --git a/libc/conv/itoa64.c b/libc/conv/itoa64.c new file mode 100644 index 00000000..78086bca --- /dev/null +++ b/libc/conv/itoa64.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/reverse.h" +#include "libc/conv/conv.h" +#include "libc/conv/itoa.h" + +noinline size_t uint64toarray(uint64_t i, char *a, int r) { + size_t j; + j = 0; + do { + a[j++] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i % r]; + i /= r; + } while (i > 0); + a[j] = '\0'; + reverse(a, j); + return j; +} + +size_t int64toarray(int64_t i, char *a, int r) { + if (i < 0) { + *a++ = '-'; + i = -i; + } + return uint64toarray(i, a, r); +} diff --git a/libc/conv/itoa64radix10.greg.c b/libc/conv/itoa64radix10.greg.c new file mode 100644 index 00000000..37e7b6ff --- /dev/null +++ b/libc/conv/itoa64radix10.greg.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/reverse.h" +#include "libc/conv/conv.h" +#include "libc/conv/itoa.h" + +noinline size_t uint64toarray_radix10(uint64_t i, char *a) { + size_t j; + j = 0; + do { + a[j++] = i % 10 + '0'; + i /= 10; + } while (i > 0); + a[j] = '\0'; + reverse(a, j); + return j; +} + +size_t int64toarray_radix10(int64_t i, char *a) { + if (i < 0) { + *a++ = '-'; + i = -i; + } + return uint64toarray_radix10(i, a); +} diff --git a/libc/conv/itoa64radix16.greg.c b/libc/conv/itoa64radix16.greg.c new file mode 100644 index 00000000..56e5ed1b --- /dev/null +++ b/libc/conv/itoa64radix16.greg.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/reverse.h" +#include "libc/conv/conv.h" + +size_t uint64toarray_radix16(uint64_t i, char a[hasatleast 17]) { + size_t j; + unsigned char d; + j = 0; + do { + d = i % 16; + a[j++] = d < 10 ? d + '0' : d + 'a'; + i /= 16; + } while (i > 0); + a[j] = '\0'; + reverse(a, j); + return j; +} diff --git a/libc/conv/labs.c b/libc/conv/labs.c new file mode 100644 index 00000000..ceded9b7 --- /dev/null +++ b/libc/conv/labs.c @@ -0,0 +1,23 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/macros.h" + +long(labs)(long x) { return ABS(x); } diff --git a/libc/conv/ldiv.c b/libc/conv/ldiv.c new file mode 100644 index 00000000..361b693c --- /dev/null +++ b/libc/conv/ldiv.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" + +ldiv_t(ldiv)(long num, long den) { return ldiv(num, den); } diff --git a/libc/conv/llabs.c b/libc/conv/llabs.c new file mode 100644 index 00000000..19998f49 --- /dev/null +++ b/libc/conv/llabs.c @@ -0,0 +1,23 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/macros.h" + +long long(llabs)(long long x) { return ABS(x); } diff --git a/libc/conv/lldiv.c b/libc/conv/lldiv.c new file mode 100644 index 00000000..e3c3e971 --- /dev/null +++ b/libc/conv/lldiv.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" + +lldiv_t(lldiv)(long long num, long long den) { return lldiv(num, den); } diff --git a/libc/conv/ltpcpy.c b/libc/conv/ltpcpy.c new file mode 100644 index 00000000..52be48c2 --- /dev/null +++ b/libc/conv/ltpcpy.c @@ -0,0 +1,32 @@ +/*-*- mode:c; indent-tabs-mode:nil; tab-width:2; coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/conv/conv.h" + +char *ltpcpy(char *dst, long x) { + unsigned len = llog10(abs(x)) + 1; + if (x < 0) *dst++ = '-'; + unsigned i = len; + do { + dst[--i] = '0' + x % 10; + x /= 10; + } while (i); + return dst + len; +} diff --git a/libc/conv/rounddecimalplaces.c b/libc/conv/rounddecimalplaces.c new file mode 100644 index 00000000..3ee5b52a --- /dev/null +++ b/libc/conv/rounddecimalplaces.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/math.h" + +double RoundDecimalPlaces(double f, double digs, double rounder(double)) { + if (!(0 <= digs && digs < 15)) { + return f; + } else { + return rounder(f * exp10(digs)) / exp10(digs); + } +} diff --git a/libc/conv/sizemultiply.h b/libc/conv/sizemultiply.h new file mode 100644 index 00000000..9323d6fe --- /dev/null +++ b/libc/conv/sizemultiply.h @@ -0,0 +1,28 @@ +#ifndef COSMOPOLITAN_LIBC_CONV_SIZEMULTIPLY_H_ +#define COSMOPOLITAN_LIBC_CONV_SIZEMULTIPLY_H_ +#include "libc/limits.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * Multiplies memory sizes. + * + * @param count may be 0 to for realloc() → free() behavior + * @param opt_out set to count*itemsize or SIZE_MAX on overflow + * @return true on success or false on overflow + */ +forceinline bool sizemultiply(size_t *opt_out, size_t count, size_t itemsize) { + size_t res = 0; + bool overflowed = false; + if (count != 0) { + res = count * itemsize; + if (((count | itemsize) & ~0xfffful) && (res / count != itemsize)) { + overflowed = true; + res = SIZE_MAX; + } + } + if (opt_out) *opt_out = res; + return !overflowed; +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CONV_SIZEMULTIPLY_H_ */ diff --git a/libc/conv/strlol.h b/libc/conv/strlol.h new file mode 100644 index 00000000..2f1d1f5d --- /dev/null +++ b/libc/conv/strlol.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_COMPAT_STRLOL_H_ +#define COSMOPOLITAN_LIBC_COMPAT_STRLOL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define STRLOL(STR, ENDPTR, OPTIONAL_BASE, MIN, MAX) \ + ({ \ + intmax_t res = strtoimax(STR, ENDPTR, OPTIONAL_BASE); \ + if (res < MIN) return MIN; \ + if (res > MAX) return MAX; \ + res; \ + }) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_COMPAT_STRLOL_H_ */ diff --git a/libc/conv/strtoimax.c b/libc/conv/strtoimax.c new file mode 100644 index 00000000..c93576a4 --- /dev/null +++ b/libc/conv/strtoimax.c @@ -0,0 +1,109 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/limits.h" +#include "libc/nexgen32e/bsr.h" +#include "libc/str/str.h" + +/** + * Decodes 128-bit signed integer from ASCII string. + * + * @param s is a non-NULL NUL-terminated string + * @param endptr if non-NULL will always receive a pointer to the char + * following the last one this function processed, which is usually + * the NUL byte, or in the case of invalid strings, would point to + * the first invalid character + * @param base can be anywhere between [2,36] or 0 to auto-detect based + * on the the prefixes 0 (octal), 0x (hexadecimal), 0b (binary), or + * decimal (base 10) by default. + * @return the decoded saturated number + * @see strtoumax + */ +intmax_t strtoimax(const char *s, char **endptr, int base) { + bool neg; + uintmax_t x; + intmax_t res; + unsigned diglet, bits; + + x = 0; + bits = 0; + neg = false; + + while (isspace(*s)) { + s++; + } + + switch (*s) { + case '-': + neg = true; + /* 𝑠𝑙𝑖𝑑𝑒 */ + case '+': + s++; + break; + default: + break; + } + + if (!(2 <= base && base <= 36)) { + if (*s == '0') { + s++; + if (*s == 'x' || *s == 'X') { + s++; + base = 16; + } else if (*s == 'b' || *s == 'B') { + s++; + base = 2; + } else { + base = 8; + } + } else { + base = 10; + } + } + + for (;;) { + diglet = kBase36[*s & 0xff]; + if (!diglet || diglet > base) break; + diglet -= 1; + if (!diglet || !x || (bits = bsr(diglet) + bsrmax(x)) < 127) { + s++; + x *= base; + x += diglet; + } else if (neg) { + if (bits == 127) { + x *= base; + x += diglet; + if (x == INTMAX_MIN) s++; + } + x = INTMAX_MIN; + break; + } else { + x = INTMAX_MAX; + break; + } + } + + if (endptr) { + *endptr = s; + } + + res = x; + return neg ? -res : res; +} diff --git a/libc/conv/strtol.c b/libc/conv/strtol.c new file mode 100644 index 00000000..f209891c --- /dev/null +++ b/libc/conv/strtol.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/conv/strlol.h" +#include "libc/limits.h" + +/** + * Converts string to number. + * + * @param optional_base is recommended as 0 for flexidecimal + */ +long strtol(const char *s, char **opt_out_end, int optional_base) { + return STRLOL(s, opt_out_end, optional_base, LONG_MIN, LONG_MAX); +} diff --git a/libc/conv/strtoll.c b/libc/conv/strtoll.c new file mode 100644 index 00000000..aae22434 --- /dev/null +++ b/libc/conv/strtoll.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/conv/strlol.h" +#include "libc/limits.h" + +long long strtoll(const char *s, char **endptr, int optional_base) { + return STRLOL(s, endptr, optional_base, LONG_LONG_MIN, LONG_LONG_MAX); +} diff --git a/libc/conv/strtonum.c b/libc/conv/strtonum.c new file mode 100644 index 00000000..e3874ecf --- /dev/null +++ b/libc/conv/strtonum.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +/** + * Converts string to integer, the BSD way. + */ +long long strtonum(const char *nptr, long long minval, long long maxval, + const char **errstr) { + char *end; + intmax_t res = strtoimax(nptr, &end, 10); + if (res < minval || res > maxval || end != nptr + strlen(nptr)) { + if (errstr) *errstr = "bad number"; + return einval(); + } else { + if (errstr) *errstr = NULL; + return res; + } +} diff --git a/libc/conv/strtoul.c b/libc/conv/strtoul.c new file mode 100644 index 00000000..16505022 --- /dev/null +++ b/libc/conv/strtoul.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/conv/strlol.h" +#include "libc/limits.h" + +unsigned long strtoul(const char *s, char **endptr, int optional_base) { + return STRLOL(s, endptr, optional_base, ULONG_MIN, ULONG_MAX); +} diff --git a/libc/conv/strtoull.c b/libc/conv/strtoull.c new file mode 100644 index 00000000..b87e55ca --- /dev/null +++ b/libc/conv/strtoull.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/conv/strlol.h" +#include "libc/limits.h" + +unsigned long long strtoull(const char *s, char **endptr, int optional_base) { + return STRLOL(s, endptr, optional_base, ULONG_LONG_MIN, ULONG_LONG_MAX); +} diff --git a/libc/conv/strtoumax.c b/libc/conv/strtoumax.c new file mode 100644 index 00000000..da06a947 --- /dev/null +++ b/libc/conv/strtoumax.c @@ -0,0 +1,64 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/str/str.h" + +/** + * Decodes 128-bit unsigned integer from ASCII string. + * + * This is a more restricted form of strtoimax() that's useful for folks + * needing to decode numbers in the range [1^127, 1^128). + */ +uintmax_t strtoumax(const char *s, char **endptr, int base) { + const unsigned char *p = (const unsigned char *)s; + uintmax_t res = 0; + + while (isspace(*p)) { + p++; + } + + if (!base) { + if (*p == '0') { + p++; + if (*p == 'x' || *p == 'X') { + p++; + base = 16; + } else if (*p == 'b' || *p == 'B') { + p++; + base = 2; + } else { + base = 8; + } + } else { + base = 10; + } + } + + for (;;) { + unsigned diglet = kBase36[*p]; + if (!diglet || diglet > base) break; + p++; + res *= base; + res += diglet - 1; + } + + if (endptr) *endptr = (char *)p; + return res; +} diff --git a/libc/conv/timetofiletime.c b/libc/conv/timetofiletime.c new file mode 100644 index 00000000..a7266240 --- /dev/null +++ b/libc/conv/timetofiletime.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/nt/struct/filetime.h" + +struct NtFileTime timetofiletime(int64_t t) { + uint64_t t2 = (t + MODERNITYSECONDS) * HECTONANOSECONDS; + return (struct NtFileTime){(uint32_t)t2, (uint32_t)(t2 >> 32)}; +} diff --git a/libc/conv/timevaltofiletime.c b/libc/conv/timevaltofiletime.c new file mode 100644 index 00000000..eeb55f2d --- /dev/null +++ b/libc/conv/timevaltofiletime.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/struct/timeval.h" +#include "libc/conv/conv.h" +#include "libc/nt/struct/filetime.h" +#include "libc/time/time.h" + +struct NtFileTime timevaltofiletime(const struct timeval *tv) { + uint64_t t2 = tv->tv_sec * HECTONANOSECONDS + tv->tv_usec * 10 + + MODERNITYSECONDS * HECTONANOSECONDS; + return (struct NtFileTime){(uint32_t)t2, (uint32_t)(t2 >> 32)}; +} diff --git a/libc/conv/wcslol.h b/libc/conv/wcslol.h new file mode 100644 index 00000000..45137aa9 --- /dev/null +++ b/libc/conv/wcslol.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_CONV_WCSLOL_H_ +#define COSMOPOLITAN_LIBC_CONV_WCSLOL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define WCSLOL(STR, ENDPTR, OPTIONAL_BASE, MIN, MAX) \ + ({ \ + intmax_t res = wcstoimax(STR, ENDPTR, OPTIONAL_BASE); \ + if (res < MIN) return MIN; \ + if (res > MAX) return MAX; \ + res; \ + }) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CONV_WCSLOL_H_ */ diff --git a/libc/conv/wcstoimax.c b/libc/conv/wcstoimax.c new file mode 100644 index 00000000..252e0297 --- /dev/null +++ b/libc/conv/wcstoimax.c @@ -0,0 +1,69 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/str/str.h" + +intmax_t wcstoimax(const wchar_t *s, wchar_t **endptr, int base) { + intmax_t res = 0; + int neg = 0; + + while (iswspace(*s)) { + s++; + } + + switch (*s) { + case '-': + neg = 1; + /* fallthrough */ + case '+': + s++; + break; + default: + break; + } + + if (!base) { + if (*s == '0') { + s++; + if (*s == 'x' || *s == 'X') { + s++; + base = 16; + } else if (*s == 'b' || *s == 'B') { + s++; + base = 2; + } else { + base = 8; + } + } else { + base = 10; + } + } + + for (;;) { + unsigned diglet = kBase36[*s]; + if (!diglet || diglet > base) break; + s++; + res *= base; /* needs __muloti4() w/ clang */ + res -= diglet - 1; + } + + if (endptr) *endptr = (wchar_t *)s; + return neg ? res : -res; +} diff --git a/libc/conv/wcstol.c b/libc/conv/wcstol.c new file mode 100644 index 00000000..e2cbc2c5 --- /dev/null +++ b/libc/conv/wcstol.c @@ -0,0 +1,27 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/conv/wcslol.h" +#include "libc/limits.h" +#include "libc/str/str.h" + +long wcstol(const wchar_t *s, wchar_t **end, int opt_base) { + return WCSLOL(s, end, opt_base, LONG_MIN, LONG_MAX); +} diff --git a/libc/crt/crt.S b/libc/crt/crt.S new file mode 100644 index 00000000..4a48c8b7 --- /dev/null +++ b/libc/crt/crt.S @@ -0,0 +1,56 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/macros.h" +#include "libc/notice.inc" +#include "libc/runtime/internal.h" +.section .start,"ax",@progbits +.yoink __FILE__ + +/ System Five userspace program entrypoint. +/ +/ @param rsp is [n,argv₀..argvₙ₋₁,0,envp₀..,0,auxv₀..,0,..] +/ @note FreeBSD is special (see freebsd/lib/csu/amd64/...) +/ @noreturn +_start_xnu: + movb $XNU,hostos(%rip) + jmp 0f +_start: test %rdi,%rdi + cmovnz %rdi,%rsp + jz 0f + movb $FREEBSD,hostos(%rip) +0: movslq (%rsp),%r12 # argc + lea 8(%rsp),%r13 # argv + lea 24(%rsp,%r12,8),%r14 # envp + .weak idata.iat,idata.iatend + ezlea missingno,ax # make win32 imps noop + ezlea idata.iat,di + ezlea idata.iatend,cx + sub %rdi,%rcx + shr $3,%ecx + rep stosq + xor %eax,%eax # find end of environ + or $-1,%ecx + mov %r14,%rdi + repnz scasq + mov %rdi,%r15 # auxv + jmp __executive + .endfn _start,weak,hidden + .endfn _start_xnu,weak,hidden diff --git a/libc/crt/crt.mk b/libc/crt/crt.mk new file mode 100644 index 00000000..febf456e --- /dev/null +++ b/libc/crt/crt.mk @@ -0,0 +1,30 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ +# +# SYNOPSIS +# +# Cosmopolitan C Runtime. +# +# OVERVIEW +# +# This is a special object library defining the Cosmopolitan SysV +# userspace runtime entrypoint, i.e. _start(). The $(CRT) argument +# should come first in the link order when building ELF binaries; +# becauseo it's the lowest level function; it wraps main(); and it +# decides which runtime support libraries get schlepped into builds. +# +# Please note that, when building an αcτµαlly pδrταblε εxεcµταblε, +# lower-level entrypoints exist and as such, $(CRT) will generally +# come second in link-order after $(APE). + +PKGS += CRT + +CRT_ARTIFACTS += CRT +CRT = o/$(MODE)/libc/crt/crt.o +CRT_FILES = libc/crt/crt.S +CRT_SRCS = libc/crt/crt.S +CRT_OBJS = o/$(MODE)/libc/crt/crt.o o/$(MODE)/libc/crt/crt.S.zip.o +$(CRT_OBJS): $(BUILD_FILES) libc/crt/crt.mk + +.PHONY: o/$(MODE)/libc/crt +o/$(MODE)/libc/crt: $(CRT) diff --git a/libc/crypto/crypto.mk b/libc/crypto/crypto.mk new file mode 100644 index 00000000..cca3711c --- /dev/null +++ b/libc/crypto/crypto.mk @@ -0,0 +1,56 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += LIBC_CRYPTO + +LIBC_CRYPTO_ARTIFACTS += LIBC_CRYPTO_A +LIBC_CRYPTO = $(LIBC_CRYPTO_A_DEPS) $(LIBC_CRYPTO_A) +LIBC_CRYPTO_A = o/$(MODE)/libc/crypto/crypto.a +LIBC_CRYPTO_A_FILES := $(wildcard libc/crypto/*) +LIBC_CRYPTO_A_HDRS = $(filter %.h,$(LIBC_CRYPTO_A_FILES)) +LIBC_CRYPTO_A_SRCS_A = $(filter %.s,$(LIBC_CRYPTO_A_FILES)) +LIBC_CRYPTO_A_SRCS_S = $(filter %.S,$(LIBC_CRYPTO_A_FILES)) +LIBC_CRYPTO_A_SRCS_C = $(filter %.c,$(LIBC_CRYPTO_A_FILES)) + +LIBC_CRYPTO_A_SRCS = \ + $(LIBC_CRYPTO_A_SRCS_A) \ + $(LIBC_CRYPTO_A_SRCS_S) \ + $(LIBC_CRYPTO_A_SRCS_C) + +LIBC_CRYPTO_A_OBJS = \ + $(LIBC_CRYPTO_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_CRYPTO_A_SRCS_A:%.s=o/$(MODE)/%.o) \ + $(LIBC_CRYPTO_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_CRYPTO_A_SRCS_C:%.c=o/$(MODE)/%.o) + +LIBC_CRYPTO_A_CHECKS = \ + $(LIBC_CRYPTO_A).pkg \ + $(LIBC_CRYPTO_A_HDRS:%=o/$(MODE)/%.ok) + +LIBC_CRYPTO_A_DIRECTDEPS = \ + LIBC_STUBS \ + LIBC_NEXGEN32E + +LIBC_CRYPTO_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_CRYPTO_A_DIRECTDEPS),$($(x)))) + +$(LIBC_CRYPTO_A): \ + libc/crypto/ \ + $(LIBC_CRYPTO_A).pkg \ + $(LIBC_CRYPTO_A_OBJS) + +$(LIBC_CRYPTO_A).pkg: \ + $(LIBC_CRYPTO_A_OBJS) \ + $(foreach x,$(LIBC_CRYPTO_A_DIRECTDEPS),$($(x)_A).pkg) + +LIBC_CRYPTO_LIBS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x))) +LIBC_CRYPTO_SRCS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_SRCS)) +LIBC_CRYPTO_HDRS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_HDRS)) +LIBC_CRYPTO_BINS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_BINS)) +LIBC_CRYPTO_CHECKS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_CHECKS)) +LIBC_CRYPTO_OBJS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_OBJS)) +LIBC_CRYPTO_TESTS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_TESTS)) +$(LIBC_CRYPTO_OBJS): $(BUILD_FILES) libc/crypto/crypto.mk + +.PHONY: o/$(MODE)/libc/crypto +o/$(MODE)/libc/crypto: $(LIBC_CRYPTO_CHECKS) diff --git a/libc/crypto/invmixcolumns.c b/libc/crypto/invmixcolumns.c new file mode 100644 index 00000000..35e04137 --- /dev/null +++ b/libc/crypto/invmixcolumns.c @@ -0,0 +1,51 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/crypto/rijndael.h" +#include "libc/dce.h" + +static noinline aes_block_t xtime(aes_block_t x) { + return ((x ^ (x & 0x80808080)) << 1) ^ (((x & 0x80808080) >> 7) * 0x1b); +} + +static aes_block_t gf256mulx4(aes_block_t x, aes_block_t c) { + return ((((c >> 0 & 0x01010101) * 0xff) & x) ^ + (((c >> 1 & 0x01010101) * 0xff) & xtime(x)) ^ + (((c >> 2 & 0x01010101) * 0xff) & xtime(xtime(x))) ^ + (((c >> 3 & 0x01010101) * 0xff) & xtime(xtime(xtime(x)))) ^ + (((c >> 4 & 0x01010101) * 0xff) & xtime(xtime(xtime(x))))); +} + +/** + * Applies inverse of Rijndael MixColumns() transformation. + * @see FIPS-197 + */ +aes_block_t InvMixColumns(aes_block_t x) { + uint32_t i; + aes_block_t y = {0, 0, 0, 0}; + aes_block_t c = {0x090D0B0E, 0x090D0B0E, 0x090D0B0E, 0x090D0B0E}; + for (i = 0; i < 4; ++i) { + y ^= gf256mulx4((x & 0xff) * 0x01010101, + (((c >> 000) & 0xff) << 000 | ((c >> 010) & 0xff) << 030 | + ((c >> 020) & 0xff) << 020 | ((c >> 030) & 0xff) << 010)); + x = x << 8 | x >> 24; + c = c << 8 | c >> 24; + } + return y; +} diff --git a/libc/crypto/kaessbox.S b/libc/crypto/kaessbox.S new file mode 100644 index 00000000..88bfe63c --- /dev/null +++ b/libc/crypto/kaessbox.S @@ -0,0 +1,58 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + + .rodata + .align 64 # for cacheline yoinking +kAesSbox: + .byte 0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5 + .byte 0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76 + .byte 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0 + .byte 0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0 + .byte 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc + .byte 0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15 + .byte 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a + .byte 0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75 + .byte 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0 + .byte 0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84 + .byte 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b + .byte 0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf + .byte 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85 + .byte 0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8 + .byte 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5 + .byte 0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2 + .byte 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17 + .byte 0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73 + .byte 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88 + .byte 0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb + .byte 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c + .byte 0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79 + .byte 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9 + .byte 0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08 + .byte 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6 + .byte 0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a + .byte 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e + .byte 0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e + .byte 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94 + .byte 0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf + .byte 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68 + .byte 0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16 + .endfn kAesSbox,globl,hidden + .previous diff --git a/libc/crypto/kaessboxinverse.S b/libc/crypto/kaessboxinverse.S new file mode 100644 index 00000000..293e8e93 --- /dev/null +++ b/libc/crypto/kaessboxinverse.S @@ -0,0 +1,58 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + + .rodata + .align 64 # for cacheline yoinking +kAesSboxInverse: + .byte 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38 + .byte 0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb + .byte 0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87 + .byte 0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb + .byte 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d + .byte 0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e + .byte 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2 + .byte 0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25 + .byte 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16 + .byte 0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92 + .byte 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda + .byte 0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84 + .byte 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a + .byte 0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06 + .byte 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02 + .byte 0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b + .byte 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea + .byte 0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73 + .byte 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85 + .byte 0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e + .byte 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89 + .byte 0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b + .byte 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20 + .byte 0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4 + .byte 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31 + .byte 0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f + .byte 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d + .byte 0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef + .byte 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0 + .byte 0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61 + .byte 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26 + .byte 0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d + .endfn kAesSboxInverse,globl,hidden + .previous diff --git a/libc/crypto/rijndael.c b/libc/crypto/rijndael.c new file mode 100644 index 00000000..696ba727 --- /dev/null +++ b/libc/crypto/rijndael.c @@ -0,0 +1,73 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/emmintrin.h" +#include "libc/crypto/rijndael.h" +#include "libc/nexgen32e/x86feature.h" + +forceinline aes_block_t rijndael$westmere(uint32_t n, aes_block_t x, + const struct Rijndael *ctx) { + uint32_t i; + x ^= ctx->rk[0].xmm; + for (i = 1; i < n; ++i) { + asm("aesenc\t%2,%0" : "=x"(x) : "0"(x), "m"(ctx->rk[i].xmm)); + } + asm("aesenclast\t%2,%0" : "=x"(x) : "0"(x), "m"(ctx->rk[i].xmm)); + return x; +} + +static noinline aes_block_t rijndael$pure(uint32_t n, aes_block_t x, + const struct Rijndael *ctx) { + uint32_t i, j; + __v16qu b1, b2; + aes_block_t u1, u2, u3, u4; + x ^= ctx->rk[0].xmm; + for (i = 1; i < n + 1; ++i) { + b2 = b1 = (__v16qu)x; + for (j = 0; j < 16; ++j) { + b2[j % 4 + 13 * j / 4 % 4 * 4] = kAesSbox[b1[j]]; + } + u1 = (aes_block_t)b2; + if (i != n) { + u2 = u1 >> 010 | u1 << 030; + u3 = u1 ^ u2; + u4 = u3 & 0x80808080; + u3 = ((u3 ^ u4) << 1) ^ ((u4 >> 7) * 0x1b); + u1 = u3 ^ u2 ^ (u1 >> 020 | u1 << 020) ^ (u1 >> 030 | u1 << 010); + } + x = ctx->rk[i].xmm ^ u1; + } + return x; +} + +/** + * Encrypts paragraph w/ AES. + * + * @param n is 14 for AES-256, 12 for AES-192, and 10 for AES-128 + * @param x is 128-bit chunk of plaintext to encrypt + * @param ctx was initialized by rijndaelinit() + * @return result of transformation + */ +aes_block_t rijndael(uint32_t n, aes_block_t x, const struct Rijndael *ctx) { + if (X86_HAVE(AES)) { + return rijndael$westmere(n, x, ctx); + } else { + return rijndael$pure(n, x, ctx); + } +} diff --git a/libc/crypto/rijndael.h b/libc/crypto/rijndael.h new file mode 100644 index 00000000..4cb9e149 --- /dev/null +++ b/libc/crypto/rijndael.h @@ -0,0 +1,56 @@ +#ifndef COSMOPOLITAN_LIBC_CRYPTO_RIJNDAEL_H_ +#define COSMOPOLITAN_LIBC_CRYPTO_RIJNDAEL_H_ +#include "libc/str/str.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § cryptography » advanced encryption standard ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─┘ + AES-256 Latency x86 2010+ SSE2 + ─────────────── ───────── ────── + rijndael(14, block, &ctx) 23 ns 218 ns + unrijndael(14, block, &ctx) 23 ns 690 ns + rijndaelinit(&ctx, 14, k1, k2) 136 ns 135 ns + unrijndaelinit(&ctx, 14, k1, k2) 186 ns 639 ns + + Untrustworthy System Viability x86 2010+ SSE2 + ────────────────────────────── ───────── ────── + rijndael(14, block, &ctx) A C + unrijndael(14, block, &ctx) A C + rijndaelinit(&ctx, 14, k1, k2) B B + unrijndaelinit(&ctx, 14, k1, k2) B C + + Comparison Cosmo Rijndael Tiny-AES + ────────────────────────────── ─────── ──────── ──────── + Generalized Math Yes Yes No + Footprint 1,782 b 9,258 b 903 b + Performance (New Hardware) ~20 ns ~40 ns ~400 ns + Performance (Old Hardware) ~400 ns ~40 ns ~400 ns */ + +typedef uint32_t aes_block_t _Vector_size(16) aligned(16); + +struct Rijndael { + union { + aes_block_t xmm; + uint32_t u32[4]; + uint8_t u8[16]; + } rk[15]; +}; + +void rijndaelinit(struct Rijndael *, uint32_t, aes_block_t, aes_block_t); +aes_block_t rijndael(uint32_t, aes_block_t, const struct Rijndael *); +void unrijndaelinit(struct Rijndael *, uint32_t, aes_block_t, aes_block_t); +aes_block_t unrijndael(uint32_t, aes_block_t, const struct Rijndael *); + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § cryptography » implementation details ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +aligned(64) extern const uint8_t kAesSbox[256]; +aligned(64) extern const uint8_t kAesSboxInverse[256]; + +aes_block_t InvMixColumns(aes_block_t x) hidden; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CRYPTO_RIJNDAEL_H_ */ diff --git a/libc/crypto/rijndaelinit.c b/libc/crypto/rijndaelinit.c new file mode 100644 index 00000000..cd68b2ef --- /dev/null +++ b/libc/crypto/rijndaelinit.c @@ -0,0 +1,67 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/bits/xmmintrin.h" +#include "libc/crypto/rijndael.h" +#include "libc/dce.h" +#include "libc/str/internal.h" + +static const uint8_t Rcon[11] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, + 0x20, 0x40, 0x80, 0x1b, 0x36}; + +forceinline uint32_t SubRot(uint32_t t) { + uint32_t j; + for (j = 0; j < 4; j++) { + t = (t & -256) | kAesSbox[t & 255]; + t = ROR(t, 8); + } + return t; +} + +/** + * Computes key schedule for rijndael(). + * + * @param ctx receives round keys + * @param n is 14 for AES-256, 12 for AES-192, and 10 for AES-128 + * @param k1/k2 holds the master key + */ +void rijndaelinit(struct Rijndael *ctx, uint32_t n, aes_block_t k1, + aes_block_t k2) { +#define Nk (n - 6) +#define W(i) (ctx->rk[(i) / 4].u32[(i) % 4]) +#define K(i) ((i) < 4 ? k1[i] : k2[(i)-4]) + uint32_t i, t; + ctx->rk[0].xmm = k1; + ctx->rk[1].xmm = k2; + for (i = Nk; i < 4 * (n + 1); ++i) { + t = W(i - 1); + if (i % Nk == 0) { + t = ROR(t, 8); + t = SubRot(t); + t ^= Rcon[i / Nk]; + } else if (Nk > 6 && i % Nk == 4) { + t = SubRot(t); + } + W(i) = W(i - Nk) ^ t; + } + XMM_DESTROY(k1); + XMM_DESTROY(k2); +} diff --git a/libc/crypto/unrijndael.c b/libc/crypto/unrijndael.c new file mode 100644 index 00000000..aadba9d0 --- /dev/null +++ b/libc/crypto/unrijndael.c @@ -0,0 +1,65 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/emmintrin.h" +#include "libc/crypto/rijndael.h" +#include "libc/nexgen32e/x86feature.h" + +forceinline aes_block_t unrijndael$westmere(uint32_t n, aes_block_t x, + const struct Rijndael *ctx) { + x ^= ctx->rk[n--].xmm; + do { + asm("aesdec\t%2,%0" : "=x"(x) : "0"(x), "m"(ctx->rk[n].xmm)); + } while (--n); + asm("aesdeclast\t%2,%0" : "=x"(x) : "0"(x), "m"(ctx->rk[n].xmm)); + return x; +} + +static noinline aes_block_t unrijndael$pure(uint32_t n, aes_block_t x, + const struct Rijndael *ctx) { + uint32_t j; + __v16qu b1, b2; + x ^= ctx->rk[n--].xmm; + do { + b2 = b1 = (__v16qu)x; + for (j = 0; j < 16; ++j) { + b2[j] = kAesSboxInverse[b1[j % 4 + j * 13 / 4 % 4 * 4]]; + } + x = (aes_block_t)b2; + if (n) x = InvMixColumns(x); + x ^= ctx->rk[n].xmm; + } while (n--); + return x; +} + +/** + * Decrypts paragraph w/ AES. + * + * @param n is 14 for AES-256, 12 for AES-192, and 10 for AES-128 + * @param x is 128-bit chunk of ciphertext to decrypt + * @param ctx was initialized by unrijndaelinit() + * @return result of transformation + */ +aes_block_t unrijndael(uint32_t n, aes_block_t x, const struct Rijndael *ctx) { + if (X86_HAVE(AES)) { + return unrijndael$westmere(n, x, ctx); + } else { + return unrijndael$pure(n, x, ctx); + } +} diff --git a/libc/crypto/unrijndaelinit.c b/libc/crypto/unrijndaelinit.c new file mode 100644 index 00000000..08c55038 --- /dev/null +++ b/libc/crypto/unrijndaelinit.c @@ -0,0 +1,70 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/bits/xmmintrin.h" +#include "libc/crypto/rijndael.h" +#include "libc/nexgen32e/x86feature.h" + +static void unrijndaelinit$westmere(struct Rijndael *ctx, uint32_t n, + aes_block_t k1, aes_block_t k2) { + uint32_t i; + aes_block_t x; + assert(n > 1); + rijndaelinit(ctx, n, k1, k2); + i = 1; + do { + x = ctx->rk[i].xmm; + asm("aesimc\t%1,%0" : "=x"(x) : "0"(x)); + ctx->rk[i].xmm = x; + } while (i++ < n); + XMM_DESTROY(x); +} + +static relegated noinline void unrijndaelinit$pure(struct Rijndael *ctx, + uint32_t n, aes_block_t k1, + aes_block_t k2) { + uint32_t i; + aes_block_t x; + assert(n > 1); + rijndaelinit(ctx, n, k1, k2); + i = 1; + do { + x = ctx->rk[i].xmm; + x = InvMixColumns(x); + ctx->rk[i].xmm = x; + } while (i++ < n); + XMM_DESTROY(x); +} + +/** + * Computes key schedule for unrijndael(). + * + * @param rk receives round keys + * @param n is 14 for AES-256, 12 for AES-192, and 10 for AES-128 + * @param k1/k2 holds the master key + */ +void unrijndaelinit(struct Rijndael *ctx, uint32_t n, aes_block_t k1, + aes_block_t k2) { + if (X86_HAVE(AES)) { + return unrijndaelinit$westmere(ctx, n, k1, k2); + } else { + return unrijndaelinit$pure(ctx, n, k1, k2); + } +} diff --git a/libc/dce.h b/libc/dce.h new file mode 100644 index 00000000..7889ccab --- /dev/null +++ b/libc/dce.h @@ -0,0 +1,123 @@ +#ifndef COSMOPOLITAN_LIBC_DCE_H_ +#define COSMOPOLITAN_LIBC_DCE_H_ +#include "libc/nexgen32e/kcpuids.h" +/*─────────────────────────────────────────────────────────────────────────────╗ +│ cosmopolitan § autotune » dead code elimination │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +/** + * Supported Platforms Tuning Knob (Runtime & Compile-Time) + * + * Cosmopolitan's design allows us to support eight platforms. We enable + * them all by default, since we're able to do eight so efficiently. We + * can't do more, due to the way the 80x86 instruction set is encoded. + * + * The user may optionally tune this bitmask, which effectively asks the + * compiler to leave out system call polyfills for a platform, which may + * offer marginal improvements in terms of code size and performance, at + * the cost of portability. + */ +#ifndef SUPPORT_VECTOR +#define SUPPORT_VECTOR 0b11111111 +#endif +#define LINUX 1 +#define METAL 2 +#define WINDOWS 4 +#define XNU 8 +#define OPENBSD 16 +#define FREEBSD 32 +/* #define YOUR_CLOUD_PLATFORM_HERE 64 /\* jtunney@gmail.com *\/ */ +/* #define YOUR_CLOUD_PLATFORM_HERE 128 /\* jtunney@gmail.com *\/ */ + +#ifdef NDEBUG +#define NoDebug() 1 +#else +#define NoDebug() 0 +#endif + +#ifdef MODE_DBG +#define IsModeDbg() 1 +#else +#define IsModeDbg() 0 +#endif + +#ifdef __MFENTRY__ +#define HaveFentry() 1 +#else +#define HaveFentry() 0 +#endif + +#ifdef TRUSTWORTHY +#define IsTrustworthy() 1 +#else +#define IsTrustworthy() 0 +#endif + +#ifdef SECURITY_BLANKETS +#define UseSecurityBlankets() 1 +#else +#define UseSecurityBlankets() 0 +#endif + +#ifdef __MGENERAL_REGS_ONLY__ +#define UseGeneralRegsOnly() 1 +#else +#define UseGeneralRegsOnly() 0 +#endif + +#ifdef TINY +#define IsTiny() 1 +#else +#define IsTiny() 0 +#endif + +#ifdef __OPTIMIZE__ +#define IsOptimized() 1 +#else +#define IsOptimized() 0 +#endif + +#if defined(__PIE__) || defined(__PIC__) +#define IsPositionIndependent() 1 +#else +#define IsPositionIndependent() 0 +#endif + +#define SupportsLinux() ((SUPPORT_VECTOR & LINUX) == LINUX) +#define SupportsMetal() ((SUPPORT_VECTOR & METAL) == METAL) +#define SupportsWindows() ((SUPPORT_VECTOR & WINDOWS) == WINDOWS) +#define SupportsXnu() ((SUPPORT_VECTOR & XNU) == XNU) +#define SupportsFreebsd() ((SUPPORT_VECTOR & FREEBSD) == FREEBSD) +#define SupportsOpenbsd() ((SUPPORT_VECTOR & OPENBSD) == OPENBSD) +#define SupportsSystemv() \ + ((SUPPORT_VECTOR & (LINUX | METAL | XNU | OPENBSD | FREEBSD)) != 0) + +#ifndef __ASSEMBLER__ +#define IsLinux() ((hostos & LINUX) == LINUX) +#define IsMetal() ((hostos & METAL) == METAL) +#define IsWindows() ((hostos & WINDOWS) == WINDOWS) +#define IsBsd() ((hostos & (XNU | FREEBSD | OPENBSD)) != 0) +#define IsXnu() ((hostos & XNU) == XNU) +#define IsFreebsd() ((hostos & FREEBSD) == FREEBSD) +#define IsOpenbsd() ((hostos & OPENBSD) == OPENBSD) +#else +/* clang-format off */ +#define IsLinux() $LINUX,hostos(%rip) +#define IsMetal() $METAL,hostos(%rip) +#define IsWindows() $WINDOWS,hostos(%rip) +#define IsBsd() $XNU|FREEBSD|OPENBSD,hostos(%rip) +#define IsXnu() $XNU,hostos(%rip) +#define IsFreebsd() $FREEBSD,hostos(%rip) +#define IsOpenbsd() $OPENBSD,hostos(%rip) +/* clang-format on */ +#endif + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define hostos (__hostos & SUPPORT_VECTOR) +extern const int __hostos asm("hostos"); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_DCE_H_ */ diff --git a/libc/disclaimer.inc b/libc/disclaimer.inc new file mode 100644 index 00000000..631cf0fd --- /dev/null +++ b/libc/disclaimer.inc @@ -0,0 +1,8 @@ +.ident "\n +THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE." diff --git a/libc/dns/consts.h b/libc/dns/consts.h new file mode 100644 index 00000000..d49f4c0d --- /dev/null +++ b/libc/dns/consts.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_DNS_CONSTS_H_ +#define COSMOPOLITAN_LIBC_DNS_CONSTS_H_ +#include "libc/sock/sock.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define DNS_TYPE_A 1 +#define DNS_CLASS_IN 1 + +#define kMinSockaddr4Size \ + (offsetof(struct sockaddr_in, sin_addr) + sizeof(struct in_addr)) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_DNS_CONSTS_H_ */ diff --git a/libc/dns/dns.h b/libc/dns/dns.h new file mode 100644 index 00000000..ba26503a --- /dev/null +++ b/libc/dns/dns.h @@ -0,0 +1,40 @@ +#ifndef COSMOPOLITAN_LIBC_DNS_DNS_H_ +#define COSMOPOLITAN_LIBC_DNS_DNS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define DNS_PORT 53 +#define DNS_NAME_MAX 253 +#define DNS_LABEL_MAX 63 + +struct sockaddr; +struct sockaddr_in; +struct ResolvConf; + +struct addrinfo { + int32_t ai_flags; /* AI_XXX */ + int32_t ai_family; /* AF_INET */ + int32_t ai_socktype; /* SOCK_XXX */ + int32_t ai_protocol; /* IPPROTO_XXX */ + uint32_t ai_addrlen; + union { + struct sockaddr *ai_addr; + struct sockaddr_in *ai_addr4; + }; + char *ai_canonname /*[DNS_NAME_MAX + 1]*/; + struct addrinfo *ai_next; +}; + +int getaddrinfo(const char *, const char *, const struct addrinfo *, + struct addrinfo **) paramsnonnull((4)); +int freeaddrinfo(struct addrinfo *); +const char *eai2str(int); +int dnsnamecmp(const char *, const char *) paramsnonnull(); +int pascalifydnsname(uint8_t *, size_t, const char *) paramsnonnull(); +int resolvedns(const struct ResolvConf *, int, const char *, struct sockaddr *, + uint32_t) paramsnonnull(); +struct addrinfo *newaddrinfo(uint16_t); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_DNS_DNS_H_ */ diff --git a/libc/dns/dns.mk b/libc/dns/dns.mk new file mode 100644 index 00000000..46dd76c1 --- /dev/null +++ b/libc/dns/dns.mk @@ -0,0 +1,61 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += LIBC_DNS + +LIBC_DNS_ARTIFACTS += LIBC_DNS_A +LIBC_DNS = $(LIBC_DNS_A_DEPS) $(LIBC_DNS_A) +LIBC_DNS_A = o/$(MODE)/libc/dns/dns.a +LIBC_DNS_A_FILES := $(wildcard libc/dns/*) +LIBC_DNS_A_HDRS = $(filter %.h,$(LIBC_DNS_A_FILES)) +LIBC_DNS_A_SRCS_C = $(filter %.c,$(LIBC_DNS_A_FILES)) +LIBC_DNS_A_SRCS_S = $(filter %.S,$(LIBC_DNS_A_FILES)) + +LIBC_DNS_A_SRCS = \ + $(LIBC_DNS_A_SRCS_S) \ + $(LIBC_DNS_A_SRCS_C) + +LIBC_DNS_A_OBJS = \ + $(LIBC_DNS_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_DNS_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_DNS_A_SRCS_C:%.c=o/$(MODE)/%.o) + +LIBC_DNS_A_CHECKS = \ + $(LIBC_DNS_A).pkg \ + $(LIBC_DNS_A_HDRS:%=o/$(MODE)/%.ok) + +LIBC_DNS_A_DIRECTDEPS = \ + LIBC_ALG \ + LIBC_CALLS \ + LIBC_FMT \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RAND \ + LIBC_RUNTIME \ + LIBC_SOCK \ + LIBC_STDIO \ + LIBC_STUBS \ + LIBC_STR \ + LIBC_SYSV \ + LIBC_NT_KERNELBASE + +LIBC_DNS_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_DNS_A_DIRECTDEPS),$($(x)))) + +$(LIBC_DNS_A): libc/dns/ \ + $(LIBC_DNS_A).pkg \ + $(LIBC_DNS_A_OBJS) + +$(LIBC_DNS_A).pkg: \ + $(LIBC_DNS_A_OBJS) \ + $(foreach x,$(LIBC_DNS_A_DIRECTDEPS),$($(x)_A).pkg) + +LIBC_DNS_LIBS = $(foreach x,$(LIBC_DNS_ARTIFACTS),$($(x))) +LIBC_DNS_SRCS = $(foreach x,$(LIBC_DNS_ARTIFACTS),$($(x)_SRCS)) +LIBC_DNS_HDRS = $(foreach x,$(LIBC_DNS_ARTIFACTS),$($(x)_HDRS)) +LIBC_DNS_CHECKS = $(foreach x,$(LIBC_DNS_ARTIFACTS),$($(x)_CHECKS)) +LIBC_DNS_OBJS = $(foreach x,$(LIBC_DNS_ARTIFACTS),$($(x)_OBJS)) +$(LIBC_DNS_OBJS): $(BUILD_FILES) libc/dns/dns.mk + +.PHONY: o/$(MODE)/libc/dns +o/$(MODE)/libc/dns: $(LIBC_DNS_CHECKS) diff --git a/libc/dns/dns.png b/libc/dns/dns.png new file mode 100644 index 00000000..193aa73d Binary files /dev/null and b/libc/dns/dns.png differ diff --git a/libc/dns/dnsheader.c b/libc/dns/dnsheader.c new file mode 100644 index 00000000..10cdc740 --- /dev/null +++ b/libc/dns/dnsheader.c @@ -0,0 +1,64 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/dns/dnsheader.h" +#include "libc/sysv/errfuns.h" + +/** + * Serializes DNS message header to wire. + * + * @return number of bytes written (always 12) or -1 w/ errno + * @see pascalifydnsname() + */ +int serializednsheader(uint8_t *buf, size_t size, + const struct DnsHeader header) { + if (size < 12) return enospc(); + buf[0x0] = header.id >> 010u; + buf[0x1] = header.id >> 000u; + buf[0x2] = header.bf1; + buf[0x3] = header.bf2; + buf[0x4] = header.qdcount >> 010u; + buf[0x5] = header.qdcount >> 000u; + buf[0x6] = header.ancount >> 010u; + buf[0x7] = header.ancount >> 000u; + buf[0x8] = header.nscount >> 010u; + buf[0x9] = header.nscount >> 000u; + buf[0xa] = header.arcount >> 010u; + buf[0xb] = header.arcount >> 000u; + return 12; +} + +/** + * Serializes DNS message header to wire. + * + * @return number of bytes read (always 12) or -1 w/ errno + */ +int deserializednsheader(struct DnsHeader *header, const uint8_t *buf, + size_t size) { + if (size < 12) return ebadmsg(); + header->id = read16be(buf + 0); + header->bf1 = buf[2]; + header->bf2 = buf[3]; + header->qdcount = read16be(buf + 4); + header->ancount = read16be(buf + 6); + header->nscount = read16be(buf + 8); + header->arcount = read16be(buf + 10); + return 12; +} diff --git a/libc/dns/dnsheader.h b/libc/dns/dnsheader.h new file mode 100644 index 00000000..3674b675 --- /dev/null +++ b/libc/dns/dnsheader.h @@ -0,0 +1,23 @@ +#ifndef COSMOPOLITAN_LIBC_DNS_DNSHEADER_H_ +#define COSMOPOLITAN_LIBC_DNS_DNSHEADER_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct DnsHeader { + uint16_t id; /* transaction id */ + uint8_t bf1; /* bit field 1 */ + uint8_t bf2; /* bit field 2 */ + uint16_t qdcount; /* question count */ + uint16_t ancount; /* answer count */ + uint16_t nscount; /* nameserver count */ + uint16_t arcount; /* additional record count */ +}; + +int serializednsheader(uint8_t *buf, size_t size, + const struct DnsHeader header); +int deserializednsheader(struct DnsHeader *header, const uint8_t *buf, + size_t size); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_DNS_DNSHEADER_H_ */ diff --git a/libc/dns/dnsnamecmp.c b/libc/dns/dnsnamecmp.c new file mode 100644 index 00000000..b044c543 --- /dev/null +++ b/libc/dns/dnsnamecmp.c @@ -0,0 +1,76 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/dns/dns.h" +#include "libc/str/str.h" + +forceinline void FindDnsLabel(const char *A, size_t *i, size_t *n) { + while (*i) { + if (A[*i - 1] == '.') { + if (*i == *n) { + --(*n); + } else { + break; + } + } + --(*i); + } +} + +/** + * Compares DNS hostnames in reverse lexicographical asciibetical order. + * @return <0, 0, or >0 + * @see test/libc/dns/dnsnamecmp_test.c (the code that matters) + */ +int dnsnamecmp(const char *A, const char *B) { + if (A == B) return 0; + size_t n = strlen(A); + size_t m = strlen(B); + if (!n || !m || ((A[n - 1] == '.') ^ (B[m - 1] == '.'))) { + if (n && m && A[n - 1] == '.' && strchr(B, '.')) { + --m; + } else if (n && m && B[m - 1] == '.' && strchr(A, '.')) { + --n; + } else { + return A[n ? n - 1 : 0] - B[m ? m - 1 : 0]; + } + } + size_t i = n; + size_t j = m; + bool first = true; + for (;;) { + FindDnsLabel(A, &i, &n); + FindDnsLabel(B, &j, &m); + if (first) { + first = false; + if (!i && j) return 1; + if (!j && i) return -1; + } + int res; + if ((res = strncasecmp(&A[i], &B[j], min(n - i + 1, m - j + 1)))) { + return res; + } + if (!i || !j) { + return i - j; + } + n = i; + m = j; + } +} diff --git a/libc/dns/dnsquestion.h b/libc/dns/dnsquestion.h new file mode 100644 index 00000000..d6dd7e4f --- /dev/null +++ b/libc/dns/dnsquestion.h @@ -0,0 +1,32 @@ +#ifndef COSMOPOLITAN_LIBC_DNS_DNSQUESTION_H_ +#define COSMOPOLITAN_LIBC_DNS_DNSQUESTION_H_ +#include "libc/dns/dns.h" +#include "libc/sysv/errfuns.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct DnsQuestion { + const char *qname; + uint16_t qtype; + uint16_t qclass; +}; + +/** + * Serializes DNS question record to wire. + * + * @return number of bytes written + * @see pascalifydnsname() + */ +forceinline int serializednsquestion(uint8_t *buf, size_t size, + struct DnsQuestion dq) { + int wrote; + if ((wrote = pascalifydnsname(buf, size, dq.qname)) == -1) return -1; + if (wrote + 1 + 4 > size) return enospc(); + buf[wrote + 1] = dq.qtype >> 010, buf[wrote + 2] = dq.qtype >> 000; + buf[wrote + 3] = dq.qclass >> 010, buf[wrote + 4] = dq.qclass >> 000; + return wrote + 5; +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_DNS_DNSQUESTION_H_ */ diff --git a/libc/dns/eai2str.c b/libc/dns/eai2str.c new file mode 100644 index 00000000..93e06a68 --- /dev/null +++ b/libc/dns/eai2str.c @@ -0,0 +1,47 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dns/dns.h" +#include "libc/sysv/consts/eai.h" + +/** + * Turns getaddrinfo() return code into string. + */ +const char *eai2str(int code) { + if (code == EAI_ADDRFAMILY) return "ADDRFAMILY"; + if (code == EAI_AGAIN) return "AGAIN"; + if (code == EAI_ALLDONE) return "ALLDONE"; + if (code == EAI_BADFLAGS) return "BADFLAGS"; + if (code == EAI_CANCELED) return "CANCELED"; + if (code == EAI_FAIL) return "FAIL"; + if (code == EAI_FAMILY) return "FAMILY"; + if (code == EAI_IDN_ENCODE) return "ENCODE"; + if (code == EAI_INPROGRESS) return "INPROGRESS"; + if (code == EAI_INTR) return "INTR"; + if (code == EAI_MEMORY) return "MEMORY"; + if (code == EAI_NODATA) return "NODATA"; + if (code == EAI_NONAME) return "NONAME"; + if (code == EAI_NOTCANCELED) return "NOTCANCELED"; + if (code == EAI_OVERFLOW) return "OVERFLOW"; + if (code == EAI_SERVICE) return "SERVICE"; + if (code == EAI_SOCKTYPE) return "SOCKTYPE"; + if (code == EAI_SUCCESS) return "SUCCESS"; + if (code == EAI_SYSTEM) return "SYSTEM"; + return "???"; +} diff --git a/libc/dns/freeaddrinfo.c b/libc/dns/freeaddrinfo.c new file mode 100644 index 00000000..79772d96 --- /dev/null +++ b/libc/dns/freeaddrinfo.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dns/dns.h" +#include "libc/mem/mem.h" + +/** + * Frees addresses returned by getaddrinfo(). + */ +int freeaddrinfo(struct addrinfo *addrs) { + struct addrinfo *next; + while (addrs) { + /* we assume ai_addr and ai_canonname are shoehorned */ + next = addrs->ai_next; + free(addrs); + addrs = next; + } + return 0; +} diff --git a/libc/dns/freehoststxt.c b/libc/dns/freehoststxt.c new file mode 100644 index 00000000..52561978 --- /dev/null +++ b/libc/dns/freehoststxt.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dns/hoststxt.h" +#include "libc/runtime/runtime.h" + +/** + * Frees HOSTS.TXT data structure populated by parsehoststxt(). + */ +void freehoststxt(struct HostsTxt **ht) { + if (*ht) { + free_s(&(*ht)->entries.p); + free_s(&(*ht)->strings.p); + free_s(ht); + } +} diff --git a/libc/dns/freeresolvconf.c b/libc/dns/freeresolvconf.c new file mode 100644 index 00000000..9654987f --- /dev/null +++ b/libc/dns/freeresolvconf.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dns/resolvconf.h" +#include "libc/runtime/runtime.h" + +/** + * Frees resolv.conf data structure populated by parseresolvconf(). + */ +void freeresolvconf(struct ResolvConf **rvp) { + if (*rvp) { + free_s(&(*rvp)->nameservers.p); + free_s(rvp); + } +} diff --git a/libc/dns/getaddrinfo.c b/libc/dns/getaddrinfo.c new file mode 100644 index 00000000..77ca0cbe --- /dev/null +++ b/libc/dns/getaddrinfo.c @@ -0,0 +1,98 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/conv/conv.h" +#include "libc/dns/dns.h" +#include "libc/dns/hoststxt.h" +#include "libc/dns/resolvconf.h" +#include "libc/mem/mem.h" +#include "libc/sock/sock.h" +#include "libc/str/str.h" +#include "libc/calls/calls.h" +#include "libc/sysv/errfuns.h" +#include "libc/sysv/consts/af.h" +#include "libc/sysv/consts/ai.h" +#include "libc/sysv/consts/eai.h" +#include "libc/sysv/consts/inaddr.h" + +/** + * Resolves address for internet name. + * + * @param node is either an ip string or a utf-8 hostname + * @param service is the port number as a string + * @param hints may be passed to specialize behavior (optional) + * @param res receives a pointer that must be freed with freeaddrinfo(), + * and won't be modified if -1 is returned + * @return 0 on success or EAI_xxx value + */ +int getaddrinfo(const char *name, const char *service, + const struct addrinfo *hints, struct addrinfo **res) { + int port = 0; + struct addrinfo *ai; + if ((!name && !service) || (service && (port = parseport(service)) == -1)) { + return EAI_NONAME; + } + if (!name && (hints->ai_flags & AI_CANONNAME) == AI_CANONNAME) { + return EAI_BADFLAGS; + } + if (!(ai = newaddrinfo(port))) { + return EAI_MEMORY; + } + if (service) { + ai->ai_addr4->sin_port = htons(port); + } + if (hints) { + ai->ai_socktype = hints->ai_socktype; + ai->ai_protocol = hints->ai_protocol; + } + if (!name) { + ai->ai_addr4->sin_addr.s_addr = + (hints && (hints->ai_flags & AI_PASSIVE) == AI_PASSIVE) + ? INADDR_ANY + : INADDR_LOOPBACK; + return 0; + } + const char *canon; + if (inet_pton(AF_INET, name, &ai->ai_addr4->sin_addr.s_addr) == 1) { + *res = ai; + return 0; + } else if (hints && (hints->ai_flags & AI_NUMERICHOST) == AI_NUMERICHOST) { + freeaddrinfo(ai); + return EAI_NONAME; + } else if (resolvehoststxt(gethoststxt(), AF_INET, name, ai->ai_addr, + sizeof(ai->ai_addr4), &canon) > 0) { + memcpy(ai->ai_canonname, canon, min(strlen(canon), DNS_NAME_MAX) + 1); + *res = ai; + return 0; + } else { + int rc = resolvedns(getresolvconf(), AF_INET, name, ai->ai_addr, + sizeof(ai->ai_addr4)); + if (rc > 0) { + *res = ai; + return 0; + } + freeaddrinfo(ai); + if (rc == 0) { + return EAI_NONAME; + } else { + return EAI_SYSTEM; + } + } +} diff --git a/libc/dns/gethoststxt.c b/libc/dns/gethoststxt.c new file mode 100644 index 00000000..c4e2911c --- /dev/null +++ b/libc/dns/gethoststxt.c @@ -0,0 +1,79 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/pushpop.h" +#include "libc/bits/safemacros.h" +#include "libc/dce.h" +#include "libc/dns/hoststxt.h" +#include "libc/fmt/fmt.h" +#include "libc/macros.h" +#include "libc/nt/systeminfo.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" + +static struct HostsTxt *g_hoststxt; +static struct HostsTxtInitialStaticMemory { + struct HostsTxt ht; + struct HostsTxtEntry entries[8]; + char strings[64]; +} g_hoststxt_init; + +static textwindows noinline char *getnthoststxtpath(char *pathbuf, + uint32_t size) { + const char *const kWinHostsPath = "\\drivers\\etc\\hosts"; + uint32_t len = GetSystemDirectoryA(&pathbuf[0], size); + if (len && len + strlen(kWinHostsPath) + 1 < size) { + if (pathbuf[len] == '\\') pathbuf[len--] = '\0'; + memcpy(&pathbuf[len], kWinHostsPath, strlen(kWinHostsPath) + 1); + return &pathbuf[0]; + } else { + return NULL; + } +} + +/** + * Returns parsed sorted singleton hardcoded hostname→ip4 map. + * + * @note yoinking realloc() ensures there's no size limits + */ +const struct HostsTxt *gethoststxt(void) { + struct HostsTxtInitialStaticMemory *init = &g_hoststxt_init; + if (!g_hoststxt) { + g_hoststxt = &init->ht; + init->ht.entries.n = pushpop(ARRAYLEN(init->entries)); + init->ht.entries.p = init->entries; + init->ht.strings.n = pushpop(ARRAYLEN(init->strings)); + init->ht.strings.p = init->strings; + __cxa_atexit(freehoststxt, &g_hoststxt, NULL); + char pathbuf[PATH_MAX]; + const char *path = "/etc/hosts"; + if (IsWindows()) { + path = firstnonnull(getnthoststxtpath(pathbuf, ARRAYLEN(pathbuf)), path); + } + FILE *f; + if (!(f = fopen(path, "r")) || parsehoststxt(g_hoststxt, f) == -1) { + if (!IsTiny()) fprintf(stderr, "%s: %s: %m\n", "warning", path); + } + fclose(f); + sorthoststxt(g_hoststxt); + } + return g_hoststxt; +} diff --git a/libc/dns/getntnameservers.c b/libc/dns/getntnameservers.c new file mode 100644 index 00000000..8c1f4116 --- /dev/null +++ b/libc/dns/getntnameservers.c @@ -0,0 +1,87 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/arraylist.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dns/dns.h" +#include "libc/dns/resolvconf.h" +#include "libc/nt/registry.h" +#include "libc/nt/runtime.h" +#include "libc/runtime/runtime.h" +#include "libc/sock/sock.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/af.h" + +/** + * Extracts DNS nameserver IPs from Windows Registry. + * + * @param resolv points to a ResolvConf object, which should be zero + * initialized by the caller; or if it already contains items, + * this function will append + * @return number of nameservers appended, or -1 w/ errno + */ +textwindows int getntnameservers(struct ResolvConf *resolv) { + int rc; + int64_t hkInterfaces = kNtInvalidHandleValue; + uint32_t keycount = 0; + if (!RegOpenKeyEx( + kNtHkeyLocalMachine, + u"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces", + 0, kNtKeyRead, &hkInterfaces) && + !RegQueryInfoKey(hkInterfaces, NULL, NULL, NULL, &keycount, NULL, NULL, + NULL, NULL, NULL, NULL, NULL)) { + struct sockaddr_in nameserver; + nameserver.sin_family = AF_INET; + nameserver.sin_port = htons(DNS_PORT); + rc = 0; + for (uint32_t i = 0; i < keycount; ++i) { + char16_t value[128], ifaceuuid[64]; + uint32_t valuebytes, ifaceuuidlen = sizeof(ifaceuuid); + if (!RegEnumKeyEx(hkInterfaces, i, ifaceuuid, &ifaceuuidlen, NULL, NULL, + NULL, NULL) && + ((!RegGetValue(hkInterfaces, ifaceuuid, u"DhcpIpAddress", + kNtRrfRtRegSz | kNtRrfRtRegMultiSz, NULL, value, + ((valuebytes = sizeof(value)), &valuebytes)) && + valuebytes > 2 * sizeof(char16_t)) || + (!RegGetValue(hkInterfaces, ifaceuuid, u"IpAddress", + kNtRrfRtRegSz | kNtRrfRtRegMultiSz, NULL, value, + ((valuebytes = sizeof(value)), &valuebytes)) && + valuebytes > 2 * sizeof(char16_t))) && + ((!RegGetValue(hkInterfaces, ifaceuuid, u"DhcpNameServer", + kNtRrfRtRegSz | kNtRrfRtRegMultiSz, NULL, value, + ((valuebytes = sizeof(value)), &valuebytes)) && + valuebytes > 2 * sizeof(char16_t)) || + (!RegGetValue(hkInterfaces, ifaceuuid, u"NameServer", + kNtRrfRtRegSz | kNtRrfRtRegMultiSz, NULL, value, + ((valuebytes = sizeof(value)), &valuebytes)) && + valuebytes > 2 * sizeof(char16_t)))) { + char value8[128]; + tprecode16to8(value8, sizeof(value8), value); + if (inet_pton(AF_INET, value8, &nameserver.sin_addr.s_addr) == 1) { + if (append(&resolv->nameservers, &nameserver) != -1) ++rc; + } + } + } + } else { + rc = winerr(); + } + RegCloseKey(hkInterfaces); + return rc; +} diff --git a/libc/dns/getresolvconf.c b/libc/dns/getresolvconf.c new file mode 100644 index 00000000..38b8b988 --- /dev/null +++ b/libc/dns/getresolvconf.c @@ -0,0 +1,62 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/pushpop.h" +#include "libc/dce.h" +#include "libc/dns/resolvconf.h" +#include "libc/fmt/fmt.h" +#include "libc/macros.h" +#include "libc/runtime/runtime.h" +#include "libc/sock/sock.h" +#include "libc/stdio/stdio.h" + +static struct ResolvConf *g_resolvconf; +static struct ResolvConfInitialStaticMemory { + struct ResolvConf rv; + struct sockaddr_in nameservers[3]; +} g_resolvconf_init; + +/** + * Returns singleton with DNS server address. + */ +const struct ResolvConf *getresolvconf(void) { + struct ResolvConfInitialStaticMemory *init = &g_resolvconf_init; + if (!g_resolvconf) { + g_resolvconf = &init->rv; + pushmov(&init->rv.nameservers.n, ARRAYLEN(init->nameservers)); + init->rv.nameservers.p = init->nameservers; + __cxa_atexit(freeresolvconf, &g_resolvconf, NULL); + int rc; + if (!IsWindows()) { + FILE *f; + if ((f = fopen("/etc/resolv.conf", "r"))) { + rc = parseresolvconf(g_resolvconf, f); + } else { + rc = -1; + } + fclose(f); + } else { + rc = getntnameservers(g_resolvconf); + } + if (rc == -1 && !IsTiny()) { + fprintf(stderr, "%s: %m\n", "nameserver discovery failed"); + } + } + return g_resolvconf; +} diff --git a/libc/dns/hoststxt.h b/libc/dns/hoststxt.h new file mode 100644 index 00000000..3972684a --- /dev/null +++ b/libc/dns/hoststxt.h @@ -0,0 +1,42 @@ +#ifndef COSMOPOLITAN_LIBC_DNS_HOSTSTXT_H_ +#define COSMOPOLITAN_LIBC_DNS_HOSTSTXT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct FILE; +struct sockaddr; + +struct HostsTxtEntry { + unsigned char ip[4]; /* inet_ntop(AF_INET, he->ip, buf, size) */ + uint32_t name; /* &ht->strings.p[he->name] */ + uint32_t canon; /* &ht->strings.p[he->canon] */ +}; + +struct HostsTxtEntries { + size_t i; + size_t n; + struct HostsTxtEntry *p; +}; + +struct HostsTxtStrings { + size_t i; + size_t n; + char *p; +}; + +struct HostsTxt { + struct HostsTxtEntries entries; + struct HostsTxtStrings strings; +}; + +const struct HostsTxt *gethoststxt(void) returnsnonnull; +void freehoststxt(struct HostsTxt **) paramsnonnull(); +int parsehoststxt(struct HostsTxt *, struct FILE *) paramsnonnull(); +void sorthoststxt(struct HostsTxt *) paramsnonnull(); +int resolvehoststxt(const struct HostsTxt *, int, const char *, + struct sockaddr *, uint32_t, const char **) + paramsnonnull((1, 3)); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_DNS_HOSTSTXT_H_ */ diff --git a/libc/dns/newaddrinfo.c b/libc/dns/newaddrinfo.c new file mode 100644 index 00000000..9cf6c48a --- /dev/null +++ b/libc/dns/newaddrinfo.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dns/dns.h" +#include "libc/macros.h" +#include "libc/mem/mem.h" +#include "libc/sock/sock.h" +#include "libc/sysv/consts/af.h" + +struct addrinfo *newaddrinfo(uint16_t port) { + void *mem; + struct addrinfo *ai = NULL; + /* shoehorning is ok since this'll never be realloc()'d */ + uint32_t size = ROUNDUP(sizeof(struct addrinfo), sizeof(void *)); + uint32_t addrlen = sizeof(struct sockaddr_in); + if ((ai = mem = calloc(1, size + addrlen + DNS_NAME_MAX + 1))) { + ai->ai_family = AF_INET; + ai->ai_addrlen = addrlen; + ai->ai_addr4 = (struct sockaddr_in *)((char *)mem + size); + ai->ai_addr4->sin_family = AF_INET; + ai->ai_addr4->sin_port = htons(port); + ai->ai_canonname = (char *)mem + size + addrlen; + } + return ai; +} diff --git a/libc/dns/parsehoststxt.c b/libc/dns/parsehoststxt.c new file mode 100644 index 00000000..40df14de --- /dev/null +++ b/libc/dns/parsehoststxt.c @@ -0,0 +1,69 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/arraylist.h" +#include "libc/dns/dns.h" +#include "libc/dns/hoststxt.h" +#include "libc/runtime/runtime.h" +#include "libc/sock/sock.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/af.h" + +/** + * Parses HOSTS.TXT contents. + * + * Hostnames were invented by Peggy Karp; her format looks like this: + * + * # this is a comment + * # IP CANON [ALT...] + * 203.0.113.1 lol.example. lol + * 203.0.113.2 cat.example. cat + * + * @param htp points to a HostsTxt object, which should be zero + * initialized by the caller; or if it already contains items, + * this function will append + * @param f is the file content; see fopen() and fmemopen() + * @return 0 on success, or -1 w/ errno + * @see hoststxtsort() which is the logical next step + */ +int parsehoststxt(struct HostsTxt *ht, FILE *f) { + int rc = 0; + char stackline[128]; + char *line = stackline; + size_t linecap = sizeof(stackline); + while ((getline(&line, &linecap, f)) != -1) { + struct HostsTxtEntry entry; + char *addr, *name, *tok, *comment; + if ((comment = strchr(line, '#'))) *comment = '\0'; + if ((addr = strtok_r(line, " \t\r\n\v", &tok)) && + inet_pton(AF_INET, addr, entry.ip) == 1) { + entry.canon = ht->strings.i; + while ((name = strtok_r(NULL, " \t\r\n\v", &tok))) { + entry.name = ht->strings.i; + if (concat(&ht->strings, name, strnlen(name, DNS_NAME_MAX) + 1) == -1 || + append(&ht->entries, &entry) == -1) { + rc = -1; + } + } + } + } + free_s(&line); + return rc | ferror(f); +} diff --git a/libc/dns/parseresolvconf.c b/libc/dns/parseresolvconf.c new file mode 100644 index 00000000..5dda632b --- /dev/null +++ b/libc/dns/parseresolvconf.c @@ -0,0 +1,68 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/arraylist.h" +#include "libc/dns/dns.h" +#include "libc/dns/resolvconf.h" +#include "libc/runtime/runtime.h" +#include "libc/sock/sock.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/af.h" +#include "libc/sysv/consts/inaddr.h" + +/** + * Parses /etc/resolv.conf file. + * + * The content of the file usually looks like this: + * + * nameserver 8.8.8.8 + * nameserver 8.8.4.4 + * + * @param resolv points to a ResolvConf object, which should be zero + * initialized by the caller; or if it already contains items, + * this function will append + * @param f is an open stream with file content + * @return number of nameservers appended, or -1 w/ errno + */ +int parseresolvconf(struct ResolvConf *resolv, struct FILE *f) { + /* TODO(jart): options ndots:5 */ + int rc = 0; + char stackline[32]; + char *line = stackline; + size_t linecap = sizeof(stackline); + struct sockaddr_in nameserver; + nameserver.sin_family = AF_INET; + nameserver.sin_port = htons(DNS_PORT); + while (getline(&line, &linecap, f) != -1) { + char *directive, *value, *tok, *comment; + if ((comment = strchr(line, '#'))) *comment = '\0'; + if ((directive = strtok_r(line, " \t\r\n\v", &tok)) && + (value = strtok_r(NULL, " \t\r\n\v", &tok))) { + if ((strcmp(directive, "nameserver") == 0 && + inet_pton(AF_INET, value, &nameserver.sin_addr.s_addr) == 1) || + (strcmp(directive, "search") == 0 && strcmp(value, "local") == 0 && + (nameserver.sin_addr.s_addr = htonl(INADDR_LOOPBACK)))) { + if (append(&resolv->nameservers, &nameserver) != -1) ++rc; + } + } + } + free_s(&line); + return rc | ferror(f); +} diff --git a/libc/dns/pascalifydnsname.c b/libc/dns/pascalifydnsname.c new file mode 100644 index 00000000..dd5dc5ab --- /dev/null +++ b/libc/dns/pascalifydnsname.c @@ -0,0 +1,60 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dns/dns.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +/** + * Writes dotted hostname to DNS message wire. + * + * The wire format is basically a sequence of Pascal strings, for each + * label in the name. We only do enough validation to maintain protocol + * invariants. + * + * @param name is a dotted NUL-terminated hostname string + * @return bytes written (excluding NUL) or -1 w/ errno + */ +int pascalifydnsname(uint8_t *buf, size_t size, const char *name) { + size_t i = 0; + size_t namelen = strlen(name); + if (namelen > DNS_NAME_MAX) return enametoolong(); + if (size || namelen) { + if (namelen + 1 > size) return enospc(); + buf[0] = '\0'; + size_t j = 0; + for (;;) { + size_t k; + for (k = 0; name[j + k] && name[j + k] != '.'; ++k) { + buf[i + k + 1] = name[j + k]; + } + if (k) { + if (k > DNS_LABEL_MAX) return enametoolong(); + buf[i] = k; + i += k + 1; + } + j += k + 1; + if (!name[j - 1]) { + break; + } + } + buf[i] = '\0'; + } + return i; +} diff --git a/libc/dns/resolvconf.h b/libc/dns/resolvconf.h new file mode 100644 index 00000000..e6dff80a --- /dev/null +++ b/libc/dns/resolvconf.h @@ -0,0 +1,25 @@ +#ifndef COSMOPOLITAN_LIBC_DNS_RESOLVCONF_H_ +#define COSMOPOLITAN_LIBC_DNS_RESOLVCONF_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct FILE; +struct sockaddr_in; + +struct Nameservers { + size_t i, n; + struct sockaddr_in *p; +}; + +struct ResolvConf { + struct Nameservers nameservers; +}; + +const struct ResolvConf *getresolvconf(void) returnsnonnull; +int parseresolvconf(struct ResolvConf *, struct FILE *) paramsnonnull(); +void freeresolvconf(struct ResolvConf **) paramsnonnull(); +int getntnameservers(struct ResolvConf *resolv) paramsnonnull(); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_DNS_RESOLVCONF_H_ */ diff --git a/libc/dns/resolvedns.c b/libc/dns/resolvedns.c new file mode 100644 index 00000000..7a5b6552 --- /dev/null +++ b/libc/dns/resolvedns.c @@ -0,0 +1,121 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/dns/consts.h" +#include "libc/dns/dns.h" +#include "libc/dns/dnsheader.h" +#include "libc/dns/dnsquestion.h" +#include "libc/dns/resolvconf.h" +#include "libc/mem/mem.h" +#include "libc/rand/rand.h" +#include "libc/runtime/runtime.h" +#include "libc/sock/sock.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/af.h" +#include "libc/sysv/consts/ipproto.h" +#include "libc/sysv/consts/sock.h" +#include "libc/sysv/errfuns.h" + +/** + * Queries Domain Name System for address associated with name. + * + * @param resolvconf can be getresolvconf() + * @param af can be AF_INET, AF_UNSPEC + * @param name can be a local or fully-qualified hostname + * @param addr should point to a struct sockaddr_in; if this function + * succeeds, its sin_family and sin_addr fields will be modified + * @param addrsize is the byte size of addr + * @return number of matches found, or -1 w/ errno + * @error EAFNOSUPPORT. ENETDOWN, ENAMETOOLONG, EBADMSG + */ +int resolvedns(const struct ResolvConf *resolvconf, int af, const char *name, + struct sockaddr *addr, uint32_t addrsize) { + if (af != AF_INET && af != AF_UNSPEC) return eafnosupport(); + if (!resolvconf->nameservers.i) return 0; + struct DnsHeader header; + struct DnsQuestion question; + memset(&header, 0, sizeof(header)); + header.id = rand32(); + header.bf1 = 1; /* recursion desired */ + header.qdcount = 1; + question.qname = name; + question.qtype = DNS_TYPE_A; + question.qclass = DNS_CLASS_IN; + const size_t kMsgMax = 512; + uint8_t *outmsg = NULL; + uint8_t *inmsg = NULL; + size_t msgsize; + int res = -1; + int rc, rc2; + if ((outmsg = malloc(kMsgMax)) && (inmsg = malloc(kMsgMax)) && + (rc = serializednsheader(outmsg, kMsgMax, header)) != -1 && + (rc2 = serializednsquestion(outmsg + rc, kMsgMax - rc, question)) != -1) { + msgsize = rc + rc2; + int fd; + if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1 && + sendto(fd, outmsg, msgsize, 0, (void *)&resolvconf->nameservers.p[0], + sizeof(resolvconf->nameservers.p[0])) == msgsize) { + struct DnsHeader response; + if ((rc = recv(fd, inmsg, kMsgMax, 0)) != -1 && + (rc2 = deserializednsheader(&response, inmsg, rc)) != -1 && + response.id == header.id) { + res = 0; + if (response.ancount) { + uint8_t *p = inmsg + rc2; + uint8_t *pe = inmsg + rc; + while (p < pe && response.qdcount) { + p += strnlen((char *)p, pe - p) + 1 + 4; + response.qdcount--; + } + if (p + 1 < pe) { + if ((p[0] & 0b11000000) == 0b11000000) { /* name pointer */ + p += 2; + } else { + p += strnlen((char *)p, pe - p) + 1; + } + if (p + 2 + 2 + 4 + 2 < pe) { + uint16_t rtype, rclass, rdlength; + rtype = read16be(p), p += 2; + rclass = read16be(p), p += 2; + /* ttl */ p += 4; + rdlength = read16be(p), p += 2; + if (p + rdlength <= pe && rdlength == 4 && + (rtype == DNS_TYPE_A && rclass == DNS_CLASS_IN)) { + res = 1; + if (addrsize) { + if (addrsize >= kMinSockaddr4Size) { + struct sockaddr_in *addr4 = (struct sockaddr_in *)addr; + addr4->sin_family = AF_INET; + memcpy(&addr4->sin_addr.s_addr, p, 4); + } else { + res = einval(); + } + } + } + } + } + } + } + } + res |= close(fd); + } + free(outmsg); + return res; +} diff --git a/libc/dns/resolvehoststxt.c b/libc/dns/resolvehoststxt.c new file mode 100644 index 00000000..ba0d87e8 --- /dev/null +++ b/libc/dns/resolvehoststxt.c @@ -0,0 +1,69 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/dns/consts.h" +#include "libc/dns/dns.h" +#include "libc/dns/hoststxt.h" +#include "libc/sock/sock.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" +#include "libc/sysv/consts/af.h" + +static int hoststxtgetcmp(const char *node, const struct HostsTxtEntry *entry, + const char *strings) { + return dnsnamecmp(node, &strings[entry->name]); +} + +/** + * Finds address associated with name in HOSTS.TXT table. + * + * This function performs binary search, so sorthoststxt() must be + * called on the table beforehand. + * + * @param ht can be gethoststxt() + * @param af can be AF_INET, AF_UNSPEC + * @param name can be a local or fully-qualified hostname + * @param addr should point to a struct sockaddr_in; if this function + * succeeds, its sin_family and sin_addr fields will be modified + * @param addrsize is the byte size of addr + * @param canon be used to return a pointer to the canonical name + * @return number of matches found, or -1 w/ errno + * @error EAFNOSUPPORT + */ +int resolvehoststxt(const struct HostsTxt *ht, int af, const char *name, + struct sockaddr *addr, uint32_t addrsize, + const char **canon) { + if (af != AF_INET && af != AF_UNSPEC) return eafnosupport(); + struct HostsTxtEntry *entry = bsearch_r( + name, ht->entries.p, ht->entries.i, sizeof(struct HostsTxtEntry), + (void *)hoststxtgetcmp, ht->strings.p); + if (entry) { + if (addr) { + if (addrsize < kMinSockaddr4Size) return einval(); + struct sockaddr_in *addr4 = (struct sockaddr_in *)addr; + addr4->sin_family = AF_INET; + memcpy(&addr4->sin_addr.s_addr, &entry->ip[0], 4); + } + if (canon) *canon = &ht->strings.p[entry->canon]; + return 1; + } else { + return 0; + } +} diff --git a/libc/dns/rfc0226.txt b/libc/dns/rfc0226.txt new file mode 100644 index 00000000..96182831 --- /dev/null +++ b/libc/dns/rfc0226.txt @@ -0,0 +1,59 @@ + + + + + + +NETWORK WORKING GROUP PEGGY KARP +REQUEST FOR COMMENTS #226 MITRE +NIC #7625 20 SEPT 71 +CATEGORIES: D.3 +UPDATES: NONE +OBSOLETES: NONE + + STANDARDIZATION OF HOST MNEUMONICS + +IN EACH TELNET IMPLEMENTATION, A LIST OF HOST NMEUMONICS IS PROVIDED +FOR THE USER TO INDICATE THE SERVING HOST DESIRED. CURRENTLY, EACH +SITE EMPLOYS THEIR OWN SPECIAL LIST. RATHER THAN REQUIRE THE USER TO +BE COGNIZANT OF THE IDIOSYNCRASIES OF EACH LIST, ESPECIALLY WHEN +CHAINED THROUGH SEVERAL HOSTS VIA TELNET, IT HAS BEEN RECOMMENDED THAT +STANDARD HOST DESIGNATORS BE ADOPTED. + +THE FOLLOWING LIST OF SIX CHARACTER DESIGNATORS IS PROPOSED AS THE +STANDARD LIST. REGISTER ANY OBJECTIONS BY 3 OCTOBER TO P. KARP (703) +893-3500 X2391, X2318. AN OFFICIAL POLICY AND IMPLEMENTATION DATE WILL +BE SET ON 8 OCTOBER. + +THE LIST: + HOST # DESIGNATOR + 1 UCLA + 65 UCLA36 + 2 SRIARC + 66 SRIAI + 3 UCSB + 4 UTAH + 6 MULTCS + 70 MITDM + 7 RAND + 8 SDC + 9 HARV + 10 LNCTX2 + 74 LNC360 + 11 STAN + 12 ILL + 69 BBN + 133 BBNB + 144 AMES + 145 MITRE + 158 TIP + + [ This RFC was put into machine readable form for entry ] + [ into the online RFC archives by BBN Corp. under the ] + [ direction of Alex McKenzie. 12/96 ] + + + + + [Page 1] + diff --git a/libc/dns/rfc0247.txt b/libc/dns/rfc0247.txt new file mode 100644 index 00000000..57e32091 --- /dev/null +++ b/libc/dns/rfc0247.txt @@ -0,0 +1,222 @@ + + + + + + +Network Working Group Peggy Karp +Request for Comments: #247 MITRE +NIC 7688 12 October 1971 +Categories: Policy, Telnet +Related: #226, 236, 239, 233, 237 +Obsoletes: #226 + + Proferred Set of Standard Host Names + + In RFC #226, BBN's TENEX list of Host names was set up as a strawman + set of standard Host names. Comments received since then (an RFC + actually generated comments!!!) have influenced me to propose the + following general rules for forming Host names. + + The Host names will be 8 characters in length. The general form is + + '-' + + will be at most 4 characters, formed as follows: + + (a) Use the keyword in the site name, if not more than + four characters, e.g., NASA Ames, Case Western + Reserve. ---- ---- + + (b) Use the standard acronym, if not more than four + characters, e.g., UCLA, RADC, NBS. + + (c) If a standard abbreviation exists, use it, e.g., Ill. + + (d) If none of the above apply, use the first four letters + in the site name, e.g., Burr, Mitr, Harv. + + (e) If none of the above is acceptable to the site, the + technical liaison should select the site mnemonic. + + will be at most 4 characters of the form + . + Examples of mfg. # are: + + IBM 360 2 digit model number + IBM 370 3 digit model number + PDP 1 - 2 digit model number + Burroughs 4 digits + CDC 4 digits + etc. + + + + + + + + [Page 1] + +RFC #247 + + + will be used when more than one machine of the same + type is located at a site (e.g., 2 PDP-10s at MIT, at SRI, and + at BBN). + + Limiting to 4 characters does not permit distinctions + to be made between machines with 4 digit mfg. #s. I expect + the situation will be handled in an ad hoc manner by the NIC if + it arises. + + TIPs are identified as 'TIP' rather than by '316'. If a Host + is not to be permanently addressable, the machine is identified + as 'TEST'. + + A list of Host names, formed according to these rules, is + attached. Alternate Host names should be provided, as + suggested by Jon Postel (RFC #236). RFC's 206, 233, and + 236 present lists with 4-character alternate names. The + Technical Liaison should select the alternate name for his + site and communicate the selection to the NIC. + + + The preceding rules and the attached list of Host names are + subject to the approval of the NWG. Hereafter, the list will + be generated and maintained by the NIC in cooperation with + the Technical Liaison at each site, as suggested in RFC #237. + Comments should be addressed to Dick Watson. + + + + + + + + [ This RFC was put into machine readable form for entry ] + + [ into the online RFC archives by BBN Corp. under the ] + + [ direction of Alex McKenzie. 12/96 ] + + + + + + + + + + + + [Page 2] + +RFC #247 +Attachment 1 + + NETWORK ADDRESS STANDARD NAME + --------------- ------------- + 1 UCLA-7 + 65 UCLA-91 + 2 SRI-10NI + 66 SRI-10AI + 3 UCSB-75 + 4 UTAH-10 + 5 BBN-516 + 69 BBN-10A + 133 BBN-10B + 6 MIT-645 + 70 MIT-10DM + 134 MIT-10AI + 7 RAND-65 + 71 RAND-10 + 8 SDC-75 + 9 HARV-10 + 73 HARV-1 + 137 HARV-11 + 10 LL-67 + 74 LL-TX2 + 138 LL-TSP + 11 SAIL-10 + 12 ILL-11 + 76 ILL-6500 + 13 CASE-10 + 14 CMU-10 + 15 BURR-6500 + 79 BURR-TEST + 16 AMES-67 + 144 AMES-TIP + 145 MITR-TIP + 18 RADC-645 + 146 RADC-TIP + 19 NBS-11 + 147 NBS-TIP + 148 ETAC-TIP + 21 TINK-418 + 22 MCCL-418 + 23 USC-44 + 151 USC-TIP + 152 GWC-TIP + 25 NCAR-7600 + 153 NCAR-TIP + 158 BBNX-TEST + + + + [Page 3] + +RFC #247 +Attachment 2 + + An Implementation Scheme + +If the standard Host names are formed according to the proposed +rules, the following implementation scheme, suggested by Steve +Crocker, can be used. + + Map into an 8-bit number, S and + map into an 8-bit number, M, + where + S + M = Network Address. + + S and M can be selected such that specification of + alone could cause a default to the "primary" Host at + the site. Note that this scheme depends on a unique + designator for each IMP. + +Some examples: + +If the "primary" Host at UCLA is the 91, let + UCLA -> S = X'41' + 7 -> M = X'40' + 91 -> M = X'00' +then for + UCLA-7, S + M = X'01' = 1 base 10 + UCLA-91,S + M = X'41' = 65 base 10 + +and + UCLA alone = X'41' = 65 base 10 + +If the primary Host at BBN is TENEX System A, let + BBN -> S = X'45' + 516 -> M = X'40' + 10A -> M = X'00' + 10B -> M = X'C0' +then for + BBN-516, S + M = X'05' = 5 base 10 + BBN-10A, S + M = X'45' = 69 base 10 + BBN-10B, S + M = X'85' = 133 base 10 + +and + BBN alone = X'45' = 69 base 10 + +The primary Host for each IMP would be designated by the +site and such information disseminated by the NIC. + + + + + + [Page 4] + diff --git a/libc/dns/rfc1035.txt b/libc/dns/rfc1035.txt new file mode 100644 index 00000000..b1a9bf5a --- /dev/null +++ b/libc/dns/rfc1035.txt @@ -0,0 +1,3077 @@ +Network Working Group P. Mockapetris +Request for Comments: 1035 ISI + November 1987 +Obsoletes: RFCs 882, 883, 973 + + DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION + + +1. STATUS OF THIS MEMO + +This RFC describes the details of the domain system and protocol, and +assumes that the reader is familiar with the concepts discussed in a +companion RFC, "Domain Names - Concepts and Facilities" [RFC-1034]. + +The domain system is a mixture of functions and data types which are an +official protocol and functions and data types which are still +experimental. Since the domain system is intentionally extensible, new +data types and experimental behavior should always be expected in parts +of the system beyond the official protocol. The official protocol parts +include standard queries, responses and the Internet class RR data +formats (e.g., host addresses). Since the previous RFC set, several +definitions have changed, so some previous definitions are obsolete. + +Experimental or obsolete features are clearly marked in these RFCs, and +such information should be used with caution. + +The reader is especially cautioned not to depend on the values which +appear in examples to be current or complete, since their purpose is +primarily pedagogical. Distribution of this memo is unlimited. + + Table of Contents + + 1. STATUS OF THIS MEMO 1 + 2. INTRODUCTION 3 + 2.1. Overview 3 + 2.2. Common configurations 4 + 2.3. Conventions 7 + 2.3.1. Preferred name syntax 7 + 2.3.2. Data Transmission Order 8 + 2.3.3. Character Case 9 + 2.3.4. Size limits 10 + 3. DOMAIN NAME SPACE AND RR DEFINITIONS 10 + 3.1. Name space definitions 10 + 3.2. RR definitions 11 + 3.2.1. Format 11 + 3.2.2. TYPE values 12 + 3.2.3. QTYPE values 12 + 3.2.4. CLASS values 13 + + + +Mockapetris [Page 1] + +RFC 1035 Domain Implementation and Specification November 1987 + + + 3.2.5. QCLASS values 13 + 3.3. Standard RRs 13 + 3.3.1. CNAME RDATA format 14 + 3.3.2. HINFO RDATA format 14 + 3.3.3. MB RDATA format (EXPERIMENTAL) 14 + 3.3.4. MD RDATA format (Obsolete) 15 + 3.3.5. MF RDATA format (Obsolete) 15 + 3.3.6. MG RDATA format (EXPERIMENTAL) 16 + 3.3.7. MINFO RDATA format (EXPERIMENTAL) 16 + 3.3.8. MR RDATA format (EXPERIMENTAL) 17 + 3.3.9. MX RDATA format 17 + 3.3.10. NULL RDATA format (EXPERIMENTAL) 17 + 3.3.11. NS RDATA format 18 + 3.3.12. PTR RDATA format 18 + 3.3.13. SOA RDATA format 19 + 3.3.14. TXT RDATA format 20 + 3.4. ARPA Internet specific RRs 20 + 3.4.1. A RDATA format 20 + 3.4.2. WKS RDATA format 21 + 3.5. IN-ADDR.ARPA domain 22 + 3.6. Defining new types, classes, and special namespaces 24 + 4. MESSAGES 25 + 4.1. Format 25 + 4.1.1. Header section format 26 + 4.1.2. Question section format 28 + 4.1.3. Resource record format 29 + 4.1.4. Message compression 30 + 4.2. Transport 32 + 4.2.1. UDP usage 32 + 4.2.2. TCP usage 32 + 5. MASTER FILES 33 + 5.1. Format 33 + 5.2. Use of master files to define zones 35 + 5.3. Master file example 36 + 6. NAME SERVER IMPLEMENTATION 37 + 6.1. Architecture 37 + 6.1.1. Control 37 + 6.1.2. Database 37 + 6.1.3. Time 39 + 6.2. Standard query processing 39 + 6.3. Zone refresh and reload processing 39 + 6.4. Inverse queries (Optional) 40 + 6.4.1. The contents of inverse queries and responses 40 + 6.4.2. Inverse query and response example 41 + 6.4.3. Inverse query processing 42 + + + + + + +Mockapetris [Page 2] + +RFC 1035 Domain Implementation and Specification November 1987 + + + 6.5. Completion queries and responses 42 + 7. RESOLVER IMPLEMENTATION 43 + 7.1. Transforming a user request into a query 43 + 7.2. Sending the queries 44 + 7.3. Processing responses 46 + 7.4. Using the cache 47 + 8. MAIL SUPPORT 47 + 8.1. Mail exchange binding 48 + 8.2. Mailbox binding (Experimental) 48 + 9. REFERENCES and BIBLIOGRAPHY 50 + Index 54 + +2. INTRODUCTION + +2.1. Overview + +The goal of domain names is to provide a mechanism for naming resources +in such a way that the names are usable in different hosts, networks, +protocol families, internets, and administrative organizations. + +From the user's point of view, domain names are useful as arguments to a +local agent, called a resolver, which retrieves information associated +with the domain name. Thus a user might ask for the host address or +mail information associated with a particular domain name. To enable +the user to request a particular type of information, an appropriate +query type is passed to the resolver with the domain name. To the user, +the domain tree is a single information space; the resolver is +responsible for hiding the distribution of data among name servers from +the user. + +From the resolver's point of view, the database that makes up the domain +space is distributed among various name servers. Different parts of the +domain space are stored in different name servers, although a particular +data item will be stored redundantly in two or more name servers. The +resolver starts with knowledge of at least one name server. When the +resolver processes a user query it asks a known name server for the +information; in return, the resolver either receives the desired +information or a referral to another name server. Using these +referrals, resolvers learn the identities and contents of other name +servers. Resolvers are responsible for dealing with the distribution of +the domain space and dealing with the effects of name server failure by +consulting redundant databases in other servers. + +Name servers manage two kinds of data. The first kind of data held in +sets called zones; each zone is the complete database for a particular +"pruned" subtree of the domain space. This data is called +authoritative. A name server periodically checks to make sure that its +zones are up to date, and if not, obtains a new copy of updated zones + + + +Mockapetris [Page 3] + +RFC 1035 Domain Implementation and Specification November 1987 + + +from master files stored locally or in another name server. The second +kind of data is cached data which was acquired by a local resolver. +This data may be incomplete, but improves the performance of the +retrieval process when non-local data is repeatedly accessed. Cached +data is eventually discarded by a timeout mechanism. + +This functional structure isolates the problems of user interface, +failure recovery, and distribution in the resolvers and isolates the +database update and refresh problems in the name servers. + +2.2. Common configurations + +A host can participate in the domain name system in a number of ways, +depending on whether the host runs programs that retrieve information +from the domain system, name servers that answer queries from other +hosts, or various combinations of both functions. The simplest, and +perhaps most typical, configuration is shown below: + + Local Host | Foreign + | + +---------+ +----------+ | +--------+ + | | user queries | |queries | | | + | User |-------------->| |---------|->|Foreign | + | Program | | Resolver | | | Name | + | |<--------------| |<--------|--| Server | + | | user responses| |responses| | | + +---------+ +----------+ | +--------+ + | A | + cache additions | | references | + V | | + +----------+ | + | cache | | + +----------+ | + +User programs interact with the domain name space through resolvers; the +format of user queries and user responses is specific to the host and +its operating system. User queries will typically be operating system +calls, and the resolver and its cache will be part of the host operating +system. Less capable hosts may choose to implement the resolver as a +subroutine to be linked in with every program that needs its services. +Resolvers answer user queries with information they acquire via queries +to foreign name servers and the local cache. + +Note that the resolver may have to make several queries to several +different foreign name servers to answer a particular user query, and +hence the resolution of a user query may involve several network +accesses and an arbitrary amount of time. The queries to foreign name +servers and the corresponding responses have a standard format described + + + +Mockapetris [Page 4] + +RFC 1035 Domain Implementation and Specification November 1987 + + +in this memo, and may be datagrams. + +Depending on its capabilities, a name server could be a stand alone +program on a dedicated machine or a process or processes on a large +timeshared host. A simple configuration might be: + + Local Host | Foreign + | + +---------+ | + / /| | + +---------+ | +----------+ | +--------+ + | | | | |responses| | | + | | | | Name |---------|->|Foreign | + | Master |-------------->| Server | | |Resolver| + | files | | | |<--------|--| | + | |/ | | queries | +--------+ + +---------+ +----------+ | + +Here a primary name server acquires information about one or more zones +by reading master files from its local file system, and answers queries +about those zones that arrive from foreign resolvers. + +The DNS requires that all zones be redundantly supported by more than +one name server. Designated secondary servers can acquire zones and +check for updates from the primary server using the zone transfer +protocol of the DNS. This configuration is shown below: + + Local Host | Foreign + | + +---------+ | + / /| | + +---------+ | +----------+ | +--------+ + | | | | |responses| | | + | | | | Name |---------|->|Foreign | + | Master |-------------->| Server | | |Resolver| + | files | | | |<--------|--| | + | |/ | | queries | +--------+ + +---------+ +----------+ | + A |maintenance | +--------+ + | +------------|->| | + | queries | |Foreign | + | | | Name | + +------------------|--| Server | + maintenance responses | +--------+ + +In this configuration, the name server periodically establishes a +virtual circuit to a foreign name server to acquire a copy of a zone or +to check that an existing copy has not changed. The messages sent for + + + +Mockapetris [Page 5] + +RFC 1035 Domain Implementation and Specification November 1987 + + +these maintenance activities follow the same form as queries and +responses, but the message sequences are somewhat different. + +The information flow in a host that supports all aspects of the domain +name system is shown below: + + Local Host | Foreign + | + +---------+ +----------+ | +--------+ + | | user queries | |queries | | | + | User |-------------->| |---------|->|Foreign | + | Program | | Resolver | | | Name | + | |<--------------| |<--------|--| Server | + | | user responses| |responses| | | + +---------+ +----------+ | +--------+ + | A | + cache additions | | references | + V | | + +----------+ | + | Shared | | + | database | | + +----------+ | + A | | + +---------+ refreshes | | references | + / /| | V | + +---------+ | +----------+ | +--------+ + | | | | |responses| | | + | | | | Name |---------|->|Foreign | + | Master |-------------->| Server | | |Resolver| + | files | | | |<--------|--| | + | |/ | | queries | +--------+ + +---------+ +----------+ | + A |maintenance | +--------+ + | +------------|->| | + | queries | |Foreign | + | | | Name | + +------------------|--| Server | + maintenance responses | +--------+ + +The shared database holds domain space data for the local name server +and resolver. The contents of the shared database will typically be a +mixture of authoritative data maintained by the periodic refresh +operations of the name server and cached data from previous resolver +requests. The structure of the domain data and the necessity for +synchronization between name servers and resolvers imply the general +characteristics of this database, but the actual format is up to the +local implementor. + + + + +Mockapetris [Page 6] + +RFC 1035 Domain Implementation and Specification November 1987 + + +Information flow can also be tailored so that a group of hosts act +together to optimize activities. Sometimes this is done to offload less +capable hosts so that they do not have to implement a full resolver. +This can be appropriate for PCs or hosts which want to minimize the +amount of new network code which is required. This scheme can also +allow a group of hosts can share a small number of caches rather than +maintaining a large number of separate caches, on the premise that the +centralized caches will have a higher hit ratio. In either case, +resolvers are replaced with stub resolvers which act as front ends to +resolvers located in a recursive server in one or more name servers +known to perform that service: + + Local Hosts | Foreign + | + +---------+ | + | | responses | + | Stub |<--------------------+ | + | Resolver| | | + | |----------------+ | | + +---------+ recursive | | | + queries | | | + V | | + +---------+ recursive +----------+ | +--------+ + | | queries | |queries | | | + | Stub |-------------->| Recursive|---------|->|Foreign | + | Resolver| | Server | | | Name | + | |<--------------| |<--------|--| Server | + +---------+ responses | |responses| | | + +----------+ | +--------+ + | Central | | + | cache | | + +----------+ | + +In any case, note that domain components are always replicated for +reliability whenever possible. + +2.3. Conventions + +The domain system has several conventions dealing with low-level, but +fundamental, issues. While the implementor is free to violate these +conventions WITHIN HIS OWN SYSTEM, he must observe these conventions in +ALL behavior observed from other hosts. + +2.3.1. Preferred name syntax + +The DNS specifications attempt to be as general as possible in the rules +for constructing domain names. The idea is that the name of any +existing object can be expressed as a domain name with minimal changes. + + + +Mockapetris [Page 7] + +RFC 1035 Domain Implementation and Specification November 1987 + + +However, when assigning a domain name for an object, the prudent user +will select a name which satisfies both the rules of the domain system +and any existing rules for the object, whether these rules are published +or implied by existing programs. + +For example, when naming a mail domain, the user should satisfy both the +rules of this memo and those in RFC-822. When creating a new host name, +the old rules for HOSTS.TXT should be followed. This avoids problems +when old software is converted to use domain names. + +The following syntax will result in fewer problems with many + +applications that use domain names (e.g., mail, TELNET). + + ::= | " " + + ::=

These functions provide the baseline of PC telecommunications + * support that doesn't require switching context or cpu mode. + * + *

Example use cases: + *

    + *
  • Qemu stdio + *
  • Bare metal stdio + *
  • FIPS-170-2 SSH alternative + *
  • NIC for key-signing servers + *
+ * + * @see www.lammertbies.nl/comm/info/serial-uart.html + */ + +#define COM1 0x0 /* offset in pc bios data area with port number (0x400) */ +#define COM2 0x2 +#define COM3 0x4 +#define COM4 0x6 +#define IRQ3 0x0b /* com2 interrupt number (irq3) */ +#define IRQ4 0x0c /* com1 interrupt number (irq4) */ +#define UART_DLAB (1 << 7) /* serial line conf mode bit */ +#define UART_DLL 0 /* divisor latch register */ +#define UART_DLM 1 /* divisor latch register */ +#define UART_IIR 2 /* interrupt identification register */ +#define UART_LCR 3 /* line control register */ +#define UART_LSR 5 /* line status register */ +#define UART_TTYDA (1 << 0) /* data available (rx ready) */ +#define UART_TTYOE (1 << 1) /* overrun error */ +#define UART_TTYPE (1 << 2) /* parity error */ +#define UART_TTYFE (1 << 3) /* framing error */ +#define UART_TTYBSR (1 << 4) /* break signal received */ +#define UART_TTYTXR (1 << 5) /* serial thr empty (tx ready) */ +#define UART_TTYIDL (1 << 6) /* serial thr empty and line idle */ +#define UART_TTYEDF (1 << 7) /* erroneous data in fifo */ + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +void sinit(unsigned short *ports, unsigned count, const char *config); +void sputc(unsigned char ch, int port); +int sgetc(int port); +void sputs(const char *s, int port); +void sflush(unsigned short *ports, unsigned count); +unsigned char slsr(int port); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NEXGEN32E_UART_H_ */ diff --git a/libc/nexgen32e/vcls.S b/libc/nexgen32e/vcls.S new file mode 100644 index 00000000..f26dbbbb --- /dev/null +++ b/libc/nexgen32e/vcls.S @@ -0,0 +1,41 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/macros.h" +#include "libc/nexgen32e/vidya.h" +#include "libc/notice.inc" +.real +.code16 # ∩ .code32 ∩ .code64 +.yoink __FILE__ + +/ Clears display page. +/ +/ @param es:di arbitrary address within video page +/ @return es:ax starting address +/ @mode long,legacy,real +vcls: xchg %di,%ax + bband VIDYA_REWIND,%ah,%al + xchg %di,%ax + push %di + bbmov VIDYA_SIZE,%cx,%ch,%cl + xor %al,%al + rep stosb + pop %ax + ret + .endfn vcls,globl diff --git a/libc/nexgen32e/vendor.h b/libc/nexgen32e/vendor.h new file mode 100644 index 00000000..fe475cbe --- /dev/null +++ b/libc/nexgen32e/vendor.h @@ -0,0 +1,62 @@ +#ifndef COSMOPOLITAN_LIBC_NEXGEN32E_VENDOR_H_ +#define COSMOPOLITAN_LIBC_NEXGEN32E_VENDOR_H_ +#include "libc/nexgen32e/kcpuids.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/* + * Known 80x86 Vendors (CPUID.0 EBX+EDX+ECX) + * + * ╤ ╤ + * GenuineIntel + * AuthenticAMD + * NexGenDriven + * AMDisbetter! + * CentaurHauls + * TransmetaCPU + * GenuineTMx86 + * CyrixInstead + * UMC UMC UMC + * SiS SiS SiS + * Geode by NSC + * RiseRiseRise + * Vortex86 SoC + * VIA VIA VIA + * VMwareVMware + * XenVMMXenVMM + * Microsoft Hv + * └────┐ │ + * G ⊕ t = 0x33 Intel + * A ⊕ A = 0x00 AMD + * N ⊕ v = 0x38 NexGen (Modern x86) + * A ⊕ e = 0x24 AMD (Rank & File) + * C ⊕ u = 0x36 Via (DBA Centaur) + * T ⊕ C = 0x17 Transmeta (Historical) + * G ⊕ x = 0x3f Transmeta (Historical) + * C ⊕ e = 0x26 Cyrix (Historical) + * U ⊕ M = 0x18 UMC (Taiwan) + * S ⊕ i = 0x3a SiS (Historical) + * G ⊕ N = 0x09 National Semiconductors (OLPC) + * R ⊕ i = 0x3b Rise Technology (Historical) + * V ⊕ S = 0x05 DM&P (Vortex86) + * V ⊕ I = 0x1f Via + * V ⊕ a = 0x37 VMware + * X ⊕ V = 0x0e Xen + * M ⊕ = 0x6d Microsoft (Win10 Hyper-V) + * │ │ + * │ │ perfect + * │ │ 𝑕(𝑠)=𝑠₀⊕𝑠₉ + * ╧ ╧ + * + * @note Parallels Desktop CPU brand string is " lrpepyh vr " since even + * folks designing microprocessor emulators apparently struggle w/ + * endianness lool. + */ +#define IsAuthenticAMD() (_KCPUIDS_VENDOR() == 0x00) +#define IsGenuineIntel() (_KCPUIDS_VENDOR() == 0x33) + +#define _KCPUIDS_VENDOR() \ + (((kCpuids[KCPUIDS_0][KCPUIDS_EBX] >> 000) & 0xff) ^ \ + ((kCpuids[KCPUIDS_0][KCPUIDS_ECX] >> 010) & 0xff)) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NEXGEN32E_VENDOR_H_ */ diff --git a/libc/nexgen32e/vidya.h b/libc/nexgen32e/vidya.h new file mode 100644 index 00000000..082306df --- /dev/null +++ b/libc/nexgen32e/vidya.h @@ -0,0 +1,130 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╠──────────────────────────────────────────────────────────────────────────────╣ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█▀█░▀█▀░█░█░█▀█░█░░░█░░░█░█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█░▄░░█░░█░█░█▀█░█░░░█░░░▀█▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░▀░▀░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀░░▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█▀█░█▀█░▀█▀░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀▀░█ █░██▀░░█░░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░▀░░░▀▀▀░▀░▀░░▀░░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀▀░█░█░█▀▀░█▀█░█░█░▀█▀░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░▄▄░░░▐█░░│ +│░░░░░░░█▀▀░▄▀▄░█▀▀░█░▄░█░█░░█░░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░▄▄▄░░░▄██▄░░█▀░░░█░▄░│ +│░░░░░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░▀░░▀░▀░▀▀▀░▀▀░▀▀▀░░░░░░░░░░▄██▀█▌░██▄▄░░▐█▀▄░▐█▀░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▐█▀▀▌░░░▄▀▌░▌░█░▌░░▌░▌░░│ +╠──────────────────────────────────────────────────────▌▀▄─▐──▀▄─▐▄─▐▄▐▄─▐▄─▐▄─│ +│ αcτµαlly pδrταblε εxεcµταblε § pc display helpers │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#ifndef COSMOPOLITAN_LIBC_NEXGEN32E_VIDYA_H_ +#define COSMOPOLITAN_LIBC_NEXGEN32E_VIDYA_H_ + +/** + * @fileoverview PC Display Helpers. + * + * These functions provide the baseline of PC graphics & teletype + * emulation support that doesn't require switching context or cpu mode. + * + * @see https://youtu.be/yHXx3orN35Y + * @see https://youtu.be/H1p1im_2uf4 + * @see Google's SGABIOS which logs MDA/CGA displays to UART as ASCII + * @mode long,legacy,real + */ + +#define VIDYA_ROWS 25 +#define VIDYA_COLUMNS 80 +#define VIDYA_SIZE (VIDYA_ROWS * VIDYA_COLUMNS * 2) +#define VIDYA_MODE_MDA 7 +#define VIDYA_MODE_CGA 3 +#define VIDYA_ADDR_MDA 0xb0000 +#define VIDYA_ADDR_CGA 0xb8000 +#define VIDYA_ATTR_NORMAL 0x07 /* cozy default for both mda and cga */ +#define VIDYA_REWIND ~0x7fff /* derived from mode addr min. lzcnt */ +#define VIDYA_SERVICE 0x10 +#define VIDYA_SET_MODE 0 +#define VIDYA_SET_CURSOR 0x0100 +#define VIDYA_SET_CURSOR_NONE 0x2000 +#define VIDYA_SET_BLINKING 0x1003 +#define VIDYA_SET_BLINKING_NONE 0x0000 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum VidyaMode { + kVidyaModeMda = VIDYA_MODE_MDA, + kVidyaModeCga = VIDYA_MODE_CGA +}; + +enum VidyaColor { + kVidyaColorBlack = 0x0, + kVidyaColorBlue = 0x1, + kVidyaColorGreen = 0x2, + kVidyaColorCyan = 0x3, + kVidyaColorRed = 0x4, + kVidyaColorMagenta = 0x5, + kVidyaColorBrown = 0x6, + kVidyaColorLightGray = 0x7, + kVidyaColorDarkGray = 0x8, + kVidyaColorLightBlue = 0x9, + kVidyaColorLightGreen = 0xa, + kVidyaColorLightCyan = 0xb, + kVidyaColorLightRed = 0xc, + kVidyaColorLightMagenta = 0xd, + kVidyaColorYellow = 0xe, + kVidyaColorWhite = 0xf +}; + +struct thatispacked VidyaCell { + unsigned glyph : 8; /* IBM Code Page 437 */ + union VidyaAttr { + enum { + kVidyaAttrBlank = 0x00, + kVidyaAttrNormal = VIDYA_ATTR_NORMAL, + kVidyaAttrMdaFlipped = 0x70, + kVidyaAttrMdaFlippedFaded = 0x78, + kVidyaAttrMdaFlippedIntense = 0xf0, + kVidyaAttrMdaFlippedFadedIntense = 0xf8 + } preset : 8; + struct VidyaTextDecoration { /* MDA Only */ + unsigned underline : 1; + unsigned __ignore1 : 1; + unsigned bold : 1; + unsigned __ignore2 : 3; + unsigned intense : 1; + } decoration; + struct { /* CGA Only */ + enum VidyaColor fg : 4; + enum VidyaColor bg : 4; + } color; + } attr; +}; + +typedef union VidyaAttr VidyaAttr; +typedef struct VidyaCell VidyaCell; +typedef struct VidyaCell VidyaPage[VIDYA_ROWS][VIDYA_COLUMNS]; + +__far VidyaPage *vinit(enum VidyaMode mode); +__far VidyaPage *vcls(__far VidyaCell *pos); +__far VidyaCell *vputc(__far VidyaCell *pos, int c); +__far VidyaCell *vputs(__far VidyaCell *pos, const char *str); +__far VidyaCell *vtput(__far VidyaCell *pos, const void *data, size_t size); +__far VidyaCell *vscroll(__far VidyaCell *pos, size_t bytes); + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NEXGEN32E_VIDYA_H_ */ diff --git a/libc/nexgen32e/wcscasecmp.S b/libc/nexgen32e/wcscasecmp.S new file mode 100644 index 00000000..7af30d1e --- /dev/null +++ b/libc/nexgen32e/wcscasecmp.S @@ -0,0 +1,74 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +/ Compares NUL-terminated wchar_t strings, ignoring ASCII case. +/ +/ @param rdi first string +/ @param rsi second string +/ @return 0 if equal, etc. +/ @note wchar_t is a 32-bit signed type +wcscasecmp: + or $-1,%rdx +/ fallthrough + .endfn wcscasecmp,globl + +/ Compares NUL-terminated wchar_t strings w/ limit ignoring ASCII case. +/ +/ @param rdi first string +/ @param rsi second string +/ @param rdx max shorts +/ @return 0 if equal, etc. +/ @note wchar_t is a 32-bit signed type +wcsncasecmp: + .leafprologue + .profilable + push %rbx + cmp %rdi,%rsi + je 3f + lea kToLower16(%rip),%r8 + or $-1,%rcx +1: add $1,%rcx + cmp %rcx,%rdx + je 3f + mov (%rsi,%rcx,4),%eax + mov %eax,%ebx + and $0x7f,%ebx + cmp %eax,%ebx + cmove (%r8,%rbx,2),%ax + push %rax + mov (%rdi,%rcx,4),%eax + mov %eax,%ebx + and $0x7f,%ebx + cmp %eax,%ebx + cmove (%r8,%rbx,2),%ax + pop %rbx + cmp %ebx,%eax + jne 2f + test %eax,%eax + jnz 1b +2: sub %ebx,%eax + jmp 4f +3: xor %eax,%eax +4: pop %rbx + .leafepilogue + .endfn wcsncasecmp,globl + + .yoink __FILE__ diff --git a/libc/nexgen32e/wcscmp-hook.S b/libc/nexgen32e/wcscmp-hook.S new file mode 100644 index 00000000..b2121dbd --- /dev/null +++ b/libc/nexgen32e/wcscmp-hook.S @@ -0,0 +1,34 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +/ Dispatches to fastest wcscmp() implementation. + .initbss 300,_init_wcscmp +hook$wcscmp: + .quad 0 + .endobj hook$wcscmp,globl,hidden + .previous + + .init.start 300,_init_wcscmp + ezlea wcscmp$k8,ax + stosq + .init.end 300,_init_wcscmp + + .yoink __FILE__ diff --git a/libc/nexgen32e/wcscmp-k8.S b/libc/nexgen32e/wcscmp-k8.S new file mode 100644 index 00000000..cd66e457 --- /dev/null +++ b/libc/nexgen32e/wcscmp-k8.S @@ -0,0 +1,68 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Compares NUL-terminated wchar_t strings. +/ +/ @param rdi first string +/ @param rsi second string +/ @return 0 if equal, etc. +/ @note wchar_t is a 32-bit signed type +wcscmp$k8: + or $-1,%rdx +/ fallthrough + .endfn wcscmp$k8,globl + +/ Compares NUL-terminated wchar_t strings w/ limit. +/ +/ @param rdi first string +/ @param rsi second string +/ @param rdx max shorts +/ @return 0 if equal, etc. +/ @note wchar_t is a 32-bit signed type +wcsncmp$k8: + .leafprologue + .profilable + push %rbx + xor %eax,%eax + cmp %rdi,%rsi + je 3f + or $-1,%rcx +1: add $1,%rcx + cmp %rcx,%rdx + je 3f + mov (%rsi,%rcx,4),%ebx + cmp (%rdi,%rcx,4),%ebx + jne 2f + test %ebx,%ebx + jnz 1b +2: cmovl .Lone(%rip),%eax + cmovg .Lneg1(%rip),%eax +3: pop %rbx + .leafepilogue + .endfn wcsncmp$k8,globl + + .rodata.cst4 +.Lone: .long 1 + .endobj .Lone +.Lneg1: .long -1 + .endobj .Lneg1 + .previous diff --git a/libc/nexgen32e/wcscmp.S b/libc/nexgen32e/wcscmp.S new file mode 100644 index 00000000..3148954e --- /dev/null +++ b/libc/nexgen32e/wcscmp.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +/ Compares NUL-terminated wchar_t strings. +/ +/ @param rdi first string +/ @param rsi second string +/ @return 0 if equal, etc. +/ @note wchar_t is a 32-bit signed type +/ @note this stub is provided for abi compatibility +wcscmp: jmp *hook$wcscmp(%rip) + .endfn wcscmp,globl + .yoink __FILE__ diff --git a/libc/nexgen32e/wcscspn.c b/libc/nexgen32e/wcscspn.c new file mode 100644 index 00000000..c45b61eb --- /dev/null +++ b/libc/nexgen32e/wcscspn.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/nexgen32e/hascharacter.h" +#include "libc/str/str.h" + +#undef strcspn +#define char wchar_t +#define HasCharacter HasCharacterWide +#define strcspn wcscspn + +#include "libc/nexgen32e/strcspn.c" diff --git a/libc/nexgen32e/wcsncmp-hook.S b/libc/nexgen32e/wcsncmp-hook.S new file mode 100644 index 00000000..4b113c36 --- /dev/null +++ b/libc/nexgen32e/wcsncmp-hook.S @@ -0,0 +1,33 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +/ Dispatches to fastest wcscmp() implementation. + .initbss 300,_init_wcsncmp +hook$wcsncmp: + .quad 0 + .endobj hook$wcsncmp,globl,hidden + .previous + + .init.start 300,_init_wcsncmp + ezlea wcsncmp$k8,ax + stosq + .init.end 300,_init_wcsncmp + .yoink __FILE__ diff --git a/libc/nexgen32e/wcsncmp.S b/libc/nexgen32e/wcsncmp.S new file mode 100644 index 00000000..c1703210 --- /dev/null +++ b/libc/nexgen32e/wcsncmp.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +/ Compares NUL-terminated wchar_t strings. +/ +/ @param rdi first string +/ @param rsi second string +/ @return 0 if equal, etc. +/ @note wchar_t is a 32-bit signed type +/ @note this stub is provided for abi compatibility +wcsncmp:jmp *hook$wcsncmp(%rip) + .endfn wcsncmp,globl + .yoink __FILE__ diff --git a/libc/nexgen32e/wcspbrk.c b/libc/nexgen32e/wcspbrk.c new file mode 100644 index 00000000..347f28ee --- /dev/null +++ b/libc/nexgen32e/wcspbrk.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/nexgen32e/hascharacter.h" +#include "libc/str/str.h" + +#undef strpbrk +#define char wchar_t +#define HasCharacter HasCharacterWide +#define strpbrk wcspbrk + +#include "libc/nexgen32e/strpbrk.c" diff --git a/libc/nexgen32e/wcsspn.c b/libc/nexgen32e/wcsspn.c new file mode 100644 index 00000000..a0549b31 --- /dev/null +++ b/libc/nexgen32e/wcsspn.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/nexgen32e/hascharacter.h" +#include "libc/str/str.h" + +#undef strspn +#define char wchar_t +#define HasCharacter HasCharacterWide +#define strspn wcsspn + +#include "libc/nexgen32e/strspn.c" diff --git a/libc/nexgen32e/wmemset.c b/libc/nexgen32e/wmemset.c new file mode 100644 index 00000000..8c8c822b --- /dev/null +++ b/libc/nexgen32e/wmemset.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bigword.h" +#include "libc/str/str.h" +#define T wchar_t +#define N (BIGWORD / sizeof(T)) +#include "libc/nexgen32e/wmemset.inc" +#undef T +#undef N diff --git a/libc/nexgen32e/wmemset.inc b/libc/nexgen32e/wmemset.inc new file mode 100644 index 00000000..26fad68d --- /dev/null +++ b/libc/nexgen32e/wmemset.inc @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +/** + * Sets wide memory. + * @asyncsignalsafe + */ +optimizespeed T *wmemset(T *dest, T c, size_t count) { + T v[N]; + size_t i, j; + for (i = 0; i < N; ++i) v[i] = c; + for (i = 0; i < count;) { + if (i + N <= count) { + for (j = 0; j < N; ++j) { + dest[i + j] = v[j]; + } + i += N; + } else { + dest[i++] = c; + } + } + return dest; +} diff --git a/libc/nexgen32e/x86compiler.h b/libc/nexgen32e/x86compiler.h new file mode 100644 index 00000000..03001136 --- /dev/null +++ b/libc/nexgen32e/x86compiler.h @@ -0,0 +1,141 @@ +#ifndef COSMOPOLITAN_LIBC_NEXGEN32E_X86COMPILER_H_ +#define COSMOPOLITAN_LIBC_NEXGEN32E_X86COMPILER_H_ + +/** + * @fileoverview x86 cpu feature compile-time requirement detection. + * @see -march=native, -mavx2, etc. + */ + +#ifdef __AES__ +#define _X86_CC_AES 1 +#else +#define _X86_CC_AES 0 +#endif + +#ifdef __AVX__ +#define _X86_CC_AVX 1 +#else +#define _X86_CC_AVX 0 +#endif + +#ifdef __AVX2__ +#define _X86_CC_AVX2 1 +#else +#define _X86_CC_AVX2 0 +#endif + +#ifdef __ABM__ +#define _X86_CC_ABM 1 +#else +#define _X86_CC_ABM 0 +#endif + +#ifdef __BMI__ +#define _X86_CC_BMI 1 +#else +#define _X86_CC_BMI 0 +#endif + +#ifdef __BMI2__ +#define _X86_CC_BMI2 1 +#else +#define _X86_CC_BMI2 0 +#endif + +#ifdef __FMA__ +#define _X86_CC_FMA 1 +#else +#define _X86_CC_FMA 0 +#endif + +#ifdef __ADX__ +#define _X86_CC_ADX 1 +#else +#define _X86_CC_ADX 0 +#endif + +#ifdef __PCLMUL__ +#define _X86_CC_PCLMUL 1 +#else +#define _X86_CC_PCLMUL 0 +#endif + +#ifdef __POPCNT__ +#define _X86_CC_POPCNT 1 +#else +#define _X86_CC_POPCNT 0 +#endif + +#ifdef __RDRND__ +#define _X86_CC_RDRND 1 +#else +#define _X86_CC_RDRND 0 +#endif + +#ifdef __RDSEED__ +#define _X86_CC_RDSEED 1 +#else +#define _X86_CC_RDSEED 0 +#endif + +#ifdef __SHA__ +#define _X86_CC_SHA 1 +#else +#define _X86_CC_SHA 0 +#endif + +#ifdef __SSSE3__ +#define _X86_CC_SSSE3 1 +#else +#define _X86_CC_SSSE3 0 +#endif + +#ifdef __SSE__ +#define _X86_CC_SSE 1 +#else +#define _X86_CC_SSE 0 +#endif + +#ifdef __SSE2__ +#define _X86_CC_SSE2 1 +#else +#define _X86_CC_SSE2 0 +#endif + +#ifdef __SSE3__ +#define _X86_CC_SSE3 1 +#else +#define _X86_CC_SSE3 0 +#endif + +#ifdef __SSE4_1__ +#define _X86_CC_SSE4_1 1 +#else +#define _X86_CC_SSE4_1 0 +#endif + +#ifdef __SSE4_2__ +#define _X86_CC_SSE4_2 1 +#else +#define _X86_CC_SSE4_2 0 +#endif + +#ifdef __XSAVE__ +#define _X86_CC_XSAVE 1 +#else +#define _X86_CC_XSAVE 0 +#endif + +#ifdef __CLFLUSHOPT__ +#define _X86_CC_CLFLUSHOPT 1 +#else +#define _X86_CC_CLFLUSHOPT 0 +#endif + +#ifdef __RDPID__ +#define _X86_CC_RDPID 1 +#else +#define _X86_CC_RDPID 0 +#endif + +#endif /* COSMOPOLITAN_LIBC_NEXGEN32E_X86COMPILER_H_ */ diff --git a/libc/nexgen32e/x86feature.h b/libc/nexgen32e/x86feature.h new file mode 100644 index 00000000..8a964cea --- /dev/null +++ b/libc/nexgen32e/x86feature.h @@ -0,0 +1,262 @@ +#ifndef COSMOPOLITAN_LIBC_NEXGEN32E_X86FEATURE_H_ +#define COSMOPOLITAN_LIBC_NEXGEN32E_X86FEATURE_H_ +#include "libc/nexgen32e/kcpuids.h" +#include "libc/nexgen32e/x86compiler.h" + +/** + * @fileoverview x86 cpu feature detection. + */ + +#define X86_HAVE(FEATURE) _X86_HAVE(X86_##FEATURE) + +/* clang-format off */ +/* --- FEATURE LEAF REG BIT COMPILE-TIME-DEFINE HOOK */ +#define X86_ACC 1H, EDX, 29, 0, _ +#define X86_ACPI 1H, EDX, 22, 0, _ +#define X86_ADX 7H, EBX, 19, _X86_CC_ADX, _ /* broadwell c. 2014 */ +#define X86_AES 1H, ECX, 25, _X86_CC_AES, _ /* westmere c. 2010 */ +#define X86_APIC 1H, EDX, 9, 0, _ +#define X86_ARCH_CAPABILITIES 7H, EDX, 29, 0, _ +#define X86_AVX 1H, ECX, 28, _X86_CC_AVX, AVX /* sandybridge c. 2012 */ +#define X86_AVX2 7H, EBX, 5, _X86_CC_AVX2, AVX /* haswell c. 2013 */ +#define X86_AVX512BW 7H, EBX, 30, 0, _ +#define X86_AVX512CD 7H, EBX, 28, 0, _ +#define X86_AVX512DQ 7H, EBX, 17, 0, _ +#define X86_AVX512ER 7H, EBX, 27, 0, _ +#define X86_AVX512F 7H, EBX, 16, 0, _ +#define X86_AVX512IFMA 7H, EBX, 21, 0, _ +#define X86_AVX512PF 7H, EBX, 26, 0, _ +#define X86_AVX512VBMI 7H, ECX, 1, 0, _ +#define X86_AVX512VL 7H, EBX, 31, 0, _ +#define X86_AVX512_4FMAPS 7H, EDX, 3, 0, _ +#define X86_AVX512_4VNNIW 7H, EDX, 2, 0, _ +#define X86_AVX512_BF16 7H, EAX, 5, 0, _ +#define X86_AVX512_BITALG 7H, ECX, 12, 0, _ +#define X86_AVX512_VBMI2 7H, ECX, 6, 0, _ +#define X86_AVX512_VNNI 7H, ECX, 11, 0, _ +#define X86_AVX512_VP2INTERSECT 7H, EDX, 8, 0, _ +#define X86_AVX512_VPOPCNTDQ 7H, ECX, 14, 0, _ +#define X86_BMI 7H, EBX, 3, _X86_CC_BMI, _ /* haswell c. 2013 */ +#define X86_BMI2 7H, EBX, 8, _X86_CC_BMI2, _ /* haswell c. 2013 */ +#define X86_CID 1H, ECX, 10, 0, _ +#define X86_CLDEMOTE 7H, ECX, 25, 0, _ +#define X86_CLFLUSH 1H, EDX, 19, _X86_CC_SSE2, _ +#define X86_CLFLUSHOPT 7H, EBX, 23, _X86_CC_CLFLUSHOPT, _ /* skylake/zen */ +#define X86_CLWB 7H, EBX, 24, 0, _ /* skylake/zen2 */ +#define X86_CMOV 1H, EDX, 15, 0, _ +#define X86_CQM 7H, EBX, 12, 0, _ +#define X86_CX16 1H, ECX, 13, 0, _ +#define X86_CX8 1H, EDX, 8, 0, _ +#define X86_DCA 1H, ECX, 18, 0, _ +#define X86_DE 1H, EDX, 2, 0, _ +#define X86_DS 1H, EDX, 21, 0, _ +#define X86_DSCPL 1H, ECX, 4, 0, _ +#define X86_DTES64 1H, ECX, 2, 0, _ +#define X86_ERMS 7H, EBX, 9, 0, _ /* broaadwell c. 2014 */ +#define X86_EST 1H, ECX, 7, 0, _ +#define X86_F16C 1H, ECX, 29, 0, _ +#define X86_FDP_EXCPTN_ONLY 7H, EBX, 6, 0, _ +#define X86_FLUSH_L1D 7H, EDX, 28, 0, _ +#define X86_FMA 1H, ECX, 12, _X86_CC_FMA, _ /* haswell c. 2013 */ +#define X86_FPU 1H, EDX, 0, 0, _ +#define X86_FSGSBASE 7H, EBX, 0, 0, _ +#define X86_FXSR 1H, EDX, 24, 0, _ +#define X86_GBPAGES 80000001H, EDX, 26, 0, _ +#define X86_GFNI 7H, ECX, 8, 0, _ +#define X86_HLE 7H, EBX, 4, 0, _ +#define X86_HT 1H, EDX, 28, 0, _ +#define X86_HYPERVISOR 1H, ECX, 31, 0, _ +#define X86_IA64 1H, EDX, 30, 0, _ +#define X86_INTEL_PT 7H, EBX, 25, 0, _ +#define X86_INTEL_STIBP 7H, EDX, 27, 0, _ +#define X86_INVPCID 1H, EBX, 10, 0, _ +#define X86_INVTSC 80000007H, EDX, 8, _X86_CC_POPCNT, _ /* i.e. not a K8 */ +#define X86_LA57 7H, ECX, 16, 0, _ +#define X86_LM 80000001H, EDX, 29, 0, _ +#define X86_MCA 1H, EDX, 14, 0, _ +#define X86_MCE 1H, EDX, 7, 0, _ +#define X86_MD_CLEAR 7H, EDX, 10, 0, _ +#define X86_MMX 1H, EDX, 23, 0, _ +#define X86_MOVBE 1H, ECX, 22, 0, _ +#define X86_MOVDIR64B 7H, ECX, 28, 0, _ +#define X86_MOVDIRI 7H, ECX, 27, 0, _ +#define X86_MP 80000001H, EDX, 19, 0, _ +#define X86_MPX 7H, EBX, 14, 0, _ +#define X86_MSR 1H, EDX, 5, 0, _ +#define X86_MTRR 1H, EDX, 12, 0, _ +#define X86_MWAIT 1H, ECX, 3, 0, _ +#define X86_NX 80000001H, EDX, 20, 0, _ +#define X86_OSPKE 7H, ECX, 4, 0, _ +#define X86_OSXSAVE 1H, ECX, 27, 0, _ +#define X86_PAE 1H, EDX, 6, 0, _ +#define X86_PAT 1H, EDX, 16, 0, _ +#define X86_PBE 1H, EDX, 31, 0, _ +#define X86_PCID 1H, ECX, 17, 0, _ +#define X86_PCLMUL 1H, ECX, 1, _X86_CC_PCLMUL, _ /* westmere c. 2010 */ +#define X86_PCONFIG 7H, EDX, 18, 0, _ +#define X86_PDCM 1H, ECX, 15, 0, _ +#define X86_PGE 1H, EDX, 13, 0, _ +#define X86_PKU 7H, ECX, 3, 0, _ +#define X86_PN 1H, EDX, 18, 0, _ +#define X86_POPCNT 1H, ECX, 23, _X86_CC_POPCNT, _ /* nehalem c. 2008 */ +#define X86_PSE 1H, EDX, 3, 0, _ +#define X86_PSE36 1H, EDX, 17, 0, _ +#define X86_RDPID 7H, ECX, 22, _X86_CC_RDPID, _ /* cannonlake c. 2018 */ +#define X86_RDRND 1H, ECX, 30, _X86_CC_RDRND, _ /* ivybridge c. 2012 */ +#define X86_RDSEED 7H, EBX, 18, _X86_CC_RDSEED, _ /* broadwell c. 2014 */ +#define X86_RDTSCP 80000001H, EDX, 27, 0, _ +#define X86_RDT_A 7H, EBX, 15, 0, _ +#define X86_RTM 7H, EBX, 11, 0, _ +#define X86_SDBG 1H, ECX, 11, 0, _ +#define X86_SELFSNOOP 1H, EDX, 27, 0, _ +#define X86_SEP 1H, EDX, 11, 0, _ +#define X86_SHA 7H, EBX, 29, _X86_CC_SHA, _ /* goldmont (2016) */ +#define X86_SMAP 7H, EBX, 20, 0, _ +#define X86_SMEP 7H, EBX, 7, 0, _ +#define X86_SMX 1H, ECX, 6, 0, _ +#define X86_SPEC_CTRL 7H, EDX, 26, 0, _ +#define X86_SPEC_CTRL_SSBD 7H, EDX, 31, 0, _ +#define X86_SSE 1H, EDX, 25, _X86_CC_SSE, _ /* pentium c. 1999 */ +#define X86_SSE2 1H, EDX, 26, _X86_CC_SSE2, _ /* pentium c. 2001 */ +#define X86_SSE3 1H, ECX, 0, _X86_CC_SSE3, _ /* k8 c. 2005 */ +#define X86_SSE4_1 1H, ECX, 19, _X86_CC_SSE4_1, _ /* core c. 2006 */ +#define X86_SSE4_2 1H, ECX, 20, _X86_CC_SSE4_2, _ /* nehalem c. 2008 */ +#define X86_SSSE3 1H, ECX, 9, _X86_CC_SSSE3, _ /* westmere c. 2010 */ +#define X86_SYSCALL 80000001H, EDX, 11, 0, _ +#define X86_TM2 1H, ECX, 8, 0, _ +#define X86_TME 7H, ECX, 13, 0, _ +#define X86_TSC 1H, EDX, 4, 0, _ +#define X86_TSC_ADJUST 7H, EBX, 1, 0, _ +#define X86_TSC_DEADLINE_TIMER 1H, ECX, 24, 0, _ +#define X86_TSX_FORCE_ABORT 7H, EDX, 13, 0, _ +#define X86_UMIP 7H, ECX, 2, 0, _ +#define X86_VAES 7H, ECX, 9, 0, _ +#define X86_VME 1H, EDX, 1, 0, _ +#define X86_VMX 1H, ECX, 5, 0, _ +#define X86_VPCLMULQDQ 7H, ECX, 10, 0, _ +#define X86_WAITPKG 7H, ECX, 5, 0, _ +#define X86_X2APIC 1H, ECX, 21, 0, _ +#define X86_XSAVE 1H, ECX, 26, _X86_CC_XSAVE, _ /* sandybridge c. 2012 */ +#define X86_XTPR 1H, ECX, 14, 0, _ +#define X86_ZERO_FCS_FDS 7H, EBX, 13, 0, _ +/* clang-format on */ + +/* AMD specific features */ +#define X86_ABM 80000001H, ECX, 5, _X86_CC_ABM, _ +#define X86_3DNOW 80000001H, EDX, 31, 0, _ +#define X86_3DNOWEXT 80000001H, EDX, 30, 0, _ +#define X86_3DNOWPREFETCH 80000001H, ECX, 8, 0, _ +#define X86_BPEXT 80000001H, ECX, 26, 0, _ +#define X86_CMP_LEGACY 80000001H, ECX, 1, 0, _ +#define X86_CR8_LEGACY 80000001H, ECX, 4, 0, _ +#define X86_EXTAPIC 80000001H, ECX, 3, 0, _ +#define X86_FMA4 80000001H, ECX, 16, 0, _ +#define X86_FXSR_OPT 80000001H, EDX, 25, 0, _ +#define X86_IBS 80000001H, ECX, 10, 0, _ +#define X86_LAHF_LM 80000001H, ECX, 0, 0, _ +#define X86_LWP 80000001H, ECX, 15, 0, _ +#define X86_MISALIGNSSE 80000001H, ECX, 7, 0, _ +#define X86_MMXEXT 80000001H, EDX, 22, 0, _ +#define X86_MWAITX 80000001H, ECX, 29, 0, _ +#define X86_NODEID_MSR 80000001H, ECX, 19, 0, _ +#define X86_OSVW 80000001H, ECX, 9, 0, _ +#define X86_OVERFLOW_RECOV 80000007H, EBX, 0, 0, _ +#define X86_PERFCTR_CORE 80000001H, ECX, 23, 0, _ +#define X86_PERFCTR_LLC 80000001H, ECX, 28, 0, _ +#define X86_PERFCTR_NB 80000001H, ECX, 24, 0, _ +#define X86_PTSC 80000001H, ECX, 27, 0, _ +#define X86_SKINIT 80000001H, ECX, 12, 0, _ +#define X86_SMCA 80000007H, EBX, 3, 0, _ +#define X86_SSE4A 80000001H, ECX, 6, 0, _ +#define X86_SUCCOR 80000007H, EBX, 1, 0, _ +#define X86_SVM 80000001H, ECX, 2, 0, _ +#define X86_TBM 80000001H, ECX, 21, 0, _ +#define X86_TCE 80000001H, ECX, 17, 0, _ +#define X86_TOPOEXT 80000001H, ECX, 22, 0, _ +#define X86_WDT 80000001H, ECX, 13, 0, _ +#define X86_XOP 80000001H, ECX, 11, 0, _ + +/* Defined but not loaded by kCpuids.S */ +#define X86_ARAT 6H, EAX, 2, 0, _ +#define X86_AVIC 8000000AH, EDX, 13, 0, _ +#define X86_CLZERO 80000008H, EBX, 0, 0, _ +#define X86_DECODEASSISTS 8000000AH, EDX, 7, 0, _ +#define X86_DTHERM 6H, EAX, 0, 0, _ +#define X86_FLUSHBYASID 8000000AH, EDX, 6, 0, _ +#define X86_HWP 6H, EAX, 7, 0, _ +#define X86_HWP_ACT_WINDOW 6H, EAX, 9, 0, _ +#define X86_HWP_EPP 6H, EAX, 10, 0, _ +#define X86_HWP_NOTIFY 6H, EAX, 8, 0, _ +#define X86_HWP_PKG_REQ 6H, EAX, 11, 0, _ +#define X86_IBPB 80000008H, EBX, 12, 0, _ +#define X86_IBRS 80000008H, EBX, 14, 0, _ +#define X86_IDA 6H, EAX, 1, 0, _ +#define X86_IRPERF 80000008H, EBX, 1, 0, _ +#define X86_LBRV 8000000AH, EDX, 1, 0, _ +#define X86_NPT 8000000AH, EDX, 0, 0, _ +#define X86_NRIPS 8000000AH, EDX, 3, 0, _ +#define X86_PAUSEFILTER 8000000AH, EDX, 10, 0, _ +#define X86_PFTHRESHOLD 8000000AH, EDX, 12, 0, _ +#define X86_PLN 6H, EAX, 4, 0, _ +#define X86_PTS 6H, EAX, 6, 0, _ +#define X86_SSBD 80000008H, EBX, 24, 0, _ +#define X86_SSB_NO 80000008H, EBX, 26, 0, _ +#define X86_STIBP 80000008H, EBX, 15, 0, _ +#define X86_STIBP_ALWAYS_ON 80000008H, EBX, 17, 0, _ +#define X86_SVML 8000000AH, EDX, 2, 0, _ +#define X86_TSCRATEMSR 8000000AH, EDX, 4, 0, _ +#define X86_VGIF 8000000AH, EDX, 16, 0, _ +#define X86_VIRT_SSBD 80000008H, EBX, 25, 0, _ +#define X86_VMCBCLEAN 8000000AH, EDX, 5, 0, _ +#define X86_V_VMSAVE_VMLOAD 8000000AH, EDX, 15, 0, _ +#define X86_WBNOINVD 80000008H, EBX, 9, 0, _ +#define X86_XGETBV1 DH, EAX, 2, 0, _ +#define X86_XSAVEC DH, EAX, 1, 0, _ +#define X86_XSAVEERPTR 80000008H, EBX, 2, 0, _ +#define X86_XSAVEOPT DH, EAX, 0, 0, _ +#define X86_XSAVES DH, EAX, 3, 0, _ + +#define X86_NEED(FEATURE) _X86_NEED(X86_##FEATURE) +#define X86_WORD(FEATURE) _X86_WORD(X86_##FEATURE) +#define X86_LEAF(FEATURE) _X86_LEAF(X86_##FEATURE) +#define X86_REG(FEATURE) _X86_REG(X86_##FEATURE) +#define X86_BIT(FEATURE) _X86_BIT(X86_##FEATURE) + +#define _X86_HAVE(FEATURE) __X86_HAVE(FEATURE) +#define _X86_NEED(FEATURE) __X86_NEED(FEATURE) +#define _X86_WORD(FEATURE) __X86_WORD(FEATURE) +#define _X86_LEAF(FEATURE) __X86_LEAF(FEATURE) +#define _X86_REG(FEATURE) __X86_REG(FEATURE) +#define _X86_BIT(FEATURE) __X86_BIT(FEATURE) + +#define __X86_HAVE(LEAF, REG, BIT, MANDATORY, HOOK) \ + ___X86_HAVE(LEAF, REG, BIT, MANDATORY, _X86_HOOK_##HOOK) +#define __X86_NEED(LEAF, REG, BIT, MANDATORY, HOOK) MANDATORY +#define __X86_WORD(LEAF, REG, BIT, MANDATORY, HOOK) KCPUIDS(LEAF, REG) +#define __X86_LEAF(LEAF, REG, BIT, MANDATORY, HOOK) LEAF +#define __X86_REG(LEAF, REG, BIT, MANDATORY, HOOK) REG +#define __X86_BIT(LEAF, REG, BIT, MANDATORY, HOOK) BIT + +#ifndef __ASSEMBLER__ +#define ___X86_HAVE(LEAF, REG, BIT, MANDATORY, HOOK) \ + HOOK(!!(MANDATORY || KCPUIDS(LEAF, REG) & (1u << BIT))) +#else +#define ___X86_HAVE(LEAF, REG, BIT, MANDATORY, HOOK) \ + $1 << (BIT % 8), BIT / 8 + KCPUIDS(LEAF, REG) +#endif + +#define _X86_HOOK__(X) X +#define _X86_HOOK_AVX(X) \ + ({ \ + YOINK(_init_enableavx); \ + X; \ + }) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +int _init_enableavx(void) pureconst; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NEXGEN32E_X86FEATURE_H_ */ diff --git a/libc/nexgen32e/x86info.h b/libc/nexgen32e/x86info.h new file mode 100644 index 00000000..c190c997 --- /dev/null +++ b/libc/nexgen32e/x86info.h @@ -0,0 +1,67 @@ +#ifndef COSMOPOLITAN_LIBC_NEXGEN32E_X86INFO_H_ +#define COSMOPOLITAN_LIBC_NEXGEN32E_X86INFO_H_ +#include "libc/nexgen32e/kcpuids.h" + +#define kX86CpuStepping ((KCPUIDS(1H, EAX) >> 0) & 0b1111) +#define kX86CpuModelid ((KCPUIDS(1H, EAX) >> 4) & 0b1111) +#define kX86CpuFamilyid ((KCPUIDS(1H, EAX) >> 8) & 0b1111) +#define kX86CpuType ((KCPUIDS(1H, EAX) >> 12) & 0b11) +#define kX86CpuExtmodelid ((KCPUIDS(1H, EAX) >> 16) & 0b1111) +#define kX86CpuExtfamilyid ((KCPUIDS(1H, EAX) >> 20) & 0b11111111) + +#define kX86CpuFamily \ + (kX86CpuFamilyid + (kX86CpuFamily == 15 ? kX86CpuExtfamilyid : 0)) + +#define kX86CpuModel \ + (kX86CpuModelid | \ + (kX86CpuFamily == 6 || kX86CpuFamily == 15 ? kX86CpuExtmodelid : 0) << 4) + +#define kX86ProcessorModelKey \ + (kX86CpuExtfamilyid << 12 | kX86CpuFamilyid << 8 | kX86CpuExtmodelid << 4 | \ + kX86CpuModelid) + +#define X86_MARCH_UNKNOWN 0 +#define X86_MARCH_CORE2 1 +#define X86_MARCH_NEHALEM 2 +#define X86_MARCH_WESTMERE 3 +#define X86_MARCH_SANDYBRIDGE 4 +#define X86_MARCH_IVYBRIDGE 5 +#define X86_MARCH_HASWELL 6 +#define X86_MARCH_BROADWELL 7 +#define X86_MARCH_SKYLAKE 8 +#define X86_MARCH_KABYLAKE 9 +#define X86_MARCH_CANNONLAKE 10 +#define X86_MARCH_ICELAKE 11 +#define X86_MARCH_TIGERLAKE 12 +#define X86_MARCH_BONNELL 13 +#define X86_MARCH_SALTWELL 14 +#define X86_MARCH_SILVERMONT 15 +#define X86_MARCH_AIRMONT 16 +#define X86_MARCH_GOLDMONT 17 +#define X86_MARCH_GOLDMONTPLUS 18 +#define X86_MARCH_TREMONT 19 +#define X86_MARCH_KNIGHTSLANDING 20 +#define X86_MARCH_KNIGHTSMILL 21 + +#define X86_GRADE_UNKNOWN 0 +#define X86_GRADE_APPLIANCE 1 +#define X86_GRADE_MOBILE 2 +#define X86_GRADE_TABLET 3 +#define X86_GRADE_DESKTOP 4 +#define X86_GRADE_CLIENT 5 +#define X86_GRADE_DENSITY 6 +#define X86_GRADE_SERVER 7 +#define X86_GRADE_SCIENCE 8 + +struct X86ProcessorModel { + short key; + unsigned char march; + unsigned char grade; +}; + +extern const size_t kX86ProcessorModelCount; +extern const struct X86ProcessorModel kX86ProcessorModels[]; + +const struct X86ProcessorModel *getx86processormodel(short) nosideeffect; + +#endif /* COSMOPOLITAN_LIBC_NEXGEN32E_X86INFO_H_ */ diff --git a/libc/nexgen32e/x87conf.inc b/libc/nexgen32e/x87conf.inc new file mode 100644 index 00000000..7d28c5dd --- /dev/null +++ b/libc/nexgen32e/x87conf.inc @@ -0,0 +1,34 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +/ Reconfigures transcendental math coprocessor. +/ +/ @param \conf can be absent to restore default +/ @clob x87 status and control words only +/ @see Intel Manual V.1 §8.1.5 +/ @mode long,legacy + .macro x87conf conf=$0x33f + push %ax + pushw \conf + fclex + fldcw (%rsp) + pop %ax + pop %ax + .endm diff --git a/libc/nexgen32e/xlm.S b/libc/nexgen32e/xlm.S new file mode 100644 index 00000000..5c812004 --- /dev/null +++ b/libc/nexgen32e/xlm.S @@ -0,0 +1,33 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +#include "libc/notice.inc" +#include "ape/config.h" + +/ eXtreme Low Memory. +/ @see ape/config.h + .section .xlm,"aw",@nobits + .align 4096 +__xlm: .rept XLM_SIZE + .byte 0 + .endr + .endobj __xlm,globl,hidden + .previous + .yoink __FILE__ diff --git a/libc/notice.inc b/libc/notice.inc new file mode 100644 index 00000000..4ed33151 --- /dev/null +++ b/libc/notice.inc @@ -0,0 +1,17 @@ +.ident "\n\ +Cosmopolitan\n\ +Copyright 2020 Justine Alexandra Roberts Tunney\n\ +\n\ +This program is free software; you can redistribute it and/or modify\n\ +it under the terms of the GNU General Public License as published by\n\ +the Free Software Foundation; version 2 of the License.\n\ +\n\ +This program is distributed in the hope that it will be useful, but\n\ +WITHOUT ANY WARRANTY; without even the implied warranty of\n\ +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n\ +General Public License for more details.\n\ +\n\ +You should have received a copy of the GNU General Public License\n\ +along with this program; if not, write to the Free Software\n\ +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n\ +02110-1301 USA" diff --git a/libc/nt/KernelBase/AccessCheck.s b/libc/nt/KernelBase/AccessCheck.s new file mode 100644 index 00000000..89d44c35 --- /dev/null +++ b/libc/nt/KernelBase/AccessCheck.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AccessCheck,AccessCheck,2 + + .text.windows +AccessCheck: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_AccessCheck(%rip),%rax + jmp __sysv2nt8 + .endfn AccessCheck,globl + .previous diff --git a/libc/nt/KernelBase/AccessCheckAndAuditAlarmW.s b/libc/nt/KernelBase/AccessCheckAndAuditAlarmW.s new file mode 100644 index 00000000..e5cd2b77 --- /dev/null +++ b/libc/nt/KernelBase/AccessCheckAndAuditAlarmW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AccessCheckAndAuditAlarmW,AccessCheckAndAuditAlarmW,3 diff --git a/libc/nt/KernelBase/AccessCheckByType.s b/libc/nt/KernelBase/AccessCheckByType.s new file mode 100644 index 00000000..e6316a1b --- /dev/null +++ b/libc/nt/KernelBase/AccessCheckByType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AccessCheckByType,AccessCheckByType,4 diff --git a/libc/nt/KernelBase/AccessCheckByTypeAndAuditAlarmW.s b/libc/nt/KernelBase/AccessCheckByTypeAndAuditAlarmW.s new file mode 100644 index 00000000..f21c6130 --- /dev/null +++ b/libc/nt/KernelBase/AccessCheckByTypeAndAuditAlarmW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AccessCheckByTypeAndAuditAlarmW,AccessCheckByTypeAndAuditAlarmW,5 diff --git a/libc/nt/KernelBase/AccessCheckByTypeResultList.s b/libc/nt/KernelBase/AccessCheckByTypeResultList.s new file mode 100644 index 00000000..77dcfbcd --- /dev/null +++ b/libc/nt/KernelBase/AccessCheckByTypeResultList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AccessCheckByTypeResultList,AccessCheckByTypeResultList,6 diff --git a/libc/nt/KernelBase/AccessCheckByTypeResultListAndAuditAlarmByHandleW.s b/libc/nt/KernelBase/AccessCheckByTypeResultListAndAuditAlarmByHandleW.s new file mode 100644 index 00000000..cb79ed1d --- /dev/null +++ b/libc/nt/KernelBase/AccessCheckByTypeResultListAndAuditAlarmByHandleW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AccessCheckByTypeResultListAndAuditAlarmByHandleW,AccessCheckByTypeResultListAndAuditAlarmByHandleW,7 diff --git a/libc/nt/KernelBase/AccessCheckByTypeResultListAndAuditAlarmW.s b/libc/nt/KernelBase/AccessCheckByTypeResultListAndAuditAlarmW.s new file mode 100644 index 00000000..6e073940 --- /dev/null +++ b/libc/nt/KernelBase/AccessCheckByTypeResultListAndAuditAlarmW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AccessCheckByTypeResultListAndAuditAlarmW,AccessCheckByTypeResultListAndAuditAlarmW,8 diff --git a/libc/nt/KernelBase/AcquireStateLock.s b/libc/nt/KernelBase/AcquireStateLock.s new file mode 100644 index 00000000..1a5ed3b0 --- /dev/null +++ b/libc/nt/KernelBase/AcquireStateLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AcquireStateLock,AcquireStateLock,11 diff --git a/libc/nt/KernelBase/ActivateActCtx.s b/libc/nt/KernelBase/ActivateActCtx.s new file mode 100644 index 00000000..734fbd1e --- /dev/null +++ b/libc/nt/KernelBase/ActivateActCtx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ActivateActCtx,ActivateActCtx,12 diff --git a/libc/nt/KernelBase/AddAccessAllowedAce.s b/libc/nt/KernelBase/AddAccessAllowedAce.s new file mode 100644 index 00000000..50d34e85 --- /dev/null +++ b/libc/nt/KernelBase/AddAccessAllowedAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddAccessAllowedAce,AddAccessAllowedAce,13 diff --git a/libc/nt/KernelBase/AddAccessAllowedAceEx.s b/libc/nt/KernelBase/AddAccessAllowedAceEx.s new file mode 100644 index 00000000..d8a60fd7 --- /dev/null +++ b/libc/nt/KernelBase/AddAccessAllowedAceEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddAccessAllowedAceEx,AddAccessAllowedAceEx,14 diff --git a/libc/nt/KernelBase/AddAccessAllowedObjectAce.s b/libc/nt/KernelBase/AddAccessAllowedObjectAce.s new file mode 100644 index 00000000..2351cbf1 --- /dev/null +++ b/libc/nt/KernelBase/AddAccessAllowedObjectAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddAccessAllowedObjectAce,AddAccessAllowedObjectAce,15 diff --git a/libc/nt/KernelBase/AddAccessDeniedAce.s b/libc/nt/KernelBase/AddAccessDeniedAce.s new file mode 100644 index 00000000..2b41ae2e --- /dev/null +++ b/libc/nt/KernelBase/AddAccessDeniedAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddAccessDeniedAce,AddAccessDeniedAce,16 diff --git a/libc/nt/KernelBase/AddAccessDeniedAceEx.s b/libc/nt/KernelBase/AddAccessDeniedAceEx.s new file mode 100644 index 00000000..6f5a5411 --- /dev/null +++ b/libc/nt/KernelBase/AddAccessDeniedAceEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddAccessDeniedAceEx,AddAccessDeniedAceEx,17 diff --git a/libc/nt/KernelBase/AddAccessDeniedObjectAce.s b/libc/nt/KernelBase/AddAccessDeniedObjectAce.s new file mode 100644 index 00000000..f3f4d7b8 --- /dev/null +++ b/libc/nt/KernelBase/AddAccessDeniedObjectAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddAccessDeniedObjectAce,AddAccessDeniedObjectAce,18 diff --git a/libc/nt/KernelBase/AddAce.s b/libc/nt/KernelBase/AddAce.s new file mode 100644 index 00000000..258213d7 --- /dev/null +++ b/libc/nt/KernelBase/AddAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddAce,AddAce,19 diff --git a/libc/nt/KernelBase/AddAuditAccessAce.s b/libc/nt/KernelBase/AddAuditAccessAce.s new file mode 100644 index 00000000..899216f8 --- /dev/null +++ b/libc/nt/KernelBase/AddAuditAccessAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddAuditAccessAce,AddAuditAccessAce,20 diff --git a/libc/nt/KernelBase/AddAuditAccessAceEx.s b/libc/nt/KernelBase/AddAuditAccessAceEx.s new file mode 100644 index 00000000..b456e808 --- /dev/null +++ b/libc/nt/KernelBase/AddAuditAccessAceEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddAuditAccessAceEx,AddAuditAccessAceEx,21 diff --git a/libc/nt/KernelBase/AddAuditAccessObjectAce.s b/libc/nt/KernelBase/AddAuditAccessObjectAce.s new file mode 100644 index 00000000..c83079f0 --- /dev/null +++ b/libc/nt/KernelBase/AddAuditAccessObjectAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddAuditAccessObjectAce,AddAuditAccessObjectAce,22 diff --git a/libc/nt/KernelBase/AddConsoleAliasA.s b/libc/nt/KernelBase/AddConsoleAliasA.s new file mode 100644 index 00000000..156d96d4 --- /dev/null +++ b/libc/nt/KernelBase/AddConsoleAliasA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddConsoleAliasA,AddConsoleAliasA,23 diff --git a/libc/nt/KernelBase/AddConsoleAliasW.s b/libc/nt/KernelBase/AddConsoleAliasW.s new file mode 100644 index 00000000..43bd696a --- /dev/null +++ b/libc/nt/KernelBase/AddConsoleAliasW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddConsoleAliasW,AddConsoleAliasW,24 diff --git a/libc/nt/KernelBase/AddDllDirectory.s b/libc/nt/KernelBase/AddDllDirectory.s new file mode 100644 index 00000000..7c34d0d7 --- /dev/null +++ b/libc/nt/KernelBase/AddDllDirectory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddDllDirectory,AddDllDirectory,25 diff --git a/libc/nt/KernelBase/AddExtensionProgId.s b/libc/nt/KernelBase/AddExtensionProgId.s new file mode 100644 index 00000000..a02c3600 --- /dev/null +++ b/libc/nt/KernelBase/AddExtensionProgId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddExtensionProgId,AddExtensionProgId,26 diff --git a/libc/nt/KernelBase/AddMandatoryAce.s b/libc/nt/KernelBase/AddMandatoryAce.s new file mode 100644 index 00000000..de1da4e2 --- /dev/null +++ b/libc/nt/KernelBase/AddMandatoryAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddMandatoryAce,AddMandatoryAce,27 diff --git a/libc/nt/KernelBase/AddPackageToFamilyXref.s b/libc/nt/KernelBase/AddPackageToFamilyXref.s new file mode 100644 index 00000000..1b8e26e4 --- /dev/null +++ b/libc/nt/KernelBase/AddPackageToFamilyXref.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddPackageToFamilyXref,AddPackageToFamilyXref,28 diff --git a/libc/nt/KernelBase/AddRefActCtx.s b/libc/nt/KernelBase/AddRefActCtx.s new file mode 100644 index 00000000..5ed04b07 --- /dev/null +++ b/libc/nt/KernelBase/AddRefActCtx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddRefActCtx,AddRefActCtx,29 diff --git a/libc/nt/KernelBase/AddResourceAttributeAce.s b/libc/nt/KernelBase/AddResourceAttributeAce.s new file mode 100644 index 00000000..047e601d --- /dev/null +++ b/libc/nt/KernelBase/AddResourceAttributeAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddResourceAttributeAce,AddResourceAttributeAce,30 diff --git a/libc/nt/KernelBase/AddSIDToBoundaryDescriptor.s b/libc/nt/KernelBase/AddSIDToBoundaryDescriptor.s new file mode 100644 index 00000000..050df47b --- /dev/null +++ b/libc/nt/KernelBase/AddSIDToBoundaryDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddSIDToBoundaryDescriptor,AddSIDToBoundaryDescriptor,31 diff --git a/libc/nt/KernelBase/AddScopedPolicyIDAce.s b/libc/nt/KernelBase/AddScopedPolicyIDAce.s new file mode 100644 index 00000000..1af913df --- /dev/null +++ b/libc/nt/KernelBase/AddScopedPolicyIDAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddScopedPolicyIDAce,AddScopedPolicyIDAce,32 diff --git a/libc/nt/KernelBase/AddVectoredContinueHandler.s b/libc/nt/KernelBase/AddVectoredContinueHandler.s new file mode 100644 index 00000000..1c981cd6 --- /dev/null +++ b/libc/nt/KernelBase/AddVectoredContinueHandler.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddVectoredContinueHandler,AddVectoredContinueHandler,33 + + .text.windows +AddVectoredContinueHandler: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_AddVectoredContinueHandler(%rip),%rax + jmp __sysv2nt + .endfn AddVectoredContinueHandler,globl + .previous diff --git a/libc/nt/KernelBase/AddVectoredExceptionHandler.s b/libc/nt/KernelBase/AddVectoredExceptionHandler.s new file mode 100644 index 00000000..2e34f386 --- /dev/null +++ b/libc/nt/KernelBase/AddVectoredExceptionHandler.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AddVectoredExceptionHandler,AddVectoredExceptionHandler,34 + + .text.windows +AddVectoredExceptionHandler: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_AddVectoredExceptionHandler(%rip),%rax + jmp __sysv2nt + .endfn AddVectoredExceptionHandler,globl + .previous diff --git a/libc/nt/KernelBase/AdjustTokenGroups.s b/libc/nt/KernelBase/AdjustTokenGroups.s new file mode 100644 index 00000000..4afc1e78 --- /dev/null +++ b/libc/nt/KernelBase/AdjustTokenGroups.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AdjustTokenGroups,AdjustTokenGroups,35 diff --git a/libc/nt/KernelBase/AdjustTokenPrivileges.s b/libc/nt/KernelBase/AdjustTokenPrivileges.s new file mode 100644 index 00000000..6421bff8 --- /dev/null +++ b/libc/nt/KernelBase/AdjustTokenPrivileges.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AdjustTokenPrivileges,AdjustTokenPrivileges,36 + + .text.windows +AdjustTokenPrivileges: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_AdjustTokenPrivileges(%rip),%rax + jmp __sysv2nt6 + .endfn AdjustTokenPrivileges,globl + .previous diff --git a/libc/nt/KernelBase/AllocConsole.s b/libc/nt/KernelBase/AllocConsole.s new file mode 100644 index 00000000..c8670dcb --- /dev/null +++ b/libc/nt/KernelBase/AllocConsole.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AllocConsole,AllocConsole,37 + + .text.windows +AllocConsole: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_AllocConsole(%rip) + leave + ret + .endfn AllocConsole,globl + .previous diff --git a/libc/nt/KernelBase/AllocateAndInitializeSid.s b/libc/nt/KernelBase/AllocateAndInitializeSid.s new file mode 100644 index 00000000..2cb3c635 --- /dev/null +++ b/libc/nt/KernelBase/AllocateAndInitializeSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AllocateAndInitializeSid,AllocateAndInitializeSid,38 diff --git a/libc/nt/KernelBase/AllocateLocallyUniqueId.s b/libc/nt/KernelBase/AllocateLocallyUniqueId.s new file mode 100644 index 00000000..efd229e5 --- /dev/null +++ b/libc/nt/KernelBase/AllocateLocallyUniqueId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AllocateLocallyUniqueId,AllocateLocallyUniqueId,39 diff --git a/libc/nt/KernelBase/AllocateUserPhysicalPages.s b/libc/nt/KernelBase/AllocateUserPhysicalPages.s new file mode 100644 index 00000000..93a79622 --- /dev/null +++ b/libc/nt/KernelBase/AllocateUserPhysicalPages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AllocateUserPhysicalPages,AllocateUserPhysicalPages,40 diff --git a/libc/nt/KernelBase/AllocateUserPhysicalPagesNuma.s b/libc/nt/KernelBase/AllocateUserPhysicalPagesNuma.s new file mode 100644 index 00000000..e3848e24 --- /dev/null +++ b/libc/nt/KernelBase/AllocateUserPhysicalPagesNuma.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AllocateUserPhysicalPagesNuma,AllocateUserPhysicalPagesNuma,41 diff --git a/libc/nt/KernelBase/AppContainerDeriveSidFromMoniker.s b/libc/nt/KernelBase/AppContainerDeriveSidFromMoniker.s new file mode 100644 index 00000000..74029dad --- /dev/null +++ b/libc/nt/KernelBase/AppContainerDeriveSidFromMoniker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppContainerDeriveSidFromMoniker,AppContainerDeriveSidFromMoniker,42 diff --git a/libc/nt/KernelBase/AppContainerFreeMemory.s b/libc/nt/KernelBase/AppContainerFreeMemory.s new file mode 100644 index 00000000..60f33030 --- /dev/null +++ b/libc/nt/KernelBase/AppContainerFreeMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppContainerFreeMemory,AppContainerFreeMemory,43 diff --git a/libc/nt/KernelBase/AppContainerLookupDisplayNameMrtReference.s b/libc/nt/KernelBase/AppContainerLookupDisplayNameMrtReference.s new file mode 100644 index 00000000..563dc600 --- /dev/null +++ b/libc/nt/KernelBase/AppContainerLookupDisplayNameMrtReference.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppContainerLookupDisplayNameMrtReference,AppContainerLookupDisplayNameMrtReference,44 diff --git a/libc/nt/KernelBase/AppContainerLookupMoniker.s b/libc/nt/KernelBase/AppContainerLookupMoniker.s new file mode 100644 index 00000000..18818ee4 --- /dev/null +++ b/libc/nt/KernelBase/AppContainerLookupMoniker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppContainerLookupMoniker,AppContainerLookupMoniker,45 diff --git a/libc/nt/KernelBase/AppContainerRegisterSid.s b/libc/nt/KernelBase/AppContainerRegisterSid.s new file mode 100644 index 00000000..d5355496 --- /dev/null +++ b/libc/nt/KernelBase/AppContainerRegisterSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppContainerRegisterSid,AppContainerRegisterSid,46 diff --git a/libc/nt/KernelBase/AppContainerUnregisterSid.s b/libc/nt/KernelBase/AppContainerUnregisterSid.s new file mode 100644 index 00000000..30882031 --- /dev/null +++ b/libc/nt/KernelBase/AppContainerUnregisterSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppContainerUnregisterSid,AppContainerUnregisterSid,47 diff --git a/libc/nt/KernelBase/AppPolicyGetClrCompat.s b/libc/nt/KernelBase/AppPolicyGetClrCompat.s new file mode 100644 index 00000000..5df4fb1c --- /dev/null +++ b/libc/nt/KernelBase/AppPolicyGetClrCompat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppPolicyGetClrCompat,AppPolicyGetClrCompat,48 diff --git a/libc/nt/KernelBase/AppPolicyGetCreateFileAccess.s b/libc/nt/KernelBase/AppPolicyGetCreateFileAccess.s new file mode 100644 index 00000000..64523c3f --- /dev/null +++ b/libc/nt/KernelBase/AppPolicyGetCreateFileAccess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppPolicyGetCreateFileAccess,AppPolicyGetCreateFileAccess,49 diff --git a/libc/nt/KernelBase/AppPolicyGetLifecycleManagement.s b/libc/nt/KernelBase/AppPolicyGetLifecycleManagement.s new file mode 100644 index 00000000..f8748f83 --- /dev/null +++ b/libc/nt/KernelBase/AppPolicyGetLifecycleManagement.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppPolicyGetLifecycleManagement,AppPolicyGetLifecycleManagement,50 diff --git a/libc/nt/KernelBase/AppPolicyGetMediaFoundationCodecLoading.s b/libc/nt/KernelBase/AppPolicyGetMediaFoundationCodecLoading.s new file mode 100644 index 00000000..5c91e73f --- /dev/null +++ b/libc/nt/KernelBase/AppPolicyGetMediaFoundationCodecLoading.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppPolicyGetMediaFoundationCodecLoading,AppPolicyGetMediaFoundationCodecLoading,51 diff --git a/libc/nt/KernelBase/AppPolicyGetProcessTerminationMethod.s b/libc/nt/KernelBase/AppPolicyGetProcessTerminationMethod.s new file mode 100644 index 00000000..8e719afb --- /dev/null +++ b/libc/nt/KernelBase/AppPolicyGetProcessTerminationMethod.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppPolicyGetProcessTerminationMethod,AppPolicyGetProcessTerminationMethod,52 diff --git a/libc/nt/KernelBase/AppPolicyGetShowDeveloperDiagnostic.s b/libc/nt/KernelBase/AppPolicyGetShowDeveloperDiagnostic.s new file mode 100644 index 00000000..fc79f336 --- /dev/null +++ b/libc/nt/KernelBase/AppPolicyGetShowDeveloperDiagnostic.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppPolicyGetShowDeveloperDiagnostic,AppPolicyGetShowDeveloperDiagnostic,53 diff --git a/libc/nt/KernelBase/AppPolicyGetThreadInitializationType.s b/libc/nt/KernelBase/AppPolicyGetThreadInitializationType.s new file mode 100644 index 00000000..18212f7d --- /dev/null +++ b/libc/nt/KernelBase/AppPolicyGetThreadInitializationType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppPolicyGetThreadInitializationType,AppPolicyGetThreadInitializationType,54 diff --git a/libc/nt/KernelBase/AppPolicyGetWindowingModel.s b/libc/nt/KernelBase/AppPolicyGetWindowingModel.s new file mode 100644 index 00000000..b8500da8 --- /dev/null +++ b/libc/nt/KernelBase/AppPolicyGetWindowingModel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppPolicyGetWindowingModel,AppPolicyGetWindowingModel,55 diff --git a/libc/nt/KernelBase/AppXFreeMemory.s b/libc/nt/KernelBase/AppXFreeMemory.s new file mode 100644 index 00000000..04e6acd8 --- /dev/null +++ b/libc/nt/KernelBase/AppXFreeMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppXFreeMemory,AppXFreeMemory,56 diff --git a/libc/nt/KernelBase/AppXGetApplicationData.s b/libc/nt/KernelBase/AppXGetApplicationData.s new file mode 100644 index 00000000..f2b85525 --- /dev/null +++ b/libc/nt/KernelBase/AppXGetApplicationData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppXGetApplicationData,AppXGetApplicationData,57 diff --git a/libc/nt/KernelBase/AppXGetDevelopmentMode.s b/libc/nt/KernelBase/AppXGetDevelopmentMode.s new file mode 100644 index 00000000..9edf379e --- /dev/null +++ b/libc/nt/KernelBase/AppXGetDevelopmentMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppXGetDevelopmentMode,AppXGetDevelopmentMode,58 diff --git a/libc/nt/KernelBase/AppXGetOSMaxVersionTested.s b/libc/nt/KernelBase/AppXGetOSMaxVersionTested.s new file mode 100644 index 00000000..c626a6af --- /dev/null +++ b/libc/nt/KernelBase/AppXGetOSMaxVersionTested.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppXGetOSMaxVersionTested,AppXGetOSMaxVersionTested,59 diff --git a/libc/nt/KernelBase/AppXGetOSMinVersion.s b/libc/nt/KernelBase/AppXGetOSMinVersion.s new file mode 100644 index 00000000..d75fa5d5 --- /dev/null +++ b/libc/nt/KernelBase/AppXGetOSMinVersion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppXGetOSMinVersion,AppXGetOSMinVersion,60 diff --git a/libc/nt/KernelBase/AppXGetPackageCapabilities.s b/libc/nt/KernelBase/AppXGetPackageCapabilities.s new file mode 100644 index 00000000..e74137ec --- /dev/null +++ b/libc/nt/KernelBase/AppXGetPackageCapabilities.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppXGetPackageCapabilities,AppXGetPackageCapabilities,61 diff --git a/libc/nt/KernelBase/AppXGetPackageSid.s b/libc/nt/KernelBase/AppXGetPackageSid.s new file mode 100644 index 00000000..64979705 --- /dev/null +++ b/libc/nt/KernelBase/AppXGetPackageSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppXGetPackageSid,AppXGetPackageSid,62 diff --git a/libc/nt/KernelBase/AppXLookupDisplayName.s b/libc/nt/KernelBase/AppXLookupDisplayName.s new file mode 100644 index 00000000..7f1d7a02 --- /dev/null +++ b/libc/nt/KernelBase/AppXLookupDisplayName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppXLookupDisplayName,AppXLookupDisplayName,63 diff --git a/libc/nt/KernelBase/AppXLookupMoniker.s b/libc/nt/KernelBase/AppXLookupMoniker.s new file mode 100644 index 00000000..bacce283 --- /dev/null +++ b/libc/nt/KernelBase/AppXLookupMoniker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppXLookupMoniker,AppXLookupMoniker,64 diff --git a/libc/nt/KernelBase/AppXPostSuccessExtension.s b/libc/nt/KernelBase/AppXPostSuccessExtension.s new file mode 100644 index 00000000..a20ed499 --- /dev/null +++ b/libc/nt/KernelBase/AppXPostSuccessExtension.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppXPostSuccessExtension,AppXPostSuccessExtension,65 diff --git a/libc/nt/KernelBase/AppXPreCreationExtension.s b/libc/nt/KernelBase/AppXPreCreationExtension.s new file mode 100644 index 00000000..0234ef7a --- /dev/null +++ b/libc/nt/KernelBase/AppXPreCreationExtension.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppXPreCreationExtension,AppXPreCreationExtension,66 diff --git a/libc/nt/KernelBase/AppXReleaseAppXContext.s b/libc/nt/KernelBase/AppXReleaseAppXContext.s new file mode 100644 index 00000000..a9084dec --- /dev/null +++ b/libc/nt/KernelBase/AppXReleaseAppXContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppXReleaseAppXContext,AppXReleaseAppXContext,67 diff --git a/libc/nt/KernelBase/AppXUpdatePackageCapabilities.s b/libc/nt/KernelBase/AppXUpdatePackageCapabilities.s new file mode 100644 index 00000000..ef1206e6 --- /dev/null +++ b/libc/nt/KernelBase/AppXUpdatePackageCapabilities.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AppXUpdatePackageCapabilities,AppXUpdatePackageCapabilities,68 diff --git a/libc/nt/KernelBase/ApplicationUserModelIdFromProductId.s b/libc/nt/KernelBase/ApplicationUserModelIdFromProductId.s new file mode 100644 index 00000000..19094e8f --- /dev/null +++ b/libc/nt/KernelBase/ApplicationUserModelIdFromProductId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ApplicationUserModelIdFromProductId,ApplicationUserModelIdFromProductId,69 diff --git a/libc/nt/KernelBase/AreAllAccessesGranted.s b/libc/nt/KernelBase/AreAllAccessesGranted.s new file mode 100644 index 00000000..cb85d0c9 --- /dev/null +++ b/libc/nt/KernelBase/AreAllAccessesGranted.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AreAllAccessesGranted,AreAllAccessesGranted,70 diff --git a/libc/nt/KernelBase/AreAnyAccessesGranted.s b/libc/nt/KernelBase/AreAnyAccessesGranted.s new file mode 100644 index 00000000..d9dc5506 --- /dev/null +++ b/libc/nt/KernelBase/AreAnyAccessesGranted.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AreAnyAccessesGranted,AreAnyAccessesGranted,71 diff --git a/libc/nt/KernelBase/AreFileApisANSI.s b/libc/nt/KernelBase/AreFileApisANSI.s new file mode 100644 index 00000000..871aeba3 --- /dev/null +++ b/libc/nt/KernelBase/AreFileApisANSI.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AreFileApisANSI,AreFileApisANSI,72 diff --git a/libc/nt/KernelBase/AreThereVisibleLogoffScriptsInternal.s b/libc/nt/KernelBase/AreThereVisibleLogoffScriptsInternal.s new file mode 100644 index 00000000..761150a7 --- /dev/null +++ b/libc/nt/KernelBase/AreThereVisibleLogoffScriptsInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AreThereVisibleLogoffScriptsInternal,AreThereVisibleLogoffScriptsInternal,73 diff --git a/libc/nt/KernelBase/AreThereVisibleShutdownScriptsInternal.s b/libc/nt/KernelBase/AreThereVisibleShutdownScriptsInternal.s new file mode 100644 index 00000000..ae99f808 --- /dev/null +++ b/libc/nt/KernelBase/AreThereVisibleShutdownScriptsInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AreThereVisibleShutdownScriptsInternal,AreThereVisibleShutdownScriptsInternal,74 diff --git a/libc/nt/KernelBase/AttachConsole.s b/libc/nt/KernelBase/AttachConsole.s new file mode 100644 index 00000000..d0ebe256 --- /dev/null +++ b/libc/nt/KernelBase/AttachConsole.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_AttachConsole,AttachConsole,75 + + .text.windows +AttachConsole: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_AttachConsole(%rip) + leave + ret + .endfn AttachConsole,globl + .previous diff --git a/libc/nt/KernelBase/BaseCheckAppcompatCache.s b/libc/nt/KernelBase/BaseCheckAppcompatCache.s new file mode 100644 index 00000000..f702f762 --- /dev/null +++ b/libc/nt/KernelBase/BaseCheckAppcompatCache.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BaseCheckAppcompatCache,BaseCheckAppcompatCache,76 diff --git a/libc/nt/KernelBase/BaseCheckAppcompatCacheEx.s b/libc/nt/KernelBase/BaseCheckAppcompatCacheEx.s new file mode 100644 index 00000000..b6ca33d0 --- /dev/null +++ b/libc/nt/KernelBase/BaseCheckAppcompatCacheEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BaseCheckAppcompatCacheEx,BaseCheckAppcompatCacheEx,77 diff --git a/libc/nt/KernelBase/BaseCleanupAppcompatCacheSupport.s b/libc/nt/KernelBase/BaseCleanupAppcompatCacheSupport.s new file mode 100644 index 00000000..62fdc5c5 --- /dev/null +++ b/libc/nt/KernelBase/BaseCleanupAppcompatCacheSupport.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BaseCleanupAppcompatCacheSupport,BaseCleanupAppcompatCacheSupport,78 diff --git a/libc/nt/KernelBase/BaseDllFreeResourceId.s b/libc/nt/KernelBase/BaseDllFreeResourceId.s new file mode 100644 index 00000000..f281a593 --- /dev/null +++ b/libc/nt/KernelBase/BaseDllFreeResourceId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BaseDllFreeResourceId,BaseDllFreeResourceId,79 diff --git a/libc/nt/KernelBase/BaseDllMapResourceIdW.s b/libc/nt/KernelBase/BaseDllMapResourceIdW.s new file mode 100644 index 00000000..4dadea52 --- /dev/null +++ b/libc/nt/KernelBase/BaseDllMapResourceIdW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BaseDllMapResourceIdW,BaseDllMapResourceIdW,80 diff --git a/libc/nt/KernelBase/BaseDumpAppcompatCache.s b/libc/nt/KernelBase/BaseDumpAppcompatCache.s new file mode 100644 index 00000000..9a0c1c2d --- /dev/null +++ b/libc/nt/KernelBase/BaseDumpAppcompatCache.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BaseDumpAppcompatCache,BaseDumpAppcompatCache,81 diff --git a/libc/nt/KernelBase/BaseFlushAppcompatCache.s b/libc/nt/KernelBase/BaseFlushAppcompatCache.s new file mode 100644 index 00000000..373eea11 --- /dev/null +++ b/libc/nt/KernelBase/BaseFlushAppcompatCache.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BaseFlushAppcompatCache,BaseFlushAppcompatCache,82 diff --git a/libc/nt/KernelBase/BaseFormatObjectAttributes.s b/libc/nt/KernelBase/BaseFormatObjectAttributes.s new file mode 100644 index 00000000..2715592c --- /dev/null +++ b/libc/nt/KernelBase/BaseFormatObjectAttributes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BaseFormatObjectAttributes,BaseFormatObjectAttributes,83 diff --git a/libc/nt/KernelBase/BaseFreeAppCompatDataForProcess.s b/libc/nt/KernelBase/BaseFreeAppCompatDataForProcess.s new file mode 100644 index 00000000..23d59f8c --- /dev/null +++ b/libc/nt/KernelBase/BaseFreeAppCompatDataForProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BaseFreeAppCompatDataForProcess,BaseFreeAppCompatDataForProcess,84 diff --git a/libc/nt/KernelBase/BaseGetConsoleReference.s b/libc/nt/KernelBase/BaseGetConsoleReference.s new file mode 100644 index 00000000..41c4118a --- /dev/null +++ b/libc/nt/KernelBase/BaseGetConsoleReference.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BaseGetConsoleReference,BaseGetConsoleReference,85 diff --git a/libc/nt/KernelBase/BaseGetNamedObjectDirectory.s b/libc/nt/KernelBase/BaseGetNamedObjectDirectory.s new file mode 100644 index 00000000..7dca1d15 --- /dev/null +++ b/libc/nt/KernelBase/BaseGetNamedObjectDirectory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BaseGetNamedObjectDirectory,BaseGetNamedObjectDirectory,86 diff --git a/libc/nt/KernelBase/BaseInitAppcompatCacheSupport.s b/libc/nt/KernelBase/BaseInitAppcompatCacheSupport.s new file mode 100644 index 00000000..9d31dcd3 --- /dev/null +++ b/libc/nt/KernelBase/BaseInitAppcompatCacheSupport.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BaseInitAppcompatCacheSupport,BaseInitAppcompatCacheSupport,87 diff --git a/libc/nt/KernelBase/BaseIsAppcompatInfrastructureDisabled.s b/libc/nt/KernelBase/BaseIsAppcompatInfrastructureDisabled.s new file mode 100644 index 00000000..d04d571e --- /dev/null +++ b/libc/nt/KernelBase/BaseIsAppcompatInfrastructureDisabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BaseIsAppcompatInfrastructureDisabled,BaseIsAppcompatInfrastructureDisabled,88 diff --git a/libc/nt/KernelBase/BaseMarkFileForDelete.s b/libc/nt/KernelBase/BaseMarkFileForDelete.s new file mode 100644 index 00000000..522afbaf --- /dev/null +++ b/libc/nt/KernelBase/BaseMarkFileForDelete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BaseMarkFileForDelete,BaseMarkFileForDelete,89 diff --git a/libc/nt/KernelBase/BaseReadAppCompatDataForProcess.s b/libc/nt/KernelBase/BaseReadAppCompatDataForProcess.s new file mode 100644 index 00000000..76deb482 --- /dev/null +++ b/libc/nt/KernelBase/BaseReadAppCompatDataForProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BaseReadAppCompatDataForProcess,BaseReadAppCompatDataForProcess,90 diff --git a/libc/nt/KernelBase/BaseUpdateAppcompatCache.s b/libc/nt/KernelBase/BaseUpdateAppcompatCache.s new file mode 100644 index 00000000..be104534 --- /dev/null +++ b/libc/nt/KernelBase/BaseUpdateAppcompatCache.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BaseUpdateAppcompatCache,BaseUpdateAppcompatCache,91 diff --git a/libc/nt/KernelBase/BasepAdjustObjectAttributesForPrivateNamespace.s b/libc/nt/KernelBase/BasepAdjustObjectAttributesForPrivateNamespace.s new file mode 100644 index 00000000..22c4ad02 --- /dev/null +++ b/libc/nt/KernelBase/BasepAdjustObjectAttributesForPrivateNamespace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BasepAdjustObjectAttributesForPrivateNamespace,BasepAdjustObjectAttributesForPrivateNamespace,92 diff --git a/libc/nt/KernelBase/BasepCopyFileCallback.s b/libc/nt/KernelBase/BasepCopyFileCallback.s new file mode 100644 index 00000000..c8aa7a9c --- /dev/null +++ b/libc/nt/KernelBase/BasepCopyFileCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BasepCopyFileCallback,BasepCopyFileCallback,93 diff --git a/libc/nt/KernelBase/BasepCopyFileExW.s b/libc/nt/KernelBase/BasepCopyFileExW.s new file mode 100644 index 00000000..459cd096 --- /dev/null +++ b/libc/nt/KernelBase/BasepCopyFileExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BasepCopyFileExW,BasepCopyFileExW,94 diff --git a/libc/nt/KernelBase/BasepNotifyTrackingService.s b/libc/nt/KernelBase/BasepNotifyTrackingService.s new file mode 100644 index 00000000..9743b645 --- /dev/null +++ b/libc/nt/KernelBase/BasepNotifyTrackingService.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_BasepNotifyTrackingService,BasepNotifyTrackingService,95 diff --git a/libc/nt/KernelBase/Beep.s b/libc/nt/KernelBase/Beep.s new file mode 100644 index 00000000..f0796586 --- /dev/null +++ b/libc/nt/KernelBase/Beep.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_Beep,Beep,96 diff --git a/libc/nt/KernelBase/CLOSE_LOCAL_HANDLE_INTERNAL.s b/libc/nt/KernelBase/CLOSE_LOCAL_HANDLE_INTERNAL.s new file mode 100644 index 00000000..45a28e5c --- /dev/null +++ b/libc/nt/KernelBase/CLOSE_LOCAL_HANDLE_INTERNAL.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CLOSE_LOCAL_HANDLE_INTERNAL,CLOSE_LOCAL_HANDLE_INTERNAL,97 diff --git a/libc/nt/KernelBase/CallEnclave.s b/libc/nt/KernelBase/CallEnclave.s new file mode 100644 index 00000000..7d89d40f --- /dev/null +++ b/libc/nt/KernelBase/CallEnclave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CallEnclave,CallEnclave,98 diff --git a/libc/nt/KernelBase/CallNamedPipeW.s b/libc/nt/KernelBase/CallNamedPipeW.s new file mode 100644 index 00000000..2ecd4fbd --- /dev/null +++ b/libc/nt/KernelBase/CallNamedPipeW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CallNamedPipeW,CallNamedPipeW,99 + + .text.windows +CallNamedPipe: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CallNamedPipeW(%rip),%rax + jmp __sysv2nt8 + .endfn CallNamedPipe,globl + .previous diff --git a/libc/nt/KernelBase/CallbackMayRunLong.s b/libc/nt/KernelBase/CallbackMayRunLong.s new file mode 100644 index 00000000..ba5bb3c5 --- /dev/null +++ b/libc/nt/KernelBase/CallbackMayRunLong.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CallbackMayRunLong,CallbackMayRunLong,100 diff --git a/libc/nt/KernelBase/CancelIo.s b/libc/nt/KernelBase/CancelIo.s new file mode 100644 index 00000000..ca6db4cf --- /dev/null +++ b/libc/nt/KernelBase/CancelIo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CancelIo,CancelIo,101 diff --git a/libc/nt/KernelBase/CancelIoEx.s b/libc/nt/KernelBase/CancelIoEx.s new file mode 100644 index 00000000..b1f1dff9 --- /dev/null +++ b/libc/nt/KernelBase/CancelIoEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CancelIoEx,CancelIoEx,102 diff --git a/libc/nt/KernelBase/CancelSynchronousIo.s b/libc/nt/KernelBase/CancelSynchronousIo.s new file mode 100644 index 00000000..ee949b11 --- /dev/null +++ b/libc/nt/KernelBase/CancelSynchronousIo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CancelSynchronousIo,CancelSynchronousIo,103 diff --git a/libc/nt/KernelBase/CancelWaitableTimer.s b/libc/nt/KernelBase/CancelWaitableTimer.s new file mode 100644 index 00000000..138b1e37 --- /dev/null +++ b/libc/nt/KernelBase/CancelWaitableTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CancelWaitableTimer,CancelWaitableTimer,105 diff --git a/libc/nt/KernelBase/CeipIsOptedIn.s b/libc/nt/KernelBase/CeipIsOptedIn.s new file mode 100644 index 00000000..8791dcad --- /dev/null +++ b/libc/nt/KernelBase/CeipIsOptedIn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CeipIsOptedIn,CeipIsOptedIn,106 diff --git a/libc/nt/KernelBase/ChangeTimerQueueTimer.s b/libc/nt/KernelBase/ChangeTimerQueueTimer.s new file mode 100644 index 00000000..1de86cee --- /dev/null +++ b/libc/nt/KernelBase/ChangeTimerQueueTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ChangeTimerQueueTimer,ChangeTimerQueueTimer,107 diff --git a/libc/nt/KernelBase/CharLowerA.s b/libc/nt/KernelBase/CharLowerA.s new file mode 100644 index 00000000..68c9e1f7 --- /dev/null +++ b/libc/nt/KernelBase/CharLowerA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CharLowerA,CharLowerA,108 diff --git a/libc/nt/KernelBase/CharLowerBuffA.s b/libc/nt/KernelBase/CharLowerBuffA.s new file mode 100644 index 00000000..280e5fb7 --- /dev/null +++ b/libc/nt/KernelBase/CharLowerBuffA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CharLowerBuffA,CharLowerBuffA,109 diff --git a/libc/nt/KernelBase/CharLowerBuffW.s b/libc/nt/KernelBase/CharLowerBuffW.s new file mode 100644 index 00000000..a6c01fb5 --- /dev/null +++ b/libc/nt/KernelBase/CharLowerBuffW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CharLowerBuffW,CharLowerBuffW,110 diff --git a/libc/nt/KernelBase/CharLowerW.s b/libc/nt/KernelBase/CharLowerW.s new file mode 100644 index 00000000..5e899a48 --- /dev/null +++ b/libc/nt/KernelBase/CharLowerW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CharLowerW,CharLowerW,111 diff --git a/libc/nt/KernelBase/CharNextA.s b/libc/nt/KernelBase/CharNextA.s new file mode 100644 index 00000000..66fa9250 --- /dev/null +++ b/libc/nt/KernelBase/CharNextA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CharNextA,CharNextA,112 diff --git a/libc/nt/KernelBase/CharNextExA.s b/libc/nt/KernelBase/CharNextExA.s new file mode 100644 index 00000000..c9ac7872 --- /dev/null +++ b/libc/nt/KernelBase/CharNextExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CharNextExA,CharNextExA,113 diff --git a/libc/nt/KernelBase/CharNextW.s b/libc/nt/KernelBase/CharNextW.s new file mode 100644 index 00000000..2cc3e4cd --- /dev/null +++ b/libc/nt/KernelBase/CharNextW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CharNextW,CharNextW,114 diff --git a/libc/nt/KernelBase/CharPrevA.s b/libc/nt/KernelBase/CharPrevA.s new file mode 100644 index 00000000..d7b654c2 --- /dev/null +++ b/libc/nt/KernelBase/CharPrevA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CharPrevA,CharPrevA,115 diff --git a/libc/nt/KernelBase/CharPrevExA.s b/libc/nt/KernelBase/CharPrevExA.s new file mode 100644 index 00000000..898633c9 --- /dev/null +++ b/libc/nt/KernelBase/CharPrevExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CharPrevExA,CharPrevExA,116 diff --git a/libc/nt/KernelBase/CharPrevW.s b/libc/nt/KernelBase/CharPrevW.s new file mode 100644 index 00000000..b15ef71b --- /dev/null +++ b/libc/nt/KernelBase/CharPrevW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CharPrevW,CharPrevW,117 diff --git a/libc/nt/KernelBase/CharUpperA.s b/libc/nt/KernelBase/CharUpperA.s new file mode 100644 index 00000000..4e4afedb --- /dev/null +++ b/libc/nt/KernelBase/CharUpperA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CharUpperA,CharUpperA,118 diff --git a/libc/nt/KernelBase/CharUpperBuffA.s b/libc/nt/KernelBase/CharUpperBuffA.s new file mode 100644 index 00000000..3b412802 --- /dev/null +++ b/libc/nt/KernelBase/CharUpperBuffA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CharUpperBuffA,CharUpperBuffA,119 diff --git a/libc/nt/KernelBase/CharUpperBuffW.s b/libc/nt/KernelBase/CharUpperBuffW.s new file mode 100644 index 00000000..aa649e6c --- /dev/null +++ b/libc/nt/KernelBase/CharUpperBuffW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CharUpperBuffW,CharUpperBuffW,120 diff --git a/libc/nt/KernelBase/CharUpperW.s b/libc/nt/KernelBase/CharUpperW.s new file mode 100644 index 00000000..ecf2234b --- /dev/null +++ b/libc/nt/KernelBase/CharUpperW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CharUpperW,CharUpperW,121 diff --git a/libc/nt/KernelBase/CheckAllowDecryptedRemoteDestinationPolicy.s b/libc/nt/KernelBase/CheckAllowDecryptedRemoteDestinationPolicy.s new file mode 100644 index 00000000..449d79e9 --- /dev/null +++ b/libc/nt/KernelBase/CheckAllowDecryptedRemoteDestinationPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CheckAllowDecryptedRemoteDestinationPolicy,CheckAllowDecryptedRemoteDestinationPolicy,122 diff --git a/libc/nt/KernelBase/CheckGroupPolicyEnabled.s b/libc/nt/KernelBase/CheckGroupPolicyEnabled.s new file mode 100644 index 00000000..7785e885 --- /dev/null +++ b/libc/nt/KernelBase/CheckGroupPolicyEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CheckGroupPolicyEnabled,CheckGroupPolicyEnabled,123 diff --git a/libc/nt/KernelBase/CheckIfStateChangeNotificationExists.s b/libc/nt/KernelBase/CheckIfStateChangeNotificationExists.s new file mode 100644 index 00000000..97093785 --- /dev/null +++ b/libc/nt/KernelBase/CheckIfStateChangeNotificationExists.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CheckIfStateChangeNotificationExists,CheckIfStateChangeNotificationExists,124 diff --git a/libc/nt/KernelBase/CheckRemoteDebuggerPresent.s b/libc/nt/KernelBase/CheckRemoteDebuggerPresent.s new file mode 100644 index 00000000..00d349ee --- /dev/null +++ b/libc/nt/KernelBase/CheckRemoteDebuggerPresent.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CheckRemoteDebuggerPresent,CheckRemoteDebuggerPresent,125 + + .text.windows +CheckRemoteDebuggerPresent: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CheckRemoteDebuggerPresent(%rip),%rax + jmp __sysv2nt + .endfn CheckRemoteDebuggerPresent,globl + .previous diff --git a/libc/nt/KernelBase/CheckTokenCapability.s b/libc/nt/KernelBase/CheckTokenCapability.s new file mode 100644 index 00000000..2d28b161 --- /dev/null +++ b/libc/nt/KernelBase/CheckTokenCapability.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CheckTokenCapability,CheckTokenCapability,126 diff --git a/libc/nt/KernelBase/CheckTokenMembership.s b/libc/nt/KernelBase/CheckTokenMembership.s new file mode 100644 index 00000000..0d450aef --- /dev/null +++ b/libc/nt/KernelBase/CheckTokenMembership.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CheckTokenMembership,CheckTokenMembership,127 diff --git a/libc/nt/KernelBase/CheckTokenMembershipEx.s b/libc/nt/KernelBase/CheckTokenMembershipEx.s new file mode 100644 index 00000000..e0c58a76 --- /dev/null +++ b/libc/nt/KernelBase/CheckTokenMembershipEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CheckTokenMembershipEx,CheckTokenMembershipEx,128 diff --git a/libc/nt/KernelBase/ChrCmpIA.s b/libc/nt/KernelBase/ChrCmpIA.s new file mode 100644 index 00000000..1ecdd330 --- /dev/null +++ b/libc/nt/KernelBase/ChrCmpIA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ChrCmpIA,ChrCmpIA,129 diff --git a/libc/nt/KernelBase/ChrCmpIW.s b/libc/nt/KernelBase/ChrCmpIW.s new file mode 100644 index 00000000..2c967418 --- /dev/null +++ b/libc/nt/KernelBase/ChrCmpIW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ChrCmpIW,ChrCmpIW,130 diff --git a/libc/nt/KernelBase/ClearCommBreak.s b/libc/nt/KernelBase/ClearCommBreak.s new file mode 100644 index 00000000..fa149491 --- /dev/null +++ b/libc/nt/KernelBase/ClearCommBreak.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ClearCommBreak,ClearCommBreak,131 diff --git a/libc/nt/KernelBase/ClearCommError.s b/libc/nt/KernelBase/ClearCommError.s new file mode 100644 index 00000000..e57f7c5b --- /dev/null +++ b/libc/nt/KernelBase/ClearCommError.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ClearCommError,ClearCommError,132 diff --git a/libc/nt/KernelBase/CloseGlobalizationUserSettingsKey.s b/libc/nt/KernelBase/CloseGlobalizationUserSettingsKey.s new file mode 100644 index 00000000..4d987ca4 --- /dev/null +++ b/libc/nt/KernelBase/CloseGlobalizationUserSettingsKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CloseGlobalizationUserSettingsKey,CloseGlobalizationUserSettingsKey,133 diff --git a/libc/nt/KernelBase/CloseHandle.s b/libc/nt/KernelBase/CloseHandle.s new file mode 100644 index 00000000..624c8f44 --- /dev/null +++ b/libc/nt/KernelBase/CloseHandle.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CloseHandle,CloseHandle,134 + + .text.windows +CloseHandle: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_CloseHandle(%rip) + leave + ret + .endfn CloseHandle,globl + .previous diff --git a/libc/nt/KernelBase/ClosePackageInfo.s b/libc/nt/KernelBase/ClosePackageInfo.s new file mode 100644 index 00000000..14cacdec --- /dev/null +++ b/libc/nt/KernelBase/ClosePackageInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ClosePackageInfo,ClosePackageInfo,135 diff --git a/libc/nt/KernelBase/ClosePrivateNamespace.s b/libc/nt/KernelBase/ClosePrivateNamespace.s new file mode 100644 index 00000000..e6f9de24 --- /dev/null +++ b/libc/nt/KernelBase/ClosePrivateNamespace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ClosePrivateNamespace,ClosePrivateNamespace,136 diff --git a/libc/nt/KernelBase/CloseState.s b/libc/nt/KernelBase/CloseState.s new file mode 100644 index 00000000..540b9c6f --- /dev/null +++ b/libc/nt/KernelBase/CloseState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CloseState,CloseState,137 diff --git a/libc/nt/KernelBase/CloseStateAtom.s b/libc/nt/KernelBase/CloseStateAtom.s new file mode 100644 index 00000000..17fb216e --- /dev/null +++ b/libc/nt/KernelBase/CloseStateAtom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CloseStateAtom,CloseStateAtom,138 diff --git a/libc/nt/KernelBase/CloseStateChangeNotification.s b/libc/nt/KernelBase/CloseStateChangeNotification.s new file mode 100644 index 00000000..59cf4c8d --- /dev/null +++ b/libc/nt/KernelBase/CloseStateChangeNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CloseStateChangeNotification,CloseStateChangeNotification,139 diff --git a/libc/nt/KernelBase/CloseStateContainer.s b/libc/nt/KernelBase/CloseStateContainer.s new file mode 100644 index 00000000..db48fffe --- /dev/null +++ b/libc/nt/KernelBase/CloseStateContainer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CloseStateContainer,CloseStateContainer,140 diff --git a/libc/nt/KernelBase/CloseStateLock.s b/libc/nt/KernelBase/CloseStateLock.s new file mode 100644 index 00000000..ff9e3e5b --- /dev/null +++ b/libc/nt/KernelBase/CloseStateLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CloseStateLock,CloseStateLock,141 diff --git a/libc/nt/KernelBase/CommitStateAtom.s b/libc/nt/KernelBase/CommitStateAtom.s new file mode 100644 index 00000000..595bcbc8 --- /dev/null +++ b/libc/nt/KernelBase/CommitStateAtom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CommitStateAtom,CommitStateAtom,149 diff --git a/libc/nt/KernelBase/CompareFileTime.s b/libc/nt/KernelBase/CompareFileTime.s new file mode 100644 index 00000000..c4a996cc --- /dev/null +++ b/libc/nt/KernelBase/CompareFileTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CompareFileTime,CompareFileTime,150 diff --git a/libc/nt/KernelBase/CompareObjectHandles.s b/libc/nt/KernelBase/CompareObjectHandles.s new file mode 100644 index 00000000..228c883c --- /dev/null +++ b/libc/nt/KernelBase/CompareObjectHandles.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CompareObjectHandles,CompareObjectHandles,151 diff --git a/libc/nt/KernelBase/CompareStringA.s b/libc/nt/KernelBase/CompareStringA.s new file mode 100644 index 00000000..2d27a9b6 --- /dev/null +++ b/libc/nt/KernelBase/CompareStringA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CompareStringA,CompareStringA,152 diff --git a/libc/nt/KernelBase/CompareStringEx.s b/libc/nt/KernelBase/CompareStringEx.s new file mode 100644 index 00000000..9b70a070 --- /dev/null +++ b/libc/nt/KernelBase/CompareStringEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CompareStringEx,CompareStringEx,153 diff --git a/libc/nt/KernelBase/CompareStringOrdinal.s b/libc/nt/KernelBase/CompareStringOrdinal.s new file mode 100644 index 00000000..9fb3c4f9 --- /dev/null +++ b/libc/nt/KernelBase/CompareStringOrdinal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CompareStringOrdinal,CompareStringOrdinal,154 diff --git a/libc/nt/KernelBase/CompareStringW.s b/libc/nt/KernelBase/CompareStringW.s new file mode 100644 index 00000000..3c69cc43 --- /dev/null +++ b/libc/nt/KernelBase/CompareStringW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CompareStringW,CompareStringW,155 diff --git a/libc/nt/KernelBase/ConnectNamedPipe.s b/libc/nt/KernelBase/ConnectNamedPipe.s new file mode 100644 index 00000000..37dd456a --- /dev/null +++ b/libc/nt/KernelBase/ConnectNamedPipe.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ConnectNamedPipe,ConnectNamedPipe,156 + + .text.windows +ConnectNamedPipe: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ConnectNamedPipe(%rip),%rax + jmp __sysv2nt + .endfn ConnectNamedPipe,globl + .previous diff --git a/libc/nt/KernelBase/ContinueDebugEvent.s b/libc/nt/KernelBase/ContinueDebugEvent.s new file mode 100644 index 00000000..177b40f0 --- /dev/null +++ b/libc/nt/KernelBase/ContinueDebugEvent.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ContinueDebugEvent,ContinueDebugEvent,157 + + .text.windows +ContinueDebugEvent: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ContinueDebugEvent(%rip),%rax + jmp __sysv2nt + .endfn ContinueDebugEvent,globl + .previous diff --git a/libc/nt/KernelBase/ConvertAuxiliaryCounterToPerformanceCounter.s b/libc/nt/KernelBase/ConvertAuxiliaryCounterToPerformanceCounter.s new file mode 100644 index 00000000..73ca792f --- /dev/null +++ b/libc/nt/KernelBase/ConvertAuxiliaryCounterToPerformanceCounter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ConvertAuxiliaryCounterToPerformanceCounter,ConvertAuxiliaryCounterToPerformanceCounter,158 diff --git a/libc/nt/KernelBase/ConvertDefaultLocale.s b/libc/nt/KernelBase/ConvertDefaultLocale.s new file mode 100644 index 00000000..2fe61402 --- /dev/null +++ b/libc/nt/KernelBase/ConvertDefaultLocale.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ConvertDefaultLocale,ConvertDefaultLocale,159 diff --git a/libc/nt/KernelBase/ConvertFiberToThread.s b/libc/nt/KernelBase/ConvertFiberToThread.s new file mode 100644 index 00000000..39a1030f --- /dev/null +++ b/libc/nt/KernelBase/ConvertFiberToThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ConvertFiberToThread,ConvertFiberToThread,160 diff --git a/libc/nt/KernelBase/ConvertPerformanceCounterToAuxiliaryCounter.s b/libc/nt/KernelBase/ConvertPerformanceCounterToAuxiliaryCounter.s new file mode 100644 index 00000000..d3bae779 --- /dev/null +++ b/libc/nt/KernelBase/ConvertPerformanceCounterToAuxiliaryCounter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ConvertPerformanceCounterToAuxiliaryCounter,ConvertPerformanceCounterToAuxiliaryCounter,161 diff --git a/libc/nt/KernelBase/ConvertThreadToFiber.s b/libc/nt/KernelBase/ConvertThreadToFiber.s new file mode 100644 index 00000000..3b4f6890 --- /dev/null +++ b/libc/nt/KernelBase/ConvertThreadToFiber.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ConvertThreadToFiber,ConvertThreadToFiber,162 diff --git a/libc/nt/KernelBase/ConvertThreadToFiberEx.s b/libc/nt/KernelBase/ConvertThreadToFiberEx.s new file mode 100644 index 00000000..1436906d --- /dev/null +++ b/libc/nt/KernelBase/ConvertThreadToFiberEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ConvertThreadToFiberEx,ConvertThreadToFiberEx,163 diff --git a/libc/nt/KernelBase/ConvertToAutoInheritPrivateObjectSecurity.s b/libc/nt/KernelBase/ConvertToAutoInheritPrivateObjectSecurity.s new file mode 100644 index 00000000..aee309f9 --- /dev/null +++ b/libc/nt/KernelBase/ConvertToAutoInheritPrivateObjectSecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ConvertToAutoInheritPrivateObjectSecurity,ConvertToAutoInheritPrivateObjectSecurity,164 diff --git a/libc/nt/KernelBase/CopyContext.s b/libc/nt/KernelBase/CopyContext.s new file mode 100644 index 00000000..57e5fbbe --- /dev/null +++ b/libc/nt/KernelBase/CopyContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CopyContext,CopyContext,165 diff --git a/libc/nt/KernelBase/CopyFile2.s b/libc/nt/KernelBase/CopyFile2.s new file mode 100644 index 00000000..65192d8f --- /dev/null +++ b/libc/nt/KernelBase/CopyFile2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CopyFile2,CopyFile2,166 diff --git a/libc/nt/KernelBase/CopyFileExW.s b/libc/nt/KernelBase/CopyFileExW.s new file mode 100644 index 00000000..15316874 --- /dev/null +++ b/libc/nt/KernelBase/CopyFileExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CopyFileExW,CopyFileExW,167 diff --git a/libc/nt/KernelBase/CopyFileW.s b/libc/nt/KernelBase/CopyFileW.s new file mode 100644 index 00000000..2cc0e26e --- /dev/null +++ b/libc/nt/KernelBase/CopyFileW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CopyFileW,CopyFileW,168 + + .text.windows +CopyFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CopyFileW(%rip),%rax + jmp __sysv2nt + .endfn CopyFile,globl + .previous diff --git a/libc/nt/KernelBase/CopySid.s b/libc/nt/KernelBase/CopySid.s new file mode 100644 index 00000000..f8275722 --- /dev/null +++ b/libc/nt/KernelBase/CopySid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CopySid,CopySid,170 diff --git a/libc/nt/KernelBase/CouldMultiUserAppsBehaviorBePossibleForPackage.s b/libc/nt/KernelBase/CouldMultiUserAppsBehaviorBePossibleForPackage.s new file mode 100644 index 00000000..95bea41d --- /dev/null +++ b/libc/nt/KernelBase/CouldMultiUserAppsBehaviorBePossibleForPackage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CouldMultiUserAppsBehaviorBePossibleForPackage,CouldMultiUserAppsBehaviorBePossibleForPackage,171 diff --git a/libc/nt/KernelBase/CreateActCtxW.s b/libc/nt/KernelBase/CreateActCtxW.s new file mode 100644 index 00000000..f5b8e0b6 --- /dev/null +++ b/libc/nt/KernelBase/CreateActCtxW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateActCtxW,CreateActCtxW,172 diff --git a/libc/nt/KernelBase/CreateAppContainerToken.s b/libc/nt/KernelBase/CreateAppContainerToken.s new file mode 100644 index 00000000..d6ea7538 --- /dev/null +++ b/libc/nt/KernelBase/CreateAppContainerToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateAppContainerToken,CreateAppContainerToken,173 diff --git a/libc/nt/KernelBase/CreateAppContainerTokenForUser.s b/libc/nt/KernelBase/CreateAppContainerTokenForUser.s new file mode 100644 index 00000000..2d8ef8f0 --- /dev/null +++ b/libc/nt/KernelBase/CreateAppContainerTokenForUser.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateAppContainerTokenForUser,CreateAppContainerTokenForUser,174 diff --git a/libc/nt/KernelBase/CreateBoundaryDescriptorW.s b/libc/nt/KernelBase/CreateBoundaryDescriptorW.s new file mode 100644 index 00000000..347f950c --- /dev/null +++ b/libc/nt/KernelBase/CreateBoundaryDescriptorW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateBoundaryDescriptorW,CreateBoundaryDescriptorW,175 diff --git a/libc/nt/KernelBase/CreateConsoleScreenBuffer.s b/libc/nt/KernelBase/CreateConsoleScreenBuffer.s new file mode 100644 index 00000000..788f53e8 --- /dev/null +++ b/libc/nt/KernelBase/CreateConsoleScreenBuffer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateConsoleScreenBuffer,CreateConsoleScreenBuffer,176 diff --git a/libc/nt/KernelBase/CreateDirectoryA.s b/libc/nt/KernelBase/CreateDirectoryA.s new file mode 100644 index 00000000..df36ef53 --- /dev/null +++ b/libc/nt/KernelBase/CreateDirectoryA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateDirectoryA,CreateDirectoryA,177 + + .text.windows +CreateDirectoryA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateDirectoryA(%rip),%rax + jmp __sysv2nt + .endfn CreateDirectoryA,globl + .previous diff --git a/libc/nt/KernelBase/CreateDirectoryExW.s b/libc/nt/KernelBase/CreateDirectoryExW.s new file mode 100644 index 00000000..dcd467b4 --- /dev/null +++ b/libc/nt/KernelBase/CreateDirectoryExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateDirectoryExW,CreateDirectoryExW,178 diff --git a/libc/nt/KernelBase/CreateDirectoryW.s b/libc/nt/KernelBase/CreateDirectoryW.s new file mode 100644 index 00000000..67a7faed --- /dev/null +++ b/libc/nt/KernelBase/CreateDirectoryW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateDirectoryW,CreateDirectoryW,179 + + .text.windows +CreateDirectory: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateDirectoryW(%rip),%rax + jmp __sysv2nt + .endfn CreateDirectory,globl + .previous diff --git a/libc/nt/KernelBase/CreateEnclave.s b/libc/nt/KernelBase/CreateEnclave.s new file mode 100644 index 00000000..6e9c5263 --- /dev/null +++ b/libc/nt/KernelBase/CreateEnclave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateEnclave,CreateEnclave,180 diff --git a/libc/nt/KernelBase/CreateEventA.s b/libc/nt/KernelBase/CreateEventA.s new file mode 100644 index 00000000..e6b9fa77 --- /dev/null +++ b/libc/nt/KernelBase/CreateEventA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateEventA,CreateEventA,181 diff --git a/libc/nt/KernelBase/CreateEventExA.s b/libc/nt/KernelBase/CreateEventExA.s new file mode 100644 index 00000000..c0d1481f --- /dev/null +++ b/libc/nt/KernelBase/CreateEventExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateEventExA,CreateEventExA,182 diff --git a/libc/nt/KernelBase/CreateEventExW.s b/libc/nt/KernelBase/CreateEventExW.s new file mode 100644 index 00000000..c8942c01 --- /dev/null +++ b/libc/nt/KernelBase/CreateEventExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateEventExW,CreateEventExW,183 diff --git a/libc/nt/KernelBase/CreateEventW.s b/libc/nt/KernelBase/CreateEventW.s new file mode 100644 index 00000000..6befbc29 --- /dev/null +++ b/libc/nt/KernelBase/CreateEventW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateEventW,CreateEventW,184 diff --git a/libc/nt/KernelBase/CreateFiber.s b/libc/nt/KernelBase/CreateFiber.s new file mode 100644 index 00000000..2e2846d1 --- /dev/null +++ b/libc/nt/KernelBase/CreateFiber.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateFiber,CreateFiber,185 diff --git a/libc/nt/KernelBase/CreateFiberEx.s b/libc/nt/KernelBase/CreateFiberEx.s new file mode 100644 index 00000000..e71281da --- /dev/null +++ b/libc/nt/KernelBase/CreateFiberEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateFiberEx,CreateFiberEx,186 diff --git a/libc/nt/KernelBase/CreateFile2.s b/libc/nt/KernelBase/CreateFile2.s new file mode 100644 index 00000000..b5083dd4 --- /dev/null +++ b/libc/nt/KernelBase/CreateFile2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateFile2,CreateFile2,187 diff --git a/libc/nt/KernelBase/CreateFileA.s b/libc/nt/KernelBase/CreateFileA.s new file mode 100644 index 00000000..87665e5e --- /dev/null +++ b/libc/nt/KernelBase/CreateFileA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateFileA,CreateFileA,188 + + .text.windows +CreateFileA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateFileA(%rip),%rax + jmp __sysv2nt8 + .endfn CreateFileA,globl + .previous diff --git a/libc/nt/KernelBase/CreateFileMappingFromApp.s b/libc/nt/KernelBase/CreateFileMappingFromApp.s new file mode 100644 index 00000000..dfe5d64c --- /dev/null +++ b/libc/nt/KernelBase/CreateFileMappingFromApp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateFileMappingFromApp,CreateFileMappingFromApp,189 diff --git a/libc/nt/KernelBase/CreateFileMappingNumaW.s b/libc/nt/KernelBase/CreateFileMappingNumaW.s new file mode 100644 index 00000000..0252f9f4 --- /dev/null +++ b/libc/nt/KernelBase/CreateFileMappingNumaW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateFileMappingNumaW,CreateFileMappingNumaW,190 + + .text.windows +CreateFileMappingNuma: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateFileMappingNumaW(%rip),%rax + jmp __sysv2nt8 + .endfn CreateFileMappingNuma,globl + .previous diff --git a/libc/nt/KernelBase/CreateFileMappingW.s b/libc/nt/KernelBase/CreateFileMappingW.s new file mode 100644 index 00000000..554dfdac --- /dev/null +++ b/libc/nt/KernelBase/CreateFileMappingW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateFileMappingW,CreateFileMappingW,191 + + .text.windows +CreateFileMapping: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateFileMappingW(%rip),%rax + jmp __sysv2nt8 + .endfn CreateFileMapping,globl + .previous diff --git a/libc/nt/KernelBase/CreateFileW.s b/libc/nt/KernelBase/CreateFileW.s new file mode 100644 index 00000000..0806223e --- /dev/null +++ b/libc/nt/KernelBase/CreateFileW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateFileW,CreateFileW,192 + + .text.windows +CreateFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateFileW(%rip),%rax + jmp __sysv2nt8 + .endfn CreateFile,globl + .previous diff --git a/libc/nt/KernelBase/CreateHardLinkA.s b/libc/nt/KernelBase/CreateHardLinkA.s new file mode 100644 index 00000000..9e2bea03 --- /dev/null +++ b/libc/nt/KernelBase/CreateHardLinkA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateHardLinkA,CreateHardLinkA,193 + + .text.windows +CreateHardLinkA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateHardLinkA(%rip),%rax + jmp __sysv2nt + .endfn CreateHardLinkA,globl + .previous diff --git a/libc/nt/KernelBase/CreateHardLinkW.s b/libc/nt/KernelBase/CreateHardLinkW.s new file mode 100644 index 00000000..ffe4191e --- /dev/null +++ b/libc/nt/KernelBase/CreateHardLinkW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateHardLinkW,CreateHardLinkW,194 + + .text.windows +CreateHardLink: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateHardLinkW(%rip),%rax + jmp __sysv2nt + .endfn CreateHardLink,globl + .previous diff --git a/libc/nt/KernelBase/CreateIoCompletionPort.s b/libc/nt/KernelBase/CreateIoCompletionPort.s new file mode 100644 index 00000000..0115b474 --- /dev/null +++ b/libc/nt/KernelBase/CreateIoCompletionPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateIoCompletionPort,CreateIoCompletionPort,195 diff --git a/libc/nt/KernelBase/CreateMemoryResourceNotification.s b/libc/nt/KernelBase/CreateMemoryResourceNotification.s new file mode 100644 index 00000000..309d5eef --- /dev/null +++ b/libc/nt/KernelBase/CreateMemoryResourceNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateMemoryResourceNotification,CreateMemoryResourceNotification,196 diff --git a/libc/nt/KernelBase/CreateMutexA.s b/libc/nt/KernelBase/CreateMutexA.s new file mode 100644 index 00000000..1679a5c3 --- /dev/null +++ b/libc/nt/KernelBase/CreateMutexA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateMutexA,CreateMutexA,197 diff --git a/libc/nt/KernelBase/CreateMutexExA.s b/libc/nt/KernelBase/CreateMutexExA.s new file mode 100644 index 00000000..d4765366 --- /dev/null +++ b/libc/nt/KernelBase/CreateMutexExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateMutexExA,CreateMutexExA,198 diff --git a/libc/nt/KernelBase/CreateMutexExW.s b/libc/nt/KernelBase/CreateMutexExW.s new file mode 100644 index 00000000..b58e5bb0 --- /dev/null +++ b/libc/nt/KernelBase/CreateMutexExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateMutexExW,CreateMutexExW,199 diff --git a/libc/nt/KernelBase/CreateMutexW.s b/libc/nt/KernelBase/CreateMutexW.s new file mode 100644 index 00000000..14589b39 --- /dev/null +++ b/libc/nt/KernelBase/CreateMutexW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateMutexW,CreateMutexW,200 diff --git a/libc/nt/KernelBase/CreateNamedPipeW.s b/libc/nt/KernelBase/CreateNamedPipeW.s new file mode 100644 index 00000000..c5a173c6 --- /dev/null +++ b/libc/nt/KernelBase/CreateNamedPipeW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateNamedPipeW,CreateNamedPipeW,201 + + .text.windows +CreateNamedPipe: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateNamedPipeW(%rip),%rax + jmp __sysv2nt8 + .endfn CreateNamedPipe,globl + .previous diff --git a/libc/nt/KernelBase/CreatePipe.s b/libc/nt/KernelBase/CreatePipe.s new file mode 100644 index 00000000..7d779b17 --- /dev/null +++ b/libc/nt/KernelBase/CreatePipe.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreatePipe,CreatePipe,202 + + .text.windows +CreatePipe: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreatePipe(%rip),%rax + jmp __sysv2nt + .endfn CreatePipe,globl + .previous diff --git a/libc/nt/KernelBase/CreatePrivateNamespaceW.s b/libc/nt/KernelBase/CreatePrivateNamespaceW.s new file mode 100644 index 00000000..c8a7717a --- /dev/null +++ b/libc/nt/KernelBase/CreatePrivateNamespaceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreatePrivateNamespaceW,CreatePrivateNamespaceW,203 diff --git a/libc/nt/KernelBase/CreatePrivateObjectSecurity.s b/libc/nt/KernelBase/CreatePrivateObjectSecurity.s new file mode 100644 index 00000000..64c84254 --- /dev/null +++ b/libc/nt/KernelBase/CreatePrivateObjectSecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreatePrivateObjectSecurity,CreatePrivateObjectSecurity,204 diff --git a/libc/nt/KernelBase/CreatePrivateObjectSecurityEx.s b/libc/nt/KernelBase/CreatePrivateObjectSecurityEx.s new file mode 100644 index 00000000..e20f6dac --- /dev/null +++ b/libc/nt/KernelBase/CreatePrivateObjectSecurityEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreatePrivateObjectSecurityEx,CreatePrivateObjectSecurityEx,205 diff --git a/libc/nt/KernelBase/CreatePrivateObjectSecurityWithMultipleInheritance.s b/libc/nt/KernelBase/CreatePrivateObjectSecurityWithMultipleInheritance.s new file mode 100644 index 00000000..b9528975 --- /dev/null +++ b/libc/nt/KernelBase/CreatePrivateObjectSecurityWithMultipleInheritance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreatePrivateObjectSecurityWithMultipleInheritance,CreatePrivateObjectSecurityWithMultipleInheritance,206 diff --git a/libc/nt/KernelBase/CreateProcessA.s b/libc/nt/KernelBase/CreateProcessA.s new file mode 100644 index 00000000..bea56cd9 --- /dev/null +++ b/libc/nt/KernelBase/CreateProcessA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateProcessA,CreateProcessA,207 + + .text.windows +CreateProcessA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateProcessA(%rip),%rax + jmp __sysv2nt10 + .endfn CreateProcessA,globl + .previous diff --git a/libc/nt/KernelBase/CreateProcessAsUserA.s b/libc/nt/KernelBase/CreateProcessAsUserA.s new file mode 100644 index 00000000..3415dbd3 --- /dev/null +++ b/libc/nt/KernelBase/CreateProcessAsUserA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateProcessAsUserA,CreateProcessAsUserA,208 diff --git a/libc/nt/KernelBase/CreateProcessAsUserW.s b/libc/nt/KernelBase/CreateProcessAsUserW.s new file mode 100644 index 00000000..00253996 --- /dev/null +++ b/libc/nt/KernelBase/CreateProcessAsUserW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateProcessAsUserW,CreateProcessAsUserW,209 diff --git a/libc/nt/KernelBase/CreateProcessInternalA.s b/libc/nt/KernelBase/CreateProcessInternalA.s new file mode 100644 index 00000000..17866d6b --- /dev/null +++ b/libc/nt/KernelBase/CreateProcessInternalA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateProcessInternalA,CreateProcessInternalA,210 diff --git a/libc/nt/KernelBase/CreateProcessInternalW.s b/libc/nt/KernelBase/CreateProcessInternalW.s new file mode 100644 index 00000000..a2f0281d --- /dev/null +++ b/libc/nt/KernelBase/CreateProcessInternalW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateProcessInternalW,CreateProcessInternalW,211 diff --git a/libc/nt/KernelBase/CreateProcessW.s b/libc/nt/KernelBase/CreateProcessW.s new file mode 100644 index 00000000..335562a9 --- /dev/null +++ b/libc/nt/KernelBase/CreateProcessW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateProcessW,CreateProcessW,212 + + .text.windows +CreateProcess: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateProcessW(%rip),%rax + jmp __sysv2nt10 + .endfn CreateProcess,globl + .previous diff --git a/libc/nt/KernelBase/CreateRemoteThread.s b/libc/nt/KernelBase/CreateRemoteThread.s new file mode 100644 index 00000000..f58e9898 --- /dev/null +++ b/libc/nt/KernelBase/CreateRemoteThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateRemoteThread,CreateRemoteThread,213 diff --git a/libc/nt/KernelBase/CreateRemoteThreadEx.s b/libc/nt/KernelBase/CreateRemoteThreadEx.s new file mode 100644 index 00000000..3ee702e3 --- /dev/null +++ b/libc/nt/KernelBase/CreateRemoteThreadEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateRemoteThreadEx,CreateRemoteThreadEx,214 diff --git a/libc/nt/KernelBase/CreateRestrictedToken.s b/libc/nt/KernelBase/CreateRestrictedToken.s new file mode 100644 index 00000000..2244c521 --- /dev/null +++ b/libc/nt/KernelBase/CreateRestrictedToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateRestrictedToken,CreateRestrictedToken,215 diff --git a/libc/nt/KernelBase/CreateSemaphoreExW.s b/libc/nt/KernelBase/CreateSemaphoreExW.s new file mode 100644 index 00000000..ac6c057b --- /dev/null +++ b/libc/nt/KernelBase/CreateSemaphoreExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateSemaphoreExW,CreateSemaphoreExW,216 diff --git a/libc/nt/KernelBase/CreateSemaphoreW.s b/libc/nt/KernelBase/CreateSemaphoreW.s new file mode 100644 index 00000000..df078957 --- /dev/null +++ b/libc/nt/KernelBase/CreateSemaphoreW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateSemaphoreW,CreateSemaphoreW,217 diff --git a/libc/nt/KernelBase/CreateStateAtom.s b/libc/nt/KernelBase/CreateStateAtom.s new file mode 100644 index 00000000..dd932fe7 --- /dev/null +++ b/libc/nt/KernelBase/CreateStateAtom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateStateAtom,CreateStateAtom,218 diff --git a/libc/nt/KernelBase/CreateStateChangeNotification.s b/libc/nt/KernelBase/CreateStateChangeNotification.s new file mode 100644 index 00000000..d6aa6978 --- /dev/null +++ b/libc/nt/KernelBase/CreateStateChangeNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateStateChangeNotification,CreateStateChangeNotification,219 diff --git a/libc/nt/KernelBase/CreateStateContainer.s b/libc/nt/KernelBase/CreateStateContainer.s new file mode 100644 index 00000000..2920265e --- /dev/null +++ b/libc/nt/KernelBase/CreateStateContainer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateStateContainer,CreateStateContainer,220 diff --git a/libc/nt/KernelBase/CreateStateLock.s b/libc/nt/KernelBase/CreateStateLock.s new file mode 100644 index 00000000..89bae352 --- /dev/null +++ b/libc/nt/KernelBase/CreateStateLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateStateLock,CreateStateLock,221 diff --git a/libc/nt/KernelBase/CreateStateSubcontainer.s b/libc/nt/KernelBase/CreateStateSubcontainer.s new file mode 100644 index 00000000..aaab2d3f --- /dev/null +++ b/libc/nt/KernelBase/CreateStateSubcontainer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateStateSubcontainer,CreateStateSubcontainer,222 diff --git a/libc/nt/KernelBase/CreateSymbolicLinkW.s b/libc/nt/KernelBase/CreateSymbolicLinkW.s new file mode 100644 index 00000000..8c9d4851 --- /dev/null +++ b/libc/nt/KernelBase/CreateSymbolicLinkW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateSymbolicLinkW,CreateSymbolicLinkW,223 + + .text.windows +CreateSymbolicLink: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateSymbolicLinkW(%rip),%rax + jmp __sysv2nt + .endfn CreateSymbolicLink,globl + .previous diff --git a/libc/nt/KernelBase/CreateThread.s b/libc/nt/KernelBase/CreateThread.s new file mode 100644 index 00000000..96963560 --- /dev/null +++ b/libc/nt/KernelBase/CreateThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateThread,CreateThread,224 diff --git a/libc/nt/KernelBase/CreateThreadpool.s b/libc/nt/KernelBase/CreateThreadpool.s new file mode 100644 index 00000000..7709b06a --- /dev/null +++ b/libc/nt/KernelBase/CreateThreadpool.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateThreadpool,CreateThreadpool,225 diff --git a/libc/nt/KernelBase/CreateThreadpoolCleanupGroup.s b/libc/nt/KernelBase/CreateThreadpoolCleanupGroup.s new file mode 100644 index 00000000..aadcdcb4 --- /dev/null +++ b/libc/nt/KernelBase/CreateThreadpoolCleanupGroup.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateThreadpoolCleanupGroup,CreateThreadpoolCleanupGroup,226 diff --git a/libc/nt/KernelBase/CreateThreadpoolIo.s b/libc/nt/KernelBase/CreateThreadpoolIo.s new file mode 100644 index 00000000..143d2eb9 --- /dev/null +++ b/libc/nt/KernelBase/CreateThreadpoolIo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateThreadpoolIo,CreateThreadpoolIo,227 diff --git a/libc/nt/KernelBase/CreateThreadpoolTimer.s b/libc/nt/KernelBase/CreateThreadpoolTimer.s new file mode 100644 index 00000000..dbb7a58d --- /dev/null +++ b/libc/nt/KernelBase/CreateThreadpoolTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateThreadpoolTimer,CreateThreadpoolTimer,228 diff --git a/libc/nt/KernelBase/CreateThreadpoolWait.s b/libc/nt/KernelBase/CreateThreadpoolWait.s new file mode 100644 index 00000000..15a585d8 --- /dev/null +++ b/libc/nt/KernelBase/CreateThreadpoolWait.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateThreadpoolWait,CreateThreadpoolWait,229 diff --git a/libc/nt/KernelBase/CreateThreadpoolWork.s b/libc/nt/KernelBase/CreateThreadpoolWork.s new file mode 100644 index 00000000..9e2e46c0 --- /dev/null +++ b/libc/nt/KernelBase/CreateThreadpoolWork.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateThreadpoolWork,CreateThreadpoolWork,230 diff --git a/libc/nt/KernelBase/CreateTimerQueue.s b/libc/nt/KernelBase/CreateTimerQueue.s new file mode 100644 index 00000000..fd12302a --- /dev/null +++ b/libc/nt/KernelBase/CreateTimerQueue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateTimerQueue,CreateTimerQueue,231 diff --git a/libc/nt/KernelBase/CreateTimerQueueTimer.s b/libc/nt/KernelBase/CreateTimerQueueTimer.s new file mode 100644 index 00000000..61014481 --- /dev/null +++ b/libc/nt/KernelBase/CreateTimerQueueTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateTimerQueueTimer,CreateTimerQueueTimer,232 diff --git a/libc/nt/KernelBase/CreateWaitableTimerExW.s b/libc/nt/KernelBase/CreateWaitableTimerExW.s new file mode 100644 index 00000000..156e0ee7 --- /dev/null +++ b/libc/nt/KernelBase/CreateWaitableTimerExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateWaitableTimerExW,CreateWaitableTimerExW,233 diff --git a/libc/nt/KernelBase/CreateWaitableTimerW.s b/libc/nt/KernelBase/CreateWaitableTimerW.s new file mode 100644 index 00000000..dae909bb --- /dev/null +++ b/libc/nt/KernelBase/CreateWaitableTimerW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateWaitableTimerW,CreateWaitableTimerW,234 diff --git a/libc/nt/KernelBase/CreateWellKnownSid.s b/libc/nt/KernelBase/CreateWellKnownSid.s new file mode 100644 index 00000000..e0b55e69 --- /dev/null +++ b/libc/nt/KernelBase/CreateWellKnownSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CreateWellKnownSid,CreateWellKnownSid,235 diff --git a/libc/nt/KernelBase/CtrlRoutine.s b/libc/nt/KernelBase/CtrlRoutine.s new file mode 100644 index 00000000..cbf47575 --- /dev/null +++ b/libc/nt/KernelBase/CtrlRoutine.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CtrlRoutine,CtrlRoutine,236 diff --git a/libc/nt/KernelBase/CveEventWrite.s b/libc/nt/KernelBase/CveEventWrite.s new file mode 100644 index 00000000..2e6ed1a8 --- /dev/null +++ b/libc/nt/KernelBase/CveEventWrite.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_CveEventWrite,CveEventWrite,237 diff --git a/libc/nt/KernelBase/DeactivateActCtx.s b/libc/nt/KernelBase/DeactivateActCtx.s new file mode 100644 index 00000000..fd52b295 --- /dev/null +++ b/libc/nt/KernelBase/DeactivateActCtx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DeactivateActCtx,DeactivateActCtx,238 diff --git a/libc/nt/KernelBase/DebugActiveProcess.s b/libc/nt/KernelBase/DebugActiveProcess.s new file mode 100644 index 00000000..fa2e4a4e --- /dev/null +++ b/libc/nt/KernelBase/DebugActiveProcess.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DebugActiveProcess,DebugActiveProcess,239 + + .text.windows +DebugActiveProcess: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_DebugActiveProcess(%rip) + leave + ret + .endfn DebugActiveProcess,globl + .previous diff --git a/libc/nt/KernelBase/DebugActiveProcessStop.s b/libc/nt/KernelBase/DebugActiveProcessStop.s new file mode 100644 index 00000000..02874f41 --- /dev/null +++ b/libc/nt/KernelBase/DebugActiveProcessStop.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DebugActiveProcessStop,DebugActiveProcessStop,240 + + .text.windows +DebugActiveProcessStop: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_DebugActiveProcessStop(%rip) + leave + ret + .endfn DebugActiveProcessStop,globl + .previous diff --git a/libc/nt/KernelBase/DefineDosDeviceW.s b/libc/nt/KernelBase/DefineDosDeviceW.s new file mode 100644 index 00000000..c9fc0450 --- /dev/null +++ b/libc/nt/KernelBase/DefineDosDeviceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DefineDosDeviceW,DefineDosDeviceW,245 diff --git a/libc/nt/KernelBase/DelayLoadFailureHook.s b/libc/nt/KernelBase/DelayLoadFailureHook.s new file mode 100644 index 00000000..841e5d0c --- /dev/null +++ b/libc/nt/KernelBase/DelayLoadFailureHook.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DelayLoadFailureHook,DelayLoadFailureHook,246 diff --git a/libc/nt/KernelBase/DelayLoadFailureHookLookup.s b/libc/nt/KernelBase/DelayLoadFailureHookLookup.s new file mode 100644 index 00000000..1acc7db7 --- /dev/null +++ b/libc/nt/KernelBase/DelayLoadFailureHookLookup.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DelayLoadFailureHookLookup,DelayLoadFailureHookLookup,247 diff --git a/libc/nt/KernelBase/DeleteAce.s b/libc/nt/KernelBase/DeleteAce.s new file mode 100644 index 00000000..f57d3cc7 --- /dev/null +++ b/libc/nt/KernelBase/DeleteAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DeleteAce,DeleteAce,248 diff --git a/libc/nt/KernelBase/DeleteBoundaryDescriptor.s b/libc/nt/KernelBase/DeleteBoundaryDescriptor.s new file mode 100644 index 00000000..b8bb4754 --- /dev/null +++ b/libc/nt/KernelBase/DeleteBoundaryDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DeleteBoundaryDescriptor,DeleteBoundaryDescriptor,249 diff --git a/libc/nt/KernelBase/DeleteEnclave.s b/libc/nt/KernelBase/DeleteEnclave.s new file mode 100644 index 00000000..ee23e2a3 --- /dev/null +++ b/libc/nt/KernelBase/DeleteEnclave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DeleteEnclave,DeleteEnclave,251 diff --git a/libc/nt/KernelBase/DeleteFiber.s b/libc/nt/KernelBase/DeleteFiber.s new file mode 100644 index 00000000..0b1f198a --- /dev/null +++ b/libc/nt/KernelBase/DeleteFiber.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DeleteFiber,DeleteFiber,252 diff --git a/libc/nt/KernelBase/DeleteFileA.s b/libc/nt/KernelBase/DeleteFileA.s new file mode 100644 index 00000000..17e0d989 --- /dev/null +++ b/libc/nt/KernelBase/DeleteFileA.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DeleteFileA,DeleteFileA,253 + + .text.windows +DeleteFileA: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_DeleteFileA(%rip) + leave + ret + .endfn DeleteFileA,globl + .previous diff --git a/libc/nt/KernelBase/DeleteFileW.s b/libc/nt/KernelBase/DeleteFileW.s new file mode 100644 index 00000000..9d348c12 --- /dev/null +++ b/libc/nt/KernelBase/DeleteFileW.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DeleteFileW,DeleteFileW,254 + + .text.windows +DeleteFile: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_DeleteFileW(%rip) + leave + ret + .endfn DeleteFile,globl + .previous diff --git a/libc/nt/KernelBase/DeleteProcThreadAttributeList.s b/libc/nt/KernelBase/DeleteProcThreadAttributeList.s new file mode 100644 index 00000000..dbe71d9f --- /dev/null +++ b/libc/nt/KernelBase/DeleteProcThreadAttributeList.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DeleteProcThreadAttributeList,DeleteProcThreadAttributeList,255 + + .text.windows +DeleteProcThreadAttributeList: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_DeleteProcThreadAttributeList(%rip) + leave + ret + .endfn DeleteProcThreadAttributeList,globl + .previous diff --git a/libc/nt/KernelBase/DeleteStateAtomValue.s b/libc/nt/KernelBase/DeleteStateAtomValue.s new file mode 100644 index 00000000..e3639361 --- /dev/null +++ b/libc/nt/KernelBase/DeleteStateAtomValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DeleteStateAtomValue,DeleteStateAtomValue,256 diff --git a/libc/nt/KernelBase/DeleteStateContainer.s b/libc/nt/KernelBase/DeleteStateContainer.s new file mode 100644 index 00000000..ae5de771 --- /dev/null +++ b/libc/nt/KernelBase/DeleteStateContainer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DeleteStateContainer,DeleteStateContainer,257 diff --git a/libc/nt/KernelBase/DeleteStateContainerValue.s b/libc/nt/KernelBase/DeleteStateContainerValue.s new file mode 100644 index 00000000..829fbc33 --- /dev/null +++ b/libc/nt/KernelBase/DeleteStateContainerValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DeleteStateContainerValue,DeleteStateContainerValue,258 diff --git a/libc/nt/KernelBase/DeleteTimerQueueEx.s b/libc/nt/KernelBase/DeleteTimerQueueEx.s new file mode 100644 index 00000000..23715446 --- /dev/null +++ b/libc/nt/KernelBase/DeleteTimerQueueEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DeleteTimerQueueEx,DeleteTimerQueueEx,260 diff --git a/libc/nt/KernelBase/DeleteTimerQueueTimer.s b/libc/nt/KernelBase/DeleteTimerQueueTimer.s new file mode 100644 index 00000000..c7b57b63 --- /dev/null +++ b/libc/nt/KernelBase/DeleteTimerQueueTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DeleteTimerQueueTimer,DeleteTimerQueueTimer,261 diff --git a/libc/nt/KernelBase/DeleteVolumeMountPointW.s b/libc/nt/KernelBase/DeleteVolumeMountPointW.s new file mode 100644 index 00000000..c0aa5808 --- /dev/null +++ b/libc/nt/KernelBase/DeleteVolumeMountPointW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DeleteVolumeMountPointW,DeleteVolumeMountPointW,262 diff --git a/libc/nt/KernelBase/DeriveCapabilitySidsFromName.s b/libc/nt/KernelBase/DeriveCapabilitySidsFromName.s new file mode 100644 index 00000000..004984e7 --- /dev/null +++ b/libc/nt/KernelBase/DeriveCapabilitySidsFromName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DeriveCapabilitySidsFromName,DeriveCapabilitySidsFromName,263 diff --git a/libc/nt/KernelBase/DestroyPrivateObjectSecurity.s b/libc/nt/KernelBase/DestroyPrivateObjectSecurity.s new file mode 100644 index 00000000..4a681263 --- /dev/null +++ b/libc/nt/KernelBase/DestroyPrivateObjectSecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DestroyPrivateObjectSecurity,DestroyPrivateObjectSecurity,264 diff --git a/libc/nt/KernelBase/DeviceIoControl.s b/libc/nt/KernelBase/DeviceIoControl.s new file mode 100644 index 00000000..03e2f9ff --- /dev/null +++ b/libc/nt/KernelBase/DeviceIoControl.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DeviceIoControl,DeviceIoControl,265 + + .text.windows +DeviceIoControl: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_DeviceIoControl(%rip),%rax + jmp __sysv2nt8 + .endfn DeviceIoControl,globl + .previous diff --git a/libc/nt/KernelBase/DisablePredefinedHandleTableInternal.s b/libc/nt/KernelBase/DisablePredefinedHandleTableInternal.s new file mode 100644 index 00000000..4882a11a --- /dev/null +++ b/libc/nt/KernelBase/DisablePredefinedHandleTableInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DisablePredefinedHandleTableInternal,DisablePredefinedHandleTableInternal,266 diff --git a/libc/nt/KernelBase/DisableThreadLibraryCalls.s b/libc/nt/KernelBase/DisableThreadLibraryCalls.s new file mode 100644 index 00000000..d1743c25 --- /dev/null +++ b/libc/nt/KernelBase/DisableThreadLibraryCalls.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DisableThreadLibraryCalls,DisableThreadLibraryCalls,267 diff --git a/libc/nt/KernelBase/DiscardVirtualMemory.s b/libc/nt/KernelBase/DiscardVirtualMemory.s new file mode 100644 index 00000000..a93283db --- /dev/null +++ b/libc/nt/KernelBase/DiscardVirtualMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DiscardVirtualMemory,DiscardVirtualMemory,269 diff --git a/libc/nt/KernelBase/DisconnectNamedPipe.s b/libc/nt/KernelBase/DisconnectNamedPipe.s new file mode 100644 index 00000000..6cb5824d --- /dev/null +++ b/libc/nt/KernelBase/DisconnectNamedPipe.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DisconnectNamedPipe,DisconnectNamedPipe,270 + + .text.windows +DisconnectNamedPipe: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_DisconnectNamedPipe(%rip) + leave + ret + .endfn DisconnectNamedPipe,globl + .previous diff --git a/libc/nt/KernelBase/DnsHostnameToComputerNameExW.s b/libc/nt/KernelBase/DnsHostnameToComputerNameExW.s new file mode 100644 index 00000000..b9d32760 --- /dev/null +++ b/libc/nt/KernelBase/DnsHostnameToComputerNameExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DnsHostnameToComputerNameExW,DnsHostnameToComputerNameExW,271 diff --git a/libc/nt/KernelBase/DsBindWithSpnExW.s b/libc/nt/KernelBase/DsBindWithSpnExW.s new file mode 100644 index 00000000..5b7a0094 --- /dev/null +++ b/libc/nt/KernelBase/DsBindWithSpnExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DsBindWithSpnExW,DsBindWithSpnExW,272 diff --git a/libc/nt/KernelBase/DsCrackNamesW.s b/libc/nt/KernelBase/DsCrackNamesW.s new file mode 100644 index 00000000..0c448671 --- /dev/null +++ b/libc/nt/KernelBase/DsCrackNamesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DsCrackNamesW,DsCrackNamesW,273 diff --git a/libc/nt/KernelBase/DsFreeDomainControllerInfoW.s b/libc/nt/KernelBase/DsFreeDomainControllerInfoW.s new file mode 100644 index 00000000..5d13d070 --- /dev/null +++ b/libc/nt/KernelBase/DsFreeDomainControllerInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DsFreeDomainControllerInfoW,DsFreeDomainControllerInfoW,274 diff --git a/libc/nt/KernelBase/DsFreeNameResultW.s b/libc/nt/KernelBase/DsFreeNameResultW.s new file mode 100644 index 00000000..ab0d6029 --- /dev/null +++ b/libc/nt/KernelBase/DsFreeNameResultW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DsFreeNameResultW,DsFreeNameResultW,275 diff --git a/libc/nt/KernelBase/DsFreeNgcKey.s b/libc/nt/KernelBase/DsFreeNgcKey.s new file mode 100644 index 00000000..91d3487a --- /dev/null +++ b/libc/nt/KernelBase/DsFreeNgcKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DsFreeNgcKey,DsFreeNgcKey,276 diff --git a/libc/nt/KernelBase/DsFreePasswordCredentials.s b/libc/nt/KernelBase/DsFreePasswordCredentials.s new file mode 100644 index 00000000..5b06e173 --- /dev/null +++ b/libc/nt/KernelBase/DsFreePasswordCredentials.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DsFreePasswordCredentials,DsFreePasswordCredentials,277 diff --git a/libc/nt/KernelBase/DsGetDomainControllerInfoW.s b/libc/nt/KernelBase/DsGetDomainControllerInfoW.s new file mode 100644 index 00000000..45793664 --- /dev/null +++ b/libc/nt/KernelBase/DsGetDomainControllerInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DsGetDomainControllerInfoW,DsGetDomainControllerInfoW,278 diff --git a/libc/nt/KernelBase/DsMakePasswordCredentialsW.s b/libc/nt/KernelBase/DsMakePasswordCredentialsW.s new file mode 100644 index 00000000..66bc309d --- /dev/null +++ b/libc/nt/KernelBase/DsMakePasswordCredentialsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DsMakePasswordCredentialsW,DsMakePasswordCredentialsW,279 diff --git a/libc/nt/KernelBase/DsReadNgcKeyW.s b/libc/nt/KernelBase/DsReadNgcKeyW.s new file mode 100644 index 00000000..be2cdc66 --- /dev/null +++ b/libc/nt/KernelBase/DsReadNgcKeyW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DsReadNgcKeyW,DsReadNgcKeyW,280 diff --git a/libc/nt/KernelBase/DsUnBindW.s b/libc/nt/KernelBase/DsUnBindW.s new file mode 100644 index 00000000..1dbfcc37 --- /dev/null +++ b/libc/nt/KernelBase/DsUnBindW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DsUnBindW,DsUnBindW,281 diff --git a/libc/nt/KernelBase/DsWriteNgcKeyW.s b/libc/nt/KernelBase/DsWriteNgcKeyW.s new file mode 100644 index 00000000..4872c023 --- /dev/null +++ b/libc/nt/KernelBase/DsWriteNgcKeyW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DsWriteNgcKeyW,DsWriteNgcKeyW,282 diff --git a/libc/nt/KernelBase/DuplicateHandle.s b/libc/nt/KernelBase/DuplicateHandle.s new file mode 100644 index 00000000..060779dc --- /dev/null +++ b/libc/nt/KernelBase/DuplicateHandle.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DuplicateHandle,DuplicateHandle,283 + + .text.windows +DuplicateHandle: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_DuplicateHandle(%rip),%rax + jmp __sysv2nt8 + .endfn DuplicateHandle,globl + .previous diff --git a/libc/nt/KernelBase/DuplicateStateContainerHandle.s b/libc/nt/KernelBase/DuplicateStateContainerHandle.s new file mode 100644 index 00000000..45ba50e1 --- /dev/null +++ b/libc/nt/KernelBase/DuplicateStateContainerHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DuplicateStateContainerHandle,DuplicateStateContainerHandle,284 diff --git a/libc/nt/KernelBase/DuplicateToken.s b/libc/nt/KernelBase/DuplicateToken.s new file mode 100644 index 00000000..15f4da4b --- /dev/null +++ b/libc/nt/KernelBase/DuplicateToken.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DuplicateToken,DuplicateToken,285 + + .text.windows +DuplicateToken: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_DuplicateToken(%rip),%rax + jmp __sysv2nt + .endfn DuplicateToken,globl + .previous diff --git a/libc/nt/KernelBase/DuplicateTokenEx.s b/libc/nt/KernelBase/DuplicateTokenEx.s new file mode 100644 index 00000000..941f0652 --- /dev/null +++ b/libc/nt/KernelBase/DuplicateTokenEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_DuplicateTokenEx,DuplicateTokenEx,286 + + .text.windows +DuplicateTokenEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_DuplicateTokenEx(%rip),%rax + jmp __sysv2nt6 + .endfn DuplicateTokenEx,globl + .previous diff --git a/libc/nt/KernelBase/EmptyWorkingSet.s b/libc/nt/KernelBase/EmptyWorkingSet.s new file mode 100644 index 00000000..911ef1ca --- /dev/null +++ b/libc/nt/KernelBase/EmptyWorkingSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EmptyWorkingSet,EmptyWorkingSet,287 diff --git a/libc/nt/KernelBase/EnterCriticalPolicySectionInternal.s b/libc/nt/KernelBase/EnterCriticalPolicySectionInternal.s new file mode 100644 index 00000000..051a1884 --- /dev/null +++ b/libc/nt/KernelBase/EnterCriticalPolicySectionInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnterCriticalPolicySectionInternal,EnterCriticalPolicySectionInternal,291 diff --git a/libc/nt/KernelBase/EnterSynchronizationBarrier.s b/libc/nt/KernelBase/EnterSynchronizationBarrier.s new file mode 100644 index 00000000..3ae976d8 --- /dev/null +++ b/libc/nt/KernelBase/EnterSynchronizationBarrier.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnterSynchronizationBarrier,EnterSynchronizationBarrier,293 diff --git a/libc/nt/KernelBase/EnumCalendarInfoExEx.s b/libc/nt/KernelBase/EnumCalendarInfoExEx.s new file mode 100644 index 00000000..4e29b5f3 --- /dev/null +++ b/libc/nt/KernelBase/EnumCalendarInfoExEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumCalendarInfoExEx,EnumCalendarInfoExEx,294 diff --git a/libc/nt/KernelBase/EnumCalendarInfoExW.s b/libc/nt/KernelBase/EnumCalendarInfoExW.s new file mode 100644 index 00000000..5f965083 --- /dev/null +++ b/libc/nt/KernelBase/EnumCalendarInfoExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumCalendarInfoExW,EnumCalendarInfoExW,295 diff --git a/libc/nt/KernelBase/EnumCalendarInfoW.s b/libc/nt/KernelBase/EnumCalendarInfoW.s new file mode 100644 index 00000000..dda3f000 --- /dev/null +++ b/libc/nt/KernelBase/EnumCalendarInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumCalendarInfoW,EnumCalendarInfoW,296 diff --git a/libc/nt/KernelBase/EnumDateFormatsExEx.s b/libc/nt/KernelBase/EnumDateFormatsExEx.s new file mode 100644 index 00000000..b2c3b05f --- /dev/null +++ b/libc/nt/KernelBase/EnumDateFormatsExEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumDateFormatsExEx,EnumDateFormatsExEx,297 diff --git a/libc/nt/KernelBase/EnumDateFormatsExW.s b/libc/nt/KernelBase/EnumDateFormatsExW.s new file mode 100644 index 00000000..2988a870 --- /dev/null +++ b/libc/nt/KernelBase/EnumDateFormatsExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumDateFormatsExW,EnumDateFormatsExW,298 diff --git a/libc/nt/KernelBase/EnumDateFormatsW.s b/libc/nt/KernelBase/EnumDateFormatsW.s new file mode 100644 index 00000000..104fb4dc --- /dev/null +++ b/libc/nt/KernelBase/EnumDateFormatsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumDateFormatsW,EnumDateFormatsW,299 diff --git a/libc/nt/KernelBase/EnumDeviceDrivers.s b/libc/nt/KernelBase/EnumDeviceDrivers.s new file mode 100644 index 00000000..9e8f6850 --- /dev/null +++ b/libc/nt/KernelBase/EnumDeviceDrivers.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumDeviceDrivers,EnumDeviceDrivers,300 diff --git a/libc/nt/KernelBase/EnumDynamicTimeZoneInformation.s b/libc/nt/KernelBase/EnumDynamicTimeZoneInformation.s new file mode 100644 index 00000000..c8326ee7 --- /dev/null +++ b/libc/nt/KernelBase/EnumDynamicTimeZoneInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumDynamicTimeZoneInformation,EnumDynamicTimeZoneInformation,301 diff --git a/libc/nt/KernelBase/EnumLanguageGroupLocalesW.s b/libc/nt/KernelBase/EnumLanguageGroupLocalesW.s new file mode 100644 index 00000000..5b598183 --- /dev/null +++ b/libc/nt/KernelBase/EnumLanguageGroupLocalesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumLanguageGroupLocalesW,EnumLanguageGroupLocalesW,302 diff --git a/libc/nt/KernelBase/EnumPageFilesA.s b/libc/nt/KernelBase/EnumPageFilesA.s new file mode 100644 index 00000000..8ceb2d18 --- /dev/null +++ b/libc/nt/KernelBase/EnumPageFilesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumPageFilesA,EnumPageFilesA,303 diff --git a/libc/nt/KernelBase/EnumPageFilesW.s b/libc/nt/KernelBase/EnumPageFilesW.s new file mode 100644 index 00000000..66a4b9f3 --- /dev/null +++ b/libc/nt/KernelBase/EnumPageFilesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumPageFilesW,EnumPageFilesW,304 diff --git a/libc/nt/KernelBase/EnumProcessModules.s b/libc/nt/KernelBase/EnumProcessModules.s new file mode 100644 index 00000000..0b9b116e --- /dev/null +++ b/libc/nt/KernelBase/EnumProcessModules.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumProcessModules,EnumProcessModules,305 diff --git a/libc/nt/KernelBase/EnumProcessModulesEx.s b/libc/nt/KernelBase/EnumProcessModulesEx.s new file mode 100644 index 00000000..5e4366cd --- /dev/null +++ b/libc/nt/KernelBase/EnumProcessModulesEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumProcessModulesEx,EnumProcessModulesEx,306 diff --git a/libc/nt/KernelBase/EnumProcesses.s b/libc/nt/KernelBase/EnumProcesses.s new file mode 100644 index 00000000..cb704c5c --- /dev/null +++ b/libc/nt/KernelBase/EnumProcesses.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumProcesses,EnumProcesses,307 diff --git a/libc/nt/KernelBase/EnumResourceLanguagesExA.s b/libc/nt/KernelBase/EnumResourceLanguagesExA.s new file mode 100644 index 00000000..e9617020 --- /dev/null +++ b/libc/nt/KernelBase/EnumResourceLanguagesExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumResourceLanguagesExA,EnumResourceLanguagesExA,308 diff --git a/libc/nt/KernelBase/EnumResourceLanguagesExW.s b/libc/nt/KernelBase/EnumResourceLanguagesExW.s new file mode 100644 index 00000000..f4f2b7a4 --- /dev/null +++ b/libc/nt/KernelBase/EnumResourceLanguagesExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumResourceLanguagesExW,EnumResourceLanguagesExW,309 diff --git a/libc/nt/KernelBase/EnumResourceNamesExA.s b/libc/nt/KernelBase/EnumResourceNamesExA.s new file mode 100644 index 00000000..4165dbed --- /dev/null +++ b/libc/nt/KernelBase/EnumResourceNamesExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumResourceNamesExA,EnumResourceNamesExA,310 diff --git a/libc/nt/KernelBase/EnumResourceNamesExW.s b/libc/nt/KernelBase/EnumResourceNamesExW.s new file mode 100644 index 00000000..029b5d63 --- /dev/null +++ b/libc/nt/KernelBase/EnumResourceNamesExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumResourceNamesExW,EnumResourceNamesExW,311 diff --git a/libc/nt/KernelBase/EnumResourceNamesW.s b/libc/nt/KernelBase/EnumResourceNamesW.s new file mode 100644 index 00000000..bf1920e1 --- /dev/null +++ b/libc/nt/KernelBase/EnumResourceNamesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumResourceNamesW,EnumResourceNamesW,312 diff --git a/libc/nt/KernelBase/EnumResourceTypesExA.s b/libc/nt/KernelBase/EnumResourceTypesExA.s new file mode 100644 index 00000000..67b0e7f6 --- /dev/null +++ b/libc/nt/KernelBase/EnumResourceTypesExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumResourceTypesExA,EnumResourceTypesExA,313 diff --git a/libc/nt/KernelBase/EnumResourceTypesExW.s b/libc/nt/KernelBase/EnumResourceTypesExW.s new file mode 100644 index 00000000..75fa6fd4 --- /dev/null +++ b/libc/nt/KernelBase/EnumResourceTypesExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumResourceTypesExW,EnumResourceTypesExW,314 diff --git a/libc/nt/KernelBase/EnumSystemCodePagesW.s b/libc/nt/KernelBase/EnumSystemCodePagesW.s new file mode 100644 index 00000000..30f4481f --- /dev/null +++ b/libc/nt/KernelBase/EnumSystemCodePagesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumSystemCodePagesW,EnumSystemCodePagesW,315 diff --git a/libc/nt/KernelBase/EnumSystemFirmwareTables.s b/libc/nt/KernelBase/EnumSystemFirmwareTables.s new file mode 100644 index 00000000..c9c96081 --- /dev/null +++ b/libc/nt/KernelBase/EnumSystemFirmwareTables.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumSystemFirmwareTables,EnumSystemFirmwareTables,316 diff --git a/libc/nt/KernelBase/EnumSystemGeoID.s b/libc/nt/KernelBase/EnumSystemGeoID.s new file mode 100644 index 00000000..5d163f93 --- /dev/null +++ b/libc/nt/KernelBase/EnumSystemGeoID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumSystemGeoID,EnumSystemGeoID,317 diff --git a/libc/nt/KernelBase/EnumSystemGeoNames.s b/libc/nt/KernelBase/EnumSystemGeoNames.s new file mode 100644 index 00000000..060c8e90 --- /dev/null +++ b/libc/nt/KernelBase/EnumSystemGeoNames.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumSystemGeoNames,EnumSystemGeoNames,318 diff --git a/libc/nt/KernelBase/EnumSystemLanguageGroupsW.s b/libc/nt/KernelBase/EnumSystemLanguageGroupsW.s new file mode 100644 index 00000000..4e3c7926 --- /dev/null +++ b/libc/nt/KernelBase/EnumSystemLanguageGroupsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumSystemLanguageGroupsW,EnumSystemLanguageGroupsW,319 diff --git a/libc/nt/KernelBase/EnumSystemLocalesA.s b/libc/nt/KernelBase/EnumSystemLocalesA.s new file mode 100644 index 00000000..049e9095 --- /dev/null +++ b/libc/nt/KernelBase/EnumSystemLocalesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumSystemLocalesA,EnumSystemLocalesA,320 diff --git a/libc/nt/KernelBase/EnumSystemLocalesEx.s b/libc/nt/KernelBase/EnumSystemLocalesEx.s new file mode 100644 index 00000000..c6476ea6 --- /dev/null +++ b/libc/nt/KernelBase/EnumSystemLocalesEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumSystemLocalesEx,EnumSystemLocalesEx,321 diff --git a/libc/nt/KernelBase/EnumSystemLocalesW.s b/libc/nt/KernelBase/EnumSystemLocalesW.s new file mode 100644 index 00000000..0e6abd61 --- /dev/null +++ b/libc/nt/KernelBase/EnumSystemLocalesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumSystemLocalesW,EnumSystemLocalesW,322 diff --git a/libc/nt/KernelBase/EnumTimeFormatsEx.s b/libc/nt/KernelBase/EnumTimeFormatsEx.s new file mode 100644 index 00000000..3467e126 --- /dev/null +++ b/libc/nt/KernelBase/EnumTimeFormatsEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumTimeFormatsEx,EnumTimeFormatsEx,323 diff --git a/libc/nt/KernelBase/EnumTimeFormatsW.s b/libc/nt/KernelBase/EnumTimeFormatsW.s new file mode 100644 index 00000000..3de068bd --- /dev/null +++ b/libc/nt/KernelBase/EnumTimeFormatsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumTimeFormatsW,EnumTimeFormatsW,324 diff --git a/libc/nt/KernelBase/EnumUILanguagesW.s b/libc/nt/KernelBase/EnumUILanguagesW.s new file mode 100644 index 00000000..65f1ea54 --- /dev/null +++ b/libc/nt/KernelBase/EnumUILanguagesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumUILanguagesW,EnumUILanguagesW,325 diff --git a/libc/nt/KernelBase/EnumerateExtensionNames.s b/libc/nt/KernelBase/EnumerateExtensionNames.s new file mode 100644 index 00000000..e1f16c60 --- /dev/null +++ b/libc/nt/KernelBase/EnumerateExtensionNames.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumerateExtensionNames,EnumerateExtensionNames,326 diff --git a/libc/nt/KernelBase/EnumerateStateAtomValues.s b/libc/nt/KernelBase/EnumerateStateAtomValues.s new file mode 100644 index 00000000..e633a3e0 --- /dev/null +++ b/libc/nt/KernelBase/EnumerateStateAtomValues.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumerateStateAtomValues,EnumerateStateAtomValues,327 diff --git a/libc/nt/KernelBase/EnumerateStateContainerItems.s b/libc/nt/KernelBase/EnumerateStateContainerItems.s new file mode 100644 index 00000000..c5e9628e --- /dev/null +++ b/libc/nt/KernelBase/EnumerateStateContainerItems.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EnumerateStateContainerItems,EnumerateStateContainerItems,328 diff --git a/libc/nt/KernelBase/EqualDomainSid.s b/libc/nt/KernelBase/EqualDomainSid.s new file mode 100644 index 00000000..434bafba --- /dev/null +++ b/libc/nt/KernelBase/EqualDomainSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EqualDomainSid,EqualDomainSid,329 diff --git a/libc/nt/KernelBase/EqualPrefixSid.s b/libc/nt/KernelBase/EqualPrefixSid.s new file mode 100644 index 00000000..c0016711 --- /dev/null +++ b/libc/nt/KernelBase/EqualPrefixSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EqualPrefixSid,EqualPrefixSid,330 diff --git a/libc/nt/KernelBase/EqualSid.s b/libc/nt/KernelBase/EqualSid.s new file mode 100644 index 00000000..f506e6a3 --- /dev/null +++ b/libc/nt/KernelBase/EqualSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EqualSid,EqualSid,331 diff --git a/libc/nt/KernelBase/EscapeCommFunction.s b/libc/nt/KernelBase/EscapeCommFunction.s new file mode 100644 index 00000000..43244875 --- /dev/null +++ b/libc/nt/KernelBase/EscapeCommFunction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_EscapeCommFunction,EscapeCommFunction,332 diff --git a/libc/nt/KernelBase/ExitProcess.s b/libc/nt/KernelBase/ExitProcess.s new file mode 100644 index 00000000..91114b8c --- /dev/null +++ b/libc/nt/KernelBase/ExitProcess.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ExitProcess,ExitProcess,1343 + + .text.windows +ExitProcess: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_ExitProcess(%rip) + leave + ret + .endfn ExitProcess,globl + .previous diff --git a/libc/nt/KernelBase/ExpandEnvironmentStringsA.s b/libc/nt/KernelBase/ExpandEnvironmentStringsA.s new file mode 100644 index 00000000..946255b5 --- /dev/null +++ b/libc/nt/KernelBase/ExpandEnvironmentStringsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ExpandEnvironmentStringsA,ExpandEnvironmentStringsA,345 diff --git a/libc/nt/KernelBase/ExpandEnvironmentStringsW.s b/libc/nt/KernelBase/ExpandEnvironmentStringsW.s new file mode 100644 index 00000000..564daeb0 --- /dev/null +++ b/libc/nt/KernelBase/ExpandEnvironmentStringsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ExpandEnvironmentStringsW,ExpandEnvironmentStringsW,346 diff --git a/libc/nt/KernelBase/ExpungeConsoleCommandHistoryA.s b/libc/nt/KernelBase/ExpungeConsoleCommandHistoryA.s new file mode 100644 index 00000000..7a72c2fa --- /dev/null +++ b/libc/nt/KernelBase/ExpungeConsoleCommandHistoryA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ExpungeConsoleCommandHistoryA,ExpungeConsoleCommandHistoryA,347 diff --git a/libc/nt/KernelBase/ExpungeConsoleCommandHistoryW.s b/libc/nt/KernelBase/ExpungeConsoleCommandHistoryW.s new file mode 100644 index 00000000..001a5146 --- /dev/null +++ b/libc/nt/KernelBase/ExpungeConsoleCommandHistoryW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ExpungeConsoleCommandHistoryW,ExpungeConsoleCommandHistoryW,348 diff --git a/libc/nt/KernelBase/ExtensionProgIdExists.s b/libc/nt/KernelBase/ExtensionProgIdExists.s new file mode 100644 index 00000000..a4a6c31f --- /dev/null +++ b/libc/nt/KernelBase/ExtensionProgIdExists.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ExtensionProgIdExists,ExtensionProgIdExists,349 diff --git a/libc/nt/KernelBase/FatalAppExitA.s b/libc/nt/KernelBase/FatalAppExitA.s new file mode 100644 index 00000000..cb123b16 --- /dev/null +++ b/libc/nt/KernelBase/FatalAppExitA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FatalAppExitA,FatalAppExitA,350 diff --git a/libc/nt/KernelBase/FatalAppExitW.s b/libc/nt/KernelBase/FatalAppExitW.s new file mode 100644 index 00000000..f3a378ab --- /dev/null +++ b/libc/nt/KernelBase/FatalAppExitW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FatalAppExitW,FatalAppExitW,351 diff --git a/libc/nt/KernelBase/FileTimeToLocalFileTime.s b/libc/nt/KernelBase/FileTimeToLocalFileTime.s new file mode 100644 index 00000000..b67ff532 --- /dev/null +++ b/libc/nt/KernelBase/FileTimeToLocalFileTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FileTimeToLocalFileTime,FileTimeToLocalFileTime,352 diff --git a/libc/nt/KernelBase/FileTimeToSystemTime.s b/libc/nt/KernelBase/FileTimeToSystemTime.s new file mode 100644 index 00000000..639db2e4 --- /dev/null +++ b/libc/nt/KernelBase/FileTimeToSystemTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FileTimeToSystemTime,FileTimeToSystemTime,353 diff --git a/libc/nt/KernelBase/FillConsoleOutputAttribute.s b/libc/nt/KernelBase/FillConsoleOutputAttribute.s new file mode 100644 index 00000000..5973c9a2 --- /dev/null +++ b/libc/nt/KernelBase/FillConsoleOutputAttribute.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FillConsoleOutputAttribute,FillConsoleOutputAttribute,354 + + .text.windows +FillConsoleOutputAttribute: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FillConsoleOutputAttribute(%rip),%rax + jmp __sysv2nt6 + .endfn FillConsoleOutputAttribute,globl + .previous diff --git a/libc/nt/KernelBase/FillConsoleOutputCharacterA.s b/libc/nt/KernelBase/FillConsoleOutputCharacterA.s new file mode 100644 index 00000000..bddb7169 --- /dev/null +++ b/libc/nt/KernelBase/FillConsoleOutputCharacterA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FillConsoleOutputCharacterA,FillConsoleOutputCharacterA,355 + + .text.windows +FillConsoleOutputCharacterA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FillConsoleOutputCharacterA(%rip),%rax + jmp __sysv2nt6 + .endfn FillConsoleOutputCharacterA,globl + .previous diff --git a/libc/nt/KernelBase/FillConsoleOutputCharacterW.s b/libc/nt/KernelBase/FillConsoleOutputCharacterW.s new file mode 100644 index 00000000..a9119abe --- /dev/null +++ b/libc/nt/KernelBase/FillConsoleOutputCharacterW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FillConsoleOutputCharacterW,FillConsoleOutputCharacterW,356 + + .text.windows +FillConsoleOutputCharacter: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FillConsoleOutputCharacterW(%rip),%rax + jmp __sysv2nt6 + .endfn FillConsoleOutputCharacter,globl + .previous diff --git a/libc/nt/KernelBase/FindActCtxSectionGuid.s b/libc/nt/KernelBase/FindActCtxSectionGuid.s new file mode 100644 index 00000000..bccd06a1 --- /dev/null +++ b/libc/nt/KernelBase/FindActCtxSectionGuid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindActCtxSectionGuid,FindActCtxSectionGuid,357 diff --git a/libc/nt/KernelBase/FindActCtxSectionStringW.s b/libc/nt/KernelBase/FindActCtxSectionStringW.s new file mode 100644 index 00000000..160ecaa7 --- /dev/null +++ b/libc/nt/KernelBase/FindActCtxSectionStringW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindActCtxSectionStringW,FindActCtxSectionStringW,358 diff --git a/libc/nt/KernelBase/FindClose.s b/libc/nt/KernelBase/FindClose.s new file mode 100644 index 00000000..512d2dd8 --- /dev/null +++ b/libc/nt/KernelBase/FindClose.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindClose,FindClose,359 + + .text.windows +FindClose: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_FindClose(%rip) + leave + ret + .endfn FindClose,globl + .previous diff --git a/libc/nt/KernelBase/FindCloseChangeNotification.s b/libc/nt/KernelBase/FindCloseChangeNotification.s new file mode 100644 index 00000000..ac2a4135 --- /dev/null +++ b/libc/nt/KernelBase/FindCloseChangeNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindCloseChangeNotification,FindCloseChangeNotification,360 diff --git a/libc/nt/KernelBase/FindFirstChangeNotificationA.s b/libc/nt/KernelBase/FindFirstChangeNotificationA.s new file mode 100644 index 00000000..9d731918 --- /dev/null +++ b/libc/nt/KernelBase/FindFirstChangeNotificationA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindFirstChangeNotificationA,FindFirstChangeNotificationA,361 diff --git a/libc/nt/KernelBase/FindFirstChangeNotificationW.s b/libc/nt/KernelBase/FindFirstChangeNotificationW.s new file mode 100644 index 00000000..90282fd7 --- /dev/null +++ b/libc/nt/KernelBase/FindFirstChangeNotificationW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindFirstChangeNotificationW,FindFirstChangeNotificationW,362 diff --git a/libc/nt/KernelBase/FindFirstFileA.s b/libc/nt/KernelBase/FindFirstFileA.s new file mode 100644 index 00000000..52129045 --- /dev/null +++ b/libc/nt/KernelBase/FindFirstFileA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindFirstFileA,FindFirstFileA,363 + + .text.windows +FindFirstFileA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FindFirstFileA(%rip),%rax + jmp __sysv2nt + .endfn FindFirstFileA,globl + .previous diff --git a/libc/nt/KernelBase/FindFirstFileExA.s b/libc/nt/KernelBase/FindFirstFileExA.s new file mode 100644 index 00000000..5d8bd448 --- /dev/null +++ b/libc/nt/KernelBase/FindFirstFileExA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindFirstFileExA,FindFirstFileExA,364 + + .text.windows +FindFirstFileExA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FindFirstFileExA(%rip),%rax + jmp __sysv2nt6 + .endfn FindFirstFileExA,globl + .previous diff --git a/libc/nt/KernelBase/FindFirstFileExW.s b/libc/nt/KernelBase/FindFirstFileExW.s new file mode 100644 index 00000000..3e182dee --- /dev/null +++ b/libc/nt/KernelBase/FindFirstFileExW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindFirstFileExW,FindFirstFileExW,365 + + .text.windows +FindFirstFileEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FindFirstFileExW(%rip),%rax + jmp __sysv2nt6 + .endfn FindFirstFileEx,globl + .previous diff --git a/libc/nt/KernelBase/FindFirstFileNameW.s b/libc/nt/KernelBase/FindFirstFileNameW.s new file mode 100644 index 00000000..7511a231 --- /dev/null +++ b/libc/nt/KernelBase/FindFirstFileNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindFirstFileNameW,FindFirstFileNameW,366 diff --git a/libc/nt/KernelBase/FindFirstFileW.s b/libc/nt/KernelBase/FindFirstFileW.s new file mode 100644 index 00000000..c7c1b429 --- /dev/null +++ b/libc/nt/KernelBase/FindFirstFileW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindFirstFileW,FindFirstFileW,367 + + .text.windows +FindFirstFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FindFirstFileW(%rip),%rax + jmp __sysv2nt + .endfn FindFirstFile,globl + .previous diff --git a/libc/nt/KernelBase/FindFirstFreeAce.s b/libc/nt/KernelBase/FindFirstFreeAce.s new file mode 100644 index 00000000..7fb650c9 --- /dev/null +++ b/libc/nt/KernelBase/FindFirstFreeAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindFirstFreeAce,FindFirstFreeAce,368 diff --git a/libc/nt/KernelBase/FindFirstStreamW.s b/libc/nt/KernelBase/FindFirstStreamW.s new file mode 100644 index 00000000..f9f91b97 --- /dev/null +++ b/libc/nt/KernelBase/FindFirstStreamW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindFirstStreamW,FindFirstStreamW,369 diff --git a/libc/nt/KernelBase/FindFirstVolumeW.s b/libc/nt/KernelBase/FindFirstVolumeW.s new file mode 100644 index 00000000..f83b83af --- /dev/null +++ b/libc/nt/KernelBase/FindFirstVolumeW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindFirstVolumeW,FindFirstVolumeW,370 + + .text.windows +FindFirstVolume: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FindFirstVolumeW(%rip),%rax + jmp __sysv2nt + .endfn FindFirstVolume,globl + .previous diff --git a/libc/nt/KernelBase/FindNLSString.s b/libc/nt/KernelBase/FindNLSString.s new file mode 100644 index 00000000..5ac2fd29 --- /dev/null +++ b/libc/nt/KernelBase/FindNLSString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindNLSString,FindNLSString,371 diff --git a/libc/nt/KernelBase/FindNLSStringEx.s b/libc/nt/KernelBase/FindNLSStringEx.s new file mode 100644 index 00000000..129ff7a6 --- /dev/null +++ b/libc/nt/KernelBase/FindNLSStringEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindNLSStringEx,FindNLSStringEx,372 diff --git a/libc/nt/KernelBase/FindNextChangeNotification.s b/libc/nt/KernelBase/FindNextChangeNotification.s new file mode 100644 index 00000000..94e7943e --- /dev/null +++ b/libc/nt/KernelBase/FindNextChangeNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindNextChangeNotification,FindNextChangeNotification,373 diff --git a/libc/nt/KernelBase/FindNextFileA.s b/libc/nt/KernelBase/FindNextFileA.s new file mode 100644 index 00000000..3a8745c8 --- /dev/null +++ b/libc/nt/KernelBase/FindNextFileA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindNextFileA,FindNextFileA,374 + + .text.windows +FindNextFileA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FindNextFileA(%rip),%rax + jmp __sysv2nt + .endfn FindNextFileA,globl + .previous diff --git a/libc/nt/KernelBase/FindNextFileNameW.s b/libc/nt/KernelBase/FindNextFileNameW.s new file mode 100644 index 00000000..953b3b9d --- /dev/null +++ b/libc/nt/KernelBase/FindNextFileNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindNextFileNameW,FindNextFileNameW,375 diff --git a/libc/nt/KernelBase/FindNextFileW.s b/libc/nt/KernelBase/FindNextFileW.s new file mode 100644 index 00000000..934a1881 --- /dev/null +++ b/libc/nt/KernelBase/FindNextFileW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindNextFileW,FindNextFileW,376 + + .text.windows +FindNextFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FindNextFileW(%rip),%rax + jmp __sysv2nt + .endfn FindNextFile,globl + .previous diff --git a/libc/nt/KernelBase/FindNextStreamW.s b/libc/nt/KernelBase/FindNextStreamW.s new file mode 100644 index 00000000..851f9952 --- /dev/null +++ b/libc/nt/KernelBase/FindNextStreamW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindNextStreamW,FindNextStreamW,377 diff --git a/libc/nt/KernelBase/FindNextVolumeW.s b/libc/nt/KernelBase/FindNextVolumeW.s new file mode 100644 index 00000000..240d148c --- /dev/null +++ b/libc/nt/KernelBase/FindNextVolumeW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindNextVolumeW,FindNextVolumeW,378 + + .text.windows +FindNextVolume: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FindNextVolumeW(%rip),%rax + jmp __sysv2nt + .endfn FindNextVolume,globl + .previous diff --git a/libc/nt/KernelBase/FindPackagesByPackageFamily.s b/libc/nt/KernelBase/FindPackagesByPackageFamily.s new file mode 100644 index 00000000..06c2cb26 --- /dev/null +++ b/libc/nt/KernelBase/FindPackagesByPackageFamily.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindPackagesByPackageFamily,FindPackagesByPackageFamily,379 diff --git a/libc/nt/KernelBase/FindResourceExW.s b/libc/nt/KernelBase/FindResourceExW.s new file mode 100644 index 00000000..9b626cbc --- /dev/null +++ b/libc/nt/KernelBase/FindResourceExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindResourceExW,FindResourceExW,380 diff --git a/libc/nt/KernelBase/FindResourceW.s b/libc/nt/KernelBase/FindResourceW.s new file mode 100644 index 00000000..9cbad3cd --- /dev/null +++ b/libc/nt/KernelBase/FindResourceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindResourceW,FindResourceW,381 diff --git a/libc/nt/KernelBase/FindStringOrdinal.s b/libc/nt/KernelBase/FindStringOrdinal.s new file mode 100644 index 00000000..ccec9e5b --- /dev/null +++ b/libc/nt/KernelBase/FindStringOrdinal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindStringOrdinal,FindStringOrdinal,382 diff --git a/libc/nt/KernelBase/FindVolumeClose.s b/libc/nt/KernelBase/FindVolumeClose.s new file mode 100644 index 00000000..2c7ae147 --- /dev/null +++ b/libc/nt/KernelBase/FindVolumeClose.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FindVolumeClose,FindVolumeClose,383 + + .text.windows +FindVolumeClose: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_FindVolumeClose(%rip) + leave + ret + .endfn FindVolumeClose,globl + .previous diff --git a/libc/nt/KernelBase/FlsAlloc.s b/libc/nt/KernelBase/FlsAlloc.s new file mode 100644 index 00000000..0387e435 --- /dev/null +++ b/libc/nt/KernelBase/FlsAlloc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FlsAlloc,FlsAlloc,384 diff --git a/libc/nt/KernelBase/FlsFree.s b/libc/nt/KernelBase/FlsFree.s new file mode 100644 index 00000000..dd2c4f7f --- /dev/null +++ b/libc/nt/KernelBase/FlsFree.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FlsFree,FlsFree,385 diff --git a/libc/nt/KernelBase/FlsGetValue.s b/libc/nt/KernelBase/FlsGetValue.s new file mode 100644 index 00000000..6ca3340f --- /dev/null +++ b/libc/nt/KernelBase/FlsGetValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FlsGetValue,FlsGetValue,386 diff --git a/libc/nt/KernelBase/FlsSetValue.s b/libc/nt/KernelBase/FlsSetValue.s new file mode 100644 index 00000000..1cf92fbc --- /dev/null +++ b/libc/nt/KernelBase/FlsSetValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FlsSetValue,FlsSetValue,387 diff --git a/libc/nt/KernelBase/FlushConsoleInputBuffer.s b/libc/nt/KernelBase/FlushConsoleInputBuffer.s new file mode 100644 index 00000000..c2f8c990 --- /dev/null +++ b/libc/nt/KernelBase/FlushConsoleInputBuffer.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FlushConsoleInputBuffer,FlushConsoleInputBuffer,388 + + .text.windows +FlushConsoleInputBuffer: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_FlushConsoleInputBuffer(%rip) + leave + ret + .endfn FlushConsoleInputBuffer,globl + .previous diff --git a/libc/nt/KernelBase/FlushFileBuffers.s b/libc/nt/KernelBase/FlushFileBuffers.s new file mode 100644 index 00000000..00e67a69 --- /dev/null +++ b/libc/nt/KernelBase/FlushFileBuffers.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FlushFileBuffers,FlushFileBuffers,389 + + .text.windows +FlushFileBuffers: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_FlushFileBuffers(%rip) + leave + ret + .endfn FlushFileBuffers,globl + .previous diff --git a/libc/nt/KernelBase/FlushInstructionCache.s b/libc/nt/KernelBase/FlushInstructionCache.s new file mode 100644 index 00000000..c4867dd3 --- /dev/null +++ b/libc/nt/KernelBase/FlushInstructionCache.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FlushInstructionCache,FlushInstructionCache,390 diff --git a/libc/nt/KernelBase/FlushViewOfFile.s b/libc/nt/KernelBase/FlushViewOfFile.s new file mode 100644 index 00000000..f29cbe0f --- /dev/null +++ b/libc/nt/KernelBase/FlushViewOfFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FlushViewOfFile,FlushViewOfFile,392 + + .text.windows +FlushViewOfFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FlushViewOfFile(%rip),%rax + jmp __sysv2nt + .endfn FlushViewOfFile,globl + .previous diff --git a/libc/nt/KernelBase/FoldStringW.s b/libc/nt/KernelBase/FoldStringW.s new file mode 100644 index 00000000..f1f1d184 --- /dev/null +++ b/libc/nt/KernelBase/FoldStringW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FoldStringW,FoldStringW,393 diff --git a/libc/nt/KernelBase/ForceSyncFgPolicyInternal.s b/libc/nt/KernelBase/ForceSyncFgPolicyInternal.s new file mode 100644 index 00000000..e52eebd8 --- /dev/null +++ b/libc/nt/KernelBase/ForceSyncFgPolicyInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ForceSyncFgPolicyInternal,ForceSyncFgPolicyInternal,394 diff --git a/libc/nt/KernelBase/FormatApplicationUserModelId.s b/libc/nt/KernelBase/FormatApplicationUserModelId.s new file mode 100644 index 00000000..00b47f37 --- /dev/null +++ b/libc/nt/KernelBase/FormatApplicationUserModelId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FormatApplicationUserModelId,FormatApplicationUserModelId,395 diff --git a/libc/nt/KernelBase/FormatApplicationUserModelIdA.s b/libc/nt/KernelBase/FormatApplicationUserModelIdA.s new file mode 100644 index 00000000..8afa4059 --- /dev/null +++ b/libc/nt/KernelBase/FormatApplicationUserModelIdA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FormatApplicationUserModelIdA,FormatApplicationUserModelIdA,396 diff --git a/libc/nt/KernelBase/FormatMessageA.s b/libc/nt/KernelBase/FormatMessageA.s new file mode 100644 index 00000000..abc95425 --- /dev/null +++ b/libc/nt/KernelBase/FormatMessageA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FormatMessageA,FormatMessageA,397 + + .text.windows +FormatMessageA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FormatMessageA(%rip),%rax + jmp __sysv2nt8 + .endfn FormatMessageA,globl + .previous diff --git a/libc/nt/KernelBase/FormatMessageW.s b/libc/nt/KernelBase/FormatMessageW.s new file mode 100644 index 00000000..ecf2425d --- /dev/null +++ b/libc/nt/KernelBase/FormatMessageW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FormatMessageW,FormatMessageW,398 + + .text.windows +FormatMessage: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FormatMessageW(%rip),%rax + jmp __sysv2nt8 + .endfn FormatMessage,globl + .previous diff --git a/libc/nt/KernelBase/FreeConsole.s b/libc/nt/KernelBase/FreeConsole.s new file mode 100644 index 00000000..9bb26ebc --- /dev/null +++ b/libc/nt/KernelBase/FreeConsole.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FreeConsole,FreeConsole,399 + + .text.windows +FreeConsole: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_FreeConsole(%rip) + leave + ret + .endfn FreeConsole,globl + .previous diff --git a/libc/nt/KernelBase/FreeEnvironmentStringsA.s b/libc/nt/KernelBase/FreeEnvironmentStringsA.s new file mode 100644 index 00000000..3dea423f --- /dev/null +++ b/libc/nt/KernelBase/FreeEnvironmentStringsA.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FreeEnvironmentStringsA,FreeEnvironmentStringsA,400 + + .text.windows +FreeEnvironmentStringsA: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_FreeEnvironmentStringsA(%rip) + leave + ret + .endfn FreeEnvironmentStringsA,globl + .previous diff --git a/libc/nt/KernelBase/FreeEnvironmentStringsW.s b/libc/nt/KernelBase/FreeEnvironmentStringsW.s new file mode 100644 index 00000000..2cddbbe3 --- /dev/null +++ b/libc/nt/KernelBase/FreeEnvironmentStringsW.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FreeEnvironmentStringsW,FreeEnvironmentStringsW,401 + + .text.windows +FreeEnvironmentStrings: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_FreeEnvironmentStringsW(%rip) + leave + ret + .endfn FreeEnvironmentStrings,globl + .previous diff --git a/libc/nt/KernelBase/FreeGPOListInternalA.s b/libc/nt/KernelBase/FreeGPOListInternalA.s new file mode 100644 index 00000000..996ead4f --- /dev/null +++ b/libc/nt/KernelBase/FreeGPOListInternalA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FreeGPOListInternalA,FreeGPOListInternalA,402 diff --git a/libc/nt/KernelBase/FreeGPOListInternalW.s b/libc/nt/KernelBase/FreeGPOListInternalW.s new file mode 100644 index 00000000..4ff9cbe4 --- /dev/null +++ b/libc/nt/KernelBase/FreeGPOListInternalW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FreeGPOListInternalW,FreeGPOListInternalW,403 diff --git a/libc/nt/KernelBase/FreeLibrary.s b/libc/nt/KernelBase/FreeLibrary.s new file mode 100644 index 00000000..bc2265f5 --- /dev/null +++ b/libc/nt/KernelBase/FreeLibrary.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FreeLibrary,FreeLibrary,404 + + .text.windows +FreeLibrary: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_FreeLibrary(%rip) + leave + ret + .endfn FreeLibrary,globl + .previous diff --git a/libc/nt/KernelBase/FreeLibraryAndExitThread.s b/libc/nt/KernelBase/FreeLibraryAndExitThread.s new file mode 100644 index 00000000..09669b5c --- /dev/null +++ b/libc/nt/KernelBase/FreeLibraryAndExitThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FreeLibraryAndExitThread,FreeLibraryAndExitThread,405 diff --git a/libc/nt/KernelBase/FreeResource.s b/libc/nt/KernelBase/FreeResource.s new file mode 100644 index 00000000..76bdbfb5 --- /dev/null +++ b/libc/nt/KernelBase/FreeResource.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FreeResource,FreeResource,407 + + .text.windows +FreeResource: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_FreeResource(%rip) + leave + ret + .endfn FreeResource,globl + .previous diff --git a/libc/nt/KernelBase/FreeSid.s b/libc/nt/KernelBase/FreeSid.s new file mode 100644 index 00000000..2c71cb88 --- /dev/null +++ b/libc/nt/KernelBase/FreeSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FreeSid,FreeSid,408 diff --git a/libc/nt/KernelBase/FreeUserPhysicalPages.s b/libc/nt/KernelBase/FreeUserPhysicalPages.s new file mode 100644 index 00000000..400984ce --- /dev/null +++ b/libc/nt/KernelBase/FreeUserPhysicalPages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_FreeUserPhysicalPages,FreeUserPhysicalPages,409 diff --git a/libc/nt/KernelBase/GenerateConsoleCtrlEvent.s b/libc/nt/KernelBase/GenerateConsoleCtrlEvent.s new file mode 100644 index 00000000..82894850 --- /dev/null +++ b/libc/nt/KernelBase/GenerateConsoleCtrlEvent.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GenerateConsoleCtrlEvent,GenerateConsoleCtrlEvent,410 + + .text.windows +GenerateConsoleCtrlEvent: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GenerateConsoleCtrlEvent(%rip),%rax + jmp __sysv2nt + .endfn GenerateConsoleCtrlEvent,globl + .previous diff --git a/libc/nt/KernelBase/GenerateGPNotificationInternal.s b/libc/nt/KernelBase/GenerateGPNotificationInternal.s new file mode 100644 index 00000000..18896e78 --- /dev/null +++ b/libc/nt/KernelBase/GenerateGPNotificationInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GenerateGPNotificationInternal,GenerateGPNotificationInternal,411 diff --git a/libc/nt/KernelBase/GetACP.s b/libc/nt/KernelBase/GetACP.s new file mode 100644 index 00000000..f580cb19 --- /dev/null +++ b/libc/nt/KernelBase/GetACP.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetACP,GetACP,412 diff --git a/libc/nt/KernelBase/GetAcceptLanguagesA.s b/libc/nt/KernelBase/GetAcceptLanguagesA.s new file mode 100644 index 00000000..91064035 --- /dev/null +++ b/libc/nt/KernelBase/GetAcceptLanguagesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetAcceptLanguagesA,GetAcceptLanguagesA,413 diff --git a/libc/nt/KernelBase/GetAcceptLanguagesW.s b/libc/nt/KernelBase/GetAcceptLanguagesW.s new file mode 100644 index 00000000..7ac2a93d --- /dev/null +++ b/libc/nt/KernelBase/GetAcceptLanguagesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetAcceptLanguagesW,GetAcceptLanguagesW,414 diff --git a/libc/nt/KernelBase/GetAce.s b/libc/nt/KernelBase/GetAce.s new file mode 100644 index 00000000..75f877a6 --- /dev/null +++ b/libc/nt/KernelBase/GetAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetAce,GetAce,415 diff --git a/libc/nt/KernelBase/GetAclInformation.s b/libc/nt/KernelBase/GetAclInformation.s new file mode 100644 index 00000000..be0a42ad --- /dev/null +++ b/libc/nt/KernelBase/GetAclInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetAclInformation,GetAclInformation,416 diff --git a/libc/nt/KernelBase/GetAdjustObjectAttributesForPrivateNamespaceRoutine.s b/libc/nt/KernelBase/GetAdjustObjectAttributesForPrivateNamespaceRoutine.s new file mode 100644 index 00000000..3ed90b0d --- /dev/null +++ b/libc/nt/KernelBase/GetAdjustObjectAttributesForPrivateNamespaceRoutine.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetAdjustObjectAttributesForPrivateNamespaceRoutine,GetAdjustObjectAttributesForPrivateNamespaceRoutine,417 diff --git a/libc/nt/KernelBase/GetAlternatePackageRoots.s b/libc/nt/KernelBase/GetAlternatePackageRoots.s new file mode 100644 index 00000000..b13e06fd --- /dev/null +++ b/libc/nt/KernelBase/GetAlternatePackageRoots.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetAlternatePackageRoots,GetAlternatePackageRoots,418 diff --git a/libc/nt/KernelBase/GetAppContainerAce.s b/libc/nt/KernelBase/GetAppContainerAce.s new file mode 100644 index 00000000..f2a12af9 --- /dev/null +++ b/libc/nt/KernelBase/GetAppContainerAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetAppContainerAce,GetAppContainerAce,419 diff --git a/libc/nt/KernelBase/GetAppContainerNamedObjectPath.s b/libc/nt/KernelBase/GetAppContainerNamedObjectPath.s new file mode 100644 index 00000000..49e5c107 --- /dev/null +++ b/libc/nt/KernelBase/GetAppContainerNamedObjectPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetAppContainerNamedObjectPath,GetAppContainerNamedObjectPath,420 diff --git a/libc/nt/KernelBase/GetAppDataFolder.s b/libc/nt/KernelBase/GetAppDataFolder.s new file mode 100644 index 00000000..45cfef21 --- /dev/null +++ b/libc/nt/KernelBase/GetAppDataFolder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetAppDataFolder,GetAppDataFolder,421 diff --git a/libc/nt/KernelBase/GetAppModelVersion.s b/libc/nt/KernelBase/GetAppModelVersion.s new file mode 100644 index 00000000..f4967a52 --- /dev/null +++ b/libc/nt/KernelBase/GetAppModelVersion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetAppModelVersion,GetAppModelVersion,422 diff --git a/libc/nt/KernelBase/GetApplicationRecoveryCallback.s b/libc/nt/KernelBase/GetApplicationRecoveryCallback.s new file mode 100644 index 00000000..d186dbd3 --- /dev/null +++ b/libc/nt/KernelBase/GetApplicationRecoveryCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetApplicationRecoveryCallback,GetApplicationRecoveryCallback,423 diff --git a/libc/nt/KernelBase/GetApplicationRestartSettings.s b/libc/nt/KernelBase/GetApplicationRestartSettings.s new file mode 100644 index 00000000..4e838974 --- /dev/null +++ b/libc/nt/KernelBase/GetApplicationRestartSettings.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetApplicationRestartSettings,GetApplicationRestartSettings,424 diff --git a/libc/nt/KernelBase/GetApplicationUserModelId.s b/libc/nt/KernelBase/GetApplicationUserModelId.s new file mode 100644 index 00000000..baf1333c --- /dev/null +++ b/libc/nt/KernelBase/GetApplicationUserModelId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetApplicationUserModelId,GetApplicationUserModelId,425 diff --git a/libc/nt/KernelBase/GetApplicationUserModelIdFromToken.s b/libc/nt/KernelBase/GetApplicationUserModelIdFromToken.s new file mode 100644 index 00000000..1a65f8d8 --- /dev/null +++ b/libc/nt/KernelBase/GetApplicationUserModelIdFromToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetApplicationUserModelIdFromToken,GetApplicationUserModelIdFromToken,426 diff --git a/libc/nt/KernelBase/GetAppliedGPOListInternalA.s b/libc/nt/KernelBase/GetAppliedGPOListInternalA.s new file mode 100644 index 00000000..51eccbbf --- /dev/null +++ b/libc/nt/KernelBase/GetAppliedGPOListInternalA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetAppliedGPOListInternalA,GetAppliedGPOListInternalA,427 diff --git a/libc/nt/KernelBase/GetAppliedGPOListInternalW.s b/libc/nt/KernelBase/GetAppliedGPOListInternalW.s new file mode 100644 index 00000000..e1fe077c --- /dev/null +++ b/libc/nt/KernelBase/GetAppliedGPOListInternalW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetAppliedGPOListInternalW,GetAppliedGPOListInternalW,428 diff --git a/libc/nt/KernelBase/GetCPFileNameFromRegistry.s b/libc/nt/KernelBase/GetCPFileNameFromRegistry.s new file mode 100644 index 00000000..a26b217f --- /dev/null +++ b/libc/nt/KernelBase/GetCPFileNameFromRegistry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCPFileNameFromRegistry,GetCPFileNameFromRegistry,429 diff --git a/libc/nt/KernelBase/GetCPHashNode.s b/libc/nt/KernelBase/GetCPHashNode.s new file mode 100644 index 00000000..32f01e19 --- /dev/null +++ b/libc/nt/KernelBase/GetCPHashNode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCPHashNode,GetCPHashNode,430 diff --git a/libc/nt/KernelBase/GetCPInfo.s b/libc/nt/KernelBase/GetCPInfo.s new file mode 100644 index 00000000..7888816e --- /dev/null +++ b/libc/nt/KernelBase/GetCPInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCPInfo,GetCPInfo,431 diff --git a/libc/nt/KernelBase/GetCPInfoExW.s b/libc/nt/KernelBase/GetCPInfoExW.s new file mode 100644 index 00000000..d12a2996 --- /dev/null +++ b/libc/nt/KernelBase/GetCPInfoExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCPInfoExW,GetCPInfoExW,432 diff --git a/libc/nt/KernelBase/GetCachedSigningLevel.s b/libc/nt/KernelBase/GetCachedSigningLevel.s new file mode 100644 index 00000000..30a7ca5e --- /dev/null +++ b/libc/nt/KernelBase/GetCachedSigningLevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCachedSigningLevel,GetCachedSigningLevel,433 diff --git a/libc/nt/KernelBase/GetCalendar.s b/libc/nt/KernelBase/GetCalendar.s new file mode 100644 index 00000000..2876137e --- /dev/null +++ b/libc/nt/KernelBase/GetCalendar.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCalendar,GetCalendar,434 diff --git a/libc/nt/KernelBase/GetCalendarInfoEx.s b/libc/nt/KernelBase/GetCalendarInfoEx.s new file mode 100644 index 00000000..4e4cfe12 --- /dev/null +++ b/libc/nt/KernelBase/GetCalendarInfoEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCalendarInfoEx,GetCalendarInfoEx,435 diff --git a/libc/nt/KernelBase/GetCalendarInfoW.s b/libc/nt/KernelBase/GetCalendarInfoW.s new file mode 100644 index 00000000..ae96e01e --- /dev/null +++ b/libc/nt/KernelBase/GetCalendarInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCalendarInfoW,GetCalendarInfoW,436 diff --git a/libc/nt/KernelBase/GetCommConfig.s b/libc/nt/KernelBase/GetCommConfig.s new file mode 100644 index 00000000..55f7d46a --- /dev/null +++ b/libc/nt/KernelBase/GetCommConfig.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCommConfig,GetCommConfig,437 diff --git a/libc/nt/KernelBase/GetCommMask.s b/libc/nt/KernelBase/GetCommMask.s new file mode 100644 index 00000000..a4229793 --- /dev/null +++ b/libc/nt/KernelBase/GetCommMask.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCommMask,GetCommMask,438 diff --git a/libc/nt/KernelBase/GetCommModemStatus.s b/libc/nt/KernelBase/GetCommModemStatus.s new file mode 100644 index 00000000..8e6caacc --- /dev/null +++ b/libc/nt/KernelBase/GetCommModemStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCommModemStatus,GetCommModemStatus,439 diff --git a/libc/nt/KernelBase/GetCommPorts.s b/libc/nt/KernelBase/GetCommPorts.s new file mode 100644 index 00000000..d31f6505 --- /dev/null +++ b/libc/nt/KernelBase/GetCommPorts.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCommPorts,GetCommPorts,440 diff --git a/libc/nt/KernelBase/GetCommProperties.s b/libc/nt/KernelBase/GetCommProperties.s new file mode 100644 index 00000000..6a263f53 --- /dev/null +++ b/libc/nt/KernelBase/GetCommProperties.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCommProperties,GetCommProperties,441 diff --git a/libc/nt/KernelBase/GetCommState.s b/libc/nt/KernelBase/GetCommState.s new file mode 100644 index 00000000..897ad0c4 --- /dev/null +++ b/libc/nt/KernelBase/GetCommState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCommState,GetCommState,442 diff --git a/libc/nt/KernelBase/GetCommTimeouts.s b/libc/nt/KernelBase/GetCommTimeouts.s new file mode 100644 index 00000000..689bcabc --- /dev/null +++ b/libc/nt/KernelBase/GetCommTimeouts.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCommTimeouts,GetCommTimeouts,443 diff --git a/libc/nt/KernelBase/GetCommandLineA.s b/libc/nt/KernelBase/GetCommandLineA.s new file mode 100644 index 00000000..7a7bbf21 --- /dev/null +++ b/libc/nt/KernelBase/GetCommandLineA.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCommandLineA,GetCommandLineA,444 + + .text.windows +GetCommandLineA: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_GetCommandLineA(%rip) + leave + ret + .endfn GetCommandLineA,globl + .previous diff --git a/libc/nt/KernelBase/GetCommandLineW.s b/libc/nt/KernelBase/GetCommandLineW.s new file mode 100644 index 00000000..b210c7d5 --- /dev/null +++ b/libc/nt/KernelBase/GetCommandLineW.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCommandLineW,GetCommandLineW,445 + + .text.windows +GetCommandLine: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_GetCommandLineW(%rip) + leave + ret + .endfn GetCommandLine,globl + .previous diff --git a/libc/nt/KernelBase/GetCompressedFileSizeA.s b/libc/nt/KernelBase/GetCompressedFileSizeA.s new file mode 100644 index 00000000..744f6393 --- /dev/null +++ b/libc/nt/KernelBase/GetCompressedFileSizeA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCompressedFileSizeA,GetCompressedFileSizeA,446 + + .text.windows +GetCompressedFileSizeA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetCompressedFileSizeA(%rip),%rax + jmp __sysv2nt + .endfn GetCompressedFileSizeA,globl + .previous diff --git a/libc/nt/KernelBase/GetCompressedFileSizeW.s b/libc/nt/KernelBase/GetCompressedFileSizeW.s new file mode 100644 index 00000000..fee74803 --- /dev/null +++ b/libc/nt/KernelBase/GetCompressedFileSizeW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCompressedFileSizeW,GetCompressedFileSizeW,447 + + .text.windows +GetCompressedFileSize: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetCompressedFileSizeW(%rip),%rax + jmp __sysv2nt + .endfn GetCompressedFileSize,globl + .previous diff --git a/libc/nt/KernelBase/GetComputerNameExA.s b/libc/nt/KernelBase/GetComputerNameExA.s new file mode 100644 index 00000000..8e705803 --- /dev/null +++ b/libc/nt/KernelBase/GetComputerNameExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetComputerNameExA,GetComputerNameExA,448 diff --git a/libc/nt/KernelBase/GetComputerNameExW.s b/libc/nt/KernelBase/GetComputerNameExW.s new file mode 100644 index 00000000..05bea6ac --- /dev/null +++ b/libc/nt/KernelBase/GetComputerNameExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetComputerNameExW,GetComputerNameExW,449 diff --git a/libc/nt/KernelBase/GetConsoleAliasA.s b/libc/nt/KernelBase/GetConsoleAliasA.s new file mode 100644 index 00000000..155a4168 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleAliasA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleAliasA,GetConsoleAliasA,450 diff --git a/libc/nt/KernelBase/GetConsoleAliasExesA.s b/libc/nt/KernelBase/GetConsoleAliasExesA.s new file mode 100644 index 00000000..7c2506ff --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleAliasExesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleAliasExesA,GetConsoleAliasExesA,451 diff --git a/libc/nt/KernelBase/GetConsoleAliasExesLengthA.s b/libc/nt/KernelBase/GetConsoleAliasExesLengthA.s new file mode 100644 index 00000000..bd000728 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleAliasExesLengthA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleAliasExesLengthA,GetConsoleAliasExesLengthA,452 diff --git a/libc/nt/KernelBase/GetConsoleAliasExesLengthW.s b/libc/nt/KernelBase/GetConsoleAliasExesLengthW.s new file mode 100644 index 00000000..bdaeda45 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleAliasExesLengthW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleAliasExesLengthW,GetConsoleAliasExesLengthW,453 diff --git a/libc/nt/KernelBase/GetConsoleAliasExesW.s b/libc/nt/KernelBase/GetConsoleAliasExesW.s new file mode 100644 index 00000000..772e65ca --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleAliasExesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleAliasExesW,GetConsoleAliasExesW,454 diff --git a/libc/nt/KernelBase/GetConsoleAliasW.s b/libc/nt/KernelBase/GetConsoleAliasW.s new file mode 100644 index 00000000..6ae90ecb --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleAliasW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleAliasW,GetConsoleAliasW,455 diff --git a/libc/nt/KernelBase/GetConsoleAliasesA.s b/libc/nt/KernelBase/GetConsoleAliasesA.s new file mode 100644 index 00000000..e23b48b9 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleAliasesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleAliasesA,GetConsoleAliasesA,456 diff --git a/libc/nt/KernelBase/GetConsoleAliasesLengthA.s b/libc/nt/KernelBase/GetConsoleAliasesLengthA.s new file mode 100644 index 00000000..9f5dbc00 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleAliasesLengthA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleAliasesLengthA,GetConsoleAliasesLengthA,457 diff --git a/libc/nt/KernelBase/GetConsoleAliasesLengthW.s b/libc/nt/KernelBase/GetConsoleAliasesLengthW.s new file mode 100644 index 00000000..611b8389 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleAliasesLengthW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleAliasesLengthW,GetConsoleAliasesLengthW,458 diff --git a/libc/nt/KernelBase/GetConsoleAliasesW.s b/libc/nt/KernelBase/GetConsoleAliasesW.s new file mode 100644 index 00000000..fe706f5b --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleAliasesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleAliasesW,GetConsoleAliasesW,459 diff --git a/libc/nt/KernelBase/GetConsoleCP.s b/libc/nt/KernelBase/GetConsoleCP.s new file mode 100644 index 00000000..cf46b222 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleCP.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleCP,GetConsoleCP,460 + + .text.windows +GetConsoleCP: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_GetConsoleCP(%rip) + leave + ret + .endfn GetConsoleCP,globl + .previous diff --git a/libc/nt/KernelBase/GetConsoleCommandHistoryA.s b/libc/nt/KernelBase/GetConsoleCommandHistoryA.s new file mode 100644 index 00000000..9bafb968 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleCommandHistoryA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleCommandHistoryA,GetConsoleCommandHistoryA,461 diff --git a/libc/nt/KernelBase/GetConsoleCommandHistoryLengthA.s b/libc/nt/KernelBase/GetConsoleCommandHistoryLengthA.s new file mode 100644 index 00000000..591d2040 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleCommandHistoryLengthA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleCommandHistoryLengthA,GetConsoleCommandHistoryLengthA,462 diff --git a/libc/nt/KernelBase/GetConsoleCommandHistoryLengthW.s b/libc/nt/KernelBase/GetConsoleCommandHistoryLengthW.s new file mode 100644 index 00000000..4c35dbc3 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleCommandHistoryLengthW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleCommandHistoryLengthW,GetConsoleCommandHistoryLengthW,463 diff --git a/libc/nt/KernelBase/GetConsoleCommandHistoryW.s b/libc/nt/KernelBase/GetConsoleCommandHistoryW.s new file mode 100644 index 00000000..e8f47077 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleCommandHistoryW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleCommandHistoryW,GetConsoleCommandHistoryW,464 diff --git a/libc/nt/KernelBase/GetConsoleCursorInfo.s b/libc/nt/KernelBase/GetConsoleCursorInfo.s new file mode 100644 index 00000000..78f2bfa0 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleCursorInfo.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleCursorInfo,GetConsoleCursorInfo,465 + + .text.windows +GetConsoleCursorInfo: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetConsoleCursorInfo(%rip),%rax + jmp __sysv2nt + .endfn GetConsoleCursorInfo,globl + .previous diff --git a/libc/nt/KernelBase/GetConsoleDisplayMode.s b/libc/nt/KernelBase/GetConsoleDisplayMode.s new file mode 100644 index 00000000..d7e86932 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleDisplayMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleDisplayMode,GetConsoleDisplayMode,466 diff --git a/libc/nt/KernelBase/GetConsoleFontSize.s b/libc/nt/KernelBase/GetConsoleFontSize.s new file mode 100644 index 00000000..7c2acc41 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleFontSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleFontSize,GetConsoleFontSize,467 diff --git a/libc/nt/KernelBase/GetConsoleHistoryInfo.s b/libc/nt/KernelBase/GetConsoleHistoryInfo.s new file mode 100644 index 00000000..eb01b5bb --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleHistoryInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleHistoryInfo,GetConsoleHistoryInfo,468 diff --git a/libc/nt/KernelBase/GetConsoleInputExeNameA.s b/libc/nt/KernelBase/GetConsoleInputExeNameA.s new file mode 100644 index 00000000..ac1f6768 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleInputExeNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleInputExeNameA,GetConsoleInputExeNameA,469 diff --git a/libc/nt/KernelBase/GetConsoleInputExeNameW.s b/libc/nt/KernelBase/GetConsoleInputExeNameW.s new file mode 100644 index 00000000..b317041c --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleInputExeNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleInputExeNameW,GetConsoleInputExeNameW,470 diff --git a/libc/nt/KernelBase/GetConsoleMode.s b/libc/nt/KernelBase/GetConsoleMode.s new file mode 100644 index 00000000..17ed20a3 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleMode.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleMode,GetConsoleMode,471 + + .text.windows +GetConsoleMode: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetConsoleMode(%rip),%rax + jmp __sysv2nt + .endfn GetConsoleMode,globl + .previous diff --git a/libc/nt/KernelBase/GetConsoleOriginalTitleA.s b/libc/nt/KernelBase/GetConsoleOriginalTitleA.s new file mode 100644 index 00000000..f2c1196c --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleOriginalTitleA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleOriginalTitleA,GetConsoleOriginalTitleA,472 diff --git a/libc/nt/KernelBase/GetConsoleOriginalTitleW.s b/libc/nt/KernelBase/GetConsoleOriginalTitleW.s new file mode 100644 index 00000000..df0c16d0 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleOriginalTitleW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleOriginalTitleW,GetConsoleOriginalTitleW,473 diff --git a/libc/nt/KernelBase/GetConsoleOutputCP.s b/libc/nt/KernelBase/GetConsoleOutputCP.s new file mode 100644 index 00000000..50de17c0 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleOutputCP.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleOutputCP,GetConsoleOutputCP,474 + + .text.windows +GetConsoleOutputCP: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_GetConsoleOutputCP(%rip) + leave + ret + .endfn GetConsoleOutputCP,globl + .previous diff --git a/libc/nt/KernelBase/GetConsoleProcessList.s b/libc/nt/KernelBase/GetConsoleProcessList.s new file mode 100644 index 00000000..e7d3c420 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleProcessList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleProcessList,GetConsoleProcessList,475 diff --git a/libc/nt/KernelBase/GetConsoleScreenBufferInfo.s b/libc/nt/KernelBase/GetConsoleScreenBufferInfo.s new file mode 100644 index 00000000..08f044c5 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleScreenBufferInfo.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleScreenBufferInfo,GetConsoleScreenBufferInfo,476 + + .text.windows +GetConsoleScreenBufferInfo: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetConsoleScreenBufferInfo(%rip),%rax + jmp __sysv2nt + .endfn GetConsoleScreenBufferInfo,globl + .previous diff --git a/libc/nt/KernelBase/GetConsoleScreenBufferInfoEx.s b/libc/nt/KernelBase/GetConsoleScreenBufferInfoEx.s new file mode 100644 index 00000000..12585e0d --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleScreenBufferInfoEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleScreenBufferInfoEx,GetConsoleScreenBufferInfoEx,477 + + .text.windows +GetConsoleScreenBufferInfoEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetConsoleScreenBufferInfoEx(%rip),%rax + jmp __sysv2nt + .endfn GetConsoleScreenBufferInfoEx,globl + .previous diff --git a/libc/nt/KernelBase/GetConsoleSelectionInfo.s b/libc/nt/KernelBase/GetConsoleSelectionInfo.s new file mode 100644 index 00000000..9acb6455 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleSelectionInfo.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleSelectionInfo,GetConsoleSelectionInfo,478 + + .text.windows +GetConsoleSelectionInfo: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetConsoleSelectionInfo(%rip) + leave + ret + .endfn GetConsoleSelectionInfo,globl + .previous diff --git a/libc/nt/KernelBase/GetConsoleTitleA.s b/libc/nt/KernelBase/GetConsoleTitleA.s new file mode 100644 index 00000000..eb53c359 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleTitleA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleTitleA,GetConsoleTitleA,479 + + .text.windows +GetConsoleTitleA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetConsoleTitleA(%rip),%rax + jmp __sysv2nt + .endfn GetConsoleTitleA,globl + .previous diff --git a/libc/nt/KernelBase/GetConsoleTitleW.s b/libc/nt/KernelBase/GetConsoleTitleW.s new file mode 100644 index 00000000..3465efd4 --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleTitleW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleTitleW,GetConsoleTitleW,480 diff --git a/libc/nt/KernelBase/GetConsoleWindow.s b/libc/nt/KernelBase/GetConsoleWindow.s new file mode 100644 index 00000000..c65f950f --- /dev/null +++ b/libc/nt/KernelBase/GetConsoleWindow.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetConsoleWindow,GetConsoleWindow,481 + + .text.windows +GetConsoleWindow: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_GetConsoleWindow(%rip) + leave + ret + .endfn GetConsoleWindow,globl + .previous diff --git a/libc/nt/KernelBase/GetCurrencyFormatEx.s b/libc/nt/KernelBase/GetCurrencyFormatEx.s new file mode 100644 index 00000000..601d84da --- /dev/null +++ b/libc/nt/KernelBase/GetCurrencyFormatEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrencyFormatEx,GetCurrencyFormatEx,482 diff --git a/libc/nt/KernelBase/GetCurrencyFormatW.s b/libc/nt/KernelBase/GetCurrencyFormatW.s new file mode 100644 index 00000000..cc4ec750 --- /dev/null +++ b/libc/nt/KernelBase/GetCurrencyFormatW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrencyFormatW,GetCurrencyFormatW,483 diff --git a/libc/nt/KernelBase/GetCurrentActCtx.s b/libc/nt/KernelBase/GetCurrentActCtx.s new file mode 100644 index 00000000..9f566cfb --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentActCtx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentActCtx,GetCurrentActCtx,484 diff --git a/libc/nt/KernelBase/GetCurrentApplicationUserModelId.s b/libc/nt/KernelBase/GetCurrentApplicationUserModelId.s new file mode 100644 index 00000000..07c7ed2e --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentApplicationUserModelId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentApplicationUserModelId,GetCurrentApplicationUserModelId,485 diff --git a/libc/nt/KernelBase/GetCurrentConsoleFont.s b/libc/nt/KernelBase/GetCurrentConsoleFont.s new file mode 100644 index 00000000..febe6157 --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentConsoleFont.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentConsoleFont,GetCurrentConsoleFont,486 diff --git a/libc/nt/KernelBase/GetCurrentConsoleFontEx.s b/libc/nt/KernelBase/GetCurrentConsoleFontEx.s new file mode 100644 index 00000000..c79aacfd --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentConsoleFontEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentConsoleFontEx,GetCurrentConsoleFontEx,487 diff --git a/libc/nt/KernelBase/GetCurrentDirectoryA.s b/libc/nt/KernelBase/GetCurrentDirectoryA.s new file mode 100644 index 00000000..783cad7a --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentDirectoryA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentDirectoryA,GetCurrentDirectoryA,488 + + .text.windows +GetCurrentDirectoryA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetCurrentDirectoryA(%rip),%rax + jmp __sysv2nt + .endfn GetCurrentDirectoryA,globl + .previous diff --git a/libc/nt/KernelBase/GetCurrentDirectoryW.s b/libc/nt/KernelBase/GetCurrentDirectoryW.s new file mode 100644 index 00000000..237e5dd1 --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentDirectoryW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentDirectoryW,GetCurrentDirectoryW,489 + + .text.windows +GetCurrentDirectory: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetCurrentDirectoryW(%rip),%rax + jmp __sysv2nt + .endfn GetCurrentDirectory,globl + .previous diff --git a/libc/nt/KernelBase/GetCurrentPackageApplicationContext.s b/libc/nt/KernelBase/GetCurrentPackageApplicationContext.s new file mode 100644 index 00000000..00f0659e --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentPackageApplicationContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentPackageApplicationContext,GetCurrentPackageApplicationContext,490 diff --git a/libc/nt/KernelBase/GetCurrentPackageApplicationResourcesContext.s b/libc/nt/KernelBase/GetCurrentPackageApplicationResourcesContext.s new file mode 100644 index 00000000..2f5d6be7 --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentPackageApplicationResourcesContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentPackageApplicationResourcesContext,GetCurrentPackageApplicationResourcesContext,491 diff --git a/libc/nt/KernelBase/GetCurrentPackageContext.s b/libc/nt/KernelBase/GetCurrentPackageContext.s new file mode 100644 index 00000000..2ad2740d --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentPackageContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentPackageContext,GetCurrentPackageContext,492 diff --git a/libc/nt/KernelBase/GetCurrentPackageFamilyName.s b/libc/nt/KernelBase/GetCurrentPackageFamilyName.s new file mode 100644 index 00000000..4add0c71 --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentPackageFamilyName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentPackageFamilyName,GetCurrentPackageFamilyName,493 diff --git a/libc/nt/KernelBase/GetCurrentPackageFullName.s b/libc/nt/KernelBase/GetCurrentPackageFullName.s new file mode 100644 index 00000000..11004879 --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentPackageFullName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentPackageFullName,GetCurrentPackageFullName,494 diff --git a/libc/nt/KernelBase/GetCurrentPackageId.s b/libc/nt/KernelBase/GetCurrentPackageId.s new file mode 100644 index 00000000..40b93581 --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentPackageId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentPackageId,GetCurrentPackageId,495 diff --git a/libc/nt/KernelBase/GetCurrentPackageInfo.s b/libc/nt/KernelBase/GetCurrentPackageInfo.s new file mode 100644 index 00000000..53d6b201 --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentPackageInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentPackageInfo,GetCurrentPackageInfo,496 diff --git a/libc/nt/KernelBase/GetCurrentPackagePath.s b/libc/nt/KernelBase/GetCurrentPackagePath.s new file mode 100644 index 00000000..8bd1454e --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentPackagePath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentPackagePath,GetCurrentPackagePath,497 diff --git a/libc/nt/KernelBase/GetCurrentPackageResourcesContext.s b/libc/nt/KernelBase/GetCurrentPackageResourcesContext.s new file mode 100644 index 00000000..5e3dbc74 --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentPackageResourcesContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentPackageResourcesContext,GetCurrentPackageResourcesContext,498 diff --git a/libc/nt/KernelBase/GetCurrentPackageSecurityContext.s b/libc/nt/KernelBase/GetCurrentPackageSecurityContext.s new file mode 100644 index 00000000..0b109d6f --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentPackageSecurityContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentPackageSecurityContext,GetCurrentPackageSecurityContext,499 diff --git a/libc/nt/KernelBase/GetCurrentProcess.s b/libc/nt/KernelBase/GetCurrentProcess.s new file mode 100644 index 00000000..c0953be5 --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentProcess.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentProcess,GetCurrentProcess,500 + + .text.windows +GetCurrentProcess: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_GetCurrentProcess(%rip) + leave + ret + .endfn GetCurrentProcess,globl + .previous diff --git a/libc/nt/KernelBase/GetCurrentProcessId.s b/libc/nt/KernelBase/GetCurrentProcessId.s new file mode 100644 index 00000000..a1488dc5 --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentProcessId.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentProcessId,GetCurrentProcessId,501 + + .text.windows +GetCurrentProcessId: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_GetCurrentProcessId(%rip) + leave + ret + .endfn GetCurrentProcessId,globl + .previous diff --git a/libc/nt/KernelBase/GetCurrentTargetPlatformContext.s b/libc/nt/KernelBase/GetCurrentTargetPlatformContext.s new file mode 100644 index 00000000..ccaf6858 --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentTargetPlatformContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentTargetPlatformContext,GetCurrentTargetPlatformContext,504 diff --git a/libc/nt/KernelBase/GetCurrentThread.s b/libc/nt/KernelBase/GetCurrentThread.s new file mode 100644 index 00000000..d33418c4 --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentThread.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentThread,GetCurrentThread,505 + + .text.windows +GetCurrentThread: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_GetCurrentThread(%rip) + leave + ret + .endfn GetCurrentThread,globl + .previous diff --git a/libc/nt/KernelBase/GetCurrentThreadId.s b/libc/nt/KernelBase/GetCurrentThreadId.s new file mode 100644 index 00000000..978a8b94 --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentThreadId.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentThreadId,GetCurrentThreadId,506 + + .text.windows +GetCurrentThreadId: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_GetCurrentThreadId(%rip) + leave + ret + .endfn GetCurrentThreadId,globl + .previous diff --git a/libc/nt/KernelBase/GetCurrentThreadStackLimits.s b/libc/nt/KernelBase/GetCurrentThreadStackLimits.s new file mode 100644 index 00000000..f6b41c4a --- /dev/null +++ b/libc/nt/KernelBase/GetCurrentThreadStackLimits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetCurrentThreadStackLimits,GetCurrentThreadStackLimits,507 diff --git a/libc/nt/KernelBase/GetDateFormatA.s b/libc/nt/KernelBase/GetDateFormatA.s new file mode 100644 index 00000000..54b42ff3 --- /dev/null +++ b/libc/nt/KernelBase/GetDateFormatA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetDateFormatA,GetDateFormatA,508 diff --git a/libc/nt/KernelBase/GetDateFormatEx.s b/libc/nt/KernelBase/GetDateFormatEx.s new file mode 100644 index 00000000..2a8d3273 --- /dev/null +++ b/libc/nt/KernelBase/GetDateFormatEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetDateFormatEx,GetDateFormatEx,509 diff --git a/libc/nt/KernelBase/GetDateFormatW.s b/libc/nt/KernelBase/GetDateFormatW.s new file mode 100644 index 00000000..466205a8 --- /dev/null +++ b/libc/nt/KernelBase/GetDateFormatW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetDateFormatW,GetDateFormatW,510 diff --git a/libc/nt/KernelBase/GetDeviceDriverBaseNameA.s b/libc/nt/KernelBase/GetDeviceDriverBaseNameA.s new file mode 100644 index 00000000..df048606 --- /dev/null +++ b/libc/nt/KernelBase/GetDeviceDriverBaseNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetDeviceDriverBaseNameA,GetDeviceDriverBaseNameA,511 diff --git a/libc/nt/KernelBase/GetDeviceDriverBaseNameW.s b/libc/nt/KernelBase/GetDeviceDriverBaseNameW.s new file mode 100644 index 00000000..1908f188 --- /dev/null +++ b/libc/nt/KernelBase/GetDeviceDriverBaseNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetDeviceDriverBaseNameW,GetDeviceDriverBaseNameW,512 diff --git a/libc/nt/KernelBase/GetDeviceDriverFileNameA.s b/libc/nt/KernelBase/GetDeviceDriverFileNameA.s new file mode 100644 index 00000000..7c6baa79 --- /dev/null +++ b/libc/nt/KernelBase/GetDeviceDriverFileNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetDeviceDriverFileNameA,GetDeviceDriverFileNameA,513 diff --git a/libc/nt/KernelBase/GetDeviceDriverFileNameW.s b/libc/nt/KernelBase/GetDeviceDriverFileNameW.s new file mode 100644 index 00000000..801b800a --- /dev/null +++ b/libc/nt/KernelBase/GetDeviceDriverFileNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetDeviceDriverFileNameW,GetDeviceDriverFileNameW,514 diff --git a/libc/nt/KernelBase/GetDiskFreeSpaceA.s b/libc/nt/KernelBase/GetDiskFreeSpaceA.s new file mode 100644 index 00000000..ae7df2f1 --- /dev/null +++ b/libc/nt/KernelBase/GetDiskFreeSpaceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetDiskFreeSpaceA,GetDiskFreeSpaceA,515 diff --git a/libc/nt/KernelBase/GetDiskFreeSpaceExA.s b/libc/nt/KernelBase/GetDiskFreeSpaceExA.s new file mode 100644 index 00000000..e96fb882 --- /dev/null +++ b/libc/nt/KernelBase/GetDiskFreeSpaceExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetDiskFreeSpaceExA,GetDiskFreeSpaceExA,516 diff --git a/libc/nt/KernelBase/GetDiskFreeSpaceExW.s b/libc/nt/KernelBase/GetDiskFreeSpaceExW.s new file mode 100644 index 00000000..4d1eb20b --- /dev/null +++ b/libc/nt/KernelBase/GetDiskFreeSpaceExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetDiskFreeSpaceExW,GetDiskFreeSpaceExW,517 diff --git a/libc/nt/KernelBase/GetDiskFreeSpaceW.s b/libc/nt/KernelBase/GetDiskFreeSpaceW.s new file mode 100644 index 00000000..6f8487b5 --- /dev/null +++ b/libc/nt/KernelBase/GetDiskFreeSpaceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetDiskFreeSpaceW,GetDiskFreeSpaceW,518 diff --git a/libc/nt/KernelBase/GetDriveTypeA.s b/libc/nt/KernelBase/GetDriveTypeA.s new file mode 100644 index 00000000..906c4ada --- /dev/null +++ b/libc/nt/KernelBase/GetDriveTypeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetDriveTypeA,GetDriveTypeA,519 diff --git a/libc/nt/KernelBase/GetDriveTypeW.s b/libc/nt/KernelBase/GetDriveTypeW.s new file mode 100644 index 00000000..193b7ddc --- /dev/null +++ b/libc/nt/KernelBase/GetDriveTypeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetDriveTypeW,GetDriveTypeW,520 diff --git a/libc/nt/KernelBase/GetDurationFormatEx.s b/libc/nt/KernelBase/GetDurationFormatEx.s new file mode 100644 index 00000000..e751c7e5 --- /dev/null +++ b/libc/nt/KernelBase/GetDurationFormatEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetDurationFormatEx,GetDurationFormatEx,521 diff --git a/libc/nt/KernelBase/GetDynamicTimeZoneInformation.s b/libc/nt/KernelBase/GetDynamicTimeZoneInformation.s new file mode 100644 index 00000000..2d10d237 --- /dev/null +++ b/libc/nt/KernelBase/GetDynamicTimeZoneInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetDynamicTimeZoneInformation,GetDynamicTimeZoneInformation,522 diff --git a/libc/nt/KernelBase/GetDynamicTimeZoneInformationEffectiveYears.s b/libc/nt/KernelBase/GetDynamicTimeZoneInformationEffectiveYears.s new file mode 100644 index 00000000..72f021fa --- /dev/null +++ b/libc/nt/KernelBase/GetDynamicTimeZoneInformationEffectiveYears.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetDynamicTimeZoneInformationEffectiveYears,GetDynamicTimeZoneInformationEffectiveYears,523 diff --git a/libc/nt/KernelBase/GetEffectivePackageStatusForUser.s b/libc/nt/KernelBase/GetEffectivePackageStatusForUser.s new file mode 100644 index 00000000..5d37a3d8 --- /dev/null +++ b/libc/nt/KernelBase/GetEffectivePackageStatusForUser.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetEffectivePackageStatusForUser,GetEffectivePackageStatusForUser,524 diff --git a/libc/nt/KernelBase/GetEffectivePackageStatusForUserSid.s b/libc/nt/KernelBase/GetEffectivePackageStatusForUserSid.s new file mode 100644 index 00000000..ba384e30 --- /dev/null +++ b/libc/nt/KernelBase/GetEffectivePackageStatusForUserSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetEffectivePackageStatusForUserSid,GetEffectivePackageStatusForUserSid,525 diff --git a/libc/nt/KernelBase/GetEightBitStringToUnicodeSizeRoutine.s b/libc/nt/KernelBase/GetEightBitStringToUnicodeSizeRoutine.s new file mode 100644 index 00000000..07fddb96 --- /dev/null +++ b/libc/nt/KernelBase/GetEightBitStringToUnicodeSizeRoutine.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetEightBitStringToUnicodeSizeRoutine,GetEightBitStringToUnicodeSizeRoutine,526 diff --git a/libc/nt/KernelBase/GetEightBitStringToUnicodeStringRoutine.s b/libc/nt/KernelBase/GetEightBitStringToUnicodeStringRoutine.s new file mode 100644 index 00000000..f86e9e10 --- /dev/null +++ b/libc/nt/KernelBase/GetEightBitStringToUnicodeStringRoutine.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetEightBitStringToUnicodeStringRoutine,GetEightBitStringToUnicodeStringRoutine,527 diff --git a/libc/nt/KernelBase/GetEnabledXStateFeatures.s b/libc/nt/KernelBase/GetEnabledXStateFeatures.s new file mode 100644 index 00000000..d7bf4dbb --- /dev/null +++ b/libc/nt/KernelBase/GetEnabledXStateFeatures.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetEnabledXStateFeatures,GetEnabledXStateFeatures,528 diff --git a/libc/nt/KernelBase/GetEnvironmentStringsA.s b/libc/nt/KernelBase/GetEnvironmentStringsA.s new file mode 100644 index 00000000..c8a12a3b --- /dev/null +++ b/libc/nt/KernelBase/GetEnvironmentStringsA.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetEnvironmentStringsA,GetEnvironmentStringsA,530 + + .text.windows +GetEnvironmentStringsA: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetEnvironmentStringsA(%rip) + leave + ret + .endfn GetEnvironmentStringsA,globl + .previous diff --git a/libc/nt/KernelBase/GetEnvironmentStringsW.s b/libc/nt/KernelBase/GetEnvironmentStringsW.s new file mode 100644 index 00000000..05f5d1e3 --- /dev/null +++ b/libc/nt/KernelBase/GetEnvironmentStringsW.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetEnvironmentStringsW,GetEnvironmentStringsW,531 + + .text.windows +GetEnvironmentStrings: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetEnvironmentStringsW(%rip) + leave + ret + .endfn GetEnvironmentStrings,globl + .previous diff --git a/libc/nt/KernelBase/GetEnvironmentVariableA.s b/libc/nt/KernelBase/GetEnvironmentVariableA.s new file mode 100644 index 00000000..d2afe2dd --- /dev/null +++ b/libc/nt/KernelBase/GetEnvironmentVariableA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetEnvironmentVariableA,GetEnvironmentVariableA,532 + + .text.windows +GetEnvironmentVariableA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetEnvironmentVariableA(%rip),%rax + jmp __sysv2nt + .endfn GetEnvironmentVariableA,globl + .previous diff --git a/libc/nt/KernelBase/GetEnvironmentVariableW.s b/libc/nt/KernelBase/GetEnvironmentVariableW.s new file mode 100644 index 00000000..9cdf268c --- /dev/null +++ b/libc/nt/KernelBase/GetEnvironmentVariableW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetEnvironmentVariableW,GetEnvironmentVariableW,533 + + .text.windows +GetEnvironmentVariable: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetEnvironmentVariableW(%rip),%rax + jmp __sysv2nt + .endfn GetEnvironmentVariable,globl + .previous diff --git a/libc/nt/KernelBase/GetEraNameCountedString.s b/libc/nt/KernelBase/GetEraNameCountedString.s new file mode 100644 index 00000000..bffabfbf --- /dev/null +++ b/libc/nt/KernelBase/GetEraNameCountedString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetEraNameCountedString,GetEraNameCountedString,534 diff --git a/libc/nt/KernelBase/GetErrorMode.s b/libc/nt/KernelBase/GetErrorMode.s new file mode 100644 index 00000000..d6e05207 --- /dev/null +++ b/libc/nt/KernelBase/GetErrorMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetErrorMode,GetErrorMode,535 diff --git a/libc/nt/KernelBase/GetExitCodeProcess.s b/libc/nt/KernelBase/GetExitCodeProcess.s new file mode 100644 index 00000000..ba7f2653 --- /dev/null +++ b/libc/nt/KernelBase/GetExitCodeProcess.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetExitCodeProcess,GetExitCodeProcess,536 + + .text.windows +GetExitCodeProcess: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetExitCodeProcess(%rip),%rax + jmp __sysv2nt + .endfn GetExitCodeProcess,globl + .previous diff --git a/libc/nt/KernelBase/GetExitCodeThread.s b/libc/nt/KernelBase/GetExitCodeThread.s new file mode 100644 index 00000000..87aa327f --- /dev/null +++ b/libc/nt/KernelBase/GetExitCodeThread.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetExitCodeThread,GetExitCodeThread,537 + + .text.windows +GetExitCodeThread: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetExitCodeThread(%rip),%rax + jmp __sysv2nt + .endfn GetExitCodeThread,globl + .previous diff --git a/libc/nt/KernelBase/GetExtensionApplicationUserModelId.s b/libc/nt/KernelBase/GetExtensionApplicationUserModelId.s new file mode 100644 index 00000000..465482c0 --- /dev/null +++ b/libc/nt/KernelBase/GetExtensionApplicationUserModelId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetExtensionApplicationUserModelId,GetExtensionApplicationUserModelId,538 diff --git a/libc/nt/KernelBase/GetExtensionProgIds.s b/libc/nt/KernelBase/GetExtensionProgIds.s new file mode 100644 index 00000000..051762da --- /dev/null +++ b/libc/nt/KernelBase/GetExtensionProgIds.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetExtensionProgIds,GetExtensionProgIds,539 diff --git a/libc/nt/KernelBase/GetExtensionProperty.s b/libc/nt/KernelBase/GetExtensionProperty.s new file mode 100644 index 00000000..6c3f1aaf --- /dev/null +++ b/libc/nt/KernelBase/GetExtensionProperty.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetExtensionProperty,GetExtensionProperty,540 diff --git a/libc/nt/KernelBase/GetExtensionProperty2.s b/libc/nt/KernelBase/GetExtensionProperty2.s new file mode 100644 index 00000000..7a41df7a --- /dev/null +++ b/libc/nt/KernelBase/GetExtensionProperty2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetExtensionProperty2,GetExtensionProperty2,541 diff --git a/libc/nt/KernelBase/GetFallbackDisplayName.s b/libc/nt/KernelBase/GetFallbackDisplayName.s new file mode 100644 index 00000000..fe7c44c2 --- /dev/null +++ b/libc/nt/KernelBase/GetFallbackDisplayName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFallbackDisplayName,GetFallbackDisplayName,542 diff --git a/libc/nt/KernelBase/GetFileAttributesA.s b/libc/nt/KernelBase/GetFileAttributesA.s new file mode 100644 index 00000000..48706c04 --- /dev/null +++ b/libc/nt/KernelBase/GetFileAttributesA.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileAttributesA,GetFileAttributesA,543 + + .text.windows +GetFileAttributesA: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetFileAttributesA(%rip) + leave + ret + .endfn GetFileAttributesA,globl + .previous diff --git a/libc/nt/KernelBase/GetFileAttributesExA.s b/libc/nt/KernelBase/GetFileAttributesExA.s new file mode 100644 index 00000000..13dc030d --- /dev/null +++ b/libc/nt/KernelBase/GetFileAttributesExA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileAttributesExA,GetFileAttributesExA,544 + + .text.windows +GetFileAttributesExA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetFileAttributesExA(%rip),%rax + jmp __sysv2nt + .endfn GetFileAttributesExA,globl + .previous diff --git a/libc/nt/KernelBase/GetFileAttributesExW.s b/libc/nt/KernelBase/GetFileAttributesExW.s new file mode 100644 index 00000000..790c6bae --- /dev/null +++ b/libc/nt/KernelBase/GetFileAttributesExW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileAttributesExW,GetFileAttributesExW,545 + + .text.windows +GetFileAttributesEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetFileAttributesExW(%rip),%rax + jmp __sysv2nt + .endfn GetFileAttributesEx,globl + .previous diff --git a/libc/nt/KernelBase/GetFileAttributesW.s b/libc/nt/KernelBase/GetFileAttributesW.s new file mode 100644 index 00000000..94ef3dd4 --- /dev/null +++ b/libc/nt/KernelBase/GetFileAttributesW.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileAttributesW,GetFileAttributesW,546 + + .text.windows +GetFileAttributes: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetFileAttributesW(%rip) + leave + ret + .endfn GetFileAttributes,globl + .previous diff --git a/libc/nt/KernelBase/GetFileInformationByHandle.s b/libc/nt/KernelBase/GetFileInformationByHandle.s new file mode 100644 index 00000000..84ab98de --- /dev/null +++ b/libc/nt/KernelBase/GetFileInformationByHandle.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileInformationByHandle,GetFileInformationByHandle,547 + + .text.windows +GetFileInformationByHandle: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetFileInformationByHandle(%rip),%rax + jmp __sysv2nt + .endfn GetFileInformationByHandle,globl + .previous diff --git a/libc/nt/KernelBase/GetFileInformationByHandleEx.s b/libc/nt/KernelBase/GetFileInformationByHandleEx.s new file mode 100644 index 00000000..34029a6b --- /dev/null +++ b/libc/nt/KernelBase/GetFileInformationByHandleEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileInformationByHandleEx,GetFileInformationByHandleEx,548 + + .text.windows +GetFileInformationByHandleEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetFileInformationByHandleEx(%rip),%rax + jmp __sysv2nt + .endfn GetFileInformationByHandleEx,globl + .previous diff --git a/libc/nt/KernelBase/GetFileMUIInfo.s b/libc/nt/KernelBase/GetFileMUIInfo.s new file mode 100644 index 00000000..c0fdae27 --- /dev/null +++ b/libc/nt/KernelBase/GetFileMUIInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileMUIInfo,GetFileMUIInfo,549 diff --git a/libc/nt/KernelBase/GetFileMUIPath.s b/libc/nt/KernelBase/GetFileMUIPath.s new file mode 100644 index 00000000..a658cdf7 --- /dev/null +++ b/libc/nt/KernelBase/GetFileMUIPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileMUIPath,GetFileMUIPath,550 diff --git a/libc/nt/KernelBase/GetFileSecurityW.s b/libc/nt/KernelBase/GetFileSecurityW.s new file mode 100644 index 00000000..3215c3ee --- /dev/null +++ b/libc/nt/KernelBase/GetFileSecurityW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileSecurityW,GetFileSecurityW,551 + + .text.windows +GetFileSecurity: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetFileSecurityW(%rip),%rax + jmp __sysv2nt6 + .endfn GetFileSecurity,globl + .previous diff --git a/libc/nt/KernelBase/GetFileSize.s b/libc/nt/KernelBase/GetFileSize.s new file mode 100644 index 00000000..7dd076f4 --- /dev/null +++ b/libc/nt/KernelBase/GetFileSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileSize,GetFileSize,552 diff --git a/libc/nt/KernelBase/GetFileSizeEx.s b/libc/nt/KernelBase/GetFileSizeEx.s new file mode 100644 index 00000000..6c56e9b8 --- /dev/null +++ b/libc/nt/KernelBase/GetFileSizeEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileSizeEx,GetFileSizeEx,553 diff --git a/libc/nt/KernelBase/GetFileTime.s b/libc/nt/KernelBase/GetFileTime.s new file mode 100644 index 00000000..f73e9b0e --- /dev/null +++ b/libc/nt/KernelBase/GetFileTime.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileTime,GetFileTime,554 + + .text.windows +GetFileTime: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetFileTime(%rip),%rax + jmp __sysv2nt + .endfn GetFileTime,globl + .previous diff --git a/libc/nt/KernelBase/GetFileType.s b/libc/nt/KernelBase/GetFileType.s new file mode 100644 index 00000000..0d67054c --- /dev/null +++ b/libc/nt/KernelBase/GetFileType.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileType,GetFileType,555 + + .text.windows +GetFileType: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetFileType(%rip) + leave + ret + .endfn GetFileType,globl + .previous diff --git a/libc/nt/KernelBase/GetFileVersionInfoA.s b/libc/nt/KernelBase/GetFileVersionInfoA.s new file mode 100644 index 00000000..d4af0a1d --- /dev/null +++ b/libc/nt/KernelBase/GetFileVersionInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileVersionInfoA,GetFileVersionInfoA,556 diff --git a/libc/nt/KernelBase/GetFileVersionInfoByHandle.s b/libc/nt/KernelBase/GetFileVersionInfoByHandle.s new file mode 100644 index 00000000..24fad978 --- /dev/null +++ b/libc/nt/KernelBase/GetFileVersionInfoByHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileVersionInfoByHandle,GetFileVersionInfoByHandle,557 diff --git a/libc/nt/KernelBase/GetFileVersionInfoExA.s b/libc/nt/KernelBase/GetFileVersionInfoExA.s new file mode 100644 index 00000000..7f9358e3 --- /dev/null +++ b/libc/nt/KernelBase/GetFileVersionInfoExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileVersionInfoExA,GetFileVersionInfoExA,558 diff --git a/libc/nt/KernelBase/GetFileVersionInfoExW.s b/libc/nt/KernelBase/GetFileVersionInfoExW.s new file mode 100644 index 00000000..740867b2 --- /dev/null +++ b/libc/nt/KernelBase/GetFileVersionInfoExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileVersionInfoExW,GetFileVersionInfoExW,559 diff --git a/libc/nt/KernelBase/GetFileVersionInfoSizeA.s b/libc/nt/KernelBase/GetFileVersionInfoSizeA.s new file mode 100644 index 00000000..a2ebb234 --- /dev/null +++ b/libc/nt/KernelBase/GetFileVersionInfoSizeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileVersionInfoSizeA,GetFileVersionInfoSizeA,560 diff --git a/libc/nt/KernelBase/GetFileVersionInfoSizeExA.s b/libc/nt/KernelBase/GetFileVersionInfoSizeExA.s new file mode 100644 index 00000000..7ff02888 --- /dev/null +++ b/libc/nt/KernelBase/GetFileVersionInfoSizeExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileVersionInfoSizeExA,GetFileVersionInfoSizeExA,561 diff --git a/libc/nt/KernelBase/GetFileVersionInfoSizeExW.s b/libc/nt/KernelBase/GetFileVersionInfoSizeExW.s new file mode 100644 index 00000000..f69d1d02 --- /dev/null +++ b/libc/nt/KernelBase/GetFileVersionInfoSizeExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileVersionInfoSizeExW,GetFileVersionInfoSizeExW,562 diff --git a/libc/nt/KernelBase/GetFileVersionInfoSizeW.s b/libc/nt/KernelBase/GetFileVersionInfoSizeW.s new file mode 100644 index 00000000..4c0298a3 --- /dev/null +++ b/libc/nt/KernelBase/GetFileVersionInfoSizeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileVersionInfoSizeW,GetFileVersionInfoSizeW,563 diff --git a/libc/nt/KernelBase/GetFileVersionInfoW.s b/libc/nt/KernelBase/GetFileVersionInfoW.s new file mode 100644 index 00000000..d078c97b --- /dev/null +++ b/libc/nt/KernelBase/GetFileVersionInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFileVersionInfoW,GetFileVersionInfoW,564 diff --git a/libc/nt/KernelBase/GetFinalPathNameByHandleA.s b/libc/nt/KernelBase/GetFinalPathNameByHandleA.s new file mode 100644 index 00000000..3fe8dc55 --- /dev/null +++ b/libc/nt/KernelBase/GetFinalPathNameByHandleA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFinalPathNameByHandleA,GetFinalPathNameByHandleA,565 diff --git a/libc/nt/KernelBase/GetFinalPathNameByHandleW.s b/libc/nt/KernelBase/GetFinalPathNameByHandleW.s new file mode 100644 index 00000000..36abc13c --- /dev/null +++ b/libc/nt/KernelBase/GetFinalPathNameByHandleW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFinalPathNameByHandleW,GetFinalPathNameByHandleW,566 diff --git a/libc/nt/KernelBase/GetFullPathNameA.s b/libc/nt/KernelBase/GetFullPathNameA.s new file mode 100644 index 00000000..c2f3ac17 --- /dev/null +++ b/libc/nt/KernelBase/GetFullPathNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFullPathNameA,GetFullPathNameA,567 diff --git a/libc/nt/KernelBase/GetFullPathNameW.s b/libc/nt/KernelBase/GetFullPathNameW.s new file mode 100644 index 00000000..6e3bf928 --- /dev/null +++ b/libc/nt/KernelBase/GetFullPathNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetFullPathNameW,GetFullPathNameW,568 diff --git a/libc/nt/KernelBase/GetGPOListInternalA.s b/libc/nt/KernelBase/GetGPOListInternalA.s new file mode 100644 index 00000000..21b98be3 --- /dev/null +++ b/libc/nt/KernelBase/GetGPOListInternalA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetGPOListInternalA,GetGPOListInternalA,569 diff --git a/libc/nt/KernelBase/GetGPOListInternalW.s b/libc/nt/KernelBase/GetGPOListInternalW.s new file mode 100644 index 00000000..10e20cc1 --- /dev/null +++ b/libc/nt/KernelBase/GetGPOListInternalW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetGPOListInternalW,GetGPOListInternalW,570 diff --git a/libc/nt/KernelBase/GetGamingDeviceModelInformation.s b/libc/nt/KernelBase/GetGamingDeviceModelInformation.s new file mode 100644 index 00000000..a344ad1f --- /dev/null +++ b/libc/nt/KernelBase/GetGamingDeviceModelInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetGamingDeviceModelInformation,GetGamingDeviceModelInformation,571 diff --git a/libc/nt/KernelBase/GetGeoInfoEx.s b/libc/nt/KernelBase/GetGeoInfoEx.s new file mode 100644 index 00000000..f0b5a13f --- /dev/null +++ b/libc/nt/KernelBase/GetGeoInfoEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetGeoInfoEx,GetGeoInfoEx,572 diff --git a/libc/nt/KernelBase/GetGeoInfoW.s b/libc/nt/KernelBase/GetGeoInfoW.s new file mode 100644 index 00000000..d00eb995 --- /dev/null +++ b/libc/nt/KernelBase/GetGeoInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetGeoInfoW,GetGeoInfoW,573 diff --git a/libc/nt/KernelBase/GetHandleInformation.s b/libc/nt/KernelBase/GetHandleInformation.s new file mode 100644 index 00000000..4b514773 --- /dev/null +++ b/libc/nt/KernelBase/GetHandleInformation.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetHandleInformation,GetHandleInformation,574 + + .text.windows +GetHandleInformation: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetHandleInformation(%rip),%rax + jmp __sysv2nt + .endfn GetHandleInformation,globl + .previous diff --git a/libc/nt/KernelBase/GetHivePath.s b/libc/nt/KernelBase/GetHivePath.s new file mode 100644 index 00000000..860fb6b8 --- /dev/null +++ b/libc/nt/KernelBase/GetHivePath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetHivePath,GetHivePath,575 diff --git a/libc/nt/KernelBase/GetIntegratedDisplaySize.s b/libc/nt/KernelBase/GetIntegratedDisplaySize.s new file mode 100644 index 00000000..ca1f9e83 --- /dev/null +++ b/libc/nt/KernelBase/GetIntegratedDisplaySize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetIntegratedDisplaySize,GetIntegratedDisplaySize,576 diff --git a/libc/nt/KernelBase/GetIsEdpEnabled.s b/libc/nt/KernelBase/GetIsEdpEnabled.s new file mode 100644 index 00000000..9bd6c899 --- /dev/null +++ b/libc/nt/KernelBase/GetIsEdpEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetIsEdpEnabled,GetIsEdpEnabled,577 diff --git a/libc/nt/KernelBase/GetKernelObjectSecurity.s b/libc/nt/KernelBase/GetKernelObjectSecurity.s new file mode 100644 index 00000000..6d5baf3f --- /dev/null +++ b/libc/nt/KernelBase/GetKernelObjectSecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetKernelObjectSecurity,GetKernelObjectSecurity,578 diff --git a/libc/nt/KernelBase/GetLargePageMinimum.s b/libc/nt/KernelBase/GetLargePageMinimum.s new file mode 100644 index 00000000..1b58f739 --- /dev/null +++ b/libc/nt/KernelBase/GetLargePageMinimum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetLargePageMinimum,GetLargePageMinimum,579 diff --git a/libc/nt/KernelBase/GetLargestConsoleWindowSize.s b/libc/nt/KernelBase/GetLargestConsoleWindowSize.s new file mode 100644 index 00000000..43b226c4 --- /dev/null +++ b/libc/nt/KernelBase/GetLargestConsoleWindowSize.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetLargestConsoleWindowSize,GetLargestConsoleWindowSize,580 + + .text.windows +GetLargestConsoleWindowSize: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetLargestConsoleWindowSize(%rip) + leave + ret + .endfn GetLargestConsoleWindowSize,globl + .previous diff --git a/libc/nt/KernelBase/GetLastError.s b/libc/nt/KernelBase/GetLastError.s new file mode 100644 index 00000000..59041da1 --- /dev/null +++ b/libc/nt/KernelBase/GetLastError.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetLastError,GetLastError,581 + + .text.windows +GetLastError: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_GetLastError(%rip) + leave + ret + .endfn GetLastError,globl + .previous diff --git a/libc/nt/KernelBase/GetLengthSid.s b/libc/nt/KernelBase/GetLengthSid.s new file mode 100644 index 00000000..74061ad9 --- /dev/null +++ b/libc/nt/KernelBase/GetLengthSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetLengthSid,GetLengthSid,582 diff --git a/libc/nt/KernelBase/GetLocalTime.s b/libc/nt/KernelBase/GetLocalTime.s new file mode 100644 index 00000000..cff6bf27 --- /dev/null +++ b/libc/nt/KernelBase/GetLocalTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetLocalTime,GetLocalTime,583 diff --git a/libc/nt/KernelBase/GetLocaleInfoA.s b/libc/nt/KernelBase/GetLocaleInfoA.s new file mode 100644 index 00000000..cb51bd98 --- /dev/null +++ b/libc/nt/KernelBase/GetLocaleInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetLocaleInfoA,GetLocaleInfoA,584 diff --git a/libc/nt/KernelBase/GetLocaleInfoEx.s b/libc/nt/KernelBase/GetLocaleInfoEx.s new file mode 100644 index 00000000..3b94f197 --- /dev/null +++ b/libc/nt/KernelBase/GetLocaleInfoEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetLocaleInfoEx,GetLocaleInfoEx,585 diff --git a/libc/nt/KernelBase/GetLocaleInfoHelper.s b/libc/nt/KernelBase/GetLocaleInfoHelper.s new file mode 100644 index 00000000..1d5e6740 --- /dev/null +++ b/libc/nt/KernelBase/GetLocaleInfoHelper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetLocaleInfoHelper,GetLocaleInfoHelper,586 diff --git a/libc/nt/KernelBase/GetLocaleInfoW.s b/libc/nt/KernelBase/GetLocaleInfoW.s new file mode 100644 index 00000000..1767646c --- /dev/null +++ b/libc/nt/KernelBase/GetLocaleInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetLocaleInfoW,GetLocaleInfoW,587 diff --git a/libc/nt/KernelBase/GetLogicalDriveStringsW.s b/libc/nt/KernelBase/GetLogicalDriveStringsW.s new file mode 100644 index 00000000..2ce75be1 --- /dev/null +++ b/libc/nt/KernelBase/GetLogicalDriveStringsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetLogicalDriveStringsW,GetLogicalDriveStringsW,588 diff --git a/libc/nt/KernelBase/GetLogicalDrives.s b/libc/nt/KernelBase/GetLogicalDrives.s new file mode 100644 index 00000000..9fd6ee86 --- /dev/null +++ b/libc/nt/KernelBase/GetLogicalDrives.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetLogicalDrives,GetLogicalDrives,589 + + .text.windows +GetLogicalDrives: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_GetLogicalDrives(%rip) + leave + ret + .endfn GetLogicalDrives,globl + .previous diff --git a/libc/nt/KernelBase/GetLogicalProcessorInformation.s b/libc/nt/KernelBase/GetLogicalProcessorInformation.s new file mode 100644 index 00000000..ad88fb85 --- /dev/null +++ b/libc/nt/KernelBase/GetLogicalProcessorInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetLogicalProcessorInformation,GetLogicalProcessorInformation,590 diff --git a/libc/nt/KernelBase/GetLogicalProcessorInformationEx.s b/libc/nt/KernelBase/GetLogicalProcessorInformationEx.s new file mode 100644 index 00000000..f83661c1 --- /dev/null +++ b/libc/nt/KernelBase/GetLogicalProcessorInformationEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetLogicalProcessorInformationEx,GetLogicalProcessorInformationEx,591 diff --git a/libc/nt/KernelBase/GetLongPathNameA.s b/libc/nt/KernelBase/GetLongPathNameA.s new file mode 100644 index 00000000..a690995d --- /dev/null +++ b/libc/nt/KernelBase/GetLongPathNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetLongPathNameA,GetLongPathNameA,592 diff --git a/libc/nt/KernelBase/GetLongPathNameW.s b/libc/nt/KernelBase/GetLongPathNameW.s new file mode 100644 index 00000000..bc591d9c --- /dev/null +++ b/libc/nt/KernelBase/GetLongPathNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetLongPathNameW,GetLongPathNameW,593 diff --git a/libc/nt/KernelBase/GetMappedFileNameA.s b/libc/nt/KernelBase/GetMappedFileNameA.s new file mode 100644 index 00000000..1968033c --- /dev/null +++ b/libc/nt/KernelBase/GetMappedFileNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetMappedFileNameA,GetMappedFileNameA,594 diff --git a/libc/nt/KernelBase/GetMappedFileNameW.s b/libc/nt/KernelBase/GetMappedFileNameW.s new file mode 100644 index 00000000..118bab1a --- /dev/null +++ b/libc/nt/KernelBase/GetMappedFileNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetMappedFileNameW,GetMappedFileNameW,595 diff --git a/libc/nt/KernelBase/GetMemoryErrorHandlingCapabilities.s b/libc/nt/KernelBase/GetMemoryErrorHandlingCapabilities.s new file mode 100644 index 00000000..4c5026d0 --- /dev/null +++ b/libc/nt/KernelBase/GetMemoryErrorHandlingCapabilities.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetMemoryErrorHandlingCapabilities,GetMemoryErrorHandlingCapabilities,596 diff --git a/libc/nt/KernelBase/GetModuleBaseNameA.s b/libc/nt/KernelBase/GetModuleBaseNameA.s new file mode 100644 index 00000000..0130241e --- /dev/null +++ b/libc/nt/KernelBase/GetModuleBaseNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetModuleBaseNameA,GetModuleBaseNameA,597 diff --git a/libc/nt/KernelBase/GetModuleBaseNameW.s b/libc/nt/KernelBase/GetModuleBaseNameW.s new file mode 100644 index 00000000..f3c1df4f --- /dev/null +++ b/libc/nt/KernelBase/GetModuleBaseNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetModuleBaseNameW,GetModuleBaseNameW,598 diff --git a/libc/nt/KernelBase/GetModuleFileNameA.s b/libc/nt/KernelBase/GetModuleFileNameA.s new file mode 100644 index 00000000..612bd5d9 --- /dev/null +++ b/libc/nt/KernelBase/GetModuleFileNameA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetModuleFileNameA,GetModuleFileNameA,599 + + .text.windows +GetModuleFileNameA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetModuleFileNameA(%rip),%rax + jmp __sysv2nt + .endfn GetModuleFileNameA,globl + .previous diff --git a/libc/nt/KernelBase/GetModuleFileNameExA.s b/libc/nt/KernelBase/GetModuleFileNameExA.s new file mode 100644 index 00000000..e04572ea --- /dev/null +++ b/libc/nt/KernelBase/GetModuleFileNameExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetModuleFileNameExA,GetModuleFileNameExA,600 diff --git a/libc/nt/KernelBase/GetModuleFileNameExW.s b/libc/nt/KernelBase/GetModuleFileNameExW.s new file mode 100644 index 00000000..61be9860 --- /dev/null +++ b/libc/nt/KernelBase/GetModuleFileNameExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetModuleFileNameExW,GetModuleFileNameExW,601 diff --git a/libc/nt/KernelBase/GetModuleFileNameW.s b/libc/nt/KernelBase/GetModuleFileNameW.s new file mode 100644 index 00000000..cec438d0 --- /dev/null +++ b/libc/nt/KernelBase/GetModuleFileNameW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetModuleFileNameW,GetModuleFileNameW,602 + + .text.windows +GetModuleFileName: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetModuleFileNameW(%rip),%rax + jmp __sysv2nt + .endfn GetModuleFileName,globl + .previous diff --git a/libc/nt/KernelBase/GetModuleHandleA.s b/libc/nt/KernelBase/GetModuleHandleA.s new file mode 100644 index 00000000..cdeb2e22 --- /dev/null +++ b/libc/nt/KernelBase/GetModuleHandleA.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetModuleHandleA,GetModuleHandleA,603 + + .text.windows +GetModuleHandle: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetModuleHandleA(%rip) + leave + ret + .endfn GetModuleHandle,globl + .previous diff --git a/libc/nt/KernelBase/GetModuleHandleExA.s b/libc/nt/KernelBase/GetModuleHandleExA.s new file mode 100644 index 00000000..114fa2ae --- /dev/null +++ b/libc/nt/KernelBase/GetModuleHandleExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetModuleHandleExA,GetModuleHandleExA,604 diff --git a/libc/nt/KernelBase/GetModuleHandleExW.s b/libc/nt/KernelBase/GetModuleHandleExW.s new file mode 100644 index 00000000..b5fd0b3a --- /dev/null +++ b/libc/nt/KernelBase/GetModuleHandleExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetModuleHandleExW,GetModuleHandleExW,605 diff --git a/libc/nt/KernelBase/GetModuleHandleW.s b/libc/nt/KernelBase/GetModuleHandleW.s new file mode 100644 index 00000000..14cc50c7 --- /dev/null +++ b/libc/nt/KernelBase/GetModuleHandleW.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetModuleHandleW,GetModuleHandleW,606 + + .text.windows +GetModuleHandleW: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetModuleHandleW(%rip) + leave + ret + .endfn GetModuleHandleW,globl + .previous diff --git a/libc/nt/KernelBase/GetModuleInformation.s b/libc/nt/KernelBase/GetModuleInformation.s new file mode 100644 index 00000000..c845db47 --- /dev/null +++ b/libc/nt/KernelBase/GetModuleInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetModuleInformation,GetModuleInformation,607 diff --git a/libc/nt/KernelBase/GetNLSVersion.s b/libc/nt/KernelBase/GetNLSVersion.s new file mode 100644 index 00000000..b9e6fde5 --- /dev/null +++ b/libc/nt/KernelBase/GetNLSVersion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetNLSVersion,GetNLSVersion,608 diff --git a/libc/nt/KernelBase/GetNLSVersionEx.s b/libc/nt/KernelBase/GetNLSVersionEx.s new file mode 100644 index 00000000..f84f20fc --- /dev/null +++ b/libc/nt/KernelBase/GetNLSVersionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetNLSVersionEx,GetNLSVersionEx,609 diff --git a/libc/nt/KernelBase/GetNamedLocaleHashNode.s b/libc/nt/KernelBase/GetNamedLocaleHashNode.s new file mode 100644 index 00000000..0c8fc35b --- /dev/null +++ b/libc/nt/KernelBase/GetNamedLocaleHashNode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetNamedLocaleHashNode,GetNamedLocaleHashNode,610 diff --git a/libc/nt/KernelBase/GetNamedPipeAttribute.s b/libc/nt/KernelBase/GetNamedPipeAttribute.s new file mode 100644 index 00000000..36af81e8 --- /dev/null +++ b/libc/nt/KernelBase/GetNamedPipeAttribute.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetNamedPipeAttribute,GetNamedPipeAttribute,611 diff --git a/libc/nt/KernelBase/GetNamedPipeClientComputerNameW.s b/libc/nt/KernelBase/GetNamedPipeClientComputerNameW.s new file mode 100644 index 00000000..052baac8 --- /dev/null +++ b/libc/nt/KernelBase/GetNamedPipeClientComputerNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetNamedPipeClientComputerNameW,GetNamedPipeClientComputerNameW,612 diff --git a/libc/nt/KernelBase/GetNamedPipeHandleStateW.s b/libc/nt/KernelBase/GetNamedPipeHandleStateW.s new file mode 100644 index 00000000..ddc99585 --- /dev/null +++ b/libc/nt/KernelBase/GetNamedPipeHandleStateW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetNamedPipeHandleStateW,GetNamedPipeHandleStateW,613 diff --git a/libc/nt/KernelBase/GetNamedPipeInfo.s b/libc/nt/KernelBase/GetNamedPipeInfo.s new file mode 100644 index 00000000..c644feeb --- /dev/null +++ b/libc/nt/KernelBase/GetNamedPipeInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetNamedPipeInfo,GetNamedPipeInfo,614 diff --git a/libc/nt/KernelBase/GetNativeSystemInfo.s b/libc/nt/KernelBase/GetNativeSystemInfo.s new file mode 100644 index 00000000..5e7f5fb3 --- /dev/null +++ b/libc/nt/KernelBase/GetNativeSystemInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetNativeSystemInfo,GetNativeSystemInfo,615 diff --git a/libc/nt/KernelBase/GetNextFgPolicyRefreshInfoInternal.s b/libc/nt/KernelBase/GetNextFgPolicyRefreshInfoInternal.s new file mode 100644 index 00000000..b39b28d5 --- /dev/null +++ b/libc/nt/KernelBase/GetNextFgPolicyRefreshInfoInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetNextFgPolicyRefreshInfoInternal,GetNextFgPolicyRefreshInfoInternal,616 diff --git a/libc/nt/KernelBase/GetNumaHighestNodeNumber.s b/libc/nt/KernelBase/GetNumaHighestNodeNumber.s new file mode 100644 index 00000000..53713638 --- /dev/null +++ b/libc/nt/KernelBase/GetNumaHighestNodeNumber.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetNumaHighestNodeNumber,GetNumaHighestNodeNumber,617 diff --git a/libc/nt/KernelBase/GetNumaNodeProcessorMaskEx.s b/libc/nt/KernelBase/GetNumaNodeProcessorMaskEx.s new file mode 100644 index 00000000..5e923a8e --- /dev/null +++ b/libc/nt/KernelBase/GetNumaNodeProcessorMaskEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetNumaNodeProcessorMaskEx,GetNumaNodeProcessorMaskEx,618 diff --git a/libc/nt/KernelBase/GetNumaProximityNodeEx.s b/libc/nt/KernelBase/GetNumaProximityNodeEx.s new file mode 100644 index 00000000..483be145 --- /dev/null +++ b/libc/nt/KernelBase/GetNumaProximityNodeEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetNumaProximityNodeEx,GetNumaProximityNodeEx,619 diff --git a/libc/nt/KernelBase/GetNumberFormatEx.s b/libc/nt/KernelBase/GetNumberFormatEx.s new file mode 100644 index 00000000..d3df5948 --- /dev/null +++ b/libc/nt/KernelBase/GetNumberFormatEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetNumberFormatEx,GetNumberFormatEx,620 diff --git a/libc/nt/KernelBase/GetNumberFormatW.s b/libc/nt/KernelBase/GetNumberFormatW.s new file mode 100644 index 00000000..e9f1e91a --- /dev/null +++ b/libc/nt/KernelBase/GetNumberFormatW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetNumberFormatW,GetNumberFormatW,621 diff --git a/libc/nt/KernelBase/GetNumberOfConsoleInputEvents.s b/libc/nt/KernelBase/GetNumberOfConsoleInputEvents.s new file mode 100644 index 00000000..6ff78caf --- /dev/null +++ b/libc/nt/KernelBase/GetNumberOfConsoleInputEvents.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetNumberOfConsoleInputEvents,GetNumberOfConsoleInputEvents,622 + + .text.windows +GetNumberOfConsoleInputEvents: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetNumberOfConsoleInputEvents(%rip),%rax + jmp __sysv2nt + .endfn GetNumberOfConsoleInputEvents,globl + .previous diff --git a/libc/nt/KernelBase/GetNumberOfConsoleMouseButtons.s b/libc/nt/KernelBase/GetNumberOfConsoleMouseButtons.s new file mode 100644 index 00000000..40f7967c --- /dev/null +++ b/libc/nt/KernelBase/GetNumberOfConsoleMouseButtons.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetNumberOfConsoleMouseButtons,GetNumberOfConsoleMouseButtons,623 + + .text.windows +GetNumberOfConsoleMouseButtons: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetNumberOfConsoleMouseButtons(%rip) + leave + ret + .endfn GetNumberOfConsoleMouseButtons,globl + .previous diff --git a/libc/nt/KernelBase/GetOEMCP.s b/libc/nt/KernelBase/GetOEMCP.s new file mode 100644 index 00000000..b7e1d89e --- /dev/null +++ b/libc/nt/KernelBase/GetOEMCP.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetOEMCP,GetOEMCP,624 diff --git a/libc/nt/KernelBase/GetOsManufacturingMode.s b/libc/nt/KernelBase/GetOsManufacturingMode.s new file mode 100644 index 00000000..69ba15f0 --- /dev/null +++ b/libc/nt/KernelBase/GetOsManufacturingMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetOsManufacturingMode,GetOsManufacturingMode,625 diff --git a/libc/nt/KernelBase/GetOsSafeBootMode.s b/libc/nt/KernelBase/GetOsSafeBootMode.s new file mode 100644 index 00000000..44288388 --- /dev/null +++ b/libc/nt/KernelBase/GetOsSafeBootMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetOsSafeBootMode,GetOsSafeBootMode,626 diff --git a/libc/nt/KernelBase/GetOverlappedResult.s b/libc/nt/KernelBase/GetOverlappedResult.s new file mode 100644 index 00000000..eda2652c --- /dev/null +++ b/libc/nt/KernelBase/GetOverlappedResult.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetOverlappedResult,GetOverlappedResult,627 diff --git a/libc/nt/KernelBase/GetOverlappedResultEx.s b/libc/nt/KernelBase/GetOverlappedResultEx.s new file mode 100644 index 00000000..e7b0adcd --- /dev/null +++ b/libc/nt/KernelBase/GetOverlappedResultEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetOverlappedResultEx,GetOverlappedResultEx,628 diff --git a/libc/nt/KernelBase/GetPackageApplicationContext.s b/libc/nt/KernelBase/GetPackageApplicationContext.s new file mode 100644 index 00000000..fecdcadc --- /dev/null +++ b/libc/nt/KernelBase/GetPackageApplicationContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageApplicationContext,GetPackageApplicationContext,629 diff --git a/libc/nt/KernelBase/GetPackageApplicationIds.s b/libc/nt/KernelBase/GetPackageApplicationIds.s new file mode 100644 index 00000000..72281799 --- /dev/null +++ b/libc/nt/KernelBase/GetPackageApplicationIds.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageApplicationIds,GetPackageApplicationIds,630 diff --git a/libc/nt/KernelBase/GetPackageApplicationProperty.s b/libc/nt/KernelBase/GetPackageApplicationProperty.s new file mode 100644 index 00000000..868279cc --- /dev/null +++ b/libc/nt/KernelBase/GetPackageApplicationProperty.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageApplicationProperty,GetPackageApplicationProperty,631 diff --git a/libc/nt/KernelBase/GetPackageApplicationPropertyString.s b/libc/nt/KernelBase/GetPackageApplicationPropertyString.s new file mode 100644 index 00000000..edc0fb89 --- /dev/null +++ b/libc/nt/KernelBase/GetPackageApplicationPropertyString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageApplicationPropertyString,GetPackageApplicationPropertyString,632 diff --git a/libc/nt/KernelBase/GetPackageApplicationResourcesContext.s b/libc/nt/KernelBase/GetPackageApplicationResourcesContext.s new file mode 100644 index 00000000..f37571da --- /dev/null +++ b/libc/nt/KernelBase/GetPackageApplicationResourcesContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageApplicationResourcesContext,GetPackageApplicationResourcesContext,633 diff --git a/libc/nt/KernelBase/GetPackageContext.s b/libc/nt/KernelBase/GetPackageContext.s new file mode 100644 index 00000000..4f493a31 --- /dev/null +++ b/libc/nt/KernelBase/GetPackageContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageContext,GetPackageContext,634 diff --git a/libc/nt/KernelBase/GetPackageFamilyName.s b/libc/nt/KernelBase/GetPackageFamilyName.s new file mode 100644 index 00000000..33c877f1 --- /dev/null +++ b/libc/nt/KernelBase/GetPackageFamilyName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageFamilyName,GetPackageFamilyName,635 diff --git a/libc/nt/KernelBase/GetPackageFamilyNameFromProgId.s b/libc/nt/KernelBase/GetPackageFamilyNameFromProgId.s new file mode 100644 index 00000000..0af86658 --- /dev/null +++ b/libc/nt/KernelBase/GetPackageFamilyNameFromProgId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageFamilyNameFromProgId,GetPackageFamilyNameFromProgId,636 diff --git a/libc/nt/KernelBase/GetPackageFamilyNameFromToken.s b/libc/nt/KernelBase/GetPackageFamilyNameFromToken.s new file mode 100644 index 00000000..d1e0a20d --- /dev/null +++ b/libc/nt/KernelBase/GetPackageFamilyNameFromToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageFamilyNameFromToken,GetPackageFamilyNameFromToken,637 diff --git a/libc/nt/KernelBase/GetPackageFullName.s b/libc/nt/KernelBase/GetPackageFullName.s new file mode 100644 index 00000000..ef025555 --- /dev/null +++ b/libc/nt/KernelBase/GetPackageFullName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageFullName,GetPackageFullName,638 diff --git a/libc/nt/KernelBase/GetPackageFullNameFromToken.s b/libc/nt/KernelBase/GetPackageFullNameFromToken.s new file mode 100644 index 00000000..8e95137e --- /dev/null +++ b/libc/nt/KernelBase/GetPackageFullNameFromToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageFullNameFromToken,GetPackageFullNameFromToken,639 diff --git a/libc/nt/KernelBase/GetPackageId.s b/libc/nt/KernelBase/GetPackageId.s new file mode 100644 index 00000000..61a4bbeb --- /dev/null +++ b/libc/nt/KernelBase/GetPackageId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageId,GetPackageId,640 diff --git a/libc/nt/KernelBase/GetPackageInfo.s b/libc/nt/KernelBase/GetPackageInfo.s new file mode 100644 index 00000000..b7af7b42 --- /dev/null +++ b/libc/nt/KernelBase/GetPackageInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageInfo,GetPackageInfo,641 diff --git a/libc/nt/KernelBase/GetPackageInstallTime.s b/libc/nt/KernelBase/GetPackageInstallTime.s new file mode 100644 index 00000000..b15edf4e --- /dev/null +++ b/libc/nt/KernelBase/GetPackageInstallTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageInstallTime,GetPackageInstallTime,642 diff --git a/libc/nt/KernelBase/GetPackageOSMaxVersionTested.s b/libc/nt/KernelBase/GetPackageOSMaxVersionTested.s new file mode 100644 index 00000000..564e7803 --- /dev/null +++ b/libc/nt/KernelBase/GetPackageOSMaxVersionTested.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageOSMaxVersionTested,GetPackageOSMaxVersionTested,643 diff --git a/libc/nt/KernelBase/GetPackagePath.s b/libc/nt/KernelBase/GetPackagePath.s new file mode 100644 index 00000000..ddedd36b --- /dev/null +++ b/libc/nt/KernelBase/GetPackagePath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackagePath,GetPackagePath,644 diff --git a/libc/nt/KernelBase/GetPackagePathByFullName.s b/libc/nt/KernelBase/GetPackagePathByFullName.s new file mode 100644 index 00000000..830f6561 --- /dev/null +++ b/libc/nt/KernelBase/GetPackagePathByFullName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackagePathByFullName,GetPackagePathByFullName,645 diff --git a/libc/nt/KernelBase/GetPackagePathOnVolume.s b/libc/nt/KernelBase/GetPackagePathOnVolume.s new file mode 100644 index 00000000..b56b7722 --- /dev/null +++ b/libc/nt/KernelBase/GetPackagePathOnVolume.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackagePathOnVolume,GetPackagePathOnVolume,646 diff --git a/libc/nt/KernelBase/GetPackageProperty.s b/libc/nt/KernelBase/GetPackageProperty.s new file mode 100644 index 00000000..2b2164d3 --- /dev/null +++ b/libc/nt/KernelBase/GetPackageProperty.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageProperty,GetPackageProperty,647 diff --git a/libc/nt/KernelBase/GetPackagePropertyString.s b/libc/nt/KernelBase/GetPackagePropertyString.s new file mode 100644 index 00000000..807f025e --- /dev/null +++ b/libc/nt/KernelBase/GetPackagePropertyString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackagePropertyString,GetPackagePropertyString,648 diff --git a/libc/nt/KernelBase/GetPackageResourcesContext.s b/libc/nt/KernelBase/GetPackageResourcesContext.s new file mode 100644 index 00000000..81643887 --- /dev/null +++ b/libc/nt/KernelBase/GetPackageResourcesContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageResourcesContext,GetPackageResourcesContext,649 diff --git a/libc/nt/KernelBase/GetPackageResourcesProperty.s b/libc/nt/KernelBase/GetPackageResourcesProperty.s new file mode 100644 index 00000000..b1422948 --- /dev/null +++ b/libc/nt/KernelBase/GetPackageResourcesProperty.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageResourcesProperty,GetPackageResourcesProperty,650 diff --git a/libc/nt/KernelBase/GetPackageSecurityContext.s b/libc/nt/KernelBase/GetPackageSecurityContext.s new file mode 100644 index 00000000..5924a03d --- /dev/null +++ b/libc/nt/KernelBase/GetPackageSecurityContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageSecurityContext,GetPackageSecurityContext,651 diff --git a/libc/nt/KernelBase/GetPackageSecurityProperty.s b/libc/nt/KernelBase/GetPackageSecurityProperty.s new file mode 100644 index 00000000..48ff81bc --- /dev/null +++ b/libc/nt/KernelBase/GetPackageSecurityProperty.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageSecurityProperty,GetPackageSecurityProperty,652 diff --git a/libc/nt/KernelBase/GetPackageStatus.s b/libc/nt/KernelBase/GetPackageStatus.s new file mode 100644 index 00000000..87e0639e --- /dev/null +++ b/libc/nt/KernelBase/GetPackageStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageStatus,GetPackageStatus,653 diff --git a/libc/nt/KernelBase/GetPackageStatusForUser.s b/libc/nt/KernelBase/GetPackageStatusForUser.s new file mode 100644 index 00000000..1159e2f1 --- /dev/null +++ b/libc/nt/KernelBase/GetPackageStatusForUser.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageStatusForUser,GetPackageStatusForUser,654 diff --git a/libc/nt/KernelBase/GetPackageStatusForUserSid.s b/libc/nt/KernelBase/GetPackageStatusForUserSid.s new file mode 100644 index 00000000..fbfecca0 --- /dev/null +++ b/libc/nt/KernelBase/GetPackageStatusForUserSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageStatusForUserSid,GetPackageStatusForUserSid,655 diff --git a/libc/nt/KernelBase/GetPackageTargetPlatformProperty.s b/libc/nt/KernelBase/GetPackageTargetPlatformProperty.s new file mode 100644 index 00000000..7b0e6ab4 --- /dev/null +++ b/libc/nt/KernelBase/GetPackageTargetPlatformProperty.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageTargetPlatformProperty,GetPackageTargetPlatformProperty,656 diff --git a/libc/nt/KernelBase/GetPackageVolumeSisPath.s b/libc/nt/KernelBase/GetPackageVolumeSisPath.s new file mode 100644 index 00000000..55ed6271 --- /dev/null +++ b/libc/nt/KernelBase/GetPackageVolumeSisPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackageVolumeSisPath,GetPackageVolumeSisPath,657 diff --git a/libc/nt/KernelBase/GetPackagesByPackageFamily.s b/libc/nt/KernelBase/GetPackagesByPackageFamily.s new file mode 100644 index 00000000..a9744152 --- /dev/null +++ b/libc/nt/KernelBase/GetPackagesByPackageFamily.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPackagesByPackageFamily,GetPackagesByPackageFamily,658 diff --git a/libc/nt/KernelBase/GetPerformanceInfo.s b/libc/nt/KernelBase/GetPerformanceInfo.s new file mode 100644 index 00000000..33d9bae1 --- /dev/null +++ b/libc/nt/KernelBase/GetPerformanceInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPerformanceInfo,GetPerformanceInfo,659 diff --git a/libc/nt/KernelBase/GetPersistedFileLocationW.s b/libc/nt/KernelBase/GetPersistedFileLocationW.s new file mode 100644 index 00000000..27a01a8f --- /dev/null +++ b/libc/nt/KernelBase/GetPersistedFileLocationW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPersistedFileLocationW,GetPersistedFileLocationW,660 diff --git a/libc/nt/KernelBase/GetPersistedRegistryLocationW.s b/libc/nt/KernelBase/GetPersistedRegistryLocationW.s new file mode 100644 index 00000000..8d8a8ce5 --- /dev/null +++ b/libc/nt/KernelBase/GetPersistedRegistryLocationW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPersistedRegistryLocationW,GetPersistedRegistryLocationW,661 diff --git a/libc/nt/KernelBase/GetPersistedRegistryValueW.s b/libc/nt/KernelBase/GetPersistedRegistryValueW.s new file mode 100644 index 00000000..d96703fb --- /dev/null +++ b/libc/nt/KernelBase/GetPersistedRegistryValueW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPersistedRegistryValueW,GetPersistedRegistryValueW,662 diff --git a/libc/nt/KernelBase/GetPhysicallyInstalledSystemMemory.s b/libc/nt/KernelBase/GetPhysicallyInstalledSystemMemory.s new file mode 100644 index 00000000..c76e260c --- /dev/null +++ b/libc/nt/KernelBase/GetPhysicallyInstalledSystemMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPhysicallyInstalledSystemMemory,GetPhysicallyInstalledSystemMemory,663 diff --git a/libc/nt/KernelBase/GetPreviousFgPolicyRefreshInfoInternal.s b/libc/nt/KernelBase/GetPreviousFgPolicyRefreshInfoInternal.s new file mode 100644 index 00000000..2cee86ce --- /dev/null +++ b/libc/nt/KernelBase/GetPreviousFgPolicyRefreshInfoInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPreviousFgPolicyRefreshInfoInternal,GetPreviousFgPolicyRefreshInfoInternal,664 diff --git a/libc/nt/KernelBase/GetPriorityClass.s b/libc/nt/KernelBase/GetPriorityClass.s new file mode 100644 index 00000000..f4eeed9d --- /dev/null +++ b/libc/nt/KernelBase/GetPriorityClass.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPriorityClass,GetPriorityClass,665 + + .text.windows +GetPriorityClass: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetPriorityClass(%rip) + leave + ret + .endfn GetPriorityClass,globl + .previous diff --git a/libc/nt/KernelBase/GetPrivateObjectSecurity.s b/libc/nt/KernelBase/GetPrivateObjectSecurity.s new file mode 100644 index 00000000..15cb395c --- /dev/null +++ b/libc/nt/KernelBase/GetPrivateObjectSecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPrivateObjectSecurity,GetPrivateObjectSecurity,666 diff --git a/libc/nt/KernelBase/GetProcAddress.s b/libc/nt/KernelBase/GetProcAddress.s new file mode 100644 index 00000000..7b0306a0 --- /dev/null +++ b/libc/nt/KernelBase/GetProcAddress.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcAddress,GetProcAddress,667 + + .text.windows +GetProcAddress: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetProcAddress(%rip),%rax + jmp __sysv2nt + .endfn GetProcAddress,globl + .previous diff --git a/libc/nt/KernelBase/GetProcAddressForCaller.s b/libc/nt/KernelBase/GetProcAddressForCaller.s new file mode 100644 index 00000000..0c1459e0 --- /dev/null +++ b/libc/nt/KernelBase/GetProcAddressForCaller.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcAddressForCaller,GetProcAddressForCaller,668 diff --git a/libc/nt/KernelBase/GetProcessDefaultCpuSets.s b/libc/nt/KernelBase/GetProcessDefaultCpuSets.s new file mode 100644 index 00000000..faa145df --- /dev/null +++ b/libc/nt/KernelBase/GetProcessDefaultCpuSets.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessDefaultCpuSets,GetProcessDefaultCpuSets,669 diff --git a/libc/nt/KernelBase/GetProcessGroupAffinity.s b/libc/nt/KernelBase/GetProcessGroupAffinity.s new file mode 100644 index 00000000..403652c3 --- /dev/null +++ b/libc/nt/KernelBase/GetProcessGroupAffinity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessGroupAffinity,GetProcessGroupAffinity,670 diff --git a/libc/nt/KernelBase/GetProcessHandleCount.s b/libc/nt/KernelBase/GetProcessHandleCount.s new file mode 100644 index 00000000..e500a4a4 --- /dev/null +++ b/libc/nt/KernelBase/GetProcessHandleCount.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessHandleCount,GetProcessHandleCount,671 + + .text.windows +GetProcessHandleCount: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetProcessHandleCount(%rip),%rax + jmp __sysv2nt + .endfn GetProcessHandleCount,globl + .previous diff --git a/libc/nt/KernelBase/GetProcessHeap.s b/libc/nt/KernelBase/GetProcessHeap.s new file mode 100644 index 00000000..a29a3751 --- /dev/null +++ b/libc/nt/KernelBase/GetProcessHeap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessHeap,GetProcessHeap,672 diff --git a/libc/nt/KernelBase/GetProcessHeaps.s b/libc/nt/KernelBase/GetProcessHeaps.s new file mode 100644 index 00000000..b7afd6f7 --- /dev/null +++ b/libc/nt/KernelBase/GetProcessHeaps.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessHeaps,GetProcessHeaps,673 diff --git a/libc/nt/KernelBase/GetProcessId.s b/libc/nt/KernelBase/GetProcessId.s new file mode 100644 index 00000000..5b131839 --- /dev/null +++ b/libc/nt/KernelBase/GetProcessId.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessId,GetProcessId,674 + + .text.windows +GetProcessId: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetProcessId(%rip) + leave + ret + .endfn GetProcessId,globl + .previous diff --git a/libc/nt/KernelBase/GetProcessIdOfThread.s b/libc/nt/KernelBase/GetProcessIdOfThread.s new file mode 100644 index 00000000..e9d421b3 --- /dev/null +++ b/libc/nt/KernelBase/GetProcessIdOfThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessIdOfThread,GetProcessIdOfThread,675 diff --git a/libc/nt/KernelBase/GetProcessImageFileNameA.s b/libc/nt/KernelBase/GetProcessImageFileNameA.s new file mode 100644 index 00000000..6db92e2c --- /dev/null +++ b/libc/nt/KernelBase/GetProcessImageFileNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessImageFileNameA,GetProcessImageFileNameA,676 diff --git a/libc/nt/KernelBase/GetProcessImageFileNameW.s b/libc/nt/KernelBase/GetProcessImageFileNameW.s new file mode 100644 index 00000000..6a68648f --- /dev/null +++ b/libc/nt/KernelBase/GetProcessImageFileNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessImageFileNameW,GetProcessImageFileNameW,677 diff --git a/libc/nt/KernelBase/GetProcessInformation.s b/libc/nt/KernelBase/GetProcessInformation.s new file mode 100644 index 00000000..f2182dc9 --- /dev/null +++ b/libc/nt/KernelBase/GetProcessInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessInformation,GetProcessInformation,678 diff --git a/libc/nt/KernelBase/GetProcessMemoryInfo.s b/libc/nt/KernelBase/GetProcessMemoryInfo.s new file mode 100644 index 00000000..ae3f6cd6 --- /dev/null +++ b/libc/nt/KernelBase/GetProcessMemoryInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessMemoryInfo,GetProcessMemoryInfo,679 diff --git a/libc/nt/KernelBase/GetProcessMitigationPolicy.s b/libc/nt/KernelBase/GetProcessMitigationPolicy.s new file mode 100644 index 00000000..2d2af4f4 --- /dev/null +++ b/libc/nt/KernelBase/GetProcessMitigationPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessMitigationPolicy,GetProcessMitigationPolicy,680 diff --git a/libc/nt/KernelBase/GetProcessPreferredUILanguages.s b/libc/nt/KernelBase/GetProcessPreferredUILanguages.s new file mode 100644 index 00000000..f3c64fb2 --- /dev/null +++ b/libc/nt/KernelBase/GetProcessPreferredUILanguages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessPreferredUILanguages,GetProcessPreferredUILanguages,681 diff --git a/libc/nt/KernelBase/GetProcessPriorityBoost.s b/libc/nt/KernelBase/GetProcessPriorityBoost.s new file mode 100644 index 00000000..ed8e0559 --- /dev/null +++ b/libc/nt/KernelBase/GetProcessPriorityBoost.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessPriorityBoost,GetProcessPriorityBoost,682 + + .text.windows +GetProcessPriorityBoost: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetProcessPriorityBoost(%rip),%rax + jmp __sysv2nt + .endfn GetProcessPriorityBoost,globl + .previous diff --git a/libc/nt/KernelBase/GetProcessShutdownParameters.s b/libc/nt/KernelBase/GetProcessShutdownParameters.s new file mode 100644 index 00000000..69ea87b3 --- /dev/null +++ b/libc/nt/KernelBase/GetProcessShutdownParameters.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessShutdownParameters,GetProcessShutdownParameters,683 diff --git a/libc/nt/KernelBase/GetProcessTimes.s b/libc/nt/KernelBase/GetProcessTimes.s new file mode 100644 index 00000000..00eeb18b --- /dev/null +++ b/libc/nt/KernelBase/GetProcessTimes.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessTimes,GetProcessTimes,684 + + .text.windows +GetProcessTimes: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetProcessTimes(%rip),%rax + jmp __sysv2nt6 + .endfn GetProcessTimes,globl + .previous diff --git a/libc/nt/KernelBase/GetProcessVersion.s b/libc/nt/KernelBase/GetProcessVersion.s new file mode 100644 index 00000000..c46a5894 --- /dev/null +++ b/libc/nt/KernelBase/GetProcessVersion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessVersion,GetProcessVersion,685 diff --git a/libc/nt/KernelBase/GetProcessWorkingSetSizeEx.s b/libc/nt/KernelBase/GetProcessWorkingSetSizeEx.s new file mode 100644 index 00000000..0c73e56c --- /dev/null +++ b/libc/nt/KernelBase/GetProcessWorkingSetSizeEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessWorkingSetSizeEx,GetProcessWorkingSetSizeEx,686 + + .text.windows +GetProcessWorkingSetSizeEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetProcessWorkingSetSizeEx(%rip),%rax + jmp __sysv2nt + .endfn GetProcessWorkingSetSizeEx,globl + .previous diff --git a/libc/nt/KernelBase/GetProcessorSystemCycleTime.s b/libc/nt/KernelBase/GetProcessorSystemCycleTime.s new file mode 100644 index 00000000..40233183 --- /dev/null +++ b/libc/nt/KernelBase/GetProcessorSystemCycleTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProcessorSystemCycleTime,GetProcessorSystemCycleTime,687 diff --git a/libc/nt/KernelBase/GetProductInfo.s b/libc/nt/KernelBase/GetProductInfo.s new file mode 100644 index 00000000..73f5e03f --- /dev/null +++ b/libc/nt/KernelBase/GetProductInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProductInfo,GetProductInfo,688 diff --git a/libc/nt/KernelBase/GetProtocolAumid.s b/libc/nt/KernelBase/GetProtocolAumid.s new file mode 100644 index 00000000..5aebc463 --- /dev/null +++ b/libc/nt/KernelBase/GetProtocolAumid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProtocolAumid,GetProtocolAumid,689 diff --git a/libc/nt/KernelBase/GetProtocolProperty.s b/libc/nt/KernelBase/GetProtocolProperty.s new file mode 100644 index 00000000..07a4a401 --- /dev/null +++ b/libc/nt/KernelBase/GetProtocolProperty.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetProtocolProperty,GetProtocolProperty,690 diff --git a/libc/nt/KernelBase/GetPtrCalData.s b/libc/nt/KernelBase/GetPtrCalData.s new file mode 100644 index 00000000..dbf51622 --- /dev/null +++ b/libc/nt/KernelBase/GetPtrCalData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPtrCalData,GetPtrCalData,691 diff --git a/libc/nt/KernelBase/GetPtrCalDataArray.s b/libc/nt/KernelBase/GetPtrCalDataArray.s new file mode 100644 index 00000000..657fec32 --- /dev/null +++ b/libc/nt/KernelBase/GetPtrCalDataArray.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPtrCalDataArray,GetPtrCalDataArray,692 diff --git a/libc/nt/KernelBase/GetPublisherCacheFolder.s b/libc/nt/KernelBase/GetPublisherCacheFolder.s new file mode 100644 index 00000000..848d0130 --- /dev/null +++ b/libc/nt/KernelBase/GetPublisherCacheFolder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPublisherCacheFolder,GetPublisherCacheFolder,693 diff --git a/libc/nt/KernelBase/GetPublisherRootFolder.s b/libc/nt/KernelBase/GetPublisherRootFolder.s new file mode 100644 index 00000000..0fd11290 --- /dev/null +++ b/libc/nt/KernelBase/GetPublisherRootFolder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetPublisherRootFolder,GetPublisherRootFolder,694 diff --git a/libc/nt/KernelBase/GetQueuedCompletionStatus.s b/libc/nt/KernelBase/GetQueuedCompletionStatus.s new file mode 100644 index 00000000..026f4ec6 --- /dev/null +++ b/libc/nt/KernelBase/GetQueuedCompletionStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetQueuedCompletionStatus,GetQueuedCompletionStatus,695 diff --git a/libc/nt/KernelBase/GetQueuedCompletionStatusEx.s b/libc/nt/KernelBase/GetQueuedCompletionStatusEx.s new file mode 100644 index 00000000..c310de42 --- /dev/null +++ b/libc/nt/KernelBase/GetQueuedCompletionStatusEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetQueuedCompletionStatusEx,GetQueuedCompletionStatusEx,696 diff --git a/libc/nt/KernelBase/GetRegistryExtensionFlags.s b/libc/nt/KernelBase/GetRegistryExtensionFlags.s new file mode 100644 index 00000000..20e0e675 --- /dev/null +++ b/libc/nt/KernelBase/GetRegistryExtensionFlags.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetRegistryExtensionFlags,GetRegistryExtensionFlags,697 diff --git a/libc/nt/KernelBase/GetRegistryValueWithFallbackW.s b/libc/nt/KernelBase/GetRegistryValueWithFallbackW.s new file mode 100644 index 00000000..6fbadf9a --- /dev/null +++ b/libc/nt/KernelBase/GetRegistryValueWithFallbackW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetRegistryValueWithFallbackW,GetRegistryValueWithFallbackW,698 diff --git a/libc/nt/KernelBase/GetRoamingLastObservedChangeTime.s b/libc/nt/KernelBase/GetRoamingLastObservedChangeTime.s new file mode 100644 index 00000000..e02726d7 --- /dev/null +++ b/libc/nt/KernelBase/GetRoamingLastObservedChangeTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetRoamingLastObservedChangeTime,GetRoamingLastObservedChangeTime,699 diff --git a/libc/nt/KernelBase/GetSecureSystemAppDataFolder.s b/libc/nt/KernelBase/GetSecureSystemAppDataFolder.s new file mode 100644 index 00000000..8fb31bbd --- /dev/null +++ b/libc/nt/KernelBase/GetSecureSystemAppDataFolder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSecureSystemAppDataFolder,GetSecureSystemAppDataFolder,700 diff --git a/libc/nt/KernelBase/GetSecurityDescriptorControl.s b/libc/nt/KernelBase/GetSecurityDescriptorControl.s new file mode 100644 index 00000000..c6385816 --- /dev/null +++ b/libc/nt/KernelBase/GetSecurityDescriptorControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSecurityDescriptorControl,GetSecurityDescriptorControl,701 diff --git a/libc/nt/KernelBase/GetSecurityDescriptorDacl.s b/libc/nt/KernelBase/GetSecurityDescriptorDacl.s new file mode 100644 index 00000000..8bd3e0bc --- /dev/null +++ b/libc/nt/KernelBase/GetSecurityDescriptorDacl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSecurityDescriptorDacl,GetSecurityDescriptorDacl,702 diff --git a/libc/nt/KernelBase/GetSecurityDescriptorGroup.s b/libc/nt/KernelBase/GetSecurityDescriptorGroup.s new file mode 100644 index 00000000..2f01896e --- /dev/null +++ b/libc/nt/KernelBase/GetSecurityDescriptorGroup.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSecurityDescriptorGroup,GetSecurityDescriptorGroup,703 diff --git a/libc/nt/KernelBase/GetSecurityDescriptorLength.s b/libc/nt/KernelBase/GetSecurityDescriptorLength.s new file mode 100644 index 00000000..2ddde2e1 --- /dev/null +++ b/libc/nt/KernelBase/GetSecurityDescriptorLength.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSecurityDescriptorLength,GetSecurityDescriptorLength,704 diff --git a/libc/nt/KernelBase/GetSecurityDescriptorOwner.s b/libc/nt/KernelBase/GetSecurityDescriptorOwner.s new file mode 100644 index 00000000..677b1766 --- /dev/null +++ b/libc/nt/KernelBase/GetSecurityDescriptorOwner.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSecurityDescriptorOwner,GetSecurityDescriptorOwner,705 diff --git a/libc/nt/KernelBase/GetSecurityDescriptorRMControl.s b/libc/nt/KernelBase/GetSecurityDescriptorRMControl.s new file mode 100644 index 00000000..26f4ff6e --- /dev/null +++ b/libc/nt/KernelBase/GetSecurityDescriptorRMControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSecurityDescriptorRMControl,GetSecurityDescriptorRMControl,706 diff --git a/libc/nt/KernelBase/GetSecurityDescriptorSacl.s b/libc/nt/KernelBase/GetSecurityDescriptorSacl.s new file mode 100644 index 00000000..00c0f81f --- /dev/null +++ b/libc/nt/KernelBase/GetSecurityDescriptorSacl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSecurityDescriptorSacl,GetSecurityDescriptorSacl,707 diff --git a/libc/nt/KernelBase/GetSerializedAtomBytes.s b/libc/nt/KernelBase/GetSerializedAtomBytes.s new file mode 100644 index 00000000..a8331eb7 --- /dev/null +++ b/libc/nt/KernelBase/GetSerializedAtomBytes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSerializedAtomBytes,GetSerializedAtomBytes,708 diff --git a/libc/nt/KernelBase/GetSharedLocalFolder.s b/libc/nt/KernelBase/GetSharedLocalFolder.s new file mode 100644 index 00000000..9feb9303 --- /dev/null +++ b/libc/nt/KernelBase/GetSharedLocalFolder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSharedLocalFolder,GetSharedLocalFolder,709 diff --git a/libc/nt/KernelBase/GetShortPathNameW.s b/libc/nt/KernelBase/GetShortPathNameW.s new file mode 100644 index 00000000..57332178 --- /dev/null +++ b/libc/nt/KernelBase/GetShortPathNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetShortPathNameW,GetShortPathNameW,710 diff --git a/libc/nt/KernelBase/GetSidIdentifierAuthority.s b/libc/nt/KernelBase/GetSidIdentifierAuthority.s new file mode 100644 index 00000000..3cf5b257 --- /dev/null +++ b/libc/nt/KernelBase/GetSidIdentifierAuthority.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSidIdentifierAuthority,GetSidIdentifierAuthority,711 diff --git a/libc/nt/KernelBase/GetSidLengthRequired.s b/libc/nt/KernelBase/GetSidLengthRequired.s new file mode 100644 index 00000000..0804fc08 --- /dev/null +++ b/libc/nt/KernelBase/GetSidLengthRequired.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSidLengthRequired,GetSidLengthRequired,712 diff --git a/libc/nt/KernelBase/GetSidSubAuthority.s b/libc/nt/KernelBase/GetSidSubAuthority.s new file mode 100644 index 00000000..23b79834 --- /dev/null +++ b/libc/nt/KernelBase/GetSidSubAuthority.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSidSubAuthority,GetSidSubAuthority,713 diff --git a/libc/nt/KernelBase/GetSidSubAuthorityCount.s b/libc/nt/KernelBase/GetSidSubAuthorityCount.s new file mode 100644 index 00000000..d5e567cd --- /dev/null +++ b/libc/nt/KernelBase/GetSidSubAuthorityCount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSidSubAuthorityCount,GetSidSubAuthorityCount,714 diff --git a/libc/nt/KernelBase/GetStagedPackageOrigin.s b/libc/nt/KernelBase/GetStagedPackageOrigin.s new file mode 100644 index 00000000..361b67b7 --- /dev/null +++ b/libc/nt/KernelBase/GetStagedPackageOrigin.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetStagedPackageOrigin,GetStagedPackageOrigin,715 diff --git a/libc/nt/KernelBase/GetStagedPackagePathByFullName.s b/libc/nt/KernelBase/GetStagedPackagePathByFullName.s new file mode 100644 index 00000000..576ef4ab --- /dev/null +++ b/libc/nt/KernelBase/GetStagedPackagePathByFullName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetStagedPackagePathByFullName,GetStagedPackagePathByFullName,716 diff --git a/libc/nt/KernelBase/GetStartupInfoW.s b/libc/nt/KernelBase/GetStartupInfoW.s new file mode 100644 index 00000000..121cf944 --- /dev/null +++ b/libc/nt/KernelBase/GetStartupInfoW.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetStartupInfoW,GetStartupInfoW,717 + + .text.windows +GetStartupInfo: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetStartupInfoW(%rip) + leave + ret + .endfn GetStartupInfo,globl + .previous diff --git a/libc/nt/KernelBase/GetStateContainerDepth.s b/libc/nt/KernelBase/GetStateContainerDepth.s new file mode 100644 index 00000000..78f7244b --- /dev/null +++ b/libc/nt/KernelBase/GetStateContainerDepth.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetStateContainerDepth,GetStateContainerDepth,718 diff --git a/libc/nt/KernelBase/GetStateFolder.s b/libc/nt/KernelBase/GetStateFolder.s new file mode 100644 index 00000000..2388a907 --- /dev/null +++ b/libc/nt/KernelBase/GetStateFolder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetStateFolder,GetStateFolder,719 diff --git a/libc/nt/KernelBase/GetStateRootFolder.s b/libc/nt/KernelBase/GetStateRootFolder.s new file mode 100644 index 00000000..62099477 --- /dev/null +++ b/libc/nt/KernelBase/GetStateRootFolder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetStateRootFolder,GetStateRootFolder,720 diff --git a/libc/nt/KernelBase/GetStateRootFolderBase.s b/libc/nt/KernelBase/GetStateRootFolderBase.s new file mode 100644 index 00000000..beecf518 --- /dev/null +++ b/libc/nt/KernelBase/GetStateRootFolderBase.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetStateRootFolderBase,GetStateRootFolderBase,721 diff --git a/libc/nt/KernelBase/GetStateSettingsFolder.s b/libc/nt/KernelBase/GetStateSettingsFolder.s new file mode 100644 index 00000000..5dad55cf --- /dev/null +++ b/libc/nt/KernelBase/GetStateSettingsFolder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetStateSettingsFolder,GetStateSettingsFolder,722 diff --git a/libc/nt/KernelBase/GetStateVersion.s b/libc/nt/KernelBase/GetStateVersion.s new file mode 100644 index 00000000..511b7f7d --- /dev/null +++ b/libc/nt/KernelBase/GetStateVersion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetStateVersion,GetStateVersion,723 diff --git a/libc/nt/KernelBase/GetStdHandle.s b/libc/nt/KernelBase/GetStdHandle.s new file mode 100644 index 00000000..b975b190 --- /dev/null +++ b/libc/nt/KernelBase/GetStdHandle.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetStdHandle,GetStdHandle,724 + + .text.windows +GetStdHandle: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetStdHandle(%rip) + leave + ret + .endfn GetStdHandle,globl + .previous diff --git a/libc/nt/KernelBase/GetStringScripts.s b/libc/nt/KernelBase/GetStringScripts.s new file mode 100644 index 00000000..3380eb62 --- /dev/null +++ b/libc/nt/KernelBase/GetStringScripts.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetStringScripts,GetStringScripts,725 diff --git a/libc/nt/KernelBase/GetStringTableEntry.s b/libc/nt/KernelBase/GetStringTableEntry.s new file mode 100644 index 00000000..73a3fdc6 --- /dev/null +++ b/libc/nt/KernelBase/GetStringTableEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetStringTableEntry,GetStringTableEntry,726 diff --git a/libc/nt/KernelBase/GetStringTypeA.s b/libc/nt/KernelBase/GetStringTypeA.s new file mode 100644 index 00000000..6489e179 --- /dev/null +++ b/libc/nt/KernelBase/GetStringTypeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetStringTypeA,GetStringTypeA,727 diff --git a/libc/nt/KernelBase/GetStringTypeExW.s b/libc/nt/KernelBase/GetStringTypeExW.s new file mode 100644 index 00000000..d86bc6a7 --- /dev/null +++ b/libc/nt/KernelBase/GetStringTypeExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetStringTypeExW,GetStringTypeExW,728 diff --git a/libc/nt/KernelBase/GetStringTypeW.s b/libc/nt/KernelBase/GetStringTypeW.s new file mode 100644 index 00000000..61cd4aa2 --- /dev/null +++ b/libc/nt/KernelBase/GetStringTypeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetStringTypeW,GetStringTypeW,729 diff --git a/libc/nt/KernelBase/GetSystemAppDataFolder.s b/libc/nt/KernelBase/GetSystemAppDataFolder.s new file mode 100644 index 00000000..f74ac604 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemAppDataFolder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemAppDataFolder,GetSystemAppDataFolder,730 diff --git a/libc/nt/KernelBase/GetSystemAppDataKey.s b/libc/nt/KernelBase/GetSystemAppDataKey.s new file mode 100644 index 00000000..569d488c --- /dev/null +++ b/libc/nt/KernelBase/GetSystemAppDataKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemAppDataKey,GetSystemAppDataKey,731 diff --git a/libc/nt/KernelBase/GetSystemCpuSetInformation.s b/libc/nt/KernelBase/GetSystemCpuSetInformation.s new file mode 100644 index 00000000..46e19fb3 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemCpuSetInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemCpuSetInformation,GetSystemCpuSetInformation,732 diff --git a/libc/nt/KernelBase/GetSystemDefaultLCID.s b/libc/nt/KernelBase/GetSystemDefaultLCID.s new file mode 100644 index 00000000..06179533 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemDefaultLCID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemDefaultLCID,GetSystemDefaultLCID,733 diff --git a/libc/nt/KernelBase/GetSystemDefaultLangID.s b/libc/nt/KernelBase/GetSystemDefaultLangID.s new file mode 100644 index 00000000..925198a8 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemDefaultLangID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemDefaultLangID,GetSystemDefaultLangID,734 diff --git a/libc/nt/KernelBase/GetSystemDefaultLocaleName.s b/libc/nt/KernelBase/GetSystemDefaultLocaleName.s new file mode 100644 index 00000000..106d03f7 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemDefaultLocaleName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemDefaultLocaleName,GetSystemDefaultLocaleName,735 diff --git a/libc/nt/KernelBase/GetSystemDefaultUILanguage.s b/libc/nt/KernelBase/GetSystemDefaultUILanguage.s new file mode 100644 index 00000000..9398e8b4 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemDefaultUILanguage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemDefaultUILanguage,GetSystemDefaultUILanguage,736 diff --git a/libc/nt/KernelBase/GetSystemDirectoryA.s b/libc/nt/KernelBase/GetSystemDirectoryA.s new file mode 100644 index 00000000..59caba2c --- /dev/null +++ b/libc/nt/KernelBase/GetSystemDirectoryA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemDirectoryA,GetSystemDirectoryA,737 + + .text.windows +GetSystemDirectoryA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetSystemDirectoryA(%rip),%rax + jmp __sysv2nt + .endfn GetSystemDirectoryA,globl + .previous diff --git a/libc/nt/KernelBase/GetSystemDirectoryW.s b/libc/nt/KernelBase/GetSystemDirectoryW.s new file mode 100644 index 00000000..337b1470 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemDirectoryW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemDirectoryW,GetSystemDirectoryW,738 + + .text.windows +GetSystemDirectory: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetSystemDirectoryW(%rip),%rax + jmp __sysv2nt + .endfn GetSystemDirectory,globl + .previous diff --git a/libc/nt/KernelBase/GetSystemFileCacheSize.s b/libc/nt/KernelBase/GetSystemFileCacheSize.s new file mode 100644 index 00000000..6fa7c4c5 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemFileCacheSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemFileCacheSize,GetSystemFileCacheSize,739 diff --git a/libc/nt/KernelBase/GetSystemFirmwareTable.s b/libc/nt/KernelBase/GetSystemFirmwareTable.s new file mode 100644 index 00000000..3e3fa2b9 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemFirmwareTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemFirmwareTable,GetSystemFirmwareTable,740 diff --git a/libc/nt/KernelBase/GetSystemInfo.s b/libc/nt/KernelBase/GetSystemInfo.s new file mode 100644 index 00000000..3f7c719f --- /dev/null +++ b/libc/nt/KernelBase/GetSystemInfo.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemInfo,GetSystemInfo,741 + + .text.windows +GetSystemInfo: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetSystemInfo(%rip) + leave + ret + .endfn GetSystemInfo,globl + .previous diff --git a/libc/nt/KernelBase/GetSystemMetadataPath.s b/libc/nt/KernelBase/GetSystemMetadataPath.s new file mode 100644 index 00000000..b28fdb4e --- /dev/null +++ b/libc/nt/KernelBase/GetSystemMetadataPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemMetadataPath,GetSystemMetadataPath,742 diff --git a/libc/nt/KernelBase/GetSystemMetadataPathForPackage.s b/libc/nt/KernelBase/GetSystemMetadataPathForPackage.s new file mode 100644 index 00000000..542f1da4 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemMetadataPathForPackage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemMetadataPathForPackage,GetSystemMetadataPathForPackage,743 diff --git a/libc/nt/KernelBase/GetSystemMetadataPathForPackageFamily.s b/libc/nt/KernelBase/GetSystemMetadataPathForPackageFamily.s new file mode 100644 index 00000000..011c50ef --- /dev/null +++ b/libc/nt/KernelBase/GetSystemMetadataPathForPackageFamily.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemMetadataPathForPackageFamily,GetSystemMetadataPathForPackageFamily,744 diff --git a/libc/nt/KernelBase/GetSystemPreferredUILanguages.s b/libc/nt/KernelBase/GetSystemPreferredUILanguages.s new file mode 100644 index 00000000..a6db0abc --- /dev/null +++ b/libc/nt/KernelBase/GetSystemPreferredUILanguages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemPreferredUILanguages,GetSystemPreferredUILanguages,745 diff --git a/libc/nt/KernelBase/GetSystemStateRootFolder.s b/libc/nt/KernelBase/GetSystemStateRootFolder.s new file mode 100644 index 00000000..d6405f23 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemStateRootFolder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemStateRootFolder,GetSystemStateRootFolder,746 diff --git a/libc/nt/KernelBase/GetSystemTime.s b/libc/nt/KernelBase/GetSystemTime.s new file mode 100644 index 00000000..084032e0 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemTime.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemTime,GetSystemTime,747 + + .text.windows +GetSystemTime: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetSystemTime(%rip) + leave + ret + .endfn GetSystemTime,globl + .previous diff --git a/libc/nt/KernelBase/GetSystemTimeAdjustment.s b/libc/nt/KernelBase/GetSystemTimeAdjustment.s new file mode 100644 index 00000000..8c42d424 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemTimeAdjustment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemTimeAdjustment,GetSystemTimeAdjustment,748 diff --git a/libc/nt/KernelBase/GetSystemTimeAdjustmentPrecise.s b/libc/nt/KernelBase/GetSystemTimeAdjustmentPrecise.s new file mode 100644 index 00000000..b5088b48 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemTimeAdjustmentPrecise.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemTimeAdjustmentPrecise,GetSystemTimeAdjustmentPrecise,749 diff --git a/libc/nt/KernelBase/GetSystemTimeAsFileTime.s b/libc/nt/KernelBase/GetSystemTimeAsFileTime.s new file mode 100644 index 00000000..b87fb5e5 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemTimeAsFileTime.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemTimeAsFileTime,GetSystemTimeAsFileTime,750 + + .text.windows +GetSystemTimeAsFileTime: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetSystemTimeAsFileTime(%rip) + leave + ret + .endfn GetSystemTimeAsFileTime,globl + .previous diff --git a/libc/nt/KernelBase/GetSystemTimePreciseAsFileTime.s b/libc/nt/KernelBase/GetSystemTimePreciseAsFileTime.s new file mode 100644 index 00000000..1dfaadb8 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemTimePreciseAsFileTime.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemTimePreciseAsFileTime,GetSystemTimePreciseAsFileTime,751 + + .text.windows +GetSystemTimePreciseAsFileTime: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetSystemTimePreciseAsFileTime(%rip) + leave + ret + .endfn GetSystemTimePreciseAsFileTime,globl + .previous diff --git a/libc/nt/KernelBase/GetSystemTimes.s b/libc/nt/KernelBase/GetSystemTimes.s new file mode 100644 index 00000000..c8cb84d0 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemTimes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemTimes,GetSystemTimes,752 diff --git a/libc/nt/KernelBase/GetSystemWindowsDirectoryA.s b/libc/nt/KernelBase/GetSystemWindowsDirectoryA.s new file mode 100644 index 00000000..32005241 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemWindowsDirectoryA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemWindowsDirectoryA,GetSystemWindowsDirectoryA,753 diff --git a/libc/nt/KernelBase/GetSystemWindowsDirectoryW.s b/libc/nt/KernelBase/GetSystemWindowsDirectoryW.s new file mode 100644 index 00000000..bf4f0109 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemWindowsDirectoryW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemWindowsDirectoryW,GetSystemWindowsDirectoryW,754 diff --git a/libc/nt/KernelBase/GetSystemWow64Directory2A.s b/libc/nt/KernelBase/GetSystemWow64Directory2A.s new file mode 100644 index 00000000..7cb6c4b2 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemWow64Directory2A.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemWow64Directory2A,GetSystemWow64Directory2A,755 diff --git a/libc/nt/KernelBase/GetSystemWow64Directory2W.s b/libc/nt/KernelBase/GetSystemWow64Directory2W.s new file mode 100644 index 00000000..4fd0b2a1 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemWow64Directory2W.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemWow64Directory2W,GetSystemWow64Directory2W,756 diff --git a/libc/nt/KernelBase/GetSystemWow64DirectoryA.s b/libc/nt/KernelBase/GetSystemWow64DirectoryA.s new file mode 100644 index 00000000..96e9d718 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemWow64DirectoryA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemWow64DirectoryA,GetSystemWow64DirectoryA,757 diff --git a/libc/nt/KernelBase/GetSystemWow64DirectoryW.s b/libc/nt/KernelBase/GetSystemWow64DirectoryW.s new file mode 100644 index 00000000..697b9423 --- /dev/null +++ b/libc/nt/KernelBase/GetSystemWow64DirectoryW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetSystemWow64DirectoryW,GetSystemWow64DirectoryW,758 diff --git a/libc/nt/KernelBase/GetTargetPlatformContext.s b/libc/nt/KernelBase/GetTargetPlatformContext.s new file mode 100644 index 00000000..85440595 --- /dev/null +++ b/libc/nt/KernelBase/GetTargetPlatformContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetTargetPlatformContext,GetTargetPlatformContext,759 diff --git a/libc/nt/KernelBase/GetTempFileNameA.s b/libc/nt/KernelBase/GetTempFileNameA.s new file mode 100644 index 00000000..e1f5abb3 --- /dev/null +++ b/libc/nt/KernelBase/GetTempFileNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetTempFileNameA,GetTempFileNameA,760 diff --git a/libc/nt/KernelBase/GetTempFileNameW.s b/libc/nt/KernelBase/GetTempFileNameW.s new file mode 100644 index 00000000..54be57a5 --- /dev/null +++ b/libc/nt/KernelBase/GetTempFileNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetTempFileNameW,GetTempFileNameW,761 diff --git a/libc/nt/KernelBase/GetTempPathA.s b/libc/nt/KernelBase/GetTempPathA.s new file mode 100644 index 00000000..74aa5dc8 --- /dev/null +++ b/libc/nt/KernelBase/GetTempPathA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetTempPathA,GetTempPathA,762 + + .text.windows +GetTempPathA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetTempPathA(%rip),%rax + jmp __sysv2nt + .endfn GetTempPathA,globl + .previous diff --git a/libc/nt/KernelBase/GetTempPathW.s b/libc/nt/KernelBase/GetTempPathW.s new file mode 100644 index 00000000..76147c1d --- /dev/null +++ b/libc/nt/KernelBase/GetTempPathW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetTempPathW,GetTempPathW,763 + + .text.windows +GetTempPath: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetTempPathW(%rip),%rax + jmp __sysv2nt + .endfn GetTempPath,globl + .previous diff --git a/libc/nt/KernelBase/GetThreadContext.s b/libc/nt/KernelBase/GetThreadContext.s new file mode 100644 index 00000000..12860e04 --- /dev/null +++ b/libc/nt/KernelBase/GetThreadContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetThreadContext,GetThreadContext,764 diff --git a/libc/nt/KernelBase/GetThreadDescription.s b/libc/nt/KernelBase/GetThreadDescription.s new file mode 100644 index 00000000..3fccdd4d --- /dev/null +++ b/libc/nt/KernelBase/GetThreadDescription.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetThreadDescription,GetThreadDescription,765 diff --git a/libc/nt/KernelBase/GetThreadErrorMode.s b/libc/nt/KernelBase/GetThreadErrorMode.s new file mode 100644 index 00000000..0f3c92aa --- /dev/null +++ b/libc/nt/KernelBase/GetThreadErrorMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetThreadErrorMode,GetThreadErrorMode,766 diff --git a/libc/nt/KernelBase/GetThreadGroupAffinity.s b/libc/nt/KernelBase/GetThreadGroupAffinity.s new file mode 100644 index 00000000..ec6a47d4 --- /dev/null +++ b/libc/nt/KernelBase/GetThreadGroupAffinity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetThreadGroupAffinity,GetThreadGroupAffinity,767 diff --git a/libc/nt/KernelBase/GetThreadIOPendingFlag.s b/libc/nt/KernelBase/GetThreadIOPendingFlag.s new file mode 100644 index 00000000..30a22fe9 --- /dev/null +++ b/libc/nt/KernelBase/GetThreadIOPendingFlag.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetThreadIOPendingFlag,GetThreadIOPendingFlag,768 + + .text.windows +GetThreadIOPendingFlag: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetThreadIOPendingFlag(%rip),%rax + jmp __sysv2nt + .endfn GetThreadIOPendingFlag,globl + .previous diff --git a/libc/nt/KernelBase/GetThreadId.s b/libc/nt/KernelBase/GetThreadId.s new file mode 100644 index 00000000..4eb15d74 --- /dev/null +++ b/libc/nt/KernelBase/GetThreadId.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetThreadId,GetThreadId,769 + + .text.windows +GetThreadId: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetThreadId(%rip) + leave + ret + .endfn GetThreadId,globl + .previous diff --git a/libc/nt/KernelBase/GetThreadIdealProcessorEx.s b/libc/nt/KernelBase/GetThreadIdealProcessorEx.s new file mode 100644 index 00000000..55ceeba8 --- /dev/null +++ b/libc/nt/KernelBase/GetThreadIdealProcessorEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetThreadIdealProcessorEx,GetThreadIdealProcessorEx,770 diff --git a/libc/nt/KernelBase/GetThreadInformation.s b/libc/nt/KernelBase/GetThreadInformation.s new file mode 100644 index 00000000..89072aea --- /dev/null +++ b/libc/nt/KernelBase/GetThreadInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetThreadInformation,GetThreadInformation,771 diff --git a/libc/nt/KernelBase/GetThreadLocale.s b/libc/nt/KernelBase/GetThreadLocale.s new file mode 100644 index 00000000..5a64e679 --- /dev/null +++ b/libc/nt/KernelBase/GetThreadLocale.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetThreadLocale,GetThreadLocale,772 diff --git a/libc/nt/KernelBase/GetThreadPreferredUILanguages.s b/libc/nt/KernelBase/GetThreadPreferredUILanguages.s new file mode 100644 index 00000000..dcbde198 --- /dev/null +++ b/libc/nt/KernelBase/GetThreadPreferredUILanguages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetThreadPreferredUILanguages,GetThreadPreferredUILanguages,773 diff --git a/libc/nt/KernelBase/GetThreadPriority.s b/libc/nt/KernelBase/GetThreadPriority.s new file mode 100644 index 00000000..249f7108 --- /dev/null +++ b/libc/nt/KernelBase/GetThreadPriority.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetThreadPriority,GetThreadPriority,774 + + .text.windows +GetThreadPriority: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetThreadPriority(%rip) + leave + ret + .endfn GetThreadPriority,globl + .previous diff --git a/libc/nt/KernelBase/GetThreadPriorityBoost.s b/libc/nt/KernelBase/GetThreadPriorityBoost.s new file mode 100644 index 00000000..385a0d6d --- /dev/null +++ b/libc/nt/KernelBase/GetThreadPriorityBoost.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetThreadPriorityBoost,GetThreadPriorityBoost,775 + + .text.windows +GetThreadPriorityBoost: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetThreadPriorityBoost(%rip),%rax + jmp __sysv2nt + .endfn GetThreadPriorityBoost,globl + .previous diff --git a/libc/nt/KernelBase/GetThreadSelectedCpuSets.s b/libc/nt/KernelBase/GetThreadSelectedCpuSets.s new file mode 100644 index 00000000..045440ad --- /dev/null +++ b/libc/nt/KernelBase/GetThreadSelectedCpuSets.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetThreadSelectedCpuSets,GetThreadSelectedCpuSets,776 diff --git a/libc/nt/KernelBase/GetThreadTimes.s b/libc/nt/KernelBase/GetThreadTimes.s new file mode 100644 index 00000000..ac252c8a --- /dev/null +++ b/libc/nt/KernelBase/GetThreadTimes.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetThreadTimes,GetThreadTimes,777 + + .text.windows +GetThreadTimes: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetThreadTimes(%rip),%rax + jmp __sysv2nt6 + .endfn GetThreadTimes,globl + .previous diff --git a/libc/nt/KernelBase/GetThreadUILanguage.s b/libc/nt/KernelBase/GetThreadUILanguage.s new file mode 100644 index 00000000..d9d7d30a --- /dev/null +++ b/libc/nt/KernelBase/GetThreadUILanguage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetThreadUILanguage,GetThreadUILanguage,778 diff --git a/libc/nt/KernelBase/GetTickCount.s b/libc/nt/KernelBase/GetTickCount.s new file mode 100644 index 00000000..075daa2a --- /dev/null +++ b/libc/nt/KernelBase/GetTickCount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetTickCount,GetTickCount,779 diff --git a/libc/nt/KernelBase/GetTickCount64.s b/libc/nt/KernelBase/GetTickCount64.s new file mode 100644 index 00000000..0a90d908 --- /dev/null +++ b/libc/nt/KernelBase/GetTickCount64.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetTickCount64,GetTickCount64,780 diff --git a/libc/nt/KernelBase/GetTimeFormatA.s b/libc/nt/KernelBase/GetTimeFormatA.s new file mode 100644 index 00000000..7471b763 --- /dev/null +++ b/libc/nt/KernelBase/GetTimeFormatA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetTimeFormatA,GetTimeFormatA,781 diff --git a/libc/nt/KernelBase/GetTimeFormatEx.s b/libc/nt/KernelBase/GetTimeFormatEx.s new file mode 100644 index 00000000..a9dd0a66 --- /dev/null +++ b/libc/nt/KernelBase/GetTimeFormatEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetTimeFormatEx,GetTimeFormatEx,782 diff --git a/libc/nt/KernelBase/GetTimeFormatW.s b/libc/nt/KernelBase/GetTimeFormatW.s new file mode 100644 index 00000000..d47b862b --- /dev/null +++ b/libc/nt/KernelBase/GetTimeFormatW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetTimeFormatW,GetTimeFormatW,783 diff --git a/libc/nt/KernelBase/GetTimeZoneInformation.s b/libc/nt/KernelBase/GetTimeZoneInformation.s new file mode 100644 index 00000000..9be1ee07 --- /dev/null +++ b/libc/nt/KernelBase/GetTimeZoneInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetTimeZoneInformation,GetTimeZoneInformation,784 diff --git a/libc/nt/KernelBase/GetTimeZoneInformationForYear.s b/libc/nt/KernelBase/GetTimeZoneInformationForYear.s new file mode 100644 index 00000000..b9c5d8c8 --- /dev/null +++ b/libc/nt/KernelBase/GetTimeZoneInformationForYear.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetTimeZoneInformationForYear,GetTimeZoneInformationForYear,785 diff --git a/libc/nt/KernelBase/GetTokenInformation.s b/libc/nt/KernelBase/GetTokenInformation.s new file mode 100644 index 00000000..1fd93155 --- /dev/null +++ b/libc/nt/KernelBase/GetTokenInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetTokenInformation,GetTokenInformation,786 diff --git a/libc/nt/KernelBase/GetUILanguageInfo.s b/libc/nt/KernelBase/GetUILanguageInfo.s new file mode 100644 index 00000000..d5ea7b09 --- /dev/null +++ b/libc/nt/KernelBase/GetUILanguageInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetUILanguageInfo,GetUILanguageInfo,790 diff --git a/libc/nt/KernelBase/GetUnicodeStringToEightBitSizeRoutine.s b/libc/nt/KernelBase/GetUnicodeStringToEightBitSizeRoutine.s new file mode 100644 index 00000000..2bfda358 --- /dev/null +++ b/libc/nt/KernelBase/GetUnicodeStringToEightBitSizeRoutine.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetUnicodeStringToEightBitSizeRoutine,GetUnicodeStringToEightBitSizeRoutine,791 diff --git a/libc/nt/KernelBase/GetUnicodeStringToEightBitStringRoutine.s b/libc/nt/KernelBase/GetUnicodeStringToEightBitStringRoutine.s new file mode 100644 index 00000000..8e16a60b --- /dev/null +++ b/libc/nt/KernelBase/GetUnicodeStringToEightBitStringRoutine.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetUnicodeStringToEightBitStringRoutine,GetUnicodeStringToEightBitStringRoutine,792 diff --git a/libc/nt/KernelBase/GetUserDefaultGeoName.s b/libc/nt/KernelBase/GetUserDefaultGeoName.s new file mode 100644 index 00000000..a97a275d --- /dev/null +++ b/libc/nt/KernelBase/GetUserDefaultGeoName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetUserDefaultGeoName,GetUserDefaultGeoName,793 diff --git a/libc/nt/KernelBase/GetUserDefaultLCID.s b/libc/nt/KernelBase/GetUserDefaultLCID.s new file mode 100644 index 00000000..614dbea3 --- /dev/null +++ b/libc/nt/KernelBase/GetUserDefaultLCID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetUserDefaultLCID,GetUserDefaultLCID,794 diff --git a/libc/nt/KernelBase/GetUserDefaultLangID.s b/libc/nt/KernelBase/GetUserDefaultLangID.s new file mode 100644 index 00000000..199d35df --- /dev/null +++ b/libc/nt/KernelBase/GetUserDefaultLangID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetUserDefaultLangID,GetUserDefaultLangID,795 diff --git a/libc/nt/KernelBase/GetUserDefaultLocaleName.s b/libc/nt/KernelBase/GetUserDefaultLocaleName.s new file mode 100644 index 00000000..413429fd --- /dev/null +++ b/libc/nt/KernelBase/GetUserDefaultLocaleName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetUserDefaultLocaleName,GetUserDefaultLocaleName,796 diff --git a/libc/nt/KernelBase/GetUserDefaultUILanguage.s b/libc/nt/KernelBase/GetUserDefaultUILanguage.s new file mode 100644 index 00000000..193ea74a --- /dev/null +++ b/libc/nt/KernelBase/GetUserDefaultUILanguage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetUserDefaultUILanguage,GetUserDefaultUILanguage,797 diff --git a/libc/nt/KernelBase/GetUserGeoID.s b/libc/nt/KernelBase/GetUserGeoID.s new file mode 100644 index 00000000..c901b9e2 --- /dev/null +++ b/libc/nt/KernelBase/GetUserGeoID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetUserGeoID,GetUserGeoID,798 diff --git a/libc/nt/KernelBase/GetUserInfo.s b/libc/nt/KernelBase/GetUserInfo.s new file mode 100644 index 00000000..98deb7e2 --- /dev/null +++ b/libc/nt/KernelBase/GetUserInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetUserInfo,GetUserInfo,799 diff --git a/libc/nt/KernelBase/GetUserInfoWord.s b/libc/nt/KernelBase/GetUserInfoWord.s new file mode 100644 index 00000000..4875087f --- /dev/null +++ b/libc/nt/KernelBase/GetUserInfoWord.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetUserInfoWord,GetUserInfoWord,800 diff --git a/libc/nt/KernelBase/GetUserOverrideString.s b/libc/nt/KernelBase/GetUserOverrideString.s new file mode 100644 index 00000000..306c3659 --- /dev/null +++ b/libc/nt/KernelBase/GetUserOverrideString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetUserOverrideString,GetUserOverrideString,801 diff --git a/libc/nt/KernelBase/GetUserOverrideWord.s b/libc/nt/KernelBase/GetUserOverrideWord.s new file mode 100644 index 00000000..308ffabd --- /dev/null +++ b/libc/nt/KernelBase/GetUserOverrideWord.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetUserOverrideWord,GetUserOverrideWord,802 diff --git a/libc/nt/KernelBase/GetUserPreferredUILanguages.s b/libc/nt/KernelBase/GetUserPreferredUILanguages.s new file mode 100644 index 00000000..81432139 --- /dev/null +++ b/libc/nt/KernelBase/GetUserPreferredUILanguages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetUserPreferredUILanguages,GetUserPreferredUILanguages,803 diff --git a/libc/nt/KernelBase/GetVersion.s b/libc/nt/KernelBase/GetVersion.s new file mode 100644 index 00000000..7f5fb7a6 --- /dev/null +++ b/libc/nt/KernelBase/GetVersion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetVersion,GetVersion,804 diff --git a/libc/nt/KernelBase/GetVersionExA.s b/libc/nt/KernelBase/GetVersionExA.s new file mode 100644 index 00000000..7027ab42 --- /dev/null +++ b/libc/nt/KernelBase/GetVersionExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetVersionExA,GetVersionExA,805 diff --git a/libc/nt/KernelBase/GetVersionExW.s b/libc/nt/KernelBase/GetVersionExW.s new file mode 100644 index 00000000..304d2bdf --- /dev/null +++ b/libc/nt/KernelBase/GetVersionExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetVersionExW,GetVersionExW,806 diff --git a/libc/nt/KernelBase/GetVolumeInformationA.s b/libc/nt/KernelBase/GetVolumeInformationA.s new file mode 100644 index 00000000..c961c417 --- /dev/null +++ b/libc/nt/KernelBase/GetVolumeInformationA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetVolumeInformationA,GetVolumeInformationA,807 diff --git a/libc/nt/KernelBase/GetVolumeInformationByHandleW.s b/libc/nt/KernelBase/GetVolumeInformationByHandleW.s new file mode 100644 index 00000000..92af41da --- /dev/null +++ b/libc/nt/KernelBase/GetVolumeInformationByHandleW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetVolumeInformationByHandleW,GetVolumeInformationByHandleW,808 diff --git a/libc/nt/KernelBase/GetVolumeInformationW.s b/libc/nt/KernelBase/GetVolumeInformationW.s new file mode 100644 index 00000000..31a8f014 --- /dev/null +++ b/libc/nt/KernelBase/GetVolumeInformationW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetVolumeInformationW,GetVolumeInformationW,809 diff --git a/libc/nt/KernelBase/GetVolumeNameForVolumeMountPointW.s b/libc/nt/KernelBase/GetVolumeNameForVolumeMountPointW.s new file mode 100644 index 00000000..06c2051a --- /dev/null +++ b/libc/nt/KernelBase/GetVolumeNameForVolumeMountPointW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetVolumeNameForVolumeMountPointW,GetVolumeNameForVolumeMountPointW,810 diff --git a/libc/nt/KernelBase/GetVolumePathNameW.s b/libc/nt/KernelBase/GetVolumePathNameW.s new file mode 100644 index 00000000..42572688 --- /dev/null +++ b/libc/nt/KernelBase/GetVolumePathNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetVolumePathNameW,GetVolumePathNameW,811 diff --git a/libc/nt/KernelBase/GetVolumePathNamesForVolumeNameW.s b/libc/nt/KernelBase/GetVolumePathNamesForVolumeNameW.s new file mode 100644 index 00000000..a22fed8a --- /dev/null +++ b/libc/nt/KernelBase/GetVolumePathNamesForVolumeNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetVolumePathNamesForVolumeNameW,GetVolumePathNamesForVolumeNameW,812 diff --git a/libc/nt/KernelBase/GetWindowsAccountDomainSid.s b/libc/nt/KernelBase/GetWindowsAccountDomainSid.s new file mode 100644 index 00000000..80d38aa9 --- /dev/null +++ b/libc/nt/KernelBase/GetWindowsAccountDomainSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetWindowsAccountDomainSid,GetWindowsAccountDomainSid,813 diff --git a/libc/nt/KernelBase/GetWindowsDirectoryA.s b/libc/nt/KernelBase/GetWindowsDirectoryA.s new file mode 100644 index 00000000..2e5f020f --- /dev/null +++ b/libc/nt/KernelBase/GetWindowsDirectoryA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetWindowsDirectoryA,GetWindowsDirectoryA,814 + + .text.windows +GetWindowsDirectoryA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetWindowsDirectoryA(%rip),%rax + jmp __sysv2nt + .endfn GetWindowsDirectoryA,globl + .previous diff --git a/libc/nt/KernelBase/GetWindowsDirectoryW.s b/libc/nt/KernelBase/GetWindowsDirectoryW.s new file mode 100644 index 00000000..5e7d9849 --- /dev/null +++ b/libc/nt/KernelBase/GetWindowsDirectoryW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetWindowsDirectoryW,GetWindowsDirectoryW,815 + + .text.windows +GetWindowsDirectory: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetWindowsDirectoryW(%rip),%rax + jmp __sysv2nt + .endfn GetWindowsDirectory,globl + .previous diff --git a/libc/nt/KernelBase/GetWriteWatch.s b/libc/nt/KernelBase/GetWriteWatch.s new file mode 100644 index 00000000..0cc558fe --- /dev/null +++ b/libc/nt/KernelBase/GetWriteWatch.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetWriteWatch,GetWriteWatch,816 diff --git a/libc/nt/KernelBase/GetWsChanges.s b/libc/nt/KernelBase/GetWsChanges.s new file mode 100644 index 00000000..24cd8dad --- /dev/null +++ b/libc/nt/KernelBase/GetWsChanges.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetWsChanges,GetWsChanges,817 diff --git a/libc/nt/KernelBase/GetWsChangesEx.s b/libc/nt/KernelBase/GetWsChangesEx.s new file mode 100644 index 00000000..80b7db59 --- /dev/null +++ b/libc/nt/KernelBase/GetWsChangesEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetWsChangesEx,GetWsChangesEx,818 diff --git a/libc/nt/KernelBase/GetXStateFeaturesMask.s b/libc/nt/KernelBase/GetXStateFeaturesMask.s new file mode 100644 index 00000000..0e91d07c --- /dev/null +++ b/libc/nt/KernelBase/GetXStateFeaturesMask.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GetXStateFeaturesMask,GetXStateFeaturesMask,819 diff --git a/libc/nt/KernelBase/GlobalAlloc.s b/libc/nt/KernelBase/GlobalAlloc.s new file mode 100644 index 00000000..1fb819f8 --- /dev/null +++ b/libc/nt/KernelBase/GlobalAlloc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GlobalAlloc,GlobalAlloc,820 diff --git a/libc/nt/KernelBase/GlobalFree.s b/libc/nt/KernelBase/GlobalFree.s new file mode 100644 index 00000000..1e856527 --- /dev/null +++ b/libc/nt/KernelBase/GlobalFree.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GlobalFree,GlobalFree,821 diff --git a/libc/nt/KernelBase/GlobalMemoryStatusEx.s b/libc/nt/KernelBase/GlobalMemoryStatusEx.s new file mode 100644 index 00000000..33b67137 --- /dev/null +++ b/libc/nt/KernelBase/GlobalMemoryStatusEx.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GlobalMemoryStatusEx,GlobalMemoryStatusEx,822 + + .text.windows +GlobalMemoryStatusEx: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GlobalMemoryStatusEx(%rip) + leave + ret + .endfn GlobalMemoryStatusEx,globl + .previous diff --git a/libc/nt/KernelBase/GuardCheckLongJumpTarget.s b/libc/nt/KernelBase/GuardCheckLongJumpTarget.s new file mode 100644 index 00000000..e4196c48 --- /dev/null +++ b/libc/nt/KernelBase/GuardCheckLongJumpTarget.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_GuardCheckLongJumpTarget,GuardCheckLongJumpTarget,823 diff --git a/libc/nt/KernelBase/HasPolicyForegroundProcessingCompletedInternal.s b/libc/nt/KernelBase/HasPolicyForegroundProcessingCompletedInternal.s new file mode 100644 index 00000000..dd8b9aa7 --- /dev/null +++ b/libc/nt/KernelBase/HasPolicyForegroundProcessingCompletedInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_HasPolicyForegroundProcessingCompletedInternal,HasPolicyForegroundProcessingCompletedInternal,824 diff --git a/libc/nt/KernelBase/HashData.s b/libc/nt/KernelBase/HashData.s new file mode 100644 index 00000000..4de4e410 --- /dev/null +++ b/libc/nt/KernelBase/HashData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_HashData,HashData,825 diff --git a/libc/nt/KernelBase/HeapCompact.s b/libc/nt/KernelBase/HeapCompact.s new file mode 100644 index 00000000..0a359ceb --- /dev/null +++ b/libc/nt/KernelBase/HeapCompact.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_HeapCompact,HeapCompact,827 diff --git a/libc/nt/KernelBase/HeapCreate.s b/libc/nt/KernelBase/HeapCreate.s new file mode 100644 index 00000000..4db91458 --- /dev/null +++ b/libc/nt/KernelBase/HeapCreate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_HeapCreate,HeapCreate,828 diff --git a/libc/nt/KernelBase/HeapDestroy.s b/libc/nt/KernelBase/HeapDestroy.s new file mode 100644 index 00000000..66da19de --- /dev/null +++ b/libc/nt/KernelBase/HeapDestroy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_HeapDestroy,HeapDestroy,829 diff --git a/libc/nt/KernelBase/HeapLock.s b/libc/nt/KernelBase/HeapLock.s new file mode 100644 index 00000000..34f791a6 --- /dev/null +++ b/libc/nt/KernelBase/HeapLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_HeapLock,HeapLock,831 diff --git a/libc/nt/KernelBase/HeapQueryInformation.s b/libc/nt/KernelBase/HeapQueryInformation.s new file mode 100644 index 00000000..885adfcc --- /dev/null +++ b/libc/nt/KernelBase/HeapQueryInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_HeapQueryInformation,HeapQueryInformation,832 diff --git a/libc/nt/KernelBase/HeapSetInformation.s b/libc/nt/KernelBase/HeapSetInformation.s new file mode 100644 index 00000000..46c8cbe7 --- /dev/null +++ b/libc/nt/KernelBase/HeapSetInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_HeapSetInformation,HeapSetInformation,834 diff --git a/libc/nt/KernelBase/HeapSummary.s b/libc/nt/KernelBase/HeapSummary.s new file mode 100644 index 00000000..12ca25bc --- /dev/null +++ b/libc/nt/KernelBase/HeapSummary.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_HeapSummary,HeapSummary,836 diff --git a/libc/nt/KernelBase/HeapUnlock.s b/libc/nt/KernelBase/HeapUnlock.s new file mode 100644 index 00000000..ed8ee767 --- /dev/null +++ b/libc/nt/KernelBase/HeapUnlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_HeapUnlock,HeapUnlock,837 diff --git a/libc/nt/KernelBase/HeapValidate.s b/libc/nt/KernelBase/HeapValidate.s new file mode 100644 index 00000000..a03340d8 --- /dev/null +++ b/libc/nt/KernelBase/HeapValidate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_HeapValidate,HeapValidate,838 diff --git a/libc/nt/KernelBase/HeapWalk.s b/libc/nt/KernelBase/HeapWalk.s new file mode 100644 index 00000000..0247d6cb --- /dev/null +++ b/libc/nt/KernelBase/HeapWalk.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_HeapWalk,HeapWalk,839 diff --git a/libc/nt/KernelBase/IdnToAscii.s b/libc/nt/KernelBase/IdnToAscii.s new file mode 100644 index 00000000..dc18e73b --- /dev/null +++ b/libc/nt/KernelBase/IdnToAscii.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IdnToAscii,IdnToAscii,840 diff --git a/libc/nt/KernelBase/IdnToNameprepUnicode.s b/libc/nt/KernelBase/IdnToNameprepUnicode.s new file mode 100644 index 00000000..683b6962 --- /dev/null +++ b/libc/nt/KernelBase/IdnToNameprepUnicode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IdnToNameprepUnicode,IdnToNameprepUnicode,841 diff --git a/libc/nt/KernelBase/IdnToUnicode.s b/libc/nt/KernelBase/IdnToUnicode.s new file mode 100644 index 00000000..f5f56224 --- /dev/null +++ b/libc/nt/KernelBase/IdnToUnicode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IdnToUnicode,IdnToUnicode,842 diff --git a/libc/nt/KernelBase/ImpersonateAnonymousToken.s b/libc/nt/KernelBase/ImpersonateAnonymousToken.s new file mode 100644 index 00000000..53055d68 --- /dev/null +++ b/libc/nt/KernelBase/ImpersonateAnonymousToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ImpersonateAnonymousToken,ImpersonateAnonymousToken,843 diff --git a/libc/nt/KernelBase/ImpersonateLoggedOnUser.s b/libc/nt/KernelBase/ImpersonateLoggedOnUser.s new file mode 100644 index 00000000..87b04282 --- /dev/null +++ b/libc/nt/KernelBase/ImpersonateLoggedOnUser.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ImpersonateLoggedOnUser,ImpersonateLoggedOnUser,844 diff --git a/libc/nt/KernelBase/ImpersonateNamedPipeClient.s b/libc/nt/KernelBase/ImpersonateNamedPipeClient.s new file mode 100644 index 00000000..2ace633a --- /dev/null +++ b/libc/nt/KernelBase/ImpersonateNamedPipeClient.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ImpersonateNamedPipeClient,ImpersonateNamedPipeClient,845 diff --git a/libc/nt/KernelBase/ImpersonateSelf.s b/libc/nt/KernelBase/ImpersonateSelf.s new file mode 100644 index 00000000..6a1c6f6a --- /dev/null +++ b/libc/nt/KernelBase/ImpersonateSelf.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ImpersonateSelf,ImpersonateSelf,846 diff --git a/libc/nt/KernelBase/IncrementPackageStatusVersion.s b/libc/nt/KernelBase/IncrementPackageStatusVersion.s new file mode 100644 index 00000000..b0ed1bc9 --- /dev/null +++ b/libc/nt/KernelBase/IncrementPackageStatusVersion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IncrementPackageStatusVersion,IncrementPackageStatusVersion,847 diff --git a/libc/nt/KernelBase/InitOnceBeginInitialize.s b/libc/nt/KernelBase/InitOnceBeginInitialize.s new file mode 100644 index 00000000..51fee457 --- /dev/null +++ b/libc/nt/KernelBase/InitOnceBeginInitialize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InitOnceBeginInitialize,InitOnceBeginInitialize,848 diff --git a/libc/nt/KernelBase/InitOnceComplete.s b/libc/nt/KernelBase/InitOnceComplete.s new file mode 100644 index 00000000..74b33b6c --- /dev/null +++ b/libc/nt/KernelBase/InitOnceComplete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InitOnceComplete,InitOnceComplete,849 diff --git a/libc/nt/KernelBase/InitOnceExecuteOnce.s b/libc/nt/KernelBase/InitOnceExecuteOnce.s new file mode 100644 index 00000000..a8ed7910 --- /dev/null +++ b/libc/nt/KernelBase/InitOnceExecuteOnce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InitOnceExecuteOnce,InitOnceExecuteOnce,850 diff --git a/libc/nt/KernelBase/InitializeAcl.s b/libc/nt/KernelBase/InitializeAcl.s new file mode 100644 index 00000000..b065d9a3 --- /dev/null +++ b/libc/nt/KernelBase/InitializeAcl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InitializeAcl,InitializeAcl,852 diff --git a/libc/nt/KernelBase/InitializeContext.s b/libc/nt/KernelBase/InitializeContext.s new file mode 100644 index 00000000..bb7547d2 --- /dev/null +++ b/libc/nt/KernelBase/InitializeContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InitializeContext,InitializeContext,854 diff --git a/libc/nt/KernelBase/InitializeCriticalSectionAndSpinCount.s b/libc/nt/KernelBase/InitializeCriticalSectionAndSpinCount.s new file mode 100644 index 00000000..ef88ca05 --- /dev/null +++ b/libc/nt/KernelBase/InitializeCriticalSectionAndSpinCount.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InitializeCriticalSectionAndSpinCount,InitializeCriticalSectionAndSpinCount,856 + + .text.windows +InitializeCriticalSectionAndSpinCount: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_InitializeCriticalSectionAndSpinCount(%rip),%rax + jmp __sysv2nt + .endfn InitializeCriticalSectionAndSpinCount,globl + .previous diff --git a/libc/nt/KernelBase/InitializeCriticalSectionEx.s b/libc/nt/KernelBase/InitializeCriticalSectionEx.s new file mode 100644 index 00000000..396ae952 --- /dev/null +++ b/libc/nt/KernelBase/InitializeCriticalSectionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InitializeCriticalSectionEx,InitializeCriticalSectionEx,857 diff --git a/libc/nt/KernelBase/InitializeEnclave.s b/libc/nt/KernelBase/InitializeEnclave.s new file mode 100644 index 00000000..7ef996ad --- /dev/null +++ b/libc/nt/KernelBase/InitializeEnclave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InitializeEnclave,InitializeEnclave,858 diff --git a/libc/nt/KernelBase/InitializeProcThreadAttributeList.s b/libc/nt/KernelBase/InitializeProcThreadAttributeList.s new file mode 100644 index 00000000..68bb8243 --- /dev/null +++ b/libc/nt/KernelBase/InitializeProcThreadAttributeList.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InitializeProcThreadAttributeList,InitializeProcThreadAttributeList,859 + + .text.windows +InitializeProcThreadAttributeList: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_InitializeProcThreadAttributeList(%rip),%rax + jmp __sysv2nt + .endfn InitializeProcThreadAttributeList,globl + .previous diff --git a/libc/nt/KernelBase/InitializeProcessForWsWatch.s b/libc/nt/KernelBase/InitializeProcessForWsWatch.s new file mode 100644 index 00000000..6b62b5f8 --- /dev/null +++ b/libc/nt/KernelBase/InitializeProcessForWsWatch.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InitializeProcessForWsWatch,InitializeProcessForWsWatch,860 diff --git a/libc/nt/KernelBase/InitializeSecurityDescriptor.s b/libc/nt/KernelBase/InitializeSecurityDescriptor.s new file mode 100644 index 00000000..4de81287 --- /dev/null +++ b/libc/nt/KernelBase/InitializeSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InitializeSecurityDescriptor,InitializeSecurityDescriptor,863 diff --git a/libc/nt/KernelBase/InitializeSid.s b/libc/nt/KernelBase/InitializeSid.s new file mode 100644 index 00000000..f7b68b05 --- /dev/null +++ b/libc/nt/KernelBase/InitializeSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InitializeSid,InitializeSid,864 diff --git a/libc/nt/KernelBase/InitializeSynchronizationBarrier.s b/libc/nt/KernelBase/InitializeSynchronizationBarrier.s new file mode 100644 index 00000000..fa3d68be --- /dev/null +++ b/libc/nt/KernelBase/InitializeSynchronizationBarrier.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InitializeSynchronizationBarrier,InitializeSynchronizationBarrier,865 diff --git a/libc/nt/KernelBase/InstallELAMCertificateInfo.s b/libc/nt/KernelBase/InstallELAMCertificateInfo.s new file mode 100644 index 00000000..c514e453 --- /dev/null +++ b/libc/nt/KernelBase/InstallELAMCertificateInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InstallELAMCertificateInfo,InstallELAMCertificateInfo,866 diff --git a/libc/nt/KernelBase/InternalLcidToName.s b/libc/nt/KernelBase/InternalLcidToName.s new file mode 100644 index 00000000..6731a080 --- /dev/null +++ b/libc/nt/KernelBase/InternalLcidToName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InternalLcidToName,InternalLcidToName,872 diff --git a/libc/nt/KernelBase/Internal_EnumCalendarInfo.s b/libc/nt/KernelBase/Internal_EnumCalendarInfo.s new file mode 100644 index 00000000..9e2c7c0d --- /dev/null +++ b/libc/nt/KernelBase/Internal_EnumCalendarInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_Internal_EnumCalendarInfo,Internal_EnumCalendarInfo,873 diff --git a/libc/nt/KernelBase/Internal_EnumDateFormats.s b/libc/nt/KernelBase/Internal_EnumDateFormats.s new file mode 100644 index 00000000..414a8841 --- /dev/null +++ b/libc/nt/KernelBase/Internal_EnumDateFormats.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_Internal_EnumDateFormats,Internal_EnumDateFormats,874 diff --git a/libc/nt/KernelBase/Internal_EnumLanguageGroupLocales.s b/libc/nt/KernelBase/Internal_EnumLanguageGroupLocales.s new file mode 100644 index 00000000..622f1f68 --- /dev/null +++ b/libc/nt/KernelBase/Internal_EnumLanguageGroupLocales.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_Internal_EnumLanguageGroupLocales,Internal_EnumLanguageGroupLocales,875 diff --git a/libc/nt/KernelBase/Internal_EnumSystemCodePages.s b/libc/nt/KernelBase/Internal_EnumSystemCodePages.s new file mode 100644 index 00000000..d2441eaa --- /dev/null +++ b/libc/nt/KernelBase/Internal_EnumSystemCodePages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_Internal_EnumSystemCodePages,Internal_EnumSystemCodePages,876 diff --git a/libc/nt/KernelBase/Internal_EnumSystemLanguageGroups.s b/libc/nt/KernelBase/Internal_EnumSystemLanguageGroups.s new file mode 100644 index 00000000..2e533c1f --- /dev/null +++ b/libc/nt/KernelBase/Internal_EnumSystemLanguageGroups.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_Internal_EnumSystemLanguageGroups,Internal_EnumSystemLanguageGroups,877 diff --git a/libc/nt/KernelBase/Internal_EnumSystemLocales.s b/libc/nt/KernelBase/Internal_EnumSystemLocales.s new file mode 100644 index 00000000..73ba0925 --- /dev/null +++ b/libc/nt/KernelBase/Internal_EnumSystemLocales.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_Internal_EnumSystemLocales,Internal_EnumSystemLocales,878 diff --git a/libc/nt/KernelBase/Internal_EnumTimeFormats.s b/libc/nt/KernelBase/Internal_EnumTimeFormats.s new file mode 100644 index 00000000..14a7bc7b --- /dev/null +++ b/libc/nt/KernelBase/Internal_EnumTimeFormats.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_Internal_EnumTimeFormats,Internal_EnumTimeFormats,879 diff --git a/libc/nt/KernelBase/Internal_EnumUILanguages.s b/libc/nt/KernelBase/Internal_EnumUILanguages.s new file mode 100644 index 00000000..f8c1649b --- /dev/null +++ b/libc/nt/KernelBase/Internal_EnumUILanguages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_Internal_EnumUILanguages,Internal_EnumUILanguages,880 diff --git a/libc/nt/KernelBase/InternetTimeFromSystemTimeA.s b/libc/nt/KernelBase/InternetTimeFromSystemTimeA.s new file mode 100644 index 00000000..30ffcf92 --- /dev/null +++ b/libc/nt/KernelBase/InternetTimeFromSystemTimeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InternetTimeFromSystemTimeA,InternetTimeFromSystemTimeA,881 diff --git a/libc/nt/KernelBase/InternetTimeFromSystemTimeW.s b/libc/nt/KernelBase/InternetTimeFromSystemTimeW.s new file mode 100644 index 00000000..26a7e0b3 --- /dev/null +++ b/libc/nt/KernelBase/InternetTimeFromSystemTimeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InternetTimeFromSystemTimeW,InternetTimeFromSystemTimeW,882 diff --git a/libc/nt/KernelBase/InternetTimeToSystemTimeA.s b/libc/nt/KernelBase/InternetTimeToSystemTimeA.s new file mode 100644 index 00000000..02752dec --- /dev/null +++ b/libc/nt/KernelBase/InternetTimeToSystemTimeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InternetTimeToSystemTimeA,InternetTimeToSystemTimeA,883 diff --git a/libc/nt/KernelBase/InternetTimeToSystemTimeW.s b/libc/nt/KernelBase/InternetTimeToSystemTimeW.s new file mode 100644 index 00000000..bd845470 --- /dev/null +++ b/libc/nt/KernelBase/InternetTimeToSystemTimeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InternetTimeToSystemTimeW,InternetTimeToSystemTimeW,884 diff --git a/libc/nt/KernelBase/InvalidateAppModelVersionCache.s b/libc/nt/KernelBase/InvalidateAppModelVersionCache.s new file mode 100644 index 00000000..957842c5 --- /dev/null +++ b/libc/nt/KernelBase/InvalidateAppModelVersionCache.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_InvalidateAppModelVersionCache,InvalidateAppModelVersionCache,885 diff --git a/libc/nt/KernelBase/IsCharAlphaA.s b/libc/nt/KernelBase/IsCharAlphaA.s new file mode 100644 index 00000000..19d1fbbd --- /dev/null +++ b/libc/nt/KernelBase/IsCharAlphaA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsCharAlphaA,IsCharAlphaA,886 diff --git a/libc/nt/KernelBase/IsCharAlphaNumericA.s b/libc/nt/KernelBase/IsCharAlphaNumericA.s new file mode 100644 index 00000000..00434f23 --- /dev/null +++ b/libc/nt/KernelBase/IsCharAlphaNumericA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsCharAlphaNumericA,IsCharAlphaNumericA,887 diff --git a/libc/nt/KernelBase/IsCharAlphaNumericW.s b/libc/nt/KernelBase/IsCharAlphaNumericW.s new file mode 100644 index 00000000..b2f40934 --- /dev/null +++ b/libc/nt/KernelBase/IsCharAlphaNumericW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsCharAlphaNumericW,IsCharAlphaNumericW,888 diff --git a/libc/nt/KernelBase/IsCharAlphaW.s b/libc/nt/KernelBase/IsCharAlphaW.s new file mode 100644 index 00000000..b644f5dd --- /dev/null +++ b/libc/nt/KernelBase/IsCharAlphaW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsCharAlphaW,IsCharAlphaW,889 diff --git a/libc/nt/KernelBase/IsCharBlankW.s b/libc/nt/KernelBase/IsCharBlankW.s new file mode 100644 index 00000000..c652cb57 --- /dev/null +++ b/libc/nt/KernelBase/IsCharBlankW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsCharBlankW,IsCharBlankW,890 diff --git a/libc/nt/KernelBase/IsCharCntrlW.s b/libc/nt/KernelBase/IsCharCntrlW.s new file mode 100644 index 00000000..b70a5188 --- /dev/null +++ b/libc/nt/KernelBase/IsCharCntrlW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsCharCntrlW,IsCharCntrlW,891 diff --git a/libc/nt/KernelBase/IsCharDigitW.s b/libc/nt/KernelBase/IsCharDigitW.s new file mode 100644 index 00000000..5dd94418 --- /dev/null +++ b/libc/nt/KernelBase/IsCharDigitW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsCharDigitW,IsCharDigitW,892 diff --git a/libc/nt/KernelBase/IsCharLowerA.s b/libc/nt/KernelBase/IsCharLowerA.s new file mode 100644 index 00000000..cd21d8d5 --- /dev/null +++ b/libc/nt/KernelBase/IsCharLowerA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsCharLowerA,IsCharLowerA,893 diff --git a/libc/nt/KernelBase/IsCharLowerW.s b/libc/nt/KernelBase/IsCharLowerW.s new file mode 100644 index 00000000..c8da6c49 --- /dev/null +++ b/libc/nt/KernelBase/IsCharLowerW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsCharLowerW,IsCharLowerW,894 diff --git a/libc/nt/KernelBase/IsCharPunctW.s b/libc/nt/KernelBase/IsCharPunctW.s new file mode 100644 index 00000000..58841d3e --- /dev/null +++ b/libc/nt/KernelBase/IsCharPunctW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsCharPunctW,IsCharPunctW,895 diff --git a/libc/nt/KernelBase/IsCharSpaceA.s b/libc/nt/KernelBase/IsCharSpaceA.s new file mode 100644 index 00000000..66c5d4cd --- /dev/null +++ b/libc/nt/KernelBase/IsCharSpaceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsCharSpaceA,IsCharSpaceA,896 diff --git a/libc/nt/KernelBase/IsCharSpaceW.s b/libc/nt/KernelBase/IsCharSpaceW.s new file mode 100644 index 00000000..7e2c7732 --- /dev/null +++ b/libc/nt/KernelBase/IsCharSpaceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsCharSpaceW,IsCharSpaceW,897 diff --git a/libc/nt/KernelBase/IsCharUpperA.s b/libc/nt/KernelBase/IsCharUpperA.s new file mode 100644 index 00000000..4f907565 --- /dev/null +++ b/libc/nt/KernelBase/IsCharUpperA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsCharUpperA,IsCharUpperA,898 diff --git a/libc/nt/KernelBase/IsCharUpperW.s b/libc/nt/KernelBase/IsCharUpperW.s new file mode 100644 index 00000000..237b2c5b --- /dev/null +++ b/libc/nt/KernelBase/IsCharUpperW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsCharUpperW,IsCharUpperW,899 diff --git a/libc/nt/KernelBase/IsCharXDigitW.s b/libc/nt/KernelBase/IsCharXDigitW.s new file mode 100644 index 00000000..bce4c780 --- /dev/null +++ b/libc/nt/KernelBase/IsCharXDigitW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsCharXDigitW,IsCharXDigitW,900 diff --git a/libc/nt/KernelBase/IsDBCSLeadByte.s b/libc/nt/KernelBase/IsDBCSLeadByte.s new file mode 100644 index 00000000..64a3c328 --- /dev/null +++ b/libc/nt/KernelBase/IsDBCSLeadByte.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsDBCSLeadByte,IsDBCSLeadByte,901 diff --git a/libc/nt/KernelBase/IsDBCSLeadByteEx.s b/libc/nt/KernelBase/IsDBCSLeadByteEx.s new file mode 100644 index 00000000..22ae7ed6 --- /dev/null +++ b/libc/nt/KernelBase/IsDBCSLeadByteEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsDBCSLeadByteEx,IsDBCSLeadByteEx,902 diff --git a/libc/nt/KernelBase/IsDebuggerPresent.s b/libc/nt/KernelBase/IsDebuggerPresent.s new file mode 100644 index 00000000..4c7c5b96 --- /dev/null +++ b/libc/nt/KernelBase/IsDebuggerPresent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsDebuggerPresent,IsDebuggerPresent,903 diff --git a/libc/nt/KernelBase/IsDeveloperModeEnabled.s b/libc/nt/KernelBase/IsDeveloperModeEnabled.s new file mode 100644 index 00000000..6c90b8ca --- /dev/null +++ b/libc/nt/KernelBase/IsDeveloperModeEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsDeveloperModeEnabled,IsDeveloperModeEnabled,904 diff --git a/libc/nt/KernelBase/IsDeveloperModePolicyApplied.s b/libc/nt/KernelBase/IsDeveloperModePolicyApplied.s new file mode 100644 index 00000000..b7256acb --- /dev/null +++ b/libc/nt/KernelBase/IsDeveloperModePolicyApplied.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsDeveloperModePolicyApplied,IsDeveloperModePolicyApplied,905 diff --git a/libc/nt/KernelBase/IsEnclaveTypeSupported.s b/libc/nt/KernelBase/IsEnclaveTypeSupported.s new file mode 100644 index 00000000..b526fe0c --- /dev/null +++ b/libc/nt/KernelBase/IsEnclaveTypeSupported.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsEnclaveTypeSupported,IsEnclaveTypeSupported,906 diff --git a/libc/nt/KernelBase/IsGlobalizationUserSettingsKeyRedirected.s b/libc/nt/KernelBase/IsGlobalizationUserSettingsKeyRedirected.s new file mode 100644 index 00000000..625b816b --- /dev/null +++ b/libc/nt/KernelBase/IsGlobalizationUserSettingsKeyRedirected.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsGlobalizationUserSettingsKeyRedirected,IsGlobalizationUserSettingsKeyRedirected,907 diff --git a/libc/nt/KernelBase/IsInternetESCEnabled.s b/libc/nt/KernelBase/IsInternetESCEnabled.s new file mode 100644 index 00000000..f1956715 --- /dev/null +++ b/libc/nt/KernelBase/IsInternetESCEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsInternetESCEnabled,IsInternetESCEnabled,908 diff --git a/libc/nt/KernelBase/IsNLSDefinedString.s b/libc/nt/KernelBase/IsNLSDefinedString.s new file mode 100644 index 00000000..8700a64b --- /dev/null +++ b/libc/nt/KernelBase/IsNLSDefinedString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsNLSDefinedString,IsNLSDefinedString,909 diff --git a/libc/nt/KernelBase/IsNormalizedString.s b/libc/nt/KernelBase/IsNormalizedString.s new file mode 100644 index 00000000..fda6c5a2 --- /dev/null +++ b/libc/nt/KernelBase/IsNormalizedString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsNormalizedString,IsNormalizedString,910 diff --git a/libc/nt/KernelBase/IsOnDemandRegistrationSupportedForExtensionCategory.s b/libc/nt/KernelBase/IsOnDemandRegistrationSupportedForExtensionCategory.s new file mode 100644 index 00000000..609b5561 --- /dev/null +++ b/libc/nt/KernelBase/IsOnDemandRegistrationSupportedForExtensionCategory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsOnDemandRegistrationSupportedForExtensionCategory,IsOnDemandRegistrationSupportedForExtensionCategory,911 diff --git a/libc/nt/KernelBase/IsProcessCritical.s b/libc/nt/KernelBase/IsProcessCritical.s new file mode 100644 index 00000000..ce330248 --- /dev/null +++ b/libc/nt/KernelBase/IsProcessCritical.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsProcessCritical,IsProcessCritical,912 diff --git a/libc/nt/KernelBase/IsProcessInJob.s b/libc/nt/KernelBase/IsProcessInJob.s new file mode 100644 index 00000000..4bac6fa3 --- /dev/null +++ b/libc/nt/KernelBase/IsProcessInJob.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsProcessInJob,IsProcessInJob,913 diff --git a/libc/nt/KernelBase/IsProcessorFeaturePresent.s b/libc/nt/KernelBase/IsProcessorFeaturePresent.s new file mode 100644 index 00000000..40669cd5 --- /dev/null +++ b/libc/nt/KernelBase/IsProcessorFeaturePresent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsProcessorFeaturePresent,IsProcessorFeaturePresent,914 diff --git a/libc/nt/KernelBase/IsSideloadingEnabled.s b/libc/nt/KernelBase/IsSideloadingEnabled.s new file mode 100644 index 00000000..b17e53be --- /dev/null +++ b/libc/nt/KernelBase/IsSideloadingEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsSideloadingEnabled,IsSideloadingEnabled,915 diff --git a/libc/nt/KernelBase/IsSideloadingPolicyApplied.s b/libc/nt/KernelBase/IsSideloadingPolicyApplied.s new file mode 100644 index 00000000..734c6212 --- /dev/null +++ b/libc/nt/KernelBase/IsSideloadingPolicyApplied.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsSideloadingPolicyApplied,IsSideloadingPolicyApplied,916 diff --git a/libc/nt/KernelBase/IsSyncForegroundPolicyRefresh.s b/libc/nt/KernelBase/IsSyncForegroundPolicyRefresh.s new file mode 100644 index 00000000..e67ed0c1 --- /dev/null +++ b/libc/nt/KernelBase/IsSyncForegroundPolicyRefresh.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsSyncForegroundPolicyRefresh,IsSyncForegroundPolicyRefresh,917 diff --git a/libc/nt/KernelBase/IsThreadAFiber.s b/libc/nt/KernelBase/IsThreadAFiber.s new file mode 100644 index 00000000..5b87eaa1 --- /dev/null +++ b/libc/nt/KernelBase/IsThreadAFiber.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsThreadAFiber,IsThreadAFiber,918 diff --git a/libc/nt/KernelBase/IsTimeZoneRedirectionEnabled.s b/libc/nt/KernelBase/IsTimeZoneRedirectionEnabled.s new file mode 100644 index 00000000..7891f498 --- /dev/null +++ b/libc/nt/KernelBase/IsTimeZoneRedirectionEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsTimeZoneRedirectionEnabled,IsTimeZoneRedirectionEnabled,920 diff --git a/libc/nt/KernelBase/IsTokenRestricted.s b/libc/nt/KernelBase/IsTokenRestricted.s new file mode 100644 index 00000000..7339893c --- /dev/null +++ b/libc/nt/KernelBase/IsTokenRestricted.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsTokenRestricted,IsTokenRestricted,921 diff --git a/libc/nt/KernelBase/IsValidAcl.s b/libc/nt/KernelBase/IsValidAcl.s new file mode 100644 index 00000000..93c8a033 --- /dev/null +++ b/libc/nt/KernelBase/IsValidAcl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsValidAcl,IsValidAcl,922 diff --git a/libc/nt/KernelBase/IsValidCodePage.s b/libc/nt/KernelBase/IsValidCodePage.s new file mode 100644 index 00000000..d9e3ae54 --- /dev/null +++ b/libc/nt/KernelBase/IsValidCodePage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsValidCodePage,IsValidCodePage,923 diff --git a/libc/nt/KernelBase/IsValidLanguageGroup.s b/libc/nt/KernelBase/IsValidLanguageGroup.s new file mode 100644 index 00000000..65106abb --- /dev/null +++ b/libc/nt/KernelBase/IsValidLanguageGroup.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsValidLanguageGroup,IsValidLanguageGroup,924 diff --git a/libc/nt/KernelBase/IsValidLocale.s b/libc/nt/KernelBase/IsValidLocale.s new file mode 100644 index 00000000..ccd7bdb3 --- /dev/null +++ b/libc/nt/KernelBase/IsValidLocale.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsValidLocale,IsValidLocale,925 diff --git a/libc/nt/KernelBase/IsValidLocaleName.s b/libc/nt/KernelBase/IsValidLocaleName.s new file mode 100644 index 00000000..91d36f3d --- /dev/null +++ b/libc/nt/KernelBase/IsValidLocaleName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsValidLocaleName,IsValidLocaleName,926 diff --git a/libc/nt/KernelBase/IsValidNLSVersion.s b/libc/nt/KernelBase/IsValidNLSVersion.s new file mode 100644 index 00000000..3cf53c21 --- /dev/null +++ b/libc/nt/KernelBase/IsValidNLSVersion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsValidNLSVersion,IsValidNLSVersion,927 diff --git a/libc/nt/KernelBase/IsValidRelativeSecurityDescriptor.s b/libc/nt/KernelBase/IsValidRelativeSecurityDescriptor.s new file mode 100644 index 00000000..210d6f07 --- /dev/null +++ b/libc/nt/KernelBase/IsValidRelativeSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsValidRelativeSecurityDescriptor,IsValidRelativeSecurityDescriptor,928 diff --git a/libc/nt/KernelBase/IsValidSecurityDescriptor.s b/libc/nt/KernelBase/IsValidSecurityDescriptor.s new file mode 100644 index 00000000..fb835092 --- /dev/null +++ b/libc/nt/KernelBase/IsValidSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsValidSecurityDescriptor,IsValidSecurityDescriptor,929 diff --git a/libc/nt/KernelBase/IsValidSid.s b/libc/nt/KernelBase/IsValidSid.s new file mode 100644 index 00000000..1ef8fa27 --- /dev/null +++ b/libc/nt/KernelBase/IsValidSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsValidSid,IsValidSid,930 diff --git a/libc/nt/KernelBase/IsWellKnownSid.s b/libc/nt/KernelBase/IsWellKnownSid.s new file mode 100644 index 00000000..22a4d58f --- /dev/null +++ b/libc/nt/KernelBase/IsWellKnownSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsWellKnownSid,IsWellKnownSid,931 diff --git a/libc/nt/KernelBase/IsWow64GuestMachineSupported.s b/libc/nt/KernelBase/IsWow64GuestMachineSupported.s new file mode 100644 index 00000000..22b7ea49 --- /dev/null +++ b/libc/nt/KernelBase/IsWow64GuestMachineSupported.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsWow64GuestMachineSupported,IsWow64GuestMachineSupported,932 diff --git a/libc/nt/KernelBase/IsWow64Process.s b/libc/nt/KernelBase/IsWow64Process.s new file mode 100644 index 00000000..439e407c --- /dev/null +++ b/libc/nt/KernelBase/IsWow64Process.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsWow64Process,IsWow64Process,933 diff --git a/libc/nt/KernelBase/IsWow64Process2.s b/libc/nt/KernelBase/IsWow64Process2.s new file mode 100644 index 00000000..333f9236 --- /dev/null +++ b/libc/nt/KernelBase/IsWow64Process2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_IsWow64Process2,IsWow64Process2,934 diff --git a/libc/nt/KernelBase/K32EmptyWorkingSet.s b/libc/nt/KernelBase/K32EmptyWorkingSet.s new file mode 100644 index 00000000..fe11faf6 --- /dev/null +++ b/libc/nt/KernelBase/K32EmptyWorkingSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32EmptyWorkingSet,K32EmptyWorkingSet,935 diff --git a/libc/nt/KernelBase/K32EnumDeviceDrivers.s b/libc/nt/KernelBase/K32EnumDeviceDrivers.s new file mode 100644 index 00000000..868b1af8 --- /dev/null +++ b/libc/nt/KernelBase/K32EnumDeviceDrivers.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32EnumDeviceDrivers,K32EnumDeviceDrivers,936 diff --git a/libc/nt/KernelBase/K32EnumPageFilesA.s b/libc/nt/KernelBase/K32EnumPageFilesA.s new file mode 100644 index 00000000..e0855279 --- /dev/null +++ b/libc/nt/KernelBase/K32EnumPageFilesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32EnumPageFilesA,K32EnumPageFilesA,937 diff --git a/libc/nt/KernelBase/K32EnumPageFilesW.s b/libc/nt/KernelBase/K32EnumPageFilesW.s new file mode 100644 index 00000000..6a010506 --- /dev/null +++ b/libc/nt/KernelBase/K32EnumPageFilesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32EnumPageFilesW,K32EnumPageFilesW,938 diff --git a/libc/nt/KernelBase/K32EnumProcessModules.s b/libc/nt/KernelBase/K32EnumProcessModules.s new file mode 100644 index 00000000..05787470 --- /dev/null +++ b/libc/nt/KernelBase/K32EnumProcessModules.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32EnumProcessModules,K32EnumProcessModules,939 diff --git a/libc/nt/KernelBase/K32EnumProcessModulesEx.s b/libc/nt/KernelBase/K32EnumProcessModulesEx.s new file mode 100644 index 00000000..b390f790 --- /dev/null +++ b/libc/nt/KernelBase/K32EnumProcessModulesEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32EnumProcessModulesEx,K32EnumProcessModulesEx,940 diff --git a/libc/nt/KernelBase/K32EnumProcesses.s b/libc/nt/KernelBase/K32EnumProcesses.s new file mode 100644 index 00000000..6a1acbff --- /dev/null +++ b/libc/nt/KernelBase/K32EnumProcesses.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32EnumProcesses,K32EnumProcesses,941 diff --git a/libc/nt/KernelBase/K32GetDeviceDriverBaseNameA.s b/libc/nt/KernelBase/K32GetDeviceDriverBaseNameA.s new file mode 100644 index 00000000..be22e1a2 --- /dev/null +++ b/libc/nt/KernelBase/K32GetDeviceDriverBaseNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32GetDeviceDriverBaseNameA,K32GetDeviceDriverBaseNameA,942 diff --git a/libc/nt/KernelBase/K32GetDeviceDriverBaseNameW.s b/libc/nt/KernelBase/K32GetDeviceDriverBaseNameW.s new file mode 100644 index 00000000..f8c2f576 --- /dev/null +++ b/libc/nt/KernelBase/K32GetDeviceDriverBaseNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32GetDeviceDriverBaseNameW,K32GetDeviceDriverBaseNameW,943 diff --git a/libc/nt/KernelBase/K32GetDeviceDriverFileNameA.s b/libc/nt/KernelBase/K32GetDeviceDriverFileNameA.s new file mode 100644 index 00000000..f6305304 --- /dev/null +++ b/libc/nt/KernelBase/K32GetDeviceDriverFileNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32GetDeviceDriverFileNameA,K32GetDeviceDriverFileNameA,944 diff --git a/libc/nt/KernelBase/K32GetDeviceDriverFileNameW.s b/libc/nt/KernelBase/K32GetDeviceDriverFileNameW.s new file mode 100644 index 00000000..ef55ff7a --- /dev/null +++ b/libc/nt/KernelBase/K32GetDeviceDriverFileNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32GetDeviceDriverFileNameW,K32GetDeviceDriverFileNameW,945 diff --git a/libc/nt/KernelBase/K32GetMappedFileNameA.s b/libc/nt/KernelBase/K32GetMappedFileNameA.s new file mode 100644 index 00000000..7269585b --- /dev/null +++ b/libc/nt/KernelBase/K32GetMappedFileNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32GetMappedFileNameA,K32GetMappedFileNameA,946 diff --git a/libc/nt/KernelBase/K32GetMappedFileNameW.s b/libc/nt/KernelBase/K32GetMappedFileNameW.s new file mode 100644 index 00000000..23e292a8 --- /dev/null +++ b/libc/nt/KernelBase/K32GetMappedFileNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32GetMappedFileNameW,K32GetMappedFileNameW,947 diff --git a/libc/nt/KernelBase/K32GetModuleBaseNameA.s b/libc/nt/KernelBase/K32GetModuleBaseNameA.s new file mode 100644 index 00000000..43e0c28f --- /dev/null +++ b/libc/nt/KernelBase/K32GetModuleBaseNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32GetModuleBaseNameA,K32GetModuleBaseNameA,948 diff --git a/libc/nt/KernelBase/K32GetModuleBaseNameW.s b/libc/nt/KernelBase/K32GetModuleBaseNameW.s new file mode 100644 index 00000000..665ef5b4 --- /dev/null +++ b/libc/nt/KernelBase/K32GetModuleBaseNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32GetModuleBaseNameW,K32GetModuleBaseNameW,949 diff --git a/libc/nt/KernelBase/K32GetModuleFileNameExA.s b/libc/nt/KernelBase/K32GetModuleFileNameExA.s new file mode 100644 index 00000000..e324b834 --- /dev/null +++ b/libc/nt/KernelBase/K32GetModuleFileNameExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32GetModuleFileNameExA,K32GetModuleFileNameExA,950 diff --git a/libc/nt/KernelBase/K32GetModuleFileNameExW.s b/libc/nt/KernelBase/K32GetModuleFileNameExW.s new file mode 100644 index 00000000..2ca28254 --- /dev/null +++ b/libc/nt/KernelBase/K32GetModuleFileNameExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32GetModuleFileNameExW,K32GetModuleFileNameExW,951 diff --git a/libc/nt/KernelBase/K32GetModuleInformation.s b/libc/nt/KernelBase/K32GetModuleInformation.s new file mode 100644 index 00000000..8adc7d10 --- /dev/null +++ b/libc/nt/KernelBase/K32GetModuleInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32GetModuleInformation,K32GetModuleInformation,952 diff --git a/libc/nt/KernelBase/K32GetPerformanceInfo.s b/libc/nt/KernelBase/K32GetPerformanceInfo.s new file mode 100644 index 00000000..98324800 --- /dev/null +++ b/libc/nt/KernelBase/K32GetPerformanceInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32GetPerformanceInfo,K32GetPerformanceInfo,953 diff --git a/libc/nt/KernelBase/K32GetProcessImageFileNameA.s b/libc/nt/KernelBase/K32GetProcessImageFileNameA.s new file mode 100644 index 00000000..0dbfc574 --- /dev/null +++ b/libc/nt/KernelBase/K32GetProcessImageFileNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32GetProcessImageFileNameA,K32GetProcessImageFileNameA,954 diff --git a/libc/nt/KernelBase/K32GetProcessImageFileNameW.s b/libc/nt/KernelBase/K32GetProcessImageFileNameW.s new file mode 100644 index 00000000..2ed68767 --- /dev/null +++ b/libc/nt/KernelBase/K32GetProcessImageFileNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32GetProcessImageFileNameW,K32GetProcessImageFileNameW,955 diff --git a/libc/nt/KernelBase/K32GetProcessMemoryInfo.s b/libc/nt/KernelBase/K32GetProcessMemoryInfo.s new file mode 100644 index 00000000..cfce604d --- /dev/null +++ b/libc/nt/KernelBase/K32GetProcessMemoryInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32GetProcessMemoryInfo,K32GetProcessMemoryInfo,956 diff --git a/libc/nt/KernelBase/K32GetWsChanges.s b/libc/nt/KernelBase/K32GetWsChanges.s new file mode 100644 index 00000000..31d27fb8 --- /dev/null +++ b/libc/nt/KernelBase/K32GetWsChanges.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32GetWsChanges,K32GetWsChanges,957 diff --git a/libc/nt/KernelBase/K32GetWsChangesEx.s b/libc/nt/KernelBase/K32GetWsChangesEx.s new file mode 100644 index 00000000..ed675099 --- /dev/null +++ b/libc/nt/KernelBase/K32GetWsChangesEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32GetWsChangesEx,K32GetWsChangesEx,958 diff --git a/libc/nt/KernelBase/K32InitializeProcessForWsWatch.s b/libc/nt/KernelBase/K32InitializeProcessForWsWatch.s new file mode 100644 index 00000000..e76a5e47 --- /dev/null +++ b/libc/nt/KernelBase/K32InitializeProcessForWsWatch.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32InitializeProcessForWsWatch,K32InitializeProcessForWsWatch,959 diff --git a/libc/nt/KernelBase/K32QueryWorkingSet.s b/libc/nt/KernelBase/K32QueryWorkingSet.s new file mode 100644 index 00000000..daa5c8c7 --- /dev/null +++ b/libc/nt/KernelBase/K32QueryWorkingSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32QueryWorkingSet,K32QueryWorkingSet,960 diff --git a/libc/nt/KernelBase/K32QueryWorkingSetEx.s b/libc/nt/KernelBase/K32QueryWorkingSetEx.s new file mode 100644 index 00000000..03585f0f --- /dev/null +++ b/libc/nt/KernelBase/K32QueryWorkingSetEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_K32QueryWorkingSetEx,K32QueryWorkingSetEx,961 diff --git a/libc/nt/KernelBase/KernelBaseGetGlobalData.s b/libc/nt/KernelBase/KernelBaseGetGlobalData.s new file mode 100644 index 00000000..4bf704a7 --- /dev/null +++ b/libc/nt/KernelBase/KernelBaseGetGlobalData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_KernelBaseGetGlobalData,KernelBaseGetGlobalData,962 diff --git a/libc/nt/KernelBase/KernelbasePostInit.s b/libc/nt/KernelBase/KernelbasePostInit.s new file mode 100644 index 00000000..fbd9bb13 --- /dev/null +++ b/libc/nt/KernelBase/KernelbasePostInit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_KernelbasePostInit,KernelbasePostInit,963 diff --git a/libc/nt/KernelBase/LCIDToLocaleName.s b/libc/nt/KernelBase/LCIDToLocaleName.s new file mode 100644 index 00000000..2d66c03c --- /dev/null +++ b/libc/nt/KernelBase/LCIDToLocaleName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LCIDToLocaleName,LCIDToLocaleName,964 diff --git a/libc/nt/KernelBase/LCMapStringA.s b/libc/nt/KernelBase/LCMapStringA.s new file mode 100644 index 00000000..46e4912c --- /dev/null +++ b/libc/nt/KernelBase/LCMapStringA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LCMapStringA,LCMapStringA,965 diff --git a/libc/nt/KernelBase/LCMapStringEx.s b/libc/nt/KernelBase/LCMapStringEx.s new file mode 100644 index 00000000..4a56e89b --- /dev/null +++ b/libc/nt/KernelBase/LCMapStringEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LCMapStringEx,LCMapStringEx,966 diff --git a/libc/nt/KernelBase/LCMapStringW.s b/libc/nt/KernelBase/LCMapStringW.s new file mode 100644 index 00000000..46bea9b5 --- /dev/null +++ b/libc/nt/KernelBase/LCMapStringW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LCMapStringW,LCMapStringW,967 diff --git a/libc/nt/KernelBase/LeaveCriticalPolicySectionInternal.s b/libc/nt/KernelBase/LeaveCriticalPolicySectionInternal.s new file mode 100644 index 00000000..b258da34 --- /dev/null +++ b/libc/nt/KernelBase/LeaveCriticalPolicySectionInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LeaveCriticalPolicySectionInternal,LeaveCriticalPolicySectionInternal,968 diff --git a/libc/nt/KernelBase/LoadAppInitDlls.s b/libc/nt/KernelBase/LoadAppInitDlls.s new file mode 100644 index 00000000..0f740e50 --- /dev/null +++ b/libc/nt/KernelBase/LoadAppInitDlls.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LoadAppInitDlls,LoadAppInitDlls,971 diff --git a/libc/nt/KernelBase/LoadEnclaveData.s b/libc/nt/KernelBase/LoadEnclaveData.s new file mode 100644 index 00000000..032f6762 --- /dev/null +++ b/libc/nt/KernelBase/LoadEnclaveData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LoadEnclaveData,LoadEnclaveData,972 diff --git a/libc/nt/KernelBase/LoadEnclaveImageA.s b/libc/nt/KernelBase/LoadEnclaveImageA.s new file mode 100644 index 00000000..37a3e50a --- /dev/null +++ b/libc/nt/KernelBase/LoadEnclaveImageA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LoadEnclaveImageA,LoadEnclaveImageA,973 diff --git a/libc/nt/KernelBase/LoadEnclaveImageW.s b/libc/nt/KernelBase/LoadEnclaveImageW.s new file mode 100644 index 00000000..980988a4 --- /dev/null +++ b/libc/nt/KernelBase/LoadEnclaveImageW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LoadEnclaveImageW,LoadEnclaveImageW,974 diff --git a/libc/nt/KernelBase/LoadLibraryA.s b/libc/nt/KernelBase/LoadLibraryA.s new file mode 100644 index 00000000..e6eb1b38 --- /dev/null +++ b/libc/nt/KernelBase/LoadLibraryA.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LoadLibraryA,LoadLibraryA,975 + + .text.windows +LoadLibraryA: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_LoadLibraryA(%rip) + leave + ret + .endfn LoadLibraryA,globl + .previous diff --git a/libc/nt/KernelBase/LoadLibraryExA.s b/libc/nt/KernelBase/LoadLibraryExA.s new file mode 100644 index 00000000..6f2827ad --- /dev/null +++ b/libc/nt/KernelBase/LoadLibraryExA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LoadLibraryExA,LoadLibraryExA,976 + + .text.windows +LoadLibraryExA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_LoadLibraryExA(%rip),%rax + jmp __sysv2nt + .endfn LoadLibraryExA,globl + .previous diff --git a/libc/nt/KernelBase/LoadLibraryExW.s b/libc/nt/KernelBase/LoadLibraryExW.s new file mode 100644 index 00000000..cf16ce74 --- /dev/null +++ b/libc/nt/KernelBase/LoadLibraryExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LoadLibraryExW,LoadLibraryExW,977 diff --git a/libc/nt/KernelBase/LoadLibraryW.s b/libc/nt/KernelBase/LoadLibraryW.s new file mode 100644 index 00000000..6afecc6c --- /dev/null +++ b/libc/nt/KernelBase/LoadLibraryW.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LoadLibraryW,LoadLibraryW,978 + + .text.windows +LoadLibrary: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_LoadLibraryW(%rip) + leave + ret + .endfn LoadLibrary,globl + .previous diff --git a/libc/nt/KernelBase/LoadPackagedLibrary.s b/libc/nt/KernelBase/LoadPackagedLibrary.s new file mode 100644 index 00000000..ebd19d16 --- /dev/null +++ b/libc/nt/KernelBase/LoadPackagedLibrary.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LoadPackagedLibrary,LoadPackagedLibrary,979 diff --git a/libc/nt/KernelBase/LoadResource.s b/libc/nt/KernelBase/LoadResource.s new file mode 100644 index 00000000..f219238e --- /dev/null +++ b/libc/nt/KernelBase/LoadResource.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LoadResource,LoadResource,980 + + .text.windows +LoadResource: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_LoadResource(%rip),%rax + jmp __sysv2nt + .endfn LoadResource,globl + .previous diff --git a/libc/nt/KernelBase/LoadStringA.s b/libc/nt/KernelBase/LoadStringA.s new file mode 100644 index 00000000..38c07816 --- /dev/null +++ b/libc/nt/KernelBase/LoadStringA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LoadStringA,LoadStringA,981 diff --git a/libc/nt/KernelBase/LoadStringBaseExW.s b/libc/nt/KernelBase/LoadStringBaseExW.s new file mode 100644 index 00000000..de006981 --- /dev/null +++ b/libc/nt/KernelBase/LoadStringBaseExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LoadStringBaseExW,LoadStringBaseExW,982 diff --git a/libc/nt/KernelBase/LoadStringByReference.s b/libc/nt/KernelBase/LoadStringByReference.s new file mode 100644 index 00000000..944edf84 --- /dev/null +++ b/libc/nt/KernelBase/LoadStringByReference.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LoadStringByReference,LoadStringByReference,983 diff --git a/libc/nt/KernelBase/LoadStringW.s b/libc/nt/KernelBase/LoadStringW.s new file mode 100644 index 00000000..5ecb3ee2 --- /dev/null +++ b/libc/nt/KernelBase/LoadStringW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LoadStringW,LoadStringW,984 diff --git a/libc/nt/KernelBase/LocalAlloc.s b/libc/nt/KernelBase/LocalAlloc.s new file mode 100644 index 00000000..bfe3bb3f --- /dev/null +++ b/libc/nt/KernelBase/LocalAlloc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LocalAlloc,LocalAlloc,985 diff --git a/libc/nt/KernelBase/LocalFileTimeToFileTime.s b/libc/nt/KernelBase/LocalFileTimeToFileTime.s new file mode 100644 index 00000000..394bd85c --- /dev/null +++ b/libc/nt/KernelBase/LocalFileTimeToFileTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LocalFileTimeToFileTime,LocalFileTimeToFileTime,986 diff --git a/libc/nt/KernelBase/LocalFree.s b/libc/nt/KernelBase/LocalFree.s new file mode 100644 index 00000000..c17bba6e --- /dev/null +++ b/libc/nt/KernelBase/LocalFree.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LocalFree,LocalFree,987 diff --git a/libc/nt/KernelBase/LocalLock.s b/libc/nt/KernelBase/LocalLock.s new file mode 100644 index 00000000..23a1e348 --- /dev/null +++ b/libc/nt/KernelBase/LocalLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LocalLock,LocalLock,988 diff --git a/libc/nt/KernelBase/LocalReAlloc.s b/libc/nt/KernelBase/LocalReAlloc.s new file mode 100644 index 00000000..ef446eb9 --- /dev/null +++ b/libc/nt/KernelBase/LocalReAlloc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LocalReAlloc,LocalReAlloc,989 diff --git a/libc/nt/KernelBase/LocalUnlock.s b/libc/nt/KernelBase/LocalUnlock.s new file mode 100644 index 00000000..6afb9f1d --- /dev/null +++ b/libc/nt/KernelBase/LocalUnlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LocalUnlock,LocalUnlock,990 diff --git a/libc/nt/KernelBase/LocaleNameToLCID.s b/libc/nt/KernelBase/LocaleNameToLCID.s new file mode 100644 index 00000000..fdefe0de --- /dev/null +++ b/libc/nt/KernelBase/LocaleNameToLCID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LocaleNameToLCID,LocaleNameToLCID,991 diff --git a/libc/nt/KernelBase/LocateXStateFeature.s b/libc/nt/KernelBase/LocateXStateFeature.s new file mode 100644 index 00000000..ae798e1b --- /dev/null +++ b/libc/nt/KernelBase/LocateXStateFeature.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LocateXStateFeature,LocateXStateFeature,992 diff --git a/libc/nt/KernelBase/LockFile.s b/libc/nt/KernelBase/LockFile.s new file mode 100644 index 00000000..a6c9c826 --- /dev/null +++ b/libc/nt/KernelBase/LockFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LockFile,LockFile,993 + + .text.windows +LockFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_LockFile(%rip),%rax + jmp __sysv2nt6 + .endfn LockFile,globl + .previous diff --git a/libc/nt/KernelBase/LockFileEx.s b/libc/nt/KernelBase/LockFileEx.s new file mode 100644 index 00000000..8683cb5b --- /dev/null +++ b/libc/nt/KernelBase/LockFileEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LockFileEx,LockFileEx,994 + + .text.windows +LockFileEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_LockFileEx(%rip),%rax + jmp __sysv2nt6 + .endfn LockFileEx,globl + .previous diff --git a/libc/nt/KernelBase/LockResource.s b/libc/nt/KernelBase/LockResource.s new file mode 100644 index 00000000..cfe1136c --- /dev/null +++ b/libc/nt/KernelBase/LockResource.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_LockResource,LockResource,995 + + .text.windows +LockResource: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_LockResource(%rip) + leave + ret + .endfn LockResource,globl + .previous diff --git a/libc/nt/KernelBase/MakeAbsoluteSD.s b/libc/nt/KernelBase/MakeAbsoluteSD.s new file mode 100644 index 00000000..25629e76 --- /dev/null +++ b/libc/nt/KernelBase/MakeAbsoluteSD.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MakeAbsoluteSD,MakeAbsoluteSD,996 diff --git a/libc/nt/KernelBase/MakeAbsoluteSD2.s b/libc/nt/KernelBase/MakeAbsoluteSD2.s new file mode 100644 index 00000000..4b96d701 --- /dev/null +++ b/libc/nt/KernelBase/MakeAbsoluteSD2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MakeAbsoluteSD2,MakeAbsoluteSD2,997 diff --git a/libc/nt/KernelBase/MakeSelfRelativeSD.s b/libc/nt/KernelBase/MakeSelfRelativeSD.s new file mode 100644 index 00000000..c664279c --- /dev/null +++ b/libc/nt/KernelBase/MakeSelfRelativeSD.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MakeSelfRelativeSD,MakeSelfRelativeSD,998 diff --git a/libc/nt/KernelBase/MapGenericMask.s b/libc/nt/KernelBase/MapGenericMask.s new file mode 100644 index 00000000..fbe35d2e --- /dev/null +++ b/libc/nt/KernelBase/MapGenericMask.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MapGenericMask,MapGenericMask,999 + + .text.windows +MapGenericMask: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_MapGenericMask(%rip),%rax + jmp __sysv2nt + .endfn MapGenericMask,globl + .previous diff --git a/libc/nt/KernelBase/MapPredefinedHandleInternal.s b/libc/nt/KernelBase/MapPredefinedHandleInternal.s new file mode 100644 index 00000000..59ec3f16 --- /dev/null +++ b/libc/nt/KernelBase/MapPredefinedHandleInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MapPredefinedHandleInternal,MapPredefinedHandleInternal,1000 diff --git a/libc/nt/KernelBase/MapUserPhysicalPages.s b/libc/nt/KernelBase/MapUserPhysicalPages.s new file mode 100644 index 00000000..f69be9c2 --- /dev/null +++ b/libc/nt/KernelBase/MapUserPhysicalPages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MapUserPhysicalPages,MapUserPhysicalPages,1001 diff --git a/libc/nt/KernelBase/MapViewOfFile.s b/libc/nt/KernelBase/MapViewOfFile.s new file mode 100644 index 00000000..2bbe13b2 --- /dev/null +++ b/libc/nt/KernelBase/MapViewOfFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MapViewOfFile,MapViewOfFile,1002 diff --git a/libc/nt/KernelBase/MapViewOfFile3.s b/libc/nt/KernelBase/MapViewOfFile3.s new file mode 100644 index 00000000..e60655af --- /dev/null +++ b/libc/nt/KernelBase/MapViewOfFile3.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MapViewOfFile3,MapViewOfFile3,1003 diff --git a/libc/nt/KernelBase/MapViewOfFile3FromApp.s b/libc/nt/KernelBase/MapViewOfFile3FromApp.s new file mode 100644 index 00000000..b4fc87f6 --- /dev/null +++ b/libc/nt/KernelBase/MapViewOfFile3FromApp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MapViewOfFile3FromApp,MapViewOfFile3FromApp,1004 diff --git a/libc/nt/KernelBase/MapViewOfFileEx.s b/libc/nt/KernelBase/MapViewOfFileEx.s new file mode 100644 index 00000000..3b379ada --- /dev/null +++ b/libc/nt/KernelBase/MapViewOfFileEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MapViewOfFileEx,MapViewOfFileEx,1005 diff --git a/libc/nt/KernelBase/MapViewOfFileExNuma.s b/libc/nt/KernelBase/MapViewOfFileExNuma.s new file mode 100644 index 00000000..1c782879 --- /dev/null +++ b/libc/nt/KernelBase/MapViewOfFileExNuma.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MapViewOfFileExNuma,MapViewOfFileExNuma,1006 + + .text.windows +MapViewOfFileExNuma: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_MapViewOfFileExNuma(%rip),%rax + jmp __sysv2nt8 + .endfn MapViewOfFileExNuma,globl + .previous diff --git a/libc/nt/KernelBase/MapViewOfFileFromApp.s b/libc/nt/KernelBase/MapViewOfFileFromApp.s new file mode 100644 index 00000000..c56692c2 --- /dev/null +++ b/libc/nt/KernelBase/MapViewOfFileFromApp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MapViewOfFileFromApp,MapViewOfFileFromApp,1007 diff --git a/libc/nt/KernelBase/MapViewOfFileNuma2.s b/libc/nt/KernelBase/MapViewOfFileNuma2.s new file mode 100644 index 00000000..8499a33c --- /dev/null +++ b/libc/nt/KernelBase/MapViewOfFileNuma2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MapViewOfFileNuma2,MapViewOfFileNuma2,1008 diff --git a/libc/nt/KernelBase/MoveFileExW.s b/libc/nt/KernelBase/MoveFileExW.s new file mode 100644 index 00000000..b68b720b --- /dev/null +++ b/libc/nt/KernelBase/MoveFileExW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MoveFileExW,MoveFileExW,1009 + + .text.windows +MoveFileEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_MoveFileExW(%rip),%rax + jmp __sysv2nt + .endfn MoveFileEx,globl + .previous diff --git a/libc/nt/KernelBase/MoveFileWithProgressTransactedW.s b/libc/nt/KernelBase/MoveFileWithProgressTransactedW.s new file mode 100644 index 00000000..c3d5ed32 --- /dev/null +++ b/libc/nt/KernelBase/MoveFileWithProgressTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MoveFileWithProgressTransactedW,MoveFileWithProgressTransactedW,1010 diff --git a/libc/nt/KernelBase/MoveFileWithProgressW.s b/libc/nt/KernelBase/MoveFileWithProgressW.s new file mode 100644 index 00000000..24d6e02a --- /dev/null +++ b/libc/nt/KernelBase/MoveFileWithProgressW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MoveFileWithProgressW,MoveFileWithProgressW,1011 diff --git a/libc/nt/KernelBase/MulDiv.s b/libc/nt/KernelBase/MulDiv.s new file mode 100644 index 00000000..f28d3483 --- /dev/null +++ b/libc/nt/KernelBase/MulDiv.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MulDiv,MulDiv,1012 diff --git a/libc/nt/KernelBase/MultiByteToWideChar.s b/libc/nt/KernelBase/MultiByteToWideChar.s new file mode 100644 index 00000000..c2902cda --- /dev/null +++ b/libc/nt/KernelBase/MultiByteToWideChar.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_MultiByteToWideChar,MultiByteToWideChar,1013 diff --git a/libc/nt/KernelBase/NamedPipeEventEnum.s b/libc/nt/KernelBase/NamedPipeEventEnum.s new file mode 100644 index 00000000..c1662089 --- /dev/null +++ b/libc/nt/KernelBase/NamedPipeEventEnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_NamedPipeEventEnum,NamedPipeEventEnum,1014 diff --git a/libc/nt/KernelBase/NamedPipeEventSelect.s b/libc/nt/KernelBase/NamedPipeEventSelect.s new file mode 100644 index 00000000..4a900c44 --- /dev/null +++ b/libc/nt/KernelBase/NamedPipeEventSelect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_NamedPipeEventSelect,NamedPipeEventSelect,1015 diff --git a/libc/nt/KernelBase/NeedCurrentDirectoryForExePathA.s b/libc/nt/KernelBase/NeedCurrentDirectoryForExePathA.s new file mode 100644 index 00000000..a9bc79fd --- /dev/null +++ b/libc/nt/KernelBase/NeedCurrentDirectoryForExePathA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_NeedCurrentDirectoryForExePathA,NeedCurrentDirectoryForExePathA,1016 diff --git a/libc/nt/KernelBase/NeedCurrentDirectoryForExePathW.s b/libc/nt/KernelBase/NeedCurrentDirectoryForExePathW.s new file mode 100644 index 00000000..ce49a7ee --- /dev/null +++ b/libc/nt/KernelBase/NeedCurrentDirectoryForExePathW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_NeedCurrentDirectoryForExePathW,NeedCurrentDirectoryForExePathW,1017 diff --git a/libc/nt/KernelBase/NlsCheckPolicy.s b/libc/nt/KernelBase/NlsCheckPolicy.s new file mode 100644 index 00000000..690de795 --- /dev/null +++ b/libc/nt/KernelBase/NlsCheckPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_NlsCheckPolicy,NlsCheckPolicy,1018 diff --git a/libc/nt/KernelBase/NlsDispatchAnsiEnumProc.s b/libc/nt/KernelBase/NlsDispatchAnsiEnumProc.s new file mode 100644 index 00000000..759dda40 --- /dev/null +++ b/libc/nt/KernelBase/NlsDispatchAnsiEnumProc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_NlsDispatchAnsiEnumProc,NlsDispatchAnsiEnumProc,1019 diff --git a/libc/nt/KernelBase/NlsEventDataDescCreate.s b/libc/nt/KernelBase/NlsEventDataDescCreate.s new file mode 100644 index 00000000..0e2ceca2 --- /dev/null +++ b/libc/nt/KernelBase/NlsEventDataDescCreate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_NlsEventDataDescCreate,NlsEventDataDescCreate,1020 diff --git a/libc/nt/KernelBase/NlsGetACPFromLocale.s b/libc/nt/KernelBase/NlsGetACPFromLocale.s new file mode 100644 index 00000000..010de0ad --- /dev/null +++ b/libc/nt/KernelBase/NlsGetACPFromLocale.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_NlsGetACPFromLocale,NlsGetACPFromLocale,1021 diff --git a/libc/nt/KernelBase/NlsGetCacheUpdateCount.s b/libc/nt/KernelBase/NlsGetCacheUpdateCount.s new file mode 100644 index 00000000..4d9d8b9c --- /dev/null +++ b/libc/nt/KernelBase/NlsGetCacheUpdateCount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_NlsGetCacheUpdateCount,NlsGetCacheUpdateCount,1022 diff --git a/libc/nt/KernelBase/NlsIsUserDefaultLocale.s b/libc/nt/KernelBase/NlsIsUserDefaultLocale.s new file mode 100644 index 00000000..f039da84 --- /dev/null +++ b/libc/nt/KernelBase/NlsIsUserDefaultLocale.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_NlsIsUserDefaultLocale,NlsIsUserDefaultLocale,1023 diff --git a/libc/nt/KernelBase/NlsUpdateLocale.s b/libc/nt/KernelBase/NlsUpdateLocale.s new file mode 100644 index 00000000..3a69d0f4 --- /dev/null +++ b/libc/nt/KernelBase/NlsUpdateLocale.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_NlsUpdateLocale,NlsUpdateLocale,1024 diff --git a/libc/nt/KernelBase/NlsUpdateSystemLocale.s b/libc/nt/KernelBase/NlsUpdateSystemLocale.s new file mode 100644 index 00000000..86e7895a --- /dev/null +++ b/libc/nt/KernelBase/NlsUpdateSystemLocale.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_NlsUpdateSystemLocale,NlsUpdateSystemLocale,1025 diff --git a/libc/nt/KernelBase/NlsValidateLocale.s b/libc/nt/KernelBase/NlsValidateLocale.s new file mode 100644 index 00000000..c43b8b95 --- /dev/null +++ b/libc/nt/KernelBase/NlsValidateLocale.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_NlsValidateLocale,NlsValidateLocale,1026 diff --git a/libc/nt/KernelBase/NlsWriteEtwEvent.s b/libc/nt/KernelBase/NlsWriteEtwEvent.s new file mode 100644 index 00000000..0a0e79ed --- /dev/null +++ b/libc/nt/KernelBase/NlsWriteEtwEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_NlsWriteEtwEvent,NlsWriteEtwEvent,1027 diff --git a/libc/nt/KernelBase/NormalizeString.s b/libc/nt/KernelBase/NormalizeString.s new file mode 100644 index 00000000..eb3f482d --- /dev/null +++ b/libc/nt/KernelBase/NormalizeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_NormalizeString,NormalizeString,1028 diff --git a/libc/nt/KernelBase/NotifyMountMgr.s b/libc/nt/KernelBase/NotifyMountMgr.s new file mode 100644 index 00000000..2bce67eb --- /dev/null +++ b/libc/nt/KernelBase/NotifyMountMgr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_NotifyMountMgr,NotifyMountMgr,1029 diff --git a/libc/nt/KernelBase/NotifyRedirectedStringChange.s b/libc/nt/KernelBase/NotifyRedirectedStringChange.s new file mode 100644 index 00000000..0dd8641b --- /dev/null +++ b/libc/nt/KernelBase/NotifyRedirectedStringChange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_NotifyRedirectedStringChange,NotifyRedirectedStringChange,1030 diff --git a/libc/nt/KernelBase/ObjectCloseAuditAlarmW.s b/libc/nt/KernelBase/ObjectCloseAuditAlarmW.s new file mode 100644 index 00000000..77c6a924 --- /dev/null +++ b/libc/nt/KernelBase/ObjectCloseAuditAlarmW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ObjectCloseAuditAlarmW,ObjectCloseAuditAlarmW,1031 diff --git a/libc/nt/KernelBase/ObjectDeleteAuditAlarmW.s b/libc/nt/KernelBase/ObjectDeleteAuditAlarmW.s new file mode 100644 index 00000000..3652bc42 --- /dev/null +++ b/libc/nt/KernelBase/ObjectDeleteAuditAlarmW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ObjectDeleteAuditAlarmW,ObjectDeleteAuditAlarmW,1032 diff --git a/libc/nt/KernelBase/ObjectOpenAuditAlarmW.s b/libc/nt/KernelBase/ObjectOpenAuditAlarmW.s new file mode 100644 index 00000000..1ed73116 --- /dev/null +++ b/libc/nt/KernelBase/ObjectOpenAuditAlarmW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ObjectOpenAuditAlarmW,ObjectOpenAuditAlarmW,1033 diff --git a/libc/nt/KernelBase/ObjectPrivilegeAuditAlarmW.s b/libc/nt/KernelBase/ObjectPrivilegeAuditAlarmW.s new file mode 100644 index 00000000..75e77824 --- /dev/null +++ b/libc/nt/KernelBase/ObjectPrivilegeAuditAlarmW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ObjectPrivilegeAuditAlarmW,ObjectPrivilegeAuditAlarmW,1034 diff --git a/libc/nt/KernelBase/OfferVirtualMemory.s b/libc/nt/KernelBase/OfferVirtualMemory.s new file mode 100644 index 00000000..645a97b9 --- /dev/null +++ b/libc/nt/KernelBase/OfferVirtualMemory.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OfferVirtualMemory,OfferVirtualMemory,1035 + + .text.windows +OfferVirtualMemory: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_OfferVirtualMemory(%rip),%rax + jmp __sysv2nt + .endfn OfferVirtualMemory,globl + .previous diff --git a/libc/nt/KernelBase/OpenCommPort.s b/libc/nt/KernelBase/OpenCommPort.s new file mode 100644 index 00000000..9532fcc9 --- /dev/null +++ b/libc/nt/KernelBase/OpenCommPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenCommPort,OpenCommPort,1036 diff --git a/libc/nt/KernelBase/OpenEventA.s b/libc/nt/KernelBase/OpenEventA.s new file mode 100644 index 00000000..858a16f3 --- /dev/null +++ b/libc/nt/KernelBase/OpenEventA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenEventA,OpenEventA,1037 diff --git a/libc/nt/KernelBase/OpenEventW.s b/libc/nt/KernelBase/OpenEventW.s new file mode 100644 index 00000000..63320a1c --- /dev/null +++ b/libc/nt/KernelBase/OpenEventW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenEventW,OpenEventW,1038 diff --git a/libc/nt/KernelBase/OpenFileById.s b/libc/nt/KernelBase/OpenFileById.s new file mode 100644 index 00000000..d1315d0c --- /dev/null +++ b/libc/nt/KernelBase/OpenFileById.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenFileById,OpenFileById,1039 diff --git a/libc/nt/KernelBase/OpenFileMappingFromApp.s b/libc/nt/KernelBase/OpenFileMappingFromApp.s new file mode 100644 index 00000000..ae087af7 --- /dev/null +++ b/libc/nt/KernelBase/OpenFileMappingFromApp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenFileMappingFromApp,OpenFileMappingFromApp,1040 diff --git a/libc/nt/KernelBase/OpenFileMappingW.s b/libc/nt/KernelBase/OpenFileMappingW.s new file mode 100644 index 00000000..016c46ac --- /dev/null +++ b/libc/nt/KernelBase/OpenFileMappingW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenFileMappingW,OpenFileMappingW,1041 diff --git a/libc/nt/KernelBase/OpenGlobalizationUserSettingsKey.s b/libc/nt/KernelBase/OpenGlobalizationUserSettingsKey.s new file mode 100644 index 00000000..3d033529 --- /dev/null +++ b/libc/nt/KernelBase/OpenGlobalizationUserSettingsKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenGlobalizationUserSettingsKey,OpenGlobalizationUserSettingsKey,1042 diff --git a/libc/nt/KernelBase/OpenMutexW.s b/libc/nt/KernelBase/OpenMutexW.s new file mode 100644 index 00000000..2704a20e --- /dev/null +++ b/libc/nt/KernelBase/OpenMutexW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenMutexW,OpenMutexW,1043 diff --git a/libc/nt/KernelBase/OpenPackageInfoByFullName.s b/libc/nt/KernelBase/OpenPackageInfoByFullName.s new file mode 100644 index 00000000..7e73a26e --- /dev/null +++ b/libc/nt/KernelBase/OpenPackageInfoByFullName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenPackageInfoByFullName,OpenPackageInfoByFullName,1044 diff --git a/libc/nt/KernelBase/OpenPackageInfoByFullNameForUser.s b/libc/nt/KernelBase/OpenPackageInfoByFullNameForUser.s new file mode 100644 index 00000000..c1563d43 --- /dev/null +++ b/libc/nt/KernelBase/OpenPackageInfoByFullNameForUser.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenPackageInfoByFullNameForUser,OpenPackageInfoByFullNameForUser,1045 diff --git a/libc/nt/KernelBase/OpenPrivateNamespaceW.s b/libc/nt/KernelBase/OpenPrivateNamespaceW.s new file mode 100644 index 00000000..792de100 --- /dev/null +++ b/libc/nt/KernelBase/OpenPrivateNamespaceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenPrivateNamespaceW,OpenPrivateNamespaceW,1046 diff --git a/libc/nt/KernelBase/OpenProcess.s b/libc/nt/KernelBase/OpenProcess.s new file mode 100644 index 00000000..b0359a86 --- /dev/null +++ b/libc/nt/KernelBase/OpenProcess.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenProcess,OpenProcess,1047 + + .text.windows +OpenProcess: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_OpenProcess(%rip),%rax + jmp __sysv2nt + .endfn OpenProcess,globl + .previous diff --git a/libc/nt/KernelBase/OpenProcessToken.s b/libc/nt/KernelBase/OpenProcessToken.s new file mode 100644 index 00000000..133bc13f --- /dev/null +++ b/libc/nt/KernelBase/OpenProcessToken.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenProcessToken,OpenProcessToken,1048 + + .text.windows +OpenProcessToken: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_OpenProcessToken(%rip),%rax + jmp __sysv2nt + .endfn OpenProcessToken,globl + .previous diff --git a/libc/nt/KernelBase/OpenRegKey.s b/libc/nt/KernelBase/OpenRegKey.s new file mode 100644 index 00000000..88f11f8d --- /dev/null +++ b/libc/nt/KernelBase/OpenRegKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenRegKey,OpenRegKey,1049 diff --git a/libc/nt/KernelBase/OpenSemaphoreW.s b/libc/nt/KernelBase/OpenSemaphoreW.s new file mode 100644 index 00000000..5fd71faa --- /dev/null +++ b/libc/nt/KernelBase/OpenSemaphoreW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenSemaphoreW,OpenSemaphoreW,1050 diff --git a/libc/nt/KernelBase/OpenState.s b/libc/nt/KernelBase/OpenState.s new file mode 100644 index 00000000..1bab8ea2 --- /dev/null +++ b/libc/nt/KernelBase/OpenState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenState,OpenState,1051 diff --git a/libc/nt/KernelBase/OpenStateAtom.s b/libc/nt/KernelBase/OpenStateAtom.s new file mode 100644 index 00000000..97b54d54 --- /dev/null +++ b/libc/nt/KernelBase/OpenStateAtom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenStateAtom,OpenStateAtom,1052 diff --git a/libc/nt/KernelBase/OpenStateExplicit.s b/libc/nt/KernelBase/OpenStateExplicit.s new file mode 100644 index 00000000..a038a930 --- /dev/null +++ b/libc/nt/KernelBase/OpenStateExplicit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenStateExplicit,OpenStateExplicit,1053 diff --git a/libc/nt/KernelBase/OpenStateExplicitForUserSid.s b/libc/nt/KernelBase/OpenStateExplicitForUserSid.s new file mode 100644 index 00000000..348b6e0b --- /dev/null +++ b/libc/nt/KernelBase/OpenStateExplicitForUserSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenStateExplicitForUserSid,OpenStateExplicitForUserSid,1054 diff --git a/libc/nt/KernelBase/OpenStateExplicitForUserSidString.s b/libc/nt/KernelBase/OpenStateExplicitForUserSidString.s new file mode 100644 index 00000000..3a479f81 --- /dev/null +++ b/libc/nt/KernelBase/OpenStateExplicitForUserSidString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenStateExplicitForUserSidString,OpenStateExplicitForUserSidString,1055 diff --git a/libc/nt/KernelBase/OpenThread.s b/libc/nt/KernelBase/OpenThread.s new file mode 100644 index 00000000..5d7e3cd9 --- /dev/null +++ b/libc/nt/KernelBase/OpenThread.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenThread,OpenThread,1056 + + .text.windows +OpenThread: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_OpenThread(%rip),%rax + jmp __sysv2nt + .endfn OpenThread,globl + .previous diff --git a/libc/nt/KernelBase/OpenThreadToken.s b/libc/nt/KernelBase/OpenThreadToken.s new file mode 100644 index 00000000..61f03faf --- /dev/null +++ b/libc/nt/KernelBase/OpenThreadToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenThreadToken,OpenThreadToken,1057 diff --git a/libc/nt/KernelBase/OpenWaitableTimerW.s b/libc/nt/KernelBase/OpenWaitableTimerW.s new file mode 100644 index 00000000..78078c0d --- /dev/null +++ b/libc/nt/KernelBase/OpenWaitableTimerW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OpenWaitableTimerW,OpenWaitableTimerW,1058 diff --git a/libc/nt/KernelBase/OutputDebugStringA.s b/libc/nt/KernelBase/OutputDebugStringA.s new file mode 100644 index 00000000..c9b2c2d9 --- /dev/null +++ b/libc/nt/KernelBase/OutputDebugStringA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OutputDebugStringA,OutputDebugStringA,1059 diff --git a/libc/nt/KernelBase/OutputDebugStringW.s b/libc/nt/KernelBase/OutputDebugStringW.s new file mode 100644 index 00000000..f275cb2c --- /dev/null +++ b/libc/nt/KernelBase/OutputDebugStringW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OutputDebugStringW,OutputDebugStringW,1060 diff --git a/libc/nt/KernelBase/OverrideRoamingDataModificationTimesInRange.s b/libc/nt/KernelBase/OverrideRoamingDataModificationTimesInRange.s new file mode 100644 index 00000000..2199682f --- /dev/null +++ b/libc/nt/KernelBase/OverrideRoamingDataModificationTimesInRange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_OverrideRoamingDataModificationTimesInRange,OverrideRoamingDataModificationTimesInRange,1061 diff --git a/libc/nt/KernelBase/PackageFamilyNameFromFullName.s b/libc/nt/KernelBase/PackageFamilyNameFromFullName.s new file mode 100644 index 00000000..8901a61e --- /dev/null +++ b/libc/nt/KernelBase/PackageFamilyNameFromFullName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PackageFamilyNameFromFullName,PackageFamilyNameFromFullName,1062 diff --git a/libc/nt/KernelBase/PackageFamilyNameFromFullNameA.s b/libc/nt/KernelBase/PackageFamilyNameFromFullNameA.s new file mode 100644 index 00000000..537cb7e6 --- /dev/null +++ b/libc/nt/KernelBase/PackageFamilyNameFromFullNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PackageFamilyNameFromFullNameA,PackageFamilyNameFromFullNameA,1063 diff --git a/libc/nt/KernelBase/PackageFamilyNameFromId.s b/libc/nt/KernelBase/PackageFamilyNameFromId.s new file mode 100644 index 00000000..91188ad5 --- /dev/null +++ b/libc/nt/KernelBase/PackageFamilyNameFromId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PackageFamilyNameFromId,PackageFamilyNameFromId,1064 diff --git a/libc/nt/KernelBase/PackageFamilyNameFromIdA.s b/libc/nt/KernelBase/PackageFamilyNameFromIdA.s new file mode 100644 index 00000000..54f4b60f --- /dev/null +++ b/libc/nt/KernelBase/PackageFamilyNameFromIdA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PackageFamilyNameFromIdA,PackageFamilyNameFromIdA,1065 diff --git a/libc/nt/KernelBase/PackageFamilyNameFromProductId.s b/libc/nt/KernelBase/PackageFamilyNameFromProductId.s new file mode 100644 index 00000000..ead4e67f --- /dev/null +++ b/libc/nt/KernelBase/PackageFamilyNameFromProductId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PackageFamilyNameFromProductId,PackageFamilyNameFromProductId,1066 diff --git a/libc/nt/KernelBase/PackageFullNameFromId.s b/libc/nt/KernelBase/PackageFullNameFromId.s new file mode 100644 index 00000000..ca89ef74 --- /dev/null +++ b/libc/nt/KernelBase/PackageFullNameFromId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PackageFullNameFromId,PackageFullNameFromId,1067 diff --git a/libc/nt/KernelBase/PackageFullNameFromIdA.s b/libc/nt/KernelBase/PackageFullNameFromIdA.s new file mode 100644 index 00000000..70691f83 --- /dev/null +++ b/libc/nt/KernelBase/PackageFullNameFromIdA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PackageFullNameFromIdA,PackageFullNameFromIdA,1068 diff --git a/libc/nt/KernelBase/PackageFullNameFromProductId.s b/libc/nt/KernelBase/PackageFullNameFromProductId.s new file mode 100644 index 00000000..3879c5ad --- /dev/null +++ b/libc/nt/KernelBase/PackageFullNameFromProductId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PackageFullNameFromProductId,PackageFullNameFromProductId,1069 diff --git a/libc/nt/KernelBase/PackageIdFromFullName.s b/libc/nt/KernelBase/PackageIdFromFullName.s new file mode 100644 index 00000000..e457a130 --- /dev/null +++ b/libc/nt/KernelBase/PackageIdFromFullName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PackageIdFromFullName,PackageIdFromFullName,1070 diff --git a/libc/nt/KernelBase/PackageIdFromFullNameA.s b/libc/nt/KernelBase/PackageIdFromFullNameA.s new file mode 100644 index 00000000..9baad166 --- /dev/null +++ b/libc/nt/KernelBase/PackageIdFromFullNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PackageIdFromFullNameA,PackageIdFromFullNameA,1071 diff --git a/libc/nt/KernelBase/PackageIdFromProductId.s b/libc/nt/KernelBase/PackageIdFromProductId.s new file mode 100644 index 00000000..cd429147 --- /dev/null +++ b/libc/nt/KernelBase/PackageIdFromProductId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PackageIdFromProductId,PackageIdFromProductId,1072 diff --git a/libc/nt/KernelBase/PackageNameAndPublisherIdFromFamilyName.s b/libc/nt/KernelBase/PackageNameAndPublisherIdFromFamilyName.s new file mode 100644 index 00000000..3f489d6e --- /dev/null +++ b/libc/nt/KernelBase/PackageNameAndPublisherIdFromFamilyName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PackageNameAndPublisherIdFromFamilyName,PackageNameAndPublisherIdFromFamilyName,1073 diff --git a/libc/nt/KernelBase/PackageNameAndPublisherIdFromFamilyNameA.s b/libc/nt/KernelBase/PackageNameAndPublisherIdFromFamilyNameA.s new file mode 100644 index 00000000..6f9e3e41 --- /dev/null +++ b/libc/nt/KernelBase/PackageNameAndPublisherIdFromFamilyNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PackageNameAndPublisherIdFromFamilyNameA,PackageNameAndPublisherIdFromFamilyNameA,1074 diff --git a/libc/nt/KernelBase/PackageRelativeApplicationIdFromProductId.s b/libc/nt/KernelBase/PackageRelativeApplicationIdFromProductId.s new file mode 100644 index 00000000..d033e423 --- /dev/null +++ b/libc/nt/KernelBase/PackageRelativeApplicationIdFromProductId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PackageRelativeApplicationIdFromProductId,PackageRelativeApplicationIdFromProductId,1075 diff --git a/libc/nt/KernelBase/PackageSidFromFamilyName.s b/libc/nt/KernelBase/PackageSidFromFamilyName.s new file mode 100644 index 00000000..8a0f4814 --- /dev/null +++ b/libc/nt/KernelBase/PackageSidFromFamilyName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PackageSidFromFamilyName,PackageSidFromFamilyName,1076 diff --git a/libc/nt/KernelBase/PackageSidFromProductId.s b/libc/nt/KernelBase/PackageSidFromProductId.s new file mode 100644 index 00000000..119437ec --- /dev/null +++ b/libc/nt/KernelBase/PackageSidFromProductId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PackageSidFromProductId,PackageSidFromProductId,1 diff --git a/libc/nt/KernelBase/ParseApplicationUserModelId.s b/libc/nt/KernelBase/ParseApplicationUserModelId.s new file mode 100644 index 00000000..e3109e08 --- /dev/null +++ b/libc/nt/KernelBase/ParseApplicationUserModelId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ParseApplicationUserModelId,ParseApplicationUserModelId,1077 diff --git a/libc/nt/KernelBase/ParseApplicationUserModelIdA.s b/libc/nt/KernelBase/ParseApplicationUserModelIdA.s new file mode 100644 index 00000000..3b6f02c6 --- /dev/null +++ b/libc/nt/KernelBase/ParseApplicationUserModelIdA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ParseApplicationUserModelIdA,ParseApplicationUserModelIdA,1078 diff --git a/libc/nt/KernelBase/ParseURLA.s b/libc/nt/KernelBase/ParseURLA.s new file mode 100644 index 00000000..21cdb6ba --- /dev/null +++ b/libc/nt/KernelBase/ParseURLA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ParseURLA,ParseURLA,1079 diff --git a/libc/nt/KernelBase/ParseURLW.s b/libc/nt/KernelBase/ParseURLW.s new file mode 100644 index 00000000..de395aba --- /dev/null +++ b/libc/nt/KernelBase/ParseURLW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ParseURLW,ParseURLW,1080 diff --git a/libc/nt/KernelBase/PathAddBackslashA.s b/libc/nt/KernelBase/PathAddBackslashA.s new file mode 100644 index 00000000..fa66931c --- /dev/null +++ b/libc/nt/KernelBase/PathAddBackslashA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathAddBackslashA,PathAddBackslashA,1081 diff --git a/libc/nt/KernelBase/PathAddBackslashW.s b/libc/nt/KernelBase/PathAddBackslashW.s new file mode 100644 index 00000000..de10501c --- /dev/null +++ b/libc/nt/KernelBase/PathAddBackslashW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathAddBackslashW,PathAddBackslashW,1082 diff --git a/libc/nt/KernelBase/PathAddExtensionA.s b/libc/nt/KernelBase/PathAddExtensionA.s new file mode 100644 index 00000000..082124e0 --- /dev/null +++ b/libc/nt/KernelBase/PathAddExtensionA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathAddExtensionA,PathAddExtensionA,1083 diff --git a/libc/nt/KernelBase/PathAddExtensionW.s b/libc/nt/KernelBase/PathAddExtensionW.s new file mode 100644 index 00000000..7b15da9e --- /dev/null +++ b/libc/nt/KernelBase/PathAddExtensionW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathAddExtensionW,PathAddExtensionW,1084 diff --git a/libc/nt/KernelBase/PathAllocCanonicalize.s b/libc/nt/KernelBase/PathAllocCanonicalize.s new file mode 100644 index 00000000..aac7e540 --- /dev/null +++ b/libc/nt/KernelBase/PathAllocCanonicalize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathAllocCanonicalize,PathAllocCanonicalize,1085 diff --git a/libc/nt/KernelBase/PathAllocCombine.s b/libc/nt/KernelBase/PathAllocCombine.s new file mode 100644 index 00000000..6c316c61 --- /dev/null +++ b/libc/nt/KernelBase/PathAllocCombine.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathAllocCombine,PathAllocCombine,1086 diff --git a/libc/nt/KernelBase/PathAppendA.s b/libc/nt/KernelBase/PathAppendA.s new file mode 100644 index 00000000..5f87fe41 --- /dev/null +++ b/libc/nt/KernelBase/PathAppendA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathAppendA,PathAppendA,1087 diff --git a/libc/nt/KernelBase/PathAppendW.s b/libc/nt/KernelBase/PathAppendW.s new file mode 100644 index 00000000..8fbb2f7e --- /dev/null +++ b/libc/nt/KernelBase/PathAppendW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathAppendW,PathAppendW,1088 diff --git a/libc/nt/KernelBase/PathCanonicalizeA.s b/libc/nt/KernelBase/PathCanonicalizeA.s new file mode 100644 index 00000000..f2594906 --- /dev/null +++ b/libc/nt/KernelBase/PathCanonicalizeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCanonicalizeA,PathCanonicalizeA,1089 diff --git a/libc/nt/KernelBase/PathCanonicalizeW.s b/libc/nt/KernelBase/PathCanonicalizeW.s new file mode 100644 index 00000000..07125417 --- /dev/null +++ b/libc/nt/KernelBase/PathCanonicalizeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCanonicalizeW,PathCanonicalizeW,1090 diff --git a/libc/nt/KernelBase/PathCchAddBackslash.s b/libc/nt/KernelBase/PathCchAddBackslash.s new file mode 100644 index 00000000..34383613 --- /dev/null +++ b/libc/nt/KernelBase/PathCchAddBackslash.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchAddBackslash,PathCchAddBackslash,1091 diff --git a/libc/nt/KernelBase/PathCchAddBackslashEx.s b/libc/nt/KernelBase/PathCchAddBackslashEx.s new file mode 100644 index 00000000..200ede37 --- /dev/null +++ b/libc/nt/KernelBase/PathCchAddBackslashEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchAddBackslashEx,PathCchAddBackslashEx,1092 diff --git a/libc/nt/KernelBase/PathCchAddExtension.s b/libc/nt/KernelBase/PathCchAddExtension.s new file mode 100644 index 00000000..7e0fb43b --- /dev/null +++ b/libc/nt/KernelBase/PathCchAddExtension.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchAddExtension,PathCchAddExtension,1093 diff --git a/libc/nt/KernelBase/PathCchAppend.s b/libc/nt/KernelBase/PathCchAppend.s new file mode 100644 index 00000000..ba191167 --- /dev/null +++ b/libc/nt/KernelBase/PathCchAppend.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchAppend,PathCchAppend,1094 diff --git a/libc/nt/KernelBase/PathCchAppendEx.s b/libc/nt/KernelBase/PathCchAppendEx.s new file mode 100644 index 00000000..38276ffb --- /dev/null +++ b/libc/nt/KernelBase/PathCchAppendEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchAppendEx,PathCchAppendEx,1095 diff --git a/libc/nt/KernelBase/PathCchCanonicalize.s b/libc/nt/KernelBase/PathCchCanonicalize.s new file mode 100644 index 00000000..cf768ea1 --- /dev/null +++ b/libc/nt/KernelBase/PathCchCanonicalize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchCanonicalize,PathCchCanonicalize,1096 diff --git a/libc/nt/KernelBase/PathCchCanonicalizeEx.s b/libc/nt/KernelBase/PathCchCanonicalizeEx.s new file mode 100644 index 00000000..0db98df2 --- /dev/null +++ b/libc/nt/KernelBase/PathCchCanonicalizeEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchCanonicalizeEx,PathCchCanonicalizeEx,1097 diff --git a/libc/nt/KernelBase/PathCchCombine.s b/libc/nt/KernelBase/PathCchCombine.s new file mode 100644 index 00000000..809c7089 --- /dev/null +++ b/libc/nt/KernelBase/PathCchCombine.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchCombine,PathCchCombine,1098 diff --git a/libc/nt/KernelBase/PathCchCombineEx.s b/libc/nt/KernelBase/PathCchCombineEx.s new file mode 100644 index 00000000..d998e71b --- /dev/null +++ b/libc/nt/KernelBase/PathCchCombineEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchCombineEx,PathCchCombineEx,1099 diff --git a/libc/nt/KernelBase/PathCchFindExtension.s b/libc/nt/KernelBase/PathCchFindExtension.s new file mode 100644 index 00000000..c3524331 --- /dev/null +++ b/libc/nt/KernelBase/PathCchFindExtension.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchFindExtension,PathCchFindExtension,1100 diff --git a/libc/nt/KernelBase/PathCchIsRoot.s b/libc/nt/KernelBase/PathCchIsRoot.s new file mode 100644 index 00000000..218176c5 --- /dev/null +++ b/libc/nt/KernelBase/PathCchIsRoot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchIsRoot,PathCchIsRoot,1101 diff --git a/libc/nt/KernelBase/PathCchRemoveBackslash.s b/libc/nt/KernelBase/PathCchRemoveBackslash.s new file mode 100644 index 00000000..4792a10a --- /dev/null +++ b/libc/nt/KernelBase/PathCchRemoveBackslash.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchRemoveBackslash,PathCchRemoveBackslash,1102 diff --git a/libc/nt/KernelBase/PathCchRemoveBackslashEx.s b/libc/nt/KernelBase/PathCchRemoveBackslashEx.s new file mode 100644 index 00000000..d153f047 --- /dev/null +++ b/libc/nt/KernelBase/PathCchRemoveBackslashEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchRemoveBackslashEx,PathCchRemoveBackslashEx,1103 diff --git a/libc/nt/KernelBase/PathCchRemoveExtension.s b/libc/nt/KernelBase/PathCchRemoveExtension.s new file mode 100644 index 00000000..ca5b471d --- /dev/null +++ b/libc/nt/KernelBase/PathCchRemoveExtension.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchRemoveExtension,PathCchRemoveExtension,1104 diff --git a/libc/nt/KernelBase/PathCchRemoveFileSpec.s b/libc/nt/KernelBase/PathCchRemoveFileSpec.s new file mode 100644 index 00000000..edcfae82 --- /dev/null +++ b/libc/nt/KernelBase/PathCchRemoveFileSpec.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchRemoveFileSpec,PathCchRemoveFileSpec,1105 diff --git a/libc/nt/KernelBase/PathCchRenameExtension.s b/libc/nt/KernelBase/PathCchRenameExtension.s new file mode 100644 index 00000000..c01680cd --- /dev/null +++ b/libc/nt/KernelBase/PathCchRenameExtension.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchRenameExtension,PathCchRenameExtension,1106 diff --git a/libc/nt/KernelBase/PathCchSkipRoot.s b/libc/nt/KernelBase/PathCchSkipRoot.s new file mode 100644 index 00000000..016cc844 --- /dev/null +++ b/libc/nt/KernelBase/PathCchSkipRoot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchSkipRoot,PathCchSkipRoot,1107 diff --git a/libc/nt/KernelBase/PathCchStripPrefix.s b/libc/nt/KernelBase/PathCchStripPrefix.s new file mode 100644 index 00000000..7b799153 --- /dev/null +++ b/libc/nt/KernelBase/PathCchStripPrefix.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchStripPrefix,PathCchStripPrefix,1108 diff --git a/libc/nt/KernelBase/PathCchStripToRoot.s b/libc/nt/KernelBase/PathCchStripToRoot.s new file mode 100644 index 00000000..679cf6e3 --- /dev/null +++ b/libc/nt/KernelBase/PathCchStripToRoot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCchStripToRoot,PathCchStripToRoot,1109 diff --git a/libc/nt/KernelBase/PathCombineA.s b/libc/nt/KernelBase/PathCombineA.s new file mode 100644 index 00000000..dd527207 --- /dev/null +++ b/libc/nt/KernelBase/PathCombineA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCombineA,PathCombineA,1110 diff --git a/libc/nt/KernelBase/PathCombineW.s b/libc/nt/KernelBase/PathCombineW.s new file mode 100644 index 00000000..3be21d96 --- /dev/null +++ b/libc/nt/KernelBase/PathCombineW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCombineW,PathCombineW,1111 diff --git a/libc/nt/KernelBase/PathCommonPrefixA.s b/libc/nt/KernelBase/PathCommonPrefixA.s new file mode 100644 index 00000000..0850b8d2 --- /dev/null +++ b/libc/nt/KernelBase/PathCommonPrefixA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCommonPrefixA,PathCommonPrefixA,1112 diff --git a/libc/nt/KernelBase/PathCommonPrefixW.s b/libc/nt/KernelBase/PathCommonPrefixW.s new file mode 100644 index 00000000..1504201e --- /dev/null +++ b/libc/nt/KernelBase/PathCommonPrefixW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCommonPrefixW,PathCommonPrefixW,1113 diff --git a/libc/nt/KernelBase/PathCreateFromUrlA.s b/libc/nt/KernelBase/PathCreateFromUrlA.s new file mode 100644 index 00000000..9cb36fc3 --- /dev/null +++ b/libc/nt/KernelBase/PathCreateFromUrlA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCreateFromUrlA,PathCreateFromUrlA,1114 diff --git a/libc/nt/KernelBase/PathCreateFromUrlAlloc.s b/libc/nt/KernelBase/PathCreateFromUrlAlloc.s new file mode 100644 index 00000000..972ff08d --- /dev/null +++ b/libc/nt/KernelBase/PathCreateFromUrlAlloc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCreateFromUrlAlloc,PathCreateFromUrlAlloc,1115 diff --git a/libc/nt/KernelBase/PathCreateFromUrlW.s b/libc/nt/KernelBase/PathCreateFromUrlW.s new file mode 100644 index 00000000..03de14ee --- /dev/null +++ b/libc/nt/KernelBase/PathCreateFromUrlW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathCreateFromUrlW,PathCreateFromUrlW,1116 diff --git a/libc/nt/KernelBase/PathFileExistsA.s b/libc/nt/KernelBase/PathFileExistsA.s new file mode 100644 index 00000000..8e247619 --- /dev/null +++ b/libc/nt/KernelBase/PathFileExistsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathFileExistsA,PathFileExistsA,1117 diff --git a/libc/nt/KernelBase/PathFileExistsW.s b/libc/nt/KernelBase/PathFileExistsW.s new file mode 100644 index 00000000..501197c9 --- /dev/null +++ b/libc/nt/KernelBase/PathFileExistsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathFileExistsW,PathFileExistsW,1118 diff --git a/libc/nt/KernelBase/PathFindExtensionA.s b/libc/nt/KernelBase/PathFindExtensionA.s new file mode 100644 index 00000000..096fdf2c --- /dev/null +++ b/libc/nt/KernelBase/PathFindExtensionA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathFindExtensionA,PathFindExtensionA,1119 diff --git a/libc/nt/KernelBase/PathFindExtensionW.s b/libc/nt/KernelBase/PathFindExtensionW.s new file mode 100644 index 00000000..7d7564ea --- /dev/null +++ b/libc/nt/KernelBase/PathFindExtensionW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathFindExtensionW,PathFindExtensionW,1120 diff --git a/libc/nt/KernelBase/PathFindFileNameA.s b/libc/nt/KernelBase/PathFindFileNameA.s new file mode 100644 index 00000000..1218e9db --- /dev/null +++ b/libc/nt/KernelBase/PathFindFileNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathFindFileNameA,PathFindFileNameA,1121 diff --git a/libc/nt/KernelBase/PathFindFileNameW.s b/libc/nt/KernelBase/PathFindFileNameW.s new file mode 100644 index 00000000..0f67bca5 --- /dev/null +++ b/libc/nt/KernelBase/PathFindFileNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathFindFileNameW,PathFindFileNameW,1122 diff --git a/libc/nt/KernelBase/PathFindNextComponentA.s b/libc/nt/KernelBase/PathFindNextComponentA.s new file mode 100644 index 00000000..786882d2 --- /dev/null +++ b/libc/nt/KernelBase/PathFindNextComponentA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathFindNextComponentA,PathFindNextComponentA,1123 diff --git a/libc/nt/KernelBase/PathFindNextComponentW.s b/libc/nt/KernelBase/PathFindNextComponentW.s new file mode 100644 index 00000000..6ed6f3e4 --- /dev/null +++ b/libc/nt/KernelBase/PathFindNextComponentW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathFindNextComponentW,PathFindNextComponentW,1124 diff --git a/libc/nt/KernelBase/PathGetArgsA.s b/libc/nt/KernelBase/PathGetArgsA.s new file mode 100644 index 00000000..aa9cc454 --- /dev/null +++ b/libc/nt/KernelBase/PathGetArgsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathGetArgsA,PathGetArgsA,1125 diff --git a/libc/nt/KernelBase/PathGetArgsW.s b/libc/nt/KernelBase/PathGetArgsW.s new file mode 100644 index 00000000..a0e99725 --- /dev/null +++ b/libc/nt/KernelBase/PathGetArgsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathGetArgsW,PathGetArgsW,1126 diff --git a/libc/nt/KernelBase/PathGetCharTypeA.s b/libc/nt/KernelBase/PathGetCharTypeA.s new file mode 100644 index 00000000..0b02382d --- /dev/null +++ b/libc/nt/KernelBase/PathGetCharTypeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathGetCharTypeA,PathGetCharTypeA,1127 diff --git a/libc/nt/KernelBase/PathGetCharTypeW.s b/libc/nt/KernelBase/PathGetCharTypeW.s new file mode 100644 index 00000000..249a2b9f --- /dev/null +++ b/libc/nt/KernelBase/PathGetCharTypeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathGetCharTypeW,PathGetCharTypeW,1128 diff --git a/libc/nt/KernelBase/PathGetDriveNumberA.s b/libc/nt/KernelBase/PathGetDriveNumberA.s new file mode 100644 index 00000000..9f6b5e05 --- /dev/null +++ b/libc/nt/KernelBase/PathGetDriveNumberA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathGetDriveNumberA,PathGetDriveNumberA,1129 diff --git a/libc/nt/KernelBase/PathGetDriveNumberW.s b/libc/nt/KernelBase/PathGetDriveNumberW.s new file mode 100644 index 00000000..122677cc --- /dev/null +++ b/libc/nt/KernelBase/PathGetDriveNumberW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathGetDriveNumberW,PathGetDriveNumberW,1130 diff --git a/libc/nt/KernelBase/PathIsFileSpecA.s b/libc/nt/KernelBase/PathIsFileSpecA.s new file mode 100644 index 00000000..43ee464d --- /dev/null +++ b/libc/nt/KernelBase/PathIsFileSpecA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsFileSpecA,PathIsFileSpecA,1131 diff --git a/libc/nt/KernelBase/PathIsFileSpecW.s b/libc/nt/KernelBase/PathIsFileSpecW.s new file mode 100644 index 00000000..eb8c0c9b --- /dev/null +++ b/libc/nt/KernelBase/PathIsFileSpecW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsFileSpecW,PathIsFileSpecW,1132 diff --git a/libc/nt/KernelBase/PathIsLFNFileSpecA.s b/libc/nt/KernelBase/PathIsLFNFileSpecA.s new file mode 100644 index 00000000..a08f4358 --- /dev/null +++ b/libc/nt/KernelBase/PathIsLFNFileSpecA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsLFNFileSpecA,PathIsLFNFileSpecA,1133 diff --git a/libc/nt/KernelBase/PathIsLFNFileSpecW.s b/libc/nt/KernelBase/PathIsLFNFileSpecW.s new file mode 100644 index 00000000..90d328fa --- /dev/null +++ b/libc/nt/KernelBase/PathIsLFNFileSpecW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsLFNFileSpecW,PathIsLFNFileSpecW,1134 diff --git a/libc/nt/KernelBase/PathIsPrefixA.s b/libc/nt/KernelBase/PathIsPrefixA.s new file mode 100644 index 00000000..5a0ae0f0 --- /dev/null +++ b/libc/nt/KernelBase/PathIsPrefixA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsPrefixA,PathIsPrefixA,1135 diff --git a/libc/nt/KernelBase/PathIsPrefixW.s b/libc/nt/KernelBase/PathIsPrefixW.s new file mode 100644 index 00000000..3b15d64b --- /dev/null +++ b/libc/nt/KernelBase/PathIsPrefixW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsPrefixW,PathIsPrefixW,1136 diff --git a/libc/nt/KernelBase/PathIsRelativeA.s b/libc/nt/KernelBase/PathIsRelativeA.s new file mode 100644 index 00000000..9c131192 --- /dev/null +++ b/libc/nt/KernelBase/PathIsRelativeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsRelativeA,PathIsRelativeA,1137 diff --git a/libc/nt/KernelBase/PathIsRelativeW.s b/libc/nt/KernelBase/PathIsRelativeW.s new file mode 100644 index 00000000..3ae43b1e --- /dev/null +++ b/libc/nt/KernelBase/PathIsRelativeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsRelativeW,PathIsRelativeW,1138 diff --git a/libc/nt/KernelBase/PathIsRootA.s b/libc/nt/KernelBase/PathIsRootA.s new file mode 100644 index 00000000..20b19c7e --- /dev/null +++ b/libc/nt/KernelBase/PathIsRootA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsRootA,PathIsRootA,1139 diff --git a/libc/nt/KernelBase/PathIsRootW.s b/libc/nt/KernelBase/PathIsRootW.s new file mode 100644 index 00000000..d5f629df --- /dev/null +++ b/libc/nt/KernelBase/PathIsRootW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsRootW,PathIsRootW,1140 diff --git a/libc/nt/KernelBase/PathIsSameRootA.s b/libc/nt/KernelBase/PathIsSameRootA.s new file mode 100644 index 00000000..3b99850c --- /dev/null +++ b/libc/nt/KernelBase/PathIsSameRootA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsSameRootA,PathIsSameRootA,1141 diff --git a/libc/nt/KernelBase/PathIsSameRootW.s b/libc/nt/KernelBase/PathIsSameRootW.s new file mode 100644 index 00000000..6a02074f --- /dev/null +++ b/libc/nt/KernelBase/PathIsSameRootW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsSameRootW,PathIsSameRootW,1142 diff --git a/libc/nt/KernelBase/PathIsUNCA.s b/libc/nt/KernelBase/PathIsUNCA.s new file mode 100644 index 00000000..6f268aa4 --- /dev/null +++ b/libc/nt/KernelBase/PathIsUNCA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsUNCA,PathIsUNCA,1143 diff --git a/libc/nt/KernelBase/PathIsUNCEx.s b/libc/nt/KernelBase/PathIsUNCEx.s new file mode 100644 index 00000000..4286c074 --- /dev/null +++ b/libc/nt/KernelBase/PathIsUNCEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsUNCEx,PathIsUNCEx,1144 diff --git a/libc/nt/KernelBase/PathIsUNCServerA.s b/libc/nt/KernelBase/PathIsUNCServerA.s new file mode 100644 index 00000000..bc65b54b --- /dev/null +++ b/libc/nt/KernelBase/PathIsUNCServerA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsUNCServerA,PathIsUNCServerA,1145 diff --git a/libc/nt/KernelBase/PathIsUNCServerShareA.s b/libc/nt/KernelBase/PathIsUNCServerShareA.s new file mode 100644 index 00000000..647be475 --- /dev/null +++ b/libc/nt/KernelBase/PathIsUNCServerShareA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsUNCServerShareA,PathIsUNCServerShareA,1146 diff --git a/libc/nt/KernelBase/PathIsUNCServerShareW.s b/libc/nt/KernelBase/PathIsUNCServerShareW.s new file mode 100644 index 00000000..c5079c87 --- /dev/null +++ b/libc/nt/KernelBase/PathIsUNCServerShareW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsUNCServerShareW,PathIsUNCServerShareW,1147 diff --git a/libc/nt/KernelBase/PathIsUNCServerW.s b/libc/nt/KernelBase/PathIsUNCServerW.s new file mode 100644 index 00000000..f63a6f2b --- /dev/null +++ b/libc/nt/KernelBase/PathIsUNCServerW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsUNCServerW,PathIsUNCServerW,1148 diff --git a/libc/nt/KernelBase/PathIsUNCW.s b/libc/nt/KernelBase/PathIsUNCW.s new file mode 100644 index 00000000..8aaeb964 --- /dev/null +++ b/libc/nt/KernelBase/PathIsUNCW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsUNCW,PathIsUNCW,1149 diff --git a/libc/nt/KernelBase/PathIsURLA.s b/libc/nt/KernelBase/PathIsURLA.s new file mode 100644 index 00000000..796cc1c2 --- /dev/null +++ b/libc/nt/KernelBase/PathIsURLA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsURLA,PathIsURLA,1150 diff --git a/libc/nt/KernelBase/PathIsURLW.s b/libc/nt/KernelBase/PathIsURLW.s new file mode 100644 index 00000000..f6ed4ae2 --- /dev/null +++ b/libc/nt/KernelBase/PathIsURLW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsURLW,PathIsURLW,1151 diff --git a/libc/nt/KernelBase/PathIsValidCharA.s b/libc/nt/KernelBase/PathIsValidCharA.s new file mode 100644 index 00000000..4af677dd --- /dev/null +++ b/libc/nt/KernelBase/PathIsValidCharA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsValidCharA,PathIsValidCharA,1152 diff --git a/libc/nt/KernelBase/PathIsValidCharW.s b/libc/nt/KernelBase/PathIsValidCharW.s new file mode 100644 index 00000000..7a77e958 --- /dev/null +++ b/libc/nt/KernelBase/PathIsValidCharW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathIsValidCharW,PathIsValidCharW,1153 diff --git a/libc/nt/KernelBase/PathMatchSpecA.s b/libc/nt/KernelBase/PathMatchSpecA.s new file mode 100644 index 00000000..0e70b5ac --- /dev/null +++ b/libc/nt/KernelBase/PathMatchSpecA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathMatchSpecA,PathMatchSpecA,1154 diff --git a/libc/nt/KernelBase/PathMatchSpecExA.s b/libc/nt/KernelBase/PathMatchSpecExA.s new file mode 100644 index 00000000..0d0318d8 --- /dev/null +++ b/libc/nt/KernelBase/PathMatchSpecExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathMatchSpecExA,PathMatchSpecExA,1155 diff --git a/libc/nt/KernelBase/PathMatchSpecExW.s b/libc/nt/KernelBase/PathMatchSpecExW.s new file mode 100644 index 00000000..aa2d37d2 --- /dev/null +++ b/libc/nt/KernelBase/PathMatchSpecExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathMatchSpecExW,PathMatchSpecExW,1156 diff --git a/libc/nt/KernelBase/PathMatchSpecW.s b/libc/nt/KernelBase/PathMatchSpecW.s new file mode 100644 index 00000000..b0277558 --- /dev/null +++ b/libc/nt/KernelBase/PathMatchSpecW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathMatchSpecW,PathMatchSpecW,1157 diff --git a/libc/nt/KernelBase/PathParseIconLocationA.s b/libc/nt/KernelBase/PathParseIconLocationA.s new file mode 100644 index 00000000..a68b2abe --- /dev/null +++ b/libc/nt/KernelBase/PathParseIconLocationA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathParseIconLocationA,PathParseIconLocationA,1158 diff --git a/libc/nt/KernelBase/PathParseIconLocationW.s b/libc/nt/KernelBase/PathParseIconLocationW.s new file mode 100644 index 00000000..cad201b5 --- /dev/null +++ b/libc/nt/KernelBase/PathParseIconLocationW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathParseIconLocationW,PathParseIconLocationW,1159 diff --git a/libc/nt/KernelBase/PathQuoteSpacesA.s b/libc/nt/KernelBase/PathQuoteSpacesA.s new file mode 100644 index 00000000..a61a5cad --- /dev/null +++ b/libc/nt/KernelBase/PathQuoteSpacesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathQuoteSpacesA,PathQuoteSpacesA,1160 diff --git a/libc/nt/KernelBase/PathQuoteSpacesW.s b/libc/nt/KernelBase/PathQuoteSpacesW.s new file mode 100644 index 00000000..2be89495 --- /dev/null +++ b/libc/nt/KernelBase/PathQuoteSpacesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathQuoteSpacesW,PathQuoteSpacesW,1161 diff --git a/libc/nt/KernelBase/PathRelativePathToA.s b/libc/nt/KernelBase/PathRelativePathToA.s new file mode 100644 index 00000000..07eefc9e --- /dev/null +++ b/libc/nt/KernelBase/PathRelativePathToA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathRelativePathToA,PathRelativePathToA,1162 diff --git a/libc/nt/KernelBase/PathRelativePathToW.s b/libc/nt/KernelBase/PathRelativePathToW.s new file mode 100644 index 00000000..21c58a53 --- /dev/null +++ b/libc/nt/KernelBase/PathRelativePathToW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathRelativePathToW,PathRelativePathToW,1163 diff --git a/libc/nt/KernelBase/PathRemoveBackslashA.s b/libc/nt/KernelBase/PathRemoveBackslashA.s new file mode 100644 index 00000000..7b368169 --- /dev/null +++ b/libc/nt/KernelBase/PathRemoveBackslashA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathRemoveBackslashA,PathRemoveBackslashA,1164 diff --git a/libc/nt/KernelBase/PathRemoveBackslashW.s b/libc/nt/KernelBase/PathRemoveBackslashW.s new file mode 100644 index 00000000..25a626fd --- /dev/null +++ b/libc/nt/KernelBase/PathRemoveBackslashW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathRemoveBackslashW,PathRemoveBackslashW,1165 diff --git a/libc/nt/KernelBase/PathRemoveBlanksA.s b/libc/nt/KernelBase/PathRemoveBlanksA.s new file mode 100644 index 00000000..ed8b2e68 --- /dev/null +++ b/libc/nt/KernelBase/PathRemoveBlanksA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathRemoveBlanksA,PathRemoveBlanksA,1166 diff --git a/libc/nt/KernelBase/PathRemoveBlanksW.s b/libc/nt/KernelBase/PathRemoveBlanksW.s new file mode 100644 index 00000000..2e96ec69 --- /dev/null +++ b/libc/nt/KernelBase/PathRemoveBlanksW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathRemoveBlanksW,PathRemoveBlanksW,1167 diff --git a/libc/nt/KernelBase/PathRemoveExtensionA.s b/libc/nt/KernelBase/PathRemoveExtensionA.s new file mode 100644 index 00000000..d1991783 --- /dev/null +++ b/libc/nt/KernelBase/PathRemoveExtensionA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathRemoveExtensionA,PathRemoveExtensionA,1168 diff --git a/libc/nt/KernelBase/PathRemoveExtensionW.s b/libc/nt/KernelBase/PathRemoveExtensionW.s new file mode 100644 index 00000000..4ab59ed0 --- /dev/null +++ b/libc/nt/KernelBase/PathRemoveExtensionW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathRemoveExtensionW,PathRemoveExtensionW,1169 diff --git a/libc/nt/KernelBase/PathRemoveFileSpecA.s b/libc/nt/KernelBase/PathRemoveFileSpecA.s new file mode 100644 index 00000000..e967db1f --- /dev/null +++ b/libc/nt/KernelBase/PathRemoveFileSpecA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathRemoveFileSpecA,PathRemoveFileSpecA,1170 diff --git a/libc/nt/KernelBase/PathRemoveFileSpecW.s b/libc/nt/KernelBase/PathRemoveFileSpecW.s new file mode 100644 index 00000000..1d159123 --- /dev/null +++ b/libc/nt/KernelBase/PathRemoveFileSpecW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathRemoveFileSpecW,PathRemoveFileSpecW,1171 diff --git a/libc/nt/KernelBase/PathRenameExtensionA.s b/libc/nt/KernelBase/PathRenameExtensionA.s new file mode 100644 index 00000000..388887d6 --- /dev/null +++ b/libc/nt/KernelBase/PathRenameExtensionA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathRenameExtensionA,PathRenameExtensionA,1172 diff --git a/libc/nt/KernelBase/PathRenameExtensionW.s b/libc/nt/KernelBase/PathRenameExtensionW.s new file mode 100644 index 00000000..d4cd80e7 --- /dev/null +++ b/libc/nt/KernelBase/PathRenameExtensionW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathRenameExtensionW,PathRenameExtensionW,1173 diff --git a/libc/nt/KernelBase/PathSearchAndQualifyA.s b/libc/nt/KernelBase/PathSearchAndQualifyA.s new file mode 100644 index 00000000..91b44164 --- /dev/null +++ b/libc/nt/KernelBase/PathSearchAndQualifyA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathSearchAndQualifyA,PathSearchAndQualifyA,1174 diff --git a/libc/nt/KernelBase/PathSearchAndQualifyW.s b/libc/nt/KernelBase/PathSearchAndQualifyW.s new file mode 100644 index 00000000..dd7ba88a --- /dev/null +++ b/libc/nt/KernelBase/PathSearchAndQualifyW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathSearchAndQualifyW,PathSearchAndQualifyW,1175 diff --git a/libc/nt/KernelBase/PathSkipRootA.s b/libc/nt/KernelBase/PathSkipRootA.s new file mode 100644 index 00000000..6ef50ea4 --- /dev/null +++ b/libc/nt/KernelBase/PathSkipRootA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathSkipRootA,PathSkipRootA,1176 diff --git a/libc/nt/KernelBase/PathSkipRootW.s b/libc/nt/KernelBase/PathSkipRootW.s new file mode 100644 index 00000000..69425790 --- /dev/null +++ b/libc/nt/KernelBase/PathSkipRootW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathSkipRootW,PathSkipRootW,1177 diff --git a/libc/nt/KernelBase/PathStripPathA.s b/libc/nt/KernelBase/PathStripPathA.s new file mode 100644 index 00000000..fba21964 --- /dev/null +++ b/libc/nt/KernelBase/PathStripPathA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathStripPathA,PathStripPathA,1178 diff --git a/libc/nt/KernelBase/PathStripPathW.s b/libc/nt/KernelBase/PathStripPathW.s new file mode 100644 index 00000000..d86d16f4 --- /dev/null +++ b/libc/nt/KernelBase/PathStripPathW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathStripPathW,PathStripPathW,1179 diff --git a/libc/nt/KernelBase/PathStripToRootA.s b/libc/nt/KernelBase/PathStripToRootA.s new file mode 100644 index 00000000..24735133 --- /dev/null +++ b/libc/nt/KernelBase/PathStripToRootA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathStripToRootA,PathStripToRootA,1180 diff --git a/libc/nt/KernelBase/PathStripToRootW.s b/libc/nt/KernelBase/PathStripToRootW.s new file mode 100644 index 00000000..daa050b8 --- /dev/null +++ b/libc/nt/KernelBase/PathStripToRootW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathStripToRootW,PathStripToRootW,1181 diff --git a/libc/nt/KernelBase/PathUnExpandEnvStringsA.s b/libc/nt/KernelBase/PathUnExpandEnvStringsA.s new file mode 100644 index 00000000..7b8a6ce3 --- /dev/null +++ b/libc/nt/KernelBase/PathUnExpandEnvStringsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathUnExpandEnvStringsA,PathUnExpandEnvStringsA,1182 diff --git a/libc/nt/KernelBase/PathUnExpandEnvStringsW.s b/libc/nt/KernelBase/PathUnExpandEnvStringsW.s new file mode 100644 index 00000000..92671021 --- /dev/null +++ b/libc/nt/KernelBase/PathUnExpandEnvStringsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathUnExpandEnvStringsW,PathUnExpandEnvStringsW,1183 diff --git a/libc/nt/KernelBase/PathUnquoteSpacesA.s b/libc/nt/KernelBase/PathUnquoteSpacesA.s new file mode 100644 index 00000000..8739bba9 --- /dev/null +++ b/libc/nt/KernelBase/PathUnquoteSpacesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathUnquoteSpacesA,PathUnquoteSpacesA,1184 diff --git a/libc/nt/KernelBase/PathUnquoteSpacesW.s b/libc/nt/KernelBase/PathUnquoteSpacesW.s new file mode 100644 index 00000000..ff74d4b6 --- /dev/null +++ b/libc/nt/KernelBase/PathUnquoteSpacesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PathUnquoteSpacesW,PathUnquoteSpacesW,1185 diff --git a/libc/nt/KernelBase/PcwAddQueryItem.s b/libc/nt/KernelBase/PcwAddQueryItem.s new file mode 100644 index 00000000..c04ada90 --- /dev/null +++ b/libc/nt/KernelBase/PcwAddQueryItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PcwAddQueryItem,PcwAddQueryItem,1186 diff --git a/libc/nt/KernelBase/PcwClearCounterSetSecurity.s b/libc/nt/KernelBase/PcwClearCounterSetSecurity.s new file mode 100644 index 00000000..d25c6f17 --- /dev/null +++ b/libc/nt/KernelBase/PcwClearCounterSetSecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PcwClearCounterSetSecurity,PcwClearCounterSetSecurity,1187 diff --git a/libc/nt/KernelBase/PcwCollectData.s b/libc/nt/KernelBase/PcwCollectData.s new file mode 100644 index 00000000..0e8e9820 --- /dev/null +++ b/libc/nt/KernelBase/PcwCollectData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PcwCollectData,PcwCollectData,1188 diff --git a/libc/nt/KernelBase/PcwCompleteNotification.s b/libc/nt/KernelBase/PcwCompleteNotification.s new file mode 100644 index 00000000..7f81cd02 --- /dev/null +++ b/libc/nt/KernelBase/PcwCompleteNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PcwCompleteNotification,PcwCompleteNotification,1189 diff --git a/libc/nt/KernelBase/PcwCreateNotifier.s b/libc/nt/KernelBase/PcwCreateNotifier.s new file mode 100644 index 00000000..0ea46e4f --- /dev/null +++ b/libc/nt/KernelBase/PcwCreateNotifier.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PcwCreateNotifier,PcwCreateNotifier,1190 diff --git a/libc/nt/KernelBase/PcwCreateQuery.s b/libc/nt/KernelBase/PcwCreateQuery.s new file mode 100644 index 00000000..e4ac67a1 --- /dev/null +++ b/libc/nt/KernelBase/PcwCreateQuery.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PcwCreateQuery,PcwCreateQuery,1191 diff --git a/libc/nt/KernelBase/PcwDisconnectCounterSet.s b/libc/nt/KernelBase/PcwDisconnectCounterSet.s new file mode 100644 index 00000000..d6bca143 --- /dev/null +++ b/libc/nt/KernelBase/PcwDisconnectCounterSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PcwDisconnectCounterSet,PcwDisconnectCounterSet,1192 diff --git a/libc/nt/KernelBase/PcwEnumerateInstances.s b/libc/nt/KernelBase/PcwEnumerateInstances.s new file mode 100644 index 00000000..0e591f4a --- /dev/null +++ b/libc/nt/KernelBase/PcwEnumerateInstances.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PcwEnumerateInstances,PcwEnumerateInstances,1193 diff --git a/libc/nt/KernelBase/PcwIsNotifierAlive.s b/libc/nt/KernelBase/PcwIsNotifierAlive.s new file mode 100644 index 00000000..178b7444 --- /dev/null +++ b/libc/nt/KernelBase/PcwIsNotifierAlive.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PcwIsNotifierAlive,PcwIsNotifierAlive,1194 diff --git a/libc/nt/KernelBase/PcwQueryCounterSetSecurity.s b/libc/nt/KernelBase/PcwQueryCounterSetSecurity.s new file mode 100644 index 00000000..916545d4 --- /dev/null +++ b/libc/nt/KernelBase/PcwQueryCounterSetSecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PcwQueryCounterSetSecurity,PcwQueryCounterSetSecurity,1195 diff --git a/libc/nt/KernelBase/PcwReadNotificationData.s b/libc/nt/KernelBase/PcwReadNotificationData.s new file mode 100644 index 00000000..761c5944 --- /dev/null +++ b/libc/nt/KernelBase/PcwReadNotificationData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PcwReadNotificationData,PcwReadNotificationData,1196 diff --git a/libc/nt/KernelBase/PcwRegisterCounterSet.s b/libc/nt/KernelBase/PcwRegisterCounterSet.s new file mode 100644 index 00000000..7b602ce6 --- /dev/null +++ b/libc/nt/KernelBase/PcwRegisterCounterSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PcwRegisterCounterSet,PcwRegisterCounterSet,1197 diff --git a/libc/nt/KernelBase/PcwRemoveQueryItem.s b/libc/nt/KernelBase/PcwRemoveQueryItem.s new file mode 100644 index 00000000..e51462c7 --- /dev/null +++ b/libc/nt/KernelBase/PcwRemoveQueryItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PcwRemoveQueryItem,PcwRemoveQueryItem,1198 diff --git a/libc/nt/KernelBase/PcwSendNotification.s b/libc/nt/KernelBase/PcwSendNotification.s new file mode 100644 index 00000000..d560fa2b --- /dev/null +++ b/libc/nt/KernelBase/PcwSendNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PcwSendNotification,PcwSendNotification,1199 diff --git a/libc/nt/KernelBase/PcwSendStatelessNotification.s b/libc/nt/KernelBase/PcwSendStatelessNotification.s new file mode 100644 index 00000000..b4ad274b --- /dev/null +++ b/libc/nt/KernelBase/PcwSendStatelessNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PcwSendStatelessNotification,PcwSendStatelessNotification,1200 diff --git a/libc/nt/KernelBase/PcwSetCounterSetSecurity.s b/libc/nt/KernelBase/PcwSetCounterSetSecurity.s new file mode 100644 index 00000000..815d7913 --- /dev/null +++ b/libc/nt/KernelBase/PcwSetCounterSetSecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PcwSetCounterSetSecurity,PcwSetCounterSetSecurity,1201 diff --git a/libc/nt/KernelBase/PcwSetQueryItemUserData.s b/libc/nt/KernelBase/PcwSetQueryItemUserData.s new file mode 100644 index 00000000..36171530 --- /dev/null +++ b/libc/nt/KernelBase/PcwSetQueryItemUserData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PcwSetQueryItemUserData,PcwSetQueryItemUserData,1202 diff --git a/libc/nt/KernelBase/PeekConsoleInputA.s b/libc/nt/KernelBase/PeekConsoleInputA.s new file mode 100644 index 00000000..8ec47107 --- /dev/null +++ b/libc/nt/KernelBase/PeekConsoleInputA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PeekConsoleInputA,PeekConsoleInputA,1203 + + .text.windows +PeekConsoleInputA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_PeekConsoleInputA(%rip),%rax + jmp __sysv2nt + .endfn PeekConsoleInputA,globl + .previous diff --git a/libc/nt/KernelBase/PeekConsoleInputW.s b/libc/nt/KernelBase/PeekConsoleInputW.s new file mode 100644 index 00000000..9093409d --- /dev/null +++ b/libc/nt/KernelBase/PeekConsoleInputW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PeekConsoleInputW,PeekConsoleInputW,1204 + + .text.windows +PeekConsoleInput: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_PeekConsoleInputW(%rip),%rax + jmp __sysv2nt + .endfn PeekConsoleInput,globl + .previous diff --git a/libc/nt/KernelBase/PeekNamedPipe.s b/libc/nt/KernelBase/PeekNamedPipe.s new file mode 100644 index 00000000..b6bbacc5 --- /dev/null +++ b/libc/nt/KernelBase/PeekNamedPipe.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PeekNamedPipe,PeekNamedPipe,1205 + + .text.windows +PeekNamedPipe: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_PeekNamedPipe(%rip),%rax + jmp __sysv2nt6 + .endfn PeekNamedPipe,globl + .previous diff --git a/libc/nt/KernelBase/PerfCreateInstance.s b/libc/nt/KernelBase/PerfCreateInstance.s new file mode 100644 index 00000000..c7d29e75 --- /dev/null +++ b/libc/nt/KernelBase/PerfCreateInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PerfCreateInstance,PerfCreateInstance,1206 diff --git a/libc/nt/KernelBase/PerfDecrementULongCounterValue.s b/libc/nt/KernelBase/PerfDecrementULongCounterValue.s new file mode 100644 index 00000000..a50bc835 --- /dev/null +++ b/libc/nt/KernelBase/PerfDecrementULongCounterValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PerfDecrementULongCounterValue,PerfDecrementULongCounterValue,1207 diff --git a/libc/nt/KernelBase/PerfDecrementULongLongCounterValue.s b/libc/nt/KernelBase/PerfDecrementULongLongCounterValue.s new file mode 100644 index 00000000..8587d956 --- /dev/null +++ b/libc/nt/KernelBase/PerfDecrementULongLongCounterValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PerfDecrementULongLongCounterValue,PerfDecrementULongLongCounterValue,1208 diff --git a/libc/nt/KernelBase/PerfDeleteInstance.s b/libc/nt/KernelBase/PerfDeleteInstance.s new file mode 100644 index 00000000..bbaca64e --- /dev/null +++ b/libc/nt/KernelBase/PerfDeleteInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PerfDeleteInstance,PerfDeleteInstance,1209 diff --git a/libc/nt/KernelBase/PerfIncrementULongCounterValue.s b/libc/nt/KernelBase/PerfIncrementULongCounterValue.s new file mode 100644 index 00000000..f5baf6e2 --- /dev/null +++ b/libc/nt/KernelBase/PerfIncrementULongCounterValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PerfIncrementULongCounterValue,PerfIncrementULongCounterValue,1210 diff --git a/libc/nt/KernelBase/PerfIncrementULongLongCounterValue.s b/libc/nt/KernelBase/PerfIncrementULongLongCounterValue.s new file mode 100644 index 00000000..de9fcf01 --- /dev/null +++ b/libc/nt/KernelBase/PerfIncrementULongLongCounterValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PerfIncrementULongLongCounterValue,PerfIncrementULongLongCounterValue,1211 diff --git a/libc/nt/KernelBase/PerfQueryInstance.s b/libc/nt/KernelBase/PerfQueryInstance.s new file mode 100644 index 00000000..2513a52c --- /dev/null +++ b/libc/nt/KernelBase/PerfQueryInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PerfQueryInstance,PerfQueryInstance,1212 diff --git a/libc/nt/KernelBase/PerfSetCounterRefValue.s b/libc/nt/KernelBase/PerfSetCounterRefValue.s new file mode 100644 index 00000000..0a145a3d --- /dev/null +++ b/libc/nt/KernelBase/PerfSetCounterRefValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PerfSetCounterRefValue,PerfSetCounterRefValue,1213 diff --git a/libc/nt/KernelBase/PerfSetCounterSetInfo.s b/libc/nt/KernelBase/PerfSetCounterSetInfo.s new file mode 100644 index 00000000..d43000b1 --- /dev/null +++ b/libc/nt/KernelBase/PerfSetCounterSetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PerfSetCounterSetInfo,PerfSetCounterSetInfo,1214 diff --git a/libc/nt/KernelBase/PerfSetULongCounterValue.s b/libc/nt/KernelBase/PerfSetULongCounterValue.s new file mode 100644 index 00000000..10d9fc7e --- /dev/null +++ b/libc/nt/KernelBase/PerfSetULongCounterValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PerfSetULongCounterValue,PerfSetULongCounterValue,1215 diff --git a/libc/nt/KernelBase/PerfSetULongLongCounterValue.s b/libc/nt/KernelBase/PerfSetULongLongCounterValue.s new file mode 100644 index 00000000..ed2c342a --- /dev/null +++ b/libc/nt/KernelBase/PerfSetULongLongCounterValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PerfSetULongLongCounterValue,PerfSetULongLongCounterValue,1216 diff --git a/libc/nt/KernelBase/PerfStartProvider.s b/libc/nt/KernelBase/PerfStartProvider.s new file mode 100644 index 00000000..32add48c --- /dev/null +++ b/libc/nt/KernelBase/PerfStartProvider.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PerfStartProvider,PerfStartProvider,1217 diff --git a/libc/nt/KernelBase/PerfStartProviderEx.s b/libc/nt/KernelBase/PerfStartProviderEx.s new file mode 100644 index 00000000..05d3d58c --- /dev/null +++ b/libc/nt/KernelBase/PerfStartProviderEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PerfStartProviderEx,PerfStartProviderEx,1218 diff --git a/libc/nt/KernelBase/PerfStopProvider.s b/libc/nt/KernelBase/PerfStopProvider.s new file mode 100644 index 00000000..8c0ee652 --- /dev/null +++ b/libc/nt/KernelBase/PerfStopProvider.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PerfStopProvider,PerfStopProvider,1219 diff --git a/libc/nt/KernelBase/PoolPerAppKeyStateInternal.s b/libc/nt/KernelBase/PoolPerAppKeyStateInternal.s new file mode 100644 index 00000000..ccf4ce65 --- /dev/null +++ b/libc/nt/KernelBase/PoolPerAppKeyStateInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PoolPerAppKeyStateInternal,PoolPerAppKeyStateInternal,1220 diff --git a/libc/nt/KernelBase/PostQueuedCompletionStatus.s b/libc/nt/KernelBase/PostQueuedCompletionStatus.s new file mode 100644 index 00000000..6584c832 --- /dev/null +++ b/libc/nt/KernelBase/PostQueuedCompletionStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PostQueuedCompletionStatus,PostQueuedCompletionStatus,1221 diff --git a/libc/nt/KernelBase/PrefetchVirtualMemory.s b/libc/nt/KernelBase/PrefetchVirtualMemory.s new file mode 100644 index 00000000..38cf19fb --- /dev/null +++ b/libc/nt/KernelBase/PrefetchVirtualMemory.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PrefetchVirtualMemory,PrefetchVirtualMemory,1222 + + .text.windows +PrefetchVirtualMemory: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_PrefetchVirtualMemory(%rip),%rax + jmp __sysv2nt + .endfn PrefetchVirtualMemory,globl + .previous diff --git a/libc/nt/KernelBase/PrivCopyFileExW.s b/libc/nt/KernelBase/PrivCopyFileExW.s new file mode 100644 index 00000000..e2336dca --- /dev/null +++ b/libc/nt/KernelBase/PrivCopyFileExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PrivCopyFileExW,PrivCopyFileExW,1223 diff --git a/libc/nt/KernelBase/PrivilegeCheck.s b/libc/nt/KernelBase/PrivilegeCheck.s new file mode 100644 index 00000000..03e1795b --- /dev/null +++ b/libc/nt/KernelBase/PrivilegeCheck.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PrivilegeCheck,PrivilegeCheck,1224 diff --git a/libc/nt/KernelBase/PrivilegedServiceAuditAlarmW.s b/libc/nt/KernelBase/PrivilegedServiceAuditAlarmW.s new file mode 100644 index 00000000..22ef867b --- /dev/null +++ b/libc/nt/KernelBase/PrivilegedServiceAuditAlarmW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PrivilegedServiceAuditAlarmW,PrivilegedServiceAuditAlarmW,1225 diff --git a/libc/nt/KernelBase/ProcessIdToSessionId.s b/libc/nt/KernelBase/ProcessIdToSessionId.s new file mode 100644 index 00000000..c9aa4756 --- /dev/null +++ b/libc/nt/KernelBase/ProcessIdToSessionId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ProcessIdToSessionId,ProcessIdToSessionId,1226 diff --git a/libc/nt/KernelBase/ProductIdFromPackageFamilyName.s b/libc/nt/KernelBase/ProductIdFromPackageFamilyName.s new file mode 100644 index 00000000..b230f29f --- /dev/null +++ b/libc/nt/KernelBase/ProductIdFromPackageFamilyName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ProductIdFromPackageFamilyName,ProductIdFromPackageFamilyName,1227 diff --git a/libc/nt/KernelBase/PsmCreateKey.s b/libc/nt/KernelBase/PsmCreateKey.s new file mode 100644 index 00000000..7c668abf --- /dev/null +++ b/libc/nt/KernelBase/PsmCreateKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PsmCreateKey,PsmCreateKey,1228 diff --git a/libc/nt/KernelBase/PsmCreateKeyWithDynamicId.s b/libc/nt/KernelBase/PsmCreateKeyWithDynamicId.s new file mode 100644 index 00000000..f095da7b --- /dev/null +++ b/libc/nt/KernelBase/PsmCreateKeyWithDynamicId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PsmCreateKeyWithDynamicId,PsmCreateKeyWithDynamicId,1229 diff --git a/libc/nt/KernelBase/PsmEqualApplication.s b/libc/nt/KernelBase/PsmEqualApplication.s new file mode 100644 index 00000000..77148802 --- /dev/null +++ b/libc/nt/KernelBase/PsmEqualApplication.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PsmEqualApplication,PsmEqualApplication,1230 diff --git a/libc/nt/KernelBase/PsmEqualPackage.s b/libc/nt/KernelBase/PsmEqualPackage.s new file mode 100644 index 00000000..4932841c --- /dev/null +++ b/libc/nt/KernelBase/PsmEqualPackage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PsmEqualPackage,PsmEqualPackage,1231 diff --git a/libc/nt/KernelBase/PsmGetApplicationNameFromKey.s b/libc/nt/KernelBase/PsmGetApplicationNameFromKey.s new file mode 100644 index 00000000..c0267689 --- /dev/null +++ b/libc/nt/KernelBase/PsmGetApplicationNameFromKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PsmGetApplicationNameFromKey,PsmGetApplicationNameFromKey,1232 diff --git a/libc/nt/KernelBase/PsmGetKeyFromProcess.s b/libc/nt/KernelBase/PsmGetKeyFromProcess.s new file mode 100644 index 00000000..9640380f --- /dev/null +++ b/libc/nt/KernelBase/PsmGetKeyFromProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PsmGetKeyFromProcess,PsmGetKeyFromProcess,1233 diff --git a/libc/nt/KernelBase/PsmGetKeyFromToken.s b/libc/nt/KernelBase/PsmGetKeyFromToken.s new file mode 100644 index 00000000..4b2b6865 --- /dev/null +++ b/libc/nt/KernelBase/PsmGetKeyFromToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PsmGetKeyFromToken,PsmGetKeyFromToken,1234 diff --git a/libc/nt/KernelBase/PsmGetPackageFullNameFromKey.s b/libc/nt/KernelBase/PsmGetPackageFullNameFromKey.s new file mode 100644 index 00000000..b5501481 --- /dev/null +++ b/libc/nt/KernelBase/PsmGetPackageFullNameFromKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PsmGetPackageFullNameFromKey,PsmGetPackageFullNameFromKey,1235 diff --git a/libc/nt/KernelBase/PsmIsChildKey.s b/libc/nt/KernelBase/PsmIsChildKey.s new file mode 100644 index 00000000..6ceb5805 --- /dev/null +++ b/libc/nt/KernelBase/PsmIsChildKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PsmIsChildKey,PsmIsChildKey,1236 diff --git a/libc/nt/KernelBase/PsmIsDynamicKey.s b/libc/nt/KernelBase/PsmIsDynamicKey.s new file mode 100644 index 00000000..a8eb81d4 --- /dev/null +++ b/libc/nt/KernelBase/PsmIsDynamicKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PsmIsDynamicKey,PsmIsDynamicKey,1237 diff --git a/libc/nt/KernelBase/PsmIsValidKey.s b/libc/nt/KernelBase/PsmIsValidKey.s new file mode 100644 index 00000000..4b52df27 --- /dev/null +++ b/libc/nt/KernelBase/PsmIsValidKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PsmIsValidKey,PsmIsValidKey,1238 diff --git a/libc/nt/KernelBase/PssCaptureSnapshot.s b/libc/nt/KernelBase/PssCaptureSnapshot.s new file mode 100644 index 00000000..4e5bc98a --- /dev/null +++ b/libc/nt/KernelBase/PssCaptureSnapshot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PssCaptureSnapshot,PssCaptureSnapshot,1239 diff --git a/libc/nt/KernelBase/PssDuplicateSnapshot.s b/libc/nt/KernelBase/PssDuplicateSnapshot.s new file mode 100644 index 00000000..6eb5600b --- /dev/null +++ b/libc/nt/KernelBase/PssDuplicateSnapshot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PssDuplicateSnapshot,PssDuplicateSnapshot,1240 diff --git a/libc/nt/KernelBase/PssFreeSnapshot.s b/libc/nt/KernelBase/PssFreeSnapshot.s new file mode 100644 index 00000000..57b341d5 --- /dev/null +++ b/libc/nt/KernelBase/PssFreeSnapshot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PssFreeSnapshot,PssFreeSnapshot,1241 diff --git a/libc/nt/KernelBase/PssQuerySnapshot.s b/libc/nt/KernelBase/PssQuerySnapshot.s new file mode 100644 index 00000000..79d1ab55 --- /dev/null +++ b/libc/nt/KernelBase/PssQuerySnapshot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PssQuerySnapshot,PssQuerySnapshot,1242 diff --git a/libc/nt/KernelBase/PssWalkMarkerCreate.s b/libc/nt/KernelBase/PssWalkMarkerCreate.s new file mode 100644 index 00000000..cf739cab --- /dev/null +++ b/libc/nt/KernelBase/PssWalkMarkerCreate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PssWalkMarkerCreate,PssWalkMarkerCreate,1243 diff --git a/libc/nt/KernelBase/PssWalkMarkerFree.s b/libc/nt/KernelBase/PssWalkMarkerFree.s new file mode 100644 index 00000000..ebe4c044 --- /dev/null +++ b/libc/nt/KernelBase/PssWalkMarkerFree.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PssWalkMarkerFree,PssWalkMarkerFree,1244 diff --git a/libc/nt/KernelBase/PssWalkMarkerGetPosition.s b/libc/nt/KernelBase/PssWalkMarkerGetPosition.s new file mode 100644 index 00000000..11a5acb3 --- /dev/null +++ b/libc/nt/KernelBase/PssWalkMarkerGetPosition.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PssWalkMarkerGetPosition,PssWalkMarkerGetPosition,1245 diff --git a/libc/nt/KernelBase/PssWalkMarkerSeekToBeginning.s b/libc/nt/KernelBase/PssWalkMarkerSeekToBeginning.s new file mode 100644 index 00000000..155f748a --- /dev/null +++ b/libc/nt/KernelBase/PssWalkMarkerSeekToBeginning.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PssWalkMarkerSeekToBeginning,PssWalkMarkerSeekToBeginning,1246 diff --git a/libc/nt/KernelBase/PssWalkMarkerSetPosition.s b/libc/nt/KernelBase/PssWalkMarkerSetPosition.s new file mode 100644 index 00000000..79fa7f1a --- /dev/null +++ b/libc/nt/KernelBase/PssWalkMarkerSetPosition.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PssWalkMarkerSetPosition,PssWalkMarkerSetPosition,1247 diff --git a/libc/nt/KernelBase/PssWalkSnapshot.s b/libc/nt/KernelBase/PssWalkSnapshot.s new file mode 100644 index 00000000..95cd66a4 --- /dev/null +++ b/libc/nt/KernelBase/PssWalkSnapshot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PssWalkSnapshot,PssWalkSnapshot,1248 diff --git a/libc/nt/KernelBase/PublishStateChangeNotification.s b/libc/nt/KernelBase/PublishStateChangeNotification.s new file mode 100644 index 00000000..4a133308 --- /dev/null +++ b/libc/nt/KernelBase/PublishStateChangeNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PublishStateChangeNotification,PublishStateChangeNotification,1249 diff --git a/libc/nt/KernelBase/PulseEvent.s b/libc/nt/KernelBase/PulseEvent.s new file mode 100644 index 00000000..54f2bf33 --- /dev/null +++ b/libc/nt/KernelBase/PulseEvent.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PulseEvent,PulseEvent,1250 + + .text.windows +PulseEvent: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_PulseEvent(%rip) + leave + ret + .endfn PulseEvent,globl + .previous diff --git a/libc/nt/KernelBase/PurgeComm.s b/libc/nt/KernelBase/PurgeComm.s new file mode 100644 index 00000000..b2f2910a --- /dev/null +++ b/libc/nt/KernelBase/PurgeComm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_PurgeComm,PurgeComm,1251 diff --git a/libc/nt/KernelBase/QISearch.s b/libc/nt/KernelBase/QISearch.s new file mode 100644 index 00000000..4d6f5043 --- /dev/null +++ b/libc/nt/KernelBase/QISearch.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QISearch,QISearch,1252 diff --git a/libc/nt/KernelBase/QueryActCtxSettingsW.s b/libc/nt/KernelBase/QueryActCtxSettingsW.s new file mode 100644 index 00000000..19f266a5 --- /dev/null +++ b/libc/nt/KernelBase/QueryActCtxSettingsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryActCtxSettingsW,QueryActCtxSettingsW,1253 diff --git a/libc/nt/KernelBase/QueryActCtxW.s b/libc/nt/KernelBase/QueryActCtxW.s new file mode 100644 index 00000000..c458c47c --- /dev/null +++ b/libc/nt/KernelBase/QueryActCtxW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryActCtxW,QueryActCtxW,1254 diff --git a/libc/nt/KernelBase/QueryAuxiliaryCounterFrequency.s b/libc/nt/KernelBase/QueryAuxiliaryCounterFrequency.s new file mode 100644 index 00000000..3b0fc912 --- /dev/null +++ b/libc/nt/KernelBase/QueryAuxiliaryCounterFrequency.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryAuxiliaryCounterFrequency,QueryAuxiliaryCounterFrequency,1255 diff --git a/libc/nt/KernelBase/QueryDosDeviceW.s b/libc/nt/KernelBase/QueryDosDeviceW.s new file mode 100644 index 00000000..68933f33 --- /dev/null +++ b/libc/nt/KernelBase/QueryDosDeviceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryDosDeviceW,QueryDosDeviceW,1257 diff --git a/libc/nt/KernelBase/QueryFullProcessImageNameA.s b/libc/nt/KernelBase/QueryFullProcessImageNameA.s new file mode 100644 index 00000000..1e92b23f --- /dev/null +++ b/libc/nt/KernelBase/QueryFullProcessImageNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryFullProcessImageNameA,QueryFullProcessImageNameA,1258 diff --git a/libc/nt/KernelBase/QueryFullProcessImageNameW.s b/libc/nt/KernelBase/QueryFullProcessImageNameW.s new file mode 100644 index 00000000..8d663ae7 --- /dev/null +++ b/libc/nt/KernelBase/QueryFullProcessImageNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryFullProcessImageNameW,QueryFullProcessImageNameW,1259 diff --git a/libc/nt/KernelBase/QueryIdleProcessorCycleTime.s b/libc/nt/KernelBase/QueryIdleProcessorCycleTime.s new file mode 100644 index 00000000..6fb29788 --- /dev/null +++ b/libc/nt/KernelBase/QueryIdleProcessorCycleTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryIdleProcessorCycleTime,QueryIdleProcessorCycleTime,1260 diff --git a/libc/nt/KernelBase/QueryIdleProcessorCycleTimeEx.s b/libc/nt/KernelBase/QueryIdleProcessorCycleTimeEx.s new file mode 100644 index 00000000..c45a3724 --- /dev/null +++ b/libc/nt/KernelBase/QueryIdleProcessorCycleTimeEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryIdleProcessorCycleTimeEx,QueryIdleProcessorCycleTimeEx,1261 diff --git a/libc/nt/KernelBase/QueryInterruptTime.s b/libc/nt/KernelBase/QueryInterruptTime.s new file mode 100644 index 00000000..f0ca82fa --- /dev/null +++ b/libc/nt/KernelBase/QueryInterruptTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryInterruptTime,QueryInterruptTime,1262 diff --git a/libc/nt/KernelBase/QueryInterruptTimePrecise.s b/libc/nt/KernelBase/QueryInterruptTimePrecise.s new file mode 100644 index 00000000..a6435a9f --- /dev/null +++ b/libc/nt/KernelBase/QueryInterruptTimePrecise.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryInterruptTimePrecise,QueryInterruptTimePrecise,1263 diff --git a/libc/nt/KernelBase/QueryMemoryResourceNotification.s b/libc/nt/KernelBase/QueryMemoryResourceNotification.s new file mode 100644 index 00000000..b4f137fd --- /dev/null +++ b/libc/nt/KernelBase/QueryMemoryResourceNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryMemoryResourceNotification,QueryMemoryResourceNotification,1264 diff --git a/libc/nt/KernelBase/QueryOptionalDelayLoadedAPI.s b/libc/nt/KernelBase/QueryOptionalDelayLoadedAPI.s new file mode 100644 index 00000000..01487246 --- /dev/null +++ b/libc/nt/KernelBase/QueryOptionalDelayLoadedAPI.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryOptionalDelayLoadedAPI,QueryOptionalDelayLoadedAPI,1265 diff --git a/libc/nt/KernelBase/QueryProcessAffinityUpdateMode.s b/libc/nt/KernelBase/QueryProcessAffinityUpdateMode.s new file mode 100644 index 00000000..8bd7b771 --- /dev/null +++ b/libc/nt/KernelBase/QueryProcessAffinityUpdateMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryProcessAffinityUpdateMode,QueryProcessAffinityUpdateMode,1268 diff --git a/libc/nt/KernelBase/QueryProcessCycleTime.s b/libc/nt/KernelBase/QueryProcessCycleTime.s new file mode 100644 index 00000000..40156132 --- /dev/null +++ b/libc/nt/KernelBase/QueryProcessCycleTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryProcessCycleTime,QueryProcessCycleTime,1269 diff --git a/libc/nt/KernelBase/QueryProtectedPolicy.s b/libc/nt/KernelBase/QueryProtectedPolicy.s new file mode 100644 index 00000000..fbe465d3 --- /dev/null +++ b/libc/nt/KernelBase/QueryProtectedPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryProtectedPolicy,QueryProtectedPolicy,1270 diff --git a/libc/nt/KernelBase/QuerySecurityAccessMask.s b/libc/nt/KernelBase/QuerySecurityAccessMask.s new file mode 100644 index 00000000..9d6ce4ad --- /dev/null +++ b/libc/nt/KernelBase/QuerySecurityAccessMask.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QuerySecurityAccessMask,QuerySecurityAccessMask,1271 diff --git a/libc/nt/KernelBase/QueryStateAtomValueInfo.s b/libc/nt/KernelBase/QueryStateAtomValueInfo.s new file mode 100644 index 00000000..f180978b --- /dev/null +++ b/libc/nt/KernelBase/QueryStateAtomValueInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryStateAtomValueInfo,QueryStateAtomValueInfo,1272 diff --git a/libc/nt/KernelBase/QueryStateContainerCreatedNew.s b/libc/nt/KernelBase/QueryStateContainerCreatedNew.s new file mode 100644 index 00000000..9640f64c --- /dev/null +++ b/libc/nt/KernelBase/QueryStateContainerCreatedNew.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryStateContainerCreatedNew,QueryStateContainerCreatedNew,1273 diff --git a/libc/nt/KernelBase/QueryStateContainerItemInfo.s b/libc/nt/KernelBase/QueryStateContainerItemInfo.s new file mode 100644 index 00000000..a4e3c8a6 --- /dev/null +++ b/libc/nt/KernelBase/QueryStateContainerItemInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryStateContainerItemInfo,QueryStateContainerItemInfo,1274 diff --git a/libc/nt/KernelBase/QueryThreadCycleTime.s b/libc/nt/KernelBase/QueryThreadCycleTime.s new file mode 100644 index 00000000..6d1d1e4b --- /dev/null +++ b/libc/nt/KernelBase/QueryThreadCycleTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryThreadCycleTime,QueryThreadCycleTime,1275 diff --git a/libc/nt/KernelBase/QueryThreadpoolStackInformation.s b/libc/nt/KernelBase/QueryThreadpoolStackInformation.s new file mode 100644 index 00000000..a99acd1a --- /dev/null +++ b/libc/nt/KernelBase/QueryThreadpoolStackInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryThreadpoolStackInformation,QueryThreadpoolStackInformation,1276 diff --git a/libc/nt/KernelBase/QueryUnbiasedInterruptTimePrecise.s b/libc/nt/KernelBase/QueryUnbiasedInterruptTimePrecise.s new file mode 100644 index 00000000..7e0ae29f --- /dev/null +++ b/libc/nt/KernelBase/QueryUnbiasedInterruptTimePrecise.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryUnbiasedInterruptTimePrecise,QueryUnbiasedInterruptTimePrecise,1278 diff --git a/libc/nt/KernelBase/QueryVirtualMemoryInformation.s b/libc/nt/KernelBase/QueryVirtualMemoryInformation.s new file mode 100644 index 00000000..60e2cfe9 --- /dev/null +++ b/libc/nt/KernelBase/QueryVirtualMemoryInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryVirtualMemoryInformation,QueryVirtualMemoryInformation,1279 diff --git a/libc/nt/KernelBase/QueryWorkingSet.s b/libc/nt/KernelBase/QueryWorkingSet.s new file mode 100644 index 00000000..33c81e0e --- /dev/null +++ b/libc/nt/KernelBase/QueryWorkingSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryWorkingSet,QueryWorkingSet,1280 diff --git a/libc/nt/KernelBase/QueryWorkingSetEx.s b/libc/nt/KernelBase/QueryWorkingSetEx.s new file mode 100644 index 00000000..8d4a394b --- /dev/null +++ b/libc/nt/KernelBase/QueryWorkingSetEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueryWorkingSetEx,QueryWorkingSetEx,1281 diff --git a/libc/nt/KernelBase/QueueUserAPC.s b/libc/nt/KernelBase/QueueUserAPC.s new file mode 100644 index 00000000..24b6f9ec --- /dev/null +++ b/libc/nt/KernelBase/QueueUserAPC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueueUserAPC,QueueUserAPC,1282 diff --git a/libc/nt/KernelBase/QueueUserWorkItem.s b/libc/nt/KernelBase/QueueUserWorkItem.s new file mode 100644 index 00000000..51a7ff60 --- /dev/null +++ b/libc/nt/KernelBase/QueueUserWorkItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QueueUserWorkItem,QueueUserWorkItem,1283 diff --git a/libc/nt/KernelBase/QuirkGetData.s b/libc/nt/KernelBase/QuirkGetData.s new file mode 100644 index 00000000..915f8a77 --- /dev/null +++ b/libc/nt/KernelBase/QuirkGetData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QuirkGetData,QuirkGetData,1284 diff --git a/libc/nt/KernelBase/QuirkGetData2.s b/libc/nt/KernelBase/QuirkGetData2.s new file mode 100644 index 00000000..fc9ea246 --- /dev/null +++ b/libc/nt/KernelBase/QuirkGetData2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QuirkGetData2,QuirkGetData2,1285 diff --git a/libc/nt/KernelBase/QuirkIsEnabled.s b/libc/nt/KernelBase/QuirkIsEnabled.s new file mode 100644 index 00000000..9a1775fd --- /dev/null +++ b/libc/nt/KernelBase/QuirkIsEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QuirkIsEnabled,QuirkIsEnabled,1286 diff --git a/libc/nt/KernelBase/QuirkIsEnabled2.s b/libc/nt/KernelBase/QuirkIsEnabled2.s new file mode 100644 index 00000000..5dbcf1de --- /dev/null +++ b/libc/nt/KernelBase/QuirkIsEnabled2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QuirkIsEnabled2,QuirkIsEnabled2,1287 diff --git a/libc/nt/KernelBase/QuirkIsEnabled3.s b/libc/nt/KernelBase/QuirkIsEnabled3.s new file mode 100644 index 00000000..d4bcc3f1 --- /dev/null +++ b/libc/nt/KernelBase/QuirkIsEnabled3.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QuirkIsEnabled3,QuirkIsEnabled3,1288 diff --git a/libc/nt/KernelBase/QuirkIsEnabledForPackage.s b/libc/nt/KernelBase/QuirkIsEnabledForPackage.s new file mode 100644 index 00000000..8497faff --- /dev/null +++ b/libc/nt/KernelBase/QuirkIsEnabledForPackage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QuirkIsEnabledForPackage,QuirkIsEnabledForPackage,1289 diff --git a/libc/nt/KernelBase/QuirkIsEnabledForPackage2.s b/libc/nt/KernelBase/QuirkIsEnabledForPackage2.s new file mode 100644 index 00000000..503be573 --- /dev/null +++ b/libc/nt/KernelBase/QuirkIsEnabledForPackage2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QuirkIsEnabledForPackage2,QuirkIsEnabledForPackage2,1290 diff --git a/libc/nt/KernelBase/QuirkIsEnabledForPackage3.s b/libc/nt/KernelBase/QuirkIsEnabledForPackage3.s new file mode 100644 index 00000000..d0bc9b1c --- /dev/null +++ b/libc/nt/KernelBase/QuirkIsEnabledForPackage3.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QuirkIsEnabledForPackage3,QuirkIsEnabledForPackage3,1291 diff --git a/libc/nt/KernelBase/QuirkIsEnabledForPackage4.s b/libc/nt/KernelBase/QuirkIsEnabledForPackage4.s new file mode 100644 index 00000000..49bbd9d3 --- /dev/null +++ b/libc/nt/KernelBase/QuirkIsEnabledForPackage4.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QuirkIsEnabledForPackage4,QuirkIsEnabledForPackage4,1292 diff --git a/libc/nt/KernelBase/QuirkIsEnabledForProcess.s b/libc/nt/KernelBase/QuirkIsEnabledForProcess.s new file mode 100644 index 00000000..084ee574 --- /dev/null +++ b/libc/nt/KernelBase/QuirkIsEnabledForProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_QuirkIsEnabledForProcess,QuirkIsEnabledForProcess,1293 diff --git a/libc/nt/KernelBase/RaiseCustomSystemEventTrigger.s b/libc/nt/KernelBase/RaiseCustomSystemEventTrigger.s new file mode 100644 index 00000000..3b98ce6c --- /dev/null +++ b/libc/nt/KernelBase/RaiseCustomSystemEventTrigger.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RaiseCustomSystemEventTrigger,RaiseCustomSystemEventTrigger,1294 diff --git a/libc/nt/KernelBase/RaiseException.s b/libc/nt/KernelBase/RaiseException.s new file mode 100644 index 00000000..b204860d --- /dev/null +++ b/libc/nt/KernelBase/RaiseException.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RaiseException,RaiseException,1295 diff --git a/libc/nt/KernelBase/RaiseFailFastException.s b/libc/nt/KernelBase/RaiseFailFastException.s new file mode 100644 index 00000000..bee4403e --- /dev/null +++ b/libc/nt/KernelBase/RaiseFailFastException.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RaiseFailFastException,RaiseFailFastException,1296 diff --git a/libc/nt/KernelBase/ReOpenFile.s b/libc/nt/KernelBase/ReOpenFile.s new file mode 100644 index 00000000..0cce2124 --- /dev/null +++ b/libc/nt/KernelBase/ReOpenFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReOpenFile,ReOpenFile,1297 + + .text.windows +ReOpenFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ReOpenFile(%rip),%rax + jmp __sysv2nt + .endfn ReOpenFile,globl + .previous diff --git a/libc/nt/KernelBase/ReadConsoleA.s b/libc/nt/KernelBase/ReadConsoleA.s new file mode 100644 index 00000000..f6c1e5de --- /dev/null +++ b/libc/nt/KernelBase/ReadConsoleA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadConsoleA,ReadConsoleA,1298 + + .text.windows +ReadConsoleA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ReadConsoleA(%rip),%rax + jmp __sysv2nt6 + .endfn ReadConsoleA,globl + .previous diff --git a/libc/nt/KernelBase/ReadConsoleInputA.s b/libc/nt/KernelBase/ReadConsoleInputA.s new file mode 100644 index 00000000..6eb9b18b --- /dev/null +++ b/libc/nt/KernelBase/ReadConsoleInputA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadConsoleInputA,ReadConsoleInputA,1299 + + .text.windows +ReadConsoleInputA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ReadConsoleInputA(%rip),%rax + jmp __sysv2nt + .endfn ReadConsoleInputA,globl + .previous diff --git a/libc/nt/KernelBase/ReadConsoleInputExA.s b/libc/nt/KernelBase/ReadConsoleInputExA.s new file mode 100644 index 00000000..68e41d03 --- /dev/null +++ b/libc/nt/KernelBase/ReadConsoleInputExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadConsoleInputExA,ReadConsoleInputExA,1300 diff --git a/libc/nt/KernelBase/ReadConsoleInputExW.s b/libc/nt/KernelBase/ReadConsoleInputExW.s new file mode 100644 index 00000000..69b2f5e7 --- /dev/null +++ b/libc/nt/KernelBase/ReadConsoleInputExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadConsoleInputExW,ReadConsoleInputExW,1301 diff --git a/libc/nt/KernelBase/ReadConsoleInputW.s b/libc/nt/KernelBase/ReadConsoleInputW.s new file mode 100644 index 00000000..7d2dd20b --- /dev/null +++ b/libc/nt/KernelBase/ReadConsoleInputW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadConsoleInputW,ReadConsoleInputW,1302 + + .text.windows +ReadConsoleInput: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ReadConsoleInputW(%rip),%rax + jmp __sysv2nt + .endfn ReadConsoleInput,globl + .previous diff --git a/libc/nt/KernelBase/ReadConsoleOutputA.s b/libc/nt/KernelBase/ReadConsoleOutputA.s new file mode 100644 index 00000000..65c6c1f9 --- /dev/null +++ b/libc/nt/KernelBase/ReadConsoleOutputA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadConsoleOutputA,ReadConsoleOutputA,1303 + + .text.windows +ReadConsoleOutputA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ReadConsoleOutputA(%rip),%rax + jmp __sysv2nt6 + .endfn ReadConsoleOutputA,globl + .previous diff --git a/libc/nt/KernelBase/ReadConsoleOutputAttribute.s b/libc/nt/KernelBase/ReadConsoleOutputAttribute.s new file mode 100644 index 00000000..ebf624e0 --- /dev/null +++ b/libc/nt/KernelBase/ReadConsoleOutputAttribute.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadConsoleOutputAttribute,ReadConsoleOutputAttribute,1304 + + .text.windows +ReadConsoleOutputAttribute: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ReadConsoleOutputAttribute(%rip),%rax + jmp __sysv2nt6 + .endfn ReadConsoleOutputAttribute,globl + .previous diff --git a/libc/nt/KernelBase/ReadConsoleOutputCharacterA.s b/libc/nt/KernelBase/ReadConsoleOutputCharacterA.s new file mode 100644 index 00000000..a589ef47 --- /dev/null +++ b/libc/nt/KernelBase/ReadConsoleOutputCharacterA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadConsoleOutputCharacterA,ReadConsoleOutputCharacterA,1305 + + .text.windows +ReadConsoleOutputCharacterA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ReadConsoleOutputCharacterA(%rip),%rax + jmp __sysv2nt6 + .endfn ReadConsoleOutputCharacterA,globl + .previous diff --git a/libc/nt/KernelBase/ReadConsoleOutputCharacterW.s b/libc/nt/KernelBase/ReadConsoleOutputCharacterW.s new file mode 100644 index 00000000..16a37a57 --- /dev/null +++ b/libc/nt/KernelBase/ReadConsoleOutputCharacterW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadConsoleOutputCharacterW,ReadConsoleOutputCharacterW,1306 + + .text.windows +ReadConsoleOutputCharacter: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ReadConsoleOutputCharacterW(%rip),%rax + jmp __sysv2nt6 + .endfn ReadConsoleOutputCharacter,globl + .previous diff --git a/libc/nt/KernelBase/ReadConsoleOutputW.s b/libc/nt/KernelBase/ReadConsoleOutputW.s new file mode 100644 index 00000000..8d7a634b --- /dev/null +++ b/libc/nt/KernelBase/ReadConsoleOutputW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadConsoleOutputW,ReadConsoleOutputW,1307 + + .text.windows +ReadConsoleOutput: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ReadConsoleOutputW(%rip),%rax + jmp __sysv2nt6 + .endfn ReadConsoleOutput,globl + .previous diff --git a/libc/nt/KernelBase/ReadConsoleW.s b/libc/nt/KernelBase/ReadConsoleW.s new file mode 100644 index 00000000..b639c6ae --- /dev/null +++ b/libc/nt/KernelBase/ReadConsoleW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadConsoleW,ReadConsoleW,1308 + + .text.windows +ReadConsole: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ReadConsoleW(%rip),%rax + jmp __sysv2nt6 + .endfn ReadConsole,globl + .previous diff --git a/libc/nt/KernelBase/ReadDirectoryChangesExW.s b/libc/nt/KernelBase/ReadDirectoryChangesExW.s new file mode 100644 index 00000000..e5dbc71a --- /dev/null +++ b/libc/nt/KernelBase/ReadDirectoryChangesExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadDirectoryChangesExW,ReadDirectoryChangesExW,1309 diff --git a/libc/nt/KernelBase/ReadDirectoryChangesW.s b/libc/nt/KernelBase/ReadDirectoryChangesW.s new file mode 100644 index 00000000..47125919 --- /dev/null +++ b/libc/nt/KernelBase/ReadDirectoryChangesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadDirectoryChangesW,ReadDirectoryChangesW,1310 diff --git a/libc/nt/KernelBase/ReadFile.s b/libc/nt/KernelBase/ReadFile.s new file mode 100644 index 00000000..f8e55fc3 --- /dev/null +++ b/libc/nt/KernelBase/ReadFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadFile,ReadFile,1311 + + .text.windows +ReadFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ReadFile(%rip),%rax + jmp __sysv2nt6 + .endfn ReadFile,globl + .previous diff --git a/libc/nt/KernelBase/ReadFileEx.s b/libc/nt/KernelBase/ReadFileEx.s new file mode 100644 index 00000000..ae5ffddc --- /dev/null +++ b/libc/nt/KernelBase/ReadFileEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadFileEx,ReadFileEx,1312 diff --git a/libc/nt/KernelBase/ReadFileScatter.s b/libc/nt/KernelBase/ReadFileScatter.s new file mode 100644 index 00000000..35bce6b7 --- /dev/null +++ b/libc/nt/KernelBase/ReadFileScatter.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadFileScatter,ReadFileScatter,1313 + + .text.windows +ReadFileScatter: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ReadFileScatter(%rip),%rax + jmp __sysv2nt6 + .endfn ReadFileScatter,globl + .previous diff --git a/libc/nt/KernelBase/ReadProcessMemory.s b/libc/nt/KernelBase/ReadProcessMemory.s new file mode 100644 index 00000000..a61132f3 --- /dev/null +++ b/libc/nt/KernelBase/ReadProcessMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadProcessMemory,ReadProcessMemory,1314 diff --git a/libc/nt/KernelBase/ReadStateAtomValue.s b/libc/nt/KernelBase/ReadStateAtomValue.s new file mode 100644 index 00000000..fe00d978 --- /dev/null +++ b/libc/nt/KernelBase/ReadStateAtomValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadStateAtomValue,ReadStateAtomValue,1315 diff --git a/libc/nt/KernelBase/ReadStateContainerValue.s b/libc/nt/KernelBase/ReadStateContainerValue.s new file mode 100644 index 00000000..73cd0c98 --- /dev/null +++ b/libc/nt/KernelBase/ReadStateContainerValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReadStateContainerValue,ReadStateContainerValue,1316 diff --git a/libc/nt/KernelBase/ReclaimVirtualMemory.s b/libc/nt/KernelBase/ReclaimVirtualMemory.s new file mode 100644 index 00000000..acad3371 --- /dev/null +++ b/libc/nt/KernelBase/ReclaimVirtualMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReclaimVirtualMemory,ReclaimVirtualMemory,1317 diff --git a/libc/nt/KernelBase/RefreshPackageInfo.s b/libc/nt/KernelBase/RefreshPackageInfo.s new file mode 100644 index 00000000..aa7fbb23 --- /dev/null +++ b/libc/nt/KernelBase/RefreshPackageInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RefreshPackageInfo,RefreshPackageInfo,1318 diff --git a/libc/nt/KernelBase/RefreshPolicyExInternal.s b/libc/nt/KernelBase/RefreshPolicyExInternal.s new file mode 100644 index 00000000..e970e590 --- /dev/null +++ b/libc/nt/KernelBase/RefreshPolicyExInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RefreshPolicyExInternal,RefreshPolicyExInternal,1319 diff --git a/libc/nt/KernelBase/RefreshPolicyInternal.s b/libc/nt/KernelBase/RefreshPolicyInternal.s new file mode 100644 index 00000000..b0c41716 --- /dev/null +++ b/libc/nt/KernelBase/RefreshPolicyInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RefreshPolicyInternal,RefreshPolicyInternal,1320 diff --git a/libc/nt/KernelBase/RegCloseKey.s b/libc/nt/KernelBase/RegCloseKey.s new file mode 100644 index 00000000..fea6afbe --- /dev/null +++ b/libc/nt/KernelBase/RegCloseKey.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegCloseKey,RegCloseKey,1321 + + .text.windows +RegCloseKey: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RegCloseKey(%rip) + leave + ret + .endfn RegCloseKey,globl + .previous diff --git a/libc/nt/KernelBase/RegCopyTreeW.s b/libc/nt/KernelBase/RegCopyTreeW.s new file mode 100644 index 00000000..c080320f --- /dev/null +++ b/libc/nt/KernelBase/RegCopyTreeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegCopyTreeW,RegCopyTreeW,1322 diff --git a/libc/nt/KernelBase/RegCreateKeyExA.s b/libc/nt/KernelBase/RegCreateKeyExA.s new file mode 100644 index 00000000..06e6ce4f --- /dev/null +++ b/libc/nt/KernelBase/RegCreateKeyExA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegCreateKeyExA,RegCreateKeyExA,1323 + + .text.windows +RegCreateKeyExA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegCreateKeyExA(%rip),%rax + jmp __sysv2nt10 + .endfn RegCreateKeyExA,globl + .previous diff --git a/libc/nt/KernelBase/RegCreateKeyExInternalA.s b/libc/nt/KernelBase/RegCreateKeyExInternalA.s new file mode 100644 index 00000000..3c194df3 --- /dev/null +++ b/libc/nt/KernelBase/RegCreateKeyExInternalA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegCreateKeyExInternalA,RegCreateKeyExInternalA,1324 diff --git a/libc/nt/KernelBase/RegCreateKeyExInternalW.s b/libc/nt/KernelBase/RegCreateKeyExInternalW.s new file mode 100644 index 00000000..2d3add29 --- /dev/null +++ b/libc/nt/KernelBase/RegCreateKeyExInternalW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegCreateKeyExInternalW,RegCreateKeyExInternalW,1325 diff --git a/libc/nt/KernelBase/RegCreateKeyExW.s b/libc/nt/KernelBase/RegCreateKeyExW.s new file mode 100644 index 00000000..ef732894 --- /dev/null +++ b/libc/nt/KernelBase/RegCreateKeyExW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegCreateKeyExW,RegCreateKeyExW,1326 + + .text.windows +RegCreateKeyEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegCreateKeyExW(%rip),%rax + jmp __sysv2nt10 + .endfn RegCreateKeyEx,globl + .previous diff --git a/libc/nt/KernelBase/RegDeleteKeyExA.s b/libc/nt/KernelBase/RegDeleteKeyExA.s new file mode 100644 index 00000000..aa7d1e5a --- /dev/null +++ b/libc/nt/KernelBase/RegDeleteKeyExA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegDeleteKeyExA,RegDeleteKeyExA,1327 + + .text.windows +RegDeleteKeyExA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegDeleteKeyExA(%rip),%rax + jmp __sysv2nt + .endfn RegDeleteKeyExA,globl + .previous diff --git a/libc/nt/KernelBase/RegDeleteKeyExInternalA.s b/libc/nt/KernelBase/RegDeleteKeyExInternalA.s new file mode 100644 index 00000000..4bfefb2f --- /dev/null +++ b/libc/nt/KernelBase/RegDeleteKeyExInternalA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegDeleteKeyExInternalA,RegDeleteKeyExInternalA,1328 diff --git a/libc/nt/KernelBase/RegDeleteKeyExInternalW.s b/libc/nt/KernelBase/RegDeleteKeyExInternalW.s new file mode 100644 index 00000000..b7d6b63d --- /dev/null +++ b/libc/nt/KernelBase/RegDeleteKeyExInternalW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegDeleteKeyExInternalW,RegDeleteKeyExInternalW,1329 diff --git a/libc/nt/KernelBase/RegDeleteKeyExW.s b/libc/nt/KernelBase/RegDeleteKeyExW.s new file mode 100644 index 00000000..7c49a5c0 --- /dev/null +++ b/libc/nt/KernelBase/RegDeleteKeyExW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegDeleteKeyExW,RegDeleteKeyExW,1330 + + .text.windows +RegDeleteKeyEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegDeleteKeyExW(%rip),%rax + jmp __sysv2nt + .endfn RegDeleteKeyEx,globl + .previous diff --git a/libc/nt/KernelBase/RegDeleteKeyValueA.s b/libc/nt/KernelBase/RegDeleteKeyValueA.s new file mode 100644 index 00000000..abda0357 --- /dev/null +++ b/libc/nt/KernelBase/RegDeleteKeyValueA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegDeleteKeyValueA,RegDeleteKeyValueA,1331 diff --git a/libc/nt/KernelBase/RegDeleteKeyValueW.s b/libc/nt/KernelBase/RegDeleteKeyValueW.s new file mode 100644 index 00000000..1f25957e --- /dev/null +++ b/libc/nt/KernelBase/RegDeleteKeyValueW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegDeleteKeyValueW,RegDeleteKeyValueW,1332 diff --git a/libc/nt/KernelBase/RegDeleteTreeA.s b/libc/nt/KernelBase/RegDeleteTreeA.s new file mode 100644 index 00000000..9117fb6f --- /dev/null +++ b/libc/nt/KernelBase/RegDeleteTreeA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegDeleteTreeA,RegDeleteTreeA,1333 + + .text.windows +RegDeleteTreeA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegDeleteTreeA(%rip),%rax + jmp __sysv2nt + .endfn RegDeleteTreeA,globl + .previous diff --git a/libc/nt/KernelBase/RegDeleteTreeW.s b/libc/nt/KernelBase/RegDeleteTreeW.s new file mode 100644 index 00000000..f479bb66 --- /dev/null +++ b/libc/nt/KernelBase/RegDeleteTreeW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegDeleteTreeW,RegDeleteTreeW,1334 + + .text.windows +RegDeleteTree: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegDeleteTreeW(%rip),%rax + jmp __sysv2nt + .endfn RegDeleteTree,globl + .previous diff --git a/libc/nt/KernelBase/RegDeleteValueA.s b/libc/nt/KernelBase/RegDeleteValueA.s new file mode 100644 index 00000000..d9a0c5d5 --- /dev/null +++ b/libc/nt/KernelBase/RegDeleteValueA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegDeleteValueA,RegDeleteValueA,1335 + + .text.windows +RegDeleteValueA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegDeleteValueA(%rip),%rax + jmp __sysv2nt + .endfn RegDeleteValueA,globl + .previous diff --git a/libc/nt/KernelBase/RegDeleteValueW.s b/libc/nt/KernelBase/RegDeleteValueW.s new file mode 100644 index 00000000..fc3f3aa1 --- /dev/null +++ b/libc/nt/KernelBase/RegDeleteValueW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegDeleteValueW,RegDeleteValueW,1336 + + .text.windows +RegDeleteValue: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegDeleteValueW(%rip),%rax + jmp __sysv2nt + .endfn RegDeleteValue,globl + .previous diff --git a/libc/nt/KernelBase/RegDisablePredefinedCacheEx.s b/libc/nt/KernelBase/RegDisablePredefinedCacheEx.s new file mode 100644 index 00000000..62d571c3 --- /dev/null +++ b/libc/nt/KernelBase/RegDisablePredefinedCacheEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegDisablePredefinedCacheEx,RegDisablePredefinedCacheEx,1337 diff --git a/libc/nt/KernelBase/RegEnumKeyExA.s b/libc/nt/KernelBase/RegEnumKeyExA.s new file mode 100644 index 00000000..c48bb1b0 --- /dev/null +++ b/libc/nt/KernelBase/RegEnumKeyExA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegEnumKeyExA,RegEnumKeyExA,1338 + + .text.windows +RegEnumKeyExA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegEnumKeyExA(%rip),%rax + jmp __sysv2nt8 + .endfn RegEnumKeyExA,globl + .previous diff --git a/libc/nt/KernelBase/RegEnumKeyExW.s b/libc/nt/KernelBase/RegEnumKeyExW.s new file mode 100644 index 00000000..761509b5 --- /dev/null +++ b/libc/nt/KernelBase/RegEnumKeyExW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegEnumKeyExW,RegEnumKeyExW,1339 + + .text.windows +RegEnumKeyEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegEnumKeyExW(%rip),%rax + jmp __sysv2nt8 + .endfn RegEnumKeyEx,globl + .previous diff --git a/libc/nt/KernelBase/RegEnumValueA.s b/libc/nt/KernelBase/RegEnumValueA.s new file mode 100644 index 00000000..c1153838 --- /dev/null +++ b/libc/nt/KernelBase/RegEnumValueA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegEnumValueA,RegEnumValueA,1340 + + .text.windows +RegEnumValueA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegEnumValueA(%rip),%rax + jmp __sysv2nt8 + .endfn RegEnumValueA,globl + .previous diff --git a/libc/nt/KernelBase/RegEnumValueW.s b/libc/nt/KernelBase/RegEnumValueW.s new file mode 100644 index 00000000..44bbfe37 --- /dev/null +++ b/libc/nt/KernelBase/RegEnumValueW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegEnumValueW,RegEnumValueW,1341 + + .text.windows +RegEnumValue: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegEnumValueW(%rip),%rax + jmp __sysv2nt8 + .endfn RegEnumValue,globl + .previous diff --git a/libc/nt/KernelBase/RegFlushKey.s b/libc/nt/KernelBase/RegFlushKey.s new file mode 100644 index 00000000..0f34a157 --- /dev/null +++ b/libc/nt/KernelBase/RegFlushKey.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegFlushKey,RegFlushKey,1342 + + .text.windows +RegFlushKey: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RegFlushKey(%rip) + leave + ret + .endfn RegFlushKey,globl + .previous diff --git a/libc/nt/KernelBase/RegGetKeySecurity.s b/libc/nt/KernelBase/RegGetKeySecurity.s new file mode 100644 index 00000000..897a7863 --- /dev/null +++ b/libc/nt/KernelBase/RegGetKeySecurity.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegGetKeySecurity,RegGetKeySecurity,1343 + + .text.windows +RegGetKeySecurity: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegGetKeySecurity(%rip),%rax + jmp __sysv2nt + .endfn RegGetKeySecurity,globl + .previous diff --git a/libc/nt/KernelBase/RegGetValueA.s b/libc/nt/KernelBase/RegGetValueA.s new file mode 100644 index 00000000..5d664de1 --- /dev/null +++ b/libc/nt/KernelBase/RegGetValueA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegGetValueA,RegGetValueA,1344 + + .text.windows +RegGetValueA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegGetValueA(%rip),%rax + jmp __sysv2nt8 + .endfn RegGetValueA,globl + .previous diff --git a/libc/nt/KernelBase/RegGetValueW.s b/libc/nt/KernelBase/RegGetValueW.s new file mode 100644 index 00000000..ee091972 --- /dev/null +++ b/libc/nt/KernelBase/RegGetValueW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegGetValueW,RegGetValueW,1345 + + .text.windows +RegGetValue: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegGetValueW(%rip),%rax + jmp __sysv2nt8 + .endfn RegGetValue,globl + .previous diff --git a/libc/nt/KernelBase/RegKrnGetAppKeyEventAddressInternal.s b/libc/nt/KernelBase/RegKrnGetAppKeyEventAddressInternal.s new file mode 100644 index 00000000..2e5d58ca --- /dev/null +++ b/libc/nt/KernelBase/RegKrnGetAppKeyEventAddressInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegKrnGetAppKeyEventAddressInternal,RegKrnGetAppKeyEventAddressInternal,1346 diff --git a/libc/nt/KernelBase/RegKrnGetAppKeyLoaded.s b/libc/nt/KernelBase/RegKrnGetAppKeyLoaded.s new file mode 100644 index 00000000..08b8666e --- /dev/null +++ b/libc/nt/KernelBase/RegKrnGetAppKeyLoaded.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegKrnGetAppKeyLoaded,RegKrnGetAppKeyLoaded,1347 diff --git a/libc/nt/KernelBase/RegKrnGetClassesEnumTableAddressInternal.s b/libc/nt/KernelBase/RegKrnGetClassesEnumTableAddressInternal.s new file mode 100644 index 00000000..bc82c45d --- /dev/null +++ b/libc/nt/KernelBase/RegKrnGetClassesEnumTableAddressInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegKrnGetClassesEnumTableAddressInternal,RegKrnGetClassesEnumTableAddressInternal,1348 diff --git a/libc/nt/KernelBase/RegKrnGetHKEY_ClassesRootAddress.s b/libc/nt/KernelBase/RegKrnGetHKEY_ClassesRootAddress.s new file mode 100644 index 00000000..6fb7e89a --- /dev/null +++ b/libc/nt/KernelBase/RegKrnGetHKEY_ClassesRootAddress.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegKrnGetHKEY_ClassesRootAddress,RegKrnGetHKEY_ClassesRootAddress,1349 diff --git a/libc/nt/KernelBase/RegKrnGetTermsrvRegistryExtensionFlags.s b/libc/nt/KernelBase/RegKrnGetTermsrvRegistryExtensionFlags.s new file mode 100644 index 00000000..270e0d5b --- /dev/null +++ b/libc/nt/KernelBase/RegKrnGetTermsrvRegistryExtensionFlags.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegKrnGetTermsrvRegistryExtensionFlags,RegKrnGetTermsrvRegistryExtensionFlags,1350 diff --git a/libc/nt/KernelBase/RegKrnResetAppKeyLoaded.s b/libc/nt/KernelBase/RegKrnResetAppKeyLoaded.s new file mode 100644 index 00000000..935a53ec --- /dev/null +++ b/libc/nt/KernelBase/RegKrnResetAppKeyLoaded.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegKrnResetAppKeyLoaded,RegKrnResetAppKeyLoaded,1351 diff --git a/libc/nt/KernelBase/RegKrnSetDllHasThreadStateGlobal.s b/libc/nt/KernelBase/RegKrnSetDllHasThreadStateGlobal.s new file mode 100644 index 00000000..e8823292 --- /dev/null +++ b/libc/nt/KernelBase/RegKrnSetDllHasThreadStateGlobal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegKrnSetDllHasThreadStateGlobal,RegKrnSetDllHasThreadStateGlobal,1352 diff --git a/libc/nt/KernelBase/RegKrnSetTermsrvRegistryExtensionFlags.s b/libc/nt/KernelBase/RegKrnSetTermsrvRegistryExtensionFlags.s new file mode 100644 index 00000000..9dd7ec5f --- /dev/null +++ b/libc/nt/KernelBase/RegKrnSetTermsrvRegistryExtensionFlags.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegKrnSetTermsrvRegistryExtensionFlags,RegKrnSetTermsrvRegistryExtensionFlags,1353 diff --git a/libc/nt/KernelBase/RegLoadAppKeyA.s b/libc/nt/KernelBase/RegLoadAppKeyA.s new file mode 100644 index 00000000..c537885b --- /dev/null +++ b/libc/nt/KernelBase/RegLoadAppKeyA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegLoadAppKeyA,RegLoadAppKeyA,1354 diff --git a/libc/nt/KernelBase/RegLoadAppKeyW.s b/libc/nt/KernelBase/RegLoadAppKeyW.s new file mode 100644 index 00000000..fd0f487f --- /dev/null +++ b/libc/nt/KernelBase/RegLoadAppKeyW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegLoadAppKeyW,RegLoadAppKeyW,1355 diff --git a/libc/nt/KernelBase/RegLoadKeyA.s b/libc/nt/KernelBase/RegLoadKeyA.s new file mode 100644 index 00000000..252d5a11 --- /dev/null +++ b/libc/nt/KernelBase/RegLoadKeyA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegLoadKeyA,RegLoadKeyA,1356 + + .text.windows +RegLoadKeyA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegLoadKeyA(%rip),%rax + jmp __sysv2nt + .endfn RegLoadKeyA,globl + .previous diff --git a/libc/nt/KernelBase/RegLoadKeyW.s b/libc/nt/KernelBase/RegLoadKeyW.s new file mode 100644 index 00000000..353526de --- /dev/null +++ b/libc/nt/KernelBase/RegLoadKeyW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegLoadKeyW,RegLoadKeyW,1357 + + .text.windows +RegLoadKey: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegLoadKeyW(%rip),%rax + jmp __sysv2nt + .endfn RegLoadKey,globl + .previous diff --git a/libc/nt/KernelBase/RegLoadMUIStringA.s b/libc/nt/KernelBase/RegLoadMUIStringA.s new file mode 100644 index 00000000..2601a6d1 --- /dev/null +++ b/libc/nt/KernelBase/RegLoadMUIStringA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegLoadMUIStringA,RegLoadMUIStringA,1358 diff --git a/libc/nt/KernelBase/RegLoadMUIStringW.s b/libc/nt/KernelBase/RegLoadMUIStringW.s new file mode 100644 index 00000000..21e2d105 --- /dev/null +++ b/libc/nt/KernelBase/RegLoadMUIStringW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegLoadMUIStringW,RegLoadMUIStringW,1359 diff --git a/libc/nt/KernelBase/RegNotifyChangeKeyValue.s b/libc/nt/KernelBase/RegNotifyChangeKeyValue.s new file mode 100644 index 00000000..1cd39b61 --- /dev/null +++ b/libc/nt/KernelBase/RegNotifyChangeKeyValue.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegNotifyChangeKeyValue,RegNotifyChangeKeyValue,1360 + + .text.windows +RegNotifyChangeKeyValue: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegNotifyChangeKeyValue(%rip),%rax + jmp __sysv2nt6 + .endfn RegNotifyChangeKeyValue,globl + .previous diff --git a/libc/nt/KernelBase/RegOpenCurrentUser.s b/libc/nt/KernelBase/RegOpenCurrentUser.s new file mode 100644 index 00000000..8d904d72 --- /dev/null +++ b/libc/nt/KernelBase/RegOpenCurrentUser.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegOpenCurrentUser,RegOpenCurrentUser,1361 + + .text.windows +RegOpenCurrentUser: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegOpenCurrentUser(%rip),%rax + jmp __sysv2nt + .endfn RegOpenCurrentUser,globl + .previous diff --git a/libc/nt/KernelBase/RegOpenKeyExA.s b/libc/nt/KernelBase/RegOpenKeyExA.s new file mode 100644 index 00000000..d070f1e3 --- /dev/null +++ b/libc/nt/KernelBase/RegOpenKeyExA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegOpenKeyExA,RegOpenKeyExA,1362 + + .text.windows +RegOpenKeyExA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegOpenKeyExA(%rip),%rax + jmp __sysv2nt6 + .endfn RegOpenKeyExA,globl + .previous diff --git a/libc/nt/KernelBase/RegOpenKeyExInternalA.s b/libc/nt/KernelBase/RegOpenKeyExInternalA.s new file mode 100644 index 00000000..6b7fdbba --- /dev/null +++ b/libc/nt/KernelBase/RegOpenKeyExInternalA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegOpenKeyExInternalA,RegOpenKeyExInternalA,1363 diff --git a/libc/nt/KernelBase/RegOpenKeyExInternalW.s b/libc/nt/KernelBase/RegOpenKeyExInternalW.s new file mode 100644 index 00000000..a4dd4139 --- /dev/null +++ b/libc/nt/KernelBase/RegOpenKeyExInternalW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegOpenKeyExInternalW,RegOpenKeyExInternalW,1364 diff --git a/libc/nt/KernelBase/RegOpenKeyExW.s b/libc/nt/KernelBase/RegOpenKeyExW.s new file mode 100644 index 00000000..dac27c2a --- /dev/null +++ b/libc/nt/KernelBase/RegOpenKeyExW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegOpenKeyExW,RegOpenKeyExW,1365 + + .text.windows +RegOpenKeyEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegOpenKeyExW(%rip),%rax + jmp __sysv2nt6 + .endfn RegOpenKeyEx,globl + .previous diff --git a/libc/nt/KernelBase/RegOpenUserClassesRoot.s b/libc/nt/KernelBase/RegOpenUserClassesRoot.s new file mode 100644 index 00000000..7436025b --- /dev/null +++ b/libc/nt/KernelBase/RegOpenUserClassesRoot.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegOpenUserClassesRoot,RegOpenUserClassesRoot,1366 + + .text.windows +RegOpenUserClassesRoot: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegOpenUserClassesRoot(%rip),%rax + jmp __sysv2nt + .endfn RegOpenUserClassesRoot,globl + .previous diff --git a/libc/nt/KernelBase/RegQueryInfoKeyA.s b/libc/nt/KernelBase/RegQueryInfoKeyA.s new file mode 100644 index 00000000..7704083c --- /dev/null +++ b/libc/nt/KernelBase/RegQueryInfoKeyA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegQueryInfoKeyA,RegQueryInfoKeyA,1367 + + .text.windows +RegQueryInfoKeyA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegQueryInfoKeyA(%rip),%rax + jmp __sysv2nt12 + .endfn RegQueryInfoKeyA,globl + .previous diff --git a/libc/nt/KernelBase/RegQueryInfoKeyW.s b/libc/nt/KernelBase/RegQueryInfoKeyW.s new file mode 100644 index 00000000..6daf87a7 --- /dev/null +++ b/libc/nt/KernelBase/RegQueryInfoKeyW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegQueryInfoKeyW,RegQueryInfoKeyW,1368 + + .text.windows +RegQueryInfoKey: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegQueryInfoKeyW(%rip),%rax + jmp __sysv2nt12 + .endfn RegQueryInfoKey,globl + .previous diff --git a/libc/nt/KernelBase/RegQueryMultipleValuesA.s b/libc/nt/KernelBase/RegQueryMultipleValuesA.s new file mode 100644 index 00000000..641b4012 --- /dev/null +++ b/libc/nt/KernelBase/RegQueryMultipleValuesA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegQueryMultipleValuesA,RegQueryMultipleValuesA,1369 + + .text.windows +RegQueryMultipleValuesA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegQueryMultipleValuesA(%rip),%rax + jmp __sysv2nt6 + .endfn RegQueryMultipleValuesA,globl + .previous diff --git a/libc/nt/KernelBase/RegQueryMultipleValuesW.s b/libc/nt/KernelBase/RegQueryMultipleValuesW.s new file mode 100644 index 00000000..637b23f2 --- /dev/null +++ b/libc/nt/KernelBase/RegQueryMultipleValuesW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegQueryMultipleValuesW,RegQueryMultipleValuesW,1370 + + .text.windows +RegQueryMultipleValues: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegQueryMultipleValuesW(%rip),%rax + jmp __sysv2nt6 + .endfn RegQueryMultipleValues,globl + .previous diff --git a/libc/nt/KernelBase/RegQueryValueExA.s b/libc/nt/KernelBase/RegQueryValueExA.s new file mode 100644 index 00000000..a6425daf --- /dev/null +++ b/libc/nt/KernelBase/RegQueryValueExA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegQueryValueExA,RegQueryValueExA,1371 + + .text.windows +RegQueryValueExA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegQueryValueExA(%rip),%rax + jmp __sysv2nt6 + .endfn RegQueryValueExA,globl + .previous diff --git a/libc/nt/KernelBase/RegQueryValueExW.s b/libc/nt/KernelBase/RegQueryValueExW.s new file mode 100644 index 00000000..d061f32b --- /dev/null +++ b/libc/nt/KernelBase/RegQueryValueExW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegQueryValueExW,RegQueryValueExW,1372 + + .text.windows +RegQueryValueEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegQueryValueExW(%rip),%rax + jmp __sysv2nt6 + .endfn RegQueryValueEx,globl + .previous diff --git a/libc/nt/KernelBase/RegRestoreKeyA.s b/libc/nt/KernelBase/RegRestoreKeyA.s new file mode 100644 index 00000000..90ec0627 --- /dev/null +++ b/libc/nt/KernelBase/RegRestoreKeyA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegRestoreKeyA,RegRestoreKeyA,1373 + + .text.windows +RegRestoreKeyA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegRestoreKeyA(%rip),%rax + jmp __sysv2nt + .endfn RegRestoreKeyA,globl + .previous diff --git a/libc/nt/KernelBase/RegRestoreKeyW.s b/libc/nt/KernelBase/RegRestoreKeyW.s new file mode 100644 index 00000000..998d6d6d --- /dev/null +++ b/libc/nt/KernelBase/RegRestoreKeyW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegRestoreKeyW,RegRestoreKeyW,1374 + + .text.windows +RegRestoreKey: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegRestoreKeyW(%rip),%rax + jmp __sysv2nt + .endfn RegRestoreKey,globl + .previous diff --git a/libc/nt/KernelBase/RegSaveKeyExA.s b/libc/nt/KernelBase/RegSaveKeyExA.s new file mode 100644 index 00000000..ef56246d --- /dev/null +++ b/libc/nt/KernelBase/RegSaveKeyExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegSaveKeyExA,RegSaveKeyExA,1375 diff --git a/libc/nt/KernelBase/RegSaveKeyExW.s b/libc/nt/KernelBase/RegSaveKeyExW.s new file mode 100644 index 00000000..c2a9b5de --- /dev/null +++ b/libc/nt/KernelBase/RegSaveKeyExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegSaveKeyExW,RegSaveKeyExW,1376 diff --git a/libc/nt/KernelBase/RegSetKeySecurity.s b/libc/nt/KernelBase/RegSetKeySecurity.s new file mode 100644 index 00000000..3ab012a9 --- /dev/null +++ b/libc/nt/KernelBase/RegSetKeySecurity.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegSetKeySecurity,RegSetKeySecurity,1377 + + .text.windows +RegSetKeySecurity: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegSetKeySecurity(%rip),%rax + jmp __sysv2nt + .endfn RegSetKeySecurity,globl + .previous diff --git a/libc/nt/KernelBase/RegSetKeyValueA.s b/libc/nt/KernelBase/RegSetKeyValueA.s new file mode 100644 index 00000000..a246bac3 --- /dev/null +++ b/libc/nt/KernelBase/RegSetKeyValueA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegSetKeyValueA,RegSetKeyValueA,1378 diff --git a/libc/nt/KernelBase/RegSetKeyValueW.s b/libc/nt/KernelBase/RegSetKeyValueW.s new file mode 100644 index 00000000..943ba36a --- /dev/null +++ b/libc/nt/KernelBase/RegSetKeyValueW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegSetKeyValueW,RegSetKeyValueW,1379 diff --git a/libc/nt/KernelBase/RegSetValueExA.s b/libc/nt/KernelBase/RegSetValueExA.s new file mode 100644 index 00000000..08ad5eb3 --- /dev/null +++ b/libc/nt/KernelBase/RegSetValueExA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegSetValueExA,RegSetValueExA,1380 + + .text.windows +RegSetValueExA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegSetValueExA(%rip),%rax + jmp __sysv2nt6 + .endfn RegSetValueExA,globl + .previous diff --git a/libc/nt/KernelBase/RegSetValueExW.s b/libc/nt/KernelBase/RegSetValueExW.s new file mode 100644 index 00000000..4bb510b2 --- /dev/null +++ b/libc/nt/KernelBase/RegSetValueExW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegSetValueExW,RegSetValueExW,1381 + + .text.windows +RegSetValueEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegSetValueExW(%rip),%rax + jmp __sysv2nt6 + .endfn RegSetValueEx,globl + .previous diff --git a/libc/nt/KernelBase/RegUnLoadKeyA.s b/libc/nt/KernelBase/RegUnLoadKeyA.s new file mode 100644 index 00000000..4cb42c76 --- /dev/null +++ b/libc/nt/KernelBase/RegUnLoadKeyA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegUnLoadKeyA,RegUnLoadKeyA,1382 + + .text.windows +RegUnLoadKeyA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegUnLoadKeyA(%rip),%rax + jmp __sysv2nt + .endfn RegUnLoadKeyA,globl + .previous diff --git a/libc/nt/KernelBase/RegUnLoadKeyW.s b/libc/nt/KernelBase/RegUnLoadKeyW.s new file mode 100644 index 00000000..1c8708cf --- /dev/null +++ b/libc/nt/KernelBase/RegUnLoadKeyW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegUnLoadKeyW,RegUnLoadKeyW,1383 + + .text.windows +RegUnLoadKey: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegUnLoadKeyW(%rip),%rax + jmp __sysv2nt + .endfn RegUnLoadKey,globl + .previous diff --git a/libc/nt/KernelBase/RegisterBadMemoryNotification.s b/libc/nt/KernelBase/RegisterBadMemoryNotification.s new file mode 100644 index 00000000..40609695 --- /dev/null +++ b/libc/nt/KernelBase/RegisterBadMemoryNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegisterBadMemoryNotification,RegisterBadMemoryNotification,1384 diff --git a/libc/nt/KernelBase/RegisterGPNotificationInternal.s b/libc/nt/KernelBase/RegisterGPNotificationInternal.s new file mode 100644 index 00000000..e4db4c26 --- /dev/null +++ b/libc/nt/KernelBase/RegisterGPNotificationInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegisterGPNotificationInternal,RegisterGPNotificationInternal,1385 diff --git a/libc/nt/KernelBase/RegisterStateChangeNotification.s b/libc/nt/KernelBase/RegisterStateChangeNotification.s new file mode 100644 index 00000000..5ffec23b --- /dev/null +++ b/libc/nt/KernelBase/RegisterStateChangeNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegisterStateChangeNotification,RegisterStateChangeNotification,1386 diff --git a/libc/nt/KernelBase/RegisterStateLock.s b/libc/nt/KernelBase/RegisterStateLock.s new file mode 100644 index 00000000..51e96a35 --- /dev/null +++ b/libc/nt/KernelBase/RegisterStateLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegisterStateLock,RegisterStateLock,1387 diff --git a/libc/nt/KernelBase/RegisterWaitForSingleObjectEx.s b/libc/nt/KernelBase/RegisterWaitForSingleObjectEx.s new file mode 100644 index 00000000..474364ba --- /dev/null +++ b/libc/nt/KernelBase/RegisterWaitForSingleObjectEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RegisterWaitForSingleObjectEx,RegisterWaitForSingleObjectEx,1389 diff --git a/libc/nt/KernelBase/ReleaseActCtx.s b/libc/nt/KernelBase/ReleaseActCtx.s new file mode 100644 index 00000000..58c315d3 --- /dev/null +++ b/libc/nt/KernelBase/ReleaseActCtx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReleaseActCtx,ReleaseActCtx,1390 diff --git a/libc/nt/KernelBase/ReleaseMutex.s b/libc/nt/KernelBase/ReleaseMutex.s new file mode 100644 index 00000000..bc47c97a --- /dev/null +++ b/libc/nt/KernelBase/ReleaseMutex.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReleaseMutex,ReleaseMutex,1391 + + .text.windows +ReleaseMutex: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_ReleaseMutex(%rip) + leave + ret + .endfn ReleaseMutex,globl + .previous diff --git a/libc/nt/KernelBase/ReleaseSemaphore.s b/libc/nt/KernelBase/ReleaseSemaphore.s new file mode 100644 index 00000000..4d68dbe3 --- /dev/null +++ b/libc/nt/KernelBase/ReleaseSemaphore.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReleaseSemaphore,ReleaseSemaphore,1395 + + .text.windows +ReleaseSemaphore: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ReleaseSemaphore(%rip),%rax + jmp __sysv2nt + .endfn ReleaseSemaphore,globl + .previous diff --git a/libc/nt/KernelBase/ReleaseStateLock.s b/libc/nt/KernelBase/ReleaseStateLock.s new file mode 100644 index 00000000..1cffda1a --- /dev/null +++ b/libc/nt/KernelBase/ReleaseStateLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReleaseStateLock,ReleaseStateLock,1397 diff --git a/libc/nt/KernelBase/RemapPredefinedHandleInternal.s b/libc/nt/KernelBase/RemapPredefinedHandleInternal.s new file mode 100644 index 00000000..fe8929b6 --- /dev/null +++ b/libc/nt/KernelBase/RemapPredefinedHandleInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RemapPredefinedHandleInternal,RemapPredefinedHandleInternal,1398 diff --git a/libc/nt/KernelBase/RemoveDirectoryA.s b/libc/nt/KernelBase/RemoveDirectoryA.s new file mode 100644 index 00000000..93ce23b8 --- /dev/null +++ b/libc/nt/KernelBase/RemoveDirectoryA.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RemoveDirectoryA,RemoveDirectoryA,1399 + + .text.windows +RemoveDirectoryA: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RemoveDirectoryA(%rip) + leave + ret + .endfn RemoveDirectoryA,globl + .previous diff --git a/libc/nt/KernelBase/RemoveDirectoryW.s b/libc/nt/KernelBase/RemoveDirectoryW.s new file mode 100644 index 00000000..8643649d --- /dev/null +++ b/libc/nt/KernelBase/RemoveDirectoryW.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RemoveDirectoryW,RemoveDirectoryW,1400 + + .text.windows +RemoveDirectory: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RemoveDirectoryW(%rip) + leave + ret + .endfn RemoveDirectory,globl + .previous diff --git a/libc/nt/KernelBase/RemoveDllDirectory.s b/libc/nt/KernelBase/RemoveDllDirectory.s new file mode 100644 index 00000000..b8519444 --- /dev/null +++ b/libc/nt/KernelBase/RemoveDllDirectory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RemoveDllDirectory,RemoveDllDirectory,1401 diff --git a/libc/nt/KernelBase/RemoveExtensionProgIds.s b/libc/nt/KernelBase/RemoveExtensionProgIds.s new file mode 100644 index 00000000..2bfba73c --- /dev/null +++ b/libc/nt/KernelBase/RemoveExtensionProgIds.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RemoveExtensionProgIds,RemoveExtensionProgIds,1402 diff --git a/libc/nt/KernelBase/RemovePackageFromFamilyXref.s b/libc/nt/KernelBase/RemovePackageFromFamilyXref.s new file mode 100644 index 00000000..2ea0d0a6 --- /dev/null +++ b/libc/nt/KernelBase/RemovePackageFromFamilyXref.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RemovePackageFromFamilyXref,RemovePackageFromFamilyXref,1403 diff --git a/libc/nt/KernelBase/RemovePackageStatus.s b/libc/nt/KernelBase/RemovePackageStatus.s new file mode 100644 index 00000000..12191c1c --- /dev/null +++ b/libc/nt/KernelBase/RemovePackageStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RemovePackageStatus,RemovePackageStatus,1404 diff --git a/libc/nt/KernelBase/RemovePackageStatusForUser.s b/libc/nt/KernelBase/RemovePackageStatusForUser.s new file mode 100644 index 00000000..f2ab94ef --- /dev/null +++ b/libc/nt/KernelBase/RemovePackageStatusForUser.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RemovePackageStatusForUser,RemovePackageStatusForUser,1405 diff --git a/libc/nt/KernelBase/RemoveVectoredContinueHandler.s b/libc/nt/KernelBase/RemoveVectoredContinueHandler.s new file mode 100644 index 00000000..ca22a36f --- /dev/null +++ b/libc/nt/KernelBase/RemoveVectoredContinueHandler.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RemoveVectoredContinueHandler,RemoveVectoredContinueHandler,1406 + + .text.windows +RemoveVectoredContinueHandler: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RemoveVectoredContinueHandler(%rip) + leave + ret + .endfn RemoveVectoredContinueHandler,globl + .previous diff --git a/libc/nt/KernelBase/RemoveVectoredExceptionHandler.s b/libc/nt/KernelBase/RemoveVectoredExceptionHandler.s new file mode 100644 index 00000000..4df49697 --- /dev/null +++ b/libc/nt/KernelBase/RemoveVectoredExceptionHandler.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RemoveVectoredExceptionHandler,RemoveVectoredExceptionHandler,1407 + + .text.windows +RemoveVectoredExceptionHandler: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RemoveVectoredExceptionHandler(%rip) + leave + ret + .endfn RemoveVectoredExceptionHandler,globl + .previous diff --git a/libc/nt/KernelBase/ReplaceFileExInternal.s b/libc/nt/KernelBase/ReplaceFileExInternal.s new file mode 100644 index 00000000..f5dcbd36 --- /dev/null +++ b/libc/nt/KernelBase/ReplaceFileExInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReplaceFileExInternal,ReplaceFileExInternal,1408 diff --git a/libc/nt/KernelBase/ReplaceFileW.s b/libc/nt/KernelBase/ReplaceFileW.s new file mode 100644 index 00000000..b6292c99 --- /dev/null +++ b/libc/nt/KernelBase/ReplaceFileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ReplaceFileW,ReplaceFileW,1409 diff --git a/libc/nt/KernelBase/ResetEvent.s b/libc/nt/KernelBase/ResetEvent.s new file mode 100644 index 00000000..11c072f3 --- /dev/null +++ b/libc/nt/KernelBase/ResetEvent.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ResetEvent,ResetEvent,1410 + + .text.windows +ResetEvent: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_ResetEvent(%rip) + leave + ret + .endfn ResetEvent,globl + .previous diff --git a/libc/nt/KernelBase/ResetState.s b/libc/nt/KernelBase/ResetState.s new file mode 100644 index 00000000..45805d4b --- /dev/null +++ b/libc/nt/KernelBase/ResetState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ResetState,ResetState,1411 diff --git a/libc/nt/KernelBase/ResetWriteWatch.s b/libc/nt/KernelBase/ResetWriteWatch.s new file mode 100644 index 00000000..aa514482 --- /dev/null +++ b/libc/nt/KernelBase/ResetWriteWatch.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ResetWriteWatch,ResetWriteWatch,1412 diff --git a/libc/nt/KernelBase/ResolveDelayLoadedAPI.s b/libc/nt/KernelBase/ResolveDelayLoadedAPI.s new file mode 100644 index 00000000..f3b2f7d8 --- /dev/null +++ b/libc/nt/KernelBase/ResolveDelayLoadedAPI.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ResolveDelayLoadedAPI,ResolveDelayLoadedAPI,1413 diff --git a/libc/nt/KernelBase/ResolveDelayLoadsFromDll.s b/libc/nt/KernelBase/ResolveDelayLoadsFromDll.s new file mode 100644 index 00000000..25eb5faa --- /dev/null +++ b/libc/nt/KernelBase/ResolveDelayLoadsFromDll.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ResolveDelayLoadsFromDll,ResolveDelayLoadsFromDll,1414 diff --git a/libc/nt/KernelBase/ResolveLocaleName.s b/libc/nt/KernelBase/ResolveLocaleName.s new file mode 100644 index 00000000..e40e9005 --- /dev/null +++ b/libc/nt/KernelBase/ResolveLocaleName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ResolveLocaleName,ResolveLocaleName,1415 diff --git a/libc/nt/KernelBase/ResumeThread.s b/libc/nt/KernelBase/ResumeThread.s new file mode 100644 index 00000000..09443276 --- /dev/null +++ b/libc/nt/KernelBase/ResumeThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ResumeThread,ResumeThread,1417 diff --git a/libc/nt/KernelBase/RevertToSelf.s b/libc/nt/KernelBase/RevertToSelf.s new file mode 100644 index 00000000..ba50826f --- /dev/null +++ b/libc/nt/KernelBase/RevertToSelf.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RevertToSelf,RevertToSelf,1418 diff --git a/libc/nt/KernelBase/RsopLoggingEnabledInternal.s b/libc/nt/KernelBase/RsopLoggingEnabledInternal.s new file mode 100644 index 00000000..ae0378b7 --- /dev/null +++ b/libc/nt/KernelBase/RsopLoggingEnabledInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_RsopLoggingEnabledInternal,RsopLoggingEnabledInternal,1419 diff --git a/libc/nt/KernelBase/SHCoCreateInstance.s b/libc/nt/KernelBase/SHCoCreateInstance.s new file mode 100644 index 00000000..05f20004 --- /dev/null +++ b/libc/nt/KernelBase/SHCoCreateInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHCoCreateInstance,SHCoCreateInstance,1420 diff --git a/libc/nt/KernelBase/SHExpandEnvironmentStringsA.s b/libc/nt/KernelBase/SHExpandEnvironmentStringsA.s new file mode 100644 index 00000000..e9c4f660 --- /dev/null +++ b/libc/nt/KernelBase/SHExpandEnvironmentStringsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHExpandEnvironmentStringsA,SHExpandEnvironmentStringsA,1421 diff --git a/libc/nt/KernelBase/SHExpandEnvironmentStringsW.s b/libc/nt/KernelBase/SHExpandEnvironmentStringsW.s new file mode 100644 index 00000000..991fec28 --- /dev/null +++ b/libc/nt/KernelBase/SHExpandEnvironmentStringsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHExpandEnvironmentStringsW,SHExpandEnvironmentStringsW,1422 diff --git a/libc/nt/KernelBase/SHLoadIndirectString.s b/libc/nt/KernelBase/SHLoadIndirectString.s new file mode 100644 index 00000000..665c3e01 --- /dev/null +++ b/libc/nt/KernelBase/SHLoadIndirectString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHLoadIndirectString,SHLoadIndirectString,1423 diff --git a/libc/nt/KernelBase/SHLoadIndirectStringInternal.s b/libc/nt/KernelBase/SHLoadIndirectStringInternal.s new file mode 100644 index 00000000..b04937d8 --- /dev/null +++ b/libc/nt/KernelBase/SHLoadIndirectStringInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHLoadIndirectStringInternal,SHLoadIndirectStringInternal,1424 diff --git a/libc/nt/KernelBase/SHRegCloseUSKey.s b/libc/nt/KernelBase/SHRegCloseUSKey.s new file mode 100644 index 00000000..75baaa60 --- /dev/null +++ b/libc/nt/KernelBase/SHRegCloseUSKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegCloseUSKey,SHRegCloseUSKey,1425 diff --git a/libc/nt/KernelBase/SHRegCreateUSKeyA.s b/libc/nt/KernelBase/SHRegCreateUSKeyA.s new file mode 100644 index 00000000..32f4fb73 --- /dev/null +++ b/libc/nt/KernelBase/SHRegCreateUSKeyA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegCreateUSKeyA,SHRegCreateUSKeyA,1426 diff --git a/libc/nt/KernelBase/SHRegCreateUSKeyW.s b/libc/nt/KernelBase/SHRegCreateUSKeyW.s new file mode 100644 index 00000000..b3a7015f --- /dev/null +++ b/libc/nt/KernelBase/SHRegCreateUSKeyW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegCreateUSKeyW,SHRegCreateUSKeyW,1427 diff --git a/libc/nt/KernelBase/SHRegDeleteEmptyUSKeyA.s b/libc/nt/KernelBase/SHRegDeleteEmptyUSKeyA.s new file mode 100644 index 00000000..9cbf12e0 --- /dev/null +++ b/libc/nt/KernelBase/SHRegDeleteEmptyUSKeyA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegDeleteEmptyUSKeyA,SHRegDeleteEmptyUSKeyA,1428 diff --git a/libc/nt/KernelBase/SHRegDeleteEmptyUSKeyW.s b/libc/nt/KernelBase/SHRegDeleteEmptyUSKeyW.s new file mode 100644 index 00000000..c5eff69b --- /dev/null +++ b/libc/nt/KernelBase/SHRegDeleteEmptyUSKeyW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegDeleteEmptyUSKeyW,SHRegDeleteEmptyUSKeyW,1429 diff --git a/libc/nt/KernelBase/SHRegDeleteUSValueA.s b/libc/nt/KernelBase/SHRegDeleteUSValueA.s new file mode 100644 index 00000000..9e9b8c93 --- /dev/null +++ b/libc/nt/KernelBase/SHRegDeleteUSValueA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegDeleteUSValueA,SHRegDeleteUSValueA,1430 diff --git a/libc/nt/KernelBase/SHRegDeleteUSValueW.s b/libc/nt/KernelBase/SHRegDeleteUSValueW.s new file mode 100644 index 00000000..015c4db7 --- /dev/null +++ b/libc/nt/KernelBase/SHRegDeleteUSValueW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegDeleteUSValueW,SHRegDeleteUSValueW,1431 diff --git a/libc/nt/KernelBase/SHRegEnumUSKeyA.s b/libc/nt/KernelBase/SHRegEnumUSKeyA.s new file mode 100644 index 00000000..932be409 --- /dev/null +++ b/libc/nt/KernelBase/SHRegEnumUSKeyA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegEnumUSKeyA,SHRegEnumUSKeyA,1432 diff --git a/libc/nt/KernelBase/SHRegEnumUSKeyW.s b/libc/nt/KernelBase/SHRegEnumUSKeyW.s new file mode 100644 index 00000000..3ea659a7 --- /dev/null +++ b/libc/nt/KernelBase/SHRegEnumUSKeyW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegEnumUSKeyW,SHRegEnumUSKeyW,1433 diff --git a/libc/nt/KernelBase/SHRegEnumUSValueA.s b/libc/nt/KernelBase/SHRegEnumUSValueA.s new file mode 100644 index 00000000..28da79b3 --- /dev/null +++ b/libc/nt/KernelBase/SHRegEnumUSValueA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegEnumUSValueA,SHRegEnumUSValueA,1434 diff --git a/libc/nt/KernelBase/SHRegEnumUSValueW.s b/libc/nt/KernelBase/SHRegEnumUSValueW.s new file mode 100644 index 00000000..a64d3dbf --- /dev/null +++ b/libc/nt/KernelBase/SHRegEnumUSValueW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegEnumUSValueW,SHRegEnumUSValueW,1435 diff --git a/libc/nt/KernelBase/SHRegGetBoolUSValueA.s b/libc/nt/KernelBase/SHRegGetBoolUSValueA.s new file mode 100644 index 00000000..41bbc03c --- /dev/null +++ b/libc/nt/KernelBase/SHRegGetBoolUSValueA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegGetBoolUSValueA,SHRegGetBoolUSValueA,1436 diff --git a/libc/nt/KernelBase/SHRegGetBoolUSValueW.s b/libc/nt/KernelBase/SHRegGetBoolUSValueW.s new file mode 100644 index 00000000..c2f54755 --- /dev/null +++ b/libc/nt/KernelBase/SHRegGetBoolUSValueW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegGetBoolUSValueW,SHRegGetBoolUSValueW,1437 diff --git a/libc/nt/KernelBase/SHRegGetUSValueA.s b/libc/nt/KernelBase/SHRegGetUSValueA.s new file mode 100644 index 00000000..59eef14a --- /dev/null +++ b/libc/nt/KernelBase/SHRegGetUSValueA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegGetUSValueA,SHRegGetUSValueA,1438 diff --git a/libc/nt/KernelBase/SHRegGetUSValueW.s b/libc/nt/KernelBase/SHRegGetUSValueW.s new file mode 100644 index 00000000..1d3c280d --- /dev/null +++ b/libc/nt/KernelBase/SHRegGetUSValueW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegGetUSValueW,SHRegGetUSValueW,1439 diff --git a/libc/nt/KernelBase/SHRegOpenUSKeyA.s b/libc/nt/KernelBase/SHRegOpenUSKeyA.s new file mode 100644 index 00000000..55437e35 --- /dev/null +++ b/libc/nt/KernelBase/SHRegOpenUSKeyA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegOpenUSKeyA,SHRegOpenUSKeyA,1440 diff --git a/libc/nt/KernelBase/SHRegOpenUSKeyW.s b/libc/nt/KernelBase/SHRegOpenUSKeyW.s new file mode 100644 index 00000000..1bd8c6ee --- /dev/null +++ b/libc/nt/KernelBase/SHRegOpenUSKeyW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegOpenUSKeyW,SHRegOpenUSKeyW,1441 diff --git a/libc/nt/KernelBase/SHRegQueryInfoUSKeyA.s b/libc/nt/KernelBase/SHRegQueryInfoUSKeyA.s new file mode 100644 index 00000000..88608e81 --- /dev/null +++ b/libc/nt/KernelBase/SHRegQueryInfoUSKeyA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegQueryInfoUSKeyA,SHRegQueryInfoUSKeyA,1442 diff --git a/libc/nt/KernelBase/SHRegQueryInfoUSKeyW.s b/libc/nt/KernelBase/SHRegQueryInfoUSKeyW.s new file mode 100644 index 00000000..b798d591 --- /dev/null +++ b/libc/nt/KernelBase/SHRegQueryInfoUSKeyW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegQueryInfoUSKeyW,SHRegQueryInfoUSKeyW,1443 diff --git a/libc/nt/KernelBase/SHRegQueryUSValueA.s b/libc/nt/KernelBase/SHRegQueryUSValueA.s new file mode 100644 index 00000000..159fcb38 --- /dev/null +++ b/libc/nt/KernelBase/SHRegQueryUSValueA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegQueryUSValueA,SHRegQueryUSValueA,1444 diff --git a/libc/nt/KernelBase/SHRegQueryUSValueW.s b/libc/nt/KernelBase/SHRegQueryUSValueW.s new file mode 100644 index 00000000..e3e42085 --- /dev/null +++ b/libc/nt/KernelBase/SHRegQueryUSValueW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegQueryUSValueW,SHRegQueryUSValueW,1445 diff --git a/libc/nt/KernelBase/SHRegSetUSValueA.s b/libc/nt/KernelBase/SHRegSetUSValueA.s new file mode 100644 index 00000000..ed18e7f6 --- /dev/null +++ b/libc/nt/KernelBase/SHRegSetUSValueA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegSetUSValueA,SHRegSetUSValueA,1446 diff --git a/libc/nt/KernelBase/SHRegSetUSValueW.s b/libc/nt/KernelBase/SHRegSetUSValueW.s new file mode 100644 index 00000000..e77831fd --- /dev/null +++ b/libc/nt/KernelBase/SHRegSetUSValueW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegSetUSValueW,SHRegSetUSValueW,1447 diff --git a/libc/nt/KernelBase/SHRegWriteUSValueA.s b/libc/nt/KernelBase/SHRegWriteUSValueA.s new file mode 100644 index 00000000..d35efa23 --- /dev/null +++ b/libc/nt/KernelBase/SHRegWriteUSValueA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegWriteUSValueA,SHRegWriteUSValueA,1448 diff --git a/libc/nt/KernelBase/SHRegWriteUSValueW.s b/libc/nt/KernelBase/SHRegWriteUSValueW.s new file mode 100644 index 00000000..f9b3763e --- /dev/null +++ b/libc/nt/KernelBase/SHRegWriteUSValueW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHRegWriteUSValueW,SHRegWriteUSValueW,1449 diff --git a/libc/nt/KernelBase/SHTruncateString.s b/libc/nt/KernelBase/SHTruncateString.s new file mode 100644 index 00000000..c671a573 --- /dev/null +++ b/libc/nt/KernelBase/SHTruncateString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SHTruncateString,SHTruncateString,1450 diff --git a/libc/nt/KernelBase/SaveAlternatePackageRootPath.s b/libc/nt/KernelBase/SaveAlternatePackageRootPath.s new file mode 100644 index 00000000..d86459a9 --- /dev/null +++ b/libc/nt/KernelBase/SaveAlternatePackageRootPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SaveAlternatePackageRootPath,SaveAlternatePackageRootPath,1451 diff --git a/libc/nt/KernelBase/SaveStateRootFolderPath.s b/libc/nt/KernelBase/SaveStateRootFolderPath.s new file mode 100644 index 00000000..bed7d45a --- /dev/null +++ b/libc/nt/KernelBase/SaveStateRootFolderPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SaveStateRootFolderPath,SaveStateRootFolderPath,1452 diff --git a/libc/nt/KernelBase/ScrollConsoleScreenBufferA.s b/libc/nt/KernelBase/ScrollConsoleScreenBufferA.s new file mode 100644 index 00000000..014a0c7a --- /dev/null +++ b/libc/nt/KernelBase/ScrollConsoleScreenBufferA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ScrollConsoleScreenBufferA,ScrollConsoleScreenBufferA,1453 diff --git a/libc/nt/KernelBase/ScrollConsoleScreenBufferW.s b/libc/nt/KernelBase/ScrollConsoleScreenBufferW.s new file mode 100644 index 00000000..8e42c16c --- /dev/null +++ b/libc/nt/KernelBase/ScrollConsoleScreenBufferW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ScrollConsoleScreenBufferW,ScrollConsoleScreenBufferW,1454 diff --git a/libc/nt/KernelBase/SearchPathA.s b/libc/nt/KernelBase/SearchPathA.s new file mode 100644 index 00000000..daa91c2b --- /dev/null +++ b/libc/nt/KernelBase/SearchPathA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SearchPathA,SearchPathA,1455 diff --git a/libc/nt/KernelBase/SearchPathW.s b/libc/nt/KernelBase/SearchPathW.s new file mode 100644 index 00000000..60c7d63b --- /dev/null +++ b/libc/nt/KernelBase/SearchPathW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SearchPathW,SearchPathW,1456 diff --git a/libc/nt/KernelBase/SetAclInformation.s b/libc/nt/KernelBase/SetAclInformation.s new file mode 100644 index 00000000..613f9ec0 --- /dev/null +++ b/libc/nt/KernelBase/SetAclInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetAclInformation,SetAclInformation,1457 diff --git a/libc/nt/KernelBase/SetCachedSigningLevel.s b/libc/nt/KernelBase/SetCachedSigningLevel.s new file mode 100644 index 00000000..9835881a --- /dev/null +++ b/libc/nt/KernelBase/SetCachedSigningLevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetCachedSigningLevel,SetCachedSigningLevel,1458 diff --git a/libc/nt/KernelBase/SetCalendarInfoW.s b/libc/nt/KernelBase/SetCalendarInfoW.s new file mode 100644 index 00000000..e098cafc --- /dev/null +++ b/libc/nt/KernelBase/SetCalendarInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetCalendarInfoW,SetCalendarInfoW,1459 diff --git a/libc/nt/KernelBase/SetClientDynamicTimeZoneInformation.s b/libc/nt/KernelBase/SetClientDynamicTimeZoneInformation.s new file mode 100644 index 00000000..fd64e510 --- /dev/null +++ b/libc/nt/KernelBase/SetClientDynamicTimeZoneInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetClientDynamicTimeZoneInformation,SetClientDynamicTimeZoneInformation,1460 diff --git a/libc/nt/KernelBase/SetClientTimeZoneInformation.s b/libc/nt/KernelBase/SetClientTimeZoneInformation.s new file mode 100644 index 00000000..724d1e46 --- /dev/null +++ b/libc/nt/KernelBase/SetClientTimeZoneInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetClientTimeZoneInformation,SetClientTimeZoneInformation,1461 diff --git a/libc/nt/KernelBase/SetCommBreak.s b/libc/nt/KernelBase/SetCommBreak.s new file mode 100644 index 00000000..1437160f --- /dev/null +++ b/libc/nt/KernelBase/SetCommBreak.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetCommBreak,SetCommBreak,1462 diff --git a/libc/nt/KernelBase/SetCommConfig.s b/libc/nt/KernelBase/SetCommConfig.s new file mode 100644 index 00000000..e1b7e99a --- /dev/null +++ b/libc/nt/KernelBase/SetCommConfig.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetCommConfig,SetCommConfig,1463 diff --git a/libc/nt/KernelBase/SetCommMask.s b/libc/nt/KernelBase/SetCommMask.s new file mode 100644 index 00000000..05bf831c --- /dev/null +++ b/libc/nt/KernelBase/SetCommMask.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetCommMask,SetCommMask,1464 diff --git a/libc/nt/KernelBase/SetCommState.s b/libc/nt/KernelBase/SetCommState.s new file mode 100644 index 00000000..b9439f93 --- /dev/null +++ b/libc/nt/KernelBase/SetCommState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetCommState,SetCommState,1465 diff --git a/libc/nt/KernelBase/SetCommTimeouts.s b/libc/nt/KernelBase/SetCommTimeouts.s new file mode 100644 index 00000000..89b1d9be --- /dev/null +++ b/libc/nt/KernelBase/SetCommTimeouts.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetCommTimeouts,SetCommTimeouts,1466 diff --git a/libc/nt/KernelBase/SetComputerNameA.s b/libc/nt/KernelBase/SetComputerNameA.s new file mode 100644 index 00000000..c3e38363 --- /dev/null +++ b/libc/nt/KernelBase/SetComputerNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetComputerNameA,SetComputerNameA,1467 diff --git a/libc/nt/KernelBase/SetComputerNameEx2W.s b/libc/nt/KernelBase/SetComputerNameEx2W.s new file mode 100644 index 00000000..f96bfc2d --- /dev/null +++ b/libc/nt/KernelBase/SetComputerNameEx2W.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetComputerNameEx2W,SetComputerNameEx2W,1468 diff --git a/libc/nt/KernelBase/SetComputerNameExA.s b/libc/nt/KernelBase/SetComputerNameExA.s new file mode 100644 index 00000000..0306ddd5 --- /dev/null +++ b/libc/nt/KernelBase/SetComputerNameExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetComputerNameExA,SetComputerNameExA,1469 diff --git a/libc/nt/KernelBase/SetComputerNameExW.s b/libc/nt/KernelBase/SetComputerNameExW.s new file mode 100644 index 00000000..6bc8ad4d --- /dev/null +++ b/libc/nt/KernelBase/SetComputerNameExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetComputerNameExW,SetComputerNameExW,1470 diff --git a/libc/nt/KernelBase/SetComputerNameW.s b/libc/nt/KernelBase/SetComputerNameW.s new file mode 100644 index 00000000..4d35ffba --- /dev/null +++ b/libc/nt/KernelBase/SetComputerNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetComputerNameW,SetComputerNameW,1471 diff --git a/libc/nt/KernelBase/SetConsoleActiveScreenBuffer.s b/libc/nt/KernelBase/SetConsoleActiveScreenBuffer.s new file mode 100644 index 00000000..18a2b6d2 --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleActiveScreenBuffer.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleActiveScreenBuffer,SetConsoleActiveScreenBuffer,1472 + + .text.windows +SetConsoleActiveScreenBuffer: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_SetConsoleActiveScreenBuffer(%rip) + leave + ret + .endfn SetConsoleActiveScreenBuffer,globl + .previous diff --git a/libc/nt/KernelBase/SetConsoleCP.s b/libc/nt/KernelBase/SetConsoleCP.s new file mode 100644 index 00000000..6ebd6b88 --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleCP.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleCP,SetConsoleCP,1473 + + .text.windows +SetConsoleCP: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_SetConsoleCP(%rip) + leave + ret + .endfn SetConsoleCP,globl + .previous diff --git a/libc/nt/KernelBase/SetConsoleCtrlHandler.s b/libc/nt/KernelBase/SetConsoleCtrlHandler.s new file mode 100644 index 00000000..d22cbcf7 --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleCtrlHandler.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleCtrlHandler,SetConsoleCtrlHandler,1474 + + .text.windows +SetConsoleCtrlHandler: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetConsoleCtrlHandler(%rip),%rax + jmp __sysv2nt + .endfn SetConsoleCtrlHandler,globl + .previous diff --git a/libc/nt/KernelBase/SetConsoleCursorInfo.s b/libc/nt/KernelBase/SetConsoleCursorInfo.s new file mode 100644 index 00000000..ccd2b23c --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleCursorInfo.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleCursorInfo,SetConsoleCursorInfo,1475 + + .text.windows +SetConsoleCursorInfo: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetConsoleCursorInfo(%rip),%rax + jmp __sysv2nt + .endfn SetConsoleCursorInfo,globl + .previous diff --git a/libc/nt/KernelBase/SetConsoleCursorPosition.s b/libc/nt/KernelBase/SetConsoleCursorPosition.s new file mode 100644 index 00000000..8603d3dd --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleCursorPosition.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleCursorPosition,SetConsoleCursorPosition,1476 + + .text.windows +SetConsoleCursorPosition: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetConsoleCursorPosition(%rip),%rax + jmp __sysv2nt + .endfn SetConsoleCursorPosition,globl + .previous diff --git a/libc/nt/KernelBase/SetConsoleDisplayMode.s b/libc/nt/KernelBase/SetConsoleDisplayMode.s new file mode 100644 index 00000000..9065f760 --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleDisplayMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleDisplayMode,SetConsoleDisplayMode,1477 diff --git a/libc/nt/KernelBase/SetConsoleHistoryInfo.s b/libc/nt/KernelBase/SetConsoleHistoryInfo.s new file mode 100644 index 00000000..be717d87 --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleHistoryInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleHistoryInfo,SetConsoleHistoryInfo,1478 diff --git a/libc/nt/KernelBase/SetConsoleInputExeNameA.s b/libc/nt/KernelBase/SetConsoleInputExeNameA.s new file mode 100644 index 00000000..4bbaa575 --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleInputExeNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleInputExeNameA,SetConsoleInputExeNameA,1479 diff --git a/libc/nt/KernelBase/SetConsoleInputExeNameW.s b/libc/nt/KernelBase/SetConsoleInputExeNameW.s new file mode 100644 index 00000000..0713e934 --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleInputExeNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleInputExeNameW,SetConsoleInputExeNameW,1480 diff --git a/libc/nt/KernelBase/SetConsoleMode.s b/libc/nt/KernelBase/SetConsoleMode.s new file mode 100644 index 00000000..1c38cbd4 --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleMode.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleMode,SetConsoleMode,1481 + + .text.windows +SetConsoleMode: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetConsoleMode(%rip),%rax + jmp __sysv2nt + .endfn SetConsoleMode,globl + .previous diff --git a/libc/nt/KernelBase/SetConsoleNumberOfCommandsA.s b/libc/nt/KernelBase/SetConsoleNumberOfCommandsA.s new file mode 100644 index 00000000..bd4a5b9c --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleNumberOfCommandsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleNumberOfCommandsA,SetConsoleNumberOfCommandsA,1482 diff --git a/libc/nt/KernelBase/SetConsoleNumberOfCommandsW.s b/libc/nt/KernelBase/SetConsoleNumberOfCommandsW.s new file mode 100644 index 00000000..68c0eb59 --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleNumberOfCommandsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleNumberOfCommandsW,SetConsoleNumberOfCommandsW,1483 diff --git a/libc/nt/KernelBase/SetConsoleOutputCP.s b/libc/nt/KernelBase/SetConsoleOutputCP.s new file mode 100644 index 00000000..e15eb8a2 --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleOutputCP.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleOutputCP,SetConsoleOutputCP,1484 + + .text.windows +SetConsoleOutputCP: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_SetConsoleOutputCP(%rip) + leave + ret + .endfn SetConsoleOutputCP,globl + .previous diff --git a/libc/nt/KernelBase/SetConsoleScreenBufferInfoEx.s b/libc/nt/KernelBase/SetConsoleScreenBufferInfoEx.s new file mode 100644 index 00000000..ce06f4c9 --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleScreenBufferInfoEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleScreenBufferInfoEx,SetConsoleScreenBufferInfoEx,1485 + + .text.windows +SetConsoleScreenBufferInfoEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetConsoleScreenBufferInfoEx(%rip),%rax + jmp __sysv2nt + .endfn SetConsoleScreenBufferInfoEx,globl + .previous diff --git a/libc/nt/KernelBase/SetConsoleScreenBufferSize.s b/libc/nt/KernelBase/SetConsoleScreenBufferSize.s new file mode 100644 index 00000000..07caec74 --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleScreenBufferSize.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleScreenBufferSize,SetConsoleScreenBufferSize,1486 + + .text.windows +SetConsoleScreenBufferSize: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetConsoleScreenBufferSize(%rip),%rax + jmp __sysv2nt + .endfn SetConsoleScreenBufferSize,globl + .previous diff --git a/libc/nt/KernelBase/SetConsoleTextAttribute.s b/libc/nt/KernelBase/SetConsoleTextAttribute.s new file mode 100644 index 00000000..22002d2a --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleTextAttribute.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleTextAttribute,SetConsoleTextAttribute,1487 diff --git a/libc/nt/KernelBase/SetConsoleTitleA.s b/libc/nt/KernelBase/SetConsoleTitleA.s new file mode 100644 index 00000000..0cb1642f --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleTitleA.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleTitleA,SetConsoleTitleA,1488 + + .text.windows +SetConsoleTitleA: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_SetConsoleTitleA(%rip) + leave + ret + .endfn SetConsoleTitleA,globl + .previous diff --git a/libc/nt/KernelBase/SetConsoleTitleW.s b/libc/nt/KernelBase/SetConsoleTitleW.s new file mode 100644 index 00000000..bf7f20c2 --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleTitleW.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleTitleW,SetConsoleTitleW,1489 + + .text.windows +SetConsoleTitle: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_SetConsoleTitleW(%rip) + leave + ret + .endfn SetConsoleTitle,globl + .previous diff --git a/libc/nt/KernelBase/SetConsoleWindowInfo.s b/libc/nt/KernelBase/SetConsoleWindowInfo.s new file mode 100644 index 00000000..2969fa11 --- /dev/null +++ b/libc/nt/KernelBase/SetConsoleWindowInfo.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetConsoleWindowInfo,SetConsoleWindowInfo,1490 + + .text.windows +SetConsoleWindowInfo: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetConsoleWindowInfo(%rip),%rax + jmp __sysv2nt + .endfn SetConsoleWindowInfo,globl + .previous diff --git a/libc/nt/KernelBase/SetCurrentConsoleFontEx.s b/libc/nt/KernelBase/SetCurrentConsoleFontEx.s new file mode 100644 index 00000000..1fc8f046 --- /dev/null +++ b/libc/nt/KernelBase/SetCurrentConsoleFontEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetCurrentConsoleFontEx,SetCurrentConsoleFontEx,1492 diff --git a/libc/nt/KernelBase/SetCurrentDirectoryA.s b/libc/nt/KernelBase/SetCurrentDirectoryA.s new file mode 100644 index 00000000..2424cfe1 --- /dev/null +++ b/libc/nt/KernelBase/SetCurrentDirectoryA.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetCurrentDirectoryA,SetCurrentDirectoryA,1493 + + .text.windows +SetCurrentDirectoryA: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_SetCurrentDirectoryA(%rip) + leave + ret + .endfn SetCurrentDirectoryA,globl + .previous diff --git a/libc/nt/KernelBase/SetCurrentDirectoryW.s b/libc/nt/KernelBase/SetCurrentDirectoryW.s new file mode 100644 index 00000000..6b242741 --- /dev/null +++ b/libc/nt/KernelBase/SetCurrentDirectoryW.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetCurrentDirectoryW,SetCurrentDirectoryW,1494 + + .text.windows +SetCurrentDirectory: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_SetCurrentDirectoryW(%rip) + leave + ret + .endfn SetCurrentDirectory,globl + .previous diff --git a/libc/nt/KernelBase/SetDefaultDllDirectories.s b/libc/nt/KernelBase/SetDefaultDllDirectories.s new file mode 100644 index 00000000..657facef --- /dev/null +++ b/libc/nt/KernelBase/SetDefaultDllDirectories.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetDefaultDllDirectories,SetDefaultDllDirectories,1495 + + .text.windows +SetDefaultDllDirectories: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_SetDefaultDllDirectories(%rip) + leave + ret + .endfn SetDefaultDllDirectories,globl + .previous diff --git a/libc/nt/KernelBase/SetDynamicTimeZoneInformation.s b/libc/nt/KernelBase/SetDynamicTimeZoneInformation.s new file mode 100644 index 00000000..b7bcfe25 --- /dev/null +++ b/libc/nt/KernelBase/SetDynamicTimeZoneInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetDynamicTimeZoneInformation,SetDynamicTimeZoneInformation,1496 diff --git a/libc/nt/KernelBase/SetEndOfFile.s b/libc/nt/KernelBase/SetEndOfFile.s new file mode 100644 index 00000000..06f4d48a --- /dev/null +++ b/libc/nt/KernelBase/SetEndOfFile.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetEndOfFile,SetEndOfFile,1497 + + .text.windows +SetEndOfFile: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_SetEndOfFile(%rip) + leave + ret + .endfn SetEndOfFile,globl + .previous diff --git a/libc/nt/KernelBase/SetEnvironmentStringsW.s b/libc/nt/KernelBase/SetEnvironmentStringsW.s new file mode 100644 index 00000000..93ca27db --- /dev/null +++ b/libc/nt/KernelBase/SetEnvironmentStringsW.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetEnvironmentStringsW,SetEnvironmentStringsW,1498 + + .text.windows +SetEnvironmentStrings: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_SetEnvironmentStringsW(%rip) + leave + ret + .endfn SetEnvironmentStrings,globl + .previous diff --git a/libc/nt/KernelBase/SetEnvironmentVariableA.s b/libc/nt/KernelBase/SetEnvironmentVariableA.s new file mode 100644 index 00000000..347d04ac --- /dev/null +++ b/libc/nt/KernelBase/SetEnvironmentVariableA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetEnvironmentVariableA,SetEnvironmentVariableA,1499 + + .text.windows +SetEnvironmentVariableA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetEnvironmentVariableA(%rip),%rax + jmp __sysv2nt + .endfn SetEnvironmentVariableA,globl + .previous diff --git a/libc/nt/KernelBase/SetEnvironmentVariableW.s b/libc/nt/KernelBase/SetEnvironmentVariableW.s new file mode 100644 index 00000000..4203c1fc --- /dev/null +++ b/libc/nt/KernelBase/SetEnvironmentVariableW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetEnvironmentVariableW,SetEnvironmentVariableW,1500 + + .text.windows +SetEnvironmentVariable: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetEnvironmentVariableW(%rip),%rax + jmp __sysv2nt + .endfn SetEnvironmentVariable,globl + .previous diff --git a/libc/nt/KernelBase/SetErrorMode.s b/libc/nt/KernelBase/SetErrorMode.s new file mode 100644 index 00000000..8a5758b2 --- /dev/null +++ b/libc/nt/KernelBase/SetErrorMode.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetErrorMode,SetErrorMode,1501 + + .text.windows +SetErrorMode: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_SetErrorMode(%rip) + leave + ret + .endfn SetErrorMode,globl + .previous diff --git a/libc/nt/KernelBase/SetEvent.s b/libc/nt/KernelBase/SetEvent.s new file mode 100644 index 00000000..2f0de3aa --- /dev/null +++ b/libc/nt/KernelBase/SetEvent.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetEvent,SetEvent,1502 + + .text.windows +SetEvent: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_SetEvent(%rip) + leave + ret + .endfn SetEvent,globl + .previous diff --git a/libc/nt/KernelBase/SetExtensionProperty.s b/libc/nt/KernelBase/SetExtensionProperty.s new file mode 100644 index 00000000..e0dcf432 --- /dev/null +++ b/libc/nt/KernelBase/SetExtensionProperty.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetExtensionProperty,SetExtensionProperty,1504 diff --git a/libc/nt/KernelBase/SetFileApisToANSI.s b/libc/nt/KernelBase/SetFileApisToANSI.s new file mode 100644 index 00000000..1886e8b4 --- /dev/null +++ b/libc/nt/KernelBase/SetFileApisToANSI.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetFileApisToANSI,SetFileApisToANSI,1505 diff --git a/libc/nt/KernelBase/SetFileApisToOEM.s b/libc/nt/KernelBase/SetFileApisToOEM.s new file mode 100644 index 00000000..7eacb066 --- /dev/null +++ b/libc/nt/KernelBase/SetFileApisToOEM.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetFileApisToOEM,SetFileApisToOEM,1506 diff --git a/libc/nt/KernelBase/SetFileAttributesA.s b/libc/nt/KernelBase/SetFileAttributesA.s new file mode 100644 index 00000000..22fddfe0 --- /dev/null +++ b/libc/nt/KernelBase/SetFileAttributesA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetFileAttributesA,SetFileAttributesA,1507 + + .text.windows +SetFileAttributesA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetFileAttributesA(%rip),%rax + jmp __sysv2nt + .endfn SetFileAttributesA,globl + .previous diff --git a/libc/nt/KernelBase/SetFileAttributesW.s b/libc/nt/KernelBase/SetFileAttributesW.s new file mode 100644 index 00000000..d49a586b --- /dev/null +++ b/libc/nt/KernelBase/SetFileAttributesW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetFileAttributesW,SetFileAttributesW,1508 + + .text.windows +SetFileAttributes: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetFileAttributesW(%rip),%rax + jmp __sysv2nt + .endfn SetFileAttributes,globl + .previous diff --git a/libc/nt/KernelBase/SetFileInformationByHandle.s b/libc/nt/KernelBase/SetFileInformationByHandle.s new file mode 100644 index 00000000..75e1e172 --- /dev/null +++ b/libc/nt/KernelBase/SetFileInformationByHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetFileInformationByHandle,SetFileInformationByHandle,1509 diff --git a/libc/nt/KernelBase/SetFileIoOverlappedRange.s b/libc/nt/KernelBase/SetFileIoOverlappedRange.s new file mode 100644 index 00000000..dc3a4c56 --- /dev/null +++ b/libc/nt/KernelBase/SetFileIoOverlappedRange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetFileIoOverlappedRange,SetFileIoOverlappedRange,1510 diff --git a/libc/nt/KernelBase/SetFilePointer.s b/libc/nt/KernelBase/SetFilePointer.s new file mode 100644 index 00000000..ddad6ef3 --- /dev/null +++ b/libc/nt/KernelBase/SetFilePointer.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetFilePointer,SetFilePointer,1511 + + .text.windows +SetFilePointer: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetFilePointer(%rip),%rax + jmp __sysv2nt + .endfn SetFilePointer,globl + .previous diff --git a/libc/nt/KernelBase/SetFilePointerEx.s b/libc/nt/KernelBase/SetFilePointerEx.s new file mode 100644 index 00000000..634007bc --- /dev/null +++ b/libc/nt/KernelBase/SetFilePointerEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetFilePointerEx,SetFilePointerEx,1512 + + .text.windows +SetFilePointerEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetFilePointerEx(%rip),%rax + jmp __sysv2nt + .endfn SetFilePointerEx,globl + .previous diff --git a/libc/nt/KernelBase/SetFileSecurityW.s b/libc/nt/KernelBase/SetFileSecurityW.s new file mode 100644 index 00000000..d0ece0b5 --- /dev/null +++ b/libc/nt/KernelBase/SetFileSecurityW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetFileSecurityW,SetFileSecurityW,1513 diff --git a/libc/nt/KernelBase/SetFileTime.s b/libc/nt/KernelBase/SetFileTime.s new file mode 100644 index 00000000..2d57d1f5 --- /dev/null +++ b/libc/nt/KernelBase/SetFileTime.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetFileTime,SetFileTime,1514 + + .text.windows +SetFileTime: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetFileTime(%rip),%rax + jmp __sysv2nt + .endfn SetFileTime,globl + .previous diff --git a/libc/nt/KernelBase/SetFileValidData.s b/libc/nt/KernelBase/SetFileValidData.s new file mode 100644 index 00000000..84b1302a --- /dev/null +++ b/libc/nt/KernelBase/SetFileValidData.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetFileValidData,SetFileValidData,1515 + + .text.windows +SetFileValidData: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetFileValidData(%rip),%rax + jmp __sysv2nt + .endfn SetFileValidData,globl + .previous diff --git a/libc/nt/KernelBase/SetHandleCount.s b/libc/nt/KernelBase/SetHandleCount.s new file mode 100644 index 00000000..7727a81f --- /dev/null +++ b/libc/nt/KernelBase/SetHandleCount.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetHandleCount,SetHandleCount,1516 + + .text.windows +SetHandleCount: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_SetHandleCount(%rip) + leave + ret + .endfn SetHandleCount,globl + .previous diff --git a/libc/nt/KernelBase/SetHandleInformation.s b/libc/nt/KernelBase/SetHandleInformation.s new file mode 100644 index 00000000..032c3787 --- /dev/null +++ b/libc/nt/KernelBase/SetHandleInformation.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetHandleInformation,SetHandleInformation,1517 + + .text.windows +SetHandleInformation: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetHandleInformation(%rip),%rax + jmp __sysv2nt + .endfn SetHandleInformation,globl + .previous diff --git a/libc/nt/KernelBase/SetIsDeveloperModeEnabled.s b/libc/nt/KernelBase/SetIsDeveloperModeEnabled.s new file mode 100644 index 00000000..cfe006c9 --- /dev/null +++ b/libc/nt/KernelBase/SetIsDeveloperModeEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetIsDeveloperModeEnabled,SetIsDeveloperModeEnabled,1518 diff --git a/libc/nt/KernelBase/SetIsSideloadingEnabled.s b/libc/nt/KernelBase/SetIsSideloadingEnabled.s new file mode 100644 index 00000000..3fe81c1f --- /dev/null +++ b/libc/nt/KernelBase/SetIsSideloadingEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetIsSideloadingEnabled,SetIsSideloadingEnabled,1519 diff --git a/libc/nt/KernelBase/SetKernelObjectSecurity.s b/libc/nt/KernelBase/SetKernelObjectSecurity.s new file mode 100644 index 00000000..4771dca4 --- /dev/null +++ b/libc/nt/KernelBase/SetKernelObjectSecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetKernelObjectSecurity,SetKernelObjectSecurity,1520 diff --git a/libc/nt/KernelBase/SetLastConsoleEventActive.s b/libc/nt/KernelBase/SetLastConsoleEventActive.s new file mode 100644 index 00000000..9f7c6ff9 --- /dev/null +++ b/libc/nt/KernelBase/SetLastConsoleEventActive.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetLastConsoleEventActive,SetLastConsoleEventActive,1521 diff --git a/libc/nt/KernelBase/SetLocalTime.s b/libc/nt/KernelBase/SetLocalTime.s new file mode 100644 index 00000000..49064a9f --- /dev/null +++ b/libc/nt/KernelBase/SetLocalTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetLocalTime,SetLocalTime,1523 diff --git a/libc/nt/KernelBase/SetLocaleInfoW.s b/libc/nt/KernelBase/SetLocaleInfoW.s new file mode 100644 index 00000000..971a6f12 --- /dev/null +++ b/libc/nt/KernelBase/SetLocaleInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetLocaleInfoW,SetLocaleInfoW,1524 diff --git a/libc/nt/KernelBase/SetNamedPipeHandleState.s b/libc/nt/KernelBase/SetNamedPipeHandleState.s new file mode 100644 index 00000000..e6ce4e9c --- /dev/null +++ b/libc/nt/KernelBase/SetNamedPipeHandleState.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetNamedPipeHandleState,SetNamedPipeHandleState,1525 + + .text.windows +SetNamedPipeHandleState: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetNamedPipeHandleState(%rip),%rax + jmp __sysv2nt + .endfn SetNamedPipeHandleState,globl + .previous diff --git a/libc/nt/KernelBase/SetPriorityClass.s b/libc/nt/KernelBase/SetPriorityClass.s new file mode 100644 index 00000000..e153fe85 --- /dev/null +++ b/libc/nt/KernelBase/SetPriorityClass.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetPriorityClass,SetPriorityClass,1526 + + .text.windows +SetPriorityClass: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetPriorityClass(%rip),%rax + jmp __sysv2nt + .endfn SetPriorityClass,globl + .previous diff --git a/libc/nt/KernelBase/SetPrivateObjectSecurity.s b/libc/nt/KernelBase/SetPrivateObjectSecurity.s new file mode 100644 index 00000000..9a6c9c48 --- /dev/null +++ b/libc/nt/KernelBase/SetPrivateObjectSecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetPrivateObjectSecurity,SetPrivateObjectSecurity,1527 diff --git a/libc/nt/KernelBase/SetPrivateObjectSecurityEx.s b/libc/nt/KernelBase/SetPrivateObjectSecurityEx.s new file mode 100644 index 00000000..2df77c63 --- /dev/null +++ b/libc/nt/KernelBase/SetPrivateObjectSecurityEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetPrivateObjectSecurityEx,SetPrivateObjectSecurityEx,1528 diff --git a/libc/nt/KernelBase/SetProcessAffinityUpdateMode.s b/libc/nt/KernelBase/SetProcessAffinityUpdateMode.s new file mode 100644 index 00000000..986c28e8 --- /dev/null +++ b/libc/nt/KernelBase/SetProcessAffinityUpdateMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetProcessAffinityUpdateMode,SetProcessAffinityUpdateMode,1529 diff --git a/libc/nt/KernelBase/SetProcessDefaultCpuSets.s b/libc/nt/KernelBase/SetProcessDefaultCpuSets.s new file mode 100644 index 00000000..d67f17b2 --- /dev/null +++ b/libc/nt/KernelBase/SetProcessDefaultCpuSets.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetProcessDefaultCpuSets,SetProcessDefaultCpuSets,1530 diff --git a/libc/nt/KernelBase/SetProcessGroupAffinity.s b/libc/nt/KernelBase/SetProcessGroupAffinity.s new file mode 100644 index 00000000..e183e31e --- /dev/null +++ b/libc/nt/KernelBase/SetProcessGroupAffinity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetProcessGroupAffinity,SetProcessGroupAffinity,1531 diff --git a/libc/nt/KernelBase/SetProcessInformation.s b/libc/nt/KernelBase/SetProcessInformation.s new file mode 100644 index 00000000..63908c32 --- /dev/null +++ b/libc/nt/KernelBase/SetProcessInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetProcessInformation,SetProcessInformation,1532 diff --git a/libc/nt/KernelBase/SetProcessMitigationPolicy.s b/libc/nt/KernelBase/SetProcessMitigationPolicy.s new file mode 100644 index 00000000..a6bb2946 --- /dev/null +++ b/libc/nt/KernelBase/SetProcessMitigationPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetProcessMitigationPolicy,SetProcessMitigationPolicy,1533 diff --git a/libc/nt/KernelBase/SetProcessPreferredUILanguages.s b/libc/nt/KernelBase/SetProcessPreferredUILanguages.s new file mode 100644 index 00000000..92541058 --- /dev/null +++ b/libc/nt/KernelBase/SetProcessPreferredUILanguages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetProcessPreferredUILanguages,SetProcessPreferredUILanguages,1534 diff --git a/libc/nt/KernelBase/SetProcessPriorityBoost.s b/libc/nt/KernelBase/SetProcessPriorityBoost.s new file mode 100644 index 00000000..0ad01405 --- /dev/null +++ b/libc/nt/KernelBase/SetProcessPriorityBoost.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetProcessPriorityBoost,SetProcessPriorityBoost,1535 + + .text.windows +SetProcessPriorityBoost: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetProcessPriorityBoost(%rip),%rax + jmp __sysv2nt + .endfn SetProcessPriorityBoost,globl + .previous diff --git a/libc/nt/KernelBase/SetProcessShutdownParameters.s b/libc/nt/KernelBase/SetProcessShutdownParameters.s new file mode 100644 index 00000000..fbd71de0 --- /dev/null +++ b/libc/nt/KernelBase/SetProcessShutdownParameters.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetProcessShutdownParameters,SetProcessShutdownParameters,1536 diff --git a/libc/nt/KernelBase/SetProcessValidCallTargets.s b/libc/nt/KernelBase/SetProcessValidCallTargets.s new file mode 100644 index 00000000..7824b56a --- /dev/null +++ b/libc/nt/KernelBase/SetProcessValidCallTargets.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetProcessValidCallTargets,SetProcessValidCallTargets,1537 diff --git a/libc/nt/KernelBase/SetProcessWorkingSetSizeEx.s b/libc/nt/KernelBase/SetProcessWorkingSetSizeEx.s new file mode 100644 index 00000000..72c4a771 --- /dev/null +++ b/libc/nt/KernelBase/SetProcessWorkingSetSizeEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetProcessWorkingSetSizeEx,SetProcessWorkingSetSizeEx,1538 + + .text.windows +SetProcessWorkingSetSizeEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetProcessWorkingSetSizeEx(%rip),%rax + jmp __sysv2nt + .endfn SetProcessWorkingSetSizeEx,globl + .previous diff --git a/libc/nt/KernelBase/SetProtectedPolicy.s b/libc/nt/KernelBase/SetProtectedPolicy.s new file mode 100644 index 00000000..43d9fd10 --- /dev/null +++ b/libc/nt/KernelBase/SetProtectedPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetProtectedPolicy,SetProtectedPolicy,1539 diff --git a/libc/nt/KernelBase/SetProtocolProperty.s b/libc/nt/KernelBase/SetProtocolProperty.s new file mode 100644 index 00000000..3cd9e7db --- /dev/null +++ b/libc/nt/KernelBase/SetProtocolProperty.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetProtocolProperty,SetProtocolProperty,1540 diff --git a/libc/nt/KernelBase/SetRoamingLastObservedChangeTime.s b/libc/nt/KernelBase/SetRoamingLastObservedChangeTime.s new file mode 100644 index 00000000..df0f447b --- /dev/null +++ b/libc/nt/KernelBase/SetRoamingLastObservedChangeTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetRoamingLastObservedChangeTime,SetRoamingLastObservedChangeTime,1541 diff --git a/libc/nt/KernelBase/SetSecurityAccessMask.s b/libc/nt/KernelBase/SetSecurityAccessMask.s new file mode 100644 index 00000000..a8dc3b63 --- /dev/null +++ b/libc/nt/KernelBase/SetSecurityAccessMask.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetSecurityAccessMask,SetSecurityAccessMask,1542 diff --git a/libc/nt/KernelBase/SetSecurityDescriptorControl.s b/libc/nt/KernelBase/SetSecurityDescriptorControl.s new file mode 100644 index 00000000..48be919c --- /dev/null +++ b/libc/nt/KernelBase/SetSecurityDescriptorControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetSecurityDescriptorControl,SetSecurityDescriptorControl,1543 diff --git a/libc/nt/KernelBase/SetSecurityDescriptorDacl.s b/libc/nt/KernelBase/SetSecurityDescriptorDacl.s new file mode 100644 index 00000000..7e27c22e --- /dev/null +++ b/libc/nt/KernelBase/SetSecurityDescriptorDacl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetSecurityDescriptorDacl,SetSecurityDescriptorDacl,1544 diff --git a/libc/nt/KernelBase/SetSecurityDescriptorGroup.s b/libc/nt/KernelBase/SetSecurityDescriptorGroup.s new file mode 100644 index 00000000..aead935b --- /dev/null +++ b/libc/nt/KernelBase/SetSecurityDescriptorGroup.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetSecurityDescriptorGroup,SetSecurityDescriptorGroup,1545 diff --git a/libc/nt/KernelBase/SetSecurityDescriptorOwner.s b/libc/nt/KernelBase/SetSecurityDescriptorOwner.s new file mode 100644 index 00000000..80f07a89 --- /dev/null +++ b/libc/nt/KernelBase/SetSecurityDescriptorOwner.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetSecurityDescriptorOwner,SetSecurityDescriptorOwner,1546 diff --git a/libc/nt/KernelBase/SetSecurityDescriptorRMControl.s b/libc/nt/KernelBase/SetSecurityDescriptorRMControl.s new file mode 100644 index 00000000..4bdded83 --- /dev/null +++ b/libc/nt/KernelBase/SetSecurityDescriptorRMControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetSecurityDescriptorRMControl,SetSecurityDescriptorRMControl,1547 diff --git a/libc/nt/KernelBase/SetSecurityDescriptorSacl.s b/libc/nt/KernelBase/SetSecurityDescriptorSacl.s new file mode 100644 index 00000000..1d6ebd8e --- /dev/null +++ b/libc/nt/KernelBase/SetSecurityDescriptorSacl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetSecurityDescriptorSacl,SetSecurityDescriptorSacl,1548 diff --git a/libc/nt/KernelBase/SetStateVersion.s b/libc/nt/KernelBase/SetStateVersion.s new file mode 100644 index 00000000..0503c5c9 --- /dev/null +++ b/libc/nt/KernelBase/SetStateVersion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetStateVersion,SetStateVersion,1549 diff --git a/libc/nt/KernelBase/SetStdHandle.s b/libc/nt/KernelBase/SetStdHandle.s new file mode 100644 index 00000000..79a9bcb3 --- /dev/null +++ b/libc/nt/KernelBase/SetStdHandle.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetStdHandle,SetStdHandle,1550 + + .text.windows +SetStdHandle: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetStdHandle(%rip),%rax + jmp __sysv2nt + .endfn SetStdHandle,globl + .previous diff --git a/libc/nt/KernelBase/SetStdHandleEx.s b/libc/nt/KernelBase/SetStdHandleEx.s new file mode 100644 index 00000000..b9c36779 --- /dev/null +++ b/libc/nt/KernelBase/SetStdHandleEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetStdHandleEx,SetStdHandleEx,1551 diff --git a/libc/nt/KernelBase/SetSystemFileCacheSize.s b/libc/nt/KernelBase/SetSystemFileCacheSize.s new file mode 100644 index 00000000..42890418 --- /dev/null +++ b/libc/nt/KernelBase/SetSystemFileCacheSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetSystemFileCacheSize,SetSystemFileCacheSize,1552 diff --git a/libc/nt/KernelBase/SetSystemTime.s b/libc/nt/KernelBase/SetSystemTime.s new file mode 100644 index 00000000..b0e37a4a --- /dev/null +++ b/libc/nt/KernelBase/SetSystemTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetSystemTime,SetSystemTime,1553 diff --git a/libc/nt/KernelBase/SetSystemTimeAdjustment.s b/libc/nt/KernelBase/SetSystemTimeAdjustment.s new file mode 100644 index 00000000..e48eae0e --- /dev/null +++ b/libc/nt/KernelBase/SetSystemTimeAdjustment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetSystemTimeAdjustment,SetSystemTimeAdjustment,1554 diff --git a/libc/nt/KernelBase/SetSystemTimeAdjustmentPrecise.s b/libc/nt/KernelBase/SetSystemTimeAdjustmentPrecise.s new file mode 100644 index 00000000..ca9ba59f --- /dev/null +++ b/libc/nt/KernelBase/SetSystemTimeAdjustmentPrecise.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetSystemTimeAdjustmentPrecise,SetSystemTimeAdjustmentPrecise,1555 diff --git a/libc/nt/KernelBase/SetThreadContext.s b/libc/nt/KernelBase/SetThreadContext.s new file mode 100644 index 00000000..38bf072e --- /dev/null +++ b/libc/nt/KernelBase/SetThreadContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetThreadContext,SetThreadContext,1556 diff --git a/libc/nt/KernelBase/SetThreadDescription.s b/libc/nt/KernelBase/SetThreadDescription.s new file mode 100644 index 00000000..655519ed --- /dev/null +++ b/libc/nt/KernelBase/SetThreadDescription.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetThreadDescription,SetThreadDescription,1557 diff --git a/libc/nt/KernelBase/SetThreadErrorMode.s b/libc/nt/KernelBase/SetThreadErrorMode.s new file mode 100644 index 00000000..75fe4a68 --- /dev/null +++ b/libc/nt/KernelBase/SetThreadErrorMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetThreadErrorMode,SetThreadErrorMode,1558 diff --git a/libc/nt/KernelBase/SetThreadGroupAffinity.s b/libc/nt/KernelBase/SetThreadGroupAffinity.s new file mode 100644 index 00000000..388a09ee --- /dev/null +++ b/libc/nt/KernelBase/SetThreadGroupAffinity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetThreadGroupAffinity,SetThreadGroupAffinity,1559 diff --git a/libc/nt/KernelBase/SetThreadIdealProcessor.s b/libc/nt/KernelBase/SetThreadIdealProcessor.s new file mode 100644 index 00000000..c3e385fb --- /dev/null +++ b/libc/nt/KernelBase/SetThreadIdealProcessor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetThreadIdealProcessor,SetThreadIdealProcessor,1560 diff --git a/libc/nt/KernelBase/SetThreadIdealProcessorEx.s b/libc/nt/KernelBase/SetThreadIdealProcessorEx.s new file mode 100644 index 00000000..57f93436 --- /dev/null +++ b/libc/nt/KernelBase/SetThreadIdealProcessorEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetThreadIdealProcessorEx,SetThreadIdealProcessorEx,1561 diff --git a/libc/nt/KernelBase/SetThreadInformation.s b/libc/nt/KernelBase/SetThreadInformation.s new file mode 100644 index 00000000..fa83895c --- /dev/null +++ b/libc/nt/KernelBase/SetThreadInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetThreadInformation,SetThreadInformation,1562 diff --git a/libc/nt/KernelBase/SetThreadLocale.s b/libc/nt/KernelBase/SetThreadLocale.s new file mode 100644 index 00000000..295ba1ee --- /dev/null +++ b/libc/nt/KernelBase/SetThreadLocale.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetThreadLocale,SetThreadLocale,1563 diff --git a/libc/nt/KernelBase/SetThreadPreferredUILanguages.s b/libc/nt/KernelBase/SetThreadPreferredUILanguages.s new file mode 100644 index 00000000..19da81eb --- /dev/null +++ b/libc/nt/KernelBase/SetThreadPreferredUILanguages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetThreadPreferredUILanguages,SetThreadPreferredUILanguages,1564 diff --git a/libc/nt/KernelBase/SetThreadPriority.s b/libc/nt/KernelBase/SetThreadPriority.s new file mode 100644 index 00000000..361b38c5 --- /dev/null +++ b/libc/nt/KernelBase/SetThreadPriority.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetThreadPriority,SetThreadPriority,1565 + + .text.windows +SetThreadPriority: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetThreadPriority(%rip),%rax + jmp __sysv2nt + .endfn SetThreadPriority,globl + .previous diff --git a/libc/nt/KernelBase/SetThreadPriorityBoost.s b/libc/nt/KernelBase/SetThreadPriorityBoost.s new file mode 100644 index 00000000..3776a5f6 --- /dev/null +++ b/libc/nt/KernelBase/SetThreadPriorityBoost.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetThreadPriorityBoost,SetThreadPriorityBoost,1566 + + .text.windows +SetThreadPriorityBoost: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetThreadPriorityBoost(%rip),%rax + jmp __sysv2nt + .endfn SetThreadPriorityBoost,globl + .previous diff --git a/libc/nt/KernelBase/SetThreadSelectedCpuSets.s b/libc/nt/KernelBase/SetThreadSelectedCpuSets.s new file mode 100644 index 00000000..5db609a7 --- /dev/null +++ b/libc/nt/KernelBase/SetThreadSelectedCpuSets.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetThreadSelectedCpuSets,SetThreadSelectedCpuSets,1567 diff --git a/libc/nt/KernelBase/SetThreadStackGuarantee.s b/libc/nt/KernelBase/SetThreadStackGuarantee.s new file mode 100644 index 00000000..a3923584 --- /dev/null +++ b/libc/nt/KernelBase/SetThreadStackGuarantee.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetThreadStackGuarantee,SetThreadStackGuarantee,1568 diff --git a/libc/nt/KernelBase/SetThreadToken.s b/libc/nt/KernelBase/SetThreadToken.s new file mode 100644 index 00000000..592e7680 --- /dev/null +++ b/libc/nt/KernelBase/SetThreadToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetThreadToken,SetThreadToken,1569 diff --git a/libc/nt/KernelBase/SetThreadUILanguage.s b/libc/nt/KernelBase/SetThreadUILanguage.s new file mode 100644 index 00000000..70ee6fba --- /dev/null +++ b/libc/nt/KernelBase/SetThreadUILanguage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetThreadUILanguage,SetThreadUILanguage,1570 diff --git a/libc/nt/KernelBase/SetThreadpoolStackInformation.s b/libc/nt/KernelBase/SetThreadpoolStackInformation.s new file mode 100644 index 00000000..7b3da51f --- /dev/null +++ b/libc/nt/KernelBase/SetThreadpoolStackInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetThreadpoolStackInformation,SetThreadpoolStackInformation,1571 diff --git a/libc/nt/KernelBase/SetThreadpoolThreadMinimum.s b/libc/nt/KernelBase/SetThreadpoolThreadMinimum.s new file mode 100644 index 00000000..4c04f4fe --- /dev/null +++ b/libc/nt/KernelBase/SetThreadpoolThreadMinimum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetThreadpoolThreadMinimum,SetThreadpoolThreadMinimum,1573 diff --git a/libc/nt/KernelBase/SetTimeZoneInformation.s b/libc/nt/KernelBase/SetTimeZoneInformation.s new file mode 100644 index 00000000..54ae3797 --- /dev/null +++ b/libc/nt/KernelBase/SetTimeZoneInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetTimeZoneInformation,SetTimeZoneInformation,1578 diff --git a/libc/nt/KernelBase/SetTokenInformation.s b/libc/nt/KernelBase/SetTokenInformation.s new file mode 100644 index 00000000..0a3f23ab --- /dev/null +++ b/libc/nt/KernelBase/SetTokenInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetTokenInformation,SetTokenInformation,1579 diff --git a/libc/nt/KernelBase/SetUnhandledExceptionFilter.s b/libc/nt/KernelBase/SetUnhandledExceptionFilter.s new file mode 100644 index 00000000..fc524c6a --- /dev/null +++ b/libc/nt/KernelBase/SetUnhandledExceptionFilter.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetUnhandledExceptionFilter,SetUnhandledExceptionFilter,1580 + + .text.windows +SetUnhandledExceptionFilter: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_SetUnhandledExceptionFilter(%rip) + leave + ret + .endfn SetUnhandledExceptionFilter,globl + .previous diff --git a/libc/nt/KernelBase/SetUserGeoID.s b/libc/nt/KernelBase/SetUserGeoID.s new file mode 100644 index 00000000..ed874b79 --- /dev/null +++ b/libc/nt/KernelBase/SetUserGeoID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetUserGeoID,SetUserGeoID,1581 diff --git a/libc/nt/KernelBase/SetUserGeoName.s b/libc/nt/KernelBase/SetUserGeoName.s new file mode 100644 index 00000000..893ceae8 --- /dev/null +++ b/libc/nt/KernelBase/SetUserGeoName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetUserGeoName,SetUserGeoName,1582 diff --git a/libc/nt/KernelBase/SetWaitableTimer.s b/libc/nt/KernelBase/SetWaitableTimer.s new file mode 100644 index 00000000..b0677465 --- /dev/null +++ b/libc/nt/KernelBase/SetWaitableTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetWaitableTimer,SetWaitableTimer,1583 diff --git a/libc/nt/KernelBase/SetWaitableTimerEx.s b/libc/nt/KernelBase/SetWaitableTimerEx.s new file mode 100644 index 00000000..2cc32f3d --- /dev/null +++ b/libc/nt/KernelBase/SetWaitableTimerEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetWaitableTimerEx,SetWaitableTimerEx,1584 diff --git a/libc/nt/KernelBase/SetXStateFeaturesMask.s b/libc/nt/KernelBase/SetXStateFeaturesMask.s new file mode 100644 index 00000000..73459521 --- /dev/null +++ b/libc/nt/KernelBase/SetXStateFeaturesMask.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetXStateFeaturesMask,SetXStateFeaturesMask,1585 diff --git a/libc/nt/KernelBase/SetupComm.s b/libc/nt/KernelBase/SetupComm.s new file mode 100644 index 00000000..d62196b8 --- /dev/null +++ b/libc/nt/KernelBase/SetupComm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SetupComm,SetupComm,1586 diff --git a/libc/nt/KernelBase/SharedLocalIsEnabled.s b/libc/nt/KernelBase/SharedLocalIsEnabled.s new file mode 100644 index 00000000..786cf9dc --- /dev/null +++ b/libc/nt/KernelBase/SharedLocalIsEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SharedLocalIsEnabled,SharedLocalIsEnabled,1587 diff --git a/libc/nt/KernelBase/SignalObjectAndWait.s b/libc/nt/KernelBase/SignalObjectAndWait.s new file mode 100644 index 00000000..36fce29e --- /dev/null +++ b/libc/nt/KernelBase/SignalObjectAndWait.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SignalObjectAndWait,SignalObjectAndWait,1588 diff --git a/libc/nt/KernelBase/SizeofResource.s b/libc/nt/KernelBase/SizeofResource.s new file mode 100644 index 00000000..6123c47b --- /dev/null +++ b/libc/nt/KernelBase/SizeofResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SizeofResource,SizeofResource,1589 diff --git a/libc/nt/KernelBase/Sleep.s b/libc/nt/KernelBase/Sleep.s new file mode 100644 index 00000000..5232e09c --- /dev/null +++ b/libc/nt/KernelBase/Sleep.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_Sleep,Sleep,1590 + + .text.windows +Sleep: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_Sleep(%rip) + leave + ret + .endfn Sleep,globl + .previous diff --git a/libc/nt/KernelBase/SleepConditionVariableCS.s b/libc/nt/KernelBase/SleepConditionVariableCS.s new file mode 100644 index 00000000..3642357d --- /dev/null +++ b/libc/nt/KernelBase/SleepConditionVariableCS.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SleepConditionVariableCS,SleepConditionVariableCS,1591 diff --git a/libc/nt/KernelBase/SleepConditionVariableSRW.s b/libc/nt/KernelBase/SleepConditionVariableSRW.s new file mode 100644 index 00000000..59b183fd --- /dev/null +++ b/libc/nt/KernelBase/SleepConditionVariableSRW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SleepConditionVariableSRW,SleepConditionVariableSRW,1592 diff --git a/libc/nt/KernelBase/SleepEx.s b/libc/nt/KernelBase/SleepEx.s new file mode 100644 index 00000000..c35ccc68 --- /dev/null +++ b/libc/nt/KernelBase/SleepEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SleepEx,SleepEx,1593 + + .text.windows +SleepEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SleepEx(%rip),%rax + jmp __sysv2nt + .endfn SleepEx,globl + .previous diff --git a/libc/nt/KernelBase/SpecialMBToWC.s b/libc/nt/KernelBase/SpecialMBToWC.s new file mode 100644 index 00000000..58f1931e --- /dev/null +++ b/libc/nt/KernelBase/SpecialMBToWC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SpecialMBToWC,SpecialMBToWC,1594 diff --git a/libc/nt/KernelBase/StmAlignSize.s b/libc/nt/KernelBase/StmAlignSize.s new file mode 100644 index 00000000..d467ca5e --- /dev/null +++ b/libc/nt/KernelBase/StmAlignSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StmAlignSize,StmAlignSize,1596 diff --git a/libc/nt/KernelBase/StmAllocateFlat.s b/libc/nt/KernelBase/StmAllocateFlat.s new file mode 100644 index 00000000..01adc5cd --- /dev/null +++ b/libc/nt/KernelBase/StmAllocateFlat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StmAllocateFlat,StmAllocateFlat,1597 diff --git a/libc/nt/KernelBase/StmCoalesceChunks.s b/libc/nt/KernelBase/StmCoalesceChunks.s new file mode 100644 index 00000000..ea4547ba --- /dev/null +++ b/libc/nt/KernelBase/StmCoalesceChunks.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StmCoalesceChunks,StmCoalesceChunks,1598 diff --git a/libc/nt/KernelBase/StmDeinitialize.s b/libc/nt/KernelBase/StmDeinitialize.s new file mode 100644 index 00000000..28e2003e --- /dev/null +++ b/libc/nt/KernelBase/StmDeinitialize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StmDeinitialize,StmDeinitialize,1599 diff --git a/libc/nt/KernelBase/StmInitialize.s b/libc/nt/KernelBase/StmInitialize.s new file mode 100644 index 00000000..fc55d824 --- /dev/null +++ b/libc/nt/KernelBase/StmInitialize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StmInitialize,StmInitialize,1600 diff --git a/libc/nt/KernelBase/StmReduceSize.s b/libc/nt/KernelBase/StmReduceSize.s new file mode 100644 index 00000000..176b58d7 --- /dev/null +++ b/libc/nt/KernelBase/StmReduceSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StmReduceSize,StmReduceSize,1601 diff --git a/libc/nt/KernelBase/StmReserve.s b/libc/nt/KernelBase/StmReserve.s new file mode 100644 index 00000000..8e158baf --- /dev/null +++ b/libc/nt/KernelBase/StmReserve.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StmReserve,StmReserve,1602 diff --git a/libc/nt/KernelBase/StmWrite.s b/libc/nt/KernelBase/StmWrite.s new file mode 100644 index 00000000..b1d66863 --- /dev/null +++ b/libc/nt/KernelBase/StmWrite.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StmWrite,StmWrite,1603 diff --git a/libc/nt/KernelBase/StrCSpnA.s b/libc/nt/KernelBase/StrCSpnA.s new file mode 100644 index 00000000..e746c336 --- /dev/null +++ b/libc/nt/KernelBase/StrCSpnA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCSpnA,StrCSpnA,1604 diff --git a/libc/nt/KernelBase/StrCSpnIA.s b/libc/nt/KernelBase/StrCSpnIA.s new file mode 100644 index 00000000..ddea4c3b --- /dev/null +++ b/libc/nt/KernelBase/StrCSpnIA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCSpnIA,StrCSpnIA,1605 diff --git a/libc/nt/KernelBase/StrCSpnIW.s b/libc/nt/KernelBase/StrCSpnIW.s new file mode 100644 index 00000000..07d7e2ac --- /dev/null +++ b/libc/nt/KernelBase/StrCSpnIW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCSpnIW,StrCSpnIW,1606 diff --git a/libc/nt/KernelBase/StrCSpnW.s b/libc/nt/KernelBase/StrCSpnW.s new file mode 100644 index 00000000..ffc748b0 --- /dev/null +++ b/libc/nt/KernelBase/StrCSpnW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCSpnW,StrCSpnW,1607 diff --git a/libc/nt/KernelBase/StrCatBuffA.s b/libc/nt/KernelBase/StrCatBuffA.s new file mode 100644 index 00000000..c220acd5 --- /dev/null +++ b/libc/nt/KernelBase/StrCatBuffA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCatBuffA,StrCatBuffA,1608 diff --git a/libc/nt/KernelBase/StrCatBuffW.s b/libc/nt/KernelBase/StrCatBuffW.s new file mode 100644 index 00000000..ac3e8a31 --- /dev/null +++ b/libc/nt/KernelBase/StrCatBuffW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCatBuffW,StrCatBuffW,1609 diff --git a/libc/nt/KernelBase/StrCatChainW.s b/libc/nt/KernelBase/StrCatChainW.s new file mode 100644 index 00000000..cd8a0789 --- /dev/null +++ b/libc/nt/KernelBase/StrCatChainW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCatChainW,StrCatChainW,1610 diff --git a/libc/nt/KernelBase/StrChrA.s b/libc/nt/KernelBase/StrChrA.s new file mode 100644 index 00000000..13ce8f17 --- /dev/null +++ b/libc/nt/KernelBase/StrChrA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrChrA,StrChrA,1611 diff --git a/libc/nt/KernelBase/StrChrA_MB.s b/libc/nt/KernelBase/StrChrA_MB.s new file mode 100644 index 00000000..5b624bf0 --- /dev/null +++ b/libc/nt/KernelBase/StrChrA_MB.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrChrA_MB,StrChrA_MB,1612 diff --git a/libc/nt/KernelBase/StrChrIA.s b/libc/nt/KernelBase/StrChrIA.s new file mode 100644 index 00000000..da4a1b08 --- /dev/null +++ b/libc/nt/KernelBase/StrChrIA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrChrIA,StrChrIA,1613 diff --git a/libc/nt/KernelBase/StrChrIW.s b/libc/nt/KernelBase/StrChrIW.s new file mode 100644 index 00000000..0253494f --- /dev/null +++ b/libc/nt/KernelBase/StrChrIW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrChrIW,StrChrIW,1614 diff --git a/libc/nt/KernelBase/StrChrNIW.s b/libc/nt/KernelBase/StrChrNIW.s new file mode 100644 index 00000000..09231351 --- /dev/null +++ b/libc/nt/KernelBase/StrChrNIW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrChrNIW,StrChrNIW,1615 diff --git a/libc/nt/KernelBase/StrChrNW.s b/libc/nt/KernelBase/StrChrNW.s new file mode 100644 index 00000000..61ede218 --- /dev/null +++ b/libc/nt/KernelBase/StrChrNW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrChrNW,StrChrNW,1616 diff --git a/libc/nt/KernelBase/StrChrW.s b/libc/nt/KernelBase/StrChrW.s new file mode 100644 index 00000000..678b3603 --- /dev/null +++ b/libc/nt/KernelBase/StrChrW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrChrW,StrChrW,1617 diff --git a/libc/nt/KernelBase/StrCmpCA.s b/libc/nt/KernelBase/StrCmpCA.s new file mode 100644 index 00000000..5d67018a --- /dev/null +++ b/libc/nt/KernelBase/StrCmpCA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCmpCA,StrCmpCA,1618 diff --git a/libc/nt/KernelBase/StrCmpCW.s b/libc/nt/KernelBase/StrCmpCW.s new file mode 100644 index 00000000..f1f1cef3 --- /dev/null +++ b/libc/nt/KernelBase/StrCmpCW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCmpCW,StrCmpCW,1619 diff --git a/libc/nt/KernelBase/StrCmpICA.s b/libc/nt/KernelBase/StrCmpICA.s new file mode 100644 index 00000000..016345f6 --- /dev/null +++ b/libc/nt/KernelBase/StrCmpICA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCmpICA,StrCmpICA,1620 diff --git a/libc/nt/KernelBase/StrCmpICW.s b/libc/nt/KernelBase/StrCmpICW.s new file mode 100644 index 00000000..6543b695 --- /dev/null +++ b/libc/nt/KernelBase/StrCmpICW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCmpICW,StrCmpICW,1621 diff --git a/libc/nt/KernelBase/StrCmpIW.s b/libc/nt/KernelBase/StrCmpIW.s new file mode 100644 index 00000000..691e5152 --- /dev/null +++ b/libc/nt/KernelBase/StrCmpIW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCmpIW,StrCmpIW,1622 diff --git a/libc/nt/KernelBase/StrCmpLogicalW.s b/libc/nt/KernelBase/StrCmpLogicalW.s new file mode 100644 index 00000000..30dd631e --- /dev/null +++ b/libc/nt/KernelBase/StrCmpLogicalW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCmpLogicalW,StrCmpLogicalW,1623 diff --git a/libc/nt/KernelBase/StrCmpNA.s b/libc/nt/KernelBase/StrCmpNA.s new file mode 100644 index 00000000..088b8bba --- /dev/null +++ b/libc/nt/KernelBase/StrCmpNA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCmpNA,StrCmpNA,1624 diff --git a/libc/nt/KernelBase/StrCmpNCA.s b/libc/nt/KernelBase/StrCmpNCA.s new file mode 100644 index 00000000..39028a6f --- /dev/null +++ b/libc/nt/KernelBase/StrCmpNCA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCmpNCA,StrCmpNCA,1625 diff --git a/libc/nt/KernelBase/StrCmpNCW.s b/libc/nt/KernelBase/StrCmpNCW.s new file mode 100644 index 00000000..15f28edf --- /dev/null +++ b/libc/nt/KernelBase/StrCmpNCW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCmpNCW,StrCmpNCW,1626 diff --git a/libc/nt/KernelBase/StrCmpNIA.s b/libc/nt/KernelBase/StrCmpNIA.s new file mode 100644 index 00000000..54509938 --- /dev/null +++ b/libc/nt/KernelBase/StrCmpNIA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCmpNIA,StrCmpNIA,1627 diff --git a/libc/nt/KernelBase/StrCmpNICA.s b/libc/nt/KernelBase/StrCmpNICA.s new file mode 100644 index 00000000..a8447add --- /dev/null +++ b/libc/nt/KernelBase/StrCmpNICA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCmpNICA,StrCmpNICA,1628 diff --git a/libc/nt/KernelBase/StrCmpNICW.s b/libc/nt/KernelBase/StrCmpNICW.s new file mode 100644 index 00000000..0a083d8c --- /dev/null +++ b/libc/nt/KernelBase/StrCmpNICW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCmpNICW,StrCmpNICW,1629 diff --git a/libc/nt/KernelBase/StrCmpNIW.s b/libc/nt/KernelBase/StrCmpNIW.s new file mode 100644 index 00000000..3b60da80 --- /dev/null +++ b/libc/nt/KernelBase/StrCmpNIW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCmpNIW,StrCmpNIW,1630 diff --git a/libc/nt/KernelBase/StrCmpNW.s b/libc/nt/KernelBase/StrCmpNW.s new file mode 100644 index 00000000..bbae7c17 --- /dev/null +++ b/libc/nt/KernelBase/StrCmpNW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCmpNW,StrCmpNW,1631 diff --git a/libc/nt/KernelBase/StrCmpW.s b/libc/nt/KernelBase/StrCmpW.s new file mode 100644 index 00000000..3586aeb0 --- /dev/null +++ b/libc/nt/KernelBase/StrCmpW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCmpW,StrCmpW,1632 diff --git a/libc/nt/KernelBase/StrCpyNW.s b/libc/nt/KernelBase/StrCpyNW.s new file mode 100644 index 00000000..acd7aad6 --- /dev/null +++ b/libc/nt/KernelBase/StrCpyNW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCpyNW,StrCpyNW,1633 diff --git a/libc/nt/KernelBase/StrCpyNXA.s b/libc/nt/KernelBase/StrCpyNXA.s new file mode 100644 index 00000000..a6581518 --- /dev/null +++ b/libc/nt/KernelBase/StrCpyNXA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCpyNXA,StrCpyNXA,1634 diff --git a/libc/nt/KernelBase/StrCpyNXW.s b/libc/nt/KernelBase/StrCpyNXW.s new file mode 100644 index 00000000..38eea986 --- /dev/null +++ b/libc/nt/KernelBase/StrCpyNXW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrCpyNXW,StrCpyNXW,1635 diff --git a/libc/nt/KernelBase/StrDupA.s b/libc/nt/KernelBase/StrDupA.s new file mode 100644 index 00000000..c86c498a --- /dev/null +++ b/libc/nt/KernelBase/StrDupA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrDupA,StrDupA,1636 diff --git a/libc/nt/KernelBase/StrDupW.s b/libc/nt/KernelBase/StrDupW.s new file mode 100644 index 00000000..0715942d --- /dev/null +++ b/libc/nt/KernelBase/StrDupW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrDupW,StrDupW,1637 diff --git a/libc/nt/KernelBase/StrIsIntlEqualA.s b/libc/nt/KernelBase/StrIsIntlEqualA.s new file mode 100644 index 00000000..e591a29d --- /dev/null +++ b/libc/nt/KernelBase/StrIsIntlEqualA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrIsIntlEqualA,StrIsIntlEqualA,1638 diff --git a/libc/nt/KernelBase/StrIsIntlEqualW.s b/libc/nt/KernelBase/StrIsIntlEqualW.s new file mode 100644 index 00000000..77a99d5d --- /dev/null +++ b/libc/nt/KernelBase/StrIsIntlEqualW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrIsIntlEqualW,StrIsIntlEqualW,1639 diff --git a/libc/nt/KernelBase/StrPBrkA.s b/libc/nt/KernelBase/StrPBrkA.s new file mode 100644 index 00000000..e70fdef8 --- /dev/null +++ b/libc/nt/KernelBase/StrPBrkA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrPBrkA,StrPBrkA,1640 diff --git a/libc/nt/KernelBase/StrPBrkW.s b/libc/nt/KernelBase/StrPBrkW.s new file mode 100644 index 00000000..90733d6d --- /dev/null +++ b/libc/nt/KernelBase/StrPBrkW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrPBrkW,StrPBrkW,1641 diff --git a/libc/nt/KernelBase/StrRChrA.s b/libc/nt/KernelBase/StrRChrA.s new file mode 100644 index 00000000..77bb1365 --- /dev/null +++ b/libc/nt/KernelBase/StrRChrA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrRChrA,StrRChrA,1642 diff --git a/libc/nt/KernelBase/StrRChrIA.s b/libc/nt/KernelBase/StrRChrIA.s new file mode 100644 index 00000000..1515df47 --- /dev/null +++ b/libc/nt/KernelBase/StrRChrIA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrRChrIA,StrRChrIA,1643 diff --git a/libc/nt/KernelBase/StrRChrIW.s b/libc/nt/KernelBase/StrRChrIW.s new file mode 100644 index 00000000..434246b4 --- /dev/null +++ b/libc/nt/KernelBase/StrRChrIW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrRChrIW,StrRChrIW,1644 diff --git a/libc/nt/KernelBase/StrRChrW.s b/libc/nt/KernelBase/StrRChrW.s new file mode 100644 index 00000000..5340cb61 --- /dev/null +++ b/libc/nt/KernelBase/StrRChrW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrRChrW,StrRChrW,1645 diff --git a/libc/nt/KernelBase/StrRStrIA.s b/libc/nt/KernelBase/StrRStrIA.s new file mode 100644 index 00000000..e1685ca1 --- /dev/null +++ b/libc/nt/KernelBase/StrRStrIA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrRStrIA,StrRStrIA,1646 diff --git a/libc/nt/KernelBase/StrRStrIW.s b/libc/nt/KernelBase/StrRStrIW.s new file mode 100644 index 00000000..1ca7ac57 --- /dev/null +++ b/libc/nt/KernelBase/StrRStrIW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrRStrIW,StrRStrIW,1647 diff --git a/libc/nt/KernelBase/StrSpnA.s b/libc/nt/KernelBase/StrSpnA.s new file mode 100644 index 00000000..acbf7bba --- /dev/null +++ b/libc/nt/KernelBase/StrSpnA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrSpnA,StrSpnA,1648 diff --git a/libc/nt/KernelBase/StrSpnW.s b/libc/nt/KernelBase/StrSpnW.s new file mode 100644 index 00000000..dfd9522f --- /dev/null +++ b/libc/nt/KernelBase/StrSpnW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrSpnW,StrSpnW,1649 diff --git a/libc/nt/KernelBase/StrStrA.s b/libc/nt/KernelBase/StrStrA.s new file mode 100644 index 00000000..da614997 --- /dev/null +++ b/libc/nt/KernelBase/StrStrA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrStrA,StrStrA,1650 diff --git a/libc/nt/KernelBase/StrStrIA.s b/libc/nt/KernelBase/StrStrIA.s new file mode 100644 index 00000000..43a03254 --- /dev/null +++ b/libc/nt/KernelBase/StrStrIA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrStrIA,StrStrIA,1651 diff --git a/libc/nt/KernelBase/StrStrIW.s b/libc/nt/KernelBase/StrStrIW.s new file mode 100644 index 00000000..ce18ee83 --- /dev/null +++ b/libc/nt/KernelBase/StrStrIW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrStrIW,StrStrIW,1652 diff --git a/libc/nt/KernelBase/StrStrNIW.s b/libc/nt/KernelBase/StrStrNIW.s new file mode 100644 index 00000000..137f2922 --- /dev/null +++ b/libc/nt/KernelBase/StrStrNIW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrStrNIW,StrStrNIW,1653 diff --git a/libc/nt/KernelBase/StrStrNW.s b/libc/nt/KernelBase/StrStrNW.s new file mode 100644 index 00000000..0a7632b0 --- /dev/null +++ b/libc/nt/KernelBase/StrStrNW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrStrNW,StrStrNW,1654 diff --git a/libc/nt/KernelBase/StrStrW.s b/libc/nt/KernelBase/StrStrW.s new file mode 100644 index 00000000..6185a2a0 --- /dev/null +++ b/libc/nt/KernelBase/StrStrW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrStrW,StrStrW,1655 diff --git a/libc/nt/KernelBase/StrToInt64ExA.s b/libc/nt/KernelBase/StrToInt64ExA.s new file mode 100644 index 00000000..3e684b0f --- /dev/null +++ b/libc/nt/KernelBase/StrToInt64ExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrToInt64ExA,StrToInt64ExA,1656 diff --git a/libc/nt/KernelBase/StrToInt64ExW.s b/libc/nt/KernelBase/StrToInt64ExW.s new file mode 100644 index 00000000..3ff471f0 --- /dev/null +++ b/libc/nt/KernelBase/StrToInt64ExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrToInt64ExW,StrToInt64ExW,1657 diff --git a/libc/nt/KernelBase/StrToIntA.s b/libc/nt/KernelBase/StrToIntA.s new file mode 100644 index 00000000..2ffc605f --- /dev/null +++ b/libc/nt/KernelBase/StrToIntA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrToIntA,StrToIntA,1658 diff --git a/libc/nt/KernelBase/StrToIntExA.s b/libc/nt/KernelBase/StrToIntExA.s new file mode 100644 index 00000000..c79a72ae --- /dev/null +++ b/libc/nt/KernelBase/StrToIntExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrToIntExA,StrToIntExA,1659 diff --git a/libc/nt/KernelBase/StrToIntExW.s b/libc/nt/KernelBase/StrToIntExW.s new file mode 100644 index 00000000..6ec3c6b3 --- /dev/null +++ b/libc/nt/KernelBase/StrToIntExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrToIntExW,StrToIntExW,1660 diff --git a/libc/nt/KernelBase/StrToIntW.s b/libc/nt/KernelBase/StrToIntW.s new file mode 100644 index 00000000..83dac340 --- /dev/null +++ b/libc/nt/KernelBase/StrToIntW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrToIntW,StrToIntW,1661 diff --git a/libc/nt/KernelBase/StrTrimA.s b/libc/nt/KernelBase/StrTrimA.s new file mode 100644 index 00000000..17b04846 --- /dev/null +++ b/libc/nt/KernelBase/StrTrimA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrTrimA,StrTrimA,1662 diff --git a/libc/nt/KernelBase/StrTrimW.s b/libc/nt/KernelBase/StrTrimW.s new file mode 100644 index 00000000..1c06a96e --- /dev/null +++ b/libc/nt/KernelBase/StrTrimW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_StrTrimW,StrTrimW,1663 diff --git a/libc/nt/KernelBase/SubscribeEdpEnabledStateChange.s b/libc/nt/KernelBase/SubscribeEdpEnabledStateChange.s new file mode 100644 index 00000000..b5844fea --- /dev/null +++ b/libc/nt/KernelBase/SubscribeEdpEnabledStateChange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SubscribeEdpEnabledStateChange,SubscribeEdpEnabledStateChange,1665 diff --git a/libc/nt/KernelBase/SubscribeStateChangeNotification.s b/libc/nt/KernelBase/SubscribeStateChangeNotification.s new file mode 100644 index 00000000..70753386 --- /dev/null +++ b/libc/nt/KernelBase/SubscribeStateChangeNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SubscribeStateChangeNotification,SubscribeStateChangeNotification,1666 diff --git a/libc/nt/KernelBase/SuspendThread.s b/libc/nt/KernelBase/SuspendThread.s new file mode 100644 index 00000000..4edfdae7 --- /dev/null +++ b/libc/nt/KernelBase/SuspendThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SuspendThread,SuspendThread,1667 diff --git a/libc/nt/KernelBase/SwitchToFiber.s b/libc/nt/KernelBase/SwitchToFiber.s new file mode 100644 index 00000000..5fb2f2cd --- /dev/null +++ b/libc/nt/KernelBase/SwitchToFiber.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SwitchToFiber,SwitchToFiber,1668 diff --git a/libc/nt/KernelBase/SwitchToThread.s b/libc/nt/KernelBase/SwitchToThread.s new file mode 100644 index 00000000..2c4920be --- /dev/null +++ b/libc/nt/KernelBase/SwitchToThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SwitchToThread,SwitchToThread,1669 diff --git a/libc/nt/KernelBase/SystemTimeToFileTime.s b/libc/nt/KernelBase/SystemTimeToFileTime.s new file mode 100644 index 00000000..645e43d0 --- /dev/null +++ b/libc/nt/KernelBase/SystemTimeToFileTime.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SystemTimeToFileTime,SystemTimeToFileTime,1670 + + .text.windows +SystemTimeToFileTime: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SystemTimeToFileTime(%rip),%rax + jmp __sysv2nt + .endfn SystemTimeToFileTime,globl + .previous diff --git a/libc/nt/KernelBase/SystemTimeToTzSpecificLocalTime.s b/libc/nt/KernelBase/SystemTimeToTzSpecificLocalTime.s new file mode 100644 index 00000000..8125c43d --- /dev/null +++ b/libc/nt/KernelBase/SystemTimeToTzSpecificLocalTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SystemTimeToTzSpecificLocalTime,SystemTimeToTzSpecificLocalTime,1671 diff --git a/libc/nt/KernelBase/SystemTimeToTzSpecificLocalTimeEx.s b/libc/nt/KernelBase/SystemTimeToTzSpecificLocalTimeEx.s new file mode 100644 index 00000000..8b65b871 --- /dev/null +++ b/libc/nt/KernelBase/SystemTimeToTzSpecificLocalTimeEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_SystemTimeToTzSpecificLocalTimeEx,SystemTimeToTzSpecificLocalTimeEx,1672 diff --git a/libc/nt/KernelBase/TerminateEnclave.s b/libc/nt/KernelBase/TerminateEnclave.s new file mode 100644 index 00000000..bdc575c5 --- /dev/null +++ b/libc/nt/KernelBase/TerminateEnclave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_TerminateEnclave,TerminateEnclave,1673 diff --git a/libc/nt/KernelBase/TerminateProcess.s b/libc/nt/KernelBase/TerminateProcess.s new file mode 100644 index 00000000..bd827043 --- /dev/null +++ b/libc/nt/KernelBase/TerminateProcess.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_TerminateProcess,TerminateProcess,1674 + + .text.windows +TerminateProcess: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_TerminateProcess(%rip),%rax + jmp __sysv2nt + .endfn TerminateProcess,globl + .previous diff --git a/libc/nt/KernelBase/TerminateProcessOnMemoryExhaustion.s b/libc/nt/KernelBase/TerminateProcessOnMemoryExhaustion.s new file mode 100644 index 00000000..da1acfd6 --- /dev/null +++ b/libc/nt/KernelBase/TerminateProcessOnMemoryExhaustion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_TerminateProcessOnMemoryExhaustion,TerminateProcessOnMemoryExhaustion,1675 diff --git a/libc/nt/KernelBase/TerminateThread.s b/libc/nt/KernelBase/TerminateThread.s new file mode 100644 index 00000000..12f42c14 --- /dev/null +++ b/libc/nt/KernelBase/TerminateThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_TerminateThread,TerminateThread,1676 diff --git a/libc/nt/KernelBase/TlsAlloc.s b/libc/nt/KernelBase/TlsAlloc.s new file mode 100644 index 00000000..0003d0e1 --- /dev/null +++ b/libc/nt/KernelBase/TlsAlloc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_TlsAlloc,TlsAlloc,1677 diff --git a/libc/nt/KernelBase/TlsFree.s b/libc/nt/KernelBase/TlsFree.s new file mode 100644 index 00000000..76c822bc --- /dev/null +++ b/libc/nt/KernelBase/TlsFree.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_TlsFree,TlsFree,1678 diff --git a/libc/nt/KernelBase/TlsGetValue.s b/libc/nt/KernelBase/TlsGetValue.s new file mode 100644 index 00000000..1149e597 --- /dev/null +++ b/libc/nt/KernelBase/TlsGetValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_TlsGetValue,TlsGetValue,1679 diff --git a/libc/nt/KernelBase/TlsSetValue.s b/libc/nt/KernelBase/TlsSetValue.s new file mode 100644 index 00000000..fec69d5a --- /dev/null +++ b/libc/nt/KernelBase/TlsSetValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_TlsSetValue,TlsSetValue,1680 diff --git a/libc/nt/KernelBase/TransactNamedPipe.s b/libc/nt/KernelBase/TransactNamedPipe.s new file mode 100644 index 00000000..43a12504 --- /dev/null +++ b/libc/nt/KernelBase/TransactNamedPipe.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_TransactNamedPipe,TransactNamedPipe,1684 + + .text.windows +TransactNamedPipe: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_TransactNamedPipe(%rip),%rax + jmp __sysv2nt8 + .endfn TransactNamedPipe,globl + .previous diff --git a/libc/nt/KernelBase/TransmitCommChar.s b/libc/nt/KernelBase/TransmitCommChar.s new file mode 100644 index 00000000..d2a5b7ee --- /dev/null +++ b/libc/nt/KernelBase/TransmitCommChar.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_TransmitCommChar,TransmitCommChar,1685 diff --git a/libc/nt/KernelBase/TrySubmitThreadpoolCallback.s b/libc/nt/KernelBase/TrySubmitThreadpoolCallback.s new file mode 100644 index 00000000..ce578409 --- /dev/null +++ b/libc/nt/KernelBase/TrySubmitThreadpoolCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_TrySubmitThreadpoolCallback,TrySubmitThreadpoolCallback,1689 diff --git a/libc/nt/KernelBase/TzSpecificLocalTimeToSystemTime.s b/libc/nt/KernelBase/TzSpecificLocalTimeToSystemTime.s new file mode 100644 index 00000000..a664b493 --- /dev/null +++ b/libc/nt/KernelBase/TzSpecificLocalTimeToSystemTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_TzSpecificLocalTimeToSystemTime,TzSpecificLocalTimeToSystemTime,1690 diff --git a/libc/nt/KernelBase/TzSpecificLocalTimeToSystemTimeEx.s b/libc/nt/KernelBase/TzSpecificLocalTimeToSystemTimeEx.s new file mode 100644 index 00000000..8313833b --- /dev/null +++ b/libc/nt/KernelBase/TzSpecificLocalTimeToSystemTimeEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_TzSpecificLocalTimeToSystemTimeEx,TzSpecificLocalTimeToSystemTimeEx,1691 diff --git a/libc/nt/KernelBase/UnhandledExceptionFilter.s b/libc/nt/KernelBase/UnhandledExceptionFilter.s new file mode 100644 index 00000000..8903e3d0 --- /dev/null +++ b/libc/nt/KernelBase/UnhandledExceptionFilter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UnhandledExceptionFilter,UnhandledExceptionFilter,1692 diff --git a/libc/nt/KernelBase/UnlockFile.s b/libc/nt/KernelBase/UnlockFile.s new file mode 100644 index 00000000..b2cfa7d6 --- /dev/null +++ b/libc/nt/KernelBase/UnlockFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UnlockFile,UnlockFile,1693 + + .text.windows +UnlockFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_UnlockFile(%rip),%rax + jmp __sysv2nt6 + .endfn UnlockFile,globl + .previous diff --git a/libc/nt/KernelBase/UnlockFileEx.s b/libc/nt/KernelBase/UnlockFileEx.s new file mode 100644 index 00000000..d6a1ee58 --- /dev/null +++ b/libc/nt/KernelBase/UnlockFileEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UnlockFileEx,UnlockFileEx,1694 + + .text.windows +UnlockFileEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_UnlockFileEx(%rip),%rax + jmp __sysv2nt6 + .endfn UnlockFileEx,globl + .previous diff --git a/libc/nt/KernelBase/UnmapViewOfFile.s b/libc/nt/KernelBase/UnmapViewOfFile.s new file mode 100644 index 00000000..c64356b7 --- /dev/null +++ b/libc/nt/KernelBase/UnmapViewOfFile.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UnmapViewOfFile,UnmapViewOfFile,1695 + + .text.windows +UnmapViewOfFile: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_UnmapViewOfFile(%rip) + leave + ret + .endfn UnmapViewOfFile,globl + .previous diff --git a/libc/nt/KernelBase/UnmapViewOfFile2.s b/libc/nt/KernelBase/UnmapViewOfFile2.s new file mode 100644 index 00000000..7b8dfd0e --- /dev/null +++ b/libc/nt/KernelBase/UnmapViewOfFile2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UnmapViewOfFile2,UnmapViewOfFile2,1696 diff --git a/libc/nt/KernelBase/UnmapViewOfFileEx.s b/libc/nt/KernelBase/UnmapViewOfFileEx.s new file mode 100644 index 00000000..04ff7e50 --- /dev/null +++ b/libc/nt/KernelBase/UnmapViewOfFileEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UnmapViewOfFileEx,UnmapViewOfFileEx,1697 diff --git a/libc/nt/KernelBase/UnregisterBadMemoryNotification.s b/libc/nt/KernelBase/UnregisterBadMemoryNotification.s new file mode 100644 index 00000000..52398be3 --- /dev/null +++ b/libc/nt/KernelBase/UnregisterBadMemoryNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UnregisterBadMemoryNotification,UnregisterBadMemoryNotification,1698 diff --git a/libc/nt/KernelBase/UnregisterGPNotificationInternal.s b/libc/nt/KernelBase/UnregisterGPNotificationInternal.s new file mode 100644 index 00000000..fb194724 --- /dev/null +++ b/libc/nt/KernelBase/UnregisterGPNotificationInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UnregisterGPNotificationInternal,UnregisterGPNotificationInternal,1699 diff --git a/libc/nt/KernelBase/UnregisterStateChangeNotification.s b/libc/nt/KernelBase/UnregisterStateChangeNotification.s new file mode 100644 index 00000000..9d96bc7d --- /dev/null +++ b/libc/nt/KernelBase/UnregisterStateChangeNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UnregisterStateChangeNotification,UnregisterStateChangeNotification,1700 diff --git a/libc/nt/KernelBase/UnregisterStateLock.s b/libc/nt/KernelBase/UnregisterStateLock.s new file mode 100644 index 00000000..85d97ab0 --- /dev/null +++ b/libc/nt/KernelBase/UnregisterStateLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UnregisterStateLock,UnregisterStateLock,1701 diff --git a/libc/nt/KernelBase/UnregisterWaitEx.s b/libc/nt/KernelBase/UnregisterWaitEx.s new file mode 100644 index 00000000..b860f9f1 --- /dev/null +++ b/libc/nt/KernelBase/UnregisterWaitEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UnregisterWaitEx,UnregisterWaitEx,1703 diff --git a/libc/nt/KernelBase/UnsubscribeEdpEnabledStateChange.s b/libc/nt/KernelBase/UnsubscribeEdpEnabledStateChange.s new file mode 100644 index 00000000..5e79469c --- /dev/null +++ b/libc/nt/KernelBase/UnsubscribeEdpEnabledStateChange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UnsubscribeEdpEnabledStateChange,UnsubscribeEdpEnabledStateChange,1704 diff --git a/libc/nt/KernelBase/UnsubscribeStateChangeNotification.s b/libc/nt/KernelBase/UnsubscribeStateChangeNotification.s new file mode 100644 index 00000000..84f1b5e1 --- /dev/null +++ b/libc/nt/KernelBase/UnsubscribeStateChangeNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UnsubscribeStateChangeNotification,UnsubscribeStateChangeNotification,1705 diff --git a/libc/nt/KernelBase/UpdatePackageStatus.s b/libc/nt/KernelBase/UpdatePackageStatus.s new file mode 100644 index 00000000..b18a6719 --- /dev/null +++ b/libc/nt/KernelBase/UpdatePackageStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UpdatePackageStatus,UpdatePackageStatus,1706 diff --git a/libc/nt/KernelBase/UpdatePackageStatusForUser.s b/libc/nt/KernelBase/UpdatePackageStatusForUser.s new file mode 100644 index 00000000..92ed9820 --- /dev/null +++ b/libc/nt/KernelBase/UpdatePackageStatusForUser.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UpdatePackageStatusForUser,UpdatePackageStatusForUser,1707 diff --git a/libc/nt/KernelBase/UpdatePackageStatusForUserSid.s b/libc/nt/KernelBase/UpdatePackageStatusForUserSid.s new file mode 100644 index 00000000..108479af --- /dev/null +++ b/libc/nt/KernelBase/UpdatePackageStatusForUserSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UpdatePackageStatusForUserSid,UpdatePackageStatusForUserSid,1708 diff --git a/libc/nt/KernelBase/UpdateProcThreadAttribute.s b/libc/nt/KernelBase/UpdateProcThreadAttribute.s new file mode 100644 index 00000000..2442c9fc --- /dev/null +++ b/libc/nt/KernelBase/UpdateProcThreadAttribute.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UpdateProcThreadAttribute,UpdateProcThreadAttribute,1709 + + .text.windows +UpdateProcThreadAttribute: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_UpdateProcThreadAttribute(%rip),%rax + jmp __sysv2nt8 + .endfn UpdateProcThreadAttribute,globl + .previous diff --git a/libc/nt/KernelBase/UrlApplySchemeA.s b/libc/nt/KernelBase/UrlApplySchemeA.s new file mode 100644 index 00000000..d8d6729d --- /dev/null +++ b/libc/nt/KernelBase/UrlApplySchemeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlApplySchemeA,UrlApplySchemeA,1710 diff --git a/libc/nt/KernelBase/UrlApplySchemeW.s b/libc/nt/KernelBase/UrlApplySchemeW.s new file mode 100644 index 00000000..f238b599 --- /dev/null +++ b/libc/nt/KernelBase/UrlApplySchemeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlApplySchemeW,UrlApplySchemeW,1711 diff --git a/libc/nt/KernelBase/UrlCanonicalizeA.s b/libc/nt/KernelBase/UrlCanonicalizeA.s new file mode 100644 index 00000000..f51ceb9e --- /dev/null +++ b/libc/nt/KernelBase/UrlCanonicalizeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlCanonicalizeA,UrlCanonicalizeA,1712 diff --git a/libc/nt/KernelBase/UrlCanonicalizeW.s b/libc/nt/KernelBase/UrlCanonicalizeW.s new file mode 100644 index 00000000..41ded187 --- /dev/null +++ b/libc/nt/KernelBase/UrlCanonicalizeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlCanonicalizeW,UrlCanonicalizeW,1713 diff --git a/libc/nt/KernelBase/UrlCombineA.s b/libc/nt/KernelBase/UrlCombineA.s new file mode 100644 index 00000000..6720f435 --- /dev/null +++ b/libc/nt/KernelBase/UrlCombineA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlCombineA,UrlCombineA,1714 diff --git a/libc/nt/KernelBase/UrlCombineW.s b/libc/nt/KernelBase/UrlCombineW.s new file mode 100644 index 00000000..78a8b828 --- /dev/null +++ b/libc/nt/KernelBase/UrlCombineW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlCombineW,UrlCombineW,1715 diff --git a/libc/nt/KernelBase/UrlCompareA.s b/libc/nt/KernelBase/UrlCompareA.s new file mode 100644 index 00000000..7f507151 --- /dev/null +++ b/libc/nt/KernelBase/UrlCompareA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlCompareA,UrlCompareA,1716 diff --git a/libc/nt/KernelBase/UrlCompareW.s b/libc/nt/KernelBase/UrlCompareW.s new file mode 100644 index 00000000..ae7ac1c3 --- /dev/null +++ b/libc/nt/KernelBase/UrlCompareW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlCompareW,UrlCompareW,1717 diff --git a/libc/nt/KernelBase/UrlCreateFromPathA.s b/libc/nt/KernelBase/UrlCreateFromPathA.s new file mode 100644 index 00000000..a83536e6 --- /dev/null +++ b/libc/nt/KernelBase/UrlCreateFromPathA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlCreateFromPathA,UrlCreateFromPathA,1718 diff --git a/libc/nt/KernelBase/UrlCreateFromPathW.s b/libc/nt/KernelBase/UrlCreateFromPathW.s new file mode 100644 index 00000000..fda675ef --- /dev/null +++ b/libc/nt/KernelBase/UrlCreateFromPathW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlCreateFromPathW,UrlCreateFromPathW,1719 diff --git a/libc/nt/KernelBase/UrlEscapeA.s b/libc/nt/KernelBase/UrlEscapeA.s new file mode 100644 index 00000000..244199c9 --- /dev/null +++ b/libc/nt/KernelBase/UrlEscapeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlEscapeA,UrlEscapeA,1720 diff --git a/libc/nt/KernelBase/UrlEscapeW.s b/libc/nt/KernelBase/UrlEscapeW.s new file mode 100644 index 00000000..50d7bad7 --- /dev/null +++ b/libc/nt/KernelBase/UrlEscapeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlEscapeW,UrlEscapeW,1721 diff --git a/libc/nt/KernelBase/UrlFixupW.s b/libc/nt/KernelBase/UrlFixupW.s new file mode 100644 index 00000000..542c2e57 --- /dev/null +++ b/libc/nt/KernelBase/UrlFixupW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlFixupW,UrlFixupW,1722 diff --git a/libc/nt/KernelBase/UrlGetLocationA.s b/libc/nt/KernelBase/UrlGetLocationA.s new file mode 100644 index 00000000..0f7858c3 --- /dev/null +++ b/libc/nt/KernelBase/UrlGetLocationA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlGetLocationA,UrlGetLocationA,1723 diff --git a/libc/nt/KernelBase/UrlGetLocationW.s b/libc/nt/KernelBase/UrlGetLocationW.s new file mode 100644 index 00000000..99e6f9f2 --- /dev/null +++ b/libc/nt/KernelBase/UrlGetLocationW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlGetLocationW,UrlGetLocationW,1724 diff --git a/libc/nt/KernelBase/UrlGetPartA.s b/libc/nt/KernelBase/UrlGetPartA.s new file mode 100644 index 00000000..36828f58 --- /dev/null +++ b/libc/nt/KernelBase/UrlGetPartA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlGetPartA,UrlGetPartA,1725 diff --git a/libc/nt/KernelBase/UrlGetPartW.s b/libc/nt/KernelBase/UrlGetPartW.s new file mode 100644 index 00000000..ceacf87b --- /dev/null +++ b/libc/nt/KernelBase/UrlGetPartW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlGetPartW,UrlGetPartW,1726 diff --git a/libc/nt/KernelBase/UrlHashA.s b/libc/nt/KernelBase/UrlHashA.s new file mode 100644 index 00000000..bc115b9a --- /dev/null +++ b/libc/nt/KernelBase/UrlHashA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlHashA,UrlHashA,1727 diff --git a/libc/nt/KernelBase/UrlHashW.s b/libc/nt/KernelBase/UrlHashW.s new file mode 100644 index 00000000..3c9ce753 --- /dev/null +++ b/libc/nt/KernelBase/UrlHashW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlHashW,UrlHashW,1728 diff --git a/libc/nt/KernelBase/UrlIsA.s b/libc/nt/KernelBase/UrlIsA.s new file mode 100644 index 00000000..63701323 --- /dev/null +++ b/libc/nt/KernelBase/UrlIsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlIsA,UrlIsA,1729 diff --git a/libc/nt/KernelBase/UrlIsNoHistoryA.s b/libc/nt/KernelBase/UrlIsNoHistoryA.s new file mode 100644 index 00000000..967140d4 --- /dev/null +++ b/libc/nt/KernelBase/UrlIsNoHistoryA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlIsNoHistoryA,UrlIsNoHistoryA,1730 diff --git a/libc/nt/KernelBase/UrlIsNoHistoryW.s b/libc/nt/KernelBase/UrlIsNoHistoryW.s new file mode 100644 index 00000000..c1c5fd3e --- /dev/null +++ b/libc/nt/KernelBase/UrlIsNoHistoryW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlIsNoHistoryW,UrlIsNoHistoryW,1731 diff --git a/libc/nt/KernelBase/UrlIsOpaqueA.s b/libc/nt/KernelBase/UrlIsOpaqueA.s new file mode 100644 index 00000000..f01b5497 --- /dev/null +++ b/libc/nt/KernelBase/UrlIsOpaqueA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlIsOpaqueA,UrlIsOpaqueA,1732 diff --git a/libc/nt/KernelBase/UrlIsOpaqueW.s b/libc/nt/KernelBase/UrlIsOpaqueW.s new file mode 100644 index 00000000..56c3ec3f --- /dev/null +++ b/libc/nt/KernelBase/UrlIsOpaqueW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlIsOpaqueW,UrlIsOpaqueW,1733 diff --git a/libc/nt/KernelBase/UrlIsW.s b/libc/nt/KernelBase/UrlIsW.s new file mode 100644 index 00000000..ac18c022 --- /dev/null +++ b/libc/nt/KernelBase/UrlIsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlIsW,UrlIsW,1734 diff --git a/libc/nt/KernelBase/UrlUnescapeA.s b/libc/nt/KernelBase/UrlUnescapeA.s new file mode 100644 index 00000000..643129cc --- /dev/null +++ b/libc/nt/KernelBase/UrlUnescapeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlUnescapeA,UrlUnescapeA,1735 diff --git a/libc/nt/KernelBase/UrlUnescapeW.s b/libc/nt/KernelBase/UrlUnescapeW.s new file mode 100644 index 00000000..6cdc64f7 --- /dev/null +++ b/libc/nt/KernelBase/UrlUnescapeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_UrlUnescapeW,UrlUnescapeW,1736 diff --git a/libc/nt/KernelBase/VerFindFileA.s b/libc/nt/KernelBase/VerFindFileA.s new file mode 100644 index 00000000..02733d6e --- /dev/null +++ b/libc/nt/KernelBase/VerFindFileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VerFindFileA,VerFindFileA,1737 diff --git a/libc/nt/KernelBase/VerFindFileW.s b/libc/nt/KernelBase/VerFindFileW.s new file mode 100644 index 00000000..0f6b7251 --- /dev/null +++ b/libc/nt/KernelBase/VerFindFileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VerFindFileW,VerFindFileW,1738 diff --git a/libc/nt/KernelBase/VerLanguageNameA.s b/libc/nt/KernelBase/VerLanguageNameA.s new file mode 100644 index 00000000..45bc33fe --- /dev/null +++ b/libc/nt/KernelBase/VerLanguageNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VerLanguageNameA,VerLanguageNameA,1739 diff --git a/libc/nt/KernelBase/VerLanguageNameW.s b/libc/nt/KernelBase/VerLanguageNameW.s new file mode 100644 index 00000000..85612603 --- /dev/null +++ b/libc/nt/KernelBase/VerLanguageNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VerLanguageNameW,VerLanguageNameW,1740 diff --git a/libc/nt/KernelBase/VerQueryValueA.s b/libc/nt/KernelBase/VerQueryValueA.s new file mode 100644 index 00000000..eb3c7ab6 --- /dev/null +++ b/libc/nt/KernelBase/VerQueryValueA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VerQueryValueA,VerQueryValueA,1741 diff --git a/libc/nt/KernelBase/VerQueryValueW.s b/libc/nt/KernelBase/VerQueryValueW.s new file mode 100644 index 00000000..bf101dbd --- /dev/null +++ b/libc/nt/KernelBase/VerQueryValueW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VerQueryValueW,VerQueryValueW,1742 diff --git a/libc/nt/KernelBase/VerifyApplicationUserModelId.s b/libc/nt/KernelBase/VerifyApplicationUserModelId.s new file mode 100644 index 00000000..0f3c3265 --- /dev/null +++ b/libc/nt/KernelBase/VerifyApplicationUserModelId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VerifyApplicationUserModelId,VerifyApplicationUserModelId,1744 diff --git a/libc/nt/KernelBase/VerifyApplicationUserModelIdA.s b/libc/nt/KernelBase/VerifyApplicationUserModelIdA.s new file mode 100644 index 00000000..b76ee2ca --- /dev/null +++ b/libc/nt/KernelBase/VerifyApplicationUserModelIdA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VerifyApplicationUserModelIdA,VerifyApplicationUserModelIdA,1745 diff --git a/libc/nt/KernelBase/VerifyPackageFamilyName.s b/libc/nt/KernelBase/VerifyPackageFamilyName.s new file mode 100644 index 00000000..a8540b2e --- /dev/null +++ b/libc/nt/KernelBase/VerifyPackageFamilyName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VerifyPackageFamilyName,VerifyPackageFamilyName,1746 diff --git a/libc/nt/KernelBase/VerifyPackageFamilyNameA.s b/libc/nt/KernelBase/VerifyPackageFamilyNameA.s new file mode 100644 index 00000000..cd750cc0 --- /dev/null +++ b/libc/nt/KernelBase/VerifyPackageFamilyNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VerifyPackageFamilyNameA,VerifyPackageFamilyNameA,1747 diff --git a/libc/nt/KernelBase/VerifyPackageFullName.s b/libc/nt/KernelBase/VerifyPackageFullName.s new file mode 100644 index 00000000..f71c36ba --- /dev/null +++ b/libc/nt/KernelBase/VerifyPackageFullName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VerifyPackageFullName,VerifyPackageFullName,1748 diff --git a/libc/nt/KernelBase/VerifyPackageFullNameA.s b/libc/nt/KernelBase/VerifyPackageFullNameA.s new file mode 100644 index 00000000..1cc746cf --- /dev/null +++ b/libc/nt/KernelBase/VerifyPackageFullNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VerifyPackageFullNameA,VerifyPackageFullNameA,1749 diff --git a/libc/nt/KernelBase/VerifyPackageId.s b/libc/nt/KernelBase/VerifyPackageId.s new file mode 100644 index 00000000..7c7f175b --- /dev/null +++ b/libc/nt/KernelBase/VerifyPackageId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VerifyPackageId,VerifyPackageId,1750 diff --git a/libc/nt/KernelBase/VerifyPackageIdA.s b/libc/nt/KernelBase/VerifyPackageIdA.s new file mode 100644 index 00000000..fb610724 --- /dev/null +++ b/libc/nt/KernelBase/VerifyPackageIdA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VerifyPackageIdA,VerifyPackageIdA,1751 diff --git a/libc/nt/KernelBase/VerifyPackageRelativeApplicationId.s b/libc/nt/KernelBase/VerifyPackageRelativeApplicationId.s new file mode 100644 index 00000000..01904db8 --- /dev/null +++ b/libc/nt/KernelBase/VerifyPackageRelativeApplicationId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VerifyPackageRelativeApplicationId,VerifyPackageRelativeApplicationId,1752 diff --git a/libc/nt/KernelBase/VerifyPackageRelativeApplicationIdA.s b/libc/nt/KernelBase/VerifyPackageRelativeApplicationIdA.s new file mode 100644 index 00000000..b5bd50ad --- /dev/null +++ b/libc/nt/KernelBase/VerifyPackageRelativeApplicationIdA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VerifyPackageRelativeApplicationIdA,VerifyPackageRelativeApplicationIdA,1753 diff --git a/libc/nt/KernelBase/VerifyScripts.s b/libc/nt/KernelBase/VerifyScripts.s new file mode 100644 index 00000000..cd0a214b --- /dev/null +++ b/libc/nt/KernelBase/VerifyScripts.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VerifyScripts,VerifyScripts,1754 diff --git a/libc/nt/KernelBase/VirtualAlloc.s b/libc/nt/KernelBase/VirtualAlloc.s new file mode 100644 index 00000000..b93adb31 --- /dev/null +++ b/libc/nt/KernelBase/VirtualAlloc.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VirtualAlloc,VirtualAlloc,1755 + + .text.windows +VirtualAlloc: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_VirtualAlloc(%rip),%rax + jmp __sysv2nt + .endfn VirtualAlloc,globl + .previous diff --git a/libc/nt/KernelBase/VirtualAlloc2.s b/libc/nt/KernelBase/VirtualAlloc2.s new file mode 100644 index 00000000..beec22fa --- /dev/null +++ b/libc/nt/KernelBase/VirtualAlloc2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VirtualAlloc2,VirtualAlloc2,1756 diff --git a/libc/nt/KernelBase/VirtualAlloc2FromApp.s b/libc/nt/KernelBase/VirtualAlloc2FromApp.s new file mode 100644 index 00000000..0d8e14fb --- /dev/null +++ b/libc/nt/KernelBase/VirtualAlloc2FromApp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VirtualAlloc2FromApp,VirtualAlloc2FromApp,1757 diff --git a/libc/nt/KernelBase/VirtualAllocEx.s b/libc/nt/KernelBase/VirtualAllocEx.s new file mode 100644 index 00000000..87465ca5 --- /dev/null +++ b/libc/nt/KernelBase/VirtualAllocEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VirtualAllocEx,VirtualAllocEx,1758 + + .text.windows +VirtualAllocEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_VirtualAllocEx(%rip),%rax + jmp __sysv2nt6 + .endfn VirtualAllocEx,globl + .previous diff --git a/libc/nt/KernelBase/VirtualAllocExNuma.s b/libc/nt/KernelBase/VirtualAllocExNuma.s new file mode 100644 index 00000000..9a85dcd6 --- /dev/null +++ b/libc/nt/KernelBase/VirtualAllocExNuma.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VirtualAllocExNuma,VirtualAllocExNuma,1759 diff --git a/libc/nt/KernelBase/VirtualAllocFromApp.s b/libc/nt/KernelBase/VirtualAllocFromApp.s new file mode 100644 index 00000000..0f3b23ad --- /dev/null +++ b/libc/nt/KernelBase/VirtualAllocFromApp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VirtualAllocFromApp,VirtualAllocFromApp,1760 diff --git a/libc/nt/KernelBase/VirtualFree.s b/libc/nt/KernelBase/VirtualFree.s new file mode 100644 index 00000000..6f86d2ad --- /dev/null +++ b/libc/nt/KernelBase/VirtualFree.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VirtualFree,VirtualFree,1761 + + .text.windows +VirtualFree: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_VirtualFree(%rip),%rax + jmp __sysv2nt + .endfn VirtualFree,globl + .previous diff --git a/libc/nt/KernelBase/VirtualFreeEx.s b/libc/nt/KernelBase/VirtualFreeEx.s new file mode 100644 index 00000000..b5e74325 --- /dev/null +++ b/libc/nt/KernelBase/VirtualFreeEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VirtualFreeEx,VirtualFreeEx,1762 diff --git a/libc/nt/KernelBase/VirtualLock.s b/libc/nt/KernelBase/VirtualLock.s new file mode 100644 index 00000000..a03e5f44 --- /dev/null +++ b/libc/nt/KernelBase/VirtualLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VirtualLock,VirtualLock,1763 diff --git a/libc/nt/KernelBase/VirtualProtect.s b/libc/nt/KernelBase/VirtualProtect.s new file mode 100644 index 00000000..8100d6b2 --- /dev/null +++ b/libc/nt/KernelBase/VirtualProtect.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VirtualProtect,VirtualProtect,1764 + + .text.windows +VirtualProtect: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_VirtualProtect(%rip),%rax + jmp __sysv2nt + .endfn VirtualProtect,globl + .previous diff --git a/libc/nt/KernelBase/VirtualProtectEx.s b/libc/nt/KernelBase/VirtualProtectEx.s new file mode 100644 index 00000000..7b43ed7b --- /dev/null +++ b/libc/nt/KernelBase/VirtualProtectEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VirtualProtectEx,VirtualProtectEx,1765 diff --git a/libc/nt/KernelBase/VirtualProtectFromApp.s b/libc/nt/KernelBase/VirtualProtectFromApp.s new file mode 100644 index 00000000..b08f07da --- /dev/null +++ b/libc/nt/KernelBase/VirtualProtectFromApp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VirtualProtectFromApp,VirtualProtectFromApp,1766 diff --git a/libc/nt/KernelBase/VirtualQuery.s b/libc/nt/KernelBase/VirtualQuery.s new file mode 100644 index 00000000..e2e731a3 --- /dev/null +++ b/libc/nt/KernelBase/VirtualQuery.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VirtualQuery,VirtualQuery,1767 + + .text.windows +VirtualQuery: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_VirtualQuery(%rip),%rax + jmp __sysv2nt + .endfn VirtualQuery,globl + .previous diff --git a/libc/nt/KernelBase/VirtualQueryEx.s b/libc/nt/KernelBase/VirtualQueryEx.s new file mode 100644 index 00000000..d7fea4c7 --- /dev/null +++ b/libc/nt/KernelBase/VirtualQueryEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VirtualQueryEx,VirtualQueryEx,1768 diff --git a/libc/nt/KernelBase/VirtualUnlock.s b/libc/nt/KernelBase/VirtualUnlock.s new file mode 100644 index 00000000..2ba738c0 --- /dev/null +++ b/libc/nt/KernelBase/VirtualUnlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VirtualUnlock,VirtualUnlock,1769 diff --git a/libc/nt/KernelBase/VirtualUnlockEx.s b/libc/nt/KernelBase/VirtualUnlockEx.s new file mode 100644 index 00000000..7cbfe492 --- /dev/null +++ b/libc/nt/KernelBase/VirtualUnlockEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_VirtualUnlockEx,VirtualUnlockEx,1770 diff --git a/libc/nt/KernelBase/WTSGetServiceSessionId.s b/libc/nt/KernelBase/WTSGetServiceSessionId.s new file mode 100644 index 00000000..653082f2 --- /dev/null +++ b/libc/nt/KernelBase/WTSGetServiceSessionId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WTSGetServiceSessionId,WTSGetServiceSessionId,1771 diff --git a/libc/nt/KernelBase/WTSIsServerContainer.s b/libc/nt/KernelBase/WTSIsServerContainer.s new file mode 100644 index 00000000..2f245de6 --- /dev/null +++ b/libc/nt/KernelBase/WTSIsServerContainer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WTSIsServerContainer,WTSIsServerContainer,1772 diff --git a/libc/nt/KernelBase/WaitCommEvent.s b/libc/nt/KernelBase/WaitCommEvent.s new file mode 100644 index 00000000..be057a54 --- /dev/null +++ b/libc/nt/KernelBase/WaitCommEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WaitCommEvent,WaitCommEvent,1773 diff --git a/libc/nt/KernelBase/WaitForDebugEvent.s b/libc/nt/KernelBase/WaitForDebugEvent.s new file mode 100644 index 00000000..6c3a6ce9 --- /dev/null +++ b/libc/nt/KernelBase/WaitForDebugEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WaitForDebugEvent,WaitForDebugEvent,1774 diff --git a/libc/nt/KernelBase/WaitForDebugEventEx.s b/libc/nt/KernelBase/WaitForDebugEventEx.s new file mode 100644 index 00000000..17986b81 --- /dev/null +++ b/libc/nt/KernelBase/WaitForDebugEventEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WaitForDebugEventEx,WaitForDebugEventEx,1775 diff --git a/libc/nt/KernelBase/WaitForMachinePolicyForegroundProcessingInternal.s b/libc/nt/KernelBase/WaitForMachinePolicyForegroundProcessingInternal.s new file mode 100644 index 00000000..6c2a41c1 --- /dev/null +++ b/libc/nt/KernelBase/WaitForMachinePolicyForegroundProcessingInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WaitForMachinePolicyForegroundProcessingInternal,WaitForMachinePolicyForegroundProcessingInternal,1776 diff --git a/libc/nt/KernelBase/WaitForMultipleObjects.s b/libc/nt/KernelBase/WaitForMultipleObjects.s new file mode 100644 index 00000000..ce4d5a7c --- /dev/null +++ b/libc/nt/KernelBase/WaitForMultipleObjects.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WaitForMultipleObjects,WaitForMultipleObjects,1777 + + .text.windows +WaitForMultipleObjects: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WaitForMultipleObjects(%rip),%rax + jmp __sysv2nt + .endfn WaitForMultipleObjects,globl + .previous diff --git a/libc/nt/KernelBase/WaitForMultipleObjectsEx.s b/libc/nt/KernelBase/WaitForMultipleObjectsEx.s new file mode 100644 index 00000000..8f48dc1d --- /dev/null +++ b/libc/nt/KernelBase/WaitForMultipleObjectsEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WaitForMultipleObjectsEx,WaitForMultipleObjectsEx,1778 + + .text.windows +WaitForMultipleObjectsEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WaitForMultipleObjectsEx(%rip),%rax + jmp __sysv2nt6 + .endfn WaitForMultipleObjectsEx,globl + .previous diff --git a/libc/nt/KernelBase/WaitForSingleObject.s b/libc/nt/KernelBase/WaitForSingleObject.s new file mode 100644 index 00000000..04d1ca43 --- /dev/null +++ b/libc/nt/KernelBase/WaitForSingleObject.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WaitForSingleObject,WaitForSingleObject,1779 + + .text.windows +WaitForSingleObject: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WaitForSingleObject(%rip),%rax + jmp __sysv2nt + .endfn WaitForSingleObject,globl + .previous diff --git a/libc/nt/KernelBase/WaitForSingleObjectEx.s b/libc/nt/KernelBase/WaitForSingleObjectEx.s new file mode 100644 index 00000000..ba483f75 --- /dev/null +++ b/libc/nt/KernelBase/WaitForSingleObjectEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WaitForSingleObjectEx,WaitForSingleObjectEx,1780 + + .text.windows +WaitForSingleObjectEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WaitForSingleObjectEx(%rip),%rax + jmp __sysv2nt + .endfn WaitForSingleObjectEx,globl + .previous diff --git a/libc/nt/KernelBase/WaitForUserPolicyForegroundProcessingInternal.s b/libc/nt/KernelBase/WaitForUserPolicyForegroundProcessingInternal.s new file mode 100644 index 00000000..d247ebc5 --- /dev/null +++ b/libc/nt/KernelBase/WaitForUserPolicyForegroundProcessingInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WaitForUserPolicyForegroundProcessingInternal,WaitForUserPolicyForegroundProcessingInternal,1785 diff --git a/libc/nt/KernelBase/WaitNamedPipeW.s b/libc/nt/KernelBase/WaitNamedPipeW.s new file mode 100644 index 00000000..84749c80 --- /dev/null +++ b/libc/nt/KernelBase/WaitNamedPipeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WaitNamedPipeW,WaitNamedPipeW,1786 diff --git a/libc/nt/KernelBase/WaitOnAddress.s b/libc/nt/KernelBase/WaitOnAddress.s new file mode 100644 index 00000000..e1f80653 --- /dev/null +++ b/libc/nt/KernelBase/WaitOnAddress.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WaitOnAddress,WaitOnAddress,1787 diff --git a/libc/nt/KernelBase/WerGetFlags.s b/libc/nt/KernelBase/WerGetFlags.s new file mode 100644 index 00000000..2a70b8e0 --- /dev/null +++ b/libc/nt/KernelBase/WerGetFlags.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerGetFlags,WerGetFlags,1792 diff --git a/libc/nt/KernelBase/WerRegisterAdditionalProcess.s b/libc/nt/KernelBase/WerRegisterAdditionalProcess.s new file mode 100644 index 00000000..338eed70 --- /dev/null +++ b/libc/nt/KernelBase/WerRegisterAdditionalProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerRegisterAdditionalProcess,WerRegisterAdditionalProcess,1793 diff --git a/libc/nt/KernelBase/WerRegisterAppLocalDump.s b/libc/nt/KernelBase/WerRegisterAppLocalDump.s new file mode 100644 index 00000000..a8b6a63f --- /dev/null +++ b/libc/nt/KernelBase/WerRegisterAppLocalDump.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerRegisterAppLocalDump,WerRegisterAppLocalDump,1794 diff --git a/libc/nt/KernelBase/WerRegisterCustomMetadata.s b/libc/nt/KernelBase/WerRegisterCustomMetadata.s new file mode 100644 index 00000000..10ace560 --- /dev/null +++ b/libc/nt/KernelBase/WerRegisterCustomMetadata.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerRegisterCustomMetadata,WerRegisterCustomMetadata,1795 diff --git a/libc/nt/KernelBase/WerRegisterExcludedMemoryBlock.s b/libc/nt/KernelBase/WerRegisterExcludedMemoryBlock.s new file mode 100644 index 00000000..348cfddd --- /dev/null +++ b/libc/nt/KernelBase/WerRegisterExcludedMemoryBlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerRegisterExcludedMemoryBlock,WerRegisterExcludedMemoryBlock,1796 diff --git a/libc/nt/KernelBase/WerRegisterFile.s b/libc/nt/KernelBase/WerRegisterFile.s new file mode 100644 index 00000000..634472d6 --- /dev/null +++ b/libc/nt/KernelBase/WerRegisterFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerRegisterFile,WerRegisterFile,1797 diff --git a/libc/nt/KernelBase/WerRegisterMemoryBlock.s b/libc/nt/KernelBase/WerRegisterMemoryBlock.s new file mode 100644 index 00000000..539003d4 --- /dev/null +++ b/libc/nt/KernelBase/WerRegisterMemoryBlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerRegisterMemoryBlock,WerRegisterMemoryBlock,1798 diff --git a/libc/nt/KernelBase/WerRegisterRuntimeExceptionModule.s b/libc/nt/KernelBase/WerRegisterRuntimeExceptionModule.s new file mode 100644 index 00000000..f1fb2f5c --- /dev/null +++ b/libc/nt/KernelBase/WerRegisterRuntimeExceptionModule.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerRegisterRuntimeExceptionModule,WerRegisterRuntimeExceptionModule,1799 diff --git a/libc/nt/KernelBase/WerSetFlags.s b/libc/nt/KernelBase/WerSetFlags.s new file mode 100644 index 00000000..cd91e335 --- /dev/null +++ b/libc/nt/KernelBase/WerSetFlags.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerSetFlags,WerSetFlags,1800 diff --git a/libc/nt/KernelBase/WerUnregisterAdditionalProcess.s b/libc/nt/KernelBase/WerUnregisterAdditionalProcess.s new file mode 100644 index 00000000..dec0f8f8 --- /dev/null +++ b/libc/nt/KernelBase/WerUnregisterAdditionalProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerUnregisterAdditionalProcess,WerUnregisterAdditionalProcess,1801 diff --git a/libc/nt/KernelBase/WerUnregisterAppLocalDump.s b/libc/nt/KernelBase/WerUnregisterAppLocalDump.s new file mode 100644 index 00000000..c9f262cd --- /dev/null +++ b/libc/nt/KernelBase/WerUnregisterAppLocalDump.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerUnregisterAppLocalDump,WerUnregisterAppLocalDump,1802 diff --git a/libc/nt/KernelBase/WerUnregisterCustomMetadata.s b/libc/nt/KernelBase/WerUnregisterCustomMetadata.s new file mode 100644 index 00000000..5cc11451 --- /dev/null +++ b/libc/nt/KernelBase/WerUnregisterCustomMetadata.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerUnregisterCustomMetadata,WerUnregisterCustomMetadata,1803 diff --git a/libc/nt/KernelBase/WerUnregisterExcludedMemoryBlock.s b/libc/nt/KernelBase/WerUnregisterExcludedMemoryBlock.s new file mode 100644 index 00000000..cd82ff0c --- /dev/null +++ b/libc/nt/KernelBase/WerUnregisterExcludedMemoryBlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerUnregisterExcludedMemoryBlock,WerUnregisterExcludedMemoryBlock,1804 diff --git a/libc/nt/KernelBase/WerUnregisterFile.s b/libc/nt/KernelBase/WerUnregisterFile.s new file mode 100644 index 00000000..2d94eb10 --- /dev/null +++ b/libc/nt/KernelBase/WerUnregisterFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerUnregisterFile,WerUnregisterFile,1805 diff --git a/libc/nt/KernelBase/WerUnregisterMemoryBlock.s b/libc/nt/KernelBase/WerUnregisterMemoryBlock.s new file mode 100644 index 00000000..65dfb28b --- /dev/null +++ b/libc/nt/KernelBase/WerUnregisterMemoryBlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerUnregisterMemoryBlock,WerUnregisterMemoryBlock,1806 diff --git a/libc/nt/KernelBase/WerUnregisterRuntimeExceptionModule.s b/libc/nt/KernelBase/WerUnregisterRuntimeExceptionModule.s new file mode 100644 index 00000000..1482ae87 --- /dev/null +++ b/libc/nt/KernelBase/WerUnregisterRuntimeExceptionModule.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerUnregisterRuntimeExceptionModule,WerUnregisterRuntimeExceptionModule,1807 diff --git a/libc/nt/KernelBase/WerpNotifyLoadStringResource.s b/libc/nt/KernelBase/WerpNotifyLoadStringResource.s new file mode 100644 index 00000000..07edd933 --- /dev/null +++ b/libc/nt/KernelBase/WerpNotifyLoadStringResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerpNotifyLoadStringResource,WerpNotifyLoadStringResource,1808 diff --git a/libc/nt/KernelBase/WerpNotifyUseStringResource.s b/libc/nt/KernelBase/WerpNotifyUseStringResource.s new file mode 100644 index 00000000..9556ded0 --- /dev/null +++ b/libc/nt/KernelBase/WerpNotifyUseStringResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WerpNotifyUseStringResource,WerpNotifyUseStringResource,1809 diff --git a/libc/nt/KernelBase/WideCharToMultiByte.s b/libc/nt/KernelBase/WideCharToMultiByte.s new file mode 100644 index 00000000..910afe93 --- /dev/null +++ b/libc/nt/KernelBase/WideCharToMultiByte.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WideCharToMultiByte,WideCharToMultiByte,1810 diff --git a/libc/nt/KernelBase/Wow64DisableWow64FsRedirection.s b/libc/nt/KernelBase/Wow64DisableWow64FsRedirection.s new file mode 100644 index 00000000..25ecbe76 --- /dev/null +++ b/libc/nt/KernelBase/Wow64DisableWow64FsRedirection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_Wow64DisableWow64FsRedirection,Wow64DisableWow64FsRedirection,1811 diff --git a/libc/nt/KernelBase/Wow64RevertWow64FsRedirection.s b/libc/nt/KernelBase/Wow64RevertWow64FsRedirection.s new file mode 100644 index 00000000..1b99d703 --- /dev/null +++ b/libc/nt/KernelBase/Wow64RevertWow64FsRedirection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_Wow64RevertWow64FsRedirection,Wow64RevertWow64FsRedirection,1812 diff --git a/libc/nt/KernelBase/Wow64SetThreadDefaultGuestMachine.s b/libc/nt/KernelBase/Wow64SetThreadDefaultGuestMachine.s new file mode 100644 index 00000000..f68ffb1a --- /dev/null +++ b/libc/nt/KernelBase/Wow64SetThreadDefaultGuestMachine.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_Wow64SetThreadDefaultGuestMachine,Wow64SetThreadDefaultGuestMachine,1813 diff --git a/libc/nt/KernelBase/WriteConsoleA.s b/libc/nt/KernelBase/WriteConsoleA.s new file mode 100644 index 00000000..207963a8 --- /dev/null +++ b/libc/nt/KernelBase/WriteConsoleA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WriteConsoleA,WriteConsoleA,1814 + + .text.windows +WriteConsoleA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WriteConsoleA(%rip),%rax + jmp __sysv2nt6 + .endfn WriteConsoleA,globl + .previous diff --git a/libc/nt/KernelBase/WriteConsoleInputA.s b/libc/nt/KernelBase/WriteConsoleInputA.s new file mode 100644 index 00000000..e76fa616 --- /dev/null +++ b/libc/nt/KernelBase/WriteConsoleInputA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WriteConsoleInputA,WriteConsoleInputA,1815 + + .text.windows +WriteConsoleInputA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WriteConsoleInputA(%rip),%rax + jmp __sysv2nt + .endfn WriteConsoleInputA,globl + .previous diff --git a/libc/nt/KernelBase/WriteConsoleInputW.s b/libc/nt/KernelBase/WriteConsoleInputW.s new file mode 100644 index 00000000..b5be8fab --- /dev/null +++ b/libc/nt/KernelBase/WriteConsoleInputW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WriteConsoleInputW,WriteConsoleInputW,1816 + + .text.windows +WriteConsoleInput: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WriteConsoleInputW(%rip),%rax + jmp __sysv2nt + .endfn WriteConsoleInput,globl + .previous diff --git a/libc/nt/KernelBase/WriteConsoleOutputA.s b/libc/nt/KernelBase/WriteConsoleOutputA.s new file mode 100644 index 00000000..b6e0b7f8 --- /dev/null +++ b/libc/nt/KernelBase/WriteConsoleOutputA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WriteConsoleOutputA,WriteConsoleOutputA,1817 diff --git a/libc/nt/KernelBase/WriteConsoleOutputAttribute.s b/libc/nt/KernelBase/WriteConsoleOutputAttribute.s new file mode 100644 index 00000000..361c39f3 --- /dev/null +++ b/libc/nt/KernelBase/WriteConsoleOutputAttribute.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WriteConsoleOutputAttribute,WriteConsoleOutputAttribute,1818 + + .text.windows +WriteConsoleOutputAttribute: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WriteConsoleOutputAttribute(%rip),%rax + jmp __sysv2nt6 + .endfn WriteConsoleOutputAttribute,globl + .previous diff --git a/libc/nt/KernelBase/WriteConsoleOutputCharacterA.s b/libc/nt/KernelBase/WriteConsoleOutputCharacterA.s new file mode 100644 index 00000000..d9f3ed23 --- /dev/null +++ b/libc/nt/KernelBase/WriteConsoleOutputCharacterA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WriteConsoleOutputCharacterA,WriteConsoleOutputCharacterA,1819 + + .text.windows +WriteConsoleOutputCharacterA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WriteConsoleOutputCharacterA(%rip),%rax + jmp __sysv2nt6 + .endfn WriteConsoleOutputCharacterA,globl + .previous diff --git a/libc/nt/KernelBase/WriteConsoleOutputCharacterW.s b/libc/nt/KernelBase/WriteConsoleOutputCharacterW.s new file mode 100644 index 00000000..df06a05e --- /dev/null +++ b/libc/nt/KernelBase/WriteConsoleOutputCharacterW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WriteConsoleOutputCharacterW,WriteConsoleOutputCharacterW,1820 + + .text.windows +WriteConsoleOutputCharacter: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WriteConsoleOutputCharacterW(%rip),%rax + jmp __sysv2nt6 + .endfn WriteConsoleOutputCharacter,globl + .previous diff --git a/libc/nt/KernelBase/WriteConsoleOutputW.s b/libc/nt/KernelBase/WriteConsoleOutputW.s new file mode 100644 index 00000000..63d2c9d4 --- /dev/null +++ b/libc/nt/KernelBase/WriteConsoleOutputW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WriteConsoleOutputW,WriteConsoleOutputW,1821 diff --git a/libc/nt/KernelBase/WriteConsoleW.s b/libc/nt/KernelBase/WriteConsoleW.s new file mode 100644 index 00000000..dacb470e --- /dev/null +++ b/libc/nt/KernelBase/WriteConsoleW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WriteConsoleW,WriteConsoleW,1822 + + .text.windows +WriteConsole: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WriteConsoleW(%rip),%rax + jmp __sysv2nt6 + .endfn WriteConsole,globl + .previous diff --git a/libc/nt/KernelBase/WriteFile.s b/libc/nt/KernelBase/WriteFile.s new file mode 100644 index 00000000..7fb711ed --- /dev/null +++ b/libc/nt/KernelBase/WriteFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WriteFile,WriteFile,1823 + + .text.windows +WriteFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WriteFile(%rip),%rax + jmp __sysv2nt6 + .endfn WriteFile,globl + .previous diff --git a/libc/nt/KernelBase/WriteFileEx.s b/libc/nt/KernelBase/WriteFileEx.s new file mode 100644 index 00000000..448d1b81 --- /dev/null +++ b/libc/nt/KernelBase/WriteFileEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WriteFileEx,WriteFileEx,1824 diff --git a/libc/nt/KernelBase/WriteFileGather.s b/libc/nt/KernelBase/WriteFileGather.s new file mode 100644 index 00000000..2f9569c6 --- /dev/null +++ b/libc/nt/KernelBase/WriteFileGather.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WriteFileGather,WriteFileGather,1825 + + .text.windows +WriteFileGather: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WriteFileGather(%rip),%rax + jmp __sysv2nt6 + .endfn WriteFileGather,globl + .previous diff --git a/libc/nt/KernelBase/WriteProcessMemory.s b/libc/nt/KernelBase/WriteProcessMemory.s new file mode 100644 index 00000000..b7c8945e --- /dev/null +++ b/libc/nt/KernelBase/WriteProcessMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WriteProcessMemory,WriteProcessMemory,1826 diff --git a/libc/nt/KernelBase/WriteStateAtomValue.s b/libc/nt/KernelBase/WriteStateAtomValue.s new file mode 100644 index 00000000..e6d971f9 --- /dev/null +++ b/libc/nt/KernelBase/WriteStateAtomValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WriteStateAtomValue,WriteStateAtomValue,1827 diff --git a/libc/nt/KernelBase/WriteStateContainerValue.s b/libc/nt/KernelBase/WriteStateContainerValue.s new file mode 100644 index 00000000..473414d8 --- /dev/null +++ b/libc/nt/KernelBase/WriteStateContainerValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_WriteStateContainerValue,WriteStateContainerValue,1828 diff --git a/libc/nt/KernelBase/ZombifyActCtx.s b/libc/nt/KernelBase/ZombifyActCtx.s new file mode 100644 index 00000000..48e5fa0d --- /dev/null +++ b/libc/nt/KernelBase/ZombifyActCtx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_ZombifyActCtx,ZombifyActCtx,1829 diff --git a/libc/nt/KernelBase/_AddMUIStringToCache.s b/libc/nt/KernelBase/_AddMUIStringToCache.s new file mode 100644 index 00000000..d841e13e --- /dev/null +++ b/libc/nt/KernelBase/_AddMUIStringToCache.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp__AddMUIStringToCache,_AddMUIStringToCache,1830 diff --git a/libc/nt/KernelBase/_GetMUIStringFromCache.s b/libc/nt/KernelBase/_GetMUIStringFromCache.s new file mode 100644 index 00000000..479b928c --- /dev/null +++ b/libc/nt/KernelBase/_GetMUIStringFromCache.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp__GetMUIStringFromCache,_GetMUIStringFromCache,1831 diff --git a/libc/nt/KernelBase/_OpenMuiStringCache.s b/libc/nt/KernelBase/_OpenMuiStringCache.s new file mode 100644 index 00000000..71be50cc --- /dev/null +++ b/libc/nt/KernelBase/_OpenMuiStringCache.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp__OpenMuiStringCache,_OpenMuiStringCache,1832 diff --git a/libc/nt/KernelBase/_amsg_exit.s b/libc/nt/KernelBase/_amsg_exit.s new file mode 100644 index 00000000..56b547b9 --- /dev/null +++ b/libc/nt/KernelBase/_amsg_exit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp__amsg_exit,_amsg_exit,1838 diff --git a/libc/nt/KernelBase/_c_exit.s b/libc/nt/KernelBase/_c_exit.s new file mode 100644 index 00000000..942e9432 --- /dev/null +++ b/libc/nt/KernelBase/_c_exit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp__c_exit,_c_exit,1839 diff --git a/libc/nt/KernelBase/_cexit.s b/libc/nt/KernelBase/_cexit.s new file mode 100644 index 00000000..4e6d4822 --- /dev/null +++ b/libc/nt/KernelBase/_cexit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp__cexit,_cexit,1840 diff --git a/libc/nt/KernelBase/_exit.s b/libc/nt/KernelBase/_exit.s new file mode 100644 index 00000000..14099d42 --- /dev/null +++ b/libc/nt/KernelBase/_exit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp__exit,_exit,1841 diff --git a/libc/nt/KernelBase/_initterm.s b/libc/nt/KernelBase/_initterm.s new file mode 100644 index 00000000..411f2950 --- /dev/null +++ b/libc/nt/KernelBase/_initterm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp__initterm,_initterm,1842 diff --git a/libc/nt/KernelBase/_initterm_e.s b/libc/nt/KernelBase/_initterm_e.s new file mode 100644 index 00000000..7e810ad1 --- /dev/null +++ b/libc/nt/KernelBase/_initterm_e.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp__initterm_e,_initterm_e,1843 diff --git a/libc/nt/KernelBase/_invalid_parameter.s b/libc/nt/KernelBase/_invalid_parameter.s new file mode 100644 index 00000000..b434c20d --- /dev/null +++ b/libc/nt/KernelBase/_invalid_parameter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp__invalid_parameter,_invalid_parameter,1844 diff --git a/libc/nt/KernelBase/_onexit.s b/libc/nt/KernelBase/_onexit.s new file mode 100644 index 00000000..4c98622e --- /dev/null +++ b/libc/nt/KernelBase/_onexit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp__onexit,_onexit,1846 diff --git a/libc/nt/KernelBase/_purecall.s b/libc/nt/KernelBase/_purecall.s new file mode 100644 index 00000000..d936fb19 --- /dev/null +++ b/libc/nt/KernelBase/_purecall.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp__purecall,_purecall,1847 diff --git a/libc/nt/KernelBase/_time64.s b/libc/nt/KernelBase/_time64.s new file mode 100644 index 00000000..92b461fc --- /dev/null +++ b/libc/nt/KernelBase/_time64.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp__time64,_time64,1848 diff --git a/libc/nt/KernelBase/atexit.s b/libc/nt/KernelBase/atexit.s new file mode 100644 index 00000000..c7e24b53 --- /dev/null +++ b/libc/nt/KernelBase/atexit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_atexit,atexit,1849 diff --git a/libc/nt/KernelBase/exit.s b/libc/nt/KernelBase/exit.s new file mode 100644 index 00000000..74b61898 --- /dev/null +++ b/libc/nt/KernelBase/exit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_exit,exit,1850 diff --git a/libc/nt/KernelBase/hgets.s b/libc/nt/KernelBase/hgets.s new file mode 100644 index 00000000..819fbd41 --- /dev/null +++ b/libc/nt/KernelBase/hgets.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_hgets,hgets,1851 diff --git a/libc/nt/KernelBase/hwprintf.s b/libc/nt/KernelBase/hwprintf.s new file mode 100644 index 00000000..e9a5edd2 --- /dev/null +++ b/libc/nt/KernelBase/hwprintf.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_hwprintf,hwprintf,1852 diff --git a/libc/nt/KernelBase/lstrcmpA.s b/libc/nt/KernelBase/lstrcmpA.s new file mode 100644 index 00000000..3701f839 --- /dev/null +++ b/libc/nt/KernelBase/lstrcmpA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_lstrcmpA,lstrcmpA,1854 diff --git a/libc/nt/KernelBase/lstrcmpW.s b/libc/nt/KernelBase/lstrcmpW.s new file mode 100644 index 00000000..79f07cc7 --- /dev/null +++ b/libc/nt/KernelBase/lstrcmpW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_lstrcmpW,lstrcmpW,1855 diff --git a/libc/nt/KernelBase/lstrcmpiA.s b/libc/nt/KernelBase/lstrcmpiA.s new file mode 100644 index 00000000..e95676d9 --- /dev/null +++ b/libc/nt/KernelBase/lstrcmpiA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_lstrcmpiA,lstrcmpiA,1857 diff --git a/libc/nt/KernelBase/lstrcmpiW.s b/libc/nt/KernelBase/lstrcmpiW.s new file mode 100644 index 00000000..a9318f39 --- /dev/null +++ b/libc/nt/KernelBase/lstrcmpiW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_lstrcmpiW,lstrcmpiW,1858 diff --git a/libc/nt/KernelBase/lstrcpynA.s b/libc/nt/KernelBase/lstrcpynA.s new file mode 100644 index 00000000..6e53f934 --- /dev/null +++ b/libc/nt/KernelBase/lstrcpynA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_lstrcpynA,lstrcpynA,1860 diff --git a/libc/nt/KernelBase/lstrcpynW.s b/libc/nt/KernelBase/lstrcpynW.s new file mode 100644 index 00000000..2bb7e2c8 --- /dev/null +++ b/libc/nt/KernelBase/lstrcpynW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_lstrcpynW,lstrcpynW,1861 diff --git a/libc/nt/KernelBase/lstrlenA.s b/libc/nt/KernelBase/lstrlenA.s new file mode 100644 index 00000000..4a9ef3c0 --- /dev/null +++ b/libc/nt/KernelBase/lstrlenA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_lstrlenA,lstrlenA,1863 diff --git a/libc/nt/KernelBase/lstrlenW.s b/libc/nt/KernelBase/lstrlenW.s new file mode 100644 index 00000000..8f82c3d5 --- /dev/null +++ b/libc/nt/KernelBase/lstrlenW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_lstrlenW,lstrlenW,1864 diff --git a/libc/nt/KernelBase/time.s b/libc/nt/KernelBase/time.s new file mode 100644 index 00000000..9eef0252 --- /dev/null +++ b/libc/nt/KernelBase/time.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_time,time,1865 diff --git a/libc/nt/KernelBase/wprintf.s b/libc/nt/KernelBase/wprintf.s new file mode 100644 index 00000000..3a0966d4 --- /dev/null +++ b/libc/nt/KernelBase/wprintf.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp KernelBase,__imp_wprintf,wprintf,1866 diff --git a/libc/nt/MsWSock/AcceptEx.s b/libc/nt/MsWSock/AcceptEx.s new file mode 100644 index 00000000..430f9684 --- /dev/null +++ b/libc/nt/MsWSock/AcceptEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp MsWSock,__imp_AcceptEx,AcceptEx,1 + + .text.windows +AcceptEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_AcceptEx(%rip),%rax + jmp __sysv2nt8 + .endfn AcceptEx,globl + .previous diff --git a/libc/nt/MsWSock/GetAcceptExSockaddrs.s b/libc/nt/MsWSock/GetAcceptExSockaddrs.s new file mode 100644 index 00000000..0aad36d0 --- /dev/null +++ b/libc/nt/MsWSock/GetAcceptExSockaddrs.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp MsWSock,__imp_GetAcceptExSockaddrs,GetAcceptExSockaddrs,4 + + .text.windows +GetAcceptExSockaddrs: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetAcceptExSockaddrs(%rip),%rax + jmp __sysv2nt8 + .endfn GetAcceptExSockaddrs,globl + .previous diff --git a/libc/nt/MsWSock/TransmitFile.s b/libc/nt/MsWSock/TransmitFile.s new file mode 100644 index 00000000..f4c66685 --- /dev/null +++ b/libc/nt/MsWSock/TransmitFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp MsWSock,__imp_TransmitFile,TransmitFile,53 + + .text.windows +TransmitFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_TransmitFile(%rip),%rax + jmp __sysv2nt8 + .endfn TransmitFile,globl + .previous diff --git a/libc/nt/MsWSock/WSARecvEx.s b/libc/nt/MsWSock/WSARecvEx.s new file mode 100644 index 00000000..1b460494 --- /dev/null +++ b/libc/nt/MsWSock/WSARecvEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp MsWSock,__imp_WSARecvEx,WSARecvEx,54 diff --git a/libc/nt/accounting.h b/libc/nt/accounting.h new file mode 100644 index 00000000..8a4de280 --- /dev/null +++ b/libc/nt/accounting.h @@ -0,0 +1,69 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ACCOUNTING_H_ +#define COSMOPOLITAN_LIBC_NT_ACCOUNTING_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » accounting ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +struct NtFileTime; +struct NtIoCounters; +struct NtMemoryStatusEx; + +int GetUserName(char16_t (*buf)[257], uint32_t *in_out_size); +bool32 GlobalMemoryStatusEx(struct NtMemoryStatusEx *lpBuffer); +int32_t GetExitCodeProcess(int64_t hProcess, uint32_t *lpExitCode); +int32_t GetProcessHandleCount(int64_t hProcess, uint32_t *pdwHandleCount); +bool32 GetProcessTimes(int64_t hProcess, + struct NtFileTime *out_lpCreationFileTime, + struct NtFileTime *out_lpExitFileTime, + struct NtFileTime *out_lpKernelFileTime, + struct NtFileTime *out_lpUserFileTime); +bool32 GetThreadTimes(int64_t hThread, + struct NtFileTime *out_lpCreationFileTime, + struct NtFileTime *out_lpExitFileTime, + struct NtFileTime *out_lpKernelFileTime, + struct NtFileTime *out_lpUserFileTime); +int32_t GetProcessIoCounters(int64_t hProcess, + struct NtIoCounters *lpIoCounters); +int32_t GetProcessWorkingSetSize(int64_t hProcess, + uint64_t *lpMinimumWorkingSetSize, + uint64_t *lpMaximumWorkingSetSize); +int32_t GetProcessWorkingSetSizeEx(int64_t hProcess, + uint64_t *lpMinimumWorkingSetSize, + uint64_t *lpMaximumWorkingSetSize, + uint32_t *Flags); +int32_t SetProcessWorkingSetSize(int64_t hProcess, + uint64_t dwMinimumWorkingSetSize, + uint64_t dwMaximumWorkingSetSize); +int32_t SetProcessWorkingSetSizeEx(int64_t hProcess, + uint64_t dwMinimumWorkingSetSize, + uint64_t dwMaximumWorkingSetSize, + uint32_t Flags); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ACCOUNTING_H_ */ diff --git a/libc/nt/advapi32/AbortSystemShutdownA.s b/libc/nt/advapi32/AbortSystemShutdownA.s new file mode 100644 index 00000000..2d942815 --- /dev/null +++ b/libc/nt/advapi32/AbortSystemShutdownA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AbortSystemShutdownA,AbortSystemShutdownA,1005 diff --git a/libc/nt/advapi32/AbortSystemShutdownW.s b/libc/nt/advapi32/AbortSystemShutdownW.s new file mode 100644 index 00000000..7e1a343a --- /dev/null +++ b/libc/nt/advapi32/AbortSystemShutdownW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AbortSystemShutdownW,AbortSystemShutdownW,1006 diff --git a/libc/nt/advapi32/AccessCheckAndAuditAlarmA.s b/libc/nt/advapi32/AccessCheckAndAuditAlarmA.s new file mode 100644 index 00000000..129f1615 --- /dev/null +++ b/libc/nt/advapi32/AccessCheckAndAuditAlarmA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AccessCheckAndAuditAlarmA,AccessCheckAndAuditAlarmA,1008 diff --git a/libc/nt/advapi32/AccessCheckByTypeAndAuditAlarmA.s b/libc/nt/advapi32/AccessCheckByTypeAndAuditAlarmA.s new file mode 100644 index 00000000..4eadb8cd --- /dev/null +++ b/libc/nt/advapi32/AccessCheckByTypeAndAuditAlarmA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AccessCheckByTypeAndAuditAlarmA,AccessCheckByTypeAndAuditAlarmA,1011 diff --git a/libc/nt/advapi32/AccessCheckByTypeResultListAndAuditAlarmA.s b/libc/nt/advapi32/AccessCheckByTypeResultListAndAuditAlarmA.s new file mode 100644 index 00000000..1c8f48df --- /dev/null +++ b/libc/nt/advapi32/AccessCheckByTypeResultListAndAuditAlarmA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AccessCheckByTypeResultListAndAuditAlarmA,AccessCheckByTypeResultListAndAuditAlarmA,1014 diff --git a/libc/nt/advapi32/AccessCheckByTypeResultListAndAuditAlarmByHandleA.s b/libc/nt/advapi32/AccessCheckByTypeResultListAndAuditAlarmByHandleA.s new file mode 100644 index 00000000..80c41743 --- /dev/null +++ b/libc/nt/advapi32/AccessCheckByTypeResultListAndAuditAlarmByHandleA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AccessCheckByTypeResultListAndAuditAlarmByHandleA,AccessCheckByTypeResultListAndAuditAlarmByHandleA,1015 diff --git a/libc/nt/advapi32/AddConditionalAce.s b/libc/nt/advapi32/AddConditionalAce.s new file mode 100644 index 00000000..81e9bc6f --- /dev/null +++ b/libc/nt/advapi32/AddConditionalAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AddConditionalAce,AddConditionalAce,1028 diff --git a/libc/nt/advapi32/AddUsersToEncryptedFile.s b/libc/nt/advapi32/AddUsersToEncryptedFile.s new file mode 100644 index 00000000..4b9c39d3 --- /dev/null +++ b/libc/nt/advapi32/AddUsersToEncryptedFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AddUsersToEncryptedFile,AddUsersToEncryptedFile,1030 diff --git a/libc/nt/advapi32/AddUsersToEncryptedFileEx.s b/libc/nt/advapi32/AddUsersToEncryptedFileEx.s new file mode 100644 index 00000000..71268708 --- /dev/null +++ b/libc/nt/advapi32/AddUsersToEncryptedFileEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AddUsersToEncryptedFileEx,AddUsersToEncryptedFileEx,1031 diff --git a/libc/nt/advapi32/AuditComputeEffectivePolicyBySid.s b/libc/nt/advapi32/AuditComputeEffectivePolicyBySid.s new file mode 100644 index 00000000..0542470f --- /dev/null +++ b/libc/nt/advapi32/AuditComputeEffectivePolicyBySid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditComputeEffectivePolicyBySid,AuditComputeEffectivePolicyBySid,1038 diff --git a/libc/nt/advapi32/AuditComputeEffectivePolicyByToken.s b/libc/nt/advapi32/AuditComputeEffectivePolicyByToken.s new file mode 100644 index 00000000..59ca2c64 --- /dev/null +++ b/libc/nt/advapi32/AuditComputeEffectivePolicyByToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditComputeEffectivePolicyByToken,AuditComputeEffectivePolicyByToken,1039 diff --git a/libc/nt/advapi32/AuditEnumerateCategories.s b/libc/nt/advapi32/AuditEnumerateCategories.s new file mode 100644 index 00000000..23025dbf --- /dev/null +++ b/libc/nt/advapi32/AuditEnumerateCategories.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditEnumerateCategories,AuditEnumerateCategories,1040 diff --git a/libc/nt/advapi32/AuditEnumeratePerUserPolicy.s b/libc/nt/advapi32/AuditEnumeratePerUserPolicy.s new file mode 100644 index 00000000..70a26550 --- /dev/null +++ b/libc/nt/advapi32/AuditEnumeratePerUserPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditEnumeratePerUserPolicy,AuditEnumeratePerUserPolicy,1041 diff --git a/libc/nt/advapi32/AuditEnumerateSubCategories.s b/libc/nt/advapi32/AuditEnumerateSubCategories.s new file mode 100644 index 00000000..9e70a352 --- /dev/null +++ b/libc/nt/advapi32/AuditEnumerateSubCategories.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditEnumerateSubCategories,AuditEnumerateSubCategories,1042 diff --git a/libc/nt/advapi32/AuditFree.s b/libc/nt/advapi32/AuditFree.s new file mode 100644 index 00000000..2b1c9bab --- /dev/null +++ b/libc/nt/advapi32/AuditFree.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditFree,AuditFree,1043 diff --git a/libc/nt/advapi32/AuditLookupCategoryGuidFromCategoryId.s b/libc/nt/advapi32/AuditLookupCategoryGuidFromCategoryId.s new file mode 100644 index 00000000..dbdd63ca --- /dev/null +++ b/libc/nt/advapi32/AuditLookupCategoryGuidFromCategoryId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditLookupCategoryGuidFromCategoryId,AuditLookupCategoryGuidFromCategoryId,1044 diff --git a/libc/nt/advapi32/AuditLookupCategoryIdFromCategoryGuid.s b/libc/nt/advapi32/AuditLookupCategoryIdFromCategoryGuid.s new file mode 100644 index 00000000..c72fe4c4 --- /dev/null +++ b/libc/nt/advapi32/AuditLookupCategoryIdFromCategoryGuid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditLookupCategoryIdFromCategoryGuid,AuditLookupCategoryIdFromCategoryGuid,1045 diff --git a/libc/nt/advapi32/AuditLookupCategoryNameA.s b/libc/nt/advapi32/AuditLookupCategoryNameA.s new file mode 100644 index 00000000..b0ac7dbc --- /dev/null +++ b/libc/nt/advapi32/AuditLookupCategoryNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditLookupCategoryNameA,AuditLookupCategoryNameA,1046 diff --git a/libc/nt/advapi32/AuditLookupCategoryNameW.s b/libc/nt/advapi32/AuditLookupCategoryNameW.s new file mode 100644 index 00000000..51e0fbcb --- /dev/null +++ b/libc/nt/advapi32/AuditLookupCategoryNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditLookupCategoryNameW,AuditLookupCategoryNameW,1047 diff --git a/libc/nt/advapi32/AuditLookupSubCategoryNameA.s b/libc/nt/advapi32/AuditLookupSubCategoryNameA.s new file mode 100644 index 00000000..6f582a72 --- /dev/null +++ b/libc/nt/advapi32/AuditLookupSubCategoryNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditLookupSubCategoryNameA,AuditLookupSubCategoryNameA,1048 diff --git a/libc/nt/advapi32/AuditLookupSubCategoryNameW.s b/libc/nt/advapi32/AuditLookupSubCategoryNameW.s new file mode 100644 index 00000000..af6c6b37 --- /dev/null +++ b/libc/nt/advapi32/AuditLookupSubCategoryNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditLookupSubCategoryNameW,AuditLookupSubCategoryNameW,1049 diff --git a/libc/nt/advapi32/AuditQueryGlobalSaclA.s b/libc/nt/advapi32/AuditQueryGlobalSaclA.s new file mode 100644 index 00000000..a2b18b67 --- /dev/null +++ b/libc/nt/advapi32/AuditQueryGlobalSaclA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditQueryGlobalSaclA,AuditQueryGlobalSaclA,1050 diff --git a/libc/nt/advapi32/AuditQueryGlobalSaclW.s b/libc/nt/advapi32/AuditQueryGlobalSaclW.s new file mode 100644 index 00000000..0f955399 --- /dev/null +++ b/libc/nt/advapi32/AuditQueryGlobalSaclW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditQueryGlobalSaclW,AuditQueryGlobalSaclW,1051 diff --git a/libc/nt/advapi32/AuditQueryPerUserPolicy.s b/libc/nt/advapi32/AuditQueryPerUserPolicy.s new file mode 100644 index 00000000..e2f13dab --- /dev/null +++ b/libc/nt/advapi32/AuditQueryPerUserPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditQueryPerUserPolicy,AuditQueryPerUserPolicy,1052 diff --git a/libc/nt/advapi32/AuditQuerySecurity.s b/libc/nt/advapi32/AuditQuerySecurity.s new file mode 100644 index 00000000..2191da05 --- /dev/null +++ b/libc/nt/advapi32/AuditQuerySecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditQuerySecurity,AuditQuerySecurity,1053 diff --git a/libc/nt/advapi32/AuditQuerySystemPolicy.s b/libc/nt/advapi32/AuditQuerySystemPolicy.s new file mode 100644 index 00000000..ab74eb86 --- /dev/null +++ b/libc/nt/advapi32/AuditQuerySystemPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditQuerySystemPolicy,AuditQuerySystemPolicy,1054 diff --git a/libc/nt/advapi32/AuditSetGlobalSaclA.s b/libc/nt/advapi32/AuditSetGlobalSaclA.s new file mode 100644 index 00000000..cba5bc82 --- /dev/null +++ b/libc/nt/advapi32/AuditSetGlobalSaclA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditSetGlobalSaclA,AuditSetGlobalSaclA,1055 diff --git a/libc/nt/advapi32/AuditSetGlobalSaclW.s b/libc/nt/advapi32/AuditSetGlobalSaclW.s new file mode 100644 index 00000000..b881abba --- /dev/null +++ b/libc/nt/advapi32/AuditSetGlobalSaclW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditSetGlobalSaclW,AuditSetGlobalSaclW,1056 diff --git a/libc/nt/advapi32/AuditSetPerUserPolicy.s b/libc/nt/advapi32/AuditSetPerUserPolicy.s new file mode 100644 index 00000000..74f898bb --- /dev/null +++ b/libc/nt/advapi32/AuditSetPerUserPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditSetPerUserPolicy,AuditSetPerUserPolicy,1057 diff --git a/libc/nt/advapi32/AuditSetSecurity.s b/libc/nt/advapi32/AuditSetSecurity.s new file mode 100644 index 00000000..741e0c8d --- /dev/null +++ b/libc/nt/advapi32/AuditSetSecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditSetSecurity,AuditSetSecurity,1058 diff --git a/libc/nt/advapi32/AuditSetSystemPolicy.s b/libc/nt/advapi32/AuditSetSystemPolicy.s new file mode 100644 index 00000000..c64636ed --- /dev/null +++ b/libc/nt/advapi32/AuditSetSystemPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_AuditSetSystemPolicy,AuditSetSystemPolicy,1059 diff --git a/libc/nt/advapi32/BackupEventLogA.s b/libc/nt/advapi32/BackupEventLogA.s new file mode 100644 index 00000000..a14c1704 --- /dev/null +++ b/libc/nt/advapi32/BackupEventLogA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BackupEventLogA,BackupEventLogA,1060 diff --git a/libc/nt/advapi32/BackupEventLogW.s b/libc/nt/advapi32/BackupEventLogW.s new file mode 100644 index 00000000..9b77c1b2 --- /dev/null +++ b/libc/nt/advapi32/BackupEventLogW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BackupEventLogW,BackupEventLogW,1061 diff --git a/libc/nt/advapi32/BaseRegCloseKey.s b/libc/nt/advapi32/BaseRegCloseKey.s new file mode 100644 index 00000000..40366160 --- /dev/null +++ b/libc/nt/advapi32/BaseRegCloseKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BaseRegCloseKey,BaseRegCloseKey,1062 diff --git a/libc/nt/advapi32/BaseRegCreateKey.s b/libc/nt/advapi32/BaseRegCreateKey.s new file mode 100644 index 00000000..9bca7c7a --- /dev/null +++ b/libc/nt/advapi32/BaseRegCreateKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BaseRegCreateKey,BaseRegCreateKey,1063 diff --git a/libc/nt/advapi32/BaseRegDeleteKeyEx.s b/libc/nt/advapi32/BaseRegDeleteKeyEx.s new file mode 100644 index 00000000..c58ae724 --- /dev/null +++ b/libc/nt/advapi32/BaseRegDeleteKeyEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BaseRegDeleteKeyEx,BaseRegDeleteKeyEx,1064 diff --git a/libc/nt/advapi32/BaseRegDeleteValue.s b/libc/nt/advapi32/BaseRegDeleteValue.s new file mode 100644 index 00000000..53ccd455 --- /dev/null +++ b/libc/nt/advapi32/BaseRegDeleteValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BaseRegDeleteValue,BaseRegDeleteValue,1065 diff --git a/libc/nt/advapi32/BaseRegFlushKey.s b/libc/nt/advapi32/BaseRegFlushKey.s new file mode 100644 index 00000000..a5efa299 --- /dev/null +++ b/libc/nt/advapi32/BaseRegFlushKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BaseRegFlushKey,BaseRegFlushKey,1066 diff --git a/libc/nt/advapi32/BaseRegGetVersion.s b/libc/nt/advapi32/BaseRegGetVersion.s new file mode 100644 index 00000000..a46ece16 --- /dev/null +++ b/libc/nt/advapi32/BaseRegGetVersion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BaseRegGetVersion,BaseRegGetVersion,1067 diff --git a/libc/nt/advapi32/BaseRegLoadKey.s b/libc/nt/advapi32/BaseRegLoadKey.s new file mode 100644 index 00000000..e838781b --- /dev/null +++ b/libc/nt/advapi32/BaseRegLoadKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BaseRegLoadKey,BaseRegLoadKey,1068 diff --git a/libc/nt/advapi32/BaseRegOpenKey.s b/libc/nt/advapi32/BaseRegOpenKey.s new file mode 100644 index 00000000..f399378f --- /dev/null +++ b/libc/nt/advapi32/BaseRegOpenKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BaseRegOpenKey,BaseRegOpenKey,1069 diff --git a/libc/nt/advapi32/BaseRegRestoreKey.s b/libc/nt/advapi32/BaseRegRestoreKey.s new file mode 100644 index 00000000..fc7d07c8 --- /dev/null +++ b/libc/nt/advapi32/BaseRegRestoreKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BaseRegRestoreKey,BaseRegRestoreKey,1070 diff --git a/libc/nt/advapi32/BaseRegSaveKeyEx.s b/libc/nt/advapi32/BaseRegSaveKeyEx.s new file mode 100644 index 00000000..af1c0ad9 --- /dev/null +++ b/libc/nt/advapi32/BaseRegSaveKeyEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BaseRegSaveKeyEx,BaseRegSaveKeyEx,1071 diff --git a/libc/nt/advapi32/BaseRegSetKeySecurity.s b/libc/nt/advapi32/BaseRegSetKeySecurity.s new file mode 100644 index 00000000..a3486877 --- /dev/null +++ b/libc/nt/advapi32/BaseRegSetKeySecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BaseRegSetKeySecurity,BaseRegSetKeySecurity,1072 diff --git a/libc/nt/advapi32/BaseRegSetValue.s b/libc/nt/advapi32/BaseRegSetValue.s new file mode 100644 index 00000000..5f50829b --- /dev/null +++ b/libc/nt/advapi32/BaseRegSetValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BaseRegSetValue,BaseRegSetValue,1073 diff --git a/libc/nt/advapi32/BaseRegUnLoadKey.s b/libc/nt/advapi32/BaseRegUnLoadKey.s new file mode 100644 index 00000000..2d9f602b --- /dev/null +++ b/libc/nt/advapi32/BaseRegUnLoadKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BaseRegUnLoadKey,BaseRegUnLoadKey,1074 diff --git a/libc/nt/advapi32/BuildExplicitAccessWithNameA.s b/libc/nt/advapi32/BuildExplicitAccessWithNameA.s new file mode 100644 index 00000000..6bf7e7c6 --- /dev/null +++ b/libc/nt/advapi32/BuildExplicitAccessWithNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BuildExplicitAccessWithNameA,BuildExplicitAccessWithNameA,1075 diff --git a/libc/nt/advapi32/BuildExplicitAccessWithNameW.s b/libc/nt/advapi32/BuildExplicitAccessWithNameW.s new file mode 100644 index 00000000..8e1d2b63 --- /dev/null +++ b/libc/nt/advapi32/BuildExplicitAccessWithNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BuildExplicitAccessWithNameW,BuildExplicitAccessWithNameW,1076 diff --git a/libc/nt/advapi32/BuildImpersonateExplicitAccessWithNameA.s b/libc/nt/advapi32/BuildImpersonateExplicitAccessWithNameA.s new file mode 100644 index 00000000..b51b1edb --- /dev/null +++ b/libc/nt/advapi32/BuildImpersonateExplicitAccessWithNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BuildImpersonateExplicitAccessWithNameA,BuildImpersonateExplicitAccessWithNameA,1077 diff --git a/libc/nt/advapi32/BuildImpersonateExplicitAccessWithNameW.s b/libc/nt/advapi32/BuildImpersonateExplicitAccessWithNameW.s new file mode 100644 index 00000000..2dc1d0b7 --- /dev/null +++ b/libc/nt/advapi32/BuildImpersonateExplicitAccessWithNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BuildImpersonateExplicitAccessWithNameW,BuildImpersonateExplicitAccessWithNameW,1078 diff --git a/libc/nt/advapi32/BuildImpersonateTrusteeA.s b/libc/nt/advapi32/BuildImpersonateTrusteeA.s new file mode 100644 index 00000000..d5f513cb --- /dev/null +++ b/libc/nt/advapi32/BuildImpersonateTrusteeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BuildImpersonateTrusteeA,BuildImpersonateTrusteeA,1079 diff --git a/libc/nt/advapi32/BuildImpersonateTrusteeW.s b/libc/nt/advapi32/BuildImpersonateTrusteeW.s new file mode 100644 index 00000000..95fe720c --- /dev/null +++ b/libc/nt/advapi32/BuildImpersonateTrusteeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BuildImpersonateTrusteeW,BuildImpersonateTrusteeW,1080 diff --git a/libc/nt/advapi32/BuildSecurityDescriptorA.s b/libc/nt/advapi32/BuildSecurityDescriptorA.s new file mode 100644 index 00000000..bb4b3a4c --- /dev/null +++ b/libc/nt/advapi32/BuildSecurityDescriptorA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BuildSecurityDescriptorA,BuildSecurityDescriptorA,1081 diff --git a/libc/nt/advapi32/BuildSecurityDescriptorW.s b/libc/nt/advapi32/BuildSecurityDescriptorW.s new file mode 100644 index 00000000..6f75b1db --- /dev/null +++ b/libc/nt/advapi32/BuildSecurityDescriptorW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BuildSecurityDescriptorW,BuildSecurityDescriptorW,1082 diff --git a/libc/nt/advapi32/BuildTrusteeWithNameA.s b/libc/nt/advapi32/BuildTrusteeWithNameA.s new file mode 100644 index 00000000..8a5acc1a --- /dev/null +++ b/libc/nt/advapi32/BuildTrusteeWithNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BuildTrusteeWithNameA,BuildTrusteeWithNameA,1083 diff --git a/libc/nt/advapi32/BuildTrusteeWithNameW.s b/libc/nt/advapi32/BuildTrusteeWithNameW.s new file mode 100644 index 00000000..d8f48862 --- /dev/null +++ b/libc/nt/advapi32/BuildTrusteeWithNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BuildTrusteeWithNameW,BuildTrusteeWithNameW,1084 diff --git a/libc/nt/advapi32/BuildTrusteeWithObjectsAndNameA.s b/libc/nt/advapi32/BuildTrusteeWithObjectsAndNameA.s new file mode 100644 index 00000000..c469025b --- /dev/null +++ b/libc/nt/advapi32/BuildTrusteeWithObjectsAndNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BuildTrusteeWithObjectsAndNameA,BuildTrusteeWithObjectsAndNameA,1085 diff --git a/libc/nt/advapi32/BuildTrusteeWithObjectsAndNameW.s b/libc/nt/advapi32/BuildTrusteeWithObjectsAndNameW.s new file mode 100644 index 00000000..f0d11d21 --- /dev/null +++ b/libc/nt/advapi32/BuildTrusteeWithObjectsAndNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BuildTrusteeWithObjectsAndNameW,BuildTrusteeWithObjectsAndNameW,1086 diff --git a/libc/nt/advapi32/BuildTrusteeWithObjectsAndSidA.s b/libc/nt/advapi32/BuildTrusteeWithObjectsAndSidA.s new file mode 100644 index 00000000..ff39652d --- /dev/null +++ b/libc/nt/advapi32/BuildTrusteeWithObjectsAndSidA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BuildTrusteeWithObjectsAndSidA,BuildTrusteeWithObjectsAndSidA,1087 diff --git a/libc/nt/advapi32/BuildTrusteeWithObjectsAndSidW.s b/libc/nt/advapi32/BuildTrusteeWithObjectsAndSidW.s new file mode 100644 index 00000000..3fbd1dc0 --- /dev/null +++ b/libc/nt/advapi32/BuildTrusteeWithObjectsAndSidW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BuildTrusteeWithObjectsAndSidW,BuildTrusteeWithObjectsAndSidW,1088 diff --git a/libc/nt/advapi32/BuildTrusteeWithSidA.s b/libc/nt/advapi32/BuildTrusteeWithSidA.s new file mode 100644 index 00000000..73820891 --- /dev/null +++ b/libc/nt/advapi32/BuildTrusteeWithSidA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BuildTrusteeWithSidA,BuildTrusteeWithSidA,1089 diff --git a/libc/nt/advapi32/BuildTrusteeWithSidW.s b/libc/nt/advapi32/BuildTrusteeWithSidW.s new file mode 100644 index 00000000..21d88603 --- /dev/null +++ b/libc/nt/advapi32/BuildTrusteeWithSidW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_BuildTrusteeWithSidW,BuildTrusteeWithSidW,1090 diff --git a/libc/nt/advapi32/CancelOverlappedAccess.s b/libc/nt/advapi32/CancelOverlappedAccess.s new file mode 100644 index 00000000..d5cd3985 --- /dev/null +++ b/libc/nt/advapi32/CancelOverlappedAccess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CancelOverlappedAccess,CancelOverlappedAccess,1091 diff --git a/libc/nt/advapi32/ChangeServiceConfig2A.s b/libc/nt/advapi32/ChangeServiceConfig2A.s new file mode 100644 index 00000000..565041f1 --- /dev/null +++ b/libc/nt/advapi32/ChangeServiceConfig2A.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ChangeServiceConfig2A,ChangeServiceConfig2A,1092 diff --git a/libc/nt/advapi32/ChangeServiceConfig2W.s b/libc/nt/advapi32/ChangeServiceConfig2W.s new file mode 100644 index 00000000..44888ab3 --- /dev/null +++ b/libc/nt/advapi32/ChangeServiceConfig2W.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ChangeServiceConfig2W,ChangeServiceConfig2W,1093 diff --git a/libc/nt/advapi32/ChangeServiceConfigA.s b/libc/nt/advapi32/ChangeServiceConfigA.s new file mode 100644 index 00000000..d3a6c14a --- /dev/null +++ b/libc/nt/advapi32/ChangeServiceConfigA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ChangeServiceConfigA,ChangeServiceConfigA,1094 diff --git a/libc/nt/advapi32/ChangeServiceConfigW.s b/libc/nt/advapi32/ChangeServiceConfigW.s new file mode 100644 index 00000000..2086076e --- /dev/null +++ b/libc/nt/advapi32/ChangeServiceConfigW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ChangeServiceConfigW,ChangeServiceConfigW,1095 diff --git a/libc/nt/advapi32/CheckForHiberboot.s b/libc/nt/advapi32/CheckForHiberboot.s new file mode 100644 index 00000000..37544b32 --- /dev/null +++ b/libc/nt/advapi32/CheckForHiberboot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CheckForHiberboot,CheckForHiberboot,1096 diff --git a/libc/nt/advapi32/ClearEventLogA.s b/libc/nt/advapi32/ClearEventLogA.s new file mode 100644 index 00000000..45b9bcd4 --- /dev/null +++ b/libc/nt/advapi32/ClearEventLogA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ClearEventLogA,ClearEventLogA,1098 diff --git a/libc/nt/advapi32/ClearEventLogW.s b/libc/nt/advapi32/ClearEventLogW.s new file mode 100644 index 00000000..2ec30bbe --- /dev/null +++ b/libc/nt/advapi32/ClearEventLogW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ClearEventLogW,ClearEventLogW,1099 diff --git a/libc/nt/advapi32/CloseCodeAuthzLevel.s b/libc/nt/advapi32/CloseCodeAuthzLevel.s new file mode 100644 index 00000000..03df1972 --- /dev/null +++ b/libc/nt/advapi32/CloseCodeAuthzLevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CloseCodeAuthzLevel,CloseCodeAuthzLevel,1100 diff --git a/libc/nt/advapi32/CloseEncryptedFileRaw.s b/libc/nt/advapi32/CloseEncryptedFileRaw.s new file mode 100644 index 00000000..9917d24f --- /dev/null +++ b/libc/nt/advapi32/CloseEncryptedFileRaw.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CloseEncryptedFileRaw,CloseEncryptedFileRaw,1101 diff --git a/libc/nt/advapi32/CloseEventLog.s b/libc/nt/advapi32/CloseEventLog.s new file mode 100644 index 00000000..4ade794c --- /dev/null +++ b/libc/nt/advapi32/CloseEventLog.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CloseEventLog,CloseEventLog,1102 diff --git a/libc/nt/advapi32/CloseServiceHandle.s b/libc/nt/advapi32/CloseServiceHandle.s new file mode 100644 index 00000000..46319e52 --- /dev/null +++ b/libc/nt/advapi32/CloseServiceHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CloseServiceHandle,CloseServiceHandle,1103 diff --git a/libc/nt/advapi32/CloseThreadWaitChainSession.s b/libc/nt/advapi32/CloseThreadWaitChainSession.s new file mode 100644 index 00000000..1e7e8389 --- /dev/null +++ b/libc/nt/advapi32/CloseThreadWaitChainSession.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CloseThreadWaitChainSession,CloseThreadWaitChainSession,1104 diff --git a/libc/nt/advapi32/CloseTrace.s b/libc/nt/advapi32/CloseTrace.s new file mode 100644 index 00000000..a22b6947 --- /dev/null +++ b/libc/nt/advapi32/CloseTrace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CloseTrace,CloseTrace,1105 diff --git a/libc/nt/advapi32/CommandLineFromMsiDescriptor.s b/libc/nt/advapi32/CommandLineFromMsiDescriptor.s new file mode 100644 index 00000000..48a7397d --- /dev/null +++ b/libc/nt/advapi32/CommandLineFromMsiDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CommandLineFromMsiDescriptor,CommandLineFromMsiDescriptor,1106 diff --git a/libc/nt/advapi32/ComputeAccessTokenFromCodeAuthzLevel.s b/libc/nt/advapi32/ComputeAccessTokenFromCodeAuthzLevel.s new file mode 100644 index 00000000..e3840b17 --- /dev/null +++ b/libc/nt/advapi32/ComputeAccessTokenFromCodeAuthzLevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ComputeAccessTokenFromCodeAuthzLevel,ComputeAccessTokenFromCodeAuthzLevel,1107 diff --git a/libc/nt/advapi32/ControlService.s b/libc/nt/advapi32/ControlService.s new file mode 100644 index 00000000..20aef463 --- /dev/null +++ b/libc/nt/advapi32/ControlService.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ControlService,ControlService,1108 diff --git a/libc/nt/advapi32/ControlServiceExA.s b/libc/nt/advapi32/ControlServiceExA.s new file mode 100644 index 00000000..22a6f089 --- /dev/null +++ b/libc/nt/advapi32/ControlServiceExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ControlServiceExA,ControlServiceExA,1109 diff --git a/libc/nt/advapi32/ControlServiceExW.s b/libc/nt/advapi32/ControlServiceExW.s new file mode 100644 index 00000000..2a967a89 --- /dev/null +++ b/libc/nt/advapi32/ControlServiceExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ControlServiceExW,ControlServiceExW,1110 diff --git a/libc/nt/advapi32/ControlTraceA.s b/libc/nt/advapi32/ControlTraceA.s new file mode 100644 index 00000000..32134e27 --- /dev/null +++ b/libc/nt/advapi32/ControlTraceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ControlTraceA,ControlTraceA,1111 diff --git a/libc/nt/advapi32/ControlTraceW.s b/libc/nt/advapi32/ControlTraceW.s new file mode 100644 index 00000000..8deddf3b --- /dev/null +++ b/libc/nt/advapi32/ControlTraceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ControlTraceW,ControlTraceW,1112 diff --git a/libc/nt/advapi32/ConvertAccessToSecurityDescriptorA.s b/libc/nt/advapi32/ConvertAccessToSecurityDescriptorA.s new file mode 100644 index 00000000..93fa925e --- /dev/null +++ b/libc/nt/advapi32/ConvertAccessToSecurityDescriptorA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertAccessToSecurityDescriptorA,ConvertAccessToSecurityDescriptorA,1113 diff --git a/libc/nt/advapi32/ConvertAccessToSecurityDescriptorW.s b/libc/nt/advapi32/ConvertAccessToSecurityDescriptorW.s new file mode 100644 index 00000000..60a3a697 --- /dev/null +++ b/libc/nt/advapi32/ConvertAccessToSecurityDescriptorW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertAccessToSecurityDescriptorW,ConvertAccessToSecurityDescriptorW,1114 diff --git a/libc/nt/advapi32/ConvertSDToStringSDDomainW.s b/libc/nt/advapi32/ConvertSDToStringSDDomainW.s new file mode 100644 index 00000000..6de85023 --- /dev/null +++ b/libc/nt/advapi32/ConvertSDToStringSDDomainW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertSDToStringSDDomainW,ConvertSDToStringSDDomainW,1115 diff --git a/libc/nt/advapi32/ConvertSDToStringSDRootDomainA.s b/libc/nt/advapi32/ConvertSDToStringSDRootDomainA.s new file mode 100644 index 00000000..57dbcb76 --- /dev/null +++ b/libc/nt/advapi32/ConvertSDToStringSDRootDomainA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertSDToStringSDRootDomainA,ConvertSDToStringSDRootDomainA,1116 diff --git a/libc/nt/advapi32/ConvertSDToStringSDRootDomainW.s b/libc/nt/advapi32/ConvertSDToStringSDRootDomainW.s new file mode 100644 index 00000000..c0e0deec --- /dev/null +++ b/libc/nt/advapi32/ConvertSDToStringSDRootDomainW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertSDToStringSDRootDomainW,ConvertSDToStringSDRootDomainW,1117 diff --git a/libc/nt/advapi32/ConvertSecurityDescriptorToAccessA.s b/libc/nt/advapi32/ConvertSecurityDescriptorToAccessA.s new file mode 100644 index 00000000..05290de9 --- /dev/null +++ b/libc/nt/advapi32/ConvertSecurityDescriptorToAccessA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertSecurityDescriptorToAccessA,ConvertSecurityDescriptorToAccessA,1118 diff --git a/libc/nt/advapi32/ConvertSecurityDescriptorToAccessNamedA.s b/libc/nt/advapi32/ConvertSecurityDescriptorToAccessNamedA.s new file mode 100644 index 00000000..046cfd2c --- /dev/null +++ b/libc/nt/advapi32/ConvertSecurityDescriptorToAccessNamedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertSecurityDescriptorToAccessNamedA,ConvertSecurityDescriptorToAccessNamedA,1119 diff --git a/libc/nt/advapi32/ConvertSecurityDescriptorToAccessNamedW.s b/libc/nt/advapi32/ConvertSecurityDescriptorToAccessNamedW.s new file mode 100644 index 00000000..ee2b8672 --- /dev/null +++ b/libc/nt/advapi32/ConvertSecurityDescriptorToAccessNamedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertSecurityDescriptorToAccessNamedW,ConvertSecurityDescriptorToAccessNamedW,1120 diff --git a/libc/nt/advapi32/ConvertSecurityDescriptorToAccessW.s b/libc/nt/advapi32/ConvertSecurityDescriptorToAccessW.s new file mode 100644 index 00000000..2ff946b5 --- /dev/null +++ b/libc/nt/advapi32/ConvertSecurityDescriptorToAccessW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertSecurityDescriptorToAccessW,ConvertSecurityDescriptorToAccessW,1121 diff --git a/libc/nt/advapi32/ConvertSecurityDescriptorToStringSecurityDescriptorA.s b/libc/nt/advapi32/ConvertSecurityDescriptorToStringSecurityDescriptorA.s new file mode 100644 index 00000000..8b8eccdc --- /dev/null +++ b/libc/nt/advapi32/ConvertSecurityDescriptorToStringSecurityDescriptorA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertSecurityDescriptorToStringSecurityDescriptorA,ConvertSecurityDescriptorToStringSecurityDescriptorA,1122 diff --git a/libc/nt/advapi32/ConvertSecurityDescriptorToStringSecurityDescriptorW.s b/libc/nt/advapi32/ConvertSecurityDescriptorToStringSecurityDescriptorW.s new file mode 100644 index 00000000..c9307746 --- /dev/null +++ b/libc/nt/advapi32/ConvertSecurityDescriptorToStringSecurityDescriptorW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertSecurityDescriptorToStringSecurityDescriptorW,ConvertSecurityDescriptorToStringSecurityDescriptorW,1123 diff --git a/libc/nt/advapi32/ConvertSidToStringSidA.s b/libc/nt/advapi32/ConvertSidToStringSidA.s new file mode 100644 index 00000000..fc25391b --- /dev/null +++ b/libc/nt/advapi32/ConvertSidToStringSidA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertSidToStringSidA,ConvertSidToStringSidA,1124 diff --git a/libc/nt/advapi32/ConvertSidToStringSidW.s b/libc/nt/advapi32/ConvertSidToStringSidW.s new file mode 100644 index 00000000..0cf5851c --- /dev/null +++ b/libc/nt/advapi32/ConvertSidToStringSidW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertSidToStringSidW,ConvertSidToStringSidW,1125 diff --git a/libc/nt/advapi32/ConvertStringSDToSDDomainA.s b/libc/nt/advapi32/ConvertStringSDToSDDomainA.s new file mode 100644 index 00000000..5e2b7cd8 --- /dev/null +++ b/libc/nt/advapi32/ConvertStringSDToSDDomainA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertStringSDToSDDomainA,ConvertStringSDToSDDomainA,1126 diff --git a/libc/nt/advapi32/ConvertStringSDToSDDomainW.s b/libc/nt/advapi32/ConvertStringSDToSDDomainW.s new file mode 100644 index 00000000..7db545c6 --- /dev/null +++ b/libc/nt/advapi32/ConvertStringSDToSDDomainW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertStringSDToSDDomainW,ConvertStringSDToSDDomainW,1127 diff --git a/libc/nt/advapi32/ConvertStringSDToSDRootDomainA.s b/libc/nt/advapi32/ConvertStringSDToSDRootDomainA.s new file mode 100644 index 00000000..4ba2d3c2 --- /dev/null +++ b/libc/nt/advapi32/ConvertStringSDToSDRootDomainA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertStringSDToSDRootDomainA,ConvertStringSDToSDRootDomainA,1128 diff --git a/libc/nt/advapi32/ConvertStringSDToSDRootDomainW.s b/libc/nt/advapi32/ConvertStringSDToSDRootDomainW.s new file mode 100644 index 00000000..9fcd207b --- /dev/null +++ b/libc/nt/advapi32/ConvertStringSDToSDRootDomainW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertStringSDToSDRootDomainW,ConvertStringSDToSDRootDomainW,1129 diff --git a/libc/nt/advapi32/ConvertStringSecurityDescriptorToSecurityDescriptorA.s b/libc/nt/advapi32/ConvertStringSecurityDescriptorToSecurityDescriptorA.s new file mode 100644 index 00000000..03cc345a --- /dev/null +++ b/libc/nt/advapi32/ConvertStringSecurityDescriptorToSecurityDescriptorA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertStringSecurityDescriptorToSecurityDescriptorA,ConvertStringSecurityDescriptorToSecurityDescriptorA,1130 diff --git a/libc/nt/advapi32/ConvertStringSecurityDescriptorToSecurityDescriptorW.s b/libc/nt/advapi32/ConvertStringSecurityDescriptorToSecurityDescriptorW.s new file mode 100644 index 00000000..bdf17c98 --- /dev/null +++ b/libc/nt/advapi32/ConvertStringSecurityDescriptorToSecurityDescriptorW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertStringSecurityDescriptorToSecurityDescriptorW,ConvertStringSecurityDescriptorToSecurityDescriptorW,1131 diff --git a/libc/nt/advapi32/ConvertStringSidToSidA.s b/libc/nt/advapi32/ConvertStringSidToSidA.s new file mode 100644 index 00000000..86d6c607 --- /dev/null +++ b/libc/nt/advapi32/ConvertStringSidToSidA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertStringSidToSidA,ConvertStringSidToSidA,1132 diff --git a/libc/nt/advapi32/ConvertStringSidToSidW.s b/libc/nt/advapi32/ConvertStringSidToSidW.s new file mode 100644 index 00000000..a7f6b872 --- /dev/null +++ b/libc/nt/advapi32/ConvertStringSidToSidW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ConvertStringSidToSidW,ConvertStringSidToSidW,1133 diff --git a/libc/nt/advapi32/CreateCodeAuthzLevel.s b/libc/nt/advapi32/CreateCodeAuthzLevel.s new file mode 100644 index 00000000..3be88021 --- /dev/null +++ b/libc/nt/advapi32/CreateCodeAuthzLevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CreateCodeAuthzLevel,CreateCodeAuthzLevel,1136 diff --git a/libc/nt/advapi32/CreateProcessWithLogonW.s b/libc/nt/advapi32/CreateProcessWithLogonW.s new file mode 100644 index 00000000..0abc26fa --- /dev/null +++ b/libc/nt/advapi32/CreateProcessWithLogonW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CreateProcessWithLogonW,CreateProcessWithLogonW,1142 diff --git a/libc/nt/advapi32/CreateProcessWithTokenW.s b/libc/nt/advapi32/CreateProcessWithTokenW.s new file mode 100644 index 00000000..71225a42 --- /dev/null +++ b/libc/nt/advapi32/CreateProcessWithTokenW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CreateProcessWithTokenW,CreateProcessWithTokenW,1143 diff --git a/libc/nt/advapi32/CreateServiceA.s b/libc/nt/advapi32/CreateServiceA.s new file mode 100644 index 00000000..5acd64e9 --- /dev/null +++ b/libc/nt/advapi32/CreateServiceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CreateServiceA,CreateServiceA,1145 diff --git a/libc/nt/advapi32/CreateServiceEx.s b/libc/nt/advapi32/CreateServiceEx.s new file mode 100644 index 00000000..c1e398dd --- /dev/null +++ b/libc/nt/advapi32/CreateServiceEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CreateServiceEx,CreateServiceEx,1146 diff --git a/libc/nt/advapi32/CreateServiceW.s b/libc/nt/advapi32/CreateServiceW.s new file mode 100644 index 00000000..47045a30 --- /dev/null +++ b/libc/nt/advapi32/CreateServiceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CreateServiceW,CreateServiceW,1147 diff --git a/libc/nt/advapi32/CredBackupCredentials.s b/libc/nt/advapi32/CredBackupCredentials.s new file mode 100644 index 00000000..29a62958 --- /dev/null +++ b/libc/nt/advapi32/CredBackupCredentials.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredBackupCredentials,CredBackupCredentials,1150 diff --git a/libc/nt/advapi32/CredDeleteA.s b/libc/nt/advapi32/CredDeleteA.s new file mode 100644 index 00000000..e64e0581 --- /dev/null +++ b/libc/nt/advapi32/CredDeleteA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredDeleteA,CredDeleteA,1151 diff --git a/libc/nt/advapi32/CredDeleteW.s b/libc/nt/advapi32/CredDeleteW.s new file mode 100644 index 00000000..fadf85d0 --- /dev/null +++ b/libc/nt/advapi32/CredDeleteW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredDeleteW,CredDeleteW,1152 diff --git a/libc/nt/advapi32/CredEncryptAndMarshalBinaryBlob.s b/libc/nt/advapi32/CredEncryptAndMarshalBinaryBlob.s new file mode 100644 index 00000000..4914e9ab --- /dev/null +++ b/libc/nt/advapi32/CredEncryptAndMarshalBinaryBlob.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredEncryptAndMarshalBinaryBlob,CredEncryptAndMarshalBinaryBlob,1153 diff --git a/libc/nt/advapi32/CredEnumerateA.s b/libc/nt/advapi32/CredEnumerateA.s new file mode 100644 index 00000000..0f373ece --- /dev/null +++ b/libc/nt/advapi32/CredEnumerateA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredEnumerateA,CredEnumerateA,1154 diff --git a/libc/nt/advapi32/CredEnumerateW.s b/libc/nt/advapi32/CredEnumerateW.s new file mode 100644 index 00000000..3d5a093b --- /dev/null +++ b/libc/nt/advapi32/CredEnumerateW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredEnumerateW,CredEnumerateW,1155 diff --git a/libc/nt/advapi32/CredFindBestCredentialA.s b/libc/nt/advapi32/CredFindBestCredentialA.s new file mode 100644 index 00000000..f89a018a --- /dev/null +++ b/libc/nt/advapi32/CredFindBestCredentialA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredFindBestCredentialA,CredFindBestCredentialA,1156 diff --git a/libc/nt/advapi32/CredFindBestCredentialW.s b/libc/nt/advapi32/CredFindBestCredentialW.s new file mode 100644 index 00000000..cd369b38 --- /dev/null +++ b/libc/nt/advapi32/CredFindBestCredentialW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredFindBestCredentialW,CredFindBestCredentialW,1157 diff --git a/libc/nt/advapi32/CredFree.s b/libc/nt/advapi32/CredFree.s new file mode 100644 index 00000000..6c3bea5b --- /dev/null +++ b/libc/nt/advapi32/CredFree.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredFree,CredFree,1158 diff --git a/libc/nt/advapi32/CredGetSessionTypes.s b/libc/nt/advapi32/CredGetSessionTypes.s new file mode 100644 index 00000000..fee8419c --- /dev/null +++ b/libc/nt/advapi32/CredGetSessionTypes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredGetSessionTypes,CredGetSessionTypes,1159 diff --git a/libc/nt/advapi32/CredGetTargetInfoA.s b/libc/nt/advapi32/CredGetTargetInfoA.s new file mode 100644 index 00000000..6e9f7bee --- /dev/null +++ b/libc/nt/advapi32/CredGetTargetInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredGetTargetInfoA,CredGetTargetInfoA,1160 diff --git a/libc/nt/advapi32/CredGetTargetInfoW.s b/libc/nt/advapi32/CredGetTargetInfoW.s new file mode 100644 index 00000000..79d3edda --- /dev/null +++ b/libc/nt/advapi32/CredGetTargetInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredGetTargetInfoW,CredGetTargetInfoW,1161 diff --git a/libc/nt/advapi32/CredIsMarshaledCredentialA.s b/libc/nt/advapi32/CredIsMarshaledCredentialA.s new file mode 100644 index 00000000..0592f2a3 --- /dev/null +++ b/libc/nt/advapi32/CredIsMarshaledCredentialA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredIsMarshaledCredentialA,CredIsMarshaledCredentialA,1162 diff --git a/libc/nt/advapi32/CredIsMarshaledCredentialW.s b/libc/nt/advapi32/CredIsMarshaledCredentialW.s new file mode 100644 index 00000000..b45e5384 --- /dev/null +++ b/libc/nt/advapi32/CredIsMarshaledCredentialW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredIsMarshaledCredentialW,CredIsMarshaledCredentialW,1163 diff --git a/libc/nt/advapi32/CredIsProtectedA.s b/libc/nt/advapi32/CredIsProtectedA.s new file mode 100644 index 00000000..326b25b3 --- /dev/null +++ b/libc/nt/advapi32/CredIsProtectedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredIsProtectedA,CredIsProtectedA,1164 diff --git a/libc/nt/advapi32/CredIsProtectedW.s b/libc/nt/advapi32/CredIsProtectedW.s new file mode 100644 index 00000000..d67e6283 --- /dev/null +++ b/libc/nt/advapi32/CredIsProtectedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredIsProtectedW,CredIsProtectedW,1165 diff --git a/libc/nt/advapi32/CredMarshalCredentialA.s b/libc/nt/advapi32/CredMarshalCredentialA.s new file mode 100644 index 00000000..18f4f815 --- /dev/null +++ b/libc/nt/advapi32/CredMarshalCredentialA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredMarshalCredentialA,CredMarshalCredentialA,1166 diff --git a/libc/nt/advapi32/CredMarshalCredentialW.s b/libc/nt/advapi32/CredMarshalCredentialW.s new file mode 100644 index 00000000..c83ebe5f --- /dev/null +++ b/libc/nt/advapi32/CredMarshalCredentialW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredMarshalCredentialW,CredMarshalCredentialW,1167 diff --git a/libc/nt/advapi32/CredProfileLoaded.s b/libc/nt/advapi32/CredProfileLoaded.s new file mode 100644 index 00000000..ff95e604 --- /dev/null +++ b/libc/nt/advapi32/CredProfileLoaded.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredProfileLoaded,CredProfileLoaded,1168 diff --git a/libc/nt/advapi32/CredProfileLoadedEx.s b/libc/nt/advapi32/CredProfileLoadedEx.s new file mode 100644 index 00000000..bec3b9b6 --- /dev/null +++ b/libc/nt/advapi32/CredProfileLoadedEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredProfileLoadedEx,CredProfileLoadedEx,1169 diff --git a/libc/nt/advapi32/CredProfileUnloaded.s b/libc/nt/advapi32/CredProfileUnloaded.s new file mode 100644 index 00000000..1c664cca --- /dev/null +++ b/libc/nt/advapi32/CredProfileUnloaded.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredProfileUnloaded,CredProfileUnloaded,1170 diff --git a/libc/nt/advapi32/CredProtectA.s b/libc/nt/advapi32/CredProtectA.s new file mode 100644 index 00000000..b682cbc7 --- /dev/null +++ b/libc/nt/advapi32/CredProtectA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredProtectA,CredProtectA,1171 diff --git a/libc/nt/advapi32/CredProtectW.s b/libc/nt/advapi32/CredProtectW.s new file mode 100644 index 00000000..9227bf0d --- /dev/null +++ b/libc/nt/advapi32/CredProtectW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredProtectW,CredProtectW,1172 diff --git a/libc/nt/advapi32/CredReadA.s b/libc/nt/advapi32/CredReadA.s new file mode 100644 index 00000000..00619edb --- /dev/null +++ b/libc/nt/advapi32/CredReadA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredReadA,CredReadA,1173 diff --git a/libc/nt/advapi32/CredReadByTokenHandle.s b/libc/nt/advapi32/CredReadByTokenHandle.s new file mode 100644 index 00000000..7bad2b39 --- /dev/null +++ b/libc/nt/advapi32/CredReadByTokenHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredReadByTokenHandle,CredReadByTokenHandle,1174 diff --git a/libc/nt/advapi32/CredReadDomainCredentialsA.s b/libc/nt/advapi32/CredReadDomainCredentialsA.s new file mode 100644 index 00000000..89fa53d4 --- /dev/null +++ b/libc/nt/advapi32/CredReadDomainCredentialsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredReadDomainCredentialsA,CredReadDomainCredentialsA,1175 diff --git a/libc/nt/advapi32/CredReadDomainCredentialsW.s b/libc/nt/advapi32/CredReadDomainCredentialsW.s new file mode 100644 index 00000000..a2b6b95e --- /dev/null +++ b/libc/nt/advapi32/CredReadDomainCredentialsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredReadDomainCredentialsW,CredReadDomainCredentialsW,1176 diff --git a/libc/nt/advapi32/CredReadW.s b/libc/nt/advapi32/CredReadW.s new file mode 100644 index 00000000..7c979031 --- /dev/null +++ b/libc/nt/advapi32/CredReadW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredReadW,CredReadW,1177 diff --git a/libc/nt/advapi32/CredRenameA.s b/libc/nt/advapi32/CredRenameA.s new file mode 100644 index 00000000..64440f2b --- /dev/null +++ b/libc/nt/advapi32/CredRenameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredRenameA,CredRenameA,1178 diff --git a/libc/nt/advapi32/CredRenameW.s b/libc/nt/advapi32/CredRenameW.s new file mode 100644 index 00000000..d0753d3f --- /dev/null +++ b/libc/nt/advapi32/CredRenameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredRenameW,CredRenameW,1179 diff --git a/libc/nt/advapi32/CredRestoreCredentials.s b/libc/nt/advapi32/CredRestoreCredentials.s new file mode 100644 index 00000000..b559b158 --- /dev/null +++ b/libc/nt/advapi32/CredRestoreCredentials.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredRestoreCredentials,CredRestoreCredentials,1180 diff --git a/libc/nt/advapi32/CredUnmarshalCredentialA.s b/libc/nt/advapi32/CredUnmarshalCredentialA.s new file mode 100644 index 00000000..0b14c0d4 --- /dev/null +++ b/libc/nt/advapi32/CredUnmarshalCredentialA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredUnmarshalCredentialA,CredUnmarshalCredentialA,1181 diff --git a/libc/nt/advapi32/CredUnmarshalCredentialW.s b/libc/nt/advapi32/CredUnmarshalCredentialW.s new file mode 100644 index 00000000..f7f9e3a7 --- /dev/null +++ b/libc/nt/advapi32/CredUnmarshalCredentialW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredUnmarshalCredentialW,CredUnmarshalCredentialW,1182 diff --git a/libc/nt/advapi32/CredUnprotectA.s b/libc/nt/advapi32/CredUnprotectA.s new file mode 100644 index 00000000..c22ac438 --- /dev/null +++ b/libc/nt/advapi32/CredUnprotectA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredUnprotectA,CredUnprotectA,1183 diff --git a/libc/nt/advapi32/CredUnprotectW.s b/libc/nt/advapi32/CredUnprotectW.s new file mode 100644 index 00000000..6de9fc84 --- /dev/null +++ b/libc/nt/advapi32/CredUnprotectW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredUnprotectW,CredUnprotectW,1184 diff --git a/libc/nt/advapi32/CredWriteA.s b/libc/nt/advapi32/CredWriteA.s new file mode 100644 index 00000000..86692e44 --- /dev/null +++ b/libc/nt/advapi32/CredWriteA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredWriteA,CredWriteA,1185 diff --git a/libc/nt/advapi32/CredWriteDomainCredentialsA.s b/libc/nt/advapi32/CredWriteDomainCredentialsA.s new file mode 100644 index 00000000..859912d9 --- /dev/null +++ b/libc/nt/advapi32/CredWriteDomainCredentialsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredWriteDomainCredentialsA,CredWriteDomainCredentialsA,1186 diff --git a/libc/nt/advapi32/CredWriteDomainCredentialsW.s b/libc/nt/advapi32/CredWriteDomainCredentialsW.s new file mode 100644 index 00000000..f66c9fc6 --- /dev/null +++ b/libc/nt/advapi32/CredWriteDomainCredentialsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredWriteDomainCredentialsW,CredWriteDomainCredentialsW,1187 diff --git a/libc/nt/advapi32/CredWriteW.s b/libc/nt/advapi32/CredWriteW.s new file mode 100644 index 00000000..4dfbc5aa --- /dev/null +++ b/libc/nt/advapi32/CredWriteW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredWriteW,CredWriteW,1188 diff --git a/libc/nt/advapi32/CredpConvertCredential.s b/libc/nt/advapi32/CredpConvertCredential.s new file mode 100644 index 00000000..be3afca6 --- /dev/null +++ b/libc/nt/advapi32/CredpConvertCredential.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredpConvertCredential,CredpConvertCredential,1189 diff --git a/libc/nt/advapi32/CredpConvertOneCredentialSize.s b/libc/nt/advapi32/CredpConvertOneCredentialSize.s new file mode 100644 index 00000000..7e7221b6 --- /dev/null +++ b/libc/nt/advapi32/CredpConvertOneCredentialSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredpConvertOneCredentialSize,CredpConvertOneCredentialSize,1190 diff --git a/libc/nt/advapi32/CredpConvertTargetInfo.s b/libc/nt/advapi32/CredpConvertTargetInfo.s new file mode 100644 index 00000000..3343b816 --- /dev/null +++ b/libc/nt/advapi32/CredpConvertTargetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredpConvertTargetInfo,CredpConvertTargetInfo,1191 diff --git a/libc/nt/advapi32/CredpDecodeCredential.s b/libc/nt/advapi32/CredpDecodeCredential.s new file mode 100644 index 00000000..f160572a --- /dev/null +++ b/libc/nt/advapi32/CredpDecodeCredential.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredpDecodeCredential,CredpDecodeCredential,1192 diff --git a/libc/nt/advapi32/CredpEncodeCredential.s b/libc/nt/advapi32/CredpEncodeCredential.s new file mode 100644 index 00000000..dee677a9 --- /dev/null +++ b/libc/nt/advapi32/CredpEncodeCredential.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredpEncodeCredential,CredpEncodeCredential,1193 diff --git a/libc/nt/advapi32/CredpEncodeSecret.s b/libc/nt/advapi32/CredpEncodeSecret.s new file mode 100644 index 00000000..bd130b94 --- /dev/null +++ b/libc/nt/advapi32/CredpEncodeSecret.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CredpEncodeSecret,CredpEncodeSecret,1194 diff --git a/libc/nt/advapi32/CryptAcquireContextA.s b/libc/nt/advapi32/CryptAcquireContextA.s new file mode 100644 index 00000000..95cec284 --- /dev/null +++ b/libc/nt/advapi32/CryptAcquireContextA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptAcquireContextA,CryptAcquireContextA,1195 diff --git a/libc/nt/advapi32/CryptAcquireContextW.s b/libc/nt/advapi32/CryptAcquireContextW.s new file mode 100644 index 00000000..62272035 --- /dev/null +++ b/libc/nt/advapi32/CryptAcquireContextW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptAcquireContextW,CryptAcquireContextW,1196 diff --git a/libc/nt/advapi32/CryptContextAddRef.s b/libc/nt/advapi32/CryptContextAddRef.s new file mode 100644 index 00000000..81cdbba1 --- /dev/null +++ b/libc/nt/advapi32/CryptContextAddRef.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptContextAddRef,CryptContextAddRef,1197 diff --git a/libc/nt/advapi32/CryptCreateHash.s b/libc/nt/advapi32/CryptCreateHash.s new file mode 100644 index 00000000..b93107cb --- /dev/null +++ b/libc/nt/advapi32/CryptCreateHash.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptCreateHash,CryptCreateHash,1198 diff --git a/libc/nt/advapi32/CryptDecrypt.s b/libc/nt/advapi32/CryptDecrypt.s new file mode 100644 index 00000000..27d8e51b --- /dev/null +++ b/libc/nt/advapi32/CryptDecrypt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptDecrypt,CryptDecrypt,1199 diff --git a/libc/nt/advapi32/CryptDeriveKey.s b/libc/nt/advapi32/CryptDeriveKey.s new file mode 100644 index 00000000..2a4647d6 --- /dev/null +++ b/libc/nt/advapi32/CryptDeriveKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptDeriveKey,CryptDeriveKey,1200 diff --git a/libc/nt/advapi32/CryptDestroyHash.s b/libc/nt/advapi32/CryptDestroyHash.s new file mode 100644 index 00000000..c464cf5e --- /dev/null +++ b/libc/nt/advapi32/CryptDestroyHash.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptDestroyHash,CryptDestroyHash,1201 diff --git a/libc/nt/advapi32/CryptDestroyKey.s b/libc/nt/advapi32/CryptDestroyKey.s new file mode 100644 index 00000000..dfc6c2d2 --- /dev/null +++ b/libc/nt/advapi32/CryptDestroyKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptDestroyKey,CryptDestroyKey,1202 diff --git a/libc/nt/advapi32/CryptDuplicateHash.s b/libc/nt/advapi32/CryptDuplicateHash.s new file mode 100644 index 00000000..97647a31 --- /dev/null +++ b/libc/nt/advapi32/CryptDuplicateHash.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptDuplicateHash,CryptDuplicateHash,1203 diff --git a/libc/nt/advapi32/CryptDuplicateKey.s b/libc/nt/advapi32/CryptDuplicateKey.s new file mode 100644 index 00000000..62c5316b --- /dev/null +++ b/libc/nt/advapi32/CryptDuplicateKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptDuplicateKey,CryptDuplicateKey,1204 diff --git a/libc/nt/advapi32/CryptEncrypt.s b/libc/nt/advapi32/CryptEncrypt.s new file mode 100644 index 00000000..78a70314 --- /dev/null +++ b/libc/nt/advapi32/CryptEncrypt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptEncrypt,CryptEncrypt,1205 diff --git a/libc/nt/advapi32/CryptEnumProviderTypesA.s b/libc/nt/advapi32/CryptEnumProviderTypesA.s new file mode 100644 index 00000000..d58b7607 --- /dev/null +++ b/libc/nt/advapi32/CryptEnumProviderTypesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptEnumProviderTypesA,CryptEnumProviderTypesA,1206 diff --git a/libc/nt/advapi32/CryptEnumProviderTypesW.s b/libc/nt/advapi32/CryptEnumProviderTypesW.s new file mode 100644 index 00000000..e566f22f --- /dev/null +++ b/libc/nt/advapi32/CryptEnumProviderTypesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptEnumProviderTypesW,CryptEnumProviderTypesW,1207 diff --git a/libc/nt/advapi32/CryptEnumProvidersA.s b/libc/nt/advapi32/CryptEnumProvidersA.s new file mode 100644 index 00000000..28e7b7e4 --- /dev/null +++ b/libc/nt/advapi32/CryptEnumProvidersA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptEnumProvidersA,CryptEnumProvidersA,1208 diff --git a/libc/nt/advapi32/CryptEnumProvidersW.s b/libc/nt/advapi32/CryptEnumProvidersW.s new file mode 100644 index 00000000..6afae9b4 --- /dev/null +++ b/libc/nt/advapi32/CryptEnumProvidersW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptEnumProvidersW,CryptEnumProvidersW,1209 diff --git a/libc/nt/advapi32/CryptExportKey.s b/libc/nt/advapi32/CryptExportKey.s new file mode 100644 index 00000000..351539df --- /dev/null +++ b/libc/nt/advapi32/CryptExportKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptExportKey,CryptExportKey,1210 diff --git a/libc/nt/advapi32/CryptGenKey.s b/libc/nt/advapi32/CryptGenKey.s new file mode 100644 index 00000000..0080e18a --- /dev/null +++ b/libc/nt/advapi32/CryptGenKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptGenKey,CryptGenKey,1211 diff --git a/libc/nt/advapi32/CryptGenRandom.s b/libc/nt/advapi32/CryptGenRandom.s new file mode 100644 index 00000000..7716dbfc --- /dev/null +++ b/libc/nt/advapi32/CryptGenRandom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptGenRandom,CryptGenRandom,1212 diff --git a/libc/nt/advapi32/CryptGetDefaultProviderA.s b/libc/nt/advapi32/CryptGetDefaultProviderA.s new file mode 100644 index 00000000..4425550a --- /dev/null +++ b/libc/nt/advapi32/CryptGetDefaultProviderA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptGetDefaultProviderA,CryptGetDefaultProviderA,1213 diff --git a/libc/nt/advapi32/CryptGetDefaultProviderW.s b/libc/nt/advapi32/CryptGetDefaultProviderW.s new file mode 100644 index 00000000..50a0bc26 --- /dev/null +++ b/libc/nt/advapi32/CryptGetDefaultProviderW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptGetDefaultProviderW,CryptGetDefaultProviderW,1214 diff --git a/libc/nt/advapi32/CryptGetHashParam.s b/libc/nt/advapi32/CryptGetHashParam.s new file mode 100644 index 00000000..7c597de4 --- /dev/null +++ b/libc/nt/advapi32/CryptGetHashParam.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptGetHashParam,CryptGetHashParam,1215 diff --git a/libc/nt/advapi32/CryptGetKeyParam.s b/libc/nt/advapi32/CryptGetKeyParam.s new file mode 100644 index 00000000..c8ec6236 --- /dev/null +++ b/libc/nt/advapi32/CryptGetKeyParam.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptGetKeyParam,CryptGetKeyParam,1216 diff --git a/libc/nt/advapi32/CryptGetProvParam.s b/libc/nt/advapi32/CryptGetProvParam.s new file mode 100644 index 00000000..3452189e --- /dev/null +++ b/libc/nt/advapi32/CryptGetProvParam.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptGetProvParam,CryptGetProvParam,1217 diff --git a/libc/nt/advapi32/CryptGetUserKey.s b/libc/nt/advapi32/CryptGetUserKey.s new file mode 100644 index 00000000..2f495cdb --- /dev/null +++ b/libc/nt/advapi32/CryptGetUserKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptGetUserKey,CryptGetUserKey,1218 diff --git a/libc/nt/advapi32/CryptHashData.s b/libc/nt/advapi32/CryptHashData.s new file mode 100644 index 00000000..7818a563 --- /dev/null +++ b/libc/nt/advapi32/CryptHashData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptHashData,CryptHashData,1219 diff --git a/libc/nt/advapi32/CryptHashSessionKey.s b/libc/nt/advapi32/CryptHashSessionKey.s new file mode 100644 index 00000000..bd55a162 --- /dev/null +++ b/libc/nt/advapi32/CryptHashSessionKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptHashSessionKey,CryptHashSessionKey,1220 diff --git a/libc/nt/advapi32/CryptImportKey.s b/libc/nt/advapi32/CryptImportKey.s new file mode 100644 index 00000000..8e8a1dce --- /dev/null +++ b/libc/nt/advapi32/CryptImportKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptImportKey,CryptImportKey,1221 diff --git a/libc/nt/advapi32/CryptReleaseContext.s b/libc/nt/advapi32/CryptReleaseContext.s new file mode 100644 index 00000000..26e0ca2d --- /dev/null +++ b/libc/nt/advapi32/CryptReleaseContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptReleaseContext,CryptReleaseContext,1222 diff --git a/libc/nt/advapi32/CryptSetHashParam.s b/libc/nt/advapi32/CryptSetHashParam.s new file mode 100644 index 00000000..c8376007 --- /dev/null +++ b/libc/nt/advapi32/CryptSetHashParam.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptSetHashParam,CryptSetHashParam,1223 diff --git a/libc/nt/advapi32/CryptSetKeyParam.s b/libc/nt/advapi32/CryptSetKeyParam.s new file mode 100644 index 00000000..0d48e7cd --- /dev/null +++ b/libc/nt/advapi32/CryptSetKeyParam.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptSetKeyParam,CryptSetKeyParam,1224 diff --git a/libc/nt/advapi32/CryptSetProvParam.s b/libc/nt/advapi32/CryptSetProvParam.s new file mode 100644 index 00000000..49d12879 --- /dev/null +++ b/libc/nt/advapi32/CryptSetProvParam.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptSetProvParam,CryptSetProvParam,1225 diff --git a/libc/nt/advapi32/CryptSetProviderA.s b/libc/nt/advapi32/CryptSetProviderA.s new file mode 100644 index 00000000..2db46b17 --- /dev/null +++ b/libc/nt/advapi32/CryptSetProviderA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptSetProviderA,CryptSetProviderA,1226 diff --git a/libc/nt/advapi32/CryptSetProviderExA.s b/libc/nt/advapi32/CryptSetProviderExA.s new file mode 100644 index 00000000..3048d7e7 --- /dev/null +++ b/libc/nt/advapi32/CryptSetProviderExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptSetProviderExA,CryptSetProviderExA,1227 diff --git a/libc/nt/advapi32/CryptSetProviderExW.s b/libc/nt/advapi32/CryptSetProviderExW.s new file mode 100644 index 00000000..e3e2cbff --- /dev/null +++ b/libc/nt/advapi32/CryptSetProviderExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptSetProviderExW,CryptSetProviderExW,1228 diff --git a/libc/nt/advapi32/CryptSetProviderW.s b/libc/nt/advapi32/CryptSetProviderW.s new file mode 100644 index 00000000..7c4d4228 --- /dev/null +++ b/libc/nt/advapi32/CryptSetProviderW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptSetProviderW,CryptSetProviderW,1229 diff --git a/libc/nt/advapi32/CryptSignHashA.s b/libc/nt/advapi32/CryptSignHashA.s new file mode 100644 index 00000000..cdec78a2 --- /dev/null +++ b/libc/nt/advapi32/CryptSignHashA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptSignHashA,CryptSignHashA,1230 diff --git a/libc/nt/advapi32/CryptSignHashW.s b/libc/nt/advapi32/CryptSignHashW.s new file mode 100644 index 00000000..e538195b --- /dev/null +++ b/libc/nt/advapi32/CryptSignHashW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptSignHashW,CryptSignHashW,1231 diff --git a/libc/nt/advapi32/CryptVerifySignatureA.s b/libc/nt/advapi32/CryptVerifySignatureA.s new file mode 100644 index 00000000..9e0ef3a3 --- /dev/null +++ b/libc/nt/advapi32/CryptVerifySignatureA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptVerifySignatureA,CryptVerifySignatureA,1232 diff --git a/libc/nt/advapi32/CryptVerifySignatureW.s b/libc/nt/advapi32/CryptVerifySignatureW.s new file mode 100644 index 00000000..36dc37cc --- /dev/null +++ b/libc/nt/advapi32/CryptVerifySignatureW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_CryptVerifySignatureW,CryptVerifySignatureW,1233 diff --git a/libc/nt/advapi32/DecryptFileA.s b/libc/nt/advapi32/DecryptFileA.s new file mode 100644 index 00000000..a4b5a1e9 --- /dev/null +++ b/libc/nt/advapi32/DecryptFileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_DecryptFileA,DecryptFileA,1235 diff --git a/libc/nt/advapi32/DecryptFileW.s b/libc/nt/advapi32/DecryptFileW.s new file mode 100644 index 00000000..33bbd4ac --- /dev/null +++ b/libc/nt/advapi32/DecryptFileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_DecryptFileW,DecryptFileW,1236 diff --git a/libc/nt/advapi32/DeleteService.s b/libc/nt/advapi32/DeleteService.s new file mode 100644 index 00000000..fdcad7b8 --- /dev/null +++ b/libc/nt/advapi32/DeleteService.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_DeleteService,DeleteService,1238 diff --git a/libc/nt/advapi32/DeregisterEventSource.s b/libc/nt/advapi32/DeregisterEventSource.s new file mode 100644 index 00000000..d1c3d264 --- /dev/null +++ b/libc/nt/advapi32/DeregisterEventSource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_DeregisterEventSource,DeregisterEventSource,1239 diff --git a/libc/nt/advapi32/DuplicateEncryptionInfoFile.s b/libc/nt/advapi32/DuplicateEncryptionInfoFile.s new file mode 100644 index 00000000..2c7473df --- /dev/null +++ b/libc/nt/advapi32/DuplicateEncryptionInfoFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_DuplicateEncryptionInfoFile,DuplicateEncryptionInfoFile,1241 diff --git a/libc/nt/advapi32/ElfBackupEventLogFileA.s b/libc/nt/advapi32/ElfBackupEventLogFileA.s new file mode 100644 index 00000000..03492208 --- /dev/null +++ b/libc/nt/advapi32/ElfBackupEventLogFileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfBackupEventLogFileA,ElfBackupEventLogFileA,1244 diff --git a/libc/nt/advapi32/ElfBackupEventLogFileW.s b/libc/nt/advapi32/ElfBackupEventLogFileW.s new file mode 100644 index 00000000..07c94626 --- /dev/null +++ b/libc/nt/advapi32/ElfBackupEventLogFileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfBackupEventLogFileW,ElfBackupEventLogFileW,1245 diff --git a/libc/nt/advapi32/ElfChangeNotify.s b/libc/nt/advapi32/ElfChangeNotify.s new file mode 100644 index 00000000..ae2e3770 --- /dev/null +++ b/libc/nt/advapi32/ElfChangeNotify.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfChangeNotify,ElfChangeNotify,1246 diff --git a/libc/nt/advapi32/ElfClearEventLogFileA.s b/libc/nt/advapi32/ElfClearEventLogFileA.s new file mode 100644 index 00000000..d779969a --- /dev/null +++ b/libc/nt/advapi32/ElfClearEventLogFileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfClearEventLogFileA,ElfClearEventLogFileA,1247 diff --git a/libc/nt/advapi32/ElfClearEventLogFileW.s b/libc/nt/advapi32/ElfClearEventLogFileW.s new file mode 100644 index 00000000..9705167e --- /dev/null +++ b/libc/nt/advapi32/ElfClearEventLogFileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfClearEventLogFileW,ElfClearEventLogFileW,1248 diff --git a/libc/nt/advapi32/ElfCloseEventLog.s b/libc/nt/advapi32/ElfCloseEventLog.s new file mode 100644 index 00000000..f6e478d1 --- /dev/null +++ b/libc/nt/advapi32/ElfCloseEventLog.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfCloseEventLog,ElfCloseEventLog,1249 diff --git a/libc/nt/advapi32/ElfDeregisterEventSource.s b/libc/nt/advapi32/ElfDeregisterEventSource.s new file mode 100644 index 00000000..3163b273 --- /dev/null +++ b/libc/nt/advapi32/ElfDeregisterEventSource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfDeregisterEventSource,ElfDeregisterEventSource,1250 diff --git a/libc/nt/advapi32/ElfFlushEventLog.s b/libc/nt/advapi32/ElfFlushEventLog.s new file mode 100644 index 00000000..76eb9e73 --- /dev/null +++ b/libc/nt/advapi32/ElfFlushEventLog.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfFlushEventLog,ElfFlushEventLog,1251 diff --git a/libc/nt/advapi32/ElfNumberOfRecords.s b/libc/nt/advapi32/ElfNumberOfRecords.s new file mode 100644 index 00000000..3817962a --- /dev/null +++ b/libc/nt/advapi32/ElfNumberOfRecords.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfNumberOfRecords,ElfNumberOfRecords,1252 diff --git a/libc/nt/advapi32/ElfOldestRecord.s b/libc/nt/advapi32/ElfOldestRecord.s new file mode 100644 index 00000000..3a75c195 --- /dev/null +++ b/libc/nt/advapi32/ElfOldestRecord.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfOldestRecord,ElfOldestRecord,1253 diff --git a/libc/nt/advapi32/ElfOpenBackupEventLogA.s b/libc/nt/advapi32/ElfOpenBackupEventLogA.s new file mode 100644 index 00000000..214c9ce7 --- /dev/null +++ b/libc/nt/advapi32/ElfOpenBackupEventLogA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfOpenBackupEventLogA,ElfOpenBackupEventLogA,1254 diff --git a/libc/nt/advapi32/ElfOpenBackupEventLogW.s b/libc/nt/advapi32/ElfOpenBackupEventLogW.s new file mode 100644 index 00000000..cfcd2965 --- /dev/null +++ b/libc/nt/advapi32/ElfOpenBackupEventLogW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfOpenBackupEventLogW,ElfOpenBackupEventLogW,1255 diff --git a/libc/nt/advapi32/ElfOpenEventLogA.s b/libc/nt/advapi32/ElfOpenEventLogA.s new file mode 100644 index 00000000..67fcfab6 --- /dev/null +++ b/libc/nt/advapi32/ElfOpenEventLogA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfOpenEventLogA,ElfOpenEventLogA,1256 diff --git a/libc/nt/advapi32/ElfOpenEventLogW.s b/libc/nt/advapi32/ElfOpenEventLogW.s new file mode 100644 index 00000000..9c3f603d --- /dev/null +++ b/libc/nt/advapi32/ElfOpenEventLogW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfOpenEventLogW,ElfOpenEventLogW,1257 diff --git a/libc/nt/advapi32/ElfReadEventLogA.s b/libc/nt/advapi32/ElfReadEventLogA.s new file mode 100644 index 00000000..4b95c42d --- /dev/null +++ b/libc/nt/advapi32/ElfReadEventLogA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfReadEventLogA,ElfReadEventLogA,1258 diff --git a/libc/nt/advapi32/ElfReadEventLogW.s b/libc/nt/advapi32/ElfReadEventLogW.s new file mode 100644 index 00000000..3e8bd64c --- /dev/null +++ b/libc/nt/advapi32/ElfReadEventLogW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfReadEventLogW,ElfReadEventLogW,1259 diff --git a/libc/nt/advapi32/ElfRegisterEventSourceA.s b/libc/nt/advapi32/ElfRegisterEventSourceA.s new file mode 100644 index 00000000..c36bb21a --- /dev/null +++ b/libc/nt/advapi32/ElfRegisterEventSourceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfRegisterEventSourceA,ElfRegisterEventSourceA,1260 diff --git a/libc/nt/advapi32/ElfRegisterEventSourceW.s b/libc/nt/advapi32/ElfRegisterEventSourceW.s new file mode 100644 index 00000000..6248798d --- /dev/null +++ b/libc/nt/advapi32/ElfRegisterEventSourceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfRegisterEventSourceW,ElfRegisterEventSourceW,1261 diff --git a/libc/nt/advapi32/ElfReportEventA.s b/libc/nt/advapi32/ElfReportEventA.s new file mode 100644 index 00000000..b7f26dfc --- /dev/null +++ b/libc/nt/advapi32/ElfReportEventA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfReportEventA,ElfReportEventA,1262 diff --git a/libc/nt/advapi32/ElfReportEventAndSourceW.s b/libc/nt/advapi32/ElfReportEventAndSourceW.s new file mode 100644 index 00000000..fd453a14 --- /dev/null +++ b/libc/nt/advapi32/ElfReportEventAndSourceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfReportEventAndSourceW,ElfReportEventAndSourceW,1263 diff --git a/libc/nt/advapi32/ElfReportEventW.s b/libc/nt/advapi32/ElfReportEventW.s new file mode 100644 index 00000000..cdb2bffd --- /dev/null +++ b/libc/nt/advapi32/ElfReportEventW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ElfReportEventW,ElfReportEventW,1264 diff --git a/libc/nt/advapi32/EnableTrace.s b/libc/nt/advapi32/EnableTrace.s new file mode 100644 index 00000000..25295de8 --- /dev/null +++ b/libc/nt/advapi32/EnableTrace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EnableTrace,EnableTrace,1265 diff --git a/libc/nt/advapi32/EnableTraceEx.s b/libc/nt/advapi32/EnableTraceEx.s new file mode 100644 index 00000000..4e6ea263 --- /dev/null +++ b/libc/nt/advapi32/EnableTraceEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EnableTraceEx,EnableTraceEx,1266 diff --git a/libc/nt/advapi32/EnableTraceEx2.s b/libc/nt/advapi32/EnableTraceEx2.s new file mode 100644 index 00000000..e44cf2d1 --- /dev/null +++ b/libc/nt/advapi32/EnableTraceEx2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EnableTraceEx2,EnableTraceEx2,1267 diff --git a/libc/nt/advapi32/EncryptFileA.s b/libc/nt/advapi32/EncryptFileA.s new file mode 100644 index 00000000..d0f36645 --- /dev/null +++ b/libc/nt/advapi32/EncryptFileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EncryptFileA,EncryptFileA,1268 diff --git a/libc/nt/advapi32/EncryptFileW.s b/libc/nt/advapi32/EncryptFileW.s new file mode 100644 index 00000000..205a7d1f --- /dev/null +++ b/libc/nt/advapi32/EncryptFileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EncryptFileW,EncryptFileW,1269 diff --git a/libc/nt/advapi32/EncryptedFileKeyInfo.s b/libc/nt/advapi32/EncryptedFileKeyInfo.s new file mode 100644 index 00000000..5aa74fe6 --- /dev/null +++ b/libc/nt/advapi32/EncryptedFileKeyInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EncryptedFileKeyInfo,EncryptedFileKeyInfo,1270 diff --git a/libc/nt/advapi32/EncryptionDisable.s b/libc/nt/advapi32/EncryptionDisable.s new file mode 100644 index 00000000..7c326ca8 --- /dev/null +++ b/libc/nt/advapi32/EncryptionDisable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EncryptionDisable,EncryptionDisable,1271 diff --git a/libc/nt/advapi32/EnumDependentServicesA.s b/libc/nt/advapi32/EnumDependentServicesA.s new file mode 100644 index 00000000..9b044376 --- /dev/null +++ b/libc/nt/advapi32/EnumDependentServicesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EnumDependentServicesA,EnumDependentServicesA,1272 diff --git a/libc/nt/advapi32/EnumDependentServicesW.s b/libc/nt/advapi32/EnumDependentServicesW.s new file mode 100644 index 00000000..1d65931c --- /dev/null +++ b/libc/nt/advapi32/EnumDependentServicesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EnumDependentServicesW,EnumDependentServicesW,1273 diff --git a/libc/nt/advapi32/EnumServiceGroupW.s b/libc/nt/advapi32/EnumServiceGroupW.s new file mode 100644 index 00000000..595247dd --- /dev/null +++ b/libc/nt/advapi32/EnumServiceGroupW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EnumServiceGroupW,EnumServiceGroupW,1275 diff --git a/libc/nt/advapi32/EnumServicesStatusA.s b/libc/nt/advapi32/EnumServicesStatusA.s new file mode 100644 index 00000000..94b57393 --- /dev/null +++ b/libc/nt/advapi32/EnumServicesStatusA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EnumServicesStatusA,EnumServicesStatusA,1276 diff --git a/libc/nt/advapi32/EnumServicesStatusExA.s b/libc/nt/advapi32/EnumServicesStatusExA.s new file mode 100644 index 00000000..44e7acae --- /dev/null +++ b/libc/nt/advapi32/EnumServicesStatusExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EnumServicesStatusExA,EnumServicesStatusExA,1277 diff --git a/libc/nt/advapi32/EnumServicesStatusExW.s b/libc/nt/advapi32/EnumServicesStatusExW.s new file mode 100644 index 00000000..049b829c --- /dev/null +++ b/libc/nt/advapi32/EnumServicesStatusExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EnumServicesStatusExW,EnumServicesStatusExW,1278 diff --git a/libc/nt/advapi32/EnumServicesStatusW.s b/libc/nt/advapi32/EnumServicesStatusW.s new file mode 100644 index 00000000..ca25cbf3 --- /dev/null +++ b/libc/nt/advapi32/EnumServicesStatusW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EnumServicesStatusW,EnumServicesStatusW,1279 diff --git a/libc/nt/advapi32/EnumerateTraceGuids.s b/libc/nt/advapi32/EnumerateTraceGuids.s new file mode 100644 index 00000000..e9ba8b9d --- /dev/null +++ b/libc/nt/advapi32/EnumerateTraceGuids.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EnumerateTraceGuids,EnumerateTraceGuids,1280 diff --git a/libc/nt/advapi32/EnumerateTraceGuidsEx.s b/libc/nt/advapi32/EnumerateTraceGuidsEx.s new file mode 100644 index 00000000..4623b28a --- /dev/null +++ b/libc/nt/advapi32/EnumerateTraceGuidsEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EnumerateTraceGuidsEx,EnumerateTraceGuidsEx,1281 diff --git a/libc/nt/advapi32/EventAccessControl.s b/libc/nt/advapi32/EventAccessControl.s new file mode 100644 index 00000000..434f05cb --- /dev/null +++ b/libc/nt/advapi32/EventAccessControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EventAccessControl,EventAccessControl,1285 diff --git a/libc/nt/advapi32/EventAccessQuery.s b/libc/nt/advapi32/EventAccessQuery.s new file mode 100644 index 00000000..e216abad --- /dev/null +++ b/libc/nt/advapi32/EventAccessQuery.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EventAccessQuery,EventAccessQuery,1286 diff --git a/libc/nt/advapi32/EventAccessRemove.s b/libc/nt/advapi32/EventAccessRemove.s new file mode 100644 index 00000000..2de4649d --- /dev/null +++ b/libc/nt/advapi32/EventAccessRemove.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_EventAccessRemove,EventAccessRemove,1287 diff --git a/libc/nt/advapi32/FileEncryptionStatusA.s b/libc/nt/advapi32/FileEncryptionStatusA.s new file mode 100644 index 00000000..8895ba50 --- /dev/null +++ b/libc/nt/advapi32/FileEncryptionStatusA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_FileEncryptionStatusA,FileEncryptionStatusA,1300 diff --git a/libc/nt/advapi32/FileEncryptionStatusW.s b/libc/nt/advapi32/FileEncryptionStatusW.s new file mode 100644 index 00000000..a3a584b0 --- /dev/null +++ b/libc/nt/advapi32/FileEncryptionStatusW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_FileEncryptionStatusW,FileEncryptionStatusW,1301 diff --git a/libc/nt/advapi32/FlushEfsCache.s b/libc/nt/advapi32/FlushEfsCache.s new file mode 100644 index 00000000..7f6cc3a1 --- /dev/null +++ b/libc/nt/advapi32/FlushEfsCache.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_FlushEfsCache,FlushEfsCache,1303 diff --git a/libc/nt/advapi32/FlushTraceA.s b/libc/nt/advapi32/FlushTraceA.s new file mode 100644 index 00000000..be58d1c5 --- /dev/null +++ b/libc/nt/advapi32/FlushTraceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_FlushTraceA,FlushTraceA,1304 diff --git a/libc/nt/advapi32/FlushTraceW.s b/libc/nt/advapi32/FlushTraceW.s new file mode 100644 index 00000000..9dcc4a81 --- /dev/null +++ b/libc/nt/advapi32/FlushTraceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_FlushTraceW,FlushTraceW,1305 diff --git a/libc/nt/advapi32/FreeEncryptedFileKeyInfo.s b/libc/nt/advapi32/FreeEncryptedFileKeyInfo.s new file mode 100644 index 00000000..52eff58a --- /dev/null +++ b/libc/nt/advapi32/FreeEncryptedFileKeyInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_FreeEncryptedFileKeyInfo,FreeEncryptedFileKeyInfo,1306 diff --git a/libc/nt/advapi32/FreeEncryptedFileMetadata.s b/libc/nt/advapi32/FreeEncryptedFileMetadata.s new file mode 100644 index 00000000..5f2d5d73 --- /dev/null +++ b/libc/nt/advapi32/FreeEncryptedFileMetadata.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_FreeEncryptedFileMetadata,FreeEncryptedFileMetadata,1307 diff --git a/libc/nt/advapi32/FreeEncryptionCertificateHashList.s b/libc/nt/advapi32/FreeEncryptionCertificateHashList.s new file mode 100644 index 00000000..2c326dba --- /dev/null +++ b/libc/nt/advapi32/FreeEncryptionCertificateHashList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_FreeEncryptionCertificateHashList,FreeEncryptionCertificateHashList,1308 diff --git a/libc/nt/advapi32/FreeInheritedFromArray.s b/libc/nt/advapi32/FreeInheritedFromArray.s new file mode 100644 index 00000000..590fc7e5 --- /dev/null +++ b/libc/nt/advapi32/FreeInheritedFromArray.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_FreeInheritedFromArray,FreeInheritedFromArray,1309 diff --git a/libc/nt/advapi32/GetAccessPermissionsForObjectA.s b/libc/nt/advapi32/GetAccessPermissionsForObjectA.s new file mode 100644 index 00000000..e402dc2b --- /dev/null +++ b/libc/nt/advapi32/GetAccessPermissionsForObjectA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetAccessPermissionsForObjectA,GetAccessPermissionsForObjectA,1311 diff --git a/libc/nt/advapi32/GetAccessPermissionsForObjectW.s b/libc/nt/advapi32/GetAccessPermissionsForObjectW.s new file mode 100644 index 00000000..4980a6b3 --- /dev/null +++ b/libc/nt/advapi32/GetAccessPermissionsForObjectW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetAccessPermissionsForObjectW,GetAccessPermissionsForObjectW,1312 diff --git a/libc/nt/advapi32/GetAuditedPermissionsFromAclA.s b/libc/nt/advapi32/GetAuditedPermissionsFromAclA.s new file mode 100644 index 00000000..4c025e07 --- /dev/null +++ b/libc/nt/advapi32/GetAuditedPermissionsFromAclA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetAuditedPermissionsFromAclA,GetAuditedPermissionsFromAclA,1315 diff --git a/libc/nt/advapi32/GetAuditedPermissionsFromAclW.s b/libc/nt/advapi32/GetAuditedPermissionsFromAclW.s new file mode 100644 index 00000000..f5609bbf --- /dev/null +++ b/libc/nt/advapi32/GetAuditedPermissionsFromAclW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetAuditedPermissionsFromAclW,GetAuditedPermissionsFromAclW,1316 diff --git a/libc/nt/advapi32/GetCurrentHwProfileA.s b/libc/nt/advapi32/GetCurrentHwProfileA.s new file mode 100644 index 00000000..10b21db0 --- /dev/null +++ b/libc/nt/advapi32/GetCurrentHwProfileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetCurrentHwProfileA,GetCurrentHwProfileA,1317 diff --git a/libc/nt/advapi32/GetCurrentHwProfileW.s b/libc/nt/advapi32/GetCurrentHwProfileW.s new file mode 100644 index 00000000..973df827 --- /dev/null +++ b/libc/nt/advapi32/GetCurrentHwProfileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetCurrentHwProfileW,GetCurrentHwProfileW,1318 diff --git a/libc/nt/advapi32/GetEffectiveRightsFromAclA.s b/libc/nt/advapi32/GetEffectiveRightsFromAclA.s new file mode 100644 index 00000000..f442b88b --- /dev/null +++ b/libc/nt/advapi32/GetEffectiveRightsFromAclA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetEffectiveRightsFromAclA,GetEffectiveRightsFromAclA,1320 diff --git a/libc/nt/advapi32/GetEffectiveRightsFromAclW.s b/libc/nt/advapi32/GetEffectiveRightsFromAclW.s new file mode 100644 index 00000000..653938af --- /dev/null +++ b/libc/nt/advapi32/GetEffectiveRightsFromAclW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetEffectiveRightsFromAclW,GetEffectiveRightsFromAclW,1321 diff --git a/libc/nt/advapi32/GetEncryptedFileMetadata.s b/libc/nt/advapi32/GetEncryptedFileMetadata.s new file mode 100644 index 00000000..85a0b0aa --- /dev/null +++ b/libc/nt/advapi32/GetEncryptedFileMetadata.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetEncryptedFileMetadata,GetEncryptedFileMetadata,1322 diff --git a/libc/nt/advapi32/GetEventLogInformation.s b/libc/nt/advapi32/GetEventLogInformation.s new file mode 100644 index 00000000..b862433c --- /dev/null +++ b/libc/nt/advapi32/GetEventLogInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetEventLogInformation,GetEventLogInformation,1323 diff --git a/libc/nt/advapi32/GetExplicitEntriesFromAclA.s b/libc/nt/advapi32/GetExplicitEntriesFromAclA.s new file mode 100644 index 00000000..bd360b3d --- /dev/null +++ b/libc/nt/advapi32/GetExplicitEntriesFromAclA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetExplicitEntriesFromAclA,GetExplicitEntriesFromAclA,1324 diff --git a/libc/nt/advapi32/GetExplicitEntriesFromAclW.s b/libc/nt/advapi32/GetExplicitEntriesFromAclW.s new file mode 100644 index 00000000..53d76db6 --- /dev/null +++ b/libc/nt/advapi32/GetExplicitEntriesFromAclW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetExplicitEntriesFromAclW,GetExplicitEntriesFromAclW,1325 diff --git a/libc/nt/advapi32/GetFileSecurityA.s b/libc/nt/advapi32/GetFileSecurityA.s new file mode 100644 index 00000000..fb8b84b1 --- /dev/null +++ b/libc/nt/advapi32/GetFileSecurityA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetFileSecurityA,GetFileSecurityA,1326 + + .text.windows +GetFileSecurityA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetFileSecurityA(%rip),%rax + jmp __sysv2nt6 + .endfn GetFileSecurityA,globl + .previous diff --git a/libc/nt/advapi32/GetInformationCodeAuthzLevelW.s b/libc/nt/advapi32/GetInformationCodeAuthzLevelW.s new file mode 100644 index 00000000..abd68214 --- /dev/null +++ b/libc/nt/advapi32/GetInformationCodeAuthzLevelW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetInformationCodeAuthzLevelW,GetInformationCodeAuthzLevelW,1328 diff --git a/libc/nt/advapi32/GetInformationCodeAuthzPolicyW.s b/libc/nt/advapi32/GetInformationCodeAuthzPolicyW.s new file mode 100644 index 00000000..2387f875 --- /dev/null +++ b/libc/nt/advapi32/GetInformationCodeAuthzPolicyW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetInformationCodeAuthzPolicyW,GetInformationCodeAuthzPolicyW,1329 diff --git a/libc/nt/advapi32/GetInheritanceSourceA.s b/libc/nt/advapi32/GetInheritanceSourceA.s new file mode 100644 index 00000000..42b22281 --- /dev/null +++ b/libc/nt/advapi32/GetInheritanceSourceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetInheritanceSourceA,GetInheritanceSourceA,1330 diff --git a/libc/nt/advapi32/GetInheritanceSourceW.s b/libc/nt/advapi32/GetInheritanceSourceW.s new file mode 100644 index 00000000..a3b6ea2d --- /dev/null +++ b/libc/nt/advapi32/GetInheritanceSourceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetInheritanceSourceW,GetInheritanceSourceW,1331 diff --git a/libc/nt/advapi32/GetLocalManagedApplicationData.s b/libc/nt/advapi32/GetLocalManagedApplicationData.s new file mode 100644 index 00000000..134a8fdb --- /dev/null +++ b/libc/nt/advapi32/GetLocalManagedApplicationData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetLocalManagedApplicationData,GetLocalManagedApplicationData,1334 diff --git a/libc/nt/advapi32/GetLocalManagedApplications.s b/libc/nt/advapi32/GetLocalManagedApplications.s new file mode 100644 index 00000000..dce723f5 --- /dev/null +++ b/libc/nt/advapi32/GetLocalManagedApplications.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetLocalManagedApplications,GetLocalManagedApplications,1335 diff --git a/libc/nt/advapi32/GetManagedApplicationCategories.s b/libc/nt/advapi32/GetManagedApplicationCategories.s new file mode 100644 index 00000000..8009fdc6 --- /dev/null +++ b/libc/nt/advapi32/GetManagedApplicationCategories.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetManagedApplicationCategories,GetManagedApplicationCategories,1336 diff --git a/libc/nt/advapi32/GetManagedApplications.s b/libc/nt/advapi32/GetManagedApplications.s new file mode 100644 index 00000000..f7970627 --- /dev/null +++ b/libc/nt/advapi32/GetManagedApplications.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetManagedApplications,GetManagedApplications,1337 diff --git a/libc/nt/advapi32/GetMultipleTrusteeA.s b/libc/nt/advapi32/GetMultipleTrusteeA.s new file mode 100644 index 00000000..503895da --- /dev/null +++ b/libc/nt/advapi32/GetMultipleTrusteeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetMultipleTrusteeA,GetMultipleTrusteeA,1338 diff --git a/libc/nt/advapi32/GetMultipleTrusteeOperationA.s b/libc/nt/advapi32/GetMultipleTrusteeOperationA.s new file mode 100644 index 00000000..d72e6ec5 --- /dev/null +++ b/libc/nt/advapi32/GetMultipleTrusteeOperationA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetMultipleTrusteeOperationA,GetMultipleTrusteeOperationA,1339 diff --git a/libc/nt/advapi32/GetMultipleTrusteeOperationW.s b/libc/nt/advapi32/GetMultipleTrusteeOperationW.s new file mode 100644 index 00000000..d30ccdb8 --- /dev/null +++ b/libc/nt/advapi32/GetMultipleTrusteeOperationW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetMultipleTrusteeOperationW,GetMultipleTrusteeOperationW,1340 diff --git a/libc/nt/advapi32/GetMultipleTrusteeW.s b/libc/nt/advapi32/GetMultipleTrusteeW.s new file mode 100644 index 00000000..223ae53c --- /dev/null +++ b/libc/nt/advapi32/GetMultipleTrusteeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetMultipleTrusteeW,GetMultipleTrusteeW,1341 diff --git a/libc/nt/advapi32/GetNamedSecurityInfoA.s b/libc/nt/advapi32/GetNamedSecurityInfoA.s new file mode 100644 index 00000000..1690883b --- /dev/null +++ b/libc/nt/advapi32/GetNamedSecurityInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetNamedSecurityInfoA,GetNamedSecurityInfoA,1342 diff --git a/libc/nt/advapi32/GetNamedSecurityInfoExA.s b/libc/nt/advapi32/GetNamedSecurityInfoExA.s new file mode 100644 index 00000000..60e041f5 --- /dev/null +++ b/libc/nt/advapi32/GetNamedSecurityInfoExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetNamedSecurityInfoExA,GetNamedSecurityInfoExA,1343 diff --git a/libc/nt/advapi32/GetNamedSecurityInfoExW.s b/libc/nt/advapi32/GetNamedSecurityInfoExW.s new file mode 100644 index 00000000..4c8aad77 --- /dev/null +++ b/libc/nt/advapi32/GetNamedSecurityInfoExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetNamedSecurityInfoExW,GetNamedSecurityInfoExW,1344 diff --git a/libc/nt/advapi32/GetNamedSecurityInfoW.s b/libc/nt/advapi32/GetNamedSecurityInfoW.s new file mode 100644 index 00000000..835f892c --- /dev/null +++ b/libc/nt/advapi32/GetNamedSecurityInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetNamedSecurityInfoW,GetNamedSecurityInfoW,1345 diff --git a/libc/nt/advapi32/GetNumberOfEventLogRecords.s b/libc/nt/advapi32/GetNumberOfEventLogRecords.s new file mode 100644 index 00000000..ecbb8dec --- /dev/null +++ b/libc/nt/advapi32/GetNumberOfEventLogRecords.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetNumberOfEventLogRecords,GetNumberOfEventLogRecords,1346 diff --git a/libc/nt/advapi32/GetOldestEventLogRecord.s b/libc/nt/advapi32/GetOldestEventLogRecord.s new file mode 100644 index 00000000..6759532b --- /dev/null +++ b/libc/nt/advapi32/GetOldestEventLogRecord.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetOldestEventLogRecord,GetOldestEventLogRecord,1347 diff --git a/libc/nt/advapi32/GetOverlappedAccessResults.s b/libc/nt/advapi32/GetOverlappedAccessResults.s new file mode 100644 index 00000000..fb96081d --- /dev/null +++ b/libc/nt/advapi32/GetOverlappedAccessResults.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetOverlappedAccessResults,GetOverlappedAccessResults,1348 diff --git a/libc/nt/advapi32/GetSecurityInfo.s b/libc/nt/advapi32/GetSecurityInfo.s new file mode 100644 index 00000000..93cb678a --- /dev/null +++ b/libc/nt/advapi32/GetSecurityInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetSecurityInfo,GetSecurityInfo,1357 diff --git a/libc/nt/advapi32/GetSecurityInfoExA.s b/libc/nt/advapi32/GetSecurityInfoExA.s new file mode 100644 index 00000000..9052865b --- /dev/null +++ b/libc/nt/advapi32/GetSecurityInfoExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetSecurityInfoExA,GetSecurityInfoExA,1358 diff --git a/libc/nt/advapi32/GetSecurityInfoExW.s b/libc/nt/advapi32/GetSecurityInfoExW.s new file mode 100644 index 00000000..0f80aafa --- /dev/null +++ b/libc/nt/advapi32/GetSecurityInfoExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetSecurityInfoExW,GetSecurityInfoExW,1359 diff --git a/libc/nt/advapi32/GetServiceDisplayNameA.s b/libc/nt/advapi32/GetServiceDisplayNameA.s new file mode 100644 index 00000000..d9b891cc --- /dev/null +++ b/libc/nt/advapi32/GetServiceDisplayNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetServiceDisplayNameA,GetServiceDisplayNameA,1360 diff --git a/libc/nt/advapi32/GetServiceDisplayNameW.s b/libc/nt/advapi32/GetServiceDisplayNameW.s new file mode 100644 index 00000000..fe40a6d7 --- /dev/null +++ b/libc/nt/advapi32/GetServiceDisplayNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetServiceDisplayNameW,GetServiceDisplayNameW,1361 diff --git a/libc/nt/advapi32/GetServiceKeyNameA.s b/libc/nt/advapi32/GetServiceKeyNameA.s new file mode 100644 index 00000000..89212504 --- /dev/null +++ b/libc/nt/advapi32/GetServiceKeyNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetServiceKeyNameA,GetServiceKeyNameA,1362 diff --git a/libc/nt/advapi32/GetServiceKeyNameW.s b/libc/nt/advapi32/GetServiceKeyNameW.s new file mode 100644 index 00000000..dbac3ae2 --- /dev/null +++ b/libc/nt/advapi32/GetServiceKeyNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetServiceKeyNameW,GetServiceKeyNameW,1363 diff --git a/libc/nt/advapi32/GetStringConditionFromBinary.s b/libc/nt/advapi32/GetStringConditionFromBinary.s new file mode 100644 index 00000000..b0fdc642 --- /dev/null +++ b/libc/nt/advapi32/GetStringConditionFromBinary.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetStringConditionFromBinary,GetStringConditionFromBinary,1368 diff --git a/libc/nt/advapi32/GetThreadWaitChain.s b/libc/nt/advapi32/GetThreadWaitChain.s new file mode 100644 index 00000000..1e663a42 --- /dev/null +++ b/libc/nt/advapi32/GetThreadWaitChain.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetThreadWaitChain,GetThreadWaitChain,1369 diff --git a/libc/nt/advapi32/GetTrusteeFormA.s b/libc/nt/advapi32/GetTrusteeFormA.s new file mode 100644 index 00000000..093b48ab --- /dev/null +++ b/libc/nt/advapi32/GetTrusteeFormA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetTrusteeFormA,GetTrusteeFormA,1374 diff --git a/libc/nt/advapi32/GetTrusteeFormW.s b/libc/nt/advapi32/GetTrusteeFormW.s new file mode 100644 index 00000000..afa01395 --- /dev/null +++ b/libc/nt/advapi32/GetTrusteeFormW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetTrusteeFormW,GetTrusteeFormW,1375 diff --git a/libc/nt/advapi32/GetTrusteeNameA.s b/libc/nt/advapi32/GetTrusteeNameA.s new file mode 100644 index 00000000..4b970e4d --- /dev/null +++ b/libc/nt/advapi32/GetTrusteeNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetTrusteeNameA,GetTrusteeNameA,1376 diff --git a/libc/nt/advapi32/GetTrusteeNameW.s b/libc/nt/advapi32/GetTrusteeNameW.s new file mode 100644 index 00000000..235365cc --- /dev/null +++ b/libc/nt/advapi32/GetTrusteeNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetTrusteeNameW,GetTrusteeNameW,1377 diff --git a/libc/nt/advapi32/GetTrusteeTypeA.s b/libc/nt/advapi32/GetTrusteeTypeA.s new file mode 100644 index 00000000..738089f5 --- /dev/null +++ b/libc/nt/advapi32/GetTrusteeTypeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetTrusteeTypeA,GetTrusteeTypeA,1378 diff --git a/libc/nt/advapi32/GetTrusteeTypeW.s b/libc/nt/advapi32/GetTrusteeTypeW.s new file mode 100644 index 00000000..264123ab --- /dev/null +++ b/libc/nt/advapi32/GetTrusteeTypeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetTrusteeTypeW,GetTrusteeTypeW,1379 diff --git a/libc/nt/advapi32/GetUserNameA.s b/libc/nt/advapi32/GetUserNameA.s new file mode 100644 index 00000000..e8029034 --- /dev/null +++ b/libc/nt/advapi32/GetUserNameA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetUserNameA,GetUserNameA,1380 + + .text.windows +GetUserNameA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetUserNameA(%rip),%rax + jmp __sysv2nt + .endfn GetUserNameA,globl + .previous diff --git a/libc/nt/advapi32/GetUserNameW.s b/libc/nt/advapi32/GetUserNameW.s new file mode 100644 index 00000000..ffd14412 --- /dev/null +++ b/libc/nt/advapi32/GetUserNameW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_GetUserNameW,GetUserNameW,1381 + + .text.windows +GetUserName: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetUserNameW(%rip),%rax + jmp __sysv2nt + .endfn GetUserName,globl + .previous diff --git a/libc/nt/advapi32/I_ScGetCurrentGroupStateW.s b/libc/nt/advapi32/I_ScGetCurrentGroupStateW.s new file mode 100644 index 00000000..888c6bd1 --- /dev/null +++ b/libc/nt/advapi32/I_ScGetCurrentGroupStateW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_I_ScGetCurrentGroupStateW,I_ScGetCurrentGroupStateW,1001 diff --git a/libc/nt/advapi32/I_ScReparseServiceDatabase.s b/libc/nt/advapi32/I_ScReparseServiceDatabase.s new file mode 100644 index 00000000..773605ae --- /dev/null +++ b/libc/nt/advapi32/I_ScReparseServiceDatabase.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_I_ScReparseServiceDatabase,I_ScReparseServiceDatabase,1388 diff --git a/libc/nt/advapi32/I_ScSetServiceBitsA.s b/libc/nt/advapi32/I_ScSetServiceBitsA.s new file mode 100644 index 00000000..3db30253 --- /dev/null +++ b/libc/nt/advapi32/I_ScSetServiceBitsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_I_ScSetServiceBitsA,I_ScSetServiceBitsA,1391 diff --git a/libc/nt/advapi32/I_ScSetServiceBitsW.s b/libc/nt/advapi32/I_ScSetServiceBitsW.s new file mode 100644 index 00000000..c94851a2 --- /dev/null +++ b/libc/nt/advapi32/I_ScSetServiceBitsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_I_ScSetServiceBitsW,I_ScSetServiceBitsW,1392 diff --git a/libc/nt/advapi32/IdentifyCodeAuthzLevelW.s b/libc/nt/advapi32/IdentifyCodeAuthzLevelW.s new file mode 100644 index 00000000..1a5ae33f --- /dev/null +++ b/libc/nt/advapi32/IdentifyCodeAuthzLevelW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_IdentifyCodeAuthzLevelW,IdentifyCodeAuthzLevelW,1394 diff --git a/libc/nt/advapi32/InitiateShutdownA.s b/libc/nt/advapi32/InitiateShutdownA.s new file mode 100644 index 00000000..2907ed2c --- /dev/null +++ b/libc/nt/advapi32/InitiateShutdownA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_InitiateShutdownA,InitiateShutdownA,1402 diff --git a/libc/nt/advapi32/InitiateShutdownW.s b/libc/nt/advapi32/InitiateShutdownW.s new file mode 100644 index 00000000..4001bcfc --- /dev/null +++ b/libc/nt/advapi32/InitiateShutdownW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_InitiateShutdownW,InitiateShutdownW,1403 diff --git a/libc/nt/advapi32/InitiateSystemShutdownA.s b/libc/nt/advapi32/InitiateSystemShutdownA.s new file mode 100644 index 00000000..cc923399 --- /dev/null +++ b/libc/nt/advapi32/InitiateSystemShutdownA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_InitiateSystemShutdownA,InitiateSystemShutdownA,1404 diff --git a/libc/nt/advapi32/InitiateSystemShutdownExA.s b/libc/nt/advapi32/InitiateSystemShutdownExA.s new file mode 100644 index 00000000..1c333eb1 --- /dev/null +++ b/libc/nt/advapi32/InitiateSystemShutdownExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_InitiateSystemShutdownExA,InitiateSystemShutdownExA,1405 diff --git a/libc/nt/advapi32/InitiateSystemShutdownExW.s b/libc/nt/advapi32/InitiateSystemShutdownExW.s new file mode 100644 index 00000000..f2b46b37 --- /dev/null +++ b/libc/nt/advapi32/InitiateSystemShutdownExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_InitiateSystemShutdownExW,InitiateSystemShutdownExW,1406 diff --git a/libc/nt/advapi32/InitiateSystemShutdownW.s b/libc/nt/advapi32/InitiateSystemShutdownW.s new file mode 100644 index 00000000..9085927a --- /dev/null +++ b/libc/nt/advapi32/InitiateSystemShutdownW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_InitiateSystemShutdownW,InitiateSystemShutdownW,1407 diff --git a/libc/nt/advapi32/InstallApplication.s b/libc/nt/advapi32/InstallApplication.s new file mode 100644 index 00000000..3d331271 --- /dev/null +++ b/libc/nt/advapi32/InstallApplication.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_InstallApplication,InstallApplication,1408 diff --git a/libc/nt/advapi32/IsTextUnicode.s b/libc/nt/advapi32/IsTextUnicode.s new file mode 100644 index 00000000..bc86718c --- /dev/null +++ b/libc/nt/advapi32/IsTextUnicode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_IsTextUnicode,IsTextUnicode,1409 diff --git a/libc/nt/advapi32/IsTokenUntrusted.s b/libc/nt/advapi32/IsTokenUntrusted.s new file mode 100644 index 00000000..7224d4df --- /dev/null +++ b/libc/nt/advapi32/IsTokenUntrusted.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_IsTokenUntrusted,IsTokenUntrusted,1411 diff --git a/libc/nt/advapi32/LockServiceDatabase.s b/libc/nt/advapi32/LockServiceDatabase.s new file mode 100644 index 00000000..6837fe9f --- /dev/null +++ b/libc/nt/advapi32/LockServiceDatabase.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LockServiceDatabase,LockServiceDatabase,1417 diff --git a/libc/nt/advapi32/LogonUserA.s b/libc/nt/advapi32/LogonUserA.s new file mode 100644 index 00000000..ac74af0e --- /dev/null +++ b/libc/nt/advapi32/LogonUserA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LogonUserA,LogonUserA,1418 diff --git a/libc/nt/advapi32/LogonUserExA.s b/libc/nt/advapi32/LogonUserExA.s new file mode 100644 index 00000000..518290db --- /dev/null +++ b/libc/nt/advapi32/LogonUserExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LogonUserExA,LogonUserExA,1419 diff --git a/libc/nt/advapi32/LogonUserExExW.s b/libc/nt/advapi32/LogonUserExExW.s new file mode 100644 index 00000000..34ee8945 --- /dev/null +++ b/libc/nt/advapi32/LogonUserExExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LogonUserExExW,LogonUserExExW,1420 diff --git a/libc/nt/advapi32/LogonUserExW.s b/libc/nt/advapi32/LogonUserExW.s new file mode 100644 index 00000000..c0b7342f --- /dev/null +++ b/libc/nt/advapi32/LogonUserExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LogonUserExW,LogonUserExW,1421 diff --git a/libc/nt/advapi32/LogonUserW.s b/libc/nt/advapi32/LogonUserW.s new file mode 100644 index 00000000..1016e9b9 --- /dev/null +++ b/libc/nt/advapi32/LogonUserW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LogonUserW,LogonUserW,1422 diff --git a/libc/nt/advapi32/LookupAccountNameA.s b/libc/nt/advapi32/LookupAccountNameA.s new file mode 100644 index 00000000..59723de5 --- /dev/null +++ b/libc/nt/advapi32/LookupAccountNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LookupAccountNameA,LookupAccountNameA,1423 diff --git a/libc/nt/advapi32/LookupAccountNameW.s b/libc/nt/advapi32/LookupAccountNameW.s new file mode 100644 index 00000000..90362e9d --- /dev/null +++ b/libc/nt/advapi32/LookupAccountNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LookupAccountNameW,LookupAccountNameW,1424 diff --git a/libc/nt/advapi32/LookupAccountSidA.s b/libc/nt/advapi32/LookupAccountSidA.s new file mode 100644 index 00000000..ef57f780 --- /dev/null +++ b/libc/nt/advapi32/LookupAccountSidA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LookupAccountSidA,LookupAccountSidA,1425 diff --git a/libc/nt/advapi32/LookupAccountSidW.s b/libc/nt/advapi32/LookupAccountSidW.s new file mode 100644 index 00000000..9c7bb76a --- /dev/null +++ b/libc/nt/advapi32/LookupAccountSidW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LookupAccountSidW,LookupAccountSidW,1426 diff --git a/libc/nt/advapi32/LookupPrivilegeDisplayNameA.s b/libc/nt/advapi32/LookupPrivilegeDisplayNameA.s new file mode 100644 index 00000000..03a29d1e --- /dev/null +++ b/libc/nt/advapi32/LookupPrivilegeDisplayNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LookupPrivilegeDisplayNameA,LookupPrivilegeDisplayNameA,1427 diff --git a/libc/nt/advapi32/LookupPrivilegeDisplayNameW.s b/libc/nt/advapi32/LookupPrivilegeDisplayNameW.s new file mode 100644 index 00000000..44d1c779 --- /dev/null +++ b/libc/nt/advapi32/LookupPrivilegeDisplayNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LookupPrivilegeDisplayNameW,LookupPrivilegeDisplayNameW,1428 diff --git a/libc/nt/advapi32/LookupPrivilegeNameA.s b/libc/nt/advapi32/LookupPrivilegeNameA.s new file mode 100644 index 00000000..ec9e72c0 --- /dev/null +++ b/libc/nt/advapi32/LookupPrivilegeNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LookupPrivilegeNameA,LookupPrivilegeNameA,1429 diff --git a/libc/nt/advapi32/LookupPrivilegeNameW.s b/libc/nt/advapi32/LookupPrivilegeNameW.s new file mode 100644 index 00000000..fb9bf976 --- /dev/null +++ b/libc/nt/advapi32/LookupPrivilegeNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LookupPrivilegeNameW,LookupPrivilegeNameW,1430 diff --git a/libc/nt/advapi32/LookupPrivilegeValueA.s b/libc/nt/advapi32/LookupPrivilegeValueA.s new file mode 100644 index 00000000..17f4e710 --- /dev/null +++ b/libc/nt/advapi32/LookupPrivilegeValueA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LookupPrivilegeValueA,LookupPrivilegeValueA,1431 + + .text.windows +LookupPrivilegeValueA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_LookupPrivilegeValueA(%rip),%rax + jmp __sysv2nt + .endfn LookupPrivilegeValueA,globl + .previous diff --git a/libc/nt/advapi32/LookupPrivilegeValueW.s b/libc/nt/advapi32/LookupPrivilegeValueW.s new file mode 100644 index 00000000..2bf5b296 --- /dev/null +++ b/libc/nt/advapi32/LookupPrivilegeValueW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LookupPrivilegeValueW,LookupPrivilegeValueW,1432 + + .text.windows +LookupPrivilegeValue: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_LookupPrivilegeValueW(%rip),%rax + jmp __sysv2nt + .endfn LookupPrivilegeValue,globl + .previous diff --git a/libc/nt/advapi32/LookupSecurityDescriptorPartsA.s b/libc/nt/advapi32/LookupSecurityDescriptorPartsA.s new file mode 100644 index 00000000..9e6c4390 --- /dev/null +++ b/libc/nt/advapi32/LookupSecurityDescriptorPartsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LookupSecurityDescriptorPartsA,LookupSecurityDescriptorPartsA,1433 diff --git a/libc/nt/advapi32/LookupSecurityDescriptorPartsW.s b/libc/nt/advapi32/LookupSecurityDescriptorPartsW.s new file mode 100644 index 00000000..644e48a6 --- /dev/null +++ b/libc/nt/advapi32/LookupSecurityDescriptorPartsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LookupSecurityDescriptorPartsW,LookupSecurityDescriptorPartsW,1434 diff --git a/libc/nt/advapi32/LsaAddAccountRights.s b/libc/nt/advapi32/LsaAddAccountRights.s new file mode 100644 index 00000000..50d6a9ee --- /dev/null +++ b/libc/nt/advapi32/LsaAddAccountRights.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaAddAccountRights,LsaAddAccountRights,1435 diff --git a/libc/nt/advapi32/LsaAddPrivilegesToAccount.s b/libc/nt/advapi32/LsaAddPrivilegesToAccount.s new file mode 100644 index 00000000..20c14ef0 --- /dev/null +++ b/libc/nt/advapi32/LsaAddPrivilegesToAccount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaAddPrivilegesToAccount,LsaAddPrivilegesToAccount,1436 diff --git a/libc/nt/advapi32/LsaClearAuditLog.s b/libc/nt/advapi32/LsaClearAuditLog.s new file mode 100644 index 00000000..ffd94c36 --- /dev/null +++ b/libc/nt/advapi32/LsaClearAuditLog.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaClearAuditLog,LsaClearAuditLog,1437 diff --git a/libc/nt/advapi32/LsaClose.s b/libc/nt/advapi32/LsaClose.s new file mode 100644 index 00000000..c1666497 --- /dev/null +++ b/libc/nt/advapi32/LsaClose.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaClose,LsaClose,1438 diff --git a/libc/nt/advapi32/LsaCreateAccount.s b/libc/nt/advapi32/LsaCreateAccount.s new file mode 100644 index 00000000..d252f6ae --- /dev/null +++ b/libc/nt/advapi32/LsaCreateAccount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaCreateAccount,LsaCreateAccount,1439 diff --git a/libc/nt/advapi32/LsaCreateSecret.s b/libc/nt/advapi32/LsaCreateSecret.s new file mode 100644 index 00000000..6deb1bbb --- /dev/null +++ b/libc/nt/advapi32/LsaCreateSecret.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaCreateSecret,LsaCreateSecret,1440 diff --git a/libc/nt/advapi32/LsaCreateTrustedDomain.s b/libc/nt/advapi32/LsaCreateTrustedDomain.s new file mode 100644 index 00000000..8d4e5290 --- /dev/null +++ b/libc/nt/advapi32/LsaCreateTrustedDomain.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaCreateTrustedDomain,LsaCreateTrustedDomain,1441 diff --git a/libc/nt/advapi32/LsaCreateTrustedDomainEx.s b/libc/nt/advapi32/LsaCreateTrustedDomainEx.s new file mode 100644 index 00000000..22813ef1 --- /dev/null +++ b/libc/nt/advapi32/LsaCreateTrustedDomainEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaCreateTrustedDomainEx,LsaCreateTrustedDomainEx,1442 diff --git a/libc/nt/advapi32/LsaDelete.s b/libc/nt/advapi32/LsaDelete.s new file mode 100644 index 00000000..176113e3 --- /dev/null +++ b/libc/nt/advapi32/LsaDelete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaDelete,LsaDelete,1443 diff --git a/libc/nt/advapi32/LsaDeleteTrustedDomain.s b/libc/nt/advapi32/LsaDeleteTrustedDomain.s new file mode 100644 index 00000000..2b3359c4 --- /dev/null +++ b/libc/nt/advapi32/LsaDeleteTrustedDomain.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaDeleteTrustedDomain,LsaDeleteTrustedDomain,1444 diff --git a/libc/nt/advapi32/LsaEnumerateAccountRights.s b/libc/nt/advapi32/LsaEnumerateAccountRights.s new file mode 100644 index 00000000..7104c73d --- /dev/null +++ b/libc/nt/advapi32/LsaEnumerateAccountRights.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaEnumerateAccountRights,LsaEnumerateAccountRights,1445 diff --git a/libc/nt/advapi32/LsaEnumerateAccounts.s b/libc/nt/advapi32/LsaEnumerateAccounts.s new file mode 100644 index 00000000..5c79a6a5 --- /dev/null +++ b/libc/nt/advapi32/LsaEnumerateAccounts.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaEnumerateAccounts,LsaEnumerateAccounts,1446 diff --git a/libc/nt/advapi32/LsaEnumerateAccountsWithUserRight.s b/libc/nt/advapi32/LsaEnumerateAccountsWithUserRight.s new file mode 100644 index 00000000..e8ea58e9 --- /dev/null +++ b/libc/nt/advapi32/LsaEnumerateAccountsWithUserRight.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaEnumerateAccountsWithUserRight,LsaEnumerateAccountsWithUserRight,1447 diff --git a/libc/nt/advapi32/LsaEnumeratePrivileges.s b/libc/nt/advapi32/LsaEnumeratePrivileges.s new file mode 100644 index 00000000..521b9b56 --- /dev/null +++ b/libc/nt/advapi32/LsaEnumeratePrivileges.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaEnumeratePrivileges,LsaEnumeratePrivileges,1448 diff --git a/libc/nt/advapi32/LsaEnumeratePrivilegesOfAccount.s b/libc/nt/advapi32/LsaEnumeratePrivilegesOfAccount.s new file mode 100644 index 00000000..05df183e --- /dev/null +++ b/libc/nt/advapi32/LsaEnumeratePrivilegesOfAccount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaEnumeratePrivilegesOfAccount,LsaEnumeratePrivilegesOfAccount,1449 diff --git a/libc/nt/advapi32/LsaEnumerateTrustedDomains.s b/libc/nt/advapi32/LsaEnumerateTrustedDomains.s new file mode 100644 index 00000000..9753e95a --- /dev/null +++ b/libc/nt/advapi32/LsaEnumerateTrustedDomains.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaEnumerateTrustedDomains,LsaEnumerateTrustedDomains,1450 diff --git a/libc/nt/advapi32/LsaEnumerateTrustedDomainsEx.s b/libc/nt/advapi32/LsaEnumerateTrustedDomainsEx.s new file mode 100644 index 00000000..c4fb6b3f --- /dev/null +++ b/libc/nt/advapi32/LsaEnumerateTrustedDomainsEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaEnumerateTrustedDomainsEx,LsaEnumerateTrustedDomainsEx,1451 diff --git a/libc/nt/advapi32/LsaFreeMemory.s b/libc/nt/advapi32/LsaFreeMemory.s new file mode 100644 index 00000000..ac88860f --- /dev/null +++ b/libc/nt/advapi32/LsaFreeMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaFreeMemory,LsaFreeMemory,1452 diff --git a/libc/nt/advapi32/LsaGetAppliedCAPIDs.s b/libc/nt/advapi32/LsaGetAppliedCAPIDs.s new file mode 100644 index 00000000..cb53b322 --- /dev/null +++ b/libc/nt/advapi32/LsaGetAppliedCAPIDs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaGetAppliedCAPIDs,LsaGetAppliedCAPIDs,1453 diff --git a/libc/nt/advapi32/LsaGetQuotasForAccount.s b/libc/nt/advapi32/LsaGetQuotasForAccount.s new file mode 100644 index 00000000..fca78dc6 --- /dev/null +++ b/libc/nt/advapi32/LsaGetQuotasForAccount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaGetQuotasForAccount,LsaGetQuotasForAccount,1454 diff --git a/libc/nt/advapi32/LsaGetRemoteUserName.s b/libc/nt/advapi32/LsaGetRemoteUserName.s new file mode 100644 index 00000000..134a09e0 --- /dev/null +++ b/libc/nt/advapi32/LsaGetRemoteUserName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaGetRemoteUserName,LsaGetRemoteUserName,1455 diff --git a/libc/nt/advapi32/LsaGetSystemAccessAccount.s b/libc/nt/advapi32/LsaGetSystemAccessAccount.s new file mode 100644 index 00000000..837c0f9a --- /dev/null +++ b/libc/nt/advapi32/LsaGetSystemAccessAccount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaGetSystemAccessAccount,LsaGetSystemAccessAccount,1456 diff --git a/libc/nt/advapi32/LsaGetUserName.s b/libc/nt/advapi32/LsaGetUserName.s new file mode 100644 index 00000000..a8a43b26 --- /dev/null +++ b/libc/nt/advapi32/LsaGetUserName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaGetUserName,LsaGetUserName,1457 diff --git a/libc/nt/advapi32/LsaICLookupNames.s b/libc/nt/advapi32/LsaICLookupNames.s new file mode 100644 index 00000000..d3f2331b --- /dev/null +++ b/libc/nt/advapi32/LsaICLookupNames.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaICLookupNames,LsaICLookupNames,1458 diff --git a/libc/nt/advapi32/LsaICLookupNamesWithCreds.s b/libc/nt/advapi32/LsaICLookupNamesWithCreds.s new file mode 100644 index 00000000..8e7db174 --- /dev/null +++ b/libc/nt/advapi32/LsaICLookupNamesWithCreds.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaICLookupNamesWithCreds,LsaICLookupNamesWithCreds,1459 diff --git a/libc/nt/advapi32/LsaICLookupSids.s b/libc/nt/advapi32/LsaICLookupSids.s new file mode 100644 index 00000000..2ccaec8d --- /dev/null +++ b/libc/nt/advapi32/LsaICLookupSids.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaICLookupSids,LsaICLookupSids,1460 diff --git a/libc/nt/advapi32/LsaICLookupSidsWithCreds.s b/libc/nt/advapi32/LsaICLookupSidsWithCreds.s new file mode 100644 index 00000000..61cd0ba1 --- /dev/null +++ b/libc/nt/advapi32/LsaICLookupSidsWithCreds.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaICLookupSidsWithCreds,LsaICLookupSidsWithCreds,1461 diff --git a/libc/nt/advapi32/LsaLookupNames.s b/libc/nt/advapi32/LsaLookupNames.s new file mode 100644 index 00000000..da3b4431 --- /dev/null +++ b/libc/nt/advapi32/LsaLookupNames.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaLookupNames,LsaLookupNames,1462 diff --git a/libc/nt/advapi32/LsaLookupNames2.s b/libc/nt/advapi32/LsaLookupNames2.s new file mode 100644 index 00000000..86a1c189 --- /dev/null +++ b/libc/nt/advapi32/LsaLookupNames2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaLookupNames2,LsaLookupNames2,1463 diff --git a/libc/nt/advapi32/LsaLookupPrivilegeDisplayName.s b/libc/nt/advapi32/LsaLookupPrivilegeDisplayName.s new file mode 100644 index 00000000..99b4cf3e --- /dev/null +++ b/libc/nt/advapi32/LsaLookupPrivilegeDisplayName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaLookupPrivilegeDisplayName,LsaLookupPrivilegeDisplayName,1464 diff --git a/libc/nt/advapi32/LsaLookupPrivilegeName.s b/libc/nt/advapi32/LsaLookupPrivilegeName.s new file mode 100644 index 00000000..55b3c7b3 --- /dev/null +++ b/libc/nt/advapi32/LsaLookupPrivilegeName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaLookupPrivilegeName,LsaLookupPrivilegeName,1465 diff --git a/libc/nt/advapi32/LsaLookupPrivilegeValue.s b/libc/nt/advapi32/LsaLookupPrivilegeValue.s new file mode 100644 index 00000000..ca2d8a1f --- /dev/null +++ b/libc/nt/advapi32/LsaLookupPrivilegeValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaLookupPrivilegeValue,LsaLookupPrivilegeValue,1466 diff --git a/libc/nt/advapi32/LsaLookupSids.s b/libc/nt/advapi32/LsaLookupSids.s new file mode 100644 index 00000000..1fdecb20 --- /dev/null +++ b/libc/nt/advapi32/LsaLookupSids.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaLookupSids,LsaLookupSids,1467 diff --git a/libc/nt/advapi32/LsaLookupSids2.s b/libc/nt/advapi32/LsaLookupSids2.s new file mode 100644 index 00000000..4b29df1e --- /dev/null +++ b/libc/nt/advapi32/LsaLookupSids2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaLookupSids2,LsaLookupSids2,1468 diff --git a/libc/nt/advapi32/LsaManageSidNameMapping.s b/libc/nt/advapi32/LsaManageSidNameMapping.s new file mode 100644 index 00000000..2d17e006 --- /dev/null +++ b/libc/nt/advapi32/LsaManageSidNameMapping.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaManageSidNameMapping,LsaManageSidNameMapping,1469 diff --git a/libc/nt/advapi32/LsaNtStatusToWinError.s b/libc/nt/advapi32/LsaNtStatusToWinError.s new file mode 100644 index 00000000..3b470da5 --- /dev/null +++ b/libc/nt/advapi32/LsaNtStatusToWinError.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaNtStatusToWinError,LsaNtStatusToWinError,1470 diff --git a/libc/nt/advapi32/LsaOpenAccount.s b/libc/nt/advapi32/LsaOpenAccount.s new file mode 100644 index 00000000..d8d624ff --- /dev/null +++ b/libc/nt/advapi32/LsaOpenAccount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaOpenAccount,LsaOpenAccount,1471 diff --git a/libc/nt/advapi32/LsaOpenPolicy.s b/libc/nt/advapi32/LsaOpenPolicy.s new file mode 100644 index 00000000..dbf2961b --- /dev/null +++ b/libc/nt/advapi32/LsaOpenPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaOpenPolicy,LsaOpenPolicy,1472 diff --git a/libc/nt/advapi32/LsaOpenPolicySce.s b/libc/nt/advapi32/LsaOpenPolicySce.s new file mode 100644 index 00000000..ab7d6ce7 --- /dev/null +++ b/libc/nt/advapi32/LsaOpenPolicySce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaOpenPolicySce,LsaOpenPolicySce,1473 diff --git a/libc/nt/advapi32/LsaOpenSecret.s b/libc/nt/advapi32/LsaOpenSecret.s new file mode 100644 index 00000000..8226992c --- /dev/null +++ b/libc/nt/advapi32/LsaOpenSecret.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaOpenSecret,LsaOpenSecret,1474 diff --git a/libc/nt/advapi32/LsaOpenTrustedDomain.s b/libc/nt/advapi32/LsaOpenTrustedDomain.s new file mode 100644 index 00000000..98c51768 --- /dev/null +++ b/libc/nt/advapi32/LsaOpenTrustedDomain.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaOpenTrustedDomain,LsaOpenTrustedDomain,1475 diff --git a/libc/nt/advapi32/LsaOpenTrustedDomainByName.s b/libc/nt/advapi32/LsaOpenTrustedDomainByName.s new file mode 100644 index 00000000..ad3e19db --- /dev/null +++ b/libc/nt/advapi32/LsaOpenTrustedDomainByName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaOpenTrustedDomainByName,LsaOpenTrustedDomainByName,1476 diff --git a/libc/nt/advapi32/LsaQueryCAPs.s b/libc/nt/advapi32/LsaQueryCAPs.s new file mode 100644 index 00000000..8bb6b194 --- /dev/null +++ b/libc/nt/advapi32/LsaQueryCAPs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaQueryCAPs,LsaQueryCAPs,1477 diff --git a/libc/nt/advapi32/LsaQueryDomainInformationPolicy.s b/libc/nt/advapi32/LsaQueryDomainInformationPolicy.s new file mode 100644 index 00000000..f7da8977 --- /dev/null +++ b/libc/nt/advapi32/LsaQueryDomainInformationPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaQueryDomainInformationPolicy,LsaQueryDomainInformationPolicy,1478 diff --git a/libc/nt/advapi32/LsaQueryForestTrustInformation.s b/libc/nt/advapi32/LsaQueryForestTrustInformation.s new file mode 100644 index 00000000..4f430554 --- /dev/null +++ b/libc/nt/advapi32/LsaQueryForestTrustInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaQueryForestTrustInformation,LsaQueryForestTrustInformation,1479 diff --git a/libc/nt/advapi32/LsaQueryInfoTrustedDomain.s b/libc/nt/advapi32/LsaQueryInfoTrustedDomain.s new file mode 100644 index 00000000..046ec869 --- /dev/null +++ b/libc/nt/advapi32/LsaQueryInfoTrustedDomain.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaQueryInfoTrustedDomain,LsaQueryInfoTrustedDomain,1480 diff --git a/libc/nt/advapi32/LsaQueryInformationPolicy.s b/libc/nt/advapi32/LsaQueryInformationPolicy.s new file mode 100644 index 00000000..ed674b36 --- /dev/null +++ b/libc/nt/advapi32/LsaQueryInformationPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaQueryInformationPolicy,LsaQueryInformationPolicy,1481 diff --git a/libc/nt/advapi32/LsaQuerySecret.s b/libc/nt/advapi32/LsaQuerySecret.s new file mode 100644 index 00000000..930457e2 --- /dev/null +++ b/libc/nt/advapi32/LsaQuerySecret.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaQuerySecret,LsaQuerySecret,1482 diff --git a/libc/nt/advapi32/LsaQuerySecurityObject.s b/libc/nt/advapi32/LsaQuerySecurityObject.s new file mode 100644 index 00000000..e18dbcbf --- /dev/null +++ b/libc/nt/advapi32/LsaQuerySecurityObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaQuerySecurityObject,LsaQuerySecurityObject,1483 diff --git a/libc/nt/advapi32/LsaQueryTrustedDomainInfo.s b/libc/nt/advapi32/LsaQueryTrustedDomainInfo.s new file mode 100644 index 00000000..d584027d --- /dev/null +++ b/libc/nt/advapi32/LsaQueryTrustedDomainInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaQueryTrustedDomainInfo,LsaQueryTrustedDomainInfo,1484 diff --git a/libc/nt/advapi32/LsaQueryTrustedDomainInfoByName.s b/libc/nt/advapi32/LsaQueryTrustedDomainInfoByName.s new file mode 100644 index 00000000..c4f96717 --- /dev/null +++ b/libc/nt/advapi32/LsaQueryTrustedDomainInfoByName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaQueryTrustedDomainInfoByName,LsaQueryTrustedDomainInfoByName,1485 diff --git a/libc/nt/advapi32/LsaRemoveAccountRights.s b/libc/nt/advapi32/LsaRemoveAccountRights.s new file mode 100644 index 00000000..b570355a --- /dev/null +++ b/libc/nt/advapi32/LsaRemoveAccountRights.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaRemoveAccountRights,LsaRemoveAccountRights,1486 diff --git a/libc/nt/advapi32/LsaRemovePrivilegesFromAccount.s b/libc/nt/advapi32/LsaRemovePrivilegesFromAccount.s new file mode 100644 index 00000000..d917c416 --- /dev/null +++ b/libc/nt/advapi32/LsaRemovePrivilegesFromAccount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaRemovePrivilegesFromAccount,LsaRemovePrivilegesFromAccount,1487 diff --git a/libc/nt/advapi32/LsaRetrievePrivateData.s b/libc/nt/advapi32/LsaRetrievePrivateData.s new file mode 100644 index 00000000..ec6f7e27 --- /dev/null +++ b/libc/nt/advapi32/LsaRetrievePrivateData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaRetrievePrivateData,LsaRetrievePrivateData,1488 diff --git a/libc/nt/advapi32/LsaSetCAPs.s b/libc/nt/advapi32/LsaSetCAPs.s new file mode 100644 index 00000000..aefc4683 --- /dev/null +++ b/libc/nt/advapi32/LsaSetCAPs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaSetCAPs,LsaSetCAPs,1489 diff --git a/libc/nt/advapi32/LsaSetDomainInformationPolicy.s b/libc/nt/advapi32/LsaSetDomainInformationPolicy.s new file mode 100644 index 00000000..2259b2bf --- /dev/null +++ b/libc/nt/advapi32/LsaSetDomainInformationPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaSetDomainInformationPolicy,LsaSetDomainInformationPolicy,1490 diff --git a/libc/nt/advapi32/LsaSetForestTrustInformation.s b/libc/nt/advapi32/LsaSetForestTrustInformation.s new file mode 100644 index 00000000..bd0d4a1d --- /dev/null +++ b/libc/nt/advapi32/LsaSetForestTrustInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaSetForestTrustInformation,LsaSetForestTrustInformation,1491 diff --git a/libc/nt/advapi32/LsaSetInformationPolicy.s b/libc/nt/advapi32/LsaSetInformationPolicy.s new file mode 100644 index 00000000..b46fef15 --- /dev/null +++ b/libc/nt/advapi32/LsaSetInformationPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaSetInformationPolicy,LsaSetInformationPolicy,1492 diff --git a/libc/nt/advapi32/LsaSetInformationTrustedDomain.s b/libc/nt/advapi32/LsaSetInformationTrustedDomain.s new file mode 100644 index 00000000..fba723b9 --- /dev/null +++ b/libc/nt/advapi32/LsaSetInformationTrustedDomain.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaSetInformationTrustedDomain,LsaSetInformationTrustedDomain,1493 diff --git a/libc/nt/advapi32/LsaSetQuotasForAccount.s b/libc/nt/advapi32/LsaSetQuotasForAccount.s new file mode 100644 index 00000000..1db84ca5 --- /dev/null +++ b/libc/nt/advapi32/LsaSetQuotasForAccount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaSetQuotasForAccount,LsaSetQuotasForAccount,1494 diff --git a/libc/nt/advapi32/LsaSetSecret.s b/libc/nt/advapi32/LsaSetSecret.s new file mode 100644 index 00000000..465a19ab --- /dev/null +++ b/libc/nt/advapi32/LsaSetSecret.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaSetSecret,LsaSetSecret,1495 diff --git a/libc/nt/advapi32/LsaSetSecurityObject.s b/libc/nt/advapi32/LsaSetSecurityObject.s new file mode 100644 index 00000000..611b6221 --- /dev/null +++ b/libc/nt/advapi32/LsaSetSecurityObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaSetSecurityObject,LsaSetSecurityObject,1496 diff --git a/libc/nt/advapi32/LsaSetSystemAccessAccount.s b/libc/nt/advapi32/LsaSetSystemAccessAccount.s new file mode 100644 index 00000000..2ce93e80 --- /dev/null +++ b/libc/nt/advapi32/LsaSetSystemAccessAccount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaSetSystemAccessAccount,LsaSetSystemAccessAccount,1497 diff --git a/libc/nt/advapi32/LsaSetTrustedDomainInfoByName.s b/libc/nt/advapi32/LsaSetTrustedDomainInfoByName.s new file mode 100644 index 00000000..0c275e7b --- /dev/null +++ b/libc/nt/advapi32/LsaSetTrustedDomainInfoByName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaSetTrustedDomainInfoByName,LsaSetTrustedDomainInfoByName,1498 diff --git a/libc/nt/advapi32/LsaSetTrustedDomainInformation.s b/libc/nt/advapi32/LsaSetTrustedDomainInformation.s new file mode 100644 index 00000000..b9060b31 --- /dev/null +++ b/libc/nt/advapi32/LsaSetTrustedDomainInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaSetTrustedDomainInformation,LsaSetTrustedDomainInformation,1499 diff --git a/libc/nt/advapi32/LsaStorePrivateData.s b/libc/nt/advapi32/LsaStorePrivateData.s new file mode 100644 index 00000000..921abd48 --- /dev/null +++ b/libc/nt/advapi32/LsaStorePrivateData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_LsaStorePrivateData,LsaStorePrivateData,1500 diff --git a/libc/nt/advapi32/MIDL_user_free_Ext.s b/libc/nt/advapi32/MIDL_user_free_Ext.s new file mode 100644 index 00000000..c267721a --- /dev/null +++ b/libc/nt/advapi32/MIDL_user_free_Ext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_MIDL_user_free_Ext,MIDL_user_free_Ext,1507 diff --git a/libc/nt/advapi32/MSChapSrvChangePassword.s b/libc/nt/advapi32/MSChapSrvChangePassword.s new file mode 100644 index 00000000..250a9c35 --- /dev/null +++ b/libc/nt/advapi32/MSChapSrvChangePassword.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_MSChapSrvChangePassword,MSChapSrvChangePassword,1508 diff --git a/libc/nt/advapi32/MSChapSrvChangePassword2.s b/libc/nt/advapi32/MSChapSrvChangePassword2.s new file mode 100644 index 00000000..6f05ad9d --- /dev/null +++ b/libc/nt/advapi32/MSChapSrvChangePassword2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_MSChapSrvChangePassword2,MSChapSrvChangePassword2,1509 diff --git a/libc/nt/advapi32/NotifyBootConfigStatus.s b/libc/nt/advapi32/NotifyBootConfigStatus.s new file mode 100644 index 00000000..e41901df --- /dev/null +++ b/libc/nt/advapi32/NotifyBootConfigStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_NotifyBootConfigStatus,NotifyBootConfigStatus,1514 diff --git a/libc/nt/advapi32/NotifyChangeEventLog.s b/libc/nt/advapi32/NotifyChangeEventLog.s new file mode 100644 index 00000000..1effbea4 --- /dev/null +++ b/libc/nt/advapi32/NotifyChangeEventLog.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_NotifyChangeEventLog,NotifyChangeEventLog,1515 diff --git a/libc/nt/advapi32/NotifyServiceStatusChangeA.s b/libc/nt/advapi32/NotifyServiceStatusChangeA.s new file mode 100644 index 00000000..5e42696c --- /dev/null +++ b/libc/nt/advapi32/NotifyServiceStatusChangeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_NotifyServiceStatusChangeA,NotifyServiceStatusChangeA,1517 diff --git a/libc/nt/advapi32/NotifyServiceStatusChangeW.s b/libc/nt/advapi32/NotifyServiceStatusChangeW.s new file mode 100644 index 00000000..a7be2f4f --- /dev/null +++ b/libc/nt/advapi32/NotifyServiceStatusChangeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_NotifyServiceStatusChangeW,NotifyServiceStatusChangeW,1518 diff --git a/libc/nt/advapi32/NpGetUserName.s b/libc/nt/advapi32/NpGetUserName.s new file mode 100644 index 00000000..30dd578c --- /dev/null +++ b/libc/nt/advapi32/NpGetUserName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_NpGetUserName,NpGetUserName,1519 diff --git a/libc/nt/advapi32/ObjectCloseAuditAlarmA.s b/libc/nt/advapi32/ObjectCloseAuditAlarmA.s new file mode 100644 index 00000000..c9ccb582 --- /dev/null +++ b/libc/nt/advapi32/ObjectCloseAuditAlarmA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ObjectCloseAuditAlarmA,ObjectCloseAuditAlarmA,1520 diff --git a/libc/nt/advapi32/ObjectDeleteAuditAlarmA.s b/libc/nt/advapi32/ObjectDeleteAuditAlarmA.s new file mode 100644 index 00000000..bc447456 --- /dev/null +++ b/libc/nt/advapi32/ObjectDeleteAuditAlarmA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ObjectDeleteAuditAlarmA,ObjectDeleteAuditAlarmA,1522 diff --git a/libc/nt/advapi32/ObjectOpenAuditAlarmA.s b/libc/nt/advapi32/ObjectOpenAuditAlarmA.s new file mode 100644 index 00000000..5350c772 --- /dev/null +++ b/libc/nt/advapi32/ObjectOpenAuditAlarmA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ObjectOpenAuditAlarmA,ObjectOpenAuditAlarmA,1524 diff --git a/libc/nt/advapi32/ObjectPrivilegeAuditAlarmA.s b/libc/nt/advapi32/ObjectPrivilegeAuditAlarmA.s new file mode 100644 index 00000000..fda0d791 --- /dev/null +++ b/libc/nt/advapi32/ObjectPrivilegeAuditAlarmA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ObjectPrivilegeAuditAlarmA,ObjectPrivilegeAuditAlarmA,1526 diff --git a/libc/nt/advapi32/OpenBackupEventLogA.s b/libc/nt/advapi32/OpenBackupEventLogA.s new file mode 100644 index 00000000..2bea5bd8 --- /dev/null +++ b/libc/nt/advapi32/OpenBackupEventLogA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_OpenBackupEventLogA,OpenBackupEventLogA,1528 diff --git a/libc/nt/advapi32/OpenBackupEventLogW.s b/libc/nt/advapi32/OpenBackupEventLogW.s new file mode 100644 index 00000000..1f5ea569 --- /dev/null +++ b/libc/nt/advapi32/OpenBackupEventLogW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_OpenBackupEventLogW,OpenBackupEventLogW,1529 diff --git a/libc/nt/advapi32/OpenEncryptedFileRawA.s b/libc/nt/advapi32/OpenEncryptedFileRawA.s new file mode 100644 index 00000000..bf571b45 --- /dev/null +++ b/libc/nt/advapi32/OpenEncryptedFileRawA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_OpenEncryptedFileRawA,OpenEncryptedFileRawA,1530 diff --git a/libc/nt/advapi32/OpenEncryptedFileRawW.s b/libc/nt/advapi32/OpenEncryptedFileRawW.s new file mode 100644 index 00000000..0b07a9f4 --- /dev/null +++ b/libc/nt/advapi32/OpenEncryptedFileRawW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_OpenEncryptedFileRawW,OpenEncryptedFileRawW,1531 diff --git a/libc/nt/advapi32/OpenEventLogA.s b/libc/nt/advapi32/OpenEventLogA.s new file mode 100644 index 00000000..70b497de --- /dev/null +++ b/libc/nt/advapi32/OpenEventLogA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_OpenEventLogA,OpenEventLogA,1532 diff --git a/libc/nt/advapi32/OpenEventLogW.s b/libc/nt/advapi32/OpenEventLogW.s new file mode 100644 index 00000000..2a5416d7 --- /dev/null +++ b/libc/nt/advapi32/OpenEventLogW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_OpenEventLogW,OpenEventLogW,1533 diff --git a/libc/nt/advapi32/OpenSCManagerA.s b/libc/nt/advapi32/OpenSCManagerA.s new file mode 100644 index 00000000..13820d2a --- /dev/null +++ b/libc/nt/advapi32/OpenSCManagerA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_OpenSCManagerA,OpenSCManagerA,1535 diff --git a/libc/nt/advapi32/OpenSCManagerW.s b/libc/nt/advapi32/OpenSCManagerW.s new file mode 100644 index 00000000..6d06be3c --- /dev/null +++ b/libc/nt/advapi32/OpenSCManagerW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_OpenSCManagerW,OpenSCManagerW,1536 diff --git a/libc/nt/advapi32/OpenServiceA.s b/libc/nt/advapi32/OpenServiceA.s new file mode 100644 index 00000000..70ee3f17 --- /dev/null +++ b/libc/nt/advapi32/OpenServiceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_OpenServiceA,OpenServiceA,1537 diff --git a/libc/nt/advapi32/OpenServiceW.s b/libc/nt/advapi32/OpenServiceW.s new file mode 100644 index 00000000..6987b60d --- /dev/null +++ b/libc/nt/advapi32/OpenServiceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_OpenServiceW,OpenServiceW,1538 diff --git a/libc/nt/advapi32/OpenThreadWaitChainSession.s b/libc/nt/advapi32/OpenThreadWaitChainSession.s new file mode 100644 index 00000000..103ea091 --- /dev/null +++ b/libc/nt/advapi32/OpenThreadWaitChainSession.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_OpenThreadWaitChainSession,OpenThreadWaitChainSession,1540 diff --git a/libc/nt/advapi32/OpenTraceA.s b/libc/nt/advapi32/OpenTraceA.s new file mode 100644 index 00000000..c2398998 --- /dev/null +++ b/libc/nt/advapi32/OpenTraceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_OpenTraceA,OpenTraceA,1541 diff --git a/libc/nt/advapi32/OpenTraceW.s b/libc/nt/advapi32/OpenTraceW.s new file mode 100644 index 00000000..fde3b3d3 --- /dev/null +++ b/libc/nt/advapi32/OpenTraceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_OpenTraceW,OpenTraceW,1542 diff --git a/libc/nt/advapi32/OperationEnd.s b/libc/nt/advapi32/OperationEnd.s new file mode 100644 index 00000000..3cba3e02 --- /dev/null +++ b/libc/nt/advapi32/OperationEnd.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_OperationEnd,OperationEnd,1543 diff --git a/libc/nt/advapi32/OperationStart.s b/libc/nt/advapi32/OperationStart.s new file mode 100644 index 00000000..0157e5bd --- /dev/null +++ b/libc/nt/advapi32/OperationStart.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_OperationStart,OperationStart,1544 diff --git a/libc/nt/advapi32/PerfAddCounters.s b/libc/nt/advapi32/PerfAddCounters.s new file mode 100644 index 00000000..92039483 --- /dev/null +++ b/libc/nt/advapi32/PerfAddCounters.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_PerfAddCounters,PerfAddCounters,1545 diff --git a/libc/nt/advapi32/PerfCloseQueryHandle.s b/libc/nt/advapi32/PerfCloseQueryHandle.s new file mode 100644 index 00000000..ff0b86b4 --- /dev/null +++ b/libc/nt/advapi32/PerfCloseQueryHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_PerfCloseQueryHandle,PerfCloseQueryHandle,1546 diff --git a/libc/nt/advapi32/PerfDeleteCounters.s b/libc/nt/advapi32/PerfDeleteCounters.s new file mode 100644 index 00000000..1211a521 --- /dev/null +++ b/libc/nt/advapi32/PerfDeleteCounters.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_PerfDeleteCounters,PerfDeleteCounters,1550 diff --git a/libc/nt/advapi32/PerfEnumerateCounterSet.s b/libc/nt/advapi32/PerfEnumerateCounterSet.s new file mode 100644 index 00000000..8b7bd91c --- /dev/null +++ b/libc/nt/advapi32/PerfEnumerateCounterSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_PerfEnumerateCounterSet,PerfEnumerateCounterSet,1552 diff --git a/libc/nt/advapi32/PerfEnumerateCounterSetInstances.s b/libc/nt/advapi32/PerfEnumerateCounterSetInstances.s new file mode 100644 index 00000000..a4bdf44d --- /dev/null +++ b/libc/nt/advapi32/PerfEnumerateCounterSetInstances.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_PerfEnumerateCounterSetInstances,PerfEnumerateCounterSetInstances,1553 diff --git a/libc/nt/advapi32/PerfOpenQueryHandle.s b/libc/nt/advapi32/PerfOpenQueryHandle.s new file mode 100644 index 00000000..174d95b5 --- /dev/null +++ b/libc/nt/advapi32/PerfOpenQueryHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_PerfOpenQueryHandle,PerfOpenQueryHandle,1556 diff --git a/libc/nt/advapi32/PerfQueryCounterData.s b/libc/nt/advapi32/PerfQueryCounterData.s new file mode 100644 index 00000000..11b6fcc6 --- /dev/null +++ b/libc/nt/advapi32/PerfQueryCounterData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_PerfQueryCounterData,PerfQueryCounterData,1557 diff --git a/libc/nt/advapi32/PerfQueryCounterInfo.s b/libc/nt/advapi32/PerfQueryCounterInfo.s new file mode 100644 index 00000000..59710f47 --- /dev/null +++ b/libc/nt/advapi32/PerfQueryCounterInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_PerfQueryCounterInfo,PerfQueryCounterInfo,1558 diff --git a/libc/nt/advapi32/PerfQueryCounterSetRegistrationInfo.s b/libc/nt/advapi32/PerfQueryCounterSetRegistrationInfo.s new file mode 100644 index 00000000..3251c417 --- /dev/null +++ b/libc/nt/advapi32/PerfQueryCounterSetRegistrationInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_PerfQueryCounterSetRegistrationInfo,PerfQueryCounterSetRegistrationInfo,1559 diff --git a/libc/nt/advapi32/PerfRegCloseKey.s b/libc/nt/advapi32/PerfRegCloseKey.s new file mode 100644 index 00000000..a6e543af --- /dev/null +++ b/libc/nt/advapi32/PerfRegCloseKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_PerfRegCloseKey,PerfRegCloseKey,1561 diff --git a/libc/nt/advapi32/PerfRegEnumKey.s b/libc/nt/advapi32/PerfRegEnumKey.s new file mode 100644 index 00000000..e55592fc --- /dev/null +++ b/libc/nt/advapi32/PerfRegEnumKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_PerfRegEnumKey,PerfRegEnumKey,1562 diff --git a/libc/nt/advapi32/PerfRegEnumValue.s b/libc/nt/advapi32/PerfRegEnumValue.s new file mode 100644 index 00000000..7d91f449 --- /dev/null +++ b/libc/nt/advapi32/PerfRegEnumValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_PerfRegEnumValue,PerfRegEnumValue,1563 diff --git a/libc/nt/advapi32/PerfRegQueryInfoKey.s b/libc/nt/advapi32/PerfRegQueryInfoKey.s new file mode 100644 index 00000000..53b63e04 --- /dev/null +++ b/libc/nt/advapi32/PerfRegQueryInfoKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_PerfRegQueryInfoKey,PerfRegQueryInfoKey,1564 diff --git a/libc/nt/advapi32/PerfRegQueryValue.s b/libc/nt/advapi32/PerfRegQueryValue.s new file mode 100644 index 00000000..9208dbea --- /dev/null +++ b/libc/nt/advapi32/PerfRegQueryValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_PerfRegQueryValue,PerfRegQueryValue,1565 diff --git a/libc/nt/advapi32/PerfRegSetValue.s b/libc/nt/advapi32/PerfRegSetValue.s new file mode 100644 index 00000000..012e2a6e --- /dev/null +++ b/libc/nt/advapi32/PerfRegSetValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_PerfRegSetValue,PerfRegSetValue,1566 diff --git a/libc/nt/advapi32/PrivilegedServiceAuditAlarmA.s b/libc/nt/advapi32/PrivilegedServiceAuditAlarmA.s new file mode 100644 index 00000000..cb359cc4 --- /dev/null +++ b/libc/nt/advapi32/PrivilegedServiceAuditAlarmA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_PrivilegedServiceAuditAlarmA,PrivilegedServiceAuditAlarmA,1575 diff --git a/libc/nt/advapi32/ProcessIdleTasksW.s b/libc/nt/advapi32/ProcessIdleTasksW.s new file mode 100644 index 00000000..08bdd06f --- /dev/null +++ b/libc/nt/advapi32/ProcessIdleTasksW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ProcessIdleTasksW,ProcessIdleTasksW,1578 diff --git a/libc/nt/advapi32/ProcessTrace.s b/libc/nt/advapi32/ProcessTrace.s new file mode 100644 index 00000000..f37f1aa8 --- /dev/null +++ b/libc/nt/advapi32/ProcessTrace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ProcessTrace,ProcessTrace,1579 diff --git a/libc/nt/advapi32/QueryAllTracesA.s b/libc/nt/advapi32/QueryAllTracesA.s new file mode 100644 index 00000000..aec11575 --- /dev/null +++ b/libc/nt/advapi32/QueryAllTracesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryAllTracesA,QueryAllTracesA,1580 diff --git a/libc/nt/advapi32/QueryAllTracesW.s b/libc/nt/advapi32/QueryAllTracesW.s new file mode 100644 index 00000000..9c97c117 --- /dev/null +++ b/libc/nt/advapi32/QueryAllTracesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryAllTracesW,QueryAllTracesW,1581 diff --git a/libc/nt/advapi32/QueryLocalUserServiceName.s b/libc/nt/advapi32/QueryLocalUserServiceName.s new file mode 100644 index 00000000..13fa6636 --- /dev/null +++ b/libc/nt/advapi32/QueryLocalUserServiceName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryLocalUserServiceName,QueryLocalUserServiceName,1582 diff --git a/libc/nt/advapi32/QueryRecoveryAgentsOnEncryptedFile.s b/libc/nt/advapi32/QueryRecoveryAgentsOnEncryptedFile.s new file mode 100644 index 00000000..d25329b2 --- /dev/null +++ b/libc/nt/advapi32/QueryRecoveryAgentsOnEncryptedFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryRecoveryAgentsOnEncryptedFile,QueryRecoveryAgentsOnEncryptedFile,1583 diff --git a/libc/nt/advapi32/QueryServiceConfig2A.s b/libc/nt/advapi32/QueryServiceConfig2A.s new file mode 100644 index 00000000..bf50d3a3 --- /dev/null +++ b/libc/nt/advapi32/QueryServiceConfig2A.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryServiceConfig2A,QueryServiceConfig2A,1585 diff --git a/libc/nt/advapi32/QueryServiceConfig2W.s b/libc/nt/advapi32/QueryServiceConfig2W.s new file mode 100644 index 00000000..d6400d2e --- /dev/null +++ b/libc/nt/advapi32/QueryServiceConfig2W.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryServiceConfig2W,QueryServiceConfig2W,1586 diff --git a/libc/nt/advapi32/QueryServiceConfigA.s b/libc/nt/advapi32/QueryServiceConfigA.s new file mode 100644 index 00000000..29a3ff62 --- /dev/null +++ b/libc/nt/advapi32/QueryServiceConfigA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryServiceConfigA,QueryServiceConfigA,1587 diff --git a/libc/nt/advapi32/QueryServiceConfigW.s b/libc/nt/advapi32/QueryServiceConfigW.s new file mode 100644 index 00000000..6eaf1262 --- /dev/null +++ b/libc/nt/advapi32/QueryServiceConfigW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryServiceConfigW,QueryServiceConfigW,1588 diff --git a/libc/nt/advapi32/QueryServiceDynamicInformation.s b/libc/nt/advapi32/QueryServiceDynamicInformation.s new file mode 100644 index 00000000..fa54cda1 --- /dev/null +++ b/libc/nt/advapi32/QueryServiceDynamicInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryServiceDynamicInformation,QueryServiceDynamicInformation,1589 diff --git a/libc/nt/advapi32/QueryServiceLockStatusA.s b/libc/nt/advapi32/QueryServiceLockStatusA.s new file mode 100644 index 00000000..50b104de --- /dev/null +++ b/libc/nt/advapi32/QueryServiceLockStatusA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryServiceLockStatusA,QueryServiceLockStatusA,1590 diff --git a/libc/nt/advapi32/QueryServiceLockStatusW.s b/libc/nt/advapi32/QueryServiceLockStatusW.s new file mode 100644 index 00000000..1e1091e0 --- /dev/null +++ b/libc/nt/advapi32/QueryServiceLockStatusW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryServiceLockStatusW,QueryServiceLockStatusW,1591 diff --git a/libc/nt/advapi32/QueryServiceObjectSecurity.s b/libc/nt/advapi32/QueryServiceObjectSecurity.s new file mode 100644 index 00000000..f959e5f5 --- /dev/null +++ b/libc/nt/advapi32/QueryServiceObjectSecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryServiceObjectSecurity,QueryServiceObjectSecurity,1592 diff --git a/libc/nt/advapi32/QueryServiceStatus.s b/libc/nt/advapi32/QueryServiceStatus.s new file mode 100644 index 00000000..2ab71366 --- /dev/null +++ b/libc/nt/advapi32/QueryServiceStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryServiceStatus,QueryServiceStatus,1593 diff --git a/libc/nt/advapi32/QueryServiceStatusEx.s b/libc/nt/advapi32/QueryServiceStatusEx.s new file mode 100644 index 00000000..662a7d26 --- /dev/null +++ b/libc/nt/advapi32/QueryServiceStatusEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryServiceStatusEx,QueryServiceStatusEx,1594 diff --git a/libc/nt/advapi32/QueryTraceA.s b/libc/nt/advapi32/QueryTraceA.s new file mode 100644 index 00000000..84dbf870 --- /dev/null +++ b/libc/nt/advapi32/QueryTraceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryTraceA,QueryTraceA,1595 diff --git a/libc/nt/advapi32/QueryTraceProcessingHandle.s b/libc/nt/advapi32/QueryTraceProcessingHandle.s new file mode 100644 index 00000000..270d0892 --- /dev/null +++ b/libc/nt/advapi32/QueryTraceProcessingHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryTraceProcessingHandle,QueryTraceProcessingHandle,1596 diff --git a/libc/nt/advapi32/QueryTraceW.s b/libc/nt/advapi32/QueryTraceW.s new file mode 100644 index 00000000..89fa0b54 --- /dev/null +++ b/libc/nt/advapi32/QueryTraceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryTraceW,QueryTraceW,1597 diff --git a/libc/nt/advapi32/QueryUserServiceName.s b/libc/nt/advapi32/QueryUserServiceName.s new file mode 100644 index 00000000..a3651e01 --- /dev/null +++ b/libc/nt/advapi32/QueryUserServiceName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryUserServiceName,QueryUserServiceName,1598 diff --git a/libc/nt/advapi32/QueryUserServiceNameForContext.s b/libc/nt/advapi32/QueryUserServiceNameForContext.s new file mode 100644 index 00000000..496280ab --- /dev/null +++ b/libc/nt/advapi32/QueryUserServiceNameForContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryUserServiceNameForContext,QueryUserServiceNameForContext,1599 diff --git a/libc/nt/advapi32/QueryUsersOnEncryptedFile.s b/libc/nt/advapi32/QueryUsersOnEncryptedFile.s new file mode 100644 index 00000000..26429eb7 --- /dev/null +++ b/libc/nt/advapi32/QueryUsersOnEncryptedFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_QueryUsersOnEncryptedFile,QueryUsersOnEncryptedFile,1600 diff --git a/libc/nt/advapi32/ReadEncryptedFileRaw.s b/libc/nt/advapi32/ReadEncryptedFileRaw.s new file mode 100644 index 00000000..febb7578 --- /dev/null +++ b/libc/nt/advapi32/ReadEncryptedFileRaw.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ReadEncryptedFileRaw,ReadEncryptedFileRaw,1601 diff --git a/libc/nt/advapi32/ReadEventLogA.s b/libc/nt/advapi32/ReadEventLogA.s new file mode 100644 index 00000000..1d652e74 --- /dev/null +++ b/libc/nt/advapi32/ReadEventLogA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ReadEventLogA,ReadEventLogA,1602 diff --git a/libc/nt/advapi32/ReadEventLogW.s b/libc/nt/advapi32/ReadEventLogW.s new file mode 100644 index 00000000..d601e8c0 --- /dev/null +++ b/libc/nt/advapi32/ReadEventLogW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ReadEventLogW,ReadEventLogW,1603 diff --git a/libc/nt/advapi32/RegConnectRegistryA.s b/libc/nt/advapi32/RegConnectRegistryA.s new file mode 100644 index 00000000..dac00954 --- /dev/null +++ b/libc/nt/advapi32/RegConnectRegistryA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegConnectRegistryA,RegConnectRegistryA,1605 + + .text.windows +RegConnectRegistryA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegConnectRegistryA(%rip),%rax + jmp __sysv2nt + .endfn RegConnectRegistryA,globl + .previous diff --git a/libc/nt/advapi32/RegConnectRegistryExA.s b/libc/nt/advapi32/RegConnectRegistryExA.s new file mode 100644 index 00000000..6e799405 --- /dev/null +++ b/libc/nt/advapi32/RegConnectRegistryExA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegConnectRegistryExA,RegConnectRegistryExA,1606 + + .text.windows +RegConnectRegistryExA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegConnectRegistryExA(%rip),%rax + jmp __sysv2nt + .endfn RegConnectRegistryExA,globl + .previous diff --git a/libc/nt/advapi32/RegConnectRegistryExW.s b/libc/nt/advapi32/RegConnectRegistryExW.s new file mode 100644 index 00000000..560183d0 --- /dev/null +++ b/libc/nt/advapi32/RegConnectRegistryExW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegConnectRegistryExW,RegConnectRegistryExW,1607 + + .text.windows +RegConnectRegistryEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegConnectRegistryExW(%rip),%rax + jmp __sysv2nt + .endfn RegConnectRegistryEx,globl + .previous diff --git a/libc/nt/advapi32/RegConnectRegistryW.s b/libc/nt/advapi32/RegConnectRegistryW.s new file mode 100644 index 00000000..4d21dfdc --- /dev/null +++ b/libc/nt/advapi32/RegConnectRegistryW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegConnectRegistryW,RegConnectRegistryW,1608 + + .text.windows +RegConnectRegistry: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegConnectRegistryW(%rip),%rax + jmp __sysv2nt + .endfn RegConnectRegistry,globl + .previous diff --git a/libc/nt/advapi32/RegCopyTreeA.s b/libc/nt/advapi32/RegCopyTreeA.s new file mode 100644 index 00000000..9777b3b7 --- /dev/null +++ b/libc/nt/advapi32/RegCopyTreeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegCopyTreeA,RegCopyTreeA,1609 diff --git a/libc/nt/advapi32/RegCreateKeyA.s b/libc/nt/advapi32/RegCreateKeyA.s new file mode 100644 index 00000000..a5bc5bea --- /dev/null +++ b/libc/nt/advapi32/RegCreateKeyA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegCreateKeyA,RegCreateKeyA,1611 + + .text.windows +RegCreateKeyA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegCreateKeyA(%rip),%rax + jmp __sysv2nt + .endfn RegCreateKeyA,globl + .previous diff --git a/libc/nt/advapi32/RegCreateKeyTransactedA.s b/libc/nt/advapi32/RegCreateKeyTransactedA.s new file mode 100644 index 00000000..af8958f5 --- /dev/null +++ b/libc/nt/advapi32/RegCreateKeyTransactedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegCreateKeyTransactedA,RegCreateKeyTransactedA,1614 diff --git a/libc/nt/advapi32/RegCreateKeyTransactedW.s b/libc/nt/advapi32/RegCreateKeyTransactedW.s new file mode 100644 index 00000000..32528043 --- /dev/null +++ b/libc/nt/advapi32/RegCreateKeyTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegCreateKeyTransactedW,RegCreateKeyTransactedW,1615 diff --git a/libc/nt/advapi32/RegCreateKeyW.s b/libc/nt/advapi32/RegCreateKeyW.s new file mode 100644 index 00000000..ba67a21a --- /dev/null +++ b/libc/nt/advapi32/RegCreateKeyW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegCreateKeyW,RegCreateKeyW,1616 + + .text.windows +RegCreateKey: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegCreateKeyW(%rip),%rax + jmp __sysv2nt + .endfn RegCreateKey,globl + .previous diff --git a/libc/nt/advapi32/RegDeleteKeyA.s b/libc/nt/advapi32/RegDeleteKeyA.s new file mode 100644 index 00000000..acabaf5d --- /dev/null +++ b/libc/nt/advapi32/RegDeleteKeyA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegDeleteKeyA,RegDeleteKeyA,1617 + + .text.windows +RegDeleteKeyA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegDeleteKeyA(%rip),%rax + jmp __sysv2nt + .endfn RegDeleteKeyA,globl + .previous diff --git a/libc/nt/advapi32/RegDeleteKeyTransactedA.s b/libc/nt/advapi32/RegDeleteKeyTransactedA.s new file mode 100644 index 00000000..f2496910 --- /dev/null +++ b/libc/nt/advapi32/RegDeleteKeyTransactedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegDeleteKeyTransactedA,RegDeleteKeyTransactedA,1620 diff --git a/libc/nt/advapi32/RegDeleteKeyTransactedW.s b/libc/nt/advapi32/RegDeleteKeyTransactedW.s new file mode 100644 index 00000000..3a976f4e --- /dev/null +++ b/libc/nt/advapi32/RegDeleteKeyTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegDeleteKeyTransactedW,RegDeleteKeyTransactedW,1621 diff --git a/libc/nt/advapi32/RegDeleteKeyW.s b/libc/nt/advapi32/RegDeleteKeyW.s new file mode 100644 index 00000000..c96b13d0 --- /dev/null +++ b/libc/nt/advapi32/RegDeleteKeyW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegDeleteKeyW,RegDeleteKeyW,1624 + + .text.windows +RegDeleteKey: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegDeleteKeyW(%rip),%rax + jmp __sysv2nt + .endfn RegDeleteKey,globl + .previous diff --git a/libc/nt/advapi32/RegDisablePredefinedCache.s b/libc/nt/advapi32/RegDisablePredefinedCache.s new file mode 100644 index 00000000..eeb1acbb --- /dev/null +++ b/libc/nt/advapi32/RegDisablePredefinedCache.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegDisablePredefinedCache,RegDisablePredefinedCache,1629 + + .text.windows +RegDisablePredefinedCache: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RegDisablePredefinedCache(%rip) + leave + ret + .endfn RegDisablePredefinedCache,globl + .previous diff --git a/libc/nt/advapi32/RegDisableReflectionKey.s b/libc/nt/advapi32/RegDisableReflectionKey.s new file mode 100644 index 00000000..3ba179f9 --- /dev/null +++ b/libc/nt/advapi32/RegDisableReflectionKey.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegDisableReflectionKey,RegDisableReflectionKey,1631 + + .text.windows +RegDisableReflectionKey: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RegDisableReflectionKey(%rip) + leave + ret + .endfn RegDisableReflectionKey,globl + .previous diff --git a/libc/nt/advapi32/RegEnableReflectionKey.s b/libc/nt/advapi32/RegEnableReflectionKey.s new file mode 100644 index 00000000..ce2d6200 --- /dev/null +++ b/libc/nt/advapi32/RegEnableReflectionKey.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegEnableReflectionKey,RegEnableReflectionKey,1632 + + .text.windows +RegEnableReflectionKey: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RegEnableReflectionKey(%rip) + leave + ret + .endfn RegEnableReflectionKey,globl + .previous diff --git a/libc/nt/advapi32/RegEnumKeyA.s b/libc/nt/advapi32/RegEnumKeyA.s new file mode 100644 index 00000000..3a3447b7 --- /dev/null +++ b/libc/nt/advapi32/RegEnumKeyA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegEnumKeyA,RegEnumKeyA,1633 + + .text.windows +RegEnumKeyA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegEnumKeyA(%rip),%rax + jmp __sysv2nt + .endfn RegEnumKeyA,globl + .previous diff --git a/libc/nt/advapi32/RegEnumKeyW.s b/libc/nt/advapi32/RegEnumKeyW.s new file mode 100644 index 00000000..a419c0db --- /dev/null +++ b/libc/nt/advapi32/RegEnumKeyW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegEnumKeyW,RegEnumKeyW,1636 + + .text.windows +RegEnumKey: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegEnumKeyW(%rip),%rax + jmp __sysv2nt + .endfn RegEnumKey,globl + .previous diff --git a/libc/nt/advapi32/RegOpenKeyA.s b/libc/nt/advapi32/RegOpenKeyA.s new file mode 100644 index 00000000..f6f11cba --- /dev/null +++ b/libc/nt/advapi32/RegOpenKeyA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegOpenKeyA,RegOpenKeyA,1651 + + .text.windows +RegOpenKeyA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegOpenKeyA(%rip),%rax + jmp __sysv2nt + .endfn RegOpenKeyA,globl + .previous diff --git a/libc/nt/advapi32/RegOpenKeyTransactedA.s b/libc/nt/advapi32/RegOpenKeyTransactedA.s new file mode 100644 index 00000000..a75602fe --- /dev/null +++ b/libc/nt/advapi32/RegOpenKeyTransactedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegOpenKeyTransactedA,RegOpenKeyTransactedA,1654 diff --git a/libc/nt/advapi32/RegOpenKeyTransactedW.s b/libc/nt/advapi32/RegOpenKeyTransactedW.s new file mode 100644 index 00000000..8d00e484 --- /dev/null +++ b/libc/nt/advapi32/RegOpenKeyTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegOpenKeyTransactedW,RegOpenKeyTransactedW,1655 diff --git a/libc/nt/advapi32/RegOpenKeyW.s b/libc/nt/advapi32/RegOpenKeyW.s new file mode 100644 index 00000000..34f65a33 --- /dev/null +++ b/libc/nt/advapi32/RegOpenKeyW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegOpenKeyW,RegOpenKeyW,1656 diff --git a/libc/nt/advapi32/RegOverridePredefKey.s b/libc/nt/advapi32/RegOverridePredefKey.s new file mode 100644 index 00000000..008f596c --- /dev/null +++ b/libc/nt/advapi32/RegOverridePredefKey.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegOverridePredefKey,RegOverridePredefKey,1658 + + .text.windows +RegOverridePredefKey: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegOverridePredefKey(%rip),%rax + jmp __sysv2nt + .endfn RegOverridePredefKey,globl + .previous diff --git a/libc/nt/advapi32/RegQueryReflectionKey.s b/libc/nt/advapi32/RegQueryReflectionKey.s new file mode 100644 index 00000000..f35e142f --- /dev/null +++ b/libc/nt/advapi32/RegQueryReflectionKey.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegQueryReflectionKey,RegQueryReflectionKey,1663 + + .text.windows +RegQueryReflectionKey: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegQueryReflectionKey(%rip),%rax + jmp __sysv2nt + .endfn RegQueryReflectionKey,globl + .previous diff --git a/libc/nt/advapi32/RegQueryValueA.s b/libc/nt/advapi32/RegQueryValueA.s new file mode 100644 index 00000000..7102f69f --- /dev/null +++ b/libc/nt/advapi32/RegQueryValueA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegQueryValueA,RegQueryValueA,1664 + + .text.windows +RegQueryValueA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegQueryValueA(%rip),%rax + jmp __sysv2nt + .endfn RegQueryValueA,globl + .previous diff --git a/libc/nt/advapi32/RegQueryValueW.s b/libc/nt/advapi32/RegQueryValueW.s new file mode 100644 index 00000000..df061056 --- /dev/null +++ b/libc/nt/advapi32/RegQueryValueW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegQueryValueW,RegQueryValueW,1667 + + .text.windows +RegQueryValue: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegQueryValueW(%rip),%rax + jmp __sysv2nt + .endfn RegQueryValue,globl + .previous diff --git a/libc/nt/advapi32/RegRenameKey.s b/libc/nt/advapi32/RegRenameKey.s new file mode 100644 index 00000000..aa440a0a --- /dev/null +++ b/libc/nt/advapi32/RegRenameKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegRenameKey,RegRenameKey,1668 diff --git a/libc/nt/advapi32/RegReplaceKeyA.s b/libc/nt/advapi32/RegReplaceKeyA.s new file mode 100644 index 00000000..66592e4d --- /dev/null +++ b/libc/nt/advapi32/RegReplaceKeyA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegReplaceKeyA,RegReplaceKeyA,1669 + + .text.windows +RegReplaceKeyA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegReplaceKeyA(%rip),%rax + jmp __sysv2nt + .endfn RegReplaceKeyA,globl + .previous diff --git a/libc/nt/advapi32/RegReplaceKeyW.s b/libc/nt/advapi32/RegReplaceKeyW.s new file mode 100644 index 00000000..96db26be --- /dev/null +++ b/libc/nt/advapi32/RegReplaceKeyW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegReplaceKeyW,RegReplaceKeyW,1670 + + .text.windows +RegReplaceKey: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegReplaceKeyW(%rip),%rax + jmp __sysv2nt + .endfn RegReplaceKey,globl + .previous diff --git a/libc/nt/advapi32/RegSaveKeyA.s b/libc/nt/advapi32/RegSaveKeyA.s new file mode 100644 index 00000000..229cf692 --- /dev/null +++ b/libc/nt/advapi32/RegSaveKeyA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegSaveKeyA,RegSaveKeyA,1673 + + .text.windows +RegSaveKeyA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegSaveKeyA(%rip),%rax + jmp __sysv2nt + .endfn RegSaveKeyA,globl + .previous diff --git a/libc/nt/advapi32/RegSaveKeyW.s b/libc/nt/advapi32/RegSaveKeyW.s new file mode 100644 index 00000000..1c0b8803 --- /dev/null +++ b/libc/nt/advapi32/RegSaveKeyW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegSaveKeyW,RegSaveKeyW,1676 + + .text.windows +RegSaveKey: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegSaveKeyW(%rip),%rax + jmp __sysv2nt + .endfn RegSaveKey,globl + .previous diff --git a/libc/nt/advapi32/RegSetValueA.s b/libc/nt/advapi32/RegSetValueA.s new file mode 100644 index 00000000..18d93682 --- /dev/null +++ b/libc/nt/advapi32/RegSetValueA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegSetValueA,RegSetValueA,1680 + + .text.windows +RegSetValueA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegSetValueA(%rip),%rax + jmp __sysv2nt6 + .endfn RegSetValueA,globl + .previous diff --git a/libc/nt/advapi32/RegSetValueW.s b/libc/nt/advapi32/RegSetValueW.s new file mode 100644 index 00000000..24e2d5b4 --- /dev/null +++ b/libc/nt/advapi32/RegSetValueW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegSetValueW,RegSetValueW,1683 + + .text.windows +RegSetValue: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RegSetValueW(%rip),%rax + jmp __sysv2nt6 + .endfn RegSetValue,globl + .previous diff --git a/libc/nt/advapi32/RegisterEventSourceA.s b/libc/nt/advapi32/RegisterEventSourceA.s new file mode 100644 index 00000000..2830af98 --- /dev/null +++ b/libc/nt/advapi32/RegisterEventSourceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegisterEventSourceA,RegisterEventSourceA,1686 diff --git a/libc/nt/advapi32/RegisterEventSourceW.s b/libc/nt/advapi32/RegisterEventSourceW.s new file mode 100644 index 00000000..21b73b78 --- /dev/null +++ b/libc/nt/advapi32/RegisterEventSourceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegisterEventSourceW,RegisterEventSourceW,1687 diff --git a/libc/nt/advapi32/RegisterIdleTask.s b/libc/nt/advapi32/RegisterIdleTask.s new file mode 100644 index 00000000..b4f1b01b --- /dev/null +++ b/libc/nt/advapi32/RegisterIdleTask.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegisterIdleTask,RegisterIdleTask,1688 diff --git a/libc/nt/advapi32/RegisterServiceCtrlHandlerA.s b/libc/nt/advapi32/RegisterServiceCtrlHandlerA.s new file mode 100644 index 00000000..4b29b24d --- /dev/null +++ b/libc/nt/advapi32/RegisterServiceCtrlHandlerA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegisterServiceCtrlHandlerA,RegisterServiceCtrlHandlerA,1689 diff --git a/libc/nt/advapi32/RegisterServiceCtrlHandlerExA.s b/libc/nt/advapi32/RegisterServiceCtrlHandlerExA.s new file mode 100644 index 00000000..7242f256 --- /dev/null +++ b/libc/nt/advapi32/RegisterServiceCtrlHandlerExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegisterServiceCtrlHandlerExA,RegisterServiceCtrlHandlerExA,1690 diff --git a/libc/nt/advapi32/RegisterServiceCtrlHandlerExW.s b/libc/nt/advapi32/RegisterServiceCtrlHandlerExW.s new file mode 100644 index 00000000..6d78f9e9 --- /dev/null +++ b/libc/nt/advapi32/RegisterServiceCtrlHandlerExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegisterServiceCtrlHandlerExW,RegisterServiceCtrlHandlerExW,1691 diff --git a/libc/nt/advapi32/RegisterServiceCtrlHandlerW.s b/libc/nt/advapi32/RegisterServiceCtrlHandlerW.s new file mode 100644 index 00000000..df69c118 --- /dev/null +++ b/libc/nt/advapi32/RegisterServiceCtrlHandlerW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegisterServiceCtrlHandlerW,RegisterServiceCtrlHandlerW,1692 diff --git a/libc/nt/advapi32/RegisterWaitChainCOMCallback.s b/libc/nt/advapi32/RegisterWaitChainCOMCallback.s new file mode 100644 index 00000000..e2cfdbec --- /dev/null +++ b/libc/nt/advapi32/RegisterWaitChainCOMCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RegisterWaitChainCOMCallback,RegisterWaitChainCOMCallback,1695 diff --git a/libc/nt/advapi32/RemoteRegEnumKeyWrapper.s b/libc/nt/advapi32/RemoteRegEnumKeyWrapper.s new file mode 100644 index 00000000..ec5d7d1a --- /dev/null +++ b/libc/nt/advapi32/RemoteRegEnumKeyWrapper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RemoteRegEnumKeyWrapper,RemoteRegEnumKeyWrapper,1696 diff --git a/libc/nt/advapi32/RemoteRegEnumValueWrapper.s b/libc/nt/advapi32/RemoteRegEnumValueWrapper.s new file mode 100644 index 00000000..4d85e32c --- /dev/null +++ b/libc/nt/advapi32/RemoteRegEnumValueWrapper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RemoteRegEnumValueWrapper,RemoteRegEnumValueWrapper,1697 diff --git a/libc/nt/advapi32/RemoteRegQueryInfoKeyWrapper.s b/libc/nt/advapi32/RemoteRegQueryInfoKeyWrapper.s new file mode 100644 index 00000000..e28dae00 --- /dev/null +++ b/libc/nt/advapi32/RemoteRegQueryInfoKeyWrapper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RemoteRegQueryInfoKeyWrapper,RemoteRegQueryInfoKeyWrapper,1698 diff --git a/libc/nt/advapi32/RemoteRegQueryMultipleValues2Wrapper.s b/libc/nt/advapi32/RemoteRegQueryMultipleValues2Wrapper.s new file mode 100644 index 00000000..9010ba07 --- /dev/null +++ b/libc/nt/advapi32/RemoteRegQueryMultipleValues2Wrapper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RemoteRegQueryMultipleValues2Wrapper,RemoteRegQueryMultipleValues2Wrapper,1699 diff --git a/libc/nt/advapi32/RemoteRegQueryMultipleValuesWrapper.s b/libc/nt/advapi32/RemoteRegQueryMultipleValuesWrapper.s new file mode 100644 index 00000000..60c18d40 --- /dev/null +++ b/libc/nt/advapi32/RemoteRegQueryMultipleValuesWrapper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RemoteRegQueryMultipleValuesWrapper,RemoteRegQueryMultipleValuesWrapper,1700 diff --git a/libc/nt/advapi32/RemoteRegQueryValueWrapper.s b/libc/nt/advapi32/RemoteRegQueryValueWrapper.s new file mode 100644 index 00000000..8eddc2cc --- /dev/null +++ b/libc/nt/advapi32/RemoteRegQueryValueWrapper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RemoteRegQueryValueWrapper,RemoteRegQueryValueWrapper,1701 diff --git a/libc/nt/advapi32/RemoveUsersFromEncryptedFile.s b/libc/nt/advapi32/RemoveUsersFromEncryptedFile.s new file mode 100644 index 00000000..3f5d5693 --- /dev/null +++ b/libc/nt/advapi32/RemoveUsersFromEncryptedFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_RemoveUsersFromEncryptedFile,RemoveUsersFromEncryptedFile,1703 diff --git a/libc/nt/advapi32/ReportEventA.s b/libc/nt/advapi32/ReportEventA.s new file mode 100644 index 00000000..e9d133b3 --- /dev/null +++ b/libc/nt/advapi32/ReportEventA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ReportEventA,ReportEventA,1704 diff --git a/libc/nt/advapi32/ReportEventW.s b/libc/nt/advapi32/ReportEventW.s new file mode 100644 index 00000000..294ac626 --- /dev/null +++ b/libc/nt/advapi32/ReportEventW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_ReportEventW,ReportEventW,1705 diff --git a/libc/nt/advapi32/SafeBaseRegGetKeySecurity.s b/libc/nt/advapi32/SafeBaseRegGetKeySecurity.s new file mode 100644 index 00000000..486e2947 --- /dev/null +++ b/libc/nt/advapi32/SafeBaseRegGetKeySecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SafeBaseRegGetKeySecurity,SafeBaseRegGetKeySecurity,1707 diff --git a/libc/nt/advapi32/SaferCloseLevel.s b/libc/nt/advapi32/SaferCloseLevel.s new file mode 100644 index 00000000..6f1b8ec7 --- /dev/null +++ b/libc/nt/advapi32/SaferCloseLevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SaferCloseLevel,SaferCloseLevel,1708 diff --git a/libc/nt/advapi32/SaferComputeTokenFromLevel.s b/libc/nt/advapi32/SaferComputeTokenFromLevel.s new file mode 100644 index 00000000..fa9df866 --- /dev/null +++ b/libc/nt/advapi32/SaferComputeTokenFromLevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SaferComputeTokenFromLevel,SaferComputeTokenFromLevel,1709 diff --git a/libc/nt/advapi32/SaferCreateLevel.s b/libc/nt/advapi32/SaferCreateLevel.s new file mode 100644 index 00000000..f16098ee --- /dev/null +++ b/libc/nt/advapi32/SaferCreateLevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SaferCreateLevel,SaferCreateLevel,1710 diff --git a/libc/nt/advapi32/SaferGetLevelInformation.s b/libc/nt/advapi32/SaferGetLevelInformation.s new file mode 100644 index 00000000..8c1a4a54 --- /dev/null +++ b/libc/nt/advapi32/SaferGetLevelInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SaferGetLevelInformation,SaferGetLevelInformation,1711 diff --git a/libc/nt/advapi32/SaferGetPolicyInformation.s b/libc/nt/advapi32/SaferGetPolicyInformation.s new file mode 100644 index 00000000..d4d72062 --- /dev/null +++ b/libc/nt/advapi32/SaferGetPolicyInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SaferGetPolicyInformation,SaferGetPolicyInformation,1712 diff --git a/libc/nt/advapi32/SaferIdentifyLevel.s b/libc/nt/advapi32/SaferIdentifyLevel.s new file mode 100644 index 00000000..0db7facc --- /dev/null +++ b/libc/nt/advapi32/SaferIdentifyLevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SaferIdentifyLevel,SaferIdentifyLevel,1713 diff --git a/libc/nt/advapi32/SaferRecordEventLogEntry.s b/libc/nt/advapi32/SaferRecordEventLogEntry.s new file mode 100644 index 00000000..fb9cb784 --- /dev/null +++ b/libc/nt/advapi32/SaferRecordEventLogEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SaferRecordEventLogEntry,SaferRecordEventLogEntry,1714 diff --git a/libc/nt/advapi32/SaferSetLevelInformation.s b/libc/nt/advapi32/SaferSetLevelInformation.s new file mode 100644 index 00000000..3b4a9968 --- /dev/null +++ b/libc/nt/advapi32/SaferSetLevelInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SaferSetLevelInformation,SaferSetLevelInformation,1715 diff --git a/libc/nt/advapi32/SaferSetPolicyInformation.s b/libc/nt/advapi32/SaferSetPolicyInformation.s new file mode 100644 index 00000000..5381a59c --- /dev/null +++ b/libc/nt/advapi32/SaferSetPolicyInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SaferSetPolicyInformation,SaferSetPolicyInformation,1716 diff --git a/libc/nt/advapi32/SaferiChangeRegistryScope.s b/libc/nt/advapi32/SaferiChangeRegistryScope.s new file mode 100644 index 00000000..881ff9e6 --- /dev/null +++ b/libc/nt/advapi32/SaferiChangeRegistryScope.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SaferiChangeRegistryScope,SaferiChangeRegistryScope,1717 diff --git a/libc/nt/advapi32/SaferiCompareTokenLevels.s b/libc/nt/advapi32/SaferiCompareTokenLevels.s new file mode 100644 index 00000000..0a9b0f3e --- /dev/null +++ b/libc/nt/advapi32/SaferiCompareTokenLevels.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SaferiCompareTokenLevels,SaferiCompareTokenLevels,1718 diff --git a/libc/nt/advapi32/SaferiIsDllAllowed.s b/libc/nt/advapi32/SaferiIsDllAllowed.s new file mode 100644 index 00000000..fe595d48 --- /dev/null +++ b/libc/nt/advapi32/SaferiIsDllAllowed.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SaferiIsDllAllowed,SaferiIsDllAllowed,1719 diff --git a/libc/nt/advapi32/SaferiIsExecutableFileType.s b/libc/nt/advapi32/SaferiIsExecutableFileType.s new file mode 100644 index 00000000..7b4b04ce --- /dev/null +++ b/libc/nt/advapi32/SaferiIsExecutableFileType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SaferiIsExecutableFileType,SaferiIsExecutableFileType,1720 diff --git a/libc/nt/advapi32/SaferiPopulateDefaultsInRegistry.s b/libc/nt/advapi32/SaferiPopulateDefaultsInRegistry.s new file mode 100644 index 00000000..482f9037 --- /dev/null +++ b/libc/nt/advapi32/SaferiPopulateDefaultsInRegistry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SaferiPopulateDefaultsInRegistry,SaferiPopulateDefaultsInRegistry,1721 diff --git a/libc/nt/advapi32/SaferiRecordEventLogEntry.s b/libc/nt/advapi32/SaferiRecordEventLogEntry.s new file mode 100644 index 00000000..b9822228 --- /dev/null +++ b/libc/nt/advapi32/SaferiRecordEventLogEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SaferiRecordEventLogEntry,SaferiRecordEventLogEntry,1722 diff --git a/libc/nt/advapi32/SaferiSearchMatchingHashRules.s b/libc/nt/advapi32/SaferiSearchMatchingHashRules.s new file mode 100644 index 00000000..480cd374 --- /dev/null +++ b/libc/nt/advapi32/SaferiSearchMatchingHashRules.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SaferiSearchMatchingHashRules,SaferiSearchMatchingHashRules,1723 diff --git a/libc/nt/advapi32/SetEncryptedFileMetadata.s b/libc/nt/advapi32/SetEncryptedFileMetadata.s new file mode 100644 index 00000000..f5dda4a8 --- /dev/null +++ b/libc/nt/advapi32/SetEncryptedFileMetadata.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetEncryptedFileMetadata,SetEncryptedFileMetadata,1725 diff --git a/libc/nt/advapi32/SetEntriesInAccessListA.s b/libc/nt/advapi32/SetEntriesInAccessListA.s new file mode 100644 index 00000000..34b06c94 --- /dev/null +++ b/libc/nt/advapi32/SetEntriesInAccessListA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetEntriesInAccessListA,SetEntriesInAccessListA,1726 diff --git a/libc/nt/advapi32/SetEntriesInAccessListW.s b/libc/nt/advapi32/SetEntriesInAccessListW.s new file mode 100644 index 00000000..a47fe611 --- /dev/null +++ b/libc/nt/advapi32/SetEntriesInAccessListW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetEntriesInAccessListW,SetEntriesInAccessListW,1727 diff --git a/libc/nt/advapi32/SetEntriesInAclA.s b/libc/nt/advapi32/SetEntriesInAclA.s new file mode 100644 index 00000000..72c39dd4 --- /dev/null +++ b/libc/nt/advapi32/SetEntriesInAclA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetEntriesInAclA,SetEntriesInAclA,1728 diff --git a/libc/nt/advapi32/SetEntriesInAclW.s b/libc/nt/advapi32/SetEntriesInAclW.s new file mode 100644 index 00000000..d362553a --- /dev/null +++ b/libc/nt/advapi32/SetEntriesInAclW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetEntriesInAclW,SetEntriesInAclW,1729 diff --git a/libc/nt/advapi32/SetEntriesInAuditListA.s b/libc/nt/advapi32/SetEntriesInAuditListA.s new file mode 100644 index 00000000..90ce4fcb --- /dev/null +++ b/libc/nt/advapi32/SetEntriesInAuditListA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetEntriesInAuditListA,SetEntriesInAuditListA,1730 diff --git a/libc/nt/advapi32/SetEntriesInAuditListW.s b/libc/nt/advapi32/SetEntriesInAuditListW.s new file mode 100644 index 00000000..b1f7c405 --- /dev/null +++ b/libc/nt/advapi32/SetEntriesInAuditListW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetEntriesInAuditListW,SetEntriesInAuditListW,1731 diff --git a/libc/nt/advapi32/SetFileSecurityA.s b/libc/nt/advapi32/SetFileSecurityA.s new file mode 100644 index 00000000..192a2f42 --- /dev/null +++ b/libc/nt/advapi32/SetFileSecurityA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetFileSecurityA,SetFileSecurityA,1732 diff --git a/libc/nt/advapi32/SetInformationCodeAuthzLevelW.s b/libc/nt/advapi32/SetInformationCodeAuthzLevelW.s new file mode 100644 index 00000000..0057b69c --- /dev/null +++ b/libc/nt/advapi32/SetInformationCodeAuthzLevelW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetInformationCodeAuthzLevelW,SetInformationCodeAuthzLevelW,1734 diff --git a/libc/nt/advapi32/SetInformationCodeAuthzPolicyW.s b/libc/nt/advapi32/SetInformationCodeAuthzPolicyW.s new file mode 100644 index 00000000..45abe27e --- /dev/null +++ b/libc/nt/advapi32/SetInformationCodeAuthzPolicyW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetInformationCodeAuthzPolicyW,SetInformationCodeAuthzPolicyW,1735 diff --git a/libc/nt/advapi32/SetNamedSecurityInfoA.s b/libc/nt/advapi32/SetNamedSecurityInfoA.s new file mode 100644 index 00000000..21387c68 --- /dev/null +++ b/libc/nt/advapi32/SetNamedSecurityInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetNamedSecurityInfoA,SetNamedSecurityInfoA,1737 diff --git a/libc/nt/advapi32/SetNamedSecurityInfoExA.s b/libc/nt/advapi32/SetNamedSecurityInfoExA.s new file mode 100644 index 00000000..07513a91 --- /dev/null +++ b/libc/nt/advapi32/SetNamedSecurityInfoExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetNamedSecurityInfoExA,SetNamedSecurityInfoExA,1738 diff --git a/libc/nt/advapi32/SetNamedSecurityInfoExW.s b/libc/nt/advapi32/SetNamedSecurityInfoExW.s new file mode 100644 index 00000000..9c891d2c --- /dev/null +++ b/libc/nt/advapi32/SetNamedSecurityInfoExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetNamedSecurityInfoExW,SetNamedSecurityInfoExW,1739 diff --git a/libc/nt/advapi32/SetNamedSecurityInfoW.s b/libc/nt/advapi32/SetNamedSecurityInfoW.s new file mode 100644 index 00000000..a745c722 --- /dev/null +++ b/libc/nt/advapi32/SetNamedSecurityInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetNamedSecurityInfoW,SetNamedSecurityInfoW,1740 diff --git a/libc/nt/advapi32/SetSecurityInfo.s b/libc/nt/advapi32/SetSecurityInfo.s new file mode 100644 index 00000000..b7dd323c --- /dev/null +++ b/libc/nt/advapi32/SetSecurityInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetSecurityInfo,SetSecurityInfo,1750 diff --git a/libc/nt/advapi32/SetSecurityInfoExA.s b/libc/nt/advapi32/SetSecurityInfoExA.s new file mode 100644 index 00000000..a4e0c9e1 --- /dev/null +++ b/libc/nt/advapi32/SetSecurityInfoExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetSecurityInfoExA,SetSecurityInfoExA,1751 diff --git a/libc/nt/advapi32/SetSecurityInfoExW.s b/libc/nt/advapi32/SetSecurityInfoExW.s new file mode 100644 index 00000000..fc626a01 --- /dev/null +++ b/libc/nt/advapi32/SetSecurityInfoExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetSecurityInfoExW,SetSecurityInfoExW,1752 diff --git a/libc/nt/advapi32/SetServiceBits.s b/libc/nt/advapi32/SetServiceBits.s new file mode 100644 index 00000000..e17cef02 --- /dev/null +++ b/libc/nt/advapi32/SetServiceBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetServiceBits,SetServiceBits,1753 diff --git a/libc/nt/advapi32/SetServiceObjectSecurity.s b/libc/nt/advapi32/SetServiceObjectSecurity.s new file mode 100644 index 00000000..b6689f19 --- /dev/null +++ b/libc/nt/advapi32/SetServiceObjectSecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetServiceObjectSecurity,SetServiceObjectSecurity,1754 diff --git a/libc/nt/advapi32/SetServiceStatus.s b/libc/nt/advapi32/SetServiceStatus.s new file mode 100644 index 00000000..ce17010d --- /dev/null +++ b/libc/nt/advapi32/SetServiceStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetServiceStatus,SetServiceStatus,1755 diff --git a/libc/nt/advapi32/SetUserFileEncryptionKey.s b/libc/nt/advapi32/SetUserFileEncryptionKey.s new file mode 100644 index 00000000..db0e7e94 --- /dev/null +++ b/libc/nt/advapi32/SetUserFileEncryptionKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetUserFileEncryptionKey,SetUserFileEncryptionKey,1759 diff --git a/libc/nt/advapi32/SetUserFileEncryptionKeyEx.s b/libc/nt/advapi32/SetUserFileEncryptionKeyEx.s new file mode 100644 index 00000000..e0a8c9a7 --- /dev/null +++ b/libc/nt/advapi32/SetUserFileEncryptionKeyEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SetUserFileEncryptionKeyEx,SetUserFileEncryptionKeyEx,1760 diff --git a/libc/nt/advapi32/StartServiceA.s b/libc/nt/advapi32/StartServiceA.s new file mode 100644 index 00000000..d9a3aa33 --- /dev/null +++ b/libc/nt/advapi32/StartServiceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_StartServiceA,StartServiceA,1761 diff --git a/libc/nt/advapi32/StartServiceCtrlDispatcherA.s b/libc/nt/advapi32/StartServiceCtrlDispatcherA.s new file mode 100644 index 00000000..db1b7f87 --- /dev/null +++ b/libc/nt/advapi32/StartServiceCtrlDispatcherA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_StartServiceCtrlDispatcherA,StartServiceCtrlDispatcherA,1762 diff --git a/libc/nt/advapi32/StartServiceCtrlDispatcherW.s b/libc/nt/advapi32/StartServiceCtrlDispatcherW.s new file mode 100644 index 00000000..e4116747 --- /dev/null +++ b/libc/nt/advapi32/StartServiceCtrlDispatcherW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_StartServiceCtrlDispatcherW,StartServiceCtrlDispatcherW,1763 diff --git a/libc/nt/advapi32/StartServiceW.s b/libc/nt/advapi32/StartServiceW.s new file mode 100644 index 00000000..6ad6e876 --- /dev/null +++ b/libc/nt/advapi32/StartServiceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_StartServiceW,StartServiceW,1764 diff --git a/libc/nt/advapi32/StartTraceA.s b/libc/nt/advapi32/StartTraceA.s new file mode 100644 index 00000000..5f0650d2 --- /dev/null +++ b/libc/nt/advapi32/StartTraceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_StartTraceA,StartTraceA,1765 diff --git a/libc/nt/advapi32/StartTraceW.s b/libc/nt/advapi32/StartTraceW.s new file mode 100644 index 00000000..5aafb5fa --- /dev/null +++ b/libc/nt/advapi32/StartTraceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_StartTraceW,StartTraceW,1766 diff --git a/libc/nt/advapi32/StopTraceA.s b/libc/nt/advapi32/StopTraceA.s new file mode 100644 index 00000000..4e193a65 --- /dev/null +++ b/libc/nt/advapi32/StopTraceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_StopTraceA,StopTraceA,1767 diff --git a/libc/nt/advapi32/StopTraceW.s b/libc/nt/advapi32/StopTraceW.s new file mode 100644 index 00000000..465fe98f --- /dev/null +++ b/libc/nt/advapi32/StopTraceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_StopTraceW,StopTraceW,1768 diff --git a/libc/nt/advapi32/SystemFunction017.s b/libc/nt/advapi32/SystemFunction017.s new file mode 100644 index 00000000..72a0d449 --- /dev/null +++ b/libc/nt/advapi32/SystemFunction017.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SystemFunction017,SystemFunction017,1785 diff --git a/libc/nt/advapi32/SystemFunction019.s b/libc/nt/advapi32/SystemFunction019.s new file mode 100644 index 00000000..66351f63 --- /dev/null +++ b/libc/nt/advapi32/SystemFunction019.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_SystemFunction019,SystemFunction019,1787 diff --git a/libc/nt/advapi32/TraceSetInformation.s b/libc/nt/advapi32/TraceSetInformation.s new file mode 100644 index 00000000..080e3415 --- /dev/null +++ b/libc/nt/advapi32/TraceSetInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_TraceSetInformation,TraceSetInformation,1812 diff --git a/libc/nt/advapi32/TreeResetNamedSecurityInfoA.s b/libc/nt/advapi32/TreeResetNamedSecurityInfoA.s new file mode 100644 index 00000000..261cf0ac --- /dev/null +++ b/libc/nt/advapi32/TreeResetNamedSecurityInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_TreeResetNamedSecurityInfoA,TreeResetNamedSecurityInfoA,1813 diff --git a/libc/nt/advapi32/TreeResetNamedSecurityInfoW.s b/libc/nt/advapi32/TreeResetNamedSecurityInfoW.s new file mode 100644 index 00000000..ad65ccdc --- /dev/null +++ b/libc/nt/advapi32/TreeResetNamedSecurityInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_TreeResetNamedSecurityInfoW,TreeResetNamedSecurityInfoW,1814 diff --git a/libc/nt/advapi32/TreeSetNamedSecurityInfoA.s b/libc/nt/advapi32/TreeSetNamedSecurityInfoA.s new file mode 100644 index 00000000..04277e6b --- /dev/null +++ b/libc/nt/advapi32/TreeSetNamedSecurityInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_TreeSetNamedSecurityInfoA,TreeSetNamedSecurityInfoA,1815 diff --git a/libc/nt/advapi32/TreeSetNamedSecurityInfoW.s b/libc/nt/advapi32/TreeSetNamedSecurityInfoW.s new file mode 100644 index 00000000..6444cd85 --- /dev/null +++ b/libc/nt/advapi32/TreeSetNamedSecurityInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_TreeSetNamedSecurityInfoW,TreeSetNamedSecurityInfoW,1816 diff --git a/libc/nt/advapi32/TrusteeAccessToObjectA.s b/libc/nt/advapi32/TrusteeAccessToObjectA.s new file mode 100644 index 00000000..94539a77 --- /dev/null +++ b/libc/nt/advapi32/TrusteeAccessToObjectA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_TrusteeAccessToObjectA,TrusteeAccessToObjectA,1817 diff --git a/libc/nt/advapi32/TrusteeAccessToObjectW.s b/libc/nt/advapi32/TrusteeAccessToObjectW.s new file mode 100644 index 00000000..a4a05a5c --- /dev/null +++ b/libc/nt/advapi32/TrusteeAccessToObjectW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_TrusteeAccessToObjectW,TrusteeAccessToObjectW,1818 diff --git a/libc/nt/advapi32/UninstallApplication.s b/libc/nt/advapi32/UninstallApplication.s new file mode 100644 index 00000000..07ea710c --- /dev/null +++ b/libc/nt/advapi32/UninstallApplication.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_UninstallApplication,UninstallApplication,1819 diff --git a/libc/nt/advapi32/UnlockServiceDatabase.s b/libc/nt/advapi32/UnlockServiceDatabase.s new file mode 100644 index 00000000..235fd1e1 --- /dev/null +++ b/libc/nt/advapi32/UnlockServiceDatabase.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_UnlockServiceDatabase,UnlockServiceDatabase,1820 diff --git a/libc/nt/advapi32/UnregisterIdleTask.s b/libc/nt/advapi32/UnregisterIdleTask.s new file mode 100644 index 00000000..240e05ad --- /dev/null +++ b/libc/nt/advapi32/UnregisterIdleTask.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_UnregisterIdleTask,UnregisterIdleTask,1821 diff --git a/libc/nt/advapi32/UpdateTraceA.s b/libc/nt/advapi32/UpdateTraceA.s new file mode 100644 index 00000000..f67a6581 --- /dev/null +++ b/libc/nt/advapi32/UpdateTraceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_UpdateTraceA,UpdateTraceA,1823 diff --git a/libc/nt/advapi32/UpdateTraceW.s b/libc/nt/advapi32/UpdateTraceW.s new file mode 100644 index 00000000..aea02175 --- /dev/null +++ b/libc/nt/advapi32/UpdateTraceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_UpdateTraceW,UpdateTraceW,1824 diff --git a/libc/nt/advapi32/UsePinForEncryptedFilesA.s b/libc/nt/advapi32/UsePinForEncryptedFilesA.s new file mode 100644 index 00000000..649519de --- /dev/null +++ b/libc/nt/advapi32/UsePinForEncryptedFilesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_UsePinForEncryptedFilesA,UsePinForEncryptedFilesA,1825 diff --git a/libc/nt/advapi32/UsePinForEncryptedFilesW.s b/libc/nt/advapi32/UsePinForEncryptedFilesW.s new file mode 100644 index 00000000..af09bc03 --- /dev/null +++ b/libc/nt/advapi32/UsePinForEncryptedFilesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_UsePinForEncryptedFilesW,UsePinForEncryptedFilesW,1826 diff --git a/libc/nt/advapi32/WaitServiceState.s b/libc/nt/advapi32/WaitServiceState.s new file mode 100644 index 00000000..3f5d0061 --- /dev/null +++ b/libc/nt/advapi32/WaitServiceState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WaitServiceState,WaitServiceState,1827 diff --git a/libc/nt/advapi32/WmiCloseBlock.s b/libc/nt/advapi32/WmiCloseBlock.s new file mode 100644 index 00000000..a833ce61 --- /dev/null +++ b/libc/nt/advapi32/WmiCloseBlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiCloseBlock,WmiCloseBlock,1828 diff --git a/libc/nt/advapi32/WmiDevInstToInstanceNameA.s b/libc/nt/advapi32/WmiDevInstToInstanceNameA.s new file mode 100644 index 00000000..5a659bc5 --- /dev/null +++ b/libc/nt/advapi32/WmiDevInstToInstanceNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiDevInstToInstanceNameA,WmiDevInstToInstanceNameA,1829 diff --git a/libc/nt/advapi32/WmiDevInstToInstanceNameW.s b/libc/nt/advapi32/WmiDevInstToInstanceNameW.s new file mode 100644 index 00000000..c4aa8f5c --- /dev/null +++ b/libc/nt/advapi32/WmiDevInstToInstanceNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiDevInstToInstanceNameW,WmiDevInstToInstanceNameW,1830 diff --git a/libc/nt/advapi32/WmiEnumerateGuids.s b/libc/nt/advapi32/WmiEnumerateGuids.s new file mode 100644 index 00000000..8607effa --- /dev/null +++ b/libc/nt/advapi32/WmiEnumerateGuids.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiEnumerateGuids,WmiEnumerateGuids,1831 diff --git a/libc/nt/advapi32/WmiExecuteMethodA.s b/libc/nt/advapi32/WmiExecuteMethodA.s new file mode 100644 index 00000000..8401c52f --- /dev/null +++ b/libc/nt/advapi32/WmiExecuteMethodA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiExecuteMethodA,WmiExecuteMethodA,1832 diff --git a/libc/nt/advapi32/WmiExecuteMethodW.s b/libc/nt/advapi32/WmiExecuteMethodW.s new file mode 100644 index 00000000..5e5f2474 --- /dev/null +++ b/libc/nt/advapi32/WmiExecuteMethodW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiExecuteMethodW,WmiExecuteMethodW,1833 diff --git a/libc/nt/advapi32/WmiFileHandleToInstanceNameA.s b/libc/nt/advapi32/WmiFileHandleToInstanceNameA.s new file mode 100644 index 00000000..aeff46af --- /dev/null +++ b/libc/nt/advapi32/WmiFileHandleToInstanceNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiFileHandleToInstanceNameA,WmiFileHandleToInstanceNameA,1834 diff --git a/libc/nt/advapi32/WmiFileHandleToInstanceNameW.s b/libc/nt/advapi32/WmiFileHandleToInstanceNameW.s new file mode 100644 index 00000000..ecd0a70a --- /dev/null +++ b/libc/nt/advapi32/WmiFileHandleToInstanceNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiFileHandleToInstanceNameW,WmiFileHandleToInstanceNameW,1835 diff --git a/libc/nt/advapi32/WmiFreeBuffer.s b/libc/nt/advapi32/WmiFreeBuffer.s new file mode 100644 index 00000000..3d9ba20b --- /dev/null +++ b/libc/nt/advapi32/WmiFreeBuffer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiFreeBuffer,WmiFreeBuffer,1836 diff --git a/libc/nt/advapi32/WmiMofEnumerateResourcesA.s b/libc/nt/advapi32/WmiMofEnumerateResourcesA.s new file mode 100644 index 00000000..7a92984b --- /dev/null +++ b/libc/nt/advapi32/WmiMofEnumerateResourcesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiMofEnumerateResourcesA,WmiMofEnumerateResourcesA,1837 diff --git a/libc/nt/advapi32/WmiMofEnumerateResourcesW.s b/libc/nt/advapi32/WmiMofEnumerateResourcesW.s new file mode 100644 index 00000000..e9920592 --- /dev/null +++ b/libc/nt/advapi32/WmiMofEnumerateResourcesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiMofEnumerateResourcesW,WmiMofEnumerateResourcesW,1838 diff --git a/libc/nt/advapi32/WmiNotificationRegistrationA.s b/libc/nt/advapi32/WmiNotificationRegistrationA.s new file mode 100644 index 00000000..0aabe8bb --- /dev/null +++ b/libc/nt/advapi32/WmiNotificationRegistrationA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiNotificationRegistrationA,WmiNotificationRegistrationA,1839 diff --git a/libc/nt/advapi32/WmiNotificationRegistrationW.s b/libc/nt/advapi32/WmiNotificationRegistrationW.s new file mode 100644 index 00000000..5490977b --- /dev/null +++ b/libc/nt/advapi32/WmiNotificationRegistrationW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiNotificationRegistrationW,WmiNotificationRegistrationW,1840 diff --git a/libc/nt/advapi32/WmiOpenBlock.s b/libc/nt/advapi32/WmiOpenBlock.s new file mode 100644 index 00000000..3fd3e431 --- /dev/null +++ b/libc/nt/advapi32/WmiOpenBlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiOpenBlock,WmiOpenBlock,1841 diff --git a/libc/nt/advapi32/WmiQueryAllDataA.s b/libc/nt/advapi32/WmiQueryAllDataA.s new file mode 100644 index 00000000..5bb41324 --- /dev/null +++ b/libc/nt/advapi32/WmiQueryAllDataA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiQueryAllDataA,WmiQueryAllDataA,1842 diff --git a/libc/nt/advapi32/WmiQueryAllDataMultipleA.s b/libc/nt/advapi32/WmiQueryAllDataMultipleA.s new file mode 100644 index 00000000..1a19806a --- /dev/null +++ b/libc/nt/advapi32/WmiQueryAllDataMultipleA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiQueryAllDataMultipleA,WmiQueryAllDataMultipleA,1843 diff --git a/libc/nt/advapi32/WmiQueryAllDataMultipleW.s b/libc/nt/advapi32/WmiQueryAllDataMultipleW.s new file mode 100644 index 00000000..2f32d3e6 --- /dev/null +++ b/libc/nt/advapi32/WmiQueryAllDataMultipleW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiQueryAllDataMultipleW,WmiQueryAllDataMultipleW,1844 diff --git a/libc/nt/advapi32/WmiQueryAllDataW.s b/libc/nt/advapi32/WmiQueryAllDataW.s new file mode 100644 index 00000000..0c4b3ce8 --- /dev/null +++ b/libc/nt/advapi32/WmiQueryAllDataW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiQueryAllDataW,WmiQueryAllDataW,1845 diff --git a/libc/nt/advapi32/WmiQueryGuidInformation.s b/libc/nt/advapi32/WmiQueryGuidInformation.s new file mode 100644 index 00000000..53c6623f --- /dev/null +++ b/libc/nt/advapi32/WmiQueryGuidInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiQueryGuidInformation,WmiQueryGuidInformation,1846 diff --git a/libc/nt/advapi32/WmiQuerySingleInstanceA.s b/libc/nt/advapi32/WmiQuerySingleInstanceA.s new file mode 100644 index 00000000..e0dcfb34 --- /dev/null +++ b/libc/nt/advapi32/WmiQuerySingleInstanceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiQuerySingleInstanceA,WmiQuerySingleInstanceA,1847 diff --git a/libc/nt/advapi32/WmiQuerySingleInstanceMultipleA.s b/libc/nt/advapi32/WmiQuerySingleInstanceMultipleA.s new file mode 100644 index 00000000..90a9ce26 --- /dev/null +++ b/libc/nt/advapi32/WmiQuerySingleInstanceMultipleA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiQuerySingleInstanceMultipleA,WmiQuerySingleInstanceMultipleA,1848 diff --git a/libc/nt/advapi32/WmiQuerySingleInstanceMultipleW.s b/libc/nt/advapi32/WmiQuerySingleInstanceMultipleW.s new file mode 100644 index 00000000..a6907981 --- /dev/null +++ b/libc/nt/advapi32/WmiQuerySingleInstanceMultipleW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiQuerySingleInstanceMultipleW,WmiQuerySingleInstanceMultipleW,1849 diff --git a/libc/nt/advapi32/WmiQuerySingleInstanceW.s b/libc/nt/advapi32/WmiQuerySingleInstanceW.s new file mode 100644 index 00000000..bc70e198 --- /dev/null +++ b/libc/nt/advapi32/WmiQuerySingleInstanceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiQuerySingleInstanceW,WmiQuerySingleInstanceW,1850 diff --git a/libc/nt/advapi32/WmiReceiveNotificationsA.s b/libc/nt/advapi32/WmiReceiveNotificationsA.s new file mode 100644 index 00000000..de7870f3 --- /dev/null +++ b/libc/nt/advapi32/WmiReceiveNotificationsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiReceiveNotificationsA,WmiReceiveNotificationsA,1851 diff --git a/libc/nt/advapi32/WmiReceiveNotificationsW.s b/libc/nt/advapi32/WmiReceiveNotificationsW.s new file mode 100644 index 00000000..2229b8b3 --- /dev/null +++ b/libc/nt/advapi32/WmiReceiveNotificationsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiReceiveNotificationsW,WmiReceiveNotificationsW,1852 diff --git a/libc/nt/advapi32/WmiSetSingleInstanceA.s b/libc/nt/advapi32/WmiSetSingleInstanceA.s new file mode 100644 index 00000000..62ad82eb --- /dev/null +++ b/libc/nt/advapi32/WmiSetSingleInstanceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiSetSingleInstanceA,WmiSetSingleInstanceA,1853 diff --git a/libc/nt/advapi32/WmiSetSingleInstanceW.s b/libc/nt/advapi32/WmiSetSingleInstanceW.s new file mode 100644 index 00000000..dff29aa1 --- /dev/null +++ b/libc/nt/advapi32/WmiSetSingleInstanceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiSetSingleInstanceW,WmiSetSingleInstanceW,1854 diff --git a/libc/nt/advapi32/WmiSetSingleItemA.s b/libc/nt/advapi32/WmiSetSingleItemA.s new file mode 100644 index 00000000..d13509e2 --- /dev/null +++ b/libc/nt/advapi32/WmiSetSingleItemA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiSetSingleItemA,WmiSetSingleItemA,1855 diff --git a/libc/nt/advapi32/WmiSetSingleItemW.s b/libc/nt/advapi32/WmiSetSingleItemW.s new file mode 100644 index 00000000..5fbe4c84 --- /dev/null +++ b/libc/nt/advapi32/WmiSetSingleItemW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WmiSetSingleItemW,WmiSetSingleItemW,1856 diff --git a/libc/nt/advapi32/WriteEncryptedFileRaw.s b/libc/nt/advapi32/WriteEncryptedFileRaw.s new file mode 100644 index 00000000..de8396c3 --- /dev/null +++ b/libc/nt/advapi32/WriteEncryptedFileRaw.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp advapi32,__imp_WriteEncryptedFileRaw,WriteEncryptedFileRaw,1857 diff --git a/libc/nt/automation.h b/libc/nt/automation.h new file mode 100644 index 00000000..591f00c2 --- /dev/null +++ b/libc/nt/automation.h @@ -0,0 +1,55 @@ +#ifndef COSMOPOLITAN_LIBC_NT_AUTOMATION_H_ +#define COSMOPOLITAN_LIBC_NT_AUTOMATION_H_ +#include "libc/nt/typedef/hookproc.h" +#include "libc/nt/typedef/wndenumproc.h" +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » aol hacking ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +int64_t GetShellWindow(void); +int64_t GetDesktopWindow(void); +int64_t GetParent(int64_t hWnd); +int64_t SetParent(int64_t hWndChild, int64_t hWndNewParent); +int32_t EnumChildWindows(int64_t hWndParent, NtWndEnumProc lpEnumFunc, + intptr_t lParam); +int64_t FindWindow(const char16_t *lpClassName, const char16_t *lpWindowName); +int64_t FindWindowEx(int64_t hWndParent, int64_t hWndChildAfter, + const char16_t *lpszClass, const char16_t *lpszWindow); +int64_t GetWindow(int64_t hWnd, uint32_t uCmd); +int64_t SetWindowsHook(int nFilterType, NtHookProc pfnFilterProc); +int32_t UnhookWindowsHook(int nCode, NtHookProc pfnFilterProc); +int64_t SetWindowsHookEx(int idHook, NtHookProc lpfn, int64_t hmod, + uint32_t dwThreadId); +int32_t UnhookWindowsHookEx(int64_t hhk); +intptr_t CallNextHookEx(int64_t hhk, int nCode, uintptr_t wParam, + intptr_t lParam); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_AUTOMATION_H_ */ diff --git a/libc/nt/codegen.h b/libc/nt/codegen.h new file mode 100644 index 00000000..0b4a0ced --- /dev/null +++ b/libc/nt/codegen.h @@ -0,0 +1,5 @@ +#ifndef COSMOPOLITAN_LIBC_NT_CODEGEN_H_ +#define COSMOPOLITAN_LIBC_NT_CODEGEN_H_ +#include "ape/idata.h" +#include "ape/macros.h" +#endif /* COSMOPOLITAN_LIBC_NT_CODEGEN_H_ */ diff --git a/libc/nt/codegen.sh b/libc/nt/codegen.sh new file mode 100644 index 00000000..a7e241cc --- /dev/null +++ b/libc/nt/codegen.sh @@ -0,0 +1,108 @@ +/*bin/echo ' -*- mode:sh; indent-tabs-mode:nil; tab-width:8; coding:utf-8 -*-│ +│vi: set net ft=sh ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚────────────────────────────────────────────────────────────────'>/dev/null #*/ +MADEDIRS= + +mkdir -p libc/nt/kernel32 && + touch libc/nt/kernel32/boop.s && + rm -f libc/nt/*/*.s || + exit + +imp() { + NAME="$1" + ACTUAL="$2" + DLL="$3" + HINT="$4" + ARITY="$5" + if [ "$MADEDIRS" != "${MADEDIRS#*$3}" ]; then # ← sre interview question + mkdir -p "libc/nt/$3" + MADEDIRS="$MADEDIRS $3" + fi + { + # Generate Portable Executable import data structures + if [ "$DLL" = "ntdll" ]; then + echo ".include \"o/libc/nt/ntdllimport.inc\"" + echo ".ntimp $ACTUAL" + else + echo ".include \"o/libc/nt/codegen.inc\"" + echo ".imp $DLL,__imp_$ACTUAL,$ACTUAL,$HINT" + fi + + # Generate System Five ABI translating thunks + if [ -n "$NAME" ]; then + case "$ARITY" in + 0) thunk0 "$NAME" "$ACTUAL" "$NAME" ;; + 1) thunk1 "$NAME" "$ACTUAL" "$NAME" ;; + 2|3|4) thunk "$NAME" "$ACTUAL" __sysv2nt "$NAME" ;; + 5|6) thunk "$NAME" "$ACTUAL" __sysv2nt6 "$NAME" ;; + 7|8) thunk "$NAME" "$ACTUAL" __sysv2nt8 "$NAME" ;; + 9|10) thunk "$NAME" "$ACTUAL" __sysv2nt10 "$NAME" ;; + 11|12) thunk "$NAME" "$ACTUAL" __sysv2nt12 "$NAME" ;; + 13|14) thunk "$NAME" "$ACTUAL" __sysv2nt14 "$NAME" ;; + esac + fi + } >libc/nt/$DLL/$ACTUAL.s +} + +thunk() { + printf ' + .text.windows +%s: + push %%rbp + mov %%rsp,%%rbp + .profilable + mov __imp_%s(%%rip),%%rax + jmp %s + .endfn %s,globl + .previous +' "$@" +} + +thunk0() { + printf ' + .text.windows +%s: + push %%rbp + mov %%rsp,%%rbp + .profilable + sub $32,%%rsp + call *__imp_%s(%%rip) + leave + ret + .endfn %s,globl + .previous +' "$@" +} + +thunk1() { + printf ' + .text.windows +%s: + push %%rbp + mov %%rsp,%%rbp + .profilable + mov %%rdi,%%rcx + sub $32,%%rsp + call *__imp_%s(%%rip) + leave + ret + .endfn %s,globl + .previous +' "$@" +} diff --git a/libc/nt/comdlg32/ChooseColorA.s b/libc/nt/comdlg32/ChooseColorA.s new file mode 100644 index 00000000..4002c535 --- /dev/null +++ b/libc/nt/comdlg32/ChooseColorA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_ChooseColorA,ChooseColorA,102 diff --git a/libc/nt/comdlg32/ChooseColorW.s b/libc/nt/comdlg32/ChooseColorW.s new file mode 100644 index 00000000..d8a8165a --- /dev/null +++ b/libc/nt/comdlg32/ChooseColorW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_ChooseColorW,ChooseColorW,103 diff --git a/libc/nt/comdlg32/ChooseFontA.s b/libc/nt/comdlg32/ChooseFontA.s new file mode 100644 index 00000000..01eeb876 --- /dev/null +++ b/libc/nt/comdlg32/ChooseFontA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_ChooseFontA,ChooseFontA,104 diff --git a/libc/nt/comdlg32/ChooseFontW.s b/libc/nt/comdlg32/ChooseFontW.s new file mode 100644 index 00000000..4a84259f --- /dev/null +++ b/libc/nt/comdlg32/ChooseFontW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_ChooseFontW,ChooseFontW,105 diff --git a/libc/nt/comdlg32/CommDlgExtendedError.s b/libc/nt/comdlg32/CommDlgExtendedError.s new file mode 100644 index 00000000..91c45d69 --- /dev/null +++ b/libc/nt/comdlg32/CommDlgExtendedError.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_CommDlgExtendedError,CommDlgExtendedError,106 diff --git a/libc/nt/comdlg32/DllCanUnloadNow.s b/libc/nt/comdlg32/DllCanUnloadNow.s new file mode 100644 index 00000000..3dfb5406 --- /dev/null +++ b/libc/nt/comdlg32/DllCanUnloadNow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_DllCanUnloadNow,DllCanUnloadNow,107 diff --git a/libc/nt/comdlg32/DllGetClassObject.s b/libc/nt/comdlg32/DllGetClassObject.s new file mode 100644 index 00000000..f8441764 --- /dev/null +++ b/libc/nt/comdlg32/DllGetClassObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_DllGetClassObject,DllGetClassObject,108 diff --git a/libc/nt/comdlg32/FindTextA.s b/libc/nt/comdlg32/FindTextA.s new file mode 100644 index 00000000..29ac262c --- /dev/null +++ b/libc/nt/comdlg32/FindTextA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_FindTextA,FindTextA,109 diff --git a/libc/nt/comdlg32/FindTextW.s b/libc/nt/comdlg32/FindTextW.s new file mode 100644 index 00000000..fa42edea --- /dev/null +++ b/libc/nt/comdlg32/FindTextW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_FindTextW,FindTextW,110 diff --git a/libc/nt/comdlg32/GetFileTitleA.s b/libc/nt/comdlg32/GetFileTitleA.s new file mode 100644 index 00000000..60cf7a34 --- /dev/null +++ b/libc/nt/comdlg32/GetFileTitleA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_GetFileTitleA,GetFileTitleA,111 diff --git a/libc/nt/comdlg32/GetFileTitleW.s b/libc/nt/comdlg32/GetFileTitleW.s new file mode 100644 index 00000000..75132c23 --- /dev/null +++ b/libc/nt/comdlg32/GetFileTitleW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_GetFileTitleW,GetFileTitleW,112 diff --git a/libc/nt/comdlg32/GetOpenFileNameA.s b/libc/nt/comdlg32/GetOpenFileNameA.s new file mode 100644 index 00000000..189576e0 --- /dev/null +++ b/libc/nt/comdlg32/GetOpenFileNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_GetOpenFileNameA,GetOpenFileNameA,113 diff --git a/libc/nt/comdlg32/GetOpenFileNameW.s b/libc/nt/comdlg32/GetOpenFileNameW.s new file mode 100644 index 00000000..8a1050ac --- /dev/null +++ b/libc/nt/comdlg32/GetOpenFileNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_GetOpenFileNameW,GetOpenFileNameW,114 diff --git a/libc/nt/comdlg32/GetSaveFileNameA.s b/libc/nt/comdlg32/GetSaveFileNameA.s new file mode 100644 index 00000000..bcc3e522 --- /dev/null +++ b/libc/nt/comdlg32/GetSaveFileNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_GetSaveFileNameA,GetSaveFileNameA,115 diff --git a/libc/nt/comdlg32/GetSaveFileNameW.s b/libc/nt/comdlg32/GetSaveFileNameW.s new file mode 100644 index 00000000..600a6b17 --- /dev/null +++ b/libc/nt/comdlg32/GetSaveFileNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_GetSaveFileNameW,GetSaveFileNameW,116 diff --git a/libc/nt/comdlg32/LoadAlterBitmap.s b/libc/nt/comdlg32/LoadAlterBitmap.s new file mode 100644 index 00000000..d5946c0c --- /dev/null +++ b/libc/nt/comdlg32/LoadAlterBitmap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_LoadAlterBitmap,LoadAlterBitmap,117 diff --git a/libc/nt/comdlg32/PageSetupDlgA.s b/libc/nt/comdlg32/PageSetupDlgA.s new file mode 100644 index 00000000..0e12a033 --- /dev/null +++ b/libc/nt/comdlg32/PageSetupDlgA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_PageSetupDlgA,PageSetupDlgA,118 diff --git a/libc/nt/comdlg32/PageSetupDlgW.s b/libc/nt/comdlg32/PageSetupDlgW.s new file mode 100644 index 00000000..03500c96 --- /dev/null +++ b/libc/nt/comdlg32/PageSetupDlgW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_PageSetupDlgW,PageSetupDlgW,119 diff --git a/libc/nt/comdlg32/PrintDlgA.s b/libc/nt/comdlg32/PrintDlgA.s new file mode 100644 index 00000000..1e943cc0 --- /dev/null +++ b/libc/nt/comdlg32/PrintDlgA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_PrintDlgA,PrintDlgA,120 diff --git a/libc/nt/comdlg32/PrintDlgExA.s b/libc/nt/comdlg32/PrintDlgExA.s new file mode 100644 index 00000000..37b1ae86 --- /dev/null +++ b/libc/nt/comdlg32/PrintDlgExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_PrintDlgExA,PrintDlgExA,121 diff --git a/libc/nt/comdlg32/PrintDlgExW.s b/libc/nt/comdlg32/PrintDlgExW.s new file mode 100644 index 00000000..97939f13 --- /dev/null +++ b/libc/nt/comdlg32/PrintDlgExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_PrintDlgExW,PrintDlgExW,122 diff --git a/libc/nt/comdlg32/PrintDlgW.s b/libc/nt/comdlg32/PrintDlgW.s new file mode 100644 index 00000000..a34648d9 --- /dev/null +++ b/libc/nt/comdlg32/PrintDlgW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_PrintDlgW,PrintDlgW,123 diff --git a/libc/nt/comdlg32/ReplaceTextA.s b/libc/nt/comdlg32/ReplaceTextA.s new file mode 100644 index 00000000..aac7f178 --- /dev/null +++ b/libc/nt/comdlg32/ReplaceTextA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_ReplaceTextA,ReplaceTextA,124 diff --git a/libc/nt/comdlg32/ReplaceTextW.s b/libc/nt/comdlg32/ReplaceTextW.s new file mode 100644 index 00000000..32aa00a9 --- /dev/null +++ b/libc/nt/comdlg32/ReplaceTextW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_ReplaceTextW,ReplaceTextW,125 diff --git a/libc/nt/comdlg32/Ssync_ANSI_UNICODE_Struct_For_WOW.s b/libc/nt/comdlg32/Ssync_ANSI_UNICODE_Struct_For_WOW.s new file mode 100644 index 00000000..f1594a8c --- /dev/null +++ b/libc/nt/comdlg32/Ssync_ANSI_UNICODE_Struct_For_WOW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_Ssync_ANSI_UNICODE_Struct_For_WOW,Ssync_ANSI_UNICODE_Struct_For_WOW,126 diff --git a/libc/nt/comdlg32/WantArrows.s b/libc/nt/comdlg32/WantArrows.s new file mode 100644 index 00000000..4116b04d --- /dev/null +++ b/libc/nt/comdlg32/WantArrows.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_WantArrows,WantArrows,127 diff --git a/libc/nt/comdlg32/dwLBSubclass.s b/libc/nt/comdlg32/dwLBSubclass.s new file mode 100644 index 00000000..9abed942 --- /dev/null +++ b/libc/nt/comdlg32/dwLBSubclass.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_dwLBSubclass,dwLBSubclass,128 diff --git a/libc/nt/comdlg32/dwOKSubclass.s b/libc/nt/comdlg32/dwOKSubclass.s new file mode 100644 index 00000000..b760c18e --- /dev/null +++ b/libc/nt/comdlg32/dwOKSubclass.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp comdlg32,__imp_dwOKSubclass,dwOKSubclass,129 diff --git a/libc/nt/console.h b/libc/nt/console.h new file mode 100644 index 00000000..c5197303 --- /dev/null +++ b/libc/nt/console.h @@ -0,0 +1,119 @@ +#ifndef COSMOPOLITAN_LIBC_NT_CONSOLE_H_ +#define COSMOPOLITAN_LIBC_NT_CONSOLE_H_ +#include "libc/nt/enum/consolemodeflags.h" +#include "libc/nt/struct/coord.h" +#include "libc/nt/thunk/msabi.h" +#include "libc/nt/typedef/handlerroutine.h" +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » console ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +#define kNtAttachParentProcess -1u + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtCharInfo; +struct NtConsoleCursorInfo; +struct NtConsoleScreenBufferInfo; +struct NtConsoleScreenBufferInfoEx; +struct NtConsoleSelectionInfo; +struct NtInputRecord; +struct NtSmallRect; + +bool32 WriteConsoleOutput(int64_t hConsoleOutput, + const struct NtCharInfo *lpBuffer, + struct NtCoord dwBufferSize, + struct NtCoord dwBufferCoord, + struct NtSmallRect *lpWriteRegion); +bool32 ReadConsoleInput(int64_t hConsoleInput, struct NtInputRecord *lpBuffer, + uint32_t nLength, uint32_t *lpNumberOfEventsRead); +bool32 PeekConsoleInput(int64_t hConsoleInput, struct NtInputRecord *lpBuffer, + uint32_t nLength, uint32_t *lpNumberOfEventsRead); +bool32 GetNumberOfConsoleInputEvent(int64_t hConsoleInput, + uint32_t *lpNumberOfEvents); +bool32 ReadConsoleOutput(int64_t hConsoleOutput, struct NtCharInfo *lpBuffer, + struct NtCoord dwBufferSize, + struct NtCoord dwBufferCoord, + struct NtSmallRect *lpReadRegion); +bool32 WriteConsoleInput(int64_t hConsoleInput, + const struct NtInputRecord *lpBuffer, uint32_t nLength, + uint32_t *lpNumberOfEventsWritten); +bool32 FlushConsoleInputBuffer(int64_t hConsoleInput); + +int64_t GetConsoleWindow(void); +bool32 GetConsoleMode(int64_t hConsoleHandle, uint32_t *lpMode); +bool32 SetConsoleMode(int64_t hConsoleHandle, uint32_t dwMode); +int32_t AllocConsole(void); +int32_t FreeConsole(void); +int32_t AttachConsole(uint32_t dwProcessId); +uint32_t GetConsoleTitle(char16_t *lpConsoleTitle, uint32_t nSize); +int32_t SetConsoleTitle(const char16_t *lpConsoleTitle); +bool32 GetConsoleScreenBufferInfo( + int64_t hConsoleOutput, + struct NtConsoleScreenBufferInfo *out_lpConsoleScreenBufferInfo); +bool32 GetConsoleScreenBufferInfoEx( + int64_t hConsoleOutput, + struct NtConsoleScreenBufferInfoEx *in_out_lpConsoleScreenBufferInfo); +bool32 SetConsoleScreenBufferInfoEx( + int64_t hConsoleOutput, + const struct NtConsoleScreenBufferInfoEx *lpConsoleScreenBufferInfo); +bool32 SetConsoleScreenBufferSize(int64_t lpConsoleOutput, + struct NtCoord dwSize); +struct NtCoord GetLargestConsoleWindowSize(int64_t hConsoleHandle); +int32_t ReadConsole(int64_t hConsoleInput, void *lpBuffer, + uint32_t nNumberOfCharsToRead, + uint32_t *lpNumberOfCharsRead, void *lpReserved); +int32_t WriteConsole(int64_t hConsoleOutput, const void *lpBuffer, + uint32_t nNumberOfCharsToWrite, + uint32_t *lpNumberOfCharsWritten, void *lpReserved) + paramsnonnull((2, 4)); +bool32 GetNumberOfConsoleMouseButtons(uint32_t *out_lpNumberOfMouseButtons) + paramsnonnull(); +bool32 GetConsoleSelectionInfo( + struct NtConsoleSelectionInfo *out_lpConsoleSelectionInfo); +uint32_t WaitForInputIdle(int64_t hProcess, uint32_t dwMilliseconds); +uint32_t GetConsoleCP(void); +bool32 SetConsoleCP(uint32_t wCodePageID); +bool32 SetConsoleOutputCP(uint32_t wCodePageID); +uint32_t GetConsoleOutputCP(void); +bool32 SetConsoleCtrlHandler(NtHandlerRoutine opt_HandlerRoutine, bool32 Add); +bool32 GenerateConsoleCtrlEvent(uint32_t dwCtrlEvent, + uint32_t dwProcessGroupId); + +bool32 GetConsoleCursorInfo( + int64_t hConsoleOutput, + struct NtConsoleCursorInfo *out_lpConsoleCursorInfo); +bool32 SetConsoleCursorInfo( + int64_t hConsoleOutput, + const struct NtConsoleCursorInfo *lpConsoleCursorInfo); + +#if ShouldUseMsabiAttribute() +#include "libc/nt/thunk/console.inc" +#endif /* ShouldUseMsabiAttribute() */ +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_CONSOLE_H_ */ diff --git a/libc/nt/createfile.h b/libc/nt/createfile.h new file mode 100644 index 00000000..853eb465 --- /dev/null +++ b/libc/nt/createfile.h @@ -0,0 +1,28 @@ +#ifndef COSMOPOLITAN_LIBC_NT_CREATEFILE_H_ +#define COSMOPOLITAN_LIBC_NT_CREATEFILE_H_ +#include "libc/nt/enum/accessmask.h" +#include "libc/nt/enum/creationdisposition.h" +#include "libc/nt/enum/fileflagandattributes.h" +#include "libc/nt/enum/filesharemode.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtSecurityAttributes; + +int64_t CreateFile( + const char16_t *lpFileName, uint32_t dwDesiredAccess, uint32_t dwShareMode, + struct NtSecurityAttributes *opt_lpSecurityAttributes, + int dwCreationDisposition, + uint32_t dwFlagsAndAttributes, /* libc/nt/enum/fileflagandattributes.h */ + int64_t opt_hTemplateFile) paramsnonnull((1)); + +int64_t CreateFileA( + const char *lpFileName, uint32_t dwDesiredAccess, uint32_t dwShareMode, + struct NtSecurityAttributes *opt_lpSecurityAttributes, + int dwCreationDisposition, + uint32_t dwFlagsAndAttributes, /* libc/nt/enum/fileflagandattributes.h */ + int64_t opt_hTemplateFile) paramsnonnull((1)); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_CREATEFILE_H_ */ diff --git a/libc/nt/debug.h b/libc/nt/debug.h new file mode 100644 index 00000000..7cfeae4c --- /dev/null +++ b/libc/nt/debug.h @@ -0,0 +1,43 @@ +#ifndef COSMOPOLITAN_LIBC_NT_DEBUG_H_ +#define COSMOPOLITAN_LIBC_NT_DEBUG_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » debugging ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +/* Some of these APIs were moved to system.h and libc.h */ +int32_t DebugBreakProcess(void *Process); +int32_t DebugActiveProcess(uint32_t dwProcessId); +int32_t DebugActiveProcessStop(uint32_t dwProcessId); +int32_t CheckRemoteDebuggerPresent(int64_t hProcess, int *pbDebuggerPresent); +int32_t ContinueDebugEvent(uint32_t dwProcessId, uint32_t dwThreadId, + uint32_t dwContinueStatus); +void FatalExit(int uExitCode); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_DEBUG_H_ */ diff --git a/libc/nt/dll.h b/libc/nt/dll.h new file mode 100644 index 00000000..50ebea45 --- /dev/null +++ b/libc/nt/dll.h @@ -0,0 +1,46 @@ +#ifndef COSMOPOLITAN_LIBC_NT_DLL_H_ +#define COSMOPOLITAN_LIBC_NT_DLL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » dynamic link libraries ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +int64_t LoadLibrary(const char16_t *lpLibFileName); +int64_t LoadLibraryEx(const char16_t *lpLibFileName, int64_t hFile, + uint32_t dwFlags); +uint32_t GetModuleFileName(int64_t hModule, char16_t *lpFilename, + uint32_t nSize); +intptr_t GetModuleHandle(const char *lpModuleName); +intptr_t GetModuleHandleW(const char16_t *lpModuleName); +void *GetProcAddress(int64_t hModule, const char *lpProcName); +int32_t FreeResource(int64_t hResData); +intptr_t LockResource(int64_t hResData); +int32_t FreeLibrary(int64_t hLibModule); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_DLL_H_ */ diff --git a/libc/nt/enum/accessmask.h b/libc/nt/enum/accessmask.h new file mode 100644 index 00000000..44cfeb01 --- /dev/null +++ b/libc/nt/enum/accessmask.h @@ -0,0 +1,88 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_ACCESSMASK_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_ACCESSMASK_H_ + +/** + * Can also be described as follows: + * + * struct NtAccessMask { + * union { + * uint32_t value; + * struct { + * uint16_t SpecificRights; + * unsigned char StandardRights; + * unsigned AccessSystemAcl : 1; + * unsigned Reserved : 3; + * unsigned GenericAll : 1; + * unsigned GenericExecute : 1; + * unsigned GenericWrite : 1; + * unsigned GenericRead : 1; + * }; + * }; + * }; + */ +#define kNtGenericRead 0x80000000u +#define kNtGenericWrite 0x40000000u +#define kNtGenericExecute 0x20000000u +#define kNtGenericAll 0x10000000u +#define kNtDelete 0x00010000u +#define kNtReadControl 0x00020000u +#define kNtWriteDac 0x00040000u +#define kNtWriteOwner 0x00080000u +#define kNtSynchronize 0x00100000u +#define kNtStandardRightsRequired 0x000F0000u +#define kNtStandardRightsRead kNtReadControl +#define kNtStandardRightsWrite kNtReadControl +#define kNtStandardRightsExecute kNtReadControl +#define kNtStandardRightsAll 0x001F0000u +#define kNtSpecificRightsAll 0x0000FFFFu +#define kNtAccessSystemSecurity 0x01000000u +#define kNtMaximumAllowed 0x02000000u +#define kNtFileReadData 0x0001u +#define kNtFileListDirectory 0x0001u +#define kNtFileWriteData 0x0002u +#define kNtFileAddFile 0x0002u +#define kNtFileAppendData 0x0004u +#define kNtFileAddSubdirectory 0x0004u +#define kNtFileCreatePipeInstance 0x0004u +#define kNtFileReadEa 0x0008u +#define kNtFileWriteEa 0x0010u +#define kNtFileExecute 0x0020u +#define kNtFileTraverse 0x0020u +#define kNtFileDeleteChild 0x0040u +#define kNtFileReadAttributes 0x0080u +#define kNtFileWriteAttributes 0x0100u +#define kNtFileAllAccess (kNtStandardRightsRequired | kNtSynchronize | 0x1FFu) +#define kNtFileGenericRead \ + (kNtStandardRightsRead | kNtFileReadData | kNtFileReadAttributes | \ + kNtFileReadEa | kNtSynchronize) +#define kNtFileGenericWrite \ + (kNtStandardRightsWrite | kNtFileWriteData | kNtFileWriteAttributes | \ + kNtFileWriteEa | kNtFileAppendData | kNtSynchronize) +#define kNtFileGenericExecute \ + (kNtStandardRightsExecute | kNtFileReadAttributes | kNtFileExecute | \ + kNtSynchronize) +#define kNtTokenAssignPrimary 0x0001u +#define kNtTokenDuplicate 0x0002u +#define kNtTokenImpersonate 0x0004u +#define kNtTokenQuery 0x0008u +#define kNtTokenQuerySource 0x0010u +#define kNtTokenAdjustPrivileges 0x0020u +#define kNtTokenAdjustGroups 0x0040u +#define kNtTokenAdjustDefault 0x0080u +#define kNtTokenAdjustSessionid 0x0100u +#define kNtTokenAllAccessP \ + (kNtStandardRightsRequired | kNtTokenAssignPrimary | kNtTokenDuplicate | \ + kNtTokenImpersonate | kNtTokenQuery | kNtTokenQuerySource | \ + kNtTokenAdjustPrivileges | kNtTokenAdjustGroups | kNtTokenAdjustDefault) +#define kNtTokenAllAccess kNtTokenAllAccessP | kNtTokenAdjustSessionid +#define kNtTokenRead kNtStandardRightsRead | kNtTokenQuery +#define kNtTokenWrite \ + (kNtStandardRightsWrite | kNtTokenAdjustPrivileges | kNtTokenAdjustGroups | \ + kNtTokenAdjustDefault) +#define kNtTokenExecute kNtStandardRightsExecute +#define kNtTokenTrustConstraintMask \ + (kNtStandardRightsRead | kNtTokenQuery | kNtTokenQuerySource) +#define kNtTokenAccessPseudoHandleWin8 kNtTokenQuery | kNtTokenQuerySource +#define kNtTokenAccessPseudoHandle kNtTokenAccessPseudoHandleWin8 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_ACCESSMASK_H_ */ diff --git a/libc/nt/enum/consolemodeflags.h b/libc/nt/enum/consolemodeflags.h new file mode 100644 index 00000000..a0d8bed1 --- /dev/null +++ b/libc/nt/enum/consolemodeflags.h @@ -0,0 +1,23 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_CONSOLEMODEFLAGS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_CONSOLEMODEFLAGS_H_ + +/* input mode */ +#define kNtEnableProcessedInput 0x0001u +#define kNtEnableLineInput 0x0002u +#define kNtEnableEchoInput 0x0004u +#define kNtEnableWindowInput 0x0008u +#define kNtEnableMouseInput 0x0010u +#define kNtEnableInsertMode 0x0020u +#define kNtEnableQuickEditMode 0x0040u +#define kNtEnableExtendedFlags 0x0080u +#define kNtEnableAutoPosition 0x0100u +#define kNtEnableVirtualTerminalInput 0x0200u + +/* output mode */ +#define kNtEnableProcessedOutput 0x0001u +#define kNtEnableWrapAtEolOutput 0x0002u +#define kNtEnableVirtualTerminalProcessing 0x0004u +#define kNtDisableNewlineAutoReturn 0x0008u +#define kNtEnableLvbGridWorldwide 0x0010u + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_CONSOLEMODEFLAGS_H_ */ diff --git a/libc/nt/enum/consoleselectionflags.h b/libc/nt/enum/consoleselectionflags.h new file mode 100644 index 00000000..75e069d1 --- /dev/null +++ b/libc/nt/enum/consoleselectionflags.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_CONSOLESELECTIONFLAGS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_CONSOLESELECTIONFLAGS_H_ + +#define kNtConsoleNoSelection 0x0000u +#define kNtConsoleSelectionInProgress 0x0001u +#define kNtConsoleSelectionNotEmpty 0x0002u +#define kNtConsoleMouseSelection 0x0004u +#define kNtConsoleMouseDown 0x0008u + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_CONSOLESELECTIONFLAGS_H_ */ diff --git a/libc/nt/enum/creationdisposition.h b/libc/nt/enum/creationdisposition.h new file mode 100644 index 00000000..989ed19f --- /dev/null +++ b/libc/nt/enum/creationdisposition.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_CREATIONDISPOSITION_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_CREATIONDISPOSITION_H_ + +#define kNtCreateNew 1 +#define kNtCreateAlways 2 +#define kNtOpenExisting 3 +#define kNtOpenAlways 4 +#define kNtTruncateExisting 5 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_CREATIONDISPOSITION_H_ */ diff --git a/libc/nt/enum/ctrlevent.h b/libc/nt/enum/ctrlevent.h new file mode 100644 index 00000000..98bd348d --- /dev/null +++ b/libc/nt/enum/ctrlevent.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_CTRLEVENT_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_CTRLEVENT_H_ + +#define kNtCtrlCEvent 0 /* SIGINT */ +#define kNtCtrlBreakEvent 1 /* SIGQUIT */ +#define kNtCtrlCloseEvent 2 /* SIGHUP */ +#define kNtCtrlLogoffEvent 5 /* SIGTERM */ +#define kNtCtrlShutdownEvent 6 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_CTRLEVENT_H_ */ diff --git a/libc/nt/enum/dialogresult.h b/libc/nt/enum/dialogresult.h new file mode 100644 index 00000000..f04508c5 --- /dev/null +++ b/libc/nt/enum/dialogresult.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_DIALOGRESULT_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_DIALOGRESULT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum DialogResult { + kNtIdok = 1, + kNtIdcancel = 2, + kNtIdabort = 3, + kNtIdretry = 4, + kNtIdignore = 5, + kNtIdyes = 6, + kNtIdno = 7, + kNtIdclose = 8, + kNtIdhelp = 9, + kNtIdtryagain = 10, + kNtIdcontinue = 11 +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_DIALOGRESULT_H_ */ diff --git a/libc/nt/enum/errormodeflags.h b/libc/nt/enum/errormodeflags.h new file mode 100644 index 00000000..bf18aba9 --- /dev/null +++ b/libc/nt/enum/errormodeflags.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_ERRORMODEFLAGS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_ERRORMODEFLAGS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +enum NtErrorModeFlags { + kNtErrorModeDefault = 0x0, + kNtSemFailcriticalerrors = 0x1, + kNtSemNogpfaulterrorbox = 0x2, + kNtSemNoopenfileerrorbox = 0x8000 +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_ERRORMODEFLAGS_H_ */ diff --git a/libc/nt/enum/eventtype.h b/libc/nt/enum/eventtype.h new file mode 100644 index 00000000..07924f1c --- /dev/null +++ b/libc/nt/enum/eventtype.h @@ -0,0 +1,8 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_EVENTTYPE_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_EVENTTYPE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtEventType { kNtNotificationEvent, kNtSynchronizationEvent }; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_EVENTTYPE_H_ */ diff --git a/libc/nt/enum/exceptionhandleractions.h b/libc/nt/enum/exceptionhandleractions.h new file mode 100644 index 00000000..15358f41 --- /dev/null +++ b/libc/nt/enum/exceptionhandleractions.h @@ -0,0 +1,8 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_EXCEPTIONHANDLERACTIONS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_EXCEPTIONHANDLERACTIONS_H_ + +#define kNtExceptionExecuteHandler 0x1u +#define kNtExceptionContinueExecution 0xffffffffu +#define kNtExceptionContinueSearch 0x0u + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_EXCEPTIONHANDLERACTIONS_H_ */ diff --git a/libc/nt/enum/fileflagandattributes.h b/libc/nt/enum/fileflagandattributes.h new file mode 100644 index 00000000..3d01e8a6 --- /dev/null +++ b/libc/nt/enum/fileflagandattributes.h @@ -0,0 +1,45 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_FILEFLAGANDATTRIBUTES_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_FILEFLAGANDATTRIBUTES_H_ + +/** + * MS-DOS File Attributes. + * + * @see GetFileInformationByHandle() + * @see libc/sysv/consts.sh + */ +#define kNtFileAttributeReadonly 0x00000001u +#define kNtFileAttributeHidden 0x00000002u +#define kNtFileAttributeSystem 0x00000004u +#define kNtFileAttributeVolumelabel 0x00000008u +#define kNtFileAttributeDirectory 0x00000010u +#define kNtFileAttributeArchive 0x00000020u + +/** + * NT File Attributes. + */ +#define kNtFileAttributeDevice 0x00000040u +#define kNtFileAttributeNormal 0x00000080u +#define kNtFileAttributeTemporary 0x00000100u +#define kNtFileAttributeSparseFile 0x00000200u +#define kNtFileAttributeReparsePoint 0x00000400u +#define kNtFileAttributeCompressed 0x00000800u +#define kNtFileAttributeOffline 0x00001000u +#define kNtFileAttributeNotContentIndexed 0x00002000u +#define kNtFileAttributeEncrypted 0x00004000u + +/** + * NT File Flags. + */ +#define kNtFileFlagWriteThrough 0x80000000u +#define kNtFileFlagOverlapped 0x40000000u +#define kNtFileFlagNoBuffering 0x20000000u +#define kNtFileFlagRandomAccess 0x10000000u +#define kNtFileFlagSequentialScan 0x08000000u +#define kNtFileFlagDeleteOnClose 0x04000000u +#define kNtFileFlagBackupSemantics 0x02000000u +#define kNtFileFlagPosixSemantics 0x01000000u +#define kNtFileFlagOpenReparsePoint 0x00200000u /* or symlink */ +#define kNtFileFlagOpenNoRecall 0x00100000u +#define kNtFileFlagFirstPipeInstance 0x00080000u + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_FILEFLAGANDATTRIBUTES_H_ */ diff --git a/libc/nt/enum/fileinfobyhandleclass.h b/libc/nt/enum/fileinfobyhandleclass.h new file mode 100644 index 00000000..9730d8a9 --- /dev/null +++ b/libc/nt/enum/fileinfobyhandleclass.h @@ -0,0 +1,31 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_FILEINFOBYHANDLECLASS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_FILEINFOBYHANDLECLASS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define kNtFileBasicInfo 0 /* struct NtFileBasicInformation */ +#define kNtFileStandardInfo 1 /* struct NtFileStandardInformation */ +#define kNtFileNameInfo 2 /* struct NtFileNameInformation */ +#define kNtFileStreamInfo 7 /* struct NtFileStreamInformation */ +#define kNtFileCompressionInfo 8 /* struct NtFileCompressionInfo */ +#define kNtFileAttributeTagInfo 9 /* struct NtFileAttributeTagInformation */ +#define kNtFileIdBothDirectoryInfo 10 +#define kNtFileIdBothDirectoryRestartInfo 11 +#define kNtFileRemoteProtocolInfo 13 +#define kNtFileFullDirectoryInfo 14 /* NtFileFullDirectoryInformation */ +#define kNtFileFullDirectoryRestartInfo 15 +#define kNtFileStorageInfo 16 /* win8+ */ +#define kNtFileAlignmentInfo 17 /* win8+ */ +#define kNtFileIdInfo 18 /* win8+ */ +#define kNtFileIdExtdDirectoryInfo 19 /* win8+ */ +#define kNtFileIdExtdDirectoryRestartInfo 20 /* win8+ */ + +/* #define kNtFileRenameInfo 4 */ +/* #define kNtFileDispositionInfo 5 */ +/* #define kNtFileAllocationInfo 6 */ +/* #define kNtFileEndOfFileInfo 7 */ +/* #define kNtFileIoPriorityHintInfo 13 */ +/* #define kNtFileDispositionInfoEx 22 /\* win10+ *\/ */ +/* #define kNtFileRenameInfoEx 23 /\* win10+ *\/ */ + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_FILEINFOBYHANDLECLASS_H_ */ diff --git a/libc/nt/enum/fileinformationclass.h b/libc/nt/enum/fileinformationclass.h new file mode 100644 index 00000000..2035ddd1 --- /dev/null +++ b/libc/nt/enum/fileinformationclass.h @@ -0,0 +1,46 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_FILEINFORMATIONCLASS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_FILEINFORMATIONCLASS_H_ + +#define kNtFileDirectoryInformation 1 /*→ struct NtFileDirectoryInformation */ +#define kNtFileFullDirectoryInformation 2 /*→ etc. */ +#define kNtFileBothDirectoryInformation 3 +#define kNtFileBasicInformation 4 +#define kNtFileStandardInformation 5 +#define kNtFileInternalInformation 6 +#define kNtFileEaInformation 7 +#define kNtFileAccessInformation 8 +#define kNtFileNameInformation 9 +#define kNtFileRenameInformation 10 +#define kNtFileLinkInformation 11 +#define kNtFileNamesInformation 12 +#define kNtFileDispositionInformation 13 +#define kNtFilePositionInformation 14 +#define kNtFileFullEaInformation 15 +#define kNtFileModeInformation 16 +#define kNtFileAlignmentInformation 17 +#define kNtFileAllInformation 18 +#define kNtFileAllocationInformation 19 +#define kNtFileEndOfFileInformation 20 +#define kNtFileAlternateNameInformation 21 +#define kNtFileStreamInformation 22 +#define kNtFilePipeInformation 23 +#define kNtFilePipeLocalInformation 24 +#define kNtFilePipeRemoteInformation 25 +#define kNtFileMailslotQueryInformation 26 +#define kNtFileMailslotSetInformation 27 +#define kNtFileCompressionInformation 28 +#define kNtFileObjectIdInformation 29 +#define kNtFileCompletionInformation 30 +#define kNtFileMoveClusterInformation 31 +#define kNtFileQuotaInformation 32 +#define kNtFileReparsePointInformation 33 +#define kNtFileNetworkOpenInformation 34 +#define kNtFileAttributeTagInformation 35 +#define kNtFileTrackingInformation 36 +#define kNtFileIdBothDirectoryInformation 37 +#define kNtFileIdFullDirectoryInformation 38 +#define kNtFileValidDataLengthInformation 39 +#define kNtFileShortNameInformation 40 +#define kNtFileInformation_MAX 40 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_FILEINFORMATIONCLASS_H_ */ diff --git a/libc/nt/enum/filelockflags.h b/libc/nt/enum/filelockflags.h new file mode 100644 index 00000000..3c1457e4 --- /dev/null +++ b/libc/nt/enum/filelockflags.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_FILELOCKFLAGS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_FILELOCKFLAGS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtFileLockFlags { + kNtLockfileFailImmediately = 1, + kNtLockfileExclusiveLock = 2, +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_FILELOCKFLAGS_H_ */ diff --git a/libc/nt/enum/filemapflags.h b/libc/nt/enum/filemapflags.h new file mode 100644 index 00000000..5da8e952 --- /dev/null +++ b/libc/nt/enum/filemapflags.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_FILEMAPFLAGS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_FILEMAPFLAGS_H_ + +/* Choose subset of NtPageFlags passed earlier. */ +#define kNtFileMapCopy 0x00000001u +#define kNtFileMapWrite 0x00000002u +#define kNtFileMapRead 0x00000004u +#define kNtFileMapExecute 0x00000020u +#define kNtFileMapReserve 0x80000000u +#define kNtFileMapTargetsInvalid 0x40000000u +#define kNtFileMapLargePages 0x20000000u + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_FILEMAPFLAGS_H_ */ diff --git a/libc/nt/enum/filemovemethod.h b/libc/nt/enum/filemovemethod.h new file mode 100644 index 00000000..bb93c3cc --- /dev/null +++ b/libc/nt/enum/filemovemethod.h @@ -0,0 +1,8 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_FILEMOVEMETHOD_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_FILEMOVEMETHOD_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtFileMoveMethod { kNtFileBegin, kNtFileCurrent, kNtFileEnd }; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_FILEMOVEMETHOD_H_ */ diff --git a/libc/nt/enum/filesharemode.h b/libc/nt/enum/filesharemode.h new file mode 100644 index 00000000..b28510ba --- /dev/null +++ b/libc/nt/enum/filesharemode.h @@ -0,0 +1,9 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_FILESHAREFLAGS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_FILESHAREFLAGS_H_ + +#define kNtFileShareExclusive 0x00000000u +#define kNtFileShareRead 0x00000001u +#define kNtFileShareWrite 0x00000002u +#define kNtFileShareDelete 0x00000004u + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_FILESHAREFLAGS_H_ */ diff --git a/libc/nt/enum/filetype.h b/libc/nt/enum/filetype.h new file mode 100644 index 00000000..7ddfe4ed --- /dev/null +++ b/libc/nt/enum/filetype.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_FILETYPE_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_FILETYPE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * NT Device File Types. + * + * @see GetFileType() + * @see libc/sysv/consts.sh + */ +enum NtFileType { + kNtFileTypeUnknown = 0x0000, + kNtFileTypeDisk = 0x0001, /* @see S_ISBLK() */ + kNtFileTypeChar = 0x0002, /* @see S_ISCHR() */ + kNtFileTypePipe = 0x0003, /* @see S_ISFIFO() */ + kNtFileTypeRemote = 0x8000 /* unused -MSDN */ +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_FILETYPE_H_ */ diff --git a/libc/nt/enum/fillattribute.h b/libc/nt/enum/fillattribute.h new file mode 100644 index 00000000..83a5c33d --- /dev/null +++ b/libc/nt/enum/fillattribute.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_NTFILLATTRIBUTE_H_ +#define COSMOPOLITAN_LIBC_NT_NTFILLATTRIBUTE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define kNtForegroundBlue 0x0001 +#define kNtForegroundGreen 0x0002 +#define kNtForegroundRed 0x0004 +#define kNtForegroundIntensity 0x0008 +#define kNtBackgroundBlue 0x0010 +#define kNtBackgroundGreen 0x0020 +#define kNtBackgroundRed 0x0040 +#define kNtBackgroundIntensity 0x0080 + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_NTFILLATTRIBUTE_H_ */ diff --git a/libc/nt/enum/findexinfolevels.h b/libc/nt/enum/findexinfolevels.h new file mode 100644 index 00000000..ea4fa1c5 --- /dev/null +++ b/libc/nt/enum/findexinfolevels.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_FINDEXINFOLEVELS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_FINDEXINFOLEVELS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtFindexInfoLevels { + kNtFindExInfoStandard, + kNtFindExInfoBasic, + kNtFindExInfoMaxInfoLevel +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_FINDEXINFOLEVELS_H_ */ diff --git a/libc/nt/enum/findexsearchops.h b/libc/nt/enum/findexsearchops.h new file mode 100644 index 00000000..566536e2 --- /dev/null +++ b/libc/nt/enum/findexsearchops.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_FINDEXSEARCHOPS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_FINDEXSEARCHOPS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtFindexSearchOps { + kNtFindExSearchNameMatch, + kNtFindExSearchLimitToDirectories, + kNtFindExSearchLimitToDevices, + kNtFindExSearchMaxSearchOp +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_FINDEXSEARCHOPS_H_ */ diff --git a/libc/nt/enum/formatmessageflags.h b/libc/nt/enum/formatmessageflags.h new file mode 100644 index 00000000..d35ce30e --- /dev/null +++ b/libc/nt/enum/formatmessageflags.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_FORMATMESSAGEFLAGS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_FORMATMESSAGEFLAGS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtFormatMessageFlags { + kNtFormatMessageAllocateBuffer = 0x100, + kNtFormatMessageIgnoreInserts = 0x200, + kNtFormatMessageFromString = 0x400, + kNtFormatMessageFromHmodule = 0x800, + kNtFormatMessageFromSystem = 0x1000, + kNtFormatMessageArgumentArray = 0x2000, + kNtFormatMessageMaxWidthMask = 0xff +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_FORMATMESSAGEFLAGS_H_ */ diff --git a/libc/nt/enum/fsctl.h b/libc/nt/enum/fsctl.h new file mode 100644 index 00000000..ad4f4447 --- /dev/null +++ b/libc/nt/enum/fsctl.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_FSCTL_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_FSCTL_H_ + +#define kNtFsctlDisableLocalBuffering 0x000902B8u +#define kNtFsctlFilePrefetch 0x00090120u +#define kNtFsctlFilesystemGetStatistics 0x00090060u +#define kNtFsctlGetCompression 0x0009003Cu +#define kNtFsctlGetNtfsFileRecord 0x00090068u +#define kNtFsctlGetNtfsVolumeData 0x00090064u +#define kNtFsctlQueryAllocatedRanges 0x000940CFu +#define kNtFsctlScrubData 0x000902B0u +#define kNtFsctlSetCompression 0x0009C040u +#define kNtFsctlSetSparse 0x000900C4u +#define kNtFsctlSetZeroData 0x000980C8u + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_FSCTL_H_ */ diff --git a/libc/nt/enum/fsinformationclass.h b/libc/nt/enum/fsinformationclass.h new file mode 100644 index 00000000..f32a702c --- /dev/null +++ b/libc/nt/enum/fsinformationclass.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_FSINFORMATIONCLASS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_FSINFORMATIONCLASS_H_ + +#define kNtFileFsVolumeInformation 1 +#define kNtFileFsLabelInformation 2 +#define kNtFileFsSizeInformation 3 +#define kNtFileFsDeviceInformation 4 +#define kNtFileFsAttributeInformation 5 +#define kNtFileFsControlInformation 6 +#define kNtFileFsFullSizeInformation 7 +#define kNtFileFsObjectIdInformation 8 +#define kNtFileFsDriverPathInformation 9 +#define kNtFileFsInformation_MAX 10 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_FSINFORMATIONCLASS_H_ */ diff --git a/libc/nt/enum/getfileexinfolevels.h b/libc/nt/enum/getfileexinfolevels.h new file mode 100644 index 00000000..520d4dbd --- /dev/null +++ b/libc/nt/enum/getfileexinfolevels.h @@ -0,0 +1,8 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_GETFILEEXINFOLEVELS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_GETFILEEXINFOLEVELS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtGetFileexInfoLevels { kNtGetFileExInfoStandard, kNtGetFile_MAX }; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_GETFILEEXINFOLEVELS_H_ */ diff --git a/libc/nt/enum/imageauxsymboltype.h b/libc/nt/enum/imageauxsymboltype.h new file mode 100644 index 00000000..d2211006 --- /dev/null +++ b/libc/nt/enum/imageauxsymboltype.h @@ -0,0 +1,8 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_IMAGEAUXSYMBOLTYPE_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_IMAGEAUXSYMBOLTYPE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtImageAuxSymbolType { IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF = 1 }; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_IMAGEAUXSYMBOLTYPE_H_ */ diff --git a/libc/nt/enum/importobjectnametype.h b/libc/nt/enum/importobjectnametype.h new file mode 100644 index 00000000..8b83c379 --- /dev/null +++ b/libc/nt/enum/importobjectnametype.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_IMPORTOBJECTNAMETYPE_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_IMPORTOBJECTNAMETYPE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtImportObjectNameType { + IMPORT_OBJECT_ORDINAL, + IMPORT_OBJECT_NAME, + IMPORT_OBJECT_NAME_NO_PREFIX, + IMPORT_OBJECT_NAME_UNDECORATE, + IMPORT_OBJECT_NAME_EXPORTAS +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_IMPORTOBJECTNAMETYPE_H_ */ diff --git a/libc/nt/enum/importobjecttype.h b/libc/nt/enum/importobjecttype.h new file mode 100644 index 00000000..9fbb3a6e --- /dev/null +++ b/libc/nt/enum/importobjecttype.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_IMPORTOBJECTTYPE_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_IMPORTOBJECTTYPE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtImportObjectType { + IMPORT_OBJECT_CODE, + IMPORT_OBJECT_DATA, + IMPORT_OBJECT_CONST +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_IMPORTOBJECTTYPE_H_ */ diff --git a/libc/nt/enum/ioctl.h b/libc/nt/enum/ioctl.h new file mode 100644 index 00000000..676d3320 --- /dev/null +++ b/libc/nt/enum/ioctl.h @@ -0,0 +1,6 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_IOCTL_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_IOCTL_H_ + +#define kNtIoctlDiskGetDriveGeometry 0x00070000u + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_IOCTL_H_ */ diff --git a/libc/nt/enum/jobobjectinfoclass.h b/libc/nt/enum/jobobjectinfoclass.h new file mode 100644 index 00000000..3da98d2a --- /dev/null +++ b/libc/nt/enum/jobobjectinfoclass.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_JOBOBJECTINFOCLASS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_JOBOBJECTINFOCLASS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtJobObjectInfoClass { + kNtJobObjectBasicAccountingInformation = 1, + kNtJobObjectBasicLimitInformation, + kNtJobObjectBasicProcessIdList, + kNtJobObjectBasicUIRestrictions, + kNtJobObjectSecurityLimitInformation, + kNtJobObjectEndOfJobTimeInformation, + kNtJobObjectAssociateCompletionPortInformation, + kNtJobObjectBasicAndIoAccountingInformation, + kNtJobObjectExtendedLimitInformation, + kNtJobObjectJobSetInformation, + kNtJobObjectInfoClass_MAX +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_JOBOBJECTINFOCLASS_H_ */ diff --git a/libc/nt/enum/keyaccess.h b/libc/nt/enum/keyaccess.h new file mode 100644 index 00000000..125a5774 --- /dev/null +++ b/libc/nt/enum/keyaccess.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_KEYACCESS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_KEYACCESS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtKeyAccess { + kNtKeyRead = 0x00020019, + kNtKeyWrite = 0x00020006, + kNtKeyExecute = 0x00020019, + kNtKeyAllAccess = 0x000f003f +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_KEYACCESS_H_ */ diff --git a/libc/nt/enum/keyinformationclass.h b/libc/nt/enum/keyinformationclass.h new file mode 100644 index 00000000..9640784e --- /dev/null +++ b/libc/nt/enum/keyinformationclass.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_KEYINFORMATIONCLASS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_KEYINFORMATIONCLASS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtKeyInformationClass { + kNtKeyBasicInformation, + kNtKeyNodeInformation, + kNtKeyFullInformation, + kNtKeyNameInformation +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_KEYINFORMATIONCLASS_H_ */ diff --git a/libc/nt/enum/kwaitreason.h b/libc/nt/enum/kwaitreason.h new file mode 100644 index 00000000..1542a48e --- /dev/null +++ b/libc/nt/enum/kwaitreason.h @@ -0,0 +1,35 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_KWAITREASON_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_KWAITREASON_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define kNtExecutive 0 +#define kNtFreePage 1 +#define kNtPageIn 2 +#define kNtPoolAllocation 3 +#define kNtDelayExecution 4 +#define kNtSuspended 5 +#define kNtUserRequest 6 +#define kNtWrExecutive 7 +#define kNtWrFreePage 8 +#define kNtWrPageIn 9 +#define kNtWrPoolAllocation 10 +#define kNtWrDelayExecution 11 +#define kNtWrSuspended 12 +#define kNtWrUserRequest 13 +#define kNtWrEventPair 14 +#define kNtWrQueue 15 +#define kNtWrLpcReceive 16 +#define kNtWrLpcReply 17 +#define kNtWrVirtualMemory 18 +#define kNtWrPageOut 19 +#define kNtWrRendezvous 20 +#define kNtSpare2 21 +#define kNtSpare3 22 +#define kNtSpare4 23 +#define kNtSpare5 24 +#define kNtSpare6 25 +#define kNtWrKernel 26 +#define kNtMaximumWaitReason 27 + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_KWAITREASON_H_ */ diff --git a/libc/nt/enum/loadlibrarysearch.h b/libc/nt/enum/loadlibrarysearch.h new file mode 100644 index 00000000..bd31e993 --- /dev/null +++ b/libc/nt/enum/loadlibrarysearch.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_LOADLIBRARYSEARCH_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_LOADLIBRARYSEARCH_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define kNtLoadLibrarySearchApplicationDir 0x00000200u +#define kNtLoadLibrarySearchSearchSystem32 0x00000800u +#define kNtLoadLibrarySearchUserDirs 0x00000400u +#define kNtLoadLibrarySearchDefaultDirs 0x00001000u + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_LOADLIBRARYSEARCH_H_ */ diff --git a/libc/nt/enum/memflags.h b/libc/nt/enum/memflags.h new file mode 100644 index 00000000..a39bba7b --- /dev/null +++ b/libc/nt/enum/memflags.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_MEMFLAGS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_MEMFLAGS_H_ + +#define kNtMemCommit 0x1000 /* perform physical memory reservation step */ +#define kNtMemReserve 0x2000 /* perform virtual memory reservation step */ +#define kNtMemDecommit 0x4000 +#define kNtMemRelease 0x8000 +#define kNtMemFree 0x10000 +#define kNtMemPrivate 0x20000 +#define kNtMemMapped 0x40000 +#define kNtMemReset 0x80000 +#define kNtMemTopDown 0x100000 +#define kNtMemWriteWatch 0x200000 +#define kNtMemPhysical 0x400000 +#define kNtMemLargePages 0x20000000 +#define kNtMem4mbPages 0x80000000 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_MEMFLAGS_H_ */ diff --git a/libc/nt/enum/memoryinformationclass.h b/libc/nt/enum/memoryinformationclass.h new file mode 100644 index 00000000..ba0705a8 --- /dev/null +++ b/libc/nt/enum/memoryinformationclass.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_MEMORYINFORMATIONCLASS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_MEMORYINFORMATIONCLASS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtMemoryInformationClass { + kNtMemoryBasicInformation, + kNtMemoryWorkingSetList, + kNtMemorySectionName, + kNtMemoryBasicVlmInformation +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_MEMORYINFORMATIONCLASS_H_ */ diff --git a/libc/nt/enum/messageboxtype.h b/libc/nt/enum/messageboxtype.h new file mode 100644 index 00000000..35c9d510 --- /dev/null +++ b/libc/nt/enum/messageboxtype.h @@ -0,0 +1,46 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_MESSAGEBOXTYPE_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_MESSAGEBOXTYPE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum MessageBoxType { + kNtMbOk = 0x00000000, + kNtMbOkcancel = 0x00000001, + kNtMbAbortretryignore = 0x00000002, + kNtMbYesnocancel = 0x00000003, + kNtMbYesno = 0x00000004, + kNtMbRetrycancel = 0x00000005, + kNtMbCanceltrycontinue = 0x00000006, + kNtMbIconhand = 0x00000010, + kNtMbIconquestion = 0x00000020, + kNtMbIconexclamation = 0x00000030, + kNtMbIconasterisk = 0x00000040, + kNtMbUsericon = 0x00000080, + kNtMbIconwarning = kNtMbIconexclamation, + kNtMbIconerror = kNtMbIconhand, + kNtMbIconinformation = kNtMbIconasterisk, + kNtMbIconstop = kNtMbIconhand, + kNtMbDefbutton1 = 0x00000000, + kNtMbDefbutton2 = 0x00000100, + kNtMbDefbutton3 = 0x00000200, + kNtMbDefbutton4 = 0x00000300, + kNtMbApplmodal = 0x00000000, + kNtMbSystemmodal = 0x00001000, + kNtMbTaskmodal = 0x00002000, + kNtMbHelp = 0x00004000, + kNtMbNofocus = 0x00008000, + kNtMbSetforeground = 0x00010000, + kNtMbDefaultDesktopOnly = 0x00020000, + kNtMbTopmost = 0x00040000, + kNtMbRight = 0x00080000, + kNtMbRtlreading = 0x00100000, + kNtMbServiceNotification = 0x00200000, + kNtMbServiceNotificationNt3x = 0x00040000, + kNtMbTypemask = 0x0000000F, + kNtMbIconmask = 0x000000F0, + kNtMbDefmask = 0x00000F00, + kNtMbModemask = 0x00003000, + kNtMbMiscmask = 0x0000C000 +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_MESSAGEBOXTYPE_H_ */ diff --git a/libc/nt/enum/movefileexflags.h b/libc/nt/enum/movefileexflags.h new file mode 100644 index 00000000..a45b124b --- /dev/null +++ b/libc/nt/enum/movefileexflags.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_MOVEFILEEXFLAGS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_MOVEFILEEXFLAGS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtMoveFileExFlags { + kNtMovefileReplaceExisting = 1, + kNtMovefileCopyAllowed = 2, + kNtMovefileDelayUntilReboot = 4, + kNtMovefileCreateHardlink = 16, + kNtMovefileFailIfNotTrackable = 32, + kNtMovefileWriteThrough = 8 +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_MOVEFILEEXFLAGS_H_ */ diff --git a/libc/nt/enum/objectinformationclass.h b/libc/nt/enum/objectinformationclass.h new file mode 100644 index 00000000..743d6a32 --- /dev/null +++ b/libc/nt/enum/objectinformationclass.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_OBJECTINFORMATIONCLASS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_OBJECTINFORMATIONCLASS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtObjectInformationClass { + kNtObjectBasicInformation, /*→ struct NtObjectBasicInformation */ + kNtObjectNameInformation, /*→ etc. */ + kNtObjectTypeInformation, + kNtObjectAllInformation, + kNtObjectDataInformation +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_OBJECTINFORMATIONCLASS_H_ */ diff --git a/libc/nt/enum/offerpriority.h b/libc/nt/enum/offerpriority.h new file mode 100644 index 00000000..10c23359 --- /dev/null +++ b/libc/nt/enum/offerpriority.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_OFFERPRIORITY_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_OFFERPRIORITY_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtOfferPriority { + /* TODO(jart): Are these values correct? */ + kNtVmOfferPriorityVeryLow = 1, /* 0x00001000? */ + kNtVmOfferPriorityLow, /* 0x00002000? */ + kNtVmOfferPriorityBelowNormal, /* 0x00002000? */ + kNtVmOfferPriorityNormal /* 0x00002000? */ +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_OFFERPRIORITY_H_ */ diff --git a/libc/nt/enum/pageflags.h b/libc/nt/enum/pageflags.h new file mode 100644 index 00000000..ba76a0db --- /dev/null +++ b/libc/nt/enum/pageflags.h @@ -0,0 +1,26 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_PAGEFLAGS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_PAGEFLAGS_H_ + +/* Pick One */ +#define kNtPageNoaccess 0x01 +#define kNtPageReadonly 0x02 +#define kNtPageReadwrite 0x04 +#define kNtPageWritecopy 0x08 +#define kNtPageExecute 0x10 +#define kNtPageExecuteRead 0x20 +#define kNtPageExecuteReadwrite 0x40 +#define kNtPageExecuteWritecopy 0x80 +#define kNtPageGuard 0x100 +#define kNtPageNocache 0x200 +#define kNtPageWritecombine 0x400 + +/* These may be OR'd */ +#define kNtSecReserve 0x4000000 +#define kNtSecCommit 0x8000000 /* ←default */ +#define kNtSecImage 0x1000000 +#define kNtSecImageNoExecute 0x11000000 +#define kNtSecLargePages 0x80000000 +#define kNtSecNocache 0x10000000 +#define kNtSecWritecombine 0x40000000 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_PAGEFLAGS_H_ */ diff --git a/libc/nt/enum/processaccess.h b/libc/nt/enum/processaccess.h new file mode 100644 index 00000000..2844f713 --- /dev/null +++ b/libc/nt/enum/processaccess.h @@ -0,0 +1,21 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_PROCESSACCESS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_PROCESSACCESS_H_ +#include "libc/nt/enum/accessmask.h" + +#define kNtProcessCreateProcess 0x0080u +#define kNtProcessCreateThread 0x0002u +#define kNtProcessDupHandle 0x0040u +#define kNtProcessQueryInformation 0x0400u +#define kNtProcessQueryLimitedInformation 0x1000u +#define kNtProcessSetInformation 0x0200u +#define kNtProcessSetQuota 0x0100u +#define kNtProcessSuspendResume 0x0800u +#define kNtProcessTerminate 0x0001u +#define kNtProcessVmOperation 0x0008u +#define kNtProcessVmRead 0x0010u +#define kNtProcessVmWrite 0x0020u +#define kNtProcessSynchronize kNtSynchronize +#define kNtProcessAllAccess \ + (kNtStandardRightsRequired | kNtSynchronize | 0xffffu) + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_PROCESSACCESS_H_ */ diff --git a/libc/nt/enum/processcreationflags.h b/libc/nt/enum/processcreationflags.h new file mode 100644 index 00000000..e0ff5403 --- /dev/null +++ b/libc/nt/enum/processcreationflags.h @@ -0,0 +1,36 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_PROCESSCREATIONFLAGS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_PROCESSCREATIONFLAGS_H_ + +#define kNtIdlePriorityClass 0x00000040u +#define kNtBelowNormalPriorityClass 0x00004000u +#define kNtNormalPriorityClass 0x00000020u +#define kNtAboveNormalPriorityClass 0x00008000u +#define kNtHighPriorityClass 0x00000080u +#define kNtRealtimePriorityClass 0x00000100u + +#define kNtDebugProcess 0x00000001u +#define kNtDebugOnlyThisProcess 0x00000002u +#define kNtCreateSuspended 0x00000004u +#define kNtDetachedProcess 0x00000008u +#define kNtCreateNewConsole 0x00000010u +#define kNtCreateNewProcessGroup 0x00000200u +#define kNtCreateUnicodeEnvironment 0x00000400u +#define kNtCreateSeparateWowVdm 0x00000800u +#define kNtCreateSharedWowVdm 0x00001000u +#define kNtCreateForcedos 0x00002000u +#define kNtInheritParentAffinity 0x00010000u +#define kNtCreateProtectedProcess 0x00040000u +#define kNtExtendedStartupinfoPresent 0x00080000u +#define kNtProcessModeBackgroundBegin 0x00100000u +#define kNtProcessModeBackgroundEnd 0x00200000u +#define kNtCreateSecureProcess 0x00400000u +#define kNtCreateBreakawayFromJob 0x01000000u +#define kNtCreatePreserveCodeAuthzLevel 0x02000000u +#define kNtCreateDefaultErrorMode 0x04000000u +#define kNtCreateNoWindow 0x08000000u +#define kNtProfileUser 0x10000000u +#define kNtProfileKernel 0x20000000u +#define kNtProfileServer 0x40000000u +#define kNtCreateIgnoreSystemDefault 0x80000000u + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_PROCESSCREATIONFLAGS_H_ */ diff --git a/libc/nt/enum/processinfoclass.h b/libc/nt/enum/processinfoclass.h new file mode 100644 index 00000000..7be961a0 --- /dev/null +++ b/libc/nt/enum/processinfoclass.h @@ -0,0 +1,21 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_PROCESSINFOCLASS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_PROCESSINFOCLASS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtProcessInfoClass { + kNtProcessBasicInformation = 0, + kNtProcessQuotaLimits = 1, + kNtProcessIoCounters = 2, + kNtProcessVmCounters = 3, + kNtProcessTimes = 4, + kNtProcessBasePriority = 5, + kNtProcessRaisePriority = 6, + kNtProcessDebugPort = 7, + kNtProcessExceptionPort = 8, + kNtProcessAccessToken = 9, + kNtProcessWow64Information = 26, + kNtProcessImageFileName = 27 +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_PROCESSINFOCLASS_H_ */ diff --git a/libc/nt/enum/procthreadattributes.h b/libc/nt/enum/procthreadattributes.h new file mode 100644 index 00000000..939f24e9 --- /dev/null +++ b/libc/nt/enum/procthreadattributes.h @@ -0,0 +1,7 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_PROCTHREADATTRIBUTES_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_PROCTHREADATTRIBUTES_H_ + +#define kNtProcThreadAttributeReplaceValue 1 +#define kNtProcThreadAttributeHandleList 0x00020002 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_PROCTHREADATTRIBUTES_H_ */ diff --git a/libc/nt/enum/reggetvalueflags.h b/libc/nt/enum/reggetvalueflags.h new file mode 100644 index 00000000..8def968f --- /dev/null +++ b/libc/nt/enum/reggetvalueflags.h @@ -0,0 +1,24 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_REGGETVALUEFLAGS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_REGGETVALUEFLAGS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtRegGetValueFlags { + kNtRrfRtRegNone = 0x00000001, + kNtRrfRtRegSz = 0x00000002, + kNtRrfRtRegExpandSz = 0x00000004, + kNtRrfRtRegBinary = 0x00000008, + kNtRrfRtRegDword = 0x00000010, + kNtRrfRtRegMultiSz = 0x00000020, + kNtRrfRtRegQword = 0x00000040, + kNtRrfRtDword = kNtRrfRtRegBinary | kNtRrfRtRegDword, + kNtRrfRtQword = kNtRrfRtRegBinary | kNtRrfRtRegQword, + kNtRrfRtAny = 0x0000ffff, + kNtRrfSubkeyWow6464key = 0x00010000, + kNtRrfSubkeyWow6432key = 0x00020000, + kNtRrfWow64Mask = 0x00030000, + kNtRrfNoexpand = 0x10000000, + kNtRrfZeroonfailure = 0x20000000 +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_REGGETVALUEFLAGS_H_ */ diff --git a/libc/nt/enum/regtype.h b/libc/nt/enum/regtype.h new file mode 100644 index 00000000..41bab0c6 --- /dev/null +++ b/libc/nt/enum/regtype.h @@ -0,0 +1,21 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_REGTYPE_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_REGTYPE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtRegType { + kNtRegNone = 0, + kNtRegSz = 1, /* UTF-16 NUL-terminated string */ + kNtRegExpandSz = 2, /* UTF-16 NUL-terminated string w/ env vars refs */ + kNtRegBinary = 3, + kNtRegDword = 4, + kNtRegDwordBigEndian = 5, + kNtRegLink = 6, + kNtRegMultiSz = 7, /* UTF-16 double-NUL-terminated string list */ + kNtRegResourceList = 8, + kNtRegFullResourceDescriptor = 9, + kNtRegResourceRequirementsList = 10, + kNtRegQword = 11, +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_REGTYPE_H_ */ diff --git a/libc/nt/enum/sectioninformationclass.h b/libc/nt/enum/sectioninformationclass.h new file mode 100644 index 00000000..1075730d --- /dev/null +++ b/libc/nt/enum/sectioninformationclass.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_SECTIONINFORMATIONCLASS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_SECTIONINFORMATIONCLASS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtSectionInformationClass { + kNtSectionBasicInformation, + kNtSectionImageInformation +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_SECTIONINFORMATIONCLASS_H_ */ diff --git a/libc/nt/enum/sectioninherit.h b/libc/nt/enum/sectioninherit.h new file mode 100644 index 00000000..552e0ba5 --- /dev/null +++ b/libc/nt/enum/sectioninherit.h @@ -0,0 +1,8 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_SECTIONINHERIT_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_SECTIONINHERIT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtSectionInherit { kNtViewShare = 1, kNtViewUnmap = 2 }; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_SECTIONINHERIT_H_ */ diff --git a/libc/nt/enum/sectionmapflags.h b/libc/nt/enum/sectionmapflags.h new file mode 100644 index 00000000..8daef5b0 --- /dev/null +++ b/libc/nt/enum/sectionmapflags.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_SECTIONMAPFLAGS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_SECTIONMAPFLAGS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtSectionMapFlags { + kNtSectionQuery = 0x0001, + kNtSectionMapWrite = 0x0002, + kNtSectionMapRead = 0x0004, + kNtSectionMapExecute = 0x0008, + kNtSectionExtendSize = 0x0010, + kNtSectionMapExecuteExplicit = 0x0020 +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_SECTIONMAPFLAGS_H_ */ diff --git a/libc/nt/enum/securityimpersonationlevel.h b/libc/nt/enum/securityimpersonationlevel.h new file mode 100644 index 00000000..9aefc6a3 --- /dev/null +++ b/libc/nt/enum/securityimpersonationlevel.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_SECURITYIMPERSONATIONLEVEL_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_SECURITYIMPERSONATIONLEVEL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtSecurityImpersonationLevel { + kNtSecurityAnonymous, + kNtSecurityIdentification, + kNtSecurityImpersonation, + kNtSecurityDelegation +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_SECURITYIMPERSONATIONLEVEL_H_ */ diff --git a/libc/nt/enum/securityinformation.h b/libc/nt/enum/securityinformation.h new file mode 100644 index 00000000..0fbd2d41 --- /dev/null +++ b/libc/nt/enum/securityinformation.h @@ -0,0 +1,19 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_SECURITYINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_SECURITYINFORMATION_H_ + +#define kNtOwnerSecurityInformation 0x00000001 +#define kNtGroupSecurityInformation 0x00000002 +#define kNtDaclSecurityInformation 0x00000004 +#define kNtSaclSecurityInformation 0x00000008 +#define kNtLabelSecurityInformation 0x00000010 +#define kNtAttributeSecurityInformation 0x00000020 +#define kNtScopeSecurityInformation 0x00000040 +#define kNtProcessTrustLabelSecurityInformation 0x00000080 +#define kNtAccessFilterSecurityInformation 0x00000100 +#define kNtBackupSecurityInformation 0x00010000 +#define kNtProtectedDaclSecurityInformation 0x80000000 +#define kNtProtectedSaclSecurityInformation 0x40000000 +#define kNtUnprotectedDaclSecurityInformation 0x20000000 +#define kNtUnprotectedSaclSecurityInformation 0x10000000 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_SECURITYINFORMATION_H_ */ diff --git a/libc/nt/enum/startf.h b/libc/nt/enum/startf.h new file mode 100644 index 00000000..5464f50a --- /dev/null +++ b/libc/nt/enum/startf.h @@ -0,0 +1,19 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_STARTF_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_STARTF_H_ + +#define kNtStartfUseshowwindow 0x00000001 /* otherwise wShowWindow ignored */ +#define kNtStartfUsesize 0x00000002 /* otherwise dwX / dwY ignored */ +#define kNtStartfUseposition 0x00000004 /* otherwise dwX/YSize ignored */ +#define kNtStartfUsecountchars 0x00000008 /* otherwise dwX/YCountChars ign. */ +#define kNtStartfUsefillattribute 0x00000010 /* etc. */ +#define kNtStartfRunfullscreen 0x00000020 +#define kNtStartfForceonfeedback 0x00000040 +#define kNtStartfForceofffeedback 0x00000080 +#define kNtStartfUsestdhandles 0x00000100 /* otherwise hStd... ignored */ +#define kNtStartfUsehotkey 0x00000200 +#define kNtStartfTitleislinkname 0x00000800 +#define kNtStartfTitleisappid 0x00001000 +#define kNtStartfPreventpinning 0x00002000 +#define kNtStartfUntrustedsource 0x00008000 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_STARTF_H_ */ diff --git a/libc/nt/enum/status.h b/libc/nt/enum/status.h new file mode 100644 index 00000000..5e2e65f1 --- /dev/null +++ b/libc/nt/enum/status.h @@ -0,0 +1,80 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STATUS_H_ +#define COSMOPOLITAN_LIBC_NT_STATUS_H_ + +/* high two bits = {success,informational,warning,error} */ +#define kNtStatusWait0 0x00000000 /* success statuses */ +#define kNtStatusAbandonedWait0 0x00000080 +#define kNtStatusUserApc 0x000000C0 +#define kNtStatusTimeout 0x00000102 +#define kNtStatusPending 0x00000103 +#define kNtStatusGuardPageViolation 0x80000001 /* warning statuses */ +#define kNtStatusDatatypeMisalignment 0x80000002 +#define kNtStatusBreakpoint 0x80000003 +#define kNtStatusSingleStep 0x80000004 +#define kNtStatusLongjump 0x80000026 +#define kNtStatusUnwindConsolidate 0x80000029 +#define kNtStatusAccessViolation 0xC0000005 /* error statuses */ +#define kNtStatusInPageError 0xC0000006 +#define kNtStatusInvalidHandle 0xC0000008 +#define kNtStatusInvalidParameter 0xC000000D +#define kNtStatusNoMemory 0xC0000017 +#define kNtStatusIllegalInstruction 0xC000001D +#define kNtStatusNoncontinuableException 0xC0000025 +#define kNtStatusInvalidDisposition 0xC0000026 +#define kNtStatusArrayBoundsExceeded 0xC000008C +#define kNtStatusFloatDenormalOperand 0xC000008D +#define kNtStatusFloatDivideByZero 0xC000008E +#define kNtStatusFloatInexactResult 0xC000008F +#define kNtStatusFloatInvalidOperation 0xC0000090 +#define kNtStatusFloatOverflow 0xC0000091 +#define kNtStatusFloatStackCheck 0xC0000092 +#define kNtStatusFloatUnderflow 0xC0000093 +#define kNtStatusIntegerDivideBYZero 0xC0000094 +#define kNtStatusIntegerOverflow 0xC0000095 +#define kNtStatusPrivilegedInstruction 0xC0000096 +#define kNtStatusStackOverflow 0xC00000FD +#define kNtStatusDllNotFound 0xC0000135 +#define kNtStatusOrdinalNotFound 0xC0000138 +#define kNtStatusEntrypointNotFound 0xC0000139 +#define kNtStatusControlCExit 0xC000013A +#define kNtStatusDllInitFailed 0xC0000142 +#define kNtStatusFloatMultipleFaults 0xC00002B4 +#define kNtStatusFloatMultipleTraps 0xC00002B5 +#define kNtStatusRegNatConsumption 0xC00002C9 +#define kNtStatusHeapCorruption 0xC0000374 +#define kNtStatusStackBufferOverrun 0xC0000409 +#define kNtStatusInvalidCruntimeParameter 0xC0000417 +#define kNtStatusAssertionFailure 0xC0000420 +#define kNtStatusEnclaveViolation 0xC00004A2 +#define kNtStatusSegmentNotification 0x40000005 +#define kNtStatusFatalAppExit 0x40000015 +/* statuses for the debugger facility */ +#define kNtDbgExceptionHandled 0x00010001 +#define kNtDbgContinue 0x00010002 +#define kNtDbgReplyLater 0x40010001 +#define kNtDbgTerminateThread 0x40010003 +#define kNtDbgTerminateProcess 0x40010004 +#define kNtDbgControlC 0x40010005 +#define kNtDbgPrintexceptionC 0x40010006 +#define kNtDbgRipexception 0x40010007 +#define kNtDbgControlBreak 0x40010008 +#define kNtDbgCommandException 0x40010009 +#define kNtDbgPrintexceptionWideC 0x4001000A +#define kNtDbgExceptionNotHandled 0x80010001 +#define kNtStillActive kNtStatusPending + +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +typedef uint32_t NtStatus; + +forceinline int NtSeverity(NtStatus s) { return (unsigned)s >> 30; } +forceinline bool32 NtSuccess(NtStatus s) { return NtSeverity(s) == 0; } +forceinline bool32 NtInformation(NtStatus s) { return NtSeverity(s) == 1; } +forceinline bool32 NtWarning(NtStatus s) { return NtSeverity(s) == 2; } +forceinline bool32 NtError(NtStatus s) { return NtSeverity(s) == 3; } +forceinline int NtCode(NtStatus s) { return s & 0xffff; } +forceinline int NtFacility(NtStatus s) { return (s >> 16) & 0xfff; } +forceinline int NtFacilityCode(NtStatus s) { return s & 0x0FFFFFFF; } + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STATUS_H_ */ diff --git a/libc/nt/enum/systeminformationclass.h b/libc/nt/enum/systeminformationclass.h new file mode 100644 index 00000000..eab431b1 --- /dev/null +++ b/libc/nt/enum/systeminformationclass.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_SYSTEMINFORMATIONCLASS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_SYSTEMINFORMATIONCLASS_H_ + +#define kNtSystemBasicInformation 0 +#define kNtSystemProcessorInformation 1 +#define kNtSystemPerformanceInformation 2 +#define kNtSystemTimeOfDayInformation 3 +#define kNtSystemProcessInformation 5 +#define kNtSystemProcessorTimes 8 +#define kNtSystemGlobalFlag 9 +#define kNtSystemModuleInformation 11 +#define kNtSystemLockInformation 12 +#define kNtSystemHandleInformation 16 +#define kNtSystemObjectInformation 17 +#define kNtSystemInterruptInformation 23 +#define kNtSystemExceptionInformation 33 +#define kNtSystemRegistryQuotaInformation 37 +#define kNtSystemLookasideInformation 45 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_SYSTEMINFORMATIONCLASS_H_ */ diff --git a/libc/nt/enum/threadaccess.h b/libc/nt/enum/threadaccess.h new file mode 100644 index 00000000..1e7694be --- /dev/null +++ b/libc/nt/enum/threadaccess.h @@ -0,0 +1,21 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_THREADACCESS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_THREADACCESS_H_ +#include "libc/nt/enum/accessmask.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define kNtThreadTerminate 0x0001 +#define kNtThreadSuspendResume 0x0002 +#define kNtThreadGetContext 0x0008 +#define kNtThreadSetContext 0x0010 +#define kNtThreadQueryInformation 0x0040 +#define kNtThreadSetInformation 0x0020 +#define kNtThreadSetThreadToken 0x0080 +#define kNtThreadImpersonate 0x0100 +#define kNtThreadDirectImpersonation 0x0200 +#define kNtThreadSetLimitedInformation 0x0400 +#define kNtThreadQueryLimitedInformation 0x0800 +#define kNtThreadResume 0x1000 +#define kNtThreadAllAccess (kNtStandardRightsRequired | kNtSynchronize | 0xFFFF) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_THREADACCESS_H_ */ diff --git a/libc/nt/enum/threadinfoclass.h b/libc/nt/enum/threadinfoclass.h new file mode 100644 index 00000000..30b320b4 --- /dev/null +++ b/libc/nt/enum/threadinfoclass.h @@ -0,0 +1,28 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_THREADINFOCLASS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_THREADINFOCLASS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtThreadInfoClass { + kNtThreadBasicInformation, + kNtThreadTimes, + kNtThreadPriority, + kNtThreadBasePriority, + kNtThreadAffinityMask, + kNtThreadImpersonationToken, + kNtThreadDescriptorTableEntry, + kNtThreadEnableAlignmentFaultFixup, + kNtThreadEventPair_Reusable, + kNtThreadQuerySetWin32StartAddress, + kNtThreadZeroTlsCell, + kNtThreadPerformanceCount, + kNtThreadAmILastThread, + kNtThreadIdealProcessor, + kNtThreadPriorityBoost, + kNtThreadSetTlsArrayAddress, + kNtThreadIsIoPending, + kNtThreadHideFromDebugger, + kNtThreadInfoClass_MAX +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_THREADINFOCLASS_H_ */ diff --git a/libc/nt/enum/threadpriority.h b/libc/nt/enum/threadpriority.h new file mode 100644 index 00000000..97e92ab4 --- /dev/null +++ b/libc/nt/enum/threadpriority.h @@ -0,0 +1,17 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_THREADPRIORITY_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_THREADPRIORITY_H_ + +#define kNtThreadBasePriorityIdle (-15) +#define kNtThreadBasePriorityMin (-2) +#define kNtThreadBasePriorityMax 2 +#define kNtThreadBasePriorityLowrt 15 + +#define kNtThreadPriorityIdle kNtThreadBasePriorityIdle +#define kNtThreadPriorityLowest kNtThreadBasePriorityMin +#define kNtThreadPriorityBelowNormal (kNtThreadPriorityLowest + 1) +#define kNtThreadPriorityNormal 0 +#define kNtThreadPriorityAboveNormal (kNtThreadPriorityHighest - 1) +#define kNtThreadPriorityHighest kNtThreadBasePriorityMax +#define kNtThreadPriorityTimeCritical kNtThreadBasePriorityLowrt + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_THREADPRIORITY_H_ */ diff --git a/libc/nt/enum/threadstate.h b/libc/nt/enum/threadstate.h new file mode 100644 index 00000000..f257c91e --- /dev/null +++ b/libc/nt/enum/threadstate.h @@ -0,0 +1,19 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_THREADSTATE_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_THREADSTATE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +enum NtThreadState { + kNtStateInitialized = 0, + kNtStateReady, + kNtStateRunning, + kNtStateStandby, + kNtStateTerminated, + kNtStateWait, + kNtStateTransition, + kNtStateUnknown +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_THREADSTATE_H_ */ diff --git a/libc/nt/enum/tokeninformationclass.h b/libc/nt/enum/tokeninformationclass.h new file mode 100644 index 00000000..b2e181ee --- /dev/null +++ b/libc/nt/enum/tokeninformationclass.h @@ -0,0 +1,23 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_TOKENINFORMATIONCLASS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_TOKENINFORMATIONCLASS_H_ + +#define kNtTokenUser 1 +#define kNtTokenGroups 2 +#define kNtTokenPrivileges 3 +#define kNtTokenOwner 4 +#define kNtTokenPrimaryGroup 5 +#define kNtTokenDefaultDacl 6 +#define kNtTokenSource 7 +#define kNtTokenType 8 +#define kNtTokenImpersonationLevel 9 +#define kNtTokenStatistics 10 +#define kNtTokenRestrictedSids 11 +#define kNtTokenSessionId 12 +#define kNtTokenGroupsAndPrivileges 13 +#define kNtTokenSessionReference 14 +#define kNtTokenSandBoxInert 15 +#define kNtTokenAuditPolicy 16 +#define kNtTokenOrigin 17 +#define kNtTokenInfoClass_MAX 18 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_TOKENINFORMATIONCLASS_H_ */ diff --git a/libc/nt/enum/tokentype.h b/libc/nt/enum/tokentype.h new file mode 100644 index 00000000..b202cb7c --- /dev/null +++ b/libc/nt/enum/tokentype.h @@ -0,0 +1,8 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_TOKENTYPE_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_TOKENTYPE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtTokenType { kNtTokenPrimary = 1, kNtTokenImpersonation }; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_TOKENTYPE_H_ */ diff --git a/libc/nt/enum/valueinformationclass.h b/libc/nt/enum/valueinformationclass.h new file mode 100644 index 00000000..7223c786 --- /dev/null +++ b/libc/nt/enum/valueinformationclass.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_VALUEINFORMATIONCLASS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_VALUEINFORMATIONCLASS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +enum NtKeyValueInformationClass { + kNtKeyValueBasicInformation, + kNtKeyValueFullInformation, + kNtKeyValuePartialInformation, + kNtKeyValueFullInformationAlign64, + kNtKeyValuePartialInformationAlign64 +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_VALUEINFORMATIONCLASS_H_ */ diff --git a/libc/nt/enum/version.h b/libc/nt/enum/version.h new file mode 100644 index 00000000..c6f67f1f --- /dev/null +++ b/libc/nt/enum/version.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_VERSION_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_VERSION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * Known versions of the New Technology executive. + * @see NtGetVersion() + */ +#define kNtVersionWindows10 0x0a00 +#define kNtVersionWindows81 0x0603 +#define kNtVersionWindows8 0x0602 +#define kNtVersionWindows7 0x0601 +#define kNtVersionWindowsVista 0x0600 /* intended baseline */ +#define kNtVersionWindowsXp64 0x0502 /* end of the road */ +#define kNtVersionWindowsXp 0x0501 /* snowball's chance */ +#define kNtVersionWindows2000 0x0500 /* the golden age */ +#define kNtVersionFuture 0x0b00 + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_VERSION_H_ */ diff --git a/libc/nt/errors.h b/libc/nt/errors.h new file mode 100644 index 00000000..e0a21267 --- /dev/null +++ b/libc/nt/errors.h @@ -0,0 +1,2672 @@ +#ifndef COSMOPOLITAN_NT_ERRORS_H_ +#define COSMOPOLITAN_NT_ERRORS_H_ + +#define kNtErrorInsufficientBuffer 122 + +#define kNtErrorSuccess 0 +#define kNtErrorInvalidFunction 1 /* ENOSYS */ +#define kNtErrorFileNotFound 2 /* ENOENT */ +#define kNtErrorPathNotFound 3 /* ENOTDIR */ +#define kNtErrorTooManyOpenFiles 4 /* EMFILE */ +#define kNtErrorAccessDenied 5 /* EACCES */ +#define kNtErrorInvalidHandle 6 /* EBADF */ +#define kNtErrorArenaTrashed 7 +#define kNtErrorNotEnoughMemory 8 +#define kNtErrorInvalidBlock 9 +#define kNtErrorBadEnvironment 10 +#define kNtErrorBadFormat 11 +#define kNtErrorInvalidAccess 12 /* EPERM */ +#define kNtErrorInvalidData 13 +#define kNtErrorOutofmemory 14 /* ENOMEM */ +#define kNtErrorInvalidDrive 15 +#define kNtErrorCurrentDirectory 16 +#define kNtErrorNotSameDevice 17 +#define kNtErrorNoMoreFiles 18 +#define kNtErrorWriteProtect 19 +#define kNtErrorBadUnit 20 +#define kNtErrorNotReady 21 +#define kNtErrorBadCommand 22 +#define kNtErrorCrc 23 +#define kNtErrorBadLength 24 +#define kNtErrorSeek 25 /* ESPIPE */ +#define kNtErrorNotDosDisk 26 /* ENOTBLK */ +#define kNtErrorSectorNotFound 27 +#define kNtErrorOutOfPaper 28 +#define kNtErrorWriteFault 29 +#define kNtErrorReadFault 30 +#define kNtErrorGenFailure 31 +#define kNtErrorSharingViolation 32 +#define kNtErrorLockViolation 33 +#define kNtErrorWrongDisk 34 +#define kNtErrorSharingBufferExceeded 36 +#define kNtErrorHandleEof 38 /* w/ GetOverlappedResult() */ +#define kNtErrorHandleDiskFull 39 +#define kNtErrorNotSupported 50 +#define kNtErrorRemNotList 51 +#define kNtErrorDupName 52 +#define kNtErrorBadNetpath 53 +#define kNtErrorNetworkBusy 54 +#define kNtErrorDevNotExist 55 +#define kNtErrorTooManyCmds 56 +#define kNtErrorAdapHdwErr 57 +#define kNtErrorBadNetResp 58 +#define kNtErrorUnexpNetErr 59 +#define kNtErrorBadRemAdap 60 +#define kNtErrorPrintqFull 61 +#define kNtErrorNoSpoolSpace 62 +#define kNtErrorPrintCancelled 63 +#define kNtErrorNetnameDeleted 64 +#define kNtErrorNetworkAccessDenied 65 +#define kNtErrorBadDevType 66 +#define kNtErrorBadNetName 67 +#define kNtErrorTooManyNames 68 +#define kNtErrorTooManySess 69 +#define kNtErrorSharingPaused 70 +#define kNtErrorReqNotAccep 71 +#define kNtErrorRedirPaused 72 +#define kNtErrorFileExists 80 /* EEXIST */ +#define kNtErrorCannotMake 82 +#define kNtErrorFailI24 83 +#define kNtErrorOutOfStructures 84 +#define kNtErrorAlreadyAssigned 85 +#define kNtErrorInvalidPassword 86 +#define kNtErrorInvalidParameter 87 /* EINVAL */ +#define kNtErrorNetWriteFault 88 +#define kNtErrorNoProcSlots 89 +#define kNtErrorTooManySemaphores 100 +#define kNtErrorExclSemAlreadyOwned 101 +#define kNtErrorSemIsSet 102 +#define kNtErrorTooManySemRequests 103 +#define kNtErrorInvalidAtInterruptTime 104 +#define kNtErrorSemOwnerDied 105 +#define kNtErrorSemUserLimit 106 +#define kNtErrorDiskChange 107 +#define kNtErrorDriveLocked 108 +#define kNtErrorBrokenPipe 109 /* EPIPE; happens on ReadFile() too */ +#define kNtErrorOpenFailed 110 +#define kNtErrorBufferOverflow 111 +#define kNtErrorDiskFull 112 /* ENOSPC */ +#define kNtErrorNoMoreSearchHandles 113 +#define kNtErrorInvalidTargetHandle 114 +#define kNtErrorInvalidCategory 117 +#define kNtErrorInvalidVerifySwitch 118 +#define kNtErrorBadDriverLevel 119 +#define kNtErrorCallNotImplemented 120 +#define kNtErrorSemTimeout 121 +#define kNtErrorInsufficientBuffer 122 +#define kNtErrorInvalidName 123 +#define kNtErrorInvalidLevel 124 +#define kNtErrorNoVolumeLabel 125 +#define kNtErrorModNotFound 126 +#define kNtErrorProcNotFound 127 +#define kNtErrorWaitNoChildren 128 /* ECHILD */ +#define kNtErrorChildNotComplete 129 +#define kNtErrorDirectAccessHandle 130 +#define kNtErrorNegativeSeek 131 +#define kNtErrorSeekOnDevice 132 +#define kNtErrorIsJoinTarget 133 +#define kNtErrorIsJoined 134 +#define kNtErrorIsSubsted 135 +#define kNtErrorNotJoined 136 +#define kNtErrorNotSubsted 137 +#define kNtErrorJoinToJoin 138 +#define kNtErrorSubstToSubst 139 +#define kNtErrorJoinToSubst 140 +#define kNtErrorSubstToJoin 141 +#define kNtErrorBusyDrive 142 +#define kNtErrorSameDrive 143 +#define kNtErrorDirNotRoot 144 +#define kNtErrorDirNotEmpty 145 +#define kNtErrorIsSubstPath 146 +#define kNtErrorIsJoinPath 147 +#define kNtErrorPathBusy 148 /* ETXTBSY */ +#define kNtErrorIsSubstTarget 149 +#define kNtErrorSystemTrace 150 +#define kNtErrorInvalidEventCount 151 +#define kNtErrorTooManyMuxwaiters 152 +#define kNtErrorInvalidListFormat 153 +#define kNtErrorLabelTooLong 154 +#define kNtErrorTooManyTcbs 155 +#define kNtErrorSignalRefused 156 +#define kNtErrorDiscarded 157 +#define kNtErrorNotLocked 158 +#define kNtErrorBadThreadidAddr 159 +#define kNtErrorBadArguments 160 +#define kNtErrorBadPathname 161 +#define kNtErrorSignalPending 162 +#define kNtErrorMaxThrdsReached 164 +#define kNtErrorLockFailed 167 +#define kNtErrorBusy 170 /* EBUSY */ +#define kNtErrorDeviceSupportInProgress 171 +#define kNtErrorCancelViolation 173 +#define kNtErrorAtomicLocksNotSupported 174 +#define kNtErrorInvalidSegmentNumber 180 +#define kNtErrorInvalidOrdinal 182 +#define kNtErrorAlreadyExists 183 /* EEXIST */ +#define kNtErrorInvalidFlagNumber 186 +#define kNtErrorSemNotFound 187 +#define kNtErrorInvalidStartingCodeseg 188 +#define kNtErrorInvalidStackseg 189 +#define kNtErrorInvalidModuletype 190 +#define kNtErrorInvalidExeSignature 191 +#define kNtErrorExeMarkedInvalid 192 +#define kNtErrorBadExeFormat 193 /* ENOEXEC */ +#define kNtErrorIteratedDataExceeds_64k 194 +#define kNtErrorInvalidMinallocsize 195 +#define kNtErrorDynlinkFromInvalidRing 196 +#define kNtErrorIoplNotEnabled 197 +#define kNtErrorInvalidSegdpl 198 +#define kNtErrorAutodatasegExceeds_64k 199 +#define kNtErrorRing2segMustBeMovable 200 +#define kNtErrorRelocChainXeedsSeglim 201 +#define kNtErrorInfloopInRelocChain 202 +#define kNtErrorEnvvarNotFound 203 +#define kNtErrorNoSignalSent 205 +#define kNtErrorFilenameExcedRange 206 +#define kNtErrorRing2StackInUse 207 +#define kNtErrorMetaExpansionTooLong 208 +#define kNtErrorInvalidSignalNumber 209 +#define kNtErrorThread_1Inactive 210 +#define kNtErrorLocked 212 +#define kNtErrorTooManyModules 214 +#define kNtErrorNestingNotAllowed 215 +#define kNtErrorExeMachineTypeMismatch 216 +#define kNtErrorExeCannotModifySignedBinary 217 +#define kNtErrorExeCannotModifyStrongSignedBinary 218 +#define kNtErrorFileCheckedOut 220 +#define kNtErrorCheckoutRequired 221 +#define kNtErrorBadFileType 222 +#define kNtErrorFileTooLarge 223 /* EFBIG */ +#define kNtErrorFormsAuthRequired 224 +#define kNtErrorVirusInfected 225 +#define kNtErrorVirusDeleted 226 +#define kNtErrorPipeLocal 229 +#define kNtErrorBadPipe 230 +#define kNtErrorPipeBusy 231 +#define kNtErrorNoData 232 +#define kNtErrorPipeNotConnected 233 +#define kNtErrorMoreData 234 +#define kNtErrorNoWorkDone 235 +#define kNtErrorVcDisconnected 240 +#define kNtErrorInvalidEaName 254 +#define kNtErrorEaListInconsistent 255 +#define kNtErrorNoMoreItems 259 +#define kNtErrorCannotCopy 266 +#define kNtErrorDirectory 267 +#define kNtErrorEasDidntFit 275 +#define kNtErrorEaFileCorrupt 276 +#define kNtErrorEaTableFull 277 +#define kNtErrorInvalidEaHandle 278 +#define kNtErrorEasNotSupported 282 +#define kNtErrorNotOwner 288 +#define kNtErrorTooManyPosts 298 +#define kNtErrorPartialCopy 299 +#define kNtErrorOplockNotGranted 300 +#define kNtErrorInvalidOplockProtocol 301 +#define kNtErrorDiskTooFragmented 302 +#define kNtErrorDeletePending 303 +#define kNtErrorIncompatibleWithGlobalShortNameRegistrySetting 304 +#define kNtErrorShortNamesNotEnabledOnVolume 305 +#define kNtErrorSecurityStreamIsInconsistent 306 +#define kNtErrorInvalidLockRange 307 +#define kNtErrorImageSubsystemNotPresent 308 +#define kNtErrorNotificationGuidAlreadyDefined 309 +#define kNtErrorInvalidExceptionHandler 310 +#define kNtErrorDuplicatePrivileges 311 +#define kNtErrorNoRangesProcessed 312 +#define kNtErrorNotAllowedOnSystemFile 313 +#define kNtErrorDiskResourcesExhausted 314 +#define kNtErrorInvalidToken 315 +#define kNtErrorDeviceFeatureNotSupported 316 +#define kNtErrorMrMidNotFound 317 +#define kNtErrorScopeNotFound 318 +#define kNtErrorUndefinedScope 319 +#define kNtErrorInvalidCap 320 +#define kNtErrorDeviceUnreachable 321 +#define kNtErrorDeviceNoResources 322 +#define kNtErrorDataChecksumError 323 +#define kNtErrorIntermixedKernelEaOperation 324 +#define kNtErrorFileLevelTrimNotSupported 326 +#define kNtErrorOffsetAlignmentViolation 327 +#define kNtErrorInvalidFieldInParameterList 328 +#define kNtErrorOperationInProgress 329 +#define kNtErrorBadDevicePath 330 +#define kNtErrorTooManyDescriptors 331 /* ENFILE */ +#define kNtErrorScrubDataDisabled 332 +#define kNtErrorNotRedundantStorage 333 +#define kNtErrorResidentFileNotSupported 334 +#define kNtErrorCompressedFileNotSupported 335 +#define kNtErrorDirectoryNotSupported 336 /* EISDIR */ +#define kNtErrorNotReadFromCopy 337 +#define kNtErrorFtWriteFailure 338 +#define kNtErrorFtDiScanRequired 339 +#define kNtErrorInvalidKernelInfoVersion 340 +#define kNtErrorInvalidPepInfoVersion 341 +#define kNtErrorObjectNotExternallyBacked 342 +#define kNtErrorExternalBackingProviderUnknown 343 +#define kNtErrorCompressionNotBeneficial 344 +#define kNtErrorStorageTopologyIdMismatch 345 +#define kNtErrorBlockedByParentalControls 346 +#define kNtErrorBlockTooManyReferences 347 +#define kNtErrorMarkedToDisallowWrites 348 +#define kNtErrorEnclaveFailure 349 +#define kNtErrorFailNoactionReboot 350 +#define kNtErrorFailShutdown 351 +#define kNtErrorFailRestart 352 +#define kNtErrorMaxSessionsReached 353 +#define kNtErrorNetworkAccessDeniedEdp 354 +#define kNtErrorDeviceHintNameBufferTooSmall 355 +#define kNtErrorEdpPolicyDeniesOperation 356 +#define kNtErrorEdpDplPolicyCantBeSatisfied 357 +#define kNtErrorCloudFileSyncRootMetadataCorrupt 358 +#define kNtErrorDeviceInMaintenance 359 +#define kNtErrorNotSupportedOnDax 360 +#define kNtErrorDaxMappingExists 361 +#define kNtErrorCloudFileProviderNotRunning 362 +#define kNtErrorCloudFileMetadataCorrupt 363 +#define kNtErrorCloudFileMetadataTooLarge 364 +#define kNtErrorCloudFilePropertyBlobTooLarge 365 +#define kNtErrorCloudFilePropertyBlobChecksumMismatch 366 +#define kNtErrorChildProcessBlocked 367 +#define kNtErrorStorageLostDataPersistence 368 +#define kNtErrorFileSystemVirtualizationUnavailable 369 +#define kNtErrorFileSystemVirtualizationMetadataCorrupt 370 +#define kNtErrorFileSystemVirtualizationBusy 371 +#define kNtErrorFileSystemVirtualizationProviderUnknown 372 +#define kNtErrorGdiHandleLeak 373 +#define kNtErrorCloudFileTooManyPropertyBlobs 374 +#define kNtErrorCloudFilePropertyVersionNotSupported 375 +#define kNtErrorNotACloudFile 376 +#define kNtErrorCloudFileNotInSync 377 +#define kNtErrorCloudFileAlreadyConnected 378 +#define kNtErrorCloudFileNotSupported 379 +#define kNtErrorCloudFileInvalidRequest 380 +#define kNtErrorCloudFileReadOnlyVolume 381 +#define kNtErrorCloudFileConnectedProviderOnly 382 +#define kNtErrorCloudFileValidationFailed 383 +#define kNtErrorSmb1NotAvailable 384 +#define kNtErrorFileSystemVirtualizationInvalidOperation 385 +#define kNtErrorCloudFileAuthenticationFailed 386 +#define kNtErrorCloudFileInsufficientResources 387 +#define kNtErrorCloudFileNetworkUnavailable 388 +#define kNtErrorCloudFileUnsuccessful 389 +#define kNtErrorCloudFileNotUnderSyncRoot 390 +#define kNtErrorCloudFileInUse 391 +#define kNtErrorCloudFilePinned 392 +#define kNtErrorCloudFileRequestAborted 393 +#define kNtErrorCloudFilePropertyCorrupt 394 +#define kNtErrorCloudFileAccessDenied 395 +#define kNtErrorCloudFileIncompatibleHardlinks 396 +#define kNtErrorCloudFilePropertyLockConflict 397 +#define kNtErrorCloudFileRequestCanceled 398 +#define kNtErrorExternalSyskeyNotSupported 399 +#define kNtErrorThreadModeAlreadyBackground 400 +#define kNtErrorThreadModeNotBackground 401 +#define kNtErrorProcessModeAlreadyBackground 402 +#define kNtErrorProcessModeNotBackground 403 +#define kNtErrorCloudFileProviderTerminated 404 +#define kNtErrorNotACloudSyncRoot 405 +#define kNtErrorFileProtectedUnderDpl 406 +#define kNtErrorVolumeNotClusterAligned 407 +#define kNtErrorNoPhysicallyAlignedFreeSpaceFound 408 +#define kNtErrorAppxFileNotEncrypted 409 +#define kNtErrorRwrawEncryptedFileNotEncrypted 410 +#define kNtErrorRwrawEncryptedInvalidEdatainfoFileoffset 411 +#define kNtErrorRwrawEncryptedInvalidEdatainfoFilerange 412 +#define kNtErrorRwrawEncryptedInvalidEdatainfoParameter 413 +#define kNtErrorLinuxSubsystemNotPresent 414 +#define kNtErrorCapauthzNotDevunlocked 450 +#define kNtErrorCapauthzChangeType 451 +#define kNtErrorCapauthzNotProvisioned 452 +#define kNtErrorCapauthzNotAuthorized 453 +#define kNtErrorCapauthzNoPolicy 454 +#define kNtErrorCapauthzDbCorrupted 455 +#define kNtErrorCapauthzSccdInvalidCatalog 456 +#define kNtErrorCapauthzSccdNoAuthEntity 457 +#define kNtErrorCapauthzSccdParseError 458 +#define kNtErrorCapauthzSccdDevModeRequired 459 +#define kNtErrorCapauthzSccdNoCapabilityMatch 460 +#define kNtErrorPnpQueryRemoveDeviceTimeout 480 +#define kNtErrorPnpQueryRemoveRelatedDeviceTimeout 481 +#define kNtErrorPnpQueryRemoveUnrelatedDeviceTimeout 482 +#define kNtErrorDeviceHardwareError 483 +#define kNtErrorInvalidAddress 487 /* EFAULT */ +#define kNtErrorVrfCfgEnabled 1183 +#define kNtErrorPartitionTerminating 1184 +#define kNtErrorUserProfileLoad 500 +#define kNtErrorArithmeticOverflow 534 +#define kNtErrorPipeConnected 535 +#define kNtErrorPipeListening 536 +#define kNtErrorVerifierStop 537 +#define kNtErrorAbiosError 538 +#define kNtErrorWx86Warning 539 +#define kNtErrorWx86Error 540 +#define kNtErrorTimerNotCanceled 541 +#define kNtErrorUnwind 542 +#define kNtErrorBadStack 543 +#define kNtErrorInvalidUnwindTarget 544 +#define kNtErrorInvalidPortAttributes 545 +#define kNtErrorPortMessageTooLong 546 +#define kNtErrorInvalidQuotaLower 547 +#define kNtErrorDeviceAlreadyAttached 548 +#define kNtErrorInstructionMisalignment 549 +#define kNtErrorProfilingNotStarted 550 +#define kNtErrorProfilingNotStopped 551 +#define kNtErrorCouldNotInterpret 552 +#define kNtErrorProfilingAtLimit 553 +#define kNtErrorCantWait 554 +#define kNtErrorCantTerminateSelf 555 +#define kNtErrorUnexpectedMmCreateErr 556 +#define kNtErrorUnexpectedMmMapError 557 +#define kNtErrorUnexpectedMmExtendErr 558 +#define kNtErrorBadFunctionTable 559 +#define kNtErrorNoGuidTranslation 560 +#define kNtErrorInvalidLdtSize 561 +#define kNtErrorInvalidLdtOffset 563 +#define kNtErrorInvalidLdtDescriptor 564 +#define kNtErrorTooManyThreads 565 +#define kNtErrorThreadNotInProcess 566 /* ESRCH */ +#define kNtErrorPagefileQuotaExceeded 567 +#define kNtErrorLogonServerConflict 568 +#define kNtErrorSynchronizationRequired 569 +#define kNtErrorNetOpenFailed 570 +#define kNtErrorIoPrivilegeFailed 571 +#define kNtErrorControlCExit 572 +#define kNtErrorMissingSystemfile 573 +#define kNtErrorUnhandledException 574 +#define kNtErrorAppInitFailure 575 +#define kNtErrorPagefileCreateFailed 576 +#define kNtErrorInvalidImageHash 577 +#define kNtErrorNoPagefile 578 +#define kNtErrorIllegalFloatContext 579 +#define kNtErrorNoEventPair 580 +#define kNtErrorDomainCtrlrConfigError 581 +#define kNtErrorIllegalCharacter 582 +#define kNtErrorUndefinedCharacter 583 +#define kNtErrorFloppyVolume 584 +#define kNtErrorBiosFailedToConnectInterrupt 585 +#define kNtErrorBackupController 586 +#define kNtErrorMutantLimitExceeded 587 +#define kNtErrorFsDriverRequired 588 +#define kNtErrorCannotLoadRegistryFile 589 +#define kNtErrorDebugAttachFailed 590 +#define kNtErrorSystemProcessTerminated 591 +#define kNtErrorDataNotAccepted 592 +#define kNtErrorVdmHardError 593 +#define kNtErrorDriverCancelTimeout 594 +#define kNtErrorReplyMessageMismatch 595 +#define kNtErrorLostWritebehindData 596 +#define kNtErrorClientServerParametersInvalid 597 +#define kNtErrorNotTinyStream 598 +#define kNtErrorStackOverflowRead 599 +#define kNtErrorConvertToLarge 600 +#define kNtErrorFoundOutOfScope 601 +#define kNtErrorAllocateBucket 602 +#define kNtErrorMarshallOverflow 603 +#define kNtErrorInvalidVariant 604 +#define kNtErrorBadCompressionBuffer 605 +#define kNtErrorAuditFailed 606 +#define kNtErrorTimerResolutionNotSet 607 +#define kNtErrorInsufficientLogonInfo 608 +#define kNtErrorBadDllEntrypoint 609 +#define kNtErrorBadServiceEntrypoint 610 +#define kNtErrorIpAddressConflict1 611 +#define kNtErrorIpAddressConflict2 612 +#define kNtErrorRegistryQuotaLimit 613 +#define kNtErrorNoCallbackActive 614 +#define kNtErrorPwdTooShort 615 +#define kNtErrorPwdTooRecent 616 +#define kNtErrorPwdHistoryConflict 617 +#define kNtErrorUnsupportedCompression 618 +#define kNtErrorInvalidHwProfile 619 +#define kNtErrorInvalidPlugplayDevicePath 620 +#define kNtErrorQuotaListInconsistent 621 +#define kNtErrorEvaluationExpiration 622 +#define kNtErrorIllegalDllRelocation 623 +#define kNtErrorDllInitFailedLogoff 624 +#define kNtErrorValidateContinue 625 +#define kNtErrorNoMoreMatches 626 +#define kNtErrorRangeListConflict 627 +#define kNtErrorServerSidMismatch 628 +#define kNtErrorCantEnableDenyOnly 629 +#define kNtErrorFloatMultipleFaults 630 +#define kNtErrorFloatMultipleTraps 631 +#define kNtErrorNointerface 632 +#define kNtErrorDriverFailedSleep 633 +#define kNtErrorCorruptSystemFile 634 +#define kNtErrorCommitmentMinimum 635 +#define kNtErrorPnpRestartEnumeration 636 +#define kNtErrorSystemImageBadSignature 637 +#define kNtErrorPnpRebootRequired 638 +#define kNtErrorInsufficientPower 639 +#define kNtErrorMultipleFaultViolation 640 +#define kNtErrorSystemShutdown 641 +#define kNtErrorPortNotSet 642 +#define kNtErrorDsVersionCheckFailure 643 +#define kNtErrorRangeNotFound 644 +#define kNtErrorNotSafeModeDriver 646 +#define kNtErrorFailedDriverEntry 647 +#define kNtErrorDeviceEnumerationError 648 +#define kNtErrorMountPointNotResolved 649 +#define kNtErrorInvalidDeviceObjectParameter 650 +#define kNtErrorMcaOccured 651 +#define kNtErrorDriverDatabaseError 652 +#define kNtErrorSystemHiveTooLarge 653 +#define kNtErrorDriverFailedPriorUnload 654 +#define kNtErrorVolsnapPrepareHibernate 655 +#define kNtErrorHibernationFailure 656 +#define kNtErrorPwdTooLong 657 +#define kNtErrorFileSystemLimitation 665 +#define kNtErrorAssertionFailure 668 +#define kNtErrorAcpiError 669 +#define kNtErrorWowAssertion 670 +#define kNtErrorPnpBadMpsTable 671 +#define kNtErrorPnpTranslationFailed 672 +#define kNtErrorPnpIrqTranslationFailed 673 +#define kNtErrorPnpInvalidId 674 +#define kNtErrorWakeSystemDebugger 675 +#define kNtErrorHandlesClosed 676 +#define kNtErrorExtraneousInformation 677 +#define kNtErrorRxactCommitNecessary 678 +#define kNtErrorMediaCheck 679 +#define kNtErrorGuidSubstitutionMade 680 +#define kNtErrorStoppedOnSymlink 681 +#define kNtErrorLongjump 682 +#define kNtErrorPlugplayQueryVetoed 683 +#define kNtErrorUnwindConsolidate 684 +#define kNtErrorRegistryHiveRecovered 685 +#define kNtErrorDllMightBeInsecure 686 +#define kNtErrorDllMightBeIncompatible 687 +#define kNtErrorDbgExceptionNotHandled 688 +#define kNtErrorDbgReplyLater 689 +#define kNtErrorDbgUnableToProvideHandle 690 +#define kNtErrorDbgTerminateThread 691 +#define kNtErrorDbgTerminateProcess 692 +#define kNtErrorDbgControlC 693 +#define kNtErrorDbgPrintexceptionC 694 +#define kNtErrorDbgRipexception 695 +#define kNtErrorDbgControlBreak 696 +#define kNtErrorDbgCommandException 697 +#define kNtErrorObjectNameExists 698 +#define kNtErrorThreadWasSuspended 699 +#define kNtErrorImageNotAtBase 700 +#define kNtErrorRxactStateCreated 701 +#define kNtErrorSegmentNotification 702 +#define kNtErrorBadCurrentDirectory 703 +#define kNtErrorFtReadRecoveryFromBackup 704 +#define kNtErrorFtWriteRecovery 705 +#define kNtErrorImageMachineTypeMismatch 706 +#define kNtErrorReceivePartial 707 +#define kNtErrorReceiveExpedited 708 +#define kNtErrorReceivePartialExpedited 709 +#define kNtErrorEventDone 710 +#define kNtErrorEventPending 711 +#define kNtErrorCheckingFileSystem 712 +#define kNtErrorFatalAppExit 713 +#define kNtErrorPredefinedHandle 714 +#define kNtErrorWasUnlocked 715 +#define kNtErrorServiceNotification 716 +#define kNtErrorWasLocked 717 +#define kNtErrorLogHardError 718 +#define kNtErrorAlreadyWin32 719 +#define kNtErrorImageMachineTypeMismatchExe 720 +#define kNtErrorNoYieldPerformed 721 +#define kNtErrorTimerResumeIgnored 722 +#define kNtErrorArbitrationUnhandled 723 +#define kNtErrorCardbusNotSupported 724 +#define kNtErrorMpProcessorMismatch 725 +#define kNtErrorHibernated 726 +#define kNtErrorResumeHibernation 727 +#define kNtErrorFirmwareUpdated 728 +#define kNtErrorDriversLeakingLockedPages 729 +#define kNtErrorWakeSystem 730 +#define kNtErrorWait_1 731 +#define kNtErrorWait_2 732 +#define kNtErrorWait_3 733 +#define kNtErrorWait_63 734 +#define kNtErrorAbandonedWait_0 735 +#define kNtErrorAbandonedWait_63 736 +#define kNtErrorUserApc 737 +#define kNtErrorKernelApc 738 +#define kNtErrorAlerted 739 +#define kNtErrorElevationRequired 740 +#define kNtErrorReparse 741 +#define kNtErrorOplockBreakInProgress 742 +#define kNtErrorVolumeMounted 743 +#define kNtErrorRxactCommitted 744 +#define kNtErrorNotifyCleanup 745 +#define kNtErrorPrimaryTransportConnectFailed 746 +#define kNtErrorPageFaultTransition 747 +#define kNtErrorPageFaultDemandZero 748 +#define kNtErrorPageFaultCopyOnWrite 749 +#define kNtErrorPageFaultGuardPage 750 +#define kNtErrorPageFaultPagingFile 751 +#define kNtErrorCachePageLocked 752 +#define kNtErrorCrashDump 753 +#define kNtErrorBufferAllZeros 754 +#define kNtErrorReparseObject 755 +#define kNtErrorResourceRequirementsChanged 756 +#define kNtErrorTranslationComplete 757 +#define kNtErrorNothingToTerminate 758 +#define kNtErrorProcessNotInJob 759 +#define kNtErrorProcessInJob 760 +#define kNtErrorVolsnapHibernateReady 761 +#define kNtErrorFsfilterOpCompletedSuccessfully 762 +#define kNtErrorInterruptVectorAlreadyConnected 763 +#define kNtErrorInterruptStillConnected 764 +#define kNtErrorWaitForOplock 765 +#define kNtErrorDbgExceptionHandled 766 +#define kNtErrorDbgContinue 767 +#define kNtErrorCallbackPopStack 768 +#define kNtErrorCompressionDisabled 769 +#define kNtErrorCantfetchbackwards 770 +#define kNtErrorCantscrollbackwards 771 +#define kNtErrorRowsnotreleased 772 +#define kNtErrorBadAccessorFlags 773 +#define kNtErrorErrorsEncountered 774 +#define kNtErrorNotCapable 775 +#define kNtErrorRequestOutOfSequence 776 +#define kNtErrorVersionParseError 777 +#define kNtErrorBadstartposition 778 +#define kNtErrorMemoryHardware 779 +#define kNtErrorDiskRepairDisabled 780 +#define kNtErrorInsufficientResourceForSpecifiedSharedSectionSize 781 +#define kNtErrorSystemPowerstateTransition 782 +#define kNtErrorSystemPowerstateComplexTransition 783 +#define kNtErrorMcaException 784 +#define kNtErrorAccessAuditByPolicy 785 +#define kNtErrorAccessDisabledNoSaferUiByPolicy 786 +#define kNtErrorAbandonHiberfile 787 +#define kNtErrorLostWritebehindDataNetworkDisconnected 788 +#define kNtErrorLostWritebehindDataNetworkServerError 789 +#define kNtErrorLostWritebehindDataLocalDiskError 790 +#define kNtErrorBadMcfgTable 791 +#define kNtErrorDiskRepairRedirected 792 +#define kNtErrorDiskRepairUnsuccessful 793 +#define kNtErrorCorruptLogOverfull 794 +#define kNtErrorCorruptLogCorrupted 795 +#define kNtErrorCorruptLogUnavailable 796 +#define kNtErrorCorruptLogDeletedFull 797 +#define kNtErrorCorruptLogCleared 798 +#define kNtErrorOrphanNameExhausted 799 +#define kNtErrorOplockSwitchedToNewHandle 800 +#define kNtErrorCannotGrantRequestedOplock 801 +#define kNtErrorCannotBreakOplock 802 +#define kNtErrorOplockHandleClosed 803 +#define kNtErrorNoAceCondition 804 +#define kNtErrorInvalidAceCondition 805 +#define kNtErrorFileHandleRevoked 806 +#define kNtErrorImageAtDifferentBase 807 +#define kNtErrorEncryptedIoNotPossible 808 +#define kNtErrorFileMetadataOptimizationInProgress 809 +#define kNtErrorQuotaActivity 810 +#define kNtErrorHandleRevoked 811 +#define kNtErrorCallbackInvokeInline 812 +#define kNtErrorCpuSetInvalid 813 +#define kNtErrorEnclaveNotTerminated 814 +#define kNtErrorEnclaveViolation 815 +#define kNtErrorEaAccessDenied 994 +#define kNtErrorOperationAborted 995 +#define kNtErrorIoIncomplete 996 +#define kNtErrorIoPending 997 +#define kNtErrorNoaccess 998 +#define kNtErrorSwaperror 999 +#define kNtErrorStackOverflow 1001 +#define kNtErrorInvalidMessage 1002 +#define kNtErrorCanNotComplete 1003 +#define kNtErrorInvalidFlags 1004 +#define kNtErrorUnrecognizedVolume 1005 +#define kNtErrorFileInvalid 1006 +#define kNtErrorFullscreenMode 1007 +#define kNtErrorNoToken 1008 +#define kNtErrorBaddb 1009 +#define kNtErrorBadkey 1010 +#define kNtErrorCantopen 1011 +#define kNtErrorCantread 1012 +#define kNtErrorCantwrite 1013 +#define kNtErrorRegistryRecovered 1014 +#define kNtErrorRegistryCorrupt 1015 +#define kNtErrorRegistryIoFailed 1016 +#define kNtErrorNotRegistryFile 1017 +#define kNtErrorKeyDeleted 1018 +#define kNtErrorNoLogSpace 1019 +#define kNtErrorKeyHasChildren 1020 +#define kNtErrorChildMustBeVolatile 1021 +#define kNtErrorNotifyEnumDir 1022 +#define kNtErrorDependentServicesRunning 1051 +#define kNtErrorInvalidServiceControl 1052 +#define kNtErrorServiceRequestTimeout 1053 +#define kNtErrorServiceNoThread 1054 +#define kNtErrorServiceDatabaseLocked 1055 +#define kNtErrorServiceAlreadyRunning 1056 +#define kNtErrorInvalidServiceAccount 1057 +#define kNtErrorServiceDisabled 1058 +#define kNtErrorCircularDependency 1059 +#define kNtErrorServiceDoesNotExist 1060 +#define kNtErrorServiceCannotAcceptCtrl 1061 +#define kNtErrorServiceNotActive 1062 +#define kNtErrorFailedServiceControllerConnect 1063 +#define kNtErrorExceptionInService 1064 +#define kNtErrorDatabaseDoesNotExist 1065 +#define kNtErrorServiceSpecificError 1066 +#define kNtErrorProcessAborted 1067 +#define kNtErrorServiceDependencyFail 1068 +#define kNtErrorServiceLogonFailed 1069 +#define kNtErrorServiceStartHang 1070 +#define kNtErrorInvalidServiceLock 1071 +#define kNtErrorServiceMarkedForDelete 1072 +#define kNtErrorServiceExists 1073 +#define kNtErrorAlreadyRunningLkg 1074 +#define kNtErrorServiceDependencyDeleted 1075 +#define kNtErrorBootAlreadyAccepted 1076 +#define kNtErrorServiceNeverStarted 1077 +#define kNtErrorDuplicateServiceName 1078 +#define kNtErrorDifferentServiceAccount 1079 +#define kNtErrorCannotDetectDriverFailure 1080 +#define kNtErrorCannotDetectProcessAbort 1081 +#define kNtErrorNoRecoveryProgram 1082 +#define kNtErrorServiceNotInExe 1083 +#define kNtErrorNotSafebootService 1084 +#define kNtErrorEndOfMedia 1100 +#define kNtErrorFilemarkDetected 1101 +#define kNtErrorBeginningOfMedia 1102 +#define kNtErrorSetmarkDetected 1103 +#define kNtErrorNoDataDetected 1104 +#define kNtErrorPartitionFailure 1105 +#define kNtErrorInvalidBlockLength 1106 +#define kNtErrorDeviceNotPartitioned 1107 +#define kNtErrorUnableToLockMedia 1108 +#define kNtErrorUnableToUnloadMedia 1109 +#define kNtErrorMediaChanged 1110 +#define kNtErrorBusReset 1111 +#define kNtErrorNoMediaInDrive 1112 /* ENXIO */ +#define kNtErrorNoUnicodeTranslation 1113 +#define kNtErrorDllInitFailed 1114 +#define kNtErrorShutdownInProgress 1115 +#define kNtErrorNoShutdownInProgress 1116 +#define kNtErrorIoDevice 1117 /* EIO */ +#define kNtErrorSerialNoDevice 1118 /* ENOTTY */ +#define kNtErrorIrqBusy 1119 +#define kNtErrorMoreWrites 1120 +#define kNtErrorCounterTimeout 1121 +#define kNtErrorFloppyIdMarkNotFound 1122 +#define kNtErrorFloppyWrongCylinder 1123 +#define kNtErrorFloppyUnknownError 1124 +#define kNtErrorFloppyBadRegisters 1125 +#define kNtErrorDiskRecalibrateFailed 1126 +#define kNtErrorDiskOperationFailed 1127 +#define kNtErrorDiskResetFailed 1128 +#define kNtErrorEomOverflow 1129 +#define kNtErrorNotEnoughServerMemory 1130 +#define kNtErrorPossibleDeadlock 1131 /* EDEADLK */ +#define kNtErrorMappedAlignment 1132 +#define kNtErrorSetPowerStateVetoed 1140 +#define kNtErrorSetPowerStateFailed 1141 +#define kNtErrorTooManyLinks 1142 +#define kNtErrorOldWinVersion 1150 +#define kNtErrorAppWrongOs 1151 +#define kNtErrorSingleInstanceApp 1152 +#define kNtErrorRmodeApp 1153 +#define kNtErrorInvalidDll 1154 +#define kNtErrorNoAssociation 1155 +#define kNtErrorDdeFail 1156 +#define kNtErrorDllNotFound 1157 +#define kNtErrorNoMoreUserHandles 1158 +#define kNtErrorMessageSyncOnly 1159 +#define kNtErrorSourceElementEmpty 1160 +#define kNtErrorDestinationElementFull 1161 +#define kNtErrorIllegalElementAddress 1162 +#define kNtErrorMagazineNotPresent 1163 +#define kNtErrorDeviceReinitializationNeeded 1164 +#define kNtErrorDeviceRequiresCleaning 1165 +#define kNtErrorDeviceDoorOpen 1166 +#define kNtErrorDeviceNotConnected 1167 +#define kNtErrorNotFound 1168 +#define kNtErrorNoMatch 1169 +#define kNtErrorSetNotFound 1170 +#define kNtErrorPointNotFound 1171 +#define kNtErrorNoTrackingService 1172 +#define kNtErrorNoVolumeId 1173 +#define kNtErrorUnableToRemoveReplaced 1175 +#define kNtErrorUnableToMoveReplacement 1176 +#define kNtErrorUnableToMoveReplacement_2 1177 +#define kNtErrorJournalDeleteInProgress 1178 +#define kNtErrorJournalNotActive 1179 +#define kNtErrorPotentialFileFound 1180 +#define kNtErrorJournalEntryDeleted 1181 +#define kNtErrorShutdownIsScheduled 1190 +#define kNtErrorShutdownUsersLoggedOn 1191 +#define kNtErrorBadDevice 1200 /* ENODEV */ +#define kNtErrorConnectionUnavail 1201 +#define kNtErrorDeviceAlreadyRemembered 1202 +#define kNtErrorNoNetOrBadPath 1203 +#define kNtErrorBadProvider 1204 +#define kNtErrorCannotOpenProfile 1205 +#define kNtErrorBadProfile 1206 +#define kNtErrorNotContainer 1207 +#define kNtErrorExtendedError 1208 +#define kNtErrorInvalidGroupname 1209 +#define kNtErrorInvalidComputername 1210 +#define kNtErrorInvalidEventname 1211 +#define kNtErrorInvalidDomainname 1212 +#define kNtErrorInvalidServicename 1213 +#define kNtErrorInvalidNetname 1214 +#define kNtErrorInvalidSharename 1215 +#define kNtErrorInvalidPasswordname 1216 +#define kNtErrorInvalidMessagename 1217 +#define kNtErrorInvalidMessagedest 1218 +#define kNtErrorSessionCredentialConflict 1219 +#define kNtErrorRemoteSessionLimitExceeded 1220 +#define kNtErrorDupDomainname 1221 +#define kNtErrorNoNetwork 1222 +#define kNtErrorCancelled 1223 +#define kNtErrorUserMappedFile 1224 +#define kNtErrorConnectionRefused 1225 +#define kNtErrorGracefulDisconnect 1226 +#define kNtErrorAddressAlreadyAssociated 1227 +#define kNtErrorAddressNotAssociated 1228 +#define kNtErrorConnectionInvalid 1229 +#define kNtErrorConnectionActive 1230 +#define kNtErrorNetworkUnreachable 1231 +#define kNtErrorHostUnreachable 1232 +#define kNtErrorProtocolUnreachable 1233 +#define kNtErrorPortUnreachable 1234 +#define kNtErrorRequestAborted 1235 +#define kNtErrorConnectionAborted 1236 +#define kNtErrorRetry 1237 +#define kNtErrorConnectionCountLimit 1238 +#define kNtErrorLoginTimeRestriction 1239 +#define kNtErrorLoginWkstaRestriction 1240 +#define kNtErrorIncorrectAddress 1241 +#define kNtErrorAlreadyRegistered 1242 +#define kNtErrorServiceNotFound 1243 +#define kNtErrorNotAuthenticated 1244 +#define kNtErrorNotLoggedOn 1245 +#define kNtErrorContinue 1246 +#define kNtErrorAlreadyInitialized 1247 +#define kNtErrorNoMoreDevices 1248 +#define kNtErrorNoSuchSite 1249 +#define kNtErrorDomainControllerExists 1250 +#define kNtErrorOnlyIfConnected 1251 +#define kNtErrorOverrideNochanges 1252 +#define kNtErrorBadUserProfile 1253 +#define kNtErrorNotSupportedOnSbs 1254 +#define kNtErrorServerShutdownInProgress 1255 +#define kNtErrorHostDown 1256 +#define kNtErrorNonAccountSid 1257 +#define kNtErrorNonDomainSid 1258 +#define kNtErrorApphelpBlock 1259 +#define kNtErrorAccessDisabledByPolicy 1260 +#define kNtErrorRegNatConsumption 1261 +#define kNtErrorCscshareOffline 1262 +#define kNtErrorPkinitFailure 1263 +#define kNtErrorSmartcardSubsystemFailure 1264 +#define kNtErrorDowngradeDetected 1265 +#define kNtErrorMachineLocked 1271 +#define kNtErrorSmbGuestLogonBlocked 1272 +#define kNtErrorCallbackSuppliedInvalidData 1273 +#define kNtErrorSyncForegroundRefreshRequired 1274 +#define kNtErrorDriverBlocked 1275 +#define kNtErrorInvalidImportOfNonDll 1276 +#define kNtErrorAccessDisabledWebblade 1277 +#define kNtErrorAccessDisabledWebbladeTamper 1278 +#define kNtErrorRecoveryFailure 1279 +#define kNtErrorAlreadyFiber 1280 +#define kNtErrorAlreadyThread 1281 +#define kNtErrorStackBufferOverrun 1282 +#define kNtErrorParameterQuotaExceeded 1283 +#define kNtErrorDebuggerInactive 1284 +#define kNtErrorDelayLoadFailed 1285 +#define kNtErrorVdmDisallowed 1286 +#define kNtErrorUnidentifiedError 1287 +#define kNtErrorInvalidCruntimeParameter 1288 +#define kNtErrorBeyondVdl 1289 +#define kNtErrorIncompatibleServiceSidType 1290 +#define kNtErrorDriverProcessTerminated 1291 +#define kNtErrorImplementationLimit 1292 +#define kNtErrorProcessIsProtected 1293 +#define kNtErrorServiceNotifyClientLagging 1294 +#define kNtErrorDiskQuotaExceeded 1295 +#define kNtErrorContentBlocked 1296 +#define kNtErrorIncompatibleServicePrivilege 1297 +#define kNtErrorAppHang 1298 +#define kNtErrorInvalidLabel 1299 +#define kNtErrorNotAllAssigned 1300 +#define kNtErrorSomeNotMapped 1301 +#define kNtErrorNoQuotasForAccount 1302 +#define kNtErrorLocalUserSessionKey 1303 +#define kNtErrorNullLmPassword 1304 +#define kNtErrorUnknownRevision 1305 +#define kNtErrorRevisionMismatch 1306 +#define kNtErrorInvalidOwner 1307 +#define kNtErrorInvalidPrimaryGroup 1308 +#define kNtErrorNoImpersonationToken 1309 +#define kNtErrorCantDisableMandatory 1310 +#define kNtErrorNoLogonServers 1311 +#define kNtErrorNoSuchLogonSession 1312 +#define kNtErrorNoSuchPrivilege 1313 +#define kNtErrorPrivilegeNotHeld 1314 +#define kNtErrorInvalidAccountName 1315 +#define kNtErrorUserExists 1316 +#define kNtErrorNoSuchUser 1317 +#define kNtErrorGroupExists 1318 +#define kNtErrorNoSuchGroup 1319 +#define kNtErrorMemberInGroup 1320 +#define kNtErrorMemberNotInGroup 1321 +#define kNtErrorLastAdmin 1322 +#define kNtErrorWrongPassword 1323 +#define kNtErrorIllFormedPassword 1324 +#define kNtErrorPasswordRestriction 1325 +#define kNtErrorLogonFailure 1326 +#define kNtErrorAccountRestriction 1327 +#define kNtErrorInvalidLogonHours 1328 +#define kNtErrorInvalidWorkstation 1329 +#define kNtErrorPasswordExpired 1330 +#define kNtErrorAccountDisabled 1331 +#define kNtErrorNoneMapped 1332 +#define kNtErrorTooManyLuidsRequested 1333 +#define kNtErrorLuidsExhausted 1334 +#define kNtErrorInvalidSubAuthority 1335 +#define kNtErrorInvalidAcl 1336 +#define kNtErrorInvalidSid 1337 +#define kNtErrorInvalidSecurityDescr 1338 +#define kNtErrorBadInheritanceAcl 1340 +#define kNtErrorServerDisabled 1341 +#define kNtErrorServerNotDisabled 1342 +#define kNtErrorInvalidIdAuthority 1343 +#define kNtErrorAllottedSpaceExceeded 1344 +#define kNtErrorInvalidGroupAttributes 1345 +#define kNtErrorBadImpersonationLevel 1346 +#define kNtErrorCantOpenAnonymous 1347 +#define kNtErrorBadValidationClass 1348 +#define kNtErrorBadTokenType 1349 +#define kNtErrorNoSecurityOnObject 1350 +#define kNtErrorCantAccessDomainInfo 1351 +#define kNtErrorInvalidServerState 1352 +#define kNtErrorInvalidDomainState 1353 +#define kNtErrorInvalidDomainRole 1354 +#define kNtErrorNoSuchDomain 1355 +#define kNtErrorDomainExists 1356 +#define kNtErrorDomainLimitExceeded 1357 +#define kNtErrorInternalDbCorruption 1358 +#define kNtErrorInternalError 1359 +#define kNtErrorGenericNotMapped 1360 +#define kNtErrorBadDescriptorFormat 1361 +#define kNtErrorNotLogonProcess 1362 +#define kNtErrorLogonSessionExists 1363 +#define kNtErrorNoSuchPackage 1364 +#define kNtErrorBadLogonSessionState 1365 +#define kNtErrorLogonSessionCollision 1366 +#define kNtErrorInvalidLogonType 1367 +#define kNtErrorCannotImpersonate 1368 +#define kNtErrorRxactInvalidState 1369 +#define kNtErrorRxactCommitFailure 1370 +#define kNtErrorSpecialAccount 1371 +#define kNtErrorSpecialGroup 1372 +#define kNtErrorSpecialUser 1373 +#define kNtErrorMembersPrimaryGroup 1374 +#define kNtErrorTokenAlreadyInUse 1375 +#define kNtErrorNoSuchAlias 1376 +#define kNtErrorMemberNotInAlias 1377 +#define kNtErrorMemberInAlias 1378 +#define kNtErrorAliasExists 1379 +#define kNtErrorLogonNotGranted 1380 +#define kNtErrorTooManySecrets 1381 +#define kNtErrorSecretTooLong 1382 +#define kNtErrorInternalDbError 1383 +#define kNtErrorTooManyContextIds 1384 +#define kNtErrorLogonTypeNotGranted 1385 +#define kNtErrorNtCrossEncryptionRequired 1386 +#define kNtErrorNoSuchMember 1387 +#define kNtErrorInvalidMember 1388 +#define kNtErrorTooManySids 1389 +#define kNtErrorLmCrossEncryptionRequired 1390 +#define kNtErrorNoInheritance 1391 +#define kNtErrorFileCorrupt 1392 +#define kNtErrorDiskCorrupt 1393 +#define kNtErrorNoUserSessionKey 1394 +#define kNtErrorLicenseQuotaExceeded 1395 +#define kNtErrorWrongTargetName 1396 +#define kNtErrorMutualAuthFailed 1397 +#define kNtErrorTimeSkew 1398 +#define kNtErrorCurrentDomainNotAllowed 1399 +#define kNtErrorInvalidWindowHandle 1400 +#define kNtErrorInvalidMenuHandle 1401 +#define kNtErrorInvalidCursorHandle 1402 +#define kNtErrorInvalidAccelHandle 1403 +#define kNtErrorInvalidHookHandle 1404 +#define kNtErrorInvalidDwpHandle 1405 +#define kNtErrorTlwWithWschild 1406 +#define kNtErrorCannotFindWndClass 1407 +#define kNtErrorWindowOfOtherThread 1408 +#define kNtErrorHotkeyAlreadyRegistered 1409 +#define kNtErrorClassAlreadyExists 1410 +#define kNtErrorClassDoesNotExist 1411 +#define kNtErrorClassHasWindows 1412 +#define kNtErrorInvalidIndex 1413 +#define kNtErrorInvalidIconHandle 1414 +#define kNtErrorPrivateDialogIndex 1415 +#define kNtErrorListboxIdNotFound 1416 +#define kNtErrorNoWildcardCharacters 1417 +#define kNtErrorClipboardNotOpen 1418 +#define kNtErrorHotkeyNotRegistered 1419 +#define kNtErrorWindowNotDialog 1420 +#define kNtErrorControlIdNotFound 1421 +#define kNtErrorInvalidComboboxMessage 1422 +#define kNtErrorWindowNotCombobox 1423 +#define kNtErrorInvalidEditHeight 1424 +#define kNtErrorDcNotFound 1425 +#define kNtErrorInvalidHookFilter 1426 +#define kNtErrorInvalidFilterProc 1427 +#define kNtErrorHookNeedsHmod 1428 +#define kNtErrorGlobalOnlyHook 1429 +#define kNtErrorJournalHookSet 1430 +#define kNtErrorHookNotInstalled 1431 +#define kNtErrorInvalidLbMessage 1432 +#define kNtErrorSetcountOnBadLb 1433 +#define kNtErrorLbWithoutTabstops 1434 +#define kNtErrorDestroyObjectOfOtherThread 1435 +#define kNtErrorChildWindowMenu 1436 +#define kNtErrorNoSystemMenu 1437 +#define kNtErrorInvalidMsgboxStyle 1438 +#define kNtErrorInvalidSpiValue 1439 +#define kNtErrorScreenAlreadyLocked 1440 +#define kNtErrorHwndsHaveDiffParent 1441 +#define kNtErrorNotChildWindow 1442 +#define kNtErrorInvalidGwCommand 1443 +#define kNtErrorInvalidThreadId 1444 +#define kNtErrorNonMdichildWindow 1445 +#define kNtErrorPopupAlreadyActive 1446 +#define kNtErrorNoScrollbars 1447 +#define kNtErrorInvalidScrollbarRange 1448 +#define kNtErrorInvalidShowwinCommand 1449 +#define kNtErrorNoSystemResources 1450 +#define kNtErrorNonpagedSystemResources 1451 +#define kNtErrorPagedSystemResources 1452 +#define kNtErrorWorkingSetQuota 1453 +#define kNtErrorPagefileQuota 1454 +#define kNtErrorCommitmentLimit 1455 +#define kNtErrorMenuItemNotFound 1456 +#define kNtErrorInvalidKeyboardHandle 1457 +#define kNtErrorHookTypeNotAllowed 1458 +#define kNtErrorRequiresInteractiveWindowstation 1459 +#define kNtErrorTimeout 1460 +#define kNtErrorInvalidMonitorHandle 1461 +#define kNtErrorIncorrectSize 1462 +#define kNtErrorSymlinkClassDisabled 1463 +#define kNtErrorSymlinkNotSupported 1464 +#define kNtErrorXmlParseError 1465 +#define kNtErrorXmldsigError 1466 +#define kNtErrorRestartApplication 1467 +#define kNtErrorWrongCompartment 1468 +#define kNtErrorAuthipFailure 1469 +#define kNtErrorNoNvramResources 1470 +#define kNtErrorNotGuiProcess 1471 +#define kNtErrorEventlogFileCorrupt 1500 +#define kNtErrorEventlogCantStart 1501 +#define kNtErrorLogFileFull 1502 +#define kNtErrorEventlogFileChanged 1503 +#define kNtErrorContainerAssigned 1504 +#define kNtErrorJobNoContainer 1505 +#define kNtErrorInvalidTaskName 1550 +#define kNtErrorInvalidTaskIndex 1551 +#define kNtErrorThreadAlreadyInTask 1552 +#define kNtErrorInstallServiceFailure 1601 +#define kNtErrorInstallUserexit 1602 +#define kNtErrorInstallFailure 1603 +#define kNtErrorInstallSuspend 1604 +#define kNtErrorUnknownProduct 1605 +#define kNtErrorUnknownFeature 1606 +#define kNtErrorUnknownComponent 1607 +#define kNtErrorUnknownProperty 1608 +#define kNtErrorInvalidHandleState 1609 +#define kNtErrorBadConfiguration 1610 +#define kNtErrorIndexAbsent 1611 +#define kNtErrorInstallSourceAbsent 1612 +#define kNtErrorInstallPackageVersion 1613 +#define kNtErrorProductUninstalled 1614 +#define kNtErrorBadQuerySyntax 1615 +#define kNtErrorInvalidField 1616 +#define kNtErrorDeviceRemoved 1617 +#define kNtErrorInstallAlreadyRunning 1618 +#define kNtErrorInstallPackageOpenFailed 1619 +#define kNtErrorInstallPackageInvalid 1620 +#define kNtErrorInstallUiFailure 1621 +#define kNtErrorInstallLogFailure 1622 +#define kNtErrorInstallLanguageUnsupported 1623 +#define kNtErrorInstallTransformFailure 1624 +#define kNtErrorInstallPackageRejected 1625 +#define kNtErrorFunctionNotCalled 1626 +#define kNtErrorFunctionFailed 1627 +#define kNtErrorInvalidTable 1628 +#define kNtErrorDatatypeMismatch 1629 +#define kNtErrorUnsupportedType 1630 +#define kNtErrorCreateFailed 1631 +#define kNtErrorInstallTempUnwritable 1632 +#define kNtErrorInstallPlatformUnsupported 1633 +#define kNtErrorInstallNotused 1634 +#define kNtErrorPatchPackageOpenFailed 1635 +#define kNtErrorPatchPackageInvalid 1636 +#define kNtErrorPatchPackageUnsupported 1637 +#define kNtErrorProductVersion 1638 +#define kNtErrorInvalidCommandLine 1639 /* E2BIG */ +#define kNtErrorInstallRemoteDisallowed 1640 +#define kNtErrorSuccessRebootInitiated 1641 +#define kNtErrorPatchTargetNotFound 1642 +#define kNtErrorPatchPackageRejected 1643 +#define kNtErrorInstallTransformRejected 1644 +#define kNtErrorInstallRemoteProhibited 1645 +#define kNtErrorPatchRemovalUnsupported 1646 +#define kNtErrorUnknownPatch 1647 +#define kNtErrorPatchNoSequence 1648 +#define kNtErrorPatchRemovalDisallowed 1649 +#define kNtErrorInvalidPatchXml 1650 +#define kNtErrorPatchManagedAdvertisedProduct 1651 +#define kNtErrorInstallServiceSafeboot 1652 +#define kNtErrorFailFastException 1653 +#define kNtErrorInstallRejected 1654 +#define kNtErrorDynamicCodeBlocked 1655 +#define kNtErrorNotSameObject 1656 +#define kNtErrorStrictCfgViolation 1657 +#define kNtErrorSetContextDenied 1660 +#define kNtErrorCrossPartitionViolation 1661 +#define kNtErrorInvalidUserBuffer 1784 +#define kNtErrorUnrecognizedMedia 1785 +#define kNtErrorNoTrustLsaSecret 1786 +#define kNtErrorNoTrustSamAccount 1787 +#define kNtErrorTrustedDomainFailure 1788 +#define kNtErrorTrustedRelationshipFailure 1789 +#define kNtErrorTrustFailure 1790 +#define kNtErrorNetlogonNotStarted 1792 +#define kNtErrorAccountExpired 1793 +#define kNtErrorRedirectorHasOpenHandles 1794 +#define kNtErrorPrinterDriverAlreadyInstalled 1795 +#define kNtErrorUnknownPort 1796 +#define kNtErrorUnknownPrinterDriver 1797 +#define kNtErrorUnknownPrintprocessor 1798 +#define kNtErrorInvalidSeparatorFile 1799 +#define kNtErrorInvalidPriority 1800 +#define kNtErrorInvalidPrinterName 1801 +#define kNtErrorPrinterAlreadyExists 1802 +#define kNtErrorInvalidPrinterCommand 1803 +#define kNtErrorInvalidDatatype 1804 +#define kNtErrorInvalidEnvironment 1805 +#define kNtErrorNologonInterdomainTrustAccount 1807 +#define kNtErrorNologonWorkstationTrustAccount 1808 +#define kNtErrorNologonServerTrustAccount 1809 +#define kNtErrorDomainTrustInconsistent 1810 +#define kNtErrorServerHasOpenHandles 1811 +#define kNtErrorResourceDataNotFound 1812 +#define kNtErrorResourceTypeNotFound 1813 +#define kNtErrorResourceNameNotFound 1814 +#define kNtErrorResourceLangNotFound 1815 +#define kNtErrorNotEnoughQuota 1816 +#define kNtErrorInvalidTime 1901 +#define kNtErrorInvalidFormName 1902 +#define kNtErrorInvalidFormSize 1903 +#define kNtErrorAlreadyWaiting 1904 +#define kNtErrorPrinterDeleted 1905 +#define kNtErrorInvalidPrinterState 1906 +#define kNtErrorPasswordMustChange 1907 +#define kNtErrorDomainControllerNotFound 1908 +#define kNtErrorAccountLockedOut 1909 +#define kNtErrorNoSitename 1919 +#define kNtErrorCantAccessFile 1920 +#define kNtErrorCantResolveFilename 1921 +#define kNtErrorKmDriverBlocked 1930 +#define kNtErrorContextExpired 1931 +#define kNtErrorPerUserTrustQuotaExceeded 1932 +#define kNtErrorAllUserTrustQuotaExceeded 1933 +#define kNtErrorUserDeleteTrustQuotaExceeded 1934 +#define kNtErrorAuthenticationFirewallFailed 1935 +#define kNtErrorRemotePrintConnectionsBlocked 1936 +#define kNtErrorNtlmBlocked 1937 +#define kNtErrorPasswordChangeRequired 1938 +#define kNtErrorLostModeLogonRestriction 1939 +#define kNtErrorInvalidPixelFormat 2000 +#define kNtErrorBadDriver 2001 +#define kNtErrorInvalidWindowStyle 2002 +#define kNtErrorMetafileNotSupported 2003 +#define kNtErrorTransformNotSupported 2004 +#define kNtErrorClippingNotSupported 2005 +#define kNtErrorInvalidCmm 2010 +#define kNtErrorInvalidProfile 2011 +#define kNtErrorTagNotFound 2012 +#define kNtErrorTagNotPresent 2013 +#define kNtErrorDuplicateTag 2014 +#define kNtErrorProfileNotAssociatedWithDevice 2015 +#define kNtErrorProfileNotFound 2016 +#define kNtErrorInvalidColorspace 2017 +#define kNtErrorIcmNotEnabled 2018 +#define kNtErrorDeletingIcmXform 2019 +#define kNtErrorInvalidTransform 2020 +#define kNtErrorColorspaceMismatch 2021 +#define kNtErrorInvalidColorindex 2022 +#define kNtErrorProfileDoesNotMatchDevice 2023 +#define kNtErrorConnectedOtherPassword 2108 +#define kNtErrorConnectedOtherPasswordDefault 2109 +#define kNtErrorBadUsername 2202 +#define kNtErrorNotConnected 2250 +#define kNtErrorOpenFiles 2401 +#define kNtErrorActiveConnections 2402 +#define kNtErrorDeviceInUse 2404 +#define kNtErrorUnknownPrintMonitor 3000 +#define kNtErrorPrinterDriverInUse 3001 +#define kNtErrorSpoolFileNotFound 3002 +#define kNtErrorSplNoStartdoc 3003 +#define kNtErrorSplNoAddjob 3004 +#define kNtErrorPrintProcessorAlreadyInstalled 3005 +#define kNtErrorPrintMonitorAlreadyInstalled 3006 +#define kNtErrorInvalidPrintMonitor 3007 +#define kNtErrorPrintMonitorInUse 3008 +#define kNtErrorPrinterHasJobsQueued 3009 +#define kNtErrorSuccessRebootRequired 3010 +#define kNtErrorSuccessRestartRequired 3011 +#define kNtErrorPrinterNotFound 3012 +#define kNtErrorPrinterDriverWarned 3013 +#define kNtErrorPrinterDriverBlocked 3014 +#define kNtErrorPrinterDriverPackageInUse 3015 +#define kNtErrorCoreDriverPackageNotFound 3016 +#define kNtErrorFailRebootRequired 3017 +#define kNtErrorFailRebootInitiated 3018 +#define kNtErrorPrinterDriverDownloadNeeded 3019 +#define kNtErrorPrintJobRestartRequired 3020 +#define kNtErrorInvalidPrinterDriverManifest 3021 +#define kNtErrorPrinterNotShareable 3022 +#define kNtErrorRequestPaused 3050 +#define kNtErrorAppexecConditionNotSatisfied 3060 +#define kNtErrorAppexecHandleInvalidated 3061 +#define kNtErrorAppexecInvalidHostGeneration 3062 +#define kNtErrorAppexecUnexpectedProcessRegistration 3063 +#define kNtErrorAppexecInvalidHostState 3064 +#define kNtErrorAppexecNoDonor 3065 +#define kNtErrorAppexecHostIdMismatch 3066 +#define kNtErrorIoReissueAsCached 3950 +#define kNtErrorWinsInternal 4000 +#define kNtErrorCanNotDelLocalWins 4001 +#define kNtErrorStaticInit 4002 +#define kNtErrorIncBackup 4003 +#define kNtErrorFullBackup 4004 +#define kNtErrorRecNonExistent 4005 +#define kNtErrorRplNotAllowed 4006 +#define kNtErrorDhcpAddressConflict 4100 +#define kNtErrorWmiGuidNotFound 4200 +#define kNtErrorWmiInstanceNotFound 4201 +#define kNtErrorWmiItemidNotFound 4202 +#define kNtErrorWmiTryAgain 4203 +#define kNtErrorWmiDpNotFound 4204 +#define kNtErrorWmiUnresolvedInstanceRef 4205 +#define kNtErrorWmiAlreadyEnabled 4206 +#define kNtErrorWmiGuidDisconnected 4207 +#define kNtErrorWmiServerUnavailable 4208 +#define kNtErrorWmiDpFailed 4209 +#define kNtErrorWmiInvalidMof 4210 +#define kNtErrorWmiInvalidReginfo 4211 +#define kNtErrorWmiAlreadyDisabled 4212 +#define kNtErrorWmiReadOnly 4213 +#define kNtErrorWmiSetFailure 4214 +#define kNtErrorNotAppcontainer 4250 +#define kNtErrorAppcontainerRequired 4251 +#define kNtErrorNotSupportedInAppcontainer 4252 +#define kNtErrorInvalidPackageSidLength 4253 +#define kNtErrorInvalidMedia 4300 +#define kNtErrorInvalidLibrary 4301 +#define kNtErrorInvalidMediaPool 4302 +#define kNtErrorDriveMediaMismatch 4303 +#define kNtErrorMediaOffline 4304 +#define kNtErrorLibraryOffline 4305 +#define kNtErrorEmpty 4306 +#define kNtErrorNotEmpty 4307 +#define kNtErrorMediaUnavailable 4308 +#define kNtErrorResourceDisabled 4309 +#define kNtErrorInvalidCleaner 4310 +#define kNtErrorUnableToClean 4311 +#define kNtErrorObjectNotFound 4312 +#define kNtErrorDatabaseFailure 4313 +#define kNtErrorDatabaseFull 4314 +#define kNtErrorMediaIncompatible 4315 +#define kNtErrorResourceNotPresent 4316 +#define kNtErrorInvalidOperation 4317 +#define kNtErrorMediaNotAvailable 4318 +#define kNtErrorDeviceNotAvailable 4319 +#define kNtErrorRequestRefused 4320 +#define kNtErrorInvalidDriveObject 4321 +#define kNtErrorLibraryFull 4322 +#define kNtErrorMediumNotAccessible 4323 +#define kNtErrorUnableToLoadMedium 4324 +#define kNtErrorUnableToInventoryDrive 4325 +#define kNtErrorUnableToInventorySlot 4326 +#define kNtErrorUnableToInventoryTransport 4327 +#define kNtErrorTransportFull 4328 +#define kNtErrorControllingIeport 4329 +#define kNtErrorUnableToEjectMountedMedia 4330 +#define kNtErrorCleanerSlotSet 4331 +#define kNtErrorCleanerSlotNotSet 4332 +#define kNtErrorCleanerCartridgeSpent 4333 +#define kNtErrorUnexpectedOmid 4334 +#define kNtErrorCantDeleteLastItem 4335 +#define kNtErrorMessageExceedsMaxSize 4336 +#define kNtErrorVolumeContainsSysFiles 4337 +#define kNtErrorIndigenousType 4338 +#define kNtErrorNoSupportingDrives 4339 +#define kNtErrorCleanerCartridgeInstalled 4340 +#define kNtErrorIeportFull 4341 +#define kNtErrorFileOffline 4350 +#define kNtErrorRemoteStorageNotActive 4351 +#define kNtErrorRemoteStorageMediaError 4352 +#define kNtErrorNotAReparsePoint 4390 +#define kNtErrorReparseAttributeConflict 4391 +#define kNtErrorInvalidReparseData 4392 +#define kNtErrorReparseTagInvalid 4393 +#define kNtErrorReparseTagMismatch 4394 +#define kNtErrorReparsePointEncountered 4395 +#define kNtErrorAppDataNotFound 4400 +#define kNtErrorAppDataExpired 4401 +#define kNtErrorAppDataCorrupt 4402 +#define kNtErrorAppDataLimitExceeded 4403 +#define kNtErrorAppDataRebootRequired 4404 +#define kNtErrorSecurebootRollbackDetected 4420 +#define kNtErrorSecurebootPolicyViolation 4421 +#define kNtErrorSecurebootInvalidPolicy 4422 +#define kNtErrorSecurebootPolicyPublisherNotFound 4423 +#define kNtErrorSecurebootPolicyNotSigned 4424 +#define kNtErrorSecurebootNotEnabled 4425 +#define kNtErrorSecurebootFileReplaced 4426 +#define kNtErrorSecurebootPolicyNotAuthorized 4427 +#define kNtErrorSecurebootPolicyUnknown 4428 +#define kNtErrorSecurebootPolicyMissingAntirollbackversion 4429 +#define kNtErrorSecurebootPlatformIdMismatch 4430 +#define kNtErrorSecurebootPolicyRollbackDetected 4431 +#define kNtErrorSecurebootPolicyUpgradeMismatch 4432 +#define kNtErrorSecurebootRequiredPolicyFileMissing 4433 +#define kNtErrorSecurebootNotBasePolicy 4434 +#define kNtErrorSecurebootNotSupplementalPolicy 4435 +#define kNtErrorOffloadReadFltNotSupported 4440 +#define kNtErrorOffloadWriteFltNotSupported 4441 +#define kNtErrorOffloadReadFileNotSupported 4442 +#define kNtErrorOffloadWriteFileNotSupported 4443 +#define kNtErrorAlreadyHasStreamId 4444 +#define kNtErrorSmrGarbageCollectionRequired 4445 +#define kNtErrorWofWimHeaderCorrupt 4446 +#define kNtErrorWofWimResourceTableCorrupt 4447 +#define kNtErrorWofFileResourceTableCorrupt 4448 +#define kNtErrorVolumeNotSisEnabled 4500 +#define kNtErrorSystemIntegrityRollbackDetected 4550 +#define kNtErrorSystemIntegrityPolicyViolation 4551 +#define kNtErrorSystemIntegrityInvalidPolicy 4552 +#define kNtErrorSystemIntegrityPolicyNotSigned 4553 +#define kNtErrorVsmNotInitialized 4560 +#define kNtErrorVsmDmaProtectionNotInUse 4561 +#define kNtErrorPlatformManifestNotAuthorized 4570 +#define kNtErrorPlatformManifestInvalid 4571 +#define kNtErrorPlatformManifestFileNotAuthorized 4572 +#define kNtErrorPlatformManifestCatalogNotAuthorized 4573 +#define kNtErrorPlatformManifestBinaryIdNotFound 4574 +#define kNtErrorPlatformManifestNotActive 4575 +#define kNtErrorPlatformManifestNotSigned 4576 +#define kNtErrorDependentResourceExists 5001 +#define kNtErrorDependencyNotFound 5002 +#define kNtErrorDependencyAlreadyExists 5003 +#define kNtErrorResourceNotOnline 5004 +#define kNtErrorHostNodeNotAvailable 5005 +#define kNtErrorResourceNotAvailable 5006 +#define kNtErrorResourceNotFound 5007 +#define kNtErrorShutdownCluster 5008 +#define kNtErrorCantEvictActiveNode 5009 +#define kNtErrorObjectAlreadyExists 5010 +#define kNtErrorObjectInList 5011 +#define kNtErrorGroupNotAvailable 5012 +#define kNtErrorGroupNotFound 5013 +#define kNtErrorGroupNotOnline 5014 +#define kNtErrorHostNodeNotResourceOwner 5015 +#define kNtErrorHostNodeNotGroupOwner 5016 +#define kNtErrorResmonCreateFailed 5017 +#define kNtErrorResmonOnlineFailed 5018 +#define kNtErrorResourceOnline 5019 +#define kNtErrorQuorumResource 5020 +#define kNtErrorNotQuorumCapable 5021 +#define kNtErrorClusterShuttingDown 5022 +#define kNtErrorInvalidState 5023 +#define kNtErrorResourcePropertiesStored 5024 +#define kNtErrorNotQuorumClass 5025 +#define kNtErrorCoreResource 5026 +#define kNtErrorQuorumResourceOnlineFailed 5027 +#define kNtErrorQuorumlogOpenFailed 5028 +#define kNtErrorClusterlogCorrupt 5029 +#define kNtErrorClusterlogRecordExceedsMaxsize 5030 +#define kNtErrorClusterlogExceedsMaxsize 5031 +#define kNtErrorClusterlogChkpointNotFound 5032 +#define kNtErrorClusterlogNotEnoughSpace 5033 +#define kNtErrorQuorumOwnerAlive 5034 +#define kNtErrorNetworkNotAvailable 5035 +#define kNtErrorNodeNotAvailable 5036 +#define kNtErrorAllNodesNotAvailable 5037 +#define kNtErrorResourceFailed 5038 +#define kNtErrorClusterInvalidNode 5039 +#define kNtErrorClusterNodeExists 5040 +#define kNtErrorClusterJoinInProgress 5041 +#define kNtErrorClusterNodeNotFound 5042 +#define kNtErrorClusterLocalNodeNotFound 5043 +#define kNtErrorClusterNetworkExists 5044 +#define kNtErrorClusterNetworkNotFound 5045 +#define kNtErrorClusterNetinterfaceExists 5046 +#define kNtErrorClusterNetinterfaceNotFound 5047 +#define kNtErrorClusterInvalidRequest 5048 +#define kNtErrorClusterInvalidNetworkProvider 5049 +#define kNtErrorClusterNodeDown 5050 +#define kNtErrorClusterNodeUnreachable 5051 +#define kNtErrorClusterNodeNotMember 5052 +#define kNtErrorClusterJoinNotInProgress 5053 +#define kNtErrorClusterInvalidNetwork 5054 +#define kNtErrorClusterNodeUp 5056 +#define kNtErrorClusterIpaddrInUse 5057 +#define kNtErrorClusterNodeNotPaused 5058 +#define kNtErrorClusterNoSecurityContext 5059 +#define kNtErrorClusterNetworkNotInternal 5060 +#define kNtErrorClusterNodeAlreadyUp 5061 +#define kNtErrorClusterNodeAlreadyDown 5062 +#define kNtErrorClusterNetworkAlreadyOnline 5063 +#define kNtErrorClusterNetworkAlreadyOffline 5064 +#define kNtErrorClusterNodeAlreadyMember 5065 +#define kNtErrorClusterLastInternalNetwork 5066 +#define kNtErrorClusterNetworkHasDependents 5067 +#define kNtErrorInvalidOperationOnQuorum 5068 +#define kNtErrorDependencyNotAllowed 5069 +#define kNtErrorClusterNodePaused 5070 +#define kNtErrorNodeCantHostResource 5071 +#define kNtErrorClusterNodeNotReady 5072 +#define kNtErrorClusterNodeShuttingDown 5073 +#define kNtErrorClusterJoinAborted 5074 +#define kNtErrorClusterIncompatibleVersions 5075 +#define kNtErrorClusterMaxnumOfResourcesExceeded 5076 +#define kNtErrorClusterSystemConfigChanged 5077 +#define kNtErrorClusterResourceTypeNotFound 5078 +#define kNtErrorClusterRestypeNotSupported 5079 +#define kNtErrorClusterResnameNotFound 5080 +#define kNtErrorClusterNoRpcPackagesRegistered 5081 +#define kNtErrorClusterOwnerNotInPreflist 5082 +#define kNtErrorClusterDatabaseSeqmismatch 5083 +#define kNtErrorResmonInvalidState 5084 +#define kNtErrorClusterGumNotLocker 5085 +#define kNtErrorQuorumDiskNotFound 5086 +#define kNtErrorDatabaseBackupCorrupt 5087 +#define kNtErrorClusterNodeAlreadyHasDfsRoot 5088 +#define kNtErrorResourcePropertyUnchangeable 5089 +#define kNtErrorNoAdminAccessPoint 5090 +#define kNtErrorClusterMembershipInvalidState 5890 +#define kNtErrorClusterQuorumlogNotFound 5891 +#define kNtErrorClusterMembershipHalt 5892 +#define kNtErrorClusterInstanceIdMismatch 5893 +#define kNtErrorClusterNetworkNotFoundForIp 5894 +#define kNtErrorClusterPropertyDataTypeMismatch 5895 +#define kNtErrorClusterEvictWithoutCleanup 5896 +#define kNtErrorClusterParameterMismatch 5897 +#define kNtErrorNodeCannotBeClustered 5898 +#define kNtErrorClusterWrongOsVersion 5899 +#define kNtErrorClusterCantCreateDupClusterName 5900 +#define kNtErrorCluscfgAlreadyCommitted 5901 +#define kNtErrorCluscfgRollbackFailed 5902 +#define kNtErrorCluscfgSystemDiskDriveLetterConflict 5903 +#define kNtErrorClusterOldVersion 5904 +#define kNtErrorClusterMismatchedComputerAcctName 5905 +#define kNtErrorClusterNoNetAdapters 5906 +#define kNtErrorClusterPoisoned 5907 +#define kNtErrorClusterGroupMoving 5908 +#define kNtErrorClusterResourceTypeBusy 5909 +#define kNtErrorResourceCallTimedOut 5910 +#define kNtErrorInvalidClusterIpv6Address 5911 +#define kNtErrorClusterInternalInvalidFunction 5912 +#define kNtErrorClusterParameterOutOfBounds 5913 +#define kNtErrorClusterPartialSend 5914 +#define kNtErrorClusterRegistryInvalidFunction 5915 +#define kNtErrorClusterInvalidStringTermination 5916 +#define kNtErrorClusterInvalidStringFormat 5917 +#define kNtErrorClusterDatabaseTransactionInProgress 5918 +#define kNtErrorClusterDatabaseTransactionNotInProgress 5919 +#define kNtErrorClusterNullData 5920 +#define kNtErrorClusterPartialRead 5921 +#define kNtErrorClusterPartialWrite 5922 +#define kNtErrorClusterCantDeserializeData 5923 +#define kNtErrorDependentResourcePropertyConflict 5924 +#define kNtErrorClusterNoQuorum 5925 +#define kNtErrorClusterInvalidIpv6Network 5926 +#define kNtErrorClusterInvalidIpv6TunnelNetwork 5927 +#define kNtErrorQuorumNotAllowedInThisGroup 5928 +#define kNtErrorDependencyTreeTooComplex 5929 +#define kNtErrorExceptionInResourceCall 5930 +#define kNtErrorClusterRhsFailedInitialization 5931 +#define kNtErrorClusterNotInstalled 5932 +#define kNtErrorClusterResourcesMustBeOnlineOnTheSameNode 5933 +#define kNtErrorClusterMaxNodesInCluster 5934 +#define kNtErrorClusterTooManyNodes 5935 +#define kNtErrorClusterObjectAlreadyUsed 5936 +#define kNtErrorNoncoreGroupsFound 5937 +#define kNtErrorFileShareResourceConflict 5938 +#define kNtErrorClusterEvictInvalidRequest 5939 +#define kNtErrorClusterSingletonResource 5940 +#define kNtErrorClusterGroupSingletonResource 5941 +#define kNtErrorClusterResourceProviderFailed 5942 +#define kNtErrorClusterResourceConfigurationError 5943 +#define kNtErrorClusterGroupBusy 5944 +#define kNtErrorClusterNotSharedVolume 5945 +#define kNtErrorClusterInvalidSecurityDescriptor 5946 +#define kNtErrorClusterSharedVolumesInUse 5947 +#define kNtErrorClusterUseSharedVolumesApi 5948 +#define kNtErrorClusterBackupInProgress 5949 +#define kNtErrorNonCsvPath 5950 +#define kNtErrorCsvVolumeNotLocal 5951 +#define kNtErrorClusterWatchdogTerminating 5952 +#define kNtErrorClusterResourceVetoedMoveIncompatibleNodes 5953 +#define kNtErrorClusterInvalidNodeWeight 5954 +#define kNtErrorClusterResourceVetoedCall 5955 +#define kNtErrorResmonSystemResourcesLacking 5956 +#define kNtErrorClusterResourceVetoedMoveNotEnoughResourcesOnSource 5958 +#define kNtErrorClusterGroupQueued 5959 +#define kNtErrorClusterResourceLockedStatus 5960 +#define kNtErrorClusterSharedVolumeFailoverNotAllowed 5961 +#define kNtErrorClusterNodeDrainInProgress 5962 +#define kNtErrorClusterDiskNotConnected 5963 +#define kNtErrorDiskNotCsvCapable 5964 +#define kNtErrorResourceNotInAvailableStorage 5965 +#define kNtErrorClusterSharedVolumeRedirected 5966 +#define kNtErrorClusterSharedVolumeNotRedirected 5967 +#define kNtErrorClusterCannotReturnProperties 5968 +#define kNtErrorClusterResourceIsInMaintenanceMode 5970 +#define kNtErrorClusterAffinityConflict 5971 +#define kNtErrorClusterResourceIsReplicaVirtualMachine 5972 +#define kNtErrorClusterUpgradeIncompatibleVersions 5973 +#define kNtErrorClusterUpgradeFixQuorumNotSupported 5974 +#define kNtErrorClusterUpgradeRestartRequired 5975 +#define kNtErrorClusterUpgradeInProgress 5976 +#define kNtErrorClusterUpgradeIncomplete 5977 +#define kNtErrorClusterNodeInGracePeriod 5978 +#define kNtErrorClusterCsvIoPauseTimeout 5979 +#define kNtErrorNodeNotActiveClusterMember 5980 +#define kNtErrorClusterResourceNotMonitored 5981 +#define kNtErrorClusterResourceDoesNotSupportUnmonitored 5982 +#define kNtErrorClusterResourceIsReplicated 5983 +#define kNtErrorClusterNodeIsolated 5984 +#define kNtErrorClusterNodeQuarantined 5985 +#define kNtErrorClusterDatabaseUpdateConditionFailed 5986 +#define kNtErrorClusterSpaceDegraded 5987 +#define kNtErrorClusterTokenDelegationNotSupported 5988 +#define kNtErrorClusterCsvInvalidHandle 5989 +#define kNtErrorClusterCsvSupportedOnlyOnCoordinator 5990 +#define kNtErrorGroupsetNotAvailable 5991 +#define kNtErrorGroupsetNotFound 5992 +#define kNtErrorGroupsetCantProvide 5993 +#define kNtErrorClusterFaultDomainParentNotFound 5994 +#define kNtErrorClusterFaultDomainInvalidHierarchy 5995 +#define kNtErrorClusterFaultDomainFailedS2dValidation 5996 +#define kNtErrorClusterFaultDomainS2dConnectivityLoss 5997 +#define kNtErrorClusterInvalidInfrastructureFileserverName 5998 +#define kNtErrorClustersetManagementClusterUnreachable 5999 +#define kNtErrorEncryptionFailed 6000 +#define kNtErrorDecryptionFailed 6001 +#define kNtErrorFileEncrypted 6002 +#define kNtErrorNoRecoveryPolicy 6003 +#define kNtErrorNoEfs 6004 +#define kNtErrorWrongEfs 6005 +#define kNtErrorNoUserKeys 6006 +#define kNtErrorFileNotEncrypted 6007 +#define kNtErrorNotExportFormat 6008 +#define kNtErrorFileReadOnly 6009 /* EROFS */ +#define kNtErrorDirEfsDisallowed 6010 +#define kNtErrorEfsServerNotTrusted 6011 +#define kNtErrorBadRecoveryPolicy 6012 +#define kNtErrorEfsAlgBlobTooBig 6013 +#define kNtErrorVolumeNotSupportEfs 6014 +#define kNtErrorEfsDisabled 6015 +#define kNtErrorEfsVersionNotSupport 6016 +#define kNtErrorCsEncryptionInvalidServerResponse 6017 +#define kNtErrorCsEncryptionUnsupportedServer 6018 +#define kNtErrorCsEncryptionExistingEncryptedFile 6019 +#define kNtErrorCsEncryptionNewEncryptedFile 6020 +#define kNtErrorCsEncryptionFileNotCse 6021 +#define kNtErrorEncryptionPolicyDeniesOperation 6022 +#define kNtErrorNoBrowserServersFound 6118 +#define kNtErrorLogSectorInvalid 6600 +#define kNtErrorLogSectorParityInvalid 6601 +#define kNtErrorLogSectorRemapped 6602 +#define kNtErrorLogBlockIncomplete 6603 +#define kNtErrorLogInvalidRange 6604 +#define kNtErrorLogBlocksExhausted 6605 +#define kNtErrorLogReadContextInvalid 6606 +#define kNtErrorLogRestartInvalid 6607 +#define kNtErrorLogBlockVersion 6608 +#define kNtErrorLogBlockInvalid 6609 +#define kNtErrorLogReadModeInvalid 6610 +#define kNtErrorLogNoRestart 6611 +#define kNtErrorLogMetadataCorrupt 6612 +#define kNtErrorLogMetadataInvalid 6613 +#define kNtErrorLogMetadataInconsistent 6614 +#define kNtErrorLogReservationInvalid 6615 +#define kNtErrorLogCantDelete 6616 +#define kNtErrorLogContainerLimitExceeded 6617 +#define kNtErrorLogStartOfLog 6618 +#define kNtErrorLogPolicyAlreadyInstalled 6619 +#define kNtErrorLogPolicyNotInstalled 6620 +#define kNtErrorLogPolicyInvalid 6621 +#define kNtErrorLogPolicyConflict 6622 +#define kNtErrorLogPinnedArchiveTail 6623 +#define kNtErrorLogRecordNonexistent 6624 +#define kNtErrorLogRecordsReservedInvalid 6625 +#define kNtErrorLogSpaceReservedInvalid 6626 +#define kNtErrorLogTailInvalid 6627 +#define kNtErrorLogFull 6628 +#define kNtErrorCouldNotResizeLog 6629 +#define kNtErrorLogMultiplexed 6630 +#define kNtErrorLogDedicated 6631 +#define kNtErrorLogArchiveNotInProgress 6632 +#define kNtErrorLogArchiveInProgress 6633 +#define kNtErrorLogEphemeral 6634 +#define kNtErrorLogNotEnoughContainers 6635 +#define kNtErrorLogClientAlreadyRegistered 6636 +#define kNtErrorLogClientNotRegistered 6637 +#define kNtErrorLogFullHandlerInProgress 6638 +#define kNtErrorLogContainerReadFailed 6639 +#define kNtErrorLogContainerWriteFailed 6640 +#define kNtErrorLogContainerOpenFailed 6641 +#define kNtErrorLogContainerStateInvalid 6642 +#define kNtErrorLogStateInvalid 6643 +#define kNtErrorLogPinned 6644 +#define kNtErrorLogMetadataFlushFailed 6645 +#define kNtErrorLogInconsistentSecurity 6646 +#define kNtErrorLogAppendedFlushFailed 6647 +#define kNtErrorLogPinnedReservation 6648 +#define kNtErrorInvalidTransaction 6700 +#define kNtErrorTransactionNotActive 6701 +#define kNtErrorTransactionRequestNotValid 6702 +#define kNtErrorTransactionNotRequested 6703 +#define kNtErrorTransactionAlreadyAborted 6704 +#define kNtErrorTransactionAlreadyCommitted 6705 +#define kNtErrorTmInitializationFailed 6706 +#define kNtErrorResourcemanagerReadOnly 6707 +#define kNtErrorTransactionNotJoined 6708 +#define kNtErrorTransactionSuperiorExists 6709 +#define kNtErrorCrmProtocolAlreadyExists 6710 +#define kNtErrorTransactionPropagationFailed 6711 +#define kNtErrorCrmProtocolNotFound 6712 +#define kNtErrorTransactionInvalidMarshallBuffer 6713 +#define kNtErrorCurrentTransactionNotValid 6714 +#define kNtErrorTransactionNotFound 6715 +#define kNtErrorResourcemanagerNotFound 6716 +#define kNtErrorEnlistmentNotFound 6717 +#define kNtErrorTransactionmanagerNotFound 6718 +#define kNtErrorTransactionmanagerNotOnline 6719 +#define kNtErrorTransactionmanagerRecoveryNameCollision 6720 +#define kNtErrorTransactionNotRoot 6721 +#define kNtErrorTransactionObjectExpired 6722 +#define kNtErrorTransactionResponseNotEnlisted 6723 +#define kNtErrorTransactionRecordTooLong 6724 +#define kNtErrorImplicitTransactionNotSupported 6725 +#define kNtErrorTransactionIntegrityViolated 6726 +#define kNtErrorTransactionmanagerIdentityMismatch 6727 +#define kNtErrorRmCannotBeFrozenForSnapshot 6728 +#define kNtErrorTransactionMustWritethrough 6729 +#define kNtErrorTransactionNoSuperior 6730 +#define kNtErrorHeuristicDamagePossible 6731 +#define kNtErrorTransactionalConflict 6800 +#define kNtErrorRmNotActive 6801 +#define kNtErrorRmMetadataCorrupt 6802 +#define kNtErrorDirectoryNotRm 6803 +#define kNtErrorTransactionsUnsupportedRemote 6805 +#define kNtErrorLogResizeInvalidSize 6806 +#define kNtErrorObjectNoLongerExists 6807 +#define kNtErrorStreamMiniversionNotFound 6808 +#define kNtErrorStreamMiniversionNotValid 6809 +#define kNtErrorMiniversionInaccessibleFromSpecifiedTransaction 6810 +#define kNtErrorCantOpenMiniversionWithModifyIntent 6811 +#define kNtErrorCantCreateMoreStreamMiniversions 6812 +#define kNtErrorRemoteFileVersionMismatch 6814 +#define kNtErrorHandleNoLongerValid 6815 +#define kNtErrorNoTxfMetadata 6816 +#define kNtErrorLogCorruptionDetected 6817 +#define kNtErrorCantRecoverWithHandleOpen 6818 +#define kNtErrorRmDisconnected 6819 +#define kNtErrorEnlistmentNotSuperior 6820 +#define kNtErrorRecoveryNotNeeded 6821 +#define kNtErrorRmAlreadyStarted 6822 +#define kNtErrorFileIdentityNotPersistent 6823 +#define kNtErrorCantBreakTransactionalDependency 6824 +#define kNtErrorCantCrossRmBoundary 6825 +#define kNtErrorTxfDirNotEmpty 6826 +#define kNtErrorIndoubtTransactionsExist 6827 +#define kNtErrorTmVolatile 6828 +#define kNtErrorRollbackTimerExpired 6829 +#define kNtErrorTxfAttributeCorrupt 6830 +#define kNtErrorEfsNotAllowedInTransaction 6831 +#define kNtErrorTransactionalOpenNotAllowed 6832 +#define kNtErrorLogGrowthFailed 6833 +#define kNtErrorTransactedMappingUnsupportedRemote 6834 +#define kNtErrorTxfMetadataAlreadyPresent 6835 +#define kNtErrorTransactionScopeCallbacksNotSet 6836 +#define kNtErrorTransactionRequiredPromotion 6837 +#define kNtErrorCannotExecuteFileInTransaction 6838 +#define kNtErrorTransactionsNotFrozen 6839 +#define kNtErrorTransactionFreezeInProgress 6840 +#define kNtErrorNotSnapshotVolume 6841 +#define kNtErrorNoSavepointWithOpenFiles 6842 +#define kNtErrorDataLostRepair 6843 +#define kNtErrorSparseNotAllowedInTransaction 6844 +#define kNtErrorTmIdentityMismatch 6845 +#define kNtErrorFloatedSection 6846 +#define kNtErrorCannotAcceptTransactedWork 6847 +#define kNtErrorCannotAbortTransactions 6848 +#define kNtErrorBadClusters 6849 +#define kNtErrorCompressionNotAllowedInTransaction 6850 +#define kNtErrorVolumeDirty 6851 +#define kNtErrorNoLinkTrackingInTransaction 6852 +#define kNtErrorOperationNotSupportedInTransaction 6853 +#define kNtErrorExpiredHandle 6854 +#define kNtErrorTransactionNotEnlisted 6855 +#define kNtErrorCtxWinstationNameInvalid 7001 +#define kNtErrorCtxInvalidPd 7002 +#define kNtErrorCtxPdNotFound 7003 +#define kNtErrorCtxWdNotFound 7004 +#define kNtErrorCtxCannotMakeEventlogEntry 7005 +#define kNtErrorCtxServiceNameCollision 7006 +#define kNtErrorCtxClosePending 7007 +#define kNtErrorCtxNoOutbuf 7008 +#define kNtErrorCtxModemInfNotFound 7009 +#define kNtErrorCtxInvalidModemname 7010 +#define kNtErrorCtxModemResponseError 7011 +#define kNtErrorCtxModemResponseTimeout 7012 +#define kNtErrorCtxModemResponseNoCarrier 7013 +#define kNtErrorCtxModemResponseNoDialtone 7014 +#define kNtErrorCtxModemResponseBusy 7015 +#define kNtErrorCtxModemResponseVoice 7016 +#define kNtErrorCtxTdError 7017 +#define kNtErrorCtxWinstationNotFound 7022 +#define kNtErrorCtxWinstationAlreadyExists 7023 +#define kNtErrorCtxWinstationBusy 7024 +#define kNtErrorCtxBadVideoMode 7025 +#define kNtErrorCtxGraphicsInvalid 7035 +#define kNtErrorCtxLogonDisabled 7037 +#define kNtErrorCtxNotConsole 7038 +#define kNtErrorCtxClientQueryTimeout 7040 +#define kNtErrorCtxConsoleDisconnect 7041 +#define kNtErrorCtxConsoleConnect 7042 +#define kNtErrorCtxShadowDenied 7044 +#define kNtErrorCtxWinstationAccessDenied 7045 +#define kNtErrorCtxInvalidWd 7049 +#define kNtErrorCtxShadowInvalid 7050 +#define kNtErrorCtxShadowDisabled 7051 +#define kNtErrorCtxClientLicenseInUse 7052 +#define kNtErrorCtxClientLicenseNotSet 7053 +#define kNtErrorCtxLicenseNotAvailable 7054 +#define kNtErrorCtxLicenseClientInvalid 7055 +#define kNtErrorCtxLicenseExpired 7056 +#define kNtErrorCtxShadowNotRunning 7057 +#define kNtErrorCtxShadowEndedByModeChange 7058 +#define kNtErrorActivationCountExceeded 7059 +#define kNtErrorCtxWinstationsDisabled 7060 +#define kNtErrorCtxEncryptionLevelRequired 7061 +#define kNtErrorCtxSessionInUse 7062 +#define kNtErrorCtxNoForceLogoff 7063 +#define kNtErrorCtxAccountRestriction 7064 +#define kNtErrorRdpProtocolError 7065 +#define kNtErrorCtxCdmConnect 7066 +#define kNtErrorCtxCdmDisconnect 7067 +#define kNtErrorCtxSecurityLayerError 7068 +#define kNtErrorTsIncompatibleSessions 7069 +#define kNtErrorTsVideoSubsystemError 7070 +#define kNtErrorDsNotInstalled 8200 +#define kNtErrorDsMembershipEvaluatedLocally 8201 +#define kNtErrorDsNoAttributeOrValue 8202 +#define kNtErrorDsInvalidAttributeSyntax 8203 +#define kNtErrorDsAttributeTypeUndefined 8204 +#define kNtErrorDsAttributeOrValueExists 8205 +#define kNtErrorDsBusy 8206 +#define kNtErrorDsUnavailable 8207 +#define kNtErrorDsNoRidsAllocated 8208 +#define kNtErrorDsNoMoreRids 8209 +#define kNtErrorDsIncorrectRoleOwner 8210 +#define kNtErrorDsRidmgrInitError 8211 +#define kNtErrorDsObjClassViolation 8212 +#define kNtErrorDsCantOnNonLeaf 8213 +#define kNtErrorDsCantOnRdn 8214 +#define kNtErrorDsCantModObjClass 8215 +#define kNtErrorDsCrossDomMoveError 8216 +#define kNtErrorDsGcNotAvailable 8217 +#define kNtErrorSharedPolicy 8218 +#define kNtErrorPolicyObjectNotFound 8219 +#define kNtErrorPolicyOnlyInDs 8220 +#define kNtErrorPromotionActive 8221 +#define kNtErrorNoPromotionActive 8222 +#define kNtErrorDsOperationsError 8224 +#define kNtErrorDsProtocolError 8225 +#define kNtErrorDsTimelimitExceeded 8226 +#define kNtErrorDsSizelimitExceeded 8227 +#define kNtErrorDsAdminLimitExceeded 8228 +#define kNtErrorDsCompareFalse 8229 +#define kNtErrorDsCompareTrue 8230 +#define kNtErrorDsAuthMethodNotSupported 8231 +#define kNtErrorDsStrongAuthRequired 8232 +#define kNtErrorDsInappropriateAuth 8233 +#define kNtErrorDsAuthUnknown 8234 +#define kNtErrorDsReferral 8235 +#define kNtErrorDsUnavailableCritExtension 8236 +#define kNtErrorDsConfidentialityRequired 8237 +#define kNtErrorDsInappropriateMatching 8238 +#define kNtErrorDsConstraintViolation 8239 +#define kNtErrorDsNoSuchObject 8240 +#define kNtErrorDsAliasProblem 8241 +#define kNtErrorDsInvalidDnSyntax 8242 +#define kNtErrorDsIsLeaf 8243 +#define kNtErrorDsAliasDerefProblem 8244 +#define kNtErrorDsUnwillingToPerform 8245 +#define kNtErrorDsLoopDetect 8246 +#define kNtErrorDsNamingViolation 8247 +#define kNtErrorDsObjectResultsTooLarge 8248 +#define kNtErrorDsAffectsMultipleDsas 8249 +#define kNtErrorDsServerDown 8250 +#define kNtErrorDsLocalError 8251 +#define kNtErrorDsEncodingError 8252 +#define kNtErrorDsDecodingError 8253 +#define kNtErrorDsFilterUnknown 8254 +#define kNtErrorDsParamError 8255 +#define kNtErrorDsNotSupported 8256 +#define kNtErrorDsNoResultsReturned 8257 +#define kNtErrorDsControlNotFound 8258 +#define kNtErrorDsClientLoop 8259 +#define kNtErrorDsReferralLimitExceeded 8260 +#define kNtErrorDsSortControlMissing 8261 +#define kNtErrorDsOffsetRangeError 8262 +#define kNtErrorDsRidmgrDisabled 8263 +#define kNtErrorDsRootMustBeNc 8301 +#define kNtErrorDsAddReplicaInhibited 8302 +#define kNtErrorDsAttNotDefInSchema 8303 +#define kNtErrorDsMaxObjSizeExceeded 8304 +#define kNtErrorDsObjStringNameExists 8305 +#define kNtErrorDsNoRdnDefinedInSchema 8306 +#define kNtErrorDsRdnDoesntMatchSchema 8307 +#define kNtErrorDsNoRequestedAttsFound 8308 +#define kNtErrorDsUserBufferToSmall 8309 +#define kNtErrorDsAttIsNotOnObj 8310 +#define kNtErrorDsIllegalModOperation 8311 +#define kNtErrorDsObjTooLarge 8312 +#define kNtErrorDsBadInstanceType 8313 +#define kNtErrorDsMasterdsaRequired 8314 +#define kNtErrorDsObjectClassRequired 8315 +#define kNtErrorDsMissingRequiredAtt 8316 +#define kNtErrorDsAttNotDefForClass 8317 +#define kNtErrorDsAttAlreadyExists 8318 +#define kNtErrorDsCantAddAttValues 8320 +#define kNtErrorDsSingleValueConstraint 8321 +#define kNtErrorDsRangeConstraint 8322 +#define kNtErrorDsAttValAlreadyExists 8323 +#define kNtErrorDsCantRemMissingAtt 8324 +#define kNtErrorDsCantRemMissingAttVal 8325 +#define kNtErrorDsRootCantBeSubref 8326 +#define kNtErrorDsNoChaining 8327 +#define kNtErrorDsNoChainedEval 8328 +#define kNtErrorDsNoParentObject 8329 +#define kNtErrorDsParentIsAnAlias 8330 +#define kNtErrorDsCantMixMasterAndReps 8331 +#define kNtErrorDsChildrenExist 8332 +#define kNtErrorDsObjNotFound 8333 +#define kNtErrorDsAliasedObjMissing 8334 +#define kNtErrorDsBadNameSyntax 8335 +#define kNtErrorDsAliasPointsToAlias 8336 +#define kNtErrorDsCantDerefAlias 8337 +#define kNtErrorDsOutOfScope 8338 +#define kNtErrorDsObjectBeingRemoved 8339 +#define kNtErrorDsCantDeleteDsaObj 8340 +#define kNtErrorDsGenericError 8341 +#define kNtErrorDsDsaMustBeIntMaster 8342 +#define kNtErrorDsClassNotDsa 8343 +#define kNtErrorDsInsuffAccessRights 8344 +#define kNtErrorDsIllegalSuperior 8345 +#define kNtErrorDsAttributeOwnedBySam 8346 +#define kNtErrorDsNameTooManyParts 8347 +#define kNtErrorDsNameTooLong 8348 +#define kNtErrorDsNameValueTooLong 8349 +#define kNtErrorDsNameUnparseable 8350 +#define kNtErrorDsNameTypeUnknown 8351 +#define kNtErrorDsNotAnObject 8352 +#define kNtErrorDsSecDescTooShort 8353 +#define kNtErrorDsSecDescInvalid 8354 +#define kNtErrorDsNoDeletedName 8355 +#define kNtErrorDsSubrefMustHaveParent 8356 +#define kNtErrorDsNcnameMustBeNc 8357 +#define kNtErrorDsCantAddSystemOnly 8358 +#define kNtErrorDsClassMustBeConcrete 8359 +#define kNtErrorDsInvalidDmd 8360 +#define kNtErrorDsObjGuidExists 8361 +#define kNtErrorDsNotOnBacklink 8362 +#define kNtErrorDsNoCrossrefForNc 8363 +#define kNtErrorDsShuttingDown 8364 +#define kNtErrorDsUnknownOperation 8365 +#define kNtErrorDsInvalidRoleOwner 8366 +#define kNtErrorDsCouldntContactFsmo 8367 +#define kNtErrorDsCrossNcDnRename 8368 +#define kNtErrorDsCantModSystemOnly 8369 +#define kNtErrorDsReplicatorOnly 8370 +#define kNtErrorDsObjClassNotDefined 8371 +#define kNtErrorDsObjClassNotSubclass 8372 +#define kNtErrorDsNameReferenceInvalid 8373 +#define kNtErrorDsCrossRefExists 8374 +#define kNtErrorDsCantDelMasterCrossref 8375 +#define kNtErrorDsSubtreeNotifyNotNcHead 8376 +#define kNtErrorDsNotifyFilterTooComplex 8377 +#define kNtErrorDsDupRdn 8378 +#define kNtErrorDsDupOid 8379 +#define kNtErrorDsDupMapiId 8380 +#define kNtErrorDsDupSchemaIdGuid 8381 +#define kNtErrorDsDupLdapDisplayName 8382 +#define kNtErrorDsSemanticAttTest 8383 +#define kNtErrorDsSyntaxMismatch 8384 +#define kNtErrorDsExistsInMustHave 8385 +#define kNtErrorDsExistsInMayHave 8386 +#define kNtErrorDsNonexistentMayHave 8387 +#define kNtErrorDsNonexistentMustHave 8388 +#define kNtErrorDsAuxClsTestFail 8389 +#define kNtErrorDsNonexistentPossSup 8390 +#define kNtErrorDsSubClsTestFail 8391 +#define kNtErrorDsBadRdnAttIdSyntax 8392 +#define kNtErrorDsExistsInAuxCls 8393 +#define kNtErrorDsExistsInSubCls 8394 +#define kNtErrorDsExistsInPossSup 8395 +#define kNtErrorDsRecalcschemaFailed 8396 +#define kNtErrorDsTreeDeleteNotFinished 8397 +#define kNtErrorDsCantDelete 8398 +#define kNtErrorDsAttSchemaReqId 8399 +#define kNtErrorDsBadAttSchemaSyntax 8400 +#define kNtErrorDsCantCacheAtt 8401 +#define kNtErrorDsCantCacheClass 8402 +#define kNtErrorDsCantRemoveAttCache 8403 +#define kNtErrorDsCantRemoveClassCache 8404 +#define kNtErrorDsCantRetrieveDn 8405 +#define kNtErrorDsMissingSupref 8406 +#define kNtErrorDsCantRetrieveInstance 8407 +#define kNtErrorDsCodeInconsistency 8408 +#define kNtErrorDsDatabaseError 8409 +#define kNtErrorDsGovernsidMissing 8410 +#define kNtErrorDsMissingExpectedAtt 8411 +#define kNtErrorDsNcnameMissingCrRef 8412 +#define kNtErrorDsSecurityCheckingError 8413 +#define kNtErrorDsSchemaNotLoaded 8414 +#define kNtErrorDsSchemaAllocFailed 8415 +#define kNtErrorDsAttSchemaReqSyntax 8416 +#define kNtErrorDsGcverifyError 8417 +#define kNtErrorDsDraSchemaMismatch 8418 +#define kNtErrorDsCantFindDsaObj 8419 +#define kNtErrorDsCantFindExpectedNc 8420 +#define kNtErrorDsCantFindNcInCache 8421 +#define kNtErrorDsCantRetrieveChild 8422 +#define kNtErrorDsSecurityIllegalModify 8423 +#define kNtErrorDsCantReplaceHiddenRec 8424 +#define kNtErrorDsBadHierarchyFile 8425 +#define kNtErrorDsBuildHierarchyTableFailed 8426 +#define kNtErrorDsConfigParamMissing 8427 +#define kNtErrorDsCountingAbIndicesFailed 8428 +#define kNtErrorDsHierarchyTableMallocFailed 8429 +#define kNtErrorDsInternalFailure 8430 +#define kNtErrorDsUnknownError 8431 +#define kNtErrorDsRootRequiresClassTop 8432 +#define kNtErrorDsRefusingFsmoRoles 8433 +#define kNtErrorDsMissingFsmoSettings 8434 +#define kNtErrorDsUnableToSurrenderRoles 8435 +#define kNtErrorDsDraGeneric 8436 +#define kNtErrorDsDraInvalidParameter 8437 +#define kNtErrorDsDraBusy 8438 +#define kNtErrorDsDraBadDn 8439 +#define kNtErrorDsDraBadNc 8440 +#define kNtErrorDsDraDnExists 8441 +#define kNtErrorDsDraInternalError 8442 +#define kNtErrorDsDraInconsistentDit 8443 +#define kNtErrorDsDraConnectionFailed 8444 +#define kNtErrorDsDraBadInstanceType 8445 +#define kNtErrorDsDraOutOfMem 8446 +#define kNtErrorDsDraMailProblem 8447 +#define kNtErrorDsDraRefAlreadyExists 8448 +#define kNtErrorDsDraRefNotFound 8449 +#define kNtErrorDsDraObjIsRepSource 8450 +#define kNtErrorDsDraDbError 8451 +#define kNtErrorDsDraNoReplica 8452 +#define kNtErrorDsDraAccessDenied 8453 +#define kNtErrorDsDraNotSupported 8454 +#define kNtErrorDsDraRpcCancelled 8455 +#define kNtErrorDsDraSourceDisabled 8456 +#define kNtErrorDsDraSinkDisabled 8457 +#define kNtErrorDsDraNameCollision 8458 +#define kNtErrorDsDraSourceReinstalled 8459 +#define kNtErrorDsDraMissingParent 8460 +#define kNtErrorDsDraPreempted 8461 +#define kNtErrorDsDraAbandonSync 8462 +#define kNtErrorDsDraShutdown 8463 +#define kNtErrorDsDraIncompatiblePartialSet 8464 +#define kNtErrorDsDraSourceIsPartialReplica 8465 +#define kNtErrorDsDraExtnConnectionFailed 8466 +#define kNtErrorDsInstallSchemaMismatch 8467 +#define kNtErrorDsDupLinkId 8468 +#define kNtErrorDsNameErrorResolving 8469 +#define kNtErrorDsNameErrorNotFound 8470 +#define kNtErrorDsNameErrorNotUnique 8471 +#define kNtErrorDsNameErrorNoMapping 8472 +#define kNtErrorDsNameErrorDomainOnly 8473 +#define kNtErrorDsNameErrorNoSyntacticalMapping 8474 +#define kNtErrorDsConstructedAttMod 8475 +#define kNtErrorDsWrongOmObjClass 8476 +#define kNtErrorDsDraReplPending 8477 +#define kNtErrorDsDsRequired 8478 +#define kNtErrorDsInvalidLdapDisplayName 8479 +#define kNtErrorDsNonBaseSearch 8480 +#define kNtErrorDsCantRetrieveAtts 8481 +#define kNtErrorDsBacklinkWithoutLink 8482 +#define kNtErrorDsEpochMismatch 8483 +#define kNtErrorDsSrcNameMismatch 8484 +#define kNtErrorDsSrcAndDstNcIdentical 8485 +#define kNtErrorDsDstNcMismatch 8486 +#define kNtErrorDsNotAuthoritiveForDstNc 8487 +#define kNtErrorDsSrcGuidMismatch 8488 +#define kNtErrorDsCantMoveDeletedObject 8489 +#define kNtErrorDsPdcOperationInProgress 8490 +#define kNtErrorDsCrossDomainCleanupReqd 8491 +#define kNtErrorDsIllegalXdomMoveOperation 8492 +#define kNtErrorDsCantWithAcctGroupMembershps 8493 +#define kNtErrorDsNcMustHaveNcParent 8494 +#define kNtErrorDsCrImpossibleToValidate 8495 +#define kNtErrorDsDstDomainNotNative 8496 +#define kNtErrorDsMissingInfrastructureContainer 8497 +#define kNtErrorDsCantMoveAccountGroup 8498 +#define kNtErrorDsCantMoveResourceGroup 8499 +#define kNtErrorDsInvalidSearchFlag 8500 +#define kNtErrorDsNoTreeDeleteAboveNc 8501 +#define kNtErrorDsCouldntLockTreeForDelete 8502 +#define kNtErrorDsCouldntIdentifyObjectsForTreeDelete 8503 +#define kNtErrorDsSamInitFailure 8504 +#define kNtErrorDsSensitiveGroupViolation 8505 +#define kNtErrorDsCantModPrimarygroupid 8506 +#define kNtErrorDsIllegalBaseSchemaMod 8507 +#define kNtErrorDsNonsafeSchemaChange 8508 +#define kNtErrorDsSchemaUpdateDisallowed 8509 +#define kNtErrorDsCantCreateUnderSchema 8510 +#define kNtErrorDsInstallNoSrcSchVersion 8511 +#define kNtErrorDsInstallNoSchVersionInInifile 8512 +#define kNtErrorDsInvalidGroupType 8513 +#define kNtErrorDsNoNestGlobalgroupInMixeddomain 8514 +#define kNtErrorDsNoNestLocalgroupInMixeddomain 8515 +#define kNtErrorDsGlobalCantHaveLocalMember 8516 +#define kNtErrorDsGlobalCantHaveUniversalMember 8517 +#define kNtErrorDsUniversalCantHaveLocalMember 8518 +#define kNtErrorDsGlobalCantHaveCrossdomainMember 8519 +#define kNtErrorDsLocalCantHaveCrossdomainLocalMember 8520 +#define kNtErrorDsHavePrimaryMembers 8521 +#define kNtErrorDsStringSdConversionFailed 8522 +#define kNtErrorDsNamingMasterGc 8523 +#define kNtErrorDsDnsLookupFailure 8524 +#define kNtErrorDsCouldntUpdateSpns 8525 +#define kNtErrorDsCantRetrieveSd 8526 +#define kNtErrorDsKeyNotUnique 8527 +#define kNtErrorDsWrongLinkedAttSyntax 8528 +#define kNtErrorDsSamNeedBootkeyPassword 8529 +#define kNtErrorDsSamNeedBootkeyFloppy 8530 +#define kNtErrorDsCantStart 8531 +#define kNtErrorDsInitFailure 8532 +#define kNtErrorDsNoPktPrivacyOnConnection 8533 +#define kNtErrorDsSourceDomainInForest 8534 +#define kNtErrorDsDestinationDomainNotInForest 8535 +#define kNtErrorDsDestinationAuditingNotEnabled 8536 +#define kNtErrorDsCantFindDcForSrcDomain 8537 +#define kNtErrorDsSrcObjNotGroupOrUser 8538 +#define kNtErrorDsSrcSidExistsInForest 8539 +#define kNtErrorDsSrcAndDstObjectClassMismatch 8540 +#define kNtErrorSamInitFailure 8541 +#define kNtErrorDsDraSchemaInfoShip 8542 +#define kNtErrorDsDraSchemaConflict 8543 +#define kNtErrorDsDraEarlierSchemaConflict 8544 +#define kNtErrorDsDraObjNcMismatch 8545 +#define kNtErrorDsNcStillHasDsas 8546 +#define kNtErrorDsGcRequired 8547 +#define kNtErrorDsLocalMemberOfLocalOnly 8548 +#define kNtErrorDsNoFpoInUniversalGroups 8549 +#define kNtErrorDsCantAddToGc 8550 +#define kNtErrorDsNoCheckpointWithPdc 8551 +#define kNtErrorDsSourceAuditingNotEnabled 8552 +#define kNtErrorDsCantCreateInNondomainNc 8553 +#define kNtErrorDsInvalidNameForSpn 8554 +#define kNtErrorDsFilterUsesContructedAttrs 8555 +#define kNtErrorDsUnicodepwdNotInQuotes 8556 +#define kNtErrorDsMachineAccountQuotaExceeded 8557 +#define kNtErrorDsMustBeRunOnDstDc 8558 +#define kNtErrorDsSrcDcMustBeSp4OrGreater 8559 +#define kNtErrorDsCantTreeDeleteCriticalObj 8560 +#define kNtErrorDsInitFailureConsole 8561 +#define kNtErrorDsSamInitFailureConsole 8562 +#define kNtErrorDsForestVersionTooHigh 8563 +#define kNtErrorDsDomainVersionTooHigh 8564 +#define kNtErrorDsForestVersionTooLow 8565 +#define kNtErrorDsDomainVersionTooLow 8566 +#define kNtErrorDsIncompatibleVersion 8567 +#define kNtErrorDsLowDsaVersion 8568 +#define kNtErrorDsNoBehaviorVersionInMixeddomain 8569 +#define kNtErrorDsNotSupportedSortOrder 8570 +#define kNtErrorDsNameNotUnique 8571 +#define kNtErrorDsMachineAccountCreatedPrent4 8572 +#define kNtErrorDsOutOfVersionStore 8573 +#define kNtErrorDsIncompatibleControlsUsed 8574 +#define kNtErrorDsNoRefDomain 8575 +#define kNtErrorDsReservedLinkId 8576 +#define kNtErrorDsLinkIdNotAvailable 8577 +#define kNtErrorDsAgCantHaveUniversalMember 8578 +#define kNtErrorDsModifydnDisallowedByInstanceType 8579 +#define kNtErrorDsNoObjectMoveInSchemaNc 8580 +#define kNtErrorDsModifydnDisallowedByFlag 8581 +#define kNtErrorDsModifydnWrongGrandparent 8582 +#define kNtErrorDsNameErrorTrustReferral 8583 +#define kNtErrorNotSupportedOnStandardServer 8584 +#define kNtErrorDsCantAccessRemotePartOfAd 8585 +#define kNtErrorDsCrImpossibleToValidateV2 8586 +#define kNtErrorDsThreadLimitExceeded 8587 +#define kNtErrorDsNotClosest 8588 +#define kNtErrorDsCantDeriveSpnWithoutServerRef 8589 +#define kNtErrorDsSingleUserModeFailed 8590 +#define kNtErrorDsNtdscriptSyntaxError 8591 +#define kNtErrorDsNtdscriptProcessError 8592 +#define kNtErrorDsDifferentReplEpochs 8593 +#define kNtErrorDsDrsExtensionsChanged 8594 +#define kNtErrorDsReplicaSetChangeNotAllowedOnDisabledCr 8595 +#define kNtErrorDsNoMsdsIntid 8596 +#define kNtErrorDsDupMsdsIntid 8597 +#define kNtErrorDsExistsInRdnattid 8598 +#define kNtErrorDsAuthorizationFailed 8599 +#define kNtErrorDsInvalidScript 8600 +#define kNtErrorDsRemoteCrossrefOpFailed 8601 +#define kNtErrorDsCrossRefBusy 8602 +#define kNtErrorDsCantDeriveSpnForDeletedDomain 8603 +#define kNtErrorDsCantDemoteWithWriteableNc 8604 +#define kNtErrorDsDuplicateIdFound 8605 +#define kNtErrorDsInsufficientAttrToCreateObject 8606 +#define kNtErrorDsGroupConversionError 8607 +#define kNtErrorDsCantMoveAppBasicGroup 8608 +#define kNtErrorDsCantMoveAppQueryGroup 8609 +#define kNtErrorDsRoleNotVerified 8610 +#define kNtErrorDsWkoContainerCannotBeSpecial 8611 +#define kNtErrorDsDomainRenameInProgress 8612 +#define kNtErrorDsExistingAdChildNc 8613 +#define kNtErrorDsReplLifetimeExceeded 8614 +#define kNtErrorDsDisallowedInSystemContainer 8615 +#define kNtErrorDsLdapSendQueueFull 8616 +#define kNtErrorDsDraOutScheduleWindow 8617 +#define kNtErrorDsPolicyNotKnown 8618 +#define kNtErrorNoSiteSettingsObject 8619 +#define kNtErrorNoSecrets 8620 +#define kNtErrorNoWritableDcFound 8621 +#define kNtErrorDsNoServerObject 8622 +#define kNtErrorDsNoNtdsaObject 8623 +#define kNtErrorDsNonAsqSearch 8624 +#define kNtErrorDsAuditFailure 8625 +#define kNtErrorDsInvalidSearchFlagSubtree 8626 +#define kNtErrorDsInvalidSearchFlagTuple 8627 +#define kNtErrorDsHierarchyTableTooDeep 8628 +#define kNtErrorDsDraCorruptUtdVector 8629 +#define kNtErrorDsDraSecretsDenied 8630 +#define kNtErrorDsReservedMapiId 8631 +#define kNtErrorDsMapiIdNotAvailable 8632 +#define kNtErrorDsDraMissingKrbtgtSecret 8633 +#define kNtErrorDsDomainNameExistsInForest 8634 +#define kNtErrorDsFlatNameExistsInForest 8635 +#define kNtErrorInvalidUserPrincipalName 8636 +#define kNtErrorDsOidMappedGroupCantHaveMembers 8637 +#define kNtErrorDsOidNotFound 8638 +#define kNtErrorDsDraRecycledTarget 8639 +#define kNtErrorDsDisallowedNcRedirect 8640 +#define kNtErrorDsHighAdldsFfl 8641 +#define kNtErrorDsHighDsaVersion 8642 +#define kNtErrorDsLowAdldsFfl 8643 +#define kNtErrorDomainSidSameAsLocalWorkstation 8644 +#define kNtErrorDsUndeleteSamValidationFailed 8645 +#define kNtErrorIncorrectAccountType 8646 +#define kNtErrorDsSpnValueNotUniqueInForest 8647 +#define kNtErrorDsUpnValueNotUniqueInForest 8648 +#define kNtErrorDsMissingForestTrust 8649 +#define kNtErrorDsValueKeyNotUnique 8650 +#define kNtErrorIpsecQmPolicyExists 13000 +#define kNtErrorIpsecQmPolicyNotFound 13001 +#define kNtErrorIpsecQmPolicyInUse 13002 +#define kNtErrorIpsecMmPolicyExists 13003 +#define kNtErrorIpsecMmPolicyNotFound 13004 +#define kNtErrorIpsecMmPolicyInUse 13005 +#define kNtErrorIpsecMmFilterExists 13006 +#define kNtErrorIpsecMmFilterNotFound 13007 +#define kNtErrorIpsecTransportFilterExists 13008 +#define kNtErrorIpsecTransportFilterNotFound 13009 +#define kNtErrorIpsecMmAuthExists 13010 +#define kNtErrorIpsecMmAuthNotFound 13011 +#define kNtErrorIpsecMmAuthInUse 13012 +#define kNtErrorIpsecDefaultMmPolicyNotFound 13013 +#define kNtErrorIpsecDefaultMmAuthNotFound 13014 +#define kNtErrorIpsecDefaultQmPolicyNotFound 13015 +#define kNtErrorIpsecTunnelFilterExists 13016 +#define kNtErrorIpsecTunnelFilterNotFound 13017 +#define kNtErrorIpsecMmFilterPendingDeletion 13018 +#define kNtErrorIpsecTransportFilterPendingDeletion 13019 +#define kNtErrorIpsecTunnelFilterPendingDeletion 13020 +#define kNtErrorIpsecMmPolicyPendingDeletion 13021 +#define kNtErrorIpsecMmAuthPendingDeletion 13022 +#define kNtErrorIpsecQmPolicyPendingDeletion 13023 +#define kNtErrorIpsecIkeNegStatusBegin 13800 +#define kNtErrorIpsecIkeAuthFail 13801 +#define kNtErrorIpsecIkeAttribFail 13802 +#define kNtErrorIpsecIkeNegotiationPending 13803 +#define kNtErrorIpsecIkeGeneralProcessingError 13804 +#define kNtErrorIpsecIkeTimedOut 13805 +#define kNtErrorIpsecIkeNoCert 13806 +#define kNtErrorIpsecIkeSaDeleted 13807 +#define kNtErrorIpsecIkeSaReaped 13808 +#define kNtErrorIpsecIkeMmAcquireDrop 13809 +#define kNtErrorIpsecIkeQmAcquireDrop 13810 +#define kNtErrorIpsecIkeQueueDropMm 13811 +#define kNtErrorIpsecIkeQueueDropNoMm 13812 +#define kNtErrorIpsecIkeDropNoResponse 13813 +#define kNtErrorIpsecIkeMmDelayDrop 13814 +#define kNtErrorIpsecIkeQmDelayDrop 13815 +#define kNtErrorIpsecIkeError 13816 +#define kNtErrorIpsecIkeCrlFailed 13817 +#define kNtErrorIpsecIkeInvalidKeyUsage 13818 +#define kNtErrorIpsecIkeInvalidCertType 13819 +#define kNtErrorIpsecIkeNoPrivateKey 13820 +#define kNtErrorIpsecIkeSimultaneousRekey 13821 +#define kNtErrorIpsecIkeDhFail 13822 +#define kNtErrorIpsecIkeCriticalPayloadNotRecognized 13823 +#define kNtErrorIpsecIkeInvalidHeader 13824 +#define kNtErrorIpsecIkeNoPolicy 13825 +#define kNtErrorIpsecIkeInvalidSignature 13826 +#define kNtErrorIpsecIkeKerberosError 13827 +#define kNtErrorIpsecIkeNoPublicKey 13828 +#define kNtErrorIpsecIkeProcessErr 13829 +#define kNtErrorIpsecIkeProcessErrSa 13830 +#define kNtErrorIpsecIkeProcessErrProp 13831 +#define kNtErrorIpsecIkeProcessErrTrans 13832 +#define kNtErrorIpsecIkeProcessErrKe 13833 +#define kNtErrorIpsecIkeProcessErrId 13834 +#define kNtErrorIpsecIkeProcessErrCert 13835 +#define kNtErrorIpsecIkeProcessErrCertReq 13836 +#define kNtErrorIpsecIkeProcessErrHash 13837 +#define kNtErrorIpsecIkeProcessErrSig 13838 +#define kNtErrorIpsecIkeProcessErrNonce 13839 +#define kNtErrorIpsecIkeProcessErrNotify 13840 +#define kNtErrorIpsecIkeProcessErrDelete 13841 +#define kNtErrorIpsecIkeProcessErrVendor 13842 +#define kNtErrorIpsecIkeInvalidPayload 13843 +#define kNtErrorIpsecIkeLoadSoftSa 13844 +#define kNtErrorIpsecIkeSoftSaTornDown 13845 +#define kNtErrorIpsecIkeInvalidCookie 13846 +#define kNtErrorIpsecIkeNoPeerCert 13847 +#define kNtErrorIpsecIkePeerCrlFailed 13848 +#define kNtErrorIpsecIkePolicyChange 13849 +#define kNtErrorIpsecIkeNoMmPolicy 13850 +#define kNtErrorIpsecIkeNotcbpriv 13851 +#define kNtErrorIpsecIkeSecloadfail 13852 +#define kNtErrorIpsecIkeFailsspinit 13853 +#define kNtErrorIpsecIkeFailqueryssp 13854 +#define kNtErrorIpsecIkeSrvacqfail 13855 +#define kNtErrorIpsecIkeSrvquerycred 13856 +#define kNtErrorIpsecIkeGetspifail 13857 +#define kNtErrorIpsecIkeInvalidFilter 13858 +#define kNtErrorIpsecIkeOutOfMemory 13859 +#define kNtErrorIpsecIkeAddUpdateKeyFailed 13860 +#define kNtErrorIpsecIkeInvalidPolicy 13861 +#define kNtErrorIpsecIkeUnknownDoi 13862 +#define kNtErrorIpsecIkeInvalidSituation 13863 +#define kNtErrorIpsecIkeDhFailure 13864 +#define kNtErrorIpsecIkeInvalidGroup 13865 +#define kNtErrorIpsecIkeEncrypt 13866 +#define kNtErrorIpsecIkeDecrypt 13867 +#define kNtErrorIpsecIkePolicyMatch 13868 +#define kNtErrorIpsecIkeUnsupportedId 13869 +#define kNtErrorIpsecIkeInvalidHash 13870 +#define kNtErrorIpsecIkeInvalidHashAlg 13871 +#define kNtErrorIpsecIkeInvalidHashSize 13872 +#define kNtErrorIpsecIkeInvalidEncryptAlg 13873 +#define kNtErrorIpsecIkeInvalidAuthAlg 13874 +#define kNtErrorIpsecIkeInvalidSig 13875 +#define kNtErrorIpsecIkeLoadFailed 13876 +#define kNtErrorIpsecIkeRpcDelete 13877 +#define kNtErrorIpsecIkeBenignReinit 13878 +#define kNtErrorIpsecIkeInvalidResponderLifetimeNotify 13879 +#define kNtErrorIpsecIkeInvalidMajorVersion 13880 +#define kNtErrorIpsecIkeInvalidCertKeylen 13881 +#define kNtErrorIpsecIkeMmLimit 13882 +#define kNtErrorIpsecIkeNegotiationDisabled 13883 +#define kNtErrorIpsecIkeQmLimit 13884 +#define kNtErrorIpsecIkeMmExpired 13885 +#define kNtErrorIpsecIkePeerMmAssumedInvalid 13886 +#define kNtErrorIpsecIkeCertChainPolicyMismatch 13887 +#define kNtErrorIpsecIkeUnexpectedMessageId 13888 +#define kNtErrorIpsecIkeInvalidAuthPayload 13889 +#define kNtErrorIpsecIkeDosCookieSent 13890 +#define kNtErrorIpsecIkeShuttingDown 13891 +#define kNtErrorIpsecIkeCgaAuthFailed 13892 +#define kNtErrorIpsecIkeProcessErrNatoa 13893 +#define kNtErrorIpsecIkeInvalidMmForQm 13894 +#define kNtErrorIpsecIkeQmExpired 13895 +#define kNtErrorIpsecIkeTooManyFilters 13896 +#define kNtErrorIpsecIkeNegStatusEnd 13897 +#define kNtErrorIpsecIkeKillDummyNapTunnel 13898 +#define kNtErrorIpsecIkeInnerIpAssignmentFailure 13899 +#define kNtErrorIpsecIkeRequireCpPayloadMissing 13900 +#define kNtErrorIpsecKeyModuleImpersonationNegotiationPending 13901 +#define kNtErrorIpsecIkeCoexistenceSuppress 13902 +#define kNtErrorIpsecIkeRatelimitDrop 13903 +#define kNtErrorIpsecIkePeerDoesntSupportMobike 13904 +#define kNtErrorIpsecIkeAuthorizationFailure 13905 +#define kNtErrorIpsecIkeStrongCredAuthorizationFailure 13906 +#define kNtErrorIpsecIkeAuthorizationFailureWithOptionalRetry 13907 +#define kNtErrorIpsecIkeStrongCredAuthorizationAndCertmapFailure 13908 +#define kNtErrorIpsecIkeNegStatusExtendedEnd 13909 +#define kNtErrorIpsecBadSpi 13910 +#define kNtErrorIpsecSaLifetimeExpired 13911 +#define kNtErrorIpsecWrongSa 13912 +#define kNtErrorIpsecReplayCheckFailed 13913 +#define kNtErrorIpsecInvalidPacket 13914 +#define kNtErrorIpsecIntegrityCheckFailed 13915 +#define kNtErrorIpsecClearTextDrop 13916 +#define kNtErrorIpsecAuthFirewallDrop 13917 +#define kNtErrorIpsecThrottleDrop 13918 +#define kNtErrorIpsecDospBlock 13925 +#define kNtErrorIpsecDospReceivedMulticast 13926 +#define kNtErrorIpsecDospInvalidPacket 13927 +#define kNtErrorIpsecDospStateLookupFailed 13928 +#define kNtErrorIpsecDospMaxEntries 13929 +#define kNtErrorIpsecDospKeymodNotAllowed 13930 +#define kNtErrorIpsecDospNotInstalled 13931 +#define kNtErrorIpsecDospMaxPerIpRatelimitQueues 13932 +#define kNtErrorSxsSectionNotFound 14000 +#define kNtErrorSxsCantGenActctx 14001 +#define kNtErrorSxsInvalidActctxdataFormat 14002 +#define kNtErrorSxsAssemblyNotFound 14003 +#define kNtErrorSxsManifestFormatError 14004 +#define kNtErrorSxsManifestParseError 14005 +#define kNtErrorSxsActivationContextDisabled 14006 +#define kNtErrorSxsKeyNotFound 14007 +#define kNtErrorSxsVersionConflict 14008 +#define kNtErrorSxsWrongSectionType 14009 +#define kNtErrorSxsThreadQueriesDisabled 14010 +#define kNtErrorSxsProcessDefaultAlreadySet 14011 +#define kNtErrorSxsUnknownEncodingGroup 14012 +#define kNtErrorSxsUnknownEncoding 14013 +#define kNtErrorSxsInvalidXmlNamespaceUri 14014 +#define kNtErrorSxsRootManifestDependencyNotInstalled 14015 +#define kNtErrorSxsLeafManifestDependencyNotInstalled 14016 +#define kNtErrorSxsInvalidAssemblyIdentityAttribute 14017 +#define kNtErrorSxsManifestMissingRequiredDefaultNamespace 14018 +#define kNtErrorSxsManifestInvalidRequiredDefaultNamespace 14019 +#define kNtErrorSxsPrivateManifestCrossPathWithReparsePoint 14020 +#define kNtErrorSxsDuplicateDllName 14021 +#define kNtErrorSxsDuplicateWindowclassName 14022 +#define kNtErrorSxsDuplicateClsid 14023 +#define kNtErrorSxsDuplicateIid 14024 +#define kNtErrorSxsDuplicateTlbid 14025 +#define kNtErrorSxsDuplicateProgid 14026 +#define kNtErrorSxsDuplicateAssemblyName 14027 +#define kNtErrorSxsFileHashMismatch 14028 +#define kNtErrorSxsPolicyParseError 14029 +#define kNtErrorSxsXmlEMissingquote 14030 +#define kNtErrorSxsXmlECommentsyntax 14031 +#define kNtErrorSxsXmlEBadstartnamechar 14032 +#define kNtErrorSxsXmlEBadnamechar 14033 +#define kNtErrorSxsXmlEBadcharinstring 14034 +#define kNtErrorSxsXmlEXmldeclsyntax 14035 +#define kNtErrorSxsXmlEBadchardata 14036 +#define kNtErrorSxsXmlEMissingwhitespace 14037 +#define kNtErrorSxsXmlEExpectingtagend 14038 +#define kNtErrorSxsXmlEMissingsemicolon 14039 +#define kNtErrorSxsXmlEUnbalancedparen 14040 +#define kNtErrorSxsXmlEInternalerror 14041 +#define kNtErrorSxsXmlEUnexpectedWhitespace 14042 +#define kNtErrorSxsXmlEIncompleteEncoding 14043 +#define kNtErrorSxsXmlEMissingParen 14044 +#define kNtErrorSxsXmlEExpectingclosequote 14045 +#define kNtErrorSxsXmlEMultipleColons 14046 +#define kNtErrorSxsXmlEInvalidDecimal 14047 +#define kNtErrorSxsXmlEInvalidHexidecimal 14048 +#define kNtErrorSxsXmlEInvalidUnicode 14049 +#define kNtErrorSxsXmlEWhitespaceorquestionmark 14050 +#define kNtErrorSxsXmlEUnexpectedendtag 14051 +#define kNtErrorSxsXmlEUnclosedtag 14052 +#define kNtErrorSxsXmlEDuplicateattribute 14053 +#define kNtErrorSxsXmlEMultipleroots 14054 +#define kNtErrorSxsXmlEInvalidatrootlevel 14055 +#define kNtErrorSxsXmlEBadxmldecl 14056 +#define kNtErrorSxsXmlEMissingroot 14057 +#define kNtErrorSxsXmlEUnexpectedeof 14058 +#define kNtErrorSxsXmlEBadperefinsubset 14059 +#define kNtErrorSxsXmlEUnclosedstarttag 14060 +#define kNtErrorSxsXmlEUnclosedendtag 14061 +#define kNtErrorSxsXmlEUnclosedstring 14062 +#define kNtErrorSxsXmlEUnclosedcomment 14063 +#define kNtErrorSxsXmlEUncloseddecl 14064 +#define kNtErrorSxsXmlEUnclosedcdata 14065 +#define kNtErrorSxsXmlEReservednamespace 14066 +#define kNtErrorSxsXmlEInvalidencoding 14067 +#define kNtErrorSxsXmlEInvalidswitch 14068 +#define kNtErrorSxsXmlEBadxmlcase 14069 +#define kNtErrorSxsXmlEInvalidStandalone 14070 +#define kNtErrorSxsXmlEUnexpectedStandalone 14071 +#define kNtErrorSxsXmlEInvalidVersion 14072 +#define kNtErrorSxsXmlEMissingequals 14073 +#define kNtErrorSxsProtectionRecoveryFailed 14074 +#define kNtErrorSxsProtectionPublicKeyTooShort 14075 +#define kNtErrorSxsProtectionCatalogNotValid 14076 +#define kNtErrorSxsUntranslatableHresult 14077 +#define kNtErrorSxsProtectionCatalogFileMissing 14078 +#define kNtErrorSxsMissingAssemblyIdentityAttribute 14079 +#define kNtErrorSxsInvalidAssemblyIdentityAttributeName 14080 +#define kNtErrorSxsAssemblyMissing 14081 +#define kNtErrorSxsCorruptActivationStack 14082 +#define kNtErrorSxsCorruption 14083 +#define kNtErrorSxsEarlyDeactivation 14084 +#define kNtErrorSxsInvalidDeactivation 14085 +#define kNtErrorSxsMultipleDeactivation 14086 +#define kNtErrorSxsProcessTerminationRequested 14087 +#define kNtErrorSxsReleaseActivationContext 14088 +#define kNtErrorSxsSystemDefaultActivationContextEmpty 14089 +#define kNtErrorSxsInvalidIdentityAttributeValue 14090 +#define kNtErrorSxsInvalidIdentityAttributeName 14091 +#define kNtErrorSxsIdentityDuplicateAttribute 14092 +#define kNtErrorSxsIdentityParseError 14093 +#define kNtErrorMalformedSubstitutionString 14094 +#define kNtErrorSxsIncorrectPublicKeyToken 14095 +#define kNtErrorUnmappedSubstitutionString 14096 +#define kNtErrorSxsAssemblyNotLocked 14097 +#define kNtErrorSxsComponentStoreCorrupt 14098 +#define kNtErrorAdvancedInstallerFailed 14099 +#define kNtErrorXmlEncodingMismatch 14100 +#define kNtErrorSxsManifestIdentitySameButContentsDifferent 14101 +#define kNtErrorSxsIdentitiesDifferent 14102 +#define kNtErrorSxsAssemblyIsNotADeployment 14103 +#define kNtErrorSxsFileNotPartOfAssembly 14104 +#define kNtErrorSxsManifestTooBig 14105 +#define kNtErrorSxsSettingNotRegistered 14106 +#define kNtErrorSxsTransactionClosureIncomplete 14107 +#define kNtErrorSmiPrimitiveInstallerFailed 14108 +#define kNtErrorGenericCommandFailed 14109 +#define kNtErrorSxsFileHashMissing 14110 +#define kNtErrorEvtInvalidChannelPath 15000 +#define kNtErrorEvtInvalidQuery 15001 +#define kNtErrorEvtPublisherMetadataNotFound 15002 +#define kNtErrorEvtEventTemplateNotFound 15003 +#define kNtErrorEvtInvalidPublisherName 15004 +#define kNtErrorEvtInvalidEventData 15005 +#define kNtErrorEvtChannelNotFound 15007 +#define kNtErrorEvtMalformedXmlText 15008 +#define kNtErrorEvtSubscriptionToDirectChannel 15009 +#define kNtErrorEvtConfigurationError 15010 +#define kNtErrorEvtQueryResultStale 15011 +#define kNtErrorEvtQueryResultInvalidPosition 15012 +#define kNtErrorEvtNonValidatingMsxml 15013 +#define kNtErrorEvtFilterAlreadyscoped 15014 +#define kNtErrorEvtFilterNoteltset 15015 +#define kNtErrorEvtFilterInvarg 15016 +#define kNtErrorEvtFilterInvtest 15017 +#define kNtErrorEvtFilterInvtype 15018 +#define kNtErrorEvtFilterParseerr 15019 +#define kNtErrorEvtFilterUnsupportedop 15020 +#define kNtErrorEvtFilterUnexpectedtoken 15021 +#define kNtErrorEvtInvalidOperationOverEnabledDirectChannel 15022 +#define kNtErrorEvtInvalidChannelPropertyValue 15023 +#define kNtErrorEvtInvalidPublisherPropertyValue 15024 +#define kNtErrorEvtChannelCannotActivate 15025 +#define kNtErrorEvtFilterTooComplex 15026 +#define kNtErrorEvtMessageNotFound 15027 +#define kNtErrorEvtMessageIdNotFound 15028 +#define kNtErrorEvtUnresolvedValueInsert 15029 +#define kNtErrorEvtUnresolvedParameterInsert 15030 +#define kNtErrorEvtMaxInsertsReached 15031 +#define kNtErrorEvtEventDefinitionNotFound 15032 +#define kNtErrorEvtMessageLocaleNotFound 15033 +#define kNtErrorEvtVersionTooOld 15034 +#define kNtErrorEvtVersionTooNew 15035 +#define kNtErrorEvtCannotOpenChannelOfQuery 15036 +#define kNtErrorEvtPublisherDisabled 15037 +#define kNtErrorEvtFilterOutOfRange 15038 +#define kNtErrorEcSubscriptionCannotActivate 15080 +#define kNtErrorEcLogDisabled 15081 +#define kNtErrorEcCircularForwarding 15082 +#define kNtErrorEcCredstoreFull 15083 +#define kNtErrorEcCredNotFound 15084 +#define kNtErrorEcNoActiveChannel 15085 +#define kNtErrorMuiFileNotFound 15100 +#define kNtErrorMuiInvalidFile 15101 +#define kNtErrorMuiInvalidRcConfig 15102 +#define kNtErrorMuiInvalidLocaleName 15103 +#define kNtErrorMuiInvalidUltimatefallbackName 15104 +#define kNtErrorMuiFileNotLoaded 15105 +#define kNtErrorResourceEnumUserStop 15106 +#define kNtErrorMuiIntlsettingsUilangNotInstalled 15107 +#define kNtErrorMuiIntlsettingsInvalidLocaleName 15108 +#define kNtErrorMrmRuntimeNoDefaultOrNeutralResource 15110 +#define kNtErrorMrmInvalidPriconfig 15111 +#define kNtErrorMrmInvalidFileType 15112 +#define kNtErrorMrmUnknownQualifier 15113 +#define kNtErrorMrmInvalidQualifierValue 15114 +#define kNtErrorMrmNoCandidate 15115 +#define kNtErrorMrmNoMatchOrDefaultCandidate 15116 +#define kNtErrorMrmResourceTypeMismatch 15117 +#define kNtErrorMrmDuplicateMapName 15118 +#define kNtErrorMrmDuplicateEntry 15119 +#define kNtErrorMrmInvalidResourceIdentifier 15120 +#define kNtErrorMrmFilepathTooLong 15121 +#define kNtErrorMrmUnsupportedDirectoryType 15122 +#define kNtErrorMrmInvalidPriFile 15126 +#define kNtErrorMrmNamedResourceNotFound 15127 +#define kNtErrorMrmMapNotFound 15135 +#define kNtErrorMrmUnsupportedProfileType 15136 +#define kNtErrorMrmInvalidQualifierOperator 15137 +#define kNtErrorMrmIndeterminateQualifierValue 15138 +#define kNtErrorMrmAutomergeEnabled 15139 +#define kNtErrorMrmTooManyResources 15140 +#define kNtErrorMrmUnsupportedFileTypeForMerge 15141 +#define kNtErrorMrmUnsupportedFileTypeForLoadUnloadPriFile 15142 +#define kNtErrorMrmNoCurrentViewOnThread 15143 +#define kNtErrorDifferentProfileResourceManagerExist 15144 +#define kNtErrorOperationNotAllowedFromSystemComponent 15145 +#define kNtErrorMrmDirectRefToNonDefaultResource 15146 +#define kNtErrorMrmGenerationCountMismatch 15147 +#define kNtErrorPriMergeVersionMismatch 15148 +#define kNtErrorPriMergeMissingSchema 15149 +#define kNtErrorPriMergeLoadFileFailed 15150 +#define kNtErrorPriMergeAddFileFailed 15151 +#define kNtErrorPriMergeWriteFileFailed 15152 +#define kNtErrorPriMergeMultiplePackageFamiliesNotAllowed 15153 +#define kNtErrorPriMergeMultipleMainPackagesNotAllowed 15154 +#define kNtErrorPriMergeBundlePackagesNotAllowed 15155 +#define kNtErrorPriMergeMainPackageRequired 15156 +#define kNtErrorPriMergeResourcePackageRequired 15157 +#define kNtErrorPriMergeInvalidFileName 15158 +#define kNtErrorMcaInvalidCapabilitiesString 15200 +#define kNtErrorMcaInvalidVcpVersion 15201 +#define kNtErrorMcaMonitorViolatesMccsSpecification 15202 +#define kNtErrorMcaMccsVersionMismatch 15203 +#define kNtErrorMcaUnsupportedMccsVersion 15204 +#define kNtErrorMcaInternalError 15205 +#define kNtErrorMcaInvalidTechnologyTypeReturned 15206 +#define kNtErrorMcaUnsupportedColorTemperature 15207 +#define kNtErrorAmbiguousSystemDevice 15250 +#define kNtErrorSystemDeviceNotFound 15299 +#define kNtErrorHashNotSupported 15300 +#define kNtErrorHashNotPresent 15301 +#define kNtErrorSecondaryIcProviderNotRegistered 15321 +#define kNtErrorGpioClientInformationInvalid 15322 +#define kNtErrorGpioVersionNotSupported 15323 +#define kNtErrorGpioInvalidRegistrationPacket 15324 +#define kNtErrorGpioOperationDenied 15325 +#define kNtErrorGpioIncompatibleConnectMode 15326 +#define kNtErrorGpioInterruptAlreadyUnmasked 15327 +#define kNtErrorCannotSwitchRunlevel 15400 +#define kNtErrorInvalidRunlevelSetting 15401 +#define kNtErrorRunlevelSwitchTimeout 15402 +#define kNtErrorRunlevelSwitchAgentTimeout 15403 +#define kNtErrorRunlevelSwitchInProgress 15404 +#define kNtErrorServicesFailedAutostart 15405 +#define kNtErrorComTaskStopPending 15501 +#define kNtErrorInstallOpenPackageFailed 15600 +#define kNtErrorInstallPackageNotFound 15601 +#define kNtErrorInstallInvalidPackage 15602 +#define kNtErrorInstallResolveDependencyFailed 15603 +#define kNtErrorInstallOutOfDiskSpace 15604 +#define kNtErrorInstallNetworkFailure 15605 +#define kNtErrorInstallRegistrationFailure 15606 +#define kNtErrorInstallDeregistrationFailure 15607 +#define kNtErrorInstallCancel 15608 +#define kNtErrorInstallFailed 15609 +#define kNtErrorRemoveFailed 15610 +#define kNtErrorPackageAlreadyExists 15611 +#define kNtErrorNeedsRemediation 15612 +#define kNtErrorInstallPrerequisiteFailed 15613 +#define kNtErrorPackageRepositoryCorrupted 15614 +#define kNtErrorInstallPolicyFailure 15615 +#define kNtErrorPackageUpdating 15616 +#define kNtErrorDeploymentBlockedByPolicy 15617 +#define kNtErrorPackagesInUse 15618 +#define kNtErrorRecoveryFileCorrupt 15619 +#define kNtErrorInvalidStagedSignature 15620 +#define kNtErrorDeletingExistingApplicationdataStoreFailed 15621 +#define kNtErrorInstallPackageDowngrade 15622 +#define kNtErrorSystemNeedsRemediation 15623 +#define kNtErrorAppxIntegrityFailureClrNgen 15624 +#define kNtErrorResiliencyFileCorrupt 15625 +#define kNtErrorInstallFirewallServiceNotRunning 15626 +#define kNtErrorPackageMoveFailed 15627 +#define kNtErrorInstallVolumeNotEmpty 15628 +#define kNtErrorInstallVolumeOffline 15629 +#define kNtErrorInstallVolumeCorrupt 15630 +#define kNtErrorNeedsRegistration 15631 +#define kNtErrorInstallWrongProcessorArchitecture 15632 +#define kNtErrorDevSideloadLimitExceeded 15633 +#define kNtErrorInstallOptionalPackageRequiresMainPackage 15634 +#define kNtErrorPackageNotSupportedOnFilesystem 15635 +#define kNtErrorPackageMoveBlockedByStreaming 15636 +#define kNtErrorInstallOptionalPackageApplicationidNotUnique 15637 +#define kNtErrorPackageStagingOnhold 15638 +#define kNtErrorInstallInvalidRelatedSetUpdate 15639 +#define kNtErrorPackagesReputationCheckFailed 15643 +#define kNtErrorPackagesReputationCheckTimedout 15644 +#define kNtErrorStateLoadStoreFailed 15800 +#define kNtErrorStateGetVersionFailed 15801 +#define kNtErrorStateSetVersionFailed 15802 +#define kNtErrorStateStructuredResetFailed 15803 +#define kNtErrorStateOpenContainerFailed 15804 +#define kNtErrorStateCreateContainerFailed 15805 +#define kNtErrorStateDeleteContainerFailed 15806 +#define kNtErrorStateReadSettingFailed 15807 +#define kNtErrorStateWriteSettingFailed 15808 +#define kNtErrorStateDeleteSettingFailed 15809 +#define kNtErrorStateQuerySettingFailed 15810 +#define kNtErrorStateReadCompositeSettingFailed 15811 +#define kNtErrorStateWriteCompositeSettingFailed 15812 +#define kNtErrorStateEnumerateContainerFailed 15813 +#define kNtErrorStateEnumerateSettingsFailed 15814 +#define kNtErrorStateCompositeSettingValueSizeLimitExceeded 15815 +#define kNtErrorStateSettingValueSizeLimitExceeded 15816 +#define kNtErrorStateSettingNameSizeLimitExceeded 15817 +#define kNtErrorStateContainerNameSizeLimitExceeded 15818 +#define kNtErrorApiUnavailable 15841 + +#define kNtWaitIoCompletion 0xc0 + +/* WinSock Error Codes: 10000-11999 */ +#define WSABASEERR 10000 +#define WSAEINTR 10004 +#define WSAEBADF 10009 +#define WSAEACCES 10013 +#define WSAEFAULT 10014 +#define WSAEINVAL 10022 +#define WSAEMFILE 10024 +#define WSAEWOULDBLOCK 10035 +#define WSAEINPROGRESS 10036 +#define WSAEALREADY 10037 +#define WSAENOTSOCK 10038 +#define WSAEDESTADDRREQ 10039 +#define WSAEMSGSIZE 10040 +#define WSAEPROTOTYPE 10041 +#define WSAENOPROTOOPT 10042 +#define WSAEPROTONOSUPPORT 10043 +#define WSAESOCKTNOSUPPORT 10044 +#define WSAEOPNOTSUPP 10045 +#define WSAEPFNOSUPPORT 10046 +#define WSAEAFNOSUPPORT 10047 +#define WSAEADDRINUSE 10048 +#define WSAEADDRNOTAVAIL 10049 +#define WSAENETDOWN 10050 +#define WSAENETUNREACH 10051 +#define WSAENETRESET 10052 +#define WSAECONNABORTED 10053 +#define WSAECONNRESET 10054 +#define WSAENOBUFS 10055 +#define WSAEISCONN 10056 +#define WSAENOTCONN 10057 +#define WSAESHUTDOWN 10058 +#define WSAETOOMANYREFS 10059 +#define WSAETIMEDOUT 10060 +#define WSAECONNREFUSED 10061 +#define WSAELOOP 10062 +#define WSAENAMETOOLONG 10063 +#define WSAEHOSTDOWN 10064 +#define WSAEHOSTUNREACH 10065 +#define WSAENOTEMPTY 10066 +#define WSAEPROCLIM 10067 +#define WSAEUSERS 10068 +#define WSAEDQUOT 10069 +#define WSAESTALE 10070 +#define WSAEREMOTE 10071 +#define WSASYSNOTREADY 10091 +#define WSAVERNOTSUPPORTED 10092 +#define WSANOTINITIALISED 10093 +#define WSAEDISCON 10101 +#define WSAENOMORE 10102 +#define WSAECANCELLED 10103 +#define WSAEINVALIDPROCTABLE 10104 +#define WSAEINVALIDPROVIDER 10105 +#define WSAEPROVIDERFAILEDINIT 10106 +#define WSASYSCALLFAILURE 10107 +#define WSASERVICE_NOT_FOUND 10108 +#define WSATYPE_NOT_FOUND 10109 +#define WSA_E_NO_MORE 10110 +#define WSA_E_CANCELLED 10111 +#define WSAEREFUSED 10112 +#define WSAHOST_NOT_FOUND 11001 +#define WSATRY_AGAIN 11002 +#define WSANO_RECOVERY 11003 +#define WSANO_DATA 11004 +#define WSA_QOS_RECEIVERS 11005 +#define WSA_QOS_SENDERS 11006 +#define WSA_QOS_NO_SENDERS 11007 +#define WSA_QOS_NO_RECEIVERS 11008 +#define WSA_QOS_REQUEST_CONFIRMED 11009 +#define WSA_QOS_ADMISSION_FAILURE 11010 +#define WSA_QOS_POLICY_FAILURE 11011 +#define WSA_QOS_BAD_STYLE 11012 +#define WSA_QOS_BAD_OBJECT 11013 +#define WSA_QOS_TRAFFIC_CTRL_ERROR 11014 +#define WSA_QOS_GENERIC_ERROR 11015 +#define WSA_QOS_ESERVICETYPE 11016 +#define WSA_QOS_EFLOWSPEC 11017 +#define WSA_QOS_EPROVSPECBUF 11018 +#define WSA_QOS_EFILTERSTYLE 11019 +#define WSA_QOS_EFILTERTYPE 11020 +#define WSA_QOS_EFILTERCOUNT 11021 +#define WSA_QOS_EOBJLENGTH 11022 +#define WSA_QOS_EFLOWCOUNT 11023 +#define WSA_QOS_EUNKOWNPSOBJ 11024 +#define WSA_QOS_EPOLICYOBJ 11025 +#define WSA_QOS_EFLOWDESC 11026 +#define WSA_QOS_EPSFLOWSPEC 11027 +#define WSA_QOS_EPSFILTERSPEC 11028 +#define WSA_QOS_ESDMODEOBJ 11029 +#define WSA_QOS_ESHAPERATEOBJ 11030 +#define WSA_QOS_RESERVED_PETYPE 11031 +#define WSA_SECURE_HOST_NOT_FOUND 11032 +#define WSA_IPSEC_NAME_POLICY_ERROR 11033 + +#define WSA_WAIT_FAILED -1u +#define WSA_WAIT_EVENT_0 0 +#define WSA_WAIT_IO_COMPLETION 0xc0 +#define WSA_WAIT_TIMEOUT 258 +#define WSA_MAXIMUM_WAIT_EVENTS 64 +#define WSA_IO_PENDING 997 + +#endif /* COSMOPOLITAN_NT_ERRORS_H_ */ diff --git a/libc/nt/events.h b/libc/nt/events.h new file mode 100644 index 00000000..683b3486 --- /dev/null +++ b/libc/nt/events.h @@ -0,0 +1,97 @@ +#ifndef COSMOPOLITAN_LIBC_NT_EVENTS_H_ +#define COSMOPOLITAN_LIBC_NT_EVENTS_H_ +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » events ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +#define NT_EVENT_SYSTEM_SOUND 0x0001 +#define NT_EVENT_SYSTEM_ALERT 0x0002 +#define NT_EVENT_SYSTEM_FOREGROUND 0x0003 +#define NT_EVENT_SYSTEM_MENUSTART 0x0004 +#define NT_EVENT_SYSTEM_MENUEND 0x0005 +#define NT_EVENT_SYSTEM_MENUPOPUPSTART 0x0006 +#define NT_EVENT_SYSTEM_MENUPOPUPEND 0x0007 +#define NT_EVENT_SYSTEM_CAPTURESTART 0x0008 +#define NT_EVENT_SYSTEM_CAPTUREEND 0x0009 +#define NT_EVENT_SYSTEM_MOVESIZESTART 0x000A +#define NT_EVENT_SYSTEM_MOVESIZEEND 0x000B +#define NT_EVENT_SYSTEM_CONTEXTHELPSTART 0x000C +#define NT_EVENT_SYSTEM_CONTEXTHELPEND 0x000D +#define NT_EVENT_SYSTEM_DRAGDROPSTART 0x000E +#define NT_EVENT_SYSTEM_DRAGDROPEND 0x000F +#define NT_EVENT_SYSTEM_DIALOGSTART 0x0010 +#define NT_EVENT_SYSTEM_DIALOGEND 0x0011 +#define NT_EVENT_SYSTEM_SCROLLINGSTART 0x0012 +#define NT_EVENT_SYSTEM_SCROLLINGEND 0x0013 +#define NT_EVENT_SYSTEM_SWITCHSTART 0x0014 +#define NT_EVENT_SYSTEM_SWITCHEND 0x0015 +#define NT_EVENT_SYSTEM_MINIMIZESTART 0x0016 +#define NT_EVENT_SYSTEM_MINIMIZEEND 0x0017 + +#define NT_EVENT_CONSOLE_CARET 0x4001 +#define NT_EVENT_CONSOLE_UPDATE_REGION 0x4002 +#define NT_EVENT_CONSOLE_UPDATE_SIMPLE 0x4003 +#define NT_EVENT_CONSOLE_UPDATE_SCROLL 0x4004 +#define NT_EVENT_CONSOLE_LAYOUT 0x4005 +#define NT_EVENT_CONSOLE_START_APPLICATION 0x4006 +#define NT_EVENT_CONSOLE_END_APPLICATION 0x4007 + +#define NT_EVENT_OBJECT_CREATE 0x8000 +#define NT_EVENT_OBJECT_DESTROY 0x8001 +#define NT_EVENT_OBJECT_SHOW 0x8002 +#define NT_EVENT_OBJECT_HIDE 0x8003 +#define NT_EVENT_OBJECT_REORDER 0x8004 +#define NT_EVENT_OBJECT_FOCUS 0x8005 +#define NT_EVENT_OBJECT_SELECTION 0x8006 +#define NT_EVENT_OBJECT_SELECTIONADD 0x8007 +#define NT_EVENT_OBJECT_SELECTIONREMOVE 0x8008 +#define NT_EVENT_OBJECT_SELECTIONWITHIN 0x8009 +#define NT_EVENT_OBJECT_STATECHANGE 0x800A +#define NT_EVENT_OBJECT_LOCATIONCHANGE 0x800B +#define NT_EVENT_OBJECT_NAMECHANGE 0x800C +#define NT_EVENT_OBJECT_DESCRIPTIONCHANGE 0x800D +#define NT_EVENT_OBJECT_VALUECHANGE 0x800E +#define NT_EVENT_OBJECT_PARENTCHANGE 0x800F +#define NT_EVENT_OBJECT_HELPCHANGE 0x8010 +#define NT_EVENT_OBJECT_DEFACTIONCHANGE 0x8011 +#define NT_EVENT_OBJECT_ACCELERATORCHANGE 0x8012 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtMsg; +struct NtPoint; + +int32_t GetMessage(struct NtMsg *lpMsg, int64_t hWnd, uint32_t wMsgFilterMin, + uint32_t wMsgFilterMax); +int32_t TranslateMessage(const struct NtMsg *lpMsg); +intptr_t DispatchMessage(const struct NtMsg *lpMsg); +void PostQuitMessage(int nExitCode); +bool32 GetCursorPos(struct NtPoint *lpPoint); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_EVENTS_H_ */ diff --git a/libc/nt/files.h b/libc/nt/files.h new file mode 100644 index 00000000..41013381 --- /dev/null +++ b/libc/nt/files.h @@ -0,0 +1,257 @@ +#ifndef COSMOPOLITAN_LIBC_NT_FILES_H_ +#define COSMOPOLITAN_LIBC_NT_FILES_H_ +#include "libc/nt/enum/accessmask.h" +#include "libc/nt/enum/fileinfobyhandleclass.h" +#include "libc/nt/enum/filemovemethod.h" +#include "libc/nt/enum/filesharemode.h" +#include "libc/nt/enum/findexinfolevels.h" +#include "libc/nt/enum/findexsearchops.h" +#include "libc/nt/enum/getfileexinfolevels.h" +#include "libc/nt/enum/movefileexflags.h" +#include "libc/nt/enum/securityimpersonationlevel.h" +#include "libc/nt/enum/securityinformation.h" +#include "libc/nt/enum/tokentype.h" +#include "libc/nt/struct/filesegmentelement.h" +#include "libc/nt/struct/filetime.h" +#include "libc/nt/thunk/msabi.h" +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » files ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +/* CopyFileEx */ +#define NT_PROGRESS_CONTINUE 0 +#define NT_PROGRESS_CANCEL 1 +#define NT_PROGRESS_STOP 2 +#define NT_PROGRESS_QUIET 3 +#define NT_CALLBACK_CHUNK_FINISHED 0x00000000 +#define NT_CALLBACK_STREAM_SWITCH 0x00000001 +#define NT_COPY_FILE_FAIL_IF_EXISTS 0x00000001 +#define NT_COPY_FILE_RESTARTABLE 0x00000002 +#define NT_COPY_FILE_OPEN_SOURCE_FOR_WRITE 0x00000004 +#define NT_COPY_FILE_ALLOW_DECRYPTED_DESTINATION 0x00000008 +#define NT_COPY_FILE_COPY_SYMLINK 0x00000800 +#define NT_COPY_FILE_NO_BUFFERING 0x00001000 +#define NT_COPY_FILE_REQUEST_SECURITY_PRIVILEGES 0x00002000 /* Win8+ */ +#define NT_COPY_FILE_RESUME_FROM_PAUSE 0x00004000 /* Win8+ */ +#define NT_COPY_FILE_REQUEST_SECURITY_PRIVILEGES 0x00002000 /* Win8+ */ +#define NT_COPY_FILE_NO_OFFLOAD 0x00040000 /* Win8+ */ +#define NT_COPY_FILE_IGNORE_EDP_BLOCK 0x00400000 /* Win10+ */ +#define NT_COPY_FILE_IGNORE_SOURCE_ENCRYPTION 0x00800000 /* Win10+ */ + +/* ReplaceFile */ +#define NT_REPLACEFILE_WRITE_THROUGH 0x00000001 +#define NT_REPLACEFILE_IGNORE_MERGE_ERRORS 0x00000002 +#define NT_REPLACEFILE_IGNORE_ACL_ERRORS 0x00000004 +#define NT_REPLACEFILE_WRITE_THROUGH 0x00000001 +#define NT_REPLACEFILE_IGNORE_MERGE_ERRORS 0x00000002 +#define NT_REPLACEFILE_IGNORE_ACL_ERRORS 0x00000004 + +/* SetHandleInformation */ +#define kNtHandleFlagInherit 0x00000001 +#define kNtHandleFlagProtectFromClose 0x00000002 + +#define kNtFindFirstExCaseSensitive 0x00000001 +#define kNtFindFirstExLargeFetch 0x00000002 + +#define kNtDuplicateCloseSource 0x00000001 +#define kNtDuplicateSameAccess 0x00000002 + +#define kNtSymbolicLinkFlagDirectory 1 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtByHandleFileInformation; +struct NtFileTime; +struct NtGenericMapping; +struct NtOverlapped; +struct NtPrivilegeSet; +struct NtSecurityAttributes; +struct NtSecurityDescriptor; +struct NtWin32FindData; +struct NtWin32FindData; + +intptr_t LoadResource(int64_t hModule, int64_t hResInfo); +uint32_t SetHandleCount(uint32_t uNumber); +uint32_t GetLogicalDrives(void); +bool32 FlushFileBuffers(int64_t hFile); + +int64_t ReOpenFile(int64_t hOriginalFile, uint32_t dwDesiredAccess, + uint32_t dwShareMode, uint32_t dwFlagsAndAttributes); + +bool32 DeleteFile(const char16_t *lpFileName) paramsnonnull(); + +bool32 CopyFile(const char16_t *lpExistingFileName, + const char16_t *lpNewFileName, bool32 bFailIfExists) + paramsnonnull(); + +bool32 MoveFile(const char16_t *lpExistingFileName, + const char16_t *lpNewFileName) paramsnonnull(); +bool32 MoveFileEx(const char16_t *lpExistingFileName, + const char16_t *lpNewFileName, enum NtMoveFileExFlags dwFlags) + paramsnonnull(); + +bool32 SetCurrentDirectory(const char16_t *lpPathName); +uint32_t GetCurrentDirectory(uint32_t nBufferLength, char16_t *out_lpBuffer); + +bool32 CreateDirectory(const char16_t *lpPathName, + struct NtSecurityAttributes *lpSecurityAttributes); +bool32 RemoveDirectory(const char16_t *lpPathName); + +int32_t DuplicateHandle(int64_t hSourceProcessHandle, int64_t hSourceHandle, + int64_t hTargetProcessHandle, int64_t *lpTargetHandle, + uint32_t dwDesiredAccess, bool32 bInheritHandle, + uint32_t dwOptions); + +bool32 GetHandleInformation(int64_t hObject, uint32_t *out_lpdwFlags); +bool32 SetHandleInformation(int64_t hObject, uint32_t dwMask, uint32_t dwFlags); +enum NtFileType GetFileType(int64_t hFile); + +bool32 GetFileInformationByHandleEx(int64_t hFile, + uint32_t FileInformationClass, + void *out_lpFileInformation, + uint32_t dwBufferSize); + +bool32 GetFileInformationByHandle( + int64_t hFile, struct NtByHandleFileInformation *lpFileInformation); + +uint32_t GetFileAttributes(const char16_t *lpFileName); +bool32 GetFileAttributesEx( + const char16_t *lpFileName, + enum NtGetFileexInfoLevels fInfoLevelId /* kNtGetFileExInfoStandard */, + void *out_lpFileInformation /* → struct NtWin32FileAttributeData * */) + paramsnonnull(); + +uint32_t GetCompressedFileSize(const char16_t *lpFileName, + uint32_t *lpFileSizeHigh); +bool32 SetFileAttributes(const char16_t *lpFileName, uint32_t dwFileAttributes); +bool32 GetFileTime(int64_t hFile, struct NtFileTime *lpCreationFileTime, + struct NtFileTime *lpLastAccessFileTime, + struct NtFileTime *lpLastWriteFileTime); +bool32 SetFileTime(int64_t hFile, + const struct NtFileTime *opt_lpCreationFileTime, + const struct NtFileTime *opt_lpLastAccessFileTime, + const struct NtFileTime *opt_lpLastWriteFileTime); + +bool32 DeviceIoControl(int64_t hDevice, uint32_t dwIoControlCode, + void *lpInBuffer, uint32_t nInBufferSize, + void *lpOutBuffer, uint32_t nOutBufferSize, + uint32_t *lpBytesReturned, + struct NtOverlapped *lpOverlapped); + +bool32 LockFile(int64_t hFile, uint32_t dwFileOffsetLow, + uint32_t dwFileOffsetHigh, uint32_t nNumberOfBytesToLockLow, + uint32_t nNumberOfBytesToLockHigh); +bool32 LockFileEx(int64_t hFile, uint32_t dwFlags, uint32_t dwReserved, + uint32_t nNumberOfBytesToLockLow, + uint32_t nNumberOfBytesToLockHigh, + struct NtOverlapped *lpOverlapped) paramsnonnull(); +bool32 UnlockFile(int64_t hFile, uint32_t dwFileOffsetLow, + uint32_t dwFileOffsetHigh, uint32_t nNumberOfBytesToUnlockLow, + uint32_t nNumberOfBytesToUnlockHigh); +bool32 UnlockFileEx(int64_t hFile, uint32_t dwReserved, + uint32_t nNumberOfBytesToUnlockLow, + uint32_t nNumberOfBytesToUnlockHigh, + struct NtOverlapped *lpOverlapped) paramsnonnull(); + +bool32 CreateHardLink(const char16_t *lpFileName, + const char16_t *lpExistingFileName, + struct NtSecurityAttributes *reserved) + paramsnonnull((1, 2)); +bool32 CreateSymbolicLink(const char16_t *lpSymlinkFileName, + const char16_t *lpTargetPathName, uint32_t dwFlags) + paramsnonnull(); + +uint32_t SetFilePointer(int64_t hFile, int32_t lDistanceToMove, + int32_t *optional_lpDistanceToMoveHigh, + enum NtFileMoveMethod dwMoveMethod); +bool32 SetFilePointerEx(int64_t hFile, int64_t liDistanceToMove, + int64_t *optional_lpNewFilePointer, + enum NtFileMoveMethod dwMoveMethod); + +bool32 SetEndOfFile(int64_t hFile); +bool32 SetFileValidData(int64_t hFile, int64_t ValidDataLength); + +bool32 GetFileSecurity(const char16_t *lpFileName, + uint32_t RequestedInformation, + struct NtSecurityDescriptor *pSecurityDescriptor, + uint32_t nLength, uint32_t *lpnLengthNeeded); + +bool32 OpenProcessToken(int64_t hProcessHandle, uint32_t dwDesiredAccess, + int64_t *out_hTokenHandle); +bool32 DuplicateToken(int64_t hExistingTokenHandle, + enum NtSecurityImpersonationLevel dwImpersonationLevel, + int64_t *out_hDuplicateTokenHandle); +bool32 DuplicateTokenEx(int64_t hExistingToken, unsigned int dwDesiredAccess, + struct NtSecurityAttributes *lpTokenAttributes, + enum NtSecurityImpersonationLevel ImpersonationLevel, + enum NtTokenType TokenType, int64_t *out_phNewToken); + +bool32 AccessCheck(struct NtSecurityDescriptor *pSecurityDescriptor, + int64_t ClientToken, unsigned int DesiredAccess, + struct NtGenericMapping *lpGenericMapping, + struct NtPrivilegeSet *lpPrivilegeSet, + unsigned int *PrivilegeSetLength, + unsigned int *GrantedAccess, bool32 *AccessStatus); + +void MapGenericMask(uint32_t *AccessMask, + struct NtGenericMapping *GenericMapping); + +int64_t FindFirstFile(const char16_t *lpFileName, + struct NtWin32FindData *out_lpFindFileData); +int64_t FindFirstFileEx(const char16_t *lpFileName, + enum NtFindexInfoLevels fInfoLevelId, + void *out_lpFindFileData, + enum NtFindexSearchOps fSearchOp, + void *reserved_lpSearchFilter, + uint32_t dwAdditionalFlags); +bool32 FindNextFile(int64_t hFindFile, + struct NtWin32FindData *out_lpFindFileData); +bool32 FindClose(int64_t inout_hFindFile); + +int64_t FindFirstVolume(char16_t *out_lpszVolumeName, uint32_t cchBufferLength); +bool32 FindNextVolume(int64_t inout_hFindVolume, char16_t *out_lpszVolumeName, + uint32_t cchBufferLength); +bool32 FindVolumeClose(int64_t hFindVolume); + +bool32 ReadFileScatter( + int64_t hFileOpenedWithOverlappedAndNoBuffering, + const union NtFileSegmentElement + aNullTerminatedPageAlignedSizedSegmentArray[], + uint32_t nNumberOfBytesToReadThatsMultipleOfFileVolumeSectorSize, + uint32_t *lpReserved, struct NtOverlapped *inout_lpOverlapped) + paramsnonnull(); +bool32 WriteFileGather(int64_t hFileOpenedWithOverlappedAndNoBuffering, + const union NtFileSegmentElement aSegmentArray[], + uint32_t nNumberOfBytesToWrite, uint32_t *lpReserved, + struct NtOverlapped inout_lpOverlapped) paramsnonnull(); + +#if ShouldUseMsabiAttribute() +#include "libc/nt/thunk/files.inc" +#endif /* ShouldUseMsabiAttribute() */ +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_FILES_H_ */ diff --git a/libc/nt/gdi32/AbortDoc.s b/libc/nt/gdi32/AbortDoc.s new file mode 100644 index 00000000..ffdebc82 --- /dev/null +++ b/libc/nt/gdi32/AbortDoc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_AbortDoc,AbortDoc,1011 diff --git a/libc/nt/gdi32/AbortPath.s b/libc/nt/gdi32/AbortPath.s new file mode 100644 index 00000000..f5d0eca6 --- /dev/null +++ b/libc/nt/gdi32/AbortPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_AbortPath,AbortPath,1012 diff --git a/libc/nt/gdi32/AddFontMemResourceEx.s b/libc/nt/gdi32/AddFontMemResourceEx.s new file mode 100644 index 00000000..7059eba5 --- /dev/null +++ b/libc/nt/gdi32/AddFontMemResourceEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_AddFontMemResourceEx,AddFontMemResourceEx,1017 diff --git a/libc/nt/gdi32/AddFontResourceA.s b/libc/nt/gdi32/AddFontResourceA.s new file mode 100644 index 00000000..048bfb16 --- /dev/null +++ b/libc/nt/gdi32/AddFontResourceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_AddFontResourceA,AddFontResourceA,1018 diff --git a/libc/nt/gdi32/AddFontResourceExA.s b/libc/nt/gdi32/AddFontResourceExA.s new file mode 100644 index 00000000..aba91b91 --- /dev/null +++ b/libc/nt/gdi32/AddFontResourceExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_AddFontResourceExA,AddFontResourceExA,1019 diff --git a/libc/nt/gdi32/AddFontResourceExW.s b/libc/nt/gdi32/AddFontResourceExW.s new file mode 100644 index 00000000..eac64f23 --- /dev/null +++ b/libc/nt/gdi32/AddFontResourceExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_AddFontResourceExW,AddFontResourceExW,1020 diff --git a/libc/nt/gdi32/AddFontResourceTracking.s b/libc/nt/gdi32/AddFontResourceTracking.s new file mode 100644 index 00000000..c463bfec --- /dev/null +++ b/libc/nt/gdi32/AddFontResourceTracking.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_AddFontResourceTracking,AddFontResourceTracking,1021 diff --git a/libc/nt/gdi32/AddFontResourceW.s b/libc/nt/gdi32/AddFontResourceW.s new file mode 100644 index 00000000..5bece6fd --- /dev/null +++ b/libc/nt/gdi32/AddFontResourceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_AddFontResourceW,AddFontResourceW,1022 diff --git a/libc/nt/gdi32/AngleArc.s b/libc/nt/gdi32/AngleArc.s new file mode 100644 index 00000000..80836d14 --- /dev/null +++ b/libc/nt/gdi32/AngleArc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_AngleArc,AngleArc,1023 diff --git a/libc/nt/gdi32/AnimatePalette.s b/libc/nt/gdi32/AnimatePalette.s new file mode 100644 index 00000000..267dae2c --- /dev/null +++ b/libc/nt/gdi32/AnimatePalette.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_AnimatePalette,AnimatePalette,1024 diff --git a/libc/nt/gdi32/AnyLinkedFonts.s b/libc/nt/gdi32/AnyLinkedFonts.s new file mode 100644 index 00000000..6dfa2c5e --- /dev/null +++ b/libc/nt/gdi32/AnyLinkedFonts.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_AnyLinkedFonts,AnyLinkedFonts,1025 diff --git a/libc/nt/gdi32/Arc.s b/libc/nt/gdi32/Arc.s new file mode 100644 index 00000000..ca20b2c1 --- /dev/null +++ b/libc/nt/gdi32/Arc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_Arc,Arc,1026 diff --git a/libc/nt/gdi32/ArcTo.s b/libc/nt/gdi32/ArcTo.s new file mode 100644 index 00000000..1eee2089 --- /dev/null +++ b/libc/nt/gdi32/ArcTo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ArcTo,ArcTo,1027 diff --git a/libc/nt/gdi32/BRUSHOBJ_hGetColorTransform.s b/libc/nt/gdi32/BRUSHOBJ_hGetColorTransform.s new file mode 100644 index 00000000..2b580030 --- /dev/null +++ b/libc/nt/gdi32/BRUSHOBJ_hGetColorTransform.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_BRUSHOBJ_hGetColorTransform,BRUSHOBJ_hGetColorTransform,1028 diff --git a/libc/nt/gdi32/BRUSHOBJ_pvAllocRbrush.s b/libc/nt/gdi32/BRUSHOBJ_pvAllocRbrush.s new file mode 100644 index 00000000..ce046b16 --- /dev/null +++ b/libc/nt/gdi32/BRUSHOBJ_pvAllocRbrush.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_BRUSHOBJ_pvAllocRbrush,BRUSHOBJ_pvAllocRbrush,1029 diff --git a/libc/nt/gdi32/BRUSHOBJ_pvGetRbrush.s b/libc/nt/gdi32/BRUSHOBJ_pvGetRbrush.s new file mode 100644 index 00000000..35cc7081 --- /dev/null +++ b/libc/nt/gdi32/BRUSHOBJ_pvGetRbrush.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_BRUSHOBJ_pvGetRbrush,BRUSHOBJ_pvGetRbrush,1030 diff --git a/libc/nt/gdi32/BRUSHOBJ_ulGetBrushColor.s b/libc/nt/gdi32/BRUSHOBJ_ulGetBrushColor.s new file mode 100644 index 00000000..f3f817c0 --- /dev/null +++ b/libc/nt/gdi32/BRUSHOBJ_ulGetBrushColor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_BRUSHOBJ_ulGetBrushColor,BRUSHOBJ_ulGetBrushColor,1031 diff --git a/libc/nt/gdi32/BeginGdiRendering.s b/libc/nt/gdi32/BeginGdiRendering.s new file mode 100644 index 00000000..68e2fabe --- /dev/null +++ b/libc/nt/gdi32/BeginGdiRendering.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_BeginGdiRendering,BeginGdiRendering,1032 diff --git a/libc/nt/gdi32/BeginPath.s b/libc/nt/gdi32/BeginPath.s new file mode 100644 index 00000000..567e03a8 --- /dev/null +++ b/libc/nt/gdi32/BeginPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_BeginPath,BeginPath,1033 diff --git a/libc/nt/gdi32/BitBlt.s b/libc/nt/gdi32/BitBlt.s new file mode 100644 index 00000000..ddc4c9ef --- /dev/null +++ b/libc/nt/gdi32/BitBlt.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_BitBlt,BitBlt,1034 + + .text.windows +BitBlt: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_BitBlt(%rip),%rax + jmp __sysv2nt10 + .endfn BitBlt,globl + .previous diff --git a/libc/nt/gdi32/CLIPOBJ_bEnum.s b/libc/nt/gdi32/CLIPOBJ_bEnum.s new file mode 100644 index 00000000..a59d40be --- /dev/null +++ b/libc/nt/gdi32/CLIPOBJ_bEnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CLIPOBJ_bEnum,CLIPOBJ_bEnum,1035 diff --git a/libc/nt/gdi32/CLIPOBJ_cEnumStart.s b/libc/nt/gdi32/CLIPOBJ_cEnumStart.s new file mode 100644 index 00000000..7ccad22d --- /dev/null +++ b/libc/nt/gdi32/CLIPOBJ_cEnumStart.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CLIPOBJ_cEnumStart,CLIPOBJ_cEnumStart,1036 diff --git a/libc/nt/gdi32/CLIPOBJ_ppoGetPath.s b/libc/nt/gdi32/CLIPOBJ_ppoGetPath.s new file mode 100644 index 00000000..b4f53893 --- /dev/null +++ b/libc/nt/gdi32/CLIPOBJ_ppoGetPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CLIPOBJ_ppoGetPath,CLIPOBJ_ppoGetPath,1037 diff --git a/libc/nt/gdi32/CancelDC.s b/libc/nt/gdi32/CancelDC.s new file mode 100644 index 00000000..aabeb692 --- /dev/null +++ b/libc/nt/gdi32/CancelDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CancelDC,CancelDC,1038 diff --git a/libc/nt/gdi32/CheckColorsInGamut.s b/libc/nt/gdi32/CheckColorsInGamut.s new file mode 100644 index 00000000..471d3b2f --- /dev/null +++ b/libc/nt/gdi32/CheckColorsInGamut.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CheckColorsInGamut,CheckColorsInGamut,1039 diff --git a/libc/nt/gdi32/ChoosePixelFormat.s b/libc/nt/gdi32/ChoosePixelFormat.s new file mode 100644 index 00000000..6b577ada --- /dev/null +++ b/libc/nt/gdi32/ChoosePixelFormat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ChoosePixelFormat,ChoosePixelFormat,1040 diff --git a/libc/nt/gdi32/Chord.s b/libc/nt/gdi32/Chord.s new file mode 100644 index 00000000..896f9cd6 --- /dev/null +++ b/libc/nt/gdi32/Chord.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_Chord,Chord,1041 diff --git a/libc/nt/gdi32/ClearBitmapAttributes.s b/libc/nt/gdi32/ClearBitmapAttributes.s new file mode 100644 index 00000000..c6f36b7f --- /dev/null +++ b/libc/nt/gdi32/ClearBitmapAttributes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ClearBitmapAttributes,ClearBitmapAttributes,1042 diff --git a/libc/nt/gdi32/ClearBrushAttributes.s b/libc/nt/gdi32/ClearBrushAttributes.s new file mode 100644 index 00000000..77227964 --- /dev/null +++ b/libc/nt/gdi32/ClearBrushAttributes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ClearBrushAttributes,ClearBrushAttributes,1043 diff --git a/libc/nt/gdi32/CloseEnhMetaFile.s b/libc/nt/gdi32/CloseEnhMetaFile.s new file mode 100644 index 00000000..01bdfa4e --- /dev/null +++ b/libc/nt/gdi32/CloseEnhMetaFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CloseEnhMetaFile,CloseEnhMetaFile,1044 diff --git a/libc/nt/gdi32/CloseFigure.s b/libc/nt/gdi32/CloseFigure.s new file mode 100644 index 00000000..cd97a700 --- /dev/null +++ b/libc/nt/gdi32/CloseFigure.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CloseFigure,CloseFigure,1045 diff --git a/libc/nt/gdi32/CloseMetaFile.s b/libc/nt/gdi32/CloseMetaFile.s new file mode 100644 index 00000000..fa86c2e4 --- /dev/null +++ b/libc/nt/gdi32/CloseMetaFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CloseMetaFile,CloseMetaFile,1046 diff --git a/libc/nt/gdi32/ColorCorrectPalette.s b/libc/nt/gdi32/ColorCorrectPalette.s new file mode 100644 index 00000000..0a86e789 --- /dev/null +++ b/libc/nt/gdi32/ColorCorrectPalette.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ColorCorrectPalette,ColorCorrectPalette,1047 diff --git a/libc/nt/gdi32/ColorMatchToTarget.s b/libc/nt/gdi32/ColorMatchToTarget.s new file mode 100644 index 00000000..f7c9b8a2 --- /dev/null +++ b/libc/nt/gdi32/ColorMatchToTarget.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ColorMatchToTarget,ColorMatchToTarget,1048 diff --git a/libc/nt/gdi32/CombineRgn.s b/libc/nt/gdi32/CombineRgn.s new file mode 100644 index 00000000..1f83ed00 --- /dev/null +++ b/libc/nt/gdi32/CombineRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CombineRgn,CombineRgn,1049 diff --git a/libc/nt/gdi32/CombineTransform.s b/libc/nt/gdi32/CombineTransform.s new file mode 100644 index 00000000..5d17ea2f --- /dev/null +++ b/libc/nt/gdi32/CombineTransform.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CombineTransform,CombineTransform,1050 diff --git a/libc/nt/gdi32/ConfigureOPMProtectedOutput.s b/libc/nt/gdi32/ConfigureOPMProtectedOutput.s new file mode 100644 index 00000000..fc28a578 --- /dev/null +++ b/libc/nt/gdi32/ConfigureOPMProtectedOutput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ConfigureOPMProtectedOutput,ConfigureOPMProtectedOutput,1051 diff --git a/libc/nt/gdi32/CopyEnhMetaFileA.s b/libc/nt/gdi32/CopyEnhMetaFileA.s new file mode 100644 index 00000000..be38e90b --- /dev/null +++ b/libc/nt/gdi32/CopyEnhMetaFileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CopyEnhMetaFileA,CopyEnhMetaFileA,1052 diff --git a/libc/nt/gdi32/CopyEnhMetaFileW.s b/libc/nt/gdi32/CopyEnhMetaFileW.s new file mode 100644 index 00000000..df5d3104 --- /dev/null +++ b/libc/nt/gdi32/CopyEnhMetaFileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CopyEnhMetaFileW,CopyEnhMetaFileW,1053 diff --git a/libc/nt/gdi32/CopyMetaFileA.s b/libc/nt/gdi32/CopyMetaFileA.s new file mode 100644 index 00000000..6de5a2b6 --- /dev/null +++ b/libc/nt/gdi32/CopyMetaFileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CopyMetaFileA,CopyMetaFileA,1054 diff --git a/libc/nt/gdi32/CopyMetaFileW.s b/libc/nt/gdi32/CopyMetaFileW.s new file mode 100644 index 00000000..3f8ccfcc --- /dev/null +++ b/libc/nt/gdi32/CopyMetaFileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CopyMetaFileW,CopyMetaFileW,1055 diff --git a/libc/nt/gdi32/CreateBitmap.s b/libc/nt/gdi32/CreateBitmap.s new file mode 100644 index 00000000..4f426851 --- /dev/null +++ b/libc/nt/gdi32/CreateBitmap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateBitmap,CreateBitmap,1056 diff --git a/libc/nt/gdi32/CreateBitmapFromDxSurface.s b/libc/nt/gdi32/CreateBitmapFromDxSurface.s new file mode 100644 index 00000000..2fad6a37 --- /dev/null +++ b/libc/nt/gdi32/CreateBitmapFromDxSurface.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateBitmapFromDxSurface,CreateBitmapFromDxSurface,1057 diff --git a/libc/nt/gdi32/CreateBitmapFromDxSurface2.s b/libc/nt/gdi32/CreateBitmapFromDxSurface2.s new file mode 100644 index 00000000..5b461762 --- /dev/null +++ b/libc/nt/gdi32/CreateBitmapFromDxSurface2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateBitmapFromDxSurface2,CreateBitmapFromDxSurface2,1058 diff --git a/libc/nt/gdi32/CreateBitmapIndirect.s b/libc/nt/gdi32/CreateBitmapIndirect.s new file mode 100644 index 00000000..b0bfacfd --- /dev/null +++ b/libc/nt/gdi32/CreateBitmapIndirect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateBitmapIndirect,CreateBitmapIndirect,1059 diff --git a/libc/nt/gdi32/CreateBrushIndirect.s b/libc/nt/gdi32/CreateBrushIndirect.s new file mode 100644 index 00000000..71724a61 --- /dev/null +++ b/libc/nt/gdi32/CreateBrushIndirect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateBrushIndirect,CreateBrushIndirect,1060 diff --git a/libc/nt/gdi32/CreateColorSpaceA.s b/libc/nt/gdi32/CreateColorSpaceA.s new file mode 100644 index 00000000..f2ad9486 --- /dev/null +++ b/libc/nt/gdi32/CreateColorSpaceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateColorSpaceA,CreateColorSpaceA,1061 diff --git a/libc/nt/gdi32/CreateColorSpaceW.s b/libc/nt/gdi32/CreateColorSpaceW.s new file mode 100644 index 00000000..f6c3c2ea --- /dev/null +++ b/libc/nt/gdi32/CreateColorSpaceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateColorSpaceW,CreateColorSpaceW,1062 diff --git a/libc/nt/gdi32/CreateCompatibleBitmap.s b/libc/nt/gdi32/CreateCompatibleBitmap.s new file mode 100644 index 00000000..20978908 --- /dev/null +++ b/libc/nt/gdi32/CreateCompatibleBitmap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateCompatibleBitmap,CreateCompatibleBitmap,1063 diff --git a/libc/nt/gdi32/CreateCompatibleDC.s b/libc/nt/gdi32/CreateCompatibleDC.s new file mode 100644 index 00000000..b2d915c1 --- /dev/null +++ b/libc/nt/gdi32/CreateCompatibleDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateCompatibleDC,CreateCompatibleDC,1064 diff --git a/libc/nt/gdi32/CreateDCA.s b/libc/nt/gdi32/CreateDCA.s new file mode 100644 index 00000000..0f9f172c --- /dev/null +++ b/libc/nt/gdi32/CreateDCA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateDCA,CreateDCA,1065 diff --git a/libc/nt/gdi32/CreateDCExW.s b/libc/nt/gdi32/CreateDCExW.s new file mode 100644 index 00000000..08c279d9 --- /dev/null +++ b/libc/nt/gdi32/CreateDCExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateDCExW,CreateDCExW,2000 diff --git a/libc/nt/gdi32/CreateDCW.s b/libc/nt/gdi32/CreateDCW.s new file mode 100644 index 00000000..4e462b8b --- /dev/null +++ b/libc/nt/gdi32/CreateDCW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateDCW,CreateDCW,1066 diff --git a/libc/nt/gdi32/CreateDIBPatternBrush.s b/libc/nt/gdi32/CreateDIBPatternBrush.s new file mode 100644 index 00000000..cc561eea --- /dev/null +++ b/libc/nt/gdi32/CreateDIBPatternBrush.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateDIBPatternBrush,CreateDIBPatternBrush,1067 diff --git a/libc/nt/gdi32/CreateDIBPatternBrushPt.s b/libc/nt/gdi32/CreateDIBPatternBrushPt.s new file mode 100644 index 00000000..cee6be97 --- /dev/null +++ b/libc/nt/gdi32/CreateDIBPatternBrushPt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateDIBPatternBrushPt,CreateDIBPatternBrushPt,1068 diff --git a/libc/nt/gdi32/CreateDIBSection.s b/libc/nt/gdi32/CreateDIBSection.s new file mode 100644 index 00000000..fb102dd3 --- /dev/null +++ b/libc/nt/gdi32/CreateDIBSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateDIBSection,CreateDIBSection,1069 diff --git a/libc/nt/gdi32/CreateDIBitmap.s b/libc/nt/gdi32/CreateDIBitmap.s new file mode 100644 index 00000000..79575179 --- /dev/null +++ b/libc/nt/gdi32/CreateDIBitmap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateDIBitmap,CreateDIBitmap,1070 diff --git a/libc/nt/gdi32/CreateDPIScaledDIBSection.s b/libc/nt/gdi32/CreateDPIScaledDIBSection.s new file mode 100644 index 00000000..14acea6e --- /dev/null +++ b/libc/nt/gdi32/CreateDPIScaledDIBSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateDPIScaledDIBSection,CreateDPIScaledDIBSection,1071 diff --git a/libc/nt/gdi32/CreateDiscardableBitmap.s b/libc/nt/gdi32/CreateDiscardableBitmap.s new file mode 100644 index 00000000..775f55c1 --- /dev/null +++ b/libc/nt/gdi32/CreateDiscardableBitmap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateDiscardableBitmap,CreateDiscardableBitmap,1072 diff --git a/libc/nt/gdi32/CreateEllipticRgn.s b/libc/nt/gdi32/CreateEllipticRgn.s new file mode 100644 index 00000000..5cdb2518 --- /dev/null +++ b/libc/nt/gdi32/CreateEllipticRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateEllipticRgn,CreateEllipticRgn,1073 diff --git a/libc/nt/gdi32/CreateEllipticRgnIndirect.s b/libc/nt/gdi32/CreateEllipticRgnIndirect.s new file mode 100644 index 00000000..0041df48 --- /dev/null +++ b/libc/nt/gdi32/CreateEllipticRgnIndirect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateEllipticRgnIndirect,CreateEllipticRgnIndirect,1074 diff --git a/libc/nt/gdi32/CreateEnhMetaFileA.s b/libc/nt/gdi32/CreateEnhMetaFileA.s new file mode 100644 index 00000000..f92acfe0 --- /dev/null +++ b/libc/nt/gdi32/CreateEnhMetaFileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateEnhMetaFileA,CreateEnhMetaFileA,1075 diff --git a/libc/nt/gdi32/CreateEnhMetaFileW.s b/libc/nt/gdi32/CreateEnhMetaFileW.s new file mode 100644 index 00000000..bed47b6b --- /dev/null +++ b/libc/nt/gdi32/CreateEnhMetaFileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateEnhMetaFileW,CreateEnhMetaFileW,1076 diff --git a/libc/nt/gdi32/CreateFontA.s b/libc/nt/gdi32/CreateFontA.s new file mode 100644 index 00000000..b230b820 --- /dev/null +++ b/libc/nt/gdi32/CreateFontA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateFontA,CreateFontA,1077 diff --git a/libc/nt/gdi32/CreateFontIndirectA.s b/libc/nt/gdi32/CreateFontIndirectA.s new file mode 100644 index 00000000..6d14ad2d --- /dev/null +++ b/libc/nt/gdi32/CreateFontIndirectA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateFontIndirectA,CreateFontIndirectA,1078 diff --git a/libc/nt/gdi32/CreateFontIndirectExA.s b/libc/nt/gdi32/CreateFontIndirectExA.s new file mode 100644 index 00000000..f533f11a --- /dev/null +++ b/libc/nt/gdi32/CreateFontIndirectExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateFontIndirectExA,CreateFontIndirectExA,1079 diff --git a/libc/nt/gdi32/CreateFontIndirectExW.s b/libc/nt/gdi32/CreateFontIndirectExW.s new file mode 100644 index 00000000..76245f9b --- /dev/null +++ b/libc/nt/gdi32/CreateFontIndirectExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateFontIndirectExW,CreateFontIndirectExW,1080 diff --git a/libc/nt/gdi32/CreateFontIndirectW.s b/libc/nt/gdi32/CreateFontIndirectW.s new file mode 100644 index 00000000..e1f45fbf --- /dev/null +++ b/libc/nt/gdi32/CreateFontIndirectW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateFontIndirectW,CreateFontIndirectW,1081 diff --git a/libc/nt/gdi32/CreateFontW.s b/libc/nt/gdi32/CreateFontW.s new file mode 100644 index 00000000..47336b7e --- /dev/null +++ b/libc/nt/gdi32/CreateFontW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateFontW,CreateFontW,1082 diff --git a/libc/nt/gdi32/CreateHalftonePalette.s b/libc/nt/gdi32/CreateHalftonePalette.s new file mode 100644 index 00000000..b874fa12 --- /dev/null +++ b/libc/nt/gdi32/CreateHalftonePalette.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateHalftonePalette,CreateHalftonePalette,1083 diff --git a/libc/nt/gdi32/CreateHatchBrush.s b/libc/nt/gdi32/CreateHatchBrush.s new file mode 100644 index 00000000..15dc7c90 --- /dev/null +++ b/libc/nt/gdi32/CreateHatchBrush.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateHatchBrush,CreateHatchBrush,1084 diff --git a/libc/nt/gdi32/CreateICA.s b/libc/nt/gdi32/CreateICA.s new file mode 100644 index 00000000..511789c5 --- /dev/null +++ b/libc/nt/gdi32/CreateICA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateICA,CreateICA,1085 diff --git a/libc/nt/gdi32/CreateICW.s b/libc/nt/gdi32/CreateICW.s new file mode 100644 index 00000000..94e90875 --- /dev/null +++ b/libc/nt/gdi32/CreateICW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateICW,CreateICW,1086 diff --git a/libc/nt/gdi32/CreateMetaFileA.s b/libc/nt/gdi32/CreateMetaFileA.s new file mode 100644 index 00000000..d80413b5 --- /dev/null +++ b/libc/nt/gdi32/CreateMetaFileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateMetaFileA,CreateMetaFileA,1087 diff --git a/libc/nt/gdi32/CreateMetaFileW.s b/libc/nt/gdi32/CreateMetaFileW.s new file mode 100644 index 00000000..dd55355f --- /dev/null +++ b/libc/nt/gdi32/CreateMetaFileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateMetaFileW,CreateMetaFileW,1088 diff --git a/libc/nt/gdi32/CreateOPMProtectedOutput.s b/libc/nt/gdi32/CreateOPMProtectedOutput.s new file mode 100644 index 00000000..31d0aaa6 --- /dev/null +++ b/libc/nt/gdi32/CreateOPMProtectedOutput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateOPMProtectedOutput,CreateOPMProtectedOutput,1089 diff --git a/libc/nt/gdi32/CreateOPMProtectedOutputs.s b/libc/nt/gdi32/CreateOPMProtectedOutputs.s new file mode 100644 index 00000000..a68d5753 --- /dev/null +++ b/libc/nt/gdi32/CreateOPMProtectedOutputs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateOPMProtectedOutputs,CreateOPMProtectedOutputs,1090 diff --git a/libc/nt/gdi32/CreatePalette.s b/libc/nt/gdi32/CreatePalette.s new file mode 100644 index 00000000..4a62edb8 --- /dev/null +++ b/libc/nt/gdi32/CreatePalette.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreatePalette,CreatePalette,1091 diff --git a/libc/nt/gdi32/CreatePatternBrush.s b/libc/nt/gdi32/CreatePatternBrush.s new file mode 100644 index 00000000..8b2ae176 --- /dev/null +++ b/libc/nt/gdi32/CreatePatternBrush.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreatePatternBrush,CreatePatternBrush,1092 diff --git a/libc/nt/gdi32/CreatePen.s b/libc/nt/gdi32/CreatePen.s new file mode 100644 index 00000000..e1ce6041 --- /dev/null +++ b/libc/nt/gdi32/CreatePen.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreatePen,CreatePen,1093 diff --git a/libc/nt/gdi32/CreatePenIndirect.s b/libc/nt/gdi32/CreatePenIndirect.s new file mode 100644 index 00000000..13a9be17 --- /dev/null +++ b/libc/nt/gdi32/CreatePenIndirect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreatePenIndirect,CreatePenIndirect,1094 diff --git a/libc/nt/gdi32/CreatePolyPolygonRgn.s b/libc/nt/gdi32/CreatePolyPolygonRgn.s new file mode 100644 index 00000000..9f47befa --- /dev/null +++ b/libc/nt/gdi32/CreatePolyPolygonRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreatePolyPolygonRgn,CreatePolyPolygonRgn,1095 diff --git a/libc/nt/gdi32/CreatePolygonRgn.s b/libc/nt/gdi32/CreatePolygonRgn.s new file mode 100644 index 00000000..2739f1b8 --- /dev/null +++ b/libc/nt/gdi32/CreatePolygonRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreatePolygonRgn,CreatePolygonRgn,1096 diff --git a/libc/nt/gdi32/CreateRectRgn.s b/libc/nt/gdi32/CreateRectRgn.s new file mode 100644 index 00000000..b24c0810 --- /dev/null +++ b/libc/nt/gdi32/CreateRectRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateRectRgn,CreateRectRgn,1097 diff --git a/libc/nt/gdi32/CreateRectRgnIndirect.s b/libc/nt/gdi32/CreateRectRgnIndirect.s new file mode 100644 index 00000000..d58997b3 --- /dev/null +++ b/libc/nt/gdi32/CreateRectRgnIndirect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateRectRgnIndirect,CreateRectRgnIndirect,1098 diff --git a/libc/nt/gdi32/CreateRoundRectRgn.s b/libc/nt/gdi32/CreateRoundRectRgn.s new file mode 100644 index 00000000..bc899d1f --- /dev/null +++ b/libc/nt/gdi32/CreateRoundRectRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateRoundRectRgn,CreateRoundRectRgn,1099 diff --git a/libc/nt/gdi32/CreateScalableFontResourceA.s b/libc/nt/gdi32/CreateScalableFontResourceA.s new file mode 100644 index 00000000..db4ec0bc --- /dev/null +++ b/libc/nt/gdi32/CreateScalableFontResourceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateScalableFontResourceA,CreateScalableFontResourceA,1100 diff --git a/libc/nt/gdi32/CreateScalableFontResourceW.s b/libc/nt/gdi32/CreateScalableFontResourceW.s new file mode 100644 index 00000000..a80e3c5e --- /dev/null +++ b/libc/nt/gdi32/CreateScalableFontResourceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateScalableFontResourceW,CreateScalableFontResourceW,1101 diff --git a/libc/nt/gdi32/CreateSessionMappedDIBSection.s b/libc/nt/gdi32/CreateSessionMappedDIBSection.s new file mode 100644 index 00000000..54a80974 --- /dev/null +++ b/libc/nt/gdi32/CreateSessionMappedDIBSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateSessionMappedDIBSection,CreateSessionMappedDIBSection,1102 diff --git a/libc/nt/gdi32/CreateSolidBrush.s b/libc/nt/gdi32/CreateSolidBrush.s new file mode 100644 index 00000000..b92ef777 --- /dev/null +++ b/libc/nt/gdi32/CreateSolidBrush.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_CreateSolidBrush,CreateSolidBrush,1103 diff --git a/libc/nt/gdi32/D3DKMTAbandonSwapChain.s b/libc/nt/gdi32/D3DKMTAbandonSwapChain.s new file mode 100644 index 00000000..02901dc0 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTAbandonSwapChain.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTAbandonSwapChain,D3DKMTAbandonSwapChain,1104 diff --git a/libc/nt/gdi32/D3DKMTAcquireKeyedMutex.s b/libc/nt/gdi32/D3DKMTAcquireKeyedMutex.s new file mode 100644 index 00000000..a5d6ef10 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTAcquireKeyedMutex.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTAcquireKeyedMutex,D3DKMTAcquireKeyedMutex,1105 diff --git a/libc/nt/gdi32/D3DKMTAcquireKeyedMutex2.s b/libc/nt/gdi32/D3DKMTAcquireKeyedMutex2.s new file mode 100644 index 00000000..b74778e4 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTAcquireKeyedMutex2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTAcquireKeyedMutex2,D3DKMTAcquireKeyedMutex2,1106 diff --git a/libc/nt/gdi32/D3DKMTAcquireSwapChain.s b/libc/nt/gdi32/D3DKMTAcquireSwapChain.s new file mode 100644 index 00000000..6d3dbaf2 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTAcquireSwapChain.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTAcquireSwapChain,D3DKMTAcquireSwapChain,1107 diff --git a/libc/nt/gdi32/D3DKMTAddSurfaceToSwapChain.s b/libc/nt/gdi32/D3DKMTAddSurfaceToSwapChain.s new file mode 100644 index 00000000..60c140c2 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTAddSurfaceToSwapChain.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTAddSurfaceToSwapChain,D3DKMTAddSurfaceToSwapChain,1108 diff --git a/libc/nt/gdi32/D3DKMTAdjustFullscreenGamma.s b/libc/nt/gdi32/D3DKMTAdjustFullscreenGamma.s new file mode 100644 index 00000000..ff64d86e --- /dev/null +++ b/libc/nt/gdi32/D3DKMTAdjustFullscreenGamma.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTAdjustFullscreenGamma,D3DKMTAdjustFullscreenGamma,1109 diff --git a/libc/nt/gdi32/D3DKMTCacheHybridQueryValue.s b/libc/nt/gdi32/D3DKMTCacheHybridQueryValue.s new file mode 100644 index 00000000..766f1aeb --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCacheHybridQueryValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCacheHybridQueryValue,D3DKMTCacheHybridQueryValue,1110 diff --git a/libc/nt/gdi32/D3DKMTChangeVideoMemoryReservation.s b/libc/nt/gdi32/D3DKMTChangeVideoMemoryReservation.s new file mode 100644 index 00000000..4ef85e0c --- /dev/null +++ b/libc/nt/gdi32/D3DKMTChangeVideoMemoryReservation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTChangeVideoMemoryReservation,D3DKMTChangeVideoMemoryReservation,1111 diff --git a/libc/nt/gdi32/D3DKMTCheckExclusiveOwnership.s b/libc/nt/gdi32/D3DKMTCheckExclusiveOwnership.s new file mode 100644 index 00000000..39be44b6 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCheckExclusiveOwnership.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCheckExclusiveOwnership,D3DKMTCheckExclusiveOwnership,1112 diff --git a/libc/nt/gdi32/D3DKMTCheckMonitorPowerState.s b/libc/nt/gdi32/D3DKMTCheckMonitorPowerState.s new file mode 100644 index 00000000..c0faecde --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCheckMonitorPowerState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCheckMonitorPowerState,D3DKMTCheckMonitorPowerState,1113 diff --git a/libc/nt/gdi32/D3DKMTCheckMultiPlaneOverlaySupport.s b/libc/nt/gdi32/D3DKMTCheckMultiPlaneOverlaySupport.s new file mode 100644 index 00000000..24d7657b --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCheckMultiPlaneOverlaySupport.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCheckMultiPlaneOverlaySupport,D3DKMTCheckMultiPlaneOverlaySupport,1114 diff --git a/libc/nt/gdi32/D3DKMTCheckMultiPlaneOverlaySupport2.s b/libc/nt/gdi32/D3DKMTCheckMultiPlaneOverlaySupport2.s new file mode 100644 index 00000000..03d44130 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCheckMultiPlaneOverlaySupport2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCheckMultiPlaneOverlaySupport2,D3DKMTCheckMultiPlaneOverlaySupport2,1115 diff --git a/libc/nt/gdi32/D3DKMTCheckMultiPlaneOverlaySupport3.s b/libc/nt/gdi32/D3DKMTCheckMultiPlaneOverlaySupport3.s new file mode 100644 index 00000000..199dc608 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCheckMultiPlaneOverlaySupport3.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCheckMultiPlaneOverlaySupport3,D3DKMTCheckMultiPlaneOverlaySupport3,1116 diff --git a/libc/nt/gdi32/D3DKMTCheckOcclusion.s b/libc/nt/gdi32/D3DKMTCheckOcclusion.s new file mode 100644 index 00000000..a91e8d8e --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCheckOcclusion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCheckOcclusion,D3DKMTCheckOcclusion,1117 diff --git a/libc/nt/gdi32/D3DKMTCheckSharedResourceAccess.s b/libc/nt/gdi32/D3DKMTCheckSharedResourceAccess.s new file mode 100644 index 00000000..b2ef8e74 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCheckSharedResourceAccess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCheckSharedResourceAccess,D3DKMTCheckSharedResourceAccess,1118 diff --git a/libc/nt/gdi32/D3DKMTCheckVidPnExclusiveOwnership.s b/libc/nt/gdi32/D3DKMTCheckVidPnExclusiveOwnership.s new file mode 100644 index 00000000..d8dc50a3 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCheckVidPnExclusiveOwnership.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCheckVidPnExclusiveOwnership,D3DKMTCheckVidPnExclusiveOwnership,1119 diff --git a/libc/nt/gdi32/D3DKMTCloseAdapter.s b/libc/nt/gdi32/D3DKMTCloseAdapter.s new file mode 100644 index 00000000..31db7778 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCloseAdapter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCloseAdapter,D3DKMTCloseAdapter,1120 diff --git a/libc/nt/gdi32/D3DKMTConfigureSharedResource.s b/libc/nt/gdi32/D3DKMTConfigureSharedResource.s new file mode 100644 index 00000000..eb5d6730 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTConfigureSharedResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTConfigureSharedResource,D3DKMTConfigureSharedResource,1121 diff --git a/libc/nt/gdi32/D3DKMTCreateAllocation.s b/libc/nt/gdi32/D3DKMTCreateAllocation.s new file mode 100644 index 00000000..4a6fb38c --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreateAllocation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreateAllocation,D3DKMTCreateAllocation,1122 diff --git a/libc/nt/gdi32/D3DKMTCreateAllocation2.s b/libc/nt/gdi32/D3DKMTCreateAllocation2.s new file mode 100644 index 00000000..1b7d94ee --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreateAllocation2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreateAllocation2,D3DKMTCreateAllocation2,1123 diff --git a/libc/nt/gdi32/D3DKMTCreateBundleObject.s b/libc/nt/gdi32/D3DKMTCreateBundleObject.s new file mode 100644 index 00000000..6bcd44a4 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreateBundleObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreateBundleObject,D3DKMTCreateBundleObject,1124 diff --git a/libc/nt/gdi32/D3DKMTCreateContext.s b/libc/nt/gdi32/D3DKMTCreateContext.s new file mode 100644 index 00000000..eb9e3c78 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreateContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreateContext,D3DKMTCreateContext,1125 diff --git a/libc/nt/gdi32/D3DKMTCreateContextVirtual.s b/libc/nt/gdi32/D3DKMTCreateContextVirtual.s new file mode 100644 index 00000000..ab346743 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreateContextVirtual.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreateContextVirtual,D3DKMTCreateContextVirtual,1126 diff --git a/libc/nt/gdi32/D3DKMTCreateDCFromMemory.s b/libc/nt/gdi32/D3DKMTCreateDCFromMemory.s new file mode 100644 index 00000000..bde8e9cc --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreateDCFromMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreateDCFromMemory,D3DKMTCreateDCFromMemory,1127 diff --git a/libc/nt/gdi32/D3DKMTCreateDevice.s b/libc/nt/gdi32/D3DKMTCreateDevice.s new file mode 100644 index 00000000..db9e7aa7 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreateDevice.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreateDevice,D3DKMTCreateDevice,1128 diff --git a/libc/nt/gdi32/D3DKMTCreateHwContext.s b/libc/nt/gdi32/D3DKMTCreateHwContext.s new file mode 100644 index 00000000..f6819c64 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreateHwContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreateHwContext,D3DKMTCreateHwContext,1129 diff --git a/libc/nt/gdi32/D3DKMTCreateHwQueue.s b/libc/nt/gdi32/D3DKMTCreateHwQueue.s new file mode 100644 index 00000000..aebda50c --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreateHwQueue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreateHwQueue,D3DKMTCreateHwQueue,1130 diff --git a/libc/nt/gdi32/D3DKMTCreateKeyedMutex.s b/libc/nt/gdi32/D3DKMTCreateKeyedMutex.s new file mode 100644 index 00000000..c76b2a22 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreateKeyedMutex.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreateKeyedMutex,D3DKMTCreateKeyedMutex,1131 diff --git a/libc/nt/gdi32/D3DKMTCreateKeyedMutex2.s b/libc/nt/gdi32/D3DKMTCreateKeyedMutex2.s new file mode 100644 index 00000000..e6162b57 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreateKeyedMutex2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreateKeyedMutex2,D3DKMTCreateKeyedMutex2,1132 diff --git a/libc/nt/gdi32/D3DKMTCreateOutputDupl.s b/libc/nt/gdi32/D3DKMTCreateOutputDupl.s new file mode 100644 index 00000000..9ead3e69 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreateOutputDupl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreateOutputDupl,D3DKMTCreateOutputDupl,1133 diff --git a/libc/nt/gdi32/D3DKMTCreateOverlay.s b/libc/nt/gdi32/D3DKMTCreateOverlay.s new file mode 100644 index 00000000..2f984081 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreateOverlay.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreateOverlay,D3DKMTCreateOverlay,1134 diff --git a/libc/nt/gdi32/D3DKMTCreatePagingQueue.s b/libc/nt/gdi32/D3DKMTCreatePagingQueue.s new file mode 100644 index 00000000..0811a112 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreatePagingQueue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreatePagingQueue,D3DKMTCreatePagingQueue,1135 diff --git a/libc/nt/gdi32/D3DKMTCreateProtectedSession.s b/libc/nt/gdi32/D3DKMTCreateProtectedSession.s new file mode 100644 index 00000000..836b43b6 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreateProtectedSession.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreateProtectedSession,D3DKMTCreateProtectedSession,1136 diff --git a/libc/nt/gdi32/D3DKMTCreateSwapChain.s b/libc/nt/gdi32/D3DKMTCreateSwapChain.s new file mode 100644 index 00000000..3a218ccd --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreateSwapChain.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreateSwapChain,D3DKMTCreateSwapChain,1137 diff --git a/libc/nt/gdi32/D3DKMTCreateSynchronizationObject.s b/libc/nt/gdi32/D3DKMTCreateSynchronizationObject.s new file mode 100644 index 00000000..d8430e21 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreateSynchronizationObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreateSynchronizationObject,D3DKMTCreateSynchronizationObject,1138 diff --git a/libc/nt/gdi32/D3DKMTCreateSynchronizationObject2.s b/libc/nt/gdi32/D3DKMTCreateSynchronizationObject2.s new file mode 100644 index 00000000..a37e93aa --- /dev/null +++ b/libc/nt/gdi32/D3DKMTCreateSynchronizationObject2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTCreateSynchronizationObject2,D3DKMTCreateSynchronizationObject2,1139 diff --git a/libc/nt/gdi32/D3DKMTDDisplayEnum.s b/libc/nt/gdi32/D3DKMTDDisplayEnum.s new file mode 100644 index 00000000..d3a34705 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTDDisplayEnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTDDisplayEnum,D3DKMTDDisplayEnum,1140 diff --git a/libc/nt/gdi32/D3DKMTDestroyAllocation.s b/libc/nt/gdi32/D3DKMTDestroyAllocation.s new file mode 100644 index 00000000..45135ceb --- /dev/null +++ b/libc/nt/gdi32/D3DKMTDestroyAllocation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTDestroyAllocation,D3DKMTDestroyAllocation,1141 diff --git a/libc/nt/gdi32/D3DKMTDestroyAllocation2.s b/libc/nt/gdi32/D3DKMTDestroyAllocation2.s new file mode 100644 index 00000000..92e91815 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTDestroyAllocation2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTDestroyAllocation2,D3DKMTDestroyAllocation2,1142 diff --git a/libc/nt/gdi32/D3DKMTDestroyContext.s b/libc/nt/gdi32/D3DKMTDestroyContext.s new file mode 100644 index 00000000..4e03595d --- /dev/null +++ b/libc/nt/gdi32/D3DKMTDestroyContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTDestroyContext,D3DKMTDestroyContext,1143 diff --git a/libc/nt/gdi32/D3DKMTDestroyDCFromMemory.s b/libc/nt/gdi32/D3DKMTDestroyDCFromMemory.s new file mode 100644 index 00000000..fc32ac03 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTDestroyDCFromMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTDestroyDCFromMemory,D3DKMTDestroyDCFromMemory,1144 diff --git a/libc/nt/gdi32/D3DKMTDestroyDevice.s b/libc/nt/gdi32/D3DKMTDestroyDevice.s new file mode 100644 index 00000000..d7fd4c9b --- /dev/null +++ b/libc/nt/gdi32/D3DKMTDestroyDevice.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTDestroyDevice,D3DKMTDestroyDevice,1145 diff --git a/libc/nt/gdi32/D3DKMTDestroyHwContext.s b/libc/nt/gdi32/D3DKMTDestroyHwContext.s new file mode 100644 index 00000000..baa01f42 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTDestroyHwContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTDestroyHwContext,D3DKMTDestroyHwContext,1146 diff --git a/libc/nt/gdi32/D3DKMTDestroyHwQueue.s b/libc/nt/gdi32/D3DKMTDestroyHwQueue.s new file mode 100644 index 00000000..d839149f --- /dev/null +++ b/libc/nt/gdi32/D3DKMTDestroyHwQueue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTDestroyHwQueue,D3DKMTDestroyHwQueue,1147 diff --git a/libc/nt/gdi32/D3DKMTDestroyKeyedMutex.s b/libc/nt/gdi32/D3DKMTDestroyKeyedMutex.s new file mode 100644 index 00000000..4f48b98c --- /dev/null +++ b/libc/nt/gdi32/D3DKMTDestroyKeyedMutex.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTDestroyKeyedMutex,D3DKMTDestroyKeyedMutex,1148 diff --git a/libc/nt/gdi32/D3DKMTDestroyOutputDupl.s b/libc/nt/gdi32/D3DKMTDestroyOutputDupl.s new file mode 100644 index 00000000..74085739 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTDestroyOutputDupl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTDestroyOutputDupl,D3DKMTDestroyOutputDupl,1149 diff --git a/libc/nt/gdi32/D3DKMTDestroyOverlay.s b/libc/nt/gdi32/D3DKMTDestroyOverlay.s new file mode 100644 index 00000000..76c06f63 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTDestroyOverlay.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTDestroyOverlay,D3DKMTDestroyOverlay,1150 diff --git a/libc/nt/gdi32/D3DKMTDestroyPagingQueue.s b/libc/nt/gdi32/D3DKMTDestroyPagingQueue.s new file mode 100644 index 00000000..eac9eff5 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTDestroyPagingQueue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTDestroyPagingQueue,D3DKMTDestroyPagingQueue,1151 diff --git a/libc/nt/gdi32/D3DKMTDestroyProtectedSession.s b/libc/nt/gdi32/D3DKMTDestroyProtectedSession.s new file mode 100644 index 00000000..1c326df3 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTDestroyProtectedSession.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTDestroyProtectedSession,D3DKMTDestroyProtectedSession,1152 diff --git a/libc/nt/gdi32/D3DKMTDestroySynchronizationObject.s b/libc/nt/gdi32/D3DKMTDestroySynchronizationObject.s new file mode 100644 index 00000000..69631131 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTDestroySynchronizationObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTDestroySynchronizationObject,D3DKMTDestroySynchronizationObject,1153 diff --git a/libc/nt/gdi32/D3DKMTDispMgrCreate.s b/libc/nt/gdi32/D3DKMTDispMgrCreate.s new file mode 100644 index 00000000..7fc88daa --- /dev/null +++ b/libc/nt/gdi32/D3DKMTDispMgrCreate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTDispMgrCreate,D3DKMTDispMgrCreate,1154 diff --git a/libc/nt/gdi32/D3DKMTDispMgrSourceOperation.s b/libc/nt/gdi32/D3DKMTDispMgrSourceOperation.s new file mode 100644 index 00000000..896cf17d --- /dev/null +++ b/libc/nt/gdi32/D3DKMTDispMgrSourceOperation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTDispMgrSourceOperation,D3DKMTDispMgrSourceOperation,1155 diff --git a/libc/nt/gdi32/D3DKMTDispMgrTargetOperation.s b/libc/nt/gdi32/D3DKMTDispMgrTargetOperation.s new file mode 100644 index 00000000..229306c7 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTDispMgrTargetOperation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTDispMgrTargetOperation,D3DKMTDispMgrTargetOperation,1156 diff --git a/libc/nt/gdi32/D3DKMTEnumAdapters.s b/libc/nt/gdi32/D3DKMTEnumAdapters.s new file mode 100644 index 00000000..10bd1f95 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTEnumAdapters.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTEnumAdapters,D3DKMTEnumAdapters,1157 diff --git a/libc/nt/gdi32/D3DKMTEnumAdapters2.s b/libc/nt/gdi32/D3DKMTEnumAdapters2.s new file mode 100644 index 00000000..55d3f6bf --- /dev/null +++ b/libc/nt/gdi32/D3DKMTEnumAdapters2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTEnumAdapters2,D3DKMTEnumAdapters2,1158 diff --git a/libc/nt/gdi32/D3DKMTEscape.s b/libc/nt/gdi32/D3DKMTEscape.s new file mode 100644 index 00000000..66f57354 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTEscape.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTEscape,D3DKMTEscape,1159 diff --git a/libc/nt/gdi32/D3DKMTEvict.s b/libc/nt/gdi32/D3DKMTEvict.s new file mode 100644 index 00000000..e7297d15 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTEvict.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTEvict,D3DKMTEvict,1160 diff --git a/libc/nt/gdi32/D3DKMTExtractBundleObject.s b/libc/nt/gdi32/D3DKMTExtractBundleObject.s new file mode 100644 index 00000000..8d906646 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTExtractBundleObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTExtractBundleObject,D3DKMTExtractBundleObject,1161 diff --git a/libc/nt/gdi32/D3DKMTFlipOverlay.s b/libc/nt/gdi32/D3DKMTFlipOverlay.s new file mode 100644 index 00000000..f02efd02 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTFlipOverlay.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTFlipOverlay,D3DKMTFlipOverlay,1162 diff --git a/libc/nt/gdi32/D3DKMTFlushHeapTransitions.s b/libc/nt/gdi32/D3DKMTFlushHeapTransitions.s new file mode 100644 index 00000000..54afe46f --- /dev/null +++ b/libc/nt/gdi32/D3DKMTFlushHeapTransitions.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTFlushHeapTransitions,D3DKMTFlushHeapTransitions,1163 diff --git a/libc/nt/gdi32/D3DKMTFreeGpuVirtualAddress.s b/libc/nt/gdi32/D3DKMTFreeGpuVirtualAddress.s new file mode 100644 index 00000000..2864aeda --- /dev/null +++ b/libc/nt/gdi32/D3DKMTFreeGpuVirtualAddress.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTFreeGpuVirtualAddress,D3DKMTFreeGpuVirtualAddress,1164 diff --git a/libc/nt/gdi32/D3DKMTGetAllocationPriority.s b/libc/nt/gdi32/D3DKMTGetAllocationPriority.s new file mode 100644 index 00000000..7b969643 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetAllocationPriority.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetAllocationPriority,D3DKMTGetAllocationPriority,1165 diff --git a/libc/nt/gdi32/D3DKMTGetCachedHybridQueryValue.s b/libc/nt/gdi32/D3DKMTGetCachedHybridQueryValue.s new file mode 100644 index 00000000..65463ea1 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetCachedHybridQueryValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetCachedHybridQueryValue,D3DKMTGetCachedHybridQueryValue,1166 diff --git a/libc/nt/gdi32/D3DKMTGetContextInProcessSchedulingPriority.s b/libc/nt/gdi32/D3DKMTGetContextInProcessSchedulingPriority.s new file mode 100644 index 00000000..78aa062a --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetContextInProcessSchedulingPriority.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetContextInProcessSchedulingPriority,D3DKMTGetContextInProcessSchedulingPriority,1167 diff --git a/libc/nt/gdi32/D3DKMTGetContextSchedulingPriority.s b/libc/nt/gdi32/D3DKMTGetContextSchedulingPriority.s new file mode 100644 index 00000000..672a71dc --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetContextSchedulingPriority.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetContextSchedulingPriority,D3DKMTGetContextSchedulingPriority,1168 diff --git a/libc/nt/gdi32/D3DKMTGetDWMVerticalBlankEvent.s b/libc/nt/gdi32/D3DKMTGetDWMVerticalBlankEvent.s new file mode 100644 index 00000000..39dc93d4 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetDWMVerticalBlankEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetDWMVerticalBlankEvent,D3DKMTGetDWMVerticalBlankEvent,1169 diff --git a/libc/nt/gdi32/D3DKMTGetDeviceState.s b/libc/nt/gdi32/D3DKMTGetDeviceState.s new file mode 100644 index 00000000..a00a1272 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetDeviceState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetDeviceState,D3DKMTGetDeviceState,1170 diff --git a/libc/nt/gdi32/D3DKMTGetDisplayModeList.s b/libc/nt/gdi32/D3DKMTGetDisplayModeList.s new file mode 100644 index 00000000..11e4854e --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetDisplayModeList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetDisplayModeList,D3DKMTGetDisplayModeList,1171 diff --git a/libc/nt/gdi32/D3DKMTGetMemoryBudgetTarget.s b/libc/nt/gdi32/D3DKMTGetMemoryBudgetTarget.s new file mode 100644 index 00000000..496b81b6 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetMemoryBudgetTarget.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetMemoryBudgetTarget,D3DKMTGetMemoryBudgetTarget,1172 diff --git a/libc/nt/gdi32/D3DKMTGetMultiPlaneOverlayCaps.s b/libc/nt/gdi32/D3DKMTGetMultiPlaneOverlayCaps.s new file mode 100644 index 00000000..48f7712c --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetMultiPlaneOverlayCaps.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetMultiPlaneOverlayCaps,D3DKMTGetMultiPlaneOverlayCaps,1173 diff --git a/libc/nt/gdi32/D3DKMTGetMultisampleMethodList.s b/libc/nt/gdi32/D3DKMTGetMultisampleMethodList.s new file mode 100644 index 00000000..afb3e8de --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetMultisampleMethodList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetMultisampleMethodList,D3DKMTGetMultisampleMethodList,1174 diff --git a/libc/nt/gdi32/D3DKMTGetOverlayState.s b/libc/nt/gdi32/D3DKMTGetOverlayState.s new file mode 100644 index 00000000..852e76d2 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetOverlayState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetOverlayState,D3DKMTGetOverlayState,1175 diff --git a/libc/nt/gdi32/D3DKMTGetPostCompositionCaps.s b/libc/nt/gdi32/D3DKMTGetPostCompositionCaps.s new file mode 100644 index 00000000..56ebd133 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetPostCompositionCaps.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetPostCompositionCaps,D3DKMTGetPostCompositionCaps,1176 diff --git a/libc/nt/gdi32/D3DKMTGetPresentHistory.s b/libc/nt/gdi32/D3DKMTGetPresentHistory.s new file mode 100644 index 00000000..066a8b9f --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetPresentHistory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetPresentHistory,D3DKMTGetPresentHistory,1177 diff --git a/libc/nt/gdi32/D3DKMTGetPresentQueueEvent.s b/libc/nt/gdi32/D3DKMTGetPresentQueueEvent.s new file mode 100644 index 00000000..89069382 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetPresentQueueEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetPresentQueueEvent,D3DKMTGetPresentQueueEvent,1178 diff --git a/libc/nt/gdi32/D3DKMTGetProcessDeviceRemovalSupport.s b/libc/nt/gdi32/D3DKMTGetProcessDeviceRemovalSupport.s new file mode 100644 index 00000000..2d438e4b --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetProcessDeviceRemovalSupport.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetProcessDeviceRemovalSupport,D3DKMTGetProcessDeviceRemovalSupport,1179 diff --git a/libc/nt/gdi32/D3DKMTGetProcessList.s b/libc/nt/gdi32/D3DKMTGetProcessList.s new file mode 100644 index 00000000..0147e2d3 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetProcessList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetProcessList,D3DKMTGetProcessList,1180 diff --git a/libc/nt/gdi32/D3DKMTGetProcessSchedulingPriorityBand.s b/libc/nt/gdi32/D3DKMTGetProcessSchedulingPriorityBand.s new file mode 100644 index 00000000..d8623873 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetProcessSchedulingPriorityBand.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetProcessSchedulingPriorityBand,D3DKMTGetProcessSchedulingPriorityBand,1181 diff --git a/libc/nt/gdi32/D3DKMTGetProcessSchedulingPriorityClass.s b/libc/nt/gdi32/D3DKMTGetProcessSchedulingPriorityClass.s new file mode 100644 index 00000000..bef2e2b6 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetProcessSchedulingPriorityClass.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetProcessSchedulingPriorityClass,D3DKMTGetProcessSchedulingPriorityClass,1182 diff --git a/libc/nt/gdi32/D3DKMTGetResourcePresentPrivateDriverData.s b/libc/nt/gdi32/D3DKMTGetResourcePresentPrivateDriverData.s new file mode 100644 index 00000000..c420d9e1 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetResourcePresentPrivateDriverData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetResourcePresentPrivateDriverData,D3DKMTGetResourcePresentPrivateDriverData,1183 diff --git a/libc/nt/gdi32/D3DKMTGetRuntimeData.s b/libc/nt/gdi32/D3DKMTGetRuntimeData.s new file mode 100644 index 00000000..e7fb0097 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetRuntimeData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetRuntimeData,D3DKMTGetRuntimeData,1184 diff --git a/libc/nt/gdi32/D3DKMTGetScanLine.s b/libc/nt/gdi32/D3DKMTGetScanLine.s new file mode 100644 index 00000000..c4761cc5 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetScanLine.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetScanLine,D3DKMTGetScanLine,1185 diff --git a/libc/nt/gdi32/D3DKMTGetSetSwapChainMetadata.s b/libc/nt/gdi32/D3DKMTGetSetSwapChainMetadata.s new file mode 100644 index 00000000..bfcc1b88 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetSetSwapChainMetadata.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetSetSwapChainMetadata,D3DKMTGetSetSwapChainMetadata,1186 diff --git a/libc/nt/gdi32/D3DKMTGetSharedPrimaryHandle.s b/libc/nt/gdi32/D3DKMTGetSharedPrimaryHandle.s new file mode 100644 index 00000000..d5e6285e --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetSharedPrimaryHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetSharedPrimaryHandle,D3DKMTGetSharedPrimaryHandle,1187 diff --git a/libc/nt/gdi32/D3DKMTGetSharedResourceAdapterLuid.s b/libc/nt/gdi32/D3DKMTGetSharedResourceAdapterLuid.s new file mode 100644 index 00000000..e80adcc6 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetSharedResourceAdapterLuid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetSharedResourceAdapterLuid,D3DKMTGetSharedResourceAdapterLuid,1188 diff --git a/libc/nt/gdi32/D3DKMTGetYieldPercentage.s b/libc/nt/gdi32/D3DKMTGetYieldPercentage.s new file mode 100644 index 00000000..e0cef1a7 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTGetYieldPercentage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTGetYieldPercentage,D3DKMTGetYieldPercentage,1189 diff --git a/libc/nt/gdi32/D3DKMTInvalidateActiveVidPn.s b/libc/nt/gdi32/D3DKMTInvalidateActiveVidPn.s new file mode 100644 index 00000000..0f8be8e5 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTInvalidateActiveVidPn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTInvalidateActiveVidPn,D3DKMTInvalidateActiveVidPn,1190 diff --git a/libc/nt/gdi32/D3DKMTInvalidateCache.s b/libc/nt/gdi32/D3DKMTInvalidateCache.s new file mode 100644 index 00000000..0320dfb1 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTInvalidateCache.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTInvalidateCache,D3DKMTInvalidateCache,1191 diff --git a/libc/nt/gdi32/D3DKMTLock.s b/libc/nt/gdi32/D3DKMTLock.s new file mode 100644 index 00000000..82cba5ea --- /dev/null +++ b/libc/nt/gdi32/D3DKMTLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTLock,D3DKMTLock,1192 diff --git a/libc/nt/gdi32/D3DKMTLock2.s b/libc/nt/gdi32/D3DKMTLock2.s new file mode 100644 index 00000000..cfe68a31 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTLock2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTLock2,D3DKMTLock2,1193 diff --git a/libc/nt/gdi32/D3DKMTMakeResident.s b/libc/nt/gdi32/D3DKMTMakeResident.s new file mode 100644 index 00000000..5cc73c85 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTMakeResident.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTMakeResident,D3DKMTMakeResident,1194 diff --git a/libc/nt/gdi32/D3DKMTMapGpuVirtualAddress.s b/libc/nt/gdi32/D3DKMTMapGpuVirtualAddress.s new file mode 100644 index 00000000..43037f46 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTMapGpuVirtualAddress.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTMapGpuVirtualAddress,D3DKMTMapGpuVirtualAddress,1195 diff --git a/libc/nt/gdi32/D3DKMTMarkDeviceAsError.s b/libc/nt/gdi32/D3DKMTMarkDeviceAsError.s new file mode 100644 index 00000000..3987259c --- /dev/null +++ b/libc/nt/gdi32/D3DKMTMarkDeviceAsError.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTMarkDeviceAsError,D3DKMTMarkDeviceAsError,1196 diff --git a/libc/nt/gdi32/D3DKMTNetDispGetNextChunkInfo.s b/libc/nt/gdi32/D3DKMTNetDispGetNextChunkInfo.s new file mode 100644 index 00000000..8e36790a --- /dev/null +++ b/libc/nt/gdi32/D3DKMTNetDispGetNextChunkInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTNetDispGetNextChunkInfo,D3DKMTNetDispGetNextChunkInfo,1197 diff --git a/libc/nt/gdi32/D3DKMTNetDispQueryMiracastDisplayDeviceStatus.s b/libc/nt/gdi32/D3DKMTNetDispQueryMiracastDisplayDeviceStatus.s new file mode 100644 index 00000000..d23ef7cb --- /dev/null +++ b/libc/nt/gdi32/D3DKMTNetDispQueryMiracastDisplayDeviceStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTNetDispQueryMiracastDisplayDeviceStatus,D3DKMTNetDispQueryMiracastDisplayDeviceStatus,1198 diff --git a/libc/nt/gdi32/D3DKMTNetDispQueryMiracastDisplayDeviceSupport.s b/libc/nt/gdi32/D3DKMTNetDispQueryMiracastDisplayDeviceSupport.s new file mode 100644 index 00000000..ac36597b --- /dev/null +++ b/libc/nt/gdi32/D3DKMTNetDispQueryMiracastDisplayDeviceSupport.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTNetDispQueryMiracastDisplayDeviceSupport,D3DKMTNetDispQueryMiracastDisplayDeviceSupport,1199 diff --git a/libc/nt/gdi32/D3DKMTNetDispStartMiracastDisplayDevice.s b/libc/nt/gdi32/D3DKMTNetDispStartMiracastDisplayDevice.s new file mode 100644 index 00000000..4b32fd2d --- /dev/null +++ b/libc/nt/gdi32/D3DKMTNetDispStartMiracastDisplayDevice.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTNetDispStartMiracastDisplayDevice,D3DKMTNetDispStartMiracastDisplayDevice,1200 diff --git a/libc/nt/gdi32/D3DKMTNetDispStartMiracastDisplayDevice2.s b/libc/nt/gdi32/D3DKMTNetDispStartMiracastDisplayDevice2.s new file mode 100644 index 00000000..7f513a10 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTNetDispStartMiracastDisplayDevice2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTNetDispStartMiracastDisplayDevice2,D3DKMTNetDispStartMiracastDisplayDevice2,1201 diff --git a/libc/nt/gdi32/D3DKMTNetDispStartMiracastDisplayDeviceEx.s b/libc/nt/gdi32/D3DKMTNetDispStartMiracastDisplayDeviceEx.s new file mode 100644 index 00000000..16a26270 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTNetDispStartMiracastDisplayDeviceEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTNetDispStartMiracastDisplayDeviceEx,D3DKMTNetDispStartMiracastDisplayDeviceEx,1202 diff --git a/libc/nt/gdi32/D3DKMTNetDispStopMiracastDisplayDevice.s b/libc/nt/gdi32/D3DKMTNetDispStopMiracastDisplayDevice.s new file mode 100644 index 00000000..772ee83c --- /dev/null +++ b/libc/nt/gdi32/D3DKMTNetDispStopMiracastDisplayDevice.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTNetDispStopMiracastDisplayDevice,D3DKMTNetDispStopMiracastDisplayDevice,1203 diff --git a/libc/nt/gdi32/D3DKMTNetDispStopSessions.s b/libc/nt/gdi32/D3DKMTNetDispStopSessions.s new file mode 100644 index 00000000..125e539f --- /dev/null +++ b/libc/nt/gdi32/D3DKMTNetDispStopSessions.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTNetDispStopSessions,D3DKMTNetDispStopSessions,1204 diff --git a/libc/nt/gdi32/D3DKMTOfferAllocations.s b/libc/nt/gdi32/D3DKMTOfferAllocations.s new file mode 100644 index 00000000..d402381e --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOfferAllocations.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOfferAllocations,D3DKMTOfferAllocations,1205 diff --git a/libc/nt/gdi32/D3DKMTOpenAdapterFromDeviceName.s b/libc/nt/gdi32/D3DKMTOpenAdapterFromDeviceName.s new file mode 100644 index 00000000..06e5da58 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenAdapterFromDeviceName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenAdapterFromDeviceName,D3DKMTOpenAdapterFromDeviceName,1206 diff --git a/libc/nt/gdi32/D3DKMTOpenAdapterFromGdiDisplayName.s b/libc/nt/gdi32/D3DKMTOpenAdapterFromGdiDisplayName.s new file mode 100644 index 00000000..9cee30b7 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenAdapterFromGdiDisplayName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenAdapterFromGdiDisplayName,D3DKMTOpenAdapterFromGdiDisplayName,1207 diff --git a/libc/nt/gdi32/D3DKMTOpenAdapterFromHdc.s b/libc/nt/gdi32/D3DKMTOpenAdapterFromHdc.s new file mode 100644 index 00000000..b20aecc3 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenAdapterFromHdc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenAdapterFromHdc,D3DKMTOpenAdapterFromHdc,1208 diff --git a/libc/nt/gdi32/D3DKMTOpenAdapterFromLuid.s b/libc/nt/gdi32/D3DKMTOpenAdapterFromLuid.s new file mode 100644 index 00000000..afac5b7a --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenAdapterFromLuid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenAdapterFromLuid,D3DKMTOpenAdapterFromLuid,1209 diff --git a/libc/nt/gdi32/D3DKMTOpenBundleObjectNtHandleFromName.s b/libc/nt/gdi32/D3DKMTOpenBundleObjectNtHandleFromName.s new file mode 100644 index 00000000..715be2f7 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenBundleObjectNtHandleFromName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenBundleObjectNtHandleFromName,D3DKMTOpenBundleObjectNtHandleFromName,1210 diff --git a/libc/nt/gdi32/D3DKMTOpenKeyedMutex.s b/libc/nt/gdi32/D3DKMTOpenKeyedMutex.s new file mode 100644 index 00000000..2afdafe9 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenKeyedMutex.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenKeyedMutex,D3DKMTOpenKeyedMutex,1211 diff --git a/libc/nt/gdi32/D3DKMTOpenKeyedMutex2.s b/libc/nt/gdi32/D3DKMTOpenKeyedMutex2.s new file mode 100644 index 00000000..bd26b527 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenKeyedMutex2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenKeyedMutex2,D3DKMTOpenKeyedMutex2,1212 diff --git a/libc/nt/gdi32/D3DKMTOpenKeyedMutexFromNtHandle.s b/libc/nt/gdi32/D3DKMTOpenKeyedMutexFromNtHandle.s new file mode 100644 index 00000000..eebbd751 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenKeyedMutexFromNtHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenKeyedMutexFromNtHandle,D3DKMTOpenKeyedMutexFromNtHandle,1213 diff --git a/libc/nt/gdi32/D3DKMTOpenNtHandleFromName.s b/libc/nt/gdi32/D3DKMTOpenNtHandleFromName.s new file mode 100644 index 00000000..d30ebe33 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenNtHandleFromName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenNtHandleFromName,D3DKMTOpenNtHandleFromName,1214 diff --git a/libc/nt/gdi32/D3DKMTOpenProtectedSessionFromNtHandle.s b/libc/nt/gdi32/D3DKMTOpenProtectedSessionFromNtHandle.s new file mode 100644 index 00000000..b4fcb931 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenProtectedSessionFromNtHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenProtectedSessionFromNtHandle,D3DKMTOpenProtectedSessionFromNtHandle,1215 diff --git a/libc/nt/gdi32/D3DKMTOpenResource.s b/libc/nt/gdi32/D3DKMTOpenResource.s new file mode 100644 index 00000000..60195fe5 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenResource,D3DKMTOpenResource,1216 diff --git a/libc/nt/gdi32/D3DKMTOpenResource2.s b/libc/nt/gdi32/D3DKMTOpenResource2.s new file mode 100644 index 00000000..1a0ed0e0 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenResource2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenResource2,D3DKMTOpenResource2,1217 diff --git a/libc/nt/gdi32/D3DKMTOpenResourceFromNtHandle.s b/libc/nt/gdi32/D3DKMTOpenResourceFromNtHandle.s new file mode 100644 index 00000000..eeeb2aa9 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenResourceFromNtHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenResourceFromNtHandle,D3DKMTOpenResourceFromNtHandle,1218 diff --git a/libc/nt/gdi32/D3DKMTOpenSwapChain.s b/libc/nt/gdi32/D3DKMTOpenSwapChain.s new file mode 100644 index 00000000..2e76c80e --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenSwapChain.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenSwapChain,D3DKMTOpenSwapChain,1219 diff --git a/libc/nt/gdi32/D3DKMTOpenSyncObjectFromNtHandle.s b/libc/nt/gdi32/D3DKMTOpenSyncObjectFromNtHandle.s new file mode 100644 index 00000000..43500662 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenSyncObjectFromNtHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenSyncObjectFromNtHandle,D3DKMTOpenSyncObjectFromNtHandle,1220 diff --git a/libc/nt/gdi32/D3DKMTOpenSyncObjectFromNtHandle2.s b/libc/nt/gdi32/D3DKMTOpenSyncObjectFromNtHandle2.s new file mode 100644 index 00000000..57c003a7 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenSyncObjectFromNtHandle2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenSyncObjectFromNtHandle2,D3DKMTOpenSyncObjectFromNtHandle2,1221 diff --git a/libc/nt/gdi32/D3DKMTOpenSyncObjectNtHandleFromName.s b/libc/nt/gdi32/D3DKMTOpenSyncObjectNtHandleFromName.s new file mode 100644 index 00000000..a615e624 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenSyncObjectNtHandleFromName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenSyncObjectNtHandleFromName,D3DKMTOpenSyncObjectNtHandleFromName,1222 diff --git a/libc/nt/gdi32/D3DKMTOpenSynchronizationObject.s b/libc/nt/gdi32/D3DKMTOpenSynchronizationObject.s new file mode 100644 index 00000000..20558fc5 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOpenSynchronizationObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOpenSynchronizationObject,D3DKMTOpenSynchronizationObject,1223 diff --git a/libc/nt/gdi32/D3DKMTOutputDuplGetFrameInfo.s b/libc/nt/gdi32/D3DKMTOutputDuplGetFrameInfo.s new file mode 100644 index 00000000..bacde9f7 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOutputDuplGetFrameInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOutputDuplGetFrameInfo,D3DKMTOutputDuplGetFrameInfo,1224 diff --git a/libc/nt/gdi32/D3DKMTOutputDuplGetMetaData.s b/libc/nt/gdi32/D3DKMTOutputDuplGetMetaData.s new file mode 100644 index 00000000..0186cb78 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOutputDuplGetMetaData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOutputDuplGetMetaData,D3DKMTOutputDuplGetMetaData,1225 diff --git a/libc/nt/gdi32/D3DKMTOutputDuplGetPointerShapeData.s b/libc/nt/gdi32/D3DKMTOutputDuplGetPointerShapeData.s new file mode 100644 index 00000000..b16e4244 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOutputDuplGetPointerShapeData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOutputDuplGetPointerShapeData,D3DKMTOutputDuplGetPointerShapeData,1226 diff --git a/libc/nt/gdi32/D3DKMTOutputDuplPresent.s b/libc/nt/gdi32/D3DKMTOutputDuplPresent.s new file mode 100644 index 00000000..57930d9e --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOutputDuplPresent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOutputDuplPresent,D3DKMTOutputDuplPresent,1227 diff --git a/libc/nt/gdi32/D3DKMTOutputDuplReleaseFrame.s b/libc/nt/gdi32/D3DKMTOutputDuplReleaseFrame.s new file mode 100644 index 00000000..cad1a779 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTOutputDuplReleaseFrame.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTOutputDuplReleaseFrame,D3DKMTOutputDuplReleaseFrame,1228 diff --git a/libc/nt/gdi32/D3DKMTPinDirectFlipResources.s b/libc/nt/gdi32/D3DKMTPinDirectFlipResources.s new file mode 100644 index 00000000..a0648245 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTPinDirectFlipResources.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTPinDirectFlipResources,D3DKMTPinDirectFlipResources,1229 diff --git a/libc/nt/gdi32/D3DKMTPollDisplayChildren.s b/libc/nt/gdi32/D3DKMTPollDisplayChildren.s new file mode 100644 index 00000000..921cef99 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTPollDisplayChildren.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTPollDisplayChildren,D3DKMTPollDisplayChildren,1230 diff --git a/libc/nt/gdi32/D3DKMTPresent.s b/libc/nt/gdi32/D3DKMTPresent.s new file mode 100644 index 00000000..d9579929 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTPresent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTPresent,D3DKMTPresent,1231 diff --git a/libc/nt/gdi32/D3DKMTPresentMultiPlaneOverlay.s b/libc/nt/gdi32/D3DKMTPresentMultiPlaneOverlay.s new file mode 100644 index 00000000..edc3f019 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTPresentMultiPlaneOverlay.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTPresentMultiPlaneOverlay,D3DKMTPresentMultiPlaneOverlay,1232 diff --git a/libc/nt/gdi32/D3DKMTPresentMultiPlaneOverlay2.s b/libc/nt/gdi32/D3DKMTPresentMultiPlaneOverlay2.s new file mode 100644 index 00000000..e190bdf7 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTPresentMultiPlaneOverlay2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTPresentMultiPlaneOverlay2,D3DKMTPresentMultiPlaneOverlay2,1233 diff --git a/libc/nt/gdi32/D3DKMTPresentMultiPlaneOverlay3.s b/libc/nt/gdi32/D3DKMTPresentMultiPlaneOverlay3.s new file mode 100644 index 00000000..d2bdf24f --- /dev/null +++ b/libc/nt/gdi32/D3DKMTPresentMultiPlaneOverlay3.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTPresentMultiPlaneOverlay3,D3DKMTPresentMultiPlaneOverlay3,1234 diff --git a/libc/nt/gdi32/D3DKMTPresentRedirected.s b/libc/nt/gdi32/D3DKMTPresentRedirected.s new file mode 100644 index 00000000..cd1d48cc --- /dev/null +++ b/libc/nt/gdi32/D3DKMTPresentRedirected.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTPresentRedirected,D3DKMTPresentRedirected,1235 diff --git a/libc/nt/gdi32/D3DKMTQueryAdapterInfo.s b/libc/nt/gdi32/D3DKMTQueryAdapterInfo.s new file mode 100644 index 00000000..1119744d --- /dev/null +++ b/libc/nt/gdi32/D3DKMTQueryAdapterInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTQueryAdapterInfo,D3DKMTQueryAdapterInfo,1236 diff --git a/libc/nt/gdi32/D3DKMTQueryAllocationResidency.s b/libc/nt/gdi32/D3DKMTQueryAllocationResidency.s new file mode 100644 index 00000000..ba1b20f3 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTQueryAllocationResidency.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTQueryAllocationResidency,D3DKMTQueryAllocationResidency,1237 diff --git a/libc/nt/gdi32/D3DKMTQueryClockCalibration.s b/libc/nt/gdi32/D3DKMTQueryClockCalibration.s new file mode 100644 index 00000000..0536fd06 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTQueryClockCalibration.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTQueryClockCalibration,D3DKMTQueryClockCalibration,1238 diff --git a/libc/nt/gdi32/D3DKMTQueryFSEBlock.s b/libc/nt/gdi32/D3DKMTQueryFSEBlock.s new file mode 100644 index 00000000..dc6f6035 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTQueryFSEBlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTQueryFSEBlock,D3DKMTQueryFSEBlock,1239 diff --git a/libc/nt/gdi32/D3DKMTQueryProcessOfferInfo.s b/libc/nt/gdi32/D3DKMTQueryProcessOfferInfo.s new file mode 100644 index 00000000..1156ae18 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTQueryProcessOfferInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTQueryProcessOfferInfo,D3DKMTQueryProcessOfferInfo,1240 diff --git a/libc/nt/gdi32/D3DKMTQueryProtectedSessionInfoFromNtHandle.s b/libc/nt/gdi32/D3DKMTQueryProtectedSessionInfoFromNtHandle.s new file mode 100644 index 00000000..0080722c --- /dev/null +++ b/libc/nt/gdi32/D3DKMTQueryProtectedSessionInfoFromNtHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTQueryProtectedSessionInfoFromNtHandle,D3DKMTQueryProtectedSessionInfoFromNtHandle,1241 diff --git a/libc/nt/gdi32/D3DKMTQueryProtectedSessionStatus.s b/libc/nt/gdi32/D3DKMTQueryProtectedSessionStatus.s new file mode 100644 index 00000000..78bf645d --- /dev/null +++ b/libc/nt/gdi32/D3DKMTQueryProtectedSessionStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTQueryProtectedSessionStatus,D3DKMTQueryProtectedSessionStatus,1242 diff --git a/libc/nt/gdi32/D3DKMTQueryRemoteVidPnSourceFromGdiDisplayName.s b/libc/nt/gdi32/D3DKMTQueryRemoteVidPnSourceFromGdiDisplayName.s new file mode 100644 index 00000000..824f6014 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTQueryRemoteVidPnSourceFromGdiDisplayName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTQueryRemoteVidPnSourceFromGdiDisplayName,D3DKMTQueryRemoteVidPnSourceFromGdiDisplayName,1243 diff --git a/libc/nt/gdi32/D3DKMTQueryResourceInfo.s b/libc/nt/gdi32/D3DKMTQueryResourceInfo.s new file mode 100644 index 00000000..aded1df0 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTQueryResourceInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTQueryResourceInfo,D3DKMTQueryResourceInfo,1244 diff --git a/libc/nt/gdi32/D3DKMTQueryResourceInfoFromNtHandle.s b/libc/nt/gdi32/D3DKMTQueryResourceInfoFromNtHandle.s new file mode 100644 index 00000000..302be62d --- /dev/null +++ b/libc/nt/gdi32/D3DKMTQueryResourceInfoFromNtHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTQueryResourceInfoFromNtHandle,D3DKMTQueryResourceInfoFromNtHandle,1245 diff --git a/libc/nt/gdi32/D3DKMTQueryStatistics.s b/libc/nt/gdi32/D3DKMTQueryStatistics.s new file mode 100644 index 00000000..37429cf9 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTQueryStatistics.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTQueryStatistics,D3DKMTQueryStatistics,1246 diff --git a/libc/nt/gdi32/D3DKMTQueryVidPnExclusiveOwnership.s b/libc/nt/gdi32/D3DKMTQueryVidPnExclusiveOwnership.s new file mode 100644 index 00000000..8afe1930 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTQueryVidPnExclusiveOwnership.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTQueryVidPnExclusiveOwnership,D3DKMTQueryVidPnExclusiveOwnership,1247 diff --git a/libc/nt/gdi32/D3DKMTQueryVideoMemoryInfo.s b/libc/nt/gdi32/D3DKMTQueryVideoMemoryInfo.s new file mode 100644 index 00000000..90eb4226 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTQueryVideoMemoryInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTQueryVideoMemoryInfo,D3DKMTQueryVideoMemoryInfo,1248 diff --git a/libc/nt/gdi32/D3DKMTReclaimAllocations.s b/libc/nt/gdi32/D3DKMTReclaimAllocations.s new file mode 100644 index 00000000..af150883 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTReclaimAllocations.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTReclaimAllocations,D3DKMTReclaimAllocations,1249 diff --git a/libc/nt/gdi32/D3DKMTReclaimAllocations2.s b/libc/nt/gdi32/D3DKMTReclaimAllocations2.s new file mode 100644 index 00000000..4988f387 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTReclaimAllocations2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTReclaimAllocations2,D3DKMTReclaimAllocations2,1250 diff --git a/libc/nt/gdi32/D3DKMTRegisterTrimNotification.s b/libc/nt/gdi32/D3DKMTRegisterTrimNotification.s new file mode 100644 index 00000000..3207cd9a --- /dev/null +++ b/libc/nt/gdi32/D3DKMTRegisterTrimNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTRegisterTrimNotification,D3DKMTRegisterTrimNotification,1251 diff --git a/libc/nt/gdi32/D3DKMTRegisterVailProcess.s b/libc/nt/gdi32/D3DKMTRegisterVailProcess.s new file mode 100644 index 00000000..4a5210e5 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTRegisterVailProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTRegisterVailProcess,D3DKMTRegisterVailProcess,1252 diff --git a/libc/nt/gdi32/D3DKMTReleaseKeyedMutex.s b/libc/nt/gdi32/D3DKMTReleaseKeyedMutex.s new file mode 100644 index 00000000..d32a6a71 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTReleaseKeyedMutex.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTReleaseKeyedMutex,D3DKMTReleaseKeyedMutex,1253 diff --git a/libc/nt/gdi32/D3DKMTReleaseKeyedMutex2.s b/libc/nt/gdi32/D3DKMTReleaseKeyedMutex2.s new file mode 100644 index 00000000..f47ac43a --- /dev/null +++ b/libc/nt/gdi32/D3DKMTReleaseKeyedMutex2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTReleaseKeyedMutex2,D3DKMTReleaseKeyedMutex2,1254 diff --git a/libc/nt/gdi32/D3DKMTReleaseProcessVidPnSourceOwners.s b/libc/nt/gdi32/D3DKMTReleaseProcessVidPnSourceOwners.s new file mode 100644 index 00000000..187ad6d2 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTReleaseProcessVidPnSourceOwners.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTReleaseProcessVidPnSourceOwners,D3DKMTReleaseProcessVidPnSourceOwners,1255 diff --git a/libc/nt/gdi32/D3DKMTReleaseSwapChain.s b/libc/nt/gdi32/D3DKMTReleaseSwapChain.s new file mode 100644 index 00000000..903c5897 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTReleaseSwapChain.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTReleaseSwapChain,D3DKMTReleaseSwapChain,1256 diff --git a/libc/nt/gdi32/D3DKMTRemoveSurfaceFromSwapChain.s b/libc/nt/gdi32/D3DKMTRemoveSurfaceFromSwapChain.s new file mode 100644 index 00000000..1fdc9c2f --- /dev/null +++ b/libc/nt/gdi32/D3DKMTRemoveSurfaceFromSwapChain.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTRemoveSurfaceFromSwapChain,D3DKMTRemoveSurfaceFromSwapChain,1257 diff --git a/libc/nt/gdi32/D3DKMTRender.s b/libc/nt/gdi32/D3DKMTRender.s new file mode 100644 index 00000000..fac037fa --- /dev/null +++ b/libc/nt/gdi32/D3DKMTRender.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTRender,D3DKMTRender,1258 diff --git a/libc/nt/gdi32/D3DKMTReserveGpuVirtualAddress.s b/libc/nt/gdi32/D3DKMTReserveGpuVirtualAddress.s new file mode 100644 index 00000000..7d821894 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTReserveGpuVirtualAddress.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTReserveGpuVirtualAddress,D3DKMTReserveGpuVirtualAddress,1259 diff --git a/libc/nt/gdi32/D3DKMTSetAllocationPriority.s b/libc/nt/gdi32/D3DKMTSetAllocationPriority.s new file mode 100644 index 00000000..90a9746e --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetAllocationPriority.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetAllocationPriority,D3DKMTSetAllocationPriority,1260 diff --git a/libc/nt/gdi32/D3DKMTSetContextInProcessSchedulingPriority.s b/libc/nt/gdi32/D3DKMTSetContextInProcessSchedulingPriority.s new file mode 100644 index 00000000..c321ea8c --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetContextInProcessSchedulingPriority.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetContextInProcessSchedulingPriority,D3DKMTSetContextInProcessSchedulingPriority,1261 diff --git a/libc/nt/gdi32/D3DKMTSetContextSchedulingPriority.s b/libc/nt/gdi32/D3DKMTSetContextSchedulingPriority.s new file mode 100644 index 00000000..60364a5c --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetContextSchedulingPriority.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetContextSchedulingPriority,D3DKMTSetContextSchedulingPriority,1262 diff --git a/libc/nt/gdi32/D3DKMTSetDisplayMode.s b/libc/nt/gdi32/D3DKMTSetDisplayMode.s new file mode 100644 index 00000000..075d6c3b --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetDisplayMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetDisplayMode,D3DKMTSetDisplayMode,1263 diff --git a/libc/nt/gdi32/D3DKMTSetDisplayPrivateDriverFormat.s b/libc/nt/gdi32/D3DKMTSetDisplayPrivateDriverFormat.s new file mode 100644 index 00000000..1151d2bb --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetDisplayPrivateDriverFormat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetDisplayPrivateDriverFormat,D3DKMTSetDisplayPrivateDriverFormat,1264 diff --git a/libc/nt/gdi32/D3DKMTSetDodIndirectSwapchain.s b/libc/nt/gdi32/D3DKMTSetDodIndirectSwapchain.s new file mode 100644 index 00000000..33cd993c --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetDodIndirectSwapchain.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetDodIndirectSwapchain,D3DKMTSetDodIndirectSwapchain,1265 diff --git a/libc/nt/gdi32/D3DKMTSetFSEBlock.s b/libc/nt/gdi32/D3DKMTSetFSEBlock.s new file mode 100644 index 00000000..86eb35f8 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetFSEBlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetFSEBlock,D3DKMTSetFSEBlock,1266 diff --git a/libc/nt/gdi32/D3DKMTSetGammaRamp.s b/libc/nt/gdi32/D3DKMTSetGammaRamp.s new file mode 100644 index 00000000..9d0ef407 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetGammaRamp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetGammaRamp,D3DKMTSetGammaRamp,1267 diff --git a/libc/nt/gdi32/D3DKMTSetHwProtectionTeardownRecovery.s b/libc/nt/gdi32/D3DKMTSetHwProtectionTeardownRecovery.s new file mode 100644 index 00000000..e99cd7c5 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetHwProtectionTeardownRecovery.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetHwProtectionTeardownRecovery,D3DKMTSetHwProtectionTeardownRecovery,1268 diff --git a/libc/nt/gdi32/D3DKMTSetMemoryBudgetTarget.s b/libc/nt/gdi32/D3DKMTSetMemoryBudgetTarget.s new file mode 100644 index 00000000..25ddf4b4 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetMemoryBudgetTarget.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetMemoryBudgetTarget,D3DKMTSetMemoryBudgetTarget,1269 diff --git a/libc/nt/gdi32/D3DKMTSetMonitorColorSpaceTransform.s b/libc/nt/gdi32/D3DKMTSetMonitorColorSpaceTransform.s new file mode 100644 index 00000000..94108f4b --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetMonitorColorSpaceTransform.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetMonitorColorSpaceTransform,D3DKMTSetMonitorColorSpaceTransform,1270 diff --git a/libc/nt/gdi32/D3DKMTSetProcessDeviceRemovalSupport.s b/libc/nt/gdi32/D3DKMTSetProcessDeviceRemovalSupport.s new file mode 100644 index 00000000..d557ee62 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetProcessDeviceRemovalSupport.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetProcessDeviceRemovalSupport,D3DKMTSetProcessDeviceRemovalSupport,1271 diff --git a/libc/nt/gdi32/D3DKMTSetProcessSchedulingPriorityBand.s b/libc/nt/gdi32/D3DKMTSetProcessSchedulingPriorityBand.s new file mode 100644 index 00000000..21d7e810 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetProcessSchedulingPriorityBand.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetProcessSchedulingPriorityBand,D3DKMTSetProcessSchedulingPriorityBand,1272 diff --git a/libc/nt/gdi32/D3DKMTSetProcessSchedulingPriorityClass.s b/libc/nt/gdi32/D3DKMTSetProcessSchedulingPriorityClass.s new file mode 100644 index 00000000..e1eb3720 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetProcessSchedulingPriorityClass.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetProcessSchedulingPriorityClass,D3DKMTSetProcessSchedulingPriorityClass,1273 diff --git a/libc/nt/gdi32/D3DKMTSetQueuedLimit.s b/libc/nt/gdi32/D3DKMTSetQueuedLimit.s new file mode 100644 index 00000000..22be1ebf --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetQueuedLimit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetQueuedLimit,D3DKMTSetQueuedLimit,1274 diff --git a/libc/nt/gdi32/D3DKMTSetStablePowerState.s b/libc/nt/gdi32/D3DKMTSetStablePowerState.s new file mode 100644 index 00000000..f43d2c56 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetStablePowerState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetStablePowerState,D3DKMTSetStablePowerState,1275 diff --git a/libc/nt/gdi32/D3DKMTSetStereoEnabled.s b/libc/nt/gdi32/D3DKMTSetStereoEnabled.s new file mode 100644 index 00000000..4afa6b2d --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetStereoEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetStereoEnabled,D3DKMTSetStereoEnabled,1276 diff --git a/libc/nt/gdi32/D3DKMTSetSyncRefreshCountWaitTarget.s b/libc/nt/gdi32/D3DKMTSetSyncRefreshCountWaitTarget.s new file mode 100644 index 00000000..f2bc639a --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetSyncRefreshCountWaitTarget.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetSyncRefreshCountWaitTarget,D3DKMTSetSyncRefreshCountWaitTarget,1277 diff --git a/libc/nt/gdi32/D3DKMTSetVidPnSourceHwProtection.s b/libc/nt/gdi32/D3DKMTSetVidPnSourceHwProtection.s new file mode 100644 index 00000000..c3de6860 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetVidPnSourceHwProtection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetVidPnSourceHwProtection,D3DKMTSetVidPnSourceHwProtection,1278 diff --git a/libc/nt/gdi32/D3DKMTSetVidPnSourceOwner.s b/libc/nt/gdi32/D3DKMTSetVidPnSourceOwner.s new file mode 100644 index 00000000..b6de3ffa --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetVidPnSourceOwner.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetVidPnSourceOwner,D3DKMTSetVidPnSourceOwner,1279 diff --git a/libc/nt/gdi32/D3DKMTSetVidPnSourceOwner1.s b/libc/nt/gdi32/D3DKMTSetVidPnSourceOwner1.s new file mode 100644 index 00000000..1b9a9685 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetVidPnSourceOwner1.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetVidPnSourceOwner1,D3DKMTSetVidPnSourceOwner1,1280 diff --git a/libc/nt/gdi32/D3DKMTSetVidPnSourceOwner2.s b/libc/nt/gdi32/D3DKMTSetVidPnSourceOwner2.s new file mode 100644 index 00000000..82d5fd1e --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetVidPnSourceOwner2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetVidPnSourceOwner2,D3DKMTSetVidPnSourceOwner2,1281 diff --git a/libc/nt/gdi32/D3DKMTSetYieldPercentage.s b/libc/nt/gdi32/D3DKMTSetYieldPercentage.s new file mode 100644 index 00000000..79beb24c --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSetYieldPercentage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSetYieldPercentage,D3DKMTSetYieldPercentage,1282 diff --git a/libc/nt/gdi32/D3DKMTShareObjects.s b/libc/nt/gdi32/D3DKMTShareObjects.s new file mode 100644 index 00000000..04f397b3 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTShareObjects.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTShareObjects,D3DKMTShareObjects,1283 diff --git a/libc/nt/gdi32/D3DKMTSharedPrimaryLockNotification.s b/libc/nt/gdi32/D3DKMTSharedPrimaryLockNotification.s new file mode 100644 index 00000000..aa9bf29f --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSharedPrimaryLockNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSharedPrimaryLockNotification,D3DKMTSharedPrimaryLockNotification,1284 diff --git a/libc/nt/gdi32/D3DKMTSharedPrimaryUnLockNotification.s b/libc/nt/gdi32/D3DKMTSharedPrimaryUnLockNotification.s new file mode 100644 index 00000000..0b34d37d --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSharedPrimaryUnLockNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSharedPrimaryUnLockNotification,D3DKMTSharedPrimaryUnLockNotification,1285 diff --git a/libc/nt/gdi32/D3DKMTSignalSynchronizationObject.s b/libc/nt/gdi32/D3DKMTSignalSynchronizationObject.s new file mode 100644 index 00000000..a717af89 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSignalSynchronizationObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSignalSynchronizationObject,D3DKMTSignalSynchronizationObject,1286 diff --git a/libc/nt/gdi32/D3DKMTSignalSynchronizationObject2.s b/libc/nt/gdi32/D3DKMTSignalSynchronizationObject2.s new file mode 100644 index 00000000..5f68b8a6 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSignalSynchronizationObject2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSignalSynchronizationObject2,D3DKMTSignalSynchronizationObject2,1287 diff --git a/libc/nt/gdi32/D3DKMTSignalSynchronizationObjectFromCpu.s b/libc/nt/gdi32/D3DKMTSignalSynchronizationObjectFromCpu.s new file mode 100644 index 00000000..1f9d3ab6 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSignalSynchronizationObjectFromCpu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSignalSynchronizationObjectFromCpu,D3DKMTSignalSynchronizationObjectFromCpu,1288 diff --git a/libc/nt/gdi32/D3DKMTSignalSynchronizationObjectFromGpu.s b/libc/nt/gdi32/D3DKMTSignalSynchronizationObjectFromGpu.s new file mode 100644 index 00000000..678cc8c8 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSignalSynchronizationObjectFromGpu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSignalSynchronizationObjectFromGpu,D3DKMTSignalSynchronizationObjectFromGpu,1289 diff --git a/libc/nt/gdi32/D3DKMTSignalSynchronizationObjectFromGpu2.s b/libc/nt/gdi32/D3DKMTSignalSynchronizationObjectFromGpu2.s new file mode 100644 index 00000000..dfa321da --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSignalSynchronizationObjectFromGpu2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSignalSynchronizationObjectFromGpu2,D3DKMTSignalSynchronizationObjectFromGpu2,1290 diff --git a/libc/nt/gdi32/D3DKMTSubmitCommand.s b/libc/nt/gdi32/D3DKMTSubmitCommand.s new file mode 100644 index 00000000..d62d7840 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSubmitCommand.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSubmitCommand,D3DKMTSubmitCommand,1291 diff --git a/libc/nt/gdi32/D3DKMTSubmitCommandToHwQueue.s b/libc/nt/gdi32/D3DKMTSubmitCommandToHwQueue.s new file mode 100644 index 00000000..05b2a9ff --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSubmitCommandToHwQueue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSubmitCommandToHwQueue,D3DKMTSubmitCommandToHwQueue,1292 diff --git a/libc/nt/gdi32/D3DKMTSubmitPresentBltToHwQueue.s b/libc/nt/gdi32/D3DKMTSubmitPresentBltToHwQueue.s new file mode 100644 index 00000000..ff4d6f0c --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSubmitPresentBltToHwQueue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSubmitPresentBltToHwQueue,D3DKMTSubmitPresentBltToHwQueue,1293 diff --git a/libc/nt/gdi32/D3DKMTSubmitSignalSyncObjectsToHwQueue.s b/libc/nt/gdi32/D3DKMTSubmitSignalSyncObjectsToHwQueue.s new file mode 100644 index 00000000..8a2fd730 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSubmitSignalSyncObjectsToHwQueue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSubmitSignalSyncObjectsToHwQueue,D3DKMTSubmitSignalSyncObjectsToHwQueue,1294 diff --git a/libc/nt/gdi32/D3DKMTSubmitWaitForSyncObjectsToHwQueue.s b/libc/nt/gdi32/D3DKMTSubmitWaitForSyncObjectsToHwQueue.s new file mode 100644 index 00000000..c6ee0515 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTSubmitWaitForSyncObjectsToHwQueue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTSubmitWaitForSyncObjectsToHwQueue,D3DKMTSubmitWaitForSyncObjectsToHwQueue,1295 diff --git a/libc/nt/gdi32/D3DKMTTrimProcessCommitment.s b/libc/nt/gdi32/D3DKMTTrimProcessCommitment.s new file mode 100644 index 00000000..46ac9225 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTTrimProcessCommitment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTTrimProcessCommitment,D3DKMTTrimProcessCommitment,1296 diff --git a/libc/nt/gdi32/D3DKMTUnOrderedPresentSwapChain.s b/libc/nt/gdi32/D3DKMTUnOrderedPresentSwapChain.s new file mode 100644 index 00000000..8f6f8d89 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTUnOrderedPresentSwapChain.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTUnOrderedPresentSwapChain,D3DKMTUnOrderedPresentSwapChain,1297 diff --git a/libc/nt/gdi32/D3DKMTUnlock.s b/libc/nt/gdi32/D3DKMTUnlock.s new file mode 100644 index 00000000..c9aab468 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTUnlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTUnlock,D3DKMTUnlock,1298 diff --git a/libc/nt/gdi32/D3DKMTUnlock2.s b/libc/nt/gdi32/D3DKMTUnlock2.s new file mode 100644 index 00000000..6ff05220 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTUnlock2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTUnlock2,D3DKMTUnlock2,1299 diff --git a/libc/nt/gdi32/D3DKMTUnpinDirectFlipResources.s b/libc/nt/gdi32/D3DKMTUnpinDirectFlipResources.s new file mode 100644 index 00000000..542166ab --- /dev/null +++ b/libc/nt/gdi32/D3DKMTUnpinDirectFlipResources.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTUnpinDirectFlipResources,D3DKMTUnpinDirectFlipResources,1300 diff --git a/libc/nt/gdi32/D3DKMTUnregisterTrimNotification.s b/libc/nt/gdi32/D3DKMTUnregisterTrimNotification.s new file mode 100644 index 00000000..f11d69a1 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTUnregisterTrimNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTUnregisterTrimNotification,D3DKMTUnregisterTrimNotification,1301 diff --git a/libc/nt/gdi32/D3DKMTUpdateAllocationProperty.s b/libc/nt/gdi32/D3DKMTUpdateAllocationProperty.s new file mode 100644 index 00000000..2f13861c --- /dev/null +++ b/libc/nt/gdi32/D3DKMTUpdateAllocationProperty.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTUpdateAllocationProperty,D3DKMTUpdateAllocationProperty,1302 diff --git a/libc/nt/gdi32/D3DKMTUpdateGpuVirtualAddress.s b/libc/nt/gdi32/D3DKMTUpdateGpuVirtualAddress.s new file mode 100644 index 00000000..13efe2ed --- /dev/null +++ b/libc/nt/gdi32/D3DKMTUpdateGpuVirtualAddress.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTUpdateGpuVirtualAddress,D3DKMTUpdateGpuVirtualAddress,1303 diff --git a/libc/nt/gdi32/D3DKMTUpdateOverlay.s b/libc/nt/gdi32/D3DKMTUpdateOverlay.s new file mode 100644 index 00000000..05231cdb --- /dev/null +++ b/libc/nt/gdi32/D3DKMTUpdateOverlay.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTUpdateOverlay,D3DKMTUpdateOverlay,1304 diff --git a/libc/nt/gdi32/D3DKMTVailConnect.s b/libc/nt/gdi32/D3DKMTVailConnect.s new file mode 100644 index 00000000..80c6df6e --- /dev/null +++ b/libc/nt/gdi32/D3DKMTVailConnect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTVailConnect,D3DKMTVailConnect,1305 diff --git a/libc/nt/gdi32/D3DKMTVailDisconnect.s b/libc/nt/gdi32/D3DKMTVailDisconnect.s new file mode 100644 index 00000000..493590c7 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTVailDisconnect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTVailDisconnect,D3DKMTVailDisconnect,1306 diff --git a/libc/nt/gdi32/D3DKMTVailPromoteCompositionSurface.s b/libc/nt/gdi32/D3DKMTVailPromoteCompositionSurface.s new file mode 100644 index 00000000..65a3a02a --- /dev/null +++ b/libc/nt/gdi32/D3DKMTVailPromoteCompositionSurface.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTVailPromoteCompositionSurface,D3DKMTVailPromoteCompositionSurface,1307 diff --git a/libc/nt/gdi32/D3DKMTWaitForIdle.s b/libc/nt/gdi32/D3DKMTWaitForIdle.s new file mode 100644 index 00000000..13097c25 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTWaitForIdle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTWaitForIdle,D3DKMTWaitForIdle,1308 diff --git a/libc/nt/gdi32/D3DKMTWaitForSynchronizationObject.s b/libc/nt/gdi32/D3DKMTWaitForSynchronizationObject.s new file mode 100644 index 00000000..29638215 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTWaitForSynchronizationObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTWaitForSynchronizationObject,D3DKMTWaitForSynchronizationObject,1309 diff --git a/libc/nt/gdi32/D3DKMTWaitForSynchronizationObject2.s b/libc/nt/gdi32/D3DKMTWaitForSynchronizationObject2.s new file mode 100644 index 00000000..9ef30d4e --- /dev/null +++ b/libc/nt/gdi32/D3DKMTWaitForSynchronizationObject2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTWaitForSynchronizationObject2,D3DKMTWaitForSynchronizationObject2,1310 diff --git a/libc/nt/gdi32/D3DKMTWaitForSynchronizationObjectFromCpu.s b/libc/nt/gdi32/D3DKMTWaitForSynchronizationObjectFromCpu.s new file mode 100644 index 00000000..f7f040dc --- /dev/null +++ b/libc/nt/gdi32/D3DKMTWaitForSynchronizationObjectFromCpu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTWaitForSynchronizationObjectFromCpu,D3DKMTWaitForSynchronizationObjectFromCpu,1311 diff --git a/libc/nt/gdi32/D3DKMTWaitForSynchronizationObjectFromGpu.s b/libc/nt/gdi32/D3DKMTWaitForSynchronizationObjectFromGpu.s new file mode 100644 index 00000000..b554e598 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTWaitForSynchronizationObjectFromGpu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTWaitForSynchronizationObjectFromGpu,D3DKMTWaitForSynchronizationObjectFromGpu,1312 diff --git a/libc/nt/gdi32/D3DKMTWaitForVerticalBlankEvent.s b/libc/nt/gdi32/D3DKMTWaitForVerticalBlankEvent.s new file mode 100644 index 00000000..1d7cb070 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTWaitForVerticalBlankEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTWaitForVerticalBlankEvent,D3DKMTWaitForVerticalBlankEvent,1313 diff --git a/libc/nt/gdi32/D3DKMTWaitForVerticalBlankEvent2.s b/libc/nt/gdi32/D3DKMTWaitForVerticalBlankEvent2.s new file mode 100644 index 00000000..2671be62 --- /dev/null +++ b/libc/nt/gdi32/D3DKMTWaitForVerticalBlankEvent2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_D3DKMTWaitForVerticalBlankEvent2,D3DKMTWaitForVerticalBlankEvent2,1314 diff --git a/libc/nt/gdi32/DDCCIGetCapabilitiesString.s b/libc/nt/gdi32/DDCCIGetCapabilitiesString.s new file mode 100644 index 00000000..d48afa2a --- /dev/null +++ b/libc/nt/gdi32/DDCCIGetCapabilitiesString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DDCCIGetCapabilitiesString,DDCCIGetCapabilitiesString,1315 diff --git a/libc/nt/gdi32/DDCCIGetCapabilitiesStringLength.s b/libc/nt/gdi32/DDCCIGetCapabilitiesStringLength.s new file mode 100644 index 00000000..22e627c0 --- /dev/null +++ b/libc/nt/gdi32/DDCCIGetCapabilitiesStringLength.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DDCCIGetCapabilitiesStringLength,DDCCIGetCapabilitiesStringLength,1316 diff --git a/libc/nt/gdi32/DDCCIGetTimingReport.s b/libc/nt/gdi32/DDCCIGetTimingReport.s new file mode 100644 index 00000000..d0fbce0c --- /dev/null +++ b/libc/nt/gdi32/DDCCIGetTimingReport.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DDCCIGetTimingReport,DDCCIGetTimingReport,1317 diff --git a/libc/nt/gdi32/DDCCIGetVCPFeature.s b/libc/nt/gdi32/DDCCIGetVCPFeature.s new file mode 100644 index 00000000..cd11e2d4 --- /dev/null +++ b/libc/nt/gdi32/DDCCIGetVCPFeature.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DDCCIGetVCPFeature,DDCCIGetVCPFeature,1318 diff --git a/libc/nt/gdi32/DDCCISaveCurrentSettings.s b/libc/nt/gdi32/DDCCISaveCurrentSettings.s new file mode 100644 index 00000000..eb7cdeca --- /dev/null +++ b/libc/nt/gdi32/DDCCISaveCurrentSettings.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DDCCISaveCurrentSettings,DDCCISaveCurrentSettings,1319 diff --git a/libc/nt/gdi32/DDCCISetVCPFeature.s b/libc/nt/gdi32/DDCCISetVCPFeature.s new file mode 100644 index 00000000..fa825aad --- /dev/null +++ b/libc/nt/gdi32/DDCCISetVCPFeature.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DDCCISetVCPFeature,DDCCISetVCPFeature,1320 diff --git a/libc/nt/gdi32/DPtoLP.s b/libc/nt/gdi32/DPtoLP.s new file mode 100644 index 00000000..a236ff22 --- /dev/null +++ b/libc/nt/gdi32/DPtoLP.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DPtoLP,DPtoLP,1321 diff --git a/libc/nt/gdi32/DdCreateFullscreenSprite.s b/libc/nt/gdi32/DdCreateFullscreenSprite.s new file mode 100644 index 00000000..19f8eb56 --- /dev/null +++ b/libc/nt/gdi32/DdCreateFullscreenSprite.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdCreateFullscreenSprite,DdCreateFullscreenSprite,1322 diff --git a/libc/nt/gdi32/DdDestroyFullscreenSprite.s b/libc/nt/gdi32/DdDestroyFullscreenSprite.s new file mode 100644 index 00000000..1204796e --- /dev/null +++ b/libc/nt/gdi32/DdDestroyFullscreenSprite.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdDestroyFullscreenSprite,DdDestroyFullscreenSprite,1323 diff --git a/libc/nt/gdi32/DdEntry0.s b/libc/nt/gdi32/DdEntry0.s new file mode 100644 index 00000000..b54a028d --- /dev/null +++ b/libc/nt/gdi32/DdEntry0.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry0,DdEntry0,1324 diff --git a/libc/nt/gdi32/DdEntry1.s b/libc/nt/gdi32/DdEntry1.s new file mode 100644 index 00000000..88ed6fc3 --- /dev/null +++ b/libc/nt/gdi32/DdEntry1.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry1,DdEntry1,1325 diff --git a/libc/nt/gdi32/DdEntry10.s b/libc/nt/gdi32/DdEntry10.s new file mode 100644 index 00000000..9d58c5a9 --- /dev/null +++ b/libc/nt/gdi32/DdEntry10.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry10,DdEntry10,1326 diff --git a/libc/nt/gdi32/DdEntry11.s b/libc/nt/gdi32/DdEntry11.s new file mode 100644 index 00000000..8193ae74 --- /dev/null +++ b/libc/nt/gdi32/DdEntry11.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry11,DdEntry11,1327 diff --git a/libc/nt/gdi32/DdEntry12.s b/libc/nt/gdi32/DdEntry12.s new file mode 100644 index 00000000..ef570674 --- /dev/null +++ b/libc/nt/gdi32/DdEntry12.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry12,DdEntry12,1328 diff --git a/libc/nt/gdi32/DdEntry13.s b/libc/nt/gdi32/DdEntry13.s new file mode 100644 index 00000000..fc13c41a --- /dev/null +++ b/libc/nt/gdi32/DdEntry13.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry13,DdEntry13,1329 diff --git a/libc/nt/gdi32/DdEntry14.s b/libc/nt/gdi32/DdEntry14.s new file mode 100644 index 00000000..4b8d188b --- /dev/null +++ b/libc/nt/gdi32/DdEntry14.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry14,DdEntry14,1330 diff --git a/libc/nt/gdi32/DdEntry15.s b/libc/nt/gdi32/DdEntry15.s new file mode 100644 index 00000000..f95c54f2 --- /dev/null +++ b/libc/nt/gdi32/DdEntry15.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry15,DdEntry15,1331 diff --git a/libc/nt/gdi32/DdEntry16.s b/libc/nt/gdi32/DdEntry16.s new file mode 100644 index 00000000..2ceb8985 --- /dev/null +++ b/libc/nt/gdi32/DdEntry16.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry16,DdEntry16,1332 diff --git a/libc/nt/gdi32/DdEntry17.s b/libc/nt/gdi32/DdEntry17.s new file mode 100644 index 00000000..2a7648d7 --- /dev/null +++ b/libc/nt/gdi32/DdEntry17.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry17,DdEntry17,1333 diff --git a/libc/nt/gdi32/DdEntry18.s b/libc/nt/gdi32/DdEntry18.s new file mode 100644 index 00000000..095275a0 --- /dev/null +++ b/libc/nt/gdi32/DdEntry18.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry18,DdEntry18,1334 diff --git a/libc/nt/gdi32/DdEntry19.s b/libc/nt/gdi32/DdEntry19.s new file mode 100644 index 00000000..8222d138 --- /dev/null +++ b/libc/nt/gdi32/DdEntry19.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry19,DdEntry19,1335 diff --git a/libc/nt/gdi32/DdEntry2.s b/libc/nt/gdi32/DdEntry2.s new file mode 100644 index 00000000..b02cd844 --- /dev/null +++ b/libc/nt/gdi32/DdEntry2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry2,DdEntry2,1336 diff --git a/libc/nt/gdi32/DdEntry20.s b/libc/nt/gdi32/DdEntry20.s new file mode 100644 index 00000000..38e796a5 --- /dev/null +++ b/libc/nt/gdi32/DdEntry20.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry20,DdEntry20,1337 diff --git a/libc/nt/gdi32/DdEntry21.s b/libc/nt/gdi32/DdEntry21.s new file mode 100644 index 00000000..48d29c6a --- /dev/null +++ b/libc/nt/gdi32/DdEntry21.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry21,DdEntry21,1338 diff --git a/libc/nt/gdi32/DdEntry22.s b/libc/nt/gdi32/DdEntry22.s new file mode 100644 index 00000000..50ce1b7c --- /dev/null +++ b/libc/nt/gdi32/DdEntry22.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry22,DdEntry22,1339 diff --git a/libc/nt/gdi32/DdEntry23.s b/libc/nt/gdi32/DdEntry23.s new file mode 100644 index 00000000..9626d375 --- /dev/null +++ b/libc/nt/gdi32/DdEntry23.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry23,DdEntry23,1340 diff --git a/libc/nt/gdi32/DdEntry24.s b/libc/nt/gdi32/DdEntry24.s new file mode 100644 index 00000000..e89d76aa --- /dev/null +++ b/libc/nt/gdi32/DdEntry24.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry24,DdEntry24,1341 diff --git a/libc/nt/gdi32/DdEntry25.s b/libc/nt/gdi32/DdEntry25.s new file mode 100644 index 00000000..cc1d638c --- /dev/null +++ b/libc/nt/gdi32/DdEntry25.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry25,DdEntry25,1342 diff --git a/libc/nt/gdi32/DdEntry26.s b/libc/nt/gdi32/DdEntry26.s new file mode 100644 index 00000000..3c7949da --- /dev/null +++ b/libc/nt/gdi32/DdEntry26.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry26,DdEntry26,1343 diff --git a/libc/nt/gdi32/DdEntry27.s b/libc/nt/gdi32/DdEntry27.s new file mode 100644 index 00000000..d088ad12 --- /dev/null +++ b/libc/nt/gdi32/DdEntry27.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry27,DdEntry27,1344 diff --git a/libc/nt/gdi32/DdEntry28.s b/libc/nt/gdi32/DdEntry28.s new file mode 100644 index 00000000..4f9a21a7 --- /dev/null +++ b/libc/nt/gdi32/DdEntry28.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry28,DdEntry28,1345 diff --git a/libc/nt/gdi32/DdEntry29.s b/libc/nt/gdi32/DdEntry29.s new file mode 100644 index 00000000..3b1bd4f1 --- /dev/null +++ b/libc/nt/gdi32/DdEntry29.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry29,DdEntry29,1346 diff --git a/libc/nt/gdi32/DdEntry3.s b/libc/nt/gdi32/DdEntry3.s new file mode 100644 index 00000000..3d69c614 --- /dev/null +++ b/libc/nt/gdi32/DdEntry3.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry3,DdEntry3,1347 diff --git a/libc/nt/gdi32/DdEntry30.s b/libc/nt/gdi32/DdEntry30.s new file mode 100644 index 00000000..403a112c --- /dev/null +++ b/libc/nt/gdi32/DdEntry30.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry30,DdEntry30,1348 diff --git a/libc/nt/gdi32/DdEntry31.s b/libc/nt/gdi32/DdEntry31.s new file mode 100644 index 00000000..462b58f3 --- /dev/null +++ b/libc/nt/gdi32/DdEntry31.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry31,DdEntry31,1349 diff --git a/libc/nt/gdi32/DdEntry32.s b/libc/nt/gdi32/DdEntry32.s new file mode 100644 index 00000000..b87b8b8d --- /dev/null +++ b/libc/nt/gdi32/DdEntry32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry32,DdEntry32,1350 diff --git a/libc/nt/gdi32/DdEntry33.s b/libc/nt/gdi32/DdEntry33.s new file mode 100644 index 00000000..84ce424f --- /dev/null +++ b/libc/nt/gdi32/DdEntry33.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry33,DdEntry33,1351 diff --git a/libc/nt/gdi32/DdEntry34.s b/libc/nt/gdi32/DdEntry34.s new file mode 100644 index 00000000..52abe275 --- /dev/null +++ b/libc/nt/gdi32/DdEntry34.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry34,DdEntry34,1352 diff --git a/libc/nt/gdi32/DdEntry35.s b/libc/nt/gdi32/DdEntry35.s new file mode 100644 index 00000000..49b45d22 --- /dev/null +++ b/libc/nt/gdi32/DdEntry35.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry35,DdEntry35,1353 diff --git a/libc/nt/gdi32/DdEntry36.s b/libc/nt/gdi32/DdEntry36.s new file mode 100644 index 00000000..3c51c152 --- /dev/null +++ b/libc/nt/gdi32/DdEntry36.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry36,DdEntry36,1354 diff --git a/libc/nt/gdi32/DdEntry37.s b/libc/nt/gdi32/DdEntry37.s new file mode 100644 index 00000000..e2eadb88 --- /dev/null +++ b/libc/nt/gdi32/DdEntry37.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry37,DdEntry37,1355 diff --git a/libc/nt/gdi32/DdEntry38.s b/libc/nt/gdi32/DdEntry38.s new file mode 100644 index 00000000..281b331e --- /dev/null +++ b/libc/nt/gdi32/DdEntry38.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry38,DdEntry38,1356 diff --git a/libc/nt/gdi32/DdEntry39.s b/libc/nt/gdi32/DdEntry39.s new file mode 100644 index 00000000..4b9e3622 --- /dev/null +++ b/libc/nt/gdi32/DdEntry39.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry39,DdEntry39,1357 diff --git a/libc/nt/gdi32/DdEntry4.s b/libc/nt/gdi32/DdEntry4.s new file mode 100644 index 00000000..d729bdfc --- /dev/null +++ b/libc/nt/gdi32/DdEntry4.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry4,DdEntry4,1358 diff --git a/libc/nt/gdi32/DdEntry40.s b/libc/nt/gdi32/DdEntry40.s new file mode 100644 index 00000000..a8dc142e --- /dev/null +++ b/libc/nt/gdi32/DdEntry40.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry40,DdEntry40,1359 diff --git a/libc/nt/gdi32/DdEntry41.s b/libc/nt/gdi32/DdEntry41.s new file mode 100644 index 00000000..aaffe57f --- /dev/null +++ b/libc/nt/gdi32/DdEntry41.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry41,DdEntry41,1360 diff --git a/libc/nt/gdi32/DdEntry42.s b/libc/nt/gdi32/DdEntry42.s new file mode 100644 index 00000000..d146ea69 --- /dev/null +++ b/libc/nt/gdi32/DdEntry42.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry42,DdEntry42,1361 diff --git a/libc/nt/gdi32/DdEntry43.s b/libc/nt/gdi32/DdEntry43.s new file mode 100644 index 00000000..1a67232c --- /dev/null +++ b/libc/nt/gdi32/DdEntry43.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry43,DdEntry43,1362 diff --git a/libc/nt/gdi32/DdEntry44.s b/libc/nt/gdi32/DdEntry44.s new file mode 100644 index 00000000..fe7a1030 --- /dev/null +++ b/libc/nt/gdi32/DdEntry44.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry44,DdEntry44,1363 diff --git a/libc/nt/gdi32/DdEntry45.s b/libc/nt/gdi32/DdEntry45.s new file mode 100644 index 00000000..b853411b --- /dev/null +++ b/libc/nt/gdi32/DdEntry45.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry45,DdEntry45,1364 diff --git a/libc/nt/gdi32/DdEntry46.s b/libc/nt/gdi32/DdEntry46.s new file mode 100644 index 00000000..9ac43e3c --- /dev/null +++ b/libc/nt/gdi32/DdEntry46.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry46,DdEntry46,1365 diff --git a/libc/nt/gdi32/DdEntry47.s b/libc/nt/gdi32/DdEntry47.s new file mode 100644 index 00000000..5fb90a3b --- /dev/null +++ b/libc/nt/gdi32/DdEntry47.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry47,DdEntry47,1366 diff --git a/libc/nt/gdi32/DdEntry48.s b/libc/nt/gdi32/DdEntry48.s new file mode 100644 index 00000000..40be41e0 --- /dev/null +++ b/libc/nt/gdi32/DdEntry48.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry48,DdEntry48,1367 diff --git a/libc/nt/gdi32/DdEntry49.s b/libc/nt/gdi32/DdEntry49.s new file mode 100644 index 00000000..62162213 --- /dev/null +++ b/libc/nt/gdi32/DdEntry49.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry49,DdEntry49,1368 diff --git a/libc/nt/gdi32/DdEntry5.s b/libc/nt/gdi32/DdEntry5.s new file mode 100644 index 00000000..15416711 --- /dev/null +++ b/libc/nt/gdi32/DdEntry5.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry5,DdEntry5,1369 diff --git a/libc/nt/gdi32/DdEntry50.s b/libc/nt/gdi32/DdEntry50.s new file mode 100644 index 00000000..6fabf567 --- /dev/null +++ b/libc/nt/gdi32/DdEntry50.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry50,DdEntry50,1370 diff --git a/libc/nt/gdi32/DdEntry51.s b/libc/nt/gdi32/DdEntry51.s new file mode 100644 index 00000000..e5d6efc3 --- /dev/null +++ b/libc/nt/gdi32/DdEntry51.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry51,DdEntry51,1371 diff --git a/libc/nt/gdi32/DdEntry52.s b/libc/nt/gdi32/DdEntry52.s new file mode 100644 index 00000000..ffb246a5 --- /dev/null +++ b/libc/nt/gdi32/DdEntry52.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry52,DdEntry52,1372 diff --git a/libc/nt/gdi32/DdEntry53.s b/libc/nt/gdi32/DdEntry53.s new file mode 100644 index 00000000..cb15fea9 --- /dev/null +++ b/libc/nt/gdi32/DdEntry53.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry53,DdEntry53,1373 diff --git a/libc/nt/gdi32/DdEntry54.s b/libc/nt/gdi32/DdEntry54.s new file mode 100644 index 00000000..2cd8d68e --- /dev/null +++ b/libc/nt/gdi32/DdEntry54.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry54,DdEntry54,1374 diff --git a/libc/nt/gdi32/DdEntry55.s b/libc/nt/gdi32/DdEntry55.s new file mode 100644 index 00000000..bd3d28ce --- /dev/null +++ b/libc/nt/gdi32/DdEntry55.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry55,DdEntry55,1375 diff --git a/libc/nt/gdi32/DdEntry56.s b/libc/nt/gdi32/DdEntry56.s new file mode 100644 index 00000000..ddae132c --- /dev/null +++ b/libc/nt/gdi32/DdEntry56.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry56,DdEntry56,1376 diff --git a/libc/nt/gdi32/DdEntry6.s b/libc/nt/gdi32/DdEntry6.s new file mode 100644 index 00000000..100809bf --- /dev/null +++ b/libc/nt/gdi32/DdEntry6.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry6,DdEntry6,1377 diff --git a/libc/nt/gdi32/DdEntry7.s b/libc/nt/gdi32/DdEntry7.s new file mode 100644 index 00000000..20ad1fc5 --- /dev/null +++ b/libc/nt/gdi32/DdEntry7.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry7,DdEntry7,1378 diff --git a/libc/nt/gdi32/DdEntry8.s b/libc/nt/gdi32/DdEntry8.s new file mode 100644 index 00000000..3502030d --- /dev/null +++ b/libc/nt/gdi32/DdEntry8.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry8,DdEntry8,1379 diff --git a/libc/nt/gdi32/DdEntry9.s b/libc/nt/gdi32/DdEntry9.s new file mode 100644 index 00000000..265418df --- /dev/null +++ b/libc/nt/gdi32/DdEntry9.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdEntry9,DdEntry9,1380 diff --git a/libc/nt/gdi32/DdNotifyFullscreenSpriteUpdate.s b/libc/nt/gdi32/DdNotifyFullscreenSpriteUpdate.s new file mode 100644 index 00000000..190095e0 --- /dev/null +++ b/libc/nt/gdi32/DdNotifyFullscreenSpriteUpdate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdNotifyFullscreenSpriteUpdate,DdNotifyFullscreenSpriteUpdate,1381 diff --git a/libc/nt/gdi32/DdQueryVisRgnUniqueness.s b/libc/nt/gdi32/DdQueryVisRgnUniqueness.s new file mode 100644 index 00000000..f7ec9084 --- /dev/null +++ b/libc/nt/gdi32/DdQueryVisRgnUniqueness.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DdQueryVisRgnUniqueness,DdQueryVisRgnUniqueness,1382 diff --git a/libc/nt/gdi32/DeleteColorSpace.s b/libc/nt/gdi32/DeleteColorSpace.s new file mode 100644 index 00000000..e340f068 --- /dev/null +++ b/libc/nt/gdi32/DeleteColorSpace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DeleteColorSpace,DeleteColorSpace,1383 diff --git a/libc/nt/gdi32/DeleteDC.s b/libc/nt/gdi32/DeleteDC.s new file mode 100644 index 00000000..9d245ff8 --- /dev/null +++ b/libc/nt/gdi32/DeleteDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DeleteDC,DeleteDC,1384 diff --git a/libc/nt/gdi32/DeleteEnhMetaFile.s b/libc/nt/gdi32/DeleteEnhMetaFile.s new file mode 100644 index 00000000..ccb1ded9 --- /dev/null +++ b/libc/nt/gdi32/DeleteEnhMetaFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DeleteEnhMetaFile,DeleteEnhMetaFile,1385 diff --git a/libc/nt/gdi32/DeleteMetaFile.s b/libc/nt/gdi32/DeleteMetaFile.s new file mode 100644 index 00000000..d6776ad1 --- /dev/null +++ b/libc/nt/gdi32/DeleteMetaFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DeleteMetaFile,DeleteMetaFile,1386 diff --git a/libc/nt/gdi32/DeleteObject.s b/libc/nt/gdi32/DeleteObject.s new file mode 100644 index 00000000..c1dabf3e --- /dev/null +++ b/libc/nt/gdi32/DeleteObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DeleteObject,DeleteObject,1387 diff --git a/libc/nt/gdi32/DescribePixelFormat.s b/libc/nt/gdi32/DescribePixelFormat.s new file mode 100644 index 00000000..e78c90f0 --- /dev/null +++ b/libc/nt/gdi32/DescribePixelFormat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DescribePixelFormat,DescribePixelFormat,1388 diff --git a/libc/nt/gdi32/DestroyOPMProtectedOutput.s b/libc/nt/gdi32/DestroyOPMProtectedOutput.s new file mode 100644 index 00000000..247a719a --- /dev/null +++ b/libc/nt/gdi32/DestroyOPMProtectedOutput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DestroyOPMProtectedOutput,DestroyOPMProtectedOutput,1389 diff --git a/libc/nt/gdi32/DestroyPhysicalMonitorInternal.s b/libc/nt/gdi32/DestroyPhysicalMonitorInternal.s new file mode 100644 index 00000000..0a8f69bf --- /dev/null +++ b/libc/nt/gdi32/DestroyPhysicalMonitorInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DestroyPhysicalMonitorInternal,DestroyPhysicalMonitorInternal,1390 diff --git a/libc/nt/gdi32/DeviceCapabilitiesExA.s b/libc/nt/gdi32/DeviceCapabilitiesExA.s new file mode 100644 index 00000000..878487c4 --- /dev/null +++ b/libc/nt/gdi32/DeviceCapabilitiesExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DeviceCapabilitiesExA,DeviceCapabilitiesExA,1391 diff --git a/libc/nt/gdi32/DrawEscape.s b/libc/nt/gdi32/DrawEscape.s new file mode 100644 index 00000000..62d73efc --- /dev/null +++ b/libc/nt/gdi32/DrawEscape.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DrawEscape,DrawEscape,1393 diff --git a/libc/nt/gdi32/DwmCreatedBitmapRemotingOutput.s b/libc/nt/gdi32/DwmCreatedBitmapRemotingOutput.s new file mode 100644 index 00000000..fc3e376f --- /dev/null +++ b/libc/nt/gdi32/DwmCreatedBitmapRemotingOutput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DwmCreatedBitmapRemotingOutput,DwmCreatedBitmapRemotingOutput,1014 diff --git a/libc/nt/gdi32/DxTrimNotificationListHead.s b/libc/nt/gdi32/DxTrimNotificationListHead.s new file mode 100644 index 00000000..5692e122 --- /dev/null +++ b/libc/nt/gdi32/DxTrimNotificationListHead.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_DxTrimNotificationListHead,DxTrimNotificationListHead,1394 diff --git a/libc/nt/gdi32/Ellipse.s b/libc/nt/gdi32/Ellipse.s new file mode 100644 index 00000000..e040a23e --- /dev/null +++ b/libc/nt/gdi32/Ellipse.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_Ellipse,Ellipse,1395 diff --git a/libc/nt/gdi32/EnableEUDC.s b/libc/nt/gdi32/EnableEUDC.s new file mode 100644 index 00000000..bf4c1a16 --- /dev/null +++ b/libc/nt/gdi32/EnableEUDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EnableEUDC,EnableEUDC,1396 diff --git a/libc/nt/gdi32/EndDoc.s b/libc/nt/gdi32/EndDoc.s new file mode 100644 index 00000000..bf9e5e0d --- /dev/null +++ b/libc/nt/gdi32/EndDoc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EndDoc,EndDoc,1397 diff --git a/libc/nt/gdi32/EndFormPage.s b/libc/nt/gdi32/EndFormPage.s new file mode 100644 index 00000000..38721b5a --- /dev/null +++ b/libc/nt/gdi32/EndFormPage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EndFormPage,EndFormPage,1398 diff --git a/libc/nt/gdi32/EndGdiRendering.s b/libc/nt/gdi32/EndGdiRendering.s new file mode 100644 index 00000000..df0327ee --- /dev/null +++ b/libc/nt/gdi32/EndGdiRendering.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EndGdiRendering,EndGdiRendering,1399 diff --git a/libc/nt/gdi32/EndPage.s b/libc/nt/gdi32/EndPage.s new file mode 100644 index 00000000..33accc0d --- /dev/null +++ b/libc/nt/gdi32/EndPage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EndPage,EndPage,1400 diff --git a/libc/nt/gdi32/EndPath.s b/libc/nt/gdi32/EndPath.s new file mode 100644 index 00000000..8f73dff7 --- /dev/null +++ b/libc/nt/gdi32/EndPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EndPath,EndPath,1401 diff --git a/libc/nt/gdi32/EngAcquireSemaphore.s b/libc/nt/gdi32/EngAcquireSemaphore.s new file mode 100644 index 00000000..de341520 --- /dev/null +++ b/libc/nt/gdi32/EngAcquireSemaphore.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngAcquireSemaphore,EngAcquireSemaphore,1402 diff --git a/libc/nt/gdi32/EngAlphaBlend.s b/libc/nt/gdi32/EngAlphaBlend.s new file mode 100644 index 00000000..3869588c --- /dev/null +++ b/libc/nt/gdi32/EngAlphaBlend.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngAlphaBlend,EngAlphaBlend,1403 diff --git a/libc/nt/gdi32/EngAssociateSurface.s b/libc/nt/gdi32/EngAssociateSurface.s new file mode 100644 index 00000000..b27646dd --- /dev/null +++ b/libc/nt/gdi32/EngAssociateSurface.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngAssociateSurface,EngAssociateSurface,1404 diff --git a/libc/nt/gdi32/EngBitBlt.s b/libc/nt/gdi32/EngBitBlt.s new file mode 100644 index 00000000..6eae569e --- /dev/null +++ b/libc/nt/gdi32/EngBitBlt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngBitBlt,EngBitBlt,1405 diff --git a/libc/nt/gdi32/EngCheckAbort.s b/libc/nt/gdi32/EngCheckAbort.s new file mode 100644 index 00000000..62370732 --- /dev/null +++ b/libc/nt/gdi32/EngCheckAbort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngCheckAbort,EngCheckAbort,1406 diff --git a/libc/nt/gdi32/EngComputeGlyphSet.s b/libc/nt/gdi32/EngComputeGlyphSet.s new file mode 100644 index 00000000..33b25a73 --- /dev/null +++ b/libc/nt/gdi32/EngComputeGlyphSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngComputeGlyphSet,EngComputeGlyphSet,1407 diff --git a/libc/nt/gdi32/EngCopyBits.s b/libc/nt/gdi32/EngCopyBits.s new file mode 100644 index 00000000..ce91a593 --- /dev/null +++ b/libc/nt/gdi32/EngCopyBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngCopyBits,EngCopyBits,1408 diff --git a/libc/nt/gdi32/EngCreateBitmap.s b/libc/nt/gdi32/EngCreateBitmap.s new file mode 100644 index 00000000..0215b69d --- /dev/null +++ b/libc/nt/gdi32/EngCreateBitmap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngCreateBitmap,EngCreateBitmap,1409 diff --git a/libc/nt/gdi32/EngCreateClip.s b/libc/nt/gdi32/EngCreateClip.s new file mode 100644 index 00000000..395a1c34 --- /dev/null +++ b/libc/nt/gdi32/EngCreateClip.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngCreateClip,EngCreateClip,1410 diff --git a/libc/nt/gdi32/EngCreateDeviceBitmap.s b/libc/nt/gdi32/EngCreateDeviceBitmap.s new file mode 100644 index 00000000..1e41e6e5 --- /dev/null +++ b/libc/nt/gdi32/EngCreateDeviceBitmap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngCreateDeviceBitmap,EngCreateDeviceBitmap,1411 diff --git a/libc/nt/gdi32/EngCreateDeviceSurface.s b/libc/nt/gdi32/EngCreateDeviceSurface.s new file mode 100644 index 00000000..9820dafa --- /dev/null +++ b/libc/nt/gdi32/EngCreateDeviceSurface.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngCreateDeviceSurface,EngCreateDeviceSurface,1412 diff --git a/libc/nt/gdi32/EngCreatePalette.s b/libc/nt/gdi32/EngCreatePalette.s new file mode 100644 index 00000000..827a9ebd --- /dev/null +++ b/libc/nt/gdi32/EngCreatePalette.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngCreatePalette,EngCreatePalette,1413 diff --git a/libc/nt/gdi32/EngCreateSemaphore.s b/libc/nt/gdi32/EngCreateSemaphore.s new file mode 100644 index 00000000..b55d4508 --- /dev/null +++ b/libc/nt/gdi32/EngCreateSemaphore.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngCreateSemaphore,EngCreateSemaphore,1414 diff --git a/libc/nt/gdi32/EngDeleteClip.s b/libc/nt/gdi32/EngDeleteClip.s new file mode 100644 index 00000000..344f7ce9 --- /dev/null +++ b/libc/nt/gdi32/EngDeleteClip.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngDeleteClip,EngDeleteClip,1415 diff --git a/libc/nt/gdi32/EngDeletePalette.s b/libc/nt/gdi32/EngDeletePalette.s new file mode 100644 index 00000000..15d34c0a --- /dev/null +++ b/libc/nt/gdi32/EngDeletePalette.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngDeletePalette,EngDeletePalette,1416 diff --git a/libc/nt/gdi32/EngDeletePath.s b/libc/nt/gdi32/EngDeletePath.s new file mode 100644 index 00000000..309e7fd2 --- /dev/null +++ b/libc/nt/gdi32/EngDeletePath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngDeletePath,EngDeletePath,1417 diff --git a/libc/nt/gdi32/EngDeleteSemaphore.s b/libc/nt/gdi32/EngDeleteSemaphore.s new file mode 100644 index 00000000..9312dad1 --- /dev/null +++ b/libc/nt/gdi32/EngDeleteSemaphore.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngDeleteSemaphore,EngDeleteSemaphore,1418 diff --git a/libc/nt/gdi32/EngDeleteSurface.s b/libc/nt/gdi32/EngDeleteSurface.s new file mode 100644 index 00000000..779d0090 --- /dev/null +++ b/libc/nt/gdi32/EngDeleteSurface.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngDeleteSurface,EngDeleteSurface,1419 diff --git a/libc/nt/gdi32/EngEraseSurface.s b/libc/nt/gdi32/EngEraseSurface.s new file mode 100644 index 00000000..389d89c3 --- /dev/null +++ b/libc/nt/gdi32/EngEraseSurface.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngEraseSurface,EngEraseSurface,1420 diff --git a/libc/nt/gdi32/EngFillPath.s b/libc/nt/gdi32/EngFillPath.s new file mode 100644 index 00000000..51be940d --- /dev/null +++ b/libc/nt/gdi32/EngFillPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngFillPath,EngFillPath,1421 diff --git a/libc/nt/gdi32/EngFindResource.s b/libc/nt/gdi32/EngFindResource.s new file mode 100644 index 00000000..d816ff30 --- /dev/null +++ b/libc/nt/gdi32/EngFindResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngFindResource,EngFindResource,1422 diff --git a/libc/nt/gdi32/EngFreeModule.s b/libc/nt/gdi32/EngFreeModule.s new file mode 100644 index 00000000..616ee7ba --- /dev/null +++ b/libc/nt/gdi32/EngFreeModule.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngFreeModule,EngFreeModule,1423 diff --git a/libc/nt/gdi32/EngGetCurrentCodePage.s b/libc/nt/gdi32/EngGetCurrentCodePage.s new file mode 100644 index 00000000..569d6a45 --- /dev/null +++ b/libc/nt/gdi32/EngGetCurrentCodePage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngGetCurrentCodePage,EngGetCurrentCodePage,1424 diff --git a/libc/nt/gdi32/EngGetDriverName.s b/libc/nt/gdi32/EngGetDriverName.s new file mode 100644 index 00000000..b57b8043 --- /dev/null +++ b/libc/nt/gdi32/EngGetDriverName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngGetDriverName,EngGetDriverName,1425 diff --git a/libc/nt/gdi32/EngGetPrinterDataFileName.s b/libc/nt/gdi32/EngGetPrinterDataFileName.s new file mode 100644 index 00000000..7b809094 --- /dev/null +++ b/libc/nt/gdi32/EngGetPrinterDataFileName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngGetPrinterDataFileName,EngGetPrinterDataFileName,1426 diff --git a/libc/nt/gdi32/EngGradientFill.s b/libc/nt/gdi32/EngGradientFill.s new file mode 100644 index 00000000..75ca8227 --- /dev/null +++ b/libc/nt/gdi32/EngGradientFill.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngGradientFill,EngGradientFill,1427 diff --git a/libc/nt/gdi32/EngLineTo.s b/libc/nt/gdi32/EngLineTo.s new file mode 100644 index 00000000..863eaccf --- /dev/null +++ b/libc/nt/gdi32/EngLineTo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngLineTo,EngLineTo,1428 diff --git a/libc/nt/gdi32/EngLoadModule.s b/libc/nt/gdi32/EngLoadModule.s new file mode 100644 index 00000000..8c19dc8d --- /dev/null +++ b/libc/nt/gdi32/EngLoadModule.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngLoadModule,EngLoadModule,1429 diff --git a/libc/nt/gdi32/EngLockSurface.s b/libc/nt/gdi32/EngLockSurface.s new file mode 100644 index 00000000..dc0b6392 --- /dev/null +++ b/libc/nt/gdi32/EngLockSurface.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngLockSurface,EngLockSurface,1430 diff --git a/libc/nt/gdi32/EngMarkBandingSurface.s b/libc/nt/gdi32/EngMarkBandingSurface.s new file mode 100644 index 00000000..1ac559df --- /dev/null +++ b/libc/nt/gdi32/EngMarkBandingSurface.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngMarkBandingSurface,EngMarkBandingSurface,1431 diff --git a/libc/nt/gdi32/EngMultiByteToUnicodeN.s b/libc/nt/gdi32/EngMultiByteToUnicodeN.s new file mode 100644 index 00000000..147004fb --- /dev/null +++ b/libc/nt/gdi32/EngMultiByteToUnicodeN.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngMultiByteToUnicodeN,EngMultiByteToUnicodeN,1432 diff --git a/libc/nt/gdi32/EngMultiByteToWideChar.s b/libc/nt/gdi32/EngMultiByteToWideChar.s new file mode 100644 index 00000000..d94c4564 --- /dev/null +++ b/libc/nt/gdi32/EngMultiByteToWideChar.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngMultiByteToWideChar,EngMultiByteToWideChar,1433 diff --git a/libc/nt/gdi32/EngPaint.s b/libc/nt/gdi32/EngPaint.s new file mode 100644 index 00000000..51df7b8a --- /dev/null +++ b/libc/nt/gdi32/EngPaint.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngPaint,EngPaint,1434 diff --git a/libc/nt/gdi32/EngPlgBlt.s b/libc/nt/gdi32/EngPlgBlt.s new file mode 100644 index 00000000..66c82b7c --- /dev/null +++ b/libc/nt/gdi32/EngPlgBlt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngPlgBlt,EngPlgBlt,1435 diff --git a/libc/nt/gdi32/EngQueryEMFInfo.s b/libc/nt/gdi32/EngQueryEMFInfo.s new file mode 100644 index 00000000..593907ce --- /dev/null +++ b/libc/nt/gdi32/EngQueryEMFInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngQueryEMFInfo,EngQueryEMFInfo,1436 diff --git a/libc/nt/gdi32/EngQueryLocalTime.s b/libc/nt/gdi32/EngQueryLocalTime.s new file mode 100644 index 00000000..a41f0c6d --- /dev/null +++ b/libc/nt/gdi32/EngQueryLocalTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngQueryLocalTime,EngQueryLocalTime,1437 diff --git a/libc/nt/gdi32/EngReleaseSemaphore.s b/libc/nt/gdi32/EngReleaseSemaphore.s new file mode 100644 index 00000000..5fcc2702 --- /dev/null +++ b/libc/nt/gdi32/EngReleaseSemaphore.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngReleaseSemaphore,EngReleaseSemaphore,1438 diff --git a/libc/nt/gdi32/EngStretchBlt.s b/libc/nt/gdi32/EngStretchBlt.s new file mode 100644 index 00000000..89c97942 --- /dev/null +++ b/libc/nt/gdi32/EngStretchBlt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngStretchBlt,EngStretchBlt,1439 diff --git a/libc/nt/gdi32/EngStretchBltROP.s b/libc/nt/gdi32/EngStretchBltROP.s new file mode 100644 index 00000000..e682ab3b --- /dev/null +++ b/libc/nt/gdi32/EngStretchBltROP.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngStretchBltROP,EngStretchBltROP,1440 diff --git a/libc/nt/gdi32/EngStrokeAndFillPath.s b/libc/nt/gdi32/EngStrokeAndFillPath.s new file mode 100644 index 00000000..466e9f45 --- /dev/null +++ b/libc/nt/gdi32/EngStrokeAndFillPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngStrokeAndFillPath,EngStrokeAndFillPath,1441 diff --git a/libc/nt/gdi32/EngStrokePath.s b/libc/nt/gdi32/EngStrokePath.s new file mode 100644 index 00000000..6d191c94 --- /dev/null +++ b/libc/nt/gdi32/EngStrokePath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngStrokePath,EngStrokePath,1442 diff --git a/libc/nt/gdi32/EngTextOut.s b/libc/nt/gdi32/EngTextOut.s new file mode 100644 index 00000000..2ad4ecba --- /dev/null +++ b/libc/nt/gdi32/EngTextOut.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngTextOut,EngTextOut,1443 diff --git a/libc/nt/gdi32/EngTransparentBlt.s b/libc/nt/gdi32/EngTransparentBlt.s new file mode 100644 index 00000000..2319116e --- /dev/null +++ b/libc/nt/gdi32/EngTransparentBlt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngTransparentBlt,EngTransparentBlt,1444 diff --git a/libc/nt/gdi32/EngUnicodeToMultiByteN.s b/libc/nt/gdi32/EngUnicodeToMultiByteN.s new file mode 100644 index 00000000..04cf4075 --- /dev/null +++ b/libc/nt/gdi32/EngUnicodeToMultiByteN.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngUnicodeToMultiByteN,EngUnicodeToMultiByteN,1445 diff --git a/libc/nt/gdi32/EngUnlockSurface.s b/libc/nt/gdi32/EngUnlockSurface.s new file mode 100644 index 00000000..0e2ed536 --- /dev/null +++ b/libc/nt/gdi32/EngUnlockSurface.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngUnlockSurface,EngUnlockSurface,1446 diff --git a/libc/nt/gdi32/EngWideCharToMultiByte.s b/libc/nt/gdi32/EngWideCharToMultiByte.s new file mode 100644 index 00000000..7569a617 --- /dev/null +++ b/libc/nt/gdi32/EngWideCharToMultiByte.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EngWideCharToMultiByte,EngWideCharToMultiByte,1447 diff --git a/libc/nt/gdi32/EnumEnhMetaFile.s b/libc/nt/gdi32/EnumEnhMetaFile.s new file mode 100644 index 00000000..37757981 --- /dev/null +++ b/libc/nt/gdi32/EnumEnhMetaFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EnumEnhMetaFile,EnumEnhMetaFile,1448 diff --git a/libc/nt/gdi32/EnumFontFamiliesA.s b/libc/nt/gdi32/EnumFontFamiliesA.s new file mode 100644 index 00000000..0ecbeb72 --- /dev/null +++ b/libc/nt/gdi32/EnumFontFamiliesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EnumFontFamiliesA,EnumFontFamiliesA,1449 diff --git a/libc/nt/gdi32/EnumFontFamiliesExA.s b/libc/nt/gdi32/EnumFontFamiliesExA.s new file mode 100644 index 00000000..22d1c5bd --- /dev/null +++ b/libc/nt/gdi32/EnumFontFamiliesExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EnumFontFamiliesExA,EnumFontFamiliesExA,1450 diff --git a/libc/nt/gdi32/EnumFontFamiliesExW.s b/libc/nt/gdi32/EnumFontFamiliesExW.s new file mode 100644 index 00000000..9c8ba04d --- /dev/null +++ b/libc/nt/gdi32/EnumFontFamiliesExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EnumFontFamiliesExW,EnumFontFamiliesExW,1451 diff --git a/libc/nt/gdi32/EnumFontFamiliesW.s b/libc/nt/gdi32/EnumFontFamiliesW.s new file mode 100644 index 00000000..676bf634 --- /dev/null +++ b/libc/nt/gdi32/EnumFontFamiliesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EnumFontFamiliesW,EnumFontFamiliesW,1452 diff --git a/libc/nt/gdi32/EnumFontsA.s b/libc/nt/gdi32/EnumFontsA.s new file mode 100644 index 00000000..1cae60dd --- /dev/null +++ b/libc/nt/gdi32/EnumFontsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EnumFontsA,EnumFontsA,1453 diff --git a/libc/nt/gdi32/EnumFontsW.s b/libc/nt/gdi32/EnumFontsW.s new file mode 100644 index 00000000..2a1b607f --- /dev/null +++ b/libc/nt/gdi32/EnumFontsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EnumFontsW,EnumFontsW,1454 diff --git a/libc/nt/gdi32/EnumICMProfilesA.s b/libc/nt/gdi32/EnumICMProfilesA.s new file mode 100644 index 00000000..b05eb628 --- /dev/null +++ b/libc/nt/gdi32/EnumICMProfilesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EnumICMProfilesA,EnumICMProfilesA,1455 diff --git a/libc/nt/gdi32/EnumICMProfilesW.s b/libc/nt/gdi32/EnumICMProfilesW.s new file mode 100644 index 00000000..6dd55cde --- /dev/null +++ b/libc/nt/gdi32/EnumICMProfilesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EnumICMProfilesW,EnumICMProfilesW,1456 diff --git a/libc/nt/gdi32/EnumMetaFile.s b/libc/nt/gdi32/EnumMetaFile.s new file mode 100644 index 00000000..d72a7f49 --- /dev/null +++ b/libc/nt/gdi32/EnumMetaFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EnumMetaFile,EnumMetaFile,1457 diff --git a/libc/nt/gdi32/EnumObjects.s b/libc/nt/gdi32/EnumObjects.s new file mode 100644 index 00000000..548fe7c0 --- /dev/null +++ b/libc/nt/gdi32/EnumObjects.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EnumObjects,EnumObjects,1458 diff --git a/libc/nt/gdi32/EqualRgn.s b/libc/nt/gdi32/EqualRgn.s new file mode 100644 index 00000000..bfd3ae07 --- /dev/null +++ b/libc/nt/gdi32/EqualRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EqualRgn,EqualRgn,1459 diff --git a/libc/nt/gdi32/Escape.s b/libc/nt/gdi32/Escape.s new file mode 100644 index 00000000..b4fe3dbb --- /dev/null +++ b/libc/nt/gdi32/Escape.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_Escape,Escape,1460 diff --git a/libc/nt/gdi32/EudcLoadLinkW.s b/libc/nt/gdi32/EudcLoadLinkW.s new file mode 100644 index 00000000..4c1b817e --- /dev/null +++ b/libc/nt/gdi32/EudcLoadLinkW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EudcLoadLinkW,EudcLoadLinkW,1461 diff --git a/libc/nt/gdi32/EudcUnloadLinkW.s b/libc/nt/gdi32/EudcUnloadLinkW.s new file mode 100644 index 00000000..65570b1b --- /dev/null +++ b/libc/nt/gdi32/EudcUnloadLinkW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_EudcUnloadLinkW,EudcUnloadLinkW,1462 diff --git a/libc/nt/gdi32/ExcludeClipRect.s b/libc/nt/gdi32/ExcludeClipRect.s new file mode 100644 index 00000000..455eef93 --- /dev/null +++ b/libc/nt/gdi32/ExcludeClipRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ExcludeClipRect,ExcludeClipRect,1463 diff --git a/libc/nt/gdi32/ExtCreatePen.s b/libc/nt/gdi32/ExtCreatePen.s new file mode 100644 index 00000000..a4614557 --- /dev/null +++ b/libc/nt/gdi32/ExtCreatePen.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ExtCreatePen,ExtCreatePen,1464 diff --git a/libc/nt/gdi32/ExtCreateRegion.s b/libc/nt/gdi32/ExtCreateRegion.s new file mode 100644 index 00000000..511a75db --- /dev/null +++ b/libc/nt/gdi32/ExtCreateRegion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ExtCreateRegion,ExtCreateRegion,1465 diff --git a/libc/nt/gdi32/ExtEscape.s b/libc/nt/gdi32/ExtEscape.s new file mode 100644 index 00000000..b1c42dcc --- /dev/null +++ b/libc/nt/gdi32/ExtEscape.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ExtEscape,ExtEscape,1466 diff --git a/libc/nt/gdi32/ExtFloodFill.s b/libc/nt/gdi32/ExtFloodFill.s new file mode 100644 index 00000000..1062084d --- /dev/null +++ b/libc/nt/gdi32/ExtFloodFill.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ExtFloodFill,ExtFloodFill,1467 diff --git a/libc/nt/gdi32/ExtSelectClipRgn.s b/libc/nt/gdi32/ExtSelectClipRgn.s new file mode 100644 index 00000000..fd2bbf4f --- /dev/null +++ b/libc/nt/gdi32/ExtSelectClipRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ExtSelectClipRgn,ExtSelectClipRgn,1468 diff --git a/libc/nt/gdi32/ExtTextOutA.s b/libc/nt/gdi32/ExtTextOutA.s new file mode 100644 index 00000000..a52441f0 --- /dev/null +++ b/libc/nt/gdi32/ExtTextOutA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ExtTextOutA,ExtTextOutA,1469 diff --git a/libc/nt/gdi32/ExtTextOutW.s b/libc/nt/gdi32/ExtTextOutW.s new file mode 100644 index 00000000..10c76cfd --- /dev/null +++ b/libc/nt/gdi32/ExtTextOutW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ExtTextOutW,ExtTextOutW,1470 diff --git a/libc/nt/gdi32/FONTOBJ_cGetAllGlyphHandles.s b/libc/nt/gdi32/FONTOBJ_cGetAllGlyphHandles.s new file mode 100644 index 00000000..8df7c771 --- /dev/null +++ b/libc/nt/gdi32/FONTOBJ_cGetAllGlyphHandles.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_FONTOBJ_cGetAllGlyphHandles,FONTOBJ_cGetAllGlyphHandles,1471 diff --git a/libc/nt/gdi32/FONTOBJ_cGetGlyphs.s b/libc/nt/gdi32/FONTOBJ_cGetGlyphs.s new file mode 100644 index 00000000..411e09b5 --- /dev/null +++ b/libc/nt/gdi32/FONTOBJ_cGetGlyphs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_FONTOBJ_cGetGlyphs,FONTOBJ_cGetGlyphs,1472 diff --git a/libc/nt/gdi32/FONTOBJ_pQueryGlyphAttrs.s b/libc/nt/gdi32/FONTOBJ_pQueryGlyphAttrs.s new file mode 100644 index 00000000..31ff4c63 --- /dev/null +++ b/libc/nt/gdi32/FONTOBJ_pQueryGlyphAttrs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_FONTOBJ_pQueryGlyphAttrs,FONTOBJ_pQueryGlyphAttrs,1473 diff --git a/libc/nt/gdi32/FONTOBJ_pfdg.s b/libc/nt/gdi32/FONTOBJ_pfdg.s new file mode 100644 index 00000000..50a95d85 --- /dev/null +++ b/libc/nt/gdi32/FONTOBJ_pfdg.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_FONTOBJ_pfdg,FONTOBJ_pfdg,1474 diff --git a/libc/nt/gdi32/FONTOBJ_pifi.s b/libc/nt/gdi32/FONTOBJ_pifi.s new file mode 100644 index 00000000..8a479717 --- /dev/null +++ b/libc/nt/gdi32/FONTOBJ_pifi.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_FONTOBJ_pifi,FONTOBJ_pifi,1475 diff --git a/libc/nt/gdi32/FONTOBJ_pvTrueTypeFontFile.s b/libc/nt/gdi32/FONTOBJ_pvTrueTypeFontFile.s new file mode 100644 index 00000000..90107439 --- /dev/null +++ b/libc/nt/gdi32/FONTOBJ_pvTrueTypeFontFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_FONTOBJ_pvTrueTypeFontFile,FONTOBJ_pvTrueTypeFontFile,1476 diff --git a/libc/nt/gdi32/FONTOBJ_pxoGetXform.s b/libc/nt/gdi32/FONTOBJ_pxoGetXform.s new file mode 100644 index 00000000..ae657693 --- /dev/null +++ b/libc/nt/gdi32/FONTOBJ_pxoGetXform.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_FONTOBJ_pxoGetXform,FONTOBJ_pxoGetXform,1477 diff --git a/libc/nt/gdi32/FONTOBJ_vGetInfo.s b/libc/nt/gdi32/FONTOBJ_vGetInfo.s new file mode 100644 index 00000000..ad07a665 --- /dev/null +++ b/libc/nt/gdi32/FONTOBJ_vGetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_FONTOBJ_vGetInfo,FONTOBJ_vGetInfo,1478 diff --git a/libc/nt/gdi32/FillPath.s b/libc/nt/gdi32/FillPath.s new file mode 100644 index 00000000..f8a289a2 --- /dev/null +++ b/libc/nt/gdi32/FillPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_FillPath,FillPath,1479 diff --git a/libc/nt/gdi32/FillRgn.s b/libc/nt/gdi32/FillRgn.s new file mode 100644 index 00000000..83418020 --- /dev/null +++ b/libc/nt/gdi32/FillRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_FillRgn,FillRgn,1480 diff --git a/libc/nt/gdi32/FixBrushOrgEx.s b/libc/nt/gdi32/FixBrushOrgEx.s new file mode 100644 index 00000000..6eb6793d --- /dev/null +++ b/libc/nt/gdi32/FixBrushOrgEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_FixBrushOrgEx,FixBrushOrgEx,1481 diff --git a/libc/nt/gdi32/FlattenPath.s b/libc/nt/gdi32/FlattenPath.s new file mode 100644 index 00000000..ad2c7884 --- /dev/null +++ b/libc/nt/gdi32/FlattenPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_FlattenPath,FlattenPath,1482 diff --git a/libc/nt/gdi32/FloodFill.s b/libc/nt/gdi32/FloodFill.s new file mode 100644 index 00000000..bb88cd97 --- /dev/null +++ b/libc/nt/gdi32/FloodFill.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_FloodFill,FloodFill,1483 diff --git a/libc/nt/gdi32/FontIsLinked.s b/libc/nt/gdi32/FontIsLinked.s new file mode 100644 index 00000000..77f64c6b --- /dev/null +++ b/libc/nt/gdi32/FontIsLinked.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_FontIsLinked,FontIsLinked,1484 diff --git a/libc/nt/gdi32/FrameRgn.s b/libc/nt/gdi32/FrameRgn.s new file mode 100644 index 00000000..db8a99a9 --- /dev/null +++ b/libc/nt/gdi32/FrameRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_FrameRgn,FrameRgn,1485 diff --git a/libc/nt/gdi32/Gdi32DllInitialize.s b/libc/nt/gdi32/Gdi32DllInitialize.s new file mode 100644 index 00000000..3881560b --- /dev/null +++ b/libc/nt/gdi32/Gdi32DllInitialize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_Gdi32DllInitialize,Gdi32DllInitialize,1486 diff --git a/libc/nt/gdi32/GdiAddFontResourceW.s b/libc/nt/gdi32/GdiAddFontResourceW.s new file mode 100644 index 00000000..6ec91071 --- /dev/null +++ b/libc/nt/gdi32/GdiAddFontResourceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiAddFontResourceW,GdiAddFontResourceW,1487 diff --git a/libc/nt/gdi32/GdiAddGlsBounds.s b/libc/nt/gdi32/GdiAddGlsBounds.s new file mode 100644 index 00000000..c31e9634 --- /dev/null +++ b/libc/nt/gdi32/GdiAddGlsBounds.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiAddGlsBounds,GdiAddGlsBounds,1488 diff --git a/libc/nt/gdi32/GdiAddGlsRecord.s b/libc/nt/gdi32/GdiAddGlsRecord.s new file mode 100644 index 00000000..e10c1fb4 --- /dev/null +++ b/libc/nt/gdi32/GdiAddGlsRecord.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiAddGlsRecord,GdiAddGlsRecord,1489 diff --git a/libc/nt/gdi32/GdiAddInitialFonts.s b/libc/nt/gdi32/GdiAddInitialFonts.s new file mode 100644 index 00000000..57baf033 --- /dev/null +++ b/libc/nt/gdi32/GdiAddInitialFonts.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiAddInitialFonts,GdiAddInitialFonts,1490 diff --git a/libc/nt/gdi32/GdiAlphaBlend.s b/libc/nt/gdi32/GdiAlphaBlend.s new file mode 100644 index 00000000..284af4d2 --- /dev/null +++ b/libc/nt/gdi32/GdiAlphaBlend.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiAlphaBlend,GdiAlphaBlend,1491 diff --git a/libc/nt/gdi32/GdiArtificialDecrementDriver.s b/libc/nt/gdi32/GdiArtificialDecrementDriver.s new file mode 100644 index 00000000..e5ffa5d2 --- /dev/null +++ b/libc/nt/gdi32/GdiArtificialDecrementDriver.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiArtificialDecrementDriver,GdiArtificialDecrementDriver,1492 diff --git a/libc/nt/gdi32/GdiBatchLimit.s b/libc/nt/gdi32/GdiBatchLimit.s new file mode 100644 index 00000000..43042a54 --- /dev/null +++ b/libc/nt/gdi32/GdiBatchLimit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiBatchLimit,GdiBatchLimit,1493 diff --git a/libc/nt/gdi32/GdiCleanCacheDC.s b/libc/nt/gdi32/GdiCleanCacheDC.s new file mode 100644 index 00000000..fb80dc14 --- /dev/null +++ b/libc/nt/gdi32/GdiCleanCacheDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiCleanCacheDC,GdiCleanCacheDC,1494 diff --git a/libc/nt/gdi32/GdiComment.s b/libc/nt/gdi32/GdiComment.s new file mode 100644 index 00000000..4d2c6ba4 --- /dev/null +++ b/libc/nt/gdi32/GdiComment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiComment,GdiComment,1495 diff --git a/libc/nt/gdi32/GdiConsoleTextOut.s b/libc/nt/gdi32/GdiConsoleTextOut.s new file mode 100644 index 00000000..1499230b --- /dev/null +++ b/libc/nt/gdi32/GdiConsoleTextOut.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiConsoleTextOut,GdiConsoleTextOut,1496 diff --git a/libc/nt/gdi32/GdiConvertAndCheckDC.s b/libc/nt/gdi32/GdiConvertAndCheckDC.s new file mode 100644 index 00000000..8374e30e --- /dev/null +++ b/libc/nt/gdi32/GdiConvertAndCheckDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiConvertAndCheckDC,GdiConvertAndCheckDC,1497 diff --git a/libc/nt/gdi32/GdiConvertBitmap.s b/libc/nt/gdi32/GdiConvertBitmap.s new file mode 100644 index 00000000..2644ae1b --- /dev/null +++ b/libc/nt/gdi32/GdiConvertBitmap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiConvertBitmap,GdiConvertBitmap,1498 diff --git a/libc/nt/gdi32/GdiConvertBitmapV5.s b/libc/nt/gdi32/GdiConvertBitmapV5.s new file mode 100644 index 00000000..3462983d --- /dev/null +++ b/libc/nt/gdi32/GdiConvertBitmapV5.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiConvertBitmapV5,GdiConvertBitmapV5,1499 diff --git a/libc/nt/gdi32/GdiConvertBrush.s b/libc/nt/gdi32/GdiConvertBrush.s new file mode 100644 index 00000000..ea79ed86 --- /dev/null +++ b/libc/nt/gdi32/GdiConvertBrush.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiConvertBrush,GdiConvertBrush,1500 diff --git a/libc/nt/gdi32/GdiConvertDC.s b/libc/nt/gdi32/GdiConvertDC.s new file mode 100644 index 00000000..aa7c9ac2 --- /dev/null +++ b/libc/nt/gdi32/GdiConvertDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiConvertDC,GdiConvertDC,1501 diff --git a/libc/nt/gdi32/GdiConvertEnhMetaFile.s b/libc/nt/gdi32/GdiConvertEnhMetaFile.s new file mode 100644 index 00000000..ec0bc59d --- /dev/null +++ b/libc/nt/gdi32/GdiConvertEnhMetaFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiConvertEnhMetaFile,GdiConvertEnhMetaFile,1502 diff --git a/libc/nt/gdi32/GdiConvertFont.s b/libc/nt/gdi32/GdiConvertFont.s new file mode 100644 index 00000000..d9470990 --- /dev/null +++ b/libc/nt/gdi32/GdiConvertFont.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiConvertFont,GdiConvertFont,1503 diff --git a/libc/nt/gdi32/GdiConvertMetaFilePict.s b/libc/nt/gdi32/GdiConvertMetaFilePict.s new file mode 100644 index 00000000..c2717644 --- /dev/null +++ b/libc/nt/gdi32/GdiConvertMetaFilePict.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiConvertMetaFilePict,GdiConvertMetaFilePict,1504 diff --git a/libc/nt/gdi32/GdiConvertPalette.s b/libc/nt/gdi32/GdiConvertPalette.s new file mode 100644 index 00000000..a6c60d88 --- /dev/null +++ b/libc/nt/gdi32/GdiConvertPalette.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiConvertPalette,GdiConvertPalette,1505 diff --git a/libc/nt/gdi32/GdiConvertRegion.s b/libc/nt/gdi32/GdiConvertRegion.s new file mode 100644 index 00000000..4c7ac4ab --- /dev/null +++ b/libc/nt/gdi32/GdiConvertRegion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiConvertRegion,GdiConvertRegion,1506 diff --git a/libc/nt/gdi32/GdiConvertToDevmodeW.s b/libc/nt/gdi32/GdiConvertToDevmodeW.s new file mode 100644 index 00000000..a5040fd0 --- /dev/null +++ b/libc/nt/gdi32/GdiConvertToDevmodeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiConvertToDevmodeW,GdiConvertToDevmodeW,1507 diff --git a/libc/nt/gdi32/GdiCreateLocalEnhMetaFile.s b/libc/nt/gdi32/GdiCreateLocalEnhMetaFile.s new file mode 100644 index 00000000..6ebd6f88 --- /dev/null +++ b/libc/nt/gdi32/GdiCreateLocalEnhMetaFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiCreateLocalEnhMetaFile,GdiCreateLocalEnhMetaFile,1508 diff --git a/libc/nt/gdi32/GdiCreateLocalMetaFilePict.s b/libc/nt/gdi32/GdiCreateLocalMetaFilePict.s new file mode 100644 index 00000000..c4f236c8 --- /dev/null +++ b/libc/nt/gdi32/GdiCreateLocalMetaFilePict.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiCreateLocalMetaFilePict,GdiCreateLocalMetaFilePict,1509 diff --git a/libc/nt/gdi32/GdiCurrentProcessSplWow64.s b/libc/nt/gdi32/GdiCurrentProcessSplWow64.s new file mode 100644 index 00000000..69abaefc --- /dev/null +++ b/libc/nt/gdi32/GdiCurrentProcessSplWow64.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiCurrentProcessSplWow64,GdiCurrentProcessSplWow64,1510 diff --git a/libc/nt/gdi32/GdiDeleteLocalDC.s b/libc/nt/gdi32/GdiDeleteLocalDC.s new file mode 100644 index 00000000..5b0a48a7 --- /dev/null +++ b/libc/nt/gdi32/GdiDeleteLocalDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiDeleteLocalDC,GdiDeleteLocalDC,1511 diff --git a/libc/nt/gdi32/GdiDeleteSpoolFileHandle.s b/libc/nt/gdi32/GdiDeleteSpoolFileHandle.s new file mode 100644 index 00000000..19df9873 --- /dev/null +++ b/libc/nt/gdi32/GdiDeleteSpoolFileHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiDeleteSpoolFileHandle,GdiDeleteSpoolFileHandle,1512 diff --git a/libc/nt/gdi32/GdiDescribePixelFormat.s b/libc/nt/gdi32/GdiDescribePixelFormat.s new file mode 100644 index 00000000..473b0ac7 --- /dev/null +++ b/libc/nt/gdi32/GdiDescribePixelFormat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiDescribePixelFormat,GdiDescribePixelFormat,1513 diff --git a/libc/nt/gdi32/GdiDllInitialize.s b/libc/nt/gdi32/GdiDllInitialize.s new file mode 100644 index 00000000..efc1ce9c --- /dev/null +++ b/libc/nt/gdi32/GdiDllInitialize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiDllInitialize,GdiDllInitialize,1514 diff --git a/libc/nt/gdi32/GdiDrawStream.s b/libc/nt/gdi32/GdiDrawStream.s new file mode 100644 index 00000000..e3e2aa01 --- /dev/null +++ b/libc/nt/gdi32/GdiDrawStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiDrawStream,GdiDrawStream,1515 diff --git a/libc/nt/gdi32/GdiEndDocEMF.s b/libc/nt/gdi32/GdiEndDocEMF.s new file mode 100644 index 00000000..6c5911cf --- /dev/null +++ b/libc/nt/gdi32/GdiEndDocEMF.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEndDocEMF,GdiEndDocEMF,1516 diff --git a/libc/nt/gdi32/GdiEndPageEMF.s b/libc/nt/gdi32/GdiEndPageEMF.s new file mode 100644 index 00000000..9db61005 --- /dev/null +++ b/libc/nt/gdi32/GdiEndPageEMF.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEndPageEMF,GdiEndPageEMF,1517 diff --git a/libc/nt/gdi32/GdiEntry1.s b/libc/nt/gdi32/GdiEntry1.s new file mode 100644 index 00000000..e21fb95c --- /dev/null +++ b/libc/nt/gdi32/GdiEntry1.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEntry1,GdiEntry1,1518 diff --git a/libc/nt/gdi32/GdiEntry10.s b/libc/nt/gdi32/GdiEntry10.s new file mode 100644 index 00000000..865d6b48 --- /dev/null +++ b/libc/nt/gdi32/GdiEntry10.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEntry10,GdiEntry10,1519 diff --git a/libc/nt/gdi32/GdiEntry11.s b/libc/nt/gdi32/GdiEntry11.s new file mode 100644 index 00000000..297be238 --- /dev/null +++ b/libc/nt/gdi32/GdiEntry11.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEntry11,GdiEntry11,1520 diff --git a/libc/nt/gdi32/GdiEntry12.s b/libc/nt/gdi32/GdiEntry12.s new file mode 100644 index 00000000..e7d9ddcb --- /dev/null +++ b/libc/nt/gdi32/GdiEntry12.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEntry12,GdiEntry12,1521 diff --git a/libc/nt/gdi32/GdiEntry13.s b/libc/nt/gdi32/GdiEntry13.s new file mode 100644 index 00000000..cd17cedc --- /dev/null +++ b/libc/nt/gdi32/GdiEntry13.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEntry13,GdiEntry13,1522 diff --git a/libc/nt/gdi32/GdiEntry14.s b/libc/nt/gdi32/GdiEntry14.s new file mode 100644 index 00000000..f2892ec2 --- /dev/null +++ b/libc/nt/gdi32/GdiEntry14.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEntry14,GdiEntry14,1523 diff --git a/libc/nt/gdi32/GdiEntry15.s b/libc/nt/gdi32/GdiEntry15.s new file mode 100644 index 00000000..81e3b1dc --- /dev/null +++ b/libc/nt/gdi32/GdiEntry15.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEntry15,GdiEntry15,1524 diff --git a/libc/nt/gdi32/GdiEntry16.s b/libc/nt/gdi32/GdiEntry16.s new file mode 100644 index 00000000..39466938 --- /dev/null +++ b/libc/nt/gdi32/GdiEntry16.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEntry16,GdiEntry16,1525 diff --git a/libc/nt/gdi32/GdiEntry2.s b/libc/nt/gdi32/GdiEntry2.s new file mode 100644 index 00000000..20c3d8e5 --- /dev/null +++ b/libc/nt/gdi32/GdiEntry2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEntry2,GdiEntry2,1526 diff --git a/libc/nt/gdi32/GdiEntry3.s b/libc/nt/gdi32/GdiEntry3.s new file mode 100644 index 00000000..07951818 --- /dev/null +++ b/libc/nt/gdi32/GdiEntry3.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEntry3,GdiEntry3,1527 diff --git a/libc/nt/gdi32/GdiEntry4.s b/libc/nt/gdi32/GdiEntry4.s new file mode 100644 index 00000000..0625863e --- /dev/null +++ b/libc/nt/gdi32/GdiEntry4.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEntry4,GdiEntry4,1528 diff --git a/libc/nt/gdi32/GdiEntry5.s b/libc/nt/gdi32/GdiEntry5.s new file mode 100644 index 00000000..833a8013 --- /dev/null +++ b/libc/nt/gdi32/GdiEntry5.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEntry5,GdiEntry5,1529 diff --git a/libc/nt/gdi32/GdiEntry6.s b/libc/nt/gdi32/GdiEntry6.s new file mode 100644 index 00000000..b814bf10 --- /dev/null +++ b/libc/nt/gdi32/GdiEntry6.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEntry6,GdiEntry6,1530 diff --git a/libc/nt/gdi32/GdiEntry7.s b/libc/nt/gdi32/GdiEntry7.s new file mode 100644 index 00000000..9bd13d5e --- /dev/null +++ b/libc/nt/gdi32/GdiEntry7.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEntry7,GdiEntry7,1531 diff --git a/libc/nt/gdi32/GdiEntry8.s b/libc/nt/gdi32/GdiEntry8.s new file mode 100644 index 00000000..2de94035 --- /dev/null +++ b/libc/nt/gdi32/GdiEntry8.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEntry8,GdiEntry8,1532 diff --git a/libc/nt/gdi32/GdiEntry9.s b/libc/nt/gdi32/GdiEntry9.s new file mode 100644 index 00000000..43944a29 --- /dev/null +++ b/libc/nt/gdi32/GdiEntry9.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiEntry9,GdiEntry9,1533 diff --git a/libc/nt/gdi32/GdiFixUpHandle.s b/libc/nt/gdi32/GdiFixUpHandle.s new file mode 100644 index 00000000..3e0180da --- /dev/null +++ b/libc/nt/gdi32/GdiFixUpHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiFixUpHandle,GdiFixUpHandle,1534 diff --git a/libc/nt/gdi32/GdiFlush.s b/libc/nt/gdi32/GdiFlush.s new file mode 100644 index 00000000..d409fb5d --- /dev/null +++ b/libc/nt/gdi32/GdiFlush.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiFlush,GdiFlush,1535 diff --git a/libc/nt/gdi32/GdiFullscreenControl.s b/libc/nt/gdi32/GdiFullscreenControl.s new file mode 100644 index 00000000..a578ff50 --- /dev/null +++ b/libc/nt/gdi32/GdiFullscreenControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiFullscreenControl,GdiFullscreenControl,1536 diff --git a/libc/nt/gdi32/GdiGetBatchLimit.s b/libc/nt/gdi32/GdiGetBatchLimit.s new file mode 100644 index 00000000..733d73f8 --- /dev/null +++ b/libc/nt/gdi32/GdiGetBatchLimit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiGetBatchLimit,GdiGetBatchLimit,1537 diff --git a/libc/nt/gdi32/GdiGetBitmapBitsSize.s b/libc/nt/gdi32/GdiGetBitmapBitsSize.s new file mode 100644 index 00000000..759912f8 --- /dev/null +++ b/libc/nt/gdi32/GdiGetBitmapBitsSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiGetBitmapBitsSize,GdiGetBitmapBitsSize,1538 diff --git a/libc/nt/gdi32/GdiGetCharDimensions.s b/libc/nt/gdi32/GdiGetCharDimensions.s new file mode 100644 index 00000000..365b07c0 --- /dev/null +++ b/libc/nt/gdi32/GdiGetCharDimensions.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiGetCharDimensions,GdiGetCharDimensions,1539 diff --git a/libc/nt/gdi32/GdiGetCodePage.s b/libc/nt/gdi32/GdiGetCodePage.s new file mode 100644 index 00000000..5d82f197 --- /dev/null +++ b/libc/nt/gdi32/GdiGetCodePage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiGetCodePage,GdiGetCodePage,1540 diff --git a/libc/nt/gdi32/GdiGetDC.s b/libc/nt/gdi32/GdiGetDC.s new file mode 100644 index 00000000..210f15f4 --- /dev/null +++ b/libc/nt/gdi32/GdiGetDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiGetDC,GdiGetDC,1541 diff --git a/libc/nt/gdi32/GdiGetDevmodeForPage.s b/libc/nt/gdi32/GdiGetDevmodeForPage.s new file mode 100644 index 00000000..fa8b9d81 --- /dev/null +++ b/libc/nt/gdi32/GdiGetDevmodeForPage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiGetDevmodeForPage,GdiGetDevmodeForPage,1542 diff --git a/libc/nt/gdi32/GdiGetEntry.s b/libc/nt/gdi32/GdiGetEntry.s new file mode 100644 index 00000000..3fe67acd --- /dev/null +++ b/libc/nt/gdi32/GdiGetEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiGetEntry,GdiGetEntry,1543 diff --git a/libc/nt/gdi32/GdiGetLocalBrush.s b/libc/nt/gdi32/GdiGetLocalBrush.s new file mode 100644 index 00000000..0bd4f844 --- /dev/null +++ b/libc/nt/gdi32/GdiGetLocalBrush.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiGetLocalBrush,GdiGetLocalBrush,1544 diff --git a/libc/nt/gdi32/GdiGetLocalDC.s b/libc/nt/gdi32/GdiGetLocalDC.s new file mode 100644 index 00000000..d2a5b5cf --- /dev/null +++ b/libc/nt/gdi32/GdiGetLocalDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiGetLocalDC,GdiGetLocalDC,1545 diff --git a/libc/nt/gdi32/GdiGetLocalFont.s b/libc/nt/gdi32/GdiGetLocalFont.s new file mode 100644 index 00000000..eaf74945 --- /dev/null +++ b/libc/nt/gdi32/GdiGetLocalFont.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiGetLocalFont,GdiGetLocalFont,1546 diff --git a/libc/nt/gdi32/GdiGetPageCount.s b/libc/nt/gdi32/GdiGetPageCount.s new file mode 100644 index 00000000..f3b2c729 --- /dev/null +++ b/libc/nt/gdi32/GdiGetPageCount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiGetPageCount,GdiGetPageCount,1547 diff --git a/libc/nt/gdi32/GdiGetPageHandle.s b/libc/nt/gdi32/GdiGetPageHandle.s new file mode 100644 index 00000000..84a4128b --- /dev/null +++ b/libc/nt/gdi32/GdiGetPageHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiGetPageHandle,GdiGetPageHandle,1548 diff --git a/libc/nt/gdi32/GdiGetSpoolFileHandle.s b/libc/nt/gdi32/GdiGetSpoolFileHandle.s new file mode 100644 index 00000000..e3c5f8a2 --- /dev/null +++ b/libc/nt/gdi32/GdiGetSpoolFileHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiGetSpoolFileHandle,GdiGetSpoolFileHandle,1549 diff --git a/libc/nt/gdi32/GdiGetSpoolMessage.s b/libc/nt/gdi32/GdiGetSpoolMessage.s new file mode 100644 index 00000000..6fd88ebe --- /dev/null +++ b/libc/nt/gdi32/GdiGetSpoolMessage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiGetSpoolMessage,GdiGetSpoolMessage,1550 diff --git a/libc/nt/gdi32/GdiGetVariationStoreDelta.s b/libc/nt/gdi32/GdiGetVariationStoreDelta.s new file mode 100644 index 00000000..ebdf7638 --- /dev/null +++ b/libc/nt/gdi32/GdiGetVariationStoreDelta.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiGetVariationStoreDelta,GdiGetVariationStoreDelta,1551 diff --git a/libc/nt/gdi32/GdiGradientFill.s b/libc/nt/gdi32/GdiGradientFill.s new file mode 100644 index 00000000..23e942eb --- /dev/null +++ b/libc/nt/gdi32/GdiGradientFill.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiGradientFill,GdiGradientFill,1552 diff --git a/libc/nt/gdi32/GdiInitSpool.s b/libc/nt/gdi32/GdiInitSpool.s new file mode 100644 index 00000000..7b69dea6 --- /dev/null +++ b/libc/nt/gdi32/GdiInitSpool.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiInitSpool,GdiInitSpool,1553 diff --git a/libc/nt/gdi32/GdiInitializeLanguagePack.s b/libc/nt/gdi32/GdiInitializeLanguagePack.s new file mode 100644 index 00000000..3b67fc71 --- /dev/null +++ b/libc/nt/gdi32/GdiInitializeLanguagePack.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiInitializeLanguagePack,GdiInitializeLanguagePack,1554 diff --git a/libc/nt/gdi32/GdiIsMetaFileDC.s b/libc/nt/gdi32/GdiIsMetaFileDC.s new file mode 100644 index 00000000..e5fc0002 --- /dev/null +++ b/libc/nt/gdi32/GdiIsMetaFileDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiIsMetaFileDC,GdiIsMetaFileDC,1555 diff --git a/libc/nt/gdi32/GdiIsMetaPrintDC.s b/libc/nt/gdi32/GdiIsMetaPrintDC.s new file mode 100644 index 00000000..20ff3647 --- /dev/null +++ b/libc/nt/gdi32/GdiIsMetaPrintDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiIsMetaPrintDC,GdiIsMetaPrintDC,1556 diff --git a/libc/nt/gdi32/GdiIsPlayMetafileDC.s b/libc/nt/gdi32/GdiIsPlayMetafileDC.s new file mode 100644 index 00000000..db887eb6 --- /dev/null +++ b/libc/nt/gdi32/GdiIsPlayMetafileDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiIsPlayMetafileDC,GdiIsPlayMetafileDC,1557 diff --git a/libc/nt/gdi32/GdiIsScreenDC.s b/libc/nt/gdi32/GdiIsScreenDC.s new file mode 100644 index 00000000..a40dd15f --- /dev/null +++ b/libc/nt/gdi32/GdiIsScreenDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiIsScreenDC,GdiIsScreenDC,1558 diff --git a/libc/nt/gdi32/GdiIsTrackingEnabled.s b/libc/nt/gdi32/GdiIsTrackingEnabled.s new file mode 100644 index 00000000..0704f4f8 --- /dev/null +++ b/libc/nt/gdi32/GdiIsTrackingEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiIsTrackingEnabled,GdiIsTrackingEnabled,1559 diff --git a/libc/nt/gdi32/GdiIsUMPDSandboxingEnabled.s b/libc/nt/gdi32/GdiIsUMPDSandboxingEnabled.s new file mode 100644 index 00000000..d32a05e5 --- /dev/null +++ b/libc/nt/gdi32/GdiIsUMPDSandboxingEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiIsUMPDSandboxingEnabled,GdiIsUMPDSandboxingEnabled,1560 diff --git a/libc/nt/gdi32/GdiLoadType1Fonts.s b/libc/nt/gdi32/GdiLoadType1Fonts.s new file mode 100644 index 00000000..24b25b3f --- /dev/null +++ b/libc/nt/gdi32/GdiLoadType1Fonts.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiLoadType1Fonts,GdiLoadType1Fonts,1561 diff --git a/libc/nt/gdi32/GdiPlayDCScript.s b/libc/nt/gdi32/GdiPlayDCScript.s new file mode 100644 index 00000000..96aaf9df --- /dev/null +++ b/libc/nt/gdi32/GdiPlayDCScript.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiPlayDCScript,GdiPlayDCScript,1562 diff --git a/libc/nt/gdi32/GdiPlayEMF.s b/libc/nt/gdi32/GdiPlayEMF.s new file mode 100644 index 00000000..b2165c0d --- /dev/null +++ b/libc/nt/gdi32/GdiPlayEMF.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiPlayEMF,GdiPlayEMF,1563 diff --git a/libc/nt/gdi32/GdiPlayJournal.s b/libc/nt/gdi32/GdiPlayJournal.s new file mode 100644 index 00000000..bfd03f27 --- /dev/null +++ b/libc/nt/gdi32/GdiPlayJournal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiPlayJournal,GdiPlayJournal,1564 diff --git a/libc/nt/gdi32/GdiPlayPageEMF.s b/libc/nt/gdi32/GdiPlayPageEMF.s new file mode 100644 index 00000000..a4b9622d --- /dev/null +++ b/libc/nt/gdi32/GdiPlayPageEMF.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiPlayPageEMF,GdiPlayPageEMF,1565 diff --git a/libc/nt/gdi32/GdiPlayPrivatePageEMF.s b/libc/nt/gdi32/GdiPlayPrivatePageEMF.s new file mode 100644 index 00000000..786bc132 --- /dev/null +++ b/libc/nt/gdi32/GdiPlayPrivatePageEMF.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiPlayPrivatePageEMF,GdiPlayPrivatePageEMF,1566 diff --git a/libc/nt/gdi32/GdiPlayScript.s b/libc/nt/gdi32/GdiPlayScript.s new file mode 100644 index 00000000..4e071ffa --- /dev/null +++ b/libc/nt/gdi32/GdiPlayScript.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiPlayScript,GdiPlayScript,1567 diff --git a/libc/nt/gdi32/GdiPrinterThunk.s b/libc/nt/gdi32/GdiPrinterThunk.s new file mode 100644 index 00000000..55aa036d --- /dev/null +++ b/libc/nt/gdi32/GdiPrinterThunk.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiPrinterThunk,GdiPrinterThunk,1568 diff --git a/libc/nt/gdi32/GdiProcessSetup.s b/libc/nt/gdi32/GdiProcessSetup.s new file mode 100644 index 00000000..08f259e2 --- /dev/null +++ b/libc/nt/gdi32/GdiProcessSetup.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiProcessSetup,GdiProcessSetup,1569 diff --git a/libc/nt/gdi32/GdiQueryFonts.s b/libc/nt/gdi32/GdiQueryFonts.s new file mode 100644 index 00000000..01950ecf --- /dev/null +++ b/libc/nt/gdi32/GdiQueryFonts.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiQueryFonts,GdiQueryFonts,1570 diff --git a/libc/nt/gdi32/GdiQueryTable.s b/libc/nt/gdi32/GdiQueryTable.s new file mode 100644 index 00000000..cfb24ba6 --- /dev/null +++ b/libc/nt/gdi32/GdiQueryTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiQueryTable,GdiQueryTable,1571 diff --git a/libc/nt/gdi32/GdiRealizationInfo.s b/libc/nt/gdi32/GdiRealizationInfo.s new file mode 100644 index 00000000..0ffb8bce --- /dev/null +++ b/libc/nt/gdi32/GdiRealizationInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiRealizationInfo,GdiRealizationInfo,1572 diff --git a/libc/nt/gdi32/GdiReleaseDC.s b/libc/nt/gdi32/GdiReleaseDC.s new file mode 100644 index 00000000..c72670ce --- /dev/null +++ b/libc/nt/gdi32/GdiReleaseDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiReleaseDC,GdiReleaseDC,1573 diff --git a/libc/nt/gdi32/GdiReleaseLocalDC.s b/libc/nt/gdi32/GdiReleaseLocalDC.s new file mode 100644 index 00000000..7a9504f6 --- /dev/null +++ b/libc/nt/gdi32/GdiReleaseLocalDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiReleaseLocalDC,GdiReleaseLocalDC,1574 diff --git a/libc/nt/gdi32/GdiResetDCEMF.s b/libc/nt/gdi32/GdiResetDCEMF.s new file mode 100644 index 00000000..72d27012 --- /dev/null +++ b/libc/nt/gdi32/GdiResetDCEMF.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiResetDCEMF,GdiResetDCEMF,1575 diff --git a/libc/nt/gdi32/GdiSetAttrs.s b/libc/nt/gdi32/GdiSetAttrs.s new file mode 100644 index 00000000..bdc982a9 --- /dev/null +++ b/libc/nt/gdi32/GdiSetAttrs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiSetAttrs,GdiSetAttrs,1576 diff --git a/libc/nt/gdi32/GdiSetBatchLimit.s b/libc/nt/gdi32/GdiSetBatchLimit.s new file mode 100644 index 00000000..20761159 --- /dev/null +++ b/libc/nt/gdi32/GdiSetBatchLimit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiSetBatchLimit,GdiSetBatchLimit,1577 diff --git a/libc/nt/gdi32/GdiSetLastError.s b/libc/nt/gdi32/GdiSetLastError.s new file mode 100644 index 00000000..0aa13ce0 --- /dev/null +++ b/libc/nt/gdi32/GdiSetLastError.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiSetLastError,GdiSetLastError,1578 diff --git a/libc/nt/gdi32/GdiSetPixelFormat.s b/libc/nt/gdi32/GdiSetPixelFormat.s new file mode 100644 index 00000000..24656ed7 --- /dev/null +++ b/libc/nt/gdi32/GdiSetPixelFormat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiSetPixelFormat,GdiSetPixelFormat,1579 diff --git a/libc/nt/gdi32/GdiSetServerAttr.s b/libc/nt/gdi32/GdiSetServerAttr.s new file mode 100644 index 00000000..bffe8a2b --- /dev/null +++ b/libc/nt/gdi32/GdiSetServerAttr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiSetServerAttr,GdiSetServerAttr,1580 diff --git a/libc/nt/gdi32/GdiStartDocEMF.s b/libc/nt/gdi32/GdiStartDocEMF.s new file mode 100644 index 00000000..7f94a6c8 --- /dev/null +++ b/libc/nt/gdi32/GdiStartDocEMF.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiStartDocEMF,GdiStartDocEMF,1581 diff --git a/libc/nt/gdi32/GdiStartPageEMF.s b/libc/nt/gdi32/GdiStartPageEMF.s new file mode 100644 index 00000000..8f863345 --- /dev/null +++ b/libc/nt/gdi32/GdiStartPageEMF.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiStartPageEMF,GdiStartPageEMF,1582 diff --git a/libc/nt/gdi32/GdiSupportsFontChangeEvent.s b/libc/nt/gdi32/GdiSupportsFontChangeEvent.s new file mode 100644 index 00000000..c21cfce8 --- /dev/null +++ b/libc/nt/gdi32/GdiSupportsFontChangeEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiSupportsFontChangeEvent,GdiSupportsFontChangeEvent,1583 diff --git a/libc/nt/gdi32/GdiSwapBuffers.s b/libc/nt/gdi32/GdiSwapBuffers.s new file mode 100644 index 00000000..d9da5088 --- /dev/null +++ b/libc/nt/gdi32/GdiSwapBuffers.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiSwapBuffers,GdiSwapBuffers,1584 diff --git a/libc/nt/gdi32/GdiTrackHCreate.s b/libc/nt/gdi32/GdiTrackHCreate.s new file mode 100644 index 00000000..63962751 --- /dev/null +++ b/libc/nt/gdi32/GdiTrackHCreate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiTrackHCreate,GdiTrackHCreate,1585 diff --git a/libc/nt/gdi32/GdiTrackHDelete.s b/libc/nt/gdi32/GdiTrackHDelete.s new file mode 100644 index 00000000..5ced0540 --- /dev/null +++ b/libc/nt/gdi32/GdiTrackHDelete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiTrackHDelete,GdiTrackHDelete,1586 diff --git a/libc/nt/gdi32/GdiTransparentBlt.s b/libc/nt/gdi32/GdiTransparentBlt.s new file mode 100644 index 00000000..5c857ef9 --- /dev/null +++ b/libc/nt/gdi32/GdiTransparentBlt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiTransparentBlt,GdiTransparentBlt,1587 diff --git a/libc/nt/gdi32/GdiValidateHandle.s b/libc/nt/gdi32/GdiValidateHandle.s new file mode 100644 index 00000000..fece8dcc --- /dev/null +++ b/libc/nt/gdi32/GdiValidateHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GdiValidateHandle,GdiValidateHandle,1588 diff --git a/libc/nt/gdi32/GetArcDirection.s b/libc/nt/gdi32/GetArcDirection.s new file mode 100644 index 00000000..28db477f --- /dev/null +++ b/libc/nt/gdi32/GetArcDirection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetArcDirection,GetArcDirection,1589 diff --git a/libc/nt/gdi32/GetAspectRatioFilterEx.s b/libc/nt/gdi32/GetAspectRatioFilterEx.s new file mode 100644 index 00000000..93417e83 --- /dev/null +++ b/libc/nt/gdi32/GetAspectRatioFilterEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetAspectRatioFilterEx,GetAspectRatioFilterEx,1590 diff --git a/libc/nt/gdi32/GetBitmapAttributes.s b/libc/nt/gdi32/GetBitmapAttributes.s new file mode 100644 index 00000000..70c060ca --- /dev/null +++ b/libc/nt/gdi32/GetBitmapAttributes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetBitmapAttributes,GetBitmapAttributes,1591 diff --git a/libc/nt/gdi32/GetBitmapBits.s b/libc/nt/gdi32/GetBitmapBits.s new file mode 100644 index 00000000..f9f4a954 --- /dev/null +++ b/libc/nt/gdi32/GetBitmapBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetBitmapBits,GetBitmapBits,1592 diff --git a/libc/nt/gdi32/GetBitmapDimensionEx.s b/libc/nt/gdi32/GetBitmapDimensionEx.s new file mode 100644 index 00000000..423f37e3 --- /dev/null +++ b/libc/nt/gdi32/GetBitmapDimensionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetBitmapDimensionEx,GetBitmapDimensionEx,1593 diff --git a/libc/nt/gdi32/GetBitmapDpiScaleValue.s b/libc/nt/gdi32/GetBitmapDpiScaleValue.s new file mode 100644 index 00000000..7c37b211 --- /dev/null +++ b/libc/nt/gdi32/GetBitmapDpiScaleValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetBitmapDpiScaleValue,GetBitmapDpiScaleValue,1594 diff --git a/libc/nt/gdi32/GetBkColor.s b/libc/nt/gdi32/GetBkColor.s new file mode 100644 index 00000000..801922ea --- /dev/null +++ b/libc/nt/gdi32/GetBkColor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetBkColor,GetBkColor,1595 diff --git a/libc/nt/gdi32/GetBkMode.s b/libc/nt/gdi32/GetBkMode.s new file mode 100644 index 00000000..e509a90b --- /dev/null +++ b/libc/nt/gdi32/GetBkMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetBkMode,GetBkMode,1596 diff --git a/libc/nt/gdi32/GetBoundsRect.s b/libc/nt/gdi32/GetBoundsRect.s new file mode 100644 index 00000000..d314ef2b --- /dev/null +++ b/libc/nt/gdi32/GetBoundsRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetBoundsRect,GetBoundsRect,1597 diff --git a/libc/nt/gdi32/GetBrushAttributes.s b/libc/nt/gdi32/GetBrushAttributes.s new file mode 100644 index 00000000..d37de50c --- /dev/null +++ b/libc/nt/gdi32/GetBrushAttributes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetBrushAttributes,GetBrushAttributes,1598 diff --git a/libc/nt/gdi32/GetBrushOrgEx.s b/libc/nt/gdi32/GetBrushOrgEx.s new file mode 100644 index 00000000..e4ea9fe6 --- /dev/null +++ b/libc/nt/gdi32/GetBrushOrgEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetBrushOrgEx,GetBrushOrgEx,1599 diff --git a/libc/nt/gdi32/GetCOPPCompatibleOPMInformation.s b/libc/nt/gdi32/GetCOPPCompatibleOPMInformation.s new file mode 100644 index 00000000..b6610bea --- /dev/null +++ b/libc/nt/gdi32/GetCOPPCompatibleOPMInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCOPPCompatibleOPMInformation,GetCOPPCompatibleOPMInformation,1600 diff --git a/libc/nt/gdi32/GetCertificate.s b/libc/nt/gdi32/GetCertificate.s new file mode 100644 index 00000000..d0bf82e2 --- /dev/null +++ b/libc/nt/gdi32/GetCertificate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCertificate,GetCertificate,1601 diff --git a/libc/nt/gdi32/GetCertificateByHandle.s b/libc/nt/gdi32/GetCertificateByHandle.s new file mode 100644 index 00000000..7721609e --- /dev/null +++ b/libc/nt/gdi32/GetCertificateByHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCertificateByHandle,GetCertificateByHandle,1602 diff --git a/libc/nt/gdi32/GetCertificateSize.s b/libc/nt/gdi32/GetCertificateSize.s new file mode 100644 index 00000000..4801a0f8 --- /dev/null +++ b/libc/nt/gdi32/GetCertificateSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCertificateSize,GetCertificateSize,1603 diff --git a/libc/nt/gdi32/GetCertificateSizeByHandle.s b/libc/nt/gdi32/GetCertificateSizeByHandle.s new file mode 100644 index 00000000..f4ac65d7 --- /dev/null +++ b/libc/nt/gdi32/GetCertificateSizeByHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCertificateSizeByHandle,GetCertificateSizeByHandle,1604 diff --git a/libc/nt/gdi32/GetCharABCWidthsA.s b/libc/nt/gdi32/GetCharABCWidthsA.s new file mode 100644 index 00000000..b4fe16f1 --- /dev/null +++ b/libc/nt/gdi32/GetCharABCWidthsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCharABCWidthsA,GetCharABCWidthsA,1605 diff --git a/libc/nt/gdi32/GetCharABCWidthsFloatA.s b/libc/nt/gdi32/GetCharABCWidthsFloatA.s new file mode 100644 index 00000000..868619f1 --- /dev/null +++ b/libc/nt/gdi32/GetCharABCWidthsFloatA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCharABCWidthsFloatA,GetCharABCWidthsFloatA,1606 diff --git a/libc/nt/gdi32/GetCharABCWidthsFloatI.s b/libc/nt/gdi32/GetCharABCWidthsFloatI.s new file mode 100644 index 00000000..86325297 --- /dev/null +++ b/libc/nt/gdi32/GetCharABCWidthsFloatI.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCharABCWidthsFloatI,GetCharABCWidthsFloatI,1607 diff --git a/libc/nt/gdi32/GetCharABCWidthsFloatW.s b/libc/nt/gdi32/GetCharABCWidthsFloatW.s new file mode 100644 index 00000000..d25d7202 --- /dev/null +++ b/libc/nt/gdi32/GetCharABCWidthsFloatW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCharABCWidthsFloatW,GetCharABCWidthsFloatW,1608 diff --git a/libc/nt/gdi32/GetCharABCWidthsI.s b/libc/nt/gdi32/GetCharABCWidthsI.s new file mode 100644 index 00000000..ecf4cf30 --- /dev/null +++ b/libc/nt/gdi32/GetCharABCWidthsI.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCharABCWidthsI,GetCharABCWidthsI,1609 diff --git a/libc/nt/gdi32/GetCharABCWidthsW.s b/libc/nt/gdi32/GetCharABCWidthsW.s new file mode 100644 index 00000000..809f00ac --- /dev/null +++ b/libc/nt/gdi32/GetCharABCWidthsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCharABCWidthsW,GetCharABCWidthsW,1610 diff --git a/libc/nt/gdi32/GetCharWidth32A.s b/libc/nt/gdi32/GetCharWidth32A.s new file mode 100644 index 00000000..d1efa1b7 --- /dev/null +++ b/libc/nt/gdi32/GetCharWidth32A.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCharWidth32A,GetCharWidth32A,1611 diff --git a/libc/nt/gdi32/GetCharWidth32W.s b/libc/nt/gdi32/GetCharWidth32W.s new file mode 100644 index 00000000..fcc856c8 --- /dev/null +++ b/libc/nt/gdi32/GetCharWidth32W.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCharWidth32W,GetCharWidth32W,1612 diff --git a/libc/nt/gdi32/GetCharWidthA.s b/libc/nt/gdi32/GetCharWidthA.s new file mode 100644 index 00000000..3d3f05bb --- /dev/null +++ b/libc/nt/gdi32/GetCharWidthA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCharWidthA,GetCharWidthA,1613 diff --git a/libc/nt/gdi32/GetCharWidthFloatA.s b/libc/nt/gdi32/GetCharWidthFloatA.s new file mode 100644 index 00000000..e813b954 --- /dev/null +++ b/libc/nt/gdi32/GetCharWidthFloatA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCharWidthFloatA,GetCharWidthFloatA,1614 diff --git a/libc/nt/gdi32/GetCharWidthFloatW.s b/libc/nt/gdi32/GetCharWidthFloatW.s new file mode 100644 index 00000000..2f437918 --- /dev/null +++ b/libc/nt/gdi32/GetCharWidthFloatW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCharWidthFloatW,GetCharWidthFloatW,1615 diff --git a/libc/nt/gdi32/GetCharWidthI.s b/libc/nt/gdi32/GetCharWidthI.s new file mode 100644 index 00000000..f6e780f6 --- /dev/null +++ b/libc/nt/gdi32/GetCharWidthI.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCharWidthI,GetCharWidthI,1616 diff --git a/libc/nt/gdi32/GetCharWidthInfo.s b/libc/nt/gdi32/GetCharWidthInfo.s new file mode 100644 index 00000000..9f303352 --- /dev/null +++ b/libc/nt/gdi32/GetCharWidthInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCharWidthInfo,GetCharWidthInfo,1617 diff --git a/libc/nt/gdi32/GetCharWidthW.s b/libc/nt/gdi32/GetCharWidthW.s new file mode 100644 index 00000000..ec92e2af --- /dev/null +++ b/libc/nt/gdi32/GetCharWidthW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCharWidthW,GetCharWidthW,1618 diff --git a/libc/nt/gdi32/GetCharacterPlacementA.s b/libc/nt/gdi32/GetCharacterPlacementA.s new file mode 100644 index 00000000..eb6fba7a --- /dev/null +++ b/libc/nt/gdi32/GetCharacterPlacementA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCharacterPlacementA,GetCharacterPlacementA,1619 diff --git a/libc/nt/gdi32/GetCharacterPlacementW.s b/libc/nt/gdi32/GetCharacterPlacementW.s new file mode 100644 index 00000000..ae11bffc --- /dev/null +++ b/libc/nt/gdi32/GetCharacterPlacementW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCharacterPlacementW,GetCharacterPlacementW,1620 diff --git a/libc/nt/gdi32/GetClipBox.s b/libc/nt/gdi32/GetClipBox.s new file mode 100644 index 00000000..fb0903bd --- /dev/null +++ b/libc/nt/gdi32/GetClipBox.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetClipBox,GetClipBox,1621 diff --git a/libc/nt/gdi32/GetClipRgn.s b/libc/nt/gdi32/GetClipRgn.s new file mode 100644 index 00000000..78ef8c33 --- /dev/null +++ b/libc/nt/gdi32/GetClipRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetClipRgn,GetClipRgn,1622 diff --git a/libc/nt/gdi32/GetColorAdjustment.s b/libc/nt/gdi32/GetColorAdjustment.s new file mode 100644 index 00000000..f5bf0113 --- /dev/null +++ b/libc/nt/gdi32/GetColorAdjustment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetColorAdjustment,GetColorAdjustment,1623 diff --git a/libc/nt/gdi32/GetColorSpace.s b/libc/nt/gdi32/GetColorSpace.s new file mode 100644 index 00000000..334095bc --- /dev/null +++ b/libc/nt/gdi32/GetColorSpace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetColorSpace,GetColorSpace,1624 diff --git a/libc/nt/gdi32/GetCurrentDpiInfo.s b/libc/nt/gdi32/GetCurrentDpiInfo.s new file mode 100644 index 00000000..090217d6 --- /dev/null +++ b/libc/nt/gdi32/GetCurrentDpiInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCurrentDpiInfo,GetCurrentDpiInfo,1625 diff --git a/libc/nt/gdi32/GetCurrentObject.s b/libc/nt/gdi32/GetCurrentObject.s new file mode 100644 index 00000000..eb85ccbf --- /dev/null +++ b/libc/nt/gdi32/GetCurrentObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCurrentObject,GetCurrentObject,1626 diff --git a/libc/nt/gdi32/GetCurrentPositionEx.s b/libc/nt/gdi32/GetCurrentPositionEx.s new file mode 100644 index 00000000..c5e9a3d3 --- /dev/null +++ b/libc/nt/gdi32/GetCurrentPositionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetCurrentPositionEx,GetCurrentPositionEx,1627 diff --git a/libc/nt/gdi32/GetDCBrushColor.s b/libc/nt/gdi32/GetDCBrushColor.s new file mode 100644 index 00000000..6d4b78df --- /dev/null +++ b/libc/nt/gdi32/GetDCBrushColor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetDCBrushColor,GetDCBrushColor,1628 diff --git a/libc/nt/gdi32/GetDCDpiScaleValue.s b/libc/nt/gdi32/GetDCDpiScaleValue.s new file mode 100644 index 00000000..f202a084 --- /dev/null +++ b/libc/nt/gdi32/GetDCDpiScaleValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetDCDpiScaleValue,GetDCDpiScaleValue,1629 diff --git a/libc/nt/gdi32/GetDCOrgEx.s b/libc/nt/gdi32/GetDCOrgEx.s new file mode 100644 index 00000000..d72d41df --- /dev/null +++ b/libc/nt/gdi32/GetDCOrgEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetDCOrgEx,GetDCOrgEx,1630 diff --git a/libc/nt/gdi32/GetDCPenColor.s b/libc/nt/gdi32/GetDCPenColor.s new file mode 100644 index 00000000..d6076f6b --- /dev/null +++ b/libc/nt/gdi32/GetDCPenColor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetDCPenColor,GetDCPenColor,1631 diff --git a/libc/nt/gdi32/GetDIBColorTable.s b/libc/nt/gdi32/GetDIBColorTable.s new file mode 100644 index 00000000..16c76319 --- /dev/null +++ b/libc/nt/gdi32/GetDIBColorTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetDIBColorTable,GetDIBColorTable,1632 diff --git a/libc/nt/gdi32/GetDIBits.s b/libc/nt/gdi32/GetDIBits.s new file mode 100644 index 00000000..d540387a --- /dev/null +++ b/libc/nt/gdi32/GetDIBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetDIBits,GetDIBits,1633 diff --git a/libc/nt/gdi32/GetDeviceCaps.s b/libc/nt/gdi32/GetDeviceCaps.s new file mode 100644 index 00000000..fd34aa00 --- /dev/null +++ b/libc/nt/gdi32/GetDeviceCaps.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetDeviceCaps,GetDeviceCaps,1634 diff --git a/libc/nt/gdi32/GetDeviceGammaRamp.s b/libc/nt/gdi32/GetDeviceGammaRamp.s new file mode 100644 index 00000000..a4a93429 --- /dev/null +++ b/libc/nt/gdi32/GetDeviceGammaRamp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetDeviceGammaRamp,GetDeviceGammaRamp,1635 diff --git a/libc/nt/gdi32/GetETM.s b/libc/nt/gdi32/GetETM.s new file mode 100644 index 00000000..4cf65646 --- /dev/null +++ b/libc/nt/gdi32/GetETM.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetETM,GetETM,1636 diff --git a/libc/nt/gdi32/GetEUDCTimeStamp.s b/libc/nt/gdi32/GetEUDCTimeStamp.s new file mode 100644 index 00000000..9c372634 --- /dev/null +++ b/libc/nt/gdi32/GetEUDCTimeStamp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetEUDCTimeStamp,GetEUDCTimeStamp,1637 diff --git a/libc/nt/gdi32/GetEUDCTimeStampExW.s b/libc/nt/gdi32/GetEUDCTimeStampExW.s new file mode 100644 index 00000000..d665dc7d --- /dev/null +++ b/libc/nt/gdi32/GetEUDCTimeStampExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetEUDCTimeStampExW,GetEUDCTimeStampExW,1638 diff --git a/libc/nt/gdi32/GetEnhMetaFileA.s b/libc/nt/gdi32/GetEnhMetaFileA.s new file mode 100644 index 00000000..080e13f7 --- /dev/null +++ b/libc/nt/gdi32/GetEnhMetaFileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetEnhMetaFileA,GetEnhMetaFileA,1639 diff --git a/libc/nt/gdi32/GetEnhMetaFileBits.s b/libc/nt/gdi32/GetEnhMetaFileBits.s new file mode 100644 index 00000000..d62ae486 --- /dev/null +++ b/libc/nt/gdi32/GetEnhMetaFileBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetEnhMetaFileBits,GetEnhMetaFileBits,1640 diff --git a/libc/nt/gdi32/GetEnhMetaFileDescriptionA.s b/libc/nt/gdi32/GetEnhMetaFileDescriptionA.s new file mode 100644 index 00000000..4fcf0a19 --- /dev/null +++ b/libc/nt/gdi32/GetEnhMetaFileDescriptionA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetEnhMetaFileDescriptionA,GetEnhMetaFileDescriptionA,1641 diff --git a/libc/nt/gdi32/GetEnhMetaFileDescriptionW.s b/libc/nt/gdi32/GetEnhMetaFileDescriptionW.s new file mode 100644 index 00000000..425424fb --- /dev/null +++ b/libc/nt/gdi32/GetEnhMetaFileDescriptionW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetEnhMetaFileDescriptionW,GetEnhMetaFileDescriptionW,1642 diff --git a/libc/nt/gdi32/GetEnhMetaFileHeader.s b/libc/nt/gdi32/GetEnhMetaFileHeader.s new file mode 100644 index 00000000..8d59d1bb --- /dev/null +++ b/libc/nt/gdi32/GetEnhMetaFileHeader.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetEnhMetaFileHeader,GetEnhMetaFileHeader,1643 diff --git a/libc/nt/gdi32/GetEnhMetaFilePaletteEntries.s b/libc/nt/gdi32/GetEnhMetaFilePaletteEntries.s new file mode 100644 index 00000000..655bfe89 --- /dev/null +++ b/libc/nt/gdi32/GetEnhMetaFilePaletteEntries.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetEnhMetaFilePaletteEntries,GetEnhMetaFilePaletteEntries,1644 diff --git a/libc/nt/gdi32/GetEnhMetaFilePixelFormat.s b/libc/nt/gdi32/GetEnhMetaFilePixelFormat.s new file mode 100644 index 00000000..c996d966 --- /dev/null +++ b/libc/nt/gdi32/GetEnhMetaFilePixelFormat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetEnhMetaFilePixelFormat,GetEnhMetaFilePixelFormat,1645 diff --git a/libc/nt/gdi32/GetEnhMetaFileW.s b/libc/nt/gdi32/GetEnhMetaFileW.s new file mode 100644 index 00000000..245f1079 --- /dev/null +++ b/libc/nt/gdi32/GetEnhMetaFileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetEnhMetaFileW,GetEnhMetaFileW,1646 diff --git a/libc/nt/gdi32/GetFontAssocStatus.s b/libc/nt/gdi32/GetFontAssocStatus.s new file mode 100644 index 00000000..d753e471 --- /dev/null +++ b/libc/nt/gdi32/GetFontAssocStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetFontAssocStatus,GetFontAssocStatus,1647 diff --git a/libc/nt/gdi32/GetFontData.s b/libc/nt/gdi32/GetFontData.s new file mode 100644 index 00000000..94f53f1b --- /dev/null +++ b/libc/nt/gdi32/GetFontData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetFontData,GetFontData,1648 diff --git a/libc/nt/gdi32/GetFontFileData.s b/libc/nt/gdi32/GetFontFileData.s new file mode 100644 index 00000000..f0fa5a3e --- /dev/null +++ b/libc/nt/gdi32/GetFontFileData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetFontFileData,GetFontFileData,1649 diff --git a/libc/nt/gdi32/GetFontFileInfo.s b/libc/nt/gdi32/GetFontFileInfo.s new file mode 100644 index 00000000..f2f4d90d --- /dev/null +++ b/libc/nt/gdi32/GetFontFileInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetFontFileInfo,GetFontFileInfo,1650 diff --git a/libc/nt/gdi32/GetFontLanguageInfo.s b/libc/nt/gdi32/GetFontLanguageInfo.s new file mode 100644 index 00000000..24a3c23f --- /dev/null +++ b/libc/nt/gdi32/GetFontLanguageInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetFontLanguageInfo,GetFontLanguageInfo,1651 diff --git a/libc/nt/gdi32/GetFontRealizationInfo.s b/libc/nt/gdi32/GetFontRealizationInfo.s new file mode 100644 index 00000000..6c431ad9 --- /dev/null +++ b/libc/nt/gdi32/GetFontRealizationInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetFontRealizationInfo,GetFontRealizationInfo,1652 diff --git a/libc/nt/gdi32/GetFontResourceInfoW.s b/libc/nt/gdi32/GetFontResourceInfoW.s new file mode 100644 index 00000000..09574e51 --- /dev/null +++ b/libc/nt/gdi32/GetFontResourceInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetFontResourceInfoW,GetFontResourceInfoW,1653 diff --git a/libc/nt/gdi32/GetFontUnicodeRanges.s b/libc/nt/gdi32/GetFontUnicodeRanges.s new file mode 100644 index 00000000..49536615 --- /dev/null +++ b/libc/nt/gdi32/GetFontUnicodeRanges.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetFontUnicodeRanges,GetFontUnicodeRanges,1654 diff --git a/libc/nt/gdi32/GetGlyphIndicesA.s b/libc/nt/gdi32/GetGlyphIndicesA.s new file mode 100644 index 00000000..ae8c5947 --- /dev/null +++ b/libc/nt/gdi32/GetGlyphIndicesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetGlyphIndicesA,GetGlyphIndicesA,1655 diff --git a/libc/nt/gdi32/GetGlyphIndicesW.s b/libc/nt/gdi32/GetGlyphIndicesW.s new file mode 100644 index 00000000..9e4b26d5 --- /dev/null +++ b/libc/nt/gdi32/GetGlyphIndicesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetGlyphIndicesW,GetGlyphIndicesW,1656 diff --git a/libc/nt/gdi32/GetGlyphOutlineA.s b/libc/nt/gdi32/GetGlyphOutlineA.s new file mode 100644 index 00000000..bc507d40 --- /dev/null +++ b/libc/nt/gdi32/GetGlyphOutlineA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetGlyphOutlineA,GetGlyphOutlineA,1658 diff --git a/libc/nt/gdi32/GetGlyphOutlineW.s b/libc/nt/gdi32/GetGlyphOutlineW.s new file mode 100644 index 00000000..ada3a56e --- /dev/null +++ b/libc/nt/gdi32/GetGlyphOutlineW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetGlyphOutlineW,GetGlyphOutlineW,1659 diff --git a/libc/nt/gdi32/GetGlyphOutlineWow.s b/libc/nt/gdi32/GetGlyphOutlineWow.s new file mode 100644 index 00000000..3cbf2cd4 --- /dev/null +++ b/libc/nt/gdi32/GetGlyphOutlineWow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetGlyphOutlineWow,GetGlyphOutlineWow,1660 diff --git a/libc/nt/gdi32/GetGraphicsMode.s b/libc/nt/gdi32/GetGraphicsMode.s new file mode 100644 index 00000000..c722d1cd --- /dev/null +++ b/libc/nt/gdi32/GetGraphicsMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetGraphicsMode,GetGraphicsMode,1661 diff --git a/libc/nt/gdi32/GetHFONT.s b/libc/nt/gdi32/GetHFONT.s new file mode 100644 index 00000000..b5d3a96a --- /dev/null +++ b/libc/nt/gdi32/GetHFONT.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetHFONT,GetHFONT,1662 diff --git a/libc/nt/gdi32/GetICMProfileA.s b/libc/nt/gdi32/GetICMProfileA.s new file mode 100644 index 00000000..0957a063 --- /dev/null +++ b/libc/nt/gdi32/GetICMProfileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetICMProfileA,GetICMProfileA,1663 diff --git a/libc/nt/gdi32/GetICMProfileW.s b/libc/nt/gdi32/GetICMProfileW.s new file mode 100644 index 00000000..1ee5c30d --- /dev/null +++ b/libc/nt/gdi32/GetICMProfileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetICMProfileW,GetICMProfileW,1664 diff --git a/libc/nt/gdi32/GetKerningPairsA.s b/libc/nt/gdi32/GetKerningPairsA.s new file mode 100644 index 00000000..a29f534f --- /dev/null +++ b/libc/nt/gdi32/GetKerningPairsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetKerningPairsA,GetKerningPairsA,1666 diff --git a/libc/nt/gdi32/GetKerningPairsW.s b/libc/nt/gdi32/GetKerningPairsW.s new file mode 100644 index 00000000..80aeb30b --- /dev/null +++ b/libc/nt/gdi32/GetKerningPairsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetKerningPairsW,GetKerningPairsW,1667 diff --git a/libc/nt/gdi32/GetLayout.s b/libc/nt/gdi32/GetLayout.s new file mode 100644 index 00000000..3c6a4e33 --- /dev/null +++ b/libc/nt/gdi32/GetLayout.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetLayout,GetLayout,1668 diff --git a/libc/nt/gdi32/GetLogColorSpaceA.s b/libc/nt/gdi32/GetLogColorSpaceA.s new file mode 100644 index 00000000..90357f02 --- /dev/null +++ b/libc/nt/gdi32/GetLogColorSpaceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetLogColorSpaceA,GetLogColorSpaceA,1669 diff --git a/libc/nt/gdi32/GetLogColorSpaceW.s b/libc/nt/gdi32/GetLogColorSpaceW.s new file mode 100644 index 00000000..053c9487 --- /dev/null +++ b/libc/nt/gdi32/GetLogColorSpaceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetLogColorSpaceW,GetLogColorSpaceW,1670 diff --git a/libc/nt/gdi32/GetMapMode.s b/libc/nt/gdi32/GetMapMode.s new file mode 100644 index 00000000..914202c2 --- /dev/null +++ b/libc/nt/gdi32/GetMapMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetMapMode,GetMapMode,1671 diff --git a/libc/nt/gdi32/GetMetaFileA.s b/libc/nt/gdi32/GetMetaFileA.s new file mode 100644 index 00000000..55d9bc83 --- /dev/null +++ b/libc/nt/gdi32/GetMetaFileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetMetaFileA,GetMetaFileA,1672 diff --git a/libc/nt/gdi32/GetMetaFileBitsEx.s b/libc/nt/gdi32/GetMetaFileBitsEx.s new file mode 100644 index 00000000..4f14ac60 --- /dev/null +++ b/libc/nt/gdi32/GetMetaFileBitsEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetMetaFileBitsEx,GetMetaFileBitsEx,1673 diff --git a/libc/nt/gdi32/GetMetaFileW.s b/libc/nt/gdi32/GetMetaFileW.s new file mode 100644 index 00000000..3bb258c6 --- /dev/null +++ b/libc/nt/gdi32/GetMetaFileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetMetaFileW,GetMetaFileW,1674 diff --git a/libc/nt/gdi32/GetMetaRgn.s b/libc/nt/gdi32/GetMetaRgn.s new file mode 100644 index 00000000..293993ef --- /dev/null +++ b/libc/nt/gdi32/GetMetaRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetMetaRgn,GetMetaRgn,1675 diff --git a/libc/nt/gdi32/GetMiterLimit.s b/libc/nt/gdi32/GetMiterLimit.s new file mode 100644 index 00000000..6be7d16c --- /dev/null +++ b/libc/nt/gdi32/GetMiterLimit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetMiterLimit,GetMiterLimit,1676 diff --git a/libc/nt/gdi32/GetNearestColor.s b/libc/nt/gdi32/GetNearestColor.s new file mode 100644 index 00000000..50ba0958 --- /dev/null +++ b/libc/nt/gdi32/GetNearestColor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetNearestColor,GetNearestColor,1677 diff --git a/libc/nt/gdi32/GetNearestPaletteIndex.s b/libc/nt/gdi32/GetNearestPaletteIndex.s new file mode 100644 index 00000000..45697435 --- /dev/null +++ b/libc/nt/gdi32/GetNearestPaletteIndex.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetNearestPaletteIndex,GetNearestPaletteIndex,1678 diff --git a/libc/nt/gdi32/GetNumberOfPhysicalMonitors.s b/libc/nt/gdi32/GetNumberOfPhysicalMonitors.s new file mode 100644 index 00000000..068362ca --- /dev/null +++ b/libc/nt/gdi32/GetNumberOfPhysicalMonitors.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetNumberOfPhysicalMonitors,GetNumberOfPhysicalMonitors,1679 diff --git a/libc/nt/gdi32/GetOPMInformation.s b/libc/nt/gdi32/GetOPMInformation.s new file mode 100644 index 00000000..fa58b363 --- /dev/null +++ b/libc/nt/gdi32/GetOPMInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetOPMInformation,GetOPMInformation,1680 diff --git a/libc/nt/gdi32/GetOPMRandomNumber.s b/libc/nt/gdi32/GetOPMRandomNumber.s new file mode 100644 index 00000000..1018c614 --- /dev/null +++ b/libc/nt/gdi32/GetOPMRandomNumber.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetOPMRandomNumber,GetOPMRandomNumber,1681 diff --git a/libc/nt/gdi32/GetObjectA.s b/libc/nt/gdi32/GetObjectA.s new file mode 100644 index 00000000..97b25f98 --- /dev/null +++ b/libc/nt/gdi32/GetObjectA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetObjectA,GetObjectA,1682 diff --git a/libc/nt/gdi32/GetObjectType.s b/libc/nt/gdi32/GetObjectType.s new file mode 100644 index 00000000..5fb7f513 --- /dev/null +++ b/libc/nt/gdi32/GetObjectType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetObjectType,GetObjectType,1683 diff --git a/libc/nt/gdi32/GetObjectW.s b/libc/nt/gdi32/GetObjectW.s new file mode 100644 index 00000000..2ef46176 --- /dev/null +++ b/libc/nt/gdi32/GetObjectW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetObjectW,GetObjectW,1684 diff --git a/libc/nt/gdi32/GetOutlineTextMetricsA.s b/libc/nt/gdi32/GetOutlineTextMetricsA.s new file mode 100644 index 00000000..b77041fe --- /dev/null +++ b/libc/nt/gdi32/GetOutlineTextMetricsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetOutlineTextMetricsA,GetOutlineTextMetricsA,1685 diff --git a/libc/nt/gdi32/GetOutlineTextMetricsW.s b/libc/nt/gdi32/GetOutlineTextMetricsW.s new file mode 100644 index 00000000..82a0905e --- /dev/null +++ b/libc/nt/gdi32/GetOutlineTextMetricsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetOutlineTextMetricsW,GetOutlineTextMetricsW,1686 diff --git a/libc/nt/gdi32/GetPaletteEntries.s b/libc/nt/gdi32/GetPaletteEntries.s new file mode 100644 index 00000000..2cd6c5b5 --- /dev/null +++ b/libc/nt/gdi32/GetPaletteEntries.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetPaletteEntries,GetPaletteEntries,1687 diff --git a/libc/nt/gdi32/GetPath.s b/libc/nt/gdi32/GetPath.s new file mode 100644 index 00000000..f38152de --- /dev/null +++ b/libc/nt/gdi32/GetPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetPath,GetPath,1688 diff --git a/libc/nt/gdi32/GetPhysicalMonitorDescription.s b/libc/nt/gdi32/GetPhysicalMonitorDescription.s new file mode 100644 index 00000000..95836975 --- /dev/null +++ b/libc/nt/gdi32/GetPhysicalMonitorDescription.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetPhysicalMonitorDescription,GetPhysicalMonitorDescription,1689 diff --git a/libc/nt/gdi32/GetPhysicalMonitors.s b/libc/nt/gdi32/GetPhysicalMonitors.s new file mode 100644 index 00000000..dcc61cd4 --- /dev/null +++ b/libc/nt/gdi32/GetPhysicalMonitors.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetPhysicalMonitors,GetPhysicalMonitors,1690 diff --git a/libc/nt/gdi32/GetPixel.s b/libc/nt/gdi32/GetPixel.s new file mode 100644 index 00000000..d3f31eb2 --- /dev/null +++ b/libc/nt/gdi32/GetPixel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetPixel,GetPixel,1691 diff --git a/libc/nt/gdi32/GetPixelFormat.s b/libc/nt/gdi32/GetPixelFormat.s new file mode 100644 index 00000000..d9312257 --- /dev/null +++ b/libc/nt/gdi32/GetPixelFormat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetPixelFormat,GetPixelFormat,1692 diff --git a/libc/nt/gdi32/GetPolyFillMode.s b/libc/nt/gdi32/GetPolyFillMode.s new file mode 100644 index 00000000..34116ae5 --- /dev/null +++ b/libc/nt/gdi32/GetPolyFillMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetPolyFillMode,GetPolyFillMode,1693 diff --git a/libc/nt/gdi32/GetProcessSessionFonts.s b/libc/nt/gdi32/GetProcessSessionFonts.s new file mode 100644 index 00000000..dc792a9a --- /dev/null +++ b/libc/nt/gdi32/GetProcessSessionFonts.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetProcessSessionFonts,GetProcessSessionFonts,1694 diff --git a/libc/nt/gdi32/GetROP2.s b/libc/nt/gdi32/GetROP2.s new file mode 100644 index 00000000..8912002d --- /dev/null +++ b/libc/nt/gdi32/GetROP2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetROP2,GetROP2,1695 diff --git a/libc/nt/gdi32/GetRandomRgn.s b/libc/nt/gdi32/GetRandomRgn.s new file mode 100644 index 00000000..c0363363 --- /dev/null +++ b/libc/nt/gdi32/GetRandomRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetRandomRgn,GetRandomRgn,1696 diff --git a/libc/nt/gdi32/GetRasterizerCaps.s b/libc/nt/gdi32/GetRasterizerCaps.s new file mode 100644 index 00000000..75396940 --- /dev/null +++ b/libc/nt/gdi32/GetRasterizerCaps.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetRasterizerCaps,GetRasterizerCaps,1697 diff --git a/libc/nt/gdi32/GetRegionData.s b/libc/nt/gdi32/GetRegionData.s new file mode 100644 index 00000000..51ace568 --- /dev/null +++ b/libc/nt/gdi32/GetRegionData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetRegionData,GetRegionData,1698 diff --git a/libc/nt/gdi32/GetRelAbs.s b/libc/nt/gdi32/GetRelAbs.s new file mode 100644 index 00000000..7dfd8ec9 --- /dev/null +++ b/libc/nt/gdi32/GetRelAbs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetRelAbs,GetRelAbs,1699 diff --git a/libc/nt/gdi32/GetRgnBox.s b/libc/nt/gdi32/GetRgnBox.s new file mode 100644 index 00000000..1f2da83d --- /dev/null +++ b/libc/nt/gdi32/GetRgnBox.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetRgnBox,GetRgnBox,1700 diff --git a/libc/nt/gdi32/GetStockObject.s b/libc/nt/gdi32/GetStockObject.s new file mode 100644 index 00000000..356129a1 --- /dev/null +++ b/libc/nt/gdi32/GetStockObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetStockObject,GetStockObject,1701 diff --git a/libc/nt/gdi32/GetStretchBltMode.s b/libc/nt/gdi32/GetStretchBltMode.s new file mode 100644 index 00000000..7e4858e6 --- /dev/null +++ b/libc/nt/gdi32/GetStretchBltMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetStretchBltMode,GetStretchBltMode,1702 diff --git a/libc/nt/gdi32/GetStringBitmapA.s b/libc/nt/gdi32/GetStringBitmapA.s new file mode 100644 index 00000000..78f4c429 --- /dev/null +++ b/libc/nt/gdi32/GetStringBitmapA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetStringBitmapA,GetStringBitmapA,1703 diff --git a/libc/nt/gdi32/GetStringBitmapW.s b/libc/nt/gdi32/GetStringBitmapW.s new file mode 100644 index 00000000..9da88776 --- /dev/null +++ b/libc/nt/gdi32/GetStringBitmapW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetStringBitmapW,GetStringBitmapW,1704 diff --git a/libc/nt/gdi32/GetSuggestedOPMProtectedOutputArraySize.s b/libc/nt/gdi32/GetSuggestedOPMProtectedOutputArraySize.s new file mode 100644 index 00000000..f05821ef --- /dev/null +++ b/libc/nt/gdi32/GetSuggestedOPMProtectedOutputArraySize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetSuggestedOPMProtectedOutputArraySize,GetSuggestedOPMProtectedOutputArraySize,1705 diff --git a/libc/nt/gdi32/GetSystemPaletteEntries.s b/libc/nt/gdi32/GetSystemPaletteEntries.s new file mode 100644 index 00000000..4c66425a --- /dev/null +++ b/libc/nt/gdi32/GetSystemPaletteEntries.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetSystemPaletteEntries,GetSystemPaletteEntries,1706 diff --git a/libc/nt/gdi32/GetSystemPaletteUse.s b/libc/nt/gdi32/GetSystemPaletteUse.s new file mode 100644 index 00000000..f3a3b456 --- /dev/null +++ b/libc/nt/gdi32/GetSystemPaletteUse.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetSystemPaletteUse,GetSystemPaletteUse,1707 diff --git a/libc/nt/gdi32/GetTextAlign.s b/libc/nt/gdi32/GetTextAlign.s new file mode 100644 index 00000000..5ff60d27 --- /dev/null +++ b/libc/nt/gdi32/GetTextAlign.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextAlign,GetTextAlign,1708 diff --git a/libc/nt/gdi32/GetTextCharacterExtra.s b/libc/nt/gdi32/GetTextCharacterExtra.s new file mode 100644 index 00000000..4271bf70 --- /dev/null +++ b/libc/nt/gdi32/GetTextCharacterExtra.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextCharacterExtra,GetTextCharacterExtra,1709 diff --git a/libc/nt/gdi32/GetTextCharset.s b/libc/nt/gdi32/GetTextCharset.s new file mode 100644 index 00000000..f8c2cadd --- /dev/null +++ b/libc/nt/gdi32/GetTextCharset.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextCharset,GetTextCharset,1710 diff --git a/libc/nt/gdi32/GetTextCharsetInfo.s b/libc/nt/gdi32/GetTextCharsetInfo.s new file mode 100644 index 00000000..1cd359e6 --- /dev/null +++ b/libc/nt/gdi32/GetTextCharsetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextCharsetInfo,GetTextCharsetInfo,1711 diff --git a/libc/nt/gdi32/GetTextColor.s b/libc/nt/gdi32/GetTextColor.s new file mode 100644 index 00000000..1ed6d7e2 --- /dev/null +++ b/libc/nt/gdi32/GetTextColor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextColor,GetTextColor,1712 diff --git a/libc/nt/gdi32/GetTextExtentExPointA.s b/libc/nt/gdi32/GetTextExtentExPointA.s new file mode 100644 index 00000000..16322547 --- /dev/null +++ b/libc/nt/gdi32/GetTextExtentExPointA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextExtentExPointA,GetTextExtentExPointA,1713 diff --git a/libc/nt/gdi32/GetTextExtentExPointI.s b/libc/nt/gdi32/GetTextExtentExPointI.s new file mode 100644 index 00000000..6859ef7d --- /dev/null +++ b/libc/nt/gdi32/GetTextExtentExPointI.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextExtentExPointI,GetTextExtentExPointI,1714 diff --git a/libc/nt/gdi32/GetTextExtentExPointW.s b/libc/nt/gdi32/GetTextExtentExPointW.s new file mode 100644 index 00000000..d337881e --- /dev/null +++ b/libc/nt/gdi32/GetTextExtentExPointW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextExtentExPointW,GetTextExtentExPointW,1715 diff --git a/libc/nt/gdi32/GetTextExtentExPointWPri.s b/libc/nt/gdi32/GetTextExtentExPointWPri.s new file mode 100644 index 00000000..5125ecfd --- /dev/null +++ b/libc/nt/gdi32/GetTextExtentExPointWPri.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextExtentExPointWPri,GetTextExtentExPointWPri,1716 diff --git a/libc/nt/gdi32/GetTextExtentPoint32A.s b/libc/nt/gdi32/GetTextExtentPoint32A.s new file mode 100644 index 00000000..4bfcfb9c --- /dev/null +++ b/libc/nt/gdi32/GetTextExtentPoint32A.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextExtentPoint32A,GetTextExtentPoint32A,1717 diff --git a/libc/nt/gdi32/GetTextExtentPoint32W.s b/libc/nt/gdi32/GetTextExtentPoint32W.s new file mode 100644 index 00000000..03b4d2a0 --- /dev/null +++ b/libc/nt/gdi32/GetTextExtentPoint32W.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextExtentPoint32W,GetTextExtentPoint32W,1718 diff --git a/libc/nt/gdi32/GetTextExtentPointA.s b/libc/nt/gdi32/GetTextExtentPointA.s new file mode 100644 index 00000000..cf536c78 --- /dev/null +++ b/libc/nt/gdi32/GetTextExtentPointA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextExtentPointA,GetTextExtentPointA,1719 diff --git a/libc/nt/gdi32/GetTextExtentPointI.s b/libc/nt/gdi32/GetTextExtentPointI.s new file mode 100644 index 00000000..9e93a811 --- /dev/null +++ b/libc/nt/gdi32/GetTextExtentPointI.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextExtentPointI,GetTextExtentPointI,1720 diff --git a/libc/nt/gdi32/GetTextExtentPointW.s b/libc/nt/gdi32/GetTextExtentPointW.s new file mode 100644 index 00000000..577c231a --- /dev/null +++ b/libc/nt/gdi32/GetTextExtentPointW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextExtentPointW,GetTextExtentPointW,1721 diff --git a/libc/nt/gdi32/GetTextFaceA.s b/libc/nt/gdi32/GetTextFaceA.s new file mode 100644 index 00000000..84403689 --- /dev/null +++ b/libc/nt/gdi32/GetTextFaceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextFaceA,GetTextFaceA,1722 diff --git a/libc/nt/gdi32/GetTextFaceAliasW.s b/libc/nt/gdi32/GetTextFaceAliasW.s new file mode 100644 index 00000000..7e2fb85e --- /dev/null +++ b/libc/nt/gdi32/GetTextFaceAliasW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextFaceAliasW,GetTextFaceAliasW,1723 diff --git a/libc/nt/gdi32/GetTextFaceW.s b/libc/nt/gdi32/GetTextFaceW.s new file mode 100644 index 00000000..4fd50062 --- /dev/null +++ b/libc/nt/gdi32/GetTextFaceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextFaceW,GetTextFaceW,1724 diff --git a/libc/nt/gdi32/GetTextMetricsA.s b/libc/nt/gdi32/GetTextMetricsA.s new file mode 100644 index 00000000..2b0fcca1 --- /dev/null +++ b/libc/nt/gdi32/GetTextMetricsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextMetricsA,GetTextMetricsA,1725 diff --git a/libc/nt/gdi32/GetTextMetricsW.s b/libc/nt/gdi32/GetTextMetricsW.s new file mode 100644 index 00000000..05f98f0c --- /dev/null +++ b/libc/nt/gdi32/GetTextMetricsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTextMetricsW,GetTextMetricsW,1726 diff --git a/libc/nt/gdi32/GetTransform.s b/libc/nt/gdi32/GetTransform.s new file mode 100644 index 00000000..1e470ab0 --- /dev/null +++ b/libc/nt/gdi32/GetTransform.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetTransform,GetTransform,1727 diff --git a/libc/nt/gdi32/GetViewportExtEx.s b/libc/nt/gdi32/GetViewportExtEx.s new file mode 100644 index 00000000..272fda4a --- /dev/null +++ b/libc/nt/gdi32/GetViewportExtEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetViewportExtEx,GetViewportExtEx,1728 diff --git a/libc/nt/gdi32/GetViewportOrgEx.s b/libc/nt/gdi32/GetViewportOrgEx.s new file mode 100644 index 00000000..891375b0 --- /dev/null +++ b/libc/nt/gdi32/GetViewportOrgEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetViewportOrgEx,GetViewportOrgEx,1729 diff --git a/libc/nt/gdi32/GetWinMetaFileBits.s b/libc/nt/gdi32/GetWinMetaFileBits.s new file mode 100644 index 00000000..c7d1ebeb --- /dev/null +++ b/libc/nt/gdi32/GetWinMetaFileBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetWinMetaFileBits,GetWinMetaFileBits,1730 diff --git a/libc/nt/gdi32/GetWindowExtEx.s b/libc/nt/gdi32/GetWindowExtEx.s new file mode 100644 index 00000000..25d6f63c --- /dev/null +++ b/libc/nt/gdi32/GetWindowExtEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetWindowExtEx,GetWindowExtEx,1731 diff --git a/libc/nt/gdi32/GetWindowOrgEx.s b/libc/nt/gdi32/GetWindowOrgEx.s new file mode 100644 index 00000000..a090ce9c --- /dev/null +++ b/libc/nt/gdi32/GetWindowOrgEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetWindowOrgEx,GetWindowOrgEx,1732 diff --git a/libc/nt/gdi32/GetWorldTransform.s b/libc/nt/gdi32/GetWorldTransform.s new file mode 100644 index 00000000..0c389a4c --- /dev/null +++ b/libc/nt/gdi32/GetWorldTransform.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_GetWorldTransform,GetWorldTransform,1733 diff --git a/libc/nt/gdi32/HT_Get8BPPFormatPalette.s b/libc/nt/gdi32/HT_Get8BPPFormatPalette.s new file mode 100644 index 00000000..c64075e3 --- /dev/null +++ b/libc/nt/gdi32/HT_Get8BPPFormatPalette.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_HT_Get8BPPFormatPalette,HT_Get8BPPFormatPalette,1734 diff --git a/libc/nt/gdi32/HT_Get8BPPMaskPalette.s b/libc/nt/gdi32/HT_Get8BPPMaskPalette.s new file mode 100644 index 00000000..943dc9db --- /dev/null +++ b/libc/nt/gdi32/HT_Get8BPPMaskPalette.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_HT_Get8BPPMaskPalette,HT_Get8BPPMaskPalette,1735 diff --git a/libc/nt/gdi32/InternalDeleteDC.s b/libc/nt/gdi32/InternalDeleteDC.s new file mode 100644 index 00000000..2953f41e --- /dev/null +++ b/libc/nt/gdi32/InternalDeleteDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_InternalDeleteDC,InternalDeleteDC,1736 diff --git a/libc/nt/gdi32/IntersectClipRect.s b/libc/nt/gdi32/IntersectClipRect.s new file mode 100644 index 00000000..916fa74e --- /dev/null +++ b/libc/nt/gdi32/IntersectClipRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_IntersectClipRect,IntersectClipRect,1737 diff --git a/libc/nt/gdi32/InvertRgn.s b/libc/nt/gdi32/InvertRgn.s new file mode 100644 index 00000000..bfc88d83 --- /dev/null +++ b/libc/nt/gdi32/InvertRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_InvertRgn,InvertRgn,1738 diff --git a/libc/nt/gdi32/IsValidEnhMetaRecord.s b/libc/nt/gdi32/IsValidEnhMetaRecord.s new file mode 100644 index 00000000..03d7b55e --- /dev/null +++ b/libc/nt/gdi32/IsValidEnhMetaRecord.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_IsValidEnhMetaRecord,IsValidEnhMetaRecord,1739 diff --git a/libc/nt/gdi32/IsValidEnhMetaRecordOffExt.s b/libc/nt/gdi32/IsValidEnhMetaRecordOffExt.s new file mode 100644 index 00000000..74c27d0d --- /dev/null +++ b/libc/nt/gdi32/IsValidEnhMetaRecordOffExt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_IsValidEnhMetaRecordOffExt,IsValidEnhMetaRecordOffExt,1740 diff --git a/libc/nt/gdi32/LPtoDP.s b/libc/nt/gdi32/LPtoDP.s new file mode 100644 index 00000000..a5568d51 --- /dev/null +++ b/libc/nt/gdi32/LPtoDP.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_LPtoDP,LPtoDP,1741 diff --git a/libc/nt/gdi32/LineDDA.s b/libc/nt/gdi32/LineDDA.s new file mode 100644 index 00000000..e598289c --- /dev/null +++ b/libc/nt/gdi32/LineDDA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_LineDDA,LineDDA,1742 diff --git a/libc/nt/gdi32/LineTo.s b/libc/nt/gdi32/LineTo.s new file mode 100644 index 00000000..3443195d --- /dev/null +++ b/libc/nt/gdi32/LineTo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_LineTo,LineTo,1743 diff --git a/libc/nt/gdi32/LpkEditControl.s b/libc/nt/gdi32/LpkEditControl.s new file mode 100644 index 00000000..2ebc9a62 --- /dev/null +++ b/libc/nt/gdi32/LpkEditControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_LpkEditControl,LpkEditControl,1745 diff --git a/libc/nt/gdi32/LpkGetEditControl.s b/libc/nt/gdi32/LpkGetEditControl.s new file mode 100644 index 00000000..c78e7420 --- /dev/null +++ b/libc/nt/gdi32/LpkGetEditControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_LpkGetEditControl,LpkGetEditControl,1748 diff --git a/libc/nt/gdi32/LpkpEditControlSize.s b/libc/nt/gdi32/LpkpEditControlSize.s new file mode 100644 index 00000000..f45ac4de --- /dev/null +++ b/libc/nt/gdi32/LpkpEditControlSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_LpkpEditControlSize,LpkpEditControlSize,1755 diff --git a/libc/nt/gdi32/LpkpInitializeEditControl.s b/libc/nt/gdi32/LpkpInitializeEditControl.s new file mode 100644 index 00000000..de5c411e --- /dev/null +++ b/libc/nt/gdi32/LpkpInitializeEditControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_LpkpInitializeEditControl,LpkpInitializeEditControl,1756 diff --git a/libc/nt/gdi32/MaskBlt.s b/libc/nt/gdi32/MaskBlt.s new file mode 100644 index 00000000..5ce6666e --- /dev/null +++ b/libc/nt/gdi32/MaskBlt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_MaskBlt,MaskBlt,1757 diff --git a/libc/nt/gdi32/MirrorRgn.s b/libc/nt/gdi32/MirrorRgn.s new file mode 100644 index 00000000..df2cb0dc --- /dev/null +++ b/libc/nt/gdi32/MirrorRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_MirrorRgn,MirrorRgn,1758 diff --git a/libc/nt/gdi32/ModerncoreGdiInit.s b/libc/nt/gdi32/ModerncoreGdiInit.s new file mode 100644 index 00000000..e467e3ff --- /dev/null +++ b/libc/nt/gdi32/ModerncoreGdiInit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ModerncoreGdiInit,ModerncoreGdiInit,1759 diff --git a/libc/nt/gdi32/ModifyWorldTransform.s b/libc/nt/gdi32/ModifyWorldTransform.s new file mode 100644 index 00000000..83176e87 --- /dev/null +++ b/libc/nt/gdi32/ModifyWorldTransform.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ModifyWorldTransform,ModifyWorldTransform,1760 diff --git a/libc/nt/gdi32/MoveToEx.s b/libc/nt/gdi32/MoveToEx.s new file mode 100644 index 00000000..32b5441d --- /dev/null +++ b/libc/nt/gdi32/MoveToEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_MoveToEx,MoveToEx,1761 diff --git a/libc/nt/gdi32/NamedEscape.s b/libc/nt/gdi32/NamedEscape.s new file mode 100644 index 00000000..0d70a43e --- /dev/null +++ b/libc/nt/gdi32/NamedEscape.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_NamedEscape,NamedEscape,1762 diff --git a/libc/nt/gdi32/OffsetClipRgn.s b/libc/nt/gdi32/OffsetClipRgn.s new file mode 100644 index 00000000..dc75ed7e --- /dev/null +++ b/libc/nt/gdi32/OffsetClipRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_OffsetClipRgn,OffsetClipRgn,1763 diff --git a/libc/nt/gdi32/OffsetRgn.s b/libc/nt/gdi32/OffsetRgn.s new file mode 100644 index 00000000..a8fdd343 --- /dev/null +++ b/libc/nt/gdi32/OffsetRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_OffsetRgn,OffsetRgn,1764 diff --git a/libc/nt/gdi32/OffsetViewportOrgEx.s b/libc/nt/gdi32/OffsetViewportOrgEx.s new file mode 100644 index 00000000..bf37bc40 --- /dev/null +++ b/libc/nt/gdi32/OffsetViewportOrgEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_OffsetViewportOrgEx,OffsetViewportOrgEx,1765 diff --git a/libc/nt/gdi32/OffsetWindowOrgEx.s b/libc/nt/gdi32/OffsetWindowOrgEx.s new file mode 100644 index 00000000..49ce552a --- /dev/null +++ b/libc/nt/gdi32/OffsetWindowOrgEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_OffsetWindowOrgEx,OffsetWindowOrgEx,1766 diff --git a/libc/nt/gdi32/PATHOBJ_bEnum.s b/libc/nt/gdi32/PATHOBJ_bEnum.s new file mode 100644 index 00000000..5e097fb4 --- /dev/null +++ b/libc/nt/gdi32/PATHOBJ_bEnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PATHOBJ_bEnum,PATHOBJ_bEnum,1767 diff --git a/libc/nt/gdi32/PATHOBJ_bEnumClipLines.s b/libc/nt/gdi32/PATHOBJ_bEnumClipLines.s new file mode 100644 index 00000000..9dfb61c3 --- /dev/null +++ b/libc/nt/gdi32/PATHOBJ_bEnumClipLines.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PATHOBJ_bEnumClipLines,PATHOBJ_bEnumClipLines,1768 diff --git a/libc/nt/gdi32/PATHOBJ_vEnumStart.s b/libc/nt/gdi32/PATHOBJ_vEnumStart.s new file mode 100644 index 00000000..af544f9a --- /dev/null +++ b/libc/nt/gdi32/PATHOBJ_vEnumStart.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PATHOBJ_vEnumStart,PATHOBJ_vEnumStart,1769 diff --git a/libc/nt/gdi32/PATHOBJ_vEnumStartClipLines.s b/libc/nt/gdi32/PATHOBJ_vEnumStartClipLines.s new file mode 100644 index 00000000..a297e935 --- /dev/null +++ b/libc/nt/gdi32/PATHOBJ_vEnumStartClipLines.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PATHOBJ_vEnumStartClipLines,PATHOBJ_vEnumStartClipLines,1770 diff --git a/libc/nt/gdi32/PATHOBJ_vGetBounds.s b/libc/nt/gdi32/PATHOBJ_vGetBounds.s new file mode 100644 index 00000000..3f9a6ed1 --- /dev/null +++ b/libc/nt/gdi32/PATHOBJ_vGetBounds.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PATHOBJ_vGetBounds,PATHOBJ_vGetBounds,1771 diff --git a/libc/nt/gdi32/PaintRgn.s b/libc/nt/gdi32/PaintRgn.s new file mode 100644 index 00000000..c6a15ec7 --- /dev/null +++ b/libc/nt/gdi32/PaintRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PaintRgn,PaintRgn,1772 diff --git a/libc/nt/gdi32/PatBlt.s b/libc/nt/gdi32/PatBlt.s new file mode 100644 index 00000000..24f5bfc3 --- /dev/null +++ b/libc/nt/gdi32/PatBlt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PatBlt,PatBlt,1773 diff --git a/libc/nt/gdi32/PathToRegion.s b/libc/nt/gdi32/PathToRegion.s new file mode 100644 index 00000000..ef035028 --- /dev/null +++ b/libc/nt/gdi32/PathToRegion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PathToRegion,PathToRegion,1774 diff --git a/libc/nt/gdi32/Pie.s b/libc/nt/gdi32/Pie.s new file mode 100644 index 00000000..37fe3eed --- /dev/null +++ b/libc/nt/gdi32/Pie.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_Pie,Pie,1775 diff --git a/libc/nt/gdi32/PlayEnhMetaFile.s b/libc/nt/gdi32/PlayEnhMetaFile.s new file mode 100644 index 00000000..178d935d --- /dev/null +++ b/libc/nt/gdi32/PlayEnhMetaFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PlayEnhMetaFile,PlayEnhMetaFile,1776 diff --git a/libc/nt/gdi32/PlayEnhMetaFileRecord.s b/libc/nt/gdi32/PlayEnhMetaFileRecord.s new file mode 100644 index 00000000..ac838821 --- /dev/null +++ b/libc/nt/gdi32/PlayEnhMetaFileRecord.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PlayEnhMetaFileRecord,PlayEnhMetaFileRecord,1777 diff --git a/libc/nt/gdi32/PlayMetaFile.s b/libc/nt/gdi32/PlayMetaFile.s new file mode 100644 index 00000000..f33f51b6 --- /dev/null +++ b/libc/nt/gdi32/PlayMetaFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PlayMetaFile,PlayMetaFile,1778 diff --git a/libc/nt/gdi32/PlayMetaFileRecord.s b/libc/nt/gdi32/PlayMetaFileRecord.s new file mode 100644 index 00000000..a6bb0c10 --- /dev/null +++ b/libc/nt/gdi32/PlayMetaFileRecord.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PlayMetaFileRecord,PlayMetaFileRecord,1779 diff --git a/libc/nt/gdi32/PlgBlt.s b/libc/nt/gdi32/PlgBlt.s new file mode 100644 index 00000000..82a1b4af --- /dev/null +++ b/libc/nt/gdi32/PlgBlt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PlgBlt,PlgBlt,1780 diff --git a/libc/nt/gdi32/PolyBezier.s b/libc/nt/gdi32/PolyBezier.s new file mode 100644 index 00000000..e651998f --- /dev/null +++ b/libc/nt/gdi32/PolyBezier.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PolyBezier,PolyBezier,1781 diff --git a/libc/nt/gdi32/PolyBezierTo.s b/libc/nt/gdi32/PolyBezierTo.s new file mode 100644 index 00000000..a87995e7 --- /dev/null +++ b/libc/nt/gdi32/PolyBezierTo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PolyBezierTo,PolyBezierTo,1782 diff --git a/libc/nt/gdi32/PolyDraw.s b/libc/nt/gdi32/PolyDraw.s new file mode 100644 index 00000000..040531e1 --- /dev/null +++ b/libc/nt/gdi32/PolyDraw.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PolyDraw,PolyDraw,1783 diff --git a/libc/nt/gdi32/PolyPatBlt.s b/libc/nt/gdi32/PolyPatBlt.s new file mode 100644 index 00000000..06d6491f --- /dev/null +++ b/libc/nt/gdi32/PolyPatBlt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PolyPatBlt,PolyPatBlt,1784 diff --git a/libc/nt/gdi32/PolyPolygon.s b/libc/nt/gdi32/PolyPolygon.s new file mode 100644 index 00000000..2804bc75 --- /dev/null +++ b/libc/nt/gdi32/PolyPolygon.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PolyPolygon,PolyPolygon,1785 diff --git a/libc/nt/gdi32/PolyPolyline.s b/libc/nt/gdi32/PolyPolyline.s new file mode 100644 index 00000000..81de7272 --- /dev/null +++ b/libc/nt/gdi32/PolyPolyline.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PolyPolyline,PolyPolyline,1786 diff --git a/libc/nt/gdi32/PolyTextOutA.s b/libc/nt/gdi32/PolyTextOutA.s new file mode 100644 index 00000000..65a98f52 --- /dev/null +++ b/libc/nt/gdi32/PolyTextOutA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PolyTextOutA,PolyTextOutA,1787 diff --git a/libc/nt/gdi32/PolyTextOutW.s b/libc/nt/gdi32/PolyTextOutW.s new file mode 100644 index 00000000..bee118ef --- /dev/null +++ b/libc/nt/gdi32/PolyTextOutW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PolyTextOutW,PolyTextOutW,1788 diff --git a/libc/nt/gdi32/Polygon.s b/libc/nt/gdi32/Polygon.s new file mode 100644 index 00000000..994d41af --- /dev/null +++ b/libc/nt/gdi32/Polygon.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_Polygon,Polygon,1789 diff --git a/libc/nt/gdi32/Polyline.s b/libc/nt/gdi32/Polyline.s new file mode 100644 index 00000000..829537fe --- /dev/null +++ b/libc/nt/gdi32/Polyline.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_Polyline,Polyline,1790 diff --git a/libc/nt/gdi32/PolylineTo.s b/libc/nt/gdi32/PolylineTo.s new file mode 100644 index 00000000..d9b4043f --- /dev/null +++ b/libc/nt/gdi32/PolylineTo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PolylineTo,PolylineTo,1791 diff --git a/libc/nt/gdi32/PtInRegion.s b/libc/nt/gdi32/PtInRegion.s new file mode 100644 index 00000000..0e114a7e --- /dev/null +++ b/libc/nt/gdi32/PtInRegion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PtInRegion,PtInRegion,1792 diff --git a/libc/nt/gdi32/PtVisible.s b/libc/nt/gdi32/PtVisible.s new file mode 100644 index 00000000..98523df2 --- /dev/null +++ b/libc/nt/gdi32/PtVisible.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_PtVisible,PtVisible,1793 diff --git a/libc/nt/gdi32/QueryFontAssocStatus.s b/libc/nt/gdi32/QueryFontAssocStatus.s new file mode 100644 index 00000000..f493e62b --- /dev/null +++ b/libc/nt/gdi32/QueryFontAssocStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_QueryFontAssocStatus,QueryFontAssocStatus,1794 diff --git a/libc/nt/gdi32/RealizePalette.s b/libc/nt/gdi32/RealizePalette.s new file mode 100644 index 00000000..4277d363 --- /dev/null +++ b/libc/nt/gdi32/RealizePalette.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_RealizePalette,RealizePalette,1795 diff --git a/libc/nt/gdi32/RectInRegion.s b/libc/nt/gdi32/RectInRegion.s new file mode 100644 index 00000000..34cce077 --- /dev/null +++ b/libc/nt/gdi32/RectInRegion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_RectInRegion,RectInRegion,1796 diff --git a/libc/nt/gdi32/RectVisible.s b/libc/nt/gdi32/RectVisible.s new file mode 100644 index 00000000..67bd007d --- /dev/null +++ b/libc/nt/gdi32/RectVisible.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_RectVisible,RectVisible,1797 diff --git a/libc/nt/gdi32/Rectangle.s b/libc/nt/gdi32/Rectangle.s new file mode 100644 index 00000000..a9e74944 --- /dev/null +++ b/libc/nt/gdi32/Rectangle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_Rectangle,Rectangle,1798 diff --git a/libc/nt/gdi32/RemoveFontMemResourceEx.s b/libc/nt/gdi32/RemoveFontMemResourceEx.s new file mode 100644 index 00000000..8a14ce88 --- /dev/null +++ b/libc/nt/gdi32/RemoveFontMemResourceEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_RemoveFontMemResourceEx,RemoveFontMemResourceEx,1799 diff --git a/libc/nt/gdi32/RemoveFontResourceA.s b/libc/nt/gdi32/RemoveFontResourceA.s new file mode 100644 index 00000000..48f46bb5 --- /dev/null +++ b/libc/nt/gdi32/RemoveFontResourceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_RemoveFontResourceA,RemoveFontResourceA,1800 diff --git a/libc/nt/gdi32/RemoveFontResourceExA.s b/libc/nt/gdi32/RemoveFontResourceExA.s new file mode 100644 index 00000000..4773bcb3 --- /dev/null +++ b/libc/nt/gdi32/RemoveFontResourceExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_RemoveFontResourceExA,RemoveFontResourceExA,1801 diff --git a/libc/nt/gdi32/RemoveFontResourceExW.s b/libc/nt/gdi32/RemoveFontResourceExW.s new file mode 100644 index 00000000..aea4cb98 --- /dev/null +++ b/libc/nt/gdi32/RemoveFontResourceExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_RemoveFontResourceExW,RemoveFontResourceExW,1802 diff --git a/libc/nt/gdi32/RemoveFontResourceTracking.s b/libc/nt/gdi32/RemoveFontResourceTracking.s new file mode 100644 index 00000000..d6ee868d --- /dev/null +++ b/libc/nt/gdi32/RemoveFontResourceTracking.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_RemoveFontResourceTracking,RemoveFontResourceTracking,1803 diff --git a/libc/nt/gdi32/RemoveFontResourceW.s b/libc/nt/gdi32/RemoveFontResourceW.s new file mode 100644 index 00000000..04da6bb8 --- /dev/null +++ b/libc/nt/gdi32/RemoveFontResourceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_RemoveFontResourceW,RemoveFontResourceW,1804 diff --git a/libc/nt/gdi32/ResetDCA.s b/libc/nt/gdi32/ResetDCA.s new file mode 100644 index 00000000..09a5ec7d --- /dev/null +++ b/libc/nt/gdi32/ResetDCA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ResetDCA,ResetDCA,1805 diff --git a/libc/nt/gdi32/ResetDCW.s b/libc/nt/gdi32/ResetDCW.s new file mode 100644 index 00000000..7e09acc0 --- /dev/null +++ b/libc/nt/gdi32/ResetDCW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ResetDCW,ResetDCW,1806 diff --git a/libc/nt/gdi32/ResizePalette.s b/libc/nt/gdi32/ResizePalette.s new file mode 100644 index 00000000..7aab05d8 --- /dev/null +++ b/libc/nt/gdi32/ResizePalette.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ResizePalette,ResizePalette,1807 diff --git a/libc/nt/gdi32/RestoreDC.s b/libc/nt/gdi32/RestoreDC.s new file mode 100644 index 00000000..eccf2195 --- /dev/null +++ b/libc/nt/gdi32/RestoreDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_RestoreDC,RestoreDC,1808 diff --git a/libc/nt/gdi32/RoundRect.s b/libc/nt/gdi32/RoundRect.s new file mode 100644 index 00000000..4868380b --- /dev/null +++ b/libc/nt/gdi32/RoundRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_RoundRect,RoundRect,1809 diff --git a/libc/nt/gdi32/STROBJ_bEnum.s b/libc/nt/gdi32/STROBJ_bEnum.s new file mode 100644 index 00000000..134954d2 --- /dev/null +++ b/libc/nt/gdi32/STROBJ_bEnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_STROBJ_bEnum,STROBJ_bEnum,1810 diff --git a/libc/nt/gdi32/STROBJ_bEnumPositionsOnly.s b/libc/nt/gdi32/STROBJ_bEnumPositionsOnly.s new file mode 100644 index 00000000..10d60d39 --- /dev/null +++ b/libc/nt/gdi32/STROBJ_bEnumPositionsOnly.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_STROBJ_bEnumPositionsOnly,STROBJ_bEnumPositionsOnly,1811 diff --git a/libc/nt/gdi32/STROBJ_bGetAdvanceWidths.s b/libc/nt/gdi32/STROBJ_bGetAdvanceWidths.s new file mode 100644 index 00000000..168bd2fa --- /dev/null +++ b/libc/nt/gdi32/STROBJ_bGetAdvanceWidths.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_STROBJ_bGetAdvanceWidths,STROBJ_bGetAdvanceWidths,1812 diff --git a/libc/nt/gdi32/STROBJ_dwGetCodePage.s b/libc/nt/gdi32/STROBJ_dwGetCodePage.s new file mode 100644 index 00000000..0816c316 --- /dev/null +++ b/libc/nt/gdi32/STROBJ_dwGetCodePage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_STROBJ_dwGetCodePage,STROBJ_dwGetCodePage,1813 diff --git a/libc/nt/gdi32/STROBJ_vEnumStart.s b/libc/nt/gdi32/STROBJ_vEnumStart.s new file mode 100644 index 00000000..5bafd2eb --- /dev/null +++ b/libc/nt/gdi32/STROBJ_vEnumStart.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_STROBJ_vEnumStart,STROBJ_vEnumStart,1814 diff --git a/libc/nt/gdi32/SaveDC.s b/libc/nt/gdi32/SaveDC.s new file mode 100644 index 00000000..469efbab --- /dev/null +++ b/libc/nt/gdi32/SaveDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SaveDC,SaveDC,1815 diff --git a/libc/nt/gdi32/ScaleRgn.s b/libc/nt/gdi32/ScaleRgn.s new file mode 100644 index 00000000..016b0bc9 --- /dev/null +++ b/libc/nt/gdi32/ScaleRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ScaleRgn,ScaleRgn,1816 diff --git a/libc/nt/gdi32/ScaleValues.s b/libc/nt/gdi32/ScaleValues.s new file mode 100644 index 00000000..370a4496 --- /dev/null +++ b/libc/nt/gdi32/ScaleValues.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ScaleValues,ScaleValues,1817 diff --git a/libc/nt/gdi32/ScaleViewportExtEx.s b/libc/nt/gdi32/ScaleViewportExtEx.s new file mode 100644 index 00000000..a41f8390 --- /dev/null +++ b/libc/nt/gdi32/ScaleViewportExtEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ScaleViewportExtEx,ScaleViewportExtEx,1818 diff --git a/libc/nt/gdi32/ScaleWindowExtEx.s b/libc/nt/gdi32/ScaleWindowExtEx.s new file mode 100644 index 00000000..942cb6ec --- /dev/null +++ b/libc/nt/gdi32/ScaleWindowExtEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ScaleWindowExtEx,ScaleWindowExtEx,1819 diff --git a/libc/nt/gdi32/SelectBrushLocal.s b/libc/nt/gdi32/SelectBrushLocal.s new file mode 100644 index 00000000..ae70dda4 --- /dev/null +++ b/libc/nt/gdi32/SelectBrushLocal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SelectBrushLocal,SelectBrushLocal,1860 diff --git a/libc/nt/gdi32/SelectClipPath.s b/libc/nt/gdi32/SelectClipPath.s new file mode 100644 index 00000000..8a93d685 --- /dev/null +++ b/libc/nt/gdi32/SelectClipPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SelectClipPath,SelectClipPath,1861 diff --git a/libc/nt/gdi32/SelectClipRgn.s b/libc/nt/gdi32/SelectClipRgn.s new file mode 100644 index 00000000..d33b097e --- /dev/null +++ b/libc/nt/gdi32/SelectClipRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SelectClipRgn,SelectClipRgn,1862 diff --git a/libc/nt/gdi32/SelectFontLocal.s b/libc/nt/gdi32/SelectFontLocal.s new file mode 100644 index 00000000..e61fb7c5 --- /dev/null +++ b/libc/nt/gdi32/SelectFontLocal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SelectFontLocal,SelectFontLocal,1863 diff --git a/libc/nt/gdi32/SelectObject.s b/libc/nt/gdi32/SelectObject.s new file mode 100644 index 00000000..a1db2074 --- /dev/null +++ b/libc/nt/gdi32/SelectObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SelectObject,SelectObject,1864 diff --git a/libc/nt/gdi32/SelectPalette.s b/libc/nt/gdi32/SelectPalette.s new file mode 100644 index 00000000..0577494a --- /dev/null +++ b/libc/nt/gdi32/SelectPalette.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SelectPalette,SelectPalette,1865 diff --git a/libc/nt/gdi32/SetAbortProc.s b/libc/nt/gdi32/SetAbortProc.s new file mode 100644 index 00000000..c3d725fb --- /dev/null +++ b/libc/nt/gdi32/SetAbortProc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetAbortProc,SetAbortProc,1866 diff --git a/libc/nt/gdi32/SetArcDirection.s b/libc/nt/gdi32/SetArcDirection.s new file mode 100644 index 00000000..4bf7a022 --- /dev/null +++ b/libc/nt/gdi32/SetArcDirection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetArcDirection,SetArcDirection,1867 diff --git a/libc/nt/gdi32/SetBitmapAttributes.s b/libc/nt/gdi32/SetBitmapAttributes.s new file mode 100644 index 00000000..54105fa0 --- /dev/null +++ b/libc/nt/gdi32/SetBitmapAttributes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetBitmapAttributes,SetBitmapAttributes,1868 diff --git a/libc/nt/gdi32/SetBitmapBits.s b/libc/nt/gdi32/SetBitmapBits.s new file mode 100644 index 00000000..ee3068d0 --- /dev/null +++ b/libc/nt/gdi32/SetBitmapBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetBitmapBits,SetBitmapBits,1869 diff --git a/libc/nt/gdi32/SetBitmapDimensionEx.s b/libc/nt/gdi32/SetBitmapDimensionEx.s new file mode 100644 index 00000000..2a0fc63b --- /dev/null +++ b/libc/nt/gdi32/SetBitmapDimensionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetBitmapDimensionEx,SetBitmapDimensionEx,1870 diff --git a/libc/nt/gdi32/SetBkColor.s b/libc/nt/gdi32/SetBkColor.s new file mode 100644 index 00000000..c989207d --- /dev/null +++ b/libc/nt/gdi32/SetBkColor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetBkColor,SetBkColor,1871 diff --git a/libc/nt/gdi32/SetBkMode.s b/libc/nt/gdi32/SetBkMode.s new file mode 100644 index 00000000..d99f379d --- /dev/null +++ b/libc/nt/gdi32/SetBkMode.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetBkMode,SetBkMode,1872 + + .text.windows +SetBkMode: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetBkMode(%rip),%rax + jmp __sysv2nt + .endfn SetBkMode,globl + .previous diff --git a/libc/nt/gdi32/SetBoundsRect.s b/libc/nt/gdi32/SetBoundsRect.s new file mode 100644 index 00000000..953083c5 --- /dev/null +++ b/libc/nt/gdi32/SetBoundsRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetBoundsRect,SetBoundsRect,1873 diff --git a/libc/nt/gdi32/SetBrushAttributes.s b/libc/nt/gdi32/SetBrushAttributes.s new file mode 100644 index 00000000..697ca16b --- /dev/null +++ b/libc/nt/gdi32/SetBrushAttributes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetBrushAttributes,SetBrushAttributes,1874 diff --git a/libc/nt/gdi32/SetBrushOrgEx.s b/libc/nt/gdi32/SetBrushOrgEx.s new file mode 100644 index 00000000..4c31f5a8 --- /dev/null +++ b/libc/nt/gdi32/SetBrushOrgEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetBrushOrgEx,SetBrushOrgEx,1875 diff --git a/libc/nt/gdi32/SetColorAdjustment.s b/libc/nt/gdi32/SetColorAdjustment.s new file mode 100644 index 00000000..a3a37d98 --- /dev/null +++ b/libc/nt/gdi32/SetColorAdjustment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetColorAdjustment,SetColorAdjustment,1876 diff --git a/libc/nt/gdi32/SetColorSpace.s b/libc/nt/gdi32/SetColorSpace.s new file mode 100644 index 00000000..c0b72379 --- /dev/null +++ b/libc/nt/gdi32/SetColorSpace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetColorSpace,SetColorSpace,1877 diff --git a/libc/nt/gdi32/SetDCBrushColor.s b/libc/nt/gdi32/SetDCBrushColor.s new file mode 100644 index 00000000..f4979c70 --- /dev/null +++ b/libc/nt/gdi32/SetDCBrushColor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetDCBrushColor,SetDCBrushColor,1878 diff --git a/libc/nt/gdi32/SetDCDpiScaleValue.s b/libc/nt/gdi32/SetDCDpiScaleValue.s new file mode 100644 index 00000000..65ee1640 --- /dev/null +++ b/libc/nt/gdi32/SetDCDpiScaleValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetDCDpiScaleValue,SetDCDpiScaleValue,1879 diff --git a/libc/nt/gdi32/SetDCPenColor.s b/libc/nt/gdi32/SetDCPenColor.s new file mode 100644 index 00000000..8eee2736 --- /dev/null +++ b/libc/nt/gdi32/SetDCPenColor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetDCPenColor,SetDCPenColor,1880 diff --git a/libc/nt/gdi32/SetDIBColorTable.s b/libc/nt/gdi32/SetDIBColorTable.s new file mode 100644 index 00000000..5cc9d4f8 --- /dev/null +++ b/libc/nt/gdi32/SetDIBColorTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetDIBColorTable,SetDIBColorTable,1881 diff --git a/libc/nt/gdi32/SetDIBits.s b/libc/nt/gdi32/SetDIBits.s new file mode 100644 index 00000000..e60cd5df --- /dev/null +++ b/libc/nt/gdi32/SetDIBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetDIBits,SetDIBits,1882 diff --git a/libc/nt/gdi32/SetDIBitsToDevice.s b/libc/nt/gdi32/SetDIBitsToDevice.s new file mode 100644 index 00000000..a92a765f --- /dev/null +++ b/libc/nt/gdi32/SetDIBitsToDevice.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetDIBitsToDevice,SetDIBitsToDevice,1883 diff --git a/libc/nt/gdi32/SetDeviceGammaRamp.s b/libc/nt/gdi32/SetDeviceGammaRamp.s new file mode 100644 index 00000000..8f9eb44f --- /dev/null +++ b/libc/nt/gdi32/SetDeviceGammaRamp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetDeviceGammaRamp,SetDeviceGammaRamp,1884 diff --git a/libc/nt/gdi32/SetEnhMetaFileBits.s b/libc/nt/gdi32/SetEnhMetaFileBits.s new file mode 100644 index 00000000..5b2f02b1 --- /dev/null +++ b/libc/nt/gdi32/SetEnhMetaFileBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetEnhMetaFileBits,SetEnhMetaFileBits,1885 diff --git a/libc/nt/gdi32/SetFontEnumeration.s b/libc/nt/gdi32/SetFontEnumeration.s new file mode 100644 index 00000000..5768c62b --- /dev/null +++ b/libc/nt/gdi32/SetFontEnumeration.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetFontEnumeration,SetFontEnumeration,1886 diff --git a/libc/nt/gdi32/SetGraphicsMode.s b/libc/nt/gdi32/SetGraphicsMode.s new file mode 100644 index 00000000..c6b47b9e --- /dev/null +++ b/libc/nt/gdi32/SetGraphicsMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetGraphicsMode,SetGraphicsMode,1887 diff --git a/libc/nt/gdi32/SetICMMode.s b/libc/nt/gdi32/SetICMMode.s new file mode 100644 index 00000000..f2f5ddbd --- /dev/null +++ b/libc/nt/gdi32/SetICMMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetICMMode,SetICMMode,1888 diff --git a/libc/nt/gdi32/SetICMProfileA.s b/libc/nt/gdi32/SetICMProfileA.s new file mode 100644 index 00000000..ddf3c9e5 --- /dev/null +++ b/libc/nt/gdi32/SetICMProfileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetICMProfileA,SetICMProfileA,1889 diff --git a/libc/nt/gdi32/SetICMProfileW.s b/libc/nt/gdi32/SetICMProfileW.s new file mode 100644 index 00000000..b51abe2f --- /dev/null +++ b/libc/nt/gdi32/SetICMProfileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetICMProfileW,SetICMProfileW,1890 diff --git a/libc/nt/gdi32/SetLayout.s b/libc/nt/gdi32/SetLayout.s new file mode 100644 index 00000000..758928e9 --- /dev/null +++ b/libc/nt/gdi32/SetLayout.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetLayout,SetLayout,1891 diff --git a/libc/nt/gdi32/SetLayoutWidth.s b/libc/nt/gdi32/SetLayoutWidth.s new file mode 100644 index 00000000..112b1760 --- /dev/null +++ b/libc/nt/gdi32/SetLayoutWidth.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetLayoutWidth,SetLayoutWidth,1892 diff --git a/libc/nt/gdi32/SetMagicColors.s b/libc/nt/gdi32/SetMagicColors.s new file mode 100644 index 00000000..074e4038 --- /dev/null +++ b/libc/nt/gdi32/SetMagicColors.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetMagicColors,SetMagicColors,1893 diff --git a/libc/nt/gdi32/SetMapMode.s b/libc/nt/gdi32/SetMapMode.s new file mode 100644 index 00000000..0bbdfd73 --- /dev/null +++ b/libc/nt/gdi32/SetMapMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetMapMode,SetMapMode,1894 diff --git a/libc/nt/gdi32/SetMapperFlags.s b/libc/nt/gdi32/SetMapperFlags.s new file mode 100644 index 00000000..034a9316 --- /dev/null +++ b/libc/nt/gdi32/SetMapperFlags.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetMapperFlags,SetMapperFlags,1895 diff --git a/libc/nt/gdi32/SetMetaFileBitsEx.s b/libc/nt/gdi32/SetMetaFileBitsEx.s new file mode 100644 index 00000000..e3950ae9 --- /dev/null +++ b/libc/nt/gdi32/SetMetaFileBitsEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetMetaFileBitsEx,SetMetaFileBitsEx,1896 diff --git a/libc/nt/gdi32/SetMetaRgn.s b/libc/nt/gdi32/SetMetaRgn.s new file mode 100644 index 00000000..8a1484d5 --- /dev/null +++ b/libc/nt/gdi32/SetMetaRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetMetaRgn,SetMetaRgn,1897 diff --git a/libc/nt/gdi32/SetMiterLimit.s b/libc/nt/gdi32/SetMiterLimit.s new file mode 100644 index 00000000..507ea29a --- /dev/null +++ b/libc/nt/gdi32/SetMiterLimit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetMiterLimit,SetMiterLimit,1898 diff --git a/libc/nt/gdi32/SetOPMSigningKeyAndSequenceNumbers.s b/libc/nt/gdi32/SetOPMSigningKeyAndSequenceNumbers.s new file mode 100644 index 00000000..5ac503bf --- /dev/null +++ b/libc/nt/gdi32/SetOPMSigningKeyAndSequenceNumbers.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetOPMSigningKeyAndSequenceNumbers,SetOPMSigningKeyAndSequenceNumbers,1899 diff --git a/libc/nt/gdi32/SetPaletteEntries.s b/libc/nt/gdi32/SetPaletteEntries.s new file mode 100644 index 00000000..71e2d77f --- /dev/null +++ b/libc/nt/gdi32/SetPaletteEntries.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetPaletteEntries,SetPaletteEntries,1900 diff --git a/libc/nt/gdi32/SetPixel.s b/libc/nt/gdi32/SetPixel.s new file mode 100644 index 00000000..42b62146 --- /dev/null +++ b/libc/nt/gdi32/SetPixel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetPixel,SetPixel,1901 diff --git a/libc/nt/gdi32/SetPixelFormat.s b/libc/nt/gdi32/SetPixelFormat.s new file mode 100644 index 00000000..63d256ec --- /dev/null +++ b/libc/nt/gdi32/SetPixelFormat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetPixelFormat,SetPixelFormat,1902 diff --git a/libc/nt/gdi32/SetPixelV.s b/libc/nt/gdi32/SetPixelV.s new file mode 100644 index 00000000..f0f55c83 --- /dev/null +++ b/libc/nt/gdi32/SetPixelV.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetPixelV,SetPixelV,1903 diff --git a/libc/nt/gdi32/SetPolyFillMode.s b/libc/nt/gdi32/SetPolyFillMode.s new file mode 100644 index 00000000..ceda990f --- /dev/null +++ b/libc/nt/gdi32/SetPolyFillMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetPolyFillMode,SetPolyFillMode,1904 diff --git a/libc/nt/gdi32/SetROP2.s b/libc/nt/gdi32/SetROP2.s new file mode 100644 index 00000000..04da5e06 --- /dev/null +++ b/libc/nt/gdi32/SetROP2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetROP2,SetROP2,1905 diff --git a/libc/nt/gdi32/SetRectRgn.s b/libc/nt/gdi32/SetRectRgn.s new file mode 100644 index 00000000..bfcce133 --- /dev/null +++ b/libc/nt/gdi32/SetRectRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetRectRgn,SetRectRgn,1906 diff --git a/libc/nt/gdi32/SetRelAbs.s b/libc/nt/gdi32/SetRelAbs.s new file mode 100644 index 00000000..155f609f --- /dev/null +++ b/libc/nt/gdi32/SetRelAbs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetRelAbs,SetRelAbs,1907 diff --git a/libc/nt/gdi32/SetStretchBltMode.s b/libc/nt/gdi32/SetStretchBltMode.s new file mode 100644 index 00000000..a55ecf0b --- /dev/null +++ b/libc/nt/gdi32/SetStretchBltMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetStretchBltMode,SetStretchBltMode,1908 diff --git a/libc/nt/gdi32/SetSystemPaletteUse.s b/libc/nt/gdi32/SetSystemPaletteUse.s new file mode 100644 index 00000000..d25305bf --- /dev/null +++ b/libc/nt/gdi32/SetSystemPaletteUse.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetSystemPaletteUse,SetSystemPaletteUse,1909 diff --git a/libc/nt/gdi32/SetTextAlign.s b/libc/nt/gdi32/SetTextAlign.s new file mode 100644 index 00000000..a73969cc --- /dev/null +++ b/libc/nt/gdi32/SetTextAlign.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetTextAlign,SetTextAlign,1910 + + .text.windows +SetTextAlign: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetTextAlign(%rip),%rax + jmp __sysv2nt + .endfn SetTextAlign,globl + .previous diff --git a/libc/nt/gdi32/SetTextCharacterExtra.s b/libc/nt/gdi32/SetTextCharacterExtra.s new file mode 100644 index 00000000..78658259 --- /dev/null +++ b/libc/nt/gdi32/SetTextCharacterExtra.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetTextCharacterExtra,SetTextCharacterExtra,1911 diff --git a/libc/nt/gdi32/SetTextColor.s b/libc/nt/gdi32/SetTextColor.s new file mode 100644 index 00000000..0ebadc95 --- /dev/null +++ b/libc/nt/gdi32/SetTextColor.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetTextColor,SetTextColor,1912 + + .text.windows +SetTextColor: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetTextColor(%rip),%rax + jmp __sysv2nt + .endfn SetTextColor,globl + .previous diff --git a/libc/nt/gdi32/SetTextJustification.s b/libc/nt/gdi32/SetTextJustification.s new file mode 100644 index 00000000..d6c38996 --- /dev/null +++ b/libc/nt/gdi32/SetTextJustification.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetTextJustification,SetTextJustification,1913 + + .text.windows +SetTextJustification: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetTextJustification(%rip),%rax + jmp __sysv2nt + .endfn SetTextJustification,globl + .previous diff --git a/libc/nt/gdi32/SetViewportExtEx.s b/libc/nt/gdi32/SetViewportExtEx.s new file mode 100644 index 00000000..f58dfb74 --- /dev/null +++ b/libc/nt/gdi32/SetViewportExtEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetViewportExtEx,SetViewportExtEx,1914 diff --git a/libc/nt/gdi32/SetViewportOrgEx.s b/libc/nt/gdi32/SetViewportOrgEx.s new file mode 100644 index 00000000..5c82b58f --- /dev/null +++ b/libc/nt/gdi32/SetViewportOrgEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetViewportOrgEx,SetViewportOrgEx,1915 diff --git a/libc/nt/gdi32/SetVirtualResolution.s b/libc/nt/gdi32/SetVirtualResolution.s new file mode 100644 index 00000000..ad43f2a5 --- /dev/null +++ b/libc/nt/gdi32/SetVirtualResolution.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetVirtualResolution,SetVirtualResolution,1916 diff --git a/libc/nt/gdi32/SetWinMetaFileBits.s b/libc/nt/gdi32/SetWinMetaFileBits.s new file mode 100644 index 00000000..e7817653 --- /dev/null +++ b/libc/nt/gdi32/SetWinMetaFileBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetWinMetaFileBits,SetWinMetaFileBits,1917 diff --git a/libc/nt/gdi32/SetWindowExtEx.s b/libc/nt/gdi32/SetWindowExtEx.s new file mode 100644 index 00000000..4eb7bf19 --- /dev/null +++ b/libc/nt/gdi32/SetWindowExtEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetWindowExtEx,SetWindowExtEx,1918 diff --git a/libc/nt/gdi32/SetWindowOrgEx.s b/libc/nt/gdi32/SetWindowOrgEx.s new file mode 100644 index 00000000..1d349219 --- /dev/null +++ b/libc/nt/gdi32/SetWindowOrgEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetWindowOrgEx,SetWindowOrgEx,1919 diff --git a/libc/nt/gdi32/SetWorldTransform.s b/libc/nt/gdi32/SetWorldTransform.s new file mode 100644 index 00000000..e8575a71 --- /dev/null +++ b/libc/nt/gdi32/SetWorldTransform.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SetWorldTransform,SetWorldTransform,1920 diff --git a/libc/nt/gdi32/StartDocA.s b/libc/nt/gdi32/StartDocA.s new file mode 100644 index 00000000..84a38ce5 --- /dev/null +++ b/libc/nt/gdi32/StartDocA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_StartDocA,StartDocA,1921 diff --git a/libc/nt/gdi32/StartDocW.s b/libc/nt/gdi32/StartDocW.s new file mode 100644 index 00000000..d4ce1c63 --- /dev/null +++ b/libc/nt/gdi32/StartDocW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_StartDocW,StartDocW,1922 diff --git a/libc/nt/gdi32/StartFormPage.s b/libc/nt/gdi32/StartFormPage.s new file mode 100644 index 00000000..008877d4 --- /dev/null +++ b/libc/nt/gdi32/StartFormPage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_StartFormPage,StartFormPage,1923 diff --git a/libc/nt/gdi32/StartPage.s b/libc/nt/gdi32/StartPage.s new file mode 100644 index 00000000..bc48e42e --- /dev/null +++ b/libc/nt/gdi32/StartPage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_StartPage,StartPage,1924 diff --git a/libc/nt/gdi32/StretchBlt.s b/libc/nt/gdi32/StretchBlt.s new file mode 100644 index 00000000..8248af75 --- /dev/null +++ b/libc/nt/gdi32/StretchBlt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_StretchBlt,StretchBlt,1925 diff --git a/libc/nt/gdi32/StretchDIBits.s b/libc/nt/gdi32/StretchDIBits.s new file mode 100644 index 00000000..d27d5408 --- /dev/null +++ b/libc/nt/gdi32/StretchDIBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_StretchDIBits,StretchDIBits,1926 diff --git a/libc/nt/gdi32/StrokeAndFillPath.s b/libc/nt/gdi32/StrokeAndFillPath.s new file mode 100644 index 00000000..ec0f4712 --- /dev/null +++ b/libc/nt/gdi32/StrokeAndFillPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_StrokeAndFillPath,StrokeAndFillPath,1927 diff --git a/libc/nt/gdi32/StrokePath.s b/libc/nt/gdi32/StrokePath.s new file mode 100644 index 00000000..8319164c --- /dev/null +++ b/libc/nt/gdi32/StrokePath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_StrokePath,StrokePath,1928 diff --git a/libc/nt/gdi32/SwapBuffers.s b/libc/nt/gdi32/SwapBuffers.s new file mode 100644 index 00000000..baebd4e3 --- /dev/null +++ b/libc/nt/gdi32/SwapBuffers.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_SwapBuffers,SwapBuffers,1929 diff --git a/libc/nt/gdi32/TextOutA.s b/libc/nt/gdi32/TextOutA.s new file mode 100644 index 00000000..9bf4a7bd --- /dev/null +++ b/libc/nt/gdi32/TextOutA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_TextOutA,TextOutA,1930 diff --git a/libc/nt/gdi32/TextOutW.s b/libc/nt/gdi32/TextOutW.s new file mode 100644 index 00000000..590e414c --- /dev/null +++ b/libc/nt/gdi32/TextOutW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_TextOutW,TextOutW,1931 diff --git a/libc/nt/gdi32/TranslateCharsetInfo.s b/libc/nt/gdi32/TranslateCharsetInfo.s new file mode 100644 index 00000000..81c1ef55 --- /dev/null +++ b/libc/nt/gdi32/TranslateCharsetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_TranslateCharsetInfo,TranslateCharsetInfo,1932 diff --git a/libc/nt/gdi32/UnloadNetworkFonts.s b/libc/nt/gdi32/UnloadNetworkFonts.s new file mode 100644 index 00000000..0d0641af --- /dev/null +++ b/libc/nt/gdi32/UnloadNetworkFonts.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_UnloadNetworkFonts,UnloadNetworkFonts,1933 diff --git a/libc/nt/gdi32/UnrealizeObject.s b/libc/nt/gdi32/UnrealizeObject.s new file mode 100644 index 00000000..01f758a8 --- /dev/null +++ b/libc/nt/gdi32/UnrealizeObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_UnrealizeObject,UnrealizeObject,1934 diff --git a/libc/nt/gdi32/UpdateColors.s b/libc/nt/gdi32/UpdateColors.s new file mode 100644 index 00000000..c94c0685 --- /dev/null +++ b/libc/nt/gdi32/UpdateColors.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_UpdateColors,UpdateColors,1935 diff --git a/libc/nt/gdi32/UpdateICMRegKeyA.s b/libc/nt/gdi32/UpdateICMRegKeyA.s new file mode 100644 index 00000000..04c16c42 --- /dev/null +++ b/libc/nt/gdi32/UpdateICMRegKeyA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_UpdateICMRegKeyA,UpdateICMRegKeyA,1936 diff --git a/libc/nt/gdi32/UpdateICMRegKeyW.s b/libc/nt/gdi32/UpdateICMRegKeyW.s new file mode 100644 index 00000000..9e264adc --- /dev/null +++ b/libc/nt/gdi32/UpdateICMRegKeyW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_UpdateICMRegKeyW,UpdateICMRegKeyW,1937 diff --git a/libc/nt/gdi32/WidenPath.s b/libc/nt/gdi32/WidenPath.s new file mode 100644 index 00000000..0d7d4da6 --- /dev/null +++ b/libc/nt/gdi32/WidenPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_WidenPath,WidenPath,1941 diff --git a/libc/nt/gdi32/XFORMOBJ_bApplyXform.s b/libc/nt/gdi32/XFORMOBJ_bApplyXform.s new file mode 100644 index 00000000..6d4d3955 --- /dev/null +++ b/libc/nt/gdi32/XFORMOBJ_bApplyXform.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_XFORMOBJ_bApplyXform,XFORMOBJ_bApplyXform,1942 diff --git a/libc/nt/gdi32/XFORMOBJ_iGetXform.s b/libc/nt/gdi32/XFORMOBJ_iGetXform.s new file mode 100644 index 00000000..5564356b --- /dev/null +++ b/libc/nt/gdi32/XFORMOBJ_iGetXform.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_XFORMOBJ_iGetXform,XFORMOBJ_iGetXform,1943 diff --git a/libc/nt/gdi32/XLATEOBJ_cGetPalette.s b/libc/nt/gdi32/XLATEOBJ_cGetPalette.s new file mode 100644 index 00000000..4c345fc4 --- /dev/null +++ b/libc/nt/gdi32/XLATEOBJ_cGetPalette.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_XLATEOBJ_cGetPalette,XLATEOBJ_cGetPalette,1944 diff --git a/libc/nt/gdi32/XLATEOBJ_hGetColorTransform.s b/libc/nt/gdi32/XLATEOBJ_hGetColorTransform.s new file mode 100644 index 00000000..f036655c --- /dev/null +++ b/libc/nt/gdi32/XLATEOBJ_hGetColorTransform.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_XLATEOBJ_hGetColorTransform,XLATEOBJ_hGetColorTransform,1945 diff --git a/libc/nt/gdi32/XLATEOBJ_iXlate.s b/libc/nt/gdi32/XLATEOBJ_iXlate.s new file mode 100644 index 00000000..066998d8 --- /dev/null +++ b/libc/nt/gdi32/XLATEOBJ_iXlate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_XLATEOBJ_iXlate,XLATEOBJ_iXlate,1946 diff --git a/libc/nt/gdi32/XLATEOBJ_piVector.s b/libc/nt/gdi32/XLATEOBJ_piVector.s new file mode 100644 index 00000000..71deeb91 --- /dev/null +++ b/libc/nt/gdi32/XLATEOBJ_piVector.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_XLATEOBJ_piVector,XLATEOBJ_piVector,1947 diff --git a/libc/nt/gdi32/bCreateDCW.s b/libc/nt/gdi32/bCreateDCW.s new file mode 100644 index 00000000..8f2b60ee --- /dev/null +++ b/libc/nt/gdi32/bCreateDCW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_bCreateDCW,bCreateDCW,1948 diff --git a/libc/nt/gdi32/bDeleteLDC.s b/libc/nt/gdi32/bDeleteLDC.s new file mode 100644 index 00000000..177273b2 --- /dev/null +++ b/libc/nt/gdi32/bDeleteLDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_bDeleteLDC,bDeleteLDC,1949 diff --git a/libc/nt/gdi32/bInitSystemAndFontsDirectoriesW.s b/libc/nt/gdi32/bInitSystemAndFontsDirectoriesW.s new file mode 100644 index 00000000..87e2d562 --- /dev/null +++ b/libc/nt/gdi32/bInitSystemAndFontsDirectoriesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_bInitSystemAndFontsDirectoriesW,bInitSystemAndFontsDirectoriesW,1950 diff --git a/libc/nt/gdi32/bMakePathNameW.s b/libc/nt/gdi32/bMakePathNameW.s new file mode 100644 index 00000000..183a6c3c --- /dev/null +++ b/libc/nt/gdi32/bMakePathNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_bMakePathNameW,bMakePathNameW,1951 diff --git a/libc/nt/gdi32/cGetTTFFromFOT.s b/libc/nt/gdi32/cGetTTFFromFOT.s new file mode 100644 index 00000000..50640460 --- /dev/null +++ b/libc/nt/gdi32/cGetTTFFromFOT.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_cGetTTFFromFOT,cGetTTFFromFOT,1952 diff --git a/libc/nt/gdi32/fpClosePrinter.s b/libc/nt/gdi32/fpClosePrinter.s new file mode 100644 index 00000000..1a0090af --- /dev/null +++ b/libc/nt/gdi32/fpClosePrinter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_fpClosePrinter,fpClosePrinter,1953 diff --git a/libc/nt/gdi32/gMaxGdiHandleCount.s b/libc/nt/gdi32/gMaxGdiHandleCount.s new file mode 100644 index 00000000..72d33a82 --- /dev/null +++ b/libc/nt/gdi32/gMaxGdiHandleCount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_gMaxGdiHandleCount,gMaxGdiHandleCount,1955 diff --git a/libc/nt/gdi32/gW32PID.s b/libc/nt/gdi32/gW32PID.s new file mode 100644 index 00000000..366f7dff --- /dev/null +++ b/libc/nt/gdi32/gW32PID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_gW32PID,gW32PID,1956 diff --git a/libc/nt/gdi32/g_systemCallFilterId.s b/libc/nt/gdi32/g_systemCallFilterId.s new file mode 100644 index 00000000..f40bb95d --- /dev/null +++ b/libc/nt/gdi32/g_systemCallFilterId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_g_systemCallFilterId,g_systemCallFilterId,1957 diff --git a/libc/nt/gdi32/gdiPlaySpoolStream.s b/libc/nt/gdi32/gdiPlaySpoolStream.s new file mode 100644 index 00000000..1504a1e0 --- /dev/null +++ b/libc/nt/gdi32/gdiPlaySpoolStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_gdiPlaySpoolStream,gdiPlaySpoolStream,1958 diff --git a/libc/nt/gdi32/ghICM.s b/libc/nt/gdi32/ghICM.s new file mode 100644 index 00000000..14ee71a0 --- /dev/null +++ b/libc/nt/gdi32/ghICM.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_ghICM,ghICM,1959 diff --git a/libc/nt/gdi32/hGetPEBHandle.s b/libc/nt/gdi32/hGetPEBHandle.s new file mode 100644 index 00000000..cdca9508 --- /dev/null +++ b/libc/nt/gdi32/hGetPEBHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_hGetPEBHandle,hGetPEBHandle,1960 diff --git a/libc/nt/gdi32/pGdiDevCaps.s b/libc/nt/gdi32/pGdiDevCaps.s new file mode 100644 index 00000000..46c58ec3 --- /dev/null +++ b/libc/nt/gdi32/pGdiDevCaps.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_pGdiDevCaps,pGdiDevCaps,1961 diff --git a/libc/nt/gdi32/pGdiSharedHandleTable.s b/libc/nt/gdi32/pGdiSharedHandleTable.s new file mode 100644 index 00000000..b85c9b52 --- /dev/null +++ b/libc/nt/gdi32/pGdiSharedHandleTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_pGdiSharedHandleTable,pGdiSharedHandleTable,1962 diff --git a/libc/nt/gdi32/pGdiSharedMemory.s b/libc/nt/gdi32/pGdiSharedMemory.s new file mode 100644 index 00000000..b71d94cd --- /dev/null +++ b/libc/nt/gdi32/pGdiSharedMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_pGdiSharedMemory,pGdiSharedMemory,1963 diff --git a/libc/nt/gdi32/pldcGet.s b/libc/nt/gdi32/pldcGet.s new file mode 100644 index 00000000..13baabd5 --- /dev/null +++ b/libc/nt/gdi32/pldcGet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_pldcGet,pldcGet,1964 diff --git a/libc/nt/gdi32/semDxTrimNotification.s b/libc/nt/gdi32/semDxTrimNotification.s new file mode 100644 index 00000000..c17cc710 --- /dev/null +++ b/libc/nt/gdi32/semDxTrimNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_semDxTrimNotification,semDxTrimNotification,1965 diff --git a/libc/nt/gdi32/vSetPldc.s b/libc/nt/gdi32/vSetPldc.s new file mode 100644 index 00000000..b246449e --- /dev/null +++ b/libc/nt/gdi32/vSetPldc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp gdi32,__imp_vSetPldc,vSetPldc,1966 diff --git a/libc/nt/ipc.h b/libc/nt/ipc.h new file mode 100644 index 00000000..52158e2d --- /dev/null +++ b/libc/nt/ipc.h @@ -0,0 +1,87 @@ +#ifndef COSMOPOLITAN_LIBC_NT_IPC_H_ +#define COSMOPOLITAN_LIBC_NT_IPC_H_ +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » ipc ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +/* CreateNamedPipe:dwOpenMode */ +#define kNtPipeAccessInbound 0x00000001 +#define kNtPipeAccessOutbound 0x00000002 +#define kNtPipeAccessDuplex 0x00000003 + +/* CreateNamedPipe::dwPipeMode */ +#define kNtPipeWait 0x00000000 +#define kNtPipeNowait 0x00000001 +#define kNtPipeReadmodeByte 0x00000000 +#define kNtPipeReadmodeMessage 0x00000002 +#define kNtPipeTypeByte 0x00000000 +#define kNtPipeTypeMessage 0x00000004 +#define kNtPipeAcceptRemoteClients 0x00000000 +#define kNtPipeRejectRemoteClients 0x00000008 + +/* CreateNamedPipe::nMaxInstances */ +#define NT_PIPE_UNLIMITED_INSTANCES 255 + +/* CreateNamedPipeInfo */ +#define PIPE_CLIENT_END 0x00000000 +#define PIPE_SERVER_END 0x00000001 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtOverlapped; +struct NtSecurityAttributes; + +int CreatePipe(int64_t *out_hReadPipe, int64_t *out_hWritePipe, + const struct NtSecurityAttributes *opt_lpPipeAttributes, + uint32_t nSize) paramsnonnull((1, 2)); +void *CreateNamedPipe( + const char16_t *lpName, uint32_t dwOpenMode, uint32_t dwPipeMode, + uint32_t nMaxInstances, uint32_t nOutBufferSize, uint32_t nInBufferSize, + uint32_t nDefaultTimeOut, + const struct NtSecurityAttributes *opt_lpSecurityAttributes) + paramsnonnull((1)); +bool32 ConnectNamedPipe(int64_t *hNamedPipe, struct NtOverlapped *lpOverlapped); +bool32 CallNamedPipe(const char16_t *lpNamedPipeName, void *lpInBuffer, + uint32_t nInBufferSize, void *lpOutBuffer, + uint32_t nOutBufferSize, uint32_t *lpBytesRead, + uint32_t nTimeOut); +bool32 WaitNamedPipe(const char16_t *lpNamedPipeName, uint32_t nTimeOut); +bool32 DisconnectNamedPipe(int64_t *hNamedPipe); +bool32 SetNamedPipeHandleState(int64_t *hNamedPipe, uint32_t *lpMode, + uint32_t *lpMaxCollectionCount, + uint32_t *lpCollectDataTimeout); +bool32 PeekNamedPipe(int64_t *hNamedPipe, void *lpBuffer, uint32_t nBufferSize, + uint32_t *lpBytesRead, uint32_t *lpTotalBytesAvail, + uint32_t *lpBytesLeftThisMessage); +bool32 TransactNamedPipe(int64_t *hNamedPipe, void *lpInBuffer, + uint32_t nInBufferSize, void *lpOutBuffer, + uint32_t nOutBufferSize, uint32_t *lpBytesRead, + struct NtOverlapped *lpOverlapped); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_IPC_H_ */ diff --git a/libc/nt/kernel32/ActivateActCtxWorker.s b/libc/nt/kernel32/ActivateActCtxWorker.s new file mode 100644 index 00000000..c15b5801 --- /dev/null +++ b/libc/nt/kernel32/ActivateActCtxWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_ActivateActCtxWorker,ActivateActCtxWorker,4 diff --git a/libc/nt/kernel32/AddAtomA.s b/libc/nt/kernel32/AddAtomA.s new file mode 100644 index 00000000..72895fbe --- /dev/null +++ b/libc/nt/kernel32/AddAtomA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_AddAtomA,AddAtomA,5 diff --git a/libc/nt/kernel32/AddAtomW.s b/libc/nt/kernel32/AddAtomW.s new file mode 100644 index 00000000..aae1a96e --- /dev/null +++ b/libc/nt/kernel32/AddAtomW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_AddAtomW,AddAtomW,6 diff --git a/libc/nt/kernel32/AddIntegrityLabelToBoundaryDescriptor.s b/libc/nt/kernel32/AddIntegrityLabelToBoundaryDescriptor.s new file mode 100644 index 00000000..2ac37503 --- /dev/null +++ b/libc/nt/kernel32/AddIntegrityLabelToBoundaryDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_AddIntegrityLabelToBoundaryDescriptor,AddIntegrityLabelToBoundaryDescriptor,10 diff --git a/libc/nt/kernel32/AddLocalAlternateComputerNameA.s b/libc/nt/kernel32/AddLocalAlternateComputerNameA.s new file mode 100644 index 00000000..5296277f --- /dev/null +++ b/libc/nt/kernel32/AddLocalAlternateComputerNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_AddLocalAlternateComputerNameA,AddLocalAlternateComputerNameA,11 diff --git a/libc/nt/kernel32/AddLocalAlternateComputerNameW.s b/libc/nt/kernel32/AddLocalAlternateComputerNameW.s new file mode 100644 index 00000000..fe634608 --- /dev/null +++ b/libc/nt/kernel32/AddLocalAlternateComputerNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_AddLocalAlternateComputerNameW,AddLocalAlternateComputerNameW,12 diff --git a/libc/nt/kernel32/AddRefActCtxWorker.s b/libc/nt/kernel32/AddRefActCtxWorker.s new file mode 100644 index 00000000..f1450c60 --- /dev/null +++ b/libc/nt/kernel32/AddRefActCtxWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_AddRefActCtxWorker,AddRefActCtxWorker,14 diff --git a/libc/nt/kernel32/AddSecureMemoryCacheCallback.s b/libc/nt/kernel32/AddSecureMemoryCacheCallback.s new file mode 100644 index 00000000..7d941e8e --- /dev/null +++ b/libc/nt/kernel32/AddSecureMemoryCacheCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_AddSecureMemoryCacheCallback,AddSecureMemoryCacheCallback,18 diff --git a/libc/nt/kernel32/AdjustCalendarDate.s b/libc/nt/kernel32/AdjustCalendarDate.s new file mode 100644 index 00000000..e206c55a --- /dev/null +++ b/libc/nt/kernel32/AdjustCalendarDate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_AdjustCalendarDate,AdjustCalendarDate,21 diff --git a/libc/nt/kernel32/ApplicationRecoveryFinished.s b/libc/nt/kernel32/ApplicationRecoveryFinished.s new file mode 100644 index 00000000..ac011fe1 --- /dev/null +++ b/libc/nt/kernel32/ApplicationRecoveryFinished.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_ApplicationRecoveryFinished,ApplicationRecoveryFinished,34 diff --git a/libc/nt/kernel32/ApplicationRecoveryInProgress.s b/libc/nt/kernel32/ApplicationRecoveryInProgress.s new file mode 100644 index 00000000..dd0efc54 --- /dev/null +++ b/libc/nt/kernel32/ApplicationRecoveryInProgress.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_ApplicationRecoveryInProgress,ApplicationRecoveryInProgress,35 diff --git a/libc/nt/kernel32/AssignProcessToJobObject.s b/libc/nt/kernel32/AssignProcessToJobObject.s new file mode 100644 index 00000000..0fd4e0c7 --- /dev/null +++ b/libc/nt/kernel32/AssignProcessToJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_AssignProcessToJobObject,AssignProcessToJobObject,37 diff --git a/libc/nt/kernel32/BackupRead.s b/libc/nt/kernel32/BackupRead.s new file mode 100644 index 00000000..78cb8c37 --- /dev/null +++ b/libc/nt/kernel32/BackupRead.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BackupRead,BackupRead,39 diff --git a/libc/nt/kernel32/BackupSeek.s b/libc/nt/kernel32/BackupSeek.s new file mode 100644 index 00000000..794be288 --- /dev/null +++ b/libc/nt/kernel32/BackupSeek.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BackupSeek,BackupSeek,40 diff --git a/libc/nt/kernel32/BackupWrite.s b/libc/nt/kernel32/BackupWrite.s new file mode 100644 index 00000000..39ad36bf --- /dev/null +++ b/libc/nt/kernel32/BackupWrite.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BackupWrite,BackupWrite,41 diff --git a/libc/nt/kernel32/BaseCheckAppcompatCacheExWorker.s b/libc/nt/kernel32/BaseCheckAppcompatCacheExWorker.s new file mode 100644 index 00000000..4c3fb8d5 --- /dev/null +++ b/libc/nt/kernel32/BaseCheckAppcompatCacheExWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseCheckAppcompatCacheExWorker,BaseCheckAppcompatCacheExWorker,44 diff --git a/libc/nt/kernel32/BaseCheckAppcompatCacheWorker.s b/libc/nt/kernel32/BaseCheckAppcompatCacheWorker.s new file mode 100644 index 00000000..ea28f477 --- /dev/null +++ b/libc/nt/kernel32/BaseCheckAppcompatCacheWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseCheckAppcompatCacheWorker,BaseCheckAppcompatCacheWorker,45 diff --git a/libc/nt/kernel32/BaseCheckElevation.s b/libc/nt/kernel32/BaseCheckElevation.s new file mode 100644 index 00000000..1df7de11 --- /dev/null +++ b/libc/nt/kernel32/BaseCheckElevation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseCheckElevation,BaseCheckElevation,46 diff --git a/libc/nt/kernel32/BaseCleanupAppcompatCacheSupportWorker.s b/libc/nt/kernel32/BaseCleanupAppcompatCacheSupportWorker.s new file mode 100644 index 00000000..a9e2f891 --- /dev/null +++ b/libc/nt/kernel32/BaseCleanupAppcompatCacheSupportWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseCleanupAppcompatCacheSupportWorker,BaseCleanupAppcompatCacheSupportWorker,48 diff --git a/libc/nt/kernel32/BaseDestroyVDMEnvironment.s b/libc/nt/kernel32/BaseDestroyVDMEnvironment.s new file mode 100644 index 00000000..49009ffc --- /dev/null +++ b/libc/nt/kernel32/BaseDestroyVDMEnvironment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseDestroyVDMEnvironment,BaseDestroyVDMEnvironment,49 diff --git a/libc/nt/kernel32/BaseDllReadWriteIniFile.s b/libc/nt/kernel32/BaseDllReadWriteIniFile.s new file mode 100644 index 00000000..6e677d2d --- /dev/null +++ b/libc/nt/kernel32/BaseDllReadWriteIniFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseDllReadWriteIniFile,BaseDllReadWriteIniFile,50 diff --git a/libc/nt/kernel32/BaseDumpAppcompatCacheWorker.s b/libc/nt/kernel32/BaseDumpAppcompatCacheWorker.s new file mode 100644 index 00000000..0506399d --- /dev/null +++ b/libc/nt/kernel32/BaseDumpAppcompatCacheWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseDumpAppcompatCacheWorker,BaseDumpAppcompatCacheWorker,52 diff --git a/libc/nt/kernel32/BaseElevationPostProcessing.s b/libc/nt/kernel32/BaseElevationPostProcessing.s new file mode 100644 index 00000000..eb459e85 --- /dev/null +++ b/libc/nt/kernel32/BaseElevationPostProcessing.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseElevationPostProcessing,BaseElevationPostProcessing,53 diff --git a/libc/nt/kernel32/BaseFlushAppcompatCacheWorker.s b/libc/nt/kernel32/BaseFlushAppcompatCacheWorker.s new file mode 100644 index 00000000..3fe41f19 --- /dev/null +++ b/libc/nt/kernel32/BaseFlushAppcompatCacheWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseFlushAppcompatCacheWorker,BaseFlushAppcompatCacheWorker,55 diff --git a/libc/nt/kernel32/BaseFormatTimeOut.s b/libc/nt/kernel32/BaseFormatTimeOut.s new file mode 100644 index 00000000..0ae6b345 --- /dev/null +++ b/libc/nt/kernel32/BaseFormatTimeOut.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseFormatTimeOut,BaseFormatTimeOut,57 diff --git a/libc/nt/kernel32/BaseFreeAppCompatDataForProcessWorker.s b/libc/nt/kernel32/BaseFreeAppCompatDataForProcessWorker.s new file mode 100644 index 00000000..b306d5e6 --- /dev/null +++ b/libc/nt/kernel32/BaseFreeAppCompatDataForProcessWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseFreeAppCompatDataForProcessWorker,BaseFreeAppCompatDataForProcessWorker,58 diff --git a/libc/nt/kernel32/BaseGenerateAppCompatData.s b/libc/nt/kernel32/BaseGenerateAppCompatData.s new file mode 100644 index 00000000..f364ae35 --- /dev/null +++ b/libc/nt/kernel32/BaseGenerateAppCompatData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseGenerateAppCompatData,BaseGenerateAppCompatData,59 diff --git a/libc/nt/kernel32/BaseInitAppcompatCacheSupportWorker.s b/libc/nt/kernel32/BaseInitAppcompatCacheSupportWorker.s new file mode 100644 index 00000000..95a86717 --- /dev/null +++ b/libc/nt/kernel32/BaseInitAppcompatCacheSupportWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseInitAppcompatCacheSupportWorker,BaseInitAppcompatCacheSupportWorker,62 diff --git a/libc/nt/kernel32/BaseIsAppcompatInfrastructureDisabledWorker.s b/libc/nt/kernel32/BaseIsAppcompatInfrastructureDisabledWorker.s new file mode 100644 index 00000000..71ded0c2 --- /dev/null +++ b/libc/nt/kernel32/BaseIsAppcompatInfrastructureDisabledWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseIsAppcompatInfrastructureDisabledWorker,BaseIsAppcompatInfrastructureDisabledWorker,64 diff --git a/libc/nt/kernel32/BaseIsDosApplication.s b/libc/nt/kernel32/BaseIsDosApplication.s new file mode 100644 index 00000000..ad0a890d --- /dev/null +++ b/libc/nt/kernel32/BaseIsDosApplication.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseIsDosApplication,BaseIsDosApplication,65 diff --git a/libc/nt/kernel32/BaseQueryModuleData.s b/libc/nt/kernel32/BaseQueryModuleData.s new file mode 100644 index 00000000..603e4a54 --- /dev/null +++ b/libc/nt/kernel32/BaseQueryModuleData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseQueryModuleData,BaseQueryModuleData,66 diff --git a/libc/nt/kernel32/BaseReadAppCompatDataForProcessWorker.s b/libc/nt/kernel32/BaseReadAppCompatDataForProcessWorker.s new file mode 100644 index 00000000..0d84353b --- /dev/null +++ b/libc/nt/kernel32/BaseReadAppCompatDataForProcessWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseReadAppCompatDataForProcessWorker,BaseReadAppCompatDataForProcessWorker,67 diff --git a/libc/nt/kernel32/BaseSetLastNTError.s b/libc/nt/kernel32/BaseSetLastNTError.s new file mode 100644 index 00000000..d564772e --- /dev/null +++ b/libc/nt/kernel32/BaseSetLastNTError.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseSetLastNTError,BaseSetLastNTError,68 diff --git a/libc/nt/kernel32/BaseThreadInitThunk.s b/libc/nt/kernel32/BaseThreadInitThunk.s new file mode 100644 index 00000000..809877a9 --- /dev/null +++ b/libc/nt/kernel32/BaseThreadInitThunk.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseThreadInitThunk,BaseThreadInitThunk,69 diff --git a/libc/nt/kernel32/BaseUpdateAppcompatCacheWorker.s b/libc/nt/kernel32/BaseUpdateAppcompatCacheWorker.s new file mode 100644 index 00000000..8e2cd007 --- /dev/null +++ b/libc/nt/kernel32/BaseUpdateAppcompatCacheWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseUpdateAppcompatCacheWorker,BaseUpdateAppcompatCacheWorker,71 diff --git a/libc/nt/kernel32/BaseUpdateVDMEntry.s b/libc/nt/kernel32/BaseUpdateVDMEntry.s new file mode 100644 index 00000000..52f9c568 --- /dev/null +++ b/libc/nt/kernel32/BaseUpdateVDMEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseUpdateVDMEntry,BaseUpdateVDMEntry,72 diff --git a/libc/nt/kernel32/BaseVerifyUnicodeString.s b/libc/nt/kernel32/BaseVerifyUnicodeString.s new file mode 100644 index 00000000..3ec04028 --- /dev/null +++ b/libc/nt/kernel32/BaseVerifyUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseVerifyUnicodeString,BaseVerifyUnicodeString,73 diff --git a/libc/nt/kernel32/BaseWriteErrorElevationRequiredEvent.s b/libc/nt/kernel32/BaseWriteErrorElevationRequiredEvent.s new file mode 100644 index 00000000..baad6a1f --- /dev/null +++ b/libc/nt/kernel32/BaseWriteErrorElevationRequiredEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BaseWriteErrorElevationRequiredEvent,BaseWriteErrorElevationRequiredEvent,74 diff --git a/libc/nt/kernel32/Basep8BitStringToDynamicUnicodeString.s b/libc/nt/kernel32/Basep8BitStringToDynamicUnicodeString.s new file mode 100644 index 00000000..56c2b4a6 --- /dev/null +++ b/libc/nt/kernel32/Basep8BitStringToDynamicUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_Basep8BitStringToDynamicUnicodeString,Basep8BitStringToDynamicUnicodeString,75 diff --git a/libc/nt/kernel32/BasepAllocateActivationContextActivationBlock.s b/libc/nt/kernel32/BasepAllocateActivationContextActivationBlock.s new file mode 100644 index 00000000..0ef68c40 --- /dev/null +++ b/libc/nt/kernel32/BasepAllocateActivationContextActivationBlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepAllocateActivationContextActivationBlock,BasepAllocateActivationContextActivationBlock,76 diff --git a/libc/nt/kernel32/BasepAnsiStringToDynamicUnicodeString.s b/libc/nt/kernel32/BasepAnsiStringToDynamicUnicodeString.s new file mode 100644 index 00000000..a59b8801 --- /dev/null +++ b/libc/nt/kernel32/BasepAnsiStringToDynamicUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepAnsiStringToDynamicUnicodeString,BasepAnsiStringToDynamicUnicodeString,77 diff --git a/libc/nt/kernel32/BasepAppContainerEnvironmentExtension.s b/libc/nt/kernel32/BasepAppContainerEnvironmentExtension.s new file mode 100644 index 00000000..b2f5212c --- /dev/null +++ b/libc/nt/kernel32/BasepAppContainerEnvironmentExtension.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepAppContainerEnvironmentExtension,BasepAppContainerEnvironmentExtension,78 diff --git a/libc/nt/kernel32/BasepAppXExtension.s b/libc/nt/kernel32/BasepAppXExtension.s new file mode 100644 index 00000000..d504e862 --- /dev/null +++ b/libc/nt/kernel32/BasepAppXExtension.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepAppXExtension,BasepAppXExtension,79 diff --git a/libc/nt/kernel32/BasepCheckAppCompat.s b/libc/nt/kernel32/BasepCheckAppCompat.s new file mode 100644 index 00000000..1fa4cd6a --- /dev/null +++ b/libc/nt/kernel32/BasepCheckAppCompat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepCheckAppCompat,BasepCheckAppCompat,80 diff --git a/libc/nt/kernel32/BasepCheckWebBladeHashes.s b/libc/nt/kernel32/BasepCheckWebBladeHashes.s new file mode 100644 index 00000000..4b7d0384 --- /dev/null +++ b/libc/nt/kernel32/BasepCheckWebBladeHashes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepCheckWebBladeHashes,BasepCheckWebBladeHashes,81 diff --git a/libc/nt/kernel32/BasepCheckWinSaferRestrictions.s b/libc/nt/kernel32/BasepCheckWinSaferRestrictions.s new file mode 100644 index 00000000..17216f3c --- /dev/null +++ b/libc/nt/kernel32/BasepCheckWinSaferRestrictions.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepCheckWinSaferRestrictions,BasepCheckWinSaferRestrictions,82 diff --git a/libc/nt/kernel32/BasepConstructSxsCreateProcessMessage.s b/libc/nt/kernel32/BasepConstructSxsCreateProcessMessage.s new file mode 100644 index 00000000..5c5498be --- /dev/null +++ b/libc/nt/kernel32/BasepConstructSxsCreateProcessMessage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepConstructSxsCreateProcessMessage,BasepConstructSxsCreateProcessMessage,83 diff --git a/libc/nt/kernel32/BasepCopyEncryption.s b/libc/nt/kernel32/BasepCopyEncryption.s new file mode 100644 index 00000000..8a1c4f72 --- /dev/null +++ b/libc/nt/kernel32/BasepCopyEncryption.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepCopyEncryption,BasepCopyEncryption,84 diff --git a/libc/nt/kernel32/BasepFreeActivationContextActivationBlock.s b/libc/nt/kernel32/BasepFreeActivationContextActivationBlock.s new file mode 100644 index 00000000..a0623136 --- /dev/null +++ b/libc/nt/kernel32/BasepFreeActivationContextActivationBlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepFreeActivationContextActivationBlock,BasepFreeActivationContextActivationBlock,85 diff --git a/libc/nt/kernel32/BasepFreeAppCompatData.s b/libc/nt/kernel32/BasepFreeAppCompatData.s new file mode 100644 index 00000000..2a9de9e2 --- /dev/null +++ b/libc/nt/kernel32/BasepFreeAppCompatData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepFreeAppCompatData,BasepFreeAppCompatData,86 diff --git a/libc/nt/kernel32/BasepGetAppCompatData.s b/libc/nt/kernel32/BasepGetAppCompatData.s new file mode 100644 index 00000000..01bc7f59 --- /dev/null +++ b/libc/nt/kernel32/BasepGetAppCompatData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepGetAppCompatData,BasepGetAppCompatData,87 diff --git a/libc/nt/kernel32/BasepGetComputerNameFromNtPath.s b/libc/nt/kernel32/BasepGetComputerNameFromNtPath.s new file mode 100644 index 00000000..c508ed69 --- /dev/null +++ b/libc/nt/kernel32/BasepGetComputerNameFromNtPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepGetComputerNameFromNtPath,BasepGetComputerNameFromNtPath,88 diff --git a/libc/nt/kernel32/BasepGetExeArchType.s b/libc/nt/kernel32/BasepGetExeArchType.s new file mode 100644 index 00000000..67114845 --- /dev/null +++ b/libc/nt/kernel32/BasepGetExeArchType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepGetExeArchType,BasepGetExeArchType,89 diff --git a/libc/nt/kernel32/BasepInitAppCompatData.s b/libc/nt/kernel32/BasepInitAppCompatData.s new file mode 100644 index 00000000..8dfb5659 --- /dev/null +++ b/libc/nt/kernel32/BasepInitAppCompatData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepInitAppCompatData,BasepInitAppCompatData,90 diff --git a/libc/nt/kernel32/BasepIsProcessAllowed.s b/libc/nt/kernel32/BasepIsProcessAllowed.s new file mode 100644 index 00000000..4fe6db46 --- /dev/null +++ b/libc/nt/kernel32/BasepIsProcessAllowed.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepIsProcessAllowed,BasepIsProcessAllowed,91 diff --git a/libc/nt/kernel32/BasepMapModuleHandle.s b/libc/nt/kernel32/BasepMapModuleHandle.s new file mode 100644 index 00000000..a39fe4da --- /dev/null +++ b/libc/nt/kernel32/BasepMapModuleHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepMapModuleHandle,BasepMapModuleHandle,92 diff --git a/libc/nt/kernel32/BasepNotifyLoadStringResource.s b/libc/nt/kernel32/BasepNotifyLoadStringResource.s new file mode 100644 index 00000000..a57c7edb --- /dev/null +++ b/libc/nt/kernel32/BasepNotifyLoadStringResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepNotifyLoadStringResource,BasepNotifyLoadStringResource,93 diff --git a/libc/nt/kernel32/BasepPostSuccessAppXExtension.s b/libc/nt/kernel32/BasepPostSuccessAppXExtension.s new file mode 100644 index 00000000..4bb5f7da --- /dev/null +++ b/libc/nt/kernel32/BasepPostSuccessAppXExtension.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepPostSuccessAppXExtension,BasepPostSuccessAppXExtension,94 diff --git a/libc/nt/kernel32/BasepProcessInvalidImage.s b/libc/nt/kernel32/BasepProcessInvalidImage.s new file mode 100644 index 00000000..edf6438f --- /dev/null +++ b/libc/nt/kernel32/BasepProcessInvalidImage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepProcessInvalidImage,BasepProcessInvalidImage,95 diff --git a/libc/nt/kernel32/BasepQueryAppCompat.s b/libc/nt/kernel32/BasepQueryAppCompat.s new file mode 100644 index 00000000..7502c3e0 --- /dev/null +++ b/libc/nt/kernel32/BasepQueryAppCompat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepQueryAppCompat,BasepQueryAppCompat,96 diff --git a/libc/nt/kernel32/BasepQueryModuleChpeSettings.s b/libc/nt/kernel32/BasepQueryModuleChpeSettings.s new file mode 100644 index 00000000..7bfb1b36 --- /dev/null +++ b/libc/nt/kernel32/BasepQueryModuleChpeSettings.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepQueryModuleChpeSettings,BasepQueryModuleChpeSettings,97 diff --git a/libc/nt/kernel32/BasepReleaseAppXContext.s b/libc/nt/kernel32/BasepReleaseAppXContext.s new file mode 100644 index 00000000..324232bd --- /dev/null +++ b/libc/nt/kernel32/BasepReleaseAppXContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepReleaseAppXContext,BasepReleaseAppXContext,98 diff --git a/libc/nt/kernel32/BasepReleaseSxsCreateProcessUtilityStruct.s b/libc/nt/kernel32/BasepReleaseSxsCreateProcessUtilityStruct.s new file mode 100644 index 00000000..ccafe627 --- /dev/null +++ b/libc/nt/kernel32/BasepReleaseSxsCreateProcessUtilityStruct.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepReleaseSxsCreateProcessUtilityStruct,BasepReleaseSxsCreateProcessUtilityStruct,99 diff --git a/libc/nt/kernel32/BasepReportFault.s b/libc/nt/kernel32/BasepReportFault.s new file mode 100644 index 00000000..35a28bc1 --- /dev/null +++ b/libc/nt/kernel32/BasepReportFault.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepReportFault,BasepReportFault,100 diff --git a/libc/nt/kernel32/BasepSetFileEncryptionCompression.s b/libc/nt/kernel32/BasepSetFileEncryptionCompression.s new file mode 100644 index 00000000..61b97317 --- /dev/null +++ b/libc/nt/kernel32/BasepSetFileEncryptionCompression.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BasepSetFileEncryptionCompression,BasepSetFileEncryptionCompression,101 diff --git a/libc/nt/kernel32/BeginUpdateResourceA.s b/libc/nt/kernel32/BeginUpdateResourceA.s new file mode 100644 index 00000000..662f88db --- /dev/null +++ b/libc/nt/kernel32/BeginUpdateResourceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BeginUpdateResourceA,BeginUpdateResourceA,103 diff --git a/libc/nt/kernel32/BeginUpdateResourceW.s b/libc/nt/kernel32/BeginUpdateResourceW.s new file mode 100644 index 00000000..b6c801d3 --- /dev/null +++ b/libc/nt/kernel32/BeginUpdateResourceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BeginUpdateResourceW,BeginUpdateResourceW,104 diff --git a/libc/nt/kernel32/BindIoCompletionCallback.s b/libc/nt/kernel32/BindIoCompletionCallback.s new file mode 100644 index 00000000..152d925c --- /dev/null +++ b/libc/nt/kernel32/BindIoCompletionCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BindIoCompletionCallback,BindIoCompletionCallback,105 diff --git a/libc/nt/kernel32/BuildCommDCBA.s b/libc/nt/kernel32/BuildCommDCBA.s new file mode 100644 index 00000000..209fc870 --- /dev/null +++ b/libc/nt/kernel32/BuildCommDCBA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BuildCommDCBA,BuildCommDCBA,106 diff --git a/libc/nt/kernel32/BuildCommDCBAndTimeoutsA.s b/libc/nt/kernel32/BuildCommDCBAndTimeoutsA.s new file mode 100644 index 00000000..9c3c0bef --- /dev/null +++ b/libc/nt/kernel32/BuildCommDCBAndTimeoutsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BuildCommDCBAndTimeoutsA,BuildCommDCBAndTimeoutsA,107 diff --git a/libc/nt/kernel32/BuildCommDCBAndTimeoutsW.s b/libc/nt/kernel32/BuildCommDCBAndTimeoutsW.s new file mode 100644 index 00000000..f620de39 --- /dev/null +++ b/libc/nt/kernel32/BuildCommDCBAndTimeoutsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BuildCommDCBAndTimeoutsW,BuildCommDCBAndTimeoutsW,108 diff --git a/libc/nt/kernel32/BuildCommDCBW.s b/libc/nt/kernel32/BuildCommDCBW.s new file mode 100644 index 00000000..cecc712a --- /dev/null +++ b/libc/nt/kernel32/BuildCommDCBW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_BuildCommDCBW,BuildCommDCBW,109 diff --git a/libc/nt/kernel32/CallNamedPipeA.s b/libc/nt/kernel32/CallNamedPipeA.s new file mode 100644 index 00000000..82c996ee --- /dev/null +++ b/libc/nt/kernel32/CallNamedPipeA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CallNamedPipeA,CallNamedPipeA,110 + + .text.windows +CallNamedPipeA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CallNamedPipeA(%rip),%rax + jmp __sysv2nt8 + .endfn CallNamedPipeA,globl + .previous diff --git a/libc/nt/kernel32/CancelDeviceWakeupRequest.s b/libc/nt/kernel32/CancelDeviceWakeupRequest.s new file mode 100644 index 00000000..478d3bd6 --- /dev/null +++ b/libc/nt/kernel32/CancelDeviceWakeupRequest.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CancelDeviceWakeupRequest,CancelDeviceWakeupRequest,113 diff --git a/libc/nt/kernel32/CancelTimerQueueTimer.s b/libc/nt/kernel32/CancelTimerQueueTimer.s new file mode 100644 index 00000000..501cbb24 --- /dev/null +++ b/libc/nt/kernel32/CancelTimerQueueTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CancelTimerQueueTimer,CancelTimerQueueTimer,118 diff --git a/libc/nt/kernel32/CheckElevation.s b/libc/nt/kernel32/CheckElevation.s new file mode 100644 index 00000000..9f4aded8 --- /dev/null +++ b/libc/nt/kernel32/CheckElevation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CheckElevation,CheckElevation,123 diff --git a/libc/nt/kernel32/CheckElevationEnabled.s b/libc/nt/kernel32/CheckElevationEnabled.s new file mode 100644 index 00000000..5c941770 --- /dev/null +++ b/libc/nt/kernel32/CheckElevationEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CheckElevationEnabled,CheckElevationEnabled,124 diff --git a/libc/nt/kernel32/CheckForReadOnlyResource.s b/libc/nt/kernel32/CheckForReadOnlyResource.s new file mode 100644 index 00000000..b0e9435e --- /dev/null +++ b/libc/nt/kernel32/CheckForReadOnlyResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CheckForReadOnlyResource,CheckForReadOnlyResource,125 diff --git a/libc/nt/kernel32/CheckForReadOnlyResourceFilter.s b/libc/nt/kernel32/CheckForReadOnlyResourceFilter.s new file mode 100644 index 00000000..ee3c6f10 --- /dev/null +++ b/libc/nt/kernel32/CheckForReadOnlyResourceFilter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CheckForReadOnlyResourceFilter,CheckForReadOnlyResourceFilter,126 diff --git a/libc/nt/kernel32/CheckNameLegalDOS8Dot3A.s b/libc/nt/kernel32/CheckNameLegalDOS8Dot3A.s new file mode 100644 index 00000000..b89a81c4 --- /dev/null +++ b/libc/nt/kernel32/CheckNameLegalDOS8Dot3A.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CheckNameLegalDOS8Dot3A,CheckNameLegalDOS8Dot3A,127 diff --git a/libc/nt/kernel32/CheckNameLegalDOS8Dot3W.s b/libc/nt/kernel32/CheckNameLegalDOS8Dot3W.s new file mode 100644 index 00000000..63db81b0 --- /dev/null +++ b/libc/nt/kernel32/CheckNameLegalDOS8Dot3W.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CheckNameLegalDOS8Dot3W,CheckNameLegalDOS8Dot3W,128 diff --git a/libc/nt/kernel32/CloseConsoleHandle.s b/libc/nt/kernel32/CloseConsoleHandle.s new file mode 100644 index 00000000..47eba184 --- /dev/null +++ b/libc/nt/kernel32/CloseConsoleHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CloseConsoleHandle,CloseConsoleHandle,134 diff --git a/libc/nt/kernel32/CloseProfileUserMapping.s b/libc/nt/kernel32/CloseProfileUserMapping.s new file mode 100644 index 00000000..9819770f --- /dev/null +++ b/libc/nt/kernel32/CloseProfileUserMapping.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CloseProfileUserMapping,CloseProfileUserMapping,138 diff --git a/libc/nt/kernel32/CmdBatNotification.s b/libc/nt/kernel32/CmdBatNotification.s new file mode 100644 index 00000000..577c6ca3 --- /dev/null +++ b/libc/nt/kernel32/CmdBatNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CmdBatNotification,CmdBatNotification,147 diff --git a/libc/nt/kernel32/CommConfigDialogA.s b/libc/nt/kernel32/CommConfigDialogA.s new file mode 100644 index 00000000..50d7b1fb --- /dev/null +++ b/libc/nt/kernel32/CommConfigDialogA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CommConfigDialogA,CommConfigDialogA,148 diff --git a/libc/nt/kernel32/CommConfigDialogW.s b/libc/nt/kernel32/CommConfigDialogW.s new file mode 100644 index 00000000..6a8170b8 --- /dev/null +++ b/libc/nt/kernel32/CommConfigDialogW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CommConfigDialogW,CommConfigDialogW,149 diff --git a/libc/nt/kernel32/CompareCalendarDates.s b/libc/nt/kernel32/CompareCalendarDates.s new file mode 100644 index 00000000..b4b2ee73 --- /dev/null +++ b/libc/nt/kernel32/CompareCalendarDates.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CompareCalendarDates,CompareCalendarDates,150 diff --git a/libc/nt/kernel32/ConsoleMenuControl.s b/libc/nt/kernel32/ConsoleMenuControl.s new file mode 100644 index 00000000..72752897 --- /dev/null +++ b/libc/nt/kernel32/ConsoleMenuControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_ConsoleMenuControl,ConsoleMenuControl,157 diff --git a/libc/nt/kernel32/ConvertCalDateTimeToSystemTime.s b/libc/nt/kernel32/ConvertCalDateTimeToSystemTime.s new file mode 100644 index 00000000..1ffc3378 --- /dev/null +++ b/libc/nt/kernel32/ConvertCalDateTimeToSystemTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_ConvertCalDateTimeToSystemTime,ConvertCalDateTimeToSystemTime,159 diff --git a/libc/nt/kernel32/ConvertNLSDayOfWeekToWin32DayOfWeek.s b/libc/nt/kernel32/ConvertNLSDayOfWeekToWin32DayOfWeek.s new file mode 100644 index 00000000..fac54464 --- /dev/null +++ b/libc/nt/kernel32/ConvertNLSDayOfWeekToWin32DayOfWeek.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_ConvertNLSDayOfWeekToWin32DayOfWeek,ConvertNLSDayOfWeekToWin32DayOfWeek,162 diff --git a/libc/nt/kernel32/ConvertSystemTimeToCalDateTime.s b/libc/nt/kernel32/ConvertSystemTimeToCalDateTime.s new file mode 100644 index 00000000..72698ea4 --- /dev/null +++ b/libc/nt/kernel32/ConvertSystemTimeToCalDateTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_ConvertSystemTimeToCalDateTime,ConvertSystemTimeToCalDateTime,163 diff --git a/libc/nt/kernel32/CopyFileA.s b/libc/nt/kernel32/CopyFileA.s new file mode 100644 index 00000000..dc5a5205 --- /dev/null +++ b/libc/nt/kernel32/CopyFileA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CopyFileA,CopyFileA,168 + + .text.windows +CopyFileA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CopyFileA(%rip),%rax + jmp __sysv2nt + .endfn CopyFileA,globl + .previous diff --git a/libc/nt/kernel32/CopyFileExA.s b/libc/nt/kernel32/CopyFileExA.s new file mode 100644 index 00000000..30bae462 --- /dev/null +++ b/libc/nt/kernel32/CopyFileExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CopyFileExA,CopyFileExA,169 diff --git a/libc/nt/kernel32/CopyFileTransactedA.s b/libc/nt/kernel32/CopyFileTransactedA.s new file mode 100644 index 00000000..e341e0fb --- /dev/null +++ b/libc/nt/kernel32/CopyFileTransactedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CopyFileTransactedA,CopyFileTransactedA,171 diff --git a/libc/nt/kernel32/CopyFileTransactedW.s b/libc/nt/kernel32/CopyFileTransactedW.s new file mode 100644 index 00000000..15588c52 --- /dev/null +++ b/libc/nt/kernel32/CopyFileTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CopyFileTransactedW,CopyFileTransactedW,172 diff --git a/libc/nt/kernel32/CopyLZFile.s b/libc/nt/kernel32/CopyLZFile.s new file mode 100644 index 00000000..62170585 --- /dev/null +++ b/libc/nt/kernel32/CopyLZFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CopyLZFile,CopyLZFile,174 diff --git a/libc/nt/kernel32/CreateActCtxA.s b/libc/nt/kernel32/CreateActCtxA.s new file mode 100644 index 00000000..a69eff7a --- /dev/null +++ b/libc/nt/kernel32/CreateActCtxA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateActCtxA,CreateActCtxA,175 diff --git a/libc/nt/kernel32/CreateActCtxWWorker.s b/libc/nt/kernel32/CreateActCtxWWorker.s new file mode 100644 index 00000000..c4f2301a --- /dev/null +++ b/libc/nt/kernel32/CreateActCtxWWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateActCtxWWorker,CreateActCtxWWorker,177 diff --git a/libc/nt/kernel32/CreateBoundaryDescriptorA.s b/libc/nt/kernel32/CreateBoundaryDescriptorA.s new file mode 100644 index 00000000..b618e369 --- /dev/null +++ b/libc/nt/kernel32/CreateBoundaryDescriptorA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateBoundaryDescriptorA,CreateBoundaryDescriptorA,178 diff --git a/libc/nt/kernel32/CreateDirectoryExA.s b/libc/nt/kernel32/CreateDirectoryExA.s new file mode 100644 index 00000000..d9bcf0db --- /dev/null +++ b/libc/nt/kernel32/CreateDirectoryExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateDirectoryExA,CreateDirectoryExA,182 diff --git a/libc/nt/kernel32/CreateDirectoryTransactedA.s b/libc/nt/kernel32/CreateDirectoryTransactedA.s new file mode 100644 index 00000000..78bd75f7 --- /dev/null +++ b/libc/nt/kernel32/CreateDirectoryTransactedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateDirectoryTransactedA,CreateDirectoryTransactedA,184 diff --git a/libc/nt/kernel32/CreateDirectoryTransactedW.s b/libc/nt/kernel32/CreateDirectoryTransactedW.s new file mode 100644 index 00000000..864b3217 --- /dev/null +++ b/libc/nt/kernel32/CreateDirectoryTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateDirectoryTransactedW,CreateDirectoryTransactedW,185 diff --git a/libc/nt/kernel32/CreateFileMappingA.s b/libc/nt/kernel32/CreateFileMappingA.s new file mode 100644 index 00000000..70e5b848 --- /dev/null +++ b/libc/nt/kernel32/CreateFileMappingA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateFileMappingA,CreateFileMappingA,196 + + .text.windows +CreateFileMappingA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateFileMappingA(%rip),%rax + jmp __sysv2nt8 + .endfn CreateFileMappingA,globl + .previous diff --git a/libc/nt/kernel32/CreateFileMappingNumaA.s b/libc/nt/kernel32/CreateFileMappingNumaA.s new file mode 100644 index 00000000..4b68c965 --- /dev/null +++ b/libc/nt/kernel32/CreateFileMappingNumaA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateFileMappingNumaA,CreateFileMappingNumaA,198 + + .text.windows +CreateFileMappingNumaA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateFileMappingNumaA(%rip),%rax + jmp __sysv2nt8 + .endfn CreateFileMappingNumaA,globl + .previous diff --git a/libc/nt/kernel32/CreateFileTransactedA.s b/libc/nt/kernel32/CreateFileTransactedA.s new file mode 100644 index 00000000..1b80cca0 --- /dev/null +++ b/libc/nt/kernel32/CreateFileTransactedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateFileTransactedA,CreateFileTransactedA,201 diff --git a/libc/nt/kernel32/CreateFileTransactedW.s b/libc/nt/kernel32/CreateFileTransactedW.s new file mode 100644 index 00000000..bf6b942f --- /dev/null +++ b/libc/nt/kernel32/CreateFileTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateFileTransactedW,CreateFileTransactedW,202 diff --git a/libc/nt/kernel32/CreateHardLinkTransactedA.s b/libc/nt/kernel32/CreateHardLinkTransactedA.s new file mode 100644 index 00000000..637efa63 --- /dev/null +++ b/libc/nt/kernel32/CreateHardLinkTransactedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateHardLinkTransactedA,CreateHardLinkTransactedA,205 diff --git a/libc/nt/kernel32/CreateHardLinkTransactedW.s b/libc/nt/kernel32/CreateHardLinkTransactedW.s new file mode 100644 index 00000000..178c0f2d --- /dev/null +++ b/libc/nt/kernel32/CreateHardLinkTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateHardLinkTransactedW,CreateHardLinkTransactedW,206 diff --git a/libc/nt/kernel32/CreateJobObjectA.s b/libc/nt/kernel32/CreateJobObjectA.s new file mode 100644 index 00000000..af4c8bf4 --- /dev/null +++ b/libc/nt/kernel32/CreateJobObjectA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateJobObjectA,CreateJobObjectA,209 diff --git a/libc/nt/kernel32/CreateJobObjectW.s b/libc/nt/kernel32/CreateJobObjectW.s new file mode 100644 index 00000000..7396d266 --- /dev/null +++ b/libc/nt/kernel32/CreateJobObjectW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateJobObjectW,CreateJobObjectW,210 diff --git a/libc/nt/kernel32/CreateJobSet.s b/libc/nt/kernel32/CreateJobSet.s new file mode 100644 index 00000000..b821692b --- /dev/null +++ b/libc/nt/kernel32/CreateJobSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateJobSet,CreateJobSet,211 diff --git a/libc/nt/kernel32/CreateMailslotA.s b/libc/nt/kernel32/CreateMailslotA.s new file mode 100644 index 00000000..7dfa3fe1 --- /dev/null +++ b/libc/nt/kernel32/CreateMailslotA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateMailslotA,CreateMailslotA,212 diff --git a/libc/nt/kernel32/CreateMailslotW.s b/libc/nt/kernel32/CreateMailslotW.s new file mode 100644 index 00000000..c71623ee --- /dev/null +++ b/libc/nt/kernel32/CreateMailslotW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateMailslotW,CreateMailslotW,213 diff --git a/libc/nt/kernel32/CreateNamedPipeA.s b/libc/nt/kernel32/CreateNamedPipeA.s new file mode 100644 index 00000000..6d248455 --- /dev/null +++ b/libc/nt/kernel32/CreateNamedPipeA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateNamedPipeA,CreateNamedPipeA,219 + + .text.windows +CreateNamedPipeA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateNamedPipeA(%rip),%rax + jmp __sysv2nt8 + .endfn CreateNamedPipeA,globl + .previous diff --git a/libc/nt/kernel32/CreatePrivateNamespaceA.s b/libc/nt/kernel32/CreatePrivateNamespaceA.s new file mode 100644 index 00000000..5b518f5e --- /dev/null +++ b/libc/nt/kernel32/CreatePrivateNamespaceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreatePrivateNamespaceA,CreatePrivateNamespaceA,222 diff --git a/libc/nt/kernel32/CreateSemaphoreA.s b/libc/nt/kernel32/CreateSemaphoreA.s new file mode 100644 index 00000000..df98b93a --- /dev/null +++ b/libc/nt/kernel32/CreateSemaphoreA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateSemaphoreA,CreateSemaphoreA,232 diff --git a/libc/nt/kernel32/CreateSemaphoreExA.s b/libc/nt/kernel32/CreateSemaphoreExA.s new file mode 100644 index 00000000..6b5a4b44 --- /dev/null +++ b/libc/nt/kernel32/CreateSemaphoreExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateSemaphoreExA,CreateSemaphoreExA,233 diff --git a/libc/nt/kernel32/CreateSymbolicLinkA.s b/libc/nt/kernel32/CreateSymbolicLinkA.s new file mode 100644 index 00000000..3b97a64b --- /dev/null +++ b/libc/nt/kernel32/CreateSymbolicLinkA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateSymbolicLinkA,CreateSymbolicLinkA,236 + + .text.windows +CreateSymbolicLinkA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateSymbolicLinkA(%rip),%rax + jmp __sysv2nt + .endfn CreateSymbolicLinkA,globl + .previous diff --git a/libc/nt/kernel32/CreateSymbolicLinkTransactedA.s b/libc/nt/kernel32/CreateSymbolicLinkTransactedA.s new file mode 100644 index 00000000..3dbdd68f --- /dev/null +++ b/libc/nt/kernel32/CreateSymbolicLinkTransactedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateSymbolicLinkTransactedA,CreateSymbolicLinkTransactedA,237 diff --git a/libc/nt/kernel32/CreateSymbolicLinkTransactedW.s b/libc/nt/kernel32/CreateSymbolicLinkTransactedW.s new file mode 100644 index 00000000..c0be2cd0 --- /dev/null +++ b/libc/nt/kernel32/CreateSymbolicLinkTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateSymbolicLinkTransactedW,CreateSymbolicLinkTransactedW,238 diff --git a/libc/nt/kernel32/CreateTapePartition.s b/libc/nt/kernel32/CreateTapePartition.s new file mode 100644 index 00000000..b3c90379 --- /dev/null +++ b/libc/nt/kernel32/CreateTapePartition.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateTapePartition,CreateTapePartition,240 diff --git a/libc/nt/kernel32/CreateToolhelp32Snapshot.s b/libc/nt/kernel32/CreateToolhelp32Snapshot.s new file mode 100644 index 00000000..54982f14 --- /dev/null +++ b/libc/nt/kernel32/CreateToolhelp32Snapshot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateToolhelp32Snapshot,CreateToolhelp32Snapshot,250 diff --git a/libc/nt/kernel32/CreateUmsCompletionList.s b/libc/nt/kernel32/CreateUmsCompletionList.s new file mode 100644 index 00000000..049806bb --- /dev/null +++ b/libc/nt/kernel32/CreateUmsCompletionList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateUmsCompletionList,CreateUmsCompletionList,251 diff --git a/libc/nt/kernel32/CreateUmsThreadContext.s b/libc/nt/kernel32/CreateUmsThreadContext.s new file mode 100644 index 00000000..0da1af28 --- /dev/null +++ b/libc/nt/kernel32/CreateUmsThreadContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateUmsThreadContext,CreateUmsThreadContext,252 diff --git a/libc/nt/kernel32/CreateWaitableTimerA.s b/libc/nt/kernel32/CreateWaitableTimerA.s new file mode 100644 index 00000000..2bf1d159 --- /dev/null +++ b/libc/nt/kernel32/CreateWaitableTimerA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateWaitableTimerA,CreateWaitableTimerA,253 diff --git a/libc/nt/kernel32/CreateWaitableTimerExA.s b/libc/nt/kernel32/CreateWaitableTimerExA.s new file mode 100644 index 00000000..bfa74d61 --- /dev/null +++ b/libc/nt/kernel32/CreateWaitableTimerExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_CreateWaitableTimerExA,CreateWaitableTimerExA,254 diff --git a/libc/nt/kernel32/DeactivateActCtxWorker.s b/libc/nt/kernel32/DeactivateActCtxWorker.s new file mode 100644 index 00000000..b3355445 --- /dev/null +++ b/libc/nt/kernel32/DeactivateActCtxWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DeactivateActCtxWorker,DeactivateActCtxWorker,259 diff --git a/libc/nt/kernel32/DebugBreakProcess.s b/libc/nt/kernel32/DebugBreakProcess.s new file mode 100644 index 00000000..cd4ab95f --- /dev/null +++ b/libc/nt/kernel32/DebugBreakProcess.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DebugBreakProcess,DebugBreakProcess,263 + + .text.windows +DebugBreakProcess: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_DebugBreakProcess(%rip) + leave + ret + .endfn DebugBreakProcess,globl + .previous diff --git a/libc/nt/kernel32/DebugSetProcessKillOnExit.s b/libc/nt/kernel32/DebugSetProcessKillOnExit.s new file mode 100644 index 00000000..c22964cb --- /dev/null +++ b/libc/nt/kernel32/DebugSetProcessKillOnExit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DebugSetProcessKillOnExit,DebugSetProcessKillOnExit,264 diff --git a/libc/nt/kernel32/DefineDosDeviceA.s b/libc/nt/kernel32/DefineDosDeviceA.s new file mode 100644 index 00000000..355665ea --- /dev/null +++ b/libc/nt/kernel32/DefineDosDeviceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DefineDosDeviceA,DefineDosDeviceA,267 diff --git a/libc/nt/kernel32/DeleteAtom.s b/libc/nt/kernel32/DeleteAtom.s new file mode 100644 index 00000000..57b6b1d2 --- /dev/null +++ b/libc/nt/kernel32/DeleteAtom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DeleteAtom,DeleteAtom,270 diff --git a/libc/nt/kernel32/DeleteFileTransactedA.s b/libc/nt/kernel32/DeleteFileTransactedA.s new file mode 100644 index 00000000..ac197a63 --- /dev/null +++ b/libc/nt/kernel32/DeleteFileTransactedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DeleteFileTransactedA,DeleteFileTransactedA,275 diff --git a/libc/nt/kernel32/DeleteFileTransactedW.s b/libc/nt/kernel32/DeleteFileTransactedW.s new file mode 100644 index 00000000..3a3b76b4 --- /dev/null +++ b/libc/nt/kernel32/DeleteFileTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DeleteFileTransactedW,DeleteFileTransactedW,276 diff --git a/libc/nt/kernel32/DeleteSynchronizationBarrier.s b/libc/nt/kernel32/DeleteSynchronizationBarrier.s new file mode 100644 index 00000000..333d9ddf --- /dev/null +++ b/libc/nt/kernel32/DeleteSynchronizationBarrier.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DeleteSynchronizationBarrier,DeleteSynchronizationBarrier,279 diff --git a/libc/nt/kernel32/DeleteTimerQueue.s b/libc/nt/kernel32/DeleteTimerQueue.s new file mode 100644 index 00000000..9f7085cc --- /dev/null +++ b/libc/nt/kernel32/DeleteTimerQueue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DeleteTimerQueue,DeleteTimerQueue,280 diff --git a/libc/nt/kernel32/DeleteUmsCompletionList.s b/libc/nt/kernel32/DeleteUmsCompletionList.s new file mode 100644 index 00000000..df29b211 --- /dev/null +++ b/libc/nt/kernel32/DeleteUmsCompletionList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DeleteUmsCompletionList,DeleteUmsCompletionList,283 diff --git a/libc/nt/kernel32/DeleteUmsThreadContext.s b/libc/nt/kernel32/DeleteUmsThreadContext.s new file mode 100644 index 00000000..3c9c8599 --- /dev/null +++ b/libc/nt/kernel32/DeleteUmsThreadContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DeleteUmsThreadContext,DeleteUmsThreadContext,284 diff --git a/libc/nt/kernel32/DeleteVolumeMountPointA.s b/libc/nt/kernel32/DeleteVolumeMountPointA.s new file mode 100644 index 00000000..352edddf --- /dev/null +++ b/libc/nt/kernel32/DeleteVolumeMountPointA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DeleteVolumeMountPointA,DeleteVolumeMountPointA,285 diff --git a/libc/nt/kernel32/DequeueUmsCompletionListItems.s b/libc/nt/kernel32/DequeueUmsCompletionListItems.s new file mode 100644 index 00000000..9d9d91ef --- /dev/null +++ b/libc/nt/kernel32/DequeueUmsCompletionListItems.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DequeueUmsCompletionListItems,DequeueUmsCompletionListItems,287 diff --git a/libc/nt/kernel32/DisableThreadProfiling.s b/libc/nt/kernel32/DisableThreadProfiling.s new file mode 100644 index 00000000..f947403a --- /dev/null +++ b/libc/nt/kernel32/DisableThreadProfiling.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DisableThreadProfiling,DisableThreadProfiling,290 diff --git a/libc/nt/kernel32/DnsHostnameToComputerNameA.s b/libc/nt/kernel32/DnsHostnameToComputerNameA.s new file mode 100644 index 00000000..f50b55a8 --- /dev/null +++ b/libc/nt/kernel32/DnsHostnameToComputerNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DnsHostnameToComputerNameA,DnsHostnameToComputerNameA,294 diff --git a/libc/nt/kernel32/DnsHostnameToComputerNameW.s b/libc/nt/kernel32/DnsHostnameToComputerNameW.s new file mode 100644 index 00000000..faabae5d --- /dev/null +++ b/libc/nt/kernel32/DnsHostnameToComputerNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DnsHostnameToComputerNameW,DnsHostnameToComputerNameW,296 diff --git a/libc/nt/kernel32/DosDateTimeToFileTime.s b/libc/nt/kernel32/DosDateTimeToFileTime.s new file mode 100644 index 00000000..b0119d77 --- /dev/null +++ b/libc/nt/kernel32/DosDateTimeToFileTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DosDateTimeToFileTime,DosDateTimeToFileTime,297 diff --git a/libc/nt/kernel32/DosPathToSessionPathA.s b/libc/nt/kernel32/DosPathToSessionPathA.s new file mode 100644 index 00000000..fcecdf55 --- /dev/null +++ b/libc/nt/kernel32/DosPathToSessionPathA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DosPathToSessionPathA,DosPathToSessionPathA,298 diff --git a/libc/nt/kernel32/DosPathToSessionPathW.s b/libc/nt/kernel32/DosPathToSessionPathW.s new file mode 100644 index 00000000..4a27daea --- /dev/null +++ b/libc/nt/kernel32/DosPathToSessionPathW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DosPathToSessionPathW,DosPathToSessionPathW,299 diff --git a/libc/nt/kernel32/DuplicateConsoleHandle.s b/libc/nt/kernel32/DuplicateConsoleHandle.s new file mode 100644 index 00000000..b38b54a5 --- /dev/null +++ b/libc/nt/kernel32/DuplicateConsoleHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DuplicateConsoleHandle,DuplicateConsoleHandle,300 diff --git a/libc/nt/kernel32/DuplicateEncryptionInfoFileExt.s b/libc/nt/kernel32/DuplicateEncryptionInfoFileExt.s new file mode 100644 index 00000000..372ac077 --- /dev/null +++ b/libc/nt/kernel32/DuplicateEncryptionInfoFileExt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_DuplicateEncryptionInfoFileExt,DuplicateEncryptionInfoFileExt,301 diff --git a/libc/nt/kernel32/EnableThreadProfiling.s b/libc/nt/kernel32/EnableThreadProfiling.s new file mode 100644 index 00000000..777814c8 --- /dev/null +++ b/libc/nt/kernel32/EnableThreadProfiling.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnableThreadProfiling,EnableThreadProfiling,303 diff --git a/libc/nt/kernel32/EndUpdateResourceA.s b/libc/nt/kernel32/EndUpdateResourceA.s new file mode 100644 index 00000000..3a083b55 --- /dev/null +++ b/libc/nt/kernel32/EndUpdateResourceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EndUpdateResourceA,EndUpdateResourceA,306 diff --git a/libc/nt/kernel32/EndUpdateResourceW.s b/libc/nt/kernel32/EndUpdateResourceW.s new file mode 100644 index 00000000..dea8d1d8 --- /dev/null +++ b/libc/nt/kernel32/EndUpdateResourceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EndUpdateResourceW,EndUpdateResourceW,307 diff --git a/libc/nt/kernel32/EnterUmsSchedulingMode.s b/libc/nt/kernel32/EnterUmsSchedulingMode.s new file mode 100644 index 00000000..1247e71f --- /dev/null +++ b/libc/nt/kernel32/EnterUmsSchedulingMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnterUmsSchedulingMode,EnterUmsSchedulingMode,310 diff --git a/libc/nt/kernel32/EnumCalendarInfoA.s b/libc/nt/kernel32/EnumCalendarInfoA.s new file mode 100644 index 00000000..91869522 --- /dev/null +++ b/libc/nt/kernel32/EnumCalendarInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnumCalendarInfoA,EnumCalendarInfoA,311 diff --git a/libc/nt/kernel32/EnumCalendarInfoExA.s b/libc/nt/kernel32/EnumCalendarInfoExA.s new file mode 100644 index 00000000..fb65ee82 --- /dev/null +++ b/libc/nt/kernel32/EnumCalendarInfoExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnumCalendarInfoExA,EnumCalendarInfoExA,312 diff --git a/libc/nt/kernel32/EnumDateFormatsA.s b/libc/nt/kernel32/EnumDateFormatsA.s new file mode 100644 index 00000000..88a6be9d --- /dev/null +++ b/libc/nt/kernel32/EnumDateFormatsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnumDateFormatsA,EnumDateFormatsA,316 diff --git a/libc/nt/kernel32/EnumDateFormatsExA.s b/libc/nt/kernel32/EnumDateFormatsExA.s new file mode 100644 index 00000000..594d98bb --- /dev/null +++ b/libc/nt/kernel32/EnumDateFormatsExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnumDateFormatsExA,EnumDateFormatsExA,317 diff --git a/libc/nt/kernel32/EnumLanguageGroupLocalesA.s b/libc/nt/kernel32/EnumLanguageGroupLocalesA.s new file mode 100644 index 00000000..a2612b2d --- /dev/null +++ b/libc/nt/kernel32/EnumLanguageGroupLocalesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnumLanguageGroupLocalesA,EnumLanguageGroupLocalesA,321 diff --git a/libc/nt/kernel32/EnumResourceLanguagesA.s b/libc/nt/kernel32/EnumResourceLanguagesA.s new file mode 100644 index 00000000..77348a97 --- /dev/null +++ b/libc/nt/kernel32/EnumResourceLanguagesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnumResourceLanguagesA,EnumResourceLanguagesA,323 diff --git a/libc/nt/kernel32/EnumResourceLanguagesW.s b/libc/nt/kernel32/EnumResourceLanguagesW.s new file mode 100644 index 00000000..cc85fba4 --- /dev/null +++ b/libc/nt/kernel32/EnumResourceLanguagesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnumResourceLanguagesW,EnumResourceLanguagesW,326 diff --git a/libc/nt/kernel32/EnumResourceNamesA.s b/libc/nt/kernel32/EnumResourceNamesA.s new file mode 100644 index 00000000..928677af --- /dev/null +++ b/libc/nt/kernel32/EnumResourceNamesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnumResourceNamesA,EnumResourceNamesA,327 diff --git a/libc/nt/kernel32/EnumResourceTypesA.s b/libc/nt/kernel32/EnumResourceTypesA.s new file mode 100644 index 00000000..f9bdeeea --- /dev/null +++ b/libc/nt/kernel32/EnumResourceTypesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnumResourceTypesA,EnumResourceTypesA,331 diff --git a/libc/nt/kernel32/EnumResourceTypesW.s b/libc/nt/kernel32/EnumResourceTypesW.s new file mode 100644 index 00000000..d89b3c69 --- /dev/null +++ b/libc/nt/kernel32/EnumResourceTypesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnumResourceTypesW,EnumResourceTypesW,334 diff --git a/libc/nt/kernel32/EnumSystemCodePagesA.s b/libc/nt/kernel32/EnumSystemCodePagesA.s new file mode 100644 index 00000000..70a1143f --- /dev/null +++ b/libc/nt/kernel32/EnumSystemCodePagesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnumSystemCodePagesA,EnumSystemCodePagesA,335 diff --git a/libc/nt/kernel32/EnumSystemLanguageGroupsA.s b/libc/nt/kernel32/EnumSystemLanguageGroupsA.s new file mode 100644 index 00000000..e71ab23c --- /dev/null +++ b/libc/nt/kernel32/EnumSystemLanguageGroupsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnumSystemLanguageGroupsA,EnumSystemLanguageGroupsA,340 diff --git a/libc/nt/kernel32/EnumTimeFormatsA.s b/libc/nt/kernel32/EnumTimeFormatsA.s new file mode 100644 index 00000000..9056d944 --- /dev/null +++ b/libc/nt/kernel32/EnumTimeFormatsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnumTimeFormatsA,EnumTimeFormatsA,345 diff --git a/libc/nt/kernel32/EnumUILanguagesA.s b/libc/nt/kernel32/EnumUILanguagesA.s new file mode 100644 index 00000000..1c16a8d3 --- /dev/null +++ b/libc/nt/kernel32/EnumUILanguagesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnumUILanguagesA,EnumUILanguagesA,348 diff --git a/libc/nt/kernel32/EnumerateLocalComputerNamesA.s b/libc/nt/kernel32/EnumerateLocalComputerNamesA.s new file mode 100644 index 00000000..6d122a65 --- /dev/null +++ b/libc/nt/kernel32/EnumerateLocalComputerNamesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnumerateLocalComputerNamesA,EnumerateLocalComputerNamesA,350 diff --git a/libc/nt/kernel32/EnumerateLocalComputerNamesW.s b/libc/nt/kernel32/EnumerateLocalComputerNamesW.s new file mode 100644 index 00000000..c40788ff --- /dev/null +++ b/libc/nt/kernel32/EnumerateLocalComputerNamesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EnumerateLocalComputerNamesW,EnumerateLocalComputerNamesW,351 diff --git a/libc/nt/kernel32/EraseTape.s b/libc/nt/kernel32/EraseTape.s new file mode 100644 index 00000000..ecd25007 --- /dev/null +++ b/libc/nt/kernel32/EraseTape.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_EraseTape,EraseTape,352 diff --git a/libc/nt/kernel32/ExecuteUmsThread.s b/libc/nt/kernel32/ExecuteUmsThread.s new file mode 100644 index 00000000..3bc96472 --- /dev/null +++ b/libc/nt/kernel32/ExecuteUmsThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_ExecuteUmsThread,ExecuteUmsThread,354 diff --git a/libc/nt/kernel32/ExitVDM.s b/libc/nt/kernel32/ExitVDM.s new file mode 100644 index 00000000..aa790018 --- /dev/null +++ b/libc/nt/kernel32/ExitVDM.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_ExitVDM,ExitVDM,357 diff --git a/libc/nt/kernel32/FatalExit.s b/libc/nt/kernel32/FatalExit.s new file mode 100644 index 00000000..69bff88d --- /dev/null +++ b/libc/nt/kernel32/FatalExit.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FatalExit,FatalExit,364 + + .text.windows +FatalExit: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_FatalExit(%rip) + leave + ret + .endfn FatalExit,globl + .previous diff --git a/libc/nt/kernel32/FileTimeToDosDateTime.s b/libc/nt/kernel32/FileTimeToDosDateTime.s new file mode 100644 index 00000000..961889b8 --- /dev/null +++ b/libc/nt/kernel32/FileTimeToDosDateTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FileTimeToDosDateTime,FileTimeToDosDateTime,365 diff --git a/libc/nt/kernel32/FindActCtxSectionGuidWorker.s b/libc/nt/kernel32/FindActCtxSectionGuidWorker.s new file mode 100644 index 00000000..3b1c68ad --- /dev/null +++ b/libc/nt/kernel32/FindActCtxSectionGuidWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindActCtxSectionGuidWorker,FindActCtxSectionGuidWorker,372 diff --git a/libc/nt/kernel32/FindActCtxSectionStringA.s b/libc/nt/kernel32/FindActCtxSectionStringA.s new file mode 100644 index 00000000..223bb398 --- /dev/null +++ b/libc/nt/kernel32/FindActCtxSectionStringA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindActCtxSectionStringA,FindActCtxSectionStringA,373 diff --git a/libc/nt/kernel32/FindActCtxSectionStringWWorker.s b/libc/nt/kernel32/FindActCtxSectionStringWWorker.s new file mode 100644 index 00000000..3860c25b --- /dev/null +++ b/libc/nt/kernel32/FindActCtxSectionStringWWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindActCtxSectionStringWWorker,FindActCtxSectionStringWWorker,375 diff --git a/libc/nt/kernel32/FindAtomA.s b/libc/nt/kernel32/FindAtomA.s new file mode 100644 index 00000000..e7f3d3be --- /dev/null +++ b/libc/nt/kernel32/FindAtomA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindAtomA,FindAtomA,376 diff --git a/libc/nt/kernel32/FindAtomW.s b/libc/nt/kernel32/FindAtomW.s new file mode 100644 index 00000000..60c2f097 --- /dev/null +++ b/libc/nt/kernel32/FindAtomW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindAtomW,FindAtomW,377 diff --git a/libc/nt/kernel32/FindFirstFileNameTransactedW.s b/libc/nt/kernel32/FindFirstFileNameTransactedW.s new file mode 100644 index 00000000..3324284a --- /dev/null +++ b/libc/nt/kernel32/FindFirstFileNameTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindFirstFileNameTransactedW,FindFirstFileNameTransactedW,385 diff --git a/libc/nt/kernel32/FindFirstFileTransactedA.s b/libc/nt/kernel32/FindFirstFileTransactedA.s new file mode 100644 index 00000000..aead76aa --- /dev/null +++ b/libc/nt/kernel32/FindFirstFileTransactedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindFirstFileTransactedA,FindFirstFileTransactedA,387 diff --git a/libc/nt/kernel32/FindFirstFileTransactedW.s b/libc/nt/kernel32/FindFirstFileTransactedW.s new file mode 100644 index 00000000..384fa0be --- /dev/null +++ b/libc/nt/kernel32/FindFirstFileTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindFirstFileTransactedW,FindFirstFileTransactedW,388 diff --git a/libc/nt/kernel32/FindFirstStreamTransactedW.s b/libc/nt/kernel32/FindFirstStreamTransactedW.s new file mode 100644 index 00000000..8a0183d2 --- /dev/null +++ b/libc/nt/kernel32/FindFirstStreamTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindFirstStreamTransactedW,FindFirstStreamTransactedW,390 diff --git a/libc/nt/kernel32/FindFirstVolumeA.s b/libc/nt/kernel32/FindFirstVolumeA.s new file mode 100644 index 00000000..27acb15d --- /dev/null +++ b/libc/nt/kernel32/FindFirstVolumeA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindFirstVolumeA,FindFirstVolumeA,392 + + .text.windows +FindFirstVolumeA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FindFirstVolumeA(%rip),%rax + jmp __sysv2nt + .endfn FindFirstVolumeA,globl + .previous diff --git a/libc/nt/kernel32/FindFirstVolumeMountPointA.s b/libc/nt/kernel32/FindFirstVolumeMountPointA.s new file mode 100644 index 00000000..caa387fe --- /dev/null +++ b/libc/nt/kernel32/FindFirstVolumeMountPointA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindFirstVolumeMountPointA,FindFirstVolumeMountPointA,393 diff --git a/libc/nt/kernel32/FindFirstVolumeMountPointW.s b/libc/nt/kernel32/FindFirstVolumeMountPointW.s new file mode 100644 index 00000000..f3efa8e6 --- /dev/null +++ b/libc/nt/kernel32/FindFirstVolumeMountPointW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindFirstVolumeMountPointW,FindFirstVolumeMountPointW,394 diff --git a/libc/nt/kernel32/FindNextVolumeA.s b/libc/nt/kernel32/FindNextVolumeA.s new file mode 100644 index 00000000..202077a6 --- /dev/null +++ b/libc/nt/kernel32/FindNextVolumeA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindNextVolumeA,FindNextVolumeA,403 + + .text.windows +FindNextVolumeA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FindNextVolumeA(%rip),%rax + jmp __sysv2nt + .endfn FindNextVolumeA,globl + .previous diff --git a/libc/nt/kernel32/FindNextVolumeMountPointA.s b/libc/nt/kernel32/FindNextVolumeMountPointA.s new file mode 100644 index 00000000..a3f05352 --- /dev/null +++ b/libc/nt/kernel32/FindNextVolumeMountPointA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindNextVolumeMountPointA,FindNextVolumeMountPointA,404 diff --git a/libc/nt/kernel32/FindNextVolumeMountPointW.s b/libc/nt/kernel32/FindNextVolumeMountPointW.s new file mode 100644 index 00000000..c5ae38a4 --- /dev/null +++ b/libc/nt/kernel32/FindNextVolumeMountPointW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindNextVolumeMountPointW,FindNextVolumeMountPointW,405 diff --git a/libc/nt/kernel32/FindResourceA.s b/libc/nt/kernel32/FindResourceA.s new file mode 100644 index 00000000..a4849f60 --- /dev/null +++ b/libc/nt/kernel32/FindResourceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindResourceA,FindResourceA,408 diff --git a/libc/nt/kernel32/FindResourceExA.s b/libc/nt/kernel32/FindResourceExA.s new file mode 100644 index 00000000..e7af846d --- /dev/null +++ b/libc/nt/kernel32/FindResourceExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindResourceExA,FindResourceExA,409 diff --git a/libc/nt/kernel32/FindVolumeMountPointClose.s b/libc/nt/kernel32/FindVolumeMountPointClose.s new file mode 100644 index 00000000..b9e2b567 --- /dev/null +++ b/libc/nt/kernel32/FindVolumeMountPointClose.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FindVolumeMountPointClose,FindVolumeMountPointClose,414 diff --git a/libc/nt/kernel32/FoldStringA.s b/libc/nt/kernel32/FoldStringA.s new file mode 100644 index 00000000..f5d8dd52 --- /dev/null +++ b/libc/nt/kernel32/FoldStringA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FoldStringA,FoldStringA,424 diff --git a/libc/nt/kernel32/FreeMemoryJobObject.s b/libc/nt/kernel32/FreeMemoryJobObject.s new file mode 100644 index 00000000..12c1b06a --- /dev/null +++ b/libc/nt/kernel32/FreeMemoryJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_FreeMemoryJobObject,FreeMemoryJobObject,435 diff --git a/libc/nt/kernel32/GetActiveProcessorCount.s b/libc/nt/kernel32/GetActiveProcessorCount.s new file mode 100644 index 00000000..9542b7cf --- /dev/null +++ b/libc/nt/kernel32/GetActiveProcessorCount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetActiveProcessorCount,GetActiveProcessorCount,440 diff --git a/libc/nt/kernel32/GetActiveProcessorGroupCount.s b/libc/nt/kernel32/GetActiveProcessorGroupCount.s new file mode 100644 index 00000000..edfd7c71 --- /dev/null +++ b/libc/nt/kernel32/GetActiveProcessorGroupCount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetActiveProcessorGroupCount,GetActiveProcessorGroupCount,441 diff --git a/libc/nt/kernel32/GetApplicationRecoveryCallbackWorker.s b/libc/nt/kernel32/GetApplicationRecoveryCallbackWorker.s new file mode 100644 index 00000000..b73f68f8 --- /dev/null +++ b/libc/nt/kernel32/GetApplicationRecoveryCallbackWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetApplicationRecoveryCallbackWorker,GetApplicationRecoveryCallbackWorker,445 diff --git a/libc/nt/kernel32/GetApplicationRestartSettingsWorker.s b/libc/nt/kernel32/GetApplicationRestartSettingsWorker.s new file mode 100644 index 00000000..5e4d1092 --- /dev/null +++ b/libc/nt/kernel32/GetApplicationRestartSettingsWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetApplicationRestartSettingsWorker,GetApplicationRestartSettingsWorker,447 diff --git a/libc/nt/kernel32/GetAtomNameA.s b/libc/nt/kernel32/GetAtomNameA.s new file mode 100644 index 00000000..ec741cbf --- /dev/null +++ b/libc/nt/kernel32/GetAtomNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetAtomNameA,GetAtomNameA,449 diff --git a/libc/nt/kernel32/GetAtomNameW.s b/libc/nt/kernel32/GetAtomNameW.s new file mode 100644 index 00000000..cf2ac0c7 --- /dev/null +++ b/libc/nt/kernel32/GetAtomNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetAtomNameW,GetAtomNameW,450 diff --git a/libc/nt/kernel32/GetBinaryTypeA.s b/libc/nt/kernel32/GetBinaryTypeA.s new file mode 100644 index 00000000..3a0cf628 --- /dev/null +++ b/libc/nt/kernel32/GetBinaryTypeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetBinaryTypeA,GetBinaryTypeA,452 diff --git a/libc/nt/kernel32/GetBinaryTypeW.s b/libc/nt/kernel32/GetBinaryTypeW.s new file mode 100644 index 00000000..2cc2cba4 --- /dev/null +++ b/libc/nt/kernel32/GetBinaryTypeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetBinaryTypeW,GetBinaryTypeW,453 diff --git a/libc/nt/kernel32/GetCPInfoExA.s b/libc/nt/kernel32/GetCPInfoExA.s new file mode 100644 index 00000000..70dd69a4 --- /dev/null +++ b/libc/nt/kernel32/GetCPInfoExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetCPInfoExA,GetCPInfoExA,455 diff --git a/libc/nt/kernel32/GetCalendarDateFormat.s b/libc/nt/kernel32/GetCalendarDateFormat.s new file mode 100644 index 00000000..29340860 --- /dev/null +++ b/libc/nt/kernel32/GetCalendarDateFormat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetCalendarDateFormat,GetCalendarDateFormat,458 diff --git a/libc/nt/kernel32/GetCalendarDateFormatEx.s b/libc/nt/kernel32/GetCalendarDateFormatEx.s new file mode 100644 index 00000000..0423877c --- /dev/null +++ b/libc/nt/kernel32/GetCalendarDateFormatEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetCalendarDateFormatEx,GetCalendarDateFormatEx,459 diff --git a/libc/nt/kernel32/GetCalendarDaysInMonth.s b/libc/nt/kernel32/GetCalendarDaysInMonth.s new file mode 100644 index 00000000..ab0c7938 --- /dev/null +++ b/libc/nt/kernel32/GetCalendarDaysInMonth.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetCalendarDaysInMonth,GetCalendarDaysInMonth,460 diff --git a/libc/nt/kernel32/GetCalendarDifferenceInDays.s b/libc/nt/kernel32/GetCalendarDifferenceInDays.s new file mode 100644 index 00000000..71f51924 --- /dev/null +++ b/libc/nt/kernel32/GetCalendarDifferenceInDays.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetCalendarDifferenceInDays,GetCalendarDifferenceInDays,461 diff --git a/libc/nt/kernel32/GetCalendarInfoA.s b/libc/nt/kernel32/GetCalendarInfoA.s new file mode 100644 index 00000000..cef23bc7 --- /dev/null +++ b/libc/nt/kernel32/GetCalendarInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetCalendarInfoA,GetCalendarInfoA,462 diff --git a/libc/nt/kernel32/GetCalendarMonthsInYear.s b/libc/nt/kernel32/GetCalendarMonthsInYear.s new file mode 100644 index 00000000..3db520f1 --- /dev/null +++ b/libc/nt/kernel32/GetCalendarMonthsInYear.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetCalendarMonthsInYear,GetCalendarMonthsInYear,465 diff --git a/libc/nt/kernel32/GetCalendarSupportedDateRange.s b/libc/nt/kernel32/GetCalendarSupportedDateRange.s new file mode 100644 index 00000000..068b9153 --- /dev/null +++ b/libc/nt/kernel32/GetCalendarSupportedDateRange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetCalendarSupportedDateRange,GetCalendarSupportedDateRange,466 diff --git a/libc/nt/kernel32/GetCalendarWeekNumber.s b/libc/nt/kernel32/GetCalendarWeekNumber.s new file mode 100644 index 00000000..080569a4 --- /dev/null +++ b/libc/nt/kernel32/GetCalendarWeekNumber.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetCalendarWeekNumber,GetCalendarWeekNumber,467 diff --git a/libc/nt/kernel32/GetComPlusPackageInstallStatus.s b/libc/nt/kernel32/GetComPlusPackageInstallStatus.s new file mode 100644 index 00000000..c87c5841 --- /dev/null +++ b/libc/nt/kernel32/GetComPlusPackageInstallStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetComPlusPackageInstallStatus,GetComPlusPackageInstallStatus,468 diff --git a/libc/nt/kernel32/GetCompressedFileSizeTransactedA.s b/libc/nt/kernel32/GetCompressedFileSizeTransactedA.s new file mode 100644 index 00000000..b32f9c26 --- /dev/null +++ b/libc/nt/kernel32/GetCompressedFileSizeTransactedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetCompressedFileSizeTransactedA,GetCompressedFileSizeTransactedA,478 diff --git a/libc/nt/kernel32/GetCompressedFileSizeTransactedW.s b/libc/nt/kernel32/GetCompressedFileSizeTransactedW.s new file mode 100644 index 00000000..504864d9 --- /dev/null +++ b/libc/nt/kernel32/GetCompressedFileSizeTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetCompressedFileSizeTransactedW,GetCompressedFileSizeTransactedW,479 diff --git a/libc/nt/kernel32/GetComputerNameA.s b/libc/nt/kernel32/GetComputerNameA.s new file mode 100644 index 00000000..e4581c65 --- /dev/null +++ b/libc/nt/kernel32/GetComputerNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetComputerNameA,GetComputerNameA,481 diff --git a/libc/nt/kernel32/GetComputerNameW.s b/libc/nt/kernel32/GetComputerNameW.s new file mode 100644 index 00000000..b4bd2a53 --- /dev/null +++ b/libc/nt/kernel32/GetComputerNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetComputerNameW,GetComputerNameW,484 diff --git a/libc/nt/kernel32/GetConsoleCharType.s b/libc/nt/kernel32/GetConsoleCharType.s new file mode 100644 index 00000000..846bbdb2 --- /dev/null +++ b/libc/nt/kernel32/GetConsoleCharType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetConsoleCharType,GetConsoleCharType,496 diff --git a/libc/nt/kernel32/GetConsoleCursorMode.s b/libc/nt/kernel32/GetConsoleCursorMode.s new file mode 100644 index 00000000..a3c2d3a6 --- /dev/null +++ b/libc/nt/kernel32/GetConsoleCursorMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetConsoleCursorMode,GetConsoleCursorMode,502 diff --git a/libc/nt/kernel32/GetConsoleFontInfo.s b/libc/nt/kernel32/GetConsoleFontInfo.s new file mode 100644 index 00000000..486538b1 --- /dev/null +++ b/libc/nt/kernel32/GetConsoleFontInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetConsoleFontInfo,GetConsoleFontInfo,504 diff --git a/libc/nt/kernel32/GetConsoleHardwareState.s b/libc/nt/kernel32/GetConsoleHardwareState.s new file mode 100644 index 00000000..eb1b2880 --- /dev/null +++ b/libc/nt/kernel32/GetConsoleHardwareState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetConsoleHardwareState,GetConsoleHardwareState,506 diff --git a/libc/nt/kernel32/GetConsoleInputWaitHandle.s b/libc/nt/kernel32/GetConsoleInputWaitHandle.s new file mode 100644 index 00000000..d1192d97 --- /dev/null +++ b/libc/nt/kernel32/GetConsoleInputWaitHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetConsoleInputWaitHandle,GetConsoleInputWaitHandle,510 diff --git a/libc/nt/kernel32/GetConsoleKeyboardLayoutNameA.s b/libc/nt/kernel32/GetConsoleKeyboardLayoutNameA.s new file mode 100644 index 00000000..89f5a9a2 --- /dev/null +++ b/libc/nt/kernel32/GetConsoleKeyboardLayoutNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetConsoleKeyboardLayoutNameA,GetConsoleKeyboardLayoutNameA,511 diff --git a/libc/nt/kernel32/GetConsoleKeyboardLayoutNameW.s b/libc/nt/kernel32/GetConsoleKeyboardLayoutNameW.s new file mode 100644 index 00000000..447c34bd --- /dev/null +++ b/libc/nt/kernel32/GetConsoleKeyboardLayoutNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetConsoleKeyboardLayoutNameW,GetConsoleKeyboardLayoutNameW,512 diff --git a/libc/nt/kernel32/GetConsoleNlsMode.s b/libc/nt/kernel32/GetConsoleNlsMode.s new file mode 100644 index 00000000..24924d8f --- /dev/null +++ b/libc/nt/kernel32/GetConsoleNlsMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetConsoleNlsMode,GetConsoleNlsMode,514 diff --git a/libc/nt/kernel32/GetCurrencyFormatA.s b/libc/nt/kernel32/GetCurrencyFormatA.s new file mode 100644 index 00000000..a2c96fbe --- /dev/null +++ b/libc/nt/kernel32/GetCurrencyFormatA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetCurrencyFormatA,GetCurrencyFormatA,525 diff --git a/libc/nt/kernel32/GetCurrentActCtxWorker.s b/libc/nt/kernel32/GetCurrentActCtxWorker.s new file mode 100644 index 00000000..70b8b759 --- /dev/null +++ b/libc/nt/kernel32/GetCurrentActCtxWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetCurrentActCtxWorker,GetCurrentActCtxWorker,529 diff --git a/libc/nt/kernel32/GetCurrentUmsThread.s b/libc/nt/kernel32/GetCurrentUmsThread.s new file mode 100644 index 00000000..20f34c57 --- /dev/null +++ b/libc/nt/kernel32/GetCurrentUmsThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetCurrentUmsThread,GetCurrentUmsThread,547 diff --git a/libc/nt/kernel32/GetDateFormatAWorker.s b/libc/nt/kernel32/GetDateFormatAWorker.s new file mode 100644 index 00000000..57d7d85c --- /dev/null +++ b/libc/nt/kernel32/GetDateFormatAWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetDateFormatAWorker,GetDateFormatAWorker,549 diff --git a/libc/nt/kernel32/GetDateFormatWWorker.s b/libc/nt/kernel32/GetDateFormatWWorker.s new file mode 100644 index 00000000..e7461346 --- /dev/null +++ b/libc/nt/kernel32/GetDateFormatWWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetDateFormatWWorker,GetDateFormatWWorker,552 diff --git a/libc/nt/kernel32/GetDefaultCommConfigA.s b/libc/nt/kernel32/GetDefaultCommConfigA.s new file mode 100644 index 00000000..5b1d8d96 --- /dev/null +++ b/libc/nt/kernel32/GetDefaultCommConfigA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetDefaultCommConfigA,GetDefaultCommConfigA,553 diff --git a/libc/nt/kernel32/GetDefaultCommConfigW.s b/libc/nt/kernel32/GetDefaultCommConfigW.s new file mode 100644 index 00000000..b9f063a8 --- /dev/null +++ b/libc/nt/kernel32/GetDefaultCommConfigW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetDefaultCommConfigW,GetDefaultCommConfigW,554 diff --git a/libc/nt/kernel32/GetDevicePowerState.s b/libc/nt/kernel32/GetDevicePowerState.s new file mode 100644 index 00000000..0eb7cf1d --- /dev/null +++ b/libc/nt/kernel32/GetDevicePowerState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetDevicePowerState,GetDevicePowerState,555 diff --git a/libc/nt/kernel32/GetDllDirectoryA.s b/libc/nt/kernel32/GetDllDirectoryA.s new file mode 100644 index 00000000..daf13d09 --- /dev/null +++ b/libc/nt/kernel32/GetDllDirectoryA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetDllDirectoryA,GetDllDirectoryA,560 diff --git a/libc/nt/kernel32/GetDllDirectoryW.s b/libc/nt/kernel32/GetDllDirectoryW.s new file mode 100644 index 00000000..20665daf --- /dev/null +++ b/libc/nt/kernel32/GetDllDirectoryW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetDllDirectoryW,GetDllDirectoryW,561 diff --git a/libc/nt/kernel32/GetDurationFormat.s b/libc/nt/kernel32/GetDurationFormat.s new file mode 100644 index 00000000..8895a3ae --- /dev/null +++ b/libc/nt/kernel32/GetDurationFormat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetDurationFormat,GetDurationFormat,564 diff --git a/libc/nt/kernel32/GetEncryptedFileVersionExt.s b/libc/nt/kernel32/GetEncryptedFileVersionExt.s new file mode 100644 index 00000000..27efc1f1 --- /dev/null +++ b/libc/nt/kernel32/GetEncryptedFileVersionExt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetEncryptedFileVersionExt,GetEncryptedFileVersionExt,568 diff --git a/libc/nt/kernel32/GetExpandedNameA.s b/libc/nt/kernel32/GetExpandedNameA.s new file mode 100644 index 00000000..34cd9a7d --- /dev/null +++ b/libc/nt/kernel32/GetExpandedNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetExpandedNameA,GetExpandedNameA,578 diff --git a/libc/nt/kernel32/GetExpandedNameW.s b/libc/nt/kernel32/GetExpandedNameW.s new file mode 100644 index 00000000..ccd3747c --- /dev/null +++ b/libc/nt/kernel32/GetExpandedNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetExpandedNameW,GetExpandedNameW,579 diff --git a/libc/nt/kernel32/GetFileAttributesTransactedA.s b/libc/nt/kernel32/GetFileAttributesTransactedA.s new file mode 100644 index 00000000..43ac281a --- /dev/null +++ b/libc/nt/kernel32/GetFileAttributesTransactedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetFileAttributesTransactedA,GetFileAttributesTransactedA,583 diff --git a/libc/nt/kernel32/GetFileAttributesTransactedW.s b/libc/nt/kernel32/GetFileAttributesTransactedW.s new file mode 100644 index 00000000..aee4635d --- /dev/null +++ b/libc/nt/kernel32/GetFileAttributesTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetFileAttributesTransactedW,GetFileAttributesTransactedW,584 diff --git a/libc/nt/kernel32/GetFileBandwidthReservation.s b/libc/nt/kernel32/GetFileBandwidthReservation.s new file mode 100644 index 00000000..5e110c5e --- /dev/null +++ b/libc/nt/kernel32/GetFileBandwidthReservation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetFileBandwidthReservation,GetFileBandwidthReservation,586 diff --git a/libc/nt/kernel32/GetFirmwareEnvironmentVariableA.s b/libc/nt/kernel32/GetFirmwareEnvironmentVariableA.s new file mode 100644 index 00000000..b3bbb3e2 --- /dev/null +++ b/libc/nt/kernel32/GetFirmwareEnvironmentVariableA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetFirmwareEnvironmentVariableA,GetFirmwareEnvironmentVariableA,597 diff --git a/libc/nt/kernel32/GetFirmwareEnvironmentVariableExA.s b/libc/nt/kernel32/GetFirmwareEnvironmentVariableExA.s new file mode 100644 index 00000000..44139603 --- /dev/null +++ b/libc/nt/kernel32/GetFirmwareEnvironmentVariableExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetFirmwareEnvironmentVariableExA,GetFirmwareEnvironmentVariableExA,598 diff --git a/libc/nt/kernel32/GetFirmwareEnvironmentVariableExW.s b/libc/nt/kernel32/GetFirmwareEnvironmentVariableExW.s new file mode 100644 index 00000000..c51ca9cb --- /dev/null +++ b/libc/nt/kernel32/GetFirmwareEnvironmentVariableExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetFirmwareEnvironmentVariableExW,GetFirmwareEnvironmentVariableExW,599 diff --git a/libc/nt/kernel32/GetFirmwareEnvironmentVariableW.s b/libc/nt/kernel32/GetFirmwareEnvironmentVariableW.s new file mode 100644 index 00000000..28f7c912 --- /dev/null +++ b/libc/nt/kernel32/GetFirmwareEnvironmentVariableW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetFirmwareEnvironmentVariableW,GetFirmwareEnvironmentVariableW,600 diff --git a/libc/nt/kernel32/GetFirmwareType.s b/libc/nt/kernel32/GetFirmwareType.s new file mode 100644 index 00000000..5372af02 --- /dev/null +++ b/libc/nt/kernel32/GetFirmwareType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetFirmwareType,GetFirmwareType,601 diff --git a/libc/nt/kernel32/GetFullPathNameTransactedA.s b/libc/nt/kernel32/GetFullPathNameTransactedA.s new file mode 100644 index 00000000..c0c17c5d --- /dev/null +++ b/libc/nt/kernel32/GetFullPathNameTransactedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetFullPathNameTransactedA,GetFullPathNameTransactedA,603 diff --git a/libc/nt/kernel32/GetFullPathNameTransactedW.s b/libc/nt/kernel32/GetFullPathNameTransactedW.s new file mode 100644 index 00000000..0206ba14 --- /dev/null +++ b/libc/nt/kernel32/GetFullPathNameTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetFullPathNameTransactedW,GetFullPathNameTransactedW,604 diff --git a/libc/nt/kernel32/GetGeoInfoA.s b/libc/nt/kernel32/GetGeoInfoA.s new file mode 100644 index 00000000..239808af --- /dev/null +++ b/libc/nt/kernel32/GetGeoInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetGeoInfoA,GetGeoInfoA,606 diff --git a/libc/nt/kernel32/GetLogicalDriveStringsA.s b/libc/nt/kernel32/GetLogicalDriveStringsA.s new file mode 100644 index 00000000..450d0ae9 --- /dev/null +++ b/libc/nt/kernel32/GetLogicalDriveStringsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetLogicalDriveStringsA,GetLogicalDriveStringsA,617 diff --git a/libc/nt/kernel32/GetLongPathNameTransactedA.s b/libc/nt/kernel32/GetLongPathNameTransactedA.s new file mode 100644 index 00000000..e46ee4c1 --- /dev/null +++ b/libc/nt/kernel32/GetLongPathNameTransactedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetLongPathNameTransactedA,GetLongPathNameTransactedA,623 diff --git a/libc/nt/kernel32/GetLongPathNameTransactedW.s b/libc/nt/kernel32/GetLongPathNameTransactedW.s new file mode 100644 index 00000000..d8d71747 --- /dev/null +++ b/libc/nt/kernel32/GetLongPathNameTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetLongPathNameTransactedW,GetLongPathNameTransactedW,624 diff --git a/libc/nt/kernel32/GetMailslotInfo.s b/libc/nt/kernel32/GetMailslotInfo.s new file mode 100644 index 00000000..8b233390 --- /dev/null +++ b/libc/nt/kernel32/GetMailslotInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetMailslotInfo,GetMailslotInfo,626 diff --git a/libc/nt/kernel32/GetMaximumProcessorCount.s b/libc/nt/kernel32/GetMaximumProcessorCount.s new file mode 100644 index 00000000..84727f82 --- /dev/null +++ b/libc/nt/kernel32/GetMaximumProcessorCount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetMaximumProcessorCount,GetMaximumProcessorCount,627 diff --git a/libc/nt/kernel32/GetMaximumProcessorGroupCount.s b/libc/nt/kernel32/GetMaximumProcessorGroupCount.s new file mode 100644 index 00000000..b0bd8975 --- /dev/null +++ b/libc/nt/kernel32/GetMaximumProcessorGroupCount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetMaximumProcessorGroupCount,GetMaximumProcessorGroupCount,628 diff --git a/libc/nt/kernel32/GetNamedPipeClientComputerNameA.s b/libc/nt/kernel32/GetNamedPipeClientComputerNameA.s new file mode 100644 index 00000000..813f59bd --- /dev/null +++ b/libc/nt/kernel32/GetNamedPipeClientComputerNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetNamedPipeClientComputerNameA,GetNamedPipeClientComputerNameA,639 diff --git a/libc/nt/kernel32/GetNamedPipeClientProcessId.s b/libc/nt/kernel32/GetNamedPipeClientProcessId.s new file mode 100644 index 00000000..1bfa20ec --- /dev/null +++ b/libc/nt/kernel32/GetNamedPipeClientProcessId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetNamedPipeClientProcessId,GetNamedPipeClientProcessId,641 diff --git a/libc/nt/kernel32/GetNamedPipeClientSessionId.s b/libc/nt/kernel32/GetNamedPipeClientSessionId.s new file mode 100644 index 00000000..4c66e167 --- /dev/null +++ b/libc/nt/kernel32/GetNamedPipeClientSessionId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetNamedPipeClientSessionId,GetNamedPipeClientSessionId,642 diff --git a/libc/nt/kernel32/GetNamedPipeHandleStateA.s b/libc/nt/kernel32/GetNamedPipeHandleStateA.s new file mode 100644 index 00000000..ff0d6980 --- /dev/null +++ b/libc/nt/kernel32/GetNamedPipeHandleStateA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetNamedPipeHandleStateA,GetNamedPipeHandleStateA,643 diff --git a/libc/nt/kernel32/GetNamedPipeServerProcessId.s b/libc/nt/kernel32/GetNamedPipeServerProcessId.s new file mode 100644 index 00000000..468e2327 --- /dev/null +++ b/libc/nt/kernel32/GetNamedPipeServerProcessId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetNamedPipeServerProcessId,GetNamedPipeServerProcessId,646 diff --git a/libc/nt/kernel32/GetNamedPipeServerSessionId.s b/libc/nt/kernel32/GetNamedPipeServerSessionId.s new file mode 100644 index 00000000..1e2d725a --- /dev/null +++ b/libc/nt/kernel32/GetNamedPipeServerSessionId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetNamedPipeServerSessionId,GetNamedPipeServerSessionId,647 diff --git a/libc/nt/kernel32/GetNextUmsListItem.s b/libc/nt/kernel32/GetNextUmsListItem.s new file mode 100644 index 00000000..740b1684 --- /dev/null +++ b/libc/nt/kernel32/GetNextUmsListItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetNextUmsListItem,GetNextUmsListItem,649 diff --git a/libc/nt/kernel32/GetNextVDMCommand.s b/libc/nt/kernel32/GetNextVDMCommand.s new file mode 100644 index 00000000..58f58e06 --- /dev/null +++ b/libc/nt/kernel32/GetNextVDMCommand.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetNextVDMCommand,GetNextVDMCommand,650 diff --git a/libc/nt/kernel32/GetNumaAvailableMemoryNode.s b/libc/nt/kernel32/GetNumaAvailableMemoryNode.s new file mode 100644 index 00000000..7c3a7b8e --- /dev/null +++ b/libc/nt/kernel32/GetNumaAvailableMemoryNode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetNumaAvailableMemoryNode,GetNumaAvailableMemoryNode,651 diff --git a/libc/nt/kernel32/GetNumaAvailableMemoryNodeEx.s b/libc/nt/kernel32/GetNumaAvailableMemoryNodeEx.s new file mode 100644 index 00000000..480bc202 --- /dev/null +++ b/libc/nt/kernel32/GetNumaAvailableMemoryNodeEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetNumaAvailableMemoryNodeEx,GetNumaAvailableMemoryNodeEx,652 diff --git a/libc/nt/kernel32/GetNumaNodeNumberFromHandle.s b/libc/nt/kernel32/GetNumaNodeNumberFromHandle.s new file mode 100644 index 00000000..4b75cbb0 --- /dev/null +++ b/libc/nt/kernel32/GetNumaNodeNumberFromHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetNumaNodeNumberFromHandle,GetNumaNodeNumberFromHandle,654 diff --git a/libc/nt/kernel32/GetNumaNodeProcessorMask.s b/libc/nt/kernel32/GetNumaNodeProcessorMask.s new file mode 100644 index 00000000..47a1ad17 --- /dev/null +++ b/libc/nt/kernel32/GetNumaNodeProcessorMask.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetNumaNodeProcessorMask,GetNumaNodeProcessorMask,655 diff --git a/libc/nt/kernel32/GetNumaProcessorNode.s b/libc/nt/kernel32/GetNumaProcessorNode.s new file mode 100644 index 00000000..415cbb00 --- /dev/null +++ b/libc/nt/kernel32/GetNumaProcessorNode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetNumaProcessorNode,GetNumaProcessorNode,657 diff --git a/libc/nt/kernel32/GetNumaProcessorNodeEx.s b/libc/nt/kernel32/GetNumaProcessorNodeEx.s new file mode 100644 index 00000000..a51f8a4a --- /dev/null +++ b/libc/nt/kernel32/GetNumaProcessorNodeEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetNumaProcessorNodeEx,GetNumaProcessorNodeEx,658 diff --git a/libc/nt/kernel32/GetNumaProximityNode.s b/libc/nt/kernel32/GetNumaProximityNode.s new file mode 100644 index 00000000..f9ceaf64 --- /dev/null +++ b/libc/nt/kernel32/GetNumaProximityNode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetNumaProximityNode,GetNumaProximityNode,659 diff --git a/libc/nt/kernel32/GetNumberFormatA.s b/libc/nt/kernel32/GetNumberFormatA.s new file mode 100644 index 00000000..9840218e --- /dev/null +++ b/libc/nt/kernel32/GetNumberFormatA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetNumberFormatA,GetNumberFormatA,661 diff --git a/libc/nt/kernel32/GetNumberOfConsoleFonts.s b/libc/nt/kernel32/GetNumberOfConsoleFonts.s new file mode 100644 index 00000000..5f37f741 --- /dev/null +++ b/libc/nt/kernel32/GetNumberOfConsoleFonts.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetNumberOfConsoleFonts,GetNumberOfConsoleFonts,664 diff --git a/libc/nt/kernel32/GetPrivateProfileIntA.s b/libc/nt/kernel32/GetPrivateProfileIntA.s new file mode 100644 index 00000000..6e15dd6d --- /dev/null +++ b/libc/nt/kernel32/GetPrivateProfileIntA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetPrivateProfileIntA,GetPrivateProfileIntA,680 diff --git a/libc/nt/kernel32/GetPrivateProfileIntW.s b/libc/nt/kernel32/GetPrivateProfileIntW.s new file mode 100644 index 00000000..b0fa574d --- /dev/null +++ b/libc/nt/kernel32/GetPrivateProfileIntW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetPrivateProfileIntW,GetPrivateProfileIntW,681 diff --git a/libc/nt/kernel32/GetPrivateProfileSectionA.s b/libc/nt/kernel32/GetPrivateProfileSectionA.s new file mode 100644 index 00000000..76f7120a --- /dev/null +++ b/libc/nt/kernel32/GetPrivateProfileSectionA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetPrivateProfileSectionA,GetPrivateProfileSectionA,682 diff --git a/libc/nt/kernel32/GetPrivateProfileSectionNamesA.s b/libc/nt/kernel32/GetPrivateProfileSectionNamesA.s new file mode 100644 index 00000000..7dfa08a7 --- /dev/null +++ b/libc/nt/kernel32/GetPrivateProfileSectionNamesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetPrivateProfileSectionNamesA,GetPrivateProfileSectionNamesA,683 diff --git a/libc/nt/kernel32/GetPrivateProfileSectionNamesW.s b/libc/nt/kernel32/GetPrivateProfileSectionNamesW.s new file mode 100644 index 00000000..b21c2e68 --- /dev/null +++ b/libc/nt/kernel32/GetPrivateProfileSectionNamesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetPrivateProfileSectionNamesW,GetPrivateProfileSectionNamesW,684 diff --git a/libc/nt/kernel32/GetPrivateProfileSectionW.s b/libc/nt/kernel32/GetPrivateProfileSectionW.s new file mode 100644 index 00000000..4189dfc9 --- /dev/null +++ b/libc/nt/kernel32/GetPrivateProfileSectionW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetPrivateProfileSectionW,GetPrivateProfileSectionW,685 diff --git a/libc/nt/kernel32/GetPrivateProfileStringA.s b/libc/nt/kernel32/GetPrivateProfileStringA.s new file mode 100644 index 00000000..2d9f5ff7 --- /dev/null +++ b/libc/nt/kernel32/GetPrivateProfileStringA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetPrivateProfileStringA,GetPrivateProfileStringA,686 diff --git a/libc/nt/kernel32/GetPrivateProfileStringW.s b/libc/nt/kernel32/GetPrivateProfileStringW.s new file mode 100644 index 00000000..13e17b20 --- /dev/null +++ b/libc/nt/kernel32/GetPrivateProfileStringW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetPrivateProfileStringW,GetPrivateProfileStringW,687 diff --git a/libc/nt/kernel32/GetPrivateProfileStructA.s b/libc/nt/kernel32/GetPrivateProfileStructA.s new file mode 100644 index 00000000..cdae4e91 --- /dev/null +++ b/libc/nt/kernel32/GetPrivateProfileStructA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetPrivateProfileStructA,GetPrivateProfileStructA,688 diff --git a/libc/nt/kernel32/GetPrivateProfileStructW.s b/libc/nt/kernel32/GetPrivateProfileStructW.s new file mode 100644 index 00000000..1cd8f186 --- /dev/null +++ b/libc/nt/kernel32/GetPrivateProfileStructW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetPrivateProfileStructW,GetPrivateProfileStructW,689 diff --git a/libc/nt/kernel32/GetProcessAffinityMask.s b/libc/nt/kernel32/GetProcessAffinityMask.s new file mode 100644 index 00000000..12265d1e --- /dev/null +++ b/libc/nt/kernel32/GetProcessAffinityMask.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetProcessAffinityMask,GetProcessAffinityMask,691 + + .text.windows +GetProcessAffinityMask: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetProcessAffinityMask(%rip),%rax + jmp __sysv2nt + .endfn GetProcessAffinityMask,globl + .previous diff --git a/libc/nt/kernel32/GetProcessDEPPolicy.s b/libc/nt/kernel32/GetProcessDEPPolicy.s new file mode 100644 index 00000000..4f75834d --- /dev/null +++ b/libc/nt/kernel32/GetProcessDEPPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetProcessDEPPolicy,GetProcessDEPPolicy,692 diff --git a/libc/nt/kernel32/GetProcessIoCounters.s b/libc/nt/kernel32/GetProcessIoCounters.s new file mode 100644 index 00000000..1447d657 --- /dev/null +++ b/libc/nt/kernel32/GetProcessIoCounters.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetProcessIoCounters,GetProcessIoCounters,701 + + .text.windows +GetProcessIoCounters: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetProcessIoCounters(%rip),%rax + jmp __sysv2nt + .endfn GetProcessIoCounters,globl + .previous diff --git a/libc/nt/kernel32/GetProcessWorkingSetSize.s b/libc/nt/kernel32/GetProcessWorkingSetSize.s new file mode 100644 index 00000000..654fcc5a --- /dev/null +++ b/libc/nt/kernel32/GetProcessWorkingSetSize.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetProcessWorkingSetSize,GetProcessWorkingSetSize,708 + + .text.windows +GetProcessWorkingSetSize: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetProcessWorkingSetSize(%rip),%rax + jmp __sysv2nt + .endfn GetProcessWorkingSetSize,globl + .previous diff --git a/libc/nt/kernel32/GetProfileIntA.s b/libc/nt/kernel32/GetProfileIntA.s new file mode 100644 index 00000000..6ca48707 --- /dev/null +++ b/libc/nt/kernel32/GetProfileIntA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetProfileIntA,GetProfileIntA,712 diff --git a/libc/nt/kernel32/GetProfileIntW.s b/libc/nt/kernel32/GetProfileIntW.s new file mode 100644 index 00000000..633addc3 --- /dev/null +++ b/libc/nt/kernel32/GetProfileIntW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetProfileIntW,GetProfileIntW,713 diff --git a/libc/nt/kernel32/GetProfileSectionA.s b/libc/nt/kernel32/GetProfileSectionA.s new file mode 100644 index 00000000..23075ae7 --- /dev/null +++ b/libc/nt/kernel32/GetProfileSectionA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetProfileSectionA,GetProfileSectionA,714 diff --git a/libc/nt/kernel32/GetProfileSectionW.s b/libc/nt/kernel32/GetProfileSectionW.s new file mode 100644 index 00000000..59121513 --- /dev/null +++ b/libc/nt/kernel32/GetProfileSectionW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetProfileSectionW,GetProfileSectionW,715 diff --git a/libc/nt/kernel32/GetProfileStringA.s b/libc/nt/kernel32/GetProfileStringA.s new file mode 100644 index 00000000..8528017c --- /dev/null +++ b/libc/nt/kernel32/GetProfileStringA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetProfileStringA,GetProfileStringA,716 diff --git a/libc/nt/kernel32/GetProfileStringW.s b/libc/nt/kernel32/GetProfileStringW.s new file mode 100644 index 00000000..02beb4aa --- /dev/null +++ b/libc/nt/kernel32/GetProfileStringW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetProfileStringW,GetProfileStringW,717 diff --git a/libc/nt/kernel32/GetShortPathNameA.s b/libc/nt/kernel32/GetShortPathNameA.s new file mode 100644 index 00000000..a6feaf9c --- /dev/null +++ b/libc/nt/kernel32/GetShortPathNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetShortPathNameA,GetShortPathNameA,720 diff --git a/libc/nt/kernel32/GetStartupInfoA.s b/libc/nt/kernel32/GetStartupInfoA.s new file mode 100644 index 00000000..25f89bf7 --- /dev/null +++ b/libc/nt/kernel32/GetStartupInfoA.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetStartupInfoA,GetStartupInfoA,723 + + .text.windows +GetStartupInfoA: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetStartupInfoA(%rip) + leave + ret + .endfn GetStartupInfoA,globl + .previous diff --git a/libc/nt/kernel32/GetStringTypeExA.s b/libc/nt/kernel32/GetStringTypeExA.s new file mode 100644 index 00000000..2890b13d --- /dev/null +++ b/libc/nt/kernel32/GetStringTypeExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetStringTypeExA,GetStringTypeExA,729 diff --git a/libc/nt/kernel32/GetSystemDEPPolicy.s b/libc/nt/kernel32/GetSystemDEPPolicy.s new file mode 100644 index 00000000..3438a4b3 --- /dev/null +++ b/libc/nt/kernel32/GetSystemDEPPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetSystemDEPPolicy,GetSystemDEPPolicy,734 diff --git a/libc/nt/kernel32/GetSystemPowerStatus.s b/libc/nt/kernel32/GetSystemPowerStatus.s new file mode 100644 index 00000000..ec506798 --- /dev/null +++ b/libc/nt/kernel32/GetSystemPowerStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetSystemPowerStatus,GetSystemPowerStatus,744 diff --git a/libc/nt/kernel32/GetSystemRegistryQuota.s b/libc/nt/kernel32/GetSystemRegistryQuota.s new file mode 100644 index 00000000..84c3d416 --- /dev/null +++ b/libc/nt/kernel32/GetSystemRegistryQuota.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetSystemRegistryQuota,GetSystemRegistryQuota,746 diff --git a/libc/nt/kernel32/GetTapeParameters.s b/libc/nt/kernel32/GetTapeParameters.s new file mode 100644 index 00000000..f10e099d --- /dev/null +++ b/libc/nt/kernel32/GetTapeParameters.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetTapeParameters,GetTapeParameters,756 diff --git a/libc/nt/kernel32/GetTapePosition.s b/libc/nt/kernel32/GetTapePosition.s new file mode 100644 index 00000000..1a3c2008 --- /dev/null +++ b/libc/nt/kernel32/GetTapePosition.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetTapePosition,GetTapePosition,757 diff --git a/libc/nt/kernel32/GetTapeStatus.s b/libc/nt/kernel32/GetTapeStatus.s new file mode 100644 index 00000000..ad1b6c7d --- /dev/null +++ b/libc/nt/kernel32/GetTapeStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetTapeStatus,GetTapeStatus,758 diff --git a/libc/nt/kernel32/GetThreadSelectorEntry.s b/libc/nt/kernel32/GetThreadSelectorEntry.s new file mode 100644 index 00000000..d8fc17d0 --- /dev/null +++ b/libc/nt/kernel32/GetThreadSelectorEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetThreadSelectorEntry,GetThreadSelectorEntry,776 diff --git a/libc/nt/kernel32/GetTimeFormatAWorker.s b/libc/nt/kernel32/GetTimeFormatAWorker.s new file mode 100644 index 00000000..4f55df4c --- /dev/null +++ b/libc/nt/kernel32/GetTimeFormatAWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetTimeFormatAWorker,GetTimeFormatAWorker,782 diff --git a/libc/nt/kernel32/GetTimeFormatWWorker.s b/libc/nt/kernel32/GetTimeFormatWWorker.s new file mode 100644 index 00000000..c1d55dad --- /dev/null +++ b/libc/nt/kernel32/GetTimeFormatWWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetTimeFormatWWorker,GetTimeFormatWWorker,785 diff --git a/libc/nt/kernel32/GetUmsCompletionListEvent.s b/libc/nt/kernel32/GetUmsCompletionListEvent.s new file mode 100644 index 00000000..dc88c3fd --- /dev/null +++ b/libc/nt/kernel32/GetUmsCompletionListEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetUmsCompletionListEvent,GetUmsCompletionListEvent,789 diff --git a/libc/nt/kernel32/GetUmsSystemThreadInformation.s b/libc/nt/kernel32/GetUmsSystemThreadInformation.s new file mode 100644 index 00000000..e71fbe7b --- /dev/null +++ b/libc/nt/kernel32/GetUmsSystemThreadInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetUmsSystemThreadInformation,GetUmsSystemThreadInformation,790 diff --git a/libc/nt/kernel32/GetVDMCurrentDirectories.s b/libc/nt/kernel32/GetVDMCurrentDirectories.s new file mode 100644 index 00000000..91a7fd34 --- /dev/null +++ b/libc/nt/kernel32/GetVDMCurrentDirectories.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetVDMCurrentDirectories,GetVDMCurrentDirectories,798 diff --git a/libc/nt/kernel32/GetVolumeNameForVolumeMountPointA.s b/libc/nt/kernel32/GetVolumeNameForVolumeMountPointA.s new file mode 100644 index 00000000..583f3575 --- /dev/null +++ b/libc/nt/kernel32/GetVolumeNameForVolumeMountPointA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetVolumeNameForVolumeMountPointA,GetVolumeNameForVolumeMountPointA,805 diff --git a/libc/nt/kernel32/GetVolumePathNameA.s b/libc/nt/kernel32/GetVolumePathNameA.s new file mode 100644 index 00000000..b0d5f819 --- /dev/null +++ b/libc/nt/kernel32/GetVolumePathNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetVolumePathNameA,GetVolumePathNameA,807 diff --git a/libc/nt/kernel32/GetVolumePathNamesForVolumeNameA.s b/libc/nt/kernel32/GetVolumePathNamesForVolumeNameA.s new file mode 100644 index 00000000..408aab79 --- /dev/null +++ b/libc/nt/kernel32/GetVolumePathNamesForVolumeNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GetVolumePathNamesForVolumeNameA,GetVolumePathNamesForVolumeNameA,809 diff --git a/libc/nt/kernel32/GlobalAddAtomA.s b/libc/nt/kernel32/GlobalAddAtomA.s new file mode 100644 index 00000000..7c8b3ace --- /dev/null +++ b/libc/nt/kernel32/GlobalAddAtomA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalAddAtomA,GlobalAddAtomA,815 diff --git a/libc/nt/kernel32/GlobalAddAtomExA.s b/libc/nt/kernel32/GlobalAddAtomExA.s new file mode 100644 index 00000000..c12de806 --- /dev/null +++ b/libc/nt/kernel32/GlobalAddAtomExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalAddAtomExA,GlobalAddAtomExA,816 diff --git a/libc/nt/kernel32/GlobalAddAtomExW.s b/libc/nt/kernel32/GlobalAddAtomExW.s new file mode 100644 index 00000000..e542a41d --- /dev/null +++ b/libc/nt/kernel32/GlobalAddAtomExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalAddAtomExW,GlobalAddAtomExW,817 diff --git a/libc/nt/kernel32/GlobalAddAtomW.s b/libc/nt/kernel32/GlobalAddAtomW.s new file mode 100644 index 00000000..0f0ad786 --- /dev/null +++ b/libc/nt/kernel32/GlobalAddAtomW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalAddAtomW,GlobalAddAtomW,818 diff --git a/libc/nt/kernel32/GlobalCompact.s b/libc/nt/kernel32/GlobalCompact.s new file mode 100644 index 00000000..88774551 --- /dev/null +++ b/libc/nt/kernel32/GlobalCompact.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalCompact,GlobalCompact,820 diff --git a/libc/nt/kernel32/GlobalDeleteAtom.s b/libc/nt/kernel32/GlobalDeleteAtom.s new file mode 100644 index 00000000..c1e01cc8 --- /dev/null +++ b/libc/nt/kernel32/GlobalDeleteAtom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalDeleteAtom,GlobalDeleteAtom,821 diff --git a/libc/nt/kernel32/GlobalFindAtomA.s b/libc/nt/kernel32/GlobalFindAtomA.s new file mode 100644 index 00000000..33ab5016 --- /dev/null +++ b/libc/nt/kernel32/GlobalFindAtomA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalFindAtomA,GlobalFindAtomA,822 diff --git a/libc/nt/kernel32/GlobalFindAtomW.s b/libc/nt/kernel32/GlobalFindAtomW.s new file mode 100644 index 00000000..7afed3bf --- /dev/null +++ b/libc/nt/kernel32/GlobalFindAtomW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalFindAtomW,GlobalFindAtomW,823 diff --git a/libc/nt/kernel32/GlobalFix.s b/libc/nt/kernel32/GlobalFix.s new file mode 100644 index 00000000..e3a84b25 --- /dev/null +++ b/libc/nt/kernel32/GlobalFix.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalFix,GlobalFix,824 diff --git a/libc/nt/kernel32/GlobalFlags.s b/libc/nt/kernel32/GlobalFlags.s new file mode 100644 index 00000000..0498af67 --- /dev/null +++ b/libc/nt/kernel32/GlobalFlags.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalFlags,GlobalFlags,825 diff --git a/libc/nt/kernel32/GlobalGetAtomNameA.s b/libc/nt/kernel32/GlobalGetAtomNameA.s new file mode 100644 index 00000000..c29c8bc0 --- /dev/null +++ b/libc/nt/kernel32/GlobalGetAtomNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalGetAtomNameA,GlobalGetAtomNameA,827 diff --git a/libc/nt/kernel32/GlobalGetAtomNameW.s b/libc/nt/kernel32/GlobalGetAtomNameW.s new file mode 100644 index 00000000..068d2018 --- /dev/null +++ b/libc/nt/kernel32/GlobalGetAtomNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalGetAtomNameW,GlobalGetAtomNameW,828 diff --git a/libc/nt/kernel32/GlobalHandle.s b/libc/nt/kernel32/GlobalHandle.s new file mode 100644 index 00000000..bb20f309 --- /dev/null +++ b/libc/nt/kernel32/GlobalHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalHandle,GlobalHandle,829 diff --git a/libc/nt/kernel32/GlobalLock.s b/libc/nt/kernel32/GlobalLock.s new file mode 100644 index 00000000..c7091cb1 --- /dev/null +++ b/libc/nt/kernel32/GlobalLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalLock,GlobalLock,830 diff --git a/libc/nt/kernel32/GlobalMemoryStatus.s b/libc/nt/kernel32/GlobalMemoryStatus.s new file mode 100644 index 00000000..38760f31 --- /dev/null +++ b/libc/nt/kernel32/GlobalMemoryStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalMemoryStatus,GlobalMemoryStatus,831 diff --git a/libc/nt/kernel32/GlobalReAlloc.s b/libc/nt/kernel32/GlobalReAlloc.s new file mode 100644 index 00000000..5a2fe153 --- /dev/null +++ b/libc/nt/kernel32/GlobalReAlloc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalReAlloc,GlobalReAlloc,833 diff --git a/libc/nt/kernel32/GlobalSize.s b/libc/nt/kernel32/GlobalSize.s new file mode 100644 index 00000000..3b5b58f0 --- /dev/null +++ b/libc/nt/kernel32/GlobalSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalSize,GlobalSize,834 diff --git a/libc/nt/kernel32/GlobalUnWire.s b/libc/nt/kernel32/GlobalUnWire.s new file mode 100644 index 00000000..5b0e8bf8 --- /dev/null +++ b/libc/nt/kernel32/GlobalUnWire.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalUnWire,GlobalUnWire,835 diff --git a/libc/nt/kernel32/GlobalUnfix.s b/libc/nt/kernel32/GlobalUnfix.s new file mode 100644 index 00000000..c843dae4 --- /dev/null +++ b/libc/nt/kernel32/GlobalUnfix.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalUnfix,GlobalUnfix,836 diff --git a/libc/nt/kernel32/GlobalUnlock.s b/libc/nt/kernel32/GlobalUnlock.s new file mode 100644 index 00000000..876ec86c --- /dev/null +++ b/libc/nt/kernel32/GlobalUnlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalUnlock,GlobalUnlock,837 diff --git a/libc/nt/kernel32/GlobalWire.s b/libc/nt/kernel32/GlobalWire.s new file mode 100644 index 00000000..e72806b3 --- /dev/null +++ b/libc/nt/kernel32/GlobalWire.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_GlobalWire,GlobalWire,838 diff --git a/libc/nt/kernel32/Heap32First.s b/libc/nt/kernel32/Heap32First.s new file mode 100644 index 00000000..a7c6486a --- /dev/null +++ b/libc/nt/kernel32/Heap32First.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_Heap32First,Heap32First,839 diff --git a/libc/nt/kernel32/Heap32ListFirst.s b/libc/nt/kernel32/Heap32ListFirst.s new file mode 100644 index 00000000..6fe106b7 --- /dev/null +++ b/libc/nt/kernel32/Heap32ListFirst.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_Heap32ListFirst,Heap32ListFirst,840 diff --git a/libc/nt/kernel32/Heap32ListNext.s b/libc/nt/kernel32/Heap32ListNext.s new file mode 100644 index 00000000..3f06b9d5 --- /dev/null +++ b/libc/nt/kernel32/Heap32ListNext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_Heap32ListNext,Heap32ListNext,841 diff --git a/libc/nt/kernel32/Heap32Next.s b/libc/nt/kernel32/Heap32Next.s new file mode 100644 index 00000000..406c6234 --- /dev/null +++ b/libc/nt/kernel32/Heap32Next.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_Heap32Next,Heap32Next,842 diff --git a/libc/nt/kernel32/HeapFree.s b/libc/nt/kernel32/HeapFree.s new file mode 100644 index 00000000..138e1927 --- /dev/null +++ b/libc/nt/kernel32/HeapFree.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_HeapFree,HeapFree,847 diff --git a/libc/nt/kernel32/InitAtomTable.s b/libc/nt/kernel32/InitAtomTable.s new file mode 100644 index 00000000..e5c88d85 --- /dev/null +++ b/libc/nt/kernel32/InitAtomTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_InitAtomTable,InitAtomTable,860 diff --git a/libc/nt/kernel32/InvalidateConsoleDIBits.s b/libc/nt/kernel32/InvalidateConsoleDIBits.s new file mode 100644 index 00000000..9105d31a --- /dev/null +++ b/libc/nt/kernel32/InvalidateConsoleDIBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_InvalidateConsoleDIBits,InvalidateConsoleDIBits,881 diff --git a/libc/nt/kernel32/IsBadCodePtr.s b/libc/nt/kernel32/IsBadCodePtr.s new file mode 100644 index 00000000..0ab794f5 --- /dev/null +++ b/libc/nt/kernel32/IsBadCodePtr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_IsBadCodePtr,IsBadCodePtr,882 diff --git a/libc/nt/kernel32/IsBadHugeReadPtr.s b/libc/nt/kernel32/IsBadHugeReadPtr.s new file mode 100644 index 00000000..368f2641 --- /dev/null +++ b/libc/nt/kernel32/IsBadHugeReadPtr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_IsBadHugeReadPtr,IsBadHugeReadPtr,883 diff --git a/libc/nt/kernel32/IsBadHugeWritePtr.s b/libc/nt/kernel32/IsBadHugeWritePtr.s new file mode 100644 index 00000000..89eee774 --- /dev/null +++ b/libc/nt/kernel32/IsBadHugeWritePtr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_IsBadHugeWritePtr,IsBadHugeWritePtr,884 diff --git a/libc/nt/kernel32/IsBadReadPtr.s b/libc/nt/kernel32/IsBadReadPtr.s new file mode 100644 index 00000000..70ea6e8d --- /dev/null +++ b/libc/nt/kernel32/IsBadReadPtr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_IsBadReadPtr,IsBadReadPtr,885 diff --git a/libc/nt/kernel32/IsBadStringPtrA.s b/libc/nt/kernel32/IsBadStringPtrA.s new file mode 100644 index 00000000..c32eea76 --- /dev/null +++ b/libc/nt/kernel32/IsBadStringPtrA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_IsBadStringPtrA,IsBadStringPtrA,886 diff --git a/libc/nt/kernel32/IsBadStringPtrW.s b/libc/nt/kernel32/IsBadStringPtrW.s new file mode 100644 index 00000000..745b3a24 --- /dev/null +++ b/libc/nt/kernel32/IsBadStringPtrW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_IsBadStringPtrW,IsBadStringPtrW,887 diff --git a/libc/nt/kernel32/IsBadWritePtr.s b/libc/nt/kernel32/IsBadWritePtr.s new file mode 100644 index 00000000..b85d5406 --- /dev/null +++ b/libc/nt/kernel32/IsBadWritePtr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_IsBadWritePtr,IsBadWritePtr,888 diff --git a/libc/nt/kernel32/IsCalendarLeapDay.s b/libc/nt/kernel32/IsCalendarLeapDay.s new file mode 100644 index 00000000..504c4741 --- /dev/null +++ b/libc/nt/kernel32/IsCalendarLeapDay.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_IsCalendarLeapDay,IsCalendarLeapDay,889 diff --git a/libc/nt/kernel32/IsCalendarLeapMonth.s b/libc/nt/kernel32/IsCalendarLeapMonth.s new file mode 100644 index 00000000..19040869 --- /dev/null +++ b/libc/nt/kernel32/IsCalendarLeapMonth.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_IsCalendarLeapMonth,IsCalendarLeapMonth,890 diff --git a/libc/nt/kernel32/IsCalendarLeapYear.s b/libc/nt/kernel32/IsCalendarLeapYear.s new file mode 100644 index 00000000..77dbea8a --- /dev/null +++ b/libc/nt/kernel32/IsCalendarLeapYear.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_IsCalendarLeapYear,IsCalendarLeapYear,891 diff --git a/libc/nt/kernel32/IsNativeVhdBoot.s b/libc/nt/kernel32/IsNativeVhdBoot.s new file mode 100644 index 00000000..7c129a5f --- /dev/null +++ b/libc/nt/kernel32/IsNativeVhdBoot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_IsNativeVhdBoot,IsNativeVhdBoot,897 diff --git a/libc/nt/kernel32/IsSystemResumeAutomatic.s b/libc/nt/kernel32/IsSystemResumeAutomatic.s new file mode 100644 index 00000000..535d12ae --- /dev/null +++ b/libc/nt/kernel32/IsSystemResumeAutomatic.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_IsSystemResumeAutomatic,IsSystemResumeAutomatic,902 diff --git a/libc/nt/kernel32/IsValidCalDateTime.s b/libc/nt/kernel32/IsValidCalDateTime.s new file mode 100644 index 00000000..9523d7e8 --- /dev/null +++ b/libc/nt/kernel32/IsValidCalDateTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_IsValidCalDateTime,IsValidCalDateTime,905 diff --git a/libc/nt/kernel32/LZClose.s b/libc/nt/kernel32/LZClose.s new file mode 100644 index 00000000..21569df9 --- /dev/null +++ b/libc/nt/kernel32/LZClose.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LZClose,LZClose,945 diff --git a/libc/nt/kernel32/LZCloseFile.s b/libc/nt/kernel32/LZCloseFile.s new file mode 100644 index 00000000..153fa385 --- /dev/null +++ b/libc/nt/kernel32/LZCloseFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LZCloseFile,LZCloseFile,946 diff --git a/libc/nt/kernel32/LZCopy.s b/libc/nt/kernel32/LZCopy.s new file mode 100644 index 00000000..41f1b1bd --- /dev/null +++ b/libc/nt/kernel32/LZCopy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LZCopy,LZCopy,947 diff --git a/libc/nt/kernel32/LZCreateFileW.s b/libc/nt/kernel32/LZCreateFileW.s new file mode 100644 index 00000000..dc328c28 --- /dev/null +++ b/libc/nt/kernel32/LZCreateFileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LZCreateFileW,LZCreateFileW,948 diff --git a/libc/nt/kernel32/LZDone.s b/libc/nt/kernel32/LZDone.s new file mode 100644 index 00000000..90468a7b --- /dev/null +++ b/libc/nt/kernel32/LZDone.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LZDone,LZDone,949 diff --git a/libc/nt/kernel32/LZInit.s b/libc/nt/kernel32/LZInit.s new file mode 100644 index 00000000..57171121 --- /dev/null +++ b/libc/nt/kernel32/LZInit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LZInit,LZInit,950 diff --git a/libc/nt/kernel32/LZOpenFileA.s b/libc/nt/kernel32/LZOpenFileA.s new file mode 100644 index 00000000..1dc33774 --- /dev/null +++ b/libc/nt/kernel32/LZOpenFileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LZOpenFileA,LZOpenFileA,951 diff --git a/libc/nt/kernel32/LZOpenFileW.s b/libc/nt/kernel32/LZOpenFileW.s new file mode 100644 index 00000000..a940e7a1 --- /dev/null +++ b/libc/nt/kernel32/LZOpenFileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LZOpenFileW,LZOpenFileW,952 diff --git a/libc/nt/kernel32/LZRead.s b/libc/nt/kernel32/LZRead.s new file mode 100644 index 00000000..e5e9454e --- /dev/null +++ b/libc/nt/kernel32/LZRead.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LZRead,LZRead,953 diff --git a/libc/nt/kernel32/LZSeek.s b/libc/nt/kernel32/LZSeek.s new file mode 100644 index 00000000..2e1b5788 --- /dev/null +++ b/libc/nt/kernel32/LZSeek.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LZSeek,LZSeek,954 diff --git a/libc/nt/kernel32/LZStart.s b/libc/nt/kernel32/LZStart.s new file mode 100644 index 00000000..c3c0147a --- /dev/null +++ b/libc/nt/kernel32/LZStart.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LZStart,LZStart,955 diff --git a/libc/nt/kernel32/LoadModule.s b/libc/nt/kernel32/LoadModule.s new file mode 100644 index 00000000..16e05eee --- /dev/null +++ b/libc/nt/kernel32/LoadModule.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LoadModule,LoadModule,964 diff --git a/libc/nt/kernel32/LoadStringBaseW.s b/libc/nt/kernel32/LoadStringBaseW.s new file mode 100644 index 00000000..2a3ac4a5 --- /dev/null +++ b/libc/nt/kernel32/LoadStringBaseW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LoadStringBaseW,LoadStringBaseW,968 diff --git a/libc/nt/kernel32/LocalCompact.s b/libc/nt/kernel32/LocalCompact.s new file mode 100644 index 00000000..ee8be2fa --- /dev/null +++ b/libc/nt/kernel32/LocalCompact.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LocalCompact,LocalCompact,970 diff --git a/libc/nt/kernel32/LocalFlags.s b/libc/nt/kernel32/LocalFlags.s new file mode 100644 index 00000000..2cca7b2f --- /dev/null +++ b/libc/nt/kernel32/LocalFlags.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LocalFlags,LocalFlags,972 diff --git a/libc/nt/kernel32/LocalHandle.s b/libc/nt/kernel32/LocalHandle.s new file mode 100644 index 00000000..1c4545d6 --- /dev/null +++ b/libc/nt/kernel32/LocalHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LocalHandle,LocalHandle,974 diff --git a/libc/nt/kernel32/LocalShrink.s b/libc/nt/kernel32/LocalShrink.s new file mode 100644 index 00000000..412eaf1e --- /dev/null +++ b/libc/nt/kernel32/LocalShrink.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LocalShrink,LocalShrink,977 diff --git a/libc/nt/kernel32/LocalSize.s b/libc/nt/kernel32/LocalSize.s new file mode 100644 index 00000000..6354583a --- /dev/null +++ b/libc/nt/kernel32/LocalSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_LocalSize,LocalSize,978 diff --git a/libc/nt/kernel32/MapUserPhysicalPagesScatter.s b/libc/nt/kernel32/MapUserPhysicalPagesScatter.s new file mode 100644 index 00000000..431df096 --- /dev/null +++ b/libc/nt/kernel32/MapUserPhysicalPagesScatter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_MapUserPhysicalPagesScatter,MapUserPhysicalPagesScatter,986 diff --git a/libc/nt/kernel32/Module32FirstW.s b/libc/nt/kernel32/Module32FirstW.s new file mode 100644 index 00000000..722b8c57 --- /dev/null +++ b/libc/nt/kernel32/Module32FirstW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_Module32FirstW,Module32FirstW,992 diff --git a/libc/nt/kernel32/Module32NextW.s b/libc/nt/kernel32/Module32NextW.s new file mode 100644 index 00000000..3fd9eae6 --- /dev/null +++ b/libc/nt/kernel32/Module32NextW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_Module32NextW,Module32NextW,994 diff --git a/libc/nt/kernel32/MoveFileA.s b/libc/nt/kernel32/MoveFileA.s new file mode 100644 index 00000000..0ff43782 --- /dev/null +++ b/libc/nt/kernel32/MoveFileA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_MoveFileA,MoveFileA,995 + + .text.windows +MoveFileA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_MoveFileA(%rip),%rax + jmp __sysv2nt + .endfn MoveFileA,globl + .previous diff --git a/libc/nt/kernel32/MoveFileExA.s b/libc/nt/kernel32/MoveFileExA.s new file mode 100644 index 00000000..a8ac033b --- /dev/null +++ b/libc/nt/kernel32/MoveFileExA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_MoveFileExA,MoveFileExA,996 + + .text.windows +MoveFileExA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_MoveFileExA(%rip),%rax + jmp __sysv2nt + .endfn MoveFileExA,globl + .previous diff --git a/libc/nt/kernel32/MoveFileTransactedA.s b/libc/nt/kernel32/MoveFileTransactedA.s new file mode 100644 index 00000000..1f8bece9 --- /dev/null +++ b/libc/nt/kernel32/MoveFileTransactedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_MoveFileTransactedA,MoveFileTransactedA,998 diff --git a/libc/nt/kernel32/MoveFileTransactedW.s b/libc/nt/kernel32/MoveFileTransactedW.s new file mode 100644 index 00000000..fa70b677 --- /dev/null +++ b/libc/nt/kernel32/MoveFileTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_MoveFileTransactedW,MoveFileTransactedW,999 diff --git a/libc/nt/kernel32/MoveFileW.s b/libc/nt/kernel32/MoveFileW.s new file mode 100644 index 00000000..ebcfa703 --- /dev/null +++ b/libc/nt/kernel32/MoveFileW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_MoveFileW,MoveFileW,1000 + + .text.windows +MoveFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_MoveFileW(%rip),%rax + jmp __sysv2nt + .endfn MoveFile,globl + .previous diff --git a/libc/nt/kernel32/MoveFileWithProgressA.s b/libc/nt/kernel32/MoveFileWithProgressA.s new file mode 100644 index 00000000..3ee49cda --- /dev/null +++ b/libc/nt/kernel32/MoveFileWithProgressA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_MoveFileWithProgressA,MoveFileWithProgressA,1001 diff --git a/libc/nt/kernel32/NotifyUILanguageChange.s b/libc/nt/kernel32/NotifyUILanguageChange.s new file mode 100644 index 00000000..f6a4f282 --- /dev/null +++ b/libc/nt/kernel32/NotifyUILanguageChange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_NotifyUILanguageChange,NotifyUILanguageChange,1015 diff --git a/libc/nt/kernel32/NtVdm64CreateProcessInternalW.s b/libc/nt/kernel32/NtVdm64CreateProcessInternalW.s new file mode 100644 index 00000000..4813ef88 --- /dev/null +++ b/libc/nt/kernel32/NtVdm64CreateProcessInternalW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_NtVdm64CreateProcessInternalW,NtVdm64CreateProcessInternalW,1016 diff --git a/libc/nt/kernel32/OOBEComplete.s b/libc/nt/kernel32/OOBEComplete.s new file mode 100644 index 00000000..1d05c264 --- /dev/null +++ b/libc/nt/kernel32/OOBEComplete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_OOBEComplete,OOBEComplete,1017 diff --git a/libc/nt/kernel32/OpenConsoleW.s b/libc/nt/kernel32/OpenConsoleW.s new file mode 100644 index 00000000..7d10849c --- /dev/null +++ b/libc/nt/kernel32/OpenConsoleW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_OpenConsoleW,OpenConsoleW,1019 diff --git a/libc/nt/kernel32/OpenConsoleWStub.s b/libc/nt/kernel32/OpenConsoleWStub.s new file mode 100644 index 00000000..e33ea7b9 --- /dev/null +++ b/libc/nt/kernel32/OpenConsoleWStub.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_OpenConsoleWStub,OpenConsoleWStub,1020 diff --git a/libc/nt/kernel32/OpenFile.s b/libc/nt/kernel32/OpenFile.s new file mode 100644 index 00000000..9cb7cfc2 --- /dev/null +++ b/libc/nt/kernel32/OpenFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_OpenFile,OpenFile,1023 diff --git a/libc/nt/kernel32/OpenFileMappingA.s b/libc/nt/kernel32/OpenFileMappingA.s new file mode 100644 index 00000000..a029381b --- /dev/null +++ b/libc/nt/kernel32/OpenFileMappingA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_OpenFileMappingA,OpenFileMappingA,1025 diff --git a/libc/nt/kernel32/OpenJobObjectA.s b/libc/nt/kernel32/OpenJobObjectA.s new file mode 100644 index 00000000..d42a5ecb --- /dev/null +++ b/libc/nt/kernel32/OpenJobObjectA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_OpenJobObjectA,OpenJobObjectA,1027 diff --git a/libc/nt/kernel32/OpenJobObjectW.s b/libc/nt/kernel32/OpenJobObjectW.s new file mode 100644 index 00000000..2d156ceb --- /dev/null +++ b/libc/nt/kernel32/OpenJobObjectW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_OpenJobObjectW,OpenJobObjectW,1028 diff --git a/libc/nt/kernel32/OpenMutexA.s b/libc/nt/kernel32/OpenMutexA.s new file mode 100644 index 00000000..c4991b12 --- /dev/null +++ b/libc/nt/kernel32/OpenMutexA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_OpenMutexA,OpenMutexA,1029 diff --git a/libc/nt/kernel32/OpenPrivateNamespaceA.s b/libc/nt/kernel32/OpenPrivateNamespaceA.s new file mode 100644 index 00000000..bb200b78 --- /dev/null +++ b/libc/nt/kernel32/OpenPrivateNamespaceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_OpenPrivateNamespaceA,OpenPrivateNamespaceA,1032 diff --git a/libc/nt/kernel32/OpenProfileUserMapping.s b/libc/nt/kernel32/OpenProfileUserMapping.s new file mode 100644 index 00000000..f6b336c8 --- /dev/null +++ b/libc/nt/kernel32/OpenProfileUserMapping.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_OpenProfileUserMapping,OpenProfileUserMapping,1036 diff --git a/libc/nt/kernel32/OpenSemaphoreA.s b/libc/nt/kernel32/OpenSemaphoreA.s new file mode 100644 index 00000000..d7266ad7 --- /dev/null +++ b/libc/nt/kernel32/OpenSemaphoreA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_OpenSemaphoreA,OpenSemaphoreA,1037 diff --git a/libc/nt/kernel32/OpenWaitableTimerA.s b/libc/nt/kernel32/OpenWaitableTimerA.s new file mode 100644 index 00000000..7714b7be --- /dev/null +++ b/libc/nt/kernel32/OpenWaitableTimerA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_OpenWaitableTimerA,OpenWaitableTimerA,1043 diff --git a/libc/nt/kernel32/PowerClearRequest.s b/libc/nt/kernel32/PowerClearRequest.s new file mode 100644 index 00000000..b930dbfb --- /dev/null +++ b/libc/nt/kernel32/PowerClearRequest.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_PowerClearRequest,PowerClearRequest,1057 diff --git a/libc/nt/kernel32/PowerCreateRequest.s b/libc/nt/kernel32/PowerCreateRequest.s new file mode 100644 index 00000000..97b65702 --- /dev/null +++ b/libc/nt/kernel32/PowerCreateRequest.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_PowerCreateRequest,PowerCreateRequest,1058 diff --git a/libc/nt/kernel32/PowerSetRequest.s b/libc/nt/kernel32/PowerSetRequest.s new file mode 100644 index 00000000..f6ea0fb7 --- /dev/null +++ b/libc/nt/kernel32/PowerSetRequest.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_PowerSetRequest,PowerSetRequest,1059 diff --git a/libc/nt/kernel32/PrepareTape.s b/libc/nt/kernel32/PrepareTape.s new file mode 100644 index 00000000..d44e3da8 --- /dev/null +++ b/libc/nt/kernel32/PrepareTape.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_PrepareTape,PrepareTape,1061 diff --git a/libc/nt/kernel32/PrivMoveFileIdentityW.s b/libc/nt/kernel32/PrivMoveFileIdentityW.s new file mode 100644 index 00000000..1ea78ff1 --- /dev/null +++ b/libc/nt/kernel32/PrivMoveFileIdentityW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_PrivMoveFileIdentityW,PrivMoveFileIdentityW,1063 diff --git a/libc/nt/kernel32/Process32FirstW.s b/libc/nt/kernel32/Process32FirstW.s new file mode 100644 index 00000000..b8408bce --- /dev/null +++ b/libc/nt/kernel32/Process32FirstW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_Process32FirstW,Process32FirstW,1065 diff --git a/libc/nt/kernel32/Process32NextW.s b/libc/nt/kernel32/Process32NextW.s new file mode 100644 index 00000000..aa49537b --- /dev/null +++ b/libc/nt/kernel32/Process32NextW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_Process32NextW,Process32NextW,1067 diff --git a/libc/nt/kernel32/PssWalkMarkerRewind.s b/libc/nt/kernel32/PssWalkMarkerRewind.s new file mode 100644 index 00000000..c8f6fe6e --- /dev/null +++ b/libc/nt/kernel32/PssWalkMarkerRewind.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_PssWalkMarkerRewind,PssWalkMarkerRewind,1076 diff --git a/libc/nt/kernel32/PssWalkMarkerSeek.s b/libc/nt/kernel32/PssWalkMarkerSeek.s new file mode 100644 index 00000000..88770c0c --- /dev/null +++ b/libc/nt/kernel32/PssWalkMarkerSeek.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_PssWalkMarkerSeek,PssWalkMarkerSeek,1077 diff --git a/libc/nt/kernel32/PssWalkMarkerTell.s b/libc/nt/kernel32/PssWalkMarkerTell.s new file mode 100644 index 00000000..89fbbb82 --- /dev/null +++ b/libc/nt/kernel32/PssWalkMarkerTell.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_PssWalkMarkerTell,PssWalkMarkerTell,1080 diff --git a/libc/nt/kernel32/QueryActCtxSettingsWWorker.s b/libc/nt/kernel32/QueryActCtxSettingsWWorker.s new file mode 100644 index 00000000..fa57a840 --- /dev/null +++ b/libc/nt/kernel32/QueryActCtxSettingsWWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QueryActCtxSettingsWWorker,QueryActCtxSettingsWWorker,1085 diff --git a/libc/nt/kernel32/QueryActCtxWWorker.s b/libc/nt/kernel32/QueryActCtxWWorker.s new file mode 100644 index 00000000..6c6f61d2 --- /dev/null +++ b/libc/nt/kernel32/QueryActCtxWWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QueryActCtxWWorker,QueryActCtxWWorker,1087 diff --git a/libc/nt/kernel32/QueryDosDeviceA.s b/libc/nt/kernel32/QueryDosDeviceA.s new file mode 100644 index 00000000..9dd3f7ad --- /dev/null +++ b/libc/nt/kernel32/QueryDosDeviceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QueryDosDeviceA,QueryDosDeviceA,1089 diff --git a/libc/nt/kernel32/QueryInformationJobObject.s b/libc/nt/kernel32/QueryInformationJobObject.s new file mode 100644 index 00000000..d75d627b --- /dev/null +++ b/libc/nt/kernel32/QueryInformationJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QueryInformationJobObject,QueryInformationJobObject,1095 diff --git a/libc/nt/kernel32/QueryIoRateControlInformationJobObject.s b/libc/nt/kernel32/QueryIoRateControlInformationJobObject.s new file mode 100644 index 00000000..0cb8e7ac --- /dev/null +++ b/libc/nt/kernel32/QueryIoRateControlInformationJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QueryIoRateControlInformationJobObject,QueryIoRateControlInformationJobObject,1096 diff --git a/libc/nt/kernel32/QueryPerformanceCounter.s b/libc/nt/kernel32/QueryPerformanceCounter.s new file mode 100644 index 00000000..e2912a3d --- /dev/null +++ b/libc/nt/kernel32/QueryPerformanceCounter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QueryPerformanceCounter,QueryPerformanceCounter,1098 diff --git a/libc/nt/kernel32/QueryPerformanceFrequency.s b/libc/nt/kernel32/QueryPerformanceFrequency.s new file mode 100644 index 00000000..c15c6f37 --- /dev/null +++ b/libc/nt/kernel32/QueryPerformanceFrequency.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QueryPerformanceFrequency,QueryPerformanceFrequency,1099 diff --git a/libc/nt/kernel32/QueryThreadProfiling.s b/libc/nt/kernel32/QueryThreadProfiling.s new file mode 100644 index 00000000..bfd633ec --- /dev/null +++ b/libc/nt/kernel32/QueryThreadProfiling.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QueryThreadProfiling,QueryThreadProfiling,1104 diff --git a/libc/nt/kernel32/QueryUmsThreadInformation.s b/libc/nt/kernel32/QueryUmsThreadInformation.s new file mode 100644 index 00000000..527e8371 --- /dev/null +++ b/libc/nt/kernel32/QueryUmsThreadInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QueryUmsThreadInformation,QueryUmsThreadInformation,1106 diff --git a/libc/nt/kernel32/QueryUnbiasedInterruptTime.s b/libc/nt/kernel32/QueryUnbiasedInterruptTime.s new file mode 100644 index 00000000..20fc3105 --- /dev/null +++ b/libc/nt/kernel32/QueryUnbiasedInterruptTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QueryUnbiasedInterruptTime,QueryUnbiasedInterruptTime,1107 diff --git a/libc/nt/kernel32/QuirkGetData2Worker.s b/libc/nt/kernel32/QuirkGetData2Worker.s new file mode 100644 index 00000000..9c2fbe55 --- /dev/null +++ b/libc/nt/kernel32/QuirkGetData2Worker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QuirkGetData2Worker,QuirkGetData2Worker,1110 diff --git a/libc/nt/kernel32/QuirkGetDataWorker.s b/libc/nt/kernel32/QuirkGetDataWorker.s new file mode 100644 index 00000000..e5754833 --- /dev/null +++ b/libc/nt/kernel32/QuirkGetDataWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QuirkGetDataWorker,QuirkGetDataWorker,1111 diff --git a/libc/nt/kernel32/QuirkIsEnabled2Worker.s b/libc/nt/kernel32/QuirkIsEnabled2Worker.s new file mode 100644 index 00000000..393f284c --- /dev/null +++ b/libc/nt/kernel32/QuirkIsEnabled2Worker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QuirkIsEnabled2Worker,QuirkIsEnabled2Worker,1112 diff --git a/libc/nt/kernel32/QuirkIsEnabled3Worker.s b/libc/nt/kernel32/QuirkIsEnabled3Worker.s new file mode 100644 index 00000000..e7e3c66d --- /dev/null +++ b/libc/nt/kernel32/QuirkIsEnabled3Worker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QuirkIsEnabled3Worker,QuirkIsEnabled3Worker,1113 diff --git a/libc/nt/kernel32/QuirkIsEnabledForPackage2Worker.s b/libc/nt/kernel32/QuirkIsEnabledForPackage2Worker.s new file mode 100644 index 00000000..e2ba96d6 --- /dev/null +++ b/libc/nt/kernel32/QuirkIsEnabledForPackage2Worker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QuirkIsEnabledForPackage2Worker,QuirkIsEnabledForPackage2Worker,1114 diff --git a/libc/nt/kernel32/QuirkIsEnabledForPackage3Worker.s b/libc/nt/kernel32/QuirkIsEnabledForPackage3Worker.s new file mode 100644 index 00000000..058674c6 --- /dev/null +++ b/libc/nt/kernel32/QuirkIsEnabledForPackage3Worker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QuirkIsEnabledForPackage3Worker,QuirkIsEnabledForPackage3Worker,1115 diff --git a/libc/nt/kernel32/QuirkIsEnabledForPackage4Worker.s b/libc/nt/kernel32/QuirkIsEnabledForPackage4Worker.s new file mode 100644 index 00000000..e1318444 --- /dev/null +++ b/libc/nt/kernel32/QuirkIsEnabledForPackage4Worker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QuirkIsEnabledForPackage4Worker,QuirkIsEnabledForPackage4Worker,1116 diff --git a/libc/nt/kernel32/QuirkIsEnabledForPackageWorker.s b/libc/nt/kernel32/QuirkIsEnabledForPackageWorker.s new file mode 100644 index 00000000..3d6f0fee --- /dev/null +++ b/libc/nt/kernel32/QuirkIsEnabledForPackageWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QuirkIsEnabledForPackageWorker,QuirkIsEnabledForPackageWorker,1117 diff --git a/libc/nt/kernel32/QuirkIsEnabledForProcessWorker.s b/libc/nt/kernel32/QuirkIsEnabledForProcessWorker.s new file mode 100644 index 00000000..a9726920 --- /dev/null +++ b/libc/nt/kernel32/QuirkIsEnabledForProcessWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QuirkIsEnabledForProcessWorker,QuirkIsEnabledForProcessWorker,1118 diff --git a/libc/nt/kernel32/QuirkIsEnabledWorker.s b/libc/nt/kernel32/QuirkIsEnabledWorker.s new file mode 100644 index 00000000..8ecffb67 --- /dev/null +++ b/libc/nt/kernel32/QuirkIsEnabledWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_QuirkIsEnabledWorker,QuirkIsEnabledWorker,1119 diff --git a/libc/nt/kernel32/RaiseInvalid16BitExeError.s b/libc/nt/kernel32/RaiseInvalid16BitExeError.s new file mode 100644 index 00000000..288cd71a --- /dev/null +++ b/libc/nt/kernel32/RaiseInvalid16BitExeError.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RaiseInvalid16BitExeError,RaiseInvalid16BitExeError,1122 diff --git a/libc/nt/kernel32/ReadThreadProfilingData.s b/libc/nt/kernel32/ReadThreadProfilingData.s new file mode 100644 index 00000000..59cbe98d --- /dev/null +++ b/libc/nt/kernel32/ReadThreadProfilingData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_ReadThreadProfilingData,ReadThreadProfilingData,1141 diff --git a/libc/nt/kernel32/RegisterApplicationRecoveryCallback.s b/libc/nt/kernel32/RegisterApplicationRecoveryCallback.s new file mode 100644 index 00000000..065b7f87 --- /dev/null +++ b/libc/nt/kernel32/RegisterApplicationRecoveryCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RegisterApplicationRecoveryCallback,RegisterApplicationRecoveryCallback,1184 diff --git a/libc/nt/kernel32/RegisterApplicationRestart.s b/libc/nt/kernel32/RegisterApplicationRestart.s new file mode 100644 index 00000000..08b97513 --- /dev/null +++ b/libc/nt/kernel32/RegisterApplicationRestart.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RegisterApplicationRestart,RegisterApplicationRestart,1185 diff --git a/libc/nt/kernel32/RegisterConsoleIME.s b/libc/nt/kernel32/RegisterConsoleIME.s new file mode 100644 index 00000000..815edc11 --- /dev/null +++ b/libc/nt/kernel32/RegisterConsoleIME.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RegisterConsoleIME,RegisterConsoleIME,1187 diff --git a/libc/nt/kernel32/RegisterConsoleOS2.s b/libc/nt/kernel32/RegisterConsoleOS2.s new file mode 100644 index 00000000..8c93d179 --- /dev/null +++ b/libc/nt/kernel32/RegisterConsoleOS2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RegisterConsoleOS2,RegisterConsoleOS2,1188 diff --git a/libc/nt/kernel32/RegisterConsoleVDM.s b/libc/nt/kernel32/RegisterConsoleVDM.s new file mode 100644 index 00000000..68b50cdf --- /dev/null +++ b/libc/nt/kernel32/RegisterConsoleVDM.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RegisterConsoleVDM,RegisterConsoleVDM,1189 diff --git a/libc/nt/kernel32/RegisterWaitForInputIdle.s b/libc/nt/kernel32/RegisterWaitForInputIdle.s new file mode 100644 index 00000000..97a027f5 --- /dev/null +++ b/libc/nt/kernel32/RegisterWaitForInputIdle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RegisterWaitForInputIdle,RegisterWaitForInputIdle,1190 diff --git a/libc/nt/kernel32/RegisterWaitForSingleObject.s b/libc/nt/kernel32/RegisterWaitForSingleObject.s new file mode 100644 index 00000000..0a36627d --- /dev/null +++ b/libc/nt/kernel32/RegisterWaitForSingleObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RegisterWaitForSingleObject,RegisterWaitForSingleObject,1191 diff --git a/libc/nt/kernel32/RegisterWaitUntilOOBECompleted.s b/libc/nt/kernel32/RegisterWaitUntilOOBECompleted.s new file mode 100644 index 00000000..2f519144 --- /dev/null +++ b/libc/nt/kernel32/RegisterWaitUntilOOBECompleted.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RegisterWaitUntilOOBECompleted,RegisterWaitUntilOOBECompleted,1193 diff --git a/libc/nt/kernel32/RegisterWowBaseHandlers.s b/libc/nt/kernel32/RegisterWowBaseHandlers.s new file mode 100644 index 00000000..7079af9c --- /dev/null +++ b/libc/nt/kernel32/RegisterWowBaseHandlers.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RegisterWowBaseHandlers,RegisterWowBaseHandlers,1194 diff --git a/libc/nt/kernel32/RegisterWowExec.s b/libc/nt/kernel32/RegisterWowExec.s new file mode 100644 index 00000000..d461ddb2 --- /dev/null +++ b/libc/nt/kernel32/RegisterWowExec.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RegisterWowExec,RegisterWowExec,1195 diff --git a/libc/nt/kernel32/ReleaseActCtxWorker.s b/libc/nt/kernel32/ReleaseActCtxWorker.s new file mode 100644 index 00000000..213d4729 --- /dev/null +++ b/libc/nt/kernel32/ReleaseActCtxWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_ReleaseActCtxWorker,ReleaseActCtxWorker,1197 diff --git a/libc/nt/kernel32/RemoveDirectoryTransactedA.s b/libc/nt/kernel32/RemoveDirectoryTransactedA.s new file mode 100644 index 00000000..3a780a39 --- /dev/null +++ b/libc/nt/kernel32/RemoveDirectoryTransactedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RemoveDirectoryTransactedA,RemoveDirectoryTransactedA,1205 diff --git a/libc/nt/kernel32/RemoveDirectoryTransactedW.s b/libc/nt/kernel32/RemoveDirectoryTransactedW.s new file mode 100644 index 00000000..e0f9c2d6 --- /dev/null +++ b/libc/nt/kernel32/RemoveDirectoryTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RemoveDirectoryTransactedW,RemoveDirectoryTransactedW,1206 diff --git a/libc/nt/kernel32/RemoveLocalAlternateComputerNameA.s b/libc/nt/kernel32/RemoveLocalAlternateComputerNameA.s new file mode 100644 index 00000000..ee7ea1be --- /dev/null +++ b/libc/nt/kernel32/RemoveLocalAlternateComputerNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RemoveLocalAlternateComputerNameA,RemoveLocalAlternateComputerNameA,1209 diff --git a/libc/nt/kernel32/RemoveLocalAlternateComputerNameW.s b/libc/nt/kernel32/RemoveLocalAlternateComputerNameW.s new file mode 100644 index 00000000..b62592ea --- /dev/null +++ b/libc/nt/kernel32/RemoveLocalAlternateComputerNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RemoveLocalAlternateComputerNameW,RemoveLocalAlternateComputerNameW,1210 diff --git a/libc/nt/kernel32/RemoveSecureMemoryCacheCallback.s b/libc/nt/kernel32/RemoveSecureMemoryCacheCallback.s new file mode 100644 index 00000000..e35f8197 --- /dev/null +++ b/libc/nt/kernel32/RemoveSecureMemoryCacheCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RemoveSecureMemoryCacheCallback,RemoveSecureMemoryCacheCallback,1211 diff --git a/libc/nt/kernel32/ReplaceFileA.s b/libc/nt/kernel32/ReplaceFileA.s new file mode 100644 index 00000000..57c02ea2 --- /dev/null +++ b/libc/nt/kernel32/ReplaceFileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_ReplaceFileA,ReplaceFileA,1215 diff --git a/libc/nt/kernel32/ReplacePartitionUnit.s b/libc/nt/kernel32/ReplacePartitionUnit.s new file mode 100644 index 00000000..606d01c1 --- /dev/null +++ b/libc/nt/kernel32/ReplacePartitionUnit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_ReplacePartitionUnit,ReplacePartitionUnit,1217 diff --git a/libc/nt/kernel32/RequestDeviceWakeup.s b/libc/nt/kernel32/RequestDeviceWakeup.s new file mode 100644 index 00000000..1dbc5bd8 --- /dev/null +++ b/libc/nt/kernel32/RequestDeviceWakeup.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RequestDeviceWakeup,RequestDeviceWakeup,1218 diff --git a/libc/nt/kernel32/RequestWakeupLatency.s b/libc/nt/kernel32/RequestWakeupLatency.s new file mode 100644 index 00000000..ff450674 --- /dev/null +++ b/libc/nt/kernel32/RequestWakeupLatency.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_RequestWakeupLatency,RequestWakeupLatency,1219 diff --git a/libc/nt/kernel32/SetCalendarInfoA.s b/libc/nt/kernel32/SetCalendarInfoA.s new file mode 100644 index 00000000..5fc5ea2c --- /dev/null +++ b/libc/nt/kernel32/SetCalendarInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetCalendarInfoA,SetCalendarInfoA,1249 diff --git a/libc/nt/kernel32/SetComPlusPackageInstallStatus.s b/libc/nt/kernel32/SetComPlusPackageInstallStatus.s new file mode 100644 index 00000000..15c94c11 --- /dev/null +++ b/libc/nt/kernel32/SetComPlusPackageInstallStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetComPlusPackageInstallStatus,SetComPlusPackageInstallStatus,1251 diff --git a/libc/nt/kernel32/SetConsoleCursor.s b/libc/nt/kernel32/SetConsoleCursor.s new file mode 100644 index 00000000..b0fb019e --- /dev/null +++ b/libc/nt/kernel32/SetConsoleCursor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetConsoleCursor,SetConsoleCursor,1265 diff --git a/libc/nt/kernel32/SetConsoleCursorMode.s b/libc/nt/kernel32/SetConsoleCursorMode.s new file mode 100644 index 00000000..5aa47732 --- /dev/null +++ b/libc/nt/kernel32/SetConsoleCursorMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetConsoleCursorMode,SetConsoleCursorMode,1267 diff --git a/libc/nt/kernel32/SetConsoleFont.s b/libc/nt/kernel32/SetConsoleFont.s new file mode 100644 index 00000000..d8ed4f06 --- /dev/null +++ b/libc/nt/kernel32/SetConsoleFont.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetConsoleFont,SetConsoleFont,1270 diff --git a/libc/nt/kernel32/SetConsoleHardwareState.s b/libc/nt/kernel32/SetConsoleHardwareState.s new file mode 100644 index 00000000..c76c0a00 --- /dev/null +++ b/libc/nt/kernel32/SetConsoleHardwareState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetConsoleHardwareState,SetConsoleHardwareState,1271 diff --git a/libc/nt/kernel32/SetConsoleIcon.s b/libc/nt/kernel32/SetConsoleIcon.s new file mode 100644 index 00000000..d1fa03b8 --- /dev/null +++ b/libc/nt/kernel32/SetConsoleIcon.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetConsoleIcon,SetConsoleIcon,1273 diff --git a/libc/nt/kernel32/SetConsoleKeyShortcuts.s b/libc/nt/kernel32/SetConsoleKeyShortcuts.s new file mode 100644 index 00000000..12d8b815 --- /dev/null +++ b/libc/nt/kernel32/SetConsoleKeyShortcuts.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetConsoleKeyShortcuts,SetConsoleKeyShortcuts,1276 diff --git a/libc/nt/kernel32/SetConsoleLocalEUDC.s b/libc/nt/kernel32/SetConsoleLocalEUDC.s new file mode 100644 index 00000000..3ebfb23b --- /dev/null +++ b/libc/nt/kernel32/SetConsoleLocalEUDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetConsoleLocalEUDC,SetConsoleLocalEUDC,1277 diff --git a/libc/nt/kernel32/SetConsoleMaximumWindowSize.s b/libc/nt/kernel32/SetConsoleMaximumWindowSize.s new file mode 100644 index 00000000..779332c3 --- /dev/null +++ b/libc/nt/kernel32/SetConsoleMaximumWindowSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetConsoleMaximumWindowSize,SetConsoleMaximumWindowSize,1278 diff --git a/libc/nt/kernel32/SetConsoleMenuClose.s b/libc/nt/kernel32/SetConsoleMenuClose.s new file mode 100644 index 00000000..23769d2c --- /dev/null +++ b/libc/nt/kernel32/SetConsoleMenuClose.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetConsoleMenuClose,SetConsoleMenuClose,1279 diff --git a/libc/nt/kernel32/SetConsoleNlsMode.s b/libc/nt/kernel32/SetConsoleNlsMode.s new file mode 100644 index 00000000..9c556533 --- /dev/null +++ b/libc/nt/kernel32/SetConsoleNlsMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetConsoleNlsMode,SetConsoleNlsMode,1281 diff --git a/libc/nt/kernel32/SetConsoleOS2OemFormat.s b/libc/nt/kernel32/SetConsoleOS2OemFormat.s new file mode 100644 index 00000000..73139a97 --- /dev/null +++ b/libc/nt/kernel32/SetConsoleOS2OemFormat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetConsoleOS2OemFormat,SetConsoleOS2OemFormat,1284 diff --git a/libc/nt/kernel32/SetConsolePalette.s b/libc/nt/kernel32/SetConsolePalette.s new file mode 100644 index 00000000..8686a3b1 --- /dev/null +++ b/libc/nt/kernel32/SetConsolePalette.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetConsolePalette,SetConsolePalette,1286 diff --git a/libc/nt/kernel32/SetDefaultCommConfigA.s b/libc/nt/kernel32/SetDefaultCommConfigA.s new file mode 100644 index 00000000..a99c297c --- /dev/null +++ b/libc/nt/kernel32/SetDefaultCommConfigA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetDefaultCommConfigA,SetDefaultCommConfigA,1297 diff --git a/libc/nt/kernel32/SetDefaultCommConfigW.s b/libc/nt/kernel32/SetDefaultCommConfigW.s new file mode 100644 index 00000000..08c0e26e --- /dev/null +++ b/libc/nt/kernel32/SetDefaultCommConfigW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetDefaultCommConfigW,SetDefaultCommConfigW,1298 diff --git a/libc/nt/kernel32/SetDllDirectoryA.s b/libc/nt/kernel32/SetDllDirectoryA.s new file mode 100644 index 00000000..604b0212 --- /dev/null +++ b/libc/nt/kernel32/SetDllDirectoryA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetDllDirectoryA,SetDllDirectoryA,1300 diff --git a/libc/nt/kernel32/SetDllDirectoryW.s b/libc/nt/kernel32/SetDllDirectoryW.s new file mode 100644 index 00000000..06ecde67 --- /dev/null +++ b/libc/nt/kernel32/SetDllDirectoryW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetDllDirectoryW,SetDllDirectoryW,1301 diff --git a/libc/nt/kernel32/SetEnvironmentStringsA.s b/libc/nt/kernel32/SetEnvironmentStringsA.s new file mode 100644 index 00000000..2cf52682 --- /dev/null +++ b/libc/nt/kernel32/SetEnvironmentStringsA.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetEnvironmentStringsA,SetEnvironmentStringsA,1304 + + .text.windows +SetEnvironmentStringsA: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_SetEnvironmentStringsA(%rip) + leave + ret + .endfn SetEnvironmentStringsA,globl + .previous diff --git a/libc/nt/kernel32/SetFileAttributesTransactedA.s b/libc/nt/kernel32/SetFileAttributesTransactedA.s new file mode 100644 index 00000000..74ed5193 --- /dev/null +++ b/libc/nt/kernel32/SetFileAttributesTransactedA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetFileAttributesTransactedA,SetFileAttributesTransactedA,1314 diff --git a/libc/nt/kernel32/SetFileAttributesTransactedW.s b/libc/nt/kernel32/SetFileAttributesTransactedW.s new file mode 100644 index 00000000..3afc383e --- /dev/null +++ b/libc/nt/kernel32/SetFileAttributesTransactedW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetFileAttributesTransactedW,SetFileAttributesTransactedW,1315 diff --git a/libc/nt/kernel32/SetFileBandwidthReservation.s b/libc/nt/kernel32/SetFileBandwidthReservation.s new file mode 100644 index 00000000..09e5ec58 --- /dev/null +++ b/libc/nt/kernel32/SetFileBandwidthReservation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetFileBandwidthReservation,SetFileBandwidthReservation,1317 diff --git a/libc/nt/kernel32/SetFileCompletionNotificationModes.s b/libc/nt/kernel32/SetFileCompletionNotificationModes.s new file mode 100644 index 00000000..ed3a3bb4 --- /dev/null +++ b/libc/nt/kernel32/SetFileCompletionNotificationModes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetFileCompletionNotificationModes,SetFileCompletionNotificationModes,1318 diff --git a/libc/nt/kernel32/SetFileShortNameA.s b/libc/nt/kernel32/SetFileShortNameA.s new file mode 100644 index 00000000..a4c00cac --- /dev/null +++ b/libc/nt/kernel32/SetFileShortNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetFileShortNameA,SetFileShortNameA,1323 diff --git a/libc/nt/kernel32/SetFileShortNameW.s b/libc/nt/kernel32/SetFileShortNameW.s new file mode 100644 index 00000000..b3503c52 --- /dev/null +++ b/libc/nt/kernel32/SetFileShortNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetFileShortNameW,SetFileShortNameW,1324 diff --git a/libc/nt/kernel32/SetFirmwareEnvironmentVariableA.s b/libc/nt/kernel32/SetFirmwareEnvironmentVariableA.s new file mode 100644 index 00000000..e32c2729 --- /dev/null +++ b/libc/nt/kernel32/SetFirmwareEnvironmentVariableA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetFirmwareEnvironmentVariableA,SetFirmwareEnvironmentVariableA,1327 diff --git a/libc/nt/kernel32/SetFirmwareEnvironmentVariableExA.s b/libc/nt/kernel32/SetFirmwareEnvironmentVariableExA.s new file mode 100644 index 00000000..548ece71 --- /dev/null +++ b/libc/nt/kernel32/SetFirmwareEnvironmentVariableExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetFirmwareEnvironmentVariableExA,SetFirmwareEnvironmentVariableExA,1328 diff --git a/libc/nt/kernel32/SetFirmwareEnvironmentVariableExW.s b/libc/nt/kernel32/SetFirmwareEnvironmentVariableExW.s new file mode 100644 index 00000000..b353c7ef --- /dev/null +++ b/libc/nt/kernel32/SetFirmwareEnvironmentVariableExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetFirmwareEnvironmentVariableExW,SetFirmwareEnvironmentVariableExW,1329 diff --git a/libc/nt/kernel32/SetFirmwareEnvironmentVariableW.s b/libc/nt/kernel32/SetFirmwareEnvironmentVariableW.s new file mode 100644 index 00000000..fc9e2523 --- /dev/null +++ b/libc/nt/kernel32/SetFirmwareEnvironmentVariableW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetFirmwareEnvironmentVariableW,SetFirmwareEnvironmentVariableW,1330 diff --git a/libc/nt/kernel32/SetInformationJobObject.s b/libc/nt/kernel32/SetInformationJobObject.s new file mode 100644 index 00000000..908b3c6c --- /dev/null +++ b/libc/nt/kernel32/SetInformationJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetInformationJobObject,SetInformationJobObject,1333 diff --git a/libc/nt/kernel32/SetIoRateControlInformationJobObject.s b/libc/nt/kernel32/SetIoRateControlInformationJobObject.s new file mode 100644 index 00000000..2a9aeb49 --- /dev/null +++ b/libc/nt/kernel32/SetIoRateControlInformationJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetIoRateControlInformationJobObject,SetIoRateControlInformationJobObject,1334 diff --git a/libc/nt/kernel32/SetLastError.s b/libc/nt/kernel32/SetLastError.s new file mode 100644 index 00000000..03a1f7d3 --- /dev/null +++ b/libc/nt/kernel32/SetLastError.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetLastError,SetLastError,1336 + + .text.windows +SetLastError: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_SetLastError(%rip) + leave + ret + .endfn SetLastError,globl + .previous diff --git a/libc/nt/kernel32/SetLocalPrimaryComputerNameA.s b/libc/nt/kernel32/SetLocalPrimaryComputerNameA.s new file mode 100644 index 00000000..d42a0237 --- /dev/null +++ b/libc/nt/kernel32/SetLocalPrimaryComputerNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetLocalPrimaryComputerNameA,SetLocalPrimaryComputerNameA,1337 diff --git a/libc/nt/kernel32/SetLocalPrimaryComputerNameW.s b/libc/nt/kernel32/SetLocalPrimaryComputerNameW.s new file mode 100644 index 00000000..096b7183 --- /dev/null +++ b/libc/nt/kernel32/SetLocalPrimaryComputerNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetLocalPrimaryComputerNameW,SetLocalPrimaryComputerNameW,1338 diff --git a/libc/nt/kernel32/SetLocaleInfoA.s b/libc/nt/kernel32/SetLocaleInfoA.s new file mode 100644 index 00000000..b048690d --- /dev/null +++ b/libc/nt/kernel32/SetLocaleInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetLocaleInfoA,SetLocaleInfoA,1340 diff --git a/libc/nt/kernel32/SetMailslotInfo.s b/libc/nt/kernel32/SetMailslotInfo.s new file mode 100644 index 00000000..b09b2d90 --- /dev/null +++ b/libc/nt/kernel32/SetMailslotInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetMailslotInfo,SetMailslotInfo,1342 diff --git a/libc/nt/kernel32/SetMessageWaitingIndicator.s b/libc/nt/kernel32/SetMessageWaitingIndicator.s new file mode 100644 index 00000000..b469a790 --- /dev/null +++ b/libc/nt/kernel32/SetMessageWaitingIndicator.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetMessageWaitingIndicator,SetMessageWaitingIndicator,1343 diff --git a/libc/nt/kernel32/SetNamedPipeAttribute.s b/libc/nt/kernel32/SetNamedPipeAttribute.s new file mode 100644 index 00000000..7cda8dfc --- /dev/null +++ b/libc/nt/kernel32/SetNamedPipeAttribute.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetNamedPipeAttribute,SetNamedPipeAttribute,1344 diff --git a/libc/nt/kernel32/SetProcessAffinityMask.s b/libc/nt/kernel32/SetProcessAffinityMask.s new file mode 100644 index 00000000..64c8d736 --- /dev/null +++ b/libc/nt/kernel32/SetProcessAffinityMask.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetProcessAffinityMask,SetProcessAffinityMask,1347 + + .text.windows +SetProcessAffinityMask: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetProcessAffinityMask(%rip),%rax + jmp __sysv2nt + .endfn SetProcessAffinityMask,globl + .previous diff --git a/libc/nt/kernel32/SetProcessDEPPolicy.s b/libc/nt/kernel32/SetProcessDEPPolicy.s new file mode 100644 index 00000000..6ba7fd2d --- /dev/null +++ b/libc/nt/kernel32/SetProcessDEPPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetProcessDEPPolicy,SetProcessDEPPolicy,1349 diff --git a/libc/nt/kernel32/SetProcessWorkingSetSize.s b/libc/nt/kernel32/SetProcessWorkingSetSize.s new file mode 100644 index 00000000..15962110 --- /dev/null +++ b/libc/nt/kernel32/SetProcessWorkingSetSize.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetProcessWorkingSetSize,SetProcessWorkingSetSize,1356 + + .text.windows +SetProcessWorkingSetSize: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetProcessWorkingSetSize(%rip),%rax + jmp __sysv2nt + .endfn SetProcessWorkingSetSize,globl + .previous diff --git a/libc/nt/kernel32/SetSearchPathMode.s b/libc/nt/kernel32/SetSearchPathMode.s new file mode 100644 index 00000000..16892837 --- /dev/null +++ b/libc/nt/kernel32/SetSearchPathMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetSearchPathMode,SetSearchPathMode,1359 diff --git a/libc/nt/kernel32/SetSystemPowerState.s b/libc/nt/kernel32/SetSystemPowerState.s new file mode 100644 index 00000000..09a072d7 --- /dev/null +++ b/libc/nt/kernel32/SetSystemPowerState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetSystemPowerState,SetSystemPowerState,1363 diff --git a/libc/nt/kernel32/SetTapeParameters.s b/libc/nt/kernel32/SetTapeParameters.s new file mode 100644 index 00000000..702a9681 --- /dev/null +++ b/libc/nt/kernel32/SetTapeParameters.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetTapeParameters,SetTapeParameters,1366 diff --git a/libc/nt/kernel32/SetTapePosition.s b/libc/nt/kernel32/SetTapePosition.s new file mode 100644 index 00000000..cde2a0e5 --- /dev/null +++ b/libc/nt/kernel32/SetTapePosition.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetTapePosition,SetTapePosition,1367 diff --git a/libc/nt/kernel32/SetTermsrvAppInstallMode.s b/libc/nt/kernel32/SetTermsrvAppInstallMode.s new file mode 100644 index 00000000..fef55913 --- /dev/null +++ b/libc/nt/kernel32/SetTermsrvAppInstallMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetTermsrvAppInstallMode,SetTermsrvAppInstallMode,1368 diff --git a/libc/nt/kernel32/SetThreadAffinityMask.s b/libc/nt/kernel32/SetThreadAffinityMask.s new file mode 100644 index 00000000..bd42fe16 --- /dev/null +++ b/libc/nt/kernel32/SetThreadAffinityMask.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetThreadAffinityMask,SetThreadAffinityMask,1369 + + .text.windows +SetThreadAffinityMask: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetThreadAffinityMask(%rip),%rax + jmp __sysv2nt + .endfn SetThreadAffinityMask,globl + .previous diff --git a/libc/nt/kernel32/SetThreadExecutionState.s b/libc/nt/kernel32/SetThreadExecutionState.s new file mode 100644 index 00000000..0a0a2ab3 --- /dev/null +++ b/libc/nt/kernel32/SetThreadExecutionState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetThreadExecutionState,SetThreadExecutionState,1373 diff --git a/libc/nt/kernel32/SetTimerQueueTimer.s b/libc/nt/kernel32/SetTimerQueueTimer.s new file mode 100644 index 00000000..90b8e8b4 --- /dev/null +++ b/libc/nt/kernel32/SetTimerQueueTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetTimerQueueTimer,SetTimerQueueTimer,1394 diff --git a/libc/nt/kernel32/SetUmsThreadInformation.s b/libc/nt/kernel32/SetUmsThreadInformation.s new file mode 100644 index 00000000..5edda132 --- /dev/null +++ b/libc/nt/kernel32/SetUmsThreadInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetUmsThreadInformation,SetUmsThreadInformation,1395 diff --git a/libc/nt/kernel32/SetVDMCurrentDirectories.s b/libc/nt/kernel32/SetVDMCurrentDirectories.s new file mode 100644 index 00000000..91a9c41d --- /dev/null +++ b/libc/nt/kernel32/SetVDMCurrentDirectories.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetVDMCurrentDirectories,SetVDMCurrentDirectories,1399 diff --git a/libc/nt/kernel32/SetVolumeLabelA.s b/libc/nt/kernel32/SetVolumeLabelA.s new file mode 100644 index 00000000..93b4ae29 --- /dev/null +++ b/libc/nt/kernel32/SetVolumeLabelA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetVolumeLabelA,SetVolumeLabelA,1400 diff --git a/libc/nt/kernel32/SetVolumeLabelW.s b/libc/nt/kernel32/SetVolumeLabelW.s new file mode 100644 index 00000000..d1ebc2fe --- /dev/null +++ b/libc/nt/kernel32/SetVolumeLabelW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetVolumeLabelW,SetVolumeLabelW,1401 diff --git a/libc/nt/kernel32/SetVolumeMountPointA.s b/libc/nt/kernel32/SetVolumeMountPointA.s new file mode 100644 index 00000000..606ebbe0 --- /dev/null +++ b/libc/nt/kernel32/SetVolumeMountPointA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetVolumeMountPointA,SetVolumeMountPointA,1402 diff --git a/libc/nt/kernel32/SetVolumeMountPointW.s b/libc/nt/kernel32/SetVolumeMountPointW.s new file mode 100644 index 00000000..16f5cd54 --- /dev/null +++ b/libc/nt/kernel32/SetVolumeMountPointW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetVolumeMountPointW,SetVolumeMountPointW,1403 diff --git a/libc/nt/kernel32/SetVolumeMountPointWStub.s b/libc/nt/kernel32/SetVolumeMountPointWStub.s new file mode 100644 index 00000000..284dbb3f --- /dev/null +++ b/libc/nt/kernel32/SetVolumeMountPointWStub.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SetVolumeMountPointWStub,SetVolumeMountPointWStub,1404 diff --git a/libc/nt/kernel32/ShowConsoleCursor.s b/libc/nt/kernel32/ShowConsoleCursor.s new file mode 100644 index 00000000..1d38c556 --- /dev/null +++ b/libc/nt/kernel32/ShowConsoleCursor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_ShowConsoleCursor,ShowConsoleCursor,1409 diff --git a/libc/nt/kernel32/SortCloseHandle.s b/libc/nt/kernel32/SortCloseHandle.s new file mode 100644 index 00000000..f0a3e6d0 --- /dev/null +++ b/libc/nt/kernel32/SortCloseHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SortCloseHandle,SortCloseHandle,1416 diff --git a/libc/nt/kernel32/SortGetHandle.s b/libc/nt/kernel32/SortGetHandle.s new file mode 100644 index 00000000..1cb22e9d --- /dev/null +++ b/libc/nt/kernel32/SortGetHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_SortGetHandle,SortGetHandle,1417 diff --git a/libc/nt/kernel32/TerminateJobObject.s b/libc/nt/kernel32/TerminateJobObject.s new file mode 100644 index 00000000..452fb29a --- /dev/null +++ b/libc/nt/kernel32/TerminateJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_TerminateJobObject,TerminateJobObject,1426 diff --git a/libc/nt/kernel32/TermsrvAppInstallMode.s b/libc/nt/kernel32/TermsrvAppInstallMode.s new file mode 100644 index 00000000..f4be54e0 --- /dev/null +++ b/libc/nt/kernel32/TermsrvAppInstallMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_TermsrvAppInstallMode,TermsrvAppInstallMode,1429 diff --git a/libc/nt/kernel32/TermsrvConvertSysRootToUserDir.s b/libc/nt/kernel32/TermsrvConvertSysRootToUserDir.s new file mode 100644 index 00000000..92a4a03d --- /dev/null +++ b/libc/nt/kernel32/TermsrvConvertSysRootToUserDir.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_TermsrvConvertSysRootToUserDir,TermsrvConvertSysRootToUserDir,1430 diff --git a/libc/nt/kernel32/TermsrvCreateRegEntry.s b/libc/nt/kernel32/TermsrvCreateRegEntry.s new file mode 100644 index 00000000..0a4e962f --- /dev/null +++ b/libc/nt/kernel32/TermsrvCreateRegEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_TermsrvCreateRegEntry,TermsrvCreateRegEntry,1431 diff --git a/libc/nt/kernel32/TermsrvDeleteKey.s b/libc/nt/kernel32/TermsrvDeleteKey.s new file mode 100644 index 00000000..49f2832b --- /dev/null +++ b/libc/nt/kernel32/TermsrvDeleteKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_TermsrvDeleteKey,TermsrvDeleteKey,1432 diff --git a/libc/nt/kernel32/TermsrvDeleteValue.s b/libc/nt/kernel32/TermsrvDeleteValue.s new file mode 100644 index 00000000..2e7b2c32 --- /dev/null +++ b/libc/nt/kernel32/TermsrvDeleteValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_TermsrvDeleteValue,TermsrvDeleteValue,1433 diff --git a/libc/nt/kernel32/TermsrvGetPreSetValue.s b/libc/nt/kernel32/TermsrvGetPreSetValue.s new file mode 100644 index 00000000..49cf384e --- /dev/null +++ b/libc/nt/kernel32/TermsrvGetPreSetValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_TermsrvGetPreSetValue,TermsrvGetPreSetValue,1434 diff --git a/libc/nt/kernel32/TermsrvGetWindowsDirectoryA.s b/libc/nt/kernel32/TermsrvGetWindowsDirectoryA.s new file mode 100644 index 00000000..e5bf6b33 --- /dev/null +++ b/libc/nt/kernel32/TermsrvGetWindowsDirectoryA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_TermsrvGetWindowsDirectoryA,TermsrvGetWindowsDirectoryA,1435 diff --git a/libc/nt/kernel32/TermsrvGetWindowsDirectoryW.s b/libc/nt/kernel32/TermsrvGetWindowsDirectoryW.s new file mode 100644 index 00000000..0c2dc36c --- /dev/null +++ b/libc/nt/kernel32/TermsrvGetWindowsDirectoryW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_TermsrvGetWindowsDirectoryW,TermsrvGetWindowsDirectoryW,1436 diff --git a/libc/nt/kernel32/TermsrvOpenRegEntry.s b/libc/nt/kernel32/TermsrvOpenRegEntry.s new file mode 100644 index 00000000..04bb7709 --- /dev/null +++ b/libc/nt/kernel32/TermsrvOpenRegEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_TermsrvOpenRegEntry,TermsrvOpenRegEntry,1437 diff --git a/libc/nt/kernel32/TermsrvOpenUserClasses.s b/libc/nt/kernel32/TermsrvOpenUserClasses.s new file mode 100644 index 00000000..e6af4e8b --- /dev/null +++ b/libc/nt/kernel32/TermsrvOpenUserClasses.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_TermsrvOpenUserClasses,TermsrvOpenUserClasses,1438 diff --git a/libc/nt/kernel32/TermsrvRestoreKey.s b/libc/nt/kernel32/TermsrvRestoreKey.s new file mode 100644 index 00000000..464e9de0 --- /dev/null +++ b/libc/nt/kernel32/TermsrvRestoreKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_TermsrvRestoreKey,TermsrvRestoreKey,1439 diff --git a/libc/nt/kernel32/TermsrvSetKeySecurity.s b/libc/nt/kernel32/TermsrvSetKeySecurity.s new file mode 100644 index 00000000..8ed33c77 --- /dev/null +++ b/libc/nt/kernel32/TermsrvSetKeySecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_TermsrvSetKeySecurity,TermsrvSetKeySecurity,1440 diff --git a/libc/nt/kernel32/TermsrvSetValueKey.s b/libc/nt/kernel32/TermsrvSetValueKey.s new file mode 100644 index 00000000..444d97f5 --- /dev/null +++ b/libc/nt/kernel32/TermsrvSetValueKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_TermsrvSetValueKey,TermsrvSetValueKey,1441 diff --git a/libc/nt/kernel32/TermsrvSyncUserIniFileExt.s b/libc/nt/kernel32/TermsrvSyncUserIniFileExt.s new file mode 100644 index 00000000..8cabd5b2 --- /dev/null +++ b/libc/nt/kernel32/TermsrvSyncUserIniFileExt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_TermsrvSyncUserIniFileExt,TermsrvSyncUserIniFileExt,1442 diff --git a/libc/nt/kernel32/Thread32First.s b/libc/nt/kernel32/Thread32First.s new file mode 100644 index 00000000..d2c387c6 --- /dev/null +++ b/libc/nt/kernel32/Thread32First.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_Thread32First,Thread32First,1443 diff --git a/libc/nt/kernel32/Thread32Next.s b/libc/nt/kernel32/Thread32Next.s new file mode 100644 index 00000000..50c30bda --- /dev/null +++ b/libc/nt/kernel32/Thread32Next.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_Thread32Next,Thread32Next,1444 diff --git a/libc/nt/kernel32/Toolhelp32ReadProcessMemory.s b/libc/nt/kernel32/Toolhelp32ReadProcessMemory.s new file mode 100644 index 00000000..26a8aed2 --- /dev/null +++ b/libc/nt/kernel32/Toolhelp32ReadProcessMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_Toolhelp32ReadProcessMemory,Toolhelp32ReadProcessMemory,1449 diff --git a/libc/nt/kernel32/UTRegister.s b/libc/nt/kernel32/UTRegister.s new file mode 100644 index 00000000..e295230e --- /dev/null +++ b/libc/nt/kernel32/UTRegister.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_UTRegister,UTRegister,1458 diff --git a/libc/nt/kernel32/UTUnRegister.s b/libc/nt/kernel32/UTUnRegister.s new file mode 100644 index 00000000..4c00daf1 --- /dev/null +++ b/libc/nt/kernel32/UTUnRegister.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_UTUnRegister,UTUnRegister,1459 diff --git a/libc/nt/kernel32/UmsThreadYield.s b/libc/nt/kernel32/UmsThreadYield.s new file mode 100644 index 00000000..2bcabaf3 --- /dev/null +++ b/libc/nt/kernel32/UmsThreadYield.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_UmsThreadYield,UmsThreadYield,1460 diff --git a/libc/nt/kernel32/UnregisterApplicationRecoveryCallback.s b/libc/nt/kernel32/UnregisterApplicationRecoveryCallback.s new file mode 100644 index 00000000..61f28290 --- /dev/null +++ b/libc/nt/kernel32/UnregisterApplicationRecoveryCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_UnregisterApplicationRecoveryCallback,UnregisterApplicationRecoveryCallback,1466 diff --git a/libc/nt/kernel32/UnregisterApplicationRestart.s b/libc/nt/kernel32/UnregisterApplicationRestart.s new file mode 100644 index 00000000..3d835f87 --- /dev/null +++ b/libc/nt/kernel32/UnregisterApplicationRestart.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_UnregisterApplicationRestart,UnregisterApplicationRestart,1467 diff --git a/libc/nt/kernel32/UnregisterConsoleIME.s b/libc/nt/kernel32/UnregisterConsoleIME.s new file mode 100644 index 00000000..f98ca964 --- /dev/null +++ b/libc/nt/kernel32/UnregisterConsoleIME.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_UnregisterConsoleIME,UnregisterConsoleIME,1469 diff --git a/libc/nt/kernel32/UnregisterWait.s b/libc/nt/kernel32/UnregisterWait.s new file mode 100644 index 00000000..0b265906 --- /dev/null +++ b/libc/nt/kernel32/UnregisterWait.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_UnregisterWait,UnregisterWait,1470 diff --git a/libc/nt/kernel32/UnregisterWaitUntilOOBECompleted.s b/libc/nt/kernel32/UnregisterWaitUntilOOBECompleted.s new file mode 100644 index 00000000..7a2a7e80 --- /dev/null +++ b/libc/nt/kernel32/UnregisterWaitUntilOOBECompleted.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_UnregisterWaitUntilOOBECompleted,UnregisterWaitUntilOOBECompleted,1472 diff --git a/libc/nt/kernel32/UpdateCalendarDayOfWeek.s b/libc/nt/kernel32/UpdateCalendarDayOfWeek.s new file mode 100644 index 00000000..9f4ce932 --- /dev/null +++ b/libc/nt/kernel32/UpdateCalendarDayOfWeek.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_UpdateCalendarDayOfWeek,UpdateCalendarDayOfWeek,1473 diff --git a/libc/nt/kernel32/UpdateResourceA.s b/libc/nt/kernel32/UpdateResourceA.s new file mode 100644 index 00000000..99abb606 --- /dev/null +++ b/libc/nt/kernel32/UpdateResourceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_UpdateResourceA,UpdateResourceA,1475 diff --git a/libc/nt/kernel32/UpdateResourceW.s b/libc/nt/kernel32/UpdateResourceW.s new file mode 100644 index 00000000..50a07173 --- /dev/null +++ b/libc/nt/kernel32/UpdateResourceW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_UpdateResourceW,UpdateResourceW,1476 diff --git a/libc/nt/kernel32/VDMConsoleOperation.s b/libc/nt/kernel32/VDMConsoleOperation.s new file mode 100644 index 00000000..021c3ed0 --- /dev/null +++ b/libc/nt/kernel32/VDMConsoleOperation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_VDMConsoleOperation,VDMConsoleOperation,1477 diff --git a/libc/nt/kernel32/VDMOperationStarted.s b/libc/nt/kernel32/VDMOperationStarted.s new file mode 100644 index 00000000..bacad6ac --- /dev/null +++ b/libc/nt/kernel32/VDMOperationStarted.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_VDMOperationStarted,VDMOperationStarted,1478 diff --git a/libc/nt/kernel32/VerifyConsoleIoHandle.s b/libc/nt/kernel32/VerifyConsoleIoHandle.s new file mode 100644 index 00000000..fb81e813 --- /dev/null +++ b/libc/nt/kernel32/VerifyConsoleIoHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_VerifyConsoleIoHandle,VerifyConsoleIoHandle,1482 diff --git a/libc/nt/kernel32/VerifyVersionInfoA.s b/libc/nt/kernel32/VerifyVersionInfoA.s new file mode 100644 index 00000000..d21a678f --- /dev/null +++ b/libc/nt/kernel32/VerifyVersionInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_VerifyVersionInfoA,VerifyVersionInfoA,1484 diff --git a/libc/nt/kernel32/VerifyVersionInfoW.s b/libc/nt/kernel32/VerifyVersionInfoW.s new file mode 100644 index 00000000..a4657e87 --- /dev/null +++ b/libc/nt/kernel32/VerifyVersionInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_VerifyVersionInfoW,VerifyVersionInfoW,1485 diff --git a/libc/nt/kernel32/WTSGetActiveConsoleSessionId.s b/libc/nt/kernel32/WTSGetActiveConsoleSessionId.s new file mode 100644 index 00000000..167d3e2e --- /dev/null +++ b/libc/nt/kernel32/WTSGetActiveConsoleSessionId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WTSGetActiveConsoleSessionId,WTSGetActiveConsoleSessionId,1497 diff --git a/libc/nt/kernel32/WaitNamedPipeA.s b/libc/nt/kernel32/WaitNamedPipeA.s new file mode 100644 index 00000000..d20e2188 --- /dev/null +++ b/libc/nt/kernel32/WaitNamedPipeA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WaitNamedPipeA,WaitNamedPipeA,1509 + + .text.windows +WaitNamedPipeA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WaitNamedPipeA(%rip),%rax + jmp __sysv2nt + .endfn WaitNamedPipeA,globl + .previous diff --git a/libc/nt/kernel32/WerGetFlagsWorker.s b/libc/nt/kernel32/WerGetFlagsWorker.s new file mode 100644 index 00000000..e5f89d1a --- /dev/null +++ b/libc/nt/kernel32/WerGetFlagsWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WerGetFlagsWorker,WerGetFlagsWorker,1514 diff --git a/libc/nt/kernel32/WerRegisterFileWorker.s b/libc/nt/kernel32/WerRegisterFileWorker.s new file mode 100644 index 00000000..e3306e21 --- /dev/null +++ b/libc/nt/kernel32/WerRegisterFileWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WerRegisterFileWorker,WerRegisterFileWorker,1520 diff --git a/libc/nt/kernel32/WerRegisterMemoryBlockWorker.s b/libc/nt/kernel32/WerRegisterMemoryBlockWorker.s new file mode 100644 index 00000000..b7e0df45 --- /dev/null +++ b/libc/nt/kernel32/WerRegisterMemoryBlockWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WerRegisterMemoryBlockWorker,WerRegisterMemoryBlockWorker,1522 diff --git a/libc/nt/kernel32/WerRegisterRuntimeExceptionModuleWorker.s b/libc/nt/kernel32/WerRegisterRuntimeExceptionModuleWorker.s new file mode 100644 index 00000000..5c18c0ee --- /dev/null +++ b/libc/nt/kernel32/WerRegisterRuntimeExceptionModuleWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WerRegisterRuntimeExceptionModuleWorker,WerRegisterRuntimeExceptionModuleWorker,1524 diff --git a/libc/nt/kernel32/WerSetFlagsWorker.s b/libc/nt/kernel32/WerSetFlagsWorker.s new file mode 100644 index 00000000..a05ef62e --- /dev/null +++ b/libc/nt/kernel32/WerSetFlagsWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WerSetFlagsWorker,WerSetFlagsWorker,1526 diff --git a/libc/nt/kernel32/WerUnregisterFileWorker.s b/libc/nt/kernel32/WerUnregisterFileWorker.s new file mode 100644 index 00000000..f80110d4 --- /dev/null +++ b/libc/nt/kernel32/WerUnregisterFileWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WerUnregisterFileWorker,WerUnregisterFileWorker,1532 diff --git a/libc/nt/kernel32/WerUnregisterMemoryBlockWorker.s b/libc/nt/kernel32/WerUnregisterMemoryBlockWorker.s new file mode 100644 index 00000000..d27e3c65 --- /dev/null +++ b/libc/nt/kernel32/WerUnregisterMemoryBlockWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WerUnregisterMemoryBlockWorker,WerUnregisterMemoryBlockWorker,1534 diff --git a/libc/nt/kernel32/WerUnregisterRuntimeExceptionModuleWorker.s b/libc/nt/kernel32/WerUnregisterRuntimeExceptionModuleWorker.s new file mode 100644 index 00000000..9daa712c --- /dev/null +++ b/libc/nt/kernel32/WerUnregisterRuntimeExceptionModuleWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WerUnregisterRuntimeExceptionModuleWorker,WerUnregisterRuntimeExceptionModuleWorker,1536 diff --git a/libc/nt/kernel32/WerpGetDebugger.s b/libc/nt/kernel32/WerpGetDebugger.s new file mode 100644 index 00000000..0b408f5c --- /dev/null +++ b/libc/nt/kernel32/WerpGetDebugger.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WerpGetDebugger,WerpGetDebugger,1537 diff --git a/libc/nt/kernel32/WerpInitiateRemoteRecovery.s b/libc/nt/kernel32/WerpInitiateRemoteRecovery.s new file mode 100644 index 00000000..d22c1646 --- /dev/null +++ b/libc/nt/kernel32/WerpInitiateRemoteRecovery.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WerpInitiateRemoteRecovery,WerpInitiateRemoteRecovery,1538 diff --git a/libc/nt/kernel32/WerpLaunchAeDebug.s b/libc/nt/kernel32/WerpLaunchAeDebug.s new file mode 100644 index 00000000..d1b22ef2 --- /dev/null +++ b/libc/nt/kernel32/WerpLaunchAeDebug.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WerpLaunchAeDebug,WerpLaunchAeDebug,1539 diff --git a/libc/nt/kernel32/WerpNotifyLoadStringResourceWorker.s b/libc/nt/kernel32/WerpNotifyLoadStringResourceWorker.s new file mode 100644 index 00000000..8a260160 --- /dev/null +++ b/libc/nt/kernel32/WerpNotifyLoadStringResourceWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WerpNotifyLoadStringResourceWorker,WerpNotifyLoadStringResourceWorker,1540 diff --git a/libc/nt/kernel32/WerpNotifyUseStringResourceWorker.s b/libc/nt/kernel32/WerpNotifyUseStringResourceWorker.s new file mode 100644 index 00000000..ed3742dc --- /dev/null +++ b/libc/nt/kernel32/WerpNotifyUseStringResourceWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WerpNotifyUseStringResourceWorker,WerpNotifyUseStringResourceWorker,1541 diff --git a/libc/nt/kernel32/WinExec.s b/libc/nt/kernel32/WinExec.s new file mode 100644 index 00000000..38a3a8b4 --- /dev/null +++ b/libc/nt/kernel32/WinExec.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WinExec,WinExec,1543 diff --git a/libc/nt/kernel32/Wow64EnableWow64FsRedirection.s b/libc/nt/kernel32/Wow64EnableWow64FsRedirection.s new file mode 100644 index 00000000..bc60272e --- /dev/null +++ b/libc/nt/kernel32/Wow64EnableWow64FsRedirection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_Wow64EnableWow64FsRedirection,Wow64EnableWow64FsRedirection,1545 diff --git a/libc/nt/kernel32/Wow64GetThreadContext.s b/libc/nt/kernel32/Wow64GetThreadContext.s new file mode 100644 index 00000000..154fa9f2 --- /dev/null +++ b/libc/nt/kernel32/Wow64GetThreadContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_Wow64GetThreadContext,Wow64GetThreadContext,1546 diff --git a/libc/nt/kernel32/Wow64GetThreadSelectorEntry.s b/libc/nt/kernel32/Wow64GetThreadSelectorEntry.s new file mode 100644 index 00000000..d7f21dc0 --- /dev/null +++ b/libc/nt/kernel32/Wow64GetThreadSelectorEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_Wow64GetThreadSelectorEntry,Wow64GetThreadSelectorEntry,1547 diff --git a/libc/nt/kernel32/Wow64SetThreadContext.s b/libc/nt/kernel32/Wow64SetThreadContext.s new file mode 100644 index 00000000..4733945d --- /dev/null +++ b/libc/nt/kernel32/Wow64SetThreadContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_Wow64SetThreadContext,Wow64SetThreadContext,1549 diff --git a/libc/nt/kernel32/Wow64SuspendThread.s b/libc/nt/kernel32/Wow64SuspendThread.s new file mode 100644 index 00000000..3507d21a --- /dev/null +++ b/libc/nt/kernel32/Wow64SuspendThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_Wow64SuspendThread,Wow64SuspendThread,1550 diff --git a/libc/nt/kernel32/WriteConsoleInputVDMA.s b/libc/nt/kernel32/WriteConsoleInputVDMA.s new file mode 100644 index 00000000..a6661b1f --- /dev/null +++ b/libc/nt/kernel32/WriteConsoleInputVDMA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WriteConsoleInputVDMA,WriteConsoleInputVDMA,1553 diff --git a/libc/nt/kernel32/WriteConsoleInputVDMW.s b/libc/nt/kernel32/WriteConsoleInputVDMW.s new file mode 100644 index 00000000..0cebd8cc --- /dev/null +++ b/libc/nt/kernel32/WriteConsoleInputVDMW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WriteConsoleInputVDMW,WriteConsoleInputVDMW,1554 diff --git a/libc/nt/kernel32/WritePrivateProfileSectionA.s b/libc/nt/kernel32/WritePrivateProfileSectionA.s new file mode 100644 index 00000000..3b1682a7 --- /dev/null +++ b/libc/nt/kernel32/WritePrivateProfileSectionA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WritePrivateProfileSectionA,WritePrivateProfileSectionA,1565 diff --git a/libc/nt/kernel32/WritePrivateProfileSectionW.s b/libc/nt/kernel32/WritePrivateProfileSectionW.s new file mode 100644 index 00000000..892edaf3 --- /dev/null +++ b/libc/nt/kernel32/WritePrivateProfileSectionW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WritePrivateProfileSectionW,WritePrivateProfileSectionW,1566 diff --git a/libc/nt/kernel32/WritePrivateProfileStringA.s b/libc/nt/kernel32/WritePrivateProfileStringA.s new file mode 100644 index 00000000..71e5fbd7 --- /dev/null +++ b/libc/nt/kernel32/WritePrivateProfileStringA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WritePrivateProfileStringA,WritePrivateProfileStringA,1567 diff --git a/libc/nt/kernel32/WritePrivateProfileStringW.s b/libc/nt/kernel32/WritePrivateProfileStringW.s new file mode 100644 index 00000000..db247dad --- /dev/null +++ b/libc/nt/kernel32/WritePrivateProfileStringW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WritePrivateProfileStringW,WritePrivateProfileStringW,1568 diff --git a/libc/nt/kernel32/WritePrivateProfileStructA.s b/libc/nt/kernel32/WritePrivateProfileStructA.s new file mode 100644 index 00000000..95974283 --- /dev/null +++ b/libc/nt/kernel32/WritePrivateProfileStructA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WritePrivateProfileStructA,WritePrivateProfileStructA,1569 diff --git a/libc/nt/kernel32/WritePrivateProfileStructW.s b/libc/nt/kernel32/WritePrivateProfileStructW.s new file mode 100644 index 00000000..d854ed4a --- /dev/null +++ b/libc/nt/kernel32/WritePrivateProfileStructW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WritePrivateProfileStructW,WritePrivateProfileStructW,1570 diff --git a/libc/nt/kernel32/WriteProfileSectionA.s b/libc/nt/kernel32/WriteProfileSectionA.s new file mode 100644 index 00000000..5226b431 --- /dev/null +++ b/libc/nt/kernel32/WriteProfileSectionA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WriteProfileSectionA,WriteProfileSectionA,1572 diff --git a/libc/nt/kernel32/WriteProfileSectionW.s b/libc/nt/kernel32/WriteProfileSectionW.s new file mode 100644 index 00000000..42056a0c --- /dev/null +++ b/libc/nt/kernel32/WriteProfileSectionW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WriteProfileSectionW,WriteProfileSectionW,1573 diff --git a/libc/nt/kernel32/WriteProfileStringA.s b/libc/nt/kernel32/WriteProfileStringA.s new file mode 100644 index 00000000..0920a7e7 --- /dev/null +++ b/libc/nt/kernel32/WriteProfileStringA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WriteProfileStringA,WriteProfileStringA,1574 diff --git a/libc/nt/kernel32/WriteProfileStringW.s b/libc/nt/kernel32/WriteProfileStringW.s new file mode 100644 index 00000000..a0327aff --- /dev/null +++ b/libc/nt/kernel32/WriteProfileStringW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WriteProfileStringW,WriteProfileStringW,1575 diff --git a/libc/nt/kernel32/WriteTapemark.s b/libc/nt/kernel32/WriteTapemark.s new file mode 100644 index 00000000..1907cdff --- /dev/null +++ b/libc/nt/kernel32/WriteTapemark.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_WriteTapemark,WriteTapemark,1576 diff --git a/libc/nt/kernel32/ZombifyActCtxWorker.s b/libc/nt/kernel32/ZombifyActCtxWorker.s new file mode 100644 index 00000000..79ae6261 --- /dev/null +++ b/libc/nt/kernel32/ZombifyActCtxWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_ZombifyActCtxWorker,ZombifyActCtxWorker,1578 diff --git a/libc/nt/kernel32/_hread.s b/libc/nt/kernel32/_hread.s new file mode 100644 index 00000000..0444e40e --- /dev/null +++ b/libc/nt/kernel32/_hread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp__hread,_hread,1582 diff --git a/libc/nt/kernel32/_hwrite.s b/libc/nt/kernel32/_hwrite.s new file mode 100644 index 00000000..24d364da --- /dev/null +++ b/libc/nt/kernel32/_hwrite.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp__hwrite,_hwrite,1583 diff --git a/libc/nt/kernel32/_lclose.s b/libc/nt/kernel32/_lclose.s new file mode 100644 index 00000000..1ff92fdd --- /dev/null +++ b/libc/nt/kernel32/_lclose.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp__lclose,_lclose,1584 diff --git a/libc/nt/kernel32/_lcreat.s b/libc/nt/kernel32/_lcreat.s new file mode 100644 index 00000000..bf03eaeb --- /dev/null +++ b/libc/nt/kernel32/_lcreat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp__lcreat,_lcreat,1585 diff --git a/libc/nt/kernel32/_llseek.s b/libc/nt/kernel32/_llseek.s new file mode 100644 index 00000000..da8081d1 --- /dev/null +++ b/libc/nt/kernel32/_llseek.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp__llseek,_llseek,1586 diff --git a/libc/nt/kernel32/_lopen.s b/libc/nt/kernel32/_lopen.s new file mode 100644 index 00000000..778ad947 --- /dev/null +++ b/libc/nt/kernel32/_lopen.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp__lopen,_lopen,1588 diff --git a/libc/nt/kernel32/_lread.s b/libc/nt/kernel32/_lread.s new file mode 100644 index 00000000..7acd0848 --- /dev/null +++ b/libc/nt/kernel32/_lread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp__lread,_lread,1589 diff --git a/libc/nt/kernel32/_lwrite.s b/libc/nt/kernel32/_lwrite.s new file mode 100644 index 00000000..fb8cc513 --- /dev/null +++ b/libc/nt/kernel32/_lwrite.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp__lwrite,_lwrite,1590 diff --git a/libc/nt/kernel32/lstrcatA.s b/libc/nt/kernel32/lstrcatA.s new file mode 100644 index 00000000..69039a38 --- /dev/null +++ b/libc/nt/kernel32/lstrcatA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_lstrcatA,lstrcatA,1592 diff --git a/libc/nt/kernel32/lstrcatW.s b/libc/nt/kernel32/lstrcatW.s new file mode 100644 index 00000000..5a541e07 --- /dev/null +++ b/libc/nt/kernel32/lstrcatW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_lstrcatW,lstrcatW,1593 diff --git a/libc/nt/kernel32/lstrcpyA.s b/libc/nt/kernel32/lstrcpyA.s new file mode 100644 index 00000000..61e877d2 --- /dev/null +++ b/libc/nt/kernel32/lstrcpyA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_lstrcpyA,lstrcpyA,1601 diff --git a/libc/nt/kernel32/lstrcpyW.s b/libc/nt/kernel32/lstrcpyW.s new file mode 100644 index 00000000..0a1f0d75 --- /dev/null +++ b/libc/nt/kernel32/lstrcpyW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_lstrcpyW,lstrcpyW,1602 diff --git a/libc/nt/kernel32/timeBeginPeriod.s b/libc/nt/kernel32/timeBeginPeriod.s new file mode 100644 index 00000000..890c9a15 --- /dev/null +++ b/libc/nt/kernel32/timeBeginPeriod.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_timeBeginPeriod,timeBeginPeriod,1609 diff --git a/libc/nt/kernel32/timeEndPeriod.s b/libc/nt/kernel32/timeEndPeriod.s new file mode 100644 index 00000000..8fa1e3f3 --- /dev/null +++ b/libc/nt/kernel32/timeEndPeriod.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_timeEndPeriod,timeEndPeriod,1610 diff --git a/libc/nt/kernel32/timeGetDevCaps.s b/libc/nt/kernel32/timeGetDevCaps.s new file mode 100644 index 00000000..28c17c21 --- /dev/null +++ b/libc/nt/kernel32/timeGetDevCaps.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_timeGetDevCaps,timeGetDevCaps,1611 diff --git a/libc/nt/kernel32/timeGetSystemTime.s b/libc/nt/kernel32/timeGetSystemTime.s new file mode 100644 index 00000000..d5ff24c8 --- /dev/null +++ b/libc/nt/kernel32/timeGetSystemTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_timeGetSystemTime,timeGetSystemTime,1612 diff --git a/libc/nt/kernel32/timeGetTime.s b/libc/nt/kernel32/timeGetTime.s new file mode 100644 index 00000000..9f36a66d --- /dev/null +++ b/libc/nt/kernel32/timeGetTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_timeGetTime,timeGetTime,1613 diff --git a/libc/nt/kernel32/uaw_lstrcmpW.s b/libc/nt/kernel32/uaw_lstrcmpW.s new file mode 100644 index 00000000..807501a4 --- /dev/null +++ b/libc/nt/kernel32/uaw_lstrcmpW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_uaw_lstrcmpW,uaw_lstrcmpW,1614 diff --git a/libc/nt/kernel32/uaw_lstrcmpiW.s b/libc/nt/kernel32/uaw_lstrcmpiW.s new file mode 100644 index 00000000..5a894917 --- /dev/null +++ b/libc/nt/kernel32/uaw_lstrcmpiW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_uaw_lstrcmpiW,uaw_lstrcmpiW,1615 diff --git a/libc/nt/kernel32/uaw_lstrlenW.s b/libc/nt/kernel32/uaw_lstrlenW.s new file mode 100644 index 00000000..da7f470d --- /dev/null +++ b/libc/nt/kernel32/uaw_lstrlenW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_uaw_lstrlenW,uaw_lstrlenW,1616 diff --git a/libc/nt/kernel32/uaw_wcschr.s b/libc/nt/kernel32/uaw_wcschr.s new file mode 100644 index 00000000..888a7421 --- /dev/null +++ b/libc/nt/kernel32/uaw_wcschr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_uaw_wcschr,uaw_wcschr,1617 diff --git a/libc/nt/kernel32/uaw_wcscpy.s b/libc/nt/kernel32/uaw_wcscpy.s new file mode 100644 index 00000000..4eae5f31 --- /dev/null +++ b/libc/nt/kernel32/uaw_wcscpy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_uaw_wcscpy,uaw_wcscpy,1618 diff --git a/libc/nt/kernel32/uaw_wcsicmp.s b/libc/nt/kernel32/uaw_wcsicmp.s new file mode 100644 index 00000000..e58af705 --- /dev/null +++ b/libc/nt/kernel32/uaw_wcsicmp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_uaw_wcsicmp,uaw_wcsicmp,1619 diff --git a/libc/nt/kernel32/uaw_wcslen.s b/libc/nt/kernel32/uaw_wcslen.s new file mode 100644 index 00000000..daca04a4 --- /dev/null +++ b/libc/nt/kernel32/uaw_wcslen.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_uaw_wcslen,uaw_wcslen,1620 diff --git a/libc/nt/kernel32/uaw_wcsrchr.s b/libc/nt/kernel32/uaw_wcsrchr.s new file mode 100644 index 00000000..e42fbf95 --- /dev/null +++ b/libc/nt/kernel32/uaw_wcsrchr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_uaw_wcsrchr,uaw_wcsrchr,1621 diff --git a/libc/nt/master.sh b/libc/nt/master.sh new file mode 100755 index 00000000..509f54f1 --- /dev/null +++ b/libc/nt/master.sh @@ -0,0 +1,7970 @@ +/*bin/echo ' -*- mode:sh; indent-tabs-mode:nil; tab-width:8; coding:utf-8 -*-│ +│vi: set net ft=sh ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚────────────────────────────────────────────────────────────────'>/dev/null #*/ +. libc/nt/codegen.sh + +# The New Technology API +# » so many sections +# +# Name Actual DLL Hint Arity +imp 'A_SHAInit' A_SHAInit ntdll 10 +imp 'A_SHAUpdate' A_SHAUpdate ntdll 11 +imp 'A_SHAFinal' A_SHAFinal ntdll 9 +imp 'AbortDoc' AbortDoc gdi32 1011 +imp 'AbortPath' AbortPath gdi32 1012 +imp 'AbortSystemShutdownA' AbortSystemShutdownA advapi32 1005 +imp 'AbortSystemShutdown' AbortSystemShutdownW advapi32 1006 +imp 'AcceptEx' AcceptEx MsWSock 1 8 +imp 'AccessCheck' AccessCheck KernelBase 2 8 +imp 'AccessCheckAndAuditAlarm' AccessCheckAndAuditAlarmW KernelBase 3 +imp 'AccessCheckAndAuditAlarmA' AccessCheckAndAuditAlarmA advapi32 1008 +imp 'AccessCheckByType' AccessCheckByType KernelBase 4 +imp 'AccessCheckByTypeAndAuditAlarm' AccessCheckByTypeAndAuditAlarmW KernelBase 5 +imp 'AccessCheckByTypeAndAuditAlarmA' AccessCheckByTypeAndAuditAlarmA advapi32 1011 +imp 'AccessCheckByTypeResultList' AccessCheckByTypeResultList KernelBase 6 +imp 'AccessCheckByTypeResultListAndAuditAlarm' AccessCheckByTypeResultListAndAuditAlarmW KernelBase 8 +imp 'AccessCheckByTypeResultListAndAuditAlarmA' AccessCheckByTypeResultListAndAuditAlarmA advapi32 1014 +imp 'AccessCheckByTypeResultListAndAuditAlarmByHandle' AccessCheckByTypeResultListAndAuditAlarmByHandleW KernelBase 7 +imp 'AccessCheckByTypeResultListAndAuditAlarmByHandleA' AccessCheckByTypeResultListAndAuditAlarmByHandleA advapi32 1015 +imp 'AcquireStateLock' AcquireStateLock KernelBase 11 +imp 'ActivateActCtx' ActivateActCtx KernelBase 12 +imp 'ActivateActCtxWorker' ActivateActCtxWorker kernel32 4 +imp 'ActivateKeyboardLayout' ActivateKeyboardLayout user32 1505 +imp 'AddAccessAllowedAce' AddAccessAllowedAce KernelBase 13 +imp 'AddAccessAllowedAceEx' AddAccessAllowedAceEx KernelBase 14 +imp 'AddAccessAllowedObjectAce' AddAccessAllowedObjectAce KernelBase 15 +imp 'AddAccessDeniedAce' AddAccessDeniedAce KernelBase 16 +imp 'AddAccessDeniedAceEx' AddAccessDeniedAceEx KernelBase 17 +imp 'AddAccessDeniedObjectAce' AddAccessDeniedObjectAce KernelBase 18 +imp 'AddAce' AddAce KernelBase 19 +imp 'AddAtomA' AddAtomA kernel32 5 +imp 'AddAtom' AddAtomW kernel32 6 +imp 'AddAuditAccessAce' AddAuditAccessAce KernelBase 20 +imp 'AddAuditAccessAceEx' AddAuditAccessAceEx KernelBase 21 +imp 'AddAuditAccessObjectAce' AddAuditAccessObjectAce KernelBase 22 +imp 'AddClipboardFormatListener' AddClipboardFormatListener user32 1506 +imp 'AddConditionalAce' AddConditionalAce advapi32 1028 +imp 'AddConsoleAliasA' AddConsoleAliasA KernelBase 23 +imp 'AddConsoleAlias' AddConsoleAliasW KernelBase 24 +imp 'AddDllDirectory' AddDllDirectory KernelBase 25 +imp 'AddExtensionProgId' AddExtensionProgId KernelBase 26 +imp 'AddFontMemResourceEx' AddFontMemResourceEx gdi32 1017 +imp 'AddFontResourceA' AddFontResourceA gdi32 1018 +imp 'AddFontResourceExA' AddFontResourceExA gdi32 1019 +imp 'AddFontResourceEx' AddFontResourceExW gdi32 1020 +imp 'AddFontResourceTracking' AddFontResourceTracking gdi32 1021 +imp 'AddFontResource' AddFontResourceW gdi32 1022 +imp 'AddIntegrityLabelToBoundaryDescriptor' AddIntegrityLabelToBoundaryDescriptor kernel32 10 +imp 'AddLocalAlternateComputerNameA' AddLocalAlternateComputerNameA kernel32 11 +imp 'AddLocalAlternateComputerName' AddLocalAlternateComputerNameW kernel32 12 +imp 'AddMIMEFileTypesPS' AddMIMEFileTypesPS url 102 +imp 'AddMandatoryAce' AddMandatoryAce KernelBase 27 +imp 'AddPackageToFamilyXref' AddPackageToFamilyXref KernelBase 28 +imp 'AddRefActCtx' AddRefActCtx KernelBase 29 +imp 'AddRefActCtxWorker' AddRefActCtxWorker kernel32 14 +imp 'AddResourceAttributeAce' AddResourceAttributeAce KernelBase 30 +imp 'AddSIDToBoundaryDescriptor' AddSIDToBoundaryDescriptor KernelBase 31 +imp 'AddScopedPolicyIDAce' AddScopedPolicyIDAce KernelBase 32 +imp 'AddSecureMemoryCacheCallback' AddSecureMemoryCacheCallback kernel32 18 +imp 'AddUsersToEncryptedFile' AddUsersToEncryptedFile advapi32 1030 +imp 'AddUsersToEncryptedFileEx' AddUsersToEncryptedFileEx advapi32 1031 +imp 'AddVectoredExceptionHandler' AddVectoredExceptionHandler KernelBase 34 2 +imp 'AddVectoredContinueHandler' AddVectoredContinueHandler KernelBase 33 2 +imp 'RemoveVectoredExceptionHandler' RemoveVectoredExceptionHandler KernelBase 1407 1 +imp 'RemoveVectoredContinueHandler' RemoveVectoredContinueHandler KernelBase 1406 1 +imp 'AdjustCalendarDate' AdjustCalendarDate kernel32 21 +imp 'AdjustTokenGroups' AdjustTokenGroups KernelBase 35 +imp 'AdjustTokenPrivileges' AdjustTokenPrivileges KernelBase 36 6 +imp 'AdjustWindowRect' AdjustWindowRect user32 1507 +imp 'AdjustWindowRectEx' AdjustWindowRectEx user32 1508 +imp 'AdjustWindowRectExForDpi' AdjustWindowRectExForDpi user32 1509 +imp 'AlignRects' AlignRects user32 1510 +imp 'AllocConsole' AllocConsole KernelBase 37 0 +imp 'AllocateAndInitializeSid' AllocateAndInitializeSid KernelBase 38 +imp 'AllocateLocallyUniqueId' AllocateLocallyUniqueId KernelBase 39 +imp 'AllocateUserPhysicalPages' AllocateUserPhysicalPages KernelBase 40 +imp 'AllocateUserPhysicalPagesNuma' AllocateUserPhysicalPagesNuma KernelBase 41 +imp 'AllowForegroundActivation' AllowForegroundActivation user32 1511 +imp 'AllowSetForegroundWindow' AllowSetForegroundWindow user32 1512 +imp 'AlpcAdjustCompletionListConcurrencyCount' AlpcAdjustCompletionListConcurrencyCount ntdll 12 +imp 'AlpcFreeCompletionListMessage' AlpcFreeCompletionListMessage ntdll 13 +imp 'AlpcGetCompletionListLastMessageInformation' AlpcGetCompletionListLastMessageInformation ntdll 14 +imp 'AlpcGetCompletionListMessageAttributes' AlpcGetCompletionListMessageAttributes ntdll 15 +imp 'AlpcGetHeaderSize' AlpcGetHeaderSize ntdll 16 +imp 'AlpcGetMessageAttribute' AlpcGetMessageAttribute ntdll 17 +imp 'AlpcGetMessageFromCompletionList' AlpcGetMessageFromCompletionList ntdll 18 +imp 'AlpcGetOutstandingCompletionListMessageCount' AlpcGetOutstandingCompletionListMessageCount ntdll 19 +imp 'AlpcInitializeMessageAttribute' AlpcInitializeMessageAttribute ntdll 20 +imp 'AlpcMaxAllowedMessageLength' AlpcMaxAllowedMessageLength ntdll 21 +imp 'AlpcRegisterCompletionList' AlpcRegisterCompletionList ntdll 22 +imp 'AlpcRegisterCompletionListWorkerThread' AlpcRegisterCompletionListWorkerThread ntdll 23 +imp 'AlpcRundownCompletionList' AlpcRundownCompletionList ntdll 24 +imp 'AlpcUnregisterCompletionList' AlpcUnregisterCompletionList ntdll 25 +imp 'AlpcUnregisterCompletionListWorkerThread' AlpcUnregisterCompletionListWorkerThread ntdll 26 +imp 'AngleArc' AngleArc gdi32 1023 +imp 'AnimatePalette' AnimatePalette gdi32 1024 +imp 'AnimateWindow' AnimateWindow user32 1513 3 +imp 'AnyLinkedFonts' AnyLinkedFonts gdi32 1025 +imp 'AnyPopup' AnyPopup user32 1514 +imp 'ApiSetQueryApiSetPresence' ApiSetQueryApiSetPresence ntdll 27 +imp 'AppCompat_RunDLLW' AppCompat_RunDLLW shell32 255 +imp 'AppContainerDeriveSidFromMoniker' AppContainerDeriveSidFromMoniker KernelBase 42 +imp 'AppContainerFreeMemory' AppContainerFreeMemory KernelBase 43 +imp 'AppContainerLookupDisplayNameMrtReference' AppContainerLookupDisplayNameMrtReference KernelBase 44 +imp 'AppContainerLookupMoniker' AppContainerLookupMoniker KernelBase 45 +imp 'AppContainerRegisterSid' AppContainerRegisterSid KernelBase 46 +imp 'AppContainerUnregisterSid' AppContainerUnregisterSid KernelBase 47 +imp 'AppPolicyGetClrCompat' AppPolicyGetClrCompat KernelBase 48 +imp 'AppPolicyGetCreateFileAccess' AppPolicyGetCreateFileAccess KernelBase 49 +imp 'AppPolicyGetLifecycleManagement' AppPolicyGetLifecycleManagement KernelBase 50 +imp 'AppPolicyGetMediaFoundationCodecLoading' AppPolicyGetMediaFoundationCodecLoading KernelBase 51 +imp 'AppPolicyGetProcessTerminationMethod' AppPolicyGetProcessTerminationMethod KernelBase 52 +imp 'AppPolicyGetShowDeveloperDiagnostic' AppPolicyGetShowDeveloperDiagnostic KernelBase 53 +imp 'AppPolicyGetThreadInitializationType' AppPolicyGetThreadInitializationType KernelBase 54 +imp 'AppPolicyGetWindowingModel' AppPolicyGetWindowingModel KernelBase 55 +imp 'AppXFreeMemory' AppXFreeMemory KernelBase 56 +imp 'AppXGetApplicationData' AppXGetApplicationData KernelBase 57 +imp 'AppXGetDevelopmentMode' AppXGetDevelopmentMode KernelBase 58 +imp 'AppXGetOSMaxVersionTested' AppXGetOSMaxVersionTested KernelBase 59 +imp 'AppXGetOSMinVersion' AppXGetOSMinVersion KernelBase 60 +imp 'AppXGetPackageCapabilities' AppXGetPackageCapabilities KernelBase 61 +imp 'AppXGetPackageSid' AppXGetPackageSid KernelBase 62 +imp 'AppXLookupDisplayName' AppXLookupDisplayName KernelBase 63 +imp 'AppXLookupMoniker' AppXLookupMoniker KernelBase 64 +imp 'AppXPostSuccessExtension' AppXPostSuccessExtension KernelBase 65 +imp 'AppXPreCreationExtension' AppXPreCreationExtension KernelBase 66 +imp 'AppXReleaseAppXContext' AppXReleaseAppXContext KernelBase 67 +imp 'AppXUpdatePackageCapabilities' AppXUpdatePackageCapabilities KernelBase 68 +imp 'AppendMenuA' AppendMenuA user32 1515 +imp 'AppendMenu' AppendMenuW user32 1516 +imp 'ApplicationRecoveryFinished' ApplicationRecoveryFinished kernel32 34 +imp 'ApplicationRecoveryInProgress' ApplicationRecoveryInProgress kernel32 35 +imp 'ApplicationUserModelIdFromProductId' ApplicationUserModelIdFromProductId KernelBase 69 +imp 'Arc' Arc gdi32 1026 +imp 'ArcTo' ArcTo gdi32 1027 +imp 'AreAllAccessesGranted' AreAllAccessesGranted KernelBase 70 +imp 'AreAnyAccessesGranted' AreAnyAccessesGranted KernelBase 71 +imp 'AreDpiAwarenessContextsEqual' AreDpiAwarenessContextsEqual user32 1517 +imp 'AreFileApisANSI' AreFileApisANSI KernelBase 72 +imp 'AreThereVisibleLogoffScriptsInternal' AreThereVisibleLogoffScriptsInternal KernelBase 73 +imp 'AreThereVisibleShutdownScriptsInternal' AreThereVisibleShutdownScriptsInternal KernelBase 74 +imp 'ArrangeIconicWindows' ArrangeIconicWindows user32 1518 +imp 'AssignProcessToJobObject' AssignProcessToJobObject kernel32 37 +imp 'AssocCreateForClasses' AssocCreateForClasses shell32 263 +imp 'AssocGetDetailsOfPropKey' AssocGetDetailsOfPropKey shell32 267 +imp 'AttachConsole' AttachConsole KernelBase 75 1 +imp 'AttachThreadInput' AttachThreadInput user32 1519 +imp 'AuditComputeEffectivePolicyBySid' AuditComputeEffectivePolicyBySid advapi32 1038 +imp 'AuditComputeEffectivePolicyByToken' AuditComputeEffectivePolicyByToken advapi32 1039 +imp 'AuditEnumerateCategories' AuditEnumerateCategories advapi32 1040 +imp 'AuditEnumeratePerUserPolicy' AuditEnumeratePerUserPolicy advapi32 1041 +imp 'AuditEnumerateSubCategories' AuditEnumerateSubCategories advapi32 1042 +imp 'AuditFree' AuditFree advapi32 1043 +imp 'AuditLookupCategoryGuidFromCategoryId' AuditLookupCategoryGuidFromCategoryId advapi32 1044 +imp 'AuditLookupCategoryIdFromCategoryGuid' AuditLookupCategoryIdFromCategoryGuid advapi32 1045 +imp 'AuditLookupCategoryNameA' AuditLookupCategoryNameA advapi32 1046 +imp 'AuditLookupCategoryName' AuditLookupCategoryNameW advapi32 1047 +imp 'AuditLookupSubCategoryNameA' AuditLookupSubCategoryNameA advapi32 1048 +imp 'AuditLookupSubCategoryName' AuditLookupSubCategoryNameW advapi32 1049 +imp 'AuditQueryGlobalSaclA' AuditQueryGlobalSaclA advapi32 1050 +imp 'AuditQueryGlobalSacl' AuditQueryGlobalSaclW advapi32 1051 +imp 'AuditQueryPerUserPolicy' AuditQueryPerUserPolicy advapi32 1052 +imp 'AuditQuerySecurity' AuditQuerySecurity advapi32 1053 +imp 'AuditQuerySystemPolicy' AuditQuerySystemPolicy advapi32 1054 +imp 'AuditSetGlobalSaclA' AuditSetGlobalSaclA advapi32 1055 +imp 'AuditSetGlobalSacl' AuditSetGlobalSaclW advapi32 1056 +imp 'AuditSetPerUserPolicy' AuditSetPerUserPolicy advapi32 1057 +imp 'AuditSetSecurity' AuditSetSecurity advapi32 1058 +imp 'AuditSetSystemPolicy' AuditSetSystemPolicy advapi32 1059 +imp 'AutodialHookCallback' AutodialHookCallback url 103 +imp 'BRUSHOBJ_hGetColorTransform' BRUSHOBJ_hGetColorTransform gdi32 1028 +imp 'BRUSHOBJ_pvAllocRbrush' BRUSHOBJ_pvAllocRbrush gdi32 1029 +imp 'BRUSHOBJ_pvGetRbrush' BRUSHOBJ_pvGetRbrush gdi32 1030 +imp 'BRUSHOBJ_ulGetBrushColor' BRUSHOBJ_ulGetBrushColor gdi32 1031 +imp 'BackupEventLogA' BackupEventLogA advapi32 1060 +imp 'BackupEventLog' BackupEventLogW advapi32 1061 +imp 'BackupRead' BackupRead kernel32 39 +imp 'BackupSeek' BackupSeek kernel32 40 +imp 'BackupWrite' BackupWrite kernel32 41 +imp 'BaseCheckAppcompatCache' BaseCheckAppcompatCache KernelBase 76 +imp 'BaseCheckAppcompatCacheEx' BaseCheckAppcompatCacheEx KernelBase 77 +imp 'BaseCheckAppcompatCacheExWorker' BaseCheckAppcompatCacheExWorker kernel32 44 +imp 'BaseCheckAppcompatCacheWorker' BaseCheckAppcompatCacheWorker kernel32 45 +imp 'BaseCheckElevation' BaseCheckElevation kernel32 46 +imp 'BaseCleanupAppcompatCacheSupport' BaseCleanupAppcompatCacheSupport KernelBase 78 +imp 'BaseCleanupAppcompatCacheSupportWorker' BaseCleanupAppcompatCacheSupportWorker kernel32 48 +imp 'BaseDestroyVDMEnvironment' BaseDestroyVDMEnvironment kernel32 49 +imp 'BaseDllFreeResourceId' BaseDllFreeResourceId KernelBase 79 +imp 'BaseDllMapResourceId' BaseDllMapResourceIdW KernelBase 80 +imp 'BaseDllReadWriteIniFile' BaseDllReadWriteIniFile kernel32 50 +imp 'BaseDumpAppcompatCache' BaseDumpAppcompatCache KernelBase 81 +imp 'BaseDumpAppcompatCacheWorker' BaseDumpAppcompatCacheWorker kernel32 52 +imp 'BaseElevationPostProcessing' BaseElevationPostProcessing kernel32 53 +imp 'BaseFlushAppcompatCache' BaseFlushAppcompatCache KernelBase 82 +imp 'BaseFlushAppcompatCacheWorker' BaseFlushAppcompatCacheWorker kernel32 55 +imp 'BaseFormatObjectAttributes' BaseFormatObjectAttributes KernelBase 83 +imp 'BaseFormatTimeOut' BaseFormatTimeOut kernel32 57 +imp 'BaseFreeAppCompatDataForProcess' BaseFreeAppCompatDataForProcess KernelBase 84 +imp 'BaseFreeAppCompatDataForProcessWorker' BaseFreeAppCompatDataForProcessWorker kernel32 58 +imp 'BaseGenerateAppCompatData' BaseGenerateAppCompatData kernel32 59 +imp 'BaseGetConsoleReference' BaseGetConsoleReference KernelBase 85 +imp 'BaseGetNamedObjectDirectory' BaseGetNamedObjectDirectory KernelBase 86 +imp 'BaseInitAppcompatCacheSupport' BaseInitAppcompatCacheSupport KernelBase 87 +imp 'BaseInitAppcompatCacheSupportWorker' BaseInitAppcompatCacheSupportWorker kernel32 62 +imp 'BaseIsAppcompatInfrastructureDisabled' BaseIsAppcompatInfrastructureDisabled KernelBase 88 +imp 'BaseIsAppcompatInfrastructureDisabledWorker' BaseIsAppcompatInfrastructureDisabledWorker kernel32 64 +imp 'BaseIsDosApplication' BaseIsDosApplication kernel32 65 +imp 'BaseMarkFileForDelete' BaseMarkFileForDelete KernelBase 89 +imp 'BaseQueryModuleData' BaseQueryModuleData kernel32 66 +imp 'BaseReadAppCompatDataForProcess' BaseReadAppCompatDataForProcess KernelBase 90 +imp 'BaseReadAppCompatDataForProcessWorker' BaseReadAppCompatDataForProcessWorker kernel32 67 +imp 'BaseRegCloseKey' BaseRegCloseKey advapi32 1062 +imp 'BaseRegCreateKey' BaseRegCreateKey advapi32 1063 +imp 'BaseRegDeleteKeyEx' BaseRegDeleteKeyEx advapi32 1064 +imp 'BaseRegDeleteValue' BaseRegDeleteValue advapi32 1065 +imp 'BaseRegFlushKey' BaseRegFlushKey advapi32 1066 +imp 'BaseRegGetVersion' BaseRegGetVersion advapi32 1067 +imp 'BaseRegLoadKey' BaseRegLoadKey advapi32 1068 +imp 'BaseRegOpenKey' BaseRegOpenKey advapi32 1069 +imp 'BaseRegRestoreKey' BaseRegRestoreKey advapi32 1070 +imp 'BaseRegSaveKeyEx' BaseRegSaveKeyEx advapi32 1071 +imp 'BaseRegSetKeySecurity' BaseRegSetKeySecurity advapi32 1072 +imp 'BaseRegSetValue' BaseRegSetValue advapi32 1073 +imp 'BaseRegUnLoadKey' BaseRegUnLoadKey advapi32 1074 +imp 'BaseSetLastNTError' BaseSetLastNTError kernel32 68 +imp 'BaseThreadInitThunk' BaseThreadInitThunk kernel32 69 +imp 'BaseUpdateAppcompatCache' BaseUpdateAppcompatCache KernelBase 91 +imp 'BaseUpdateAppcompatCacheWorker' BaseUpdateAppcompatCacheWorker kernel32 71 +imp 'BaseUpdateVDMEntry' BaseUpdateVDMEntry kernel32 72 +imp 'BaseVerifyUnicodeString' BaseVerifyUnicodeString kernel32 73 +imp 'BaseWriteErrorElevationRequiredEvent' BaseWriteErrorElevationRequiredEvent kernel32 74 +imp 'Basep8BitStringToDynamicUnicodeString' Basep8BitStringToDynamicUnicodeString kernel32 75 +imp 'BasepAdjustObjectAttributesForPrivateNamespace' BasepAdjustObjectAttributesForPrivateNamespace KernelBase 92 +imp 'BasepAllocateActivationContextActivationBlock' BasepAllocateActivationContextActivationBlock kernel32 76 +imp 'BasepAnsiStringToDynamicUnicodeString' BasepAnsiStringToDynamicUnicodeString kernel32 77 +imp 'BasepAppContainerEnvironmentExtension' BasepAppContainerEnvironmentExtension kernel32 78 +imp 'BasepAppXExtension' BasepAppXExtension kernel32 79 +imp 'BasepCheckAppCompat' BasepCheckAppCompat kernel32 80 +imp 'BasepCheckWebBladeHashes' BasepCheckWebBladeHashes kernel32 81 +imp 'BasepCheckWinSaferRestrictions' BasepCheckWinSaferRestrictions kernel32 82 +imp 'BasepConstructSxsCreateProcessMessage' BasepConstructSxsCreateProcessMessage kernel32 83 +imp 'BasepCopyEncryption' BasepCopyEncryption kernel32 84 +imp 'BasepCopyFileCallback' BasepCopyFileCallback KernelBase 93 +imp 'BasepCopyFileEx' BasepCopyFileExW KernelBase 94 +imp 'BasepFreeActivationContextActivationBlock' BasepFreeActivationContextActivationBlock kernel32 85 +imp 'BasepFreeAppCompatData' BasepFreeAppCompatData kernel32 86 +imp 'BasepGetAppCompatData' BasepGetAppCompatData kernel32 87 +imp 'BasepGetComputerNameFromNtPath' BasepGetComputerNameFromNtPath kernel32 88 +imp 'BasepGetExeArchType' BasepGetExeArchType kernel32 89 +imp 'BasepInitAppCompatData' BasepInitAppCompatData kernel32 90 +imp 'BasepIsProcessAllowed' BasepIsProcessAllowed kernel32 91 +imp 'BasepMapModuleHandle' BasepMapModuleHandle kernel32 92 +imp 'BasepNotifyLoadStringResource' BasepNotifyLoadStringResource kernel32 93 +imp 'BasepNotifyTrackingService' BasepNotifyTrackingService KernelBase 95 +imp 'BasepPostSuccessAppXExtension' BasepPostSuccessAppXExtension kernel32 94 +imp 'BasepProcessInvalidImage' BasepProcessInvalidImage kernel32 95 +imp 'BasepQueryAppCompat' BasepQueryAppCompat kernel32 96 +imp 'BasepQueryModuleChpeSettings' BasepQueryModuleChpeSettings kernel32 97 +imp 'BasepReleaseAppXContext' BasepReleaseAppXContext kernel32 98 +imp 'BasepReleaseSxsCreateProcessUtilityStruct' BasepReleaseSxsCreateProcessUtilityStruct kernel32 99 +imp 'BasepReportFault' BasepReportFault kernel32 100 +imp 'BasepSetFileEncryptionCompression' BasepSetFileEncryptionCompression kernel32 101 +imp 'Beep' Beep KernelBase 96 +imp 'BeginDeferWindowPos' BeginDeferWindowPos user32 1520 +imp 'BeginGdiRendering' BeginGdiRendering gdi32 1032 +imp 'BeginPaint' BeginPaint user32 1521 2 +imp 'BeginPath' BeginPath gdi32 1033 +imp 'BeginUpdateResourceA' BeginUpdateResourceA kernel32 103 +imp 'BeginUpdateResource' BeginUpdateResourceW kernel32 104 +imp 'BindIoCompletionCallback' BindIoCompletionCallback kernel32 105 +imp 'BitBlt' BitBlt gdi32 1034 9 +imp 'BlockInput' BlockInput user32 1522 +imp 'BringWindowToTop' BringWindowToTop user32 1523 1 +imp 'BroadcastSystemMessageA' BroadcastSystemMessageA user32 1525 +imp 'BroadcastSystemMessageExA' BroadcastSystemMessageExA user32 1526 +imp 'BroadcastSystemMessageEx' BroadcastSystemMessageExW user32 1527 +imp 'BroadcastSystemMessage' BroadcastSystemMessageW user32 1528 +imp 'BuildCommDCBA' BuildCommDCBA kernel32 106 +imp 'BuildCommDCBAndTimeoutsA' BuildCommDCBAndTimeoutsA kernel32 107 +imp 'BuildCommDCBAndTimeouts' BuildCommDCBAndTimeoutsW kernel32 108 +imp 'BuildCommDCBW' BuildCommDCBW kernel32 109 +imp 'BuildExplicitAccessWithNameA' BuildExplicitAccessWithNameA advapi32 1075 +imp 'BuildExplicitAccessWithName' BuildExplicitAccessWithNameW advapi32 1076 +imp 'BuildImpersonateExplicitAccessWithNameA' BuildImpersonateExplicitAccessWithNameA advapi32 1077 +imp 'BuildImpersonateExplicitAccessWithName' BuildImpersonateExplicitAccessWithNameW advapi32 1078 +imp 'BuildImpersonateTrusteeA' BuildImpersonateTrusteeA advapi32 1079 +imp 'BuildImpersonateTrustee' BuildImpersonateTrusteeW advapi32 1080 +imp 'BuildReasonArray' BuildReasonArray user32 1529 +imp 'BuildSecurityDescriptorA' BuildSecurityDescriptorA advapi32 1081 +imp 'BuildSecurityDescriptor' BuildSecurityDescriptorW advapi32 1082 +imp 'BuildTrusteeWithNameA' BuildTrusteeWithNameA advapi32 1083 +imp 'BuildTrusteeWithName' BuildTrusteeWithNameW advapi32 1084 +imp 'BuildTrusteeWithObjectsAndNameA' BuildTrusteeWithObjectsAndNameA advapi32 1085 +imp 'BuildTrusteeWithObjectsAndName' BuildTrusteeWithObjectsAndNameW advapi32 1086 +imp 'BuildTrusteeWithObjectsAndSidA' BuildTrusteeWithObjectsAndSidA advapi32 1087 +imp 'BuildTrusteeWithObjectsAndSid' BuildTrusteeWithObjectsAndSidW advapi32 1088 +imp 'BuildTrusteeWithSidA' BuildTrusteeWithSidA advapi32 1089 +imp 'BuildTrusteeWithSid' BuildTrusteeWithSidW advapi32 1090 +imp 'CDefFolderMenu_Create2' CDefFolderMenu_Create2 shell32 701 +imp 'CIDLData_CreateFromIDArray' CIDLData_CreateFromIDArray shell32 83 +imp 'CLIPOBJ_bEnum' CLIPOBJ_bEnum gdi32 1035 +imp 'CLIPOBJ_cEnumStart' CLIPOBJ_cEnumStart gdi32 1036 +imp 'CLIPOBJ_ppoGetPath' CLIPOBJ_ppoGetPath gdi32 1037 +imp 'CLOSE_LOCAL_HANDLE_INTERNAL' CLOSE_LOCAL_HANDLE_INTERNAL KernelBase 97 +imp 'CStorageItem_GetValidatedStorageItemObject' CStorageItem_GetValidatedStorageItemObject shell32 937 +imp 'CalcMenuBar' CalcMenuBar user32 1530 +imp 'CalculatePopupWindowPosition' CalculatePopupWindowPosition user32 1531 +imp 'CallEnclave' CallEnclave KernelBase 98 +imp 'CallMsgFilter' CallMsgFilterW user32 1534 +imp 'CallMsgFilterA' CallMsgFilterA user32 1533 +imp 'CallNamedPipe' CallNamedPipeW KernelBase 99 7 +imp 'CallNamedPipeA' CallNamedPipeA kernel32 110 7 +imp 'CallNextHookEx' CallNextHookEx user32 1535 4 +imp 'CallWindowProcA' CallWindowProcA user32 1536 +imp 'CallWindowProc' CallWindowProcW user32 1537 +imp 'CallbackMayRunLong' CallbackMayRunLong KernelBase 100 +imp 'CancelDC' CancelDC gdi32 1038 +imp 'CancelDeviceWakeupRequest' CancelDeviceWakeupRequest kernel32 113 +imp 'CancelIo' CancelIo KernelBase 101 +imp 'CancelIoEx' CancelIoEx KernelBase 102 +imp 'CancelOverlappedAccess' CancelOverlappedAccess advapi32 1091 +imp 'CancelShutdown' CancelShutdown user32 1538 +imp 'CancelSynchronousIo' CancelSynchronousIo KernelBase 103 +imp 'CancelTimerQueueTimer' CancelTimerQueueTimer kernel32 118 +imp 'CancelWaitableTimer' CancelWaitableTimer KernelBase 105 +imp 'CascadeChildWindows' CascadeChildWindows user32 1539 +imp 'CascadeWindows' CascadeWindows user32 1540 +imp 'CeipIsOptedIn' CeipIsOptedIn KernelBase 106 +imp 'ChangeClipboardChain' ChangeClipboardChain user32 1541 +imp 'ChangeDisplaySettingsA' ChangeDisplaySettingsA user32 1542 +imp 'ChangeDisplaySettingsExA' ChangeDisplaySettingsExA user32 1543 +imp 'ChangeDisplaySettingsEx' ChangeDisplaySettingsExW user32 1544 +imp 'ChangeDisplaySettings' ChangeDisplaySettingsW user32 1545 +imp 'ChangeMenuA' ChangeMenuA user32 1546 +imp 'ChangeMenu' ChangeMenuW user32 1547 +imp 'ChangeServiceConfig2A' ChangeServiceConfig2A advapi32 1092 +imp 'ChangeServiceConfig2W' ChangeServiceConfig2W advapi32 1093 +imp 'ChangeServiceConfigA' ChangeServiceConfigA advapi32 1094 +imp 'ChangeServiceConfig' ChangeServiceConfigW advapi32 1095 +imp 'ChangeTimerQueueTimer' ChangeTimerQueueTimer KernelBase 107 +imp 'ChangeWindowMessageFilter' ChangeWindowMessageFilter user32 1548 +imp 'ChangeWindowMessageFilterEx' ChangeWindowMessageFilterEx user32 1549 +imp 'CharLowerA' CharLowerA KernelBase 108 +imp 'CharLowerBuffA' CharLowerBuffA KernelBase 109 +imp 'CharLowerBuff' CharLowerBuffW KernelBase 110 +imp 'CharLower' CharLowerW KernelBase 111 +imp 'CharNextA' CharNextA KernelBase 112 +imp 'CharNextExA' CharNextExA KernelBase 113 +imp 'CharNext' CharNextW KernelBase 114 +imp 'CharPrevA' CharPrevA KernelBase 115 +imp 'CharPrevExA' CharPrevExA KernelBase 116 +imp 'CharPrev' CharPrevW KernelBase 117 +imp 'CharToOemA' CharToOemA user32 1565 +imp 'CharToOemBuff' CharToOemBuffW user32 1567 +imp 'CharToOemBuffA' CharToOemBuffA user32 1566 +imp 'CharToOem' CharToOemW user32 1568 +imp 'CharUpper' CharUpperW KernelBase 121 +imp 'CharUpperA' CharUpperA KernelBase 118 +imp 'CharUpperBuffA' CharUpperBuffA KernelBase 119 +imp 'CharUpperBuff' CharUpperBuffW KernelBase 120 +imp 'CheckAllowDecryptedRemoteDestinationPolicy' CheckAllowDecryptedRemoteDestinationPolicy KernelBase 122 +imp 'CheckColorsInGamut' CheckColorsInGamut gdi32 1039 +imp 'CheckDBCSEnabledExt' CheckDBCSEnabledExt user32 1573 +imp 'CheckDlgButton' CheckDlgButton user32 1574 +imp 'CheckElevation' CheckElevation kernel32 123 +imp 'CheckElevationEnabled' CheckElevationEnabled kernel32 124 +imp 'CheckEscapes' CheckEscapesW shell32 268 +imp 'CheckForHiberboot' CheckForHiberboot advapi32 1096 +imp 'CheckForReadOnlyResource' CheckForReadOnlyResource kernel32 125 +imp 'CheckForReadOnlyResourceFilter' CheckForReadOnlyResourceFilter kernel32 126 +imp 'CheckGroupPolicyEnabled' CheckGroupPolicyEnabled KernelBase 123 +imp 'CheckIfStateChangeNotificationExists' CheckIfStateChangeNotificationExists KernelBase 124 +imp 'CheckMenuItem' CheckMenuItem user32 1575 +imp 'CheckMenuRadioItem' CheckMenuRadioItem user32 1576 +imp 'CheckNameLegalDOS8Dot3A' CheckNameLegalDOS8Dot3A kernel32 127 +imp 'CheckNameLegalDOS8Dot3W' CheckNameLegalDOS8Dot3W kernel32 128 +imp 'CheckProcessForClipboardAccess' CheckProcessForClipboardAccess user32 1577 +imp 'CheckProcessSession' CheckProcessSession user32 1578 +imp 'CheckRadioButton' CheckRadioButton user32 1579 +imp 'CheckRemoteDebuggerPresent' CheckRemoteDebuggerPresent KernelBase 125 2 +imp 'CheckTokenCapability' CheckTokenCapability KernelBase 126 +imp 'CheckTokenMembership' CheckTokenMembership KernelBase 127 +imp 'CheckTokenMembershipEx' CheckTokenMembershipEx KernelBase 128 +imp 'CheckWindowThreadDesktop' CheckWindowThreadDesktop user32 1580 +imp 'ChildWindowFromPoint' ChildWindowFromPoint user32 1581 +imp 'ChildWindowFromPointEx' ChildWindowFromPointEx user32 1582 +imp 'ChooseColorA' ChooseColorA comdlg32 102 +imp 'ChooseColor' ChooseColorW comdlg32 103 +imp 'ChooseFontA' ChooseFontA comdlg32 104 +imp 'ChooseFont' ChooseFontW comdlg32 105 +imp 'ChoosePixelFormat' ChoosePixelFormat gdi32 1040 +imp 'Chord' Chord gdi32 1041 +imp 'ChrCmpIA' ChrCmpIA KernelBase 129 +imp 'ChrCmpIW' ChrCmpIW KernelBase 130 +imp 'ClearBitmapAttributes' ClearBitmapAttributes gdi32 1042 +imp 'ClearBrushAttributes' ClearBrushAttributes gdi32 1043 +imp 'ClearCommBreak' ClearCommBreak KernelBase 131 +imp 'ClearCommError' ClearCommError KernelBase 132 +imp 'ClearEventLogA' ClearEventLogA advapi32 1098 +imp 'ClearEventLog' ClearEventLogW advapi32 1099 +imp 'CliImmSetHotKey' CliImmSetHotKey user32 1583 +imp 'ClientThreadSetup' ClientThreadSetup user32 1584 +imp 'ClientToScreen' ClientToScreen user32 1585 +imp 'ClipCursor' ClipCursor user32 1586 +imp 'CloseClipboard' CloseClipboard user32 1587 +imp 'CloseCodeAuthzLevel' CloseCodeAuthzLevel advapi32 1100 +imp 'CloseConsoleHandle' CloseConsoleHandle kernel32 134 +imp 'CloseDesktop' CloseDesktop user32 1588 +imp 'CloseEncryptedFileRaw' CloseEncryptedFileRaw advapi32 1101 +imp 'CloseEnhMetaFile' CloseEnhMetaFile gdi32 1044 +imp 'CloseEventLog' CloseEventLog advapi32 1102 +imp 'CloseFigure' CloseFigure gdi32 1045 +imp 'CloseGestureInfoHandle' CloseGestureInfoHandle user32 1589 +imp 'CloseGlobalizationUserSettingsKey' CloseGlobalizationUserSettingsKey KernelBase 133 +imp 'CloseHandle' CloseHandle KernelBase 134 1 +imp 'CloseMetaFile' CloseMetaFile gdi32 1046 +imp 'ClosePackageInfo' ClosePackageInfo KernelBase 135 +imp 'ClosePrivateNamespace' ClosePrivateNamespace KernelBase 136 +imp 'CloseProfileUserMapping' CloseProfileUserMapping kernel32 138 +imp 'CloseServiceHandle' CloseServiceHandle advapi32 1103 +imp 'CloseState' CloseState KernelBase 137 +imp 'CloseStateAtom' CloseStateAtom KernelBase 138 +imp 'CloseStateChangeNotification' CloseStateChangeNotification KernelBase 139 +imp 'CloseStateContainer' CloseStateContainer KernelBase 140 +imp 'CloseStateLock' CloseStateLock KernelBase 141 +imp 'CloseThreadWaitChainSession' CloseThreadWaitChainSession advapi32 1104 +imp 'CloseTouchInputHandle' CloseTouchInputHandle user32 1590 +imp 'CloseTrace' CloseTrace advapi32 1105 +imp 'CloseWindow' CloseWindow user32 1591 1 +imp 'CloseWindowStation' CloseWindowStation user32 1592 +imp 'CmdBatNotification' CmdBatNotification kernel32 147 +imp 'ColorCorrectPalette' ColorCorrectPalette gdi32 1047 +imp 'ColorMatchToTarget' ColorMatchToTarget gdi32 1048 +imp 'CombineRgn' CombineRgn gdi32 1049 +imp 'CombineTransform' CombineTransform gdi32 1050 +imp 'CommConfigDialogA' CommConfigDialogA kernel32 148 +imp 'CommConfigDialog' CommConfigDialogW kernel32 149 +imp 'CommDlgExtendedError' CommDlgExtendedError comdlg32 106 +imp 'CommandLineFromMsiDescriptor' CommandLineFromMsiDescriptor advapi32 1106 +imp 'CommandLineToArgv' CommandLineToArgvW shell32 269 +imp 'CommitStateAtom' CommitStateAtom KernelBase 149 +imp 'CompareCalendarDates' CompareCalendarDates kernel32 150 +imp 'CompareFileTime' CompareFileTime KernelBase 150 +imp 'CompareObjectHandles' CompareObjectHandles KernelBase 151 +imp 'CompareStringA' CompareStringA KernelBase 152 +imp 'CompareStringEx' CompareStringEx KernelBase 153 +imp 'CompareStringOrdinal' CompareStringOrdinal KernelBase 154 +imp 'CompareString' CompareStringW KernelBase 155 +imp 'ComputeAccessTokenFromCodeAuthzLevel' ComputeAccessTokenFromCodeAuthzLevel advapi32 1107 +imp 'ConfigureOPMProtectedOutput' ConfigureOPMProtectedOutput gdi32 1051 +imp 'ConnectNamedPipe' ConnectNamedPipe KernelBase 156 2 +imp 'ConsoleControl' ConsoleControl user32 1593 +imp 'ConsoleMenuControl' ConsoleMenuControl kernel32 157 +imp 'ContinueDebugEvent' ContinueDebugEvent KernelBase 157 3 +imp 'ControlMagnification' ControlMagnification user32 1594 +imp 'ControlService' ControlService advapi32 1108 +imp 'ControlServiceExA' ControlServiceExA advapi32 1109 +imp 'ControlServiceEx' ControlServiceExW advapi32 1110 +imp 'ControlTraceA' ControlTraceA advapi32 1111 +imp 'ControlTrace' ControlTraceW advapi32 1112 +imp 'Control_RunDLL' Control_RunDLL shell32 272 +imp 'Control_RunDLLA' Control_RunDLLA shell32 273 +imp 'Control_RunDLLAsUser' Control_RunDLLAsUserW shell32 274 +imp 'Control_RunDLLW' Control_RunDLLW shell32 275 +imp 'ConvertAccessToSecurityDescriptorA' ConvertAccessToSecurityDescriptorA advapi32 1113 +imp 'ConvertAccessToSecurityDescriptor' ConvertAccessToSecurityDescriptorW advapi32 1114 +imp 'ConvertAuxiliaryCounterToPerformanceCounter' ConvertAuxiliaryCounterToPerformanceCounter KernelBase 158 +imp 'ConvertCalDateTimeToSystemTime' ConvertCalDateTimeToSystemTime kernel32 159 +imp 'ConvertDefaultLocale' ConvertDefaultLocale KernelBase 159 +imp 'ConvertFiberToThread' ConvertFiberToThread KernelBase 160 +imp 'ConvertNLSDayOfWeekToWin32DayOfWeek' ConvertNLSDayOfWeekToWin32DayOfWeek kernel32 162 +imp 'ConvertPerformanceCounterToAuxiliaryCounter' ConvertPerformanceCounterToAuxiliaryCounter KernelBase 161 +imp 'ConvertSDToStringSDDomain' ConvertSDToStringSDDomainW advapi32 1115 +imp 'ConvertSDToStringSDRootDomainA' ConvertSDToStringSDRootDomainA advapi32 1116 +imp 'ConvertSDToStringSDRootDomain' ConvertSDToStringSDRootDomainW advapi32 1117 +imp 'ConvertSecurityDescriptorToAccessA' ConvertSecurityDescriptorToAccessA advapi32 1118 +imp 'ConvertSecurityDescriptorToAccessNamedA' ConvertSecurityDescriptorToAccessNamedA advapi32 1119 +imp 'ConvertSecurityDescriptorToAccessNamed' ConvertSecurityDescriptorToAccessNamedW advapi32 1120 +imp 'ConvertSecurityDescriptorToAccess' ConvertSecurityDescriptorToAccessW advapi32 1121 +imp 'ConvertSecurityDescriptorToStringSecurityDescriptorA' ConvertSecurityDescriptorToStringSecurityDescriptorA advapi32 1122 +imp 'ConvertSecurityDescriptorToStringSecurityDescriptor' ConvertSecurityDescriptorToStringSecurityDescriptorW advapi32 1123 +imp 'ConvertSidToStringSidA' ConvertSidToStringSidA advapi32 1124 +imp 'ConvertSidToStringSid' ConvertSidToStringSidW advapi32 1125 +imp 'ConvertStringSDToSDDomainA' ConvertStringSDToSDDomainA advapi32 1126 +imp 'ConvertStringSDToSDDomain' ConvertStringSDToSDDomainW advapi32 1127 +imp 'ConvertStringSDToSDRootDomainA' ConvertStringSDToSDRootDomainA advapi32 1128 +imp 'ConvertStringSDToSDRootDomain' ConvertStringSDToSDRootDomainW advapi32 1129 +imp 'ConvertStringSecurityDescriptorToSecurityDescriptorA' ConvertStringSecurityDescriptorToSecurityDescriptorA advapi32 1130 +imp 'ConvertStringSecurityDescriptorToSecurityDescriptor' ConvertStringSecurityDescriptorToSecurityDescriptorW advapi32 1131 +imp 'ConvertStringSidToSidA' ConvertStringSidToSidA advapi32 1132 +imp 'ConvertStringSidToSid' ConvertStringSidToSidW advapi32 1133 +imp 'ConvertSystemTimeToCalDateTime' ConvertSystemTimeToCalDateTime kernel32 163 +imp 'ConvertThreadToFiber' ConvertThreadToFiber KernelBase 162 +imp 'ConvertThreadToFiberEx' ConvertThreadToFiberEx KernelBase 163 +imp 'ConvertToAutoInheritPrivateObjectSecurity' ConvertToAutoInheritPrivateObjectSecurity KernelBase 164 +imp 'CopyAcceleratorTable' CopyAcceleratorTableW user32 1596 +imp 'CopyAcceleratorTableA' CopyAcceleratorTableA user32 1595 +imp 'CopyContext' CopyContext KernelBase 165 +imp 'CopyEnhMetaFile' CopyEnhMetaFileW gdi32 1053 +imp 'CopyEnhMetaFileA' CopyEnhMetaFileA gdi32 1052 +imp 'CopyFile2' CopyFile2 KernelBase 166 +imp 'CopyFile' CopyFileW KernelBase 168 3 +imp 'CopyFileA' CopyFileA kernel32 168 3 +imp 'CopyFileEx' CopyFileExW KernelBase 167 +imp 'CopyFileExA' CopyFileExA kernel32 169 +imp 'CopyFileTransacted' CopyFileTransactedW kernel32 172 +imp 'CopyFileTransactedA' CopyFileTransactedA kernel32 171 +imp 'CopyIcon' CopyIcon user32 1597 +imp 'CopyImage' CopyImage user32 1598 +imp 'CopyLZFile' CopyLZFile kernel32 174 +imp 'CopyMetaFileA' CopyMetaFileA gdi32 1054 +imp 'CopyMetaFile' CopyMetaFileW gdi32 1055 +imp 'CopyRect' CopyRect user32 1599 +imp 'CopySid' CopySid KernelBase 170 +imp 'CouldMultiUserAppsBehaviorBePossibleForPackage' CouldMultiUserAppsBehaviorBePossibleForPackage KernelBase 171 +imp 'CountClipboardFormats' CountClipboardFormats user32 1600 +imp 'CreateAcceleratorTableA' CreateAcceleratorTableA user32 1601 +imp 'CreateAcceleratorTable' CreateAcceleratorTableW user32 1602 +imp 'CreateActCtxA' CreateActCtxA kernel32 175 +imp 'CreateActCtx' CreateActCtxW KernelBase 172 +imp 'CreateActCtxWWorker' CreateActCtxWWorker kernel32 177 +imp 'CreateAppContainerToken' CreateAppContainerToken KernelBase 173 +imp 'CreateAppContainerTokenForUser' CreateAppContainerTokenForUser KernelBase 174 +imp 'CreateBitmap' CreateBitmap gdi32 1056 +imp 'CreateBitmapFromDxSurface' CreateBitmapFromDxSurface gdi32 1057 +imp 'CreateBitmapFromDxSurface2' CreateBitmapFromDxSurface2 gdi32 1058 +imp 'CreateBitmapIndirect' CreateBitmapIndirect gdi32 1059 +imp 'CreateBoundaryDescriptorA' CreateBoundaryDescriptorA kernel32 178 +imp 'CreateBoundaryDescriptor' CreateBoundaryDescriptorW KernelBase 175 +imp 'CreateBrushIndirect' CreateBrushIndirect gdi32 1060 +imp 'CreateCaret' CreateCaret user32 1603 +imp 'CreateCodeAuthzLevel' CreateCodeAuthzLevel advapi32 1136 +imp 'CreateColorSpaceA' CreateColorSpaceA gdi32 1061 +imp 'CreateColorSpace' CreateColorSpaceW gdi32 1062 +imp 'CreateCompatibleBitmap' CreateCompatibleBitmap gdi32 1063 +imp 'CreateCompatibleDC' CreateCompatibleDC gdi32 1064 +imp 'CreateConsoleScreenBuffer' CreateConsoleScreenBuffer KernelBase 176 +imp 'CreateCursor' CreateCursor user32 1604 +imp 'CreateDCA' CreateDCA gdi32 1065 +imp 'CreateDCEx' CreateDCExW gdi32 2000 +imp 'CreateDCW' CreateDCW gdi32 1066 +imp 'CreateDCompositionHwndTarget' CreateDCompositionHwndTarget user32 1605 +imp 'CreateDIBPatternBrush' CreateDIBPatternBrush gdi32 1067 +imp 'CreateDIBPatternBrushPt' CreateDIBPatternBrushPt gdi32 1068 +imp 'CreateDIBSection' CreateDIBSection gdi32 1069 +imp 'CreateDIBitmap' CreateDIBitmap gdi32 1070 +imp 'CreateDPIScaledDIBSection' CreateDPIScaledDIBSection gdi32 1071 +imp 'CreateDesktopA' CreateDesktopA user32 1606 +imp 'CreateDesktopEx' CreateDesktopExW user32 1608 +imp 'CreateDesktopExA' CreateDesktopExA user32 1607 +imp 'CreateDesktop' CreateDesktopW user32 1609 +imp 'CreateDialogIndirectParamA' CreateDialogIndirectParamA user32 1610 +imp 'CreateDialogIndirectParamAor' CreateDialogIndirectParamAorW user32 1611 +imp 'CreateDialogIndirectParam' CreateDialogIndirectParamW user32 1612 +imp 'CreateDialogParamA' CreateDialogParamA user32 1613 +imp 'CreateDialogParam' CreateDialogParamW user32 1614 +imp 'CreateDirectory' CreateDirectoryW KernelBase 179 2 +imp 'CreateDirectoryA' CreateDirectoryA KernelBase 177 2 +imp 'CreateDirectoryExA' CreateDirectoryExA kernel32 182 +imp 'CreateDirectoryEx' CreateDirectoryExW KernelBase 178 +imp 'CreateDirectoryTransactedA' CreateDirectoryTransactedA kernel32 184 +imp 'CreateDirectoryTransacted' CreateDirectoryTransactedW kernel32 185 +imp 'CreateDiscardableBitmap' CreateDiscardableBitmap gdi32 1072 +imp 'CreateEllipticRgn' CreateEllipticRgn gdi32 1073 +imp 'CreateEllipticRgnIndirect' CreateEllipticRgnIndirect gdi32 1074 +imp 'CreateEnclave' CreateEnclave KernelBase 180 +imp 'CreateEnhMetaFileA' CreateEnhMetaFileA gdi32 1075 +imp 'CreateEnhMetaFile' CreateEnhMetaFileW gdi32 1076 +imp 'CreateEventA' CreateEventA KernelBase 181 +imp 'CreateEventExA' CreateEventExA KernelBase 182 +imp 'CreateEventEx' CreateEventExW KernelBase 183 +imp 'CreateEvent' CreateEventW KernelBase 184 +imp 'CreateFiber' CreateFiber KernelBase 185 +imp 'CreateFiberEx' CreateFiberEx KernelBase 186 +imp 'CreateFile' CreateFileW KernelBase 192 7 +imp 'CreateFileA' CreateFileA KernelBase 188 7 +imp 'CreateFileMappingNuma' CreateFileMappingNumaW KernelBase 190 7 +imp 'CreateFileMappingNumaA' CreateFileMappingNumaA kernel32 198 7 +imp 'CreateFileMapping' CreateFileMappingW KernelBase 191 7 +imp 'CreateFileMappingA' CreateFileMappingA kernel32 196 7 +imp 'CreateFileTransacted' CreateFileTransactedW kernel32 202 +imp 'CreateFileTransactedA' CreateFileTransactedA kernel32 201 +imp 'CreateFile2' CreateFile2 KernelBase 187 +imp 'CreateFileMappingFromApp' CreateFileMappingFromApp KernelBase 189 +imp 'CreateFontA' CreateFontA gdi32 1077 +imp 'CreateFontIndirectA' CreateFontIndirectA gdi32 1078 +imp 'CreateFontIndirectExA' CreateFontIndirectExA gdi32 1079 +imp 'CreateFontIndirectEx' CreateFontIndirectExW gdi32 1080 +imp 'CreateFontIndirect' CreateFontIndirectW gdi32 1081 +imp 'CreateFont' CreateFontW gdi32 1082 +imp 'CreateHalftonePalette' CreateHalftonePalette gdi32 1083 +imp 'CreateHardLink' CreateHardLinkW KernelBase 194 3 +imp 'CreateHardLinkA' CreateHardLinkA KernelBase 193 3 +imp 'CreateHardLinkTransactedA' CreateHardLinkTransactedA kernel32 205 +imp 'CreateHardLinkTransacted' CreateHardLinkTransactedW kernel32 206 +imp 'CreateHatchBrush' CreateHatchBrush gdi32 1084 +imp 'CreateICA' CreateICA gdi32 1085 +imp 'CreateICW' CreateICW gdi32 1086 +imp 'CreateIcon' CreateIcon user32 1615 +imp 'CreateIconFromResource' CreateIconFromResource user32 1616 +imp 'CreateIconFromResourceEx' CreateIconFromResourceEx user32 1617 +imp 'CreateIconIndirect' CreateIconIndirect user32 1618 +imp 'CreateIoCompletionPort' CreateIoCompletionPort KernelBase 195 +imp 'CreateJobObjectA' CreateJobObjectA kernel32 209 +imp 'CreateJobObject' CreateJobObjectW kernel32 210 +imp 'CreateJobSet' CreateJobSet kernel32 211 +imp 'CreateMDIWindowA' CreateMDIWindowA user32 1619 +imp 'CreateMDIWindow' CreateMDIWindowW user32 1620 +imp 'CreateMailslotA' CreateMailslotA kernel32 212 +imp 'CreateMailslot' CreateMailslotW kernel32 213 +imp 'CreateMemoryResourceNotification' CreateMemoryResourceNotification KernelBase 196 +imp 'CreateMenu' CreateMenu user32 1621 +imp 'CreateMetaFileA' CreateMetaFileA gdi32 1087 +imp 'CreateMetaFile' CreateMetaFileW gdi32 1088 +imp 'CreateMutex' CreateMutexW KernelBase 200 +imp 'CreateMutexA' CreateMutexA KernelBase 197 +imp 'CreateMutexEx' CreateMutexExW KernelBase 199 +imp 'CreateMutexExA' CreateMutexExA KernelBase 198 +imp 'CreateNamedPipe' CreateNamedPipeW KernelBase 201 8 +imp 'CreateNamedPipeA' CreateNamedPipeA kernel32 219 8 +imp 'CreateOPMProtectedOutput' CreateOPMProtectedOutput gdi32 1089 +imp 'CreateOPMProtectedOutputs' CreateOPMProtectedOutputs gdi32 1090 +imp 'CreatePalette' CreatePalette gdi32 1091 +imp 'CreatePalmRejectionDelayZone' CreatePalmRejectionDelayZone user32 1503 +imp 'CreatePatternBrush' CreatePatternBrush gdi32 1092 +imp 'CreatePen' CreatePen gdi32 1093 +imp 'CreatePenIndirect' CreatePenIndirect gdi32 1094 +imp 'CreatePipe' CreatePipe KernelBase 202 4 +imp 'CreatePolyPolygonRgn' CreatePolyPolygonRgn gdi32 1095 +imp 'CreatePolygonRgn' CreatePolygonRgn gdi32 1096 +imp 'CreatePopupMenu' CreatePopupMenu user32 1622 +imp 'CreatePrivateNamespaceA' CreatePrivateNamespaceA kernel32 222 +imp 'CreatePrivateNamespace' CreatePrivateNamespaceW KernelBase 203 +imp 'CreatePrivateObjectSecurity' CreatePrivateObjectSecurity KernelBase 204 +imp 'CreatePrivateObjectSecurityEx' CreatePrivateObjectSecurityEx KernelBase 205 +imp 'CreatePrivateObjectSecurityWithMultipleInheritance' CreatePrivateObjectSecurityWithMultipleInheritance KernelBase 206 +imp 'CreateProcessA' CreateProcessA KernelBase 207 10 +imp 'CreateProcess' CreateProcessW KernelBase 212 10 +imp 'CreateProcessAsUserA' CreateProcessAsUserA KernelBase 208 +imp 'CreateProcessAsUser' CreateProcessAsUserW KernelBase 209 +imp 'CreateProcessInternal' CreateProcessInternalW KernelBase 211 +imp 'CreateProcessInternalA' CreateProcessInternalA KernelBase 210 +imp 'CreateProcessWithLogon' CreateProcessWithLogonW advapi32 1142 +imp 'CreateProcessWithToken' CreateProcessWithTokenW advapi32 1143 +imp 'CreateRectRgn' CreateRectRgn gdi32 1097 +imp 'CreateRectRgnIndirect' CreateRectRgnIndirect gdi32 1098 +imp 'CreateRemoteThread' CreateRemoteThread KernelBase 213 +imp 'CreateRemoteThreadEx' CreateRemoteThreadEx KernelBase 214 +imp 'CreateRestrictedToken' CreateRestrictedToken KernelBase 215 +imp 'CreateRoundRectRgn' CreateRoundRectRgn gdi32 1099 +imp 'CreateScalableFontResourceA' CreateScalableFontResourceA gdi32 1100 +imp 'CreateScalableFontResource' CreateScalableFontResourceW gdi32 1101 +imp 'CreateSemaphoreA' CreateSemaphoreA kernel32 232 +imp 'CreateSemaphoreExA' CreateSemaphoreExA kernel32 233 +imp 'CreateSemaphoreEx' CreateSemaphoreExW KernelBase 216 +imp 'CreateSemaphore' CreateSemaphoreW KernelBase 217 +imp 'CreateServiceA' CreateServiceA advapi32 1145 +imp 'CreateServiceEx' CreateServiceEx advapi32 1146 +imp 'CreateService' CreateServiceW advapi32 1147 +imp 'CreateSessionMappedDIBSection' CreateSessionMappedDIBSection gdi32 1102 +imp 'CreateSolidBrush' CreateSolidBrush gdi32 1103 +imp 'CreateStateAtom' CreateStateAtom KernelBase 218 +imp 'CreateStateChangeNotification' CreateStateChangeNotification KernelBase 219 +imp 'CreateStateContainer' CreateStateContainer KernelBase 220 +imp 'CreateStateLock' CreateStateLock KernelBase 221 +imp 'CreateStateSubcontainer' CreateStateSubcontainer KernelBase 222 +imp 'CreateStorageItemFromPath_FullTrustCaller' CreateStorageItemFromPath_FullTrustCaller shell32 935 +imp 'CreateStorageItemFromPath_FullTrustCaller_ForPackage' CreateStorageItemFromPath_FullTrustCaller_ForPackage shell32 936 +imp 'CreateStorageItemFromPath_PartialTrustCaller' CreateStorageItemFromPath_PartialTrustCaller shell32 920 +imp 'CreateStorageItemFromShellItem_FullTrustCaller' CreateStorageItemFromShellItem_FullTrustCaller shell32 921 +imp 'CreateStorageItemFromShellItem_FullTrustCaller_ForPackage' CreateStorageItemFromShellItem_FullTrustCaller_ForPackage shell32 925 +imp 'CreateStorageItemFromShellItem_FullTrustCaller_ForPackage_WithProcessHandle' CreateStorageItemFromShellItem_FullTrustCaller_ForPackage_WithProcessHandle shell32 929 +imp 'CreateStorageItemFromShellItem_FullTrustCaller_UseImplicitFlagsAndPackage' CreateStorageItemFromShellItem_FullTrustCaller_UseImplicitFlagsAndPackage shell32 931 +imp 'CreateSymbolicLink' CreateSymbolicLinkW KernelBase 223 3 +imp 'CreateSymbolicLinkA' CreateSymbolicLinkA kernel32 236 3 +imp 'CreateSymbolicLinkTransactedA' CreateSymbolicLinkTransactedA kernel32 237 +imp 'CreateSymbolicLinkTransacted' CreateSymbolicLinkTransactedW kernel32 238 +imp 'CreateSystemThreads' CreateSystemThreads user32 1623 +imp 'CreateTapePartition' CreateTapePartition kernel32 240 +imp 'CreateThread' CreateThread KernelBase 224 +imp 'CreateThreadpool' CreateThreadpool KernelBase 225 +imp 'CreateThreadpoolCleanupGroup' CreateThreadpoolCleanupGroup KernelBase 226 +imp 'CreateThreadpoolIo' CreateThreadpoolIo KernelBase 227 +imp 'CreateThreadpoolTimer' CreateThreadpoolTimer KernelBase 228 +imp 'CreateThreadpoolWait' CreateThreadpoolWait KernelBase 229 +imp 'CreateThreadpoolWork' CreateThreadpoolWork KernelBase 230 +imp 'CreateTimerQueue' CreateTimerQueue KernelBase 231 +imp 'CreateTimerQueueTimer' CreateTimerQueueTimer KernelBase 232 +imp 'CreateToolhelp32Snapshot' CreateToolhelp32Snapshot kernel32 250 +imp 'CreateUmsCompletionList' CreateUmsCompletionList kernel32 251 +imp 'CreateUmsThreadContext' CreateUmsThreadContext kernel32 252 +imp 'CreateWaitableTimerA' CreateWaitableTimerA kernel32 253 +imp 'CreateWaitableTimerExA' CreateWaitableTimerExA kernel32 254 +imp 'CreateWaitableTimerEx' CreateWaitableTimerExW KernelBase 233 +imp 'CreateWaitableTimer' CreateWaitableTimerW KernelBase 234 +imp 'CreateWellKnownSid' CreateWellKnownSid KernelBase 235 +imp 'CreateWindowEx' CreateWindowExW user32 1625 12 +imp 'CreateWindowExA' CreateWindowExA user32 1624 12 +imp 'CreateWindowInBand' CreateWindowInBand user32 1626 +imp 'CreateWindowInBandEx' CreateWindowInBandEx user32 1627 +imp 'CreateWindowIndirect' CreateWindowIndirect user32 1628 +imp 'CreateWindowStationA' CreateWindowStationA user32 1629 +imp 'CreateWindowStation' CreateWindowStationW user32 1630 +imp 'CredBackupCredentials' CredBackupCredentials advapi32 1150 +imp 'CredDeleteA' CredDeleteA advapi32 1151 +imp 'CredDelete' CredDeleteW advapi32 1152 +imp 'CredEncryptAndMarshalBinaryBlob' CredEncryptAndMarshalBinaryBlob advapi32 1153 +imp 'CredEnumerateA' CredEnumerateA advapi32 1154 +imp 'CredEnumerate' CredEnumerateW advapi32 1155 +imp 'CredFindBestCredentialA' CredFindBestCredentialA advapi32 1156 +imp 'CredFindBestCredential' CredFindBestCredentialW advapi32 1157 +imp 'CredFree' CredFree advapi32 1158 +imp 'CredGetSessionTypes' CredGetSessionTypes advapi32 1159 +imp 'CredGetTargetInfoA' CredGetTargetInfoA advapi32 1160 +imp 'CredGetTargetInfo' CredGetTargetInfoW advapi32 1161 +imp 'CredIsMarshaledCredentialA' CredIsMarshaledCredentialA advapi32 1162 +imp 'CredIsMarshaledCredential' CredIsMarshaledCredentialW advapi32 1163 +imp 'CredIsProtectedA' CredIsProtectedA advapi32 1164 +imp 'CredIsProtected' CredIsProtectedW advapi32 1165 +imp 'CredMarshalCredentialA' CredMarshalCredentialA advapi32 1166 +imp 'CredMarshalCredential' CredMarshalCredentialW advapi32 1167 +imp 'CredProfileLoaded' CredProfileLoaded advapi32 1168 +imp 'CredProfileLoadedEx' CredProfileLoadedEx advapi32 1169 +imp 'CredProfileUnloaded' CredProfileUnloaded advapi32 1170 +imp 'CredProtectA' CredProtectA advapi32 1171 +imp 'CredProtect' CredProtectW advapi32 1172 +imp 'CredReadA' CredReadA advapi32 1173 +imp 'CredReadByTokenHandle' CredReadByTokenHandle advapi32 1174 +imp 'CredReadDomainCredentialsA' CredReadDomainCredentialsA advapi32 1175 +imp 'CredReadDomainCredentials' CredReadDomainCredentialsW advapi32 1176 +imp 'CredRead' CredReadW advapi32 1177 +imp 'CredRenameA' CredRenameA advapi32 1178 +imp 'CredRename' CredRenameW advapi32 1179 +imp 'CredRestoreCredentials' CredRestoreCredentials advapi32 1180 +imp 'CredUnmarshalCredentialA' CredUnmarshalCredentialA advapi32 1181 +imp 'CredUnmarshalCredential' CredUnmarshalCredentialW advapi32 1182 +imp 'CredUnprotectA' CredUnprotectA advapi32 1183 +imp 'CredUnprotect' CredUnprotectW advapi32 1184 +imp 'CredWriteA' CredWriteA advapi32 1185 +imp 'CredWriteDomainCredentialsA' CredWriteDomainCredentialsA advapi32 1186 +imp 'CredWriteDomainCredentials' CredWriteDomainCredentialsW advapi32 1187 +imp 'CredWrite' CredWriteW advapi32 1188 +imp 'CredpConvertCredential' CredpConvertCredential advapi32 1189 +imp 'CredpConvertOneCredentialSize' CredpConvertOneCredentialSize advapi32 1190 +imp 'CredpConvertTargetInfo' CredpConvertTargetInfo advapi32 1191 +imp 'CredpDecodeCredential' CredpDecodeCredential advapi32 1192 +imp 'CredpEncodeCredential' CredpEncodeCredential advapi32 1193 +imp 'CredpEncodeSecret' CredpEncodeSecret advapi32 1194 +imp 'CryptAcquireContextA' CryptAcquireContextA advapi32 1195 +imp 'CryptAcquireContext' CryptAcquireContextW advapi32 1196 +imp 'CryptContextAddRef' CryptContextAddRef advapi32 1197 +imp 'CryptCreateHash' CryptCreateHash advapi32 1198 +imp 'CryptDecrypt' CryptDecrypt advapi32 1199 +imp 'CryptDeriveKey' CryptDeriveKey advapi32 1200 +imp 'CryptDestroyHash' CryptDestroyHash advapi32 1201 +imp 'CryptDestroyKey' CryptDestroyKey advapi32 1202 +imp 'CryptDuplicateHash' CryptDuplicateHash advapi32 1203 +imp 'CryptDuplicateKey' CryptDuplicateKey advapi32 1204 +imp 'CryptEncrypt' CryptEncrypt advapi32 1205 +imp 'CryptEnumProviderTypesA' CryptEnumProviderTypesA advapi32 1206 +imp 'CryptEnumProviderTypes' CryptEnumProviderTypesW advapi32 1207 +imp 'CryptEnumProvidersA' CryptEnumProvidersA advapi32 1208 +imp 'CryptEnumProviders' CryptEnumProvidersW advapi32 1209 +imp 'CryptExportKey' CryptExportKey advapi32 1210 +imp 'CryptGenKey' CryptGenKey advapi32 1211 +imp 'CryptGenRandom' CryptGenRandom advapi32 1212 +imp 'CryptGetDefaultProviderA' CryptGetDefaultProviderA advapi32 1213 +imp 'CryptGetDefaultProvider' CryptGetDefaultProviderW advapi32 1214 +imp 'CryptGetHashParam' CryptGetHashParam advapi32 1215 +imp 'CryptGetKeyParam' CryptGetKeyParam advapi32 1216 +imp 'CryptGetProvParam' CryptGetProvParam advapi32 1217 +imp 'CryptGetUserKey' CryptGetUserKey advapi32 1218 +imp 'CryptHashData' CryptHashData advapi32 1219 +imp 'CryptHashSessionKey' CryptHashSessionKey advapi32 1220 +imp 'CryptImportKey' CryptImportKey advapi32 1221 +imp 'CryptReleaseContext' CryptReleaseContext advapi32 1222 +imp 'CryptSetHashParam' CryptSetHashParam advapi32 1223 +imp 'CryptSetKeyParam' CryptSetKeyParam advapi32 1224 +imp 'CryptSetProvParam' CryptSetProvParam advapi32 1225 +imp 'CryptSetProviderA' CryptSetProviderA advapi32 1226 +imp 'CryptSetProviderExA' CryptSetProviderExA advapi32 1227 +imp 'CryptSetProviderEx' CryptSetProviderExW advapi32 1228 +imp 'CryptSetProvider' CryptSetProviderW advapi32 1229 +imp 'CryptSignHashA' CryptSignHashA advapi32 1230 +imp 'CryptSignHash' CryptSignHashW advapi32 1231 +imp 'CryptVerifySignatureA' CryptVerifySignatureA advapi32 1232 +imp 'CryptVerifySignature' CryptVerifySignatureW advapi32 1233 +imp 'CsrAllocateCaptureBuffer' CsrAllocateCaptureBuffer ntdll 28 +imp 'CsrAllocateMessagePointer' CsrAllocateMessagePointer ntdll 29 +imp 'CsrBroadcastSystemMessageEx' CsrBroadcastSystemMessageExW user32 1631 +imp 'CsrCaptureMessageBuffer' CsrCaptureMessageBuffer ntdll 30 +imp 'CsrCaptureMessageMultiUnicodeStringsInPlace' CsrCaptureMessageMultiUnicodeStringsInPlace ntdll 31 +imp 'CsrCaptureMessageString' CsrCaptureMessageString ntdll 32 +imp 'CsrCaptureTimeout' CsrCaptureTimeout ntdll 33 +imp 'CsrClientCallServer' CsrClientCallServer ntdll 34 4 +imp 'CsrClientConnectToServer' CsrClientConnectToServer ntdll 35 +imp 'CsrFreeCaptureBuffer' CsrFreeCaptureBuffer ntdll 36 +imp 'CsrGetProcessId' CsrGetProcessId ntdll 37 +imp 'CsrIdentifyAlertableThread' CsrIdentifyAlertableThread ntdll 38 +imp 'CsrSetPriorityClass' CsrSetPriorityClass ntdll 39 +imp 'CsrVerifyRegion' CsrVerifyRegion ntdll 40 +imp 'CtrlRoutine' CtrlRoutine KernelBase 236 +imp 'CtxInitUser32' CtxInitUser32 user32 1632 +imp 'CveEventWrite' CveEventWrite KernelBase 237 +imp 'D3DKMTAbandonSwapChain' D3DKMTAbandonSwapChain gdi32 1104 +imp 'D3DKMTAcquireKeyedMutex' D3DKMTAcquireKeyedMutex gdi32 1105 +imp 'D3DKMTAcquireKeyedMutex2' D3DKMTAcquireKeyedMutex2 gdi32 1106 +imp 'D3DKMTAcquireSwapChain' D3DKMTAcquireSwapChain gdi32 1107 +imp 'D3DKMTAddSurfaceToSwapChain' D3DKMTAddSurfaceToSwapChain gdi32 1108 +imp 'D3DKMTAdjustFullscreenGamma' D3DKMTAdjustFullscreenGamma gdi32 1109 +imp 'D3DKMTCacheHybridQueryValue' D3DKMTCacheHybridQueryValue gdi32 1110 +imp 'D3DKMTChangeVideoMemoryReservation' D3DKMTChangeVideoMemoryReservation gdi32 1111 +imp 'D3DKMTCheckExclusiveOwnership' D3DKMTCheckExclusiveOwnership gdi32 1112 +imp 'D3DKMTCheckMonitorPowerState' D3DKMTCheckMonitorPowerState gdi32 1113 +imp 'D3DKMTCheckMultiPlaneOverlaySupport' D3DKMTCheckMultiPlaneOverlaySupport gdi32 1114 +imp 'D3DKMTCheckMultiPlaneOverlaySupport2' D3DKMTCheckMultiPlaneOverlaySupport2 gdi32 1115 +imp 'D3DKMTCheckMultiPlaneOverlaySupport3' D3DKMTCheckMultiPlaneOverlaySupport3 gdi32 1116 +imp 'D3DKMTCheckOcclusion' D3DKMTCheckOcclusion gdi32 1117 +imp 'D3DKMTCheckSharedResourceAccess' D3DKMTCheckSharedResourceAccess gdi32 1118 +imp 'D3DKMTCheckVidPnExclusiveOwnership' D3DKMTCheckVidPnExclusiveOwnership gdi32 1119 +imp 'D3DKMTCloseAdapter' D3DKMTCloseAdapter gdi32 1120 +imp 'D3DKMTConfigureSharedResource' D3DKMTConfigureSharedResource gdi32 1121 +imp 'D3DKMTCreateAllocation' D3DKMTCreateAllocation gdi32 1122 +imp 'D3DKMTCreateAllocation2' D3DKMTCreateAllocation2 gdi32 1123 +imp 'D3DKMTCreateBundleObject' D3DKMTCreateBundleObject gdi32 1124 +imp 'D3DKMTCreateContext' D3DKMTCreateContext gdi32 1125 +imp 'D3DKMTCreateContextVirtual' D3DKMTCreateContextVirtual gdi32 1126 +imp 'D3DKMTCreateDCFromMemory' D3DKMTCreateDCFromMemory gdi32 1127 +imp 'D3DKMTCreateDevice' D3DKMTCreateDevice gdi32 1128 +imp 'D3DKMTCreateHwContext' D3DKMTCreateHwContext gdi32 1129 +imp 'D3DKMTCreateHwQueue' D3DKMTCreateHwQueue gdi32 1130 +imp 'D3DKMTCreateKeyedMutex' D3DKMTCreateKeyedMutex gdi32 1131 +imp 'D3DKMTCreateKeyedMutex2' D3DKMTCreateKeyedMutex2 gdi32 1132 +imp 'D3DKMTCreateOutputDupl' D3DKMTCreateOutputDupl gdi32 1133 +imp 'D3DKMTCreateOverlay' D3DKMTCreateOverlay gdi32 1134 +imp 'D3DKMTCreatePagingQueue' D3DKMTCreatePagingQueue gdi32 1135 +imp 'D3DKMTCreateProtectedSession' D3DKMTCreateProtectedSession gdi32 1136 +imp 'D3DKMTCreateSwapChain' D3DKMTCreateSwapChain gdi32 1137 +imp 'D3DKMTCreateSynchronizationObject' D3DKMTCreateSynchronizationObject gdi32 1138 +imp 'D3DKMTCreateSynchronizationObject2' D3DKMTCreateSynchronizationObject2 gdi32 1139 +imp 'D3DKMTDDisplayEnum' D3DKMTDDisplayEnum gdi32 1140 +imp 'D3DKMTDestroyAllocation' D3DKMTDestroyAllocation gdi32 1141 +imp 'D3DKMTDestroyAllocation2' D3DKMTDestroyAllocation2 gdi32 1142 +imp 'D3DKMTDestroyContext' D3DKMTDestroyContext gdi32 1143 +imp 'D3DKMTDestroyDCFromMemory' D3DKMTDestroyDCFromMemory gdi32 1144 +imp 'D3DKMTDestroyDevice' D3DKMTDestroyDevice gdi32 1145 +imp 'D3DKMTDestroyHwContext' D3DKMTDestroyHwContext gdi32 1146 +imp 'D3DKMTDestroyHwQueue' D3DKMTDestroyHwQueue gdi32 1147 +imp 'D3DKMTDestroyKeyedMutex' D3DKMTDestroyKeyedMutex gdi32 1148 +imp 'D3DKMTDestroyOutputDupl' D3DKMTDestroyOutputDupl gdi32 1149 +imp 'D3DKMTDestroyOverlay' D3DKMTDestroyOverlay gdi32 1150 +imp 'D3DKMTDestroyPagingQueue' D3DKMTDestroyPagingQueue gdi32 1151 +imp 'D3DKMTDestroyProtectedSession' D3DKMTDestroyProtectedSession gdi32 1152 +imp 'D3DKMTDestroySynchronizationObject' D3DKMTDestroySynchronizationObject gdi32 1153 +imp 'D3DKMTDispMgrCreate' D3DKMTDispMgrCreate gdi32 1154 +imp 'D3DKMTDispMgrSourceOperation' D3DKMTDispMgrSourceOperation gdi32 1155 +imp 'D3DKMTDispMgrTargetOperation' D3DKMTDispMgrTargetOperation gdi32 1156 +imp 'D3DKMTEnumAdapters' D3DKMTEnumAdapters gdi32 1157 +imp 'D3DKMTEnumAdapters2' D3DKMTEnumAdapters2 gdi32 1158 +imp 'D3DKMTEscape' D3DKMTEscape gdi32 1159 +imp 'D3DKMTEvict' D3DKMTEvict gdi32 1160 +imp 'D3DKMTExtractBundleObject' D3DKMTExtractBundleObject gdi32 1161 +imp 'D3DKMTFlipOverlay' D3DKMTFlipOverlay gdi32 1162 +imp 'D3DKMTFlushHeapTransitions' D3DKMTFlushHeapTransitions gdi32 1163 +imp 'D3DKMTFreeGpuVirtualAddress' D3DKMTFreeGpuVirtualAddress gdi32 1164 +imp 'D3DKMTGetAllocationPriority' D3DKMTGetAllocationPriority gdi32 1165 +imp 'D3DKMTGetCachedHybridQueryValue' D3DKMTGetCachedHybridQueryValue gdi32 1166 +imp 'D3DKMTGetContextInProcessSchedulingPriority' D3DKMTGetContextInProcessSchedulingPriority gdi32 1167 +imp 'D3DKMTGetContextSchedulingPriority' D3DKMTGetContextSchedulingPriority gdi32 1168 +imp 'D3DKMTGetDWMVerticalBlankEvent' D3DKMTGetDWMVerticalBlankEvent gdi32 1169 +imp 'D3DKMTGetDeviceState' D3DKMTGetDeviceState gdi32 1170 +imp 'D3DKMTGetDisplayModeList' D3DKMTGetDisplayModeList gdi32 1171 +imp 'D3DKMTGetMemoryBudgetTarget' D3DKMTGetMemoryBudgetTarget gdi32 1172 +imp 'D3DKMTGetMultiPlaneOverlayCaps' D3DKMTGetMultiPlaneOverlayCaps gdi32 1173 +imp 'D3DKMTGetMultisampleMethodList' D3DKMTGetMultisampleMethodList gdi32 1174 +imp 'D3DKMTGetOverlayState' D3DKMTGetOverlayState gdi32 1175 +imp 'D3DKMTGetPostCompositionCaps' D3DKMTGetPostCompositionCaps gdi32 1176 +imp 'D3DKMTGetPresentHistory' D3DKMTGetPresentHistory gdi32 1177 +imp 'D3DKMTGetPresentQueueEvent' D3DKMTGetPresentQueueEvent gdi32 1178 +imp 'D3DKMTGetProcessDeviceRemovalSupport' D3DKMTGetProcessDeviceRemovalSupport gdi32 1179 +imp 'D3DKMTGetProcessList' D3DKMTGetProcessList gdi32 1180 +imp 'D3DKMTGetProcessSchedulingPriorityBand' D3DKMTGetProcessSchedulingPriorityBand gdi32 1181 +imp 'D3DKMTGetProcessSchedulingPriorityClass' D3DKMTGetProcessSchedulingPriorityClass gdi32 1182 +imp 'D3DKMTGetResourcePresentPrivateDriverData' D3DKMTGetResourcePresentPrivateDriverData gdi32 1183 +imp 'D3DKMTGetRuntimeData' D3DKMTGetRuntimeData gdi32 1184 +imp 'D3DKMTGetScanLine' D3DKMTGetScanLine gdi32 1185 +imp 'D3DKMTGetSetSwapChainMetadata' D3DKMTGetSetSwapChainMetadata gdi32 1186 +imp 'D3DKMTGetSharedPrimaryHandle' D3DKMTGetSharedPrimaryHandle gdi32 1187 +imp 'D3DKMTGetSharedResourceAdapterLuid' D3DKMTGetSharedResourceAdapterLuid gdi32 1188 +imp 'D3DKMTGetYieldPercentage' D3DKMTGetYieldPercentage gdi32 1189 +imp 'D3DKMTInvalidateActiveVidPn' D3DKMTInvalidateActiveVidPn gdi32 1190 +imp 'D3DKMTInvalidateCache' D3DKMTInvalidateCache gdi32 1191 +imp 'D3DKMTLock' D3DKMTLock gdi32 1192 +imp 'D3DKMTLock2' D3DKMTLock2 gdi32 1193 +imp 'D3DKMTMakeResident' D3DKMTMakeResident gdi32 1194 +imp 'D3DKMTMapGpuVirtualAddress' D3DKMTMapGpuVirtualAddress gdi32 1195 +imp 'D3DKMTMarkDeviceAsError' D3DKMTMarkDeviceAsError gdi32 1196 +imp 'D3DKMTNetDispGetNextChunkInfo' D3DKMTNetDispGetNextChunkInfo gdi32 1197 +imp 'D3DKMTNetDispQueryMiracastDisplayDeviceStatus' D3DKMTNetDispQueryMiracastDisplayDeviceStatus gdi32 1198 +imp 'D3DKMTNetDispQueryMiracastDisplayDeviceSupport' D3DKMTNetDispQueryMiracastDisplayDeviceSupport gdi32 1199 +imp 'D3DKMTNetDispStartMiracastDisplayDevice' D3DKMTNetDispStartMiracastDisplayDevice gdi32 1200 +imp 'D3DKMTNetDispStartMiracastDisplayDevice2' D3DKMTNetDispStartMiracastDisplayDevice2 gdi32 1201 +imp 'D3DKMTNetDispStartMiracastDisplayDeviceEx' D3DKMTNetDispStartMiracastDisplayDeviceEx gdi32 1202 +imp 'D3DKMTNetDispStopMiracastDisplayDevice' D3DKMTNetDispStopMiracastDisplayDevice gdi32 1203 +imp 'D3DKMTNetDispStopSessions' D3DKMTNetDispStopSessions gdi32 1204 +imp 'D3DKMTOfferAllocations' D3DKMTOfferAllocations gdi32 1205 +imp 'D3DKMTOpenAdapterFromDeviceName' D3DKMTOpenAdapterFromDeviceName gdi32 1206 +imp 'D3DKMTOpenAdapterFromGdiDisplayName' D3DKMTOpenAdapterFromGdiDisplayName gdi32 1207 +imp 'D3DKMTOpenAdapterFromHdc' D3DKMTOpenAdapterFromHdc gdi32 1208 +imp 'D3DKMTOpenAdapterFromLuid' D3DKMTOpenAdapterFromLuid gdi32 1209 +imp 'D3DKMTOpenBundleObjectNtHandleFromName' D3DKMTOpenBundleObjectNtHandleFromName gdi32 1210 +imp 'D3DKMTOpenKeyedMutex' D3DKMTOpenKeyedMutex gdi32 1211 +imp 'D3DKMTOpenKeyedMutex2' D3DKMTOpenKeyedMutex2 gdi32 1212 +imp 'D3DKMTOpenKeyedMutexFromNtHandle' D3DKMTOpenKeyedMutexFromNtHandle gdi32 1213 +imp 'D3DKMTOpenNtHandleFromName' D3DKMTOpenNtHandleFromName gdi32 1214 +imp 'D3DKMTOpenProtectedSessionFromNtHandle' D3DKMTOpenProtectedSessionFromNtHandle gdi32 1215 +imp 'D3DKMTOpenResource' D3DKMTOpenResource gdi32 1216 +imp 'D3DKMTOpenResource2' D3DKMTOpenResource2 gdi32 1217 +imp 'D3DKMTOpenResourceFromNtHandle' D3DKMTOpenResourceFromNtHandle gdi32 1218 +imp 'D3DKMTOpenSwapChain' D3DKMTOpenSwapChain gdi32 1219 +imp 'D3DKMTOpenSyncObjectFromNtHandle' D3DKMTOpenSyncObjectFromNtHandle gdi32 1220 +imp 'D3DKMTOpenSyncObjectFromNtHandle2' D3DKMTOpenSyncObjectFromNtHandle2 gdi32 1221 +imp 'D3DKMTOpenSyncObjectNtHandleFromName' D3DKMTOpenSyncObjectNtHandleFromName gdi32 1222 +imp 'D3DKMTOpenSynchronizationObject' D3DKMTOpenSynchronizationObject gdi32 1223 +imp 'D3DKMTOutputDuplGetFrameInfo' D3DKMTOutputDuplGetFrameInfo gdi32 1224 +imp 'D3DKMTOutputDuplGetMetaData' D3DKMTOutputDuplGetMetaData gdi32 1225 +imp 'D3DKMTOutputDuplGetPointerShapeData' D3DKMTOutputDuplGetPointerShapeData gdi32 1226 +imp 'D3DKMTOutputDuplPresent' D3DKMTOutputDuplPresent gdi32 1227 +imp 'D3DKMTOutputDuplReleaseFrame' D3DKMTOutputDuplReleaseFrame gdi32 1228 +imp 'D3DKMTPinDirectFlipResources' D3DKMTPinDirectFlipResources gdi32 1229 +imp 'D3DKMTPollDisplayChildren' D3DKMTPollDisplayChildren gdi32 1230 +imp 'D3DKMTPresent' D3DKMTPresent gdi32 1231 +imp 'D3DKMTPresentMultiPlaneOverlay' D3DKMTPresentMultiPlaneOverlay gdi32 1232 +imp 'D3DKMTPresentMultiPlaneOverlay2' D3DKMTPresentMultiPlaneOverlay2 gdi32 1233 +imp 'D3DKMTPresentMultiPlaneOverlay3' D3DKMTPresentMultiPlaneOverlay3 gdi32 1234 +imp 'D3DKMTPresentRedirected' D3DKMTPresentRedirected gdi32 1235 +imp 'D3DKMTQueryAdapterInfo' D3DKMTQueryAdapterInfo gdi32 1236 +imp 'D3DKMTQueryAllocationResidency' D3DKMTQueryAllocationResidency gdi32 1237 +imp 'D3DKMTQueryClockCalibration' D3DKMTQueryClockCalibration gdi32 1238 +imp 'D3DKMTQueryFSEBlock' D3DKMTQueryFSEBlock gdi32 1239 +imp 'D3DKMTQueryProcessOfferInfo' D3DKMTQueryProcessOfferInfo gdi32 1240 +imp 'D3DKMTQueryProtectedSessionInfoFromNtHandle' D3DKMTQueryProtectedSessionInfoFromNtHandle gdi32 1241 +imp 'D3DKMTQueryProtectedSessionStatus' D3DKMTQueryProtectedSessionStatus gdi32 1242 +imp 'D3DKMTQueryRemoteVidPnSourceFromGdiDisplayName' D3DKMTQueryRemoteVidPnSourceFromGdiDisplayName gdi32 1243 +imp 'D3DKMTQueryResourceInfo' D3DKMTQueryResourceInfo gdi32 1244 +imp 'D3DKMTQueryResourceInfoFromNtHandle' D3DKMTQueryResourceInfoFromNtHandle gdi32 1245 +imp 'D3DKMTQueryStatistics' D3DKMTQueryStatistics gdi32 1246 +imp 'D3DKMTQueryVidPnExclusiveOwnership' D3DKMTQueryVidPnExclusiveOwnership gdi32 1247 +imp 'D3DKMTQueryVideoMemoryInfo' D3DKMTQueryVideoMemoryInfo gdi32 1248 +imp 'D3DKMTReclaimAllocations' D3DKMTReclaimAllocations gdi32 1249 +imp 'D3DKMTReclaimAllocations2' D3DKMTReclaimAllocations2 gdi32 1250 +imp 'D3DKMTRegisterTrimNotification' D3DKMTRegisterTrimNotification gdi32 1251 +imp 'D3DKMTRegisterVailProcess' D3DKMTRegisterVailProcess gdi32 1252 +imp 'D3DKMTReleaseKeyedMutex' D3DKMTReleaseKeyedMutex gdi32 1253 +imp 'D3DKMTReleaseKeyedMutex2' D3DKMTReleaseKeyedMutex2 gdi32 1254 +imp 'D3DKMTReleaseProcessVidPnSourceOwners' D3DKMTReleaseProcessVidPnSourceOwners gdi32 1255 +imp 'D3DKMTReleaseSwapChain' D3DKMTReleaseSwapChain gdi32 1256 +imp 'D3DKMTRemoveSurfaceFromSwapChain' D3DKMTRemoveSurfaceFromSwapChain gdi32 1257 +imp 'D3DKMTRender' D3DKMTRender gdi32 1258 +imp 'D3DKMTReserveGpuVirtualAddress' D3DKMTReserveGpuVirtualAddress gdi32 1259 +imp 'D3DKMTSetAllocationPriority' D3DKMTSetAllocationPriority gdi32 1260 +imp 'D3DKMTSetContextInProcessSchedulingPriority' D3DKMTSetContextInProcessSchedulingPriority gdi32 1261 +imp 'D3DKMTSetContextSchedulingPriority' D3DKMTSetContextSchedulingPriority gdi32 1262 +imp 'D3DKMTSetDisplayMode' D3DKMTSetDisplayMode gdi32 1263 +imp 'D3DKMTSetDisplayPrivateDriverFormat' D3DKMTSetDisplayPrivateDriverFormat gdi32 1264 +imp 'D3DKMTSetDodIndirectSwapchain' D3DKMTSetDodIndirectSwapchain gdi32 1265 +imp 'D3DKMTSetFSEBlock' D3DKMTSetFSEBlock gdi32 1266 +imp 'D3DKMTSetGammaRamp' D3DKMTSetGammaRamp gdi32 1267 +imp 'D3DKMTSetHwProtectionTeardownRecovery' D3DKMTSetHwProtectionTeardownRecovery gdi32 1268 +imp 'D3DKMTSetMemoryBudgetTarget' D3DKMTSetMemoryBudgetTarget gdi32 1269 +imp 'D3DKMTSetMonitorColorSpaceTransform' D3DKMTSetMonitorColorSpaceTransform gdi32 1270 +imp 'D3DKMTSetProcessDeviceRemovalSupport' D3DKMTSetProcessDeviceRemovalSupport gdi32 1271 +imp 'D3DKMTSetProcessSchedulingPriorityBand' D3DKMTSetProcessSchedulingPriorityBand gdi32 1272 +imp 'D3DKMTSetProcessSchedulingPriorityClass' D3DKMTSetProcessSchedulingPriorityClass gdi32 1273 +imp 'D3DKMTSetQueuedLimit' D3DKMTSetQueuedLimit gdi32 1274 +imp 'D3DKMTSetStablePowerState' D3DKMTSetStablePowerState gdi32 1275 +imp 'D3DKMTSetStereoEnabled' D3DKMTSetStereoEnabled gdi32 1276 +imp 'D3DKMTSetSyncRefreshCountWaitTarget' D3DKMTSetSyncRefreshCountWaitTarget gdi32 1277 +imp 'D3DKMTSetVidPnSourceHwProtection' D3DKMTSetVidPnSourceHwProtection gdi32 1278 +imp 'D3DKMTSetVidPnSourceOwner' D3DKMTSetVidPnSourceOwner gdi32 1279 +imp 'D3DKMTSetVidPnSourceOwner1' D3DKMTSetVidPnSourceOwner1 gdi32 1280 +imp 'D3DKMTSetVidPnSourceOwner2' D3DKMTSetVidPnSourceOwner2 gdi32 1281 +imp 'D3DKMTSetYieldPercentage' D3DKMTSetYieldPercentage gdi32 1282 +imp 'D3DKMTShareObjects' D3DKMTShareObjects gdi32 1283 +imp 'D3DKMTSharedPrimaryLockNotification' D3DKMTSharedPrimaryLockNotification gdi32 1284 +imp 'D3DKMTSharedPrimaryUnLockNotification' D3DKMTSharedPrimaryUnLockNotification gdi32 1285 +imp 'D3DKMTSignalSynchronizationObject' D3DKMTSignalSynchronizationObject gdi32 1286 +imp 'D3DKMTSignalSynchronizationObject2' D3DKMTSignalSynchronizationObject2 gdi32 1287 +imp 'D3DKMTSignalSynchronizationObjectFromCpu' D3DKMTSignalSynchronizationObjectFromCpu gdi32 1288 +imp 'D3DKMTSignalSynchronizationObjectFromGpu' D3DKMTSignalSynchronizationObjectFromGpu gdi32 1289 +imp 'D3DKMTSignalSynchronizationObjectFromGpu2' D3DKMTSignalSynchronizationObjectFromGpu2 gdi32 1290 +imp 'D3DKMTSubmitCommand' D3DKMTSubmitCommand gdi32 1291 +imp 'D3DKMTSubmitCommandToHwQueue' D3DKMTSubmitCommandToHwQueue gdi32 1292 +imp 'D3DKMTSubmitPresentBltToHwQueue' D3DKMTSubmitPresentBltToHwQueue gdi32 1293 +imp 'D3DKMTSubmitSignalSyncObjectsToHwQueue' D3DKMTSubmitSignalSyncObjectsToHwQueue gdi32 1294 +imp 'D3DKMTSubmitWaitForSyncObjectsToHwQueue' D3DKMTSubmitWaitForSyncObjectsToHwQueue gdi32 1295 +imp 'D3DKMTTrimProcessCommitment' D3DKMTTrimProcessCommitment gdi32 1296 +imp 'D3DKMTUnOrderedPresentSwapChain' D3DKMTUnOrderedPresentSwapChain gdi32 1297 +imp 'D3DKMTUnlock' D3DKMTUnlock gdi32 1298 +imp 'D3DKMTUnlock2' D3DKMTUnlock2 gdi32 1299 +imp 'D3DKMTUnpinDirectFlipResources' D3DKMTUnpinDirectFlipResources gdi32 1300 +imp 'D3DKMTUnregisterTrimNotification' D3DKMTUnregisterTrimNotification gdi32 1301 +imp 'D3DKMTUpdateAllocationProperty' D3DKMTUpdateAllocationProperty gdi32 1302 +imp 'D3DKMTUpdateGpuVirtualAddress' D3DKMTUpdateGpuVirtualAddress gdi32 1303 +imp 'D3DKMTUpdateOverlay' D3DKMTUpdateOverlay gdi32 1304 +imp 'D3DKMTVailConnect' D3DKMTVailConnect gdi32 1305 +imp 'D3DKMTVailDisconnect' D3DKMTVailDisconnect gdi32 1306 +imp 'D3DKMTVailPromoteCompositionSurface' D3DKMTVailPromoteCompositionSurface gdi32 1307 +imp 'D3DKMTWaitForIdle' D3DKMTWaitForIdle gdi32 1308 +imp 'D3DKMTWaitForSynchronizationObject' D3DKMTWaitForSynchronizationObject gdi32 1309 +imp 'D3DKMTWaitForSynchronizationObject2' D3DKMTWaitForSynchronizationObject2 gdi32 1310 +imp 'D3DKMTWaitForSynchronizationObjectFromCpu' D3DKMTWaitForSynchronizationObjectFromCpu gdi32 1311 +imp 'D3DKMTWaitForSynchronizationObjectFromGpu' D3DKMTWaitForSynchronizationObjectFromGpu gdi32 1312 +imp 'D3DKMTWaitForVerticalBlankEvent' D3DKMTWaitForVerticalBlankEvent gdi32 1313 +imp 'D3DKMTWaitForVerticalBlankEvent2' D3DKMTWaitForVerticalBlankEvent2 gdi32 1314 +imp 'DAD_AutoScroll' DAD_AutoScroll shell32 129 +imp 'DAD_DragEnterEx' DAD_DragEnterEx shell32 131 +imp 'DAD_DragEnterEx2' DAD_DragEnterEx2 shell32 22 +imp 'DAD_DragLeave' DAD_DragLeave shell32 132 +imp 'DAD_DragMove' DAD_DragMove shell32 134 +imp 'DAD_SetDragImage' DAD_SetDragImage shell32 136 +imp 'DAD_ShowDragImage' DAD_ShowDragImage shell32 137 +imp 'DDCCIGetCapabilitiesString' DDCCIGetCapabilitiesString gdi32 1315 +imp 'DDCCIGetCapabilitiesStringLength' DDCCIGetCapabilitiesStringLength gdi32 1316 +imp 'DDCCIGetTimingReport' DDCCIGetTimingReport gdi32 1317 +imp 'DDCCIGetVCPFeature' DDCCIGetVCPFeature gdi32 1318 +imp 'DDCCISaveCurrentSettings' DDCCISaveCurrentSettings gdi32 1319 +imp 'DDCCISetVCPFeature' DDCCISetVCPFeature gdi32 1320 +imp 'DPtoLP' DPtoLP gdi32 1321 +imp 'DWMBindCursorToOutputConfig' DWMBindCursorToOutputConfig user32 1633 +imp 'DWMCommitInputSystemOutputConfig' DWMCommitInputSystemOutputConfig user32 1634 +imp 'DWMSetCursorOrientation' DWMSetCursorOrientation user32 1635 +imp 'DWMSetInputSystemOutputConfig' DWMSetInputSystemOutputConfig user32 1636 +imp 'DbgBreakPoint' DbgBreakPoint ntdll 41 +imp 'DbgPrint' DbgPrint ntdll 42 +imp 'DbgPrintEx' DbgPrintEx ntdll 43 +imp 'DbgPrintReturnControlC' DbgPrintReturnControlC ntdll 44 +imp 'DbgPrompt' DbgPrompt ntdll 45 +imp 'DbgQueryDebugFilterState' DbgQueryDebugFilterState ntdll 46 +imp 'DbgSetDebugFilterState' DbgSetDebugFilterState ntdll 47 +imp 'DbgUiConnectToDbg' DbgUiConnectToDbg ntdll 48 +imp 'DbgUiContinue' DbgUiContinue ntdll 49 +imp 'DbgUiConvertStateChangeStructure' DbgUiConvertStateChangeStructure ntdll 50 +imp 'DbgUiConvertStateChangeStructureEx' DbgUiConvertStateChangeStructureEx ntdll 51 +imp 'DbgUiDebugActiveProcess' DbgUiDebugActiveProcess ntdll 52 +imp 'DbgUiGetThreadDebugObject' DbgUiGetThreadDebugObject ntdll 53 +imp 'DbgUiIssueRemoteBreakin' DbgUiIssueRemoteBreakin ntdll 54 +imp 'DbgUiRemoteBreakin' DbgUiRemoteBreakin ntdll 55 +imp 'DbgUiSetThreadDebugObject' DbgUiSetThreadDebugObject ntdll 56 +imp 'DbgUiStopDebugging' DbgUiStopDebugging ntdll 57 +imp 'DbgUiWaitStateChange' DbgUiWaitStateChange ntdll 58 +imp 'DbgUserBreakPoint' DbgUserBreakPoint ntdll 59 +imp 'DdCreateFullscreenSprite' DdCreateFullscreenSprite gdi32 1322 +imp 'DdDestroyFullscreenSprite' DdDestroyFullscreenSprite gdi32 1323 +imp 'DdEntry0' DdEntry0 gdi32 1324 +imp 'DdEntry1' DdEntry1 gdi32 1325 +imp 'DdEntry10' DdEntry10 gdi32 1326 +imp 'DdEntry11' DdEntry11 gdi32 1327 +imp 'DdEntry12' DdEntry12 gdi32 1328 +imp 'DdEntry13' DdEntry13 gdi32 1329 +imp 'DdEntry14' DdEntry14 gdi32 1330 +imp 'DdEntry15' DdEntry15 gdi32 1331 +imp 'DdEntry16' DdEntry16 gdi32 1332 +imp 'DdEntry17' DdEntry17 gdi32 1333 +imp 'DdEntry18' DdEntry18 gdi32 1334 +imp 'DdEntry19' DdEntry19 gdi32 1335 +imp 'DdEntry2' DdEntry2 gdi32 1336 +imp 'DdEntry20' DdEntry20 gdi32 1337 +imp 'DdEntry21' DdEntry21 gdi32 1338 +imp 'DdEntry22' DdEntry22 gdi32 1339 +imp 'DdEntry23' DdEntry23 gdi32 1340 +imp 'DdEntry24' DdEntry24 gdi32 1341 +imp 'DdEntry25' DdEntry25 gdi32 1342 +imp 'DdEntry26' DdEntry26 gdi32 1343 +imp 'DdEntry27' DdEntry27 gdi32 1344 +imp 'DdEntry28' DdEntry28 gdi32 1345 +imp 'DdEntry29' DdEntry29 gdi32 1346 +imp 'DdEntry3' DdEntry3 gdi32 1347 +imp 'DdEntry30' DdEntry30 gdi32 1348 +imp 'DdEntry31' DdEntry31 gdi32 1349 +imp 'DdEntry32' DdEntry32 gdi32 1350 +imp 'DdEntry33' DdEntry33 gdi32 1351 +imp 'DdEntry34' DdEntry34 gdi32 1352 +imp 'DdEntry35' DdEntry35 gdi32 1353 +imp 'DdEntry36' DdEntry36 gdi32 1354 +imp 'DdEntry37' DdEntry37 gdi32 1355 +imp 'DdEntry38' DdEntry38 gdi32 1356 +imp 'DdEntry39' DdEntry39 gdi32 1357 +imp 'DdEntry4' DdEntry4 gdi32 1358 +imp 'DdEntry40' DdEntry40 gdi32 1359 +imp 'DdEntry41' DdEntry41 gdi32 1360 +imp 'DdEntry42' DdEntry42 gdi32 1361 +imp 'DdEntry43' DdEntry43 gdi32 1362 +imp 'DdEntry44' DdEntry44 gdi32 1363 +imp 'DdEntry45' DdEntry45 gdi32 1364 +imp 'DdEntry46' DdEntry46 gdi32 1365 +imp 'DdEntry47' DdEntry47 gdi32 1366 +imp 'DdEntry48' DdEntry48 gdi32 1367 +imp 'DdEntry49' DdEntry49 gdi32 1368 +imp 'DdEntry5' DdEntry5 gdi32 1369 +imp 'DdEntry50' DdEntry50 gdi32 1370 +imp 'DdEntry51' DdEntry51 gdi32 1371 +imp 'DdEntry52' DdEntry52 gdi32 1372 +imp 'DdEntry53' DdEntry53 gdi32 1373 +imp 'DdEntry54' DdEntry54 gdi32 1374 +imp 'DdEntry55' DdEntry55 gdi32 1375 +imp 'DdEntry56' DdEntry56 gdi32 1376 +imp 'DdEntry6' DdEntry6 gdi32 1377 +imp 'DdEntry7' DdEntry7 gdi32 1378 +imp 'DdEntry8' DdEntry8 gdi32 1379 +imp 'DdEntry9' DdEntry9 gdi32 1380 +imp 'DdNotifyFullscreenSpriteUpdate' DdNotifyFullscreenSpriteUpdate gdi32 1381 +imp 'DdQueryVisRgnUniqueness' DdQueryVisRgnUniqueness gdi32 1382 +imp 'DdeAbandonTransaction' DdeAbandonTransaction user32 1637 +imp 'DdeAccessData' DdeAccessData user32 1638 +imp 'DdeAddData' DdeAddData user32 1639 +imp 'DdeClientTransaction' DdeClientTransaction user32 1640 +imp 'DdeCmpStringHandles' DdeCmpStringHandles user32 1641 +imp 'DdeConnect' DdeConnect user32 1642 +imp 'DdeConnectList' DdeConnectList user32 1643 +imp 'DdeCreateDataHandle' DdeCreateDataHandle user32 1644 +imp 'DdeCreateStringHandleA' DdeCreateStringHandleA user32 1645 +imp 'DdeCreateStringHandle' DdeCreateStringHandleW user32 1646 +imp 'DdeDisconnect' DdeDisconnect user32 1647 +imp 'DdeDisconnectList' DdeDisconnectList user32 1648 +imp 'DdeEnableCallback' DdeEnableCallback user32 1649 +imp 'DdeFreeDataHandle' DdeFreeDataHandle user32 1650 +imp 'DdeFreeStringHandle' DdeFreeStringHandle user32 1651 +imp 'DdeGetData' DdeGetData user32 1652 +imp 'DdeGetLastError' DdeGetLastError user32 1653 +imp 'DdeGetQualityOfService' DdeGetQualityOfService user32 1654 +imp 'DdeImpersonateClient' DdeImpersonateClient user32 1655 +imp 'DdeInitializeA' DdeInitializeA user32 1656 +imp 'DdeInitialize' DdeInitializeW user32 1657 +imp 'DdeKeepStringHandle' DdeKeepStringHandle user32 1658 +imp 'DdeNameService' DdeNameService user32 1659 +imp 'DdePostAdvise' DdePostAdvise user32 1660 +imp 'DdeQueryConvInfo' DdeQueryConvInfo user32 1661 +imp 'DdeQueryNextServer' DdeQueryNextServer user32 1662 +imp 'DdeQueryStringA' DdeQueryStringA user32 1663 +imp 'DdeQueryString' DdeQueryStringW user32 1664 +imp 'DdeReconnect' DdeReconnect user32 1665 +imp 'DdeSetQualityOfService' DdeSetQualityOfService user32 1666 +imp 'DdeSetUserHandle' DdeSetUserHandle user32 1667 +imp 'DdeUnaccessData' DdeUnaccessData user32 1668 +imp 'DdeUninitialize' DdeUninitialize user32 1669 +imp 'DeactivateActCtx' DeactivateActCtx KernelBase 238 +imp 'DeactivateActCtxWorker' DeactivateActCtxWorker kernel32 259 +imp 'DebugActiveProcess' DebugActiveProcess KernelBase 239 1 +imp 'DebugActiveProcessStop' DebugActiveProcessStop KernelBase 240 1 +imp 'DebugBreakProcess' DebugBreakProcess kernel32 263 1 +imp 'DebugSetProcessKillOnExit' DebugSetProcessKillOnExit kernel32 264 +imp 'DecryptFileA' DecryptFileA advapi32 1235 +imp 'DecryptFile' DecryptFileW advapi32 1236 +imp 'DefFrameProcA' DefFrameProcA user32 1672 +imp 'DefFrameProc' DefFrameProcW user32 1673 +imp 'DefMDIChildProcA' DefMDIChildProcA user32 1674 +imp 'DefMDIChildProc' DefMDIChildProcW user32 1675 +imp 'DefRawInputProc' DefRawInputProc user32 1676 +imp 'DeferWindowPos' DeferWindowPos user32 1679 +imp 'DeferWindowPosAndBand' DeferWindowPosAndBand user32 1680 +imp 'DefineDosDeviceA' DefineDosDeviceA kernel32 267 +imp 'DefineDosDevice' DefineDosDeviceW KernelBase 245 +imp 'DelayLoadFailureHook' DelayLoadFailureHook KernelBase 246 +imp 'DelayLoadFailureHookLookup' DelayLoadFailureHookLookup KernelBase 247 +imp 'DelegateInput' DelegateInput user32 2503 +imp 'DeleteAce' DeleteAce KernelBase 248 +imp 'DeleteAtom' DeleteAtom kernel32 270 +imp 'DeleteBoundaryDescriptor' DeleteBoundaryDescriptor KernelBase 249 +imp 'DeleteColorSpace' DeleteColorSpace gdi32 1383 +imp 'DeleteDC' DeleteDC gdi32 1384 +imp 'DeleteEnclave' DeleteEnclave KernelBase 251 +imp 'DeleteEnhMetaFile' DeleteEnhMetaFile gdi32 1385 +imp 'DeleteFiber' DeleteFiber KernelBase 252 +imp 'DeleteFile' DeleteFileW KernelBase 254 1 +imp 'DeleteFileA' DeleteFileA KernelBase 253 1 +imp 'DeleteFileTransactedA' DeleteFileTransactedA kernel32 275 +imp 'DeleteFileTransacted' DeleteFileTransactedW kernel32 276 +imp 'DeleteMenu' DeleteMenu user32 1681 +imp 'DeleteMetaFile' DeleteMetaFile gdi32 1386 +imp 'DeleteObject' DeleteObject gdi32 1387 +imp 'DeleteProcThreadAttributeList' DeleteProcThreadAttributeList KernelBase 255 1 +imp 'DeleteService' DeleteService advapi32 1238 +imp 'DeleteStateAtomValue' DeleteStateAtomValue KernelBase 256 +imp 'DeleteStateContainer' DeleteStateContainer KernelBase 257 +imp 'DeleteStateContainerValue' DeleteStateContainerValue KernelBase 258 +imp 'DeleteSynchronizationBarrier' DeleteSynchronizationBarrier kernel32 279 +imp 'DeleteTimerQueue' DeleteTimerQueue kernel32 280 +imp 'DeleteTimerQueueEx' DeleteTimerQueueEx KernelBase 260 +imp 'DeleteTimerQueueTimer' DeleteTimerQueueTimer KernelBase 261 +imp 'DeleteUmsCompletionList' DeleteUmsCompletionList kernel32 283 +imp 'DeleteUmsThreadContext' DeleteUmsThreadContext kernel32 284 +imp 'DeleteVolumeMountPointA' DeleteVolumeMountPointA kernel32 285 +imp 'DeleteVolumeMountPoint' DeleteVolumeMountPointW KernelBase 262 +imp 'DequeueUmsCompletionListItems' DequeueUmsCompletionListItems kernel32 287 +imp 'DeregisterEventSource' DeregisterEventSource advapi32 1239 +imp 'DeregisterShellHookWindow' DeregisterShellHookWindow user32 1682 +imp 'DeriveCapabilitySidsFromName' DeriveCapabilitySidsFromName KernelBase 263 +imp 'DescribePixelFormat' DescribePixelFormat gdi32 1388 +imp 'DestroyAcceleratorTable' DestroyAcceleratorTable user32 1683 +imp 'DestroyCaret' DestroyCaret user32 1684 +imp 'DestroyCursor' DestroyCursor user32 1685 +imp 'DestroyDCompositionHwndTarget' DestroyDCompositionHwndTarget user32 1686 +imp 'DestroyIcon' DestroyIcon user32 1687 +imp 'DestroyMenu' DestroyMenu user32 1688 +imp 'DestroyOPMProtectedOutput' DestroyOPMProtectedOutput gdi32 1389 +imp 'DestroyPalmRejectionDelayZone' DestroyPalmRejectionDelayZone user32 1504 +imp 'DestroyPhysicalMonitorInternal' DestroyPhysicalMonitorInternal gdi32 1390 +imp 'DestroyPrivateObjectSecurity' DestroyPrivateObjectSecurity KernelBase 264 +imp 'DestroyReasons' DestroyReasons user32 1689 +imp 'DestroyWindow' DestroyWindow user32 1690 1 +imp 'DeviceCapabilitiesExA' DeviceCapabilitiesExA gdi32 1391 +imp 'DeviceIoControl' DeviceIoControl KernelBase 265 8 +imp 'DialogBoxIndirectParamA' DialogBoxIndirectParamA user32 1691 +imp 'DialogBoxIndirectParamAor' DialogBoxIndirectParamAorW user32 1692 +imp 'DialogBoxIndirectParam' DialogBoxIndirectParamW user32 1693 +imp 'DialogBoxParamA' DialogBoxParamA user32 1694 +imp 'DialogBoxParam' DialogBoxParamW user32 1695 +imp 'DisablePredefinedHandleTableInternal' DisablePredefinedHandleTableInternal KernelBase 266 +imp 'DisableProcessWindowsGhosting' DisableProcessWindowsGhosting user32 1696 +imp 'DisableThreadLibraryCalls' DisableThreadLibraryCalls KernelBase 267 +imp 'DisableThreadProfiling' DisableThreadProfiling kernel32 290 +imp 'DiscardVirtualMemory' DiscardVirtualMemory KernelBase 269 +imp 'DisconnectNamedPipe' DisconnectNamedPipe KernelBase 270 1 +imp 'DispatchMessage' DispatchMessageW user32 1698 1 +imp 'DispatchMessageA' DispatchMessageA user32 1697 1 +imp 'DisplayConfigGetDeviceInfo' DisplayConfigGetDeviceInfo user32 1699 +imp 'DisplayConfigSetDeviceInfo' DisplayConfigSetDeviceInfo user32 1700 +imp 'DisplayExitWindowsWarnings' DisplayExitWindowsWarnings user32 1701 +imp 'DlgDirListA' DlgDirListA user32 1702 +imp 'DlgDirListComboBoxA' DlgDirListComboBoxA user32 1703 +imp 'DlgDirListComboBox' DlgDirListComboBoxW user32 1704 +imp 'DlgDirList' DlgDirListW user32 1705 +imp 'DlgDirSelectComboBoxExA' DlgDirSelectComboBoxExA user32 1706 +imp 'DlgDirSelectComboBoxEx' DlgDirSelectComboBoxExW user32 1707 +imp 'DlgDirSelectExA' DlgDirSelectExA user32 1708 +imp 'DlgDirSelectEx' DlgDirSelectExW user32 1709 +imp 'DllCanUnloadNow' DllCanUnloadNow comdlg32 107 +imp 'DllGetActivationFactory' DllGetActivationFactory shell32 277 +imp 'DllGetClassObject' DllGetClassObject comdlg32 108 +imp 'DllGetVersion' DllGetVersion shell32 279 +imp 'DllInstall' DllInstall shell32 280 +imp 'DllRegisterServer' DllRegisterServer shell32 281 +imp 'DllUnregisterServer' DllUnregisterServer shell32 282 +imp 'DnsHostnameToComputerNameA' DnsHostnameToComputerNameA kernel32 294 +imp 'DnsHostnameToComputerNameEx' DnsHostnameToComputerNameExW KernelBase 271 +imp 'DnsHostnameToComputerName' DnsHostnameToComputerNameW kernel32 296 +imp 'DoEnvironmentSubstA' DoEnvironmentSubstA shell32 283 +imp 'DoEnvironmentSubst' DoEnvironmentSubstW shell32 284 +imp 'DoSoundConnect' DoSoundConnect user32 1710 +imp 'DoSoundDisconnect' DoSoundDisconnect user32 1711 +imp 'DosDateTimeToFileTime' DosDateTimeToFileTime kernel32 297 +imp 'DosPathToSessionPathA' DosPathToSessionPathA kernel32 298 +imp 'DosPathToSessionPath' DosPathToSessionPathW kernel32 299 +imp 'DragAcceptFiles' DragAcceptFiles shell32 285 +imp 'DragDetect' DragDetect user32 1712 +imp 'DragFinish' DragFinish shell32 286 +imp 'DragObject' DragObject user32 1713 +imp 'DragQueryFileA' DragQueryFileA shell32 288 +imp 'DragQueryFileAor' DragQueryFileAorW shell32 289 +imp 'DragQueryFile' DragQueryFileW shell32 290 +imp 'DragQueryPoint' DragQueryPoint shell32 291 +imp 'DrawAnimatedRects' DrawAnimatedRects user32 1714 +imp 'DrawCaption' DrawCaption user32 1715 +imp 'DrawCaptionTempA' DrawCaptionTempA user32 1716 +imp 'DrawCaptionTemp' DrawCaptionTempW user32 1717 +imp 'DrawEdge' DrawEdge user32 1718 +imp 'DrawEscape' DrawEscape gdi32 1393 +imp 'DrawFocusRect' DrawFocusRect user32 1719 +imp 'DrawFrame' DrawFrame user32 1720 +imp 'DrawFrameControl' DrawFrameControl user32 1721 +imp 'DrawIcon' DrawIcon user32 1722 +imp 'DrawIconEx' DrawIconEx user32 1723 +imp 'DrawMenuBar' DrawMenuBar user32 1724 +imp 'DrawMenuBarTemp' DrawMenuBarTemp user32 1725 +imp 'DrawStateA' DrawStateA user32 1726 +imp 'DrawState' DrawStateW user32 1727 +imp 'DrawText' DrawTextW user32 1731 5 +imp 'DrawTextA' DrawTextA user32 1728 5 +imp 'DrawTextEx' DrawTextExW user32 1730 6 +imp 'DrawTextExA' DrawTextExA user32 1729 6 +imp 'DriveType' DriveType shell32 64 +imp 'DsBindWithSpnEx' DsBindWithSpnExW KernelBase 272 +imp 'DsCrackNames' DsCrackNamesW KernelBase 273 +imp 'DsFreeDomainControllerInfo' DsFreeDomainControllerInfoW KernelBase 274 +imp 'DsFreeNameResult' DsFreeNameResultW KernelBase 275 +imp 'DsFreeNgcKey' DsFreeNgcKey KernelBase 276 +imp 'DsFreePasswordCredentials' DsFreePasswordCredentials KernelBase 277 +imp 'DsGetDomainControllerInfo' DsGetDomainControllerInfoW KernelBase 278 +imp 'DsMakePasswordCredentials' DsMakePasswordCredentialsW KernelBase 279 +imp 'DsReadNgcKey' DsReadNgcKeyW KernelBase 280 +imp 'DsUnBind' DsUnBindW KernelBase 281 +imp 'DsWriteNgcKey' DsWriteNgcKeyW KernelBase 282 +imp 'DuplicateConsoleHandle' DuplicateConsoleHandle kernel32 300 +imp 'DuplicateEncryptionInfoFile' DuplicateEncryptionInfoFile advapi32 1241 +imp 'DuplicateEncryptionInfoFileExt' DuplicateEncryptionInfoFileExt kernel32 301 +imp 'DuplicateHandle' DuplicateHandle KernelBase 283 7 +imp 'DuplicateIcon' DuplicateIcon shell32 292 +imp 'DuplicateStateContainerHandle' DuplicateStateContainerHandle KernelBase 284 +imp 'DuplicateToken' DuplicateToken KernelBase 285 3 +imp 'DuplicateTokenEx' DuplicateTokenEx KernelBase 286 6 +imp 'DwmCreatedBitmapRemotingOutput' DwmCreatedBitmapRemotingOutput gdi32 1014 +imp 'DwmGetDxRgn' DwmGetDxRgn user32 1553 +imp 'DwmGetDxSharedSurface' DwmGetDxSharedSurface user32 1732 +imp 'DwmGetRemoteSessionOcclusionEvent' DwmGetRemoteSessionOcclusionEvent user32 1733 +imp 'DwmGetRemoteSessionOcclusionState' DwmGetRemoteSessionOcclusionState user32 1734 +imp 'DwmKernelShutdown' DwmKernelShutdown user32 1735 +imp 'DwmKernelStartup' DwmKernelStartup user32 1736 +imp 'DwmLockScreenUpdates' DwmLockScreenUpdates user32 1737 +imp 'DwmValidateWindow' DwmValidateWindow user32 1738 +imp 'DxTrimNotificationListHead' DxTrimNotificationListHead gdi32 1394 +imp 'EditWndProc' EditWndProc user32 1739 +imp 'ElfBackupEventLogFileA' ElfBackupEventLogFileA advapi32 1244 +imp 'ElfBackupEventLogFile' ElfBackupEventLogFileW advapi32 1245 +imp 'ElfChangeNotify' ElfChangeNotify advapi32 1246 +imp 'ElfClearEventLogFileA' ElfClearEventLogFileA advapi32 1247 +imp 'ElfClearEventLogFile' ElfClearEventLogFileW advapi32 1248 +imp 'ElfCloseEventLog' ElfCloseEventLog advapi32 1249 +imp 'ElfDeregisterEventSource' ElfDeregisterEventSource advapi32 1250 +imp 'ElfFlushEventLog' ElfFlushEventLog advapi32 1251 +imp 'ElfNumberOfRecords' ElfNumberOfRecords advapi32 1252 +imp 'ElfOldestRecord' ElfOldestRecord advapi32 1253 +imp 'ElfOpenBackupEventLogA' ElfOpenBackupEventLogA advapi32 1254 +imp 'ElfOpenBackupEventLog' ElfOpenBackupEventLogW advapi32 1255 +imp 'ElfOpenEventLogA' ElfOpenEventLogA advapi32 1256 +imp 'ElfOpenEventLog' ElfOpenEventLogW advapi32 1257 +imp 'ElfReadEventLogA' ElfReadEventLogA advapi32 1258 +imp 'ElfReadEventLog' ElfReadEventLogW advapi32 1259 +imp 'ElfRegisterEventSourceA' ElfRegisterEventSourceA advapi32 1260 +imp 'ElfRegisterEventSource' ElfRegisterEventSourceW advapi32 1261 +imp 'ElfReportEventA' ElfReportEventA advapi32 1262 +imp 'ElfReportEventAndSource' ElfReportEventAndSourceW advapi32 1263 +imp 'ElfReportEvent' ElfReportEventW advapi32 1264 +imp 'Ellipse' Ellipse gdi32 1395 +imp 'EmptyClipboard' EmptyClipboard user32 1740 +imp 'EmptyWorkingSet' EmptyWorkingSet KernelBase 287 +imp 'EnableEUDC' EnableEUDC gdi32 1396 +imp 'EnableMenuItem' EnableMenuItem user32 1741 +imp 'EnableMouseInPointer' EnableMouseInPointer user32 1742 +imp 'EnableNonClientDpiScaling' EnableNonClientDpiScaling user32 1743 +imp 'EnableOneCoreTransformMode' EnableOneCoreTransformMode user32 1744 +imp 'EnableScrollBar' EnableScrollBar user32 1745 +imp 'EnableSessionForMMCSS' EnableSessionForMMCSS user32 1746 +imp 'EnableThreadProfiling' EnableThreadProfiling kernel32 303 +imp 'EnableTrace' EnableTrace advapi32 1265 +imp 'EnableTraceEx' EnableTraceEx advapi32 1266 +imp 'EnableTraceEx2' EnableTraceEx2 advapi32 1267 +imp 'EnableWindow' EnableWindow user32 1747 +imp 'EncryptFileA' EncryptFileA advapi32 1268 +imp 'EncryptFile' EncryptFileW advapi32 1269 +imp 'EncryptedFileKeyInfo' EncryptedFileKeyInfo advapi32 1270 +imp 'EncryptionDisable' EncryptionDisable advapi32 1271 +imp 'EndDeferWindowPos' EndDeferWindowPos user32 1748 +imp 'EndDeferWindowPosEx' EndDeferWindowPosEx user32 1749 +imp 'EndDialog' EndDialog user32 1750 +imp 'EndDoc' EndDoc gdi32 1397 +imp 'EndFormPage' EndFormPage gdi32 1398 +imp 'EndGdiRendering' EndGdiRendering gdi32 1399 +imp 'EndMenu' EndMenu user32 1751 +imp 'EndPage' EndPage gdi32 1400 +imp 'EndPaint' EndPaint user32 1752 2 +imp 'EndPath' EndPath gdi32 1401 +imp 'EndTask' EndTask user32 1753 +imp 'EndUpdateResourceA' EndUpdateResourceA kernel32 306 +imp 'EndUpdateResource' EndUpdateResourceW kernel32 307 +imp 'EngAcquireSemaphore' EngAcquireSemaphore gdi32 1402 +imp 'EngAlphaBlend' EngAlphaBlend gdi32 1403 +imp 'EngAssociateSurface' EngAssociateSurface gdi32 1404 +imp 'EngBitBlt' EngBitBlt gdi32 1405 +imp 'EngCheckAbort' EngCheckAbort gdi32 1406 +imp 'EngComputeGlyphSet' EngComputeGlyphSet gdi32 1407 +imp 'EngCopyBits' EngCopyBits gdi32 1408 +imp 'EngCreateBitmap' EngCreateBitmap gdi32 1409 +imp 'EngCreateClip' EngCreateClip gdi32 1410 +imp 'EngCreateDeviceBitmap' EngCreateDeviceBitmap gdi32 1411 +imp 'EngCreateDeviceSurface' EngCreateDeviceSurface gdi32 1412 +imp 'EngCreatePalette' EngCreatePalette gdi32 1413 +imp 'EngCreateSemaphore' EngCreateSemaphore gdi32 1414 +imp 'EngDeleteClip' EngDeleteClip gdi32 1415 +imp 'EngDeletePalette' EngDeletePalette gdi32 1416 +imp 'EngDeletePath' EngDeletePath gdi32 1417 +imp 'EngDeleteSemaphore' EngDeleteSemaphore gdi32 1418 +imp 'EngDeleteSurface' EngDeleteSurface gdi32 1419 +imp 'EngEraseSurface' EngEraseSurface gdi32 1420 +imp 'EngFillPath' EngFillPath gdi32 1421 +imp 'EngFindResource' EngFindResource gdi32 1422 +imp 'EngFreeModule' EngFreeModule gdi32 1423 +imp 'EngGetCurrentCodePage' EngGetCurrentCodePage gdi32 1424 +imp 'EngGetDriverName' EngGetDriverName gdi32 1425 +imp 'EngGetPrinterDataFileName' EngGetPrinterDataFileName gdi32 1426 +imp 'EngGradientFill' EngGradientFill gdi32 1427 +imp 'EngLineTo' EngLineTo gdi32 1428 +imp 'EngLoadModule' EngLoadModule gdi32 1429 +imp 'EngLockSurface' EngLockSurface gdi32 1430 +imp 'EngMarkBandingSurface' EngMarkBandingSurface gdi32 1431 +imp 'EngMultiByteToUnicodeN' EngMultiByteToUnicodeN gdi32 1432 +imp 'EngMultiByteToWideChar' EngMultiByteToWideChar gdi32 1433 +imp 'EngPaint' EngPaint gdi32 1434 +imp 'EngPlgBlt' EngPlgBlt gdi32 1435 +imp 'EngQueryEMFInfo' EngQueryEMFInfo gdi32 1436 +imp 'EngQueryLocalTime' EngQueryLocalTime gdi32 1437 +imp 'EngReleaseSemaphore' EngReleaseSemaphore gdi32 1438 +imp 'EngStretchBlt' EngStretchBlt gdi32 1439 +imp 'EngStretchBltROP' EngStretchBltROP gdi32 1440 +imp 'EngStrokeAndFillPath' EngStrokeAndFillPath gdi32 1441 +imp 'EngStrokePath' EngStrokePath gdi32 1442 +imp 'EngTextOut' EngTextOut gdi32 1443 +imp 'EngTransparentBlt' EngTransparentBlt gdi32 1444 +imp 'EngUnicodeToMultiByteN' EngUnicodeToMultiByteN gdi32 1445 +imp 'EngUnlockSurface' EngUnlockSurface gdi32 1446 +imp 'EngWideCharToMultiByte' EngWideCharToMultiByte gdi32 1447 +imp 'EnterCriticalPolicySectionInternal' EnterCriticalPolicySectionInternal KernelBase 291 +imp 'EnterReaderModeHelper' EnterReaderModeHelper user32 1754 +imp 'EnterSynchronizationBarrier' EnterSynchronizationBarrier KernelBase 293 +imp 'EnterUmsSchedulingMode' EnterUmsSchedulingMode kernel32 310 +imp 'EnumCalendarInfoA' EnumCalendarInfoA kernel32 311 +imp 'EnumCalendarInfoExA' EnumCalendarInfoExA kernel32 312 +imp 'EnumCalendarInfoExEx' EnumCalendarInfoExEx KernelBase 294 +imp 'EnumCalendarInfoEx' EnumCalendarInfoExW KernelBase 295 +imp 'EnumCalendarInfo' EnumCalendarInfoW KernelBase 296 +imp 'EnumChildWindows' EnumChildWindows user32 1755 3 +imp 'EnumClipboardFormats' EnumClipboardFormats user32 1756 +imp 'EnumDateFormatsA' EnumDateFormatsA kernel32 316 +imp 'EnumDateFormatsExA' EnumDateFormatsExA kernel32 317 +imp 'EnumDateFormatsExEx' EnumDateFormatsExEx KernelBase 297 +imp 'EnumDateFormatsEx' EnumDateFormatsExW KernelBase 298 +imp 'EnumDateFormats' EnumDateFormatsW KernelBase 299 +imp 'EnumDependentServicesA' EnumDependentServicesA advapi32 1272 +imp 'EnumDependentServices' EnumDependentServicesW advapi32 1273 +imp 'EnumDesktopWindows' EnumDesktopWindows user32 1757 +imp 'EnumDesktopsA' EnumDesktopsA user32 1758 +imp 'EnumDesktops' EnumDesktopsW user32 1759 +imp 'EnumDeviceDrivers' EnumDeviceDrivers KernelBase 300 +imp 'EnumDisplayDevicesA' EnumDisplayDevicesA user32 1760 +imp 'EnumDisplayDevices' EnumDisplayDevicesW user32 1761 +imp 'EnumDisplayMonitors' EnumDisplayMonitors user32 1762 +imp 'EnumDisplaySettingsA' EnumDisplaySettingsA user32 1763 +imp 'EnumDisplaySettingsExA' EnumDisplaySettingsExA user32 1764 +imp 'EnumDisplaySettingsEx' EnumDisplaySettingsExW user32 1765 +imp 'EnumDisplaySettings' EnumDisplaySettingsW user32 1766 +imp 'EnumDynamicTimeZoneInformation' EnumDynamicTimeZoneInformation KernelBase 301 +imp 'EnumEnhMetaFile' EnumEnhMetaFile gdi32 1448 +imp 'EnumFontFamiliesA' EnumFontFamiliesA gdi32 1449 +imp 'EnumFontFamiliesExA' EnumFontFamiliesExA gdi32 1450 +imp 'EnumFontFamiliesEx' EnumFontFamiliesExW gdi32 1451 +imp 'EnumFontFamilies' EnumFontFamiliesW gdi32 1452 +imp 'EnumFontsA' EnumFontsA gdi32 1453 +imp 'EnumFonts' EnumFontsW gdi32 1454 +imp 'EnumICMProfilesA' EnumICMProfilesA gdi32 1455 +imp 'EnumICMProfiles' EnumICMProfilesW gdi32 1456 +imp 'EnumLanguageGroupLocalesA' EnumLanguageGroupLocalesA kernel32 321 +imp 'EnumLanguageGroupLocales' EnumLanguageGroupLocalesW KernelBase 302 +imp 'EnumMetaFile' EnumMetaFile gdi32 1457 +imp 'EnumObjects' EnumObjects gdi32 1458 +imp 'EnumPageFilesA' EnumPageFilesA KernelBase 303 +imp 'EnumPageFiles' EnumPageFilesW KernelBase 304 +imp 'EnumProcessModules' EnumProcessModules KernelBase 305 +imp 'EnumProcessModulesEx' EnumProcessModulesEx KernelBase 306 +imp 'EnumProcesses' EnumProcesses KernelBase 307 +imp 'EnumPropsA' EnumPropsA user32 1767 +imp 'EnumPropsExA' EnumPropsExA user32 1768 +imp 'EnumPropsEx' EnumPropsExW user32 1769 +imp 'EnumProps' EnumPropsW user32 1770 +imp 'EnumResourceLanguagesA' EnumResourceLanguagesA kernel32 323 +imp 'EnumResourceLanguagesExA' EnumResourceLanguagesExA KernelBase 308 +imp 'EnumResourceLanguagesEx' EnumResourceLanguagesExW KernelBase 309 +imp 'EnumResourceLanguages' EnumResourceLanguagesW kernel32 326 +imp 'EnumResourceNamesA' EnumResourceNamesA kernel32 327 +imp 'EnumResourceNamesExA' EnumResourceNamesExA KernelBase 310 +imp 'EnumResourceNamesEx' EnumResourceNamesExW KernelBase 311 +imp 'EnumResourceNames' EnumResourceNamesW KernelBase 312 +imp 'EnumResourceTypesA' EnumResourceTypesA kernel32 331 +imp 'EnumResourceTypesExA' EnumResourceTypesExA KernelBase 313 +imp 'EnumResourceTypesEx' EnumResourceTypesExW KernelBase 314 +imp 'EnumResourceTypes' EnumResourceTypesW kernel32 334 +imp 'EnumServiceGroup' EnumServiceGroupW advapi32 1275 +imp 'EnumServicesStatusA' EnumServicesStatusA advapi32 1276 +imp 'EnumServicesStatusExA' EnumServicesStatusExA advapi32 1277 +imp 'EnumServicesStatusEx' EnumServicesStatusExW advapi32 1278 +imp 'EnumServicesStatus' EnumServicesStatusW advapi32 1279 +imp 'EnumSystemCodePagesA' EnumSystemCodePagesA kernel32 335 +imp 'EnumSystemCodePages' EnumSystemCodePagesW KernelBase 315 +imp 'EnumSystemFirmwareTables' EnumSystemFirmwareTables KernelBase 316 +imp 'EnumSystemGeoID' EnumSystemGeoID KernelBase 317 +imp 'EnumSystemGeoNames' EnumSystemGeoNames KernelBase 318 +imp 'EnumSystemLanguageGroupsA' EnumSystemLanguageGroupsA kernel32 340 +imp 'EnumSystemLanguageGroups' EnumSystemLanguageGroupsW KernelBase 319 +imp 'EnumSystemLocalesA' EnumSystemLocalesA KernelBase 320 +imp 'EnumSystemLocalesEx' EnumSystemLocalesEx KernelBase 321 +imp 'EnumSystemLocales' EnumSystemLocalesW KernelBase 322 +imp 'EnumThreadWindows' EnumThreadWindows user32 1771 +imp 'EnumTimeFormatsA' EnumTimeFormatsA kernel32 345 +imp 'EnumTimeFormatsEx' EnumTimeFormatsEx KernelBase 323 +imp 'EnumTimeFormats' EnumTimeFormatsW KernelBase 324 +imp 'EnumUILanguagesA' EnumUILanguagesA kernel32 348 +imp 'EnumUILanguages' EnumUILanguagesW KernelBase 325 +imp 'EnumWindowStationsA' EnumWindowStationsA user32 1772 +imp 'EnumWindowStations' EnumWindowStationsW user32 1773 +imp 'EnumWindows' EnumWindows user32 1774 +imp 'EnumerateExtensionNames' EnumerateExtensionNames KernelBase 326 +imp 'EnumerateLocalComputerNamesA' EnumerateLocalComputerNamesA kernel32 350 +imp 'EnumerateLocalComputerNames' EnumerateLocalComputerNamesW kernel32 351 +imp 'EnumerateStateAtomValues' EnumerateStateAtomValues KernelBase 327 +imp 'EnumerateStateContainerItems' EnumerateStateContainerItems KernelBase 328 +imp 'EnumerateTraceGuids' EnumerateTraceGuids advapi32 1280 +imp 'EnumerateTraceGuidsEx' EnumerateTraceGuidsEx advapi32 1281 +imp 'EqualDomainSid' EqualDomainSid KernelBase 329 +imp 'EqualPrefixSid' EqualPrefixSid KernelBase 330 +imp 'EqualRect' EqualRect user32 1775 +imp 'EqualRgn' EqualRgn gdi32 1459 +imp 'EqualSid' EqualSid KernelBase 331 +imp 'EraseTape' EraseTape kernel32 352 +imp 'Escape' Escape gdi32 1460 +imp 'EscapeCommFunction' EscapeCommFunction KernelBase 332 +imp 'EtwCheckCoverage' EtwCheckCoverage ntdll 60 +imp 'EtwCreateTraceInstanceId' EtwCreateTraceInstanceId ntdll 61 +imp 'EtwDeliverDataBlock' EtwDeliverDataBlock ntdll 62 +imp 'EtwEnumerateProcessRegGuids' EtwEnumerateProcessRegGuids ntdll 63 +imp 'EtwEventActivityIdControl' EtwEventActivityIdControl ntdll 64 +imp 'EtwEventEnabled' EtwEventEnabled ntdll 65 +imp 'EtwEventProviderEnabled' EtwEventProviderEnabled ntdll 66 +imp 'EtwEventRegister' EtwEventRegister ntdll 67 +imp 'EtwEventSetInformation' EtwEventSetInformation ntdll 68 +imp 'EtwEventUnregister' EtwEventUnregister ntdll 69 +imp 'EtwEventWrite' EtwEventWrite ntdll 70 +imp 'EtwEventWriteEndScenario' EtwEventWriteEndScenario ntdll 71 +imp 'EtwEventWriteEx' EtwEventWriteEx ntdll 72 +imp 'EtwEventWriteFull' EtwEventWriteFull ntdll 73 +imp 'EtwEventWriteNoRegistration' EtwEventWriteNoRegistration ntdll 74 +imp 'EtwEventWriteStartScenario' EtwEventWriteStartScenario ntdll 75 +imp 'EtwEventWriteString' EtwEventWriteString ntdll 76 +imp 'EtwEventWriteTransfer' EtwEventWriteTransfer ntdll 77 +imp 'EtwGetTraceEnableFlags' EtwGetTraceEnableFlags ntdll 78 +imp 'EtwGetTraceEnableLevel' EtwGetTraceEnableLevel ntdll 79 +imp 'EtwGetTraceLoggerHandle' EtwGetTraceLoggerHandle ntdll 80 +imp 'EtwLogTraceEvent' EtwLogTraceEvent ntdll 81 +imp 'EtwNotificationRegister' EtwNotificationRegister ntdll 82 +imp 'EtwNotificationUnregister' EtwNotificationUnregister ntdll 83 +imp 'EtwProcessPrivateLoggerRequest' EtwProcessPrivateLoggerRequest ntdll 84 +imp 'EtwRegisterSecurityProvider' EtwRegisterSecurityProvider ntdll 85 +imp 'EtwRegisterTraceGuidsA' EtwRegisterTraceGuidsA ntdll 86 +imp 'EtwRegisterTraceGuids' EtwRegisterTraceGuidsW ntdll 87 +imp 'EtwReplyNotification' EtwReplyNotification ntdll 88 +imp 'EtwSendNotification' EtwSendNotification ntdll 89 +imp 'EtwSetMark' EtwSetMark ntdll 90 +imp 'EtwTraceEventInstance' EtwTraceEventInstance ntdll 91 +imp 'EtwTraceMessage' EtwTraceMessage ntdll 92 +imp 'EtwTraceMessageVa' EtwTraceMessageVa ntdll 93 +imp 'EtwUnregisterTraceGuids' EtwUnregisterTraceGuids ntdll 94 +imp 'EtwWriteUMSecurityEvent' EtwWriteUMSecurityEvent ntdll 95 +imp 'EtwpCreateEtwThread' EtwpCreateEtwThread ntdll 96 +imp 'EtwpGetCpuSpeed' EtwpGetCpuSpeed ntdll 97 +imp 'EudcLoadLink' EudcLoadLinkW gdi32 1461 +imp 'EudcUnloadLink' EudcUnloadLinkW gdi32 1462 +imp 'EvaluateProximityToPolygon' EvaluateProximityToPolygon user32 1776 +imp 'EvaluateProximityToRect' EvaluateProximityToRect user32 1777 +imp 'EventAccessControl' EventAccessControl advapi32 1285 +imp 'EventAccessQuery' EventAccessQuery advapi32 1286 +imp 'EventAccessRemove' EventAccessRemove advapi32 1287 +imp 'EvtIntReportAuthzEventAndSourceAsync' EvtIntReportAuthzEventAndSourceAsync ntdll 98 +imp 'EvtIntReportEventAndSourceAsync' EvtIntReportEventAndSourceAsync ntdll 99 +imp 'ExcludeClipRect' ExcludeClipRect gdi32 1463 +imp 'ExcludeUpdateRgn' ExcludeUpdateRgn user32 1778 +imp 'ExecuteUmsThread' ExecuteUmsThread kernel32 354 +imp 'ExitProcess' ExitProcess KernelBase 1343 1 # a.k.a. RtlExitUserProcess +imp 'ExitVDM' ExitVDM kernel32 357 +imp 'ExitWindowsEx' ExitWindowsEx user32 1779 +imp 'ExpInterlockedPopEntrySListEnd' ExpInterlockedPopEntrySListEnd ntdll 100 +imp 'ExpInterlockedPopEntrySListFault' ExpInterlockedPopEntrySListFault ntdll 101 +imp 'ExpInterlockedPopEntrySListResume' ExpInterlockedPopEntrySListResume ntdll 102 +imp 'ExpandEnvironmentStringsA' ExpandEnvironmentStringsA KernelBase 345 +imp 'ExpandEnvironmentStrings' ExpandEnvironmentStringsW KernelBase 346 +imp 'ExpungeConsoleCommandHistoryA' ExpungeConsoleCommandHistoryA KernelBase 347 +imp 'ExpungeConsoleCommandHistory' ExpungeConsoleCommandHistoryW KernelBase 348 +imp 'ExtCreatePen' ExtCreatePen gdi32 1464 +imp 'ExtCreateRegion' ExtCreateRegion gdi32 1465 +imp 'ExtEscape' ExtEscape gdi32 1466 +imp 'ExtFloodFill' ExtFloodFill gdi32 1467 +imp 'ExtSelectClipRgn' ExtSelectClipRgn gdi32 1468 +imp 'ExtTextOutA' ExtTextOutA gdi32 1469 +imp 'ExtTextOut' ExtTextOutW gdi32 1470 +imp 'ExtensionProgIdExists' ExtensionProgIdExists KernelBase 349 +imp 'ExtractAssociatedIconA' ExtractAssociatedIconA shell32 293 +imp 'ExtractAssociatedIconExA' ExtractAssociatedIconExA shell32 294 +imp 'ExtractAssociatedIconEx' ExtractAssociatedIconExW shell32 295 +imp 'ExtractAssociatedIcon' ExtractAssociatedIconW shell32 296 +imp 'ExtractIconA' ExtractIconA shell32 297 +imp 'ExtractIconExA' ExtractIconExA shell32 299 +imp 'ExtractIconEx' ExtractIconExW shell32 300 +imp 'ExtractIcon' ExtractIconW shell32 301 +imp 'FONTOBJ_cGetAllGlyphHandles' FONTOBJ_cGetAllGlyphHandles gdi32 1471 +imp 'FONTOBJ_cGetGlyphs' FONTOBJ_cGetGlyphs gdi32 1472 +imp 'FONTOBJ_pQueryGlyphAttrs' FONTOBJ_pQueryGlyphAttrs gdi32 1473 +imp 'FONTOBJ_pfdg' FONTOBJ_pfdg gdi32 1474 +imp 'FONTOBJ_pifi' FONTOBJ_pifi gdi32 1475 +imp 'FONTOBJ_pvTrueTypeFontFile' FONTOBJ_pvTrueTypeFontFile gdi32 1476 +imp 'FONTOBJ_pxoGetXform' FONTOBJ_pxoGetXform gdi32 1477 +imp 'FONTOBJ_vGetInfo' FONTOBJ_vGetInfo gdi32 1478 +imp 'FatalAppExitA' FatalAppExitA KernelBase 350 +imp 'FatalAppExit' FatalAppExitW KernelBase 351 +imp 'FatalExit' FatalExit kernel32 364 1 +imp 'FileEncryptionStatusA' FileEncryptionStatusA advapi32 1300 +imp 'FileEncryptionStatus' FileEncryptionStatusW advapi32 1301 +imp 'FileProtocolHandler' FileProtocolHandler url 104 +imp 'FileProtocolHandlerA' FileProtocolHandlerA url 105 +imp 'FileTimeToDosDateTime' FileTimeToDosDateTime kernel32 365 +imp 'FileTimeToLocalFileTime' FileTimeToLocalFileTime KernelBase 352 +imp 'FileTimeToSystemTime' FileTimeToSystemTime KernelBase 353 +imp 'FillConsoleOutputAttribute' FillConsoleOutputAttribute KernelBase 354 5 +imp 'FillConsoleOutputCharacter' FillConsoleOutputCharacterW KernelBase 356 5 +imp 'FillConsoleOutputCharacterA' FillConsoleOutputCharacterA KernelBase 355 5 +imp 'FillPath' FillPath gdi32 1479 +imp 'FillRect' FillRect user32 1780 +imp 'FillRgn' FillRgn gdi32 1480 +imp 'FindActCtxSectionGuid' FindActCtxSectionGuid KernelBase 357 +imp 'FindActCtxSectionGuidWorker' FindActCtxSectionGuidWorker kernel32 372 +imp 'FindActCtxSectionStringA' FindActCtxSectionStringA kernel32 373 +imp 'FindActCtxSectionString' FindActCtxSectionStringW KernelBase 358 +imp 'FindActCtxSectionStringWWorker' FindActCtxSectionStringWWorker kernel32 375 +imp 'FindAtomA' FindAtomA kernel32 376 +imp 'FindAtom' FindAtomW kernel32 377 +imp 'FindClose' FindClose KernelBase 359 1 +imp 'FindCloseChangeNotification' FindCloseChangeNotification KernelBase 360 +imp 'FindExecutableA' FindExecutableA shell32 302 +imp 'FindExecutable' FindExecutableW shell32 303 +imp 'FindFirstChangeNotificationA' FindFirstChangeNotificationA KernelBase 361 +imp 'FindFirstChangeNotification' FindFirstChangeNotificationW KernelBase 362 +imp 'FindFirstFile' FindFirstFileW KernelBase 367 2 +imp 'FindFirstFileA' FindFirstFileA KernelBase 363 2 +imp 'FindFirstFileEx' FindFirstFileExW KernelBase 365 6 +imp 'FindFirstFileExA' FindFirstFileExA KernelBase 364 6 +imp 'FindFirstFileNameTransacted' FindFirstFileNameTransactedW kernel32 385 +imp 'FindFirstFileName' FindFirstFileNameW KernelBase 366 +imp 'FindFirstFileTransactedA' FindFirstFileTransactedA kernel32 387 +imp 'FindFirstFileTransacted' FindFirstFileTransactedW kernel32 388 +imp 'FindFirstFreeAce' FindFirstFreeAce KernelBase 368 +imp 'FindFirstStream' FindFirstStreamW KernelBase 369 +imp 'FindFirstStreamTransacted' FindFirstStreamTransactedW kernel32 390 +imp 'FindFirstVolume' FindFirstVolumeW KernelBase 370 2 +imp 'FindFirstVolumeA' FindFirstVolumeA kernel32 392 2 +imp 'FindFirstVolumeMountPointA' FindFirstVolumeMountPointA kernel32 393 +imp 'FindFirstVolumeMountPoint' FindFirstVolumeMountPointW kernel32 394 +imp 'FindNLSString' FindNLSString KernelBase 371 +imp 'FindNLSStringEx' FindNLSStringEx KernelBase 372 +imp 'FindNextChangeNotification' FindNextChangeNotification KernelBase 373 +imp 'FindNextFile' FindNextFileW KernelBase 376 2 +imp 'FindNextFileA' FindNextFileA KernelBase 374 2 +imp 'FindNextFileName' FindNextFileNameW KernelBase 375 +imp 'FindNextStream' FindNextStreamW KernelBase 377 +imp 'FindNextVolume' FindNextVolumeW KernelBase 378 3 +imp 'FindNextVolumeA' FindNextVolumeA kernel32 403 3 +imp 'FindNextVolumeMountPointA' FindNextVolumeMountPointA kernel32 404 +imp 'FindNextVolumeMountPoint' FindNextVolumeMountPointW kernel32 405 +imp 'FindPackagesByPackageFamily' FindPackagesByPackageFamily KernelBase 379 +imp 'FindResourceA' FindResourceA kernel32 408 +imp 'FindResourceExA' FindResourceExA kernel32 409 +imp 'FindResourceEx' FindResourceExW KernelBase 380 +imp 'FindResource' FindResourceW KernelBase 381 +imp 'FindStringOrdinal' FindStringOrdinal KernelBase 382 +imp 'FindTextA' FindTextA comdlg32 109 +imp 'FindText' FindTextW comdlg32 110 +imp 'FindVolumeClose' FindVolumeClose KernelBase 383 1 +imp 'FindVolumeMountPointClose' FindVolumeMountPointClose kernel32 414 +imp 'FindWindow' FindWindowW user32 1784 2 +imp 'FindWindowA' FindWindowA user32 1781 2 +imp 'FindWindowEx' FindWindowExW user32 1783 4 +imp 'FindWindowExA' FindWindowExA user32 1782 4 +imp 'FixBrushOrgEx' FixBrushOrgEx gdi32 1481 +imp 'FlashWindow' FlashWindow user32 1785 +imp 'FlashWindowEx' FlashWindowEx user32 1786 +imp 'FlattenPath' FlattenPath gdi32 1482 +imp 'FloodFill' FloodFill gdi32 1483 +imp 'FlsAlloc' FlsAlloc KernelBase 384 +imp 'FlsFree' FlsFree KernelBase 385 +imp 'FlsGetValue' FlsGetValue KernelBase 386 +imp 'FlsSetValue' FlsSetValue KernelBase 387 +imp 'FlushConsoleInputBuffer' FlushConsoleInputBuffer KernelBase 388 1 +imp 'FlushEfsCache' FlushEfsCache advapi32 1303 +imp 'FlushFileBuffers' FlushFileBuffers KernelBase 389 1 +imp 'FlushInstructionCache' FlushInstructionCache KernelBase 390 +imp 'FlushTraceA' FlushTraceA advapi32 1304 +imp 'FlushTrace' FlushTraceW advapi32 1305 +imp 'FlushViewOfFile' FlushViewOfFile KernelBase 392 2 +imp 'FoldStringA' FoldStringA kernel32 424 +imp 'FoldString' FoldStringW KernelBase 393 +imp 'FontIsLinked' FontIsLinked gdi32 1484 +imp 'ForceSyncFgPolicyInternal' ForceSyncFgPolicyInternal KernelBase 394 +imp 'FormatApplicationUserModelId' FormatApplicationUserModelId KernelBase 395 +imp 'FormatApplicationUserModelIdA' FormatApplicationUserModelIdA KernelBase 396 +imp 'FormatMessage' FormatMessageW KernelBase 398 7 +imp 'FormatMessageA' FormatMessageA KernelBase 397 7 +imp 'FrameRect' FrameRect user32 1787 +imp 'FrameRgn' FrameRgn gdi32 1485 +imp 'FreeAddrInfoEx' FreeAddrInfoExW ws2_32 26 +imp 'FreeAddrInfo' FreeAddrInfoW ws2_32 27 +imp 'FreeConsole' FreeConsole KernelBase 399 0 +imp 'FreeDDElParam' FreeDDElParam user32 1788 +imp 'FreeEncryptedFileKeyInfo' FreeEncryptedFileKeyInfo advapi32 1306 +imp 'FreeEncryptedFileMetadata' FreeEncryptedFileMetadata advapi32 1307 +imp 'FreeEncryptionCertificateHashList' FreeEncryptionCertificateHashList advapi32 1308 +imp 'FreeEnvironmentStrings' FreeEnvironmentStringsW KernelBase 401 1 +imp 'FreeEnvironmentStringsA' FreeEnvironmentStringsA KernelBase 400 1 +imp 'FreeGPOListInternalA' FreeGPOListInternalA KernelBase 402 +imp 'FreeGPOListInternal' FreeGPOListInternalW KernelBase 403 +imp 'FreeIconList' FreeIconList shell32 304 +imp 'FreeInheritedFromArray' FreeInheritedFromArray advapi32 1309 +imp 'FreeLibrary' FreeLibrary KernelBase 404 1 +imp 'FreeLibraryAndExitThread' FreeLibraryAndExitThread KernelBase 405 +imp 'FreeMemoryJobObject' FreeMemoryJobObject kernel32 435 +imp 'FreeResource' FreeResource KernelBase 407 1 +imp 'FreeSid' FreeSid KernelBase 408 +imp 'FreeUserPhysicalPages' FreeUserPhysicalPages KernelBase 409 +imp 'FrostCrashedWindow' FrostCrashedWindow user32 1789 +imp 'Gdi32DllInitialize' Gdi32DllInitialize gdi32 1486 +imp 'GdiAddFontResource' GdiAddFontResourceW gdi32 1487 +imp 'GdiAddGlsBounds' GdiAddGlsBounds gdi32 1488 +imp 'GdiAddGlsRecord' GdiAddGlsRecord gdi32 1489 +imp 'GdiAddInitialFonts' GdiAddInitialFonts gdi32 1490 +imp 'GdiAlphaBlend' GdiAlphaBlend gdi32 1491 +imp 'GdiArtificialDecrementDriver' GdiArtificialDecrementDriver gdi32 1492 +imp 'GdiBatchLimit' GdiBatchLimit gdi32 1493 +imp 'GdiCleanCacheDC' GdiCleanCacheDC gdi32 1494 +imp 'GdiComment' GdiComment gdi32 1495 +imp 'GdiConsoleTextOut' GdiConsoleTextOut gdi32 1496 +imp 'GdiConvertAndCheckDC' GdiConvertAndCheckDC gdi32 1497 +imp 'GdiConvertBitmap' GdiConvertBitmap gdi32 1498 +imp 'GdiConvertBitmapV5' GdiConvertBitmapV5 gdi32 1499 +imp 'GdiConvertBrush' GdiConvertBrush gdi32 1500 +imp 'GdiConvertDC' GdiConvertDC gdi32 1501 +imp 'GdiConvertEnhMetaFile' GdiConvertEnhMetaFile gdi32 1502 +imp 'GdiConvertFont' GdiConvertFont gdi32 1503 +imp 'GdiConvertMetaFilePict' GdiConvertMetaFilePict gdi32 1504 +imp 'GdiConvertPalette' GdiConvertPalette gdi32 1505 +imp 'GdiConvertRegion' GdiConvertRegion gdi32 1506 +imp 'GdiConvertToDevmode' GdiConvertToDevmodeW gdi32 1507 +imp 'GdiCreateLocalEnhMetaFile' GdiCreateLocalEnhMetaFile gdi32 1508 +imp 'GdiCreateLocalMetaFilePict' GdiCreateLocalMetaFilePict gdi32 1509 +imp 'GdiCurrentProcessSplWow64' GdiCurrentProcessSplWow64 gdi32 1510 +imp 'GdiDeleteLocalDC' GdiDeleteLocalDC gdi32 1511 +imp 'GdiDeleteSpoolFileHandle' GdiDeleteSpoolFileHandle gdi32 1512 +imp 'GdiDescribePixelFormat' GdiDescribePixelFormat gdi32 1513 +imp 'GdiDllInitialize' GdiDllInitialize gdi32 1514 +imp 'GdiDrawStream' GdiDrawStream gdi32 1515 +imp 'GdiEndDocEMF' GdiEndDocEMF gdi32 1516 +imp 'GdiEndPageEMF' GdiEndPageEMF gdi32 1517 +imp 'GdiEntry1' GdiEntry1 gdi32 1518 +imp 'GdiEntry10' GdiEntry10 gdi32 1519 +imp 'GdiEntry11' GdiEntry11 gdi32 1520 +imp 'GdiEntry12' GdiEntry12 gdi32 1521 +imp 'GdiEntry13' GdiEntry13 gdi32 1522 +imp 'GdiEntry14' GdiEntry14 gdi32 1523 +imp 'GdiEntry15' GdiEntry15 gdi32 1524 +imp 'GdiEntry16' GdiEntry16 gdi32 1525 +imp 'GdiEntry2' GdiEntry2 gdi32 1526 +imp 'GdiEntry3' GdiEntry3 gdi32 1527 +imp 'GdiEntry4' GdiEntry4 gdi32 1528 +imp 'GdiEntry5' GdiEntry5 gdi32 1529 +imp 'GdiEntry6' GdiEntry6 gdi32 1530 +imp 'GdiEntry7' GdiEntry7 gdi32 1531 +imp 'GdiEntry8' GdiEntry8 gdi32 1532 +imp 'GdiEntry9' GdiEntry9 gdi32 1533 +imp 'GdiFixUpHandle' GdiFixUpHandle gdi32 1534 +imp 'GdiFlush' GdiFlush gdi32 1535 +imp 'GdiFullscreenControl' GdiFullscreenControl gdi32 1536 +imp 'GdiGetBatchLimit' GdiGetBatchLimit gdi32 1537 +imp 'GdiGetBitmapBitsSize' GdiGetBitmapBitsSize gdi32 1538 +imp 'GdiGetCharDimensions' GdiGetCharDimensions gdi32 1539 +imp 'GdiGetCodePage' GdiGetCodePage gdi32 1540 +imp 'GdiGetDC' GdiGetDC gdi32 1541 +imp 'GdiGetDevmodeForPage' GdiGetDevmodeForPage gdi32 1542 +imp 'GdiGetEntry' GdiGetEntry gdi32 1543 +imp 'GdiGetLocalBrush' GdiGetLocalBrush gdi32 1544 +imp 'GdiGetLocalDC' GdiGetLocalDC gdi32 1545 +imp 'GdiGetLocalFont' GdiGetLocalFont gdi32 1546 +imp 'GdiGetPageCount' GdiGetPageCount gdi32 1547 +imp 'GdiGetPageHandle' GdiGetPageHandle gdi32 1548 +imp 'GdiGetSpoolFileHandle' GdiGetSpoolFileHandle gdi32 1549 +imp 'GdiGetSpoolMessage' GdiGetSpoolMessage gdi32 1550 +imp 'GdiGetVariationStoreDelta' GdiGetVariationStoreDelta gdi32 1551 +imp 'GdiGradientFill' GdiGradientFill gdi32 1552 +imp 'GdiInitSpool' GdiInitSpool gdi32 1553 +imp 'GdiInitializeLanguagePack' GdiInitializeLanguagePack gdi32 1554 +imp 'GdiIsMetaFileDC' GdiIsMetaFileDC gdi32 1555 +imp 'GdiIsMetaPrintDC' GdiIsMetaPrintDC gdi32 1556 +imp 'GdiIsPlayMetafileDC' GdiIsPlayMetafileDC gdi32 1557 +imp 'GdiIsScreenDC' GdiIsScreenDC gdi32 1558 +imp 'GdiIsTrackingEnabled' GdiIsTrackingEnabled gdi32 1559 +imp 'GdiIsUMPDSandboxingEnabled' GdiIsUMPDSandboxingEnabled gdi32 1560 +imp 'GdiLoadType1Fonts' GdiLoadType1Fonts gdi32 1561 +imp 'GdiPlayDCScript' GdiPlayDCScript gdi32 1562 +imp 'GdiPlayEMF' GdiPlayEMF gdi32 1563 +imp 'GdiPlayJournal' GdiPlayJournal gdi32 1564 +imp 'GdiPlayPageEMF' GdiPlayPageEMF gdi32 1565 +imp 'GdiPlayPrivatePageEMF' GdiPlayPrivatePageEMF gdi32 1566 +imp 'GdiPlayScript' GdiPlayScript gdi32 1567 +imp 'GdiPrinterThunk' GdiPrinterThunk gdi32 1568 +imp 'GdiProcessSetup' GdiProcessSetup gdi32 1569 +imp 'GdiQueryFonts' GdiQueryFonts gdi32 1570 +imp 'GdiQueryTable' GdiQueryTable gdi32 1571 +imp 'GdiRealizationInfo' GdiRealizationInfo gdi32 1572 +imp 'GdiReleaseDC' GdiReleaseDC gdi32 1573 +imp 'GdiReleaseLocalDC' GdiReleaseLocalDC gdi32 1574 +imp 'GdiResetDCEMF' GdiResetDCEMF gdi32 1575 +imp 'GdiSetAttrs' GdiSetAttrs gdi32 1576 +imp 'GdiSetBatchLimit' GdiSetBatchLimit gdi32 1577 +imp 'GdiSetLastError' GdiSetLastError gdi32 1578 +imp 'GdiSetPixelFormat' GdiSetPixelFormat gdi32 1579 +imp 'GdiSetServerAttr' GdiSetServerAttr gdi32 1580 +imp 'GdiStartDocEMF' GdiStartDocEMF gdi32 1581 +imp 'GdiStartPageEMF' GdiStartPageEMF gdi32 1582 +imp 'GdiSupportsFontChangeEvent' GdiSupportsFontChangeEvent gdi32 1583 +imp 'GdiSwapBuffers' GdiSwapBuffers gdi32 1584 +imp 'GdiTrackHCreate' GdiTrackHCreate gdi32 1585 +imp 'GdiTrackHDelete' GdiTrackHDelete gdi32 1586 +imp 'GdiTransparentBlt' GdiTransparentBlt gdi32 1587 +imp 'GdiValidateHandle' GdiValidateHandle gdi32 1588 +imp 'GenerateConsoleCtrlEvent' GenerateConsoleCtrlEvent KernelBase 410 2 +imp 'GenerateGPNotificationInternal' GenerateGPNotificationInternal KernelBase 411 +imp 'GetACP' GetACP KernelBase 412 +imp 'GetAcceptExSockaddrs' GetAcceptExSockaddrs MsWSock 4 8 +imp 'GetAcceptLanguagesA' GetAcceptLanguagesA KernelBase 413 +imp 'GetAcceptLanguages' GetAcceptLanguagesW KernelBase 414 +imp 'GetAccessPermissionsForObjectA' GetAccessPermissionsForObjectA advapi32 1311 +imp 'GetAccessPermissionsForObject' GetAccessPermissionsForObjectW advapi32 1312 +imp 'GetAce' GetAce KernelBase 415 +imp 'GetAclInformation' GetAclInformation KernelBase 416 +imp 'GetActiveProcessorCount' GetActiveProcessorCount kernel32 440 +imp 'GetActiveProcessorGroupCount' GetActiveProcessorGroupCount kernel32 441 +imp 'GetActiveWindow' GetActiveWindow user32 1790 +imp 'GetAddrInfoExA' GetAddrInfoExA ws2_32 28 +imp 'GetAddrInfoExCancel' GetAddrInfoExCancel ws2_32 29 +imp 'GetAddrInfoExOverlappedResult' GetAddrInfoExOverlappedResult ws2_32 30 +imp 'GetAddrInfoEx' GetAddrInfoExW ws2_32 31 +imp 'GetAddrInfo' GetAddrInfoW ws2_32 32 +imp 'GetAdjustObjectAttributesForPrivateNamespaceRoutine' GetAdjustObjectAttributesForPrivateNamespaceRoutine KernelBase 417 +imp 'GetAltTabInfoA' GetAltTabInfoA user32 1792 +imp 'GetAltTabInfo' GetAltTabInfoW user32 1793 +imp 'GetAlternatePackageRoots' GetAlternatePackageRoots KernelBase 418 +imp 'GetAncestor' GetAncestor user32 1794 +imp 'GetAppCompatFlags' GetAppCompatFlags user32 1795 +imp 'GetAppCompatFlags2' GetAppCompatFlags2 user32 1796 +imp 'GetAppContainerAce' GetAppContainerAce KernelBase 419 +imp 'GetAppContainerNamedObjectPath' GetAppContainerNamedObjectPath KernelBase 420 +imp 'GetAppDataFolder' GetAppDataFolder KernelBase 421 +imp 'GetAppModelVersion' GetAppModelVersion KernelBase 422 +imp 'GetApplicationRecoveryCallback' GetApplicationRecoveryCallback KernelBase 423 +imp 'GetApplicationRecoveryCallbackWorker' GetApplicationRecoveryCallbackWorker kernel32 445 +imp 'GetApplicationRestartSettings' GetApplicationRestartSettings KernelBase 424 +imp 'GetApplicationRestartSettingsWorker' GetApplicationRestartSettingsWorker kernel32 447 +imp 'GetApplicationUserModelId' GetApplicationUserModelId KernelBase 425 +imp 'GetApplicationUserModelIdFromToken' GetApplicationUserModelIdFromToken KernelBase 426 +imp 'GetAppliedGPOListInternalA' GetAppliedGPOListInternalA KernelBase 427 +imp 'GetAppliedGPOListInternal' GetAppliedGPOListInternalW KernelBase 428 +imp 'GetArcDirection' GetArcDirection gdi32 1589 +imp 'GetAspectRatioFilterEx' GetAspectRatioFilterEx gdi32 1590 +imp 'GetAsyncKeyState' GetAsyncKeyState user32 1797 +imp 'GetAtomNameA' GetAtomNameA kernel32 449 +imp 'GetAtomName' GetAtomNameW kernel32 450 +imp 'GetAuditedPermissionsFromAclA' GetAuditedPermissionsFromAclA advapi32 1315 +imp 'GetAuditedPermissionsFromAcl' GetAuditedPermissionsFromAclW advapi32 1316 +imp 'GetAutoRotationState' GetAutoRotationState user32 1798 +imp 'GetAwarenessFromDpiAwarenessContext' GetAwarenessFromDpiAwarenessContext user32 1799 +imp 'GetBinaryTypeA' GetBinaryTypeA kernel32 452 +imp 'GetBinaryType' GetBinaryTypeW kernel32 453 +imp 'GetBitmapAttributes' GetBitmapAttributes gdi32 1591 +imp 'GetBitmapBits' GetBitmapBits gdi32 1592 +imp 'GetBitmapDimensionEx' GetBitmapDimensionEx gdi32 1593 +imp 'GetBitmapDpiScaleValue' GetBitmapDpiScaleValue gdi32 1594 +imp 'GetBkColor' GetBkColor gdi32 1595 +imp 'GetBkMode' GetBkMode gdi32 1596 +imp 'GetBoundsRect' GetBoundsRect gdi32 1597 +imp 'GetBrushAttributes' GetBrushAttributes gdi32 1598 +imp 'GetBrushOrgEx' GetBrushOrgEx gdi32 1599 +imp 'GetCIMSSM' GetCIMSSM user32 1800 +imp 'GetCOPPCompatibleOPMInformation' GetCOPPCompatibleOPMInformation gdi32 1600 +imp 'GetCPFileNameFromRegistry' GetCPFileNameFromRegistry KernelBase 429 +imp 'GetCPHashNode' GetCPHashNode KernelBase 430 +imp 'GetCPInfo' GetCPInfo KernelBase 431 +imp 'GetCPInfoExA' GetCPInfoExA kernel32 455 +imp 'GetCPInfoEx' GetCPInfoExW KernelBase 432 +imp 'GetCachedSigningLevel' GetCachedSigningLevel KernelBase 433 +imp 'GetCalendar' GetCalendar KernelBase 434 +imp 'GetCalendarDateFormat' GetCalendarDateFormat kernel32 458 +imp 'GetCalendarDateFormatEx' GetCalendarDateFormatEx kernel32 459 +imp 'GetCalendarDaysInMonth' GetCalendarDaysInMonth kernel32 460 +imp 'GetCalendarDifferenceInDays' GetCalendarDifferenceInDays kernel32 461 +imp 'GetCalendarInfoA' GetCalendarInfoA kernel32 462 +imp 'GetCalendarInfoEx' GetCalendarInfoEx KernelBase 435 +imp 'GetCalendarInfo' GetCalendarInfoW KernelBase 436 +imp 'GetCalendarMonthsInYear' GetCalendarMonthsInYear kernel32 465 +imp 'GetCalendarSupportedDateRange' GetCalendarSupportedDateRange kernel32 466 +imp 'GetCalendarWeekNumber' GetCalendarWeekNumber kernel32 467 +imp 'GetCapture' GetCapture user32 1801 +imp 'GetCaretBlinkTime' GetCaretBlinkTime user32 1802 +imp 'GetCaretPos' GetCaretPos user32 1803 +imp 'GetCertificate' GetCertificate gdi32 1601 +imp 'GetCertificateByHandle' GetCertificateByHandle gdi32 1602 +imp 'GetCertificateSize' GetCertificateSize gdi32 1603 +imp 'GetCertificateSizeByHandle' GetCertificateSizeByHandle gdi32 1604 +imp 'GetCharABCWidthsA' GetCharABCWidthsA gdi32 1605 +imp 'GetCharABCWidthsFloatA' GetCharABCWidthsFloatA gdi32 1606 +imp 'GetCharABCWidthsFloatI' GetCharABCWidthsFloatI gdi32 1607 +imp 'GetCharABCWidthsFloat' GetCharABCWidthsFloatW gdi32 1608 +imp 'GetCharABCWidthsI' GetCharABCWidthsI gdi32 1609 +imp 'GetCharABCWidths' GetCharABCWidthsW gdi32 1610 +imp 'GetCharWidth32A' GetCharWidth32A gdi32 1611 +imp 'GetCharWidth32W' GetCharWidth32W gdi32 1612 +imp 'GetCharWidthA' GetCharWidthA gdi32 1613 +imp 'GetCharWidthFloatA' GetCharWidthFloatA gdi32 1614 +imp 'GetCharWidthFloat' GetCharWidthFloatW gdi32 1615 +imp 'GetCharWidthI' GetCharWidthI gdi32 1616 +imp 'GetCharWidthInfo' GetCharWidthInfo gdi32 1617 +imp 'GetCharWidth' GetCharWidthW gdi32 1618 +imp 'GetCharacterPlacementA' GetCharacterPlacementA gdi32 1619 +imp 'GetCharacterPlacement' GetCharacterPlacementW gdi32 1620 +imp 'GetClassInfoA' GetClassInfoA user32 1804 +imp 'GetClassInfoExA' GetClassInfoExA user32 1805 +imp 'GetClassInfoEx' GetClassInfoExW user32 1806 +imp 'GetClassInfo' GetClassInfoW user32 1807 +imp 'GetClassLongA' GetClassLongA user32 1808 +imp 'GetClassLongPtrA' GetClassLongPtrA user32 1809 +imp 'GetClassLongPtr' GetClassLongPtrW user32 1810 +imp 'GetClassLong' GetClassLongW user32 1811 +imp 'GetClassNameA' GetClassNameA user32 1812 +imp 'GetClassName' GetClassNameW user32 1813 +imp 'GetClassWord' GetClassWord user32 1814 +imp 'GetClientRect' GetClientRect user32 1815 2 +imp 'GetClipBox' GetClipBox gdi32 1621 +imp 'GetClipCursor' GetClipCursor user32 1816 +imp 'GetClipRgn' GetClipRgn gdi32 1622 +imp 'GetClipboardAccessToken' GetClipboardAccessToken user32 1817 +imp 'GetClipboardData' GetClipboardData user32 1818 +imp 'GetClipboardFormatNameA' GetClipboardFormatNameA user32 1819 +imp 'GetClipboardFormatName' GetClipboardFormatNameW user32 1820 +imp 'GetClipboardOwner' GetClipboardOwner user32 1821 +imp 'GetClipboardSequenceNumber' GetClipboardSequenceNumber user32 1822 +imp 'GetClipboardViewer' GetClipboardViewer user32 1823 +imp 'GetColorAdjustment' GetColorAdjustment gdi32 1623 +imp 'GetColorSpace' GetColorSpace gdi32 1624 +imp 'GetComPlusPackageInstallStatus' GetComPlusPackageInstallStatus kernel32 468 +imp 'GetComboBoxInfo' GetComboBoxInfo user32 1824 +imp 'GetCommConfig' GetCommConfig KernelBase 437 +imp 'GetCommMask' GetCommMask KernelBase 438 +imp 'GetCommModemStatus' GetCommModemStatus KernelBase 439 +imp 'GetCommPorts' GetCommPorts KernelBase 440 +imp 'GetCommProperties' GetCommProperties KernelBase 441 +imp 'GetCommState' GetCommState KernelBase 442 +imp 'GetCommTimeouts' GetCommTimeouts KernelBase 443 +imp 'GetCommandLine' GetCommandLineW KernelBase 445 0 +imp 'GetCommandLineA' GetCommandLineA KernelBase 444 0 +imp 'GetCompressedFileSize' GetCompressedFileSizeW KernelBase 447 2 +imp 'GetCompressedFileSizeA' GetCompressedFileSizeA KernelBase 446 2 +imp 'GetCompressedFileSizeTransactedA' GetCompressedFileSizeTransactedA kernel32 478 +imp 'GetCompressedFileSizeTransacted' GetCompressedFileSizeTransactedW kernel32 479 +imp 'GetComputerNameA' GetComputerNameA kernel32 481 +imp 'GetComputerNameExA' GetComputerNameExA KernelBase 448 +imp 'GetComputerNameEx' GetComputerNameExW KernelBase 449 +imp 'GetComputerName' GetComputerNameW kernel32 484 +imp 'GetConsoleAliasA' GetConsoleAliasA KernelBase 450 +imp 'GetConsoleAliasExesA' GetConsoleAliasExesA KernelBase 451 +imp 'GetConsoleAliasExesLengthA' GetConsoleAliasExesLengthA KernelBase 452 +imp 'GetConsoleAliasExesLength' GetConsoleAliasExesLengthW KernelBase 453 +imp 'GetConsoleAliasExes' GetConsoleAliasExesW KernelBase 454 +imp 'GetConsoleAlias' GetConsoleAliasW KernelBase 455 +imp 'GetConsoleAliasesA' GetConsoleAliasesA KernelBase 456 +imp 'GetConsoleAliasesLengthA' GetConsoleAliasesLengthA KernelBase 457 +imp 'GetConsoleAliasesLength' GetConsoleAliasesLengthW KernelBase 458 +imp 'GetConsoleAliases' GetConsoleAliasesW KernelBase 459 +imp 'GetConsoleCP' GetConsoleCP KernelBase 460 0 +imp 'GetConsoleCharType' GetConsoleCharType kernel32 496 +imp 'GetConsoleCommandHistoryA' GetConsoleCommandHistoryA KernelBase 461 +imp 'GetConsoleCommandHistoryLengthA' GetConsoleCommandHistoryLengthA KernelBase 462 +imp 'GetConsoleCommandHistoryLength' GetConsoleCommandHistoryLengthW KernelBase 463 +imp 'GetConsoleCommandHistory' GetConsoleCommandHistoryW KernelBase 464 +imp 'GetConsoleCursorInfo' GetConsoleCursorInfo KernelBase 465 2 +imp 'GetConsoleCursorMode' GetConsoleCursorMode kernel32 502 +imp 'GetConsoleDisplayMode' GetConsoleDisplayMode KernelBase 466 +imp 'GetConsoleFontInfo' GetConsoleFontInfo kernel32 504 +imp 'GetConsoleFontSize' GetConsoleFontSize KernelBase 467 +imp 'GetConsoleHardwareState' GetConsoleHardwareState kernel32 506 +imp 'GetConsoleHistoryInfo' GetConsoleHistoryInfo KernelBase 468 +imp 'GetConsoleInputExeNameA' GetConsoleInputExeNameA KernelBase 469 +imp 'GetConsoleInputExeName' GetConsoleInputExeNameW KernelBase 470 +imp 'GetConsoleInputWaitHandle' GetConsoleInputWaitHandle kernel32 510 +imp 'GetConsoleKeyboardLayoutNameA' GetConsoleKeyboardLayoutNameA kernel32 511 +imp 'GetConsoleKeyboardLayoutName' GetConsoleKeyboardLayoutNameW kernel32 512 +imp 'GetConsoleMode' GetConsoleMode KernelBase 471 2 +imp 'GetConsoleNlsMode' GetConsoleNlsMode kernel32 514 +imp 'GetConsoleOriginalTitleA' GetConsoleOriginalTitleA KernelBase 472 +imp 'GetConsoleOriginalTitle' GetConsoleOriginalTitleW KernelBase 473 +imp 'GetConsoleOutputCP' GetConsoleOutputCP KernelBase 474 0 +imp 'GetConsoleProcessList' GetConsoleProcessList KernelBase 475 +imp 'GetConsoleScreenBufferInfo' GetConsoleScreenBufferInfo KernelBase 476 2 +imp 'GetConsoleScreenBufferInfoEx' GetConsoleScreenBufferInfoEx KernelBase 477 2 +imp 'GetConsoleSelectionInfo' GetConsoleSelectionInfo KernelBase 478 1 +imp 'GetConsoleTitleA' GetConsoleTitleA KernelBase 479 2 +imp 'GetConsoleTitle' GetConsoleTitleW KernelBase 480 +imp 'GetConsoleWindow' GetConsoleWindow KernelBase 481 0 +imp 'GetCurrencyFormatA' GetCurrencyFormatA kernel32 525 +imp 'GetCurrencyFormatEx' GetCurrencyFormatEx KernelBase 482 +imp 'GetCurrencyFormat' GetCurrencyFormatW KernelBase 483 +imp 'GetCurrentActCtx' GetCurrentActCtx KernelBase 484 +imp 'GetCurrentActCtxWorker' GetCurrentActCtxWorker kernel32 529 +imp 'GetCurrentApplicationUserModelId' GetCurrentApplicationUserModelId KernelBase 485 +imp 'GetCurrentConsoleFont' GetCurrentConsoleFont KernelBase 486 +imp 'GetCurrentConsoleFontEx' GetCurrentConsoleFontEx KernelBase 487 +imp 'GetCurrentDirectory' GetCurrentDirectoryW KernelBase 489 2 +imp 'GetCurrentDirectoryA' GetCurrentDirectoryA KernelBase 488 2 +imp 'GetCurrentDpiInfo' GetCurrentDpiInfo gdi32 1625 +imp 'GetCurrentHwProfileA' GetCurrentHwProfileA advapi32 1317 +imp 'GetCurrentHwProfile' GetCurrentHwProfileW advapi32 1318 +imp 'GetCurrentInputMessageSource' GetCurrentInputMessageSource user32 1825 +imp 'GetCurrentObject' GetCurrentObject gdi32 1626 +imp 'GetCurrentPackageApplicationContext' GetCurrentPackageApplicationContext KernelBase 490 +imp 'GetCurrentPackageApplicationResourcesContext' GetCurrentPackageApplicationResourcesContext KernelBase 491 +imp 'GetCurrentPackageContext' GetCurrentPackageContext KernelBase 492 +imp 'GetCurrentPackageFamilyName' GetCurrentPackageFamilyName KernelBase 493 +imp 'GetCurrentPackageFullName' GetCurrentPackageFullName KernelBase 494 +imp 'GetCurrentPackageId' GetCurrentPackageId KernelBase 495 +imp 'GetCurrentPackageInfo' GetCurrentPackageInfo KernelBase 496 +imp 'GetCurrentPackagePath' GetCurrentPackagePath KernelBase 497 +imp 'GetCurrentPackageResourcesContext' GetCurrentPackageResourcesContext KernelBase 498 +imp 'GetCurrentPackageSecurityContext' GetCurrentPackageSecurityContext KernelBase 499 +imp 'GetCurrentPositionEx' GetCurrentPositionEx gdi32 1627 +imp 'GetCurrentProcess' GetCurrentProcess KernelBase 500 0 +imp 'GetCurrentProcessExplicitAppUserModelID' GetCurrentProcessExplicitAppUserModelID shell32 305 +imp 'GetCurrentProcessId' GetCurrentProcessId KernelBase 501 0 +imp 'GetCurrentTargetPlatformContext' GetCurrentTargetPlatformContext KernelBase 504 +imp 'GetCurrentThread' GetCurrentThread KernelBase 505 0 +imp 'GetCurrentThreadId' GetCurrentThreadId KernelBase 506 0 +imp 'GetCurrentThreadStackLimits' GetCurrentThreadStackLimits KernelBase 507 +imp 'GetCurrentUmsThread' GetCurrentUmsThread kernel32 547 +imp 'GetCursor' GetCursor user32 1826 +imp 'GetCursorFrameInfo' GetCursorFrameInfo user32 1827 +imp 'GetCursorInfo' GetCursorInfo user32 1828 +imp 'GetCursorPos' GetCursorPos user32 1829 1 +imp 'GetDC' GetDC user32 1830 +imp 'GetDCBrushColor' GetDCBrushColor gdi32 1628 +imp 'GetDCDpiScaleValue' GetDCDpiScaleValue gdi32 1629 +imp 'GetDCEx' GetDCEx user32 1831 +imp 'GetDCOrgEx' GetDCOrgEx gdi32 1630 +imp 'GetDCPenColor' GetDCPenColor gdi32 1631 +imp 'GetDIBColorTable' GetDIBColorTable gdi32 1632 +imp 'GetDIBits' GetDIBits gdi32 1633 +imp 'GetDateFormatA' GetDateFormatA KernelBase 508 +imp 'GetDateFormatAWorker' GetDateFormatAWorker kernel32 549 +imp 'GetDateFormatEx' GetDateFormatEx KernelBase 509 +imp 'GetDateFormat' GetDateFormatW KernelBase 510 +imp 'GetDateFormatWWorker' GetDateFormatWWorker kernel32 552 +imp 'GetDefaultCommConfigA' GetDefaultCommConfigA kernel32 553 +imp 'GetDefaultCommConfig' GetDefaultCommConfigW kernel32 554 +imp 'GetDesktopID' GetDesktopID user32 1832 +imp 'GetDesktopWindow' GetDesktopWindow user32 1833 0 +imp 'GetDeviceCaps' GetDeviceCaps gdi32 1634 +imp 'GetDeviceDriverBaseNameA' GetDeviceDriverBaseNameA KernelBase 511 +imp 'GetDeviceDriverBaseName' GetDeviceDriverBaseNameW KernelBase 512 +imp 'GetDeviceDriverFileNameA' GetDeviceDriverFileNameA KernelBase 513 +imp 'GetDeviceDriverFileName' GetDeviceDriverFileNameW KernelBase 514 +imp 'GetDeviceGammaRamp' GetDeviceGammaRamp gdi32 1635 +imp 'GetDevicePowerState' GetDevicePowerState kernel32 555 +imp 'GetDialogBaseUnits' GetDialogBaseUnits user32 1834 +imp 'GetDialogControlDpiChangeBehavior' GetDialogControlDpiChangeBehavior user32 1835 +imp 'GetDialogDpiChangeBehavior' GetDialogDpiChangeBehavior user32 1836 +imp 'GetDiskFreeSpaceA' GetDiskFreeSpaceA KernelBase 515 +imp 'GetDiskFreeSpaceExA' GetDiskFreeSpaceExA KernelBase 516 +imp 'GetDiskFreeSpaceEx' GetDiskFreeSpaceExW KernelBase 517 +imp 'GetDiskFreeSpace' GetDiskFreeSpaceW KernelBase 518 +imp 'GetDisplayAutoRotationPreferences' GetDisplayAutoRotationPreferences user32 1837 +imp 'GetDisplayConfigBufferSizes' GetDisplayConfigBufferSizes user32 1838 +imp 'GetDlgCtrlID' GetDlgCtrlID user32 1839 +imp 'GetDlgItem' GetDlgItem user32 1840 +imp 'GetDlgItemInt' GetDlgItemInt user32 1841 +imp 'GetDlgItemTextA' GetDlgItemTextA user32 1842 +imp 'GetDlgItemText' GetDlgItemTextW user32 1843 +imp 'GetDllDirectoryA' GetDllDirectoryA kernel32 560 +imp 'GetDllDirectory' GetDllDirectoryW kernel32 561 +imp 'GetDoubleClickTime' GetDoubleClickTime user32 1844 +imp 'GetDpiForMonitorInternal' GetDpiForMonitorInternal user32 1845 +imp 'GetDpiForSystem' GetDpiForSystem user32 1846 +imp 'GetDpiForWindow' GetDpiForWindow user32 1847 +imp 'GetDpiFromDpiAwarenessContext' GetDpiFromDpiAwarenessContext user32 1848 +imp 'GetDriveTypeA' GetDriveTypeA KernelBase 519 +imp 'GetDriveType' GetDriveTypeW KernelBase 520 +imp 'GetDurationFormat' GetDurationFormat kernel32 564 +imp 'GetDurationFormatEx' GetDurationFormatEx KernelBase 521 +imp 'GetDynamicTimeZoneInformation' GetDynamicTimeZoneInformation KernelBase 522 +imp 'GetDynamicTimeZoneInformationEffectiveYears' GetDynamicTimeZoneInformationEffectiveYears KernelBase 523 +imp 'GetETM' GetETM gdi32 1636 +imp 'GetEUDCTimeStamp' GetEUDCTimeStamp gdi32 1637 +imp 'GetEUDCTimeStampEx' GetEUDCTimeStampExW gdi32 1638 +imp 'GetEffectivePackageStatusForUser' GetEffectivePackageStatusForUser KernelBase 524 +imp 'GetEffectivePackageStatusForUserSid' GetEffectivePackageStatusForUserSid KernelBase 525 +imp 'GetEffectiveRightsFromAclA' GetEffectiveRightsFromAclA advapi32 1320 +imp 'GetEffectiveRightsFromAcl' GetEffectiveRightsFromAclW advapi32 1321 +imp 'GetEightBitStringToUnicodeSizeRoutine' GetEightBitStringToUnicodeSizeRoutine KernelBase 526 +imp 'GetEightBitStringToUnicodeStringRoutine' GetEightBitStringToUnicodeStringRoutine KernelBase 527 +imp 'GetEnabledXStateFeatures' GetEnabledXStateFeatures KernelBase 528 +imp 'GetEncryptedFileMetadata' GetEncryptedFileMetadata advapi32 1322 +imp 'GetEncryptedFileVersionExt' GetEncryptedFileVersionExt kernel32 568 +imp 'GetEnhMetaFileA' GetEnhMetaFileA gdi32 1639 +imp 'GetEnhMetaFileBits' GetEnhMetaFileBits gdi32 1640 +imp 'GetEnhMetaFileDescriptionA' GetEnhMetaFileDescriptionA gdi32 1641 +imp 'GetEnhMetaFileDescription' GetEnhMetaFileDescriptionW gdi32 1642 +imp 'GetEnhMetaFileHeader' GetEnhMetaFileHeader gdi32 1643 +imp 'GetEnhMetaFilePaletteEntries' GetEnhMetaFilePaletteEntries gdi32 1644 +imp 'GetEnhMetaFilePixelFormat' GetEnhMetaFilePixelFormat gdi32 1645 +imp 'GetEnhMetaFile' GetEnhMetaFileW gdi32 1646 +imp 'GetEnvironmentStrings' GetEnvironmentStringsW KernelBase 531 1 +imp 'GetEnvironmentStringsA' GetEnvironmentStringsA KernelBase 530 1 +imp 'GetEnvironmentVariable' GetEnvironmentVariableW KernelBase 533 3 +imp 'GetEnvironmentVariableA' GetEnvironmentVariableA KernelBase 532 3 +imp 'GetEraNameCountedString' GetEraNameCountedString KernelBase 534 +imp 'GetErrorMode' GetErrorMode KernelBase 535 +imp 'GetEventLogInformation' GetEventLogInformation advapi32 1323 +imp 'GetExitCodeProcess' GetExitCodeProcess KernelBase 536 2 +imp 'GetExitCodeThread' GetExitCodeThread KernelBase 537 2 +imp 'GetExpandedNameA' GetExpandedNameA kernel32 578 +imp 'GetExpandedName' GetExpandedNameW kernel32 579 +imp 'GetExplicitEntriesFromAclA' GetExplicitEntriesFromAclA advapi32 1324 +imp 'GetExplicitEntriesFromAcl' GetExplicitEntriesFromAclW advapi32 1325 +imp 'GetExtensionApplicationUserModelId' GetExtensionApplicationUserModelId KernelBase 538 +imp 'GetExtensionProgIds' GetExtensionProgIds KernelBase 539 +imp 'GetExtensionProperty' GetExtensionProperty KernelBase 540 +imp 'GetExtensionProperty2' GetExtensionProperty2 KernelBase 541 +imp 'GetFallbackDisplayName' GetFallbackDisplayName KernelBase 542 +imp 'GetFileAttributesA' GetFileAttributesA KernelBase 543 1 +imp 'GetFileAttributes' GetFileAttributesW KernelBase 546 1 +imp 'GetFileAttributesExA' GetFileAttributesExA KernelBase 544 3 +imp 'GetFileAttributesEx' GetFileAttributesExW KernelBase 545 3 +imp 'GetFileAttributesTransactedA' GetFileAttributesTransactedA kernel32 583 +imp 'GetFileAttributesTransacted' GetFileAttributesTransactedW kernel32 584 +imp 'GetFileBandwidthReservation' GetFileBandwidthReservation kernel32 586 +imp 'GetFileInformationByHandle' GetFileInformationByHandle KernelBase 547 2 +imp 'GetFileInformationByHandleEx' GetFileInformationByHandleEx KernelBase 548 4 +imp 'GetFileMUIInfo' GetFileMUIInfo KernelBase 549 +imp 'GetFileMUIPath' GetFileMUIPath KernelBase 550 +imp 'GetFileNameFromBrowse' GetFileNameFromBrowse shell32 63 +imp 'GetFileSecurity' GetFileSecurityW KernelBase 551 5 +imp 'GetFileSecurityA' GetFileSecurityA advapi32 1326 5 +imp 'GetFileSize$nopenopenope' GetFileSize KernelBase 552 +imp 'GetFileSizeEx$nopenopenope' GetFileSizeEx KernelBase 553 +imp 'GetFileTime' GetFileTime KernelBase 554 4 +imp 'GetFileTitleA' GetFileTitleA comdlg32 111 +imp 'GetFileTitle' GetFileTitleW comdlg32 112 +imp 'GetFileType' GetFileType KernelBase 555 1 +imp 'GetFileVersionInfoA' GetFileVersionInfoA KernelBase 556 +imp 'GetFileVersionInfoByHandle' GetFileVersionInfoByHandle KernelBase 557 +imp 'GetFileVersionInfoExA' GetFileVersionInfoExA KernelBase 558 +imp 'GetFileVersionInfoEx' GetFileVersionInfoExW KernelBase 559 +imp 'GetFileVersionInfoSizeA' GetFileVersionInfoSizeA KernelBase 560 +imp 'GetFileVersionInfoSizeExA' GetFileVersionInfoSizeExA KernelBase 561 +imp 'GetFileVersionInfoSizeEx' GetFileVersionInfoSizeExW KernelBase 562 +imp 'GetFileVersionInfoSize' GetFileVersionInfoSizeW KernelBase 563 +imp 'GetFileVersionInfo' GetFileVersionInfoW KernelBase 564 +imp 'GetFinalPathNameByHandleA' GetFinalPathNameByHandleA KernelBase 565 +imp 'GetFinalPathNameByHandle' GetFinalPathNameByHandleW KernelBase 566 +imp 'GetFirmwareEnvironmentVariableA' GetFirmwareEnvironmentVariableA kernel32 597 +imp 'GetFirmwareEnvironmentVariableExA' GetFirmwareEnvironmentVariableExA kernel32 598 +imp 'GetFirmwareEnvironmentVariableEx' GetFirmwareEnvironmentVariableExW kernel32 599 +imp 'GetFirmwareEnvironmentVariable' GetFirmwareEnvironmentVariableW kernel32 600 +imp 'GetFirmwareType' GetFirmwareType kernel32 601 +imp 'GetFocus' GetFocus user32 1849 +imp 'GetFontAssocStatus' GetFontAssocStatus gdi32 1647 +imp 'GetFontData' GetFontData gdi32 1648 +imp 'GetFontFileData' GetFontFileData gdi32 1649 +imp 'GetFontFileInfo' GetFontFileInfo gdi32 1650 +imp 'GetFontLanguageInfo' GetFontLanguageInfo gdi32 1651 +imp 'GetFontRealizationInfo' GetFontRealizationInfo gdi32 1652 +imp 'GetFontResourceInfo' GetFontResourceInfoW gdi32 1653 +imp 'GetFontUnicodeRanges' GetFontUnicodeRanges gdi32 1654 +imp 'GetForegroundWindow' GetForegroundWindow user32 1850 +imp 'GetFullPathNameA' GetFullPathNameA KernelBase 567 +imp 'GetFullPathNameTransactedA' GetFullPathNameTransactedA kernel32 603 +imp 'GetFullPathNameTransacted' GetFullPathNameTransactedW kernel32 604 +imp 'GetFullPathName' GetFullPathNameW KernelBase 568 +imp 'GetGPOListInternalA' GetGPOListInternalA KernelBase 569 +imp 'GetGPOListInternal' GetGPOListInternalW KernelBase 570 +imp 'GetGUIThreadInfo' GetGUIThreadInfo user32 1851 +imp 'GetGamingDeviceModelInformation' GetGamingDeviceModelInformation KernelBase 571 +imp 'GetGeoInfoA' GetGeoInfoA kernel32 606 +imp 'GetGeoInfoEx' GetGeoInfoEx KernelBase 572 +imp 'GetGeoInfo' GetGeoInfoW KernelBase 573 +imp 'GetGestureConfig' GetGestureConfig user32 1852 +imp 'GetGestureExtraArgs' GetGestureExtraArgs user32 1853 +imp 'GetGestureInfo' GetGestureInfo user32 1854 +imp 'GetGlyphIndicesA' GetGlyphIndicesA gdi32 1655 +imp 'GetGlyphIndices' GetGlyphIndicesW gdi32 1656 +imp 'GetGlyphOutlineA' GetGlyphOutlineA gdi32 1658 +imp 'GetGlyphOutline' GetGlyphOutlineW gdi32 1659 +imp 'GetGlyphOutlineWow' GetGlyphOutlineWow gdi32 1660 +imp 'GetGraphicsMode' GetGraphicsMode gdi32 1661 +imp 'GetGuiResources' GetGuiResources user32 1855 +imp 'GetHFONT' GetHFONT gdi32 1662 +imp 'GetHandleInformation' GetHandleInformation KernelBase 574 2 +imp 'GetHivePath' GetHivePath KernelBase 575 +imp 'GetHostName' GetHostNameW ws2_32 33 +imp 'GetICMProfileA' GetICMProfileA gdi32 1663 +imp 'GetICMProfile' GetICMProfileW gdi32 1664 +imp 'GetIconInfo' GetIconInfo user32 1856 +imp 'GetIconInfoExA' GetIconInfoExA user32 1857 +imp 'GetIconInfoEx' GetIconInfoExW user32 1858 +imp 'GetInformationCodeAuthzLevel' GetInformationCodeAuthzLevelW advapi32 1328 +imp 'GetInformationCodeAuthzPolicy' GetInformationCodeAuthzPolicyW advapi32 1329 +imp 'GetInheritanceSourceA' GetInheritanceSourceA advapi32 1330 +imp 'GetInheritanceSource' GetInheritanceSourceW advapi32 1331 +imp 'GetInputDesktop' GetInputDesktop user32 1859 +imp 'GetInputLocaleInfo' GetInputLocaleInfo user32 1860 +imp 'GetInputState' GetInputState user32 1861 +imp 'GetIntegratedDisplaySize' GetIntegratedDisplaySize KernelBase 576 +imp 'GetInternalWindowPos' GetInternalWindowPos user32 1862 +imp 'GetIsEdpEnabled' GetIsEdpEnabled KernelBase 577 +imp 'GetKBCodePage' GetKBCodePage user32 1863 +imp 'GetKernelObjectSecurity' GetKernelObjectSecurity KernelBase 578 +imp 'GetKerningPairsA' GetKerningPairsA gdi32 1666 +imp 'GetKerningPairs' GetKerningPairsW gdi32 1667 +imp 'GetKeyNameTextA' GetKeyNameTextA user32 1864 +imp 'GetKeyNameText' GetKeyNameTextW user32 1865 +imp 'GetKeyState' GetKeyState user32 1866 +imp 'GetKeyboardLayout' GetKeyboardLayout user32 1867 +imp 'GetKeyboardLayoutList' GetKeyboardLayoutList user32 1868 +imp 'GetKeyboardLayoutNameA' GetKeyboardLayoutNameA user32 1869 +imp 'GetKeyboardLayoutName' GetKeyboardLayoutNameW user32 1870 +imp 'GetKeyboardState' GetKeyboardState user32 1871 +imp 'GetKeyboardType' GetKeyboardType user32 1872 +imp 'GetLargePageMinimum' GetLargePageMinimum KernelBase 579 +imp 'GetLargestConsoleWindowSize' GetLargestConsoleWindowSize KernelBase 580 1 +imp 'GetLastActivePopup' GetLastActivePopup user32 1873 +imp 'GetLastError' GetLastError KernelBase 581 0 +imp 'GetLastInputInfo' GetLastInputInfo user32 1874 +imp 'GetLayeredWindowAttributes' GetLayeredWindowAttributes user32 1875 +imp 'GetLayout' GetLayout gdi32 1668 +imp 'GetLengthSid' GetLengthSid KernelBase 582 +imp 'GetListBoxInfo' GetListBoxInfo user32 1876 +imp 'GetLocalManagedApplicationData' GetLocalManagedApplicationData advapi32 1334 +imp 'GetLocalManagedApplications' GetLocalManagedApplications advapi32 1335 +imp 'GetLocalTime' GetLocalTime KernelBase 583 +imp 'GetLocaleInfoA' GetLocaleInfoA KernelBase 584 +imp 'GetLocaleInfoEx' GetLocaleInfoEx KernelBase 585 +imp 'GetLocaleInfoHelper' GetLocaleInfoHelper KernelBase 586 +imp 'GetLocaleInfo' GetLocaleInfoW KernelBase 587 +imp 'GetLogColorSpaceA' GetLogColorSpaceA gdi32 1669 +imp 'GetLogColorSpace' GetLogColorSpaceW gdi32 1670 +imp 'GetLogicalDriveStringsA' GetLogicalDriveStringsA kernel32 617 +imp 'GetLogicalDriveStrings' GetLogicalDriveStringsW KernelBase 588 +imp 'GetLogicalDrives' GetLogicalDrives KernelBase 589 0 +imp 'GetLogicalProcessorInformation' GetLogicalProcessorInformation KernelBase 590 +imp 'GetLogicalProcessorInformationEx' GetLogicalProcessorInformationEx KernelBase 591 +imp 'GetLongPathNameA' GetLongPathNameA KernelBase 592 +imp 'GetLongPathNameTransactedA' GetLongPathNameTransactedA kernel32 623 +imp 'GetLongPathNameTransacted' GetLongPathNameTransactedW kernel32 624 +imp 'GetLongPathName' GetLongPathNameW KernelBase 593 +imp 'GetMagnificationDesktopColorEffect' GetMagnificationDesktopColorEffect user32 1877 +imp 'GetMagnificationDesktopMagnification' GetMagnificationDesktopMagnification user32 1878 +imp 'GetMagnificationDesktopSamplingMode' GetMagnificationDesktopSamplingMode user32 1879 +imp 'GetMagnificationLensCtxInformation' GetMagnificationLensCtxInformation user32 1880 +imp 'GetMailslotInfo' GetMailslotInfo kernel32 626 +imp 'GetManagedApplicationCategories' GetManagedApplicationCategories advapi32 1336 +imp 'GetManagedApplications' GetManagedApplications advapi32 1337 +imp 'GetMapMode' GetMapMode gdi32 1671 +imp 'GetMappedFileNameA' GetMappedFileNameA KernelBase 594 +imp 'GetMappedFileName' GetMappedFileNameW KernelBase 595 +imp 'GetMaximumProcessorCount' GetMaximumProcessorCount kernel32 627 +imp 'GetMaximumProcessorGroupCount' GetMaximumProcessorGroupCount kernel32 628 +imp 'GetMemoryErrorHandlingCapabilities' GetMemoryErrorHandlingCapabilities KernelBase 596 +imp 'GetMenu' GetMenu user32 1881 +imp 'GetMenuBarInfo' GetMenuBarInfo user32 1882 +imp 'GetMenuCheckMarkDimensions' GetMenuCheckMarkDimensions user32 1883 +imp 'GetMenuContextHelpId' GetMenuContextHelpId user32 1884 +imp 'GetMenuDefaultItem' GetMenuDefaultItem user32 1885 +imp 'GetMenuInfo' GetMenuInfo user32 1886 +imp 'GetMenuItemCount' GetMenuItemCount user32 1887 +imp 'GetMenuItemID' GetMenuItemID user32 1888 +imp 'GetMenuItemInfoA' GetMenuItemInfoA user32 1889 +imp 'GetMenuItemInfo' GetMenuItemInfoW user32 1890 +imp 'GetMenuItemRect' GetMenuItemRect user32 1891 +imp 'GetMenuState' GetMenuState user32 1892 +imp 'GetMenuStringA' GetMenuStringA user32 1893 +imp 'GetMenuString' GetMenuStringW user32 1894 +imp 'GetMessage' GetMessageW user32 1899 4 +imp 'GetMessageA' GetMessageA user32 1895 4 +imp 'GetMessageExtraInfo' GetMessageExtraInfo user32 1896 +imp 'GetMessagePos' GetMessagePos user32 1897 +imp 'GetMessageTime' GetMessageTime user32 1898 +imp 'GetMetaFileA' GetMetaFileA gdi32 1672 +imp 'GetMetaFileBitsEx' GetMetaFileBitsEx gdi32 1673 +imp 'GetMetaFile' GetMetaFileW gdi32 1674 +imp 'GetMetaRgn' GetMetaRgn gdi32 1675 +imp 'GetMiterLimit' GetMiterLimit gdi32 1676 +imp 'GetModuleBaseNameA' GetModuleBaseNameA KernelBase 597 +imp 'GetModuleBaseName' GetModuleBaseNameW KernelBase 598 +imp 'GetModuleFileName' GetModuleFileNameW KernelBase 602 3 +imp 'GetModuleFileNameA' GetModuleFileNameA KernelBase 599 3 +imp 'GetModuleFileNameExA' GetModuleFileNameExA KernelBase 600 +imp 'GetModuleFileNameEx' GetModuleFileNameExW KernelBase 601 +imp 'GetModuleHandle' GetModuleHandleA KernelBase 603 1 +imp 'GetModuleHandleW' GetModuleHandleW KernelBase 606 1 +imp 'GetModuleHandleExA' GetModuleHandleExA KernelBase 604 +imp 'GetModuleHandleEx' GetModuleHandleExW KernelBase 605 +imp 'GetModuleInformation' GetModuleInformation KernelBase 607 +imp 'GetMonitorInfoA' GetMonitorInfoA user32 1900 +imp 'GetMonitorInfo' GetMonitorInfoW user32 1901 +imp 'GetMouseMovePointsEx' GetMouseMovePointsEx user32 1902 +imp 'GetMultipleTrusteeA' GetMultipleTrusteeA advapi32 1338 +imp 'GetMultipleTrusteeOperationA' GetMultipleTrusteeOperationA advapi32 1339 +imp 'GetMultipleTrusteeOperation' GetMultipleTrusteeOperationW advapi32 1340 +imp 'GetMultipleTrustee' GetMultipleTrusteeW advapi32 1341 +imp 'GetNLSVersion' GetNLSVersion KernelBase 608 +imp 'GetNLSVersionEx' GetNLSVersionEx KernelBase 609 +imp 'GetNameInfo' GetNameInfoW ws2_32 34 +imp 'GetNamedLocaleHashNode' GetNamedLocaleHashNode KernelBase 610 +imp 'GetNamedPipeAttribute' GetNamedPipeAttribute KernelBase 611 +imp 'GetNamedPipeClientComputerNameA' GetNamedPipeClientComputerNameA kernel32 639 +imp 'GetNamedPipeClientComputerName' GetNamedPipeClientComputerNameW KernelBase 612 +imp 'GetNamedPipeClientProcessId' GetNamedPipeClientProcessId kernel32 641 +imp 'GetNamedPipeClientSessionId' GetNamedPipeClientSessionId kernel32 642 +imp 'GetNamedPipeHandleStateA' GetNamedPipeHandleStateA kernel32 643 +imp 'GetNamedPipeHandleState' GetNamedPipeHandleStateW KernelBase 613 +imp 'GetNamedPipeInfo' GetNamedPipeInfo KernelBase 614 +imp 'GetNamedPipeServerProcessId' GetNamedPipeServerProcessId kernel32 646 +imp 'GetNamedPipeServerSessionId' GetNamedPipeServerSessionId kernel32 647 +imp 'GetNamedSecurityInfoA' GetNamedSecurityInfoA advapi32 1342 +imp 'GetNamedSecurityInfoExA' GetNamedSecurityInfoExA advapi32 1343 +imp 'GetNamedSecurityInfoEx' GetNamedSecurityInfoExW advapi32 1344 +imp 'GetNamedSecurityInfo' GetNamedSecurityInfoW advapi32 1345 +imp 'GetNativeSystemInfo' GetNativeSystemInfo KernelBase 615 +imp 'GetNearestColor' GetNearestColor gdi32 1677 +imp 'GetNearestPaletteIndex' GetNearestPaletteIndex gdi32 1678 +imp 'GetNextDlgGroupItem' GetNextDlgGroupItem user32 1903 +imp 'GetNextDlgTabItem' GetNextDlgTabItem user32 1904 +imp 'GetNextFgPolicyRefreshInfoInternal' GetNextFgPolicyRefreshInfoInternal KernelBase 616 +imp 'GetNextUmsListItem' GetNextUmsListItem kernel32 649 +imp 'GetNextVDMCommand' GetNextVDMCommand kernel32 650 +imp 'GetNumaAvailableMemoryNode' GetNumaAvailableMemoryNode kernel32 651 +imp 'GetNumaAvailableMemoryNodeEx' GetNumaAvailableMemoryNodeEx kernel32 652 +imp 'GetNumaHighestNodeNumber' GetNumaHighestNodeNumber KernelBase 617 +imp 'GetNumaNodeNumberFromHandle' GetNumaNodeNumberFromHandle kernel32 654 +imp 'GetNumaNodeProcessorMask' GetNumaNodeProcessorMask kernel32 655 +imp 'GetNumaNodeProcessorMaskEx' GetNumaNodeProcessorMaskEx KernelBase 618 +imp 'GetNumaProcessorNode' GetNumaProcessorNode kernel32 657 +imp 'GetNumaProcessorNodeEx' GetNumaProcessorNodeEx kernel32 658 +imp 'GetNumaProximityNode' GetNumaProximityNode kernel32 659 +imp 'GetNumaProximityNodeEx' GetNumaProximityNodeEx KernelBase 619 +imp 'GetNumberFormatA' GetNumberFormatA kernel32 661 +imp 'GetNumberFormatEx' GetNumberFormatEx KernelBase 620 +imp 'GetNumberFormat' GetNumberFormatW KernelBase 621 +imp 'GetNumberOfConsoleFonts' GetNumberOfConsoleFonts kernel32 664 +imp 'GetNumberOfConsoleInputEvents' GetNumberOfConsoleInputEvents KernelBase 622 2 +imp 'GetNumberOfConsoleMouseButtons' GetNumberOfConsoleMouseButtons KernelBase 623 1 +imp 'GetNumberOfEventLogRecords' GetNumberOfEventLogRecords advapi32 1346 +imp 'GetNumberOfPhysicalMonitors' GetNumberOfPhysicalMonitors gdi32 1679 +imp 'GetOEMCP' GetOEMCP KernelBase 624 +imp 'GetOPMInformation' GetOPMInformation gdi32 1680 +imp 'GetOPMRandomNumber' GetOPMRandomNumber gdi32 1681 +imp 'GetObjectA' GetObjectA gdi32 1682 +imp 'GetObjectType' GetObjectType gdi32 1683 +imp 'GetObject' GetObjectW gdi32 1684 +imp 'GetOldestEventLogRecord' GetOldestEventLogRecord advapi32 1347 +imp 'GetOpenClipboardWindow' GetOpenClipboardWindow user32 1905 +imp 'GetOpenFileNameA' GetOpenFileNameA comdlg32 113 +imp 'GetOpenFileName' GetOpenFileNameW comdlg32 114 +imp 'GetOsManufacturingMode' GetOsManufacturingMode KernelBase 625 +imp 'GetOsSafeBootMode' GetOsSafeBootMode KernelBase 626 +imp 'GetOutlineTextMetricsA' GetOutlineTextMetricsA gdi32 1685 +imp 'GetOutlineTextMetrics' GetOutlineTextMetricsW gdi32 1686 +imp 'GetOverlappedAccessResults' GetOverlappedAccessResults advapi32 1348 +imp 'GetOverlappedResult' GetOverlappedResult KernelBase 627 +imp 'GetOverlappedResultEx' GetOverlappedResultEx KernelBase 628 +imp 'GetPackageApplicationContext' GetPackageApplicationContext KernelBase 629 +imp 'GetPackageApplicationIds' GetPackageApplicationIds KernelBase 630 +imp 'GetPackageApplicationProperty' GetPackageApplicationProperty KernelBase 631 +imp 'GetPackageApplicationPropertyString' GetPackageApplicationPropertyString KernelBase 632 +imp 'GetPackageApplicationResourcesContext' GetPackageApplicationResourcesContext KernelBase 633 +imp 'GetPackageContext' GetPackageContext KernelBase 634 +imp 'GetPackageFamilyName' GetPackageFamilyName KernelBase 635 +imp 'GetPackageFamilyNameFromProgId' GetPackageFamilyNameFromProgId KernelBase 636 +imp 'GetPackageFamilyNameFromToken' GetPackageFamilyNameFromToken KernelBase 637 +imp 'GetPackageFullName' GetPackageFullName KernelBase 638 +imp 'GetPackageFullNameFromToken' GetPackageFullNameFromToken KernelBase 639 +imp 'GetPackageId' GetPackageId KernelBase 640 +imp 'GetPackageInfo' GetPackageInfo KernelBase 641 +imp 'GetPackageInstallTime' GetPackageInstallTime KernelBase 642 +imp 'GetPackageOSMaxVersionTested' GetPackageOSMaxVersionTested KernelBase 643 +imp 'GetPackagePath' GetPackagePath KernelBase 644 +imp 'GetPackagePathByFullName' GetPackagePathByFullName KernelBase 645 +imp 'GetPackagePathOnVolume' GetPackagePathOnVolume KernelBase 646 +imp 'GetPackageProperty' GetPackageProperty KernelBase 647 +imp 'GetPackagePropertyString' GetPackagePropertyString KernelBase 648 +imp 'GetPackageResourcesContext' GetPackageResourcesContext KernelBase 649 +imp 'GetPackageResourcesProperty' GetPackageResourcesProperty KernelBase 650 +imp 'GetPackageSecurityContext' GetPackageSecurityContext KernelBase 651 +imp 'GetPackageSecurityProperty' GetPackageSecurityProperty KernelBase 652 +imp 'GetPackageStatus' GetPackageStatus KernelBase 653 +imp 'GetPackageStatusForUser' GetPackageStatusForUser KernelBase 654 +imp 'GetPackageStatusForUserSid' GetPackageStatusForUserSid KernelBase 655 +imp 'GetPackageTargetPlatformProperty' GetPackageTargetPlatformProperty KernelBase 656 +imp 'GetPackageVolumeSisPath' GetPackageVolumeSisPath KernelBase 657 +imp 'GetPackagesByPackageFamily' GetPackagesByPackageFamily KernelBase 658 +imp 'GetPaletteEntries' GetPaletteEntries gdi32 1687 +imp 'GetParent' GetParent user32 1906 1 +imp 'GetPath' GetPath gdi32 1688 +imp 'GetPerformanceInfo' GetPerformanceInfo KernelBase 659 +imp 'GetPersistedFileLocation' GetPersistedFileLocationW KernelBase 660 +imp 'GetPersistedRegistryLocation' GetPersistedRegistryLocationW KernelBase 661 +imp 'GetPersistedRegistryValue' GetPersistedRegistryValueW KernelBase 662 +imp 'GetPhysicalCursorPos' GetPhysicalCursorPos user32 1907 +imp 'GetPhysicalMonitorDescription' GetPhysicalMonitorDescription gdi32 1689 +imp 'GetPhysicalMonitors' GetPhysicalMonitors gdi32 1690 +imp 'GetPhysicallyInstalledSystemMemory' GetPhysicallyInstalledSystemMemory KernelBase 663 +imp 'GetPixel' GetPixel gdi32 1691 +imp 'GetPixelFormat' GetPixelFormat gdi32 1692 +imp 'GetPointerCursorId' GetPointerCursorId user32 1908 +imp 'GetPointerDevice' GetPointerDevice user32 1909 +imp 'GetPointerDeviceCursors' GetPointerDeviceCursors user32 1910 +imp 'GetPointerDeviceProperties' GetPointerDeviceProperties user32 1911 +imp 'GetPointerDeviceRects' GetPointerDeviceRects user32 1912 +imp 'GetPointerDevices' GetPointerDevices user32 1913 +imp 'GetPointerFrameArrivalTimes' GetPointerFrameArrivalTimes user32 1914 +imp 'GetPointerFrameInfo' GetPointerFrameInfo user32 1915 +imp 'GetPointerFrameInfoHistory' GetPointerFrameInfoHistory user32 1916 +imp 'GetPointerFramePenInfo' GetPointerFramePenInfo user32 1917 +imp 'GetPointerFramePenInfoHistory' GetPointerFramePenInfoHistory user32 1918 +imp 'GetPointerFrameTouchInfo' GetPointerFrameTouchInfo user32 1919 +imp 'GetPointerFrameTouchInfoHistory' GetPointerFrameTouchInfoHistory user32 1920 +imp 'GetPointerInfo' GetPointerInfo user32 1921 +imp 'GetPointerInfoHistory' GetPointerInfoHistory user32 1922 +imp 'GetPointerInputTransform' GetPointerInputTransform user32 1923 +imp 'GetPointerPenInfo' GetPointerPenInfo user32 1924 +imp 'GetPointerPenInfoHistory' GetPointerPenInfoHistory user32 1925 +imp 'GetPointerTouchInfo' GetPointerTouchInfo user32 1926 +imp 'GetPointerTouchInfoHistory' GetPointerTouchInfoHistory user32 1927 +imp 'GetPointerType' GetPointerType user32 1928 +imp 'GetPolyFillMode' GetPolyFillMode gdi32 1693 +imp 'GetPreviousFgPolicyRefreshInfoInternal' GetPreviousFgPolicyRefreshInfoInternal KernelBase 664 +imp 'GetPriorityClass' GetPriorityClass KernelBase 665 1 +imp 'GetPriorityClipboardFormat' GetPriorityClipboardFormat user32 1929 +imp 'GetPrivateObjectSecurity' GetPrivateObjectSecurity KernelBase 666 +imp 'GetPrivateProfileIntA' GetPrivateProfileIntA kernel32 680 +imp 'GetPrivateProfileInt' GetPrivateProfileIntW kernel32 681 +imp 'GetPrivateProfileSectionA' GetPrivateProfileSectionA kernel32 682 +imp 'GetPrivateProfileSectionNamesA' GetPrivateProfileSectionNamesA kernel32 683 +imp 'GetPrivateProfileSectionNames' GetPrivateProfileSectionNamesW kernel32 684 +imp 'GetPrivateProfileSection' GetPrivateProfileSectionW kernel32 685 +imp 'GetPrivateProfileStringA' GetPrivateProfileStringA kernel32 686 +imp 'GetPrivateProfileString' GetPrivateProfileStringW kernel32 687 +imp 'GetPrivateProfileStructA' GetPrivateProfileStructA kernel32 688 +imp 'GetPrivateProfileStruct' GetPrivateProfileStructW kernel32 689 +imp 'GetProcAddress' GetProcAddress KernelBase 667 2 +imp 'GetProcAddressForCaller' GetProcAddressForCaller KernelBase 668 +imp 'GetProcessAffinityMask' GetProcessAffinityMask kernel32 691 3 +imp 'GetProcessDEPPolicy' GetProcessDEPPolicy kernel32 692 +imp 'GetProcessDefaultCpuSets' GetProcessDefaultCpuSets KernelBase 669 +imp 'GetProcessDefaultLayout' GetProcessDefaultLayout user32 1930 +imp 'GetProcessDpiAwarenessInternal' GetProcessDpiAwarenessInternal user32 1931 +imp 'GetProcessGroupAffinity' GetProcessGroupAffinity KernelBase 670 +imp 'GetProcessHandleCount' GetProcessHandleCount KernelBase 671 2 +imp 'GetProcessHeap' GetProcessHeap KernelBase 672 +imp 'GetProcessHeaps' GetProcessHeaps KernelBase 673 +imp 'GetProcessId' GetProcessId KernelBase 674 1 +imp 'GetProcessIdOfThread' GetProcessIdOfThread KernelBase 675 +imp 'GetProcessImageFileNameA' GetProcessImageFileNameA KernelBase 676 +imp 'GetProcessImageFileName' GetProcessImageFileNameW KernelBase 677 +imp 'GetProcessInformation' GetProcessInformation KernelBase 678 +imp 'GetProcessIoCounters' GetProcessIoCounters kernel32 701 2 +imp 'GetProcessMemoryInfo' GetProcessMemoryInfo KernelBase 679 +imp 'GetProcessMitigationPolicy' GetProcessMitigationPolicy KernelBase 680 +imp 'GetProcessPreferredUILanguages' GetProcessPreferredUILanguages KernelBase 681 +imp 'GetProcessPriorityBoost' GetProcessPriorityBoost KernelBase 682 2 +imp 'GetProcessSessionFonts' GetProcessSessionFonts gdi32 1694 +imp 'GetProcessShutdownParameters' GetProcessShutdownParameters KernelBase 683 +imp 'GetProcessTimes' GetProcessTimes KernelBase 684 5 +imp 'GetProcessUIContextInformation' GetProcessUIContextInformation user32 2521 +imp 'GetProcessVersion' GetProcessVersion KernelBase 685 +imp 'GetProcessWindowStation' GetProcessWindowStation user32 1932 +imp 'GetProcessWorkingSetSize' GetProcessWorkingSetSize kernel32 708 3 +imp 'GetProcessWorkingSetSizeEx' GetProcessWorkingSetSizeEx KernelBase 686 4 +imp 'GetProcessorSystemCycleTime' GetProcessorSystemCycleTime KernelBase 687 +imp 'GetProductInfo' GetProductInfo KernelBase 688 +imp 'GetProfileIntA' GetProfileIntA kernel32 712 +imp 'GetProfileInt' GetProfileIntW kernel32 713 +imp 'GetProfileSectionA' GetProfileSectionA kernel32 714 +imp 'GetProfileSection' GetProfileSectionW kernel32 715 +imp 'GetProfileStringA' GetProfileStringA kernel32 716 +imp 'GetProfileString' GetProfileStringW kernel32 717 +imp 'GetProgmanWindow' GetProgmanWindow user32 1933 +imp 'GetPropA' GetPropA user32 1934 +imp 'GetProp' GetPropW user32 1935 +imp 'GetProtocolAumid' GetProtocolAumid KernelBase 689 +imp 'GetProtocolProperty' GetProtocolProperty KernelBase 690 +imp 'GetPtrCalData' GetPtrCalData KernelBase 691 +imp 'GetPtrCalDataArray' GetPtrCalDataArray KernelBase 692 +imp 'GetPublisherCacheFolder' GetPublisherCacheFolder KernelBase 693 +imp 'GetPublisherRootFolder' GetPublisherRootFolder KernelBase 694 +imp 'GetQueueStatus' GetQueueStatus user32 1936 +imp 'GetQueuedCompletionStatus' GetQueuedCompletionStatus KernelBase 695 +imp 'GetQueuedCompletionStatusEx' GetQueuedCompletionStatusEx KernelBase 696 +imp 'GetROP2' GetROP2 gdi32 1695 +imp 'GetRandomRgn' GetRandomRgn gdi32 1696 +imp 'GetRasterizerCaps' GetRasterizerCaps gdi32 1697 +imp 'GetRawInputBuffer' GetRawInputBuffer user32 1937 +imp 'GetRawInputData' GetRawInputData user32 1938 +imp 'GetRawInputDeviceInfoA' GetRawInputDeviceInfoA user32 1939 +imp 'GetRawInputDeviceInfo' GetRawInputDeviceInfoW user32 1940 +imp 'GetRawInputDeviceList' GetRawInputDeviceList user32 1941 +imp 'GetRawPointerDeviceData' GetRawPointerDeviceData user32 1942 +imp 'GetReasonTitleFromReasonCode' GetReasonTitleFromReasonCode user32 1943 +imp 'GetRegionData' GetRegionData gdi32 1698 +imp 'GetRegisteredRawInputDevices' GetRegisteredRawInputDevices user32 1944 +imp 'GetRegistryExtensionFlags' GetRegistryExtensionFlags KernelBase 697 +imp 'GetRegistryValueWithFallback' GetRegistryValueWithFallbackW KernelBase 698 +imp 'GetRelAbs' GetRelAbs gdi32 1699 +imp 'GetRgnBox' GetRgnBox gdi32 1700 +imp 'GetRoamingLastObservedChangeTime' GetRoamingLastObservedChangeTime KernelBase 699 +imp 'GetSaveFileNameA' GetSaveFileNameA comdlg32 115 +imp 'GetSaveFileName' GetSaveFileNameW comdlg32 116 +imp 'GetScrollBarInfo' GetScrollBarInfo user32 1945 +imp 'GetScrollInfo' GetScrollInfo user32 1946 +imp 'GetScrollPos' GetScrollPos user32 1947 +imp 'GetScrollRange' GetScrollRange user32 1948 +imp 'GetSecureSystemAppDataFolder' GetSecureSystemAppDataFolder KernelBase 700 +imp 'GetSecurityDescriptorControl' GetSecurityDescriptorControl KernelBase 701 +imp 'GetSecurityDescriptorDacl' GetSecurityDescriptorDacl KernelBase 702 +imp 'GetSecurityDescriptorGroup' GetSecurityDescriptorGroup KernelBase 703 +imp 'GetSecurityDescriptorLength' GetSecurityDescriptorLength KernelBase 704 +imp 'GetSecurityDescriptorOwner' GetSecurityDescriptorOwner KernelBase 705 +imp 'GetSecurityDescriptorRMControl' GetSecurityDescriptorRMControl KernelBase 706 +imp 'GetSecurityDescriptorSacl' GetSecurityDescriptorSacl KernelBase 707 +imp 'GetSecurityInfo' GetSecurityInfo advapi32 1357 +imp 'GetSecurityInfoExA' GetSecurityInfoExA advapi32 1358 +imp 'GetSecurityInfoEx' GetSecurityInfoExW advapi32 1359 +imp 'GetSendMessageReceiver' GetSendMessageReceiver user32 1949 +imp 'GetSerializedAtomBytes' GetSerializedAtomBytes KernelBase 708 +imp 'GetServiceDisplayNameA' GetServiceDisplayNameA advapi32 1360 +imp 'GetServiceDisplayName' GetServiceDisplayNameW advapi32 1361 +imp 'GetServiceKeyNameA' GetServiceKeyNameA advapi32 1362 +imp 'GetServiceKeyName' GetServiceKeyNameW advapi32 1363 +imp 'GetSharedLocalFolder' GetSharedLocalFolder KernelBase 709 +imp 'GetShellWindow' GetShellWindow user32 1950 0 +imp 'GetShortPathNameA' GetShortPathNameA kernel32 720 +imp 'GetShortPathName' GetShortPathNameW KernelBase 710 +imp 'GetSidIdentifierAuthority' GetSidIdentifierAuthority KernelBase 711 +imp 'GetSidLengthRequired' GetSidLengthRequired KernelBase 712 +imp 'GetSidSubAuthority' GetSidSubAuthority KernelBase 713 +imp 'GetSidSubAuthorityCount' GetSidSubAuthorityCount KernelBase 714 +imp 'GetStagedPackageOrigin' GetStagedPackageOrigin KernelBase 715 +imp 'GetStagedPackagePathByFullName' GetStagedPackagePathByFullName KernelBase 716 +imp 'GetStartupInfo' GetStartupInfoW KernelBase 717 1 +imp 'GetStartupInfoA' GetStartupInfoA kernel32 723 1 +imp 'GetStateContainerDepth' GetStateContainerDepth KernelBase 718 +imp 'GetStateFolder' GetStateFolder KernelBase 719 +imp 'GetStateRootFolder' GetStateRootFolder KernelBase 720 +imp 'GetStateRootFolderBase' GetStateRootFolderBase KernelBase 721 +imp 'GetStateSettingsFolder' GetStateSettingsFolder KernelBase 722 +imp 'GetStateVersion' GetStateVersion KernelBase 723 +imp 'GetStdHandle' GetStdHandle KernelBase 724 1 +imp 'GetStockObject' GetStockObject gdi32 1701 +imp 'GetStretchBltMode' GetStretchBltMode gdi32 1702 +imp 'GetStringBitmapA' GetStringBitmapA gdi32 1703 +imp 'GetStringBitmap' GetStringBitmapW gdi32 1704 +imp 'GetStringConditionFromBinary' GetStringConditionFromBinary advapi32 1368 +imp 'GetStringScripts' GetStringScripts KernelBase 725 +imp 'GetStringTableEntry' GetStringTableEntry KernelBase 726 +imp 'GetStringTypeA' GetStringTypeA KernelBase 727 +imp 'GetStringTypeExA' GetStringTypeExA kernel32 729 +imp 'GetStringTypeEx' GetStringTypeExW KernelBase 728 +imp 'GetStringType' GetStringTypeW KernelBase 729 +imp 'GetSubMenu' GetSubMenu user32 1951 +imp 'GetSuggestedOPMProtectedOutputArraySize' GetSuggestedOPMProtectedOutputArraySize gdi32 1705 +imp 'GetSysColor' GetSysColor user32 1952 +imp 'GetSysColorBrush' GetSysColorBrush user32 1953 +imp 'GetSystemAppDataFolder' GetSystemAppDataFolder KernelBase 730 +imp 'GetSystemAppDataKey' GetSystemAppDataKey KernelBase 731 +imp 'GetSystemCpuSetInformation' GetSystemCpuSetInformation KernelBase 732 +imp 'GetSystemDEPPolicy' GetSystemDEPPolicy kernel32 734 +imp 'GetSystemDefaultLCID' GetSystemDefaultLCID KernelBase 733 +imp 'GetSystemDefaultLangID' GetSystemDefaultLangID KernelBase 734 +imp 'GetSystemDefaultLocaleName' GetSystemDefaultLocaleName KernelBase 735 +imp 'GetSystemDefaultUILanguage' GetSystemDefaultUILanguage KernelBase 736 +imp 'GetSystemDirectory' GetSystemDirectoryW KernelBase 738 2 +imp 'GetSystemDirectoryA' GetSystemDirectoryA KernelBase 737 2 +imp 'GetSystemDpiForProcess' GetSystemDpiForProcess user32 1954 +imp 'GetSystemFileCacheSize' GetSystemFileCacheSize KernelBase 739 +imp 'GetSystemFirmwareTable' GetSystemFirmwareTable KernelBase 740 +imp 'GetSystemInfo' GetSystemInfo KernelBase 741 1 +imp 'GetSystemMenu' GetSystemMenu user32 1955 +imp 'GetSystemMetadataPath' GetSystemMetadataPath KernelBase 742 +imp 'GetSystemMetadataPathForPackage' GetSystemMetadataPathForPackage KernelBase 743 +imp 'GetSystemMetadataPathForPackageFamily' GetSystemMetadataPathForPackageFamily KernelBase 744 +imp 'GetSystemMetrics' GetSystemMetrics user32 1956 +imp 'GetSystemMetricsForDpi' GetSystemMetricsForDpi user32 1957 +imp 'GetSystemPaletteEntries' GetSystemPaletteEntries gdi32 1706 +imp 'GetSystemPaletteUse' GetSystemPaletteUse gdi32 1707 +imp 'GetSystemPersistedStorageItemList' GetSystemPersistedStorageItemList shell32 919 +imp 'GetSystemPowerStatus' GetSystemPowerStatus kernel32 744 +imp 'GetSystemPreferredUILanguages' GetSystemPreferredUILanguages KernelBase 745 +imp 'GetSystemRegistryQuota' GetSystemRegistryQuota kernel32 746 +imp 'GetSystemStateRootFolder' GetSystemStateRootFolder KernelBase 746 +imp 'GetSystemTime' GetSystemTime KernelBase 747 1 +imp 'GetSystemTimeAdjustment' GetSystemTimeAdjustment KernelBase 748 +imp 'GetSystemTimeAdjustmentPrecise' GetSystemTimeAdjustmentPrecise KernelBase 749 +imp 'GetSystemTimeAsFileTime' GetSystemTimeAsFileTime KernelBase 750 1 +imp 'GetSystemTimePreciseAsFileTime' GetSystemTimePreciseAsFileTime KernelBase 751 1 +imp 'GetSystemTimes' GetSystemTimes KernelBase 752 +imp 'GetSystemWindowsDirectoryA' GetSystemWindowsDirectoryA KernelBase 753 +imp 'GetSystemWindowsDirectory' GetSystemWindowsDirectoryW KernelBase 754 +imp 'GetSystemWow64Directory2A' GetSystemWow64Directory2A KernelBase 755 +imp 'GetSystemWow64Directory2W' GetSystemWow64Directory2W KernelBase 756 +imp 'GetSystemWow64DirectoryA' GetSystemWow64DirectoryA KernelBase 757 +imp 'GetSystemWow64Directory' GetSystemWow64DirectoryW KernelBase 758 +imp 'GetTabbedTextExtentA' GetTabbedTextExtentA user32 1958 +imp 'GetTabbedTextExtent' GetTabbedTextExtentW user32 1959 +imp 'GetTapeParameters' GetTapeParameters kernel32 756 +imp 'GetTapePosition' GetTapePosition kernel32 757 +imp 'GetTapeStatus' GetTapeStatus kernel32 758 +imp 'GetTargetPlatformContext' GetTargetPlatformContext KernelBase 759 +imp 'GetTaskmanWindow' GetTaskmanWindow user32 1960 +imp 'GetTempFileNameA' GetTempFileNameA KernelBase 760 +imp 'GetTempFileName' GetTempFileNameW KernelBase 761 +imp 'GetTempPath' GetTempPathW KernelBase 763 2 +imp 'GetTempPathA' GetTempPathA KernelBase 762 2 +imp 'GetTextAlign' GetTextAlign gdi32 1708 +imp 'GetTextCharacterExtra' GetTextCharacterExtra gdi32 1709 +imp 'GetTextCharset' GetTextCharset gdi32 1710 +imp 'GetTextCharsetInfo' GetTextCharsetInfo gdi32 1711 +imp 'GetTextColor' GetTextColor gdi32 1712 +imp 'GetTextExtentExPointA' GetTextExtentExPointA gdi32 1713 +imp 'GetTextExtentExPointI' GetTextExtentExPointI gdi32 1714 +imp 'GetTextExtentExPoint' GetTextExtentExPointW gdi32 1715 +imp 'GetTextExtentExPointWPri' GetTextExtentExPointWPri gdi32 1716 +imp 'GetTextExtentPoint32A' GetTextExtentPoint32A gdi32 1717 +imp 'GetTextExtentPoint32W' GetTextExtentPoint32W gdi32 1718 +imp 'GetTextExtentPointA' GetTextExtentPointA gdi32 1719 +imp 'GetTextExtentPointI' GetTextExtentPointI gdi32 1720 +imp 'GetTextExtentPoint' GetTextExtentPointW gdi32 1721 +imp 'GetTextFaceA' GetTextFaceA gdi32 1722 +imp 'GetTextFaceAlias' GetTextFaceAliasW gdi32 1723 +imp 'GetTextFace' GetTextFaceW gdi32 1724 +imp 'GetTextMetricsA' GetTextMetricsA gdi32 1725 +imp 'GetTextMetrics' GetTextMetricsW gdi32 1726 +imp 'GetThreadContext' GetThreadContext KernelBase 764 +imp 'GetThreadDescription' GetThreadDescription KernelBase 765 +imp 'GetThreadDesktop' GetThreadDesktop user32 1961 +imp 'GetThreadDpiAwarenessContext' GetThreadDpiAwarenessContext user32 1962 +imp 'GetThreadDpiHostingBehavior' GetThreadDpiHostingBehavior user32 1963 +imp 'GetThreadErrorMode' GetThreadErrorMode KernelBase 766 +imp 'GetThreadGroupAffinity' GetThreadGroupAffinity KernelBase 767 +imp 'GetThreadIOPendingFlag' GetThreadIOPendingFlag KernelBase 768 2 +imp 'GetThreadId' GetThreadId KernelBase 769 1 +imp 'GetThreadIdealProcessorEx' GetThreadIdealProcessorEx KernelBase 770 +imp 'GetThreadInformation' GetThreadInformation KernelBase 771 +imp 'GetThreadLocale' GetThreadLocale KernelBase 772 +imp 'GetThreadPreferredUILanguages' GetThreadPreferredUILanguages KernelBase 773 +imp 'GetThreadPriority' GetThreadPriority KernelBase 774 1 +imp 'GetThreadPriorityBoost' GetThreadPriorityBoost KernelBase 775 2 +imp 'GetThreadSelectedCpuSets' GetThreadSelectedCpuSets KernelBase 776 +imp 'GetThreadSelectorEntry' GetThreadSelectorEntry kernel32 776 +imp 'GetThreadTimes' GetThreadTimes KernelBase 777 5 +imp 'GetThreadUILanguage' GetThreadUILanguage KernelBase 778 +imp 'GetThreadWaitChain' GetThreadWaitChain advapi32 1369 +imp 'GetTickCount' GetTickCount KernelBase 779 +imp 'GetTickCount64' GetTickCount64 KernelBase 780 +imp 'GetTimeFormatA' GetTimeFormatA KernelBase 781 +imp 'GetTimeFormatAWorker' GetTimeFormatAWorker kernel32 782 +imp 'GetTimeFormatEx' GetTimeFormatEx KernelBase 782 +imp 'GetTimeFormat' GetTimeFormatW KernelBase 783 +imp 'GetTimeFormatWWorker' GetTimeFormatWWorker kernel32 785 +imp 'GetTimeZoneInformation' GetTimeZoneInformation KernelBase 784 +imp 'GetTimeZoneInformationForYear' GetTimeZoneInformationForYear KernelBase 785 +imp 'GetTitleBarInfo' GetTitleBarInfo user32 1964 +imp 'GetTokenInformation' GetTokenInformation KernelBase 786 +imp 'GetTopLevelWindow' GetTopLevelWindow user32 1965 +imp 'GetTopWindow' GetTopWindow user32 1966 +imp 'GetTouchInputInfo' GetTouchInputInfo user32 1967 +imp 'GetTransform' GetTransform gdi32 1727 +imp 'GetTrusteeFormA' GetTrusteeFormA advapi32 1374 +imp 'GetTrusteeForm' GetTrusteeFormW advapi32 1375 +imp 'GetTrusteeNameA' GetTrusteeNameA advapi32 1376 +imp 'GetTrusteeName' GetTrusteeNameW advapi32 1377 +imp 'GetTrusteeTypeA' GetTrusteeTypeA advapi32 1378 +imp 'GetTrusteeType' GetTrusteeTypeW advapi32 1379 +imp 'GetUILanguageInfo' GetUILanguageInfo KernelBase 790 +imp 'GetUmsCompletionListEvent' GetUmsCompletionListEvent kernel32 789 +imp 'GetUmsSystemThreadInformation' GetUmsSystemThreadInformation kernel32 790 +imp 'GetUnicodeStringToEightBitSizeRoutine' GetUnicodeStringToEightBitSizeRoutine KernelBase 791 +imp 'GetUnicodeStringToEightBitStringRoutine' GetUnicodeStringToEightBitStringRoutine KernelBase 792 +imp 'GetUnpredictedMessagePos' GetUnpredictedMessagePos user32 1968 +imp 'GetUpdateRect' GetUpdateRect user32 1969 +imp 'GetUpdateRgn' GetUpdateRgn user32 1970 +imp 'GetUpdatedClipboardFormats' GetUpdatedClipboardFormats user32 1971 +imp 'GetUserDefaultGeoName' GetUserDefaultGeoName KernelBase 793 +imp 'GetUserDefaultLCID' GetUserDefaultLCID KernelBase 794 +imp 'GetUserDefaultLangID' GetUserDefaultLangID KernelBase 795 +imp 'GetUserDefaultLocaleName' GetUserDefaultLocaleName KernelBase 796 +imp 'GetUserDefaultUILanguage' GetUserDefaultUILanguage KernelBase 797 +imp 'GetUserGeoID' GetUserGeoID KernelBase 798 +imp 'GetUserInfo' GetUserInfo KernelBase 799 +imp 'GetUserInfoWord' GetUserInfoWord KernelBase 800 +imp 'GetUserName' GetUserNameW advapi32 1381 2 +imp 'GetUserNameA' GetUserNameA advapi32 1380 2 +imp 'GetUserObjectInformationA' GetUserObjectInformationA user32 1972 +imp 'GetUserObjectInformation' GetUserObjectInformationW user32 1973 +imp 'GetUserObjectSecurity' GetUserObjectSecurity user32 1974 +imp 'GetUserOverrideString' GetUserOverrideString KernelBase 801 +imp 'GetUserOverrideWord' GetUserOverrideWord KernelBase 802 +imp 'GetUserPreferredUILanguages' GetUserPreferredUILanguages KernelBase 803 +imp 'GetVDMCurrentDirectories' GetVDMCurrentDirectories kernel32 798 +imp 'GetVersion' GetVersion KernelBase 804 +imp 'GetVersionExA' GetVersionExA KernelBase 805 +imp 'GetVersionEx' GetVersionExW KernelBase 806 +imp 'GetViewportExtEx' GetViewportExtEx gdi32 1728 +imp 'GetViewportOrgEx' GetViewportOrgEx gdi32 1729 +imp 'GetVolumeInformationA' GetVolumeInformationA KernelBase 807 +imp 'GetVolumeInformationByHandle' GetVolumeInformationByHandleW KernelBase 808 +imp 'GetVolumeInformation' GetVolumeInformationW KernelBase 809 +imp 'GetVolumeNameForVolumeMountPointA' GetVolumeNameForVolumeMountPointA kernel32 805 +imp 'GetVolumeNameForVolumeMountPoint' GetVolumeNameForVolumeMountPointW KernelBase 810 +imp 'GetVolumePathNameA' GetVolumePathNameA kernel32 807 +imp 'GetVolumePathName' GetVolumePathNameW KernelBase 811 +imp 'GetVolumePathNamesForVolumeNameA' GetVolumePathNamesForVolumeNameA kernel32 809 +imp 'GetVolumePathNamesForVolumeName' GetVolumePathNamesForVolumeNameW KernelBase 812 +imp 'GetWinMetaFileBits' GetWinMetaFileBits gdi32 1730 +imp 'GetWinStationInfo' GetWinStationInfo user32 1975 +imp 'GetWindow' GetWindow user32 1976 2 +imp 'GetWindowBand' GetWindowBand user32 1977 +imp 'GetWindowCompositionAttribute' GetWindowCompositionAttribute user32 1978 +imp 'GetWindowCompositionInfo' GetWindowCompositionInfo user32 1979 +imp 'GetWindowContextHelpId' GetWindowContextHelpId user32 1980 +imp 'GetWindowDC' GetWindowDC user32 1981 +imp 'GetWindowDisplayAffinity' GetWindowDisplayAffinity user32 1982 +imp 'GetWindowDpiAwarenessContext' GetWindowDpiAwarenessContext user32 1983 +imp 'GetWindowDpiHostingBehavior' GetWindowDpiHostingBehavior user32 1984 +imp 'GetWindowExtEx' GetWindowExtEx gdi32 1731 +imp 'GetWindowFeedbackSetting' GetWindowFeedbackSetting user32 1985 +imp 'GetWindowInfo' GetWindowInfo user32 1986 +imp 'GetWindowLongA' GetWindowLongA user32 1987 +imp 'GetWindowLongPtrA' GetWindowLongPtrA user32 1988 +imp 'GetWindowLongPtr' GetWindowLongPtrW user32 1989 +imp 'GetWindowLong' GetWindowLongW user32 1990 +imp 'GetWindowMinimizeRect' GetWindowMinimizeRect user32 1991 +imp 'GetWindowModuleFileNameA' GetWindowModuleFileNameA user32 1993 +imp 'GetWindowModuleFileName' GetWindowModuleFileNameW user32 1994 +imp 'GetWindowOrgEx' GetWindowOrgEx gdi32 1732 +imp 'GetWindowPlacement' GetWindowPlacement user32 1995 +imp 'GetWindowProcessHandle' GetWindowProcessHandle user32 1996 +imp 'GetWindowRect' GetWindowRect user32 1997 2 +imp 'GetWindowRgn' GetWindowRgn user32 1998 +imp 'GetWindowRgnBox' GetWindowRgnBox user32 1999 +imp 'GetWindowRgnEx' GetWindowRgnEx user32 2000 +imp 'GetWindowText' GetWindowTextW user32 2007 3 +imp 'GetWindowTextA' GetWindowTextA user32 2003 3 +imp 'GetWindowTextLengthA' GetWindowTextLengthA user32 2004 +imp 'GetWindowTextLength' GetWindowTextLengthW user32 2006 +imp 'GetWindowThreadProcessId' GetWindowThreadProcessId user32 2008 +imp 'GetWindowWord' GetWindowWord user32 2009 +imp 'GetWindowsAccountDomainSid' GetWindowsAccountDomainSid KernelBase 813 +imp 'GetWindowsDirectory' GetWindowsDirectoryW KernelBase 815 2 +imp 'GetWindowsDirectoryA' GetWindowsDirectoryA KernelBase 814 2 +imp 'GetWorldTransform' GetWorldTransform gdi32 1733 +imp 'GetWriteWatch' GetWriteWatch KernelBase 816 +imp 'GetWsChanges' GetWsChanges KernelBase 817 +imp 'GetWsChangesEx' GetWsChangesEx KernelBase 818 +imp 'GetXStateFeaturesMask' GetXStateFeaturesMask KernelBase 819 +imp 'GhostWindowFromHungWindow' GhostWindowFromHungWindow user32 2011 +imp 'GlobalAddAtomA' GlobalAddAtomA kernel32 815 +imp 'GlobalAddAtomExA' GlobalAddAtomExA kernel32 816 +imp 'GlobalAddAtomEx' GlobalAddAtomExW kernel32 817 +imp 'GlobalAddAtom' GlobalAddAtomW kernel32 818 +imp 'GlobalAlloc' GlobalAlloc KernelBase 820 +imp 'GlobalCompact' GlobalCompact kernel32 820 +imp 'GlobalDeleteAtom' GlobalDeleteAtom kernel32 821 +imp 'GlobalFindAtomA' GlobalFindAtomA kernel32 822 +imp 'GlobalFindAtom' GlobalFindAtomW kernel32 823 +imp 'GlobalFix' GlobalFix kernel32 824 +imp 'GlobalFlags' GlobalFlags kernel32 825 +imp 'GlobalFree' GlobalFree KernelBase 821 +imp 'GlobalGetAtomNameA' GlobalGetAtomNameA kernel32 827 +imp 'GlobalGetAtomName' GlobalGetAtomNameW kernel32 828 +imp 'GlobalHandle' GlobalHandle kernel32 829 +imp 'GlobalLock' GlobalLock kernel32 830 +imp 'GlobalMemoryStatus' GlobalMemoryStatus kernel32 831 +imp 'GlobalMemoryStatusEx' GlobalMemoryStatusEx KernelBase 822 1 +imp 'GlobalReAlloc' GlobalReAlloc kernel32 833 +imp 'GlobalSize' GlobalSize kernel32 834 +imp 'GlobalUnWire' GlobalUnWire kernel32 835 +imp 'GlobalUnfix' GlobalUnfix kernel32 836 +imp 'GlobalUnlock' GlobalUnlock kernel32 837 +imp 'GlobalWire' GlobalWire kernel32 838 +imp 'GrayStringA' GrayStringA user32 2012 +imp 'GrayString' GrayStringW user32 2013 +imp 'GuardCheckLongJumpTarget' GuardCheckLongJumpTarget KernelBase 823 +imp 'HT_Get8BPPFormatPalette' HT_Get8BPPFormatPalette gdi32 1734 +imp 'HT_Get8BPPMaskPalette' HT_Get8BPPMaskPalette gdi32 1735 +imp 'HandleDelegatedInput' HandleDelegatedInput user32 2505 +imp 'HasPolicyForegroundProcessingCompletedInternal' HasPolicyForegroundProcessingCompletedInternal KernelBase 824 +imp 'HashData' HashData KernelBase 825 +imp 'Heap32First' Heap32First kernel32 839 +imp 'Heap32ListFirst' Heap32ListFirst kernel32 840 +imp 'Heap32ListNext' Heap32ListNext kernel32 841 +imp 'Heap32Next' Heap32Next kernel32 842 +imp 'HeapCompact' HeapCompact KernelBase 827 +imp 'HeapCreate' HeapCreate KernelBase 828 +imp 'HeapDestroy' HeapDestroy KernelBase 829 +imp 'HeapFree' HeapFree kernel32 847 +imp 'HeapLock' HeapLock KernelBase 831 +imp 'HeapQueryInformation' HeapQueryInformation KernelBase 832 +imp 'HeapSetInformation' HeapSetInformation KernelBase 834 +imp 'HeapSummary' HeapSummary KernelBase 836 +imp 'HeapUnlock' HeapUnlock KernelBase 837 +imp 'HeapValidate' HeapValidate KernelBase 838 +imp 'HeapWalk' HeapWalk KernelBase 839 +imp 'HideCaret' HideCaret user32 2014 +imp 'HiliteMenuItem' HiliteMenuItem user32 2015 +imp 'HungWindowFromGhostWindow' HungWindowFromGhostWindow user32 2016 +imp 'ILAppendID' ILAppendID shell32 154 +imp 'ILClone' ILClone shell32 18 +imp 'ILCloneFirst' ILCloneFirst shell32 19 +imp 'ILCombine' ILCombine shell32 25 +imp 'ILCreateFromPathA' ILCreateFromPathA shell32 189 +imp 'ILCreateFromPath' ILCreateFromPathW shell32 190 +imp 'ILFindChild' ILFindChild shell32 24 +imp 'ILFindLastID' ILFindLastID shell32 16 +imp 'ILFree' ILFree shell32 155 +imp 'ILGetNext' ILGetNext shell32 153 +imp 'ILGetSize' ILGetSize shell32 152 +imp 'ILIsEqual' ILIsEqual shell32 21 +imp 'ILIsParent' ILIsParent shell32 23 +imp 'ILLoadFromStreamEx' ILLoadFromStreamEx shell32 846 +imp 'ILRemoveLastID' ILRemoveLastID shell32 17 +imp 'ILSaveToStream' ILSaveToStream shell32 27 +imp 'IMPGetIMEA' IMPGetIMEA user32 2017 +imp 'IMPGetIMEW' IMPGetIMEW user32 2018 +imp 'IMPQueryIMEA' IMPQueryIMEA user32 2019 +imp 'IMPQueryIMEW' IMPQueryIMEW user32 2020 +imp 'IMPSetIMEA' IMPSetIMEA user32 2021 +imp 'IMPSetIMEW' IMPSetIMEW user32 2022 +imp 'I_BrowserSetNetlogonState' I_BrowserSetNetlogonState netapi32 34 +imp 'I_ScGetCurrentGroupState' I_ScGetCurrentGroupStateW advapi32 1001 +imp 'I_ScReparseServiceDatabase' I_ScReparseServiceDatabase advapi32 1388 +imp 'I_ScSetServiceBitsA' I_ScSetServiceBitsA advapi32 1391 +imp 'I_ScSetServiceBits' I_ScSetServiceBitsW advapi32 1392 +imp 'IdentifyCodeAuthzLevel' IdentifyCodeAuthzLevelW advapi32 1394 +imp 'IdnToAscii' IdnToAscii KernelBase 840 +imp 'IdnToNameprepUnicode' IdnToNameprepUnicode KernelBase 841 +imp 'IdnToUnicode' IdnToUnicode KernelBase 842 +imp 'ImpersonateAnonymousToken' ImpersonateAnonymousToken KernelBase 843 +imp 'ImpersonateDdeClientWindow' ImpersonateDdeClientWindow user32 2023 +imp 'ImpersonateLoggedOnUser' ImpersonateLoggedOnUser KernelBase 844 +imp 'ImpersonateNamedPipeClient' ImpersonateNamedPipeClient KernelBase 845 +imp 'ImpersonateSelf' ImpersonateSelf KernelBase 846 +imp 'InSendMessage' InSendMessage user32 2024 +imp 'InSendMessageEx' InSendMessageEx user32 2025 +imp 'IncrementPackageStatusVersion' IncrementPackageStatusVersion KernelBase 847 +imp 'InetIsOffline' InetIsOffline url 106 +imp 'InetNtop' InetNtopW ws2_32 35 +imp 'InetPton' InetPtonW ws2_32 36 +imp 'InflateRect' InflateRect user32 2026 +imp 'InheritWindowMonitor' InheritWindowMonitor user32 2027 +imp 'InitAtomTable' InitAtomTable kernel32 860 +imp 'InitDManipHook' InitDManipHook user32 2028 +imp 'InitNetworkAddressControl' InitNetworkAddressControl shell32 306 +imp 'InitOnceBeginInitialize' InitOnceBeginInitialize KernelBase 848 +imp 'InitOnceComplete' InitOnceComplete KernelBase 849 +imp 'InitOnceExecuteOnce' InitOnceExecuteOnce KernelBase 850 +imp 'InitializeAcl' InitializeAcl KernelBase 852 +imp 'InitializeContext' InitializeContext KernelBase 854 +imp 'InitializeCriticalSectionAndSpinCount' InitializeCriticalSectionAndSpinCount KernelBase 856 2 +imp 'InitializeCriticalSectionEx' InitializeCriticalSectionEx KernelBase 857 +imp 'InitializeEnclave' InitializeEnclave KernelBase 858 +imp 'InitializeGenericHidInjection' InitializeGenericHidInjection user32 2029 +imp 'InitializeInputDeviceInjection' InitializeInputDeviceInjection user32 2030 +imp 'InitializeLpkHooks' InitializeLpkHooks user32 2031 +imp 'InitializePointerDeviceInjection' InitializePointerDeviceInjection user32 2032 +imp 'InitializePointerDeviceInjectionEx' InitializePointerDeviceInjectionEx user32 2033 +imp 'InitializeProcThreadAttributeList' InitializeProcThreadAttributeList KernelBase 859 4 +imp 'InitializeProcessForWsWatch' InitializeProcessForWsWatch KernelBase 860 +imp 'InitializeSecurityDescriptor' InitializeSecurityDescriptor KernelBase 863 +imp 'InitializeSid' InitializeSid KernelBase 864 +imp 'InitializeSynchronizationBarrier' InitializeSynchronizationBarrier KernelBase 865 +imp 'InitializeTouchInjection' InitializeTouchInjection user32 2034 +imp 'InitiateShutdownA' InitiateShutdownA advapi32 1402 +imp 'InitiateShutdown' InitiateShutdownW advapi32 1403 +imp 'InitiateSystemShutdownA' InitiateSystemShutdownA advapi32 1404 +imp 'InitiateSystemShutdownExA' InitiateSystemShutdownExA advapi32 1405 +imp 'InitiateSystemShutdownEx' InitiateSystemShutdownExW advapi32 1406 +imp 'InitiateSystemShutdown' InitiateSystemShutdownW advapi32 1407 +imp 'InjectDeviceInput' InjectDeviceInput user32 2035 +imp 'InjectGenericHidInput' InjectGenericHidInput user32 2036 +imp 'InjectKeyboardInput' InjectKeyboardInput user32 2037 +imp 'InjectMouseInput' InjectMouseInput user32 2038 +imp 'InjectPointerInput' InjectPointerInput user32 2039 +imp 'InjectTouchInput' InjectTouchInput user32 2040 +imp 'InsertMenuA' InsertMenuA user32 2041 +imp 'InsertMenuItemA' InsertMenuItemA user32 2042 +imp 'InsertMenuItem' InsertMenuItemW user32 2043 +imp 'InsertMenu' InsertMenuW user32 2044 +imp 'InstallApplication' InstallApplication advapi32 1408 +imp 'InstallELAMCertificateInfo' InstallELAMCertificateInfo KernelBase 866 +imp 'InternalDeleteDC' InternalDeleteDC gdi32 1736 +imp 'InternalExtractIconListA' InternalExtractIconListA shell32 307 +imp 'InternalExtractIconList' InternalExtractIconListW shell32 308 +imp 'InternalGetWindowIcon' InternalGetWindowIcon user32 2045 +imp 'InternalGetWindowText' InternalGetWindowText user32 2046 +imp 'InternalLcidToName' InternalLcidToName KernelBase 872 +imp 'Internal_EnumCalendarInfo' Internal_EnumCalendarInfo KernelBase 873 +imp 'Internal_EnumDateFormats' Internal_EnumDateFormats KernelBase 874 +imp 'Internal_EnumLanguageGroupLocales' Internal_EnumLanguageGroupLocales KernelBase 875 +imp 'Internal_EnumSystemCodePages' Internal_EnumSystemCodePages KernelBase 876 +imp 'Internal_EnumSystemLanguageGroups' Internal_EnumSystemLanguageGroups KernelBase 877 +imp 'Internal_EnumSystemLocales' Internal_EnumSystemLocales KernelBase 878 +imp 'Internal_EnumTimeFormats' Internal_EnumTimeFormats KernelBase 879 +imp 'Internal_EnumUILanguages' Internal_EnumUILanguages KernelBase 880 +imp 'InternetTimeFromSystemTimeA' InternetTimeFromSystemTimeA KernelBase 881 +imp 'InternetTimeFromSystemTime' InternetTimeFromSystemTimeW KernelBase 882 +imp 'InternetTimeToSystemTimeA' InternetTimeToSystemTimeA KernelBase 883 +imp 'InternetTimeToSystemTime' InternetTimeToSystemTimeW KernelBase 884 +imp 'IntersectClipRect' IntersectClipRect gdi32 1737 +imp 'IntersectRect' IntersectRect user32 2047 +imp 'InvalidateAppModelVersionCache' InvalidateAppModelVersionCache KernelBase 885 +imp 'InvalidateConsoleDIBits' InvalidateConsoleDIBits kernel32 881 +imp 'InvalidateRect' InvalidateRect user32 2048 +imp 'InvalidateRgn' InvalidateRgn user32 2049 +imp 'InvertRect' InvertRect user32 2050 +imp 'InvertRgn' InvertRgn gdi32 1738 +imp 'IsBadCodePtr' IsBadCodePtr kernel32 882 +imp 'IsBadHugeReadPtr' IsBadHugeReadPtr kernel32 883 +imp 'IsBadHugeWritePtr' IsBadHugeWritePtr kernel32 884 +imp 'IsBadReadPtr' IsBadReadPtr kernel32 885 +imp 'IsBadStringPtrA' IsBadStringPtrA kernel32 886 +imp 'IsBadStringPtr' IsBadStringPtrW kernel32 887 +imp 'IsBadWritePtr' IsBadWritePtr kernel32 888 +imp 'IsCalendarLeapDay' IsCalendarLeapDay kernel32 889 +imp 'IsCalendarLeapMonth' IsCalendarLeapMonth kernel32 890 +imp 'IsCalendarLeapYear' IsCalendarLeapYear kernel32 891 +imp 'IsCharAlphaA' IsCharAlphaA KernelBase 886 +imp 'IsCharAlphaNumericA' IsCharAlphaNumericA KernelBase 887 +imp 'IsCharAlphaNumeric' IsCharAlphaNumericW KernelBase 888 +imp 'IsCharAlpha' IsCharAlphaW KernelBase 889 +imp 'IsCharBlank' IsCharBlankW KernelBase 890 +imp 'IsCharCntrl' IsCharCntrlW KernelBase 891 +imp 'IsCharDigit' IsCharDigitW KernelBase 892 +imp 'IsCharLowerA' IsCharLowerA KernelBase 893 +imp 'IsCharLower' IsCharLowerW KernelBase 894 +imp 'IsCharPunct' IsCharPunctW KernelBase 895 +imp 'IsCharSpaceA' IsCharSpaceA KernelBase 896 +imp 'IsCharSpace' IsCharSpaceW KernelBase 897 +imp 'IsCharUpperA' IsCharUpperA KernelBase 898 +imp 'IsCharUpper' IsCharUpperW KernelBase 899 +imp 'IsCharXDigit' IsCharXDigitW KernelBase 900 +imp 'IsChild' IsChild user32 2059 2 +imp 'IsClipboardFormatAvailable' IsClipboardFormatAvailable user32 2060 +imp 'IsDBCSLeadByte' IsDBCSLeadByte KernelBase 901 +imp 'IsDBCSLeadByteEx' IsDBCSLeadByteEx KernelBase 902 +imp 'IsDebuggerPresent$nt' IsDebuggerPresent KernelBase 903 +imp 'IsDesktopExplorerProcess' IsDesktopExplorerProcess shell32 942 +imp 'IsDeveloperModeEnabled' IsDeveloperModeEnabled KernelBase 904 +imp 'IsDeveloperModePolicyApplied' IsDeveloperModePolicyApplied KernelBase 905 +imp 'IsDialogMessageA' IsDialogMessageA user32 2062 +imp 'IsDialogMessage' IsDialogMessageW user32 2063 +imp 'IsDlgButtonChecked' IsDlgButtonChecked user32 2064 +imp 'IsEnclaveTypeSupported' IsEnclaveTypeSupported KernelBase 906 +imp 'IsGUIThread' IsGUIThread user32 2065 +imp 'IsGlobalizationUserSettingsKeyRedirected' IsGlobalizationUserSettingsKeyRedirected KernelBase 907 +imp 'IsHungAppWindow' IsHungAppWindow user32 2066 +imp 'IsIconic' IsIconic user32 2067 +imp 'IsImmersiveProcess' IsImmersiveProcess user32 2068 +imp 'IsInDesktopWindowBand' IsInDesktopWindowBand user32 2069 +imp 'IsInternetESCEnabled' IsInternetESCEnabled KernelBase 908 +imp 'IsLFNDriveA' IsLFNDriveA shell32 41 +imp 'IsLFNDrive' IsLFNDriveW shell32 42 +imp 'IsMenu' IsMenu user32 2070 1 +imp 'IsMouseInPointerEnabled' IsMouseInPointerEnabled user32 2071 +imp 'IsNLSDefinedString' IsNLSDefinedString KernelBase 909 +imp 'IsNativeVhdBoot' IsNativeVhdBoot kernel32 897 +imp 'IsNetDrive' IsNetDrive shell32 66 +imp 'IsNormalizedString' IsNormalizedString KernelBase 910 +imp 'IsOnDemandRegistrationSupportedForExtensionCategory' IsOnDemandRegistrationSupportedForExtensionCategory KernelBase 911 +imp 'IsOneCoreTransformMode' IsOneCoreTransformMode user32 2072 +imp 'IsProcessAnExplorer' IsProcessAnExplorer shell32 941 +imp 'IsProcessCritical' IsProcessCritical KernelBase 912 +imp 'IsProcessDPIAware' IsProcessDPIAware user32 2073 +imp 'IsProcessInJob' IsProcessInJob KernelBase 913 +imp 'IsProcessorFeaturePresent' IsProcessorFeaturePresent KernelBase 914 +imp 'IsQueueAttached' IsQueueAttached user32 2074 +imp 'IsRectEmpty' IsRectEmpty user32 2075 +imp 'IsSETEnabled' IsSETEnabled user32 2076 +imp 'IsServerSideWindow' IsServerSideWindow user32 2077 +imp 'IsSideloadingEnabled' IsSideloadingEnabled KernelBase 915 +imp 'IsSideloadingPolicyApplied' IsSideloadingPolicyApplied KernelBase 916 +imp 'IsSyncForegroundPolicyRefresh' IsSyncForegroundPolicyRefresh KernelBase 917 +imp 'IsSystemResumeAutomatic' IsSystemResumeAutomatic kernel32 902 +imp 'IsTextUnicode' IsTextUnicode advapi32 1409 +imp 'IsThreadAFiber' IsThreadAFiber KernelBase 918 +imp 'IsThreadDesktopComposited' IsThreadDesktopComposited user32 2078 +imp 'IsThreadMessageQueueAttached' IsThreadMessageQueueAttached user32 2528 +imp 'IsThreadTSFEventAware' IsThreadTSFEventAware user32 2079 +imp 'IsTimeZoneRedirectionEnabled' IsTimeZoneRedirectionEnabled KernelBase 920 +imp 'IsTokenRestricted' IsTokenRestricted KernelBase 921 +imp 'IsTokenUntrusted' IsTokenUntrusted advapi32 1411 +imp 'IsTopLevelWindow' IsTopLevelWindow user32 2080 +imp 'IsTouchWindow' IsTouchWindow user32 2081 +imp 'IsUserAnAdmin' IsUserAnAdmin shell32 680 +imp 'IsValidAcl' IsValidAcl KernelBase 922 +imp 'IsValidCalDateTime' IsValidCalDateTime kernel32 905 +imp 'IsValidCodePage' IsValidCodePage KernelBase 923 +imp 'IsValidDpiAwarenessContext' IsValidDpiAwarenessContext user32 2082 +imp 'IsValidEnhMetaRecord' IsValidEnhMetaRecord gdi32 1739 +imp 'IsValidEnhMetaRecordOffExt' IsValidEnhMetaRecordOffExt gdi32 1740 +imp 'IsValidLanguageGroup' IsValidLanguageGroup KernelBase 924 +imp 'IsValidLocale' IsValidLocale KernelBase 925 +imp 'IsValidLocaleName' IsValidLocaleName KernelBase 926 +imp 'IsValidNLSVersion' IsValidNLSVersion KernelBase 927 +imp 'IsValidRelativeSecurityDescriptor' IsValidRelativeSecurityDescriptor KernelBase 928 +imp 'IsValidSecurityDescriptor' IsValidSecurityDescriptor KernelBase 929 +imp 'IsValidSid' IsValidSid KernelBase 930 +imp 'IsWellKnownSid' IsWellKnownSid KernelBase 931 +imp 'IsWinEventHookInstalled' IsWinEventHookInstalled user32 2083 +imp 'IsWindow' IsWindow user32 2084 1 +imp 'IsWindowArranged' IsWindowArranged user32 2085 +imp 'IsWindowEnabled' IsWindowEnabled user32 2086 +imp 'IsWindowInDestroy' IsWindowInDestroy user32 2087 +imp 'IsWindowRedirectedForPrint' IsWindowRedirectedForPrint user32 2088 +imp 'IsWindowUnicode' IsWindowUnicode user32 2089 +imp 'IsWindowVisible' IsWindowVisible user32 2090 1 +imp 'IsWow64GuestMachineSupported' IsWow64GuestMachineSupported KernelBase 932 +imp 'IsWow64Message' IsWow64Message user32 2091 +imp 'IsWow64Process' IsWow64Process KernelBase 933 +imp 'IsWow64Process2' IsWow64Process2 KernelBase 934 +imp 'IsZoomed' IsZoomed user32 2092 1 +imp 'K32EmptyWorkingSet' K32EmptyWorkingSet KernelBase 935 +imp 'K32EnumDeviceDrivers' K32EnumDeviceDrivers KernelBase 936 +imp 'K32EnumPageFilesA' K32EnumPageFilesA KernelBase 937 +imp 'K32EnumPageFiles' K32EnumPageFilesW KernelBase 938 +imp 'K32EnumProcessModules' K32EnumProcessModules KernelBase 939 +imp 'K32EnumProcessModulesEx' K32EnumProcessModulesEx KernelBase 940 +imp 'K32EnumProcesses' K32EnumProcesses KernelBase 941 +imp 'K32GetDeviceDriverBaseNameA' K32GetDeviceDriverBaseNameA KernelBase 942 +imp 'K32GetDeviceDriverBaseName' K32GetDeviceDriverBaseNameW KernelBase 943 +imp 'K32GetDeviceDriverFileNameA' K32GetDeviceDriverFileNameA KernelBase 944 +imp 'K32GetDeviceDriverFileName' K32GetDeviceDriverFileNameW KernelBase 945 +imp 'K32GetMappedFileNameA' K32GetMappedFileNameA KernelBase 946 +imp 'K32GetMappedFileName' K32GetMappedFileNameW KernelBase 947 +imp 'K32GetModuleBaseNameA' K32GetModuleBaseNameA KernelBase 948 +imp 'K32GetModuleBaseName' K32GetModuleBaseNameW KernelBase 949 +imp 'K32GetModuleFileNameExA' K32GetModuleFileNameExA KernelBase 950 +imp 'K32GetModuleFileNameEx' K32GetModuleFileNameExW KernelBase 951 +imp 'K32GetModuleInformation' K32GetModuleInformation KernelBase 952 +imp 'K32GetPerformanceInfo' K32GetPerformanceInfo KernelBase 953 +imp 'K32GetProcessImageFileNameA' K32GetProcessImageFileNameA KernelBase 954 +imp 'K32GetProcessImageFileName' K32GetProcessImageFileNameW KernelBase 955 +imp 'K32GetProcessMemoryInfo' K32GetProcessMemoryInfo KernelBase 956 +imp 'K32GetWsChanges' K32GetWsChanges KernelBase 957 +imp 'K32GetWsChangesEx' K32GetWsChangesEx KernelBase 958 +imp 'K32InitializeProcessForWsWatch' K32InitializeProcessForWsWatch KernelBase 959 +imp 'K32QueryWorkingSet' K32QueryWorkingSet KernelBase 960 +imp 'K32QueryWorkingSetEx' K32QueryWorkingSetEx KernelBase 961 +imp 'KernelBaseGetGlobalData' KernelBaseGetGlobalData KernelBase 962 +imp 'KernelbasePostInit' KernelbasePostInit KernelBase 963 +imp 'KiRaiseUserExceptionDispatcher' KiRaiseUserExceptionDispatcher ntdll 103 +imp 'KiUserApcDispatcher' KiUserApcDispatcher ntdll 104 +imp 'KiUserCallbackDispatcher' KiUserCallbackDispatcher ntdll 105 +imp 'KiUserExceptionDispatcher' KiUserExceptionDispatcher ntdll 106 +imp 'KiUserInvertedFunctionTable' KiUserInvertedFunctionTable ntdll 107 +imp 'KillTimer' KillTimer user32 2093 2 +imp 'LCIDToLocaleName' LCIDToLocaleName KernelBase 964 +imp 'LCMapStringA' LCMapStringA KernelBase 965 +imp 'LCMapStringEx' LCMapStringEx KernelBase 966 +imp 'LCMapString' LCMapStringW KernelBase 967 +imp 'LPtoDP' LPtoDP gdi32 1741 +imp 'LZClose' LZClose kernel32 945 +imp 'LZCloseFile' LZCloseFile kernel32 946 +imp 'LZCopy' LZCopy kernel32 947 +imp 'LZCreateFile' LZCreateFileW kernel32 948 +imp 'LZDone' LZDone kernel32 949 +imp 'LZInit' LZInit kernel32 950 +imp 'LZOpenFileA' LZOpenFileA kernel32 951 +imp 'LZOpenFile' LZOpenFileW kernel32 952 +imp 'LZRead' LZRead kernel32 953 +imp 'LZSeek' LZSeek kernel32 954 +imp 'LZStart' LZStart kernel32 955 +imp 'LaunchMSHelp_RunDLLW' LaunchMSHelp_RunDLLW shell32 309 +imp 'LdrAccessResource' LdrAccessResource ntdll 108 +imp 'LdrAddDllDirectory' LdrAddDllDirectory ntdll 109 +imp 'LdrAddLoadAsDataTable' LdrAddLoadAsDataTable ntdll 110 +imp 'LdrAddRefDll' LdrAddRefDll ntdll 111 +imp 'LdrAppxHandleIntegrityFailure' LdrAppxHandleIntegrityFailure ntdll 112 +imp 'LdrCallEnclave' LdrCallEnclave ntdll 113 +imp 'LdrControlFlowGuardEnforced' LdrControlFlowGuardEnforced ntdll 114 +imp 'LdrCreateEnclave' LdrCreateEnclave ntdll 115 +imp 'LdrDeleteEnclave' LdrDeleteEnclave ntdll 116 +imp 'LdrDisableThreadCalloutsForDll' LdrDisableThreadCalloutsForDll ntdll 117 +imp 'LdrEnumResources' LdrEnumResources ntdll 118 +imp 'LdrEnumerateLoadedModules' LdrEnumerateLoadedModules ntdll 119 +imp 'LdrFastFailInLoaderCallout' LdrFastFailInLoaderCallout ntdll 120 +imp 'LdrFindEntryForAddress' LdrFindEntryForAddress ntdll 121 +imp 'LdrFindResourceDirectory_U' LdrFindResourceDirectory_U ntdll 122 +imp 'LdrFindResourceEx_U' LdrFindResourceEx_U ntdll 123 +imp 'LdrFindResource_U' LdrFindResource_U ntdll 124 +imp 'LdrFlushAlternateResourceModules' LdrFlushAlternateResourceModules ntdll 125 +imp 'LdrGetDllDirectory' LdrGetDllDirectory ntdll 126 +imp 'LdrGetDllFullName' LdrGetDllFullName ntdll 127 +imp 'LdrGetDllHandle' LdrGetDllHandle ntdll 128 4 +imp 'LdrGetDllHandleByMapping' LdrGetDllHandleByMapping ntdll 129 +imp 'LdrGetDllHandleByName' LdrGetDllHandleByName ntdll 130 +imp 'LdrGetDllHandleEx' LdrGetDllHandleEx ntdll 131 +imp 'LdrGetDllPath' LdrGetDllPath ntdll 132 +imp 'LdrGetFailureData' LdrGetFailureData ntdll 133 +imp 'LdrGetFileNameFromLoadAsDataTable' LdrGetFileNameFromLoadAsDataTable ntdll 134 +imp 'LdrGetKnownDllSectionHandle' LdrGetKnownDllSectionHandle ntdll 135 +imp 'LdrGetProcedureAddress' LdrGetProcedureAddress ntdll 136 4 +imp 'LdrGetProcedureAddressEx' LdrGetProcedureAddressEx ntdll 137 +imp 'LdrGetProcedureAddressForCaller' LdrGetProcedureAddressForCaller ntdll 138 +imp 'LdrInitShimEngineDynamic' LdrInitShimEngineDynamic ntdll 139 +imp 'LdrInitializeEnclave' LdrInitializeEnclave ntdll 140 +imp 'LdrInitializeThunk' LdrInitializeThunk ntdll 141 +imp 'LdrLoadAlternateResourceModule' LdrLoadAlternateResourceModule ntdll 142 +imp 'LdrLoadAlternateResourceModuleEx' LdrLoadAlternateResourceModuleEx ntdll 143 +imp 'LdrLoadDll' LdrLoadDll ntdll 144 4 +imp 'LdrLoadEnclaveModule' LdrLoadEnclaveModule ntdll 145 +imp 'LdrLockLoaderLock' LdrLockLoaderLock ntdll 146 +imp 'LdrOpenImageFileOptionsKey' LdrOpenImageFileOptionsKey ntdll 147 +imp 'LdrProcessInitializationComplete' LdrProcessInitializationComplete ntdll 148 +imp 'LdrProcessRelocationBlock' LdrProcessRelocationBlock ntdll 149 +imp 'LdrProcessRelocationBlockEx' LdrProcessRelocationBlockEx ntdll 150 +imp 'LdrQueryImageFileExecutionOptions' LdrQueryImageFileExecutionOptions ntdll 151 +imp 'LdrQueryImageFileExecutionOptionsEx' LdrQueryImageFileExecutionOptionsEx ntdll 152 +imp 'LdrQueryImageFileKeyOption' LdrQueryImageFileKeyOption ntdll 153 +imp 'LdrQueryModuleServiceTags' LdrQueryModuleServiceTags ntdll 154 +imp 'LdrQueryOptionalDelayLoadedAPI' LdrQueryOptionalDelayLoadedAPI ntdll 155 +imp 'LdrQueryProcessModuleInformation' LdrQueryProcessModuleInformation ntdll 156 +imp 'LdrRegisterDllNotification' LdrRegisterDllNotification ntdll 157 +imp 'LdrRemoveDllDirectory' LdrRemoveDllDirectory ntdll 158 +imp 'LdrRemoveLoadAsDataTable' LdrRemoveLoadAsDataTable ntdll 159 +imp 'LdrResFindResource' LdrResFindResource ntdll 160 +imp 'LdrResFindResourceDirectory' LdrResFindResourceDirectory ntdll 161 +imp 'LdrResGetRCConfig' LdrResGetRCConfig ntdll 162 +imp 'LdrResRelease' LdrResRelease ntdll 163 +imp 'LdrResSearchResource' LdrResSearchResource ntdll 164 +imp 'LdrResolveDelayLoadedAPI' LdrResolveDelayLoadedAPI ntdll 165 +imp 'LdrResolveDelayLoadsFromDll' LdrResolveDelayLoadsFromDll ntdll 166 +imp 'LdrRscIsTypeExist' LdrRscIsTypeExist ntdll 167 +imp 'LdrSetAppCompatDllRedirectionCallback' LdrSetAppCompatDllRedirectionCallback ntdll 168 +imp 'LdrSetDefaultDllDirectories' LdrSetDefaultDllDirectories ntdll 169 +imp 'LdrSetDllDirectory' LdrSetDllDirectory ntdll 170 +imp 'LdrSetDllManifestProber' LdrSetDllManifestProber ntdll 171 +imp 'LdrSetImplicitPathOptions' LdrSetImplicitPathOptions ntdll 172 +imp 'LdrSetMUICacheType' LdrSetMUICacheType ntdll 173 +imp 'LdrShutdownProcess' LdrShutdownProcess ntdll 174 +imp 'LdrShutdownThread' LdrShutdownThread ntdll 175 +imp 'LdrStandardizeSystemPath' LdrStandardizeSystemPath ntdll 176 +imp 'LdrSystemDllInitBlock' LdrSystemDllInitBlock ntdll 177 +imp 'LdrUnloadAlternateResourceModule' LdrUnloadAlternateResourceModule ntdll 178 +imp 'LdrUnloadAlternateResourceModuleEx' LdrUnloadAlternateResourceModuleEx ntdll 179 +imp 'LdrUnloadDll' LdrUnloadDll ntdll 180 1 +imp 'LdrUnlockLoaderLock' LdrUnlockLoaderLock ntdll 181 +imp 'LdrUnregisterDllNotification' LdrUnregisterDllNotification ntdll 182 +imp 'LdrUpdatePackageSearchPath' LdrUpdatePackageSearchPath ntdll 183 +imp 'LdrVerifyImageMatchesChecksum' LdrVerifyImageMatchesChecksum ntdll 184 +imp 'LdrVerifyImageMatchesChecksumEx' LdrVerifyImageMatchesChecksumEx ntdll 185 +imp 'LdrpResGetMappingSize' LdrpResGetMappingSize ntdll 186 +imp 'LdrpResGetResourceDirectory' LdrpResGetResourceDirectory ntdll 187 +imp 'LeaveCriticalPolicySectionInternal' LeaveCriticalPolicySectionInternal KernelBase 968 +imp 'LineDDA' LineDDA gdi32 1742 +imp 'LineTo' LineTo gdi32 1743 +imp 'LoadAcceleratorsA' LoadAcceleratorsA user32 2094 +imp 'LoadAccelerators' LoadAcceleratorsW user32 2095 +imp 'LoadAlterBitmap' LoadAlterBitmap comdlg32 117 +imp 'LoadAppInitDlls' LoadAppInitDlls KernelBase 971 +imp 'LoadBitmapA' LoadBitmapA user32 2096 +imp 'LoadBitmap' LoadBitmapW user32 2097 +imp 'LoadCursorA' LoadCursorA user32 2098 +imp 'LoadCursorFromFileA' LoadCursorFromFileA user32 2099 +imp 'LoadCursorFromFile' LoadCursorFromFileW user32 2100 +imp 'LoadCursor' LoadCursorW user32 2101 +imp 'LoadEnclaveData' LoadEnclaveData KernelBase 972 +imp 'LoadEnclaveImageA' LoadEnclaveImageA KernelBase 973 +imp 'LoadEnclaveImage' LoadEnclaveImageW KernelBase 974 +imp 'LoadIcon' LoadIconW user32 2103 2 +imp 'LoadIconA' LoadIconA user32 2102 2 +imp 'LoadImageA' LoadImageA user32 2104 +imp 'LoadImage' LoadImageW user32 2105 +imp 'LoadKeyboardLayoutA' LoadKeyboardLayoutA user32 2106 +imp 'LoadKeyboardLayoutEx' LoadKeyboardLayoutEx user32 2107 +imp 'LoadKeyboardLayout' LoadKeyboardLayoutW user32 2108 +imp 'LoadLibrary' LoadLibraryW KernelBase 978 1 +imp 'LoadLibraryA' LoadLibraryA KernelBase 975 1 +imp 'LoadLibraryExA' LoadLibraryExA KernelBase 976 3 +imp 'LoadLibraryEx' LoadLibraryExW KernelBase 977 +imp 'LoadLocalFonts' LoadLocalFonts user32 2109 +imp 'LoadMenuA' LoadMenuA user32 2110 +imp 'LoadMenuIndirectA' LoadMenuIndirectA user32 2111 +imp 'LoadMenuIndirect' LoadMenuIndirectW user32 2112 +imp 'LoadMenu' LoadMenuW user32 2113 +imp 'LoadModule' LoadModule kernel32 964 +imp 'LoadPackagedLibrary' LoadPackagedLibrary KernelBase 979 +imp 'LoadRemoteFonts' LoadRemoteFonts user32 2114 +imp 'LoadResource' LoadResource KernelBase 980 2 +imp 'LoadStringA' LoadStringA KernelBase 981 +imp 'LoadStringBaseEx' LoadStringBaseExW KernelBase 982 +imp 'LoadStringBase' LoadStringBaseW kernel32 968 +imp 'LoadStringByReference' LoadStringByReference KernelBase 983 +imp 'LoadString' LoadStringW KernelBase 984 +imp 'LocalAlloc' LocalAlloc KernelBase 985 +imp 'LocalCompact' LocalCompact kernel32 970 +imp 'LocalFileTimeToFileTime' LocalFileTimeToFileTime KernelBase 986 +imp 'LocalFlags' LocalFlags kernel32 972 +imp 'LocalFree' LocalFree KernelBase 987 +imp 'LocalHandle' LocalHandle kernel32 974 +imp 'LocalLock' LocalLock KernelBase 988 +imp 'LocalReAlloc' LocalReAlloc KernelBase 989 +imp 'LocalShrink' LocalShrink kernel32 977 +imp 'LocalSize' LocalSize kernel32 978 +imp 'LocalUnlock' LocalUnlock KernelBase 990 +imp 'LocaleNameToLCID' LocaleNameToLCID KernelBase 991 +imp 'LocateXStateFeature' LocateXStateFeature KernelBase 992 +imp 'LockFile' LockFile KernelBase 993 5 +imp 'LockFileEx' LockFileEx KernelBase 994 6 +imp 'LockResource' LockResource KernelBase 995 1 +imp 'LockServiceDatabase' LockServiceDatabase advapi32 1417 +imp 'LockSetForegroundWindow' LockSetForegroundWindow user32 2117 +imp 'LockWindowStation' LockWindowStation user32 2118 +imp 'LockWindowUpdate' LockWindowUpdate user32 2119 +imp 'LockWorkStation' LockWorkStation user32 2120 +imp 'LogicalToPhysicalPoint' LogicalToPhysicalPoint user32 2121 +imp 'LogicalToPhysicalPointForPerMonitorDPI' LogicalToPhysicalPointForPerMonitorDPI user32 2122 +imp 'LogonUserA' LogonUserA advapi32 1418 +imp 'LogonUserExA' LogonUserExA advapi32 1419 +imp 'LogonUserExEx' LogonUserExExW advapi32 1420 +imp 'LogonUserEx' LogonUserExW advapi32 1421 +imp 'LogonUser' LogonUserW advapi32 1422 +imp 'LookupAccountNameA' LookupAccountNameA advapi32 1423 +imp 'LookupAccountName' LookupAccountNameW advapi32 1424 +imp 'LookupAccountSidA' LookupAccountSidA advapi32 1425 +imp 'LookupAccountSid' LookupAccountSidW advapi32 1426 +imp 'LookupIconIdFromDirectory' LookupIconIdFromDirectory user32 2123 +imp 'LookupIconIdFromDirectoryEx' LookupIconIdFromDirectoryEx user32 2124 +imp 'LookupPrivilegeDisplayNameA' LookupPrivilegeDisplayNameA advapi32 1427 +imp 'LookupPrivilegeDisplayName' LookupPrivilegeDisplayNameW advapi32 1428 +imp 'LookupPrivilegeNameA' LookupPrivilegeNameA advapi32 1429 +imp 'LookupPrivilegeName' LookupPrivilegeNameW advapi32 1430 +imp 'LookupPrivilegeValue' LookupPrivilegeValueW advapi32 1432 3 +imp 'LookupPrivilegeValueA' LookupPrivilegeValueA advapi32 1431 3 +imp 'LookupSecurityDescriptorPartsA' LookupSecurityDescriptorPartsA advapi32 1433 +imp 'LookupSecurityDescriptorParts' LookupSecurityDescriptorPartsW advapi32 1434 +imp 'LpkEditControl' LpkEditControl gdi32 1745 +imp 'LpkGetEditControl' LpkGetEditControl gdi32 1748 +imp 'LpkpEditControlSize' LpkpEditControlSize gdi32 1755 +imp 'LpkpInitializeEditControl' LpkpInitializeEditControl gdi32 1756 +imp 'LsaAddAccountRights' LsaAddAccountRights advapi32 1435 +imp 'LsaAddPrivilegesToAccount' LsaAddPrivilegesToAccount advapi32 1436 +imp 'LsaClearAuditLog' LsaClearAuditLog advapi32 1437 +imp 'LsaClose' LsaClose advapi32 1438 +imp 'LsaCreateAccount' LsaCreateAccount advapi32 1439 +imp 'LsaCreateSecret' LsaCreateSecret advapi32 1440 +imp 'LsaCreateTrustedDomain' LsaCreateTrustedDomain advapi32 1441 +imp 'LsaCreateTrustedDomainEx' LsaCreateTrustedDomainEx advapi32 1442 +imp 'LsaDelete' LsaDelete advapi32 1443 +imp 'LsaDeleteTrustedDomain' LsaDeleteTrustedDomain advapi32 1444 +imp 'LsaEnumerateAccountRights' LsaEnumerateAccountRights advapi32 1445 +imp 'LsaEnumerateAccounts' LsaEnumerateAccounts advapi32 1446 +imp 'LsaEnumerateAccountsWithUserRight' LsaEnumerateAccountsWithUserRight advapi32 1447 +imp 'LsaEnumeratePrivileges' LsaEnumeratePrivileges advapi32 1448 +imp 'LsaEnumeratePrivilegesOfAccount' LsaEnumeratePrivilegesOfAccount advapi32 1449 +imp 'LsaEnumerateTrustedDomains' LsaEnumerateTrustedDomains advapi32 1450 +imp 'LsaEnumerateTrustedDomainsEx' LsaEnumerateTrustedDomainsEx advapi32 1451 +imp 'LsaFreeMemory' LsaFreeMemory advapi32 1452 +imp 'LsaGetAppliedCAPIDs' LsaGetAppliedCAPIDs advapi32 1453 +imp 'LsaGetQuotasForAccount' LsaGetQuotasForAccount advapi32 1454 +imp 'LsaGetRemoteUserName' LsaGetRemoteUserName advapi32 1455 +imp 'LsaGetSystemAccessAccount' LsaGetSystemAccessAccount advapi32 1456 +imp 'LsaGetUserName' LsaGetUserName advapi32 1457 +imp 'LsaICLookupNames' LsaICLookupNames advapi32 1458 +imp 'LsaICLookupNamesWithCreds' LsaICLookupNamesWithCreds advapi32 1459 +imp 'LsaICLookupSids' LsaICLookupSids advapi32 1460 +imp 'LsaICLookupSidsWithCreds' LsaICLookupSidsWithCreds advapi32 1461 +imp 'LsaLookupNames' LsaLookupNames advapi32 1462 +imp 'LsaLookupNames2' LsaLookupNames2 advapi32 1463 +imp 'LsaLookupPrivilegeDisplayName' LsaLookupPrivilegeDisplayName advapi32 1464 +imp 'LsaLookupPrivilegeName' LsaLookupPrivilegeName advapi32 1465 +imp 'LsaLookupPrivilegeValue' LsaLookupPrivilegeValue advapi32 1466 +imp 'LsaLookupSids' LsaLookupSids advapi32 1467 +imp 'LsaLookupSids2' LsaLookupSids2 advapi32 1468 +imp 'LsaManageSidNameMapping' LsaManageSidNameMapping advapi32 1469 +imp 'LsaNtStatusToWinError' LsaNtStatusToWinError advapi32 1470 +imp 'LsaOpenAccount' LsaOpenAccount advapi32 1471 +imp 'LsaOpenPolicy' LsaOpenPolicy advapi32 1472 +imp 'LsaOpenPolicySce' LsaOpenPolicySce advapi32 1473 +imp 'LsaOpenSecret' LsaOpenSecret advapi32 1474 +imp 'LsaOpenTrustedDomain' LsaOpenTrustedDomain advapi32 1475 +imp 'LsaOpenTrustedDomainByName' LsaOpenTrustedDomainByName advapi32 1476 +imp 'LsaQueryCAPs' LsaQueryCAPs advapi32 1477 +imp 'LsaQueryDomainInformationPolicy' LsaQueryDomainInformationPolicy advapi32 1478 +imp 'LsaQueryForestTrustInformation' LsaQueryForestTrustInformation advapi32 1479 +imp 'LsaQueryInfoTrustedDomain' LsaQueryInfoTrustedDomain advapi32 1480 +imp 'LsaQueryInformationPolicy' LsaQueryInformationPolicy advapi32 1481 +imp 'LsaQuerySecret' LsaQuerySecret advapi32 1482 +imp 'LsaQuerySecurityObject' LsaQuerySecurityObject advapi32 1483 +imp 'LsaQueryTrustedDomainInfo' LsaQueryTrustedDomainInfo advapi32 1484 +imp 'LsaQueryTrustedDomainInfoByName' LsaQueryTrustedDomainInfoByName advapi32 1485 +imp 'LsaRemoveAccountRights' LsaRemoveAccountRights advapi32 1486 +imp 'LsaRemovePrivilegesFromAccount' LsaRemovePrivilegesFromAccount advapi32 1487 +imp 'LsaRetrievePrivateData' LsaRetrievePrivateData advapi32 1488 +imp 'LsaSetCAPs' LsaSetCAPs advapi32 1489 +imp 'LsaSetDomainInformationPolicy' LsaSetDomainInformationPolicy advapi32 1490 +imp 'LsaSetForestTrustInformation' LsaSetForestTrustInformation advapi32 1491 +imp 'LsaSetInformationPolicy' LsaSetInformationPolicy advapi32 1492 +imp 'LsaSetInformationTrustedDomain' LsaSetInformationTrustedDomain advapi32 1493 +imp 'LsaSetQuotasForAccount' LsaSetQuotasForAccount advapi32 1494 +imp 'LsaSetSecret' LsaSetSecret advapi32 1495 +imp 'LsaSetSecurityObject' LsaSetSecurityObject advapi32 1496 +imp 'LsaSetSystemAccessAccount' LsaSetSystemAccessAccount advapi32 1497 +imp 'LsaSetTrustedDomainInfoByName' LsaSetTrustedDomainInfoByName advapi32 1498 +imp 'LsaSetTrustedDomainInformation' LsaSetTrustedDomainInformation advapi32 1499 +imp 'LsaStorePrivateData' LsaStorePrivateData advapi32 1500 +imp 'MBToWCSEx' MBToWCSEx user32 2125 +imp 'MBToWCSExt' MBToWCSExt user32 2126 +imp 'MB_GetString' MB_GetString user32 2127 +imp 'MD4Final' MD4Final ntdll 188 +imp 'MD4Init' MD4Init ntdll 189 +imp 'MD4Update' MD4Update ntdll 190 +imp 'MD5Final$nt' MD5Final ntdll 191 +imp 'MD5Init$nt' MD5Init ntdll 192 +imp 'MD5Update$nt' MD5Update ntdll 193 +imp 'MIDL_user_free_Ext' MIDL_user_free_Ext advapi32 1507 +imp 'MIMEAssociationDialogA' MIMEAssociationDialogA url 107 +imp 'MIMEAssociationDialog' MIMEAssociationDialogW url 108 +imp 'MITActivateInputProcessing' MITActivateInputProcessing user32 2128 +imp 'MITBindInputTypeToMonitors' MITBindInputTypeToMonitors user32 2129 +imp 'MITCoreMsgKGetConnectionHandle' MITCoreMsgKGetConnectionHandle user32 2130 +imp 'MITCoreMsgKOpenConnectionTo' MITCoreMsgKOpenConnectionTo user32 2131 +imp 'MITCoreMsgKSend' MITCoreMsgKSend user32 2132 +imp 'MITDeactivateInputProcessing' MITDeactivateInputProcessing user32 2133 +imp 'MITDisableMouseIntercept' MITDisableMouseIntercept user32 2134 +imp 'MITDispatchCompletion' MITDispatchCompletion user32 2135 +imp 'MITEnableMouseIntercept' MITEnableMouseIntercept user32 2136 +imp 'MITGetCursorUpdateHandle' MITGetCursorUpdateHandle user32 2137 +imp 'MITInjectLegacyISMTouchFrame' MITInjectLegacyISMTouchFrame user32 2138 +imp 'MITRegisterManipulationThread' MITRegisterManipulationThread user32 2139 +imp 'MITSetForegroundRoutingInfo' MITSetForegroundRoutingInfo user32 2140 +imp 'MITSetInputCallbacks' MITSetInputCallbacks user32 2141 +imp 'MITSetInputDelegationMode' MITSetInputDelegationMode user32 2142 +imp 'MITSetLastInputRecipient' MITSetLastInputRecipient user32 2143 +imp 'MITSetManipulationInputTarget' MITSetManipulationInputTarget user32 2144 +imp 'MITStopAndEndInertia' MITStopAndEndInertia user32 2145 +imp 'MITSynthesizeMouseInput' MITSynthesizeMouseInput user32 2146 +imp 'MITSynthesizeMouseWheel' MITSynthesizeMouseWheel user32 2147 +imp 'MITSynthesizeTouchInput' MITSynthesizeTouchInput user32 2148 +imp 'MITUpdateInputGlobals' MITUpdateInputGlobals user32 2149 +imp 'MITWaitForMultipleObjectsEx' MITWaitForMultipleObjectsEx user32 2150 +imp 'MSChapSrvChangePassword' MSChapSrvChangePassword advapi32 1508 +imp 'MSChapSrvChangePassword2' MSChapSrvChangePassword2 advapi32 1509 +imp 'MailToProtocolHandler' MailToProtocolHandler url 109 +imp 'MailToProtocolHandlerA' MailToProtocolHandlerA url 110 +imp 'MakeAbsoluteSD' MakeAbsoluteSD KernelBase 996 +imp 'MakeAbsoluteSD2' MakeAbsoluteSD2 KernelBase 997 +imp 'MakeSelfRelativeSD' MakeSelfRelativeSD KernelBase 998 +imp 'MakeThreadTSFEventAware' MakeThreadTSFEventAware user32 2151 +imp 'MapDialogRect' MapDialogRect user32 2152 +imp 'MapGenericMask' MapGenericMask KernelBase 999 2 +imp 'MapPredefinedHandleInternal' MapPredefinedHandleInternal KernelBase 1000 +imp 'MapUserPhysicalPages' MapUserPhysicalPages KernelBase 1001 +imp 'MapUserPhysicalPagesScatter' MapUserPhysicalPagesScatter kernel32 986 +imp 'MapViewOfFile' MapViewOfFile KernelBase 1002 +imp 'MapViewOfFile3' MapViewOfFile3 KernelBase 1003 +imp 'MapViewOfFile3FromApp' MapViewOfFile3FromApp KernelBase 1004 +imp 'MapViewOfFileEx' MapViewOfFileEx KernelBase 1005 +imp 'MapViewOfFileExNuma' MapViewOfFileExNuma KernelBase 1006 7 +imp 'MapViewOfFileFromApp' MapViewOfFileFromApp KernelBase 1007 +imp 'MapViewOfFileNuma2' MapViewOfFileNuma2 KernelBase 1008 +imp 'MapVirtualKeyA' MapVirtualKeyA user32 2153 +imp 'MapVirtualKeyExA' MapVirtualKeyExA user32 2154 +imp 'MapVirtualKeyEx' MapVirtualKeyExW user32 2155 +imp 'MapVirtualKey' MapVirtualKeyW user32 2156 +imp 'MapVisualRelativePoints' MapVisualRelativePoints user32 2157 +imp 'MapWindowPoints' MapWindowPoints user32 2158 +imp 'MaskBlt' MaskBlt gdi32 1757 +imp 'MenuItemFromPoint' MenuItemFromPoint user32 2159 +imp 'MenuWindowProcA' MenuWindowProcA user32 2160 +imp 'MenuWindowProc' MenuWindowProcW user32 2161 +imp 'MessageBeep' MessageBeep user32 2162 +imp 'MessageBox' MessageBoxW user32 2170 4 +imp 'MessageBoxA' MessageBoxA user32 2163 4 +imp 'MessageBoxEx' MessageBoxExW user32 2165 5 +imp 'MessageBoxExA' MessageBoxExA user32 2164 5 +imp 'MessageBoxIndirectA' MessageBoxIndirectA user32 2166 +imp 'MessageBoxIndirect' MessageBoxIndirectW user32 2167 +imp 'MessageBoxTimeoutA' MessageBoxTimeoutA user32 2168 +imp 'MessageBoxTimeout' MessageBoxTimeoutW user32 2169 +imp 'MirrorRgn' MirrorRgn gdi32 1758 +imp 'ModerncoreGdiInit' ModerncoreGdiInit gdi32 1759 +imp 'ModifyMenuA' ModifyMenuA user32 2171 +imp 'ModifyMenu' ModifyMenuW user32 2172 +imp 'ModifyWorldTransform' ModifyWorldTransform gdi32 1760 +imp 'Module32First' Module32FirstW kernel32 992 +imp 'Module32Next' Module32NextW kernel32 994 +imp 'MonitorFromPoint' MonitorFromPoint user32 2173 +imp 'MonitorFromRect' MonitorFromRect user32 2174 +imp 'MonitorFromWindow' MonitorFromWindow user32 2175 +imp 'MoveFile' MoveFileW kernel32 1000 2 +imp 'MoveFileA' MoveFileA kernel32 995 2 +imp 'MoveFileEx' MoveFileExW KernelBase 1009 3 +imp 'MoveFileExA' MoveFileExA kernel32 996 3 +imp 'MoveFileTransactedA' MoveFileTransactedA kernel32 998 +imp 'MoveFileTransacted' MoveFileTransactedW kernel32 999 +imp 'MoveFileWithProgressA' MoveFileWithProgressA kernel32 1001 +imp 'MoveFileWithProgressTransacted' MoveFileWithProgressTransactedW KernelBase 1010 +imp 'MoveFileWithProgress' MoveFileWithProgressW KernelBase 1011 +imp 'MoveToEx' MoveToEx gdi32 1761 +imp 'MoveWindow' MoveWindow user32 2176 6 +imp 'MsgWaitForMultipleObjects' MsgWaitForMultipleObjects user32 2177 +imp 'MsgWaitForMultipleObjectsEx' MsgWaitForMultipleObjectsEx user32 2178 +imp 'MulDiv' MulDiv KernelBase 1012 +imp 'MultiByteToWideChar' MultiByteToWideChar KernelBase 1013 +imp 'NamedEscape' NamedEscape gdi32 1762 +imp 'NamedPipeEventEnum' NamedPipeEventEnum KernelBase 1014 +imp 'NamedPipeEventSelect' NamedPipeEventSelect KernelBase 1015 +imp 'NeedCurrentDirectoryForExePathA' NeedCurrentDirectoryForExePathA KernelBase 1016 +imp 'NeedCurrentDirectoryForExePath' NeedCurrentDirectoryForExePathW KernelBase 1017 +imp 'NetAccessAdd' NetAccessAdd netapi32 71 +imp 'NetAccessDel' NetAccessDel netapi32 72 +imp 'NetAccessEnum' NetAccessEnum netapi32 73 +imp 'NetAccessGetInfo' NetAccessGetInfo netapi32 74 +imp 'NetAccessGetUserPerms' NetAccessGetUserPerms netapi32 75 +imp 'NetAccessSetInfo' NetAccessSetInfo netapi32 76 +imp 'NetAlertRaise' NetAlertRaise netapi32 79 +imp 'NetAlertRaiseEx' NetAlertRaiseEx netapi32 80 +imp 'NetAuditClear' NetAuditClear netapi32 85 +imp 'NetAuditRead' NetAuditRead netapi32 86 +imp 'NetAuditWrite' NetAuditWrite netapi32 87 +imp 'NetConfigGet' NetConfigGet netapi32 88 +imp 'NetConfigGetAll' NetConfigGetAll netapi32 89 +imp 'NetConfigSet' NetConfigSet netapi32 90 +imp 'NetErrorLogClear' NetErrorLogClear netapi32 124 +imp 'NetErrorLogRead' NetErrorLogRead netapi32 125 +imp 'NetErrorLogWrite' NetErrorLogWrite netapi32 126 +imp 'NetMessageBufferSend' NetMessageBufferSend netapi32 161 +imp 'NetMessageNameAdd' NetMessageNameAdd netapi32 162 +imp 'NetMessageNameDel' NetMessageNameDel netapi32 163 +imp 'NetMessageNameEnum' NetMessageNameEnum netapi32 164 +imp 'NetMessageNameGetInfo' NetMessageNameGetInfo netapi32 165 +imp 'NetRegisterDomainNameChangeNotification' NetRegisterDomainNameChangeNotification netapi32 169 +imp 'NetReplExportDirAdd' NetReplExportDirAdd netapi32 175 +imp 'NetReplExportDirDel' NetReplExportDirDel netapi32 176 +imp 'NetReplExportDirEnum' NetReplExportDirEnum netapi32 177 +imp 'NetReplExportDirGetInfo' NetReplExportDirGetInfo netapi32 178 +imp 'NetReplExportDirLock' NetReplExportDirLock netapi32 179 +imp 'NetReplExportDirSetInfo' NetReplExportDirSetInfo netapi32 180 +imp 'NetReplExportDirUnlock' NetReplExportDirUnlock netapi32 181 +imp 'NetReplGetInfo' NetReplGetInfo netapi32 182 +imp 'NetReplImportDirAdd' NetReplImportDirAdd netapi32 183 +imp 'NetReplImportDirDel' NetReplImportDirDel netapi32 184 +imp 'NetReplImportDirEnum' NetReplImportDirEnum netapi32 185 +imp 'NetReplImportDirGetInfo' NetReplImportDirGetInfo netapi32 186 +imp 'NetReplImportDirLock' NetReplImportDirLock netapi32 187 +imp 'NetReplImportDirUnlock' NetReplImportDirUnlock netapi32 188 +imp 'NetReplSetInfo' NetReplSetInfo netapi32 189 +imp 'NetServerEnum' NetServerEnum netapi32 202 +imp 'NetServerEnumEx' NetServerEnumEx netapi32 203 +imp 'NetServiceControl' NetServiceControl netapi32 210 +imp 'NetServiceEnum' NetServiceEnum netapi32 211 +imp 'NetServiceGetInfo' NetServiceGetInfo netapi32 212 +imp 'NetServiceInstall' NetServiceInstall netapi32 213 +imp 'NetStatisticsGet' NetStatisticsGet netapi32 227 +imp 'NetUnregisterDomainNameChangeNotification' NetUnregisterDomainNameChangeNotification netapi32 229 +imp 'NetWkstaGetInfo' NetWkstaGetInfo netapi32 248 +imp 'NetWkstaSetInfo' NetWkstaSetInfo netapi32 249 +imp 'Netbios' Netbios netapi32 257 +imp 'NetpAddTlnFtinfoEntry' NetpAddTlnFtinfoEntry netapi32 258 +imp 'NetpAllocFtinfoEntry' NetpAllocFtinfoEntry netapi32 259 +imp 'NetpAssertFailed' NetpAssertFailed netapi32 260 +imp 'NetpCleanFtinfoContext' NetpCleanFtinfoContext netapi32 261 +imp 'NetpCloseConfigData' NetpCloseConfigData netapi32 262 +imp 'NetpCopyFtinfoContext' NetpCopyFtinfoContext netapi32 263 +imp 'NetpDbgPrint' NetpDbgPrint netapi32 264 +imp 'NetpGetConfigBool' NetpGetConfigBool netapi32 265 +imp 'NetpGetConfigDword' NetpGetConfigDword netapi32 266 +imp 'NetpGetConfigTStrArray' NetpGetConfigTStrArray netapi32 267 +imp 'NetpGetConfigValue' NetpGetConfigValue netapi32 268 +imp 'NetpGetFileSecurity' NetpGetFileSecurity netapi32 269 +imp 'NetpHexDump' NetpHexDump netapi32 270 +imp 'NetpInitFtinfoContext' NetpInitFtinfoContext netapi32 271 +imp 'NetpIsUncComputerNameValid' NetpIsUncComputerNameValid netapi32 273 +imp 'NetpMergeFtinfo' NetpMergeFtinfo netapi32 274 +imp 'NetpNetBiosReset' NetpNetBiosReset netapi32 275 +imp 'NetpNetBiosStatusToApiStatus' NetpNetBiosStatusToApiStatus netapi32 276 +imp 'NetpOpenConfigData' NetpOpenConfigData netapi32 277 +imp 'NetpSetFileSecurity' NetpSetFileSecurity netapi32 278 +imp 'NlsAnsiCodePage' NlsAnsiCodePage ntdll 194 +imp 'NlsCheckPolicy' NlsCheckPolicy KernelBase 1018 +imp 'NlsDispatchAnsiEnumProc' NlsDispatchAnsiEnumProc KernelBase 1019 +imp 'NlsEventDataDescCreate' NlsEventDataDescCreate KernelBase 1020 +imp 'NlsGetACPFromLocale' NlsGetACPFromLocale KernelBase 1021 +imp 'NlsGetCacheUpdateCount' NlsGetCacheUpdateCount KernelBase 1022 +imp 'NlsIsUserDefaultLocale' NlsIsUserDefaultLocale KernelBase 1023 +imp 'NlsMbCodePageTag' NlsMbCodePageTag ntdll 195 +imp 'NlsMbOemCodePageTag' NlsMbOemCodePageTag ntdll 196 +imp 'NlsUpdateLocale' NlsUpdateLocale KernelBase 1024 +imp 'NlsUpdateSystemLocale' NlsUpdateSystemLocale KernelBase 1025 +imp 'NlsValidateLocale' NlsValidateLocale KernelBase 1026 +imp 'NlsWriteEtwEvent' NlsWriteEtwEvent KernelBase 1027 +imp 'NormalizeString' NormalizeString KernelBase 1028 +imp 'NotifyBootConfigStatus' NotifyBootConfigStatus advapi32 1514 +imp 'NotifyChangeEventLog' NotifyChangeEventLog advapi32 1515 +imp 'NotifyMountMgr' NotifyMountMgr KernelBase 1029 +imp 'NotifyOverlayWindow' NotifyOverlayWindow user32 2179 +imp 'NotifyRedirectedStringChange' NotifyRedirectedStringChange KernelBase 1030 +imp 'NotifyServiceStatusChangeA' NotifyServiceStatusChangeA advapi32 1517 +imp 'NotifyServiceStatusChange' NotifyServiceStatusChangeW advapi32 1518 +imp 'NotifyUILanguageChange' NotifyUILanguageChange kernel32 1015 +imp 'NotifyWinEvent' NotifyWinEvent user32 2180 +imp 'NpGetUserName' NpGetUserName advapi32 1519 +imp 'NtAcceptConnectPort' NtAcceptConnectPort ntdll 197 +imp 'NtAccessCheck' NtAccessCheck ntdll 198 +imp 'NtAccessCheckAndAuditAlarm' NtAccessCheckAndAuditAlarm ntdll 199 +imp 'NtAccessCheckByType' NtAccessCheckByType ntdll 200 +imp 'NtAccessCheckByTypeAndAuditAlarm' NtAccessCheckByTypeAndAuditAlarm ntdll 201 +imp 'NtAccessCheckByTypeResultList' NtAccessCheckByTypeResultList ntdll 202 +imp 'NtAccessCheckByTypeResultListAndAuditAlarm' NtAccessCheckByTypeResultListAndAuditAlarm ntdll 203 +imp 'NtAccessCheckByTypeResultListAndAuditAlarmByHandle' NtAccessCheckByTypeResultListAndAuditAlarmByHandle ntdll 204 +imp 'NtAcquireProcessActivityReference' NtAcquireProcessActivityReference ntdll 205 +imp 'NtAddAtom' NtAddAtom ntdll 206 +imp 'NtAddAtomEx' NtAddAtomEx ntdll 207 +imp 'NtAddBootEntry' NtAddBootEntry ntdll 208 +imp 'NtAddDriverEntry' NtAddDriverEntry ntdll 209 +imp 'NtAdjustGroupsToken' NtAdjustGroupsToken ntdll 210 +imp 'NtAdjustPrivilegesToken' NtAdjustPrivilegesToken ntdll 211 +imp 'NtAdjustTokenClaimsAndDeviceGroups' NtAdjustTokenClaimsAndDeviceGroups ntdll 212 +imp 'NtAlertResumeThread' NtAlertResumeThread ntdll 213 +imp 'NtAlertThread' NtAlertThread ntdll 214 +imp 'NtAlertThreadByThreadId' NtAlertThreadByThreadId ntdll 215 +imp 'NtAllocateLocallyUniqueId' NtAllocateLocallyUniqueId ntdll 216 +imp 'NtAllocateReserveObject' NtAllocateReserveObject ntdll 217 +imp 'NtAllocateUserPhysicalPages' NtAllocateUserPhysicalPages ntdll 218 +imp 'NtAllocateUuids' NtAllocateUuids ntdll 219 +imp 'NtAllocateVirtualMemory' NtAllocateVirtualMemory ntdll 220 6 +imp 'NtAllocateVirtualMemoryEx' NtAllocateVirtualMemoryEx ntdll 221 +imp 'NtAlpcAcceptConnectPort' NtAlpcAcceptConnectPort ntdll 222 +imp 'NtAlpcCancelMessage' NtAlpcCancelMessage ntdll 223 +imp 'NtAlpcConnectPort' NtAlpcConnectPort ntdll 224 +imp 'NtAlpcConnectPortEx' NtAlpcConnectPortEx ntdll 225 +imp 'NtAlpcCreatePort' NtAlpcCreatePort ntdll 226 +imp 'NtAlpcCreatePortSection' NtAlpcCreatePortSection ntdll 227 +imp 'NtAlpcCreateResourceReserve' NtAlpcCreateResourceReserve ntdll 228 +imp 'NtAlpcCreateSectionView' NtAlpcCreateSectionView ntdll 229 +imp 'NtAlpcCreateSecurityContext' NtAlpcCreateSecurityContext ntdll 230 +imp 'NtAlpcDeletePortSection' NtAlpcDeletePortSection ntdll 231 +imp 'NtAlpcDeleteResourceReserve' NtAlpcDeleteResourceReserve ntdll 232 +imp 'NtAlpcDeleteSectionView' NtAlpcDeleteSectionView ntdll 233 +imp 'NtAlpcDeleteSecurityContext' NtAlpcDeleteSecurityContext ntdll 234 +imp 'NtAlpcDisconnectPort' NtAlpcDisconnectPort ntdll 235 +imp 'NtAlpcImpersonateClientContainerOfPort' NtAlpcImpersonateClientContainerOfPort ntdll 236 +imp 'NtAlpcImpersonateClientOfPort' NtAlpcImpersonateClientOfPort ntdll 237 +imp 'NtAlpcOpenSenderProcess' NtAlpcOpenSenderProcess ntdll 238 +imp 'NtAlpcOpenSenderThread' NtAlpcOpenSenderThread ntdll 239 +imp 'NtAlpcQueryInformation' NtAlpcQueryInformation ntdll 240 +imp 'NtAlpcQueryInformationMessage' NtAlpcQueryInformationMessage ntdll 241 +imp 'NtAlpcRevokeSecurityContext' NtAlpcRevokeSecurityContext ntdll 242 +imp 'NtAlpcSendWaitReceivePort' NtAlpcSendWaitReceivePort ntdll 243 +imp 'NtAlpcSetInformation' NtAlpcSetInformation ntdll 244 +imp 'NtApphelpCacheControl' NtApphelpCacheControl ntdll 245 +imp 'NtAreMappedFilesTheSame' NtAreMappedFilesTheSame ntdll 246 +imp 'NtAssignProcessToJobObject' NtAssignProcessToJobObject ntdll 247 +imp 'NtAssociateWaitCompletionPacket' NtAssociateWaitCompletionPacket ntdll 248 +imp 'NtCallEnclave' NtCallEnclave ntdll 249 +imp 'NtCallbackReturn' NtCallbackReturn ntdll 250 3 +imp 'NtCancelIoFile' NtCancelIoFile ntdll 251 2 +imp 'NtCancelIoFileEx' NtCancelIoFileEx ntdll 252 +imp 'NtCancelSynchronousIoFile' NtCancelSynchronousIoFile ntdll 253 +imp 'NtCancelTimer' NtCancelTimer ntdll 254 +imp 'NtCancelTimer2' NtCancelTimer2 ntdll 255 +imp 'NtCancelWaitCompletionPacket' NtCancelWaitCompletionPacket ntdll 256 +imp 'NtClearEvent' NtClearEvent ntdll 257 1 +imp 'NtClose' NtClose ntdll 258 1 +imp 'NtCloseObjectAuditAlarm' NtCloseObjectAuditAlarm ntdll 259 +imp 'NtCommitComplete' NtCommitComplete ntdll 260 +imp 'NtCommitEnlistment' NtCommitEnlistment ntdll 261 +imp 'NtCommitRegistryTransaction' NtCommitRegistryTransaction ntdll 262 +imp 'NtCommitTransaction' NtCommitTransaction ntdll 263 +imp 'NtCompactKeys' NtCompactKeys ntdll 264 +imp 'NtCompareObjects' NtCompareObjects ntdll 265 +imp 'NtCompareSigningLevels' NtCompareSigningLevels ntdll 266 +imp 'NtCompareTokens' NtCompareTokens ntdll 267 +imp 'NtCompleteConnectPort' NtCompleteConnectPort ntdll 268 +imp 'NtCompressKey' NtCompressKey ntdll 269 +imp 'NtConnectPort' NtConnectPort ntdll 270 +imp 'NtContinue' NtContinue ntdll 271 2 +imp 'NtConvertBetweenAuxiliaryCounterAndPerformanceCounter' NtConvertBetweenAuxiliaryCounterAndPerformanceCounter ntdll 272 +imp 'NtCreateDebugObject' NtCreateDebugObject ntdll 273 +imp 'NtCreateDirectoryObject' NtCreateDirectoryObject ntdll 274 3 +imp 'NtCreateDirectoryObjectEx' NtCreateDirectoryObjectEx ntdll 275 +imp 'NtCreateEnclave' NtCreateEnclave ntdll 276 +imp 'NtCreateEnlistment' NtCreateEnlistment ntdll 277 +imp 'NtCreateEvent' NtCreateEvent ntdll 278 5 +imp 'NtCreateEventPair' NtCreateEventPair ntdll 279 +imp 'NtCreateFile' NtCreateFile ntdll 280 11 +imp 'NtCreateIRTimer' NtCreateIRTimer ntdll 281 +imp 'NtCreateIoCompletion' NtCreateIoCompletion ntdll 282 4 +imp 'NtCreateJobObject' NtCreateJobObject ntdll 283 +imp 'NtCreateJobSet' NtCreateJobSet ntdll 284 +imp 'NtCreateKey' NtCreateKey ntdll 285 7 +imp 'NtCreateKeyTransacted' NtCreateKeyTransacted ntdll 286 +imp 'NtCreateKeyedEvent' NtCreateKeyedEvent ntdll 287 +imp 'NtCreateLowBoxToken' NtCreateLowBoxToken ntdll 288 +imp 'NtCreateMailslotFile' NtCreateMailslotFile ntdll 289 +imp 'NtCreateMutant' NtCreateMutant ntdll 290 +imp 'NtCreateNamedPipeFile' NtCreateNamedPipeFile ntdll 291 14 +imp 'NtCreatePagingFile' NtCreatePagingFile ntdll 292 +imp 'NtCreatePartition' NtCreatePartition ntdll 293 +imp 'NtCreatePort' NtCreatePort ntdll 294 +imp 'NtCreatePrivateNamespace' NtCreatePrivateNamespace ntdll 295 +imp 'NtCreateProcess' NtCreateProcess ntdll 296 8 +imp 'NtCreateProcessEx' NtCreateProcessEx ntdll 297 +imp 'NtCreateProfile' NtCreateProfile ntdll 298 9 +imp 'NtCreateProfileEx' NtCreateProfileEx ntdll 299 +imp 'NtCreateRegistryTransaction' NtCreateRegistryTransaction ntdll 300 +imp 'NtCreateResourceManager' NtCreateResourceManager ntdll 301 +imp 'NtCreateSection' NtCreateSection ntdll 302 7 +imp 'NtCreateSemaphore' NtCreateSemaphore ntdll 303 +imp 'NtCreateSymbolicLinkObject' NtCreateSymbolicLinkObject ntdll 304 +imp 'NtCreateThread' NtCreateThread ntdll 305 8 +imp 'NtCreateThreadEx' NtCreateThreadEx ntdll 306 +imp 'NtCreateTimer' NtCreateTimer ntdll 307 4 +imp 'NtCreateTimer2' NtCreateTimer2 ntdll 308 +imp 'NtCreateToken' NtCreateToken ntdll 309 +imp 'NtCreateTokenEx' NtCreateTokenEx ntdll 310 +imp 'NtCreateTransaction' NtCreateTransaction ntdll 311 +imp 'NtCreateTransactionManager' NtCreateTransactionManager ntdll 312 +imp 'NtCreateUserProcess' NtCreateUserProcess ntdll 313 +imp 'NtCreateWaitCompletionPacket' NtCreateWaitCompletionPacket ntdll 314 +imp 'NtCreateWaitablePort' NtCreateWaitablePort ntdll 315 +imp 'NtCreateWnfStateName' NtCreateWnfStateName ntdll 316 +imp 'NtCreateWorkerFactory' NtCreateWorkerFactory ntdll 317 +imp 'NtDebugActiveProcess' NtDebugActiveProcess ntdll 318 +imp 'NtDebugContinue' NtDebugContinue ntdll 319 +imp 'NtDelayExecution' NtDelayExecution ntdll 320 2 +imp 'NtDeleteAtom' NtDeleteAtom ntdll 321 +imp 'NtDeleteBootEntry' NtDeleteBootEntry ntdll 322 +imp 'NtDeleteDriverEntry' NtDeleteDriverEntry ntdll 323 +imp 'NtDeleteFile' NtDeleteFile ntdll 324 1 +imp 'NtDeleteKey' NtDeleteKey ntdll 325 1 +imp 'NtDeleteObjectAuditAlarm' NtDeleteObjectAuditAlarm ntdll 326 +imp 'NtDeletePrivateNamespace' NtDeletePrivateNamespace ntdll 327 +imp 'NtDeleteValueKey' NtDeleteValueKey ntdll 328 +imp 'NtDeleteWnfStateData' NtDeleteWnfStateData ntdll 329 +imp 'NtDeleteWnfStateName' NtDeleteWnfStateName ntdll 330 +imp 'NtDeviceIoControlFile' NtDeviceIoControlFile ntdll 331 10 +imp 'NtDisableLastKnownGood' NtDisableLastKnownGood ntdll 332 +imp 'NtDisplayString' NtDisplayString ntdll 333 +imp 'NtDrawText' NtDrawText ntdll 334 +imp 'NtDuplicateObject' NtDuplicateObject ntdll 335 7 +imp 'NtDuplicateToken' NtDuplicateToken ntdll 336 +imp 'NtEnableLastKnownGood' NtEnableLastKnownGood ntdll 337 +imp 'NtEnumerateBootEntries' NtEnumerateBootEntries ntdll 338 +imp 'NtEnumerateDriverEntries' NtEnumerateDriverEntries ntdll 339 +imp 'NtEnumerateKey' NtEnumerateKey ntdll 340 6 +imp 'NtEnumerateSystemEnvironmentValuesEx' NtEnumerateSystemEnvironmentValuesEx ntdll 341 +imp 'NtEnumerateTransactionObject' NtEnumerateTransactionObject ntdll 342 +imp 'NtEnumerateValueKey' NtEnumerateValueKey ntdll 343 6 +imp 'NtExtendSection' NtExtendSection ntdll 344 +imp 'NtFilterBootOption' NtFilterBootOption ntdll 345 +imp 'NtFilterToken' NtFilterToken ntdll 346 +imp 'NtFilterTokenEx' NtFilterTokenEx ntdll 347 +imp 'NtFindAtom' NtFindAtom ntdll 348 +imp 'NtFlushBuffersFile' NtFlushBuffersFile ntdll 349 2 +imp 'NtFlushBuffersFileEx' NtFlushBuffersFileEx ntdll 350 +imp 'NtFlushInstallUILanguage' NtFlushInstallUILanguage ntdll 351 +imp 'NtFlushInstructionCache' NtFlushInstructionCache ntdll 352 3 +imp 'NtFlushKey' NtFlushKey ntdll 353 1 +imp 'NtFlushProcessWriteBuffers' NtFlushProcessWriteBuffers ntdll 354 +imp 'NtFlushVirtualMemory' NtFlushVirtualMemory ntdll 355 4 +imp 'NtFlushWriteBuffer' NtFlushWriteBuffer ntdll 356 +imp 'NtFreeUserPhysicalPages' NtFreeUserPhysicalPages ntdll 357 +imp 'NtFreeVirtualMemory' NtFreeVirtualMemory ntdll 358 4 +imp 'NtFreezeRegistry' NtFreezeRegistry ntdll 359 +imp 'NtFreezeTransactions' NtFreezeTransactions ntdll 360 +imp 'NtFsControlFile' NtFsControlFile ntdll 361 10 +imp 'NtGetCachedSigningLevel' NtGetCachedSigningLevel ntdll 362 +imp 'NtGetCompleteWnfStateSubscription' NtGetCompleteWnfStateSubscription ntdll 363 +imp 'NtGetContextThread' NtGetContextThread ntdll 364 2 +imp 'NtGetCurrentProcessorNumber' NtGetCurrentProcessorNumber ntdll 365 +imp 'NtGetCurrentProcessorNumberEx' NtGetCurrentProcessorNumberEx ntdll 366 +imp 'NtGetDevicePowerState' NtGetDevicePowerState ntdll 367 +imp 'NtGetMUIRegistryInfo' NtGetMUIRegistryInfo ntdll 368 +imp 'NtGetNextProcess' NtGetNextProcess ntdll 369 +imp 'NtGetNextThread' NtGetNextThread ntdll 370 +imp 'NtGetNlsSectionPtr' NtGetNlsSectionPtr ntdll 371 +imp 'NtGetNotificationResourceManager' NtGetNotificationResourceManager ntdll 372 +imp 'NtGetTickCount' NtGetTickCount ntdll 373 +imp 'NtGetWriteWatch' NtGetWriteWatch ntdll 374 +imp 'NtImpersonateAnonymousToken' NtImpersonateAnonymousToken ntdll 375 +imp 'NtImpersonateClientOfPort' NtImpersonateClientOfPort ntdll 376 +imp 'NtImpersonateThread' NtImpersonateThread ntdll 377 +imp 'NtInitializeEnclave' NtInitializeEnclave ntdll 378 +imp 'NtInitializeNlsFiles' NtInitializeNlsFiles ntdll 379 +imp 'NtInitializeRegistry' NtInitializeRegistry ntdll 380 +imp 'NtInitiatePowerAction' NtInitiatePowerAction ntdll 381 +imp 'NtIsProcessInJob' NtIsProcessInJob ntdll 382 +imp 'NtIsSystemResumeAutomatic' NtIsSystemResumeAutomatic ntdll 383 +imp 'NtIsUILanguageComitted' NtIsUILanguageComitted ntdll 384 +imp 'NtListenPort' NtListenPort ntdll 385 +imp 'NtLoadDriver' NtLoadDriver ntdll 386 +imp 'NtLoadEnclaveData' NtLoadEnclaveData ntdll 387 +imp 'NtLoadHotPatch' NtLoadHotPatch ntdll 388 +imp 'NtLoadKey' NtLoadKey ntdll 389 +imp 'NtLoadKey2' NtLoadKey2 ntdll 390 +imp 'NtLoadKeyEx' NtLoadKeyEx ntdll 391 +imp 'NtLockFile' NtLockFile ntdll 392 +imp 'NtLockProductActivationKeys' NtLockProductActivationKeys ntdll 393 +imp 'NtLockRegistryKey' NtLockRegistryKey ntdll 394 +imp 'NtLockVirtualMemory' NtLockVirtualMemory ntdll 395 +imp 'NtMakePermanentObject' NtMakePermanentObject ntdll 396 +imp 'NtMakeTemporaryObject' NtMakeTemporaryObject ntdll 397 +imp 'NtManagePartition' NtManagePartition ntdll 398 +imp 'NtMapCMFModule' NtMapCMFModule ntdll 399 +imp 'NtMapUserPhysicalPages' NtMapUserPhysicalPages ntdll 400 +imp 'NtMapUserPhysicalPagesScatter' NtMapUserPhysicalPagesScatter ntdll 401 +imp 'NtMapViewOfSection' NtMapViewOfSection ntdll 402 10 +imp 'NtMapViewOfSectionEx' NtMapViewOfSectionEx ntdll 403 +imp 'NtModifyBootEntry' NtModifyBootEntry ntdll 404 +imp 'NtModifyDriverEntry' NtModifyDriverEntry ntdll 405 +imp 'NtNotifyChangeDirectoryFile' NtNotifyChangeDirectoryFile ntdll 406 +imp 'NtNotifyChangeDirectoryFileEx' NtNotifyChangeDirectoryFileEx ntdll 407 +imp 'NtNotifyChangeKey' NtNotifyChangeKey ntdll 408 +imp 'NtNotifyChangeMultipleKeys' NtNotifyChangeMultipleKeys ntdll 409 +imp 'NtNotifyChangeSession' NtNotifyChangeSession ntdll 410 +imp 'NtOpenDirectoryObject' NtOpenDirectoryObject ntdll 411 3 +imp 'NtOpenEnlistment' NtOpenEnlistment ntdll 412 +imp 'NtOpenEvent' NtOpenEvent ntdll 413 +imp 'NtOpenEventPair' NtOpenEventPair ntdll 414 +imp 'NtOpenFile' NtOpenFile ntdll 415 6 +imp 'NtOpenIoCompletion' NtOpenIoCompletion ntdll 416 +imp 'NtOpenJobObject' NtOpenJobObject ntdll 417 +imp 'NtOpenKey' NtOpenKey ntdll 418 3 +imp 'NtOpenKeyEx' NtOpenKeyEx ntdll 419 +imp 'NtOpenKeyTransacted' NtOpenKeyTransacted ntdll 420 +imp 'NtOpenKeyTransactedEx' NtOpenKeyTransactedEx ntdll 421 +imp 'NtOpenKeyedEvent' NtOpenKeyedEvent ntdll 422 +imp 'NtOpenMutant' NtOpenMutant ntdll 423 +imp 'NtOpenObjectAuditAlarm' NtOpenObjectAuditAlarm ntdll 424 +imp 'NtOpenPartition' NtOpenPartition ntdll 425 +imp 'NtOpenPrivateNamespace' NtOpenPrivateNamespace ntdll 426 +imp 'NtOpenProcess' NtOpenProcess ntdll 427 4 +imp 'NtOpenProcessToken' NtOpenProcessToken ntdll 428 3 +imp 'NtOpenProcessTokenEx' NtOpenProcessTokenEx ntdll 429 +imp 'NtOpenRegistryTransaction' NtOpenRegistryTransaction ntdll 430 +imp 'NtOpenResourceManager' NtOpenResourceManager ntdll 431 +imp 'NtOpenSection' NtOpenSection ntdll 432 3 +imp 'NtOpenSemaphore' NtOpenSemaphore ntdll 433 +imp 'NtOpenSession' NtOpenSession ntdll 434 +imp 'NtOpenSymbolicLinkObject' NtOpenSymbolicLinkObject ntdll 435 3 +imp 'NtOpenThread' NtOpenThread ntdll 436 4 +imp 'NtOpenThreadToken' NtOpenThreadToken ntdll 437 4 +imp 'NtOpenThreadTokenEx' NtOpenThreadTokenEx ntdll 438 +imp 'NtOpenTimer' NtOpenTimer ntdll 439 +imp 'NtOpenTransaction' NtOpenTransaction ntdll 440 +imp 'NtOpenTransactionManager' NtOpenTransactionManager ntdll 441 +imp 'NtPlugPlayControl' NtPlugPlayControl ntdll 442 +imp 'NtPowerInformation' NtPowerInformation ntdll 443 +imp 'NtPrePrepareComplete' NtPrePrepareComplete ntdll 444 +imp 'NtPrePrepareEnlistment' NtPrePrepareEnlistment ntdll 445 +imp 'NtPrepareComplete' NtPrepareComplete ntdll 446 +imp 'NtPrepareEnlistment' NtPrepareEnlistment ntdll 447 +imp 'NtPrivilegeCheck' NtPrivilegeCheck ntdll 448 +imp 'NtPrivilegeObjectAuditAlarm' NtPrivilegeObjectAuditAlarm ntdll 449 +imp 'NtPrivilegedServiceAuditAlarm' NtPrivilegedServiceAuditAlarm ntdll 450 +imp 'NtPropagationComplete' NtPropagationComplete ntdll 451 +imp 'NtPropagationFailed' NtPropagationFailed ntdll 452 +imp 'NtProtectVirtualMemory' NtProtectVirtualMemory ntdll 453 5 +imp 'NtPulseEvent' NtPulseEvent ntdll 454 +imp 'NtQueryAttributesFile' NtQueryAttributesFile ntdll 455 2 +imp 'NtQueryAuxiliaryCounterFrequency' NtQueryAuxiliaryCounterFrequency ntdll 456 +imp 'NtQueryBootEntryOrder' NtQueryBootEntryOrder ntdll 457 +imp 'NtQueryBootOptions' NtQueryBootOptions ntdll 458 +imp 'NtQueryDebugFilterState' NtQueryDebugFilterState ntdll 459 +imp 'NtQueryDefaultLocale' NtQueryDefaultLocale ntdll 460 +imp 'NtQueryDefaultUILanguage' NtQueryDefaultUILanguage ntdll 461 +imp 'NtQueryDirectoryFile' NtQueryDirectoryFile ntdll 462 11 +imp 'NtQueryDirectoryFileEx' NtQueryDirectoryFileEx ntdll 463 +imp 'NtQueryDirectoryObject' NtQueryDirectoryObject ntdll 464 +imp 'NtQueryDriverEntryOrder' NtQueryDriverEntryOrder ntdll 465 +imp 'NtQueryEaFile' NtQueryEaFile ntdll 466 +imp 'NtQueryEvent' NtQueryEvent ntdll 467 +imp 'NtQueryFullAttributesFile' NtQueryFullAttributesFile ntdll 468 2 +imp 'NtQueryInformationAtom' NtQueryInformationAtom ntdll 469 +imp 'NtQueryInformationByName' NtQueryInformationByName ntdll 470 +imp 'NtQueryInformationEnlistment' NtQueryInformationEnlistment ntdll 471 +imp 'NtQueryInformationFile' NtQueryInformationFile ntdll 472 5 +imp 'NtQueryInformationJobObject' NtQueryInformationJobObject ntdll 473 5 +imp 'NtQueryInformationPort' NtQueryInformationPort ntdll 474 +imp 'NtQueryInformationProcess' NtQueryInformationProcess ntdll 475 5 +imp 'NtQueryInformationResourceManager' NtQueryInformationResourceManager ntdll 476 +imp 'NtQueryInformationThread' NtQueryInformationThread ntdll 477 5 +imp 'NtQueryInformationToken' NtQueryInformationToken ntdll 478 5 +imp 'NtQueryInformationTransaction' NtQueryInformationTransaction ntdll 479 +imp 'NtQueryInformationTransactionManager' NtQueryInformationTransactionManager ntdll 480 +imp 'NtQueryInformationWorkerFactory' NtQueryInformationWorkerFactory ntdll 481 +imp 'NtQueryInstallUILanguage' NtQueryInstallUILanguage ntdll 482 +imp 'NtQueryIntervalProfile' NtQueryIntervalProfile ntdll 483 2 +imp 'NtQueryIoCompletion' NtQueryIoCompletion ntdll 484 +imp 'NtQueryKey' NtQueryKey ntdll 485 +imp 'NtQueryLicenseValue' NtQueryLicenseValue ntdll 486 +imp 'NtQueryMultipleValueKey' NtQueryMultipleValueKey ntdll 487 +imp 'NtQueryMutant' NtQueryMutant ntdll 488 +imp 'NtQueryObject' NtQueryObject ntdll 489 5 +imp 'NtQueryOpenSubKeys' NtQueryOpenSubKeys ntdll 490 +imp 'NtQueryOpenSubKeysEx' NtQueryOpenSubKeysEx ntdll 491 +imp 'NtQueryPerformanceCounter' NtQueryPerformanceCounter ntdll 492 2 +imp 'NtQueryPortInformationProcess' NtQueryPortInformationProcess ntdll 493 +imp 'NtQueryQuotaInformationFile' NtQueryQuotaInformationFile ntdll 494 +imp 'NtQuerySection' NtQuerySection ntdll 495 5 +imp 'NtQuerySecurityAttributesToken' NtQuerySecurityAttributesToken ntdll 496 +imp 'NtQuerySecurityObject' NtQuerySecurityObject ntdll 497 5 +imp 'NtQuerySecurityPolicy' NtQuerySecurityPolicy ntdll 498 +imp 'NtQuerySemaphore' NtQuerySemaphore ntdll 499 +imp 'NtQuerySymbolicLinkObject' NtQuerySymbolicLinkObject ntdll 500 3 +imp 'NtQuerySystemEnvironmentValue' NtQuerySystemEnvironmentValue ntdll 501 +imp 'NtQuerySystemEnvironmentValueEx' NtQuerySystemEnvironmentValueEx ntdll 502 +imp 'NtQuerySystemInformation' NtQuerySystemInformation ntdll 503 4 +imp 'NtQuerySystemInformationEx' NtQuerySystemInformationEx ntdll 504 +imp 'NtQuerySystemTime' NtQuerySystemTime ntdll 505 1 +imp 'NtQueryTimer' NtQueryTimer ntdll 506 +imp 'NtQueryTimerResolution' NtQueryTimerResolution ntdll 507 +imp 'NtQueryValueKey' NtQueryValueKey ntdll 508 6 +imp 'NtQueryVirtualMemory' NtQueryVirtualMemory ntdll 509 6 +imp 'NtQueryVolumeInformationFile' NtQueryVolumeInformationFile ntdll 510 5 +imp 'NtQueryWnfStateData' NtQueryWnfStateData ntdll 511 +imp 'NtQueryWnfStateNameInformation' NtQueryWnfStateNameInformation ntdll 512 +imp 'NtQueueApcThread' NtQueueApcThread ntdll 513 5 +imp 'NtQueueApcThreadEx' NtQueueApcThreadEx ntdll 514 +imp 'NtRaiseException' NtRaiseException ntdll 515 3 +imp 'NtRaiseHardError' NtRaiseHardError ntdll 516 6 +imp 'NtReadFile' NtReadFile ntdll 517 9 +imp 'NtReadFileScatter' NtReadFileScatter ntdll 518 +imp 'NtReadOnlyEnlistment' NtReadOnlyEnlistment ntdll 519 +imp 'NtReadRequestData' NtReadRequestData ntdll 520 +imp 'NtReadVirtualMemory' NtReadVirtualMemory ntdll 521 5 +imp 'NtRecoverEnlistment' NtRecoverEnlistment ntdll 522 +imp 'NtRecoverResourceManager' NtRecoverResourceManager ntdll 523 +imp 'NtRecoverTransactionManager' NtRecoverTransactionManager ntdll 524 +imp 'NtRegisterProtocolAddressInformation' NtRegisterProtocolAddressInformation ntdll 525 +imp 'NtRegisterThreadTerminatePort' NtRegisterThreadTerminatePort ntdll 526 +imp 'NtReleaseKeyedEvent' NtReleaseKeyedEvent ntdll 527 +imp 'NtReleaseMutant' NtReleaseMutant ntdll 528 +imp 'NtReleaseSemaphore' NtReleaseSemaphore ntdll 529 +imp 'NtReleaseWorkerFactoryWorker' NtReleaseWorkerFactoryWorker ntdll 530 +imp 'NtRemoveIoCompletion' NtRemoveIoCompletion ntdll 531 +imp 'NtRemoveIoCompletionEx' NtRemoveIoCompletionEx ntdll 532 +imp 'NtRemoveProcessDebug' NtRemoveProcessDebug ntdll 533 +imp 'NtRenameKey' NtRenameKey ntdll 534 +imp 'NtRenameTransactionManager' NtRenameTransactionManager ntdll 535 +imp 'NtReplaceKey' NtReplaceKey ntdll 536 +imp 'NtReplacePartitionUnit' NtReplacePartitionUnit ntdll 537 +imp 'NtReplyPort' NtReplyPort ntdll 538 +imp 'NtReplyWaitReceivePort' NtReplyWaitReceivePort ntdll 539 +imp 'NtReplyWaitReceivePortEx' NtReplyWaitReceivePortEx ntdll 540 +imp 'NtReplyWaitReplyPort' NtReplyWaitReplyPort ntdll 541 +imp 'NtRequestPort' NtRequestPort ntdll 542 +imp 'NtRequestWaitReplyPort' NtRequestWaitReplyPort ntdll 543 +imp 'NtResetEvent' NtResetEvent ntdll 544 +imp 'NtResetWriteWatch' NtResetWriteWatch ntdll 545 +imp 'NtRestoreKey' NtRestoreKey ntdll 546 +imp 'NtResumeProcess' NtResumeProcess ntdll 547 +imp 'NtResumeThread' NtResumeThread ntdll 548 2 +imp 'NtRevertContainerImpersonation' NtRevertContainerImpersonation ntdll 549 +imp 'NtRollbackComplete' NtRollbackComplete ntdll 550 +imp 'NtRollbackEnlistment' NtRollbackEnlistment ntdll 551 +imp 'NtRollbackRegistryTransaction' NtRollbackRegistryTransaction ntdll 552 +imp 'NtRollbackTransaction' NtRollbackTransaction ntdll 553 +imp 'NtRollforwardTransactionManager' NtRollforwardTransactionManager ntdll 554 +imp 'NtSaveKey' NtSaveKey ntdll 555 +imp 'NtSaveKeyEx' NtSaveKeyEx ntdll 556 +imp 'NtSaveMergedKeys' NtSaveMergedKeys ntdll 557 +imp 'NtSecureConnectPort' NtSecureConnectPort ntdll 558 +imp 'NtSerializeBoot' NtSerializeBoot ntdll 559 +imp 'NtSetBootEntryOrder' NtSetBootEntryOrder ntdll 560 +imp 'NtSetBootOptions' NtSetBootOptions ntdll 561 +imp 'NtSetCachedSigningLevel' NtSetCachedSigningLevel ntdll 562 +imp 'NtSetCachedSigningLevel2' NtSetCachedSigningLevel2 ntdll 563 +imp 'NtSetContextThread' NtSetContextThread ntdll 564 2 +imp 'NtSetDebugFilterState' NtSetDebugFilterState ntdll 565 +imp 'NtSetDefaultHardErrorPort' NtSetDefaultHardErrorPort ntdll 566 +imp 'NtSetDefaultLocale' NtSetDefaultLocale ntdll 567 +imp 'NtSetDefaultUILanguage' NtSetDefaultUILanguage ntdll 568 +imp 'NtSetDriverEntryOrder' NtSetDriverEntryOrder ntdll 569 +imp 'NtSetEaFile' NtSetEaFile ntdll 570 +imp 'NtSetEvent' NtSetEvent ntdll 571 2 +imp 'NtSetEventBoostPriority' NtSetEventBoostPriority ntdll 572 +imp 'NtSetHighEventPair' NtSetHighEventPair ntdll 573 +imp 'NtSetHighWaitLowEventPair' NtSetHighWaitLowEventPair ntdll 574 +imp 'NtSetIRTimer' NtSetIRTimer ntdll 575 +imp 'NtSetInformationDebugObject' NtSetInformationDebugObject ntdll 576 +imp 'NtSetInformationEnlistment' NtSetInformationEnlistment ntdll 577 +imp 'NtSetInformationFile' NtSetInformationFile ntdll 578 5 +imp 'NtSetInformationJobObject' NtSetInformationJobObject ntdll 579 +imp 'NtSetInformationKey' NtSetInformationKey ntdll 580 +imp 'NtSetInformationObject' NtSetInformationObject ntdll 581 +imp 'NtSetInformationProcess' NtSetInformationProcess ntdll 582 +imp 'NtSetInformationResourceManager' NtSetInformationResourceManager ntdll 583 +imp 'NtSetInformationSymbolicLink' NtSetInformationSymbolicLink ntdll 584 +imp 'NtSetInformationThread' NtSetInformationThread ntdll 585 4 +imp 'NtSetInformationToken' NtSetInformationToken ntdll 586 +imp 'NtSetInformationTransaction' NtSetInformationTransaction ntdll 587 +imp 'NtSetInformationTransactionManager' NtSetInformationTransactionManager ntdll 588 +imp 'NtSetInformationVirtualMemory' NtSetInformationVirtualMemory ntdll 589 +imp 'NtSetInformationWorkerFactory' NtSetInformationWorkerFactory ntdll 590 +imp 'NtSetIntervalProfile' NtSetIntervalProfile ntdll 591 2 +imp 'NtSetIoCompletion' NtSetIoCompletion ntdll 592 +imp 'NtSetIoCompletionEx' NtSetIoCompletionEx ntdll 593 +imp 'NtSetLdtEntries' NtSetLdtEntries ntdll 594 +imp 'NtSetLowEventPair' NtSetLowEventPair ntdll 595 +imp 'NtSetLowWaitHighEventPair' NtSetLowWaitHighEventPair ntdll 596 +imp 'NtSetQuotaInformationFile' NtSetQuotaInformationFile ntdll 597 +imp 'NtSetSecurityObject' NtSetSecurityObject ntdll 598 +imp 'NtSetSystemEnvironmentValue' NtSetSystemEnvironmentValue ntdll 599 +imp 'NtSetSystemEnvironmentValueEx' NtSetSystemEnvironmentValueEx ntdll 600 +imp 'NtSetSystemInformation' NtSetSystemInformation ntdll 601 +imp 'NtSetSystemPowerState' NtSetSystemPowerState ntdll 602 +imp 'NtSetSystemTime' NtSetSystemTime ntdll 603 +imp 'NtSetThreadExecutionState' NtSetThreadExecutionState ntdll 604 +imp 'NtSetTimer' NtSetTimer ntdll 605 7 +imp 'NtSetTimer2' NtSetTimer2 ntdll 606 +imp 'NtSetTimerEx' NtSetTimerEx ntdll 607 +imp 'NtSetTimerResolution' NtSetTimerResolution ntdll 608 +imp 'NtSetUuidSeed' NtSetUuidSeed ntdll 609 +imp 'NtSetValueKey' NtSetValueKey ntdll 610 6 +imp 'NtSetVolumeInformationFile' NtSetVolumeInformationFile ntdll 611 +imp 'NtSetWnfProcessNotificationEvent' NtSetWnfProcessNotificationEvent ntdll 612 +imp 'NtShutdownSystem' NtShutdownSystem ntdll 613 +imp 'NtShutdownWorkerFactory' NtShutdownWorkerFactory ntdll 614 +imp 'NtSignalAndWaitForSingleObject' NtSignalAndWaitForSingleObject ntdll 615 4 +imp 'NtSinglePhaseReject' NtSinglePhaseReject ntdll 616 +imp 'NtStartProfile' NtStartProfile ntdll 617 1 +imp 'NtStopProfile' NtStopProfile ntdll 618 1 +imp 'NtSubscribeWnfStateChange' NtSubscribeWnfStateChange ntdll 619 +imp 'NtSuspendProcess' NtSuspendProcess ntdll 620 +imp 'NtSuspendThread' NtSuspendThread ntdll 621 2 +imp 'NtSystemDebugControl' NtSystemDebugControl ntdll 622 +imp 'NtTerminateEnclave' NtTerminateEnclave ntdll 623 +imp 'NtTerminateJobObject' NtTerminateJobObject ntdll 624 +imp 'NtTerminateProcess' NtTerminateProcess ntdll 625 2 +imp 'NtTerminateThread' NtTerminateThread ntdll 626 2 +imp 'NtTestAlert' NtTestAlert ntdll 627 0 +imp 'NtThawRegistry' NtThawRegistry ntdll 628 +imp 'NtThawTransactions' NtThawTransactions ntdll 629 +imp 'NtTraceControl' NtTraceControl ntdll 630 +imp 'NtTraceEvent' NtTraceEvent ntdll 631 +imp 'NtTranslateFilePath' NtTranslateFilePath ntdll 632 +imp 'NtUmsThreadYield' NtUmsThreadYield ntdll 633 +imp 'NtUnloadDriver' NtUnloadDriver ntdll 634 +imp 'NtUnloadKey' NtUnloadKey ntdll 635 +imp 'NtUnloadKey2' NtUnloadKey2 ntdll 636 +imp 'NtUnloadKeyEx' NtUnloadKeyEx ntdll 637 +imp 'NtUnlockFile' NtUnlockFile ntdll 638 +imp 'NtUnlockVirtualMemory' NtUnlockVirtualMemory ntdll 639 +imp 'NtUnmapViewOfSection' NtUnmapViewOfSection ntdll 640 2 +imp 'NtUnmapViewOfSectionEx' NtUnmapViewOfSectionEx ntdll 641 +imp 'NtUnsubscribeWnfStateChange' NtUnsubscribeWnfStateChange ntdll 642 +imp 'NtUpdateWnfStateData' NtUpdateWnfStateData ntdll 643 +imp 'NtVdm64CreateProcessInternal' NtVdm64CreateProcessInternalW kernel32 1016 +imp 'NtVdmControl' NtVdmControl ntdll 644 +imp 'NtWaitForAlertByThreadId' NtWaitForAlertByThreadId ntdll 645 +imp 'NtWaitForDebugEvent' NtWaitForDebugEvent ntdll 646 +imp 'NtWaitForKeyedEvent' NtWaitForKeyedEvent ntdll 647 +imp 'NtWaitForMultipleObjects' NtWaitForMultipleObjects ntdll 648 +imp 'NtWaitForMultipleObjects32' NtWaitForMultipleObjects32 ntdll 649 +imp 'NtWaitForSingleObject' NtWaitForSingleObject ntdll 650 3 +imp 'NtWaitForWorkViaWorkerFactory' NtWaitForWorkViaWorkerFactory ntdll 651 +imp 'NtWaitHighEventPair' NtWaitHighEventPair ntdll 652 +imp 'NtWaitLowEventPair' NtWaitLowEventPair ntdll 653 +imp 'NtWorkerFactoryWorkerReady' NtWorkerFactoryWorkerReady ntdll 654 +imp 'NtWriteFile' NtWriteFile ntdll 655 9 +imp 'NtWriteFileGather' NtWriteFileGather ntdll 656 +imp 'NtWriteRequestData' NtWriteRequestData ntdll 657 +imp 'NtWriteVirtualMemory' NtWriteVirtualMemory ntdll 658 5 +imp 'NtYieldExecution' NtYieldExecution ntdll 659 0 +imp 'NtdllDefWindowProc_A' NtdllDefWindowProc_A ntdll 660 +imp 'NtdllDefWindowProc_W' NtdllDefWindowProc_W ntdll 661 +imp 'NtdllDialogWndProc_A' NtdllDialogWndProc_A ntdll 662 +imp 'NtdllDialogWndProc_W' NtdllDialogWndProc_W ntdll 663 +imp 'OOBEComplete' OOBEComplete kernel32 1017 +imp 'ObjectCloseAuditAlarmA' ObjectCloseAuditAlarmA advapi32 1520 +imp 'ObjectCloseAuditAlarm' ObjectCloseAuditAlarmW KernelBase 1031 +imp 'ObjectDeleteAuditAlarmA' ObjectDeleteAuditAlarmA advapi32 1522 +imp 'ObjectDeleteAuditAlarm' ObjectDeleteAuditAlarmW KernelBase 1032 +imp 'ObjectOpenAuditAlarmA' ObjectOpenAuditAlarmA advapi32 1524 +imp 'ObjectOpenAuditAlarm' ObjectOpenAuditAlarmW KernelBase 1033 +imp 'ObjectPrivilegeAuditAlarmA' ObjectPrivilegeAuditAlarmA advapi32 1526 +imp 'ObjectPrivilegeAuditAlarm' ObjectPrivilegeAuditAlarmW KernelBase 1034 +imp 'OemKeyScan' OemKeyScan user32 2181 +imp 'OemToCharA' OemToCharA user32 2182 +imp 'OemToCharBuffA' OemToCharBuffA user32 2183 +imp 'OemToCharBuff' OemToCharBuffW user32 2184 +imp 'OemToChar' OemToCharW user32 2185 +imp 'OfferVirtualMemory' OfferVirtualMemory KernelBase 1035 3 +imp 'OffsetClipRgn' OffsetClipRgn gdi32 1763 +imp 'OffsetRect' OffsetRect user32 2186 +imp 'OffsetRgn' OffsetRgn gdi32 1764 +imp 'OffsetViewportOrgEx' OffsetViewportOrgEx gdi32 1765 +imp 'OffsetWindowOrgEx' OffsetWindowOrgEx gdi32 1766 +imp 'OpenAs_RunDLL' OpenAs_RunDLL shell32 81 +imp 'OpenAs_RunDLLA' OpenAs_RunDLLA shell32 125 +imp 'OpenAs_RunDLLW' OpenAs_RunDLLW shell32 133 +imp 'OpenBackupEventLogA' OpenBackupEventLogA advapi32 1528 +imp 'OpenBackupEventLog' OpenBackupEventLogW advapi32 1529 +imp 'OpenClipboard' OpenClipboard user32 2187 +imp 'OpenCommPort' OpenCommPort KernelBase 1036 +imp 'OpenConsole' OpenConsoleW kernel32 1019 +imp 'OpenConsoleWStub' OpenConsoleWStub kernel32 1020 +imp 'OpenDesktopA' OpenDesktopA user32 2188 +imp 'OpenDesktop' OpenDesktopW user32 2189 +imp 'OpenEncryptedFileRawA' OpenEncryptedFileRawA advapi32 1530 +imp 'OpenEncryptedFileRaw' OpenEncryptedFileRawW advapi32 1531 +imp 'OpenEventA' OpenEventA KernelBase 1037 +imp 'OpenEventLogA' OpenEventLogA advapi32 1532 +imp 'OpenEventLog' OpenEventLogW advapi32 1533 +imp 'OpenEvent' OpenEventW KernelBase 1038 +imp 'OpenFile' OpenFile kernel32 1023 +imp 'OpenFileById' OpenFileById KernelBase 1039 +imp 'OpenFileMappingA' OpenFileMappingA kernel32 1025 +imp 'OpenFileMappingFromApp' OpenFileMappingFromApp KernelBase 1040 +imp 'OpenFileMapping' OpenFileMappingW KernelBase 1041 +imp 'OpenGlobalizationUserSettingsKey' OpenGlobalizationUserSettingsKey KernelBase 1042 +imp 'OpenIcon' OpenIcon user32 2190 +imp 'OpenInputDesktop' OpenInputDesktop user32 2191 +imp 'OpenJobObjectA' OpenJobObjectA kernel32 1027 +imp 'OpenJobObject' OpenJobObjectW kernel32 1028 +imp 'OpenMutexA' OpenMutexA kernel32 1029 +imp 'OpenMutex' OpenMutexW KernelBase 1043 +imp 'OpenPackageInfoByFullName' OpenPackageInfoByFullName KernelBase 1044 +imp 'OpenPackageInfoByFullNameForUser' OpenPackageInfoByFullNameForUser KernelBase 1045 +imp 'OpenPrivateNamespaceA' OpenPrivateNamespaceA kernel32 1032 +imp 'OpenPrivateNamespace' OpenPrivateNamespaceW KernelBase 1046 +imp 'OpenProcess' OpenProcess KernelBase 1047 3 +imp 'OpenProcessToken' OpenProcessToken KernelBase 1048 3 # NOTE: MSDN says ADVAPI32 but we're not going to add milliseconds of startup latency to every binary that calls access() just for a jump slot +imp 'OpenProfileUserMapping' OpenProfileUserMapping kernel32 1036 # TODO: Do old versions of Windows actually require we get it from there? +imp 'OpenRegKey' OpenRegKey KernelBase 1049 +imp 'OpenRegStream' OpenRegStream shell32 85 +imp 'OpenSCManagerA' OpenSCManagerA advapi32 1535 +imp 'OpenSCManager' OpenSCManagerW advapi32 1536 +imp 'OpenSemaphoreA' OpenSemaphoreA kernel32 1037 +imp 'OpenSemaphore' OpenSemaphoreW KernelBase 1050 +imp 'OpenServiceA' OpenServiceA advapi32 1537 +imp 'OpenService' OpenServiceW advapi32 1538 +imp 'OpenState' OpenState KernelBase 1051 +imp 'OpenStateAtom' OpenStateAtom KernelBase 1052 +imp 'OpenStateExplicit' OpenStateExplicit KernelBase 1053 +imp 'OpenStateExplicitForUserSid' OpenStateExplicitForUserSid KernelBase 1054 +imp 'OpenStateExplicitForUserSidString' OpenStateExplicitForUserSidString KernelBase 1055 +imp 'OpenThread' OpenThread KernelBase 1056 3 +imp 'OpenThreadDesktop' OpenThreadDesktop user32 2192 +imp 'OpenThreadToken' OpenThreadToken KernelBase 1057 +imp 'OpenThreadWaitChainSession' OpenThreadWaitChainSession advapi32 1540 +imp 'OpenTraceA' OpenTraceA advapi32 1541 +imp 'OpenTrace' OpenTraceW advapi32 1542 +imp 'OpenURL' OpenURL url 111 +imp 'OpenURLA' OpenURLA url 112 +imp 'OpenWaitableTimerA' OpenWaitableTimerA kernel32 1043 +imp 'OpenWaitableTimer' OpenWaitableTimerW KernelBase 1058 +imp 'OpenWindowStationA' OpenWindowStationA user32 2193 +imp 'OpenWindowStation' OpenWindowStationW user32 2194 +imp 'OperationEnd' OperationEnd advapi32 1543 +imp 'OperationStart' OperationStart advapi32 1544 +imp 'Options_RunDLL' Options_RunDLL shell32 310 +imp 'Options_RunDLLA' Options_RunDLLA shell32 311 +imp 'Options_RunDLLW' Options_RunDLLW shell32 312 +imp 'OutputDebugStringA' OutputDebugStringA KernelBase 1059 +imp 'OutputDebugString' OutputDebugStringW KernelBase 1060 +imp 'OverrideRoamingDataModificationTimesInRange' OverrideRoamingDataModificationTimesInRange KernelBase 1061 +imp 'PATHOBJ_bEnum' PATHOBJ_bEnum gdi32 1767 +imp 'PATHOBJ_bEnumClipLines' PATHOBJ_bEnumClipLines gdi32 1768 +imp 'PATHOBJ_vEnumStart' PATHOBJ_vEnumStart gdi32 1769 +imp 'PATHOBJ_vEnumStartClipLines' PATHOBJ_vEnumStartClipLines gdi32 1770 +imp 'PATHOBJ_vGetBounds' PATHOBJ_vGetBounds gdi32 1771 +imp 'PackDDElParam' PackDDElParam user32 2195 +imp 'PackTouchHitTestingProximityEvaluation' PackTouchHitTestingProximityEvaluation user32 2196 +imp 'PackageFamilyNameFromFullName' PackageFamilyNameFromFullName KernelBase 1062 +imp 'PackageFamilyNameFromFullNameA' PackageFamilyNameFromFullNameA KernelBase 1063 +imp 'PackageFamilyNameFromId' PackageFamilyNameFromId KernelBase 1064 +imp 'PackageFamilyNameFromIdA' PackageFamilyNameFromIdA KernelBase 1065 +imp 'PackageFamilyNameFromProductId' PackageFamilyNameFromProductId KernelBase 1066 +imp 'PackageFullNameFromId' PackageFullNameFromId KernelBase 1067 +imp 'PackageFullNameFromIdA' PackageFullNameFromIdA KernelBase 1068 +imp 'PackageFullNameFromProductId' PackageFullNameFromProductId KernelBase 1069 +imp 'PackageIdFromFullName' PackageIdFromFullName KernelBase 1070 +imp 'PackageIdFromFullNameA' PackageIdFromFullNameA KernelBase 1071 +imp 'PackageIdFromProductId' PackageIdFromProductId KernelBase 1072 +imp 'PackageNameAndPublisherIdFromFamilyName' PackageNameAndPublisherIdFromFamilyName KernelBase 1073 +imp 'PackageNameAndPublisherIdFromFamilyNameA' PackageNameAndPublisherIdFromFamilyNameA KernelBase 1074 +imp 'PackageRelativeApplicationIdFromProductId' PackageRelativeApplicationIdFromProductId KernelBase 1075 +imp 'PackageSidFromFamilyName' PackageSidFromFamilyName KernelBase 1076 +imp 'PackageSidFromProductId' PackageSidFromProductId KernelBase 1 +imp 'PageSetupDlgA' PageSetupDlgA comdlg32 118 +imp 'PageSetupDlg' PageSetupDlgW comdlg32 119 +imp 'PaintDesktop' PaintDesktop user32 2197 +imp 'PaintMenuBar' PaintMenuBar user32 2198 +imp 'PaintMonitor' PaintMonitor user32 2199 +imp 'PaintRgn' PaintRgn gdi32 1772 +imp 'ParseApplicationUserModelId' ParseApplicationUserModelId KernelBase 1077 +imp 'ParseApplicationUserModelIdA' ParseApplicationUserModelIdA KernelBase 1078 +imp 'ParseURLA' ParseURLA KernelBase 1079 +imp 'ParseURLW' ParseURLW KernelBase 1080 +imp 'PatBlt' PatBlt gdi32 1773 +imp 'PathAddBackslashA' PathAddBackslashA KernelBase 1081 +imp 'PathAddBackslash' PathAddBackslashW KernelBase 1082 +imp 'PathAddExtensionA' PathAddExtensionA KernelBase 1083 +imp 'PathAddExtension' PathAddExtensionW KernelBase 1084 +imp 'PathAllocCanonicalize' PathAllocCanonicalize KernelBase 1085 +imp 'PathAllocCombine' PathAllocCombine KernelBase 1086 +imp 'PathAppendA' PathAppendA KernelBase 1087 +imp 'PathAppend' PathAppendW KernelBase 1088 +imp 'PathCanonicalizeA' PathCanonicalizeA KernelBase 1089 +imp 'PathCanonicalize' PathCanonicalizeW KernelBase 1090 +imp 'PathCchAddBackslash' PathCchAddBackslash KernelBase 1091 +imp 'PathCchAddBackslashEx' PathCchAddBackslashEx KernelBase 1092 +imp 'PathCchAddExtension' PathCchAddExtension KernelBase 1093 +imp 'PathCchAppend' PathCchAppend KernelBase 1094 +imp 'PathCchAppendEx' PathCchAppendEx KernelBase 1095 +imp 'PathCchCanonicalize' PathCchCanonicalize KernelBase 1096 +imp 'PathCchCanonicalizeEx' PathCchCanonicalizeEx KernelBase 1097 +imp 'PathCchCombine' PathCchCombine KernelBase 1098 +imp 'PathCchCombineEx' PathCchCombineEx KernelBase 1099 +imp 'PathCchFindExtension' PathCchFindExtension KernelBase 1100 +imp 'PathCchIsRoot' PathCchIsRoot KernelBase 1101 +imp 'PathCchRemoveBackslash' PathCchRemoveBackslash KernelBase 1102 +imp 'PathCchRemoveBackslashEx' PathCchRemoveBackslashEx KernelBase 1103 +imp 'PathCchRemoveExtension' PathCchRemoveExtension KernelBase 1104 +imp 'PathCchRemoveFileSpec' PathCchRemoveFileSpec KernelBase 1105 +imp 'PathCchRenameExtension' PathCchRenameExtension KernelBase 1106 +imp 'PathCchSkipRoot' PathCchSkipRoot KernelBase 1107 +imp 'PathCchStripPrefix' PathCchStripPrefix KernelBase 1108 +imp 'PathCchStripToRoot' PathCchStripToRoot KernelBase 1109 +imp 'PathCleanupSpec' PathCleanupSpec shell32 171 +imp 'PathCombineA' PathCombineA KernelBase 1110 +imp 'PathCombine' PathCombineW KernelBase 1111 +imp 'PathCommonPrefixA' PathCommonPrefixA KernelBase 1112 +imp 'PathCommonPrefix' PathCommonPrefixW KernelBase 1113 +imp 'PathCreateFromUrlA' PathCreateFromUrlA KernelBase 1114 +imp 'PathCreateFromUrlAlloc' PathCreateFromUrlAlloc KernelBase 1115 +imp 'PathCreateFromUrl' PathCreateFromUrlW KernelBase 1116 +imp 'PathFileExistsA' PathFileExistsA KernelBase 1117 +imp 'PathFileExists' PathFileExistsW KernelBase 1118 +imp 'PathFindExtensionA' PathFindExtensionA KernelBase 1119 +imp 'PathFindExtension' PathFindExtensionW KernelBase 1120 +imp 'PathFindFileNameA' PathFindFileNameA KernelBase 1121 +imp 'PathFindFileName' PathFindFileNameW KernelBase 1122 +imp 'PathFindNextComponentA' PathFindNextComponentA KernelBase 1123 +imp 'PathFindNextComponent' PathFindNextComponentW KernelBase 1124 +imp 'PathGetArgsA' PathGetArgsA KernelBase 1125 +imp 'PathGetArgs' PathGetArgsW KernelBase 1126 +imp 'PathGetCharTypeA' PathGetCharTypeA KernelBase 1127 +imp 'PathGetCharType' PathGetCharTypeW KernelBase 1128 +imp 'PathGetDriveNumberA' PathGetDriveNumberA KernelBase 1129 +imp 'PathGetDriveNumber' PathGetDriveNumberW KernelBase 1130 +imp 'PathGetShortPath' PathGetShortPath shell32 92 +imp 'PathIsExe' PathIsExe shell32 43 +imp 'PathIsFileSpecA' PathIsFileSpecA KernelBase 1131 +imp 'PathIsFileSpec' PathIsFileSpecW KernelBase 1132 +imp 'PathIsLFNFileSpecA' PathIsLFNFileSpecA KernelBase 1133 +imp 'PathIsLFNFileSpec' PathIsLFNFileSpecW KernelBase 1134 +imp 'PathIsPrefixA' PathIsPrefixA KernelBase 1135 +imp 'PathIsPrefix' PathIsPrefixW KernelBase 1136 +imp 'PathIsRelativeA' PathIsRelativeA KernelBase 1137 +imp 'PathIsRelative' PathIsRelativeW KernelBase 1138 +imp 'PathIsRootA' PathIsRootA KernelBase 1139 +imp 'PathIsRoot' PathIsRootW KernelBase 1140 +imp 'PathIsSameRootA' PathIsSameRootA KernelBase 1141 +imp 'PathIsSameRoot' PathIsSameRootW KernelBase 1142 +imp 'PathIsSlowA' PathIsSlowA shell32 240 +imp 'PathIsSlow' PathIsSlowW shell32 239 +imp 'PathIsUNCA' PathIsUNCA KernelBase 1143 +imp 'PathIsUNCEx' PathIsUNCEx KernelBase 1144 +imp 'PathIsUNCServerA' PathIsUNCServerA KernelBase 1145 +imp 'PathIsUNCServerShareA' PathIsUNCServerShareA KernelBase 1146 +imp 'PathIsUNCServerShare' PathIsUNCServerShareW KernelBase 1147 +imp 'PathIsUNCServer' PathIsUNCServerW KernelBase 1148 +imp 'PathIsUNCW' PathIsUNCW KernelBase 1149 +imp 'PathIsURLA' PathIsURLA KernelBase 1150 +imp 'PathIsURLW' PathIsURLW KernelBase 1151 +imp 'PathIsValidCharA' PathIsValidCharA KernelBase 1152 +imp 'PathIsValidChar' PathIsValidCharW KernelBase 1153 +imp 'PathMakeUniqueName' PathMakeUniqueName shell32 47 +imp 'PathMatchSpecA' PathMatchSpecA KernelBase 1154 +imp 'PathMatchSpecExA' PathMatchSpecExA KernelBase 1155 +imp 'PathMatchSpecEx' PathMatchSpecExW KernelBase 1156 +imp 'PathMatchSpec' PathMatchSpecW KernelBase 1157 +imp 'PathParseIconLocationA' PathParseIconLocationA KernelBase 1158 +imp 'PathParseIconLocation' PathParseIconLocationW KernelBase 1159 +imp 'PathQualify' PathQualify shell32 49 +imp 'PathQuoteSpacesA' PathQuoteSpacesA KernelBase 1160 +imp 'PathQuoteSpaces' PathQuoteSpacesW KernelBase 1161 +imp 'PathRelativePathToA' PathRelativePathToA KernelBase 1162 +imp 'PathRelativePathTo' PathRelativePathToW KernelBase 1163 +imp 'PathRemoveBackslashA' PathRemoveBackslashA KernelBase 1164 +imp 'PathRemoveBackslash' PathRemoveBackslashW KernelBase 1165 +imp 'PathRemoveBlanksA' PathRemoveBlanksA KernelBase 1166 +imp 'PathRemoveBlanks' PathRemoveBlanksW KernelBase 1167 +imp 'PathRemoveExtensionA' PathRemoveExtensionA KernelBase 1168 +imp 'PathRemoveExtension' PathRemoveExtensionW KernelBase 1169 +imp 'PathRemoveFileSpecA' PathRemoveFileSpecA KernelBase 1170 +imp 'PathRemoveFileSpec' PathRemoveFileSpecW KernelBase 1171 +imp 'PathRenameExtensionA' PathRenameExtensionA KernelBase 1172 +imp 'PathRenameExtension' PathRenameExtensionW KernelBase 1173 +imp 'PathResolve' PathResolve shell32 51 +imp 'PathSearchAndQualifyA' PathSearchAndQualifyA KernelBase 1174 +imp 'PathSearchAndQualify' PathSearchAndQualifyW KernelBase 1175 +imp 'PathSkipRootA' PathSkipRootA KernelBase 1176 +imp 'PathSkipRoot' PathSkipRootW KernelBase 1177 +imp 'PathStripPathA' PathStripPathA KernelBase 1178 +imp 'PathStripPath' PathStripPathW KernelBase 1179 +imp 'PathStripToRootA' PathStripToRootA KernelBase 1180 +imp 'PathStripToRoot' PathStripToRootW KernelBase 1181 +imp 'PathToRegion' PathToRegion gdi32 1774 +imp 'PathUnExpandEnvStringsA' PathUnExpandEnvStringsA KernelBase 1182 +imp 'PathUnExpandEnvStrings' PathUnExpandEnvStringsW KernelBase 1183 +imp 'PathUnquoteSpacesA' PathUnquoteSpacesA KernelBase 1184 +imp 'PathUnquoteSpaces' PathUnquoteSpacesW KernelBase 1185 +imp 'PathYetAnotherMakeUniqueName' PathYetAnotherMakeUniqueName shell32 75 +imp 'PcwAddQueryItem' PcwAddQueryItem KernelBase 1186 +imp 'PcwClearCounterSetSecurity' PcwClearCounterSetSecurity KernelBase 1187 +imp 'PcwCollectData' PcwCollectData KernelBase 1188 +imp 'PcwCompleteNotification' PcwCompleteNotification KernelBase 1189 +imp 'PcwCreateNotifier' PcwCreateNotifier KernelBase 1190 +imp 'PcwCreateQuery' PcwCreateQuery KernelBase 1191 +imp 'PcwDisconnectCounterSet' PcwDisconnectCounterSet KernelBase 1192 +imp 'PcwEnumerateInstances' PcwEnumerateInstances KernelBase 1193 +imp 'PcwIsNotifierAlive' PcwIsNotifierAlive KernelBase 1194 +imp 'PcwQueryCounterSetSecurity' PcwQueryCounterSetSecurity KernelBase 1195 +imp 'PcwReadNotificationData' PcwReadNotificationData KernelBase 1196 +imp 'PcwRegisterCounterSet' PcwRegisterCounterSet KernelBase 1197 +imp 'PcwRemoveQueryItem' PcwRemoveQueryItem KernelBase 1198 +imp 'PcwSendNotification' PcwSendNotification KernelBase 1199 +imp 'PcwSendStatelessNotification' PcwSendStatelessNotification KernelBase 1200 +imp 'PcwSetCounterSetSecurity' PcwSetCounterSetSecurity KernelBase 1201 +imp 'PcwSetQueryItemUserData' PcwSetQueryItemUserData KernelBase 1202 +imp 'PeekConsoleInput' PeekConsoleInputW KernelBase 1204 4 +imp 'PeekConsoleInputA' PeekConsoleInputA KernelBase 1203 4 +imp 'PeekMessageA' PeekMessageA user32 2200 +imp 'PeekMessage' PeekMessageW user32 2201 +imp 'PeekNamedPipe' PeekNamedPipe KernelBase 1205 6 +imp 'PerfAddCounters' PerfAddCounters advapi32 1545 +imp 'PerfCloseQueryHandle' PerfCloseQueryHandle advapi32 1546 +imp 'PerfCreateInstance' PerfCreateInstance KernelBase 1206 +imp 'PerfDecrementULongCounterValue' PerfDecrementULongCounterValue KernelBase 1207 +imp 'PerfDecrementULongLongCounterValue' PerfDecrementULongLongCounterValue KernelBase 1208 +imp 'PerfDeleteCounters' PerfDeleteCounters advapi32 1550 +imp 'PerfDeleteInstance' PerfDeleteInstance KernelBase 1209 +imp 'PerfEnumerateCounterSet' PerfEnumerateCounterSet advapi32 1552 +imp 'PerfEnumerateCounterSetInstances' PerfEnumerateCounterSetInstances advapi32 1553 +imp 'PerfIncrementULongCounterValue' PerfIncrementULongCounterValue KernelBase 1210 +imp 'PerfIncrementULongLongCounterValue' PerfIncrementULongLongCounterValue KernelBase 1211 +imp 'PerfOpenQueryHandle' PerfOpenQueryHandle advapi32 1556 +imp 'PerfQueryCounterData' PerfQueryCounterData advapi32 1557 +imp 'PerfQueryCounterInfo' PerfQueryCounterInfo advapi32 1558 +imp 'PerfQueryCounterSetRegistrationInfo' PerfQueryCounterSetRegistrationInfo advapi32 1559 +imp 'PerfQueryInstance' PerfQueryInstance KernelBase 1212 +imp 'PerfRegCloseKey' PerfRegCloseKey advapi32 1561 +imp 'PerfRegEnumKey' PerfRegEnumKey advapi32 1562 +imp 'PerfRegEnumValue' PerfRegEnumValue advapi32 1563 +imp 'PerfRegQueryInfoKey' PerfRegQueryInfoKey advapi32 1564 +imp 'PerfRegQueryValue' PerfRegQueryValue advapi32 1565 +imp 'PerfRegSetValue' PerfRegSetValue advapi32 1566 +imp 'PerfSetCounterRefValue' PerfSetCounterRefValue KernelBase 1213 +imp 'PerfSetCounterSetInfo' PerfSetCounterSetInfo KernelBase 1214 +imp 'PerfSetULongCounterValue' PerfSetULongCounterValue KernelBase 1215 +imp 'PerfSetULongLongCounterValue' PerfSetULongLongCounterValue KernelBase 1216 +imp 'PerfStartProvider' PerfStartProvider KernelBase 1217 +imp 'PerfStartProviderEx' PerfStartProviderEx KernelBase 1218 +imp 'PerfStopProvider' PerfStopProvider KernelBase 1219 +imp 'PfxFindPrefix' PfxFindPrefix ntdll 664 +imp 'PfxInitialize' PfxInitialize ntdll 665 +imp 'PfxInsertPrefix' PfxInsertPrefix ntdll 666 +imp 'PfxRemovePrefix' PfxRemovePrefix ntdll 667 +imp 'PhysicalToLogicalPoint' PhysicalToLogicalPoint user32 2202 +imp 'PhysicalToLogicalPointForPerMonitorDPI' PhysicalToLogicalPointForPerMonitorDPI user32 2203 +imp 'PickIconDlg' PickIconDlg shell32 62 +imp 'Pie' Pie gdi32 1775 +imp 'PifMgr_CloseProperties' PifMgr_CloseProperties shell32 13 +imp 'PifMgr_GetProperties' PifMgr_GetProperties shell32 10 +imp 'PifMgr_OpenProperties' PifMgr_OpenProperties shell32 9 +imp 'PifMgr_SetProperties' PifMgr_SetProperties shell32 11 +imp 'PlayEnhMetaFile' PlayEnhMetaFile gdi32 1776 +imp 'PlayEnhMetaFileRecord' PlayEnhMetaFileRecord gdi32 1777 +imp 'PlayMetaFile' PlayMetaFile gdi32 1778 +imp 'PlayMetaFileRecord' PlayMetaFileRecord gdi32 1779 +imp 'PlgBlt' PlgBlt gdi32 1780 +imp 'PolyBezier' PolyBezier gdi32 1781 +imp 'PolyBezierTo' PolyBezierTo gdi32 1782 +imp 'PolyDraw' PolyDraw gdi32 1783 +imp 'PolyPatBlt' PolyPatBlt gdi32 1784 +imp 'PolyPolygon' PolyPolygon gdi32 1785 +imp 'PolyPolyline' PolyPolyline gdi32 1786 +imp 'PolyTextOutA' PolyTextOutA gdi32 1787 +imp 'PolyTextOut' PolyTextOutW gdi32 1788 +imp 'Polygon' Polygon gdi32 1789 +imp 'Polyline' Polyline gdi32 1790 +imp 'PolylineTo' PolylineTo gdi32 1791 +imp 'PoolPerAppKeyStateInternal' PoolPerAppKeyStateInternal KernelBase 1220 +imp 'PostMessageA' PostMessageA user32 2204 +imp 'PostMessage' PostMessageW user32 2205 +imp 'PostQueuedCompletionStatus' PostQueuedCompletionStatus KernelBase 1221 +imp 'PostQuitMessage' PostQuitMessage user32 2206 1 +imp 'PostThreadMessageA' PostThreadMessageA user32 2207 +imp 'PostThreadMessage' PostThreadMessageW user32 2208 +imp 'PowerClearRequest' PowerClearRequest kernel32 1057 +imp 'PowerCreateRequest' PowerCreateRequest kernel32 1058 +imp 'PowerSetRequest' PowerSetRequest kernel32 1059 +imp 'PrefetchVirtualMemory' PrefetchVirtualMemory KernelBase 1222 4 +imp 'PrepareDiscForBurnRunDll' PrepareDiscForBurnRunDllW shell32 135 +imp 'PrepareTape' PrepareTape kernel32 1061 +imp 'PrintDlgA' PrintDlgA comdlg32 120 +imp 'PrintDlgExA' PrintDlgExA comdlg32 121 +imp 'PrintDlgEx' PrintDlgExW comdlg32 122 +imp 'PrintDlg' PrintDlgW comdlg32 123 +imp 'PrintWindow' PrintWindow user32 2209 +imp 'PrintersGetCommand_RunDLL' PrintersGetCommand_RunDLL shell32 138 +imp 'PrintersGetCommand_RunDLLA' PrintersGetCommand_RunDLLA shell32 139 +imp 'PrintersGetCommand_RunDLLW' PrintersGetCommand_RunDLLW shell32 150 +imp 'PrivCopyFileEx' PrivCopyFileExW KernelBase 1223 +imp 'PrivMoveFileIdentity' PrivMoveFileIdentityW kernel32 1063 +imp 'PrivateExtractIconExA' PrivateExtractIconExA user32 2210 +imp 'PrivateExtractIconEx' PrivateExtractIconExW user32 2211 +imp 'PrivateExtractIconsA' PrivateExtractIconsA user32 2212 +imp 'PrivateExtractIcons' PrivateExtractIconsW user32 2213 +imp 'PrivateRegisterICSProc' PrivateRegisterICSProc user32 2214 +imp 'PrivilegeCheck' PrivilegeCheck KernelBase 1224 +imp 'PrivilegedServiceAuditAlarmA' PrivilegedServiceAuditAlarmA advapi32 1575 +imp 'PrivilegedServiceAuditAlarm' PrivilegedServiceAuditAlarmW KernelBase 1225 +imp 'Process32First' Process32FirstW kernel32 1065 +imp 'Process32Next' Process32NextW kernel32 1067 +imp 'ProcessIdToSessionId' ProcessIdToSessionId KernelBase 1226 +imp 'ProcessIdleTasks' ProcessIdleTasksW advapi32 1578 +imp 'ProcessTrace' ProcessTrace advapi32 1579 +imp 'ProductIdFromPackageFamilyName' ProductIdFromPackageFamilyName KernelBase 1227 +imp 'PsmCreateKey' PsmCreateKey KernelBase 1228 +imp 'PsmCreateKeyWithDynamicId' PsmCreateKeyWithDynamicId KernelBase 1229 +imp 'PsmEqualApplication' PsmEqualApplication KernelBase 1230 +imp 'PsmEqualPackage' PsmEqualPackage KernelBase 1231 +imp 'PsmGetApplicationNameFromKey' PsmGetApplicationNameFromKey KernelBase 1232 +imp 'PsmGetKeyFromProcess' PsmGetKeyFromProcess KernelBase 1233 +imp 'PsmGetKeyFromToken' PsmGetKeyFromToken KernelBase 1234 +imp 'PsmGetPackageFullNameFromKey' PsmGetPackageFullNameFromKey KernelBase 1235 +imp 'PsmIsChildKey' PsmIsChildKey KernelBase 1236 +imp 'PsmIsDynamicKey' PsmIsDynamicKey KernelBase 1237 +imp 'PsmIsValidKey' PsmIsValidKey KernelBase 1238 +imp 'PssCaptureSnapshot' PssCaptureSnapshot KernelBase 1239 +imp 'PssDuplicateSnapshot' PssDuplicateSnapshot KernelBase 1240 +imp 'PssFreeSnapshot' PssFreeSnapshot KernelBase 1241 +imp 'PssNtCaptureSnapshot' PssNtCaptureSnapshot ntdll 668 +imp 'PssNtDuplicateSnapshot' PssNtDuplicateSnapshot ntdll 669 +imp 'PssNtFreeRemoteSnapshot' PssNtFreeRemoteSnapshot ntdll 670 +imp 'PssNtFreeSnapshot' PssNtFreeSnapshot ntdll 671 +imp 'PssNtFreeWalkMarker' PssNtFreeWalkMarker ntdll 672 +imp 'PssNtQuerySnapshot' PssNtQuerySnapshot ntdll 673 +imp 'PssNtValidateDescriptor' PssNtValidateDescriptor ntdll 674 +imp 'PssNtWalkSnapshot' PssNtWalkSnapshot ntdll 675 +imp 'PssQuerySnapshot' PssQuerySnapshot KernelBase 1242 +imp 'PssWalkMarkerCreate' PssWalkMarkerCreate KernelBase 1243 +imp 'PssWalkMarkerFree' PssWalkMarkerFree KernelBase 1244 +imp 'PssWalkMarkerGetPosition' PssWalkMarkerGetPosition KernelBase 1245 +imp 'PssWalkMarkerRewind' PssWalkMarkerRewind kernel32 1076 +imp 'PssWalkMarkerSeek' PssWalkMarkerSeek kernel32 1077 +imp 'PssWalkMarkerSeekToBeginning' PssWalkMarkerSeekToBeginning KernelBase 1246 +imp 'PssWalkMarkerSetPosition' PssWalkMarkerSetPosition KernelBase 1247 +imp 'PssWalkMarkerTell' PssWalkMarkerTell kernel32 1080 +imp 'PssWalkSnapshot' PssWalkSnapshot KernelBase 1248 +imp 'PtInRect' PtInRect user32 2215 +imp 'PtInRegion' PtInRegion gdi32 1792 +imp 'PtVisible' PtVisible gdi32 1793 +imp 'PublishStateChangeNotification' PublishStateChangeNotification KernelBase 1249 +imp 'PulseEvent' PulseEvent KernelBase 1250 1 +imp 'PurgeComm' PurgeComm KernelBase 1251 +imp 'QISearch' QISearch KernelBase 1252 +imp 'QueryActCtxSettings' QueryActCtxSettingsW KernelBase 1253 +imp 'QueryActCtxSettingsWWorker' QueryActCtxSettingsWWorker kernel32 1085 +imp 'QueryActCtx' QueryActCtxW KernelBase 1254 +imp 'QueryActCtxWWorker' QueryActCtxWWorker kernel32 1087 +imp 'QueryAllTracesA' QueryAllTracesA advapi32 1580 +imp 'QueryAllTraces' QueryAllTracesW advapi32 1581 +imp 'QueryAuxiliaryCounterFrequency' QueryAuxiliaryCounterFrequency KernelBase 1255 +imp 'QueryBSDRWindow' QueryBSDRWindow user32 2216 +imp 'QueryDisplayConfig' QueryDisplayConfig user32 2217 +imp 'QueryDosDeviceA' QueryDosDeviceA kernel32 1089 +imp 'QueryDosDevice' QueryDosDeviceW KernelBase 1257 +imp 'QueryFontAssocStatus' QueryFontAssocStatus gdi32 1794 +imp 'QueryFullProcessImageNameA' QueryFullProcessImageNameA KernelBase 1258 +imp 'QueryFullProcessImageName' QueryFullProcessImageNameW KernelBase 1259 +imp 'QueryIdleProcessorCycleTime' QueryIdleProcessorCycleTime KernelBase 1260 +imp 'QueryIdleProcessorCycleTimeEx' QueryIdleProcessorCycleTimeEx KernelBase 1261 +imp 'QueryInformationJobObject' QueryInformationJobObject kernel32 1095 +imp 'QueryInterruptTime' QueryInterruptTime KernelBase 1262 +imp 'QueryInterruptTimePrecise' QueryInterruptTimePrecise KernelBase 1263 +imp 'QueryIoRateControlInformationJobObject' QueryIoRateControlInformationJobObject kernel32 1096 +imp 'QueryLocalUserServiceName' QueryLocalUserServiceName advapi32 1582 +imp 'QueryMemoryResourceNotification' QueryMemoryResourceNotification KernelBase 1264 +imp 'QueryOptionalDelayLoadedAPI' QueryOptionalDelayLoadedAPI KernelBase 1265 +imp 'QueryPerformanceCounter' QueryPerformanceCounter kernel32 1098 +imp 'QueryPerformanceFrequency' QueryPerformanceFrequency kernel32 1099 +imp 'QueryProcessAffinityUpdateMode' QueryProcessAffinityUpdateMode KernelBase 1268 +imp 'QueryProcessCycleTime' QueryProcessCycleTime KernelBase 1269 +imp 'QueryProtectedPolicy' QueryProtectedPolicy KernelBase 1270 +imp 'QueryRecoveryAgentsOnEncryptedFile' QueryRecoveryAgentsOnEncryptedFile advapi32 1583 +imp 'QuerySecurityAccessMask' QuerySecurityAccessMask KernelBase 1271 +imp 'QuerySendMessage' QuerySendMessage user32 2218 +imp 'QueryServiceConfig2A' QueryServiceConfig2A advapi32 1585 +imp 'QueryServiceConfig2W' QueryServiceConfig2W advapi32 1586 +imp 'QueryServiceConfigA' QueryServiceConfigA advapi32 1587 +imp 'QueryServiceConfig' QueryServiceConfigW advapi32 1588 +imp 'QueryServiceDynamicInformation' QueryServiceDynamicInformation advapi32 1589 +imp 'QueryServiceLockStatusA' QueryServiceLockStatusA advapi32 1590 +imp 'QueryServiceLockStatus' QueryServiceLockStatusW advapi32 1591 +imp 'QueryServiceObjectSecurity' QueryServiceObjectSecurity advapi32 1592 +imp 'QueryServiceStatus' QueryServiceStatus advapi32 1593 +imp 'QueryServiceStatusEx' QueryServiceStatusEx advapi32 1594 +imp 'QueryStateAtomValueInfo' QueryStateAtomValueInfo KernelBase 1272 +imp 'QueryStateContainerCreatedNew' QueryStateContainerCreatedNew KernelBase 1273 +imp 'QueryStateContainerItemInfo' QueryStateContainerItemInfo KernelBase 1274 +imp 'QueryThreadCycleTime' QueryThreadCycleTime KernelBase 1275 +imp 'QueryThreadProfiling' QueryThreadProfiling kernel32 1104 +imp 'QueryThreadpoolStackInformation' QueryThreadpoolStackInformation KernelBase 1276 +imp 'QueryTraceA' QueryTraceA advapi32 1595 +imp 'QueryTraceProcessingHandle' QueryTraceProcessingHandle advapi32 1596 +imp 'QueryTrace' QueryTraceW advapi32 1597 +imp 'QueryUmsThreadInformation' QueryUmsThreadInformation kernel32 1106 +imp 'QueryUnbiasedInterruptTime' QueryUnbiasedInterruptTime kernel32 1107 +imp 'QueryUnbiasedInterruptTimePrecise' QueryUnbiasedInterruptTimePrecise KernelBase 1278 +imp 'QueryUserServiceName' QueryUserServiceName advapi32 1598 +imp 'QueryUserServiceNameForContext' QueryUserServiceNameForContext advapi32 1599 +imp 'QueryUsersOnEncryptedFile' QueryUsersOnEncryptedFile advapi32 1600 +imp 'QueryVirtualMemoryInformation' QueryVirtualMemoryInformation KernelBase 1279 +imp 'QueryWorkingSet' QueryWorkingSet KernelBase 1280 +imp 'QueryWorkingSetEx' QueryWorkingSetEx KernelBase 1281 +imp 'QueueUserAPC' QueueUserAPC KernelBase 1282 +imp 'QueueUserWorkItem' QueueUserWorkItem KernelBase 1283 +imp 'QuirkGetData' QuirkGetData KernelBase 1284 +imp 'QuirkGetData2' QuirkGetData2 KernelBase 1285 +imp 'QuirkGetData2Worker' QuirkGetData2Worker kernel32 1110 +imp 'QuirkGetDataWorker' QuirkGetDataWorker kernel32 1111 +imp 'QuirkIsEnabled' QuirkIsEnabled KernelBase 1286 +imp 'QuirkIsEnabled2' QuirkIsEnabled2 KernelBase 1287 +imp 'QuirkIsEnabled2Worker' QuirkIsEnabled2Worker kernel32 1112 +imp 'QuirkIsEnabled3' QuirkIsEnabled3 KernelBase 1288 +imp 'QuirkIsEnabled3Worker' QuirkIsEnabled3Worker kernel32 1113 +imp 'QuirkIsEnabledForPackage' QuirkIsEnabledForPackage KernelBase 1289 +imp 'QuirkIsEnabledForPackage2' QuirkIsEnabledForPackage2 KernelBase 1290 +imp 'QuirkIsEnabledForPackage2Worker' QuirkIsEnabledForPackage2Worker kernel32 1114 +imp 'QuirkIsEnabledForPackage3' QuirkIsEnabledForPackage3 KernelBase 1291 +imp 'QuirkIsEnabledForPackage3Worker' QuirkIsEnabledForPackage3Worker kernel32 1115 +imp 'QuirkIsEnabledForPackage4' QuirkIsEnabledForPackage4 KernelBase 1292 +imp 'QuirkIsEnabledForPackage4Worker' QuirkIsEnabledForPackage4Worker kernel32 1116 +imp 'QuirkIsEnabledForPackageWorker' QuirkIsEnabledForPackageWorker kernel32 1117 +imp 'QuirkIsEnabledForProcess' QuirkIsEnabledForProcess KernelBase 1293 +imp 'QuirkIsEnabledForProcessWorker' QuirkIsEnabledForProcessWorker kernel32 1118 +imp 'QuirkIsEnabledWorker' QuirkIsEnabledWorker kernel32 1119 +imp 'RIMAddInputObserver' RIMAddInputObserver user32 2219 +imp 'RIMAreSiblingDevices' RIMAreSiblingDevices user32 2220 +imp 'RIMDeviceIoControl' RIMDeviceIoControl user32 2221 +imp 'RIMEnableMonitorMappingForDevice' RIMEnableMonitorMappingForDevice user32 2222 +imp 'RIMFreeInputBuffer' RIMFreeInputBuffer user32 2223 +imp 'RIMGetDevicePreparsedData' RIMGetDevicePreparsedData user32 2224 +imp 'RIMGetDevicePreparsedDataLockfree' RIMGetDevicePreparsedDataLockfree user32 2225 +imp 'RIMGetDeviceProperties' RIMGetDeviceProperties user32 2226 +imp 'RIMGetDevicePropertiesLockfree' RIMGetDevicePropertiesLockfree user32 2227 +imp 'RIMGetPhysicalDeviceRect' RIMGetPhysicalDeviceRect user32 2228 +imp 'RIMGetSourceProcessId' RIMGetSourceProcessId user32 2229 +imp 'RIMObserveNextInput' RIMObserveNextInput user32 2230 +imp 'RIMOnPnpNotification' RIMOnPnpNotification user32 2231 +imp 'RIMOnTimerNotification' RIMOnTimerNotification user32 2232 +imp 'RIMReadInput' RIMReadInput user32 2233 +imp 'RIMRegisterForInput' RIMRegisterForInput user32 2234 +imp 'RIMRemoveInputObserver' RIMRemoveInputObserver user32 2235 +imp 'RIMSetTestModeStatus' RIMSetTestModeStatus user32 2236 +imp 'RIMUnregisterForInput' RIMUnregisterForInput user32 2237 +imp 'RIMUpdateInputObserverRegistration' RIMUpdateInputObserverRegistration user32 2238 +imp 'RaiseCustomSystemEventTrigger' RaiseCustomSystemEventTrigger KernelBase 1294 +imp 'RaiseException' RaiseException KernelBase 1295 +imp 'RaiseFailFastException' RaiseFailFastException KernelBase 1296 +imp 'RaiseInvalid16BitExeError' RaiseInvalid16BitExeError kernel32 1122 +imp 'ReOpenFile' ReOpenFile KernelBase 1297 4 +imp 'ReadCabinetState' ReadCabinetState shell32 654 +imp 'ReadConsole' ReadConsoleW KernelBase 1308 5 +imp 'ReadConsoleA' ReadConsoleA KernelBase 1298 5 +imp 'ReadConsoleInput' ReadConsoleInputW KernelBase 1302 4 +imp 'ReadConsoleInputA' ReadConsoleInputA KernelBase 1299 4 +imp 'ReadConsoleInputExA' ReadConsoleInputExA KernelBase 1300 +imp 'ReadConsoleInputEx' ReadConsoleInputExW KernelBase 1301 +imp 'ReadConsoleOutput' ReadConsoleOutputW KernelBase 1307 5 +imp 'ReadConsoleOutputA' ReadConsoleOutputA KernelBase 1303 5 +imp 'ReadConsoleOutputAttribute' ReadConsoleOutputAttribute KernelBase 1304 5 +imp 'ReadConsoleOutputCharacter' ReadConsoleOutputCharacterW KernelBase 1306 5 +imp 'ReadConsoleOutputCharacterA' ReadConsoleOutputCharacterA KernelBase 1305 5 +imp 'ReadDirectoryChangesEx' ReadDirectoryChangesExW KernelBase 1309 +imp 'ReadDirectoryChanges' ReadDirectoryChangesW KernelBase 1310 +imp 'ReadEncryptedFileRaw' ReadEncryptedFileRaw advapi32 1601 +imp 'ReadEventLogA' ReadEventLogA advapi32 1602 +imp 'ReadEventLog' ReadEventLogW advapi32 1603 +imp 'ReadFile' ReadFile KernelBase 1311 5 +imp 'ReadFileEx' ReadFileEx KernelBase 1312 +imp 'ReadFileScatter' ReadFileScatter KernelBase 1313 5 +imp 'ReadProcessMemory' ReadProcessMemory KernelBase 1314 +imp 'ReadStateAtomValue' ReadStateAtomValue KernelBase 1315 +imp 'ReadStateContainerValue' ReadStateContainerValue KernelBase 1316 +imp 'ReadThreadProfilingData' ReadThreadProfilingData kernel32 1141 +imp 'RealChildWindowFromPoint' RealChildWindowFromPoint user32 2239 +imp 'RealDriveType' RealDriveType shell32 524 +imp 'RealGetWindowClassA' RealGetWindowClassA user32 2241 +imp 'RealGetWindowClass' RealGetWindowClassW user32 2242 +imp 'RealShellExecuteA' RealShellExecuteA shell32 199 +imp 'RealShellExecuteExA' RealShellExecuteExA shell32 207 +imp 'RealShellExecuteEx' RealShellExecuteExW shell32 208 +imp 'RealShellExecute' RealShellExecuteW shell32 226 +imp 'RealizePalette' RealizePalette gdi32 1795 +imp 'ReasonCodeNeedsBugID' ReasonCodeNeedsBugID user32 2243 +imp 'ReasonCodeNeedsComment' ReasonCodeNeedsComment user32 2244 +imp 'ReclaimVirtualMemory' ReclaimVirtualMemory KernelBase 1317 +imp 'RecordShutdownReason' RecordShutdownReason user32 2245 +imp 'RectInRegion' RectInRegion gdi32 1796 +imp 'RectVisible' RectVisible gdi32 1797 +imp 'Rectangle' Rectangle gdi32 1798 +imp 'RedrawWindow' RedrawWindow user32 2246 +imp 'RefreshPackageInfo' RefreshPackageInfo KernelBase 1318 +imp 'RefreshPolicyExInternal' RefreshPolicyExInternal KernelBase 1319 +imp 'RefreshPolicyInternal' RefreshPolicyInternal KernelBase 1320 +imp 'RegCloseKey' RegCloseKey KernelBase 1321 1 +imp 'RegConnectRegistry' RegConnectRegistryW advapi32 1608 3 +imp 'RegConnectRegistryA' RegConnectRegistryA advapi32 1605 3 +imp 'RegConnectRegistryEx' RegConnectRegistryExW advapi32 1607 4 +imp 'RegConnectRegistryExA' RegConnectRegistryExA advapi32 1606 4 +imp 'RegCopyTreeA' RegCopyTreeA advapi32 1609 +imp 'RegCopyTree' RegCopyTreeW KernelBase 1322 +imp 'RegCreateKey' RegCreateKeyW advapi32 1616 3 +imp 'RegCreateKeyA' RegCreateKeyA advapi32 1611 3 +imp 'RegCreateKeyEx' RegCreateKeyExW KernelBase 1326 9 +imp 'RegCreateKeyExA' RegCreateKeyExA KernelBase 1323 9 +imp 'RegCreateKeyExInternalA' RegCreateKeyExInternalA KernelBase 1324 +imp 'RegCreateKeyExInternal' RegCreateKeyExInternalW KernelBase 1325 +imp 'RegCreateKeyTransactedA' RegCreateKeyTransactedA advapi32 1614 +imp 'RegCreateKeyTransacted' RegCreateKeyTransactedW advapi32 1615 +imp 'RegDeleteKey' RegDeleteKeyW advapi32 1624 2 +imp 'RegDeleteKeyA' RegDeleteKeyA advapi32 1617 2 +imp 'RegDeleteKeyEx' RegDeleteKeyExW KernelBase 1330 4 +imp 'RegDeleteKeyExA' RegDeleteKeyExA KernelBase 1327 4 +imp 'RegDeleteKeyExInternalA' RegDeleteKeyExInternalA KernelBase 1328 +imp 'RegDeleteKeyExInternal' RegDeleteKeyExInternalW KernelBase 1329 +imp 'RegDeleteKeyTransactedA' RegDeleteKeyTransactedA advapi32 1620 +imp 'RegDeleteKeyTransacted' RegDeleteKeyTransactedW advapi32 1621 +imp 'RegDeleteKeyValueA' RegDeleteKeyValueA KernelBase 1331 +imp 'RegDeleteKeyValue' RegDeleteKeyValueW KernelBase 1332 +imp 'RegDeleteTree' RegDeleteTreeW KernelBase 1334 2 +imp 'RegDeleteTreeA' RegDeleteTreeA KernelBase 1333 2 +imp 'RegDeleteValue' RegDeleteValueW KernelBase 1336 2 +imp 'RegDeleteValueA' RegDeleteValueA KernelBase 1335 2 +imp 'RegDisablePredefinedCache' RegDisablePredefinedCache advapi32 1629 1 +imp 'RegDisablePredefinedCacheEx' RegDisablePredefinedCacheEx KernelBase 1337 +imp 'RegDisableReflectionKey' RegDisableReflectionKey advapi32 1631 1 +imp 'RegEnableReflectionKey' RegEnableReflectionKey advapi32 1632 1 +imp 'RegEnumKey' RegEnumKeyW advapi32 1636 4 +imp 'RegEnumKeyA' RegEnumKeyA advapi32 1633 4 +imp 'RegEnumKeyEx' RegEnumKeyExW KernelBase 1339 8 +imp 'RegEnumKeyExA' RegEnumKeyExA KernelBase 1338 8 +imp 'RegEnumValue' RegEnumValueW KernelBase 1341 8 +imp 'RegEnumValueA' RegEnumValueA KernelBase 1340 8 +imp 'RegFlushKey' RegFlushKey KernelBase 1342 1 +imp 'RegGetKeySecurity' RegGetKeySecurity KernelBase 1343 4 +imp 'RegGetValue' RegGetValueW KernelBase 1345 7 +imp 'RegGetValueA' RegGetValueA KernelBase 1344 7 +imp 'RegKrnGetAppKeyEventAddressInternal' RegKrnGetAppKeyEventAddressInternal KernelBase 1346 +imp 'RegKrnGetAppKeyLoaded' RegKrnGetAppKeyLoaded KernelBase 1347 +imp 'RegKrnGetClassesEnumTableAddressInternal' RegKrnGetClassesEnumTableAddressInternal KernelBase 1348 +imp 'RegKrnGetHKEY_ClassesRootAddress' RegKrnGetHKEY_ClassesRootAddress KernelBase 1349 +imp 'RegKrnGetTermsrvRegistryExtensionFlags' RegKrnGetTermsrvRegistryExtensionFlags KernelBase 1350 +imp 'RegKrnResetAppKeyLoaded' RegKrnResetAppKeyLoaded KernelBase 1351 +imp 'RegKrnSetDllHasThreadStateGlobal' RegKrnSetDllHasThreadStateGlobal KernelBase 1352 +imp 'RegKrnSetTermsrvRegistryExtensionFlags' RegKrnSetTermsrvRegistryExtensionFlags KernelBase 1353 +imp 'RegLoadAppKeyA' RegLoadAppKeyA KernelBase 1354 +imp 'RegLoadAppKey' RegLoadAppKeyW KernelBase 1355 +imp 'RegLoadKey' RegLoadKeyW KernelBase 1357 3 +imp 'RegLoadKeyA' RegLoadKeyA KernelBase 1356 3 +imp 'RegLoadMUIStringA' RegLoadMUIStringA KernelBase 1358 +imp 'RegLoadMUIString' RegLoadMUIStringW KernelBase 1359 +imp 'RegNotifyChangeKeyValue' RegNotifyChangeKeyValue KernelBase 1360 5 +imp 'RegOpenCurrentUser' RegOpenCurrentUser KernelBase 1361 2 +imp 'RegOpenKeyA' RegOpenKeyA advapi32 1651 3 +imp 'RegOpenKeyEx' RegOpenKeyExW KernelBase 1365 5 +imp 'RegOpenKeyExA' RegOpenKeyExA KernelBase 1362 5 +imp 'RegOpenKeyExInternalA' RegOpenKeyExInternalA KernelBase 1363 +imp 'RegOpenKeyExInternal' RegOpenKeyExInternalW KernelBase 1364 +imp 'RegOpenKeyTransactedA' RegOpenKeyTransactedA advapi32 1654 +imp 'RegOpenKeyTransacted' RegOpenKeyTransactedW advapi32 1655 +imp 'RegOpenKey' RegOpenKeyW advapi32 1656 +imp 'RegOpenUserClassesRoot' RegOpenUserClassesRoot KernelBase 1366 4 +imp 'RegOverridePredefKey' RegOverridePredefKey advapi32 1658 2 +imp 'RegQueryInfoKey' RegQueryInfoKeyW KernelBase 1368 12 +imp 'RegQueryInfoKeyA' RegQueryInfoKeyA KernelBase 1367 12 +imp 'RegQueryMultipleValues' RegQueryMultipleValuesW KernelBase 1370 5 +imp 'RegQueryMultipleValuesA' RegQueryMultipleValuesA KernelBase 1369 5 +imp 'RegQueryReflectionKey' RegQueryReflectionKey advapi32 1663 2 +imp 'RegQueryValue' RegQueryValueW advapi32 1667 4 +imp 'RegQueryValueA' RegQueryValueA advapi32 1664 4 +imp 'RegQueryValueEx' RegQueryValueExW KernelBase 1372 6 +imp 'RegQueryValueExA' RegQueryValueExA KernelBase 1371 6 +imp 'RegRenameKey' RegRenameKey advapi32 1668 +imp 'RegReplaceKey' RegReplaceKeyW advapi32 1670 4 +imp 'RegReplaceKeyA' RegReplaceKeyA advapi32 1669 4 +imp 'RegRestoreKey' RegRestoreKeyW KernelBase 1374 3 +imp 'RegRestoreKeyA' RegRestoreKeyA KernelBase 1373 3 +imp 'RegSaveKey' RegSaveKeyW advapi32 1676 3 +imp 'RegSaveKeyA' RegSaveKeyA advapi32 1673 3 +imp 'RegSaveKeyExA' RegSaveKeyExA KernelBase 1375 +imp 'RegSaveKeyEx' RegSaveKeyExW KernelBase 1376 +imp 'RegSetKeySecurity' RegSetKeySecurity KernelBase 1377 3 +imp 'RegSetKeyValueA' RegSetKeyValueA KernelBase 1378 +imp 'RegSetKeyValue' RegSetKeyValueW KernelBase 1379 +imp 'RegSetValue' RegSetValueW advapi32 1683 5 +imp 'RegSetValueA' RegSetValueA advapi32 1680 5 +imp 'RegSetValueEx' RegSetValueExW KernelBase 1381 6 +imp 'RegSetValueExA' RegSetValueExA KernelBase 1380 6 +imp 'RegUnLoadKey' RegUnLoadKeyW KernelBase 1383 2 +imp 'RegUnLoadKeyA' RegUnLoadKeyA KernelBase 1382 2 +imp 'RegenerateUserEnvironment' RegenerateUserEnvironment shell32 313 +imp 'RegisterApplicationRecoveryCallback' RegisterApplicationRecoveryCallback kernel32 1184 +imp 'RegisterApplicationRestart' RegisterApplicationRestart kernel32 1185 +imp 'RegisterBSDRWindow' RegisterBSDRWindow user32 2247 +imp 'RegisterBadMemoryNotification' RegisterBadMemoryNotification KernelBase 1384 +imp 'RegisterClassA' RegisterClassA user32 2248 +imp 'RegisterClassExA' RegisterClassExA user32 2249 +imp 'RegisterClassEx' RegisterClassExW user32 2250 +imp 'RegisterClass' RegisterClassW user32 2251 +imp 'RegisterClipboardFormatA' RegisterClipboardFormatA user32 2252 +imp 'RegisterClipboardFormat' RegisterClipboardFormatW user32 2253 +imp 'RegisterConsoleIME' RegisterConsoleIME kernel32 1187 +imp 'RegisterConsoleOS2' RegisterConsoleOS2 kernel32 1188 +imp 'RegisterConsoleVDM' RegisterConsoleVDM kernel32 1189 +imp 'RegisterDManipHook' RegisterDManipHook user32 2254 +imp 'RegisterDeviceNotificationA' RegisterDeviceNotificationA user32 2255 +imp 'RegisterDeviceNotification' RegisterDeviceNotificationW user32 2256 +imp 'RegisterErrorReportingDialog' RegisterErrorReportingDialog user32 2257 +imp 'RegisterEventSourceA' RegisterEventSourceA advapi32 1686 +imp 'RegisterEventSource' RegisterEventSourceW advapi32 1687 +imp 'RegisterFrostWindow' RegisterFrostWindow user32 2258 +imp 'RegisterGPNotificationInternal' RegisterGPNotificationInternal KernelBase 1385 +imp 'RegisterGhostWindow' RegisterGhostWindow user32 2259 +imp 'RegisterHotKey' RegisterHotKey user32 2260 +imp 'RegisterIdleTask' RegisterIdleTask advapi32 1688 +imp 'RegisterLogonProcess' RegisterLogonProcess user32 2261 +imp 'RegisterMessagePumpHook' RegisterMessagePumpHook user32 2262 +imp 'RegisterPointerDeviceNotifications' RegisterPointerDeviceNotifications user32 2263 +imp 'RegisterPointerInputTarget' RegisterPointerInputTarget user32 2264 +imp 'RegisterPointerInputTargetEx' RegisterPointerInputTargetEx user32 2265 +imp 'RegisterPowerSettingNotification' RegisterPowerSettingNotification user32 2266 +imp 'RegisterRawInputDevices' RegisterRawInputDevices user32 2267 +imp 'RegisterServiceCtrlHandlerA' RegisterServiceCtrlHandlerA advapi32 1689 +imp 'RegisterServiceCtrlHandlerExA' RegisterServiceCtrlHandlerExA advapi32 1690 +imp 'RegisterServiceCtrlHandlerEx' RegisterServiceCtrlHandlerExW advapi32 1691 +imp 'RegisterServiceCtrlHandler' RegisterServiceCtrlHandlerW advapi32 1692 +imp 'RegisterServicesProcess' RegisterServicesProcess user32 2268 +imp 'RegisterSessionPort' RegisterSessionPort user32 2269 +imp 'RegisterShellHookWindow' RegisterShellHookWindow user32 2270 +imp 'RegisterStateChangeNotification' RegisterStateChangeNotification KernelBase 1386 +imp 'RegisterStateLock' RegisterStateLock KernelBase 1387 +imp 'RegisterSuspendResumeNotification' RegisterSuspendResumeNotification user32 2271 +imp 'RegisterSystemThread' RegisterSystemThread user32 2272 +imp 'RegisterTasklist' RegisterTasklist user32 2273 +imp 'RegisterTouchHitTestingWindow' RegisterTouchHitTestingWindow user32 2274 +imp 'RegisterTouchWindow' RegisterTouchWindow user32 2275 +imp 'RegisterUserApiHook' RegisterUserApiHook user32 2276 +imp 'RegisterWaitChainCOMCallback' RegisterWaitChainCOMCallback advapi32 1695 +imp 'RegisterWaitForInputIdle' RegisterWaitForInputIdle kernel32 1190 +imp 'RegisterWaitForSingleObject' RegisterWaitForSingleObject kernel32 1191 +imp 'RegisterWaitForSingleObjectEx' RegisterWaitForSingleObjectEx KernelBase 1389 +imp 'RegisterWaitUntilOOBECompleted' RegisterWaitUntilOOBECompleted kernel32 1193 +imp 'RegisterWindowMessageA' RegisterWindowMessageA user32 2277 +imp 'RegisterWindowMessage' RegisterWindowMessageW user32 2278 +imp 'RegisterWowBaseHandlers' RegisterWowBaseHandlers kernel32 1194 +imp 'RegisterWowExec' RegisterWowExec kernel32 1195 +imp 'ReleaseActCtx' ReleaseActCtx KernelBase 1390 +imp 'ReleaseActCtxWorker' ReleaseActCtxWorker kernel32 1197 +imp 'ReleaseCapture' ReleaseCapture user32 2279 +imp 'ReleaseDC' ReleaseDC user32 2280 +imp 'ReleaseDwmHitTestWaiters' ReleaseDwmHitTestWaiters user32 2281 +imp 'ReleaseMutex' ReleaseMutex KernelBase 1391 1 +imp 'ReleaseSemaphore' ReleaseSemaphore KernelBase 1395 3 +imp 'ReleaseStateLock' ReleaseStateLock KernelBase 1397 +imp 'RemapPredefinedHandleInternal' RemapPredefinedHandleInternal KernelBase 1398 +imp 'RemoteRegEnumKeyWrapper' RemoteRegEnumKeyWrapper advapi32 1696 +imp 'RemoteRegEnumValueWrapper' RemoteRegEnumValueWrapper advapi32 1697 +imp 'RemoteRegQueryInfoKeyWrapper' RemoteRegQueryInfoKeyWrapper advapi32 1698 +imp 'RemoteRegQueryMultipleValues2Wrapper' RemoteRegQueryMultipleValues2Wrapper advapi32 1699 +imp 'RemoteRegQueryMultipleValuesWrapper' RemoteRegQueryMultipleValuesWrapper advapi32 1700 +imp 'RemoteRegQueryValueWrapper' RemoteRegQueryValueWrapper advapi32 1701 +imp 'RemoveClipboardFormatListener' RemoveClipboardFormatListener user32 2282 +imp 'RemoveDirectory' RemoveDirectoryW KernelBase 1400 1 +imp 'RemoveDirectoryA' RemoveDirectoryA KernelBase 1399 1 +imp 'RemoveDirectoryTransactedA' RemoveDirectoryTransactedA kernel32 1205 +imp 'RemoveDirectoryTransacted' RemoveDirectoryTransactedW kernel32 1206 +imp 'RemoveDllDirectory' RemoveDllDirectory KernelBase 1401 +imp 'RemoveExtensionProgIds' RemoveExtensionProgIds KernelBase 1402 +imp 'RemoveFontMemResourceEx' RemoveFontMemResourceEx gdi32 1799 +imp 'RemoveFontResourceA' RemoveFontResourceA gdi32 1800 +imp 'RemoveFontResourceExA' RemoveFontResourceExA gdi32 1801 +imp 'RemoveFontResourceEx' RemoveFontResourceExW gdi32 1802 +imp 'RemoveFontResourceTracking' RemoveFontResourceTracking gdi32 1803 +imp 'RemoveFontResource' RemoveFontResourceW gdi32 1804 +imp 'RemoveInjectionDevice' RemoveInjectionDevice user32 2283 +imp 'RemoveLocalAlternateComputerNameA' RemoveLocalAlternateComputerNameA kernel32 1209 +imp 'RemoveLocalAlternateComputerName' RemoveLocalAlternateComputerNameW kernel32 1210 +imp 'RemoveMenu' RemoveMenu user32 2284 +imp 'RemovePackageFromFamilyXref' RemovePackageFromFamilyXref KernelBase 1403 +imp 'RemovePackageStatus' RemovePackageStatus KernelBase 1404 +imp 'RemovePackageStatusForUser' RemovePackageStatusForUser KernelBase 1405 +imp 'RemovePropA' RemovePropA user32 2285 +imp 'RemoveProp' RemovePropW user32 2286 +imp 'RemoveSecureMemoryCacheCallback' RemoveSecureMemoryCacheCallback kernel32 1211 +imp 'RemoveThreadTSFEventAwareness' RemoveThreadTSFEventAwareness user32 2287 +imp 'RemoveUsersFromEncryptedFile' RemoveUsersFromEncryptedFile advapi32 1703 +imp 'ReplaceFileA' ReplaceFileA kernel32 1215 +imp 'ReplaceFileExInternal' ReplaceFileExInternal KernelBase 1408 +imp 'ReplaceFile' ReplaceFileW KernelBase 1409 +imp 'ReplacePartitionUnit' ReplacePartitionUnit kernel32 1217 +imp 'ReplaceTextA' ReplaceTextA comdlg32 124 +imp 'ReplaceText' ReplaceTextW comdlg32 125 +imp 'ReplyMessage' ReplyMessage user32 2288 +imp 'ReportEventA' ReportEventA advapi32 1704 +imp 'ReportEvent' ReportEventW advapi32 1705 +imp 'ReportInertia' ReportInertia user32 2551 +imp 'RequestDeviceWakeup' RequestDeviceWakeup kernel32 1218 +imp 'RequestWakeupLatency' RequestWakeupLatency kernel32 1219 +imp 'ResetDCA' ResetDCA gdi32 1805 +imp 'ResetDCW' ResetDCW gdi32 1806 +imp 'ResetEvent' ResetEvent KernelBase 1410 1 +imp 'ResetState' ResetState KernelBase 1411 +imp 'ResetWriteWatch' ResetWriteWatch KernelBase 1412 +imp 'ResizePalette' ResizePalette gdi32 1807 +imp 'ResolveDelayLoadedAPI' ResolveDelayLoadedAPI KernelBase 1413 +imp 'ResolveDelayLoadsFromDll' ResolveDelayLoadsFromDll KernelBase 1414 +imp 'ResolveDesktopForWOW' ResolveDesktopForWOW user32 2289 +imp 'ResolveLocaleName' ResolveLocaleName KernelBase 1415 +imp 'RestartDialog' RestartDialog shell32 59 +imp 'RestartDialogEx' RestartDialogEx shell32 730 +imp 'RestoreDC' RestoreDC gdi32 1808 +imp 'ResumeThread' ResumeThread KernelBase 1417 +imp 'ReuseDDElParam' ReuseDDElParam user32 2290 +imp 'RevertToSelf' RevertToSelf KernelBase 1418 +imp 'RoundRect' RoundRect gdi32 1809 +imp 'RsopLoggingEnabledInternal' RsopLoggingEnabledInternal KernelBase 1419 +imp 'RtlAbortRXact' RtlAbortRXact ntdll 676 +imp 'RtlAbsoluteToSelfRelativeSD' RtlAbsoluteToSelfRelativeSD ntdll 677 +imp 'RtlAcquirePebLock' RtlAcquirePebLock ntdll 678 +imp 'RtlAcquirePrivilege' RtlAcquirePrivilege ntdll 679 +imp 'RtlAcquireReleaseSRWLockExclusive' RtlAcquireReleaseSRWLockExclusive ntdll 680 +imp 'RtlAcquireResourceExclusive' RtlAcquireResourceExclusive ntdll 681 +imp 'RtlAcquireResourceShared' RtlAcquireResourceShared ntdll 682 +imp 'RtlAcquireSRWLockExclusive' RtlAcquireSRWLockExclusive ntdll 683 +imp 'RtlAcquireSRWLockShared' RtlAcquireSRWLockShared ntdll 684 +imp 'RtlActivateActivationContext' RtlActivateActivationContext ntdll 685 +imp 'RtlActivateActivationContextEx' RtlActivateActivationContextEx ntdll 686 +imp 'RtlActivateActivationContextUnsafeFast' RtlActivateActivationContextUnsafeFast ntdll 687 +imp 'RtlAddAccessAllowedAce' RtlAddAccessAllowedAce ntdll 688 +imp 'RtlAddAccessAllowedAceEx' RtlAddAccessAllowedAceEx ntdll 689 +imp 'RtlAddAccessAllowedObjectAce' RtlAddAccessAllowedObjectAce ntdll 690 +imp 'RtlAddAccessDeniedAce' RtlAddAccessDeniedAce ntdll 691 +imp 'RtlAddAccessDeniedAceEx' RtlAddAccessDeniedAceEx ntdll 692 +imp 'RtlAddAccessDeniedObjectAce' RtlAddAccessDeniedObjectAce ntdll 693 +imp 'RtlAddAccessFilterAce' RtlAddAccessFilterAce ntdll 694 +imp 'RtlAddAce' RtlAddAce ntdll 695 +imp 'RtlAddActionToRXact' RtlAddActionToRXact ntdll 696 +imp 'RtlAddAtomToAtomTable' RtlAddAtomToAtomTable ntdll 697 +imp 'RtlAddAttributeActionToRXact' RtlAddAttributeActionToRXact ntdll 698 +imp 'RtlAddAuditAccessAce' RtlAddAuditAccessAce ntdll 699 +imp 'RtlAddAuditAccessAceEx' RtlAddAuditAccessAceEx ntdll 700 +imp 'RtlAddAuditAccessObjectAce' RtlAddAuditAccessObjectAce ntdll 701 +imp 'RtlAddCompoundAce' RtlAddCompoundAce ntdll 702 +imp 'RtlAddFunctionTable' RtlAddFunctionTable ntdll 703 +imp 'RtlAddGrowableFunctionTable' RtlAddGrowableFunctionTable ntdll 704 +imp 'RtlAddIntegrityLabelToBoundaryDescriptor' RtlAddIntegrityLabelToBoundaryDescriptor ntdll 705 +imp 'RtlAddMandatoryAce' RtlAddMandatoryAce ntdll 706 +imp 'RtlAddProcessTrustLabelAce' RtlAddProcessTrustLabelAce ntdll 707 +imp 'RtlAddRefActivationContext' RtlAddRefActivationContext ntdll 708 +imp 'RtlAddRefMemoryStream' RtlAddRefMemoryStream ntdll 709 +imp 'RtlAddResourceAttributeAce' RtlAddResourceAttributeAce ntdll 710 +imp 'RtlAddSIDToBoundaryDescriptor' RtlAddSIDToBoundaryDescriptor ntdll 711 +imp 'RtlAddScopedPolicyIDAce' RtlAddScopedPolicyIDAce ntdll 712 +imp 'RtlAddVectoredContinueHandler' RtlAddVectoredContinueHandler ntdll 713 +imp 'RtlAddVectoredExceptionHandler' RtlAddVectoredExceptionHandler ntdll 714 +imp 'RtlAddressInSectionTable' RtlAddressInSectionTable ntdll 715 +imp 'RtlAdjustPrivilege' RtlAdjustPrivilege ntdll 716 +imp 'RtlAllocateActivationContextStack' RtlAllocateActivationContextStack ntdll 717 +imp 'RtlAllocateAndInitializeSid' RtlAllocateAndInitializeSid ntdll 718 +imp 'RtlAllocateAndInitializeSidEx' RtlAllocateAndInitializeSidEx ntdll 719 +imp 'RtlAllocateHandle' RtlAllocateHandle ntdll 720 +imp 'RtlAllocateHeap' RtlAllocateHeap ntdll 721 3 +imp 'RtlAllocateMemoryBlockLookaside' RtlAllocateMemoryBlockLookaside ntdll 722 +imp 'RtlAllocateMemoryZone' RtlAllocateMemoryZone ntdll 723 +imp 'RtlAllocateWnfSerializationGroup' RtlAllocateWnfSerializationGroup ntdll 724 +imp 'RtlAnsiCharToUnicodeChar' RtlAnsiCharToUnicodeChar ntdll 725 +imp 'RtlAnsiStringToUnicodeSize' RtlAnsiStringToUnicodeSize ntdll 726 +imp 'RtlAnsiStringToUnicodeString' RtlAnsiStringToUnicodeString ntdll 727 +imp 'RtlAppendAsciizToString' RtlAppendAsciizToString ntdll 728 +imp 'RtlAppendPathElement' RtlAppendPathElement ntdll 729 +imp 'RtlAppendStringToString' RtlAppendStringToString ntdll 730 +imp 'RtlAppendUnicodeStringToString' RtlAppendUnicodeStringToString ntdll 731 +imp 'RtlAppendUnicodeToString' RtlAppendUnicodeToString ntdll 732 +imp 'RtlApplicationVerifierStop' RtlApplicationVerifierStop ntdll 733 +imp 'RtlApplyRXact' RtlApplyRXact ntdll 734 +imp 'RtlApplyRXactNoFlush' RtlApplyRXactNoFlush ntdll 735 +imp 'RtlAppxIsFileOwnedByTrustedInstaller' RtlAppxIsFileOwnedByTrustedInstaller ntdll 736 +imp 'RtlAreAllAccessesGranted' RtlAreAllAccessesGranted ntdll 737 +imp 'RtlAreAnyAccessesGranted' RtlAreAnyAccessesGranted ntdll 738 +imp 'RtlAreBitsClear' RtlAreBitsClear ntdll 739 +imp 'RtlAreBitsSet' RtlAreBitsSet ntdll 740 +imp 'RtlAreLongPathsEnabled' RtlAreLongPathsEnabled ntdll 741 +imp 'RtlAssert' RtlAssert ntdll 742 +imp 'RtlAvlInsertNodeEx' RtlAvlInsertNodeEx ntdll 743 +imp 'RtlAvlRemoveNode' RtlAvlRemoveNode ntdll 744 +imp 'RtlBarrier' RtlBarrier ntdll 745 +imp 'RtlBarrierForDelete' RtlBarrierForDelete ntdll 746 +imp 'RtlCallEnclaveReturn' RtlCallEnclaveReturn ntdll 747 +imp 'RtlCancelTimer' RtlCancelTimer ntdll 748 +imp 'RtlCanonicalizeDomainName' RtlCanonicalizeDomainName ntdll 749 +imp 'RtlCapabilityCheck' RtlCapabilityCheck ntdll 750 +imp 'RtlCapabilityCheckForSingleSessionSku' RtlCapabilityCheckForSingleSessionSku ntdll 751 +imp 'RtlCaptureContext' RtlCaptureContext ntdll 752 +imp 'RtlCaptureStackBackTrace' RtlCaptureStackBackTrace ntdll 753 +imp 'RtlCharToInteger' RtlCharToInteger ntdll 754 +imp 'RtlCheckBootStatusIntegrity' RtlCheckBootStatusIntegrity ntdll 755 +imp 'RtlCheckForOrphanedCriticalSections' RtlCheckForOrphanedCriticalSections ntdll 756 +imp 'RtlCheckPortableOperatingSystem' RtlCheckPortableOperatingSystem ntdll 757 +imp 'RtlCheckRegistryKey' RtlCheckRegistryKey ntdll 758 +imp 'RtlCheckSandboxedToken' RtlCheckSandboxedToken ntdll 759 +imp 'RtlCheckSystemBootStatusIntegrity' RtlCheckSystemBootStatusIntegrity ntdll 760 +imp 'RtlCheckTokenCapability' RtlCheckTokenCapability ntdll 761 +imp 'RtlCheckTokenMembership' RtlCheckTokenMembership ntdll 762 +imp 'RtlCheckTokenMembershipEx' RtlCheckTokenMembershipEx ntdll 763 +imp 'RtlCleanUpTEBLangLists' RtlCleanUpTEBLangLists ntdll 764 +imp 'RtlClearAllBits' RtlClearAllBits ntdll 765 +imp 'RtlClearBit' RtlClearBit ntdll 766 +imp 'RtlClearBits' RtlClearBits ntdll 767 +imp 'RtlClearThreadWorkOnBehalfTicket' RtlClearThreadWorkOnBehalfTicket ntdll 768 +imp 'RtlCloneMemoryStream' RtlCloneMemoryStream ntdll 769 +imp 'RtlCloneUserProcess' RtlCloneUserProcess ntdll 770 5 +imp 'RtlCmDecodeMemIoResource' RtlCmDecodeMemIoResource ntdll 771 +imp 'RtlCmEncodeMemIoResource' RtlCmEncodeMemIoResource ntdll 772 +imp 'RtlCommitDebugInfo' RtlCommitDebugInfo ntdll 773 +imp 'RtlCommitMemoryStream' RtlCommitMemoryStream ntdll 774 +imp 'RtlCompactHeap' RtlCompactHeap ntdll 775 +imp 'RtlCompareAltitudes' RtlCompareAltitudes ntdll 776 +imp 'RtlCompareMemory' RtlCompareMemory ntdll 777 +imp 'RtlCompareMemoryUlong' RtlCompareMemoryUlong ntdll 778 +imp 'RtlCompareString' RtlCompareString ntdll 779 +imp 'RtlCompareUnicodeString' RtlCompareUnicodeString ntdll 780 +imp 'RtlCompareUnicodeStrings' RtlCompareUnicodeStrings ntdll 781 +imp 'RtlCompleteProcessCloning' RtlCompleteProcessCloning ntdll 782 +imp 'RtlCompressBuffer' RtlCompressBuffer ntdll 783 +imp 'RtlComputeCrc32' RtlComputeCrc32 ntdll 784 +imp 'RtlComputeImportTableHash' RtlComputeImportTableHash ntdll 785 +imp 'RtlComputePrivatizedDllName_U' RtlComputePrivatizedDllName_U ntdll 786 +imp 'RtlConnectToSm' RtlConnectToSm ntdll 787 +imp 'RtlConsoleMultiByteToUnicodeN' RtlConsoleMultiByteToUnicodeN ntdll 788 +imp 'RtlContractHashTable' RtlContractHashTable ntdll 789 +imp 'RtlConvertDeviceFamilyInfoToString' RtlConvertDeviceFamilyInfoToString ntdll 790 +imp 'RtlConvertExclusiveToShared' RtlConvertExclusiveToShared ntdll 791 +imp 'RtlConvertLCIDToString' RtlConvertLCIDToString ntdll 792 +imp 'RtlConvertSRWLockExclusiveToShared' RtlConvertSRWLockExclusiveToShared ntdll 793 +imp 'RtlConvertSharedToExclusive' RtlConvertSharedToExclusive ntdll 794 +imp 'RtlConvertSidToUnicodeString' RtlConvertSidToUnicodeString ntdll 795 3 +imp 'RtlConvertToAutoInheritSecurityObject' RtlConvertToAutoInheritSecurityObject ntdll 796 +imp 'RtlCopyBitMap' RtlCopyBitMap ntdll 797 +imp 'RtlCopyContext' RtlCopyContext ntdll 798 +imp 'RtlCopyExtendedContext' RtlCopyExtendedContext ntdll 799 +imp 'RtlCopyLuid' RtlCopyLuid ntdll 800 +imp 'RtlCopyLuidAndAttributesArray' RtlCopyLuidAndAttributesArray ntdll 801 +imp 'RtlCopyMappedMemory' RtlCopyMappedMemory ntdll 802 +imp 'RtlCopyMemory' RtlCopyMemory ntdll 803 +imp 'RtlCopyMemoryNonTemporal' RtlCopyMemoryNonTemporal ntdll 804 +imp 'RtlCopyMemoryStreamTo' RtlCopyMemoryStreamTo ntdll 805 +imp 'RtlCopyOutOfProcessMemoryStreamTo' RtlCopyOutOfProcessMemoryStreamTo ntdll 806 +imp 'RtlCopySecurityDescriptor' RtlCopySecurityDescriptor ntdll 807 +imp 'RtlCopySid' RtlCopySid ntdll 808 +imp 'RtlCopySidAndAttributesArray' RtlCopySidAndAttributesArray ntdll 809 +imp 'RtlCopyString' RtlCopyString ntdll 810 +imp 'RtlCopyUnicodeString' RtlCopyUnicodeString ntdll 811 +imp 'RtlCrc32' RtlCrc32 ntdll 812 +imp 'RtlCrc64' RtlCrc64 ntdll 813 +imp 'RtlCreateAcl' RtlCreateAcl ntdll 814 +imp 'RtlCreateActivationContext' RtlCreateActivationContext ntdll 815 +imp 'RtlCreateAndSetSD' RtlCreateAndSetSD ntdll 816 +imp 'RtlCreateAtomTable' RtlCreateAtomTable ntdll 817 +imp 'RtlCreateBootStatusDataFile' RtlCreateBootStatusDataFile ntdll 818 +imp 'RtlCreateBoundaryDescriptor' RtlCreateBoundaryDescriptor ntdll 819 +imp 'RtlCreateEnvironment' RtlCreateEnvironment ntdll 820 +imp 'RtlCreateEnvironmentEx' RtlCreateEnvironmentEx ntdll 821 +imp 'RtlCreateHashTable' RtlCreateHashTable ntdll 822 +imp 'RtlCreateHashTableEx' RtlCreateHashTableEx ntdll 823 +imp 'RtlCreateHeap' RtlCreateHeap ntdll 824 6 +imp 'RtlCreateMemoryBlockLookaside' RtlCreateMemoryBlockLookaside ntdll 825 +imp 'RtlCreateMemoryZone' RtlCreateMemoryZone ntdll 826 +imp 'RtlCreateProcessParameters' RtlCreateProcessParameters ntdll 827 10 +imp 'RtlCreateProcessParametersEx' RtlCreateProcessParametersEx ntdll 828 +imp 'RtlCreateProcessReflection' RtlCreateProcessReflection ntdll 829 +imp 'RtlCreateQueryDebugBuffer' RtlCreateQueryDebugBuffer ntdll 830 +imp 'RtlCreateRegistryKey' RtlCreateRegistryKey ntdll 831 +imp 'RtlCreateSecurityDescriptor' RtlCreateSecurityDescriptor ntdll 832 +imp 'RtlCreateServiceSid' RtlCreateServiceSid ntdll 833 +imp 'RtlCreateSystemVolumeInformationFolder' RtlCreateSystemVolumeInformationFolder ntdll 834 +imp 'RtlCreateTagHeap' RtlCreateTagHeap ntdll 835 +imp 'RtlCreateTimer' RtlCreateTimer ntdll 836 +imp 'RtlCreateTimerQueue' RtlCreateTimerQueue ntdll 837 +imp 'RtlCreateUmsCompletionList' RtlCreateUmsCompletionList ntdll 838 +imp 'RtlCreateUmsThreadContext' RtlCreateUmsThreadContext ntdll 839 +imp 'RtlCreateUnicodeString' RtlCreateUnicodeString ntdll 840 +imp 'RtlCreateUnicodeStringFromAsciiz' RtlCreateUnicodeStringFromAsciiz ntdll 841 +imp 'RtlCreateUserProcess' RtlCreateUserProcess ntdll 842 +imp 'RtlCreateUserProcessEx' RtlCreateUserProcessEx ntdll 843 +imp 'RtlCreateUserSecurityObject' RtlCreateUserSecurityObject ntdll 844 +imp 'RtlCreateUserStack' RtlCreateUserStack ntdll 845 +imp 'RtlCreateUserThread' RtlCreateUserThread ntdll 846 +imp 'RtlCreateVirtualAccountSid' RtlCreateVirtualAccountSid ntdll 847 +imp 'RtlCultureNameToLCID' RtlCultureNameToLCID ntdll 848 +imp 'RtlCustomCPToUnicodeN' RtlCustomCPToUnicodeN ntdll 849 +imp 'RtlCutoverTimeToSystemTime' RtlCutoverTimeToSystemTime ntdll 850 +imp 'RtlDeCommitDebugInfo' RtlDeCommitDebugInfo ntdll 851 +imp 'RtlDeNormalizeProcessParams' RtlDeNormalizeProcessParams ntdll 852 +imp 'RtlDeactivateActivationContext' RtlDeactivateActivationContext ntdll 853 +imp 'RtlDeactivateActivationContextUnsafeFast' RtlDeactivateActivationContextUnsafeFast ntdll 854 +imp 'RtlDebugPrintTimes' RtlDebugPrintTimes ntdll 855 +imp 'RtlDecodePointer' RtlDecodePointer ntdll 856 +imp 'RtlDecodeRemotePointer' RtlDecodeRemotePointer ntdll 857 +imp 'RtlDecodeSystemPointer' RtlDecodeSystemPointer ntdll 858 +imp 'RtlDecompressBuffer' RtlDecompressBuffer ntdll 859 +imp 'RtlDecompressBufferEx' RtlDecompressBufferEx ntdll 860 +imp 'RtlDecompressFragment' RtlDecompressFragment ntdll 861 +imp 'RtlDefaultNpAcl' RtlDefaultNpAcl ntdll 862 +imp 'RtlDelete' RtlDelete ntdll 863 +imp 'RtlDeleteAce' RtlDeleteAce ntdll 864 +imp 'RtlDeleteAtomFromAtomTable' RtlDeleteAtomFromAtomTable ntdll 865 +imp 'RtlDeleteBarrier' RtlDeleteBarrier ntdll 866 +imp 'RtlDeleteBoundaryDescriptor' RtlDeleteBoundaryDescriptor ntdll 867 +imp 'RtlDeleteCriticalSection' RtlDeleteCriticalSection ntdll 868 1 +imp 'RtlDeleteElementGenericTable' RtlDeleteElementGenericTable ntdll 869 +imp 'RtlDeleteElementGenericTableAvl' RtlDeleteElementGenericTableAvl ntdll 870 +imp 'RtlDeleteElementGenericTableAvlEx' RtlDeleteElementGenericTableAvlEx ntdll 871 +imp 'RtlDeleteFunctionTable' RtlDeleteFunctionTable ntdll 872 +imp 'RtlDeleteGrowableFunctionTable' RtlDeleteGrowableFunctionTable ntdll 873 +imp 'RtlDeleteHashTable' RtlDeleteHashTable ntdll 874 +imp 'RtlDeleteNoSplay' RtlDeleteNoSplay ntdll 875 +imp 'RtlDeleteRegistryValue' RtlDeleteRegistryValue ntdll 876 +imp 'RtlDeleteResource' RtlDeleteResource ntdll 877 +imp 'RtlDeleteSecurityObject' RtlDeleteSecurityObject ntdll 878 +imp 'RtlDeleteTimer' RtlDeleteTimer ntdll 879 +imp 'RtlDeleteTimerQueue' RtlDeleteTimerQueue ntdll 880 +imp 'RtlDeleteTimerQueueEx' RtlDeleteTimerQueueEx ntdll 881 +imp 'RtlDeleteUmsCompletionList' RtlDeleteUmsCompletionList ntdll 882 +imp 'RtlDeleteUmsThreadContext' RtlDeleteUmsThreadContext ntdll 883 +imp 'RtlDequeueUmsCompletionListItems' RtlDequeueUmsCompletionListItems ntdll 884 +imp 'RtlDeregisterSecureMemoryCacheCallback' RtlDeregisterSecureMemoryCacheCallback ntdll 885 +imp 'RtlDeregisterWait' RtlDeregisterWait ntdll 886 +imp 'RtlDeregisterWaitEx' RtlDeregisterWaitEx ntdll 887 +imp 'RtlDeriveCapabilitySidsFromName' RtlDeriveCapabilitySidsFromName ntdll 888 +imp 'RtlDestroyAtomTable' RtlDestroyAtomTable ntdll 889 +imp 'RtlDestroyEnvironment' RtlDestroyEnvironment ntdll 890 +imp 'RtlDestroyHandleTable' RtlDestroyHandleTable ntdll 891 +imp 'RtlDestroyHeap' RtlDestroyHeap ntdll 892 1 +imp 'RtlDestroyMemoryBlockLookaside' RtlDestroyMemoryBlockLookaside ntdll 893 +imp 'RtlDestroyMemoryZone' RtlDestroyMemoryZone ntdll 894 +imp 'RtlDestroyProcessParameters' RtlDestroyProcessParameters ntdll 895 1 +imp 'RtlDestroyQueryDebugBuffer' RtlDestroyQueryDebugBuffer ntdll 896 +imp 'RtlDetectHeapLeaks' RtlDetectHeapLeaks ntdll 897 +imp 'RtlDetermineDosPathNameType_U' RtlDetermineDosPathNameType_U ntdll 898 +imp 'RtlDisableThreadProfiling' RtlDisableThreadProfiling ntdll 899 +imp 'RtlDllShutdownInProgress' RtlDllShutdownInProgress ntdll 900 +imp 'RtlDnsHostNameToComputerName' RtlDnsHostNameToComputerName ntdll 901 +imp 'RtlDoesFileExists_U' RtlDoesFileExists_U ntdll 902 +imp 'RtlDosApplyFileIsolationRedirection_Ustr' RtlDosApplyFileIsolationRedirection_Ustr ntdll 903 +imp 'RtlDosLongPathNameToNtPathName_U_WithStatus' RtlDosLongPathNameToNtPathName_U_WithStatus ntdll 904 +imp 'RtlDosLongPathNameToRelativeNtPathName_U_WithStatus' RtlDosLongPathNameToRelativeNtPathName_U_WithStatus ntdll 905 +imp 'RtlDosPathNameToNtPathName_U' RtlDosPathNameToNtPathName_U ntdll 906 +imp 'RtlDosPathNameToNtPathName_U_WithStatus' RtlDosPathNameToNtPathName_U_WithStatus ntdll 907 +imp 'RtlDosPathNameToRelativeNtPathName_U' RtlDosPathNameToRelativeNtPathName_U ntdll 908 +imp 'RtlDosPathNameToRelativeNtPathName_U_WithStatus' RtlDosPathNameToRelativeNtPathName_U_WithStatus ntdll 909 +imp 'RtlDosSearchPath_U' RtlDosSearchPath_U ntdll 910 +imp 'RtlDosSearchPath_Ustr' RtlDosSearchPath_Ustr ntdll 911 +imp 'RtlDowncaseUnicodeChar' RtlDowncaseUnicodeChar ntdll 912 +imp 'RtlDowncaseUnicodeString' RtlDowncaseUnicodeString ntdll 913 +imp 'RtlDrainNonVolatileFlush' RtlDrainNonVolatileFlush ntdll 914 +imp 'RtlDumpResource' RtlDumpResource ntdll 915 +imp 'RtlDuplicateUnicodeString' RtlDuplicateUnicodeString ntdll 916 +imp 'RtlEmptyAtomTable' RtlEmptyAtomTable ntdll 917 +imp 'RtlEnableEarlyCriticalSectionEventCreation' RtlEnableEarlyCriticalSectionEventCreation ntdll 918 +imp 'RtlEnableThreadProfiling' RtlEnableThreadProfiling ntdll 919 +imp 'RtlEnclaveCallDispatch' RtlEnclaveCallDispatch ntdll 920 +imp 'RtlEnclaveCallDispatchReturn' RtlEnclaveCallDispatchReturn ntdll 921 +imp 'RtlEncodePointer' RtlEncodePointer ntdll 922 +imp 'RtlEncodeRemotePointer' RtlEncodeRemotePointer ntdll 923 +imp 'RtlEncodeSystemPointer' RtlEncodeSystemPointer ntdll 924 +imp 'RtlEndEnumerationHashTable' RtlEndEnumerationHashTable ntdll 925 +imp 'RtlEndStrongEnumerationHashTable' RtlEndStrongEnumerationHashTable ntdll 926 +imp 'RtlEndWeakEnumerationHashTable' RtlEndWeakEnumerationHashTable ntdll 927 +imp 'RtlEnterCriticalSection' RtlEnterCriticalSection ntdll 928 1 +imp 'RtlEnterUmsSchedulingMode' RtlEnterUmsSchedulingMode ntdll 929 +imp 'RtlEnumProcessHeaps' RtlEnumProcessHeaps ntdll 930 +imp 'RtlEnumerateEntryHashTable' RtlEnumerateEntryHashTable ntdll 931 +imp 'RtlEnumerateGenericTable' RtlEnumerateGenericTable ntdll 932 +imp 'RtlEnumerateGenericTableAvl' RtlEnumerateGenericTableAvl ntdll 933 +imp 'RtlEnumerateGenericTableLikeADirectory' RtlEnumerateGenericTableLikeADirectory ntdll 934 +imp 'RtlEnumerateGenericTableWithoutSplaying' RtlEnumerateGenericTableWithoutSplaying ntdll 935 +imp 'RtlEnumerateGenericTableWithoutSplayingAvl' RtlEnumerateGenericTableWithoutSplayingAvl ntdll 936 +imp 'RtlEqualComputerName' RtlEqualComputerName ntdll 937 +imp 'RtlEqualDomainName' RtlEqualDomainName ntdll 938 +imp 'RtlEqualLuid' RtlEqualLuid ntdll 939 +imp 'RtlEqualPrefixSid' RtlEqualPrefixSid ntdll 940 +imp 'RtlEqualSid' RtlEqualSid ntdll 941 +imp 'RtlEqualString' RtlEqualString ntdll 942 +imp 'RtlEqualUnicodeString' RtlEqualUnicodeString ntdll 943 +imp 'RtlEqualWnfChangeStamps' RtlEqualWnfChangeStamps ntdll 944 +imp 'RtlEraseUnicodeString' RtlEraseUnicodeString ntdll 945 +imp 'RtlEthernetAddressToStringA' RtlEthernetAddressToStringA ntdll 946 +imp 'RtlEthernetAddressToString' RtlEthernetAddressToStringW ntdll 947 +imp 'RtlEthernetStringToAddressA' RtlEthernetStringToAddressA ntdll 948 +imp 'RtlEthernetStringToAddress' RtlEthernetStringToAddressW ntdll 949 +imp 'RtlExecuteUmsThread' RtlExecuteUmsThread ntdll 950 +imp 'RtlExitUserProcess' RtlExitUserProcess ntdll 951 +imp 'RtlExitUserThread' RtlExitUserThread ntdll 952 +imp 'RtlExpandEnvironmentStrings' RtlExpandEnvironmentStrings ntdll 953 +imp 'RtlExpandEnvironmentStrings_U' RtlExpandEnvironmentStrings_U ntdll 954 +imp 'RtlExpandHashTable' RtlExpandHashTable ntdll 955 +imp 'RtlExtendCorrelationVector' RtlExtendCorrelationVector ntdll 956 +imp 'RtlExtendMemoryBlockLookaside' RtlExtendMemoryBlockLookaside ntdll 957 +imp 'RtlExtendMemoryZone' RtlExtendMemoryZone ntdll 958 +imp 'RtlExtractBitMap' RtlExtractBitMap ntdll 959 +imp 'RtlFillMemory' RtlFillMemory ntdll 960 +imp 'RtlFinalReleaseOutOfProcessMemoryStream' RtlFinalReleaseOutOfProcessMemoryStream ntdll 961 +imp 'RtlFindAceByType' RtlFindAceByType ntdll 962 +imp 'RtlFindActivationContextSectionGuid' RtlFindActivationContextSectionGuid ntdll 963 +imp 'RtlFindActivationContextSectionString' RtlFindActivationContextSectionString ntdll 964 +imp 'RtlFindCharInUnicodeString' RtlFindCharInUnicodeString ntdll 965 +imp 'RtlFindClearBits' RtlFindClearBits ntdll 966 +imp 'RtlFindClearBitsAndSet' RtlFindClearBitsAndSet ntdll 967 +imp 'RtlFindClearRuns' RtlFindClearRuns ntdll 968 +imp 'RtlFindClosestEncodableLength' RtlFindClosestEncodableLength ntdll 969 +imp 'RtlFindExportedRoutineByName' RtlFindExportedRoutineByName ntdll 970 +imp 'RtlFindLastBackwardRunClear' RtlFindLastBackwardRunClear ntdll 971 +imp 'RtlFindLeastSignificantBit' RtlFindLeastSignificantBit ntdll 972 +imp 'RtlFindLongestRunClear' RtlFindLongestRunClear ntdll 973 +imp 'RtlFindMessage' RtlFindMessage ntdll 974 +imp 'RtlFindMostSignificantBit' RtlFindMostSignificantBit ntdll 975 +imp 'RtlFindNextForwardRunClear' RtlFindNextForwardRunClear ntdll 976 +imp 'RtlFindSetBits' RtlFindSetBits ntdll 977 +imp 'RtlFindSetBitsAndClear' RtlFindSetBitsAndClear ntdll 978 +imp 'RtlFindUnicodeSubstring' RtlFindUnicodeSubstring ntdll 979 +imp 'RtlFirstEntrySList' RtlFirstEntrySList ntdll 980 +imp 'RtlFirstFreeAce' RtlFirstFreeAce ntdll 981 +imp 'RtlFlsAlloc' RtlFlsAlloc ntdll 982 +imp 'RtlFlsFree' RtlFlsFree ntdll 983 +imp 'RtlFlushHeaps' RtlFlushHeaps ntdll 984 +imp 'RtlFlushNonVolatileMemory' RtlFlushNonVolatileMemory ntdll 985 +imp 'RtlFlushNonVolatileMemoryRanges' RtlFlushNonVolatileMemoryRanges ntdll 986 +imp 'RtlFlushSecureMemoryCache' RtlFlushSecureMemoryCache ntdll 987 +imp 'RtlFormatCurrentUserKeyPath' RtlFormatCurrentUserKeyPath ntdll 988 +imp 'RtlFormatMessage' RtlFormatMessage ntdll 989 +imp 'RtlFormatMessageEx' RtlFormatMessageEx ntdll 990 +imp 'RtlFreeActivationContextStack' RtlFreeActivationContextStack ntdll 991 +imp 'RtlFreeAnsiString' RtlFreeAnsiString ntdll 992 +imp 'RtlFreeHandle' RtlFreeHandle ntdll 993 +imp 'RtlFreeHeap' RtlFreeHeap ntdll 994 3 +imp 'RtlFreeMemoryBlockLookaside' RtlFreeMemoryBlockLookaside ntdll 995 +imp 'RtlFreeNonVolatileToken' RtlFreeNonVolatileToken ntdll 996 +imp 'RtlFreeOemString' RtlFreeOemString ntdll 997 +imp 'RtlFreeSid' RtlFreeSid ntdll 998 +imp 'RtlFreeThreadActivationContextStack' RtlFreeThreadActivationContextStack ntdll 999 +imp 'RtlFreeUnicodeString' RtlFreeUnicodeString ntdll 1000 1 +imp 'RtlFreeUserStack' RtlFreeUserStack ntdll 1001 +imp 'RtlGUIDFromString' RtlGUIDFromString ntdll 1002 +imp 'RtlGenerate8dot3Name' RtlGenerate8dot3Name ntdll 1003 +imp 'RtlGetAce' RtlGetAce ntdll 1004 +imp 'RtlGetActiveActivationContext' RtlGetActiveActivationContext ntdll 1005 +imp 'RtlGetActiveConsoleId' RtlGetActiveConsoleId ntdll 1006 +imp 'RtlGetAppContainerNamedObjectPath' RtlGetAppContainerNamedObjectPath ntdll 1007 +imp 'RtlGetAppContainerParent' RtlGetAppContainerParent ntdll 1008 +imp 'RtlGetAppContainerSidType' RtlGetAppContainerSidType ntdll 1009 +imp 'RtlGetCallersAddress' RtlGetCallersAddress ntdll 1010 +imp 'RtlGetCompressionWorkSpaceSize' RtlGetCompressionWorkSpaceSize ntdll 1011 +imp 'RtlGetConsoleSessionForegroundProcessId' RtlGetConsoleSessionForegroundProcessId ntdll 1012 +imp 'RtlGetControlSecurityDescriptor' RtlGetControlSecurityDescriptor ntdll 1013 +imp 'RtlGetCriticalSectionRecursionCount' RtlGetCriticalSectionRecursionCount ntdll 1014 +imp 'RtlGetCurrentDirectory_U' RtlGetCurrentDirectory_U ntdll 1015 +imp 'RtlGetCurrentPeb' RtlGetCurrentPeb ntdll 1016 +imp 'RtlGetCurrentProcessorNumber' RtlGetCurrentProcessorNumber ntdll 1017 +imp 'RtlGetCurrentProcessorNumberEx' RtlGetCurrentProcessorNumberEx ntdll 1018 +imp 'RtlGetCurrentServiceSessionId' RtlGetCurrentServiceSessionId ntdll 1019 +imp 'RtlGetCurrentTransaction' RtlGetCurrentTransaction ntdll 1020 +imp 'RtlGetCurrentUmsThread' RtlGetCurrentUmsThread ntdll 1021 +imp 'RtlGetDaclSecurityDescriptor' RtlGetDaclSecurityDescriptor ntdll 1022 +imp 'RtlGetDeviceFamilyInfoEnum' RtlGetDeviceFamilyInfoEnum ntdll 1023 +imp 'RtlGetElementGenericTable' RtlGetElementGenericTable ntdll 1024 +imp 'RtlGetElementGenericTableAvl' RtlGetElementGenericTableAvl ntdll 1025 +imp 'RtlGetEnabledExtendedFeatures' RtlGetEnabledExtendedFeatures ntdll 1026 +imp 'RtlGetExePath' RtlGetExePath ntdll 1027 +imp 'RtlGetExtendedContextLength' RtlGetExtendedContextLength ntdll 1028 +imp 'RtlGetExtendedFeaturesMask' RtlGetExtendedFeaturesMask ntdll 1029 +imp 'RtlGetFileMUIPath' RtlGetFileMUIPath ntdll 1030 +imp 'RtlGetFrame' RtlGetFrame ntdll 1031 +imp 'RtlGetFullPathName_U' RtlGetFullPathName_U ntdll 1032 +imp 'RtlGetFullPathName_UEx' RtlGetFullPathName_UEx ntdll 1033 +imp 'RtlGetFullPathName_UstrEx' RtlGetFullPathName_UstrEx ntdll 1034 +imp 'RtlGetFunctionTableListHead' RtlGetFunctionTableListHead ntdll 1035 +imp 'RtlGetGroupSecurityDescriptor' RtlGetGroupSecurityDescriptor ntdll 1036 +imp 'RtlGetIntegerAtom' RtlGetIntegerAtom ntdll 1037 +imp 'RtlGetInterruptTimePrecise' RtlGetInterruptTimePrecise ntdll 1038 +imp 'RtlGetLastNtStatus' RtlGetLastNtStatus ntdll 1039 +imp 'RtlGetLastWin32Error' RtlGetLastWin32Error ntdll 1040 +imp 'RtlGetLengthWithoutLastFullDosOrNtPathElement' RtlGetLengthWithoutLastFullDosOrNtPathElement ntdll 1041 +imp 'RtlGetLengthWithoutTrailingPathSeperators' RtlGetLengthWithoutTrailingPathSeperators ntdll 1042 +imp 'RtlGetLocaleFileMappingAddress' RtlGetLocaleFileMappingAddress ntdll 1043 +imp 'RtlGetLongestNtPathLength' RtlGetLongestNtPathLength ntdll 1044 +imp 'RtlGetNativeSystemInformation' RtlGetNativeSystemInformation ntdll 1045 +imp 'RtlGetNextEntryHashTable' RtlGetNextEntryHashTable ntdll 1046 +imp 'RtlGetNextUmsListItem' RtlGetNextUmsListItem ntdll 1047 +imp 'RtlGetNonVolatileToken' RtlGetNonVolatileToken ntdll 1048 +imp 'RtlGetNtGlobalFlags' RtlGetNtGlobalFlags ntdll 1049 +imp 'RtlGetNtProductType' RtlGetNtProductType ntdll 1050 +imp 'RtlGetNtSystemRoot' RtlGetNtSystemRoot ntdll 1051 +imp 'RtlGetNtVersionNumbers' RtlGetNtVersionNumbers ntdll 1052 +imp 'RtlGetOwnerSecurityDescriptor' RtlGetOwnerSecurityDescriptor ntdll 1053 +imp 'RtlGetParentLocaleName' RtlGetParentLocaleName ntdll 1054 +imp 'RtlGetPersistedStateLocation' RtlGetPersistedStateLocation ntdll 1055 +imp 'RtlGetProcessHeaps' RtlGetProcessHeaps ntdll 1056 2 +imp 'RtlGetProcessPreferredUILanguages' RtlGetProcessPreferredUILanguages ntdll 1057 +imp 'RtlGetProductInfo' RtlGetProductInfo ntdll 1058 +imp 'RtlGetSaclSecurityDescriptor' RtlGetSaclSecurityDescriptor ntdll 1059 +imp 'RtlGetSearchPath' RtlGetSearchPath ntdll 1060 +imp 'RtlGetSecurityDescriptorRMControl' RtlGetSecurityDescriptorRMControl ntdll 1061 +imp 'RtlGetSessionProperties' RtlGetSessionProperties ntdll 1062 +imp 'RtlGetSetBootStatusData' RtlGetSetBootStatusData ntdll 1063 +imp 'RtlGetSuiteMask' RtlGetSuiteMask ntdll 1064 +imp 'RtlGetSystemBootStatus' RtlGetSystemBootStatus ntdll 1065 +imp 'RtlGetSystemBootStatusEx' RtlGetSystemBootStatusEx ntdll 1066 +imp 'RtlGetSystemPreferredUILanguages' RtlGetSystemPreferredUILanguages ntdll 1067 +imp 'RtlGetSystemTimePrecise' RtlGetSystemTimePrecise ntdll 1068 +imp 'RtlGetThreadErrorMode' RtlGetThreadErrorMode ntdll 1069 +imp 'RtlGetThreadLangIdByIndex' RtlGetThreadLangIdByIndex ntdll 1070 +imp 'RtlGetThreadPreferredUILanguages' RtlGetThreadPreferredUILanguages ntdll 1071 +imp 'RtlGetThreadWorkOnBehalfTicket' RtlGetThreadWorkOnBehalfTicket ntdll 1072 +imp 'RtlGetTokenNamedObjectPath' RtlGetTokenNamedObjectPath ntdll 1073 +imp 'RtlGetUILanguageInfo' RtlGetUILanguageInfo ntdll 1074 +imp 'RtlGetUmsCompletionListEvent' RtlGetUmsCompletionListEvent ntdll 1075 +imp 'RtlGetUnloadEventTrace' RtlGetUnloadEventTrace ntdll 1076 +imp 'RtlGetUnloadEventTraceEx' RtlGetUnloadEventTraceEx ntdll 1077 +imp 'RtlGetUserInfoHeap' RtlGetUserInfoHeap ntdll 1078 +imp 'RtlGetUserPreferredUILanguages' RtlGetUserPreferredUILanguages ntdll 1079 +imp 'RtlGetVersion' RtlGetVersion ntdll 1080 +imp 'RtlGrowFunctionTable' RtlGrowFunctionTable ntdll 1081 +imp 'RtlGuardCheckLongJumpTarget' RtlGuardCheckLongJumpTarget ntdll 1082 +imp 'RtlHashUnicodeString' RtlHashUnicodeString ntdll 1083 +imp 'RtlHeapTrkInitialize' RtlHeapTrkInitialize ntdll 1084 +imp 'RtlIdentifierAuthoritySid' RtlIdentifierAuthoritySid ntdll 1085 +imp 'RtlIdnToAscii' RtlIdnToAscii ntdll 1086 +imp 'RtlIdnToNameprepUnicode' RtlIdnToNameprepUnicode ntdll 1087 +imp 'RtlIdnToUnicode' RtlIdnToUnicode ntdll 1088 +imp 'RtlImageDirectoryEntryToData' RtlImageDirectoryEntryToData ntdll 1089 +imp 'RtlImageNtHeader' RtlImageNtHeader ntdll 1090 +imp 'RtlImageNtHeaderEx' RtlImageNtHeaderEx ntdll 1091 +imp 'RtlImageRvaToSection' RtlImageRvaToSection ntdll 1092 +imp 'RtlImageRvaToVa' RtlImageRvaToVa ntdll 1093 +imp 'RtlImpersonateSelf' RtlImpersonateSelf ntdll 1094 +imp 'RtlImpersonateSelfEx' RtlImpersonateSelfEx ntdll 1095 +imp 'RtlIncrementCorrelationVector' RtlIncrementCorrelationVector ntdll 1096 +imp 'RtlInitAnsiString' RtlInitAnsiString ntdll 1097 +imp 'RtlInitAnsiStringEx' RtlInitAnsiStringEx ntdll 1098 +imp 'RtlInitBarrier' RtlInitBarrier ntdll 1099 +imp 'RtlInitCodePageTable' RtlInitCodePageTable ntdll 1100 +imp 'RtlInitEnumerationHashTable' RtlInitEnumerationHashTable ntdll 1101 +imp 'RtlInitMemoryStream' RtlInitMemoryStream ntdll 1102 +imp 'RtlInitNlsTables' RtlInitNlsTables ntdll 1103 +imp 'RtlInitOutOfProcessMemoryStream' RtlInitOutOfProcessMemoryStream ntdll 1104 +imp 'RtlInitString' RtlInitString ntdll 1105 +imp 'RtlInitStringEx' RtlInitStringEx ntdll 1106 +imp 'RtlInitStrongEnumerationHashTable' RtlInitStrongEnumerationHashTable ntdll 1107 +imp 'RtlInitUnicodeString' RtlInitUnicodeString ntdll 1108 2 +imp 'RtlInitUnicodeStringEx' RtlInitUnicodeStringEx ntdll 1109 +imp 'RtlInitWeakEnumerationHashTable' RtlInitWeakEnumerationHashTable ntdll 1110 +imp 'RtlInitializeAtomPackage' RtlInitializeAtomPackage ntdll 1111 +imp 'RtlInitializeBitMap' RtlInitializeBitMap ntdll 1112 +imp 'RtlInitializeBitMapEx' RtlInitializeBitMapEx ntdll 1113 +imp 'RtlInitializeConditionVariable' RtlInitializeConditionVariable ntdll 1114 +imp 'RtlInitializeContext' RtlInitializeContext ntdll 1115 +imp 'RtlInitializeCorrelationVector' RtlInitializeCorrelationVector ntdll 1116 +imp 'RtlInitializeCriticalSection' RtlInitializeCriticalSection ntdll 1117 1 +imp 'RtlInitializeCriticalSectionAndSpinCount' RtlInitializeCriticalSectionAndSpinCount ntdll 1118 +imp 'RtlInitializeCriticalSectionEx' RtlInitializeCriticalSectionEx ntdll 1119 +imp 'RtlInitializeExtendedContext' RtlInitializeExtendedContext ntdll 1120 +imp 'RtlInitializeGenericTable' RtlInitializeGenericTable ntdll 1121 +imp 'RtlInitializeGenericTableAvl' RtlInitializeGenericTableAvl ntdll 1122 +imp 'RtlInitializeHandleTable' RtlInitializeHandleTable ntdll 1123 +imp 'RtlInitializeNtUserPfn' RtlInitializeNtUserPfn ntdll 1124 +imp 'RtlInitializeRXact' RtlInitializeRXact ntdll 1125 +imp 'RtlInitializeResource' RtlInitializeResource ntdll 1126 +imp 'RtlInitializeSListHead' RtlInitializeSListHead ntdll 1127 +imp 'RtlInitializeSRWLock' RtlInitializeSRWLock ntdll 1128 +imp 'RtlInitializeSid' RtlInitializeSid ntdll 1129 +imp 'RtlInitializeSidEx' RtlInitializeSidEx ntdll 1130 +imp 'RtlInsertElementGenericTable' RtlInsertElementGenericTable ntdll 1131 +imp 'RtlInsertElementGenericTableAvl' RtlInsertElementGenericTableAvl ntdll 1132 +imp 'RtlInsertElementGenericTableFull' RtlInsertElementGenericTableFull ntdll 1133 +imp 'RtlInsertElementGenericTableFullAvl' RtlInsertElementGenericTableFullAvl ntdll 1134 +imp 'RtlInsertEntryHashTable' RtlInsertEntryHashTable ntdll 1135 +imp 'RtlInstallFunctionTableCallback' RtlInstallFunctionTableCallback ntdll 1136 +imp 'RtlInt64ToUnicodeString' RtlInt64ToUnicodeString ntdll 1137 +imp 'RtlIntegerToChar' RtlIntegerToChar ntdll 1138 +imp 'RtlIntegerToUnicodeString' RtlIntegerToUnicodeString ntdll 1139 +imp 'RtlInterlockedClearBitRun' RtlInterlockedClearBitRun ntdll 1140 +imp 'RtlInterlockedFlushSList' RtlInterlockedFlushSList ntdll 1141 +imp 'RtlInterlockedPopEntrySList' RtlInterlockedPopEntrySList ntdll 1142 +imp 'RtlInterlockedPushEntrySList' RtlInterlockedPushEntrySList ntdll 1143 +imp 'RtlInterlockedPushListSList' RtlInterlockedPushListSList ntdll 1144 +imp 'RtlInterlockedPushListSListEx' RtlInterlockedPushListSListEx ntdll 1145 +imp 'RtlInterlockedSetBitRun' RtlInterlockedSetBitRun ntdll 1146 +imp 'RtlIoDecodeMemIoResource' RtlIoDecodeMemIoResource ntdll 1147 +imp 'RtlIoEncodeMemIoResource' RtlIoEncodeMemIoResource ntdll 1148 +imp 'RtlIpv4AddressToStringA' RtlIpv4AddressToStringA ntdll 1149 +imp 'RtlIpv4AddressToStringExA' RtlIpv4AddressToStringExA ntdll 1150 +imp 'RtlIpv4AddressToStringEx' RtlIpv4AddressToStringExW ntdll 1151 +imp 'RtlIpv4AddressToString' RtlIpv4AddressToStringW ntdll 1152 +imp 'RtlIpv4StringToAddressA' RtlIpv4StringToAddressA ntdll 1153 +imp 'RtlIpv4StringToAddressExA' RtlIpv4StringToAddressExA ntdll 1154 +imp 'RtlIpv4StringToAddressEx' RtlIpv4StringToAddressExW ntdll 1155 +imp 'RtlIpv4StringToAddress' RtlIpv4StringToAddressW ntdll 1156 +imp 'RtlIpv6AddressToStringA' RtlIpv6AddressToStringA ntdll 1157 +imp 'RtlIpv6AddressToStringExA' RtlIpv6AddressToStringExA ntdll 1158 +imp 'RtlIpv6AddressToStringEx' RtlIpv6AddressToStringExW ntdll 1159 +imp 'RtlIpv6AddressToString' RtlIpv6AddressToStringW ntdll 1160 +imp 'RtlIpv6StringToAddressA' RtlIpv6StringToAddressA ntdll 1161 +imp 'RtlIpv6StringToAddressExA' RtlIpv6StringToAddressExA ntdll 1162 +imp 'RtlIpv6StringToAddressEx' RtlIpv6StringToAddressExW ntdll 1163 +imp 'RtlIpv6StringToAddress' RtlIpv6StringToAddressW ntdll 1164 +imp 'RtlIsActivationContextActive' RtlIsActivationContextActive ntdll 1165 +imp 'RtlIsCapabilitySid' RtlIsCapabilitySid ntdll 1166 +imp 'RtlIsCloudFilesPlaceholder' RtlIsCloudFilesPlaceholder ntdll 1167 +imp 'RtlIsCriticalSectionLocked' RtlIsCriticalSectionLocked ntdll 1168 +imp 'RtlIsCriticalSectionLockedByThread' RtlIsCriticalSectionLockedByThread ntdll 1169 +imp 'RtlIsCurrentProcess' RtlIsCurrentProcess ntdll 1170 +imp 'RtlIsCurrentThread' RtlIsCurrentThread ntdll 1171 +imp 'RtlIsCurrentThreadAttachExempt' RtlIsCurrentThreadAttachExempt ntdll 1172 +imp 'RtlIsDosDeviceName_U' RtlIsDosDeviceName_U ntdll 1173 +imp 'RtlIsElevatedRid' RtlIsElevatedRid ntdll 1174 +imp 'RtlIsGenericTableEmpty' RtlIsGenericTableEmpty ntdll 1175 +imp 'RtlIsGenericTableEmptyAvl' RtlIsGenericTableEmptyAvl ntdll 1176 +imp 'RtlIsMultiSessionSku' RtlIsMultiSessionSku ntdll 1177 +imp 'RtlIsMultiUsersInSessionSku' RtlIsMultiUsersInSessionSku ntdll 1178 +imp 'RtlIsNameInExpression' RtlIsNameInExpression ntdll 1179 +imp 'RtlIsNameInUnUpcasedExpression' RtlIsNameInUnUpcasedExpression ntdll 1180 +imp 'RtlIsNameLegalDOS8Dot3' RtlIsNameLegalDOS8Dot3 ntdll 1181 +imp 'RtlIsNonEmptyDirectoryReparsePointAllowed' RtlIsNonEmptyDirectoryReparsePointAllowed ntdll 1182 +imp 'RtlIsNormalizedString' RtlIsNormalizedString ntdll 1183 +imp 'RtlIsPackageSid' RtlIsPackageSid ntdll 1184 +imp 'RtlIsParentOfChildAppContainer' RtlIsParentOfChildAppContainer ntdll 1185 +imp 'RtlIsPartialPlaceholder' RtlIsPartialPlaceholder ntdll 1186 +imp 'RtlIsPartialPlaceholderFileHandle' RtlIsPartialPlaceholderFileHandle ntdll 1187 +imp 'RtlIsPartialPlaceholderFileInfo' RtlIsPartialPlaceholderFileInfo ntdll 1188 +imp 'RtlIsProcessorFeaturePresent' RtlIsProcessorFeaturePresent ntdll 1189 +imp 'RtlIsStateSeparationEnabled' RtlIsStateSeparationEnabled ntdll 1190 +imp 'RtlIsTextUnicode' RtlIsTextUnicode ntdll 1191 +imp 'RtlIsThreadWithinLoaderCallout' RtlIsThreadWithinLoaderCallout ntdll 1192 +imp 'RtlIsUntrustedObject' RtlIsUntrustedObject ntdll 1193 +imp 'RtlIsValidHandle' RtlIsValidHandle ntdll 1194 +imp 'RtlIsValidIndexHandle' RtlIsValidIndexHandle ntdll 1195 +imp 'RtlIsValidLocaleName' RtlIsValidLocaleName ntdll 1196 +imp 'RtlIsValidProcessTrustLabelSid' RtlIsValidProcessTrustLabelSid ntdll 1197 +imp 'RtlKnownExceptionFilter' RtlKnownExceptionFilter ntdll 1198 +imp 'RtlLCIDToCultureName' RtlLCIDToCultureName ntdll 1199 +imp 'RtlLargeIntegerToChar' RtlLargeIntegerToChar ntdll 1200 +imp 'RtlLcidToLocaleName' RtlLcidToLocaleName ntdll 1201 +imp 'RtlLeaveCriticalSection' RtlLeaveCriticalSection ntdll 1202 1 +imp 'RtlLengthRequiredSid' RtlLengthRequiredSid ntdll 1203 +imp 'RtlLengthSecurityDescriptor' RtlLengthSecurityDescriptor ntdll 1204 +imp 'RtlLengthSid' RtlLengthSid ntdll 1205 +imp 'RtlLengthSidAsUnicodeString' RtlLengthSidAsUnicodeString ntdll 1206 +imp 'RtlLoadString' RtlLoadString ntdll 1207 +imp 'RtlLocalTimeToSystemTime' RtlLocalTimeToSystemTime ntdll 1208 +imp 'RtlLocaleNameToLcid' RtlLocaleNameToLcid ntdll 1209 +imp 'RtlLocateExtendedFeature' RtlLocateExtendedFeature ntdll 1210 +imp 'RtlLocateExtendedFeature2' RtlLocateExtendedFeature2 ntdll 1211 +imp 'RtlLocateLegacyContext' RtlLocateLegacyContext ntdll 1212 +imp 'RtlLockBootStatusData' RtlLockBootStatusData ntdll 1213 +imp 'RtlLockCurrentThread' RtlLockCurrentThread ntdll 1214 +imp 'RtlLockHeap' RtlLockHeap ntdll 1215 1 +imp 'RtlLockMemoryBlockLookaside' RtlLockMemoryBlockLookaside ntdll 1216 +imp 'RtlLockMemoryStreamRegion' RtlLockMemoryStreamRegion ntdll 1217 +imp 'RtlLockMemoryZone' RtlLockMemoryZone ntdll 1218 +imp 'RtlLockModuleSection' RtlLockModuleSection ntdll 1219 +imp 'RtlLogStackBackTrace' RtlLogStackBackTrace ntdll 1220 +imp 'RtlLookupAtomInAtomTable' RtlLookupAtomInAtomTable ntdll 1221 +imp 'RtlLookupElementGenericTable' RtlLookupElementGenericTable ntdll 1222 +imp 'RtlLookupElementGenericTableAvl' RtlLookupElementGenericTableAvl ntdll 1223 +imp 'RtlLookupElementGenericTableFull' RtlLookupElementGenericTableFull ntdll 1224 +imp 'RtlLookupElementGenericTableFullAvl' RtlLookupElementGenericTableFullAvl ntdll 1225 +imp 'RtlLookupEntryHashTable' RtlLookupEntryHashTable ntdll 1226 +imp 'RtlLookupFirstMatchingElementGenericTableAvl' RtlLookupFirstMatchingElementGenericTableAvl ntdll 1227 +imp 'RtlLookupFunctionEntry' RtlLookupFunctionEntry ntdll 1228 +imp 'RtlLookupFunctionTable' RtlLookupFunctionTable ntdll 1229 +imp 'RtlMakeSelfRelativeSD' RtlMakeSelfRelativeSD ntdll 1230 +imp 'RtlMapGenericMask' RtlMapGenericMask ntdll 1231 +imp 'RtlMapSecurityErrorToNtStatus' RtlMapSecurityErrorToNtStatus ntdll 1232 +imp 'RtlMoveMemory' RtlMoveMemory ntdll 1233 +imp 'RtlMultiAppendUnicodeStringBuffer' RtlMultiAppendUnicodeStringBuffer ntdll 1234 +imp 'RtlMultiByteToUnicodeN' RtlMultiByteToUnicodeN ntdll 1235 +imp 'RtlMultiByteToUnicodeSize' RtlMultiByteToUnicodeSize ntdll 1236 +imp 'RtlMultipleAllocateHeap' RtlMultipleAllocateHeap ntdll 1237 +imp 'RtlMultipleFreeHeap' RtlMultipleFreeHeap ntdll 1238 +imp 'RtlNewInstanceSecurityObject' RtlNewInstanceSecurityObject ntdll 1239 +imp 'RtlNewSecurityGrantedAccess' RtlNewSecurityGrantedAccess ntdll 1240 +imp 'RtlNewSecurityObject' RtlNewSecurityObject ntdll 1241 +imp 'RtlNewSecurityObjectEx' RtlNewSecurityObjectEx ntdll 1242 +imp 'RtlNewSecurityObjectWithMultipleInheritance' RtlNewSecurityObjectWithMultipleInheritance ntdll 1243 +imp 'RtlNormalizeProcessParams' RtlNormalizeProcessParams ntdll 1244 +imp 'RtlNormalizeString' RtlNormalizeString ntdll 1245 +imp 'RtlNtPathNameToDosPathName' RtlNtPathNameToDosPathName ntdll 1246 +imp 'RtlNtStatusToDosError' RtlNtStatusToDosError ntdll 1247 +imp 'RtlNtStatusToDosErrorNoTeb' RtlNtStatusToDosErrorNoTeb ntdll 1248 +imp 'RtlNtdllName' RtlNtdllName ntdll 1249 +imp 'RtlNumberGenericTableElements' RtlNumberGenericTableElements ntdll 1250 +imp 'RtlNumberGenericTableElementsAvl' RtlNumberGenericTableElementsAvl ntdll 1251 +imp 'RtlNumberOfClearBits' RtlNumberOfClearBits ntdll 1252 +imp 'RtlNumberOfClearBitsInRange' RtlNumberOfClearBitsInRange ntdll 1253 +imp 'RtlNumberOfSetBits' RtlNumberOfSetBits ntdll 1254 +imp 'RtlNumberOfSetBitsInRange' RtlNumberOfSetBitsInRange ntdll 1255 +imp 'RtlNumberOfSetBitsUlongPtr' RtlNumberOfSetBitsUlongPtr ntdll 1256 +imp 'RtlOemStringToUnicodeSize' RtlOemStringToUnicodeSize ntdll 1257 +imp 'RtlOemStringToUnicodeString' RtlOemStringToUnicodeString ntdll 1258 +imp 'RtlOemToUnicodeN' RtlOemToUnicodeN ntdll 1259 +imp 'RtlOpenCurrentUser' RtlOpenCurrentUser ntdll 1260 +imp 'RtlOsDeploymentState' RtlOsDeploymentState ntdll 1261 +imp 'RtlOwnerAcesPresent' RtlOwnerAcesPresent ntdll 1262 +imp 'RtlPcToFileHeader' RtlPcToFileHeader ntdll 1263 +imp 'RtlPinAtomInAtomTable' RtlPinAtomInAtomTable ntdll 1264 +imp 'RtlPopFrame' RtlPopFrame ntdll 1265 +imp 'RtlPrefixString' RtlPrefixString ntdll 1266 +imp 'RtlPrefixUnicodeString' RtlPrefixUnicodeString ntdll 1267 +imp 'RtlPrepareForProcessCloning' RtlPrepareForProcessCloning ntdll 1268 +imp 'RtlProcessFlsData' RtlProcessFlsData ntdll 1269 +imp 'RtlProtectHeap' RtlProtectHeap ntdll 1270 +imp 'RtlPublishWnfStateData' RtlPublishWnfStateData ntdll 1271 +imp 'RtlPushFrame' RtlPushFrame ntdll 1272 +imp 'RtlQueryActivationContextApplicationSettings' RtlQueryActivationContextApplicationSettings ntdll 1273 +imp 'RtlQueryAtomInAtomTable' RtlQueryAtomInAtomTable ntdll 1274 +imp 'RtlQueryCriticalSectionOwner' RtlQueryCriticalSectionOwner ntdll 1275 +imp 'RtlQueryDepthSList' RtlQueryDepthSList ntdll 1276 +imp 'RtlQueryDynamicTimeZoneInformation' RtlQueryDynamicTimeZoneInformation ntdll 1277 +imp 'RtlQueryElevationFlags' RtlQueryElevationFlags ntdll 1278 +imp 'RtlQueryEnvironmentVariable' RtlQueryEnvironmentVariable ntdll 1279 3 +imp 'RtlQueryEnvironmentVariable_U' RtlQueryEnvironmentVariable_U ntdll 1280 +imp 'RtlQueryHeapInformation' RtlQueryHeapInformation ntdll 1281 +imp 'RtlQueryImageMitigationPolicy' RtlQueryImageMitigationPolicy ntdll 1282 +imp 'RtlQueryInformationAcl' RtlQueryInformationAcl ntdll 1283 +imp 'RtlQueryInformationActivationContext' RtlQueryInformationActivationContext ntdll 1284 +imp 'RtlQueryInformationActiveActivationContext' RtlQueryInformationActiveActivationContext ntdll 1285 +imp 'RtlQueryInterfaceMemoryStream' RtlQueryInterfaceMemoryStream ntdll 1286 +imp 'RtlQueryModuleInformation' RtlQueryModuleInformation ntdll 1287 +imp 'RtlQueryPackageClaims' RtlQueryPackageClaims ntdll 1288 +imp 'RtlQueryPackageIdentity' RtlQueryPackageIdentity ntdll 1289 +imp 'RtlQueryPackageIdentityEx' RtlQueryPackageIdentityEx ntdll 1290 +imp 'RtlQueryPerformanceCounter' RtlQueryPerformanceCounter ntdll 1291 +imp 'RtlQueryPerformanceFrequency' RtlQueryPerformanceFrequency ntdll 1292 +imp 'RtlQueryProcessBackTraceInformation' RtlQueryProcessBackTraceInformation ntdll 1293 +imp 'RtlQueryProcessDebugInformation' RtlQueryProcessDebugInformation ntdll 1294 +imp 'RtlQueryProcessHeapInformation' RtlQueryProcessHeapInformation ntdll 1295 +imp 'RtlQueryProcessLockInformation' RtlQueryProcessLockInformation ntdll 1296 +imp 'RtlQueryProcessPlaceholderCompatibilityMode' RtlQueryProcessPlaceholderCompatibilityMode ntdll 1297 +imp 'RtlQueryProtectedPolicy' RtlQueryProtectedPolicy ntdll 1298 +imp 'RtlQueryRegistryValueWithFallback' RtlQueryRegistryValueWithFallback ntdll 1299 +imp 'RtlQueryRegistryValues' RtlQueryRegistryValues ntdll 1300 +imp 'RtlQueryRegistryValuesEx' RtlQueryRegistryValuesEx ntdll 1301 +imp 'RtlQueryResourcePolicy' RtlQueryResourcePolicy ntdll 1302 +imp 'RtlQuerySecurityObject' RtlQuerySecurityObject ntdll 1303 +imp 'RtlQueryTagHeap' RtlQueryTagHeap ntdll 1304 +imp 'RtlQueryThreadPlaceholderCompatibilityMode' RtlQueryThreadPlaceholderCompatibilityMode ntdll 1305 +imp 'RtlQueryThreadProfiling' RtlQueryThreadProfiling ntdll 1306 +imp 'RtlQueryTimeZoneInformation' RtlQueryTimeZoneInformation ntdll 1307 +imp 'RtlQueryTokenHostIdAsUlong64' RtlQueryTokenHostIdAsUlong64 ntdll 1308 +imp 'RtlQueryUmsThreadInformation' RtlQueryUmsThreadInformation ntdll 1309 +imp 'RtlQueryUnbiasedInterruptTime' RtlQueryUnbiasedInterruptTime ntdll 1310 +imp 'RtlQueryValidationRunlevel' RtlQueryValidationRunlevel ntdll 1311 +imp 'RtlQueryWnfMetaNotification' RtlQueryWnfMetaNotification ntdll 1312 +imp 'RtlQueryWnfStateData' RtlQueryWnfStateData ntdll 1313 +imp 'RtlQueryWnfStateDataWithExplicitScope' RtlQueryWnfStateDataWithExplicitScope ntdll 1314 +imp 'RtlQueueApcWow64Thread' RtlQueueApcWow64Thread ntdll 1315 +imp 'RtlQueueWorkItem' RtlQueueWorkItem ntdll 1316 +imp 'RtlRaiseCustomSystemEventTrigger' RtlRaiseCustomSystemEventTrigger ntdll 1317 +imp 'RtlRaiseException' RtlRaiseException ntdll 1318 +imp 'RtlRaiseStatus' RtlRaiseStatus ntdll 1319 +imp 'RtlRandom' RtlRandom ntdll 1320 +imp 'RtlRandomEx' RtlRandomEx ntdll 1321 +imp 'RtlRbInsertNodeEx' RtlRbInsertNodeEx ntdll 1322 +imp 'RtlRbRemoveNode' RtlRbRemoveNode ntdll 1323 +imp 'RtlReAllocateHeap' RtlReAllocateHeap ntdll 1324 4 +imp 'RtlReadMemoryStream' RtlReadMemoryStream ntdll 1325 +imp 'RtlReadOutOfProcessMemoryStream' RtlReadOutOfProcessMemoryStream ntdll 1326 +imp 'RtlReadThreadProfilingData' RtlReadThreadProfilingData ntdll 1327 +imp 'RtlRealPredecessor' RtlRealPredecessor ntdll 1328 +imp 'RtlRealSuccessor' RtlRealSuccessor ntdll 1329 +imp 'RtlRegisterForWnfMetaNotification' RtlRegisterForWnfMetaNotification ntdll 1330 +imp 'RtlRegisterSecureMemoryCacheCallback' RtlRegisterSecureMemoryCacheCallback ntdll 1331 +imp 'RtlRegisterThreadWithCsrss' RtlRegisterThreadWithCsrss ntdll 1332 +imp 'RtlRegisterWait' RtlRegisterWait ntdll 1333 +imp 'RtlReleaseActivationContext' RtlReleaseActivationContext ntdll 1334 +imp 'RtlReleaseMemoryStream' RtlReleaseMemoryStream ntdll 1335 +imp 'RtlReleasePath' RtlReleasePath ntdll 1336 +imp 'RtlReleasePebLock' RtlReleasePebLock ntdll 1337 +imp 'RtlReleasePrivilege' RtlReleasePrivilege ntdll 1338 +imp 'RtlReleaseRelativeName' RtlReleaseRelativeName ntdll 1339 +imp 'RtlReleaseResource' RtlReleaseResource ntdll 1340 +imp 'RtlReleaseSRWLockExclusive' RtlReleaseSRWLockExclusive ntdll 1341 +imp 'RtlReleaseSRWLockShared' RtlReleaseSRWLockShared ntdll 1342 +imp 'RtlRemoteCall' RtlRemoteCall ntdll 1343 +imp 'RtlRemoveEntryHashTable' RtlRemoveEntryHashTable ntdll 1344 +imp 'RtlRemovePrivileges' RtlRemovePrivileges ntdll 1345 +imp 'RtlRemoveVectoredContinueHandler' RtlRemoveVectoredContinueHandler ntdll 1346 +imp 'RtlRemoveVectoredExceptionHandler' RtlRemoveVectoredExceptionHandler ntdll 1347 +imp 'RtlReplaceSidInSd' RtlReplaceSidInSd ntdll 1348 +imp 'RtlReplaceSystemDirectoryInPath' RtlReplaceSystemDirectoryInPath ntdll 1349 +imp 'RtlReportException' RtlReportException ntdll 1350 +imp 'RtlReportExceptionEx' RtlReportExceptionEx ntdll 1351 +imp 'RtlReportSilentProcessExit' RtlReportSilentProcessExit ntdll 1352 +imp 'RtlReportSqmEscalation' RtlReportSqmEscalation ntdll 1353 +imp 'RtlResetMemoryBlockLookaside' RtlResetMemoryBlockLookaside ntdll 1354 +imp 'RtlResetMemoryZone' RtlResetMemoryZone ntdll 1355 +imp 'RtlResetNtUserPfn' RtlResetNtUserPfn ntdll 1356 +imp 'RtlResetRtlTranslations' RtlResetRtlTranslations ntdll 1357 +imp 'RtlRestoreBootStatusDefaults' RtlRestoreBootStatusDefaults ntdll 1358 +imp 'RtlRestoreContext' RtlRestoreContext ntdll 1359 +imp 'RtlRestoreLastWin32Error' RtlRestoreLastWin32Error ntdll 1360 +imp 'RtlRestoreSystemBootStatusDefaults' RtlRestoreSystemBootStatusDefaults ntdll 1361 +imp 'RtlRetrieveNtUserPfn' RtlRetrieveNtUserPfn ntdll 1362 +imp 'RtlRevertMemoryStream' RtlRevertMemoryStream ntdll 1363 +imp 'RtlRunDecodeUnicodeString' RtlRunDecodeUnicodeString ntdll 1364 +imp 'RtlRunEncodeUnicodeString' RtlRunEncodeUnicodeString ntdll 1365 +imp 'RtlRunOnceBeginInitialize' RtlRunOnceBeginInitialize ntdll 1366 +imp 'RtlRunOnceComplete' RtlRunOnceComplete ntdll 1367 +imp 'RtlRunOnceExecuteOnce' RtlRunOnceExecuteOnce ntdll 1368 +imp 'RtlRunOnceInitialize' RtlRunOnceInitialize ntdll 1369 +imp 'RtlSecondsSince1970ToTime' RtlSecondsSince1970ToTime ntdll 1370 +imp 'RtlSecondsSince1980ToTime' RtlSecondsSince1980ToTime ntdll 1371 +imp 'RtlSeekMemoryStream' RtlSeekMemoryStream ntdll 1372 +imp 'RtlSelfRelativeToAbsoluteSD' RtlSelfRelativeToAbsoluteSD ntdll 1373 +imp 'RtlSelfRelativeToAbsoluteSD2' RtlSelfRelativeToAbsoluteSD2 ntdll 1374 +imp 'RtlSendMsgToSm' RtlSendMsgToSm ntdll 1375 +imp 'RtlSetAllBits' RtlSetAllBits ntdll 1376 +imp 'RtlSetAttributesSecurityDescriptor' RtlSetAttributesSecurityDescriptor ntdll 1377 +imp 'RtlSetBit' RtlSetBit ntdll 1378 +imp 'RtlSetBits' RtlSetBits ntdll 1379 +imp 'RtlSetControlSecurityDescriptor' RtlSetControlSecurityDescriptor ntdll 1380 +imp 'RtlSetCriticalSectionSpinCount' RtlSetCriticalSectionSpinCount ntdll 1381 +imp 'RtlSetCurrentDirectory_U' RtlSetCurrentDirectory_U ntdll 1382 +imp 'RtlSetCurrentEnvironment' RtlSetCurrentEnvironment ntdll 1383 +imp 'RtlSetCurrentTransaction' RtlSetCurrentTransaction ntdll 1384 +imp 'RtlSetDaclSecurityDescriptor' RtlSetDaclSecurityDescriptor ntdll 1385 +imp 'RtlSetDynamicTimeZoneInformation' RtlSetDynamicTimeZoneInformation ntdll 1386 +imp 'RtlSetEnvironmentStrings' RtlSetEnvironmentStrings ntdll 1387 +imp 'RtlSetEnvironmentVar' RtlSetEnvironmentVar ntdll 1388 +imp 'RtlSetEnvironmentVariable' RtlSetEnvironmentVariable ntdll 1389 +imp 'RtlSetExtendedFeaturesMask' RtlSetExtendedFeaturesMask ntdll 1390 +imp 'RtlSetGroupSecurityDescriptor' RtlSetGroupSecurityDescriptor ntdll 1391 +imp 'RtlSetHeapInformation' RtlSetHeapInformation ntdll 1392 +imp 'RtlSetImageMitigationPolicy' RtlSetImageMitigationPolicy ntdll 1393 +imp 'RtlSetInformationAcl' RtlSetInformationAcl ntdll 1394 +imp 'RtlSetIoCompletionCallback' RtlSetIoCompletionCallback ntdll 1395 +imp 'RtlSetLastWin32Error' RtlSetLastWin32Error ntdll 1396 +imp 'RtlSetLastWin32ErrorAndNtStatusFromNtStatus' RtlSetLastWin32ErrorAndNtStatusFromNtStatus ntdll 1397 +imp 'RtlSetMemoryStreamSize' RtlSetMemoryStreamSize ntdll 1398 +imp 'RtlSetOwnerSecurityDescriptor' RtlSetOwnerSecurityDescriptor ntdll 1399 +imp 'RtlSetPortableOperatingSystem' RtlSetPortableOperatingSystem ntdll 1400 +imp 'RtlSetProcessDebugInformation' RtlSetProcessDebugInformation ntdll 1401 +imp 'RtlSetProcessIsCritical' RtlSetProcessIsCritical ntdll 1402 +imp 'RtlSetProcessPlaceholderCompatibilityMode' RtlSetProcessPlaceholderCompatibilityMode ntdll 1403 +imp 'RtlSetProcessPreferredUILanguages' RtlSetProcessPreferredUILanguages ntdll 1404 +imp 'RtlSetProtectedPolicy' RtlSetProtectedPolicy ntdll 1405 +imp 'RtlSetProxiedProcessId' RtlSetProxiedProcessId ntdll 1406 +imp 'RtlSetSaclSecurityDescriptor' RtlSetSaclSecurityDescriptor ntdll 1407 +imp 'RtlSetSearchPathMode' RtlSetSearchPathMode ntdll 1408 +imp 'RtlSetSecurityDescriptorRMControl' RtlSetSecurityDescriptorRMControl ntdll 1409 +imp 'RtlSetSecurityObject' RtlSetSecurityObject ntdll 1410 +imp 'RtlSetSecurityObjectEx' RtlSetSecurityObjectEx ntdll 1411 +imp 'RtlSetSystemBootStatus' RtlSetSystemBootStatus ntdll 1412 +imp 'RtlSetSystemBootStatusEx' RtlSetSystemBootStatusEx ntdll 1413 +imp 'RtlSetThreadErrorMode' RtlSetThreadErrorMode ntdll 1414 +imp 'RtlSetThreadIsCritical' RtlSetThreadIsCritical ntdll 1415 +imp 'RtlSetThreadPlaceholderCompatibilityMode' RtlSetThreadPlaceholderCompatibilityMode ntdll 1416 +imp 'RtlSetThreadPoolStartFunc' RtlSetThreadPoolStartFunc ntdll 1417 +imp 'RtlSetThreadPreferredUILanguages' RtlSetThreadPreferredUILanguages ntdll 1418 +imp 'RtlSetThreadSubProcessTag' RtlSetThreadSubProcessTag ntdll 1419 +imp 'RtlSetThreadWorkOnBehalfTicket' RtlSetThreadWorkOnBehalfTicket ntdll 1420 +imp 'RtlSetTimeZoneInformation' RtlSetTimeZoneInformation ntdll 1421 +imp 'RtlSetTimer' RtlSetTimer ntdll 1422 +imp 'RtlSetUmsThreadInformation' RtlSetUmsThreadInformation ntdll 1423 +imp 'RtlSetUnhandledExceptionFilter' RtlSetUnhandledExceptionFilter ntdll 1424 +imp 'RtlSetUserFlagsHeap' RtlSetUserFlagsHeap ntdll 1425 +imp 'RtlSetUserValueHeap' RtlSetUserValueHeap ntdll 1426 +imp 'RtlSidDominates' RtlSidDominates ntdll 1427 +imp 'RtlSidDominatesForTrust' RtlSidDominatesForTrust ntdll 1428 +imp 'RtlSidEqualLevel' RtlSidEqualLevel ntdll 1429 +imp 'RtlSidHashInitialize' RtlSidHashInitialize ntdll 1430 +imp 'RtlSidHashLookup' RtlSidHashLookup ntdll 1431 +imp 'RtlSidIsHigherLevel' RtlSidIsHigherLevel ntdll 1432 +imp 'RtlSizeHeap' RtlSizeHeap ntdll 1433 3 +imp 'RtlSleepConditionVariableCS' RtlSleepConditionVariableCS ntdll 1434 +imp 'RtlSleepConditionVariableSRW' RtlSleepConditionVariableSRW ntdll 1435 +imp 'RtlSplay' RtlSplay ntdll 1436 +imp 'RtlStartRXact' RtlStartRXact ntdll 1437 +imp 'RtlStatMemoryStream' RtlStatMemoryStream ntdll 1438 +imp 'RtlStringFromGUID' RtlStringFromGUID ntdll 1439 +imp 'RtlStringFromGUIDEx' RtlStringFromGUIDEx ntdll 1440 +imp 'RtlStronglyEnumerateEntryHashTable' RtlStronglyEnumerateEntryHashTable ntdll 1441 +imp 'RtlSubAuthorityCountSid' RtlSubAuthorityCountSid ntdll 1442 +imp 'RtlSubAuthoritySid' RtlSubAuthoritySid ntdll 1443 +imp 'RtlSubscribeWnfStateChangeNotification' RtlSubscribeWnfStateChangeNotification ntdll 1444 +imp 'RtlSubtreePredecessor' RtlSubtreePredecessor ntdll 1445 +imp 'RtlSubtreeSuccessor' RtlSubtreeSuccessor ntdll 1446 +imp 'RtlSwitchedVVI' RtlSwitchedVVI ntdll 1447 +imp 'RtlSystemTimeToLocalTime' RtlSystemTimeToLocalTime ntdll 1448 +imp 'RtlTestAndPublishWnfStateData' RtlTestAndPublishWnfStateData ntdll 1449 +imp 'RtlTestBit' RtlTestBit ntdll 1450 +imp 'RtlTestBitEx' RtlTestBitEx ntdll 1451 +imp 'RtlTestProtectedAccess' RtlTestProtectedAccess ntdll 1452 +imp 'RtlTimeFieldsToTime' RtlTimeFieldsToTime ntdll 1453 +imp 'RtlTimeToElapsedTimeFields' RtlTimeToElapsedTimeFields ntdll 1454 +imp 'RtlTimeToSecondsSince1970' RtlTimeToSecondsSince1970 ntdll 1455 +imp 'RtlTimeToSecondsSince1980' RtlTimeToSecondsSince1980 ntdll 1456 +imp 'RtlTimeToTimeFields' RtlTimeToTimeFields ntdll 1457 +imp 'RtlTraceDatabaseAdd' RtlTraceDatabaseAdd ntdll 1458 +imp 'RtlTraceDatabaseCreate' RtlTraceDatabaseCreate ntdll 1459 +imp 'RtlTraceDatabaseDestroy' RtlTraceDatabaseDestroy ntdll 1460 +imp 'RtlTraceDatabaseEnumerate' RtlTraceDatabaseEnumerate ntdll 1461 +imp 'RtlTraceDatabaseFind' RtlTraceDatabaseFind ntdll 1462 +imp 'RtlTraceDatabaseLock' RtlTraceDatabaseLock ntdll 1463 +imp 'RtlTraceDatabaseUnlock' RtlTraceDatabaseUnlock ntdll 1464 +imp 'RtlTraceDatabaseValidate' RtlTraceDatabaseValidate ntdll 1465 +imp 'RtlTryAcquirePebLock' RtlTryAcquirePebLock ntdll 1466 +imp 'RtlTryAcquireSRWLockExclusive' RtlTryAcquireSRWLockExclusive ntdll 1467 +imp 'RtlTryAcquireSRWLockShared' RtlTryAcquireSRWLockShared ntdll 1468 +imp 'RtlTryConvertSRWLockSharedToExclusiveOrRelease' RtlTryConvertSRWLockSharedToExclusiveOrRelease ntdll 1469 +imp 'RtlTryEnterCriticalSection' RtlTryEnterCriticalSection ntdll 1470 1 +imp 'RtlUTF8ToUnicodeN' RtlUTF8ToUnicodeN ntdll 1471 +imp 'RtlUmsThreadYield' RtlUmsThreadYield ntdll 1472 +imp 'RtlUnhandledExceptionFilter' RtlUnhandledExceptionFilter ntdll 1473 +imp 'RtlUnhandledExceptionFilter2' RtlUnhandledExceptionFilter2 ntdll 1474 +imp 'RtlUnicodeStringToAnsiSize' RtlUnicodeStringToAnsiSize ntdll 1475 +imp 'RtlUnicodeStringToAnsiString' RtlUnicodeStringToAnsiString ntdll 1476 +imp 'RtlUnicodeStringToCountedOemString' RtlUnicodeStringToCountedOemString ntdll 1477 +imp 'RtlUnicodeStringToInteger' RtlUnicodeStringToInteger ntdll 1478 +imp 'RtlUnicodeStringToOemSize' RtlUnicodeStringToOemSize ntdll 1479 +imp 'RtlUnicodeStringToOemString' RtlUnicodeStringToOemString ntdll 1480 +imp 'RtlUnicodeToCustomCPN' RtlUnicodeToCustomCPN ntdll 1481 +imp 'RtlUnicodeToMultiByteN' RtlUnicodeToMultiByteN ntdll 1482 +imp 'RtlUnicodeToMultiByteSize' RtlUnicodeToMultiByteSize ntdll 1483 +imp 'RtlUnicodeToOemN' RtlUnicodeToOemN ntdll 1484 +imp 'RtlUnicodeToUTF8N' RtlUnicodeToUTF8N ntdll 1485 +imp 'RtlUniform' RtlUniform ntdll 1486 +imp 'RtlUnlockBootStatusData' RtlUnlockBootStatusData ntdll 1487 +imp 'RtlUnlockCurrentThread' RtlUnlockCurrentThread ntdll 1488 +imp 'RtlUnlockHeap' RtlUnlockHeap ntdll 1489 1 +imp 'RtlUnlockMemoryBlockLookaside' RtlUnlockMemoryBlockLookaside ntdll 1490 +imp 'RtlUnlockMemoryStreamRegion' RtlUnlockMemoryStreamRegion ntdll 1491 +imp 'RtlUnlockMemoryZone' RtlUnlockMemoryZone ntdll 1492 +imp 'RtlUnlockModuleSection' RtlUnlockModuleSection ntdll 1493 +imp 'RtlUnsubscribeWnfNotificationWaitForCompletion' RtlUnsubscribeWnfNotificationWaitForCompletion ntdll 1494 +imp 'RtlUnsubscribeWnfNotificationWithCompletionCallback' RtlUnsubscribeWnfNotificationWithCompletionCallback ntdll 1495 +imp 'RtlUnsubscribeWnfStateChangeNotification' RtlUnsubscribeWnfStateChangeNotification ntdll 1496 +imp 'RtlUnwind' RtlUnwind ntdll 1497 +imp 'RtlUnwindEx' RtlUnwindEx ntdll 1498 +imp 'RtlUpcaseUnicodeChar' RtlUpcaseUnicodeChar ntdll 1499 +imp 'RtlUpcaseUnicodeString' RtlUpcaseUnicodeString ntdll 1500 +imp 'RtlUpcaseUnicodeStringToAnsiString' RtlUpcaseUnicodeStringToAnsiString ntdll 1501 +imp 'RtlUpcaseUnicodeStringToCountedOemString' RtlUpcaseUnicodeStringToCountedOemString ntdll 1502 +imp 'RtlUpcaseUnicodeStringToOemString' RtlUpcaseUnicodeStringToOemString ntdll 1503 +imp 'RtlUpcaseUnicodeToCustomCPN' RtlUpcaseUnicodeToCustomCPN ntdll 1504 +imp 'RtlUpcaseUnicodeToMultiByteN' RtlUpcaseUnicodeToMultiByteN ntdll 1505 +imp 'RtlUpcaseUnicodeToOemN' RtlUpcaseUnicodeToOemN ntdll 1506 +imp 'RtlUpdateClonedCriticalSection' RtlUpdateClonedCriticalSection ntdll 1507 +imp 'RtlUpdateClonedSRWLock' RtlUpdateClonedSRWLock ntdll 1508 +imp 'RtlUpdateTimer' RtlUpdateTimer ntdll 1509 +imp 'RtlUpperChar' RtlUpperChar ntdll 1510 +imp 'RtlUpperString' RtlUpperString ntdll 1511 +imp 'RtlUserThreadStart' RtlUserThreadStart ntdll 1512 +imp 'RtlValidAcl' RtlValidAcl ntdll 1513 +imp 'RtlValidProcessProtection' RtlValidProcessProtection ntdll 1514 +imp 'RtlValidRelativeSecurityDescriptor' RtlValidRelativeSecurityDescriptor ntdll 1515 +imp 'RtlValidSecurityDescriptor' RtlValidSecurityDescriptor ntdll 1516 +imp 'RtlValidSid' RtlValidSid ntdll 1517 +imp 'RtlValidateCorrelationVector' RtlValidateCorrelationVector ntdll 1518 +imp 'RtlValidateHeap' RtlValidateHeap ntdll 1519 3 +imp 'RtlValidateProcessHeaps' RtlValidateProcessHeaps ntdll 1520 +imp 'RtlValidateUnicodeString' RtlValidateUnicodeString ntdll 1521 +imp 'RtlVerifyVersionInfo' RtlVerifyVersionInfo ntdll 1522 +imp 'RtlVirtualUnwind' RtlVirtualUnwind ntdll 1523 +imp 'RtlWaitForWnfMetaNotification' RtlWaitForWnfMetaNotification ntdll 1524 +imp 'RtlWaitOnAddress' RtlWaitOnAddress ntdll 1525 +imp 'RtlWakeAddressAll' RtlWakeAddressAll ntdll 1526 +imp 'RtlWakeAddressAllNoFence' RtlWakeAddressAllNoFence ntdll 1527 +imp 'RtlWakeAddressSingle' RtlWakeAddressSingle ntdll 1528 +imp 'RtlWakeAddressSingleNoFence' RtlWakeAddressSingleNoFence ntdll 1529 +imp 'RtlWakeAllConditionVariable' RtlWakeAllConditionVariable ntdll 1530 +imp 'RtlWakeConditionVariable' RtlWakeConditionVariable ntdll 1531 +imp 'RtlWalkFrameChain' RtlWalkFrameChain ntdll 1532 +imp 'RtlWalkHeap' RtlWalkHeap ntdll 1533 2 +imp 'RtlWeaklyEnumerateEntryHashTable' RtlWeaklyEnumerateEntryHashTable ntdll 1534 +imp 'RtlWerpReportException' RtlWerpReportException ntdll 1535 +imp 'RtlWnfCompareChangeStamp' RtlWnfCompareChangeStamp ntdll 1536 +imp 'RtlWnfDllUnloadCallback' RtlWnfDllUnloadCallback ntdll 1537 +imp 'RtlWow64CallFunction64' RtlWow64CallFunction64 ntdll 1538 +imp 'RtlWow64EnableFsRedirection' RtlWow64EnableFsRedirection ntdll 1539 +imp 'RtlWow64EnableFsRedirectionEx' RtlWow64EnableFsRedirectionEx ntdll 1540 +imp 'RtlWow64GetCpuAreaInfo' RtlWow64GetCpuAreaInfo ntdll 1541 +imp 'RtlWow64GetCurrentCpuArea' RtlWow64GetCurrentCpuArea ntdll 1542 +imp 'RtlWow64GetCurrentMachine' RtlWow64GetCurrentMachine ntdll 1543 +imp 'RtlWow64GetEquivalentMachineCHPE' RtlWow64GetEquivalentMachineCHPE ntdll 1544 +imp 'RtlWow64GetProcessMachines' RtlWow64GetProcessMachines ntdll 1545 +imp 'RtlWow64GetSharedInfoProcess' RtlWow64GetSharedInfoProcess ntdll 1546 +imp 'RtlWow64GetThreadContext' RtlWow64GetThreadContext ntdll 1547 +imp 'RtlWow64GetThreadSelectorEntry' RtlWow64GetThreadSelectorEntry ntdll 1548 +imp 'RtlWow64IsWowGuestMachineSupported' RtlWow64IsWowGuestMachineSupported ntdll 1549 +imp 'RtlWow64LogMessageInEventLogger' RtlWow64LogMessageInEventLogger ntdll 1550 +imp 'RtlWow64PopAllCrossProcessWork' RtlWow64PopAllCrossProcessWork ntdll 1551 +imp 'RtlWow64PopCrossProcessWork' RtlWow64PopCrossProcessWork ntdll 1552 +imp 'RtlWow64PushCrossProcessWork' RtlWow64PushCrossProcessWork ntdll 1553 +imp 'RtlWow64SetThreadContext' RtlWow64SetThreadContext ntdll 1554 +imp 'RtlWow64SuspendThread' RtlWow64SuspendThread ntdll 1555 +imp 'RtlWriteMemoryStream' RtlWriteMemoryStream ntdll 1556 +imp 'RtlWriteNonVolatileMemory' RtlWriteNonVolatileMemory ntdll 1557 +imp 'RtlWriteRegistryValue' RtlWriteRegistryValue ntdll 1558 +imp 'RtlZeroHeap' RtlZeroHeap ntdll 1559 +imp 'RtlZeroMemory' RtlZeroMemory ntdll 1560 +imp 'RtlZombifyActivationContext' RtlZombifyActivationContext ntdll 1561 +imp 'RtlpApplyLengthFunction' RtlpApplyLengthFunction ntdll 1562 +imp 'RtlpCheckDynamicTimeZoneInformation' RtlpCheckDynamicTimeZoneInformation ntdll 1563 +imp 'RtlpCleanupRegistryKeys' RtlpCleanupRegistryKeys ntdll 1564 +imp 'RtlpConvertAbsoluteToRelativeSecurityAttribute' RtlpConvertAbsoluteToRelativeSecurityAttribute ntdll 1565 +imp 'RtlpConvertCultureNamesToLCIDs' RtlpConvertCultureNamesToLCIDs ntdll 1566 +imp 'RtlpConvertLCIDsToCultureNames' RtlpConvertLCIDsToCultureNames ntdll 1567 +imp 'RtlpConvertRelativeToAbsoluteSecurityAttribute' RtlpConvertRelativeToAbsoluteSecurityAttribute ntdll 1568 +imp 'RtlpCreateProcessRegistryInfo' RtlpCreateProcessRegistryInfo ntdll 1569 +imp 'RtlpEnsureBufferSize' RtlpEnsureBufferSize ntdll 1570 +imp 'RtlpExecuteUmsThread' RtlpExecuteUmsThread ntdll 1571 +imp 'RtlpFreezeTimeBias' RtlpFreezeTimeBias ntdll 1572 +imp 'RtlpGetDeviceFamilyInfoEnum' RtlpGetDeviceFamilyInfoEnum ntdll 1573 +imp 'RtlpGetLCIDFromLangInfoNode' RtlpGetLCIDFromLangInfoNode ntdll 1574 +imp 'RtlpGetNameFromLangInfoNode' RtlpGetNameFromLangInfoNode ntdll 1575 +imp 'RtlpGetSystemDefaultUILanguage' RtlpGetSystemDefaultUILanguage ntdll 1576 +imp 'RtlpGetUserOrMachineUILanguage4NLS' RtlpGetUserOrMachineUILanguage4NLS ntdll 1577 +imp 'RtlpInitializeLangRegistryInfo' RtlpInitializeLangRegistryInfo ntdll 1578 +imp 'RtlpIsQualifiedLanguage' RtlpIsQualifiedLanguage ntdll 1579 +imp 'RtlpLoadMachineUIByPolicy' RtlpLoadMachineUIByPolicy ntdll 1580 +imp 'RtlpLoadUserUIByPolicy' RtlpLoadUserUIByPolicy ntdll 1581 +imp 'RtlpMergeSecurityAttributeInformation' RtlpMergeSecurityAttributeInformation ntdll 1582 +imp 'RtlpMuiFreeLangRegistryInfo' RtlpMuiFreeLangRegistryInfo ntdll 1583 +imp 'RtlpMuiRegCreateRegistryInfo' RtlpMuiRegCreateRegistryInfo ntdll 1584 +imp 'RtlpMuiRegFreeRegistryInfo' RtlpMuiRegFreeRegistryInfo ntdll 1585 +imp 'RtlpMuiRegLoadRegistryInfo' RtlpMuiRegLoadRegistryInfo ntdll 1586 +imp 'RtlpNotOwnerCriticalSection' RtlpNotOwnerCriticalSection ntdll 1587 +imp 'RtlpNtCreateKey' RtlpNtCreateKey ntdll 1588 +imp 'RtlpNtEnumerateSubKey' RtlpNtEnumerateSubKey ntdll 1589 +imp 'RtlpNtMakeTemporaryKey' RtlpNtMakeTemporaryKey ntdll 1590 +imp 'RtlpNtOpenKey' RtlpNtOpenKey ntdll 1591 +imp 'RtlpNtQueryValueKey' RtlpNtQueryValueKey ntdll 1592 +imp 'RtlpNtSetValueKey' RtlpNtSetValueKey ntdll 1593 +imp 'RtlpQueryDefaultUILanguage' RtlpQueryDefaultUILanguage ntdll 1594 +imp 'RtlpQueryProcessDebugInformationFromWow64' RtlpQueryProcessDebugInformationFromWow64 ntdll 1595 +imp 'RtlpQueryProcessDebugInformationRemote' RtlpQueryProcessDebugInformationRemote ntdll 1596 +imp 'RtlpRefreshCachedUILanguage' RtlpRefreshCachedUILanguage ntdll 1597 +imp 'RtlpSetInstallLanguage' RtlpSetInstallLanguage ntdll 1598 +imp 'RtlpSetPreferredUILanguages' RtlpSetPreferredUILanguages ntdll 1599 +imp 'RtlpSetUserPreferredUILanguages' RtlpSetUserPreferredUILanguages ntdll 1600 +imp 'RtlpUmsExecuteYieldThreadEnd' RtlpUmsExecuteYieldThreadEnd ntdll 1601 +imp 'RtlpUmsThreadYield' RtlpUmsThreadYield ntdll 1602 +imp 'RtlpUnWaitCriticalSection' RtlpUnWaitCriticalSection ntdll 1603 +imp 'RtlpVerifyAndCommitUILanguageSettings' RtlpVerifyAndCommitUILanguageSettings ntdll 1604 +imp 'RtlpWaitForCriticalSection' RtlpWaitForCriticalSection ntdll 1605 +imp 'RtlxAnsiStringToUnicodeSize' RtlxAnsiStringToUnicodeSize ntdll 1606 +imp 'RtlxOemStringToUnicodeSize' RtlxOemStringToUnicodeSize ntdll 1607 +imp 'RtlxUnicodeStringToAnsiSize' RtlxUnicodeStringToAnsiSize ntdll 1608 +imp 'RtlxUnicodeStringToOemSize' RtlxUnicodeStringToOemSize ntdll 1609 +imp 'RunAsNewUser_RunDLLW' RunAsNewUser_RunDLLW shell32 314 +imp 'RxNetAccessAdd' RxNetAccessAdd netapi32 288 +imp 'RxNetAccessDel' RxNetAccessDel netapi32 289 +imp 'RxNetAccessEnum' RxNetAccessEnum netapi32 290 +imp 'RxNetAccessGetInfo' RxNetAccessGetInfo netapi32 291 +imp 'RxNetAccessGetUserPerms' RxNetAccessGetUserPerms netapi32 292 +imp 'RxNetAccessSetInfo' RxNetAccessSetInfo netapi32 293 +imp 'RxNetServerEnum' RxNetServerEnum netapi32 294 +imp 'RxNetUserPasswordSet' RxNetUserPasswordSet netapi32 295 +imp 'RxRemoteApi' RxRemoteApi netapi32 296 +imp 'SHAddDefaultPropertiesByExt' SHAddDefaultPropertiesByExt shell32 315 +imp 'SHAddFromPropSheetExtArray' SHAddFromPropSheetExtArray shell32 167 +imp 'SHAddToRecentDocs' SHAddToRecentDocs shell32 316 +imp 'SHAlloc' SHAlloc shell32 196 +imp 'SHAppBarMessage' SHAppBarMessage shell32 317 +imp 'SHAssocEnumHandlers' SHAssocEnumHandlers shell32 318 +imp 'SHAssocEnumHandlersForProtocolByApplication' SHAssocEnumHandlersForProtocolByApplication shell32 319 +imp 'SHBindToFolderIDListParent' SHBindToFolderIDListParent shell32 320 +imp 'SHBindToFolderIDListParentEx' SHBindToFolderIDListParentEx shell32 321 +imp 'SHBindToObject' SHBindToObject shell32 322 +imp 'SHBindToParent' SHBindToParent shell32 323 +imp 'SHBrowseForFolderA' SHBrowseForFolderA shell32 325 +imp 'SHBrowseForFolder' SHBrowseForFolderW shell32 326 +imp 'SHCLSIDFromString' SHCLSIDFromString shell32 147 +imp 'SHChangeNotification_Lock' SHChangeNotification_Lock shell32 644 +imp 'SHChangeNotification_Unlock' SHChangeNotification_Unlock shell32 645 +imp 'SHChangeNotify' SHChangeNotify shell32 327 +imp 'SHChangeNotifyDeregister' SHChangeNotifyDeregister shell32 4 +imp 'SHChangeNotifyRegister' SHChangeNotifyRegister shell32 2 +imp 'SHChangeNotifyRegisterThread' SHChangeNotifyRegisterThread shell32 328 +imp 'SHChangeNotifySuspendResume' SHChangeNotifySuspendResume shell32 329 +imp 'SHCloneSpecialIDList' SHCloneSpecialIDList shell32 89 +imp 'SHCoCreateInstance' SHCoCreateInstance KernelBase 1420 +imp 'SHCoCreateInstanceWorker' SHCoCreateInstanceWorker shell32 330 +imp 'SHCreateAssociationRegistration' SHCreateAssociationRegistration shell32 331 +imp 'SHCreateCategoryEnum' SHCreateCategoryEnum shell32 332 +imp 'SHCreateDataObject' SHCreateDataObject shell32 333 +imp 'SHCreateDefaultContextMenu' SHCreateDefaultContextMenu shell32 334 +imp 'SHCreateDefaultExtractIcon' SHCreateDefaultExtractIcon shell32 335 +imp 'SHCreateDefaultPropertiesOp' SHCreateDefaultPropertiesOp shell32 336 +imp 'SHCreateDirectory' SHCreateDirectory shell32 165 +imp 'SHCreateDirectoryExA' SHCreateDirectoryExA shell32 337 +imp 'SHCreateDirectoryEx' SHCreateDirectoryExW shell32 338 +imp 'SHCreateDrvExtIcon' SHCreateDrvExtIcon shell32 339 +imp 'SHCreateFileExtractIcon' SHCreateFileExtractIconW shell32 743 +imp 'SHCreateItemFromIDList' SHCreateItemFromIDList shell32 340 +imp 'SHCreateItemFromParsingName' SHCreateItemFromParsingName shell32 341 +imp 'SHCreateItemFromRelativeName' SHCreateItemFromRelativeName shell32 342 +imp 'SHCreateItemInKnownFolder' SHCreateItemInKnownFolder shell32 343 +imp 'SHCreateItemWithParent' SHCreateItemWithParent shell32 344 +imp 'SHCreateLocalServerRunDll' SHCreateLocalServerRunDll shell32 345 +imp 'SHCreateProcessAsUser' SHCreateProcessAsUserW shell32 346 +imp 'SHCreatePropSheetExtArray' SHCreatePropSheetExtArray shell32 168 +imp 'SHCreateQueryCancelAutoPlayMoniker' SHCreateQueryCancelAutoPlayMoniker shell32 347 +imp 'SHCreateShellFolderView' SHCreateShellFolderView shell32 256 +imp 'SHCreateShellFolderViewEx' SHCreateShellFolderViewEx shell32 174 +imp 'SHCreateShellItem' SHCreateShellItem shell32 348 +imp 'SHCreateShellItemArray' SHCreateShellItemArray shell32 349 +imp 'SHCreateShellItemArrayFromDataObject' SHCreateShellItemArrayFromDataObject shell32 350 +imp 'SHCreateShellItemArrayFromIDLists' SHCreateShellItemArrayFromIDLists shell32 351 +imp 'SHCreateShellItemArrayFromShellItem' SHCreateShellItemArrayFromShellItem shell32 352 +imp 'SHCreateStdEnumFmtEtc' SHCreateStdEnumFmtEtc shell32 74 +imp 'SHDefExtractIconA' SHDefExtractIconA shell32 3 +imp 'SHDefExtractIcon' SHDefExtractIconW shell32 6 +imp 'SHDestroyPropSheetExtArray' SHDestroyPropSheetExtArray shell32 169 +imp 'SHDoDragDrop' SHDoDragDrop shell32 88 +imp 'SHELL32_AddToBackIconTable' SHELL32_AddToBackIconTable shell32 353 +imp 'SHELL32_AddToFrontIconTable' SHELL32_AddToFrontIconTable shell32 354 +imp 'SHELL32_AreAllItemsAvailable' SHELL32_AreAllItemsAvailable shell32 355 +imp 'SHELL32_BindToFilePlaceholderHandler' SHELL32_BindToFilePlaceholderHandler shell32 356 +imp 'SHELL32_CCommonPlacesFolder_CreateInstance' SHELL32_CCommonPlacesFolder_CreateInstance shell32 357 +imp 'SHELL32_CDBurn_CloseSession' SHELL32_CDBurn_CloseSession shell32 358 +imp 'SHELL32_CDBurn_DriveSupportedForDataBurn' SHELL32_CDBurn_DriveSupportedForDataBurn shell32 359 +imp 'SHELL32_CDBurn_Erase' SHELL32_CDBurn_Erase shell32 360 +imp 'SHELL32_CDBurn_GetCDInfo' SHELL32_CDBurn_GetCDInfo shell32 361 +imp 'SHELL32_CDBurn_GetLiveFSDiscInfo' SHELL32_CDBurn_GetLiveFSDiscInfo shell32 362 +imp 'SHELL32_CDBurn_GetStagingPathOrNormalPath' SHELL32_CDBurn_GetStagingPathOrNormalPath shell32 363 +imp 'SHELL32_CDBurn_GetTaskInfo' SHELL32_CDBurn_GetTaskInfo shell32 364 +imp 'SHELL32_CDBurn_IsBlankDisc' SHELL32_CDBurn_IsBlankDisc shell32 365 +imp 'SHELL32_CDBurn_IsBlankDisc2' SHELL32_CDBurn_IsBlankDisc2 shell32 366 +imp 'SHELL32_CDBurn_IsLiveFS' SHELL32_CDBurn_IsLiveFS shell32 367 +imp 'SHELL32_CDBurn_OnDeviceChange' SHELL32_CDBurn_OnDeviceChange shell32 368 +imp 'SHELL32_CDBurn_OnEject' SHELL32_CDBurn_OnEject shell32 369 +imp 'SHELL32_CDBurn_OnMediaChange' SHELL32_CDBurn_OnMediaChange shell32 370 +imp 'SHELL32_CDefFolderMenu_Create2' SHELL32_CDefFolderMenu_Create2 shell32 371 +imp 'SHELL32_CDefFolderMenu_Create2Ex' SHELL32_CDefFolderMenu_Create2Ex shell32 372 +imp 'SHELL32_CDefFolderMenu_MergeMenu' SHELL32_CDefFolderMenu_MergeMenu shell32 373 +imp 'SHELL32_CDrivesContextMenu_Create' SHELL32_CDrivesContextMenu_Create shell32 374 +imp 'SHELL32_CDrivesDropTarget_Create' SHELL32_CDrivesDropTarget_Create shell32 375 +imp 'SHELL32_CDrives_CreateSFVCB' SHELL32_CDrives_CreateSFVCB shell32 376 +imp 'SHELL32_CFSDropTarget_CreateInstance' SHELL32_CFSDropTarget_CreateInstance shell32 377 +imp 'SHELL32_CFSFolderCallback_Create' SHELL32_CFSFolderCallback_Create shell32 378 +imp 'SHELL32_CFillPropertiesTask_CreateInstance' SHELL32_CFillPropertiesTask_CreateInstance shell32 379 +imp 'SHELL32_CLibraryDropTarget_CreateInstance' SHELL32_CLibraryDropTarget_CreateInstance shell32 380 +imp 'SHELL32_CLocationContextMenu_Create' SHELL32_CLocationContextMenu_Create shell32 381 +imp 'SHELL32_CLocationFolderUI_CreateInstance' SHELL32_CLocationFolderUI_CreateInstance shell32 382 +imp 'SHELL32_CMountPoint_DoAutorun' SHELL32_CMountPoint_DoAutorun shell32 383 +imp 'SHELL32_CMountPoint_DoAutorunPrompt' SHELL32_CMountPoint_DoAutorunPrompt shell32 384 +imp 'SHELL32_CMountPoint_IsAutoRunDriveAndEnabledByPolicy' SHELL32_CMountPoint_IsAutoRunDriveAndEnabledByPolicy shell32 385 +imp 'SHELL32_CMountPoint_ProcessAutoRunFile' SHELL32_CMountPoint_ProcessAutoRunFile shell32 386 +imp 'SHELL32_CMountPoint_WantAutorunUI' SHELL32_CMountPoint_WantAutorunUI shell32 387 +imp 'SHELL32_CMountPoint_WantAutorunUIGetReady' SHELL32_CMountPoint_WantAutorunUIGetReady shell32 388 +imp 'SHELL32_CPL_CategoryIdArrayFromVariant' SHELL32_CPL_CategoryIdArrayFromVariant shell32 389 +imp 'SHELL32_CPL_IsLegacyCanonicalNameListedUnderKey' SHELL32_CPL_IsLegacyCanonicalNameListedUnderKey shell32 390 +imp 'SHELL32_CPL_ModifyWowDisplayName' SHELL32_CPL_ModifyWowDisplayName shell32 391 +imp 'SHELL32_CRecentDocsContextMenu_CreateInstance' SHELL32_CRecentDocsContextMenu_CreateInstance shell32 392 +imp 'SHELL32_CSyncRootManager_CreateInstance' SHELL32_CSyncRootManager_CreateInstance shell32 393 +imp 'SHELL32_CTransferConfirmation_CreateInstance' SHELL32_CTransferConfirmation_CreateInstance shell32 394 +imp 'SHELL32_CallFileCopyHooks' SHELL32_CallFileCopyHooks shell32 395 +imp 'SHELL32_CanDisplayWin8CopyDialog' SHELL32_CanDisplayWin8CopyDialog shell32 396 +imp 'SHELL32_CloseAutoplayPrompt' SHELL32_CloseAutoplayPrompt shell32 397 +imp 'SHELL32_CommandLineFromMsiDescriptor' SHELL32_CommandLineFromMsiDescriptor shell32 398 +imp 'SHELL32_CopyFilePlaceholderToNewFile' SHELL32_CopyFilePlaceholderToNewFile shell32 399 +imp 'SHELL32_CopySecondaryTiles' SHELL32_CopySecondaryTiles shell32 400 +imp 'SHELL32_CreateConfirmationInterrupt' SHELL32_CreateConfirmationInterrupt shell32 401 +imp 'SHELL32_CreateConflictInterrupt' SHELL32_CreateConflictInterrupt shell32 402 +imp 'SHELL32_CreateDefaultOperationDataProvider' SHELL32_CreateDefaultOperationDataProvider shell32 403 +imp 'SHELL32_CreateFileFolderContextMenu' SHELL32_CreateFileFolderContextMenu shell32 404 +imp 'SHELL32_CreateLinkInfo' SHELL32_CreateLinkInfoW shell32 405 +imp 'SHELL32_CreatePlaceholderFile' SHELL32_CreatePlaceholderFile shell32 406 +imp 'SHELL32_CreateQosRecorder' SHELL32_CreateQosRecorder shell32 407 +imp 'SHELL32_CreateSharePointView' SHELL32_CreateSharePointView shell32 408 +imp 'SHELL32_Create_IEnumUICommand' SHELL32_Create_IEnumUICommand shell32 409 +imp 'SHELL32_DestroyLinkInfo' SHELL32_DestroyLinkInfo shell32 410 +imp 'SHELL32_EncryptDirectory' SHELL32_EncryptDirectory shell32 411 +imp 'SHELL32_EncryptedFileKeyInfo' SHELL32_EncryptedFileKeyInfo shell32 412 +imp 'SHELL32_EnumCommonTasks' SHELL32_EnumCommonTasks shell32 413 +imp 'SHELL32_FilePlaceholder_BindToPrimaryStream' SHELL32_FilePlaceholder_BindToPrimaryStream shell32 414 +imp 'SHELL32_FilePlaceholder_CreateInstance' SHELL32_FilePlaceholder_CreateInstance shell32 415 +imp 'SHELL32_FreeEncryptedFileKeyInfo' SHELL32_FreeEncryptedFileKeyInfo shell32 416 +imp 'SHELL32_GenerateAppID' SHELL32_GenerateAppID shell32 417 +imp 'SHELL32_GetAppIDRoot' SHELL32_GetAppIDRoot shell32 418 +imp 'SHELL32_GetCommandProviderForFolderType' SHELL32_GetCommandProviderForFolderType shell32 419 +imp 'SHELL32_GetDPIAdjustedLogicalSize' SHELL32_GetDPIAdjustedLogicalSize shell32 420 +imp 'SHELL32_GetDiskCleanupPath' SHELL32_GetDiskCleanupPath shell32 421 +imp 'SHELL32_GetFileNameFromBrowse' SHELL32_GetFileNameFromBrowse shell32 422 +imp 'SHELL32_GetIconOverlayManager' SHELL32_GetIconOverlayManager shell32 423 +imp 'SHELL32_GetLinkInfoData' SHELL32_GetLinkInfoData shell32 424 +imp 'SHELL32_GetPlaceholderStatesFromFileAttributesAndReparsePointTag' SHELL32_GetPlaceholderStatesFromFileAttributesAndReparsePointTag shell32 425 +imp 'SHELL32_GetRatingBucket' SHELL32_GetRatingBucket shell32 426 +imp 'SHELL32_GetSkyDriveNetworkStates' SHELL32_GetSkyDriveNetworkStates shell32 427 +imp 'SHELL32_GetSqmableFileName' SHELL32_GetSqmableFileName shell32 428 +imp 'SHELL32_GetThumbnailAdornerFromFactory' SHELL32_GetThumbnailAdornerFromFactory shell32 429 +imp 'SHELL32_GetThumbnailAdornerFromFactory2' SHELL32_GetThumbnailAdornerFromFactory2 shell32 430 +imp 'SHELL32_HandleUnrecognizedFileSystem' SHELL32_HandleUnrecognizedFileSystem shell32 431 +imp 'SHELL32_IconCacheCreate' SHELL32_IconCacheCreate shell32 432 +imp 'SHELL32_IconCacheDestroy' SHELL32_IconCacheDestroy shell32 433 +imp 'SHELL32_IconCacheHandleAssociationChanged' SHELL32_IconCacheHandleAssociationChanged shell32 434 +imp 'SHELL32_IconCacheRestore' SHELL32_IconCacheRestore shell32 435 +imp 'SHELL32_IconCache_AboutToExtractIcons' SHELL32_IconCache_AboutToExtractIcons shell32 436 +imp 'SHELL32_IconCache_DoneExtractingIcons' SHELL32_IconCache_DoneExtractingIcons shell32 437 +imp 'SHELL32_IconCache_ExpandEnvAndSearchPath' SHELL32_IconCache_ExpandEnvAndSearchPath shell32 438 +imp 'SHELL32_IconCache_RememberRecentlyExtractedIcons' SHELL32_IconCache_RememberRecentlyExtractedIconsW shell32 439 +imp 'SHELL32_IconOverlayManagerInit' SHELL32_IconOverlayManagerInit shell32 440 +imp 'SHELL32_IsGetKeyboardLayoutPresent' SHELL32_IsGetKeyboardLayoutPresent shell32 441 +imp 'SHELL32_IsSystemUpgradeInProgress' SHELL32_IsSystemUpgradeInProgress shell32 442 +imp 'SHELL32_IsValidLinkInfo' SHELL32_IsValidLinkInfo shell32 443 +imp 'SHELL32_LegacyEnumSpecialTasksByType' SHELL32_LegacyEnumSpecialTasksByType shell32 444 +imp 'SHELL32_LegacyEnumTasks' SHELL32_LegacyEnumTasks shell32 445 +imp 'SHELL32_LookupBackIconIndex' SHELL32_LookupBackIconIndex shell32 446 +imp 'SHELL32_LookupFrontIconIndex' SHELL32_LookupFrontIconIndex shell32 447 +imp 'SHELL32_NormalizeRating' SHELL32_NormalizeRating shell32 448 +imp 'SHELL32_NotifyLinkTrackingServiceOfMove' SHELL32_NotifyLinkTrackingServiceOfMove shell32 449 +imp 'SHELL32_PifMgr_CloseProperties' SHELL32_PifMgr_CloseProperties shell32 450 +imp 'SHELL32_PifMgr_GetProperties' SHELL32_PifMgr_GetProperties shell32 451 +imp 'SHELL32_PifMgr_OpenProperties' SHELL32_PifMgr_OpenProperties shell32 452 +imp 'SHELL32_PifMgr_SetProperties' SHELL32_PifMgr_SetProperties shell32 453 +imp 'SHELL32_Printers_CreateBindInfo' SHELL32_Printers_CreateBindInfo shell32 454 +imp 'SHELL32_Printjob_GetPidl' SHELL32_Printjob_GetPidl shell32 455 +imp 'SHELL32_PurgeSystemIcon' SHELL32_PurgeSystemIcon shell32 456 +imp 'SHELL32_RefreshOverlayImages' SHELL32_RefreshOverlayImages shell32 457 +imp 'SHELL32_ResolveLinkInfo' SHELL32_ResolveLinkInfoW shell32 458 +imp 'SHELL32_SHAddSparseIcon' SHELL32_SHAddSparseIcon shell32 459 +imp 'SHELL32_SHCreateByValueOperationInterrupt' SHELL32_SHCreateByValueOperationInterrupt shell32 460 +imp 'SHELL32_SHCreateDefaultContextMenu' SHELL32_SHCreateDefaultContextMenu shell32 461 +imp 'SHELL32_SHCreateLocalServer' SHELL32_SHCreateLocalServer shell32 462 +imp 'SHELL32_SHCreateShellFolderView' SHELL32_SHCreateShellFolderView shell32 463 +imp 'SHELL32_SHDuplicateEncryptionInfoFile' SHELL32_SHDuplicateEncryptionInfoFile shell32 464 +imp 'SHELL32_SHEncryptFile' SHELL32_SHEncryptFile shell32 465 +imp 'SHELL32_SHFormatDriveAsync' SHELL32_SHFormatDriveAsync shell32 466 +imp 'SHELL32_SHGetThreadUndoManager' SHELL32_SHGetThreadUndoManager shell32 467 +imp 'SHELL32_SHGetUserName' SHELL32_SHGetUserNameW shell32 468 +imp 'SHELL32_SHIsVirtualDevice' SHELL32_SHIsVirtualDevice shell32 469 +imp 'SHELL32_SHLaunchPropSheet' SHELL32_SHLaunchPropSheet shell32 470 +imp 'SHELL32_SHLogILFromFSIL' SHELL32_SHLogILFromFSIL shell32 471 +imp 'SHELL32_SHOpenWithDialog' SHELL32_SHOpenWithDialog shell32 472 +imp 'SHELL32_SHStartNetConnectionDialog' SHELL32_SHStartNetConnectionDialogW shell32 473 +imp 'SHELL32_SHUICommandFromGUID' SHELL32_SHUICommandFromGUID shell32 474 +imp 'SHELL32_SendToMenu_InvokeTargetedCommand' SHELL32_SendToMenu_InvokeTargetedCommand shell32 475 +imp 'SHELL32_SendToMenu_VerifyTargetedCommand' SHELL32_SendToMenu_VerifyTargetedCommand shell32 476 +imp 'SHELL32_SetPlaceholderReparsePointAttribute' SHELL32_SetPlaceholderReparsePointAttribute shell32 477 +imp 'SHELL32_SetPlaceholderReparsePointAttribute2' SHELL32_SetPlaceholderReparsePointAttribute2 shell32 478 +imp 'SHELL32_ShowHideIconOnlyOnDesktop' SHELL32_ShowHideIconOnlyOnDesktop shell32 479 +imp 'SHELL32_SimpleRatingToFilterCondition' SHELL32_SimpleRatingToFilterCondition shell32 480 +imp 'SHELL32_StampIconForFile' SHELL32_StampIconForFile shell32 481 +imp 'SHELL32_SuspendUndo' SHELL32_SuspendUndo shell32 482 +imp 'SHELL32_TryVirtualDiscImageDriveEject' SHELL32_TryVirtualDiscImageDriveEject shell32 483 +imp 'SHELL32_UpdateFilePlaceholderStates' SHELL32_UpdateFilePlaceholderStates shell32 484 +imp 'SHELL32_VerifySaferTrust' SHELL32_VerifySaferTrust shell32 485 +imp 'SHEmptyRecycleBinA' SHEmptyRecycleBinA shell32 486 +imp 'SHEmptyRecycleBin' SHEmptyRecycleBinW shell32 487 +imp 'SHEnableServiceObject' SHEnableServiceObject shell32 488 +imp 'SHEnumerateUnreadMailAccounts' SHEnumerateUnreadMailAccountsW shell32 489 +imp 'SHEvaluateSystemCommandTemplate' SHEvaluateSystemCommandTemplate shell32 490 +imp 'SHExpandEnvironmentStringsA' SHExpandEnvironmentStringsA KernelBase 1421 +imp 'SHExpandEnvironmentStrings' SHExpandEnvironmentStringsW KernelBase 1422 +imp 'SHExtractIcons' SHExtractIconsW shell32 491 +imp 'SHFileOperationA' SHFileOperationA shell32 493 +imp 'SHFileOperation' SHFileOperationW shell32 494 +imp 'SHFindFiles' SHFindFiles shell32 90 +imp 'SHFind_InitMenuPopup' SHFind_InitMenuPopup shell32 149 +imp 'SHFlushSFCache' SHFlushSFCache shell32 526 +imp 'SHFormatDrive' SHFormatDrive shell32 495 +imp 'SHFree' SHFree shell32 195 +imp 'SHFreeNameMappings' SHFreeNameMappings shell32 496 +imp 'SHGetAttributesFromDataObject' SHGetAttributesFromDataObject shell32 750 +imp 'SHGetDataFromIDListA' SHGetDataFromIDListA shell32 497 +imp 'SHGetDataFromIDList' SHGetDataFromIDListW shell32 498 +imp 'SHGetDesktopFolder' SHGetDesktopFolder shell32 499 +imp 'SHGetDiskFreeSpaceA' SHGetDiskFreeSpaceA shell32 500 +imp 'SHGetDiskFreeSpaceExA' SHGetDiskFreeSpaceExA shell32 501 +imp 'SHGetDiskFreeSpaceEx' SHGetDiskFreeSpaceExW shell32 502 +imp 'SHGetDriveMedia' SHGetDriveMedia shell32 503 +imp 'SHGetFileInfoA' SHGetFileInfoA shell32 505 +imp 'SHGetFileInfo' SHGetFileInfoW shell32 506 +imp 'SHGetFolderLocation' SHGetFolderLocation shell32 507 +imp 'SHGetFolderPathA' SHGetFolderPathA shell32 508 +imp 'SHGetFolderPathAndSubDirA' SHGetFolderPathAndSubDirA shell32 509 +imp 'SHGetFolderPathAndSubDir' SHGetFolderPathAndSubDirW shell32 510 +imp 'SHGetFolderPathEx' SHGetFolderPathEx shell32 511 +imp 'SHGetFolderPath' SHGetFolderPathW shell32 512 +imp 'SHGetIDListFromObject' SHGetIDListFromObject shell32 513 +imp 'SHGetIconOverlayIndexA' SHGetIconOverlayIndexA shell32 514 +imp 'SHGetIconOverlayIndex' SHGetIconOverlayIndexW shell32 515 +imp 'SHGetImageList' SHGetImageList shell32 727 +imp 'SHGetInstanceExplorer' SHGetInstanceExplorer shell32 516 +imp 'SHGetItemFromDataObject' SHGetItemFromDataObject shell32 517 +imp 'SHGetItemFromObject' SHGetItemFromObject shell32 518 +imp 'SHGetKnownFolderIDList' SHGetKnownFolderIDList shell32 519 +imp 'SHGetKnownFolderItem' SHGetKnownFolderItem shell32 527 +imp 'SHGetKnownFolderPath' SHGetKnownFolderPath shell32 528 +imp 'SHGetLocalizedName' SHGetLocalizedName shell32 529 +imp 'SHGetMalloc' SHGetMalloc shell32 530 +imp 'SHGetNameFromIDList' SHGetNameFromIDList shell32 531 +imp 'SHGetNewLinkInfoA' SHGetNewLinkInfoA shell32 179 +imp 'SHGetNewLinkInfo' SHGetNewLinkInfoW shell32 180 +imp 'SHGetPathFromIDListA' SHGetPathFromIDListA shell32 534 +imp 'SHGetPathFromIDListEx' SHGetPathFromIDListEx shell32 535 +imp 'SHGetPathFromIDList' SHGetPathFromIDListW shell32 536 +imp 'SHGetPropertyStoreForWindow' SHGetPropertyStoreForWindow shell32 537 +imp 'SHGetPropertyStoreFromIDList' SHGetPropertyStoreFromIDList shell32 538 +imp 'SHGetPropertyStoreFromParsingName' SHGetPropertyStoreFromParsingName shell32 539 +imp 'SHGetRealIDL' SHGetRealIDL shell32 98 +imp 'SHGetSetFolderCustomSettings' SHGetSetFolderCustomSettings shell32 709 +imp 'SHGetSetSettings' SHGetSetSettings shell32 68 +imp 'SHGetSettings' SHGetSettings shell32 540 +imp 'SHGetSpecialFolderLocation' SHGetSpecialFolderLocation shell32 541 +imp 'SHGetSpecialFolderPathA' SHGetSpecialFolderPathA shell32 542 +imp 'SHGetSpecialFolderPath' SHGetSpecialFolderPathW shell32 543 +imp 'SHGetStockIconInfo' SHGetStockIconInfo shell32 544 +imp 'SHGetTemporaryPropertyForItem' SHGetTemporaryPropertyForItem shell32 545 +imp 'SHGetUnreadMailCount' SHGetUnreadMailCountW shell32 546 +imp 'SHHandleUpdateImage' SHHandleUpdateImage shell32 193 +imp 'SHHelpShortcuts_RunDLL' SHHelpShortcuts_RunDLL shell32 228 +imp 'SHHelpShortcuts_RunDLLA' SHHelpShortcuts_RunDLLA shell32 229 +imp 'SHHelpShortcuts_RunDLLW' SHHelpShortcuts_RunDLLW shell32 238 +imp 'SHILCreateFromPath' SHILCreateFromPath shell32 28 +imp 'SHInvokePrinterCommandA' SHInvokePrinterCommandA shell32 547 +imp 'SHInvokePrinterCommand' SHInvokePrinterCommandW shell32 548 +imp 'SHIsFileAvailableOffline' SHIsFileAvailableOffline shell32 549 +imp 'SHLimitInputEdit' SHLimitInputEdit shell32 747 +imp 'SHLoadInProc' SHLoadInProc shell32 550 +imp 'SHLoadIndirectString' SHLoadIndirectString KernelBase 1423 +imp 'SHLoadIndirectStringInternal' SHLoadIndirectStringInternal KernelBase 1424 +imp 'SHLoadNonloadedIconOverlayIdentifiers' SHLoadNonloadedIconOverlayIdentifiers shell32 551 +imp 'SHMapPIDLToSystemImageListIndex' SHMapPIDLToSystemImageListIndex shell32 77 +imp 'SHMultiFileProperties' SHMultiFileProperties shell32 716 +imp 'SHObjectProperties' SHObjectProperties shell32 178 +imp 'SHOpenFolderAndSelectItems' SHOpenFolderAndSelectItems shell32 552 +imp 'SHOpenPropSheet' SHOpenPropSheetW shell32 80 +imp 'SHOpenWithDialog' SHOpenWithDialog shell32 553 +imp 'SHParseDisplayName' SHParseDisplayName shell32 554 +imp 'SHPathPrepareForWriteA' SHPathPrepareForWriteA shell32 555 +imp 'SHPathPrepareForWrite' SHPathPrepareForWriteW shell32 556 +imp 'SHPropStgCreate' SHPropStgCreate shell32 685 +imp 'SHPropStgReadMultiple' SHPropStgReadMultiple shell32 688 +imp 'SHPropStgWriteMultiple' SHPropStgWriteMultiple shell32 689 +imp 'SHQueryRecycleBinA' SHQueryRecycleBinA shell32 557 +imp 'SHQueryRecycleBin' SHQueryRecycleBinW shell32 558 +imp 'SHQueryUserNotificationState' SHQueryUserNotificationState shell32 559 +imp 'SHRegCloseUSKey' SHRegCloseUSKey KernelBase 1425 +imp 'SHRegCreateUSKeyA' SHRegCreateUSKeyA KernelBase 1426 +imp 'SHRegCreateUSKey' SHRegCreateUSKeyW KernelBase 1427 +imp 'SHRegDeleteEmptyUSKeyA' SHRegDeleteEmptyUSKeyA KernelBase 1428 +imp 'SHRegDeleteEmptyUSKey' SHRegDeleteEmptyUSKeyW KernelBase 1429 +imp 'SHRegDeleteUSValueA' SHRegDeleteUSValueA KernelBase 1430 +imp 'SHRegDeleteUSValue' SHRegDeleteUSValueW KernelBase 1431 +imp 'SHRegEnumUSKeyA' SHRegEnumUSKeyA KernelBase 1432 +imp 'SHRegEnumUSKey' SHRegEnumUSKeyW KernelBase 1433 +imp 'SHRegEnumUSValueA' SHRegEnumUSValueA KernelBase 1434 +imp 'SHRegEnumUSValue' SHRegEnumUSValueW KernelBase 1435 +imp 'SHRegGetBoolUSValueA' SHRegGetBoolUSValueA KernelBase 1436 +imp 'SHRegGetBoolUSValue' SHRegGetBoolUSValueW KernelBase 1437 +imp 'SHRegGetUSValueA' SHRegGetUSValueA KernelBase 1438 +imp 'SHRegGetUSValue' SHRegGetUSValueW KernelBase 1439 +imp 'SHRegOpenUSKeyA' SHRegOpenUSKeyA KernelBase 1440 +imp 'SHRegOpenUSKey' SHRegOpenUSKeyW KernelBase 1441 +imp 'SHRegQueryInfoUSKeyA' SHRegQueryInfoUSKeyA KernelBase 1442 +imp 'SHRegQueryInfoUSKey' SHRegQueryInfoUSKeyW KernelBase 1443 +imp 'SHRegQueryUSValueA' SHRegQueryUSValueA KernelBase 1444 +imp 'SHRegQueryUSValue' SHRegQueryUSValueW KernelBase 1445 +imp 'SHRegSetUSValueA' SHRegSetUSValueA KernelBase 1446 +imp 'SHRegSetUSValue' SHRegSetUSValueW KernelBase 1447 +imp 'SHRegWriteUSValueA' SHRegWriteUSValueA KernelBase 1448 +imp 'SHRegWriteUSValue' SHRegWriteUSValueW KernelBase 1449 +imp 'SHRemoveLocalizedName' SHRemoveLocalizedName shell32 560 +imp 'SHReplaceFromPropSheetExtArray' SHReplaceFromPropSheetExtArray shell32 170 +imp 'SHResolveLibrary' SHResolveLibrary shell32 561 +imp 'SHRestricted' SHRestricted shell32 100 +imp 'SHSetDefaultProperties' SHSetDefaultProperties shell32 562 +imp 'SHSetFolderPathA' SHSetFolderPathA shell32 231 +imp 'SHSetFolderPath' SHSetFolderPathW shell32 232 +imp 'SHSetInstanceExplorer' SHSetInstanceExplorer shell32 176 +imp 'SHSetKnownFolderPath' SHSetKnownFolderPath shell32 563 +imp 'SHSetLocalizedName' SHSetLocalizedName shell32 564 +imp 'SHSetTemporaryPropertyForItem' SHSetTemporaryPropertyForItem shell32 565 +imp 'SHSetUnreadMailCount' SHSetUnreadMailCountW shell32 566 +imp 'SHShellFolderView_Message' SHShellFolderView_Message shell32 73 +imp 'SHShowManageLibraryUI' SHShowManageLibraryUI shell32 567 +imp 'SHSimpleIDListFromPath' SHSimpleIDListFromPath shell32 162 +imp 'SHStartNetConnectionDialog' SHStartNetConnectionDialogW shell32 14 +imp 'SHTestTokenMembership' SHTestTokenMembership shell32 245 +imp 'SHTruncateString' SHTruncateString KernelBase 1450 +imp 'SHUpdateImageA' SHUpdateImageA shell32 191 +imp 'SHUpdateImage' SHUpdateImageW shell32 192 +imp 'SHUpdateRecycleBinIcon' SHUpdateRecycleBinIcon shell32 568 +imp 'SHValidateUNC' SHValidateUNC shell32 173 +imp 'STROBJ_bEnum' STROBJ_bEnum gdi32 1810 +imp 'STROBJ_bEnumPositionsOnly' STROBJ_bEnumPositionsOnly gdi32 1811 +imp 'STROBJ_bGetAdvanceWidths' STROBJ_bGetAdvanceWidths gdi32 1812 +imp 'STROBJ_dwGetCodePage' STROBJ_dwGetCodePage gdi32 1813 +imp 'STROBJ_vEnumStart' STROBJ_vEnumStart gdi32 1814 +imp 'SafeBaseRegGetKeySecurity' SafeBaseRegGetKeySecurity advapi32 1707 +imp 'SaferCloseLevel' SaferCloseLevel advapi32 1708 +imp 'SaferComputeTokenFromLevel' SaferComputeTokenFromLevel advapi32 1709 +imp 'SaferCreateLevel' SaferCreateLevel advapi32 1710 +imp 'SaferGetLevelInformation' SaferGetLevelInformation advapi32 1711 +imp 'SaferGetPolicyInformation' SaferGetPolicyInformation advapi32 1712 +imp 'SaferIdentifyLevel' SaferIdentifyLevel advapi32 1713 +imp 'SaferRecordEventLogEntry' SaferRecordEventLogEntry advapi32 1714 +imp 'SaferSetLevelInformation' SaferSetLevelInformation advapi32 1715 +imp 'SaferSetPolicyInformation' SaferSetPolicyInformation advapi32 1716 +imp 'SaferiChangeRegistryScope' SaferiChangeRegistryScope advapi32 1717 +imp 'SaferiCompareTokenLevels' SaferiCompareTokenLevels advapi32 1718 +imp 'SaferiIsDllAllowed' SaferiIsDllAllowed advapi32 1719 +imp 'SaferiIsExecutableFileType' SaferiIsExecutableFileType advapi32 1720 +imp 'SaferiPopulateDefaultsInRegistry' SaferiPopulateDefaultsInRegistry advapi32 1721 +imp 'SaferiRecordEventLogEntry' SaferiRecordEventLogEntry advapi32 1722 +imp 'SaferiSearchMatchingHashRules' SaferiSearchMatchingHashRules advapi32 1723 +imp 'SaveAlternatePackageRootPath' SaveAlternatePackageRootPath KernelBase 1451 +imp 'SaveDC' SaveDC gdi32 1815 +imp 'SaveStateRootFolderPath' SaveStateRootFolderPath KernelBase 1452 +imp 'SbExecuteProcedure' SbExecuteProcedure ntdll 1610 +imp 'SbSelectProcedure' SbSelectProcedure ntdll 1611 +imp 'ScaleRgn' ScaleRgn gdi32 1816 +imp 'ScaleValues' ScaleValues gdi32 1817 +imp 'ScaleViewportExtEx' ScaleViewportExtEx gdi32 1818 +imp 'ScaleWindowExtEx' ScaleWindowExtEx gdi32 1819 +imp 'ScreenToClient' ScreenToClient user32 2291 +imp 'ScrollChildren' ScrollChildren user32 2292 +imp 'ScrollConsoleScreenBufferA' ScrollConsoleScreenBufferA KernelBase 1453 +imp 'ScrollConsoleScreenBuffer' ScrollConsoleScreenBufferW KernelBase 1454 +imp 'ScrollDC' ScrollDC user32 2293 +imp 'ScrollWindow' ScrollWindow user32 2294 +imp 'ScrollWindowEx' ScrollWindowEx user32 2295 +imp 'SearchPathA' SearchPathA KernelBase 1455 +imp 'SearchPath' SearchPathW KernelBase 1456 +imp 'SelectBrushLocal' SelectBrushLocal gdi32 1860 +imp 'SelectClipPath' SelectClipPath gdi32 1861 +imp 'SelectClipRgn' SelectClipRgn gdi32 1862 +imp 'SelectFontLocal' SelectFontLocal gdi32 1863 +imp 'SelectObject' SelectObject gdi32 1864 +imp 'SelectPalette' SelectPalette gdi32 1865 +imp 'SendDlgItemMessageA' SendDlgItemMessageA user32 2296 +imp 'SendDlgItemMessage' SendDlgItemMessageW user32 2297 +imp 'SendIMEMessageExA' SendIMEMessageExA user32 2298 +imp 'SendIMEMessageEx' SendIMEMessageExW user32 2299 +imp 'SendInput' SendInput user32 2300 +imp 'SendMessageA' SendMessageA user32 2301 +imp 'SendMessageCallbackA' SendMessageCallbackA user32 2302 +imp 'SendMessageCallback' SendMessageCallbackW user32 2303 +imp 'SendMessageTimeoutA' SendMessageTimeoutA user32 2304 +imp 'SendMessageTimeout' SendMessageTimeoutW user32 2305 +imp 'SendMessage' SendMessageW user32 2306 +imp 'SendNotifyMessageA' SendNotifyMessageA user32 2307 +imp 'SendNotifyMessage' SendNotifyMessageW user32 2308 +imp 'SetAbortProc' SetAbortProc gdi32 1866 +imp 'SetAclInformation' SetAclInformation KernelBase 1457 +imp 'SetActiveWindow' SetActiveWindow user32 2309 +imp 'SetAddrInfoExA' SetAddrInfoExA ws2_32 37 +imp 'SetAddrInfoEx' SetAddrInfoExW ws2_32 38 +imp 'SetArcDirection' SetArcDirection gdi32 1867 +imp 'SetBitmapAttributes' SetBitmapAttributes gdi32 1868 +imp 'SetBitmapBits' SetBitmapBits gdi32 1869 +imp 'SetBitmapDimensionEx' SetBitmapDimensionEx gdi32 1870 +imp 'SetBkColor' SetBkColor gdi32 1871 +imp 'SetBkMode' SetBkMode gdi32 1872 2 +imp 'SetBoundsRect' SetBoundsRect gdi32 1873 +imp 'SetBrushAttributes' SetBrushAttributes gdi32 1874 +imp 'SetBrushOrgEx' SetBrushOrgEx gdi32 1875 +imp 'SetCachedSigningLevel' SetCachedSigningLevel KernelBase 1458 +imp 'SetCalendarInfoA' SetCalendarInfoA kernel32 1249 +imp 'SetCalendarInfo' SetCalendarInfoW KernelBase 1459 +imp 'SetCapture' SetCapture user32 2310 +imp 'SetCaretBlinkTime' SetCaretBlinkTime user32 2311 +imp 'SetCaretPos' SetCaretPos user32 2312 +imp 'SetClassLongA' SetClassLongA user32 2313 +imp 'SetClassLongPtrA' SetClassLongPtrA user32 2314 +imp 'SetClassLongPtr' SetClassLongPtrW user32 2315 +imp 'SetClassLong' SetClassLongW user32 2316 +imp 'SetClassWord' SetClassWord user32 2317 +imp 'SetClientDynamicTimeZoneInformation' SetClientDynamicTimeZoneInformation KernelBase 1460 +imp 'SetClientTimeZoneInformation' SetClientTimeZoneInformation KernelBase 1461 +imp 'SetClipboardData' SetClipboardData user32 2318 +imp 'SetClipboardViewer' SetClipboardViewer user32 2319 +imp 'SetCoalescableTimer' SetCoalescableTimer user32 2320 +imp 'SetColorAdjustment' SetColorAdjustment gdi32 1876 +imp 'SetColorSpace' SetColorSpace gdi32 1877 +imp 'SetComPlusPackageInstallStatus' SetComPlusPackageInstallStatus kernel32 1251 +imp 'SetCommBreak' SetCommBreak KernelBase 1462 +imp 'SetCommConfig' SetCommConfig KernelBase 1463 +imp 'SetCommMask' SetCommMask KernelBase 1464 +imp 'SetCommState' SetCommState KernelBase 1465 +imp 'SetCommTimeouts' SetCommTimeouts KernelBase 1466 +imp 'SetComputerNameA' SetComputerNameA KernelBase 1467 +imp 'SetComputerNameEx2W' SetComputerNameEx2W KernelBase 1468 +imp 'SetComputerNameExA' SetComputerNameExA KernelBase 1469 +imp 'SetComputerNameEx' SetComputerNameExW KernelBase 1470 +imp 'SetComputerName' SetComputerNameW KernelBase 1471 +imp 'SetConsoleActiveScreenBuffer' SetConsoleActiveScreenBuffer KernelBase 1472 1 +imp 'SetConsoleCP' SetConsoleCP KernelBase 1473 1 +imp 'SetConsoleCtrlHandler' SetConsoleCtrlHandler KernelBase 1474 2 +imp 'SetConsoleCursor' SetConsoleCursor kernel32 1265 +imp 'SetConsoleCursorInfo' SetConsoleCursorInfo KernelBase 1475 2 +imp 'SetConsoleCursorMode' SetConsoleCursorMode kernel32 1267 +imp 'SetConsoleCursorPosition' SetConsoleCursorPosition KernelBase 1476 2 +imp 'SetConsoleDisplayMode' SetConsoleDisplayMode KernelBase 1477 +imp 'SetConsoleFont' SetConsoleFont kernel32 1270 +imp 'SetConsoleHardwareState' SetConsoleHardwareState kernel32 1271 +imp 'SetConsoleHistoryInfo' SetConsoleHistoryInfo KernelBase 1478 +imp 'SetConsoleIcon' SetConsoleIcon kernel32 1273 +imp 'SetConsoleInputExeNameA' SetConsoleInputExeNameA KernelBase 1479 +imp 'SetConsoleInputExeName' SetConsoleInputExeNameW KernelBase 1480 +imp 'SetConsoleKeyShortcuts' SetConsoleKeyShortcuts kernel32 1276 +imp 'SetConsoleLocalEUDC' SetConsoleLocalEUDC kernel32 1277 +imp 'SetConsoleMaximumWindowSize' SetConsoleMaximumWindowSize kernel32 1278 +imp 'SetConsoleMenuClose' SetConsoleMenuClose kernel32 1279 +imp 'SetConsoleMode' SetConsoleMode KernelBase 1481 2 +imp 'SetConsoleNlsMode' SetConsoleNlsMode kernel32 1281 +imp 'SetConsoleNumberOfCommandsA' SetConsoleNumberOfCommandsA KernelBase 1482 +imp 'SetConsoleNumberOfCommands' SetConsoleNumberOfCommandsW KernelBase 1483 +imp 'SetConsoleOS2OemFormat' SetConsoleOS2OemFormat kernel32 1284 +imp 'SetConsoleOutputCP' SetConsoleOutputCP KernelBase 1484 1 +imp 'SetConsolePalette' SetConsolePalette kernel32 1286 +imp 'SetConsoleScreenBufferInfoEx' SetConsoleScreenBufferInfoEx KernelBase 1485 2 +imp 'SetConsoleScreenBufferSize' SetConsoleScreenBufferSize KernelBase 1486 2 +imp 'SetConsoleTextAttribute' SetConsoleTextAttribute KernelBase 1487 +imp 'SetConsoleTitle' SetConsoleTitleW KernelBase 1489 1 +imp 'SetConsoleTitleA' SetConsoleTitleA KernelBase 1488 1 +imp 'SetConsoleWindowInfo' SetConsoleWindowInfo KernelBase 1490 3 +imp 'SetCoreWindow' SetCoreWindow user32 2571 +imp 'SetCurrentConsoleFontEx' SetCurrentConsoleFontEx KernelBase 1492 +imp 'SetCurrentDirectory' SetCurrentDirectoryW KernelBase 1494 1 +imp 'SetCurrentDirectoryA' SetCurrentDirectoryA KernelBase 1493 1 +imp 'SetCurrentProcessExplicitAppUserModelID' SetCurrentProcessExplicitAppUserModelID shell32 569 +imp 'SetCursor' SetCursor user32 2321 +imp 'SetCursorContents' SetCursorContents user32 2322 +imp 'SetCursorPos' SetCursorPos user32 2323 +imp 'SetDCBrushColor' SetDCBrushColor gdi32 1878 +imp 'SetDCDpiScaleValue' SetDCDpiScaleValue gdi32 1879 +imp 'SetDCPenColor' SetDCPenColor gdi32 1880 +imp 'SetDIBColorTable' SetDIBColorTable gdi32 1881 +imp 'SetDIBits' SetDIBits gdi32 1882 +imp 'SetDIBitsToDevice' SetDIBitsToDevice gdi32 1883 +imp 'SetDebugErrorLevel' SetDebugErrorLevel user32 2324 +imp 'SetDefaultCommConfigA' SetDefaultCommConfigA kernel32 1297 +imp 'SetDefaultCommConfig' SetDefaultCommConfigW kernel32 1298 +imp 'SetDefaultDllDirectories' SetDefaultDllDirectories KernelBase 1495 1 +imp 'SetDeskWallpaper' SetDeskWallpaper user32 2325 +imp 'SetDesktopColorTransform' SetDesktopColorTransform user32 2326 +imp 'SetDeviceGammaRamp' SetDeviceGammaRamp gdi32 1884 +imp 'SetDialogControlDpiChangeBehavior' SetDialogControlDpiChangeBehavior user32 2327 +imp 'SetDialogDpiChangeBehavior' SetDialogDpiChangeBehavior user32 2328 +imp 'SetDisplayAutoRotationPreferences' SetDisplayAutoRotationPreferences user32 2329 +imp 'SetDisplayConfig' SetDisplayConfig user32 2330 +imp 'SetDlgItemInt' SetDlgItemInt user32 2331 +imp 'SetDlgItemTextA' SetDlgItemTextA user32 2332 +imp 'SetDlgItemText' SetDlgItemTextW user32 2333 +imp 'SetDllDirectoryA' SetDllDirectoryA kernel32 1300 +imp 'SetDllDirectory' SetDllDirectoryW kernel32 1301 +imp 'SetDoubleClickTime' SetDoubleClickTime user32 2334 +imp 'SetDynamicTimeZoneInformation' SetDynamicTimeZoneInformation KernelBase 1496 +imp 'SetEncryptedFileMetadata' SetEncryptedFileMetadata advapi32 1725 +imp 'SetEndOfFile' SetEndOfFile KernelBase 1497 1 +imp 'SetEnhMetaFileBits' SetEnhMetaFileBits gdi32 1885 +imp 'SetEntriesInAccessListA' SetEntriesInAccessListA advapi32 1726 +imp 'SetEntriesInAccessList' SetEntriesInAccessListW advapi32 1727 +imp 'SetEntriesInAclA' SetEntriesInAclA advapi32 1728 +imp 'SetEntriesInAcl' SetEntriesInAclW advapi32 1729 +imp 'SetEntriesInAuditListA' SetEntriesInAuditListA advapi32 1730 +imp 'SetEntriesInAuditList' SetEntriesInAuditListW advapi32 1731 +imp 'SetEnvironmentStrings' SetEnvironmentStringsW KernelBase 1498 1 +imp 'SetEnvironmentStringsA' SetEnvironmentStringsA kernel32 1304 1 +imp 'SetEnvironmentVariable' SetEnvironmentVariableW KernelBase 1500 2 +imp 'SetEnvironmentVariableA' SetEnvironmentVariableA KernelBase 1499 2 +imp 'SetErrorMode' SetErrorMode KernelBase 1501 1 +imp 'SetEvent' SetEvent KernelBase 1502 1 +imp 'SetExtensionProperty' SetExtensionProperty KernelBase 1504 +imp 'SetFeatureReportResponse' SetFeatureReportResponse user32 2335 +imp 'SetFileApisToANSI' SetFileApisToANSI KernelBase 1505 +imp 'SetFileApisToOEM' SetFileApisToOEM KernelBase 1506 +imp 'SetFileAttributes' SetFileAttributesW KernelBase 1508 2 +imp 'SetFileAttributesA' SetFileAttributesA KernelBase 1507 2 +imp 'SetFileAttributesTransactedA' SetFileAttributesTransactedA kernel32 1314 +imp 'SetFileAttributesTransacted' SetFileAttributesTransactedW kernel32 1315 +imp 'SetFileBandwidthReservation' SetFileBandwidthReservation kernel32 1317 +imp 'SetFileCompletionNotificationModes' SetFileCompletionNotificationModes kernel32 1318 +imp 'SetFileInformationByHandle' SetFileInformationByHandle KernelBase 1509 +imp 'SetFileIoOverlappedRange' SetFileIoOverlappedRange KernelBase 1510 +imp 'SetFilePointer' SetFilePointer KernelBase 1511 4 +imp 'SetFilePointerEx' SetFilePointerEx KernelBase 1512 4 +imp 'SetFileSecurityA' SetFileSecurityA advapi32 1732 +imp 'SetFileSecurity' SetFileSecurityW KernelBase 1513 +imp 'SetFileShortNameA' SetFileShortNameA kernel32 1323 +imp 'SetFileShortName' SetFileShortNameW kernel32 1324 +imp 'SetFileTime' SetFileTime KernelBase 1514 4 +imp 'SetFileValidData' SetFileValidData KernelBase 1515 2 +imp 'SetFirmwareEnvironmentVariableA' SetFirmwareEnvironmentVariableA kernel32 1327 +imp 'SetFirmwareEnvironmentVariableExA' SetFirmwareEnvironmentVariableExA kernel32 1328 +imp 'SetFirmwareEnvironmentVariableEx' SetFirmwareEnvironmentVariableExW kernel32 1329 +imp 'SetFirmwareEnvironmentVariable' SetFirmwareEnvironmentVariableW kernel32 1330 +imp 'SetFocus' SetFocus user32 2336 +imp 'SetFontEnumeration' SetFontEnumeration gdi32 1886 +imp 'SetForegroundWindow' SetForegroundWindow user32 2337 +imp 'SetGestureConfig' SetGestureConfig user32 2338 +imp 'SetGraphicsMode' SetGraphicsMode gdi32 1887 +imp 'SetHandleCount' SetHandleCount KernelBase 1516 1 +imp 'SetHandleInformation' SetHandleInformation KernelBase 1517 3 +imp 'SetICMMode' SetICMMode gdi32 1888 +imp 'SetICMProfileA' SetICMProfileA gdi32 1889 +imp 'SetICMProfile' SetICMProfileW gdi32 1890 +imp 'SetInformationCodeAuthzLevel' SetInformationCodeAuthzLevelW advapi32 1734 +imp 'SetInformationCodeAuthzPolicy' SetInformationCodeAuthzPolicyW advapi32 1735 +imp 'SetInformationJobObject' SetInformationJobObject kernel32 1333 +imp 'SetInternalWindowPos' SetInternalWindowPos user32 2339 +imp 'SetIoRateControlInformationJobObject' SetIoRateControlInformationJobObject kernel32 1334 +imp 'SetIsDeveloperModeEnabled' SetIsDeveloperModeEnabled KernelBase 1518 +imp 'SetIsSideloadingEnabled' SetIsSideloadingEnabled KernelBase 1519 +imp 'SetKernelObjectSecurity' SetKernelObjectSecurity KernelBase 1520 +imp 'SetKeyboardState' SetKeyboardState user32 2340 +imp 'SetLastConsoleEventActive' SetLastConsoleEventActive KernelBase 1521 +imp 'SetLastError' SetLastError kernel32 1336 1 +imp 'SetLastErrorEx' SetLastErrorEx user32 2341 +imp 'SetLayeredWindowAttributes' SetLayeredWindowAttributes user32 2342 +imp 'SetLayout' SetLayout gdi32 1891 +imp 'SetLayoutWidth' SetLayoutWidth gdi32 1892 +imp 'SetLocalPrimaryComputerNameA' SetLocalPrimaryComputerNameA kernel32 1337 +imp 'SetLocalPrimaryComputerName' SetLocalPrimaryComputerNameW kernel32 1338 +imp 'SetLocalTime' SetLocalTime KernelBase 1523 +imp 'SetLocaleInfoA' SetLocaleInfoA kernel32 1340 +imp 'SetLocaleInfo' SetLocaleInfoW KernelBase 1524 +imp 'SetMagicColors' SetMagicColors gdi32 1893 +imp 'SetMagnificationDesktopColorEffect' SetMagnificationDesktopColorEffect user32 2343 +imp 'SetMagnificationDesktopMagnification' SetMagnificationDesktopMagnification user32 2344 +imp 'SetMagnificationDesktopSamplingMode' SetMagnificationDesktopSamplingMode user32 2345 +imp 'SetMagnificationLensCtxInformation' SetMagnificationLensCtxInformation user32 2346 +imp 'SetMailslotInfo' SetMailslotInfo kernel32 1342 +imp 'SetMapMode' SetMapMode gdi32 1894 +imp 'SetMapperFlags' SetMapperFlags gdi32 1895 +imp 'SetMenu' SetMenu user32 2347 +imp 'SetMenuContextHelpId' SetMenuContextHelpId user32 2348 +imp 'SetMenuDefaultItem' SetMenuDefaultItem user32 2349 +imp 'SetMenuInfo' SetMenuInfo user32 2350 +imp 'SetMenuItemBitmaps' SetMenuItemBitmaps user32 2351 +imp 'SetMenuItemInfoA' SetMenuItemInfoA user32 2352 +imp 'SetMenuItemInfo' SetMenuItemInfoW user32 2353 +imp 'SetMessageExtraInfo' SetMessageExtraInfo user32 2354 +imp 'SetMessageQueue' SetMessageQueue user32 2355 +imp 'SetMessageWaitingIndicator' SetMessageWaitingIndicator kernel32 1343 +imp 'SetMetaFileBitsEx' SetMetaFileBitsEx gdi32 1896 +imp 'SetMetaRgn' SetMetaRgn gdi32 1897 +imp 'SetMirrorRendering' SetMirrorRendering user32 2356 +imp 'SetMiterLimit' SetMiterLimit gdi32 1898 +imp 'SetNamedPipeAttribute' SetNamedPipeAttribute kernel32 1344 +imp 'SetNamedPipeHandleState' SetNamedPipeHandleState KernelBase 1525 4 +imp 'SetNamedSecurityInfoA' SetNamedSecurityInfoA advapi32 1737 +imp 'SetNamedSecurityInfoExA' SetNamedSecurityInfoExA advapi32 1738 +imp 'SetNamedSecurityInfoEx' SetNamedSecurityInfoExW advapi32 1739 +imp 'SetNamedSecurityInfo' SetNamedSecurityInfoW advapi32 1740 +imp 'SetOPMSigningKeyAndSequenceNumbers' SetOPMSigningKeyAndSequenceNumbers gdi32 1899 +imp 'SetPaletteEntries' SetPaletteEntries gdi32 1900 +imp 'SetParent' SetParent user32 2357 2 +imp 'SetPhysicalCursorPos' SetPhysicalCursorPos user32 2358 +imp 'SetPixel' SetPixel gdi32 1901 +imp 'SetPixelFormat' SetPixelFormat gdi32 1902 +imp 'SetPixelV' SetPixelV gdi32 1903 +imp 'SetPolyFillMode' SetPolyFillMode gdi32 1904 +imp 'SetPriorityClass' SetPriorityClass KernelBase 1526 2 +imp 'SetPrivateObjectSecurity' SetPrivateObjectSecurity KernelBase 1527 +imp 'SetPrivateObjectSecurityEx' SetPrivateObjectSecurityEx KernelBase 1528 +imp 'SetProcessAffinityMask' SetProcessAffinityMask kernel32 1347 2 +imp 'SetProcessAffinityUpdateMode' SetProcessAffinityUpdateMode KernelBase 1529 +imp 'SetProcessDEPPolicy' SetProcessDEPPolicy kernel32 1349 +imp 'SetProcessDPIAware' SetProcessDPIAware user32 2359 +imp 'SetProcessDefaultCpuSets' SetProcessDefaultCpuSets KernelBase 1530 +imp 'SetProcessDefaultLayout' SetProcessDefaultLayout user32 2360 +imp 'SetProcessDpiAwarenessContext' SetProcessDpiAwarenessContext user32 2361 +imp 'SetProcessDpiAwarenessInternal' SetProcessDpiAwarenessInternal user32 2362 +imp 'SetProcessGroupAffinity' SetProcessGroupAffinity KernelBase 1531 +imp 'SetProcessInformation' SetProcessInformation KernelBase 1532 +imp 'SetProcessMitigationPolicy' SetProcessMitigationPolicy KernelBase 1533 +imp 'SetProcessPreferredUILanguages' SetProcessPreferredUILanguages KernelBase 1534 +imp 'SetProcessPriorityBoost' SetProcessPriorityBoost KernelBase 1535 2 +imp 'SetProcessRestrictionExemption' SetProcessRestrictionExemption user32 2363 +imp 'SetProcessShutdownParameters' SetProcessShutdownParameters KernelBase 1536 +imp 'SetProcessValidCallTargets' SetProcessValidCallTargets KernelBase 1537 +imp 'SetProcessWindowStation' SetProcessWindowStation user32 2364 +imp 'SetProcessWorkingSetSize' SetProcessWorkingSetSize kernel32 1356 3 +imp 'SetProcessWorkingSetSizeEx' SetProcessWorkingSetSizeEx KernelBase 1538 4 +imp 'SetProgmanWindow' SetProgmanWindow user32 2365 +imp 'SetPropA' SetPropA user32 2366 +imp 'SetProp' SetPropW user32 2367 +imp 'SetProtectedPolicy' SetProtectedPolicy KernelBase 1539 +imp 'SetProtocolProperty' SetProtocolProperty KernelBase 1540 +imp 'SetROP2' SetROP2 gdi32 1905 +imp 'SetRect' SetRect user32 2368 +imp 'SetRectEmpty' SetRectEmpty user32 2369 +imp 'SetRectRgn' SetRectRgn gdi32 1906 +imp 'SetRelAbs' SetRelAbs gdi32 1907 +imp 'SetRoamingLastObservedChangeTime' SetRoamingLastObservedChangeTime KernelBase 1541 +imp 'SetScrollInfo' SetScrollInfo user32 2370 +imp 'SetScrollPos' SetScrollPos user32 2371 +imp 'SetScrollRange' SetScrollRange user32 2372 +imp 'SetSearchPathMode' SetSearchPathMode kernel32 1359 +imp 'SetSecurityAccessMask' SetSecurityAccessMask KernelBase 1542 +imp 'SetSecurityDescriptorControl' SetSecurityDescriptorControl KernelBase 1543 +imp 'SetSecurityDescriptorDacl' SetSecurityDescriptorDacl KernelBase 1544 +imp 'SetSecurityDescriptorGroup' SetSecurityDescriptorGroup KernelBase 1545 +imp 'SetSecurityDescriptorOwner' SetSecurityDescriptorOwner KernelBase 1546 +imp 'SetSecurityDescriptorRMControl' SetSecurityDescriptorRMControl KernelBase 1547 +imp 'SetSecurityDescriptorSacl' SetSecurityDescriptorSacl KernelBase 1548 +imp 'SetSecurityInfo' SetSecurityInfo advapi32 1750 +imp 'SetSecurityInfoExA' SetSecurityInfoExA advapi32 1751 +imp 'SetSecurityInfoEx' SetSecurityInfoExW advapi32 1752 +imp 'SetServiceBits' SetServiceBits advapi32 1753 +imp 'SetServiceObjectSecurity' SetServiceObjectSecurity advapi32 1754 +imp 'SetServiceStatus' SetServiceStatus advapi32 1755 +imp 'SetShellWindow' SetShellWindow user32 2373 +imp 'SetShellWindowEx' SetShellWindowEx user32 2374 +imp 'SetStateVersion' SetStateVersion KernelBase 1549 +imp 'SetStdHandle' SetStdHandle KernelBase 1550 2 +imp 'SetStdHandleEx' SetStdHandleEx KernelBase 1551 +imp 'SetStretchBltMode' SetStretchBltMode gdi32 1908 +imp 'SetSysColors' SetSysColors user32 2375 +imp 'SetSysColorsTemp' SetSysColorsTemp user32 2376 +imp 'SetSystemCursor' SetSystemCursor user32 2377 +imp 'SetSystemFileCacheSize' SetSystemFileCacheSize KernelBase 1552 +imp 'SetSystemMenu' SetSystemMenu user32 2378 +imp 'SetSystemPaletteUse' SetSystemPaletteUse gdi32 1909 +imp 'SetSystemPowerState' SetSystemPowerState kernel32 1363 +imp 'SetSystemTime' SetSystemTime KernelBase 1553 +imp 'SetSystemTimeAdjustment' SetSystemTimeAdjustment KernelBase 1554 +imp 'SetSystemTimeAdjustmentPrecise' SetSystemTimeAdjustmentPrecise KernelBase 1555 +imp 'SetTapeParameters' SetTapeParameters kernel32 1366 +imp 'SetTapePosition' SetTapePosition kernel32 1367 +imp 'SetTaskmanWindow' SetTaskmanWindow user32 2379 +imp 'SetTermsrvAppInstallMode' SetTermsrvAppInstallMode kernel32 1368 +imp 'SetTextAlign' SetTextAlign gdi32 1910 2 +imp 'SetTextCharacterExtra' SetTextCharacterExtra gdi32 1911 +imp 'SetTextColor' SetTextColor gdi32 1912 2 +imp 'SetTextJustification' SetTextJustification gdi32 1913 3 +imp 'SetThreadAffinityMask' SetThreadAffinityMask kernel32 1369 2 +imp 'SetThreadContext' SetThreadContext KernelBase 1556 +imp 'SetThreadDescription' SetThreadDescription KernelBase 1557 +imp 'SetThreadDesktop' SetThreadDesktop user32 2380 +imp 'SetThreadDpiAwarenessContext' SetThreadDpiAwarenessContext user32 2381 +imp 'SetThreadDpiHostingBehavior' SetThreadDpiHostingBehavior user32 2382 +imp 'SetThreadErrorMode' SetThreadErrorMode KernelBase 1558 +imp 'SetThreadExecutionState' SetThreadExecutionState kernel32 1373 +imp 'SetThreadGroupAffinity' SetThreadGroupAffinity KernelBase 1559 +imp 'SetThreadIdealProcessor' SetThreadIdealProcessor KernelBase 1560 +imp 'SetThreadIdealProcessorEx' SetThreadIdealProcessorEx KernelBase 1561 +imp 'SetThreadInformation' SetThreadInformation KernelBase 1562 +imp 'SetThreadInputBlocked' SetThreadInputBlocked user32 2383 +imp 'SetThreadLocale' SetThreadLocale KernelBase 1563 +imp 'SetThreadPreferredUILanguages' SetThreadPreferredUILanguages KernelBase 1564 +imp 'SetThreadPriority' SetThreadPriority KernelBase 1565 2 +imp 'SetThreadPriorityBoost' SetThreadPriorityBoost KernelBase 1566 2 +imp 'SetThreadSelectedCpuSets' SetThreadSelectedCpuSets KernelBase 1567 +imp 'SetThreadStackGuarantee' SetThreadStackGuarantee KernelBase 1568 +imp 'SetThreadToken' SetThreadToken KernelBase 1569 +imp 'SetThreadUILanguage' SetThreadUILanguage KernelBase 1570 +imp 'SetThreadpoolStackInformation' SetThreadpoolStackInformation KernelBase 1571 +imp 'SetThreadpoolThreadMinimum' SetThreadpoolThreadMinimum KernelBase 1573 +imp 'SetTimeZoneInformation' SetTimeZoneInformation KernelBase 1578 +imp 'SetTimer' SetTimer user32 2384 4 +imp 'SetTimerQueueTimer' SetTimerQueueTimer kernel32 1394 +imp 'SetTokenInformation' SetTokenInformation KernelBase 1579 +imp 'SetUmsThreadInformation' SetUmsThreadInformation kernel32 1395 +imp 'SetUnhandledExceptionFilter' SetUnhandledExceptionFilter KernelBase 1580 1 +imp 'SetUserFileEncryptionKey' SetUserFileEncryptionKey advapi32 1759 +imp 'SetUserFileEncryptionKeyEx' SetUserFileEncryptionKeyEx advapi32 1760 +imp 'SetUserGeoID' SetUserGeoID KernelBase 1581 +imp 'SetUserGeoName' SetUserGeoName KernelBase 1582 +imp 'SetUserObjectInformationA' SetUserObjectInformationA user32 2385 +imp 'SetUserObjectInformation' SetUserObjectInformationW user32 2386 +imp 'SetUserObjectSecurity' SetUserObjectSecurity user32 2387 +imp 'SetVDMCurrentDirectories' SetVDMCurrentDirectories kernel32 1399 +imp 'SetViewportExtEx' SetViewportExtEx gdi32 1914 +imp 'SetViewportOrgEx' SetViewportOrgEx gdi32 1915 +imp 'SetVirtualResolution' SetVirtualResolution gdi32 1916 +imp 'SetVolumeLabelA' SetVolumeLabelA kernel32 1400 +imp 'SetVolumeLabel' SetVolumeLabelW kernel32 1401 +imp 'SetVolumeMountPointA' SetVolumeMountPointA kernel32 1402 +imp 'SetVolumeMountPoint' SetVolumeMountPointW kernel32 1403 +imp 'SetVolumeMountPointWStub' SetVolumeMountPointWStub kernel32 1404 +imp 'SetWaitableTimer' SetWaitableTimer KernelBase 1583 +imp 'SetWaitableTimerEx' SetWaitableTimerEx KernelBase 1584 +imp 'SetWinEventHook' SetWinEventHook user32 2388 +imp 'SetWinMetaFileBits' SetWinMetaFileBits gdi32 1917 +imp 'SetWindowBand' SetWindowBand user32 2389 +imp 'SetWindowCompositionAttribute' SetWindowCompositionAttribute user32 2390 +imp 'SetWindowCompositionTransition' SetWindowCompositionTransition user32 2391 +imp 'SetWindowContextHelpId' SetWindowContextHelpId user32 2392 +imp 'SetWindowDisplayAffinity' SetWindowDisplayAffinity user32 2393 +imp 'SetWindowExtEx' SetWindowExtEx gdi32 1918 +imp 'SetWindowFeedbackSetting' SetWindowFeedbackSetting user32 2394 +imp 'SetWindowLongA' SetWindowLongA user32 2395 +imp 'SetWindowLongPtrA' SetWindowLongPtrA user32 2396 +imp 'SetWindowLongPtr' SetWindowLongPtrW user32 2397 +imp 'SetWindowLong' SetWindowLongW user32 2398 +imp 'SetWindowOrgEx' SetWindowOrgEx gdi32 1919 +imp 'SetWindowPlacement' SetWindowPlacement user32 2399 +imp 'SetWindowPos' SetWindowPos user32 2400 7 +imp 'SetWindowRgn' SetWindowRgn user32 2401 +imp 'SetWindowRgnEx' SetWindowRgnEx user32 2402 +imp 'SetWindowStationUser' SetWindowStationUser user32 2403 +imp 'SetWindowText' SetWindowTextW user32 2405 2 +imp 'SetWindowTextA' SetWindowTextA user32 2404 2 +imp 'SetWindowWord' SetWindowWord user32 2406 +imp 'SetWindowsHook' SetWindowsHookW user32 2410 2 +imp 'SetWindowsHookA' SetWindowsHookA user32 2407 2 +imp 'SetWindowsHookEx' SetWindowsHookExW user32 2409 4 +imp 'SetWindowsHookExA' SetWindowsHookExA user32 2408 4 +imp 'SetWorldTransform' SetWorldTransform gdi32 1920 +imp 'SetXStateFeaturesMask' SetXStateFeaturesMask KernelBase 1585 +imp 'SetupComm' SetupComm KernelBase 1586 +imp 'SharedLocalIsEnabled' SharedLocalIsEnabled KernelBase 1587 +imp 'SheChangeDirA' SheChangeDirA shell32 570 +imp 'SheChangeDirEx' SheChangeDirExW shell32 571 +imp 'SheGetDirA' SheGetDirA shell32 572 +imp 'SheSetCurDrive' SheSetCurDrive shell32 573 +imp 'ShellAboutA' ShellAboutA shell32 574 +imp 'ShellAbout' ShellAboutW shell32 575 +imp 'ShellExec_RunDLL' ShellExec_RunDLL shell32 576 +imp 'ShellExec_RunDLLA' ShellExec_RunDLLA shell32 577 +imp 'ShellExec_RunDLLW' ShellExec_RunDLLW shell32 578 +imp 'ShellExecuteA' ShellExecuteA shell32 579 +imp 'ShellExecuteExA' ShellExecuteExA shell32 581 +imp 'ShellExecuteEx' ShellExecuteExW shell32 582 +imp 'ShellExecute' ShellExecuteW shell32 583 +imp 'ShellHookProc' ShellHookProc shell32 584 +imp 'Shell_GetCachedImageIndexA' Shell_GetCachedImageIndexA shell32 585 +imp 'Shell_GetCachedImageIndex' Shell_GetCachedImageIndexW shell32 586 +imp 'Shell_GetImageLists' Shell_GetImageLists shell32 71 +imp 'Shell_MergeMenus' Shell_MergeMenus shell32 67 +imp 'Shell_NotifyIconA' Shell_NotifyIconA shell32 588 +imp 'Shell_NotifyIconGetRect' Shell_NotifyIconGetRect shell32 589 +imp 'Shell_NotifyIcon' Shell_NotifyIconW shell32 590 +imp 'ShipAssert' ShipAssert ntdll 1612 +imp 'ShipAssertGetBufferInfo' ShipAssertGetBufferInfo ntdll 1613 +imp 'ShipAssertMsgA' ShipAssertMsgA ntdll 1614 +imp 'ShipAssertMsg' ShipAssertMsgW ntdll 1615 +imp 'ShowCaret' ShowCaret user32 2411 +imp 'ShowConsoleCursor' ShowConsoleCursor kernel32 1409 +imp 'ShowCursor' ShowCursor user32 2412 +imp 'ShowOwnedPopups' ShowOwnedPopups user32 2413 +imp 'ShowScrollBar' ShowScrollBar user32 2414 +imp 'ShowStartGlass' ShowStartGlass user32 2415 +imp 'ShowSystemCursor' ShowSystemCursor user32 2416 +imp 'ShowWindow' ShowWindow user32 2417 2 +imp 'ShowWindowAsync' ShowWindowAsync user32 2418 +imp 'ShutdownBlockReasonCreate' ShutdownBlockReasonCreate user32 2419 +imp 'ShutdownBlockReasonDestroy' ShutdownBlockReasonDestroy user32 2420 +imp 'ShutdownBlockReasonQuery' ShutdownBlockReasonQuery user32 2421 +imp 'SignalFileOpen' SignalFileOpen shell32 103 +imp 'SignalObjectAndWait' SignalObjectAndWait KernelBase 1588 +imp 'SignalRedirectionStartComplete' SignalRedirectionStartComplete user32 2422 +imp 'SizeofResource' SizeofResource KernelBase 1589 +imp 'SkipPointerFrameMessages' SkipPointerFrameMessages user32 2423 +imp 'Sleep' Sleep KernelBase 1590 1 +imp 'SleepConditionVariableCS' SleepConditionVariableCS KernelBase 1591 +imp 'SleepConditionVariableSRW' SleepConditionVariableSRW KernelBase 1592 +imp 'SleepEx' SleepEx KernelBase 1593 2 +imp 'SoftModalMessageBox' SoftModalMessageBox user32 2424 +imp 'SortCloseHandle' SortCloseHandle kernel32 1416 +imp 'SortGetHandle' SortGetHandle kernel32 1417 +imp 'SoundSentry' SoundSentry user32 2425 +imp 'SpecialMBToWC' SpecialMBToWC KernelBase 1594 +imp 'Ssync_ANSI_UNICODE_Struct_For_WOW' Ssync_ANSI_UNICODE_Struct_For_WOW comdlg32 126 +imp 'StartDocA' StartDocA gdi32 1921 +imp 'StartDoc' StartDocW gdi32 1922 +imp 'StartFormPage' StartFormPage gdi32 1923 +imp 'StartPage' StartPage gdi32 1924 +imp 'StartServiceA' StartServiceA advapi32 1761 +imp 'StartServiceCtrlDispatcherA' StartServiceCtrlDispatcherA advapi32 1762 +imp 'StartServiceCtrlDispatcher' StartServiceCtrlDispatcherW advapi32 1763 +imp 'StartService' StartServiceW advapi32 1764 +imp 'StartTraceA' StartTraceA advapi32 1765 +imp 'StartTrace' StartTraceW advapi32 1766 +imp 'StgMakeUniqueName' StgMakeUniqueName shell32 682 +imp 'StmAlignSize' StmAlignSize KernelBase 1596 +imp 'StmAllocateFlat' StmAllocateFlat KernelBase 1597 +imp 'StmCoalesceChunks' StmCoalesceChunks KernelBase 1598 +imp 'StmDeinitialize' StmDeinitialize KernelBase 1599 +imp 'StmInitialize' StmInitialize KernelBase 1600 +imp 'StmReduceSize' StmReduceSize KernelBase 1601 +imp 'StmReserve' StmReserve KernelBase 1602 +imp 'StmWrite' StmWrite KernelBase 1603 +imp 'StopTraceA' StopTraceA advapi32 1767 +imp 'StopTrace' StopTraceW advapi32 1768 +imp 'StrCSpnA' StrCSpnA KernelBase 1604 +imp 'StrCSpnIA' StrCSpnIA KernelBase 1605 +imp 'StrCSpnIW' StrCSpnIW KernelBase 1606 +imp 'StrCSpn' StrCSpnW KernelBase 1607 +imp 'StrCatBuffA' StrCatBuffA KernelBase 1608 +imp 'StrCatBuff' StrCatBuffW KernelBase 1609 +imp 'StrCatChain' StrCatChainW KernelBase 1610 +imp 'StrChrA' StrChrA KernelBase 1611 +imp 'StrChrA_MB' StrChrA_MB KernelBase 1612 +imp 'StrChrIA' StrChrIA KernelBase 1613 +imp 'StrChrIW' StrChrIW KernelBase 1614 +imp 'StrChrNIW' StrChrNIW KernelBase 1615 +imp 'StrChrNW' StrChrNW KernelBase 1616 +imp 'StrChr' StrChrW KernelBase 1617 +imp 'StrCmpCA' StrCmpCA KernelBase 1618 +imp 'StrCmpCW' StrCmpCW KernelBase 1619 +imp 'StrCmpICA' StrCmpICA KernelBase 1620 +imp 'StrCmpICW' StrCmpICW KernelBase 1621 +imp 'StrCmpIW' StrCmpIW KernelBase 1622 +imp 'StrCmpLogical' StrCmpLogicalW KernelBase 1623 +imp 'StrCmpNA' StrCmpNA KernelBase 1624 +imp 'StrCmpNCA' StrCmpNCA KernelBase 1625 +imp 'StrCmpNCW' StrCmpNCW KernelBase 1626 +imp 'StrCmpNIA' StrCmpNIA KernelBase 1627 +imp 'StrCmpNICA' StrCmpNICA KernelBase 1628 +imp 'StrCmpNICW' StrCmpNICW KernelBase 1629 +imp 'StrCmpNIW' StrCmpNIW KernelBase 1630 +imp 'StrCmpNW' StrCmpNW KernelBase 1631 +imp 'StrCmp' StrCmpW KernelBase 1632 +imp 'StrCpyNW' StrCpyNW KernelBase 1633 +imp 'StrCpyNXA' StrCpyNXA KernelBase 1634 +imp 'StrCpyNXW' StrCpyNXW KernelBase 1635 +imp 'StrDupA' StrDupA KernelBase 1636 +imp 'StrDup' StrDupW KernelBase 1637 +imp 'StrIsIntlEqualA' StrIsIntlEqualA KernelBase 1638 +imp 'StrIsIntlEqual' StrIsIntlEqualW KernelBase 1639 +imp 'StrNCmpA' StrNCmpA shell32 599 +imp 'StrNCmpIA' StrNCmpIA shell32 600 +imp 'StrNCmpIW' StrNCmpIW shell32 601 +imp 'StrNCmp' StrNCmpW shell32 602 +imp 'StrPBrkA' StrPBrkA KernelBase 1640 +imp 'StrPBrk' StrPBrkW KernelBase 1641 +imp 'StrRChrA' StrRChrA KernelBase 1642 +imp 'StrRChrIA' StrRChrIA KernelBase 1643 +imp 'StrRChrIW' StrRChrIW KernelBase 1644 +imp 'StrRChr' StrRChrW KernelBase 1645 +imp 'StrRStrA' StrRStrA shell32 607 +imp 'StrRStrIA' StrRStrIA KernelBase 1646 +imp 'StrRStrIW' StrRStrIW KernelBase 1647 +imp 'StrRStr' StrRStrW shell32 610 +imp 'StrSpnA' StrSpnA KernelBase 1648 +imp 'StrSpn' StrSpnW KernelBase 1649 +imp 'StrStrA' StrStrA KernelBase 1650 +imp 'StrStrIA' StrStrIA KernelBase 1651 +imp 'StrStrIW' StrStrIW KernelBase 1652 +imp 'StrStrNIW' StrStrNIW KernelBase 1653 +imp 'StrStrNW' StrStrNW KernelBase 1654 +imp 'StrStr' StrStrW KernelBase 1655 +imp 'StrToInt64ExA' StrToInt64ExA KernelBase 1656 +imp 'StrToInt64Ex' StrToInt64ExW KernelBase 1657 +imp 'StrToIntA' StrToIntA KernelBase 1658 +imp 'StrToIntExA' StrToIntExA KernelBase 1659 +imp 'StrToIntEx' StrToIntExW KernelBase 1660 +imp 'StrToInt' StrToIntW KernelBase 1661 +imp 'StrTrimA' StrTrimA KernelBase 1662 +imp 'StrTrim' StrTrimW KernelBase 1663 +imp 'StretchBlt' StretchBlt gdi32 1925 +imp 'StretchDIBits' StretchDIBits gdi32 1926 +imp 'StrokeAndFillPath' StrokeAndFillPath gdi32 1927 +imp 'StrokePath' StrokePath gdi32 1928 +imp 'SubscribeEdpEnabledStateChange' SubscribeEdpEnabledStateChange KernelBase 1665 +imp 'SubscribeStateChangeNotification' SubscribeStateChangeNotification KernelBase 1666 +imp 'SubtractRect' SubtractRect user32 2426 +imp 'SuspendThread' SuspendThread KernelBase 1667 +imp 'SwapBuffers' SwapBuffers gdi32 1929 +imp 'SwapMouseButton' SwapMouseButton user32 2427 +imp 'SwitchDesktop' SwitchDesktop user32 2428 +imp 'SwitchDesktopWithFade' SwitchDesktopWithFade user32 2429 +imp 'SwitchToFiber' SwitchToFiber KernelBase 1668 +imp 'SwitchToThisWindow' SwitchToThisWindow user32 2430 +imp 'SwitchToThread' SwitchToThread KernelBase 1669 +imp 'SystemFunction017' SystemFunction017 advapi32 1785 +imp 'SystemFunction019' SystemFunction019 advapi32 1787 +imp 'SystemParametersInfoA' SystemParametersInfoA user32 2431 +imp 'SystemParametersInfoForDpi' SystemParametersInfoForDpi user32 2432 +imp 'SystemParametersInfo' SystemParametersInfoW user32 2433 +imp 'SystemTimeToFileTime' SystemTimeToFileTime KernelBase 1670 2 +imp 'SystemTimeToTzSpecificLocalTime' SystemTimeToTzSpecificLocalTime KernelBase 1671 +imp 'SystemTimeToTzSpecificLocalTimeEx' SystemTimeToTzSpecificLocalTimeEx KernelBase 1672 +imp 'TabbedTextOutA' TabbedTextOutA user32 2434 +imp 'TabbedTextOut' TabbedTextOutW user32 2435 +imp 'TelnetProtocolHandler' TelnetProtocolHandler url 113 +imp 'TelnetProtocolHandlerA' TelnetProtocolHandlerA url 114 +imp 'TerminateEnclave' TerminateEnclave KernelBase 1673 +imp 'TerminateJobObject' TerminateJobObject kernel32 1426 +imp 'TerminateProcess' TerminateProcess KernelBase 1674 2 +imp 'TerminateProcessOnMemoryExhaustion' TerminateProcessOnMemoryExhaustion KernelBase 1675 +imp 'TerminateThread' TerminateThread KernelBase 1676 +imp 'TermsrvAppInstallMode' TermsrvAppInstallMode kernel32 1429 +imp 'TermsrvConvertSysRootToUserDir' TermsrvConvertSysRootToUserDir kernel32 1430 +imp 'TermsrvCreateRegEntry' TermsrvCreateRegEntry kernel32 1431 +imp 'TermsrvDeleteKey' TermsrvDeleteKey kernel32 1432 +imp 'TermsrvDeleteValue' TermsrvDeleteValue kernel32 1433 +imp 'TermsrvGetPreSetValue' TermsrvGetPreSetValue kernel32 1434 +imp 'TermsrvGetWindowsDirectoryA' TermsrvGetWindowsDirectoryA kernel32 1435 +imp 'TermsrvGetWindowsDirectory' TermsrvGetWindowsDirectoryW kernel32 1436 +imp 'TermsrvOpenRegEntry' TermsrvOpenRegEntry kernel32 1437 +imp 'TermsrvOpenUserClasses' TermsrvOpenUserClasses kernel32 1438 +imp 'TermsrvRestoreKey' TermsrvRestoreKey kernel32 1439 +imp 'TermsrvSetKeySecurity' TermsrvSetKeySecurity kernel32 1440 +imp 'TermsrvSetValueKey' TermsrvSetValueKey kernel32 1441 +imp 'TermsrvSyncUserIniFileExt' TermsrvSyncUserIniFileExt kernel32 1442 +imp 'TextOutA' TextOutA gdi32 1930 +imp 'TextOut' TextOutW gdi32 1931 +imp 'Thread32First' Thread32First kernel32 1443 +imp 'Thread32Next' Thread32Next kernel32 1444 +imp 'TileChildWindows' TileChildWindows user32 2436 +imp 'TileWindows' TileWindows user32 2437 +imp 'TlsAlloc' TlsAlloc KernelBase 1677 +imp 'TlsFree' TlsFree KernelBase 1678 +imp 'TlsGetValue' TlsGetValue KernelBase 1679 +imp 'TlsSetValue' TlsSetValue KernelBase 1680 +imp 'ToAscii' ToAscii user32 2438 +imp 'ToAsciiEx' ToAsciiEx user32 2439 +imp 'ToUnicode' ToUnicode user32 2440 +imp 'ToUnicodeEx' ToUnicodeEx user32 2441 +imp 'Toolhelp32ReadProcessMemory' Toolhelp32ReadProcessMemory kernel32 1449 +imp 'TpAllocAlpcCompletion' TpAllocAlpcCompletion ntdll 1616 +imp 'TpAllocAlpcCompletionEx' TpAllocAlpcCompletionEx ntdll 1617 +imp 'TpAllocCleanupGroup' TpAllocCleanupGroup ntdll 1618 +imp 'TpAllocIoCompletion' TpAllocIoCompletion ntdll 1619 +imp 'TpAllocJobNotification' TpAllocJobNotification ntdll 1620 +imp 'TpAllocPool' TpAllocPool ntdll 1621 +imp 'TpAllocTimer' TpAllocTimer ntdll 1622 +imp 'TpAllocWait' TpAllocWait ntdll 1623 +imp 'TpAllocWork' TpAllocWork ntdll 1624 +imp 'TpAlpcRegisterCompletionList' TpAlpcRegisterCompletionList ntdll 1625 +imp 'TpAlpcUnregisterCompletionList' TpAlpcUnregisterCompletionList ntdll 1626 +imp 'TpCallbackDetectedUnrecoverableError' TpCallbackDetectedUnrecoverableError ntdll 1627 +imp 'TpCallbackIndependent' TpCallbackIndependent ntdll 1628 +imp 'TpCallbackLeaveCriticalSectionOnCompletion' TpCallbackLeaveCriticalSectionOnCompletion ntdll 1629 +imp 'TpCallbackMayRunLong' TpCallbackMayRunLong ntdll 1630 +imp 'TpCallbackReleaseMutexOnCompletion' TpCallbackReleaseMutexOnCompletion ntdll 1631 +imp 'TpCallbackReleaseSemaphoreOnCompletion' TpCallbackReleaseSemaphoreOnCompletion ntdll 1632 +imp 'TpCallbackSendAlpcMessageOnCompletion' TpCallbackSendAlpcMessageOnCompletion ntdll 1633 +imp 'TpCallbackSendPendingAlpcMessage' TpCallbackSendPendingAlpcMessage ntdll 1634 +imp 'TpCallbackSetEventOnCompletion' TpCallbackSetEventOnCompletion ntdll 1635 +imp 'TpCallbackUnloadDllOnCompletion' TpCallbackUnloadDllOnCompletion ntdll 1636 +imp 'TpCancelAsyncIoOperation' TpCancelAsyncIoOperation ntdll 1637 +imp 'TpCaptureCaller' TpCaptureCaller ntdll 1638 +imp 'TpCheckTerminateWorker' TpCheckTerminateWorker ntdll 1639 +imp 'TpDbgDumpHeapUsage' TpDbgDumpHeapUsage ntdll 1640 +imp 'TpDbgSetLogRoutine' TpDbgSetLogRoutine ntdll 1641 +imp 'TpDisablePoolCallbackChecks' TpDisablePoolCallbackChecks ntdll 1642 +imp 'TpDisassociateCallback' TpDisassociateCallback ntdll 1643 +imp 'TpIsTimerSet' TpIsTimerSet ntdll 1644 +imp 'TpPostWork' TpPostWork ntdll 1645 +imp 'TpQueryPoolStackInformation' TpQueryPoolStackInformation ntdll 1646 +imp 'TpReleaseAlpcCompletion' TpReleaseAlpcCompletion ntdll 1647 +imp 'TpReleaseCleanupGroup' TpReleaseCleanupGroup ntdll 1648 +imp 'TpReleaseCleanupGroupMembers' TpReleaseCleanupGroupMembers ntdll 1649 +imp 'TpReleaseIoCompletion' TpReleaseIoCompletion ntdll 1650 +imp 'TpReleaseJobNotification' TpReleaseJobNotification ntdll 1651 +imp 'TpReleasePool' TpReleasePool ntdll 1652 +imp 'TpReleaseTimer' TpReleaseTimer ntdll 1653 +imp 'TpReleaseWait' TpReleaseWait ntdll 1654 +imp 'TpReleaseWork' TpReleaseWork ntdll 1655 +imp 'TpSetDefaultPoolMaxThreads' TpSetDefaultPoolMaxThreads ntdll 1656 +imp 'TpSetDefaultPoolStackInformation' TpSetDefaultPoolStackInformation ntdll 1657 +imp 'TpSetPoolMaxThreads' TpSetPoolMaxThreads ntdll 1658 +imp 'TpSetPoolMaxThreadsSoftLimit' TpSetPoolMaxThreadsSoftLimit ntdll 1659 +imp 'TpSetPoolMinThreads' TpSetPoolMinThreads ntdll 1660 +imp 'TpSetPoolStackInformation' TpSetPoolStackInformation ntdll 1661 +imp 'TpSetPoolThreadBasePriority' TpSetPoolThreadBasePriority ntdll 1662 +imp 'TpSetPoolWorkerThreadIdleTimeout' TpSetPoolWorkerThreadIdleTimeout ntdll 1663 +imp 'TpSetTimer' TpSetTimer ntdll 1664 +imp 'TpSetTimerEx' TpSetTimerEx ntdll 1665 +imp 'TpSetWait' TpSetWait ntdll 1666 +imp 'TpSetWaitEx' TpSetWaitEx ntdll 1667 +imp 'TpSimpleTryPost' TpSimpleTryPost ntdll 1668 +imp 'TpStartAsyncIoOperation' TpStartAsyncIoOperation ntdll 1669 +imp 'TpTimerOutstandingCallbackCount' TpTimerOutstandingCallbackCount ntdll 1670 +imp 'TpTrimPools' TpTrimPools ntdll 1671 +imp 'TpWaitForAlpcCompletion' TpWaitForAlpcCompletion ntdll 1672 +imp 'TpWaitForIoCompletion' TpWaitForIoCompletion ntdll 1673 +imp 'TpWaitForJobNotification' TpWaitForJobNotification ntdll 1674 +imp 'TpWaitForTimer' TpWaitForTimer ntdll 1675 +imp 'TpWaitForWait' TpWaitForWait ntdll 1676 +imp 'TpWaitForWork' TpWaitForWork ntdll 1677 +imp 'TraceSetInformation' TraceSetInformation advapi32 1812 +imp 'TrackMouseEvent' TrackMouseEvent user32 2442 +imp 'TrackPopupMenu' TrackPopupMenu user32 2443 +imp 'TrackPopupMenuEx' TrackPopupMenuEx user32 2444 +imp 'TransactNamedPipe' TransactNamedPipe KernelBase 1684 7 +imp 'TranslateAcceleratorA' TranslateAcceleratorA user32 2446 +imp 'TranslateAccelerator' TranslateAcceleratorW user32 2447 +imp 'TranslateCharsetInfo' TranslateCharsetInfo gdi32 1932 +imp 'TranslateMDISysAccel' TranslateMDISysAccel user32 2448 +imp 'TranslateMessage' TranslateMessage user32 2449 1 +imp 'TranslateMessageEx' TranslateMessageEx user32 2450 +imp 'TranslateURLA' TranslateURLA url 115 +imp 'TranslateURLW' TranslateURLW url 116 +imp 'TransmitFile' TransmitFile MsWSock 53 7 +imp 'TransmitCommChar' TransmitCommChar KernelBase 1685 +imp 'TreeResetNamedSecurityInfoA' TreeResetNamedSecurityInfoA advapi32 1813 +imp 'TreeResetNamedSecurityInfo' TreeResetNamedSecurityInfoW advapi32 1814 +imp 'TreeSetNamedSecurityInfoA' TreeSetNamedSecurityInfoA advapi32 1815 +imp 'TreeSetNamedSecurityInfo' TreeSetNamedSecurityInfoW advapi32 1816 +imp 'TrusteeAccessToObjectA' TrusteeAccessToObjectA advapi32 1817 +imp 'TrusteeAccessToObject' TrusteeAccessToObjectW advapi32 1818 +imp 'TrySubmitThreadpoolCallback' TrySubmitThreadpoolCallback KernelBase 1689 +imp 'TzSpecificLocalTimeToSystemTime' TzSpecificLocalTimeToSystemTime KernelBase 1690 +imp 'TzSpecificLocalTimeToSystemTimeEx' TzSpecificLocalTimeToSystemTimeEx KernelBase 1691 +imp 'URLAssociationDialogA' URLAssociationDialogA url 117 +imp 'URLAssociationDialog' URLAssociationDialogW url 118 +imp 'UTRegister' UTRegister kernel32 1458 +imp 'UTUnRegister' UTUnRegister kernel32 1459 +imp 'UmsThreadYield' UmsThreadYield kernel32 1460 +imp 'UndelegateInput' UndelegateInput user32 2504 +imp 'UnhandledExceptionFilter' UnhandledExceptionFilter KernelBase 1692 +imp 'UnhookWinEvent' UnhookWinEvent user32 2451 +imp 'UnhookWindowsHook' UnhookWindowsHook user32 2452 2 +imp 'UnhookWindowsHookEx' UnhookWindowsHookEx user32 2453 1 +imp 'UninstallApplication' UninstallApplication advapi32 1819 +imp 'UnionRect' UnionRect user32 2454 +imp 'UnloadKeyboardLayout' UnloadKeyboardLayout user32 2455 +imp 'UnloadNetworkFonts' UnloadNetworkFonts gdi32 1933 +imp 'UnlockFile' UnlockFile KernelBase 1693 5 +imp 'UnlockFileEx' UnlockFileEx KernelBase 1694 5 +imp 'UnlockServiceDatabase' UnlockServiceDatabase advapi32 1820 +imp 'UnlockWindowStation' UnlockWindowStation user32 2456 +imp 'UnmapViewOfFile' UnmapViewOfFile KernelBase 1695 1 +imp 'UnmapViewOfFile2' UnmapViewOfFile2 KernelBase 1696 +imp 'UnmapViewOfFileEx' UnmapViewOfFileEx KernelBase 1697 +imp 'UnpackDDElParam' UnpackDDElParam user32 2457 +imp 'UnrealizeObject' UnrealizeObject gdi32 1934 +imp 'UnregisterApplicationRecoveryCallback' UnregisterApplicationRecoveryCallback kernel32 1466 +imp 'UnregisterApplicationRestart' UnregisterApplicationRestart kernel32 1467 +imp 'UnregisterBadMemoryNotification' UnregisterBadMemoryNotification KernelBase 1698 +imp 'UnregisterClassA' UnregisterClassA user32 2458 +imp 'UnregisterClass' UnregisterClassW user32 2459 +imp 'UnregisterConsoleIME' UnregisterConsoleIME kernel32 1469 +imp 'UnregisterDeviceNotification' UnregisterDeviceNotification user32 2460 +imp 'UnregisterGPNotificationInternal' UnregisterGPNotificationInternal KernelBase 1699 +imp 'UnregisterHotKey' UnregisterHotKey user32 2461 +imp 'UnregisterIdleTask' UnregisterIdleTask advapi32 1821 +imp 'UnregisterMessagePumpHook' UnregisterMessagePumpHook user32 2462 +imp 'UnregisterPointerInputTarget' UnregisterPointerInputTarget user32 2463 +imp 'UnregisterPointerInputTargetEx' UnregisterPointerInputTargetEx user32 2464 +imp 'UnregisterPowerSettingNotification' UnregisterPowerSettingNotification user32 2465 +imp 'UnregisterSessionPort' UnregisterSessionPort user32 2466 +imp 'UnregisterStateChangeNotification' UnregisterStateChangeNotification KernelBase 1700 +imp 'UnregisterStateLock' UnregisterStateLock KernelBase 1701 +imp 'UnregisterSuspendResumeNotification' UnregisterSuspendResumeNotification user32 2467 +imp 'UnregisterTouchWindow' UnregisterTouchWindow user32 2468 +imp 'UnregisterUserApiHook' UnregisterUserApiHook user32 2469 +imp 'UnregisterWait' UnregisterWait kernel32 1470 +imp 'UnregisterWaitEx' UnregisterWaitEx KernelBase 1703 +imp 'UnregisterWaitUntilOOBECompleted' UnregisterWaitUntilOOBECompleted kernel32 1472 +imp 'UnsubscribeEdpEnabledStateChange' UnsubscribeEdpEnabledStateChange KernelBase 1704 +imp 'UnsubscribeStateChangeNotification' UnsubscribeStateChangeNotification KernelBase 1705 +imp 'UpdateCalendarDayOfWeek' UpdateCalendarDayOfWeek kernel32 1473 +imp 'UpdateColors' UpdateColors gdi32 1935 +imp 'UpdateDefaultDesktopThumbnail' UpdateDefaultDesktopThumbnail user32 2470 +imp 'UpdateICMRegKeyA' UpdateICMRegKeyA gdi32 1936 +imp 'UpdateICMRegKey' UpdateICMRegKeyW gdi32 1937 +imp 'UpdateLayeredWindow' UpdateLayeredWindow user32 2471 +imp 'UpdateLayeredWindowIndirect' UpdateLayeredWindowIndirect user32 2472 +imp 'UpdatePackageStatus' UpdatePackageStatus KernelBase 1706 +imp 'UpdatePackageStatusForUser' UpdatePackageStatusForUser KernelBase 1707 +imp 'UpdatePackageStatusForUserSid' UpdatePackageStatusForUserSid KernelBase 1708 +imp 'UpdatePerUserSystemParameters' UpdatePerUserSystemParameters user32 2473 +imp 'UpdateProcThreadAttribute' UpdateProcThreadAttribute KernelBase 1709 7 +imp 'UpdateResourceA' UpdateResourceA kernel32 1475 +imp 'UpdateResource' UpdateResourceW kernel32 1476 +imp 'UpdateTraceA' UpdateTraceA advapi32 1823 +imp 'UpdateTrace' UpdateTraceW advapi32 1824 +imp 'UpdateWindow' UpdateWindow user32 2474 +imp 'UpdateWindowInputSinkHints' UpdateWindowInputSinkHints user32 2475 +imp 'UrlApplySchemeA' UrlApplySchemeA KernelBase 1710 +imp 'UrlApplyScheme' UrlApplySchemeW KernelBase 1711 +imp 'UrlCanonicalizeA' UrlCanonicalizeA KernelBase 1712 +imp 'UrlCanonicalize' UrlCanonicalizeW KernelBase 1713 +imp 'UrlCombineA' UrlCombineA KernelBase 1714 +imp 'UrlCombine' UrlCombineW KernelBase 1715 +imp 'UrlCompareA' UrlCompareA KernelBase 1716 +imp 'UrlCompare' UrlCompareW KernelBase 1717 +imp 'UrlCreateFromPathA' UrlCreateFromPathA KernelBase 1718 +imp 'UrlCreateFromPath' UrlCreateFromPathW KernelBase 1719 +imp 'UrlEscapeA' UrlEscapeA KernelBase 1720 +imp 'UrlEscape' UrlEscapeW KernelBase 1721 +imp 'UrlFixup' UrlFixupW KernelBase 1722 +imp 'UrlGetLocationA' UrlGetLocationA KernelBase 1723 +imp 'UrlGetLocation' UrlGetLocationW KernelBase 1724 +imp 'UrlGetPartA' UrlGetPartA KernelBase 1725 +imp 'UrlGetPart' UrlGetPartW KernelBase 1726 +imp 'UrlHashA' UrlHashA KernelBase 1727 +imp 'UrlHash' UrlHashW KernelBase 1728 +imp 'UrlIsA' UrlIsA KernelBase 1729 +imp 'UrlIsNoHistoryA' UrlIsNoHistoryA KernelBase 1730 +imp 'UrlIsNoHistory' UrlIsNoHistoryW KernelBase 1731 +imp 'UrlIsOpaqueA' UrlIsOpaqueA KernelBase 1732 +imp 'UrlIsOpaque' UrlIsOpaqueW KernelBase 1733 +imp 'UrlIs' UrlIsW KernelBase 1734 +imp 'UrlUnescapeA' UrlUnescapeA KernelBase 1735 +imp 'UrlUnescape' UrlUnescapeW KernelBase 1736 +imp 'UsePinForEncryptedFilesA' UsePinForEncryptedFilesA advapi32 1825 +imp 'UsePinForEncryptedFiles' UsePinForEncryptedFilesW advapi32 1826 +imp 'User32InitializeImmEntryTable' User32InitializeImmEntryTable user32 2476 +imp 'UserClientDllInitialize' UserClientDllInitialize user32 2477 +imp 'UserHandleGrantAccess' UserHandleGrantAccess user32 2478 +imp 'UserLpkPSMTextOut' UserLpkPSMTextOut user32 2479 +imp 'UserLpkTabbedTextOut' UserLpkTabbedTextOut user32 2480 +imp 'UserRealizePalette' UserRealizePalette user32 2481 +imp 'UserRegisterWowHandlers' UserRegisterWowHandlers user32 2482 +imp 'UsersLibrariesFolderUI_CreateInstance' UsersLibrariesFolderUI_CreateInstance shell32 615 +imp 'VDMConsoleOperation' VDMConsoleOperation kernel32 1477 +imp 'VDMOperationStarted' VDMOperationStarted kernel32 1478 +imp 'VRipOutput' VRipOutput user32 2483 +imp 'VTagOutput' VTagOutput user32 2484 +imp 'ValidateRect' ValidateRect user32 2485 +imp 'ValidateRgn' ValidateRgn user32 2486 +imp 'VerFindFileA' VerFindFileA KernelBase 1737 +imp 'VerFindFile' VerFindFileW KernelBase 1738 +imp 'VerLanguageNameA' VerLanguageNameA KernelBase 1739 +imp 'VerLanguageName' VerLanguageNameW KernelBase 1740 +imp 'VerQueryValueA' VerQueryValueA KernelBase 1741 +imp 'VerQueryValue' VerQueryValueW KernelBase 1742 +imp 'VerSetConditionMask' VerSetConditionMask ntdll 1678 +imp 'VerifyApplicationUserModelId' VerifyApplicationUserModelId KernelBase 1744 +imp 'VerifyApplicationUserModelIdA' VerifyApplicationUserModelIdA KernelBase 1745 +imp 'VerifyConsoleIoHandle' VerifyConsoleIoHandle kernel32 1482 +imp 'VerifyPackageFamilyName' VerifyPackageFamilyName KernelBase 1746 +imp 'VerifyPackageFamilyNameA' VerifyPackageFamilyNameA KernelBase 1747 +imp 'VerifyPackageFullName' VerifyPackageFullName KernelBase 1748 +imp 'VerifyPackageFullNameA' VerifyPackageFullNameA KernelBase 1749 +imp 'VerifyPackageId' VerifyPackageId KernelBase 1750 +imp 'VerifyPackageIdA' VerifyPackageIdA KernelBase 1751 +imp 'VerifyPackageRelativeApplicationId' VerifyPackageRelativeApplicationId KernelBase 1752 +imp 'VerifyPackageRelativeApplicationIdA' VerifyPackageRelativeApplicationIdA KernelBase 1753 +imp 'VerifyScripts' VerifyScripts KernelBase 1754 +imp 'VerifyVersionInfoA' VerifyVersionInfoA kernel32 1484 +imp 'VerifyVersionInfo' VerifyVersionInfoW kernel32 1485 +imp 'VirtualAlloc' VirtualAlloc KernelBase 1755 4 +imp 'VirtualAlloc2' VirtualAlloc2 KernelBase 1756 +imp 'VirtualAlloc2FromApp' VirtualAlloc2FromApp KernelBase 1757 +imp 'VirtualAllocEx' VirtualAllocEx KernelBase 1758 5 +imp 'VirtualAllocExNuma' VirtualAllocExNuma KernelBase 1759 +imp 'VirtualAllocFromApp' VirtualAllocFromApp KernelBase 1760 +imp 'VirtualFree' VirtualFree KernelBase 1761 3 +imp 'VirtualFreeEx' VirtualFreeEx KernelBase 1762 +imp 'VirtualLock' VirtualLock KernelBase 1763 +imp 'VirtualProtect' VirtualProtect KernelBase 1764 4 +imp 'VirtualProtectEx' VirtualProtectEx KernelBase 1765 +imp 'VirtualProtectFromApp' VirtualProtectFromApp KernelBase 1766 +imp 'VirtualQuery' VirtualQuery KernelBase 1767 3 +imp 'VirtualQueryEx' VirtualQueryEx KernelBase 1768 +imp 'VirtualUnlock' VirtualUnlock KernelBase 1769 +imp 'VirtualUnlockEx' VirtualUnlockEx KernelBase 1770 +imp 'VkKeyScanA' VkKeyScanA user32 2487 +imp 'VkKeyScanExA' VkKeyScanExA user32 2488 +imp 'VkKeyScanEx' VkKeyScanExW user32 2489 +imp 'VkKeyScan' VkKeyScanW user32 2490 +imp 'WCSToMBEx' WCSToMBEx user32 2491 +imp 'WEP' WEP ws2_32 500 +imp 'WINNLSEnableIME' WINNLSEnableIME user32 2492 +imp 'WINNLSGetEnableStatus' WINNLSGetEnableStatus user32 2493 +imp 'WINNLSGetIMEHotkey' WINNLSGetIMEHotkey user32 2494 +imp 'WOWShellExecute' WOWShellExecute shell32 616 +imp 'WPUCompleteOverlappedRequest' WPUCompleteOverlappedRequest ws2_32 39 +imp 'WPUGetProviderPathEx' WPUGetProviderPathEx ws2_32 40 +imp 'WSAAccept' WSAAccept ws2_32 41 5 +imp 'WSAAddressToString' WSAAddressToStringW ws2_32 43 5 +imp 'WSAAddressToStringA' WSAAddressToStringA ws2_32 42 5 +imp 'WSAAdvertiseProvider' WSAAdvertiseProvider ws2_32 44 +imp 'WSAAsyncGetHostByAddr' WSAAsyncGetHostByAddr ws2_32 102 +imp 'WSAAsyncGetHostByName' WSAAsyncGetHostByName ws2_32 103 +imp 'WSAAsyncGetProtoByName' WSAAsyncGetProtoByName ws2_32 105 +imp 'WSAAsyncGetProtoByNumber' WSAAsyncGetProtoByNumber ws2_32 104 +imp 'WSAAsyncGetServByName' WSAAsyncGetServByName ws2_32 107 +imp 'WSAAsyncGetServByPort' WSAAsyncGetServByPort ws2_32 106 +imp 'WSAAsyncSelect' WSAAsyncSelect ws2_32 101 +imp 'WSACancelAsyncRequest' WSACancelAsyncRequest ws2_32 108 +imp 'WSACancelBlockingCall' WSACancelBlockingCall ws2_32 113 +imp 'WSACleanup' WSACleanup ws2_32 116 0 +imp 'WSACloseEvent' WSACloseEvent ws2_32 45 1 +imp 'WSAConnect' WSAConnect ws2_32 46 7 +imp 'WSAConnectByList' WSAConnectByList ws2_32 47 8 +imp 'WSAConnectByName' WSAConnectByNameW ws2_32 49 9 +imp 'WSAConnectByNameA' WSAConnectByNameA ws2_32 48 9 +imp 'WSACreateEvent' WSACreateEvent ws2_32 50 0 +imp 'WSADuplicateSocket' WSADuplicateSocketW ws2_32 59 3 +imp 'WSADuplicateSocketA' WSADuplicateSocketA ws2_32 58 3 +imp 'WSAEnumNameSpaceProvidersEx' WSAEnumNameSpaceProvidersExW ws2_32 62 2 +imp 'WSAEnumNameSpaceProvidersExA' WSAEnumNameSpaceProvidersExA ws2_32 61 2 +imp 'WSAEnumNameSpaceProviders' WSAEnumNameSpaceProvidersW ws2_32 63 +imp 'WSAEnumNameSpaceProvidersA' WSAEnumNameSpaceProvidersA ws2_32 60 +imp 'WSAEnumNetworkEvents' WSAEnumNetworkEvents ws2_32 64 3 +imp 'WSAEnumProtocols' WSAEnumProtocolsW ws2_32 66 3 +imp 'WSAEnumProtocolsA' WSAEnumProtocolsA ws2_32 65 3 +imp 'WSAEventSelect' WSAEventSelect ws2_32 67 3 +imp 'WSAGetLastError' WSAGetLastError ws2_32 111 0 +imp 'WSAGetOverlappedResult' WSAGetOverlappedResult ws2_32 68 5 +imp 'WSAGetQOSByName' WSAGetQOSByName ws2_32 69 3 +imp 'WSAGetServiceClassInfo' WSAGetServiceClassInfoW ws2_32 71 4 +imp 'WSAGetServiceClassInfoA' WSAGetServiceClassInfoA ws2_32 70 4 +imp 'WSAGetServiceClassNameByClassId' WSAGetServiceClassNameByClassIdW ws2_32 73 3 +imp 'WSAGetServiceClassNameByClassIdA' WSAGetServiceClassNameByClassIdA ws2_32 72 3 +imp 'WSAHtonl' WSAHtonl ws2_32 74 +imp 'WSAHtons' WSAHtons ws2_32 75 +imp 'WSAInstallServiceClass' WSAInstallServiceClassW ws2_32 77 1 +imp 'WSAInstallServiceClassA' WSAInstallServiceClassA ws2_32 76 1 +imp 'WSAIoctl' WSAIoctl ws2_32 78 9 +imp 'WSAIsBlocking' WSAIsBlocking ws2_32 114 +imp 'WSAJoinLeaf' WSAJoinLeaf ws2_32 79 8 +imp 'WSALookupServiceBegin' WSALookupServiceBeginW ws2_32 81 3 +imp 'WSALookupServiceBeginA' WSALookupServiceBeginA ws2_32 80 3 +imp 'WSALookupServiceEnd' WSALookupServiceEnd ws2_32 82 1 +imp 'WSALookupServiceNext' WSALookupServiceNextW ws2_32 84 4 +imp 'WSALookupServiceNextA' WSALookupServiceNextA ws2_32 83 4 +imp 'WSANSPIoctl' WSANSPIoctl ws2_32 85 8 +imp 'WSANtohl' WSANtohl ws2_32 86 +imp 'WSANtohs' WSANtohs ws2_32 87 +imp 'WSAPoll' WSAPoll ws2_32 88 3 +imp 'WSAProviderCompleteAsyncCall' WSAProviderCompleteAsyncCall ws2_32 89 +imp 'WSAProviderConfigChange' WSAProviderConfigChange ws2_32 90 3 +imp 'WSARecv' WSARecv ws2_32 91 7 +imp 'WSARecvDisconnect' WSARecvDisconnect ws2_32 92 2 +imp 'WSARecvFrom' WSARecvFrom ws2_32 93 9 +imp 'WSARecvEx' WSARecvEx MsWSock 54 +imp 'WSARemoveServiceClass' WSARemoveServiceClass ws2_32 94 1 +imp 'WSAResetEvent' WSAResetEvent ws2_32 95 1 +imp 'WSASend' WSASend ws2_32 96 7 +imp 'WSASendDisconnect' WSASendDisconnect ws2_32 97 +imp 'WSASendMsg' WSASendMsg ws2_32 98 6 +imp 'WSASendTo' WSASendTo ws2_32 99 9 +imp 'WSASetBlockingHook' WSASetBlockingHook ws2_32 109 +imp 'WSASetEvent' WSASetEvent ws2_32 100 1 +imp 'WSASetLastError' WSASetLastError ws2_32 112 1 +imp 'WSASetService' WSASetServiceW ws2_32 118 3 +imp 'WSASetServiceA' WSASetServiceA ws2_32 117 3 +imp 'WSASocket' WSASocketW ws2_32 120 6 +imp 'WSASocketA' WSASocketA ws2_32 119 6 +imp 'WSAStartup' WSAStartup ws2_32 115 2 +imp 'WSAStringToAddressA' WSAStringToAddressA ws2_32 121 5 +imp 'WSAStringToAddress' WSAStringToAddressW ws2_32 122 +imp 'WSAUnadvertiseProvider' WSAUnadvertiseProvider ws2_32 123 +imp 'WSAUnhookBlockingHook' WSAUnhookBlockingHook ws2_32 110 +imp 'WSAWaitForMultipleEvents' WSAWaitForMultipleEvents ws2_32 124 5 +imp 'WSApSetPostRoutine' WSApSetPostRoutine ws2_32 24 +imp 'WSCDeinstallProvider' WSCDeinstallProvider ws2_32 125 +imp 'WSCDeinstallProvider32' WSCDeinstallProvider32 ws2_32 126 +imp 'WSCDeinstallProviderEx' WSCDeinstallProviderEx ws2_32 127 +imp 'WSCEnableNSProvider' WSCEnableNSProvider ws2_32 128 +imp 'WSCEnableNSProvider32' WSCEnableNSProvider32 ws2_32 129 +imp 'WSCEnumNameSpaceProviders32' WSCEnumNameSpaceProviders32 ws2_32 130 +imp 'WSCEnumNameSpaceProvidersEx32' WSCEnumNameSpaceProvidersEx32 ws2_32 131 +imp 'WSCEnumProtocols' WSCEnumProtocols ws2_32 132 +imp 'WSCEnumProtocols32' WSCEnumProtocols32 ws2_32 133 +imp 'WSCEnumProtocolsEx' WSCEnumProtocolsEx ws2_32 134 +imp 'WSCGetApplicationCategory' WSCGetApplicationCategory ws2_32 135 +imp 'WSCGetApplicationCategoryEx' WSCGetApplicationCategoryEx ws2_32 136 +imp 'WSCGetProviderInfo' WSCGetProviderInfo ws2_32 137 +imp 'WSCGetProviderInfo32' WSCGetProviderInfo32 ws2_32 138 +imp 'WSCGetProviderPath' WSCGetProviderPath ws2_32 139 +imp 'WSCGetProviderPath32' WSCGetProviderPath32 ws2_32 140 +imp 'WSCInstallNameSpace' WSCInstallNameSpace ws2_32 141 +imp 'WSCInstallNameSpace32' WSCInstallNameSpace32 ws2_32 142 +imp 'WSCInstallNameSpaceEx' WSCInstallNameSpaceEx ws2_32 143 +imp 'WSCInstallNameSpaceEx2' WSCInstallNameSpaceEx2 ws2_32 144 +imp 'WSCInstallNameSpaceEx32' WSCInstallNameSpaceEx32 ws2_32 145 +imp 'WSCInstallProvider' WSCInstallProvider ws2_32 146 +imp 'WSCInstallProvider64_32' WSCInstallProvider64_32 ws2_32 147 +imp 'WSCInstallProviderAndChains64_32' WSCInstallProviderAndChains64_32 ws2_32 148 +imp 'WSCInstallProviderEx' WSCInstallProviderEx ws2_32 149 +imp 'WSCSetApplicationCategory' WSCSetApplicationCategory ws2_32 150 +imp 'WSCSetApplicationCategoryEx' WSCSetApplicationCategoryEx ws2_32 152 +imp 'WSCSetProviderInfo' WSCSetProviderInfo ws2_32 153 +imp 'WSCSetProviderInfo32' WSCSetProviderInfo32 ws2_32 154 +imp 'WSCUnInstallNameSpace' WSCUnInstallNameSpace ws2_32 155 +imp 'WSCUnInstallNameSpace32' WSCUnInstallNameSpace32 ws2_32 156 +imp 'WSCUnInstallNameSpaceEx2' WSCUnInstallNameSpaceEx2 ws2_32 157 +imp 'WSCUpdateProvider' WSCUpdateProvider ws2_32 158 +imp 'WSCUpdateProvider32' WSCUpdateProvider32 ws2_32 159 +imp 'WSCUpdateProviderEx' WSCUpdateProviderEx ws2_32 160 +imp 'WSCWriteNameSpaceOrder' WSCWriteNameSpaceOrder ws2_32 161 +imp 'WSCWriteNameSpaceOrder32' WSCWriteNameSpaceOrder32 ws2_32 162 +imp 'WSCWriteProviderOrder' WSCWriteProviderOrder ws2_32 163 +imp 'WSCWriteProviderOrder32' WSCWriteProviderOrder32 ws2_32 164 +imp 'WSCWriteProviderOrderEx' WSCWriteProviderOrderEx ws2_32 165 +imp 'WTSGetActiveConsoleSessionId' WTSGetActiveConsoleSessionId kernel32 1497 +imp 'WTSGetServiceSessionId' WTSGetServiceSessionId KernelBase 1771 +imp 'WTSIsServerContainer' WTSIsServerContainer KernelBase 1772 +imp 'WahCloseApcHelper' WahCloseApcHelper ws2_32 166 +imp 'WahCloseHandleHelper' WahCloseHandleHelper ws2_32 167 +imp 'WahCloseNotificationHandleHelper' WahCloseNotificationHandleHelper ws2_32 168 +imp 'WahCloseSocketHandle' WahCloseSocketHandle ws2_32 169 +imp 'WahCloseThread' WahCloseThread ws2_32 170 +imp 'WahCompleteRequest' WahCompleteRequest ws2_32 171 +imp 'WahCreateHandleContextTable' WahCreateHandleContextTable ws2_32 172 +imp 'WahCreateNotificationHandle' WahCreateNotificationHandle ws2_32 173 +imp 'WahCreateSocketHandle' WahCreateSocketHandle ws2_32 174 +imp 'WahDestroyHandleContextTable' WahDestroyHandleContextTable ws2_32 175 +imp 'WahDisableNonIFSHandleSupport' WahDisableNonIFSHandleSupport ws2_32 176 +imp 'WahEnableNonIFSHandleSupport' WahEnableNonIFSHandleSupport ws2_32 177 +imp 'WahEnumerateHandleContexts' WahEnumerateHandleContexts ws2_32 178 +imp 'WahInsertHandleContext' WahInsertHandleContext ws2_32 179 +imp 'WahNotifyAllProcesses' WahNotifyAllProcesses ws2_32 180 +imp 'WahOpenApcHelper' WahOpenApcHelper ws2_32 181 +imp 'WahOpenCurrentThread' WahOpenCurrentThread ws2_32 182 +imp 'WahOpenHandleHelper' WahOpenHandleHelper ws2_32 183 +imp 'WahOpenNotificationHandleHelper' WahOpenNotificationHandleHelper ws2_32 184 +imp 'WahQueueUserApc' WahQueueUserApc ws2_32 185 +imp 'WahReferenceContextByHandle' WahReferenceContextByHandle ws2_32 186 +imp 'WahRemoveHandleContext' WahRemoveHandleContext ws2_32 187 +imp 'WahWaitForNotification' WahWaitForNotification ws2_32 188 +imp 'WahWriteLSPEvent' WahWriteLSPEvent ws2_32 189 +imp 'WaitCommEvent' WaitCommEvent KernelBase 1773 +imp 'WaitForDebugEvent' WaitForDebugEvent KernelBase 1774 +imp 'WaitForDebugEventEx' WaitForDebugEventEx KernelBase 1775 +imp 'WaitForExplorerRestart' WaitForExplorerRestartW shell32 617 +imp 'WaitForInputIdle' WaitForInputIdle user32 2495 2 +imp 'WaitForMachinePolicyForegroundProcessingInternal' WaitForMachinePolicyForegroundProcessingInternal KernelBase 1776 +imp 'WaitForMultipleObjects' WaitForMultipleObjects KernelBase 1777 4 +imp 'WaitForMultipleObjectsEx' WaitForMultipleObjectsEx KernelBase 1778 5 +imp 'WaitForRedirectionStartComplete' WaitForRedirectionStartComplete user32 2496 +imp 'WaitForSingleObject' WaitForSingleObject KernelBase 1779 2 +imp 'WaitForSingleObjectEx' WaitForSingleObjectEx KernelBase 1780 3 +imp 'WaitForUserPolicyForegroundProcessingInternal' WaitForUserPolicyForegroundProcessingInternal KernelBase 1785 +imp 'WaitMessage' WaitMessage user32 2497 +imp 'WaitNamedPipeA' WaitNamedPipeA kernel32 1509 2 +imp 'WaitNamedPipe' WaitNamedPipeW KernelBase 1786 +imp 'WaitOnAddress' WaitOnAddress KernelBase 1787 +imp 'WaitServiceState' WaitServiceState advapi32 1827 +imp 'WantArrows' WantArrows comdlg32 127 +imp 'WerGetFlags' WerGetFlags KernelBase 1792 +imp 'WerGetFlagsWorker' WerGetFlagsWorker kernel32 1514 +imp 'WerRegisterAdditionalProcess' WerRegisterAdditionalProcess KernelBase 1793 +imp 'WerRegisterAppLocalDump' WerRegisterAppLocalDump KernelBase 1794 +imp 'WerRegisterCustomMetadata' WerRegisterCustomMetadata KernelBase 1795 +imp 'WerRegisterExcludedMemoryBlock' WerRegisterExcludedMemoryBlock KernelBase 1796 +imp 'WerRegisterFile' WerRegisterFile KernelBase 1797 +imp 'WerRegisterFileWorker' WerRegisterFileWorker kernel32 1520 +imp 'WerRegisterMemoryBlock' WerRegisterMemoryBlock KernelBase 1798 +imp 'WerRegisterMemoryBlockWorker' WerRegisterMemoryBlockWorker kernel32 1522 +imp 'WerRegisterRuntimeExceptionModule' WerRegisterRuntimeExceptionModule KernelBase 1799 +imp 'WerRegisterRuntimeExceptionModuleWorker' WerRegisterRuntimeExceptionModuleWorker kernel32 1524 +imp 'WerReportExceptionWorker' WerReportExceptionWorker ntdll 1679 +imp 'WerReportSQMEvent' WerReportSQMEvent ntdll 1680 +imp 'WerSetFlags' WerSetFlags KernelBase 1800 +imp 'WerSetFlagsWorker' WerSetFlagsWorker kernel32 1526 +imp 'WerUnregisterAdditionalProcess' WerUnregisterAdditionalProcess KernelBase 1801 +imp 'WerUnregisterAppLocalDump' WerUnregisterAppLocalDump KernelBase 1802 +imp 'WerUnregisterCustomMetadata' WerUnregisterCustomMetadata KernelBase 1803 +imp 'WerUnregisterExcludedMemoryBlock' WerUnregisterExcludedMemoryBlock KernelBase 1804 +imp 'WerUnregisterFile' WerUnregisterFile KernelBase 1805 +imp 'WerUnregisterFileWorker' WerUnregisterFileWorker kernel32 1532 +imp 'WerUnregisterMemoryBlock' WerUnregisterMemoryBlock KernelBase 1806 +imp 'WerUnregisterMemoryBlockWorker' WerUnregisterMemoryBlockWorker kernel32 1534 +imp 'WerUnregisterRuntimeExceptionModule' WerUnregisterRuntimeExceptionModule KernelBase 1807 +imp 'WerUnregisterRuntimeExceptionModuleWorker' WerUnregisterRuntimeExceptionModuleWorker kernel32 1536 +imp 'WerpGetDebugger' WerpGetDebugger kernel32 1537 +imp 'WerpInitiateRemoteRecovery' WerpInitiateRemoteRecovery kernel32 1538 +imp 'WerpLaunchAeDebug' WerpLaunchAeDebug kernel32 1539 +imp 'WerpNotifyLoadStringResource' WerpNotifyLoadStringResource KernelBase 1808 +imp 'WerpNotifyLoadStringResourceWorker' WerpNotifyLoadStringResourceWorker kernel32 1540 +imp 'WerpNotifyUseStringResource' WerpNotifyUseStringResource KernelBase 1809 +imp 'WerpNotifyUseStringResourceWorker' WerpNotifyUseStringResourceWorker kernel32 1541 +imp 'WideCharToMultiByte' WideCharToMultiByte KernelBase 1810 +imp 'WidenPath' WidenPath gdi32 1941 +imp 'Win32DeleteFile' Win32DeleteFile shell32 164 +imp 'WinExec' WinExec kernel32 1543 +imp 'WinHelpA' WinHelpA user32 2498 +imp 'WinHelp' WinHelpW user32 2499 +imp 'WinSqmAddToAverageDWORD' WinSqmAddToAverageDWORD ntdll 1681 +imp 'WinSqmAddToStream' WinSqmAddToStream ntdll 1682 +imp 'WinSqmAddToStreamEx' WinSqmAddToStreamEx ntdll 1683 +imp 'WinSqmCheckEscalationAddToStreamEx' WinSqmCheckEscalationAddToStreamEx ntdll 1684 +imp 'WinSqmCheckEscalationSetDWORD' WinSqmCheckEscalationSetDWORD ntdll 1685 +imp 'WinSqmCheckEscalationSetDWORD64' WinSqmCheckEscalationSetDWORD64 ntdll 1686 +imp 'WinSqmCheckEscalationSetString' WinSqmCheckEscalationSetString ntdll 1687 +imp 'WinSqmCommonDatapointDelete' WinSqmCommonDatapointDelete ntdll 1688 +imp 'WinSqmCommonDatapointSetDWORD' WinSqmCommonDatapointSetDWORD ntdll 1689 +imp 'WinSqmCommonDatapointSetDWORD64' WinSqmCommonDatapointSetDWORD64 ntdll 1690 +imp 'WinSqmCommonDatapointSetStreamEx' WinSqmCommonDatapointSetStreamEx ntdll 1691 +imp 'WinSqmCommonDatapointSetString' WinSqmCommonDatapointSetString ntdll 1692 +imp 'WinSqmEndSession' WinSqmEndSession ntdll 1693 +imp 'WinSqmEventEnabled' WinSqmEventEnabled ntdll 1694 +imp 'WinSqmEventWrite' WinSqmEventWrite ntdll 1695 +imp 'WinSqmGetEscalationRuleStatus' WinSqmGetEscalationRuleStatus ntdll 1696 +imp 'WinSqmGetInstrumentationProperty' WinSqmGetInstrumentationProperty ntdll 1697 +imp 'WinSqmIncrementDWORD' WinSqmIncrementDWORD ntdll 1698 +imp 'WinSqmIsOptedIn' WinSqmIsOptedIn ntdll 1699 +imp 'WinSqmIsOptedInEx' WinSqmIsOptedInEx ntdll 1700 +imp 'WinSqmIsSessionDisabled' WinSqmIsSessionDisabled ntdll 1701 +imp 'WinSqmSetDWORD' WinSqmSetDWORD ntdll 1702 +imp 'WinSqmSetDWORD64' WinSqmSetDWORD64 ntdll 1703 +imp 'WinSqmSetEscalationInfo' WinSqmSetEscalationInfo ntdll 1704 +imp 'WinSqmSetIfMaxDWORD' WinSqmSetIfMaxDWORD ntdll 1705 +imp 'WinSqmSetIfMinDWORD' WinSqmSetIfMinDWORD ntdll 1706 +imp 'WinSqmSetString' WinSqmSetString ntdll 1707 +imp 'WinSqmStartSession' WinSqmStartSession ntdll 1708 +imp 'WinSqmStartSessionForPartner' WinSqmStartSessionForPartner ntdll 1709 +imp 'WinSqmStartSqmOptinListener' WinSqmStartSqmOptinListener ntdll 1710 +imp 'WindowFromDC' WindowFromDC user32 2500 +imp 'WindowFromPhysicalPoint' WindowFromPhysicalPoint user32 2501 +imp 'WindowFromPoint' WindowFromPoint user32 2502 +imp 'WmiCloseBlock' WmiCloseBlock advapi32 1828 +imp 'WmiDevInstToInstanceNameA' WmiDevInstToInstanceNameA advapi32 1829 +imp 'WmiDevInstToInstanceName' WmiDevInstToInstanceNameW advapi32 1830 +imp 'WmiEnumerateGuids' WmiEnumerateGuids advapi32 1831 +imp 'WmiExecuteMethodA' WmiExecuteMethodA advapi32 1832 +imp 'WmiExecuteMethod' WmiExecuteMethodW advapi32 1833 +imp 'WmiFileHandleToInstanceNameA' WmiFileHandleToInstanceNameA advapi32 1834 +imp 'WmiFileHandleToInstanceName' WmiFileHandleToInstanceNameW advapi32 1835 +imp 'WmiFreeBuffer' WmiFreeBuffer advapi32 1836 +imp 'WmiMofEnumerateResourcesA' WmiMofEnumerateResourcesA advapi32 1837 +imp 'WmiMofEnumerateResources' WmiMofEnumerateResourcesW advapi32 1838 +imp 'WmiNotificationRegistrationA' WmiNotificationRegistrationA advapi32 1839 +imp 'WmiNotificationRegistration' WmiNotificationRegistrationW advapi32 1840 +imp 'WmiOpenBlock' WmiOpenBlock advapi32 1841 +imp 'WmiQueryAllDataA' WmiQueryAllDataA advapi32 1842 +imp 'WmiQueryAllDataMultipleA' WmiQueryAllDataMultipleA advapi32 1843 +imp 'WmiQueryAllDataMultiple' WmiQueryAllDataMultipleW advapi32 1844 +imp 'WmiQueryAllData' WmiQueryAllDataW advapi32 1845 +imp 'WmiQueryGuidInformation' WmiQueryGuidInformation advapi32 1846 +imp 'WmiQuerySingleInstanceA' WmiQuerySingleInstanceA advapi32 1847 +imp 'WmiQuerySingleInstanceMultipleA' WmiQuerySingleInstanceMultipleA advapi32 1848 +imp 'WmiQuerySingleInstanceMultiple' WmiQuerySingleInstanceMultipleW advapi32 1849 +imp 'WmiQuerySingleInstance' WmiQuerySingleInstanceW advapi32 1850 +imp 'WmiReceiveNotificationsA' WmiReceiveNotificationsA advapi32 1851 +imp 'WmiReceiveNotifications' WmiReceiveNotificationsW advapi32 1852 +imp 'WmiSetSingleInstanceA' WmiSetSingleInstanceA advapi32 1853 +imp 'WmiSetSingleInstance' WmiSetSingleInstanceW advapi32 1854 +imp 'WmiSetSingleItemA' WmiSetSingleItemA advapi32 1855 +imp 'WmiSetSingleItem' WmiSetSingleItemW advapi32 1856 +imp 'Wow64DisableWow64FsRedirection' Wow64DisableWow64FsRedirection KernelBase 1811 +imp 'Wow64EnableWow64FsRedirection' Wow64EnableWow64FsRedirection kernel32 1545 +imp 'Wow64GetThreadContext' Wow64GetThreadContext kernel32 1546 +imp 'Wow64GetThreadSelectorEntry' Wow64GetThreadSelectorEntry kernel32 1547 +imp 'Wow64RevertWow64FsRedirection' Wow64RevertWow64FsRedirection KernelBase 1812 +imp 'Wow64SetThreadContext' Wow64SetThreadContext kernel32 1549 +imp 'Wow64SetThreadDefaultGuestMachine' Wow64SetThreadDefaultGuestMachine KernelBase 1813 +imp 'Wow64SuspendThread' Wow64SuspendThread kernel32 1550 +imp 'WriteCabinetState' WriteCabinetState shell32 652 +imp 'WriteConsole' WriteConsoleW KernelBase 1822 5 +imp 'WriteConsoleA' WriteConsoleA KernelBase 1814 5 +imp 'WriteConsoleInput' WriteConsoleInputW KernelBase 1816 4 +imp 'WriteConsoleInputA' WriteConsoleInputA KernelBase 1815 4 +imp 'WriteConsoleInputVDMA' WriteConsoleInputVDMA kernel32 1553 +imp 'WriteConsoleInputVDMW' WriteConsoleInputVDMW kernel32 1554 +imp 'WriteConsoleOutput' WriteConsoleOutputW KernelBase 1821 +imp 'WriteConsoleOutputA' WriteConsoleOutputA KernelBase 1817 +imp 'WriteConsoleOutputAttribute' WriteConsoleOutputAttribute KernelBase 1818 5 +imp 'WriteConsoleOutputCharacter' WriteConsoleOutputCharacterW KernelBase 1820 5 +imp 'WriteConsoleOutputCharacterA' WriteConsoleOutputCharacterA KernelBase 1819 5 +imp 'WriteEncryptedFileRaw' WriteEncryptedFileRaw advapi32 1857 +imp 'WriteFile' WriteFile KernelBase 1823 5 +imp 'WriteFileEx' WriteFileEx KernelBase 1824 +imp 'WriteFileGather' WriteFileGather KernelBase 1825 5 +imp 'WritePrivateProfileSectionA' WritePrivateProfileSectionA kernel32 1565 +imp 'WritePrivateProfileSection' WritePrivateProfileSectionW kernel32 1566 +imp 'WritePrivateProfileStringA' WritePrivateProfileStringA kernel32 1567 +imp 'WritePrivateProfileString' WritePrivateProfileStringW kernel32 1568 +imp 'WritePrivateProfileStructA' WritePrivateProfileStructA kernel32 1569 +imp 'WritePrivateProfileStruct' WritePrivateProfileStructW kernel32 1570 +imp 'WriteProcessMemory' WriteProcessMemory KernelBase 1826 +imp 'WriteProfileSectionA' WriteProfileSectionA kernel32 1572 +imp 'WriteProfileSection' WriteProfileSectionW kernel32 1573 +imp 'WriteProfileStringA' WriteProfileStringA kernel32 1574 +imp 'WriteProfileString' WriteProfileStringW kernel32 1575 +imp 'WriteStateAtomValue' WriteStateAtomValue KernelBase 1827 +imp 'WriteStateContainerValue' WriteStateContainerValue KernelBase 1828 +imp 'WriteTapemark' WriteTapemark kernel32 1576 +imp 'XFORMOBJ_bApplyXform' XFORMOBJ_bApplyXform gdi32 1942 +imp 'XFORMOBJ_iGetXform' XFORMOBJ_iGetXform gdi32 1943 +imp 'XLATEOBJ_cGetPalette' XLATEOBJ_cGetPalette gdi32 1944 +imp 'XLATEOBJ_hGetColorTransform' XLATEOBJ_hGetColorTransform gdi32 1945 +imp 'XLATEOBJ_iXlate' XLATEOBJ_iXlate gdi32 1946 +imp 'XLATEOBJ_piVector' XLATEOBJ_piVector gdi32 1947 +imp 'ZombifyActCtx' ZombifyActCtx KernelBase 1829 +imp 'ZombifyActCtxWorker' ZombifyActCtxWorker kernel32 1578 +imp 'ZwAcceptConnectPort' ZwAcceptConnectPort ntdll 1711 +imp 'ZwAccessCheck' ZwAccessCheck ntdll 1712 +imp 'ZwAccessCheckAndAuditAlarm' ZwAccessCheckAndAuditAlarm ntdll 1713 +imp 'ZwAccessCheckByType' ZwAccessCheckByType ntdll 1714 +imp 'ZwAccessCheckByTypeAndAuditAlarm' ZwAccessCheckByTypeAndAuditAlarm ntdll 1715 +imp 'ZwAccessCheckByTypeResultList' ZwAccessCheckByTypeResultList ntdll 1716 +imp 'ZwAccessCheckByTypeResultListAndAuditAlarm' ZwAccessCheckByTypeResultListAndAuditAlarm ntdll 1717 +imp 'ZwAccessCheckByTypeResultListAndAuditAlarmByHandle' ZwAccessCheckByTypeResultListAndAuditAlarmByHandle ntdll 1718 +imp 'ZwAcquireProcessActivityReference' ZwAcquireProcessActivityReference ntdll 1719 +imp 'ZwAddAtom' ZwAddAtom ntdll 1720 +imp 'ZwAddAtomEx' ZwAddAtomEx ntdll 1721 +imp 'ZwAddBootEntry' ZwAddBootEntry ntdll 1722 +imp 'ZwAddDriverEntry' ZwAddDriverEntry ntdll 1723 +imp 'ZwAdjustGroupsToken' ZwAdjustGroupsToken ntdll 1724 +imp 'ZwAdjustPrivilegesToken' ZwAdjustPrivilegesToken ntdll 1725 +imp 'ZwAdjustTokenClaimsAndDeviceGroups' ZwAdjustTokenClaimsAndDeviceGroups ntdll 1726 +imp 'ZwAlertResumeThread' ZwAlertResumeThread ntdll 1727 +imp 'ZwAlertThread' ZwAlertThread ntdll 1728 +imp 'ZwAlertThreadByThreadId' ZwAlertThreadByThreadId ntdll 1729 +imp 'ZwAllocateLocallyUniqueId' ZwAllocateLocallyUniqueId ntdll 1730 +imp 'ZwAllocateReserveObject' ZwAllocateReserveObject ntdll 1731 +imp 'ZwAllocateUserPhysicalPages' ZwAllocateUserPhysicalPages ntdll 1732 +imp 'ZwAllocateUuids' ZwAllocateUuids ntdll 1733 +imp 'ZwAllocateVirtualMemory' ZwAllocateVirtualMemory ntdll 1734 +imp 'ZwAllocateVirtualMemoryEx' ZwAllocateVirtualMemoryEx ntdll 1735 +imp 'ZwAlpcAcceptConnectPort' ZwAlpcAcceptConnectPort ntdll 1736 +imp 'ZwAlpcCancelMessage' ZwAlpcCancelMessage ntdll 1737 +imp 'ZwAlpcConnectPort' ZwAlpcConnectPort ntdll 1738 +imp 'ZwAlpcConnectPortEx' ZwAlpcConnectPortEx ntdll 1739 +imp 'ZwAlpcCreatePort' ZwAlpcCreatePort ntdll 1740 +imp 'ZwAlpcCreatePortSection' ZwAlpcCreatePortSection ntdll 1741 +imp 'ZwAlpcCreateResourceReserve' ZwAlpcCreateResourceReserve ntdll 1742 +imp 'ZwAlpcCreateSectionView' ZwAlpcCreateSectionView ntdll 1743 +imp 'ZwAlpcCreateSecurityContext' ZwAlpcCreateSecurityContext ntdll 1744 +imp 'ZwAlpcDeletePortSection' ZwAlpcDeletePortSection ntdll 1745 +imp 'ZwAlpcDeleteResourceReserve' ZwAlpcDeleteResourceReserve ntdll 1746 +imp 'ZwAlpcDeleteSectionView' ZwAlpcDeleteSectionView ntdll 1747 +imp 'ZwAlpcDeleteSecurityContext' ZwAlpcDeleteSecurityContext ntdll 1748 +imp 'ZwAlpcDisconnectPort' ZwAlpcDisconnectPort ntdll 1749 +imp 'ZwAlpcImpersonateClientContainerOfPort' ZwAlpcImpersonateClientContainerOfPort ntdll 1750 +imp 'ZwAlpcImpersonateClientOfPort' ZwAlpcImpersonateClientOfPort ntdll 1751 +imp 'ZwAlpcOpenSenderProcess' ZwAlpcOpenSenderProcess ntdll 1752 +imp 'ZwAlpcOpenSenderThread' ZwAlpcOpenSenderThread ntdll 1753 +imp 'ZwAlpcQueryInformation' ZwAlpcQueryInformation ntdll 1754 +imp 'ZwAlpcQueryInformationMessage' ZwAlpcQueryInformationMessage ntdll 1755 +imp 'ZwAlpcRevokeSecurityContext' ZwAlpcRevokeSecurityContext ntdll 1756 +imp 'ZwAlpcSendWaitReceivePort' ZwAlpcSendWaitReceivePort ntdll 1757 +imp 'ZwAlpcSetInformation' ZwAlpcSetInformation ntdll 1758 +imp 'ZwApphelpCacheControl' ZwApphelpCacheControl ntdll 1759 +imp 'ZwAreMappedFilesTheSame' ZwAreMappedFilesTheSame ntdll 1760 2 +imp 'ZwAssignProcessToJobObject' ZwAssignProcessToJobObject ntdll 1761 +imp 'ZwAssociateWaitCompletionPacket' ZwAssociateWaitCompletionPacket ntdll 1762 +imp 'ZwCallEnclave' ZwCallEnclave ntdll 1763 +imp 'ZwCallbackReturn' ZwCallbackReturn ntdll 1764 +imp 'ZwCancelIoFile' ZwCancelIoFile ntdll 1765 +imp 'ZwCancelIoFileEx' ZwCancelIoFileEx ntdll 1766 +imp 'ZwCancelSynchronousIoFile' ZwCancelSynchronousIoFile ntdll 1767 +imp 'ZwCancelTimer' ZwCancelTimer ntdll 1768 +imp 'ZwCancelTimer2' ZwCancelTimer2 ntdll 1769 +imp 'ZwCancelWaitCompletionPacket' ZwCancelWaitCompletionPacket ntdll 1770 +imp 'ZwClearEvent' ZwClearEvent ntdll 1771 +imp 'ZwClose' ZwClose ntdll 1772 +imp 'ZwCloseObjectAuditAlarm' ZwCloseObjectAuditAlarm ntdll 1773 +imp 'ZwCommitComplete' ZwCommitComplete ntdll 1774 +imp 'ZwCommitEnlistment' ZwCommitEnlistment ntdll 1775 +imp 'ZwCommitRegistryTransaction' ZwCommitRegistryTransaction ntdll 1776 +imp 'ZwCommitTransaction' ZwCommitTransaction ntdll 1777 +imp 'ZwCompactKeys' ZwCompactKeys ntdll 1778 +imp 'ZwCompareObjects' ZwCompareObjects ntdll 1779 +imp 'ZwCompareSigningLevels' ZwCompareSigningLevels ntdll 1780 +imp 'ZwCompareTokens' ZwCompareTokens ntdll 1781 +imp 'ZwCompleteConnectPort' ZwCompleteConnectPort ntdll 1782 +imp 'ZwCompressKey' ZwCompressKey ntdll 1783 +imp 'ZwConnectPort' ZwConnectPort ntdll 1784 +imp 'ZwContinue' ZwContinue ntdll 1785 +imp 'ZwConvertBetweenAuxiliaryCounterAndPerformanceCounter' ZwConvertBetweenAuxiliaryCounterAndPerformanceCounter ntdll 1786 +imp 'ZwCreateDebugObject' ZwCreateDebugObject ntdll 1787 +imp 'ZwCreateDirectoryObject' ZwCreateDirectoryObject ntdll 1788 +imp 'ZwCreateDirectoryObjectEx' ZwCreateDirectoryObjectEx ntdll 1789 +imp 'ZwCreateEnclave' ZwCreateEnclave ntdll 1790 +imp 'ZwCreateEnlistment' ZwCreateEnlistment ntdll 1791 +imp 'ZwCreateEvent' ZwCreateEvent ntdll 1792 +imp 'ZwCreateEventPair' ZwCreateEventPair ntdll 1793 +imp 'ZwCreateFile' ZwCreateFile ntdll 1794 +imp 'ZwCreateIRTimer' ZwCreateIRTimer ntdll 1795 +imp 'ZwCreateIoCompletion' ZwCreateIoCompletion ntdll 1796 +imp 'ZwCreateJobObject' ZwCreateJobObject ntdll 1797 +imp 'ZwCreateJobSet' ZwCreateJobSet ntdll 1798 +imp 'ZwCreateKey' ZwCreateKey ntdll 1799 +imp 'ZwCreateKeyTransacted' ZwCreateKeyTransacted ntdll 1800 +imp 'ZwCreateKeyedEvent' ZwCreateKeyedEvent ntdll 1801 +imp 'ZwCreateLowBoxToken' ZwCreateLowBoxToken ntdll 1802 +imp 'ZwCreateMailslotFile' ZwCreateMailslotFile ntdll 1803 +imp 'ZwCreateMutant' ZwCreateMutant ntdll 1804 +imp 'ZwCreateNamedPipeFile' ZwCreateNamedPipeFile ntdll 1805 +imp 'ZwCreatePagingFile' ZwCreatePagingFile ntdll 1806 +imp 'ZwCreatePartition' ZwCreatePartition ntdll 1807 +imp 'ZwCreatePort' ZwCreatePort ntdll 1808 +imp 'ZwCreatePrivateNamespace' ZwCreatePrivateNamespace ntdll 1809 +imp 'ZwCreateProcess' ZwCreateProcess ntdll 1810 +imp 'ZwCreateProcessEx' ZwCreateProcessEx ntdll 1811 +imp 'ZwCreateProfile' ZwCreateProfile ntdll 1812 +imp 'ZwCreateProfileEx' ZwCreateProfileEx ntdll 1813 +imp 'ZwCreateRegistryTransaction' ZwCreateRegistryTransaction ntdll 1814 +imp 'ZwCreateResourceManager' ZwCreateResourceManager ntdll 1815 +imp 'ZwCreateSection' ZwCreateSection ntdll 1816 +imp 'ZwCreateSemaphore' ZwCreateSemaphore ntdll 1817 +imp 'ZwCreateSymbolicLinkObject' ZwCreateSymbolicLinkObject ntdll 1818 +imp 'ZwCreateThread' ZwCreateThread ntdll 1819 +imp 'ZwCreateThreadEx' ZwCreateThreadEx ntdll 1820 +imp 'ZwCreateTimer' ZwCreateTimer ntdll 1821 +imp 'ZwCreateTimer2' ZwCreateTimer2 ntdll 1822 +imp 'ZwCreateToken' ZwCreateToken ntdll 1823 +imp 'ZwCreateTokenEx' ZwCreateTokenEx ntdll 1824 +imp 'ZwCreateTransaction' ZwCreateTransaction ntdll 1825 +imp 'ZwCreateTransactionManager' ZwCreateTransactionManager ntdll 1826 +imp 'ZwCreateUserProcess' ZwCreateUserProcess ntdll 1827 +imp 'ZwCreateWaitCompletionPacket' ZwCreateWaitCompletionPacket ntdll 1828 +imp 'ZwCreateWaitablePort' ZwCreateWaitablePort ntdll 1829 +imp 'ZwCreateWnfStateName' ZwCreateWnfStateName ntdll 1830 +imp 'ZwCreateWorkerFactory' ZwCreateWorkerFactory ntdll 1831 +imp 'ZwDebugActiveProcess' ZwDebugActiveProcess ntdll 1832 +imp 'ZwDebugContinue' ZwDebugContinue ntdll 1833 +imp 'ZwDelayExecution' ZwDelayExecution ntdll 1834 +imp 'ZwDeleteAtom' ZwDeleteAtom ntdll 1835 +imp 'ZwDeleteBootEntry' ZwDeleteBootEntry ntdll 1836 +imp 'ZwDeleteDriverEntry' ZwDeleteDriverEntry ntdll 1837 +imp 'ZwDeleteFile' ZwDeleteFile ntdll 1838 +imp 'ZwDeleteKey' ZwDeleteKey ntdll 1839 +imp 'ZwDeleteObjectAuditAlarm' ZwDeleteObjectAuditAlarm ntdll 1840 +imp 'ZwDeletePrivateNamespace' ZwDeletePrivateNamespace ntdll 1841 +imp 'ZwDeleteValueKey' ZwDeleteValueKey ntdll 1842 +imp 'ZwDeleteWnfStateData' ZwDeleteWnfStateData ntdll 1843 +imp 'ZwDeleteWnfStateName' ZwDeleteWnfStateName ntdll 1844 +imp 'ZwDeviceIoControlFile' ZwDeviceIoControlFile ntdll 1845 +imp 'ZwDisableLastKnownGood' ZwDisableLastKnownGood ntdll 1846 +imp 'ZwDisplayString' ZwDisplayString ntdll 1847 +imp 'ZwDrawText' ZwDrawText ntdll 1848 +imp 'ZwDuplicateObject' ZwDuplicateObject ntdll 1849 +imp 'ZwDuplicateToken' ZwDuplicateToken ntdll 1850 +imp 'ZwEnableLastKnownGood' ZwEnableLastKnownGood ntdll 1851 +imp 'ZwEnumerateBootEntries' ZwEnumerateBootEntries ntdll 1852 +imp 'ZwEnumerateDriverEntries' ZwEnumerateDriverEntries ntdll 1853 +imp 'ZwEnumerateKey' ZwEnumerateKey ntdll 1854 +imp 'ZwEnumerateSystemEnvironmentValuesEx' ZwEnumerateSystemEnvironmentValuesEx ntdll 1855 +imp 'ZwEnumerateTransactionObject' ZwEnumerateTransactionObject ntdll 1856 +imp 'ZwEnumerateValueKey' ZwEnumerateValueKey ntdll 1857 +imp 'ZwExtendSection' ZwExtendSection ntdll 1858 +imp 'ZwFilterBootOption' ZwFilterBootOption ntdll 1859 +imp 'ZwFilterToken' ZwFilterToken ntdll 1860 +imp 'ZwFilterTokenEx' ZwFilterTokenEx ntdll 1861 +imp 'ZwFindAtom' ZwFindAtom ntdll 1862 +imp 'ZwFlushBuffersFile' ZwFlushBuffersFile ntdll 1863 +imp 'ZwFlushBuffersFileEx' ZwFlushBuffersFileEx ntdll 1864 +imp 'ZwFlushInstallUILanguage' ZwFlushInstallUILanguage ntdll 1865 +imp 'ZwFlushInstructionCache' ZwFlushInstructionCache ntdll 1866 +imp 'ZwFlushKey' ZwFlushKey ntdll 1867 +imp 'ZwFlushProcessWriteBuffers' ZwFlushProcessWriteBuffers ntdll 1868 +imp 'ZwFlushVirtualMemory' ZwFlushVirtualMemory ntdll 1869 +imp 'ZwFlushWriteBuffer' ZwFlushWriteBuffer ntdll 1870 +imp 'ZwFreeUserPhysicalPages' ZwFreeUserPhysicalPages ntdll 1871 +imp 'ZwFreeVirtualMemory' ZwFreeVirtualMemory ntdll 1872 +imp 'ZwFreezeRegistry' ZwFreezeRegistry ntdll 1873 +imp 'ZwFreezeTransactions' ZwFreezeTransactions ntdll 1874 +imp 'ZwFsControlFile' ZwFsControlFile ntdll 1875 +imp 'ZwGetCachedSigningLevel' ZwGetCachedSigningLevel ntdll 1876 +imp 'ZwGetCompleteWnfStateSubscription' ZwGetCompleteWnfStateSubscription ntdll 1877 +imp 'ZwGetContextThread' ZwGetContextThread ntdll 1878 +imp 'ZwGetCurrentProcessorNumber' ZwGetCurrentProcessorNumber ntdll 1879 +imp 'ZwGetCurrentProcessorNumberEx' ZwGetCurrentProcessorNumberEx ntdll 1880 +imp 'ZwGetDevicePowerState' ZwGetDevicePowerState ntdll 1881 +imp 'ZwGetMUIRegistryInfo' ZwGetMUIRegistryInfo ntdll 1882 +imp 'ZwGetNextProcess' ZwGetNextProcess ntdll 1883 +imp 'ZwGetNextThread' ZwGetNextThread ntdll 1884 +imp 'ZwGetNlsSectionPtr' ZwGetNlsSectionPtr ntdll 1885 +imp 'ZwGetNotificationResourceManager' ZwGetNotificationResourceManager ntdll 1886 +imp 'ZwGetWriteWatch' ZwGetWriteWatch ntdll 1887 +imp 'ZwImpersonateAnonymousToken' ZwImpersonateAnonymousToken ntdll 1888 +imp 'ZwImpersonateClientOfPort' ZwImpersonateClientOfPort ntdll 1889 +imp 'ZwImpersonateThread' ZwImpersonateThread ntdll 1890 +imp 'ZwInitializeEnclave' ZwInitializeEnclave ntdll 1891 +imp 'ZwInitializeNlsFiles' ZwInitializeNlsFiles ntdll 1892 +imp 'ZwInitializeRegistry' ZwInitializeRegistry ntdll 1893 +imp 'ZwInitiatePowerAction' ZwInitiatePowerAction ntdll 1894 +imp 'ZwIsProcessInJob' ZwIsProcessInJob ntdll 1895 +imp 'ZwIsSystemResumeAutomatic' ZwIsSystemResumeAutomatic ntdll 1896 +imp 'ZwIsUILanguageComitted' ZwIsUILanguageComitted ntdll 1897 +imp 'ZwListenPort' ZwListenPort ntdll 1898 +imp 'ZwLoadDriver' ZwLoadDriver ntdll 1899 +imp 'ZwLoadEnclaveData' ZwLoadEnclaveData ntdll 1900 +imp 'ZwLoadHotPatch' ZwLoadHotPatch ntdll 1901 +imp 'ZwLoadKey' ZwLoadKey ntdll 1902 +imp 'ZwLoadKey2' ZwLoadKey2 ntdll 1903 +imp 'ZwLoadKeyEx' ZwLoadKeyEx ntdll 1904 +imp 'ZwLockFile' ZwLockFile ntdll 1905 +imp 'ZwLockProductActivationKeys' ZwLockProductActivationKeys ntdll 1906 +imp 'ZwLockRegistryKey' ZwLockRegistryKey ntdll 1907 +imp 'ZwLockVirtualMemory' ZwLockVirtualMemory ntdll 1908 +imp 'ZwMakePermanentObject' ZwMakePermanentObject ntdll 1909 +imp 'ZwMakeTemporaryObject' ZwMakeTemporaryObject ntdll 1910 +imp 'ZwManagePartition' ZwManagePartition ntdll 1911 +imp 'ZwMapCMFModule' ZwMapCMFModule ntdll 1912 +imp 'ZwMapUserPhysicalPages' ZwMapUserPhysicalPages ntdll 1913 +imp 'ZwMapUserPhysicalPagesScatter' ZwMapUserPhysicalPagesScatter ntdll 1914 +imp 'ZwMapViewOfSection' ZwMapViewOfSection ntdll 1915 +imp 'ZwMapViewOfSectionEx' ZwMapViewOfSectionEx ntdll 1916 +imp 'ZwModifyBootEntry' ZwModifyBootEntry ntdll 1917 +imp 'ZwModifyDriverEntry' ZwModifyDriverEntry ntdll 1918 +imp 'ZwNotifyChangeDirectoryFile' ZwNotifyChangeDirectoryFile ntdll 1919 +imp 'ZwNotifyChangeDirectoryFileEx' ZwNotifyChangeDirectoryFileEx ntdll 1920 +imp 'ZwNotifyChangeKey' ZwNotifyChangeKey ntdll 1921 +imp 'ZwNotifyChangeMultipleKeys' ZwNotifyChangeMultipleKeys ntdll 1922 +imp 'ZwNotifyChangeSession' ZwNotifyChangeSession ntdll 1923 +imp 'ZwOpenDirectoryObject' ZwOpenDirectoryObject ntdll 1924 +imp 'ZwOpenEnlistment' ZwOpenEnlistment ntdll 1925 +imp 'ZwOpenEvent' ZwOpenEvent ntdll 1926 +imp 'ZwOpenEventPair' ZwOpenEventPair ntdll 1927 +imp 'ZwOpenFile' ZwOpenFile ntdll 1928 +imp 'ZwOpenIoCompletion' ZwOpenIoCompletion ntdll 1929 +imp 'ZwOpenJobObject' ZwOpenJobObject ntdll 1930 +imp 'ZwOpenKey' ZwOpenKey ntdll 1931 +imp 'ZwOpenKeyEx' ZwOpenKeyEx ntdll 1932 +imp 'ZwOpenKeyTransacted' ZwOpenKeyTransacted ntdll 1933 +imp 'ZwOpenKeyTransactedEx' ZwOpenKeyTransactedEx ntdll 1934 +imp 'ZwOpenKeyedEvent' ZwOpenKeyedEvent ntdll 1935 +imp 'ZwOpenMutant' ZwOpenMutant ntdll 1936 +imp 'ZwOpenObjectAuditAlarm' ZwOpenObjectAuditAlarm ntdll 1937 +imp 'ZwOpenPartition' ZwOpenPartition ntdll 1938 +imp 'ZwOpenPrivateNamespace' ZwOpenPrivateNamespace ntdll 1939 +imp 'ZwOpenProcess' ZwOpenProcess ntdll 1940 +imp 'ZwOpenProcessToken' ZwOpenProcessToken ntdll 1941 +imp 'ZwOpenProcessTokenEx' ZwOpenProcessTokenEx ntdll 1942 +imp 'ZwOpenRegistryTransaction' ZwOpenRegistryTransaction ntdll 1943 +imp 'ZwOpenResourceManager' ZwOpenResourceManager ntdll 1944 +imp 'ZwOpenSection' ZwOpenSection ntdll 1945 +imp 'ZwOpenSemaphore' ZwOpenSemaphore ntdll 1946 +imp 'ZwOpenSession' ZwOpenSession ntdll 1947 +imp 'ZwOpenSymbolicLinkObject' ZwOpenSymbolicLinkObject ntdll 1948 +imp 'ZwOpenThread' ZwOpenThread ntdll 1949 +imp 'ZwOpenThreadToken' ZwOpenThreadToken ntdll 1950 +imp 'ZwOpenThreadTokenEx' ZwOpenThreadTokenEx ntdll 1951 +imp 'ZwOpenTimer' ZwOpenTimer ntdll 1952 +imp 'ZwOpenTransaction' ZwOpenTransaction ntdll 1953 +imp 'ZwOpenTransactionManager' ZwOpenTransactionManager ntdll 1954 +imp 'ZwPlugPlayControl' ZwPlugPlayControl ntdll 1955 +imp 'ZwPowerInformation' ZwPowerInformation ntdll 1956 +imp 'ZwPrePrepareComplete' ZwPrePrepareComplete ntdll 1957 +imp 'ZwPrePrepareEnlistment' ZwPrePrepareEnlistment ntdll 1958 +imp 'ZwPrepareComplete' ZwPrepareComplete ntdll 1959 +imp 'ZwPrepareEnlistment' ZwPrepareEnlistment ntdll 1960 +imp 'ZwPrivilegeCheck' ZwPrivilegeCheck ntdll 1961 +imp 'ZwPrivilegeObjectAuditAlarm' ZwPrivilegeObjectAuditAlarm ntdll 1962 +imp 'ZwPrivilegedServiceAuditAlarm' ZwPrivilegedServiceAuditAlarm ntdll 1963 +imp 'ZwPropagationComplete' ZwPropagationComplete ntdll 1964 +imp 'ZwPropagationFailed' ZwPropagationFailed ntdll 1965 +imp 'ZwProtectVirtualMemory' ZwProtectVirtualMemory ntdll 1966 +imp 'ZwPulseEvent' ZwPulseEvent ntdll 1967 +imp 'ZwQueryAttributesFile' ZwQueryAttributesFile ntdll 1968 +imp 'ZwQueryAuxiliaryCounterFrequency' ZwQueryAuxiliaryCounterFrequency ntdll 1969 +imp 'ZwQueryBootEntryOrder' ZwQueryBootEntryOrder ntdll 1970 +imp 'ZwQueryBootOptions' ZwQueryBootOptions ntdll 1971 +imp 'ZwQueryDebugFilterState' ZwQueryDebugFilterState ntdll 1972 +imp 'ZwQueryDefaultLocale' ZwQueryDefaultLocale ntdll 1973 +imp 'ZwQueryDefaultUILanguage' ZwQueryDefaultUILanguage ntdll 1974 +imp 'ZwQueryDirectoryFile' ZwQueryDirectoryFile ntdll 1975 +imp 'ZwQueryDirectoryFileEx' ZwQueryDirectoryFileEx ntdll 1976 +imp 'ZwQueryDirectoryObject' ZwQueryDirectoryObject ntdll 1977 +imp 'ZwQueryDriverEntryOrder' ZwQueryDriverEntryOrder ntdll 1978 +imp 'ZwQueryEaFile' ZwQueryEaFile ntdll 1979 +imp 'ZwQueryEvent' ZwQueryEvent ntdll 1980 +imp 'ZwQueryFullAttributesFile' ZwQueryFullAttributesFile ntdll 1981 +imp 'ZwQueryInformationAtom' ZwQueryInformationAtom ntdll 1982 +imp 'ZwQueryInformationByName' ZwQueryInformationByName ntdll 1983 +imp 'ZwQueryInformationEnlistment' ZwQueryInformationEnlistment ntdll 1984 +imp 'ZwQueryInformationFile' ZwQueryInformationFile ntdll 1985 +imp 'ZwQueryInformationJobObject' ZwQueryInformationJobObject ntdll 1986 +imp 'ZwQueryInformationPort' ZwQueryInformationPort ntdll 1987 +imp 'ZwQueryInformationProcess' ZwQueryInformationProcess ntdll 1988 +imp 'ZwQueryInformationResourceManager' ZwQueryInformationResourceManager ntdll 1989 +imp 'ZwQueryInformationThread' ZwQueryInformationThread ntdll 1990 +imp 'ZwQueryInformationToken' ZwQueryInformationToken ntdll 1991 +imp 'ZwQueryInformationTransaction' ZwQueryInformationTransaction ntdll 1992 +imp 'ZwQueryInformationTransactionManager' ZwQueryInformationTransactionManager ntdll 1993 +imp 'ZwQueryInformationWorkerFactory' ZwQueryInformationWorkerFactory ntdll 1994 +imp 'ZwQueryInstallUILanguage' ZwQueryInstallUILanguage ntdll 1995 +imp 'ZwQueryIntervalProfile' ZwQueryIntervalProfile ntdll 1996 +imp 'ZwQueryIoCompletion' ZwQueryIoCompletion ntdll 1997 +imp 'ZwQueryKey' ZwQueryKey ntdll 1998 +imp 'ZwQueryLicenseValue' ZwQueryLicenseValue ntdll 1999 +imp 'ZwQueryMultipleValueKey' ZwQueryMultipleValueKey ntdll 2000 +imp 'ZwQueryMutant' ZwQueryMutant ntdll 2001 +imp 'ZwQueryObject' ZwQueryObject ntdll 2002 +imp 'ZwQueryOpenSubKeys' ZwQueryOpenSubKeys ntdll 2003 +imp 'ZwQueryOpenSubKeysEx' ZwQueryOpenSubKeysEx ntdll 2004 +imp 'ZwQueryPerformanceCounter' ZwQueryPerformanceCounter ntdll 2005 +imp 'ZwQueryPortInformationProcess' ZwQueryPortInformationProcess ntdll 2006 +imp 'ZwQueryQuotaInformationFile' ZwQueryQuotaInformationFile ntdll 2007 +imp 'ZwQuerySection' ZwQuerySection ntdll 2008 +imp 'ZwQuerySecurityAttributesToken' ZwQuerySecurityAttributesToken ntdll 2009 +imp 'ZwQuerySecurityObject' ZwQuerySecurityObject ntdll 2010 +imp 'ZwQuerySecurityPolicy' ZwQuerySecurityPolicy ntdll 2011 +imp 'ZwQuerySemaphore' ZwQuerySemaphore ntdll 2012 +imp 'ZwQuerySymbolicLinkObject' ZwQuerySymbolicLinkObject ntdll 2013 +imp 'ZwQuerySystemEnvironmentValue' ZwQuerySystemEnvironmentValue ntdll 2014 +imp 'ZwQuerySystemEnvironmentValueEx' ZwQuerySystemEnvironmentValueEx ntdll 2015 +imp 'ZwQuerySystemInformation' ZwQuerySystemInformation ntdll 2016 +imp 'ZwQuerySystemInformationEx' ZwQuerySystemInformationEx ntdll 2017 +imp 'ZwQuerySystemTime' ZwQuerySystemTime ntdll 2018 +imp 'ZwQueryTimer' ZwQueryTimer ntdll 2019 +imp 'ZwQueryTimerResolution' ZwQueryTimerResolution ntdll 2020 +imp 'ZwQueryValueKey' ZwQueryValueKey ntdll 2021 +imp 'ZwQueryVirtualMemory' ZwQueryVirtualMemory ntdll 2022 +imp 'ZwQueryVolumeInformationFile' ZwQueryVolumeInformationFile ntdll 2023 +imp 'ZwQueryWnfStateData' ZwQueryWnfStateData ntdll 2024 +imp 'ZwQueryWnfStateNameInformation' ZwQueryWnfStateNameInformation ntdll 2025 +imp 'ZwQueueApcThread' ZwQueueApcThread ntdll 2026 +imp 'ZwQueueApcThreadEx' ZwQueueApcThreadEx ntdll 2027 +imp 'ZwRaiseException' ZwRaiseException ntdll 2028 +imp 'ZwRaiseHardError' ZwRaiseHardError ntdll 2029 +imp 'ZwReadFile' ZwReadFile ntdll 2030 +imp 'ZwReadFileScatter' ZwReadFileScatter ntdll 2031 +imp 'ZwReadOnlyEnlistment' ZwReadOnlyEnlistment ntdll 2032 +imp 'ZwReadRequestData' ZwReadRequestData ntdll 2033 +imp 'ZwReadVirtualMemory' ZwReadVirtualMemory ntdll 2034 +imp 'ZwRecoverEnlistment' ZwRecoverEnlistment ntdll 2035 +imp 'ZwRecoverResourceManager' ZwRecoverResourceManager ntdll 2036 +imp 'ZwRecoverTransactionManager' ZwRecoverTransactionManager ntdll 2037 +imp 'ZwRegisterProtocolAddressInformation' ZwRegisterProtocolAddressInformation ntdll 2038 +imp 'ZwRegisterThreadTerminatePort' ZwRegisterThreadTerminatePort ntdll 2039 +imp 'ZwReleaseKeyedEvent' ZwReleaseKeyedEvent ntdll 2040 +imp 'ZwReleaseMutant' ZwReleaseMutant ntdll 2041 +imp 'ZwReleaseSemaphore' ZwReleaseSemaphore ntdll 2042 +imp 'ZwReleaseWorkerFactoryWorker' ZwReleaseWorkerFactoryWorker ntdll 2043 +imp 'ZwRemoveIoCompletion' ZwRemoveIoCompletion ntdll 2044 +imp 'ZwRemoveIoCompletionEx' ZwRemoveIoCompletionEx ntdll 2045 +imp 'ZwRemoveProcessDebug' ZwRemoveProcessDebug ntdll 2046 +imp 'ZwRenameKey' ZwRenameKey ntdll 2047 +imp 'ZwRenameTransactionManager' ZwRenameTransactionManager ntdll 2048 +imp 'ZwReplaceKey' ZwReplaceKey ntdll 2049 +imp 'ZwReplacePartitionUnit' ZwReplacePartitionUnit ntdll 2050 +imp 'ZwReplyPort' ZwReplyPort ntdll 2051 +imp 'ZwReplyWaitReceivePort' ZwReplyWaitReceivePort ntdll 2052 +imp 'ZwReplyWaitReceivePortEx' ZwReplyWaitReceivePortEx ntdll 2053 +imp 'ZwReplyWaitReplyPort' ZwReplyWaitReplyPort ntdll 2054 +imp 'ZwRequestPort' ZwRequestPort ntdll 2055 +imp 'ZwRequestWaitReplyPort' ZwRequestWaitReplyPort ntdll 2056 +imp 'ZwResetEvent' ZwResetEvent ntdll 2057 +imp 'ZwResetWriteWatch' ZwResetWriteWatch ntdll 2058 +imp 'ZwRestoreKey' ZwRestoreKey ntdll 2059 +imp 'ZwResumeProcess' ZwResumeProcess ntdll 2060 +imp 'ZwResumeThread' ZwResumeThread ntdll 2061 +imp 'ZwRevertContainerImpersonation' ZwRevertContainerImpersonation ntdll 2062 +imp 'ZwRollbackComplete' ZwRollbackComplete ntdll 2063 +imp 'ZwRollbackEnlistment' ZwRollbackEnlistment ntdll 2064 +imp 'ZwRollbackRegistryTransaction' ZwRollbackRegistryTransaction ntdll 2065 +imp 'ZwRollbackTransaction' ZwRollbackTransaction ntdll 2066 +imp 'ZwRollforwardTransactionManager' ZwRollforwardTransactionManager ntdll 2067 +imp 'ZwSaveKey' ZwSaveKey ntdll 2068 +imp 'ZwSaveKeyEx' ZwSaveKeyEx ntdll 2069 +imp 'ZwSaveMergedKeys' ZwSaveMergedKeys ntdll 2070 +imp 'ZwSecureConnectPort' ZwSecureConnectPort ntdll 2071 +imp 'ZwSerializeBoot' ZwSerializeBoot ntdll 2072 +imp 'ZwSetBootEntryOrder' ZwSetBootEntryOrder ntdll 2073 +imp 'ZwSetBootOptions' ZwSetBootOptions ntdll 2074 +imp 'ZwSetCachedSigningLevel' ZwSetCachedSigningLevel ntdll 2075 +imp 'ZwSetCachedSigningLevel2' ZwSetCachedSigningLevel2 ntdll 2076 +imp 'ZwSetContextThread' ZwSetContextThread ntdll 2077 +imp 'ZwSetDebugFilterState' ZwSetDebugFilterState ntdll 2078 +imp 'ZwSetDefaultHardErrorPort' ZwSetDefaultHardErrorPort ntdll 2079 +imp 'ZwSetDefaultLocale' ZwSetDefaultLocale ntdll 2080 +imp 'ZwSetDefaultUILanguage' ZwSetDefaultUILanguage ntdll 2081 +imp 'ZwSetDriverEntryOrder' ZwSetDriverEntryOrder ntdll 2082 +imp 'ZwSetEaFile' ZwSetEaFile ntdll 2083 +imp 'ZwSetEvent' ZwSetEvent ntdll 2084 +imp 'ZwSetEventBoostPriority' ZwSetEventBoostPriority ntdll 2085 +imp 'ZwSetHighEventPair' ZwSetHighEventPair ntdll 2086 +imp 'ZwSetHighWaitLowEventPair' ZwSetHighWaitLowEventPair ntdll 2087 +imp 'ZwSetIRTimer' ZwSetIRTimer ntdll 2088 +imp 'ZwSetInformationDebugObject' ZwSetInformationDebugObject ntdll 2089 +imp 'ZwSetInformationEnlistment' ZwSetInformationEnlistment ntdll 2090 +imp 'ZwSetInformationFile' ZwSetInformationFile ntdll 2091 +imp 'ZwSetInformationJobObject' ZwSetInformationJobObject ntdll 2092 +imp 'ZwSetInformationKey' ZwSetInformationKey ntdll 2093 +imp 'ZwSetInformationObject' ZwSetInformationObject ntdll 2094 +imp 'ZwSetInformationProcess' ZwSetInformationProcess ntdll 2095 +imp 'ZwSetInformationResourceManager' ZwSetInformationResourceManager ntdll 2096 +imp 'ZwSetInformationSymbolicLink' ZwSetInformationSymbolicLink ntdll 2097 +imp 'ZwSetInformationThread' ZwSetInformationThread ntdll 2098 +imp 'ZwSetInformationToken' ZwSetInformationToken ntdll 2099 +imp 'ZwSetInformationTransaction' ZwSetInformationTransaction ntdll 2100 +imp 'ZwSetInformationTransactionManager' ZwSetInformationTransactionManager ntdll 2101 +imp 'ZwSetInformationVirtualMemory' ZwSetInformationVirtualMemory ntdll 2102 +imp 'ZwSetInformationWorkerFactory' ZwSetInformationWorkerFactory ntdll 2103 +imp 'ZwSetIntervalProfile' ZwSetIntervalProfile ntdll 2104 +imp 'ZwSetIoCompletion' ZwSetIoCompletion ntdll 2105 +imp 'ZwSetIoCompletionEx' ZwSetIoCompletionEx ntdll 2106 +imp 'ZwSetLdtEntries' ZwSetLdtEntries ntdll 2107 +imp 'ZwSetLowEventPair' ZwSetLowEventPair ntdll 2108 +imp 'ZwSetLowWaitHighEventPair' ZwSetLowWaitHighEventPair ntdll 2109 +imp 'ZwSetQuotaInformationFile' ZwSetQuotaInformationFile ntdll 2110 +imp 'ZwSetSecurityObject' ZwSetSecurityObject ntdll 2111 +imp 'ZwSetSystemEnvironmentValue' ZwSetSystemEnvironmentValue ntdll 2112 +imp 'ZwSetSystemEnvironmentValueEx' ZwSetSystemEnvironmentValueEx ntdll 2113 +imp 'ZwSetSystemInformation' ZwSetSystemInformation ntdll 2114 +imp 'ZwSetSystemPowerState' ZwSetSystemPowerState ntdll 2115 +imp 'ZwSetSystemTime' ZwSetSystemTime ntdll 2116 +imp 'ZwSetThreadExecutionState' ZwSetThreadExecutionState ntdll 2117 +imp 'ZwSetTimer' ZwSetTimer ntdll 2118 +imp 'ZwSetTimer2' ZwSetTimer2 ntdll 2119 +imp 'ZwSetTimerEx' ZwSetTimerEx ntdll 2120 +imp 'ZwSetTimerResolution' ZwSetTimerResolution ntdll 2121 +imp 'ZwSetUuidSeed' ZwSetUuidSeed ntdll 2122 +imp 'ZwSetValueKey' ZwSetValueKey ntdll 2123 +imp 'ZwSetVolumeInformationFile' ZwSetVolumeInformationFile ntdll 2124 +imp 'ZwSetWnfProcessNotificationEvent' ZwSetWnfProcessNotificationEvent ntdll 2125 +imp 'ZwShutdownSystem' ZwShutdownSystem ntdll 2126 +imp 'ZwShutdownWorkerFactory' ZwShutdownWorkerFactory ntdll 2127 +imp 'ZwSignalAndWaitForSingleObject' ZwSignalAndWaitForSingleObject ntdll 2128 +imp 'ZwSinglePhaseReject' ZwSinglePhaseReject ntdll 2129 +imp 'ZwStartProfile' ZwStartProfile ntdll 2130 +imp 'ZwStopProfile' ZwStopProfile ntdll 2131 +imp 'ZwSubscribeWnfStateChange' ZwSubscribeWnfStateChange ntdll 2132 +imp 'ZwSuspendProcess' ZwSuspendProcess ntdll 2133 +imp 'ZwSuspendThread' ZwSuspendThread ntdll 2134 +imp 'ZwSystemDebugControl' ZwSystemDebugControl ntdll 2135 +imp 'ZwTerminateEnclave' ZwTerminateEnclave ntdll 2136 +imp 'ZwTerminateJobObject' ZwTerminateJobObject ntdll 2137 +imp 'ZwTerminateProcess' ZwTerminateProcess ntdll 2138 +imp 'ZwTerminateThread' ZwTerminateThread ntdll 2139 +imp 'ZwTestAlert' ZwTestAlert ntdll 2140 +imp 'ZwThawRegistry' ZwThawRegistry ntdll 2141 +imp 'ZwThawTransactions' ZwThawTransactions ntdll 2142 +imp 'ZwTraceControl' ZwTraceControl ntdll 2143 +imp 'ZwTraceEvent' ZwTraceEvent ntdll 2144 +imp 'ZwTranslateFilePath' ZwTranslateFilePath ntdll 2145 +imp 'ZwUmsThreadYield' ZwUmsThreadYield ntdll 2146 +imp 'ZwUnloadDriver' ZwUnloadDriver ntdll 2147 +imp 'ZwUnloadKey' ZwUnloadKey ntdll 2148 +imp 'ZwUnloadKey2' ZwUnloadKey2 ntdll 2149 +imp 'ZwUnloadKeyEx' ZwUnloadKeyEx ntdll 2150 +imp 'ZwUnlockFile' ZwUnlockFile ntdll 2151 +imp 'ZwUnlockVirtualMemory' ZwUnlockVirtualMemory ntdll 2152 +imp 'ZwUnmapViewOfSection' ZwUnmapViewOfSection ntdll 2153 +imp 'ZwUnmapViewOfSectionEx' ZwUnmapViewOfSectionEx ntdll 2154 +imp 'ZwUnsubscribeWnfStateChange' ZwUnsubscribeWnfStateChange ntdll 2155 +imp 'ZwUpdateWnfStateData' ZwUpdateWnfStateData ntdll 2156 +imp 'ZwVdmControl' ZwVdmControl ntdll 2157 +imp 'ZwWaitForAlertByThreadId' ZwWaitForAlertByThreadId ntdll 2158 +imp 'ZwWaitForDebugEvent' ZwWaitForDebugEvent ntdll 2159 +imp 'ZwWaitForKeyedEvent' ZwWaitForKeyedEvent ntdll 2160 +imp 'ZwWaitForMultipleObjects' ZwWaitForMultipleObjects ntdll 2161 +imp 'ZwWaitForMultipleObjects32' ZwWaitForMultipleObjects32 ntdll 2162 +imp 'ZwWaitForSingleObject' ZwWaitForSingleObject ntdll 2163 +imp 'ZwWaitForWorkViaWorkerFactory' ZwWaitForWorkViaWorkerFactory ntdll 2164 +imp 'ZwWaitHighEventPair' ZwWaitHighEventPair ntdll 2165 +imp 'ZwWaitLowEventPair' ZwWaitLowEventPair ntdll 2166 +imp 'ZwWorkerFactoryWorkerReady' ZwWorkerFactoryWorkerReady ntdll 2167 +imp 'ZwWriteFile' ZwWriteFile ntdll 2168 +imp 'ZwWriteFileGather' ZwWriteFileGather ntdll 2169 +imp 'ZwWriteRequestData' ZwWriteRequestData ntdll 2170 +imp 'ZwWriteVirtualMemory' ZwWriteVirtualMemory ntdll 2171 +imp 'ZwYieldExecution' ZwYieldExecution ntdll 2172 +imp '_AddMUIStringToCache' _AddMUIStringToCache KernelBase 1830 +imp '_GetMUIStringFromCache' _GetMUIStringFromCache KernelBase 1831 +imp '_OpenMuiStringCache' _OpenMuiStringCache KernelBase 1832 +imp '_UserTestTokenForInteractive' _UserTestTokenForInteractive user32 2543 +imp '_amsg_exit' _amsg_exit KernelBase 1838 +imp '_atoi64' _atoi64 ntdll 2180 +imp '_c_exit' _c_exit KernelBase 1839 +imp '_cexit' _cexit KernelBase 1840 +imp '_errno' _errno ntdll 2181 +imp '_exit$nt' _exit KernelBase 1841 +imp '_fltused' _fltused ntdll 2182 +imp '_hread' _hread kernel32 1582 +imp '_hwrite' _hwrite kernel32 1583 +imp '_i64toa' _i64toa ntdll 2183 +imp '_i64toa_s' _i64toa_s ntdll 2184 +imp '_i64tow' _i64tow ntdll 2185 +imp '_i64tow_s' _i64tow_s ntdll 2186 +imp '_initterm' _initterm KernelBase 1842 +imp '_initterm_e' _initterm_e KernelBase 1843 +imp '_invalid_parameter' _invalid_parameter KernelBase 1844 +imp '_itoa' _itoa ntdll 2187 +imp '_itoa_s' _itoa_s ntdll 2188 +imp '_itow' _itow ntdll 2189 +imp '_itow_s' _itow_s ntdll 2190 +imp '_lclose' _lclose kernel32 1584 +imp '_lcreat' _lcreat kernel32 1585 +imp '_lfind' _lfind ntdll 2191 +imp '_llseek' _llseek kernel32 1586 +imp '_local_unwind' _local_unwind ntdll 2192 +imp '_lopen' _lopen kernel32 1588 +imp '_lread' _lread kernel32 1589 +imp '_ltoa' _ltoa ntdll 2193 +imp '_ltoa_s' _ltoa_s ntdll 2194 +imp '_ltow' _ltow ntdll 2195 +imp '_ltow_s' _ltow_s ntdll 2196 +imp '_lwrite' _lwrite kernel32 1590 +imp '_makepath_s' _makepath_s ntdll 2197 +imp '_memccpy' _memccpy ntdll 2198 +imp '_memicmp' _memicmp ntdll 2199 +imp '_onexit' _onexit KernelBase 1846 +imp '_purecall' _purecall KernelBase 1847 +imp '_setjmp$nt' _setjmp ntdll 2200 +imp '_setjmpex' _setjmpex ntdll 2201 +imp '_snprintf' _snprintf ntdll 2202 +imp '_snprintf_s' _snprintf_s ntdll 2203 +imp '_snscanf_s' _snscanf_s ntdll 2204 +imp '_snwprintf' _snwprintf ntdll 2205 +imp '_snwprintf_s' _snwprintf_s ntdll 2206 +imp '_snwscanf_s' _snwscanf_s ntdll 2207 +imp '_splitpath' _splitpath ntdll 2208 +imp '_splitpath_s' _splitpath_s ntdll 2209 +imp '_strcmpi' _strcmpi ntdll 2210 +imp '_stricmp' _stricmp ntdll 2211 +imp '_strlwr' _strlwr ntdll 2212 +imp '_strlwr_s' _strlwr_s ntdll 2213 +imp '_strnicmp' _strnicmp ntdll 2214 +imp '_strnset_s' _strnset_s ntdll 2215 +imp '_strset_s' _strset_s ntdll 2216 +imp '_strupr' _strupr ntdll 2217 +imp '_strupr_s' _strupr_s ntdll 2218 +imp '_swprintf' _swprintf ntdll 2219 +imp '_time64' _time64 KernelBase 1848 +imp '_ui64toa' _ui64toa ntdll 2220 +imp '_ui64toa_s' _ui64toa_s ntdll 2221 +imp '_ui64tow' _ui64tow ntdll 2222 +imp '_ui64tow_s' _ui64tow_s ntdll 2223 +imp '_ultoa' _ultoa ntdll 2224 +imp '_ultoa_s' _ultoa_s ntdll 2225 +imp '_ultow' _ultow ntdll 2226 +imp '_ultow_s' _ultow_s ntdll 2227 +imp '_vscprintf' _vscprintf ntdll 2228 +imp '_vscwprintf' _vscwprintf ntdll 2229 +imp '_vsnprintf' _vsnprintf ntdll 2230 +imp '_vsnprintf_s' _vsnprintf_s ntdll 2231 +imp '_vsnwprintf' _vsnwprintf ntdll 2232 +imp '_vsnwprintf_s' _vsnwprintf_s ntdll 2233 +imp '_vswprintf' _vswprintf ntdll 2234 +imp '_wcsicmp' _wcsicmp ntdll 2235 +imp '_wcslwr' _wcslwr ntdll 2236 +imp '_wcslwr_s' _wcslwr_s ntdll 2237 +imp '_wcsnicmp' _wcsnicmp ntdll 2238 +imp '_wcsnset_s' _wcsnset_s ntdll 2239 +imp '_wcsset_s' _wcsset_s ntdll 2240 +imp '_wcstoi64' _wcstoi64 ntdll 2241 +imp '_wcstoui64' _wcstoui64 ntdll 2242 +imp '_wcsupr' _wcsupr ntdll 2243 +imp '_wcsupr_s' _wcsupr_s ntdll 2244 +imp '_wmakepath_s' _wmakepath_s ntdll 2245 +imp '_wsplitpath_s' _wsplitpath_s ntdll 2246 +imp '_wtoi' _wtoi ntdll 2247 +imp '_wtoi64' _wtoi64 ntdll 2248 +imp '_wtol' _wtol ntdll 2249 +imp 'abs$nt' abs ntdll 2250 +imp '__accept$nt' accept ws2_32 1 +imp 'atan$nt' atan ntdll 2251 +imp 'atan2$nt' atan2 ntdll 2252 +imp 'atexit$nt' atexit KernelBase 1849 +imp 'atoi$nt' atoi ntdll 2253 +imp 'atol$nt' atol ntdll 2254 +imp 'bCreateDCW' bCreateDCW gdi32 1948 +imp 'bDeleteLDC' bDeleteLDC gdi32 1949 +imp 'bInitSystemAndFontsDirectories' bInitSystemAndFontsDirectoriesW gdi32 1950 +imp 'bMakePathName' bMakePathNameW gdi32 1951 +imp '__bind$nt' bind ws2_32 2 3 +imp 'bsearch$nt' bsearch ntdll 2255 +imp 'bsearch_s' bsearch_s ntdll 2256 +imp 'cGetTTFFromFOT' cGetTTFFromFOT gdi32 1952 +imp 'ceil$nt' ceil ntdll 2257 +imp '__closesocket$nt' closesocket ws2_32 3 1 +imp '__connect$nt' connect ws2_32 4 +imp 'cos$nt' cos ntdll 2258 +imp 'dwLBSubclass' dwLBSubclass comdlg32 128 +imp 'dwOKSubclass' dwOKSubclass comdlg32 129 +imp 'exit$nt' exit KernelBase 1850 +imp 'fabs$nt' fabs ntdll 2259 +imp 'floor$nt' floor ntdll 2260 +imp 'fpClosePrinter' fpClosePrinter gdi32 1953 +imp 'freeaddrinfo$nt' freeaddrinfo ws2_32 190 +imp 'gMaxGdiHandleCount' gMaxGdiHandleCount gdi32 1955 +imp 'gSharedInfo' gSharedInfo user32 2547 +imp 'gW32PID' gW32PID gdi32 1956 +imp 'g_systemCallFilterId' g_systemCallFilterId gdi32 1957 +imp 'gapfnScSendMessage' gapfnScSendMessage user32 2562 +imp 'gdiPlaySpoolStream' gdiPlaySpoolStream gdi32 1958 +imp 'getaddrinfo$nt' getaddrinfo ws2_32 191 +imp 'gethostbyaddr$nt' gethostbyaddr ws2_32 51 +imp 'gethostbyname$nt' gethostbyname ws2_32 52 +imp 'gethostname$nt' gethostname ws2_32 57 +imp 'getnameinfo$nt' getnameinfo ws2_32 192 +imp '__getpeername$nt' getpeername ws2_32 5 3 +imp 'getprotobyname$nt' getprotobyname ws2_32 53 +imp 'getprotobynumber$nt' getprotobynumber ws2_32 54 +imp 'getservbyname$nt' getservbyname ws2_32 55 +imp 'getservbyport$nt' getservbyport ws2_32 56 +imp '__getsockname$nt' getsockname ws2_32 6 3 +imp '__getsockopt$nt' getsockopt ws2_32 7 5 +imp 'ghICM' ghICM gdi32 1959 +imp 'hGetPEBHandle' hGetPEBHandle gdi32 1960 +imp 'hgets' hgets KernelBase 1851 +imp 'htonl$nt' htonl ws2_32 8 +imp 'htons$nt' htons ws2_32 9 +imp 'hwprintf' hwprintf KernelBase 1852 +imp 'inet_addr$nt' inet_addr ws2_32 11 +imp 'inet_ntoa$nt' inet_ntoa ws2_32 12 +imp 'inet_ntop$nt' inet_ntop ws2_32 193 +imp 'inet_pton$nt' inet_pton ws2_32 194 +imp '__ioctlsocket$nt' ioctlsocket ws2_32 10 3 +imp 'isalnum$nt' isalnum ntdll 2261 +imp 'isalpha$nt' isalpha ntdll 2262 +imp 'iscntrl$nt' iscntrl ntdll 2263 +imp 'isdigit$nt' isdigit ntdll 2264 +imp 'isgraph$nt' isgraph ntdll 2265 +imp 'islower$nt' islower ntdll 2266 +imp 'isprint$nt' isprint ntdll 2267 +imp 'ispunct$nt' ispunct ntdll 2268 +imp 'isspace$nt' isspace ntdll 2269 +imp 'isupper$nt' isupper ntdll 2270 +imp 'iswalnum$nt' iswalnum ntdll 2271 +imp 'iswalpha$nt' iswalpha ntdll 2272 +imp 'iswascii' iswascii ntdll 2273 +imp 'iswctype$nt' iswctype ntdll 2274 +imp 'iswdigit$nt' iswdigit ntdll 2275 +imp 'iswgraph$nt' iswgraph ntdll 2276 +imp 'iswlower$nt' iswlower ntdll 2277 +imp 'iswprint$nt' iswprint ntdll 2278 +imp 'iswspace$nt' iswspace ntdll 2279 +imp 'iswxdigit$nt' iswxdigit ntdll 2280 +imp 'isxdigit$nt' isxdigit ntdll 2281 +imp 'keybd_event' keybd_event user32 2580 +imp 'labs$nt' labs ntdll 2282 +imp '__listen$nt' listen ws2_32 13 2 +imp 'log$nt' log ntdll 2283 +imp 'longjmp$nt' longjmp ntdll 2284 +imp 'lstrcatA' lstrcatA kernel32 1592 +imp 'lstrcat' lstrcatW kernel32 1593 +imp 'lstrcmpA' lstrcmpA KernelBase 1854 +imp 'lstrcmp' lstrcmpW KernelBase 1855 +imp 'lstrcmpiA' lstrcmpiA KernelBase 1857 +imp 'lstrcmpi' lstrcmpiW KernelBase 1858 +imp 'lstrcpyA' lstrcpyA kernel32 1601 +imp 'lstrcpy' lstrcpyW kernel32 1602 +imp 'lstrcpynA' lstrcpynA KernelBase 1860 +imp 'lstrcpyn' lstrcpynW KernelBase 1861 +imp 'lstrlenA' lstrlenA KernelBase 1863 +imp 'lstrlen' lstrlenW KernelBase 1864 +imp 'mbstowcs$nt' mbstowcs ntdll 2285 +imp 'memchr$nt' memchr ntdll 2286 +imp 'memcmp$nt' memcmp ntdll 2287 +imp 'memcpy$nt' memcpy ntdll 2288 +imp 'memcpy_s' memcpy_s ntdll 2289 +imp 'memmove$nt' memmove ntdll 2290 +imp 'memmove_s' memmove_s ntdll 2291 +imp 'memset$nt' memset ntdll 2292 +imp 'mouse_event' mouse_event user32 2583 +imp 'ntohl$nt' ntohl ws2_32 14 +imp 'ntohs$nt' ntohs ws2_32 15 +imp 'pGdiDevCaps' pGdiDevCaps gdi32 1961 +imp 'pGdiSharedHandleTable' pGdiSharedHandleTable gdi32 1962 +imp 'pGdiSharedMemory' pGdiSharedMemory gdi32 1963 +imp 'pldcGet' pldcGet gdi32 1964 +imp 'pow$nt' pow ntdll 2293 +imp 'qsort$nt' qsort ntdll 2294 +imp 'qsort_s$nt' qsort_s ntdll 2295 +imp 'recv$nt' recv ws2_32 16 +imp '__recvfrom$nt' recvfrom ws2_32 17 +imp 'select$nt' select ws2_32 18 +imp 'semDxTrimNotification' semDxTrimNotification gdi32 1965 +imp 'send$nt' send ws2_32 19 +imp '__sendto$nt' sendto ws2_32 20 +imp '__setsockopt$nt' setsockopt ws2_32 21 5 +imp '__shutdown$nt' shutdown ws2_32 22 2 +imp 'sin$nt' sin ntdll 2296 +imp '__socket$nt' socket ws2_32 23 +imp 'sprintf$nt' sprintf ntdll 2297 +imp 'sprintf_s$nt' sprintf_s ntdll 2298 +imp 'sqrt$nt' sqrt ntdll 2299 +imp 'sscanf$nt' sscanf ntdll 2300 +imp 'sscanf_s$nt' sscanf_s ntdll 2301 +imp 'strcat$nt' strcat ntdll 2302 +imp 'strcat_s$nt' strcat_s ntdll 2303 +imp 'strchr$nt' strchr ntdll 2304 +imp 'strcmp$nt' strcmp ntdll 2305 +imp 'strcpy$nt' strcpy ntdll 2306 +imp 'strcpy_s$nt' strcpy_s ntdll 2307 +imp 'strcspn$nt' strcspn ntdll 2308 +imp 'strlen$nt' strlen ntdll 2309 +imp 'strncat$nt' strncat ntdll 2310 +imp 'strncat_s$nt' strncat_s ntdll 2311 +imp 'strncmp$nt' strncmp ntdll 2312 +imp 'strncpy$nt' strncpy ntdll 2313 +imp 'strncpy_s$nt' strncpy_s ntdll 2314 +imp 'strnlen$nt' strnlen ntdll 2315 +imp 'strpbrk$nt' strpbrk ntdll 2316 +imp 'strrchr$nt' strrchr ntdll 2317 +imp 'strspn$nt' strspn ntdll 2318 +imp 'strstr$nt' strstr ntdll 2319 +imp 'strtok_s$nt' strtok_s ntdll 2320 +imp 'strtol$nt' strtol ntdll 2321 +imp 'strtoul$nt' strtoul ntdll 2322 +imp 'swprintf$nt' swprintf ntdll 2323 +imp 'swprintf_s' swprintf_s ntdll 2324 +imp 'swscanf_s' swscanf_s ntdll 2325 +imp 'tan$nt' tan ntdll 2326 +imp 'time$nt' time KernelBase 1865 +imp 'timeBeginPeriod' timeBeginPeriod kernel32 1609 +imp 'timeEndPeriod' timeEndPeriod kernel32 1610 +imp 'timeGetDevCaps' timeGetDevCaps kernel32 1611 +imp 'timeGetSystemTime' timeGetSystemTime kernel32 1612 +imp 'timeGetTime' timeGetTime kernel32 1613 +imp 'tolower$nt' tolower ntdll 2327 +imp 'toupper$nt' toupper ntdll 2328 +imp 'towlower$nt' towlower ntdll 2329 +imp 'towupper$nt' towupper ntdll 2330 +imp 'uaw_lstrcmp' uaw_lstrcmpW kernel32 1614 +imp 'uaw_lstrcmpi' uaw_lstrcmpiW kernel32 1615 +imp 'uaw_lstrlen' uaw_lstrlenW kernel32 1616 +imp 'uaw_wcschr' uaw_wcschr kernel32 1617 +imp 'uaw_wcscpy' uaw_wcscpy kernel32 1618 +imp 'uaw_wcsicmp' uaw_wcsicmp kernel32 1619 +imp 'uaw_wcslen' uaw_wcslen kernel32 1620 +imp 'uaw_wcsrchr' uaw_wcsrchr kernel32 1621 +imp 'vDbgPrintEx' vDbgPrintEx ntdll 2331 +imp 'vDbgPrintExWithPrefix' vDbgPrintExWithPrefix ntdll 2332 +imp 'vSetPldc' vSetPldc gdi32 1966 +imp 'vsprintf$nt' vsprintf ntdll 2333 +imp 'vsprintf_s' vsprintf_s ntdll 2334 +imp 'vswprintf_s' vswprintf_s ntdll 2335 +imp 'wcscat$nt' wcscat ntdll 2336 +imp 'wcscat_s' wcscat_s ntdll 2337 +imp 'wcschr$nt' wcschr ntdll 2338 +imp 'wcscmp$nt' wcscmp ntdll 2339 +imp 'wcscpy$nt' wcscpy ntdll 2340 +imp 'wcscpy_s' wcscpy_s ntdll 2341 +imp 'wcscspn$nt' wcscspn ntdll 2342 +imp 'wcslen$nt' wcslen ntdll 2343 +imp 'wcsncat$nt' wcsncat ntdll 2344 +imp 'wcsncat_s' wcsncat_s ntdll 2345 +imp 'wcsncmp$nt' wcsncmp ntdll 2346 +imp 'wcsncpy$nt' wcsncpy ntdll 2347 +imp 'wcsncpy_s' wcsncpy_s ntdll 2348 +imp 'wcsnlen$nt' wcsnlen ntdll 2349 +imp 'wcspbrk$nt' wcspbrk ntdll 2350 +imp 'wcsrchr$nt' wcsrchr ntdll 2351 +imp 'wcsspn$nt' wcsspn ntdll 2352 +imp 'wcsstr$nt' wcsstr ntdll 2353 +imp 'wcstok_s' wcstok_s ntdll 2354 +imp 'wcstol$nt' wcstol ntdll 2355 +imp 'wcstombs$nt' wcstombs ntdll 2356 +imp 'wcstoul$nt' wcstoul ntdll 2357 +imp 'wprintf$nt' wprintf KernelBase 1866 +imp 'wsprintfA' wsprintfA user32 2596 +imp 'wsprintf' wsprintfW user32 2601 +imp 'wvsprintfA' wvsprintfA user32 2602 +imp 'wvsprintf' wvsprintfW user32 2603 diff --git a/libc/nt/memory.h b/libc/nt/memory.h new file mode 100644 index 00000000..af80b372 --- /dev/null +++ b/libc/nt/memory.h @@ -0,0 +1,77 @@ +#ifndef COSMOPOLITAN_LIBC_NT_MEMORY_H_ +#define COSMOPOLITAN_LIBC_NT_MEMORY_H_ +#include "libc/nt/enum/filemapflags.h" +#include "libc/nt/enum/memflags.h" +#include "libc/nt/enum/offerpriority.h" +#include "libc/nt/enum/pageflags.h" +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » memory ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +#define kNtNumaNoPreferredNode 0xffffffff + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtMemoryBasicInformation; +struct NtMemoryRangeEntry; +struct NtSecurityAttributes; + +int64_t CreateFileMappingNuma( + int64_t opt_hFile /* -1ul is MAP_ANONYMOUS */, + const struct NtSecurityAttributes *opt_lpFileMappingAttributes, + uint32_t flProtect, uint32_t dwMaximumSizeHigh, uint32_t dwMaximumSizeLow, + const char16_t *opt_lpName, uint32_t nndDesiredNumaNode); +void *MapViewOfFileExNuma( + int64_t hFileMappingObject, /* @see CreateFileMapping() */ + uint32_t dwDesiredAccess, uint32_t dwFileOffsetHigh, /* high order bits */ + uint32_t dwFileOffsetLow, /* low order bits */ + size_t dwNumberOfBytesToMap, void *opt_lpDesiredBaseAddress, + uint32_t nndDesiredNumaNode); +bool32 UnmapViewOfFile(const void *lpBaseAddress); +bool32 FlushViewOfFile(const void *lpBaseAddress, + size_t dwNumberOfBytesToFlush); + +void *VirtualAlloc(void *opt_lpAddress, uint64_t dwSize, + uint32_t flAllocationType, uint32_t flProtect); +bool32 VirtualFree(void *lpAddress, uint64_t dwSize, uint32_t dwFreeType); +bool32 VirtualProtect(void *lpAddress, uint64_t dwSize, uint32_t flNewProtect, + uint32_t *lpflOldProtect) paramsnonnull(); +uint64_t VirtualQuery(const void *lpAddress, + struct NtMemoryBasicInformation *lpBuffer, + uint64_t dwLength); +void *VirtualAllocEx(int64_t hProcess, void *lpAddress, uint64_t dwSize, + uint32_t flAllocationType, uint32_t flProtect); + +bool32 PrefetchVirtualMemory(int64_t hProcess, const uint32_t *NumberOfEntries, + struct NtMemoryRangeEntry *VirtualAddresses, + uint32_t reserved_Flags); +bool32 OfferVirtualMemory(void *inout_VirtualAddress, size_t Size, + enum NtOfferPriority Priority); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_MEMORY_H_ */ diff --git a/libc/nt/messagebox.h b/libc/nt/messagebox.h new file mode 100644 index 00000000..bd84f788 --- /dev/null +++ b/libc/nt/messagebox.h @@ -0,0 +1,17 @@ +#ifndef COSMOPOLITAN_LIBC_NT_MESSAGEBOX_H_ +#define COSMOPOLITAN_LIBC_NT_MESSAGEBOX_H_ +#include "libc/nt/enum/dialogresult.h" +#include "libc/nt/enum/messageboxtype.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +enum DialogResult MessageBox(int64_t hWnd, const char16_t *lpText, + const char16_t *lpCaption, + enum MessageBoxType uType); +enum DialogResult MessageBoxEx(int64_t hWnd, const char16_t *lpText, + const char16_t *lpCaption, + enum MessageBoxType uType, uint16_t wLanguageId); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_MESSAGEBOX_H_ */ diff --git a/libc/nt/netapi32/I_BrowserSetNetlogonState.s b/libc/nt/netapi32/I_BrowserSetNetlogonState.s new file mode 100644 index 00000000..21fd5a35 --- /dev/null +++ b/libc/nt/netapi32/I_BrowserSetNetlogonState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_I_BrowserSetNetlogonState,I_BrowserSetNetlogonState,34 diff --git a/libc/nt/netapi32/NetAccessAdd.s b/libc/nt/netapi32/NetAccessAdd.s new file mode 100644 index 00000000..58641fe9 --- /dev/null +++ b/libc/nt/netapi32/NetAccessAdd.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetAccessAdd,NetAccessAdd,71 diff --git a/libc/nt/netapi32/NetAccessDel.s b/libc/nt/netapi32/NetAccessDel.s new file mode 100644 index 00000000..2d586fde --- /dev/null +++ b/libc/nt/netapi32/NetAccessDel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetAccessDel,NetAccessDel,72 diff --git a/libc/nt/netapi32/NetAccessEnum.s b/libc/nt/netapi32/NetAccessEnum.s new file mode 100644 index 00000000..39ae2783 --- /dev/null +++ b/libc/nt/netapi32/NetAccessEnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetAccessEnum,NetAccessEnum,73 diff --git a/libc/nt/netapi32/NetAccessGetInfo.s b/libc/nt/netapi32/NetAccessGetInfo.s new file mode 100644 index 00000000..fa21f71e --- /dev/null +++ b/libc/nt/netapi32/NetAccessGetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetAccessGetInfo,NetAccessGetInfo,74 diff --git a/libc/nt/netapi32/NetAccessGetUserPerms.s b/libc/nt/netapi32/NetAccessGetUserPerms.s new file mode 100644 index 00000000..d00b357c --- /dev/null +++ b/libc/nt/netapi32/NetAccessGetUserPerms.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetAccessGetUserPerms,NetAccessGetUserPerms,75 diff --git a/libc/nt/netapi32/NetAccessSetInfo.s b/libc/nt/netapi32/NetAccessSetInfo.s new file mode 100644 index 00000000..0ce41176 --- /dev/null +++ b/libc/nt/netapi32/NetAccessSetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetAccessSetInfo,NetAccessSetInfo,76 diff --git a/libc/nt/netapi32/NetAlertRaise.s b/libc/nt/netapi32/NetAlertRaise.s new file mode 100644 index 00000000..a5e3b515 --- /dev/null +++ b/libc/nt/netapi32/NetAlertRaise.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetAlertRaise,NetAlertRaise,79 diff --git a/libc/nt/netapi32/NetAlertRaiseEx.s b/libc/nt/netapi32/NetAlertRaiseEx.s new file mode 100644 index 00000000..898ebc6d --- /dev/null +++ b/libc/nt/netapi32/NetAlertRaiseEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetAlertRaiseEx,NetAlertRaiseEx,80 diff --git a/libc/nt/netapi32/NetAuditClear.s b/libc/nt/netapi32/NetAuditClear.s new file mode 100644 index 00000000..8d19d51a --- /dev/null +++ b/libc/nt/netapi32/NetAuditClear.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetAuditClear,NetAuditClear,85 diff --git a/libc/nt/netapi32/NetAuditRead.s b/libc/nt/netapi32/NetAuditRead.s new file mode 100644 index 00000000..96641ff1 --- /dev/null +++ b/libc/nt/netapi32/NetAuditRead.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetAuditRead,NetAuditRead,86 diff --git a/libc/nt/netapi32/NetAuditWrite.s b/libc/nt/netapi32/NetAuditWrite.s new file mode 100644 index 00000000..a496bfc6 --- /dev/null +++ b/libc/nt/netapi32/NetAuditWrite.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetAuditWrite,NetAuditWrite,87 diff --git a/libc/nt/netapi32/NetConfigGet.s b/libc/nt/netapi32/NetConfigGet.s new file mode 100644 index 00000000..ceac0432 --- /dev/null +++ b/libc/nt/netapi32/NetConfigGet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetConfigGet,NetConfigGet,88 diff --git a/libc/nt/netapi32/NetConfigGetAll.s b/libc/nt/netapi32/NetConfigGetAll.s new file mode 100644 index 00000000..48276209 --- /dev/null +++ b/libc/nt/netapi32/NetConfigGetAll.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetConfigGetAll,NetConfigGetAll,89 diff --git a/libc/nt/netapi32/NetConfigSet.s b/libc/nt/netapi32/NetConfigSet.s new file mode 100644 index 00000000..1a1ff4c9 --- /dev/null +++ b/libc/nt/netapi32/NetConfigSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetConfigSet,NetConfigSet,90 diff --git a/libc/nt/netapi32/NetErrorLogClear.s b/libc/nt/netapi32/NetErrorLogClear.s new file mode 100644 index 00000000..eb49eaae --- /dev/null +++ b/libc/nt/netapi32/NetErrorLogClear.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetErrorLogClear,NetErrorLogClear,124 diff --git a/libc/nt/netapi32/NetErrorLogRead.s b/libc/nt/netapi32/NetErrorLogRead.s new file mode 100644 index 00000000..287f6d12 --- /dev/null +++ b/libc/nt/netapi32/NetErrorLogRead.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetErrorLogRead,NetErrorLogRead,125 diff --git a/libc/nt/netapi32/NetErrorLogWrite.s b/libc/nt/netapi32/NetErrorLogWrite.s new file mode 100644 index 00000000..3b2ae959 --- /dev/null +++ b/libc/nt/netapi32/NetErrorLogWrite.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetErrorLogWrite,NetErrorLogWrite,126 diff --git a/libc/nt/netapi32/NetMessageBufferSend.s b/libc/nt/netapi32/NetMessageBufferSend.s new file mode 100644 index 00000000..b536f662 --- /dev/null +++ b/libc/nt/netapi32/NetMessageBufferSend.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetMessageBufferSend,NetMessageBufferSend,161 diff --git a/libc/nt/netapi32/NetMessageNameAdd.s b/libc/nt/netapi32/NetMessageNameAdd.s new file mode 100644 index 00000000..10bf3bd8 --- /dev/null +++ b/libc/nt/netapi32/NetMessageNameAdd.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetMessageNameAdd,NetMessageNameAdd,162 diff --git a/libc/nt/netapi32/NetMessageNameDel.s b/libc/nt/netapi32/NetMessageNameDel.s new file mode 100644 index 00000000..74a42a6a --- /dev/null +++ b/libc/nt/netapi32/NetMessageNameDel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetMessageNameDel,NetMessageNameDel,163 diff --git a/libc/nt/netapi32/NetMessageNameEnum.s b/libc/nt/netapi32/NetMessageNameEnum.s new file mode 100644 index 00000000..438a6339 --- /dev/null +++ b/libc/nt/netapi32/NetMessageNameEnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetMessageNameEnum,NetMessageNameEnum,164 diff --git a/libc/nt/netapi32/NetMessageNameGetInfo.s b/libc/nt/netapi32/NetMessageNameGetInfo.s new file mode 100644 index 00000000..03c162d9 --- /dev/null +++ b/libc/nt/netapi32/NetMessageNameGetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetMessageNameGetInfo,NetMessageNameGetInfo,165 diff --git a/libc/nt/netapi32/NetRegisterDomainNameChangeNotification.s b/libc/nt/netapi32/NetRegisterDomainNameChangeNotification.s new file mode 100644 index 00000000..740b7c88 --- /dev/null +++ b/libc/nt/netapi32/NetRegisterDomainNameChangeNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetRegisterDomainNameChangeNotification,NetRegisterDomainNameChangeNotification,169 diff --git a/libc/nt/netapi32/NetReplExportDirAdd.s b/libc/nt/netapi32/NetReplExportDirAdd.s new file mode 100644 index 00000000..6b9dfa18 --- /dev/null +++ b/libc/nt/netapi32/NetReplExportDirAdd.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetReplExportDirAdd,NetReplExportDirAdd,175 diff --git a/libc/nt/netapi32/NetReplExportDirDel.s b/libc/nt/netapi32/NetReplExportDirDel.s new file mode 100644 index 00000000..31c0d35d --- /dev/null +++ b/libc/nt/netapi32/NetReplExportDirDel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetReplExportDirDel,NetReplExportDirDel,176 diff --git a/libc/nt/netapi32/NetReplExportDirEnum.s b/libc/nt/netapi32/NetReplExportDirEnum.s new file mode 100644 index 00000000..918e4e8c --- /dev/null +++ b/libc/nt/netapi32/NetReplExportDirEnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetReplExportDirEnum,NetReplExportDirEnum,177 diff --git a/libc/nt/netapi32/NetReplExportDirGetInfo.s b/libc/nt/netapi32/NetReplExportDirGetInfo.s new file mode 100644 index 00000000..2a48f7f2 --- /dev/null +++ b/libc/nt/netapi32/NetReplExportDirGetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetReplExportDirGetInfo,NetReplExportDirGetInfo,178 diff --git a/libc/nt/netapi32/NetReplExportDirLock.s b/libc/nt/netapi32/NetReplExportDirLock.s new file mode 100644 index 00000000..6d386476 --- /dev/null +++ b/libc/nt/netapi32/NetReplExportDirLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetReplExportDirLock,NetReplExportDirLock,179 diff --git a/libc/nt/netapi32/NetReplExportDirSetInfo.s b/libc/nt/netapi32/NetReplExportDirSetInfo.s new file mode 100644 index 00000000..a755c0d9 --- /dev/null +++ b/libc/nt/netapi32/NetReplExportDirSetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetReplExportDirSetInfo,NetReplExportDirSetInfo,180 diff --git a/libc/nt/netapi32/NetReplExportDirUnlock.s b/libc/nt/netapi32/NetReplExportDirUnlock.s new file mode 100644 index 00000000..0f027c79 --- /dev/null +++ b/libc/nt/netapi32/NetReplExportDirUnlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetReplExportDirUnlock,NetReplExportDirUnlock,181 diff --git a/libc/nt/netapi32/NetReplGetInfo.s b/libc/nt/netapi32/NetReplGetInfo.s new file mode 100644 index 00000000..823f8ea9 --- /dev/null +++ b/libc/nt/netapi32/NetReplGetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetReplGetInfo,NetReplGetInfo,182 diff --git a/libc/nt/netapi32/NetReplImportDirAdd.s b/libc/nt/netapi32/NetReplImportDirAdd.s new file mode 100644 index 00000000..5a4aba81 --- /dev/null +++ b/libc/nt/netapi32/NetReplImportDirAdd.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetReplImportDirAdd,NetReplImportDirAdd,183 diff --git a/libc/nt/netapi32/NetReplImportDirDel.s b/libc/nt/netapi32/NetReplImportDirDel.s new file mode 100644 index 00000000..10a41cbd --- /dev/null +++ b/libc/nt/netapi32/NetReplImportDirDel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetReplImportDirDel,NetReplImportDirDel,184 diff --git a/libc/nt/netapi32/NetReplImportDirEnum.s b/libc/nt/netapi32/NetReplImportDirEnum.s new file mode 100644 index 00000000..d94d65b8 --- /dev/null +++ b/libc/nt/netapi32/NetReplImportDirEnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetReplImportDirEnum,NetReplImportDirEnum,185 diff --git a/libc/nt/netapi32/NetReplImportDirGetInfo.s b/libc/nt/netapi32/NetReplImportDirGetInfo.s new file mode 100644 index 00000000..2092fb07 --- /dev/null +++ b/libc/nt/netapi32/NetReplImportDirGetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetReplImportDirGetInfo,NetReplImportDirGetInfo,186 diff --git a/libc/nt/netapi32/NetReplImportDirLock.s b/libc/nt/netapi32/NetReplImportDirLock.s new file mode 100644 index 00000000..3f0a861c --- /dev/null +++ b/libc/nt/netapi32/NetReplImportDirLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetReplImportDirLock,NetReplImportDirLock,187 diff --git a/libc/nt/netapi32/NetReplImportDirUnlock.s b/libc/nt/netapi32/NetReplImportDirUnlock.s new file mode 100644 index 00000000..0bfc94c0 --- /dev/null +++ b/libc/nt/netapi32/NetReplImportDirUnlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetReplImportDirUnlock,NetReplImportDirUnlock,188 diff --git a/libc/nt/netapi32/NetReplSetInfo.s b/libc/nt/netapi32/NetReplSetInfo.s new file mode 100644 index 00000000..07865ac9 --- /dev/null +++ b/libc/nt/netapi32/NetReplSetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetReplSetInfo,NetReplSetInfo,189 diff --git a/libc/nt/netapi32/NetServerEnum.s b/libc/nt/netapi32/NetServerEnum.s new file mode 100644 index 00000000..7ae85e1e --- /dev/null +++ b/libc/nt/netapi32/NetServerEnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetServerEnum,NetServerEnum,202 diff --git a/libc/nt/netapi32/NetServerEnumEx.s b/libc/nt/netapi32/NetServerEnumEx.s new file mode 100644 index 00000000..fee87183 --- /dev/null +++ b/libc/nt/netapi32/NetServerEnumEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetServerEnumEx,NetServerEnumEx,203 diff --git a/libc/nt/netapi32/NetServiceControl.s b/libc/nt/netapi32/NetServiceControl.s new file mode 100644 index 00000000..6e447ae6 --- /dev/null +++ b/libc/nt/netapi32/NetServiceControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetServiceControl,NetServiceControl,210 diff --git a/libc/nt/netapi32/NetServiceEnum.s b/libc/nt/netapi32/NetServiceEnum.s new file mode 100644 index 00000000..8eaca1c3 --- /dev/null +++ b/libc/nt/netapi32/NetServiceEnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetServiceEnum,NetServiceEnum,211 diff --git a/libc/nt/netapi32/NetServiceGetInfo.s b/libc/nt/netapi32/NetServiceGetInfo.s new file mode 100644 index 00000000..861e164b --- /dev/null +++ b/libc/nt/netapi32/NetServiceGetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetServiceGetInfo,NetServiceGetInfo,212 diff --git a/libc/nt/netapi32/NetServiceInstall.s b/libc/nt/netapi32/NetServiceInstall.s new file mode 100644 index 00000000..06666a4d --- /dev/null +++ b/libc/nt/netapi32/NetServiceInstall.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetServiceInstall,NetServiceInstall,213 diff --git a/libc/nt/netapi32/NetStatisticsGet.s b/libc/nt/netapi32/NetStatisticsGet.s new file mode 100644 index 00000000..03bf556a --- /dev/null +++ b/libc/nt/netapi32/NetStatisticsGet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetStatisticsGet,NetStatisticsGet,227 diff --git a/libc/nt/netapi32/NetUnregisterDomainNameChangeNotification.s b/libc/nt/netapi32/NetUnregisterDomainNameChangeNotification.s new file mode 100644 index 00000000..f0fb782b --- /dev/null +++ b/libc/nt/netapi32/NetUnregisterDomainNameChangeNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetUnregisterDomainNameChangeNotification,NetUnregisterDomainNameChangeNotification,229 diff --git a/libc/nt/netapi32/NetWkstaGetInfo.s b/libc/nt/netapi32/NetWkstaGetInfo.s new file mode 100644 index 00000000..aded82e6 --- /dev/null +++ b/libc/nt/netapi32/NetWkstaGetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetWkstaGetInfo,NetWkstaGetInfo,248 diff --git a/libc/nt/netapi32/NetWkstaSetInfo.s b/libc/nt/netapi32/NetWkstaSetInfo.s new file mode 100644 index 00000000..6e4b0de3 --- /dev/null +++ b/libc/nt/netapi32/NetWkstaSetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetWkstaSetInfo,NetWkstaSetInfo,249 diff --git a/libc/nt/netapi32/Netbios.s b/libc/nt/netapi32/Netbios.s new file mode 100644 index 00000000..6609c000 --- /dev/null +++ b/libc/nt/netapi32/Netbios.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_Netbios,Netbios,257 diff --git a/libc/nt/netapi32/NetpAddTlnFtinfoEntry.s b/libc/nt/netapi32/NetpAddTlnFtinfoEntry.s new file mode 100644 index 00000000..c0a91661 --- /dev/null +++ b/libc/nt/netapi32/NetpAddTlnFtinfoEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpAddTlnFtinfoEntry,NetpAddTlnFtinfoEntry,258 diff --git a/libc/nt/netapi32/NetpAllocFtinfoEntry.s b/libc/nt/netapi32/NetpAllocFtinfoEntry.s new file mode 100644 index 00000000..1df7637b --- /dev/null +++ b/libc/nt/netapi32/NetpAllocFtinfoEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpAllocFtinfoEntry,NetpAllocFtinfoEntry,259 diff --git a/libc/nt/netapi32/NetpAssertFailed.s b/libc/nt/netapi32/NetpAssertFailed.s new file mode 100644 index 00000000..a88f6224 --- /dev/null +++ b/libc/nt/netapi32/NetpAssertFailed.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpAssertFailed,NetpAssertFailed,260 diff --git a/libc/nt/netapi32/NetpCleanFtinfoContext.s b/libc/nt/netapi32/NetpCleanFtinfoContext.s new file mode 100644 index 00000000..d9bf47a9 --- /dev/null +++ b/libc/nt/netapi32/NetpCleanFtinfoContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpCleanFtinfoContext,NetpCleanFtinfoContext,261 diff --git a/libc/nt/netapi32/NetpCloseConfigData.s b/libc/nt/netapi32/NetpCloseConfigData.s new file mode 100644 index 00000000..85208671 --- /dev/null +++ b/libc/nt/netapi32/NetpCloseConfigData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpCloseConfigData,NetpCloseConfigData,262 diff --git a/libc/nt/netapi32/NetpCopyFtinfoContext.s b/libc/nt/netapi32/NetpCopyFtinfoContext.s new file mode 100644 index 00000000..daf86ce1 --- /dev/null +++ b/libc/nt/netapi32/NetpCopyFtinfoContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpCopyFtinfoContext,NetpCopyFtinfoContext,263 diff --git a/libc/nt/netapi32/NetpDbgPrint.s b/libc/nt/netapi32/NetpDbgPrint.s new file mode 100644 index 00000000..fc1e4374 --- /dev/null +++ b/libc/nt/netapi32/NetpDbgPrint.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpDbgPrint,NetpDbgPrint,264 diff --git a/libc/nt/netapi32/NetpGetConfigBool.s b/libc/nt/netapi32/NetpGetConfigBool.s new file mode 100644 index 00000000..e7e7dfd2 --- /dev/null +++ b/libc/nt/netapi32/NetpGetConfigBool.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpGetConfigBool,NetpGetConfigBool,265 diff --git a/libc/nt/netapi32/NetpGetConfigDword.s b/libc/nt/netapi32/NetpGetConfigDword.s new file mode 100644 index 00000000..ca17c618 --- /dev/null +++ b/libc/nt/netapi32/NetpGetConfigDword.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpGetConfigDword,NetpGetConfigDword,266 diff --git a/libc/nt/netapi32/NetpGetConfigTStrArray.s b/libc/nt/netapi32/NetpGetConfigTStrArray.s new file mode 100644 index 00000000..982c5165 --- /dev/null +++ b/libc/nt/netapi32/NetpGetConfigTStrArray.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpGetConfigTStrArray,NetpGetConfigTStrArray,267 diff --git a/libc/nt/netapi32/NetpGetConfigValue.s b/libc/nt/netapi32/NetpGetConfigValue.s new file mode 100644 index 00000000..fde79467 --- /dev/null +++ b/libc/nt/netapi32/NetpGetConfigValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpGetConfigValue,NetpGetConfigValue,268 diff --git a/libc/nt/netapi32/NetpGetFileSecurity.s b/libc/nt/netapi32/NetpGetFileSecurity.s new file mode 100644 index 00000000..b9b027bc --- /dev/null +++ b/libc/nt/netapi32/NetpGetFileSecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpGetFileSecurity,NetpGetFileSecurity,269 diff --git a/libc/nt/netapi32/NetpHexDump.s b/libc/nt/netapi32/NetpHexDump.s new file mode 100644 index 00000000..245ac3b1 --- /dev/null +++ b/libc/nt/netapi32/NetpHexDump.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpHexDump,NetpHexDump,270 diff --git a/libc/nt/netapi32/NetpInitFtinfoContext.s b/libc/nt/netapi32/NetpInitFtinfoContext.s new file mode 100644 index 00000000..a9f58554 --- /dev/null +++ b/libc/nt/netapi32/NetpInitFtinfoContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpInitFtinfoContext,NetpInitFtinfoContext,271 diff --git a/libc/nt/netapi32/NetpIsUncComputerNameValid.s b/libc/nt/netapi32/NetpIsUncComputerNameValid.s new file mode 100644 index 00000000..44be4bbe --- /dev/null +++ b/libc/nt/netapi32/NetpIsUncComputerNameValid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpIsUncComputerNameValid,NetpIsUncComputerNameValid,273 diff --git a/libc/nt/netapi32/NetpMergeFtinfo.s b/libc/nt/netapi32/NetpMergeFtinfo.s new file mode 100644 index 00000000..e1e9d93b --- /dev/null +++ b/libc/nt/netapi32/NetpMergeFtinfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpMergeFtinfo,NetpMergeFtinfo,274 diff --git a/libc/nt/netapi32/NetpNetBiosReset.s b/libc/nt/netapi32/NetpNetBiosReset.s new file mode 100644 index 00000000..8e196bae --- /dev/null +++ b/libc/nt/netapi32/NetpNetBiosReset.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpNetBiosReset,NetpNetBiosReset,275 diff --git a/libc/nt/netapi32/NetpNetBiosStatusToApiStatus.s b/libc/nt/netapi32/NetpNetBiosStatusToApiStatus.s new file mode 100644 index 00000000..41ac7f71 --- /dev/null +++ b/libc/nt/netapi32/NetpNetBiosStatusToApiStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpNetBiosStatusToApiStatus,NetpNetBiosStatusToApiStatus,276 diff --git a/libc/nt/netapi32/NetpOpenConfigData.s b/libc/nt/netapi32/NetpOpenConfigData.s new file mode 100644 index 00000000..264c088e --- /dev/null +++ b/libc/nt/netapi32/NetpOpenConfigData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpOpenConfigData,NetpOpenConfigData,277 diff --git a/libc/nt/netapi32/NetpSetFileSecurity.s b/libc/nt/netapi32/NetpSetFileSecurity.s new file mode 100644 index 00000000..99d5e374 --- /dev/null +++ b/libc/nt/netapi32/NetpSetFileSecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_NetpSetFileSecurity,NetpSetFileSecurity,278 diff --git a/libc/nt/netapi32/RxNetAccessAdd.s b/libc/nt/netapi32/RxNetAccessAdd.s new file mode 100644 index 00000000..ea3d3db9 --- /dev/null +++ b/libc/nt/netapi32/RxNetAccessAdd.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_RxNetAccessAdd,RxNetAccessAdd,288 diff --git a/libc/nt/netapi32/RxNetAccessDel.s b/libc/nt/netapi32/RxNetAccessDel.s new file mode 100644 index 00000000..726e9e77 --- /dev/null +++ b/libc/nt/netapi32/RxNetAccessDel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_RxNetAccessDel,RxNetAccessDel,289 diff --git a/libc/nt/netapi32/RxNetAccessEnum.s b/libc/nt/netapi32/RxNetAccessEnum.s new file mode 100644 index 00000000..ee99b768 --- /dev/null +++ b/libc/nt/netapi32/RxNetAccessEnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_RxNetAccessEnum,RxNetAccessEnum,290 diff --git a/libc/nt/netapi32/RxNetAccessGetInfo.s b/libc/nt/netapi32/RxNetAccessGetInfo.s new file mode 100644 index 00000000..1b9f5a82 --- /dev/null +++ b/libc/nt/netapi32/RxNetAccessGetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_RxNetAccessGetInfo,RxNetAccessGetInfo,291 diff --git a/libc/nt/netapi32/RxNetAccessGetUserPerms.s b/libc/nt/netapi32/RxNetAccessGetUserPerms.s new file mode 100644 index 00000000..d0bd31ba --- /dev/null +++ b/libc/nt/netapi32/RxNetAccessGetUserPerms.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_RxNetAccessGetUserPerms,RxNetAccessGetUserPerms,292 diff --git a/libc/nt/netapi32/RxNetAccessSetInfo.s b/libc/nt/netapi32/RxNetAccessSetInfo.s new file mode 100644 index 00000000..44c5db7e --- /dev/null +++ b/libc/nt/netapi32/RxNetAccessSetInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_RxNetAccessSetInfo,RxNetAccessSetInfo,293 diff --git a/libc/nt/netapi32/RxNetServerEnum.s b/libc/nt/netapi32/RxNetServerEnum.s new file mode 100644 index 00000000..e94802e5 --- /dev/null +++ b/libc/nt/netapi32/RxNetServerEnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_RxNetServerEnum,RxNetServerEnum,294 diff --git a/libc/nt/netapi32/RxNetUserPasswordSet.s b/libc/nt/netapi32/RxNetUserPasswordSet.s new file mode 100644 index 00000000..3a8b31a3 --- /dev/null +++ b/libc/nt/netapi32/RxNetUserPasswordSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_RxNetUserPasswordSet,RxNetUserPasswordSet,295 diff --git a/libc/nt/netapi32/RxRemoteApi.s b/libc/nt/netapi32/RxRemoteApi.s new file mode 100644 index 00000000..cdb316f3 --- /dev/null +++ b/libc/nt/netapi32/RxRemoteApi.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp netapi32,__imp_RxRemoteApi,RxRemoteApi,296 diff --git a/libc/nt/nt.mk b/libc/nt/nt.mk new file mode 100644 index 00000000..c4478934 --- /dev/null +++ b/libc/nt/nt.mk @@ -0,0 +1,306 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += LIBC_NT + +LIBC_NT_LIBS = $(foreach x,$(LIBC_NT_ARTIFACTS),$($(x))) +LIBC_NT_HDRS = $(foreach x,$(LIBC_NT_ARTIFACTS),$($(x)_HDRS)) +LIBC_NT_SRCS = $(foreach x,$(LIBC_NT_ARTIFACTS),$($(x)_SRCS)) +LIBC_NT_OBJS = $(foreach x,$(LIBC_NT_ARTIFACTS),$($(x)_OBJS)) +LIBC_NT_CHECKS = $(foreach x,$(LIBC_NT_ARTIFACTS),$($(x)_CHECKS)) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_NT_ARTIFACTS += LIBC_NT_A + +LIBC_NT_A_FILES := \ + $(wildcard libc/nt/enum/*) \ + $(wildcard libc/nt/struct/*) \ + $(wildcard libc/nt/typedef/*) \ + $(wildcard libc/nt/thunk/*) \ + $(wildcard libc/nt/nt/thunk/*) \ + $(wildcard libc/nt/nt/*.*) \ + $(wildcard libc/nt/*) + +LIBC_NT_A_HDRS = \ + $(filter %.h,$(LIBC_NT_A_FILES)) + +LIBC_NT_A_CHECKS = $(patsubst %,o/$(MODE)/%.ok,$(filter %.h,$(LIBC_NT_A_HDRS))) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_NT_ARTIFACTS += LIBC_NT_KERNEL32_A +LIBC_NT_KERNEL32 = $(LIBC_NT_KERNEL32_A_DEPS) $(LIBC_NT_KERNEL32_A) +LIBC_NT_KERNEL32_A = o/$(MODE)/libc/nt/kernel32.a +LIBC_NT_KERNEL32_A_SRCS := $(wildcard libc/nt/kernel32/*.s) +LIBC_NT_KERNEL32_A_OBJS = $(LIBC_NT_KERNEL32_A_SRCS:%.s=o/$(MODE)/%.o) +LIBC_NT_KERNEL32_A_CHECKS = $(LIBC_NT_KERNEL32_A).pkg +LIBC_NT_KERNEL32_A_DIRECTDEPS = LIBC_STUBS LIBC_NEXGEN32E +LIBC_NT_KERNEL32_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_NT_KERNEL32_A_DIRECTDEPS),$($(x)))) + +$(LIBC_NT_KERNEL32_A): \ + libc/nt/kernel32/ \ + $(LIBC_NT_KERNEL32_A).pkg \ + $(LIBC_NT_KERNEL32_A_OBJS) + +$(LIBC_NT_KERNEL32_A).pkg: \ + $(LIBC_NT_KERNEL32_A_OBJS) \ + $(foreach x,$(LIBC_NT_KERNEL32_A_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_NT_ARTIFACTS += LIBC_NT_ADVAPI32_A +LIBC_NT_ADVAPI32 = $(LIBC_NT_ADVAPI32_A_DEPS) $(LIBC_NT_ADVAPI32_A) +LIBC_NT_ADVAPI32_A = o/$(MODE)/libc/nt/advapi32.a +LIBC_NT_ADVAPI32_A_SRCS := $(wildcard libc/nt/advapi32/*.s) +LIBC_NT_ADVAPI32_A_OBJS = $(LIBC_NT_ADVAPI32_A_SRCS:%.s=o/$(MODE)/%.o) +LIBC_NT_ADVAPI32_A_CHECKS = $(LIBC_NT_ADVAPI32_A).pkg +LIBC_NT_ADVAPI32_A_DIRECTDEPS = LIBC_STUBS LIBC_NEXGEN32E +LIBC_NT_ADVAPI32_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_NT_ADVAPI32_A_DIRECTDEPS),$($(x)))) + +$(LIBC_NT_ADVAPI32_A): \ + libc/nt/advapi32/ \ + $(LIBC_NT_ADVAPI32_A).pkg \ + $(LIBC_NT_ADVAPI32_A_OBJS) + +$(LIBC_NT_ADVAPI32_A).pkg: \ + $(LIBC_NT_ADVAPI32_A_OBJS) \ + $(foreach x,$(LIBC_NT_ADVAPI32_A_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_NT_ARTIFACTS += LIBC_NT_COMDLG32_A +LIBC_NT_COMDLG32 = $(LIBC_NT_COMDLG32_A_DEPS) $(LIBC_NT_COMDLG32_A) +LIBC_NT_COMDLG32_A = o/$(MODE)/libc/nt/comdlg32.a +LIBC_NT_COMDLG32_A_SRCS := $(wildcard libc/nt/comdlg32/*.s) +LIBC_NT_COMDLG32_A_OBJS = $(LIBC_NT_COMDLG32_A_SRCS:%.s=o/$(MODE)/%.o) +LIBC_NT_COMDLG32_A_CHECKS = $(LIBC_NT_COMDLG32_A).pkg +LIBC_NT_COMDLG32_A_DIRECTDEPS = LIBC_STUBS LIBC_NEXGEN32E +LIBC_NT_COMDLG32_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_NT_COMDLG32_A_DIRECTDEPS),$($(x)))) + +$(LIBC_NT_COMDLG32_A): \ + libc/nt/comdlg32/ \ + $(LIBC_NT_COMDLG32_A).pkg \ + $(LIBC_NT_COMDLG32_A_OBJS) + +$(LIBC_NT_COMDLG32_A).pkg: \ + $(LIBC_NT_COMDLG32_A_OBJS) \ + $(foreach x,$(LIBC_NT_COMDLG32_A_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_NT_ARTIFACTS += LIBC_NT_GDI32_A +LIBC_NT_GDI32 = $(LIBC_NT_GDI32_A_DEPS) $(LIBC_NT_GDI32_A) +LIBC_NT_GDI32_A = o/$(MODE)/libc/nt/gdi32.a +LIBC_NT_GDI32_A_SRCS := $(wildcard libc/nt/gdi32/*.s) +LIBC_NT_GDI32_A_OBJS = $(LIBC_NT_GDI32_A_SRCS:%.s=o/$(MODE)/%.o) +LIBC_NT_GDI32_A_CHECKS = $(LIBC_NT_GDI32_A).pkg +LIBC_NT_GDI32_A_DIRECTDEPS = LIBC_STUBS LIBC_NEXGEN32E +LIBC_NT_GDI32_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_NT_GDI32_A_DIRECTDEPS),$($(x)))) + +$(LIBC_NT_GDI32_A): \ + libc/nt/gdi32/ \ + $(LIBC_NT_GDI32_A).pkg \ + $(LIBC_NT_GDI32_A_OBJS) + +$(LIBC_NT_GDI32_A).pkg: \ + $(LIBC_NT_GDI32_A_OBJS) \ + $(foreach x,$(LIBC_NT_GDI32_A_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_NT_ARTIFACTS += LIBC_NT_KERNELBASE_A +LIBC_NT_KERNELBASE = $(LIBC_NT_KERNELBASE_A_DEPS) $(LIBC_NT_KERNELBASE_A) +LIBC_NT_KERNELBASE_A = o/$(MODE)/libc/nt/KernelBase.a +LIBC_NT_KERNELBASE_A_SRCS := $(wildcard libc/nt/KernelBase/*.s) +LIBC_NT_KERNELBASE_A_OBJS = $(LIBC_NT_KERNELBASE_A_SRCS:%.s=o/$(MODE)/%.o) +LIBC_NT_KERNELBASE_A_CHECKS = $(LIBC_NT_KERNELBASE_A).pkg +LIBC_NT_KERNELBASE_A_DIRECTDEPS = LIBC_STUBS LIBC_NEXGEN32E +LIBC_NT_KERNELBASE_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_NT_KERNELBASE_A_DIRECTDEPS),$($(x)))) + +$(LIBC_NT_KERNELBASE_A): \ + libc/nt/KernelBase/ \ + $(LIBC_NT_KERNELBASE_A).pkg \ + $(LIBC_NT_KERNELBASE_A_OBJS) + +$(LIBC_NT_KERNELBASE_A).pkg: \ + $(LIBC_NT_KERNELBASE_A_OBJS) \ + $(foreach x,$(LIBC_NT_KERNELBASE_A_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_NT_ARTIFACTS += LIBC_NT_NTDLL_A +LIBC_NT_NTDLL = $(LIBC_NT_NTDLL_A_DEPS) $(LIBC_NT_NTDLL_A) +LIBC_NT_NTDLL_A = o/$(MODE)/libc/nt/ntdll.a +LIBC_NT_NTDLL_A_SRCS_A := $(wildcard libc/nt/ntdll/*.s) +LIBC_NT_NTDLL_A_SRCS_S = libc/nt/ntdllimport.S +LIBC_NT_NTDLL_A_SRCS = $(LIBC_NT_NTDLL_A_SRCS_A) $(LIBC_NT_NTDLL_A_SRCS_S) +LIBC_NT_NTDLL_A_OBJS = \ + $(LIBC_NT_NTDLL_A_SRCS_A:%.s=o/$(MODE)/%.o) \ + $(LIBC_NT_NTDLL_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_NT_NTDLL_A_SRCS:%=o/$(MODE)/%.zip.o) +LIBC_NT_NTDLL_A_CHECKS = $(LIBC_NT_NTDLL_A).pkg +LIBC_NT_NTDLL_A_DIRECTDEPS = LIBC_STUBS LIBC_NEXGEN32E LIBC_NT_KERNELBASE +LIBC_NT_NTDLL_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_NT_NTDLL_A_DIRECTDEPS),$($(x)))) + +$(LIBC_NT_NTDLL_A): \ + libc/nt/ntdll/ \ + $(LIBC_NT_NTDLL_A).pkg \ + $(LIBC_NT_NTDLL_A_OBJS) + +$(LIBC_NT_NTDLL_A).pkg: \ + $(LIBC_NT_NTDLL_A_OBJS) \ + $(foreach x,$(LIBC_NT_NTDLL_A_DIRECTDEPS),$($(x)_A).pkg) + +$(LIBC_NT_NTDLL_A_OBJS): \ + o/libc/nt/ntdllimport.inc + +o/libc/nt/ntdllimport.inc: \ + ape/relocations.h \ + libc/nt/ntdllimport.h \ + libc/macros.h \ + libc/macros.inc \ + libc/macros-cpp.inc + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_NT_ARTIFACTS += LIBC_NT_NETAPI32_A +LIBC_NT_NETAPI32 = $(LIBC_NT_NETAPI32_A_DEPS) $(LIBC_NT_NETAPI32_A) +LIBC_NT_NETAPI32_A = o/$(MODE)/libc/nt/netapi32.a +LIBC_NT_NETAPI32_A_SRCS := $(wildcard libc/nt/netapi32/*.s) +LIBC_NT_NETAPI32_A_OBJS = $(LIBC_NT_NETAPI32_A_SRCS:%.s=o/$(MODE)/%.o) +LIBC_NT_NETAPI32_A_CHECKS = $(LIBC_NT_NETAPI32_A).pkg +LIBC_NT_NETAPI32_A_DIRECTDEPS = LIBC_STUBS LIBC_NEXGEN32E +LIBC_NT_NETAPI32_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_NT_NETAPI32_A_DIRECTDEPS),$($(x)))) + +$(LIBC_NT_NETAPI32_A): \ + libc/nt/netapi32/ \ + $(LIBC_NT_NETAPI32_A).pkg \ + $(LIBC_NT_NETAPI32_A_OBJS) + +$(LIBC_NT_NETAPI32_A).pkg: \ + $(LIBC_NT_NETAPI32_A_OBJS) \ + $(foreach x,$(LIBC_NT_NETAPI32_A_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_NT_ARTIFACTS += LIBC_NT_URL_A +LIBC_NT_URL = $(LIBC_NT_URL_A_DEPS) $(LIBC_NT_URL_A) +LIBC_NT_URL_A = o/$(MODE)/libc/nt/url.a +LIBC_NT_URL_A_SRCS := $(wildcard libc/nt/url/*.s) +LIBC_NT_URL_A_OBJS = $(LIBC_NT_URL_A_SRCS:%.s=o/$(MODE)/%.o) +LIBC_NT_URL_A_CHECKS = $(LIBC_NT_URL_A).pkg +LIBC_NT_URL_A_DIRECTDEPS = LIBC_STUBS LIBC_NEXGEN32E +LIBC_NT_URL_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_NT_URL_A_DIRECTDEPS),$($(x)))) + +$(LIBC_NT_URL_A): \ + libc/nt/url/ \ + $(LIBC_NT_URL_A).pkg \ + $(LIBC_NT_URL_A_OBJS) + +$(LIBC_NT_URL_A).pkg: \ + $(LIBC_NT_URL_A_OBJS) \ + $(foreach x,$(LIBC_NT_URL_A_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_NT_ARTIFACTS += LIBC_NT_USER32_A +LIBC_NT_USER32 = $(LIBC_NT_USER32_A_DEPS) $(LIBC_NT_USER32_A) +LIBC_NT_USER32_A = o/$(MODE)/libc/nt/user32.a +LIBC_NT_USER32_A_SRCS := $(wildcard libc/nt/user32/*.s) +LIBC_NT_USER32_A_OBJS = $(LIBC_NT_USER32_A_SRCS:%.s=o/$(MODE)/%.o) +LIBC_NT_USER32_A_CHECKS = $(LIBC_NT_USER32_A).pkg +LIBC_NT_USER32_A_DIRECTDEPS = LIBC_STUBS LIBC_NEXGEN32E +LIBC_NT_USER32_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_NT_USER32_A_DIRECTDEPS),$($(x)))) + +$(LIBC_NT_USER32_A): \ + libc/nt/user32/ \ + $(LIBC_NT_USER32_A).pkg \ + $(LIBC_NT_USER32_A_OBJS) + +$(LIBC_NT_USER32_A).pkg: \ + $(LIBC_NT_USER32_A_OBJS) \ + $(foreach x,$(LIBC_NT_USER32_A_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_NT_ARTIFACTS += LIBC_NT_WS2_32_A +LIBC_NT_WS2_32 = $(LIBC_NT_WS2_32_A_DEPS) $(LIBC_NT_WS2_32_A) +LIBC_NT_WS2_32_A = o/$(MODE)/libc/nt/ws2_32.a +LIBC_NT_WS2_32_A_SRCS := $(wildcard libc/nt/ws2_32/*.s) +LIBC_NT_WS2_32_A_OBJS = $(LIBC_NT_WS2_32_A_SRCS:%.s=o/$(MODE)/%.o) +LIBC_NT_WS2_32_A_CHECKS = $(LIBC_NT_WS2_32_A).pkg +LIBC_NT_WS2_32_A_DIRECTDEPS = LIBC_STUBS LIBC_NEXGEN32E +LIBC_NT_WS2_32_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_NT_WS2_32_A_DIRECTDEPS),$($(x)))) + +$(LIBC_NT_WS2_32_A): \ + libc/nt/ws2_32/ \ + $(LIBC_NT_WS2_32_A).pkg \ + $(LIBC_NT_WS2_32_A_OBJS) + +$(LIBC_NT_WS2_32_A).pkg: \ + $(LIBC_NT_WS2_32_A_OBJS) \ + $(foreach x,$(LIBC_NT_WS2_32_A_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_NT_ARTIFACTS += LIBC_NT_MSWSOCK_A +LIBC_NT_MSWSOCK = $(LIBC_NT_MSWSOCK_A_DEPS) $(LIBC_NT_MSWSOCK_A) +LIBC_NT_MSWSOCK_A = o/$(MODE)/libc/nt/MsWSock.a +LIBC_NT_MSWSOCK_A_SRCS := $(wildcard libc/nt/MsWSock/*.s) +LIBC_NT_MSWSOCK_A_OBJS = $(LIBC_NT_MSWSOCK_A_SRCS:%.s=o/$(MODE)/%.o) +LIBC_NT_MSWSOCK_A_CHECKS = $(LIBC_NT_MSWSOCK_A).pkg +LIBC_NT_MSWSOCK_A_DIRECTDEPS = LIBC_STUBS LIBC_NEXGEN32E +LIBC_NT_MSWSOCK_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_NT_MSWSOCK_A_DIRECTDEPS),$($(x)))) + +$(LIBC_NT_MSWSOCK_A): \ + libc/nt/MsWSock/ \ + $(LIBC_NT_MSWSOCK_A).pkg \ + $(LIBC_NT_MSWSOCK_A_OBJS) + +$(LIBC_NT_MSWSOCK_A).pkg: \ + $(LIBC_NT_MSWSOCK_A_OBJS) \ + $(foreach x,$(LIBC_NT_MSWSOCK_A_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_NT_ARTIFACTS += LIBC_NT_SHELL32_A +LIBC_NT_SHELL32 = $(LIBC_NT_SHELL32_A_DEPS) $(LIBC_NT_SHELL32_A) +LIBC_NT_SHELL32_A = o/$(MODE)/libc/nt/shell32.a +LIBC_NT_SHELL32_A_SRCS := $(wildcard libc/nt/shell32/*.s) +LIBC_NT_SHELL32_A_OBJS = $(LIBC_NT_SHELL32_A_SRCS:%.s=o/$(MODE)/%.o) +LIBC_NT_SHELL32_A_CHECKS = $(LIBC_NT_SHELL32_A).pkg +LIBC_NT_SHELL32_A_DIRECTDEPS = LIBC_STUBS LIBC_NEXGEN32E +LIBC_NT_SHELL32_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_NT_SHELL32_A_DIRECTDEPS),$($(x)))) +$(LIBC_NT_SHELL32_A): \ + libc/nt/shell32/ \ + $(LIBC_NT_SHELL32_A).pkg \ + $(LIBC_NT_SHELL32_A_OBJS) +$(LIBC_NT_SHELL32_A).pkg: \ + $(LIBC_NT_SHELL32_A_OBJS) \ + $(foreach x,$(LIBC_NT_SHELL32_A_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + +$(LIBC_NT_OBJS): libc/nt/nt.mk o/libc/nt/codegen.inc + +.PHONY: o/libc/nt +o/libc/nt: $(LIBC_NT_LIBS) \ + $(LIBC_NT_CHECKS) + +.PHONY: o/$(MODE)/libc/nt +o/$(MODE)/libc/nt: \ + $(LIBC_NT_LIBS) \ + $(LIBC_NT_CHECKS) diff --git a/libc/nt/nt/debug.h b/libc/nt/nt/debug.h new file mode 100644 index 00000000..2145af1a --- /dev/null +++ b/libc/nt/nt/debug.h @@ -0,0 +1,43 @@ +#ifndef COSMOPOLITAN_LIBC_NT_NT_DEBUG_H_ +#define COSMOPOLITAN_LIBC_NT_NT_DEBUG_H_ +#include "libc/nt/enum/status.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » beyond the pale » debugging ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + “The functions and structures in [for these APIs] are internal to + the operating system and subject to change from one release of + Windows to the next, and possibly even between service packs for + each release.” ──Quoth MSDN */ +#endif + +struct NtContext; + +NtStatus NtContinue(struct NtContext *Context, int32_t TestAlert); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_NT_DEBUG_H_ */ diff --git a/libc/nt/nt/file.h b/libc/nt/nt/file.h new file mode 100644 index 00000000..313ac511 --- /dev/null +++ b/libc/nt/nt/file.h @@ -0,0 +1,81 @@ +#ifndef COSMOPOLITAN_LIBC_NT_NT_FILE_H_ +#define COSMOPOLITAN_LIBC_NT_NT_FILE_H_ +#include "libc/nt/enum/fileinformationclass.h" +#include "libc/nt/enum/status.h" +#include "libc/nt/thunk/msabi.h" +#include "libc/nt/typedef/ioapcroutine.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » beyond the pale » files ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + “The functions and structures in [for these APIs] are internal to + the operating system and subject to change from one release of + Windows to the next, and possibly even between service packs for + each release.” ──Quoth MSDN */ +#endif + +struct NtIoStatusBlock; +struct NtObjectAttributes; + +NtStatus NtCreateFile(int64_t *out_FileHandle, uint32_t DesiredAccess, + struct NtObjectAttributes *ObjectAttributes, + struct NtIoStatusBlock *out_IoStatusBlock, + int64_t *opt_AllocationSize, uint32_t FileAttributes, + uint32_t ShareAccess, uint32_t CreateDisposition, + uint32_t CreateOptions, void *opt_EaBuffer, + uint32_t EaLength); +NtStatus NtReadFile(int64_t FileHandle, void *opt_Event, + NtIoApcRoutine opt_ApcRoutine, void *opt_ApcContext, + struct NtIoStatusBlock *out_IoStatusBlock, void *out_Buffer, + uint32_t Length, int64_t *opt_ByteOffset, + uint32_t *opt_Key); +NtStatus NtWriteFile(int64_t FileHandle, void *opt_Event, + NtIoApcRoutine opt_ApcRoutine, void *opt_ApcContext, + struct NtIoStatusBlock *out_IoStatusBlock, + const void *Buffer, uint32_t Length, + int64_t *opt_ByteOffset, uint32_t *opt_Key); +NtStatus NtClose(int64_t handle); +NtStatus NtDuplicateObject(int64_t SourceProcessHandle, void *SourceHandle, + void *TargetProcessHandle, + void **opt_out_TargetHandle, uint32_t DesiredAcess, + uint32_t Atrributes, uint32_t options_t); +NtStatus NtQueryInformationFile(int64_t FileHandle, + struct NtIoStatusBlock *out_IoStatusBlock, + void *out_FileInformation, + uint32_t FileInformationLength, + uint32_t FileInformationClass); +NtStatus NtSetInformationFile(int64_t FileHandle, + struct NtIoStatusBlock *out_IoStatusBlock, + void *FileInformation, + uint32_t FileInformationLength, + uint32_t FileInformationClass); + +#if ShouldUseMsabiAttribute() +#include "libc/nt/thunk/ntfile.inc" +#endif /* ShouldUseMsabiAttribute() */ +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_NT_FILE_H_ */ diff --git a/libc/nt/nt/ipc.h b/libc/nt/nt/ipc.h new file mode 100644 index 00000000..f60657b8 --- /dev/null +++ b/libc/nt/nt/ipc.h @@ -0,0 +1,52 @@ +#ifndef COSMOPOLITAN_LIBC_NT_NT_IPC_H_ +#define COSMOPOLITAN_LIBC_NT_NT_IPC_H_ +#include "libc/nt/enum/status.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » beyond the pale » ipc ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + “The functions and structures in [for these APIs] are internal to + the operating system and subject to change from one release of + Windows to the next, and possibly even between service packs for + each release.” ──Quoth MSDN */ +#endif + +struct NtIoStatusBlock; +struct NtObjectAttributes; + +NtStatus NtCreateNamedPipeFile(int64_t *out_FileHandle, uint32_t DesiredAccess, + struct NtObjectAttributes *ObjectAttributes, + struct NtIoStatusBlock *out_IoStatusBlock, + uint32_t ShareAccess, uint32_t CreateDisposition, + uint32_t CreateOptions, int32_t TypeMessage, + int32_t ReadmodeMessage, int32_t Nonblocking, + uint32_t MaxInstances, uint32_t InBufferSize, + uint32_t OutBufferSize, + int64_t *opt_DefaultTimeout); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_NT_IPC_H_ */ diff --git a/libc/nt/nt/loader.h b/libc/nt/nt/loader.h new file mode 100644 index 00000000..523d160f --- /dev/null +++ b/libc/nt/nt/loader.h @@ -0,0 +1,58 @@ +#ifndef COSMOPOLITAN_LIBC_NT_NT_LOADER_H_ +#define COSMOPOLITAN_LIBC_NT_NT_LOADER_H_ +#include "libc/nt/enum/status.h" +#include "libc/nt/typedef/wambda.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » beyond the pale » loader ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + “The functions and structures in [for these APIs] are internal to + the operating system and subject to change from one release of + Windows to the next, and possibly even between service packs for + each release.” ──Quoth MSDN */ +#endif + +struct NtAnsiString; +struct NtLdrDataTableEntry; +struct NtUnicodeString; + +const struct NtLdrDataTableEntry *NtGetModule(const char *basename) nothrow; + +NtStatus LdrLoadDll(const char16_t *opt_PathToFile, uint32_t *opt_Flags, + struct NtUnicodeString *ModuleFileName, + void **out_ModuleHandle); +NtStatus LdrUnloadDll(void *ModuleHandle); +NtStatus LdrGetProcedureAddress(void *ModuleHandle, + struct NtAnsiString *opt_ProcedureName, + uint32_t opt_Ordinal, + wambda *out_ProcedureAddress); +NtStatus LdrGetDllHandle(const char16_t *opt_PathToFile, uint32_t opt_Unused, + struct NtUnicodeString *ModuleFileName, + void **out_ModuleHandle); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_NT_LOADER_H_ */ diff --git a/libc/nt/nt/memory.h b/libc/nt/nt/memory.h new file mode 100644 index 00000000..3934d7a9 --- /dev/null +++ b/libc/nt/nt/memory.h @@ -0,0 +1,59 @@ +#ifndef COSMOPOLITAN_LIBC_NT_NT_MEMORY_H_ +#define COSMOPOLITAN_LIBC_NT_NT_MEMORY_H_ +#include "libc/nt/enum/memoryinformationclass.h" +#include "libc/nt/enum/status.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » beyond the pale » memory ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + “The functions and structures in [for these APIs] are internal to + the operating system and subject to change from one release of + Windows to the next, and possibly even between service packs for + each release.” ──Quoth MSDN */ +#endif + +NtStatus NtAllocateVirtualMemory(int64_t ProcessHandle, + void **inout_BaseAddress, uint32_t dwZeroBits, + uint32_t *inout_AllocationSize, + uint32_t dwMemAllocationType, + uint32_t dwPageProtect); +NtStatus NtFreeVirtualMemory(int64_t ProcessHandle, void **inout_BaseAddress, + size_t *inout_FreeSize, uint32_t FreeType); +NtStatus NtQueryVirtualMemory( + int64_t ProcessHandle, const void *BaseAddress, + enum NtMemoryInformationClass MemoryInformationClass, + void *out_MemoryInformation, size_t MemoryInformationLength, + size_t *opt_out_ReturnLength); +NtStatus NtProtectVirtualMemory(int64_t ProcessHandle, void **inout_BaseAddress, + uint32_t *inout_ProtectSize, + uint32_t NewProtect, uint32_t *out_OldProtect); +NtStatus NtWriteVirtualMemory(int64_t ProcessHandle, void *BaseAddress, + const void *Buffer, size_t BufferLength, + size_t *opt_out_ReturnLength); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_NT_MEMORY_H_ */ diff --git a/libc/nt/nt/process.h b/libc/nt/nt/process.h new file mode 100644 index 00000000..a4457f41 --- /dev/null +++ b/libc/nt/nt/process.h @@ -0,0 +1,87 @@ +#ifndef COSMOPOLITAN_LIBC_NT_NT_PROCESS_H_ +#define COSMOPOLITAN_LIBC_NT_NT_PROCESS_H_ +#include "libc/nt/enum/status.h" +#include "libc/nt/thunk/msabi.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » beyond the pale » processes ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + “The functions and structures in [for these APIs] are internal to + the operating system and subject to change from one release of + Windows to the next, and possibly even between service packs for + each release.” ──Quoth MSDN */ +#endif + +struct NtClientId; +struct NtObjectAttributes; +struct NtRtlUserProcessInformation; +struct NtRtlUserProcessParameters; +struct NtSecurityDescriptor; +struct NtUnicodeString; + +NtStatus NtCreateProcess(int64_t *out_ProcessHandle, uint32_t dwDesiredAccess, + struct NtObjectAttributes *opt_ObjectAttributes, + void *InheritFromProcessHandle, int32_t InheritHandles, + void *opt_SectionHandle, void *opt_DebugPort, + void *opt_ExceptionPort); +NtStatus NtTerminateProcess(int64_t opt_ProcessHandle, int32_t ExitStatus); + +NtStatus NtQueryInformationProcess(int64_t ProcessHandle, + int ProcessInformationClass, + void *out_ProcessInformation, + uint32_t ProcessInformationLength, + uint32_t *opt_out_ReturnLength); +NtStatus NtOpenProcessToken(int64_t ProcessToken, uint32_t DesiredAccess, + int64_t *out_TokenHandle); +NtStatus NtOpenProcess(int64_t *out_ProcessHandle, uint32_t DesiredAccess, + struct NtObjectAttributes *ObjectAttributes, + struct NtClientId *ClientId); + +NtStatus RtlCreateProcessParameters( + struct NtRtlUserProcessParameters **out_ProcessParameters, + struct NtUnicodeString *ImageFile, struct NtUnicodeString *opt_DllPath, + struct NtUnicodeString *opt_CurrentDirectory, + struct NtUnicodeString *opt_CommandLine, uint32_t CreationFlags, + struct NtUnicodeString *opt_WindowTitle, + struct NtUnicodeString *opt_Desktop, struct NtUnicodeString *opt_Reserved, + struct NtUnicodeString *opt_Reserved2); + +NtStatus RtlDestroyProcessParameters( + struct NtRtlUserProcessParameters *ProcessParameters); + +NtStatus RtlCloneUserProcess( + uint32_t ProcessFlags, + struct NtSecurityDescriptor *opt_ProcessSecurityDescriptor, + struct NtSecurityDescriptor *opt_ThreadSecurityDescriptor, + void *opt_DebugPort, + struct NtRtlUserProcessInformation *ProcessInformation); + +#if ShouldUseMsabiAttribute() +#include "libc/nt/nt/thunk/process.inc" +#endif /* ShouldUseMsabiAttribute() */ +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_NT_PROCESS_H_ */ diff --git a/libc/nt/nt/sections.h b/libc/nt/nt/sections.h new file mode 100644 index 00000000..697658f7 --- /dev/null +++ b/libc/nt/nt/sections.h @@ -0,0 +1,32 @@ +#ifndef COSMOPOLITAN_LIBC_NT_NT_SECTIONS_H_ +#define COSMOPOLITAN_LIBC_NT_NT_SECTIONS_H_ +#include "libc/nt/enum/sectioninformationclass.h" +#include "libc/nt/enum/sectioninherit.h" +#include "libc/nt/enum/status.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtObjectAttributes; + +NtStatus NtCreateSection(int64_t *out_SectionHandle, uint32_t DesiredAccess, + struct NtObjectAttributes *ObjectAttributes, + int64_t *opt_SectionSize, uint32_t Protect, + uint32_t Attributes, int64_t FileHandle); +NtStatus NtOpenSection(int64_t *out_SectionHandle, uint32_t DesiredAccess, + struct NtObjectAttributes *ObjectAttributes); +NtStatus NtMapViewOfSection(int64_t SectionHandle, int64_t ProcessHandle, + void **inout_BaseAddress, uint32_t *ZeroBits, + size_t CommitSize, int64_t *opt_inout_SectionOffset, + size_t *inout_ViewSize, + enum NtSectionInherit InheritDisposition, + uint32_t AllocationType, uint32_t Protect); +NtStatus NtUnmapViewOfSection(int64_t ProcessHandle, void *BaseAddress); +NtStatus NtQuerySection(int64_t SectionHandle, + enum NtSectionInformationClass SectionInformationClass, + void *out_SectionInformation, + uint32_t SectionInformationLength, + uint32_t *opt_out_ResultLength); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_NT_SECTIONS_H_ */ diff --git a/libc/nt/nt/signing.h b/libc/nt/nt/signing.h new file mode 100644 index 00000000..dccb6a15 --- /dev/null +++ b/libc/nt/nt/signing.h @@ -0,0 +1,42 @@ +#ifndef COSMOPOLITAN_LIBC_NT_NT_SIGNING_H_ +#define COSMOPOLITAN_LIBC_NT_NT_SIGNING_H_ +#include "libc/nt/enum/status.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » beyond the pale » code signing ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + “The functions and structures in [for these APIs] are internal to + the operating system and subject to change from one release of + Windows to the next, and possibly even between service packs for + each release.” ──Quoth MSDN */ +#endif + +NtStatus CsrClientCallServer(void *inout_Message, void *unknown, + uint32_t Opcode, uint32_t Size); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_NT_SIGNING_H_ */ diff --git a/libc/nt/nt/systemthreads.h b/libc/nt/nt/systemthreads.h new file mode 100644 index 00000000..1a3124b7 --- /dev/null +++ b/libc/nt/nt/systemthreads.h @@ -0,0 +1,23 @@ +#ifndef COSMOPOLITAN_LIBC_NT_NT_SYSTEMTHREADS_H_ +#define COSMOPOLITAN_LIBC_NT_NT_SYSTEMTHREADS_H_ +#include "libc/nt/enum/kwaitreason.h" +#include "libc/nt/enum/threadstate.h" +#include "libc/nt/struct/clientid.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSystemThreads { + int64_t KernelTime; + int64_t UserTime; + int64_t CreateTime; + uint32_t WaitTime; + void *StartAddress; + struct NtClientId ClientId; + int32_t Priority; + int32_t BasePriority; + uint32_t ContextSwitchCount; + enum NtThreadState State; + uint32_t WaitReason; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_NT_SYSTEMTHREADS_H_ */ diff --git a/libc/nt/nt/thread.h b/libc/nt/nt/thread.h new file mode 100644 index 00000000..d4ecb09e --- /dev/null +++ b/libc/nt/nt/thread.h @@ -0,0 +1,79 @@ +#ifndef COSMOPOLITAN_LIBC_NT_NT_THREAD_H_ +#define COSMOPOLITAN_LIBC_NT_NT_THREAD_H_ +#include "libc/nt/enum/status.h" +#include "libc/nt/enum/threadinfoclass.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » beyond the pale » threads ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + “The functions and structures in [for these APIs] are internal to + the operating system and subject to change from one release of + Windows to the next, and possibly even between service packs for + each release.” ──Quoth MSDN */ +#endif + +struct NtClientId; +struct NtContext; +struct NtObjectAttributes; +struct NtUserStack; + +NtStatus NtCreateThread(int64_t *out_ThreadHandle, uint32_t DesiredAccess, + struct NtObjectAttributes *ObjectAttributes, + int64_t ProcessHandle, struct NtClientId *out_ClientId, + struct NtContext *ThreadContext, + struct NtUserStack *UserStack, int32_t CreateSuspended); + +NtStatus NtTerminateThread(void *opt_ThreadHandle, int32_t ExitStatus); + +NtStatus NtOpenThread(int64_t *out_ThreadHandle, uint32_t DesiredAccess, + struct NtObjectAttributes *ObjectAttributes, + struct NtClientId *ClientId); + +NtStatus NtQueryInformationThread(int64_t ThreadHandle, + enum NtThreadInfoClass ThreadInformationClass, + void *out_ThreadInformation, + uint32_t ThreadInformationLength, + uint32_t *opt_out_ReturnLength); + +NtStatus NtGetContextThread(int64_t ThreadHandle, + struct NtContext *out_Context); +NtStatus NtSetContextThread(int64_t ThreadHandle, struct NtContext *Context); +NtStatus NtSuspendThread(int64_t ThreadHandle, + uint32_t *opt_out_PreviousSuspendCount); +NtStatus NtResumeThread(int64_t ThreadHandle, + uint32_t *opt_out_PreviousSuspendCount); + +NtStatus NtOpenThreadToken(int64_t ThreadHandle, uint32_t DesiredAccess, + int32_t OpenAsSelf, int64_t *out_TokenHandle); + +NtStatus NtSetInformationThread(int64_t ThreadHandle, + enum NtThreadInfoClass ThreadInformationClass, + void *ThreadInformation, + uint32_t ThreadInformationLength); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_NT_THREAD_H_ */ diff --git a/libc/nt/nt/thunk/process.inc b/libc/nt/nt/thunk/process.inc new file mode 100644 index 00000000..cd3c03cb --- /dev/null +++ b/libc/nt/nt/thunk/process.inc @@ -0,0 +1,5 @@ +#define NtQueryInformationProcess(...) \ + __imp_NtQueryInformationProcess(__VA_ARGS__) + +extern typeof(NtQueryInformationProcess) *const + __imp_NtQueryInformationProcess __msabi; diff --git a/libc/nt/nt/thunk/time.inc b/libc/nt/nt/thunk/time.inc new file mode 100644 index 00000000..eb5ad49c --- /dev/null +++ b/libc/nt/nt/thunk/time.inc @@ -0,0 +1,3 @@ +#define NtDelayExecution(...) __imp_NtDelayExecution(__VA_ARGS__) + +extern typeof(NtDelayExecution) *const __imp_NtDelayExecution __msabi; diff --git a/libc/nt/nt/time.h b/libc/nt/nt/time.h new file mode 100644 index 00000000..2d5d2e42 --- /dev/null +++ b/libc/nt/nt/time.h @@ -0,0 +1,45 @@ +#ifndef COSMOPOLITAN_LIBC_NT_NT_THREAD_H_ +#define COSMOPOLITAN_LIBC_NT_NT_THREAD_H_ +#include "libc/nt/enum/status.h" +#include "libc/nt/thunk/msabi.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » beyond the pale » time ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + “The functions and structures in [for these APIs] are internal to + the operating system and subject to change from one release of + Windows to the next, and possibly even between service packs for + each release.” ──Quoth MSDN */ +#endif + +NtStatus NtDelayExecution(bool32 alertable, int64_t *hectonanoseconds); + +#if ShouldUseMsabiAttribute() +#include "libc/nt/nt/thunk/time.inc" +#endif /* ShouldUseMsabiAttribute() */ +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_NT_THREAD_H_ */ diff --git a/libc/nt/ntdll.h b/libc/nt/ntdll.h new file mode 100644 index 00000000..6a3bc6c2 --- /dev/null +++ b/libc/nt/ntdll.h @@ -0,0 +1,260 @@ +#ifndef COSMOPOLITAN_LIBC_NT_NTDLL_H_ +#define COSMOPOLITAN_LIBC_NT_NTDLL_H_ +#include "libc/nt/enum/eventtype.h" +#include "libc/nt/enum/fileinformationclass.h" +#include "libc/nt/enum/fsinformationclass.h" +#include "libc/nt/enum/jobobjectinfoclass.h" +#include "libc/nt/enum/keyinformationclass.h" +#include "libc/nt/enum/objectinformationclass.h" +#include "libc/nt/enum/status.h" +#include "libc/nt/enum/systeminformationclass.h" +#include "libc/nt/enum/tokeninformationclass.h" +#include "libc/nt/enum/valueinformationclass.h" +#include "libc/nt/thunk/msabi.h" +#include "libc/nt/typedef/ioapcroutine.h" +#include "libc/nt/typedef/pknormalroutine.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » beyond the pale ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + “The functions and structures in [for these APIs] are internal to + the operating system and subject to change from one release of + Windows to the next, and possibly even between service packs for + each release.” ──Quoth MSDN */ +#endif + +#define g_nt_system_call_dispatcher (wambda *)0x7ffe0308 + +extern const struct NtUnicodeString *const RtlNtdllName; + +#if 0 +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § new technology » beyond the pale » eponymous runtime ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +struct NtContext; +struct NtCriticalSection; +struct NtExceptionRecord; +struct NtFileBasicInformation; +struct NtFileNetworkOpenInformation; +struct NtIoStatusBlock; +struct NtObjectAttributes; +struct NtSecurityDescriptor; +struct NtUnicodeString; + +#define NT_PROCESS_FLAGS_CREATE_SUSPENDED 0x00000001 +#define NT_PROCESS_FLAGS_INHERIT_HANDLES 0x00000002 +#define NT_PROCESS_FLAGS_NO_SYNCHRONIZE 0x00000004 +#define NT_RTL_CLONE_PARENT 0 +#define NT_RTL_CLONE_CHILD 297 + +NtStatus NtCallbackReturn(void *opt_Result, uint32_t ResultLength, + int32_t Status); +NtStatus NtTestAlert(void); + +NtStatus NtOpenFile(int64_t *out_FileHandle, uint32_t DesiredAccess, + struct NtObjectAttributes *ObjectAttributes, + struct NtIoStatusBlock *out_IoStatusBlock, + uint32_t ShareAccess, uint32_t OpenOptions); + +NtStatus NtQueryInformationToken(int64_t TokenHandle, + uint32_t TokenInformationClass, + void *out_TokenInformation, + uint32_t TokenInformationLength, + uint32_t *out_ReturnLength); +NtStatus NtYieldExecution(void); +NtStatus NtQuerySystemInformation(uint32_t info_class, void *out_info, + uint32_t info_size, + uint32_t *out_bytes_received); +NtStatus NtReadVirtualMemory(int64_t ProcessHandle, const void *BaseAddress, + void *out_Buffer, size_t BufferLength, + size_t *opt_out_ReturnLength); +NtStatus NtCreateTimer(void **out_TimerHandle, uint32_t DesiredAccess, + struct NtObjectAttributes *ObjectAttributes, + uint32_t TimerType); +NtStatus NtSetTimer(void *TimerHandle, int64_t *DueTime, void *TimerApcRoutine, + void *TimerContext, int32_t Resume, int32_t Period, + int32_t *out_PreviousState); +NtStatus NtQueryObject(void *ObjectHandle, + enum NtObjectInformationClass ObjectInformationClass, + void *out_ObjectInformation, + uint32_t ObjectInformationLength, + uint32_t *opt_out_ReturnLength); +NtStatus NtQueryFullAttributesFile( + struct NtObjectAttributes *attributes, + struct NtFileNetworkOpenInformation *out_info); +NtStatus NtCreateKey(void **out_KeyHandle, uint32_t DesiredAccess, + struct NtObjectAttributes *ObjectAttributes, + uint32_t TitleIndex, struct NtUnicodeString *opt_Class, + uint32_t CreateOptions, uint32_t *opt_out_Disposition); +NtStatus NtOpenKey(void **out_KeyHandle, uint32_t DesiredAccess, + struct NtObjectAttributes *ObjectAttributes); +NtStatus NtSetValueKey(void *KeyHandle, struct NtUnicodeString *ValueName, + uint32_t opt_TitleIndex, uint32_t Type, void *Data, + uint32_t DataSize); +NtStatus NtDeleteKey(void *KeyHandle); +NtStatus NtQueryValueKey( + void *KeyHandle, struct NtUnicodeString *ValueName, + enum NtKeyValueInformationClass KeyValueInformationClass, + void *out_KeyValueInformation, uint32_t Length, uint32_t *out_ResultLength); +NtStatus NtFlushKey(void *KeyHandle); +NtStatus NtEnumerateKey(int64_t hkey, uint32_t index, + enum NtKeyInformationClass info_class, + void *out_key_info, uint32_t key_info_size, + uint32_t *out_bytes_received); +NtStatus NtEnumerateValueKey(int64_t hKey, uint32_t index, + enum NtKeyValueInformationClass info_class, + void *out_key_info, uint32_t key_info_size, + uint32_t *out_bytes_received); +NtStatus NtQuerySystemTime(int64_t *SystemTime); +NtStatus NtDeleteFile(struct NtObjectAttributes *ObjectAttributes); +NtStatus NtFlushBuffersFile(int64_t FileHandle, + struct NtIoStatusBlock *out_IoStatusBlock); +NtStatus NtCreateIoCompletion(void **out_IoCompletionHandle, + uint32_t DesiredAccess, + struct NtObjectAttributes *ObjectAttributes, + uint32_t NumberOfConcurrentThreads); +NtStatus NtRaiseHardError(int32_t ErrorStatus, uint32_t NumberOfArguments, + uint32_t UnicodeStringArgumentsMask, void *Arguments, + uint32_t MessageBoxType, + uint32_t *out_MessageBoxResult); +NtStatus NtRaiseException(struct NtExceptionRecord *ExceptionRecord, + struct NtContext *Context, int32_t SearchFrames); +NtStatus NtCreateEvent(void **out_EventHandle, uint32_t DesiredAccess, + struct NtObjectAttributes *ObjectAttributes, + enum NtEventType EventType, int32_t InitialState); +NtStatus NtWaitForSingleObject(void *ObjectHandle, int32_t Alertable, + int64_t *TimeOut); +NtStatus NtSetEvent(void *EventHandle, int32_t *opt_out_PreviousState); +NtStatus NtClearEvent(void *EventHandle); +NtStatus NtSignalAndWaitForSingleObject(void *ObjectToSignal, + void *WaitableObject, int32_t Alertable, + int64_t *opt_Time); +NtStatus NtQueryPerformanceCounter(int64_t *out_PerformanceCount, + int64_t *opt_out_PerformanceFrequency); +NtStatus NtFsControlFile(int64_t FileHandle, void *opt_Event, + NtIoApcRoutine opt_ApcRoutine, void *opt_ApcContext, + struct NtIoStatusBlock *out_IoStatusBlock, + uint32_t FsControlCode, void *opt_InputBuffer, + uint32_t InputBufferLength, void *opt_out_OutputBuffer, + uint32_t OutputBufferLength); +NtStatus NtCancelIoFile(int64_t FileHandle, + struct NtIoStatusBlock *out_IoStatusBlock); +NtStatus NtCreateProfile(void **out_ProfileHandle, int64_t ProcessHandle, + void *Base, uint32_t Size, uint32_t BucketShift, + uint32_t *Buffer, uint32_t BufferLength, int Source, + uint32_t ProcessorMask); +NtStatus NtSetIntervalProfile(uint32_t Interval, int Source); +NtStatus NtQueryIntervalProfile(int Source, uint32_t *out_Interval); +NtStatus NtStartProfile(void *ProfileHandle); +NtStatus NtStopProfile(void *ProfileHandle); +NtStatus NtCreateDirectoryObject(int64_t *out_DirectoryHandle, + uint32_t DesiredAccess, + struct NtObjectAttributes *ObjectAttributes); +NtStatus NtOpenDirectoryObject(int64_t *out_DirectoryHandle, + uint32_t DesiredAccess, + struct NtObjectAttributes *ObjectAttributes); +NtStatus NtOpenSymbolicLinkObject(int64_t *out_DirectoryHandle, + uint32_t DesiredAccess, + struct NtObjectAttributes *ObjectAttributes); +NtStatus NtQuerySymbolicLinkObject(int64_t DirectoryHandle, + struct NtUnicodeString *inout_TargetName, + uint32_t *opt_out_ReturnLength); +NtStatus ZwAreMappedFilesTheSame(void *Address1, void *Address2); +NtStatus NtQueryVolumeInformationFile(int64_t FileHandle, + struct NtIoStatusBlock *out_IoStatusBlock, + void *out_FsInformation, uint32_t Length, + uint32_t FsInformationClass); +NtStatus NtQuerySecurityObject( + int64_t handle, int RequestedInformation, + struct NtSecurityDescriptor *out_SecurityDescriptor, + uint32_t SecurityDescriptorLength, uint32_t *out_ReturnLength); +NtStatus NtQueueApcThread(int64_t ThreadHandle, NtPkNormalRoutine ApcRoutine, + void *opt_ApcContext, void *opt_Argument1, + void *opt_Argument2); +NtStatus NtFlushInstructionCache(int64_t ProcessHandle, void *opt_BaseAddress, + size_t FlushSize); +NtStatus NtQueryAttributesFile(const struct NtObjectAttributes *object, + struct NtFileBasicInformation *file_information); +NtStatus NtDeviceIoControlFile( + int64_t FileHandle, void *opt_Event, NtIoApcRoutine opt_ApcRoutine, + void *opt_ApcContext, struct NtIoStatusBlock *out_IoStatusBlock, + uint32_t IoControlCode, void *opt_InputBuffer, uint32_t InputBufferLength, + void *opt_out_OutputBuffer, uint32_t OutputBufferLength); +NtStatus NtQueryDirectoryFile( + int64_t FileHandle, void *opt_Event, NtIoApcRoutine opt_ApcRoutine, + void *opt_ApcContext, struct NtIoStatusBlock *out_IoStatusBlock, + void *out_FileInformation, uint32_t FileInformationLength, + uint32_t FileInformationClass, int32_t ReturnSingleEntry, + struct NtUnicodeString *opt_FileName, int32_t RestartScan); +NtStatus NtFlushVirtualMemory(int64_t ProcessHandle, void **inout_BaseAddress, + uint32_t **inout_FlushSize, + struct NtIoStatusBlock *out_IoStatusBlock); +NtStatus NtQueryInformationJobObject( + void *JobHandle, enum NtJobObjectInfoClass JobInformationClass, + void *out_JobInformation, uint32_t JobInformationLength, + uint32_t *opt_out_ReturnLength); + +#if 0 +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § new technology » beyond the pale » runtime library ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +NtStatus RtlInitializeCriticalSection(struct NtCriticalSection *out_crit); +NtStatus RtlDeleteCriticalSection(struct NtCriticalSection *crit); +NtStatus RtlEnterCriticalSection(struct NtCriticalSection *inout_crit); +NtStatus RtlLeaveCriticalSection(struct NtCriticalSection *inout_crit); +NtStatus RtlTryEnterCriticalSection(struct NtCriticalSection *inout_crit); +NtStatus RtlInitUnicodeString(struct NtUnicodeString *inout_DestinationString, + const char16_t *SourceString); +void RtlFreeUnicodeString(struct NtUnicodeString **string); +NtStatus RtlQueryEnvironmentVariable_U(char16_t *Environment, + struct NtUnicodeString *Name, + struct NtUnicodeString *Value); +NtStatus RtlConvertSidToUnicodeString(struct NtUnicodeString *out_UnicodeString, + void *Sid, + int32_t AllocateDestinationString); +void *RtlCreateHeap(uint32_t flags, void *base, size_t reserve_sz, + size_t commit_sz, void *lock, void *params); +NtStatus RtlDestroyHeap(void *base); +void *RtlAllocateHeap(int64_t heap, uint32_t flags, size_t size); +void *RtlReAllocateHeap(int64_t heap, uint32_t flags, void *ptr, size_t size); +NtStatus RtlFreeHeap(int64_t heap, uint32_t flags, void *ptr); +size_t RtlSizeHeap(int64_t heap, uint32_t flags, void *ptr); +NtStatus RtlValidateHeap(int64_t heap, uint32_t flags, void *ptr); +NtStatus RtlLockHeap(int64_t heap); +NtStatus RtlUnlockHeap(int64_t heap); +NtStatus RtlGetProcessHeaps(uint32_t count, void **out_Heaps); +NtStatus RtlWalkHeap(int64_t heap, void *out_Info); + +#if ShouldUseMsabiAttribute() +#include "libc/nt/thunk/ntdll.inc" +#endif /* ShouldUseMsabiAttribute() */ +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_NTDLL_H_ */ diff --git a/libc/nt/ntdll/A_SHAFinal.s b/libc/nt/ntdll/A_SHAFinal.s new file mode 100644 index 00000000..be95a48d --- /dev/null +++ b/libc/nt/ntdll/A_SHAFinal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp A_SHAFinal diff --git a/libc/nt/ntdll/A_SHAInit.s b/libc/nt/ntdll/A_SHAInit.s new file mode 100644 index 00000000..16290c4e --- /dev/null +++ b/libc/nt/ntdll/A_SHAInit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp A_SHAInit diff --git a/libc/nt/ntdll/A_SHAUpdate.s b/libc/nt/ntdll/A_SHAUpdate.s new file mode 100644 index 00000000..ea0c3283 --- /dev/null +++ b/libc/nt/ntdll/A_SHAUpdate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp A_SHAUpdate diff --git a/libc/nt/ntdll/AlpcAdjustCompletionListConcurrencyCount.s b/libc/nt/ntdll/AlpcAdjustCompletionListConcurrencyCount.s new file mode 100644 index 00000000..aa1f19f2 --- /dev/null +++ b/libc/nt/ntdll/AlpcAdjustCompletionListConcurrencyCount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp AlpcAdjustCompletionListConcurrencyCount diff --git a/libc/nt/ntdll/AlpcFreeCompletionListMessage.s b/libc/nt/ntdll/AlpcFreeCompletionListMessage.s new file mode 100644 index 00000000..93bebd07 --- /dev/null +++ b/libc/nt/ntdll/AlpcFreeCompletionListMessage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp AlpcFreeCompletionListMessage diff --git a/libc/nt/ntdll/AlpcGetCompletionListLastMessageInformation.s b/libc/nt/ntdll/AlpcGetCompletionListLastMessageInformation.s new file mode 100644 index 00000000..134361f1 --- /dev/null +++ b/libc/nt/ntdll/AlpcGetCompletionListLastMessageInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp AlpcGetCompletionListLastMessageInformation diff --git a/libc/nt/ntdll/AlpcGetCompletionListMessageAttributes.s b/libc/nt/ntdll/AlpcGetCompletionListMessageAttributes.s new file mode 100644 index 00000000..de3715f8 --- /dev/null +++ b/libc/nt/ntdll/AlpcGetCompletionListMessageAttributes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp AlpcGetCompletionListMessageAttributes diff --git a/libc/nt/ntdll/AlpcGetHeaderSize.s b/libc/nt/ntdll/AlpcGetHeaderSize.s new file mode 100644 index 00000000..362a389a --- /dev/null +++ b/libc/nt/ntdll/AlpcGetHeaderSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp AlpcGetHeaderSize diff --git a/libc/nt/ntdll/AlpcGetMessageAttribute.s b/libc/nt/ntdll/AlpcGetMessageAttribute.s new file mode 100644 index 00000000..d0897534 --- /dev/null +++ b/libc/nt/ntdll/AlpcGetMessageAttribute.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp AlpcGetMessageAttribute diff --git a/libc/nt/ntdll/AlpcGetMessageFromCompletionList.s b/libc/nt/ntdll/AlpcGetMessageFromCompletionList.s new file mode 100644 index 00000000..d82144d4 --- /dev/null +++ b/libc/nt/ntdll/AlpcGetMessageFromCompletionList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp AlpcGetMessageFromCompletionList diff --git a/libc/nt/ntdll/AlpcGetOutstandingCompletionListMessageCount.s b/libc/nt/ntdll/AlpcGetOutstandingCompletionListMessageCount.s new file mode 100644 index 00000000..dc6f19e6 --- /dev/null +++ b/libc/nt/ntdll/AlpcGetOutstandingCompletionListMessageCount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp AlpcGetOutstandingCompletionListMessageCount diff --git a/libc/nt/ntdll/AlpcInitializeMessageAttribute.s b/libc/nt/ntdll/AlpcInitializeMessageAttribute.s new file mode 100644 index 00000000..2dad466d --- /dev/null +++ b/libc/nt/ntdll/AlpcInitializeMessageAttribute.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp AlpcInitializeMessageAttribute diff --git a/libc/nt/ntdll/AlpcMaxAllowedMessageLength.s b/libc/nt/ntdll/AlpcMaxAllowedMessageLength.s new file mode 100644 index 00000000..5d0e986d --- /dev/null +++ b/libc/nt/ntdll/AlpcMaxAllowedMessageLength.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp AlpcMaxAllowedMessageLength diff --git a/libc/nt/ntdll/AlpcRegisterCompletionList.s b/libc/nt/ntdll/AlpcRegisterCompletionList.s new file mode 100644 index 00000000..c9a246e7 --- /dev/null +++ b/libc/nt/ntdll/AlpcRegisterCompletionList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp AlpcRegisterCompletionList diff --git a/libc/nt/ntdll/AlpcRegisterCompletionListWorkerThread.s b/libc/nt/ntdll/AlpcRegisterCompletionListWorkerThread.s new file mode 100644 index 00000000..e8c3623c --- /dev/null +++ b/libc/nt/ntdll/AlpcRegisterCompletionListWorkerThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp AlpcRegisterCompletionListWorkerThread diff --git a/libc/nt/ntdll/AlpcRundownCompletionList.s b/libc/nt/ntdll/AlpcRundownCompletionList.s new file mode 100644 index 00000000..58cfe363 --- /dev/null +++ b/libc/nt/ntdll/AlpcRundownCompletionList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp AlpcRundownCompletionList diff --git a/libc/nt/ntdll/AlpcUnregisterCompletionList.s b/libc/nt/ntdll/AlpcUnregisterCompletionList.s new file mode 100644 index 00000000..937178df --- /dev/null +++ b/libc/nt/ntdll/AlpcUnregisterCompletionList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp AlpcUnregisterCompletionList diff --git a/libc/nt/ntdll/AlpcUnregisterCompletionListWorkerThread.s b/libc/nt/ntdll/AlpcUnregisterCompletionListWorkerThread.s new file mode 100644 index 00000000..1630ea02 --- /dev/null +++ b/libc/nt/ntdll/AlpcUnregisterCompletionListWorkerThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp AlpcUnregisterCompletionListWorkerThread diff --git a/libc/nt/ntdll/ApiSetQueryApiSetPresence.s b/libc/nt/ntdll/ApiSetQueryApiSetPresence.s new file mode 100644 index 00000000..a8907ab0 --- /dev/null +++ b/libc/nt/ntdll/ApiSetQueryApiSetPresence.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ApiSetQueryApiSetPresence diff --git a/libc/nt/ntdll/CsrAllocateCaptureBuffer.s b/libc/nt/ntdll/CsrAllocateCaptureBuffer.s new file mode 100644 index 00000000..870cca8d --- /dev/null +++ b/libc/nt/ntdll/CsrAllocateCaptureBuffer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp CsrAllocateCaptureBuffer diff --git a/libc/nt/ntdll/CsrAllocateMessagePointer.s b/libc/nt/ntdll/CsrAllocateMessagePointer.s new file mode 100644 index 00000000..7c3ff6e4 --- /dev/null +++ b/libc/nt/ntdll/CsrAllocateMessagePointer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp CsrAllocateMessagePointer diff --git a/libc/nt/ntdll/CsrCaptureMessageBuffer.s b/libc/nt/ntdll/CsrCaptureMessageBuffer.s new file mode 100644 index 00000000..9206f097 --- /dev/null +++ b/libc/nt/ntdll/CsrCaptureMessageBuffer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp CsrCaptureMessageBuffer diff --git a/libc/nt/ntdll/CsrCaptureMessageMultiUnicodeStringsInPlace.s b/libc/nt/ntdll/CsrCaptureMessageMultiUnicodeStringsInPlace.s new file mode 100644 index 00000000..454f61b2 --- /dev/null +++ b/libc/nt/ntdll/CsrCaptureMessageMultiUnicodeStringsInPlace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp CsrCaptureMessageMultiUnicodeStringsInPlace diff --git a/libc/nt/ntdll/CsrCaptureMessageString.s b/libc/nt/ntdll/CsrCaptureMessageString.s new file mode 100644 index 00000000..62af1c64 --- /dev/null +++ b/libc/nt/ntdll/CsrCaptureMessageString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp CsrCaptureMessageString diff --git a/libc/nt/ntdll/CsrCaptureTimeout.s b/libc/nt/ntdll/CsrCaptureTimeout.s new file mode 100644 index 00000000..413c74b7 --- /dev/null +++ b/libc/nt/ntdll/CsrCaptureTimeout.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp CsrCaptureTimeout diff --git a/libc/nt/ntdll/CsrClientCallServer.s b/libc/nt/ntdll/CsrClientCallServer.s new file mode 100644 index 00000000..17712944 --- /dev/null +++ b/libc/nt/ntdll/CsrClientCallServer.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp CsrClientCallServer + + .text.windows +CsrClientCallServer: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CsrClientCallServer(%rip),%rax + jmp __sysv2nt + .endfn CsrClientCallServer,globl + .previous diff --git a/libc/nt/ntdll/CsrClientConnectToServer.s b/libc/nt/ntdll/CsrClientConnectToServer.s new file mode 100644 index 00000000..ef7ee754 --- /dev/null +++ b/libc/nt/ntdll/CsrClientConnectToServer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp CsrClientConnectToServer diff --git a/libc/nt/ntdll/CsrFreeCaptureBuffer.s b/libc/nt/ntdll/CsrFreeCaptureBuffer.s new file mode 100644 index 00000000..a0c37726 --- /dev/null +++ b/libc/nt/ntdll/CsrFreeCaptureBuffer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp CsrFreeCaptureBuffer diff --git a/libc/nt/ntdll/CsrGetProcessId.s b/libc/nt/ntdll/CsrGetProcessId.s new file mode 100644 index 00000000..9b69216b --- /dev/null +++ b/libc/nt/ntdll/CsrGetProcessId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp CsrGetProcessId diff --git a/libc/nt/ntdll/CsrIdentifyAlertableThread.s b/libc/nt/ntdll/CsrIdentifyAlertableThread.s new file mode 100644 index 00000000..b96af507 --- /dev/null +++ b/libc/nt/ntdll/CsrIdentifyAlertableThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp CsrIdentifyAlertableThread diff --git a/libc/nt/ntdll/CsrSetPriorityClass.s b/libc/nt/ntdll/CsrSetPriorityClass.s new file mode 100644 index 00000000..02b7fd95 --- /dev/null +++ b/libc/nt/ntdll/CsrSetPriorityClass.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp CsrSetPriorityClass diff --git a/libc/nt/ntdll/CsrVerifyRegion.s b/libc/nt/ntdll/CsrVerifyRegion.s new file mode 100644 index 00000000..f913c9a3 --- /dev/null +++ b/libc/nt/ntdll/CsrVerifyRegion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp CsrVerifyRegion diff --git a/libc/nt/ntdll/DbgBreakPoint.s b/libc/nt/ntdll/DbgBreakPoint.s new file mode 100644 index 00000000..1f3b5c9c --- /dev/null +++ b/libc/nt/ntdll/DbgBreakPoint.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgBreakPoint diff --git a/libc/nt/ntdll/DbgPrint.s b/libc/nt/ntdll/DbgPrint.s new file mode 100644 index 00000000..e53aad0e --- /dev/null +++ b/libc/nt/ntdll/DbgPrint.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgPrint diff --git a/libc/nt/ntdll/DbgPrintEx.s b/libc/nt/ntdll/DbgPrintEx.s new file mode 100644 index 00000000..573d413e --- /dev/null +++ b/libc/nt/ntdll/DbgPrintEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgPrintEx diff --git a/libc/nt/ntdll/DbgPrintReturnControlC.s b/libc/nt/ntdll/DbgPrintReturnControlC.s new file mode 100644 index 00000000..c07539d0 --- /dev/null +++ b/libc/nt/ntdll/DbgPrintReturnControlC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgPrintReturnControlC diff --git a/libc/nt/ntdll/DbgPrompt.s b/libc/nt/ntdll/DbgPrompt.s new file mode 100644 index 00000000..b33a816f --- /dev/null +++ b/libc/nt/ntdll/DbgPrompt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgPrompt diff --git a/libc/nt/ntdll/DbgQueryDebugFilterState.s b/libc/nt/ntdll/DbgQueryDebugFilterState.s new file mode 100644 index 00000000..3b314b99 --- /dev/null +++ b/libc/nt/ntdll/DbgQueryDebugFilterState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgQueryDebugFilterState diff --git a/libc/nt/ntdll/DbgSetDebugFilterState.s b/libc/nt/ntdll/DbgSetDebugFilterState.s new file mode 100644 index 00000000..56eb5dd2 --- /dev/null +++ b/libc/nt/ntdll/DbgSetDebugFilterState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgSetDebugFilterState diff --git a/libc/nt/ntdll/DbgUiConnectToDbg.s b/libc/nt/ntdll/DbgUiConnectToDbg.s new file mode 100644 index 00000000..355d6e48 --- /dev/null +++ b/libc/nt/ntdll/DbgUiConnectToDbg.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgUiConnectToDbg diff --git a/libc/nt/ntdll/DbgUiContinue.s b/libc/nt/ntdll/DbgUiContinue.s new file mode 100644 index 00000000..9c26fa27 --- /dev/null +++ b/libc/nt/ntdll/DbgUiContinue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgUiContinue diff --git a/libc/nt/ntdll/DbgUiConvertStateChangeStructure.s b/libc/nt/ntdll/DbgUiConvertStateChangeStructure.s new file mode 100644 index 00000000..1ce5df25 --- /dev/null +++ b/libc/nt/ntdll/DbgUiConvertStateChangeStructure.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgUiConvertStateChangeStructure diff --git a/libc/nt/ntdll/DbgUiConvertStateChangeStructureEx.s b/libc/nt/ntdll/DbgUiConvertStateChangeStructureEx.s new file mode 100644 index 00000000..5de7e57b --- /dev/null +++ b/libc/nt/ntdll/DbgUiConvertStateChangeStructureEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgUiConvertStateChangeStructureEx diff --git a/libc/nt/ntdll/DbgUiDebugActiveProcess.s b/libc/nt/ntdll/DbgUiDebugActiveProcess.s new file mode 100644 index 00000000..ef471f40 --- /dev/null +++ b/libc/nt/ntdll/DbgUiDebugActiveProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgUiDebugActiveProcess diff --git a/libc/nt/ntdll/DbgUiGetThreadDebugObject.s b/libc/nt/ntdll/DbgUiGetThreadDebugObject.s new file mode 100644 index 00000000..ac8cfe77 --- /dev/null +++ b/libc/nt/ntdll/DbgUiGetThreadDebugObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgUiGetThreadDebugObject diff --git a/libc/nt/ntdll/DbgUiIssueRemoteBreakin.s b/libc/nt/ntdll/DbgUiIssueRemoteBreakin.s new file mode 100644 index 00000000..d04c29ed --- /dev/null +++ b/libc/nt/ntdll/DbgUiIssueRemoteBreakin.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgUiIssueRemoteBreakin diff --git a/libc/nt/ntdll/DbgUiRemoteBreakin.s b/libc/nt/ntdll/DbgUiRemoteBreakin.s new file mode 100644 index 00000000..aed3fe78 --- /dev/null +++ b/libc/nt/ntdll/DbgUiRemoteBreakin.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgUiRemoteBreakin diff --git a/libc/nt/ntdll/DbgUiSetThreadDebugObject.s b/libc/nt/ntdll/DbgUiSetThreadDebugObject.s new file mode 100644 index 00000000..35e4a943 --- /dev/null +++ b/libc/nt/ntdll/DbgUiSetThreadDebugObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgUiSetThreadDebugObject diff --git a/libc/nt/ntdll/DbgUiStopDebugging.s b/libc/nt/ntdll/DbgUiStopDebugging.s new file mode 100644 index 00000000..205f2662 --- /dev/null +++ b/libc/nt/ntdll/DbgUiStopDebugging.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgUiStopDebugging diff --git a/libc/nt/ntdll/DbgUiWaitStateChange.s b/libc/nt/ntdll/DbgUiWaitStateChange.s new file mode 100644 index 00000000..5212e42a --- /dev/null +++ b/libc/nt/ntdll/DbgUiWaitStateChange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgUiWaitStateChange diff --git a/libc/nt/ntdll/DbgUserBreakPoint.s b/libc/nt/ntdll/DbgUserBreakPoint.s new file mode 100644 index 00000000..82f382b5 --- /dev/null +++ b/libc/nt/ntdll/DbgUserBreakPoint.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp DbgUserBreakPoint diff --git a/libc/nt/ntdll/EtwCheckCoverage.s b/libc/nt/ntdll/EtwCheckCoverage.s new file mode 100644 index 00000000..def8d0bc --- /dev/null +++ b/libc/nt/ntdll/EtwCheckCoverage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwCheckCoverage diff --git a/libc/nt/ntdll/EtwCreateTraceInstanceId.s b/libc/nt/ntdll/EtwCreateTraceInstanceId.s new file mode 100644 index 00000000..615e9f53 --- /dev/null +++ b/libc/nt/ntdll/EtwCreateTraceInstanceId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwCreateTraceInstanceId diff --git a/libc/nt/ntdll/EtwDeliverDataBlock.s b/libc/nt/ntdll/EtwDeliverDataBlock.s new file mode 100644 index 00000000..64fe0a9b --- /dev/null +++ b/libc/nt/ntdll/EtwDeliverDataBlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwDeliverDataBlock diff --git a/libc/nt/ntdll/EtwEnumerateProcessRegGuids.s b/libc/nt/ntdll/EtwEnumerateProcessRegGuids.s new file mode 100644 index 00000000..ee0fed06 --- /dev/null +++ b/libc/nt/ntdll/EtwEnumerateProcessRegGuids.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwEnumerateProcessRegGuids diff --git a/libc/nt/ntdll/EtwEventActivityIdControl.s b/libc/nt/ntdll/EtwEventActivityIdControl.s new file mode 100644 index 00000000..cf149dd9 --- /dev/null +++ b/libc/nt/ntdll/EtwEventActivityIdControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwEventActivityIdControl diff --git a/libc/nt/ntdll/EtwEventEnabled.s b/libc/nt/ntdll/EtwEventEnabled.s new file mode 100644 index 00000000..a5b87cc3 --- /dev/null +++ b/libc/nt/ntdll/EtwEventEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwEventEnabled diff --git a/libc/nt/ntdll/EtwEventProviderEnabled.s b/libc/nt/ntdll/EtwEventProviderEnabled.s new file mode 100644 index 00000000..00d78da6 --- /dev/null +++ b/libc/nt/ntdll/EtwEventProviderEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwEventProviderEnabled diff --git a/libc/nt/ntdll/EtwEventRegister.s b/libc/nt/ntdll/EtwEventRegister.s new file mode 100644 index 00000000..61b7022e --- /dev/null +++ b/libc/nt/ntdll/EtwEventRegister.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwEventRegister diff --git a/libc/nt/ntdll/EtwEventSetInformation.s b/libc/nt/ntdll/EtwEventSetInformation.s new file mode 100644 index 00000000..6874c4cb --- /dev/null +++ b/libc/nt/ntdll/EtwEventSetInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwEventSetInformation diff --git a/libc/nt/ntdll/EtwEventUnregister.s b/libc/nt/ntdll/EtwEventUnregister.s new file mode 100644 index 00000000..9e95bbf3 --- /dev/null +++ b/libc/nt/ntdll/EtwEventUnregister.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwEventUnregister diff --git a/libc/nt/ntdll/EtwEventWrite.s b/libc/nt/ntdll/EtwEventWrite.s new file mode 100644 index 00000000..4885da6f --- /dev/null +++ b/libc/nt/ntdll/EtwEventWrite.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwEventWrite diff --git a/libc/nt/ntdll/EtwEventWriteEndScenario.s b/libc/nt/ntdll/EtwEventWriteEndScenario.s new file mode 100644 index 00000000..d4bfadc0 --- /dev/null +++ b/libc/nt/ntdll/EtwEventWriteEndScenario.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwEventWriteEndScenario diff --git a/libc/nt/ntdll/EtwEventWriteEx.s b/libc/nt/ntdll/EtwEventWriteEx.s new file mode 100644 index 00000000..80f6aaf5 --- /dev/null +++ b/libc/nt/ntdll/EtwEventWriteEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwEventWriteEx diff --git a/libc/nt/ntdll/EtwEventWriteFull.s b/libc/nt/ntdll/EtwEventWriteFull.s new file mode 100644 index 00000000..d6b0a316 --- /dev/null +++ b/libc/nt/ntdll/EtwEventWriteFull.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwEventWriteFull diff --git a/libc/nt/ntdll/EtwEventWriteNoRegistration.s b/libc/nt/ntdll/EtwEventWriteNoRegistration.s new file mode 100644 index 00000000..bf131923 --- /dev/null +++ b/libc/nt/ntdll/EtwEventWriteNoRegistration.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwEventWriteNoRegistration diff --git a/libc/nt/ntdll/EtwEventWriteStartScenario.s b/libc/nt/ntdll/EtwEventWriteStartScenario.s new file mode 100644 index 00000000..1a8ee2ee --- /dev/null +++ b/libc/nt/ntdll/EtwEventWriteStartScenario.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwEventWriteStartScenario diff --git a/libc/nt/ntdll/EtwEventWriteString.s b/libc/nt/ntdll/EtwEventWriteString.s new file mode 100644 index 00000000..8b556320 --- /dev/null +++ b/libc/nt/ntdll/EtwEventWriteString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwEventWriteString diff --git a/libc/nt/ntdll/EtwEventWriteTransfer.s b/libc/nt/ntdll/EtwEventWriteTransfer.s new file mode 100644 index 00000000..d7e52d4c --- /dev/null +++ b/libc/nt/ntdll/EtwEventWriteTransfer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwEventWriteTransfer diff --git a/libc/nt/ntdll/EtwGetTraceEnableFlags.s b/libc/nt/ntdll/EtwGetTraceEnableFlags.s new file mode 100644 index 00000000..d3ba4e2e --- /dev/null +++ b/libc/nt/ntdll/EtwGetTraceEnableFlags.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwGetTraceEnableFlags diff --git a/libc/nt/ntdll/EtwGetTraceEnableLevel.s b/libc/nt/ntdll/EtwGetTraceEnableLevel.s new file mode 100644 index 00000000..0a606dd7 --- /dev/null +++ b/libc/nt/ntdll/EtwGetTraceEnableLevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwGetTraceEnableLevel diff --git a/libc/nt/ntdll/EtwGetTraceLoggerHandle.s b/libc/nt/ntdll/EtwGetTraceLoggerHandle.s new file mode 100644 index 00000000..c6b2bcd2 --- /dev/null +++ b/libc/nt/ntdll/EtwGetTraceLoggerHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwGetTraceLoggerHandle diff --git a/libc/nt/ntdll/EtwLogTraceEvent.s b/libc/nt/ntdll/EtwLogTraceEvent.s new file mode 100644 index 00000000..183937f0 --- /dev/null +++ b/libc/nt/ntdll/EtwLogTraceEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwLogTraceEvent diff --git a/libc/nt/ntdll/EtwNotificationRegister.s b/libc/nt/ntdll/EtwNotificationRegister.s new file mode 100644 index 00000000..067a2f87 --- /dev/null +++ b/libc/nt/ntdll/EtwNotificationRegister.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwNotificationRegister diff --git a/libc/nt/ntdll/EtwNotificationUnregister.s b/libc/nt/ntdll/EtwNotificationUnregister.s new file mode 100644 index 00000000..2228b7fe --- /dev/null +++ b/libc/nt/ntdll/EtwNotificationUnregister.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwNotificationUnregister diff --git a/libc/nt/ntdll/EtwProcessPrivateLoggerRequest.s b/libc/nt/ntdll/EtwProcessPrivateLoggerRequest.s new file mode 100644 index 00000000..efdc70d1 --- /dev/null +++ b/libc/nt/ntdll/EtwProcessPrivateLoggerRequest.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwProcessPrivateLoggerRequest diff --git a/libc/nt/ntdll/EtwRegisterSecurityProvider.s b/libc/nt/ntdll/EtwRegisterSecurityProvider.s new file mode 100644 index 00000000..87188752 --- /dev/null +++ b/libc/nt/ntdll/EtwRegisterSecurityProvider.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwRegisterSecurityProvider diff --git a/libc/nt/ntdll/EtwRegisterTraceGuidsA.s b/libc/nt/ntdll/EtwRegisterTraceGuidsA.s new file mode 100644 index 00000000..3aa28c32 --- /dev/null +++ b/libc/nt/ntdll/EtwRegisterTraceGuidsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwRegisterTraceGuidsA diff --git a/libc/nt/ntdll/EtwRegisterTraceGuidsW.s b/libc/nt/ntdll/EtwRegisterTraceGuidsW.s new file mode 100644 index 00000000..cc9f29a8 --- /dev/null +++ b/libc/nt/ntdll/EtwRegisterTraceGuidsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwRegisterTraceGuidsW diff --git a/libc/nt/ntdll/EtwReplyNotification.s b/libc/nt/ntdll/EtwReplyNotification.s new file mode 100644 index 00000000..8861eaea --- /dev/null +++ b/libc/nt/ntdll/EtwReplyNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwReplyNotification diff --git a/libc/nt/ntdll/EtwSendNotification.s b/libc/nt/ntdll/EtwSendNotification.s new file mode 100644 index 00000000..ed09d030 --- /dev/null +++ b/libc/nt/ntdll/EtwSendNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwSendNotification diff --git a/libc/nt/ntdll/EtwSetMark.s b/libc/nt/ntdll/EtwSetMark.s new file mode 100644 index 00000000..bb2c5a82 --- /dev/null +++ b/libc/nt/ntdll/EtwSetMark.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwSetMark diff --git a/libc/nt/ntdll/EtwTraceEventInstance.s b/libc/nt/ntdll/EtwTraceEventInstance.s new file mode 100644 index 00000000..36dfc704 --- /dev/null +++ b/libc/nt/ntdll/EtwTraceEventInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwTraceEventInstance diff --git a/libc/nt/ntdll/EtwTraceMessage.s b/libc/nt/ntdll/EtwTraceMessage.s new file mode 100644 index 00000000..e96da425 --- /dev/null +++ b/libc/nt/ntdll/EtwTraceMessage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwTraceMessage diff --git a/libc/nt/ntdll/EtwTraceMessageVa.s b/libc/nt/ntdll/EtwTraceMessageVa.s new file mode 100644 index 00000000..f541bda5 --- /dev/null +++ b/libc/nt/ntdll/EtwTraceMessageVa.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwTraceMessageVa diff --git a/libc/nt/ntdll/EtwUnregisterTraceGuids.s b/libc/nt/ntdll/EtwUnregisterTraceGuids.s new file mode 100644 index 00000000..a0e1af97 --- /dev/null +++ b/libc/nt/ntdll/EtwUnregisterTraceGuids.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwUnregisterTraceGuids diff --git a/libc/nt/ntdll/EtwWriteUMSecurityEvent.s b/libc/nt/ntdll/EtwWriteUMSecurityEvent.s new file mode 100644 index 00000000..0024b304 --- /dev/null +++ b/libc/nt/ntdll/EtwWriteUMSecurityEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwWriteUMSecurityEvent diff --git a/libc/nt/ntdll/EtwpCreateEtwThread.s b/libc/nt/ntdll/EtwpCreateEtwThread.s new file mode 100644 index 00000000..f6401a98 --- /dev/null +++ b/libc/nt/ntdll/EtwpCreateEtwThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwpCreateEtwThread diff --git a/libc/nt/ntdll/EtwpGetCpuSpeed.s b/libc/nt/ntdll/EtwpGetCpuSpeed.s new file mode 100644 index 00000000..1060fa4c --- /dev/null +++ b/libc/nt/ntdll/EtwpGetCpuSpeed.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EtwpGetCpuSpeed diff --git a/libc/nt/ntdll/EvtIntReportAuthzEventAndSourceAsync.s b/libc/nt/ntdll/EvtIntReportAuthzEventAndSourceAsync.s new file mode 100644 index 00000000..dcd8178f --- /dev/null +++ b/libc/nt/ntdll/EvtIntReportAuthzEventAndSourceAsync.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EvtIntReportAuthzEventAndSourceAsync diff --git a/libc/nt/ntdll/EvtIntReportEventAndSourceAsync.s b/libc/nt/ntdll/EvtIntReportEventAndSourceAsync.s new file mode 100644 index 00000000..7d7b6620 --- /dev/null +++ b/libc/nt/ntdll/EvtIntReportEventAndSourceAsync.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp EvtIntReportEventAndSourceAsync diff --git a/libc/nt/ntdll/ExpInterlockedPopEntrySListEnd.s b/libc/nt/ntdll/ExpInterlockedPopEntrySListEnd.s new file mode 100644 index 00000000..3c59745a --- /dev/null +++ b/libc/nt/ntdll/ExpInterlockedPopEntrySListEnd.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ExpInterlockedPopEntrySListEnd diff --git a/libc/nt/ntdll/ExpInterlockedPopEntrySListFault.s b/libc/nt/ntdll/ExpInterlockedPopEntrySListFault.s new file mode 100644 index 00000000..70f841b7 --- /dev/null +++ b/libc/nt/ntdll/ExpInterlockedPopEntrySListFault.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ExpInterlockedPopEntrySListFault diff --git a/libc/nt/ntdll/ExpInterlockedPopEntrySListResume.s b/libc/nt/ntdll/ExpInterlockedPopEntrySListResume.s new file mode 100644 index 00000000..38261288 --- /dev/null +++ b/libc/nt/ntdll/ExpInterlockedPopEntrySListResume.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ExpInterlockedPopEntrySListResume diff --git a/libc/nt/ntdll/KiRaiseUserExceptionDispatcher.s b/libc/nt/ntdll/KiRaiseUserExceptionDispatcher.s new file mode 100644 index 00000000..04c7726e --- /dev/null +++ b/libc/nt/ntdll/KiRaiseUserExceptionDispatcher.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp KiRaiseUserExceptionDispatcher diff --git a/libc/nt/ntdll/KiUserApcDispatcher.s b/libc/nt/ntdll/KiUserApcDispatcher.s new file mode 100644 index 00000000..a55b5b9d --- /dev/null +++ b/libc/nt/ntdll/KiUserApcDispatcher.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp KiUserApcDispatcher diff --git a/libc/nt/ntdll/KiUserCallbackDispatcher.s b/libc/nt/ntdll/KiUserCallbackDispatcher.s new file mode 100644 index 00000000..225ab841 --- /dev/null +++ b/libc/nt/ntdll/KiUserCallbackDispatcher.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp KiUserCallbackDispatcher diff --git a/libc/nt/ntdll/KiUserExceptionDispatcher.s b/libc/nt/ntdll/KiUserExceptionDispatcher.s new file mode 100644 index 00000000..0b1c0ec9 --- /dev/null +++ b/libc/nt/ntdll/KiUserExceptionDispatcher.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp KiUserExceptionDispatcher diff --git a/libc/nt/ntdll/KiUserInvertedFunctionTable.s b/libc/nt/ntdll/KiUserInvertedFunctionTable.s new file mode 100644 index 00000000..4598c19d --- /dev/null +++ b/libc/nt/ntdll/KiUserInvertedFunctionTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp KiUserInvertedFunctionTable diff --git a/libc/nt/ntdll/LdrAccessResource.s b/libc/nt/ntdll/LdrAccessResource.s new file mode 100644 index 00000000..eb701ddf --- /dev/null +++ b/libc/nt/ntdll/LdrAccessResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrAccessResource diff --git a/libc/nt/ntdll/LdrAddDllDirectory.s b/libc/nt/ntdll/LdrAddDllDirectory.s new file mode 100644 index 00000000..cad91185 --- /dev/null +++ b/libc/nt/ntdll/LdrAddDllDirectory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrAddDllDirectory diff --git a/libc/nt/ntdll/LdrAddLoadAsDataTable.s b/libc/nt/ntdll/LdrAddLoadAsDataTable.s new file mode 100644 index 00000000..82689ba0 --- /dev/null +++ b/libc/nt/ntdll/LdrAddLoadAsDataTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrAddLoadAsDataTable diff --git a/libc/nt/ntdll/LdrAddRefDll.s b/libc/nt/ntdll/LdrAddRefDll.s new file mode 100644 index 00000000..461af24e --- /dev/null +++ b/libc/nt/ntdll/LdrAddRefDll.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrAddRefDll diff --git a/libc/nt/ntdll/LdrAppxHandleIntegrityFailure.s b/libc/nt/ntdll/LdrAppxHandleIntegrityFailure.s new file mode 100644 index 00000000..ce94cbb9 --- /dev/null +++ b/libc/nt/ntdll/LdrAppxHandleIntegrityFailure.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrAppxHandleIntegrityFailure diff --git a/libc/nt/ntdll/LdrCallEnclave.s b/libc/nt/ntdll/LdrCallEnclave.s new file mode 100644 index 00000000..b77a5bfe --- /dev/null +++ b/libc/nt/ntdll/LdrCallEnclave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrCallEnclave diff --git a/libc/nt/ntdll/LdrControlFlowGuardEnforced.s b/libc/nt/ntdll/LdrControlFlowGuardEnforced.s new file mode 100644 index 00000000..06f2bafb --- /dev/null +++ b/libc/nt/ntdll/LdrControlFlowGuardEnforced.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrControlFlowGuardEnforced diff --git a/libc/nt/ntdll/LdrCreateEnclave.s b/libc/nt/ntdll/LdrCreateEnclave.s new file mode 100644 index 00000000..ca85be92 --- /dev/null +++ b/libc/nt/ntdll/LdrCreateEnclave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrCreateEnclave diff --git a/libc/nt/ntdll/LdrDeleteEnclave.s b/libc/nt/ntdll/LdrDeleteEnclave.s new file mode 100644 index 00000000..6d5d8ec7 --- /dev/null +++ b/libc/nt/ntdll/LdrDeleteEnclave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrDeleteEnclave diff --git a/libc/nt/ntdll/LdrDisableThreadCalloutsForDll.s b/libc/nt/ntdll/LdrDisableThreadCalloutsForDll.s new file mode 100644 index 00000000..a218dbd6 --- /dev/null +++ b/libc/nt/ntdll/LdrDisableThreadCalloutsForDll.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrDisableThreadCalloutsForDll diff --git a/libc/nt/ntdll/LdrEnumResources.s b/libc/nt/ntdll/LdrEnumResources.s new file mode 100644 index 00000000..a10169ab --- /dev/null +++ b/libc/nt/ntdll/LdrEnumResources.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrEnumResources diff --git a/libc/nt/ntdll/LdrEnumerateLoadedModules.s b/libc/nt/ntdll/LdrEnumerateLoadedModules.s new file mode 100644 index 00000000..15454d5f --- /dev/null +++ b/libc/nt/ntdll/LdrEnumerateLoadedModules.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrEnumerateLoadedModules diff --git a/libc/nt/ntdll/LdrFastFailInLoaderCallout.s b/libc/nt/ntdll/LdrFastFailInLoaderCallout.s new file mode 100644 index 00000000..13ff6713 --- /dev/null +++ b/libc/nt/ntdll/LdrFastFailInLoaderCallout.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrFastFailInLoaderCallout diff --git a/libc/nt/ntdll/LdrFindEntryForAddress.s b/libc/nt/ntdll/LdrFindEntryForAddress.s new file mode 100644 index 00000000..d0a06369 --- /dev/null +++ b/libc/nt/ntdll/LdrFindEntryForAddress.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrFindEntryForAddress diff --git a/libc/nt/ntdll/LdrFindResourceDirectory_U.s b/libc/nt/ntdll/LdrFindResourceDirectory_U.s new file mode 100644 index 00000000..a002f81f --- /dev/null +++ b/libc/nt/ntdll/LdrFindResourceDirectory_U.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrFindResourceDirectory_U diff --git a/libc/nt/ntdll/LdrFindResourceEx_U.s b/libc/nt/ntdll/LdrFindResourceEx_U.s new file mode 100644 index 00000000..30ff8ff5 --- /dev/null +++ b/libc/nt/ntdll/LdrFindResourceEx_U.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrFindResourceEx_U diff --git a/libc/nt/ntdll/LdrFindResource_U.s b/libc/nt/ntdll/LdrFindResource_U.s new file mode 100644 index 00000000..d7184b3e --- /dev/null +++ b/libc/nt/ntdll/LdrFindResource_U.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrFindResource_U diff --git a/libc/nt/ntdll/LdrFlushAlternateResourceModules.s b/libc/nt/ntdll/LdrFlushAlternateResourceModules.s new file mode 100644 index 00000000..6f5732cf --- /dev/null +++ b/libc/nt/ntdll/LdrFlushAlternateResourceModules.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrFlushAlternateResourceModules diff --git a/libc/nt/ntdll/LdrGetDllDirectory.s b/libc/nt/ntdll/LdrGetDllDirectory.s new file mode 100644 index 00000000..daf5e697 --- /dev/null +++ b/libc/nt/ntdll/LdrGetDllDirectory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrGetDllDirectory diff --git a/libc/nt/ntdll/LdrGetDllFullName.s b/libc/nt/ntdll/LdrGetDllFullName.s new file mode 100644 index 00000000..e0b7f0de --- /dev/null +++ b/libc/nt/ntdll/LdrGetDllFullName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrGetDllFullName diff --git a/libc/nt/ntdll/LdrGetDllHandle.s b/libc/nt/ntdll/LdrGetDllHandle.s new file mode 100644 index 00000000..925365fd --- /dev/null +++ b/libc/nt/ntdll/LdrGetDllHandle.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrGetDllHandle + + .text.windows +LdrGetDllHandle: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_LdrGetDllHandle(%rip),%rax + jmp __sysv2nt + .endfn LdrGetDllHandle,globl + .previous diff --git a/libc/nt/ntdll/LdrGetDllHandleByMapping.s b/libc/nt/ntdll/LdrGetDllHandleByMapping.s new file mode 100644 index 00000000..d323ff11 --- /dev/null +++ b/libc/nt/ntdll/LdrGetDllHandleByMapping.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrGetDllHandleByMapping diff --git a/libc/nt/ntdll/LdrGetDllHandleByName.s b/libc/nt/ntdll/LdrGetDllHandleByName.s new file mode 100644 index 00000000..e2d2bd45 --- /dev/null +++ b/libc/nt/ntdll/LdrGetDllHandleByName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrGetDllHandleByName diff --git a/libc/nt/ntdll/LdrGetDllHandleEx.s b/libc/nt/ntdll/LdrGetDllHandleEx.s new file mode 100644 index 00000000..8ac9b87e --- /dev/null +++ b/libc/nt/ntdll/LdrGetDllHandleEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrGetDllHandleEx diff --git a/libc/nt/ntdll/LdrGetDllPath.s b/libc/nt/ntdll/LdrGetDllPath.s new file mode 100644 index 00000000..307e073f --- /dev/null +++ b/libc/nt/ntdll/LdrGetDllPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrGetDllPath diff --git a/libc/nt/ntdll/LdrGetFailureData.s b/libc/nt/ntdll/LdrGetFailureData.s new file mode 100644 index 00000000..4d5ed418 --- /dev/null +++ b/libc/nt/ntdll/LdrGetFailureData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrGetFailureData diff --git a/libc/nt/ntdll/LdrGetFileNameFromLoadAsDataTable.s b/libc/nt/ntdll/LdrGetFileNameFromLoadAsDataTable.s new file mode 100644 index 00000000..477215ff --- /dev/null +++ b/libc/nt/ntdll/LdrGetFileNameFromLoadAsDataTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrGetFileNameFromLoadAsDataTable diff --git a/libc/nt/ntdll/LdrGetKnownDllSectionHandle.s b/libc/nt/ntdll/LdrGetKnownDllSectionHandle.s new file mode 100644 index 00000000..56b8154f --- /dev/null +++ b/libc/nt/ntdll/LdrGetKnownDllSectionHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrGetKnownDllSectionHandle diff --git a/libc/nt/ntdll/LdrGetProcedureAddress.s b/libc/nt/ntdll/LdrGetProcedureAddress.s new file mode 100644 index 00000000..16dfd8de --- /dev/null +++ b/libc/nt/ntdll/LdrGetProcedureAddress.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrGetProcedureAddress + + .text.windows +LdrGetProcedureAddress: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_LdrGetProcedureAddress(%rip),%rax + jmp __sysv2nt + .endfn LdrGetProcedureAddress,globl + .previous diff --git a/libc/nt/ntdll/LdrGetProcedureAddressEx.s b/libc/nt/ntdll/LdrGetProcedureAddressEx.s new file mode 100644 index 00000000..6db15d70 --- /dev/null +++ b/libc/nt/ntdll/LdrGetProcedureAddressEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrGetProcedureAddressEx diff --git a/libc/nt/ntdll/LdrGetProcedureAddressForCaller.s b/libc/nt/ntdll/LdrGetProcedureAddressForCaller.s new file mode 100644 index 00000000..fc40c16e --- /dev/null +++ b/libc/nt/ntdll/LdrGetProcedureAddressForCaller.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrGetProcedureAddressForCaller diff --git a/libc/nt/ntdll/LdrInitShimEngineDynamic.s b/libc/nt/ntdll/LdrInitShimEngineDynamic.s new file mode 100644 index 00000000..114a079b --- /dev/null +++ b/libc/nt/ntdll/LdrInitShimEngineDynamic.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrInitShimEngineDynamic diff --git a/libc/nt/ntdll/LdrInitializeEnclave.s b/libc/nt/ntdll/LdrInitializeEnclave.s new file mode 100644 index 00000000..80cb4bb0 --- /dev/null +++ b/libc/nt/ntdll/LdrInitializeEnclave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrInitializeEnclave diff --git a/libc/nt/ntdll/LdrInitializeThunk.s b/libc/nt/ntdll/LdrInitializeThunk.s new file mode 100644 index 00000000..14bb0482 --- /dev/null +++ b/libc/nt/ntdll/LdrInitializeThunk.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrInitializeThunk diff --git a/libc/nt/ntdll/LdrLoadAlternateResourceModule.s b/libc/nt/ntdll/LdrLoadAlternateResourceModule.s new file mode 100644 index 00000000..7c72b1f0 --- /dev/null +++ b/libc/nt/ntdll/LdrLoadAlternateResourceModule.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrLoadAlternateResourceModule diff --git a/libc/nt/ntdll/LdrLoadAlternateResourceModuleEx.s b/libc/nt/ntdll/LdrLoadAlternateResourceModuleEx.s new file mode 100644 index 00000000..af58320f --- /dev/null +++ b/libc/nt/ntdll/LdrLoadAlternateResourceModuleEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrLoadAlternateResourceModuleEx diff --git a/libc/nt/ntdll/LdrLoadDll.s b/libc/nt/ntdll/LdrLoadDll.s new file mode 100644 index 00000000..814830ec --- /dev/null +++ b/libc/nt/ntdll/LdrLoadDll.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrLoadDll + + .text.windows +LdrLoadDll: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_LdrLoadDll(%rip),%rax + jmp __sysv2nt + .endfn LdrLoadDll,globl + .previous diff --git a/libc/nt/ntdll/LdrLoadEnclaveModule.s b/libc/nt/ntdll/LdrLoadEnclaveModule.s new file mode 100644 index 00000000..20390bd0 --- /dev/null +++ b/libc/nt/ntdll/LdrLoadEnclaveModule.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrLoadEnclaveModule diff --git a/libc/nt/ntdll/LdrLockLoaderLock.s b/libc/nt/ntdll/LdrLockLoaderLock.s new file mode 100644 index 00000000..e8604fc7 --- /dev/null +++ b/libc/nt/ntdll/LdrLockLoaderLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrLockLoaderLock diff --git a/libc/nt/ntdll/LdrOpenImageFileOptionsKey.s b/libc/nt/ntdll/LdrOpenImageFileOptionsKey.s new file mode 100644 index 00000000..c34e629c --- /dev/null +++ b/libc/nt/ntdll/LdrOpenImageFileOptionsKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrOpenImageFileOptionsKey diff --git a/libc/nt/ntdll/LdrProcessInitializationComplete.s b/libc/nt/ntdll/LdrProcessInitializationComplete.s new file mode 100644 index 00000000..8055ae92 --- /dev/null +++ b/libc/nt/ntdll/LdrProcessInitializationComplete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrProcessInitializationComplete diff --git a/libc/nt/ntdll/LdrProcessRelocationBlock.s b/libc/nt/ntdll/LdrProcessRelocationBlock.s new file mode 100644 index 00000000..d6315224 --- /dev/null +++ b/libc/nt/ntdll/LdrProcessRelocationBlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrProcessRelocationBlock diff --git a/libc/nt/ntdll/LdrProcessRelocationBlockEx.s b/libc/nt/ntdll/LdrProcessRelocationBlockEx.s new file mode 100644 index 00000000..ff143b2d --- /dev/null +++ b/libc/nt/ntdll/LdrProcessRelocationBlockEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrProcessRelocationBlockEx diff --git a/libc/nt/ntdll/LdrQueryImageFileExecutionOptions.s b/libc/nt/ntdll/LdrQueryImageFileExecutionOptions.s new file mode 100644 index 00000000..5845d765 --- /dev/null +++ b/libc/nt/ntdll/LdrQueryImageFileExecutionOptions.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrQueryImageFileExecutionOptions diff --git a/libc/nt/ntdll/LdrQueryImageFileExecutionOptionsEx.s b/libc/nt/ntdll/LdrQueryImageFileExecutionOptionsEx.s new file mode 100644 index 00000000..d0a6f111 --- /dev/null +++ b/libc/nt/ntdll/LdrQueryImageFileExecutionOptionsEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrQueryImageFileExecutionOptionsEx diff --git a/libc/nt/ntdll/LdrQueryImageFileKeyOption.s b/libc/nt/ntdll/LdrQueryImageFileKeyOption.s new file mode 100644 index 00000000..6f4f1d0b --- /dev/null +++ b/libc/nt/ntdll/LdrQueryImageFileKeyOption.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrQueryImageFileKeyOption diff --git a/libc/nt/ntdll/LdrQueryModuleServiceTags.s b/libc/nt/ntdll/LdrQueryModuleServiceTags.s new file mode 100644 index 00000000..d7cc59ec --- /dev/null +++ b/libc/nt/ntdll/LdrQueryModuleServiceTags.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrQueryModuleServiceTags diff --git a/libc/nt/ntdll/LdrQueryOptionalDelayLoadedAPI.s b/libc/nt/ntdll/LdrQueryOptionalDelayLoadedAPI.s new file mode 100644 index 00000000..bddf7763 --- /dev/null +++ b/libc/nt/ntdll/LdrQueryOptionalDelayLoadedAPI.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrQueryOptionalDelayLoadedAPI diff --git a/libc/nt/ntdll/LdrQueryProcessModuleInformation.s b/libc/nt/ntdll/LdrQueryProcessModuleInformation.s new file mode 100644 index 00000000..7e684cc2 --- /dev/null +++ b/libc/nt/ntdll/LdrQueryProcessModuleInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrQueryProcessModuleInformation diff --git a/libc/nt/ntdll/LdrRegisterDllNotification.s b/libc/nt/ntdll/LdrRegisterDllNotification.s new file mode 100644 index 00000000..8be754a9 --- /dev/null +++ b/libc/nt/ntdll/LdrRegisterDllNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrRegisterDllNotification diff --git a/libc/nt/ntdll/LdrRemoveDllDirectory.s b/libc/nt/ntdll/LdrRemoveDllDirectory.s new file mode 100644 index 00000000..d7285505 --- /dev/null +++ b/libc/nt/ntdll/LdrRemoveDllDirectory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrRemoveDllDirectory diff --git a/libc/nt/ntdll/LdrRemoveLoadAsDataTable.s b/libc/nt/ntdll/LdrRemoveLoadAsDataTable.s new file mode 100644 index 00000000..5a04ce84 --- /dev/null +++ b/libc/nt/ntdll/LdrRemoveLoadAsDataTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrRemoveLoadAsDataTable diff --git a/libc/nt/ntdll/LdrResFindResource.s b/libc/nt/ntdll/LdrResFindResource.s new file mode 100644 index 00000000..0c9c8300 --- /dev/null +++ b/libc/nt/ntdll/LdrResFindResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrResFindResource diff --git a/libc/nt/ntdll/LdrResFindResourceDirectory.s b/libc/nt/ntdll/LdrResFindResourceDirectory.s new file mode 100644 index 00000000..58bc46fc --- /dev/null +++ b/libc/nt/ntdll/LdrResFindResourceDirectory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrResFindResourceDirectory diff --git a/libc/nt/ntdll/LdrResGetRCConfig.s b/libc/nt/ntdll/LdrResGetRCConfig.s new file mode 100644 index 00000000..7431412f --- /dev/null +++ b/libc/nt/ntdll/LdrResGetRCConfig.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrResGetRCConfig diff --git a/libc/nt/ntdll/LdrResRelease.s b/libc/nt/ntdll/LdrResRelease.s new file mode 100644 index 00000000..55f079da --- /dev/null +++ b/libc/nt/ntdll/LdrResRelease.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrResRelease diff --git a/libc/nt/ntdll/LdrResSearchResource.s b/libc/nt/ntdll/LdrResSearchResource.s new file mode 100644 index 00000000..e65adb93 --- /dev/null +++ b/libc/nt/ntdll/LdrResSearchResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrResSearchResource diff --git a/libc/nt/ntdll/LdrResolveDelayLoadedAPI.s b/libc/nt/ntdll/LdrResolveDelayLoadedAPI.s new file mode 100644 index 00000000..c8d7aded --- /dev/null +++ b/libc/nt/ntdll/LdrResolveDelayLoadedAPI.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrResolveDelayLoadedAPI diff --git a/libc/nt/ntdll/LdrResolveDelayLoadsFromDll.s b/libc/nt/ntdll/LdrResolveDelayLoadsFromDll.s new file mode 100644 index 00000000..d24d2e19 --- /dev/null +++ b/libc/nt/ntdll/LdrResolveDelayLoadsFromDll.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrResolveDelayLoadsFromDll diff --git a/libc/nt/ntdll/LdrRscIsTypeExist.s b/libc/nt/ntdll/LdrRscIsTypeExist.s new file mode 100644 index 00000000..04228842 --- /dev/null +++ b/libc/nt/ntdll/LdrRscIsTypeExist.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrRscIsTypeExist diff --git a/libc/nt/ntdll/LdrSetAppCompatDllRedirectionCallback.s b/libc/nt/ntdll/LdrSetAppCompatDllRedirectionCallback.s new file mode 100644 index 00000000..ed928f67 --- /dev/null +++ b/libc/nt/ntdll/LdrSetAppCompatDllRedirectionCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrSetAppCompatDllRedirectionCallback diff --git a/libc/nt/ntdll/LdrSetDefaultDllDirectories.s b/libc/nt/ntdll/LdrSetDefaultDllDirectories.s new file mode 100644 index 00000000..5f91059f --- /dev/null +++ b/libc/nt/ntdll/LdrSetDefaultDllDirectories.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrSetDefaultDllDirectories diff --git a/libc/nt/ntdll/LdrSetDllDirectory.s b/libc/nt/ntdll/LdrSetDllDirectory.s new file mode 100644 index 00000000..4f793b2a --- /dev/null +++ b/libc/nt/ntdll/LdrSetDllDirectory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrSetDllDirectory diff --git a/libc/nt/ntdll/LdrSetDllManifestProber.s b/libc/nt/ntdll/LdrSetDllManifestProber.s new file mode 100644 index 00000000..34fe3d2a --- /dev/null +++ b/libc/nt/ntdll/LdrSetDllManifestProber.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrSetDllManifestProber diff --git a/libc/nt/ntdll/LdrSetImplicitPathOptions.s b/libc/nt/ntdll/LdrSetImplicitPathOptions.s new file mode 100644 index 00000000..8fe8f338 --- /dev/null +++ b/libc/nt/ntdll/LdrSetImplicitPathOptions.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrSetImplicitPathOptions diff --git a/libc/nt/ntdll/LdrSetMUICacheType.s b/libc/nt/ntdll/LdrSetMUICacheType.s new file mode 100644 index 00000000..2394501e --- /dev/null +++ b/libc/nt/ntdll/LdrSetMUICacheType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrSetMUICacheType diff --git a/libc/nt/ntdll/LdrShutdownProcess.s b/libc/nt/ntdll/LdrShutdownProcess.s new file mode 100644 index 00000000..fb664d25 --- /dev/null +++ b/libc/nt/ntdll/LdrShutdownProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrShutdownProcess diff --git a/libc/nt/ntdll/LdrShutdownThread.s b/libc/nt/ntdll/LdrShutdownThread.s new file mode 100644 index 00000000..70a6d2e8 --- /dev/null +++ b/libc/nt/ntdll/LdrShutdownThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrShutdownThread diff --git a/libc/nt/ntdll/LdrStandardizeSystemPath.s b/libc/nt/ntdll/LdrStandardizeSystemPath.s new file mode 100644 index 00000000..cfe920c3 --- /dev/null +++ b/libc/nt/ntdll/LdrStandardizeSystemPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrStandardizeSystemPath diff --git a/libc/nt/ntdll/LdrSystemDllInitBlock.s b/libc/nt/ntdll/LdrSystemDllInitBlock.s new file mode 100644 index 00000000..69ce60cb --- /dev/null +++ b/libc/nt/ntdll/LdrSystemDllInitBlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrSystemDllInitBlock diff --git a/libc/nt/ntdll/LdrUnloadAlternateResourceModule.s b/libc/nt/ntdll/LdrUnloadAlternateResourceModule.s new file mode 100644 index 00000000..748527a7 --- /dev/null +++ b/libc/nt/ntdll/LdrUnloadAlternateResourceModule.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrUnloadAlternateResourceModule diff --git a/libc/nt/ntdll/LdrUnloadAlternateResourceModuleEx.s b/libc/nt/ntdll/LdrUnloadAlternateResourceModuleEx.s new file mode 100644 index 00000000..9cebc72e --- /dev/null +++ b/libc/nt/ntdll/LdrUnloadAlternateResourceModuleEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrUnloadAlternateResourceModuleEx diff --git a/libc/nt/ntdll/LdrUnloadDll.s b/libc/nt/ntdll/LdrUnloadDll.s new file mode 100644 index 00000000..01761acf --- /dev/null +++ b/libc/nt/ntdll/LdrUnloadDll.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrUnloadDll + + .text.windows +LdrUnloadDll: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_LdrUnloadDll(%rip) + leave + ret + .endfn LdrUnloadDll,globl + .previous diff --git a/libc/nt/ntdll/LdrUnlockLoaderLock.s b/libc/nt/ntdll/LdrUnlockLoaderLock.s new file mode 100644 index 00000000..065b2cf4 --- /dev/null +++ b/libc/nt/ntdll/LdrUnlockLoaderLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrUnlockLoaderLock diff --git a/libc/nt/ntdll/LdrUnregisterDllNotification.s b/libc/nt/ntdll/LdrUnregisterDllNotification.s new file mode 100644 index 00000000..fef135dd --- /dev/null +++ b/libc/nt/ntdll/LdrUnregisterDllNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrUnregisterDllNotification diff --git a/libc/nt/ntdll/LdrUpdatePackageSearchPath.s b/libc/nt/ntdll/LdrUpdatePackageSearchPath.s new file mode 100644 index 00000000..6783dd6b --- /dev/null +++ b/libc/nt/ntdll/LdrUpdatePackageSearchPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrUpdatePackageSearchPath diff --git a/libc/nt/ntdll/LdrVerifyImageMatchesChecksum.s b/libc/nt/ntdll/LdrVerifyImageMatchesChecksum.s new file mode 100644 index 00000000..1f8f8dcf --- /dev/null +++ b/libc/nt/ntdll/LdrVerifyImageMatchesChecksum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrVerifyImageMatchesChecksum diff --git a/libc/nt/ntdll/LdrVerifyImageMatchesChecksumEx.s b/libc/nt/ntdll/LdrVerifyImageMatchesChecksumEx.s new file mode 100644 index 00000000..88583c9f --- /dev/null +++ b/libc/nt/ntdll/LdrVerifyImageMatchesChecksumEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrVerifyImageMatchesChecksumEx diff --git a/libc/nt/ntdll/LdrpResGetMappingSize.s b/libc/nt/ntdll/LdrpResGetMappingSize.s new file mode 100644 index 00000000..11e157e5 --- /dev/null +++ b/libc/nt/ntdll/LdrpResGetMappingSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrpResGetMappingSize diff --git a/libc/nt/ntdll/LdrpResGetResourceDirectory.s b/libc/nt/ntdll/LdrpResGetResourceDirectory.s new file mode 100644 index 00000000..23b6102d --- /dev/null +++ b/libc/nt/ntdll/LdrpResGetResourceDirectory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp LdrpResGetResourceDirectory diff --git a/libc/nt/ntdll/MD4Final.s b/libc/nt/ntdll/MD4Final.s new file mode 100644 index 00000000..5dc82443 --- /dev/null +++ b/libc/nt/ntdll/MD4Final.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp MD4Final diff --git a/libc/nt/ntdll/MD4Init.s b/libc/nt/ntdll/MD4Init.s new file mode 100644 index 00000000..e2c9cecf --- /dev/null +++ b/libc/nt/ntdll/MD4Init.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp MD4Init diff --git a/libc/nt/ntdll/MD4Update.s b/libc/nt/ntdll/MD4Update.s new file mode 100644 index 00000000..d5af8453 --- /dev/null +++ b/libc/nt/ntdll/MD4Update.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp MD4Update diff --git a/libc/nt/ntdll/MD5Final.s b/libc/nt/ntdll/MD5Final.s new file mode 100644 index 00000000..d800a5ee --- /dev/null +++ b/libc/nt/ntdll/MD5Final.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp MD5Final diff --git a/libc/nt/ntdll/MD5Init.s b/libc/nt/ntdll/MD5Init.s new file mode 100644 index 00000000..5103d62c --- /dev/null +++ b/libc/nt/ntdll/MD5Init.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp MD5Init diff --git a/libc/nt/ntdll/MD5Update.s b/libc/nt/ntdll/MD5Update.s new file mode 100644 index 00000000..d5965eb8 --- /dev/null +++ b/libc/nt/ntdll/MD5Update.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp MD5Update diff --git a/libc/nt/ntdll/NlsAnsiCodePage.s b/libc/nt/ntdll/NlsAnsiCodePage.s new file mode 100644 index 00000000..eb742120 --- /dev/null +++ b/libc/nt/ntdll/NlsAnsiCodePage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NlsAnsiCodePage diff --git a/libc/nt/ntdll/NlsMbCodePageTag.s b/libc/nt/ntdll/NlsMbCodePageTag.s new file mode 100644 index 00000000..4b1adbbe --- /dev/null +++ b/libc/nt/ntdll/NlsMbCodePageTag.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NlsMbCodePageTag diff --git a/libc/nt/ntdll/NlsMbOemCodePageTag.s b/libc/nt/ntdll/NlsMbOemCodePageTag.s new file mode 100644 index 00000000..434c1e94 --- /dev/null +++ b/libc/nt/ntdll/NlsMbOemCodePageTag.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NlsMbOemCodePageTag diff --git a/libc/nt/ntdll/NtAcceptConnectPort.s b/libc/nt/ntdll/NtAcceptConnectPort.s new file mode 100644 index 00000000..0d1d0489 --- /dev/null +++ b/libc/nt/ntdll/NtAcceptConnectPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAcceptConnectPort diff --git a/libc/nt/ntdll/NtAccessCheck.s b/libc/nt/ntdll/NtAccessCheck.s new file mode 100644 index 00000000..da282cc6 --- /dev/null +++ b/libc/nt/ntdll/NtAccessCheck.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAccessCheck diff --git a/libc/nt/ntdll/NtAccessCheckAndAuditAlarm.s b/libc/nt/ntdll/NtAccessCheckAndAuditAlarm.s new file mode 100644 index 00000000..9f2ffb27 --- /dev/null +++ b/libc/nt/ntdll/NtAccessCheckAndAuditAlarm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAccessCheckAndAuditAlarm diff --git a/libc/nt/ntdll/NtAccessCheckByType.s b/libc/nt/ntdll/NtAccessCheckByType.s new file mode 100644 index 00000000..209f99a3 --- /dev/null +++ b/libc/nt/ntdll/NtAccessCheckByType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAccessCheckByType diff --git a/libc/nt/ntdll/NtAccessCheckByTypeAndAuditAlarm.s b/libc/nt/ntdll/NtAccessCheckByTypeAndAuditAlarm.s new file mode 100644 index 00000000..1815350c --- /dev/null +++ b/libc/nt/ntdll/NtAccessCheckByTypeAndAuditAlarm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAccessCheckByTypeAndAuditAlarm diff --git a/libc/nt/ntdll/NtAccessCheckByTypeResultList.s b/libc/nt/ntdll/NtAccessCheckByTypeResultList.s new file mode 100644 index 00000000..6afab0e3 --- /dev/null +++ b/libc/nt/ntdll/NtAccessCheckByTypeResultList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAccessCheckByTypeResultList diff --git a/libc/nt/ntdll/NtAccessCheckByTypeResultListAndAuditAlarm.s b/libc/nt/ntdll/NtAccessCheckByTypeResultListAndAuditAlarm.s new file mode 100644 index 00000000..70ada82f --- /dev/null +++ b/libc/nt/ntdll/NtAccessCheckByTypeResultListAndAuditAlarm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAccessCheckByTypeResultListAndAuditAlarm diff --git a/libc/nt/ntdll/NtAccessCheckByTypeResultListAndAuditAlarmByHandle.s b/libc/nt/ntdll/NtAccessCheckByTypeResultListAndAuditAlarmByHandle.s new file mode 100644 index 00000000..7758d5d9 --- /dev/null +++ b/libc/nt/ntdll/NtAccessCheckByTypeResultListAndAuditAlarmByHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAccessCheckByTypeResultListAndAuditAlarmByHandle diff --git a/libc/nt/ntdll/NtAcquireProcessActivityReference.s b/libc/nt/ntdll/NtAcquireProcessActivityReference.s new file mode 100644 index 00000000..70e238f5 --- /dev/null +++ b/libc/nt/ntdll/NtAcquireProcessActivityReference.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAcquireProcessActivityReference diff --git a/libc/nt/ntdll/NtAddAtom.s b/libc/nt/ntdll/NtAddAtom.s new file mode 100644 index 00000000..f8b40fde --- /dev/null +++ b/libc/nt/ntdll/NtAddAtom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAddAtom diff --git a/libc/nt/ntdll/NtAddAtomEx.s b/libc/nt/ntdll/NtAddAtomEx.s new file mode 100644 index 00000000..f31cce14 --- /dev/null +++ b/libc/nt/ntdll/NtAddAtomEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAddAtomEx diff --git a/libc/nt/ntdll/NtAddBootEntry.s b/libc/nt/ntdll/NtAddBootEntry.s new file mode 100644 index 00000000..a5823d55 --- /dev/null +++ b/libc/nt/ntdll/NtAddBootEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAddBootEntry diff --git a/libc/nt/ntdll/NtAddDriverEntry.s b/libc/nt/ntdll/NtAddDriverEntry.s new file mode 100644 index 00000000..0c036fe0 --- /dev/null +++ b/libc/nt/ntdll/NtAddDriverEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAddDriverEntry diff --git a/libc/nt/ntdll/NtAdjustGroupsToken.s b/libc/nt/ntdll/NtAdjustGroupsToken.s new file mode 100644 index 00000000..68c10a1d --- /dev/null +++ b/libc/nt/ntdll/NtAdjustGroupsToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAdjustGroupsToken diff --git a/libc/nt/ntdll/NtAdjustPrivilegesToken.s b/libc/nt/ntdll/NtAdjustPrivilegesToken.s new file mode 100644 index 00000000..500f1b78 --- /dev/null +++ b/libc/nt/ntdll/NtAdjustPrivilegesToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAdjustPrivilegesToken diff --git a/libc/nt/ntdll/NtAdjustTokenClaimsAndDeviceGroups.s b/libc/nt/ntdll/NtAdjustTokenClaimsAndDeviceGroups.s new file mode 100644 index 00000000..3284784e --- /dev/null +++ b/libc/nt/ntdll/NtAdjustTokenClaimsAndDeviceGroups.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAdjustTokenClaimsAndDeviceGroups diff --git a/libc/nt/ntdll/NtAlertResumeThread.s b/libc/nt/ntdll/NtAlertResumeThread.s new file mode 100644 index 00000000..aa1078ae --- /dev/null +++ b/libc/nt/ntdll/NtAlertResumeThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlertResumeThread diff --git a/libc/nt/ntdll/NtAlertThread.s b/libc/nt/ntdll/NtAlertThread.s new file mode 100644 index 00000000..30d3f1af --- /dev/null +++ b/libc/nt/ntdll/NtAlertThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlertThread diff --git a/libc/nt/ntdll/NtAlertThreadByThreadId.s b/libc/nt/ntdll/NtAlertThreadByThreadId.s new file mode 100644 index 00000000..1910d7f3 --- /dev/null +++ b/libc/nt/ntdll/NtAlertThreadByThreadId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlertThreadByThreadId diff --git a/libc/nt/ntdll/NtAllocateLocallyUniqueId.s b/libc/nt/ntdll/NtAllocateLocallyUniqueId.s new file mode 100644 index 00000000..140445a9 --- /dev/null +++ b/libc/nt/ntdll/NtAllocateLocallyUniqueId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAllocateLocallyUniqueId diff --git a/libc/nt/ntdll/NtAllocateReserveObject.s b/libc/nt/ntdll/NtAllocateReserveObject.s new file mode 100644 index 00000000..a5bcf839 --- /dev/null +++ b/libc/nt/ntdll/NtAllocateReserveObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAllocateReserveObject diff --git a/libc/nt/ntdll/NtAllocateUserPhysicalPages.s b/libc/nt/ntdll/NtAllocateUserPhysicalPages.s new file mode 100644 index 00000000..12aa5044 --- /dev/null +++ b/libc/nt/ntdll/NtAllocateUserPhysicalPages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAllocateUserPhysicalPages diff --git a/libc/nt/ntdll/NtAllocateUuids.s b/libc/nt/ntdll/NtAllocateUuids.s new file mode 100644 index 00000000..8b341a6a --- /dev/null +++ b/libc/nt/ntdll/NtAllocateUuids.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAllocateUuids diff --git a/libc/nt/ntdll/NtAllocateVirtualMemory.s b/libc/nt/ntdll/NtAllocateVirtualMemory.s new file mode 100644 index 00000000..ce1411f3 --- /dev/null +++ b/libc/nt/ntdll/NtAllocateVirtualMemory.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAllocateVirtualMemory + + .text.windows +NtAllocateVirtualMemory: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtAllocateVirtualMemory(%rip),%rax + jmp __sysv2nt6 + .endfn NtAllocateVirtualMemory,globl + .previous diff --git a/libc/nt/ntdll/NtAllocateVirtualMemoryEx.s b/libc/nt/ntdll/NtAllocateVirtualMemoryEx.s new file mode 100644 index 00000000..062ed159 --- /dev/null +++ b/libc/nt/ntdll/NtAllocateVirtualMemoryEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAllocateVirtualMemoryEx diff --git a/libc/nt/ntdll/NtAlpcAcceptConnectPort.s b/libc/nt/ntdll/NtAlpcAcceptConnectPort.s new file mode 100644 index 00000000..a6bb9cfd --- /dev/null +++ b/libc/nt/ntdll/NtAlpcAcceptConnectPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcAcceptConnectPort diff --git a/libc/nt/ntdll/NtAlpcCancelMessage.s b/libc/nt/ntdll/NtAlpcCancelMessage.s new file mode 100644 index 00000000..0fcae9b5 --- /dev/null +++ b/libc/nt/ntdll/NtAlpcCancelMessage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcCancelMessage diff --git a/libc/nt/ntdll/NtAlpcConnectPort.s b/libc/nt/ntdll/NtAlpcConnectPort.s new file mode 100644 index 00000000..a4f89da1 --- /dev/null +++ b/libc/nt/ntdll/NtAlpcConnectPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcConnectPort diff --git a/libc/nt/ntdll/NtAlpcConnectPortEx.s b/libc/nt/ntdll/NtAlpcConnectPortEx.s new file mode 100644 index 00000000..feb4671d --- /dev/null +++ b/libc/nt/ntdll/NtAlpcConnectPortEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcConnectPortEx diff --git a/libc/nt/ntdll/NtAlpcCreatePort.s b/libc/nt/ntdll/NtAlpcCreatePort.s new file mode 100644 index 00000000..9a53d411 --- /dev/null +++ b/libc/nt/ntdll/NtAlpcCreatePort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcCreatePort diff --git a/libc/nt/ntdll/NtAlpcCreatePortSection.s b/libc/nt/ntdll/NtAlpcCreatePortSection.s new file mode 100644 index 00000000..66cb6180 --- /dev/null +++ b/libc/nt/ntdll/NtAlpcCreatePortSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcCreatePortSection diff --git a/libc/nt/ntdll/NtAlpcCreateResourceReserve.s b/libc/nt/ntdll/NtAlpcCreateResourceReserve.s new file mode 100644 index 00000000..70dd7585 --- /dev/null +++ b/libc/nt/ntdll/NtAlpcCreateResourceReserve.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcCreateResourceReserve diff --git a/libc/nt/ntdll/NtAlpcCreateSectionView.s b/libc/nt/ntdll/NtAlpcCreateSectionView.s new file mode 100644 index 00000000..608e680a --- /dev/null +++ b/libc/nt/ntdll/NtAlpcCreateSectionView.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcCreateSectionView diff --git a/libc/nt/ntdll/NtAlpcCreateSecurityContext.s b/libc/nt/ntdll/NtAlpcCreateSecurityContext.s new file mode 100644 index 00000000..75145713 --- /dev/null +++ b/libc/nt/ntdll/NtAlpcCreateSecurityContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcCreateSecurityContext diff --git a/libc/nt/ntdll/NtAlpcDeletePortSection.s b/libc/nt/ntdll/NtAlpcDeletePortSection.s new file mode 100644 index 00000000..1b2ae174 --- /dev/null +++ b/libc/nt/ntdll/NtAlpcDeletePortSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcDeletePortSection diff --git a/libc/nt/ntdll/NtAlpcDeleteResourceReserve.s b/libc/nt/ntdll/NtAlpcDeleteResourceReserve.s new file mode 100644 index 00000000..f80d8198 --- /dev/null +++ b/libc/nt/ntdll/NtAlpcDeleteResourceReserve.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcDeleteResourceReserve diff --git a/libc/nt/ntdll/NtAlpcDeleteSectionView.s b/libc/nt/ntdll/NtAlpcDeleteSectionView.s new file mode 100644 index 00000000..8d6a5842 --- /dev/null +++ b/libc/nt/ntdll/NtAlpcDeleteSectionView.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcDeleteSectionView diff --git a/libc/nt/ntdll/NtAlpcDeleteSecurityContext.s b/libc/nt/ntdll/NtAlpcDeleteSecurityContext.s new file mode 100644 index 00000000..c823a3e9 --- /dev/null +++ b/libc/nt/ntdll/NtAlpcDeleteSecurityContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcDeleteSecurityContext diff --git a/libc/nt/ntdll/NtAlpcDisconnectPort.s b/libc/nt/ntdll/NtAlpcDisconnectPort.s new file mode 100644 index 00000000..1c1bc57e --- /dev/null +++ b/libc/nt/ntdll/NtAlpcDisconnectPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcDisconnectPort diff --git a/libc/nt/ntdll/NtAlpcImpersonateClientContainerOfPort.s b/libc/nt/ntdll/NtAlpcImpersonateClientContainerOfPort.s new file mode 100644 index 00000000..97563c7d --- /dev/null +++ b/libc/nt/ntdll/NtAlpcImpersonateClientContainerOfPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcImpersonateClientContainerOfPort diff --git a/libc/nt/ntdll/NtAlpcImpersonateClientOfPort.s b/libc/nt/ntdll/NtAlpcImpersonateClientOfPort.s new file mode 100644 index 00000000..fca71aed --- /dev/null +++ b/libc/nt/ntdll/NtAlpcImpersonateClientOfPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcImpersonateClientOfPort diff --git a/libc/nt/ntdll/NtAlpcOpenSenderProcess.s b/libc/nt/ntdll/NtAlpcOpenSenderProcess.s new file mode 100644 index 00000000..90799fa5 --- /dev/null +++ b/libc/nt/ntdll/NtAlpcOpenSenderProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcOpenSenderProcess diff --git a/libc/nt/ntdll/NtAlpcOpenSenderThread.s b/libc/nt/ntdll/NtAlpcOpenSenderThread.s new file mode 100644 index 00000000..1318ad33 --- /dev/null +++ b/libc/nt/ntdll/NtAlpcOpenSenderThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcOpenSenderThread diff --git a/libc/nt/ntdll/NtAlpcQueryInformation.s b/libc/nt/ntdll/NtAlpcQueryInformation.s new file mode 100644 index 00000000..7009a14a --- /dev/null +++ b/libc/nt/ntdll/NtAlpcQueryInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcQueryInformation diff --git a/libc/nt/ntdll/NtAlpcQueryInformationMessage.s b/libc/nt/ntdll/NtAlpcQueryInformationMessage.s new file mode 100644 index 00000000..0d4262af --- /dev/null +++ b/libc/nt/ntdll/NtAlpcQueryInformationMessage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcQueryInformationMessage diff --git a/libc/nt/ntdll/NtAlpcRevokeSecurityContext.s b/libc/nt/ntdll/NtAlpcRevokeSecurityContext.s new file mode 100644 index 00000000..b5629b15 --- /dev/null +++ b/libc/nt/ntdll/NtAlpcRevokeSecurityContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcRevokeSecurityContext diff --git a/libc/nt/ntdll/NtAlpcSendWaitReceivePort.s b/libc/nt/ntdll/NtAlpcSendWaitReceivePort.s new file mode 100644 index 00000000..d7fea709 --- /dev/null +++ b/libc/nt/ntdll/NtAlpcSendWaitReceivePort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcSendWaitReceivePort diff --git a/libc/nt/ntdll/NtAlpcSetInformation.s b/libc/nt/ntdll/NtAlpcSetInformation.s new file mode 100644 index 00000000..c3f00ab8 --- /dev/null +++ b/libc/nt/ntdll/NtAlpcSetInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAlpcSetInformation diff --git a/libc/nt/ntdll/NtApphelpCacheControl.s b/libc/nt/ntdll/NtApphelpCacheControl.s new file mode 100644 index 00000000..54059b82 --- /dev/null +++ b/libc/nt/ntdll/NtApphelpCacheControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtApphelpCacheControl diff --git a/libc/nt/ntdll/NtAreMappedFilesTheSame.s b/libc/nt/ntdll/NtAreMappedFilesTheSame.s new file mode 100644 index 00000000..3b05bfa0 --- /dev/null +++ b/libc/nt/ntdll/NtAreMappedFilesTheSame.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAreMappedFilesTheSame diff --git a/libc/nt/ntdll/NtAssignProcessToJobObject.s b/libc/nt/ntdll/NtAssignProcessToJobObject.s new file mode 100644 index 00000000..1f00ce55 --- /dev/null +++ b/libc/nt/ntdll/NtAssignProcessToJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAssignProcessToJobObject diff --git a/libc/nt/ntdll/NtAssociateWaitCompletionPacket.s b/libc/nt/ntdll/NtAssociateWaitCompletionPacket.s new file mode 100644 index 00000000..3a766f7c --- /dev/null +++ b/libc/nt/ntdll/NtAssociateWaitCompletionPacket.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtAssociateWaitCompletionPacket diff --git a/libc/nt/ntdll/NtCallEnclave.s b/libc/nt/ntdll/NtCallEnclave.s new file mode 100644 index 00000000..9a2b8cb1 --- /dev/null +++ b/libc/nt/ntdll/NtCallEnclave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCallEnclave diff --git a/libc/nt/ntdll/NtCallbackReturn.s b/libc/nt/ntdll/NtCallbackReturn.s new file mode 100644 index 00000000..6000fdb1 --- /dev/null +++ b/libc/nt/ntdll/NtCallbackReturn.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCallbackReturn + + .text.windows +NtCallbackReturn: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtCallbackReturn(%rip),%rax + jmp __sysv2nt + .endfn NtCallbackReturn,globl + .previous diff --git a/libc/nt/ntdll/NtCancelIoFile.s b/libc/nt/ntdll/NtCancelIoFile.s new file mode 100644 index 00000000..6c2c6b80 --- /dev/null +++ b/libc/nt/ntdll/NtCancelIoFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCancelIoFile + + .text.windows +NtCancelIoFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtCancelIoFile(%rip),%rax + jmp __sysv2nt + .endfn NtCancelIoFile,globl + .previous diff --git a/libc/nt/ntdll/NtCancelIoFileEx.s b/libc/nt/ntdll/NtCancelIoFileEx.s new file mode 100644 index 00000000..67026e07 --- /dev/null +++ b/libc/nt/ntdll/NtCancelIoFileEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCancelIoFileEx diff --git a/libc/nt/ntdll/NtCancelSynchronousIoFile.s b/libc/nt/ntdll/NtCancelSynchronousIoFile.s new file mode 100644 index 00000000..f9b38a8c --- /dev/null +++ b/libc/nt/ntdll/NtCancelSynchronousIoFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCancelSynchronousIoFile diff --git a/libc/nt/ntdll/NtCancelTimer.s b/libc/nt/ntdll/NtCancelTimer.s new file mode 100644 index 00000000..3ef2a4b6 --- /dev/null +++ b/libc/nt/ntdll/NtCancelTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCancelTimer diff --git a/libc/nt/ntdll/NtCancelTimer2.s b/libc/nt/ntdll/NtCancelTimer2.s new file mode 100644 index 00000000..9aa6835c --- /dev/null +++ b/libc/nt/ntdll/NtCancelTimer2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCancelTimer2 diff --git a/libc/nt/ntdll/NtCancelWaitCompletionPacket.s b/libc/nt/ntdll/NtCancelWaitCompletionPacket.s new file mode 100644 index 00000000..6d4c5486 --- /dev/null +++ b/libc/nt/ntdll/NtCancelWaitCompletionPacket.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCancelWaitCompletionPacket diff --git a/libc/nt/ntdll/NtClearEvent.s b/libc/nt/ntdll/NtClearEvent.s new file mode 100644 index 00000000..e29dac4c --- /dev/null +++ b/libc/nt/ntdll/NtClearEvent.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtClearEvent + + .text.windows +NtClearEvent: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_NtClearEvent(%rip) + leave + ret + .endfn NtClearEvent,globl + .previous diff --git a/libc/nt/ntdll/NtClose.s b/libc/nt/ntdll/NtClose.s new file mode 100644 index 00000000..7f83c0ef --- /dev/null +++ b/libc/nt/ntdll/NtClose.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtClose + + .text.windows +NtClose: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_NtClose(%rip) + leave + ret + .endfn NtClose,globl + .previous diff --git a/libc/nt/ntdll/NtCloseObjectAuditAlarm.s b/libc/nt/ntdll/NtCloseObjectAuditAlarm.s new file mode 100644 index 00000000..f37531d4 --- /dev/null +++ b/libc/nt/ntdll/NtCloseObjectAuditAlarm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCloseObjectAuditAlarm diff --git a/libc/nt/ntdll/NtCommitComplete.s b/libc/nt/ntdll/NtCommitComplete.s new file mode 100644 index 00000000..576ae957 --- /dev/null +++ b/libc/nt/ntdll/NtCommitComplete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCommitComplete diff --git a/libc/nt/ntdll/NtCommitEnlistment.s b/libc/nt/ntdll/NtCommitEnlistment.s new file mode 100644 index 00000000..f025a83a --- /dev/null +++ b/libc/nt/ntdll/NtCommitEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCommitEnlistment diff --git a/libc/nt/ntdll/NtCommitRegistryTransaction.s b/libc/nt/ntdll/NtCommitRegistryTransaction.s new file mode 100644 index 00000000..7604a342 --- /dev/null +++ b/libc/nt/ntdll/NtCommitRegistryTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCommitRegistryTransaction diff --git a/libc/nt/ntdll/NtCommitTransaction.s b/libc/nt/ntdll/NtCommitTransaction.s new file mode 100644 index 00000000..80995e49 --- /dev/null +++ b/libc/nt/ntdll/NtCommitTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCommitTransaction diff --git a/libc/nt/ntdll/NtCompactKeys.s b/libc/nt/ntdll/NtCompactKeys.s new file mode 100644 index 00000000..a88701e0 --- /dev/null +++ b/libc/nt/ntdll/NtCompactKeys.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCompactKeys diff --git a/libc/nt/ntdll/NtCompareObjects.s b/libc/nt/ntdll/NtCompareObjects.s new file mode 100644 index 00000000..54de6a42 --- /dev/null +++ b/libc/nt/ntdll/NtCompareObjects.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCompareObjects diff --git a/libc/nt/ntdll/NtCompareSigningLevels.s b/libc/nt/ntdll/NtCompareSigningLevels.s new file mode 100644 index 00000000..6c249f99 --- /dev/null +++ b/libc/nt/ntdll/NtCompareSigningLevels.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCompareSigningLevels diff --git a/libc/nt/ntdll/NtCompareTokens.s b/libc/nt/ntdll/NtCompareTokens.s new file mode 100644 index 00000000..9a7080da --- /dev/null +++ b/libc/nt/ntdll/NtCompareTokens.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCompareTokens diff --git a/libc/nt/ntdll/NtCompleteConnectPort.s b/libc/nt/ntdll/NtCompleteConnectPort.s new file mode 100644 index 00000000..2579a6f5 --- /dev/null +++ b/libc/nt/ntdll/NtCompleteConnectPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCompleteConnectPort diff --git a/libc/nt/ntdll/NtCompressKey.s b/libc/nt/ntdll/NtCompressKey.s new file mode 100644 index 00000000..b0d3b096 --- /dev/null +++ b/libc/nt/ntdll/NtCompressKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCompressKey diff --git a/libc/nt/ntdll/NtConnectPort.s b/libc/nt/ntdll/NtConnectPort.s new file mode 100644 index 00000000..ebe47785 --- /dev/null +++ b/libc/nt/ntdll/NtConnectPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtConnectPort diff --git a/libc/nt/ntdll/NtContinue.s b/libc/nt/ntdll/NtContinue.s new file mode 100644 index 00000000..74ff1d6e --- /dev/null +++ b/libc/nt/ntdll/NtContinue.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtContinue + + .text.windows +NtContinue: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtContinue(%rip),%rax + jmp __sysv2nt + .endfn NtContinue,globl + .previous diff --git a/libc/nt/ntdll/NtConvertBetweenAuxiliaryCounterAndPerformanceCounter.s b/libc/nt/ntdll/NtConvertBetweenAuxiliaryCounterAndPerformanceCounter.s new file mode 100644 index 00000000..4dbc8d03 --- /dev/null +++ b/libc/nt/ntdll/NtConvertBetweenAuxiliaryCounterAndPerformanceCounter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtConvertBetweenAuxiliaryCounterAndPerformanceCounter diff --git a/libc/nt/ntdll/NtCreateDebugObject.s b/libc/nt/ntdll/NtCreateDebugObject.s new file mode 100644 index 00000000..9c5d906c --- /dev/null +++ b/libc/nt/ntdll/NtCreateDebugObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateDebugObject diff --git a/libc/nt/ntdll/NtCreateDirectoryObject.s b/libc/nt/ntdll/NtCreateDirectoryObject.s new file mode 100644 index 00000000..a0e7bdfb --- /dev/null +++ b/libc/nt/ntdll/NtCreateDirectoryObject.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateDirectoryObject + + .text.windows +NtCreateDirectoryObject: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtCreateDirectoryObject(%rip),%rax + jmp __sysv2nt + .endfn NtCreateDirectoryObject,globl + .previous diff --git a/libc/nt/ntdll/NtCreateDirectoryObjectEx.s b/libc/nt/ntdll/NtCreateDirectoryObjectEx.s new file mode 100644 index 00000000..c3f959de --- /dev/null +++ b/libc/nt/ntdll/NtCreateDirectoryObjectEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateDirectoryObjectEx diff --git a/libc/nt/ntdll/NtCreateEnclave.s b/libc/nt/ntdll/NtCreateEnclave.s new file mode 100644 index 00000000..83e95850 --- /dev/null +++ b/libc/nt/ntdll/NtCreateEnclave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateEnclave diff --git a/libc/nt/ntdll/NtCreateEnlistment.s b/libc/nt/ntdll/NtCreateEnlistment.s new file mode 100644 index 00000000..d92ac163 --- /dev/null +++ b/libc/nt/ntdll/NtCreateEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateEnlistment diff --git a/libc/nt/ntdll/NtCreateEvent.s b/libc/nt/ntdll/NtCreateEvent.s new file mode 100644 index 00000000..2dacaa39 --- /dev/null +++ b/libc/nt/ntdll/NtCreateEvent.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateEvent + + .text.windows +NtCreateEvent: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtCreateEvent(%rip),%rax + jmp __sysv2nt6 + .endfn NtCreateEvent,globl + .previous diff --git a/libc/nt/ntdll/NtCreateEventPair.s b/libc/nt/ntdll/NtCreateEventPair.s new file mode 100644 index 00000000..093133c1 --- /dev/null +++ b/libc/nt/ntdll/NtCreateEventPair.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateEventPair diff --git a/libc/nt/ntdll/NtCreateFile.s b/libc/nt/ntdll/NtCreateFile.s new file mode 100644 index 00000000..9ed5cfd8 --- /dev/null +++ b/libc/nt/ntdll/NtCreateFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateFile + + .text.windows +NtCreateFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtCreateFile(%rip),%rax + jmp __sysv2nt12 + .endfn NtCreateFile,globl + .previous diff --git a/libc/nt/ntdll/NtCreateIRTimer.s b/libc/nt/ntdll/NtCreateIRTimer.s new file mode 100644 index 00000000..86a93e8b --- /dev/null +++ b/libc/nt/ntdll/NtCreateIRTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateIRTimer diff --git a/libc/nt/ntdll/NtCreateIoCompletion.s b/libc/nt/ntdll/NtCreateIoCompletion.s new file mode 100644 index 00000000..d852537c --- /dev/null +++ b/libc/nt/ntdll/NtCreateIoCompletion.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateIoCompletion + + .text.windows +NtCreateIoCompletion: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtCreateIoCompletion(%rip),%rax + jmp __sysv2nt + .endfn NtCreateIoCompletion,globl + .previous diff --git a/libc/nt/ntdll/NtCreateJobObject.s b/libc/nt/ntdll/NtCreateJobObject.s new file mode 100644 index 00000000..9b3ce146 --- /dev/null +++ b/libc/nt/ntdll/NtCreateJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateJobObject diff --git a/libc/nt/ntdll/NtCreateJobSet.s b/libc/nt/ntdll/NtCreateJobSet.s new file mode 100644 index 00000000..26e48725 --- /dev/null +++ b/libc/nt/ntdll/NtCreateJobSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateJobSet diff --git a/libc/nt/ntdll/NtCreateKey.s b/libc/nt/ntdll/NtCreateKey.s new file mode 100644 index 00000000..c7c0dc9d --- /dev/null +++ b/libc/nt/ntdll/NtCreateKey.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateKey + + .text.windows +NtCreateKey: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtCreateKey(%rip),%rax + jmp __sysv2nt8 + .endfn NtCreateKey,globl + .previous diff --git a/libc/nt/ntdll/NtCreateKeyTransacted.s b/libc/nt/ntdll/NtCreateKeyTransacted.s new file mode 100644 index 00000000..476e9c32 --- /dev/null +++ b/libc/nt/ntdll/NtCreateKeyTransacted.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateKeyTransacted diff --git a/libc/nt/ntdll/NtCreateKeyedEvent.s b/libc/nt/ntdll/NtCreateKeyedEvent.s new file mode 100644 index 00000000..9f592845 --- /dev/null +++ b/libc/nt/ntdll/NtCreateKeyedEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateKeyedEvent diff --git a/libc/nt/ntdll/NtCreateLowBoxToken.s b/libc/nt/ntdll/NtCreateLowBoxToken.s new file mode 100644 index 00000000..56e48ea7 --- /dev/null +++ b/libc/nt/ntdll/NtCreateLowBoxToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateLowBoxToken diff --git a/libc/nt/ntdll/NtCreateMailslotFile.s b/libc/nt/ntdll/NtCreateMailslotFile.s new file mode 100644 index 00000000..52b23c16 --- /dev/null +++ b/libc/nt/ntdll/NtCreateMailslotFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateMailslotFile diff --git a/libc/nt/ntdll/NtCreateMutant.s b/libc/nt/ntdll/NtCreateMutant.s new file mode 100644 index 00000000..6d36cab2 --- /dev/null +++ b/libc/nt/ntdll/NtCreateMutant.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateMutant diff --git a/libc/nt/ntdll/NtCreateNamedPipeFile.s b/libc/nt/ntdll/NtCreateNamedPipeFile.s new file mode 100644 index 00000000..a25ff21b --- /dev/null +++ b/libc/nt/ntdll/NtCreateNamedPipeFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateNamedPipeFile + + .text.windows +NtCreateNamedPipeFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtCreateNamedPipeFile(%rip),%rax + jmp __sysv2nt14 + .endfn NtCreateNamedPipeFile,globl + .previous diff --git a/libc/nt/ntdll/NtCreatePagingFile.s b/libc/nt/ntdll/NtCreatePagingFile.s new file mode 100644 index 00000000..380e1891 --- /dev/null +++ b/libc/nt/ntdll/NtCreatePagingFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreatePagingFile diff --git a/libc/nt/ntdll/NtCreatePartition.s b/libc/nt/ntdll/NtCreatePartition.s new file mode 100644 index 00000000..422c7111 --- /dev/null +++ b/libc/nt/ntdll/NtCreatePartition.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreatePartition diff --git a/libc/nt/ntdll/NtCreatePort.s b/libc/nt/ntdll/NtCreatePort.s new file mode 100644 index 00000000..fb6c3ebd --- /dev/null +++ b/libc/nt/ntdll/NtCreatePort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreatePort diff --git a/libc/nt/ntdll/NtCreatePrivateNamespace.s b/libc/nt/ntdll/NtCreatePrivateNamespace.s new file mode 100644 index 00000000..3b9bbbd5 --- /dev/null +++ b/libc/nt/ntdll/NtCreatePrivateNamespace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreatePrivateNamespace diff --git a/libc/nt/ntdll/NtCreateProcess.s b/libc/nt/ntdll/NtCreateProcess.s new file mode 100644 index 00000000..689cac99 --- /dev/null +++ b/libc/nt/ntdll/NtCreateProcess.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateProcess + + .text.windows +NtCreateProcess: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtCreateProcess(%rip),%rax + jmp __sysv2nt8 + .endfn NtCreateProcess,globl + .previous diff --git a/libc/nt/ntdll/NtCreateProcessEx.s b/libc/nt/ntdll/NtCreateProcessEx.s new file mode 100644 index 00000000..b8503939 --- /dev/null +++ b/libc/nt/ntdll/NtCreateProcessEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateProcessEx diff --git a/libc/nt/ntdll/NtCreateProfile.s b/libc/nt/ntdll/NtCreateProfile.s new file mode 100644 index 00000000..3aa7ba6e --- /dev/null +++ b/libc/nt/ntdll/NtCreateProfile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateProfile + + .text.windows +NtCreateProfile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtCreateProfile(%rip),%rax + jmp __sysv2nt10 + .endfn NtCreateProfile,globl + .previous diff --git a/libc/nt/ntdll/NtCreateProfileEx.s b/libc/nt/ntdll/NtCreateProfileEx.s new file mode 100644 index 00000000..663dc890 --- /dev/null +++ b/libc/nt/ntdll/NtCreateProfileEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateProfileEx diff --git a/libc/nt/ntdll/NtCreateRegistryTransaction.s b/libc/nt/ntdll/NtCreateRegistryTransaction.s new file mode 100644 index 00000000..5a2a5fa4 --- /dev/null +++ b/libc/nt/ntdll/NtCreateRegistryTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateRegistryTransaction diff --git a/libc/nt/ntdll/NtCreateResourceManager.s b/libc/nt/ntdll/NtCreateResourceManager.s new file mode 100644 index 00000000..f12bb8f3 --- /dev/null +++ b/libc/nt/ntdll/NtCreateResourceManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateResourceManager diff --git a/libc/nt/ntdll/NtCreateSection.s b/libc/nt/ntdll/NtCreateSection.s new file mode 100644 index 00000000..1d9da9dc --- /dev/null +++ b/libc/nt/ntdll/NtCreateSection.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateSection + + .text.windows +NtCreateSection: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtCreateSection(%rip),%rax + jmp __sysv2nt8 + .endfn NtCreateSection,globl + .previous diff --git a/libc/nt/ntdll/NtCreateSemaphore.s b/libc/nt/ntdll/NtCreateSemaphore.s new file mode 100644 index 00000000..40d8d45e --- /dev/null +++ b/libc/nt/ntdll/NtCreateSemaphore.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateSemaphore diff --git a/libc/nt/ntdll/NtCreateSymbolicLinkObject.s b/libc/nt/ntdll/NtCreateSymbolicLinkObject.s new file mode 100644 index 00000000..d5b8edf6 --- /dev/null +++ b/libc/nt/ntdll/NtCreateSymbolicLinkObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateSymbolicLinkObject diff --git a/libc/nt/ntdll/NtCreateThread.s b/libc/nt/ntdll/NtCreateThread.s new file mode 100644 index 00000000..3e6cf0d7 --- /dev/null +++ b/libc/nt/ntdll/NtCreateThread.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateThread + + .text.windows +NtCreateThread: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtCreateThread(%rip),%rax + jmp __sysv2nt8 + .endfn NtCreateThread,globl + .previous diff --git a/libc/nt/ntdll/NtCreateThreadEx.s b/libc/nt/ntdll/NtCreateThreadEx.s new file mode 100644 index 00000000..e15926e7 --- /dev/null +++ b/libc/nt/ntdll/NtCreateThreadEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateThreadEx diff --git a/libc/nt/ntdll/NtCreateTimer.s b/libc/nt/ntdll/NtCreateTimer.s new file mode 100644 index 00000000..e7ef043a --- /dev/null +++ b/libc/nt/ntdll/NtCreateTimer.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateTimer + + .text.windows +NtCreateTimer: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtCreateTimer(%rip),%rax + jmp __sysv2nt + .endfn NtCreateTimer,globl + .previous diff --git a/libc/nt/ntdll/NtCreateTimer2.s b/libc/nt/ntdll/NtCreateTimer2.s new file mode 100644 index 00000000..36a3821a --- /dev/null +++ b/libc/nt/ntdll/NtCreateTimer2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateTimer2 diff --git a/libc/nt/ntdll/NtCreateToken.s b/libc/nt/ntdll/NtCreateToken.s new file mode 100644 index 00000000..9b3e0037 --- /dev/null +++ b/libc/nt/ntdll/NtCreateToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateToken diff --git a/libc/nt/ntdll/NtCreateTokenEx.s b/libc/nt/ntdll/NtCreateTokenEx.s new file mode 100644 index 00000000..dbd5b1a8 --- /dev/null +++ b/libc/nt/ntdll/NtCreateTokenEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateTokenEx diff --git a/libc/nt/ntdll/NtCreateTransaction.s b/libc/nt/ntdll/NtCreateTransaction.s new file mode 100644 index 00000000..49dbc4b5 --- /dev/null +++ b/libc/nt/ntdll/NtCreateTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateTransaction diff --git a/libc/nt/ntdll/NtCreateTransactionManager.s b/libc/nt/ntdll/NtCreateTransactionManager.s new file mode 100644 index 00000000..6c59e09d --- /dev/null +++ b/libc/nt/ntdll/NtCreateTransactionManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateTransactionManager diff --git a/libc/nt/ntdll/NtCreateUserProcess.s b/libc/nt/ntdll/NtCreateUserProcess.s new file mode 100644 index 00000000..c7f38c68 --- /dev/null +++ b/libc/nt/ntdll/NtCreateUserProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateUserProcess diff --git a/libc/nt/ntdll/NtCreateWaitCompletionPacket.s b/libc/nt/ntdll/NtCreateWaitCompletionPacket.s new file mode 100644 index 00000000..2bb712c5 --- /dev/null +++ b/libc/nt/ntdll/NtCreateWaitCompletionPacket.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateWaitCompletionPacket diff --git a/libc/nt/ntdll/NtCreateWaitablePort.s b/libc/nt/ntdll/NtCreateWaitablePort.s new file mode 100644 index 00000000..e504dc6b --- /dev/null +++ b/libc/nt/ntdll/NtCreateWaitablePort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateWaitablePort diff --git a/libc/nt/ntdll/NtCreateWnfStateName.s b/libc/nt/ntdll/NtCreateWnfStateName.s new file mode 100644 index 00000000..88dd2639 --- /dev/null +++ b/libc/nt/ntdll/NtCreateWnfStateName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateWnfStateName diff --git a/libc/nt/ntdll/NtCreateWorkerFactory.s b/libc/nt/ntdll/NtCreateWorkerFactory.s new file mode 100644 index 00000000..467a0c6d --- /dev/null +++ b/libc/nt/ntdll/NtCreateWorkerFactory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtCreateWorkerFactory diff --git a/libc/nt/ntdll/NtDebugActiveProcess.s b/libc/nt/ntdll/NtDebugActiveProcess.s new file mode 100644 index 00000000..30d97b37 --- /dev/null +++ b/libc/nt/ntdll/NtDebugActiveProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDebugActiveProcess diff --git a/libc/nt/ntdll/NtDebugContinue.s b/libc/nt/ntdll/NtDebugContinue.s new file mode 100644 index 00000000..5a01ae42 --- /dev/null +++ b/libc/nt/ntdll/NtDebugContinue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDebugContinue diff --git a/libc/nt/ntdll/NtDelayExecution.s b/libc/nt/ntdll/NtDelayExecution.s new file mode 100644 index 00000000..3f167d36 --- /dev/null +++ b/libc/nt/ntdll/NtDelayExecution.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDelayExecution + + .text.windows +NtDelayExecution: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtDelayExecution(%rip),%rax + jmp __sysv2nt + .endfn NtDelayExecution,globl + .previous diff --git a/libc/nt/ntdll/NtDeleteAtom.s b/libc/nt/ntdll/NtDeleteAtom.s new file mode 100644 index 00000000..6064766a --- /dev/null +++ b/libc/nt/ntdll/NtDeleteAtom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDeleteAtom diff --git a/libc/nt/ntdll/NtDeleteBootEntry.s b/libc/nt/ntdll/NtDeleteBootEntry.s new file mode 100644 index 00000000..f959686b --- /dev/null +++ b/libc/nt/ntdll/NtDeleteBootEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDeleteBootEntry diff --git a/libc/nt/ntdll/NtDeleteDriverEntry.s b/libc/nt/ntdll/NtDeleteDriverEntry.s new file mode 100644 index 00000000..b272456f --- /dev/null +++ b/libc/nt/ntdll/NtDeleteDriverEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDeleteDriverEntry diff --git a/libc/nt/ntdll/NtDeleteFile.s b/libc/nt/ntdll/NtDeleteFile.s new file mode 100644 index 00000000..576f4838 --- /dev/null +++ b/libc/nt/ntdll/NtDeleteFile.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDeleteFile + + .text.windows +NtDeleteFile: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_NtDeleteFile(%rip) + leave + ret + .endfn NtDeleteFile,globl + .previous diff --git a/libc/nt/ntdll/NtDeleteKey.s b/libc/nt/ntdll/NtDeleteKey.s new file mode 100644 index 00000000..96b20e9e --- /dev/null +++ b/libc/nt/ntdll/NtDeleteKey.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDeleteKey + + .text.windows +NtDeleteKey: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_NtDeleteKey(%rip) + leave + ret + .endfn NtDeleteKey,globl + .previous diff --git a/libc/nt/ntdll/NtDeleteObjectAuditAlarm.s b/libc/nt/ntdll/NtDeleteObjectAuditAlarm.s new file mode 100644 index 00000000..966da395 --- /dev/null +++ b/libc/nt/ntdll/NtDeleteObjectAuditAlarm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDeleteObjectAuditAlarm diff --git a/libc/nt/ntdll/NtDeletePrivateNamespace.s b/libc/nt/ntdll/NtDeletePrivateNamespace.s new file mode 100644 index 00000000..4d540b8d --- /dev/null +++ b/libc/nt/ntdll/NtDeletePrivateNamespace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDeletePrivateNamespace diff --git a/libc/nt/ntdll/NtDeleteValueKey.s b/libc/nt/ntdll/NtDeleteValueKey.s new file mode 100644 index 00000000..16722052 --- /dev/null +++ b/libc/nt/ntdll/NtDeleteValueKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDeleteValueKey diff --git a/libc/nt/ntdll/NtDeleteWnfStateData.s b/libc/nt/ntdll/NtDeleteWnfStateData.s new file mode 100644 index 00000000..4ca480ce --- /dev/null +++ b/libc/nt/ntdll/NtDeleteWnfStateData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDeleteWnfStateData diff --git a/libc/nt/ntdll/NtDeleteWnfStateName.s b/libc/nt/ntdll/NtDeleteWnfStateName.s new file mode 100644 index 00000000..f567c365 --- /dev/null +++ b/libc/nt/ntdll/NtDeleteWnfStateName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDeleteWnfStateName diff --git a/libc/nt/ntdll/NtDeviceIoControlFile.s b/libc/nt/ntdll/NtDeviceIoControlFile.s new file mode 100644 index 00000000..6c52f2a6 --- /dev/null +++ b/libc/nt/ntdll/NtDeviceIoControlFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDeviceIoControlFile + + .text.windows +NtDeviceIoControlFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtDeviceIoControlFile(%rip),%rax + jmp __sysv2nt10 + .endfn NtDeviceIoControlFile,globl + .previous diff --git a/libc/nt/ntdll/NtDisableLastKnownGood.s b/libc/nt/ntdll/NtDisableLastKnownGood.s new file mode 100644 index 00000000..aebd1529 --- /dev/null +++ b/libc/nt/ntdll/NtDisableLastKnownGood.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDisableLastKnownGood diff --git a/libc/nt/ntdll/NtDisplayString.s b/libc/nt/ntdll/NtDisplayString.s new file mode 100644 index 00000000..3abb9ca8 --- /dev/null +++ b/libc/nt/ntdll/NtDisplayString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDisplayString diff --git a/libc/nt/ntdll/NtDrawText.s b/libc/nt/ntdll/NtDrawText.s new file mode 100644 index 00000000..13a5ed9d --- /dev/null +++ b/libc/nt/ntdll/NtDrawText.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDrawText diff --git a/libc/nt/ntdll/NtDuplicateObject.s b/libc/nt/ntdll/NtDuplicateObject.s new file mode 100644 index 00000000..7e2edf33 --- /dev/null +++ b/libc/nt/ntdll/NtDuplicateObject.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDuplicateObject + + .text.windows +NtDuplicateObject: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtDuplicateObject(%rip),%rax + jmp __sysv2nt8 + .endfn NtDuplicateObject,globl + .previous diff --git a/libc/nt/ntdll/NtDuplicateToken.s b/libc/nt/ntdll/NtDuplicateToken.s new file mode 100644 index 00000000..3dbaffbf --- /dev/null +++ b/libc/nt/ntdll/NtDuplicateToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtDuplicateToken diff --git a/libc/nt/ntdll/NtEnableLastKnownGood.s b/libc/nt/ntdll/NtEnableLastKnownGood.s new file mode 100644 index 00000000..58ae9da5 --- /dev/null +++ b/libc/nt/ntdll/NtEnableLastKnownGood.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtEnableLastKnownGood diff --git a/libc/nt/ntdll/NtEnumerateBootEntries.s b/libc/nt/ntdll/NtEnumerateBootEntries.s new file mode 100644 index 00000000..7931a339 --- /dev/null +++ b/libc/nt/ntdll/NtEnumerateBootEntries.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtEnumerateBootEntries diff --git a/libc/nt/ntdll/NtEnumerateDriverEntries.s b/libc/nt/ntdll/NtEnumerateDriverEntries.s new file mode 100644 index 00000000..80ee24e5 --- /dev/null +++ b/libc/nt/ntdll/NtEnumerateDriverEntries.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtEnumerateDriverEntries diff --git a/libc/nt/ntdll/NtEnumerateKey.s b/libc/nt/ntdll/NtEnumerateKey.s new file mode 100644 index 00000000..d42a7aa4 --- /dev/null +++ b/libc/nt/ntdll/NtEnumerateKey.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtEnumerateKey + + .text.windows +NtEnumerateKey: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtEnumerateKey(%rip),%rax + jmp __sysv2nt6 + .endfn NtEnumerateKey,globl + .previous diff --git a/libc/nt/ntdll/NtEnumerateSystemEnvironmentValuesEx.s b/libc/nt/ntdll/NtEnumerateSystemEnvironmentValuesEx.s new file mode 100644 index 00000000..51bd5cf2 --- /dev/null +++ b/libc/nt/ntdll/NtEnumerateSystemEnvironmentValuesEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtEnumerateSystemEnvironmentValuesEx diff --git a/libc/nt/ntdll/NtEnumerateTransactionObject.s b/libc/nt/ntdll/NtEnumerateTransactionObject.s new file mode 100644 index 00000000..91a8b2fb --- /dev/null +++ b/libc/nt/ntdll/NtEnumerateTransactionObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtEnumerateTransactionObject diff --git a/libc/nt/ntdll/NtEnumerateValueKey.s b/libc/nt/ntdll/NtEnumerateValueKey.s new file mode 100644 index 00000000..729cb461 --- /dev/null +++ b/libc/nt/ntdll/NtEnumerateValueKey.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtEnumerateValueKey + + .text.windows +NtEnumerateValueKey: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtEnumerateValueKey(%rip),%rax + jmp __sysv2nt6 + .endfn NtEnumerateValueKey,globl + .previous diff --git a/libc/nt/ntdll/NtExtendSection.s b/libc/nt/ntdll/NtExtendSection.s new file mode 100644 index 00000000..22139345 --- /dev/null +++ b/libc/nt/ntdll/NtExtendSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtExtendSection diff --git a/libc/nt/ntdll/NtFilterBootOption.s b/libc/nt/ntdll/NtFilterBootOption.s new file mode 100644 index 00000000..aceff40b --- /dev/null +++ b/libc/nt/ntdll/NtFilterBootOption.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtFilterBootOption diff --git a/libc/nt/ntdll/NtFilterToken.s b/libc/nt/ntdll/NtFilterToken.s new file mode 100644 index 00000000..b68acdc6 --- /dev/null +++ b/libc/nt/ntdll/NtFilterToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtFilterToken diff --git a/libc/nt/ntdll/NtFilterTokenEx.s b/libc/nt/ntdll/NtFilterTokenEx.s new file mode 100644 index 00000000..2ec605f7 --- /dev/null +++ b/libc/nt/ntdll/NtFilterTokenEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtFilterTokenEx diff --git a/libc/nt/ntdll/NtFindAtom.s b/libc/nt/ntdll/NtFindAtom.s new file mode 100644 index 00000000..814ef0c6 --- /dev/null +++ b/libc/nt/ntdll/NtFindAtom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtFindAtom diff --git a/libc/nt/ntdll/NtFlushBuffersFile.s b/libc/nt/ntdll/NtFlushBuffersFile.s new file mode 100644 index 00000000..d3e662eb --- /dev/null +++ b/libc/nt/ntdll/NtFlushBuffersFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtFlushBuffersFile + + .text.windows +NtFlushBuffersFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtFlushBuffersFile(%rip),%rax + jmp __sysv2nt + .endfn NtFlushBuffersFile,globl + .previous diff --git a/libc/nt/ntdll/NtFlushBuffersFileEx.s b/libc/nt/ntdll/NtFlushBuffersFileEx.s new file mode 100644 index 00000000..bacbe92e --- /dev/null +++ b/libc/nt/ntdll/NtFlushBuffersFileEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtFlushBuffersFileEx diff --git a/libc/nt/ntdll/NtFlushInstallUILanguage.s b/libc/nt/ntdll/NtFlushInstallUILanguage.s new file mode 100644 index 00000000..8a3b8b57 --- /dev/null +++ b/libc/nt/ntdll/NtFlushInstallUILanguage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtFlushInstallUILanguage diff --git a/libc/nt/ntdll/NtFlushInstructionCache.s b/libc/nt/ntdll/NtFlushInstructionCache.s new file mode 100644 index 00000000..776274c8 --- /dev/null +++ b/libc/nt/ntdll/NtFlushInstructionCache.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtFlushInstructionCache + + .text.windows +NtFlushInstructionCache: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtFlushInstructionCache(%rip),%rax + jmp __sysv2nt + .endfn NtFlushInstructionCache,globl + .previous diff --git a/libc/nt/ntdll/NtFlushKey.s b/libc/nt/ntdll/NtFlushKey.s new file mode 100644 index 00000000..b5ef1849 --- /dev/null +++ b/libc/nt/ntdll/NtFlushKey.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtFlushKey + + .text.windows +NtFlushKey: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_NtFlushKey(%rip) + leave + ret + .endfn NtFlushKey,globl + .previous diff --git a/libc/nt/ntdll/NtFlushProcessWriteBuffers.s b/libc/nt/ntdll/NtFlushProcessWriteBuffers.s new file mode 100644 index 00000000..72c9d615 --- /dev/null +++ b/libc/nt/ntdll/NtFlushProcessWriteBuffers.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtFlushProcessWriteBuffers diff --git a/libc/nt/ntdll/NtFlushVirtualMemory.s b/libc/nt/ntdll/NtFlushVirtualMemory.s new file mode 100644 index 00000000..019abfa0 --- /dev/null +++ b/libc/nt/ntdll/NtFlushVirtualMemory.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtFlushVirtualMemory + + .text.windows +NtFlushVirtualMemory: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtFlushVirtualMemory(%rip),%rax + jmp __sysv2nt + .endfn NtFlushVirtualMemory,globl + .previous diff --git a/libc/nt/ntdll/NtFlushWriteBuffer.s b/libc/nt/ntdll/NtFlushWriteBuffer.s new file mode 100644 index 00000000..279a6775 --- /dev/null +++ b/libc/nt/ntdll/NtFlushWriteBuffer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtFlushWriteBuffer diff --git a/libc/nt/ntdll/NtFreeUserPhysicalPages.s b/libc/nt/ntdll/NtFreeUserPhysicalPages.s new file mode 100644 index 00000000..be14f3d1 --- /dev/null +++ b/libc/nt/ntdll/NtFreeUserPhysicalPages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtFreeUserPhysicalPages diff --git a/libc/nt/ntdll/NtFreeVirtualMemory.s b/libc/nt/ntdll/NtFreeVirtualMemory.s new file mode 100644 index 00000000..610f0bae --- /dev/null +++ b/libc/nt/ntdll/NtFreeVirtualMemory.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtFreeVirtualMemory + + .text.windows +NtFreeVirtualMemory: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtFreeVirtualMemory(%rip),%rax + jmp __sysv2nt + .endfn NtFreeVirtualMemory,globl + .previous diff --git a/libc/nt/ntdll/NtFreezeRegistry.s b/libc/nt/ntdll/NtFreezeRegistry.s new file mode 100644 index 00000000..5b8b05a6 --- /dev/null +++ b/libc/nt/ntdll/NtFreezeRegistry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtFreezeRegistry diff --git a/libc/nt/ntdll/NtFreezeTransactions.s b/libc/nt/ntdll/NtFreezeTransactions.s new file mode 100644 index 00000000..7f23c54b --- /dev/null +++ b/libc/nt/ntdll/NtFreezeTransactions.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtFreezeTransactions diff --git a/libc/nt/ntdll/NtFsControlFile.s b/libc/nt/ntdll/NtFsControlFile.s new file mode 100644 index 00000000..99ac203b --- /dev/null +++ b/libc/nt/ntdll/NtFsControlFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtFsControlFile + + .text.windows +NtFsControlFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtFsControlFile(%rip),%rax + jmp __sysv2nt10 + .endfn NtFsControlFile,globl + .previous diff --git a/libc/nt/ntdll/NtGetCachedSigningLevel.s b/libc/nt/ntdll/NtGetCachedSigningLevel.s new file mode 100644 index 00000000..81c45050 --- /dev/null +++ b/libc/nt/ntdll/NtGetCachedSigningLevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtGetCachedSigningLevel diff --git a/libc/nt/ntdll/NtGetCompleteWnfStateSubscription.s b/libc/nt/ntdll/NtGetCompleteWnfStateSubscription.s new file mode 100644 index 00000000..4f3094e9 --- /dev/null +++ b/libc/nt/ntdll/NtGetCompleteWnfStateSubscription.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtGetCompleteWnfStateSubscription diff --git a/libc/nt/ntdll/NtGetContextThread.s b/libc/nt/ntdll/NtGetContextThread.s new file mode 100644 index 00000000..0723bb45 --- /dev/null +++ b/libc/nt/ntdll/NtGetContextThread.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtGetContextThread + + .text.windows +NtGetContextThread: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtGetContextThread(%rip),%rax + jmp __sysv2nt + .endfn NtGetContextThread,globl + .previous diff --git a/libc/nt/ntdll/NtGetCurrentProcessorNumber.s b/libc/nt/ntdll/NtGetCurrentProcessorNumber.s new file mode 100644 index 00000000..734958d2 --- /dev/null +++ b/libc/nt/ntdll/NtGetCurrentProcessorNumber.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtGetCurrentProcessorNumber diff --git a/libc/nt/ntdll/NtGetCurrentProcessorNumberEx.s b/libc/nt/ntdll/NtGetCurrentProcessorNumberEx.s new file mode 100644 index 00000000..fd683908 --- /dev/null +++ b/libc/nt/ntdll/NtGetCurrentProcessorNumberEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtGetCurrentProcessorNumberEx diff --git a/libc/nt/ntdll/NtGetDevicePowerState.s b/libc/nt/ntdll/NtGetDevicePowerState.s new file mode 100644 index 00000000..2b986137 --- /dev/null +++ b/libc/nt/ntdll/NtGetDevicePowerState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtGetDevicePowerState diff --git a/libc/nt/ntdll/NtGetMUIRegistryInfo.s b/libc/nt/ntdll/NtGetMUIRegistryInfo.s new file mode 100644 index 00000000..11899936 --- /dev/null +++ b/libc/nt/ntdll/NtGetMUIRegistryInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtGetMUIRegistryInfo diff --git a/libc/nt/ntdll/NtGetNextProcess.s b/libc/nt/ntdll/NtGetNextProcess.s new file mode 100644 index 00000000..8449bccd --- /dev/null +++ b/libc/nt/ntdll/NtGetNextProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtGetNextProcess diff --git a/libc/nt/ntdll/NtGetNextThread.s b/libc/nt/ntdll/NtGetNextThread.s new file mode 100644 index 00000000..d2340b6f --- /dev/null +++ b/libc/nt/ntdll/NtGetNextThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtGetNextThread diff --git a/libc/nt/ntdll/NtGetNlsSectionPtr.s b/libc/nt/ntdll/NtGetNlsSectionPtr.s new file mode 100644 index 00000000..a634fff2 --- /dev/null +++ b/libc/nt/ntdll/NtGetNlsSectionPtr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtGetNlsSectionPtr diff --git a/libc/nt/ntdll/NtGetNotificationResourceManager.s b/libc/nt/ntdll/NtGetNotificationResourceManager.s new file mode 100644 index 00000000..50e871be --- /dev/null +++ b/libc/nt/ntdll/NtGetNotificationResourceManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtGetNotificationResourceManager diff --git a/libc/nt/ntdll/NtGetTickCount.s b/libc/nt/ntdll/NtGetTickCount.s new file mode 100644 index 00000000..43afd709 --- /dev/null +++ b/libc/nt/ntdll/NtGetTickCount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtGetTickCount diff --git a/libc/nt/ntdll/NtGetWriteWatch.s b/libc/nt/ntdll/NtGetWriteWatch.s new file mode 100644 index 00000000..b3f80f71 --- /dev/null +++ b/libc/nt/ntdll/NtGetWriteWatch.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtGetWriteWatch diff --git a/libc/nt/ntdll/NtImpersonateAnonymousToken.s b/libc/nt/ntdll/NtImpersonateAnonymousToken.s new file mode 100644 index 00000000..49d7a830 --- /dev/null +++ b/libc/nt/ntdll/NtImpersonateAnonymousToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtImpersonateAnonymousToken diff --git a/libc/nt/ntdll/NtImpersonateClientOfPort.s b/libc/nt/ntdll/NtImpersonateClientOfPort.s new file mode 100644 index 00000000..0cf878e0 --- /dev/null +++ b/libc/nt/ntdll/NtImpersonateClientOfPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtImpersonateClientOfPort diff --git a/libc/nt/ntdll/NtImpersonateThread.s b/libc/nt/ntdll/NtImpersonateThread.s new file mode 100644 index 00000000..efe061b2 --- /dev/null +++ b/libc/nt/ntdll/NtImpersonateThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtImpersonateThread diff --git a/libc/nt/ntdll/NtInitializeEnclave.s b/libc/nt/ntdll/NtInitializeEnclave.s new file mode 100644 index 00000000..e75bf74b --- /dev/null +++ b/libc/nt/ntdll/NtInitializeEnclave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtInitializeEnclave diff --git a/libc/nt/ntdll/NtInitializeNlsFiles.s b/libc/nt/ntdll/NtInitializeNlsFiles.s new file mode 100644 index 00000000..eb99a055 --- /dev/null +++ b/libc/nt/ntdll/NtInitializeNlsFiles.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtInitializeNlsFiles diff --git a/libc/nt/ntdll/NtInitializeRegistry.s b/libc/nt/ntdll/NtInitializeRegistry.s new file mode 100644 index 00000000..991ae40d --- /dev/null +++ b/libc/nt/ntdll/NtInitializeRegistry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtInitializeRegistry diff --git a/libc/nt/ntdll/NtInitiatePowerAction.s b/libc/nt/ntdll/NtInitiatePowerAction.s new file mode 100644 index 00000000..aa1ce3e7 --- /dev/null +++ b/libc/nt/ntdll/NtInitiatePowerAction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtInitiatePowerAction diff --git a/libc/nt/ntdll/NtIsProcessInJob.s b/libc/nt/ntdll/NtIsProcessInJob.s new file mode 100644 index 00000000..05c58d85 --- /dev/null +++ b/libc/nt/ntdll/NtIsProcessInJob.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtIsProcessInJob diff --git a/libc/nt/ntdll/NtIsSystemResumeAutomatic.s b/libc/nt/ntdll/NtIsSystemResumeAutomatic.s new file mode 100644 index 00000000..aa204d19 --- /dev/null +++ b/libc/nt/ntdll/NtIsSystemResumeAutomatic.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtIsSystemResumeAutomatic diff --git a/libc/nt/ntdll/NtIsUILanguageComitted.s b/libc/nt/ntdll/NtIsUILanguageComitted.s new file mode 100644 index 00000000..c6f3ad18 --- /dev/null +++ b/libc/nt/ntdll/NtIsUILanguageComitted.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtIsUILanguageComitted diff --git a/libc/nt/ntdll/NtListenPort.s b/libc/nt/ntdll/NtListenPort.s new file mode 100644 index 00000000..45cff3ea --- /dev/null +++ b/libc/nt/ntdll/NtListenPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtListenPort diff --git a/libc/nt/ntdll/NtLoadDriver.s b/libc/nt/ntdll/NtLoadDriver.s new file mode 100644 index 00000000..96eb4ee6 --- /dev/null +++ b/libc/nt/ntdll/NtLoadDriver.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtLoadDriver diff --git a/libc/nt/ntdll/NtLoadEnclaveData.s b/libc/nt/ntdll/NtLoadEnclaveData.s new file mode 100644 index 00000000..3d4e2837 --- /dev/null +++ b/libc/nt/ntdll/NtLoadEnclaveData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtLoadEnclaveData diff --git a/libc/nt/ntdll/NtLoadHotPatch.s b/libc/nt/ntdll/NtLoadHotPatch.s new file mode 100644 index 00000000..b91701cd --- /dev/null +++ b/libc/nt/ntdll/NtLoadHotPatch.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtLoadHotPatch diff --git a/libc/nt/ntdll/NtLoadKey.s b/libc/nt/ntdll/NtLoadKey.s new file mode 100644 index 00000000..554ea238 --- /dev/null +++ b/libc/nt/ntdll/NtLoadKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtLoadKey diff --git a/libc/nt/ntdll/NtLoadKey2.s b/libc/nt/ntdll/NtLoadKey2.s new file mode 100644 index 00000000..88fcd757 --- /dev/null +++ b/libc/nt/ntdll/NtLoadKey2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtLoadKey2 diff --git a/libc/nt/ntdll/NtLoadKeyEx.s b/libc/nt/ntdll/NtLoadKeyEx.s new file mode 100644 index 00000000..019506cb --- /dev/null +++ b/libc/nt/ntdll/NtLoadKeyEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtLoadKeyEx diff --git a/libc/nt/ntdll/NtLockFile.s b/libc/nt/ntdll/NtLockFile.s new file mode 100644 index 00000000..0ce039ff --- /dev/null +++ b/libc/nt/ntdll/NtLockFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtLockFile diff --git a/libc/nt/ntdll/NtLockProductActivationKeys.s b/libc/nt/ntdll/NtLockProductActivationKeys.s new file mode 100644 index 00000000..86aec1fe --- /dev/null +++ b/libc/nt/ntdll/NtLockProductActivationKeys.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtLockProductActivationKeys diff --git a/libc/nt/ntdll/NtLockRegistryKey.s b/libc/nt/ntdll/NtLockRegistryKey.s new file mode 100644 index 00000000..77530986 --- /dev/null +++ b/libc/nt/ntdll/NtLockRegistryKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtLockRegistryKey diff --git a/libc/nt/ntdll/NtLockVirtualMemory.s b/libc/nt/ntdll/NtLockVirtualMemory.s new file mode 100644 index 00000000..8ce1672a --- /dev/null +++ b/libc/nt/ntdll/NtLockVirtualMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtLockVirtualMemory diff --git a/libc/nt/ntdll/NtMakePermanentObject.s b/libc/nt/ntdll/NtMakePermanentObject.s new file mode 100644 index 00000000..ac4b6f92 --- /dev/null +++ b/libc/nt/ntdll/NtMakePermanentObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtMakePermanentObject diff --git a/libc/nt/ntdll/NtMakeTemporaryObject.s b/libc/nt/ntdll/NtMakeTemporaryObject.s new file mode 100644 index 00000000..656c7043 --- /dev/null +++ b/libc/nt/ntdll/NtMakeTemporaryObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtMakeTemporaryObject diff --git a/libc/nt/ntdll/NtManagePartition.s b/libc/nt/ntdll/NtManagePartition.s new file mode 100644 index 00000000..441551c2 --- /dev/null +++ b/libc/nt/ntdll/NtManagePartition.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtManagePartition diff --git a/libc/nt/ntdll/NtMapCMFModule.s b/libc/nt/ntdll/NtMapCMFModule.s new file mode 100644 index 00000000..cf0ae1c2 --- /dev/null +++ b/libc/nt/ntdll/NtMapCMFModule.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtMapCMFModule diff --git a/libc/nt/ntdll/NtMapUserPhysicalPages.s b/libc/nt/ntdll/NtMapUserPhysicalPages.s new file mode 100644 index 00000000..5e65511c --- /dev/null +++ b/libc/nt/ntdll/NtMapUserPhysicalPages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtMapUserPhysicalPages diff --git a/libc/nt/ntdll/NtMapUserPhysicalPagesScatter.s b/libc/nt/ntdll/NtMapUserPhysicalPagesScatter.s new file mode 100644 index 00000000..a1fcc6ba --- /dev/null +++ b/libc/nt/ntdll/NtMapUserPhysicalPagesScatter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtMapUserPhysicalPagesScatter diff --git a/libc/nt/ntdll/NtMapViewOfSection.s b/libc/nt/ntdll/NtMapViewOfSection.s new file mode 100644 index 00000000..732d9487 --- /dev/null +++ b/libc/nt/ntdll/NtMapViewOfSection.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtMapViewOfSection + + .text.windows +NtMapViewOfSection: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtMapViewOfSection(%rip),%rax + jmp __sysv2nt10 + .endfn NtMapViewOfSection,globl + .previous diff --git a/libc/nt/ntdll/NtMapViewOfSectionEx.s b/libc/nt/ntdll/NtMapViewOfSectionEx.s new file mode 100644 index 00000000..b1997c07 --- /dev/null +++ b/libc/nt/ntdll/NtMapViewOfSectionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtMapViewOfSectionEx diff --git a/libc/nt/ntdll/NtModifyBootEntry.s b/libc/nt/ntdll/NtModifyBootEntry.s new file mode 100644 index 00000000..f9dbd93c --- /dev/null +++ b/libc/nt/ntdll/NtModifyBootEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtModifyBootEntry diff --git a/libc/nt/ntdll/NtModifyDriverEntry.s b/libc/nt/ntdll/NtModifyDriverEntry.s new file mode 100644 index 00000000..d60731aa --- /dev/null +++ b/libc/nt/ntdll/NtModifyDriverEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtModifyDriverEntry diff --git a/libc/nt/ntdll/NtNotifyChangeDirectoryFile.s b/libc/nt/ntdll/NtNotifyChangeDirectoryFile.s new file mode 100644 index 00000000..3bb0d40b --- /dev/null +++ b/libc/nt/ntdll/NtNotifyChangeDirectoryFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtNotifyChangeDirectoryFile diff --git a/libc/nt/ntdll/NtNotifyChangeDirectoryFileEx.s b/libc/nt/ntdll/NtNotifyChangeDirectoryFileEx.s new file mode 100644 index 00000000..ae0f6215 --- /dev/null +++ b/libc/nt/ntdll/NtNotifyChangeDirectoryFileEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtNotifyChangeDirectoryFileEx diff --git a/libc/nt/ntdll/NtNotifyChangeKey.s b/libc/nt/ntdll/NtNotifyChangeKey.s new file mode 100644 index 00000000..6eb5cb11 --- /dev/null +++ b/libc/nt/ntdll/NtNotifyChangeKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtNotifyChangeKey diff --git a/libc/nt/ntdll/NtNotifyChangeMultipleKeys.s b/libc/nt/ntdll/NtNotifyChangeMultipleKeys.s new file mode 100644 index 00000000..8ddb363b --- /dev/null +++ b/libc/nt/ntdll/NtNotifyChangeMultipleKeys.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtNotifyChangeMultipleKeys diff --git a/libc/nt/ntdll/NtNotifyChangeSession.s b/libc/nt/ntdll/NtNotifyChangeSession.s new file mode 100644 index 00000000..e0344780 --- /dev/null +++ b/libc/nt/ntdll/NtNotifyChangeSession.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtNotifyChangeSession diff --git a/libc/nt/ntdll/NtOpenDirectoryObject.s b/libc/nt/ntdll/NtOpenDirectoryObject.s new file mode 100644 index 00000000..56bab9b4 --- /dev/null +++ b/libc/nt/ntdll/NtOpenDirectoryObject.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenDirectoryObject + + .text.windows +NtOpenDirectoryObject: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtOpenDirectoryObject(%rip),%rax + jmp __sysv2nt + .endfn NtOpenDirectoryObject,globl + .previous diff --git a/libc/nt/ntdll/NtOpenEnlistment.s b/libc/nt/ntdll/NtOpenEnlistment.s new file mode 100644 index 00000000..96cfb1b0 --- /dev/null +++ b/libc/nt/ntdll/NtOpenEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenEnlistment diff --git a/libc/nt/ntdll/NtOpenEvent.s b/libc/nt/ntdll/NtOpenEvent.s new file mode 100644 index 00000000..6f2c2280 --- /dev/null +++ b/libc/nt/ntdll/NtOpenEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenEvent diff --git a/libc/nt/ntdll/NtOpenEventPair.s b/libc/nt/ntdll/NtOpenEventPair.s new file mode 100644 index 00000000..2b2e83fe --- /dev/null +++ b/libc/nt/ntdll/NtOpenEventPair.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenEventPair diff --git a/libc/nt/ntdll/NtOpenFile.s b/libc/nt/ntdll/NtOpenFile.s new file mode 100644 index 00000000..9aa20a87 --- /dev/null +++ b/libc/nt/ntdll/NtOpenFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenFile + + .text.windows +NtOpenFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtOpenFile(%rip),%rax + jmp __sysv2nt6 + .endfn NtOpenFile,globl + .previous diff --git a/libc/nt/ntdll/NtOpenIoCompletion.s b/libc/nt/ntdll/NtOpenIoCompletion.s new file mode 100644 index 00000000..77ecf79f --- /dev/null +++ b/libc/nt/ntdll/NtOpenIoCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenIoCompletion diff --git a/libc/nt/ntdll/NtOpenJobObject.s b/libc/nt/ntdll/NtOpenJobObject.s new file mode 100644 index 00000000..961eb64b --- /dev/null +++ b/libc/nt/ntdll/NtOpenJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenJobObject diff --git a/libc/nt/ntdll/NtOpenKey.s b/libc/nt/ntdll/NtOpenKey.s new file mode 100644 index 00000000..58d39a00 --- /dev/null +++ b/libc/nt/ntdll/NtOpenKey.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenKey + + .text.windows +NtOpenKey: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtOpenKey(%rip),%rax + jmp __sysv2nt + .endfn NtOpenKey,globl + .previous diff --git a/libc/nt/ntdll/NtOpenKeyEx.s b/libc/nt/ntdll/NtOpenKeyEx.s new file mode 100644 index 00000000..c713a6c0 --- /dev/null +++ b/libc/nt/ntdll/NtOpenKeyEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenKeyEx diff --git a/libc/nt/ntdll/NtOpenKeyTransacted.s b/libc/nt/ntdll/NtOpenKeyTransacted.s new file mode 100644 index 00000000..b5e9ef53 --- /dev/null +++ b/libc/nt/ntdll/NtOpenKeyTransacted.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenKeyTransacted diff --git a/libc/nt/ntdll/NtOpenKeyTransactedEx.s b/libc/nt/ntdll/NtOpenKeyTransactedEx.s new file mode 100644 index 00000000..f77403f4 --- /dev/null +++ b/libc/nt/ntdll/NtOpenKeyTransactedEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenKeyTransactedEx diff --git a/libc/nt/ntdll/NtOpenKeyedEvent.s b/libc/nt/ntdll/NtOpenKeyedEvent.s new file mode 100644 index 00000000..9aeade6d --- /dev/null +++ b/libc/nt/ntdll/NtOpenKeyedEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenKeyedEvent diff --git a/libc/nt/ntdll/NtOpenMutant.s b/libc/nt/ntdll/NtOpenMutant.s new file mode 100644 index 00000000..8811fd2b --- /dev/null +++ b/libc/nt/ntdll/NtOpenMutant.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenMutant diff --git a/libc/nt/ntdll/NtOpenObjectAuditAlarm.s b/libc/nt/ntdll/NtOpenObjectAuditAlarm.s new file mode 100644 index 00000000..c88dd3aa --- /dev/null +++ b/libc/nt/ntdll/NtOpenObjectAuditAlarm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenObjectAuditAlarm diff --git a/libc/nt/ntdll/NtOpenPartition.s b/libc/nt/ntdll/NtOpenPartition.s new file mode 100644 index 00000000..3e3c7365 --- /dev/null +++ b/libc/nt/ntdll/NtOpenPartition.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenPartition diff --git a/libc/nt/ntdll/NtOpenPrivateNamespace.s b/libc/nt/ntdll/NtOpenPrivateNamespace.s new file mode 100644 index 00000000..27c6ae6c --- /dev/null +++ b/libc/nt/ntdll/NtOpenPrivateNamespace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenPrivateNamespace diff --git a/libc/nt/ntdll/NtOpenProcess.s b/libc/nt/ntdll/NtOpenProcess.s new file mode 100644 index 00000000..d58ba8ec --- /dev/null +++ b/libc/nt/ntdll/NtOpenProcess.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenProcess + + .text.windows +NtOpenProcess: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtOpenProcess(%rip),%rax + jmp __sysv2nt + .endfn NtOpenProcess,globl + .previous diff --git a/libc/nt/ntdll/NtOpenProcessToken.s b/libc/nt/ntdll/NtOpenProcessToken.s new file mode 100644 index 00000000..acb36526 --- /dev/null +++ b/libc/nt/ntdll/NtOpenProcessToken.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenProcessToken + + .text.windows +NtOpenProcessToken: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtOpenProcessToken(%rip),%rax + jmp __sysv2nt + .endfn NtOpenProcessToken,globl + .previous diff --git a/libc/nt/ntdll/NtOpenProcessTokenEx.s b/libc/nt/ntdll/NtOpenProcessTokenEx.s new file mode 100644 index 00000000..4c37d555 --- /dev/null +++ b/libc/nt/ntdll/NtOpenProcessTokenEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenProcessTokenEx diff --git a/libc/nt/ntdll/NtOpenRegistryTransaction.s b/libc/nt/ntdll/NtOpenRegistryTransaction.s new file mode 100644 index 00000000..a1501da5 --- /dev/null +++ b/libc/nt/ntdll/NtOpenRegistryTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenRegistryTransaction diff --git a/libc/nt/ntdll/NtOpenResourceManager.s b/libc/nt/ntdll/NtOpenResourceManager.s new file mode 100644 index 00000000..f785634b --- /dev/null +++ b/libc/nt/ntdll/NtOpenResourceManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenResourceManager diff --git a/libc/nt/ntdll/NtOpenSection.s b/libc/nt/ntdll/NtOpenSection.s new file mode 100644 index 00000000..72c9303f --- /dev/null +++ b/libc/nt/ntdll/NtOpenSection.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenSection + + .text.windows +NtOpenSection: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtOpenSection(%rip),%rax + jmp __sysv2nt + .endfn NtOpenSection,globl + .previous diff --git a/libc/nt/ntdll/NtOpenSemaphore.s b/libc/nt/ntdll/NtOpenSemaphore.s new file mode 100644 index 00000000..b5168824 --- /dev/null +++ b/libc/nt/ntdll/NtOpenSemaphore.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenSemaphore diff --git a/libc/nt/ntdll/NtOpenSession.s b/libc/nt/ntdll/NtOpenSession.s new file mode 100644 index 00000000..48b30371 --- /dev/null +++ b/libc/nt/ntdll/NtOpenSession.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenSession diff --git a/libc/nt/ntdll/NtOpenSymbolicLinkObject.s b/libc/nt/ntdll/NtOpenSymbolicLinkObject.s new file mode 100644 index 00000000..7d8dfa42 --- /dev/null +++ b/libc/nt/ntdll/NtOpenSymbolicLinkObject.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenSymbolicLinkObject + + .text.windows +NtOpenSymbolicLinkObject: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtOpenSymbolicLinkObject(%rip),%rax + jmp __sysv2nt + .endfn NtOpenSymbolicLinkObject,globl + .previous diff --git a/libc/nt/ntdll/NtOpenThread.s b/libc/nt/ntdll/NtOpenThread.s new file mode 100644 index 00000000..42dd10e7 --- /dev/null +++ b/libc/nt/ntdll/NtOpenThread.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenThread + + .text.windows +NtOpenThread: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtOpenThread(%rip),%rax + jmp __sysv2nt + .endfn NtOpenThread,globl + .previous diff --git a/libc/nt/ntdll/NtOpenThreadToken.s b/libc/nt/ntdll/NtOpenThreadToken.s new file mode 100644 index 00000000..a07a0f6d --- /dev/null +++ b/libc/nt/ntdll/NtOpenThreadToken.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenThreadToken + + .text.windows +NtOpenThreadToken: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtOpenThreadToken(%rip),%rax + jmp __sysv2nt + .endfn NtOpenThreadToken,globl + .previous diff --git a/libc/nt/ntdll/NtOpenThreadTokenEx.s b/libc/nt/ntdll/NtOpenThreadTokenEx.s new file mode 100644 index 00000000..053b3cba --- /dev/null +++ b/libc/nt/ntdll/NtOpenThreadTokenEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenThreadTokenEx diff --git a/libc/nt/ntdll/NtOpenTimer.s b/libc/nt/ntdll/NtOpenTimer.s new file mode 100644 index 00000000..144180ff --- /dev/null +++ b/libc/nt/ntdll/NtOpenTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenTimer diff --git a/libc/nt/ntdll/NtOpenTransaction.s b/libc/nt/ntdll/NtOpenTransaction.s new file mode 100644 index 00000000..390bbf73 --- /dev/null +++ b/libc/nt/ntdll/NtOpenTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenTransaction diff --git a/libc/nt/ntdll/NtOpenTransactionManager.s b/libc/nt/ntdll/NtOpenTransactionManager.s new file mode 100644 index 00000000..9c30dfbf --- /dev/null +++ b/libc/nt/ntdll/NtOpenTransactionManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtOpenTransactionManager diff --git a/libc/nt/ntdll/NtPlugPlayControl.s b/libc/nt/ntdll/NtPlugPlayControl.s new file mode 100644 index 00000000..f42552d8 --- /dev/null +++ b/libc/nt/ntdll/NtPlugPlayControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtPlugPlayControl diff --git a/libc/nt/ntdll/NtPowerInformation.s b/libc/nt/ntdll/NtPowerInformation.s new file mode 100644 index 00000000..116eae81 --- /dev/null +++ b/libc/nt/ntdll/NtPowerInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtPowerInformation diff --git a/libc/nt/ntdll/NtPrePrepareComplete.s b/libc/nt/ntdll/NtPrePrepareComplete.s new file mode 100644 index 00000000..fb25256b --- /dev/null +++ b/libc/nt/ntdll/NtPrePrepareComplete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtPrePrepareComplete diff --git a/libc/nt/ntdll/NtPrePrepareEnlistment.s b/libc/nt/ntdll/NtPrePrepareEnlistment.s new file mode 100644 index 00000000..11273068 --- /dev/null +++ b/libc/nt/ntdll/NtPrePrepareEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtPrePrepareEnlistment diff --git a/libc/nt/ntdll/NtPrepareComplete.s b/libc/nt/ntdll/NtPrepareComplete.s new file mode 100644 index 00000000..a3f48f17 --- /dev/null +++ b/libc/nt/ntdll/NtPrepareComplete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtPrepareComplete diff --git a/libc/nt/ntdll/NtPrepareEnlistment.s b/libc/nt/ntdll/NtPrepareEnlistment.s new file mode 100644 index 00000000..7ef90f52 --- /dev/null +++ b/libc/nt/ntdll/NtPrepareEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtPrepareEnlistment diff --git a/libc/nt/ntdll/NtPrivilegeCheck.s b/libc/nt/ntdll/NtPrivilegeCheck.s new file mode 100644 index 00000000..e26d9fa7 --- /dev/null +++ b/libc/nt/ntdll/NtPrivilegeCheck.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtPrivilegeCheck diff --git a/libc/nt/ntdll/NtPrivilegeObjectAuditAlarm.s b/libc/nt/ntdll/NtPrivilegeObjectAuditAlarm.s new file mode 100644 index 00000000..07ed1e44 --- /dev/null +++ b/libc/nt/ntdll/NtPrivilegeObjectAuditAlarm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtPrivilegeObjectAuditAlarm diff --git a/libc/nt/ntdll/NtPrivilegedServiceAuditAlarm.s b/libc/nt/ntdll/NtPrivilegedServiceAuditAlarm.s new file mode 100644 index 00000000..76b5c1b8 --- /dev/null +++ b/libc/nt/ntdll/NtPrivilegedServiceAuditAlarm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtPrivilegedServiceAuditAlarm diff --git a/libc/nt/ntdll/NtPropagationComplete.s b/libc/nt/ntdll/NtPropagationComplete.s new file mode 100644 index 00000000..13b843d5 --- /dev/null +++ b/libc/nt/ntdll/NtPropagationComplete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtPropagationComplete diff --git a/libc/nt/ntdll/NtPropagationFailed.s b/libc/nt/ntdll/NtPropagationFailed.s new file mode 100644 index 00000000..2e891c3c --- /dev/null +++ b/libc/nt/ntdll/NtPropagationFailed.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtPropagationFailed diff --git a/libc/nt/ntdll/NtProtectVirtualMemory.s b/libc/nt/ntdll/NtProtectVirtualMemory.s new file mode 100644 index 00000000..300bb8ff --- /dev/null +++ b/libc/nt/ntdll/NtProtectVirtualMemory.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtProtectVirtualMemory + + .text.windows +NtProtectVirtualMemory: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtProtectVirtualMemory(%rip),%rax + jmp __sysv2nt6 + .endfn NtProtectVirtualMemory,globl + .previous diff --git a/libc/nt/ntdll/NtPulseEvent.s b/libc/nt/ntdll/NtPulseEvent.s new file mode 100644 index 00000000..e0ece79f --- /dev/null +++ b/libc/nt/ntdll/NtPulseEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtPulseEvent diff --git a/libc/nt/ntdll/NtQueryAttributesFile.s b/libc/nt/ntdll/NtQueryAttributesFile.s new file mode 100644 index 00000000..7922de63 --- /dev/null +++ b/libc/nt/ntdll/NtQueryAttributesFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryAttributesFile + + .text.windows +NtQueryAttributesFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQueryAttributesFile(%rip),%rax + jmp __sysv2nt + .endfn NtQueryAttributesFile,globl + .previous diff --git a/libc/nt/ntdll/NtQueryAuxiliaryCounterFrequency.s b/libc/nt/ntdll/NtQueryAuxiliaryCounterFrequency.s new file mode 100644 index 00000000..8a949faf --- /dev/null +++ b/libc/nt/ntdll/NtQueryAuxiliaryCounterFrequency.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryAuxiliaryCounterFrequency diff --git a/libc/nt/ntdll/NtQueryBootEntryOrder.s b/libc/nt/ntdll/NtQueryBootEntryOrder.s new file mode 100644 index 00000000..c18cc914 --- /dev/null +++ b/libc/nt/ntdll/NtQueryBootEntryOrder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryBootEntryOrder diff --git a/libc/nt/ntdll/NtQueryBootOptions.s b/libc/nt/ntdll/NtQueryBootOptions.s new file mode 100644 index 00000000..c1339cf3 --- /dev/null +++ b/libc/nt/ntdll/NtQueryBootOptions.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryBootOptions diff --git a/libc/nt/ntdll/NtQueryDebugFilterState.s b/libc/nt/ntdll/NtQueryDebugFilterState.s new file mode 100644 index 00000000..19939c51 --- /dev/null +++ b/libc/nt/ntdll/NtQueryDebugFilterState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryDebugFilterState diff --git a/libc/nt/ntdll/NtQueryDefaultLocale.s b/libc/nt/ntdll/NtQueryDefaultLocale.s new file mode 100644 index 00000000..af8d4fa8 --- /dev/null +++ b/libc/nt/ntdll/NtQueryDefaultLocale.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryDefaultLocale diff --git a/libc/nt/ntdll/NtQueryDefaultUILanguage.s b/libc/nt/ntdll/NtQueryDefaultUILanguage.s new file mode 100644 index 00000000..09172e80 --- /dev/null +++ b/libc/nt/ntdll/NtQueryDefaultUILanguage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryDefaultUILanguage diff --git a/libc/nt/ntdll/NtQueryDirectoryFile.s b/libc/nt/ntdll/NtQueryDirectoryFile.s new file mode 100644 index 00000000..2b94f5ea --- /dev/null +++ b/libc/nt/ntdll/NtQueryDirectoryFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryDirectoryFile + + .text.windows +NtQueryDirectoryFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQueryDirectoryFile(%rip),%rax + jmp __sysv2nt12 + .endfn NtQueryDirectoryFile,globl + .previous diff --git a/libc/nt/ntdll/NtQueryDirectoryFileEx.s b/libc/nt/ntdll/NtQueryDirectoryFileEx.s new file mode 100644 index 00000000..f07175d0 --- /dev/null +++ b/libc/nt/ntdll/NtQueryDirectoryFileEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryDirectoryFileEx diff --git a/libc/nt/ntdll/NtQueryDirectoryObject.s b/libc/nt/ntdll/NtQueryDirectoryObject.s new file mode 100644 index 00000000..1b521d88 --- /dev/null +++ b/libc/nt/ntdll/NtQueryDirectoryObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryDirectoryObject diff --git a/libc/nt/ntdll/NtQueryDriverEntryOrder.s b/libc/nt/ntdll/NtQueryDriverEntryOrder.s new file mode 100644 index 00000000..9149a443 --- /dev/null +++ b/libc/nt/ntdll/NtQueryDriverEntryOrder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryDriverEntryOrder diff --git a/libc/nt/ntdll/NtQueryEaFile.s b/libc/nt/ntdll/NtQueryEaFile.s new file mode 100644 index 00000000..8d5748a6 --- /dev/null +++ b/libc/nt/ntdll/NtQueryEaFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryEaFile diff --git a/libc/nt/ntdll/NtQueryEvent.s b/libc/nt/ntdll/NtQueryEvent.s new file mode 100644 index 00000000..2def514f --- /dev/null +++ b/libc/nt/ntdll/NtQueryEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryEvent diff --git a/libc/nt/ntdll/NtQueryFullAttributesFile.s b/libc/nt/ntdll/NtQueryFullAttributesFile.s new file mode 100644 index 00000000..099820ba --- /dev/null +++ b/libc/nt/ntdll/NtQueryFullAttributesFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryFullAttributesFile + + .text.windows +NtQueryFullAttributesFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQueryFullAttributesFile(%rip),%rax + jmp __sysv2nt + .endfn NtQueryFullAttributesFile,globl + .previous diff --git a/libc/nt/ntdll/NtQueryInformationAtom.s b/libc/nt/ntdll/NtQueryInformationAtom.s new file mode 100644 index 00000000..0d265e5e --- /dev/null +++ b/libc/nt/ntdll/NtQueryInformationAtom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryInformationAtom diff --git a/libc/nt/ntdll/NtQueryInformationByName.s b/libc/nt/ntdll/NtQueryInformationByName.s new file mode 100644 index 00000000..56c5ec95 --- /dev/null +++ b/libc/nt/ntdll/NtQueryInformationByName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryInformationByName diff --git a/libc/nt/ntdll/NtQueryInformationEnlistment.s b/libc/nt/ntdll/NtQueryInformationEnlistment.s new file mode 100644 index 00000000..651a2e78 --- /dev/null +++ b/libc/nt/ntdll/NtQueryInformationEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryInformationEnlistment diff --git a/libc/nt/ntdll/NtQueryInformationFile.s b/libc/nt/ntdll/NtQueryInformationFile.s new file mode 100644 index 00000000..b356e87e --- /dev/null +++ b/libc/nt/ntdll/NtQueryInformationFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryInformationFile + + .text.windows +NtQueryInformationFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQueryInformationFile(%rip),%rax + jmp __sysv2nt6 + .endfn NtQueryInformationFile,globl + .previous diff --git a/libc/nt/ntdll/NtQueryInformationJobObject.s b/libc/nt/ntdll/NtQueryInformationJobObject.s new file mode 100644 index 00000000..8991ba52 --- /dev/null +++ b/libc/nt/ntdll/NtQueryInformationJobObject.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryInformationJobObject + + .text.windows +NtQueryInformationJobObject: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQueryInformationJobObject(%rip),%rax + jmp __sysv2nt6 + .endfn NtQueryInformationJobObject,globl + .previous diff --git a/libc/nt/ntdll/NtQueryInformationPort.s b/libc/nt/ntdll/NtQueryInformationPort.s new file mode 100644 index 00000000..8d46c871 --- /dev/null +++ b/libc/nt/ntdll/NtQueryInformationPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryInformationPort diff --git a/libc/nt/ntdll/NtQueryInformationProcess.s b/libc/nt/ntdll/NtQueryInformationProcess.s new file mode 100644 index 00000000..fdafcbd5 --- /dev/null +++ b/libc/nt/ntdll/NtQueryInformationProcess.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryInformationProcess + + .text.windows +NtQueryInformationProcess: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQueryInformationProcess(%rip),%rax + jmp __sysv2nt6 + .endfn NtQueryInformationProcess,globl + .previous diff --git a/libc/nt/ntdll/NtQueryInformationResourceManager.s b/libc/nt/ntdll/NtQueryInformationResourceManager.s new file mode 100644 index 00000000..90a5d0f6 --- /dev/null +++ b/libc/nt/ntdll/NtQueryInformationResourceManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryInformationResourceManager diff --git a/libc/nt/ntdll/NtQueryInformationThread.s b/libc/nt/ntdll/NtQueryInformationThread.s new file mode 100644 index 00000000..559c8265 --- /dev/null +++ b/libc/nt/ntdll/NtQueryInformationThread.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryInformationThread + + .text.windows +NtQueryInformationThread: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQueryInformationThread(%rip),%rax + jmp __sysv2nt6 + .endfn NtQueryInformationThread,globl + .previous diff --git a/libc/nt/ntdll/NtQueryInformationToken.s b/libc/nt/ntdll/NtQueryInformationToken.s new file mode 100644 index 00000000..ad9887c7 --- /dev/null +++ b/libc/nt/ntdll/NtQueryInformationToken.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryInformationToken + + .text.windows +NtQueryInformationToken: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQueryInformationToken(%rip),%rax + jmp __sysv2nt6 + .endfn NtQueryInformationToken,globl + .previous diff --git a/libc/nt/ntdll/NtQueryInformationTransaction.s b/libc/nt/ntdll/NtQueryInformationTransaction.s new file mode 100644 index 00000000..871ccff0 --- /dev/null +++ b/libc/nt/ntdll/NtQueryInformationTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryInformationTransaction diff --git a/libc/nt/ntdll/NtQueryInformationTransactionManager.s b/libc/nt/ntdll/NtQueryInformationTransactionManager.s new file mode 100644 index 00000000..032d8a22 --- /dev/null +++ b/libc/nt/ntdll/NtQueryInformationTransactionManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryInformationTransactionManager diff --git a/libc/nt/ntdll/NtQueryInformationWorkerFactory.s b/libc/nt/ntdll/NtQueryInformationWorkerFactory.s new file mode 100644 index 00000000..f21af193 --- /dev/null +++ b/libc/nt/ntdll/NtQueryInformationWorkerFactory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryInformationWorkerFactory diff --git a/libc/nt/ntdll/NtQueryInstallUILanguage.s b/libc/nt/ntdll/NtQueryInstallUILanguage.s new file mode 100644 index 00000000..a2c21458 --- /dev/null +++ b/libc/nt/ntdll/NtQueryInstallUILanguage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryInstallUILanguage diff --git a/libc/nt/ntdll/NtQueryIntervalProfile.s b/libc/nt/ntdll/NtQueryIntervalProfile.s new file mode 100644 index 00000000..31cecea5 --- /dev/null +++ b/libc/nt/ntdll/NtQueryIntervalProfile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryIntervalProfile + + .text.windows +NtQueryIntervalProfile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQueryIntervalProfile(%rip),%rax + jmp __sysv2nt + .endfn NtQueryIntervalProfile,globl + .previous diff --git a/libc/nt/ntdll/NtQueryIoCompletion.s b/libc/nt/ntdll/NtQueryIoCompletion.s new file mode 100644 index 00000000..44c47252 --- /dev/null +++ b/libc/nt/ntdll/NtQueryIoCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryIoCompletion diff --git a/libc/nt/ntdll/NtQueryKey.s b/libc/nt/ntdll/NtQueryKey.s new file mode 100644 index 00000000..7c384146 --- /dev/null +++ b/libc/nt/ntdll/NtQueryKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryKey diff --git a/libc/nt/ntdll/NtQueryLicenseValue.s b/libc/nt/ntdll/NtQueryLicenseValue.s new file mode 100644 index 00000000..156fe104 --- /dev/null +++ b/libc/nt/ntdll/NtQueryLicenseValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryLicenseValue diff --git a/libc/nt/ntdll/NtQueryMultipleValueKey.s b/libc/nt/ntdll/NtQueryMultipleValueKey.s new file mode 100644 index 00000000..bbd7fd6d --- /dev/null +++ b/libc/nt/ntdll/NtQueryMultipleValueKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryMultipleValueKey diff --git a/libc/nt/ntdll/NtQueryMutant.s b/libc/nt/ntdll/NtQueryMutant.s new file mode 100644 index 00000000..fb4825c2 --- /dev/null +++ b/libc/nt/ntdll/NtQueryMutant.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryMutant diff --git a/libc/nt/ntdll/NtQueryObject.s b/libc/nt/ntdll/NtQueryObject.s new file mode 100644 index 00000000..0dfcce39 --- /dev/null +++ b/libc/nt/ntdll/NtQueryObject.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryObject + + .text.windows +NtQueryObject: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQueryObject(%rip),%rax + jmp __sysv2nt6 + .endfn NtQueryObject,globl + .previous diff --git a/libc/nt/ntdll/NtQueryOpenSubKeys.s b/libc/nt/ntdll/NtQueryOpenSubKeys.s new file mode 100644 index 00000000..d2dda2b9 --- /dev/null +++ b/libc/nt/ntdll/NtQueryOpenSubKeys.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryOpenSubKeys diff --git a/libc/nt/ntdll/NtQueryOpenSubKeysEx.s b/libc/nt/ntdll/NtQueryOpenSubKeysEx.s new file mode 100644 index 00000000..5191b731 --- /dev/null +++ b/libc/nt/ntdll/NtQueryOpenSubKeysEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryOpenSubKeysEx diff --git a/libc/nt/ntdll/NtQueryPerformanceCounter.s b/libc/nt/ntdll/NtQueryPerformanceCounter.s new file mode 100644 index 00000000..9f9f566b --- /dev/null +++ b/libc/nt/ntdll/NtQueryPerformanceCounter.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryPerformanceCounter + + .text.windows +NtQueryPerformanceCounter: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQueryPerformanceCounter(%rip),%rax + jmp __sysv2nt + .endfn NtQueryPerformanceCounter,globl + .previous diff --git a/libc/nt/ntdll/NtQueryPortInformationProcess.s b/libc/nt/ntdll/NtQueryPortInformationProcess.s new file mode 100644 index 00000000..c8fbd602 --- /dev/null +++ b/libc/nt/ntdll/NtQueryPortInformationProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryPortInformationProcess diff --git a/libc/nt/ntdll/NtQueryQuotaInformationFile.s b/libc/nt/ntdll/NtQueryQuotaInformationFile.s new file mode 100644 index 00000000..c949cf48 --- /dev/null +++ b/libc/nt/ntdll/NtQueryQuotaInformationFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryQuotaInformationFile diff --git a/libc/nt/ntdll/NtQuerySection.s b/libc/nt/ntdll/NtQuerySection.s new file mode 100644 index 00000000..51401e95 --- /dev/null +++ b/libc/nt/ntdll/NtQuerySection.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQuerySection + + .text.windows +NtQuerySection: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQuerySection(%rip),%rax + jmp __sysv2nt6 + .endfn NtQuerySection,globl + .previous diff --git a/libc/nt/ntdll/NtQuerySecurityAttributesToken.s b/libc/nt/ntdll/NtQuerySecurityAttributesToken.s new file mode 100644 index 00000000..0c2ab53d --- /dev/null +++ b/libc/nt/ntdll/NtQuerySecurityAttributesToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQuerySecurityAttributesToken diff --git a/libc/nt/ntdll/NtQuerySecurityObject.s b/libc/nt/ntdll/NtQuerySecurityObject.s new file mode 100644 index 00000000..e9ce0115 --- /dev/null +++ b/libc/nt/ntdll/NtQuerySecurityObject.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQuerySecurityObject + + .text.windows +NtQuerySecurityObject: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQuerySecurityObject(%rip),%rax + jmp __sysv2nt6 + .endfn NtQuerySecurityObject,globl + .previous diff --git a/libc/nt/ntdll/NtQuerySecurityPolicy.s b/libc/nt/ntdll/NtQuerySecurityPolicy.s new file mode 100644 index 00000000..50d0e433 --- /dev/null +++ b/libc/nt/ntdll/NtQuerySecurityPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQuerySecurityPolicy diff --git a/libc/nt/ntdll/NtQuerySemaphore.s b/libc/nt/ntdll/NtQuerySemaphore.s new file mode 100644 index 00000000..8d68d6de --- /dev/null +++ b/libc/nt/ntdll/NtQuerySemaphore.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQuerySemaphore diff --git a/libc/nt/ntdll/NtQuerySymbolicLinkObject.s b/libc/nt/ntdll/NtQuerySymbolicLinkObject.s new file mode 100644 index 00000000..1a52f1cd --- /dev/null +++ b/libc/nt/ntdll/NtQuerySymbolicLinkObject.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQuerySymbolicLinkObject + + .text.windows +NtQuerySymbolicLinkObject: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQuerySymbolicLinkObject(%rip),%rax + jmp __sysv2nt + .endfn NtQuerySymbolicLinkObject,globl + .previous diff --git a/libc/nt/ntdll/NtQuerySystemEnvironmentValue.s b/libc/nt/ntdll/NtQuerySystemEnvironmentValue.s new file mode 100644 index 00000000..30b90d7a --- /dev/null +++ b/libc/nt/ntdll/NtQuerySystemEnvironmentValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQuerySystemEnvironmentValue diff --git a/libc/nt/ntdll/NtQuerySystemEnvironmentValueEx.s b/libc/nt/ntdll/NtQuerySystemEnvironmentValueEx.s new file mode 100644 index 00000000..b988953f --- /dev/null +++ b/libc/nt/ntdll/NtQuerySystemEnvironmentValueEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQuerySystemEnvironmentValueEx diff --git a/libc/nt/ntdll/NtQuerySystemInformation.s b/libc/nt/ntdll/NtQuerySystemInformation.s new file mode 100644 index 00000000..7528cdbf --- /dev/null +++ b/libc/nt/ntdll/NtQuerySystemInformation.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQuerySystemInformation + + .text.windows +NtQuerySystemInformation: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQuerySystemInformation(%rip),%rax + jmp __sysv2nt + .endfn NtQuerySystemInformation,globl + .previous diff --git a/libc/nt/ntdll/NtQuerySystemInformationEx.s b/libc/nt/ntdll/NtQuerySystemInformationEx.s new file mode 100644 index 00000000..0f322fd5 --- /dev/null +++ b/libc/nt/ntdll/NtQuerySystemInformationEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQuerySystemInformationEx diff --git a/libc/nt/ntdll/NtQuerySystemTime.s b/libc/nt/ntdll/NtQuerySystemTime.s new file mode 100644 index 00000000..c9c4842f --- /dev/null +++ b/libc/nt/ntdll/NtQuerySystemTime.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQuerySystemTime + + .text.windows +NtQuerySystemTime: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_NtQuerySystemTime(%rip) + leave + ret + .endfn NtQuerySystemTime,globl + .previous diff --git a/libc/nt/ntdll/NtQueryTimer.s b/libc/nt/ntdll/NtQueryTimer.s new file mode 100644 index 00000000..41acad9f --- /dev/null +++ b/libc/nt/ntdll/NtQueryTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryTimer diff --git a/libc/nt/ntdll/NtQueryTimerResolution.s b/libc/nt/ntdll/NtQueryTimerResolution.s new file mode 100644 index 00000000..5050345b --- /dev/null +++ b/libc/nt/ntdll/NtQueryTimerResolution.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryTimerResolution diff --git a/libc/nt/ntdll/NtQueryValueKey.s b/libc/nt/ntdll/NtQueryValueKey.s new file mode 100644 index 00000000..eb192acf --- /dev/null +++ b/libc/nt/ntdll/NtQueryValueKey.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryValueKey + + .text.windows +NtQueryValueKey: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQueryValueKey(%rip),%rax + jmp __sysv2nt6 + .endfn NtQueryValueKey,globl + .previous diff --git a/libc/nt/ntdll/NtQueryVirtualMemory.s b/libc/nt/ntdll/NtQueryVirtualMemory.s new file mode 100644 index 00000000..4202eea2 --- /dev/null +++ b/libc/nt/ntdll/NtQueryVirtualMemory.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryVirtualMemory + + .text.windows +NtQueryVirtualMemory: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQueryVirtualMemory(%rip),%rax + jmp __sysv2nt6 + .endfn NtQueryVirtualMemory,globl + .previous diff --git a/libc/nt/ntdll/NtQueryVolumeInformationFile.s b/libc/nt/ntdll/NtQueryVolumeInformationFile.s new file mode 100644 index 00000000..1a1e8167 --- /dev/null +++ b/libc/nt/ntdll/NtQueryVolumeInformationFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryVolumeInformationFile + + .text.windows +NtQueryVolumeInformationFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQueryVolumeInformationFile(%rip),%rax + jmp __sysv2nt6 + .endfn NtQueryVolumeInformationFile,globl + .previous diff --git a/libc/nt/ntdll/NtQueryWnfStateData.s b/libc/nt/ntdll/NtQueryWnfStateData.s new file mode 100644 index 00000000..eeb5c79b --- /dev/null +++ b/libc/nt/ntdll/NtQueryWnfStateData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryWnfStateData diff --git a/libc/nt/ntdll/NtQueryWnfStateNameInformation.s b/libc/nt/ntdll/NtQueryWnfStateNameInformation.s new file mode 100644 index 00000000..5202f908 --- /dev/null +++ b/libc/nt/ntdll/NtQueryWnfStateNameInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueryWnfStateNameInformation diff --git a/libc/nt/ntdll/NtQueueApcThread.s b/libc/nt/ntdll/NtQueueApcThread.s new file mode 100644 index 00000000..a42e988f --- /dev/null +++ b/libc/nt/ntdll/NtQueueApcThread.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueueApcThread + + .text.windows +NtQueueApcThread: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtQueueApcThread(%rip),%rax + jmp __sysv2nt6 + .endfn NtQueueApcThread,globl + .previous diff --git a/libc/nt/ntdll/NtQueueApcThreadEx.s b/libc/nt/ntdll/NtQueueApcThreadEx.s new file mode 100644 index 00000000..c1e5ea4c --- /dev/null +++ b/libc/nt/ntdll/NtQueueApcThreadEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtQueueApcThreadEx diff --git a/libc/nt/ntdll/NtRaiseException.s b/libc/nt/ntdll/NtRaiseException.s new file mode 100644 index 00000000..91a5873b --- /dev/null +++ b/libc/nt/ntdll/NtRaiseException.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRaiseException + + .text.windows +NtRaiseException: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtRaiseException(%rip),%rax + jmp __sysv2nt + .endfn NtRaiseException,globl + .previous diff --git a/libc/nt/ntdll/NtRaiseHardError.s b/libc/nt/ntdll/NtRaiseHardError.s new file mode 100644 index 00000000..e48d9e22 --- /dev/null +++ b/libc/nt/ntdll/NtRaiseHardError.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRaiseHardError + + .text.windows +NtRaiseHardError: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtRaiseHardError(%rip),%rax + jmp __sysv2nt6 + .endfn NtRaiseHardError,globl + .previous diff --git a/libc/nt/ntdll/NtReadFile.s b/libc/nt/ntdll/NtReadFile.s new file mode 100644 index 00000000..55f50c85 --- /dev/null +++ b/libc/nt/ntdll/NtReadFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtReadFile + + .text.windows +NtReadFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtReadFile(%rip),%rax + jmp __sysv2nt10 + .endfn NtReadFile,globl + .previous diff --git a/libc/nt/ntdll/NtReadFileScatter.s b/libc/nt/ntdll/NtReadFileScatter.s new file mode 100644 index 00000000..05d90b77 --- /dev/null +++ b/libc/nt/ntdll/NtReadFileScatter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtReadFileScatter diff --git a/libc/nt/ntdll/NtReadOnlyEnlistment.s b/libc/nt/ntdll/NtReadOnlyEnlistment.s new file mode 100644 index 00000000..1312c956 --- /dev/null +++ b/libc/nt/ntdll/NtReadOnlyEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtReadOnlyEnlistment diff --git a/libc/nt/ntdll/NtReadRequestData.s b/libc/nt/ntdll/NtReadRequestData.s new file mode 100644 index 00000000..a88d0c4d --- /dev/null +++ b/libc/nt/ntdll/NtReadRequestData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtReadRequestData diff --git a/libc/nt/ntdll/NtReadVirtualMemory.s b/libc/nt/ntdll/NtReadVirtualMemory.s new file mode 100644 index 00000000..b24de4b4 --- /dev/null +++ b/libc/nt/ntdll/NtReadVirtualMemory.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtReadVirtualMemory + + .text.windows +NtReadVirtualMemory: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtReadVirtualMemory(%rip),%rax + jmp __sysv2nt6 + .endfn NtReadVirtualMemory,globl + .previous diff --git a/libc/nt/ntdll/NtRecoverEnlistment.s b/libc/nt/ntdll/NtRecoverEnlistment.s new file mode 100644 index 00000000..2581a3e5 --- /dev/null +++ b/libc/nt/ntdll/NtRecoverEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRecoverEnlistment diff --git a/libc/nt/ntdll/NtRecoverResourceManager.s b/libc/nt/ntdll/NtRecoverResourceManager.s new file mode 100644 index 00000000..bee89500 --- /dev/null +++ b/libc/nt/ntdll/NtRecoverResourceManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRecoverResourceManager diff --git a/libc/nt/ntdll/NtRecoverTransactionManager.s b/libc/nt/ntdll/NtRecoverTransactionManager.s new file mode 100644 index 00000000..9234c9ff --- /dev/null +++ b/libc/nt/ntdll/NtRecoverTransactionManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRecoverTransactionManager diff --git a/libc/nt/ntdll/NtRegisterProtocolAddressInformation.s b/libc/nt/ntdll/NtRegisterProtocolAddressInformation.s new file mode 100644 index 00000000..acd6a140 --- /dev/null +++ b/libc/nt/ntdll/NtRegisterProtocolAddressInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRegisterProtocolAddressInformation diff --git a/libc/nt/ntdll/NtRegisterThreadTerminatePort.s b/libc/nt/ntdll/NtRegisterThreadTerminatePort.s new file mode 100644 index 00000000..ba7ffff9 --- /dev/null +++ b/libc/nt/ntdll/NtRegisterThreadTerminatePort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRegisterThreadTerminatePort diff --git a/libc/nt/ntdll/NtReleaseKeyedEvent.s b/libc/nt/ntdll/NtReleaseKeyedEvent.s new file mode 100644 index 00000000..83210f8c --- /dev/null +++ b/libc/nt/ntdll/NtReleaseKeyedEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtReleaseKeyedEvent diff --git a/libc/nt/ntdll/NtReleaseMutant.s b/libc/nt/ntdll/NtReleaseMutant.s new file mode 100644 index 00000000..3486490c --- /dev/null +++ b/libc/nt/ntdll/NtReleaseMutant.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtReleaseMutant diff --git a/libc/nt/ntdll/NtReleaseSemaphore.s b/libc/nt/ntdll/NtReleaseSemaphore.s new file mode 100644 index 00000000..1dac0852 --- /dev/null +++ b/libc/nt/ntdll/NtReleaseSemaphore.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtReleaseSemaphore diff --git a/libc/nt/ntdll/NtReleaseWorkerFactoryWorker.s b/libc/nt/ntdll/NtReleaseWorkerFactoryWorker.s new file mode 100644 index 00000000..367efa49 --- /dev/null +++ b/libc/nt/ntdll/NtReleaseWorkerFactoryWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtReleaseWorkerFactoryWorker diff --git a/libc/nt/ntdll/NtRemoveIoCompletion.s b/libc/nt/ntdll/NtRemoveIoCompletion.s new file mode 100644 index 00000000..c07326f5 --- /dev/null +++ b/libc/nt/ntdll/NtRemoveIoCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRemoveIoCompletion diff --git a/libc/nt/ntdll/NtRemoveIoCompletionEx.s b/libc/nt/ntdll/NtRemoveIoCompletionEx.s new file mode 100644 index 00000000..5c0e681e --- /dev/null +++ b/libc/nt/ntdll/NtRemoveIoCompletionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRemoveIoCompletionEx diff --git a/libc/nt/ntdll/NtRemoveProcessDebug.s b/libc/nt/ntdll/NtRemoveProcessDebug.s new file mode 100644 index 00000000..0edbd0b7 --- /dev/null +++ b/libc/nt/ntdll/NtRemoveProcessDebug.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRemoveProcessDebug diff --git a/libc/nt/ntdll/NtRenameKey.s b/libc/nt/ntdll/NtRenameKey.s new file mode 100644 index 00000000..a7bf8af7 --- /dev/null +++ b/libc/nt/ntdll/NtRenameKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRenameKey diff --git a/libc/nt/ntdll/NtRenameTransactionManager.s b/libc/nt/ntdll/NtRenameTransactionManager.s new file mode 100644 index 00000000..2de29481 --- /dev/null +++ b/libc/nt/ntdll/NtRenameTransactionManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRenameTransactionManager diff --git a/libc/nt/ntdll/NtReplaceKey.s b/libc/nt/ntdll/NtReplaceKey.s new file mode 100644 index 00000000..9074bc73 --- /dev/null +++ b/libc/nt/ntdll/NtReplaceKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtReplaceKey diff --git a/libc/nt/ntdll/NtReplacePartitionUnit.s b/libc/nt/ntdll/NtReplacePartitionUnit.s new file mode 100644 index 00000000..9be1f84d --- /dev/null +++ b/libc/nt/ntdll/NtReplacePartitionUnit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtReplacePartitionUnit diff --git a/libc/nt/ntdll/NtReplyPort.s b/libc/nt/ntdll/NtReplyPort.s new file mode 100644 index 00000000..5da0ba79 --- /dev/null +++ b/libc/nt/ntdll/NtReplyPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtReplyPort diff --git a/libc/nt/ntdll/NtReplyWaitReceivePort.s b/libc/nt/ntdll/NtReplyWaitReceivePort.s new file mode 100644 index 00000000..933d8270 --- /dev/null +++ b/libc/nt/ntdll/NtReplyWaitReceivePort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtReplyWaitReceivePort diff --git a/libc/nt/ntdll/NtReplyWaitReceivePortEx.s b/libc/nt/ntdll/NtReplyWaitReceivePortEx.s new file mode 100644 index 00000000..622462f8 --- /dev/null +++ b/libc/nt/ntdll/NtReplyWaitReceivePortEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtReplyWaitReceivePortEx diff --git a/libc/nt/ntdll/NtReplyWaitReplyPort.s b/libc/nt/ntdll/NtReplyWaitReplyPort.s new file mode 100644 index 00000000..2246cef2 --- /dev/null +++ b/libc/nt/ntdll/NtReplyWaitReplyPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtReplyWaitReplyPort diff --git a/libc/nt/ntdll/NtRequestPort.s b/libc/nt/ntdll/NtRequestPort.s new file mode 100644 index 00000000..3e000418 --- /dev/null +++ b/libc/nt/ntdll/NtRequestPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRequestPort diff --git a/libc/nt/ntdll/NtRequestWaitReplyPort.s b/libc/nt/ntdll/NtRequestWaitReplyPort.s new file mode 100644 index 00000000..b79ba2fa --- /dev/null +++ b/libc/nt/ntdll/NtRequestWaitReplyPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRequestWaitReplyPort diff --git a/libc/nt/ntdll/NtResetEvent.s b/libc/nt/ntdll/NtResetEvent.s new file mode 100644 index 00000000..a89c752a --- /dev/null +++ b/libc/nt/ntdll/NtResetEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtResetEvent diff --git a/libc/nt/ntdll/NtResetWriteWatch.s b/libc/nt/ntdll/NtResetWriteWatch.s new file mode 100644 index 00000000..ce1e005a --- /dev/null +++ b/libc/nt/ntdll/NtResetWriteWatch.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtResetWriteWatch diff --git a/libc/nt/ntdll/NtRestoreKey.s b/libc/nt/ntdll/NtRestoreKey.s new file mode 100644 index 00000000..e84855a9 --- /dev/null +++ b/libc/nt/ntdll/NtRestoreKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRestoreKey diff --git a/libc/nt/ntdll/NtResumeProcess.s b/libc/nt/ntdll/NtResumeProcess.s new file mode 100644 index 00000000..26b2fcf5 --- /dev/null +++ b/libc/nt/ntdll/NtResumeProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtResumeProcess diff --git a/libc/nt/ntdll/NtResumeThread.s b/libc/nt/ntdll/NtResumeThread.s new file mode 100644 index 00000000..2d4d272a --- /dev/null +++ b/libc/nt/ntdll/NtResumeThread.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtResumeThread + + .text.windows +NtResumeThread: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtResumeThread(%rip),%rax + jmp __sysv2nt + .endfn NtResumeThread,globl + .previous diff --git a/libc/nt/ntdll/NtRevertContainerImpersonation.s b/libc/nt/ntdll/NtRevertContainerImpersonation.s new file mode 100644 index 00000000..9416322c --- /dev/null +++ b/libc/nt/ntdll/NtRevertContainerImpersonation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRevertContainerImpersonation diff --git a/libc/nt/ntdll/NtRollbackComplete.s b/libc/nt/ntdll/NtRollbackComplete.s new file mode 100644 index 00000000..88d9fad4 --- /dev/null +++ b/libc/nt/ntdll/NtRollbackComplete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRollbackComplete diff --git a/libc/nt/ntdll/NtRollbackEnlistment.s b/libc/nt/ntdll/NtRollbackEnlistment.s new file mode 100644 index 00000000..a7e33280 --- /dev/null +++ b/libc/nt/ntdll/NtRollbackEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRollbackEnlistment diff --git a/libc/nt/ntdll/NtRollbackRegistryTransaction.s b/libc/nt/ntdll/NtRollbackRegistryTransaction.s new file mode 100644 index 00000000..fbc1dfa0 --- /dev/null +++ b/libc/nt/ntdll/NtRollbackRegistryTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRollbackRegistryTransaction diff --git a/libc/nt/ntdll/NtRollbackTransaction.s b/libc/nt/ntdll/NtRollbackTransaction.s new file mode 100644 index 00000000..9772b960 --- /dev/null +++ b/libc/nt/ntdll/NtRollbackTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRollbackTransaction diff --git a/libc/nt/ntdll/NtRollforwardTransactionManager.s b/libc/nt/ntdll/NtRollforwardTransactionManager.s new file mode 100644 index 00000000..3fcc7128 --- /dev/null +++ b/libc/nt/ntdll/NtRollforwardTransactionManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtRollforwardTransactionManager diff --git a/libc/nt/ntdll/NtSaveKey.s b/libc/nt/ntdll/NtSaveKey.s new file mode 100644 index 00000000..b448a900 --- /dev/null +++ b/libc/nt/ntdll/NtSaveKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSaveKey diff --git a/libc/nt/ntdll/NtSaveKeyEx.s b/libc/nt/ntdll/NtSaveKeyEx.s new file mode 100644 index 00000000..99eb4c26 --- /dev/null +++ b/libc/nt/ntdll/NtSaveKeyEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSaveKeyEx diff --git a/libc/nt/ntdll/NtSaveMergedKeys.s b/libc/nt/ntdll/NtSaveMergedKeys.s new file mode 100644 index 00000000..eca8342f --- /dev/null +++ b/libc/nt/ntdll/NtSaveMergedKeys.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSaveMergedKeys diff --git a/libc/nt/ntdll/NtSecureConnectPort.s b/libc/nt/ntdll/NtSecureConnectPort.s new file mode 100644 index 00000000..ba9c086c --- /dev/null +++ b/libc/nt/ntdll/NtSecureConnectPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSecureConnectPort diff --git a/libc/nt/ntdll/NtSerializeBoot.s b/libc/nt/ntdll/NtSerializeBoot.s new file mode 100644 index 00000000..8c6a8718 --- /dev/null +++ b/libc/nt/ntdll/NtSerializeBoot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSerializeBoot diff --git a/libc/nt/ntdll/NtSetBootEntryOrder.s b/libc/nt/ntdll/NtSetBootEntryOrder.s new file mode 100644 index 00000000..b73d7ba3 --- /dev/null +++ b/libc/nt/ntdll/NtSetBootEntryOrder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetBootEntryOrder diff --git a/libc/nt/ntdll/NtSetBootOptions.s b/libc/nt/ntdll/NtSetBootOptions.s new file mode 100644 index 00000000..b42d7cd6 --- /dev/null +++ b/libc/nt/ntdll/NtSetBootOptions.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetBootOptions diff --git a/libc/nt/ntdll/NtSetCachedSigningLevel.s b/libc/nt/ntdll/NtSetCachedSigningLevel.s new file mode 100644 index 00000000..1d133b2e --- /dev/null +++ b/libc/nt/ntdll/NtSetCachedSigningLevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetCachedSigningLevel diff --git a/libc/nt/ntdll/NtSetCachedSigningLevel2.s b/libc/nt/ntdll/NtSetCachedSigningLevel2.s new file mode 100644 index 00000000..62a70db9 --- /dev/null +++ b/libc/nt/ntdll/NtSetCachedSigningLevel2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetCachedSigningLevel2 diff --git a/libc/nt/ntdll/NtSetContextThread.s b/libc/nt/ntdll/NtSetContextThread.s new file mode 100644 index 00000000..0c47aa7b --- /dev/null +++ b/libc/nt/ntdll/NtSetContextThread.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetContextThread + + .text.windows +NtSetContextThread: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtSetContextThread(%rip),%rax + jmp __sysv2nt + .endfn NtSetContextThread,globl + .previous diff --git a/libc/nt/ntdll/NtSetDebugFilterState.s b/libc/nt/ntdll/NtSetDebugFilterState.s new file mode 100644 index 00000000..2b7cb3c9 --- /dev/null +++ b/libc/nt/ntdll/NtSetDebugFilterState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetDebugFilterState diff --git a/libc/nt/ntdll/NtSetDefaultHardErrorPort.s b/libc/nt/ntdll/NtSetDefaultHardErrorPort.s new file mode 100644 index 00000000..110b7aff --- /dev/null +++ b/libc/nt/ntdll/NtSetDefaultHardErrorPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetDefaultHardErrorPort diff --git a/libc/nt/ntdll/NtSetDefaultLocale.s b/libc/nt/ntdll/NtSetDefaultLocale.s new file mode 100644 index 00000000..2db99871 --- /dev/null +++ b/libc/nt/ntdll/NtSetDefaultLocale.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetDefaultLocale diff --git a/libc/nt/ntdll/NtSetDefaultUILanguage.s b/libc/nt/ntdll/NtSetDefaultUILanguage.s new file mode 100644 index 00000000..54280f69 --- /dev/null +++ b/libc/nt/ntdll/NtSetDefaultUILanguage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetDefaultUILanguage diff --git a/libc/nt/ntdll/NtSetDriverEntryOrder.s b/libc/nt/ntdll/NtSetDriverEntryOrder.s new file mode 100644 index 00000000..d49903a5 --- /dev/null +++ b/libc/nt/ntdll/NtSetDriverEntryOrder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetDriverEntryOrder diff --git a/libc/nt/ntdll/NtSetEaFile.s b/libc/nt/ntdll/NtSetEaFile.s new file mode 100644 index 00000000..4d5612a8 --- /dev/null +++ b/libc/nt/ntdll/NtSetEaFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetEaFile diff --git a/libc/nt/ntdll/NtSetEvent.s b/libc/nt/ntdll/NtSetEvent.s new file mode 100644 index 00000000..c2d9edc2 --- /dev/null +++ b/libc/nt/ntdll/NtSetEvent.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetEvent + + .text.windows +NtSetEvent: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtSetEvent(%rip),%rax + jmp __sysv2nt + .endfn NtSetEvent,globl + .previous diff --git a/libc/nt/ntdll/NtSetEventBoostPriority.s b/libc/nt/ntdll/NtSetEventBoostPriority.s new file mode 100644 index 00000000..7ccb0c20 --- /dev/null +++ b/libc/nt/ntdll/NtSetEventBoostPriority.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetEventBoostPriority diff --git a/libc/nt/ntdll/NtSetHighEventPair.s b/libc/nt/ntdll/NtSetHighEventPair.s new file mode 100644 index 00000000..928f15e9 --- /dev/null +++ b/libc/nt/ntdll/NtSetHighEventPair.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetHighEventPair diff --git a/libc/nt/ntdll/NtSetHighWaitLowEventPair.s b/libc/nt/ntdll/NtSetHighWaitLowEventPair.s new file mode 100644 index 00000000..f5f25709 --- /dev/null +++ b/libc/nt/ntdll/NtSetHighWaitLowEventPair.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetHighWaitLowEventPair diff --git a/libc/nt/ntdll/NtSetIRTimer.s b/libc/nt/ntdll/NtSetIRTimer.s new file mode 100644 index 00000000..593cecfe --- /dev/null +++ b/libc/nt/ntdll/NtSetIRTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetIRTimer diff --git a/libc/nt/ntdll/NtSetInformationDebugObject.s b/libc/nt/ntdll/NtSetInformationDebugObject.s new file mode 100644 index 00000000..892aace3 --- /dev/null +++ b/libc/nt/ntdll/NtSetInformationDebugObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetInformationDebugObject diff --git a/libc/nt/ntdll/NtSetInformationEnlistment.s b/libc/nt/ntdll/NtSetInformationEnlistment.s new file mode 100644 index 00000000..4284fae6 --- /dev/null +++ b/libc/nt/ntdll/NtSetInformationEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetInformationEnlistment diff --git a/libc/nt/ntdll/NtSetInformationFile.s b/libc/nt/ntdll/NtSetInformationFile.s new file mode 100644 index 00000000..b8387118 --- /dev/null +++ b/libc/nt/ntdll/NtSetInformationFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetInformationFile + + .text.windows +NtSetInformationFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtSetInformationFile(%rip),%rax + jmp __sysv2nt6 + .endfn NtSetInformationFile,globl + .previous diff --git a/libc/nt/ntdll/NtSetInformationJobObject.s b/libc/nt/ntdll/NtSetInformationJobObject.s new file mode 100644 index 00000000..ee0af022 --- /dev/null +++ b/libc/nt/ntdll/NtSetInformationJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetInformationJobObject diff --git a/libc/nt/ntdll/NtSetInformationKey.s b/libc/nt/ntdll/NtSetInformationKey.s new file mode 100644 index 00000000..a852c2ed --- /dev/null +++ b/libc/nt/ntdll/NtSetInformationKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetInformationKey diff --git a/libc/nt/ntdll/NtSetInformationObject.s b/libc/nt/ntdll/NtSetInformationObject.s new file mode 100644 index 00000000..8b576277 --- /dev/null +++ b/libc/nt/ntdll/NtSetInformationObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetInformationObject diff --git a/libc/nt/ntdll/NtSetInformationProcess.s b/libc/nt/ntdll/NtSetInformationProcess.s new file mode 100644 index 00000000..50eb6a4e --- /dev/null +++ b/libc/nt/ntdll/NtSetInformationProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetInformationProcess diff --git a/libc/nt/ntdll/NtSetInformationResourceManager.s b/libc/nt/ntdll/NtSetInformationResourceManager.s new file mode 100644 index 00000000..4bb94bb6 --- /dev/null +++ b/libc/nt/ntdll/NtSetInformationResourceManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetInformationResourceManager diff --git a/libc/nt/ntdll/NtSetInformationSymbolicLink.s b/libc/nt/ntdll/NtSetInformationSymbolicLink.s new file mode 100644 index 00000000..5c89542b --- /dev/null +++ b/libc/nt/ntdll/NtSetInformationSymbolicLink.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetInformationSymbolicLink diff --git a/libc/nt/ntdll/NtSetInformationThread.s b/libc/nt/ntdll/NtSetInformationThread.s new file mode 100644 index 00000000..0c7c8f85 --- /dev/null +++ b/libc/nt/ntdll/NtSetInformationThread.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetInformationThread + + .text.windows +NtSetInformationThread: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtSetInformationThread(%rip),%rax + jmp __sysv2nt + .endfn NtSetInformationThread,globl + .previous diff --git a/libc/nt/ntdll/NtSetInformationToken.s b/libc/nt/ntdll/NtSetInformationToken.s new file mode 100644 index 00000000..604a77da --- /dev/null +++ b/libc/nt/ntdll/NtSetInformationToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetInformationToken diff --git a/libc/nt/ntdll/NtSetInformationTransaction.s b/libc/nt/ntdll/NtSetInformationTransaction.s new file mode 100644 index 00000000..41bd4a73 --- /dev/null +++ b/libc/nt/ntdll/NtSetInformationTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetInformationTransaction diff --git a/libc/nt/ntdll/NtSetInformationTransactionManager.s b/libc/nt/ntdll/NtSetInformationTransactionManager.s new file mode 100644 index 00000000..4d90081a --- /dev/null +++ b/libc/nt/ntdll/NtSetInformationTransactionManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetInformationTransactionManager diff --git a/libc/nt/ntdll/NtSetInformationVirtualMemory.s b/libc/nt/ntdll/NtSetInformationVirtualMemory.s new file mode 100644 index 00000000..da1f16fa --- /dev/null +++ b/libc/nt/ntdll/NtSetInformationVirtualMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetInformationVirtualMemory diff --git a/libc/nt/ntdll/NtSetInformationWorkerFactory.s b/libc/nt/ntdll/NtSetInformationWorkerFactory.s new file mode 100644 index 00000000..baed3cbe --- /dev/null +++ b/libc/nt/ntdll/NtSetInformationWorkerFactory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetInformationWorkerFactory diff --git a/libc/nt/ntdll/NtSetIntervalProfile.s b/libc/nt/ntdll/NtSetIntervalProfile.s new file mode 100644 index 00000000..111d4f92 --- /dev/null +++ b/libc/nt/ntdll/NtSetIntervalProfile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetIntervalProfile + + .text.windows +NtSetIntervalProfile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtSetIntervalProfile(%rip),%rax + jmp __sysv2nt + .endfn NtSetIntervalProfile,globl + .previous diff --git a/libc/nt/ntdll/NtSetIoCompletion.s b/libc/nt/ntdll/NtSetIoCompletion.s new file mode 100644 index 00000000..a23d7bf7 --- /dev/null +++ b/libc/nt/ntdll/NtSetIoCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetIoCompletion diff --git a/libc/nt/ntdll/NtSetIoCompletionEx.s b/libc/nt/ntdll/NtSetIoCompletionEx.s new file mode 100644 index 00000000..fd5034b1 --- /dev/null +++ b/libc/nt/ntdll/NtSetIoCompletionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetIoCompletionEx diff --git a/libc/nt/ntdll/NtSetLdtEntries.s b/libc/nt/ntdll/NtSetLdtEntries.s new file mode 100644 index 00000000..744da425 --- /dev/null +++ b/libc/nt/ntdll/NtSetLdtEntries.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetLdtEntries diff --git a/libc/nt/ntdll/NtSetLowEventPair.s b/libc/nt/ntdll/NtSetLowEventPair.s new file mode 100644 index 00000000..9d99d2e9 --- /dev/null +++ b/libc/nt/ntdll/NtSetLowEventPair.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetLowEventPair diff --git a/libc/nt/ntdll/NtSetLowWaitHighEventPair.s b/libc/nt/ntdll/NtSetLowWaitHighEventPair.s new file mode 100644 index 00000000..5fa73f64 --- /dev/null +++ b/libc/nt/ntdll/NtSetLowWaitHighEventPair.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetLowWaitHighEventPair diff --git a/libc/nt/ntdll/NtSetQuotaInformationFile.s b/libc/nt/ntdll/NtSetQuotaInformationFile.s new file mode 100644 index 00000000..78406728 --- /dev/null +++ b/libc/nt/ntdll/NtSetQuotaInformationFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetQuotaInformationFile diff --git a/libc/nt/ntdll/NtSetSecurityObject.s b/libc/nt/ntdll/NtSetSecurityObject.s new file mode 100644 index 00000000..8e910b9c --- /dev/null +++ b/libc/nt/ntdll/NtSetSecurityObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetSecurityObject diff --git a/libc/nt/ntdll/NtSetSystemEnvironmentValue.s b/libc/nt/ntdll/NtSetSystemEnvironmentValue.s new file mode 100644 index 00000000..29d8fb8b --- /dev/null +++ b/libc/nt/ntdll/NtSetSystemEnvironmentValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetSystemEnvironmentValue diff --git a/libc/nt/ntdll/NtSetSystemEnvironmentValueEx.s b/libc/nt/ntdll/NtSetSystemEnvironmentValueEx.s new file mode 100644 index 00000000..9ff24203 --- /dev/null +++ b/libc/nt/ntdll/NtSetSystemEnvironmentValueEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetSystemEnvironmentValueEx diff --git a/libc/nt/ntdll/NtSetSystemInformation.s b/libc/nt/ntdll/NtSetSystemInformation.s new file mode 100644 index 00000000..86072da8 --- /dev/null +++ b/libc/nt/ntdll/NtSetSystemInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetSystemInformation diff --git a/libc/nt/ntdll/NtSetSystemPowerState.s b/libc/nt/ntdll/NtSetSystemPowerState.s new file mode 100644 index 00000000..32724357 --- /dev/null +++ b/libc/nt/ntdll/NtSetSystemPowerState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetSystemPowerState diff --git a/libc/nt/ntdll/NtSetSystemTime.s b/libc/nt/ntdll/NtSetSystemTime.s new file mode 100644 index 00000000..c0759100 --- /dev/null +++ b/libc/nt/ntdll/NtSetSystemTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetSystemTime diff --git a/libc/nt/ntdll/NtSetThreadExecutionState.s b/libc/nt/ntdll/NtSetThreadExecutionState.s new file mode 100644 index 00000000..ffc899bd --- /dev/null +++ b/libc/nt/ntdll/NtSetThreadExecutionState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetThreadExecutionState diff --git a/libc/nt/ntdll/NtSetTimer.s b/libc/nt/ntdll/NtSetTimer.s new file mode 100644 index 00000000..f6d53733 --- /dev/null +++ b/libc/nt/ntdll/NtSetTimer.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetTimer + + .text.windows +NtSetTimer: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtSetTimer(%rip),%rax + jmp __sysv2nt8 + .endfn NtSetTimer,globl + .previous diff --git a/libc/nt/ntdll/NtSetTimer2.s b/libc/nt/ntdll/NtSetTimer2.s new file mode 100644 index 00000000..bcaf6891 --- /dev/null +++ b/libc/nt/ntdll/NtSetTimer2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetTimer2 diff --git a/libc/nt/ntdll/NtSetTimerEx.s b/libc/nt/ntdll/NtSetTimerEx.s new file mode 100644 index 00000000..f424fbf5 --- /dev/null +++ b/libc/nt/ntdll/NtSetTimerEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetTimerEx diff --git a/libc/nt/ntdll/NtSetTimerResolution.s b/libc/nt/ntdll/NtSetTimerResolution.s new file mode 100644 index 00000000..01ac040e --- /dev/null +++ b/libc/nt/ntdll/NtSetTimerResolution.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetTimerResolution diff --git a/libc/nt/ntdll/NtSetUuidSeed.s b/libc/nt/ntdll/NtSetUuidSeed.s new file mode 100644 index 00000000..9f5eaee8 --- /dev/null +++ b/libc/nt/ntdll/NtSetUuidSeed.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetUuidSeed diff --git a/libc/nt/ntdll/NtSetValueKey.s b/libc/nt/ntdll/NtSetValueKey.s new file mode 100644 index 00000000..18404ba2 --- /dev/null +++ b/libc/nt/ntdll/NtSetValueKey.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetValueKey + + .text.windows +NtSetValueKey: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtSetValueKey(%rip),%rax + jmp __sysv2nt6 + .endfn NtSetValueKey,globl + .previous diff --git a/libc/nt/ntdll/NtSetVolumeInformationFile.s b/libc/nt/ntdll/NtSetVolumeInformationFile.s new file mode 100644 index 00000000..3469c5e3 --- /dev/null +++ b/libc/nt/ntdll/NtSetVolumeInformationFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetVolumeInformationFile diff --git a/libc/nt/ntdll/NtSetWnfProcessNotificationEvent.s b/libc/nt/ntdll/NtSetWnfProcessNotificationEvent.s new file mode 100644 index 00000000..b4cbf133 --- /dev/null +++ b/libc/nt/ntdll/NtSetWnfProcessNotificationEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSetWnfProcessNotificationEvent diff --git a/libc/nt/ntdll/NtShutdownSystem.s b/libc/nt/ntdll/NtShutdownSystem.s new file mode 100644 index 00000000..16608ce9 --- /dev/null +++ b/libc/nt/ntdll/NtShutdownSystem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtShutdownSystem diff --git a/libc/nt/ntdll/NtShutdownWorkerFactory.s b/libc/nt/ntdll/NtShutdownWorkerFactory.s new file mode 100644 index 00000000..5f45b412 --- /dev/null +++ b/libc/nt/ntdll/NtShutdownWorkerFactory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtShutdownWorkerFactory diff --git a/libc/nt/ntdll/NtSignalAndWaitForSingleObject.s b/libc/nt/ntdll/NtSignalAndWaitForSingleObject.s new file mode 100644 index 00000000..13fbaf79 --- /dev/null +++ b/libc/nt/ntdll/NtSignalAndWaitForSingleObject.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSignalAndWaitForSingleObject + + .text.windows +NtSignalAndWaitForSingleObject: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtSignalAndWaitForSingleObject(%rip),%rax + jmp __sysv2nt + .endfn NtSignalAndWaitForSingleObject,globl + .previous diff --git a/libc/nt/ntdll/NtSinglePhaseReject.s b/libc/nt/ntdll/NtSinglePhaseReject.s new file mode 100644 index 00000000..5d2ef19d --- /dev/null +++ b/libc/nt/ntdll/NtSinglePhaseReject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSinglePhaseReject diff --git a/libc/nt/ntdll/NtStartProfile.s b/libc/nt/ntdll/NtStartProfile.s new file mode 100644 index 00000000..4facb746 --- /dev/null +++ b/libc/nt/ntdll/NtStartProfile.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtStartProfile + + .text.windows +NtStartProfile: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_NtStartProfile(%rip) + leave + ret + .endfn NtStartProfile,globl + .previous diff --git a/libc/nt/ntdll/NtStopProfile.s b/libc/nt/ntdll/NtStopProfile.s new file mode 100644 index 00000000..62b9122a --- /dev/null +++ b/libc/nt/ntdll/NtStopProfile.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtStopProfile + + .text.windows +NtStopProfile: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_NtStopProfile(%rip) + leave + ret + .endfn NtStopProfile,globl + .previous diff --git a/libc/nt/ntdll/NtSubscribeWnfStateChange.s b/libc/nt/ntdll/NtSubscribeWnfStateChange.s new file mode 100644 index 00000000..79561a10 --- /dev/null +++ b/libc/nt/ntdll/NtSubscribeWnfStateChange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSubscribeWnfStateChange diff --git a/libc/nt/ntdll/NtSuspendProcess.s b/libc/nt/ntdll/NtSuspendProcess.s new file mode 100644 index 00000000..132fc2de --- /dev/null +++ b/libc/nt/ntdll/NtSuspendProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSuspendProcess diff --git a/libc/nt/ntdll/NtSuspendThread.s b/libc/nt/ntdll/NtSuspendThread.s new file mode 100644 index 00000000..de6cfb61 --- /dev/null +++ b/libc/nt/ntdll/NtSuspendThread.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSuspendThread + + .text.windows +NtSuspendThread: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtSuspendThread(%rip),%rax + jmp __sysv2nt + .endfn NtSuspendThread,globl + .previous diff --git a/libc/nt/ntdll/NtSystemDebugControl.s b/libc/nt/ntdll/NtSystemDebugControl.s new file mode 100644 index 00000000..908cfd29 --- /dev/null +++ b/libc/nt/ntdll/NtSystemDebugControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtSystemDebugControl diff --git a/libc/nt/ntdll/NtTerminateEnclave.s b/libc/nt/ntdll/NtTerminateEnclave.s new file mode 100644 index 00000000..02a6a5fc --- /dev/null +++ b/libc/nt/ntdll/NtTerminateEnclave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtTerminateEnclave diff --git a/libc/nt/ntdll/NtTerminateJobObject.s b/libc/nt/ntdll/NtTerminateJobObject.s new file mode 100644 index 00000000..20637c34 --- /dev/null +++ b/libc/nt/ntdll/NtTerminateJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtTerminateJobObject diff --git a/libc/nt/ntdll/NtTerminateProcess.s b/libc/nt/ntdll/NtTerminateProcess.s new file mode 100644 index 00000000..0a40c124 --- /dev/null +++ b/libc/nt/ntdll/NtTerminateProcess.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtTerminateProcess + + .text.windows +NtTerminateProcess: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtTerminateProcess(%rip),%rax + jmp __sysv2nt + .endfn NtTerminateProcess,globl + .previous diff --git a/libc/nt/ntdll/NtTerminateThread.s b/libc/nt/ntdll/NtTerminateThread.s new file mode 100644 index 00000000..eab84cd8 --- /dev/null +++ b/libc/nt/ntdll/NtTerminateThread.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtTerminateThread + + .text.windows +NtTerminateThread: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtTerminateThread(%rip),%rax + jmp __sysv2nt + .endfn NtTerminateThread,globl + .previous diff --git a/libc/nt/ntdll/NtTestAlert.s b/libc/nt/ntdll/NtTestAlert.s new file mode 100644 index 00000000..67a5c04d --- /dev/null +++ b/libc/nt/ntdll/NtTestAlert.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtTestAlert + + .text.windows +NtTestAlert: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_NtTestAlert(%rip) + leave + ret + .endfn NtTestAlert,globl + .previous diff --git a/libc/nt/ntdll/NtThawRegistry.s b/libc/nt/ntdll/NtThawRegistry.s new file mode 100644 index 00000000..ed4afd9c --- /dev/null +++ b/libc/nt/ntdll/NtThawRegistry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtThawRegistry diff --git a/libc/nt/ntdll/NtThawTransactions.s b/libc/nt/ntdll/NtThawTransactions.s new file mode 100644 index 00000000..229763df --- /dev/null +++ b/libc/nt/ntdll/NtThawTransactions.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtThawTransactions diff --git a/libc/nt/ntdll/NtTraceControl.s b/libc/nt/ntdll/NtTraceControl.s new file mode 100644 index 00000000..2f191cde --- /dev/null +++ b/libc/nt/ntdll/NtTraceControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtTraceControl diff --git a/libc/nt/ntdll/NtTraceEvent.s b/libc/nt/ntdll/NtTraceEvent.s new file mode 100644 index 00000000..cd6adb8e --- /dev/null +++ b/libc/nt/ntdll/NtTraceEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtTraceEvent diff --git a/libc/nt/ntdll/NtTranslateFilePath.s b/libc/nt/ntdll/NtTranslateFilePath.s new file mode 100644 index 00000000..53261d2e --- /dev/null +++ b/libc/nt/ntdll/NtTranslateFilePath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtTranslateFilePath diff --git a/libc/nt/ntdll/NtUmsThreadYield.s b/libc/nt/ntdll/NtUmsThreadYield.s new file mode 100644 index 00000000..c30c5838 --- /dev/null +++ b/libc/nt/ntdll/NtUmsThreadYield.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtUmsThreadYield diff --git a/libc/nt/ntdll/NtUnloadDriver.s b/libc/nt/ntdll/NtUnloadDriver.s new file mode 100644 index 00000000..4d839407 --- /dev/null +++ b/libc/nt/ntdll/NtUnloadDriver.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtUnloadDriver diff --git a/libc/nt/ntdll/NtUnloadKey.s b/libc/nt/ntdll/NtUnloadKey.s new file mode 100644 index 00000000..04c1a778 --- /dev/null +++ b/libc/nt/ntdll/NtUnloadKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtUnloadKey diff --git a/libc/nt/ntdll/NtUnloadKey2.s b/libc/nt/ntdll/NtUnloadKey2.s new file mode 100644 index 00000000..84ca12f2 --- /dev/null +++ b/libc/nt/ntdll/NtUnloadKey2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtUnloadKey2 diff --git a/libc/nt/ntdll/NtUnloadKeyEx.s b/libc/nt/ntdll/NtUnloadKeyEx.s new file mode 100644 index 00000000..697cc7b8 --- /dev/null +++ b/libc/nt/ntdll/NtUnloadKeyEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtUnloadKeyEx diff --git a/libc/nt/ntdll/NtUnlockFile.s b/libc/nt/ntdll/NtUnlockFile.s new file mode 100644 index 00000000..1f583ab2 --- /dev/null +++ b/libc/nt/ntdll/NtUnlockFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtUnlockFile diff --git a/libc/nt/ntdll/NtUnlockVirtualMemory.s b/libc/nt/ntdll/NtUnlockVirtualMemory.s new file mode 100644 index 00000000..96dea09d --- /dev/null +++ b/libc/nt/ntdll/NtUnlockVirtualMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtUnlockVirtualMemory diff --git a/libc/nt/ntdll/NtUnmapViewOfSection.s b/libc/nt/ntdll/NtUnmapViewOfSection.s new file mode 100644 index 00000000..2d5fc1fd --- /dev/null +++ b/libc/nt/ntdll/NtUnmapViewOfSection.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtUnmapViewOfSection + + .text.windows +NtUnmapViewOfSection: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtUnmapViewOfSection(%rip),%rax + jmp __sysv2nt + .endfn NtUnmapViewOfSection,globl + .previous diff --git a/libc/nt/ntdll/NtUnmapViewOfSectionEx.s b/libc/nt/ntdll/NtUnmapViewOfSectionEx.s new file mode 100644 index 00000000..1d033543 --- /dev/null +++ b/libc/nt/ntdll/NtUnmapViewOfSectionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtUnmapViewOfSectionEx diff --git a/libc/nt/ntdll/NtUnsubscribeWnfStateChange.s b/libc/nt/ntdll/NtUnsubscribeWnfStateChange.s new file mode 100644 index 00000000..30f3de6d --- /dev/null +++ b/libc/nt/ntdll/NtUnsubscribeWnfStateChange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtUnsubscribeWnfStateChange diff --git a/libc/nt/ntdll/NtUpdateWnfStateData.s b/libc/nt/ntdll/NtUpdateWnfStateData.s new file mode 100644 index 00000000..5d64cf3d --- /dev/null +++ b/libc/nt/ntdll/NtUpdateWnfStateData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtUpdateWnfStateData diff --git a/libc/nt/ntdll/NtVdmControl.s b/libc/nt/ntdll/NtVdmControl.s new file mode 100644 index 00000000..a786e88c --- /dev/null +++ b/libc/nt/ntdll/NtVdmControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtVdmControl diff --git a/libc/nt/ntdll/NtWaitForAlertByThreadId.s b/libc/nt/ntdll/NtWaitForAlertByThreadId.s new file mode 100644 index 00000000..0718fa81 --- /dev/null +++ b/libc/nt/ntdll/NtWaitForAlertByThreadId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtWaitForAlertByThreadId diff --git a/libc/nt/ntdll/NtWaitForDebugEvent.s b/libc/nt/ntdll/NtWaitForDebugEvent.s new file mode 100644 index 00000000..75218bd4 --- /dev/null +++ b/libc/nt/ntdll/NtWaitForDebugEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtWaitForDebugEvent diff --git a/libc/nt/ntdll/NtWaitForKeyedEvent.s b/libc/nt/ntdll/NtWaitForKeyedEvent.s new file mode 100644 index 00000000..032ab561 --- /dev/null +++ b/libc/nt/ntdll/NtWaitForKeyedEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtWaitForKeyedEvent diff --git a/libc/nt/ntdll/NtWaitForMultipleObjects.s b/libc/nt/ntdll/NtWaitForMultipleObjects.s new file mode 100644 index 00000000..89174232 --- /dev/null +++ b/libc/nt/ntdll/NtWaitForMultipleObjects.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtWaitForMultipleObjects diff --git a/libc/nt/ntdll/NtWaitForMultipleObjects32.s b/libc/nt/ntdll/NtWaitForMultipleObjects32.s new file mode 100644 index 00000000..0955c67e --- /dev/null +++ b/libc/nt/ntdll/NtWaitForMultipleObjects32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtWaitForMultipleObjects32 diff --git a/libc/nt/ntdll/NtWaitForSingleObject.s b/libc/nt/ntdll/NtWaitForSingleObject.s new file mode 100644 index 00000000..2422cced --- /dev/null +++ b/libc/nt/ntdll/NtWaitForSingleObject.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtWaitForSingleObject + + .text.windows +NtWaitForSingleObject: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtWaitForSingleObject(%rip),%rax + jmp __sysv2nt + .endfn NtWaitForSingleObject,globl + .previous diff --git a/libc/nt/ntdll/NtWaitForWorkViaWorkerFactory.s b/libc/nt/ntdll/NtWaitForWorkViaWorkerFactory.s new file mode 100644 index 00000000..d316eb36 --- /dev/null +++ b/libc/nt/ntdll/NtWaitForWorkViaWorkerFactory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtWaitForWorkViaWorkerFactory diff --git a/libc/nt/ntdll/NtWaitHighEventPair.s b/libc/nt/ntdll/NtWaitHighEventPair.s new file mode 100644 index 00000000..9cca1a5a --- /dev/null +++ b/libc/nt/ntdll/NtWaitHighEventPair.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtWaitHighEventPair diff --git a/libc/nt/ntdll/NtWaitLowEventPair.s b/libc/nt/ntdll/NtWaitLowEventPair.s new file mode 100644 index 00000000..a0a9f5da --- /dev/null +++ b/libc/nt/ntdll/NtWaitLowEventPair.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtWaitLowEventPair diff --git a/libc/nt/ntdll/NtWorkerFactoryWorkerReady.s b/libc/nt/ntdll/NtWorkerFactoryWorkerReady.s new file mode 100644 index 00000000..9a1ab2a9 --- /dev/null +++ b/libc/nt/ntdll/NtWorkerFactoryWorkerReady.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtWorkerFactoryWorkerReady diff --git a/libc/nt/ntdll/NtWriteFile.s b/libc/nt/ntdll/NtWriteFile.s new file mode 100644 index 00000000..686d6513 --- /dev/null +++ b/libc/nt/ntdll/NtWriteFile.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtWriteFile + + .text.windows +NtWriteFile: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtWriteFile(%rip),%rax + jmp __sysv2nt10 + .endfn NtWriteFile,globl + .previous diff --git a/libc/nt/ntdll/NtWriteFileGather.s b/libc/nt/ntdll/NtWriteFileGather.s new file mode 100644 index 00000000..17903dec --- /dev/null +++ b/libc/nt/ntdll/NtWriteFileGather.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtWriteFileGather diff --git a/libc/nt/ntdll/NtWriteRequestData.s b/libc/nt/ntdll/NtWriteRequestData.s new file mode 100644 index 00000000..5626e302 --- /dev/null +++ b/libc/nt/ntdll/NtWriteRequestData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtWriteRequestData diff --git a/libc/nt/ntdll/NtWriteVirtualMemory.s b/libc/nt/ntdll/NtWriteVirtualMemory.s new file mode 100644 index 00000000..cf3a0e3a --- /dev/null +++ b/libc/nt/ntdll/NtWriteVirtualMemory.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtWriteVirtualMemory + + .text.windows +NtWriteVirtualMemory: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_NtWriteVirtualMemory(%rip),%rax + jmp __sysv2nt6 + .endfn NtWriteVirtualMemory,globl + .previous diff --git a/libc/nt/ntdll/NtYieldExecution.s b/libc/nt/ntdll/NtYieldExecution.s new file mode 100644 index 00000000..e052de6a --- /dev/null +++ b/libc/nt/ntdll/NtYieldExecution.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtYieldExecution + + .text.windows +NtYieldExecution: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_NtYieldExecution(%rip) + leave + ret + .endfn NtYieldExecution,globl + .previous diff --git a/libc/nt/ntdll/NtdllDefWindowProc_A.s b/libc/nt/ntdll/NtdllDefWindowProc_A.s new file mode 100644 index 00000000..3cd3bb87 --- /dev/null +++ b/libc/nt/ntdll/NtdllDefWindowProc_A.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtdllDefWindowProc_A diff --git a/libc/nt/ntdll/NtdllDefWindowProc_W.s b/libc/nt/ntdll/NtdllDefWindowProc_W.s new file mode 100644 index 00000000..1bb8fc03 --- /dev/null +++ b/libc/nt/ntdll/NtdllDefWindowProc_W.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtdllDefWindowProc_W diff --git a/libc/nt/ntdll/NtdllDialogWndProc_A.s b/libc/nt/ntdll/NtdllDialogWndProc_A.s new file mode 100644 index 00000000..32b492cd --- /dev/null +++ b/libc/nt/ntdll/NtdllDialogWndProc_A.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtdllDialogWndProc_A diff --git a/libc/nt/ntdll/NtdllDialogWndProc_W.s b/libc/nt/ntdll/NtdllDialogWndProc_W.s new file mode 100644 index 00000000..0b6b2e29 --- /dev/null +++ b/libc/nt/ntdll/NtdllDialogWndProc_W.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp NtdllDialogWndProc_W diff --git a/libc/nt/ntdll/PfxFindPrefix.s b/libc/nt/ntdll/PfxFindPrefix.s new file mode 100644 index 00000000..cc4278ac --- /dev/null +++ b/libc/nt/ntdll/PfxFindPrefix.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp PfxFindPrefix diff --git a/libc/nt/ntdll/PfxInitialize.s b/libc/nt/ntdll/PfxInitialize.s new file mode 100644 index 00000000..f77b486b --- /dev/null +++ b/libc/nt/ntdll/PfxInitialize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp PfxInitialize diff --git a/libc/nt/ntdll/PfxInsertPrefix.s b/libc/nt/ntdll/PfxInsertPrefix.s new file mode 100644 index 00000000..ff353946 --- /dev/null +++ b/libc/nt/ntdll/PfxInsertPrefix.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp PfxInsertPrefix diff --git a/libc/nt/ntdll/PfxRemovePrefix.s b/libc/nt/ntdll/PfxRemovePrefix.s new file mode 100644 index 00000000..2684e889 --- /dev/null +++ b/libc/nt/ntdll/PfxRemovePrefix.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp PfxRemovePrefix diff --git a/libc/nt/ntdll/PssNtCaptureSnapshot.s b/libc/nt/ntdll/PssNtCaptureSnapshot.s new file mode 100644 index 00000000..d9171edd --- /dev/null +++ b/libc/nt/ntdll/PssNtCaptureSnapshot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp PssNtCaptureSnapshot diff --git a/libc/nt/ntdll/PssNtDuplicateSnapshot.s b/libc/nt/ntdll/PssNtDuplicateSnapshot.s new file mode 100644 index 00000000..156890db --- /dev/null +++ b/libc/nt/ntdll/PssNtDuplicateSnapshot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp PssNtDuplicateSnapshot diff --git a/libc/nt/ntdll/PssNtFreeRemoteSnapshot.s b/libc/nt/ntdll/PssNtFreeRemoteSnapshot.s new file mode 100644 index 00000000..582e4887 --- /dev/null +++ b/libc/nt/ntdll/PssNtFreeRemoteSnapshot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp PssNtFreeRemoteSnapshot diff --git a/libc/nt/ntdll/PssNtFreeSnapshot.s b/libc/nt/ntdll/PssNtFreeSnapshot.s new file mode 100644 index 00000000..c0dc81df --- /dev/null +++ b/libc/nt/ntdll/PssNtFreeSnapshot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp PssNtFreeSnapshot diff --git a/libc/nt/ntdll/PssNtFreeWalkMarker.s b/libc/nt/ntdll/PssNtFreeWalkMarker.s new file mode 100644 index 00000000..2fd46209 --- /dev/null +++ b/libc/nt/ntdll/PssNtFreeWalkMarker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp PssNtFreeWalkMarker diff --git a/libc/nt/ntdll/PssNtQuerySnapshot.s b/libc/nt/ntdll/PssNtQuerySnapshot.s new file mode 100644 index 00000000..771b83fb --- /dev/null +++ b/libc/nt/ntdll/PssNtQuerySnapshot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp PssNtQuerySnapshot diff --git a/libc/nt/ntdll/PssNtValidateDescriptor.s b/libc/nt/ntdll/PssNtValidateDescriptor.s new file mode 100644 index 00000000..342f7edf --- /dev/null +++ b/libc/nt/ntdll/PssNtValidateDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp PssNtValidateDescriptor diff --git a/libc/nt/ntdll/PssNtWalkSnapshot.s b/libc/nt/ntdll/PssNtWalkSnapshot.s new file mode 100644 index 00000000..eb926f67 --- /dev/null +++ b/libc/nt/ntdll/PssNtWalkSnapshot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp PssNtWalkSnapshot diff --git a/libc/nt/ntdll/RtlAbortRXact.s b/libc/nt/ntdll/RtlAbortRXact.s new file mode 100644 index 00000000..44a7c21c --- /dev/null +++ b/libc/nt/ntdll/RtlAbortRXact.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAbortRXact diff --git a/libc/nt/ntdll/RtlAbsoluteToSelfRelativeSD.s b/libc/nt/ntdll/RtlAbsoluteToSelfRelativeSD.s new file mode 100644 index 00000000..8e49011d --- /dev/null +++ b/libc/nt/ntdll/RtlAbsoluteToSelfRelativeSD.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAbsoluteToSelfRelativeSD diff --git a/libc/nt/ntdll/RtlAcquirePebLock.s b/libc/nt/ntdll/RtlAcquirePebLock.s new file mode 100644 index 00000000..e0457525 --- /dev/null +++ b/libc/nt/ntdll/RtlAcquirePebLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAcquirePebLock diff --git a/libc/nt/ntdll/RtlAcquirePrivilege.s b/libc/nt/ntdll/RtlAcquirePrivilege.s new file mode 100644 index 00000000..fa1101c2 --- /dev/null +++ b/libc/nt/ntdll/RtlAcquirePrivilege.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAcquirePrivilege diff --git a/libc/nt/ntdll/RtlAcquireReleaseSRWLockExclusive.s b/libc/nt/ntdll/RtlAcquireReleaseSRWLockExclusive.s new file mode 100644 index 00000000..c3b9bb46 --- /dev/null +++ b/libc/nt/ntdll/RtlAcquireReleaseSRWLockExclusive.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAcquireReleaseSRWLockExclusive diff --git a/libc/nt/ntdll/RtlAcquireResourceExclusive.s b/libc/nt/ntdll/RtlAcquireResourceExclusive.s new file mode 100644 index 00000000..e83a2a42 --- /dev/null +++ b/libc/nt/ntdll/RtlAcquireResourceExclusive.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAcquireResourceExclusive diff --git a/libc/nt/ntdll/RtlAcquireResourceShared.s b/libc/nt/ntdll/RtlAcquireResourceShared.s new file mode 100644 index 00000000..a8868fa6 --- /dev/null +++ b/libc/nt/ntdll/RtlAcquireResourceShared.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAcquireResourceShared diff --git a/libc/nt/ntdll/RtlAcquireSRWLockExclusive.s b/libc/nt/ntdll/RtlAcquireSRWLockExclusive.s new file mode 100644 index 00000000..dd6456e9 --- /dev/null +++ b/libc/nt/ntdll/RtlAcquireSRWLockExclusive.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAcquireSRWLockExclusive diff --git a/libc/nt/ntdll/RtlAcquireSRWLockShared.s b/libc/nt/ntdll/RtlAcquireSRWLockShared.s new file mode 100644 index 00000000..3ce96f25 --- /dev/null +++ b/libc/nt/ntdll/RtlAcquireSRWLockShared.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAcquireSRWLockShared diff --git a/libc/nt/ntdll/RtlActivateActivationContext.s b/libc/nt/ntdll/RtlActivateActivationContext.s new file mode 100644 index 00000000..f4389b04 --- /dev/null +++ b/libc/nt/ntdll/RtlActivateActivationContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlActivateActivationContext diff --git a/libc/nt/ntdll/RtlActivateActivationContextEx.s b/libc/nt/ntdll/RtlActivateActivationContextEx.s new file mode 100644 index 00000000..ea2bea9a --- /dev/null +++ b/libc/nt/ntdll/RtlActivateActivationContextEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlActivateActivationContextEx diff --git a/libc/nt/ntdll/RtlActivateActivationContextUnsafeFast.s b/libc/nt/ntdll/RtlActivateActivationContextUnsafeFast.s new file mode 100644 index 00000000..9e610cfd --- /dev/null +++ b/libc/nt/ntdll/RtlActivateActivationContextUnsafeFast.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlActivateActivationContextUnsafeFast diff --git a/libc/nt/ntdll/RtlAddAccessAllowedAce.s b/libc/nt/ntdll/RtlAddAccessAllowedAce.s new file mode 100644 index 00000000..829a122b --- /dev/null +++ b/libc/nt/ntdll/RtlAddAccessAllowedAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddAccessAllowedAce diff --git a/libc/nt/ntdll/RtlAddAccessAllowedAceEx.s b/libc/nt/ntdll/RtlAddAccessAllowedAceEx.s new file mode 100644 index 00000000..82ebfc0f --- /dev/null +++ b/libc/nt/ntdll/RtlAddAccessAllowedAceEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddAccessAllowedAceEx diff --git a/libc/nt/ntdll/RtlAddAccessAllowedObjectAce.s b/libc/nt/ntdll/RtlAddAccessAllowedObjectAce.s new file mode 100644 index 00000000..338d6f90 --- /dev/null +++ b/libc/nt/ntdll/RtlAddAccessAllowedObjectAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddAccessAllowedObjectAce diff --git a/libc/nt/ntdll/RtlAddAccessDeniedAce.s b/libc/nt/ntdll/RtlAddAccessDeniedAce.s new file mode 100644 index 00000000..0cdf9667 --- /dev/null +++ b/libc/nt/ntdll/RtlAddAccessDeniedAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddAccessDeniedAce diff --git a/libc/nt/ntdll/RtlAddAccessDeniedAceEx.s b/libc/nt/ntdll/RtlAddAccessDeniedAceEx.s new file mode 100644 index 00000000..601c0051 --- /dev/null +++ b/libc/nt/ntdll/RtlAddAccessDeniedAceEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddAccessDeniedAceEx diff --git a/libc/nt/ntdll/RtlAddAccessDeniedObjectAce.s b/libc/nt/ntdll/RtlAddAccessDeniedObjectAce.s new file mode 100644 index 00000000..e5deedc8 --- /dev/null +++ b/libc/nt/ntdll/RtlAddAccessDeniedObjectAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddAccessDeniedObjectAce diff --git a/libc/nt/ntdll/RtlAddAccessFilterAce.s b/libc/nt/ntdll/RtlAddAccessFilterAce.s new file mode 100644 index 00000000..27150af8 --- /dev/null +++ b/libc/nt/ntdll/RtlAddAccessFilterAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddAccessFilterAce diff --git a/libc/nt/ntdll/RtlAddAce.s b/libc/nt/ntdll/RtlAddAce.s new file mode 100644 index 00000000..7a571df1 --- /dev/null +++ b/libc/nt/ntdll/RtlAddAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddAce diff --git a/libc/nt/ntdll/RtlAddActionToRXact.s b/libc/nt/ntdll/RtlAddActionToRXact.s new file mode 100644 index 00000000..bf56614e --- /dev/null +++ b/libc/nt/ntdll/RtlAddActionToRXact.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddActionToRXact diff --git a/libc/nt/ntdll/RtlAddAtomToAtomTable.s b/libc/nt/ntdll/RtlAddAtomToAtomTable.s new file mode 100644 index 00000000..2bf1e30a --- /dev/null +++ b/libc/nt/ntdll/RtlAddAtomToAtomTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddAtomToAtomTable diff --git a/libc/nt/ntdll/RtlAddAttributeActionToRXact.s b/libc/nt/ntdll/RtlAddAttributeActionToRXact.s new file mode 100644 index 00000000..feb90f2f --- /dev/null +++ b/libc/nt/ntdll/RtlAddAttributeActionToRXact.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddAttributeActionToRXact diff --git a/libc/nt/ntdll/RtlAddAuditAccessAce.s b/libc/nt/ntdll/RtlAddAuditAccessAce.s new file mode 100644 index 00000000..879212cf --- /dev/null +++ b/libc/nt/ntdll/RtlAddAuditAccessAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddAuditAccessAce diff --git a/libc/nt/ntdll/RtlAddAuditAccessAceEx.s b/libc/nt/ntdll/RtlAddAuditAccessAceEx.s new file mode 100644 index 00000000..0780a413 --- /dev/null +++ b/libc/nt/ntdll/RtlAddAuditAccessAceEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddAuditAccessAceEx diff --git a/libc/nt/ntdll/RtlAddAuditAccessObjectAce.s b/libc/nt/ntdll/RtlAddAuditAccessObjectAce.s new file mode 100644 index 00000000..d909ea1e --- /dev/null +++ b/libc/nt/ntdll/RtlAddAuditAccessObjectAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddAuditAccessObjectAce diff --git a/libc/nt/ntdll/RtlAddCompoundAce.s b/libc/nt/ntdll/RtlAddCompoundAce.s new file mode 100644 index 00000000..89a1aeba --- /dev/null +++ b/libc/nt/ntdll/RtlAddCompoundAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddCompoundAce diff --git a/libc/nt/ntdll/RtlAddFunctionTable.s b/libc/nt/ntdll/RtlAddFunctionTable.s new file mode 100644 index 00000000..2a06ce94 --- /dev/null +++ b/libc/nt/ntdll/RtlAddFunctionTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddFunctionTable diff --git a/libc/nt/ntdll/RtlAddGrowableFunctionTable.s b/libc/nt/ntdll/RtlAddGrowableFunctionTable.s new file mode 100644 index 00000000..50a4658d --- /dev/null +++ b/libc/nt/ntdll/RtlAddGrowableFunctionTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddGrowableFunctionTable diff --git a/libc/nt/ntdll/RtlAddIntegrityLabelToBoundaryDescriptor.s b/libc/nt/ntdll/RtlAddIntegrityLabelToBoundaryDescriptor.s new file mode 100644 index 00000000..8daf3cdf --- /dev/null +++ b/libc/nt/ntdll/RtlAddIntegrityLabelToBoundaryDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddIntegrityLabelToBoundaryDescriptor diff --git a/libc/nt/ntdll/RtlAddMandatoryAce.s b/libc/nt/ntdll/RtlAddMandatoryAce.s new file mode 100644 index 00000000..ae2bf0fb --- /dev/null +++ b/libc/nt/ntdll/RtlAddMandatoryAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddMandatoryAce diff --git a/libc/nt/ntdll/RtlAddProcessTrustLabelAce.s b/libc/nt/ntdll/RtlAddProcessTrustLabelAce.s new file mode 100644 index 00000000..a84a61c0 --- /dev/null +++ b/libc/nt/ntdll/RtlAddProcessTrustLabelAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddProcessTrustLabelAce diff --git a/libc/nt/ntdll/RtlAddRefActivationContext.s b/libc/nt/ntdll/RtlAddRefActivationContext.s new file mode 100644 index 00000000..ef376b97 --- /dev/null +++ b/libc/nt/ntdll/RtlAddRefActivationContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddRefActivationContext diff --git a/libc/nt/ntdll/RtlAddRefMemoryStream.s b/libc/nt/ntdll/RtlAddRefMemoryStream.s new file mode 100644 index 00000000..1af21805 --- /dev/null +++ b/libc/nt/ntdll/RtlAddRefMemoryStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddRefMemoryStream diff --git a/libc/nt/ntdll/RtlAddResourceAttributeAce.s b/libc/nt/ntdll/RtlAddResourceAttributeAce.s new file mode 100644 index 00000000..170dd278 --- /dev/null +++ b/libc/nt/ntdll/RtlAddResourceAttributeAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddResourceAttributeAce diff --git a/libc/nt/ntdll/RtlAddSIDToBoundaryDescriptor.s b/libc/nt/ntdll/RtlAddSIDToBoundaryDescriptor.s new file mode 100644 index 00000000..c9dbcd23 --- /dev/null +++ b/libc/nt/ntdll/RtlAddSIDToBoundaryDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddSIDToBoundaryDescriptor diff --git a/libc/nt/ntdll/RtlAddScopedPolicyIDAce.s b/libc/nt/ntdll/RtlAddScopedPolicyIDAce.s new file mode 100644 index 00000000..470c4820 --- /dev/null +++ b/libc/nt/ntdll/RtlAddScopedPolicyIDAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddScopedPolicyIDAce diff --git a/libc/nt/ntdll/RtlAddVectoredContinueHandler.s b/libc/nt/ntdll/RtlAddVectoredContinueHandler.s new file mode 100644 index 00000000..4d958798 --- /dev/null +++ b/libc/nt/ntdll/RtlAddVectoredContinueHandler.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddVectoredContinueHandler diff --git a/libc/nt/ntdll/RtlAddVectoredExceptionHandler.s b/libc/nt/ntdll/RtlAddVectoredExceptionHandler.s new file mode 100644 index 00000000..b675ff14 --- /dev/null +++ b/libc/nt/ntdll/RtlAddVectoredExceptionHandler.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddVectoredExceptionHandler diff --git a/libc/nt/ntdll/RtlAddressInSectionTable.s b/libc/nt/ntdll/RtlAddressInSectionTable.s new file mode 100644 index 00000000..a80fd81b --- /dev/null +++ b/libc/nt/ntdll/RtlAddressInSectionTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAddressInSectionTable diff --git a/libc/nt/ntdll/RtlAdjustPrivilege.s b/libc/nt/ntdll/RtlAdjustPrivilege.s new file mode 100644 index 00000000..5cb079a9 --- /dev/null +++ b/libc/nt/ntdll/RtlAdjustPrivilege.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAdjustPrivilege diff --git a/libc/nt/ntdll/RtlAllocateActivationContextStack.s b/libc/nt/ntdll/RtlAllocateActivationContextStack.s new file mode 100644 index 00000000..3e945e1d --- /dev/null +++ b/libc/nt/ntdll/RtlAllocateActivationContextStack.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAllocateActivationContextStack diff --git a/libc/nt/ntdll/RtlAllocateAndInitializeSid.s b/libc/nt/ntdll/RtlAllocateAndInitializeSid.s new file mode 100644 index 00000000..59455842 --- /dev/null +++ b/libc/nt/ntdll/RtlAllocateAndInitializeSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAllocateAndInitializeSid diff --git a/libc/nt/ntdll/RtlAllocateAndInitializeSidEx.s b/libc/nt/ntdll/RtlAllocateAndInitializeSidEx.s new file mode 100644 index 00000000..190e6862 --- /dev/null +++ b/libc/nt/ntdll/RtlAllocateAndInitializeSidEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAllocateAndInitializeSidEx diff --git a/libc/nt/ntdll/RtlAllocateHandle.s b/libc/nt/ntdll/RtlAllocateHandle.s new file mode 100644 index 00000000..73bd222e --- /dev/null +++ b/libc/nt/ntdll/RtlAllocateHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAllocateHandle diff --git a/libc/nt/ntdll/RtlAllocateHeap.s b/libc/nt/ntdll/RtlAllocateHeap.s new file mode 100644 index 00000000..f4ac9aca --- /dev/null +++ b/libc/nt/ntdll/RtlAllocateHeap.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAllocateHeap + + .text.windows +RtlAllocateHeap: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RtlAllocateHeap(%rip),%rax + jmp __sysv2nt + .endfn RtlAllocateHeap,globl + .previous diff --git a/libc/nt/ntdll/RtlAllocateMemoryBlockLookaside.s b/libc/nt/ntdll/RtlAllocateMemoryBlockLookaside.s new file mode 100644 index 00000000..88547429 --- /dev/null +++ b/libc/nt/ntdll/RtlAllocateMemoryBlockLookaside.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAllocateMemoryBlockLookaside diff --git a/libc/nt/ntdll/RtlAllocateMemoryZone.s b/libc/nt/ntdll/RtlAllocateMemoryZone.s new file mode 100644 index 00000000..7584cd85 --- /dev/null +++ b/libc/nt/ntdll/RtlAllocateMemoryZone.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAllocateMemoryZone diff --git a/libc/nt/ntdll/RtlAllocateWnfSerializationGroup.s b/libc/nt/ntdll/RtlAllocateWnfSerializationGroup.s new file mode 100644 index 00000000..b303a415 --- /dev/null +++ b/libc/nt/ntdll/RtlAllocateWnfSerializationGroup.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAllocateWnfSerializationGroup diff --git a/libc/nt/ntdll/RtlAnsiCharToUnicodeChar.s b/libc/nt/ntdll/RtlAnsiCharToUnicodeChar.s new file mode 100644 index 00000000..d346cfa1 --- /dev/null +++ b/libc/nt/ntdll/RtlAnsiCharToUnicodeChar.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAnsiCharToUnicodeChar diff --git a/libc/nt/ntdll/RtlAnsiStringToUnicodeSize.s b/libc/nt/ntdll/RtlAnsiStringToUnicodeSize.s new file mode 100644 index 00000000..080dd33f --- /dev/null +++ b/libc/nt/ntdll/RtlAnsiStringToUnicodeSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAnsiStringToUnicodeSize diff --git a/libc/nt/ntdll/RtlAnsiStringToUnicodeString.s b/libc/nt/ntdll/RtlAnsiStringToUnicodeString.s new file mode 100644 index 00000000..e1b30ec7 --- /dev/null +++ b/libc/nt/ntdll/RtlAnsiStringToUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAnsiStringToUnicodeString diff --git a/libc/nt/ntdll/RtlAppendAsciizToString.s b/libc/nt/ntdll/RtlAppendAsciizToString.s new file mode 100644 index 00000000..7bdfd848 --- /dev/null +++ b/libc/nt/ntdll/RtlAppendAsciizToString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAppendAsciizToString diff --git a/libc/nt/ntdll/RtlAppendPathElement.s b/libc/nt/ntdll/RtlAppendPathElement.s new file mode 100644 index 00000000..f7a73be8 --- /dev/null +++ b/libc/nt/ntdll/RtlAppendPathElement.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAppendPathElement diff --git a/libc/nt/ntdll/RtlAppendStringToString.s b/libc/nt/ntdll/RtlAppendStringToString.s new file mode 100644 index 00000000..001d5245 --- /dev/null +++ b/libc/nt/ntdll/RtlAppendStringToString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAppendStringToString diff --git a/libc/nt/ntdll/RtlAppendUnicodeStringToString.s b/libc/nt/ntdll/RtlAppendUnicodeStringToString.s new file mode 100644 index 00000000..82dba2ee --- /dev/null +++ b/libc/nt/ntdll/RtlAppendUnicodeStringToString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAppendUnicodeStringToString diff --git a/libc/nt/ntdll/RtlAppendUnicodeToString.s b/libc/nt/ntdll/RtlAppendUnicodeToString.s new file mode 100644 index 00000000..74b0b0a6 --- /dev/null +++ b/libc/nt/ntdll/RtlAppendUnicodeToString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAppendUnicodeToString diff --git a/libc/nt/ntdll/RtlApplicationVerifierStop.s b/libc/nt/ntdll/RtlApplicationVerifierStop.s new file mode 100644 index 00000000..6cd7e31e --- /dev/null +++ b/libc/nt/ntdll/RtlApplicationVerifierStop.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlApplicationVerifierStop diff --git a/libc/nt/ntdll/RtlApplyRXact.s b/libc/nt/ntdll/RtlApplyRXact.s new file mode 100644 index 00000000..3864c0bd --- /dev/null +++ b/libc/nt/ntdll/RtlApplyRXact.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlApplyRXact diff --git a/libc/nt/ntdll/RtlApplyRXactNoFlush.s b/libc/nt/ntdll/RtlApplyRXactNoFlush.s new file mode 100644 index 00000000..1be0bcba --- /dev/null +++ b/libc/nt/ntdll/RtlApplyRXactNoFlush.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlApplyRXactNoFlush diff --git a/libc/nt/ntdll/RtlAppxIsFileOwnedByTrustedInstaller.s b/libc/nt/ntdll/RtlAppxIsFileOwnedByTrustedInstaller.s new file mode 100644 index 00000000..704365d0 --- /dev/null +++ b/libc/nt/ntdll/RtlAppxIsFileOwnedByTrustedInstaller.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAppxIsFileOwnedByTrustedInstaller diff --git a/libc/nt/ntdll/RtlAreAllAccessesGranted.s b/libc/nt/ntdll/RtlAreAllAccessesGranted.s new file mode 100644 index 00000000..f611cef7 --- /dev/null +++ b/libc/nt/ntdll/RtlAreAllAccessesGranted.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAreAllAccessesGranted diff --git a/libc/nt/ntdll/RtlAreAnyAccessesGranted.s b/libc/nt/ntdll/RtlAreAnyAccessesGranted.s new file mode 100644 index 00000000..6c85d664 --- /dev/null +++ b/libc/nt/ntdll/RtlAreAnyAccessesGranted.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAreAnyAccessesGranted diff --git a/libc/nt/ntdll/RtlAreBitsClear.s b/libc/nt/ntdll/RtlAreBitsClear.s new file mode 100644 index 00000000..7fdd011e --- /dev/null +++ b/libc/nt/ntdll/RtlAreBitsClear.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAreBitsClear diff --git a/libc/nt/ntdll/RtlAreBitsSet.s b/libc/nt/ntdll/RtlAreBitsSet.s new file mode 100644 index 00000000..5ae4ba7e --- /dev/null +++ b/libc/nt/ntdll/RtlAreBitsSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAreBitsSet diff --git a/libc/nt/ntdll/RtlAreLongPathsEnabled.s b/libc/nt/ntdll/RtlAreLongPathsEnabled.s new file mode 100644 index 00000000..1ae443d1 --- /dev/null +++ b/libc/nt/ntdll/RtlAreLongPathsEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAreLongPathsEnabled diff --git a/libc/nt/ntdll/RtlAssert.s b/libc/nt/ntdll/RtlAssert.s new file mode 100644 index 00000000..5552a1ae --- /dev/null +++ b/libc/nt/ntdll/RtlAssert.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAssert diff --git a/libc/nt/ntdll/RtlAvlInsertNodeEx.s b/libc/nt/ntdll/RtlAvlInsertNodeEx.s new file mode 100644 index 00000000..19e498c4 --- /dev/null +++ b/libc/nt/ntdll/RtlAvlInsertNodeEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAvlInsertNodeEx diff --git a/libc/nt/ntdll/RtlAvlRemoveNode.s b/libc/nt/ntdll/RtlAvlRemoveNode.s new file mode 100644 index 00000000..9dbdbf03 --- /dev/null +++ b/libc/nt/ntdll/RtlAvlRemoveNode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlAvlRemoveNode diff --git a/libc/nt/ntdll/RtlBarrier.s b/libc/nt/ntdll/RtlBarrier.s new file mode 100644 index 00000000..7bdda71a --- /dev/null +++ b/libc/nt/ntdll/RtlBarrier.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlBarrier diff --git a/libc/nt/ntdll/RtlBarrierForDelete.s b/libc/nt/ntdll/RtlBarrierForDelete.s new file mode 100644 index 00000000..ba6154c0 --- /dev/null +++ b/libc/nt/ntdll/RtlBarrierForDelete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlBarrierForDelete diff --git a/libc/nt/ntdll/RtlCallEnclaveReturn.s b/libc/nt/ntdll/RtlCallEnclaveReturn.s new file mode 100644 index 00000000..c14f1487 --- /dev/null +++ b/libc/nt/ntdll/RtlCallEnclaveReturn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCallEnclaveReturn diff --git a/libc/nt/ntdll/RtlCancelTimer.s b/libc/nt/ntdll/RtlCancelTimer.s new file mode 100644 index 00000000..af3fc5c3 --- /dev/null +++ b/libc/nt/ntdll/RtlCancelTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCancelTimer diff --git a/libc/nt/ntdll/RtlCanonicalizeDomainName.s b/libc/nt/ntdll/RtlCanonicalizeDomainName.s new file mode 100644 index 00000000..b44d4fdf --- /dev/null +++ b/libc/nt/ntdll/RtlCanonicalizeDomainName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCanonicalizeDomainName diff --git a/libc/nt/ntdll/RtlCapabilityCheck.s b/libc/nt/ntdll/RtlCapabilityCheck.s new file mode 100644 index 00000000..2f4bc0ab --- /dev/null +++ b/libc/nt/ntdll/RtlCapabilityCheck.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCapabilityCheck diff --git a/libc/nt/ntdll/RtlCapabilityCheckForSingleSessionSku.s b/libc/nt/ntdll/RtlCapabilityCheckForSingleSessionSku.s new file mode 100644 index 00000000..1b397573 --- /dev/null +++ b/libc/nt/ntdll/RtlCapabilityCheckForSingleSessionSku.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCapabilityCheckForSingleSessionSku diff --git a/libc/nt/ntdll/RtlCaptureContext.s b/libc/nt/ntdll/RtlCaptureContext.s new file mode 100644 index 00000000..5689265f --- /dev/null +++ b/libc/nt/ntdll/RtlCaptureContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCaptureContext diff --git a/libc/nt/ntdll/RtlCaptureStackBackTrace.s b/libc/nt/ntdll/RtlCaptureStackBackTrace.s new file mode 100644 index 00000000..43629f5f --- /dev/null +++ b/libc/nt/ntdll/RtlCaptureStackBackTrace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCaptureStackBackTrace diff --git a/libc/nt/ntdll/RtlCharToInteger.s b/libc/nt/ntdll/RtlCharToInteger.s new file mode 100644 index 00000000..49dfa1a5 --- /dev/null +++ b/libc/nt/ntdll/RtlCharToInteger.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCharToInteger diff --git a/libc/nt/ntdll/RtlCheckBootStatusIntegrity.s b/libc/nt/ntdll/RtlCheckBootStatusIntegrity.s new file mode 100644 index 00000000..ed896575 --- /dev/null +++ b/libc/nt/ntdll/RtlCheckBootStatusIntegrity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCheckBootStatusIntegrity diff --git a/libc/nt/ntdll/RtlCheckForOrphanedCriticalSections.s b/libc/nt/ntdll/RtlCheckForOrphanedCriticalSections.s new file mode 100644 index 00000000..97ec0681 --- /dev/null +++ b/libc/nt/ntdll/RtlCheckForOrphanedCriticalSections.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCheckForOrphanedCriticalSections diff --git a/libc/nt/ntdll/RtlCheckPortableOperatingSystem.s b/libc/nt/ntdll/RtlCheckPortableOperatingSystem.s new file mode 100644 index 00000000..c3905e58 --- /dev/null +++ b/libc/nt/ntdll/RtlCheckPortableOperatingSystem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCheckPortableOperatingSystem diff --git a/libc/nt/ntdll/RtlCheckRegistryKey.s b/libc/nt/ntdll/RtlCheckRegistryKey.s new file mode 100644 index 00000000..b70245bf --- /dev/null +++ b/libc/nt/ntdll/RtlCheckRegistryKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCheckRegistryKey diff --git a/libc/nt/ntdll/RtlCheckSandboxedToken.s b/libc/nt/ntdll/RtlCheckSandboxedToken.s new file mode 100644 index 00000000..ae5cf1c0 --- /dev/null +++ b/libc/nt/ntdll/RtlCheckSandboxedToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCheckSandboxedToken diff --git a/libc/nt/ntdll/RtlCheckSystemBootStatusIntegrity.s b/libc/nt/ntdll/RtlCheckSystemBootStatusIntegrity.s new file mode 100644 index 00000000..9c751626 --- /dev/null +++ b/libc/nt/ntdll/RtlCheckSystemBootStatusIntegrity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCheckSystemBootStatusIntegrity diff --git a/libc/nt/ntdll/RtlCheckTokenCapability.s b/libc/nt/ntdll/RtlCheckTokenCapability.s new file mode 100644 index 00000000..864d8e7a --- /dev/null +++ b/libc/nt/ntdll/RtlCheckTokenCapability.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCheckTokenCapability diff --git a/libc/nt/ntdll/RtlCheckTokenMembership.s b/libc/nt/ntdll/RtlCheckTokenMembership.s new file mode 100644 index 00000000..e8267764 --- /dev/null +++ b/libc/nt/ntdll/RtlCheckTokenMembership.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCheckTokenMembership diff --git a/libc/nt/ntdll/RtlCheckTokenMembershipEx.s b/libc/nt/ntdll/RtlCheckTokenMembershipEx.s new file mode 100644 index 00000000..0a447ae8 --- /dev/null +++ b/libc/nt/ntdll/RtlCheckTokenMembershipEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCheckTokenMembershipEx diff --git a/libc/nt/ntdll/RtlCleanUpTEBLangLists.s b/libc/nt/ntdll/RtlCleanUpTEBLangLists.s new file mode 100644 index 00000000..44c58aa2 --- /dev/null +++ b/libc/nt/ntdll/RtlCleanUpTEBLangLists.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCleanUpTEBLangLists diff --git a/libc/nt/ntdll/RtlClearAllBits.s b/libc/nt/ntdll/RtlClearAllBits.s new file mode 100644 index 00000000..acde925a --- /dev/null +++ b/libc/nt/ntdll/RtlClearAllBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlClearAllBits diff --git a/libc/nt/ntdll/RtlClearBit.s b/libc/nt/ntdll/RtlClearBit.s new file mode 100644 index 00000000..258311e2 --- /dev/null +++ b/libc/nt/ntdll/RtlClearBit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlClearBit diff --git a/libc/nt/ntdll/RtlClearBits.s b/libc/nt/ntdll/RtlClearBits.s new file mode 100644 index 00000000..0c7c740f --- /dev/null +++ b/libc/nt/ntdll/RtlClearBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlClearBits diff --git a/libc/nt/ntdll/RtlClearThreadWorkOnBehalfTicket.s b/libc/nt/ntdll/RtlClearThreadWorkOnBehalfTicket.s new file mode 100644 index 00000000..10e58a3b --- /dev/null +++ b/libc/nt/ntdll/RtlClearThreadWorkOnBehalfTicket.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlClearThreadWorkOnBehalfTicket diff --git a/libc/nt/ntdll/RtlCloneMemoryStream.s b/libc/nt/ntdll/RtlCloneMemoryStream.s new file mode 100644 index 00000000..1570cfbb --- /dev/null +++ b/libc/nt/ntdll/RtlCloneMemoryStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCloneMemoryStream diff --git a/libc/nt/ntdll/RtlCloneUserProcess.s b/libc/nt/ntdll/RtlCloneUserProcess.s new file mode 100644 index 00000000..296ddc8b --- /dev/null +++ b/libc/nt/ntdll/RtlCloneUserProcess.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCloneUserProcess + + .text.windows +RtlCloneUserProcess: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RtlCloneUserProcess(%rip),%rax + jmp __sysv2nt6 + .endfn RtlCloneUserProcess,globl + .previous diff --git a/libc/nt/ntdll/RtlCmDecodeMemIoResource.s b/libc/nt/ntdll/RtlCmDecodeMemIoResource.s new file mode 100644 index 00000000..ced097d0 --- /dev/null +++ b/libc/nt/ntdll/RtlCmDecodeMemIoResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCmDecodeMemIoResource diff --git a/libc/nt/ntdll/RtlCmEncodeMemIoResource.s b/libc/nt/ntdll/RtlCmEncodeMemIoResource.s new file mode 100644 index 00000000..d0f753c0 --- /dev/null +++ b/libc/nt/ntdll/RtlCmEncodeMemIoResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCmEncodeMemIoResource diff --git a/libc/nt/ntdll/RtlCommitDebugInfo.s b/libc/nt/ntdll/RtlCommitDebugInfo.s new file mode 100644 index 00000000..acf2d2cf --- /dev/null +++ b/libc/nt/ntdll/RtlCommitDebugInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCommitDebugInfo diff --git a/libc/nt/ntdll/RtlCommitMemoryStream.s b/libc/nt/ntdll/RtlCommitMemoryStream.s new file mode 100644 index 00000000..1d50fb3a --- /dev/null +++ b/libc/nt/ntdll/RtlCommitMemoryStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCommitMemoryStream diff --git a/libc/nt/ntdll/RtlCompactHeap.s b/libc/nt/ntdll/RtlCompactHeap.s new file mode 100644 index 00000000..8b66fe24 --- /dev/null +++ b/libc/nt/ntdll/RtlCompactHeap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCompactHeap diff --git a/libc/nt/ntdll/RtlCompareAltitudes.s b/libc/nt/ntdll/RtlCompareAltitudes.s new file mode 100644 index 00000000..c7b28ef9 --- /dev/null +++ b/libc/nt/ntdll/RtlCompareAltitudes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCompareAltitudes diff --git a/libc/nt/ntdll/RtlCompareMemory.s b/libc/nt/ntdll/RtlCompareMemory.s new file mode 100644 index 00000000..718633ae --- /dev/null +++ b/libc/nt/ntdll/RtlCompareMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCompareMemory diff --git a/libc/nt/ntdll/RtlCompareMemoryUlong.s b/libc/nt/ntdll/RtlCompareMemoryUlong.s new file mode 100644 index 00000000..85f63514 --- /dev/null +++ b/libc/nt/ntdll/RtlCompareMemoryUlong.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCompareMemoryUlong diff --git a/libc/nt/ntdll/RtlCompareString.s b/libc/nt/ntdll/RtlCompareString.s new file mode 100644 index 00000000..5f5faee5 --- /dev/null +++ b/libc/nt/ntdll/RtlCompareString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCompareString diff --git a/libc/nt/ntdll/RtlCompareUnicodeString.s b/libc/nt/ntdll/RtlCompareUnicodeString.s new file mode 100644 index 00000000..683f285d --- /dev/null +++ b/libc/nt/ntdll/RtlCompareUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCompareUnicodeString diff --git a/libc/nt/ntdll/RtlCompareUnicodeStrings.s b/libc/nt/ntdll/RtlCompareUnicodeStrings.s new file mode 100644 index 00000000..36291bdb --- /dev/null +++ b/libc/nt/ntdll/RtlCompareUnicodeStrings.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCompareUnicodeStrings diff --git a/libc/nt/ntdll/RtlCompleteProcessCloning.s b/libc/nt/ntdll/RtlCompleteProcessCloning.s new file mode 100644 index 00000000..25ff19ce --- /dev/null +++ b/libc/nt/ntdll/RtlCompleteProcessCloning.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCompleteProcessCloning diff --git a/libc/nt/ntdll/RtlCompressBuffer.s b/libc/nt/ntdll/RtlCompressBuffer.s new file mode 100644 index 00000000..07029afb --- /dev/null +++ b/libc/nt/ntdll/RtlCompressBuffer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCompressBuffer diff --git a/libc/nt/ntdll/RtlComputeCrc32.s b/libc/nt/ntdll/RtlComputeCrc32.s new file mode 100644 index 00000000..40f8ef11 --- /dev/null +++ b/libc/nt/ntdll/RtlComputeCrc32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlComputeCrc32 diff --git a/libc/nt/ntdll/RtlComputeImportTableHash.s b/libc/nt/ntdll/RtlComputeImportTableHash.s new file mode 100644 index 00000000..c27217fb --- /dev/null +++ b/libc/nt/ntdll/RtlComputeImportTableHash.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlComputeImportTableHash diff --git a/libc/nt/ntdll/RtlComputePrivatizedDllName_U.s b/libc/nt/ntdll/RtlComputePrivatizedDllName_U.s new file mode 100644 index 00000000..b3f25577 --- /dev/null +++ b/libc/nt/ntdll/RtlComputePrivatizedDllName_U.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlComputePrivatizedDllName_U diff --git a/libc/nt/ntdll/RtlConnectToSm.s b/libc/nt/ntdll/RtlConnectToSm.s new file mode 100644 index 00000000..90cb7bcc --- /dev/null +++ b/libc/nt/ntdll/RtlConnectToSm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlConnectToSm diff --git a/libc/nt/ntdll/RtlConsoleMultiByteToUnicodeN.s b/libc/nt/ntdll/RtlConsoleMultiByteToUnicodeN.s new file mode 100644 index 00000000..382f16c6 --- /dev/null +++ b/libc/nt/ntdll/RtlConsoleMultiByteToUnicodeN.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlConsoleMultiByteToUnicodeN diff --git a/libc/nt/ntdll/RtlContractHashTable.s b/libc/nt/ntdll/RtlContractHashTable.s new file mode 100644 index 00000000..44ef26a3 --- /dev/null +++ b/libc/nt/ntdll/RtlContractHashTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlContractHashTable diff --git a/libc/nt/ntdll/RtlConvertDeviceFamilyInfoToString.s b/libc/nt/ntdll/RtlConvertDeviceFamilyInfoToString.s new file mode 100644 index 00000000..e8e0c0ff --- /dev/null +++ b/libc/nt/ntdll/RtlConvertDeviceFamilyInfoToString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlConvertDeviceFamilyInfoToString diff --git a/libc/nt/ntdll/RtlConvertExclusiveToShared.s b/libc/nt/ntdll/RtlConvertExclusiveToShared.s new file mode 100644 index 00000000..5b773a4a --- /dev/null +++ b/libc/nt/ntdll/RtlConvertExclusiveToShared.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlConvertExclusiveToShared diff --git a/libc/nt/ntdll/RtlConvertLCIDToString.s b/libc/nt/ntdll/RtlConvertLCIDToString.s new file mode 100644 index 00000000..d268f41f --- /dev/null +++ b/libc/nt/ntdll/RtlConvertLCIDToString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlConvertLCIDToString diff --git a/libc/nt/ntdll/RtlConvertSRWLockExclusiveToShared.s b/libc/nt/ntdll/RtlConvertSRWLockExclusiveToShared.s new file mode 100644 index 00000000..9eb382f6 --- /dev/null +++ b/libc/nt/ntdll/RtlConvertSRWLockExclusiveToShared.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlConvertSRWLockExclusiveToShared diff --git a/libc/nt/ntdll/RtlConvertSharedToExclusive.s b/libc/nt/ntdll/RtlConvertSharedToExclusive.s new file mode 100644 index 00000000..50d2d0a1 --- /dev/null +++ b/libc/nt/ntdll/RtlConvertSharedToExclusive.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlConvertSharedToExclusive diff --git a/libc/nt/ntdll/RtlConvertSidToUnicodeString.s b/libc/nt/ntdll/RtlConvertSidToUnicodeString.s new file mode 100644 index 00000000..dd14c052 --- /dev/null +++ b/libc/nt/ntdll/RtlConvertSidToUnicodeString.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlConvertSidToUnicodeString + + .text.windows +RtlConvertSidToUnicodeString: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RtlConvertSidToUnicodeString(%rip),%rax + jmp __sysv2nt + .endfn RtlConvertSidToUnicodeString,globl + .previous diff --git a/libc/nt/ntdll/RtlConvertToAutoInheritSecurityObject.s b/libc/nt/ntdll/RtlConvertToAutoInheritSecurityObject.s new file mode 100644 index 00000000..55fa3379 --- /dev/null +++ b/libc/nt/ntdll/RtlConvertToAutoInheritSecurityObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlConvertToAutoInheritSecurityObject diff --git a/libc/nt/ntdll/RtlCopyBitMap.s b/libc/nt/ntdll/RtlCopyBitMap.s new file mode 100644 index 00000000..6339e551 --- /dev/null +++ b/libc/nt/ntdll/RtlCopyBitMap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCopyBitMap diff --git a/libc/nt/ntdll/RtlCopyContext.s b/libc/nt/ntdll/RtlCopyContext.s new file mode 100644 index 00000000..827a36ec --- /dev/null +++ b/libc/nt/ntdll/RtlCopyContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCopyContext diff --git a/libc/nt/ntdll/RtlCopyExtendedContext.s b/libc/nt/ntdll/RtlCopyExtendedContext.s new file mode 100644 index 00000000..297b5055 --- /dev/null +++ b/libc/nt/ntdll/RtlCopyExtendedContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCopyExtendedContext diff --git a/libc/nt/ntdll/RtlCopyLuid.s b/libc/nt/ntdll/RtlCopyLuid.s new file mode 100644 index 00000000..87a7a1ce --- /dev/null +++ b/libc/nt/ntdll/RtlCopyLuid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCopyLuid diff --git a/libc/nt/ntdll/RtlCopyLuidAndAttributesArray.s b/libc/nt/ntdll/RtlCopyLuidAndAttributesArray.s new file mode 100644 index 00000000..2c78f231 --- /dev/null +++ b/libc/nt/ntdll/RtlCopyLuidAndAttributesArray.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCopyLuidAndAttributesArray diff --git a/libc/nt/ntdll/RtlCopyMappedMemory.s b/libc/nt/ntdll/RtlCopyMappedMemory.s new file mode 100644 index 00000000..60c62c16 --- /dev/null +++ b/libc/nt/ntdll/RtlCopyMappedMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCopyMappedMemory diff --git a/libc/nt/ntdll/RtlCopyMemory.s b/libc/nt/ntdll/RtlCopyMemory.s new file mode 100644 index 00000000..a1cf0a61 --- /dev/null +++ b/libc/nt/ntdll/RtlCopyMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCopyMemory diff --git a/libc/nt/ntdll/RtlCopyMemoryNonTemporal.s b/libc/nt/ntdll/RtlCopyMemoryNonTemporal.s new file mode 100644 index 00000000..169ea8aa --- /dev/null +++ b/libc/nt/ntdll/RtlCopyMemoryNonTemporal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCopyMemoryNonTemporal diff --git a/libc/nt/ntdll/RtlCopyMemoryStreamTo.s b/libc/nt/ntdll/RtlCopyMemoryStreamTo.s new file mode 100644 index 00000000..fd84250a --- /dev/null +++ b/libc/nt/ntdll/RtlCopyMemoryStreamTo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCopyMemoryStreamTo diff --git a/libc/nt/ntdll/RtlCopyOutOfProcessMemoryStreamTo.s b/libc/nt/ntdll/RtlCopyOutOfProcessMemoryStreamTo.s new file mode 100644 index 00000000..17270de8 --- /dev/null +++ b/libc/nt/ntdll/RtlCopyOutOfProcessMemoryStreamTo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCopyOutOfProcessMemoryStreamTo diff --git a/libc/nt/ntdll/RtlCopySecurityDescriptor.s b/libc/nt/ntdll/RtlCopySecurityDescriptor.s new file mode 100644 index 00000000..e10d1af1 --- /dev/null +++ b/libc/nt/ntdll/RtlCopySecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCopySecurityDescriptor diff --git a/libc/nt/ntdll/RtlCopySid.s b/libc/nt/ntdll/RtlCopySid.s new file mode 100644 index 00000000..a7b6eabf --- /dev/null +++ b/libc/nt/ntdll/RtlCopySid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCopySid diff --git a/libc/nt/ntdll/RtlCopySidAndAttributesArray.s b/libc/nt/ntdll/RtlCopySidAndAttributesArray.s new file mode 100644 index 00000000..c1109fee --- /dev/null +++ b/libc/nt/ntdll/RtlCopySidAndAttributesArray.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCopySidAndAttributesArray diff --git a/libc/nt/ntdll/RtlCopyString.s b/libc/nt/ntdll/RtlCopyString.s new file mode 100644 index 00000000..e3072470 --- /dev/null +++ b/libc/nt/ntdll/RtlCopyString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCopyString diff --git a/libc/nt/ntdll/RtlCopyUnicodeString.s b/libc/nt/ntdll/RtlCopyUnicodeString.s new file mode 100644 index 00000000..5280b761 --- /dev/null +++ b/libc/nt/ntdll/RtlCopyUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCopyUnicodeString diff --git a/libc/nt/ntdll/RtlCrc32.s b/libc/nt/ntdll/RtlCrc32.s new file mode 100644 index 00000000..6ec3b33a --- /dev/null +++ b/libc/nt/ntdll/RtlCrc32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCrc32 diff --git a/libc/nt/ntdll/RtlCrc64.s b/libc/nt/ntdll/RtlCrc64.s new file mode 100644 index 00000000..44f38104 --- /dev/null +++ b/libc/nt/ntdll/RtlCrc64.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCrc64 diff --git a/libc/nt/ntdll/RtlCreateAcl.s b/libc/nt/ntdll/RtlCreateAcl.s new file mode 100644 index 00000000..c785be35 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateAcl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateAcl diff --git a/libc/nt/ntdll/RtlCreateActivationContext.s b/libc/nt/ntdll/RtlCreateActivationContext.s new file mode 100644 index 00000000..4b5c7c6c --- /dev/null +++ b/libc/nt/ntdll/RtlCreateActivationContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateActivationContext diff --git a/libc/nt/ntdll/RtlCreateAndSetSD.s b/libc/nt/ntdll/RtlCreateAndSetSD.s new file mode 100644 index 00000000..7ff5a29a --- /dev/null +++ b/libc/nt/ntdll/RtlCreateAndSetSD.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateAndSetSD diff --git a/libc/nt/ntdll/RtlCreateAtomTable.s b/libc/nt/ntdll/RtlCreateAtomTable.s new file mode 100644 index 00000000..9b86a0eb --- /dev/null +++ b/libc/nt/ntdll/RtlCreateAtomTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateAtomTable diff --git a/libc/nt/ntdll/RtlCreateBootStatusDataFile.s b/libc/nt/ntdll/RtlCreateBootStatusDataFile.s new file mode 100644 index 00000000..41d8ce88 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateBootStatusDataFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateBootStatusDataFile diff --git a/libc/nt/ntdll/RtlCreateBoundaryDescriptor.s b/libc/nt/ntdll/RtlCreateBoundaryDescriptor.s new file mode 100644 index 00000000..c661111a --- /dev/null +++ b/libc/nt/ntdll/RtlCreateBoundaryDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateBoundaryDescriptor diff --git a/libc/nt/ntdll/RtlCreateEnvironment.s b/libc/nt/ntdll/RtlCreateEnvironment.s new file mode 100644 index 00000000..91939557 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateEnvironment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateEnvironment diff --git a/libc/nt/ntdll/RtlCreateEnvironmentEx.s b/libc/nt/ntdll/RtlCreateEnvironmentEx.s new file mode 100644 index 00000000..64c4da66 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateEnvironmentEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateEnvironmentEx diff --git a/libc/nt/ntdll/RtlCreateHashTable.s b/libc/nt/ntdll/RtlCreateHashTable.s new file mode 100644 index 00000000..b1de90b5 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateHashTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateHashTable diff --git a/libc/nt/ntdll/RtlCreateHashTableEx.s b/libc/nt/ntdll/RtlCreateHashTableEx.s new file mode 100644 index 00000000..0e007a88 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateHashTableEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateHashTableEx diff --git a/libc/nt/ntdll/RtlCreateHeap.s b/libc/nt/ntdll/RtlCreateHeap.s new file mode 100644 index 00000000..9428478a --- /dev/null +++ b/libc/nt/ntdll/RtlCreateHeap.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateHeap + + .text.windows +RtlCreateHeap: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RtlCreateHeap(%rip),%rax + jmp __sysv2nt6 + .endfn RtlCreateHeap,globl + .previous diff --git a/libc/nt/ntdll/RtlCreateMemoryBlockLookaside.s b/libc/nt/ntdll/RtlCreateMemoryBlockLookaside.s new file mode 100644 index 00000000..badc3913 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateMemoryBlockLookaside.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateMemoryBlockLookaside diff --git a/libc/nt/ntdll/RtlCreateMemoryZone.s b/libc/nt/ntdll/RtlCreateMemoryZone.s new file mode 100644 index 00000000..7111e189 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateMemoryZone.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateMemoryZone diff --git a/libc/nt/ntdll/RtlCreateProcessParameters.s b/libc/nt/ntdll/RtlCreateProcessParameters.s new file mode 100644 index 00000000..19a23d4e --- /dev/null +++ b/libc/nt/ntdll/RtlCreateProcessParameters.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateProcessParameters + + .text.windows +RtlCreateProcessParameters: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RtlCreateProcessParameters(%rip),%rax + jmp __sysv2nt10 + .endfn RtlCreateProcessParameters,globl + .previous diff --git a/libc/nt/ntdll/RtlCreateProcessParametersEx.s b/libc/nt/ntdll/RtlCreateProcessParametersEx.s new file mode 100644 index 00000000..1fa7b3cd --- /dev/null +++ b/libc/nt/ntdll/RtlCreateProcessParametersEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateProcessParametersEx diff --git a/libc/nt/ntdll/RtlCreateProcessReflection.s b/libc/nt/ntdll/RtlCreateProcessReflection.s new file mode 100644 index 00000000..3985c4b3 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateProcessReflection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateProcessReflection diff --git a/libc/nt/ntdll/RtlCreateQueryDebugBuffer.s b/libc/nt/ntdll/RtlCreateQueryDebugBuffer.s new file mode 100644 index 00000000..b84453fd --- /dev/null +++ b/libc/nt/ntdll/RtlCreateQueryDebugBuffer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateQueryDebugBuffer diff --git a/libc/nt/ntdll/RtlCreateRegistryKey.s b/libc/nt/ntdll/RtlCreateRegistryKey.s new file mode 100644 index 00000000..b7ddbb70 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateRegistryKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateRegistryKey diff --git a/libc/nt/ntdll/RtlCreateSecurityDescriptor.s b/libc/nt/ntdll/RtlCreateSecurityDescriptor.s new file mode 100644 index 00000000..1528d266 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateSecurityDescriptor diff --git a/libc/nt/ntdll/RtlCreateServiceSid.s b/libc/nt/ntdll/RtlCreateServiceSid.s new file mode 100644 index 00000000..e95bebf9 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateServiceSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateServiceSid diff --git a/libc/nt/ntdll/RtlCreateSystemVolumeInformationFolder.s b/libc/nt/ntdll/RtlCreateSystemVolumeInformationFolder.s new file mode 100644 index 00000000..b1bcf753 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateSystemVolumeInformationFolder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateSystemVolumeInformationFolder diff --git a/libc/nt/ntdll/RtlCreateTagHeap.s b/libc/nt/ntdll/RtlCreateTagHeap.s new file mode 100644 index 00000000..cfaec4af --- /dev/null +++ b/libc/nt/ntdll/RtlCreateTagHeap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateTagHeap diff --git a/libc/nt/ntdll/RtlCreateTimer.s b/libc/nt/ntdll/RtlCreateTimer.s new file mode 100644 index 00000000..e97621a5 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateTimer diff --git a/libc/nt/ntdll/RtlCreateTimerQueue.s b/libc/nt/ntdll/RtlCreateTimerQueue.s new file mode 100644 index 00000000..1b202f64 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateTimerQueue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateTimerQueue diff --git a/libc/nt/ntdll/RtlCreateUmsCompletionList.s b/libc/nt/ntdll/RtlCreateUmsCompletionList.s new file mode 100644 index 00000000..65b1ce2e --- /dev/null +++ b/libc/nt/ntdll/RtlCreateUmsCompletionList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateUmsCompletionList diff --git a/libc/nt/ntdll/RtlCreateUmsThreadContext.s b/libc/nt/ntdll/RtlCreateUmsThreadContext.s new file mode 100644 index 00000000..bea85d36 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateUmsThreadContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateUmsThreadContext diff --git a/libc/nt/ntdll/RtlCreateUnicodeString.s b/libc/nt/ntdll/RtlCreateUnicodeString.s new file mode 100644 index 00000000..243f0596 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateUnicodeString diff --git a/libc/nt/ntdll/RtlCreateUnicodeStringFromAsciiz.s b/libc/nt/ntdll/RtlCreateUnicodeStringFromAsciiz.s new file mode 100644 index 00000000..89834ea6 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateUnicodeStringFromAsciiz.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateUnicodeStringFromAsciiz diff --git a/libc/nt/ntdll/RtlCreateUserProcess.s b/libc/nt/ntdll/RtlCreateUserProcess.s new file mode 100644 index 00000000..0cbedca1 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateUserProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateUserProcess diff --git a/libc/nt/ntdll/RtlCreateUserProcessEx.s b/libc/nt/ntdll/RtlCreateUserProcessEx.s new file mode 100644 index 00000000..ce9cf0e7 --- /dev/null +++ b/libc/nt/ntdll/RtlCreateUserProcessEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateUserProcessEx diff --git a/libc/nt/ntdll/RtlCreateUserSecurityObject.s b/libc/nt/ntdll/RtlCreateUserSecurityObject.s new file mode 100644 index 00000000..85dfda0d --- /dev/null +++ b/libc/nt/ntdll/RtlCreateUserSecurityObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateUserSecurityObject diff --git a/libc/nt/ntdll/RtlCreateUserStack.s b/libc/nt/ntdll/RtlCreateUserStack.s new file mode 100644 index 00000000..03346a0c --- /dev/null +++ b/libc/nt/ntdll/RtlCreateUserStack.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateUserStack diff --git a/libc/nt/ntdll/RtlCreateUserThread.s b/libc/nt/ntdll/RtlCreateUserThread.s new file mode 100644 index 00000000..c8a0a53e --- /dev/null +++ b/libc/nt/ntdll/RtlCreateUserThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateUserThread diff --git a/libc/nt/ntdll/RtlCreateVirtualAccountSid.s b/libc/nt/ntdll/RtlCreateVirtualAccountSid.s new file mode 100644 index 00000000..7aa881ce --- /dev/null +++ b/libc/nt/ntdll/RtlCreateVirtualAccountSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCreateVirtualAccountSid diff --git a/libc/nt/ntdll/RtlCultureNameToLCID.s b/libc/nt/ntdll/RtlCultureNameToLCID.s new file mode 100644 index 00000000..e6eb7484 --- /dev/null +++ b/libc/nt/ntdll/RtlCultureNameToLCID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCultureNameToLCID diff --git a/libc/nt/ntdll/RtlCustomCPToUnicodeN.s b/libc/nt/ntdll/RtlCustomCPToUnicodeN.s new file mode 100644 index 00000000..d7c7a8a6 --- /dev/null +++ b/libc/nt/ntdll/RtlCustomCPToUnicodeN.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCustomCPToUnicodeN diff --git a/libc/nt/ntdll/RtlCutoverTimeToSystemTime.s b/libc/nt/ntdll/RtlCutoverTimeToSystemTime.s new file mode 100644 index 00000000..a16970c8 --- /dev/null +++ b/libc/nt/ntdll/RtlCutoverTimeToSystemTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlCutoverTimeToSystemTime diff --git a/libc/nt/ntdll/RtlDeCommitDebugInfo.s b/libc/nt/ntdll/RtlDeCommitDebugInfo.s new file mode 100644 index 00000000..d1f3c933 --- /dev/null +++ b/libc/nt/ntdll/RtlDeCommitDebugInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeCommitDebugInfo diff --git a/libc/nt/ntdll/RtlDeNormalizeProcessParams.s b/libc/nt/ntdll/RtlDeNormalizeProcessParams.s new file mode 100644 index 00000000..39c592b8 --- /dev/null +++ b/libc/nt/ntdll/RtlDeNormalizeProcessParams.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeNormalizeProcessParams diff --git a/libc/nt/ntdll/RtlDeactivateActivationContext.s b/libc/nt/ntdll/RtlDeactivateActivationContext.s new file mode 100644 index 00000000..218717a1 --- /dev/null +++ b/libc/nt/ntdll/RtlDeactivateActivationContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeactivateActivationContext diff --git a/libc/nt/ntdll/RtlDeactivateActivationContextUnsafeFast.s b/libc/nt/ntdll/RtlDeactivateActivationContextUnsafeFast.s new file mode 100644 index 00000000..bb92488a --- /dev/null +++ b/libc/nt/ntdll/RtlDeactivateActivationContextUnsafeFast.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeactivateActivationContextUnsafeFast diff --git a/libc/nt/ntdll/RtlDebugPrintTimes.s b/libc/nt/ntdll/RtlDebugPrintTimes.s new file mode 100644 index 00000000..dfef2903 --- /dev/null +++ b/libc/nt/ntdll/RtlDebugPrintTimes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDebugPrintTimes diff --git a/libc/nt/ntdll/RtlDecodePointer.s b/libc/nt/ntdll/RtlDecodePointer.s new file mode 100644 index 00000000..03e8ee18 --- /dev/null +++ b/libc/nt/ntdll/RtlDecodePointer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDecodePointer diff --git a/libc/nt/ntdll/RtlDecodeRemotePointer.s b/libc/nt/ntdll/RtlDecodeRemotePointer.s new file mode 100644 index 00000000..432131b0 --- /dev/null +++ b/libc/nt/ntdll/RtlDecodeRemotePointer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDecodeRemotePointer diff --git a/libc/nt/ntdll/RtlDecodeSystemPointer.s b/libc/nt/ntdll/RtlDecodeSystemPointer.s new file mode 100644 index 00000000..90e07045 --- /dev/null +++ b/libc/nt/ntdll/RtlDecodeSystemPointer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDecodeSystemPointer diff --git a/libc/nt/ntdll/RtlDecompressBuffer.s b/libc/nt/ntdll/RtlDecompressBuffer.s new file mode 100644 index 00000000..b47b6bc1 --- /dev/null +++ b/libc/nt/ntdll/RtlDecompressBuffer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDecompressBuffer diff --git a/libc/nt/ntdll/RtlDecompressBufferEx.s b/libc/nt/ntdll/RtlDecompressBufferEx.s new file mode 100644 index 00000000..f55ea3a7 --- /dev/null +++ b/libc/nt/ntdll/RtlDecompressBufferEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDecompressBufferEx diff --git a/libc/nt/ntdll/RtlDecompressFragment.s b/libc/nt/ntdll/RtlDecompressFragment.s new file mode 100644 index 00000000..0efabbbe --- /dev/null +++ b/libc/nt/ntdll/RtlDecompressFragment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDecompressFragment diff --git a/libc/nt/ntdll/RtlDefaultNpAcl.s b/libc/nt/ntdll/RtlDefaultNpAcl.s new file mode 100644 index 00000000..947370e3 --- /dev/null +++ b/libc/nt/ntdll/RtlDefaultNpAcl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDefaultNpAcl diff --git a/libc/nt/ntdll/RtlDelete.s b/libc/nt/ntdll/RtlDelete.s new file mode 100644 index 00000000..49ea0cf1 --- /dev/null +++ b/libc/nt/ntdll/RtlDelete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDelete diff --git a/libc/nt/ntdll/RtlDeleteAce.s b/libc/nt/ntdll/RtlDeleteAce.s new file mode 100644 index 00000000..dc1aec4f --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteAce diff --git a/libc/nt/ntdll/RtlDeleteAtomFromAtomTable.s b/libc/nt/ntdll/RtlDeleteAtomFromAtomTable.s new file mode 100644 index 00000000..f192fc47 --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteAtomFromAtomTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteAtomFromAtomTable diff --git a/libc/nt/ntdll/RtlDeleteBarrier.s b/libc/nt/ntdll/RtlDeleteBarrier.s new file mode 100644 index 00000000..a7cc6d16 --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteBarrier.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteBarrier diff --git a/libc/nt/ntdll/RtlDeleteBoundaryDescriptor.s b/libc/nt/ntdll/RtlDeleteBoundaryDescriptor.s new file mode 100644 index 00000000..cf8dd2a6 --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteBoundaryDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteBoundaryDescriptor diff --git a/libc/nt/ntdll/RtlDeleteCriticalSection.s b/libc/nt/ntdll/RtlDeleteCriticalSection.s new file mode 100644 index 00000000..de0f34a5 --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteCriticalSection.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteCriticalSection + + .text.windows +RtlDeleteCriticalSection: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RtlDeleteCriticalSection(%rip) + leave + ret + .endfn RtlDeleteCriticalSection,globl + .previous diff --git a/libc/nt/ntdll/RtlDeleteElementGenericTable.s b/libc/nt/ntdll/RtlDeleteElementGenericTable.s new file mode 100644 index 00000000..42c6d584 --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteElementGenericTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteElementGenericTable diff --git a/libc/nt/ntdll/RtlDeleteElementGenericTableAvl.s b/libc/nt/ntdll/RtlDeleteElementGenericTableAvl.s new file mode 100644 index 00000000..7d3871bc --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteElementGenericTableAvl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteElementGenericTableAvl diff --git a/libc/nt/ntdll/RtlDeleteElementGenericTableAvlEx.s b/libc/nt/ntdll/RtlDeleteElementGenericTableAvlEx.s new file mode 100644 index 00000000..6ee68511 --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteElementGenericTableAvlEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteElementGenericTableAvlEx diff --git a/libc/nt/ntdll/RtlDeleteFunctionTable.s b/libc/nt/ntdll/RtlDeleteFunctionTable.s new file mode 100644 index 00000000..0bfeb01e --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteFunctionTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteFunctionTable diff --git a/libc/nt/ntdll/RtlDeleteGrowableFunctionTable.s b/libc/nt/ntdll/RtlDeleteGrowableFunctionTable.s new file mode 100644 index 00000000..50b4a582 --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteGrowableFunctionTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteGrowableFunctionTable diff --git a/libc/nt/ntdll/RtlDeleteHashTable.s b/libc/nt/ntdll/RtlDeleteHashTable.s new file mode 100644 index 00000000..1645dcf1 --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteHashTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteHashTable diff --git a/libc/nt/ntdll/RtlDeleteNoSplay.s b/libc/nt/ntdll/RtlDeleteNoSplay.s new file mode 100644 index 00000000..79f82973 --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteNoSplay.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteNoSplay diff --git a/libc/nt/ntdll/RtlDeleteRegistryValue.s b/libc/nt/ntdll/RtlDeleteRegistryValue.s new file mode 100644 index 00000000..935ca85b --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteRegistryValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteRegistryValue diff --git a/libc/nt/ntdll/RtlDeleteResource.s b/libc/nt/ntdll/RtlDeleteResource.s new file mode 100644 index 00000000..4cf3733f --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteResource diff --git a/libc/nt/ntdll/RtlDeleteSecurityObject.s b/libc/nt/ntdll/RtlDeleteSecurityObject.s new file mode 100644 index 00000000..3f26abe5 --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteSecurityObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteSecurityObject diff --git a/libc/nt/ntdll/RtlDeleteTimer.s b/libc/nt/ntdll/RtlDeleteTimer.s new file mode 100644 index 00000000..efe1e034 --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteTimer diff --git a/libc/nt/ntdll/RtlDeleteTimerQueue.s b/libc/nt/ntdll/RtlDeleteTimerQueue.s new file mode 100644 index 00000000..69a3ff3e --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteTimerQueue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteTimerQueue diff --git a/libc/nt/ntdll/RtlDeleteTimerQueueEx.s b/libc/nt/ntdll/RtlDeleteTimerQueueEx.s new file mode 100644 index 00000000..b38b89be --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteTimerQueueEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteTimerQueueEx diff --git a/libc/nt/ntdll/RtlDeleteUmsCompletionList.s b/libc/nt/ntdll/RtlDeleteUmsCompletionList.s new file mode 100644 index 00000000..65c54768 --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteUmsCompletionList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteUmsCompletionList diff --git a/libc/nt/ntdll/RtlDeleteUmsThreadContext.s b/libc/nt/ntdll/RtlDeleteUmsThreadContext.s new file mode 100644 index 00000000..2fe4abb6 --- /dev/null +++ b/libc/nt/ntdll/RtlDeleteUmsThreadContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeleteUmsThreadContext diff --git a/libc/nt/ntdll/RtlDequeueUmsCompletionListItems.s b/libc/nt/ntdll/RtlDequeueUmsCompletionListItems.s new file mode 100644 index 00000000..bdce24e3 --- /dev/null +++ b/libc/nt/ntdll/RtlDequeueUmsCompletionListItems.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDequeueUmsCompletionListItems diff --git a/libc/nt/ntdll/RtlDeregisterSecureMemoryCacheCallback.s b/libc/nt/ntdll/RtlDeregisterSecureMemoryCacheCallback.s new file mode 100644 index 00000000..7f05c5de --- /dev/null +++ b/libc/nt/ntdll/RtlDeregisterSecureMemoryCacheCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeregisterSecureMemoryCacheCallback diff --git a/libc/nt/ntdll/RtlDeregisterWait.s b/libc/nt/ntdll/RtlDeregisterWait.s new file mode 100644 index 00000000..c09bccc1 --- /dev/null +++ b/libc/nt/ntdll/RtlDeregisterWait.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeregisterWait diff --git a/libc/nt/ntdll/RtlDeregisterWaitEx.s b/libc/nt/ntdll/RtlDeregisterWaitEx.s new file mode 100644 index 00000000..a1e4c18c --- /dev/null +++ b/libc/nt/ntdll/RtlDeregisterWaitEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeregisterWaitEx diff --git a/libc/nt/ntdll/RtlDeriveCapabilitySidsFromName.s b/libc/nt/ntdll/RtlDeriveCapabilitySidsFromName.s new file mode 100644 index 00000000..9373bd46 --- /dev/null +++ b/libc/nt/ntdll/RtlDeriveCapabilitySidsFromName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDeriveCapabilitySidsFromName diff --git a/libc/nt/ntdll/RtlDestroyAtomTable.s b/libc/nt/ntdll/RtlDestroyAtomTable.s new file mode 100644 index 00000000..f1347cd1 --- /dev/null +++ b/libc/nt/ntdll/RtlDestroyAtomTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDestroyAtomTable diff --git a/libc/nt/ntdll/RtlDestroyEnvironment.s b/libc/nt/ntdll/RtlDestroyEnvironment.s new file mode 100644 index 00000000..7f5940b0 --- /dev/null +++ b/libc/nt/ntdll/RtlDestroyEnvironment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDestroyEnvironment diff --git a/libc/nt/ntdll/RtlDestroyHandleTable.s b/libc/nt/ntdll/RtlDestroyHandleTable.s new file mode 100644 index 00000000..3cacf5cc --- /dev/null +++ b/libc/nt/ntdll/RtlDestroyHandleTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDestroyHandleTable diff --git a/libc/nt/ntdll/RtlDestroyHeap.s b/libc/nt/ntdll/RtlDestroyHeap.s new file mode 100644 index 00000000..f5df00bc --- /dev/null +++ b/libc/nt/ntdll/RtlDestroyHeap.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDestroyHeap + + .text.windows +RtlDestroyHeap: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RtlDestroyHeap(%rip) + leave + ret + .endfn RtlDestroyHeap,globl + .previous diff --git a/libc/nt/ntdll/RtlDestroyMemoryBlockLookaside.s b/libc/nt/ntdll/RtlDestroyMemoryBlockLookaside.s new file mode 100644 index 00000000..e746f77c --- /dev/null +++ b/libc/nt/ntdll/RtlDestroyMemoryBlockLookaside.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDestroyMemoryBlockLookaside diff --git a/libc/nt/ntdll/RtlDestroyMemoryZone.s b/libc/nt/ntdll/RtlDestroyMemoryZone.s new file mode 100644 index 00000000..f99b0534 --- /dev/null +++ b/libc/nt/ntdll/RtlDestroyMemoryZone.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDestroyMemoryZone diff --git a/libc/nt/ntdll/RtlDestroyProcessParameters.s b/libc/nt/ntdll/RtlDestroyProcessParameters.s new file mode 100644 index 00000000..618d1139 --- /dev/null +++ b/libc/nt/ntdll/RtlDestroyProcessParameters.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDestroyProcessParameters + + .text.windows +RtlDestroyProcessParameters: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RtlDestroyProcessParameters(%rip) + leave + ret + .endfn RtlDestroyProcessParameters,globl + .previous diff --git a/libc/nt/ntdll/RtlDestroyQueryDebugBuffer.s b/libc/nt/ntdll/RtlDestroyQueryDebugBuffer.s new file mode 100644 index 00000000..e8bb7ddb --- /dev/null +++ b/libc/nt/ntdll/RtlDestroyQueryDebugBuffer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDestroyQueryDebugBuffer diff --git a/libc/nt/ntdll/RtlDetectHeapLeaks.s b/libc/nt/ntdll/RtlDetectHeapLeaks.s new file mode 100644 index 00000000..a7d955d6 --- /dev/null +++ b/libc/nt/ntdll/RtlDetectHeapLeaks.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDetectHeapLeaks diff --git a/libc/nt/ntdll/RtlDetermineDosPathNameType_U.s b/libc/nt/ntdll/RtlDetermineDosPathNameType_U.s new file mode 100644 index 00000000..7743188e --- /dev/null +++ b/libc/nt/ntdll/RtlDetermineDosPathNameType_U.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDetermineDosPathNameType_U diff --git a/libc/nt/ntdll/RtlDisableThreadProfiling.s b/libc/nt/ntdll/RtlDisableThreadProfiling.s new file mode 100644 index 00000000..dceaebcc --- /dev/null +++ b/libc/nt/ntdll/RtlDisableThreadProfiling.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDisableThreadProfiling diff --git a/libc/nt/ntdll/RtlDllShutdownInProgress.s b/libc/nt/ntdll/RtlDllShutdownInProgress.s new file mode 100644 index 00000000..97788eae --- /dev/null +++ b/libc/nt/ntdll/RtlDllShutdownInProgress.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDllShutdownInProgress diff --git a/libc/nt/ntdll/RtlDnsHostNameToComputerName.s b/libc/nt/ntdll/RtlDnsHostNameToComputerName.s new file mode 100644 index 00000000..692dd448 --- /dev/null +++ b/libc/nt/ntdll/RtlDnsHostNameToComputerName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDnsHostNameToComputerName diff --git a/libc/nt/ntdll/RtlDoesFileExists_U.s b/libc/nt/ntdll/RtlDoesFileExists_U.s new file mode 100644 index 00000000..39051d17 --- /dev/null +++ b/libc/nt/ntdll/RtlDoesFileExists_U.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDoesFileExists_U diff --git a/libc/nt/ntdll/RtlDosApplyFileIsolationRedirection_Ustr.s b/libc/nt/ntdll/RtlDosApplyFileIsolationRedirection_Ustr.s new file mode 100644 index 00000000..cc085334 --- /dev/null +++ b/libc/nt/ntdll/RtlDosApplyFileIsolationRedirection_Ustr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDosApplyFileIsolationRedirection_Ustr diff --git a/libc/nt/ntdll/RtlDosLongPathNameToNtPathName_U_WithStatus.s b/libc/nt/ntdll/RtlDosLongPathNameToNtPathName_U_WithStatus.s new file mode 100644 index 00000000..f74a94ba --- /dev/null +++ b/libc/nt/ntdll/RtlDosLongPathNameToNtPathName_U_WithStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDosLongPathNameToNtPathName_U_WithStatus diff --git a/libc/nt/ntdll/RtlDosLongPathNameToRelativeNtPathName_U_WithStatus.s b/libc/nt/ntdll/RtlDosLongPathNameToRelativeNtPathName_U_WithStatus.s new file mode 100644 index 00000000..2bed942d --- /dev/null +++ b/libc/nt/ntdll/RtlDosLongPathNameToRelativeNtPathName_U_WithStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDosLongPathNameToRelativeNtPathName_U_WithStatus diff --git a/libc/nt/ntdll/RtlDosPathNameToNtPathName_U.s b/libc/nt/ntdll/RtlDosPathNameToNtPathName_U.s new file mode 100644 index 00000000..a99f3885 --- /dev/null +++ b/libc/nt/ntdll/RtlDosPathNameToNtPathName_U.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDosPathNameToNtPathName_U diff --git a/libc/nt/ntdll/RtlDosPathNameToNtPathName_U_WithStatus.s b/libc/nt/ntdll/RtlDosPathNameToNtPathName_U_WithStatus.s new file mode 100644 index 00000000..e1623b52 --- /dev/null +++ b/libc/nt/ntdll/RtlDosPathNameToNtPathName_U_WithStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDosPathNameToNtPathName_U_WithStatus diff --git a/libc/nt/ntdll/RtlDosPathNameToRelativeNtPathName_U.s b/libc/nt/ntdll/RtlDosPathNameToRelativeNtPathName_U.s new file mode 100644 index 00000000..ff4648f0 --- /dev/null +++ b/libc/nt/ntdll/RtlDosPathNameToRelativeNtPathName_U.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDosPathNameToRelativeNtPathName_U diff --git a/libc/nt/ntdll/RtlDosPathNameToRelativeNtPathName_U_WithStatus.s b/libc/nt/ntdll/RtlDosPathNameToRelativeNtPathName_U_WithStatus.s new file mode 100644 index 00000000..953288eb --- /dev/null +++ b/libc/nt/ntdll/RtlDosPathNameToRelativeNtPathName_U_WithStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDosPathNameToRelativeNtPathName_U_WithStatus diff --git a/libc/nt/ntdll/RtlDosSearchPath_U.s b/libc/nt/ntdll/RtlDosSearchPath_U.s new file mode 100644 index 00000000..dad0cfda --- /dev/null +++ b/libc/nt/ntdll/RtlDosSearchPath_U.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDosSearchPath_U diff --git a/libc/nt/ntdll/RtlDosSearchPath_Ustr.s b/libc/nt/ntdll/RtlDosSearchPath_Ustr.s new file mode 100644 index 00000000..11d0a199 --- /dev/null +++ b/libc/nt/ntdll/RtlDosSearchPath_Ustr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDosSearchPath_Ustr diff --git a/libc/nt/ntdll/RtlDowncaseUnicodeChar.s b/libc/nt/ntdll/RtlDowncaseUnicodeChar.s new file mode 100644 index 00000000..997c6645 --- /dev/null +++ b/libc/nt/ntdll/RtlDowncaseUnicodeChar.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDowncaseUnicodeChar diff --git a/libc/nt/ntdll/RtlDowncaseUnicodeString.s b/libc/nt/ntdll/RtlDowncaseUnicodeString.s new file mode 100644 index 00000000..d1d67913 --- /dev/null +++ b/libc/nt/ntdll/RtlDowncaseUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDowncaseUnicodeString diff --git a/libc/nt/ntdll/RtlDrainNonVolatileFlush.s b/libc/nt/ntdll/RtlDrainNonVolatileFlush.s new file mode 100644 index 00000000..3c1416a7 --- /dev/null +++ b/libc/nt/ntdll/RtlDrainNonVolatileFlush.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDrainNonVolatileFlush diff --git a/libc/nt/ntdll/RtlDumpResource.s b/libc/nt/ntdll/RtlDumpResource.s new file mode 100644 index 00000000..43613dc8 --- /dev/null +++ b/libc/nt/ntdll/RtlDumpResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDumpResource diff --git a/libc/nt/ntdll/RtlDuplicateUnicodeString.s b/libc/nt/ntdll/RtlDuplicateUnicodeString.s new file mode 100644 index 00000000..6508ddaa --- /dev/null +++ b/libc/nt/ntdll/RtlDuplicateUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlDuplicateUnicodeString diff --git a/libc/nt/ntdll/RtlEmptyAtomTable.s b/libc/nt/ntdll/RtlEmptyAtomTable.s new file mode 100644 index 00000000..6fa40fb6 --- /dev/null +++ b/libc/nt/ntdll/RtlEmptyAtomTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEmptyAtomTable diff --git a/libc/nt/ntdll/RtlEnableEarlyCriticalSectionEventCreation.s b/libc/nt/ntdll/RtlEnableEarlyCriticalSectionEventCreation.s new file mode 100644 index 00000000..062c633e --- /dev/null +++ b/libc/nt/ntdll/RtlEnableEarlyCriticalSectionEventCreation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEnableEarlyCriticalSectionEventCreation diff --git a/libc/nt/ntdll/RtlEnableThreadProfiling.s b/libc/nt/ntdll/RtlEnableThreadProfiling.s new file mode 100644 index 00000000..b83d40e1 --- /dev/null +++ b/libc/nt/ntdll/RtlEnableThreadProfiling.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEnableThreadProfiling diff --git a/libc/nt/ntdll/RtlEnclaveCallDispatch.s b/libc/nt/ntdll/RtlEnclaveCallDispatch.s new file mode 100644 index 00000000..802034d4 --- /dev/null +++ b/libc/nt/ntdll/RtlEnclaveCallDispatch.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEnclaveCallDispatch diff --git a/libc/nt/ntdll/RtlEnclaveCallDispatchReturn.s b/libc/nt/ntdll/RtlEnclaveCallDispatchReturn.s new file mode 100644 index 00000000..750580c8 --- /dev/null +++ b/libc/nt/ntdll/RtlEnclaveCallDispatchReturn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEnclaveCallDispatchReturn diff --git a/libc/nt/ntdll/RtlEncodePointer.s b/libc/nt/ntdll/RtlEncodePointer.s new file mode 100644 index 00000000..ea5abf57 --- /dev/null +++ b/libc/nt/ntdll/RtlEncodePointer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEncodePointer diff --git a/libc/nt/ntdll/RtlEncodeRemotePointer.s b/libc/nt/ntdll/RtlEncodeRemotePointer.s new file mode 100644 index 00000000..597fbafb --- /dev/null +++ b/libc/nt/ntdll/RtlEncodeRemotePointer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEncodeRemotePointer diff --git a/libc/nt/ntdll/RtlEncodeSystemPointer.s b/libc/nt/ntdll/RtlEncodeSystemPointer.s new file mode 100644 index 00000000..12bf34c8 --- /dev/null +++ b/libc/nt/ntdll/RtlEncodeSystemPointer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEncodeSystemPointer diff --git a/libc/nt/ntdll/RtlEndEnumerationHashTable.s b/libc/nt/ntdll/RtlEndEnumerationHashTable.s new file mode 100644 index 00000000..ee1a14fc --- /dev/null +++ b/libc/nt/ntdll/RtlEndEnumerationHashTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEndEnumerationHashTable diff --git a/libc/nt/ntdll/RtlEndStrongEnumerationHashTable.s b/libc/nt/ntdll/RtlEndStrongEnumerationHashTable.s new file mode 100644 index 00000000..cb858dd7 --- /dev/null +++ b/libc/nt/ntdll/RtlEndStrongEnumerationHashTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEndStrongEnumerationHashTable diff --git a/libc/nt/ntdll/RtlEndWeakEnumerationHashTable.s b/libc/nt/ntdll/RtlEndWeakEnumerationHashTable.s new file mode 100644 index 00000000..99635d1f --- /dev/null +++ b/libc/nt/ntdll/RtlEndWeakEnumerationHashTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEndWeakEnumerationHashTable diff --git a/libc/nt/ntdll/RtlEnterCriticalSection.s b/libc/nt/ntdll/RtlEnterCriticalSection.s new file mode 100644 index 00000000..5fb95d69 --- /dev/null +++ b/libc/nt/ntdll/RtlEnterCriticalSection.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEnterCriticalSection + + .text.windows +RtlEnterCriticalSection: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RtlEnterCriticalSection(%rip) + leave + ret + .endfn RtlEnterCriticalSection,globl + .previous diff --git a/libc/nt/ntdll/RtlEnterUmsSchedulingMode.s b/libc/nt/ntdll/RtlEnterUmsSchedulingMode.s new file mode 100644 index 00000000..ca7083c5 --- /dev/null +++ b/libc/nt/ntdll/RtlEnterUmsSchedulingMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEnterUmsSchedulingMode diff --git a/libc/nt/ntdll/RtlEnumProcessHeaps.s b/libc/nt/ntdll/RtlEnumProcessHeaps.s new file mode 100644 index 00000000..90c4e534 --- /dev/null +++ b/libc/nt/ntdll/RtlEnumProcessHeaps.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEnumProcessHeaps diff --git a/libc/nt/ntdll/RtlEnumerateEntryHashTable.s b/libc/nt/ntdll/RtlEnumerateEntryHashTable.s new file mode 100644 index 00000000..81ac3663 --- /dev/null +++ b/libc/nt/ntdll/RtlEnumerateEntryHashTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEnumerateEntryHashTable diff --git a/libc/nt/ntdll/RtlEnumerateGenericTable.s b/libc/nt/ntdll/RtlEnumerateGenericTable.s new file mode 100644 index 00000000..620afa5b --- /dev/null +++ b/libc/nt/ntdll/RtlEnumerateGenericTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEnumerateGenericTable diff --git a/libc/nt/ntdll/RtlEnumerateGenericTableAvl.s b/libc/nt/ntdll/RtlEnumerateGenericTableAvl.s new file mode 100644 index 00000000..0eaf54ea --- /dev/null +++ b/libc/nt/ntdll/RtlEnumerateGenericTableAvl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEnumerateGenericTableAvl diff --git a/libc/nt/ntdll/RtlEnumerateGenericTableLikeADirectory.s b/libc/nt/ntdll/RtlEnumerateGenericTableLikeADirectory.s new file mode 100644 index 00000000..5fe64a4c --- /dev/null +++ b/libc/nt/ntdll/RtlEnumerateGenericTableLikeADirectory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEnumerateGenericTableLikeADirectory diff --git a/libc/nt/ntdll/RtlEnumerateGenericTableWithoutSplaying.s b/libc/nt/ntdll/RtlEnumerateGenericTableWithoutSplaying.s new file mode 100644 index 00000000..d6675de6 --- /dev/null +++ b/libc/nt/ntdll/RtlEnumerateGenericTableWithoutSplaying.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEnumerateGenericTableWithoutSplaying diff --git a/libc/nt/ntdll/RtlEnumerateGenericTableWithoutSplayingAvl.s b/libc/nt/ntdll/RtlEnumerateGenericTableWithoutSplayingAvl.s new file mode 100644 index 00000000..10a15522 --- /dev/null +++ b/libc/nt/ntdll/RtlEnumerateGenericTableWithoutSplayingAvl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEnumerateGenericTableWithoutSplayingAvl diff --git a/libc/nt/ntdll/RtlEqualComputerName.s b/libc/nt/ntdll/RtlEqualComputerName.s new file mode 100644 index 00000000..905a52ef --- /dev/null +++ b/libc/nt/ntdll/RtlEqualComputerName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEqualComputerName diff --git a/libc/nt/ntdll/RtlEqualDomainName.s b/libc/nt/ntdll/RtlEqualDomainName.s new file mode 100644 index 00000000..3b124218 --- /dev/null +++ b/libc/nt/ntdll/RtlEqualDomainName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEqualDomainName diff --git a/libc/nt/ntdll/RtlEqualLuid.s b/libc/nt/ntdll/RtlEqualLuid.s new file mode 100644 index 00000000..c8cb2a72 --- /dev/null +++ b/libc/nt/ntdll/RtlEqualLuid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEqualLuid diff --git a/libc/nt/ntdll/RtlEqualPrefixSid.s b/libc/nt/ntdll/RtlEqualPrefixSid.s new file mode 100644 index 00000000..15ef8e26 --- /dev/null +++ b/libc/nt/ntdll/RtlEqualPrefixSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEqualPrefixSid diff --git a/libc/nt/ntdll/RtlEqualSid.s b/libc/nt/ntdll/RtlEqualSid.s new file mode 100644 index 00000000..0f5ccaf4 --- /dev/null +++ b/libc/nt/ntdll/RtlEqualSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEqualSid diff --git a/libc/nt/ntdll/RtlEqualString.s b/libc/nt/ntdll/RtlEqualString.s new file mode 100644 index 00000000..46efa373 --- /dev/null +++ b/libc/nt/ntdll/RtlEqualString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEqualString diff --git a/libc/nt/ntdll/RtlEqualUnicodeString.s b/libc/nt/ntdll/RtlEqualUnicodeString.s new file mode 100644 index 00000000..da7387db --- /dev/null +++ b/libc/nt/ntdll/RtlEqualUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEqualUnicodeString diff --git a/libc/nt/ntdll/RtlEqualWnfChangeStamps.s b/libc/nt/ntdll/RtlEqualWnfChangeStamps.s new file mode 100644 index 00000000..5b683acd --- /dev/null +++ b/libc/nt/ntdll/RtlEqualWnfChangeStamps.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEqualWnfChangeStamps diff --git a/libc/nt/ntdll/RtlEraseUnicodeString.s b/libc/nt/ntdll/RtlEraseUnicodeString.s new file mode 100644 index 00000000..f83e1e27 --- /dev/null +++ b/libc/nt/ntdll/RtlEraseUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEraseUnicodeString diff --git a/libc/nt/ntdll/RtlEthernetAddressToStringA.s b/libc/nt/ntdll/RtlEthernetAddressToStringA.s new file mode 100644 index 00000000..a76641a0 --- /dev/null +++ b/libc/nt/ntdll/RtlEthernetAddressToStringA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEthernetAddressToStringA diff --git a/libc/nt/ntdll/RtlEthernetAddressToStringW.s b/libc/nt/ntdll/RtlEthernetAddressToStringW.s new file mode 100644 index 00000000..75f5a959 --- /dev/null +++ b/libc/nt/ntdll/RtlEthernetAddressToStringW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEthernetAddressToStringW diff --git a/libc/nt/ntdll/RtlEthernetStringToAddressA.s b/libc/nt/ntdll/RtlEthernetStringToAddressA.s new file mode 100644 index 00000000..d234cefc --- /dev/null +++ b/libc/nt/ntdll/RtlEthernetStringToAddressA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEthernetStringToAddressA diff --git a/libc/nt/ntdll/RtlEthernetStringToAddressW.s b/libc/nt/ntdll/RtlEthernetStringToAddressW.s new file mode 100644 index 00000000..64d35909 --- /dev/null +++ b/libc/nt/ntdll/RtlEthernetStringToAddressW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlEthernetStringToAddressW diff --git a/libc/nt/ntdll/RtlExecuteUmsThread.s b/libc/nt/ntdll/RtlExecuteUmsThread.s new file mode 100644 index 00000000..cb2ab385 --- /dev/null +++ b/libc/nt/ntdll/RtlExecuteUmsThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlExecuteUmsThread diff --git a/libc/nt/ntdll/RtlExitUserProcess.s b/libc/nt/ntdll/RtlExitUserProcess.s new file mode 100644 index 00000000..f68ed619 --- /dev/null +++ b/libc/nt/ntdll/RtlExitUserProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlExitUserProcess diff --git a/libc/nt/ntdll/RtlExitUserThread.s b/libc/nt/ntdll/RtlExitUserThread.s new file mode 100644 index 00000000..72bb2937 --- /dev/null +++ b/libc/nt/ntdll/RtlExitUserThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlExitUserThread diff --git a/libc/nt/ntdll/RtlExpandEnvironmentStrings.s b/libc/nt/ntdll/RtlExpandEnvironmentStrings.s new file mode 100644 index 00000000..371a7e45 --- /dev/null +++ b/libc/nt/ntdll/RtlExpandEnvironmentStrings.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlExpandEnvironmentStrings diff --git a/libc/nt/ntdll/RtlExpandEnvironmentStrings_U.s b/libc/nt/ntdll/RtlExpandEnvironmentStrings_U.s new file mode 100644 index 00000000..e137fff6 --- /dev/null +++ b/libc/nt/ntdll/RtlExpandEnvironmentStrings_U.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlExpandEnvironmentStrings_U diff --git a/libc/nt/ntdll/RtlExpandHashTable.s b/libc/nt/ntdll/RtlExpandHashTable.s new file mode 100644 index 00000000..0cb87e36 --- /dev/null +++ b/libc/nt/ntdll/RtlExpandHashTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlExpandHashTable diff --git a/libc/nt/ntdll/RtlExtendCorrelationVector.s b/libc/nt/ntdll/RtlExtendCorrelationVector.s new file mode 100644 index 00000000..5afe0dae --- /dev/null +++ b/libc/nt/ntdll/RtlExtendCorrelationVector.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlExtendCorrelationVector diff --git a/libc/nt/ntdll/RtlExtendMemoryBlockLookaside.s b/libc/nt/ntdll/RtlExtendMemoryBlockLookaside.s new file mode 100644 index 00000000..ceb6fe36 --- /dev/null +++ b/libc/nt/ntdll/RtlExtendMemoryBlockLookaside.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlExtendMemoryBlockLookaside diff --git a/libc/nt/ntdll/RtlExtendMemoryZone.s b/libc/nt/ntdll/RtlExtendMemoryZone.s new file mode 100644 index 00000000..25ce390f --- /dev/null +++ b/libc/nt/ntdll/RtlExtendMemoryZone.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlExtendMemoryZone diff --git a/libc/nt/ntdll/RtlExtractBitMap.s b/libc/nt/ntdll/RtlExtractBitMap.s new file mode 100644 index 00000000..2f3563f9 --- /dev/null +++ b/libc/nt/ntdll/RtlExtractBitMap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlExtractBitMap diff --git a/libc/nt/ntdll/RtlFillMemory.s b/libc/nt/ntdll/RtlFillMemory.s new file mode 100644 index 00000000..f89e54ee --- /dev/null +++ b/libc/nt/ntdll/RtlFillMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFillMemory diff --git a/libc/nt/ntdll/RtlFinalReleaseOutOfProcessMemoryStream.s b/libc/nt/ntdll/RtlFinalReleaseOutOfProcessMemoryStream.s new file mode 100644 index 00000000..84001bed --- /dev/null +++ b/libc/nt/ntdll/RtlFinalReleaseOutOfProcessMemoryStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFinalReleaseOutOfProcessMemoryStream diff --git a/libc/nt/ntdll/RtlFindAceByType.s b/libc/nt/ntdll/RtlFindAceByType.s new file mode 100644 index 00000000..a3f7b803 --- /dev/null +++ b/libc/nt/ntdll/RtlFindAceByType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindAceByType diff --git a/libc/nt/ntdll/RtlFindActivationContextSectionGuid.s b/libc/nt/ntdll/RtlFindActivationContextSectionGuid.s new file mode 100644 index 00000000..383f825b --- /dev/null +++ b/libc/nt/ntdll/RtlFindActivationContextSectionGuid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindActivationContextSectionGuid diff --git a/libc/nt/ntdll/RtlFindActivationContextSectionString.s b/libc/nt/ntdll/RtlFindActivationContextSectionString.s new file mode 100644 index 00000000..f9aaf2dc --- /dev/null +++ b/libc/nt/ntdll/RtlFindActivationContextSectionString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindActivationContextSectionString diff --git a/libc/nt/ntdll/RtlFindCharInUnicodeString.s b/libc/nt/ntdll/RtlFindCharInUnicodeString.s new file mode 100644 index 00000000..18e27634 --- /dev/null +++ b/libc/nt/ntdll/RtlFindCharInUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindCharInUnicodeString diff --git a/libc/nt/ntdll/RtlFindClearBits.s b/libc/nt/ntdll/RtlFindClearBits.s new file mode 100644 index 00000000..b6472aa9 --- /dev/null +++ b/libc/nt/ntdll/RtlFindClearBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindClearBits diff --git a/libc/nt/ntdll/RtlFindClearBitsAndSet.s b/libc/nt/ntdll/RtlFindClearBitsAndSet.s new file mode 100644 index 00000000..1816d2ce --- /dev/null +++ b/libc/nt/ntdll/RtlFindClearBitsAndSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindClearBitsAndSet diff --git a/libc/nt/ntdll/RtlFindClearRuns.s b/libc/nt/ntdll/RtlFindClearRuns.s new file mode 100644 index 00000000..054d150a --- /dev/null +++ b/libc/nt/ntdll/RtlFindClearRuns.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindClearRuns diff --git a/libc/nt/ntdll/RtlFindClosestEncodableLength.s b/libc/nt/ntdll/RtlFindClosestEncodableLength.s new file mode 100644 index 00000000..be74f311 --- /dev/null +++ b/libc/nt/ntdll/RtlFindClosestEncodableLength.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindClosestEncodableLength diff --git a/libc/nt/ntdll/RtlFindExportedRoutineByName.s b/libc/nt/ntdll/RtlFindExportedRoutineByName.s new file mode 100644 index 00000000..915e16fa --- /dev/null +++ b/libc/nt/ntdll/RtlFindExportedRoutineByName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindExportedRoutineByName diff --git a/libc/nt/ntdll/RtlFindLastBackwardRunClear.s b/libc/nt/ntdll/RtlFindLastBackwardRunClear.s new file mode 100644 index 00000000..f349fb41 --- /dev/null +++ b/libc/nt/ntdll/RtlFindLastBackwardRunClear.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindLastBackwardRunClear diff --git a/libc/nt/ntdll/RtlFindLeastSignificantBit.s b/libc/nt/ntdll/RtlFindLeastSignificantBit.s new file mode 100644 index 00000000..e5f4afea --- /dev/null +++ b/libc/nt/ntdll/RtlFindLeastSignificantBit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindLeastSignificantBit diff --git a/libc/nt/ntdll/RtlFindLongestRunClear.s b/libc/nt/ntdll/RtlFindLongestRunClear.s new file mode 100644 index 00000000..8a5247f3 --- /dev/null +++ b/libc/nt/ntdll/RtlFindLongestRunClear.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindLongestRunClear diff --git a/libc/nt/ntdll/RtlFindMessage.s b/libc/nt/ntdll/RtlFindMessage.s new file mode 100644 index 00000000..c24cfc5a --- /dev/null +++ b/libc/nt/ntdll/RtlFindMessage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindMessage diff --git a/libc/nt/ntdll/RtlFindMostSignificantBit.s b/libc/nt/ntdll/RtlFindMostSignificantBit.s new file mode 100644 index 00000000..3377a30f --- /dev/null +++ b/libc/nt/ntdll/RtlFindMostSignificantBit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindMostSignificantBit diff --git a/libc/nt/ntdll/RtlFindNextForwardRunClear.s b/libc/nt/ntdll/RtlFindNextForwardRunClear.s new file mode 100644 index 00000000..52dedd90 --- /dev/null +++ b/libc/nt/ntdll/RtlFindNextForwardRunClear.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindNextForwardRunClear diff --git a/libc/nt/ntdll/RtlFindSetBits.s b/libc/nt/ntdll/RtlFindSetBits.s new file mode 100644 index 00000000..300c9d78 --- /dev/null +++ b/libc/nt/ntdll/RtlFindSetBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindSetBits diff --git a/libc/nt/ntdll/RtlFindSetBitsAndClear.s b/libc/nt/ntdll/RtlFindSetBitsAndClear.s new file mode 100644 index 00000000..ec59e85d --- /dev/null +++ b/libc/nt/ntdll/RtlFindSetBitsAndClear.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindSetBitsAndClear diff --git a/libc/nt/ntdll/RtlFindUnicodeSubstring.s b/libc/nt/ntdll/RtlFindUnicodeSubstring.s new file mode 100644 index 00000000..8b169235 --- /dev/null +++ b/libc/nt/ntdll/RtlFindUnicodeSubstring.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFindUnicodeSubstring diff --git a/libc/nt/ntdll/RtlFirstEntrySList.s b/libc/nt/ntdll/RtlFirstEntrySList.s new file mode 100644 index 00000000..bb326585 --- /dev/null +++ b/libc/nt/ntdll/RtlFirstEntrySList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFirstEntrySList diff --git a/libc/nt/ntdll/RtlFirstFreeAce.s b/libc/nt/ntdll/RtlFirstFreeAce.s new file mode 100644 index 00000000..75974183 --- /dev/null +++ b/libc/nt/ntdll/RtlFirstFreeAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFirstFreeAce diff --git a/libc/nt/ntdll/RtlFlsAlloc.s b/libc/nt/ntdll/RtlFlsAlloc.s new file mode 100644 index 00000000..0527e85f --- /dev/null +++ b/libc/nt/ntdll/RtlFlsAlloc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFlsAlloc diff --git a/libc/nt/ntdll/RtlFlsFree.s b/libc/nt/ntdll/RtlFlsFree.s new file mode 100644 index 00000000..39170055 --- /dev/null +++ b/libc/nt/ntdll/RtlFlsFree.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFlsFree diff --git a/libc/nt/ntdll/RtlFlushHeaps.s b/libc/nt/ntdll/RtlFlushHeaps.s new file mode 100644 index 00000000..4b9de271 --- /dev/null +++ b/libc/nt/ntdll/RtlFlushHeaps.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFlushHeaps diff --git a/libc/nt/ntdll/RtlFlushNonVolatileMemory.s b/libc/nt/ntdll/RtlFlushNonVolatileMemory.s new file mode 100644 index 00000000..390abd19 --- /dev/null +++ b/libc/nt/ntdll/RtlFlushNonVolatileMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFlushNonVolatileMemory diff --git a/libc/nt/ntdll/RtlFlushNonVolatileMemoryRanges.s b/libc/nt/ntdll/RtlFlushNonVolatileMemoryRanges.s new file mode 100644 index 00000000..db061416 --- /dev/null +++ b/libc/nt/ntdll/RtlFlushNonVolatileMemoryRanges.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFlushNonVolatileMemoryRanges diff --git a/libc/nt/ntdll/RtlFlushSecureMemoryCache.s b/libc/nt/ntdll/RtlFlushSecureMemoryCache.s new file mode 100644 index 00000000..5a8d3c92 --- /dev/null +++ b/libc/nt/ntdll/RtlFlushSecureMemoryCache.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFlushSecureMemoryCache diff --git a/libc/nt/ntdll/RtlFormatCurrentUserKeyPath.s b/libc/nt/ntdll/RtlFormatCurrentUserKeyPath.s new file mode 100644 index 00000000..4a8c80c2 --- /dev/null +++ b/libc/nt/ntdll/RtlFormatCurrentUserKeyPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFormatCurrentUserKeyPath diff --git a/libc/nt/ntdll/RtlFormatMessage.s b/libc/nt/ntdll/RtlFormatMessage.s new file mode 100644 index 00000000..5322af40 --- /dev/null +++ b/libc/nt/ntdll/RtlFormatMessage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFormatMessage diff --git a/libc/nt/ntdll/RtlFormatMessageEx.s b/libc/nt/ntdll/RtlFormatMessageEx.s new file mode 100644 index 00000000..18acbec5 --- /dev/null +++ b/libc/nt/ntdll/RtlFormatMessageEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFormatMessageEx diff --git a/libc/nt/ntdll/RtlFreeActivationContextStack.s b/libc/nt/ntdll/RtlFreeActivationContextStack.s new file mode 100644 index 00000000..ee7911c1 --- /dev/null +++ b/libc/nt/ntdll/RtlFreeActivationContextStack.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFreeActivationContextStack diff --git a/libc/nt/ntdll/RtlFreeAnsiString.s b/libc/nt/ntdll/RtlFreeAnsiString.s new file mode 100644 index 00000000..4fcd538c --- /dev/null +++ b/libc/nt/ntdll/RtlFreeAnsiString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFreeAnsiString diff --git a/libc/nt/ntdll/RtlFreeHandle.s b/libc/nt/ntdll/RtlFreeHandle.s new file mode 100644 index 00000000..7b880491 --- /dev/null +++ b/libc/nt/ntdll/RtlFreeHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFreeHandle diff --git a/libc/nt/ntdll/RtlFreeHeap.s b/libc/nt/ntdll/RtlFreeHeap.s new file mode 100644 index 00000000..b7ee8d85 --- /dev/null +++ b/libc/nt/ntdll/RtlFreeHeap.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFreeHeap + + .text.windows +RtlFreeHeap: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RtlFreeHeap(%rip),%rax + jmp __sysv2nt + .endfn RtlFreeHeap,globl + .previous diff --git a/libc/nt/ntdll/RtlFreeMemoryBlockLookaside.s b/libc/nt/ntdll/RtlFreeMemoryBlockLookaside.s new file mode 100644 index 00000000..63341c2f --- /dev/null +++ b/libc/nt/ntdll/RtlFreeMemoryBlockLookaside.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFreeMemoryBlockLookaside diff --git a/libc/nt/ntdll/RtlFreeNonVolatileToken.s b/libc/nt/ntdll/RtlFreeNonVolatileToken.s new file mode 100644 index 00000000..4ecd1be5 --- /dev/null +++ b/libc/nt/ntdll/RtlFreeNonVolatileToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFreeNonVolatileToken diff --git a/libc/nt/ntdll/RtlFreeOemString.s b/libc/nt/ntdll/RtlFreeOemString.s new file mode 100644 index 00000000..764fb338 --- /dev/null +++ b/libc/nt/ntdll/RtlFreeOemString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFreeOemString diff --git a/libc/nt/ntdll/RtlFreeSid.s b/libc/nt/ntdll/RtlFreeSid.s new file mode 100644 index 00000000..bf8ee573 --- /dev/null +++ b/libc/nt/ntdll/RtlFreeSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFreeSid diff --git a/libc/nt/ntdll/RtlFreeThreadActivationContextStack.s b/libc/nt/ntdll/RtlFreeThreadActivationContextStack.s new file mode 100644 index 00000000..21556164 --- /dev/null +++ b/libc/nt/ntdll/RtlFreeThreadActivationContextStack.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFreeThreadActivationContextStack diff --git a/libc/nt/ntdll/RtlFreeUnicodeString.s b/libc/nt/ntdll/RtlFreeUnicodeString.s new file mode 100644 index 00000000..414e37c7 --- /dev/null +++ b/libc/nt/ntdll/RtlFreeUnicodeString.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFreeUnicodeString + + .text.windows +RtlFreeUnicodeString: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RtlFreeUnicodeString(%rip) + leave + ret + .endfn RtlFreeUnicodeString,globl + .previous diff --git a/libc/nt/ntdll/RtlFreeUserStack.s b/libc/nt/ntdll/RtlFreeUserStack.s new file mode 100644 index 00000000..80f3d1dc --- /dev/null +++ b/libc/nt/ntdll/RtlFreeUserStack.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlFreeUserStack diff --git a/libc/nt/ntdll/RtlGUIDFromString.s b/libc/nt/ntdll/RtlGUIDFromString.s new file mode 100644 index 00000000..f1482811 --- /dev/null +++ b/libc/nt/ntdll/RtlGUIDFromString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGUIDFromString diff --git a/libc/nt/ntdll/RtlGenerate8dot3Name.s b/libc/nt/ntdll/RtlGenerate8dot3Name.s new file mode 100644 index 00000000..3b45dfbb --- /dev/null +++ b/libc/nt/ntdll/RtlGenerate8dot3Name.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGenerate8dot3Name diff --git a/libc/nt/ntdll/RtlGetAce.s b/libc/nt/ntdll/RtlGetAce.s new file mode 100644 index 00000000..6d129896 --- /dev/null +++ b/libc/nt/ntdll/RtlGetAce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetAce diff --git a/libc/nt/ntdll/RtlGetActiveActivationContext.s b/libc/nt/ntdll/RtlGetActiveActivationContext.s new file mode 100644 index 00000000..d1b36821 --- /dev/null +++ b/libc/nt/ntdll/RtlGetActiveActivationContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetActiveActivationContext diff --git a/libc/nt/ntdll/RtlGetActiveConsoleId.s b/libc/nt/ntdll/RtlGetActiveConsoleId.s new file mode 100644 index 00000000..f9b44e64 --- /dev/null +++ b/libc/nt/ntdll/RtlGetActiveConsoleId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetActiveConsoleId diff --git a/libc/nt/ntdll/RtlGetAppContainerNamedObjectPath.s b/libc/nt/ntdll/RtlGetAppContainerNamedObjectPath.s new file mode 100644 index 00000000..e4a33ed4 --- /dev/null +++ b/libc/nt/ntdll/RtlGetAppContainerNamedObjectPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetAppContainerNamedObjectPath diff --git a/libc/nt/ntdll/RtlGetAppContainerParent.s b/libc/nt/ntdll/RtlGetAppContainerParent.s new file mode 100644 index 00000000..fc867c57 --- /dev/null +++ b/libc/nt/ntdll/RtlGetAppContainerParent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetAppContainerParent diff --git a/libc/nt/ntdll/RtlGetAppContainerSidType.s b/libc/nt/ntdll/RtlGetAppContainerSidType.s new file mode 100644 index 00000000..32dcdd61 --- /dev/null +++ b/libc/nt/ntdll/RtlGetAppContainerSidType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetAppContainerSidType diff --git a/libc/nt/ntdll/RtlGetCallersAddress.s b/libc/nt/ntdll/RtlGetCallersAddress.s new file mode 100644 index 00000000..8ab9e6d4 --- /dev/null +++ b/libc/nt/ntdll/RtlGetCallersAddress.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetCallersAddress diff --git a/libc/nt/ntdll/RtlGetCompressionWorkSpaceSize.s b/libc/nt/ntdll/RtlGetCompressionWorkSpaceSize.s new file mode 100644 index 00000000..9464e558 --- /dev/null +++ b/libc/nt/ntdll/RtlGetCompressionWorkSpaceSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetCompressionWorkSpaceSize diff --git a/libc/nt/ntdll/RtlGetConsoleSessionForegroundProcessId.s b/libc/nt/ntdll/RtlGetConsoleSessionForegroundProcessId.s new file mode 100644 index 00000000..6cb3f77b --- /dev/null +++ b/libc/nt/ntdll/RtlGetConsoleSessionForegroundProcessId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetConsoleSessionForegroundProcessId diff --git a/libc/nt/ntdll/RtlGetControlSecurityDescriptor.s b/libc/nt/ntdll/RtlGetControlSecurityDescriptor.s new file mode 100644 index 00000000..0bc2977a --- /dev/null +++ b/libc/nt/ntdll/RtlGetControlSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetControlSecurityDescriptor diff --git a/libc/nt/ntdll/RtlGetCriticalSectionRecursionCount.s b/libc/nt/ntdll/RtlGetCriticalSectionRecursionCount.s new file mode 100644 index 00000000..767f7afb --- /dev/null +++ b/libc/nt/ntdll/RtlGetCriticalSectionRecursionCount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetCriticalSectionRecursionCount diff --git a/libc/nt/ntdll/RtlGetCurrentDirectory_U.s b/libc/nt/ntdll/RtlGetCurrentDirectory_U.s new file mode 100644 index 00000000..f43d3707 --- /dev/null +++ b/libc/nt/ntdll/RtlGetCurrentDirectory_U.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetCurrentDirectory_U diff --git a/libc/nt/ntdll/RtlGetCurrentPeb.s b/libc/nt/ntdll/RtlGetCurrentPeb.s new file mode 100644 index 00000000..c632e21f --- /dev/null +++ b/libc/nt/ntdll/RtlGetCurrentPeb.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetCurrentPeb diff --git a/libc/nt/ntdll/RtlGetCurrentProcessorNumber.s b/libc/nt/ntdll/RtlGetCurrentProcessorNumber.s new file mode 100644 index 00000000..2f042d31 --- /dev/null +++ b/libc/nt/ntdll/RtlGetCurrentProcessorNumber.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetCurrentProcessorNumber diff --git a/libc/nt/ntdll/RtlGetCurrentProcessorNumberEx.s b/libc/nt/ntdll/RtlGetCurrentProcessorNumberEx.s new file mode 100644 index 00000000..3a2a7101 --- /dev/null +++ b/libc/nt/ntdll/RtlGetCurrentProcessorNumberEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetCurrentProcessorNumberEx diff --git a/libc/nt/ntdll/RtlGetCurrentServiceSessionId.s b/libc/nt/ntdll/RtlGetCurrentServiceSessionId.s new file mode 100644 index 00000000..cee7ad28 --- /dev/null +++ b/libc/nt/ntdll/RtlGetCurrentServiceSessionId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetCurrentServiceSessionId diff --git a/libc/nt/ntdll/RtlGetCurrentTransaction.s b/libc/nt/ntdll/RtlGetCurrentTransaction.s new file mode 100644 index 00000000..01cb4e0b --- /dev/null +++ b/libc/nt/ntdll/RtlGetCurrentTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetCurrentTransaction diff --git a/libc/nt/ntdll/RtlGetCurrentUmsThread.s b/libc/nt/ntdll/RtlGetCurrentUmsThread.s new file mode 100644 index 00000000..a8d16abc --- /dev/null +++ b/libc/nt/ntdll/RtlGetCurrentUmsThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetCurrentUmsThread diff --git a/libc/nt/ntdll/RtlGetDaclSecurityDescriptor.s b/libc/nt/ntdll/RtlGetDaclSecurityDescriptor.s new file mode 100644 index 00000000..62c9a962 --- /dev/null +++ b/libc/nt/ntdll/RtlGetDaclSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetDaclSecurityDescriptor diff --git a/libc/nt/ntdll/RtlGetDeviceFamilyInfoEnum.s b/libc/nt/ntdll/RtlGetDeviceFamilyInfoEnum.s new file mode 100644 index 00000000..eaa536d4 --- /dev/null +++ b/libc/nt/ntdll/RtlGetDeviceFamilyInfoEnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetDeviceFamilyInfoEnum diff --git a/libc/nt/ntdll/RtlGetElementGenericTable.s b/libc/nt/ntdll/RtlGetElementGenericTable.s new file mode 100644 index 00000000..56387f7a --- /dev/null +++ b/libc/nt/ntdll/RtlGetElementGenericTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetElementGenericTable diff --git a/libc/nt/ntdll/RtlGetElementGenericTableAvl.s b/libc/nt/ntdll/RtlGetElementGenericTableAvl.s new file mode 100644 index 00000000..1da7942e --- /dev/null +++ b/libc/nt/ntdll/RtlGetElementGenericTableAvl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetElementGenericTableAvl diff --git a/libc/nt/ntdll/RtlGetEnabledExtendedFeatures.s b/libc/nt/ntdll/RtlGetEnabledExtendedFeatures.s new file mode 100644 index 00000000..358fd190 --- /dev/null +++ b/libc/nt/ntdll/RtlGetEnabledExtendedFeatures.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetEnabledExtendedFeatures diff --git a/libc/nt/ntdll/RtlGetExePath.s b/libc/nt/ntdll/RtlGetExePath.s new file mode 100644 index 00000000..d860446d --- /dev/null +++ b/libc/nt/ntdll/RtlGetExePath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetExePath diff --git a/libc/nt/ntdll/RtlGetExtendedContextLength.s b/libc/nt/ntdll/RtlGetExtendedContextLength.s new file mode 100644 index 00000000..e6e38e48 --- /dev/null +++ b/libc/nt/ntdll/RtlGetExtendedContextLength.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetExtendedContextLength diff --git a/libc/nt/ntdll/RtlGetExtendedFeaturesMask.s b/libc/nt/ntdll/RtlGetExtendedFeaturesMask.s new file mode 100644 index 00000000..35dccea4 --- /dev/null +++ b/libc/nt/ntdll/RtlGetExtendedFeaturesMask.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetExtendedFeaturesMask diff --git a/libc/nt/ntdll/RtlGetFileMUIPath.s b/libc/nt/ntdll/RtlGetFileMUIPath.s new file mode 100644 index 00000000..1ceb7c2c --- /dev/null +++ b/libc/nt/ntdll/RtlGetFileMUIPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetFileMUIPath diff --git a/libc/nt/ntdll/RtlGetFrame.s b/libc/nt/ntdll/RtlGetFrame.s new file mode 100644 index 00000000..f258cf35 --- /dev/null +++ b/libc/nt/ntdll/RtlGetFrame.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetFrame diff --git a/libc/nt/ntdll/RtlGetFullPathName_U.s b/libc/nt/ntdll/RtlGetFullPathName_U.s new file mode 100644 index 00000000..0129a529 --- /dev/null +++ b/libc/nt/ntdll/RtlGetFullPathName_U.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetFullPathName_U diff --git a/libc/nt/ntdll/RtlGetFullPathName_UEx.s b/libc/nt/ntdll/RtlGetFullPathName_UEx.s new file mode 100644 index 00000000..7fedded3 --- /dev/null +++ b/libc/nt/ntdll/RtlGetFullPathName_UEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetFullPathName_UEx diff --git a/libc/nt/ntdll/RtlGetFullPathName_UstrEx.s b/libc/nt/ntdll/RtlGetFullPathName_UstrEx.s new file mode 100644 index 00000000..38751598 --- /dev/null +++ b/libc/nt/ntdll/RtlGetFullPathName_UstrEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetFullPathName_UstrEx diff --git a/libc/nt/ntdll/RtlGetFunctionTableListHead.s b/libc/nt/ntdll/RtlGetFunctionTableListHead.s new file mode 100644 index 00000000..ab1d6fe4 --- /dev/null +++ b/libc/nt/ntdll/RtlGetFunctionTableListHead.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetFunctionTableListHead diff --git a/libc/nt/ntdll/RtlGetGroupSecurityDescriptor.s b/libc/nt/ntdll/RtlGetGroupSecurityDescriptor.s new file mode 100644 index 00000000..d4c9ec7f --- /dev/null +++ b/libc/nt/ntdll/RtlGetGroupSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetGroupSecurityDescriptor diff --git a/libc/nt/ntdll/RtlGetIntegerAtom.s b/libc/nt/ntdll/RtlGetIntegerAtom.s new file mode 100644 index 00000000..1d066708 --- /dev/null +++ b/libc/nt/ntdll/RtlGetIntegerAtom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetIntegerAtom diff --git a/libc/nt/ntdll/RtlGetInterruptTimePrecise.s b/libc/nt/ntdll/RtlGetInterruptTimePrecise.s new file mode 100644 index 00000000..a7c11767 --- /dev/null +++ b/libc/nt/ntdll/RtlGetInterruptTimePrecise.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetInterruptTimePrecise diff --git a/libc/nt/ntdll/RtlGetLastNtStatus.s b/libc/nt/ntdll/RtlGetLastNtStatus.s new file mode 100644 index 00000000..4541f2e1 --- /dev/null +++ b/libc/nt/ntdll/RtlGetLastNtStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetLastNtStatus diff --git a/libc/nt/ntdll/RtlGetLastWin32Error.s b/libc/nt/ntdll/RtlGetLastWin32Error.s new file mode 100644 index 00000000..6c7e31fb --- /dev/null +++ b/libc/nt/ntdll/RtlGetLastWin32Error.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetLastWin32Error diff --git a/libc/nt/ntdll/RtlGetLengthWithoutLastFullDosOrNtPathElement.s b/libc/nt/ntdll/RtlGetLengthWithoutLastFullDosOrNtPathElement.s new file mode 100644 index 00000000..b036a14c --- /dev/null +++ b/libc/nt/ntdll/RtlGetLengthWithoutLastFullDosOrNtPathElement.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetLengthWithoutLastFullDosOrNtPathElement diff --git a/libc/nt/ntdll/RtlGetLengthWithoutTrailingPathSeperators.s b/libc/nt/ntdll/RtlGetLengthWithoutTrailingPathSeperators.s new file mode 100644 index 00000000..6ddf8ba6 --- /dev/null +++ b/libc/nt/ntdll/RtlGetLengthWithoutTrailingPathSeperators.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetLengthWithoutTrailingPathSeperators diff --git a/libc/nt/ntdll/RtlGetLocaleFileMappingAddress.s b/libc/nt/ntdll/RtlGetLocaleFileMappingAddress.s new file mode 100644 index 00000000..e5345e42 --- /dev/null +++ b/libc/nt/ntdll/RtlGetLocaleFileMappingAddress.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetLocaleFileMappingAddress diff --git a/libc/nt/ntdll/RtlGetLongestNtPathLength.s b/libc/nt/ntdll/RtlGetLongestNtPathLength.s new file mode 100644 index 00000000..6f50b6f5 --- /dev/null +++ b/libc/nt/ntdll/RtlGetLongestNtPathLength.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetLongestNtPathLength diff --git a/libc/nt/ntdll/RtlGetNativeSystemInformation.s b/libc/nt/ntdll/RtlGetNativeSystemInformation.s new file mode 100644 index 00000000..e7b6492f --- /dev/null +++ b/libc/nt/ntdll/RtlGetNativeSystemInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetNativeSystemInformation diff --git a/libc/nt/ntdll/RtlGetNextEntryHashTable.s b/libc/nt/ntdll/RtlGetNextEntryHashTable.s new file mode 100644 index 00000000..e6aff9d8 --- /dev/null +++ b/libc/nt/ntdll/RtlGetNextEntryHashTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetNextEntryHashTable diff --git a/libc/nt/ntdll/RtlGetNextUmsListItem.s b/libc/nt/ntdll/RtlGetNextUmsListItem.s new file mode 100644 index 00000000..ebbd99bb --- /dev/null +++ b/libc/nt/ntdll/RtlGetNextUmsListItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetNextUmsListItem diff --git a/libc/nt/ntdll/RtlGetNonVolatileToken.s b/libc/nt/ntdll/RtlGetNonVolatileToken.s new file mode 100644 index 00000000..d863e122 --- /dev/null +++ b/libc/nt/ntdll/RtlGetNonVolatileToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetNonVolatileToken diff --git a/libc/nt/ntdll/RtlGetNtGlobalFlags.s b/libc/nt/ntdll/RtlGetNtGlobalFlags.s new file mode 100644 index 00000000..110d2566 --- /dev/null +++ b/libc/nt/ntdll/RtlGetNtGlobalFlags.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetNtGlobalFlags diff --git a/libc/nt/ntdll/RtlGetNtProductType.s b/libc/nt/ntdll/RtlGetNtProductType.s new file mode 100644 index 00000000..1d372376 --- /dev/null +++ b/libc/nt/ntdll/RtlGetNtProductType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetNtProductType diff --git a/libc/nt/ntdll/RtlGetNtSystemRoot.s b/libc/nt/ntdll/RtlGetNtSystemRoot.s new file mode 100644 index 00000000..de42357b --- /dev/null +++ b/libc/nt/ntdll/RtlGetNtSystemRoot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetNtSystemRoot diff --git a/libc/nt/ntdll/RtlGetNtVersionNumbers.s b/libc/nt/ntdll/RtlGetNtVersionNumbers.s new file mode 100644 index 00000000..2ffd6a83 --- /dev/null +++ b/libc/nt/ntdll/RtlGetNtVersionNumbers.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetNtVersionNumbers diff --git a/libc/nt/ntdll/RtlGetOwnerSecurityDescriptor.s b/libc/nt/ntdll/RtlGetOwnerSecurityDescriptor.s new file mode 100644 index 00000000..3f58698d --- /dev/null +++ b/libc/nt/ntdll/RtlGetOwnerSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetOwnerSecurityDescriptor diff --git a/libc/nt/ntdll/RtlGetParentLocaleName.s b/libc/nt/ntdll/RtlGetParentLocaleName.s new file mode 100644 index 00000000..f20f9f8c --- /dev/null +++ b/libc/nt/ntdll/RtlGetParentLocaleName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetParentLocaleName diff --git a/libc/nt/ntdll/RtlGetPersistedStateLocation.s b/libc/nt/ntdll/RtlGetPersistedStateLocation.s new file mode 100644 index 00000000..56149970 --- /dev/null +++ b/libc/nt/ntdll/RtlGetPersistedStateLocation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetPersistedStateLocation diff --git a/libc/nt/ntdll/RtlGetProcessHeaps.s b/libc/nt/ntdll/RtlGetProcessHeaps.s new file mode 100644 index 00000000..9a8bd5d4 --- /dev/null +++ b/libc/nt/ntdll/RtlGetProcessHeaps.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetProcessHeaps + + .text.windows +RtlGetProcessHeaps: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RtlGetProcessHeaps(%rip),%rax + jmp __sysv2nt + .endfn RtlGetProcessHeaps,globl + .previous diff --git a/libc/nt/ntdll/RtlGetProcessPreferredUILanguages.s b/libc/nt/ntdll/RtlGetProcessPreferredUILanguages.s new file mode 100644 index 00000000..a86dced1 --- /dev/null +++ b/libc/nt/ntdll/RtlGetProcessPreferredUILanguages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetProcessPreferredUILanguages diff --git a/libc/nt/ntdll/RtlGetProductInfo.s b/libc/nt/ntdll/RtlGetProductInfo.s new file mode 100644 index 00000000..304b1103 --- /dev/null +++ b/libc/nt/ntdll/RtlGetProductInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetProductInfo diff --git a/libc/nt/ntdll/RtlGetSaclSecurityDescriptor.s b/libc/nt/ntdll/RtlGetSaclSecurityDescriptor.s new file mode 100644 index 00000000..25c6e7d2 --- /dev/null +++ b/libc/nt/ntdll/RtlGetSaclSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetSaclSecurityDescriptor diff --git a/libc/nt/ntdll/RtlGetSearchPath.s b/libc/nt/ntdll/RtlGetSearchPath.s new file mode 100644 index 00000000..2b2318d4 --- /dev/null +++ b/libc/nt/ntdll/RtlGetSearchPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetSearchPath diff --git a/libc/nt/ntdll/RtlGetSecurityDescriptorRMControl.s b/libc/nt/ntdll/RtlGetSecurityDescriptorRMControl.s new file mode 100644 index 00000000..c6e5b932 --- /dev/null +++ b/libc/nt/ntdll/RtlGetSecurityDescriptorRMControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetSecurityDescriptorRMControl diff --git a/libc/nt/ntdll/RtlGetSessionProperties.s b/libc/nt/ntdll/RtlGetSessionProperties.s new file mode 100644 index 00000000..d3b3c931 --- /dev/null +++ b/libc/nt/ntdll/RtlGetSessionProperties.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetSessionProperties diff --git a/libc/nt/ntdll/RtlGetSetBootStatusData.s b/libc/nt/ntdll/RtlGetSetBootStatusData.s new file mode 100644 index 00000000..fd7bfa80 --- /dev/null +++ b/libc/nt/ntdll/RtlGetSetBootStatusData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetSetBootStatusData diff --git a/libc/nt/ntdll/RtlGetSuiteMask.s b/libc/nt/ntdll/RtlGetSuiteMask.s new file mode 100644 index 00000000..cec2bcdd --- /dev/null +++ b/libc/nt/ntdll/RtlGetSuiteMask.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetSuiteMask diff --git a/libc/nt/ntdll/RtlGetSystemBootStatus.s b/libc/nt/ntdll/RtlGetSystemBootStatus.s new file mode 100644 index 00000000..7bca62a6 --- /dev/null +++ b/libc/nt/ntdll/RtlGetSystemBootStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetSystemBootStatus diff --git a/libc/nt/ntdll/RtlGetSystemBootStatusEx.s b/libc/nt/ntdll/RtlGetSystemBootStatusEx.s new file mode 100644 index 00000000..6fd2da7f --- /dev/null +++ b/libc/nt/ntdll/RtlGetSystemBootStatusEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetSystemBootStatusEx diff --git a/libc/nt/ntdll/RtlGetSystemPreferredUILanguages.s b/libc/nt/ntdll/RtlGetSystemPreferredUILanguages.s new file mode 100644 index 00000000..293987ed --- /dev/null +++ b/libc/nt/ntdll/RtlGetSystemPreferredUILanguages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetSystemPreferredUILanguages diff --git a/libc/nt/ntdll/RtlGetSystemTimePrecise.s b/libc/nt/ntdll/RtlGetSystemTimePrecise.s new file mode 100644 index 00000000..0f21b014 --- /dev/null +++ b/libc/nt/ntdll/RtlGetSystemTimePrecise.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetSystemTimePrecise diff --git a/libc/nt/ntdll/RtlGetThreadErrorMode.s b/libc/nt/ntdll/RtlGetThreadErrorMode.s new file mode 100644 index 00000000..48656148 --- /dev/null +++ b/libc/nt/ntdll/RtlGetThreadErrorMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetThreadErrorMode diff --git a/libc/nt/ntdll/RtlGetThreadLangIdByIndex.s b/libc/nt/ntdll/RtlGetThreadLangIdByIndex.s new file mode 100644 index 00000000..341f43aa --- /dev/null +++ b/libc/nt/ntdll/RtlGetThreadLangIdByIndex.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetThreadLangIdByIndex diff --git a/libc/nt/ntdll/RtlGetThreadPreferredUILanguages.s b/libc/nt/ntdll/RtlGetThreadPreferredUILanguages.s new file mode 100644 index 00000000..69ac8fd9 --- /dev/null +++ b/libc/nt/ntdll/RtlGetThreadPreferredUILanguages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetThreadPreferredUILanguages diff --git a/libc/nt/ntdll/RtlGetThreadWorkOnBehalfTicket.s b/libc/nt/ntdll/RtlGetThreadWorkOnBehalfTicket.s new file mode 100644 index 00000000..cd67965e --- /dev/null +++ b/libc/nt/ntdll/RtlGetThreadWorkOnBehalfTicket.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetThreadWorkOnBehalfTicket diff --git a/libc/nt/ntdll/RtlGetTokenNamedObjectPath.s b/libc/nt/ntdll/RtlGetTokenNamedObjectPath.s new file mode 100644 index 00000000..86d8a5db --- /dev/null +++ b/libc/nt/ntdll/RtlGetTokenNamedObjectPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetTokenNamedObjectPath diff --git a/libc/nt/ntdll/RtlGetUILanguageInfo.s b/libc/nt/ntdll/RtlGetUILanguageInfo.s new file mode 100644 index 00000000..481534bf --- /dev/null +++ b/libc/nt/ntdll/RtlGetUILanguageInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetUILanguageInfo diff --git a/libc/nt/ntdll/RtlGetUmsCompletionListEvent.s b/libc/nt/ntdll/RtlGetUmsCompletionListEvent.s new file mode 100644 index 00000000..30eb6bde --- /dev/null +++ b/libc/nt/ntdll/RtlGetUmsCompletionListEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetUmsCompletionListEvent diff --git a/libc/nt/ntdll/RtlGetUnloadEventTrace.s b/libc/nt/ntdll/RtlGetUnloadEventTrace.s new file mode 100644 index 00000000..ed07213b --- /dev/null +++ b/libc/nt/ntdll/RtlGetUnloadEventTrace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetUnloadEventTrace diff --git a/libc/nt/ntdll/RtlGetUnloadEventTraceEx.s b/libc/nt/ntdll/RtlGetUnloadEventTraceEx.s new file mode 100644 index 00000000..b787d287 --- /dev/null +++ b/libc/nt/ntdll/RtlGetUnloadEventTraceEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetUnloadEventTraceEx diff --git a/libc/nt/ntdll/RtlGetUserInfoHeap.s b/libc/nt/ntdll/RtlGetUserInfoHeap.s new file mode 100644 index 00000000..c4da8e85 --- /dev/null +++ b/libc/nt/ntdll/RtlGetUserInfoHeap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetUserInfoHeap diff --git a/libc/nt/ntdll/RtlGetUserPreferredUILanguages.s b/libc/nt/ntdll/RtlGetUserPreferredUILanguages.s new file mode 100644 index 00000000..ad1a0b5d --- /dev/null +++ b/libc/nt/ntdll/RtlGetUserPreferredUILanguages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetUserPreferredUILanguages diff --git a/libc/nt/ntdll/RtlGetVersion.s b/libc/nt/ntdll/RtlGetVersion.s new file mode 100644 index 00000000..ee181564 --- /dev/null +++ b/libc/nt/ntdll/RtlGetVersion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGetVersion diff --git a/libc/nt/ntdll/RtlGrowFunctionTable.s b/libc/nt/ntdll/RtlGrowFunctionTable.s new file mode 100644 index 00000000..1ec35ad3 --- /dev/null +++ b/libc/nt/ntdll/RtlGrowFunctionTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGrowFunctionTable diff --git a/libc/nt/ntdll/RtlGuardCheckLongJumpTarget.s b/libc/nt/ntdll/RtlGuardCheckLongJumpTarget.s new file mode 100644 index 00000000..e3b7721f --- /dev/null +++ b/libc/nt/ntdll/RtlGuardCheckLongJumpTarget.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlGuardCheckLongJumpTarget diff --git a/libc/nt/ntdll/RtlHashUnicodeString.s b/libc/nt/ntdll/RtlHashUnicodeString.s new file mode 100644 index 00000000..b954dc60 --- /dev/null +++ b/libc/nt/ntdll/RtlHashUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlHashUnicodeString diff --git a/libc/nt/ntdll/RtlHeapTrkInitialize.s b/libc/nt/ntdll/RtlHeapTrkInitialize.s new file mode 100644 index 00000000..fd8a57b7 --- /dev/null +++ b/libc/nt/ntdll/RtlHeapTrkInitialize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlHeapTrkInitialize diff --git a/libc/nt/ntdll/RtlIdentifierAuthoritySid.s b/libc/nt/ntdll/RtlIdentifierAuthoritySid.s new file mode 100644 index 00000000..ce5af8f1 --- /dev/null +++ b/libc/nt/ntdll/RtlIdentifierAuthoritySid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIdentifierAuthoritySid diff --git a/libc/nt/ntdll/RtlIdnToAscii.s b/libc/nt/ntdll/RtlIdnToAscii.s new file mode 100644 index 00000000..e0d02429 --- /dev/null +++ b/libc/nt/ntdll/RtlIdnToAscii.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIdnToAscii diff --git a/libc/nt/ntdll/RtlIdnToNameprepUnicode.s b/libc/nt/ntdll/RtlIdnToNameprepUnicode.s new file mode 100644 index 00000000..4debbf7f --- /dev/null +++ b/libc/nt/ntdll/RtlIdnToNameprepUnicode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIdnToNameprepUnicode diff --git a/libc/nt/ntdll/RtlIdnToUnicode.s b/libc/nt/ntdll/RtlIdnToUnicode.s new file mode 100644 index 00000000..ca49fd76 --- /dev/null +++ b/libc/nt/ntdll/RtlIdnToUnicode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIdnToUnicode diff --git a/libc/nt/ntdll/RtlImageDirectoryEntryToData.s b/libc/nt/ntdll/RtlImageDirectoryEntryToData.s new file mode 100644 index 00000000..da91a162 --- /dev/null +++ b/libc/nt/ntdll/RtlImageDirectoryEntryToData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlImageDirectoryEntryToData diff --git a/libc/nt/ntdll/RtlImageNtHeader.s b/libc/nt/ntdll/RtlImageNtHeader.s new file mode 100644 index 00000000..9739f93e --- /dev/null +++ b/libc/nt/ntdll/RtlImageNtHeader.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlImageNtHeader diff --git a/libc/nt/ntdll/RtlImageNtHeaderEx.s b/libc/nt/ntdll/RtlImageNtHeaderEx.s new file mode 100644 index 00000000..3548ca64 --- /dev/null +++ b/libc/nt/ntdll/RtlImageNtHeaderEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlImageNtHeaderEx diff --git a/libc/nt/ntdll/RtlImageRvaToSection.s b/libc/nt/ntdll/RtlImageRvaToSection.s new file mode 100644 index 00000000..9526f541 --- /dev/null +++ b/libc/nt/ntdll/RtlImageRvaToSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlImageRvaToSection diff --git a/libc/nt/ntdll/RtlImageRvaToVa.s b/libc/nt/ntdll/RtlImageRvaToVa.s new file mode 100644 index 00000000..f668f705 --- /dev/null +++ b/libc/nt/ntdll/RtlImageRvaToVa.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlImageRvaToVa diff --git a/libc/nt/ntdll/RtlImpersonateSelf.s b/libc/nt/ntdll/RtlImpersonateSelf.s new file mode 100644 index 00000000..c454e400 --- /dev/null +++ b/libc/nt/ntdll/RtlImpersonateSelf.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlImpersonateSelf diff --git a/libc/nt/ntdll/RtlImpersonateSelfEx.s b/libc/nt/ntdll/RtlImpersonateSelfEx.s new file mode 100644 index 00000000..99d31a3f --- /dev/null +++ b/libc/nt/ntdll/RtlImpersonateSelfEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlImpersonateSelfEx diff --git a/libc/nt/ntdll/RtlIncrementCorrelationVector.s b/libc/nt/ntdll/RtlIncrementCorrelationVector.s new file mode 100644 index 00000000..772388e1 --- /dev/null +++ b/libc/nt/ntdll/RtlIncrementCorrelationVector.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIncrementCorrelationVector diff --git a/libc/nt/ntdll/RtlInitAnsiString.s b/libc/nt/ntdll/RtlInitAnsiString.s new file mode 100644 index 00000000..c6b25e88 --- /dev/null +++ b/libc/nt/ntdll/RtlInitAnsiString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitAnsiString diff --git a/libc/nt/ntdll/RtlInitAnsiStringEx.s b/libc/nt/ntdll/RtlInitAnsiStringEx.s new file mode 100644 index 00000000..29baef6e --- /dev/null +++ b/libc/nt/ntdll/RtlInitAnsiStringEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitAnsiStringEx diff --git a/libc/nt/ntdll/RtlInitBarrier.s b/libc/nt/ntdll/RtlInitBarrier.s new file mode 100644 index 00000000..6a40a401 --- /dev/null +++ b/libc/nt/ntdll/RtlInitBarrier.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitBarrier diff --git a/libc/nt/ntdll/RtlInitCodePageTable.s b/libc/nt/ntdll/RtlInitCodePageTable.s new file mode 100644 index 00000000..dab1e800 --- /dev/null +++ b/libc/nt/ntdll/RtlInitCodePageTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitCodePageTable diff --git a/libc/nt/ntdll/RtlInitEnumerationHashTable.s b/libc/nt/ntdll/RtlInitEnumerationHashTable.s new file mode 100644 index 00000000..c6b75b9b --- /dev/null +++ b/libc/nt/ntdll/RtlInitEnumerationHashTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitEnumerationHashTable diff --git a/libc/nt/ntdll/RtlInitMemoryStream.s b/libc/nt/ntdll/RtlInitMemoryStream.s new file mode 100644 index 00000000..e3b4374d --- /dev/null +++ b/libc/nt/ntdll/RtlInitMemoryStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitMemoryStream diff --git a/libc/nt/ntdll/RtlInitNlsTables.s b/libc/nt/ntdll/RtlInitNlsTables.s new file mode 100644 index 00000000..6d6cf8b5 --- /dev/null +++ b/libc/nt/ntdll/RtlInitNlsTables.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitNlsTables diff --git a/libc/nt/ntdll/RtlInitOutOfProcessMemoryStream.s b/libc/nt/ntdll/RtlInitOutOfProcessMemoryStream.s new file mode 100644 index 00000000..098c3cb2 --- /dev/null +++ b/libc/nt/ntdll/RtlInitOutOfProcessMemoryStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitOutOfProcessMemoryStream diff --git a/libc/nt/ntdll/RtlInitString.s b/libc/nt/ntdll/RtlInitString.s new file mode 100644 index 00000000..cdcda32e --- /dev/null +++ b/libc/nt/ntdll/RtlInitString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitString diff --git a/libc/nt/ntdll/RtlInitStringEx.s b/libc/nt/ntdll/RtlInitStringEx.s new file mode 100644 index 00000000..87ee7fae --- /dev/null +++ b/libc/nt/ntdll/RtlInitStringEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitStringEx diff --git a/libc/nt/ntdll/RtlInitStrongEnumerationHashTable.s b/libc/nt/ntdll/RtlInitStrongEnumerationHashTable.s new file mode 100644 index 00000000..0da7c1ff --- /dev/null +++ b/libc/nt/ntdll/RtlInitStrongEnumerationHashTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitStrongEnumerationHashTable diff --git a/libc/nt/ntdll/RtlInitUnicodeString.s b/libc/nt/ntdll/RtlInitUnicodeString.s new file mode 100644 index 00000000..85266a53 --- /dev/null +++ b/libc/nt/ntdll/RtlInitUnicodeString.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitUnicodeString + + .text.windows +RtlInitUnicodeString: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RtlInitUnicodeString(%rip),%rax + jmp __sysv2nt + .endfn RtlInitUnicodeString,globl + .previous diff --git a/libc/nt/ntdll/RtlInitUnicodeStringEx.s b/libc/nt/ntdll/RtlInitUnicodeStringEx.s new file mode 100644 index 00000000..f5480467 --- /dev/null +++ b/libc/nt/ntdll/RtlInitUnicodeStringEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitUnicodeStringEx diff --git a/libc/nt/ntdll/RtlInitWeakEnumerationHashTable.s b/libc/nt/ntdll/RtlInitWeakEnumerationHashTable.s new file mode 100644 index 00000000..681f5506 --- /dev/null +++ b/libc/nt/ntdll/RtlInitWeakEnumerationHashTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitWeakEnumerationHashTable diff --git a/libc/nt/ntdll/RtlInitializeAtomPackage.s b/libc/nt/ntdll/RtlInitializeAtomPackage.s new file mode 100644 index 00000000..039e75c5 --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeAtomPackage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeAtomPackage diff --git a/libc/nt/ntdll/RtlInitializeBitMap.s b/libc/nt/ntdll/RtlInitializeBitMap.s new file mode 100644 index 00000000..0b537af8 --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeBitMap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeBitMap diff --git a/libc/nt/ntdll/RtlInitializeBitMapEx.s b/libc/nt/ntdll/RtlInitializeBitMapEx.s new file mode 100644 index 00000000..a7d2497f --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeBitMapEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeBitMapEx diff --git a/libc/nt/ntdll/RtlInitializeConditionVariable.s b/libc/nt/ntdll/RtlInitializeConditionVariable.s new file mode 100644 index 00000000..14bbe537 --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeConditionVariable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeConditionVariable diff --git a/libc/nt/ntdll/RtlInitializeContext.s b/libc/nt/ntdll/RtlInitializeContext.s new file mode 100644 index 00000000..7af6e620 --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeContext diff --git a/libc/nt/ntdll/RtlInitializeCorrelationVector.s b/libc/nt/ntdll/RtlInitializeCorrelationVector.s new file mode 100644 index 00000000..99b8a724 --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeCorrelationVector.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeCorrelationVector diff --git a/libc/nt/ntdll/RtlInitializeCriticalSection.s b/libc/nt/ntdll/RtlInitializeCriticalSection.s new file mode 100644 index 00000000..576f3431 --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeCriticalSection.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeCriticalSection + + .text.windows +RtlInitializeCriticalSection: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RtlInitializeCriticalSection(%rip) + leave + ret + .endfn RtlInitializeCriticalSection,globl + .previous diff --git a/libc/nt/ntdll/RtlInitializeCriticalSectionAndSpinCount.s b/libc/nt/ntdll/RtlInitializeCriticalSectionAndSpinCount.s new file mode 100644 index 00000000..56bfe7d3 --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeCriticalSectionAndSpinCount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeCriticalSectionAndSpinCount diff --git a/libc/nt/ntdll/RtlInitializeCriticalSectionEx.s b/libc/nt/ntdll/RtlInitializeCriticalSectionEx.s new file mode 100644 index 00000000..eda71579 --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeCriticalSectionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeCriticalSectionEx diff --git a/libc/nt/ntdll/RtlInitializeExtendedContext.s b/libc/nt/ntdll/RtlInitializeExtendedContext.s new file mode 100644 index 00000000..47b9aa7d --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeExtendedContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeExtendedContext diff --git a/libc/nt/ntdll/RtlInitializeGenericTable.s b/libc/nt/ntdll/RtlInitializeGenericTable.s new file mode 100644 index 00000000..950594ce --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeGenericTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeGenericTable diff --git a/libc/nt/ntdll/RtlInitializeGenericTableAvl.s b/libc/nt/ntdll/RtlInitializeGenericTableAvl.s new file mode 100644 index 00000000..a2c862d5 --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeGenericTableAvl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeGenericTableAvl diff --git a/libc/nt/ntdll/RtlInitializeHandleTable.s b/libc/nt/ntdll/RtlInitializeHandleTable.s new file mode 100644 index 00000000..a56dae1e --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeHandleTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeHandleTable diff --git a/libc/nt/ntdll/RtlInitializeNtUserPfn.s b/libc/nt/ntdll/RtlInitializeNtUserPfn.s new file mode 100644 index 00000000..ac188095 --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeNtUserPfn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeNtUserPfn diff --git a/libc/nt/ntdll/RtlInitializeRXact.s b/libc/nt/ntdll/RtlInitializeRXact.s new file mode 100644 index 00000000..8a56bbb2 --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeRXact.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeRXact diff --git a/libc/nt/ntdll/RtlInitializeResource.s b/libc/nt/ntdll/RtlInitializeResource.s new file mode 100644 index 00000000..fd323829 --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeResource diff --git a/libc/nt/ntdll/RtlInitializeSListHead.s b/libc/nt/ntdll/RtlInitializeSListHead.s new file mode 100644 index 00000000..39cc1081 --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeSListHead.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeSListHead diff --git a/libc/nt/ntdll/RtlInitializeSRWLock.s b/libc/nt/ntdll/RtlInitializeSRWLock.s new file mode 100644 index 00000000..8dbf5288 --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeSRWLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeSRWLock diff --git a/libc/nt/ntdll/RtlInitializeSid.s b/libc/nt/ntdll/RtlInitializeSid.s new file mode 100644 index 00000000..70b82af9 --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeSid diff --git a/libc/nt/ntdll/RtlInitializeSidEx.s b/libc/nt/ntdll/RtlInitializeSidEx.s new file mode 100644 index 00000000..59772352 --- /dev/null +++ b/libc/nt/ntdll/RtlInitializeSidEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInitializeSidEx diff --git a/libc/nt/ntdll/RtlInsertElementGenericTable.s b/libc/nt/ntdll/RtlInsertElementGenericTable.s new file mode 100644 index 00000000..2eff4c86 --- /dev/null +++ b/libc/nt/ntdll/RtlInsertElementGenericTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInsertElementGenericTable diff --git a/libc/nt/ntdll/RtlInsertElementGenericTableAvl.s b/libc/nt/ntdll/RtlInsertElementGenericTableAvl.s new file mode 100644 index 00000000..cd3ab4ee --- /dev/null +++ b/libc/nt/ntdll/RtlInsertElementGenericTableAvl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInsertElementGenericTableAvl diff --git a/libc/nt/ntdll/RtlInsertElementGenericTableFull.s b/libc/nt/ntdll/RtlInsertElementGenericTableFull.s new file mode 100644 index 00000000..a2f25871 --- /dev/null +++ b/libc/nt/ntdll/RtlInsertElementGenericTableFull.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInsertElementGenericTableFull diff --git a/libc/nt/ntdll/RtlInsertElementGenericTableFullAvl.s b/libc/nt/ntdll/RtlInsertElementGenericTableFullAvl.s new file mode 100644 index 00000000..9d636bc6 --- /dev/null +++ b/libc/nt/ntdll/RtlInsertElementGenericTableFullAvl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInsertElementGenericTableFullAvl diff --git a/libc/nt/ntdll/RtlInsertEntryHashTable.s b/libc/nt/ntdll/RtlInsertEntryHashTable.s new file mode 100644 index 00000000..8ea4a0e2 --- /dev/null +++ b/libc/nt/ntdll/RtlInsertEntryHashTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInsertEntryHashTable diff --git a/libc/nt/ntdll/RtlInstallFunctionTableCallback.s b/libc/nt/ntdll/RtlInstallFunctionTableCallback.s new file mode 100644 index 00000000..10a32f98 --- /dev/null +++ b/libc/nt/ntdll/RtlInstallFunctionTableCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInstallFunctionTableCallback diff --git a/libc/nt/ntdll/RtlInt64ToUnicodeString.s b/libc/nt/ntdll/RtlInt64ToUnicodeString.s new file mode 100644 index 00000000..53085fac --- /dev/null +++ b/libc/nt/ntdll/RtlInt64ToUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInt64ToUnicodeString diff --git a/libc/nt/ntdll/RtlIntegerToChar.s b/libc/nt/ntdll/RtlIntegerToChar.s new file mode 100644 index 00000000..e676d63b --- /dev/null +++ b/libc/nt/ntdll/RtlIntegerToChar.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIntegerToChar diff --git a/libc/nt/ntdll/RtlIntegerToUnicodeString.s b/libc/nt/ntdll/RtlIntegerToUnicodeString.s new file mode 100644 index 00000000..6262178b --- /dev/null +++ b/libc/nt/ntdll/RtlIntegerToUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIntegerToUnicodeString diff --git a/libc/nt/ntdll/RtlInterlockedClearBitRun.s b/libc/nt/ntdll/RtlInterlockedClearBitRun.s new file mode 100644 index 00000000..0ac15d82 --- /dev/null +++ b/libc/nt/ntdll/RtlInterlockedClearBitRun.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInterlockedClearBitRun diff --git a/libc/nt/ntdll/RtlInterlockedFlushSList.s b/libc/nt/ntdll/RtlInterlockedFlushSList.s new file mode 100644 index 00000000..b52ec14d --- /dev/null +++ b/libc/nt/ntdll/RtlInterlockedFlushSList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInterlockedFlushSList diff --git a/libc/nt/ntdll/RtlInterlockedPopEntrySList.s b/libc/nt/ntdll/RtlInterlockedPopEntrySList.s new file mode 100644 index 00000000..7fda408e --- /dev/null +++ b/libc/nt/ntdll/RtlInterlockedPopEntrySList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInterlockedPopEntrySList diff --git a/libc/nt/ntdll/RtlInterlockedPushEntrySList.s b/libc/nt/ntdll/RtlInterlockedPushEntrySList.s new file mode 100644 index 00000000..dbc3bf82 --- /dev/null +++ b/libc/nt/ntdll/RtlInterlockedPushEntrySList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInterlockedPushEntrySList diff --git a/libc/nt/ntdll/RtlInterlockedPushListSList.s b/libc/nt/ntdll/RtlInterlockedPushListSList.s new file mode 100644 index 00000000..0166e161 --- /dev/null +++ b/libc/nt/ntdll/RtlInterlockedPushListSList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInterlockedPushListSList diff --git a/libc/nt/ntdll/RtlInterlockedPushListSListEx.s b/libc/nt/ntdll/RtlInterlockedPushListSListEx.s new file mode 100644 index 00000000..3b75d4dc --- /dev/null +++ b/libc/nt/ntdll/RtlInterlockedPushListSListEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInterlockedPushListSListEx diff --git a/libc/nt/ntdll/RtlInterlockedSetBitRun.s b/libc/nt/ntdll/RtlInterlockedSetBitRun.s new file mode 100644 index 00000000..c75552a7 --- /dev/null +++ b/libc/nt/ntdll/RtlInterlockedSetBitRun.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlInterlockedSetBitRun diff --git a/libc/nt/ntdll/RtlIoDecodeMemIoResource.s b/libc/nt/ntdll/RtlIoDecodeMemIoResource.s new file mode 100644 index 00000000..7afd2012 --- /dev/null +++ b/libc/nt/ntdll/RtlIoDecodeMemIoResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIoDecodeMemIoResource diff --git a/libc/nt/ntdll/RtlIoEncodeMemIoResource.s b/libc/nt/ntdll/RtlIoEncodeMemIoResource.s new file mode 100644 index 00000000..8b5a070c --- /dev/null +++ b/libc/nt/ntdll/RtlIoEncodeMemIoResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIoEncodeMemIoResource diff --git a/libc/nt/ntdll/RtlIpv4AddressToStringA.s b/libc/nt/ntdll/RtlIpv4AddressToStringA.s new file mode 100644 index 00000000..c9f6fe8b --- /dev/null +++ b/libc/nt/ntdll/RtlIpv4AddressToStringA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIpv4AddressToStringA diff --git a/libc/nt/ntdll/RtlIpv4AddressToStringExA.s b/libc/nt/ntdll/RtlIpv4AddressToStringExA.s new file mode 100644 index 00000000..4184755e --- /dev/null +++ b/libc/nt/ntdll/RtlIpv4AddressToStringExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIpv4AddressToStringExA diff --git a/libc/nt/ntdll/RtlIpv4AddressToStringExW.s b/libc/nt/ntdll/RtlIpv4AddressToStringExW.s new file mode 100644 index 00000000..c8cb2523 --- /dev/null +++ b/libc/nt/ntdll/RtlIpv4AddressToStringExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIpv4AddressToStringExW diff --git a/libc/nt/ntdll/RtlIpv4AddressToStringW.s b/libc/nt/ntdll/RtlIpv4AddressToStringW.s new file mode 100644 index 00000000..ce709d2d --- /dev/null +++ b/libc/nt/ntdll/RtlIpv4AddressToStringW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIpv4AddressToStringW diff --git a/libc/nt/ntdll/RtlIpv4StringToAddressA.s b/libc/nt/ntdll/RtlIpv4StringToAddressA.s new file mode 100644 index 00000000..010e104b --- /dev/null +++ b/libc/nt/ntdll/RtlIpv4StringToAddressA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIpv4StringToAddressA diff --git a/libc/nt/ntdll/RtlIpv4StringToAddressExA.s b/libc/nt/ntdll/RtlIpv4StringToAddressExA.s new file mode 100644 index 00000000..d8714c93 --- /dev/null +++ b/libc/nt/ntdll/RtlIpv4StringToAddressExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIpv4StringToAddressExA diff --git a/libc/nt/ntdll/RtlIpv4StringToAddressExW.s b/libc/nt/ntdll/RtlIpv4StringToAddressExW.s new file mode 100644 index 00000000..8eb237b7 --- /dev/null +++ b/libc/nt/ntdll/RtlIpv4StringToAddressExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIpv4StringToAddressExW diff --git a/libc/nt/ntdll/RtlIpv4StringToAddressW.s b/libc/nt/ntdll/RtlIpv4StringToAddressW.s new file mode 100644 index 00000000..6d75229c --- /dev/null +++ b/libc/nt/ntdll/RtlIpv4StringToAddressW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIpv4StringToAddressW diff --git a/libc/nt/ntdll/RtlIpv6AddressToStringA.s b/libc/nt/ntdll/RtlIpv6AddressToStringA.s new file mode 100644 index 00000000..6e61b445 --- /dev/null +++ b/libc/nt/ntdll/RtlIpv6AddressToStringA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIpv6AddressToStringA diff --git a/libc/nt/ntdll/RtlIpv6AddressToStringExA.s b/libc/nt/ntdll/RtlIpv6AddressToStringExA.s new file mode 100644 index 00000000..c543f766 --- /dev/null +++ b/libc/nt/ntdll/RtlIpv6AddressToStringExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIpv6AddressToStringExA diff --git a/libc/nt/ntdll/RtlIpv6AddressToStringExW.s b/libc/nt/ntdll/RtlIpv6AddressToStringExW.s new file mode 100644 index 00000000..4b7e0194 --- /dev/null +++ b/libc/nt/ntdll/RtlIpv6AddressToStringExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIpv6AddressToStringExW diff --git a/libc/nt/ntdll/RtlIpv6AddressToStringW.s b/libc/nt/ntdll/RtlIpv6AddressToStringW.s new file mode 100644 index 00000000..9b7ab393 --- /dev/null +++ b/libc/nt/ntdll/RtlIpv6AddressToStringW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIpv6AddressToStringW diff --git a/libc/nt/ntdll/RtlIpv6StringToAddressA.s b/libc/nt/ntdll/RtlIpv6StringToAddressA.s new file mode 100644 index 00000000..ecebc8a4 --- /dev/null +++ b/libc/nt/ntdll/RtlIpv6StringToAddressA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIpv6StringToAddressA diff --git a/libc/nt/ntdll/RtlIpv6StringToAddressExA.s b/libc/nt/ntdll/RtlIpv6StringToAddressExA.s new file mode 100644 index 00000000..14b73d8d --- /dev/null +++ b/libc/nt/ntdll/RtlIpv6StringToAddressExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIpv6StringToAddressExA diff --git a/libc/nt/ntdll/RtlIpv6StringToAddressExW.s b/libc/nt/ntdll/RtlIpv6StringToAddressExW.s new file mode 100644 index 00000000..14ced44e --- /dev/null +++ b/libc/nt/ntdll/RtlIpv6StringToAddressExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIpv6StringToAddressExW diff --git a/libc/nt/ntdll/RtlIpv6StringToAddressW.s b/libc/nt/ntdll/RtlIpv6StringToAddressW.s new file mode 100644 index 00000000..d73004d0 --- /dev/null +++ b/libc/nt/ntdll/RtlIpv6StringToAddressW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIpv6StringToAddressW diff --git a/libc/nt/ntdll/RtlIsActivationContextActive.s b/libc/nt/ntdll/RtlIsActivationContextActive.s new file mode 100644 index 00000000..c26a808e --- /dev/null +++ b/libc/nt/ntdll/RtlIsActivationContextActive.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsActivationContextActive diff --git a/libc/nt/ntdll/RtlIsCapabilitySid.s b/libc/nt/ntdll/RtlIsCapabilitySid.s new file mode 100644 index 00000000..5d2afb3e --- /dev/null +++ b/libc/nt/ntdll/RtlIsCapabilitySid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsCapabilitySid diff --git a/libc/nt/ntdll/RtlIsCloudFilesPlaceholder.s b/libc/nt/ntdll/RtlIsCloudFilesPlaceholder.s new file mode 100644 index 00000000..adff94f5 --- /dev/null +++ b/libc/nt/ntdll/RtlIsCloudFilesPlaceholder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsCloudFilesPlaceholder diff --git a/libc/nt/ntdll/RtlIsCriticalSectionLocked.s b/libc/nt/ntdll/RtlIsCriticalSectionLocked.s new file mode 100644 index 00000000..6c9fa461 --- /dev/null +++ b/libc/nt/ntdll/RtlIsCriticalSectionLocked.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsCriticalSectionLocked diff --git a/libc/nt/ntdll/RtlIsCriticalSectionLockedByThread.s b/libc/nt/ntdll/RtlIsCriticalSectionLockedByThread.s new file mode 100644 index 00000000..cb1750f9 --- /dev/null +++ b/libc/nt/ntdll/RtlIsCriticalSectionLockedByThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsCriticalSectionLockedByThread diff --git a/libc/nt/ntdll/RtlIsCurrentProcess.s b/libc/nt/ntdll/RtlIsCurrentProcess.s new file mode 100644 index 00000000..5b6f17cc --- /dev/null +++ b/libc/nt/ntdll/RtlIsCurrentProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsCurrentProcess diff --git a/libc/nt/ntdll/RtlIsCurrentThread.s b/libc/nt/ntdll/RtlIsCurrentThread.s new file mode 100644 index 00000000..4eed8e2f --- /dev/null +++ b/libc/nt/ntdll/RtlIsCurrentThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsCurrentThread diff --git a/libc/nt/ntdll/RtlIsCurrentThreadAttachExempt.s b/libc/nt/ntdll/RtlIsCurrentThreadAttachExempt.s new file mode 100644 index 00000000..f2592c75 --- /dev/null +++ b/libc/nt/ntdll/RtlIsCurrentThreadAttachExempt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsCurrentThreadAttachExempt diff --git a/libc/nt/ntdll/RtlIsDosDeviceName_U.s b/libc/nt/ntdll/RtlIsDosDeviceName_U.s new file mode 100644 index 00000000..5fcc50f6 --- /dev/null +++ b/libc/nt/ntdll/RtlIsDosDeviceName_U.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsDosDeviceName_U diff --git a/libc/nt/ntdll/RtlIsElevatedRid.s b/libc/nt/ntdll/RtlIsElevatedRid.s new file mode 100644 index 00000000..0c3ff453 --- /dev/null +++ b/libc/nt/ntdll/RtlIsElevatedRid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsElevatedRid diff --git a/libc/nt/ntdll/RtlIsGenericTableEmpty.s b/libc/nt/ntdll/RtlIsGenericTableEmpty.s new file mode 100644 index 00000000..640716a0 --- /dev/null +++ b/libc/nt/ntdll/RtlIsGenericTableEmpty.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsGenericTableEmpty diff --git a/libc/nt/ntdll/RtlIsGenericTableEmptyAvl.s b/libc/nt/ntdll/RtlIsGenericTableEmptyAvl.s new file mode 100644 index 00000000..7d3f533b --- /dev/null +++ b/libc/nt/ntdll/RtlIsGenericTableEmptyAvl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsGenericTableEmptyAvl diff --git a/libc/nt/ntdll/RtlIsMultiSessionSku.s b/libc/nt/ntdll/RtlIsMultiSessionSku.s new file mode 100644 index 00000000..d6cbd112 --- /dev/null +++ b/libc/nt/ntdll/RtlIsMultiSessionSku.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsMultiSessionSku diff --git a/libc/nt/ntdll/RtlIsMultiUsersInSessionSku.s b/libc/nt/ntdll/RtlIsMultiUsersInSessionSku.s new file mode 100644 index 00000000..cd6840d6 --- /dev/null +++ b/libc/nt/ntdll/RtlIsMultiUsersInSessionSku.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsMultiUsersInSessionSku diff --git a/libc/nt/ntdll/RtlIsNameInExpression.s b/libc/nt/ntdll/RtlIsNameInExpression.s new file mode 100644 index 00000000..a9ed2c3e --- /dev/null +++ b/libc/nt/ntdll/RtlIsNameInExpression.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsNameInExpression diff --git a/libc/nt/ntdll/RtlIsNameInUnUpcasedExpression.s b/libc/nt/ntdll/RtlIsNameInUnUpcasedExpression.s new file mode 100644 index 00000000..54637c91 --- /dev/null +++ b/libc/nt/ntdll/RtlIsNameInUnUpcasedExpression.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsNameInUnUpcasedExpression diff --git a/libc/nt/ntdll/RtlIsNameLegalDOS8Dot3.s b/libc/nt/ntdll/RtlIsNameLegalDOS8Dot3.s new file mode 100644 index 00000000..f07dca64 --- /dev/null +++ b/libc/nt/ntdll/RtlIsNameLegalDOS8Dot3.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsNameLegalDOS8Dot3 diff --git a/libc/nt/ntdll/RtlIsNonEmptyDirectoryReparsePointAllowed.s b/libc/nt/ntdll/RtlIsNonEmptyDirectoryReparsePointAllowed.s new file mode 100644 index 00000000..0b114ee6 --- /dev/null +++ b/libc/nt/ntdll/RtlIsNonEmptyDirectoryReparsePointAllowed.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsNonEmptyDirectoryReparsePointAllowed diff --git a/libc/nt/ntdll/RtlIsNormalizedString.s b/libc/nt/ntdll/RtlIsNormalizedString.s new file mode 100644 index 00000000..0f5a3090 --- /dev/null +++ b/libc/nt/ntdll/RtlIsNormalizedString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsNormalizedString diff --git a/libc/nt/ntdll/RtlIsPackageSid.s b/libc/nt/ntdll/RtlIsPackageSid.s new file mode 100644 index 00000000..518715cf --- /dev/null +++ b/libc/nt/ntdll/RtlIsPackageSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsPackageSid diff --git a/libc/nt/ntdll/RtlIsParentOfChildAppContainer.s b/libc/nt/ntdll/RtlIsParentOfChildAppContainer.s new file mode 100644 index 00000000..47d762e9 --- /dev/null +++ b/libc/nt/ntdll/RtlIsParentOfChildAppContainer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsParentOfChildAppContainer diff --git a/libc/nt/ntdll/RtlIsPartialPlaceholder.s b/libc/nt/ntdll/RtlIsPartialPlaceholder.s new file mode 100644 index 00000000..88efadf3 --- /dev/null +++ b/libc/nt/ntdll/RtlIsPartialPlaceholder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsPartialPlaceholder diff --git a/libc/nt/ntdll/RtlIsPartialPlaceholderFileHandle.s b/libc/nt/ntdll/RtlIsPartialPlaceholderFileHandle.s new file mode 100644 index 00000000..30f729d3 --- /dev/null +++ b/libc/nt/ntdll/RtlIsPartialPlaceholderFileHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsPartialPlaceholderFileHandle diff --git a/libc/nt/ntdll/RtlIsPartialPlaceholderFileInfo.s b/libc/nt/ntdll/RtlIsPartialPlaceholderFileInfo.s new file mode 100644 index 00000000..41d3d8bc --- /dev/null +++ b/libc/nt/ntdll/RtlIsPartialPlaceholderFileInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsPartialPlaceholderFileInfo diff --git a/libc/nt/ntdll/RtlIsProcessorFeaturePresent.s b/libc/nt/ntdll/RtlIsProcessorFeaturePresent.s new file mode 100644 index 00000000..d98c0450 --- /dev/null +++ b/libc/nt/ntdll/RtlIsProcessorFeaturePresent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsProcessorFeaturePresent diff --git a/libc/nt/ntdll/RtlIsStateSeparationEnabled.s b/libc/nt/ntdll/RtlIsStateSeparationEnabled.s new file mode 100644 index 00000000..613fdc44 --- /dev/null +++ b/libc/nt/ntdll/RtlIsStateSeparationEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsStateSeparationEnabled diff --git a/libc/nt/ntdll/RtlIsTextUnicode.s b/libc/nt/ntdll/RtlIsTextUnicode.s new file mode 100644 index 00000000..6304c74f --- /dev/null +++ b/libc/nt/ntdll/RtlIsTextUnicode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsTextUnicode diff --git a/libc/nt/ntdll/RtlIsThreadWithinLoaderCallout.s b/libc/nt/ntdll/RtlIsThreadWithinLoaderCallout.s new file mode 100644 index 00000000..55a8fdfb --- /dev/null +++ b/libc/nt/ntdll/RtlIsThreadWithinLoaderCallout.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsThreadWithinLoaderCallout diff --git a/libc/nt/ntdll/RtlIsUntrustedObject.s b/libc/nt/ntdll/RtlIsUntrustedObject.s new file mode 100644 index 00000000..bae2463d --- /dev/null +++ b/libc/nt/ntdll/RtlIsUntrustedObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsUntrustedObject diff --git a/libc/nt/ntdll/RtlIsValidHandle.s b/libc/nt/ntdll/RtlIsValidHandle.s new file mode 100644 index 00000000..7fde4bda --- /dev/null +++ b/libc/nt/ntdll/RtlIsValidHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsValidHandle diff --git a/libc/nt/ntdll/RtlIsValidIndexHandle.s b/libc/nt/ntdll/RtlIsValidIndexHandle.s new file mode 100644 index 00000000..82386699 --- /dev/null +++ b/libc/nt/ntdll/RtlIsValidIndexHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsValidIndexHandle diff --git a/libc/nt/ntdll/RtlIsValidLocaleName.s b/libc/nt/ntdll/RtlIsValidLocaleName.s new file mode 100644 index 00000000..20e92282 --- /dev/null +++ b/libc/nt/ntdll/RtlIsValidLocaleName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsValidLocaleName diff --git a/libc/nt/ntdll/RtlIsValidProcessTrustLabelSid.s b/libc/nt/ntdll/RtlIsValidProcessTrustLabelSid.s new file mode 100644 index 00000000..da63ce1a --- /dev/null +++ b/libc/nt/ntdll/RtlIsValidProcessTrustLabelSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlIsValidProcessTrustLabelSid diff --git a/libc/nt/ntdll/RtlKnownExceptionFilter.s b/libc/nt/ntdll/RtlKnownExceptionFilter.s new file mode 100644 index 00000000..ec6b8d1f --- /dev/null +++ b/libc/nt/ntdll/RtlKnownExceptionFilter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlKnownExceptionFilter diff --git a/libc/nt/ntdll/RtlLCIDToCultureName.s b/libc/nt/ntdll/RtlLCIDToCultureName.s new file mode 100644 index 00000000..9fc7e3d9 --- /dev/null +++ b/libc/nt/ntdll/RtlLCIDToCultureName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLCIDToCultureName diff --git a/libc/nt/ntdll/RtlLargeIntegerToChar.s b/libc/nt/ntdll/RtlLargeIntegerToChar.s new file mode 100644 index 00000000..a391a4d6 --- /dev/null +++ b/libc/nt/ntdll/RtlLargeIntegerToChar.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLargeIntegerToChar diff --git a/libc/nt/ntdll/RtlLcidToLocaleName.s b/libc/nt/ntdll/RtlLcidToLocaleName.s new file mode 100644 index 00000000..68457915 --- /dev/null +++ b/libc/nt/ntdll/RtlLcidToLocaleName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLcidToLocaleName diff --git a/libc/nt/ntdll/RtlLeaveCriticalSection.s b/libc/nt/ntdll/RtlLeaveCriticalSection.s new file mode 100644 index 00000000..febd88ae --- /dev/null +++ b/libc/nt/ntdll/RtlLeaveCriticalSection.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLeaveCriticalSection + + .text.windows +RtlLeaveCriticalSection: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RtlLeaveCriticalSection(%rip) + leave + ret + .endfn RtlLeaveCriticalSection,globl + .previous diff --git a/libc/nt/ntdll/RtlLengthRequiredSid.s b/libc/nt/ntdll/RtlLengthRequiredSid.s new file mode 100644 index 00000000..15bdb01f --- /dev/null +++ b/libc/nt/ntdll/RtlLengthRequiredSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLengthRequiredSid diff --git a/libc/nt/ntdll/RtlLengthSecurityDescriptor.s b/libc/nt/ntdll/RtlLengthSecurityDescriptor.s new file mode 100644 index 00000000..137da1cc --- /dev/null +++ b/libc/nt/ntdll/RtlLengthSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLengthSecurityDescriptor diff --git a/libc/nt/ntdll/RtlLengthSid.s b/libc/nt/ntdll/RtlLengthSid.s new file mode 100644 index 00000000..54311453 --- /dev/null +++ b/libc/nt/ntdll/RtlLengthSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLengthSid diff --git a/libc/nt/ntdll/RtlLengthSidAsUnicodeString.s b/libc/nt/ntdll/RtlLengthSidAsUnicodeString.s new file mode 100644 index 00000000..57bd991f --- /dev/null +++ b/libc/nt/ntdll/RtlLengthSidAsUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLengthSidAsUnicodeString diff --git a/libc/nt/ntdll/RtlLoadString.s b/libc/nt/ntdll/RtlLoadString.s new file mode 100644 index 00000000..6e1e9638 --- /dev/null +++ b/libc/nt/ntdll/RtlLoadString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLoadString diff --git a/libc/nt/ntdll/RtlLocalTimeToSystemTime.s b/libc/nt/ntdll/RtlLocalTimeToSystemTime.s new file mode 100644 index 00000000..b519bf41 --- /dev/null +++ b/libc/nt/ntdll/RtlLocalTimeToSystemTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLocalTimeToSystemTime diff --git a/libc/nt/ntdll/RtlLocaleNameToLcid.s b/libc/nt/ntdll/RtlLocaleNameToLcid.s new file mode 100644 index 00000000..d6cc117d --- /dev/null +++ b/libc/nt/ntdll/RtlLocaleNameToLcid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLocaleNameToLcid diff --git a/libc/nt/ntdll/RtlLocateExtendedFeature.s b/libc/nt/ntdll/RtlLocateExtendedFeature.s new file mode 100644 index 00000000..ba840c6a --- /dev/null +++ b/libc/nt/ntdll/RtlLocateExtendedFeature.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLocateExtendedFeature diff --git a/libc/nt/ntdll/RtlLocateExtendedFeature2.s b/libc/nt/ntdll/RtlLocateExtendedFeature2.s new file mode 100644 index 00000000..4c2f2e0e --- /dev/null +++ b/libc/nt/ntdll/RtlLocateExtendedFeature2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLocateExtendedFeature2 diff --git a/libc/nt/ntdll/RtlLocateLegacyContext.s b/libc/nt/ntdll/RtlLocateLegacyContext.s new file mode 100644 index 00000000..42156fe5 --- /dev/null +++ b/libc/nt/ntdll/RtlLocateLegacyContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLocateLegacyContext diff --git a/libc/nt/ntdll/RtlLockBootStatusData.s b/libc/nt/ntdll/RtlLockBootStatusData.s new file mode 100644 index 00000000..cf5cfe6f --- /dev/null +++ b/libc/nt/ntdll/RtlLockBootStatusData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLockBootStatusData diff --git a/libc/nt/ntdll/RtlLockCurrentThread.s b/libc/nt/ntdll/RtlLockCurrentThread.s new file mode 100644 index 00000000..358ede57 --- /dev/null +++ b/libc/nt/ntdll/RtlLockCurrentThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLockCurrentThread diff --git a/libc/nt/ntdll/RtlLockHeap.s b/libc/nt/ntdll/RtlLockHeap.s new file mode 100644 index 00000000..ce1662c0 --- /dev/null +++ b/libc/nt/ntdll/RtlLockHeap.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLockHeap + + .text.windows +RtlLockHeap: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RtlLockHeap(%rip) + leave + ret + .endfn RtlLockHeap,globl + .previous diff --git a/libc/nt/ntdll/RtlLockMemoryBlockLookaside.s b/libc/nt/ntdll/RtlLockMemoryBlockLookaside.s new file mode 100644 index 00000000..84b3ce61 --- /dev/null +++ b/libc/nt/ntdll/RtlLockMemoryBlockLookaside.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLockMemoryBlockLookaside diff --git a/libc/nt/ntdll/RtlLockMemoryStreamRegion.s b/libc/nt/ntdll/RtlLockMemoryStreamRegion.s new file mode 100644 index 00000000..00d2364a --- /dev/null +++ b/libc/nt/ntdll/RtlLockMemoryStreamRegion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLockMemoryStreamRegion diff --git a/libc/nt/ntdll/RtlLockMemoryZone.s b/libc/nt/ntdll/RtlLockMemoryZone.s new file mode 100644 index 00000000..4f1f9923 --- /dev/null +++ b/libc/nt/ntdll/RtlLockMemoryZone.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLockMemoryZone diff --git a/libc/nt/ntdll/RtlLockModuleSection.s b/libc/nt/ntdll/RtlLockModuleSection.s new file mode 100644 index 00000000..c54e0ced --- /dev/null +++ b/libc/nt/ntdll/RtlLockModuleSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLockModuleSection diff --git a/libc/nt/ntdll/RtlLogStackBackTrace.s b/libc/nt/ntdll/RtlLogStackBackTrace.s new file mode 100644 index 00000000..862e7f40 --- /dev/null +++ b/libc/nt/ntdll/RtlLogStackBackTrace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLogStackBackTrace diff --git a/libc/nt/ntdll/RtlLookupAtomInAtomTable.s b/libc/nt/ntdll/RtlLookupAtomInAtomTable.s new file mode 100644 index 00000000..d75dab0f --- /dev/null +++ b/libc/nt/ntdll/RtlLookupAtomInAtomTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLookupAtomInAtomTable diff --git a/libc/nt/ntdll/RtlLookupElementGenericTable.s b/libc/nt/ntdll/RtlLookupElementGenericTable.s new file mode 100644 index 00000000..4d1f24ad --- /dev/null +++ b/libc/nt/ntdll/RtlLookupElementGenericTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLookupElementGenericTable diff --git a/libc/nt/ntdll/RtlLookupElementGenericTableAvl.s b/libc/nt/ntdll/RtlLookupElementGenericTableAvl.s new file mode 100644 index 00000000..b692bd73 --- /dev/null +++ b/libc/nt/ntdll/RtlLookupElementGenericTableAvl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLookupElementGenericTableAvl diff --git a/libc/nt/ntdll/RtlLookupElementGenericTableFull.s b/libc/nt/ntdll/RtlLookupElementGenericTableFull.s new file mode 100644 index 00000000..e5f20406 --- /dev/null +++ b/libc/nt/ntdll/RtlLookupElementGenericTableFull.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLookupElementGenericTableFull diff --git a/libc/nt/ntdll/RtlLookupElementGenericTableFullAvl.s b/libc/nt/ntdll/RtlLookupElementGenericTableFullAvl.s new file mode 100644 index 00000000..b9ddc12a --- /dev/null +++ b/libc/nt/ntdll/RtlLookupElementGenericTableFullAvl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLookupElementGenericTableFullAvl diff --git a/libc/nt/ntdll/RtlLookupEntryHashTable.s b/libc/nt/ntdll/RtlLookupEntryHashTable.s new file mode 100644 index 00000000..32022b55 --- /dev/null +++ b/libc/nt/ntdll/RtlLookupEntryHashTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLookupEntryHashTable diff --git a/libc/nt/ntdll/RtlLookupFirstMatchingElementGenericTableAvl.s b/libc/nt/ntdll/RtlLookupFirstMatchingElementGenericTableAvl.s new file mode 100644 index 00000000..87f0bf9a --- /dev/null +++ b/libc/nt/ntdll/RtlLookupFirstMatchingElementGenericTableAvl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLookupFirstMatchingElementGenericTableAvl diff --git a/libc/nt/ntdll/RtlLookupFunctionEntry.s b/libc/nt/ntdll/RtlLookupFunctionEntry.s new file mode 100644 index 00000000..d534f395 --- /dev/null +++ b/libc/nt/ntdll/RtlLookupFunctionEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLookupFunctionEntry diff --git a/libc/nt/ntdll/RtlLookupFunctionTable.s b/libc/nt/ntdll/RtlLookupFunctionTable.s new file mode 100644 index 00000000..9e692ab6 --- /dev/null +++ b/libc/nt/ntdll/RtlLookupFunctionTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlLookupFunctionTable diff --git a/libc/nt/ntdll/RtlMakeSelfRelativeSD.s b/libc/nt/ntdll/RtlMakeSelfRelativeSD.s new file mode 100644 index 00000000..80183192 --- /dev/null +++ b/libc/nt/ntdll/RtlMakeSelfRelativeSD.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlMakeSelfRelativeSD diff --git a/libc/nt/ntdll/RtlMapGenericMask.s b/libc/nt/ntdll/RtlMapGenericMask.s new file mode 100644 index 00000000..5ab26117 --- /dev/null +++ b/libc/nt/ntdll/RtlMapGenericMask.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlMapGenericMask diff --git a/libc/nt/ntdll/RtlMapSecurityErrorToNtStatus.s b/libc/nt/ntdll/RtlMapSecurityErrorToNtStatus.s new file mode 100644 index 00000000..acb9cf2e --- /dev/null +++ b/libc/nt/ntdll/RtlMapSecurityErrorToNtStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlMapSecurityErrorToNtStatus diff --git a/libc/nt/ntdll/RtlMoveMemory.s b/libc/nt/ntdll/RtlMoveMemory.s new file mode 100644 index 00000000..eb507847 --- /dev/null +++ b/libc/nt/ntdll/RtlMoveMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlMoveMemory diff --git a/libc/nt/ntdll/RtlMultiAppendUnicodeStringBuffer.s b/libc/nt/ntdll/RtlMultiAppendUnicodeStringBuffer.s new file mode 100644 index 00000000..ca7a7817 --- /dev/null +++ b/libc/nt/ntdll/RtlMultiAppendUnicodeStringBuffer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlMultiAppendUnicodeStringBuffer diff --git a/libc/nt/ntdll/RtlMultiByteToUnicodeN.s b/libc/nt/ntdll/RtlMultiByteToUnicodeN.s new file mode 100644 index 00000000..3531f324 --- /dev/null +++ b/libc/nt/ntdll/RtlMultiByteToUnicodeN.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlMultiByteToUnicodeN diff --git a/libc/nt/ntdll/RtlMultiByteToUnicodeSize.s b/libc/nt/ntdll/RtlMultiByteToUnicodeSize.s new file mode 100644 index 00000000..66a4ed97 --- /dev/null +++ b/libc/nt/ntdll/RtlMultiByteToUnicodeSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlMultiByteToUnicodeSize diff --git a/libc/nt/ntdll/RtlMultipleAllocateHeap.s b/libc/nt/ntdll/RtlMultipleAllocateHeap.s new file mode 100644 index 00000000..6c0dae21 --- /dev/null +++ b/libc/nt/ntdll/RtlMultipleAllocateHeap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlMultipleAllocateHeap diff --git a/libc/nt/ntdll/RtlMultipleFreeHeap.s b/libc/nt/ntdll/RtlMultipleFreeHeap.s new file mode 100644 index 00000000..45d2abdb --- /dev/null +++ b/libc/nt/ntdll/RtlMultipleFreeHeap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlMultipleFreeHeap diff --git a/libc/nt/ntdll/RtlNewInstanceSecurityObject.s b/libc/nt/ntdll/RtlNewInstanceSecurityObject.s new file mode 100644 index 00000000..780f5620 --- /dev/null +++ b/libc/nt/ntdll/RtlNewInstanceSecurityObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNewInstanceSecurityObject diff --git a/libc/nt/ntdll/RtlNewSecurityGrantedAccess.s b/libc/nt/ntdll/RtlNewSecurityGrantedAccess.s new file mode 100644 index 00000000..b85d90fe --- /dev/null +++ b/libc/nt/ntdll/RtlNewSecurityGrantedAccess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNewSecurityGrantedAccess diff --git a/libc/nt/ntdll/RtlNewSecurityObject.s b/libc/nt/ntdll/RtlNewSecurityObject.s new file mode 100644 index 00000000..0a8feab4 --- /dev/null +++ b/libc/nt/ntdll/RtlNewSecurityObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNewSecurityObject diff --git a/libc/nt/ntdll/RtlNewSecurityObjectEx.s b/libc/nt/ntdll/RtlNewSecurityObjectEx.s new file mode 100644 index 00000000..dbae6ec5 --- /dev/null +++ b/libc/nt/ntdll/RtlNewSecurityObjectEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNewSecurityObjectEx diff --git a/libc/nt/ntdll/RtlNewSecurityObjectWithMultipleInheritance.s b/libc/nt/ntdll/RtlNewSecurityObjectWithMultipleInheritance.s new file mode 100644 index 00000000..d9a0a26a --- /dev/null +++ b/libc/nt/ntdll/RtlNewSecurityObjectWithMultipleInheritance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNewSecurityObjectWithMultipleInheritance diff --git a/libc/nt/ntdll/RtlNormalizeProcessParams.s b/libc/nt/ntdll/RtlNormalizeProcessParams.s new file mode 100644 index 00000000..b35e33cb --- /dev/null +++ b/libc/nt/ntdll/RtlNormalizeProcessParams.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNormalizeProcessParams diff --git a/libc/nt/ntdll/RtlNormalizeString.s b/libc/nt/ntdll/RtlNormalizeString.s new file mode 100644 index 00000000..e1c32c76 --- /dev/null +++ b/libc/nt/ntdll/RtlNormalizeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNormalizeString diff --git a/libc/nt/ntdll/RtlNtPathNameToDosPathName.s b/libc/nt/ntdll/RtlNtPathNameToDosPathName.s new file mode 100644 index 00000000..e87caeb0 --- /dev/null +++ b/libc/nt/ntdll/RtlNtPathNameToDosPathName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNtPathNameToDosPathName diff --git a/libc/nt/ntdll/RtlNtStatusToDosError.s b/libc/nt/ntdll/RtlNtStatusToDosError.s new file mode 100644 index 00000000..3acd7a7c --- /dev/null +++ b/libc/nt/ntdll/RtlNtStatusToDosError.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNtStatusToDosError diff --git a/libc/nt/ntdll/RtlNtStatusToDosErrorNoTeb.s b/libc/nt/ntdll/RtlNtStatusToDosErrorNoTeb.s new file mode 100644 index 00000000..4ec1471b --- /dev/null +++ b/libc/nt/ntdll/RtlNtStatusToDosErrorNoTeb.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNtStatusToDosErrorNoTeb diff --git a/libc/nt/ntdll/RtlNtdllName.s b/libc/nt/ntdll/RtlNtdllName.s new file mode 100644 index 00000000..710ef960 --- /dev/null +++ b/libc/nt/ntdll/RtlNtdllName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNtdllName diff --git a/libc/nt/ntdll/RtlNumberGenericTableElements.s b/libc/nt/ntdll/RtlNumberGenericTableElements.s new file mode 100644 index 00000000..2283167e --- /dev/null +++ b/libc/nt/ntdll/RtlNumberGenericTableElements.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNumberGenericTableElements diff --git a/libc/nt/ntdll/RtlNumberGenericTableElementsAvl.s b/libc/nt/ntdll/RtlNumberGenericTableElementsAvl.s new file mode 100644 index 00000000..53800322 --- /dev/null +++ b/libc/nt/ntdll/RtlNumberGenericTableElementsAvl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNumberGenericTableElementsAvl diff --git a/libc/nt/ntdll/RtlNumberOfClearBits.s b/libc/nt/ntdll/RtlNumberOfClearBits.s new file mode 100644 index 00000000..c9aaf612 --- /dev/null +++ b/libc/nt/ntdll/RtlNumberOfClearBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNumberOfClearBits diff --git a/libc/nt/ntdll/RtlNumberOfClearBitsInRange.s b/libc/nt/ntdll/RtlNumberOfClearBitsInRange.s new file mode 100644 index 00000000..bbfda31e --- /dev/null +++ b/libc/nt/ntdll/RtlNumberOfClearBitsInRange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNumberOfClearBitsInRange diff --git a/libc/nt/ntdll/RtlNumberOfSetBits.s b/libc/nt/ntdll/RtlNumberOfSetBits.s new file mode 100644 index 00000000..6dfb71a0 --- /dev/null +++ b/libc/nt/ntdll/RtlNumberOfSetBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNumberOfSetBits diff --git a/libc/nt/ntdll/RtlNumberOfSetBitsInRange.s b/libc/nt/ntdll/RtlNumberOfSetBitsInRange.s new file mode 100644 index 00000000..e856508e --- /dev/null +++ b/libc/nt/ntdll/RtlNumberOfSetBitsInRange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNumberOfSetBitsInRange diff --git a/libc/nt/ntdll/RtlNumberOfSetBitsUlongPtr.s b/libc/nt/ntdll/RtlNumberOfSetBitsUlongPtr.s new file mode 100644 index 00000000..a0f926d1 --- /dev/null +++ b/libc/nt/ntdll/RtlNumberOfSetBitsUlongPtr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlNumberOfSetBitsUlongPtr diff --git a/libc/nt/ntdll/RtlOemStringToUnicodeSize.s b/libc/nt/ntdll/RtlOemStringToUnicodeSize.s new file mode 100644 index 00000000..e28bdc43 --- /dev/null +++ b/libc/nt/ntdll/RtlOemStringToUnicodeSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlOemStringToUnicodeSize diff --git a/libc/nt/ntdll/RtlOemStringToUnicodeString.s b/libc/nt/ntdll/RtlOemStringToUnicodeString.s new file mode 100644 index 00000000..8c23644a --- /dev/null +++ b/libc/nt/ntdll/RtlOemStringToUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlOemStringToUnicodeString diff --git a/libc/nt/ntdll/RtlOemToUnicodeN.s b/libc/nt/ntdll/RtlOemToUnicodeN.s new file mode 100644 index 00000000..1aebabf3 --- /dev/null +++ b/libc/nt/ntdll/RtlOemToUnicodeN.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlOemToUnicodeN diff --git a/libc/nt/ntdll/RtlOpenCurrentUser.s b/libc/nt/ntdll/RtlOpenCurrentUser.s new file mode 100644 index 00000000..fa3baafd --- /dev/null +++ b/libc/nt/ntdll/RtlOpenCurrentUser.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlOpenCurrentUser diff --git a/libc/nt/ntdll/RtlOsDeploymentState.s b/libc/nt/ntdll/RtlOsDeploymentState.s new file mode 100644 index 00000000..327ce2d1 --- /dev/null +++ b/libc/nt/ntdll/RtlOsDeploymentState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlOsDeploymentState diff --git a/libc/nt/ntdll/RtlOwnerAcesPresent.s b/libc/nt/ntdll/RtlOwnerAcesPresent.s new file mode 100644 index 00000000..43d9c3fe --- /dev/null +++ b/libc/nt/ntdll/RtlOwnerAcesPresent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlOwnerAcesPresent diff --git a/libc/nt/ntdll/RtlPcToFileHeader.s b/libc/nt/ntdll/RtlPcToFileHeader.s new file mode 100644 index 00000000..f9bd5e43 --- /dev/null +++ b/libc/nt/ntdll/RtlPcToFileHeader.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlPcToFileHeader diff --git a/libc/nt/ntdll/RtlPinAtomInAtomTable.s b/libc/nt/ntdll/RtlPinAtomInAtomTable.s new file mode 100644 index 00000000..7df22807 --- /dev/null +++ b/libc/nt/ntdll/RtlPinAtomInAtomTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlPinAtomInAtomTable diff --git a/libc/nt/ntdll/RtlPopFrame.s b/libc/nt/ntdll/RtlPopFrame.s new file mode 100644 index 00000000..6320cec1 --- /dev/null +++ b/libc/nt/ntdll/RtlPopFrame.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlPopFrame diff --git a/libc/nt/ntdll/RtlPrefixString.s b/libc/nt/ntdll/RtlPrefixString.s new file mode 100644 index 00000000..16db3550 --- /dev/null +++ b/libc/nt/ntdll/RtlPrefixString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlPrefixString diff --git a/libc/nt/ntdll/RtlPrefixUnicodeString.s b/libc/nt/ntdll/RtlPrefixUnicodeString.s new file mode 100644 index 00000000..537d75f6 --- /dev/null +++ b/libc/nt/ntdll/RtlPrefixUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlPrefixUnicodeString diff --git a/libc/nt/ntdll/RtlPrepareForProcessCloning.s b/libc/nt/ntdll/RtlPrepareForProcessCloning.s new file mode 100644 index 00000000..7f45efeb --- /dev/null +++ b/libc/nt/ntdll/RtlPrepareForProcessCloning.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlPrepareForProcessCloning diff --git a/libc/nt/ntdll/RtlProcessFlsData.s b/libc/nt/ntdll/RtlProcessFlsData.s new file mode 100644 index 00000000..af8620ef --- /dev/null +++ b/libc/nt/ntdll/RtlProcessFlsData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlProcessFlsData diff --git a/libc/nt/ntdll/RtlProtectHeap.s b/libc/nt/ntdll/RtlProtectHeap.s new file mode 100644 index 00000000..d05846b5 --- /dev/null +++ b/libc/nt/ntdll/RtlProtectHeap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlProtectHeap diff --git a/libc/nt/ntdll/RtlPublishWnfStateData.s b/libc/nt/ntdll/RtlPublishWnfStateData.s new file mode 100644 index 00000000..a0918403 --- /dev/null +++ b/libc/nt/ntdll/RtlPublishWnfStateData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlPublishWnfStateData diff --git a/libc/nt/ntdll/RtlPushFrame.s b/libc/nt/ntdll/RtlPushFrame.s new file mode 100644 index 00000000..04db6644 --- /dev/null +++ b/libc/nt/ntdll/RtlPushFrame.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlPushFrame diff --git a/libc/nt/ntdll/RtlQueryActivationContextApplicationSettings.s b/libc/nt/ntdll/RtlQueryActivationContextApplicationSettings.s new file mode 100644 index 00000000..96fb4bb2 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryActivationContextApplicationSettings.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryActivationContextApplicationSettings diff --git a/libc/nt/ntdll/RtlQueryAtomInAtomTable.s b/libc/nt/ntdll/RtlQueryAtomInAtomTable.s new file mode 100644 index 00000000..a16ff909 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryAtomInAtomTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryAtomInAtomTable diff --git a/libc/nt/ntdll/RtlQueryCriticalSectionOwner.s b/libc/nt/ntdll/RtlQueryCriticalSectionOwner.s new file mode 100644 index 00000000..6e09deb8 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryCriticalSectionOwner.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryCriticalSectionOwner diff --git a/libc/nt/ntdll/RtlQueryDepthSList.s b/libc/nt/ntdll/RtlQueryDepthSList.s new file mode 100644 index 00000000..8e2b44b9 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryDepthSList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryDepthSList diff --git a/libc/nt/ntdll/RtlQueryDynamicTimeZoneInformation.s b/libc/nt/ntdll/RtlQueryDynamicTimeZoneInformation.s new file mode 100644 index 00000000..504d7e42 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryDynamicTimeZoneInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryDynamicTimeZoneInformation diff --git a/libc/nt/ntdll/RtlQueryElevationFlags.s b/libc/nt/ntdll/RtlQueryElevationFlags.s new file mode 100644 index 00000000..91d2588f --- /dev/null +++ b/libc/nt/ntdll/RtlQueryElevationFlags.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryElevationFlags diff --git a/libc/nt/ntdll/RtlQueryEnvironmentVariable.s b/libc/nt/ntdll/RtlQueryEnvironmentVariable.s new file mode 100644 index 00000000..95cf5eeb --- /dev/null +++ b/libc/nt/ntdll/RtlQueryEnvironmentVariable.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryEnvironmentVariable + + .text.windows +RtlQueryEnvironmentVariable: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RtlQueryEnvironmentVariable(%rip),%rax + jmp __sysv2nt + .endfn RtlQueryEnvironmentVariable,globl + .previous diff --git a/libc/nt/ntdll/RtlQueryEnvironmentVariable_U.s b/libc/nt/ntdll/RtlQueryEnvironmentVariable_U.s new file mode 100644 index 00000000..a025f414 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryEnvironmentVariable_U.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryEnvironmentVariable_U diff --git a/libc/nt/ntdll/RtlQueryHeapInformation.s b/libc/nt/ntdll/RtlQueryHeapInformation.s new file mode 100644 index 00000000..64ae38a6 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryHeapInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryHeapInformation diff --git a/libc/nt/ntdll/RtlQueryImageMitigationPolicy.s b/libc/nt/ntdll/RtlQueryImageMitigationPolicy.s new file mode 100644 index 00000000..5c08748a --- /dev/null +++ b/libc/nt/ntdll/RtlQueryImageMitigationPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryImageMitigationPolicy diff --git a/libc/nt/ntdll/RtlQueryInformationAcl.s b/libc/nt/ntdll/RtlQueryInformationAcl.s new file mode 100644 index 00000000..60eaa0e5 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryInformationAcl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryInformationAcl diff --git a/libc/nt/ntdll/RtlQueryInformationActivationContext.s b/libc/nt/ntdll/RtlQueryInformationActivationContext.s new file mode 100644 index 00000000..68a00472 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryInformationActivationContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryInformationActivationContext diff --git a/libc/nt/ntdll/RtlQueryInformationActiveActivationContext.s b/libc/nt/ntdll/RtlQueryInformationActiveActivationContext.s new file mode 100644 index 00000000..886ab527 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryInformationActiveActivationContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryInformationActiveActivationContext diff --git a/libc/nt/ntdll/RtlQueryInterfaceMemoryStream.s b/libc/nt/ntdll/RtlQueryInterfaceMemoryStream.s new file mode 100644 index 00000000..52e7bfa4 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryInterfaceMemoryStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryInterfaceMemoryStream diff --git a/libc/nt/ntdll/RtlQueryModuleInformation.s b/libc/nt/ntdll/RtlQueryModuleInformation.s new file mode 100644 index 00000000..6fa79de8 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryModuleInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryModuleInformation diff --git a/libc/nt/ntdll/RtlQueryPackageClaims.s b/libc/nt/ntdll/RtlQueryPackageClaims.s new file mode 100644 index 00000000..ca45b3aa --- /dev/null +++ b/libc/nt/ntdll/RtlQueryPackageClaims.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryPackageClaims diff --git a/libc/nt/ntdll/RtlQueryPackageIdentity.s b/libc/nt/ntdll/RtlQueryPackageIdentity.s new file mode 100644 index 00000000..995fc733 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryPackageIdentity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryPackageIdentity diff --git a/libc/nt/ntdll/RtlQueryPackageIdentityEx.s b/libc/nt/ntdll/RtlQueryPackageIdentityEx.s new file mode 100644 index 00000000..e25b600b --- /dev/null +++ b/libc/nt/ntdll/RtlQueryPackageIdentityEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryPackageIdentityEx diff --git a/libc/nt/ntdll/RtlQueryPerformanceCounter.s b/libc/nt/ntdll/RtlQueryPerformanceCounter.s new file mode 100644 index 00000000..489a0585 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryPerformanceCounter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryPerformanceCounter diff --git a/libc/nt/ntdll/RtlQueryPerformanceFrequency.s b/libc/nt/ntdll/RtlQueryPerformanceFrequency.s new file mode 100644 index 00000000..e00f66e2 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryPerformanceFrequency.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryPerformanceFrequency diff --git a/libc/nt/ntdll/RtlQueryProcessBackTraceInformation.s b/libc/nt/ntdll/RtlQueryProcessBackTraceInformation.s new file mode 100644 index 00000000..6c5001d3 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryProcessBackTraceInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryProcessBackTraceInformation diff --git a/libc/nt/ntdll/RtlQueryProcessDebugInformation.s b/libc/nt/ntdll/RtlQueryProcessDebugInformation.s new file mode 100644 index 00000000..e3d6075e --- /dev/null +++ b/libc/nt/ntdll/RtlQueryProcessDebugInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryProcessDebugInformation diff --git a/libc/nt/ntdll/RtlQueryProcessHeapInformation.s b/libc/nt/ntdll/RtlQueryProcessHeapInformation.s new file mode 100644 index 00000000..b24abf8e --- /dev/null +++ b/libc/nt/ntdll/RtlQueryProcessHeapInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryProcessHeapInformation diff --git a/libc/nt/ntdll/RtlQueryProcessLockInformation.s b/libc/nt/ntdll/RtlQueryProcessLockInformation.s new file mode 100644 index 00000000..7edcb5de --- /dev/null +++ b/libc/nt/ntdll/RtlQueryProcessLockInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryProcessLockInformation diff --git a/libc/nt/ntdll/RtlQueryProcessPlaceholderCompatibilityMode.s b/libc/nt/ntdll/RtlQueryProcessPlaceholderCompatibilityMode.s new file mode 100644 index 00000000..a535f33a --- /dev/null +++ b/libc/nt/ntdll/RtlQueryProcessPlaceholderCompatibilityMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryProcessPlaceholderCompatibilityMode diff --git a/libc/nt/ntdll/RtlQueryProtectedPolicy.s b/libc/nt/ntdll/RtlQueryProtectedPolicy.s new file mode 100644 index 00000000..70e425d2 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryProtectedPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryProtectedPolicy diff --git a/libc/nt/ntdll/RtlQueryRegistryValueWithFallback.s b/libc/nt/ntdll/RtlQueryRegistryValueWithFallback.s new file mode 100644 index 00000000..9179e526 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryRegistryValueWithFallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryRegistryValueWithFallback diff --git a/libc/nt/ntdll/RtlQueryRegistryValues.s b/libc/nt/ntdll/RtlQueryRegistryValues.s new file mode 100644 index 00000000..aeab9a52 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryRegistryValues.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryRegistryValues diff --git a/libc/nt/ntdll/RtlQueryRegistryValuesEx.s b/libc/nt/ntdll/RtlQueryRegistryValuesEx.s new file mode 100644 index 00000000..bb238cc5 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryRegistryValuesEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryRegistryValuesEx diff --git a/libc/nt/ntdll/RtlQueryResourcePolicy.s b/libc/nt/ntdll/RtlQueryResourcePolicy.s new file mode 100644 index 00000000..7e354500 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryResourcePolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryResourcePolicy diff --git a/libc/nt/ntdll/RtlQuerySecurityObject.s b/libc/nt/ntdll/RtlQuerySecurityObject.s new file mode 100644 index 00000000..3e0f484c --- /dev/null +++ b/libc/nt/ntdll/RtlQuerySecurityObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQuerySecurityObject diff --git a/libc/nt/ntdll/RtlQueryTagHeap.s b/libc/nt/ntdll/RtlQueryTagHeap.s new file mode 100644 index 00000000..a8190a7f --- /dev/null +++ b/libc/nt/ntdll/RtlQueryTagHeap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryTagHeap diff --git a/libc/nt/ntdll/RtlQueryThreadPlaceholderCompatibilityMode.s b/libc/nt/ntdll/RtlQueryThreadPlaceholderCompatibilityMode.s new file mode 100644 index 00000000..b0d53a67 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryThreadPlaceholderCompatibilityMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryThreadPlaceholderCompatibilityMode diff --git a/libc/nt/ntdll/RtlQueryThreadProfiling.s b/libc/nt/ntdll/RtlQueryThreadProfiling.s new file mode 100644 index 00000000..c81325ae --- /dev/null +++ b/libc/nt/ntdll/RtlQueryThreadProfiling.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryThreadProfiling diff --git a/libc/nt/ntdll/RtlQueryTimeZoneInformation.s b/libc/nt/ntdll/RtlQueryTimeZoneInformation.s new file mode 100644 index 00000000..5a81b849 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryTimeZoneInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryTimeZoneInformation diff --git a/libc/nt/ntdll/RtlQueryTokenHostIdAsUlong64.s b/libc/nt/ntdll/RtlQueryTokenHostIdAsUlong64.s new file mode 100644 index 00000000..4dec02d0 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryTokenHostIdAsUlong64.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryTokenHostIdAsUlong64 diff --git a/libc/nt/ntdll/RtlQueryUmsThreadInformation.s b/libc/nt/ntdll/RtlQueryUmsThreadInformation.s new file mode 100644 index 00000000..54c493e3 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryUmsThreadInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryUmsThreadInformation diff --git a/libc/nt/ntdll/RtlQueryUnbiasedInterruptTime.s b/libc/nt/ntdll/RtlQueryUnbiasedInterruptTime.s new file mode 100644 index 00000000..a487cae5 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryUnbiasedInterruptTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryUnbiasedInterruptTime diff --git a/libc/nt/ntdll/RtlQueryValidationRunlevel.s b/libc/nt/ntdll/RtlQueryValidationRunlevel.s new file mode 100644 index 00000000..bf177e81 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryValidationRunlevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryValidationRunlevel diff --git a/libc/nt/ntdll/RtlQueryWnfMetaNotification.s b/libc/nt/ntdll/RtlQueryWnfMetaNotification.s new file mode 100644 index 00000000..b89336d7 --- /dev/null +++ b/libc/nt/ntdll/RtlQueryWnfMetaNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryWnfMetaNotification diff --git a/libc/nt/ntdll/RtlQueryWnfStateData.s b/libc/nt/ntdll/RtlQueryWnfStateData.s new file mode 100644 index 00000000..4f842fda --- /dev/null +++ b/libc/nt/ntdll/RtlQueryWnfStateData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryWnfStateData diff --git a/libc/nt/ntdll/RtlQueryWnfStateDataWithExplicitScope.s b/libc/nt/ntdll/RtlQueryWnfStateDataWithExplicitScope.s new file mode 100644 index 00000000..7d3c985d --- /dev/null +++ b/libc/nt/ntdll/RtlQueryWnfStateDataWithExplicitScope.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueryWnfStateDataWithExplicitScope diff --git a/libc/nt/ntdll/RtlQueueApcWow64Thread.s b/libc/nt/ntdll/RtlQueueApcWow64Thread.s new file mode 100644 index 00000000..5605eca2 --- /dev/null +++ b/libc/nt/ntdll/RtlQueueApcWow64Thread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueueApcWow64Thread diff --git a/libc/nt/ntdll/RtlQueueWorkItem.s b/libc/nt/ntdll/RtlQueueWorkItem.s new file mode 100644 index 00000000..efa43bf9 --- /dev/null +++ b/libc/nt/ntdll/RtlQueueWorkItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlQueueWorkItem diff --git a/libc/nt/ntdll/RtlRaiseCustomSystemEventTrigger.s b/libc/nt/ntdll/RtlRaiseCustomSystemEventTrigger.s new file mode 100644 index 00000000..d09cdd83 --- /dev/null +++ b/libc/nt/ntdll/RtlRaiseCustomSystemEventTrigger.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRaiseCustomSystemEventTrigger diff --git a/libc/nt/ntdll/RtlRaiseException.s b/libc/nt/ntdll/RtlRaiseException.s new file mode 100644 index 00000000..e09cd45f --- /dev/null +++ b/libc/nt/ntdll/RtlRaiseException.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRaiseException diff --git a/libc/nt/ntdll/RtlRaiseStatus.s b/libc/nt/ntdll/RtlRaiseStatus.s new file mode 100644 index 00000000..d7e3559d --- /dev/null +++ b/libc/nt/ntdll/RtlRaiseStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRaiseStatus diff --git a/libc/nt/ntdll/RtlRandom.s b/libc/nt/ntdll/RtlRandom.s new file mode 100644 index 00000000..37384c12 --- /dev/null +++ b/libc/nt/ntdll/RtlRandom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRandom diff --git a/libc/nt/ntdll/RtlRandomEx.s b/libc/nt/ntdll/RtlRandomEx.s new file mode 100644 index 00000000..63450d39 --- /dev/null +++ b/libc/nt/ntdll/RtlRandomEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRandomEx diff --git a/libc/nt/ntdll/RtlRbInsertNodeEx.s b/libc/nt/ntdll/RtlRbInsertNodeEx.s new file mode 100644 index 00000000..8e137be5 --- /dev/null +++ b/libc/nt/ntdll/RtlRbInsertNodeEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRbInsertNodeEx diff --git a/libc/nt/ntdll/RtlRbRemoveNode.s b/libc/nt/ntdll/RtlRbRemoveNode.s new file mode 100644 index 00000000..934aa82c --- /dev/null +++ b/libc/nt/ntdll/RtlRbRemoveNode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRbRemoveNode diff --git a/libc/nt/ntdll/RtlReAllocateHeap.s b/libc/nt/ntdll/RtlReAllocateHeap.s new file mode 100644 index 00000000..dc442b40 --- /dev/null +++ b/libc/nt/ntdll/RtlReAllocateHeap.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReAllocateHeap + + .text.windows +RtlReAllocateHeap: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RtlReAllocateHeap(%rip),%rax + jmp __sysv2nt + .endfn RtlReAllocateHeap,globl + .previous diff --git a/libc/nt/ntdll/RtlReadMemoryStream.s b/libc/nt/ntdll/RtlReadMemoryStream.s new file mode 100644 index 00000000..99e0786a --- /dev/null +++ b/libc/nt/ntdll/RtlReadMemoryStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReadMemoryStream diff --git a/libc/nt/ntdll/RtlReadOutOfProcessMemoryStream.s b/libc/nt/ntdll/RtlReadOutOfProcessMemoryStream.s new file mode 100644 index 00000000..f513bdb8 --- /dev/null +++ b/libc/nt/ntdll/RtlReadOutOfProcessMemoryStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReadOutOfProcessMemoryStream diff --git a/libc/nt/ntdll/RtlReadThreadProfilingData.s b/libc/nt/ntdll/RtlReadThreadProfilingData.s new file mode 100644 index 00000000..8c617115 --- /dev/null +++ b/libc/nt/ntdll/RtlReadThreadProfilingData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReadThreadProfilingData diff --git a/libc/nt/ntdll/RtlRealPredecessor.s b/libc/nt/ntdll/RtlRealPredecessor.s new file mode 100644 index 00000000..db9c279e --- /dev/null +++ b/libc/nt/ntdll/RtlRealPredecessor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRealPredecessor diff --git a/libc/nt/ntdll/RtlRealSuccessor.s b/libc/nt/ntdll/RtlRealSuccessor.s new file mode 100644 index 00000000..d3c1b257 --- /dev/null +++ b/libc/nt/ntdll/RtlRealSuccessor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRealSuccessor diff --git a/libc/nt/ntdll/RtlRegisterForWnfMetaNotification.s b/libc/nt/ntdll/RtlRegisterForWnfMetaNotification.s new file mode 100644 index 00000000..6bbe3d3c --- /dev/null +++ b/libc/nt/ntdll/RtlRegisterForWnfMetaNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRegisterForWnfMetaNotification diff --git a/libc/nt/ntdll/RtlRegisterSecureMemoryCacheCallback.s b/libc/nt/ntdll/RtlRegisterSecureMemoryCacheCallback.s new file mode 100644 index 00000000..6584c08a --- /dev/null +++ b/libc/nt/ntdll/RtlRegisterSecureMemoryCacheCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRegisterSecureMemoryCacheCallback diff --git a/libc/nt/ntdll/RtlRegisterThreadWithCsrss.s b/libc/nt/ntdll/RtlRegisterThreadWithCsrss.s new file mode 100644 index 00000000..b3d321f5 --- /dev/null +++ b/libc/nt/ntdll/RtlRegisterThreadWithCsrss.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRegisterThreadWithCsrss diff --git a/libc/nt/ntdll/RtlRegisterWait.s b/libc/nt/ntdll/RtlRegisterWait.s new file mode 100644 index 00000000..f7afaf99 --- /dev/null +++ b/libc/nt/ntdll/RtlRegisterWait.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRegisterWait diff --git a/libc/nt/ntdll/RtlReleaseActivationContext.s b/libc/nt/ntdll/RtlReleaseActivationContext.s new file mode 100644 index 00000000..a25193b7 --- /dev/null +++ b/libc/nt/ntdll/RtlReleaseActivationContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReleaseActivationContext diff --git a/libc/nt/ntdll/RtlReleaseMemoryStream.s b/libc/nt/ntdll/RtlReleaseMemoryStream.s new file mode 100644 index 00000000..2da90ad2 --- /dev/null +++ b/libc/nt/ntdll/RtlReleaseMemoryStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReleaseMemoryStream diff --git a/libc/nt/ntdll/RtlReleasePath.s b/libc/nt/ntdll/RtlReleasePath.s new file mode 100644 index 00000000..0755dd79 --- /dev/null +++ b/libc/nt/ntdll/RtlReleasePath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReleasePath diff --git a/libc/nt/ntdll/RtlReleasePebLock.s b/libc/nt/ntdll/RtlReleasePebLock.s new file mode 100644 index 00000000..c429d016 --- /dev/null +++ b/libc/nt/ntdll/RtlReleasePebLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReleasePebLock diff --git a/libc/nt/ntdll/RtlReleasePrivilege.s b/libc/nt/ntdll/RtlReleasePrivilege.s new file mode 100644 index 00000000..11de7226 --- /dev/null +++ b/libc/nt/ntdll/RtlReleasePrivilege.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReleasePrivilege diff --git a/libc/nt/ntdll/RtlReleaseRelativeName.s b/libc/nt/ntdll/RtlReleaseRelativeName.s new file mode 100644 index 00000000..5463e6cb --- /dev/null +++ b/libc/nt/ntdll/RtlReleaseRelativeName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReleaseRelativeName diff --git a/libc/nt/ntdll/RtlReleaseResource.s b/libc/nt/ntdll/RtlReleaseResource.s new file mode 100644 index 00000000..c3fbe45e --- /dev/null +++ b/libc/nt/ntdll/RtlReleaseResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReleaseResource diff --git a/libc/nt/ntdll/RtlReleaseSRWLockExclusive.s b/libc/nt/ntdll/RtlReleaseSRWLockExclusive.s new file mode 100644 index 00000000..f66b32f4 --- /dev/null +++ b/libc/nt/ntdll/RtlReleaseSRWLockExclusive.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReleaseSRWLockExclusive diff --git a/libc/nt/ntdll/RtlReleaseSRWLockShared.s b/libc/nt/ntdll/RtlReleaseSRWLockShared.s new file mode 100644 index 00000000..c0de4381 --- /dev/null +++ b/libc/nt/ntdll/RtlReleaseSRWLockShared.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReleaseSRWLockShared diff --git a/libc/nt/ntdll/RtlRemoteCall.s b/libc/nt/ntdll/RtlRemoteCall.s new file mode 100644 index 00000000..3f40fe80 --- /dev/null +++ b/libc/nt/ntdll/RtlRemoteCall.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRemoteCall diff --git a/libc/nt/ntdll/RtlRemoveEntryHashTable.s b/libc/nt/ntdll/RtlRemoveEntryHashTable.s new file mode 100644 index 00000000..7fc0d1fb --- /dev/null +++ b/libc/nt/ntdll/RtlRemoveEntryHashTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRemoveEntryHashTable diff --git a/libc/nt/ntdll/RtlRemovePrivileges.s b/libc/nt/ntdll/RtlRemovePrivileges.s new file mode 100644 index 00000000..9515dea6 --- /dev/null +++ b/libc/nt/ntdll/RtlRemovePrivileges.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRemovePrivileges diff --git a/libc/nt/ntdll/RtlRemoveVectoredContinueHandler.s b/libc/nt/ntdll/RtlRemoveVectoredContinueHandler.s new file mode 100644 index 00000000..ffda952e --- /dev/null +++ b/libc/nt/ntdll/RtlRemoveVectoredContinueHandler.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRemoveVectoredContinueHandler diff --git a/libc/nt/ntdll/RtlRemoveVectoredExceptionHandler.s b/libc/nt/ntdll/RtlRemoveVectoredExceptionHandler.s new file mode 100644 index 00000000..fd276f6e --- /dev/null +++ b/libc/nt/ntdll/RtlRemoveVectoredExceptionHandler.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRemoveVectoredExceptionHandler diff --git a/libc/nt/ntdll/RtlReplaceSidInSd.s b/libc/nt/ntdll/RtlReplaceSidInSd.s new file mode 100644 index 00000000..bd703d57 --- /dev/null +++ b/libc/nt/ntdll/RtlReplaceSidInSd.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReplaceSidInSd diff --git a/libc/nt/ntdll/RtlReplaceSystemDirectoryInPath.s b/libc/nt/ntdll/RtlReplaceSystemDirectoryInPath.s new file mode 100644 index 00000000..2e302e6b --- /dev/null +++ b/libc/nt/ntdll/RtlReplaceSystemDirectoryInPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReplaceSystemDirectoryInPath diff --git a/libc/nt/ntdll/RtlReportException.s b/libc/nt/ntdll/RtlReportException.s new file mode 100644 index 00000000..6f165279 --- /dev/null +++ b/libc/nt/ntdll/RtlReportException.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReportException diff --git a/libc/nt/ntdll/RtlReportExceptionEx.s b/libc/nt/ntdll/RtlReportExceptionEx.s new file mode 100644 index 00000000..2403db26 --- /dev/null +++ b/libc/nt/ntdll/RtlReportExceptionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReportExceptionEx diff --git a/libc/nt/ntdll/RtlReportSilentProcessExit.s b/libc/nt/ntdll/RtlReportSilentProcessExit.s new file mode 100644 index 00000000..7a654cce --- /dev/null +++ b/libc/nt/ntdll/RtlReportSilentProcessExit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReportSilentProcessExit diff --git a/libc/nt/ntdll/RtlReportSqmEscalation.s b/libc/nt/ntdll/RtlReportSqmEscalation.s new file mode 100644 index 00000000..ba692c60 --- /dev/null +++ b/libc/nt/ntdll/RtlReportSqmEscalation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlReportSqmEscalation diff --git a/libc/nt/ntdll/RtlResetMemoryBlockLookaside.s b/libc/nt/ntdll/RtlResetMemoryBlockLookaside.s new file mode 100644 index 00000000..78b3b6fc --- /dev/null +++ b/libc/nt/ntdll/RtlResetMemoryBlockLookaside.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlResetMemoryBlockLookaside diff --git a/libc/nt/ntdll/RtlResetMemoryZone.s b/libc/nt/ntdll/RtlResetMemoryZone.s new file mode 100644 index 00000000..2cb0f266 --- /dev/null +++ b/libc/nt/ntdll/RtlResetMemoryZone.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlResetMemoryZone diff --git a/libc/nt/ntdll/RtlResetNtUserPfn.s b/libc/nt/ntdll/RtlResetNtUserPfn.s new file mode 100644 index 00000000..b4358041 --- /dev/null +++ b/libc/nt/ntdll/RtlResetNtUserPfn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlResetNtUserPfn diff --git a/libc/nt/ntdll/RtlResetRtlTranslations.s b/libc/nt/ntdll/RtlResetRtlTranslations.s new file mode 100644 index 00000000..d2d5ebbb --- /dev/null +++ b/libc/nt/ntdll/RtlResetRtlTranslations.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlResetRtlTranslations diff --git a/libc/nt/ntdll/RtlRestoreBootStatusDefaults.s b/libc/nt/ntdll/RtlRestoreBootStatusDefaults.s new file mode 100644 index 00000000..3029d8dd --- /dev/null +++ b/libc/nt/ntdll/RtlRestoreBootStatusDefaults.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRestoreBootStatusDefaults diff --git a/libc/nt/ntdll/RtlRestoreContext.s b/libc/nt/ntdll/RtlRestoreContext.s new file mode 100644 index 00000000..8afd1c53 --- /dev/null +++ b/libc/nt/ntdll/RtlRestoreContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRestoreContext diff --git a/libc/nt/ntdll/RtlRestoreLastWin32Error.s b/libc/nt/ntdll/RtlRestoreLastWin32Error.s new file mode 100644 index 00000000..fe075840 --- /dev/null +++ b/libc/nt/ntdll/RtlRestoreLastWin32Error.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRestoreLastWin32Error diff --git a/libc/nt/ntdll/RtlRestoreSystemBootStatusDefaults.s b/libc/nt/ntdll/RtlRestoreSystemBootStatusDefaults.s new file mode 100644 index 00000000..60215bfe --- /dev/null +++ b/libc/nt/ntdll/RtlRestoreSystemBootStatusDefaults.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRestoreSystemBootStatusDefaults diff --git a/libc/nt/ntdll/RtlRetrieveNtUserPfn.s b/libc/nt/ntdll/RtlRetrieveNtUserPfn.s new file mode 100644 index 00000000..7ae34d14 --- /dev/null +++ b/libc/nt/ntdll/RtlRetrieveNtUserPfn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRetrieveNtUserPfn diff --git a/libc/nt/ntdll/RtlRevertMemoryStream.s b/libc/nt/ntdll/RtlRevertMemoryStream.s new file mode 100644 index 00000000..21353442 --- /dev/null +++ b/libc/nt/ntdll/RtlRevertMemoryStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRevertMemoryStream diff --git a/libc/nt/ntdll/RtlRunDecodeUnicodeString.s b/libc/nt/ntdll/RtlRunDecodeUnicodeString.s new file mode 100644 index 00000000..b29cbaae --- /dev/null +++ b/libc/nt/ntdll/RtlRunDecodeUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRunDecodeUnicodeString diff --git a/libc/nt/ntdll/RtlRunEncodeUnicodeString.s b/libc/nt/ntdll/RtlRunEncodeUnicodeString.s new file mode 100644 index 00000000..b2d78ef2 --- /dev/null +++ b/libc/nt/ntdll/RtlRunEncodeUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRunEncodeUnicodeString diff --git a/libc/nt/ntdll/RtlRunOnceBeginInitialize.s b/libc/nt/ntdll/RtlRunOnceBeginInitialize.s new file mode 100644 index 00000000..34a01b92 --- /dev/null +++ b/libc/nt/ntdll/RtlRunOnceBeginInitialize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRunOnceBeginInitialize diff --git a/libc/nt/ntdll/RtlRunOnceComplete.s b/libc/nt/ntdll/RtlRunOnceComplete.s new file mode 100644 index 00000000..31284020 --- /dev/null +++ b/libc/nt/ntdll/RtlRunOnceComplete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRunOnceComplete diff --git a/libc/nt/ntdll/RtlRunOnceExecuteOnce.s b/libc/nt/ntdll/RtlRunOnceExecuteOnce.s new file mode 100644 index 00000000..cb28c6c1 --- /dev/null +++ b/libc/nt/ntdll/RtlRunOnceExecuteOnce.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRunOnceExecuteOnce diff --git a/libc/nt/ntdll/RtlRunOnceInitialize.s b/libc/nt/ntdll/RtlRunOnceInitialize.s new file mode 100644 index 00000000..caaeaee7 --- /dev/null +++ b/libc/nt/ntdll/RtlRunOnceInitialize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlRunOnceInitialize diff --git a/libc/nt/ntdll/RtlSecondsSince1970ToTime.s b/libc/nt/ntdll/RtlSecondsSince1970ToTime.s new file mode 100644 index 00000000..356faeac --- /dev/null +++ b/libc/nt/ntdll/RtlSecondsSince1970ToTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSecondsSince1970ToTime diff --git a/libc/nt/ntdll/RtlSecondsSince1980ToTime.s b/libc/nt/ntdll/RtlSecondsSince1980ToTime.s new file mode 100644 index 00000000..733cc0ca --- /dev/null +++ b/libc/nt/ntdll/RtlSecondsSince1980ToTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSecondsSince1980ToTime diff --git a/libc/nt/ntdll/RtlSeekMemoryStream.s b/libc/nt/ntdll/RtlSeekMemoryStream.s new file mode 100644 index 00000000..add7dd0b --- /dev/null +++ b/libc/nt/ntdll/RtlSeekMemoryStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSeekMemoryStream diff --git a/libc/nt/ntdll/RtlSelfRelativeToAbsoluteSD.s b/libc/nt/ntdll/RtlSelfRelativeToAbsoluteSD.s new file mode 100644 index 00000000..c3a856d3 --- /dev/null +++ b/libc/nt/ntdll/RtlSelfRelativeToAbsoluteSD.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSelfRelativeToAbsoluteSD diff --git a/libc/nt/ntdll/RtlSelfRelativeToAbsoluteSD2.s b/libc/nt/ntdll/RtlSelfRelativeToAbsoluteSD2.s new file mode 100644 index 00000000..7ed404cc --- /dev/null +++ b/libc/nt/ntdll/RtlSelfRelativeToAbsoluteSD2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSelfRelativeToAbsoluteSD2 diff --git a/libc/nt/ntdll/RtlSendMsgToSm.s b/libc/nt/ntdll/RtlSendMsgToSm.s new file mode 100644 index 00000000..42f8faab --- /dev/null +++ b/libc/nt/ntdll/RtlSendMsgToSm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSendMsgToSm diff --git a/libc/nt/ntdll/RtlSetAllBits.s b/libc/nt/ntdll/RtlSetAllBits.s new file mode 100644 index 00000000..ec4c6363 --- /dev/null +++ b/libc/nt/ntdll/RtlSetAllBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetAllBits diff --git a/libc/nt/ntdll/RtlSetAttributesSecurityDescriptor.s b/libc/nt/ntdll/RtlSetAttributesSecurityDescriptor.s new file mode 100644 index 00000000..f304ac4f --- /dev/null +++ b/libc/nt/ntdll/RtlSetAttributesSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetAttributesSecurityDescriptor diff --git a/libc/nt/ntdll/RtlSetBit.s b/libc/nt/ntdll/RtlSetBit.s new file mode 100644 index 00000000..9b8bb60e --- /dev/null +++ b/libc/nt/ntdll/RtlSetBit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetBit diff --git a/libc/nt/ntdll/RtlSetBits.s b/libc/nt/ntdll/RtlSetBits.s new file mode 100644 index 00000000..e899222f --- /dev/null +++ b/libc/nt/ntdll/RtlSetBits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetBits diff --git a/libc/nt/ntdll/RtlSetControlSecurityDescriptor.s b/libc/nt/ntdll/RtlSetControlSecurityDescriptor.s new file mode 100644 index 00000000..858b0fa8 --- /dev/null +++ b/libc/nt/ntdll/RtlSetControlSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetControlSecurityDescriptor diff --git a/libc/nt/ntdll/RtlSetCriticalSectionSpinCount.s b/libc/nt/ntdll/RtlSetCriticalSectionSpinCount.s new file mode 100644 index 00000000..a92cf0b6 --- /dev/null +++ b/libc/nt/ntdll/RtlSetCriticalSectionSpinCount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetCriticalSectionSpinCount diff --git a/libc/nt/ntdll/RtlSetCurrentDirectory_U.s b/libc/nt/ntdll/RtlSetCurrentDirectory_U.s new file mode 100644 index 00000000..0c563794 --- /dev/null +++ b/libc/nt/ntdll/RtlSetCurrentDirectory_U.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetCurrentDirectory_U diff --git a/libc/nt/ntdll/RtlSetCurrentEnvironment.s b/libc/nt/ntdll/RtlSetCurrentEnvironment.s new file mode 100644 index 00000000..83bf9a62 --- /dev/null +++ b/libc/nt/ntdll/RtlSetCurrentEnvironment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetCurrentEnvironment diff --git a/libc/nt/ntdll/RtlSetCurrentTransaction.s b/libc/nt/ntdll/RtlSetCurrentTransaction.s new file mode 100644 index 00000000..45024115 --- /dev/null +++ b/libc/nt/ntdll/RtlSetCurrentTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetCurrentTransaction diff --git a/libc/nt/ntdll/RtlSetDaclSecurityDescriptor.s b/libc/nt/ntdll/RtlSetDaclSecurityDescriptor.s new file mode 100644 index 00000000..38a94bac --- /dev/null +++ b/libc/nt/ntdll/RtlSetDaclSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetDaclSecurityDescriptor diff --git a/libc/nt/ntdll/RtlSetDynamicTimeZoneInformation.s b/libc/nt/ntdll/RtlSetDynamicTimeZoneInformation.s new file mode 100644 index 00000000..ec70e2d9 --- /dev/null +++ b/libc/nt/ntdll/RtlSetDynamicTimeZoneInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetDynamicTimeZoneInformation diff --git a/libc/nt/ntdll/RtlSetEnvironmentStrings.s b/libc/nt/ntdll/RtlSetEnvironmentStrings.s new file mode 100644 index 00000000..57a5e309 --- /dev/null +++ b/libc/nt/ntdll/RtlSetEnvironmentStrings.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetEnvironmentStrings diff --git a/libc/nt/ntdll/RtlSetEnvironmentVar.s b/libc/nt/ntdll/RtlSetEnvironmentVar.s new file mode 100644 index 00000000..117e6f93 --- /dev/null +++ b/libc/nt/ntdll/RtlSetEnvironmentVar.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetEnvironmentVar diff --git a/libc/nt/ntdll/RtlSetEnvironmentVariable.s b/libc/nt/ntdll/RtlSetEnvironmentVariable.s new file mode 100644 index 00000000..d4a7e0ae --- /dev/null +++ b/libc/nt/ntdll/RtlSetEnvironmentVariable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetEnvironmentVariable diff --git a/libc/nt/ntdll/RtlSetExtendedFeaturesMask.s b/libc/nt/ntdll/RtlSetExtendedFeaturesMask.s new file mode 100644 index 00000000..b3411b96 --- /dev/null +++ b/libc/nt/ntdll/RtlSetExtendedFeaturesMask.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetExtendedFeaturesMask diff --git a/libc/nt/ntdll/RtlSetGroupSecurityDescriptor.s b/libc/nt/ntdll/RtlSetGroupSecurityDescriptor.s new file mode 100644 index 00000000..d78dcbfe --- /dev/null +++ b/libc/nt/ntdll/RtlSetGroupSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetGroupSecurityDescriptor diff --git a/libc/nt/ntdll/RtlSetHeapInformation.s b/libc/nt/ntdll/RtlSetHeapInformation.s new file mode 100644 index 00000000..90dfe17f --- /dev/null +++ b/libc/nt/ntdll/RtlSetHeapInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetHeapInformation diff --git a/libc/nt/ntdll/RtlSetImageMitigationPolicy.s b/libc/nt/ntdll/RtlSetImageMitigationPolicy.s new file mode 100644 index 00000000..5b322137 --- /dev/null +++ b/libc/nt/ntdll/RtlSetImageMitigationPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetImageMitigationPolicy diff --git a/libc/nt/ntdll/RtlSetInformationAcl.s b/libc/nt/ntdll/RtlSetInformationAcl.s new file mode 100644 index 00000000..0c3739d0 --- /dev/null +++ b/libc/nt/ntdll/RtlSetInformationAcl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetInformationAcl diff --git a/libc/nt/ntdll/RtlSetIoCompletionCallback.s b/libc/nt/ntdll/RtlSetIoCompletionCallback.s new file mode 100644 index 00000000..c1fe77f0 --- /dev/null +++ b/libc/nt/ntdll/RtlSetIoCompletionCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetIoCompletionCallback diff --git a/libc/nt/ntdll/RtlSetLastWin32Error.s b/libc/nt/ntdll/RtlSetLastWin32Error.s new file mode 100644 index 00000000..ff2b4c91 --- /dev/null +++ b/libc/nt/ntdll/RtlSetLastWin32Error.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetLastWin32Error diff --git a/libc/nt/ntdll/RtlSetLastWin32ErrorAndNtStatusFromNtStatus.s b/libc/nt/ntdll/RtlSetLastWin32ErrorAndNtStatusFromNtStatus.s new file mode 100644 index 00000000..86bf87e7 --- /dev/null +++ b/libc/nt/ntdll/RtlSetLastWin32ErrorAndNtStatusFromNtStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetLastWin32ErrorAndNtStatusFromNtStatus diff --git a/libc/nt/ntdll/RtlSetMemoryStreamSize.s b/libc/nt/ntdll/RtlSetMemoryStreamSize.s new file mode 100644 index 00000000..cc9c3202 --- /dev/null +++ b/libc/nt/ntdll/RtlSetMemoryStreamSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetMemoryStreamSize diff --git a/libc/nt/ntdll/RtlSetOwnerSecurityDescriptor.s b/libc/nt/ntdll/RtlSetOwnerSecurityDescriptor.s new file mode 100644 index 00000000..49fda9d2 --- /dev/null +++ b/libc/nt/ntdll/RtlSetOwnerSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetOwnerSecurityDescriptor diff --git a/libc/nt/ntdll/RtlSetPortableOperatingSystem.s b/libc/nt/ntdll/RtlSetPortableOperatingSystem.s new file mode 100644 index 00000000..168c0ee5 --- /dev/null +++ b/libc/nt/ntdll/RtlSetPortableOperatingSystem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetPortableOperatingSystem diff --git a/libc/nt/ntdll/RtlSetProcessDebugInformation.s b/libc/nt/ntdll/RtlSetProcessDebugInformation.s new file mode 100644 index 00000000..4a21533e --- /dev/null +++ b/libc/nt/ntdll/RtlSetProcessDebugInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetProcessDebugInformation diff --git a/libc/nt/ntdll/RtlSetProcessIsCritical.s b/libc/nt/ntdll/RtlSetProcessIsCritical.s new file mode 100644 index 00000000..d185a39a --- /dev/null +++ b/libc/nt/ntdll/RtlSetProcessIsCritical.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetProcessIsCritical diff --git a/libc/nt/ntdll/RtlSetProcessPlaceholderCompatibilityMode.s b/libc/nt/ntdll/RtlSetProcessPlaceholderCompatibilityMode.s new file mode 100644 index 00000000..74c55974 --- /dev/null +++ b/libc/nt/ntdll/RtlSetProcessPlaceholderCompatibilityMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetProcessPlaceholderCompatibilityMode diff --git a/libc/nt/ntdll/RtlSetProcessPreferredUILanguages.s b/libc/nt/ntdll/RtlSetProcessPreferredUILanguages.s new file mode 100644 index 00000000..69cac7cf --- /dev/null +++ b/libc/nt/ntdll/RtlSetProcessPreferredUILanguages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetProcessPreferredUILanguages diff --git a/libc/nt/ntdll/RtlSetProtectedPolicy.s b/libc/nt/ntdll/RtlSetProtectedPolicy.s new file mode 100644 index 00000000..d83d0220 --- /dev/null +++ b/libc/nt/ntdll/RtlSetProtectedPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetProtectedPolicy diff --git a/libc/nt/ntdll/RtlSetProxiedProcessId.s b/libc/nt/ntdll/RtlSetProxiedProcessId.s new file mode 100644 index 00000000..11886a80 --- /dev/null +++ b/libc/nt/ntdll/RtlSetProxiedProcessId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetProxiedProcessId diff --git a/libc/nt/ntdll/RtlSetSaclSecurityDescriptor.s b/libc/nt/ntdll/RtlSetSaclSecurityDescriptor.s new file mode 100644 index 00000000..f5bf3579 --- /dev/null +++ b/libc/nt/ntdll/RtlSetSaclSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetSaclSecurityDescriptor diff --git a/libc/nt/ntdll/RtlSetSearchPathMode.s b/libc/nt/ntdll/RtlSetSearchPathMode.s new file mode 100644 index 00000000..67dc8799 --- /dev/null +++ b/libc/nt/ntdll/RtlSetSearchPathMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetSearchPathMode diff --git a/libc/nt/ntdll/RtlSetSecurityDescriptorRMControl.s b/libc/nt/ntdll/RtlSetSecurityDescriptorRMControl.s new file mode 100644 index 00000000..707200c5 --- /dev/null +++ b/libc/nt/ntdll/RtlSetSecurityDescriptorRMControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetSecurityDescriptorRMControl diff --git a/libc/nt/ntdll/RtlSetSecurityObject.s b/libc/nt/ntdll/RtlSetSecurityObject.s new file mode 100644 index 00000000..d5d5224d --- /dev/null +++ b/libc/nt/ntdll/RtlSetSecurityObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetSecurityObject diff --git a/libc/nt/ntdll/RtlSetSecurityObjectEx.s b/libc/nt/ntdll/RtlSetSecurityObjectEx.s new file mode 100644 index 00000000..3fc0f1c0 --- /dev/null +++ b/libc/nt/ntdll/RtlSetSecurityObjectEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetSecurityObjectEx diff --git a/libc/nt/ntdll/RtlSetSystemBootStatus.s b/libc/nt/ntdll/RtlSetSystemBootStatus.s new file mode 100644 index 00000000..beeda106 --- /dev/null +++ b/libc/nt/ntdll/RtlSetSystemBootStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetSystemBootStatus diff --git a/libc/nt/ntdll/RtlSetSystemBootStatusEx.s b/libc/nt/ntdll/RtlSetSystemBootStatusEx.s new file mode 100644 index 00000000..d772784f --- /dev/null +++ b/libc/nt/ntdll/RtlSetSystemBootStatusEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetSystemBootStatusEx diff --git a/libc/nt/ntdll/RtlSetThreadErrorMode.s b/libc/nt/ntdll/RtlSetThreadErrorMode.s new file mode 100644 index 00000000..6e88a8b6 --- /dev/null +++ b/libc/nt/ntdll/RtlSetThreadErrorMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetThreadErrorMode diff --git a/libc/nt/ntdll/RtlSetThreadIsCritical.s b/libc/nt/ntdll/RtlSetThreadIsCritical.s new file mode 100644 index 00000000..621ddfda --- /dev/null +++ b/libc/nt/ntdll/RtlSetThreadIsCritical.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetThreadIsCritical diff --git a/libc/nt/ntdll/RtlSetThreadPlaceholderCompatibilityMode.s b/libc/nt/ntdll/RtlSetThreadPlaceholderCompatibilityMode.s new file mode 100644 index 00000000..1499a574 --- /dev/null +++ b/libc/nt/ntdll/RtlSetThreadPlaceholderCompatibilityMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetThreadPlaceholderCompatibilityMode diff --git a/libc/nt/ntdll/RtlSetThreadPoolStartFunc.s b/libc/nt/ntdll/RtlSetThreadPoolStartFunc.s new file mode 100644 index 00000000..5269dd03 --- /dev/null +++ b/libc/nt/ntdll/RtlSetThreadPoolStartFunc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetThreadPoolStartFunc diff --git a/libc/nt/ntdll/RtlSetThreadPreferredUILanguages.s b/libc/nt/ntdll/RtlSetThreadPreferredUILanguages.s new file mode 100644 index 00000000..2338f745 --- /dev/null +++ b/libc/nt/ntdll/RtlSetThreadPreferredUILanguages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetThreadPreferredUILanguages diff --git a/libc/nt/ntdll/RtlSetThreadSubProcessTag.s b/libc/nt/ntdll/RtlSetThreadSubProcessTag.s new file mode 100644 index 00000000..7469b8f1 --- /dev/null +++ b/libc/nt/ntdll/RtlSetThreadSubProcessTag.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetThreadSubProcessTag diff --git a/libc/nt/ntdll/RtlSetThreadWorkOnBehalfTicket.s b/libc/nt/ntdll/RtlSetThreadWorkOnBehalfTicket.s new file mode 100644 index 00000000..7994cacb --- /dev/null +++ b/libc/nt/ntdll/RtlSetThreadWorkOnBehalfTicket.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetThreadWorkOnBehalfTicket diff --git a/libc/nt/ntdll/RtlSetTimeZoneInformation.s b/libc/nt/ntdll/RtlSetTimeZoneInformation.s new file mode 100644 index 00000000..0f5fb734 --- /dev/null +++ b/libc/nt/ntdll/RtlSetTimeZoneInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetTimeZoneInformation diff --git a/libc/nt/ntdll/RtlSetTimer.s b/libc/nt/ntdll/RtlSetTimer.s new file mode 100644 index 00000000..a9d9a881 --- /dev/null +++ b/libc/nt/ntdll/RtlSetTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetTimer diff --git a/libc/nt/ntdll/RtlSetUmsThreadInformation.s b/libc/nt/ntdll/RtlSetUmsThreadInformation.s new file mode 100644 index 00000000..6cdd1da9 --- /dev/null +++ b/libc/nt/ntdll/RtlSetUmsThreadInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetUmsThreadInformation diff --git a/libc/nt/ntdll/RtlSetUnhandledExceptionFilter.s b/libc/nt/ntdll/RtlSetUnhandledExceptionFilter.s new file mode 100644 index 00000000..ee606483 --- /dev/null +++ b/libc/nt/ntdll/RtlSetUnhandledExceptionFilter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetUnhandledExceptionFilter diff --git a/libc/nt/ntdll/RtlSetUserFlagsHeap.s b/libc/nt/ntdll/RtlSetUserFlagsHeap.s new file mode 100644 index 00000000..f7760f68 --- /dev/null +++ b/libc/nt/ntdll/RtlSetUserFlagsHeap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetUserFlagsHeap diff --git a/libc/nt/ntdll/RtlSetUserValueHeap.s b/libc/nt/ntdll/RtlSetUserValueHeap.s new file mode 100644 index 00000000..74b02a8c --- /dev/null +++ b/libc/nt/ntdll/RtlSetUserValueHeap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSetUserValueHeap diff --git a/libc/nt/ntdll/RtlSidDominates.s b/libc/nt/ntdll/RtlSidDominates.s new file mode 100644 index 00000000..c802ba88 --- /dev/null +++ b/libc/nt/ntdll/RtlSidDominates.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSidDominates diff --git a/libc/nt/ntdll/RtlSidDominatesForTrust.s b/libc/nt/ntdll/RtlSidDominatesForTrust.s new file mode 100644 index 00000000..4ef6717e --- /dev/null +++ b/libc/nt/ntdll/RtlSidDominatesForTrust.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSidDominatesForTrust diff --git a/libc/nt/ntdll/RtlSidEqualLevel.s b/libc/nt/ntdll/RtlSidEqualLevel.s new file mode 100644 index 00000000..77d838dd --- /dev/null +++ b/libc/nt/ntdll/RtlSidEqualLevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSidEqualLevel diff --git a/libc/nt/ntdll/RtlSidHashInitialize.s b/libc/nt/ntdll/RtlSidHashInitialize.s new file mode 100644 index 00000000..04bcd48e --- /dev/null +++ b/libc/nt/ntdll/RtlSidHashInitialize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSidHashInitialize diff --git a/libc/nt/ntdll/RtlSidHashLookup.s b/libc/nt/ntdll/RtlSidHashLookup.s new file mode 100644 index 00000000..62f7d0f6 --- /dev/null +++ b/libc/nt/ntdll/RtlSidHashLookup.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSidHashLookup diff --git a/libc/nt/ntdll/RtlSidIsHigherLevel.s b/libc/nt/ntdll/RtlSidIsHigherLevel.s new file mode 100644 index 00000000..b9c0721a --- /dev/null +++ b/libc/nt/ntdll/RtlSidIsHigherLevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSidIsHigherLevel diff --git a/libc/nt/ntdll/RtlSizeHeap.s b/libc/nt/ntdll/RtlSizeHeap.s new file mode 100644 index 00000000..50107993 --- /dev/null +++ b/libc/nt/ntdll/RtlSizeHeap.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSizeHeap + + .text.windows +RtlSizeHeap: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RtlSizeHeap(%rip),%rax + jmp __sysv2nt + .endfn RtlSizeHeap,globl + .previous diff --git a/libc/nt/ntdll/RtlSleepConditionVariableCS.s b/libc/nt/ntdll/RtlSleepConditionVariableCS.s new file mode 100644 index 00000000..d6674ba0 --- /dev/null +++ b/libc/nt/ntdll/RtlSleepConditionVariableCS.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSleepConditionVariableCS diff --git a/libc/nt/ntdll/RtlSleepConditionVariableSRW.s b/libc/nt/ntdll/RtlSleepConditionVariableSRW.s new file mode 100644 index 00000000..181f672a --- /dev/null +++ b/libc/nt/ntdll/RtlSleepConditionVariableSRW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSleepConditionVariableSRW diff --git a/libc/nt/ntdll/RtlSplay.s b/libc/nt/ntdll/RtlSplay.s new file mode 100644 index 00000000..d3949fd4 --- /dev/null +++ b/libc/nt/ntdll/RtlSplay.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSplay diff --git a/libc/nt/ntdll/RtlStartRXact.s b/libc/nt/ntdll/RtlStartRXact.s new file mode 100644 index 00000000..a6af9cb8 --- /dev/null +++ b/libc/nt/ntdll/RtlStartRXact.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlStartRXact diff --git a/libc/nt/ntdll/RtlStatMemoryStream.s b/libc/nt/ntdll/RtlStatMemoryStream.s new file mode 100644 index 00000000..32e20fc9 --- /dev/null +++ b/libc/nt/ntdll/RtlStatMemoryStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlStatMemoryStream diff --git a/libc/nt/ntdll/RtlStringFromGUID.s b/libc/nt/ntdll/RtlStringFromGUID.s new file mode 100644 index 00000000..04cdeed0 --- /dev/null +++ b/libc/nt/ntdll/RtlStringFromGUID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlStringFromGUID diff --git a/libc/nt/ntdll/RtlStringFromGUIDEx.s b/libc/nt/ntdll/RtlStringFromGUIDEx.s new file mode 100644 index 00000000..3a3b83af --- /dev/null +++ b/libc/nt/ntdll/RtlStringFromGUIDEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlStringFromGUIDEx diff --git a/libc/nt/ntdll/RtlStronglyEnumerateEntryHashTable.s b/libc/nt/ntdll/RtlStronglyEnumerateEntryHashTable.s new file mode 100644 index 00000000..c1c14090 --- /dev/null +++ b/libc/nt/ntdll/RtlStronglyEnumerateEntryHashTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlStronglyEnumerateEntryHashTable diff --git a/libc/nt/ntdll/RtlSubAuthorityCountSid.s b/libc/nt/ntdll/RtlSubAuthorityCountSid.s new file mode 100644 index 00000000..cf5497bb --- /dev/null +++ b/libc/nt/ntdll/RtlSubAuthorityCountSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSubAuthorityCountSid diff --git a/libc/nt/ntdll/RtlSubAuthoritySid.s b/libc/nt/ntdll/RtlSubAuthoritySid.s new file mode 100644 index 00000000..5203bfea --- /dev/null +++ b/libc/nt/ntdll/RtlSubAuthoritySid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSubAuthoritySid diff --git a/libc/nt/ntdll/RtlSubscribeWnfStateChangeNotification.s b/libc/nt/ntdll/RtlSubscribeWnfStateChangeNotification.s new file mode 100644 index 00000000..d210a812 --- /dev/null +++ b/libc/nt/ntdll/RtlSubscribeWnfStateChangeNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSubscribeWnfStateChangeNotification diff --git a/libc/nt/ntdll/RtlSubtreePredecessor.s b/libc/nt/ntdll/RtlSubtreePredecessor.s new file mode 100644 index 00000000..4889cb60 --- /dev/null +++ b/libc/nt/ntdll/RtlSubtreePredecessor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSubtreePredecessor diff --git a/libc/nt/ntdll/RtlSubtreeSuccessor.s b/libc/nt/ntdll/RtlSubtreeSuccessor.s new file mode 100644 index 00000000..238af043 --- /dev/null +++ b/libc/nt/ntdll/RtlSubtreeSuccessor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSubtreeSuccessor diff --git a/libc/nt/ntdll/RtlSwitchedVVI.s b/libc/nt/ntdll/RtlSwitchedVVI.s new file mode 100644 index 00000000..59fbc3b1 --- /dev/null +++ b/libc/nt/ntdll/RtlSwitchedVVI.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSwitchedVVI diff --git a/libc/nt/ntdll/RtlSystemTimeToLocalTime.s b/libc/nt/ntdll/RtlSystemTimeToLocalTime.s new file mode 100644 index 00000000..fa0c3b62 --- /dev/null +++ b/libc/nt/ntdll/RtlSystemTimeToLocalTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlSystemTimeToLocalTime diff --git a/libc/nt/ntdll/RtlTestAndPublishWnfStateData.s b/libc/nt/ntdll/RtlTestAndPublishWnfStateData.s new file mode 100644 index 00000000..b70d7f5a --- /dev/null +++ b/libc/nt/ntdll/RtlTestAndPublishWnfStateData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTestAndPublishWnfStateData diff --git a/libc/nt/ntdll/RtlTestBit.s b/libc/nt/ntdll/RtlTestBit.s new file mode 100644 index 00000000..a753a8af --- /dev/null +++ b/libc/nt/ntdll/RtlTestBit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTestBit diff --git a/libc/nt/ntdll/RtlTestBitEx.s b/libc/nt/ntdll/RtlTestBitEx.s new file mode 100644 index 00000000..856fe894 --- /dev/null +++ b/libc/nt/ntdll/RtlTestBitEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTestBitEx diff --git a/libc/nt/ntdll/RtlTestProtectedAccess.s b/libc/nt/ntdll/RtlTestProtectedAccess.s new file mode 100644 index 00000000..24a75703 --- /dev/null +++ b/libc/nt/ntdll/RtlTestProtectedAccess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTestProtectedAccess diff --git a/libc/nt/ntdll/RtlTimeFieldsToTime.s b/libc/nt/ntdll/RtlTimeFieldsToTime.s new file mode 100644 index 00000000..e70856a2 --- /dev/null +++ b/libc/nt/ntdll/RtlTimeFieldsToTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTimeFieldsToTime diff --git a/libc/nt/ntdll/RtlTimeToElapsedTimeFields.s b/libc/nt/ntdll/RtlTimeToElapsedTimeFields.s new file mode 100644 index 00000000..2d7b7da6 --- /dev/null +++ b/libc/nt/ntdll/RtlTimeToElapsedTimeFields.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTimeToElapsedTimeFields diff --git a/libc/nt/ntdll/RtlTimeToSecondsSince1970.s b/libc/nt/ntdll/RtlTimeToSecondsSince1970.s new file mode 100644 index 00000000..85663c85 --- /dev/null +++ b/libc/nt/ntdll/RtlTimeToSecondsSince1970.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTimeToSecondsSince1970 diff --git a/libc/nt/ntdll/RtlTimeToSecondsSince1980.s b/libc/nt/ntdll/RtlTimeToSecondsSince1980.s new file mode 100644 index 00000000..13086312 --- /dev/null +++ b/libc/nt/ntdll/RtlTimeToSecondsSince1980.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTimeToSecondsSince1980 diff --git a/libc/nt/ntdll/RtlTimeToTimeFields.s b/libc/nt/ntdll/RtlTimeToTimeFields.s new file mode 100644 index 00000000..593c8a62 --- /dev/null +++ b/libc/nt/ntdll/RtlTimeToTimeFields.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTimeToTimeFields diff --git a/libc/nt/ntdll/RtlTraceDatabaseAdd.s b/libc/nt/ntdll/RtlTraceDatabaseAdd.s new file mode 100644 index 00000000..dba6f3e4 --- /dev/null +++ b/libc/nt/ntdll/RtlTraceDatabaseAdd.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTraceDatabaseAdd diff --git a/libc/nt/ntdll/RtlTraceDatabaseCreate.s b/libc/nt/ntdll/RtlTraceDatabaseCreate.s new file mode 100644 index 00000000..1a27a598 --- /dev/null +++ b/libc/nt/ntdll/RtlTraceDatabaseCreate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTraceDatabaseCreate diff --git a/libc/nt/ntdll/RtlTraceDatabaseDestroy.s b/libc/nt/ntdll/RtlTraceDatabaseDestroy.s new file mode 100644 index 00000000..1af80f17 --- /dev/null +++ b/libc/nt/ntdll/RtlTraceDatabaseDestroy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTraceDatabaseDestroy diff --git a/libc/nt/ntdll/RtlTraceDatabaseEnumerate.s b/libc/nt/ntdll/RtlTraceDatabaseEnumerate.s new file mode 100644 index 00000000..704275d8 --- /dev/null +++ b/libc/nt/ntdll/RtlTraceDatabaseEnumerate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTraceDatabaseEnumerate diff --git a/libc/nt/ntdll/RtlTraceDatabaseFind.s b/libc/nt/ntdll/RtlTraceDatabaseFind.s new file mode 100644 index 00000000..b68c8806 --- /dev/null +++ b/libc/nt/ntdll/RtlTraceDatabaseFind.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTraceDatabaseFind diff --git a/libc/nt/ntdll/RtlTraceDatabaseLock.s b/libc/nt/ntdll/RtlTraceDatabaseLock.s new file mode 100644 index 00000000..e3ed0f0f --- /dev/null +++ b/libc/nt/ntdll/RtlTraceDatabaseLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTraceDatabaseLock diff --git a/libc/nt/ntdll/RtlTraceDatabaseUnlock.s b/libc/nt/ntdll/RtlTraceDatabaseUnlock.s new file mode 100644 index 00000000..d58da83d --- /dev/null +++ b/libc/nt/ntdll/RtlTraceDatabaseUnlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTraceDatabaseUnlock diff --git a/libc/nt/ntdll/RtlTraceDatabaseValidate.s b/libc/nt/ntdll/RtlTraceDatabaseValidate.s new file mode 100644 index 00000000..9ec4e63b --- /dev/null +++ b/libc/nt/ntdll/RtlTraceDatabaseValidate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTraceDatabaseValidate diff --git a/libc/nt/ntdll/RtlTryAcquirePebLock.s b/libc/nt/ntdll/RtlTryAcquirePebLock.s new file mode 100644 index 00000000..8c4e2be5 --- /dev/null +++ b/libc/nt/ntdll/RtlTryAcquirePebLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTryAcquirePebLock diff --git a/libc/nt/ntdll/RtlTryAcquireSRWLockExclusive.s b/libc/nt/ntdll/RtlTryAcquireSRWLockExclusive.s new file mode 100644 index 00000000..cc6fb38e --- /dev/null +++ b/libc/nt/ntdll/RtlTryAcquireSRWLockExclusive.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTryAcquireSRWLockExclusive diff --git a/libc/nt/ntdll/RtlTryAcquireSRWLockShared.s b/libc/nt/ntdll/RtlTryAcquireSRWLockShared.s new file mode 100644 index 00000000..ae3c74db --- /dev/null +++ b/libc/nt/ntdll/RtlTryAcquireSRWLockShared.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTryAcquireSRWLockShared diff --git a/libc/nt/ntdll/RtlTryConvertSRWLockSharedToExclusiveOrRelease.s b/libc/nt/ntdll/RtlTryConvertSRWLockSharedToExclusiveOrRelease.s new file mode 100644 index 00000000..539cb9c3 --- /dev/null +++ b/libc/nt/ntdll/RtlTryConvertSRWLockSharedToExclusiveOrRelease.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTryConvertSRWLockSharedToExclusiveOrRelease diff --git a/libc/nt/ntdll/RtlTryEnterCriticalSection.s b/libc/nt/ntdll/RtlTryEnterCriticalSection.s new file mode 100644 index 00000000..571aa08f --- /dev/null +++ b/libc/nt/ntdll/RtlTryEnterCriticalSection.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlTryEnterCriticalSection + + .text.windows +RtlTryEnterCriticalSection: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RtlTryEnterCriticalSection(%rip) + leave + ret + .endfn RtlTryEnterCriticalSection,globl + .previous diff --git a/libc/nt/ntdll/RtlUTF8ToUnicodeN.s b/libc/nt/ntdll/RtlUTF8ToUnicodeN.s new file mode 100644 index 00000000..cb03b359 --- /dev/null +++ b/libc/nt/ntdll/RtlUTF8ToUnicodeN.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUTF8ToUnicodeN diff --git a/libc/nt/ntdll/RtlUmsThreadYield.s b/libc/nt/ntdll/RtlUmsThreadYield.s new file mode 100644 index 00000000..78847fbd --- /dev/null +++ b/libc/nt/ntdll/RtlUmsThreadYield.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUmsThreadYield diff --git a/libc/nt/ntdll/RtlUnhandledExceptionFilter.s b/libc/nt/ntdll/RtlUnhandledExceptionFilter.s new file mode 100644 index 00000000..71f6df69 --- /dev/null +++ b/libc/nt/ntdll/RtlUnhandledExceptionFilter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnhandledExceptionFilter diff --git a/libc/nt/ntdll/RtlUnhandledExceptionFilter2.s b/libc/nt/ntdll/RtlUnhandledExceptionFilter2.s new file mode 100644 index 00000000..77f8b687 --- /dev/null +++ b/libc/nt/ntdll/RtlUnhandledExceptionFilter2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnhandledExceptionFilter2 diff --git a/libc/nt/ntdll/RtlUnicodeStringToAnsiSize.s b/libc/nt/ntdll/RtlUnicodeStringToAnsiSize.s new file mode 100644 index 00000000..4e66b134 --- /dev/null +++ b/libc/nt/ntdll/RtlUnicodeStringToAnsiSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnicodeStringToAnsiSize diff --git a/libc/nt/ntdll/RtlUnicodeStringToAnsiString.s b/libc/nt/ntdll/RtlUnicodeStringToAnsiString.s new file mode 100644 index 00000000..279ca0bd --- /dev/null +++ b/libc/nt/ntdll/RtlUnicodeStringToAnsiString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnicodeStringToAnsiString diff --git a/libc/nt/ntdll/RtlUnicodeStringToCountedOemString.s b/libc/nt/ntdll/RtlUnicodeStringToCountedOemString.s new file mode 100644 index 00000000..999752f0 --- /dev/null +++ b/libc/nt/ntdll/RtlUnicodeStringToCountedOemString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnicodeStringToCountedOemString diff --git a/libc/nt/ntdll/RtlUnicodeStringToInteger.s b/libc/nt/ntdll/RtlUnicodeStringToInteger.s new file mode 100644 index 00000000..be1377dc --- /dev/null +++ b/libc/nt/ntdll/RtlUnicodeStringToInteger.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnicodeStringToInteger diff --git a/libc/nt/ntdll/RtlUnicodeStringToOemSize.s b/libc/nt/ntdll/RtlUnicodeStringToOemSize.s new file mode 100644 index 00000000..8b36713c --- /dev/null +++ b/libc/nt/ntdll/RtlUnicodeStringToOemSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnicodeStringToOemSize diff --git a/libc/nt/ntdll/RtlUnicodeStringToOemString.s b/libc/nt/ntdll/RtlUnicodeStringToOemString.s new file mode 100644 index 00000000..7d99b8e9 --- /dev/null +++ b/libc/nt/ntdll/RtlUnicodeStringToOemString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnicodeStringToOemString diff --git a/libc/nt/ntdll/RtlUnicodeToCustomCPN.s b/libc/nt/ntdll/RtlUnicodeToCustomCPN.s new file mode 100644 index 00000000..3483702a --- /dev/null +++ b/libc/nt/ntdll/RtlUnicodeToCustomCPN.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnicodeToCustomCPN diff --git a/libc/nt/ntdll/RtlUnicodeToMultiByteN.s b/libc/nt/ntdll/RtlUnicodeToMultiByteN.s new file mode 100644 index 00000000..e891f463 --- /dev/null +++ b/libc/nt/ntdll/RtlUnicodeToMultiByteN.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnicodeToMultiByteN diff --git a/libc/nt/ntdll/RtlUnicodeToMultiByteSize.s b/libc/nt/ntdll/RtlUnicodeToMultiByteSize.s new file mode 100644 index 00000000..5bf03cde --- /dev/null +++ b/libc/nt/ntdll/RtlUnicodeToMultiByteSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnicodeToMultiByteSize diff --git a/libc/nt/ntdll/RtlUnicodeToOemN.s b/libc/nt/ntdll/RtlUnicodeToOemN.s new file mode 100644 index 00000000..c4f5f347 --- /dev/null +++ b/libc/nt/ntdll/RtlUnicodeToOemN.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnicodeToOemN diff --git a/libc/nt/ntdll/RtlUnicodeToUTF8N.s b/libc/nt/ntdll/RtlUnicodeToUTF8N.s new file mode 100644 index 00000000..1b0840e8 --- /dev/null +++ b/libc/nt/ntdll/RtlUnicodeToUTF8N.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnicodeToUTF8N diff --git a/libc/nt/ntdll/RtlUniform.s b/libc/nt/ntdll/RtlUniform.s new file mode 100644 index 00000000..f38ba700 --- /dev/null +++ b/libc/nt/ntdll/RtlUniform.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUniform diff --git a/libc/nt/ntdll/RtlUnlockBootStatusData.s b/libc/nt/ntdll/RtlUnlockBootStatusData.s new file mode 100644 index 00000000..812aa44d --- /dev/null +++ b/libc/nt/ntdll/RtlUnlockBootStatusData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnlockBootStatusData diff --git a/libc/nt/ntdll/RtlUnlockCurrentThread.s b/libc/nt/ntdll/RtlUnlockCurrentThread.s new file mode 100644 index 00000000..8eb49936 --- /dev/null +++ b/libc/nt/ntdll/RtlUnlockCurrentThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnlockCurrentThread diff --git a/libc/nt/ntdll/RtlUnlockHeap.s b/libc/nt/ntdll/RtlUnlockHeap.s new file mode 100644 index 00000000..bdc300a7 --- /dev/null +++ b/libc/nt/ntdll/RtlUnlockHeap.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnlockHeap + + .text.windows +RtlUnlockHeap: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RtlUnlockHeap(%rip) + leave + ret + .endfn RtlUnlockHeap,globl + .previous diff --git a/libc/nt/ntdll/RtlUnlockMemoryBlockLookaside.s b/libc/nt/ntdll/RtlUnlockMemoryBlockLookaside.s new file mode 100644 index 00000000..7392dddf --- /dev/null +++ b/libc/nt/ntdll/RtlUnlockMemoryBlockLookaside.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnlockMemoryBlockLookaside diff --git a/libc/nt/ntdll/RtlUnlockMemoryStreamRegion.s b/libc/nt/ntdll/RtlUnlockMemoryStreamRegion.s new file mode 100644 index 00000000..5d195cae --- /dev/null +++ b/libc/nt/ntdll/RtlUnlockMemoryStreamRegion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnlockMemoryStreamRegion diff --git a/libc/nt/ntdll/RtlUnlockMemoryZone.s b/libc/nt/ntdll/RtlUnlockMemoryZone.s new file mode 100644 index 00000000..315ef6ec --- /dev/null +++ b/libc/nt/ntdll/RtlUnlockMemoryZone.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnlockMemoryZone diff --git a/libc/nt/ntdll/RtlUnlockModuleSection.s b/libc/nt/ntdll/RtlUnlockModuleSection.s new file mode 100644 index 00000000..06f74a15 --- /dev/null +++ b/libc/nt/ntdll/RtlUnlockModuleSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnlockModuleSection diff --git a/libc/nt/ntdll/RtlUnsubscribeWnfNotificationWaitForCompletion.s b/libc/nt/ntdll/RtlUnsubscribeWnfNotificationWaitForCompletion.s new file mode 100644 index 00000000..3597de1a --- /dev/null +++ b/libc/nt/ntdll/RtlUnsubscribeWnfNotificationWaitForCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnsubscribeWnfNotificationWaitForCompletion diff --git a/libc/nt/ntdll/RtlUnsubscribeWnfNotificationWithCompletionCallback.s b/libc/nt/ntdll/RtlUnsubscribeWnfNotificationWithCompletionCallback.s new file mode 100644 index 00000000..9a225178 --- /dev/null +++ b/libc/nt/ntdll/RtlUnsubscribeWnfNotificationWithCompletionCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnsubscribeWnfNotificationWithCompletionCallback diff --git a/libc/nt/ntdll/RtlUnsubscribeWnfStateChangeNotification.s b/libc/nt/ntdll/RtlUnsubscribeWnfStateChangeNotification.s new file mode 100644 index 00000000..d0d42fa8 --- /dev/null +++ b/libc/nt/ntdll/RtlUnsubscribeWnfStateChangeNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnsubscribeWnfStateChangeNotification diff --git a/libc/nt/ntdll/RtlUnwind.s b/libc/nt/ntdll/RtlUnwind.s new file mode 100644 index 00000000..adecb3a9 --- /dev/null +++ b/libc/nt/ntdll/RtlUnwind.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnwind diff --git a/libc/nt/ntdll/RtlUnwindEx.s b/libc/nt/ntdll/RtlUnwindEx.s new file mode 100644 index 00000000..5927ac88 --- /dev/null +++ b/libc/nt/ntdll/RtlUnwindEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUnwindEx diff --git a/libc/nt/ntdll/RtlUpcaseUnicodeChar.s b/libc/nt/ntdll/RtlUpcaseUnicodeChar.s new file mode 100644 index 00000000..f0c58727 --- /dev/null +++ b/libc/nt/ntdll/RtlUpcaseUnicodeChar.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUpcaseUnicodeChar diff --git a/libc/nt/ntdll/RtlUpcaseUnicodeString.s b/libc/nt/ntdll/RtlUpcaseUnicodeString.s new file mode 100644 index 00000000..ea895e06 --- /dev/null +++ b/libc/nt/ntdll/RtlUpcaseUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUpcaseUnicodeString diff --git a/libc/nt/ntdll/RtlUpcaseUnicodeStringToAnsiString.s b/libc/nt/ntdll/RtlUpcaseUnicodeStringToAnsiString.s new file mode 100644 index 00000000..6550c11b --- /dev/null +++ b/libc/nt/ntdll/RtlUpcaseUnicodeStringToAnsiString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUpcaseUnicodeStringToAnsiString diff --git a/libc/nt/ntdll/RtlUpcaseUnicodeStringToCountedOemString.s b/libc/nt/ntdll/RtlUpcaseUnicodeStringToCountedOemString.s new file mode 100644 index 00000000..1216cd92 --- /dev/null +++ b/libc/nt/ntdll/RtlUpcaseUnicodeStringToCountedOemString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUpcaseUnicodeStringToCountedOemString diff --git a/libc/nt/ntdll/RtlUpcaseUnicodeStringToOemString.s b/libc/nt/ntdll/RtlUpcaseUnicodeStringToOemString.s new file mode 100644 index 00000000..93387016 --- /dev/null +++ b/libc/nt/ntdll/RtlUpcaseUnicodeStringToOemString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUpcaseUnicodeStringToOemString diff --git a/libc/nt/ntdll/RtlUpcaseUnicodeToCustomCPN.s b/libc/nt/ntdll/RtlUpcaseUnicodeToCustomCPN.s new file mode 100644 index 00000000..6f0205a8 --- /dev/null +++ b/libc/nt/ntdll/RtlUpcaseUnicodeToCustomCPN.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUpcaseUnicodeToCustomCPN diff --git a/libc/nt/ntdll/RtlUpcaseUnicodeToMultiByteN.s b/libc/nt/ntdll/RtlUpcaseUnicodeToMultiByteN.s new file mode 100644 index 00000000..e4246b62 --- /dev/null +++ b/libc/nt/ntdll/RtlUpcaseUnicodeToMultiByteN.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUpcaseUnicodeToMultiByteN diff --git a/libc/nt/ntdll/RtlUpcaseUnicodeToOemN.s b/libc/nt/ntdll/RtlUpcaseUnicodeToOemN.s new file mode 100644 index 00000000..42dca569 --- /dev/null +++ b/libc/nt/ntdll/RtlUpcaseUnicodeToOemN.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUpcaseUnicodeToOemN diff --git a/libc/nt/ntdll/RtlUpdateClonedCriticalSection.s b/libc/nt/ntdll/RtlUpdateClonedCriticalSection.s new file mode 100644 index 00000000..422daf22 --- /dev/null +++ b/libc/nt/ntdll/RtlUpdateClonedCriticalSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUpdateClonedCriticalSection diff --git a/libc/nt/ntdll/RtlUpdateClonedSRWLock.s b/libc/nt/ntdll/RtlUpdateClonedSRWLock.s new file mode 100644 index 00000000..b5244eac --- /dev/null +++ b/libc/nt/ntdll/RtlUpdateClonedSRWLock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUpdateClonedSRWLock diff --git a/libc/nt/ntdll/RtlUpdateTimer.s b/libc/nt/ntdll/RtlUpdateTimer.s new file mode 100644 index 00000000..9c280ffb --- /dev/null +++ b/libc/nt/ntdll/RtlUpdateTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUpdateTimer diff --git a/libc/nt/ntdll/RtlUpperChar.s b/libc/nt/ntdll/RtlUpperChar.s new file mode 100644 index 00000000..9e9cfd43 --- /dev/null +++ b/libc/nt/ntdll/RtlUpperChar.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUpperChar diff --git a/libc/nt/ntdll/RtlUpperString.s b/libc/nt/ntdll/RtlUpperString.s new file mode 100644 index 00000000..0b1539b3 --- /dev/null +++ b/libc/nt/ntdll/RtlUpperString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUpperString diff --git a/libc/nt/ntdll/RtlUserThreadStart.s b/libc/nt/ntdll/RtlUserThreadStart.s new file mode 100644 index 00000000..43fcfc6a --- /dev/null +++ b/libc/nt/ntdll/RtlUserThreadStart.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlUserThreadStart diff --git a/libc/nt/ntdll/RtlValidAcl.s b/libc/nt/ntdll/RtlValidAcl.s new file mode 100644 index 00000000..cf033a9a --- /dev/null +++ b/libc/nt/ntdll/RtlValidAcl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlValidAcl diff --git a/libc/nt/ntdll/RtlValidProcessProtection.s b/libc/nt/ntdll/RtlValidProcessProtection.s new file mode 100644 index 00000000..7995dfbd --- /dev/null +++ b/libc/nt/ntdll/RtlValidProcessProtection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlValidProcessProtection diff --git a/libc/nt/ntdll/RtlValidRelativeSecurityDescriptor.s b/libc/nt/ntdll/RtlValidRelativeSecurityDescriptor.s new file mode 100644 index 00000000..3ac6a37d --- /dev/null +++ b/libc/nt/ntdll/RtlValidRelativeSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlValidRelativeSecurityDescriptor diff --git a/libc/nt/ntdll/RtlValidSecurityDescriptor.s b/libc/nt/ntdll/RtlValidSecurityDescriptor.s new file mode 100644 index 00000000..a6d96efc --- /dev/null +++ b/libc/nt/ntdll/RtlValidSecurityDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlValidSecurityDescriptor diff --git a/libc/nt/ntdll/RtlValidSid.s b/libc/nt/ntdll/RtlValidSid.s new file mode 100644 index 00000000..51f72b4c --- /dev/null +++ b/libc/nt/ntdll/RtlValidSid.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlValidSid diff --git a/libc/nt/ntdll/RtlValidateCorrelationVector.s b/libc/nt/ntdll/RtlValidateCorrelationVector.s new file mode 100644 index 00000000..f34f1f20 --- /dev/null +++ b/libc/nt/ntdll/RtlValidateCorrelationVector.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlValidateCorrelationVector diff --git a/libc/nt/ntdll/RtlValidateHeap.s b/libc/nt/ntdll/RtlValidateHeap.s new file mode 100644 index 00000000..be0267ff --- /dev/null +++ b/libc/nt/ntdll/RtlValidateHeap.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlValidateHeap + + .text.windows +RtlValidateHeap: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RtlValidateHeap(%rip),%rax + jmp __sysv2nt + .endfn RtlValidateHeap,globl + .previous diff --git a/libc/nt/ntdll/RtlValidateProcessHeaps.s b/libc/nt/ntdll/RtlValidateProcessHeaps.s new file mode 100644 index 00000000..631de98a --- /dev/null +++ b/libc/nt/ntdll/RtlValidateProcessHeaps.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlValidateProcessHeaps diff --git a/libc/nt/ntdll/RtlValidateUnicodeString.s b/libc/nt/ntdll/RtlValidateUnicodeString.s new file mode 100644 index 00000000..e31b3069 --- /dev/null +++ b/libc/nt/ntdll/RtlValidateUnicodeString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlValidateUnicodeString diff --git a/libc/nt/ntdll/RtlVerifyVersionInfo.s b/libc/nt/ntdll/RtlVerifyVersionInfo.s new file mode 100644 index 00000000..c65f7f97 --- /dev/null +++ b/libc/nt/ntdll/RtlVerifyVersionInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlVerifyVersionInfo diff --git a/libc/nt/ntdll/RtlVirtualUnwind.s b/libc/nt/ntdll/RtlVirtualUnwind.s new file mode 100644 index 00000000..254af9ce --- /dev/null +++ b/libc/nt/ntdll/RtlVirtualUnwind.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlVirtualUnwind diff --git a/libc/nt/ntdll/RtlWaitForWnfMetaNotification.s b/libc/nt/ntdll/RtlWaitForWnfMetaNotification.s new file mode 100644 index 00000000..f7c1ddc6 --- /dev/null +++ b/libc/nt/ntdll/RtlWaitForWnfMetaNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWaitForWnfMetaNotification diff --git a/libc/nt/ntdll/RtlWaitOnAddress.s b/libc/nt/ntdll/RtlWaitOnAddress.s new file mode 100644 index 00000000..8b527295 --- /dev/null +++ b/libc/nt/ntdll/RtlWaitOnAddress.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWaitOnAddress diff --git a/libc/nt/ntdll/RtlWakeAddressAll.s b/libc/nt/ntdll/RtlWakeAddressAll.s new file mode 100644 index 00000000..b215fe87 --- /dev/null +++ b/libc/nt/ntdll/RtlWakeAddressAll.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWakeAddressAll diff --git a/libc/nt/ntdll/RtlWakeAddressAllNoFence.s b/libc/nt/ntdll/RtlWakeAddressAllNoFence.s new file mode 100644 index 00000000..be309cec --- /dev/null +++ b/libc/nt/ntdll/RtlWakeAddressAllNoFence.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWakeAddressAllNoFence diff --git a/libc/nt/ntdll/RtlWakeAddressSingle.s b/libc/nt/ntdll/RtlWakeAddressSingle.s new file mode 100644 index 00000000..9b2c68d7 --- /dev/null +++ b/libc/nt/ntdll/RtlWakeAddressSingle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWakeAddressSingle diff --git a/libc/nt/ntdll/RtlWakeAddressSingleNoFence.s b/libc/nt/ntdll/RtlWakeAddressSingleNoFence.s new file mode 100644 index 00000000..e88db172 --- /dev/null +++ b/libc/nt/ntdll/RtlWakeAddressSingleNoFence.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWakeAddressSingleNoFence diff --git a/libc/nt/ntdll/RtlWakeAllConditionVariable.s b/libc/nt/ntdll/RtlWakeAllConditionVariable.s new file mode 100644 index 00000000..d1bac06b --- /dev/null +++ b/libc/nt/ntdll/RtlWakeAllConditionVariable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWakeAllConditionVariable diff --git a/libc/nt/ntdll/RtlWakeConditionVariable.s b/libc/nt/ntdll/RtlWakeConditionVariable.s new file mode 100644 index 00000000..101f9167 --- /dev/null +++ b/libc/nt/ntdll/RtlWakeConditionVariable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWakeConditionVariable diff --git a/libc/nt/ntdll/RtlWalkFrameChain.s b/libc/nt/ntdll/RtlWalkFrameChain.s new file mode 100644 index 00000000..34cb6c6b --- /dev/null +++ b/libc/nt/ntdll/RtlWalkFrameChain.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWalkFrameChain diff --git a/libc/nt/ntdll/RtlWalkHeap.s b/libc/nt/ntdll/RtlWalkHeap.s new file mode 100644 index 00000000..01634122 --- /dev/null +++ b/libc/nt/ntdll/RtlWalkHeap.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWalkHeap + + .text.windows +RtlWalkHeap: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_RtlWalkHeap(%rip),%rax + jmp __sysv2nt + .endfn RtlWalkHeap,globl + .previous diff --git a/libc/nt/ntdll/RtlWeaklyEnumerateEntryHashTable.s b/libc/nt/ntdll/RtlWeaklyEnumerateEntryHashTable.s new file mode 100644 index 00000000..4ca13f43 --- /dev/null +++ b/libc/nt/ntdll/RtlWeaklyEnumerateEntryHashTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWeaklyEnumerateEntryHashTable diff --git a/libc/nt/ntdll/RtlWerpReportException.s b/libc/nt/ntdll/RtlWerpReportException.s new file mode 100644 index 00000000..09593312 --- /dev/null +++ b/libc/nt/ntdll/RtlWerpReportException.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWerpReportException diff --git a/libc/nt/ntdll/RtlWnfCompareChangeStamp.s b/libc/nt/ntdll/RtlWnfCompareChangeStamp.s new file mode 100644 index 00000000..4f284c8c --- /dev/null +++ b/libc/nt/ntdll/RtlWnfCompareChangeStamp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWnfCompareChangeStamp diff --git a/libc/nt/ntdll/RtlWnfDllUnloadCallback.s b/libc/nt/ntdll/RtlWnfDllUnloadCallback.s new file mode 100644 index 00000000..90811f8c --- /dev/null +++ b/libc/nt/ntdll/RtlWnfDllUnloadCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWnfDllUnloadCallback diff --git a/libc/nt/ntdll/RtlWow64CallFunction64.s b/libc/nt/ntdll/RtlWow64CallFunction64.s new file mode 100644 index 00000000..33fc5883 --- /dev/null +++ b/libc/nt/ntdll/RtlWow64CallFunction64.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64CallFunction64 diff --git a/libc/nt/ntdll/RtlWow64EnableFsRedirection.s b/libc/nt/ntdll/RtlWow64EnableFsRedirection.s new file mode 100644 index 00000000..dd622350 --- /dev/null +++ b/libc/nt/ntdll/RtlWow64EnableFsRedirection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64EnableFsRedirection diff --git a/libc/nt/ntdll/RtlWow64EnableFsRedirectionEx.s b/libc/nt/ntdll/RtlWow64EnableFsRedirectionEx.s new file mode 100644 index 00000000..31e1874c --- /dev/null +++ b/libc/nt/ntdll/RtlWow64EnableFsRedirectionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64EnableFsRedirectionEx diff --git a/libc/nt/ntdll/RtlWow64GetCpuAreaInfo.s b/libc/nt/ntdll/RtlWow64GetCpuAreaInfo.s new file mode 100644 index 00000000..1baf76e1 --- /dev/null +++ b/libc/nt/ntdll/RtlWow64GetCpuAreaInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64GetCpuAreaInfo diff --git a/libc/nt/ntdll/RtlWow64GetCurrentCpuArea.s b/libc/nt/ntdll/RtlWow64GetCurrentCpuArea.s new file mode 100644 index 00000000..58416995 --- /dev/null +++ b/libc/nt/ntdll/RtlWow64GetCurrentCpuArea.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64GetCurrentCpuArea diff --git a/libc/nt/ntdll/RtlWow64GetCurrentMachine.s b/libc/nt/ntdll/RtlWow64GetCurrentMachine.s new file mode 100644 index 00000000..2dfcd11e --- /dev/null +++ b/libc/nt/ntdll/RtlWow64GetCurrentMachine.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64GetCurrentMachine diff --git a/libc/nt/ntdll/RtlWow64GetEquivalentMachineCHPE.s b/libc/nt/ntdll/RtlWow64GetEquivalentMachineCHPE.s new file mode 100644 index 00000000..b2c91c5b --- /dev/null +++ b/libc/nt/ntdll/RtlWow64GetEquivalentMachineCHPE.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64GetEquivalentMachineCHPE diff --git a/libc/nt/ntdll/RtlWow64GetProcessMachines.s b/libc/nt/ntdll/RtlWow64GetProcessMachines.s new file mode 100644 index 00000000..11b1bb3c --- /dev/null +++ b/libc/nt/ntdll/RtlWow64GetProcessMachines.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64GetProcessMachines diff --git a/libc/nt/ntdll/RtlWow64GetSharedInfoProcess.s b/libc/nt/ntdll/RtlWow64GetSharedInfoProcess.s new file mode 100644 index 00000000..f974d314 --- /dev/null +++ b/libc/nt/ntdll/RtlWow64GetSharedInfoProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64GetSharedInfoProcess diff --git a/libc/nt/ntdll/RtlWow64GetThreadContext.s b/libc/nt/ntdll/RtlWow64GetThreadContext.s new file mode 100644 index 00000000..b2250298 --- /dev/null +++ b/libc/nt/ntdll/RtlWow64GetThreadContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64GetThreadContext diff --git a/libc/nt/ntdll/RtlWow64GetThreadSelectorEntry.s b/libc/nt/ntdll/RtlWow64GetThreadSelectorEntry.s new file mode 100644 index 00000000..a825354a --- /dev/null +++ b/libc/nt/ntdll/RtlWow64GetThreadSelectorEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64GetThreadSelectorEntry diff --git a/libc/nt/ntdll/RtlWow64IsWowGuestMachineSupported.s b/libc/nt/ntdll/RtlWow64IsWowGuestMachineSupported.s new file mode 100644 index 00000000..4ea47ad7 --- /dev/null +++ b/libc/nt/ntdll/RtlWow64IsWowGuestMachineSupported.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64IsWowGuestMachineSupported diff --git a/libc/nt/ntdll/RtlWow64LogMessageInEventLogger.s b/libc/nt/ntdll/RtlWow64LogMessageInEventLogger.s new file mode 100644 index 00000000..0d79f31b --- /dev/null +++ b/libc/nt/ntdll/RtlWow64LogMessageInEventLogger.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64LogMessageInEventLogger diff --git a/libc/nt/ntdll/RtlWow64PopAllCrossProcessWork.s b/libc/nt/ntdll/RtlWow64PopAllCrossProcessWork.s new file mode 100644 index 00000000..4b133ab5 --- /dev/null +++ b/libc/nt/ntdll/RtlWow64PopAllCrossProcessWork.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64PopAllCrossProcessWork diff --git a/libc/nt/ntdll/RtlWow64PopCrossProcessWork.s b/libc/nt/ntdll/RtlWow64PopCrossProcessWork.s new file mode 100644 index 00000000..8c96ebd0 --- /dev/null +++ b/libc/nt/ntdll/RtlWow64PopCrossProcessWork.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64PopCrossProcessWork diff --git a/libc/nt/ntdll/RtlWow64PushCrossProcessWork.s b/libc/nt/ntdll/RtlWow64PushCrossProcessWork.s new file mode 100644 index 00000000..edc05e24 --- /dev/null +++ b/libc/nt/ntdll/RtlWow64PushCrossProcessWork.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64PushCrossProcessWork diff --git a/libc/nt/ntdll/RtlWow64SetThreadContext.s b/libc/nt/ntdll/RtlWow64SetThreadContext.s new file mode 100644 index 00000000..d4cbe94d --- /dev/null +++ b/libc/nt/ntdll/RtlWow64SetThreadContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64SetThreadContext diff --git a/libc/nt/ntdll/RtlWow64SuspendThread.s b/libc/nt/ntdll/RtlWow64SuspendThread.s new file mode 100644 index 00000000..cef3bfd1 --- /dev/null +++ b/libc/nt/ntdll/RtlWow64SuspendThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWow64SuspendThread diff --git a/libc/nt/ntdll/RtlWriteMemoryStream.s b/libc/nt/ntdll/RtlWriteMemoryStream.s new file mode 100644 index 00000000..83c5ac31 --- /dev/null +++ b/libc/nt/ntdll/RtlWriteMemoryStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWriteMemoryStream diff --git a/libc/nt/ntdll/RtlWriteNonVolatileMemory.s b/libc/nt/ntdll/RtlWriteNonVolatileMemory.s new file mode 100644 index 00000000..3f79bc0e --- /dev/null +++ b/libc/nt/ntdll/RtlWriteNonVolatileMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWriteNonVolatileMemory diff --git a/libc/nt/ntdll/RtlWriteRegistryValue.s b/libc/nt/ntdll/RtlWriteRegistryValue.s new file mode 100644 index 00000000..7c3579b9 --- /dev/null +++ b/libc/nt/ntdll/RtlWriteRegistryValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlWriteRegistryValue diff --git a/libc/nt/ntdll/RtlZeroHeap.s b/libc/nt/ntdll/RtlZeroHeap.s new file mode 100644 index 00000000..6ccb3e6b --- /dev/null +++ b/libc/nt/ntdll/RtlZeroHeap.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlZeroHeap diff --git a/libc/nt/ntdll/RtlZeroMemory.s b/libc/nt/ntdll/RtlZeroMemory.s new file mode 100644 index 00000000..26692e7c --- /dev/null +++ b/libc/nt/ntdll/RtlZeroMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlZeroMemory diff --git a/libc/nt/ntdll/RtlZombifyActivationContext.s b/libc/nt/ntdll/RtlZombifyActivationContext.s new file mode 100644 index 00000000..3da92634 --- /dev/null +++ b/libc/nt/ntdll/RtlZombifyActivationContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlZombifyActivationContext diff --git a/libc/nt/ntdll/RtlpApplyLengthFunction.s b/libc/nt/ntdll/RtlpApplyLengthFunction.s new file mode 100644 index 00000000..46646b93 --- /dev/null +++ b/libc/nt/ntdll/RtlpApplyLengthFunction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpApplyLengthFunction diff --git a/libc/nt/ntdll/RtlpCheckDynamicTimeZoneInformation.s b/libc/nt/ntdll/RtlpCheckDynamicTimeZoneInformation.s new file mode 100644 index 00000000..6272ac17 --- /dev/null +++ b/libc/nt/ntdll/RtlpCheckDynamicTimeZoneInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpCheckDynamicTimeZoneInformation diff --git a/libc/nt/ntdll/RtlpCleanupRegistryKeys.s b/libc/nt/ntdll/RtlpCleanupRegistryKeys.s new file mode 100644 index 00000000..42d16252 --- /dev/null +++ b/libc/nt/ntdll/RtlpCleanupRegistryKeys.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpCleanupRegistryKeys diff --git a/libc/nt/ntdll/RtlpConvertAbsoluteToRelativeSecurityAttribute.s b/libc/nt/ntdll/RtlpConvertAbsoluteToRelativeSecurityAttribute.s new file mode 100644 index 00000000..2016f7e6 --- /dev/null +++ b/libc/nt/ntdll/RtlpConvertAbsoluteToRelativeSecurityAttribute.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpConvertAbsoluteToRelativeSecurityAttribute diff --git a/libc/nt/ntdll/RtlpConvertCultureNamesToLCIDs.s b/libc/nt/ntdll/RtlpConvertCultureNamesToLCIDs.s new file mode 100644 index 00000000..5fb86f4e --- /dev/null +++ b/libc/nt/ntdll/RtlpConvertCultureNamesToLCIDs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpConvertCultureNamesToLCIDs diff --git a/libc/nt/ntdll/RtlpConvertLCIDsToCultureNames.s b/libc/nt/ntdll/RtlpConvertLCIDsToCultureNames.s new file mode 100644 index 00000000..e8ed2ec3 --- /dev/null +++ b/libc/nt/ntdll/RtlpConvertLCIDsToCultureNames.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpConvertLCIDsToCultureNames diff --git a/libc/nt/ntdll/RtlpConvertRelativeToAbsoluteSecurityAttribute.s b/libc/nt/ntdll/RtlpConvertRelativeToAbsoluteSecurityAttribute.s new file mode 100644 index 00000000..a3b9b4f1 --- /dev/null +++ b/libc/nt/ntdll/RtlpConvertRelativeToAbsoluteSecurityAttribute.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpConvertRelativeToAbsoluteSecurityAttribute diff --git a/libc/nt/ntdll/RtlpCreateProcessRegistryInfo.s b/libc/nt/ntdll/RtlpCreateProcessRegistryInfo.s new file mode 100644 index 00000000..9760afc9 --- /dev/null +++ b/libc/nt/ntdll/RtlpCreateProcessRegistryInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpCreateProcessRegistryInfo diff --git a/libc/nt/ntdll/RtlpEnsureBufferSize.s b/libc/nt/ntdll/RtlpEnsureBufferSize.s new file mode 100644 index 00000000..3ceae35e --- /dev/null +++ b/libc/nt/ntdll/RtlpEnsureBufferSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpEnsureBufferSize diff --git a/libc/nt/ntdll/RtlpExecuteUmsThread.s b/libc/nt/ntdll/RtlpExecuteUmsThread.s new file mode 100644 index 00000000..ebc18229 --- /dev/null +++ b/libc/nt/ntdll/RtlpExecuteUmsThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpExecuteUmsThread diff --git a/libc/nt/ntdll/RtlpFreezeTimeBias.s b/libc/nt/ntdll/RtlpFreezeTimeBias.s new file mode 100644 index 00000000..7ac1b2c7 --- /dev/null +++ b/libc/nt/ntdll/RtlpFreezeTimeBias.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpFreezeTimeBias diff --git a/libc/nt/ntdll/RtlpGetDeviceFamilyInfoEnum.s b/libc/nt/ntdll/RtlpGetDeviceFamilyInfoEnum.s new file mode 100644 index 00000000..d61bd3cd --- /dev/null +++ b/libc/nt/ntdll/RtlpGetDeviceFamilyInfoEnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpGetDeviceFamilyInfoEnum diff --git a/libc/nt/ntdll/RtlpGetLCIDFromLangInfoNode.s b/libc/nt/ntdll/RtlpGetLCIDFromLangInfoNode.s new file mode 100644 index 00000000..a61e3471 --- /dev/null +++ b/libc/nt/ntdll/RtlpGetLCIDFromLangInfoNode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpGetLCIDFromLangInfoNode diff --git a/libc/nt/ntdll/RtlpGetNameFromLangInfoNode.s b/libc/nt/ntdll/RtlpGetNameFromLangInfoNode.s new file mode 100644 index 00000000..44807b7f --- /dev/null +++ b/libc/nt/ntdll/RtlpGetNameFromLangInfoNode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpGetNameFromLangInfoNode diff --git a/libc/nt/ntdll/RtlpGetSystemDefaultUILanguage.s b/libc/nt/ntdll/RtlpGetSystemDefaultUILanguage.s new file mode 100644 index 00000000..cef04979 --- /dev/null +++ b/libc/nt/ntdll/RtlpGetSystemDefaultUILanguage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpGetSystemDefaultUILanguage diff --git a/libc/nt/ntdll/RtlpGetUserOrMachineUILanguage4NLS.s b/libc/nt/ntdll/RtlpGetUserOrMachineUILanguage4NLS.s new file mode 100644 index 00000000..d3b38e0f --- /dev/null +++ b/libc/nt/ntdll/RtlpGetUserOrMachineUILanguage4NLS.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpGetUserOrMachineUILanguage4NLS diff --git a/libc/nt/ntdll/RtlpInitializeLangRegistryInfo.s b/libc/nt/ntdll/RtlpInitializeLangRegistryInfo.s new file mode 100644 index 00000000..0a4ea60b --- /dev/null +++ b/libc/nt/ntdll/RtlpInitializeLangRegistryInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpInitializeLangRegistryInfo diff --git a/libc/nt/ntdll/RtlpIsQualifiedLanguage.s b/libc/nt/ntdll/RtlpIsQualifiedLanguage.s new file mode 100644 index 00000000..20150a60 --- /dev/null +++ b/libc/nt/ntdll/RtlpIsQualifiedLanguage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpIsQualifiedLanguage diff --git a/libc/nt/ntdll/RtlpLoadMachineUIByPolicy.s b/libc/nt/ntdll/RtlpLoadMachineUIByPolicy.s new file mode 100644 index 00000000..613c2aa0 --- /dev/null +++ b/libc/nt/ntdll/RtlpLoadMachineUIByPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpLoadMachineUIByPolicy diff --git a/libc/nt/ntdll/RtlpLoadUserUIByPolicy.s b/libc/nt/ntdll/RtlpLoadUserUIByPolicy.s new file mode 100644 index 00000000..63f6e73e --- /dev/null +++ b/libc/nt/ntdll/RtlpLoadUserUIByPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpLoadUserUIByPolicy diff --git a/libc/nt/ntdll/RtlpMergeSecurityAttributeInformation.s b/libc/nt/ntdll/RtlpMergeSecurityAttributeInformation.s new file mode 100644 index 00000000..cf4e4646 --- /dev/null +++ b/libc/nt/ntdll/RtlpMergeSecurityAttributeInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpMergeSecurityAttributeInformation diff --git a/libc/nt/ntdll/RtlpMuiFreeLangRegistryInfo.s b/libc/nt/ntdll/RtlpMuiFreeLangRegistryInfo.s new file mode 100644 index 00000000..90191793 --- /dev/null +++ b/libc/nt/ntdll/RtlpMuiFreeLangRegistryInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpMuiFreeLangRegistryInfo diff --git a/libc/nt/ntdll/RtlpMuiRegCreateRegistryInfo.s b/libc/nt/ntdll/RtlpMuiRegCreateRegistryInfo.s new file mode 100644 index 00000000..ff5a62f7 --- /dev/null +++ b/libc/nt/ntdll/RtlpMuiRegCreateRegistryInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpMuiRegCreateRegistryInfo diff --git a/libc/nt/ntdll/RtlpMuiRegFreeRegistryInfo.s b/libc/nt/ntdll/RtlpMuiRegFreeRegistryInfo.s new file mode 100644 index 00000000..9cb92d28 --- /dev/null +++ b/libc/nt/ntdll/RtlpMuiRegFreeRegistryInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpMuiRegFreeRegistryInfo diff --git a/libc/nt/ntdll/RtlpMuiRegLoadRegistryInfo.s b/libc/nt/ntdll/RtlpMuiRegLoadRegistryInfo.s new file mode 100644 index 00000000..df3b90de --- /dev/null +++ b/libc/nt/ntdll/RtlpMuiRegLoadRegistryInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpMuiRegLoadRegistryInfo diff --git a/libc/nt/ntdll/RtlpNotOwnerCriticalSection.s b/libc/nt/ntdll/RtlpNotOwnerCriticalSection.s new file mode 100644 index 00000000..3a98ab26 --- /dev/null +++ b/libc/nt/ntdll/RtlpNotOwnerCriticalSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpNotOwnerCriticalSection diff --git a/libc/nt/ntdll/RtlpNtCreateKey.s b/libc/nt/ntdll/RtlpNtCreateKey.s new file mode 100644 index 00000000..6843dc8d --- /dev/null +++ b/libc/nt/ntdll/RtlpNtCreateKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpNtCreateKey diff --git a/libc/nt/ntdll/RtlpNtEnumerateSubKey.s b/libc/nt/ntdll/RtlpNtEnumerateSubKey.s new file mode 100644 index 00000000..84572750 --- /dev/null +++ b/libc/nt/ntdll/RtlpNtEnumerateSubKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpNtEnumerateSubKey diff --git a/libc/nt/ntdll/RtlpNtMakeTemporaryKey.s b/libc/nt/ntdll/RtlpNtMakeTemporaryKey.s new file mode 100644 index 00000000..71e8056b --- /dev/null +++ b/libc/nt/ntdll/RtlpNtMakeTemporaryKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpNtMakeTemporaryKey diff --git a/libc/nt/ntdll/RtlpNtOpenKey.s b/libc/nt/ntdll/RtlpNtOpenKey.s new file mode 100644 index 00000000..6ce81ddf --- /dev/null +++ b/libc/nt/ntdll/RtlpNtOpenKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpNtOpenKey diff --git a/libc/nt/ntdll/RtlpNtQueryValueKey.s b/libc/nt/ntdll/RtlpNtQueryValueKey.s new file mode 100644 index 00000000..1d618d3e --- /dev/null +++ b/libc/nt/ntdll/RtlpNtQueryValueKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpNtQueryValueKey diff --git a/libc/nt/ntdll/RtlpNtSetValueKey.s b/libc/nt/ntdll/RtlpNtSetValueKey.s new file mode 100644 index 00000000..fdf50087 --- /dev/null +++ b/libc/nt/ntdll/RtlpNtSetValueKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpNtSetValueKey diff --git a/libc/nt/ntdll/RtlpQueryDefaultUILanguage.s b/libc/nt/ntdll/RtlpQueryDefaultUILanguage.s new file mode 100644 index 00000000..388a4fcb --- /dev/null +++ b/libc/nt/ntdll/RtlpQueryDefaultUILanguage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpQueryDefaultUILanguage diff --git a/libc/nt/ntdll/RtlpQueryProcessDebugInformationFromWow64.s b/libc/nt/ntdll/RtlpQueryProcessDebugInformationFromWow64.s new file mode 100644 index 00000000..0a960344 --- /dev/null +++ b/libc/nt/ntdll/RtlpQueryProcessDebugInformationFromWow64.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpQueryProcessDebugInformationFromWow64 diff --git a/libc/nt/ntdll/RtlpQueryProcessDebugInformationRemote.s b/libc/nt/ntdll/RtlpQueryProcessDebugInformationRemote.s new file mode 100644 index 00000000..9925e896 --- /dev/null +++ b/libc/nt/ntdll/RtlpQueryProcessDebugInformationRemote.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpQueryProcessDebugInformationRemote diff --git a/libc/nt/ntdll/RtlpRefreshCachedUILanguage.s b/libc/nt/ntdll/RtlpRefreshCachedUILanguage.s new file mode 100644 index 00000000..93d82890 --- /dev/null +++ b/libc/nt/ntdll/RtlpRefreshCachedUILanguage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpRefreshCachedUILanguage diff --git a/libc/nt/ntdll/RtlpSetInstallLanguage.s b/libc/nt/ntdll/RtlpSetInstallLanguage.s new file mode 100644 index 00000000..d6fee068 --- /dev/null +++ b/libc/nt/ntdll/RtlpSetInstallLanguage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpSetInstallLanguage diff --git a/libc/nt/ntdll/RtlpSetPreferredUILanguages.s b/libc/nt/ntdll/RtlpSetPreferredUILanguages.s new file mode 100644 index 00000000..2e06ff43 --- /dev/null +++ b/libc/nt/ntdll/RtlpSetPreferredUILanguages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpSetPreferredUILanguages diff --git a/libc/nt/ntdll/RtlpSetUserPreferredUILanguages.s b/libc/nt/ntdll/RtlpSetUserPreferredUILanguages.s new file mode 100644 index 00000000..47e554c9 --- /dev/null +++ b/libc/nt/ntdll/RtlpSetUserPreferredUILanguages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpSetUserPreferredUILanguages diff --git a/libc/nt/ntdll/RtlpUmsExecuteYieldThreadEnd.s b/libc/nt/ntdll/RtlpUmsExecuteYieldThreadEnd.s new file mode 100644 index 00000000..6d478e3f --- /dev/null +++ b/libc/nt/ntdll/RtlpUmsExecuteYieldThreadEnd.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpUmsExecuteYieldThreadEnd diff --git a/libc/nt/ntdll/RtlpUmsThreadYield.s b/libc/nt/ntdll/RtlpUmsThreadYield.s new file mode 100644 index 00000000..2b71d123 --- /dev/null +++ b/libc/nt/ntdll/RtlpUmsThreadYield.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpUmsThreadYield diff --git a/libc/nt/ntdll/RtlpUnWaitCriticalSection.s b/libc/nt/ntdll/RtlpUnWaitCriticalSection.s new file mode 100644 index 00000000..8cea0654 --- /dev/null +++ b/libc/nt/ntdll/RtlpUnWaitCriticalSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpUnWaitCriticalSection diff --git a/libc/nt/ntdll/RtlpVerifyAndCommitUILanguageSettings.s b/libc/nt/ntdll/RtlpVerifyAndCommitUILanguageSettings.s new file mode 100644 index 00000000..52f528c0 --- /dev/null +++ b/libc/nt/ntdll/RtlpVerifyAndCommitUILanguageSettings.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpVerifyAndCommitUILanguageSettings diff --git a/libc/nt/ntdll/RtlpWaitForCriticalSection.s b/libc/nt/ntdll/RtlpWaitForCriticalSection.s new file mode 100644 index 00000000..886d998f --- /dev/null +++ b/libc/nt/ntdll/RtlpWaitForCriticalSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlpWaitForCriticalSection diff --git a/libc/nt/ntdll/RtlxAnsiStringToUnicodeSize.s b/libc/nt/ntdll/RtlxAnsiStringToUnicodeSize.s new file mode 100644 index 00000000..d5246dc7 --- /dev/null +++ b/libc/nt/ntdll/RtlxAnsiStringToUnicodeSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlxAnsiStringToUnicodeSize diff --git a/libc/nt/ntdll/RtlxOemStringToUnicodeSize.s b/libc/nt/ntdll/RtlxOemStringToUnicodeSize.s new file mode 100644 index 00000000..80c6c0dc --- /dev/null +++ b/libc/nt/ntdll/RtlxOemStringToUnicodeSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlxOemStringToUnicodeSize diff --git a/libc/nt/ntdll/RtlxUnicodeStringToAnsiSize.s b/libc/nt/ntdll/RtlxUnicodeStringToAnsiSize.s new file mode 100644 index 00000000..971cfe28 --- /dev/null +++ b/libc/nt/ntdll/RtlxUnicodeStringToAnsiSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlxUnicodeStringToAnsiSize diff --git a/libc/nt/ntdll/RtlxUnicodeStringToOemSize.s b/libc/nt/ntdll/RtlxUnicodeStringToOemSize.s new file mode 100644 index 00000000..d8c0681d --- /dev/null +++ b/libc/nt/ntdll/RtlxUnicodeStringToOemSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp RtlxUnicodeStringToOemSize diff --git a/libc/nt/ntdll/SbExecuteProcedure.s b/libc/nt/ntdll/SbExecuteProcedure.s new file mode 100644 index 00000000..de782271 --- /dev/null +++ b/libc/nt/ntdll/SbExecuteProcedure.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp SbExecuteProcedure diff --git a/libc/nt/ntdll/SbSelectProcedure.s b/libc/nt/ntdll/SbSelectProcedure.s new file mode 100644 index 00000000..993e4fdd --- /dev/null +++ b/libc/nt/ntdll/SbSelectProcedure.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp SbSelectProcedure diff --git a/libc/nt/ntdll/ShipAssert.s b/libc/nt/ntdll/ShipAssert.s new file mode 100644 index 00000000..64cc76ec --- /dev/null +++ b/libc/nt/ntdll/ShipAssert.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ShipAssert diff --git a/libc/nt/ntdll/ShipAssertGetBufferInfo.s b/libc/nt/ntdll/ShipAssertGetBufferInfo.s new file mode 100644 index 00000000..a0b8ebf1 --- /dev/null +++ b/libc/nt/ntdll/ShipAssertGetBufferInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ShipAssertGetBufferInfo diff --git a/libc/nt/ntdll/ShipAssertMsgA.s b/libc/nt/ntdll/ShipAssertMsgA.s new file mode 100644 index 00000000..24696c06 --- /dev/null +++ b/libc/nt/ntdll/ShipAssertMsgA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ShipAssertMsgA diff --git a/libc/nt/ntdll/ShipAssertMsgW.s b/libc/nt/ntdll/ShipAssertMsgW.s new file mode 100644 index 00000000..33cb8ee1 --- /dev/null +++ b/libc/nt/ntdll/ShipAssertMsgW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ShipAssertMsgW diff --git a/libc/nt/ntdll/TpAllocAlpcCompletion.s b/libc/nt/ntdll/TpAllocAlpcCompletion.s new file mode 100644 index 00000000..8c206173 --- /dev/null +++ b/libc/nt/ntdll/TpAllocAlpcCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpAllocAlpcCompletion diff --git a/libc/nt/ntdll/TpAllocAlpcCompletionEx.s b/libc/nt/ntdll/TpAllocAlpcCompletionEx.s new file mode 100644 index 00000000..debbb688 --- /dev/null +++ b/libc/nt/ntdll/TpAllocAlpcCompletionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpAllocAlpcCompletionEx diff --git a/libc/nt/ntdll/TpAllocCleanupGroup.s b/libc/nt/ntdll/TpAllocCleanupGroup.s new file mode 100644 index 00000000..f5984134 --- /dev/null +++ b/libc/nt/ntdll/TpAllocCleanupGroup.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpAllocCleanupGroup diff --git a/libc/nt/ntdll/TpAllocIoCompletion.s b/libc/nt/ntdll/TpAllocIoCompletion.s new file mode 100644 index 00000000..79837e77 --- /dev/null +++ b/libc/nt/ntdll/TpAllocIoCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpAllocIoCompletion diff --git a/libc/nt/ntdll/TpAllocJobNotification.s b/libc/nt/ntdll/TpAllocJobNotification.s new file mode 100644 index 00000000..73212a25 --- /dev/null +++ b/libc/nt/ntdll/TpAllocJobNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpAllocJobNotification diff --git a/libc/nt/ntdll/TpAllocPool.s b/libc/nt/ntdll/TpAllocPool.s new file mode 100644 index 00000000..ceb1d608 --- /dev/null +++ b/libc/nt/ntdll/TpAllocPool.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpAllocPool diff --git a/libc/nt/ntdll/TpAllocTimer.s b/libc/nt/ntdll/TpAllocTimer.s new file mode 100644 index 00000000..144bd50b --- /dev/null +++ b/libc/nt/ntdll/TpAllocTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpAllocTimer diff --git a/libc/nt/ntdll/TpAllocWait.s b/libc/nt/ntdll/TpAllocWait.s new file mode 100644 index 00000000..67ea8cad --- /dev/null +++ b/libc/nt/ntdll/TpAllocWait.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpAllocWait diff --git a/libc/nt/ntdll/TpAllocWork.s b/libc/nt/ntdll/TpAllocWork.s new file mode 100644 index 00000000..d17a1486 --- /dev/null +++ b/libc/nt/ntdll/TpAllocWork.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpAllocWork diff --git a/libc/nt/ntdll/TpAlpcRegisterCompletionList.s b/libc/nt/ntdll/TpAlpcRegisterCompletionList.s new file mode 100644 index 00000000..d85b495d --- /dev/null +++ b/libc/nt/ntdll/TpAlpcRegisterCompletionList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpAlpcRegisterCompletionList diff --git a/libc/nt/ntdll/TpAlpcUnregisterCompletionList.s b/libc/nt/ntdll/TpAlpcUnregisterCompletionList.s new file mode 100644 index 00000000..dcf5216b --- /dev/null +++ b/libc/nt/ntdll/TpAlpcUnregisterCompletionList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpAlpcUnregisterCompletionList diff --git a/libc/nt/ntdll/TpCallbackDetectedUnrecoverableError.s b/libc/nt/ntdll/TpCallbackDetectedUnrecoverableError.s new file mode 100644 index 00000000..f1507ba2 --- /dev/null +++ b/libc/nt/ntdll/TpCallbackDetectedUnrecoverableError.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpCallbackDetectedUnrecoverableError diff --git a/libc/nt/ntdll/TpCallbackIndependent.s b/libc/nt/ntdll/TpCallbackIndependent.s new file mode 100644 index 00000000..6250d3e8 --- /dev/null +++ b/libc/nt/ntdll/TpCallbackIndependent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpCallbackIndependent diff --git a/libc/nt/ntdll/TpCallbackLeaveCriticalSectionOnCompletion.s b/libc/nt/ntdll/TpCallbackLeaveCriticalSectionOnCompletion.s new file mode 100644 index 00000000..b626d168 --- /dev/null +++ b/libc/nt/ntdll/TpCallbackLeaveCriticalSectionOnCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpCallbackLeaveCriticalSectionOnCompletion diff --git a/libc/nt/ntdll/TpCallbackMayRunLong.s b/libc/nt/ntdll/TpCallbackMayRunLong.s new file mode 100644 index 00000000..8b1bbb7b --- /dev/null +++ b/libc/nt/ntdll/TpCallbackMayRunLong.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpCallbackMayRunLong diff --git a/libc/nt/ntdll/TpCallbackReleaseMutexOnCompletion.s b/libc/nt/ntdll/TpCallbackReleaseMutexOnCompletion.s new file mode 100644 index 00000000..2bb2e5b0 --- /dev/null +++ b/libc/nt/ntdll/TpCallbackReleaseMutexOnCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpCallbackReleaseMutexOnCompletion diff --git a/libc/nt/ntdll/TpCallbackReleaseSemaphoreOnCompletion.s b/libc/nt/ntdll/TpCallbackReleaseSemaphoreOnCompletion.s new file mode 100644 index 00000000..5be51e66 --- /dev/null +++ b/libc/nt/ntdll/TpCallbackReleaseSemaphoreOnCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpCallbackReleaseSemaphoreOnCompletion diff --git a/libc/nt/ntdll/TpCallbackSendAlpcMessageOnCompletion.s b/libc/nt/ntdll/TpCallbackSendAlpcMessageOnCompletion.s new file mode 100644 index 00000000..43a48e46 --- /dev/null +++ b/libc/nt/ntdll/TpCallbackSendAlpcMessageOnCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpCallbackSendAlpcMessageOnCompletion diff --git a/libc/nt/ntdll/TpCallbackSendPendingAlpcMessage.s b/libc/nt/ntdll/TpCallbackSendPendingAlpcMessage.s new file mode 100644 index 00000000..19569919 --- /dev/null +++ b/libc/nt/ntdll/TpCallbackSendPendingAlpcMessage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpCallbackSendPendingAlpcMessage diff --git a/libc/nt/ntdll/TpCallbackSetEventOnCompletion.s b/libc/nt/ntdll/TpCallbackSetEventOnCompletion.s new file mode 100644 index 00000000..b87c26e5 --- /dev/null +++ b/libc/nt/ntdll/TpCallbackSetEventOnCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpCallbackSetEventOnCompletion diff --git a/libc/nt/ntdll/TpCallbackUnloadDllOnCompletion.s b/libc/nt/ntdll/TpCallbackUnloadDllOnCompletion.s new file mode 100644 index 00000000..a0d4abc1 --- /dev/null +++ b/libc/nt/ntdll/TpCallbackUnloadDllOnCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpCallbackUnloadDllOnCompletion diff --git a/libc/nt/ntdll/TpCancelAsyncIoOperation.s b/libc/nt/ntdll/TpCancelAsyncIoOperation.s new file mode 100644 index 00000000..4d4b4398 --- /dev/null +++ b/libc/nt/ntdll/TpCancelAsyncIoOperation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpCancelAsyncIoOperation diff --git a/libc/nt/ntdll/TpCaptureCaller.s b/libc/nt/ntdll/TpCaptureCaller.s new file mode 100644 index 00000000..df2baedf --- /dev/null +++ b/libc/nt/ntdll/TpCaptureCaller.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpCaptureCaller diff --git a/libc/nt/ntdll/TpCheckTerminateWorker.s b/libc/nt/ntdll/TpCheckTerminateWorker.s new file mode 100644 index 00000000..331d2b9c --- /dev/null +++ b/libc/nt/ntdll/TpCheckTerminateWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpCheckTerminateWorker diff --git a/libc/nt/ntdll/TpDbgDumpHeapUsage.s b/libc/nt/ntdll/TpDbgDumpHeapUsage.s new file mode 100644 index 00000000..72dc0d6d --- /dev/null +++ b/libc/nt/ntdll/TpDbgDumpHeapUsage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpDbgDumpHeapUsage diff --git a/libc/nt/ntdll/TpDbgSetLogRoutine.s b/libc/nt/ntdll/TpDbgSetLogRoutine.s new file mode 100644 index 00000000..9b6e6b59 --- /dev/null +++ b/libc/nt/ntdll/TpDbgSetLogRoutine.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpDbgSetLogRoutine diff --git a/libc/nt/ntdll/TpDisablePoolCallbackChecks.s b/libc/nt/ntdll/TpDisablePoolCallbackChecks.s new file mode 100644 index 00000000..ea695581 --- /dev/null +++ b/libc/nt/ntdll/TpDisablePoolCallbackChecks.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpDisablePoolCallbackChecks diff --git a/libc/nt/ntdll/TpDisassociateCallback.s b/libc/nt/ntdll/TpDisassociateCallback.s new file mode 100644 index 00000000..b5b4f1d0 --- /dev/null +++ b/libc/nt/ntdll/TpDisassociateCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpDisassociateCallback diff --git a/libc/nt/ntdll/TpIsTimerSet.s b/libc/nt/ntdll/TpIsTimerSet.s new file mode 100644 index 00000000..2018571f --- /dev/null +++ b/libc/nt/ntdll/TpIsTimerSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpIsTimerSet diff --git a/libc/nt/ntdll/TpPostWork.s b/libc/nt/ntdll/TpPostWork.s new file mode 100644 index 00000000..f6c2c8af --- /dev/null +++ b/libc/nt/ntdll/TpPostWork.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpPostWork diff --git a/libc/nt/ntdll/TpQueryPoolStackInformation.s b/libc/nt/ntdll/TpQueryPoolStackInformation.s new file mode 100644 index 00000000..c95674b2 --- /dev/null +++ b/libc/nt/ntdll/TpQueryPoolStackInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpQueryPoolStackInformation diff --git a/libc/nt/ntdll/TpReleaseAlpcCompletion.s b/libc/nt/ntdll/TpReleaseAlpcCompletion.s new file mode 100644 index 00000000..7bf75221 --- /dev/null +++ b/libc/nt/ntdll/TpReleaseAlpcCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpReleaseAlpcCompletion diff --git a/libc/nt/ntdll/TpReleaseCleanupGroup.s b/libc/nt/ntdll/TpReleaseCleanupGroup.s new file mode 100644 index 00000000..41f95fec --- /dev/null +++ b/libc/nt/ntdll/TpReleaseCleanupGroup.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpReleaseCleanupGroup diff --git a/libc/nt/ntdll/TpReleaseCleanupGroupMembers.s b/libc/nt/ntdll/TpReleaseCleanupGroupMembers.s new file mode 100644 index 00000000..b2868235 --- /dev/null +++ b/libc/nt/ntdll/TpReleaseCleanupGroupMembers.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpReleaseCleanupGroupMembers diff --git a/libc/nt/ntdll/TpReleaseIoCompletion.s b/libc/nt/ntdll/TpReleaseIoCompletion.s new file mode 100644 index 00000000..ef17d3d5 --- /dev/null +++ b/libc/nt/ntdll/TpReleaseIoCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpReleaseIoCompletion diff --git a/libc/nt/ntdll/TpReleaseJobNotification.s b/libc/nt/ntdll/TpReleaseJobNotification.s new file mode 100644 index 00000000..209bc694 --- /dev/null +++ b/libc/nt/ntdll/TpReleaseJobNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpReleaseJobNotification diff --git a/libc/nt/ntdll/TpReleasePool.s b/libc/nt/ntdll/TpReleasePool.s new file mode 100644 index 00000000..391ab63a --- /dev/null +++ b/libc/nt/ntdll/TpReleasePool.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpReleasePool diff --git a/libc/nt/ntdll/TpReleaseTimer.s b/libc/nt/ntdll/TpReleaseTimer.s new file mode 100644 index 00000000..aea92884 --- /dev/null +++ b/libc/nt/ntdll/TpReleaseTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpReleaseTimer diff --git a/libc/nt/ntdll/TpReleaseWait.s b/libc/nt/ntdll/TpReleaseWait.s new file mode 100644 index 00000000..77cd6b3f --- /dev/null +++ b/libc/nt/ntdll/TpReleaseWait.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpReleaseWait diff --git a/libc/nt/ntdll/TpReleaseWork.s b/libc/nt/ntdll/TpReleaseWork.s new file mode 100644 index 00000000..9a05bd3a --- /dev/null +++ b/libc/nt/ntdll/TpReleaseWork.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpReleaseWork diff --git a/libc/nt/ntdll/TpSetDefaultPoolMaxThreads.s b/libc/nt/ntdll/TpSetDefaultPoolMaxThreads.s new file mode 100644 index 00000000..957a0309 --- /dev/null +++ b/libc/nt/ntdll/TpSetDefaultPoolMaxThreads.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpSetDefaultPoolMaxThreads diff --git a/libc/nt/ntdll/TpSetDefaultPoolStackInformation.s b/libc/nt/ntdll/TpSetDefaultPoolStackInformation.s new file mode 100644 index 00000000..df48c792 --- /dev/null +++ b/libc/nt/ntdll/TpSetDefaultPoolStackInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpSetDefaultPoolStackInformation diff --git a/libc/nt/ntdll/TpSetPoolMaxThreads.s b/libc/nt/ntdll/TpSetPoolMaxThreads.s new file mode 100644 index 00000000..1ce0116d --- /dev/null +++ b/libc/nt/ntdll/TpSetPoolMaxThreads.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpSetPoolMaxThreads diff --git a/libc/nt/ntdll/TpSetPoolMaxThreadsSoftLimit.s b/libc/nt/ntdll/TpSetPoolMaxThreadsSoftLimit.s new file mode 100644 index 00000000..8b8386fc --- /dev/null +++ b/libc/nt/ntdll/TpSetPoolMaxThreadsSoftLimit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpSetPoolMaxThreadsSoftLimit diff --git a/libc/nt/ntdll/TpSetPoolMinThreads.s b/libc/nt/ntdll/TpSetPoolMinThreads.s new file mode 100644 index 00000000..ea98e822 --- /dev/null +++ b/libc/nt/ntdll/TpSetPoolMinThreads.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpSetPoolMinThreads diff --git a/libc/nt/ntdll/TpSetPoolStackInformation.s b/libc/nt/ntdll/TpSetPoolStackInformation.s new file mode 100644 index 00000000..d42318a5 --- /dev/null +++ b/libc/nt/ntdll/TpSetPoolStackInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpSetPoolStackInformation diff --git a/libc/nt/ntdll/TpSetPoolThreadBasePriority.s b/libc/nt/ntdll/TpSetPoolThreadBasePriority.s new file mode 100644 index 00000000..032dd251 --- /dev/null +++ b/libc/nt/ntdll/TpSetPoolThreadBasePriority.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpSetPoolThreadBasePriority diff --git a/libc/nt/ntdll/TpSetPoolWorkerThreadIdleTimeout.s b/libc/nt/ntdll/TpSetPoolWorkerThreadIdleTimeout.s new file mode 100644 index 00000000..711ce2f5 --- /dev/null +++ b/libc/nt/ntdll/TpSetPoolWorkerThreadIdleTimeout.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpSetPoolWorkerThreadIdleTimeout diff --git a/libc/nt/ntdll/TpSetTimer.s b/libc/nt/ntdll/TpSetTimer.s new file mode 100644 index 00000000..dfd35e63 --- /dev/null +++ b/libc/nt/ntdll/TpSetTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpSetTimer diff --git a/libc/nt/ntdll/TpSetTimerEx.s b/libc/nt/ntdll/TpSetTimerEx.s new file mode 100644 index 00000000..212a44fc --- /dev/null +++ b/libc/nt/ntdll/TpSetTimerEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpSetTimerEx diff --git a/libc/nt/ntdll/TpSetWait.s b/libc/nt/ntdll/TpSetWait.s new file mode 100644 index 00000000..48373de8 --- /dev/null +++ b/libc/nt/ntdll/TpSetWait.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpSetWait diff --git a/libc/nt/ntdll/TpSetWaitEx.s b/libc/nt/ntdll/TpSetWaitEx.s new file mode 100644 index 00000000..6935e53d --- /dev/null +++ b/libc/nt/ntdll/TpSetWaitEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpSetWaitEx diff --git a/libc/nt/ntdll/TpSimpleTryPost.s b/libc/nt/ntdll/TpSimpleTryPost.s new file mode 100644 index 00000000..a2297feb --- /dev/null +++ b/libc/nt/ntdll/TpSimpleTryPost.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpSimpleTryPost diff --git a/libc/nt/ntdll/TpStartAsyncIoOperation.s b/libc/nt/ntdll/TpStartAsyncIoOperation.s new file mode 100644 index 00000000..ecedd76d --- /dev/null +++ b/libc/nt/ntdll/TpStartAsyncIoOperation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpStartAsyncIoOperation diff --git a/libc/nt/ntdll/TpTimerOutstandingCallbackCount.s b/libc/nt/ntdll/TpTimerOutstandingCallbackCount.s new file mode 100644 index 00000000..5ac546cb --- /dev/null +++ b/libc/nt/ntdll/TpTimerOutstandingCallbackCount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpTimerOutstandingCallbackCount diff --git a/libc/nt/ntdll/TpTrimPools.s b/libc/nt/ntdll/TpTrimPools.s new file mode 100644 index 00000000..876fb9d9 --- /dev/null +++ b/libc/nt/ntdll/TpTrimPools.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpTrimPools diff --git a/libc/nt/ntdll/TpWaitForAlpcCompletion.s b/libc/nt/ntdll/TpWaitForAlpcCompletion.s new file mode 100644 index 00000000..7d24fd62 --- /dev/null +++ b/libc/nt/ntdll/TpWaitForAlpcCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpWaitForAlpcCompletion diff --git a/libc/nt/ntdll/TpWaitForIoCompletion.s b/libc/nt/ntdll/TpWaitForIoCompletion.s new file mode 100644 index 00000000..2d9a82f3 --- /dev/null +++ b/libc/nt/ntdll/TpWaitForIoCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpWaitForIoCompletion diff --git a/libc/nt/ntdll/TpWaitForJobNotification.s b/libc/nt/ntdll/TpWaitForJobNotification.s new file mode 100644 index 00000000..d3643526 --- /dev/null +++ b/libc/nt/ntdll/TpWaitForJobNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpWaitForJobNotification diff --git a/libc/nt/ntdll/TpWaitForTimer.s b/libc/nt/ntdll/TpWaitForTimer.s new file mode 100644 index 00000000..10e2515c --- /dev/null +++ b/libc/nt/ntdll/TpWaitForTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpWaitForTimer diff --git a/libc/nt/ntdll/TpWaitForWait.s b/libc/nt/ntdll/TpWaitForWait.s new file mode 100644 index 00000000..b6f46c64 --- /dev/null +++ b/libc/nt/ntdll/TpWaitForWait.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpWaitForWait diff --git a/libc/nt/ntdll/TpWaitForWork.s b/libc/nt/ntdll/TpWaitForWork.s new file mode 100644 index 00000000..7cd7a716 --- /dev/null +++ b/libc/nt/ntdll/TpWaitForWork.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp TpWaitForWork diff --git a/libc/nt/ntdll/VerSetConditionMask.s b/libc/nt/ntdll/VerSetConditionMask.s new file mode 100644 index 00000000..b10bc310 --- /dev/null +++ b/libc/nt/ntdll/VerSetConditionMask.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp VerSetConditionMask diff --git a/libc/nt/ntdll/WerReportExceptionWorker.s b/libc/nt/ntdll/WerReportExceptionWorker.s new file mode 100644 index 00000000..674af927 --- /dev/null +++ b/libc/nt/ntdll/WerReportExceptionWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WerReportExceptionWorker diff --git a/libc/nt/ntdll/WerReportSQMEvent.s b/libc/nt/ntdll/WerReportSQMEvent.s new file mode 100644 index 00000000..d94034f4 --- /dev/null +++ b/libc/nt/ntdll/WerReportSQMEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WerReportSQMEvent diff --git a/libc/nt/ntdll/WinSqmAddToAverageDWORD.s b/libc/nt/ntdll/WinSqmAddToAverageDWORD.s new file mode 100644 index 00000000..fd166624 --- /dev/null +++ b/libc/nt/ntdll/WinSqmAddToAverageDWORD.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmAddToAverageDWORD diff --git a/libc/nt/ntdll/WinSqmAddToStream.s b/libc/nt/ntdll/WinSqmAddToStream.s new file mode 100644 index 00000000..e175c574 --- /dev/null +++ b/libc/nt/ntdll/WinSqmAddToStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmAddToStream diff --git a/libc/nt/ntdll/WinSqmAddToStreamEx.s b/libc/nt/ntdll/WinSqmAddToStreamEx.s new file mode 100644 index 00000000..ec42e948 --- /dev/null +++ b/libc/nt/ntdll/WinSqmAddToStreamEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmAddToStreamEx diff --git a/libc/nt/ntdll/WinSqmCheckEscalationAddToStreamEx.s b/libc/nt/ntdll/WinSqmCheckEscalationAddToStreamEx.s new file mode 100644 index 00000000..20bd9fe2 --- /dev/null +++ b/libc/nt/ntdll/WinSqmCheckEscalationAddToStreamEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmCheckEscalationAddToStreamEx diff --git a/libc/nt/ntdll/WinSqmCheckEscalationSetDWORD.s b/libc/nt/ntdll/WinSqmCheckEscalationSetDWORD.s new file mode 100644 index 00000000..fc066959 --- /dev/null +++ b/libc/nt/ntdll/WinSqmCheckEscalationSetDWORD.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmCheckEscalationSetDWORD diff --git a/libc/nt/ntdll/WinSqmCheckEscalationSetDWORD64.s b/libc/nt/ntdll/WinSqmCheckEscalationSetDWORD64.s new file mode 100644 index 00000000..73656fab --- /dev/null +++ b/libc/nt/ntdll/WinSqmCheckEscalationSetDWORD64.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmCheckEscalationSetDWORD64 diff --git a/libc/nt/ntdll/WinSqmCheckEscalationSetString.s b/libc/nt/ntdll/WinSqmCheckEscalationSetString.s new file mode 100644 index 00000000..ef62b1f0 --- /dev/null +++ b/libc/nt/ntdll/WinSqmCheckEscalationSetString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmCheckEscalationSetString diff --git a/libc/nt/ntdll/WinSqmCommonDatapointDelete.s b/libc/nt/ntdll/WinSqmCommonDatapointDelete.s new file mode 100644 index 00000000..5e7d3a4f --- /dev/null +++ b/libc/nt/ntdll/WinSqmCommonDatapointDelete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmCommonDatapointDelete diff --git a/libc/nt/ntdll/WinSqmCommonDatapointSetDWORD.s b/libc/nt/ntdll/WinSqmCommonDatapointSetDWORD.s new file mode 100644 index 00000000..3a14e8b5 --- /dev/null +++ b/libc/nt/ntdll/WinSqmCommonDatapointSetDWORD.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmCommonDatapointSetDWORD diff --git a/libc/nt/ntdll/WinSqmCommonDatapointSetDWORD64.s b/libc/nt/ntdll/WinSqmCommonDatapointSetDWORD64.s new file mode 100644 index 00000000..4ab624d8 --- /dev/null +++ b/libc/nt/ntdll/WinSqmCommonDatapointSetDWORD64.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmCommonDatapointSetDWORD64 diff --git a/libc/nt/ntdll/WinSqmCommonDatapointSetStreamEx.s b/libc/nt/ntdll/WinSqmCommonDatapointSetStreamEx.s new file mode 100644 index 00000000..654896cb --- /dev/null +++ b/libc/nt/ntdll/WinSqmCommonDatapointSetStreamEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmCommonDatapointSetStreamEx diff --git a/libc/nt/ntdll/WinSqmCommonDatapointSetString.s b/libc/nt/ntdll/WinSqmCommonDatapointSetString.s new file mode 100644 index 00000000..aac04224 --- /dev/null +++ b/libc/nt/ntdll/WinSqmCommonDatapointSetString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmCommonDatapointSetString diff --git a/libc/nt/ntdll/WinSqmEndSession.s b/libc/nt/ntdll/WinSqmEndSession.s new file mode 100644 index 00000000..9d2dbb8c --- /dev/null +++ b/libc/nt/ntdll/WinSqmEndSession.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmEndSession diff --git a/libc/nt/ntdll/WinSqmEventEnabled.s b/libc/nt/ntdll/WinSqmEventEnabled.s new file mode 100644 index 00000000..c0cc2903 --- /dev/null +++ b/libc/nt/ntdll/WinSqmEventEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmEventEnabled diff --git a/libc/nt/ntdll/WinSqmEventWrite.s b/libc/nt/ntdll/WinSqmEventWrite.s new file mode 100644 index 00000000..db7de801 --- /dev/null +++ b/libc/nt/ntdll/WinSqmEventWrite.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmEventWrite diff --git a/libc/nt/ntdll/WinSqmGetEscalationRuleStatus.s b/libc/nt/ntdll/WinSqmGetEscalationRuleStatus.s new file mode 100644 index 00000000..8b11596b --- /dev/null +++ b/libc/nt/ntdll/WinSqmGetEscalationRuleStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmGetEscalationRuleStatus diff --git a/libc/nt/ntdll/WinSqmGetInstrumentationProperty.s b/libc/nt/ntdll/WinSqmGetInstrumentationProperty.s new file mode 100644 index 00000000..58c42dbf --- /dev/null +++ b/libc/nt/ntdll/WinSqmGetInstrumentationProperty.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmGetInstrumentationProperty diff --git a/libc/nt/ntdll/WinSqmIncrementDWORD.s b/libc/nt/ntdll/WinSqmIncrementDWORD.s new file mode 100644 index 00000000..c9829819 --- /dev/null +++ b/libc/nt/ntdll/WinSqmIncrementDWORD.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmIncrementDWORD diff --git a/libc/nt/ntdll/WinSqmIsOptedIn.s b/libc/nt/ntdll/WinSqmIsOptedIn.s new file mode 100644 index 00000000..14735011 --- /dev/null +++ b/libc/nt/ntdll/WinSqmIsOptedIn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmIsOptedIn diff --git a/libc/nt/ntdll/WinSqmIsOptedInEx.s b/libc/nt/ntdll/WinSqmIsOptedInEx.s new file mode 100644 index 00000000..07eab38f --- /dev/null +++ b/libc/nt/ntdll/WinSqmIsOptedInEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmIsOptedInEx diff --git a/libc/nt/ntdll/WinSqmIsSessionDisabled.s b/libc/nt/ntdll/WinSqmIsSessionDisabled.s new file mode 100644 index 00000000..2854f586 --- /dev/null +++ b/libc/nt/ntdll/WinSqmIsSessionDisabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmIsSessionDisabled diff --git a/libc/nt/ntdll/WinSqmSetDWORD.s b/libc/nt/ntdll/WinSqmSetDWORD.s new file mode 100644 index 00000000..234d8648 --- /dev/null +++ b/libc/nt/ntdll/WinSqmSetDWORD.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmSetDWORD diff --git a/libc/nt/ntdll/WinSqmSetDWORD64.s b/libc/nt/ntdll/WinSqmSetDWORD64.s new file mode 100644 index 00000000..9e798db0 --- /dev/null +++ b/libc/nt/ntdll/WinSqmSetDWORD64.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmSetDWORD64 diff --git a/libc/nt/ntdll/WinSqmSetEscalationInfo.s b/libc/nt/ntdll/WinSqmSetEscalationInfo.s new file mode 100644 index 00000000..dddaace3 --- /dev/null +++ b/libc/nt/ntdll/WinSqmSetEscalationInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmSetEscalationInfo diff --git a/libc/nt/ntdll/WinSqmSetIfMaxDWORD.s b/libc/nt/ntdll/WinSqmSetIfMaxDWORD.s new file mode 100644 index 00000000..e4c57c8e --- /dev/null +++ b/libc/nt/ntdll/WinSqmSetIfMaxDWORD.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmSetIfMaxDWORD diff --git a/libc/nt/ntdll/WinSqmSetIfMinDWORD.s b/libc/nt/ntdll/WinSqmSetIfMinDWORD.s new file mode 100644 index 00000000..e11cb0c1 --- /dev/null +++ b/libc/nt/ntdll/WinSqmSetIfMinDWORD.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmSetIfMinDWORD diff --git a/libc/nt/ntdll/WinSqmSetString.s b/libc/nt/ntdll/WinSqmSetString.s new file mode 100644 index 00000000..c0111049 --- /dev/null +++ b/libc/nt/ntdll/WinSqmSetString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmSetString diff --git a/libc/nt/ntdll/WinSqmStartSession.s b/libc/nt/ntdll/WinSqmStartSession.s new file mode 100644 index 00000000..85574df7 --- /dev/null +++ b/libc/nt/ntdll/WinSqmStartSession.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmStartSession diff --git a/libc/nt/ntdll/WinSqmStartSessionForPartner.s b/libc/nt/ntdll/WinSqmStartSessionForPartner.s new file mode 100644 index 00000000..3b702940 --- /dev/null +++ b/libc/nt/ntdll/WinSqmStartSessionForPartner.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmStartSessionForPartner diff --git a/libc/nt/ntdll/WinSqmStartSqmOptinListener.s b/libc/nt/ntdll/WinSqmStartSqmOptinListener.s new file mode 100644 index 00000000..4201027c --- /dev/null +++ b/libc/nt/ntdll/WinSqmStartSqmOptinListener.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp WinSqmStartSqmOptinListener diff --git a/libc/nt/ntdll/ZwAcceptConnectPort.s b/libc/nt/ntdll/ZwAcceptConnectPort.s new file mode 100644 index 00000000..9043a2aa --- /dev/null +++ b/libc/nt/ntdll/ZwAcceptConnectPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAcceptConnectPort diff --git a/libc/nt/ntdll/ZwAccessCheck.s b/libc/nt/ntdll/ZwAccessCheck.s new file mode 100644 index 00000000..a7c18e3f --- /dev/null +++ b/libc/nt/ntdll/ZwAccessCheck.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAccessCheck diff --git a/libc/nt/ntdll/ZwAccessCheckAndAuditAlarm.s b/libc/nt/ntdll/ZwAccessCheckAndAuditAlarm.s new file mode 100644 index 00000000..1bae7561 --- /dev/null +++ b/libc/nt/ntdll/ZwAccessCheckAndAuditAlarm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAccessCheckAndAuditAlarm diff --git a/libc/nt/ntdll/ZwAccessCheckByType.s b/libc/nt/ntdll/ZwAccessCheckByType.s new file mode 100644 index 00000000..50f5b0db --- /dev/null +++ b/libc/nt/ntdll/ZwAccessCheckByType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAccessCheckByType diff --git a/libc/nt/ntdll/ZwAccessCheckByTypeAndAuditAlarm.s b/libc/nt/ntdll/ZwAccessCheckByTypeAndAuditAlarm.s new file mode 100644 index 00000000..51a14197 --- /dev/null +++ b/libc/nt/ntdll/ZwAccessCheckByTypeAndAuditAlarm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAccessCheckByTypeAndAuditAlarm diff --git a/libc/nt/ntdll/ZwAccessCheckByTypeResultList.s b/libc/nt/ntdll/ZwAccessCheckByTypeResultList.s new file mode 100644 index 00000000..9815530b --- /dev/null +++ b/libc/nt/ntdll/ZwAccessCheckByTypeResultList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAccessCheckByTypeResultList diff --git a/libc/nt/ntdll/ZwAccessCheckByTypeResultListAndAuditAlarm.s b/libc/nt/ntdll/ZwAccessCheckByTypeResultListAndAuditAlarm.s new file mode 100644 index 00000000..6a83b7b9 --- /dev/null +++ b/libc/nt/ntdll/ZwAccessCheckByTypeResultListAndAuditAlarm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAccessCheckByTypeResultListAndAuditAlarm diff --git a/libc/nt/ntdll/ZwAccessCheckByTypeResultListAndAuditAlarmByHandle.s b/libc/nt/ntdll/ZwAccessCheckByTypeResultListAndAuditAlarmByHandle.s new file mode 100644 index 00000000..0fc845b9 --- /dev/null +++ b/libc/nt/ntdll/ZwAccessCheckByTypeResultListAndAuditAlarmByHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAccessCheckByTypeResultListAndAuditAlarmByHandle diff --git a/libc/nt/ntdll/ZwAcquireProcessActivityReference.s b/libc/nt/ntdll/ZwAcquireProcessActivityReference.s new file mode 100644 index 00000000..2f5e2fb8 --- /dev/null +++ b/libc/nt/ntdll/ZwAcquireProcessActivityReference.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAcquireProcessActivityReference diff --git a/libc/nt/ntdll/ZwAddAtom.s b/libc/nt/ntdll/ZwAddAtom.s new file mode 100644 index 00000000..5f5f336a --- /dev/null +++ b/libc/nt/ntdll/ZwAddAtom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAddAtom diff --git a/libc/nt/ntdll/ZwAddAtomEx.s b/libc/nt/ntdll/ZwAddAtomEx.s new file mode 100644 index 00000000..fb98de2a --- /dev/null +++ b/libc/nt/ntdll/ZwAddAtomEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAddAtomEx diff --git a/libc/nt/ntdll/ZwAddBootEntry.s b/libc/nt/ntdll/ZwAddBootEntry.s new file mode 100644 index 00000000..405fbfb5 --- /dev/null +++ b/libc/nt/ntdll/ZwAddBootEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAddBootEntry diff --git a/libc/nt/ntdll/ZwAddDriverEntry.s b/libc/nt/ntdll/ZwAddDriverEntry.s new file mode 100644 index 00000000..7eaec000 --- /dev/null +++ b/libc/nt/ntdll/ZwAddDriverEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAddDriverEntry diff --git a/libc/nt/ntdll/ZwAdjustGroupsToken.s b/libc/nt/ntdll/ZwAdjustGroupsToken.s new file mode 100644 index 00000000..46f593ca --- /dev/null +++ b/libc/nt/ntdll/ZwAdjustGroupsToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAdjustGroupsToken diff --git a/libc/nt/ntdll/ZwAdjustPrivilegesToken.s b/libc/nt/ntdll/ZwAdjustPrivilegesToken.s new file mode 100644 index 00000000..bb2e139b --- /dev/null +++ b/libc/nt/ntdll/ZwAdjustPrivilegesToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAdjustPrivilegesToken diff --git a/libc/nt/ntdll/ZwAdjustTokenClaimsAndDeviceGroups.s b/libc/nt/ntdll/ZwAdjustTokenClaimsAndDeviceGroups.s new file mode 100644 index 00000000..3e51a559 --- /dev/null +++ b/libc/nt/ntdll/ZwAdjustTokenClaimsAndDeviceGroups.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAdjustTokenClaimsAndDeviceGroups diff --git a/libc/nt/ntdll/ZwAlertResumeThread.s b/libc/nt/ntdll/ZwAlertResumeThread.s new file mode 100644 index 00000000..e3cd5d57 --- /dev/null +++ b/libc/nt/ntdll/ZwAlertResumeThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlertResumeThread diff --git a/libc/nt/ntdll/ZwAlertThread.s b/libc/nt/ntdll/ZwAlertThread.s new file mode 100644 index 00000000..dac1b951 --- /dev/null +++ b/libc/nt/ntdll/ZwAlertThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlertThread diff --git a/libc/nt/ntdll/ZwAlertThreadByThreadId.s b/libc/nt/ntdll/ZwAlertThreadByThreadId.s new file mode 100644 index 00000000..45cfb12c --- /dev/null +++ b/libc/nt/ntdll/ZwAlertThreadByThreadId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlertThreadByThreadId diff --git a/libc/nt/ntdll/ZwAllocateLocallyUniqueId.s b/libc/nt/ntdll/ZwAllocateLocallyUniqueId.s new file mode 100644 index 00000000..9699841a --- /dev/null +++ b/libc/nt/ntdll/ZwAllocateLocallyUniqueId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAllocateLocallyUniqueId diff --git a/libc/nt/ntdll/ZwAllocateReserveObject.s b/libc/nt/ntdll/ZwAllocateReserveObject.s new file mode 100644 index 00000000..d68f9513 --- /dev/null +++ b/libc/nt/ntdll/ZwAllocateReserveObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAllocateReserveObject diff --git a/libc/nt/ntdll/ZwAllocateUserPhysicalPages.s b/libc/nt/ntdll/ZwAllocateUserPhysicalPages.s new file mode 100644 index 00000000..b60d0694 --- /dev/null +++ b/libc/nt/ntdll/ZwAllocateUserPhysicalPages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAllocateUserPhysicalPages diff --git a/libc/nt/ntdll/ZwAllocateUuids.s b/libc/nt/ntdll/ZwAllocateUuids.s new file mode 100644 index 00000000..8b08f3c4 --- /dev/null +++ b/libc/nt/ntdll/ZwAllocateUuids.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAllocateUuids diff --git a/libc/nt/ntdll/ZwAllocateVirtualMemory.s b/libc/nt/ntdll/ZwAllocateVirtualMemory.s new file mode 100644 index 00000000..d18baeb1 --- /dev/null +++ b/libc/nt/ntdll/ZwAllocateVirtualMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAllocateVirtualMemory diff --git a/libc/nt/ntdll/ZwAllocateVirtualMemoryEx.s b/libc/nt/ntdll/ZwAllocateVirtualMemoryEx.s new file mode 100644 index 00000000..f4b3f604 --- /dev/null +++ b/libc/nt/ntdll/ZwAllocateVirtualMemoryEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAllocateVirtualMemoryEx diff --git a/libc/nt/ntdll/ZwAlpcAcceptConnectPort.s b/libc/nt/ntdll/ZwAlpcAcceptConnectPort.s new file mode 100644 index 00000000..fefdc17a --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcAcceptConnectPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcAcceptConnectPort diff --git a/libc/nt/ntdll/ZwAlpcCancelMessage.s b/libc/nt/ntdll/ZwAlpcCancelMessage.s new file mode 100644 index 00000000..0310a078 --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcCancelMessage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcCancelMessage diff --git a/libc/nt/ntdll/ZwAlpcConnectPort.s b/libc/nt/ntdll/ZwAlpcConnectPort.s new file mode 100644 index 00000000..4ff9e980 --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcConnectPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcConnectPort diff --git a/libc/nt/ntdll/ZwAlpcConnectPortEx.s b/libc/nt/ntdll/ZwAlpcConnectPortEx.s new file mode 100644 index 00000000..0dad49df --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcConnectPortEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcConnectPortEx diff --git a/libc/nt/ntdll/ZwAlpcCreatePort.s b/libc/nt/ntdll/ZwAlpcCreatePort.s new file mode 100644 index 00000000..0e33d48a --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcCreatePort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcCreatePort diff --git a/libc/nt/ntdll/ZwAlpcCreatePortSection.s b/libc/nt/ntdll/ZwAlpcCreatePortSection.s new file mode 100644 index 00000000..195e7e73 --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcCreatePortSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcCreatePortSection diff --git a/libc/nt/ntdll/ZwAlpcCreateResourceReserve.s b/libc/nt/ntdll/ZwAlpcCreateResourceReserve.s new file mode 100644 index 00000000..be747c99 --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcCreateResourceReserve.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcCreateResourceReserve diff --git a/libc/nt/ntdll/ZwAlpcCreateSectionView.s b/libc/nt/ntdll/ZwAlpcCreateSectionView.s new file mode 100644 index 00000000..3a91e363 --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcCreateSectionView.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcCreateSectionView diff --git a/libc/nt/ntdll/ZwAlpcCreateSecurityContext.s b/libc/nt/ntdll/ZwAlpcCreateSecurityContext.s new file mode 100644 index 00000000..dfca5c2e --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcCreateSecurityContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcCreateSecurityContext diff --git a/libc/nt/ntdll/ZwAlpcDeletePortSection.s b/libc/nt/ntdll/ZwAlpcDeletePortSection.s new file mode 100644 index 00000000..69df413e --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcDeletePortSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcDeletePortSection diff --git a/libc/nt/ntdll/ZwAlpcDeleteResourceReserve.s b/libc/nt/ntdll/ZwAlpcDeleteResourceReserve.s new file mode 100644 index 00000000..8e8df079 --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcDeleteResourceReserve.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcDeleteResourceReserve diff --git a/libc/nt/ntdll/ZwAlpcDeleteSectionView.s b/libc/nt/ntdll/ZwAlpcDeleteSectionView.s new file mode 100644 index 00000000..d4b2d9a9 --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcDeleteSectionView.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcDeleteSectionView diff --git a/libc/nt/ntdll/ZwAlpcDeleteSecurityContext.s b/libc/nt/ntdll/ZwAlpcDeleteSecurityContext.s new file mode 100644 index 00000000..473918c8 --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcDeleteSecurityContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcDeleteSecurityContext diff --git a/libc/nt/ntdll/ZwAlpcDisconnectPort.s b/libc/nt/ntdll/ZwAlpcDisconnectPort.s new file mode 100644 index 00000000..881abb4b --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcDisconnectPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcDisconnectPort diff --git a/libc/nt/ntdll/ZwAlpcImpersonateClientContainerOfPort.s b/libc/nt/ntdll/ZwAlpcImpersonateClientContainerOfPort.s new file mode 100644 index 00000000..d62dcc23 --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcImpersonateClientContainerOfPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcImpersonateClientContainerOfPort diff --git a/libc/nt/ntdll/ZwAlpcImpersonateClientOfPort.s b/libc/nt/ntdll/ZwAlpcImpersonateClientOfPort.s new file mode 100644 index 00000000..0ee0e5b8 --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcImpersonateClientOfPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcImpersonateClientOfPort diff --git a/libc/nt/ntdll/ZwAlpcOpenSenderProcess.s b/libc/nt/ntdll/ZwAlpcOpenSenderProcess.s new file mode 100644 index 00000000..75fac71f --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcOpenSenderProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcOpenSenderProcess diff --git a/libc/nt/ntdll/ZwAlpcOpenSenderThread.s b/libc/nt/ntdll/ZwAlpcOpenSenderThread.s new file mode 100644 index 00000000..40ba3c41 --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcOpenSenderThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcOpenSenderThread diff --git a/libc/nt/ntdll/ZwAlpcQueryInformation.s b/libc/nt/ntdll/ZwAlpcQueryInformation.s new file mode 100644 index 00000000..245205a9 --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcQueryInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcQueryInformation diff --git a/libc/nt/ntdll/ZwAlpcQueryInformationMessage.s b/libc/nt/ntdll/ZwAlpcQueryInformationMessage.s new file mode 100644 index 00000000..c5c1451f --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcQueryInformationMessage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcQueryInformationMessage diff --git a/libc/nt/ntdll/ZwAlpcRevokeSecurityContext.s b/libc/nt/ntdll/ZwAlpcRevokeSecurityContext.s new file mode 100644 index 00000000..48bcf709 --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcRevokeSecurityContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcRevokeSecurityContext diff --git a/libc/nt/ntdll/ZwAlpcSendWaitReceivePort.s b/libc/nt/ntdll/ZwAlpcSendWaitReceivePort.s new file mode 100644 index 00000000..7f13c3d6 --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcSendWaitReceivePort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcSendWaitReceivePort diff --git a/libc/nt/ntdll/ZwAlpcSetInformation.s b/libc/nt/ntdll/ZwAlpcSetInformation.s new file mode 100644 index 00000000..5d62c58a --- /dev/null +++ b/libc/nt/ntdll/ZwAlpcSetInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAlpcSetInformation diff --git a/libc/nt/ntdll/ZwApphelpCacheControl.s b/libc/nt/ntdll/ZwApphelpCacheControl.s new file mode 100644 index 00000000..c5acd182 --- /dev/null +++ b/libc/nt/ntdll/ZwApphelpCacheControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwApphelpCacheControl diff --git a/libc/nt/ntdll/ZwAreMappedFilesTheSame.s b/libc/nt/ntdll/ZwAreMappedFilesTheSame.s new file mode 100644 index 00000000..df27792c --- /dev/null +++ b/libc/nt/ntdll/ZwAreMappedFilesTheSame.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAreMappedFilesTheSame + + .text.windows +ZwAreMappedFilesTheSame: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ZwAreMappedFilesTheSame(%rip),%rax + jmp __sysv2nt + .endfn ZwAreMappedFilesTheSame,globl + .previous diff --git a/libc/nt/ntdll/ZwAssignProcessToJobObject.s b/libc/nt/ntdll/ZwAssignProcessToJobObject.s new file mode 100644 index 00000000..7a17cef1 --- /dev/null +++ b/libc/nt/ntdll/ZwAssignProcessToJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAssignProcessToJobObject diff --git a/libc/nt/ntdll/ZwAssociateWaitCompletionPacket.s b/libc/nt/ntdll/ZwAssociateWaitCompletionPacket.s new file mode 100644 index 00000000..d4b33582 --- /dev/null +++ b/libc/nt/ntdll/ZwAssociateWaitCompletionPacket.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwAssociateWaitCompletionPacket diff --git a/libc/nt/ntdll/ZwCallEnclave.s b/libc/nt/ntdll/ZwCallEnclave.s new file mode 100644 index 00000000..20746202 --- /dev/null +++ b/libc/nt/ntdll/ZwCallEnclave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCallEnclave diff --git a/libc/nt/ntdll/ZwCallbackReturn.s b/libc/nt/ntdll/ZwCallbackReturn.s new file mode 100644 index 00000000..bcf80bf9 --- /dev/null +++ b/libc/nt/ntdll/ZwCallbackReturn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCallbackReturn diff --git a/libc/nt/ntdll/ZwCancelIoFile.s b/libc/nt/ntdll/ZwCancelIoFile.s new file mode 100644 index 00000000..316d8e87 --- /dev/null +++ b/libc/nt/ntdll/ZwCancelIoFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCancelIoFile diff --git a/libc/nt/ntdll/ZwCancelIoFileEx.s b/libc/nt/ntdll/ZwCancelIoFileEx.s new file mode 100644 index 00000000..054be00f --- /dev/null +++ b/libc/nt/ntdll/ZwCancelIoFileEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCancelIoFileEx diff --git a/libc/nt/ntdll/ZwCancelSynchronousIoFile.s b/libc/nt/ntdll/ZwCancelSynchronousIoFile.s new file mode 100644 index 00000000..f482a8b8 --- /dev/null +++ b/libc/nt/ntdll/ZwCancelSynchronousIoFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCancelSynchronousIoFile diff --git a/libc/nt/ntdll/ZwCancelTimer.s b/libc/nt/ntdll/ZwCancelTimer.s new file mode 100644 index 00000000..ed388236 --- /dev/null +++ b/libc/nt/ntdll/ZwCancelTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCancelTimer diff --git a/libc/nt/ntdll/ZwCancelTimer2.s b/libc/nt/ntdll/ZwCancelTimer2.s new file mode 100644 index 00000000..3ee85d93 --- /dev/null +++ b/libc/nt/ntdll/ZwCancelTimer2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCancelTimer2 diff --git a/libc/nt/ntdll/ZwCancelWaitCompletionPacket.s b/libc/nt/ntdll/ZwCancelWaitCompletionPacket.s new file mode 100644 index 00000000..05db89e3 --- /dev/null +++ b/libc/nt/ntdll/ZwCancelWaitCompletionPacket.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCancelWaitCompletionPacket diff --git a/libc/nt/ntdll/ZwClearEvent.s b/libc/nt/ntdll/ZwClearEvent.s new file mode 100644 index 00000000..c7dbac45 --- /dev/null +++ b/libc/nt/ntdll/ZwClearEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwClearEvent diff --git a/libc/nt/ntdll/ZwClose.s b/libc/nt/ntdll/ZwClose.s new file mode 100644 index 00000000..10b23b5a --- /dev/null +++ b/libc/nt/ntdll/ZwClose.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwClose diff --git a/libc/nt/ntdll/ZwCloseObjectAuditAlarm.s b/libc/nt/ntdll/ZwCloseObjectAuditAlarm.s new file mode 100644 index 00000000..078545e6 --- /dev/null +++ b/libc/nt/ntdll/ZwCloseObjectAuditAlarm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCloseObjectAuditAlarm diff --git a/libc/nt/ntdll/ZwCommitComplete.s b/libc/nt/ntdll/ZwCommitComplete.s new file mode 100644 index 00000000..872c7e5c --- /dev/null +++ b/libc/nt/ntdll/ZwCommitComplete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCommitComplete diff --git a/libc/nt/ntdll/ZwCommitEnlistment.s b/libc/nt/ntdll/ZwCommitEnlistment.s new file mode 100644 index 00000000..28ce4e16 --- /dev/null +++ b/libc/nt/ntdll/ZwCommitEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCommitEnlistment diff --git a/libc/nt/ntdll/ZwCommitRegistryTransaction.s b/libc/nt/ntdll/ZwCommitRegistryTransaction.s new file mode 100644 index 00000000..e82e7a6e --- /dev/null +++ b/libc/nt/ntdll/ZwCommitRegistryTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCommitRegistryTransaction diff --git a/libc/nt/ntdll/ZwCommitTransaction.s b/libc/nt/ntdll/ZwCommitTransaction.s new file mode 100644 index 00000000..3b0ab6be --- /dev/null +++ b/libc/nt/ntdll/ZwCommitTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCommitTransaction diff --git a/libc/nt/ntdll/ZwCompactKeys.s b/libc/nt/ntdll/ZwCompactKeys.s new file mode 100644 index 00000000..53ae167b --- /dev/null +++ b/libc/nt/ntdll/ZwCompactKeys.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCompactKeys diff --git a/libc/nt/ntdll/ZwCompareObjects.s b/libc/nt/ntdll/ZwCompareObjects.s new file mode 100644 index 00000000..bd22638a --- /dev/null +++ b/libc/nt/ntdll/ZwCompareObjects.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCompareObjects diff --git a/libc/nt/ntdll/ZwCompareSigningLevels.s b/libc/nt/ntdll/ZwCompareSigningLevels.s new file mode 100644 index 00000000..21b8bebb --- /dev/null +++ b/libc/nt/ntdll/ZwCompareSigningLevels.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCompareSigningLevels diff --git a/libc/nt/ntdll/ZwCompareTokens.s b/libc/nt/ntdll/ZwCompareTokens.s new file mode 100644 index 00000000..a4130fdf --- /dev/null +++ b/libc/nt/ntdll/ZwCompareTokens.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCompareTokens diff --git a/libc/nt/ntdll/ZwCompleteConnectPort.s b/libc/nt/ntdll/ZwCompleteConnectPort.s new file mode 100644 index 00000000..e9fa9e5e --- /dev/null +++ b/libc/nt/ntdll/ZwCompleteConnectPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCompleteConnectPort diff --git a/libc/nt/ntdll/ZwCompressKey.s b/libc/nt/ntdll/ZwCompressKey.s new file mode 100644 index 00000000..e32c8aa3 --- /dev/null +++ b/libc/nt/ntdll/ZwCompressKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCompressKey diff --git a/libc/nt/ntdll/ZwConnectPort.s b/libc/nt/ntdll/ZwConnectPort.s new file mode 100644 index 00000000..21664f26 --- /dev/null +++ b/libc/nt/ntdll/ZwConnectPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwConnectPort diff --git a/libc/nt/ntdll/ZwContinue.s b/libc/nt/ntdll/ZwContinue.s new file mode 100644 index 00000000..569d9f5c --- /dev/null +++ b/libc/nt/ntdll/ZwContinue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwContinue diff --git a/libc/nt/ntdll/ZwConvertBetweenAuxiliaryCounterAndPerformanceCounter.s b/libc/nt/ntdll/ZwConvertBetweenAuxiliaryCounterAndPerformanceCounter.s new file mode 100644 index 00000000..334a9c30 --- /dev/null +++ b/libc/nt/ntdll/ZwConvertBetweenAuxiliaryCounterAndPerformanceCounter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwConvertBetweenAuxiliaryCounterAndPerformanceCounter diff --git a/libc/nt/ntdll/ZwCreateDebugObject.s b/libc/nt/ntdll/ZwCreateDebugObject.s new file mode 100644 index 00000000..be81f1cc --- /dev/null +++ b/libc/nt/ntdll/ZwCreateDebugObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateDebugObject diff --git a/libc/nt/ntdll/ZwCreateDirectoryObject.s b/libc/nt/ntdll/ZwCreateDirectoryObject.s new file mode 100644 index 00000000..057214b6 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateDirectoryObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateDirectoryObject diff --git a/libc/nt/ntdll/ZwCreateDirectoryObjectEx.s b/libc/nt/ntdll/ZwCreateDirectoryObjectEx.s new file mode 100644 index 00000000..688ced92 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateDirectoryObjectEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateDirectoryObjectEx diff --git a/libc/nt/ntdll/ZwCreateEnclave.s b/libc/nt/ntdll/ZwCreateEnclave.s new file mode 100644 index 00000000..1cebab84 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateEnclave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateEnclave diff --git a/libc/nt/ntdll/ZwCreateEnlistment.s b/libc/nt/ntdll/ZwCreateEnlistment.s new file mode 100644 index 00000000..5a7eda60 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateEnlistment diff --git a/libc/nt/ntdll/ZwCreateEvent.s b/libc/nt/ntdll/ZwCreateEvent.s new file mode 100644 index 00000000..c19c4bfc --- /dev/null +++ b/libc/nt/ntdll/ZwCreateEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateEvent diff --git a/libc/nt/ntdll/ZwCreateEventPair.s b/libc/nt/ntdll/ZwCreateEventPair.s new file mode 100644 index 00000000..714f7f8a --- /dev/null +++ b/libc/nt/ntdll/ZwCreateEventPair.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateEventPair diff --git a/libc/nt/ntdll/ZwCreateFile.s b/libc/nt/ntdll/ZwCreateFile.s new file mode 100644 index 00000000..d549901e --- /dev/null +++ b/libc/nt/ntdll/ZwCreateFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateFile diff --git a/libc/nt/ntdll/ZwCreateIRTimer.s b/libc/nt/ntdll/ZwCreateIRTimer.s new file mode 100644 index 00000000..63c27fe1 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateIRTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateIRTimer diff --git a/libc/nt/ntdll/ZwCreateIoCompletion.s b/libc/nt/ntdll/ZwCreateIoCompletion.s new file mode 100644 index 00000000..783d7eca --- /dev/null +++ b/libc/nt/ntdll/ZwCreateIoCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateIoCompletion diff --git a/libc/nt/ntdll/ZwCreateJobObject.s b/libc/nt/ntdll/ZwCreateJobObject.s new file mode 100644 index 00000000..c2281b85 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateJobObject diff --git a/libc/nt/ntdll/ZwCreateJobSet.s b/libc/nt/ntdll/ZwCreateJobSet.s new file mode 100644 index 00000000..8018ae0b --- /dev/null +++ b/libc/nt/ntdll/ZwCreateJobSet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateJobSet diff --git a/libc/nt/ntdll/ZwCreateKey.s b/libc/nt/ntdll/ZwCreateKey.s new file mode 100644 index 00000000..e9176016 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateKey diff --git a/libc/nt/ntdll/ZwCreateKeyTransacted.s b/libc/nt/ntdll/ZwCreateKeyTransacted.s new file mode 100644 index 00000000..3284a469 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateKeyTransacted.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateKeyTransacted diff --git a/libc/nt/ntdll/ZwCreateKeyedEvent.s b/libc/nt/ntdll/ZwCreateKeyedEvent.s new file mode 100644 index 00000000..7fd3337e --- /dev/null +++ b/libc/nt/ntdll/ZwCreateKeyedEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateKeyedEvent diff --git a/libc/nt/ntdll/ZwCreateLowBoxToken.s b/libc/nt/ntdll/ZwCreateLowBoxToken.s new file mode 100644 index 00000000..78839754 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateLowBoxToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateLowBoxToken diff --git a/libc/nt/ntdll/ZwCreateMailslotFile.s b/libc/nt/ntdll/ZwCreateMailslotFile.s new file mode 100644 index 00000000..86f95169 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateMailslotFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateMailslotFile diff --git a/libc/nt/ntdll/ZwCreateMutant.s b/libc/nt/ntdll/ZwCreateMutant.s new file mode 100644 index 00000000..b46c6d7d --- /dev/null +++ b/libc/nt/ntdll/ZwCreateMutant.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateMutant diff --git a/libc/nt/ntdll/ZwCreateNamedPipeFile.s b/libc/nt/ntdll/ZwCreateNamedPipeFile.s new file mode 100644 index 00000000..ce4114b9 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateNamedPipeFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateNamedPipeFile diff --git a/libc/nt/ntdll/ZwCreatePagingFile.s b/libc/nt/ntdll/ZwCreatePagingFile.s new file mode 100644 index 00000000..8115111f --- /dev/null +++ b/libc/nt/ntdll/ZwCreatePagingFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreatePagingFile diff --git a/libc/nt/ntdll/ZwCreatePartition.s b/libc/nt/ntdll/ZwCreatePartition.s new file mode 100644 index 00000000..835dbcc4 --- /dev/null +++ b/libc/nt/ntdll/ZwCreatePartition.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreatePartition diff --git a/libc/nt/ntdll/ZwCreatePort.s b/libc/nt/ntdll/ZwCreatePort.s new file mode 100644 index 00000000..40c62f06 --- /dev/null +++ b/libc/nt/ntdll/ZwCreatePort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreatePort diff --git a/libc/nt/ntdll/ZwCreatePrivateNamespace.s b/libc/nt/ntdll/ZwCreatePrivateNamespace.s new file mode 100644 index 00000000..093204b1 --- /dev/null +++ b/libc/nt/ntdll/ZwCreatePrivateNamespace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreatePrivateNamespace diff --git a/libc/nt/ntdll/ZwCreateProcess.s b/libc/nt/ntdll/ZwCreateProcess.s new file mode 100644 index 00000000..d90829f9 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateProcess diff --git a/libc/nt/ntdll/ZwCreateProcessEx.s b/libc/nt/ntdll/ZwCreateProcessEx.s new file mode 100644 index 00000000..915cb6d1 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateProcessEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateProcessEx diff --git a/libc/nt/ntdll/ZwCreateProfile.s b/libc/nt/ntdll/ZwCreateProfile.s new file mode 100644 index 00000000..16b25655 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateProfile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateProfile diff --git a/libc/nt/ntdll/ZwCreateProfileEx.s b/libc/nt/ntdll/ZwCreateProfileEx.s new file mode 100644 index 00000000..13963833 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateProfileEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateProfileEx diff --git a/libc/nt/ntdll/ZwCreateRegistryTransaction.s b/libc/nt/ntdll/ZwCreateRegistryTransaction.s new file mode 100644 index 00000000..56061bea --- /dev/null +++ b/libc/nt/ntdll/ZwCreateRegistryTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateRegistryTransaction diff --git a/libc/nt/ntdll/ZwCreateResourceManager.s b/libc/nt/ntdll/ZwCreateResourceManager.s new file mode 100644 index 00000000..e688bcb3 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateResourceManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateResourceManager diff --git a/libc/nt/ntdll/ZwCreateSection.s b/libc/nt/ntdll/ZwCreateSection.s new file mode 100644 index 00000000..303828fc --- /dev/null +++ b/libc/nt/ntdll/ZwCreateSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateSection diff --git a/libc/nt/ntdll/ZwCreateSemaphore.s b/libc/nt/ntdll/ZwCreateSemaphore.s new file mode 100644 index 00000000..0f46b3b7 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateSemaphore.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateSemaphore diff --git a/libc/nt/ntdll/ZwCreateSymbolicLinkObject.s b/libc/nt/ntdll/ZwCreateSymbolicLinkObject.s new file mode 100644 index 00000000..fa91747b --- /dev/null +++ b/libc/nt/ntdll/ZwCreateSymbolicLinkObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateSymbolicLinkObject diff --git a/libc/nt/ntdll/ZwCreateThread.s b/libc/nt/ntdll/ZwCreateThread.s new file mode 100644 index 00000000..10efeb7f --- /dev/null +++ b/libc/nt/ntdll/ZwCreateThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateThread diff --git a/libc/nt/ntdll/ZwCreateThreadEx.s b/libc/nt/ntdll/ZwCreateThreadEx.s new file mode 100644 index 00000000..36750edd --- /dev/null +++ b/libc/nt/ntdll/ZwCreateThreadEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateThreadEx diff --git a/libc/nt/ntdll/ZwCreateTimer.s b/libc/nt/ntdll/ZwCreateTimer.s new file mode 100644 index 00000000..5779263b --- /dev/null +++ b/libc/nt/ntdll/ZwCreateTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateTimer diff --git a/libc/nt/ntdll/ZwCreateTimer2.s b/libc/nt/ntdll/ZwCreateTimer2.s new file mode 100644 index 00000000..2c698e7f --- /dev/null +++ b/libc/nt/ntdll/ZwCreateTimer2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateTimer2 diff --git a/libc/nt/ntdll/ZwCreateToken.s b/libc/nt/ntdll/ZwCreateToken.s new file mode 100644 index 00000000..f8e497cd --- /dev/null +++ b/libc/nt/ntdll/ZwCreateToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateToken diff --git a/libc/nt/ntdll/ZwCreateTokenEx.s b/libc/nt/ntdll/ZwCreateTokenEx.s new file mode 100644 index 00000000..b779819e --- /dev/null +++ b/libc/nt/ntdll/ZwCreateTokenEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateTokenEx diff --git a/libc/nt/ntdll/ZwCreateTransaction.s b/libc/nt/ntdll/ZwCreateTransaction.s new file mode 100644 index 00000000..4df69fac --- /dev/null +++ b/libc/nt/ntdll/ZwCreateTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateTransaction diff --git a/libc/nt/ntdll/ZwCreateTransactionManager.s b/libc/nt/ntdll/ZwCreateTransactionManager.s new file mode 100644 index 00000000..625d8ec6 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateTransactionManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateTransactionManager diff --git a/libc/nt/ntdll/ZwCreateUserProcess.s b/libc/nt/ntdll/ZwCreateUserProcess.s new file mode 100644 index 00000000..a6c70e3b --- /dev/null +++ b/libc/nt/ntdll/ZwCreateUserProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateUserProcess diff --git a/libc/nt/ntdll/ZwCreateWaitCompletionPacket.s b/libc/nt/ntdll/ZwCreateWaitCompletionPacket.s new file mode 100644 index 00000000..db944aa7 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateWaitCompletionPacket.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateWaitCompletionPacket diff --git a/libc/nt/ntdll/ZwCreateWaitablePort.s b/libc/nt/ntdll/ZwCreateWaitablePort.s new file mode 100644 index 00000000..3100df5b --- /dev/null +++ b/libc/nt/ntdll/ZwCreateWaitablePort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateWaitablePort diff --git a/libc/nt/ntdll/ZwCreateWnfStateName.s b/libc/nt/ntdll/ZwCreateWnfStateName.s new file mode 100644 index 00000000..123d57db --- /dev/null +++ b/libc/nt/ntdll/ZwCreateWnfStateName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateWnfStateName diff --git a/libc/nt/ntdll/ZwCreateWorkerFactory.s b/libc/nt/ntdll/ZwCreateWorkerFactory.s new file mode 100644 index 00000000..01cd1ee4 --- /dev/null +++ b/libc/nt/ntdll/ZwCreateWorkerFactory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwCreateWorkerFactory diff --git a/libc/nt/ntdll/ZwDebugActiveProcess.s b/libc/nt/ntdll/ZwDebugActiveProcess.s new file mode 100644 index 00000000..6e72a820 --- /dev/null +++ b/libc/nt/ntdll/ZwDebugActiveProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDebugActiveProcess diff --git a/libc/nt/ntdll/ZwDebugContinue.s b/libc/nt/ntdll/ZwDebugContinue.s new file mode 100644 index 00000000..ca399a3d --- /dev/null +++ b/libc/nt/ntdll/ZwDebugContinue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDebugContinue diff --git a/libc/nt/ntdll/ZwDelayExecution.s b/libc/nt/ntdll/ZwDelayExecution.s new file mode 100644 index 00000000..bfe0831f --- /dev/null +++ b/libc/nt/ntdll/ZwDelayExecution.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDelayExecution diff --git a/libc/nt/ntdll/ZwDeleteAtom.s b/libc/nt/ntdll/ZwDeleteAtom.s new file mode 100644 index 00000000..2d8fa3a4 --- /dev/null +++ b/libc/nt/ntdll/ZwDeleteAtom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDeleteAtom diff --git a/libc/nt/ntdll/ZwDeleteBootEntry.s b/libc/nt/ntdll/ZwDeleteBootEntry.s new file mode 100644 index 00000000..14c032a4 --- /dev/null +++ b/libc/nt/ntdll/ZwDeleteBootEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDeleteBootEntry diff --git a/libc/nt/ntdll/ZwDeleteDriverEntry.s b/libc/nt/ntdll/ZwDeleteDriverEntry.s new file mode 100644 index 00000000..12a6dff8 --- /dev/null +++ b/libc/nt/ntdll/ZwDeleteDriverEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDeleteDriverEntry diff --git a/libc/nt/ntdll/ZwDeleteFile.s b/libc/nt/ntdll/ZwDeleteFile.s new file mode 100644 index 00000000..b2498d32 --- /dev/null +++ b/libc/nt/ntdll/ZwDeleteFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDeleteFile diff --git a/libc/nt/ntdll/ZwDeleteKey.s b/libc/nt/ntdll/ZwDeleteKey.s new file mode 100644 index 00000000..de2a36d1 --- /dev/null +++ b/libc/nt/ntdll/ZwDeleteKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDeleteKey diff --git a/libc/nt/ntdll/ZwDeleteObjectAuditAlarm.s b/libc/nt/ntdll/ZwDeleteObjectAuditAlarm.s new file mode 100644 index 00000000..21bf4e5a --- /dev/null +++ b/libc/nt/ntdll/ZwDeleteObjectAuditAlarm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDeleteObjectAuditAlarm diff --git a/libc/nt/ntdll/ZwDeletePrivateNamespace.s b/libc/nt/ntdll/ZwDeletePrivateNamespace.s new file mode 100644 index 00000000..ebc1321b --- /dev/null +++ b/libc/nt/ntdll/ZwDeletePrivateNamespace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDeletePrivateNamespace diff --git a/libc/nt/ntdll/ZwDeleteValueKey.s b/libc/nt/ntdll/ZwDeleteValueKey.s new file mode 100644 index 00000000..05c1d53c --- /dev/null +++ b/libc/nt/ntdll/ZwDeleteValueKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDeleteValueKey diff --git a/libc/nt/ntdll/ZwDeleteWnfStateData.s b/libc/nt/ntdll/ZwDeleteWnfStateData.s new file mode 100644 index 00000000..c53e6dc8 --- /dev/null +++ b/libc/nt/ntdll/ZwDeleteWnfStateData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDeleteWnfStateData diff --git a/libc/nt/ntdll/ZwDeleteWnfStateName.s b/libc/nt/ntdll/ZwDeleteWnfStateName.s new file mode 100644 index 00000000..f1ac14a7 --- /dev/null +++ b/libc/nt/ntdll/ZwDeleteWnfStateName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDeleteWnfStateName diff --git a/libc/nt/ntdll/ZwDeviceIoControlFile.s b/libc/nt/ntdll/ZwDeviceIoControlFile.s new file mode 100644 index 00000000..1a0b2a4f --- /dev/null +++ b/libc/nt/ntdll/ZwDeviceIoControlFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDeviceIoControlFile diff --git a/libc/nt/ntdll/ZwDisableLastKnownGood.s b/libc/nt/ntdll/ZwDisableLastKnownGood.s new file mode 100644 index 00000000..cc58207e --- /dev/null +++ b/libc/nt/ntdll/ZwDisableLastKnownGood.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDisableLastKnownGood diff --git a/libc/nt/ntdll/ZwDisplayString.s b/libc/nt/ntdll/ZwDisplayString.s new file mode 100644 index 00000000..bb8ed191 --- /dev/null +++ b/libc/nt/ntdll/ZwDisplayString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDisplayString diff --git a/libc/nt/ntdll/ZwDrawText.s b/libc/nt/ntdll/ZwDrawText.s new file mode 100644 index 00000000..acb8bef0 --- /dev/null +++ b/libc/nt/ntdll/ZwDrawText.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDrawText diff --git a/libc/nt/ntdll/ZwDuplicateObject.s b/libc/nt/ntdll/ZwDuplicateObject.s new file mode 100644 index 00000000..3b5897da --- /dev/null +++ b/libc/nt/ntdll/ZwDuplicateObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDuplicateObject diff --git a/libc/nt/ntdll/ZwDuplicateToken.s b/libc/nt/ntdll/ZwDuplicateToken.s new file mode 100644 index 00000000..b0292c9a --- /dev/null +++ b/libc/nt/ntdll/ZwDuplicateToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwDuplicateToken diff --git a/libc/nt/ntdll/ZwEnableLastKnownGood.s b/libc/nt/ntdll/ZwEnableLastKnownGood.s new file mode 100644 index 00000000..789d0ba3 --- /dev/null +++ b/libc/nt/ntdll/ZwEnableLastKnownGood.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwEnableLastKnownGood diff --git a/libc/nt/ntdll/ZwEnumerateBootEntries.s b/libc/nt/ntdll/ZwEnumerateBootEntries.s new file mode 100644 index 00000000..2ddaaa70 --- /dev/null +++ b/libc/nt/ntdll/ZwEnumerateBootEntries.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwEnumerateBootEntries diff --git a/libc/nt/ntdll/ZwEnumerateDriverEntries.s b/libc/nt/ntdll/ZwEnumerateDriverEntries.s new file mode 100644 index 00000000..315474af --- /dev/null +++ b/libc/nt/ntdll/ZwEnumerateDriverEntries.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwEnumerateDriverEntries diff --git a/libc/nt/ntdll/ZwEnumerateKey.s b/libc/nt/ntdll/ZwEnumerateKey.s new file mode 100644 index 00000000..9e1e8941 --- /dev/null +++ b/libc/nt/ntdll/ZwEnumerateKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwEnumerateKey diff --git a/libc/nt/ntdll/ZwEnumerateSystemEnvironmentValuesEx.s b/libc/nt/ntdll/ZwEnumerateSystemEnvironmentValuesEx.s new file mode 100644 index 00000000..c7e89838 --- /dev/null +++ b/libc/nt/ntdll/ZwEnumerateSystemEnvironmentValuesEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwEnumerateSystemEnvironmentValuesEx diff --git a/libc/nt/ntdll/ZwEnumerateTransactionObject.s b/libc/nt/ntdll/ZwEnumerateTransactionObject.s new file mode 100644 index 00000000..fdde4164 --- /dev/null +++ b/libc/nt/ntdll/ZwEnumerateTransactionObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwEnumerateTransactionObject diff --git a/libc/nt/ntdll/ZwEnumerateValueKey.s b/libc/nt/ntdll/ZwEnumerateValueKey.s new file mode 100644 index 00000000..77c7115d --- /dev/null +++ b/libc/nt/ntdll/ZwEnumerateValueKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwEnumerateValueKey diff --git a/libc/nt/ntdll/ZwExtendSection.s b/libc/nt/ntdll/ZwExtendSection.s new file mode 100644 index 00000000..15446164 --- /dev/null +++ b/libc/nt/ntdll/ZwExtendSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwExtendSection diff --git a/libc/nt/ntdll/ZwFilterBootOption.s b/libc/nt/ntdll/ZwFilterBootOption.s new file mode 100644 index 00000000..f4c1e076 --- /dev/null +++ b/libc/nt/ntdll/ZwFilterBootOption.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwFilterBootOption diff --git a/libc/nt/ntdll/ZwFilterToken.s b/libc/nt/ntdll/ZwFilterToken.s new file mode 100644 index 00000000..93e6ac42 --- /dev/null +++ b/libc/nt/ntdll/ZwFilterToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwFilterToken diff --git a/libc/nt/ntdll/ZwFilterTokenEx.s b/libc/nt/ntdll/ZwFilterTokenEx.s new file mode 100644 index 00000000..69454e78 --- /dev/null +++ b/libc/nt/ntdll/ZwFilterTokenEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwFilterTokenEx diff --git a/libc/nt/ntdll/ZwFindAtom.s b/libc/nt/ntdll/ZwFindAtom.s new file mode 100644 index 00000000..a5536dde --- /dev/null +++ b/libc/nt/ntdll/ZwFindAtom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwFindAtom diff --git a/libc/nt/ntdll/ZwFlushBuffersFile.s b/libc/nt/ntdll/ZwFlushBuffersFile.s new file mode 100644 index 00000000..292136a6 --- /dev/null +++ b/libc/nt/ntdll/ZwFlushBuffersFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwFlushBuffersFile diff --git a/libc/nt/ntdll/ZwFlushBuffersFileEx.s b/libc/nt/ntdll/ZwFlushBuffersFileEx.s new file mode 100644 index 00000000..fa58fd2a --- /dev/null +++ b/libc/nt/ntdll/ZwFlushBuffersFileEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwFlushBuffersFileEx diff --git a/libc/nt/ntdll/ZwFlushInstallUILanguage.s b/libc/nt/ntdll/ZwFlushInstallUILanguage.s new file mode 100644 index 00000000..04080cf3 --- /dev/null +++ b/libc/nt/ntdll/ZwFlushInstallUILanguage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwFlushInstallUILanguage diff --git a/libc/nt/ntdll/ZwFlushInstructionCache.s b/libc/nt/ntdll/ZwFlushInstructionCache.s new file mode 100644 index 00000000..97997ee7 --- /dev/null +++ b/libc/nt/ntdll/ZwFlushInstructionCache.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwFlushInstructionCache diff --git a/libc/nt/ntdll/ZwFlushKey.s b/libc/nt/ntdll/ZwFlushKey.s new file mode 100644 index 00000000..2fe67b0a --- /dev/null +++ b/libc/nt/ntdll/ZwFlushKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwFlushKey diff --git a/libc/nt/ntdll/ZwFlushProcessWriteBuffers.s b/libc/nt/ntdll/ZwFlushProcessWriteBuffers.s new file mode 100644 index 00000000..0059aff1 --- /dev/null +++ b/libc/nt/ntdll/ZwFlushProcessWriteBuffers.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwFlushProcessWriteBuffers diff --git a/libc/nt/ntdll/ZwFlushVirtualMemory.s b/libc/nt/ntdll/ZwFlushVirtualMemory.s new file mode 100644 index 00000000..938db98a --- /dev/null +++ b/libc/nt/ntdll/ZwFlushVirtualMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwFlushVirtualMemory diff --git a/libc/nt/ntdll/ZwFlushWriteBuffer.s b/libc/nt/ntdll/ZwFlushWriteBuffer.s new file mode 100644 index 00000000..460da5fa --- /dev/null +++ b/libc/nt/ntdll/ZwFlushWriteBuffer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwFlushWriteBuffer diff --git a/libc/nt/ntdll/ZwFreeUserPhysicalPages.s b/libc/nt/ntdll/ZwFreeUserPhysicalPages.s new file mode 100644 index 00000000..d138d89b --- /dev/null +++ b/libc/nt/ntdll/ZwFreeUserPhysicalPages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwFreeUserPhysicalPages diff --git a/libc/nt/ntdll/ZwFreeVirtualMemory.s b/libc/nt/ntdll/ZwFreeVirtualMemory.s new file mode 100644 index 00000000..a12be9f4 --- /dev/null +++ b/libc/nt/ntdll/ZwFreeVirtualMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwFreeVirtualMemory diff --git a/libc/nt/ntdll/ZwFreezeRegistry.s b/libc/nt/ntdll/ZwFreezeRegistry.s new file mode 100644 index 00000000..8acac9d3 --- /dev/null +++ b/libc/nt/ntdll/ZwFreezeRegistry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwFreezeRegistry diff --git a/libc/nt/ntdll/ZwFreezeTransactions.s b/libc/nt/ntdll/ZwFreezeTransactions.s new file mode 100644 index 00000000..c2a8eeed --- /dev/null +++ b/libc/nt/ntdll/ZwFreezeTransactions.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwFreezeTransactions diff --git a/libc/nt/ntdll/ZwFsControlFile.s b/libc/nt/ntdll/ZwFsControlFile.s new file mode 100644 index 00000000..37a33c4f --- /dev/null +++ b/libc/nt/ntdll/ZwFsControlFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwFsControlFile diff --git a/libc/nt/ntdll/ZwGetCachedSigningLevel.s b/libc/nt/ntdll/ZwGetCachedSigningLevel.s new file mode 100644 index 00000000..1487ecb4 --- /dev/null +++ b/libc/nt/ntdll/ZwGetCachedSigningLevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwGetCachedSigningLevel diff --git a/libc/nt/ntdll/ZwGetCompleteWnfStateSubscription.s b/libc/nt/ntdll/ZwGetCompleteWnfStateSubscription.s new file mode 100644 index 00000000..f9b01048 --- /dev/null +++ b/libc/nt/ntdll/ZwGetCompleteWnfStateSubscription.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwGetCompleteWnfStateSubscription diff --git a/libc/nt/ntdll/ZwGetContextThread.s b/libc/nt/ntdll/ZwGetContextThread.s new file mode 100644 index 00000000..0f1b42e1 --- /dev/null +++ b/libc/nt/ntdll/ZwGetContextThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwGetContextThread diff --git a/libc/nt/ntdll/ZwGetCurrentProcessorNumber.s b/libc/nt/ntdll/ZwGetCurrentProcessorNumber.s new file mode 100644 index 00000000..5f27db35 --- /dev/null +++ b/libc/nt/ntdll/ZwGetCurrentProcessorNumber.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwGetCurrentProcessorNumber diff --git a/libc/nt/ntdll/ZwGetCurrentProcessorNumberEx.s b/libc/nt/ntdll/ZwGetCurrentProcessorNumberEx.s new file mode 100644 index 00000000..0eb2ce1c --- /dev/null +++ b/libc/nt/ntdll/ZwGetCurrentProcessorNumberEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwGetCurrentProcessorNumberEx diff --git a/libc/nt/ntdll/ZwGetDevicePowerState.s b/libc/nt/ntdll/ZwGetDevicePowerState.s new file mode 100644 index 00000000..59a735d7 --- /dev/null +++ b/libc/nt/ntdll/ZwGetDevicePowerState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwGetDevicePowerState diff --git a/libc/nt/ntdll/ZwGetMUIRegistryInfo.s b/libc/nt/ntdll/ZwGetMUIRegistryInfo.s new file mode 100644 index 00000000..edd2a904 --- /dev/null +++ b/libc/nt/ntdll/ZwGetMUIRegistryInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwGetMUIRegistryInfo diff --git a/libc/nt/ntdll/ZwGetNextProcess.s b/libc/nt/ntdll/ZwGetNextProcess.s new file mode 100644 index 00000000..2c69db80 --- /dev/null +++ b/libc/nt/ntdll/ZwGetNextProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwGetNextProcess diff --git a/libc/nt/ntdll/ZwGetNextThread.s b/libc/nt/ntdll/ZwGetNextThread.s new file mode 100644 index 00000000..fcbdd91e --- /dev/null +++ b/libc/nt/ntdll/ZwGetNextThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwGetNextThread diff --git a/libc/nt/ntdll/ZwGetNlsSectionPtr.s b/libc/nt/ntdll/ZwGetNlsSectionPtr.s new file mode 100644 index 00000000..0414b3dd --- /dev/null +++ b/libc/nt/ntdll/ZwGetNlsSectionPtr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwGetNlsSectionPtr diff --git a/libc/nt/ntdll/ZwGetNotificationResourceManager.s b/libc/nt/ntdll/ZwGetNotificationResourceManager.s new file mode 100644 index 00000000..22868505 --- /dev/null +++ b/libc/nt/ntdll/ZwGetNotificationResourceManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwGetNotificationResourceManager diff --git a/libc/nt/ntdll/ZwGetWriteWatch.s b/libc/nt/ntdll/ZwGetWriteWatch.s new file mode 100644 index 00000000..b3687689 --- /dev/null +++ b/libc/nt/ntdll/ZwGetWriteWatch.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwGetWriteWatch diff --git a/libc/nt/ntdll/ZwImpersonateAnonymousToken.s b/libc/nt/ntdll/ZwImpersonateAnonymousToken.s new file mode 100644 index 00000000..41c261a0 --- /dev/null +++ b/libc/nt/ntdll/ZwImpersonateAnonymousToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwImpersonateAnonymousToken diff --git a/libc/nt/ntdll/ZwImpersonateClientOfPort.s b/libc/nt/ntdll/ZwImpersonateClientOfPort.s new file mode 100644 index 00000000..7b65097b --- /dev/null +++ b/libc/nt/ntdll/ZwImpersonateClientOfPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwImpersonateClientOfPort diff --git a/libc/nt/ntdll/ZwImpersonateThread.s b/libc/nt/ntdll/ZwImpersonateThread.s new file mode 100644 index 00000000..baa4c8bc --- /dev/null +++ b/libc/nt/ntdll/ZwImpersonateThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwImpersonateThread diff --git a/libc/nt/ntdll/ZwInitializeEnclave.s b/libc/nt/ntdll/ZwInitializeEnclave.s new file mode 100644 index 00000000..5c17e270 --- /dev/null +++ b/libc/nt/ntdll/ZwInitializeEnclave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwInitializeEnclave diff --git a/libc/nt/ntdll/ZwInitializeNlsFiles.s b/libc/nt/ntdll/ZwInitializeNlsFiles.s new file mode 100644 index 00000000..b4b3c9e1 --- /dev/null +++ b/libc/nt/ntdll/ZwInitializeNlsFiles.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwInitializeNlsFiles diff --git a/libc/nt/ntdll/ZwInitializeRegistry.s b/libc/nt/ntdll/ZwInitializeRegistry.s new file mode 100644 index 00000000..631feb98 --- /dev/null +++ b/libc/nt/ntdll/ZwInitializeRegistry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwInitializeRegistry diff --git a/libc/nt/ntdll/ZwInitiatePowerAction.s b/libc/nt/ntdll/ZwInitiatePowerAction.s new file mode 100644 index 00000000..1d9d3cd9 --- /dev/null +++ b/libc/nt/ntdll/ZwInitiatePowerAction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwInitiatePowerAction diff --git a/libc/nt/ntdll/ZwIsProcessInJob.s b/libc/nt/ntdll/ZwIsProcessInJob.s new file mode 100644 index 00000000..5882aa80 --- /dev/null +++ b/libc/nt/ntdll/ZwIsProcessInJob.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwIsProcessInJob diff --git a/libc/nt/ntdll/ZwIsSystemResumeAutomatic.s b/libc/nt/ntdll/ZwIsSystemResumeAutomatic.s new file mode 100644 index 00000000..ae890fdd --- /dev/null +++ b/libc/nt/ntdll/ZwIsSystemResumeAutomatic.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwIsSystemResumeAutomatic diff --git a/libc/nt/ntdll/ZwIsUILanguageComitted.s b/libc/nt/ntdll/ZwIsUILanguageComitted.s new file mode 100644 index 00000000..8960e483 --- /dev/null +++ b/libc/nt/ntdll/ZwIsUILanguageComitted.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwIsUILanguageComitted diff --git a/libc/nt/ntdll/ZwListenPort.s b/libc/nt/ntdll/ZwListenPort.s new file mode 100644 index 00000000..669509a5 --- /dev/null +++ b/libc/nt/ntdll/ZwListenPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwListenPort diff --git a/libc/nt/ntdll/ZwLoadDriver.s b/libc/nt/ntdll/ZwLoadDriver.s new file mode 100644 index 00000000..96fb61dd --- /dev/null +++ b/libc/nt/ntdll/ZwLoadDriver.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwLoadDriver diff --git a/libc/nt/ntdll/ZwLoadEnclaveData.s b/libc/nt/ntdll/ZwLoadEnclaveData.s new file mode 100644 index 00000000..325850ee --- /dev/null +++ b/libc/nt/ntdll/ZwLoadEnclaveData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwLoadEnclaveData diff --git a/libc/nt/ntdll/ZwLoadHotPatch.s b/libc/nt/ntdll/ZwLoadHotPatch.s new file mode 100644 index 00000000..9498c862 --- /dev/null +++ b/libc/nt/ntdll/ZwLoadHotPatch.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwLoadHotPatch diff --git a/libc/nt/ntdll/ZwLoadKey.s b/libc/nt/ntdll/ZwLoadKey.s new file mode 100644 index 00000000..284e5649 --- /dev/null +++ b/libc/nt/ntdll/ZwLoadKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwLoadKey diff --git a/libc/nt/ntdll/ZwLoadKey2.s b/libc/nt/ntdll/ZwLoadKey2.s new file mode 100644 index 00000000..69b10b93 --- /dev/null +++ b/libc/nt/ntdll/ZwLoadKey2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwLoadKey2 diff --git a/libc/nt/ntdll/ZwLoadKeyEx.s b/libc/nt/ntdll/ZwLoadKeyEx.s new file mode 100644 index 00000000..69fd93f9 --- /dev/null +++ b/libc/nt/ntdll/ZwLoadKeyEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwLoadKeyEx diff --git a/libc/nt/ntdll/ZwLockFile.s b/libc/nt/ntdll/ZwLockFile.s new file mode 100644 index 00000000..b406b744 --- /dev/null +++ b/libc/nt/ntdll/ZwLockFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwLockFile diff --git a/libc/nt/ntdll/ZwLockProductActivationKeys.s b/libc/nt/ntdll/ZwLockProductActivationKeys.s new file mode 100644 index 00000000..37952f8a --- /dev/null +++ b/libc/nt/ntdll/ZwLockProductActivationKeys.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwLockProductActivationKeys diff --git a/libc/nt/ntdll/ZwLockRegistryKey.s b/libc/nt/ntdll/ZwLockRegistryKey.s new file mode 100644 index 00000000..9695de46 --- /dev/null +++ b/libc/nt/ntdll/ZwLockRegistryKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwLockRegistryKey diff --git a/libc/nt/ntdll/ZwLockVirtualMemory.s b/libc/nt/ntdll/ZwLockVirtualMemory.s new file mode 100644 index 00000000..98073c22 --- /dev/null +++ b/libc/nt/ntdll/ZwLockVirtualMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwLockVirtualMemory diff --git a/libc/nt/ntdll/ZwMakePermanentObject.s b/libc/nt/ntdll/ZwMakePermanentObject.s new file mode 100644 index 00000000..0e972716 --- /dev/null +++ b/libc/nt/ntdll/ZwMakePermanentObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwMakePermanentObject diff --git a/libc/nt/ntdll/ZwMakeTemporaryObject.s b/libc/nt/ntdll/ZwMakeTemporaryObject.s new file mode 100644 index 00000000..306842f3 --- /dev/null +++ b/libc/nt/ntdll/ZwMakeTemporaryObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwMakeTemporaryObject diff --git a/libc/nt/ntdll/ZwManagePartition.s b/libc/nt/ntdll/ZwManagePartition.s new file mode 100644 index 00000000..e326e8ab --- /dev/null +++ b/libc/nt/ntdll/ZwManagePartition.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwManagePartition diff --git a/libc/nt/ntdll/ZwMapCMFModule.s b/libc/nt/ntdll/ZwMapCMFModule.s new file mode 100644 index 00000000..cc553a67 --- /dev/null +++ b/libc/nt/ntdll/ZwMapCMFModule.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwMapCMFModule diff --git a/libc/nt/ntdll/ZwMapUserPhysicalPages.s b/libc/nt/ntdll/ZwMapUserPhysicalPages.s new file mode 100644 index 00000000..fde76f11 --- /dev/null +++ b/libc/nt/ntdll/ZwMapUserPhysicalPages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwMapUserPhysicalPages diff --git a/libc/nt/ntdll/ZwMapUserPhysicalPagesScatter.s b/libc/nt/ntdll/ZwMapUserPhysicalPagesScatter.s new file mode 100644 index 00000000..b4425af9 --- /dev/null +++ b/libc/nt/ntdll/ZwMapUserPhysicalPagesScatter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwMapUserPhysicalPagesScatter diff --git a/libc/nt/ntdll/ZwMapViewOfSection.s b/libc/nt/ntdll/ZwMapViewOfSection.s new file mode 100644 index 00000000..6bf6cb7c --- /dev/null +++ b/libc/nt/ntdll/ZwMapViewOfSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwMapViewOfSection diff --git a/libc/nt/ntdll/ZwMapViewOfSectionEx.s b/libc/nt/ntdll/ZwMapViewOfSectionEx.s new file mode 100644 index 00000000..d2d51a90 --- /dev/null +++ b/libc/nt/ntdll/ZwMapViewOfSectionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwMapViewOfSectionEx diff --git a/libc/nt/ntdll/ZwModifyBootEntry.s b/libc/nt/ntdll/ZwModifyBootEntry.s new file mode 100644 index 00000000..a90b888a --- /dev/null +++ b/libc/nt/ntdll/ZwModifyBootEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwModifyBootEntry diff --git a/libc/nt/ntdll/ZwModifyDriverEntry.s b/libc/nt/ntdll/ZwModifyDriverEntry.s new file mode 100644 index 00000000..e0871dd4 --- /dev/null +++ b/libc/nt/ntdll/ZwModifyDriverEntry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwModifyDriverEntry diff --git a/libc/nt/ntdll/ZwNotifyChangeDirectoryFile.s b/libc/nt/ntdll/ZwNotifyChangeDirectoryFile.s new file mode 100644 index 00000000..b082a9e6 --- /dev/null +++ b/libc/nt/ntdll/ZwNotifyChangeDirectoryFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwNotifyChangeDirectoryFile diff --git a/libc/nt/ntdll/ZwNotifyChangeDirectoryFileEx.s b/libc/nt/ntdll/ZwNotifyChangeDirectoryFileEx.s new file mode 100644 index 00000000..5d601604 --- /dev/null +++ b/libc/nt/ntdll/ZwNotifyChangeDirectoryFileEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwNotifyChangeDirectoryFileEx diff --git a/libc/nt/ntdll/ZwNotifyChangeKey.s b/libc/nt/ntdll/ZwNotifyChangeKey.s new file mode 100644 index 00000000..31fc1c3d --- /dev/null +++ b/libc/nt/ntdll/ZwNotifyChangeKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwNotifyChangeKey diff --git a/libc/nt/ntdll/ZwNotifyChangeMultipleKeys.s b/libc/nt/ntdll/ZwNotifyChangeMultipleKeys.s new file mode 100644 index 00000000..5a6c9c11 --- /dev/null +++ b/libc/nt/ntdll/ZwNotifyChangeMultipleKeys.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwNotifyChangeMultipleKeys diff --git a/libc/nt/ntdll/ZwNotifyChangeSession.s b/libc/nt/ntdll/ZwNotifyChangeSession.s new file mode 100644 index 00000000..219063be --- /dev/null +++ b/libc/nt/ntdll/ZwNotifyChangeSession.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwNotifyChangeSession diff --git a/libc/nt/ntdll/ZwOpenDirectoryObject.s b/libc/nt/ntdll/ZwOpenDirectoryObject.s new file mode 100644 index 00000000..3900b977 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenDirectoryObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenDirectoryObject diff --git a/libc/nt/ntdll/ZwOpenEnlistment.s b/libc/nt/ntdll/ZwOpenEnlistment.s new file mode 100644 index 00000000..e252c380 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenEnlistment diff --git a/libc/nt/ntdll/ZwOpenEvent.s b/libc/nt/ntdll/ZwOpenEvent.s new file mode 100644 index 00000000..11dee1bd --- /dev/null +++ b/libc/nt/ntdll/ZwOpenEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenEvent diff --git a/libc/nt/ntdll/ZwOpenEventPair.s b/libc/nt/ntdll/ZwOpenEventPair.s new file mode 100644 index 00000000..aeb26679 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenEventPair.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenEventPair diff --git a/libc/nt/ntdll/ZwOpenFile.s b/libc/nt/ntdll/ZwOpenFile.s new file mode 100644 index 00000000..5f3108fc --- /dev/null +++ b/libc/nt/ntdll/ZwOpenFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenFile diff --git a/libc/nt/ntdll/ZwOpenIoCompletion.s b/libc/nt/ntdll/ZwOpenIoCompletion.s new file mode 100644 index 00000000..b127e734 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenIoCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenIoCompletion diff --git a/libc/nt/ntdll/ZwOpenJobObject.s b/libc/nt/ntdll/ZwOpenJobObject.s new file mode 100644 index 00000000..4eca7115 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenJobObject diff --git a/libc/nt/ntdll/ZwOpenKey.s b/libc/nt/ntdll/ZwOpenKey.s new file mode 100644 index 00000000..341119fc --- /dev/null +++ b/libc/nt/ntdll/ZwOpenKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenKey diff --git a/libc/nt/ntdll/ZwOpenKeyEx.s b/libc/nt/ntdll/ZwOpenKeyEx.s new file mode 100644 index 00000000..ae946d54 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenKeyEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenKeyEx diff --git a/libc/nt/ntdll/ZwOpenKeyTransacted.s b/libc/nt/ntdll/ZwOpenKeyTransacted.s new file mode 100644 index 00000000..c3896b29 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenKeyTransacted.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenKeyTransacted diff --git a/libc/nt/ntdll/ZwOpenKeyTransactedEx.s b/libc/nt/ntdll/ZwOpenKeyTransactedEx.s new file mode 100644 index 00000000..83d6a51a --- /dev/null +++ b/libc/nt/ntdll/ZwOpenKeyTransactedEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenKeyTransactedEx diff --git a/libc/nt/ntdll/ZwOpenKeyedEvent.s b/libc/nt/ntdll/ZwOpenKeyedEvent.s new file mode 100644 index 00000000..8776743c --- /dev/null +++ b/libc/nt/ntdll/ZwOpenKeyedEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenKeyedEvent diff --git a/libc/nt/ntdll/ZwOpenMutant.s b/libc/nt/ntdll/ZwOpenMutant.s new file mode 100644 index 00000000..51271ea6 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenMutant.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenMutant diff --git a/libc/nt/ntdll/ZwOpenObjectAuditAlarm.s b/libc/nt/ntdll/ZwOpenObjectAuditAlarm.s new file mode 100644 index 00000000..2e6d9c4f --- /dev/null +++ b/libc/nt/ntdll/ZwOpenObjectAuditAlarm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenObjectAuditAlarm diff --git a/libc/nt/ntdll/ZwOpenPartition.s b/libc/nt/ntdll/ZwOpenPartition.s new file mode 100644 index 00000000..b2662cfb --- /dev/null +++ b/libc/nt/ntdll/ZwOpenPartition.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenPartition diff --git a/libc/nt/ntdll/ZwOpenPrivateNamespace.s b/libc/nt/ntdll/ZwOpenPrivateNamespace.s new file mode 100644 index 00000000..15fa2e42 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenPrivateNamespace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenPrivateNamespace diff --git a/libc/nt/ntdll/ZwOpenProcess.s b/libc/nt/ntdll/ZwOpenProcess.s new file mode 100644 index 00000000..fcc939d1 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenProcess diff --git a/libc/nt/ntdll/ZwOpenProcessToken.s b/libc/nt/ntdll/ZwOpenProcessToken.s new file mode 100644 index 00000000..2df0f0d8 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenProcessToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenProcessToken diff --git a/libc/nt/ntdll/ZwOpenProcessTokenEx.s b/libc/nt/ntdll/ZwOpenProcessTokenEx.s new file mode 100644 index 00000000..27d8dfa8 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenProcessTokenEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenProcessTokenEx diff --git a/libc/nt/ntdll/ZwOpenRegistryTransaction.s b/libc/nt/ntdll/ZwOpenRegistryTransaction.s new file mode 100644 index 00000000..f66b2bd4 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenRegistryTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenRegistryTransaction diff --git a/libc/nt/ntdll/ZwOpenResourceManager.s b/libc/nt/ntdll/ZwOpenResourceManager.s new file mode 100644 index 00000000..61907aa5 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenResourceManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenResourceManager diff --git a/libc/nt/ntdll/ZwOpenSection.s b/libc/nt/ntdll/ZwOpenSection.s new file mode 100644 index 00000000..f0d978ed --- /dev/null +++ b/libc/nt/ntdll/ZwOpenSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenSection diff --git a/libc/nt/ntdll/ZwOpenSemaphore.s b/libc/nt/ntdll/ZwOpenSemaphore.s new file mode 100644 index 00000000..ff3e8260 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenSemaphore.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenSemaphore diff --git a/libc/nt/ntdll/ZwOpenSession.s b/libc/nt/ntdll/ZwOpenSession.s new file mode 100644 index 00000000..60557363 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenSession.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenSession diff --git a/libc/nt/ntdll/ZwOpenSymbolicLinkObject.s b/libc/nt/ntdll/ZwOpenSymbolicLinkObject.s new file mode 100644 index 00000000..ff5a7a1f --- /dev/null +++ b/libc/nt/ntdll/ZwOpenSymbolicLinkObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenSymbolicLinkObject diff --git a/libc/nt/ntdll/ZwOpenThread.s b/libc/nt/ntdll/ZwOpenThread.s new file mode 100644 index 00000000..2a9da6eb --- /dev/null +++ b/libc/nt/ntdll/ZwOpenThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenThread diff --git a/libc/nt/ntdll/ZwOpenThreadToken.s b/libc/nt/ntdll/ZwOpenThreadToken.s new file mode 100644 index 00000000..9797fae8 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenThreadToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenThreadToken diff --git a/libc/nt/ntdll/ZwOpenThreadTokenEx.s b/libc/nt/ntdll/ZwOpenThreadTokenEx.s new file mode 100644 index 00000000..16080013 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenThreadTokenEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenThreadTokenEx diff --git a/libc/nt/ntdll/ZwOpenTimer.s b/libc/nt/ntdll/ZwOpenTimer.s new file mode 100644 index 00000000..dea7caf8 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenTimer diff --git a/libc/nt/ntdll/ZwOpenTransaction.s b/libc/nt/ntdll/ZwOpenTransaction.s new file mode 100644 index 00000000..fa5acf41 --- /dev/null +++ b/libc/nt/ntdll/ZwOpenTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenTransaction diff --git a/libc/nt/ntdll/ZwOpenTransactionManager.s b/libc/nt/ntdll/ZwOpenTransactionManager.s new file mode 100644 index 00000000..4cf8c7bc --- /dev/null +++ b/libc/nt/ntdll/ZwOpenTransactionManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwOpenTransactionManager diff --git a/libc/nt/ntdll/ZwPlugPlayControl.s b/libc/nt/ntdll/ZwPlugPlayControl.s new file mode 100644 index 00000000..4d0bf703 --- /dev/null +++ b/libc/nt/ntdll/ZwPlugPlayControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwPlugPlayControl diff --git a/libc/nt/ntdll/ZwPowerInformation.s b/libc/nt/ntdll/ZwPowerInformation.s new file mode 100644 index 00000000..53bd8c0d --- /dev/null +++ b/libc/nt/ntdll/ZwPowerInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwPowerInformation diff --git a/libc/nt/ntdll/ZwPrePrepareComplete.s b/libc/nt/ntdll/ZwPrePrepareComplete.s new file mode 100644 index 00000000..ff82e647 --- /dev/null +++ b/libc/nt/ntdll/ZwPrePrepareComplete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwPrePrepareComplete diff --git a/libc/nt/ntdll/ZwPrePrepareEnlistment.s b/libc/nt/ntdll/ZwPrePrepareEnlistment.s new file mode 100644 index 00000000..a31fd1ba --- /dev/null +++ b/libc/nt/ntdll/ZwPrePrepareEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwPrePrepareEnlistment diff --git a/libc/nt/ntdll/ZwPrepareComplete.s b/libc/nt/ntdll/ZwPrepareComplete.s new file mode 100644 index 00000000..adf0c79a --- /dev/null +++ b/libc/nt/ntdll/ZwPrepareComplete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwPrepareComplete diff --git a/libc/nt/ntdll/ZwPrepareEnlistment.s b/libc/nt/ntdll/ZwPrepareEnlistment.s new file mode 100644 index 00000000..8de9049d --- /dev/null +++ b/libc/nt/ntdll/ZwPrepareEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwPrepareEnlistment diff --git a/libc/nt/ntdll/ZwPrivilegeCheck.s b/libc/nt/ntdll/ZwPrivilegeCheck.s new file mode 100644 index 00000000..b3072ab1 --- /dev/null +++ b/libc/nt/ntdll/ZwPrivilegeCheck.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwPrivilegeCheck diff --git a/libc/nt/ntdll/ZwPrivilegeObjectAuditAlarm.s b/libc/nt/ntdll/ZwPrivilegeObjectAuditAlarm.s new file mode 100644 index 00000000..b1e44511 --- /dev/null +++ b/libc/nt/ntdll/ZwPrivilegeObjectAuditAlarm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwPrivilegeObjectAuditAlarm diff --git a/libc/nt/ntdll/ZwPrivilegedServiceAuditAlarm.s b/libc/nt/ntdll/ZwPrivilegedServiceAuditAlarm.s new file mode 100644 index 00000000..2d5a55f6 --- /dev/null +++ b/libc/nt/ntdll/ZwPrivilegedServiceAuditAlarm.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwPrivilegedServiceAuditAlarm diff --git a/libc/nt/ntdll/ZwPropagationComplete.s b/libc/nt/ntdll/ZwPropagationComplete.s new file mode 100644 index 00000000..adf96644 --- /dev/null +++ b/libc/nt/ntdll/ZwPropagationComplete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwPropagationComplete diff --git a/libc/nt/ntdll/ZwPropagationFailed.s b/libc/nt/ntdll/ZwPropagationFailed.s new file mode 100644 index 00000000..c0f6f88d --- /dev/null +++ b/libc/nt/ntdll/ZwPropagationFailed.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwPropagationFailed diff --git a/libc/nt/ntdll/ZwProtectVirtualMemory.s b/libc/nt/ntdll/ZwProtectVirtualMemory.s new file mode 100644 index 00000000..f40525af --- /dev/null +++ b/libc/nt/ntdll/ZwProtectVirtualMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwProtectVirtualMemory diff --git a/libc/nt/ntdll/ZwPulseEvent.s b/libc/nt/ntdll/ZwPulseEvent.s new file mode 100644 index 00000000..01119f8c --- /dev/null +++ b/libc/nt/ntdll/ZwPulseEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwPulseEvent diff --git a/libc/nt/ntdll/ZwQueryAttributesFile.s b/libc/nt/ntdll/ZwQueryAttributesFile.s new file mode 100644 index 00000000..41c5f7d3 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryAttributesFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryAttributesFile diff --git a/libc/nt/ntdll/ZwQueryAuxiliaryCounterFrequency.s b/libc/nt/ntdll/ZwQueryAuxiliaryCounterFrequency.s new file mode 100644 index 00000000..504d07cf --- /dev/null +++ b/libc/nt/ntdll/ZwQueryAuxiliaryCounterFrequency.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryAuxiliaryCounterFrequency diff --git a/libc/nt/ntdll/ZwQueryBootEntryOrder.s b/libc/nt/ntdll/ZwQueryBootEntryOrder.s new file mode 100644 index 00000000..1f63d39f --- /dev/null +++ b/libc/nt/ntdll/ZwQueryBootEntryOrder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryBootEntryOrder diff --git a/libc/nt/ntdll/ZwQueryBootOptions.s b/libc/nt/ntdll/ZwQueryBootOptions.s new file mode 100644 index 00000000..c2747803 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryBootOptions.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryBootOptions diff --git a/libc/nt/ntdll/ZwQueryDebugFilterState.s b/libc/nt/ntdll/ZwQueryDebugFilterState.s new file mode 100644 index 00000000..9a193f46 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryDebugFilterState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryDebugFilterState diff --git a/libc/nt/ntdll/ZwQueryDefaultLocale.s b/libc/nt/ntdll/ZwQueryDefaultLocale.s new file mode 100644 index 00000000..24206375 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryDefaultLocale.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryDefaultLocale diff --git a/libc/nt/ntdll/ZwQueryDefaultUILanguage.s b/libc/nt/ntdll/ZwQueryDefaultUILanguage.s new file mode 100644 index 00000000..a8ecfbeb --- /dev/null +++ b/libc/nt/ntdll/ZwQueryDefaultUILanguage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryDefaultUILanguage diff --git a/libc/nt/ntdll/ZwQueryDirectoryFile.s b/libc/nt/ntdll/ZwQueryDirectoryFile.s new file mode 100644 index 00000000..8e2313ab --- /dev/null +++ b/libc/nt/ntdll/ZwQueryDirectoryFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryDirectoryFile diff --git a/libc/nt/ntdll/ZwQueryDirectoryFileEx.s b/libc/nt/ntdll/ZwQueryDirectoryFileEx.s new file mode 100644 index 00000000..c9146b37 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryDirectoryFileEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryDirectoryFileEx diff --git a/libc/nt/ntdll/ZwQueryDirectoryObject.s b/libc/nt/ntdll/ZwQueryDirectoryObject.s new file mode 100644 index 00000000..871e3b5b --- /dev/null +++ b/libc/nt/ntdll/ZwQueryDirectoryObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryDirectoryObject diff --git a/libc/nt/ntdll/ZwQueryDriverEntryOrder.s b/libc/nt/ntdll/ZwQueryDriverEntryOrder.s new file mode 100644 index 00000000..95f74e95 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryDriverEntryOrder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryDriverEntryOrder diff --git a/libc/nt/ntdll/ZwQueryEaFile.s b/libc/nt/ntdll/ZwQueryEaFile.s new file mode 100644 index 00000000..1b415d61 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryEaFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryEaFile diff --git a/libc/nt/ntdll/ZwQueryEvent.s b/libc/nt/ntdll/ZwQueryEvent.s new file mode 100644 index 00000000..b98bbf59 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryEvent diff --git a/libc/nt/ntdll/ZwQueryFullAttributesFile.s b/libc/nt/ntdll/ZwQueryFullAttributesFile.s new file mode 100644 index 00000000..ffd7d015 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryFullAttributesFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryFullAttributesFile diff --git a/libc/nt/ntdll/ZwQueryInformationAtom.s b/libc/nt/ntdll/ZwQueryInformationAtom.s new file mode 100644 index 00000000..051a6402 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryInformationAtom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryInformationAtom diff --git a/libc/nt/ntdll/ZwQueryInformationByName.s b/libc/nt/ntdll/ZwQueryInformationByName.s new file mode 100644 index 00000000..6174bc23 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryInformationByName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryInformationByName diff --git a/libc/nt/ntdll/ZwQueryInformationEnlistment.s b/libc/nt/ntdll/ZwQueryInformationEnlistment.s new file mode 100644 index 00000000..d624ed08 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryInformationEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryInformationEnlistment diff --git a/libc/nt/ntdll/ZwQueryInformationFile.s b/libc/nt/ntdll/ZwQueryInformationFile.s new file mode 100644 index 00000000..b108da9b --- /dev/null +++ b/libc/nt/ntdll/ZwQueryInformationFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryInformationFile diff --git a/libc/nt/ntdll/ZwQueryInformationJobObject.s b/libc/nt/ntdll/ZwQueryInformationJobObject.s new file mode 100644 index 00000000..3e1df17a --- /dev/null +++ b/libc/nt/ntdll/ZwQueryInformationJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryInformationJobObject diff --git a/libc/nt/ntdll/ZwQueryInformationPort.s b/libc/nt/ntdll/ZwQueryInformationPort.s new file mode 100644 index 00000000..09adc8ad --- /dev/null +++ b/libc/nt/ntdll/ZwQueryInformationPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryInformationPort diff --git a/libc/nt/ntdll/ZwQueryInformationProcess.s b/libc/nt/ntdll/ZwQueryInformationProcess.s new file mode 100644 index 00000000..484abbbb --- /dev/null +++ b/libc/nt/ntdll/ZwQueryInformationProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryInformationProcess diff --git a/libc/nt/ntdll/ZwQueryInformationResourceManager.s b/libc/nt/ntdll/ZwQueryInformationResourceManager.s new file mode 100644 index 00000000..9fa102b4 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryInformationResourceManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryInformationResourceManager diff --git a/libc/nt/ntdll/ZwQueryInformationThread.s b/libc/nt/ntdll/ZwQueryInformationThread.s new file mode 100644 index 00000000..451ec6ef --- /dev/null +++ b/libc/nt/ntdll/ZwQueryInformationThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryInformationThread diff --git a/libc/nt/ntdll/ZwQueryInformationToken.s b/libc/nt/ntdll/ZwQueryInformationToken.s new file mode 100644 index 00000000..7061e6c4 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryInformationToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryInformationToken diff --git a/libc/nt/ntdll/ZwQueryInformationTransaction.s b/libc/nt/ntdll/ZwQueryInformationTransaction.s new file mode 100644 index 00000000..5a3c2a39 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryInformationTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryInformationTransaction diff --git a/libc/nt/ntdll/ZwQueryInformationTransactionManager.s b/libc/nt/ntdll/ZwQueryInformationTransactionManager.s new file mode 100644 index 00000000..0dfc8676 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryInformationTransactionManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryInformationTransactionManager diff --git a/libc/nt/ntdll/ZwQueryInformationWorkerFactory.s b/libc/nt/ntdll/ZwQueryInformationWorkerFactory.s new file mode 100644 index 00000000..194a27a0 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryInformationWorkerFactory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryInformationWorkerFactory diff --git a/libc/nt/ntdll/ZwQueryInstallUILanguage.s b/libc/nt/ntdll/ZwQueryInstallUILanguage.s new file mode 100644 index 00000000..78882c63 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryInstallUILanguage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryInstallUILanguage diff --git a/libc/nt/ntdll/ZwQueryIntervalProfile.s b/libc/nt/ntdll/ZwQueryIntervalProfile.s new file mode 100644 index 00000000..c97ef074 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryIntervalProfile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryIntervalProfile diff --git a/libc/nt/ntdll/ZwQueryIoCompletion.s b/libc/nt/ntdll/ZwQueryIoCompletion.s new file mode 100644 index 00000000..c4f868d0 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryIoCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryIoCompletion diff --git a/libc/nt/ntdll/ZwQueryKey.s b/libc/nt/ntdll/ZwQueryKey.s new file mode 100644 index 00000000..73487286 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryKey diff --git a/libc/nt/ntdll/ZwQueryLicenseValue.s b/libc/nt/ntdll/ZwQueryLicenseValue.s new file mode 100644 index 00000000..bca32604 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryLicenseValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryLicenseValue diff --git a/libc/nt/ntdll/ZwQueryMultipleValueKey.s b/libc/nt/ntdll/ZwQueryMultipleValueKey.s new file mode 100644 index 00000000..d3f83123 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryMultipleValueKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryMultipleValueKey diff --git a/libc/nt/ntdll/ZwQueryMutant.s b/libc/nt/ntdll/ZwQueryMutant.s new file mode 100644 index 00000000..f34cd718 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryMutant.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryMutant diff --git a/libc/nt/ntdll/ZwQueryObject.s b/libc/nt/ntdll/ZwQueryObject.s new file mode 100644 index 00000000..7333e49b --- /dev/null +++ b/libc/nt/ntdll/ZwQueryObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryObject diff --git a/libc/nt/ntdll/ZwQueryOpenSubKeys.s b/libc/nt/ntdll/ZwQueryOpenSubKeys.s new file mode 100644 index 00000000..4622c6f8 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryOpenSubKeys.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryOpenSubKeys diff --git a/libc/nt/ntdll/ZwQueryOpenSubKeysEx.s b/libc/nt/ntdll/ZwQueryOpenSubKeysEx.s new file mode 100644 index 00000000..aeff1029 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryOpenSubKeysEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryOpenSubKeysEx diff --git a/libc/nt/ntdll/ZwQueryPerformanceCounter.s b/libc/nt/ntdll/ZwQueryPerformanceCounter.s new file mode 100644 index 00000000..933f493b --- /dev/null +++ b/libc/nt/ntdll/ZwQueryPerformanceCounter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryPerformanceCounter diff --git a/libc/nt/ntdll/ZwQueryPortInformationProcess.s b/libc/nt/ntdll/ZwQueryPortInformationProcess.s new file mode 100644 index 00000000..616aba26 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryPortInformationProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryPortInformationProcess diff --git a/libc/nt/ntdll/ZwQueryQuotaInformationFile.s b/libc/nt/ntdll/ZwQueryQuotaInformationFile.s new file mode 100644 index 00000000..b9696f05 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryQuotaInformationFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryQuotaInformationFile diff --git a/libc/nt/ntdll/ZwQuerySection.s b/libc/nt/ntdll/ZwQuerySection.s new file mode 100644 index 00000000..a4a4d585 --- /dev/null +++ b/libc/nt/ntdll/ZwQuerySection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQuerySection diff --git a/libc/nt/ntdll/ZwQuerySecurityAttributesToken.s b/libc/nt/ntdll/ZwQuerySecurityAttributesToken.s new file mode 100644 index 00000000..469da254 --- /dev/null +++ b/libc/nt/ntdll/ZwQuerySecurityAttributesToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQuerySecurityAttributesToken diff --git a/libc/nt/ntdll/ZwQuerySecurityObject.s b/libc/nt/ntdll/ZwQuerySecurityObject.s new file mode 100644 index 00000000..e14625c7 --- /dev/null +++ b/libc/nt/ntdll/ZwQuerySecurityObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQuerySecurityObject diff --git a/libc/nt/ntdll/ZwQuerySecurityPolicy.s b/libc/nt/ntdll/ZwQuerySecurityPolicy.s new file mode 100644 index 00000000..066cad29 --- /dev/null +++ b/libc/nt/ntdll/ZwQuerySecurityPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQuerySecurityPolicy diff --git a/libc/nt/ntdll/ZwQuerySemaphore.s b/libc/nt/ntdll/ZwQuerySemaphore.s new file mode 100644 index 00000000..757d96b8 --- /dev/null +++ b/libc/nt/ntdll/ZwQuerySemaphore.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQuerySemaphore diff --git a/libc/nt/ntdll/ZwQuerySymbolicLinkObject.s b/libc/nt/ntdll/ZwQuerySymbolicLinkObject.s new file mode 100644 index 00000000..1d4fed46 --- /dev/null +++ b/libc/nt/ntdll/ZwQuerySymbolicLinkObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQuerySymbolicLinkObject diff --git a/libc/nt/ntdll/ZwQuerySystemEnvironmentValue.s b/libc/nt/ntdll/ZwQuerySystemEnvironmentValue.s new file mode 100644 index 00000000..c50c2603 --- /dev/null +++ b/libc/nt/ntdll/ZwQuerySystemEnvironmentValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQuerySystemEnvironmentValue diff --git a/libc/nt/ntdll/ZwQuerySystemEnvironmentValueEx.s b/libc/nt/ntdll/ZwQuerySystemEnvironmentValueEx.s new file mode 100644 index 00000000..10ac902c --- /dev/null +++ b/libc/nt/ntdll/ZwQuerySystemEnvironmentValueEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQuerySystemEnvironmentValueEx diff --git a/libc/nt/ntdll/ZwQuerySystemInformation.s b/libc/nt/ntdll/ZwQuerySystemInformation.s new file mode 100644 index 00000000..d4da0088 --- /dev/null +++ b/libc/nt/ntdll/ZwQuerySystemInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQuerySystemInformation diff --git a/libc/nt/ntdll/ZwQuerySystemInformationEx.s b/libc/nt/ntdll/ZwQuerySystemInformationEx.s new file mode 100644 index 00000000..469c4150 --- /dev/null +++ b/libc/nt/ntdll/ZwQuerySystemInformationEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQuerySystemInformationEx diff --git a/libc/nt/ntdll/ZwQuerySystemTime.s b/libc/nt/ntdll/ZwQuerySystemTime.s new file mode 100644 index 00000000..e0fddb7f --- /dev/null +++ b/libc/nt/ntdll/ZwQuerySystemTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQuerySystemTime diff --git a/libc/nt/ntdll/ZwQueryTimer.s b/libc/nt/ntdll/ZwQueryTimer.s new file mode 100644 index 00000000..ddcb8012 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryTimer diff --git a/libc/nt/ntdll/ZwQueryTimerResolution.s b/libc/nt/ntdll/ZwQueryTimerResolution.s new file mode 100644 index 00000000..9db4c3a9 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryTimerResolution.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryTimerResolution diff --git a/libc/nt/ntdll/ZwQueryValueKey.s b/libc/nt/ntdll/ZwQueryValueKey.s new file mode 100644 index 00000000..52ad54bb --- /dev/null +++ b/libc/nt/ntdll/ZwQueryValueKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryValueKey diff --git a/libc/nt/ntdll/ZwQueryVirtualMemory.s b/libc/nt/ntdll/ZwQueryVirtualMemory.s new file mode 100644 index 00000000..2ae6d6da --- /dev/null +++ b/libc/nt/ntdll/ZwQueryVirtualMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryVirtualMemory diff --git a/libc/nt/ntdll/ZwQueryVolumeInformationFile.s b/libc/nt/ntdll/ZwQueryVolumeInformationFile.s new file mode 100644 index 00000000..262694ec --- /dev/null +++ b/libc/nt/ntdll/ZwQueryVolumeInformationFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryVolumeInformationFile diff --git a/libc/nt/ntdll/ZwQueryWnfStateData.s b/libc/nt/ntdll/ZwQueryWnfStateData.s new file mode 100644 index 00000000..6919a988 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryWnfStateData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryWnfStateData diff --git a/libc/nt/ntdll/ZwQueryWnfStateNameInformation.s b/libc/nt/ntdll/ZwQueryWnfStateNameInformation.s new file mode 100644 index 00000000..0f912ca4 --- /dev/null +++ b/libc/nt/ntdll/ZwQueryWnfStateNameInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueryWnfStateNameInformation diff --git a/libc/nt/ntdll/ZwQueueApcThread.s b/libc/nt/ntdll/ZwQueueApcThread.s new file mode 100644 index 00000000..4dda903c --- /dev/null +++ b/libc/nt/ntdll/ZwQueueApcThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueueApcThread diff --git a/libc/nt/ntdll/ZwQueueApcThreadEx.s b/libc/nt/ntdll/ZwQueueApcThreadEx.s new file mode 100644 index 00000000..da7c5814 --- /dev/null +++ b/libc/nt/ntdll/ZwQueueApcThreadEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwQueueApcThreadEx diff --git a/libc/nt/ntdll/ZwRaiseException.s b/libc/nt/ntdll/ZwRaiseException.s new file mode 100644 index 00000000..51247642 --- /dev/null +++ b/libc/nt/ntdll/ZwRaiseException.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRaiseException diff --git a/libc/nt/ntdll/ZwRaiseHardError.s b/libc/nt/ntdll/ZwRaiseHardError.s new file mode 100644 index 00000000..de38ef3a --- /dev/null +++ b/libc/nt/ntdll/ZwRaiseHardError.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRaiseHardError diff --git a/libc/nt/ntdll/ZwReadFile.s b/libc/nt/ntdll/ZwReadFile.s new file mode 100644 index 00000000..d7268136 --- /dev/null +++ b/libc/nt/ntdll/ZwReadFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwReadFile diff --git a/libc/nt/ntdll/ZwReadFileScatter.s b/libc/nt/ntdll/ZwReadFileScatter.s new file mode 100644 index 00000000..c7d1f2be --- /dev/null +++ b/libc/nt/ntdll/ZwReadFileScatter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwReadFileScatter diff --git a/libc/nt/ntdll/ZwReadOnlyEnlistment.s b/libc/nt/ntdll/ZwReadOnlyEnlistment.s new file mode 100644 index 00000000..5ec93a4e --- /dev/null +++ b/libc/nt/ntdll/ZwReadOnlyEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwReadOnlyEnlistment diff --git a/libc/nt/ntdll/ZwReadRequestData.s b/libc/nt/ntdll/ZwReadRequestData.s new file mode 100644 index 00000000..62456c51 --- /dev/null +++ b/libc/nt/ntdll/ZwReadRequestData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwReadRequestData diff --git a/libc/nt/ntdll/ZwReadVirtualMemory.s b/libc/nt/ntdll/ZwReadVirtualMemory.s new file mode 100644 index 00000000..dde31712 --- /dev/null +++ b/libc/nt/ntdll/ZwReadVirtualMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwReadVirtualMemory diff --git a/libc/nt/ntdll/ZwRecoverEnlistment.s b/libc/nt/ntdll/ZwRecoverEnlistment.s new file mode 100644 index 00000000..79476f98 --- /dev/null +++ b/libc/nt/ntdll/ZwRecoverEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRecoverEnlistment diff --git a/libc/nt/ntdll/ZwRecoverResourceManager.s b/libc/nt/ntdll/ZwRecoverResourceManager.s new file mode 100644 index 00000000..e41cd385 --- /dev/null +++ b/libc/nt/ntdll/ZwRecoverResourceManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRecoverResourceManager diff --git a/libc/nt/ntdll/ZwRecoverTransactionManager.s b/libc/nt/ntdll/ZwRecoverTransactionManager.s new file mode 100644 index 00000000..3be44f2b --- /dev/null +++ b/libc/nt/ntdll/ZwRecoverTransactionManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRecoverTransactionManager diff --git a/libc/nt/ntdll/ZwRegisterProtocolAddressInformation.s b/libc/nt/ntdll/ZwRegisterProtocolAddressInformation.s new file mode 100644 index 00000000..ef17cc8a --- /dev/null +++ b/libc/nt/ntdll/ZwRegisterProtocolAddressInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRegisterProtocolAddressInformation diff --git a/libc/nt/ntdll/ZwRegisterThreadTerminatePort.s b/libc/nt/ntdll/ZwRegisterThreadTerminatePort.s new file mode 100644 index 00000000..80220e19 --- /dev/null +++ b/libc/nt/ntdll/ZwRegisterThreadTerminatePort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRegisterThreadTerminatePort diff --git a/libc/nt/ntdll/ZwReleaseKeyedEvent.s b/libc/nt/ntdll/ZwReleaseKeyedEvent.s new file mode 100644 index 00000000..dace6cbc --- /dev/null +++ b/libc/nt/ntdll/ZwReleaseKeyedEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwReleaseKeyedEvent diff --git a/libc/nt/ntdll/ZwReleaseMutant.s b/libc/nt/ntdll/ZwReleaseMutant.s new file mode 100644 index 00000000..b707cdf3 --- /dev/null +++ b/libc/nt/ntdll/ZwReleaseMutant.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwReleaseMutant diff --git a/libc/nt/ntdll/ZwReleaseSemaphore.s b/libc/nt/ntdll/ZwReleaseSemaphore.s new file mode 100644 index 00000000..da5d921f --- /dev/null +++ b/libc/nt/ntdll/ZwReleaseSemaphore.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwReleaseSemaphore diff --git a/libc/nt/ntdll/ZwReleaseWorkerFactoryWorker.s b/libc/nt/ntdll/ZwReleaseWorkerFactoryWorker.s new file mode 100644 index 00000000..3f6f3c8b --- /dev/null +++ b/libc/nt/ntdll/ZwReleaseWorkerFactoryWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwReleaseWorkerFactoryWorker diff --git a/libc/nt/ntdll/ZwRemoveIoCompletion.s b/libc/nt/ntdll/ZwRemoveIoCompletion.s new file mode 100644 index 00000000..8e89b55d --- /dev/null +++ b/libc/nt/ntdll/ZwRemoveIoCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRemoveIoCompletion diff --git a/libc/nt/ntdll/ZwRemoveIoCompletionEx.s b/libc/nt/ntdll/ZwRemoveIoCompletionEx.s new file mode 100644 index 00000000..68781590 --- /dev/null +++ b/libc/nt/ntdll/ZwRemoveIoCompletionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRemoveIoCompletionEx diff --git a/libc/nt/ntdll/ZwRemoveProcessDebug.s b/libc/nt/ntdll/ZwRemoveProcessDebug.s new file mode 100644 index 00000000..dd1bfe62 --- /dev/null +++ b/libc/nt/ntdll/ZwRemoveProcessDebug.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRemoveProcessDebug diff --git a/libc/nt/ntdll/ZwRenameKey.s b/libc/nt/ntdll/ZwRenameKey.s new file mode 100644 index 00000000..77addb88 --- /dev/null +++ b/libc/nt/ntdll/ZwRenameKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRenameKey diff --git a/libc/nt/ntdll/ZwRenameTransactionManager.s b/libc/nt/ntdll/ZwRenameTransactionManager.s new file mode 100644 index 00000000..bf793d46 --- /dev/null +++ b/libc/nt/ntdll/ZwRenameTransactionManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRenameTransactionManager diff --git a/libc/nt/ntdll/ZwReplaceKey.s b/libc/nt/ntdll/ZwReplaceKey.s new file mode 100644 index 00000000..70ff9afd --- /dev/null +++ b/libc/nt/ntdll/ZwReplaceKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwReplaceKey diff --git a/libc/nt/ntdll/ZwReplacePartitionUnit.s b/libc/nt/ntdll/ZwReplacePartitionUnit.s new file mode 100644 index 00000000..82643db5 --- /dev/null +++ b/libc/nt/ntdll/ZwReplacePartitionUnit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwReplacePartitionUnit diff --git a/libc/nt/ntdll/ZwReplyPort.s b/libc/nt/ntdll/ZwReplyPort.s new file mode 100644 index 00000000..7cb402a6 --- /dev/null +++ b/libc/nt/ntdll/ZwReplyPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwReplyPort diff --git a/libc/nt/ntdll/ZwReplyWaitReceivePort.s b/libc/nt/ntdll/ZwReplyWaitReceivePort.s new file mode 100644 index 00000000..bf818aa2 --- /dev/null +++ b/libc/nt/ntdll/ZwReplyWaitReceivePort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwReplyWaitReceivePort diff --git a/libc/nt/ntdll/ZwReplyWaitReceivePortEx.s b/libc/nt/ntdll/ZwReplyWaitReceivePortEx.s new file mode 100644 index 00000000..2b0c9267 --- /dev/null +++ b/libc/nt/ntdll/ZwReplyWaitReceivePortEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwReplyWaitReceivePortEx diff --git a/libc/nt/ntdll/ZwReplyWaitReplyPort.s b/libc/nt/ntdll/ZwReplyWaitReplyPort.s new file mode 100644 index 00000000..96184b54 --- /dev/null +++ b/libc/nt/ntdll/ZwReplyWaitReplyPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwReplyWaitReplyPort diff --git a/libc/nt/ntdll/ZwRequestPort.s b/libc/nt/ntdll/ZwRequestPort.s new file mode 100644 index 00000000..17604c84 --- /dev/null +++ b/libc/nt/ntdll/ZwRequestPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRequestPort diff --git a/libc/nt/ntdll/ZwRequestWaitReplyPort.s b/libc/nt/ntdll/ZwRequestWaitReplyPort.s new file mode 100644 index 00000000..7766072e --- /dev/null +++ b/libc/nt/ntdll/ZwRequestWaitReplyPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRequestWaitReplyPort diff --git a/libc/nt/ntdll/ZwResetEvent.s b/libc/nt/ntdll/ZwResetEvent.s new file mode 100644 index 00000000..0f890204 --- /dev/null +++ b/libc/nt/ntdll/ZwResetEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwResetEvent diff --git a/libc/nt/ntdll/ZwResetWriteWatch.s b/libc/nt/ntdll/ZwResetWriteWatch.s new file mode 100644 index 00000000..b45ef82c --- /dev/null +++ b/libc/nt/ntdll/ZwResetWriteWatch.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwResetWriteWatch diff --git a/libc/nt/ntdll/ZwRestoreKey.s b/libc/nt/ntdll/ZwRestoreKey.s new file mode 100644 index 00000000..c8d81e6d --- /dev/null +++ b/libc/nt/ntdll/ZwRestoreKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRestoreKey diff --git a/libc/nt/ntdll/ZwResumeProcess.s b/libc/nt/ntdll/ZwResumeProcess.s new file mode 100644 index 00000000..d307fbe8 --- /dev/null +++ b/libc/nt/ntdll/ZwResumeProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwResumeProcess diff --git a/libc/nt/ntdll/ZwResumeThread.s b/libc/nt/ntdll/ZwResumeThread.s new file mode 100644 index 00000000..153c94fb --- /dev/null +++ b/libc/nt/ntdll/ZwResumeThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwResumeThread diff --git a/libc/nt/ntdll/ZwRevertContainerImpersonation.s b/libc/nt/ntdll/ZwRevertContainerImpersonation.s new file mode 100644 index 00000000..b5d3e6ba --- /dev/null +++ b/libc/nt/ntdll/ZwRevertContainerImpersonation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRevertContainerImpersonation diff --git a/libc/nt/ntdll/ZwRollbackComplete.s b/libc/nt/ntdll/ZwRollbackComplete.s new file mode 100644 index 00000000..788e7ab3 --- /dev/null +++ b/libc/nt/ntdll/ZwRollbackComplete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRollbackComplete diff --git a/libc/nt/ntdll/ZwRollbackEnlistment.s b/libc/nt/ntdll/ZwRollbackEnlistment.s new file mode 100644 index 00000000..d33d66ec --- /dev/null +++ b/libc/nt/ntdll/ZwRollbackEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRollbackEnlistment diff --git a/libc/nt/ntdll/ZwRollbackRegistryTransaction.s b/libc/nt/ntdll/ZwRollbackRegistryTransaction.s new file mode 100644 index 00000000..973ca609 --- /dev/null +++ b/libc/nt/ntdll/ZwRollbackRegistryTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRollbackRegistryTransaction diff --git a/libc/nt/ntdll/ZwRollbackTransaction.s b/libc/nt/ntdll/ZwRollbackTransaction.s new file mode 100644 index 00000000..aa79680e --- /dev/null +++ b/libc/nt/ntdll/ZwRollbackTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRollbackTransaction diff --git a/libc/nt/ntdll/ZwRollforwardTransactionManager.s b/libc/nt/ntdll/ZwRollforwardTransactionManager.s new file mode 100644 index 00000000..1f88ff8c --- /dev/null +++ b/libc/nt/ntdll/ZwRollforwardTransactionManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwRollforwardTransactionManager diff --git a/libc/nt/ntdll/ZwSaveKey.s b/libc/nt/ntdll/ZwSaveKey.s new file mode 100644 index 00000000..cb574c38 --- /dev/null +++ b/libc/nt/ntdll/ZwSaveKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSaveKey diff --git a/libc/nt/ntdll/ZwSaveKeyEx.s b/libc/nt/ntdll/ZwSaveKeyEx.s new file mode 100644 index 00000000..d21dc2e4 --- /dev/null +++ b/libc/nt/ntdll/ZwSaveKeyEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSaveKeyEx diff --git a/libc/nt/ntdll/ZwSaveMergedKeys.s b/libc/nt/ntdll/ZwSaveMergedKeys.s new file mode 100644 index 00000000..133cd046 --- /dev/null +++ b/libc/nt/ntdll/ZwSaveMergedKeys.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSaveMergedKeys diff --git a/libc/nt/ntdll/ZwSecureConnectPort.s b/libc/nt/ntdll/ZwSecureConnectPort.s new file mode 100644 index 00000000..56286e44 --- /dev/null +++ b/libc/nt/ntdll/ZwSecureConnectPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSecureConnectPort diff --git a/libc/nt/ntdll/ZwSerializeBoot.s b/libc/nt/ntdll/ZwSerializeBoot.s new file mode 100644 index 00000000..5445e5ac --- /dev/null +++ b/libc/nt/ntdll/ZwSerializeBoot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSerializeBoot diff --git a/libc/nt/ntdll/ZwSetBootEntryOrder.s b/libc/nt/ntdll/ZwSetBootEntryOrder.s new file mode 100644 index 00000000..22f6490a --- /dev/null +++ b/libc/nt/ntdll/ZwSetBootEntryOrder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetBootEntryOrder diff --git a/libc/nt/ntdll/ZwSetBootOptions.s b/libc/nt/ntdll/ZwSetBootOptions.s new file mode 100644 index 00000000..0cc531b2 --- /dev/null +++ b/libc/nt/ntdll/ZwSetBootOptions.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetBootOptions diff --git a/libc/nt/ntdll/ZwSetCachedSigningLevel.s b/libc/nt/ntdll/ZwSetCachedSigningLevel.s new file mode 100644 index 00000000..88d15777 --- /dev/null +++ b/libc/nt/ntdll/ZwSetCachedSigningLevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetCachedSigningLevel diff --git a/libc/nt/ntdll/ZwSetCachedSigningLevel2.s b/libc/nt/ntdll/ZwSetCachedSigningLevel2.s new file mode 100644 index 00000000..27c56491 --- /dev/null +++ b/libc/nt/ntdll/ZwSetCachedSigningLevel2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetCachedSigningLevel2 diff --git a/libc/nt/ntdll/ZwSetContextThread.s b/libc/nt/ntdll/ZwSetContextThread.s new file mode 100644 index 00000000..7d36e8ee --- /dev/null +++ b/libc/nt/ntdll/ZwSetContextThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetContextThread diff --git a/libc/nt/ntdll/ZwSetDebugFilterState.s b/libc/nt/ntdll/ZwSetDebugFilterState.s new file mode 100644 index 00000000..0d63feef --- /dev/null +++ b/libc/nt/ntdll/ZwSetDebugFilterState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetDebugFilterState diff --git a/libc/nt/ntdll/ZwSetDefaultHardErrorPort.s b/libc/nt/ntdll/ZwSetDefaultHardErrorPort.s new file mode 100644 index 00000000..790efe08 --- /dev/null +++ b/libc/nt/ntdll/ZwSetDefaultHardErrorPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetDefaultHardErrorPort diff --git a/libc/nt/ntdll/ZwSetDefaultLocale.s b/libc/nt/ntdll/ZwSetDefaultLocale.s new file mode 100644 index 00000000..e5ee7e78 --- /dev/null +++ b/libc/nt/ntdll/ZwSetDefaultLocale.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetDefaultLocale diff --git a/libc/nt/ntdll/ZwSetDefaultUILanguage.s b/libc/nt/ntdll/ZwSetDefaultUILanguage.s new file mode 100644 index 00000000..6eaf1b47 --- /dev/null +++ b/libc/nt/ntdll/ZwSetDefaultUILanguage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetDefaultUILanguage diff --git a/libc/nt/ntdll/ZwSetDriverEntryOrder.s b/libc/nt/ntdll/ZwSetDriverEntryOrder.s new file mode 100644 index 00000000..a1232805 --- /dev/null +++ b/libc/nt/ntdll/ZwSetDriverEntryOrder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetDriverEntryOrder diff --git a/libc/nt/ntdll/ZwSetEaFile.s b/libc/nt/ntdll/ZwSetEaFile.s new file mode 100644 index 00000000..03194ec6 --- /dev/null +++ b/libc/nt/ntdll/ZwSetEaFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetEaFile diff --git a/libc/nt/ntdll/ZwSetEvent.s b/libc/nt/ntdll/ZwSetEvent.s new file mode 100644 index 00000000..e04a0378 --- /dev/null +++ b/libc/nt/ntdll/ZwSetEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetEvent diff --git a/libc/nt/ntdll/ZwSetEventBoostPriority.s b/libc/nt/ntdll/ZwSetEventBoostPriority.s new file mode 100644 index 00000000..b8c890f0 --- /dev/null +++ b/libc/nt/ntdll/ZwSetEventBoostPriority.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetEventBoostPriority diff --git a/libc/nt/ntdll/ZwSetHighEventPair.s b/libc/nt/ntdll/ZwSetHighEventPair.s new file mode 100644 index 00000000..6f240676 --- /dev/null +++ b/libc/nt/ntdll/ZwSetHighEventPair.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetHighEventPair diff --git a/libc/nt/ntdll/ZwSetHighWaitLowEventPair.s b/libc/nt/ntdll/ZwSetHighWaitLowEventPair.s new file mode 100644 index 00000000..a3f31f0e --- /dev/null +++ b/libc/nt/ntdll/ZwSetHighWaitLowEventPair.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetHighWaitLowEventPair diff --git a/libc/nt/ntdll/ZwSetIRTimer.s b/libc/nt/ntdll/ZwSetIRTimer.s new file mode 100644 index 00000000..10ff03a7 --- /dev/null +++ b/libc/nt/ntdll/ZwSetIRTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetIRTimer diff --git a/libc/nt/ntdll/ZwSetInformationDebugObject.s b/libc/nt/ntdll/ZwSetInformationDebugObject.s new file mode 100644 index 00000000..efecf62a --- /dev/null +++ b/libc/nt/ntdll/ZwSetInformationDebugObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetInformationDebugObject diff --git a/libc/nt/ntdll/ZwSetInformationEnlistment.s b/libc/nt/ntdll/ZwSetInformationEnlistment.s new file mode 100644 index 00000000..0bb333bb --- /dev/null +++ b/libc/nt/ntdll/ZwSetInformationEnlistment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetInformationEnlistment diff --git a/libc/nt/ntdll/ZwSetInformationFile.s b/libc/nt/ntdll/ZwSetInformationFile.s new file mode 100644 index 00000000..5421c9f7 --- /dev/null +++ b/libc/nt/ntdll/ZwSetInformationFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetInformationFile diff --git a/libc/nt/ntdll/ZwSetInformationJobObject.s b/libc/nt/ntdll/ZwSetInformationJobObject.s new file mode 100644 index 00000000..a5e44d06 --- /dev/null +++ b/libc/nt/ntdll/ZwSetInformationJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetInformationJobObject diff --git a/libc/nt/ntdll/ZwSetInformationKey.s b/libc/nt/ntdll/ZwSetInformationKey.s new file mode 100644 index 00000000..aa6789c8 --- /dev/null +++ b/libc/nt/ntdll/ZwSetInformationKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetInformationKey diff --git a/libc/nt/ntdll/ZwSetInformationObject.s b/libc/nt/ntdll/ZwSetInformationObject.s new file mode 100644 index 00000000..0ad6f721 --- /dev/null +++ b/libc/nt/ntdll/ZwSetInformationObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetInformationObject diff --git a/libc/nt/ntdll/ZwSetInformationProcess.s b/libc/nt/ntdll/ZwSetInformationProcess.s new file mode 100644 index 00000000..14f7340b --- /dev/null +++ b/libc/nt/ntdll/ZwSetInformationProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetInformationProcess diff --git a/libc/nt/ntdll/ZwSetInformationResourceManager.s b/libc/nt/ntdll/ZwSetInformationResourceManager.s new file mode 100644 index 00000000..7ca147d6 --- /dev/null +++ b/libc/nt/ntdll/ZwSetInformationResourceManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetInformationResourceManager diff --git a/libc/nt/ntdll/ZwSetInformationSymbolicLink.s b/libc/nt/ntdll/ZwSetInformationSymbolicLink.s new file mode 100644 index 00000000..e8533179 --- /dev/null +++ b/libc/nt/ntdll/ZwSetInformationSymbolicLink.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetInformationSymbolicLink diff --git a/libc/nt/ntdll/ZwSetInformationThread.s b/libc/nt/ntdll/ZwSetInformationThread.s new file mode 100644 index 00000000..db320f5c --- /dev/null +++ b/libc/nt/ntdll/ZwSetInformationThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetInformationThread diff --git a/libc/nt/ntdll/ZwSetInformationToken.s b/libc/nt/ntdll/ZwSetInformationToken.s new file mode 100644 index 00000000..89fb436a --- /dev/null +++ b/libc/nt/ntdll/ZwSetInformationToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetInformationToken diff --git a/libc/nt/ntdll/ZwSetInformationTransaction.s b/libc/nt/ntdll/ZwSetInformationTransaction.s new file mode 100644 index 00000000..95b82b04 --- /dev/null +++ b/libc/nt/ntdll/ZwSetInformationTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetInformationTransaction diff --git a/libc/nt/ntdll/ZwSetInformationTransactionManager.s b/libc/nt/ntdll/ZwSetInformationTransactionManager.s new file mode 100644 index 00000000..5596fbac --- /dev/null +++ b/libc/nt/ntdll/ZwSetInformationTransactionManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetInformationTransactionManager diff --git a/libc/nt/ntdll/ZwSetInformationVirtualMemory.s b/libc/nt/ntdll/ZwSetInformationVirtualMemory.s new file mode 100644 index 00000000..95de1e1a --- /dev/null +++ b/libc/nt/ntdll/ZwSetInformationVirtualMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetInformationVirtualMemory diff --git a/libc/nt/ntdll/ZwSetInformationWorkerFactory.s b/libc/nt/ntdll/ZwSetInformationWorkerFactory.s new file mode 100644 index 00000000..ad37d5d3 --- /dev/null +++ b/libc/nt/ntdll/ZwSetInformationWorkerFactory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetInformationWorkerFactory diff --git a/libc/nt/ntdll/ZwSetIntervalProfile.s b/libc/nt/ntdll/ZwSetIntervalProfile.s new file mode 100644 index 00000000..db1176d6 --- /dev/null +++ b/libc/nt/ntdll/ZwSetIntervalProfile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetIntervalProfile diff --git a/libc/nt/ntdll/ZwSetIoCompletion.s b/libc/nt/ntdll/ZwSetIoCompletion.s new file mode 100644 index 00000000..b45ce2b2 --- /dev/null +++ b/libc/nt/ntdll/ZwSetIoCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetIoCompletion diff --git a/libc/nt/ntdll/ZwSetIoCompletionEx.s b/libc/nt/ntdll/ZwSetIoCompletionEx.s new file mode 100644 index 00000000..ac61b20b --- /dev/null +++ b/libc/nt/ntdll/ZwSetIoCompletionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetIoCompletionEx diff --git a/libc/nt/ntdll/ZwSetLdtEntries.s b/libc/nt/ntdll/ZwSetLdtEntries.s new file mode 100644 index 00000000..017e1d54 --- /dev/null +++ b/libc/nt/ntdll/ZwSetLdtEntries.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetLdtEntries diff --git a/libc/nt/ntdll/ZwSetLowEventPair.s b/libc/nt/ntdll/ZwSetLowEventPair.s new file mode 100644 index 00000000..708435ed --- /dev/null +++ b/libc/nt/ntdll/ZwSetLowEventPair.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetLowEventPair diff --git a/libc/nt/ntdll/ZwSetLowWaitHighEventPair.s b/libc/nt/ntdll/ZwSetLowWaitHighEventPair.s new file mode 100644 index 00000000..9f7f9eb2 --- /dev/null +++ b/libc/nt/ntdll/ZwSetLowWaitHighEventPair.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetLowWaitHighEventPair diff --git a/libc/nt/ntdll/ZwSetQuotaInformationFile.s b/libc/nt/ntdll/ZwSetQuotaInformationFile.s new file mode 100644 index 00000000..11bd4fc8 --- /dev/null +++ b/libc/nt/ntdll/ZwSetQuotaInformationFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetQuotaInformationFile diff --git a/libc/nt/ntdll/ZwSetSecurityObject.s b/libc/nt/ntdll/ZwSetSecurityObject.s new file mode 100644 index 00000000..77844bc4 --- /dev/null +++ b/libc/nt/ntdll/ZwSetSecurityObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetSecurityObject diff --git a/libc/nt/ntdll/ZwSetSystemEnvironmentValue.s b/libc/nt/ntdll/ZwSetSystemEnvironmentValue.s new file mode 100644 index 00000000..06d02390 --- /dev/null +++ b/libc/nt/ntdll/ZwSetSystemEnvironmentValue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetSystemEnvironmentValue diff --git a/libc/nt/ntdll/ZwSetSystemEnvironmentValueEx.s b/libc/nt/ntdll/ZwSetSystemEnvironmentValueEx.s new file mode 100644 index 00000000..73c48868 --- /dev/null +++ b/libc/nt/ntdll/ZwSetSystemEnvironmentValueEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetSystemEnvironmentValueEx diff --git a/libc/nt/ntdll/ZwSetSystemInformation.s b/libc/nt/ntdll/ZwSetSystemInformation.s new file mode 100644 index 00000000..a40e420e --- /dev/null +++ b/libc/nt/ntdll/ZwSetSystemInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetSystemInformation diff --git a/libc/nt/ntdll/ZwSetSystemPowerState.s b/libc/nt/ntdll/ZwSetSystemPowerState.s new file mode 100644 index 00000000..53132f1e --- /dev/null +++ b/libc/nt/ntdll/ZwSetSystemPowerState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetSystemPowerState diff --git a/libc/nt/ntdll/ZwSetSystemTime.s b/libc/nt/ntdll/ZwSetSystemTime.s new file mode 100644 index 00000000..a1fa0094 --- /dev/null +++ b/libc/nt/ntdll/ZwSetSystemTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetSystemTime diff --git a/libc/nt/ntdll/ZwSetThreadExecutionState.s b/libc/nt/ntdll/ZwSetThreadExecutionState.s new file mode 100644 index 00000000..f979634b --- /dev/null +++ b/libc/nt/ntdll/ZwSetThreadExecutionState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetThreadExecutionState diff --git a/libc/nt/ntdll/ZwSetTimer.s b/libc/nt/ntdll/ZwSetTimer.s new file mode 100644 index 00000000..f7b0ab45 --- /dev/null +++ b/libc/nt/ntdll/ZwSetTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetTimer diff --git a/libc/nt/ntdll/ZwSetTimer2.s b/libc/nt/ntdll/ZwSetTimer2.s new file mode 100644 index 00000000..eb8285d5 --- /dev/null +++ b/libc/nt/ntdll/ZwSetTimer2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetTimer2 diff --git a/libc/nt/ntdll/ZwSetTimerEx.s b/libc/nt/ntdll/ZwSetTimerEx.s new file mode 100644 index 00000000..e987535b --- /dev/null +++ b/libc/nt/ntdll/ZwSetTimerEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetTimerEx diff --git a/libc/nt/ntdll/ZwSetTimerResolution.s b/libc/nt/ntdll/ZwSetTimerResolution.s new file mode 100644 index 00000000..cefbc250 --- /dev/null +++ b/libc/nt/ntdll/ZwSetTimerResolution.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetTimerResolution diff --git a/libc/nt/ntdll/ZwSetUuidSeed.s b/libc/nt/ntdll/ZwSetUuidSeed.s new file mode 100644 index 00000000..eb25046a --- /dev/null +++ b/libc/nt/ntdll/ZwSetUuidSeed.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetUuidSeed diff --git a/libc/nt/ntdll/ZwSetValueKey.s b/libc/nt/ntdll/ZwSetValueKey.s new file mode 100644 index 00000000..13bd53e8 --- /dev/null +++ b/libc/nt/ntdll/ZwSetValueKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetValueKey diff --git a/libc/nt/ntdll/ZwSetVolumeInformationFile.s b/libc/nt/ntdll/ZwSetVolumeInformationFile.s new file mode 100644 index 00000000..f4c23154 --- /dev/null +++ b/libc/nt/ntdll/ZwSetVolumeInformationFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetVolumeInformationFile diff --git a/libc/nt/ntdll/ZwSetWnfProcessNotificationEvent.s b/libc/nt/ntdll/ZwSetWnfProcessNotificationEvent.s new file mode 100644 index 00000000..ad78b119 --- /dev/null +++ b/libc/nt/ntdll/ZwSetWnfProcessNotificationEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSetWnfProcessNotificationEvent diff --git a/libc/nt/ntdll/ZwShutdownSystem.s b/libc/nt/ntdll/ZwShutdownSystem.s new file mode 100644 index 00000000..865140b1 --- /dev/null +++ b/libc/nt/ntdll/ZwShutdownSystem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwShutdownSystem diff --git a/libc/nt/ntdll/ZwShutdownWorkerFactory.s b/libc/nt/ntdll/ZwShutdownWorkerFactory.s new file mode 100644 index 00000000..f7eee54a --- /dev/null +++ b/libc/nt/ntdll/ZwShutdownWorkerFactory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwShutdownWorkerFactory diff --git a/libc/nt/ntdll/ZwSignalAndWaitForSingleObject.s b/libc/nt/ntdll/ZwSignalAndWaitForSingleObject.s new file mode 100644 index 00000000..b8db9ffa --- /dev/null +++ b/libc/nt/ntdll/ZwSignalAndWaitForSingleObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSignalAndWaitForSingleObject diff --git a/libc/nt/ntdll/ZwSinglePhaseReject.s b/libc/nt/ntdll/ZwSinglePhaseReject.s new file mode 100644 index 00000000..ffa08310 --- /dev/null +++ b/libc/nt/ntdll/ZwSinglePhaseReject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSinglePhaseReject diff --git a/libc/nt/ntdll/ZwStartProfile.s b/libc/nt/ntdll/ZwStartProfile.s new file mode 100644 index 00000000..b9c7469b --- /dev/null +++ b/libc/nt/ntdll/ZwStartProfile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwStartProfile diff --git a/libc/nt/ntdll/ZwStopProfile.s b/libc/nt/ntdll/ZwStopProfile.s new file mode 100644 index 00000000..9cdb7b93 --- /dev/null +++ b/libc/nt/ntdll/ZwStopProfile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwStopProfile diff --git a/libc/nt/ntdll/ZwSubscribeWnfStateChange.s b/libc/nt/ntdll/ZwSubscribeWnfStateChange.s new file mode 100644 index 00000000..39abd5a8 --- /dev/null +++ b/libc/nt/ntdll/ZwSubscribeWnfStateChange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSubscribeWnfStateChange diff --git a/libc/nt/ntdll/ZwSuspendProcess.s b/libc/nt/ntdll/ZwSuspendProcess.s new file mode 100644 index 00000000..2e99d46b --- /dev/null +++ b/libc/nt/ntdll/ZwSuspendProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSuspendProcess diff --git a/libc/nt/ntdll/ZwSuspendThread.s b/libc/nt/ntdll/ZwSuspendThread.s new file mode 100644 index 00000000..12979b99 --- /dev/null +++ b/libc/nt/ntdll/ZwSuspendThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSuspendThread diff --git a/libc/nt/ntdll/ZwSystemDebugControl.s b/libc/nt/ntdll/ZwSystemDebugControl.s new file mode 100644 index 00000000..47809000 --- /dev/null +++ b/libc/nt/ntdll/ZwSystemDebugControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwSystemDebugControl diff --git a/libc/nt/ntdll/ZwTerminateEnclave.s b/libc/nt/ntdll/ZwTerminateEnclave.s new file mode 100644 index 00000000..1fc2b894 --- /dev/null +++ b/libc/nt/ntdll/ZwTerminateEnclave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwTerminateEnclave diff --git a/libc/nt/ntdll/ZwTerminateJobObject.s b/libc/nt/ntdll/ZwTerminateJobObject.s new file mode 100644 index 00000000..f96219ca --- /dev/null +++ b/libc/nt/ntdll/ZwTerminateJobObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwTerminateJobObject diff --git a/libc/nt/ntdll/ZwTerminateProcess.s b/libc/nt/ntdll/ZwTerminateProcess.s new file mode 100644 index 00000000..6e67193d --- /dev/null +++ b/libc/nt/ntdll/ZwTerminateProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwTerminateProcess diff --git a/libc/nt/ntdll/ZwTerminateThread.s b/libc/nt/ntdll/ZwTerminateThread.s new file mode 100644 index 00000000..75e989c1 --- /dev/null +++ b/libc/nt/ntdll/ZwTerminateThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwTerminateThread diff --git a/libc/nt/ntdll/ZwTestAlert.s b/libc/nt/ntdll/ZwTestAlert.s new file mode 100644 index 00000000..744810ee --- /dev/null +++ b/libc/nt/ntdll/ZwTestAlert.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwTestAlert diff --git a/libc/nt/ntdll/ZwThawRegistry.s b/libc/nt/ntdll/ZwThawRegistry.s new file mode 100644 index 00000000..e22c20c7 --- /dev/null +++ b/libc/nt/ntdll/ZwThawRegistry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwThawRegistry diff --git a/libc/nt/ntdll/ZwThawTransactions.s b/libc/nt/ntdll/ZwThawTransactions.s new file mode 100644 index 00000000..b46124b0 --- /dev/null +++ b/libc/nt/ntdll/ZwThawTransactions.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwThawTransactions diff --git a/libc/nt/ntdll/ZwTraceControl.s b/libc/nt/ntdll/ZwTraceControl.s new file mode 100644 index 00000000..61f50a3b --- /dev/null +++ b/libc/nt/ntdll/ZwTraceControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwTraceControl diff --git a/libc/nt/ntdll/ZwTraceEvent.s b/libc/nt/ntdll/ZwTraceEvent.s new file mode 100644 index 00000000..76949c28 --- /dev/null +++ b/libc/nt/ntdll/ZwTraceEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwTraceEvent diff --git a/libc/nt/ntdll/ZwTranslateFilePath.s b/libc/nt/ntdll/ZwTranslateFilePath.s new file mode 100644 index 00000000..9c135ff8 --- /dev/null +++ b/libc/nt/ntdll/ZwTranslateFilePath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwTranslateFilePath diff --git a/libc/nt/ntdll/ZwUmsThreadYield.s b/libc/nt/ntdll/ZwUmsThreadYield.s new file mode 100644 index 00000000..94cbcede --- /dev/null +++ b/libc/nt/ntdll/ZwUmsThreadYield.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwUmsThreadYield diff --git a/libc/nt/ntdll/ZwUnloadDriver.s b/libc/nt/ntdll/ZwUnloadDriver.s new file mode 100644 index 00000000..5b5e2d5b --- /dev/null +++ b/libc/nt/ntdll/ZwUnloadDriver.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwUnloadDriver diff --git a/libc/nt/ntdll/ZwUnloadKey.s b/libc/nt/ntdll/ZwUnloadKey.s new file mode 100644 index 00000000..c2fd38ff --- /dev/null +++ b/libc/nt/ntdll/ZwUnloadKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwUnloadKey diff --git a/libc/nt/ntdll/ZwUnloadKey2.s b/libc/nt/ntdll/ZwUnloadKey2.s new file mode 100644 index 00000000..d545ffde --- /dev/null +++ b/libc/nt/ntdll/ZwUnloadKey2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwUnloadKey2 diff --git a/libc/nt/ntdll/ZwUnloadKeyEx.s b/libc/nt/ntdll/ZwUnloadKeyEx.s new file mode 100644 index 00000000..281b7262 --- /dev/null +++ b/libc/nt/ntdll/ZwUnloadKeyEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwUnloadKeyEx diff --git a/libc/nt/ntdll/ZwUnlockFile.s b/libc/nt/ntdll/ZwUnlockFile.s new file mode 100644 index 00000000..a4491944 --- /dev/null +++ b/libc/nt/ntdll/ZwUnlockFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwUnlockFile diff --git a/libc/nt/ntdll/ZwUnlockVirtualMemory.s b/libc/nt/ntdll/ZwUnlockVirtualMemory.s new file mode 100644 index 00000000..f5f1d0c9 --- /dev/null +++ b/libc/nt/ntdll/ZwUnlockVirtualMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwUnlockVirtualMemory diff --git a/libc/nt/ntdll/ZwUnmapViewOfSection.s b/libc/nt/ntdll/ZwUnmapViewOfSection.s new file mode 100644 index 00000000..96d2ffa6 --- /dev/null +++ b/libc/nt/ntdll/ZwUnmapViewOfSection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwUnmapViewOfSection diff --git a/libc/nt/ntdll/ZwUnmapViewOfSectionEx.s b/libc/nt/ntdll/ZwUnmapViewOfSectionEx.s new file mode 100644 index 00000000..f967ad65 --- /dev/null +++ b/libc/nt/ntdll/ZwUnmapViewOfSectionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwUnmapViewOfSectionEx diff --git a/libc/nt/ntdll/ZwUnsubscribeWnfStateChange.s b/libc/nt/ntdll/ZwUnsubscribeWnfStateChange.s new file mode 100644 index 00000000..04143847 --- /dev/null +++ b/libc/nt/ntdll/ZwUnsubscribeWnfStateChange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwUnsubscribeWnfStateChange diff --git a/libc/nt/ntdll/ZwUpdateWnfStateData.s b/libc/nt/ntdll/ZwUpdateWnfStateData.s new file mode 100644 index 00000000..33b12b45 --- /dev/null +++ b/libc/nt/ntdll/ZwUpdateWnfStateData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwUpdateWnfStateData diff --git a/libc/nt/ntdll/ZwVdmControl.s b/libc/nt/ntdll/ZwVdmControl.s new file mode 100644 index 00000000..4d9bf117 --- /dev/null +++ b/libc/nt/ntdll/ZwVdmControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwVdmControl diff --git a/libc/nt/ntdll/ZwWaitForAlertByThreadId.s b/libc/nt/ntdll/ZwWaitForAlertByThreadId.s new file mode 100644 index 00000000..22b7e7de --- /dev/null +++ b/libc/nt/ntdll/ZwWaitForAlertByThreadId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwWaitForAlertByThreadId diff --git a/libc/nt/ntdll/ZwWaitForDebugEvent.s b/libc/nt/ntdll/ZwWaitForDebugEvent.s new file mode 100644 index 00000000..03ba24a4 --- /dev/null +++ b/libc/nt/ntdll/ZwWaitForDebugEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwWaitForDebugEvent diff --git a/libc/nt/ntdll/ZwWaitForKeyedEvent.s b/libc/nt/ntdll/ZwWaitForKeyedEvent.s new file mode 100644 index 00000000..936f66db --- /dev/null +++ b/libc/nt/ntdll/ZwWaitForKeyedEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwWaitForKeyedEvent diff --git a/libc/nt/ntdll/ZwWaitForMultipleObjects.s b/libc/nt/ntdll/ZwWaitForMultipleObjects.s new file mode 100644 index 00000000..9dc23d37 --- /dev/null +++ b/libc/nt/ntdll/ZwWaitForMultipleObjects.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwWaitForMultipleObjects diff --git a/libc/nt/ntdll/ZwWaitForMultipleObjects32.s b/libc/nt/ntdll/ZwWaitForMultipleObjects32.s new file mode 100644 index 00000000..59a749c7 --- /dev/null +++ b/libc/nt/ntdll/ZwWaitForMultipleObjects32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwWaitForMultipleObjects32 diff --git a/libc/nt/ntdll/ZwWaitForSingleObject.s b/libc/nt/ntdll/ZwWaitForSingleObject.s new file mode 100644 index 00000000..a9589950 --- /dev/null +++ b/libc/nt/ntdll/ZwWaitForSingleObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwWaitForSingleObject diff --git a/libc/nt/ntdll/ZwWaitForWorkViaWorkerFactory.s b/libc/nt/ntdll/ZwWaitForWorkViaWorkerFactory.s new file mode 100644 index 00000000..e8c99fde --- /dev/null +++ b/libc/nt/ntdll/ZwWaitForWorkViaWorkerFactory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwWaitForWorkViaWorkerFactory diff --git a/libc/nt/ntdll/ZwWaitHighEventPair.s b/libc/nt/ntdll/ZwWaitHighEventPair.s new file mode 100644 index 00000000..c73297c5 --- /dev/null +++ b/libc/nt/ntdll/ZwWaitHighEventPair.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwWaitHighEventPair diff --git a/libc/nt/ntdll/ZwWaitLowEventPair.s b/libc/nt/ntdll/ZwWaitLowEventPair.s new file mode 100644 index 00000000..adb5b25a --- /dev/null +++ b/libc/nt/ntdll/ZwWaitLowEventPair.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwWaitLowEventPair diff --git a/libc/nt/ntdll/ZwWorkerFactoryWorkerReady.s b/libc/nt/ntdll/ZwWorkerFactoryWorkerReady.s new file mode 100644 index 00000000..297a805c --- /dev/null +++ b/libc/nt/ntdll/ZwWorkerFactoryWorkerReady.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwWorkerFactoryWorkerReady diff --git a/libc/nt/ntdll/ZwWriteFile.s b/libc/nt/ntdll/ZwWriteFile.s new file mode 100644 index 00000000..53681391 --- /dev/null +++ b/libc/nt/ntdll/ZwWriteFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwWriteFile diff --git a/libc/nt/ntdll/ZwWriteFileGather.s b/libc/nt/ntdll/ZwWriteFileGather.s new file mode 100644 index 00000000..110c2579 --- /dev/null +++ b/libc/nt/ntdll/ZwWriteFileGather.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwWriteFileGather diff --git a/libc/nt/ntdll/ZwWriteRequestData.s b/libc/nt/ntdll/ZwWriteRequestData.s new file mode 100644 index 00000000..464ac7be --- /dev/null +++ b/libc/nt/ntdll/ZwWriteRequestData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwWriteRequestData diff --git a/libc/nt/ntdll/ZwWriteVirtualMemory.s b/libc/nt/ntdll/ZwWriteVirtualMemory.s new file mode 100644 index 00000000..471e52b4 --- /dev/null +++ b/libc/nt/ntdll/ZwWriteVirtualMemory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwWriteVirtualMemory diff --git a/libc/nt/ntdll/ZwYieldExecution.s b/libc/nt/ntdll/ZwYieldExecution.s new file mode 100644 index 00000000..da46b759 --- /dev/null +++ b/libc/nt/ntdll/ZwYieldExecution.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ZwYieldExecution diff --git a/libc/nt/ntdll/_atoi64.s b/libc/nt/ntdll/_atoi64.s new file mode 100644 index 00000000..627372f1 --- /dev/null +++ b/libc/nt/ntdll/_atoi64.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _atoi64 diff --git a/libc/nt/ntdll/_errno.s b/libc/nt/ntdll/_errno.s new file mode 100644 index 00000000..4b5180ad --- /dev/null +++ b/libc/nt/ntdll/_errno.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _errno diff --git a/libc/nt/ntdll/_fltused.s b/libc/nt/ntdll/_fltused.s new file mode 100644 index 00000000..c6e48447 --- /dev/null +++ b/libc/nt/ntdll/_fltused.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _fltused diff --git a/libc/nt/ntdll/_i64toa.s b/libc/nt/ntdll/_i64toa.s new file mode 100644 index 00000000..cd9c8277 --- /dev/null +++ b/libc/nt/ntdll/_i64toa.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _i64toa diff --git a/libc/nt/ntdll/_i64toa_s.s b/libc/nt/ntdll/_i64toa_s.s new file mode 100644 index 00000000..3e160227 --- /dev/null +++ b/libc/nt/ntdll/_i64toa_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _i64toa_s diff --git a/libc/nt/ntdll/_i64tow.s b/libc/nt/ntdll/_i64tow.s new file mode 100644 index 00000000..af09db1b --- /dev/null +++ b/libc/nt/ntdll/_i64tow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _i64tow diff --git a/libc/nt/ntdll/_i64tow_s.s b/libc/nt/ntdll/_i64tow_s.s new file mode 100644 index 00000000..8436028a --- /dev/null +++ b/libc/nt/ntdll/_i64tow_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _i64tow_s diff --git a/libc/nt/ntdll/_itoa.s b/libc/nt/ntdll/_itoa.s new file mode 100644 index 00000000..d5acc31d --- /dev/null +++ b/libc/nt/ntdll/_itoa.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _itoa diff --git a/libc/nt/ntdll/_itoa_s.s b/libc/nt/ntdll/_itoa_s.s new file mode 100644 index 00000000..f8147967 --- /dev/null +++ b/libc/nt/ntdll/_itoa_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _itoa_s diff --git a/libc/nt/ntdll/_itow.s b/libc/nt/ntdll/_itow.s new file mode 100644 index 00000000..b03576f2 --- /dev/null +++ b/libc/nt/ntdll/_itow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _itow diff --git a/libc/nt/ntdll/_itow_s.s b/libc/nt/ntdll/_itow_s.s new file mode 100644 index 00000000..1d497c0c --- /dev/null +++ b/libc/nt/ntdll/_itow_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _itow_s diff --git a/libc/nt/ntdll/_lfind.s b/libc/nt/ntdll/_lfind.s new file mode 100644 index 00000000..e3560716 --- /dev/null +++ b/libc/nt/ntdll/_lfind.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _lfind diff --git a/libc/nt/ntdll/_local_unwind.s b/libc/nt/ntdll/_local_unwind.s new file mode 100644 index 00000000..62016943 --- /dev/null +++ b/libc/nt/ntdll/_local_unwind.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _local_unwind diff --git a/libc/nt/ntdll/_ltoa.s b/libc/nt/ntdll/_ltoa.s new file mode 100644 index 00000000..5e4720ff --- /dev/null +++ b/libc/nt/ntdll/_ltoa.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _ltoa diff --git a/libc/nt/ntdll/_ltoa_s.s b/libc/nt/ntdll/_ltoa_s.s new file mode 100644 index 00000000..4e8d6e15 --- /dev/null +++ b/libc/nt/ntdll/_ltoa_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _ltoa_s diff --git a/libc/nt/ntdll/_ltow.s b/libc/nt/ntdll/_ltow.s new file mode 100644 index 00000000..c652c26f --- /dev/null +++ b/libc/nt/ntdll/_ltow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _ltow diff --git a/libc/nt/ntdll/_ltow_s.s b/libc/nt/ntdll/_ltow_s.s new file mode 100644 index 00000000..bf077f47 --- /dev/null +++ b/libc/nt/ntdll/_ltow_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _ltow_s diff --git a/libc/nt/ntdll/_makepath_s.s b/libc/nt/ntdll/_makepath_s.s new file mode 100644 index 00000000..1ac6a4d2 --- /dev/null +++ b/libc/nt/ntdll/_makepath_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _makepath_s diff --git a/libc/nt/ntdll/_memccpy.s b/libc/nt/ntdll/_memccpy.s new file mode 100644 index 00000000..9d5ee9d4 --- /dev/null +++ b/libc/nt/ntdll/_memccpy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _memccpy diff --git a/libc/nt/ntdll/_memicmp.s b/libc/nt/ntdll/_memicmp.s new file mode 100644 index 00000000..26ee4f9a --- /dev/null +++ b/libc/nt/ntdll/_memicmp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _memicmp diff --git a/libc/nt/ntdll/_setjmp.s b/libc/nt/ntdll/_setjmp.s new file mode 100644 index 00000000..0d191e1b --- /dev/null +++ b/libc/nt/ntdll/_setjmp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _setjmp diff --git a/libc/nt/ntdll/_setjmpex.s b/libc/nt/ntdll/_setjmpex.s new file mode 100644 index 00000000..4a10e386 --- /dev/null +++ b/libc/nt/ntdll/_setjmpex.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _setjmpex diff --git a/libc/nt/ntdll/_snprintf.s b/libc/nt/ntdll/_snprintf.s new file mode 100644 index 00000000..9c4f2e0e --- /dev/null +++ b/libc/nt/ntdll/_snprintf.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _snprintf diff --git a/libc/nt/ntdll/_snprintf_s.s b/libc/nt/ntdll/_snprintf_s.s new file mode 100644 index 00000000..e0db5792 --- /dev/null +++ b/libc/nt/ntdll/_snprintf_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _snprintf_s diff --git a/libc/nt/ntdll/_snscanf_s.s b/libc/nt/ntdll/_snscanf_s.s new file mode 100644 index 00000000..0dc68773 --- /dev/null +++ b/libc/nt/ntdll/_snscanf_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _snscanf_s diff --git a/libc/nt/ntdll/_snwprintf.s b/libc/nt/ntdll/_snwprintf.s new file mode 100644 index 00000000..6d250cce --- /dev/null +++ b/libc/nt/ntdll/_snwprintf.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _snwprintf diff --git a/libc/nt/ntdll/_snwprintf_s.s b/libc/nt/ntdll/_snwprintf_s.s new file mode 100644 index 00000000..8b0c7be7 --- /dev/null +++ b/libc/nt/ntdll/_snwprintf_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _snwprintf_s diff --git a/libc/nt/ntdll/_snwscanf_s.s b/libc/nt/ntdll/_snwscanf_s.s new file mode 100644 index 00000000..805bbbf3 --- /dev/null +++ b/libc/nt/ntdll/_snwscanf_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _snwscanf_s diff --git a/libc/nt/ntdll/_splitpath.s b/libc/nt/ntdll/_splitpath.s new file mode 100644 index 00000000..f353e3ac --- /dev/null +++ b/libc/nt/ntdll/_splitpath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _splitpath diff --git a/libc/nt/ntdll/_splitpath_s.s b/libc/nt/ntdll/_splitpath_s.s new file mode 100644 index 00000000..eddcea76 --- /dev/null +++ b/libc/nt/ntdll/_splitpath_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _splitpath_s diff --git a/libc/nt/ntdll/_strcmpi.s b/libc/nt/ntdll/_strcmpi.s new file mode 100644 index 00000000..9c11325b --- /dev/null +++ b/libc/nt/ntdll/_strcmpi.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _strcmpi diff --git a/libc/nt/ntdll/_stricmp.s b/libc/nt/ntdll/_stricmp.s new file mode 100644 index 00000000..e32e57cc --- /dev/null +++ b/libc/nt/ntdll/_stricmp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _stricmp diff --git a/libc/nt/ntdll/_strlwr.s b/libc/nt/ntdll/_strlwr.s new file mode 100644 index 00000000..55b948b0 --- /dev/null +++ b/libc/nt/ntdll/_strlwr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _strlwr diff --git a/libc/nt/ntdll/_strlwr_s.s b/libc/nt/ntdll/_strlwr_s.s new file mode 100644 index 00000000..e5a58c1f --- /dev/null +++ b/libc/nt/ntdll/_strlwr_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _strlwr_s diff --git a/libc/nt/ntdll/_strnicmp.s b/libc/nt/ntdll/_strnicmp.s new file mode 100644 index 00000000..739a724f --- /dev/null +++ b/libc/nt/ntdll/_strnicmp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _strnicmp diff --git a/libc/nt/ntdll/_strnset_s.s b/libc/nt/ntdll/_strnset_s.s new file mode 100644 index 00000000..c3425d0f --- /dev/null +++ b/libc/nt/ntdll/_strnset_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _strnset_s diff --git a/libc/nt/ntdll/_strset_s.s b/libc/nt/ntdll/_strset_s.s new file mode 100644 index 00000000..27478a75 --- /dev/null +++ b/libc/nt/ntdll/_strset_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _strset_s diff --git a/libc/nt/ntdll/_strupr.s b/libc/nt/ntdll/_strupr.s new file mode 100644 index 00000000..618424b7 --- /dev/null +++ b/libc/nt/ntdll/_strupr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _strupr diff --git a/libc/nt/ntdll/_strupr_s.s b/libc/nt/ntdll/_strupr_s.s new file mode 100644 index 00000000..e3f3b110 --- /dev/null +++ b/libc/nt/ntdll/_strupr_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _strupr_s diff --git a/libc/nt/ntdll/_swprintf.s b/libc/nt/ntdll/_swprintf.s new file mode 100644 index 00000000..c4e629b5 --- /dev/null +++ b/libc/nt/ntdll/_swprintf.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _swprintf diff --git a/libc/nt/ntdll/_ui64toa.s b/libc/nt/ntdll/_ui64toa.s new file mode 100644 index 00000000..2f3a46f2 --- /dev/null +++ b/libc/nt/ntdll/_ui64toa.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _ui64toa diff --git a/libc/nt/ntdll/_ui64toa_s.s b/libc/nt/ntdll/_ui64toa_s.s new file mode 100644 index 00000000..4125819b --- /dev/null +++ b/libc/nt/ntdll/_ui64toa_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _ui64toa_s diff --git a/libc/nt/ntdll/_ui64tow.s b/libc/nt/ntdll/_ui64tow.s new file mode 100644 index 00000000..fb18658e --- /dev/null +++ b/libc/nt/ntdll/_ui64tow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _ui64tow diff --git a/libc/nt/ntdll/_ui64tow_s.s b/libc/nt/ntdll/_ui64tow_s.s new file mode 100644 index 00000000..d287e98b --- /dev/null +++ b/libc/nt/ntdll/_ui64tow_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _ui64tow_s diff --git a/libc/nt/ntdll/_ultoa.s b/libc/nt/ntdll/_ultoa.s new file mode 100644 index 00000000..55bae46d --- /dev/null +++ b/libc/nt/ntdll/_ultoa.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _ultoa diff --git a/libc/nt/ntdll/_ultoa_s.s b/libc/nt/ntdll/_ultoa_s.s new file mode 100644 index 00000000..c2206e60 --- /dev/null +++ b/libc/nt/ntdll/_ultoa_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _ultoa_s diff --git a/libc/nt/ntdll/_ultow.s b/libc/nt/ntdll/_ultow.s new file mode 100644 index 00000000..9299dffc --- /dev/null +++ b/libc/nt/ntdll/_ultow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _ultow diff --git a/libc/nt/ntdll/_ultow_s.s b/libc/nt/ntdll/_ultow_s.s new file mode 100644 index 00000000..8092cf55 --- /dev/null +++ b/libc/nt/ntdll/_ultow_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _ultow_s diff --git a/libc/nt/ntdll/_vscprintf.s b/libc/nt/ntdll/_vscprintf.s new file mode 100644 index 00000000..6c8643c7 --- /dev/null +++ b/libc/nt/ntdll/_vscprintf.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _vscprintf diff --git a/libc/nt/ntdll/_vscwprintf.s b/libc/nt/ntdll/_vscwprintf.s new file mode 100644 index 00000000..c55d727f --- /dev/null +++ b/libc/nt/ntdll/_vscwprintf.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _vscwprintf diff --git a/libc/nt/ntdll/_vsnprintf.s b/libc/nt/ntdll/_vsnprintf.s new file mode 100644 index 00000000..f4ef3825 --- /dev/null +++ b/libc/nt/ntdll/_vsnprintf.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _vsnprintf diff --git a/libc/nt/ntdll/_vsnprintf_s.s b/libc/nt/ntdll/_vsnprintf_s.s new file mode 100644 index 00000000..921ff598 --- /dev/null +++ b/libc/nt/ntdll/_vsnprintf_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _vsnprintf_s diff --git a/libc/nt/ntdll/_vsnwprintf.s b/libc/nt/ntdll/_vsnwprintf.s new file mode 100644 index 00000000..ae82c6a4 --- /dev/null +++ b/libc/nt/ntdll/_vsnwprintf.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _vsnwprintf diff --git a/libc/nt/ntdll/_vsnwprintf_s.s b/libc/nt/ntdll/_vsnwprintf_s.s new file mode 100644 index 00000000..5024b7de --- /dev/null +++ b/libc/nt/ntdll/_vsnwprintf_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _vsnwprintf_s diff --git a/libc/nt/ntdll/_vswprintf.s b/libc/nt/ntdll/_vswprintf.s new file mode 100644 index 00000000..3dc1c8ed --- /dev/null +++ b/libc/nt/ntdll/_vswprintf.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _vswprintf diff --git a/libc/nt/ntdll/_wcsicmp.s b/libc/nt/ntdll/_wcsicmp.s new file mode 100644 index 00000000..b9187e0d --- /dev/null +++ b/libc/nt/ntdll/_wcsicmp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _wcsicmp diff --git a/libc/nt/ntdll/_wcslwr.s b/libc/nt/ntdll/_wcslwr.s new file mode 100644 index 00000000..5446d978 --- /dev/null +++ b/libc/nt/ntdll/_wcslwr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _wcslwr diff --git a/libc/nt/ntdll/_wcslwr_s.s b/libc/nt/ntdll/_wcslwr_s.s new file mode 100644 index 00000000..b7171b0f --- /dev/null +++ b/libc/nt/ntdll/_wcslwr_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _wcslwr_s diff --git a/libc/nt/ntdll/_wcsnicmp.s b/libc/nt/ntdll/_wcsnicmp.s new file mode 100644 index 00000000..f65f0e4c --- /dev/null +++ b/libc/nt/ntdll/_wcsnicmp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _wcsnicmp diff --git a/libc/nt/ntdll/_wcsnset_s.s b/libc/nt/ntdll/_wcsnset_s.s new file mode 100644 index 00000000..f564b2db --- /dev/null +++ b/libc/nt/ntdll/_wcsnset_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _wcsnset_s diff --git a/libc/nt/ntdll/_wcsset_s.s b/libc/nt/ntdll/_wcsset_s.s new file mode 100644 index 00000000..e8da96d4 --- /dev/null +++ b/libc/nt/ntdll/_wcsset_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _wcsset_s diff --git a/libc/nt/ntdll/_wcstoi64.s b/libc/nt/ntdll/_wcstoi64.s new file mode 100644 index 00000000..52f9f7a4 --- /dev/null +++ b/libc/nt/ntdll/_wcstoi64.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _wcstoi64 diff --git a/libc/nt/ntdll/_wcstoui64.s b/libc/nt/ntdll/_wcstoui64.s new file mode 100644 index 00000000..16e68277 --- /dev/null +++ b/libc/nt/ntdll/_wcstoui64.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _wcstoui64 diff --git a/libc/nt/ntdll/_wcsupr.s b/libc/nt/ntdll/_wcsupr.s new file mode 100644 index 00000000..84e916e9 --- /dev/null +++ b/libc/nt/ntdll/_wcsupr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _wcsupr diff --git a/libc/nt/ntdll/_wcsupr_s.s b/libc/nt/ntdll/_wcsupr_s.s new file mode 100644 index 00000000..a334fd7f --- /dev/null +++ b/libc/nt/ntdll/_wcsupr_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _wcsupr_s diff --git a/libc/nt/ntdll/_wmakepath_s.s b/libc/nt/ntdll/_wmakepath_s.s new file mode 100644 index 00000000..b7c7a87c --- /dev/null +++ b/libc/nt/ntdll/_wmakepath_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _wmakepath_s diff --git a/libc/nt/ntdll/_wsplitpath_s.s b/libc/nt/ntdll/_wsplitpath_s.s new file mode 100644 index 00000000..6c3f5c7f --- /dev/null +++ b/libc/nt/ntdll/_wsplitpath_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _wsplitpath_s diff --git a/libc/nt/ntdll/_wtoi.s b/libc/nt/ntdll/_wtoi.s new file mode 100644 index 00000000..ee6b579d --- /dev/null +++ b/libc/nt/ntdll/_wtoi.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _wtoi diff --git a/libc/nt/ntdll/_wtoi64.s b/libc/nt/ntdll/_wtoi64.s new file mode 100644 index 00000000..11b722b3 --- /dev/null +++ b/libc/nt/ntdll/_wtoi64.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _wtoi64 diff --git a/libc/nt/ntdll/_wtol.s b/libc/nt/ntdll/_wtol.s new file mode 100644 index 00000000..5e313f73 --- /dev/null +++ b/libc/nt/ntdll/_wtol.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp _wtol diff --git a/libc/nt/ntdll/abs.s b/libc/nt/ntdll/abs.s new file mode 100644 index 00000000..e35980ba --- /dev/null +++ b/libc/nt/ntdll/abs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp abs diff --git a/libc/nt/ntdll/atan.s b/libc/nt/ntdll/atan.s new file mode 100644 index 00000000..cbc1e6d9 --- /dev/null +++ b/libc/nt/ntdll/atan.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp atan diff --git a/libc/nt/ntdll/atan2.s b/libc/nt/ntdll/atan2.s new file mode 100644 index 00000000..7034bfea --- /dev/null +++ b/libc/nt/ntdll/atan2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp atan2 diff --git a/libc/nt/ntdll/atoi.s b/libc/nt/ntdll/atoi.s new file mode 100644 index 00000000..7f018c96 --- /dev/null +++ b/libc/nt/ntdll/atoi.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp atoi diff --git a/libc/nt/ntdll/atol.s b/libc/nt/ntdll/atol.s new file mode 100644 index 00000000..7f62fd42 --- /dev/null +++ b/libc/nt/ntdll/atol.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp atol diff --git a/libc/nt/ntdll/bsearch.s b/libc/nt/ntdll/bsearch.s new file mode 100644 index 00000000..088ef2b1 --- /dev/null +++ b/libc/nt/ntdll/bsearch.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp bsearch diff --git a/libc/nt/ntdll/bsearch_s.s b/libc/nt/ntdll/bsearch_s.s new file mode 100644 index 00000000..807cf55c --- /dev/null +++ b/libc/nt/ntdll/bsearch_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp bsearch_s diff --git a/libc/nt/ntdll/ceil.s b/libc/nt/ntdll/ceil.s new file mode 100644 index 00000000..3620a156 --- /dev/null +++ b/libc/nt/ntdll/ceil.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ceil diff --git a/libc/nt/ntdll/cos.s b/libc/nt/ntdll/cos.s new file mode 100644 index 00000000..2a4c2055 --- /dev/null +++ b/libc/nt/ntdll/cos.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp cos diff --git a/libc/nt/ntdll/fabs.s b/libc/nt/ntdll/fabs.s new file mode 100644 index 00000000..b36fb18e --- /dev/null +++ b/libc/nt/ntdll/fabs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp fabs diff --git a/libc/nt/ntdll/floor.s b/libc/nt/ntdll/floor.s new file mode 100644 index 00000000..26f5229a --- /dev/null +++ b/libc/nt/ntdll/floor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp floor diff --git a/libc/nt/ntdll/isalnum.s b/libc/nt/ntdll/isalnum.s new file mode 100644 index 00000000..04d202ca --- /dev/null +++ b/libc/nt/ntdll/isalnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp isalnum diff --git a/libc/nt/ntdll/isalpha.s b/libc/nt/ntdll/isalpha.s new file mode 100644 index 00000000..afc7608e --- /dev/null +++ b/libc/nt/ntdll/isalpha.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp isalpha diff --git a/libc/nt/ntdll/iscntrl.s b/libc/nt/ntdll/iscntrl.s new file mode 100644 index 00000000..72f4a3da --- /dev/null +++ b/libc/nt/ntdll/iscntrl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp iscntrl diff --git a/libc/nt/ntdll/isdigit.s b/libc/nt/ntdll/isdigit.s new file mode 100644 index 00000000..0eab8659 --- /dev/null +++ b/libc/nt/ntdll/isdigit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp isdigit diff --git a/libc/nt/ntdll/isgraph.s b/libc/nt/ntdll/isgraph.s new file mode 100644 index 00000000..57fcd7b5 --- /dev/null +++ b/libc/nt/ntdll/isgraph.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp isgraph diff --git a/libc/nt/ntdll/islower.s b/libc/nt/ntdll/islower.s new file mode 100644 index 00000000..bf1a7745 --- /dev/null +++ b/libc/nt/ntdll/islower.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp islower diff --git a/libc/nt/ntdll/isprint.s b/libc/nt/ntdll/isprint.s new file mode 100644 index 00000000..bc6eaee3 --- /dev/null +++ b/libc/nt/ntdll/isprint.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp isprint diff --git a/libc/nt/ntdll/ispunct.s b/libc/nt/ntdll/ispunct.s new file mode 100644 index 00000000..a772c0ac --- /dev/null +++ b/libc/nt/ntdll/ispunct.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp ispunct diff --git a/libc/nt/ntdll/isspace.s b/libc/nt/ntdll/isspace.s new file mode 100644 index 00000000..0668588d --- /dev/null +++ b/libc/nt/ntdll/isspace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp isspace diff --git a/libc/nt/ntdll/isupper.s b/libc/nt/ntdll/isupper.s new file mode 100644 index 00000000..98b5b1ab --- /dev/null +++ b/libc/nt/ntdll/isupper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp isupper diff --git a/libc/nt/ntdll/iswalnum.s b/libc/nt/ntdll/iswalnum.s new file mode 100644 index 00000000..30416e3f --- /dev/null +++ b/libc/nt/ntdll/iswalnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp iswalnum diff --git a/libc/nt/ntdll/iswalpha.s b/libc/nt/ntdll/iswalpha.s new file mode 100644 index 00000000..4303e716 --- /dev/null +++ b/libc/nt/ntdll/iswalpha.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp iswalpha diff --git a/libc/nt/ntdll/iswascii.s b/libc/nt/ntdll/iswascii.s new file mode 100644 index 00000000..ca5a3b87 --- /dev/null +++ b/libc/nt/ntdll/iswascii.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp iswascii diff --git a/libc/nt/ntdll/iswctype.s b/libc/nt/ntdll/iswctype.s new file mode 100644 index 00000000..96d43c62 --- /dev/null +++ b/libc/nt/ntdll/iswctype.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp iswctype diff --git a/libc/nt/ntdll/iswdigit.s b/libc/nt/ntdll/iswdigit.s new file mode 100644 index 00000000..8333385e --- /dev/null +++ b/libc/nt/ntdll/iswdigit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp iswdigit diff --git a/libc/nt/ntdll/iswgraph.s b/libc/nt/ntdll/iswgraph.s new file mode 100644 index 00000000..a9ef4d9c --- /dev/null +++ b/libc/nt/ntdll/iswgraph.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp iswgraph diff --git a/libc/nt/ntdll/iswlower.s b/libc/nt/ntdll/iswlower.s new file mode 100644 index 00000000..11b333e7 --- /dev/null +++ b/libc/nt/ntdll/iswlower.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp iswlower diff --git a/libc/nt/ntdll/iswprint.s b/libc/nt/ntdll/iswprint.s new file mode 100644 index 00000000..254cd09a --- /dev/null +++ b/libc/nt/ntdll/iswprint.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp iswprint diff --git a/libc/nt/ntdll/iswspace.s b/libc/nt/ntdll/iswspace.s new file mode 100644 index 00000000..cd424bb9 --- /dev/null +++ b/libc/nt/ntdll/iswspace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp iswspace diff --git a/libc/nt/ntdll/iswxdigit.s b/libc/nt/ntdll/iswxdigit.s new file mode 100644 index 00000000..96409f8a --- /dev/null +++ b/libc/nt/ntdll/iswxdigit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp iswxdigit diff --git a/libc/nt/ntdll/isxdigit.s b/libc/nt/ntdll/isxdigit.s new file mode 100644 index 00000000..955b9625 --- /dev/null +++ b/libc/nt/ntdll/isxdigit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp isxdigit diff --git a/libc/nt/ntdll/labs.s b/libc/nt/ntdll/labs.s new file mode 100644 index 00000000..f2abdb42 --- /dev/null +++ b/libc/nt/ntdll/labs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp labs diff --git a/libc/nt/ntdll/log.s b/libc/nt/ntdll/log.s new file mode 100644 index 00000000..0a2e2c13 --- /dev/null +++ b/libc/nt/ntdll/log.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp log diff --git a/libc/nt/ntdll/longjmp.s b/libc/nt/ntdll/longjmp.s new file mode 100644 index 00000000..cd225e25 --- /dev/null +++ b/libc/nt/ntdll/longjmp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp longjmp diff --git a/libc/nt/ntdll/mbstowcs.s b/libc/nt/ntdll/mbstowcs.s new file mode 100644 index 00000000..7e6f30ab --- /dev/null +++ b/libc/nt/ntdll/mbstowcs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp mbstowcs diff --git a/libc/nt/ntdll/memchr.s b/libc/nt/ntdll/memchr.s new file mode 100644 index 00000000..ce56543c --- /dev/null +++ b/libc/nt/ntdll/memchr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp memchr diff --git a/libc/nt/ntdll/memcmp.s b/libc/nt/ntdll/memcmp.s new file mode 100644 index 00000000..0d655958 --- /dev/null +++ b/libc/nt/ntdll/memcmp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp memcmp diff --git a/libc/nt/ntdll/memcpy.s b/libc/nt/ntdll/memcpy.s new file mode 100644 index 00000000..42542b3e --- /dev/null +++ b/libc/nt/ntdll/memcpy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp memcpy diff --git a/libc/nt/ntdll/memcpy_s.s b/libc/nt/ntdll/memcpy_s.s new file mode 100644 index 00000000..35f1ea68 --- /dev/null +++ b/libc/nt/ntdll/memcpy_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp memcpy_s diff --git a/libc/nt/ntdll/memmove.s b/libc/nt/ntdll/memmove.s new file mode 100644 index 00000000..3b9da693 --- /dev/null +++ b/libc/nt/ntdll/memmove.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp memmove diff --git a/libc/nt/ntdll/memmove_s.s b/libc/nt/ntdll/memmove_s.s new file mode 100644 index 00000000..6492335a --- /dev/null +++ b/libc/nt/ntdll/memmove_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp memmove_s diff --git a/libc/nt/ntdll/memset.s b/libc/nt/ntdll/memset.s new file mode 100644 index 00000000..0bd1ea33 --- /dev/null +++ b/libc/nt/ntdll/memset.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp memset diff --git a/libc/nt/ntdll/pow.s b/libc/nt/ntdll/pow.s new file mode 100644 index 00000000..386f2ec7 --- /dev/null +++ b/libc/nt/ntdll/pow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp pow diff --git a/libc/nt/ntdll/qsort.s b/libc/nt/ntdll/qsort.s new file mode 100644 index 00000000..9fe292cf --- /dev/null +++ b/libc/nt/ntdll/qsort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp qsort diff --git a/libc/nt/ntdll/qsort_s.s b/libc/nt/ntdll/qsort_s.s new file mode 100644 index 00000000..b4395226 --- /dev/null +++ b/libc/nt/ntdll/qsort_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp qsort_s diff --git a/libc/nt/ntdll/sin.s b/libc/nt/ntdll/sin.s new file mode 100644 index 00000000..4e5d229f --- /dev/null +++ b/libc/nt/ntdll/sin.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp sin diff --git a/libc/nt/ntdll/sprintf.s b/libc/nt/ntdll/sprintf.s new file mode 100644 index 00000000..ec2ac1cd --- /dev/null +++ b/libc/nt/ntdll/sprintf.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp sprintf diff --git a/libc/nt/ntdll/sprintf_s.s b/libc/nt/ntdll/sprintf_s.s new file mode 100644 index 00000000..b500799e --- /dev/null +++ b/libc/nt/ntdll/sprintf_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp sprintf_s diff --git a/libc/nt/ntdll/sqrt.s b/libc/nt/ntdll/sqrt.s new file mode 100644 index 00000000..ab0cabd5 --- /dev/null +++ b/libc/nt/ntdll/sqrt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp sqrt diff --git a/libc/nt/ntdll/sscanf.s b/libc/nt/ntdll/sscanf.s new file mode 100644 index 00000000..31e921f6 --- /dev/null +++ b/libc/nt/ntdll/sscanf.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp sscanf diff --git a/libc/nt/ntdll/sscanf_s.s b/libc/nt/ntdll/sscanf_s.s new file mode 100644 index 00000000..5ccd0c87 --- /dev/null +++ b/libc/nt/ntdll/sscanf_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp sscanf_s diff --git a/libc/nt/ntdll/strcat.s b/libc/nt/ntdll/strcat.s new file mode 100644 index 00000000..9030d154 --- /dev/null +++ b/libc/nt/ntdll/strcat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strcat diff --git a/libc/nt/ntdll/strcat_s.s b/libc/nt/ntdll/strcat_s.s new file mode 100644 index 00000000..51950759 --- /dev/null +++ b/libc/nt/ntdll/strcat_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strcat_s diff --git a/libc/nt/ntdll/strchr.s b/libc/nt/ntdll/strchr.s new file mode 100644 index 00000000..148957c2 --- /dev/null +++ b/libc/nt/ntdll/strchr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strchr diff --git a/libc/nt/ntdll/strcmp.s b/libc/nt/ntdll/strcmp.s new file mode 100644 index 00000000..8c9c1240 --- /dev/null +++ b/libc/nt/ntdll/strcmp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strcmp diff --git a/libc/nt/ntdll/strcpy.s b/libc/nt/ntdll/strcpy.s new file mode 100644 index 00000000..2b15bf99 --- /dev/null +++ b/libc/nt/ntdll/strcpy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strcpy diff --git a/libc/nt/ntdll/strcpy_s.s b/libc/nt/ntdll/strcpy_s.s new file mode 100644 index 00000000..ee06532c --- /dev/null +++ b/libc/nt/ntdll/strcpy_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strcpy_s diff --git a/libc/nt/ntdll/strcspn.s b/libc/nt/ntdll/strcspn.s new file mode 100644 index 00000000..1e50f15b --- /dev/null +++ b/libc/nt/ntdll/strcspn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strcspn diff --git a/libc/nt/ntdll/strlen.s b/libc/nt/ntdll/strlen.s new file mode 100644 index 00000000..93552928 --- /dev/null +++ b/libc/nt/ntdll/strlen.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strlen diff --git a/libc/nt/ntdll/strncat.s b/libc/nt/ntdll/strncat.s new file mode 100644 index 00000000..acc90be9 --- /dev/null +++ b/libc/nt/ntdll/strncat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strncat diff --git a/libc/nt/ntdll/strncat_s.s b/libc/nt/ntdll/strncat_s.s new file mode 100644 index 00000000..8407a966 --- /dev/null +++ b/libc/nt/ntdll/strncat_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strncat_s diff --git a/libc/nt/ntdll/strncmp.s b/libc/nt/ntdll/strncmp.s new file mode 100644 index 00000000..220f1195 --- /dev/null +++ b/libc/nt/ntdll/strncmp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strncmp diff --git a/libc/nt/ntdll/strncpy.s b/libc/nt/ntdll/strncpy.s new file mode 100644 index 00000000..b8ebdc03 --- /dev/null +++ b/libc/nt/ntdll/strncpy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strncpy diff --git a/libc/nt/ntdll/strncpy_s.s b/libc/nt/ntdll/strncpy_s.s new file mode 100644 index 00000000..33fa1d17 --- /dev/null +++ b/libc/nt/ntdll/strncpy_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strncpy_s diff --git a/libc/nt/ntdll/strnlen.s b/libc/nt/ntdll/strnlen.s new file mode 100644 index 00000000..a6ea8ef6 --- /dev/null +++ b/libc/nt/ntdll/strnlen.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strnlen diff --git a/libc/nt/ntdll/strpbrk.s b/libc/nt/ntdll/strpbrk.s new file mode 100644 index 00000000..28f7cd02 --- /dev/null +++ b/libc/nt/ntdll/strpbrk.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strpbrk diff --git a/libc/nt/ntdll/strrchr.s b/libc/nt/ntdll/strrchr.s new file mode 100644 index 00000000..3c407175 --- /dev/null +++ b/libc/nt/ntdll/strrchr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strrchr diff --git a/libc/nt/ntdll/strspn.s b/libc/nt/ntdll/strspn.s new file mode 100644 index 00000000..893c0112 --- /dev/null +++ b/libc/nt/ntdll/strspn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strspn diff --git a/libc/nt/ntdll/strstr.s b/libc/nt/ntdll/strstr.s new file mode 100644 index 00000000..32696bac --- /dev/null +++ b/libc/nt/ntdll/strstr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strstr diff --git a/libc/nt/ntdll/strtok_s.s b/libc/nt/ntdll/strtok_s.s new file mode 100644 index 00000000..f8a8b9e4 --- /dev/null +++ b/libc/nt/ntdll/strtok_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strtok_s diff --git a/libc/nt/ntdll/strtol.s b/libc/nt/ntdll/strtol.s new file mode 100644 index 00000000..70e5b862 --- /dev/null +++ b/libc/nt/ntdll/strtol.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strtol diff --git a/libc/nt/ntdll/strtoul.s b/libc/nt/ntdll/strtoul.s new file mode 100644 index 00000000..0e4ae1ec --- /dev/null +++ b/libc/nt/ntdll/strtoul.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp strtoul diff --git a/libc/nt/ntdll/swprintf.s b/libc/nt/ntdll/swprintf.s new file mode 100644 index 00000000..a80315eb --- /dev/null +++ b/libc/nt/ntdll/swprintf.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp swprintf diff --git a/libc/nt/ntdll/swprintf_s.s b/libc/nt/ntdll/swprintf_s.s new file mode 100644 index 00000000..095ad94f --- /dev/null +++ b/libc/nt/ntdll/swprintf_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp swprintf_s diff --git a/libc/nt/ntdll/swscanf_s.s b/libc/nt/ntdll/swscanf_s.s new file mode 100644 index 00000000..78e3e9a0 --- /dev/null +++ b/libc/nt/ntdll/swscanf_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp swscanf_s diff --git a/libc/nt/ntdll/tan.s b/libc/nt/ntdll/tan.s new file mode 100644 index 00000000..8441ce1a --- /dev/null +++ b/libc/nt/ntdll/tan.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp tan diff --git a/libc/nt/ntdll/tolower.s b/libc/nt/ntdll/tolower.s new file mode 100644 index 00000000..745a39a3 --- /dev/null +++ b/libc/nt/ntdll/tolower.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp tolower diff --git a/libc/nt/ntdll/toupper.s b/libc/nt/ntdll/toupper.s new file mode 100644 index 00000000..b7f2f145 --- /dev/null +++ b/libc/nt/ntdll/toupper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp toupper diff --git a/libc/nt/ntdll/towlower.s b/libc/nt/ntdll/towlower.s new file mode 100644 index 00000000..ba462a67 --- /dev/null +++ b/libc/nt/ntdll/towlower.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp towlower diff --git a/libc/nt/ntdll/towupper.s b/libc/nt/ntdll/towupper.s new file mode 100644 index 00000000..8c066c6e --- /dev/null +++ b/libc/nt/ntdll/towupper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp towupper diff --git a/libc/nt/ntdll/vDbgPrintEx.s b/libc/nt/ntdll/vDbgPrintEx.s new file mode 100644 index 00000000..60b39544 --- /dev/null +++ b/libc/nt/ntdll/vDbgPrintEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp vDbgPrintEx diff --git a/libc/nt/ntdll/vDbgPrintExWithPrefix.s b/libc/nt/ntdll/vDbgPrintExWithPrefix.s new file mode 100644 index 00000000..1222cbd2 --- /dev/null +++ b/libc/nt/ntdll/vDbgPrintExWithPrefix.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp vDbgPrintExWithPrefix diff --git a/libc/nt/ntdll/vsprintf.s b/libc/nt/ntdll/vsprintf.s new file mode 100644 index 00000000..514c9909 --- /dev/null +++ b/libc/nt/ntdll/vsprintf.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp vsprintf diff --git a/libc/nt/ntdll/vsprintf_s.s b/libc/nt/ntdll/vsprintf_s.s new file mode 100644 index 00000000..d29daf33 --- /dev/null +++ b/libc/nt/ntdll/vsprintf_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp vsprintf_s diff --git a/libc/nt/ntdll/vswprintf_s.s b/libc/nt/ntdll/vswprintf_s.s new file mode 100644 index 00000000..2a1f9b33 --- /dev/null +++ b/libc/nt/ntdll/vswprintf_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp vswprintf_s diff --git a/libc/nt/ntdll/wcscat.s b/libc/nt/ntdll/wcscat.s new file mode 100644 index 00000000..47b7e318 --- /dev/null +++ b/libc/nt/ntdll/wcscat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcscat diff --git a/libc/nt/ntdll/wcscat_s.s b/libc/nt/ntdll/wcscat_s.s new file mode 100644 index 00000000..0774f637 --- /dev/null +++ b/libc/nt/ntdll/wcscat_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcscat_s diff --git a/libc/nt/ntdll/wcschr.s b/libc/nt/ntdll/wcschr.s new file mode 100644 index 00000000..65441f19 --- /dev/null +++ b/libc/nt/ntdll/wcschr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcschr diff --git a/libc/nt/ntdll/wcscmp.s b/libc/nt/ntdll/wcscmp.s new file mode 100644 index 00000000..24947caa --- /dev/null +++ b/libc/nt/ntdll/wcscmp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcscmp diff --git a/libc/nt/ntdll/wcscpy.s b/libc/nt/ntdll/wcscpy.s new file mode 100644 index 00000000..232e55e7 --- /dev/null +++ b/libc/nt/ntdll/wcscpy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcscpy diff --git a/libc/nt/ntdll/wcscpy_s.s b/libc/nt/ntdll/wcscpy_s.s new file mode 100644 index 00000000..f8743bac --- /dev/null +++ b/libc/nt/ntdll/wcscpy_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcscpy_s diff --git a/libc/nt/ntdll/wcscspn.s b/libc/nt/ntdll/wcscspn.s new file mode 100644 index 00000000..f8fa5adc --- /dev/null +++ b/libc/nt/ntdll/wcscspn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcscspn diff --git a/libc/nt/ntdll/wcslen.s b/libc/nt/ntdll/wcslen.s new file mode 100644 index 00000000..853b4428 --- /dev/null +++ b/libc/nt/ntdll/wcslen.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcslen diff --git a/libc/nt/ntdll/wcsncat.s b/libc/nt/ntdll/wcsncat.s new file mode 100644 index 00000000..e727952c --- /dev/null +++ b/libc/nt/ntdll/wcsncat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcsncat diff --git a/libc/nt/ntdll/wcsncat_s.s b/libc/nt/ntdll/wcsncat_s.s new file mode 100644 index 00000000..358c3a59 --- /dev/null +++ b/libc/nt/ntdll/wcsncat_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcsncat_s diff --git a/libc/nt/ntdll/wcsncmp.s b/libc/nt/ntdll/wcsncmp.s new file mode 100644 index 00000000..8bb3fff4 --- /dev/null +++ b/libc/nt/ntdll/wcsncmp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcsncmp diff --git a/libc/nt/ntdll/wcsncpy.s b/libc/nt/ntdll/wcsncpy.s new file mode 100644 index 00000000..ce427565 --- /dev/null +++ b/libc/nt/ntdll/wcsncpy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcsncpy diff --git a/libc/nt/ntdll/wcsncpy_s.s b/libc/nt/ntdll/wcsncpy_s.s new file mode 100644 index 00000000..395fd015 --- /dev/null +++ b/libc/nt/ntdll/wcsncpy_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcsncpy_s diff --git a/libc/nt/ntdll/wcsnlen.s b/libc/nt/ntdll/wcsnlen.s new file mode 100644 index 00000000..72f4a19d --- /dev/null +++ b/libc/nt/ntdll/wcsnlen.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcsnlen diff --git a/libc/nt/ntdll/wcspbrk.s b/libc/nt/ntdll/wcspbrk.s new file mode 100644 index 00000000..725ee657 --- /dev/null +++ b/libc/nt/ntdll/wcspbrk.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcspbrk diff --git a/libc/nt/ntdll/wcsrchr.s b/libc/nt/ntdll/wcsrchr.s new file mode 100644 index 00000000..ddc9ded2 --- /dev/null +++ b/libc/nt/ntdll/wcsrchr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcsrchr diff --git a/libc/nt/ntdll/wcsspn.s b/libc/nt/ntdll/wcsspn.s new file mode 100644 index 00000000..a5d579d6 --- /dev/null +++ b/libc/nt/ntdll/wcsspn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcsspn diff --git a/libc/nt/ntdll/wcsstr.s b/libc/nt/ntdll/wcsstr.s new file mode 100644 index 00000000..c8593e33 --- /dev/null +++ b/libc/nt/ntdll/wcsstr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcsstr diff --git a/libc/nt/ntdll/wcstok_s.s b/libc/nt/ntdll/wcstok_s.s new file mode 100644 index 00000000..ef7843e5 --- /dev/null +++ b/libc/nt/ntdll/wcstok_s.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcstok_s diff --git a/libc/nt/ntdll/wcstol.s b/libc/nt/ntdll/wcstol.s new file mode 100644 index 00000000..9f39db06 --- /dev/null +++ b/libc/nt/ntdll/wcstol.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcstol diff --git a/libc/nt/ntdll/wcstombs.s b/libc/nt/ntdll/wcstombs.s new file mode 100644 index 00000000..a8a67888 --- /dev/null +++ b/libc/nt/ntdll/wcstombs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcstombs diff --git a/libc/nt/ntdll/wcstoul.s b/libc/nt/ntdll/wcstoul.s new file mode 100644 index 00000000..2af779ac --- /dev/null +++ b/libc/nt/ntdll/wcstoul.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/ntdllimport.inc" +.ntimp wcstoul diff --git a/libc/nt/ntdllimport.S b/libc/nt/ntdllimport.S new file mode 100644 index 00000000..a8e5c632 --- /dev/null +++ b/libc/nt/ntdllimport.S @@ -0,0 +1,68 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/nt/enum/status.h" +#include "libc/macros.h" +.yoink __FILE__ + +/ @fileoverview NTDLL.DLL Non-Mandatory Importer +/ +/ This module lets us import Microsoft's private APIs in a way +/ that ensures executables won't fail to load in the future, +/ should Microsoft ever choose to delete these APIs. + + .initro 202,_init_ntdll.1 + .type kNtdllProcRvas,@object +kNtdllProcRvas: + .previous/* + ... + decentralized content + ... + */.initro 202,_init_ntdll.3 + .quad 0 + .previous + + .init.start 202,_init_ntdll + push %r12 + push %r13 + lea ntdllmissingno(%rip),%r13 + sub $32,%rsp + loadstr "ntdll.dll",cx + call *__imp_GetModuleHandleA(%rip) + mov %rax,%r12 +0: lodsq + test %rax,%rax + jz 1f + lea (%rbx,%rax),%rdx + mov %r12,%rcx + call *__imp_GetProcAddress(%rip) + test %rax,%rax + cmovz %r13,%rax + stosq + jmp 0b +1: add $32,%rsp + pop %r13 + pop %r12 + .init.end 202,_init_ntdll,globl,hidden + + .text.windows +ntdllmissingno: + mov $kNtStatusDllNotFound,%eax + ret + .previous diff --git a/libc/nt/ntdllimport.h b/libc/nt/ntdllimport.h new file mode 100644 index 00000000..c1834881 --- /dev/null +++ b/libc/nt/ntdllimport.h @@ -0,0 +1,45 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#ifndef COSMOPOLITAN_LIBC_NT_NTDLLIMPORT_H_ +#define COSMOPOLITAN_LIBC_NT_NTDLLIMPORT_H_ +#include "ape/relocations.h" +#include "libc/macros.h" +#ifdef __ASSEMBLER__ +/* clang-format off */ + +.macro .ntimp fn:req + yoink _init_ntdll + .initbss 202,_init_ntdll.\fn +__imp_\fn: + .quad 0 + .endobj __imp_\fn,globl,hidden + .previous + .initro 202,_init_ntdll.2.\fn + .quad RVA(.L\fn) + .previous + .section .rodata.str1.1,"aSM",@progbits,1 +.L\fn: + .asciz "\fn" + .previous +.endm + +/* clang-format on */ +#endif /* __ASSEMBLER__ */ +#endif /* COSMOPOLITAN_LIBC_NT_NTDLLIMPORT_H_ */ diff --git a/libc/nt/paint.h b/libc/nt/paint.h new file mode 100644 index 00000000..699213fa --- /dev/null +++ b/libc/nt/paint.h @@ -0,0 +1,58 @@ +#ifndef COSMOPOLITAN_LIBC_NT_PAINT_H_ +#define COSMOPOLITAN_LIBC_NT_PAINT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § new technology » cpu graphics ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +struct NtSize { + int32_t cx; + int32_t cy; +}; + +struct NtRectangle { + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; +}; + +struct NtDrawTextParams { + uint32_t cbSize; + int32_t iTabLength; + int32_t iLeftMargin; + int32_t iRightMargin; + uint32_t uiLengthDrawn; +}; + +struct NtPaintStruct { + int64_t hdc; + int32_t fErase; + struct NtRectangle rcPaint; + int32_t fRestore; + int32_t fIncUpdate; + unsigned char rgbReserved[32]; +}; + +int64_t BeginPaint(int64_t hWnd, struct NtPaintStruct *lpPaint); +int32_t EndPaint(int64_t hWnd, const struct NtPaintStruct *lpPaint); +int32_t BitBlt(int64_t hdc, int x, int y, int cx, int cy, int64_t hdcSrc, + int x1, int y1, uint32_t rop); +int32_t GetClientRect(int64_t hWnd, struct NtRectangle *lpRect); +int32_t GetWindowRect(int64_t hWnd, struct NtRectangle *lpRect); +int32_t SetBkMode(int64_t hdc, int mode); +uint32_t SetTextColor(int64_t hdc, uint32_t color); +uint32_t SetTextAlign(int64_t hdc, uint32_t align); +int32_t SetTextJustification(int64_t hdc, int extra, int count); +int32_t DrawText(int64_t hdc, const char16_t *lpchText, int cchText, + struct NtRectangle *lprc, uint32_t format); +int32_t DrawTextEx(int64_t hdc, char16_t *lpchText, int cchText, + struct NtRectangle *lprc, uint32_t format, + struct NtDrawTextParams *lpdtp); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_PAINT_H_ */ diff --git a/libc/nt/pedef.h b/libc/nt/pedef.h new file mode 100644 index 00000000..1df4209e --- /dev/null +++ b/libc/nt/pedef.h @@ -0,0 +1,385 @@ +#ifndef COSMOPOLITAN_LIBC_NT_PEDEF_H_ +#define COSMOPOLITAN_LIBC_NT_PEDEF_H_ +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ αcτµαlly pδrταblε εxεcµταblε § portable executable ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + .text: Code + .data: Initialized data + .bss: Uninitialized data + .rdata: Const/read-only (and initialized) data + .edata: Export descriptors + .idata: Import descriptors + .reloc: Relocation table (for code instructions with absolute + addressing when the module could not be loaded at its + preferred base address) + .rsrc: Resources (icon, bitmap, dialog, ...) + .tls: __declspec(thread) data (Fails with dynamically loaded DLLs -> + hard to find bugs) */ + +#define kNtImageDosSignature 0x5A4D +#define kNtImageOs2Signature 0x454E +#define kNtImageOs2SignatureLe 0x454C +#define kNtImageVxdSignature 0x454C +#define kNtImageNtSignature 0x00004550 + +#define kNtPeFileRelocsStripped 0x00001 +#define kNtPeFileExecutableImage 0x00002 +#define kNtPeFileLineNumsStripped 0x00004 +#define kNtPeFileLocalSymsStripped 0x00008 +#define kNtPeFile_32bitMachine 0x00100 +#define kNtPeFileDll 0x02000 + +#define kNtPe32bit 0x010b +#define kNtPe64bit 0x020b + +#define kNtPeSectionCntCode 0x000000020 +#define kNtPeSectionCntInitializedData 0x000000040 +#define kNtPeSectionCntUninitializedData 0x000000080 +#define kNtPeSectionGprel 0x000008000 +#define kNtPeSectionMemDiscardable 0x02000000 +#define kNtPeSectionMemNotCached 0x04000000 +#define kNtPeSectionMemNotPaged 0x08000000 +#define kNtPeSectionMemShared 0x10000000 +#define kNtPeSectionMemExecute 0x20000000 +#define kNtPeSectionMemRead 0x40000000 +#define kNtPeSectionMemWrite 0x80000000 + +#define kNtPeGuardCfInstrumented 0x000000100 +#define kNtPeGuardCfwInstrumented 0x000000200 +#define kNtPeGuardCfFunctionTablePresent 0x000000400 +#define kNtPeGuardSecurityCookieUnused 0x000000800 + +#define kNtPeRelBasedAbsolute 0 +#define kNtPeRelBasedHigh 1 +#define kNtPeRelBasedLow 2 +#define kNtPeRelBasedHighlow 3 +#define kNtPeRelBasedHighadj 4 +#define kNtPeRelBasedMipsJmpaddr 5 +#define kNtPeRelBasedSection 6 +#define kNtPeRelBasedRel32 7 +#define kNtPeRelBasedMipsJmpaddr16 9 +#define kNtPeRelBasedIa64Imm64 9 +#define kNtPeRelBasedDir64 10 +#define kNtPeRelBasedHigh3adj 11 + +#define kNtImageFileRelocsStripped 0x0001 +#define kNtImageFileExecutableImage 0x0002 +#define kNtImageFileLineNumsStripped 0x0004 +#define kNtImageFileLocalSymsStripped 0x0008 +#define kNtImageFileAggresiveWsTrim 0x0010 +#define kNtImageFileLargeAddressAware 0x0020 +#define kNtImageFileBytesReversedLo 0x0080 +#define kNtImageFile32bitMachine 0x0100 +#define kNtImageFileDebugStripped 0x0200 +#define kNtImageFileRemovableRunFromSwap 0x0400 +#define kNtImageFileNetRunFromSwap 0x0800 +#define kNtImageFileSystem 0x1000 +#define kNtImageFileDll 0x2000 +#define kNtImageFileUpSystemOnly 0x4000 +#define kNtImageFileBytesReversedHi 0x8000 + +#define kNtImageFileMachineUnknown 0 +#define kNtImageFileMachineTargetHost 0x0001 +#define kNtImageFileMachineI386 0x014c +#define kNtImageFileMachineR3000 0x0162 +#define kNtImageFileMachineR4000 0x0166 +#define kNtImageFileMachineR10000 0x0168 +#define kNtImageFileMachineWcemipsv2 0x0169 +#define kNtImageFileMachineAlpha 0x0184 +#define kNtImageFileMachineSh3 0x01a2 +#define kNtImageFileMachineSh3dsp 0x01a3 +#define kNtImageFileMachineSh3e 0x01a4 +#define kNtImageFileMachineSh4 0x01a6 +#define kNtImageFileMachineSh5 0x01a8 +#define kNtImageFileMachineArm 0x01c0 +#define kNtImageFileMachineThumb 0x01c2 +#define kNtImageFileMachineArmnt 0x01c4 +#define kNtImageFileMachineAm33 0x01d3 +#define kNtImageFileMachinePowerpc 0x01F0 +#define kNtImageFileMachinePowerpcfp 0x01f1 +#define kNtImageFileMachineIa64 0x0200 +#define kNtImageFileMachineMips16 0x0266 +#define kNtImageFileMachineAlpha64 0x0284 +#define kNtImageFileMachineMipsfpu 0x0366 +#define kNtImageFileMachineMipsfpu16 0x0466 +#define kNtImageFileMachineAxp64 kNtImageFileMachineAlpha64 +#define kNtImageFileMachineTricore 0x0520 +#define kNtImageFileMachineCef 0x0CEF +#define kNtImageFileMachineEbc 0x0EBC +#define kNtImageFileMachineNexgen32e 0x8664 +#define kNtImageFileMachineM32r 0x9041 +#define kNtImageFileMachineArm64 0xAA64 +#define kNtImageFileMachineCee 0xC0EE + +#define kNtImageSubsystemUnknown 0 +#define kNtImageSubsystemNative 1 +#define kNtImageSubsystemWindowsGui 2 +#define kNtImageSubsystemWindowsCui 3 +#define kNtImageSubsystemOs2Cui 5 +#define kNtImageSubsystemPosixCui 7 +#define kNtImageSubsystemNativeWindows 8 +#define kNtImageSubsystemWindowsCeGui 9 +#define kNtImageSubsystemEfiApplication 1 +#define kNtImageSubsystemEfiBootServiceDriver 11 +#define kNtImageSubsystemEfiRuntimeDriver 12 +#define kNtImageSubsystemEfiRom 13 +#define kNtImageSubsystemXbox 14 +#define kNtImageSubsystemWindowsBootApplication 16 +#define kNtImageSubsystemXboxCodeCatalog 17 + +#define kNtImageDllcharacteristicsHighEntropyVa 0x0020 +#define kNtImageDllcharacteristicsDynamicBase 0x0040 +#define kNtImageDllcharacteristicsForceIntegrity 0x0080 +#define kNtImageDllcharacteristicsNxCompat 0x0100 +#define kNtImageDllcharacteristicsNoIsolation 0x0200 +#define kNtImageDllcharacteristicsNoSeh 0x0400 +#define kNtImageDllcharacteristicsNoBind 0x0800 +#define kNtImageDllcharacteristicsAppcontainer 0x1000 +#define kNtImageDllcharacteristicsWdmDriver 0x2000 +#define kNtImageDllcharacteristicsGuardCf 0x4000 +#define kNtImageDllcharacteristicsTerminalServerAware 0x8000 + +#define kNtImageDirectoryEntryExport 0 +#define kNtImageDirectoryEntryImport 1 +#define kNtImageDirectoryEntryResource 2 +#define kNtImageDirectoryEntryException 3 +#define kNtImageDirectoryEntrySecurity 4 +#define kNtImageDirectoryEntryBasereloc 5 +#define kNtImageDirectoryEntryDebug 6 +#define kNtImageDirectoryEntryArchitecture 7 +#define kNtImageDirectoryEntryGlobalptr 8 +#define kNtImageDirectoryEntryTls 9 +#define kNtImageDirectoryEntryLoadConfig 10 +#define kNtImageDirectoryEntryBoundImport 11 +#define kNtImageDirectoryEntryIat 12 +#define kNtImageDirectoryEntryDelayImport 13 +#define kNtImageDirectoryEntryComDescriptor 14 + +#define kNtImageScnTypeNoPad 0x00000008 +#define kNtImageScnCntCode 0x00000020 +#define kNtImageScnCntInitializedData 0x00000040 +#define kNtImageScnCntUninitializedData 0x00000080 +#define kNtImageScnLnkOther 0x00000100 +#define kNtImageScnLnkInfo 0x00000200 +#define kNtImageScnLnkRemove 0x00000800 +#define kNtImageScnLnkComdat 0x00001000 +#define kNtImageScnNoDeferSpecExc 0x00004000 +#define kNtImageScnGprel 0x00008000 +#define kNtImageScnMemFardata 0x00008000 +#define kNtImageScnMemPurgeable 0x00020000 +#define kNtImageScnMem16bit 0x00020000 +#define kNtImageScnMemLocked 0x00040000 +#define kNtImageScnMemPreload 0x00080000 + +#define kNtImageScnAlign1bytes 0x00100000 +#define kNtImageScnAlign2bytes 0x00200000 +#define kNtImageScnAlign4bytes 0x00300000 +#define kNtImageScnAlign8bytes 0x00400000 +#define kNtImageScnAlign16bytes 0x00500000 +#define kNtImageScnAlign32bytes 0x00600000 +#define kNtImageScnAlign64bytes 0x00700000 +#define kNtImageScnAlign128bytes 0x00800000 +#define kNtImageScnAlign256bytes 0x00900000 +#define kNtImageScnAlign512bytes 0x00A00000 +#define kNtImageScnAlign1024bytes 0x00B00000 +#define kNtImageScnAlign2048bytes 0x00C00000 +#define kNtImageScnAlign4096bytes 0x00D00000 +#define kNtImageScnAlign8192bytes 0x00E00000 +#define kNtImageScnAlignMask 0x00F00000 + +#define kNtImageScnLnkNrelocOvfl 0x01000000 +#define kNtImageScnMemDiscardable 0x02000000 +#define kNtImageScnMemNotCached 0x04000000 +#define kNtImageScnMemNotPaged 0x08000000 +#define kNtImageScnMemShared 0x10000000 +#define kNtImageScnMemExecute 0x20000000 +#define kNtImageScnMemRead 0x40000000 +#define kNtImageScnMemWrite 0x80000000 +#define kNtImageScnScaleIndex 0x00000001 + +#define kNtImageSymUndefined ((uint16_t)0) +#define kNtImageSymAbsolute ((uint16_t)-1) +#define kNtImageSymDebug ((uint16_t)-2) +#define kNtImageSymSectionMax 0xFEFF +#define kNtImageSymSectionMaxEx __LONG_MAX__ +#define kNtImageSymTypeNull 0x0000 +#define kNtImageSymTypeVoid 0x0001 +#define kNtImageSymTypeChar 0x0002 +#define kNtImageSymTypeShort 0x0003 +#define kNtImageSymTypeInt 0x0004 +#define kNtImageSymTypeLong 0x0005 +#define kNtImageSymTypeFloat 0x0006 +#define kNtImageSymTypeDouble 0x0007 +#define kNtImageSymTypeStruct 0x0008 +#define kNtImageSymTypeUnion 0x0009 +#define kNtImageSymTypeEnum 0x000A +#define kNtImageSymTypeMoe 0x000B +#define kNtImageSymTypeByte 0x000C +#define kNtImageSymTypeWord 0x000D +#define kNtImageSymTypeUint 0x000E +#define kNtImageSymTypeDword 0x000F +#define kNtImageSymTypePcode 0x8000 +#define kNtImageSymDtypeNull 0 +#define kNtImageSymDtypePointer 1 +#define kNtImageSymDtypeFunction 2 +#define kNtImageSymDtypeArray 3 +#define kNtImageSymClassEndOfFunction ((unsigned char)-1) +#define kNtImageSymClassNull 0x0000 +#define kNtImageSymClassAutomatic 0x0001 +#define kNtImageSymClassExternal 0x0002 +#define kNtImageSymClassStatic 0x0003 +#define kNtImageSymClassRegister 0x0004 +#define kNtImageSymClassExternalDef 0x0005 +#define kNtImageSymClassLabel 0x0006 +#define kNtImageSymClassUndefinedLabel 0x0007 +#define kNtImageSymClassMemberOfStruct 0x0008 +#define kNtImageSymClassArgument 0x0009 +#define kNtImageSymClassStructTag 0x000A +#define kNtImageSymClassMemberOfUnion 0x000B +#define kNtImageSymClassUnionTag 0x000C +#define kNtImageSymClassTypeDefinition 0x000D +#define kNtImageSymClassUndefinedStatic 0x000E +#define kNtImageSymClassEnumTag 0x000F +#define kNtImageSymClassMemberOfEnum 0x0010 +#define kNtImageSymClassRegisterParam 0x0011 +#define kNtImageSymClassBitField 0x0012 +#define kNtImageSymClassFarExternal 0x0044 +#define kNtImageSymClassBlock 0x0064 +#define kNtImageSymClassFunction 0x0065 +#define kNtImageSymClassEndOfStruct 0x0066 +#define kNtImageSymClassFile 0x0067 +#define kNtImageSymClassSection 0x0068 +#define kNtImageSymClassWeakExternal 0x0069 +#define kNtImageSymClassClrToken 0x006B + +#define kNtImageComdatSelectNoduplicates 1 +#define kNtImageComdatSelectAny 2 +#define kNtImageComdatSelectSameSize 3 +#define kNtImageComdatSelectExactMatch 4 +#define kNtImageComdatSelectAssociative 5 +#define kNtImageComdatSelectLargest 6 +#define kNtImageComdatSelectNewest 7 + +#define kNtImageWeakExternSearchNolibrary 1 +#define kNtImageWeakExternSearchLibrary 2 +#define kNtImageWeakExternSearchAlias 3 +#define kNtImageWeakExternAntiDependency 4 + +#define kNtImageRelNexgen32eAbsolute 0x0000 +#define kNtImageRelNexgen32eAddr64 0x0001 +#define kNtImageRelNexgen32eAddr32 0x0002 +#define kNtImageRelNexgen32eAddr32nb 0x0003 +#define kNtImageRelNexgen32eRel32 0x0004 +#define kNtImageRelNexgen32eRel32_1 0x0005 +#define kNtImageRelNexgen32eRel32_2 0x0006 +#define kNtImageRelNexgen32eRel32_3 0x0007 +#define kNtImageRelNexgen32eRel32_4 0x0008 +#define kNtImageRelNexgen32eRel32_5 0x0009 +#define kNtImageRelNexgen32eSection 0x000A +#define kNtImageRelNexgen32eSecrel 0x000B +#define kNtImageRelNexgen32eSecrel7 0x000C +#define kNtImageRelNexgen32eToken 0x000D +#define kNtImageRelNexgen32eSrel32 0x000E +#define kNtImageRelNexgen32ePair 0x000F +#define kNtImageRelNexgen32eSspan32 0x0010 + +#define kNtImageRelBasedAbsolute 0 +#define kNtImageRelBasedHigh 1 +#define kNtImageRelBasedLow 2 +#define kNtImageRelBasedHighlow 3 +#define kNtImageRelBasedHighadj 4 +#define kNtImageRelBasedMachineSpecific_5 5 +#define kNtImageRelBasedReserved 6 +#define kNtImageRelBasedMachineSpecific_7 7 +#define kNtImageRelBasedMachineSpecific_8 8 +#define kNtImageRelBasedMachineSpecific_9 9 +#define kNtImageRelBasedDir64 10 + +#define kNtImageArchiveStartSize 8 +#define kNtImageArchiveStart "!\n" +#define kNtImageArchiveEnd "`\n" +#define kNtImageArchivePad "\n" +#define kNtImageArchiveLinkerMember "/ " +#define kNtImageArchiveLongnamesMember "// " +#define kNtImageArchiveHybridmapMember "// " + +#define kNtImageOrdinalFlag 0x8000000000000000 +#define NtImageOrdinal(Ordinal) (Ordinal & 0xffff) +#define NtImageSnapByOrdinal(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG64) != 0) + +#define kNtImageResourceNameIsString 0x80000000 +#define kNtImageResourceDataIsDirectory 0x80000000 + +#define kNtImageDynamicRelocationGuardRfPrologue 0x00000001 +#define kNtImageDynamicRelocationGuardRfEpilogue 0x00000002 + +#define kNtImageHotPatchBaseObligatory 0x00000001 +#define kNtImageHotPatchChunkInverse 0x80000000 +#define kNtImageHotPatchChunkObligatory 0x40000000 +#define kNtImageHotPatchChunkReserved 0x3FF03000 +#define kNtImageHotPatchChunkType 0x000FC000 +#define kNtImageHotPatchChunkSourceRva 0x00008000 +#define kNtImageHotPatchChunkTargetRva 0x00004000 +#define kNtImageHotPatchChunkSize 0x00000FFF +#define kNtImageHotPatchNone 0x00000000 +#define kNtImageHotPatchFunction 0x0001C000 +#define kNtImageHotPatchAbsolute 0x0002C000 +#define kNtImageHotPatchRel32 0x0003C000 +#define kNtImageHotPatchCallTarget 0x00044000 +#define kNtImageHotPatchIndirect 0x0005C000 +#define kNtImageHotPatchNoCallTarget 0x00064000 +#define kNtImageHotPatchDynamicValue 0x00078000 +#define kNtImageGuardCfInstrumented 0x00000100 +#define kNtImageGuardCfwInstrumented 0x00000200 +#define kNtImageGuardCfFunctionTablePresent 0x00000400 +#define kNtImageGuardSecurityCookieUnused 0x00000800 +#define kNtImageGuardProtectDelayloadIat 0x00001000 +#define kNtImageGuardDelayloadIatInItsOwnSection 0x00002000 +#define kNtImageGuardCfExportSuppressionInfoPresent 0x00004000 +#define kNtImageGuardCfEnableExportSuppression 0x00008000 +#define kNtImageGuardCfLongjumpTablePresent 0x00010000 +#define kNtImageGuardRfInstrumented 0x00020000 +#define kNtImageGuardRfEnable 0x00040000 +#define kNtImageGuardRfStrict 0x00080000 +#define kNtImageGuardCfFunctionTableSizeMask 0xF0000000 +#define kNtImageGuardCfFunctionTableSizeShift 28 +#define kNtImageGuardFlagFidSuppressed 0x01 +#define kNtImageGuardFlagExportSuppressed 0x02 + +#define kNtImageEnclaveImportMatchNone 0x00000000 +#define kNtImageEnclaveImportMatchUniqueId 0x00000001 +#define kNtImageEnclaveImportMatchAuthorId 0x00000002 +#define kNtImageEnclaveImportMatchFamilyId 0x00000003 +#define kNtImageEnclaveImportMatchImageId 0x00000004 + +#define kNtImageDebugTypeUnknown 0 +#define kNtImageDebugTypeCoff 1 +#define kNtImageDebugTypeCodeview 2 +#define kNtImageDebugTypeFpo 3 +#define kNtImageDebugTypeMisc 4 +#define kNtImageDebugTypeException 5 +#define kNtImageDebugTypeFixup 6 +#define kNtImageDebugTypeOmapToSrc 7 +#define kNtImageDebugTypeOmapFromSrc 8 +#define kNtImageDebugTypeBorland 9 +#define kNtImageDebugTypeReserved10 10 +#define kNtImageDebugTypeClsid 11 +#define kNtImageDebugTypeVcFeature 12 +#define kNtImageDebugTypePogo 13 +#define kNtImageDebugTypeIltcg 14 +#define kNtImageDebugTypeMpx 15 +#define kNtImageDebugTypeRepro 16 + +#define kNtFrameFpo 0 +#define kNtFrameTrap 1 +#define kNtFrameTss 2 +#define kNtFrameNonfpo 3 + +#define kNtImageSizeofShortName 8 +#define kNtImageSizeofSectionHeader 40 +#define kNtImageSizeofSymbol 18 +#define kNtImageEnclaveLongIdLength 32 +#define kNtImageEnclaveShortIdLength 16 +#define kNtImageNumberofDirectoryEntries 16 + +#endif /* COSMOPOLITAN_LIBC_NT_PEDEF_H_ */ diff --git a/libc/nt/privilege.h b/libc/nt/privilege.h new file mode 100644 index 00000000..36f6763b --- /dev/null +++ b/libc/nt/privilege.h @@ -0,0 +1,53 @@ +#ifndef COSMOPOLITAN_LIBC_NT_PRIVILEGE_H_ +#define COSMOPOLITAN_LIBC_NT_PRIVILEGE_H_ +#include "libc/nt/struct/luid.h" +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » check your privilege ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +#define kNtSePrivilegeEnabledByDefault 0x00000001u +#define kNtSePrivilegeEnabled 0x00000002u +#define kNtSePrivilegeRemoved 0x00000004u +#define kNtSePrivilegeUsedForAccess 0x80000000u + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtLuid; +struct NtTokenPrivileges; + +bool32 LookupPrivilegeValue(const char16_t *opt_lpSystemName, + const char16_t *lpName, struct NtLuid *out_lpLuid); + +bool32 AdjustTokenPrivileges(int64_t TokenHandle, bool32 DisableAllPrivileges, + const struct NtTokenPrivileges *opt_NewState, + uint32_t BufferLength, + struct NtTokenPrivileges *opt_out_PreviousState, + uint32_t *opt_out_ReturnLength); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_PRIVILEGE_H_ */ diff --git a/libc/nt/process.h b/libc/nt/process.h new file mode 100644 index 00000000..f70718ca --- /dev/null +++ b/libc/nt/process.h @@ -0,0 +1,83 @@ +#ifndef COSMOPOLITAN_LIBC_NT_PROCESS_H_ +#define COSMOPOLITAN_LIBC_NT_PROCESS_H_ +#include "libc/nt/enum/accessmask.h" +#include "libc/nt/enum/processaccess.h" +#include "libc/nt/enum/processcreationflags.h" +#include "libc/nt/startupinfo.h" +#include "libc/nt/thunk/msabi.h" +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » processes ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtProcessInformation; +struct NtSecurityAttributes; +struct NtStartupInfo; + +bool32 CreateProcess(const char16_t *opt_lpApplicationName, + char16_t *lpCommandLine, + struct NtSecurityAttributes *opt_lpProcessAttributes, + struct NtSecurityAttributes *opt_lpThreadAttributes, + bool32 bInheritHandles, uint32_t dwCreationFlags, + void *opt_lpEnvironment, + const char16_t *opt_lpCurrentDirectory, + const struct NtStartupInfo *lpStartupInfo, + struct NtProcessInformation *opt_out_lpProcessInformation) + paramsnonnull((2, 9)); + +uint32_t GetThreadId(int64_t Thread); /* cf. NT_TID */ +uint32_t GetProcessId(int64_t Process); /* cf. NT_PID */ +void SetLastError(uint32_t dwErrCode); +uint32_t FormatMessage(uint32_t dwFlags, const void *lpSource, + uint32_t dwMessageId, uint32_t dwLanguageId, + char16_t *lpBuffer, uint32_t nSize, va_list *Arguments); +int64_t OpenProcess(uint32_t dwDesiredAccess, bool32 bInheritHandle, + uint32_t dwProcessId); +uint32_t GetCurrentProcessId(void); /* %gs:0x40 */ +uint32_t GetEnvironmentVariable(const char16_t *lpName, char16_t *lpBuffer, + uint32_t nSize); +uint32_t SetEnvironmentVariable(const char16_t *lpName, char16_t *lpValue); +int32_t SetEnvironmentStrings(char16_t *NewEnvironment); +bool32 GetProcessAffinityMask(int64_t hProcess, + uintptr_t *lpProcessAffinityMask, + uintptr_t *lpSystemAffinityMask); +uint64_t /*bool32*/ SetProcessAffinityMask(int64_t hProcess, + uintptr_t dwProcessAffinityMask); + +/* e.g. kNtAboveNormalPriorityClass, kNtHighPriorityClass */ +uint32_t GetPriorityClass(int64_t hProcess); +bool32 SetPriorityClass(int64_t hProcess, uint32_t dwPriorityClass); +bool32 SetProcessPriorityBoost(int64_t hProcess, bool32 bDisablePriorityBoost); +bool32 GetProcessPriorityBoost(int64_t hProcess, bool32 *pDisablePriorityBoost); + +#if ShouldUseMsabiAttribute() +#include "libc/nt/thunk/msabi.h" +#endif /* ShouldUseMsabiAttribute() */ +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_PROCESS_H_ */ diff --git a/libc/nt/registry.h b/libc/nt/registry.h new file mode 100644 index 00000000..6ee1a6b4 --- /dev/null +++ b/libc/nt/registry.h @@ -0,0 +1,146 @@ +#ifndef COSMOPOLITAN_LIBC_NT_REGISTRY_H_ +#define COSMOPOLITAN_LIBC_NT_REGISTRY_H_ +#include "libc/nt/enum/keyaccess.h" +#include "libc/nt/enum/reggetvalueflags.h" +#include "libc/nt/enum/regtype.h" +#include "libc/nt/enum/securityinformation.h" +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » registry ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +#define kNtMaxKeyNameChars 255 +#define kNtMaxValueNameChars 16383 +#define kNtMaxValueBytes 0x100000 + +#define kNtHkeyClassesRoot 0x80000000l +#define kNtHkeyCurrentUser 0x80000001l +#define kNtHkeyLocalMachine 0x80000002l +#define kNtHkeyUsers 0x80000003l +#define kNtHkeyPerformanceData 0x80000004l +#define kNtHkeyPerformanceText 0x80000050l +#define kNtHkeyPerformanceNlstext 0x80000060l +#define kNtHkeyCurrentConfig 0x80000005l +#define kNtHkeyDynData 0x80000006l +#define kNtHkeyCurrentUserLocalSettings 0x80000007l + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtFileTime; +struct NtSecurityAttributes; +struct NtValent; + +int RegOpenKey(int64_t hKey, const char16_t *opt_lpSubKey, + int64_t *out_phkResult) paramsnonnull((3)); +int RegOpenKeyEx(int64_t hKey, const char16_t *opt_lpSubKey, + uint32_t opt_ulOptions, enum NtKeyAccess samDesired, + int64_t *out_phkResult) paramsnonnull((5)); +int RegCloseKey(int64_t hKey); + +int RegGetValue(int64_t hkey, const char16_t *opt_lpSubKey, + const char16_t *opt_lpValue, enum NtRegGetValueFlags dwFlags, + enum NtRegType *opt_pdwType, void *opt_out_pvData, + uint32_t *opt_inout_pcbDataBytes); +int RegSetValue(int64_t hKey, const char16_t *lpSubKey, enum NtRegType dwType, + const char16_t *lpData, uint32_t cbData); +int RegSetValueEx(int64_t hKey, const char16_t *lpValueName, uint32_t Reserved, + enum NtRegType dwType, const unsigned char *lpData, + uint32_t cbData); + +int RegQueryInfoKey(int64_t hKey, char16_t *opt_out_lpClass, + uint32_t *opt_inout_lpClassLen, uint32_t *lpReserved, + uint32_t *opt_out_lpcSubKeys, + uint32_t *opt_out_lpcbMaxSubKeyBytes, + uint32_t *opt_out_lpcbMaxClassBytes, + uint32_t *opt_out_lpcValues, + uint32_t *opt_out_lpcbMaxValueNameBytes, + uint32_t *opt_out_lpcbMaxValueBytes, + uint32_t *opt_out_lpcbSecurityDescriptorBytes, + struct NtFileTime *opt_out_lpftLastWriteTime); +int RegEnumKey(int64_t hKey, uint32_t dwIndex, char16_t *opt_lpName, + uint32_t NameLen); +int RegEnumKeyEx(int64_t hKey, uint32_t dwIndex, char16_t *out_lpName, + uint32_t *inout_lpcchName, uint32_t *lpReserved, + char16_t *opt_out_lpClass, uint32_t *opt_inout_lpcchClassLen, + struct NtFileTime *opt_out_lpftLastWriteTime); + +int RegEnumValue(int64_t hKey, uint32_t dwIndex, char16_t *lpValueName, + uint32_t *lpValueNameLen, uint32_t *lpReserved, + enum NtRegType *opt_out_lpType, unsigned char *opt_out_lpData, + uint32_t *opt_inout_lpcbDataBytes); +int RegQueryValue(int64_t hKey, const char16_t *opt_lpSubKey, + char16_t *opt_out_lpData, int32_t *opt_inout_lpcbDataBytes); +int RegQueryValueEx(int64_t hKey, const char16_t *opt_lpValueName, + uint32_t *lpReserved, enum NtRegType *opt_out_lpType, + unsigned char *opt_out_lpData, + uint32_t *opt_inout_lpcbDataBytes); + +int RegOverridePredefKey(int64_t hKey, int64_t hNewHKey); +int RegOpenUserClassesRoot(void *hToken, uint32_t dwOptions, + enum NtKeyAccess samDesired, int64_t *phkResult); +int RegOpenCurrentUser(enum NtKeyAccess samDesired, int64_t *phkResult); +int RegDisablePredefinedCache(); +int RegConnectRegistry(const char16_t *lpMachineName, int64_t hKey, + int64_t *phkResult); +int RegConnectRegistryEx(const char16_t *lpMachineName, int64_t hKey, + uint32_t Flags, int64_t *phkResult); +int RegCreateKey(int64_t hKey, const char16_t *lpSubKey, int64_t *phkResult); +int RegCreateKeyEx(int64_t hKey, const char16_t *lpSubKey, uint32_t Reserved, + int16_t *lpClass, uint32_t dwOptions, + enum NtKeyAccess samDesired, + struct NtSecurityAttributes *lpSecurityAttributes, + int64_t *phkResult, uint32_t *lpdwDisposition); +int RegDeleteKey(int64_t hKey, const char16_t *lpSubKey); +int RegDeleteKeyEx(int64_t hKey, const char16_t *lpSubKey, + enum NtKeyAccess samDesired, uint32_t Reserved); +int RegDeleteTree(int64_t hKey, const char16_t *opt_lpSubKey); +int RegDisableReflectionKey(int64_t hBase); +int RegEnableReflectionKey(int64_t hBase); +int RegQueryReflectionKey(int64_t hBase, bool32 *bIsReflectionDisabled); +int RegDeleteValue(int64_t hKey, const char16_t *lpValueName); +int RegFlushKey(int64_t hKey); +int RegGetKeySecurity(int64_t hKey, uint32_t SecurityInformation, + void *pSecurityDescriptor, + uint32_t *lpcbSecurityDescriptorBytes); +int RegLoadKey(int64_t hKey, const char16_t *lpSubKey, const char16_t *lpFile); +int RegNotifyChangeKeyValue(int64_t hKey, bool32 bWatchSubtree, + uint32_t dwNotifyFilter, void *hEvent, + int fAsynchronous); +int RegQueryMultipleValues(int64_t hKey, struct NtValent *inout_val_list, + uint32_t num_vals, int16_t *out_lpValueBuf, + uint32_t *inout_ldwTotsize) paramsnonnull(); +int RegReplaceKey(int64_t hKey, const char16_t *lpSubKey, + const char16_t *lpNewFile, const char16_t *lpOldFile); +int RegRestoreKey(int64_t hKey, const char16_t *lpFile, uint32_t dwFlags); +int RegSaveKey(int64_t hKey, const char16_t *lpFile, + struct NtSecurityAttributes *lpSecurityAttributes); +int RegSetKeySecurity(int64_t hKey, uint32_t SecurityInformation, + void *pSecurityDescriptor); +int RegUnLoadKey(int64_t hKey, const char16_t *lpSubKey); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_REGISTRY_H_ */ diff --git a/libc/nt/runtime.h b/libc/nt/runtime.h new file mode 100644 index 00000000..5caba845 --- /dev/null +++ b/libc/nt/runtime.h @@ -0,0 +1,50 @@ +#ifndef COSMOPOLITAN_LIBC_NT_RUNTIME_H_ +#define COSMOPOLITAN_LIBC_NT_RUNTIME_H_ +#include "libc/nt/enum/ctrlevent.h" +#include "libc/nt/thunk/msabi.h" +#include "libc/nt/typedef/handlerroutine.h" + +/** + * @fileoverview NT Obligatory Runtime Functions. + * + * These functions are placed in their own file because they're (a) + * abstracted by the Cosmopolitan runtime; and (b) it helps GCC avoid + * bloating binaries with debug information the user doesn't need. + */ + +#define kNtCpUtf8 65001 +#define kNtInvalidHandleValue -1L +#define kNtStdInputHandle -10L +#define kNtStdOutputHandle -11L +#define kNtStdErrorHandle -12L + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtOverlapped; + +char16_t *GetCommandLine(void) nosideeffect; +char16_t *GetEnvironmentStrings(void) nodiscard; +bool32 FreeEnvironmentStrings(char16_t *) paramsnonnull(); +bool32 ReadFile(int64_t hFile, void *lpBuffer, uint32_t nNumberOfBytesToRead, + uint32_t *lpNumberOfBytesRead, + struct NtOverlapped *opt_lpOverlapped); +bool32 WriteFile(int64_t hFile, const void *lpBuffer, + uint32_t nNumberOfBytesToWrite, + uint32_t *lpNumberOfBytesWritten, + struct NtOverlapped *opt_lpOverlapped); +bool32 TerminateProcess(int64_t hProcess, uint32_t uExitCode); +int64_t GetCurrentProcess(void) pureconst; +void ExitProcess(uint32_t uExitCode); +uint32_t GetLastError(void) nosideeffect; +bool32 CloseHandle(int64_t hObject) nothrow nocallback; +intptr_t GetStdHandle(int64_t nStdHandle) nosideeffect; +bool32 SetStdHandle(int64_t nStdHandle, int64_t hHandle); +bool32 SetDefaultDllDirectories(unsigned dirflags); + +#if ShouldUseMsabiAttribute() +#include "libc/nt/thunk/runtime.inc" +#endif /* ShouldUseMsabiAttribute() */ +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_RUNTIME_H_ */ diff --git a/libc/nt/shell32/AppCompat_RunDLLW.s b/libc/nt/shell32/AppCompat_RunDLLW.s new file mode 100644 index 00000000..ce1119de --- /dev/null +++ b/libc/nt/shell32/AppCompat_RunDLLW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_AppCompat_RunDLLW,AppCompat_RunDLLW,255 diff --git a/libc/nt/shell32/AssocCreateForClasses.s b/libc/nt/shell32/AssocCreateForClasses.s new file mode 100644 index 00000000..de212895 --- /dev/null +++ b/libc/nt/shell32/AssocCreateForClasses.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_AssocCreateForClasses,AssocCreateForClasses,263 diff --git a/libc/nt/shell32/AssocGetDetailsOfPropKey.s b/libc/nt/shell32/AssocGetDetailsOfPropKey.s new file mode 100644 index 00000000..71c70389 --- /dev/null +++ b/libc/nt/shell32/AssocGetDetailsOfPropKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_AssocGetDetailsOfPropKey,AssocGetDetailsOfPropKey,267 diff --git a/libc/nt/shell32/CDefFolderMenu_Create2.s b/libc/nt/shell32/CDefFolderMenu_Create2.s new file mode 100644 index 00000000..17ed3164 --- /dev/null +++ b/libc/nt/shell32/CDefFolderMenu_Create2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_CDefFolderMenu_Create2,CDefFolderMenu_Create2,701 diff --git a/libc/nt/shell32/CIDLData_CreateFromIDArray.s b/libc/nt/shell32/CIDLData_CreateFromIDArray.s new file mode 100644 index 00000000..cf84c007 --- /dev/null +++ b/libc/nt/shell32/CIDLData_CreateFromIDArray.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_CIDLData_CreateFromIDArray,CIDLData_CreateFromIDArray,83 diff --git a/libc/nt/shell32/CStorageItem_GetValidatedStorageItemObject.s b/libc/nt/shell32/CStorageItem_GetValidatedStorageItemObject.s new file mode 100644 index 00000000..cb143502 --- /dev/null +++ b/libc/nt/shell32/CStorageItem_GetValidatedStorageItemObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_CStorageItem_GetValidatedStorageItemObject,CStorageItem_GetValidatedStorageItemObject,937 diff --git a/libc/nt/shell32/CheckEscapesW.s b/libc/nt/shell32/CheckEscapesW.s new file mode 100644 index 00000000..425e35bc --- /dev/null +++ b/libc/nt/shell32/CheckEscapesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_CheckEscapesW,CheckEscapesW,268 diff --git a/libc/nt/shell32/CommandLineToArgvW.s b/libc/nt/shell32/CommandLineToArgvW.s new file mode 100644 index 00000000..aca5c648 --- /dev/null +++ b/libc/nt/shell32/CommandLineToArgvW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_CommandLineToArgvW,CommandLineToArgvW,269 diff --git a/libc/nt/shell32/Control_RunDLL.s b/libc/nt/shell32/Control_RunDLL.s new file mode 100644 index 00000000..df79b3e0 --- /dev/null +++ b/libc/nt/shell32/Control_RunDLL.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_Control_RunDLL,Control_RunDLL,272 diff --git a/libc/nt/shell32/Control_RunDLLA.s b/libc/nt/shell32/Control_RunDLLA.s new file mode 100644 index 00000000..8141371b --- /dev/null +++ b/libc/nt/shell32/Control_RunDLLA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_Control_RunDLLA,Control_RunDLLA,273 diff --git a/libc/nt/shell32/Control_RunDLLAsUserW.s b/libc/nt/shell32/Control_RunDLLAsUserW.s new file mode 100644 index 00000000..d363943d --- /dev/null +++ b/libc/nt/shell32/Control_RunDLLAsUserW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_Control_RunDLLAsUserW,Control_RunDLLAsUserW,274 diff --git a/libc/nt/shell32/Control_RunDLLW.s b/libc/nt/shell32/Control_RunDLLW.s new file mode 100644 index 00000000..9e918cff --- /dev/null +++ b/libc/nt/shell32/Control_RunDLLW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_Control_RunDLLW,Control_RunDLLW,275 diff --git a/libc/nt/shell32/CreateStorageItemFromPath_FullTrustCaller.s b/libc/nt/shell32/CreateStorageItemFromPath_FullTrustCaller.s new file mode 100644 index 00000000..b1a5d9a0 --- /dev/null +++ b/libc/nt/shell32/CreateStorageItemFromPath_FullTrustCaller.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_CreateStorageItemFromPath_FullTrustCaller,CreateStorageItemFromPath_FullTrustCaller,935 diff --git a/libc/nt/shell32/CreateStorageItemFromPath_FullTrustCaller_ForPackage.s b/libc/nt/shell32/CreateStorageItemFromPath_FullTrustCaller_ForPackage.s new file mode 100644 index 00000000..26d6e5ab --- /dev/null +++ b/libc/nt/shell32/CreateStorageItemFromPath_FullTrustCaller_ForPackage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_CreateStorageItemFromPath_FullTrustCaller_ForPackage,CreateStorageItemFromPath_FullTrustCaller_ForPackage,936 diff --git a/libc/nt/shell32/CreateStorageItemFromPath_PartialTrustCaller.s b/libc/nt/shell32/CreateStorageItemFromPath_PartialTrustCaller.s new file mode 100644 index 00000000..4cb344fa --- /dev/null +++ b/libc/nt/shell32/CreateStorageItemFromPath_PartialTrustCaller.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_CreateStorageItemFromPath_PartialTrustCaller,CreateStorageItemFromPath_PartialTrustCaller,920 diff --git a/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller.s b/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller.s new file mode 100644 index 00000000..1a82b1bb --- /dev/null +++ b/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_CreateStorageItemFromShellItem_FullTrustCaller,CreateStorageItemFromShellItem_FullTrustCaller,921 diff --git a/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_ForPackage.s b/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_ForPackage.s new file mode 100644 index 00000000..a907a660 --- /dev/null +++ b/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_ForPackage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_CreateStorageItemFromShellItem_FullTrustCaller_ForPackage,CreateStorageItemFromShellItem_FullTrustCaller_ForPackage,925 diff --git a/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_ForPackage_WithProcessHandle.s b/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_ForPackage_WithProcessHandle.s new file mode 100644 index 00000000..18301d7c --- /dev/null +++ b/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_ForPackage_WithProcessHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_CreateStorageItemFromShellItem_FullTrustCaller_ForPackage_WithProcessHandle,CreateStorageItemFromShellItem_FullTrustCaller_ForPackage_WithProcessHandle,929 diff --git a/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_UseImplicitFlagsAndPackage.s b/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_UseImplicitFlagsAndPackage.s new file mode 100644 index 00000000..27f241b9 --- /dev/null +++ b/libc/nt/shell32/CreateStorageItemFromShellItem_FullTrustCaller_UseImplicitFlagsAndPackage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_CreateStorageItemFromShellItem_FullTrustCaller_UseImplicitFlagsAndPackage,CreateStorageItemFromShellItem_FullTrustCaller_UseImplicitFlagsAndPackage,931 diff --git a/libc/nt/shell32/DAD_AutoScroll.s b/libc/nt/shell32/DAD_AutoScroll.s new file mode 100644 index 00000000..a2762c27 --- /dev/null +++ b/libc/nt/shell32/DAD_AutoScroll.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DAD_AutoScroll,DAD_AutoScroll,129 diff --git a/libc/nt/shell32/DAD_DragEnterEx.s b/libc/nt/shell32/DAD_DragEnterEx.s new file mode 100644 index 00000000..1b5ff54e --- /dev/null +++ b/libc/nt/shell32/DAD_DragEnterEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DAD_DragEnterEx,DAD_DragEnterEx,131 diff --git a/libc/nt/shell32/DAD_DragEnterEx2.s b/libc/nt/shell32/DAD_DragEnterEx2.s new file mode 100644 index 00000000..b90073b5 --- /dev/null +++ b/libc/nt/shell32/DAD_DragEnterEx2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DAD_DragEnterEx2,DAD_DragEnterEx2,22 diff --git a/libc/nt/shell32/DAD_DragLeave.s b/libc/nt/shell32/DAD_DragLeave.s new file mode 100644 index 00000000..cce330cf --- /dev/null +++ b/libc/nt/shell32/DAD_DragLeave.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DAD_DragLeave,DAD_DragLeave,132 diff --git a/libc/nt/shell32/DAD_DragMove.s b/libc/nt/shell32/DAD_DragMove.s new file mode 100644 index 00000000..73161722 --- /dev/null +++ b/libc/nt/shell32/DAD_DragMove.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DAD_DragMove,DAD_DragMove,134 diff --git a/libc/nt/shell32/DAD_SetDragImage.s b/libc/nt/shell32/DAD_SetDragImage.s new file mode 100644 index 00000000..725a644f --- /dev/null +++ b/libc/nt/shell32/DAD_SetDragImage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DAD_SetDragImage,DAD_SetDragImage,136 diff --git a/libc/nt/shell32/DAD_ShowDragImage.s b/libc/nt/shell32/DAD_ShowDragImage.s new file mode 100644 index 00000000..aeead5ca --- /dev/null +++ b/libc/nt/shell32/DAD_ShowDragImage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DAD_ShowDragImage,DAD_ShowDragImage,137 diff --git a/libc/nt/shell32/DllGetActivationFactory.s b/libc/nt/shell32/DllGetActivationFactory.s new file mode 100644 index 00000000..9ef53e48 --- /dev/null +++ b/libc/nt/shell32/DllGetActivationFactory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DllGetActivationFactory,DllGetActivationFactory,277 diff --git a/libc/nt/shell32/DllGetVersion.s b/libc/nt/shell32/DllGetVersion.s new file mode 100644 index 00000000..58f5d227 --- /dev/null +++ b/libc/nt/shell32/DllGetVersion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DllGetVersion,DllGetVersion,279 diff --git a/libc/nt/shell32/DllInstall.s b/libc/nt/shell32/DllInstall.s new file mode 100644 index 00000000..08736498 --- /dev/null +++ b/libc/nt/shell32/DllInstall.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DllInstall,DllInstall,280 diff --git a/libc/nt/shell32/DllRegisterServer.s b/libc/nt/shell32/DllRegisterServer.s new file mode 100644 index 00000000..d041bcc2 --- /dev/null +++ b/libc/nt/shell32/DllRegisterServer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DllRegisterServer,DllRegisterServer,281 diff --git a/libc/nt/shell32/DllUnregisterServer.s b/libc/nt/shell32/DllUnregisterServer.s new file mode 100644 index 00000000..9b58f38a --- /dev/null +++ b/libc/nt/shell32/DllUnregisterServer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DllUnregisterServer,DllUnregisterServer,282 diff --git a/libc/nt/shell32/DoEnvironmentSubstA.s b/libc/nt/shell32/DoEnvironmentSubstA.s new file mode 100644 index 00000000..dabfde0f --- /dev/null +++ b/libc/nt/shell32/DoEnvironmentSubstA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DoEnvironmentSubstA,DoEnvironmentSubstA,283 diff --git a/libc/nt/shell32/DoEnvironmentSubstW.s b/libc/nt/shell32/DoEnvironmentSubstW.s new file mode 100644 index 00000000..5a115e11 --- /dev/null +++ b/libc/nt/shell32/DoEnvironmentSubstW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DoEnvironmentSubstW,DoEnvironmentSubstW,284 diff --git a/libc/nt/shell32/DragAcceptFiles.s b/libc/nt/shell32/DragAcceptFiles.s new file mode 100644 index 00000000..e4407b24 --- /dev/null +++ b/libc/nt/shell32/DragAcceptFiles.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DragAcceptFiles,DragAcceptFiles,285 diff --git a/libc/nt/shell32/DragFinish.s b/libc/nt/shell32/DragFinish.s new file mode 100644 index 00000000..bbc74a55 --- /dev/null +++ b/libc/nt/shell32/DragFinish.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DragFinish,DragFinish,286 diff --git a/libc/nt/shell32/DragQueryFileA.s b/libc/nt/shell32/DragQueryFileA.s new file mode 100644 index 00000000..207f5a3a --- /dev/null +++ b/libc/nt/shell32/DragQueryFileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DragQueryFileA,DragQueryFileA,288 diff --git a/libc/nt/shell32/DragQueryFileAorW.s b/libc/nt/shell32/DragQueryFileAorW.s new file mode 100644 index 00000000..f6120804 --- /dev/null +++ b/libc/nt/shell32/DragQueryFileAorW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DragQueryFileAorW,DragQueryFileAorW,289 diff --git a/libc/nt/shell32/DragQueryFileW.s b/libc/nt/shell32/DragQueryFileW.s new file mode 100644 index 00000000..bc577274 --- /dev/null +++ b/libc/nt/shell32/DragQueryFileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DragQueryFileW,DragQueryFileW,290 diff --git a/libc/nt/shell32/DragQueryPoint.s b/libc/nt/shell32/DragQueryPoint.s new file mode 100644 index 00000000..74f4aaa3 --- /dev/null +++ b/libc/nt/shell32/DragQueryPoint.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DragQueryPoint,DragQueryPoint,291 diff --git a/libc/nt/shell32/DriveType.s b/libc/nt/shell32/DriveType.s new file mode 100644 index 00000000..865240ff --- /dev/null +++ b/libc/nt/shell32/DriveType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DriveType,DriveType,64 diff --git a/libc/nt/shell32/DuplicateIcon.s b/libc/nt/shell32/DuplicateIcon.s new file mode 100644 index 00000000..e948ad17 --- /dev/null +++ b/libc/nt/shell32/DuplicateIcon.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_DuplicateIcon,DuplicateIcon,292 diff --git a/libc/nt/shell32/ExtractAssociatedIconA.s b/libc/nt/shell32/ExtractAssociatedIconA.s new file mode 100644 index 00000000..07bf1762 --- /dev/null +++ b/libc/nt/shell32/ExtractAssociatedIconA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ExtractAssociatedIconA,ExtractAssociatedIconA,293 diff --git a/libc/nt/shell32/ExtractAssociatedIconExA.s b/libc/nt/shell32/ExtractAssociatedIconExA.s new file mode 100644 index 00000000..01d10fd7 --- /dev/null +++ b/libc/nt/shell32/ExtractAssociatedIconExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ExtractAssociatedIconExA,ExtractAssociatedIconExA,294 diff --git a/libc/nt/shell32/ExtractAssociatedIconExW.s b/libc/nt/shell32/ExtractAssociatedIconExW.s new file mode 100644 index 00000000..efca3a1c --- /dev/null +++ b/libc/nt/shell32/ExtractAssociatedIconExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ExtractAssociatedIconExW,ExtractAssociatedIconExW,295 diff --git a/libc/nt/shell32/ExtractAssociatedIconW.s b/libc/nt/shell32/ExtractAssociatedIconW.s new file mode 100644 index 00000000..bc5444fc --- /dev/null +++ b/libc/nt/shell32/ExtractAssociatedIconW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ExtractAssociatedIconW,ExtractAssociatedIconW,296 diff --git a/libc/nt/shell32/ExtractIconA.s b/libc/nt/shell32/ExtractIconA.s new file mode 100644 index 00000000..bb2a35b8 --- /dev/null +++ b/libc/nt/shell32/ExtractIconA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ExtractIconA,ExtractIconA,297 diff --git a/libc/nt/shell32/ExtractIconExA.s b/libc/nt/shell32/ExtractIconExA.s new file mode 100644 index 00000000..80cbfe68 --- /dev/null +++ b/libc/nt/shell32/ExtractIconExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ExtractIconExA,ExtractIconExA,299 diff --git a/libc/nt/shell32/ExtractIconExW.s b/libc/nt/shell32/ExtractIconExW.s new file mode 100644 index 00000000..08ff5754 --- /dev/null +++ b/libc/nt/shell32/ExtractIconExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ExtractIconExW,ExtractIconExW,300 diff --git a/libc/nt/shell32/ExtractIconW.s b/libc/nt/shell32/ExtractIconW.s new file mode 100644 index 00000000..7b675432 --- /dev/null +++ b/libc/nt/shell32/ExtractIconW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ExtractIconW,ExtractIconW,301 diff --git a/libc/nt/shell32/FindExecutableA.s b/libc/nt/shell32/FindExecutableA.s new file mode 100644 index 00000000..1f96574e --- /dev/null +++ b/libc/nt/shell32/FindExecutableA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_FindExecutableA,FindExecutableA,302 diff --git a/libc/nt/shell32/FindExecutableW.s b/libc/nt/shell32/FindExecutableW.s new file mode 100644 index 00000000..54a84927 --- /dev/null +++ b/libc/nt/shell32/FindExecutableW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_FindExecutableW,FindExecutableW,303 diff --git a/libc/nt/shell32/FreeIconList.s b/libc/nt/shell32/FreeIconList.s new file mode 100644 index 00000000..741c27b2 --- /dev/null +++ b/libc/nt/shell32/FreeIconList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_FreeIconList,FreeIconList,304 diff --git a/libc/nt/shell32/GetCurrentProcessExplicitAppUserModelID.s b/libc/nt/shell32/GetCurrentProcessExplicitAppUserModelID.s new file mode 100644 index 00000000..44947931 --- /dev/null +++ b/libc/nt/shell32/GetCurrentProcessExplicitAppUserModelID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_GetCurrentProcessExplicitAppUserModelID,GetCurrentProcessExplicitAppUserModelID,305 diff --git a/libc/nt/shell32/GetFileNameFromBrowse.s b/libc/nt/shell32/GetFileNameFromBrowse.s new file mode 100644 index 00000000..b88a0e9b --- /dev/null +++ b/libc/nt/shell32/GetFileNameFromBrowse.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_GetFileNameFromBrowse,GetFileNameFromBrowse,63 diff --git a/libc/nt/shell32/GetSystemPersistedStorageItemList.s b/libc/nt/shell32/GetSystemPersistedStorageItemList.s new file mode 100644 index 00000000..5e624653 --- /dev/null +++ b/libc/nt/shell32/GetSystemPersistedStorageItemList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_GetSystemPersistedStorageItemList,GetSystemPersistedStorageItemList,919 diff --git a/libc/nt/shell32/ILAppendID.s b/libc/nt/shell32/ILAppendID.s new file mode 100644 index 00000000..7d4acc8d --- /dev/null +++ b/libc/nt/shell32/ILAppendID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ILAppendID,ILAppendID,154 diff --git a/libc/nt/shell32/ILClone.s b/libc/nt/shell32/ILClone.s new file mode 100644 index 00000000..e77f46b4 --- /dev/null +++ b/libc/nt/shell32/ILClone.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ILClone,ILClone,18 diff --git a/libc/nt/shell32/ILCloneFirst.s b/libc/nt/shell32/ILCloneFirst.s new file mode 100644 index 00000000..1841c475 --- /dev/null +++ b/libc/nt/shell32/ILCloneFirst.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ILCloneFirst,ILCloneFirst,19 diff --git a/libc/nt/shell32/ILCombine.s b/libc/nt/shell32/ILCombine.s new file mode 100644 index 00000000..7dbf9f9f --- /dev/null +++ b/libc/nt/shell32/ILCombine.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ILCombine,ILCombine,25 diff --git a/libc/nt/shell32/ILCreateFromPathA.s b/libc/nt/shell32/ILCreateFromPathA.s new file mode 100644 index 00000000..4d7207ee --- /dev/null +++ b/libc/nt/shell32/ILCreateFromPathA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ILCreateFromPathA,ILCreateFromPathA,189 diff --git a/libc/nt/shell32/ILCreateFromPathW.s b/libc/nt/shell32/ILCreateFromPathW.s new file mode 100644 index 00000000..f514fc4f --- /dev/null +++ b/libc/nt/shell32/ILCreateFromPathW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ILCreateFromPathW,ILCreateFromPathW,190 diff --git a/libc/nt/shell32/ILFindChild.s b/libc/nt/shell32/ILFindChild.s new file mode 100644 index 00000000..8a688642 --- /dev/null +++ b/libc/nt/shell32/ILFindChild.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ILFindChild,ILFindChild,24 diff --git a/libc/nt/shell32/ILFindLastID.s b/libc/nt/shell32/ILFindLastID.s new file mode 100644 index 00000000..62b7cdad --- /dev/null +++ b/libc/nt/shell32/ILFindLastID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ILFindLastID,ILFindLastID,16 diff --git a/libc/nt/shell32/ILFree.s b/libc/nt/shell32/ILFree.s new file mode 100644 index 00000000..6a1cfb51 --- /dev/null +++ b/libc/nt/shell32/ILFree.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ILFree,ILFree,155 diff --git a/libc/nt/shell32/ILGetNext.s b/libc/nt/shell32/ILGetNext.s new file mode 100644 index 00000000..a1565256 --- /dev/null +++ b/libc/nt/shell32/ILGetNext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ILGetNext,ILGetNext,153 diff --git a/libc/nt/shell32/ILGetSize.s b/libc/nt/shell32/ILGetSize.s new file mode 100644 index 00000000..7063072d --- /dev/null +++ b/libc/nt/shell32/ILGetSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ILGetSize,ILGetSize,152 diff --git a/libc/nt/shell32/ILIsEqual.s b/libc/nt/shell32/ILIsEqual.s new file mode 100644 index 00000000..2c374cca --- /dev/null +++ b/libc/nt/shell32/ILIsEqual.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ILIsEqual,ILIsEqual,21 diff --git a/libc/nt/shell32/ILIsParent.s b/libc/nt/shell32/ILIsParent.s new file mode 100644 index 00000000..b53111d5 --- /dev/null +++ b/libc/nt/shell32/ILIsParent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ILIsParent,ILIsParent,23 diff --git a/libc/nt/shell32/ILLoadFromStreamEx.s b/libc/nt/shell32/ILLoadFromStreamEx.s new file mode 100644 index 00000000..78371b17 --- /dev/null +++ b/libc/nt/shell32/ILLoadFromStreamEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ILLoadFromStreamEx,ILLoadFromStreamEx,846 diff --git a/libc/nt/shell32/ILRemoveLastID.s b/libc/nt/shell32/ILRemoveLastID.s new file mode 100644 index 00000000..c51ab1a9 --- /dev/null +++ b/libc/nt/shell32/ILRemoveLastID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ILRemoveLastID,ILRemoveLastID,17 diff --git a/libc/nt/shell32/ILSaveToStream.s b/libc/nt/shell32/ILSaveToStream.s new file mode 100644 index 00000000..4ea8520f --- /dev/null +++ b/libc/nt/shell32/ILSaveToStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ILSaveToStream,ILSaveToStream,27 diff --git a/libc/nt/shell32/InitNetworkAddressControl.s b/libc/nt/shell32/InitNetworkAddressControl.s new file mode 100644 index 00000000..c28b1eaf --- /dev/null +++ b/libc/nt/shell32/InitNetworkAddressControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_InitNetworkAddressControl,InitNetworkAddressControl,306 diff --git a/libc/nt/shell32/InternalExtractIconListA.s b/libc/nt/shell32/InternalExtractIconListA.s new file mode 100644 index 00000000..2744e8b4 --- /dev/null +++ b/libc/nt/shell32/InternalExtractIconListA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_InternalExtractIconListA,InternalExtractIconListA,307 diff --git a/libc/nt/shell32/InternalExtractIconListW.s b/libc/nt/shell32/InternalExtractIconListW.s new file mode 100644 index 00000000..e0c68f12 --- /dev/null +++ b/libc/nt/shell32/InternalExtractIconListW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_InternalExtractIconListW,InternalExtractIconListW,308 diff --git a/libc/nt/shell32/IsDesktopExplorerProcess.s b/libc/nt/shell32/IsDesktopExplorerProcess.s new file mode 100644 index 00000000..158ac44d --- /dev/null +++ b/libc/nt/shell32/IsDesktopExplorerProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_IsDesktopExplorerProcess,IsDesktopExplorerProcess,942 diff --git a/libc/nt/shell32/IsLFNDriveA.s b/libc/nt/shell32/IsLFNDriveA.s new file mode 100644 index 00000000..ba5abd7e --- /dev/null +++ b/libc/nt/shell32/IsLFNDriveA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_IsLFNDriveA,IsLFNDriveA,41 diff --git a/libc/nt/shell32/IsLFNDriveW.s b/libc/nt/shell32/IsLFNDriveW.s new file mode 100644 index 00000000..fe8b6709 --- /dev/null +++ b/libc/nt/shell32/IsLFNDriveW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_IsLFNDriveW,IsLFNDriveW,42 diff --git a/libc/nt/shell32/IsNetDrive.s b/libc/nt/shell32/IsNetDrive.s new file mode 100644 index 00000000..d5623837 --- /dev/null +++ b/libc/nt/shell32/IsNetDrive.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_IsNetDrive,IsNetDrive,66 diff --git a/libc/nt/shell32/IsProcessAnExplorer.s b/libc/nt/shell32/IsProcessAnExplorer.s new file mode 100644 index 00000000..04e05a61 --- /dev/null +++ b/libc/nt/shell32/IsProcessAnExplorer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_IsProcessAnExplorer,IsProcessAnExplorer,941 diff --git a/libc/nt/shell32/IsUserAnAdmin.s b/libc/nt/shell32/IsUserAnAdmin.s new file mode 100644 index 00000000..cc360258 --- /dev/null +++ b/libc/nt/shell32/IsUserAnAdmin.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_IsUserAnAdmin,IsUserAnAdmin,680 diff --git a/libc/nt/shell32/LaunchMSHelp_RunDLLW.s b/libc/nt/shell32/LaunchMSHelp_RunDLLW.s new file mode 100644 index 00000000..db55f480 --- /dev/null +++ b/libc/nt/shell32/LaunchMSHelp_RunDLLW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_LaunchMSHelp_RunDLLW,LaunchMSHelp_RunDLLW,309 diff --git a/libc/nt/shell32/OpenAs_RunDLL.s b/libc/nt/shell32/OpenAs_RunDLL.s new file mode 100644 index 00000000..994ac6d8 --- /dev/null +++ b/libc/nt/shell32/OpenAs_RunDLL.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_OpenAs_RunDLL,OpenAs_RunDLL,81 diff --git a/libc/nt/shell32/OpenAs_RunDLLA.s b/libc/nt/shell32/OpenAs_RunDLLA.s new file mode 100644 index 00000000..276f73a1 --- /dev/null +++ b/libc/nt/shell32/OpenAs_RunDLLA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_OpenAs_RunDLLA,OpenAs_RunDLLA,125 diff --git a/libc/nt/shell32/OpenAs_RunDLLW.s b/libc/nt/shell32/OpenAs_RunDLLW.s new file mode 100644 index 00000000..be2fe39d --- /dev/null +++ b/libc/nt/shell32/OpenAs_RunDLLW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_OpenAs_RunDLLW,OpenAs_RunDLLW,133 diff --git a/libc/nt/shell32/OpenRegStream.s b/libc/nt/shell32/OpenRegStream.s new file mode 100644 index 00000000..2498dfa0 --- /dev/null +++ b/libc/nt/shell32/OpenRegStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_OpenRegStream,OpenRegStream,85 diff --git a/libc/nt/shell32/Options_RunDLL.s b/libc/nt/shell32/Options_RunDLL.s new file mode 100644 index 00000000..4d228482 --- /dev/null +++ b/libc/nt/shell32/Options_RunDLL.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_Options_RunDLL,Options_RunDLL,310 diff --git a/libc/nt/shell32/Options_RunDLLA.s b/libc/nt/shell32/Options_RunDLLA.s new file mode 100644 index 00000000..e8de7273 --- /dev/null +++ b/libc/nt/shell32/Options_RunDLLA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_Options_RunDLLA,Options_RunDLLA,311 diff --git a/libc/nt/shell32/Options_RunDLLW.s b/libc/nt/shell32/Options_RunDLLW.s new file mode 100644 index 00000000..6e3e70cb --- /dev/null +++ b/libc/nt/shell32/Options_RunDLLW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_Options_RunDLLW,Options_RunDLLW,312 diff --git a/libc/nt/shell32/PathCleanupSpec.s b/libc/nt/shell32/PathCleanupSpec.s new file mode 100644 index 00000000..17479546 --- /dev/null +++ b/libc/nt/shell32/PathCleanupSpec.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PathCleanupSpec,PathCleanupSpec,171 diff --git a/libc/nt/shell32/PathGetShortPath.s b/libc/nt/shell32/PathGetShortPath.s new file mode 100644 index 00000000..aff92c95 --- /dev/null +++ b/libc/nt/shell32/PathGetShortPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PathGetShortPath,PathGetShortPath,92 diff --git a/libc/nt/shell32/PathIsExe.s b/libc/nt/shell32/PathIsExe.s new file mode 100644 index 00000000..6c4bfa02 --- /dev/null +++ b/libc/nt/shell32/PathIsExe.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PathIsExe,PathIsExe,43 diff --git a/libc/nt/shell32/PathIsSlowA.s b/libc/nt/shell32/PathIsSlowA.s new file mode 100644 index 00000000..a3bd7fa4 --- /dev/null +++ b/libc/nt/shell32/PathIsSlowA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PathIsSlowA,PathIsSlowA,240 diff --git a/libc/nt/shell32/PathIsSlowW.s b/libc/nt/shell32/PathIsSlowW.s new file mode 100644 index 00000000..df31cc39 --- /dev/null +++ b/libc/nt/shell32/PathIsSlowW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PathIsSlowW,PathIsSlowW,239 diff --git a/libc/nt/shell32/PathMakeUniqueName.s b/libc/nt/shell32/PathMakeUniqueName.s new file mode 100644 index 00000000..61cf19c8 --- /dev/null +++ b/libc/nt/shell32/PathMakeUniqueName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PathMakeUniqueName,PathMakeUniqueName,47 diff --git a/libc/nt/shell32/PathQualify.s b/libc/nt/shell32/PathQualify.s new file mode 100644 index 00000000..c51e5aff --- /dev/null +++ b/libc/nt/shell32/PathQualify.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PathQualify,PathQualify,49 diff --git a/libc/nt/shell32/PathResolve.s b/libc/nt/shell32/PathResolve.s new file mode 100644 index 00000000..2415c9d0 --- /dev/null +++ b/libc/nt/shell32/PathResolve.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PathResolve,PathResolve,51 diff --git a/libc/nt/shell32/PathYetAnotherMakeUniqueName.s b/libc/nt/shell32/PathYetAnotherMakeUniqueName.s new file mode 100644 index 00000000..70be47e5 --- /dev/null +++ b/libc/nt/shell32/PathYetAnotherMakeUniqueName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PathYetAnotherMakeUniqueName,PathYetAnotherMakeUniqueName,75 diff --git a/libc/nt/shell32/PickIconDlg.s b/libc/nt/shell32/PickIconDlg.s new file mode 100644 index 00000000..22c54ec4 --- /dev/null +++ b/libc/nt/shell32/PickIconDlg.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PickIconDlg,PickIconDlg,62 diff --git a/libc/nt/shell32/PifMgr_CloseProperties.s b/libc/nt/shell32/PifMgr_CloseProperties.s new file mode 100644 index 00000000..e0879d22 --- /dev/null +++ b/libc/nt/shell32/PifMgr_CloseProperties.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PifMgr_CloseProperties,PifMgr_CloseProperties,13 diff --git a/libc/nt/shell32/PifMgr_GetProperties.s b/libc/nt/shell32/PifMgr_GetProperties.s new file mode 100644 index 00000000..4e5207e0 --- /dev/null +++ b/libc/nt/shell32/PifMgr_GetProperties.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PifMgr_GetProperties,PifMgr_GetProperties,10 diff --git a/libc/nt/shell32/PifMgr_OpenProperties.s b/libc/nt/shell32/PifMgr_OpenProperties.s new file mode 100644 index 00000000..65482943 --- /dev/null +++ b/libc/nt/shell32/PifMgr_OpenProperties.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PifMgr_OpenProperties,PifMgr_OpenProperties,9 diff --git a/libc/nt/shell32/PifMgr_SetProperties.s b/libc/nt/shell32/PifMgr_SetProperties.s new file mode 100644 index 00000000..52c40354 --- /dev/null +++ b/libc/nt/shell32/PifMgr_SetProperties.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PifMgr_SetProperties,PifMgr_SetProperties,11 diff --git a/libc/nt/shell32/PrepareDiscForBurnRunDllW.s b/libc/nt/shell32/PrepareDiscForBurnRunDllW.s new file mode 100644 index 00000000..b839f895 --- /dev/null +++ b/libc/nt/shell32/PrepareDiscForBurnRunDllW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PrepareDiscForBurnRunDllW,PrepareDiscForBurnRunDllW,135 diff --git a/libc/nt/shell32/PrintersGetCommand_RunDLL.s b/libc/nt/shell32/PrintersGetCommand_RunDLL.s new file mode 100644 index 00000000..f7ed2f73 --- /dev/null +++ b/libc/nt/shell32/PrintersGetCommand_RunDLL.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PrintersGetCommand_RunDLL,PrintersGetCommand_RunDLL,138 diff --git a/libc/nt/shell32/PrintersGetCommand_RunDLLA.s b/libc/nt/shell32/PrintersGetCommand_RunDLLA.s new file mode 100644 index 00000000..6fa562d0 --- /dev/null +++ b/libc/nt/shell32/PrintersGetCommand_RunDLLA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PrintersGetCommand_RunDLLA,PrintersGetCommand_RunDLLA,139 diff --git a/libc/nt/shell32/PrintersGetCommand_RunDLLW.s b/libc/nt/shell32/PrintersGetCommand_RunDLLW.s new file mode 100644 index 00000000..5f1ef275 --- /dev/null +++ b/libc/nt/shell32/PrintersGetCommand_RunDLLW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_PrintersGetCommand_RunDLLW,PrintersGetCommand_RunDLLW,150 diff --git a/libc/nt/shell32/ReadCabinetState.s b/libc/nt/shell32/ReadCabinetState.s new file mode 100644 index 00000000..aa0b8632 --- /dev/null +++ b/libc/nt/shell32/ReadCabinetState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ReadCabinetState,ReadCabinetState,654 diff --git a/libc/nt/shell32/RealDriveType.s b/libc/nt/shell32/RealDriveType.s new file mode 100644 index 00000000..1f895229 --- /dev/null +++ b/libc/nt/shell32/RealDriveType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_RealDriveType,RealDriveType,524 diff --git a/libc/nt/shell32/RealShellExecuteA.s b/libc/nt/shell32/RealShellExecuteA.s new file mode 100644 index 00000000..4f4342ed --- /dev/null +++ b/libc/nt/shell32/RealShellExecuteA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_RealShellExecuteA,RealShellExecuteA,199 diff --git a/libc/nt/shell32/RealShellExecuteExA.s b/libc/nt/shell32/RealShellExecuteExA.s new file mode 100644 index 00000000..4744a6be --- /dev/null +++ b/libc/nt/shell32/RealShellExecuteExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_RealShellExecuteExA,RealShellExecuteExA,207 diff --git a/libc/nt/shell32/RealShellExecuteExW.s b/libc/nt/shell32/RealShellExecuteExW.s new file mode 100644 index 00000000..d6836cd5 --- /dev/null +++ b/libc/nt/shell32/RealShellExecuteExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_RealShellExecuteExW,RealShellExecuteExW,208 diff --git a/libc/nt/shell32/RealShellExecuteW.s b/libc/nt/shell32/RealShellExecuteW.s new file mode 100644 index 00000000..247669af --- /dev/null +++ b/libc/nt/shell32/RealShellExecuteW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_RealShellExecuteW,RealShellExecuteW,226 diff --git a/libc/nt/shell32/RegenerateUserEnvironment.s b/libc/nt/shell32/RegenerateUserEnvironment.s new file mode 100644 index 00000000..56851c0f --- /dev/null +++ b/libc/nt/shell32/RegenerateUserEnvironment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_RegenerateUserEnvironment,RegenerateUserEnvironment,313 diff --git a/libc/nt/shell32/RestartDialog.s b/libc/nt/shell32/RestartDialog.s new file mode 100644 index 00000000..738c1d89 --- /dev/null +++ b/libc/nt/shell32/RestartDialog.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_RestartDialog,RestartDialog,59 diff --git a/libc/nt/shell32/RestartDialogEx.s b/libc/nt/shell32/RestartDialogEx.s new file mode 100644 index 00000000..16fadf48 --- /dev/null +++ b/libc/nt/shell32/RestartDialogEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_RestartDialogEx,RestartDialogEx,730 diff --git a/libc/nt/shell32/RunAsNewUser_RunDLLW.s b/libc/nt/shell32/RunAsNewUser_RunDLLW.s new file mode 100644 index 00000000..9ed51c5d --- /dev/null +++ b/libc/nt/shell32/RunAsNewUser_RunDLLW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_RunAsNewUser_RunDLLW,RunAsNewUser_RunDLLW,314 diff --git a/libc/nt/shell32/SHAddDefaultPropertiesByExt.s b/libc/nt/shell32/SHAddDefaultPropertiesByExt.s new file mode 100644 index 00000000..619ac165 --- /dev/null +++ b/libc/nt/shell32/SHAddDefaultPropertiesByExt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHAddDefaultPropertiesByExt,SHAddDefaultPropertiesByExt,315 diff --git a/libc/nt/shell32/SHAddFromPropSheetExtArray.s b/libc/nt/shell32/SHAddFromPropSheetExtArray.s new file mode 100644 index 00000000..9e68a8ec --- /dev/null +++ b/libc/nt/shell32/SHAddFromPropSheetExtArray.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHAddFromPropSheetExtArray,SHAddFromPropSheetExtArray,167 diff --git a/libc/nt/shell32/SHAddToRecentDocs.s b/libc/nt/shell32/SHAddToRecentDocs.s new file mode 100644 index 00000000..70b66db3 --- /dev/null +++ b/libc/nt/shell32/SHAddToRecentDocs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHAddToRecentDocs,SHAddToRecentDocs,316 diff --git a/libc/nt/shell32/SHAlloc.s b/libc/nt/shell32/SHAlloc.s new file mode 100644 index 00000000..a3f7d019 --- /dev/null +++ b/libc/nt/shell32/SHAlloc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHAlloc,SHAlloc,196 diff --git a/libc/nt/shell32/SHAppBarMessage.s b/libc/nt/shell32/SHAppBarMessage.s new file mode 100644 index 00000000..86b01b4d --- /dev/null +++ b/libc/nt/shell32/SHAppBarMessage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHAppBarMessage,SHAppBarMessage,317 diff --git a/libc/nt/shell32/SHAssocEnumHandlers.s b/libc/nt/shell32/SHAssocEnumHandlers.s new file mode 100644 index 00000000..5019a3ea --- /dev/null +++ b/libc/nt/shell32/SHAssocEnumHandlers.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHAssocEnumHandlers,SHAssocEnumHandlers,318 diff --git a/libc/nt/shell32/SHAssocEnumHandlersForProtocolByApplication.s b/libc/nt/shell32/SHAssocEnumHandlersForProtocolByApplication.s new file mode 100644 index 00000000..d5bce168 --- /dev/null +++ b/libc/nt/shell32/SHAssocEnumHandlersForProtocolByApplication.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHAssocEnumHandlersForProtocolByApplication,SHAssocEnumHandlersForProtocolByApplication,319 diff --git a/libc/nt/shell32/SHBindToFolderIDListParent.s b/libc/nt/shell32/SHBindToFolderIDListParent.s new file mode 100644 index 00000000..1d097884 --- /dev/null +++ b/libc/nt/shell32/SHBindToFolderIDListParent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHBindToFolderIDListParent,SHBindToFolderIDListParent,320 diff --git a/libc/nt/shell32/SHBindToFolderIDListParentEx.s b/libc/nt/shell32/SHBindToFolderIDListParentEx.s new file mode 100644 index 00000000..19d3374f --- /dev/null +++ b/libc/nt/shell32/SHBindToFolderIDListParentEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHBindToFolderIDListParentEx,SHBindToFolderIDListParentEx,321 diff --git a/libc/nt/shell32/SHBindToObject.s b/libc/nt/shell32/SHBindToObject.s new file mode 100644 index 00000000..021ecedd --- /dev/null +++ b/libc/nt/shell32/SHBindToObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHBindToObject,SHBindToObject,322 diff --git a/libc/nt/shell32/SHBindToParent.s b/libc/nt/shell32/SHBindToParent.s new file mode 100644 index 00000000..614c1658 --- /dev/null +++ b/libc/nt/shell32/SHBindToParent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHBindToParent,SHBindToParent,323 diff --git a/libc/nt/shell32/SHBrowseForFolderA.s b/libc/nt/shell32/SHBrowseForFolderA.s new file mode 100644 index 00000000..d0254e68 --- /dev/null +++ b/libc/nt/shell32/SHBrowseForFolderA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHBrowseForFolderA,SHBrowseForFolderA,325 diff --git a/libc/nt/shell32/SHBrowseForFolderW.s b/libc/nt/shell32/SHBrowseForFolderW.s new file mode 100644 index 00000000..036908c6 --- /dev/null +++ b/libc/nt/shell32/SHBrowseForFolderW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHBrowseForFolderW,SHBrowseForFolderW,326 diff --git a/libc/nt/shell32/SHCLSIDFromString.s b/libc/nt/shell32/SHCLSIDFromString.s new file mode 100644 index 00000000..e2c26a1d --- /dev/null +++ b/libc/nt/shell32/SHCLSIDFromString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCLSIDFromString,SHCLSIDFromString,147 diff --git a/libc/nt/shell32/SHChangeNotification_Lock.s b/libc/nt/shell32/SHChangeNotification_Lock.s new file mode 100644 index 00000000..930ef7d4 --- /dev/null +++ b/libc/nt/shell32/SHChangeNotification_Lock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHChangeNotification_Lock,SHChangeNotification_Lock,644 diff --git a/libc/nt/shell32/SHChangeNotification_Unlock.s b/libc/nt/shell32/SHChangeNotification_Unlock.s new file mode 100644 index 00000000..175eca58 --- /dev/null +++ b/libc/nt/shell32/SHChangeNotification_Unlock.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHChangeNotification_Unlock,SHChangeNotification_Unlock,645 diff --git a/libc/nt/shell32/SHChangeNotify.s b/libc/nt/shell32/SHChangeNotify.s new file mode 100644 index 00000000..c15a67b7 --- /dev/null +++ b/libc/nt/shell32/SHChangeNotify.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHChangeNotify,SHChangeNotify,327 diff --git a/libc/nt/shell32/SHChangeNotifyDeregister.s b/libc/nt/shell32/SHChangeNotifyDeregister.s new file mode 100644 index 00000000..96f7d177 --- /dev/null +++ b/libc/nt/shell32/SHChangeNotifyDeregister.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHChangeNotifyDeregister,SHChangeNotifyDeregister,4 diff --git a/libc/nt/shell32/SHChangeNotifyRegister.s b/libc/nt/shell32/SHChangeNotifyRegister.s new file mode 100644 index 00000000..47597afa --- /dev/null +++ b/libc/nt/shell32/SHChangeNotifyRegister.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHChangeNotifyRegister,SHChangeNotifyRegister,2 diff --git a/libc/nt/shell32/SHChangeNotifyRegisterThread.s b/libc/nt/shell32/SHChangeNotifyRegisterThread.s new file mode 100644 index 00000000..43ad789a --- /dev/null +++ b/libc/nt/shell32/SHChangeNotifyRegisterThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHChangeNotifyRegisterThread,SHChangeNotifyRegisterThread,328 diff --git a/libc/nt/shell32/SHChangeNotifySuspendResume.s b/libc/nt/shell32/SHChangeNotifySuspendResume.s new file mode 100644 index 00000000..1a471b3f --- /dev/null +++ b/libc/nt/shell32/SHChangeNotifySuspendResume.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHChangeNotifySuspendResume,SHChangeNotifySuspendResume,329 diff --git a/libc/nt/shell32/SHCloneSpecialIDList.s b/libc/nt/shell32/SHCloneSpecialIDList.s new file mode 100644 index 00000000..db9a143e --- /dev/null +++ b/libc/nt/shell32/SHCloneSpecialIDList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCloneSpecialIDList,SHCloneSpecialIDList,89 diff --git a/libc/nt/shell32/SHCoCreateInstanceWorker.s b/libc/nt/shell32/SHCoCreateInstanceWorker.s new file mode 100644 index 00000000..c1966b0d --- /dev/null +++ b/libc/nt/shell32/SHCoCreateInstanceWorker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCoCreateInstanceWorker,SHCoCreateInstanceWorker,330 diff --git a/libc/nt/shell32/SHCreateAssociationRegistration.s b/libc/nt/shell32/SHCreateAssociationRegistration.s new file mode 100644 index 00000000..28d28529 --- /dev/null +++ b/libc/nt/shell32/SHCreateAssociationRegistration.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateAssociationRegistration,SHCreateAssociationRegistration,331 diff --git a/libc/nt/shell32/SHCreateCategoryEnum.s b/libc/nt/shell32/SHCreateCategoryEnum.s new file mode 100644 index 00000000..11e6a3a8 --- /dev/null +++ b/libc/nt/shell32/SHCreateCategoryEnum.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateCategoryEnum,SHCreateCategoryEnum,332 diff --git a/libc/nt/shell32/SHCreateDataObject.s b/libc/nt/shell32/SHCreateDataObject.s new file mode 100644 index 00000000..a4599eff --- /dev/null +++ b/libc/nt/shell32/SHCreateDataObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateDataObject,SHCreateDataObject,333 diff --git a/libc/nt/shell32/SHCreateDefaultContextMenu.s b/libc/nt/shell32/SHCreateDefaultContextMenu.s new file mode 100644 index 00000000..e955c077 --- /dev/null +++ b/libc/nt/shell32/SHCreateDefaultContextMenu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateDefaultContextMenu,SHCreateDefaultContextMenu,334 diff --git a/libc/nt/shell32/SHCreateDefaultExtractIcon.s b/libc/nt/shell32/SHCreateDefaultExtractIcon.s new file mode 100644 index 00000000..8866eae9 --- /dev/null +++ b/libc/nt/shell32/SHCreateDefaultExtractIcon.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateDefaultExtractIcon,SHCreateDefaultExtractIcon,335 diff --git a/libc/nt/shell32/SHCreateDefaultPropertiesOp.s b/libc/nt/shell32/SHCreateDefaultPropertiesOp.s new file mode 100644 index 00000000..d15642a7 --- /dev/null +++ b/libc/nt/shell32/SHCreateDefaultPropertiesOp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateDefaultPropertiesOp,SHCreateDefaultPropertiesOp,336 diff --git a/libc/nt/shell32/SHCreateDirectory.s b/libc/nt/shell32/SHCreateDirectory.s new file mode 100644 index 00000000..93af6385 --- /dev/null +++ b/libc/nt/shell32/SHCreateDirectory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateDirectory,SHCreateDirectory,165 diff --git a/libc/nt/shell32/SHCreateDirectoryExA.s b/libc/nt/shell32/SHCreateDirectoryExA.s new file mode 100644 index 00000000..27309fd2 --- /dev/null +++ b/libc/nt/shell32/SHCreateDirectoryExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateDirectoryExA,SHCreateDirectoryExA,337 diff --git a/libc/nt/shell32/SHCreateDirectoryExW.s b/libc/nt/shell32/SHCreateDirectoryExW.s new file mode 100644 index 00000000..9509b8cc --- /dev/null +++ b/libc/nt/shell32/SHCreateDirectoryExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateDirectoryExW,SHCreateDirectoryExW,338 diff --git a/libc/nt/shell32/SHCreateDrvExtIcon.s b/libc/nt/shell32/SHCreateDrvExtIcon.s new file mode 100644 index 00000000..53983544 --- /dev/null +++ b/libc/nt/shell32/SHCreateDrvExtIcon.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateDrvExtIcon,SHCreateDrvExtIcon,339 diff --git a/libc/nt/shell32/SHCreateFileExtractIconW.s b/libc/nt/shell32/SHCreateFileExtractIconW.s new file mode 100644 index 00000000..91e0630e --- /dev/null +++ b/libc/nt/shell32/SHCreateFileExtractIconW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateFileExtractIconW,SHCreateFileExtractIconW,743 diff --git a/libc/nt/shell32/SHCreateItemFromIDList.s b/libc/nt/shell32/SHCreateItemFromIDList.s new file mode 100644 index 00000000..a7f99309 --- /dev/null +++ b/libc/nt/shell32/SHCreateItemFromIDList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateItemFromIDList,SHCreateItemFromIDList,340 diff --git a/libc/nt/shell32/SHCreateItemFromParsingName.s b/libc/nt/shell32/SHCreateItemFromParsingName.s new file mode 100644 index 00000000..48725bd9 --- /dev/null +++ b/libc/nt/shell32/SHCreateItemFromParsingName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateItemFromParsingName,SHCreateItemFromParsingName,341 diff --git a/libc/nt/shell32/SHCreateItemFromRelativeName.s b/libc/nt/shell32/SHCreateItemFromRelativeName.s new file mode 100644 index 00000000..d8135b18 --- /dev/null +++ b/libc/nt/shell32/SHCreateItemFromRelativeName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateItemFromRelativeName,SHCreateItemFromRelativeName,342 diff --git a/libc/nt/shell32/SHCreateItemInKnownFolder.s b/libc/nt/shell32/SHCreateItemInKnownFolder.s new file mode 100644 index 00000000..86759813 --- /dev/null +++ b/libc/nt/shell32/SHCreateItemInKnownFolder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateItemInKnownFolder,SHCreateItemInKnownFolder,343 diff --git a/libc/nt/shell32/SHCreateItemWithParent.s b/libc/nt/shell32/SHCreateItemWithParent.s new file mode 100644 index 00000000..a7d3096b --- /dev/null +++ b/libc/nt/shell32/SHCreateItemWithParent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateItemWithParent,SHCreateItemWithParent,344 diff --git a/libc/nt/shell32/SHCreateLocalServerRunDll.s b/libc/nt/shell32/SHCreateLocalServerRunDll.s new file mode 100644 index 00000000..228e1cab --- /dev/null +++ b/libc/nt/shell32/SHCreateLocalServerRunDll.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateLocalServerRunDll,SHCreateLocalServerRunDll,345 diff --git a/libc/nt/shell32/SHCreateProcessAsUserW.s b/libc/nt/shell32/SHCreateProcessAsUserW.s new file mode 100644 index 00000000..08d45e6c --- /dev/null +++ b/libc/nt/shell32/SHCreateProcessAsUserW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateProcessAsUserW,SHCreateProcessAsUserW,346 diff --git a/libc/nt/shell32/SHCreatePropSheetExtArray.s b/libc/nt/shell32/SHCreatePropSheetExtArray.s new file mode 100644 index 00000000..07c81e57 --- /dev/null +++ b/libc/nt/shell32/SHCreatePropSheetExtArray.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreatePropSheetExtArray,SHCreatePropSheetExtArray,168 diff --git a/libc/nt/shell32/SHCreateQueryCancelAutoPlayMoniker.s b/libc/nt/shell32/SHCreateQueryCancelAutoPlayMoniker.s new file mode 100644 index 00000000..e1ec6c21 --- /dev/null +++ b/libc/nt/shell32/SHCreateQueryCancelAutoPlayMoniker.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateQueryCancelAutoPlayMoniker,SHCreateQueryCancelAutoPlayMoniker,347 diff --git a/libc/nt/shell32/SHCreateShellFolderView.s b/libc/nt/shell32/SHCreateShellFolderView.s new file mode 100644 index 00000000..eb433ff0 --- /dev/null +++ b/libc/nt/shell32/SHCreateShellFolderView.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateShellFolderView,SHCreateShellFolderView,256 diff --git a/libc/nt/shell32/SHCreateShellFolderViewEx.s b/libc/nt/shell32/SHCreateShellFolderViewEx.s new file mode 100644 index 00000000..ceee0cc8 --- /dev/null +++ b/libc/nt/shell32/SHCreateShellFolderViewEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateShellFolderViewEx,SHCreateShellFolderViewEx,174 diff --git a/libc/nt/shell32/SHCreateShellItem.s b/libc/nt/shell32/SHCreateShellItem.s new file mode 100644 index 00000000..c95fdc25 --- /dev/null +++ b/libc/nt/shell32/SHCreateShellItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateShellItem,SHCreateShellItem,348 diff --git a/libc/nt/shell32/SHCreateShellItemArray.s b/libc/nt/shell32/SHCreateShellItemArray.s new file mode 100644 index 00000000..8a30d954 --- /dev/null +++ b/libc/nt/shell32/SHCreateShellItemArray.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateShellItemArray,SHCreateShellItemArray,349 diff --git a/libc/nt/shell32/SHCreateShellItemArrayFromDataObject.s b/libc/nt/shell32/SHCreateShellItemArrayFromDataObject.s new file mode 100644 index 00000000..ff5b9dd3 --- /dev/null +++ b/libc/nt/shell32/SHCreateShellItemArrayFromDataObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateShellItemArrayFromDataObject,SHCreateShellItemArrayFromDataObject,350 diff --git a/libc/nt/shell32/SHCreateShellItemArrayFromIDLists.s b/libc/nt/shell32/SHCreateShellItemArrayFromIDLists.s new file mode 100644 index 00000000..70473a05 --- /dev/null +++ b/libc/nt/shell32/SHCreateShellItemArrayFromIDLists.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateShellItemArrayFromIDLists,SHCreateShellItemArrayFromIDLists,351 diff --git a/libc/nt/shell32/SHCreateShellItemArrayFromShellItem.s b/libc/nt/shell32/SHCreateShellItemArrayFromShellItem.s new file mode 100644 index 00000000..bed032c4 --- /dev/null +++ b/libc/nt/shell32/SHCreateShellItemArrayFromShellItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateShellItemArrayFromShellItem,SHCreateShellItemArrayFromShellItem,352 diff --git a/libc/nt/shell32/SHCreateStdEnumFmtEtc.s b/libc/nt/shell32/SHCreateStdEnumFmtEtc.s new file mode 100644 index 00000000..68c60d39 --- /dev/null +++ b/libc/nt/shell32/SHCreateStdEnumFmtEtc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHCreateStdEnumFmtEtc,SHCreateStdEnumFmtEtc,74 diff --git a/libc/nt/shell32/SHDefExtractIconA.s b/libc/nt/shell32/SHDefExtractIconA.s new file mode 100644 index 00000000..bd55e899 --- /dev/null +++ b/libc/nt/shell32/SHDefExtractIconA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHDefExtractIconA,SHDefExtractIconA,3 diff --git a/libc/nt/shell32/SHDefExtractIconW.s b/libc/nt/shell32/SHDefExtractIconW.s new file mode 100644 index 00000000..7b030bea --- /dev/null +++ b/libc/nt/shell32/SHDefExtractIconW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHDefExtractIconW,SHDefExtractIconW,6 diff --git a/libc/nt/shell32/SHDestroyPropSheetExtArray.s b/libc/nt/shell32/SHDestroyPropSheetExtArray.s new file mode 100644 index 00000000..4c9bcdd2 --- /dev/null +++ b/libc/nt/shell32/SHDestroyPropSheetExtArray.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHDestroyPropSheetExtArray,SHDestroyPropSheetExtArray,169 diff --git a/libc/nt/shell32/SHDoDragDrop.s b/libc/nt/shell32/SHDoDragDrop.s new file mode 100644 index 00000000..3ac0a768 --- /dev/null +++ b/libc/nt/shell32/SHDoDragDrop.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHDoDragDrop,SHDoDragDrop,88 diff --git a/libc/nt/shell32/SHELL32_AddToBackIconTable.s b/libc/nt/shell32/SHELL32_AddToBackIconTable.s new file mode 100644 index 00000000..c6a9e93f --- /dev/null +++ b/libc/nt/shell32/SHELL32_AddToBackIconTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_AddToBackIconTable,SHELL32_AddToBackIconTable,353 diff --git a/libc/nt/shell32/SHELL32_AddToFrontIconTable.s b/libc/nt/shell32/SHELL32_AddToFrontIconTable.s new file mode 100644 index 00000000..67823a79 --- /dev/null +++ b/libc/nt/shell32/SHELL32_AddToFrontIconTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_AddToFrontIconTable,SHELL32_AddToFrontIconTable,354 diff --git a/libc/nt/shell32/SHELL32_AreAllItemsAvailable.s b/libc/nt/shell32/SHELL32_AreAllItemsAvailable.s new file mode 100644 index 00000000..1571a62b --- /dev/null +++ b/libc/nt/shell32/SHELL32_AreAllItemsAvailable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_AreAllItemsAvailable,SHELL32_AreAllItemsAvailable,355 diff --git a/libc/nt/shell32/SHELL32_BindToFilePlaceholderHandler.s b/libc/nt/shell32/SHELL32_BindToFilePlaceholderHandler.s new file mode 100644 index 00000000..e4462346 --- /dev/null +++ b/libc/nt/shell32/SHELL32_BindToFilePlaceholderHandler.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_BindToFilePlaceholderHandler,SHELL32_BindToFilePlaceholderHandler,356 diff --git a/libc/nt/shell32/SHELL32_CCommonPlacesFolder_CreateInstance.s b/libc/nt/shell32/SHELL32_CCommonPlacesFolder_CreateInstance.s new file mode 100644 index 00000000..7efc1dde --- /dev/null +++ b/libc/nt/shell32/SHELL32_CCommonPlacesFolder_CreateInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CCommonPlacesFolder_CreateInstance,SHELL32_CCommonPlacesFolder_CreateInstance,357 diff --git a/libc/nt/shell32/SHELL32_CDBurn_CloseSession.s b/libc/nt/shell32/SHELL32_CDBurn_CloseSession.s new file mode 100644 index 00000000..e89ebdff --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDBurn_CloseSession.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDBurn_CloseSession,SHELL32_CDBurn_CloseSession,358 diff --git a/libc/nt/shell32/SHELL32_CDBurn_DriveSupportedForDataBurn.s b/libc/nt/shell32/SHELL32_CDBurn_DriveSupportedForDataBurn.s new file mode 100644 index 00000000..2001dee8 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDBurn_DriveSupportedForDataBurn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDBurn_DriveSupportedForDataBurn,SHELL32_CDBurn_DriveSupportedForDataBurn,359 diff --git a/libc/nt/shell32/SHELL32_CDBurn_Erase.s b/libc/nt/shell32/SHELL32_CDBurn_Erase.s new file mode 100644 index 00000000..b06330f6 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDBurn_Erase.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDBurn_Erase,SHELL32_CDBurn_Erase,360 diff --git a/libc/nt/shell32/SHELL32_CDBurn_GetCDInfo.s b/libc/nt/shell32/SHELL32_CDBurn_GetCDInfo.s new file mode 100644 index 00000000..2bd2f291 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDBurn_GetCDInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDBurn_GetCDInfo,SHELL32_CDBurn_GetCDInfo,361 diff --git a/libc/nt/shell32/SHELL32_CDBurn_GetLiveFSDiscInfo.s b/libc/nt/shell32/SHELL32_CDBurn_GetLiveFSDiscInfo.s new file mode 100644 index 00000000..c6b120a7 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDBurn_GetLiveFSDiscInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDBurn_GetLiveFSDiscInfo,SHELL32_CDBurn_GetLiveFSDiscInfo,362 diff --git a/libc/nt/shell32/SHELL32_CDBurn_GetStagingPathOrNormalPath.s b/libc/nt/shell32/SHELL32_CDBurn_GetStagingPathOrNormalPath.s new file mode 100644 index 00000000..c8023799 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDBurn_GetStagingPathOrNormalPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDBurn_GetStagingPathOrNormalPath,SHELL32_CDBurn_GetStagingPathOrNormalPath,363 diff --git a/libc/nt/shell32/SHELL32_CDBurn_GetTaskInfo.s b/libc/nt/shell32/SHELL32_CDBurn_GetTaskInfo.s new file mode 100644 index 00000000..06e955b1 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDBurn_GetTaskInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDBurn_GetTaskInfo,SHELL32_CDBurn_GetTaskInfo,364 diff --git a/libc/nt/shell32/SHELL32_CDBurn_IsBlankDisc.s b/libc/nt/shell32/SHELL32_CDBurn_IsBlankDisc.s new file mode 100644 index 00000000..276ed379 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDBurn_IsBlankDisc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDBurn_IsBlankDisc,SHELL32_CDBurn_IsBlankDisc,365 diff --git a/libc/nt/shell32/SHELL32_CDBurn_IsBlankDisc2.s b/libc/nt/shell32/SHELL32_CDBurn_IsBlankDisc2.s new file mode 100644 index 00000000..07be7099 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDBurn_IsBlankDisc2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDBurn_IsBlankDisc2,SHELL32_CDBurn_IsBlankDisc2,366 diff --git a/libc/nt/shell32/SHELL32_CDBurn_IsLiveFS.s b/libc/nt/shell32/SHELL32_CDBurn_IsLiveFS.s new file mode 100644 index 00000000..a34ee644 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDBurn_IsLiveFS.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDBurn_IsLiveFS,SHELL32_CDBurn_IsLiveFS,367 diff --git a/libc/nt/shell32/SHELL32_CDBurn_OnDeviceChange.s b/libc/nt/shell32/SHELL32_CDBurn_OnDeviceChange.s new file mode 100644 index 00000000..59970ec4 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDBurn_OnDeviceChange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDBurn_OnDeviceChange,SHELL32_CDBurn_OnDeviceChange,368 diff --git a/libc/nt/shell32/SHELL32_CDBurn_OnEject.s b/libc/nt/shell32/SHELL32_CDBurn_OnEject.s new file mode 100644 index 00000000..fd045efa --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDBurn_OnEject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDBurn_OnEject,SHELL32_CDBurn_OnEject,369 diff --git a/libc/nt/shell32/SHELL32_CDBurn_OnMediaChange.s b/libc/nt/shell32/SHELL32_CDBurn_OnMediaChange.s new file mode 100644 index 00000000..cd9e0056 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDBurn_OnMediaChange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDBurn_OnMediaChange,SHELL32_CDBurn_OnMediaChange,370 diff --git a/libc/nt/shell32/SHELL32_CDefFolderMenu_Create2.s b/libc/nt/shell32/SHELL32_CDefFolderMenu_Create2.s new file mode 100644 index 00000000..f80d1763 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDefFolderMenu_Create2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDefFolderMenu_Create2,SHELL32_CDefFolderMenu_Create2,371 diff --git a/libc/nt/shell32/SHELL32_CDefFolderMenu_Create2Ex.s b/libc/nt/shell32/SHELL32_CDefFolderMenu_Create2Ex.s new file mode 100644 index 00000000..3cc86886 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDefFolderMenu_Create2Ex.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDefFolderMenu_Create2Ex,SHELL32_CDefFolderMenu_Create2Ex,372 diff --git a/libc/nt/shell32/SHELL32_CDefFolderMenu_MergeMenu.s b/libc/nt/shell32/SHELL32_CDefFolderMenu_MergeMenu.s new file mode 100644 index 00000000..b7ec9c44 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDefFolderMenu_MergeMenu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDefFolderMenu_MergeMenu,SHELL32_CDefFolderMenu_MergeMenu,373 diff --git a/libc/nt/shell32/SHELL32_CDrivesContextMenu_Create.s b/libc/nt/shell32/SHELL32_CDrivesContextMenu_Create.s new file mode 100644 index 00000000..b7c09407 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDrivesContextMenu_Create.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDrivesContextMenu_Create,SHELL32_CDrivesContextMenu_Create,374 diff --git a/libc/nt/shell32/SHELL32_CDrivesDropTarget_Create.s b/libc/nt/shell32/SHELL32_CDrivesDropTarget_Create.s new file mode 100644 index 00000000..c072222a --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDrivesDropTarget_Create.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDrivesDropTarget_Create,SHELL32_CDrivesDropTarget_Create,375 diff --git a/libc/nt/shell32/SHELL32_CDrives_CreateSFVCB.s b/libc/nt/shell32/SHELL32_CDrives_CreateSFVCB.s new file mode 100644 index 00000000..c0521b2c --- /dev/null +++ b/libc/nt/shell32/SHELL32_CDrives_CreateSFVCB.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CDrives_CreateSFVCB,SHELL32_CDrives_CreateSFVCB,376 diff --git a/libc/nt/shell32/SHELL32_CFSDropTarget_CreateInstance.s b/libc/nt/shell32/SHELL32_CFSDropTarget_CreateInstance.s new file mode 100644 index 00000000..b5eba867 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CFSDropTarget_CreateInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CFSDropTarget_CreateInstance,SHELL32_CFSDropTarget_CreateInstance,377 diff --git a/libc/nt/shell32/SHELL32_CFSFolderCallback_Create.s b/libc/nt/shell32/SHELL32_CFSFolderCallback_Create.s new file mode 100644 index 00000000..149a25d7 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CFSFolderCallback_Create.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CFSFolderCallback_Create,SHELL32_CFSFolderCallback_Create,378 diff --git a/libc/nt/shell32/SHELL32_CFillPropertiesTask_CreateInstance.s b/libc/nt/shell32/SHELL32_CFillPropertiesTask_CreateInstance.s new file mode 100644 index 00000000..2688fd5f --- /dev/null +++ b/libc/nt/shell32/SHELL32_CFillPropertiesTask_CreateInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CFillPropertiesTask_CreateInstance,SHELL32_CFillPropertiesTask_CreateInstance,379 diff --git a/libc/nt/shell32/SHELL32_CLibraryDropTarget_CreateInstance.s b/libc/nt/shell32/SHELL32_CLibraryDropTarget_CreateInstance.s new file mode 100644 index 00000000..60cdf7b3 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CLibraryDropTarget_CreateInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CLibraryDropTarget_CreateInstance,SHELL32_CLibraryDropTarget_CreateInstance,380 diff --git a/libc/nt/shell32/SHELL32_CLocationContextMenu_Create.s b/libc/nt/shell32/SHELL32_CLocationContextMenu_Create.s new file mode 100644 index 00000000..fa30c2c5 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CLocationContextMenu_Create.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CLocationContextMenu_Create,SHELL32_CLocationContextMenu_Create,381 diff --git a/libc/nt/shell32/SHELL32_CLocationFolderUI_CreateInstance.s b/libc/nt/shell32/SHELL32_CLocationFolderUI_CreateInstance.s new file mode 100644 index 00000000..b51ce2d6 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CLocationFolderUI_CreateInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CLocationFolderUI_CreateInstance,SHELL32_CLocationFolderUI_CreateInstance,382 diff --git a/libc/nt/shell32/SHELL32_CMountPoint_DoAutorun.s b/libc/nt/shell32/SHELL32_CMountPoint_DoAutorun.s new file mode 100644 index 00000000..ffa76fe8 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CMountPoint_DoAutorun.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CMountPoint_DoAutorun,SHELL32_CMountPoint_DoAutorun,383 diff --git a/libc/nt/shell32/SHELL32_CMountPoint_DoAutorunPrompt.s b/libc/nt/shell32/SHELL32_CMountPoint_DoAutorunPrompt.s new file mode 100644 index 00000000..2f09b8a8 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CMountPoint_DoAutorunPrompt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CMountPoint_DoAutorunPrompt,SHELL32_CMountPoint_DoAutorunPrompt,384 diff --git a/libc/nt/shell32/SHELL32_CMountPoint_IsAutoRunDriveAndEnabledByPolicy.s b/libc/nt/shell32/SHELL32_CMountPoint_IsAutoRunDriveAndEnabledByPolicy.s new file mode 100644 index 00000000..8ec67fdf --- /dev/null +++ b/libc/nt/shell32/SHELL32_CMountPoint_IsAutoRunDriveAndEnabledByPolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CMountPoint_IsAutoRunDriveAndEnabledByPolicy,SHELL32_CMountPoint_IsAutoRunDriveAndEnabledByPolicy,385 diff --git a/libc/nt/shell32/SHELL32_CMountPoint_ProcessAutoRunFile.s b/libc/nt/shell32/SHELL32_CMountPoint_ProcessAutoRunFile.s new file mode 100644 index 00000000..5b6d71cd --- /dev/null +++ b/libc/nt/shell32/SHELL32_CMountPoint_ProcessAutoRunFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CMountPoint_ProcessAutoRunFile,SHELL32_CMountPoint_ProcessAutoRunFile,386 diff --git a/libc/nt/shell32/SHELL32_CMountPoint_WantAutorunUI.s b/libc/nt/shell32/SHELL32_CMountPoint_WantAutorunUI.s new file mode 100644 index 00000000..1816777c --- /dev/null +++ b/libc/nt/shell32/SHELL32_CMountPoint_WantAutorunUI.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CMountPoint_WantAutorunUI,SHELL32_CMountPoint_WantAutorunUI,387 diff --git a/libc/nt/shell32/SHELL32_CMountPoint_WantAutorunUIGetReady.s b/libc/nt/shell32/SHELL32_CMountPoint_WantAutorunUIGetReady.s new file mode 100644 index 00000000..f607c484 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CMountPoint_WantAutorunUIGetReady.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CMountPoint_WantAutorunUIGetReady,SHELL32_CMountPoint_WantAutorunUIGetReady,388 diff --git a/libc/nt/shell32/SHELL32_CPL_CategoryIdArrayFromVariant.s b/libc/nt/shell32/SHELL32_CPL_CategoryIdArrayFromVariant.s new file mode 100644 index 00000000..61e0b55e --- /dev/null +++ b/libc/nt/shell32/SHELL32_CPL_CategoryIdArrayFromVariant.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CPL_CategoryIdArrayFromVariant,SHELL32_CPL_CategoryIdArrayFromVariant,389 diff --git a/libc/nt/shell32/SHELL32_CPL_IsLegacyCanonicalNameListedUnderKey.s b/libc/nt/shell32/SHELL32_CPL_IsLegacyCanonicalNameListedUnderKey.s new file mode 100644 index 00000000..e75eae81 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CPL_IsLegacyCanonicalNameListedUnderKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CPL_IsLegacyCanonicalNameListedUnderKey,SHELL32_CPL_IsLegacyCanonicalNameListedUnderKey,390 diff --git a/libc/nt/shell32/SHELL32_CPL_ModifyWowDisplayName.s b/libc/nt/shell32/SHELL32_CPL_ModifyWowDisplayName.s new file mode 100644 index 00000000..a94e10a9 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CPL_ModifyWowDisplayName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CPL_ModifyWowDisplayName,SHELL32_CPL_ModifyWowDisplayName,391 diff --git a/libc/nt/shell32/SHELL32_CRecentDocsContextMenu_CreateInstance.s b/libc/nt/shell32/SHELL32_CRecentDocsContextMenu_CreateInstance.s new file mode 100644 index 00000000..72b40362 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CRecentDocsContextMenu_CreateInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CRecentDocsContextMenu_CreateInstance,SHELL32_CRecentDocsContextMenu_CreateInstance,392 diff --git a/libc/nt/shell32/SHELL32_CSyncRootManager_CreateInstance.s b/libc/nt/shell32/SHELL32_CSyncRootManager_CreateInstance.s new file mode 100644 index 00000000..ba58b701 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CSyncRootManager_CreateInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CSyncRootManager_CreateInstance,SHELL32_CSyncRootManager_CreateInstance,393 diff --git a/libc/nt/shell32/SHELL32_CTransferConfirmation_CreateInstance.s b/libc/nt/shell32/SHELL32_CTransferConfirmation_CreateInstance.s new file mode 100644 index 00000000..be45e05c --- /dev/null +++ b/libc/nt/shell32/SHELL32_CTransferConfirmation_CreateInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CTransferConfirmation_CreateInstance,SHELL32_CTransferConfirmation_CreateInstance,394 diff --git a/libc/nt/shell32/SHELL32_CallFileCopyHooks.s b/libc/nt/shell32/SHELL32_CallFileCopyHooks.s new file mode 100644 index 00000000..0f1c6c8b --- /dev/null +++ b/libc/nt/shell32/SHELL32_CallFileCopyHooks.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CallFileCopyHooks,SHELL32_CallFileCopyHooks,395 diff --git a/libc/nt/shell32/SHELL32_CanDisplayWin8CopyDialog.s b/libc/nt/shell32/SHELL32_CanDisplayWin8CopyDialog.s new file mode 100644 index 00000000..3bc28413 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CanDisplayWin8CopyDialog.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CanDisplayWin8CopyDialog,SHELL32_CanDisplayWin8CopyDialog,396 diff --git a/libc/nt/shell32/SHELL32_CloseAutoplayPrompt.s b/libc/nt/shell32/SHELL32_CloseAutoplayPrompt.s new file mode 100644 index 00000000..a13aec03 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CloseAutoplayPrompt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CloseAutoplayPrompt,SHELL32_CloseAutoplayPrompt,397 diff --git a/libc/nt/shell32/SHELL32_CommandLineFromMsiDescriptor.s b/libc/nt/shell32/SHELL32_CommandLineFromMsiDescriptor.s new file mode 100644 index 00000000..4fb32148 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CommandLineFromMsiDescriptor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CommandLineFromMsiDescriptor,SHELL32_CommandLineFromMsiDescriptor,398 diff --git a/libc/nt/shell32/SHELL32_CopyFilePlaceholderToNewFile.s b/libc/nt/shell32/SHELL32_CopyFilePlaceholderToNewFile.s new file mode 100644 index 00000000..341cfeba --- /dev/null +++ b/libc/nt/shell32/SHELL32_CopyFilePlaceholderToNewFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CopyFilePlaceholderToNewFile,SHELL32_CopyFilePlaceholderToNewFile,399 diff --git a/libc/nt/shell32/SHELL32_CopySecondaryTiles.s b/libc/nt/shell32/SHELL32_CopySecondaryTiles.s new file mode 100644 index 00000000..445cc144 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CopySecondaryTiles.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CopySecondaryTiles,SHELL32_CopySecondaryTiles,400 diff --git a/libc/nt/shell32/SHELL32_CreateConfirmationInterrupt.s b/libc/nt/shell32/SHELL32_CreateConfirmationInterrupt.s new file mode 100644 index 00000000..1545afe8 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CreateConfirmationInterrupt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CreateConfirmationInterrupt,SHELL32_CreateConfirmationInterrupt,401 diff --git a/libc/nt/shell32/SHELL32_CreateConflictInterrupt.s b/libc/nt/shell32/SHELL32_CreateConflictInterrupt.s new file mode 100644 index 00000000..8d56bf46 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CreateConflictInterrupt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CreateConflictInterrupt,SHELL32_CreateConflictInterrupt,402 diff --git a/libc/nt/shell32/SHELL32_CreateDefaultOperationDataProvider.s b/libc/nt/shell32/SHELL32_CreateDefaultOperationDataProvider.s new file mode 100644 index 00000000..de973b39 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CreateDefaultOperationDataProvider.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CreateDefaultOperationDataProvider,SHELL32_CreateDefaultOperationDataProvider,403 diff --git a/libc/nt/shell32/SHELL32_CreateFileFolderContextMenu.s b/libc/nt/shell32/SHELL32_CreateFileFolderContextMenu.s new file mode 100644 index 00000000..a2ed8615 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CreateFileFolderContextMenu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CreateFileFolderContextMenu,SHELL32_CreateFileFolderContextMenu,404 diff --git a/libc/nt/shell32/SHELL32_CreateLinkInfoW.s b/libc/nt/shell32/SHELL32_CreateLinkInfoW.s new file mode 100644 index 00000000..bc03f8b2 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CreateLinkInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CreateLinkInfoW,SHELL32_CreateLinkInfoW,405 diff --git a/libc/nt/shell32/SHELL32_CreatePlaceholderFile.s b/libc/nt/shell32/SHELL32_CreatePlaceholderFile.s new file mode 100644 index 00000000..7e064758 --- /dev/null +++ b/libc/nt/shell32/SHELL32_CreatePlaceholderFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CreatePlaceholderFile,SHELL32_CreatePlaceholderFile,406 diff --git a/libc/nt/shell32/SHELL32_CreateQosRecorder.s b/libc/nt/shell32/SHELL32_CreateQosRecorder.s new file mode 100644 index 00000000..94b47b6f --- /dev/null +++ b/libc/nt/shell32/SHELL32_CreateQosRecorder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CreateQosRecorder,SHELL32_CreateQosRecorder,407 diff --git a/libc/nt/shell32/SHELL32_CreateSharePointView.s b/libc/nt/shell32/SHELL32_CreateSharePointView.s new file mode 100644 index 00000000..9fcda67b --- /dev/null +++ b/libc/nt/shell32/SHELL32_CreateSharePointView.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_CreateSharePointView,SHELL32_CreateSharePointView,408 diff --git a/libc/nt/shell32/SHELL32_Create_IEnumUICommand.s b/libc/nt/shell32/SHELL32_Create_IEnumUICommand.s new file mode 100644 index 00000000..47ed45ac --- /dev/null +++ b/libc/nt/shell32/SHELL32_Create_IEnumUICommand.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_Create_IEnumUICommand,SHELL32_Create_IEnumUICommand,409 diff --git a/libc/nt/shell32/SHELL32_DestroyLinkInfo.s b/libc/nt/shell32/SHELL32_DestroyLinkInfo.s new file mode 100644 index 00000000..dcce08f6 --- /dev/null +++ b/libc/nt/shell32/SHELL32_DestroyLinkInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_DestroyLinkInfo,SHELL32_DestroyLinkInfo,410 diff --git a/libc/nt/shell32/SHELL32_EncryptDirectory.s b/libc/nt/shell32/SHELL32_EncryptDirectory.s new file mode 100644 index 00000000..a834c631 --- /dev/null +++ b/libc/nt/shell32/SHELL32_EncryptDirectory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_EncryptDirectory,SHELL32_EncryptDirectory,411 diff --git a/libc/nt/shell32/SHELL32_EncryptedFileKeyInfo.s b/libc/nt/shell32/SHELL32_EncryptedFileKeyInfo.s new file mode 100644 index 00000000..9f30cc10 --- /dev/null +++ b/libc/nt/shell32/SHELL32_EncryptedFileKeyInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_EncryptedFileKeyInfo,SHELL32_EncryptedFileKeyInfo,412 diff --git a/libc/nt/shell32/SHELL32_EnumCommonTasks.s b/libc/nt/shell32/SHELL32_EnumCommonTasks.s new file mode 100644 index 00000000..dbd2fe7f --- /dev/null +++ b/libc/nt/shell32/SHELL32_EnumCommonTasks.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_EnumCommonTasks,SHELL32_EnumCommonTasks,413 diff --git a/libc/nt/shell32/SHELL32_FilePlaceholder_BindToPrimaryStream.s b/libc/nt/shell32/SHELL32_FilePlaceholder_BindToPrimaryStream.s new file mode 100644 index 00000000..bfb8e80d --- /dev/null +++ b/libc/nt/shell32/SHELL32_FilePlaceholder_BindToPrimaryStream.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_FilePlaceholder_BindToPrimaryStream,SHELL32_FilePlaceholder_BindToPrimaryStream,414 diff --git a/libc/nt/shell32/SHELL32_FilePlaceholder_CreateInstance.s b/libc/nt/shell32/SHELL32_FilePlaceholder_CreateInstance.s new file mode 100644 index 00000000..c4876c4a --- /dev/null +++ b/libc/nt/shell32/SHELL32_FilePlaceholder_CreateInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_FilePlaceholder_CreateInstance,SHELL32_FilePlaceholder_CreateInstance,415 diff --git a/libc/nt/shell32/SHELL32_FreeEncryptedFileKeyInfo.s b/libc/nt/shell32/SHELL32_FreeEncryptedFileKeyInfo.s new file mode 100644 index 00000000..21b1a7ca --- /dev/null +++ b/libc/nt/shell32/SHELL32_FreeEncryptedFileKeyInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_FreeEncryptedFileKeyInfo,SHELL32_FreeEncryptedFileKeyInfo,416 diff --git a/libc/nt/shell32/SHELL32_GenerateAppID.s b/libc/nt/shell32/SHELL32_GenerateAppID.s new file mode 100644 index 00000000..377d0bd3 --- /dev/null +++ b/libc/nt/shell32/SHELL32_GenerateAppID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_GenerateAppID,SHELL32_GenerateAppID,417 diff --git a/libc/nt/shell32/SHELL32_GetAppIDRoot.s b/libc/nt/shell32/SHELL32_GetAppIDRoot.s new file mode 100644 index 00000000..b950019a --- /dev/null +++ b/libc/nt/shell32/SHELL32_GetAppIDRoot.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_GetAppIDRoot,SHELL32_GetAppIDRoot,418 diff --git a/libc/nt/shell32/SHELL32_GetCommandProviderForFolderType.s b/libc/nt/shell32/SHELL32_GetCommandProviderForFolderType.s new file mode 100644 index 00000000..eb970bbe --- /dev/null +++ b/libc/nt/shell32/SHELL32_GetCommandProviderForFolderType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_GetCommandProviderForFolderType,SHELL32_GetCommandProviderForFolderType,419 diff --git a/libc/nt/shell32/SHELL32_GetDPIAdjustedLogicalSize.s b/libc/nt/shell32/SHELL32_GetDPIAdjustedLogicalSize.s new file mode 100644 index 00000000..e2b7c85e --- /dev/null +++ b/libc/nt/shell32/SHELL32_GetDPIAdjustedLogicalSize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_GetDPIAdjustedLogicalSize,SHELL32_GetDPIAdjustedLogicalSize,420 diff --git a/libc/nt/shell32/SHELL32_GetDiskCleanupPath.s b/libc/nt/shell32/SHELL32_GetDiskCleanupPath.s new file mode 100644 index 00000000..da917cd6 --- /dev/null +++ b/libc/nt/shell32/SHELL32_GetDiskCleanupPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_GetDiskCleanupPath,SHELL32_GetDiskCleanupPath,421 diff --git a/libc/nt/shell32/SHELL32_GetFileNameFromBrowse.s b/libc/nt/shell32/SHELL32_GetFileNameFromBrowse.s new file mode 100644 index 00000000..a3d56cce --- /dev/null +++ b/libc/nt/shell32/SHELL32_GetFileNameFromBrowse.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_GetFileNameFromBrowse,SHELL32_GetFileNameFromBrowse,422 diff --git a/libc/nt/shell32/SHELL32_GetIconOverlayManager.s b/libc/nt/shell32/SHELL32_GetIconOverlayManager.s new file mode 100644 index 00000000..fdb01620 --- /dev/null +++ b/libc/nt/shell32/SHELL32_GetIconOverlayManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_GetIconOverlayManager,SHELL32_GetIconOverlayManager,423 diff --git a/libc/nt/shell32/SHELL32_GetLinkInfoData.s b/libc/nt/shell32/SHELL32_GetLinkInfoData.s new file mode 100644 index 00000000..37e3689f --- /dev/null +++ b/libc/nt/shell32/SHELL32_GetLinkInfoData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_GetLinkInfoData,SHELL32_GetLinkInfoData,424 diff --git a/libc/nt/shell32/SHELL32_GetPlaceholderStatesFromFileAttributesAndReparsePointTag.s b/libc/nt/shell32/SHELL32_GetPlaceholderStatesFromFileAttributesAndReparsePointTag.s new file mode 100644 index 00000000..eeff03da --- /dev/null +++ b/libc/nt/shell32/SHELL32_GetPlaceholderStatesFromFileAttributesAndReparsePointTag.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_GetPlaceholderStatesFromFileAttributesAndReparsePointTag,SHELL32_GetPlaceholderStatesFromFileAttributesAndReparsePointTag,425 diff --git a/libc/nt/shell32/SHELL32_GetRatingBucket.s b/libc/nt/shell32/SHELL32_GetRatingBucket.s new file mode 100644 index 00000000..fdf5e3d6 --- /dev/null +++ b/libc/nt/shell32/SHELL32_GetRatingBucket.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_GetRatingBucket,SHELL32_GetRatingBucket,426 diff --git a/libc/nt/shell32/SHELL32_GetSkyDriveNetworkStates.s b/libc/nt/shell32/SHELL32_GetSkyDriveNetworkStates.s new file mode 100644 index 00000000..90faa199 --- /dev/null +++ b/libc/nt/shell32/SHELL32_GetSkyDriveNetworkStates.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_GetSkyDriveNetworkStates,SHELL32_GetSkyDriveNetworkStates,427 diff --git a/libc/nt/shell32/SHELL32_GetSqmableFileName.s b/libc/nt/shell32/SHELL32_GetSqmableFileName.s new file mode 100644 index 00000000..8d23e381 --- /dev/null +++ b/libc/nt/shell32/SHELL32_GetSqmableFileName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_GetSqmableFileName,SHELL32_GetSqmableFileName,428 diff --git a/libc/nt/shell32/SHELL32_GetThumbnailAdornerFromFactory.s b/libc/nt/shell32/SHELL32_GetThumbnailAdornerFromFactory.s new file mode 100644 index 00000000..8254bc2f --- /dev/null +++ b/libc/nt/shell32/SHELL32_GetThumbnailAdornerFromFactory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_GetThumbnailAdornerFromFactory,SHELL32_GetThumbnailAdornerFromFactory,429 diff --git a/libc/nt/shell32/SHELL32_GetThumbnailAdornerFromFactory2.s b/libc/nt/shell32/SHELL32_GetThumbnailAdornerFromFactory2.s new file mode 100644 index 00000000..b3e16ac0 --- /dev/null +++ b/libc/nt/shell32/SHELL32_GetThumbnailAdornerFromFactory2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_GetThumbnailAdornerFromFactory2,SHELL32_GetThumbnailAdornerFromFactory2,430 diff --git a/libc/nt/shell32/SHELL32_HandleUnrecognizedFileSystem.s b/libc/nt/shell32/SHELL32_HandleUnrecognizedFileSystem.s new file mode 100644 index 00000000..a61f7e23 --- /dev/null +++ b/libc/nt/shell32/SHELL32_HandleUnrecognizedFileSystem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_HandleUnrecognizedFileSystem,SHELL32_HandleUnrecognizedFileSystem,431 diff --git a/libc/nt/shell32/SHELL32_IconCacheCreate.s b/libc/nt/shell32/SHELL32_IconCacheCreate.s new file mode 100644 index 00000000..4f20016f --- /dev/null +++ b/libc/nt/shell32/SHELL32_IconCacheCreate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_IconCacheCreate,SHELL32_IconCacheCreate,432 diff --git a/libc/nt/shell32/SHELL32_IconCacheDestroy.s b/libc/nt/shell32/SHELL32_IconCacheDestroy.s new file mode 100644 index 00000000..0572b4ac --- /dev/null +++ b/libc/nt/shell32/SHELL32_IconCacheDestroy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_IconCacheDestroy,SHELL32_IconCacheDestroy,433 diff --git a/libc/nt/shell32/SHELL32_IconCacheHandleAssociationChanged.s b/libc/nt/shell32/SHELL32_IconCacheHandleAssociationChanged.s new file mode 100644 index 00000000..f7aca4f6 --- /dev/null +++ b/libc/nt/shell32/SHELL32_IconCacheHandleAssociationChanged.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_IconCacheHandleAssociationChanged,SHELL32_IconCacheHandleAssociationChanged,434 diff --git a/libc/nt/shell32/SHELL32_IconCacheRestore.s b/libc/nt/shell32/SHELL32_IconCacheRestore.s new file mode 100644 index 00000000..45f9c85c --- /dev/null +++ b/libc/nt/shell32/SHELL32_IconCacheRestore.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_IconCacheRestore,SHELL32_IconCacheRestore,435 diff --git a/libc/nt/shell32/SHELL32_IconCache_AboutToExtractIcons.s b/libc/nt/shell32/SHELL32_IconCache_AboutToExtractIcons.s new file mode 100644 index 00000000..791de087 --- /dev/null +++ b/libc/nt/shell32/SHELL32_IconCache_AboutToExtractIcons.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_IconCache_AboutToExtractIcons,SHELL32_IconCache_AboutToExtractIcons,436 diff --git a/libc/nt/shell32/SHELL32_IconCache_DoneExtractingIcons.s b/libc/nt/shell32/SHELL32_IconCache_DoneExtractingIcons.s new file mode 100644 index 00000000..957fa189 --- /dev/null +++ b/libc/nt/shell32/SHELL32_IconCache_DoneExtractingIcons.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_IconCache_DoneExtractingIcons,SHELL32_IconCache_DoneExtractingIcons,437 diff --git a/libc/nt/shell32/SHELL32_IconCache_ExpandEnvAndSearchPath.s b/libc/nt/shell32/SHELL32_IconCache_ExpandEnvAndSearchPath.s new file mode 100644 index 00000000..e43425f6 --- /dev/null +++ b/libc/nt/shell32/SHELL32_IconCache_ExpandEnvAndSearchPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_IconCache_ExpandEnvAndSearchPath,SHELL32_IconCache_ExpandEnvAndSearchPath,438 diff --git a/libc/nt/shell32/SHELL32_IconCache_RememberRecentlyExtractedIconsW.s b/libc/nt/shell32/SHELL32_IconCache_RememberRecentlyExtractedIconsW.s new file mode 100644 index 00000000..af4b8d36 --- /dev/null +++ b/libc/nt/shell32/SHELL32_IconCache_RememberRecentlyExtractedIconsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_IconCache_RememberRecentlyExtractedIconsW,SHELL32_IconCache_RememberRecentlyExtractedIconsW,439 diff --git a/libc/nt/shell32/SHELL32_IconOverlayManagerInit.s b/libc/nt/shell32/SHELL32_IconOverlayManagerInit.s new file mode 100644 index 00000000..65c0e3fc --- /dev/null +++ b/libc/nt/shell32/SHELL32_IconOverlayManagerInit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_IconOverlayManagerInit,SHELL32_IconOverlayManagerInit,440 diff --git a/libc/nt/shell32/SHELL32_IsGetKeyboardLayoutPresent.s b/libc/nt/shell32/SHELL32_IsGetKeyboardLayoutPresent.s new file mode 100644 index 00000000..3bc3dba7 --- /dev/null +++ b/libc/nt/shell32/SHELL32_IsGetKeyboardLayoutPresent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_IsGetKeyboardLayoutPresent,SHELL32_IsGetKeyboardLayoutPresent,441 diff --git a/libc/nt/shell32/SHELL32_IsSystemUpgradeInProgress.s b/libc/nt/shell32/SHELL32_IsSystemUpgradeInProgress.s new file mode 100644 index 00000000..936628f5 --- /dev/null +++ b/libc/nt/shell32/SHELL32_IsSystemUpgradeInProgress.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_IsSystemUpgradeInProgress,SHELL32_IsSystemUpgradeInProgress,442 diff --git a/libc/nt/shell32/SHELL32_IsValidLinkInfo.s b/libc/nt/shell32/SHELL32_IsValidLinkInfo.s new file mode 100644 index 00000000..2f7035a5 --- /dev/null +++ b/libc/nt/shell32/SHELL32_IsValidLinkInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_IsValidLinkInfo,SHELL32_IsValidLinkInfo,443 diff --git a/libc/nt/shell32/SHELL32_LegacyEnumSpecialTasksByType.s b/libc/nt/shell32/SHELL32_LegacyEnumSpecialTasksByType.s new file mode 100644 index 00000000..e05b207c --- /dev/null +++ b/libc/nt/shell32/SHELL32_LegacyEnumSpecialTasksByType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_LegacyEnumSpecialTasksByType,SHELL32_LegacyEnumSpecialTasksByType,444 diff --git a/libc/nt/shell32/SHELL32_LegacyEnumTasks.s b/libc/nt/shell32/SHELL32_LegacyEnumTasks.s new file mode 100644 index 00000000..d1f42c7b --- /dev/null +++ b/libc/nt/shell32/SHELL32_LegacyEnumTasks.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_LegacyEnumTasks,SHELL32_LegacyEnumTasks,445 diff --git a/libc/nt/shell32/SHELL32_LookupBackIconIndex.s b/libc/nt/shell32/SHELL32_LookupBackIconIndex.s new file mode 100644 index 00000000..35b87ad7 --- /dev/null +++ b/libc/nt/shell32/SHELL32_LookupBackIconIndex.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_LookupBackIconIndex,SHELL32_LookupBackIconIndex,446 diff --git a/libc/nt/shell32/SHELL32_LookupFrontIconIndex.s b/libc/nt/shell32/SHELL32_LookupFrontIconIndex.s new file mode 100644 index 00000000..49b18e3e --- /dev/null +++ b/libc/nt/shell32/SHELL32_LookupFrontIconIndex.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_LookupFrontIconIndex,SHELL32_LookupFrontIconIndex,447 diff --git a/libc/nt/shell32/SHELL32_NormalizeRating.s b/libc/nt/shell32/SHELL32_NormalizeRating.s new file mode 100644 index 00000000..3b845be4 --- /dev/null +++ b/libc/nt/shell32/SHELL32_NormalizeRating.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_NormalizeRating,SHELL32_NormalizeRating,448 diff --git a/libc/nt/shell32/SHELL32_NotifyLinkTrackingServiceOfMove.s b/libc/nt/shell32/SHELL32_NotifyLinkTrackingServiceOfMove.s new file mode 100644 index 00000000..a5b6e060 --- /dev/null +++ b/libc/nt/shell32/SHELL32_NotifyLinkTrackingServiceOfMove.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_NotifyLinkTrackingServiceOfMove,SHELL32_NotifyLinkTrackingServiceOfMove,449 diff --git a/libc/nt/shell32/SHELL32_PifMgr_CloseProperties.s b/libc/nt/shell32/SHELL32_PifMgr_CloseProperties.s new file mode 100644 index 00000000..38a6c761 --- /dev/null +++ b/libc/nt/shell32/SHELL32_PifMgr_CloseProperties.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_PifMgr_CloseProperties,SHELL32_PifMgr_CloseProperties,450 diff --git a/libc/nt/shell32/SHELL32_PifMgr_GetProperties.s b/libc/nt/shell32/SHELL32_PifMgr_GetProperties.s new file mode 100644 index 00000000..2dd11b35 --- /dev/null +++ b/libc/nt/shell32/SHELL32_PifMgr_GetProperties.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_PifMgr_GetProperties,SHELL32_PifMgr_GetProperties,451 diff --git a/libc/nt/shell32/SHELL32_PifMgr_OpenProperties.s b/libc/nt/shell32/SHELL32_PifMgr_OpenProperties.s new file mode 100644 index 00000000..a1943e23 --- /dev/null +++ b/libc/nt/shell32/SHELL32_PifMgr_OpenProperties.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_PifMgr_OpenProperties,SHELL32_PifMgr_OpenProperties,452 diff --git a/libc/nt/shell32/SHELL32_PifMgr_SetProperties.s b/libc/nt/shell32/SHELL32_PifMgr_SetProperties.s new file mode 100644 index 00000000..d00605e2 --- /dev/null +++ b/libc/nt/shell32/SHELL32_PifMgr_SetProperties.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_PifMgr_SetProperties,SHELL32_PifMgr_SetProperties,453 diff --git a/libc/nt/shell32/SHELL32_Printers_CreateBindInfo.s b/libc/nt/shell32/SHELL32_Printers_CreateBindInfo.s new file mode 100644 index 00000000..4acbf93a --- /dev/null +++ b/libc/nt/shell32/SHELL32_Printers_CreateBindInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_Printers_CreateBindInfo,SHELL32_Printers_CreateBindInfo,454 diff --git a/libc/nt/shell32/SHELL32_Printjob_GetPidl.s b/libc/nt/shell32/SHELL32_Printjob_GetPidl.s new file mode 100644 index 00000000..0db335fc --- /dev/null +++ b/libc/nt/shell32/SHELL32_Printjob_GetPidl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_Printjob_GetPidl,SHELL32_Printjob_GetPidl,455 diff --git a/libc/nt/shell32/SHELL32_PurgeSystemIcon.s b/libc/nt/shell32/SHELL32_PurgeSystemIcon.s new file mode 100644 index 00000000..856883fb --- /dev/null +++ b/libc/nt/shell32/SHELL32_PurgeSystemIcon.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_PurgeSystemIcon,SHELL32_PurgeSystemIcon,456 diff --git a/libc/nt/shell32/SHELL32_RefreshOverlayImages.s b/libc/nt/shell32/SHELL32_RefreshOverlayImages.s new file mode 100644 index 00000000..7ce6388c --- /dev/null +++ b/libc/nt/shell32/SHELL32_RefreshOverlayImages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_RefreshOverlayImages,SHELL32_RefreshOverlayImages,457 diff --git a/libc/nt/shell32/SHELL32_ResolveLinkInfoW.s b/libc/nt/shell32/SHELL32_ResolveLinkInfoW.s new file mode 100644 index 00000000..d4ab19d6 --- /dev/null +++ b/libc/nt/shell32/SHELL32_ResolveLinkInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_ResolveLinkInfoW,SHELL32_ResolveLinkInfoW,458 diff --git a/libc/nt/shell32/SHELL32_SHAddSparseIcon.s b/libc/nt/shell32/SHELL32_SHAddSparseIcon.s new file mode 100644 index 00000000..46ff5a9a --- /dev/null +++ b/libc/nt/shell32/SHELL32_SHAddSparseIcon.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SHAddSparseIcon,SHELL32_SHAddSparseIcon,459 diff --git a/libc/nt/shell32/SHELL32_SHCreateByValueOperationInterrupt.s b/libc/nt/shell32/SHELL32_SHCreateByValueOperationInterrupt.s new file mode 100644 index 00000000..73461fc4 --- /dev/null +++ b/libc/nt/shell32/SHELL32_SHCreateByValueOperationInterrupt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SHCreateByValueOperationInterrupt,SHELL32_SHCreateByValueOperationInterrupt,460 diff --git a/libc/nt/shell32/SHELL32_SHCreateDefaultContextMenu.s b/libc/nt/shell32/SHELL32_SHCreateDefaultContextMenu.s new file mode 100644 index 00000000..32c544e3 --- /dev/null +++ b/libc/nt/shell32/SHELL32_SHCreateDefaultContextMenu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SHCreateDefaultContextMenu,SHELL32_SHCreateDefaultContextMenu,461 diff --git a/libc/nt/shell32/SHELL32_SHCreateLocalServer.s b/libc/nt/shell32/SHELL32_SHCreateLocalServer.s new file mode 100644 index 00000000..879925e0 --- /dev/null +++ b/libc/nt/shell32/SHELL32_SHCreateLocalServer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SHCreateLocalServer,SHELL32_SHCreateLocalServer,462 diff --git a/libc/nt/shell32/SHELL32_SHCreateShellFolderView.s b/libc/nt/shell32/SHELL32_SHCreateShellFolderView.s new file mode 100644 index 00000000..7be8765a --- /dev/null +++ b/libc/nt/shell32/SHELL32_SHCreateShellFolderView.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SHCreateShellFolderView,SHELL32_SHCreateShellFolderView,463 diff --git a/libc/nt/shell32/SHELL32_SHDuplicateEncryptionInfoFile.s b/libc/nt/shell32/SHELL32_SHDuplicateEncryptionInfoFile.s new file mode 100644 index 00000000..e963873d --- /dev/null +++ b/libc/nt/shell32/SHELL32_SHDuplicateEncryptionInfoFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SHDuplicateEncryptionInfoFile,SHELL32_SHDuplicateEncryptionInfoFile,464 diff --git a/libc/nt/shell32/SHELL32_SHEncryptFile.s b/libc/nt/shell32/SHELL32_SHEncryptFile.s new file mode 100644 index 00000000..89fc04b0 --- /dev/null +++ b/libc/nt/shell32/SHELL32_SHEncryptFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SHEncryptFile,SHELL32_SHEncryptFile,465 diff --git a/libc/nt/shell32/SHELL32_SHFormatDriveAsync.s b/libc/nt/shell32/SHELL32_SHFormatDriveAsync.s new file mode 100644 index 00000000..b970862a --- /dev/null +++ b/libc/nt/shell32/SHELL32_SHFormatDriveAsync.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SHFormatDriveAsync,SHELL32_SHFormatDriveAsync,466 diff --git a/libc/nt/shell32/SHELL32_SHGetThreadUndoManager.s b/libc/nt/shell32/SHELL32_SHGetThreadUndoManager.s new file mode 100644 index 00000000..03dab2bb --- /dev/null +++ b/libc/nt/shell32/SHELL32_SHGetThreadUndoManager.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SHGetThreadUndoManager,SHELL32_SHGetThreadUndoManager,467 diff --git a/libc/nt/shell32/SHELL32_SHGetUserNameW.s b/libc/nt/shell32/SHELL32_SHGetUserNameW.s new file mode 100644 index 00000000..489dedbd --- /dev/null +++ b/libc/nt/shell32/SHELL32_SHGetUserNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SHGetUserNameW,SHELL32_SHGetUserNameW,468 diff --git a/libc/nt/shell32/SHELL32_SHIsVirtualDevice.s b/libc/nt/shell32/SHELL32_SHIsVirtualDevice.s new file mode 100644 index 00000000..bd8f5b90 --- /dev/null +++ b/libc/nt/shell32/SHELL32_SHIsVirtualDevice.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SHIsVirtualDevice,SHELL32_SHIsVirtualDevice,469 diff --git a/libc/nt/shell32/SHELL32_SHLaunchPropSheet.s b/libc/nt/shell32/SHELL32_SHLaunchPropSheet.s new file mode 100644 index 00000000..ea78cec4 --- /dev/null +++ b/libc/nt/shell32/SHELL32_SHLaunchPropSheet.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SHLaunchPropSheet,SHELL32_SHLaunchPropSheet,470 diff --git a/libc/nt/shell32/SHELL32_SHLogILFromFSIL.s b/libc/nt/shell32/SHELL32_SHLogILFromFSIL.s new file mode 100644 index 00000000..5992b9df --- /dev/null +++ b/libc/nt/shell32/SHELL32_SHLogILFromFSIL.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SHLogILFromFSIL,SHELL32_SHLogILFromFSIL,471 diff --git a/libc/nt/shell32/SHELL32_SHOpenWithDialog.s b/libc/nt/shell32/SHELL32_SHOpenWithDialog.s new file mode 100644 index 00000000..a19f97b2 --- /dev/null +++ b/libc/nt/shell32/SHELL32_SHOpenWithDialog.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SHOpenWithDialog,SHELL32_SHOpenWithDialog,472 diff --git a/libc/nt/shell32/SHELL32_SHStartNetConnectionDialogW.s b/libc/nt/shell32/SHELL32_SHStartNetConnectionDialogW.s new file mode 100644 index 00000000..dca3f8d4 --- /dev/null +++ b/libc/nt/shell32/SHELL32_SHStartNetConnectionDialogW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SHStartNetConnectionDialogW,SHELL32_SHStartNetConnectionDialogW,473 diff --git a/libc/nt/shell32/SHELL32_SHUICommandFromGUID.s b/libc/nt/shell32/SHELL32_SHUICommandFromGUID.s new file mode 100644 index 00000000..65ef908c --- /dev/null +++ b/libc/nt/shell32/SHELL32_SHUICommandFromGUID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SHUICommandFromGUID,SHELL32_SHUICommandFromGUID,474 diff --git a/libc/nt/shell32/SHELL32_SendToMenu_InvokeTargetedCommand.s b/libc/nt/shell32/SHELL32_SendToMenu_InvokeTargetedCommand.s new file mode 100644 index 00000000..7ff680bf --- /dev/null +++ b/libc/nt/shell32/SHELL32_SendToMenu_InvokeTargetedCommand.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SendToMenu_InvokeTargetedCommand,SHELL32_SendToMenu_InvokeTargetedCommand,475 diff --git a/libc/nt/shell32/SHELL32_SendToMenu_VerifyTargetedCommand.s b/libc/nt/shell32/SHELL32_SendToMenu_VerifyTargetedCommand.s new file mode 100644 index 00000000..bbbed7e4 --- /dev/null +++ b/libc/nt/shell32/SHELL32_SendToMenu_VerifyTargetedCommand.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SendToMenu_VerifyTargetedCommand,SHELL32_SendToMenu_VerifyTargetedCommand,476 diff --git a/libc/nt/shell32/SHELL32_SetPlaceholderReparsePointAttribute.s b/libc/nt/shell32/SHELL32_SetPlaceholderReparsePointAttribute.s new file mode 100644 index 00000000..92247577 --- /dev/null +++ b/libc/nt/shell32/SHELL32_SetPlaceholderReparsePointAttribute.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SetPlaceholderReparsePointAttribute,SHELL32_SetPlaceholderReparsePointAttribute,477 diff --git a/libc/nt/shell32/SHELL32_SetPlaceholderReparsePointAttribute2.s b/libc/nt/shell32/SHELL32_SetPlaceholderReparsePointAttribute2.s new file mode 100644 index 00000000..30cea6fe --- /dev/null +++ b/libc/nt/shell32/SHELL32_SetPlaceholderReparsePointAttribute2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SetPlaceholderReparsePointAttribute2,SHELL32_SetPlaceholderReparsePointAttribute2,478 diff --git a/libc/nt/shell32/SHELL32_ShowHideIconOnlyOnDesktop.s b/libc/nt/shell32/SHELL32_ShowHideIconOnlyOnDesktop.s new file mode 100644 index 00000000..acdaa50a --- /dev/null +++ b/libc/nt/shell32/SHELL32_ShowHideIconOnlyOnDesktop.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_ShowHideIconOnlyOnDesktop,SHELL32_ShowHideIconOnlyOnDesktop,479 diff --git a/libc/nt/shell32/SHELL32_SimpleRatingToFilterCondition.s b/libc/nt/shell32/SHELL32_SimpleRatingToFilterCondition.s new file mode 100644 index 00000000..5c41b712 --- /dev/null +++ b/libc/nt/shell32/SHELL32_SimpleRatingToFilterCondition.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SimpleRatingToFilterCondition,SHELL32_SimpleRatingToFilterCondition,480 diff --git a/libc/nt/shell32/SHELL32_StampIconForFile.s b/libc/nt/shell32/SHELL32_StampIconForFile.s new file mode 100644 index 00000000..ac9625c4 --- /dev/null +++ b/libc/nt/shell32/SHELL32_StampIconForFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_StampIconForFile,SHELL32_StampIconForFile,481 diff --git a/libc/nt/shell32/SHELL32_SuspendUndo.s b/libc/nt/shell32/SHELL32_SuspendUndo.s new file mode 100644 index 00000000..23ef6410 --- /dev/null +++ b/libc/nt/shell32/SHELL32_SuspendUndo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_SuspendUndo,SHELL32_SuspendUndo,482 diff --git a/libc/nt/shell32/SHELL32_TryVirtualDiscImageDriveEject.s b/libc/nt/shell32/SHELL32_TryVirtualDiscImageDriveEject.s new file mode 100644 index 00000000..4ef517ea --- /dev/null +++ b/libc/nt/shell32/SHELL32_TryVirtualDiscImageDriveEject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_TryVirtualDiscImageDriveEject,SHELL32_TryVirtualDiscImageDriveEject,483 diff --git a/libc/nt/shell32/SHELL32_UpdateFilePlaceholderStates.s b/libc/nt/shell32/SHELL32_UpdateFilePlaceholderStates.s new file mode 100644 index 00000000..e4e516f5 --- /dev/null +++ b/libc/nt/shell32/SHELL32_UpdateFilePlaceholderStates.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_UpdateFilePlaceholderStates,SHELL32_UpdateFilePlaceholderStates,484 diff --git a/libc/nt/shell32/SHELL32_VerifySaferTrust.s b/libc/nt/shell32/SHELL32_VerifySaferTrust.s new file mode 100644 index 00000000..012e4bff --- /dev/null +++ b/libc/nt/shell32/SHELL32_VerifySaferTrust.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHELL32_VerifySaferTrust,SHELL32_VerifySaferTrust,485 diff --git a/libc/nt/shell32/SHEmptyRecycleBinA.s b/libc/nt/shell32/SHEmptyRecycleBinA.s new file mode 100644 index 00000000..91a864f9 --- /dev/null +++ b/libc/nt/shell32/SHEmptyRecycleBinA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHEmptyRecycleBinA,SHEmptyRecycleBinA,486 diff --git a/libc/nt/shell32/SHEmptyRecycleBinW.s b/libc/nt/shell32/SHEmptyRecycleBinW.s new file mode 100644 index 00000000..69b5fa50 --- /dev/null +++ b/libc/nt/shell32/SHEmptyRecycleBinW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHEmptyRecycleBinW,SHEmptyRecycleBinW,487 diff --git a/libc/nt/shell32/SHEnableServiceObject.s b/libc/nt/shell32/SHEnableServiceObject.s new file mode 100644 index 00000000..426fc878 --- /dev/null +++ b/libc/nt/shell32/SHEnableServiceObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHEnableServiceObject,SHEnableServiceObject,488 diff --git a/libc/nt/shell32/SHEnumerateUnreadMailAccountsW.s b/libc/nt/shell32/SHEnumerateUnreadMailAccountsW.s new file mode 100644 index 00000000..51e96cb6 --- /dev/null +++ b/libc/nt/shell32/SHEnumerateUnreadMailAccountsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHEnumerateUnreadMailAccountsW,SHEnumerateUnreadMailAccountsW,489 diff --git a/libc/nt/shell32/SHEvaluateSystemCommandTemplate.s b/libc/nt/shell32/SHEvaluateSystemCommandTemplate.s new file mode 100644 index 00000000..b6ea37d3 --- /dev/null +++ b/libc/nt/shell32/SHEvaluateSystemCommandTemplate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHEvaluateSystemCommandTemplate,SHEvaluateSystemCommandTemplate,490 diff --git a/libc/nt/shell32/SHExtractIconsW.s b/libc/nt/shell32/SHExtractIconsW.s new file mode 100644 index 00000000..0cfd6b92 --- /dev/null +++ b/libc/nt/shell32/SHExtractIconsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHExtractIconsW,SHExtractIconsW,491 diff --git a/libc/nt/shell32/SHFileOperationA.s b/libc/nt/shell32/SHFileOperationA.s new file mode 100644 index 00000000..cf28a8ac --- /dev/null +++ b/libc/nt/shell32/SHFileOperationA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHFileOperationA,SHFileOperationA,493 diff --git a/libc/nt/shell32/SHFileOperationW.s b/libc/nt/shell32/SHFileOperationW.s new file mode 100644 index 00000000..f01d6b86 --- /dev/null +++ b/libc/nt/shell32/SHFileOperationW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHFileOperationW,SHFileOperationW,494 diff --git a/libc/nt/shell32/SHFindFiles.s b/libc/nt/shell32/SHFindFiles.s new file mode 100644 index 00000000..f2c770e7 --- /dev/null +++ b/libc/nt/shell32/SHFindFiles.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHFindFiles,SHFindFiles,90 diff --git a/libc/nt/shell32/SHFind_InitMenuPopup.s b/libc/nt/shell32/SHFind_InitMenuPopup.s new file mode 100644 index 00000000..e8cb6b4f --- /dev/null +++ b/libc/nt/shell32/SHFind_InitMenuPopup.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHFind_InitMenuPopup,SHFind_InitMenuPopup,149 diff --git a/libc/nt/shell32/SHFlushSFCache.s b/libc/nt/shell32/SHFlushSFCache.s new file mode 100644 index 00000000..0e5bafd0 --- /dev/null +++ b/libc/nt/shell32/SHFlushSFCache.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHFlushSFCache,SHFlushSFCache,526 diff --git a/libc/nt/shell32/SHFormatDrive.s b/libc/nt/shell32/SHFormatDrive.s new file mode 100644 index 00000000..97d552d6 --- /dev/null +++ b/libc/nt/shell32/SHFormatDrive.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHFormatDrive,SHFormatDrive,495 diff --git a/libc/nt/shell32/SHFree.s b/libc/nt/shell32/SHFree.s new file mode 100644 index 00000000..5f75eed7 --- /dev/null +++ b/libc/nt/shell32/SHFree.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHFree,SHFree,195 diff --git a/libc/nt/shell32/SHFreeNameMappings.s b/libc/nt/shell32/SHFreeNameMappings.s new file mode 100644 index 00000000..dd581c74 --- /dev/null +++ b/libc/nt/shell32/SHFreeNameMappings.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHFreeNameMappings,SHFreeNameMappings,496 diff --git a/libc/nt/shell32/SHGetAttributesFromDataObject.s b/libc/nt/shell32/SHGetAttributesFromDataObject.s new file mode 100644 index 00000000..8f2ca7fe --- /dev/null +++ b/libc/nt/shell32/SHGetAttributesFromDataObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetAttributesFromDataObject,SHGetAttributesFromDataObject,750 diff --git a/libc/nt/shell32/SHGetDataFromIDListA.s b/libc/nt/shell32/SHGetDataFromIDListA.s new file mode 100644 index 00000000..577cb478 --- /dev/null +++ b/libc/nt/shell32/SHGetDataFromIDListA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetDataFromIDListA,SHGetDataFromIDListA,497 diff --git a/libc/nt/shell32/SHGetDataFromIDListW.s b/libc/nt/shell32/SHGetDataFromIDListW.s new file mode 100644 index 00000000..54179f70 --- /dev/null +++ b/libc/nt/shell32/SHGetDataFromIDListW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetDataFromIDListW,SHGetDataFromIDListW,498 diff --git a/libc/nt/shell32/SHGetDesktopFolder.s b/libc/nt/shell32/SHGetDesktopFolder.s new file mode 100644 index 00000000..bde1dbb5 --- /dev/null +++ b/libc/nt/shell32/SHGetDesktopFolder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetDesktopFolder,SHGetDesktopFolder,499 diff --git a/libc/nt/shell32/SHGetDiskFreeSpaceA.s b/libc/nt/shell32/SHGetDiskFreeSpaceA.s new file mode 100644 index 00000000..67c04941 --- /dev/null +++ b/libc/nt/shell32/SHGetDiskFreeSpaceA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetDiskFreeSpaceA,SHGetDiskFreeSpaceA,500 diff --git a/libc/nt/shell32/SHGetDiskFreeSpaceExA.s b/libc/nt/shell32/SHGetDiskFreeSpaceExA.s new file mode 100644 index 00000000..36c4008c --- /dev/null +++ b/libc/nt/shell32/SHGetDiskFreeSpaceExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetDiskFreeSpaceExA,SHGetDiskFreeSpaceExA,501 diff --git a/libc/nt/shell32/SHGetDiskFreeSpaceExW.s b/libc/nt/shell32/SHGetDiskFreeSpaceExW.s new file mode 100644 index 00000000..fd978633 --- /dev/null +++ b/libc/nt/shell32/SHGetDiskFreeSpaceExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetDiskFreeSpaceExW,SHGetDiskFreeSpaceExW,502 diff --git a/libc/nt/shell32/SHGetDriveMedia.s b/libc/nt/shell32/SHGetDriveMedia.s new file mode 100644 index 00000000..33699a8b --- /dev/null +++ b/libc/nt/shell32/SHGetDriveMedia.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetDriveMedia,SHGetDriveMedia,503 diff --git a/libc/nt/shell32/SHGetFileInfoA.s b/libc/nt/shell32/SHGetFileInfoA.s new file mode 100644 index 00000000..54786a07 --- /dev/null +++ b/libc/nt/shell32/SHGetFileInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetFileInfoA,SHGetFileInfoA,505 diff --git a/libc/nt/shell32/SHGetFileInfoW.s b/libc/nt/shell32/SHGetFileInfoW.s new file mode 100644 index 00000000..fd3043dd --- /dev/null +++ b/libc/nt/shell32/SHGetFileInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetFileInfoW,SHGetFileInfoW,506 diff --git a/libc/nt/shell32/SHGetFolderLocation.s b/libc/nt/shell32/SHGetFolderLocation.s new file mode 100644 index 00000000..4a703978 --- /dev/null +++ b/libc/nt/shell32/SHGetFolderLocation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetFolderLocation,SHGetFolderLocation,507 diff --git a/libc/nt/shell32/SHGetFolderPathA.s b/libc/nt/shell32/SHGetFolderPathA.s new file mode 100644 index 00000000..8b20154a --- /dev/null +++ b/libc/nt/shell32/SHGetFolderPathA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetFolderPathA,SHGetFolderPathA,508 diff --git a/libc/nt/shell32/SHGetFolderPathAndSubDirA.s b/libc/nt/shell32/SHGetFolderPathAndSubDirA.s new file mode 100644 index 00000000..e8f1265d --- /dev/null +++ b/libc/nt/shell32/SHGetFolderPathAndSubDirA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetFolderPathAndSubDirA,SHGetFolderPathAndSubDirA,509 diff --git a/libc/nt/shell32/SHGetFolderPathAndSubDirW.s b/libc/nt/shell32/SHGetFolderPathAndSubDirW.s new file mode 100644 index 00000000..ca0ea6c8 --- /dev/null +++ b/libc/nt/shell32/SHGetFolderPathAndSubDirW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetFolderPathAndSubDirW,SHGetFolderPathAndSubDirW,510 diff --git a/libc/nt/shell32/SHGetFolderPathEx.s b/libc/nt/shell32/SHGetFolderPathEx.s new file mode 100644 index 00000000..a8935424 --- /dev/null +++ b/libc/nt/shell32/SHGetFolderPathEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetFolderPathEx,SHGetFolderPathEx,511 diff --git a/libc/nt/shell32/SHGetFolderPathW.s b/libc/nt/shell32/SHGetFolderPathW.s new file mode 100644 index 00000000..7b1f12b9 --- /dev/null +++ b/libc/nt/shell32/SHGetFolderPathW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetFolderPathW,SHGetFolderPathW,512 diff --git a/libc/nt/shell32/SHGetIDListFromObject.s b/libc/nt/shell32/SHGetIDListFromObject.s new file mode 100644 index 00000000..74367cc7 --- /dev/null +++ b/libc/nt/shell32/SHGetIDListFromObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetIDListFromObject,SHGetIDListFromObject,513 diff --git a/libc/nt/shell32/SHGetIconOverlayIndexA.s b/libc/nt/shell32/SHGetIconOverlayIndexA.s new file mode 100644 index 00000000..b78116de --- /dev/null +++ b/libc/nt/shell32/SHGetIconOverlayIndexA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetIconOverlayIndexA,SHGetIconOverlayIndexA,514 diff --git a/libc/nt/shell32/SHGetIconOverlayIndexW.s b/libc/nt/shell32/SHGetIconOverlayIndexW.s new file mode 100644 index 00000000..33a6d3df --- /dev/null +++ b/libc/nt/shell32/SHGetIconOverlayIndexW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetIconOverlayIndexW,SHGetIconOverlayIndexW,515 diff --git a/libc/nt/shell32/SHGetImageList.s b/libc/nt/shell32/SHGetImageList.s new file mode 100644 index 00000000..b3d8092c --- /dev/null +++ b/libc/nt/shell32/SHGetImageList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetImageList,SHGetImageList,727 diff --git a/libc/nt/shell32/SHGetInstanceExplorer.s b/libc/nt/shell32/SHGetInstanceExplorer.s new file mode 100644 index 00000000..306685c9 --- /dev/null +++ b/libc/nt/shell32/SHGetInstanceExplorer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetInstanceExplorer,SHGetInstanceExplorer,516 diff --git a/libc/nt/shell32/SHGetItemFromDataObject.s b/libc/nt/shell32/SHGetItemFromDataObject.s new file mode 100644 index 00000000..b78945b4 --- /dev/null +++ b/libc/nt/shell32/SHGetItemFromDataObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetItemFromDataObject,SHGetItemFromDataObject,517 diff --git a/libc/nt/shell32/SHGetItemFromObject.s b/libc/nt/shell32/SHGetItemFromObject.s new file mode 100644 index 00000000..69584419 --- /dev/null +++ b/libc/nt/shell32/SHGetItemFromObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetItemFromObject,SHGetItemFromObject,518 diff --git a/libc/nt/shell32/SHGetKnownFolderIDList.s b/libc/nt/shell32/SHGetKnownFolderIDList.s new file mode 100644 index 00000000..1c8b7871 --- /dev/null +++ b/libc/nt/shell32/SHGetKnownFolderIDList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetKnownFolderIDList,SHGetKnownFolderIDList,519 diff --git a/libc/nt/shell32/SHGetKnownFolderItem.s b/libc/nt/shell32/SHGetKnownFolderItem.s new file mode 100644 index 00000000..e51e4aa8 --- /dev/null +++ b/libc/nt/shell32/SHGetKnownFolderItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetKnownFolderItem,SHGetKnownFolderItem,527 diff --git a/libc/nt/shell32/SHGetKnownFolderPath.s b/libc/nt/shell32/SHGetKnownFolderPath.s new file mode 100644 index 00000000..59bfd5d7 --- /dev/null +++ b/libc/nt/shell32/SHGetKnownFolderPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetKnownFolderPath,SHGetKnownFolderPath,528 diff --git a/libc/nt/shell32/SHGetLocalizedName.s b/libc/nt/shell32/SHGetLocalizedName.s new file mode 100644 index 00000000..240f35bd --- /dev/null +++ b/libc/nt/shell32/SHGetLocalizedName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetLocalizedName,SHGetLocalizedName,529 diff --git a/libc/nt/shell32/SHGetMalloc.s b/libc/nt/shell32/SHGetMalloc.s new file mode 100644 index 00000000..23ec1adb --- /dev/null +++ b/libc/nt/shell32/SHGetMalloc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetMalloc,SHGetMalloc,530 diff --git a/libc/nt/shell32/SHGetNameFromIDList.s b/libc/nt/shell32/SHGetNameFromIDList.s new file mode 100644 index 00000000..f247b5e6 --- /dev/null +++ b/libc/nt/shell32/SHGetNameFromIDList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetNameFromIDList,SHGetNameFromIDList,531 diff --git a/libc/nt/shell32/SHGetNewLinkInfoA.s b/libc/nt/shell32/SHGetNewLinkInfoA.s new file mode 100644 index 00000000..4c42a627 --- /dev/null +++ b/libc/nt/shell32/SHGetNewLinkInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetNewLinkInfoA,SHGetNewLinkInfoA,179 diff --git a/libc/nt/shell32/SHGetNewLinkInfoW.s b/libc/nt/shell32/SHGetNewLinkInfoW.s new file mode 100644 index 00000000..a9717393 --- /dev/null +++ b/libc/nt/shell32/SHGetNewLinkInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetNewLinkInfoW,SHGetNewLinkInfoW,180 diff --git a/libc/nt/shell32/SHGetPathFromIDListA.s b/libc/nt/shell32/SHGetPathFromIDListA.s new file mode 100644 index 00000000..593cf4fa --- /dev/null +++ b/libc/nt/shell32/SHGetPathFromIDListA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetPathFromIDListA,SHGetPathFromIDListA,534 diff --git a/libc/nt/shell32/SHGetPathFromIDListEx.s b/libc/nt/shell32/SHGetPathFromIDListEx.s new file mode 100644 index 00000000..353ddbce --- /dev/null +++ b/libc/nt/shell32/SHGetPathFromIDListEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetPathFromIDListEx,SHGetPathFromIDListEx,535 diff --git a/libc/nt/shell32/SHGetPathFromIDListW.s b/libc/nt/shell32/SHGetPathFromIDListW.s new file mode 100644 index 00000000..ad222808 --- /dev/null +++ b/libc/nt/shell32/SHGetPathFromIDListW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetPathFromIDListW,SHGetPathFromIDListW,536 diff --git a/libc/nt/shell32/SHGetPropertyStoreForWindow.s b/libc/nt/shell32/SHGetPropertyStoreForWindow.s new file mode 100644 index 00000000..ecc3530b --- /dev/null +++ b/libc/nt/shell32/SHGetPropertyStoreForWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetPropertyStoreForWindow,SHGetPropertyStoreForWindow,537 diff --git a/libc/nt/shell32/SHGetPropertyStoreFromIDList.s b/libc/nt/shell32/SHGetPropertyStoreFromIDList.s new file mode 100644 index 00000000..5d160031 --- /dev/null +++ b/libc/nt/shell32/SHGetPropertyStoreFromIDList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetPropertyStoreFromIDList,SHGetPropertyStoreFromIDList,538 diff --git a/libc/nt/shell32/SHGetPropertyStoreFromParsingName.s b/libc/nt/shell32/SHGetPropertyStoreFromParsingName.s new file mode 100644 index 00000000..1abab458 --- /dev/null +++ b/libc/nt/shell32/SHGetPropertyStoreFromParsingName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetPropertyStoreFromParsingName,SHGetPropertyStoreFromParsingName,539 diff --git a/libc/nt/shell32/SHGetRealIDL.s b/libc/nt/shell32/SHGetRealIDL.s new file mode 100644 index 00000000..cae4badd --- /dev/null +++ b/libc/nt/shell32/SHGetRealIDL.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetRealIDL,SHGetRealIDL,98 diff --git a/libc/nt/shell32/SHGetSetFolderCustomSettings.s b/libc/nt/shell32/SHGetSetFolderCustomSettings.s new file mode 100644 index 00000000..c971208e --- /dev/null +++ b/libc/nt/shell32/SHGetSetFolderCustomSettings.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetSetFolderCustomSettings,SHGetSetFolderCustomSettings,709 diff --git a/libc/nt/shell32/SHGetSetSettings.s b/libc/nt/shell32/SHGetSetSettings.s new file mode 100644 index 00000000..6480ba3c --- /dev/null +++ b/libc/nt/shell32/SHGetSetSettings.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetSetSettings,SHGetSetSettings,68 diff --git a/libc/nt/shell32/SHGetSettings.s b/libc/nt/shell32/SHGetSettings.s new file mode 100644 index 00000000..a6957b6f --- /dev/null +++ b/libc/nt/shell32/SHGetSettings.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetSettings,SHGetSettings,540 diff --git a/libc/nt/shell32/SHGetSpecialFolderLocation.s b/libc/nt/shell32/SHGetSpecialFolderLocation.s new file mode 100644 index 00000000..681f7c58 --- /dev/null +++ b/libc/nt/shell32/SHGetSpecialFolderLocation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetSpecialFolderLocation,SHGetSpecialFolderLocation,541 diff --git a/libc/nt/shell32/SHGetSpecialFolderPathA.s b/libc/nt/shell32/SHGetSpecialFolderPathA.s new file mode 100644 index 00000000..80876d1a --- /dev/null +++ b/libc/nt/shell32/SHGetSpecialFolderPathA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetSpecialFolderPathA,SHGetSpecialFolderPathA,542 diff --git a/libc/nt/shell32/SHGetSpecialFolderPathW.s b/libc/nt/shell32/SHGetSpecialFolderPathW.s new file mode 100644 index 00000000..3194d582 --- /dev/null +++ b/libc/nt/shell32/SHGetSpecialFolderPathW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetSpecialFolderPathW,SHGetSpecialFolderPathW,543 diff --git a/libc/nt/shell32/SHGetStockIconInfo.s b/libc/nt/shell32/SHGetStockIconInfo.s new file mode 100644 index 00000000..bf5da49d --- /dev/null +++ b/libc/nt/shell32/SHGetStockIconInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetStockIconInfo,SHGetStockIconInfo,544 diff --git a/libc/nt/shell32/SHGetTemporaryPropertyForItem.s b/libc/nt/shell32/SHGetTemporaryPropertyForItem.s new file mode 100644 index 00000000..e6be8d8a --- /dev/null +++ b/libc/nt/shell32/SHGetTemporaryPropertyForItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetTemporaryPropertyForItem,SHGetTemporaryPropertyForItem,545 diff --git a/libc/nt/shell32/SHGetUnreadMailCountW.s b/libc/nt/shell32/SHGetUnreadMailCountW.s new file mode 100644 index 00000000..90cc75ce --- /dev/null +++ b/libc/nt/shell32/SHGetUnreadMailCountW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHGetUnreadMailCountW,SHGetUnreadMailCountW,546 diff --git a/libc/nt/shell32/SHHandleUpdateImage.s b/libc/nt/shell32/SHHandleUpdateImage.s new file mode 100644 index 00000000..a4c48397 --- /dev/null +++ b/libc/nt/shell32/SHHandleUpdateImage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHHandleUpdateImage,SHHandleUpdateImage,193 diff --git a/libc/nt/shell32/SHHelpShortcuts_RunDLL.s b/libc/nt/shell32/SHHelpShortcuts_RunDLL.s new file mode 100644 index 00000000..c4b7dcb9 --- /dev/null +++ b/libc/nt/shell32/SHHelpShortcuts_RunDLL.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHHelpShortcuts_RunDLL,SHHelpShortcuts_RunDLL,228 diff --git a/libc/nt/shell32/SHHelpShortcuts_RunDLLA.s b/libc/nt/shell32/SHHelpShortcuts_RunDLLA.s new file mode 100644 index 00000000..2f15a669 --- /dev/null +++ b/libc/nt/shell32/SHHelpShortcuts_RunDLLA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHHelpShortcuts_RunDLLA,SHHelpShortcuts_RunDLLA,229 diff --git a/libc/nt/shell32/SHHelpShortcuts_RunDLLW.s b/libc/nt/shell32/SHHelpShortcuts_RunDLLW.s new file mode 100644 index 00000000..60d6a39b --- /dev/null +++ b/libc/nt/shell32/SHHelpShortcuts_RunDLLW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHHelpShortcuts_RunDLLW,SHHelpShortcuts_RunDLLW,238 diff --git a/libc/nt/shell32/SHILCreateFromPath.s b/libc/nt/shell32/SHILCreateFromPath.s new file mode 100644 index 00000000..79f5d91f --- /dev/null +++ b/libc/nt/shell32/SHILCreateFromPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHILCreateFromPath,SHILCreateFromPath,28 diff --git a/libc/nt/shell32/SHInvokePrinterCommandA.s b/libc/nt/shell32/SHInvokePrinterCommandA.s new file mode 100644 index 00000000..45382032 --- /dev/null +++ b/libc/nt/shell32/SHInvokePrinterCommandA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHInvokePrinterCommandA,SHInvokePrinterCommandA,547 diff --git a/libc/nt/shell32/SHInvokePrinterCommandW.s b/libc/nt/shell32/SHInvokePrinterCommandW.s new file mode 100644 index 00000000..1fecbd0a --- /dev/null +++ b/libc/nt/shell32/SHInvokePrinterCommandW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHInvokePrinterCommandW,SHInvokePrinterCommandW,548 diff --git a/libc/nt/shell32/SHIsFileAvailableOffline.s b/libc/nt/shell32/SHIsFileAvailableOffline.s new file mode 100644 index 00000000..5344763c --- /dev/null +++ b/libc/nt/shell32/SHIsFileAvailableOffline.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHIsFileAvailableOffline,SHIsFileAvailableOffline,549 diff --git a/libc/nt/shell32/SHLimitInputEdit.s b/libc/nt/shell32/SHLimitInputEdit.s new file mode 100644 index 00000000..1df48db3 --- /dev/null +++ b/libc/nt/shell32/SHLimitInputEdit.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHLimitInputEdit,SHLimitInputEdit,747 diff --git a/libc/nt/shell32/SHLoadInProc.s b/libc/nt/shell32/SHLoadInProc.s new file mode 100644 index 00000000..86cfc874 --- /dev/null +++ b/libc/nt/shell32/SHLoadInProc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHLoadInProc,SHLoadInProc,550 diff --git a/libc/nt/shell32/SHLoadNonloadedIconOverlayIdentifiers.s b/libc/nt/shell32/SHLoadNonloadedIconOverlayIdentifiers.s new file mode 100644 index 00000000..856bfa86 --- /dev/null +++ b/libc/nt/shell32/SHLoadNonloadedIconOverlayIdentifiers.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHLoadNonloadedIconOverlayIdentifiers,SHLoadNonloadedIconOverlayIdentifiers,551 diff --git a/libc/nt/shell32/SHMapPIDLToSystemImageListIndex.s b/libc/nt/shell32/SHMapPIDLToSystemImageListIndex.s new file mode 100644 index 00000000..05c77f32 --- /dev/null +++ b/libc/nt/shell32/SHMapPIDLToSystemImageListIndex.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHMapPIDLToSystemImageListIndex,SHMapPIDLToSystemImageListIndex,77 diff --git a/libc/nt/shell32/SHMultiFileProperties.s b/libc/nt/shell32/SHMultiFileProperties.s new file mode 100644 index 00000000..3cf8b338 --- /dev/null +++ b/libc/nt/shell32/SHMultiFileProperties.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHMultiFileProperties,SHMultiFileProperties,716 diff --git a/libc/nt/shell32/SHObjectProperties.s b/libc/nt/shell32/SHObjectProperties.s new file mode 100644 index 00000000..9f4faa29 --- /dev/null +++ b/libc/nt/shell32/SHObjectProperties.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHObjectProperties,SHObjectProperties,178 diff --git a/libc/nt/shell32/SHOpenFolderAndSelectItems.s b/libc/nt/shell32/SHOpenFolderAndSelectItems.s new file mode 100644 index 00000000..1518e1ab --- /dev/null +++ b/libc/nt/shell32/SHOpenFolderAndSelectItems.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHOpenFolderAndSelectItems,SHOpenFolderAndSelectItems,552 diff --git a/libc/nt/shell32/SHOpenPropSheetW.s b/libc/nt/shell32/SHOpenPropSheetW.s new file mode 100644 index 00000000..67aed356 --- /dev/null +++ b/libc/nt/shell32/SHOpenPropSheetW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHOpenPropSheetW,SHOpenPropSheetW,80 diff --git a/libc/nt/shell32/SHOpenWithDialog.s b/libc/nt/shell32/SHOpenWithDialog.s new file mode 100644 index 00000000..b1a93f07 --- /dev/null +++ b/libc/nt/shell32/SHOpenWithDialog.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHOpenWithDialog,SHOpenWithDialog,553 diff --git a/libc/nt/shell32/SHParseDisplayName.s b/libc/nt/shell32/SHParseDisplayName.s new file mode 100644 index 00000000..b2f20772 --- /dev/null +++ b/libc/nt/shell32/SHParseDisplayName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHParseDisplayName,SHParseDisplayName,554 diff --git a/libc/nt/shell32/SHPathPrepareForWriteA.s b/libc/nt/shell32/SHPathPrepareForWriteA.s new file mode 100644 index 00000000..b3c78ae7 --- /dev/null +++ b/libc/nt/shell32/SHPathPrepareForWriteA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHPathPrepareForWriteA,SHPathPrepareForWriteA,555 diff --git a/libc/nt/shell32/SHPathPrepareForWriteW.s b/libc/nt/shell32/SHPathPrepareForWriteW.s new file mode 100644 index 00000000..8fc46fd3 --- /dev/null +++ b/libc/nt/shell32/SHPathPrepareForWriteW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHPathPrepareForWriteW,SHPathPrepareForWriteW,556 diff --git a/libc/nt/shell32/SHPropStgCreate.s b/libc/nt/shell32/SHPropStgCreate.s new file mode 100644 index 00000000..5776ea13 --- /dev/null +++ b/libc/nt/shell32/SHPropStgCreate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHPropStgCreate,SHPropStgCreate,685 diff --git a/libc/nt/shell32/SHPropStgReadMultiple.s b/libc/nt/shell32/SHPropStgReadMultiple.s new file mode 100644 index 00000000..62d70b9c --- /dev/null +++ b/libc/nt/shell32/SHPropStgReadMultiple.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHPropStgReadMultiple,SHPropStgReadMultiple,688 diff --git a/libc/nt/shell32/SHPropStgWriteMultiple.s b/libc/nt/shell32/SHPropStgWriteMultiple.s new file mode 100644 index 00000000..1a61fe4f --- /dev/null +++ b/libc/nt/shell32/SHPropStgWriteMultiple.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHPropStgWriteMultiple,SHPropStgWriteMultiple,689 diff --git a/libc/nt/shell32/SHQueryRecycleBinA.s b/libc/nt/shell32/SHQueryRecycleBinA.s new file mode 100644 index 00000000..99d5f600 --- /dev/null +++ b/libc/nt/shell32/SHQueryRecycleBinA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHQueryRecycleBinA,SHQueryRecycleBinA,557 diff --git a/libc/nt/shell32/SHQueryRecycleBinW.s b/libc/nt/shell32/SHQueryRecycleBinW.s new file mode 100644 index 00000000..57c48128 --- /dev/null +++ b/libc/nt/shell32/SHQueryRecycleBinW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHQueryRecycleBinW,SHQueryRecycleBinW,558 diff --git a/libc/nt/shell32/SHQueryUserNotificationState.s b/libc/nt/shell32/SHQueryUserNotificationState.s new file mode 100644 index 00000000..50818a52 --- /dev/null +++ b/libc/nt/shell32/SHQueryUserNotificationState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHQueryUserNotificationState,SHQueryUserNotificationState,559 diff --git a/libc/nt/shell32/SHRemoveLocalizedName.s b/libc/nt/shell32/SHRemoveLocalizedName.s new file mode 100644 index 00000000..2acffba9 --- /dev/null +++ b/libc/nt/shell32/SHRemoveLocalizedName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHRemoveLocalizedName,SHRemoveLocalizedName,560 diff --git a/libc/nt/shell32/SHReplaceFromPropSheetExtArray.s b/libc/nt/shell32/SHReplaceFromPropSheetExtArray.s new file mode 100644 index 00000000..63a5a7f4 --- /dev/null +++ b/libc/nt/shell32/SHReplaceFromPropSheetExtArray.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHReplaceFromPropSheetExtArray,SHReplaceFromPropSheetExtArray,170 diff --git a/libc/nt/shell32/SHResolveLibrary.s b/libc/nt/shell32/SHResolveLibrary.s new file mode 100644 index 00000000..127eea71 --- /dev/null +++ b/libc/nt/shell32/SHResolveLibrary.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHResolveLibrary,SHResolveLibrary,561 diff --git a/libc/nt/shell32/SHRestricted.s b/libc/nt/shell32/SHRestricted.s new file mode 100644 index 00000000..620b03fe --- /dev/null +++ b/libc/nt/shell32/SHRestricted.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHRestricted,SHRestricted,100 diff --git a/libc/nt/shell32/SHSetDefaultProperties.s b/libc/nt/shell32/SHSetDefaultProperties.s new file mode 100644 index 00000000..21b2510b --- /dev/null +++ b/libc/nt/shell32/SHSetDefaultProperties.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHSetDefaultProperties,SHSetDefaultProperties,562 diff --git a/libc/nt/shell32/SHSetFolderPathA.s b/libc/nt/shell32/SHSetFolderPathA.s new file mode 100644 index 00000000..a33397f7 --- /dev/null +++ b/libc/nt/shell32/SHSetFolderPathA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHSetFolderPathA,SHSetFolderPathA,231 diff --git a/libc/nt/shell32/SHSetFolderPathW.s b/libc/nt/shell32/SHSetFolderPathW.s new file mode 100644 index 00000000..262da958 --- /dev/null +++ b/libc/nt/shell32/SHSetFolderPathW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHSetFolderPathW,SHSetFolderPathW,232 diff --git a/libc/nt/shell32/SHSetInstanceExplorer.s b/libc/nt/shell32/SHSetInstanceExplorer.s new file mode 100644 index 00000000..0f7a385d --- /dev/null +++ b/libc/nt/shell32/SHSetInstanceExplorer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHSetInstanceExplorer,SHSetInstanceExplorer,176 diff --git a/libc/nt/shell32/SHSetKnownFolderPath.s b/libc/nt/shell32/SHSetKnownFolderPath.s new file mode 100644 index 00000000..99241efd --- /dev/null +++ b/libc/nt/shell32/SHSetKnownFolderPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHSetKnownFolderPath,SHSetKnownFolderPath,563 diff --git a/libc/nt/shell32/SHSetLocalizedName.s b/libc/nt/shell32/SHSetLocalizedName.s new file mode 100644 index 00000000..066cba13 --- /dev/null +++ b/libc/nt/shell32/SHSetLocalizedName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHSetLocalizedName,SHSetLocalizedName,564 diff --git a/libc/nt/shell32/SHSetTemporaryPropertyForItem.s b/libc/nt/shell32/SHSetTemporaryPropertyForItem.s new file mode 100644 index 00000000..17caeb54 --- /dev/null +++ b/libc/nt/shell32/SHSetTemporaryPropertyForItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHSetTemporaryPropertyForItem,SHSetTemporaryPropertyForItem,565 diff --git a/libc/nt/shell32/SHSetUnreadMailCountW.s b/libc/nt/shell32/SHSetUnreadMailCountW.s new file mode 100644 index 00000000..89c141fc --- /dev/null +++ b/libc/nt/shell32/SHSetUnreadMailCountW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHSetUnreadMailCountW,SHSetUnreadMailCountW,566 diff --git a/libc/nt/shell32/SHShellFolderView_Message.s b/libc/nt/shell32/SHShellFolderView_Message.s new file mode 100644 index 00000000..b6113c0c --- /dev/null +++ b/libc/nt/shell32/SHShellFolderView_Message.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHShellFolderView_Message,SHShellFolderView_Message,73 diff --git a/libc/nt/shell32/SHShowManageLibraryUI.s b/libc/nt/shell32/SHShowManageLibraryUI.s new file mode 100644 index 00000000..a5e6458d --- /dev/null +++ b/libc/nt/shell32/SHShowManageLibraryUI.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHShowManageLibraryUI,SHShowManageLibraryUI,567 diff --git a/libc/nt/shell32/SHSimpleIDListFromPath.s b/libc/nt/shell32/SHSimpleIDListFromPath.s new file mode 100644 index 00000000..40f5a62f --- /dev/null +++ b/libc/nt/shell32/SHSimpleIDListFromPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHSimpleIDListFromPath,SHSimpleIDListFromPath,162 diff --git a/libc/nt/shell32/SHStartNetConnectionDialogW.s b/libc/nt/shell32/SHStartNetConnectionDialogW.s new file mode 100644 index 00000000..b0e18429 --- /dev/null +++ b/libc/nt/shell32/SHStartNetConnectionDialogW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHStartNetConnectionDialogW,SHStartNetConnectionDialogW,14 diff --git a/libc/nt/shell32/SHTestTokenMembership.s b/libc/nt/shell32/SHTestTokenMembership.s new file mode 100644 index 00000000..26677a01 --- /dev/null +++ b/libc/nt/shell32/SHTestTokenMembership.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHTestTokenMembership,SHTestTokenMembership,245 diff --git a/libc/nt/shell32/SHUpdateImageA.s b/libc/nt/shell32/SHUpdateImageA.s new file mode 100644 index 00000000..98c7962e --- /dev/null +++ b/libc/nt/shell32/SHUpdateImageA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHUpdateImageA,SHUpdateImageA,191 diff --git a/libc/nt/shell32/SHUpdateImageW.s b/libc/nt/shell32/SHUpdateImageW.s new file mode 100644 index 00000000..e750e38f --- /dev/null +++ b/libc/nt/shell32/SHUpdateImageW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHUpdateImageW,SHUpdateImageW,192 diff --git a/libc/nt/shell32/SHUpdateRecycleBinIcon.s b/libc/nt/shell32/SHUpdateRecycleBinIcon.s new file mode 100644 index 00000000..4173d607 --- /dev/null +++ b/libc/nt/shell32/SHUpdateRecycleBinIcon.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHUpdateRecycleBinIcon,SHUpdateRecycleBinIcon,568 diff --git a/libc/nt/shell32/SHValidateUNC.s b/libc/nt/shell32/SHValidateUNC.s new file mode 100644 index 00000000..7ddf5996 --- /dev/null +++ b/libc/nt/shell32/SHValidateUNC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SHValidateUNC,SHValidateUNC,173 diff --git a/libc/nt/shell32/SetCurrentProcessExplicitAppUserModelID.s b/libc/nt/shell32/SetCurrentProcessExplicitAppUserModelID.s new file mode 100644 index 00000000..b318be6b --- /dev/null +++ b/libc/nt/shell32/SetCurrentProcessExplicitAppUserModelID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SetCurrentProcessExplicitAppUserModelID,SetCurrentProcessExplicitAppUserModelID,569 diff --git a/libc/nt/shell32/SheChangeDirA.s b/libc/nt/shell32/SheChangeDirA.s new file mode 100644 index 00000000..a3d2328d --- /dev/null +++ b/libc/nt/shell32/SheChangeDirA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SheChangeDirA,SheChangeDirA,570 diff --git a/libc/nt/shell32/SheChangeDirExW.s b/libc/nt/shell32/SheChangeDirExW.s new file mode 100644 index 00000000..de54d076 --- /dev/null +++ b/libc/nt/shell32/SheChangeDirExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SheChangeDirExW,SheChangeDirExW,571 diff --git a/libc/nt/shell32/SheGetDirA.s b/libc/nt/shell32/SheGetDirA.s new file mode 100644 index 00000000..6ec00953 --- /dev/null +++ b/libc/nt/shell32/SheGetDirA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SheGetDirA,SheGetDirA,572 diff --git a/libc/nt/shell32/SheSetCurDrive.s b/libc/nt/shell32/SheSetCurDrive.s new file mode 100644 index 00000000..e8d1b542 --- /dev/null +++ b/libc/nt/shell32/SheSetCurDrive.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SheSetCurDrive,SheSetCurDrive,573 diff --git a/libc/nt/shell32/ShellAboutA.s b/libc/nt/shell32/ShellAboutA.s new file mode 100644 index 00000000..bde32111 --- /dev/null +++ b/libc/nt/shell32/ShellAboutA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ShellAboutA,ShellAboutA,574 diff --git a/libc/nt/shell32/ShellAboutW.s b/libc/nt/shell32/ShellAboutW.s new file mode 100644 index 00000000..30f19f58 --- /dev/null +++ b/libc/nt/shell32/ShellAboutW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ShellAboutW,ShellAboutW,575 diff --git a/libc/nt/shell32/ShellExec_RunDLL.s b/libc/nt/shell32/ShellExec_RunDLL.s new file mode 100644 index 00000000..b871a199 --- /dev/null +++ b/libc/nt/shell32/ShellExec_RunDLL.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ShellExec_RunDLL,ShellExec_RunDLL,576 diff --git a/libc/nt/shell32/ShellExec_RunDLLA.s b/libc/nt/shell32/ShellExec_RunDLLA.s new file mode 100644 index 00000000..05a75b9d --- /dev/null +++ b/libc/nt/shell32/ShellExec_RunDLLA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ShellExec_RunDLLA,ShellExec_RunDLLA,577 diff --git a/libc/nt/shell32/ShellExec_RunDLLW.s b/libc/nt/shell32/ShellExec_RunDLLW.s new file mode 100644 index 00000000..10c6c505 --- /dev/null +++ b/libc/nt/shell32/ShellExec_RunDLLW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ShellExec_RunDLLW,ShellExec_RunDLLW,578 diff --git a/libc/nt/shell32/ShellExecuteA.s b/libc/nt/shell32/ShellExecuteA.s new file mode 100644 index 00000000..5fd2fd99 --- /dev/null +++ b/libc/nt/shell32/ShellExecuteA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ShellExecuteA,ShellExecuteA,579 diff --git a/libc/nt/shell32/ShellExecuteExA.s b/libc/nt/shell32/ShellExecuteExA.s new file mode 100644 index 00000000..17f1404f --- /dev/null +++ b/libc/nt/shell32/ShellExecuteExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ShellExecuteExA,ShellExecuteExA,581 diff --git a/libc/nt/shell32/ShellExecuteExW.s b/libc/nt/shell32/ShellExecuteExW.s new file mode 100644 index 00000000..f672c287 --- /dev/null +++ b/libc/nt/shell32/ShellExecuteExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ShellExecuteExW,ShellExecuteExW,582 diff --git a/libc/nt/shell32/ShellExecuteW.s b/libc/nt/shell32/ShellExecuteW.s new file mode 100644 index 00000000..048ff280 --- /dev/null +++ b/libc/nt/shell32/ShellExecuteW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ShellExecuteW,ShellExecuteW,583 diff --git a/libc/nt/shell32/ShellHookProc.s b/libc/nt/shell32/ShellHookProc.s new file mode 100644 index 00000000..fc8856f9 --- /dev/null +++ b/libc/nt/shell32/ShellHookProc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_ShellHookProc,ShellHookProc,584 diff --git a/libc/nt/shell32/Shell_GetCachedImageIndexA.s b/libc/nt/shell32/Shell_GetCachedImageIndexA.s new file mode 100644 index 00000000..2186828d --- /dev/null +++ b/libc/nt/shell32/Shell_GetCachedImageIndexA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_Shell_GetCachedImageIndexA,Shell_GetCachedImageIndexA,585 diff --git a/libc/nt/shell32/Shell_GetCachedImageIndexW.s b/libc/nt/shell32/Shell_GetCachedImageIndexW.s new file mode 100644 index 00000000..b72b7ec4 --- /dev/null +++ b/libc/nt/shell32/Shell_GetCachedImageIndexW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_Shell_GetCachedImageIndexW,Shell_GetCachedImageIndexW,586 diff --git a/libc/nt/shell32/Shell_GetImageLists.s b/libc/nt/shell32/Shell_GetImageLists.s new file mode 100644 index 00000000..4b16892d --- /dev/null +++ b/libc/nt/shell32/Shell_GetImageLists.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_Shell_GetImageLists,Shell_GetImageLists,71 diff --git a/libc/nt/shell32/Shell_MergeMenus.s b/libc/nt/shell32/Shell_MergeMenus.s new file mode 100644 index 00000000..35d09ff9 --- /dev/null +++ b/libc/nt/shell32/Shell_MergeMenus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_Shell_MergeMenus,Shell_MergeMenus,67 diff --git a/libc/nt/shell32/Shell_NotifyIconA.s b/libc/nt/shell32/Shell_NotifyIconA.s new file mode 100644 index 00000000..06d9eaad --- /dev/null +++ b/libc/nt/shell32/Shell_NotifyIconA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_Shell_NotifyIconA,Shell_NotifyIconA,588 diff --git a/libc/nt/shell32/Shell_NotifyIconGetRect.s b/libc/nt/shell32/Shell_NotifyIconGetRect.s new file mode 100644 index 00000000..a205fd73 --- /dev/null +++ b/libc/nt/shell32/Shell_NotifyIconGetRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_Shell_NotifyIconGetRect,Shell_NotifyIconGetRect,589 diff --git a/libc/nt/shell32/Shell_NotifyIconW.s b/libc/nt/shell32/Shell_NotifyIconW.s new file mode 100644 index 00000000..f8c4e81d --- /dev/null +++ b/libc/nt/shell32/Shell_NotifyIconW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_Shell_NotifyIconW,Shell_NotifyIconW,590 diff --git a/libc/nt/shell32/SignalFileOpen.s b/libc/nt/shell32/SignalFileOpen.s new file mode 100644 index 00000000..68f5acd1 --- /dev/null +++ b/libc/nt/shell32/SignalFileOpen.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_SignalFileOpen,SignalFileOpen,103 diff --git a/libc/nt/shell32/StgMakeUniqueName.s b/libc/nt/shell32/StgMakeUniqueName.s new file mode 100644 index 00000000..cadc0a62 --- /dev/null +++ b/libc/nt/shell32/StgMakeUniqueName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_StgMakeUniqueName,StgMakeUniqueName,682 diff --git a/libc/nt/shell32/StrNCmpA.s b/libc/nt/shell32/StrNCmpA.s new file mode 100644 index 00000000..864500e1 --- /dev/null +++ b/libc/nt/shell32/StrNCmpA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_StrNCmpA,StrNCmpA,599 diff --git a/libc/nt/shell32/StrNCmpIA.s b/libc/nt/shell32/StrNCmpIA.s new file mode 100644 index 00000000..50eea456 --- /dev/null +++ b/libc/nt/shell32/StrNCmpIA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_StrNCmpIA,StrNCmpIA,600 diff --git a/libc/nt/shell32/StrNCmpIW.s b/libc/nt/shell32/StrNCmpIW.s new file mode 100644 index 00000000..0d88f8b9 --- /dev/null +++ b/libc/nt/shell32/StrNCmpIW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_StrNCmpIW,StrNCmpIW,601 diff --git a/libc/nt/shell32/StrNCmpW.s b/libc/nt/shell32/StrNCmpW.s new file mode 100644 index 00000000..59c37dab --- /dev/null +++ b/libc/nt/shell32/StrNCmpW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_StrNCmpW,StrNCmpW,602 diff --git a/libc/nt/shell32/StrRStrA.s b/libc/nt/shell32/StrRStrA.s new file mode 100644 index 00000000..96fef5ab --- /dev/null +++ b/libc/nt/shell32/StrRStrA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_StrRStrA,StrRStrA,607 diff --git a/libc/nt/shell32/StrRStrW.s b/libc/nt/shell32/StrRStrW.s new file mode 100644 index 00000000..b4ab46db --- /dev/null +++ b/libc/nt/shell32/StrRStrW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_StrRStrW,StrRStrW,610 diff --git a/libc/nt/shell32/UsersLibrariesFolderUI_CreateInstance.s b/libc/nt/shell32/UsersLibrariesFolderUI_CreateInstance.s new file mode 100644 index 00000000..2b3f989e --- /dev/null +++ b/libc/nt/shell32/UsersLibrariesFolderUI_CreateInstance.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_UsersLibrariesFolderUI_CreateInstance,UsersLibrariesFolderUI_CreateInstance,615 diff --git a/libc/nt/shell32/WOWShellExecute.s b/libc/nt/shell32/WOWShellExecute.s new file mode 100644 index 00000000..4929181d --- /dev/null +++ b/libc/nt/shell32/WOWShellExecute.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_WOWShellExecute,WOWShellExecute,616 diff --git a/libc/nt/shell32/WaitForExplorerRestartW.s b/libc/nt/shell32/WaitForExplorerRestartW.s new file mode 100644 index 00000000..93ff8b9a --- /dev/null +++ b/libc/nt/shell32/WaitForExplorerRestartW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_WaitForExplorerRestartW,WaitForExplorerRestartW,617 diff --git a/libc/nt/shell32/Win32DeleteFile.s b/libc/nt/shell32/Win32DeleteFile.s new file mode 100644 index 00000000..53a8667b --- /dev/null +++ b/libc/nt/shell32/Win32DeleteFile.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_Win32DeleteFile,Win32DeleteFile,164 diff --git a/libc/nt/shell32/WriteCabinetState.s b/libc/nt/shell32/WriteCabinetState.s new file mode 100644 index 00000000..3a6fcd73 --- /dev/null +++ b/libc/nt/shell32/WriteCabinetState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp shell32,__imp_WriteCabinetState,WriteCabinetState,652 diff --git a/libc/nt/signals.h b/libc/nt/signals.h new file mode 100644 index 00000000..d391f190 --- /dev/null +++ b/libc/nt/signals.h @@ -0,0 +1,87 @@ +#ifndef COSMOPOLITAN_LIBC_NT_EXCEPTIONS_H_ +#define COSMOPOLITAN_LIBC_NT_EXCEPTIONS_H_ +#include "libc/nt/enum/errormodeflags.h" +#include "libc/nt/struct/context.h" +#include "libc/nt/thunk/msabi.h" +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » signals ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +#define kNtSignalBreakpoint 0x80000003u +#define kNtSignalIllegalInstruction 0xC000001Du +#define kNtSignalPrivInstruction 0xC0000096u +#define kNtSignalGuardPage 0x80000001u +#define kNtSignalAccessViolation 0xC0000005u +#define kNtSignalInPageError 0xC0000006u +#define kNtSignalInvalidHandle 0xC0000008u +#define kNtSignalInvalidParameter 0xC000000du +#define kNtSignalFltDenormalOperand 0xC000008Du +#define kNtSignalFltDivideByZero 0xC000008Eu +#define kNtSignalFltInexactResult 0xC000008Fu +#define kNtSignalFltInvalidOperation 0xC0000090u +#define kNtSignalFltOverflow 0xC0000091u +#define kNtSignalFltStackCheck 0xC0000092u +#define kNtSignalFltUnderflow 0xC0000093u +#define kNtSignalIntegerDivideByZero 0xC0000094u +#define kNtSignalDllNotFound 0xC0000135u +#define kNtSignalOrdinalNotFound 0xC0000138u +#define kNtSignalEntrypointNotFound 0xC0000139u +#define kNtSignalControlCExit 0xC000013Au +#define kNtSignalDllInitFailed 0xC0000142u +#define kNtSignalFloatMultipleFaults 0xC00002B4u +#define kNtSignalFloatMultipleTraps 0xC00002B5u +#define kNtSignalAssertionFailure 0xC0000420u + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtExceptionPointers; + +typedef enum NtExceptionHandlerActions (*NtTopLevelExceptionFilter)( + const struct NtExceptionPointers *ExceptionInfo); + +typedef int32_t (*NtVectoredExceptionHandler)( + struct NtExceptionPointers *ExceptionInfo); + +enum NtErrorModeFlags SetErrorMode(enum NtErrorModeFlags uMode); + +int64_t AddVectoredExceptionHandler(uint32_t First, + NtVectoredExceptionHandler pHandler); +int64_t AddVectoredContinueHandler(uint32_t First, + NtVectoredExceptionHandler pHandler); + +uint32_t RemoveVectoredExceptionHandler(int64_t hHandle); +uint32_t RemoveVectoredContinueHandler(int64_t hHandle); + +NtTopLevelExceptionFilter SetUnhandledExceptionFilter( + NtTopLevelExceptionFilter opt_lpTopLevelExceptionFilter); + +#if ShouldUseMsabiAttribute() +#include "libc/nt/thunk/signals.inc" +#endif /* ShouldUseMsabiAttribute() */ +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_EXCEPTIONS_H_ */ diff --git a/libc/nt/startupinfo.h b/libc/nt/startupinfo.h new file mode 100644 index 00000000..45b0cc60 --- /dev/null +++ b/libc/nt/startupinfo.h @@ -0,0 +1,29 @@ +#ifndef COSMOPOLITAN_LIBC_NT_NTSTARTUPINFO_H_ +#define COSMOPOLITAN_LIBC_NT_NTSTARTUPINFO_H_ +#include "libc/nt/thunk/msabi.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtStartupInfo; +struct NtProcThreadAttributeList; /* opaque */ + +void GetStartupInfo(struct NtStartupInfo *lpStartupInfo); + +bool32 InitializeProcThreadAttributeList( + struct NtProcThreadAttributeList *opt_inout_lpAttributeList, + uint32_t dwAttributeCount, uint32_t reserved_dwFlags, size_t *inout_lpSize) + paramsnonnull((4)); +bool32 UpdateProcThreadAttribute( + struct NtProcThreadAttributeList *inout_lpAttributeList, uint32_t dwFlags, + const uint32_t *Attribute, const void *lpValue, size_t cbSize, + void *reserved_lpPreviousValue, size_t *reserved_lpReturnSize) + paramsnonnull((1, 3, 4)); +void DeleteProcThreadAttributeList( + struct NtProcThreadAttributeList *inout_lpAttributeList) paramsnonnull(); + +#if ShouldUseMsabiAttribute() +#include "libc/nt/thunk/startupinfo.inc" +#endif /* ShouldUseMsabiAttribute() */ +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_NTSTARTUPINFO_H_ */ diff --git a/libc/nt/struct/acl.h b/libc/nt/struct/acl.h new file mode 100644 index 00000000..9b374d9e --- /dev/null +++ b/libc/nt/struct/acl.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_ACL_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_ACL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtAcl { + uint8_t AclRevision; + uint8_t Sbz1; + uint16_t AclSize; + uint16_t AceCount; + uint16_t Sbz2; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_ACL_H_ */ diff --git a/libc/nt/struct/ansistring.h b/libc/nt/struct/ansistring.h new file mode 100644 index 00000000..58195f4c --- /dev/null +++ b/libc/nt/struct/ansistring.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_ANSISTRING_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_ANSISTRING_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtAnsiString { + unsigned short Length; + unsigned short MaximumLength; + char *Buffer; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_ANSISTRING_H_ */ diff --git a/libc/nt/struct/byhandlefileinformation.h b/libc/nt/struct/byhandlefileinformation.h new file mode 100644 index 00000000..0a258e9a --- /dev/null +++ b/libc/nt/struct/byhandlefileinformation.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_BYHANDLEFILEINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_BYHANDLEFILEINFORMATION_H_ +#include "libc/nt/struct/filetime.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtByHandleFileInformation { + uint32_t dwFileAttributes; /* ←NtFileFlagAndAttributes */ + struct NtFileTime ftCreationFileTime; + struct NtFileTime ftLastAccessFileTime; + struct NtFileTime ftLastWriteFileTime; + uint32_t dwVolumeSerialNumber; + uint32_t nFileSizeHigh; + uint32_t nFileSizeLow; + uint32_t nNumberOfLinks; + uint32_t nFileIndexHigh; + uint32_t nFileIndexLow; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_BYHANDLEFILEINFORMATION_H_ */ diff --git a/libc/nt/struct/charinfo.h b/libc/nt/struct/charinfo.h new file mode 100644 index 00000000..c66621db --- /dev/null +++ b/libc/nt/struct/charinfo.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_CHARINFO_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_CHARINFO_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtCharInfo { + union { + char16_t UnicodeChar; + char AsciiChar; + } Char; + uint16_t Attributes; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_CHARINFO_H_ */ diff --git a/libc/nt/struct/clientid.h b/libc/nt/struct/clientid.h new file mode 100644 index 00000000..05b1e03f --- /dev/null +++ b/libc/nt/struct/clientid.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_CLIENTID_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_CLIENTID_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtClientId { + void *UniqueProcess; + void *UniqueThread; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_CLIENTID_H_ */ diff --git a/libc/nt/struct/consolecursorinfo.h b/libc/nt/struct/consolecursorinfo.h new file mode 100644 index 00000000..2aca0f5b --- /dev/null +++ b/libc/nt/struct/consolecursorinfo.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_CONSOLECURSORINFO_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_CONSOLECURSORINFO_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtConsoleCursorInfo { + uint32_t dwSize; + bool32 bVisible; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_CONSOLECURSORINFO_H_ */ diff --git a/libc/nt/struct/consolescreenbufferinfo.h b/libc/nt/struct/consolescreenbufferinfo.h new file mode 100644 index 00000000..3ca6757e --- /dev/null +++ b/libc/nt/struct/consolescreenbufferinfo.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_CONSOLESCREENBUFFERINFO_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_CONSOLESCREENBUFFERINFO_H_ +#include "libc/nt/struct/coord.h" +#include "libc/nt/struct/smallrect.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtConsoleScreenBufferInfo { + struct NtCoord dwSize; + struct NtCoord dwCursorPosition; + uint16_t wAttributes; + struct NtSmallRect srWindow; + struct NtCoord dwMaximumWindowSize; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_CONSOLESCREENBUFFERINFO_H_ */ diff --git a/libc/nt/struct/consolescreenbufferinfoex.h b/libc/nt/struct/consolescreenbufferinfoex.h new file mode 100644 index 00000000..087f571a --- /dev/null +++ b/libc/nt/struct/consolescreenbufferinfoex.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_CONSOLESCREENBUFFERINFOEX_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_CONSOLESCREENBUFFERINFOEX_H_ +#include "libc/nt/struct/coord.h" +#include "libc/nt/struct/smallrect.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtConsoleScreenBufferInfoEx { + uint32_t cbSize; /* sizeof(struct NtConsoleScreenBufferInfoEx) */ + struct NtCoord dwSize; + struct NtCoord dwCursorPosition; + uint16_t wAttributes; /* kNt{Foreground,Background}... */ + struct NtSmallRect srWindow; + struct NtCoord dwMaximumWindowSize; + uint16_t wPopupAttributes; + bool32 bFullscreenSupported; + uint32_t ColorTable[16]; /* 0x00BBGGRR */ +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_CONSOLESCREENBUFFERINFOEX_H_ */ diff --git a/libc/nt/struct/consoleselectioninfo.h b/libc/nt/struct/consoleselectioninfo.h new file mode 100644 index 00000000..270b30a5 --- /dev/null +++ b/libc/nt/struct/consoleselectioninfo.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_CONSOLESELECTIONINFO_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_CONSOLESELECTIONINFO_H_ +#include "libc/nt/struct/coord.h" +#include "libc/nt/struct/smallrect.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtConsoleSelectionInfo { + uint32_t dwFlags; + struct NtCoord dwSelectionAnchor; + struct NtSmallRect srSelection; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_CONSOLESELECTIONINFO_H_ */ diff --git a/libc/nt/struct/context.h b/libc/nt/struct/context.h new file mode 100644 index 00000000..d15dceb6 --- /dev/null +++ b/libc/nt/struct/context.h @@ -0,0 +1,59 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_CONTEXT_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_CONTEXT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtM128A { + uint64_t Low; + int64_t High; +} aligned(16); + +struct NtXmmSaveArea32 { + uint16_t ControlWord; + uint16_t StatusWord; + uint8_t TagWord; + uint8_t Reserved1; + uint16_t ErrorOpcode; + uint32_t ErrorOffset; + uint16_t ErrorSelector; + uint16_t Reserved2; + uint32_t DataOffset; + uint16_t DataSelector; + uint16_t Reserved3; + uint32_t MxCsr; + uint32_t MxCsr_Mask; + struct NtM128A FloatRegisters[8]; + struct NtM128A XmmRegisters[16]; + uint8_t Reserved4[96]; +}; + +struct NtContext { + uint64_t P1Home, P2Home, P3Home, P4Home, P5Home, P6Home; + uint32_t ContextFlags; + uint32_t MxCsr; + uint16_t SegCs, SegDs, SegEs, SegFs, SegGs, SegSs; + uint32_t EFlags; + uint64_t Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; + uint64_t Rax, Rcx, Rdx, Rbx, Rsp, Rbp, Rsi, Rdi; + uint64_t R8, R9, R10, R11, R12, R13, R14, R15; + uint64_t Rip; + union { + struct NtXmmSaveArea32 FltSave; + struct NtXmmSaveArea32 FloatSave; + struct { + struct NtM128A Header[2]; + struct NtM128A Legacy[8]; + struct NtM128A Xmm0, Xmm1, Xmm2, Xmm3, Xmm4, Xmm5, Xmm6, Xmm7; + struct NtM128A Xmm8, Xmm9, Xmm10, Xmm11, Xmm12, Xmm13, Xmm14, Xmm15; + }; + }; + struct NtM128A VectorRegister[26]; + uint64_t VectorControl; + uint64_t DebugControl; + uint64_t LastBranchToRip; + uint64_t LastBranchFromRip; + uint64_t LastExceptionToRip; + uint64_t LastExceptionFromRip; +} aligned(16); + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_CONTEXT_H_ */ diff --git a/libc/nt/struct/coord.h b/libc/nt/struct/coord.h new file mode 100644 index 00000000..e4c0d0c4 --- /dev/null +++ b/libc/nt/struct/coord.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_COORD_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_COORD_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtCoord { + int16_t X; + int16_t Y; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_COORD_H_ */ diff --git a/libc/nt/struct/criticalsection.h b/libc/nt/struct/criticalsection.h new file mode 100644 index 00000000..289c86a9 --- /dev/null +++ b/libc/nt/struct/criticalsection.h @@ -0,0 +1,17 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_CRITICALSECTION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_CRITICALSECTION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtCriticalSectionDebug; + +struct NtCriticalSection { + struct NtCriticalSectionDebug *DebugInfo; + int32_t LockCount; + int32_t RecursionCount; + void *OwningThread; + void *LockSemaphore; + uintptr_t SpinCount; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_CRITICALSECTION_H_ */ diff --git a/libc/nt/struct/criticalsectiondebug.h b/libc/nt/struct/criticalsectiondebug.h new file mode 100644 index 00000000..6a62c315 --- /dev/null +++ b/libc/nt/struct/criticalsectiondebug.h @@ -0,0 +1,19 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_CRITICALSECTIONDEBUG_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_CRITICALSECTIONDEBUG_H_ +#include "libc/nt/struct/linkedlist.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtCriticalSection; + +struct NtCriticalSectionDebug { + uint16_t Type; + uint16_t CreatorBackTraceIndex; + struct NtCriticalSection *CriticalSection; + struct NtLinkedList ProcessLocksList; + uint32_t EntryCount; + uint32_t ContentionCount; + uint32_t Spare[2]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_CRITICALSECTIONDEBUG_H_ */ diff --git a/libc/nt/struct/exceptionframe.h b/libc/nt/struct/exceptionframe.h new file mode 100644 index 00000000..59449cac --- /dev/null +++ b/libc/nt/struct/exceptionframe.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_EXCEPTIONFRAME_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_EXCEPTIONFRAME_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtExceptionFrame { + struct NtExceptionFrame *Prev; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_EXCEPTIONFRAME_H_ */ diff --git a/libc/nt/struct/fileaccessinformation.h b/libc/nt/struct/fileaccessinformation.h new file mode 100644 index 00000000..4049ae98 --- /dev/null +++ b/libc/nt/struct/fileaccessinformation.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEACCESSINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEACCESSINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileAccessInformation { + uint32_t AccessFlags; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEACCESSINFORMATION_H_ */ diff --git a/libc/nt/struct/filealignmentinformation.h b/libc/nt/struct/filealignmentinformation.h new file mode 100644 index 00000000..67008b93 --- /dev/null +++ b/libc/nt/struct/filealignmentinformation.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEALIGNMENTINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEALIGNMENTINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileAlignmentInformation { + uint32_t AlignmentRequirement; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEALIGNMENTINFORMATION_H_ */ diff --git a/libc/nt/struct/fileallinformation.h b/libc/nt/struct/fileallinformation.h new file mode 100644 index 00000000..4a6ebfeb --- /dev/null +++ b/libc/nt/struct/fileallinformation.h @@ -0,0 +1,27 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEALLINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEALLINFORMATION_H_ +#include "libc/nt/struct/fileaccessinformation.h" +#include "libc/nt/struct/filealignmentinformation.h" +#include "libc/nt/struct/filebasicinformation.h" +#include "libc/nt/struct/fileeainformation.h" +#include "libc/nt/struct/fileinternalinformation.h" +#include "libc/nt/struct/filemodeinformation.h" +#include "libc/nt/struct/filenameinformation.h" +#include "libc/nt/struct/filepositioninformation.h" +#include "libc/nt/struct/filestandardinformation.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileAllInformation { + struct NtFileBasicInformation BasicInformation; + struct NtFileStandardInformation StandardInformation; + struct NtFileInternalInformation InternalInformation; + struct NtFileEaInformation EaInformation; + struct NtFileAccessInformation AccessInformation; + struct NtFilePositionInformation PositionInformation; + struct NtFileModeInformation ModeInformation; + struct NtFileAlignmentInformation AlignmentInformation; + struct NtFileNameInformation NameInformation; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEALLINFORMATION_H_ */ diff --git a/libc/nt/struct/fileallocationinformation.h b/libc/nt/struct/fileallocationinformation.h new file mode 100644 index 00000000..d95fd274 --- /dev/null +++ b/libc/nt/struct/fileallocationinformation.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEALLOCATIONINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEALLOCATIONINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileAllocationInformation { + int64_t AllocationSize; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEALLOCATIONINFORMATION_H_ */ diff --git a/libc/nt/struct/fileattributetaginformation.h b/libc/nt/struct/fileattributetaginformation.h new file mode 100644 index 00000000..76ce8e38 --- /dev/null +++ b/libc/nt/struct/fileattributetaginformation.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEATTRIBUTETAGINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEATTRIBUTETAGINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileAttributeTagInformation { + uint32_t FileAttributes; + uint32_t ReparseTag; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEATTRIBUTETAGINFORMATION_H_ */ diff --git a/libc/nt/struct/filebasicinfo.h b/libc/nt/struct/filebasicinfo.h new file mode 100644 index 00000000..584b5738 --- /dev/null +++ b/libc/nt/struct/filebasicinfo.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEBASICINFO_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEBASICINFO_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileBasicInfo { + int64_t CreationTime; /* in 100ns units */ + int64_t LastAccessTime; /* in 100ns units */ + int64_t LastWriteTime; /* in 100ns units */ + int64_t ChangeTime; /* in 100ns units */ + uint32_t FileAttributes; /* kNtFileAttributeXXX */ +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEBASICINFO_H_ */ diff --git a/libc/nt/struct/filebasicinformation.h b/libc/nt/struct/filebasicinformation.h new file mode 100644 index 00000000..d91db4ae --- /dev/null +++ b/libc/nt/struct/filebasicinformation.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEBASICINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEBASICINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileBasicInformation { + int64_t CreationTime; /* in 100ns units */ + int64_t LastAccessTime; /* in 100ns units */ + int64_t LastWriteTime; /* in 100ns units */ + int64_t ChangeTime; /* in 100ns units */ + uint32_t FileAttributes; /* kNtFileAttributeXXX */ +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEBASICINFORMATION_H_ */ diff --git a/libc/nt/struct/filebothdirectoryinformation.h b/libc/nt/struct/filebothdirectoryinformation.h new file mode 100644 index 00000000..29087d63 --- /dev/null +++ b/libc/nt/struct/filebothdirectoryinformation.h @@ -0,0 +1,25 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEBOTHDIRECTORYINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEBOTHDIRECTORYINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtFileBothDirectoryInformation { + uint32_t NextEntryOffset; + uint32_t FileIndex; + int64_t CreationTime; + int64_t LastAccessTime; + int64_t LastWriteTime; + int64_t ChangeTime; + int64_t EndOfFile; + int64_t AllocationSize; + uint32_t FileAttributes; + uint32_t FileNameLength; + uint32_t EaSize; + unsigned char ShortNameLength; + char16_t ShortName[12]; + char16_t FileName[1]; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEBOTHDIRECTORYINFORMATION_H_ */ diff --git a/libc/nt/struct/filecompressioninfo.h b/libc/nt/struct/filecompressioninfo.h new file mode 100644 index 00000000..58402826 --- /dev/null +++ b/libc/nt/struct/filecompressioninfo.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILECOMPRESSIONINFO_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILECOMPRESSIONINFO_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileCompressionInfo { + int64_t CompressedFileSize; + uint16_t CompressionFormat; + uint8_t CompressionUnitShift; + uint8_t ChunkShift; + uint8_t ClusterShift; + uint8_t Reserved[3]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILECOMPRESSIONINFO_H_ */ diff --git a/libc/nt/struct/filedirectoryinformation.h b/libc/nt/struct/filedirectoryinformation.h new file mode 100644 index 00000000..badf4fd2 --- /dev/null +++ b/libc/nt/struct/filedirectoryinformation.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEDIRECTORYINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEDIRECTORYINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileDirectoryInformation { + uint32_t NextEntryOffset; + uint32_t FileIndex; + int64_t CreationTime; + int64_t LastAccessTime; + int64_t LastWriteTime; + int64_t ChangeTime; + int64_t EndOfFile; + int64_t AllocationSize; + uint32_t FileAttributes; + uint32_t FileNameLength; + char16_t FileName[1]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEDIRECTORYINFORMATION_H_ */ diff --git a/libc/nt/struct/filedispositioninformation.h b/libc/nt/struct/filedispositioninformation.h new file mode 100644 index 00000000..ed7b685f --- /dev/null +++ b/libc/nt/struct/filedispositioninformation.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEDISPOSITIONINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEDISPOSITIONINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileDispositionInformation { + bool32 DoDeleteFile; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEDISPOSITIONINFORMATION_H_ */ diff --git a/libc/nt/struct/fileeainformation.h b/libc/nt/struct/fileeainformation.h new file mode 100644 index 00000000..54597ba4 --- /dev/null +++ b/libc/nt/struct/fileeainformation.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEEAINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEEAINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileEaInformation { + uint32_t EaSize; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEEAINFORMATION_H_ */ diff --git a/libc/nt/struct/fileendoffileinformation.h b/libc/nt/struct/fileendoffileinformation.h new file mode 100644 index 00000000..4c840ae3 --- /dev/null +++ b/libc/nt/struct/fileendoffileinformation.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEENDOFFILEINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEENDOFFILEINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct FileEndOfFileInformation { + int64_t EndOfFile; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEENDOFFILEINFORMATION_H_ */ diff --git a/libc/nt/struct/filefulldirectoryinformation.h b/libc/nt/struct/filefulldirectoryinformation.h new file mode 100644 index 00000000..a07f12c4 --- /dev/null +++ b/libc/nt/struct/filefulldirectoryinformation.h @@ -0,0 +1,21 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEFULLDIRECTORYINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEFULLDIRECTORYINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileFullDirectoryInformation { + uint32_t NextEntryOffset; + uint32_t FileIndex; + int64_t CreationTime; + int64_t LastAccessTime; + int64_t LastWriteTime; + int64_t ChangeTime; + int64_t EndOfFile; + int64_t AllocationSize; + uint32_t FileAttributes; + uint32_t FileNameLength; + uint32_t EaSize; + char16_t FileName[1]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEFULLDIRECTORYINFORMATION_H_ */ diff --git a/libc/nt/struct/filefulleainformation.h b/libc/nt/struct/filefulleainformation.h new file mode 100644 index 00000000..f352d32d --- /dev/null +++ b/libc/nt/struct/filefulleainformation.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEFULLEAINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEFULLEAINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileFullEaInformation { + uint32_t NextEntryOffset; + uint8_t Flags; + uint8_t EaNameLength; + uint16_t EaValueLength; + char EaName[1]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEFULLEAINFORMATION_H_ */ diff --git a/libc/nt/struct/fileinternalinformation.h b/libc/nt/struct/fileinternalinformation.h new file mode 100644 index 00000000..0b7e2532 --- /dev/null +++ b/libc/nt/struct/fileinternalinformation.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEINTERNALINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEINTERNALINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileInternalInformation { + int64_t IndexNumber; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEINTERNALINFORMATION_H_ */ diff --git a/libc/nt/struct/filemailslotqueryinformation.h b/libc/nt/struct/filemailslotqueryinformation.h new file mode 100644 index 00000000..2c442037 --- /dev/null +++ b/libc/nt/struct/filemailslotqueryinformation.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEMAILSLOTQUERYINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEMAILSLOTQUERYINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileMailslotQueryInformation { + uint32_t MaximumMessageSize; + uint32_t MailslotQuota; + uint32_t NextMessageSize; + uint32_t MessagesAvailable; + int64_t ReadTimeout; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEMAILSLOTQUERYINFORMATION_H_ */ diff --git a/libc/nt/struct/filemailslotsetinformation.h b/libc/nt/struct/filemailslotsetinformation.h new file mode 100644 index 00000000..8bf13d9e --- /dev/null +++ b/libc/nt/struct/filemailslotsetinformation.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEMAILSLOTSETINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEMAILSLOTSETINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileMailslotSetInformation { + int64_t ReadTimeout; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEMAILSLOTSETINFORMATION_H_ */ diff --git a/libc/nt/struct/filemodeinformation.h b/libc/nt/struct/filemodeinformation.h new file mode 100644 index 00000000..d5333001 --- /dev/null +++ b/libc/nt/struct/filemodeinformation.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEMODEINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEMODEINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileModeInformation { + uint32_t Mode; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEMODEINFORMATION_H_ */ diff --git a/libc/nt/struct/filenameinformation.h b/libc/nt/struct/filenameinformation.h new file mode 100644 index 00000000..0c0607f8 --- /dev/null +++ b/libc/nt/struct/filenameinformation.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILENAMEINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILENAMEINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileNameInformation { + uint32_t FileNameLength; + char16_t FileName[1]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILENAMEINFORMATION_H_ */ diff --git a/libc/nt/struct/filenamesinformation.h b/libc/nt/struct/filenamesinformation.h new file mode 100644 index 00000000..5bf97638 --- /dev/null +++ b/libc/nt/struct/filenamesinformation.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILENAMESINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILENAMESINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileNamesInformation { + uint32_t NextEntryOffset; + uint32_t FileIndex; + uint32_t FileNameLength; + char16_t FileName[1]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILENAMESINFORMATION_H_ */ diff --git a/libc/nt/struct/filenetworkopeninformation.h b/libc/nt/struct/filenetworkopeninformation.h new file mode 100644 index 00000000..c5e80423 --- /dev/null +++ b/libc/nt/struct/filenetworkopeninformation.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILENETWORKOPENINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILENETWORKOPENINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileNetworkOpenInformation { + int64_t CreationTime; + int64_t LastAccessTime; + int64_t LastWriteTime; + int64_t ChangeTime; + int64_t AllocationSize; + int64_t EndOfFile; + uint32_t FileAttributes; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILENETWORKOPENINFORMATION_H_ */ diff --git a/libc/nt/struct/filepipelocalinformation.h b/libc/nt/struct/filepipelocalinformation.h new file mode 100644 index 00000000..545d3b4c --- /dev/null +++ b/libc/nt/struct/filepipelocalinformation.h @@ -0,0 +1,19 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEPIPELOCALINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEPIPELOCALINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFilePipeLocalInformation { + uint32_t NamedPipeType; + uint32_t NamedPipeConfiguration; + uint32_t MaximumInstances; + uint32_t CurrentInstances; + uint32_t InboundQuota; + uint32_t ReadDataAvailable; + uint32_t OutboundQuota; + uint32_t WriteQuotaAvailable; + uint32_t NamedPipeState; + uint32_t NamedPipeEnd; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEPIPELOCALINFORMATION_H_ */ diff --git a/libc/nt/struct/filepositioninformation.h b/libc/nt/struct/filepositioninformation.h new file mode 100644 index 00000000..2c10a493 --- /dev/null +++ b/libc/nt/struct/filepositioninformation.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEPOSITIONINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEPOSITIONINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFilePositionInformation { + int64_t CurrentByteOffset; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEPOSITIONINFORMATION_H_ */ diff --git a/libc/nt/struct/filerenameinformation.h b/libc/nt/struct/filerenameinformation.h new file mode 100644 index 00000000..03c99c2f --- /dev/null +++ b/libc/nt/struct/filerenameinformation.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILERENAMEINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILERENAMEINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileRenameInformation { + bool32 Replace; + void *RootDir; + uint32_t FileNameLength; + char16_t FileName[1]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILERENAMEINFORMATION_H_ */ diff --git a/libc/nt/struct/filesegmentelement.h b/libc/nt/struct/filesegmentelement.h new file mode 100644 index 00000000..6e7e6a9e --- /dev/null +++ b/libc/nt/struct/filesegmentelement.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILESEGMENTELEMENT_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILESEGMENTELEMENT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +union NtFileSegmentElement { + void *Buffer; + uint64_t Alignment; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILESEGMENTELEMENT_H_ */ diff --git a/libc/nt/struct/filestandardinformation.h b/libc/nt/struct/filestandardinformation.h new file mode 100644 index 00000000..8bde3b4b --- /dev/null +++ b/libc/nt/struct/filestandardinformation.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILESTANDARDINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILESTANDARDINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileStandardInformation { + int64_t AllocationSize; + int64_t EndOfFile; + uint32_t NumberOfLinks; + bool32 DeletePending; + bool32 Directory; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILESTANDARDINFORMATION_H_ */ diff --git a/libc/nt/struct/filestreaminformation.h b/libc/nt/struct/filestreaminformation.h new file mode 100644 index 00000000..aa647aef --- /dev/null +++ b/libc/nt/struct/filestreaminformation.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILESTREAMINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILESTREAMINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileStreamInformation { + uint32_t NextEntryOffset; + uint32_t StreamNameLength; + int64_t StreamSize; + int64_t StreamAllocationSize; + char16_t StreamName[1]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILESTREAMINFORMATION_H_ */ diff --git a/libc/nt/struct/filetime.h b/libc/nt/struct/filetime.h new file mode 100644 index 00000000..882c7a74 --- /dev/null +++ b/libc/nt/struct/filetime.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_FILETIME_H_ +#define COSMOPOLITAN_LIBC_NT_FILETIME_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileTime { + uint32_t dwLowDateTime; + uint32_t dwHighDateTime; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_FILETIME_H_ */ diff --git a/libc/nt/struct/filezerodatainformation.h b/libc/nt/struct/filezerodatainformation.h new file mode 100644 index 00000000..0204a5fc --- /dev/null +++ b/libc/nt/struct/filezerodatainformation.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEZERODATAINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEZERODATAINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFileZeroDataInformation { + uint64_t FileOffset; + uint64_t BeyondFinalZero; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEZERODATAINFORMATION_H_ */ diff --git a/libc/nt/struct/fpodata.h b/libc/nt/struct/fpodata.h new file mode 100644 index 00000000..80eb982d --- /dev/null +++ b/libc/nt/struct/fpodata.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FPODATA_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_FPODATA_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtFpoData { + /* TODO(jart): No bitfields. */ + uint32_t ulOffStart; + uint32_t cbProcSize; + uint32_t cdwLocals; + uint16_t cdwParams; + uint16_t cbProlog : 8; + uint16_t cbRegs : 3; + uint16_t fHasSEH : 1; + uint16_t fUseBP : 1; + uint16_t reserved : 1; + uint16_t cbFrame : 2; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FPODATA_H_ */ diff --git a/libc/nt/struct/genericmapping.h b/libc/nt/struct/genericmapping.h new file mode 100644 index 00000000..67a8f3ff --- /dev/null +++ b/libc/nt/struct/genericmapping.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_GENERICMAPPING_H_ +#define COSMOPOLITAN_LIBC_NT_GENERICMAPPING_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtGenericMapping { + unsigned int GenericRead; + unsigned int GenericWrite; + unsigned int GenericExecute; + unsigned int GenericAll; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_GENERICMAPPING_H_ */ diff --git a/libc/nt/struct/imagearchivememberheader.h b/libc/nt/struct/imagearchivememberheader.h new file mode 100644 index 00000000..0c0760d7 --- /dev/null +++ b/libc/nt/struct/imagearchivememberheader.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEARCHIVEMEMBERHEADER_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEARCHIVEMEMBERHEADER_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageArchiveMemberHeader { + uint8_t Name[16]; + uint8_t Date[12]; + uint8_t UserID[6]; + uint8_t GroupID[6]; + uint8_t Mode[8]; + uint8_t Size[10]; + uint8_t EndHeader[2]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEARCHIVEMEMBERHEADER_H_ */ diff --git a/libc/nt/struct/imageauxsymbol.h b/libc/nt/struct/imageauxsymbol.h new file mode 100644 index 00000000..846af297 --- /dev/null +++ b/libc/nt/struct/imageauxsymbol.h @@ -0,0 +1,49 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEAUXSYMBOL_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEAUXSYMBOL_H_ +#include "libc/nt/pedef.h" +#include "libc/nt/struct/imageauxsymboltokendef.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +union NtImageAuxSymbol { + struct { + uint32_t TagIndex; + union { + struct { + uint16_t Linenumber; + uint16_t Size; + } LnSz; + uint32_t TotalSize; + } Misc; + union { + struct { + uint32_t PointerToLinenumber; + uint32_t PointerToNextFunction; + } Function; + struct { + uint16_t Dimension[4]; + } Array; + } FcnAry; + uint16_t TvIndex; + } Sym; + struct { + uint8_t Name[kNtImageSizeofSymbol]; + } File; + struct { + uint32_t Length; + uint16_t NumberOfRelocations; + uint16_t NumberOfLinenumbers; + uint32_t CheckSum; + uint16_t Number; + uint8_t Selection; + uint8_t bReserved; + uint16_t HighNumber; + } Section; + struct NtImageAuxSymbolTokenDef TokenDef; + struct { + uint32_t crc; + uint8_t rgbReserved[14]; + } CRC; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEAUXSYMBOL_H_ */ diff --git a/libc/nt/struct/imageauxsymbolex.h b/libc/nt/struct/imageauxsymbolex.h new file mode 100644 index 00000000..13876890 --- /dev/null +++ b/libc/nt/struct/imageauxsymbolex.h @@ -0,0 +1,38 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEAUXSYMBOLEX_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEAUXSYMBOLEX_H_ +#include "libc/nt/struct/imageauxsymboltokendef.h" +#include "libc/nt/struct/imagesymbolex.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +union NtImageAuxSymbolEx { + struct { + uint32_t WeakDefaultSymIndex; + uint32_t WeakSearchType; + uint8_t rgbReserved[12]; + } Sym; + struct { + uint8_t Name[sizeof(struct NtImageSymbolEx)]; + } File; + struct { + uint32_t Length; + uint16_t NumberOfRelocations; + uint16_t NumberOfLinenumbers; + uint32_t CheckSum; + uint16_t Number; + uint8_t Selection; + uint8_t bReserved; + uint16_t HighNumber; + uint8_t rgbReserved[2]; + } Section; + struct { + struct NtImageAuxSymbolTokenDef TokenDef; + uint8_t rgbReserved[2]; + }; + struct { + uint32_t crc; + uint8_t rgbReserved[16]; + } CRC; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEAUXSYMBOLEX_H_ */ diff --git a/libc/nt/struct/imageauxsymboltokendef.h b/libc/nt/struct/imageauxsymboltokendef.h new file mode 100644 index 00000000..4ab4ed18 --- /dev/null +++ b/libc/nt/struct/imageauxsymboltokendef.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEAUXSYMBOLTOKENDEF_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEAUXSYMBOLTOKENDEF_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageAuxSymbolTokenDef { + uint8_t bAuxType; + uint8_t bReserved; + uint32_t SymbolTableIndex; + uint8_t rgbReserved[12]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEAUXSYMBOLTOKENDEF_H_ */ diff --git a/libc/nt/struct/imagebaserelocation.h b/libc/nt/struct/imagebaserelocation.h new file mode 100644 index 00000000..19b6a182 --- /dev/null +++ b/libc/nt/struct/imagebaserelocation.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEBASERELOCATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEBASERELOCATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageBaseRelocation { + uint32_t VirtualAddress; + uint32_t SizeOfBlock; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEBASERELOCATION_H_ */ diff --git a/libc/nt/struct/imageboundforwarderref.h b/libc/nt/struct/imageboundforwarderref.h new file mode 100644 index 00000000..59c17a85 --- /dev/null +++ b/libc/nt/struct/imageboundforwarderref.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEBOUNDFORWARDERREF_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEBOUNDFORWARDERREF_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageBoundForwarderRef { + uint32_t TimeDateStamp; + uint16_t OffsetModuleName; + uint16_t Reserved; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEBOUNDFORWARDERREF_H_ */ diff --git a/libc/nt/struct/imageboundimportdescriptor.h b/libc/nt/struct/imageboundimportdescriptor.h new file mode 100644 index 00000000..6b67c46d --- /dev/null +++ b/libc/nt/struct/imageboundimportdescriptor.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEBOUNDIMPORTDESCRIPTOR_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEBOUNDIMPORTDESCRIPTOR_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageBoundImportDescriptor { + uint32_t TimeDateStamp; + uint16_t OffsetModuleName; + uint16_t NumberOfModuleForwarderRefs; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEBOUNDIMPORTDESCRIPTOR_H_ */ diff --git a/libc/nt/struct/imageceruntimefunctionentry.h b/libc/nt/struct/imageceruntimefunctionentry.h new file mode 100644 index 00000000..59c867ef --- /dev/null +++ b/libc/nt/struct/imageceruntimefunctionentry.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGECERUNTIMEFUNCTIONENTRY_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGECERUNTIMEFUNCTIONENTRY_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageCeRuntimeFunctionEntry { + uint32_t FuncStart; + uint32_t PrologLen : 8; + uint32_t FuncLen : 22; + uint32_t ThirtyTwoBit : 1; + uint32_t ExceptionFlag : 1; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGECERUNTIMEFUNCTIONENTRY_H_ */ diff --git a/libc/nt/struct/imagecoffsymbolsheader.h b/libc/nt/struct/imagecoffsymbolsheader.h new file mode 100644 index 00000000..7bed197b --- /dev/null +++ b/libc/nt/struct/imagecoffsymbolsheader.h @@ -0,0 +1,17 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGECOFFSYMBOLSHEADER_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGECOFFSYMBOLSHEADER_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageCoffSymbolsHeader { + uint32_t NumberOfSymbols; + uint32_t LvaToFirstSymbol; + uint32_t NumberOfLinenumbers; + uint32_t LvaToFirstLinenumber; + uint32_t RvaToFirstByteOfCode; + uint32_t RvaToLastByteOfCode; + uint32_t RvaToFirstByteOfData; + uint32_t RvaToLastByteOfData; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGECOFFSYMBOLSHEADER_H_ */ diff --git a/libc/nt/struct/imagedatadirectory.h b/libc/nt/struct/imagedatadirectory.h new file mode 100644 index 00000000..aa9553c6 --- /dev/null +++ b/libc/nt/struct/imagedatadirectory.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDATADIRECTORY_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDATADIRECTORY_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageDataDirectory { + uint32_t VirtualAddress; + uint32_t Size; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDATADIRECTORY_H_ */ diff --git a/libc/nt/struct/imagedebugdirectory.h b/libc/nt/struct/imagedebugdirectory.h new file mode 100644 index 00000000..abf7d860 --- /dev/null +++ b/libc/nt/struct/imagedebugdirectory.h @@ -0,0 +1,17 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDEBUGDIRECTORY_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDEBUGDIRECTORY_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageDebugDirectory { + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t Type; + uint32_t SizeOfData; + uint32_t AddressOfRawData; + uint32_t PointerToRawData; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDEBUGDIRECTORY_H_ */ diff --git a/libc/nt/struct/imagedebugmisc.h b/libc/nt/struct/imagedebugmisc.h new file mode 100644 index 00000000..30a5c5a3 --- /dev/null +++ b/libc/nt/struct/imagedebugmisc.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDEBUGMISC_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDEBUGMISC_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageDebugMisc { + uint32_t DataType; + uint32_t Length; + bool32 Unicode; + uint8_t Reserved[3]; + uint8_t Data[1]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDEBUGMISC_H_ */ diff --git a/libc/nt/struct/imagedelayloaddescriptor.h b/libc/nt/struct/imagedelayloaddescriptor.h new file mode 100644 index 00000000..87f2a5f8 --- /dev/null +++ b/libc/nt/struct/imagedelayloaddescriptor.h @@ -0,0 +1,23 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDELAYLOADDESCRIPTOR_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDELAYLOADDESCRIPTOR_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageDelayloadDescriptor { + union { + uint32_t AllAttributes; + struct { + uint32_t RvaBased : 1; + uint32_t ReservedAttributes : 31; + }; + } Attributes; + uint32_t DllNameRVA; + uint32_t ModuleHandleRVA; + uint32_t ImportAddressTableRVA; + uint32_t ImportNameTableRVA; + uint32_t BoundImportAddressTableRVA; + uint32_t UnloadInformationTableRVA; + uint32_t TimeDateStamp; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDELAYLOADDESCRIPTOR_H_ */ diff --git a/libc/nt/struct/imagedosheader.h b/libc/nt/struct/imagedosheader.h new file mode 100644 index 00000000..858b7726 --- /dev/null +++ b/libc/nt/struct/imagedosheader.h @@ -0,0 +1,28 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDOSHEADER_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDOSHEADER_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageDosHeader { + uint16_t e_magic; + uint16_t e_cblp; + uint16_t e_cp; + uint16_t e_crlc; + uint16_t e_cparhdr; + uint16_t e_minalloc; + uint16_t e_maxalloc; + uint16_t e_ss; + uint16_t e_sp; + uint16_t e_csum; + uint16_t e_ip; + uint16_t e_cs; + uint16_t e_lfarlc; + uint16_t e_ovno; + uint16_t e_res[4]; + uint16_t e_oemid; + uint16_t e_oeminfo; + uint16_t e_res2[10]; + uint32_t e_lfanew; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDOSHEADER_H_ */ diff --git a/libc/nt/struct/imagedynamicrelocation.h b/libc/nt/struct/imagedynamicrelocation.h new file mode 100644 index 00000000..4092e2b6 --- /dev/null +++ b/libc/nt/struct/imagedynamicrelocation.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDYNAMICRELOCATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDYNAMICRELOCATION_H_ +#include "libc/nt/struct/imagebaserelocation.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageDynamicRelocation { + uint64_t Symbol; + uint32_t BaseRelocSize; + struct NtImageBaseRelocation BaseRelocations[0]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDYNAMICRELOCATION_H_ */ diff --git a/libc/nt/struct/imagedynamicrelocationtable.h b/libc/nt/struct/imagedynamicrelocationtable.h new file mode 100644 index 00000000..b3d0e843 --- /dev/null +++ b/libc/nt/struct/imagedynamicrelocationtable.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDYNAMICRELOCATIONTABLE_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDYNAMICRELOCATIONTABLE_H_ +#include "libc/nt/struct/imagedynamicrelocation.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageDynamicRelocationTable { + uint32_t Version; + uint32_t Size; + struct NtImageDynamicRelocation DynamicRelocations[0]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDYNAMICRELOCATIONTABLE_H_ */ diff --git a/libc/nt/struct/imagedynamicrelocationv2.h b/libc/nt/struct/imagedynamicrelocationv2.h new file mode 100644 index 00000000..8b74684d --- /dev/null +++ b/libc/nt/struct/imagedynamicrelocationv2.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDYNAMICRELOCATIONV2_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDYNAMICRELOCATIONV2_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageDynamicRelocationV2 { + uint32_t HeaderSize; + uint32_t FixupInfoSize; + uint64_t Symbol; + uint32_t SymbolGroup; + uint32_t Flags; + uint8_t FixupInfo[0]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEDYNAMICRELOCATIONV2_H_ */ diff --git a/libc/nt/struct/imageenclaveconfig.h b/libc/nt/struct/imageenclaveconfig.h new file mode 100644 index 00000000..e970f2a1 --- /dev/null +++ b/libc/nt/struct/imageenclaveconfig.h @@ -0,0 +1,23 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEENCLAVECONFIG_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEENCLAVECONFIG_H_ +#include "libc/nt/pedef.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageEnclaveConfig { + uint32_t Size; + uint32_t MinimumRequiredConfigSize; + uint32_t PolicyFlags; + uint32_t NumberOfImports; + uint32_t ImportList; + uint32_t ImportEntrySize; + uint8_t FamilyID[kNtImageEnclaveShortIdLength]; + uint8_t ImageID[kNtImageEnclaveShortIdLength]; + uint32_t ImageVersion; + uint32_t SecurityVersion; + uint64_t EnclaveSize; + uint32_t NumberOfThreads; + uint32_t EnclaveFlags; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEENCLAVECONFIG_H_ */ diff --git a/libc/nt/struct/imageenclaveimport.h b/libc/nt/struct/imageenclaveimport.h new file mode 100644 index 00000000..2c4e5250 --- /dev/null +++ b/libc/nt/struct/imageenclaveimport.h @@ -0,0 +1,17 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEENCLAVEIMPORT_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEENCLAVEIMPORT_H_ +#include "libc/nt/pedef.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageEnclaveImport { + uint32_t MatchType; + uint32_t MinimumSecurityVersion; + uint8_t UniqueOrAuthorID[kNtImageEnclaveLongIdLength]; + uint8_t FamilyID[kNtImageEnclaveShortIdLength]; + uint8_t ImageID[kNtImageEnclaveShortIdLength]; + uint32_t ImportName; + uint32_t Reserved; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEENCLAVEIMPORT_H_ */ diff --git a/libc/nt/struct/imageepiloguedynamicrelocationheader.h b/libc/nt/struct/imageepiloguedynamicrelocationheader.h new file mode 100644 index 00000000..33273f7a --- /dev/null +++ b/libc/nt/struct/imageepiloguedynamicrelocationheader.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEEPILOGUEDYNAMICRELOCATIONHEADER_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEEPILOGUEDYNAMICRELOCATIONHEADER_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageEpilogueDynamicRelocationHeader { + uint32_t EpilogueCount; + uint8_t EpilogueByteCount; + uint8_t BranchDescriptorElementSize; + uint16_t BranchDescriptorCount; + /* uint8_t BranchDescriptors[...]; */ + /* uint8_t BranchDescriptorBitMap[...]; */ +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEEPILOGUEDYNAMICRELOCATIONHEADER_H_ \ + */ diff --git a/libc/nt/struct/imageexportdirectory.h b/libc/nt/struct/imageexportdirectory.h new file mode 100644 index 00000000..bbd9dc12 --- /dev/null +++ b/libc/nt/struct/imageexportdirectory.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEEXPORTDIRECTORY_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEEXPORTDIRECTORY_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageExportDirectory { + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t Name; + uint32_t Base; + uint32_t NumberOfFunctions; + uint32_t NumberOfNames; + uint32_t AddressOfFunctions; + uint32_t AddressOfNames; + uint32_t AddressOfNameOrdinals; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEEXPORTDIRECTORY_H_ */ diff --git a/libc/nt/struct/imagefileheader.h b/libc/nt/struct/imagefileheader.h new file mode 100644 index 00000000..0eaf97f7 --- /dev/null +++ b/libc/nt/struct/imagefileheader.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEFILEHEADER_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEFILEHEADER_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageFileHeader { + uint16_t Machine; + uint16_t NumberOfSections; + uint32_t TimeDateStamp; + uint32_t PointerToSymbolTable; + uint32_t NumberOfSymbols; + uint16_t SizeOfOptionalHeader; + uint16_t Characteristics; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEFILEHEADER_H_ */ diff --git a/libc/nt/struct/imagehotpatchbase.h b/libc/nt/struct/imagehotpatchbase.h new file mode 100644 index 00000000..950519d8 --- /dev/null +++ b/libc/nt/struct/imagehotpatchbase.h @@ -0,0 +1,17 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEHOTPATCHBASE_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEHOTPATCHBASE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageHotPatchBase { + uint32_t SequenceNumber; + uint32_t Flags; + uint32_t OriginalTimeDateStamp; + uint32_t OriginalCheckSum; + uint32_t CodeIntegrityInfo; + uint32_t CodeIntegritySize; + uint32_t PatchTable; + uint32_t BufferOffset; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEHOTPATCHBASE_H_ */ diff --git a/libc/nt/struct/imagehotpatchhashes.h b/libc/nt/struct/imagehotpatchhashes.h new file mode 100644 index 00000000..8e035f84 --- /dev/null +++ b/libc/nt/struct/imagehotpatchhashes.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEHOTPATCHHASHES_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEHOTPATCHHASHES_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageHotPatchHashes { + uint8_t SHA256[32]; + uint8_t SHA1[20]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEHOTPATCHHASHES_H_ */ diff --git a/libc/nt/struct/imagehotpatchinfo.h b/libc/nt/struct/imagehotpatchinfo.h new file mode 100644 index 00000000..d825f3b6 --- /dev/null +++ b/libc/nt/struct/imagehotpatchinfo.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEHOTPATCHINFO_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEHOTPATCHINFO_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageHotPatchInfo { + uint32_t Version; + uint32_t Size; + uint32_t SequenceNumber; + uint32_t BaseImageList; + uint32_t BaseImageCount; + uint32_t BufferOffset; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEHOTPATCHINFO_H_ */ diff --git a/libc/nt/struct/imageimportbyname.h b/libc/nt/struct/imageimportbyname.h new file mode 100644 index 00000000..b06bb0f9 --- /dev/null +++ b/libc/nt/struct/imageimportbyname.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEIMPORTBYNAME_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEIMPORTBYNAME_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageImportByName { + uint16_t Hint; + char Name[1]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEIMPORTBYNAME_H_ */ diff --git a/libc/nt/struct/imageimportdescriptor.h b/libc/nt/struct/imageimportdescriptor.h new file mode 100644 index 00000000..3f3d863c --- /dev/null +++ b/libc/nt/struct/imageimportdescriptor.h @@ -0,0 +1,17 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEIMPORTDESCRIPTOR_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEIMPORTDESCRIPTOR_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageImportDescriptor { + union { + uint32_t Characteristics; + uint32_t OriginalFirstThunk; + }; + uint32_t TimeDateStamp; + uint32_t ForwarderChain; + uint32_t Name; + uint32_t FirstThunk; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEIMPORTDESCRIPTOR_H_ */ diff --git a/libc/nt/struct/imagelinenumber.h b/libc/nt/struct/imagelinenumber.h new file mode 100644 index 00000000..19a2ca38 --- /dev/null +++ b/libc/nt/struct/imagelinenumber.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGELINENUMBER_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGELINENUMBER_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageLinenumber { + union { + uint32_t SymbolTableIndex; + uint32_t VirtualAddress; + } Type; + uint16_t Linenumber; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGELINENUMBER_H_ */ diff --git a/libc/nt/struct/imageloadconfigcodeintegrity.h b/libc/nt/struct/imageloadconfigcodeintegrity.h new file mode 100644 index 00000000..c73fb55f --- /dev/null +++ b/libc/nt/struct/imageloadconfigcodeintegrity.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGELOADCONFIGCODEINTEGRITY_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGELOADCONFIGCODEINTEGRITY_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageLoadConfigCodeIntegrity { + uint16_t Flags; + uint16_t Catalog; + uint32_t CatalogOffset; + uint32_t Reserved; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGELOADCONFIGCODEINTEGRITY_H_ */ diff --git a/libc/nt/struct/imageloadconfigdirectory.h b/libc/nt/struct/imageloadconfigdirectory.h new file mode 100644 index 00000000..cef2ee2c --- /dev/null +++ b/libc/nt/struct/imageloadconfigdirectory.h @@ -0,0 +1,51 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGELOADCONFIGDIRECTORY_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGELOADCONFIGDIRECTORY_H_ +#include "libc/nt/struct/imageloadconfigcodeintegrity.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageLoadConfigDirectory { + uint32_t Size; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t GlobalFlagsClear; + uint32_t GlobalFlagsSet; + uint32_t CriticalSectionDefaultTimeout; + uint64_t DeCommitFreeBlockThreshold; + uint64_t DeCommitTotalFreeThreshold; + uint64_t LockPrefixTable; + uint64_t MaximumAllocationSize; + uint64_t VirtualMemoryThreshold; + uint64_t ProcessAffinityMask; + uint32_t ProcessHeapFlags; + uint16_t CSDVersion; + uint16_t DependentLoadFlags; + uint64_t EditList; + uint64_t SecurityCookie; + uint64_t SEHandlerTable; + uint64_t SEHandlerCount; + uint64_t GuardCFCheckFunctionPointer; + uint64_t GuardCFDispatchFunctionPointer; + uint64_t GuardCFFunctionTable; + uint64_t GuardCFFunctionCount; + uint32_t GuardFlags; + struct NtImageLoadConfigCodeIntegrity CodeIntegrity; + uint64_t GuardAddressTakenIatEntryTable; + uint64_t GuardAddressTakenIatEntryCount; + uint64_t GuardLongJumpTargetTable; + uint64_t GuardLongJumpTargetCount; + uint64_t DynamicValueRelocTable; + uint64_t CHPEMetadataPointer; + uint64_t GuardRFFailureRoutine; + uint64_t GuardRFFailureRoutineFunctionPointer; + uint32_t DynamicValueRelocTableOffset; + uint16_t DynamicValueRelocTableSection; + uint16_t Reserved2; + uint64_t GuardRFVerifyStackPointerFunctionPointer; + uint32_t HotPatchTableOffset; + uint32_t Reserved3; + uint64_t EnclaveConfigurationPointer; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGELOADCONFIGDIRECTORY_H_ */ diff --git a/libc/nt/struct/imagentheaders.h b/libc/nt/struct/imagentheaders.h new file mode 100644 index 00000000..ea643b85 --- /dev/null +++ b/libc/nt/struct/imagentheaders.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGENTHEADERS_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGENTHEADERS_H_ +#include "libc/nt/struct/imagefileheader.h" +#include "libc/nt/struct/imageoptionalheader.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageNtHeaders { + uint32_t Signature; + struct NtImageFileHeader FileHeader; + struct NtImageOptionalHeader OptionalHeader; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGENTHEADERS_H_ */ diff --git a/libc/nt/struct/imageoptionalheader.h b/libc/nt/struct/imageoptionalheader.h new file mode 100644 index 00000000..552efe5d --- /dev/null +++ b/libc/nt/struct/imageoptionalheader.h @@ -0,0 +1,41 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEOPTIONALHEADER_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEOPTIONALHEADER_H_ +#include "libc/nt/pedef.h" +#include "libc/nt/struct/imagedatadirectory.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageOptionalHeader { + uint16_t Magic; + uint8_t MajorLinkerVersion; + uint8_t MinorLinkerVersion; + uint32_t SizeOfCode; + uint32_t SizeOfInitializedData; + uint32_t SizeOfUninitializedData; + uint32_t AddressOfEntryPoint; + uint32_t BaseOfCode; + uint64_t ImageBase; + uint32_t SectionAlignment; + uint32_t FileAlignment; + uint16_t MajorOperatingSystemVersion; + uint16_t MinorOperatingSystemVersion; + uint16_t MajorImageVersion; + uint16_t MinorImageVersion; + uint16_t MajorSubsystemVersion; + uint16_t MinorSubsystemVersion; + uint32_t Win32VersionValue; + uint32_t SizeOfImage; + uint32_t SizeOfHeaders; + uint32_t CheckSum; + uint16_t Subsystem; + uint16_t DllCharacteristics; + uint64_t SizeOfStackReserve; + uint64_t SizeOfStackCommit; + uint64_t SizeOfHeapReserve; + uint64_t SizeOfHeapCommit; + uint32_t LoaderFlags; + uint32_t NumberOfRvaAndSizes; + struct NtImageDataDirectory DataDirectory[kNtImageNumberofDirectoryEntries]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEOPTIONALHEADER_H_ */ diff --git a/libc/nt/struct/imageprologuedynamicrelocationheader.h b/libc/nt/struct/imageprologuedynamicrelocationheader.h new file mode 100644 index 00000000..3e1e8c51 --- /dev/null +++ b/libc/nt/struct/imageprologuedynamicrelocationheader.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEPROLOGUEDYNAMICRELOCATIONHEADER_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEPROLOGUEDYNAMICRELOCATIONHEADER_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImagePrologueDynamicRelocationHeader { + uint8_t PrologueByteCount; + uint8_t PrologueBytes[0]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEPROLOGUEDYNAMICRELOCATIONHEADER_H_ \ + */ diff --git a/libc/nt/struct/imagerelocation.h b/libc/nt/struct/imagerelocation.h new file mode 100644 index 00000000..f94c7064 --- /dev/null +++ b/libc/nt/struct/imagerelocation.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERELOCATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERELOCATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageRelocation { + union { + uint32_t VirtualAddress; + uint32_t RelocCount; + }; + uint32_t SymbolTableIndex; + uint16_t Type; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERELOCATION_H_ */ diff --git a/libc/nt/struct/imageresourcedataentry.h b/libc/nt/struct/imageresourcedataentry.h new file mode 100644 index 00000000..03858aca --- /dev/null +++ b/libc/nt/struct/imageresourcedataentry.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERESOURCEDATAENTRY_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERESOURCEDATAENTRY_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageResourceDataEntry { + uint32_t OffsetToData; + uint32_t Size; + uint32_t CodePage; + uint32_t Reserved; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERESOURCEDATAENTRY_H_ */ diff --git a/libc/nt/struct/imageresourcedirectory.h b/libc/nt/struct/imageresourcedirectory.h new file mode 100644 index 00000000..5a1c1fb4 --- /dev/null +++ b/libc/nt/struct/imageresourcedirectory.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERESOURCEDIRECTORY_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERESOURCEDIRECTORY_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageResourceDirectory { + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint16_t NumberOfNamedEntries; + uint16_t NumberOfIdEntries; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERESOURCEDIRECTORY_H_ */ diff --git a/libc/nt/struct/imageresourcedirectoryentry.h b/libc/nt/struct/imageresourcedirectoryentry.h new file mode 100644 index 00000000..1b1a357a --- /dev/null +++ b/libc/nt/struct/imageresourcedirectoryentry.h @@ -0,0 +1,25 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERESOURCEDIRECTORYENTRY_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERESOURCEDIRECTORYENTRY_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageResourceDirectoryEntry { + /* TODO(jart): No bitfields. */ + union { + struct { + uint32_t NameOffset : 31; + uint32_t NameIsString : 1; + }; + uint32_t Name; + uint16_t Id; + }; + union { + uint32_t OffsetToData; + struct { + uint32_t OffsetToDirectory : 31; + uint32_t DataIsDirectory : 1; + }; + }; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERESOURCEDIRECTORYENTRY_H_ */ diff --git a/libc/nt/struct/imageresourcedirstring.h b/libc/nt/struct/imageresourcedirstring.h new file mode 100644 index 00000000..dce59e8d --- /dev/null +++ b/libc/nt/struct/imageresourcedirstring.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERESOURCEDIRSTRING_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERESOURCEDIRSTRING_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageResourceDirString { + uint16_t Length; + char16_t NameString[1]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERESOURCEDIRSTRING_H_ */ diff --git a/libc/nt/struct/imageromoptionalheader.h b/libc/nt/struct/imageromoptionalheader.h new file mode 100644 index 00000000..1cb5a08c --- /dev/null +++ b/libc/nt/struct/imageromoptionalheader.h @@ -0,0 +1,22 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEROMOPTIONALHEADER_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEROMOPTIONALHEADER_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageRomOptionalHeader { + uint16_t Magic; + uint8_t MajorLinkerVersion; + uint8_t MinorLinkerVersion; + uint32_t SizeOfCode; + uint32_t SizeOfInitializedData; + uint32_t SizeOfUninitializedData; + uint32_t AddressOfEntryPoint; + uint32_t BaseOfCode; + uint32_t BaseOfData; + uint32_t BaseOfBss; + uint32_t GprMask; + uint32_t CprMask[4]; + uint32_t GpValue; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGEROMOPTIONALHEADER_H_ */ diff --git a/libc/nt/struct/imageruntimefunctionentry.h b/libc/nt/struct/imageruntimefunctionentry.h new file mode 100644 index 00000000..cb0e6dee --- /dev/null +++ b/libc/nt/struct/imageruntimefunctionentry.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERUNTIMEFUNCTIONENTRY_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERUNTIMEFUNCTIONENTRY_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageRuntimeFunctionEntry { + uint32_t BeginAddress; + uint32_t EndAddress; + union { + uint32_t UnwindInfoAddress; + uint32_t UnwindData; + }; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGERUNTIMEFUNCTIONENTRY_H_ */ diff --git a/libc/nt/struct/imagesectionheader.h b/libc/nt/struct/imagesectionheader.h new file mode 100644 index 00000000..8f857c69 --- /dev/null +++ b/libc/nt/struct/imagesectionheader.h @@ -0,0 +1,23 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGESECTIONHEADER_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGESECTIONHEADER_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +#include "libc/nt/pedef.h" + +struct NtImageSectionHeader { + uint8_t Name[kNtImageSizeofShortName]; + union { + uint32_t PhysicalAddress; + uint32_t VirtualSize; + } Misc; + uint32_t VirtualAddress; + uint32_t SizeOfRawData; + uint32_t PointerToRawData; + uint32_t PointerToRelocations; + uint32_t PointerToLinenumbers; + uint16_t NumberOfRelocations; + uint16_t NumberOfLinenumbers; + uint32_t Characteristics; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGESECTIONHEADER_H_ */ diff --git a/libc/nt/struct/imageseparatedebugheader.h b/libc/nt/struct/imageseparatedebugheader.h new file mode 100644 index 00000000..f7bf1a51 --- /dev/null +++ b/libc/nt/struct/imageseparatedebugheader.h @@ -0,0 +1,22 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGESEPARATEDEBUGHEADER_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGESEPARATEDEBUGHEADER_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageSeparateDebugHeader { + uint16_t Signature; + uint16_t Flags; + uint16_t Machine; + uint16_t Characteristics; + uint32_t TimeDateStamp; + uint32_t CheckSum; + uint32_t ImageBase; + uint32_t SizeOfImage; + uint32_t NumberOfSections; + uint32_t ExportedNamesSize; + uint32_t DebugDirectorySize; + uint32_t SectionAlignment; + uint32_t Reserved[2]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGESEPARATEDEBUGHEADER_H_ */ diff --git a/libc/nt/struct/imagesymbol.h b/libc/nt/struct/imagesymbol.h new file mode 100644 index 00000000..afadf3e8 --- /dev/null +++ b/libc/nt/struct/imagesymbol.h @@ -0,0 +1,22 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGESYMBOL_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGESYMBOL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageSymbol { + union { + uint8_t ShortName[8]; + struct { + uint32_t Short; + uint32_t Long; + } Name; + uint32_t LongName[2]; + } N; + uint32_t Value; + uint16_t SectionNumber; + uint16_t Type; + uint8_t StorageClass; + uint8_t NumberOfAuxSymbols; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGESYMBOL_H_ */ diff --git a/libc/nt/struct/imagesymbolex.h b/libc/nt/struct/imagesymbolex.h new file mode 100644 index 00000000..e6220a66 --- /dev/null +++ b/libc/nt/struct/imagesymbolex.h @@ -0,0 +1,22 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGESYMBOLEX_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGESYMBOLEX_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageSymbolEx { + union { + uint8_t ShortName[8]; + struct { + uint32_t Short; + uint32_t Long; + } Name; + uint32_t LongName[2]; + } N; + uint32_t Value; + int32_t SectionNumber; + uint16_t Type; + uint8_t StorageClass; + uint8_t NumberOfAuxSymbols; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGESYMBOLEX_H_ */ diff --git a/libc/nt/struct/imagethunkdata.h b/libc/nt/struct/imagethunkdata.h new file mode 100644 index 00000000..d4067e32 --- /dev/null +++ b/libc/nt/struct/imagethunkdata.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGETHUNKDATA_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGETHUNKDATA_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageThunkData { + union { + uint64_t ForwarderString; + uint64_t Function; + uint64_t Ordinal; + uint64_t AddressOfData; + } u1; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGETHUNKDATA_H_ */ diff --git a/libc/nt/struct/imagetlsdirectory.h b/libc/nt/struct/imagetlsdirectory.h new file mode 100644 index 00000000..604a532d --- /dev/null +++ b/libc/nt/struct/imagetlsdirectory.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMAGETLSDIRECTORY_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMAGETLSDIRECTORY_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImageTlsDirectory { + uint64_t StartAddressOfRawData; + uint64_t EndAddressOfRawData; + uint64_t AddressOfIndex; + uint64_t AddressOfCallBacks; + uint32_t SizeOfZeroFill; + uint32_t Characteristics; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMAGETLSDIRECTORY_H_ */ diff --git a/libc/nt/struct/importobjectheader.h b/libc/nt/struct/importobjectheader.h new file mode 100644 index 00000000..ce658b6a --- /dev/null +++ b/libc/nt/struct/importobjectheader.h @@ -0,0 +1,23 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IMPORTOBJECTHEADER_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IMPORTOBJECTHEADER_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtImportObjectHeader { + /* TODO(jart): No bitfields. */ + uint16_t Sig1; + uint16_t Sig2; + uint16_t Version; + uint16_t Machine; + uint32_t TimeDateStamp; + uint32_t SizeOfData; + union { + uint16_t Ordinal; + uint16_t Hint; + }; + uint16_t Type : 2; + uint16_t NameType : 3; + uint16_t Reserved : 11; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IMPORTOBJECTHEADER_H_ */ diff --git a/libc/nt/struct/inputrecord.h b/libc/nt/struct/inputrecord.h new file mode 100644 index 00000000..f2b02a7e --- /dev/null +++ b/libc/nt/struct/inputrecord.h @@ -0,0 +1,49 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_INPUTRECORD_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_INPUTRECORD_H_ +#include "libc/nt/struct/coord.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtKeyEventRecord { + bool32 bKeyDown; + uint16_t wRepeatCount; + uint16_t wVirtualKeyCode; + uint16_t wVirtualScanCode; + union { + int16_t UnicodeChar; + char AsciiChar; + } uChar; + unsigned int dwControlKeyState; +}; + +struct NtMouseEventRecord { + struct NtCoord dwMousePosition; + uint32_t dwButtonState; + uint32_t dwControlKeyState; + uint32_t dwEventFlags; +}; + +struct NtWindowBufferSizeRecord { + struct NtCoord dwSize; +}; + +struct NtMenuEventRecord { + uint32_t dwCommandId; +}; + +struct NtFocusEventRecord { + bool32 bSetFocus; +}; + +struct NtInputRecord { + uint16_t EventType; + union { + struct NtKeyEventRecord KeyEvent; + struct NtMouseEventRecord MouseEvent; + struct NtWindowBufferSizeRecord WindowBufferSizeEvent; + struct NtMenuEventRecord MenuEvent; + struct NtFocusEventRecord FocusEvent; + } Event; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_INPUTRECORD_H_ */ diff --git a/libc/nt/struct/iocounters.h b/libc/nt/struct/iocounters.h new file mode 100644 index 00000000..48fcf736 --- /dev/null +++ b/libc/nt/struct/iocounters.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IOCOUNTERS_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IOCOUNTERS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtIoCounters { + uint64_t ReadOperationCount; + uint64_t WriteOperationCount; + uint64_t OtherOperationCount; + uint64_t ReadTransferCount; + uint64_t WriteTransferCount; + uint64_t OtherTransferCount; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IOCOUNTERS_H_ */ diff --git a/libc/nt/struct/iostatusblock.h b/libc/nt/struct/iostatusblock.h new file mode 100644 index 00000000..4ed41a75 --- /dev/null +++ b/libc/nt/struct/iostatusblock.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_IOSTATUSBLOCK_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_IOSTATUSBLOCK_H_ +#include "libc/nt/enum/status.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtIoStatusBlock { + union { + NtStatus Status; + void *Pointer; /* reserved for internal use */ + }; + uint32_t *Information; /* request dependent */ +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IOSTATUSBLOCK_H_ */ diff --git a/libc/nt/struct/kernelusertimes.h b/libc/nt/struct/kernelusertimes.h new file mode 100644 index 00000000..3e42abfa --- /dev/null +++ b/libc/nt/struct/kernelusertimes.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_KERNELUSERTIMES_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_KERNELUSERTIMES_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtKernelUserTimes { + uint64_t CreateFileTime; + uint64_t ExitFileTime; + int64_t KernelTime; + int64_t UserTime; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_KERNELUSERTIMES_H_ */ diff --git a/libc/nt/struct/ldr.h b/libc/nt/struct/ldr.h new file mode 100644 index 00000000..e2a69269 --- /dev/null +++ b/libc/nt/struct/ldr.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_LDR_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_LDR_H_ +#include "libc/nt/struct/linkedlist.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtLdr { + uint32_t SizeOfThis; /* msdn:reserved */ + uint32_t IsInitialized; /* msdn:reserved */ + void *SsHandle; /* msdn:reserved */ + struct NtLinkedList InLoadOrderModuleList; /* msdn:reserved */ + struct NtLinkedList /*∩NtLdrDataTableEntry*/ InMemoryOrderModuleList; + struct NtLinkedList InInitOrderModuleList; /* msdn:reserved */ +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_LDR_H_ */ diff --git a/libc/nt/struct/ldrdatatableentry.h b/libc/nt/struct/ldrdatatableentry.h new file mode 100644 index 00000000..14a707cc --- /dev/null +++ b/libc/nt/struct/ldrdatatableentry.h @@ -0,0 +1,44 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_LDRDATATABLEENTRY_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_LDRDATATABLEENTRY_H_ +#include "libc/nt/struct/linkedlist.h" +#include "libc/nt/struct/unicodestring.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtLdrDataTableEntry { + struct NtLinkedList InLoadOrderLinks; /* msdn:reserved */ + struct NtLinkedList InMemoryOrderLinks; + struct NtLinkedList InInitOrderLinks; /* msdn:reserved */ + void *DllBase; + void *EntryPoint; + union { + uint32_t SizeOfImage; + unsigned char SizeOfImagePadding[__SIZEOF_POINTER__]; + }; + struct NtUnicodeString FullDllName; + struct NtUnicodeString BaseDllName; + uint32_t Flags; + uint16_t Load_Count; + uint16_t TlsIndex; + union { + struct NtLinkedList HashLinks; + struct { + void *SectionPointer; + uint32_t CheckSum; + }; + }; + union { + void *LoadedImports; + uint32_t TimeDateStamp; + }; + void *EntryPointActivationContext; + void *PatchInformation; + struct NtLinkedList ForwarderLinks; + struct NtLinkedList ServiceTagLinks; + struct NtLinkedList StaticLinks; + void *ContextInformation; + uintptr_t OriginalBase; + int64_t LoadTime; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_LDRDATATABLEENTRY_H_ */ diff --git a/libc/nt/struct/linkedlist.h b/libc/nt/struct/linkedlist.h new file mode 100644 index 00000000..461c1235 --- /dev/null +++ b/libc/nt/struct/linkedlist.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_LINKEDLIST_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_LINKEDLIST_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * Dynamic linked list overlay. + */ +struct NtLinkedList { + struct NtLinkedList *Next; + struct NtLinkedList *Prev; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_LINKEDLIST_H_ */ diff --git a/libc/nt/struct/luid.h b/libc/nt/struct/luid.h new file mode 100644 index 00000000..c6f35d36 --- /dev/null +++ b/libc/nt/struct/luid.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_LUID_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_LUID_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtLuid { + uint32_t LowPart; + int32_t HighPart; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_LUID_H_ */ diff --git a/libc/nt/struct/luidandattributes.h b/libc/nt/struct/luidandattributes.h new file mode 100644 index 00000000..8bf068ff --- /dev/null +++ b/libc/nt/struct/luidandattributes.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_LUIDANDATTRIBUTES_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_LUIDANDATTRIBUTES_H_ +#include "libc/nt/struct/luid.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtLuidAndAttributes { + struct NtLuid Luid; + uint32_t Attributes; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_LUIDANDATTRIBUTES_H_ */ diff --git a/libc/nt/struct/memorybasicinformation.h b/libc/nt/struct/memorybasicinformation.h new file mode 100644 index 00000000..c8895d9d --- /dev/null +++ b/libc/nt/struct/memorybasicinformation.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_MEMORYBASICINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_MEMORYBASICINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtMemoryBasicInformation { + void *BaseAddress; + void *AllocationBase; + uint32_t AllocationProtect; + uint64_t RegionSize; + uint32_t State; + uint32_t Protect; + uint32_t Type; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_MEMORYBASICINFORMATION_H_ */ diff --git a/libc/nt/struct/memoryrangeentry.h b/libc/nt/struct/memoryrangeentry.h new file mode 100644 index 00000000..63787981 --- /dev/null +++ b/libc/nt/struct/memoryrangeentry.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_MEMORYRANGEENTRY_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_MEMORYRANGEENTRY_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtMemoryRangeEntry { + void *VirtualAddress; + size_t NumberOfBytes; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_MEMORYRANGEENTRY_H_ */ diff --git a/libc/nt/struct/memorystatusex.h b/libc/nt/struct/memorystatusex.h new file mode 100644 index 00000000..9576f657 --- /dev/null +++ b/libc/nt/struct/memorystatusex.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_MEMORYSTATUSEX_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_MEMORYSTATUSEX_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtMemoryStatusEx { + uint32_t dwLength; + uint32_t dwMemoryLoad; + uint64_t ullTotalPhys; + uint64_t ullAvailPhys; + uint64_t ullTotalPageFile; + uint64_t ullAvailPageFile; + uint64_t ullTotalVirtual; + uint64_t ullAvailVirtual; + uint64_t ullAvailExtendedVirtual; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_MEMORYSTATUSEX_H_ */ diff --git a/libc/nt/struct/msg.h b/libc/nt/struct/msg.h new file mode 100644 index 00000000..a0790fad --- /dev/null +++ b/libc/nt/struct/msg.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_MSG_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_MSG_H_ +#include "libc/nt/struct/point.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtMsg { + int64_t hwnd; + uint32_t message; + uintptr_t wParam; + intptr_t lParam; + uint32_t time; + struct NtPoint pt; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_MSG_H_ */ diff --git a/libc/nt/struct/nonpageddebuginfo.h b/libc/nt/struct/nonpageddebuginfo.h new file mode 100644 index 00000000..f08c33cb --- /dev/null +++ b/libc/nt/struct/nonpageddebuginfo.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_NONPAGEDDEBUGINFO_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_NONPAGEDDEBUGINFO_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtNonPagedDebugInfo { + uint16_t Signature; + uint16_t Flags; + uint32_t Size; + uint16_t Machine; + uint16_t Characteristics; + uint32_t TimeDateStamp; + uint32_t CheckSum; + uint32_t SizeOfImage; + uint64_t ImageBase; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_NONPAGEDDEBUGINFO_H_ */ diff --git a/libc/nt/struct/ntexceptionpointers.h b/libc/nt/struct/ntexceptionpointers.h new file mode 100644 index 00000000..5d6c6e7d --- /dev/null +++ b/libc/nt/struct/ntexceptionpointers.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_NTEXCEPTIONPOINTERS_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_NTEXCEPTIONPOINTERS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtContext; +struct NtExceptionRecord; + +struct NtExceptionPointers { + struct NtExceptionRecord *ExceptionRecord; + struct NtContext *ContextRecord; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_NTEXCEPTIONPOINTERS_H_ */ diff --git a/libc/nt/struct/ntexceptionrecord.h b/libc/nt/struct/ntexceptionrecord.h new file mode 100644 index 00000000..ff1b50e4 --- /dev/null +++ b/libc/nt/struct/ntexceptionrecord.h @@ -0,0 +1,19 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_NTEXCEPTIONRECORD_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_NTEXCEPTIONRECORD_H_ + +#define kNtExceptionMaximumParameters 15 +#define kNtExceptionNoncontinuable 1 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtExceptionRecord { + uint32_t ExceptionCode; /* kNtException... */ + uint32_t ExceptionFlags; /* kNtExceptionNoncontinuable */ + struct NtExceptionRecord *ExceptionRecord; /* nested exceptions */ + void *ExceptionAddress; /* %rip */ + uint32_t NumberParameters; /* #ExceptionInformation */ + uint32_t *ExceptionInformation[kNtExceptionMaximumParameters]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_NTEXCEPTIONRECORD_H_ */ diff --git a/libc/nt/struct/objectallinformation.h b/libc/nt/struct/objectallinformation.h new file mode 100644 index 00000000..38797514 --- /dev/null +++ b/libc/nt/struct/objectallinformation.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_OBJECTALLINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_OBJECTALLINFORMATION_H_ +#include "libc/nt/struct/objecttypeinformation.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtObjectAllInformation { + uint32_t NumberOfObjects; + struct NtObjectTypeInformation ObjectTypeInformation[1]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_OBJECTALLINFORMATION_H_ */ diff --git a/libc/nt/struct/objectattributes.h b/libc/nt/struct/objectattributes.h new file mode 100644 index 00000000..55de4184 --- /dev/null +++ b/libc/nt/struct/objectattributes.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_LIBC_NT_I_OBJECTATTRIBUTES_H_ +#define COSMOPOLITAN_LIBC_NT_I_OBJECTATTRIBUTES_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtUnicodeString; +struct NtSecurityDescriptor; + +struct NtObjectAttributes { + uint32_t Length; + void *RootDirectory; + struct NtUnicodeString *ObjectName; + uint32_t Attributes; /* OBJ_INHERIT, etc. */ + struct NtSecurityDescriptor *SecurityDescriptor; + void *SecurityQualityOfService; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_I_OBJECTATTRIBUTES_H_ */ diff --git a/libc/nt/struct/objectbasicinformation.h b/libc/nt/struct/objectbasicinformation.h new file mode 100644 index 00000000..8eb056e8 --- /dev/null +++ b/libc/nt/struct/objectbasicinformation.h @@ -0,0 +1,21 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_OBJECTBASICINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_OBJECTBASICINFORMATION_H_ +#include "libc/nt/enum/accessmask.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtObjectBasicInformation { + uint32_t Attributes; + uint32_t GrantedAccess; + uint32_t HandleCount; + uint32_t PointerCount; + uint32_t PagedPoolUsage; + uint32_t NonPagedPoolUsage; + uint32_t Reserved[3]; + uint32_t NameInformationLength; + uint32_t TypeInformationLength; + uint32_t SecurityDescriptorLength; + int64_t CreateTime; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_OBJECTBASICINFORMATION_H_ */ diff --git a/libc/nt/struct/objectnameinformation.h b/libc/nt/struct/objectnameinformation.h new file mode 100644 index 00000000..4d942b66 --- /dev/null +++ b/libc/nt/struct/objectnameinformation.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_OBJECTNAMEINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_OBJECTNAMEINFORMATION_H_ +#include "libc/nt/struct/unicodestring.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtObjectNameInformation { + struct NtUnicodeString Name; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_OBJECTNAMEINFORMATION_H_ */ diff --git a/libc/nt/struct/objecttypeinformation.h b/libc/nt/struct/objecttypeinformation.h new file mode 100644 index 00000000..f153f129 --- /dev/null +++ b/libc/nt/struct/objecttypeinformation.h @@ -0,0 +1,32 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_OBJECTTYPEINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_OBJECTTYPEINFORMATION_H_ +#include "libc/nt/struct/genericmapping.h" +#include "libc/nt/struct/unicodestring.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtObjectTypeInformation { + struct NtUnicodeString TypeName; + uint32_t TotalNumberOfObjects; + uint32_t TotalNumberOfHandles; + uint32_t TotalPagedPoolUsage; + uint32_t TotalNonPagedPoolUsage; + uint32_t TotalNamePoolUsage; + uint32_t TotalHandleTableUsage; + uint32_t HighWaterNumberOfObjects; + uint32_t HighWaterNumberOfHandles; + uint32_t HighWaterPagedPoolUsage; + uint32_t HighWaterNonPagedPoolUsage; + uint32_t HighWaterNamePoolUsage; + uint32_t HighWaterHandleTableUsage; + uint32_t InvalidAttributes; + struct NtGenericMapping GenericMapping; + uint32_t ValidAccessMask; + bool32 SecurityRequired; + bool32 MaintainHandleCount; + uint32_t PoolType; + uint32_t DefaultPagedPoolCharge; + uint32_t DefaultNonPagedPoolCharge; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_OBJECTTYPEINFORMATION_H_ */ diff --git a/libc/nt/struct/overlapped.h b/libc/nt/struct/overlapped.h new file mode 100644 index 00000000..a957ea5c --- /dev/null +++ b/libc/nt/struct/overlapped.h @@ -0,0 +1,19 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_OVERLAPPED_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_OVERLAPPED_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtOverlapped { + uintptr_t Internal; + uintptr_t InternalHigh; + union { + struct { + uint32_t Offset; + uint32_t OffsetHigh; + }; + void *Pointer; + }; + int64_t hEvent; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_OVERLAPPED_H_ */ diff --git a/libc/nt/struct/peb.h b/libc/nt/struct/peb.h new file mode 100644 index 00000000..371a6d20 --- /dev/null +++ b/libc/nt/struct/peb.h @@ -0,0 +1,96 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_PEB_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_PEB_H_ +#include "libc/nt/struct/ldr.h" +#include "libc/nt/struct/unicodestring.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtPeb { + union { + struct { + unsigned char InheritedAddressSpace; + unsigned char ReadImageFileExecOptions; + unsigned char BeingDebugged; + unsigned char __wut1; + }; + uint64_t __wut2; + }; + uint64_t Mutant; + uint64_t ImageBaseAddress; + struct NtLdr *Ldr; + uint64_t ProcessParameters; + uint64_t SubSystemData; + uint64_t ProcessHeap; + uint64_t FastPebLock; + uint64_t __wut3; + uint64_t __wut4; + uint64_t __wut5; + union { + uint64_t KernelCallbackTable; + uint64_t UserSharedInfoPtr; + }; + uint32_t SystemReserved; + uint32_t __wut6; + uint64_t __wut7; + uint64_t TlsExpansionCounter; + uint64_t TlsBitmap; + uint32_t TlsBitmapBits[2]; + uint64_t ReadOnlySharedMemoryBase; + uint64_t __wut8; + uint64_t ReadOnlyStaticServerData; + uint64_t AnsiCodePageData; + uint64_t OemCodePageData; + uint64_t UnicodeCaseTableData; + uint32_t NumberOfProcessors; +#ifdef __x86_64__ + uint32_t NtGlobalFlag; +#else + uint64_t NtGlobalFlag; +#endif + int64_t CriticalSectionTimeout; + uint64_t HeapSegmentReserve; + uint64_t HeapSegmentCommit; + uint64_t HeapDeCommitTotalFreeThreshold; + uint64_t HeapDeCommitFreeBlockThreshold; + uint32_t NumberOfHeaps; + uint32_t MaximumNumberOfHeaps; + uint64_t ProcessHeaps; + uint64_t GdiSharedHandleTable; + uint64_t ProcessStarterHelper; + uint64_t GdiDCAttributeList; + uint64_t LoaderLock; + union { + struct { + uint32_t OSMajorVersion; + uint32_t OSMinorVersion; + }; + uint64_t OSVersion; + }; + uint16_t OSBuildNumber; + uint16_t OSCSDVersion; + uint32_t OSPlatformId; + uint32_t ImageSubsystem; + uint32_t ImageSubsystemMajorVersion; + uint64_t ImageSubsystemMinorVersion; + union { + uint64_t ImageProcessAffinityMask; + uint64_t ActiveProcessAffinityMask; + }; + uint64_t GdiHandleBuffer[38 - __SIZEOF_POINTER__]; + uint64_t PostProcessInitRoutine; + uint64_t TlsExpansionBitmap; + uint32_t TlsExpansionBitmapBits[32]; + uint64_t SessionId; + uint64_t AppCompatFlags; + uint64_t AppCompatFlagsUser; + uint64_t pShimData; + uint64_t AppCompatInfo; + struct NtUnicodeString CSDVersion; + uint64_t ActivationContextData; + uint64_t ProcessAssemblyStorageMap; + uint64_t SystemDefaultActivationContextData; + uint64_t SystemAssemblyStorageMap; + uint64_t MinimumStackCommit; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_PEB_H_ */ diff --git a/libc/nt/struct/point.h b/libc/nt/struct/point.h new file mode 100644 index 00000000..9eddde86 --- /dev/null +++ b/libc/nt/struct/point.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_POINT_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_POINT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtPoint { + int32_t x; + int32_t y; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_POINT_H_ */ diff --git a/libc/nt/struct/pollfd.h b/libc/nt/struct/pollfd.h new file mode 100644 index 00000000..b8fc6323 --- /dev/null +++ b/libc/nt/struct/pollfd.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_POLLFD_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_POLLFD_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct pollfd$nt { + int64_t handle; + int16_t events; + int16_t revents; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_POLLFD_H_ */ diff --git a/libc/nt/struct/privilegeset.h b/libc/nt/struct/privilegeset.h new file mode 100644 index 00000000..3f027c05 --- /dev/null +++ b/libc/nt/struct/privilegeset.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_PRIVILEGESET_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_PRIVILEGESET_H_ +#include "libc/nt/struct/luidandattributes.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtPrivilegeSet { + uint32_t PrivilegeCount; + uint32_t Control; + struct NtLuidAndAttributes Privilege[1]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_PRIVILEGESET_H_ */ diff --git a/libc/nt/struct/processbasicinformation.h b/libc/nt/struct/processbasicinformation.h new file mode 100644 index 00000000..1f34b751 --- /dev/null +++ b/libc/nt/struct/processbasicinformation.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_PROCESSBASICINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_PROCESSBASICINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtProcessBasicInformation { + int32_t ExitStatus; + struct NtPeb *PebBaseAddress; + uint32_t *AffinityMask; + int32_t BasePriority; + int64_t UniqueProcessId; + int64_t InheritedFromUniqueProcessId; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_PROCESSBASICINFORMATION_H_ */ diff --git a/libc/nt/struct/processinformation.h b/libc/nt/struct/processinformation.h new file mode 100644 index 00000000..cfe11749 --- /dev/null +++ b/libc/nt/struct/processinformation.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_PROCESSINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_PROCESSINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtProcessInformation { + int64_t hProcess; + int64_t hThread; + uint32_t dwProcessId; + uint32_t dwThreadId; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_PROCESSINFORMATION_H_ */ diff --git a/libc/nt/struct/rtluserprocessinformation.h b/libc/nt/struct/rtluserprocessinformation.h new file mode 100644 index 00000000..fdce24f6 --- /dev/null +++ b/libc/nt/struct/rtluserprocessinformation.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_RTLUSERPROCESSINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_RTLUSERPROCESSINFORMATION_H_ +#include "libc/nt/struct/clientid.h" +#include "libc/nt/struct/sectionimageinformation.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtRtlUserProcessInformation { + uint32_t SizeOfThis; + int64_t ProcessHandle; + int64_t ThreadHandle; + struct NtClientId ClientId; + struct NtSectionImageInformation ImageInformation; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_RTLUSERPROCESSINFORMATION_H_ */ diff --git a/libc/nt/struct/rtluserprocessparameters.h b/libc/nt/struct/rtluserprocessparameters.h new file mode 100644 index 00000000..fd5ca717 --- /dev/null +++ b/libc/nt/struct/rtluserprocessparameters.h @@ -0,0 +1,39 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_RTLUSERPROCESSPARAMETERS_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_RTLUSERPROCESSPARAMETERS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtUnicodeString; + +struct NtRtlUserProcessParameters { + uint32_t MaximumLength; + uint32_t Length; + uint32_t Flags; + uint32_t DebugFlags; + int64_t ConsoleHandle; + uint32_t ConsoleFlags; + int64_t StdInputHandle; + int64_t StdOutputHandle; + int64_t StdErrorHandle; + struct NtUnicodeString *CurrentDirectoryPath; + int64_t CurrentDirectoryHandle; + struct NtUnicodeString *DllPath; + struct NtUnicodeString *ImagePathName; + struct NtUnicodeString *CommandLine; + void *Environment; + uint32_t StartingPositionLeft; + uint32_t StartingPositionTop; + uint32_t Width; + uint32_t Height; + uint32_t CharWidth; + uint32_t CharHeight; + uint32_t ConsoleTextAttributes; + uint32_t WindowFlags; + uint32_t ShowWindowFlags; + struct NtUnicodeString *WindowTitle; + struct NtUnicodeString *DesktopName; + struct NtUnicodeString *ShellInfo; + struct NtUnicodeString *RuntimeData; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_RTLUSERPROCESSPARAMETERS_H_ */ diff --git a/libc/nt/struct/sectionimageinformation.h b/libc/nt/struct/sectionimageinformation.h new file mode 100644 index 00000000..b516df32 --- /dev/null +++ b/libc/nt/struct/sectionimageinformation.h @@ -0,0 +1,22 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SECTIONIMAGEINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SECTIONIMAGEINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSectionImageInformation { + void *EntryPoint; + uint32_t Unknown1; + uint32_t StackReserve; + uint32_t StackCommit; + uint32_t Subsystem; + uint16_t MinorSubsystemVersion; + uint16_t MajorSubsystemVersion; + uint32_t Unknown2; + uint32_t Characteristics; + uint16_t ImageNumber; + uint32_t IsExecutable; + uint8_t __wut1; + uint32_t __wut2[3]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SECTIONIMAGEINFORMATION_H_ */ diff --git a/libc/nt/struct/securityattributes.h b/libc/nt/struct/securityattributes.h new file mode 100644 index 00000000..7e388bbf --- /dev/null +++ b/libc/nt/struct/securityattributes.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SECURITYATTRIBUTES_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SECURITYATTRIBUTES_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSecurityDescriptor; + +struct NtSecurityAttributes { + uint32_t nLength; + struct NtSecurityDescriptor *lpSecurityDescriptor; + bool32 bInheritHandle; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SECURITYATTRIBUTES_H_ */ diff --git a/libc/nt/struct/securitydescriptor.h b/libc/nt/struct/securitydescriptor.h new file mode 100644 index 00000000..ad1e6392 --- /dev/null +++ b/libc/nt/struct/securitydescriptor.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SECURITYDESCRIPTOR_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SECURITYDESCRIPTOR_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtAcl; + +struct NtSecurityDescriptor { + uint8_t Revision; + uint8_t Sbz1; + uint16_t Control; + void *Owner; + void *Group; + struct NtAcl *Sacl; + struct NtAcl *Dacl; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SECURITYDESCRIPTOR_H_ */ diff --git a/libc/nt/struct/smallrect.h b/libc/nt/struct/smallrect.h new file mode 100644 index 00000000..d5c3765e --- /dev/null +++ b/libc/nt/struct/smallrect.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_SMALLRECT_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_SMALLRECT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSmallRect { + int16_t Left; + int16_t Top; + int16_t Right; + int16_t Bottom; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_SMALLRECT_H_ */ diff --git a/libc/nt/struct/startupinfo.h b/libc/nt/struct/startupinfo.h new file mode 100644 index 00000000..f14346a5 --- /dev/null +++ b/libc/nt/struct/startupinfo.h @@ -0,0 +1,32 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_STARTUPINFO_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_STARTUPINFO_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtStartupInfo { + uint32_t cb /* = sizeof(struct NtStartupInfo) */; + uint16_t *lpReserved; + char16_t *lpDesktop; + char16_t *lpTitle; /* title of *new* console window only */ + uint32_t dwX; /* position of window on screen */ + uint32_t dwY; + uint32_t dwXSize; + uint32_t dwYSize; + uint32_t dwXCountChars; /* used to dimension the dos terminal */ + uint32_t dwYCountChars; + uint32_t dwFillAttribute; + uint32_t dwFlags; + uint16_t wShowWindow; + uint16_t cbReserved2; + uint8_t *lpReserved2; + union { + struct { + int64_t hStdInput; + int64_t hStdOutput; + int64_t hStdError; + }; + int64_t stdiofds[3]; + }; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_STARTUPINFO_H_ */ diff --git a/libc/nt/struct/startupinfoex.h b/libc/nt/struct/startupinfoex.h new file mode 100644 index 00000000..0b513ebf --- /dev/null +++ b/libc/nt/struct/startupinfoex.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_STARTUPINFOEX_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_STARTUPINFOEX_H_ +#include "libc/nt/struct/startupinfo.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtProcThreadAttributeList; + +struct NtStartupInfoEx { + struct NtStartupInfo StartupInfo; + struct NtProcThreadAttributeList *lpAttributeList; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_STARTUPINFOEX_H_ */ diff --git a/libc/nt/struct/systembasicinformation.h b/libc/nt/struct/systembasicinformation.h new file mode 100644 index 00000000..8f2affa8 --- /dev/null +++ b/libc/nt/struct/systembasicinformation.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMBASICINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMBASICINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSystemBasicInformation { + unsigned char Reserved1[4]; + uint32_t MaximumIncrement; + uint32_t PhysicalPageSize; + uint32_t NumberOfPhysicalPages; + uint32_t LowestPhysicalPage; + uint32_t HighestPhysicalPage; + uint32_t AllocationGranularity; + uint32_t LowestUserAddress; + uint32_t HighestUserAddress; + uint32_t ActiveProcessors; + char NumberOfProcessors; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMBASICINFORMATION_H_ */ diff --git a/libc/nt/struct/systemexceptioninformation.h b/libc/nt/struct/systemexceptioninformation.h new file mode 100644 index 00000000..8dfa4f10 --- /dev/null +++ b/libc/nt/struct/systemexceptioninformation.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMEXCEPTIONINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMEXCEPTIONINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSystemExceptionInformation { + unsigned char Reserved1[16]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMEXCEPTIONINFORMATION_H_ */ diff --git a/libc/nt/struct/systemhandleentry.h b/libc/nt/struct/systemhandleentry.h new file mode 100644 index 00000000..e6e6ead0 --- /dev/null +++ b/libc/nt/struct/systemhandleentry.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMHANDLEENTRY_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMHANDLEENTRY_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSystemHandleEntry { + uint32_t OwnerPid; + unsigned char ObjectType; + unsigned char HandleFlags; + unsigned short HandleValue; + void *ObjectPointer; + uint32_t AccessMask; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMHANDLEENTRY_H_ */ diff --git a/libc/nt/struct/systemhandleinformation.h b/libc/nt/struct/systemhandleinformation.h new file mode 100644 index 00000000..ec5c2e79 --- /dev/null +++ b/libc/nt/struct/systemhandleinformation.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMHANDLEINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMHANDLEINFORMATION_H_ +#include "libc/nt/struct/systemhandleentry.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSystemHandleInformation { + uint32_t Count; + struct NtSystemHandleEntry Handle[1]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMHANDLEINFORMATION_H_ */ diff --git a/libc/nt/struct/systeminfo.h b/libc/nt/struct/systeminfo.h new file mode 100644 index 00000000..efa33c20 --- /dev/null +++ b/libc/nt/struct/systeminfo.h @@ -0,0 +1,25 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMINFO_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMINFO_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSystemInfo { + union { + uint32_t dwOemId; + struct { + uint16_t wProcessorArchitecture; + uint16_t wReserved; + }; + }; + uint32_t dwPageSize; + void *lpMinimumApplicationAddress; + void *lpMaximumApplicationAddress; + uintptr_t dwActiveProcessorMask; + uint32_t dwNumberOfProcessors; + uint32_t dwProcessorType; + uint32_t dwAllocationGranularity; + uint16_t wProcessorLevel; + uint16_t wProcessorRevision; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMINFO_H_ */ diff --git a/libc/nt/struct/systeminterruptinformation.h b/libc/nt/struct/systeminterruptinformation.h new file mode 100644 index 00000000..316109b2 --- /dev/null +++ b/libc/nt/struct/systeminterruptinformation.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMINTERRUPTINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMINTERRUPTINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSystemInterruptInformation { + unsigned char Reserved1[24]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMINTERRUPTINFORMATION_H_ */ diff --git a/libc/nt/struct/systemlookasideinformation.h b/libc/nt/struct/systemlookasideinformation.h new file mode 100644 index 00000000..8df8e6e3 --- /dev/null +++ b/libc/nt/struct/systemlookasideinformation.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMLOOKASIDEINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMLOOKASIDEINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSystemLookasideInformation { + unsigned char Reserved1[32]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMLOOKASIDEINFORMATION_H_ */ diff --git a/libc/nt/struct/systemperformanceinformation.h b/libc/nt/struct/systemperformanceinformation.h new file mode 100644 index 00000000..116121bf --- /dev/null +++ b/libc/nt/struct/systemperformanceinformation.h @@ -0,0 +1,83 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMPERFORMANCEINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMPERFORMANCEINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSystemPerformanceInformation { + int64_t IdleTime; + int64_t ReadTransferCount; + int64_t WriteTransferCount; + int64_t OtherTransferCount; + uint32_t ReadOperationCount; + uint32_t WriteOperationCount; + uint32_t OtherOperationCount; + uint32_t AvailablePages; + uint32_t TotalCommittedPages; + uint32_t TotalCommitLimit; + uint32_t PeakCommitment; + uint32_t PageFaults; + uint32_t WriteCopyFaults; + uint32_t TransitionFaults; + uint32_t CacheTransitionFaults; + uint32_t DemandZeroFaults; + uint32_t PagesRead; + uint32_t PageReadIos; + uint32_t CacheReads; + uint32_t CacheIos; + uint32_t PagefilePagesWritten; + uint32_t PagefilePageWriteIos; + uint32_t MappedFilePagesWritten; + uint32_t MappedFilePageWriteIos; + uint32_t PagedPoolUsage; + uint32_t NonPagedPoolUsage; + uint32_t PagedPoolAllocs; + uint32_t PagedPoolFrees; + uint32_t NonPagedPoolAllocs; + uint32_t NonPagedPoolFrees; + uint32_t TotalFreeSystemPtes; + uint32_t SystemCodePage; + uint32_t TotalSystemDriverPages; + uint32_t TotalSystemCodePages; + uint32_t SmallNonPagedLookasideListAllocateHits; + uint32_t SmallPagedLookasideListAllocateHits; + uint32_t Reserved3; + uint32_t MmSystemCachePage; + uint32_t PagedPoolPage; + uint32_t SystemDriverPage; + uint32_t FastReadNoWait; + uint32_t FastReadWait; + uint32_t FastReadResourceMiss; + uint32_t FastReadNotPossible; + uint32_t FastMdlReadNoWait; + uint32_t FastMdlReadWait; + uint32_t FastMdlReadResourceMiss; + uint32_t FastMdlReadNotPossible; + uint32_t MapDataNoWait; + uint32_t MapDataWait; + uint32_t MapDataNoWaitMiss; + uint32_t MapDataWaitMiss; + uint32_t PinMappedDataCount; + uint32_t PinReadNoWait; + uint32_t PinReadWait; + uint32_t PinReadNoWaitMiss; + uint32_t PinReadWaitMiss; + uint32_t CopyReadNoWait; + uint32_t CopyReadWait; + uint32_t CopyReadNoWaitMiss; + uint32_t CopyReadWaitMiss; + uint32_t MdlReadNoWait; + uint32_t MdlReadWait; + uint32_t MdlReadNoWaitMiss; + uint32_t MdlReadWaitMiss; + uint32_t ReadAheadIos; + uint32_t LazyWriteIos; + uint32_t LazyWritePages; + uint32_t DataFlushes; + uint32_t DataPages; + uint32_t ContextSwitches; + uint32_t FirstLevelTbFills; + uint32_t SecondLevelTbFills; + uint32_t SystemCalls; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMPERFORMANCEINFORMATION_H_ */ diff --git a/libc/nt/struct/systemprocessinformation.h b/libc/nt/struct/systemprocessinformation.h new file mode 100644 index 00000000..41c4d874 --- /dev/null +++ b/libc/nt/struct/systemprocessinformation.h @@ -0,0 +1,28 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMPROCESSINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMPROCESSINFORMATION_H_ +#include "libc/nt/struct/iocounters.h" +#include "libc/nt/struct/unicodestring.h" +#include "libc/nt/struct/vmcounters.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSystemProcessInformation { + uint32_t NextEntryOffset; + uint32_t NumberOfThreads; + int64_t Reserved[3]; + int64_t CreateTime; + int64_t UserTime; + int64_t KernelTime; + struct NtUnicodeString ImageName; + int32_t BasePriority; + int64_t UniqueProcessId; + int64_t InheritedFromUniqueProcessId; + uint32_t HandleCount; + uint32_t SessionId; + uint32_t PageDirectoryBase; + struct NtVmCounters VirtualMemoryCounters; + size_t PrivatePageCount; + struct NtIoCounters IoCounters; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMPROCESSINFORMATION_H_ */ diff --git a/libc/nt/struct/systemprocessorinformation.h b/libc/nt/struct/systemprocessorinformation.h new file mode 100644 index 00000000..7854230b --- /dev/null +++ b/libc/nt/struct/systemprocessorinformation.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMPROCESSORINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMPROCESSORINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSystemProcessorInformation { + unsigned short ProcessorArchitecture; + unsigned short ProcessorLevel; + unsigned short ProcessorRevision; + unsigned short Unknown; + uint32_t FeatureBits; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMPROCESSORINFORMATION_H_ */ diff --git a/libc/nt/struct/systemprocessorperformanceinformation.h b/libc/nt/struct/systemprocessorperformanceinformation.h new file mode 100644 index 00000000..e8122e3d --- /dev/null +++ b/libc/nt/struct/systemprocessorperformanceinformation.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMPROCESSORPERFORMANCEINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMPROCESSORPERFORMANCEINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSystemProcessorPerformanceInformation { + int64_t IdleTime; + int64_t KernelTime; + int64_t UserTime; + int64_t Reserved1[2]; + uint32_t Reserved2; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMPROCESSORPERFORMANCEINFORMATION_H_ \ + */ diff --git a/libc/nt/struct/systemregistryquotainformation.h b/libc/nt/struct/systemregistryquotainformation.h new file mode 100644 index 00000000..a6188c8b --- /dev/null +++ b/libc/nt/struct/systemregistryquotainformation.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMREGISTRYQUOTAINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMREGISTRYQUOTAINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSystemRegistryQuotaInformation { + uint32_t RegistryQuotaAllowed; + uint32_t RegistryQuotaUsed; + void *Reserved1; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMREGISTRYQUOTAINFORMATION_H_ */ diff --git a/libc/nt/struct/systemthreads.h b/libc/nt/struct/systemthreads.h new file mode 100644 index 00000000..657de8f1 --- /dev/null +++ b/libc/nt/struct/systemthreads.h @@ -0,0 +1,23 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMTHREADS_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMTHREADS_H_ +#include "libc/nt/enum/kwaitreason.h" +#include "libc/nt/enum/threadstate.h" +#include "libc/nt/struct/clientid.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSystemThreads { + int64_t KernelTime; + int64_t UserTime; + int64_t CreateTime; + uint32_t WaitTime; + void *StartAddress; + struct NtClientId ClientId; + int32_t Priority; + int32_t BasePriority; + uint32_t ContextSwitchCount; + enum NtThreadState State; + uint32_t WaitReason; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMTHREADS_H_ */ diff --git a/libc/nt/struct/systemtime.h b/libc/nt/struct/systemtime.h new file mode 100644 index 00000000..26074d70 --- /dev/null +++ b/libc/nt/struct/systemtime.h @@ -0,0 +1,17 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMTIME_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMTIME_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSystemTime { + uint16_t wYear; + uint16_t wMonth; + uint16_t wDayOfWeek; + uint16_t wDay; + uint16_t wHour; + uint16_t wMinute; + uint16_t wSecond; + uint16_t wMilliseconds; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMTIME_H_ */ diff --git a/libc/nt/struct/systemtimeofdayinformation.h b/libc/nt/struct/systemtimeofdayinformation.h new file mode 100644 index 00000000..9bb3be38 --- /dev/null +++ b/libc/nt/struct/systemtimeofdayinformation.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMTIMEOFDAYINFORMATION_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMTIMEOFDAYINFORMATION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtSystemTimeofdayInformation { + int64_t BootTime; + int64_t CurrentTime; + int64_t TimeZoneBias; + uint32_t CurrentTimeZoneId; + unsigned char Reserved1[20]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SYSTEMTIMEOFDAYINFORMATION_H_ */ diff --git a/libc/nt/struct/teb.h b/libc/nt/struct/teb.h new file mode 100644 index 00000000..be7f437b --- /dev/null +++ b/libc/nt/struct/teb.h @@ -0,0 +1,27 @@ +#ifndef COSMOPOLITAN_LIBC_NT_TEB_H_ +#define COSMOPOLITAN_LIBC_NT_TEB_H_ +#include "libc/bits/bits.h" +#include "libc/nt/struct/peb.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#if 0 +/* These macros address directly into NT's TEB a.k.a. TIB */ +#endif +#define NtGetPeb() gs((struct NtPeb **)(0x60ULL)) +#define NtGetTeb() gs((void **)(0x30)) /* %gs:0 linear address */ +#define NtGetPid() gs((uint32_t *)(0x40)) /* GetCurrentProcessId() */ +#define NtGetTid() gs((uint32_t *)(0x48)) /* GetCurrentThreadId() */ +#define NtGetErr() gs((int *)(0x68)) +#define NtGetVersion() \ + ((NtGetPeb()->OSMajorVersion & 0xff) << 8 | NtGetPeb()->OSMinorVersion) +#define _NtGetSeh() gs((void **)(0x00)) +#define _NtGetStackHigh() gs((void **)(0x08)) +#define _NtGetStackLow() gs((void **)(0x10)) +#define _NtGetSubsystemTib() gs((void **)(0x18)) +#define _NtGetFib() gs((void **)(0x20)) +#define _NtGetEnv() gs((char16_t **)(0x38)) +#define _NtGetRpc() gs((void **)(0x50)) +#define _NtGetTls() gs((void **)(0x58)) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_TEB_H_ */ diff --git a/libc/nt/struct/tokenprivileges.h b/libc/nt/struct/tokenprivileges.h new file mode 100644 index 00000000..69b41afc --- /dev/null +++ b/libc/nt/struct/tokenprivileges.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_TOKENPRIVILEGES_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_TOKENPRIVILEGES_H_ +#include "libc/nt/struct/luidandattributes.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtTokenPrivileges { + uint32_t PrivilegeCount; + struct NtLuidAndAttributes Privileges[1]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_TOKENPRIVILEGES_H_ */ diff --git a/libc/nt/struct/unicodestring.h b/libc/nt/struct/unicodestring.h new file mode 100644 index 00000000..ce01321f --- /dev/null +++ b/libc/nt/struct/unicodestring.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_NT_UNICODE_H_ +#define COSMOPOLITAN_LIBC_NT_UNICODE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtUnicodeString { + uint16_t Length; + uint16_t MaxLength; + char16_t *Data; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_UNICODE_H_ */ diff --git a/libc/nt/struct/userstack.h b/libc/nt/struct/userstack.h new file mode 100644 index 00000000..6d9e882c --- /dev/null +++ b/libc/nt/struct/userstack.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_NTUSERSTACK_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_NTUSERSTACK_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtUserStack { + void *FixedStackBase; + void *FixedStackLimit; + void *ExpandableStackBase; + void *ExpandableStackLimit; + void *ExpandableStackBottom; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_NTUSERSTACK_H_ */ diff --git a/libc/nt/struct/valent.h b/libc/nt/struct/valent.h new file mode 100644 index 00000000..972684c6 --- /dev/null +++ b/libc/nt/struct/valent.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_VALENT_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_VALENT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtValent { + char16_t *ve_valuename; + uint32_t ve_valuelen; + uintptr_t ve_valueptr; + uint32_t ve_type; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_VALENT_H_ */ diff --git a/libc/nt/struct/vmcounters.h b/libc/nt/struct/vmcounters.h new file mode 100644 index 00000000..bc92e1fd --- /dev/null +++ b/libc/nt/struct/vmcounters.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_VMCOUNTERS_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_VMCOUNTERS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtVmCounters { + size_t PeakVirtualSize; + size_t VirtualSize; + uint32_t PageFaultCount; + size_t PeakWorkingSetSize; + size_t WorkingSetSize; + size_t QuotaPeakPagedPoolUsage; + size_t QuotaPagedPoolUsage; + size_t QuotaPeakNonPagedPoolUsage; + size_t QuotaNonPagedPoolUsage; + size_t PagefileUsage; + size_t PeakPagefileUsage; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_VMCOUNTERS_H_ */ diff --git a/libc/nt/struct/win32fileattributedata.h b/libc/nt/struct/win32fileattributedata.h new file mode 100644 index 00000000..17001f36 --- /dev/null +++ b/libc/nt/struct/win32fileattributedata.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_WIN32FILEATTRIBUTEDATA_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_WIN32FILEATTRIBUTEDATA_H_ +#include "libc/nt/struct/filetime.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtWin32FileAttributeData { + uint32_t dwFileAttributes; /* ←NtFileFlagAndAttributes */ + struct NtFileTime ftCreationTime; + struct NtFileTime ftLastAccessTime; + struct NtFileTime ftLastWriteTime; + uint32_t nFileSizeHigh; + uint32_t nFileSizeLow; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_WIN32FILEATTRIBUTEDATA_H_ */ diff --git a/libc/nt/struct/win32finddata.h b/libc/nt/struct/win32finddata.h new file mode 100644 index 00000000..02842b45 --- /dev/null +++ b/libc/nt/struct/win32finddata.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_WIN32FINDDATA_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_WIN32FINDDATA_H_ +#include "libc/nt/struct/filetime.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtWin32FindData { + uint32_t dwFileAttributes; + struct NtFileTime ftCreationTime; + struct NtFileTime ftLastAccessTime; + struct NtFileTime ftLastWriteTime; + uint32_t nFileSizeHigh; + uint32_t nFileSizeLow; + uint32_t dwReserved0; + uint32_t dwReserved1; + char16_t cFileName[PATH_MAX]; + char16_t cAlternateFileName[14]; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_WIN32FINDDATA_H_ */ diff --git a/libc/nt/synchronization.h b/libc/nt/synchronization.h new file mode 100644 index 00000000..75584463 --- /dev/null +++ b/libc/nt/synchronization.h @@ -0,0 +1,72 @@ +#ifndef COSMOPOLITAN_LIBC_NT_SYNCHRONIZATION_H_ +#define COSMOPOLITAN_LIBC_NT_SYNCHRONIZATION_H_ +#include "libc/nt/struct/linkedlist.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » synchronization ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +struct NtCriticalSection; +struct NtFileTime; +struct NtSystemTime; + +void Sleep(uint32_t dwMilliseconds); +uint32_t SleepEx(uint32_t dwMilliseconds, bool32 bAlertable); +void GetSystemTime(struct NtSystemTime *lpSystemTime); +bool32 SystemTimeToFileTime(const struct NtSystemTime *lpSystemTime, + struct NtFileTime *lpFileTime); +void GetSystemTimeAsFileTime( + struct NtFileTime *out_lpSystemTimeAsFileTime); /* win8+ */ +void GetSystemTimePreciseAsFileTime( + struct NtFileTime *out_lpSystemTimeAsFileTime); /* win8+ */ +void InitializeCriticalSection(struct NtCriticalSection *lpCriticalSection); +void EnterCriticalSection(struct NtCriticalSection *lpCriticalSection); +void LeaveCriticalSection(struct NtCriticalSection *lpCriticalSection); +int32_t InitializeCriticalSectionAndSpinCount( + struct NtCriticalSection *lpCriticalSection, uint32_t dwSpinCount); +uint32_t SetCriticalSectionSpinCount( + struct NtCriticalSection *lpCriticalSection, uint32_t dwSpinCount); +int32_t TryEnterCriticalSection(struct NtCriticalSection *lpCriticalSection); +void DeleteCriticalSection(struct NtCriticalSection *lpCriticalSection); +int32_t SetEvent(int64_t hEvent); +int32_t ResetEvent(int64_t hEvent); +int32_t PulseEvent(int64_t hEvent); +int32_t ReleaseSemaphore(int64_t hSemaphore, int32_t lReleaseCount, + int *lpPreviousCount); +int32_t ReleaseMutex(int64_t hMutex); +uint32_t WaitForSingleObject(int64_t hHandle, uint32_t dwMilliseconds); +uint32_t WaitForMultipleObjects(uint32_t nCount, const void **lpHandles, + bool32 bWaitAll, uint32_t dwMilliseconds); +uint32_t WaitForSingleObjectEx(int64_t hHandle, uint32_t dwMilliseconds, + bool32 bAlertable); +uint32_t WaitForMultipleObjectsEx(unsigned int nCount, const void **lpHandles, + bool32 bWaitAll, uint32_t dwMilliseconds, + bool32 bAlertable); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_SYNCHRONIZATION_H_ */ diff --git a/libc/nt/systeminfo.h b/libc/nt/systeminfo.h new file mode 100644 index 00000000..99e0ee12 --- /dev/null +++ b/libc/nt/systeminfo.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_NT_INFO_H_ +#define COSMOPOLITAN_LIBC_NT_INFO_H_ +#include "libc/nt/struct/systeminfo.h" +#include "libc/nt/thunk/msabi.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtSystemInfo; + +void GetSystemInfo(struct NtSystemInfo *lpSystemInfo); +uint32_t GetSystemDirectory(char16_t *lpBuffer, uint32_t uSize); +uint32_t GetSystemDirectoryA(char *lpBuffer, uint32_t uSize); +uint32_t GetWindowsDirectory(char16_t *lpBuffer, uint32_t uSize); +uint32_t GetTempPath(uint32_t uSize, char16_t *lpBuffer); + +#if ShouldUseMsabiAttribute() +#include "libc/nt/thunk/systeminfo.inc" +#endif /* ShouldUseMsabiAttribute() */ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_INFO_H_ */ diff --git a/libc/nt/thread.h b/libc/nt/thread.h new file mode 100644 index 00000000..560a90b7 --- /dev/null +++ b/libc/nt/thread.h @@ -0,0 +1,55 @@ +#ifndef COSMOPOLITAN_LIBC_NT_THREADS_H_ +#define COSMOPOLITAN_LIBC_NT_THREADS_H_ +#include "libc/nt/enum/threadaccess.h" +#include "libc/nt/thunk/msabi.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » threads ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +void ExitThread(uint32_t dwExitCode) noreturn; +int64_t GetCurrentThread(void); +uint32_t GetCurrentThreadId(void); +uint64_t SetThreadAffinityMask(int64_t hThread, uintptr_t dwThreadAffinityMask); +int64_t OpenThread(uint32_t dwDesiredAccess, bool32 bInheritHandle, + uint32_t dwThreadId); +bool32 TerminateThread(int64_t hThread, uint32_t dwExitCode); +bool32 GetExitCodeThread(int64_t hThread, uint32_t *lpExitCode); + +/* e.g. kNtThreadPriorityAboveNormal, -1u on error */ +uint32_t GetThreadPriority(int64_t hThread); +bool32 SetThreadPriority(int64_t hThread, int32_t nPriority); +bool32 SetThreadPriorityBoost(int64_t hThread, bool32 bDisablePriorityBoost); +bool32 GetThreadPriorityBoost(int64_t hThread, bool32 *pDisablePriorityBoost); +bool32 GetThreadIOPendingFlag(int64_t hThread, bool32 *lpIOIsPending); + +#if ShouldUseMsabiAttribute() +#include "libc/nt/thunk/thread.inc" +#endif /* ShouldUseMsabiAttribute() */ +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_THREADS_H_ */ diff --git a/libc/nt/thunk/console.inc b/libc/nt/thunk/console.inc new file mode 100644 index 00000000..72e4f36f --- /dev/null +++ b/libc/nt/thunk/console.inc @@ -0,0 +1,11 @@ +#define GetConsoleMode(...) __imp_GetConsoleMode(__VA_ARGS__) +#define SetConsoleCP(...) __imp_SetConsoleCP(__VA_ARGS__) +#define SetConsoleCtrlHandler(...) __imp_SetConsoleCtrlHandler(__VA_ARGS__) +#define SetConsoleMode(...) __imp_SetConsoleMode(__VA_ARGS__) +#define SetConsoleOutputCP(...) __imp_SetConsoleOutputCP(__VA_ARGS__) + +extern typeof(GetConsoleMode) *const __imp_GetConsoleMode __msabi; +extern typeof(SetConsoleCP) *const __imp_SetConsoleCP __msabi; +extern typeof(SetConsoleCtrlHandler) *const __imp_SetConsoleCtrlHandler __msabi; +extern typeof(SetConsoleMode) *const __imp_SetConsoleMode __msabi; +extern typeof(SetConsoleOutputCP) *const __imp_SetConsoleOutputCP __msabi; diff --git a/libc/nt/thunk/files.inc b/libc/nt/thunk/files.inc new file mode 100644 index 00000000..3afabee5 --- /dev/null +++ b/libc/nt/thunk/files.inc @@ -0,0 +1,3 @@ +#define FlushFileBuffers(...) __imp_FlushFileBuffers(__VA_ARGS__) + +extern typeof(FlushFileBuffers) *const __imp_FlushFileBuffers __msabi; diff --git a/libc/nt/thunk/msabi.h b/libc/nt/thunk/msabi.h new file mode 100644 index 00000000..0ac5526e --- /dev/null +++ b/libc/nt/thunk/msabi.h @@ -0,0 +1,29 @@ +#ifndef COSMOPOLITAN_LIBC_NT_THUNK_MSABI_H_ +#define COSMOPOLITAN_LIBC_NT_THUNK_MSABI_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * Defines function as using Microsoft x64 calling convention. + * + * This can be used to define prototypes that allow modern compilers to + * generate code that calls MS ABI functions directly, without needing + * to jump through the assembly thunks. + */ +#if __GNUC__ * 100 + __GNUC_MINOR_ >= 408 || \ + (__has_attribute(__ms_abi__) || defined(__llvm__)) +#define __msabi __attribute__((__ms_abi__)) +#endif + +/** + * Returns true if header should provide MS-ABI overrides. + */ +#ifndef ShouldUseMsabiAttribute +#if defined(__msabi) && defined(NDEBUG) && !defined(__STRICT_ANSI__) +#define ShouldUseMsabiAttribute() 1 +#else +#define ShouldUseMsabiAttribute() 0 +#endif +#endif + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_THUNK_MSABI_H_ */ diff --git a/libc/nt/thunk/ntdll.inc b/libc/nt/thunk/ntdll.inc new file mode 100644 index 00000000..78b75122 --- /dev/null +++ b/libc/nt/thunk/ntdll.inc @@ -0,0 +1,3 @@ +#define NtYieldExecution(...) __imp_NtYieldExecution(__VA_ARGS__) + +extern typeof(NtYieldExecution) *const __imp_NtYieldExecution __msabi; diff --git a/libc/nt/thunk/ntfile.inc b/libc/nt/thunk/ntfile.inc new file mode 100644 index 00000000..aeb0b88e --- /dev/null +++ b/libc/nt/thunk/ntfile.inc @@ -0,0 +1,4 @@ +#define NtQueryInformationFile(...) __imp_NtQueryInformationFile(__VA_ARGS__) + +extern typeof(NtQueryInformationFile) *const + __imp_NtQueryInformationFile __msabi; diff --git a/libc/nt/thunk/process.inc b/libc/nt/thunk/process.inc new file mode 100644 index 00000000..5fb34189 --- /dev/null +++ b/libc/nt/thunk/process.inc @@ -0,0 +1,8 @@ +#define GetEnvironmentVariable(...) __imp_GetEnvironmentVariableW(__VA_ARGS__) +#define GetPriorityClass(...) __imp_GetPriorityClass(__VA_ARGS__) +#define SetPriorityClass(...) __imp_SetPriorityClass(__VA_ARGS__) + +extern typeof(GetEnvironmentVariable) *const + __imp_GetEnvironmentVariableW __msabi; +extern typeof(GetPriorityClass) *const __imp_GetPriorityClass __msabi; +extern typeof(SetPriorityClass) *const __imp_SetPriorityClass __msabi; diff --git a/libc/nt/thunk/runtime.inc b/libc/nt/thunk/runtime.inc new file mode 100644 index 00000000..ea5a3faa --- /dev/null +++ b/libc/nt/thunk/runtime.inc @@ -0,0 +1,23 @@ +#define ExitProcess(...) __imp_ExitProcess(__VA_ARGS__) +#define FreeEnvironmentStrings(...) __imp_FreeEnvironmentStringsW(__VA_ARGS__) +#define GetCommandLine(...) __imp_GetCommandLineW(__VA_ARGS__) +#define GetEnvironmentStrings(...) __imp_GetEnvironmentStringsW(__VA_ARGS__) +#define GetStdHandle(...) __imp_GetStdHandle(__VA_ARGS__) +#define SetStdHandle(...) __imp_SetStdHandle(__VA_ARGS__) +#define ReadFile(...) __imp_ReadFile(__VA_ARGS__) +#define WriteFile(...) __imp_WriteFile(__VA_ARGS__) +#define SetDefaultDllDirectories(...) \ + __imp_SetDefaultDllDirectories(__VA_ARGS__) + +extern typeof(ExitProcess) *const __imp_ExitProcess __msabi; +extern typeof(FreeEnvironmentStrings) *const + __imp_FreeEnvironmentStringsW __msabi; +extern typeof(GetCommandLine) *const __imp_GetCommandLineW __msabi; +extern typeof(GetEnvironmentStrings) *const + __imp_GetEnvironmentStringsW __msabi; +extern typeof(GetStdHandle) *const __imp_GetStdHandle __msabi; +extern typeof(SetStdHandle) *const __imp_SetStdHandle __msabi; +extern typeof(ReadFile) *const __imp_ReadFile __msabi; +extern typeof(WriteFile) *const __imp_WriteFile __msabi; +extern typeof(SetDefaultDllDirectories) *const + __imp_SetDefaultDllDirectories __msabi; diff --git a/libc/nt/thunk/signals.inc b/libc/nt/thunk/signals.inc new file mode 100644 index 00000000..9257786f --- /dev/null +++ b/libc/nt/thunk/signals.inc @@ -0,0 +1,23 @@ +#define SetErrorMode(...) __imp_SetErrorMode(__VA_ARGS__) +#define AddVectoredExceptionHandler(...) \ + __imp_AddVectoredExceptionHandler(__VA_ARGS__) +#define AddVectoredContinueHandler(...) \ + __imp_AddVectoredContinueHandler(__VA_ARGS__) +#define RemoveVectoredExceptionHandler(...) \ + __imp_RemoveVectoredExceptionHandler(__VA_ARGS__) +#define RemoveVectoredContinueHandler(...) \ + __imp_RemoveVectoredContinueHandler(__VA_ARGS__) +#define SetUnhandledExceptionFilter(...) \ + __imp_SetUnhandledExceptionFilter(__VA_ARGS__) + +extern typeof(SetErrorMode) *const __imp_SetErrorMode __msabi; +extern typeof(AddVectoredExceptionHandler) *const + __imp_AddVectoredExceptionHandler __msabi; +extern typeof(AddVectoredContinueHandler) *const + __imp_AddVectoredContinueHandler __msabi; +extern typeof(RemoveVectoredExceptionHandler) *const + __imp_RemoveVectoredExceptionHandler __msabi; +extern typeof(RemoveVectoredContinueHandler) *const + __imp_RemoveVectoredContinueHandler __msabi; +extern typeof(SetUnhandledExceptionFilter) *const + __imp_SetUnhandledExceptionFilter __msabi; diff --git a/libc/nt/thunk/startupinfo.inc b/libc/nt/thunk/startupinfo.inc new file mode 100644 index 00000000..86ee25cd --- /dev/null +++ b/libc/nt/thunk/startupinfo.inc @@ -0,0 +1,3 @@ +#define GetStartupInfo(...) __imp_GetStartupInfoW(__VA_ARGS__) + +extern typeof(GetStartupInfo) *const __imp_GetStartupInfoW __msabi; diff --git a/libc/nt/thunk/systeminfo.inc b/libc/nt/thunk/systeminfo.inc new file mode 100644 index 00000000..a37c9c4c --- /dev/null +++ b/libc/nt/thunk/systeminfo.inc @@ -0,0 +1,5 @@ +#define GetSystemInfo(...) __imp_GetSystemInfo(__VA_ARGS__) +#define GetTempPath(...) __imp_GetTempPathW(__VA_ARGS__) + +extern typeof(GetSystemInfo) *const __imp_GetSystemInfo __msabi; +extern typeof(GetTempPath) *const __imp_GetTempPathW __msabi; diff --git a/libc/nt/thunk/thread.inc b/libc/nt/thunk/thread.inc new file mode 100644 index 00000000..a34c2640 --- /dev/null +++ b/libc/nt/thunk/thread.inc @@ -0,0 +1,7 @@ +#define GetCurrentThread(...) __imp_GetCurrentThread(__VA_ARGS__) +#define GetThreadPriority(...) __imp_GetThreadPriority(__VA_ARGS__) +#define SetThreadPriority(...) __imp_SetThreadPriority(__VA_ARGS__) + +extern typeof(GetCurrentThread) *const __imp_GetCurrentThread __msabi; +extern typeof(GetThreadPriority) *const __imp_GetThreadPriority __msabi; +extern typeof(SetThreadPriority) *const __imp_SetThreadPriority __msabi; diff --git a/libc/nt/typedef/exceptionhandler.h b/libc/nt/typedef/exceptionhandler.h new file mode 100644 index 00000000..d45afe2a --- /dev/null +++ b/libc/nt/typedef/exceptionhandler.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_NT_TYPEDEF_EXCEPTIONHANDLER_H_ +#define COSMOPOLITAN_LIBC_NT_TYPEDEF_EXCEPTIONHANDLER_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtExceptionFrame; +struct NtExceptionRecord; +struct NtContext; + +typedef unsigned (*NtExceptionHandler)(struct NtExceptionRecord *, + struct NtExceptionFrame *, + struct NtContext *, void *); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_TYPEDEF_EXCEPTIONHANDLER_H_ */ diff --git a/libc/nt/typedef/handlerroutine.h b/libc/nt/typedef/handlerroutine.h new file mode 100644 index 00000000..52140e60 --- /dev/null +++ b/libc/nt/typedef/handlerroutine.h @@ -0,0 +1,9 @@ +#ifndef COSMOPOLITAN_LIBC_NT_TYPEDEF_HANDLERROUTINE_H_ +#define COSMOPOLITAN_LIBC_NT_TYPEDEF_HANDLERROUTINE_H_ +#include "libc/nt/enum/ctrlevent.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +typedef bool32 (*NtHandlerRoutine)(uint32_t); + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_TYPEDEF_HANDLERROUTINE_H_ */ diff --git a/libc/nt/typedef/hookproc.h b/libc/nt/typedef/hookproc.h new file mode 100644 index 00000000..3f612e02 --- /dev/null +++ b/libc/nt/typedef/hookproc.h @@ -0,0 +1,8 @@ +#ifndef COSMOPOLITAN_LIBC_NT_TYPEDEF_HOOKPROC_H_ +#define COSMOPOLITAN_LIBC_NT_TYPEDEF_HOOKPROC_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +typedef intptr_t (*NtHookProc)(int code, uintptr_t wParam, intptr_t lParam); + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_TYPEDEF_HOOKPROC_H_ */ diff --git a/libc/nt/typedef/imagetlscallback.h b/libc/nt/typedef/imagetlscallback.h new file mode 100644 index 00000000..3315209c --- /dev/null +++ b/libc/nt/typedef/imagetlscallback.h @@ -0,0 +1,9 @@ +#ifndef COSMOPOLITAN_LIBC_NT_TYPEDEF_IMAGETLSCALLBACK_H_ +#define COSMOPOLITAN_LIBC_NT_TYPEDEF_IMAGETLSCALLBACK_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +typedef void (*NtImageTlsCallback)(void *DllHandle, uint32_t Reason, + void *Reserved); + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_TYPEDEF_IMAGETLSCALLBACK_H_ */ diff --git a/libc/nt/typedef/ioapcroutine.h b/libc/nt/typedef/ioapcroutine.h new file mode 100644 index 00000000..24436531 --- /dev/null +++ b/libc/nt/typedef/ioapcroutine.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_NT_TYPEDEF_IOAPCROUTINE_H_ +#define COSMOPOLITAN_LIBC_NT_TYPEDEF_IOAPCROUTINE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct NtIoStatusBlock; + +typedef void (*NtIoApcRoutine)(void *ApcContext, + struct NtIoStatusBlock *IoStatusBlock, + uint32_t Reserved); + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_TYPEDEF_IOAPCROUTINE_H_ */ diff --git a/libc/nt/typedef/pknormalroutine.h b/libc/nt/typedef/pknormalroutine.h new file mode 100644 index 00000000..78cbef04 --- /dev/null +++ b/libc/nt/typedef/pknormalroutine.h @@ -0,0 +1,9 @@ +#ifndef COSMOPOLITAN_LIBC_NT_TYPEDEF_PKNORMALROUTINE_H_ +#define COSMOPOLITAN_LIBC_NT_TYPEDEF_PKNORMALROUTINE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +typedef void (*NtPkNormalRoutine)(void *NormalContext, void *SystemArgument1, + void *SystemArgument2); + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_TYPEDEF_PKNORMALROUTINE_H_ */ diff --git a/libc/nt/typedef/timerproc.h b/libc/nt/typedef/timerproc.h new file mode 100644 index 00000000..154ac735 --- /dev/null +++ b/libc/nt/typedef/timerproc.h @@ -0,0 +1,8 @@ +#ifndef COSMOPOLITAN_LIBC_NT_TYPEDEF_TIMERPROC_H_ +#define COSMOPOLITAN_LIBC_NT_TYPEDEF_TIMERPROC_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +typedef void (*NtTimerProc)(int64_t, uint32_t, uintptr_t, uint32_t); + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_TYPEDEF_TIMERPROC_H_ */ diff --git a/libc/nt/typedef/wambda.h b/libc/nt/typedef/wambda.h new file mode 100644 index 00000000..4cb817b5 --- /dev/null +++ b/libc/nt/typedef/wambda.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_WAMBDA_H_ +#define COSMOPOLITAN_LIBC_NT_WAMBDA_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +typedef intptr_t (*wambda)(); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_WAMBDA_H_ */ diff --git a/libc/nt/typedef/wndenumproc.h b/libc/nt/typedef/wndenumproc.h new file mode 100644 index 00000000..6f5ac154 --- /dev/null +++ b/libc/nt/typedef/wndenumproc.h @@ -0,0 +1,8 @@ +#ifndef COSMOPOLITAN_LIBC_NT_TYPEDEF_WNDENUMPROC_H_ +#define COSMOPOLITAN_LIBC_NT_TYPEDEF_WNDENUMPROC_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +typedef int (*NtWndEnumProc)(int64_t foo, intptr_t bar); + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_TYPEDEF_WNDENUMPROC_H_ */ diff --git a/libc/nt/url/AddMIMEFileTypesPS.s b/libc/nt/url/AddMIMEFileTypesPS.s new file mode 100644 index 00000000..a7d5e120 --- /dev/null +++ b/libc/nt/url/AddMIMEFileTypesPS.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp url,__imp_AddMIMEFileTypesPS,AddMIMEFileTypesPS,102 diff --git a/libc/nt/url/AutodialHookCallback.s b/libc/nt/url/AutodialHookCallback.s new file mode 100644 index 00000000..424b9192 --- /dev/null +++ b/libc/nt/url/AutodialHookCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp url,__imp_AutodialHookCallback,AutodialHookCallback,103 diff --git a/libc/nt/url/FileProtocolHandler.s b/libc/nt/url/FileProtocolHandler.s new file mode 100644 index 00000000..ebc56b2b --- /dev/null +++ b/libc/nt/url/FileProtocolHandler.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp url,__imp_FileProtocolHandler,FileProtocolHandler,104 diff --git a/libc/nt/url/FileProtocolHandlerA.s b/libc/nt/url/FileProtocolHandlerA.s new file mode 100644 index 00000000..71e17f79 --- /dev/null +++ b/libc/nt/url/FileProtocolHandlerA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp url,__imp_FileProtocolHandlerA,FileProtocolHandlerA,105 diff --git a/libc/nt/url/InetIsOffline.s b/libc/nt/url/InetIsOffline.s new file mode 100644 index 00000000..36b208d6 --- /dev/null +++ b/libc/nt/url/InetIsOffline.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp url,__imp_InetIsOffline,InetIsOffline,106 diff --git a/libc/nt/url/MIMEAssociationDialogA.s b/libc/nt/url/MIMEAssociationDialogA.s new file mode 100644 index 00000000..ff082a45 --- /dev/null +++ b/libc/nt/url/MIMEAssociationDialogA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp url,__imp_MIMEAssociationDialogA,MIMEAssociationDialogA,107 diff --git a/libc/nt/url/MIMEAssociationDialogW.s b/libc/nt/url/MIMEAssociationDialogW.s new file mode 100644 index 00000000..750cbaab --- /dev/null +++ b/libc/nt/url/MIMEAssociationDialogW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp url,__imp_MIMEAssociationDialogW,MIMEAssociationDialogW,108 diff --git a/libc/nt/url/MailToProtocolHandler.s b/libc/nt/url/MailToProtocolHandler.s new file mode 100644 index 00000000..419f8019 --- /dev/null +++ b/libc/nt/url/MailToProtocolHandler.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp url,__imp_MailToProtocolHandler,MailToProtocolHandler,109 diff --git a/libc/nt/url/MailToProtocolHandlerA.s b/libc/nt/url/MailToProtocolHandlerA.s new file mode 100644 index 00000000..fdf10d14 --- /dev/null +++ b/libc/nt/url/MailToProtocolHandlerA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp url,__imp_MailToProtocolHandlerA,MailToProtocolHandlerA,110 diff --git a/libc/nt/url/OpenURL.s b/libc/nt/url/OpenURL.s new file mode 100644 index 00000000..13aeccf3 --- /dev/null +++ b/libc/nt/url/OpenURL.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp url,__imp_OpenURL,OpenURL,111 diff --git a/libc/nt/url/OpenURLA.s b/libc/nt/url/OpenURLA.s new file mode 100644 index 00000000..361a716a --- /dev/null +++ b/libc/nt/url/OpenURLA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp url,__imp_OpenURLA,OpenURLA,112 diff --git a/libc/nt/url/TelnetProtocolHandler.s b/libc/nt/url/TelnetProtocolHandler.s new file mode 100644 index 00000000..7b55c837 --- /dev/null +++ b/libc/nt/url/TelnetProtocolHandler.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp url,__imp_TelnetProtocolHandler,TelnetProtocolHandler,113 diff --git a/libc/nt/url/TelnetProtocolHandlerA.s b/libc/nt/url/TelnetProtocolHandlerA.s new file mode 100644 index 00000000..a835cea8 --- /dev/null +++ b/libc/nt/url/TelnetProtocolHandlerA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp url,__imp_TelnetProtocolHandlerA,TelnetProtocolHandlerA,114 diff --git a/libc/nt/url/TranslateURLA.s b/libc/nt/url/TranslateURLA.s new file mode 100644 index 00000000..9091728f --- /dev/null +++ b/libc/nt/url/TranslateURLA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp url,__imp_TranslateURLA,TranslateURLA,115 diff --git a/libc/nt/url/TranslateURLW.s b/libc/nt/url/TranslateURLW.s new file mode 100644 index 00000000..6ea73e4d --- /dev/null +++ b/libc/nt/url/TranslateURLW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp url,__imp_TranslateURLW,TranslateURLW,116 diff --git a/libc/nt/url/URLAssociationDialogA.s b/libc/nt/url/URLAssociationDialogA.s new file mode 100644 index 00000000..31aef379 --- /dev/null +++ b/libc/nt/url/URLAssociationDialogA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp url,__imp_URLAssociationDialogA,URLAssociationDialogA,117 diff --git a/libc/nt/url/URLAssociationDialogW.s b/libc/nt/url/URLAssociationDialogW.s new file mode 100644 index 00000000..578fe233 --- /dev/null +++ b/libc/nt/url/URLAssociationDialogW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp url,__imp_URLAssociationDialogW,URLAssociationDialogW,118 diff --git a/libc/nt/user32/ActivateKeyboardLayout.s b/libc/nt/user32/ActivateKeyboardLayout.s new file mode 100644 index 00000000..bbc267f1 --- /dev/null +++ b/libc/nt/user32/ActivateKeyboardLayout.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ActivateKeyboardLayout,ActivateKeyboardLayout,1505 diff --git a/libc/nt/user32/AddClipboardFormatListener.s b/libc/nt/user32/AddClipboardFormatListener.s new file mode 100644 index 00000000..0885a4f1 --- /dev/null +++ b/libc/nt/user32/AddClipboardFormatListener.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_AddClipboardFormatListener,AddClipboardFormatListener,1506 diff --git a/libc/nt/user32/AdjustWindowRect.s b/libc/nt/user32/AdjustWindowRect.s new file mode 100644 index 00000000..022d4dd5 --- /dev/null +++ b/libc/nt/user32/AdjustWindowRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_AdjustWindowRect,AdjustWindowRect,1507 diff --git a/libc/nt/user32/AdjustWindowRectEx.s b/libc/nt/user32/AdjustWindowRectEx.s new file mode 100644 index 00000000..f580d479 --- /dev/null +++ b/libc/nt/user32/AdjustWindowRectEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_AdjustWindowRectEx,AdjustWindowRectEx,1508 diff --git a/libc/nt/user32/AdjustWindowRectExForDpi.s b/libc/nt/user32/AdjustWindowRectExForDpi.s new file mode 100644 index 00000000..029b7296 --- /dev/null +++ b/libc/nt/user32/AdjustWindowRectExForDpi.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_AdjustWindowRectExForDpi,AdjustWindowRectExForDpi,1509 diff --git a/libc/nt/user32/AlignRects.s b/libc/nt/user32/AlignRects.s new file mode 100644 index 00000000..df6b6a0b --- /dev/null +++ b/libc/nt/user32/AlignRects.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_AlignRects,AlignRects,1510 diff --git a/libc/nt/user32/AllowForegroundActivation.s b/libc/nt/user32/AllowForegroundActivation.s new file mode 100644 index 00000000..430a5c0f --- /dev/null +++ b/libc/nt/user32/AllowForegroundActivation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_AllowForegroundActivation,AllowForegroundActivation,1511 diff --git a/libc/nt/user32/AllowSetForegroundWindow.s b/libc/nt/user32/AllowSetForegroundWindow.s new file mode 100644 index 00000000..7caf6138 --- /dev/null +++ b/libc/nt/user32/AllowSetForegroundWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_AllowSetForegroundWindow,AllowSetForegroundWindow,1512 diff --git a/libc/nt/user32/AnimateWindow.s b/libc/nt/user32/AnimateWindow.s new file mode 100644 index 00000000..84333689 --- /dev/null +++ b/libc/nt/user32/AnimateWindow.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_AnimateWindow,AnimateWindow,1513 + + .text.windows +AnimateWindow: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_AnimateWindow(%rip),%rax + jmp __sysv2nt + .endfn AnimateWindow,globl + .previous diff --git a/libc/nt/user32/AnyPopup.s b/libc/nt/user32/AnyPopup.s new file mode 100644 index 00000000..1fb58364 --- /dev/null +++ b/libc/nt/user32/AnyPopup.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_AnyPopup,AnyPopup,1514 diff --git a/libc/nt/user32/AppendMenuA.s b/libc/nt/user32/AppendMenuA.s new file mode 100644 index 00000000..d54061ef --- /dev/null +++ b/libc/nt/user32/AppendMenuA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_AppendMenuA,AppendMenuA,1515 diff --git a/libc/nt/user32/AppendMenuW.s b/libc/nt/user32/AppendMenuW.s new file mode 100644 index 00000000..eb358da9 --- /dev/null +++ b/libc/nt/user32/AppendMenuW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_AppendMenuW,AppendMenuW,1516 diff --git a/libc/nt/user32/AreDpiAwarenessContextsEqual.s b/libc/nt/user32/AreDpiAwarenessContextsEqual.s new file mode 100644 index 00000000..a8cb4a22 --- /dev/null +++ b/libc/nt/user32/AreDpiAwarenessContextsEqual.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_AreDpiAwarenessContextsEqual,AreDpiAwarenessContextsEqual,1517 diff --git a/libc/nt/user32/ArrangeIconicWindows.s b/libc/nt/user32/ArrangeIconicWindows.s new file mode 100644 index 00000000..91112aee --- /dev/null +++ b/libc/nt/user32/ArrangeIconicWindows.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ArrangeIconicWindows,ArrangeIconicWindows,1518 diff --git a/libc/nt/user32/AttachThreadInput.s b/libc/nt/user32/AttachThreadInput.s new file mode 100644 index 00000000..2f489378 --- /dev/null +++ b/libc/nt/user32/AttachThreadInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_AttachThreadInput,AttachThreadInput,1519 diff --git a/libc/nt/user32/BeginDeferWindowPos.s b/libc/nt/user32/BeginDeferWindowPos.s new file mode 100644 index 00000000..74c57a4a --- /dev/null +++ b/libc/nt/user32/BeginDeferWindowPos.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_BeginDeferWindowPos,BeginDeferWindowPos,1520 diff --git a/libc/nt/user32/BeginPaint.s b/libc/nt/user32/BeginPaint.s new file mode 100644 index 00000000..6c9bf51e --- /dev/null +++ b/libc/nt/user32/BeginPaint.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_BeginPaint,BeginPaint,1521 + + .text.windows +BeginPaint: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_BeginPaint(%rip),%rax + jmp __sysv2nt + .endfn BeginPaint,globl + .previous diff --git a/libc/nt/user32/BlockInput.s b/libc/nt/user32/BlockInput.s new file mode 100644 index 00000000..692ea4fb --- /dev/null +++ b/libc/nt/user32/BlockInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_BlockInput,BlockInput,1522 diff --git a/libc/nt/user32/BringWindowToTop.s b/libc/nt/user32/BringWindowToTop.s new file mode 100644 index 00000000..552f3c89 --- /dev/null +++ b/libc/nt/user32/BringWindowToTop.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_BringWindowToTop,BringWindowToTop,1523 + + .text.windows +BringWindowToTop: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_BringWindowToTop(%rip) + leave + ret + .endfn BringWindowToTop,globl + .previous diff --git a/libc/nt/user32/BroadcastSystemMessageA.s b/libc/nt/user32/BroadcastSystemMessageA.s new file mode 100644 index 00000000..3952224c --- /dev/null +++ b/libc/nt/user32/BroadcastSystemMessageA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_BroadcastSystemMessageA,BroadcastSystemMessageA,1525 diff --git a/libc/nt/user32/BroadcastSystemMessageExA.s b/libc/nt/user32/BroadcastSystemMessageExA.s new file mode 100644 index 00000000..52d3cb71 --- /dev/null +++ b/libc/nt/user32/BroadcastSystemMessageExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_BroadcastSystemMessageExA,BroadcastSystemMessageExA,1526 diff --git a/libc/nt/user32/BroadcastSystemMessageExW.s b/libc/nt/user32/BroadcastSystemMessageExW.s new file mode 100644 index 00000000..70f3b8a9 --- /dev/null +++ b/libc/nt/user32/BroadcastSystemMessageExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_BroadcastSystemMessageExW,BroadcastSystemMessageExW,1527 diff --git a/libc/nt/user32/BroadcastSystemMessageW.s b/libc/nt/user32/BroadcastSystemMessageW.s new file mode 100644 index 00000000..4e2caf3b --- /dev/null +++ b/libc/nt/user32/BroadcastSystemMessageW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_BroadcastSystemMessageW,BroadcastSystemMessageW,1528 diff --git a/libc/nt/user32/BuildReasonArray.s b/libc/nt/user32/BuildReasonArray.s new file mode 100644 index 00000000..cee3ab95 --- /dev/null +++ b/libc/nt/user32/BuildReasonArray.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_BuildReasonArray,BuildReasonArray,1529 diff --git a/libc/nt/user32/CalcMenuBar.s b/libc/nt/user32/CalcMenuBar.s new file mode 100644 index 00000000..554507c9 --- /dev/null +++ b/libc/nt/user32/CalcMenuBar.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CalcMenuBar,CalcMenuBar,1530 diff --git a/libc/nt/user32/CalculatePopupWindowPosition.s b/libc/nt/user32/CalculatePopupWindowPosition.s new file mode 100644 index 00000000..f49f2f95 --- /dev/null +++ b/libc/nt/user32/CalculatePopupWindowPosition.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CalculatePopupWindowPosition,CalculatePopupWindowPosition,1531 diff --git a/libc/nt/user32/CallMsgFilterA.s b/libc/nt/user32/CallMsgFilterA.s new file mode 100644 index 00000000..2db1621a --- /dev/null +++ b/libc/nt/user32/CallMsgFilterA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CallMsgFilterA,CallMsgFilterA,1533 diff --git a/libc/nt/user32/CallMsgFilterW.s b/libc/nt/user32/CallMsgFilterW.s new file mode 100644 index 00000000..b555982f --- /dev/null +++ b/libc/nt/user32/CallMsgFilterW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CallMsgFilterW,CallMsgFilterW,1534 diff --git a/libc/nt/user32/CallNextHookEx.s b/libc/nt/user32/CallNextHookEx.s new file mode 100644 index 00000000..fbe938bb --- /dev/null +++ b/libc/nt/user32/CallNextHookEx.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CallNextHookEx,CallNextHookEx,1535 + + .text.windows +CallNextHookEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CallNextHookEx(%rip),%rax + jmp __sysv2nt + .endfn CallNextHookEx,globl + .previous diff --git a/libc/nt/user32/CallWindowProcA.s b/libc/nt/user32/CallWindowProcA.s new file mode 100644 index 00000000..316d1225 --- /dev/null +++ b/libc/nt/user32/CallWindowProcA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CallWindowProcA,CallWindowProcA,1536 diff --git a/libc/nt/user32/CallWindowProcW.s b/libc/nt/user32/CallWindowProcW.s new file mode 100644 index 00000000..c35b4dbe --- /dev/null +++ b/libc/nt/user32/CallWindowProcW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CallWindowProcW,CallWindowProcW,1537 diff --git a/libc/nt/user32/CancelShutdown.s b/libc/nt/user32/CancelShutdown.s new file mode 100644 index 00000000..8969ec29 --- /dev/null +++ b/libc/nt/user32/CancelShutdown.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CancelShutdown,CancelShutdown,1538 diff --git a/libc/nt/user32/CascadeChildWindows.s b/libc/nt/user32/CascadeChildWindows.s new file mode 100644 index 00000000..1f677b4e --- /dev/null +++ b/libc/nt/user32/CascadeChildWindows.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CascadeChildWindows,CascadeChildWindows,1539 diff --git a/libc/nt/user32/CascadeWindows.s b/libc/nt/user32/CascadeWindows.s new file mode 100644 index 00000000..f134d4d7 --- /dev/null +++ b/libc/nt/user32/CascadeWindows.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CascadeWindows,CascadeWindows,1540 diff --git a/libc/nt/user32/ChangeClipboardChain.s b/libc/nt/user32/ChangeClipboardChain.s new file mode 100644 index 00000000..eb9ea9b4 --- /dev/null +++ b/libc/nt/user32/ChangeClipboardChain.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ChangeClipboardChain,ChangeClipboardChain,1541 diff --git a/libc/nt/user32/ChangeDisplaySettingsA.s b/libc/nt/user32/ChangeDisplaySettingsA.s new file mode 100644 index 00000000..76ee2f26 --- /dev/null +++ b/libc/nt/user32/ChangeDisplaySettingsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ChangeDisplaySettingsA,ChangeDisplaySettingsA,1542 diff --git a/libc/nt/user32/ChangeDisplaySettingsExA.s b/libc/nt/user32/ChangeDisplaySettingsExA.s new file mode 100644 index 00000000..3b9b1389 --- /dev/null +++ b/libc/nt/user32/ChangeDisplaySettingsExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ChangeDisplaySettingsExA,ChangeDisplaySettingsExA,1543 diff --git a/libc/nt/user32/ChangeDisplaySettingsExW.s b/libc/nt/user32/ChangeDisplaySettingsExW.s new file mode 100644 index 00000000..7a80e785 --- /dev/null +++ b/libc/nt/user32/ChangeDisplaySettingsExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ChangeDisplaySettingsExW,ChangeDisplaySettingsExW,1544 diff --git a/libc/nt/user32/ChangeDisplaySettingsW.s b/libc/nt/user32/ChangeDisplaySettingsW.s new file mode 100644 index 00000000..685fdef2 --- /dev/null +++ b/libc/nt/user32/ChangeDisplaySettingsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ChangeDisplaySettingsW,ChangeDisplaySettingsW,1545 diff --git a/libc/nt/user32/ChangeMenuA.s b/libc/nt/user32/ChangeMenuA.s new file mode 100644 index 00000000..3df49bfe --- /dev/null +++ b/libc/nt/user32/ChangeMenuA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ChangeMenuA,ChangeMenuA,1546 diff --git a/libc/nt/user32/ChangeMenuW.s b/libc/nt/user32/ChangeMenuW.s new file mode 100644 index 00000000..3e798e36 --- /dev/null +++ b/libc/nt/user32/ChangeMenuW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ChangeMenuW,ChangeMenuW,1547 diff --git a/libc/nt/user32/ChangeWindowMessageFilter.s b/libc/nt/user32/ChangeWindowMessageFilter.s new file mode 100644 index 00000000..e03e71c4 --- /dev/null +++ b/libc/nt/user32/ChangeWindowMessageFilter.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ChangeWindowMessageFilter,ChangeWindowMessageFilter,1548 diff --git a/libc/nt/user32/ChangeWindowMessageFilterEx.s b/libc/nt/user32/ChangeWindowMessageFilterEx.s new file mode 100644 index 00000000..1ea298b6 --- /dev/null +++ b/libc/nt/user32/ChangeWindowMessageFilterEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ChangeWindowMessageFilterEx,ChangeWindowMessageFilterEx,1549 diff --git a/libc/nt/user32/CharToOemA.s b/libc/nt/user32/CharToOemA.s new file mode 100644 index 00000000..7518ac04 --- /dev/null +++ b/libc/nt/user32/CharToOemA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CharToOemA,CharToOemA,1565 diff --git a/libc/nt/user32/CharToOemBuffA.s b/libc/nt/user32/CharToOemBuffA.s new file mode 100644 index 00000000..19cc9eea --- /dev/null +++ b/libc/nt/user32/CharToOemBuffA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CharToOemBuffA,CharToOemBuffA,1566 diff --git a/libc/nt/user32/CharToOemBuffW.s b/libc/nt/user32/CharToOemBuffW.s new file mode 100644 index 00000000..8ebf9ae0 --- /dev/null +++ b/libc/nt/user32/CharToOemBuffW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CharToOemBuffW,CharToOemBuffW,1567 diff --git a/libc/nt/user32/CharToOemW.s b/libc/nt/user32/CharToOemW.s new file mode 100644 index 00000000..fcf0d38b --- /dev/null +++ b/libc/nt/user32/CharToOemW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CharToOemW,CharToOemW,1568 diff --git a/libc/nt/user32/CheckDBCSEnabledExt.s b/libc/nt/user32/CheckDBCSEnabledExt.s new file mode 100644 index 00000000..92255596 --- /dev/null +++ b/libc/nt/user32/CheckDBCSEnabledExt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CheckDBCSEnabledExt,CheckDBCSEnabledExt,1573 diff --git a/libc/nt/user32/CheckDlgButton.s b/libc/nt/user32/CheckDlgButton.s new file mode 100644 index 00000000..3f15995b --- /dev/null +++ b/libc/nt/user32/CheckDlgButton.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CheckDlgButton,CheckDlgButton,1574 diff --git a/libc/nt/user32/CheckMenuItem.s b/libc/nt/user32/CheckMenuItem.s new file mode 100644 index 00000000..1cab22b4 --- /dev/null +++ b/libc/nt/user32/CheckMenuItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CheckMenuItem,CheckMenuItem,1575 diff --git a/libc/nt/user32/CheckMenuRadioItem.s b/libc/nt/user32/CheckMenuRadioItem.s new file mode 100644 index 00000000..10cc2cdc --- /dev/null +++ b/libc/nt/user32/CheckMenuRadioItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CheckMenuRadioItem,CheckMenuRadioItem,1576 diff --git a/libc/nt/user32/CheckProcessForClipboardAccess.s b/libc/nt/user32/CheckProcessForClipboardAccess.s new file mode 100644 index 00000000..d56392fd --- /dev/null +++ b/libc/nt/user32/CheckProcessForClipboardAccess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CheckProcessForClipboardAccess,CheckProcessForClipboardAccess,1577 diff --git a/libc/nt/user32/CheckProcessSession.s b/libc/nt/user32/CheckProcessSession.s new file mode 100644 index 00000000..ae025948 --- /dev/null +++ b/libc/nt/user32/CheckProcessSession.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CheckProcessSession,CheckProcessSession,1578 diff --git a/libc/nt/user32/CheckRadioButton.s b/libc/nt/user32/CheckRadioButton.s new file mode 100644 index 00000000..069abeb5 --- /dev/null +++ b/libc/nt/user32/CheckRadioButton.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CheckRadioButton,CheckRadioButton,1579 diff --git a/libc/nt/user32/CheckWindowThreadDesktop.s b/libc/nt/user32/CheckWindowThreadDesktop.s new file mode 100644 index 00000000..7db5483a --- /dev/null +++ b/libc/nt/user32/CheckWindowThreadDesktop.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CheckWindowThreadDesktop,CheckWindowThreadDesktop,1580 diff --git a/libc/nt/user32/ChildWindowFromPoint.s b/libc/nt/user32/ChildWindowFromPoint.s new file mode 100644 index 00000000..8917dffd --- /dev/null +++ b/libc/nt/user32/ChildWindowFromPoint.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ChildWindowFromPoint,ChildWindowFromPoint,1581 diff --git a/libc/nt/user32/ChildWindowFromPointEx.s b/libc/nt/user32/ChildWindowFromPointEx.s new file mode 100644 index 00000000..38f747ec --- /dev/null +++ b/libc/nt/user32/ChildWindowFromPointEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ChildWindowFromPointEx,ChildWindowFromPointEx,1582 diff --git a/libc/nt/user32/CliImmSetHotKey.s b/libc/nt/user32/CliImmSetHotKey.s new file mode 100644 index 00000000..98d53153 --- /dev/null +++ b/libc/nt/user32/CliImmSetHotKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CliImmSetHotKey,CliImmSetHotKey,1583 diff --git a/libc/nt/user32/ClientThreadSetup.s b/libc/nt/user32/ClientThreadSetup.s new file mode 100644 index 00000000..f6816fc7 --- /dev/null +++ b/libc/nt/user32/ClientThreadSetup.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ClientThreadSetup,ClientThreadSetup,1584 diff --git a/libc/nt/user32/ClientToScreen.s b/libc/nt/user32/ClientToScreen.s new file mode 100644 index 00000000..cae15f61 --- /dev/null +++ b/libc/nt/user32/ClientToScreen.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ClientToScreen,ClientToScreen,1585 diff --git a/libc/nt/user32/ClipCursor.s b/libc/nt/user32/ClipCursor.s new file mode 100644 index 00000000..5288c096 --- /dev/null +++ b/libc/nt/user32/ClipCursor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ClipCursor,ClipCursor,1586 diff --git a/libc/nt/user32/CloseClipboard.s b/libc/nt/user32/CloseClipboard.s new file mode 100644 index 00000000..c4fb6045 --- /dev/null +++ b/libc/nt/user32/CloseClipboard.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CloseClipboard,CloseClipboard,1587 diff --git a/libc/nt/user32/CloseDesktop.s b/libc/nt/user32/CloseDesktop.s new file mode 100644 index 00000000..47439b4a --- /dev/null +++ b/libc/nt/user32/CloseDesktop.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CloseDesktop,CloseDesktop,1588 diff --git a/libc/nt/user32/CloseGestureInfoHandle.s b/libc/nt/user32/CloseGestureInfoHandle.s new file mode 100644 index 00000000..1cdf2b0a --- /dev/null +++ b/libc/nt/user32/CloseGestureInfoHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CloseGestureInfoHandle,CloseGestureInfoHandle,1589 diff --git a/libc/nt/user32/CloseTouchInputHandle.s b/libc/nt/user32/CloseTouchInputHandle.s new file mode 100644 index 00000000..4e9e1e66 --- /dev/null +++ b/libc/nt/user32/CloseTouchInputHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CloseTouchInputHandle,CloseTouchInputHandle,1590 diff --git a/libc/nt/user32/CloseWindow.s b/libc/nt/user32/CloseWindow.s new file mode 100644 index 00000000..d13347ed --- /dev/null +++ b/libc/nt/user32/CloseWindow.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CloseWindow,CloseWindow,1591 + + .text.windows +CloseWindow: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_CloseWindow(%rip) + leave + ret + .endfn CloseWindow,globl + .previous diff --git a/libc/nt/user32/CloseWindowStation.s b/libc/nt/user32/CloseWindowStation.s new file mode 100644 index 00000000..3c08792c --- /dev/null +++ b/libc/nt/user32/CloseWindowStation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CloseWindowStation,CloseWindowStation,1592 diff --git a/libc/nt/user32/ConsoleControl.s b/libc/nt/user32/ConsoleControl.s new file mode 100644 index 00000000..bca4996b --- /dev/null +++ b/libc/nt/user32/ConsoleControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ConsoleControl,ConsoleControl,1593 diff --git a/libc/nt/user32/ControlMagnification.s b/libc/nt/user32/ControlMagnification.s new file mode 100644 index 00000000..ed6ed947 --- /dev/null +++ b/libc/nt/user32/ControlMagnification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ControlMagnification,ControlMagnification,1594 diff --git a/libc/nt/user32/CopyAcceleratorTableA.s b/libc/nt/user32/CopyAcceleratorTableA.s new file mode 100644 index 00000000..e38cd62d --- /dev/null +++ b/libc/nt/user32/CopyAcceleratorTableA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CopyAcceleratorTableA,CopyAcceleratorTableA,1595 diff --git a/libc/nt/user32/CopyAcceleratorTableW.s b/libc/nt/user32/CopyAcceleratorTableW.s new file mode 100644 index 00000000..8a046b80 --- /dev/null +++ b/libc/nt/user32/CopyAcceleratorTableW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CopyAcceleratorTableW,CopyAcceleratorTableW,1596 diff --git a/libc/nt/user32/CopyIcon.s b/libc/nt/user32/CopyIcon.s new file mode 100644 index 00000000..0ca55db1 --- /dev/null +++ b/libc/nt/user32/CopyIcon.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CopyIcon,CopyIcon,1597 diff --git a/libc/nt/user32/CopyImage.s b/libc/nt/user32/CopyImage.s new file mode 100644 index 00000000..9ba4a3c3 --- /dev/null +++ b/libc/nt/user32/CopyImage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CopyImage,CopyImage,1598 diff --git a/libc/nt/user32/CopyRect.s b/libc/nt/user32/CopyRect.s new file mode 100644 index 00000000..e11ce03f --- /dev/null +++ b/libc/nt/user32/CopyRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CopyRect,CopyRect,1599 diff --git a/libc/nt/user32/CountClipboardFormats.s b/libc/nt/user32/CountClipboardFormats.s new file mode 100644 index 00000000..0d755234 --- /dev/null +++ b/libc/nt/user32/CountClipboardFormats.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CountClipboardFormats,CountClipboardFormats,1600 diff --git a/libc/nt/user32/CreateAcceleratorTableA.s b/libc/nt/user32/CreateAcceleratorTableA.s new file mode 100644 index 00000000..255ffe06 --- /dev/null +++ b/libc/nt/user32/CreateAcceleratorTableA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateAcceleratorTableA,CreateAcceleratorTableA,1601 diff --git a/libc/nt/user32/CreateAcceleratorTableW.s b/libc/nt/user32/CreateAcceleratorTableW.s new file mode 100644 index 00000000..dfb1434c --- /dev/null +++ b/libc/nt/user32/CreateAcceleratorTableW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateAcceleratorTableW,CreateAcceleratorTableW,1602 diff --git a/libc/nt/user32/CreateCaret.s b/libc/nt/user32/CreateCaret.s new file mode 100644 index 00000000..f43e4291 --- /dev/null +++ b/libc/nt/user32/CreateCaret.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateCaret,CreateCaret,1603 diff --git a/libc/nt/user32/CreateCursor.s b/libc/nt/user32/CreateCursor.s new file mode 100644 index 00000000..e9cc92f0 --- /dev/null +++ b/libc/nt/user32/CreateCursor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateCursor,CreateCursor,1604 diff --git a/libc/nt/user32/CreateDCompositionHwndTarget.s b/libc/nt/user32/CreateDCompositionHwndTarget.s new file mode 100644 index 00000000..67b92f4c --- /dev/null +++ b/libc/nt/user32/CreateDCompositionHwndTarget.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateDCompositionHwndTarget,CreateDCompositionHwndTarget,1605 diff --git a/libc/nt/user32/CreateDesktopA.s b/libc/nt/user32/CreateDesktopA.s new file mode 100644 index 00000000..09f7ec96 --- /dev/null +++ b/libc/nt/user32/CreateDesktopA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateDesktopA,CreateDesktopA,1606 diff --git a/libc/nt/user32/CreateDesktopExA.s b/libc/nt/user32/CreateDesktopExA.s new file mode 100644 index 00000000..824063af --- /dev/null +++ b/libc/nt/user32/CreateDesktopExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateDesktopExA,CreateDesktopExA,1607 diff --git a/libc/nt/user32/CreateDesktopExW.s b/libc/nt/user32/CreateDesktopExW.s new file mode 100644 index 00000000..509bd05c --- /dev/null +++ b/libc/nt/user32/CreateDesktopExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateDesktopExW,CreateDesktopExW,1608 diff --git a/libc/nt/user32/CreateDesktopW.s b/libc/nt/user32/CreateDesktopW.s new file mode 100644 index 00000000..0bbbaad1 --- /dev/null +++ b/libc/nt/user32/CreateDesktopW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateDesktopW,CreateDesktopW,1609 diff --git a/libc/nt/user32/CreateDialogIndirectParamA.s b/libc/nt/user32/CreateDialogIndirectParamA.s new file mode 100644 index 00000000..37a4c7b5 --- /dev/null +++ b/libc/nt/user32/CreateDialogIndirectParamA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateDialogIndirectParamA,CreateDialogIndirectParamA,1610 diff --git a/libc/nt/user32/CreateDialogIndirectParamAorW.s b/libc/nt/user32/CreateDialogIndirectParamAorW.s new file mode 100644 index 00000000..44e491d2 --- /dev/null +++ b/libc/nt/user32/CreateDialogIndirectParamAorW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateDialogIndirectParamAorW,CreateDialogIndirectParamAorW,1611 diff --git a/libc/nt/user32/CreateDialogIndirectParamW.s b/libc/nt/user32/CreateDialogIndirectParamW.s new file mode 100644 index 00000000..2866db76 --- /dev/null +++ b/libc/nt/user32/CreateDialogIndirectParamW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateDialogIndirectParamW,CreateDialogIndirectParamW,1612 diff --git a/libc/nt/user32/CreateDialogParamA.s b/libc/nt/user32/CreateDialogParamA.s new file mode 100644 index 00000000..2d707f9b --- /dev/null +++ b/libc/nt/user32/CreateDialogParamA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateDialogParamA,CreateDialogParamA,1613 diff --git a/libc/nt/user32/CreateDialogParamW.s b/libc/nt/user32/CreateDialogParamW.s new file mode 100644 index 00000000..69ee1bd0 --- /dev/null +++ b/libc/nt/user32/CreateDialogParamW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateDialogParamW,CreateDialogParamW,1614 diff --git a/libc/nt/user32/CreateIcon.s b/libc/nt/user32/CreateIcon.s new file mode 100644 index 00000000..f892f30c --- /dev/null +++ b/libc/nt/user32/CreateIcon.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateIcon,CreateIcon,1615 diff --git a/libc/nt/user32/CreateIconFromResource.s b/libc/nt/user32/CreateIconFromResource.s new file mode 100644 index 00000000..f4a43748 --- /dev/null +++ b/libc/nt/user32/CreateIconFromResource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateIconFromResource,CreateIconFromResource,1616 diff --git a/libc/nt/user32/CreateIconFromResourceEx.s b/libc/nt/user32/CreateIconFromResourceEx.s new file mode 100644 index 00000000..f7821ce3 --- /dev/null +++ b/libc/nt/user32/CreateIconFromResourceEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateIconFromResourceEx,CreateIconFromResourceEx,1617 diff --git a/libc/nt/user32/CreateIconIndirect.s b/libc/nt/user32/CreateIconIndirect.s new file mode 100644 index 00000000..524f6519 --- /dev/null +++ b/libc/nt/user32/CreateIconIndirect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateIconIndirect,CreateIconIndirect,1618 diff --git a/libc/nt/user32/CreateMDIWindowA.s b/libc/nt/user32/CreateMDIWindowA.s new file mode 100644 index 00000000..9933634b --- /dev/null +++ b/libc/nt/user32/CreateMDIWindowA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateMDIWindowA,CreateMDIWindowA,1619 diff --git a/libc/nt/user32/CreateMDIWindowW.s b/libc/nt/user32/CreateMDIWindowW.s new file mode 100644 index 00000000..b80e0d5f --- /dev/null +++ b/libc/nt/user32/CreateMDIWindowW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateMDIWindowW,CreateMDIWindowW,1620 diff --git a/libc/nt/user32/CreateMenu.s b/libc/nt/user32/CreateMenu.s new file mode 100644 index 00000000..a1729e19 --- /dev/null +++ b/libc/nt/user32/CreateMenu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateMenu,CreateMenu,1621 diff --git a/libc/nt/user32/CreatePalmRejectionDelayZone.s b/libc/nt/user32/CreatePalmRejectionDelayZone.s new file mode 100644 index 00000000..bc0e687a --- /dev/null +++ b/libc/nt/user32/CreatePalmRejectionDelayZone.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreatePalmRejectionDelayZone,CreatePalmRejectionDelayZone,1503 diff --git a/libc/nt/user32/CreatePopupMenu.s b/libc/nt/user32/CreatePopupMenu.s new file mode 100644 index 00000000..c3512f59 --- /dev/null +++ b/libc/nt/user32/CreatePopupMenu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreatePopupMenu,CreatePopupMenu,1622 diff --git a/libc/nt/user32/CreateSystemThreads.s b/libc/nt/user32/CreateSystemThreads.s new file mode 100644 index 00000000..bbe4cf10 --- /dev/null +++ b/libc/nt/user32/CreateSystemThreads.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateSystemThreads,CreateSystemThreads,1623 diff --git a/libc/nt/user32/CreateWindowExA.s b/libc/nt/user32/CreateWindowExA.s new file mode 100644 index 00000000..e02cd2d2 --- /dev/null +++ b/libc/nt/user32/CreateWindowExA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateWindowExA,CreateWindowExA,1624 + + .text.windows +CreateWindowExA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateWindowExA(%rip),%rax + jmp __sysv2nt12 + .endfn CreateWindowExA,globl + .previous diff --git a/libc/nt/user32/CreateWindowExW.s b/libc/nt/user32/CreateWindowExW.s new file mode 100644 index 00000000..5f922116 --- /dev/null +++ b/libc/nt/user32/CreateWindowExW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateWindowExW,CreateWindowExW,1625 + + .text.windows +CreateWindowEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_CreateWindowExW(%rip),%rax + jmp __sysv2nt12 + .endfn CreateWindowEx,globl + .previous diff --git a/libc/nt/user32/CreateWindowInBand.s b/libc/nt/user32/CreateWindowInBand.s new file mode 100644 index 00000000..dae42a2b --- /dev/null +++ b/libc/nt/user32/CreateWindowInBand.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateWindowInBand,CreateWindowInBand,1626 diff --git a/libc/nt/user32/CreateWindowInBandEx.s b/libc/nt/user32/CreateWindowInBandEx.s new file mode 100644 index 00000000..8d942e44 --- /dev/null +++ b/libc/nt/user32/CreateWindowInBandEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateWindowInBandEx,CreateWindowInBandEx,1627 diff --git a/libc/nt/user32/CreateWindowIndirect.s b/libc/nt/user32/CreateWindowIndirect.s new file mode 100644 index 00000000..aee7ae10 --- /dev/null +++ b/libc/nt/user32/CreateWindowIndirect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateWindowIndirect,CreateWindowIndirect,1628 diff --git a/libc/nt/user32/CreateWindowStationA.s b/libc/nt/user32/CreateWindowStationA.s new file mode 100644 index 00000000..43ef77e1 --- /dev/null +++ b/libc/nt/user32/CreateWindowStationA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateWindowStationA,CreateWindowStationA,1629 diff --git a/libc/nt/user32/CreateWindowStationW.s b/libc/nt/user32/CreateWindowStationW.s new file mode 100644 index 00000000..a4a72e66 --- /dev/null +++ b/libc/nt/user32/CreateWindowStationW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CreateWindowStationW,CreateWindowStationW,1630 diff --git a/libc/nt/user32/CsrBroadcastSystemMessageExW.s b/libc/nt/user32/CsrBroadcastSystemMessageExW.s new file mode 100644 index 00000000..9490b2cb --- /dev/null +++ b/libc/nt/user32/CsrBroadcastSystemMessageExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CsrBroadcastSystemMessageExW,CsrBroadcastSystemMessageExW,1631 diff --git a/libc/nt/user32/CtxInitUser32.s b/libc/nt/user32/CtxInitUser32.s new file mode 100644 index 00000000..9a7aaa71 --- /dev/null +++ b/libc/nt/user32/CtxInitUser32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_CtxInitUser32,CtxInitUser32,1632 diff --git a/libc/nt/user32/DWMBindCursorToOutputConfig.s b/libc/nt/user32/DWMBindCursorToOutputConfig.s new file mode 100644 index 00000000..3d30fa2b --- /dev/null +++ b/libc/nt/user32/DWMBindCursorToOutputConfig.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DWMBindCursorToOutputConfig,DWMBindCursorToOutputConfig,1633 diff --git a/libc/nt/user32/DWMCommitInputSystemOutputConfig.s b/libc/nt/user32/DWMCommitInputSystemOutputConfig.s new file mode 100644 index 00000000..22d791d5 --- /dev/null +++ b/libc/nt/user32/DWMCommitInputSystemOutputConfig.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DWMCommitInputSystemOutputConfig,DWMCommitInputSystemOutputConfig,1634 diff --git a/libc/nt/user32/DWMSetCursorOrientation.s b/libc/nt/user32/DWMSetCursorOrientation.s new file mode 100644 index 00000000..56471675 --- /dev/null +++ b/libc/nt/user32/DWMSetCursorOrientation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DWMSetCursorOrientation,DWMSetCursorOrientation,1635 diff --git a/libc/nt/user32/DWMSetInputSystemOutputConfig.s b/libc/nt/user32/DWMSetInputSystemOutputConfig.s new file mode 100644 index 00000000..3d40675c --- /dev/null +++ b/libc/nt/user32/DWMSetInputSystemOutputConfig.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DWMSetInputSystemOutputConfig,DWMSetInputSystemOutputConfig,1636 diff --git a/libc/nt/user32/DdeAbandonTransaction.s b/libc/nt/user32/DdeAbandonTransaction.s new file mode 100644 index 00000000..0add094d --- /dev/null +++ b/libc/nt/user32/DdeAbandonTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeAbandonTransaction,DdeAbandonTransaction,1637 diff --git a/libc/nt/user32/DdeAccessData.s b/libc/nt/user32/DdeAccessData.s new file mode 100644 index 00000000..fa2bea7f --- /dev/null +++ b/libc/nt/user32/DdeAccessData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeAccessData,DdeAccessData,1638 diff --git a/libc/nt/user32/DdeAddData.s b/libc/nt/user32/DdeAddData.s new file mode 100644 index 00000000..74c68e9a --- /dev/null +++ b/libc/nt/user32/DdeAddData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeAddData,DdeAddData,1639 diff --git a/libc/nt/user32/DdeClientTransaction.s b/libc/nt/user32/DdeClientTransaction.s new file mode 100644 index 00000000..d6a8af8b --- /dev/null +++ b/libc/nt/user32/DdeClientTransaction.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeClientTransaction,DdeClientTransaction,1640 diff --git a/libc/nt/user32/DdeCmpStringHandles.s b/libc/nt/user32/DdeCmpStringHandles.s new file mode 100644 index 00000000..978d3ab9 --- /dev/null +++ b/libc/nt/user32/DdeCmpStringHandles.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeCmpStringHandles,DdeCmpStringHandles,1641 diff --git a/libc/nt/user32/DdeConnect.s b/libc/nt/user32/DdeConnect.s new file mode 100644 index 00000000..3818529d --- /dev/null +++ b/libc/nt/user32/DdeConnect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeConnect,DdeConnect,1642 diff --git a/libc/nt/user32/DdeConnectList.s b/libc/nt/user32/DdeConnectList.s new file mode 100644 index 00000000..7af61103 --- /dev/null +++ b/libc/nt/user32/DdeConnectList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeConnectList,DdeConnectList,1643 diff --git a/libc/nt/user32/DdeCreateDataHandle.s b/libc/nt/user32/DdeCreateDataHandle.s new file mode 100644 index 00000000..91008856 --- /dev/null +++ b/libc/nt/user32/DdeCreateDataHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeCreateDataHandle,DdeCreateDataHandle,1644 diff --git a/libc/nt/user32/DdeCreateStringHandleA.s b/libc/nt/user32/DdeCreateStringHandleA.s new file mode 100644 index 00000000..58c7c08e --- /dev/null +++ b/libc/nt/user32/DdeCreateStringHandleA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeCreateStringHandleA,DdeCreateStringHandleA,1645 diff --git a/libc/nt/user32/DdeCreateStringHandleW.s b/libc/nt/user32/DdeCreateStringHandleW.s new file mode 100644 index 00000000..ad7e28b1 --- /dev/null +++ b/libc/nt/user32/DdeCreateStringHandleW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeCreateStringHandleW,DdeCreateStringHandleW,1646 diff --git a/libc/nt/user32/DdeDisconnect.s b/libc/nt/user32/DdeDisconnect.s new file mode 100644 index 00000000..99f04cc4 --- /dev/null +++ b/libc/nt/user32/DdeDisconnect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeDisconnect,DdeDisconnect,1647 diff --git a/libc/nt/user32/DdeDisconnectList.s b/libc/nt/user32/DdeDisconnectList.s new file mode 100644 index 00000000..f052e71e --- /dev/null +++ b/libc/nt/user32/DdeDisconnectList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeDisconnectList,DdeDisconnectList,1648 diff --git a/libc/nt/user32/DdeEnableCallback.s b/libc/nt/user32/DdeEnableCallback.s new file mode 100644 index 00000000..5ec360c3 --- /dev/null +++ b/libc/nt/user32/DdeEnableCallback.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeEnableCallback,DdeEnableCallback,1649 diff --git a/libc/nt/user32/DdeFreeDataHandle.s b/libc/nt/user32/DdeFreeDataHandle.s new file mode 100644 index 00000000..2d465cbb --- /dev/null +++ b/libc/nt/user32/DdeFreeDataHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeFreeDataHandle,DdeFreeDataHandle,1650 diff --git a/libc/nt/user32/DdeFreeStringHandle.s b/libc/nt/user32/DdeFreeStringHandle.s new file mode 100644 index 00000000..b025d1d1 --- /dev/null +++ b/libc/nt/user32/DdeFreeStringHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeFreeStringHandle,DdeFreeStringHandle,1651 diff --git a/libc/nt/user32/DdeGetData.s b/libc/nt/user32/DdeGetData.s new file mode 100644 index 00000000..85f65404 --- /dev/null +++ b/libc/nt/user32/DdeGetData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeGetData,DdeGetData,1652 diff --git a/libc/nt/user32/DdeGetLastError.s b/libc/nt/user32/DdeGetLastError.s new file mode 100644 index 00000000..89ea4e22 --- /dev/null +++ b/libc/nt/user32/DdeGetLastError.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeGetLastError,DdeGetLastError,1653 diff --git a/libc/nt/user32/DdeGetQualityOfService.s b/libc/nt/user32/DdeGetQualityOfService.s new file mode 100644 index 00000000..7c981f39 --- /dev/null +++ b/libc/nt/user32/DdeGetQualityOfService.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeGetQualityOfService,DdeGetQualityOfService,1654 diff --git a/libc/nt/user32/DdeImpersonateClient.s b/libc/nt/user32/DdeImpersonateClient.s new file mode 100644 index 00000000..7ed7d9ae --- /dev/null +++ b/libc/nt/user32/DdeImpersonateClient.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeImpersonateClient,DdeImpersonateClient,1655 diff --git a/libc/nt/user32/DdeInitializeA.s b/libc/nt/user32/DdeInitializeA.s new file mode 100644 index 00000000..3223a7ea --- /dev/null +++ b/libc/nt/user32/DdeInitializeA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeInitializeA,DdeInitializeA,1656 diff --git a/libc/nt/user32/DdeInitializeW.s b/libc/nt/user32/DdeInitializeW.s new file mode 100644 index 00000000..cd727e7f --- /dev/null +++ b/libc/nt/user32/DdeInitializeW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeInitializeW,DdeInitializeW,1657 diff --git a/libc/nt/user32/DdeKeepStringHandle.s b/libc/nt/user32/DdeKeepStringHandle.s new file mode 100644 index 00000000..7e898329 --- /dev/null +++ b/libc/nt/user32/DdeKeepStringHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeKeepStringHandle,DdeKeepStringHandle,1658 diff --git a/libc/nt/user32/DdeNameService.s b/libc/nt/user32/DdeNameService.s new file mode 100644 index 00000000..6ea76c61 --- /dev/null +++ b/libc/nt/user32/DdeNameService.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeNameService,DdeNameService,1659 diff --git a/libc/nt/user32/DdePostAdvise.s b/libc/nt/user32/DdePostAdvise.s new file mode 100644 index 00000000..94ff89b1 --- /dev/null +++ b/libc/nt/user32/DdePostAdvise.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdePostAdvise,DdePostAdvise,1660 diff --git a/libc/nt/user32/DdeQueryConvInfo.s b/libc/nt/user32/DdeQueryConvInfo.s new file mode 100644 index 00000000..6269b843 --- /dev/null +++ b/libc/nt/user32/DdeQueryConvInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeQueryConvInfo,DdeQueryConvInfo,1661 diff --git a/libc/nt/user32/DdeQueryNextServer.s b/libc/nt/user32/DdeQueryNextServer.s new file mode 100644 index 00000000..a0aab4e4 --- /dev/null +++ b/libc/nt/user32/DdeQueryNextServer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeQueryNextServer,DdeQueryNextServer,1662 diff --git a/libc/nt/user32/DdeQueryStringA.s b/libc/nt/user32/DdeQueryStringA.s new file mode 100644 index 00000000..36619ce7 --- /dev/null +++ b/libc/nt/user32/DdeQueryStringA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeQueryStringA,DdeQueryStringA,1663 diff --git a/libc/nt/user32/DdeQueryStringW.s b/libc/nt/user32/DdeQueryStringW.s new file mode 100644 index 00000000..99771567 --- /dev/null +++ b/libc/nt/user32/DdeQueryStringW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeQueryStringW,DdeQueryStringW,1664 diff --git a/libc/nt/user32/DdeReconnect.s b/libc/nt/user32/DdeReconnect.s new file mode 100644 index 00000000..ff04d645 --- /dev/null +++ b/libc/nt/user32/DdeReconnect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeReconnect,DdeReconnect,1665 diff --git a/libc/nt/user32/DdeSetQualityOfService.s b/libc/nt/user32/DdeSetQualityOfService.s new file mode 100644 index 00000000..fc3d6f3b --- /dev/null +++ b/libc/nt/user32/DdeSetQualityOfService.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeSetQualityOfService,DdeSetQualityOfService,1666 diff --git a/libc/nt/user32/DdeSetUserHandle.s b/libc/nt/user32/DdeSetUserHandle.s new file mode 100644 index 00000000..f9644086 --- /dev/null +++ b/libc/nt/user32/DdeSetUserHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeSetUserHandle,DdeSetUserHandle,1667 diff --git a/libc/nt/user32/DdeUnaccessData.s b/libc/nt/user32/DdeUnaccessData.s new file mode 100644 index 00000000..30435b1e --- /dev/null +++ b/libc/nt/user32/DdeUnaccessData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeUnaccessData,DdeUnaccessData,1668 diff --git a/libc/nt/user32/DdeUninitialize.s b/libc/nt/user32/DdeUninitialize.s new file mode 100644 index 00000000..6bb3e5f7 --- /dev/null +++ b/libc/nt/user32/DdeUninitialize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DdeUninitialize,DdeUninitialize,1669 diff --git a/libc/nt/user32/DefFrameProcA.s b/libc/nt/user32/DefFrameProcA.s new file mode 100644 index 00000000..965d84e7 --- /dev/null +++ b/libc/nt/user32/DefFrameProcA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DefFrameProcA,DefFrameProcA,1672 diff --git a/libc/nt/user32/DefFrameProcW.s b/libc/nt/user32/DefFrameProcW.s new file mode 100644 index 00000000..a99dd022 --- /dev/null +++ b/libc/nt/user32/DefFrameProcW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DefFrameProcW,DefFrameProcW,1673 diff --git a/libc/nt/user32/DefMDIChildProcA.s b/libc/nt/user32/DefMDIChildProcA.s new file mode 100644 index 00000000..4eeda69e --- /dev/null +++ b/libc/nt/user32/DefMDIChildProcA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DefMDIChildProcA,DefMDIChildProcA,1674 diff --git a/libc/nt/user32/DefMDIChildProcW.s b/libc/nt/user32/DefMDIChildProcW.s new file mode 100644 index 00000000..6578cd66 --- /dev/null +++ b/libc/nt/user32/DefMDIChildProcW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DefMDIChildProcW,DefMDIChildProcW,1675 diff --git a/libc/nt/user32/DefRawInputProc.s b/libc/nt/user32/DefRawInputProc.s new file mode 100644 index 00000000..4d45cd68 --- /dev/null +++ b/libc/nt/user32/DefRawInputProc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DefRawInputProc,DefRawInputProc,1676 diff --git a/libc/nt/user32/DeferWindowPos.s b/libc/nt/user32/DeferWindowPos.s new file mode 100644 index 00000000..a3cb30db --- /dev/null +++ b/libc/nt/user32/DeferWindowPos.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DeferWindowPos,DeferWindowPos,1679 diff --git a/libc/nt/user32/DeferWindowPosAndBand.s b/libc/nt/user32/DeferWindowPosAndBand.s new file mode 100644 index 00000000..7d6b64c7 --- /dev/null +++ b/libc/nt/user32/DeferWindowPosAndBand.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DeferWindowPosAndBand,DeferWindowPosAndBand,1680 diff --git a/libc/nt/user32/DelegateInput.s b/libc/nt/user32/DelegateInput.s new file mode 100644 index 00000000..d8f64842 --- /dev/null +++ b/libc/nt/user32/DelegateInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DelegateInput,DelegateInput,2503 diff --git a/libc/nt/user32/DeleteMenu.s b/libc/nt/user32/DeleteMenu.s new file mode 100644 index 00000000..0a225fb6 --- /dev/null +++ b/libc/nt/user32/DeleteMenu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DeleteMenu,DeleteMenu,1681 diff --git a/libc/nt/user32/DeregisterShellHookWindow.s b/libc/nt/user32/DeregisterShellHookWindow.s new file mode 100644 index 00000000..c9ecfabf --- /dev/null +++ b/libc/nt/user32/DeregisterShellHookWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DeregisterShellHookWindow,DeregisterShellHookWindow,1682 diff --git a/libc/nt/user32/DestroyAcceleratorTable.s b/libc/nt/user32/DestroyAcceleratorTable.s new file mode 100644 index 00000000..f6f6c5f4 --- /dev/null +++ b/libc/nt/user32/DestroyAcceleratorTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DestroyAcceleratorTable,DestroyAcceleratorTable,1683 diff --git a/libc/nt/user32/DestroyCaret.s b/libc/nt/user32/DestroyCaret.s new file mode 100644 index 00000000..532542b2 --- /dev/null +++ b/libc/nt/user32/DestroyCaret.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DestroyCaret,DestroyCaret,1684 diff --git a/libc/nt/user32/DestroyCursor.s b/libc/nt/user32/DestroyCursor.s new file mode 100644 index 00000000..67b37946 --- /dev/null +++ b/libc/nt/user32/DestroyCursor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DestroyCursor,DestroyCursor,1685 diff --git a/libc/nt/user32/DestroyDCompositionHwndTarget.s b/libc/nt/user32/DestroyDCompositionHwndTarget.s new file mode 100644 index 00000000..41e7e7bd --- /dev/null +++ b/libc/nt/user32/DestroyDCompositionHwndTarget.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DestroyDCompositionHwndTarget,DestroyDCompositionHwndTarget,1686 diff --git a/libc/nt/user32/DestroyIcon.s b/libc/nt/user32/DestroyIcon.s new file mode 100644 index 00000000..006cfa38 --- /dev/null +++ b/libc/nt/user32/DestroyIcon.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DestroyIcon,DestroyIcon,1687 diff --git a/libc/nt/user32/DestroyMenu.s b/libc/nt/user32/DestroyMenu.s new file mode 100644 index 00000000..fb47cc65 --- /dev/null +++ b/libc/nt/user32/DestroyMenu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DestroyMenu,DestroyMenu,1688 diff --git a/libc/nt/user32/DestroyPalmRejectionDelayZone.s b/libc/nt/user32/DestroyPalmRejectionDelayZone.s new file mode 100644 index 00000000..eb597204 --- /dev/null +++ b/libc/nt/user32/DestroyPalmRejectionDelayZone.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DestroyPalmRejectionDelayZone,DestroyPalmRejectionDelayZone,1504 diff --git a/libc/nt/user32/DestroyReasons.s b/libc/nt/user32/DestroyReasons.s new file mode 100644 index 00000000..b727411f --- /dev/null +++ b/libc/nt/user32/DestroyReasons.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DestroyReasons,DestroyReasons,1689 diff --git a/libc/nt/user32/DestroyWindow.s b/libc/nt/user32/DestroyWindow.s new file mode 100644 index 00000000..2b5fb112 --- /dev/null +++ b/libc/nt/user32/DestroyWindow.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DestroyWindow,DestroyWindow,1690 + + .text.windows +DestroyWindow: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_DestroyWindow(%rip) + leave + ret + .endfn DestroyWindow,globl + .previous diff --git a/libc/nt/user32/DialogBoxIndirectParamA.s b/libc/nt/user32/DialogBoxIndirectParamA.s new file mode 100644 index 00000000..3be9d925 --- /dev/null +++ b/libc/nt/user32/DialogBoxIndirectParamA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DialogBoxIndirectParamA,DialogBoxIndirectParamA,1691 diff --git a/libc/nt/user32/DialogBoxIndirectParamAorW.s b/libc/nt/user32/DialogBoxIndirectParamAorW.s new file mode 100644 index 00000000..a9d10de9 --- /dev/null +++ b/libc/nt/user32/DialogBoxIndirectParamAorW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DialogBoxIndirectParamAorW,DialogBoxIndirectParamAorW,1692 diff --git a/libc/nt/user32/DialogBoxIndirectParamW.s b/libc/nt/user32/DialogBoxIndirectParamW.s new file mode 100644 index 00000000..75ac8d52 --- /dev/null +++ b/libc/nt/user32/DialogBoxIndirectParamW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DialogBoxIndirectParamW,DialogBoxIndirectParamW,1693 diff --git a/libc/nt/user32/DialogBoxParamA.s b/libc/nt/user32/DialogBoxParamA.s new file mode 100644 index 00000000..9b2a446d --- /dev/null +++ b/libc/nt/user32/DialogBoxParamA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DialogBoxParamA,DialogBoxParamA,1694 diff --git a/libc/nt/user32/DialogBoxParamW.s b/libc/nt/user32/DialogBoxParamW.s new file mode 100644 index 00000000..b08d8869 --- /dev/null +++ b/libc/nt/user32/DialogBoxParamW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DialogBoxParamW,DialogBoxParamW,1695 diff --git a/libc/nt/user32/DisableProcessWindowsGhosting.s b/libc/nt/user32/DisableProcessWindowsGhosting.s new file mode 100644 index 00000000..619e93a3 --- /dev/null +++ b/libc/nt/user32/DisableProcessWindowsGhosting.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DisableProcessWindowsGhosting,DisableProcessWindowsGhosting,1696 diff --git a/libc/nt/user32/DispatchMessageA.s b/libc/nt/user32/DispatchMessageA.s new file mode 100644 index 00000000..1d4aa7ac --- /dev/null +++ b/libc/nt/user32/DispatchMessageA.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DispatchMessageA,DispatchMessageA,1697 + + .text.windows +DispatchMessageA: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_DispatchMessageA(%rip) + leave + ret + .endfn DispatchMessageA,globl + .previous diff --git a/libc/nt/user32/DispatchMessageW.s b/libc/nt/user32/DispatchMessageW.s new file mode 100644 index 00000000..c8e2215d --- /dev/null +++ b/libc/nt/user32/DispatchMessageW.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DispatchMessageW,DispatchMessageW,1698 + + .text.windows +DispatchMessage: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_DispatchMessageW(%rip) + leave + ret + .endfn DispatchMessage,globl + .previous diff --git a/libc/nt/user32/DisplayConfigGetDeviceInfo.s b/libc/nt/user32/DisplayConfigGetDeviceInfo.s new file mode 100644 index 00000000..adda2c14 --- /dev/null +++ b/libc/nt/user32/DisplayConfigGetDeviceInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DisplayConfigGetDeviceInfo,DisplayConfigGetDeviceInfo,1699 diff --git a/libc/nt/user32/DisplayConfigSetDeviceInfo.s b/libc/nt/user32/DisplayConfigSetDeviceInfo.s new file mode 100644 index 00000000..a2361020 --- /dev/null +++ b/libc/nt/user32/DisplayConfigSetDeviceInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DisplayConfigSetDeviceInfo,DisplayConfigSetDeviceInfo,1700 diff --git a/libc/nt/user32/DisplayExitWindowsWarnings.s b/libc/nt/user32/DisplayExitWindowsWarnings.s new file mode 100644 index 00000000..73d49293 --- /dev/null +++ b/libc/nt/user32/DisplayExitWindowsWarnings.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DisplayExitWindowsWarnings,DisplayExitWindowsWarnings,1701 diff --git a/libc/nt/user32/DlgDirListA.s b/libc/nt/user32/DlgDirListA.s new file mode 100644 index 00000000..32988e34 --- /dev/null +++ b/libc/nt/user32/DlgDirListA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DlgDirListA,DlgDirListA,1702 diff --git a/libc/nt/user32/DlgDirListComboBoxA.s b/libc/nt/user32/DlgDirListComboBoxA.s new file mode 100644 index 00000000..f984f53d --- /dev/null +++ b/libc/nt/user32/DlgDirListComboBoxA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DlgDirListComboBoxA,DlgDirListComboBoxA,1703 diff --git a/libc/nt/user32/DlgDirListComboBoxW.s b/libc/nt/user32/DlgDirListComboBoxW.s new file mode 100644 index 00000000..db3a1485 --- /dev/null +++ b/libc/nt/user32/DlgDirListComboBoxW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DlgDirListComboBoxW,DlgDirListComboBoxW,1704 diff --git a/libc/nt/user32/DlgDirListW.s b/libc/nt/user32/DlgDirListW.s new file mode 100644 index 00000000..4ac3f8fd --- /dev/null +++ b/libc/nt/user32/DlgDirListW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DlgDirListW,DlgDirListW,1705 diff --git a/libc/nt/user32/DlgDirSelectComboBoxExA.s b/libc/nt/user32/DlgDirSelectComboBoxExA.s new file mode 100644 index 00000000..eac68f1d --- /dev/null +++ b/libc/nt/user32/DlgDirSelectComboBoxExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DlgDirSelectComboBoxExA,DlgDirSelectComboBoxExA,1706 diff --git a/libc/nt/user32/DlgDirSelectComboBoxExW.s b/libc/nt/user32/DlgDirSelectComboBoxExW.s new file mode 100644 index 00000000..124bf03f --- /dev/null +++ b/libc/nt/user32/DlgDirSelectComboBoxExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DlgDirSelectComboBoxExW,DlgDirSelectComboBoxExW,1707 diff --git a/libc/nt/user32/DlgDirSelectExA.s b/libc/nt/user32/DlgDirSelectExA.s new file mode 100644 index 00000000..ec172075 --- /dev/null +++ b/libc/nt/user32/DlgDirSelectExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DlgDirSelectExA,DlgDirSelectExA,1708 diff --git a/libc/nt/user32/DlgDirSelectExW.s b/libc/nt/user32/DlgDirSelectExW.s new file mode 100644 index 00000000..ecc04d2d --- /dev/null +++ b/libc/nt/user32/DlgDirSelectExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DlgDirSelectExW,DlgDirSelectExW,1709 diff --git a/libc/nt/user32/DoSoundConnect.s b/libc/nt/user32/DoSoundConnect.s new file mode 100644 index 00000000..90a8a147 --- /dev/null +++ b/libc/nt/user32/DoSoundConnect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DoSoundConnect,DoSoundConnect,1710 diff --git a/libc/nt/user32/DoSoundDisconnect.s b/libc/nt/user32/DoSoundDisconnect.s new file mode 100644 index 00000000..4c53fcec --- /dev/null +++ b/libc/nt/user32/DoSoundDisconnect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DoSoundDisconnect,DoSoundDisconnect,1711 diff --git a/libc/nt/user32/DragDetect.s b/libc/nt/user32/DragDetect.s new file mode 100644 index 00000000..f5d6d10e --- /dev/null +++ b/libc/nt/user32/DragDetect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DragDetect,DragDetect,1712 diff --git a/libc/nt/user32/DragObject.s b/libc/nt/user32/DragObject.s new file mode 100644 index 00000000..96da773a --- /dev/null +++ b/libc/nt/user32/DragObject.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DragObject,DragObject,1713 diff --git a/libc/nt/user32/DrawAnimatedRects.s b/libc/nt/user32/DrawAnimatedRects.s new file mode 100644 index 00000000..e2eeed7a --- /dev/null +++ b/libc/nt/user32/DrawAnimatedRects.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawAnimatedRects,DrawAnimatedRects,1714 diff --git a/libc/nt/user32/DrawCaption.s b/libc/nt/user32/DrawCaption.s new file mode 100644 index 00000000..c0c6060d --- /dev/null +++ b/libc/nt/user32/DrawCaption.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawCaption,DrawCaption,1715 diff --git a/libc/nt/user32/DrawCaptionTempA.s b/libc/nt/user32/DrawCaptionTempA.s new file mode 100644 index 00000000..d29688aa --- /dev/null +++ b/libc/nt/user32/DrawCaptionTempA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawCaptionTempA,DrawCaptionTempA,1716 diff --git a/libc/nt/user32/DrawCaptionTempW.s b/libc/nt/user32/DrawCaptionTempW.s new file mode 100644 index 00000000..6d3efb41 --- /dev/null +++ b/libc/nt/user32/DrawCaptionTempW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawCaptionTempW,DrawCaptionTempW,1717 diff --git a/libc/nt/user32/DrawEdge.s b/libc/nt/user32/DrawEdge.s new file mode 100644 index 00000000..9e84c6c4 --- /dev/null +++ b/libc/nt/user32/DrawEdge.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawEdge,DrawEdge,1718 diff --git a/libc/nt/user32/DrawFocusRect.s b/libc/nt/user32/DrawFocusRect.s new file mode 100644 index 00000000..cf40eb19 --- /dev/null +++ b/libc/nt/user32/DrawFocusRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawFocusRect,DrawFocusRect,1719 diff --git a/libc/nt/user32/DrawFrame.s b/libc/nt/user32/DrawFrame.s new file mode 100644 index 00000000..1abd0da5 --- /dev/null +++ b/libc/nt/user32/DrawFrame.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawFrame,DrawFrame,1720 diff --git a/libc/nt/user32/DrawFrameControl.s b/libc/nt/user32/DrawFrameControl.s new file mode 100644 index 00000000..47c621f3 --- /dev/null +++ b/libc/nt/user32/DrawFrameControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawFrameControl,DrawFrameControl,1721 diff --git a/libc/nt/user32/DrawIcon.s b/libc/nt/user32/DrawIcon.s new file mode 100644 index 00000000..df7102ee --- /dev/null +++ b/libc/nt/user32/DrawIcon.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawIcon,DrawIcon,1722 diff --git a/libc/nt/user32/DrawIconEx.s b/libc/nt/user32/DrawIconEx.s new file mode 100644 index 00000000..684d60e9 --- /dev/null +++ b/libc/nt/user32/DrawIconEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawIconEx,DrawIconEx,1723 diff --git a/libc/nt/user32/DrawMenuBar.s b/libc/nt/user32/DrawMenuBar.s new file mode 100644 index 00000000..a4fb23eb --- /dev/null +++ b/libc/nt/user32/DrawMenuBar.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawMenuBar,DrawMenuBar,1724 diff --git a/libc/nt/user32/DrawMenuBarTemp.s b/libc/nt/user32/DrawMenuBarTemp.s new file mode 100644 index 00000000..4edf40b0 --- /dev/null +++ b/libc/nt/user32/DrawMenuBarTemp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawMenuBarTemp,DrawMenuBarTemp,1725 diff --git a/libc/nt/user32/DrawStateA.s b/libc/nt/user32/DrawStateA.s new file mode 100644 index 00000000..a14d02b8 --- /dev/null +++ b/libc/nt/user32/DrawStateA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawStateA,DrawStateA,1726 diff --git a/libc/nt/user32/DrawStateW.s b/libc/nt/user32/DrawStateW.s new file mode 100644 index 00000000..92e9ea23 --- /dev/null +++ b/libc/nt/user32/DrawStateW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawStateW,DrawStateW,1727 diff --git a/libc/nt/user32/DrawTextA.s b/libc/nt/user32/DrawTextA.s new file mode 100644 index 00000000..ee7f93b4 --- /dev/null +++ b/libc/nt/user32/DrawTextA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawTextA,DrawTextA,1728 + + .text.windows +DrawTextA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_DrawTextA(%rip),%rax + jmp __sysv2nt6 + .endfn DrawTextA,globl + .previous diff --git a/libc/nt/user32/DrawTextExA.s b/libc/nt/user32/DrawTextExA.s new file mode 100644 index 00000000..8dc9af14 --- /dev/null +++ b/libc/nt/user32/DrawTextExA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawTextExA,DrawTextExA,1729 + + .text.windows +DrawTextExA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_DrawTextExA(%rip),%rax + jmp __sysv2nt6 + .endfn DrawTextExA,globl + .previous diff --git a/libc/nt/user32/DrawTextExW.s b/libc/nt/user32/DrawTextExW.s new file mode 100644 index 00000000..dce10e45 --- /dev/null +++ b/libc/nt/user32/DrawTextExW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawTextExW,DrawTextExW,1730 + + .text.windows +DrawTextEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_DrawTextExW(%rip),%rax + jmp __sysv2nt6 + .endfn DrawTextEx,globl + .previous diff --git a/libc/nt/user32/DrawTextW.s b/libc/nt/user32/DrawTextW.s new file mode 100644 index 00000000..08c58ba5 --- /dev/null +++ b/libc/nt/user32/DrawTextW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DrawTextW,DrawTextW,1731 + + .text.windows +DrawText: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_DrawTextW(%rip),%rax + jmp __sysv2nt6 + .endfn DrawText,globl + .previous diff --git a/libc/nt/user32/DwmGetDxRgn.s b/libc/nt/user32/DwmGetDxRgn.s new file mode 100644 index 00000000..6c5bfa52 --- /dev/null +++ b/libc/nt/user32/DwmGetDxRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DwmGetDxRgn,DwmGetDxRgn,1553 diff --git a/libc/nt/user32/DwmGetDxSharedSurface.s b/libc/nt/user32/DwmGetDxSharedSurface.s new file mode 100644 index 00000000..eb29fa88 --- /dev/null +++ b/libc/nt/user32/DwmGetDxSharedSurface.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DwmGetDxSharedSurface,DwmGetDxSharedSurface,1732 diff --git a/libc/nt/user32/DwmGetRemoteSessionOcclusionEvent.s b/libc/nt/user32/DwmGetRemoteSessionOcclusionEvent.s new file mode 100644 index 00000000..4fb772ff --- /dev/null +++ b/libc/nt/user32/DwmGetRemoteSessionOcclusionEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DwmGetRemoteSessionOcclusionEvent,DwmGetRemoteSessionOcclusionEvent,1733 diff --git a/libc/nt/user32/DwmGetRemoteSessionOcclusionState.s b/libc/nt/user32/DwmGetRemoteSessionOcclusionState.s new file mode 100644 index 00000000..04a009f4 --- /dev/null +++ b/libc/nt/user32/DwmGetRemoteSessionOcclusionState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DwmGetRemoteSessionOcclusionState,DwmGetRemoteSessionOcclusionState,1734 diff --git a/libc/nt/user32/DwmKernelShutdown.s b/libc/nt/user32/DwmKernelShutdown.s new file mode 100644 index 00000000..1ae7040f --- /dev/null +++ b/libc/nt/user32/DwmKernelShutdown.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DwmKernelShutdown,DwmKernelShutdown,1735 diff --git a/libc/nt/user32/DwmKernelStartup.s b/libc/nt/user32/DwmKernelStartup.s new file mode 100644 index 00000000..a951b846 --- /dev/null +++ b/libc/nt/user32/DwmKernelStartup.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DwmKernelStartup,DwmKernelStartup,1736 diff --git a/libc/nt/user32/DwmLockScreenUpdates.s b/libc/nt/user32/DwmLockScreenUpdates.s new file mode 100644 index 00000000..34ca8cd8 --- /dev/null +++ b/libc/nt/user32/DwmLockScreenUpdates.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DwmLockScreenUpdates,DwmLockScreenUpdates,1737 diff --git a/libc/nt/user32/DwmValidateWindow.s b/libc/nt/user32/DwmValidateWindow.s new file mode 100644 index 00000000..b048dbc7 --- /dev/null +++ b/libc/nt/user32/DwmValidateWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DwmValidateWindow,DwmValidateWindow,1738 diff --git a/libc/nt/user32/EditWndProc.s b/libc/nt/user32/EditWndProc.s new file mode 100644 index 00000000..87db5dfb --- /dev/null +++ b/libc/nt/user32/EditWndProc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EditWndProc,EditWndProc,1739 diff --git a/libc/nt/user32/EmptyClipboard.s b/libc/nt/user32/EmptyClipboard.s new file mode 100644 index 00000000..d01c76c2 --- /dev/null +++ b/libc/nt/user32/EmptyClipboard.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EmptyClipboard,EmptyClipboard,1740 diff --git a/libc/nt/user32/EnableMenuItem.s b/libc/nt/user32/EnableMenuItem.s new file mode 100644 index 00000000..f4d96a7c --- /dev/null +++ b/libc/nt/user32/EnableMenuItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnableMenuItem,EnableMenuItem,1741 diff --git a/libc/nt/user32/EnableMouseInPointer.s b/libc/nt/user32/EnableMouseInPointer.s new file mode 100644 index 00000000..f02ba2c0 --- /dev/null +++ b/libc/nt/user32/EnableMouseInPointer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnableMouseInPointer,EnableMouseInPointer,1742 diff --git a/libc/nt/user32/EnableNonClientDpiScaling.s b/libc/nt/user32/EnableNonClientDpiScaling.s new file mode 100644 index 00000000..87c49ef4 --- /dev/null +++ b/libc/nt/user32/EnableNonClientDpiScaling.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnableNonClientDpiScaling,EnableNonClientDpiScaling,1743 diff --git a/libc/nt/user32/EnableOneCoreTransformMode.s b/libc/nt/user32/EnableOneCoreTransformMode.s new file mode 100644 index 00000000..72baa32d --- /dev/null +++ b/libc/nt/user32/EnableOneCoreTransformMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnableOneCoreTransformMode,EnableOneCoreTransformMode,1744 diff --git a/libc/nt/user32/EnableScrollBar.s b/libc/nt/user32/EnableScrollBar.s new file mode 100644 index 00000000..6326346b --- /dev/null +++ b/libc/nt/user32/EnableScrollBar.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnableScrollBar,EnableScrollBar,1745 diff --git a/libc/nt/user32/EnableSessionForMMCSS.s b/libc/nt/user32/EnableSessionForMMCSS.s new file mode 100644 index 00000000..a6aac16d --- /dev/null +++ b/libc/nt/user32/EnableSessionForMMCSS.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnableSessionForMMCSS,EnableSessionForMMCSS,1746 diff --git a/libc/nt/user32/EnableWindow.s b/libc/nt/user32/EnableWindow.s new file mode 100644 index 00000000..f0113d8d --- /dev/null +++ b/libc/nt/user32/EnableWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnableWindow,EnableWindow,1747 diff --git a/libc/nt/user32/EndDeferWindowPos.s b/libc/nt/user32/EndDeferWindowPos.s new file mode 100644 index 00000000..b49aeb17 --- /dev/null +++ b/libc/nt/user32/EndDeferWindowPos.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EndDeferWindowPos,EndDeferWindowPos,1748 diff --git a/libc/nt/user32/EndDeferWindowPosEx.s b/libc/nt/user32/EndDeferWindowPosEx.s new file mode 100644 index 00000000..6a57f4a6 --- /dev/null +++ b/libc/nt/user32/EndDeferWindowPosEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EndDeferWindowPosEx,EndDeferWindowPosEx,1749 diff --git a/libc/nt/user32/EndDialog.s b/libc/nt/user32/EndDialog.s new file mode 100644 index 00000000..9c418bee --- /dev/null +++ b/libc/nt/user32/EndDialog.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EndDialog,EndDialog,1750 diff --git a/libc/nt/user32/EndMenu.s b/libc/nt/user32/EndMenu.s new file mode 100644 index 00000000..ff9c7406 --- /dev/null +++ b/libc/nt/user32/EndMenu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EndMenu,EndMenu,1751 diff --git a/libc/nt/user32/EndPaint.s b/libc/nt/user32/EndPaint.s new file mode 100644 index 00000000..e355a507 --- /dev/null +++ b/libc/nt/user32/EndPaint.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EndPaint,EndPaint,1752 + + .text.windows +EndPaint: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_EndPaint(%rip),%rax + jmp __sysv2nt + .endfn EndPaint,globl + .previous diff --git a/libc/nt/user32/EndTask.s b/libc/nt/user32/EndTask.s new file mode 100644 index 00000000..a55a70ee --- /dev/null +++ b/libc/nt/user32/EndTask.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EndTask,EndTask,1753 diff --git a/libc/nt/user32/EnterReaderModeHelper.s b/libc/nt/user32/EnterReaderModeHelper.s new file mode 100644 index 00000000..0b7c1f0b --- /dev/null +++ b/libc/nt/user32/EnterReaderModeHelper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnterReaderModeHelper,EnterReaderModeHelper,1754 diff --git a/libc/nt/user32/EnumChildWindows.s b/libc/nt/user32/EnumChildWindows.s new file mode 100644 index 00000000..c59a6226 --- /dev/null +++ b/libc/nt/user32/EnumChildWindows.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumChildWindows,EnumChildWindows,1755 + + .text.windows +EnumChildWindows: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_EnumChildWindows(%rip),%rax + jmp __sysv2nt + .endfn EnumChildWindows,globl + .previous diff --git a/libc/nt/user32/EnumClipboardFormats.s b/libc/nt/user32/EnumClipboardFormats.s new file mode 100644 index 00000000..e378473b --- /dev/null +++ b/libc/nt/user32/EnumClipboardFormats.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumClipboardFormats,EnumClipboardFormats,1756 diff --git a/libc/nt/user32/EnumDesktopWindows.s b/libc/nt/user32/EnumDesktopWindows.s new file mode 100644 index 00000000..fa30108d --- /dev/null +++ b/libc/nt/user32/EnumDesktopWindows.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumDesktopWindows,EnumDesktopWindows,1757 diff --git a/libc/nt/user32/EnumDesktopsA.s b/libc/nt/user32/EnumDesktopsA.s new file mode 100644 index 00000000..4ec65d1e --- /dev/null +++ b/libc/nt/user32/EnumDesktopsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumDesktopsA,EnumDesktopsA,1758 diff --git a/libc/nt/user32/EnumDesktopsW.s b/libc/nt/user32/EnumDesktopsW.s new file mode 100644 index 00000000..0372b03a --- /dev/null +++ b/libc/nt/user32/EnumDesktopsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumDesktopsW,EnumDesktopsW,1759 diff --git a/libc/nt/user32/EnumDisplayDevicesA.s b/libc/nt/user32/EnumDisplayDevicesA.s new file mode 100644 index 00000000..83feba45 --- /dev/null +++ b/libc/nt/user32/EnumDisplayDevicesA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumDisplayDevicesA,EnumDisplayDevicesA,1760 diff --git a/libc/nt/user32/EnumDisplayDevicesW.s b/libc/nt/user32/EnumDisplayDevicesW.s new file mode 100644 index 00000000..7b98c2a0 --- /dev/null +++ b/libc/nt/user32/EnumDisplayDevicesW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumDisplayDevicesW,EnumDisplayDevicesW,1761 diff --git a/libc/nt/user32/EnumDisplayMonitors.s b/libc/nt/user32/EnumDisplayMonitors.s new file mode 100644 index 00000000..add43108 --- /dev/null +++ b/libc/nt/user32/EnumDisplayMonitors.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumDisplayMonitors,EnumDisplayMonitors,1762 diff --git a/libc/nt/user32/EnumDisplaySettingsA.s b/libc/nt/user32/EnumDisplaySettingsA.s new file mode 100644 index 00000000..736878de --- /dev/null +++ b/libc/nt/user32/EnumDisplaySettingsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumDisplaySettingsA,EnumDisplaySettingsA,1763 diff --git a/libc/nt/user32/EnumDisplaySettingsExA.s b/libc/nt/user32/EnumDisplaySettingsExA.s new file mode 100644 index 00000000..bb73928f --- /dev/null +++ b/libc/nt/user32/EnumDisplaySettingsExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumDisplaySettingsExA,EnumDisplaySettingsExA,1764 diff --git a/libc/nt/user32/EnumDisplaySettingsExW.s b/libc/nt/user32/EnumDisplaySettingsExW.s new file mode 100644 index 00000000..1b8d0ee0 --- /dev/null +++ b/libc/nt/user32/EnumDisplaySettingsExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumDisplaySettingsExW,EnumDisplaySettingsExW,1765 diff --git a/libc/nt/user32/EnumDisplaySettingsW.s b/libc/nt/user32/EnumDisplaySettingsW.s new file mode 100644 index 00000000..f5d4178e --- /dev/null +++ b/libc/nt/user32/EnumDisplaySettingsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumDisplaySettingsW,EnumDisplaySettingsW,1766 diff --git a/libc/nt/user32/EnumPropsA.s b/libc/nt/user32/EnumPropsA.s new file mode 100644 index 00000000..0996a54f --- /dev/null +++ b/libc/nt/user32/EnumPropsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumPropsA,EnumPropsA,1767 diff --git a/libc/nt/user32/EnumPropsExA.s b/libc/nt/user32/EnumPropsExA.s new file mode 100644 index 00000000..4aae02d2 --- /dev/null +++ b/libc/nt/user32/EnumPropsExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumPropsExA,EnumPropsExA,1768 diff --git a/libc/nt/user32/EnumPropsExW.s b/libc/nt/user32/EnumPropsExW.s new file mode 100644 index 00000000..ad5a96b1 --- /dev/null +++ b/libc/nt/user32/EnumPropsExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumPropsExW,EnumPropsExW,1769 diff --git a/libc/nt/user32/EnumPropsW.s b/libc/nt/user32/EnumPropsW.s new file mode 100644 index 00000000..ded7efd7 --- /dev/null +++ b/libc/nt/user32/EnumPropsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumPropsW,EnumPropsW,1770 diff --git a/libc/nt/user32/EnumThreadWindows.s b/libc/nt/user32/EnumThreadWindows.s new file mode 100644 index 00000000..fdfb6203 --- /dev/null +++ b/libc/nt/user32/EnumThreadWindows.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumThreadWindows,EnumThreadWindows,1771 diff --git a/libc/nt/user32/EnumWindowStationsA.s b/libc/nt/user32/EnumWindowStationsA.s new file mode 100644 index 00000000..3a87274f --- /dev/null +++ b/libc/nt/user32/EnumWindowStationsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumWindowStationsA,EnumWindowStationsA,1772 diff --git a/libc/nt/user32/EnumWindowStationsW.s b/libc/nt/user32/EnumWindowStationsW.s new file mode 100644 index 00000000..b851ec9a --- /dev/null +++ b/libc/nt/user32/EnumWindowStationsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumWindowStationsW,EnumWindowStationsW,1773 diff --git a/libc/nt/user32/EnumWindows.s b/libc/nt/user32/EnumWindows.s new file mode 100644 index 00000000..dd91563d --- /dev/null +++ b/libc/nt/user32/EnumWindows.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EnumWindows,EnumWindows,1774 diff --git a/libc/nt/user32/EqualRect.s b/libc/nt/user32/EqualRect.s new file mode 100644 index 00000000..8352a442 --- /dev/null +++ b/libc/nt/user32/EqualRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EqualRect,EqualRect,1775 diff --git a/libc/nt/user32/EvaluateProximityToPolygon.s b/libc/nt/user32/EvaluateProximityToPolygon.s new file mode 100644 index 00000000..94bc8c88 --- /dev/null +++ b/libc/nt/user32/EvaluateProximityToPolygon.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EvaluateProximityToPolygon,EvaluateProximityToPolygon,1776 diff --git a/libc/nt/user32/EvaluateProximityToRect.s b/libc/nt/user32/EvaluateProximityToRect.s new file mode 100644 index 00000000..108fb0ac --- /dev/null +++ b/libc/nt/user32/EvaluateProximityToRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_EvaluateProximityToRect,EvaluateProximityToRect,1777 diff --git a/libc/nt/user32/ExcludeUpdateRgn.s b/libc/nt/user32/ExcludeUpdateRgn.s new file mode 100644 index 00000000..4608d341 --- /dev/null +++ b/libc/nt/user32/ExcludeUpdateRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ExcludeUpdateRgn,ExcludeUpdateRgn,1778 diff --git a/libc/nt/user32/ExitWindowsEx.s b/libc/nt/user32/ExitWindowsEx.s new file mode 100644 index 00000000..baa9f6c7 --- /dev/null +++ b/libc/nt/user32/ExitWindowsEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ExitWindowsEx,ExitWindowsEx,1779 diff --git a/libc/nt/user32/FillRect.s b/libc/nt/user32/FillRect.s new file mode 100644 index 00000000..d1a4886a --- /dev/null +++ b/libc/nt/user32/FillRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_FillRect,FillRect,1780 diff --git a/libc/nt/user32/FindWindowA.s b/libc/nt/user32/FindWindowA.s new file mode 100644 index 00000000..982cd56a --- /dev/null +++ b/libc/nt/user32/FindWindowA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_FindWindowA,FindWindowA,1781 + + .text.windows +FindWindowA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FindWindowA(%rip),%rax + jmp __sysv2nt + .endfn FindWindowA,globl + .previous diff --git a/libc/nt/user32/FindWindowExA.s b/libc/nt/user32/FindWindowExA.s new file mode 100644 index 00000000..ae2a6e7b --- /dev/null +++ b/libc/nt/user32/FindWindowExA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_FindWindowExA,FindWindowExA,1782 + + .text.windows +FindWindowExA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FindWindowExA(%rip),%rax + jmp __sysv2nt + .endfn FindWindowExA,globl + .previous diff --git a/libc/nt/user32/FindWindowExW.s b/libc/nt/user32/FindWindowExW.s new file mode 100644 index 00000000..e6a28047 --- /dev/null +++ b/libc/nt/user32/FindWindowExW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_FindWindowExW,FindWindowExW,1783 + + .text.windows +FindWindowEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FindWindowExW(%rip),%rax + jmp __sysv2nt + .endfn FindWindowEx,globl + .previous diff --git a/libc/nt/user32/FindWindowW.s b/libc/nt/user32/FindWindowW.s new file mode 100644 index 00000000..09e8d6d6 --- /dev/null +++ b/libc/nt/user32/FindWindowW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_FindWindowW,FindWindowW,1784 + + .text.windows +FindWindow: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FindWindowW(%rip),%rax + jmp __sysv2nt + .endfn FindWindow,globl + .previous diff --git a/libc/nt/user32/FlashWindow.s b/libc/nt/user32/FlashWindow.s new file mode 100644 index 00000000..3f103b66 --- /dev/null +++ b/libc/nt/user32/FlashWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_FlashWindow,FlashWindow,1785 diff --git a/libc/nt/user32/FlashWindowEx.s b/libc/nt/user32/FlashWindowEx.s new file mode 100644 index 00000000..c015bd47 --- /dev/null +++ b/libc/nt/user32/FlashWindowEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_FlashWindowEx,FlashWindowEx,1786 diff --git a/libc/nt/user32/FrameRect.s b/libc/nt/user32/FrameRect.s new file mode 100644 index 00000000..47059ade --- /dev/null +++ b/libc/nt/user32/FrameRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_FrameRect,FrameRect,1787 diff --git a/libc/nt/user32/FreeDDElParam.s b/libc/nt/user32/FreeDDElParam.s new file mode 100644 index 00000000..8c801057 --- /dev/null +++ b/libc/nt/user32/FreeDDElParam.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_FreeDDElParam,FreeDDElParam,1788 diff --git a/libc/nt/user32/FrostCrashedWindow.s b/libc/nt/user32/FrostCrashedWindow.s new file mode 100644 index 00000000..04c3692a --- /dev/null +++ b/libc/nt/user32/FrostCrashedWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_FrostCrashedWindow,FrostCrashedWindow,1789 diff --git a/libc/nt/user32/GetActiveWindow.s b/libc/nt/user32/GetActiveWindow.s new file mode 100644 index 00000000..96317959 --- /dev/null +++ b/libc/nt/user32/GetActiveWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetActiveWindow,GetActiveWindow,1790 diff --git a/libc/nt/user32/GetAltTabInfoA.s b/libc/nt/user32/GetAltTabInfoA.s new file mode 100644 index 00000000..0d6897d1 --- /dev/null +++ b/libc/nt/user32/GetAltTabInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetAltTabInfoA,GetAltTabInfoA,1792 diff --git a/libc/nt/user32/GetAltTabInfoW.s b/libc/nt/user32/GetAltTabInfoW.s new file mode 100644 index 00000000..3fe042c6 --- /dev/null +++ b/libc/nt/user32/GetAltTabInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetAltTabInfoW,GetAltTabInfoW,1793 diff --git a/libc/nt/user32/GetAncestor.s b/libc/nt/user32/GetAncestor.s new file mode 100644 index 00000000..b788e16a --- /dev/null +++ b/libc/nt/user32/GetAncestor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetAncestor,GetAncestor,1794 diff --git a/libc/nt/user32/GetAppCompatFlags.s b/libc/nt/user32/GetAppCompatFlags.s new file mode 100644 index 00000000..3184a884 --- /dev/null +++ b/libc/nt/user32/GetAppCompatFlags.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetAppCompatFlags,GetAppCompatFlags,1795 diff --git a/libc/nt/user32/GetAppCompatFlags2.s b/libc/nt/user32/GetAppCompatFlags2.s new file mode 100644 index 00000000..028b7987 --- /dev/null +++ b/libc/nt/user32/GetAppCompatFlags2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetAppCompatFlags2,GetAppCompatFlags2,1796 diff --git a/libc/nt/user32/GetAsyncKeyState.s b/libc/nt/user32/GetAsyncKeyState.s new file mode 100644 index 00000000..f6bbe8df --- /dev/null +++ b/libc/nt/user32/GetAsyncKeyState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetAsyncKeyState,GetAsyncKeyState,1797 diff --git a/libc/nt/user32/GetAutoRotationState.s b/libc/nt/user32/GetAutoRotationState.s new file mode 100644 index 00000000..61ce04b6 --- /dev/null +++ b/libc/nt/user32/GetAutoRotationState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetAutoRotationState,GetAutoRotationState,1798 diff --git a/libc/nt/user32/GetAwarenessFromDpiAwarenessContext.s b/libc/nt/user32/GetAwarenessFromDpiAwarenessContext.s new file mode 100644 index 00000000..95966198 --- /dev/null +++ b/libc/nt/user32/GetAwarenessFromDpiAwarenessContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetAwarenessFromDpiAwarenessContext,GetAwarenessFromDpiAwarenessContext,1799 diff --git a/libc/nt/user32/GetCIMSSM.s b/libc/nt/user32/GetCIMSSM.s new file mode 100644 index 00000000..6bb137d9 --- /dev/null +++ b/libc/nt/user32/GetCIMSSM.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetCIMSSM,GetCIMSSM,1800 diff --git a/libc/nt/user32/GetCapture.s b/libc/nt/user32/GetCapture.s new file mode 100644 index 00000000..641e3ab9 --- /dev/null +++ b/libc/nt/user32/GetCapture.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetCapture,GetCapture,1801 diff --git a/libc/nt/user32/GetCaretBlinkTime.s b/libc/nt/user32/GetCaretBlinkTime.s new file mode 100644 index 00000000..d5bb22cd --- /dev/null +++ b/libc/nt/user32/GetCaretBlinkTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetCaretBlinkTime,GetCaretBlinkTime,1802 diff --git a/libc/nt/user32/GetCaretPos.s b/libc/nt/user32/GetCaretPos.s new file mode 100644 index 00000000..ba2ce400 --- /dev/null +++ b/libc/nt/user32/GetCaretPos.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetCaretPos,GetCaretPos,1803 diff --git a/libc/nt/user32/GetClassInfoA.s b/libc/nt/user32/GetClassInfoA.s new file mode 100644 index 00000000..c86e4254 --- /dev/null +++ b/libc/nt/user32/GetClassInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClassInfoA,GetClassInfoA,1804 diff --git a/libc/nt/user32/GetClassInfoExA.s b/libc/nt/user32/GetClassInfoExA.s new file mode 100644 index 00000000..095c4348 --- /dev/null +++ b/libc/nt/user32/GetClassInfoExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClassInfoExA,GetClassInfoExA,1805 diff --git a/libc/nt/user32/GetClassInfoExW.s b/libc/nt/user32/GetClassInfoExW.s new file mode 100644 index 00000000..eb0e10da --- /dev/null +++ b/libc/nt/user32/GetClassInfoExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClassInfoExW,GetClassInfoExW,1806 diff --git a/libc/nt/user32/GetClassInfoW.s b/libc/nt/user32/GetClassInfoW.s new file mode 100644 index 00000000..b29751c5 --- /dev/null +++ b/libc/nt/user32/GetClassInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClassInfoW,GetClassInfoW,1807 diff --git a/libc/nt/user32/GetClassLongA.s b/libc/nt/user32/GetClassLongA.s new file mode 100644 index 00000000..25b41e6d --- /dev/null +++ b/libc/nt/user32/GetClassLongA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClassLongA,GetClassLongA,1808 diff --git a/libc/nt/user32/GetClassLongPtrA.s b/libc/nt/user32/GetClassLongPtrA.s new file mode 100644 index 00000000..f41e1fba --- /dev/null +++ b/libc/nt/user32/GetClassLongPtrA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClassLongPtrA,GetClassLongPtrA,1809 diff --git a/libc/nt/user32/GetClassLongPtrW.s b/libc/nt/user32/GetClassLongPtrW.s new file mode 100644 index 00000000..e2581e0c --- /dev/null +++ b/libc/nt/user32/GetClassLongPtrW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClassLongPtrW,GetClassLongPtrW,1810 diff --git a/libc/nt/user32/GetClassLongW.s b/libc/nt/user32/GetClassLongW.s new file mode 100644 index 00000000..f995490e --- /dev/null +++ b/libc/nt/user32/GetClassLongW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClassLongW,GetClassLongW,1811 diff --git a/libc/nt/user32/GetClassNameA.s b/libc/nt/user32/GetClassNameA.s new file mode 100644 index 00000000..943fc0b2 --- /dev/null +++ b/libc/nt/user32/GetClassNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClassNameA,GetClassNameA,1812 diff --git a/libc/nt/user32/GetClassNameW.s b/libc/nt/user32/GetClassNameW.s new file mode 100644 index 00000000..cc6c008e --- /dev/null +++ b/libc/nt/user32/GetClassNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClassNameW,GetClassNameW,1813 diff --git a/libc/nt/user32/GetClassWord.s b/libc/nt/user32/GetClassWord.s new file mode 100644 index 00000000..4aacdf08 --- /dev/null +++ b/libc/nt/user32/GetClassWord.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClassWord,GetClassWord,1814 diff --git a/libc/nt/user32/GetClientRect.s b/libc/nt/user32/GetClientRect.s new file mode 100644 index 00000000..9de29a48 --- /dev/null +++ b/libc/nt/user32/GetClientRect.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClientRect,GetClientRect,1815 + + .text.windows +GetClientRect: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetClientRect(%rip),%rax + jmp __sysv2nt + .endfn GetClientRect,globl + .previous diff --git a/libc/nt/user32/GetClipCursor.s b/libc/nt/user32/GetClipCursor.s new file mode 100644 index 00000000..ee393984 --- /dev/null +++ b/libc/nt/user32/GetClipCursor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClipCursor,GetClipCursor,1816 diff --git a/libc/nt/user32/GetClipboardAccessToken.s b/libc/nt/user32/GetClipboardAccessToken.s new file mode 100644 index 00000000..6cf4186d --- /dev/null +++ b/libc/nt/user32/GetClipboardAccessToken.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClipboardAccessToken,GetClipboardAccessToken,1817 diff --git a/libc/nt/user32/GetClipboardData.s b/libc/nt/user32/GetClipboardData.s new file mode 100644 index 00000000..31aa5e18 --- /dev/null +++ b/libc/nt/user32/GetClipboardData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClipboardData,GetClipboardData,1818 diff --git a/libc/nt/user32/GetClipboardFormatNameA.s b/libc/nt/user32/GetClipboardFormatNameA.s new file mode 100644 index 00000000..7689d217 --- /dev/null +++ b/libc/nt/user32/GetClipboardFormatNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClipboardFormatNameA,GetClipboardFormatNameA,1819 diff --git a/libc/nt/user32/GetClipboardFormatNameW.s b/libc/nt/user32/GetClipboardFormatNameW.s new file mode 100644 index 00000000..3bec0899 --- /dev/null +++ b/libc/nt/user32/GetClipboardFormatNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClipboardFormatNameW,GetClipboardFormatNameW,1820 diff --git a/libc/nt/user32/GetClipboardOwner.s b/libc/nt/user32/GetClipboardOwner.s new file mode 100644 index 00000000..c2fee27c --- /dev/null +++ b/libc/nt/user32/GetClipboardOwner.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClipboardOwner,GetClipboardOwner,1821 diff --git a/libc/nt/user32/GetClipboardSequenceNumber.s b/libc/nt/user32/GetClipboardSequenceNumber.s new file mode 100644 index 00000000..5eb25ad8 --- /dev/null +++ b/libc/nt/user32/GetClipboardSequenceNumber.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClipboardSequenceNumber,GetClipboardSequenceNumber,1822 diff --git a/libc/nt/user32/GetClipboardViewer.s b/libc/nt/user32/GetClipboardViewer.s new file mode 100644 index 00000000..023d9451 --- /dev/null +++ b/libc/nt/user32/GetClipboardViewer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetClipboardViewer,GetClipboardViewer,1823 diff --git a/libc/nt/user32/GetComboBoxInfo.s b/libc/nt/user32/GetComboBoxInfo.s new file mode 100644 index 00000000..4286c190 --- /dev/null +++ b/libc/nt/user32/GetComboBoxInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetComboBoxInfo,GetComboBoxInfo,1824 diff --git a/libc/nt/user32/GetCurrentInputMessageSource.s b/libc/nt/user32/GetCurrentInputMessageSource.s new file mode 100644 index 00000000..35886d71 --- /dev/null +++ b/libc/nt/user32/GetCurrentInputMessageSource.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetCurrentInputMessageSource,GetCurrentInputMessageSource,1825 diff --git a/libc/nt/user32/GetCursor.s b/libc/nt/user32/GetCursor.s new file mode 100644 index 00000000..d6cd5972 --- /dev/null +++ b/libc/nt/user32/GetCursor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetCursor,GetCursor,1826 diff --git a/libc/nt/user32/GetCursorFrameInfo.s b/libc/nt/user32/GetCursorFrameInfo.s new file mode 100644 index 00000000..20b47509 --- /dev/null +++ b/libc/nt/user32/GetCursorFrameInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetCursorFrameInfo,GetCursorFrameInfo,1827 diff --git a/libc/nt/user32/GetCursorInfo.s b/libc/nt/user32/GetCursorInfo.s new file mode 100644 index 00000000..2f936933 --- /dev/null +++ b/libc/nt/user32/GetCursorInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetCursorInfo,GetCursorInfo,1828 diff --git a/libc/nt/user32/GetCursorPos.s b/libc/nt/user32/GetCursorPos.s new file mode 100644 index 00000000..f5eef493 --- /dev/null +++ b/libc/nt/user32/GetCursorPos.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetCursorPos,GetCursorPos,1829 + + .text.windows +GetCursorPos: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetCursorPos(%rip) + leave + ret + .endfn GetCursorPos,globl + .previous diff --git a/libc/nt/user32/GetDC.s b/libc/nt/user32/GetDC.s new file mode 100644 index 00000000..3343e456 --- /dev/null +++ b/libc/nt/user32/GetDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDC,GetDC,1830 diff --git a/libc/nt/user32/GetDCEx.s b/libc/nt/user32/GetDCEx.s new file mode 100644 index 00000000..27654718 --- /dev/null +++ b/libc/nt/user32/GetDCEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDCEx,GetDCEx,1831 diff --git a/libc/nt/user32/GetDesktopID.s b/libc/nt/user32/GetDesktopID.s new file mode 100644 index 00000000..c2624e4d --- /dev/null +++ b/libc/nt/user32/GetDesktopID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDesktopID,GetDesktopID,1832 diff --git a/libc/nt/user32/GetDesktopWindow.s b/libc/nt/user32/GetDesktopWindow.s new file mode 100644 index 00000000..49e14dca --- /dev/null +++ b/libc/nt/user32/GetDesktopWindow.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDesktopWindow,GetDesktopWindow,1833 + + .text.windows +GetDesktopWindow: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_GetDesktopWindow(%rip) + leave + ret + .endfn GetDesktopWindow,globl + .previous diff --git a/libc/nt/user32/GetDialogBaseUnits.s b/libc/nt/user32/GetDialogBaseUnits.s new file mode 100644 index 00000000..7adac204 --- /dev/null +++ b/libc/nt/user32/GetDialogBaseUnits.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDialogBaseUnits,GetDialogBaseUnits,1834 diff --git a/libc/nt/user32/GetDialogControlDpiChangeBehavior.s b/libc/nt/user32/GetDialogControlDpiChangeBehavior.s new file mode 100644 index 00000000..42db7a4f --- /dev/null +++ b/libc/nt/user32/GetDialogControlDpiChangeBehavior.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDialogControlDpiChangeBehavior,GetDialogControlDpiChangeBehavior,1835 diff --git a/libc/nt/user32/GetDialogDpiChangeBehavior.s b/libc/nt/user32/GetDialogDpiChangeBehavior.s new file mode 100644 index 00000000..e1da4d26 --- /dev/null +++ b/libc/nt/user32/GetDialogDpiChangeBehavior.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDialogDpiChangeBehavior,GetDialogDpiChangeBehavior,1836 diff --git a/libc/nt/user32/GetDisplayAutoRotationPreferences.s b/libc/nt/user32/GetDisplayAutoRotationPreferences.s new file mode 100644 index 00000000..8f4b0f54 --- /dev/null +++ b/libc/nt/user32/GetDisplayAutoRotationPreferences.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDisplayAutoRotationPreferences,GetDisplayAutoRotationPreferences,1837 diff --git a/libc/nt/user32/GetDisplayConfigBufferSizes.s b/libc/nt/user32/GetDisplayConfigBufferSizes.s new file mode 100644 index 00000000..6bc6b703 --- /dev/null +++ b/libc/nt/user32/GetDisplayConfigBufferSizes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDisplayConfigBufferSizes,GetDisplayConfigBufferSizes,1838 diff --git a/libc/nt/user32/GetDlgCtrlID.s b/libc/nt/user32/GetDlgCtrlID.s new file mode 100644 index 00000000..a78eac07 --- /dev/null +++ b/libc/nt/user32/GetDlgCtrlID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDlgCtrlID,GetDlgCtrlID,1839 diff --git a/libc/nt/user32/GetDlgItem.s b/libc/nt/user32/GetDlgItem.s new file mode 100644 index 00000000..21891d2b --- /dev/null +++ b/libc/nt/user32/GetDlgItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDlgItem,GetDlgItem,1840 diff --git a/libc/nt/user32/GetDlgItemInt.s b/libc/nt/user32/GetDlgItemInt.s new file mode 100644 index 00000000..53b62ce1 --- /dev/null +++ b/libc/nt/user32/GetDlgItemInt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDlgItemInt,GetDlgItemInt,1841 diff --git a/libc/nt/user32/GetDlgItemTextA.s b/libc/nt/user32/GetDlgItemTextA.s new file mode 100644 index 00000000..3f855f89 --- /dev/null +++ b/libc/nt/user32/GetDlgItemTextA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDlgItemTextA,GetDlgItemTextA,1842 diff --git a/libc/nt/user32/GetDlgItemTextW.s b/libc/nt/user32/GetDlgItemTextW.s new file mode 100644 index 00000000..8455e5d2 --- /dev/null +++ b/libc/nt/user32/GetDlgItemTextW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDlgItemTextW,GetDlgItemTextW,1843 diff --git a/libc/nt/user32/GetDoubleClickTime.s b/libc/nt/user32/GetDoubleClickTime.s new file mode 100644 index 00000000..6c50c2b4 --- /dev/null +++ b/libc/nt/user32/GetDoubleClickTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDoubleClickTime,GetDoubleClickTime,1844 diff --git a/libc/nt/user32/GetDpiForMonitorInternal.s b/libc/nt/user32/GetDpiForMonitorInternal.s new file mode 100644 index 00000000..6cd0a755 --- /dev/null +++ b/libc/nt/user32/GetDpiForMonitorInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDpiForMonitorInternal,GetDpiForMonitorInternal,1845 diff --git a/libc/nt/user32/GetDpiForSystem.s b/libc/nt/user32/GetDpiForSystem.s new file mode 100644 index 00000000..d7353693 --- /dev/null +++ b/libc/nt/user32/GetDpiForSystem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDpiForSystem,GetDpiForSystem,1846 diff --git a/libc/nt/user32/GetDpiForWindow.s b/libc/nt/user32/GetDpiForWindow.s new file mode 100644 index 00000000..fca4be88 --- /dev/null +++ b/libc/nt/user32/GetDpiForWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDpiForWindow,GetDpiForWindow,1847 diff --git a/libc/nt/user32/GetDpiFromDpiAwarenessContext.s b/libc/nt/user32/GetDpiFromDpiAwarenessContext.s new file mode 100644 index 00000000..c972d6b7 --- /dev/null +++ b/libc/nt/user32/GetDpiFromDpiAwarenessContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetDpiFromDpiAwarenessContext,GetDpiFromDpiAwarenessContext,1848 diff --git a/libc/nt/user32/GetFocus.s b/libc/nt/user32/GetFocus.s new file mode 100644 index 00000000..8ef9d809 --- /dev/null +++ b/libc/nt/user32/GetFocus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetFocus,GetFocus,1849 diff --git a/libc/nt/user32/GetForegroundWindow.s b/libc/nt/user32/GetForegroundWindow.s new file mode 100644 index 00000000..99e7d881 --- /dev/null +++ b/libc/nt/user32/GetForegroundWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetForegroundWindow,GetForegroundWindow,1850 diff --git a/libc/nt/user32/GetGUIThreadInfo.s b/libc/nt/user32/GetGUIThreadInfo.s new file mode 100644 index 00000000..74900033 --- /dev/null +++ b/libc/nt/user32/GetGUIThreadInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetGUIThreadInfo,GetGUIThreadInfo,1851 diff --git a/libc/nt/user32/GetGestureConfig.s b/libc/nt/user32/GetGestureConfig.s new file mode 100644 index 00000000..f48ac7d5 --- /dev/null +++ b/libc/nt/user32/GetGestureConfig.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetGestureConfig,GetGestureConfig,1852 diff --git a/libc/nt/user32/GetGestureExtraArgs.s b/libc/nt/user32/GetGestureExtraArgs.s new file mode 100644 index 00000000..07bbc580 --- /dev/null +++ b/libc/nt/user32/GetGestureExtraArgs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetGestureExtraArgs,GetGestureExtraArgs,1853 diff --git a/libc/nt/user32/GetGestureInfo.s b/libc/nt/user32/GetGestureInfo.s new file mode 100644 index 00000000..dc666379 --- /dev/null +++ b/libc/nt/user32/GetGestureInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetGestureInfo,GetGestureInfo,1854 diff --git a/libc/nt/user32/GetGuiResources.s b/libc/nt/user32/GetGuiResources.s new file mode 100644 index 00000000..2f80c1b2 --- /dev/null +++ b/libc/nt/user32/GetGuiResources.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetGuiResources,GetGuiResources,1855 diff --git a/libc/nt/user32/GetIconInfo.s b/libc/nt/user32/GetIconInfo.s new file mode 100644 index 00000000..aec09d0e --- /dev/null +++ b/libc/nt/user32/GetIconInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetIconInfo,GetIconInfo,1856 diff --git a/libc/nt/user32/GetIconInfoExA.s b/libc/nt/user32/GetIconInfoExA.s new file mode 100644 index 00000000..ded0bdf0 --- /dev/null +++ b/libc/nt/user32/GetIconInfoExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetIconInfoExA,GetIconInfoExA,1857 diff --git a/libc/nt/user32/GetIconInfoExW.s b/libc/nt/user32/GetIconInfoExW.s new file mode 100644 index 00000000..2bf8dfa6 --- /dev/null +++ b/libc/nt/user32/GetIconInfoExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetIconInfoExW,GetIconInfoExW,1858 diff --git a/libc/nt/user32/GetInputDesktop.s b/libc/nt/user32/GetInputDesktop.s new file mode 100644 index 00000000..8b2fd270 --- /dev/null +++ b/libc/nt/user32/GetInputDesktop.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetInputDesktop,GetInputDesktop,1859 diff --git a/libc/nt/user32/GetInputLocaleInfo.s b/libc/nt/user32/GetInputLocaleInfo.s new file mode 100644 index 00000000..518f6d5a --- /dev/null +++ b/libc/nt/user32/GetInputLocaleInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetInputLocaleInfo,GetInputLocaleInfo,1860 diff --git a/libc/nt/user32/GetInputState.s b/libc/nt/user32/GetInputState.s new file mode 100644 index 00000000..21ab5518 --- /dev/null +++ b/libc/nt/user32/GetInputState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetInputState,GetInputState,1861 diff --git a/libc/nt/user32/GetInternalWindowPos.s b/libc/nt/user32/GetInternalWindowPos.s new file mode 100644 index 00000000..0e5928b8 --- /dev/null +++ b/libc/nt/user32/GetInternalWindowPos.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetInternalWindowPos,GetInternalWindowPos,1862 diff --git a/libc/nt/user32/GetKBCodePage.s b/libc/nt/user32/GetKBCodePage.s new file mode 100644 index 00000000..c37d82a5 --- /dev/null +++ b/libc/nt/user32/GetKBCodePage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetKBCodePage,GetKBCodePage,1863 diff --git a/libc/nt/user32/GetKeyNameTextA.s b/libc/nt/user32/GetKeyNameTextA.s new file mode 100644 index 00000000..5956b01a --- /dev/null +++ b/libc/nt/user32/GetKeyNameTextA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetKeyNameTextA,GetKeyNameTextA,1864 diff --git a/libc/nt/user32/GetKeyNameTextW.s b/libc/nt/user32/GetKeyNameTextW.s new file mode 100644 index 00000000..dc50b2a7 --- /dev/null +++ b/libc/nt/user32/GetKeyNameTextW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetKeyNameTextW,GetKeyNameTextW,1865 diff --git a/libc/nt/user32/GetKeyState.s b/libc/nt/user32/GetKeyState.s new file mode 100644 index 00000000..e230a818 --- /dev/null +++ b/libc/nt/user32/GetKeyState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetKeyState,GetKeyState,1866 diff --git a/libc/nt/user32/GetKeyboardLayout.s b/libc/nt/user32/GetKeyboardLayout.s new file mode 100644 index 00000000..a1d4ff60 --- /dev/null +++ b/libc/nt/user32/GetKeyboardLayout.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetKeyboardLayout,GetKeyboardLayout,1867 diff --git a/libc/nt/user32/GetKeyboardLayoutList.s b/libc/nt/user32/GetKeyboardLayoutList.s new file mode 100644 index 00000000..0328e4d3 --- /dev/null +++ b/libc/nt/user32/GetKeyboardLayoutList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetKeyboardLayoutList,GetKeyboardLayoutList,1868 diff --git a/libc/nt/user32/GetKeyboardLayoutNameA.s b/libc/nt/user32/GetKeyboardLayoutNameA.s new file mode 100644 index 00000000..1b35ac95 --- /dev/null +++ b/libc/nt/user32/GetKeyboardLayoutNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetKeyboardLayoutNameA,GetKeyboardLayoutNameA,1869 diff --git a/libc/nt/user32/GetKeyboardLayoutNameW.s b/libc/nt/user32/GetKeyboardLayoutNameW.s new file mode 100644 index 00000000..061d72b4 --- /dev/null +++ b/libc/nt/user32/GetKeyboardLayoutNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetKeyboardLayoutNameW,GetKeyboardLayoutNameW,1870 diff --git a/libc/nt/user32/GetKeyboardState.s b/libc/nt/user32/GetKeyboardState.s new file mode 100644 index 00000000..3ccfdd67 --- /dev/null +++ b/libc/nt/user32/GetKeyboardState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetKeyboardState,GetKeyboardState,1871 diff --git a/libc/nt/user32/GetKeyboardType.s b/libc/nt/user32/GetKeyboardType.s new file mode 100644 index 00000000..0bd6d411 --- /dev/null +++ b/libc/nt/user32/GetKeyboardType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetKeyboardType,GetKeyboardType,1872 diff --git a/libc/nt/user32/GetLastActivePopup.s b/libc/nt/user32/GetLastActivePopup.s new file mode 100644 index 00000000..e833ab09 --- /dev/null +++ b/libc/nt/user32/GetLastActivePopup.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetLastActivePopup,GetLastActivePopup,1873 diff --git a/libc/nt/user32/GetLastInputInfo.s b/libc/nt/user32/GetLastInputInfo.s new file mode 100644 index 00000000..b19492e2 --- /dev/null +++ b/libc/nt/user32/GetLastInputInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetLastInputInfo,GetLastInputInfo,1874 diff --git a/libc/nt/user32/GetLayeredWindowAttributes.s b/libc/nt/user32/GetLayeredWindowAttributes.s new file mode 100644 index 00000000..2ea1b6df --- /dev/null +++ b/libc/nt/user32/GetLayeredWindowAttributes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetLayeredWindowAttributes,GetLayeredWindowAttributes,1875 diff --git a/libc/nt/user32/GetListBoxInfo.s b/libc/nt/user32/GetListBoxInfo.s new file mode 100644 index 00000000..1aad0292 --- /dev/null +++ b/libc/nt/user32/GetListBoxInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetListBoxInfo,GetListBoxInfo,1876 diff --git a/libc/nt/user32/GetMagnificationDesktopColorEffect.s b/libc/nt/user32/GetMagnificationDesktopColorEffect.s new file mode 100644 index 00000000..300d5bcc --- /dev/null +++ b/libc/nt/user32/GetMagnificationDesktopColorEffect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMagnificationDesktopColorEffect,GetMagnificationDesktopColorEffect,1877 diff --git a/libc/nt/user32/GetMagnificationDesktopMagnification.s b/libc/nt/user32/GetMagnificationDesktopMagnification.s new file mode 100644 index 00000000..87885d49 --- /dev/null +++ b/libc/nt/user32/GetMagnificationDesktopMagnification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMagnificationDesktopMagnification,GetMagnificationDesktopMagnification,1878 diff --git a/libc/nt/user32/GetMagnificationDesktopSamplingMode.s b/libc/nt/user32/GetMagnificationDesktopSamplingMode.s new file mode 100644 index 00000000..e234f2f1 --- /dev/null +++ b/libc/nt/user32/GetMagnificationDesktopSamplingMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMagnificationDesktopSamplingMode,GetMagnificationDesktopSamplingMode,1879 diff --git a/libc/nt/user32/GetMagnificationLensCtxInformation.s b/libc/nt/user32/GetMagnificationLensCtxInformation.s new file mode 100644 index 00000000..955f0ed1 --- /dev/null +++ b/libc/nt/user32/GetMagnificationLensCtxInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMagnificationLensCtxInformation,GetMagnificationLensCtxInformation,1880 diff --git a/libc/nt/user32/GetMenu.s b/libc/nt/user32/GetMenu.s new file mode 100644 index 00000000..051db423 --- /dev/null +++ b/libc/nt/user32/GetMenu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMenu,GetMenu,1881 diff --git a/libc/nt/user32/GetMenuBarInfo.s b/libc/nt/user32/GetMenuBarInfo.s new file mode 100644 index 00000000..0ca4f02c --- /dev/null +++ b/libc/nt/user32/GetMenuBarInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMenuBarInfo,GetMenuBarInfo,1882 diff --git a/libc/nt/user32/GetMenuCheckMarkDimensions.s b/libc/nt/user32/GetMenuCheckMarkDimensions.s new file mode 100644 index 00000000..8d079b7b --- /dev/null +++ b/libc/nt/user32/GetMenuCheckMarkDimensions.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMenuCheckMarkDimensions,GetMenuCheckMarkDimensions,1883 diff --git a/libc/nt/user32/GetMenuContextHelpId.s b/libc/nt/user32/GetMenuContextHelpId.s new file mode 100644 index 00000000..0df9d9a4 --- /dev/null +++ b/libc/nt/user32/GetMenuContextHelpId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMenuContextHelpId,GetMenuContextHelpId,1884 diff --git a/libc/nt/user32/GetMenuDefaultItem.s b/libc/nt/user32/GetMenuDefaultItem.s new file mode 100644 index 00000000..01395d7b --- /dev/null +++ b/libc/nt/user32/GetMenuDefaultItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMenuDefaultItem,GetMenuDefaultItem,1885 diff --git a/libc/nt/user32/GetMenuInfo.s b/libc/nt/user32/GetMenuInfo.s new file mode 100644 index 00000000..86e0a7ab --- /dev/null +++ b/libc/nt/user32/GetMenuInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMenuInfo,GetMenuInfo,1886 diff --git a/libc/nt/user32/GetMenuItemCount.s b/libc/nt/user32/GetMenuItemCount.s new file mode 100644 index 00000000..c2f5f9bd --- /dev/null +++ b/libc/nt/user32/GetMenuItemCount.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMenuItemCount,GetMenuItemCount,1887 diff --git a/libc/nt/user32/GetMenuItemID.s b/libc/nt/user32/GetMenuItemID.s new file mode 100644 index 00000000..ce3c6746 --- /dev/null +++ b/libc/nt/user32/GetMenuItemID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMenuItemID,GetMenuItemID,1888 diff --git a/libc/nt/user32/GetMenuItemInfoA.s b/libc/nt/user32/GetMenuItemInfoA.s new file mode 100644 index 00000000..3fe0f2a4 --- /dev/null +++ b/libc/nt/user32/GetMenuItemInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMenuItemInfoA,GetMenuItemInfoA,1889 diff --git a/libc/nt/user32/GetMenuItemInfoW.s b/libc/nt/user32/GetMenuItemInfoW.s new file mode 100644 index 00000000..f2244b8a --- /dev/null +++ b/libc/nt/user32/GetMenuItemInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMenuItemInfoW,GetMenuItemInfoW,1890 diff --git a/libc/nt/user32/GetMenuItemRect.s b/libc/nt/user32/GetMenuItemRect.s new file mode 100644 index 00000000..c5d78f9b --- /dev/null +++ b/libc/nt/user32/GetMenuItemRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMenuItemRect,GetMenuItemRect,1891 diff --git a/libc/nt/user32/GetMenuState.s b/libc/nt/user32/GetMenuState.s new file mode 100644 index 00000000..f190bce9 --- /dev/null +++ b/libc/nt/user32/GetMenuState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMenuState,GetMenuState,1892 diff --git a/libc/nt/user32/GetMenuStringA.s b/libc/nt/user32/GetMenuStringA.s new file mode 100644 index 00000000..1f1148d9 --- /dev/null +++ b/libc/nt/user32/GetMenuStringA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMenuStringA,GetMenuStringA,1893 diff --git a/libc/nt/user32/GetMenuStringW.s b/libc/nt/user32/GetMenuStringW.s new file mode 100644 index 00000000..a9a7b609 --- /dev/null +++ b/libc/nt/user32/GetMenuStringW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMenuStringW,GetMenuStringW,1894 diff --git a/libc/nt/user32/GetMessageA.s b/libc/nt/user32/GetMessageA.s new file mode 100644 index 00000000..cbf3670d --- /dev/null +++ b/libc/nt/user32/GetMessageA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMessageA,GetMessageA,1895 + + .text.windows +GetMessageA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetMessageA(%rip),%rax + jmp __sysv2nt + .endfn GetMessageA,globl + .previous diff --git a/libc/nt/user32/GetMessageExtraInfo.s b/libc/nt/user32/GetMessageExtraInfo.s new file mode 100644 index 00000000..efa1b7a3 --- /dev/null +++ b/libc/nt/user32/GetMessageExtraInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMessageExtraInfo,GetMessageExtraInfo,1896 diff --git a/libc/nt/user32/GetMessagePos.s b/libc/nt/user32/GetMessagePos.s new file mode 100644 index 00000000..9ede3d83 --- /dev/null +++ b/libc/nt/user32/GetMessagePos.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMessagePos,GetMessagePos,1897 diff --git a/libc/nt/user32/GetMessageTime.s b/libc/nt/user32/GetMessageTime.s new file mode 100644 index 00000000..85ab5611 --- /dev/null +++ b/libc/nt/user32/GetMessageTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMessageTime,GetMessageTime,1898 diff --git a/libc/nt/user32/GetMessageW.s b/libc/nt/user32/GetMessageW.s new file mode 100644 index 00000000..394b5c9d --- /dev/null +++ b/libc/nt/user32/GetMessageW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMessageW,GetMessageW,1899 + + .text.windows +GetMessage: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetMessageW(%rip),%rax + jmp __sysv2nt + .endfn GetMessage,globl + .previous diff --git a/libc/nt/user32/GetMonitorInfoA.s b/libc/nt/user32/GetMonitorInfoA.s new file mode 100644 index 00000000..402b47df --- /dev/null +++ b/libc/nt/user32/GetMonitorInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMonitorInfoA,GetMonitorInfoA,1900 diff --git a/libc/nt/user32/GetMonitorInfoW.s b/libc/nt/user32/GetMonitorInfoW.s new file mode 100644 index 00000000..e687155a --- /dev/null +++ b/libc/nt/user32/GetMonitorInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMonitorInfoW,GetMonitorInfoW,1901 diff --git a/libc/nt/user32/GetMouseMovePointsEx.s b/libc/nt/user32/GetMouseMovePointsEx.s new file mode 100644 index 00000000..8d0c3d5e --- /dev/null +++ b/libc/nt/user32/GetMouseMovePointsEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetMouseMovePointsEx,GetMouseMovePointsEx,1902 diff --git a/libc/nt/user32/GetNextDlgGroupItem.s b/libc/nt/user32/GetNextDlgGroupItem.s new file mode 100644 index 00000000..e219258d --- /dev/null +++ b/libc/nt/user32/GetNextDlgGroupItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetNextDlgGroupItem,GetNextDlgGroupItem,1903 diff --git a/libc/nt/user32/GetNextDlgTabItem.s b/libc/nt/user32/GetNextDlgTabItem.s new file mode 100644 index 00000000..27b5e704 --- /dev/null +++ b/libc/nt/user32/GetNextDlgTabItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetNextDlgTabItem,GetNextDlgTabItem,1904 diff --git a/libc/nt/user32/GetOpenClipboardWindow.s b/libc/nt/user32/GetOpenClipboardWindow.s new file mode 100644 index 00000000..ec5fdcea --- /dev/null +++ b/libc/nt/user32/GetOpenClipboardWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetOpenClipboardWindow,GetOpenClipboardWindow,1905 diff --git a/libc/nt/user32/GetParent.s b/libc/nt/user32/GetParent.s new file mode 100644 index 00000000..7adc3772 --- /dev/null +++ b/libc/nt/user32/GetParent.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetParent,GetParent,1906 + + .text.windows +GetParent: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_GetParent(%rip) + leave + ret + .endfn GetParent,globl + .previous diff --git a/libc/nt/user32/GetPhysicalCursorPos.s b/libc/nt/user32/GetPhysicalCursorPos.s new file mode 100644 index 00000000..cdf078cb --- /dev/null +++ b/libc/nt/user32/GetPhysicalCursorPos.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPhysicalCursorPos,GetPhysicalCursorPos,1907 diff --git a/libc/nt/user32/GetPointerCursorId.s b/libc/nt/user32/GetPointerCursorId.s new file mode 100644 index 00000000..9a95b245 --- /dev/null +++ b/libc/nt/user32/GetPointerCursorId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerCursorId,GetPointerCursorId,1908 diff --git a/libc/nt/user32/GetPointerDevice.s b/libc/nt/user32/GetPointerDevice.s new file mode 100644 index 00000000..58378586 --- /dev/null +++ b/libc/nt/user32/GetPointerDevice.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerDevice,GetPointerDevice,1909 diff --git a/libc/nt/user32/GetPointerDeviceCursors.s b/libc/nt/user32/GetPointerDeviceCursors.s new file mode 100644 index 00000000..0479f59a --- /dev/null +++ b/libc/nt/user32/GetPointerDeviceCursors.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerDeviceCursors,GetPointerDeviceCursors,1910 diff --git a/libc/nt/user32/GetPointerDeviceProperties.s b/libc/nt/user32/GetPointerDeviceProperties.s new file mode 100644 index 00000000..731ed4b6 --- /dev/null +++ b/libc/nt/user32/GetPointerDeviceProperties.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerDeviceProperties,GetPointerDeviceProperties,1911 diff --git a/libc/nt/user32/GetPointerDeviceRects.s b/libc/nt/user32/GetPointerDeviceRects.s new file mode 100644 index 00000000..4161aad7 --- /dev/null +++ b/libc/nt/user32/GetPointerDeviceRects.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerDeviceRects,GetPointerDeviceRects,1912 diff --git a/libc/nt/user32/GetPointerDevices.s b/libc/nt/user32/GetPointerDevices.s new file mode 100644 index 00000000..6e4b9cbc --- /dev/null +++ b/libc/nt/user32/GetPointerDevices.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerDevices,GetPointerDevices,1913 diff --git a/libc/nt/user32/GetPointerFrameArrivalTimes.s b/libc/nt/user32/GetPointerFrameArrivalTimes.s new file mode 100644 index 00000000..ca1d2704 --- /dev/null +++ b/libc/nt/user32/GetPointerFrameArrivalTimes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerFrameArrivalTimes,GetPointerFrameArrivalTimes,1914 diff --git a/libc/nt/user32/GetPointerFrameInfo.s b/libc/nt/user32/GetPointerFrameInfo.s new file mode 100644 index 00000000..c05564ce --- /dev/null +++ b/libc/nt/user32/GetPointerFrameInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerFrameInfo,GetPointerFrameInfo,1915 diff --git a/libc/nt/user32/GetPointerFrameInfoHistory.s b/libc/nt/user32/GetPointerFrameInfoHistory.s new file mode 100644 index 00000000..f63463a7 --- /dev/null +++ b/libc/nt/user32/GetPointerFrameInfoHistory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerFrameInfoHistory,GetPointerFrameInfoHistory,1916 diff --git a/libc/nt/user32/GetPointerFramePenInfo.s b/libc/nt/user32/GetPointerFramePenInfo.s new file mode 100644 index 00000000..4b18213d --- /dev/null +++ b/libc/nt/user32/GetPointerFramePenInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerFramePenInfo,GetPointerFramePenInfo,1917 diff --git a/libc/nt/user32/GetPointerFramePenInfoHistory.s b/libc/nt/user32/GetPointerFramePenInfoHistory.s new file mode 100644 index 00000000..1d904e34 --- /dev/null +++ b/libc/nt/user32/GetPointerFramePenInfoHistory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerFramePenInfoHistory,GetPointerFramePenInfoHistory,1918 diff --git a/libc/nt/user32/GetPointerFrameTouchInfo.s b/libc/nt/user32/GetPointerFrameTouchInfo.s new file mode 100644 index 00000000..141472e9 --- /dev/null +++ b/libc/nt/user32/GetPointerFrameTouchInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerFrameTouchInfo,GetPointerFrameTouchInfo,1919 diff --git a/libc/nt/user32/GetPointerFrameTouchInfoHistory.s b/libc/nt/user32/GetPointerFrameTouchInfoHistory.s new file mode 100644 index 00000000..64ebcfd9 --- /dev/null +++ b/libc/nt/user32/GetPointerFrameTouchInfoHistory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerFrameTouchInfoHistory,GetPointerFrameTouchInfoHistory,1920 diff --git a/libc/nt/user32/GetPointerInfo.s b/libc/nt/user32/GetPointerInfo.s new file mode 100644 index 00000000..a7a30e7b --- /dev/null +++ b/libc/nt/user32/GetPointerInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerInfo,GetPointerInfo,1921 diff --git a/libc/nt/user32/GetPointerInfoHistory.s b/libc/nt/user32/GetPointerInfoHistory.s new file mode 100644 index 00000000..18467919 --- /dev/null +++ b/libc/nt/user32/GetPointerInfoHistory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerInfoHistory,GetPointerInfoHistory,1922 diff --git a/libc/nt/user32/GetPointerInputTransform.s b/libc/nt/user32/GetPointerInputTransform.s new file mode 100644 index 00000000..f040d213 --- /dev/null +++ b/libc/nt/user32/GetPointerInputTransform.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerInputTransform,GetPointerInputTransform,1923 diff --git a/libc/nt/user32/GetPointerPenInfo.s b/libc/nt/user32/GetPointerPenInfo.s new file mode 100644 index 00000000..ce0fc61b --- /dev/null +++ b/libc/nt/user32/GetPointerPenInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerPenInfo,GetPointerPenInfo,1924 diff --git a/libc/nt/user32/GetPointerPenInfoHistory.s b/libc/nt/user32/GetPointerPenInfoHistory.s new file mode 100644 index 00000000..59c5c3fc --- /dev/null +++ b/libc/nt/user32/GetPointerPenInfoHistory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerPenInfoHistory,GetPointerPenInfoHistory,1925 diff --git a/libc/nt/user32/GetPointerTouchInfo.s b/libc/nt/user32/GetPointerTouchInfo.s new file mode 100644 index 00000000..bbe0ad2b --- /dev/null +++ b/libc/nt/user32/GetPointerTouchInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerTouchInfo,GetPointerTouchInfo,1926 diff --git a/libc/nt/user32/GetPointerTouchInfoHistory.s b/libc/nt/user32/GetPointerTouchInfoHistory.s new file mode 100644 index 00000000..29feccf3 --- /dev/null +++ b/libc/nt/user32/GetPointerTouchInfoHistory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerTouchInfoHistory,GetPointerTouchInfoHistory,1927 diff --git a/libc/nt/user32/GetPointerType.s b/libc/nt/user32/GetPointerType.s new file mode 100644 index 00000000..b3354c33 --- /dev/null +++ b/libc/nt/user32/GetPointerType.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPointerType,GetPointerType,1928 diff --git a/libc/nt/user32/GetPriorityClipboardFormat.s b/libc/nt/user32/GetPriorityClipboardFormat.s new file mode 100644 index 00000000..af1f4187 --- /dev/null +++ b/libc/nt/user32/GetPriorityClipboardFormat.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPriorityClipboardFormat,GetPriorityClipboardFormat,1929 diff --git a/libc/nt/user32/GetProcessDefaultLayout.s b/libc/nt/user32/GetProcessDefaultLayout.s new file mode 100644 index 00000000..68d31b4c --- /dev/null +++ b/libc/nt/user32/GetProcessDefaultLayout.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetProcessDefaultLayout,GetProcessDefaultLayout,1930 diff --git a/libc/nt/user32/GetProcessDpiAwarenessInternal.s b/libc/nt/user32/GetProcessDpiAwarenessInternal.s new file mode 100644 index 00000000..e3a305ce --- /dev/null +++ b/libc/nt/user32/GetProcessDpiAwarenessInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetProcessDpiAwarenessInternal,GetProcessDpiAwarenessInternal,1931 diff --git a/libc/nt/user32/GetProcessUIContextInformation.s b/libc/nt/user32/GetProcessUIContextInformation.s new file mode 100644 index 00000000..733b5ad8 --- /dev/null +++ b/libc/nt/user32/GetProcessUIContextInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetProcessUIContextInformation,GetProcessUIContextInformation,2521 diff --git a/libc/nt/user32/GetProcessWindowStation.s b/libc/nt/user32/GetProcessWindowStation.s new file mode 100644 index 00000000..c083671e --- /dev/null +++ b/libc/nt/user32/GetProcessWindowStation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetProcessWindowStation,GetProcessWindowStation,1932 diff --git a/libc/nt/user32/GetProgmanWindow.s b/libc/nt/user32/GetProgmanWindow.s new file mode 100644 index 00000000..607218b8 --- /dev/null +++ b/libc/nt/user32/GetProgmanWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetProgmanWindow,GetProgmanWindow,1933 diff --git a/libc/nt/user32/GetPropA.s b/libc/nt/user32/GetPropA.s new file mode 100644 index 00000000..207e1118 --- /dev/null +++ b/libc/nt/user32/GetPropA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPropA,GetPropA,1934 diff --git a/libc/nt/user32/GetPropW.s b/libc/nt/user32/GetPropW.s new file mode 100644 index 00000000..cf93f0a3 --- /dev/null +++ b/libc/nt/user32/GetPropW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetPropW,GetPropW,1935 diff --git a/libc/nt/user32/GetQueueStatus.s b/libc/nt/user32/GetQueueStatus.s new file mode 100644 index 00000000..fc849159 --- /dev/null +++ b/libc/nt/user32/GetQueueStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetQueueStatus,GetQueueStatus,1936 diff --git a/libc/nt/user32/GetRawInputBuffer.s b/libc/nt/user32/GetRawInputBuffer.s new file mode 100644 index 00000000..b2a8092a --- /dev/null +++ b/libc/nt/user32/GetRawInputBuffer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetRawInputBuffer,GetRawInputBuffer,1937 diff --git a/libc/nt/user32/GetRawInputData.s b/libc/nt/user32/GetRawInputData.s new file mode 100644 index 00000000..d36d0d89 --- /dev/null +++ b/libc/nt/user32/GetRawInputData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetRawInputData,GetRawInputData,1938 diff --git a/libc/nt/user32/GetRawInputDeviceInfoA.s b/libc/nt/user32/GetRawInputDeviceInfoA.s new file mode 100644 index 00000000..6e6770e8 --- /dev/null +++ b/libc/nt/user32/GetRawInputDeviceInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetRawInputDeviceInfoA,GetRawInputDeviceInfoA,1939 diff --git a/libc/nt/user32/GetRawInputDeviceInfoW.s b/libc/nt/user32/GetRawInputDeviceInfoW.s new file mode 100644 index 00000000..fc16f341 --- /dev/null +++ b/libc/nt/user32/GetRawInputDeviceInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetRawInputDeviceInfoW,GetRawInputDeviceInfoW,1940 diff --git a/libc/nt/user32/GetRawInputDeviceList.s b/libc/nt/user32/GetRawInputDeviceList.s new file mode 100644 index 00000000..dc7443e4 --- /dev/null +++ b/libc/nt/user32/GetRawInputDeviceList.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetRawInputDeviceList,GetRawInputDeviceList,1941 diff --git a/libc/nt/user32/GetRawPointerDeviceData.s b/libc/nt/user32/GetRawPointerDeviceData.s new file mode 100644 index 00000000..8fc5f3ac --- /dev/null +++ b/libc/nt/user32/GetRawPointerDeviceData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetRawPointerDeviceData,GetRawPointerDeviceData,1942 diff --git a/libc/nt/user32/GetReasonTitleFromReasonCode.s b/libc/nt/user32/GetReasonTitleFromReasonCode.s new file mode 100644 index 00000000..c04e177d --- /dev/null +++ b/libc/nt/user32/GetReasonTitleFromReasonCode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetReasonTitleFromReasonCode,GetReasonTitleFromReasonCode,1943 diff --git a/libc/nt/user32/GetRegisteredRawInputDevices.s b/libc/nt/user32/GetRegisteredRawInputDevices.s new file mode 100644 index 00000000..d968f1d4 --- /dev/null +++ b/libc/nt/user32/GetRegisteredRawInputDevices.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetRegisteredRawInputDevices,GetRegisteredRawInputDevices,1944 diff --git a/libc/nt/user32/GetScrollBarInfo.s b/libc/nt/user32/GetScrollBarInfo.s new file mode 100644 index 00000000..eda200be --- /dev/null +++ b/libc/nt/user32/GetScrollBarInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetScrollBarInfo,GetScrollBarInfo,1945 diff --git a/libc/nt/user32/GetScrollInfo.s b/libc/nt/user32/GetScrollInfo.s new file mode 100644 index 00000000..623a551f --- /dev/null +++ b/libc/nt/user32/GetScrollInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetScrollInfo,GetScrollInfo,1946 diff --git a/libc/nt/user32/GetScrollPos.s b/libc/nt/user32/GetScrollPos.s new file mode 100644 index 00000000..9b687c07 --- /dev/null +++ b/libc/nt/user32/GetScrollPos.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetScrollPos,GetScrollPos,1947 diff --git a/libc/nt/user32/GetScrollRange.s b/libc/nt/user32/GetScrollRange.s new file mode 100644 index 00000000..32b64718 --- /dev/null +++ b/libc/nt/user32/GetScrollRange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetScrollRange,GetScrollRange,1948 diff --git a/libc/nt/user32/GetSendMessageReceiver.s b/libc/nt/user32/GetSendMessageReceiver.s new file mode 100644 index 00000000..f1cfa4e4 --- /dev/null +++ b/libc/nt/user32/GetSendMessageReceiver.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetSendMessageReceiver,GetSendMessageReceiver,1949 diff --git a/libc/nt/user32/GetShellWindow.s b/libc/nt/user32/GetShellWindow.s new file mode 100644 index 00000000..02600b6a --- /dev/null +++ b/libc/nt/user32/GetShellWindow.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetShellWindow,GetShellWindow,1950 + + .text.windows +GetShellWindow: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_GetShellWindow(%rip) + leave + ret + .endfn GetShellWindow,globl + .previous diff --git a/libc/nt/user32/GetSubMenu.s b/libc/nt/user32/GetSubMenu.s new file mode 100644 index 00000000..0a3c1859 --- /dev/null +++ b/libc/nt/user32/GetSubMenu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetSubMenu,GetSubMenu,1951 diff --git a/libc/nt/user32/GetSysColor.s b/libc/nt/user32/GetSysColor.s new file mode 100644 index 00000000..e4500105 --- /dev/null +++ b/libc/nt/user32/GetSysColor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetSysColor,GetSysColor,1952 diff --git a/libc/nt/user32/GetSysColorBrush.s b/libc/nt/user32/GetSysColorBrush.s new file mode 100644 index 00000000..25bc6bf4 --- /dev/null +++ b/libc/nt/user32/GetSysColorBrush.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetSysColorBrush,GetSysColorBrush,1953 diff --git a/libc/nt/user32/GetSystemDpiForProcess.s b/libc/nt/user32/GetSystemDpiForProcess.s new file mode 100644 index 00000000..4740ddc6 --- /dev/null +++ b/libc/nt/user32/GetSystemDpiForProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetSystemDpiForProcess,GetSystemDpiForProcess,1954 diff --git a/libc/nt/user32/GetSystemMenu.s b/libc/nt/user32/GetSystemMenu.s new file mode 100644 index 00000000..20e42ed3 --- /dev/null +++ b/libc/nt/user32/GetSystemMenu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetSystemMenu,GetSystemMenu,1955 diff --git a/libc/nt/user32/GetSystemMetrics.s b/libc/nt/user32/GetSystemMetrics.s new file mode 100644 index 00000000..60a5396d --- /dev/null +++ b/libc/nt/user32/GetSystemMetrics.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetSystemMetrics,GetSystemMetrics,1956 diff --git a/libc/nt/user32/GetSystemMetricsForDpi.s b/libc/nt/user32/GetSystemMetricsForDpi.s new file mode 100644 index 00000000..ecd724fb --- /dev/null +++ b/libc/nt/user32/GetSystemMetricsForDpi.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetSystemMetricsForDpi,GetSystemMetricsForDpi,1957 diff --git a/libc/nt/user32/GetTabbedTextExtentA.s b/libc/nt/user32/GetTabbedTextExtentA.s new file mode 100644 index 00000000..ff42066e --- /dev/null +++ b/libc/nt/user32/GetTabbedTextExtentA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetTabbedTextExtentA,GetTabbedTextExtentA,1958 diff --git a/libc/nt/user32/GetTabbedTextExtentW.s b/libc/nt/user32/GetTabbedTextExtentW.s new file mode 100644 index 00000000..7012f109 --- /dev/null +++ b/libc/nt/user32/GetTabbedTextExtentW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetTabbedTextExtentW,GetTabbedTextExtentW,1959 diff --git a/libc/nt/user32/GetTaskmanWindow.s b/libc/nt/user32/GetTaskmanWindow.s new file mode 100644 index 00000000..8619a0e2 --- /dev/null +++ b/libc/nt/user32/GetTaskmanWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetTaskmanWindow,GetTaskmanWindow,1960 diff --git a/libc/nt/user32/GetThreadDesktop.s b/libc/nt/user32/GetThreadDesktop.s new file mode 100644 index 00000000..75435183 --- /dev/null +++ b/libc/nt/user32/GetThreadDesktop.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetThreadDesktop,GetThreadDesktop,1961 diff --git a/libc/nt/user32/GetThreadDpiAwarenessContext.s b/libc/nt/user32/GetThreadDpiAwarenessContext.s new file mode 100644 index 00000000..b0ed9b7c --- /dev/null +++ b/libc/nt/user32/GetThreadDpiAwarenessContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetThreadDpiAwarenessContext,GetThreadDpiAwarenessContext,1962 diff --git a/libc/nt/user32/GetThreadDpiHostingBehavior.s b/libc/nt/user32/GetThreadDpiHostingBehavior.s new file mode 100644 index 00000000..ed92cd31 --- /dev/null +++ b/libc/nt/user32/GetThreadDpiHostingBehavior.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetThreadDpiHostingBehavior,GetThreadDpiHostingBehavior,1963 diff --git a/libc/nt/user32/GetTitleBarInfo.s b/libc/nt/user32/GetTitleBarInfo.s new file mode 100644 index 00000000..9a62db9a --- /dev/null +++ b/libc/nt/user32/GetTitleBarInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetTitleBarInfo,GetTitleBarInfo,1964 diff --git a/libc/nt/user32/GetTopLevelWindow.s b/libc/nt/user32/GetTopLevelWindow.s new file mode 100644 index 00000000..1932c86f --- /dev/null +++ b/libc/nt/user32/GetTopLevelWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetTopLevelWindow,GetTopLevelWindow,1965 diff --git a/libc/nt/user32/GetTopWindow.s b/libc/nt/user32/GetTopWindow.s new file mode 100644 index 00000000..b8aaf015 --- /dev/null +++ b/libc/nt/user32/GetTopWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetTopWindow,GetTopWindow,1966 diff --git a/libc/nt/user32/GetTouchInputInfo.s b/libc/nt/user32/GetTouchInputInfo.s new file mode 100644 index 00000000..e59a2d42 --- /dev/null +++ b/libc/nt/user32/GetTouchInputInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetTouchInputInfo,GetTouchInputInfo,1967 diff --git a/libc/nt/user32/GetUnpredictedMessagePos.s b/libc/nt/user32/GetUnpredictedMessagePos.s new file mode 100644 index 00000000..b396948e --- /dev/null +++ b/libc/nt/user32/GetUnpredictedMessagePos.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetUnpredictedMessagePos,GetUnpredictedMessagePos,1968 diff --git a/libc/nt/user32/GetUpdateRect.s b/libc/nt/user32/GetUpdateRect.s new file mode 100644 index 00000000..6515d03b --- /dev/null +++ b/libc/nt/user32/GetUpdateRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetUpdateRect,GetUpdateRect,1969 diff --git a/libc/nt/user32/GetUpdateRgn.s b/libc/nt/user32/GetUpdateRgn.s new file mode 100644 index 00000000..b57035c4 --- /dev/null +++ b/libc/nt/user32/GetUpdateRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetUpdateRgn,GetUpdateRgn,1970 diff --git a/libc/nt/user32/GetUpdatedClipboardFormats.s b/libc/nt/user32/GetUpdatedClipboardFormats.s new file mode 100644 index 00000000..b8fa4c1b --- /dev/null +++ b/libc/nt/user32/GetUpdatedClipboardFormats.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetUpdatedClipboardFormats,GetUpdatedClipboardFormats,1971 diff --git a/libc/nt/user32/GetUserObjectInformationA.s b/libc/nt/user32/GetUserObjectInformationA.s new file mode 100644 index 00000000..c448503c --- /dev/null +++ b/libc/nt/user32/GetUserObjectInformationA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetUserObjectInformationA,GetUserObjectInformationA,1972 diff --git a/libc/nt/user32/GetUserObjectInformationW.s b/libc/nt/user32/GetUserObjectInformationW.s new file mode 100644 index 00000000..093adc5c --- /dev/null +++ b/libc/nt/user32/GetUserObjectInformationW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetUserObjectInformationW,GetUserObjectInformationW,1973 diff --git a/libc/nt/user32/GetUserObjectSecurity.s b/libc/nt/user32/GetUserObjectSecurity.s new file mode 100644 index 00000000..7bcadc3f --- /dev/null +++ b/libc/nt/user32/GetUserObjectSecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetUserObjectSecurity,GetUserObjectSecurity,1974 diff --git a/libc/nt/user32/GetWinStationInfo.s b/libc/nt/user32/GetWinStationInfo.s new file mode 100644 index 00000000..ac36fe0d --- /dev/null +++ b/libc/nt/user32/GetWinStationInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWinStationInfo,GetWinStationInfo,1975 diff --git a/libc/nt/user32/GetWindow.s b/libc/nt/user32/GetWindow.s new file mode 100644 index 00000000..e1ad9693 --- /dev/null +++ b/libc/nt/user32/GetWindow.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindow,GetWindow,1976 + + .text.windows +GetWindow: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetWindow(%rip),%rax + jmp __sysv2nt + .endfn GetWindow,globl + .previous diff --git a/libc/nt/user32/GetWindowBand.s b/libc/nt/user32/GetWindowBand.s new file mode 100644 index 00000000..14b35b30 --- /dev/null +++ b/libc/nt/user32/GetWindowBand.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowBand,GetWindowBand,1977 diff --git a/libc/nt/user32/GetWindowCompositionAttribute.s b/libc/nt/user32/GetWindowCompositionAttribute.s new file mode 100644 index 00000000..62132eab --- /dev/null +++ b/libc/nt/user32/GetWindowCompositionAttribute.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowCompositionAttribute,GetWindowCompositionAttribute,1978 diff --git a/libc/nt/user32/GetWindowCompositionInfo.s b/libc/nt/user32/GetWindowCompositionInfo.s new file mode 100644 index 00000000..7103e581 --- /dev/null +++ b/libc/nt/user32/GetWindowCompositionInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowCompositionInfo,GetWindowCompositionInfo,1979 diff --git a/libc/nt/user32/GetWindowContextHelpId.s b/libc/nt/user32/GetWindowContextHelpId.s new file mode 100644 index 00000000..ce047aa0 --- /dev/null +++ b/libc/nt/user32/GetWindowContextHelpId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowContextHelpId,GetWindowContextHelpId,1980 diff --git a/libc/nt/user32/GetWindowDC.s b/libc/nt/user32/GetWindowDC.s new file mode 100644 index 00000000..e2ef76d9 --- /dev/null +++ b/libc/nt/user32/GetWindowDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowDC,GetWindowDC,1981 diff --git a/libc/nt/user32/GetWindowDisplayAffinity.s b/libc/nt/user32/GetWindowDisplayAffinity.s new file mode 100644 index 00000000..8c6cd981 --- /dev/null +++ b/libc/nt/user32/GetWindowDisplayAffinity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowDisplayAffinity,GetWindowDisplayAffinity,1982 diff --git a/libc/nt/user32/GetWindowDpiAwarenessContext.s b/libc/nt/user32/GetWindowDpiAwarenessContext.s new file mode 100644 index 00000000..ea83a794 --- /dev/null +++ b/libc/nt/user32/GetWindowDpiAwarenessContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowDpiAwarenessContext,GetWindowDpiAwarenessContext,1983 diff --git a/libc/nt/user32/GetWindowDpiHostingBehavior.s b/libc/nt/user32/GetWindowDpiHostingBehavior.s new file mode 100644 index 00000000..7325af46 --- /dev/null +++ b/libc/nt/user32/GetWindowDpiHostingBehavior.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowDpiHostingBehavior,GetWindowDpiHostingBehavior,1984 diff --git a/libc/nt/user32/GetWindowFeedbackSetting.s b/libc/nt/user32/GetWindowFeedbackSetting.s new file mode 100644 index 00000000..4ecd91a2 --- /dev/null +++ b/libc/nt/user32/GetWindowFeedbackSetting.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowFeedbackSetting,GetWindowFeedbackSetting,1985 diff --git a/libc/nt/user32/GetWindowInfo.s b/libc/nt/user32/GetWindowInfo.s new file mode 100644 index 00000000..70307e52 --- /dev/null +++ b/libc/nt/user32/GetWindowInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowInfo,GetWindowInfo,1986 diff --git a/libc/nt/user32/GetWindowLongA.s b/libc/nt/user32/GetWindowLongA.s new file mode 100644 index 00000000..66f0c812 --- /dev/null +++ b/libc/nt/user32/GetWindowLongA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowLongA,GetWindowLongA,1987 diff --git a/libc/nt/user32/GetWindowLongPtrA.s b/libc/nt/user32/GetWindowLongPtrA.s new file mode 100644 index 00000000..44fb0a81 --- /dev/null +++ b/libc/nt/user32/GetWindowLongPtrA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowLongPtrA,GetWindowLongPtrA,1988 diff --git a/libc/nt/user32/GetWindowLongPtrW.s b/libc/nt/user32/GetWindowLongPtrW.s new file mode 100644 index 00000000..a4da6092 --- /dev/null +++ b/libc/nt/user32/GetWindowLongPtrW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowLongPtrW,GetWindowLongPtrW,1989 diff --git a/libc/nt/user32/GetWindowLongW.s b/libc/nt/user32/GetWindowLongW.s new file mode 100644 index 00000000..c3221afd --- /dev/null +++ b/libc/nt/user32/GetWindowLongW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowLongW,GetWindowLongW,1990 diff --git a/libc/nt/user32/GetWindowMinimizeRect.s b/libc/nt/user32/GetWindowMinimizeRect.s new file mode 100644 index 00000000..b5b62267 --- /dev/null +++ b/libc/nt/user32/GetWindowMinimizeRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowMinimizeRect,GetWindowMinimizeRect,1991 diff --git a/libc/nt/user32/GetWindowModuleFileNameA.s b/libc/nt/user32/GetWindowModuleFileNameA.s new file mode 100644 index 00000000..f9f5c543 --- /dev/null +++ b/libc/nt/user32/GetWindowModuleFileNameA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowModuleFileNameA,GetWindowModuleFileNameA,1993 diff --git a/libc/nt/user32/GetWindowModuleFileNameW.s b/libc/nt/user32/GetWindowModuleFileNameW.s new file mode 100644 index 00000000..c18b466b --- /dev/null +++ b/libc/nt/user32/GetWindowModuleFileNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowModuleFileNameW,GetWindowModuleFileNameW,1994 diff --git a/libc/nt/user32/GetWindowPlacement.s b/libc/nt/user32/GetWindowPlacement.s new file mode 100644 index 00000000..5ddb46a3 --- /dev/null +++ b/libc/nt/user32/GetWindowPlacement.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowPlacement,GetWindowPlacement,1995 diff --git a/libc/nt/user32/GetWindowProcessHandle.s b/libc/nt/user32/GetWindowProcessHandle.s new file mode 100644 index 00000000..fb127f03 --- /dev/null +++ b/libc/nt/user32/GetWindowProcessHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowProcessHandle,GetWindowProcessHandle,1996 diff --git a/libc/nt/user32/GetWindowRect.s b/libc/nt/user32/GetWindowRect.s new file mode 100644 index 00000000..183537b1 --- /dev/null +++ b/libc/nt/user32/GetWindowRect.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowRect,GetWindowRect,1997 + + .text.windows +GetWindowRect: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetWindowRect(%rip),%rax + jmp __sysv2nt + .endfn GetWindowRect,globl + .previous diff --git a/libc/nt/user32/GetWindowRgn.s b/libc/nt/user32/GetWindowRgn.s new file mode 100644 index 00000000..cedaf0b0 --- /dev/null +++ b/libc/nt/user32/GetWindowRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowRgn,GetWindowRgn,1998 diff --git a/libc/nt/user32/GetWindowRgnBox.s b/libc/nt/user32/GetWindowRgnBox.s new file mode 100644 index 00000000..a204d152 --- /dev/null +++ b/libc/nt/user32/GetWindowRgnBox.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowRgnBox,GetWindowRgnBox,1999 diff --git a/libc/nt/user32/GetWindowRgnEx.s b/libc/nt/user32/GetWindowRgnEx.s new file mode 100644 index 00000000..d663f284 --- /dev/null +++ b/libc/nt/user32/GetWindowRgnEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowRgnEx,GetWindowRgnEx,2000 diff --git a/libc/nt/user32/GetWindowTextA.s b/libc/nt/user32/GetWindowTextA.s new file mode 100644 index 00000000..65af805b --- /dev/null +++ b/libc/nt/user32/GetWindowTextA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowTextA,GetWindowTextA,2003 + + .text.windows +GetWindowTextA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetWindowTextA(%rip),%rax + jmp __sysv2nt + .endfn GetWindowTextA,globl + .previous diff --git a/libc/nt/user32/GetWindowTextLengthA.s b/libc/nt/user32/GetWindowTextLengthA.s new file mode 100644 index 00000000..06dd3bb7 --- /dev/null +++ b/libc/nt/user32/GetWindowTextLengthA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowTextLengthA,GetWindowTextLengthA,2004 diff --git a/libc/nt/user32/GetWindowTextLengthW.s b/libc/nt/user32/GetWindowTextLengthW.s new file mode 100644 index 00000000..9ef47cf6 --- /dev/null +++ b/libc/nt/user32/GetWindowTextLengthW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowTextLengthW,GetWindowTextLengthW,2006 diff --git a/libc/nt/user32/GetWindowTextW.s b/libc/nt/user32/GetWindowTextW.s new file mode 100644 index 00000000..2ce6f577 --- /dev/null +++ b/libc/nt/user32/GetWindowTextW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowTextW,GetWindowTextW,2007 + + .text.windows +GetWindowText: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_GetWindowTextW(%rip),%rax + jmp __sysv2nt + .endfn GetWindowText,globl + .previous diff --git a/libc/nt/user32/GetWindowThreadProcessId.s b/libc/nt/user32/GetWindowThreadProcessId.s new file mode 100644 index 00000000..7786e929 --- /dev/null +++ b/libc/nt/user32/GetWindowThreadProcessId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowThreadProcessId,GetWindowThreadProcessId,2008 diff --git a/libc/nt/user32/GetWindowWord.s b/libc/nt/user32/GetWindowWord.s new file mode 100644 index 00000000..334a352c --- /dev/null +++ b/libc/nt/user32/GetWindowWord.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GetWindowWord,GetWindowWord,2009 diff --git a/libc/nt/user32/GhostWindowFromHungWindow.s b/libc/nt/user32/GhostWindowFromHungWindow.s new file mode 100644 index 00000000..c3debed2 --- /dev/null +++ b/libc/nt/user32/GhostWindowFromHungWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GhostWindowFromHungWindow,GhostWindowFromHungWindow,2011 diff --git a/libc/nt/user32/GrayStringA.s b/libc/nt/user32/GrayStringA.s new file mode 100644 index 00000000..8cb2581b --- /dev/null +++ b/libc/nt/user32/GrayStringA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GrayStringA,GrayStringA,2012 diff --git a/libc/nt/user32/GrayStringW.s b/libc/nt/user32/GrayStringW.s new file mode 100644 index 00000000..d577ab24 --- /dev/null +++ b/libc/nt/user32/GrayStringW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_GrayStringW,GrayStringW,2013 diff --git a/libc/nt/user32/HandleDelegatedInput.s b/libc/nt/user32/HandleDelegatedInput.s new file mode 100644 index 00000000..cf8f2444 --- /dev/null +++ b/libc/nt/user32/HandleDelegatedInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_HandleDelegatedInput,HandleDelegatedInput,2505 diff --git a/libc/nt/user32/HideCaret.s b/libc/nt/user32/HideCaret.s new file mode 100644 index 00000000..d9239e34 --- /dev/null +++ b/libc/nt/user32/HideCaret.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_HideCaret,HideCaret,2014 diff --git a/libc/nt/user32/HiliteMenuItem.s b/libc/nt/user32/HiliteMenuItem.s new file mode 100644 index 00000000..c1286905 --- /dev/null +++ b/libc/nt/user32/HiliteMenuItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_HiliteMenuItem,HiliteMenuItem,2015 diff --git a/libc/nt/user32/HungWindowFromGhostWindow.s b/libc/nt/user32/HungWindowFromGhostWindow.s new file mode 100644 index 00000000..e828ac07 --- /dev/null +++ b/libc/nt/user32/HungWindowFromGhostWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_HungWindowFromGhostWindow,HungWindowFromGhostWindow,2016 diff --git a/libc/nt/user32/IMPGetIMEA.s b/libc/nt/user32/IMPGetIMEA.s new file mode 100644 index 00000000..6fd07d26 --- /dev/null +++ b/libc/nt/user32/IMPGetIMEA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IMPGetIMEA,IMPGetIMEA,2017 diff --git a/libc/nt/user32/IMPGetIMEW.s b/libc/nt/user32/IMPGetIMEW.s new file mode 100644 index 00000000..d59f3aba --- /dev/null +++ b/libc/nt/user32/IMPGetIMEW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IMPGetIMEW,IMPGetIMEW,2018 diff --git a/libc/nt/user32/IMPQueryIMEA.s b/libc/nt/user32/IMPQueryIMEA.s new file mode 100644 index 00000000..e8669606 --- /dev/null +++ b/libc/nt/user32/IMPQueryIMEA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IMPQueryIMEA,IMPQueryIMEA,2019 diff --git a/libc/nt/user32/IMPQueryIMEW.s b/libc/nt/user32/IMPQueryIMEW.s new file mode 100644 index 00000000..c0da7f70 --- /dev/null +++ b/libc/nt/user32/IMPQueryIMEW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IMPQueryIMEW,IMPQueryIMEW,2020 diff --git a/libc/nt/user32/IMPSetIMEA.s b/libc/nt/user32/IMPSetIMEA.s new file mode 100644 index 00000000..33687434 --- /dev/null +++ b/libc/nt/user32/IMPSetIMEA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IMPSetIMEA,IMPSetIMEA,2021 diff --git a/libc/nt/user32/IMPSetIMEW.s b/libc/nt/user32/IMPSetIMEW.s new file mode 100644 index 00000000..2ea6565e --- /dev/null +++ b/libc/nt/user32/IMPSetIMEW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IMPSetIMEW,IMPSetIMEW,2022 diff --git a/libc/nt/user32/ImpersonateDdeClientWindow.s b/libc/nt/user32/ImpersonateDdeClientWindow.s new file mode 100644 index 00000000..79482db7 --- /dev/null +++ b/libc/nt/user32/ImpersonateDdeClientWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ImpersonateDdeClientWindow,ImpersonateDdeClientWindow,2023 diff --git a/libc/nt/user32/InSendMessage.s b/libc/nt/user32/InSendMessage.s new file mode 100644 index 00000000..634d097c --- /dev/null +++ b/libc/nt/user32/InSendMessage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InSendMessage,InSendMessage,2024 diff --git a/libc/nt/user32/InSendMessageEx.s b/libc/nt/user32/InSendMessageEx.s new file mode 100644 index 00000000..9a7b0d8f --- /dev/null +++ b/libc/nt/user32/InSendMessageEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InSendMessageEx,InSendMessageEx,2025 diff --git a/libc/nt/user32/InflateRect.s b/libc/nt/user32/InflateRect.s new file mode 100644 index 00000000..0c5d6f2e --- /dev/null +++ b/libc/nt/user32/InflateRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InflateRect,InflateRect,2026 diff --git a/libc/nt/user32/InheritWindowMonitor.s b/libc/nt/user32/InheritWindowMonitor.s new file mode 100644 index 00000000..9805a237 --- /dev/null +++ b/libc/nt/user32/InheritWindowMonitor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InheritWindowMonitor,InheritWindowMonitor,2027 diff --git a/libc/nt/user32/InitDManipHook.s b/libc/nt/user32/InitDManipHook.s new file mode 100644 index 00000000..192c4917 --- /dev/null +++ b/libc/nt/user32/InitDManipHook.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InitDManipHook,InitDManipHook,2028 diff --git a/libc/nt/user32/InitializeGenericHidInjection.s b/libc/nt/user32/InitializeGenericHidInjection.s new file mode 100644 index 00000000..61eae080 --- /dev/null +++ b/libc/nt/user32/InitializeGenericHidInjection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InitializeGenericHidInjection,InitializeGenericHidInjection,2029 diff --git a/libc/nt/user32/InitializeInputDeviceInjection.s b/libc/nt/user32/InitializeInputDeviceInjection.s new file mode 100644 index 00000000..01ace8e1 --- /dev/null +++ b/libc/nt/user32/InitializeInputDeviceInjection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InitializeInputDeviceInjection,InitializeInputDeviceInjection,2030 diff --git a/libc/nt/user32/InitializeLpkHooks.s b/libc/nt/user32/InitializeLpkHooks.s new file mode 100644 index 00000000..c734e3f9 --- /dev/null +++ b/libc/nt/user32/InitializeLpkHooks.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InitializeLpkHooks,InitializeLpkHooks,2031 diff --git a/libc/nt/user32/InitializePointerDeviceInjection.s b/libc/nt/user32/InitializePointerDeviceInjection.s new file mode 100644 index 00000000..87731539 --- /dev/null +++ b/libc/nt/user32/InitializePointerDeviceInjection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InitializePointerDeviceInjection,InitializePointerDeviceInjection,2032 diff --git a/libc/nt/user32/InitializePointerDeviceInjectionEx.s b/libc/nt/user32/InitializePointerDeviceInjectionEx.s new file mode 100644 index 00000000..a705e15f --- /dev/null +++ b/libc/nt/user32/InitializePointerDeviceInjectionEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InitializePointerDeviceInjectionEx,InitializePointerDeviceInjectionEx,2033 diff --git a/libc/nt/user32/InitializeTouchInjection.s b/libc/nt/user32/InitializeTouchInjection.s new file mode 100644 index 00000000..3a664671 --- /dev/null +++ b/libc/nt/user32/InitializeTouchInjection.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InitializeTouchInjection,InitializeTouchInjection,2034 diff --git a/libc/nt/user32/InjectDeviceInput.s b/libc/nt/user32/InjectDeviceInput.s new file mode 100644 index 00000000..93015fa6 --- /dev/null +++ b/libc/nt/user32/InjectDeviceInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InjectDeviceInput,InjectDeviceInput,2035 diff --git a/libc/nt/user32/InjectGenericHidInput.s b/libc/nt/user32/InjectGenericHidInput.s new file mode 100644 index 00000000..6dee3c76 --- /dev/null +++ b/libc/nt/user32/InjectGenericHidInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InjectGenericHidInput,InjectGenericHidInput,2036 diff --git a/libc/nt/user32/InjectKeyboardInput.s b/libc/nt/user32/InjectKeyboardInput.s new file mode 100644 index 00000000..f26b0f63 --- /dev/null +++ b/libc/nt/user32/InjectKeyboardInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InjectKeyboardInput,InjectKeyboardInput,2037 diff --git a/libc/nt/user32/InjectMouseInput.s b/libc/nt/user32/InjectMouseInput.s new file mode 100644 index 00000000..72a60d74 --- /dev/null +++ b/libc/nt/user32/InjectMouseInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InjectMouseInput,InjectMouseInput,2038 diff --git a/libc/nt/user32/InjectPointerInput.s b/libc/nt/user32/InjectPointerInput.s new file mode 100644 index 00000000..c8b36885 --- /dev/null +++ b/libc/nt/user32/InjectPointerInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InjectPointerInput,InjectPointerInput,2039 diff --git a/libc/nt/user32/InjectTouchInput.s b/libc/nt/user32/InjectTouchInput.s new file mode 100644 index 00000000..0809b0bf --- /dev/null +++ b/libc/nt/user32/InjectTouchInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InjectTouchInput,InjectTouchInput,2040 diff --git a/libc/nt/user32/InsertMenuA.s b/libc/nt/user32/InsertMenuA.s new file mode 100644 index 00000000..84fe4953 --- /dev/null +++ b/libc/nt/user32/InsertMenuA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InsertMenuA,InsertMenuA,2041 diff --git a/libc/nt/user32/InsertMenuItemA.s b/libc/nt/user32/InsertMenuItemA.s new file mode 100644 index 00000000..68c019ba --- /dev/null +++ b/libc/nt/user32/InsertMenuItemA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InsertMenuItemA,InsertMenuItemA,2042 diff --git a/libc/nt/user32/InsertMenuItemW.s b/libc/nt/user32/InsertMenuItemW.s new file mode 100644 index 00000000..7a6e79e5 --- /dev/null +++ b/libc/nt/user32/InsertMenuItemW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InsertMenuItemW,InsertMenuItemW,2043 diff --git a/libc/nt/user32/InsertMenuW.s b/libc/nt/user32/InsertMenuW.s new file mode 100644 index 00000000..9ffd81f7 --- /dev/null +++ b/libc/nt/user32/InsertMenuW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InsertMenuW,InsertMenuW,2044 diff --git a/libc/nt/user32/InternalGetWindowIcon.s b/libc/nt/user32/InternalGetWindowIcon.s new file mode 100644 index 00000000..c48295a1 --- /dev/null +++ b/libc/nt/user32/InternalGetWindowIcon.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InternalGetWindowIcon,InternalGetWindowIcon,2045 diff --git a/libc/nt/user32/InternalGetWindowText.s b/libc/nt/user32/InternalGetWindowText.s new file mode 100644 index 00000000..49f1f5f9 --- /dev/null +++ b/libc/nt/user32/InternalGetWindowText.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InternalGetWindowText,InternalGetWindowText,2046 diff --git a/libc/nt/user32/IntersectRect.s b/libc/nt/user32/IntersectRect.s new file mode 100644 index 00000000..f368b97a --- /dev/null +++ b/libc/nt/user32/IntersectRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IntersectRect,IntersectRect,2047 diff --git a/libc/nt/user32/InvalidateRect.s b/libc/nt/user32/InvalidateRect.s new file mode 100644 index 00000000..7a002f0d --- /dev/null +++ b/libc/nt/user32/InvalidateRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InvalidateRect,InvalidateRect,2048 diff --git a/libc/nt/user32/InvalidateRgn.s b/libc/nt/user32/InvalidateRgn.s new file mode 100644 index 00000000..2e3220e3 --- /dev/null +++ b/libc/nt/user32/InvalidateRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InvalidateRgn,InvalidateRgn,2049 diff --git a/libc/nt/user32/InvertRect.s b/libc/nt/user32/InvertRect.s new file mode 100644 index 00000000..041a93e9 --- /dev/null +++ b/libc/nt/user32/InvertRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_InvertRect,InvertRect,2050 diff --git a/libc/nt/user32/IsChild.s b/libc/nt/user32/IsChild.s new file mode 100644 index 00000000..dc9d31ed --- /dev/null +++ b/libc/nt/user32/IsChild.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsChild,IsChild,2059 + + .text.windows +IsChild: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_IsChild(%rip),%rax + jmp __sysv2nt + .endfn IsChild,globl + .previous diff --git a/libc/nt/user32/IsClipboardFormatAvailable.s b/libc/nt/user32/IsClipboardFormatAvailable.s new file mode 100644 index 00000000..bfbaf360 --- /dev/null +++ b/libc/nt/user32/IsClipboardFormatAvailable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsClipboardFormatAvailable,IsClipboardFormatAvailable,2060 diff --git a/libc/nt/user32/IsDialogMessageA.s b/libc/nt/user32/IsDialogMessageA.s new file mode 100644 index 00000000..b7935646 --- /dev/null +++ b/libc/nt/user32/IsDialogMessageA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsDialogMessageA,IsDialogMessageA,2062 diff --git a/libc/nt/user32/IsDialogMessageW.s b/libc/nt/user32/IsDialogMessageW.s new file mode 100644 index 00000000..1522b638 --- /dev/null +++ b/libc/nt/user32/IsDialogMessageW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsDialogMessageW,IsDialogMessageW,2063 diff --git a/libc/nt/user32/IsDlgButtonChecked.s b/libc/nt/user32/IsDlgButtonChecked.s new file mode 100644 index 00000000..bcc3e28a --- /dev/null +++ b/libc/nt/user32/IsDlgButtonChecked.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsDlgButtonChecked,IsDlgButtonChecked,2064 diff --git a/libc/nt/user32/IsGUIThread.s b/libc/nt/user32/IsGUIThread.s new file mode 100644 index 00000000..8a54d4c2 --- /dev/null +++ b/libc/nt/user32/IsGUIThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsGUIThread,IsGUIThread,2065 diff --git a/libc/nt/user32/IsHungAppWindow.s b/libc/nt/user32/IsHungAppWindow.s new file mode 100644 index 00000000..4e690011 --- /dev/null +++ b/libc/nt/user32/IsHungAppWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsHungAppWindow,IsHungAppWindow,2066 diff --git a/libc/nt/user32/IsIconic.s b/libc/nt/user32/IsIconic.s new file mode 100644 index 00000000..4d15f8ef --- /dev/null +++ b/libc/nt/user32/IsIconic.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsIconic,IsIconic,2067 diff --git a/libc/nt/user32/IsImmersiveProcess.s b/libc/nt/user32/IsImmersiveProcess.s new file mode 100644 index 00000000..3e4b520b --- /dev/null +++ b/libc/nt/user32/IsImmersiveProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsImmersiveProcess,IsImmersiveProcess,2068 diff --git a/libc/nt/user32/IsInDesktopWindowBand.s b/libc/nt/user32/IsInDesktopWindowBand.s new file mode 100644 index 00000000..6a632c9a --- /dev/null +++ b/libc/nt/user32/IsInDesktopWindowBand.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsInDesktopWindowBand,IsInDesktopWindowBand,2069 diff --git a/libc/nt/user32/IsMenu.s b/libc/nt/user32/IsMenu.s new file mode 100644 index 00000000..f87f905b --- /dev/null +++ b/libc/nt/user32/IsMenu.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsMenu,IsMenu,2070 + + .text.windows +IsMenu: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_IsMenu(%rip) + leave + ret + .endfn IsMenu,globl + .previous diff --git a/libc/nt/user32/IsMouseInPointerEnabled.s b/libc/nt/user32/IsMouseInPointerEnabled.s new file mode 100644 index 00000000..09438fdb --- /dev/null +++ b/libc/nt/user32/IsMouseInPointerEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsMouseInPointerEnabled,IsMouseInPointerEnabled,2071 diff --git a/libc/nt/user32/IsOneCoreTransformMode.s b/libc/nt/user32/IsOneCoreTransformMode.s new file mode 100644 index 00000000..0516e222 --- /dev/null +++ b/libc/nt/user32/IsOneCoreTransformMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsOneCoreTransformMode,IsOneCoreTransformMode,2072 diff --git a/libc/nt/user32/IsProcessDPIAware.s b/libc/nt/user32/IsProcessDPIAware.s new file mode 100644 index 00000000..36d2c79a --- /dev/null +++ b/libc/nt/user32/IsProcessDPIAware.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsProcessDPIAware,IsProcessDPIAware,2073 diff --git a/libc/nt/user32/IsQueueAttached.s b/libc/nt/user32/IsQueueAttached.s new file mode 100644 index 00000000..4d4da934 --- /dev/null +++ b/libc/nt/user32/IsQueueAttached.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsQueueAttached,IsQueueAttached,2074 diff --git a/libc/nt/user32/IsRectEmpty.s b/libc/nt/user32/IsRectEmpty.s new file mode 100644 index 00000000..83c04ef9 --- /dev/null +++ b/libc/nt/user32/IsRectEmpty.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsRectEmpty,IsRectEmpty,2075 diff --git a/libc/nt/user32/IsSETEnabled.s b/libc/nt/user32/IsSETEnabled.s new file mode 100644 index 00000000..6a639487 --- /dev/null +++ b/libc/nt/user32/IsSETEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsSETEnabled,IsSETEnabled,2076 diff --git a/libc/nt/user32/IsServerSideWindow.s b/libc/nt/user32/IsServerSideWindow.s new file mode 100644 index 00000000..d53b059f --- /dev/null +++ b/libc/nt/user32/IsServerSideWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsServerSideWindow,IsServerSideWindow,2077 diff --git a/libc/nt/user32/IsThreadDesktopComposited.s b/libc/nt/user32/IsThreadDesktopComposited.s new file mode 100644 index 00000000..146274c1 --- /dev/null +++ b/libc/nt/user32/IsThreadDesktopComposited.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsThreadDesktopComposited,IsThreadDesktopComposited,2078 diff --git a/libc/nt/user32/IsThreadMessageQueueAttached.s b/libc/nt/user32/IsThreadMessageQueueAttached.s new file mode 100644 index 00000000..7ee7128c --- /dev/null +++ b/libc/nt/user32/IsThreadMessageQueueAttached.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsThreadMessageQueueAttached,IsThreadMessageQueueAttached,2528 diff --git a/libc/nt/user32/IsThreadTSFEventAware.s b/libc/nt/user32/IsThreadTSFEventAware.s new file mode 100644 index 00000000..7e2b0b51 --- /dev/null +++ b/libc/nt/user32/IsThreadTSFEventAware.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsThreadTSFEventAware,IsThreadTSFEventAware,2079 diff --git a/libc/nt/user32/IsTopLevelWindow.s b/libc/nt/user32/IsTopLevelWindow.s new file mode 100644 index 00000000..f52f1257 --- /dev/null +++ b/libc/nt/user32/IsTopLevelWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsTopLevelWindow,IsTopLevelWindow,2080 diff --git a/libc/nt/user32/IsTouchWindow.s b/libc/nt/user32/IsTouchWindow.s new file mode 100644 index 00000000..1db7cef1 --- /dev/null +++ b/libc/nt/user32/IsTouchWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsTouchWindow,IsTouchWindow,2081 diff --git a/libc/nt/user32/IsValidDpiAwarenessContext.s b/libc/nt/user32/IsValidDpiAwarenessContext.s new file mode 100644 index 00000000..3026f51e --- /dev/null +++ b/libc/nt/user32/IsValidDpiAwarenessContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsValidDpiAwarenessContext,IsValidDpiAwarenessContext,2082 diff --git a/libc/nt/user32/IsWinEventHookInstalled.s b/libc/nt/user32/IsWinEventHookInstalled.s new file mode 100644 index 00000000..004d2a26 --- /dev/null +++ b/libc/nt/user32/IsWinEventHookInstalled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsWinEventHookInstalled,IsWinEventHookInstalled,2083 diff --git a/libc/nt/user32/IsWindow.s b/libc/nt/user32/IsWindow.s new file mode 100644 index 00000000..61cc8c5d --- /dev/null +++ b/libc/nt/user32/IsWindow.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsWindow,IsWindow,2084 + + .text.windows +IsWindow: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_IsWindow(%rip) + leave + ret + .endfn IsWindow,globl + .previous diff --git a/libc/nt/user32/IsWindowArranged.s b/libc/nt/user32/IsWindowArranged.s new file mode 100644 index 00000000..d2a50639 --- /dev/null +++ b/libc/nt/user32/IsWindowArranged.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsWindowArranged,IsWindowArranged,2085 diff --git a/libc/nt/user32/IsWindowEnabled.s b/libc/nt/user32/IsWindowEnabled.s new file mode 100644 index 00000000..f5739de4 --- /dev/null +++ b/libc/nt/user32/IsWindowEnabled.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsWindowEnabled,IsWindowEnabled,2086 diff --git a/libc/nt/user32/IsWindowInDestroy.s b/libc/nt/user32/IsWindowInDestroy.s new file mode 100644 index 00000000..3ac6b613 --- /dev/null +++ b/libc/nt/user32/IsWindowInDestroy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsWindowInDestroy,IsWindowInDestroy,2087 diff --git a/libc/nt/user32/IsWindowRedirectedForPrint.s b/libc/nt/user32/IsWindowRedirectedForPrint.s new file mode 100644 index 00000000..847d6754 --- /dev/null +++ b/libc/nt/user32/IsWindowRedirectedForPrint.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsWindowRedirectedForPrint,IsWindowRedirectedForPrint,2088 diff --git a/libc/nt/user32/IsWindowUnicode.s b/libc/nt/user32/IsWindowUnicode.s new file mode 100644 index 00000000..82bbc164 --- /dev/null +++ b/libc/nt/user32/IsWindowUnicode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsWindowUnicode,IsWindowUnicode,2089 diff --git a/libc/nt/user32/IsWindowVisible.s b/libc/nt/user32/IsWindowVisible.s new file mode 100644 index 00000000..4e89b100 --- /dev/null +++ b/libc/nt/user32/IsWindowVisible.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsWindowVisible,IsWindowVisible,2090 + + .text.windows +IsWindowVisible: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_IsWindowVisible(%rip) + leave + ret + .endfn IsWindowVisible,globl + .previous diff --git a/libc/nt/user32/IsWow64Message.s b/libc/nt/user32/IsWow64Message.s new file mode 100644 index 00000000..9d6d87ad --- /dev/null +++ b/libc/nt/user32/IsWow64Message.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsWow64Message,IsWow64Message,2091 diff --git a/libc/nt/user32/IsZoomed.s b/libc/nt/user32/IsZoomed.s new file mode 100644 index 00000000..e098ac78 --- /dev/null +++ b/libc/nt/user32/IsZoomed.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_IsZoomed,IsZoomed,2092 + + .text.windows +IsZoomed: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_IsZoomed(%rip) + leave + ret + .endfn IsZoomed,globl + .previous diff --git a/libc/nt/user32/KillTimer.s b/libc/nt/user32/KillTimer.s new file mode 100644 index 00000000..4ae77198 --- /dev/null +++ b/libc/nt/user32/KillTimer.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_KillTimer,KillTimer,2093 + + .text.windows +KillTimer: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_KillTimer(%rip),%rax + jmp __sysv2nt + .endfn KillTimer,globl + .previous diff --git a/libc/nt/user32/LoadAcceleratorsA.s b/libc/nt/user32/LoadAcceleratorsA.s new file mode 100644 index 00000000..e91c2678 --- /dev/null +++ b/libc/nt/user32/LoadAcceleratorsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadAcceleratorsA,LoadAcceleratorsA,2094 diff --git a/libc/nt/user32/LoadAcceleratorsW.s b/libc/nt/user32/LoadAcceleratorsW.s new file mode 100644 index 00000000..3ae00696 --- /dev/null +++ b/libc/nt/user32/LoadAcceleratorsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadAcceleratorsW,LoadAcceleratorsW,2095 diff --git a/libc/nt/user32/LoadBitmapA.s b/libc/nt/user32/LoadBitmapA.s new file mode 100644 index 00000000..944927ff --- /dev/null +++ b/libc/nt/user32/LoadBitmapA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadBitmapA,LoadBitmapA,2096 diff --git a/libc/nt/user32/LoadBitmapW.s b/libc/nt/user32/LoadBitmapW.s new file mode 100644 index 00000000..ac531b58 --- /dev/null +++ b/libc/nt/user32/LoadBitmapW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadBitmapW,LoadBitmapW,2097 diff --git a/libc/nt/user32/LoadCursorA.s b/libc/nt/user32/LoadCursorA.s new file mode 100644 index 00000000..15ce8b49 --- /dev/null +++ b/libc/nt/user32/LoadCursorA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadCursorA,LoadCursorA,2098 diff --git a/libc/nt/user32/LoadCursorFromFileA.s b/libc/nt/user32/LoadCursorFromFileA.s new file mode 100644 index 00000000..ba1c2274 --- /dev/null +++ b/libc/nt/user32/LoadCursorFromFileA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadCursorFromFileA,LoadCursorFromFileA,2099 diff --git a/libc/nt/user32/LoadCursorFromFileW.s b/libc/nt/user32/LoadCursorFromFileW.s new file mode 100644 index 00000000..5f864bf5 --- /dev/null +++ b/libc/nt/user32/LoadCursorFromFileW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadCursorFromFileW,LoadCursorFromFileW,2100 diff --git a/libc/nt/user32/LoadCursorW.s b/libc/nt/user32/LoadCursorW.s new file mode 100644 index 00000000..9562838d --- /dev/null +++ b/libc/nt/user32/LoadCursorW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadCursorW,LoadCursorW,2101 diff --git a/libc/nt/user32/LoadIconA.s b/libc/nt/user32/LoadIconA.s new file mode 100644 index 00000000..abe4c4a9 --- /dev/null +++ b/libc/nt/user32/LoadIconA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadIconA,LoadIconA,2102 + + .text.windows +LoadIconA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_LoadIconA(%rip),%rax + jmp __sysv2nt + .endfn LoadIconA,globl + .previous diff --git a/libc/nt/user32/LoadIconW.s b/libc/nt/user32/LoadIconW.s new file mode 100644 index 00000000..6dd0330f --- /dev/null +++ b/libc/nt/user32/LoadIconW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadIconW,LoadIconW,2103 + + .text.windows +LoadIcon: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_LoadIconW(%rip),%rax + jmp __sysv2nt + .endfn LoadIcon,globl + .previous diff --git a/libc/nt/user32/LoadImageA.s b/libc/nt/user32/LoadImageA.s new file mode 100644 index 00000000..d802b412 --- /dev/null +++ b/libc/nt/user32/LoadImageA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadImageA,LoadImageA,2104 diff --git a/libc/nt/user32/LoadImageW.s b/libc/nt/user32/LoadImageW.s new file mode 100644 index 00000000..ce0e5ebc --- /dev/null +++ b/libc/nt/user32/LoadImageW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadImageW,LoadImageW,2105 diff --git a/libc/nt/user32/LoadKeyboardLayoutA.s b/libc/nt/user32/LoadKeyboardLayoutA.s new file mode 100644 index 00000000..167913ac --- /dev/null +++ b/libc/nt/user32/LoadKeyboardLayoutA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadKeyboardLayoutA,LoadKeyboardLayoutA,2106 diff --git a/libc/nt/user32/LoadKeyboardLayoutEx.s b/libc/nt/user32/LoadKeyboardLayoutEx.s new file mode 100644 index 00000000..e9a7ddf2 --- /dev/null +++ b/libc/nt/user32/LoadKeyboardLayoutEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadKeyboardLayoutEx,LoadKeyboardLayoutEx,2107 diff --git a/libc/nt/user32/LoadKeyboardLayoutW.s b/libc/nt/user32/LoadKeyboardLayoutW.s new file mode 100644 index 00000000..caf5da98 --- /dev/null +++ b/libc/nt/user32/LoadKeyboardLayoutW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadKeyboardLayoutW,LoadKeyboardLayoutW,2108 diff --git a/libc/nt/user32/LoadLocalFonts.s b/libc/nt/user32/LoadLocalFonts.s new file mode 100644 index 00000000..03e9757c --- /dev/null +++ b/libc/nt/user32/LoadLocalFonts.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadLocalFonts,LoadLocalFonts,2109 diff --git a/libc/nt/user32/LoadMenuA.s b/libc/nt/user32/LoadMenuA.s new file mode 100644 index 00000000..b13133c8 --- /dev/null +++ b/libc/nt/user32/LoadMenuA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadMenuA,LoadMenuA,2110 diff --git a/libc/nt/user32/LoadMenuIndirectA.s b/libc/nt/user32/LoadMenuIndirectA.s new file mode 100644 index 00000000..dca70722 --- /dev/null +++ b/libc/nt/user32/LoadMenuIndirectA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadMenuIndirectA,LoadMenuIndirectA,2111 diff --git a/libc/nt/user32/LoadMenuIndirectW.s b/libc/nt/user32/LoadMenuIndirectW.s new file mode 100644 index 00000000..332f05a4 --- /dev/null +++ b/libc/nt/user32/LoadMenuIndirectW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadMenuIndirectW,LoadMenuIndirectW,2112 diff --git a/libc/nt/user32/LoadMenuW.s b/libc/nt/user32/LoadMenuW.s new file mode 100644 index 00000000..0ca20bc4 --- /dev/null +++ b/libc/nt/user32/LoadMenuW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadMenuW,LoadMenuW,2113 diff --git a/libc/nt/user32/LoadRemoteFonts.s b/libc/nt/user32/LoadRemoteFonts.s new file mode 100644 index 00000000..94a8c6a0 --- /dev/null +++ b/libc/nt/user32/LoadRemoteFonts.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LoadRemoteFonts,LoadRemoteFonts,2114 diff --git a/libc/nt/user32/LockSetForegroundWindow.s b/libc/nt/user32/LockSetForegroundWindow.s new file mode 100644 index 00000000..037f9632 --- /dev/null +++ b/libc/nt/user32/LockSetForegroundWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LockSetForegroundWindow,LockSetForegroundWindow,2117 diff --git a/libc/nt/user32/LockWindowStation.s b/libc/nt/user32/LockWindowStation.s new file mode 100644 index 00000000..d2292635 --- /dev/null +++ b/libc/nt/user32/LockWindowStation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LockWindowStation,LockWindowStation,2118 diff --git a/libc/nt/user32/LockWindowUpdate.s b/libc/nt/user32/LockWindowUpdate.s new file mode 100644 index 00000000..95ccf50a --- /dev/null +++ b/libc/nt/user32/LockWindowUpdate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LockWindowUpdate,LockWindowUpdate,2119 diff --git a/libc/nt/user32/LockWorkStation.s b/libc/nt/user32/LockWorkStation.s new file mode 100644 index 00000000..127fa751 --- /dev/null +++ b/libc/nt/user32/LockWorkStation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LockWorkStation,LockWorkStation,2120 diff --git a/libc/nt/user32/LogicalToPhysicalPoint.s b/libc/nt/user32/LogicalToPhysicalPoint.s new file mode 100644 index 00000000..0571eaa6 --- /dev/null +++ b/libc/nt/user32/LogicalToPhysicalPoint.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LogicalToPhysicalPoint,LogicalToPhysicalPoint,2121 diff --git a/libc/nt/user32/LogicalToPhysicalPointForPerMonitorDPI.s b/libc/nt/user32/LogicalToPhysicalPointForPerMonitorDPI.s new file mode 100644 index 00000000..eafc1077 --- /dev/null +++ b/libc/nt/user32/LogicalToPhysicalPointForPerMonitorDPI.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LogicalToPhysicalPointForPerMonitorDPI,LogicalToPhysicalPointForPerMonitorDPI,2122 diff --git a/libc/nt/user32/LookupIconIdFromDirectory.s b/libc/nt/user32/LookupIconIdFromDirectory.s new file mode 100644 index 00000000..7219224c --- /dev/null +++ b/libc/nt/user32/LookupIconIdFromDirectory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LookupIconIdFromDirectory,LookupIconIdFromDirectory,2123 diff --git a/libc/nt/user32/LookupIconIdFromDirectoryEx.s b/libc/nt/user32/LookupIconIdFromDirectoryEx.s new file mode 100644 index 00000000..778dff2a --- /dev/null +++ b/libc/nt/user32/LookupIconIdFromDirectoryEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_LookupIconIdFromDirectoryEx,LookupIconIdFromDirectoryEx,2124 diff --git a/libc/nt/user32/MBToWCSEx.s b/libc/nt/user32/MBToWCSEx.s new file mode 100644 index 00000000..a52c6bce --- /dev/null +++ b/libc/nt/user32/MBToWCSEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MBToWCSEx,MBToWCSEx,2125 diff --git a/libc/nt/user32/MBToWCSExt.s b/libc/nt/user32/MBToWCSExt.s new file mode 100644 index 00000000..7cbadd16 --- /dev/null +++ b/libc/nt/user32/MBToWCSExt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MBToWCSExt,MBToWCSExt,2126 diff --git a/libc/nt/user32/MB_GetString.s b/libc/nt/user32/MB_GetString.s new file mode 100644 index 00000000..15f5486e --- /dev/null +++ b/libc/nt/user32/MB_GetString.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MB_GetString,MB_GetString,2127 diff --git a/libc/nt/user32/MITActivateInputProcessing.s b/libc/nt/user32/MITActivateInputProcessing.s new file mode 100644 index 00000000..f213fc9d --- /dev/null +++ b/libc/nt/user32/MITActivateInputProcessing.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITActivateInputProcessing,MITActivateInputProcessing,2128 diff --git a/libc/nt/user32/MITBindInputTypeToMonitors.s b/libc/nt/user32/MITBindInputTypeToMonitors.s new file mode 100644 index 00000000..ed92df64 --- /dev/null +++ b/libc/nt/user32/MITBindInputTypeToMonitors.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITBindInputTypeToMonitors,MITBindInputTypeToMonitors,2129 diff --git a/libc/nt/user32/MITCoreMsgKGetConnectionHandle.s b/libc/nt/user32/MITCoreMsgKGetConnectionHandle.s new file mode 100644 index 00000000..f05df617 --- /dev/null +++ b/libc/nt/user32/MITCoreMsgKGetConnectionHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITCoreMsgKGetConnectionHandle,MITCoreMsgKGetConnectionHandle,2130 diff --git a/libc/nt/user32/MITCoreMsgKOpenConnectionTo.s b/libc/nt/user32/MITCoreMsgKOpenConnectionTo.s new file mode 100644 index 00000000..86f2869b --- /dev/null +++ b/libc/nt/user32/MITCoreMsgKOpenConnectionTo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITCoreMsgKOpenConnectionTo,MITCoreMsgKOpenConnectionTo,2131 diff --git a/libc/nt/user32/MITCoreMsgKSend.s b/libc/nt/user32/MITCoreMsgKSend.s new file mode 100644 index 00000000..68f5115f --- /dev/null +++ b/libc/nt/user32/MITCoreMsgKSend.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITCoreMsgKSend,MITCoreMsgKSend,2132 diff --git a/libc/nt/user32/MITDeactivateInputProcessing.s b/libc/nt/user32/MITDeactivateInputProcessing.s new file mode 100644 index 00000000..a91c16d7 --- /dev/null +++ b/libc/nt/user32/MITDeactivateInputProcessing.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITDeactivateInputProcessing,MITDeactivateInputProcessing,2133 diff --git a/libc/nt/user32/MITDisableMouseIntercept.s b/libc/nt/user32/MITDisableMouseIntercept.s new file mode 100644 index 00000000..1ea6dcb8 --- /dev/null +++ b/libc/nt/user32/MITDisableMouseIntercept.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITDisableMouseIntercept,MITDisableMouseIntercept,2134 diff --git a/libc/nt/user32/MITDispatchCompletion.s b/libc/nt/user32/MITDispatchCompletion.s new file mode 100644 index 00000000..bc04a66e --- /dev/null +++ b/libc/nt/user32/MITDispatchCompletion.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITDispatchCompletion,MITDispatchCompletion,2135 diff --git a/libc/nt/user32/MITEnableMouseIntercept.s b/libc/nt/user32/MITEnableMouseIntercept.s new file mode 100644 index 00000000..5a00d30e --- /dev/null +++ b/libc/nt/user32/MITEnableMouseIntercept.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITEnableMouseIntercept,MITEnableMouseIntercept,2136 diff --git a/libc/nt/user32/MITGetCursorUpdateHandle.s b/libc/nt/user32/MITGetCursorUpdateHandle.s new file mode 100644 index 00000000..249b35ef --- /dev/null +++ b/libc/nt/user32/MITGetCursorUpdateHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITGetCursorUpdateHandle,MITGetCursorUpdateHandle,2137 diff --git a/libc/nt/user32/MITInjectLegacyISMTouchFrame.s b/libc/nt/user32/MITInjectLegacyISMTouchFrame.s new file mode 100644 index 00000000..17408063 --- /dev/null +++ b/libc/nt/user32/MITInjectLegacyISMTouchFrame.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITInjectLegacyISMTouchFrame,MITInjectLegacyISMTouchFrame,2138 diff --git a/libc/nt/user32/MITRegisterManipulationThread.s b/libc/nt/user32/MITRegisterManipulationThread.s new file mode 100644 index 00000000..3a08a07a --- /dev/null +++ b/libc/nt/user32/MITRegisterManipulationThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITRegisterManipulationThread,MITRegisterManipulationThread,2139 diff --git a/libc/nt/user32/MITSetForegroundRoutingInfo.s b/libc/nt/user32/MITSetForegroundRoutingInfo.s new file mode 100644 index 00000000..9529a259 --- /dev/null +++ b/libc/nt/user32/MITSetForegroundRoutingInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITSetForegroundRoutingInfo,MITSetForegroundRoutingInfo,2140 diff --git a/libc/nt/user32/MITSetInputCallbacks.s b/libc/nt/user32/MITSetInputCallbacks.s new file mode 100644 index 00000000..ac64c57f --- /dev/null +++ b/libc/nt/user32/MITSetInputCallbacks.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITSetInputCallbacks,MITSetInputCallbacks,2141 diff --git a/libc/nt/user32/MITSetInputDelegationMode.s b/libc/nt/user32/MITSetInputDelegationMode.s new file mode 100644 index 00000000..f5de0e2f --- /dev/null +++ b/libc/nt/user32/MITSetInputDelegationMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITSetInputDelegationMode,MITSetInputDelegationMode,2142 diff --git a/libc/nt/user32/MITSetLastInputRecipient.s b/libc/nt/user32/MITSetLastInputRecipient.s new file mode 100644 index 00000000..42eefc50 --- /dev/null +++ b/libc/nt/user32/MITSetLastInputRecipient.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITSetLastInputRecipient,MITSetLastInputRecipient,2143 diff --git a/libc/nt/user32/MITSetManipulationInputTarget.s b/libc/nt/user32/MITSetManipulationInputTarget.s new file mode 100644 index 00000000..7959e836 --- /dev/null +++ b/libc/nt/user32/MITSetManipulationInputTarget.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITSetManipulationInputTarget,MITSetManipulationInputTarget,2144 diff --git a/libc/nt/user32/MITStopAndEndInertia.s b/libc/nt/user32/MITStopAndEndInertia.s new file mode 100644 index 00000000..fd9edfc4 --- /dev/null +++ b/libc/nt/user32/MITStopAndEndInertia.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITStopAndEndInertia,MITStopAndEndInertia,2145 diff --git a/libc/nt/user32/MITSynthesizeMouseInput.s b/libc/nt/user32/MITSynthesizeMouseInput.s new file mode 100644 index 00000000..ea5cacf8 --- /dev/null +++ b/libc/nt/user32/MITSynthesizeMouseInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITSynthesizeMouseInput,MITSynthesizeMouseInput,2146 diff --git a/libc/nt/user32/MITSynthesizeMouseWheel.s b/libc/nt/user32/MITSynthesizeMouseWheel.s new file mode 100644 index 00000000..19eebc86 --- /dev/null +++ b/libc/nt/user32/MITSynthesizeMouseWheel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITSynthesizeMouseWheel,MITSynthesizeMouseWheel,2147 diff --git a/libc/nt/user32/MITSynthesizeTouchInput.s b/libc/nt/user32/MITSynthesizeTouchInput.s new file mode 100644 index 00000000..0ccbb508 --- /dev/null +++ b/libc/nt/user32/MITSynthesizeTouchInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITSynthesizeTouchInput,MITSynthesizeTouchInput,2148 diff --git a/libc/nt/user32/MITUpdateInputGlobals.s b/libc/nt/user32/MITUpdateInputGlobals.s new file mode 100644 index 00000000..5893649e --- /dev/null +++ b/libc/nt/user32/MITUpdateInputGlobals.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITUpdateInputGlobals,MITUpdateInputGlobals,2149 diff --git a/libc/nt/user32/MITWaitForMultipleObjectsEx.s b/libc/nt/user32/MITWaitForMultipleObjectsEx.s new file mode 100644 index 00000000..7df9bec9 --- /dev/null +++ b/libc/nt/user32/MITWaitForMultipleObjectsEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MITWaitForMultipleObjectsEx,MITWaitForMultipleObjectsEx,2150 diff --git a/libc/nt/user32/MakeThreadTSFEventAware.s b/libc/nt/user32/MakeThreadTSFEventAware.s new file mode 100644 index 00000000..a881a33e --- /dev/null +++ b/libc/nt/user32/MakeThreadTSFEventAware.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MakeThreadTSFEventAware,MakeThreadTSFEventAware,2151 diff --git a/libc/nt/user32/MapDialogRect.s b/libc/nt/user32/MapDialogRect.s new file mode 100644 index 00000000..d0d0a0c4 --- /dev/null +++ b/libc/nt/user32/MapDialogRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MapDialogRect,MapDialogRect,2152 diff --git a/libc/nt/user32/MapVirtualKeyA.s b/libc/nt/user32/MapVirtualKeyA.s new file mode 100644 index 00000000..7162c7a0 --- /dev/null +++ b/libc/nt/user32/MapVirtualKeyA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MapVirtualKeyA,MapVirtualKeyA,2153 diff --git a/libc/nt/user32/MapVirtualKeyExA.s b/libc/nt/user32/MapVirtualKeyExA.s new file mode 100644 index 00000000..1a997fd5 --- /dev/null +++ b/libc/nt/user32/MapVirtualKeyExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MapVirtualKeyExA,MapVirtualKeyExA,2154 diff --git a/libc/nt/user32/MapVirtualKeyExW.s b/libc/nt/user32/MapVirtualKeyExW.s new file mode 100644 index 00000000..a30493c3 --- /dev/null +++ b/libc/nt/user32/MapVirtualKeyExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MapVirtualKeyExW,MapVirtualKeyExW,2155 diff --git a/libc/nt/user32/MapVirtualKeyW.s b/libc/nt/user32/MapVirtualKeyW.s new file mode 100644 index 00000000..f3a240eb --- /dev/null +++ b/libc/nt/user32/MapVirtualKeyW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MapVirtualKeyW,MapVirtualKeyW,2156 diff --git a/libc/nt/user32/MapVisualRelativePoints.s b/libc/nt/user32/MapVisualRelativePoints.s new file mode 100644 index 00000000..6151b4fd --- /dev/null +++ b/libc/nt/user32/MapVisualRelativePoints.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MapVisualRelativePoints,MapVisualRelativePoints,2157 diff --git a/libc/nt/user32/MapWindowPoints.s b/libc/nt/user32/MapWindowPoints.s new file mode 100644 index 00000000..bd67208f --- /dev/null +++ b/libc/nt/user32/MapWindowPoints.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MapWindowPoints,MapWindowPoints,2158 diff --git a/libc/nt/user32/MenuItemFromPoint.s b/libc/nt/user32/MenuItemFromPoint.s new file mode 100644 index 00000000..e05fc43c --- /dev/null +++ b/libc/nt/user32/MenuItemFromPoint.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MenuItemFromPoint,MenuItemFromPoint,2159 diff --git a/libc/nt/user32/MenuWindowProcA.s b/libc/nt/user32/MenuWindowProcA.s new file mode 100644 index 00000000..059f3b33 --- /dev/null +++ b/libc/nt/user32/MenuWindowProcA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MenuWindowProcA,MenuWindowProcA,2160 diff --git a/libc/nt/user32/MenuWindowProcW.s b/libc/nt/user32/MenuWindowProcW.s new file mode 100644 index 00000000..32e2ebe9 --- /dev/null +++ b/libc/nt/user32/MenuWindowProcW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MenuWindowProcW,MenuWindowProcW,2161 diff --git a/libc/nt/user32/MessageBeep.s b/libc/nt/user32/MessageBeep.s new file mode 100644 index 00000000..3882822e --- /dev/null +++ b/libc/nt/user32/MessageBeep.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MessageBeep,MessageBeep,2162 diff --git a/libc/nt/user32/MessageBoxA.s b/libc/nt/user32/MessageBoxA.s new file mode 100644 index 00000000..e7983614 --- /dev/null +++ b/libc/nt/user32/MessageBoxA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MessageBoxA,MessageBoxA,2163 + + .text.windows +MessageBoxA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_MessageBoxA(%rip),%rax + jmp __sysv2nt + .endfn MessageBoxA,globl + .previous diff --git a/libc/nt/user32/MessageBoxExA.s b/libc/nt/user32/MessageBoxExA.s new file mode 100644 index 00000000..0cd8e4fc --- /dev/null +++ b/libc/nt/user32/MessageBoxExA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MessageBoxExA,MessageBoxExA,2164 + + .text.windows +MessageBoxExA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_MessageBoxExA(%rip),%rax + jmp __sysv2nt6 + .endfn MessageBoxExA,globl + .previous diff --git a/libc/nt/user32/MessageBoxExW.s b/libc/nt/user32/MessageBoxExW.s new file mode 100644 index 00000000..5569e448 --- /dev/null +++ b/libc/nt/user32/MessageBoxExW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MessageBoxExW,MessageBoxExW,2165 + + .text.windows +MessageBoxEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_MessageBoxExW(%rip),%rax + jmp __sysv2nt6 + .endfn MessageBoxEx,globl + .previous diff --git a/libc/nt/user32/MessageBoxIndirectA.s b/libc/nt/user32/MessageBoxIndirectA.s new file mode 100644 index 00000000..6df3b556 --- /dev/null +++ b/libc/nt/user32/MessageBoxIndirectA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MessageBoxIndirectA,MessageBoxIndirectA,2166 diff --git a/libc/nt/user32/MessageBoxIndirectW.s b/libc/nt/user32/MessageBoxIndirectW.s new file mode 100644 index 00000000..2c842a5a --- /dev/null +++ b/libc/nt/user32/MessageBoxIndirectW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MessageBoxIndirectW,MessageBoxIndirectW,2167 diff --git a/libc/nt/user32/MessageBoxTimeoutA.s b/libc/nt/user32/MessageBoxTimeoutA.s new file mode 100644 index 00000000..6ee56536 --- /dev/null +++ b/libc/nt/user32/MessageBoxTimeoutA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MessageBoxTimeoutA,MessageBoxTimeoutA,2168 diff --git a/libc/nt/user32/MessageBoxTimeoutW.s b/libc/nt/user32/MessageBoxTimeoutW.s new file mode 100644 index 00000000..0f17f7a0 --- /dev/null +++ b/libc/nt/user32/MessageBoxTimeoutW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MessageBoxTimeoutW,MessageBoxTimeoutW,2169 diff --git a/libc/nt/user32/MessageBoxW.s b/libc/nt/user32/MessageBoxW.s new file mode 100644 index 00000000..1287e5c8 --- /dev/null +++ b/libc/nt/user32/MessageBoxW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MessageBoxW,MessageBoxW,2170 + + .text.windows +MessageBox: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_MessageBoxW(%rip),%rax + jmp __sysv2nt + .endfn MessageBox,globl + .previous diff --git a/libc/nt/user32/ModifyMenuA.s b/libc/nt/user32/ModifyMenuA.s new file mode 100644 index 00000000..6dd007ab --- /dev/null +++ b/libc/nt/user32/ModifyMenuA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ModifyMenuA,ModifyMenuA,2171 diff --git a/libc/nt/user32/ModifyMenuW.s b/libc/nt/user32/ModifyMenuW.s new file mode 100644 index 00000000..ab1e22a2 --- /dev/null +++ b/libc/nt/user32/ModifyMenuW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ModifyMenuW,ModifyMenuW,2172 diff --git a/libc/nt/user32/MonitorFromPoint.s b/libc/nt/user32/MonitorFromPoint.s new file mode 100644 index 00000000..9a80adcf --- /dev/null +++ b/libc/nt/user32/MonitorFromPoint.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MonitorFromPoint,MonitorFromPoint,2173 diff --git a/libc/nt/user32/MonitorFromRect.s b/libc/nt/user32/MonitorFromRect.s new file mode 100644 index 00000000..7a99aeeb --- /dev/null +++ b/libc/nt/user32/MonitorFromRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MonitorFromRect,MonitorFromRect,2174 diff --git a/libc/nt/user32/MonitorFromWindow.s b/libc/nt/user32/MonitorFromWindow.s new file mode 100644 index 00000000..7916ef23 --- /dev/null +++ b/libc/nt/user32/MonitorFromWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MonitorFromWindow,MonitorFromWindow,2175 diff --git a/libc/nt/user32/MoveWindow.s b/libc/nt/user32/MoveWindow.s new file mode 100644 index 00000000..ac1081e4 --- /dev/null +++ b/libc/nt/user32/MoveWindow.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MoveWindow,MoveWindow,2176 + + .text.windows +MoveWindow: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_MoveWindow(%rip),%rax + jmp __sysv2nt6 + .endfn MoveWindow,globl + .previous diff --git a/libc/nt/user32/MsgWaitForMultipleObjects.s b/libc/nt/user32/MsgWaitForMultipleObjects.s new file mode 100644 index 00000000..c267a101 --- /dev/null +++ b/libc/nt/user32/MsgWaitForMultipleObjects.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MsgWaitForMultipleObjects,MsgWaitForMultipleObjects,2177 diff --git a/libc/nt/user32/MsgWaitForMultipleObjectsEx.s b/libc/nt/user32/MsgWaitForMultipleObjectsEx.s new file mode 100644 index 00000000..e0dca323 --- /dev/null +++ b/libc/nt/user32/MsgWaitForMultipleObjectsEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_MsgWaitForMultipleObjectsEx,MsgWaitForMultipleObjectsEx,2178 diff --git a/libc/nt/user32/NotifyOverlayWindow.s b/libc/nt/user32/NotifyOverlayWindow.s new file mode 100644 index 00000000..046f099d --- /dev/null +++ b/libc/nt/user32/NotifyOverlayWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_NotifyOverlayWindow,NotifyOverlayWindow,2179 diff --git a/libc/nt/user32/NotifyWinEvent.s b/libc/nt/user32/NotifyWinEvent.s new file mode 100644 index 00000000..3d305812 --- /dev/null +++ b/libc/nt/user32/NotifyWinEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_NotifyWinEvent,NotifyWinEvent,2180 diff --git a/libc/nt/user32/OemKeyScan.s b/libc/nt/user32/OemKeyScan.s new file mode 100644 index 00000000..51974d98 --- /dev/null +++ b/libc/nt/user32/OemKeyScan.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_OemKeyScan,OemKeyScan,2181 diff --git a/libc/nt/user32/OemToCharA.s b/libc/nt/user32/OemToCharA.s new file mode 100644 index 00000000..e68750bd --- /dev/null +++ b/libc/nt/user32/OemToCharA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_OemToCharA,OemToCharA,2182 diff --git a/libc/nt/user32/OemToCharBuffA.s b/libc/nt/user32/OemToCharBuffA.s new file mode 100644 index 00000000..bac11de9 --- /dev/null +++ b/libc/nt/user32/OemToCharBuffA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_OemToCharBuffA,OemToCharBuffA,2183 diff --git a/libc/nt/user32/OemToCharBuffW.s b/libc/nt/user32/OemToCharBuffW.s new file mode 100644 index 00000000..83482eb9 --- /dev/null +++ b/libc/nt/user32/OemToCharBuffW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_OemToCharBuffW,OemToCharBuffW,2184 diff --git a/libc/nt/user32/OemToCharW.s b/libc/nt/user32/OemToCharW.s new file mode 100644 index 00000000..e3ca55b5 --- /dev/null +++ b/libc/nt/user32/OemToCharW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_OemToCharW,OemToCharW,2185 diff --git a/libc/nt/user32/OffsetRect.s b/libc/nt/user32/OffsetRect.s new file mode 100644 index 00000000..8fabef7d --- /dev/null +++ b/libc/nt/user32/OffsetRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_OffsetRect,OffsetRect,2186 diff --git a/libc/nt/user32/OpenClipboard.s b/libc/nt/user32/OpenClipboard.s new file mode 100644 index 00000000..5aeb9a2a --- /dev/null +++ b/libc/nt/user32/OpenClipboard.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_OpenClipboard,OpenClipboard,2187 diff --git a/libc/nt/user32/OpenDesktopA.s b/libc/nt/user32/OpenDesktopA.s new file mode 100644 index 00000000..81be7999 --- /dev/null +++ b/libc/nt/user32/OpenDesktopA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_OpenDesktopA,OpenDesktopA,2188 diff --git a/libc/nt/user32/OpenDesktopW.s b/libc/nt/user32/OpenDesktopW.s new file mode 100644 index 00000000..e962a8c9 --- /dev/null +++ b/libc/nt/user32/OpenDesktopW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_OpenDesktopW,OpenDesktopW,2189 diff --git a/libc/nt/user32/OpenIcon.s b/libc/nt/user32/OpenIcon.s new file mode 100644 index 00000000..02c3bcd6 --- /dev/null +++ b/libc/nt/user32/OpenIcon.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_OpenIcon,OpenIcon,2190 diff --git a/libc/nt/user32/OpenInputDesktop.s b/libc/nt/user32/OpenInputDesktop.s new file mode 100644 index 00000000..1f78a088 --- /dev/null +++ b/libc/nt/user32/OpenInputDesktop.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_OpenInputDesktop,OpenInputDesktop,2191 diff --git a/libc/nt/user32/OpenThreadDesktop.s b/libc/nt/user32/OpenThreadDesktop.s new file mode 100644 index 00000000..5bfc8e9f --- /dev/null +++ b/libc/nt/user32/OpenThreadDesktop.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_OpenThreadDesktop,OpenThreadDesktop,2192 diff --git a/libc/nt/user32/OpenWindowStationA.s b/libc/nt/user32/OpenWindowStationA.s new file mode 100644 index 00000000..b5d7c051 --- /dev/null +++ b/libc/nt/user32/OpenWindowStationA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_OpenWindowStationA,OpenWindowStationA,2193 diff --git a/libc/nt/user32/OpenWindowStationW.s b/libc/nt/user32/OpenWindowStationW.s new file mode 100644 index 00000000..057b09f6 --- /dev/null +++ b/libc/nt/user32/OpenWindowStationW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_OpenWindowStationW,OpenWindowStationW,2194 diff --git a/libc/nt/user32/PackDDElParam.s b/libc/nt/user32/PackDDElParam.s new file mode 100644 index 00000000..dd29f4ba --- /dev/null +++ b/libc/nt/user32/PackDDElParam.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PackDDElParam,PackDDElParam,2195 diff --git a/libc/nt/user32/PackTouchHitTestingProximityEvaluation.s b/libc/nt/user32/PackTouchHitTestingProximityEvaluation.s new file mode 100644 index 00000000..8ff2b863 --- /dev/null +++ b/libc/nt/user32/PackTouchHitTestingProximityEvaluation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PackTouchHitTestingProximityEvaluation,PackTouchHitTestingProximityEvaluation,2196 diff --git a/libc/nt/user32/PaintDesktop.s b/libc/nt/user32/PaintDesktop.s new file mode 100644 index 00000000..53d9a75f --- /dev/null +++ b/libc/nt/user32/PaintDesktop.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PaintDesktop,PaintDesktop,2197 diff --git a/libc/nt/user32/PaintMenuBar.s b/libc/nt/user32/PaintMenuBar.s new file mode 100644 index 00000000..128b476b --- /dev/null +++ b/libc/nt/user32/PaintMenuBar.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PaintMenuBar,PaintMenuBar,2198 diff --git a/libc/nt/user32/PaintMonitor.s b/libc/nt/user32/PaintMonitor.s new file mode 100644 index 00000000..fbc20621 --- /dev/null +++ b/libc/nt/user32/PaintMonitor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PaintMonitor,PaintMonitor,2199 diff --git a/libc/nt/user32/PeekMessageA.s b/libc/nt/user32/PeekMessageA.s new file mode 100644 index 00000000..869dff5a --- /dev/null +++ b/libc/nt/user32/PeekMessageA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PeekMessageA,PeekMessageA,2200 diff --git a/libc/nt/user32/PeekMessageW.s b/libc/nt/user32/PeekMessageW.s new file mode 100644 index 00000000..219a967c --- /dev/null +++ b/libc/nt/user32/PeekMessageW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PeekMessageW,PeekMessageW,2201 diff --git a/libc/nt/user32/PhysicalToLogicalPoint.s b/libc/nt/user32/PhysicalToLogicalPoint.s new file mode 100644 index 00000000..11e4c802 --- /dev/null +++ b/libc/nt/user32/PhysicalToLogicalPoint.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PhysicalToLogicalPoint,PhysicalToLogicalPoint,2202 diff --git a/libc/nt/user32/PhysicalToLogicalPointForPerMonitorDPI.s b/libc/nt/user32/PhysicalToLogicalPointForPerMonitorDPI.s new file mode 100644 index 00000000..56f99f95 --- /dev/null +++ b/libc/nt/user32/PhysicalToLogicalPointForPerMonitorDPI.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PhysicalToLogicalPointForPerMonitorDPI,PhysicalToLogicalPointForPerMonitorDPI,2203 diff --git a/libc/nt/user32/PostMessageA.s b/libc/nt/user32/PostMessageA.s new file mode 100644 index 00000000..2cef4887 --- /dev/null +++ b/libc/nt/user32/PostMessageA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PostMessageA,PostMessageA,2204 diff --git a/libc/nt/user32/PostMessageW.s b/libc/nt/user32/PostMessageW.s new file mode 100644 index 00000000..fde5827f --- /dev/null +++ b/libc/nt/user32/PostMessageW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PostMessageW,PostMessageW,2205 diff --git a/libc/nt/user32/PostQuitMessage.s b/libc/nt/user32/PostQuitMessage.s new file mode 100644 index 00000000..4a6f204c --- /dev/null +++ b/libc/nt/user32/PostQuitMessage.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PostQuitMessage,PostQuitMessage,2206 + + .text.windows +PostQuitMessage: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_PostQuitMessage(%rip) + leave + ret + .endfn PostQuitMessage,globl + .previous diff --git a/libc/nt/user32/PostThreadMessageA.s b/libc/nt/user32/PostThreadMessageA.s new file mode 100644 index 00000000..3ec4102d --- /dev/null +++ b/libc/nt/user32/PostThreadMessageA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PostThreadMessageA,PostThreadMessageA,2207 diff --git a/libc/nt/user32/PostThreadMessageW.s b/libc/nt/user32/PostThreadMessageW.s new file mode 100644 index 00000000..b1feb3d0 --- /dev/null +++ b/libc/nt/user32/PostThreadMessageW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PostThreadMessageW,PostThreadMessageW,2208 diff --git a/libc/nt/user32/PrintWindow.s b/libc/nt/user32/PrintWindow.s new file mode 100644 index 00000000..318b3c53 --- /dev/null +++ b/libc/nt/user32/PrintWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PrintWindow,PrintWindow,2209 diff --git a/libc/nt/user32/PrivateExtractIconExA.s b/libc/nt/user32/PrivateExtractIconExA.s new file mode 100644 index 00000000..c549eb7e --- /dev/null +++ b/libc/nt/user32/PrivateExtractIconExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PrivateExtractIconExA,PrivateExtractIconExA,2210 diff --git a/libc/nt/user32/PrivateExtractIconExW.s b/libc/nt/user32/PrivateExtractIconExW.s new file mode 100644 index 00000000..0d1d17c2 --- /dev/null +++ b/libc/nt/user32/PrivateExtractIconExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PrivateExtractIconExW,PrivateExtractIconExW,2211 diff --git a/libc/nt/user32/PrivateExtractIconsA.s b/libc/nt/user32/PrivateExtractIconsA.s new file mode 100644 index 00000000..39c48fd0 --- /dev/null +++ b/libc/nt/user32/PrivateExtractIconsA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PrivateExtractIconsA,PrivateExtractIconsA,2212 diff --git a/libc/nt/user32/PrivateExtractIconsW.s b/libc/nt/user32/PrivateExtractIconsW.s new file mode 100644 index 00000000..ba55c744 --- /dev/null +++ b/libc/nt/user32/PrivateExtractIconsW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PrivateExtractIconsW,PrivateExtractIconsW,2213 diff --git a/libc/nt/user32/PrivateRegisterICSProc.s b/libc/nt/user32/PrivateRegisterICSProc.s new file mode 100644 index 00000000..05c504e0 --- /dev/null +++ b/libc/nt/user32/PrivateRegisterICSProc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PrivateRegisterICSProc,PrivateRegisterICSProc,2214 diff --git a/libc/nt/user32/PtInRect.s b/libc/nt/user32/PtInRect.s new file mode 100644 index 00000000..19efca27 --- /dev/null +++ b/libc/nt/user32/PtInRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_PtInRect,PtInRect,2215 diff --git a/libc/nt/user32/QueryBSDRWindow.s b/libc/nt/user32/QueryBSDRWindow.s new file mode 100644 index 00000000..5608f519 --- /dev/null +++ b/libc/nt/user32/QueryBSDRWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_QueryBSDRWindow,QueryBSDRWindow,2216 diff --git a/libc/nt/user32/QueryDisplayConfig.s b/libc/nt/user32/QueryDisplayConfig.s new file mode 100644 index 00000000..1f04dff4 --- /dev/null +++ b/libc/nt/user32/QueryDisplayConfig.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_QueryDisplayConfig,QueryDisplayConfig,2217 diff --git a/libc/nt/user32/QuerySendMessage.s b/libc/nt/user32/QuerySendMessage.s new file mode 100644 index 00000000..2fe89119 --- /dev/null +++ b/libc/nt/user32/QuerySendMessage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_QuerySendMessage,QuerySendMessage,2218 diff --git a/libc/nt/user32/RIMAddInputObserver.s b/libc/nt/user32/RIMAddInputObserver.s new file mode 100644 index 00000000..ce97538d --- /dev/null +++ b/libc/nt/user32/RIMAddInputObserver.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMAddInputObserver,RIMAddInputObserver,2219 diff --git a/libc/nt/user32/RIMAreSiblingDevices.s b/libc/nt/user32/RIMAreSiblingDevices.s new file mode 100644 index 00000000..7d68b03b --- /dev/null +++ b/libc/nt/user32/RIMAreSiblingDevices.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMAreSiblingDevices,RIMAreSiblingDevices,2220 diff --git a/libc/nt/user32/RIMDeviceIoControl.s b/libc/nt/user32/RIMDeviceIoControl.s new file mode 100644 index 00000000..862da124 --- /dev/null +++ b/libc/nt/user32/RIMDeviceIoControl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMDeviceIoControl,RIMDeviceIoControl,2221 diff --git a/libc/nt/user32/RIMEnableMonitorMappingForDevice.s b/libc/nt/user32/RIMEnableMonitorMappingForDevice.s new file mode 100644 index 00000000..72f32154 --- /dev/null +++ b/libc/nt/user32/RIMEnableMonitorMappingForDevice.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMEnableMonitorMappingForDevice,RIMEnableMonitorMappingForDevice,2222 diff --git a/libc/nt/user32/RIMFreeInputBuffer.s b/libc/nt/user32/RIMFreeInputBuffer.s new file mode 100644 index 00000000..9de25691 --- /dev/null +++ b/libc/nt/user32/RIMFreeInputBuffer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMFreeInputBuffer,RIMFreeInputBuffer,2223 diff --git a/libc/nt/user32/RIMGetDevicePreparsedData.s b/libc/nt/user32/RIMGetDevicePreparsedData.s new file mode 100644 index 00000000..f7a14952 --- /dev/null +++ b/libc/nt/user32/RIMGetDevicePreparsedData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMGetDevicePreparsedData,RIMGetDevicePreparsedData,2224 diff --git a/libc/nt/user32/RIMGetDevicePreparsedDataLockfree.s b/libc/nt/user32/RIMGetDevicePreparsedDataLockfree.s new file mode 100644 index 00000000..343ce46c --- /dev/null +++ b/libc/nt/user32/RIMGetDevicePreparsedDataLockfree.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMGetDevicePreparsedDataLockfree,RIMGetDevicePreparsedDataLockfree,2225 diff --git a/libc/nt/user32/RIMGetDeviceProperties.s b/libc/nt/user32/RIMGetDeviceProperties.s new file mode 100644 index 00000000..7864a61c --- /dev/null +++ b/libc/nt/user32/RIMGetDeviceProperties.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMGetDeviceProperties,RIMGetDeviceProperties,2226 diff --git a/libc/nt/user32/RIMGetDevicePropertiesLockfree.s b/libc/nt/user32/RIMGetDevicePropertiesLockfree.s new file mode 100644 index 00000000..1f8111b0 --- /dev/null +++ b/libc/nt/user32/RIMGetDevicePropertiesLockfree.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMGetDevicePropertiesLockfree,RIMGetDevicePropertiesLockfree,2227 diff --git a/libc/nt/user32/RIMGetPhysicalDeviceRect.s b/libc/nt/user32/RIMGetPhysicalDeviceRect.s new file mode 100644 index 00000000..4400ffdd --- /dev/null +++ b/libc/nt/user32/RIMGetPhysicalDeviceRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMGetPhysicalDeviceRect,RIMGetPhysicalDeviceRect,2228 diff --git a/libc/nt/user32/RIMGetSourceProcessId.s b/libc/nt/user32/RIMGetSourceProcessId.s new file mode 100644 index 00000000..80141676 --- /dev/null +++ b/libc/nt/user32/RIMGetSourceProcessId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMGetSourceProcessId,RIMGetSourceProcessId,2229 diff --git a/libc/nt/user32/RIMObserveNextInput.s b/libc/nt/user32/RIMObserveNextInput.s new file mode 100644 index 00000000..3082a158 --- /dev/null +++ b/libc/nt/user32/RIMObserveNextInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMObserveNextInput,RIMObserveNextInput,2230 diff --git a/libc/nt/user32/RIMOnPnpNotification.s b/libc/nt/user32/RIMOnPnpNotification.s new file mode 100644 index 00000000..f011502f --- /dev/null +++ b/libc/nt/user32/RIMOnPnpNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMOnPnpNotification,RIMOnPnpNotification,2231 diff --git a/libc/nt/user32/RIMOnTimerNotification.s b/libc/nt/user32/RIMOnTimerNotification.s new file mode 100644 index 00000000..bc965b0e --- /dev/null +++ b/libc/nt/user32/RIMOnTimerNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMOnTimerNotification,RIMOnTimerNotification,2232 diff --git a/libc/nt/user32/RIMReadInput.s b/libc/nt/user32/RIMReadInput.s new file mode 100644 index 00000000..1425393e --- /dev/null +++ b/libc/nt/user32/RIMReadInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMReadInput,RIMReadInput,2233 diff --git a/libc/nt/user32/RIMRegisterForInput.s b/libc/nt/user32/RIMRegisterForInput.s new file mode 100644 index 00000000..761b44d3 --- /dev/null +++ b/libc/nt/user32/RIMRegisterForInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMRegisterForInput,RIMRegisterForInput,2234 diff --git a/libc/nt/user32/RIMRemoveInputObserver.s b/libc/nt/user32/RIMRemoveInputObserver.s new file mode 100644 index 00000000..c20c20e8 --- /dev/null +++ b/libc/nt/user32/RIMRemoveInputObserver.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMRemoveInputObserver,RIMRemoveInputObserver,2235 diff --git a/libc/nt/user32/RIMSetTestModeStatus.s b/libc/nt/user32/RIMSetTestModeStatus.s new file mode 100644 index 00000000..2bf71074 --- /dev/null +++ b/libc/nt/user32/RIMSetTestModeStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMSetTestModeStatus,RIMSetTestModeStatus,2236 diff --git a/libc/nt/user32/RIMUnregisterForInput.s b/libc/nt/user32/RIMUnregisterForInput.s new file mode 100644 index 00000000..5a97d9e4 --- /dev/null +++ b/libc/nt/user32/RIMUnregisterForInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMUnregisterForInput,RIMUnregisterForInput,2237 diff --git a/libc/nt/user32/RIMUpdateInputObserverRegistration.s b/libc/nt/user32/RIMUpdateInputObserverRegistration.s new file mode 100644 index 00000000..7cc088be --- /dev/null +++ b/libc/nt/user32/RIMUpdateInputObserverRegistration.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RIMUpdateInputObserverRegistration,RIMUpdateInputObserverRegistration,2238 diff --git a/libc/nt/user32/RealChildWindowFromPoint.s b/libc/nt/user32/RealChildWindowFromPoint.s new file mode 100644 index 00000000..8e16678b --- /dev/null +++ b/libc/nt/user32/RealChildWindowFromPoint.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RealChildWindowFromPoint,RealChildWindowFromPoint,2239 diff --git a/libc/nt/user32/RealGetWindowClassA.s b/libc/nt/user32/RealGetWindowClassA.s new file mode 100644 index 00000000..695483e1 --- /dev/null +++ b/libc/nt/user32/RealGetWindowClassA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RealGetWindowClassA,RealGetWindowClassA,2241 diff --git a/libc/nt/user32/RealGetWindowClassW.s b/libc/nt/user32/RealGetWindowClassW.s new file mode 100644 index 00000000..1b826aed --- /dev/null +++ b/libc/nt/user32/RealGetWindowClassW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RealGetWindowClassW,RealGetWindowClassW,2242 diff --git a/libc/nt/user32/ReasonCodeNeedsBugID.s b/libc/nt/user32/ReasonCodeNeedsBugID.s new file mode 100644 index 00000000..ad29c934 --- /dev/null +++ b/libc/nt/user32/ReasonCodeNeedsBugID.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ReasonCodeNeedsBugID,ReasonCodeNeedsBugID,2243 diff --git a/libc/nt/user32/ReasonCodeNeedsComment.s b/libc/nt/user32/ReasonCodeNeedsComment.s new file mode 100644 index 00000000..621e9838 --- /dev/null +++ b/libc/nt/user32/ReasonCodeNeedsComment.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ReasonCodeNeedsComment,ReasonCodeNeedsComment,2244 diff --git a/libc/nt/user32/RecordShutdownReason.s b/libc/nt/user32/RecordShutdownReason.s new file mode 100644 index 00000000..37174f63 --- /dev/null +++ b/libc/nt/user32/RecordShutdownReason.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RecordShutdownReason,RecordShutdownReason,2245 diff --git a/libc/nt/user32/RedrawWindow.s b/libc/nt/user32/RedrawWindow.s new file mode 100644 index 00000000..092c4843 --- /dev/null +++ b/libc/nt/user32/RedrawWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RedrawWindow,RedrawWindow,2246 diff --git a/libc/nt/user32/RegisterBSDRWindow.s b/libc/nt/user32/RegisterBSDRWindow.s new file mode 100644 index 00000000..0e0100f7 --- /dev/null +++ b/libc/nt/user32/RegisterBSDRWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterBSDRWindow,RegisterBSDRWindow,2247 diff --git a/libc/nt/user32/RegisterClassA.s b/libc/nt/user32/RegisterClassA.s new file mode 100644 index 00000000..bdc2267f --- /dev/null +++ b/libc/nt/user32/RegisterClassA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterClassA,RegisterClassA,2248 diff --git a/libc/nt/user32/RegisterClassExA.s b/libc/nt/user32/RegisterClassExA.s new file mode 100644 index 00000000..8a8c75e3 --- /dev/null +++ b/libc/nt/user32/RegisterClassExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterClassExA,RegisterClassExA,2249 diff --git a/libc/nt/user32/RegisterClassExW.s b/libc/nt/user32/RegisterClassExW.s new file mode 100644 index 00000000..dbd2c382 --- /dev/null +++ b/libc/nt/user32/RegisterClassExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterClassExW,RegisterClassExW,2250 diff --git a/libc/nt/user32/RegisterClassW.s b/libc/nt/user32/RegisterClassW.s new file mode 100644 index 00000000..308f050e --- /dev/null +++ b/libc/nt/user32/RegisterClassW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterClassW,RegisterClassW,2251 diff --git a/libc/nt/user32/RegisterClipboardFormatA.s b/libc/nt/user32/RegisterClipboardFormatA.s new file mode 100644 index 00000000..df44dc3c --- /dev/null +++ b/libc/nt/user32/RegisterClipboardFormatA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterClipboardFormatA,RegisterClipboardFormatA,2252 diff --git a/libc/nt/user32/RegisterClipboardFormatW.s b/libc/nt/user32/RegisterClipboardFormatW.s new file mode 100644 index 00000000..a016a5f3 --- /dev/null +++ b/libc/nt/user32/RegisterClipboardFormatW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterClipboardFormatW,RegisterClipboardFormatW,2253 diff --git a/libc/nt/user32/RegisterDManipHook.s b/libc/nt/user32/RegisterDManipHook.s new file mode 100644 index 00000000..db760f06 --- /dev/null +++ b/libc/nt/user32/RegisterDManipHook.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterDManipHook,RegisterDManipHook,2254 diff --git a/libc/nt/user32/RegisterDeviceNotificationA.s b/libc/nt/user32/RegisterDeviceNotificationA.s new file mode 100644 index 00000000..4e8dab32 --- /dev/null +++ b/libc/nt/user32/RegisterDeviceNotificationA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterDeviceNotificationA,RegisterDeviceNotificationA,2255 diff --git a/libc/nt/user32/RegisterDeviceNotificationW.s b/libc/nt/user32/RegisterDeviceNotificationW.s new file mode 100644 index 00000000..154fa4dc --- /dev/null +++ b/libc/nt/user32/RegisterDeviceNotificationW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterDeviceNotificationW,RegisterDeviceNotificationW,2256 diff --git a/libc/nt/user32/RegisterErrorReportingDialog.s b/libc/nt/user32/RegisterErrorReportingDialog.s new file mode 100644 index 00000000..f06579bf --- /dev/null +++ b/libc/nt/user32/RegisterErrorReportingDialog.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterErrorReportingDialog,RegisterErrorReportingDialog,2257 diff --git a/libc/nt/user32/RegisterFrostWindow.s b/libc/nt/user32/RegisterFrostWindow.s new file mode 100644 index 00000000..a9281be2 --- /dev/null +++ b/libc/nt/user32/RegisterFrostWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterFrostWindow,RegisterFrostWindow,2258 diff --git a/libc/nt/user32/RegisterGhostWindow.s b/libc/nt/user32/RegisterGhostWindow.s new file mode 100644 index 00000000..40ab6555 --- /dev/null +++ b/libc/nt/user32/RegisterGhostWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterGhostWindow,RegisterGhostWindow,2259 diff --git a/libc/nt/user32/RegisterHotKey.s b/libc/nt/user32/RegisterHotKey.s new file mode 100644 index 00000000..4091d4f7 --- /dev/null +++ b/libc/nt/user32/RegisterHotKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterHotKey,RegisterHotKey,2260 diff --git a/libc/nt/user32/RegisterLogonProcess.s b/libc/nt/user32/RegisterLogonProcess.s new file mode 100644 index 00000000..1d07eaa7 --- /dev/null +++ b/libc/nt/user32/RegisterLogonProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterLogonProcess,RegisterLogonProcess,2261 diff --git a/libc/nt/user32/RegisterMessagePumpHook.s b/libc/nt/user32/RegisterMessagePumpHook.s new file mode 100644 index 00000000..0165788c --- /dev/null +++ b/libc/nt/user32/RegisterMessagePumpHook.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterMessagePumpHook,RegisterMessagePumpHook,2262 diff --git a/libc/nt/user32/RegisterPointerDeviceNotifications.s b/libc/nt/user32/RegisterPointerDeviceNotifications.s new file mode 100644 index 00000000..5083bde5 --- /dev/null +++ b/libc/nt/user32/RegisterPointerDeviceNotifications.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterPointerDeviceNotifications,RegisterPointerDeviceNotifications,2263 diff --git a/libc/nt/user32/RegisterPointerInputTarget.s b/libc/nt/user32/RegisterPointerInputTarget.s new file mode 100644 index 00000000..f140a34f --- /dev/null +++ b/libc/nt/user32/RegisterPointerInputTarget.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterPointerInputTarget,RegisterPointerInputTarget,2264 diff --git a/libc/nt/user32/RegisterPointerInputTargetEx.s b/libc/nt/user32/RegisterPointerInputTargetEx.s new file mode 100644 index 00000000..0b482537 --- /dev/null +++ b/libc/nt/user32/RegisterPointerInputTargetEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterPointerInputTargetEx,RegisterPointerInputTargetEx,2265 diff --git a/libc/nt/user32/RegisterPowerSettingNotification.s b/libc/nt/user32/RegisterPowerSettingNotification.s new file mode 100644 index 00000000..ec1307ef --- /dev/null +++ b/libc/nt/user32/RegisterPowerSettingNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterPowerSettingNotification,RegisterPowerSettingNotification,2266 diff --git a/libc/nt/user32/RegisterRawInputDevices.s b/libc/nt/user32/RegisterRawInputDevices.s new file mode 100644 index 00000000..114b2eb9 --- /dev/null +++ b/libc/nt/user32/RegisterRawInputDevices.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterRawInputDevices,RegisterRawInputDevices,2267 diff --git a/libc/nt/user32/RegisterServicesProcess.s b/libc/nt/user32/RegisterServicesProcess.s new file mode 100644 index 00000000..3980db8b --- /dev/null +++ b/libc/nt/user32/RegisterServicesProcess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterServicesProcess,RegisterServicesProcess,2268 diff --git a/libc/nt/user32/RegisterSessionPort.s b/libc/nt/user32/RegisterSessionPort.s new file mode 100644 index 00000000..01ebe03f --- /dev/null +++ b/libc/nt/user32/RegisterSessionPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterSessionPort,RegisterSessionPort,2269 diff --git a/libc/nt/user32/RegisterShellHookWindow.s b/libc/nt/user32/RegisterShellHookWindow.s new file mode 100644 index 00000000..4f1e4a0d --- /dev/null +++ b/libc/nt/user32/RegisterShellHookWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterShellHookWindow,RegisterShellHookWindow,2270 diff --git a/libc/nt/user32/RegisterSuspendResumeNotification.s b/libc/nt/user32/RegisterSuspendResumeNotification.s new file mode 100644 index 00000000..d3c3ff02 --- /dev/null +++ b/libc/nt/user32/RegisterSuspendResumeNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterSuspendResumeNotification,RegisterSuspendResumeNotification,2271 diff --git a/libc/nt/user32/RegisterSystemThread.s b/libc/nt/user32/RegisterSystemThread.s new file mode 100644 index 00000000..f8b6f859 --- /dev/null +++ b/libc/nt/user32/RegisterSystemThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterSystemThread,RegisterSystemThread,2272 diff --git a/libc/nt/user32/RegisterTasklist.s b/libc/nt/user32/RegisterTasklist.s new file mode 100644 index 00000000..969ee6c5 --- /dev/null +++ b/libc/nt/user32/RegisterTasklist.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterTasklist,RegisterTasklist,2273 diff --git a/libc/nt/user32/RegisterTouchHitTestingWindow.s b/libc/nt/user32/RegisterTouchHitTestingWindow.s new file mode 100644 index 00000000..7fdb67a6 --- /dev/null +++ b/libc/nt/user32/RegisterTouchHitTestingWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterTouchHitTestingWindow,RegisterTouchHitTestingWindow,2274 diff --git a/libc/nt/user32/RegisterTouchWindow.s b/libc/nt/user32/RegisterTouchWindow.s new file mode 100644 index 00000000..429f1ded --- /dev/null +++ b/libc/nt/user32/RegisterTouchWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterTouchWindow,RegisterTouchWindow,2275 diff --git a/libc/nt/user32/RegisterUserApiHook.s b/libc/nt/user32/RegisterUserApiHook.s new file mode 100644 index 00000000..01762b5c --- /dev/null +++ b/libc/nt/user32/RegisterUserApiHook.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterUserApiHook,RegisterUserApiHook,2276 diff --git a/libc/nt/user32/RegisterWindowMessageA.s b/libc/nt/user32/RegisterWindowMessageA.s new file mode 100644 index 00000000..a7520a4e --- /dev/null +++ b/libc/nt/user32/RegisterWindowMessageA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterWindowMessageA,RegisterWindowMessageA,2277 diff --git a/libc/nt/user32/RegisterWindowMessageW.s b/libc/nt/user32/RegisterWindowMessageW.s new file mode 100644 index 00000000..45fe0623 --- /dev/null +++ b/libc/nt/user32/RegisterWindowMessageW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RegisterWindowMessageW,RegisterWindowMessageW,2278 diff --git a/libc/nt/user32/ReleaseCapture.s b/libc/nt/user32/ReleaseCapture.s new file mode 100644 index 00000000..afb1b4be --- /dev/null +++ b/libc/nt/user32/ReleaseCapture.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ReleaseCapture,ReleaseCapture,2279 diff --git a/libc/nt/user32/ReleaseDC.s b/libc/nt/user32/ReleaseDC.s new file mode 100644 index 00000000..91729d90 --- /dev/null +++ b/libc/nt/user32/ReleaseDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ReleaseDC,ReleaseDC,2280 diff --git a/libc/nt/user32/ReleaseDwmHitTestWaiters.s b/libc/nt/user32/ReleaseDwmHitTestWaiters.s new file mode 100644 index 00000000..a9e8a88c --- /dev/null +++ b/libc/nt/user32/ReleaseDwmHitTestWaiters.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ReleaseDwmHitTestWaiters,ReleaseDwmHitTestWaiters,2281 diff --git a/libc/nt/user32/RemoveClipboardFormatListener.s b/libc/nt/user32/RemoveClipboardFormatListener.s new file mode 100644 index 00000000..27c22675 --- /dev/null +++ b/libc/nt/user32/RemoveClipboardFormatListener.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RemoveClipboardFormatListener,RemoveClipboardFormatListener,2282 diff --git a/libc/nt/user32/RemoveInjectionDevice.s b/libc/nt/user32/RemoveInjectionDevice.s new file mode 100644 index 00000000..cd8d5d5d --- /dev/null +++ b/libc/nt/user32/RemoveInjectionDevice.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RemoveInjectionDevice,RemoveInjectionDevice,2283 diff --git a/libc/nt/user32/RemoveMenu.s b/libc/nt/user32/RemoveMenu.s new file mode 100644 index 00000000..fa4e43b7 --- /dev/null +++ b/libc/nt/user32/RemoveMenu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RemoveMenu,RemoveMenu,2284 diff --git a/libc/nt/user32/RemovePropA.s b/libc/nt/user32/RemovePropA.s new file mode 100644 index 00000000..9feb0631 --- /dev/null +++ b/libc/nt/user32/RemovePropA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RemovePropA,RemovePropA,2285 diff --git a/libc/nt/user32/RemovePropW.s b/libc/nt/user32/RemovePropW.s new file mode 100644 index 00000000..4ea7384a --- /dev/null +++ b/libc/nt/user32/RemovePropW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RemovePropW,RemovePropW,2286 diff --git a/libc/nt/user32/RemoveThreadTSFEventAwareness.s b/libc/nt/user32/RemoveThreadTSFEventAwareness.s new file mode 100644 index 00000000..92325307 --- /dev/null +++ b/libc/nt/user32/RemoveThreadTSFEventAwareness.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_RemoveThreadTSFEventAwareness,RemoveThreadTSFEventAwareness,2287 diff --git a/libc/nt/user32/ReplyMessage.s b/libc/nt/user32/ReplyMessage.s new file mode 100644 index 00000000..6a515e99 --- /dev/null +++ b/libc/nt/user32/ReplyMessage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ReplyMessage,ReplyMessage,2288 diff --git a/libc/nt/user32/ReportInertia.s b/libc/nt/user32/ReportInertia.s new file mode 100644 index 00000000..f8d8a292 --- /dev/null +++ b/libc/nt/user32/ReportInertia.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ReportInertia,ReportInertia,2551 diff --git a/libc/nt/user32/ResolveDesktopForWOW.s b/libc/nt/user32/ResolveDesktopForWOW.s new file mode 100644 index 00000000..680c9ab4 --- /dev/null +++ b/libc/nt/user32/ResolveDesktopForWOW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ResolveDesktopForWOW,ResolveDesktopForWOW,2289 diff --git a/libc/nt/user32/ReuseDDElParam.s b/libc/nt/user32/ReuseDDElParam.s new file mode 100644 index 00000000..e843b5e0 --- /dev/null +++ b/libc/nt/user32/ReuseDDElParam.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ReuseDDElParam,ReuseDDElParam,2290 diff --git a/libc/nt/user32/ScreenToClient.s b/libc/nt/user32/ScreenToClient.s new file mode 100644 index 00000000..5e9c3b64 --- /dev/null +++ b/libc/nt/user32/ScreenToClient.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ScreenToClient,ScreenToClient,2291 diff --git a/libc/nt/user32/ScrollChildren.s b/libc/nt/user32/ScrollChildren.s new file mode 100644 index 00000000..b19c0409 --- /dev/null +++ b/libc/nt/user32/ScrollChildren.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ScrollChildren,ScrollChildren,2292 diff --git a/libc/nt/user32/ScrollDC.s b/libc/nt/user32/ScrollDC.s new file mode 100644 index 00000000..c69c9bf4 --- /dev/null +++ b/libc/nt/user32/ScrollDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ScrollDC,ScrollDC,2293 diff --git a/libc/nt/user32/ScrollWindow.s b/libc/nt/user32/ScrollWindow.s new file mode 100644 index 00000000..a19f96b5 --- /dev/null +++ b/libc/nt/user32/ScrollWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ScrollWindow,ScrollWindow,2294 diff --git a/libc/nt/user32/ScrollWindowEx.s b/libc/nt/user32/ScrollWindowEx.s new file mode 100644 index 00000000..a1c174d4 --- /dev/null +++ b/libc/nt/user32/ScrollWindowEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ScrollWindowEx,ScrollWindowEx,2295 diff --git a/libc/nt/user32/SendDlgItemMessageA.s b/libc/nt/user32/SendDlgItemMessageA.s new file mode 100644 index 00000000..0365be78 --- /dev/null +++ b/libc/nt/user32/SendDlgItemMessageA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SendDlgItemMessageA,SendDlgItemMessageA,2296 diff --git a/libc/nt/user32/SendDlgItemMessageW.s b/libc/nt/user32/SendDlgItemMessageW.s new file mode 100644 index 00000000..63208612 --- /dev/null +++ b/libc/nt/user32/SendDlgItemMessageW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SendDlgItemMessageW,SendDlgItemMessageW,2297 diff --git a/libc/nt/user32/SendIMEMessageExA.s b/libc/nt/user32/SendIMEMessageExA.s new file mode 100644 index 00000000..a9432360 --- /dev/null +++ b/libc/nt/user32/SendIMEMessageExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SendIMEMessageExA,SendIMEMessageExA,2298 diff --git a/libc/nt/user32/SendIMEMessageExW.s b/libc/nt/user32/SendIMEMessageExW.s new file mode 100644 index 00000000..ae515264 --- /dev/null +++ b/libc/nt/user32/SendIMEMessageExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SendIMEMessageExW,SendIMEMessageExW,2299 diff --git a/libc/nt/user32/SendInput.s b/libc/nt/user32/SendInput.s new file mode 100644 index 00000000..2daca245 --- /dev/null +++ b/libc/nt/user32/SendInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SendInput,SendInput,2300 diff --git a/libc/nt/user32/SendMessageA.s b/libc/nt/user32/SendMessageA.s new file mode 100644 index 00000000..d854968f --- /dev/null +++ b/libc/nt/user32/SendMessageA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SendMessageA,SendMessageA,2301 diff --git a/libc/nt/user32/SendMessageCallbackA.s b/libc/nt/user32/SendMessageCallbackA.s new file mode 100644 index 00000000..83d7c30a --- /dev/null +++ b/libc/nt/user32/SendMessageCallbackA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SendMessageCallbackA,SendMessageCallbackA,2302 diff --git a/libc/nt/user32/SendMessageCallbackW.s b/libc/nt/user32/SendMessageCallbackW.s new file mode 100644 index 00000000..eeb6853f --- /dev/null +++ b/libc/nt/user32/SendMessageCallbackW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SendMessageCallbackW,SendMessageCallbackW,2303 diff --git a/libc/nt/user32/SendMessageTimeoutA.s b/libc/nt/user32/SendMessageTimeoutA.s new file mode 100644 index 00000000..01d07bd1 --- /dev/null +++ b/libc/nt/user32/SendMessageTimeoutA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SendMessageTimeoutA,SendMessageTimeoutA,2304 diff --git a/libc/nt/user32/SendMessageTimeoutW.s b/libc/nt/user32/SendMessageTimeoutW.s new file mode 100644 index 00000000..709dd772 --- /dev/null +++ b/libc/nt/user32/SendMessageTimeoutW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SendMessageTimeoutW,SendMessageTimeoutW,2305 diff --git a/libc/nt/user32/SendMessageW.s b/libc/nt/user32/SendMessageW.s new file mode 100644 index 00000000..68eccca1 --- /dev/null +++ b/libc/nt/user32/SendMessageW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SendMessageW,SendMessageW,2306 diff --git a/libc/nt/user32/SendNotifyMessageA.s b/libc/nt/user32/SendNotifyMessageA.s new file mode 100644 index 00000000..d760ff4b --- /dev/null +++ b/libc/nt/user32/SendNotifyMessageA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SendNotifyMessageA,SendNotifyMessageA,2307 diff --git a/libc/nt/user32/SendNotifyMessageW.s b/libc/nt/user32/SendNotifyMessageW.s new file mode 100644 index 00000000..07376784 --- /dev/null +++ b/libc/nt/user32/SendNotifyMessageW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SendNotifyMessageW,SendNotifyMessageW,2308 diff --git a/libc/nt/user32/SetActiveWindow.s b/libc/nt/user32/SetActiveWindow.s new file mode 100644 index 00000000..8d2234d0 --- /dev/null +++ b/libc/nt/user32/SetActiveWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetActiveWindow,SetActiveWindow,2309 diff --git a/libc/nt/user32/SetCapture.s b/libc/nt/user32/SetCapture.s new file mode 100644 index 00000000..c92c51f3 --- /dev/null +++ b/libc/nt/user32/SetCapture.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetCapture,SetCapture,2310 diff --git a/libc/nt/user32/SetCaretBlinkTime.s b/libc/nt/user32/SetCaretBlinkTime.s new file mode 100644 index 00000000..9d8c4151 --- /dev/null +++ b/libc/nt/user32/SetCaretBlinkTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetCaretBlinkTime,SetCaretBlinkTime,2311 diff --git a/libc/nt/user32/SetCaretPos.s b/libc/nt/user32/SetCaretPos.s new file mode 100644 index 00000000..1127e869 --- /dev/null +++ b/libc/nt/user32/SetCaretPos.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetCaretPos,SetCaretPos,2312 diff --git a/libc/nt/user32/SetClassLongA.s b/libc/nt/user32/SetClassLongA.s new file mode 100644 index 00000000..306142f6 --- /dev/null +++ b/libc/nt/user32/SetClassLongA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetClassLongA,SetClassLongA,2313 diff --git a/libc/nt/user32/SetClassLongPtrA.s b/libc/nt/user32/SetClassLongPtrA.s new file mode 100644 index 00000000..94b92806 --- /dev/null +++ b/libc/nt/user32/SetClassLongPtrA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetClassLongPtrA,SetClassLongPtrA,2314 diff --git a/libc/nt/user32/SetClassLongPtrW.s b/libc/nt/user32/SetClassLongPtrW.s new file mode 100644 index 00000000..a2e292cd --- /dev/null +++ b/libc/nt/user32/SetClassLongPtrW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetClassLongPtrW,SetClassLongPtrW,2315 diff --git a/libc/nt/user32/SetClassLongW.s b/libc/nt/user32/SetClassLongW.s new file mode 100644 index 00000000..0c6e0dde --- /dev/null +++ b/libc/nt/user32/SetClassLongW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetClassLongW,SetClassLongW,2316 diff --git a/libc/nt/user32/SetClassWord.s b/libc/nt/user32/SetClassWord.s new file mode 100644 index 00000000..bb673f53 --- /dev/null +++ b/libc/nt/user32/SetClassWord.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetClassWord,SetClassWord,2317 diff --git a/libc/nt/user32/SetClipboardData.s b/libc/nt/user32/SetClipboardData.s new file mode 100644 index 00000000..861b7b01 --- /dev/null +++ b/libc/nt/user32/SetClipboardData.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetClipboardData,SetClipboardData,2318 diff --git a/libc/nt/user32/SetClipboardViewer.s b/libc/nt/user32/SetClipboardViewer.s new file mode 100644 index 00000000..13f3722a --- /dev/null +++ b/libc/nt/user32/SetClipboardViewer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetClipboardViewer,SetClipboardViewer,2319 diff --git a/libc/nt/user32/SetCoalescableTimer.s b/libc/nt/user32/SetCoalescableTimer.s new file mode 100644 index 00000000..1ceb8bb4 --- /dev/null +++ b/libc/nt/user32/SetCoalescableTimer.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetCoalescableTimer,SetCoalescableTimer,2320 diff --git a/libc/nt/user32/SetCoreWindow.s b/libc/nt/user32/SetCoreWindow.s new file mode 100644 index 00000000..ac10f33b --- /dev/null +++ b/libc/nt/user32/SetCoreWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetCoreWindow,SetCoreWindow,2571 diff --git a/libc/nt/user32/SetCursor.s b/libc/nt/user32/SetCursor.s new file mode 100644 index 00000000..2b9a20f3 --- /dev/null +++ b/libc/nt/user32/SetCursor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetCursor,SetCursor,2321 diff --git a/libc/nt/user32/SetCursorContents.s b/libc/nt/user32/SetCursorContents.s new file mode 100644 index 00000000..9aad5302 --- /dev/null +++ b/libc/nt/user32/SetCursorContents.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetCursorContents,SetCursorContents,2322 diff --git a/libc/nt/user32/SetCursorPos.s b/libc/nt/user32/SetCursorPos.s new file mode 100644 index 00000000..893b7743 --- /dev/null +++ b/libc/nt/user32/SetCursorPos.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetCursorPos,SetCursorPos,2323 diff --git a/libc/nt/user32/SetDebugErrorLevel.s b/libc/nt/user32/SetDebugErrorLevel.s new file mode 100644 index 00000000..4806d60f --- /dev/null +++ b/libc/nt/user32/SetDebugErrorLevel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetDebugErrorLevel,SetDebugErrorLevel,2324 diff --git a/libc/nt/user32/SetDeskWallpaper.s b/libc/nt/user32/SetDeskWallpaper.s new file mode 100644 index 00000000..ea49b6d2 --- /dev/null +++ b/libc/nt/user32/SetDeskWallpaper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetDeskWallpaper,SetDeskWallpaper,2325 diff --git a/libc/nt/user32/SetDesktopColorTransform.s b/libc/nt/user32/SetDesktopColorTransform.s new file mode 100644 index 00000000..82dfe6a5 --- /dev/null +++ b/libc/nt/user32/SetDesktopColorTransform.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetDesktopColorTransform,SetDesktopColorTransform,2326 diff --git a/libc/nt/user32/SetDialogControlDpiChangeBehavior.s b/libc/nt/user32/SetDialogControlDpiChangeBehavior.s new file mode 100644 index 00000000..2165529c --- /dev/null +++ b/libc/nt/user32/SetDialogControlDpiChangeBehavior.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetDialogControlDpiChangeBehavior,SetDialogControlDpiChangeBehavior,2327 diff --git a/libc/nt/user32/SetDialogDpiChangeBehavior.s b/libc/nt/user32/SetDialogDpiChangeBehavior.s new file mode 100644 index 00000000..b43f5eee --- /dev/null +++ b/libc/nt/user32/SetDialogDpiChangeBehavior.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetDialogDpiChangeBehavior,SetDialogDpiChangeBehavior,2328 diff --git a/libc/nt/user32/SetDisplayAutoRotationPreferences.s b/libc/nt/user32/SetDisplayAutoRotationPreferences.s new file mode 100644 index 00000000..22d40375 --- /dev/null +++ b/libc/nt/user32/SetDisplayAutoRotationPreferences.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetDisplayAutoRotationPreferences,SetDisplayAutoRotationPreferences,2329 diff --git a/libc/nt/user32/SetDisplayConfig.s b/libc/nt/user32/SetDisplayConfig.s new file mode 100644 index 00000000..70a31828 --- /dev/null +++ b/libc/nt/user32/SetDisplayConfig.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetDisplayConfig,SetDisplayConfig,2330 diff --git a/libc/nt/user32/SetDlgItemInt.s b/libc/nt/user32/SetDlgItemInt.s new file mode 100644 index 00000000..24aecfa9 --- /dev/null +++ b/libc/nt/user32/SetDlgItemInt.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetDlgItemInt,SetDlgItemInt,2331 diff --git a/libc/nt/user32/SetDlgItemTextA.s b/libc/nt/user32/SetDlgItemTextA.s new file mode 100644 index 00000000..b5c158d5 --- /dev/null +++ b/libc/nt/user32/SetDlgItemTextA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetDlgItemTextA,SetDlgItemTextA,2332 diff --git a/libc/nt/user32/SetDlgItemTextW.s b/libc/nt/user32/SetDlgItemTextW.s new file mode 100644 index 00000000..3e6660a3 --- /dev/null +++ b/libc/nt/user32/SetDlgItemTextW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetDlgItemTextW,SetDlgItemTextW,2333 diff --git a/libc/nt/user32/SetDoubleClickTime.s b/libc/nt/user32/SetDoubleClickTime.s new file mode 100644 index 00000000..3bfa9ba3 --- /dev/null +++ b/libc/nt/user32/SetDoubleClickTime.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetDoubleClickTime,SetDoubleClickTime,2334 diff --git a/libc/nt/user32/SetFeatureReportResponse.s b/libc/nt/user32/SetFeatureReportResponse.s new file mode 100644 index 00000000..432045c5 --- /dev/null +++ b/libc/nt/user32/SetFeatureReportResponse.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetFeatureReportResponse,SetFeatureReportResponse,2335 diff --git a/libc/nt/user32/SetFocus.s b/libc/nt/user32/SetFocus.s new file mode 100644 index 00000000..e4239416 --- /dev/null +++ b/libc/nt/user32/SetFocus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetFocus,SetFocus,2336 diff --git a/libc/nt/user32/SetForegroundWindow.s b/libc/nt/user32/SetForegroundWindow.s new file mode 100644 index 00000000..9486058e --- /dev/null +++ b/libc/nt/user32/SetForegroundWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetForegroundWindow,SetForegroundWindow,2337 diff --git a/libc/nt/user32/SetGestureConfig.s b/libc/nt/user32/SetGestureConfig.s new file mode 100644 index 00000000..554d948e --- /dev/null +++ b/libc/nt/user32/SetGestureConfig.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetGestureConfig,SetGestureConfig,2338 diff --git a/libc/nt/user32/SetInternalWindowPos.s b/libc/nt/user32/SetInternalWindowPos.s new file mode 100644 index 00000000..3e31c93c --- /dev/null +++ b/libc/nt/user32/SetInternalWindowPos.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetInternalWindowPos,SetInternalWindowPos,2339 diff --git a/libc/nt/user32/SetKeyboardState.s b/libc/nt/user32/SetKeyboardState.s new file mode 100644 index 00000000..2740877e --- /dev/null +++ b/libc/nt/user32/SetKeyboardState.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetKeyboardState,SetKeyboardState,2340 diff --git a/libc/nt/user32/SetLastErrorEx.s b/libc/nt/user32/SetLastErrorEx.s new file mode 100644 index 00000000..6b45a0aa --- /dev/null +++ b/libc/nt/user32/SetLastErrorEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetLastErrorEx,SetLastErrorEx,2341 diff --git a/libc/nt/user32/SetLayeredWindowAttributes.s b/libc/nt/user32/SetLayeredWindowAttributes.s new file mode 100644 index 00000000..65bbc13c --- /dev/null +++ b/libc/nt/user32/SetLayeredWindowAttributes.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetLayeredWindowAttributes,SetLayeredWindowAttributes,2342 diff --git a/libc/nt/user32/SetMagnificationDesktopColorEffect.s b/libc/nt/user32/SetMagnificationDesktopColorEffect.s new file mode 100644 index 00000000..90ca19be --- /dev/null +++ b/libc/nt/user32/SetMagnificationDesktopColorEffect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetMagnificationDesktopColorEffect,SetMagnificationDesktopColorEffect,2343 diff --git a/libc/nt/user32/SetMagnificationDesktopMagnification.s b/libc/nt/user32/SetMagnificationDesktopMagnification.s new file mode 100644 index 00000000..9e3f3f15 --- /dev/null +++ b/libc/nt/user32/SetMagnificationDesktopMagnification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetMagnificationDesktopMagnification,SetMagnificationDesktopMagnification,2344 diff --git a/libc/nt/user32/SetMagnificationDesktopSamplingMode.s b/libc/nt/user32/SetMagnificationDesktopSamplingMode.s new file mode 100644 index 00000000..4f056436 --- /dev/null +++ b/libc/nt/user32/SetMagnificationDesktopSamplingMode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetMagnificationDesktopSamplingMode,SetMagnificationDesktopSamplingMode,2345 diff --git a/libc/nt/user32/SetMagnificationLensCtxInformation.s b/libc/nt/user32/SetMagnificationLensCtxInformation.s new file mode 100644 index 00000000..af74da7d --- /dev/null +++ b/libc/nt/user32/SetMagnificationLensCtxInformation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetMagnificationLensCtxInformation,SetMagnificationLensCtxInformation,2346 diff --git a/libc/nt/user32/SetMenu.s b/libc/nt/user32/SetMenu.s new file mode 100644 index 00000000..f0068d0e --- /dev/null +++ b/libc/nt/user32/SetMenu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetMenu,SetMenu,2347 diff --git a/libc/nt/user32/SetMenuContextHelpId.s b/libc/nt/user32/SetMenuContextHelpId.s new file mode 100644 index 00000000..901e402c --- /dev/null +++ b/libc/nt/user32/SetMenuContextHelpId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetMenuContextHelpId,SetMenuContextHelpId,2348 diff --git a/libc/nt/user32/SetMenuDefaultItem.s b/libc/nt/user32/SetMenuDefaultItem.s new file mode 100644 index 00000000..a652724d --- /dev/null +++ b/libc/nt/user32/SetMenuDefaultItem.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetMenuDefaultItem,SetMenuDefaultItem,2349 diff --git a/libc/nt/user32/SetMenuInfo.s b/libc/nt/user32/SetMenuInfo.s new file mode 100644 index 00000000..bf2d4999 --- /dev/null +++ b/libc/nt/user32/SetMenuInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetMenuInfo,SetMenuInfo,2350 diff --git a/libc/nt/user32/SetMenuItemBitmaps.s b/libc/nt/user32/SetMenuItemBitmaps.s new file mode 100644 index 00000000..6ce5de9e --- /dev/null +++ b/libc/nt/user32/SetMenuItemBitmaps.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetMenuItemBitmaps,SetMenuItemBitmaps,2351 diff --git a/libc/nt/user32/SetMenuItemInfoA.s b/libc/nt/user32/SetMenuItemInfoA.s new file mode 100644 index 00000000..32207919 --- /dev/null +++ b/libc/nt/user32/SetMenuItemInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetMenuItemInfoA,SetMenuItemInfoA,2352 diff --git a/libc/nt/user32/SetMenuItemInfoW.s b/libc/nt/user32/SetMenuItemInfoW.s new file mode 100644 index 00000000..4411401e --- /dev/null +++ b/libc/nt/user32/SetMenuItemInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetMenuItemInfoW,SetMenuItemInfoW,2353 diff --git a/libc/nt/user32/SetMessageExtraInfo.s b/libc/nt/user32/SetMessageExtraInfo.s new file mode 100644 index 00000000..e41d7a0b --- /dev/null +++ b/libc/nt/user32/SetMessageExtraInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetMessageExtraInfo,SetMessageExtraInfo,2354 diff --git a/libc/nt/user32/SetMessageQueue.s b/libc/nt/user32/SetMessageQueue.s new file mode 100644 index 00000000..9245c205 --- /dev/null +++ b/libc/nt/user32/SetMessageQueue.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetMessageQueue,SetMessageQueue,2355 diff --git a/libc/nt/user32/SetMirrorRendering.s b/libc/nt/user32/SetMirrorRendering.s new file mode 100644 index 00000000..774936d1 --- /dev/null +++ b/libc/nt/user32/SetMirrorRendering.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetMirrorRendering,SetMirrorRendering,2356 diff --git a/libc/nt/user32/SetParent.s b/libc/nt/user32/SetParent.s new file mode 100644 index 00000000..2a4b6006 --- /dev/null +++ b/libc/nt/user32/SetParent.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetParent,SetParent,2357 + + .text.windows +SetParent: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetParent(%rip),%rax + jmp __sysv2nt + .endfn SetParent,globl + .previous diff --git a/libc/nt/user32/SetPhysicalCursorPos.s b/libc/nt/user32/SetPhysicalCursorPos.s new file mode 100644 index 00000000..1835ef74 --- /dev/null +++ b/libc/nt/user32/SetPhysicalCursorPos.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetPhysicalCursorPos,SetPhysicalCursorPos,2358 diff --git a/libc/nt/user32/SetProcessDPIAware.s b/libc/nt/user32/SetProcessDPIAware.s new file mode 100644 index 00000000..4bcbab61 --- /dev/null +++ b/libc/nt/user32/SetProcessDPIAware.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetProcessDPIAware,SetProcessDPIAware,2359 diff --git a/libc/nt/user32/SetProcessDefaultLayout.s b/libc/nt/user32/SetProcessDefaultLayout.s new file mode 100644 index 00000000..578dd2bf --- /dev/null +++ b/libc/nt/user32/SetProcessDefaultLayout.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetProcessDefaultLayout,SetProcessDefaultLayout,2360 diff --git a/libc/nt/user32/SetProcessDpiAwarenessContext.s b/libc/nt/user32/SetProcessDpiAwarenessContext.s new file mode 100644 index 00000000..8f7475d0 --- /dev/null +++ b/libc/nt/user32/SetProcessDpiAwarenessContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetProcessDpiAwarenessContext,SetProcessDpiAwarenessContext,2361 diff --git a/libc/nt/user32/SetProcessDpiAwarenessInternal.s b/libc/nt/user32/SetProcessDpiAwarenessInternal.s new file mode 100644 index 00000000..30949bd4 --- /dev/null +++ b/libc/nt/user32/SetProcessDpiAwarenessInternal.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetProcessDpiAwarenessInternal,SetProcessDpiAwarenessInternal,2362 diff --git a/libc/nt/user32/SetProcessRestrictionExemption.s b/libc/nt/user32/SetProcessRestrictionExemption.s new file mode 100644 index 00000000..3fed77dd --- /dev/null +++ b/libc/nt/user32/SetProcessRestrictionExemption.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetProcessRestrictionExemption,SetProcessRestrictionExemption,2363 diff --git a/libc/nt/user32/SetProcessWindowStation.s b/libc/nt/user32/SetProcessWindowStation.s new file mode 100644 index 00000000..71e40e68 --- /dev/null +++ b/libc/nt/user32/SetProcessWindowStation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetProcessWindowStation,SetProcessWindowStation,2364 diff --git a/libc/nt/user32/SetProgmanWindow.s b/libc/nt/user32/SetProgmanWindow.s new file mode 100644 index 00000000..7dc4ec04 --- /dev/null +++ b/libc/nt/user32/SetProgmanWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetProgmanWindow,SetProgmanWindow,2365 diff --git a/libc/nt/user32/SetPropA.s b/libc/nt/user32/SetPropA.s new file mode 100644 index 00000000..445f16e4 --- /dev/null +++ b/libc/nt/user32/SetPropA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetPropA,SetPropA,2366 diff --git a/libc/nt/user32/SetPropW.s b/libc/nt/user32/SetPropW.s new file mode 100644 index 00000000..4c432931 --- /dev/null +++ b/libc/nt/user32/SetPropW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetPropW,SetPropW,2367 diff --git a/libc/nt/user32/SetRect.s b/libc/nt/user32/SetRect.s new file mode 100644 index 00000000..7503f03d --- /dev/null +++ b/libc/nt/user32/SetRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetRect,SetRect,2368 diff --git a/libc/nt/user32/SetRectEmpty.s b/libc/nt/user32/SetRectEmpty.s new file mode 100644 index 00000000..d4198aed --- /dev/null +++ b/libc/nt/user32/SetRectEmpty.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetRectEmpty,SetRectEmpty,2369 diff --git a/libc/nt/user32/SetScrollInfo.s b/libc/nt/user32/SetScrollInfo.s new file mode 100644 index 00000000..c6128c5c --- /dev/null +++ b/libc/nt/user32/SetScrollInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetScrollInfo,SetScrollInfo,2370 diff --git a/libc/nt/user32/SetScrollPos.s b/libc/nt/user32/SetScrollPos.s new file mode 100644 index 00000000..95028538 --- /dev/null +++ b/libc/nt/user32/SetScrollPos.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetScrollPos,SetScrollPos,2371 diff --git a/libc/nt/user32/SetScrollRange.s b/libc/nt/user32/SetScrollRange.s new file mode 100644 index 00000000..5d93a5ab --- /dev/null +++ b/libc/nt/user32/SetScrollRange.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetScrollRange,SetScrollRange,2372 diff --git a/libc/nt/user32/SetShellWindow.s b/libc/nt/user32/SetShellWindow.s new file mode 100644 index 00000000..2a749d16 --- /dev/null +++ b/libc/nt/user32/SetShellWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetShellWindow,SetShellWindow,2373 diff --git a/libc/nt/user32/SetShellWindowEx.s b/libc/nt/user32/SetShellWindowEx.s new file mode 100644 index 00000000..45ffcf90 --- /dev/null +++ b/libc/nt/user32/SetShellWindowEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetShellWindowEx,SetShellWindowEx,2374 diff --git a/libc/nt/user32/SetSysColors.s b/libc/nt/user32/SetSysColors.s new file mode 100644 index 00000000..558957d1 --- /dev/null +++ b/libc/nt/user32/SetSysColors.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetSysColors,SetSysColors,2375 diff --git a/libc/nt/user32/SetSysColorsTemp.s b/libc/nt/user32/SetSysColorsTemp.s new file mode 100644 index 00000000..48cbe450 --- /dev/null +++ b/libc/nt/user32/SetSysColorsTemp.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetSysColorsTemp,SetSysColorsTemp,2376 diff --git a/libc/nt/user32/SetSystemCursor.s b/libc/nt/user32/SetSystemCursor.s new file mode 100644 index 00000000..f85c3462 --- /dev/null +++ b/libc/nt/user32/SetSystemCursor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetSystemCursor,SetSystemCursor,2377 diff --git a/libc/nt/user32/SetSystemMenu.s b/libc/nt/user32/SetSystemMenu.s new file mode 100644 index 00000000..4855f403 --- /dev/null +++ b/libc/nt/user32/SetSystemMenu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetSystemMenu,SetSystemMenu,2378 diff --git a/libc/nt/user32/SetTaskmanWindow.s b/libc/nt/user32/SetTaskmanWindow.s new file mode 100644 index 00000000..2e36ad97 --- /dev/null +++ b/libc/nt/user32/SetTaskmanWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetTaskmanWindow,SetTaskmanWindow,2379 diff --git a/libc/nt/user32/SetThreadDesktop.s b/libc/nt/user32/SetThreadDesktop.s new file mode 100644 index 00000000..cd06c575 --- /dev/null +++ b/libc/nt/user32/SetThreadDesktop.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetThreadDesktop,SetThreadDesktop,2380 diff --git a/libc/nt/user32/SetThreadDpiAwarenessContext.s b/libc/nt/user32/SetThreadDpiAwarenessContext.s new file mode 100644 index 00000000..7c7a2733 --- /dev/null +++ b/libc/nt/user32/SetThreadDpiAwarenessContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetThreadDpiAwarenessContext,SetThreadDpiAwarenessContext,2381 diff --git a/libc/nt/user32/SetThreadDpiHostingBehavior.s b/libc/nt/user32/SetThreadDpiHostingBehavior.s new file mode 100644 index 00000000..20d52d67 --- /dev/null +++ b/libc/nt/user32/SetThreadDpiHostingBehavior.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetThreadDpiHostingBehavior,SetThreadDpiHostingBehavior,2382 diff --git a/libc/nt/user32/SetThreadInputBlocked.s b/libc/nt/user32/SetThreadInputBlocked.s new file mode 100644 index 00000000..22fd5fc6 --- /dev/null +++ b/libc/nt/user32/SetThreadInputBlocked.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetThreadInputBlocked,SetThreadInputBlocked,2383 diff --git a/libc/nt/user32/SetTimer.s b/libc/nt/user32/SetTimer.s new file mode 100644 index 00000000..6dc97c88 --- /dev/null +++ b/libc/nt/user32/SetTimer.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetTimer,SetTimer,2384 + + .text.windows +SetTimer: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetTimer(%rip),%rax + jmp __sysv2nt + .endfn SetTimer,globl + .previous diff --git a/libc/nt/user32/SetUserObjectInformationA.s b/libc/nt/user32/SetUserObjectInformationA.s new file mode 100644 index 00000000..6ec7b556 --- /dev/null +++ b/libc/nt/user32/SetUserObjectInformationA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetUserObjectInformationA,SetUserObjectInformationA,2385 diff --git a/libc/nt/user32/SetUserObjectInformationW.s b/libc/nt/user32/SetUserObjectInformationW.s new file mode 100644 index 00000000..f0d7f1eb --- /dev/null +++ b/libc/nt/user32/SetUserObjectInformationW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetUserObjectInformationW,SetUserObjectInformationW,2386 diff --git a/libc/nt/user32/SetUserObjectSecurity.s b/libc/nt/user32/SetUserObjectSecurity.s new file mode 100644 index 00000000..3672f462 --- /dev/null +++ b/libc/nt/user32/SetUserObjectSecurity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetUserObjectSecurity,SetUserObjectSecurity,2387 diff --git a/libc/nt/user32/SetWinEventHook.s b/libc/nt/user32/SetWinEventHook.s new file mode 100644 index 00000000..3bbc0301 --- /dev/null +++ b/libc/nt/user32/SetWinEventHook.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWinEventHook,SetWinEventHook,2388 diff --git a/libc/nt/user32/SetWindowBand.s b/libc/nt/user32/SetWindowBand.s new file mode 100644 index 00000000..742e57f6 --- /dev/null +++ b/libc/nt/user32/SetWindowBand.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowBand,SetWindowBand,2389 diff --git a/libc/nt/user32/SetWindowCompositionAttribute.s b/libc/nt/user32/SetWindowCompositionAttribute.s new file mode 100644 index 00000000..aa98ccf1 --- /dev/null +++ b/libc/nt/user32/SetWindowCompositionAttribute.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowCompositionAttribute,SetWindowCompositionAttribute,2390 diff --git a/libc/nt/user32/SetWindowCompositionTransition.s b/libc/nt/user32/SetWindowCompositionTransition.s new file mode 100644 index 00000000..81f0a8ae --- /dev/null +++ b/libc/nt/user32/SetWindowCompositionTransition.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowCompositionTransition,SetWindowCompositionTransition,2391 diff --git a/libc/nt/user32/SetWindowContextHelpId.s b/libc/nt/user32/SetWindowContextHelpId.s new file mode 100644 index 00000000..c443e113 --- /dev/null +++ b/libc/nt/user32/SetWindowContextHelpId.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowContextHelpId,SetWindowContextHelpId,2392 diff --git a/libc/nt/user32/SetWindowDisplayAffinity.s b/libc/nt/user32/SetWindowDisplayAffinity.s new file mode 100644 index 00000000..0809d37d --- /dev/null +++ b/libc/nt/user32/SetWindowDisplayAffinity.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowDisplayAffinity,SetWindowDisplayAffinity,2393 diff --git a/libc/nt/user32/SetWindowFeedbackSetting.s b/libc/nt/user32/SetWindowFeedbackSetting.s new file mode 100644 index 00000000..2356f0d9 --- /dev/null +++ b/libc/nt/user32/SetWindowFeedbackSetting.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowFeedbackSetting,SetWindowFeedbackSetting,2394 diff --git a/libc/nt/user32/SetWindowLongA.s b/libc/nt/user32/SetWindowLongA.s new file mode 100644 index 00000000..28deade3 --- /dev/null +++ b/libc/nt/user32/SetWindowLongA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowLongA,SetWindowLongA,2395 diff --git a/libc/nt/user32/SetWindowLongPtrA.s b/libc/nt/user32/SetWindowLongPtrA.s new file mode 100644 index 00000000..252441d8 --- /dev/null +++ b/libc/nt/user32/SetWindowLongPtrA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowLongPtrA,SetWindowLongPtrA,2396 diff --git a/libc/nt/user32/SetWindowLongPtrW.s b/libc/nt/user32/SetWindowLongPtrW.s new file mode 100644 index 00000000..6e18c83c --- /dev/null +++ b/libc/nt/user32/SetWindowLongPtrW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowLongPtrW,SetWindowLongPtrW,2397 diff --git a/libc/nt/user32/SetWindowLongW.s b/libc/nt/user32/SetWindowLongW.s new file mode 100644 index 00000000..d911b0fc --- /dev/null +++ b/libc/nt/user32/SetWindowLongW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowLongW,SetWindowLongW,2398 diff --git a/libc/nt/user32/SetWindowPlacement.s b/libc/nt/user32/SetWindowPlacement.s new file mode 100644 index 00000000..648f9b5d --- /dev/null +++ b/libc/nt/user32/SetWindowPlacement.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowPlacement,SetWindowPlacement,2399 diff --git a/libc/nt/user32/SetWindowPos.s b/libc/nt/user32/SetWindowPos.s new file mode 100644 index 00000000..e6a14d30 --- /dev/null +++ b/libc/nt/user32/SetWindowPos.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowPos,SetWindowPos,2400 + + .text.windows +SetWindowPos: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetWindowPos(%rip),%rax + jmp __sysv2nt8 + .endfn SetWindowPos,globl + .previous diff --git a/libc/nt/user32/SetWindowRgn.s b/libc/nt/user32/SetWindowRgn.s new file mode 100644 index 00000000..0367d891 --- /dev/null +++ b/libc/nt/user32/SetWindowRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowRgn,SetWindowRgn,2401 diff --git a/libc/nt/user32/SetWindowRgnEx.s b/libc/nt/user32/SetWindowRgnEx.s new file mode 100644 index 00000000..e3b4ce97 --- /dev/null +++ b/libc/nt/user32/SetWindowRgnEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowRgnEx,SetWindowRgnEx,2402 diff --git a/libc/nt/user32/SetWindowStationUser.s b/libc/nt/user32/SetWindowStationUser.s new file mode 100644 index 00000000..77dfaf17 --- /dev/null +++ b/libc/nt/user32/SetWindowStationUser.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowStationUser,SetWindowStationUser,2403 diff --git a/libc/nt/user32/SetWindowTextA.s b/libc/nt/user32/SetWindowTextA.s new file mode 100644 index 00000000..b5c4040b --- /dev/null +++ b/libc/nt/user32/SetWindowTextA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowTextA,SetWindowTextA,2404 + + .text.windows +SetWindowTextA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetWindowTextA(%rip),%rax + jmp __sysv2nt + .endfn SetWindowTextA,globl + .previous diff --git a/libc/nt/user32/SetWindowTextW.s b/libc/nt/user32/SetWindowTextW.s new file mode 100644 index 00000000..8b861be4 --- /dev/null +++ b/libc/nt/user32/SetWindowTextW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowTextW,SetWindowTextW,2405 + + .text.windows +SetWindowText: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetWindowTextW(%rip),%rax + jmp __sysv2nt + .endfn SetWindowText,globl + .previous diff --git a/libc/nt/user32/SetWindowWord.s b/libc/nt/user32/SetWindowWord.s new file mode 100644 index 00000000..7ca9b7f9 --- /dev/null +++ b/libc/nt/user32/SetWindowWord.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowWord,SetWindowWord,2406 diff --git a/libc/nt/user32/SetWindowsHookA.s b/libc/nt/user32/SetWindowsHookA.s new file mode 100644 index 00000000..37ca05f8 --- /dev/null +++ b/libc/nt/user32/SetWindowsHookA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowsHookA,SetWindowsHookA,2407 + + .text.windows +SetWindowsHookA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetWindowsHookA(%rip),%rax + jmp __sysv2nt + .endfn SetWindowsHookA,globl + .previous diff --git a/libc/nt/user32/SetWindowsHookExA.s b/libc/nt/user32/SetWindowsHookExA.s new file mode 100644 index 00000000..21b73239 --- /dev/null +++ b/libc/nt/user32/SetWindowsHookExA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowsHookExA,SetWindowsHookExA,2408 + + .text.windows +SetWindowsHookExA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetWindowsHookExA(%rip),%rax + jmp __sysv2nt + .endfn SetWindowsHookExA,globl + .previous diff --git a/libc/nt/user32/SetWindowsHookExW.s b/libc/nt/user32/SetWindowsHookExW.s new file mode 100644 index 00000000..f3e46d7f --- /dev/null +++ b/libc/nt/user32/SetWindowsHookExW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowsHookExW,SetWindowsHookExW,2409 + + .text.windows +SetWindowsHookEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetWindowsHookExW(%rip),%rax + jmp __sysv2nt + .endfn SetWindowsHookEx,globl + .previous diff --git a/libc/nt/user32/SetWindowsHookW.s b/libc/nt/user32/SetWindowsHookW.s new file mode 100644 index 00000000..9c09a8fb --- /dev/null +++ b/libc/nt/user32/SetWindowsHookW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SetWindowsHookW,SetWindowsHookW,2410 + + .text.windows +SetWindowsHook: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_SetWindowsHookW(%rip),%rax + jmp __sysv2nt + .endfn SetWindowsHook,globl + .previous diff --git a/libc/nt/user32/ShowCaret.s b/libc/nt/user32/ShowCaret.s new file mode 100644 index 00000000..a56d01dc --- /dev/null +++ b/libc/nt/user32/ShowCaret.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ShowCaret,ShowCaret,2411 diff --git a/libc/nt/user32/ShowCursor.s b/libc/nt/user32/ShowCursor.s new file mode 100644 index 00000000..2fa3a525 --- /dev/null +++ b/libc/nt/user32/ShowCursor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ShowCursor,ShowCursor,2412 diff --git a/libc/nt/user32/ShowOwnedPopups.s b/libc/nt/user32/ShowOwnedPopups.s new file mode 100644 index 00000000..9cc9da5d --- /dev/null +++ b/libc/nt/user32/ShowOwnedPopups.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ShowOwnedPopups,ShowOwnedPopups,2413 diff --git a/libc/nt/user32/ShowScrollBar.s b/libc/nt/user32/ShowScrollBar.s new file mode 100644 index 00000000..5ba40978 --- /dev/null +++ b/libc/nt/user32/ShowScrollBar.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ShowScrollBar,ShowScrollBar,2414 diff --git a/libc/nt/user32/ShowStartGlass.s b/libc/nt/user32/ShowStartGlass.s new file mode 100644 index 00000000..b295fc9a --- /dev/null +++ b/libc/nt/user32/ShowStartGlass.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ShowStartGlass,ShowStartGlass,2415 diff --git a/libc/nt/user32/ShowSystemCursor.s b/libc/nt/user32/ShowSystemCursor.s new file mode 100644 index 00000000..d4668881 --- /dev/null +++ b/libc/nt/user32/ShowSystemCursor.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ShowSystemCursor,ShowSystemCursor,2416 diff --git a/libc/nt/user32/ShowWindow.s b/libc/nt/user32/ShowWindow.s new file mode 100644 index 00000000..ba2f057d --- /dev/null +++ b/libc/nt/user32/ShowWindow.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ShowWindow,ShowWindow,2417 + + .text.windows +ShowWindow: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ShowWindow(%rip),%rax + jmp __sysv2nt + .endfn ShowWindow,globl + .previous diff --git a/libc/nt/user32/ShowWindowAsync.s b/libc/nt/user32/ShowWindowAsync.s new file mode 100644 index 00000000..3a0bb937 --- /dev/null +++ b/libc/nt/user32/ShowWindowAsync.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ShowWindowAsync,ShowWindowAsync,2418 diff --git a/libc/nt/user32/ShutdownBlockReasonCreate.s b/libc/nt/user32/ShutdownBlockReasonCreate.s new file mode 100644 index 00000000..24f9b4ec --- /dev/null +++ b/libc/nt/user32/ShutdownBlockReasonCreate.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ShutdownBlockReasonCreate,ShutdownBlockReasonCreate,2419 diff --git a/libc/nt/user32/ShutdownBlockReasonDestroy.s b/libc/nt/user32/ShutdownBlockReasonDestroy.s new file mode 100644 index 00000000..84bc2ab7 --- /dev/null +++ b/libc/nt/user32/ShutdownBlockReasonDestroy.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ShutdownBlockReasonDestroy,ShutdownBlockReasonDestroy,2420 diff --git a/libc/nt/user32/ShutdownBlockReasonQuery.s b/libc/nt/user32/ShutdownBlockReasonQuery.s new file mode 100644 index 00000000..a4648bbd --- /dev/null +++ b/libc/nt/user32/ShutdownBlockReasonQuery.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ShutdownBlockReasonQuery,ShutdownBlockReasonQuery,2421 diff --git a/libc/nt/user32/SignalRedirectionStartComplete.s b/libc/nt/user32/SignalRedirectionStartComplete.s new file mode 100644 index 00000000..cc1163ae --- /dev/null +++ b/libc/nt/user32/SignalRedirectionStartComplete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SignalRedirectionStartComplete,SignalRedirectionStartComplete,2422 diff --git a/libc/nt/user32/SkipPointerFrameMessages.s b/libc/nt/user32/SkipPointerFrameMessages.s new file mode 100644 index 00000000..37f03cb5 --- /dev/null +++ b/libc/nt/user32/SkipPointerFrameMessages.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SkipPointerFrameMessages,SkipPointerFrameMessages,2423 diff --git a/libc/nt/user32/SoftModalMessageBox.s b/libc/nt/user32/SoftModalMessageBox.s new file mode 100644 index 00000000..0c695c48 --- /dev/null +++ b/libc/nt/user32/SoftModalMessageBox.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SoftModalMessageBox,SoftModalMessageBox,2424 diff --git a/libc/nt/user32/SoundSentry.s b/libc/nt/user32/SoundSentry.s new file mode 100644 index 00000000..7b3a2709 --- /dev/null +++ b/libc/nt/user32/SoundSentry.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SoundSentry,SoundSentry,2425 diff --git a/libc/nt/user32/SubtractRect.s b/libc/nt/user32/SubtractRect.s new file mode 100644 index 00000000..2978174e --- /dev/null +++ b/libc/nt/user32/SubtractRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SubtractRect,SubtractRect,2426 diff --git a/libc/nt/user32/SwapMouseButton.s b/libc/nt/user32/SwapMouseButton.s new file mode 100644 index 00000000..1d168a63 --- /dev/null +++ b/libc/nt/user32/SwapMouseButton.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SwapMouseButton,SwapMouseButton,2427 diff --git a/libc/nt/user32/SwitchDesktop.s b/libc/nt/user32/SwitchDesktop.s new file mode 100644 index 00000000..544be2e0 --- /dev/null +++ b/libc/nt/user32/SwitchDesktop.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SwitchDesktop,SwitchDesktop,2428 diff --git a/libc/nt/user32/SwitchDesktopWithFade.s b/libc/nt/user32/SwitchDesktopWithFade.s new file mode 100644 index 00000000..a26d0381 --- /dev/null +++ b/libc/nt/user32/SwitchDesktopWithFade.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SwitchDesktopWithFade,SwitchDesktopWithFade,2429 diff --git a/libc/nt/user32/SwitchToThisWindow.s b/libc/nt/user32/SwitchToThisWindow.s new file mode 100644 index 00000000..468edde5 --- /dev/null +++ b/libc/nt/user32/SwitchToThisWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SwitchToThisWindow,SwitchToThisWindow,2430 diff --git a/libc/nt/user32/SystemParametersInfoA.s b/libc/nt/user32/SystemParametersInfoA.s new file mode 100644 index 00000000..2dab6d65 --- /dev/null +++ b/libc/nt/user32/SystemParametersInfoA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SystemParametersInfoA,SystemParametersInfoA,2431 diff --git a/libc/nt/user32/SystemParametersInfoForDpi.s b/libc/nt/user32/SystemParametersInfoForDpi.s new file mode 100644 index 00000000..48b34d2e --- /dev/null +++ b/libc/nt/user32/SystemParametersInfoForDpi.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SystemParametersInfoForDpi,SystemParametersInfoForDpi,2432 diff --git a/libc/nt/user32/SystemParametersInfoW.s b/libc/nt/user32/SystemParametersInfoW.s new file mode 100644 index 00000000..bf556770 --- /dev/null +++ b/libc/nt/user32/SystemParametersInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_SystemParametersInfoW,SystemParametersInfoW,2433 diff --git a/libc/nt/user32/TabbedTextOutA.s b/libc/nt/user32/TabbedTextOutA.s new file mode 100644 index 00000000..65f70b2f --- /dev/null +++ b/libc/nt/user32/TabbedTextOutA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_TabbedTextOutA,TabbedTextOutA,2434 diff --git a/libc/nt/user32/TabbedTextOutW.s b/libc/nt/user32/TabbedTextOutW.s new file mode 100644 index 00000000..4f822bf7 --- /dev/null +++ b/libc/nt/user32/TabbedTextOutW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_TabbedTextOutW,TabbedTextOutW,2435 diff --git a/libc/nt/user32/TileChildWindows.s b/libc/nt/user32/TileChildWindows.s new file mode 100644 index 00000000..2dbf4d9d --- /dev/null +++ b/libc/nt/user32/TileChildWindows.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_TileChildWindows,TileChildWindows,2436 diff --git a/libc/nt/user32/TileWindows.s b/libc/nt/user32/TileWindows.s new file mode 100644 index 00000000..c153267f --- /dev/null +++ b/libc/nt/user32/TileWindows.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_TileWindows,TileWindows,2437 diff --git a/libc/nt/user32/ToAscii.s b/libc/nt/user32/ToAscii.s new file mode 100644 index 00000000..12e4062d --- /dev/null +++ b/libc/nt/user32/ToAscii.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ToAscii,ToAscii,2438 diff --git a/libc/nt/user32/ToAsciiEx.s b/libc/nt/user32/ToAsciiEx.s new file mode 100644 index 00000000..06b693a9 --- /dev/null +++ b/libc/nt/user32/ToAsciiEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ToAsciiEx,ToAsciiEx,2439 diff --git a/libc/nt/user32/ToUnicode.s b/libc/nt/user32/ToUnicode.s new file mode 100644 index 00000000..d7622ad6 --- /dev/null +++ b/libc/nt/user32/ToUnicode.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ToUnicode,ToUnicode,2440 diff --git a/libc/nt/user32/ToUnicodeEx.s b/libc/nt/user32/ToUnicodeEx.s new file mode 100644 index 00000000..79e9d009 --- /dev/null +++ b/libc/nt/user32/ToUnicodeEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ToUnicodeEx,ToUnicodeEx,2441 diff --git a/libc/nt/user32/TrackMouseEvent.s b/libc/nt/user32/TrackMouseEvent.s new file mode 100644 index 00000000..9b20a9f9 --- /dev/null +++ b/libc/nt/user32/TrackMouseEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_TrackMouseEvent,TrackMouseEvent,2442 diff --git a/libc/nt/user32/TrackPopupMenu.s b/libc/nt/user32/TrackPopupMenu.s new file mode 100644 index 00000000..f5e233a6 --- /dev/null +++ b/libc/nt/user32/TrackPopupMenu.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_TrackPopupMenu,TrackPopupMenu,2443 diff --git a/libc/nt/user32/TrackPopupMenuEx.s b/libc/nt/user32/TrackPopupMenuEx.s new file mode 100644 index 00000000..230f939a --- /dev/null +++ b/libc/nt/user32/TrackPopupMenuEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_TrackPopupMenuEx,TrackPopupMenuEx,2444 diff --git a/libc/nt/user32/TranslateAcceleratorA.s b/libc/nt/user32/TranslateAcceleratorA.s new file mode 100644 index 00000000..894e2808 --- /dev/null +++ b/libc/nt/user32/TranslateAcceleratorA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_TranslateAcceleratorA,TranslateAcceleratorA,2446 diff --git a/libc/nt/user32/TranslateAcceleratorW.s b/libc/nt/user32/TranslateAcceleratorW.s new file mode 100644 index 00000000..83613c43 --- /dev/null +++ b/libc/nt/user32/TranslateAcceleratorW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_TranslateAcceleratorW,TranslateAcceleratorW,2447 diff --git a/libc/nt/user32/TranslateMDISysAccel.s b/libc/nt/user32/TranslateMDISysAccel.s new file mode 100644 index 00000000..cd4fe316 --- /dev/null +++ b/libc/nt/user32/TranslateMDISysAccel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_TranslateMDISysAccel,TranslateMDISysAccel,2448 diff --git a/libc/nt/user32/TranslateMessage.s b/libc/nt/user32/TranslateMessage.s new file mode 100644 index 00000000..c98c623c --- /dev/null +++ b/libc/nt/user32/TranslateMessage.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_TranslateMessage,TranslateMessage,2449 + + .text.windows +TranslateMessage: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_TranslateMessage(%rip) + leave + ret + .endfn TranslateMessage,globl + .previous diff --git a/libc/nt/user32/TranslateMessageEx.s b/libc/nt/user32/TranslateMessageEx.s new file mode 100644 index 00000000..e09da5d8 --- /dev/null +++ b/libc/nt/user32/TranslateMessageEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_TranslateMessageEx,TranslateMessageEx,2450 diff --git a/libc/nt/user32/UndelegateInput.s b/libc/nt/user32/UndelegateInput.s new file mode 100644 index 00000000..d7d5fddb --- /dev/null +++ b/libc/nt/user32/UndelegateInput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UndelegateInput,UndelegateInput,2504 diff --git a/libc/nt/user32/UnhookWinEvent.s b/libc/nt/user32/UnhookWinEvent.s new file mode 100644 index 00000000..a81d3f94 --- /dev/null +++ b/libc/nt/user32/UnhookWinEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnhookWinEvent,UnhookWinEvent,2451 diff --git a/libc/nt/user32/UnhookWindowsHook.s b/libc/nt/user32/UnhookWindowsHook.s new file mode 100644 index 00000000..4cabb570 --- /dev/null +++ b/libc/nt/user32/UnhookWindowsHook.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnhookWindowsHook,UnhookWindowsHook,2452 + + .text.windows +UnhookWindowsHook: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_UnhookWindowsHook(%rip),%rax + jmp __sysv2nt + .endfn UnhookWindowsHook,globl + .previous diff --git a/libc/nt/user32/UnhookWindowsHookEx.s b/libc/nt/user32/UnhookWindowsHookEx.s new file mode 100644 index 00000000..d70955da --- /dev/null +++ b/libc/nt/user32/UnhookWindowsHookEx.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnhookWindowsHookEx,UnhookWindowsHookEx,2453 + + .text.windows +UnhookWindowsHookEx: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_UnhookWindowsHookEx(%rip) + leave + ret + .endfn UnhookWindowsHookEx,globl + .previous diff --git a/libc/nt/user32/UnionRect.s b/libc/nt/user32/UnionRect.s new file mode 100644 index 00000000..34bf1cbd --- /dev/null +++ b/libc/nt/user32/UnionRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnionRect,UnionRect,2454 diff --git a/libc/nt/user32/UnloadKeyboardLayout.s b/libc/nt/user32/UnloadKeyboardLayout.s new file mode 100644 index 00000000..148c39a5 --- /dev/null +++ b/libc/nt/user32/UnloadKeyboardLayout.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnloadKeyboardLayout,UnloadKeyboardLayout,2455 diff --git a/libc/nt/user32/UnlockWindowStation.s b/libc/nt/user32/UnlockWindowStation.s new file mode 100644 index 00000000..68b6416a --- /dev/null +++ b/libc/nt/user32/UnlockWindowStation.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnlockWindowStation,UnlockWindowStation,2456 diff --git a/libc/nt/user32/UnpackDDElParam.s b/libc/nt/user32/UnpackDDElParam.s new file mode 100644 index 00000000..8c9625c6 --- /dev/null +++ b/libc/nt/user32/UnpackDDElParam.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnpackDDElParam,UnpackDDElParam,2457 diff --git a/libc/nt/user32/UnregisterClassA.s b/libc/nt/user32/UnregisterClassA.s new file mode 100644 index 00000000..ae91b90c --- /dev/null +++ b/libc/nt/user32/UnregisterClassA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnregisterClassA,UnregisterClassA,2458 diff --git a/libc/nt/user32/UnregisterClassW.s b/libc/nt/user32/UnregisterClassW.s new file mode 100644 index 00000000..96b96d77 --- /dev/null +++ b/libc/nt/user32/UnregisterClassW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnregisterClassW,UnregisterClassW,2459 diff --git a/libc/nt/user32/UnregisterDeviceNotification.s b/libc/nt/user32/UnregisterDeviceNotification.s new file mode 100644 index 00000000..b8dd3dbb --- /dev/null +++ b/libc/nt/user32/UnregisterDeviceNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnregisterDeviceNotification,UnregisterDeviceNotification,2460 diff --git a/libc/nt/user32/UnregisterHotKey.s b/libc/nt/user32/UnregisterHotKey.s new file mode 100644 index 00000000..b4b42dbc --- /dev/null +++ b/libc/nt/user32/UnregisterHotKey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnregisterHotKey,UnregisterHotKey,2461 diff --git a/libc/nt/user32/UnregisterMessagePumpHook.s b/libc/nt/user32/UnregisterMessagePumpHook.s new file mode 100644 index 00000000..b051a517 --- /dev/null +++ b/libc/nt/user32/UnregisterMessagePumpHook.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnregisterMessagePumpHook,UnregisterMessagePumpHook,2462 diff --git a/libc/nt/user32/UnregisterPointerInputTarget.s b/libc/nt/user32/UnregisterPointerInputTarget.s new file mode 100644 index 00000000..72d1d97a --- /dev/null +++ b/libc/nt/user32/UnregisterPointerInputTarget.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnregisterPointerInputTarget,UnregisterPointerInputTarget,2463 diff --git a/libc/nt/user32/UnregisterPointerInputTargetEx.s b/libc/nt/user32/UnregisterPointerInputTargetEx.s new file mode 100644 index 00000000..7789cbcc --- /dev/null +++ b/libc/nt/user32/UnregisterPointerInputTargetEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnregisterPointerInputTargetEx,UnregisterPointerInputTargetEx,2464 diff --git a/libc/nt/user32/UnregisterPowerSettingNotification.s b/libc/nt/user32/UnregisterPowerSettingNotification.s new file mode 100644 index 00000000..dc092b0e --- /dev/null +++ b/libc/nt/user32/UnregisterPowerSettingNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnregisterPowerSettingNotification,UnregisterPowerSettingNotification,2465 diff --git a/libc/nt/user32/UnregisterSessionPort.s b/libc/nt/user32/UnregisterSessionPort.s new file mode 100644 index 00000000..39331da1 --- /dev/null +++ b/libc/nt/user32/UnregisterSessionPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnregisterSessionPort,UnregisterSessionPort,2466 diff --git a/libc/nt/user32/UnregisterSuspendResumeNotification.s b/libc/nt/user32/UnregisterSuspendResumeNotification.s new file mode 100644 index 00000000..68633e51 --- /dev/null +++ b/libc/nt/user32/UnregisterSuspendResumeNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnregisterSuspendResumeNotification,UnregisterSuspendResumeNotification,2467 diff --git a/libc/nt/user32/UnregisterTouchWindow.s b/libc/nt/user32/UnregisterTouchWindow.s new file mode 100644 index 00000000..5ba0551c --- /dev/null +++ b/libc/nt/user32/UnregisterTouchWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnregisterTouchWindow,UnregisterTouchWindow,2468 diff --git a/libc/nt/user32/UnregisterUserApiHook.s b/libc/nt/user32/UnregisterUserApiHook.s new file mode 100644 index 00000000..bc71dfea --- /dev/null +++ b/libc/nt/user32/UnregisterUserApiHook.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UnregisterUserApiHook,UnregisterUserApiHook,2469 diff --git a/libc/nt/user32/UpdateDefaultDesktopThumbnail.s b/libc/nt/user32/UpdateDefaultDesktopThumbnail.s new file mode 100644 index 00000000..a69e67ff --- /dev/null +++ b/libc/nt/user32/UpdateDefaultDesktopThumbnail.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UpdateDefaultDesktopThumbnail,UpdateDefaultDesktopThumbnail,2470 diff --git a/libc/nt/user32/UpdateLayeredWindow.s b/libc/nt/user32/UpdateLayeredWindow.s new file mode 100644 index 00000000..ec1d7366 --- /dev/null +++ b/libc/nt/user32/UpdateLayeredWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UpdateLayeredWindow,UpdateLayeredWindow,2471 diff --git a/libc/nt/user32/UpdateLayeredWindowIndirect.s b/libc/nt/user32/UpdateLayeredWindowIndirect.s new file mode 100644 index 00000000..dd0fa1b7 --- /dev/null +++ b/libc/nt/user32/UpdateLayeredWindowIndirect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UpdateLayeredWindowIndirect,UpdateLayeredWindowIndirect,2472 diff --git a/libc/nt/user32/UpdatePerUserSystemParameters.s b/libc/nt/user32/UpdatePerUserSystemParameters.s new file mode 100644 index 00000000..f4e9574b --- /dev/null +++ b/libc/nt/user32/UpdatePerUserSystemParameters.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UpdatePerUserSystemParameters,UpdatePerUserSystemParameters,2473 diff --git a/libc/nt/user32/UpdateWindow.s b/libc/nt/user32/UpdateWindow.s new file mode 100644 index 00000000..dc0de51e --- /dev/null +++ b/libc/nt/user32/UpdateWindow.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UpdateWindow,UpdateWindow,2474 diff --git a/libc/nt/user32/UpdateWindowInputSinkHints.s b/libc/nt/user32/UpdateWindowInputSinkHints.s new file mode 100644 index 00000000..1be4f7c8 --- /dev/null +++ b/libc/nt/user32/UpdateWindowInputSinkHints.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UpdateWindowInputSinkHints,UpdateWindowInputSinkHints,2475 diff --git a/libc/nt/user32/User32InitializeImmEntryTable.s b/libc/nt/user32/User32InitializeImmEntryTable.s new file mode 100644 index 00000000..9b390599 --- /dev/null +++ b/libc/nt/user32/User32InitializeImmEntryTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_User32InitializeImmEntryTable,User32InitializeImmEntryTable,2476 diff --git a/libc/nt/user32/UserClientDllInitialize.s b/libc/nt/user32/UserClientDllInitialize.s new file mode 100644 index 00000000..05c06092 --- /dev/null +++ b/libc/nt/user32/UserClientDllInitialize.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UserClientDllInitialize,UserClientDllInitialize,2477 diff --git a/libc/nt/user32/UserHandleGrantAccess.s b/libc/nt/user32/UserHandleGrantAccess.s new file mode 100644 index 00000000..88406ed3 --- /dev/null +++ b/libc/nt/user32/UserHandleGrantAccess.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UserHandleGrantAccess,UserHandleGrantAccess,2478 diff --git a/libc/nt/user32/UserLpkPSMTextOut.s b/libc/nt/user32/UserLpkPSMTextOut.s new file mode 100644 index 00000000..b522b98b --- /dev/null +++ b/libc/nt/user32/UserLpkPSMTextOut.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UserLpkPSMTextOut,UserLpkPSMTextOut,2479 diff --git a/libc/nt/user32/UserLpkTabbedTextOut.s b/libc/nt/user32/UserLpkTabbedTextOut.s new file mode 100644 index 00000000..0cd8bbc7 --- /dev/null +++ b/libc/nt/user32/UserLpkTabbedTextOut.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UserLpkTabbedTextOut,UserLpkTabbedTextOut,2480 diff --git a/libc/nt/user32/UserRealizePalette.s b/libc/nt/user32/UserRealizePalette.s new file mode 100644 index 00000000..a43d83ed --- /dev/null +++ b/libc/nt/user32/UserRealizePalette.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UserRealizePalette,UserRealizePalette,2481 diff --git a/libc/nt/user32/UserRegisterWowHandlers.s b/libc/nt/user32/UserRegisterWowHandlers.s new file mode 100644 index 00000000..e217ac38 --- /dev/null +++ b/libc/nt/user32/UserRegisterWowHandlers.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_UserRegisterWowHandlers,UserRegisterWowHandlers,2482 diff --git a/libc/nt/user32/VRipOutput.s b/libc/nt/user32/VRipOutput.s new file mode 100644 index 00000000..97874fcc --- /dev/null +++ b/libc/nt/user32/VRipOutput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_VRipOutput,VRipOutput,2483 diff --git a/libc/nt/user32/VTagOutput.s b/libc/nt/user32/VTagOutput.s new file mode 100644 index 00000000..2ccec542 --- /dev/null +++ b/libc/nt/user32/VTagOutput.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_VTagOutput,VTagOutput,2484 diff --git a/libc/nt/user32/ValidateRect.s b/libc/nt/user32/ValidateRect.s new file mode 100644 index 00000000..0ddd2173 --- /dev/null +++ b/libc/nt/user32/ValidateRect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ValidateRect,ValidateRect,2485 diff --git a/libc/nt/user32/ValidateRgn.s b/libc/nt/user32/ValidateRgn.s new file mode 100644 index 00000000..52afc430 --- /dev/null +++ b/libc/nt/user32/ValidateRgn.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_ValidateRgn,ValidateRgn,2486 diff --git a/libc/nt/user32/VkKeyScanA.s b/libc/nt/user32/VkKeyScanA.s new file mode 100644 index 00000000..80f92a96 --- /dev/null +++ b/libc/nt/user32/VkKeyScanA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_VkKeyScanA,VkKeyScanA,2487 diff --git a/libc/nt/user32/VkKeyScanExA.s b/libc/nt/user32/VkKeyScanExA.s new file mode 100644 index 00000000..910db486 --- /dev/null +++ b/libc/nt/user32/VkKeyScanExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_VkKeyScanExA,VkKeyScanExA,2488 diff --git a/libc/nt/user32/VkKeyScanExW.s b/libc/nt/user32/VkKeyScanExW.s new file mode 100644 index 00000000..43f458f5 --- /dev/null +++ b/libc/nt/user32/VkKeyScanExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_VkKeyScanExW,VkKeyScanExW,2489 diff --git a/libc/nt/user32/VkKeyScanW.s b/libc/nt/user32/VkKeyScanW.s new file mode 100644 index 00000000..20305605 --- /dev/null +++ b/libc/nt/user32/VkKeyScanW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_VkKeyScanW,VkKeyScanW,2490 diff --git a/libc/nt/user32/WCSToMBEx.s b/libc/nt/user32/WCSToMBEx.s new file mode 100644 index 00000000..aa996d38 --- /dev/null +++ b/libc/nt/user32/WCSToMBEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_WCSToMBEx,WCSToMBEx,2491 diff --git a/libc/nt/user32/WINNLSEnableIME.s b/libc/nt/user32/WINNLSEnableIME.s new file mode 100644 index 00000000..6832a52d --- /dev/null +++ b/libc/nt/user32/WINNLSEnableIME.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_WINNLSEnableIME,WINNLSEnableIME,2492 diff --git a/libc/nt/user32/WINNLSGetEnableStatus.s b/libc/nt/user32/WINNLSGetEnableStatus.s new file mode 100644 index 00000000..0087c832 --- /dev/null +++ b/libc/nt/user32/WINNLSGetEnableStatus.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_WINNLSGetEnableStatus,WINNLSGetEnableStatus,2493 diff --git a/libc/nt/user32/WINNLSGetIMEHotkey.s b/libc/nt/user32/WINNLSGetIMEHotkey.s new file mode 100644 index 00000000..f440e626 --- /dev/null +++ b/libc/nt/user32/WINNLSGetIMEHotkey.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_WINNLSGetIMEHotkey,WINNLSGetIMEHotkey,2494 diff --git a/libc/nt/user32/WaitForInputIdle.s b/libc/nt/user32/WaitForInputIdle.s new file mode 100644 index 00000000..ca70e459 --- /dev/null +++ b/libc/nt/user32/WaitForInputIdle.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_WaitForInputIdle,WaitForInputIdle,2495 + + .text.windows +WaitForInputIdle: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WaitForInputIdle(%rip),%rax + jmp __sysv2nt + .endfn WaitForInputIdle,globl + .previous diff --git a/libc/nt/user32/WaitForRedirectionStartComplete.s b/libc/nt/user32/WaitForRedirectionStartComplete.s new file mode 100644 index 00000000..979c757d --- /dev/null +++ b/libc/nt/user32/WaitForRedirectionStartComplete.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_WaitForRedirectionStartComplete,WaitForRedirectionStartComplete,2496 diff --git a/libc/nt/user32/WaitMessage.s b/libc/nt/user32/WaitMessage.s new file mode 100644 index 00000000..1da00ac3 --- /dev/null +++ b/libc/nt/user32/WaitMessage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_WaitMessage,WaitMessage,2497 diff --git a/libc/nt/user32/WinHelpA.s b/libc/nt/user32/WinHelpA.s new file mode 100644 index 00000000..e8e0e25a --- /dev/null +++ b/libc/nt/user32/WinHelpA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_WinHelpA,WinHelpA,2498 diff --git a/libc/nt/user32/WinHelpW.s b/libc/nt/user32/WinHelpW.s new file mode 100644 index 00000000..b6f93309 --- /dev/null +++ b/libc/nt/user32/WinHelpW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_WinHelpW,WinHelpW,2499 diff --git a/libc/nt/user32/WindowFromDC.s b/libc/nt/user32/WindowFromDC.s new file mode 100644 index 00000000..07073bc0 --- /dev/null +++ b/libc/nt/user32/WindowFromDC.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_WindowFromDC,WindowFromDC,2500 diff --git a/libc/nt/user32/WindowFromPhysicalPoint.s b/libc/nt/user32/WindowFromPhysicalPoint.s new file mode 100644 index 00000000..b47984b2 --- /dev/null +++ b/libc/nt/user32/WindowFromPhysicalPoint.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_WindowFromPhysicalPoint,WindowFromPhysicalPoint,2501 diff --git a/libc/nt/user32/WindowFromPoint.s b/libc/nt/user32/WindowFromPoint.s new file mode 100644 index 00000000..1f0aa4ad --- /dev/null +++ b/libc/nt/user32/WindowFromPoint.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_WindowFromPoint,WindowFromPoint,2502 diff --git a/libc/nt/user32/_UserTestTokenForInteractive.s b/libc/nt/user32/_UserTestTokenForInteractive.s new file mode 100644 index 00000000..16fd5e75 --- /dev/null +++ b/libc/nt/user32/_UserTestTokenForInteractive.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp__UserTestTokenForInteractive,_UserTestTokenForInteractive,2543 diff --git a/libc/nt/user32/gSharedInfo.s b/libc/nt/user32/gSharedInfo.s new file mode 100644 index 00000000..14dd57d3 --- /dev/null +++ b/libc/nt/user32/gSharedInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_gSharedInfo,gSharedInfo,2547 diff --git a/libc/nt/user32/gapfnScSendMessage.s b/libc/nt/user32/gapfnScSendMessage.s new file mode 100644 index 00000000..d46a63e8 --- /dev/null +++ b/libc/nt/user32/gapfnScSendMessage.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_gapfnScSendMessage,gapfnScSendMessage,2562 diff --git a/libc/nt/user32/keybd_event.s b/libc/nt/user32/keybd_event.s new file mode 100644 index 00000000..b0e1ca1e --- /dev/null +++ b/libc/nt/user32/keybd_event.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_keybd_event,keybd_event,2580 diff --git a/libc/nt/user32/mouse_event.s b/libc/nt/user32/mouse_event.s new file mode 100644 index 00000000..e4a0b74b --- /dev/null +++ b/libc/nt/user32/mouse_event.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_mouse_event,mouse_event,2583 diff --git a/libc/nt/user32/wsprintfA.s b/libc/nt/user32/wsprintfA.s new file mode 100644 index 00000000..59fc8b67 --- /dev/null +++ b/libc/nt/user32/wsprintfA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_wsprintfA,wsprintfA,2596 diff --git a/libc/nt/user32/wsprintfW.s b/libc/nt/user32/wsprintfW.s new file mode 100644 index 00000000..fb207c7a --- /dev/null +++ b/libc/nt/user32/wsprintfW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_wsprintfW,wsprintfW,2601 diff --git a/libc/nt/user32/wvsprintfA.s b/libc/nt/user32/wvsprintfA.s new file mode 100644 index 00000000..28aeda0c --- /dev/null +++ b/libc/nt/user32/wvsprintfA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_wvsprintfA,wvsprintfA,2602 diff --git a/libc/nt/user32/wvsprintfW.s b/libc/nt/user32/wvsprintfW.s new file mode 100644 index 00000000..9fa280dc --- /dev/null +++ b/libc/nt/user32/wvsprintfW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_wvsprintfW,wvsprintfW,2603 diff --git a/libc/nt/windows.h b/libc/nt/windows.h new file mode 100644 index 00000000..43b8ea91 --- /dev/null +++ b/libc/nt/windows.h @@ -0,0 +1,367 @@ +#ifndef COSMOPOLITAN_LIBC_NT_WINDOWS_H_ +#define COSMOPOLITAN_LIBC_NT_WINDOWS_H_ +#include "libc/nt/typedef/timerproc.h" +#if 0 +/* ░░░░ + ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▓▓▓▓▓▓░ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓░ + ▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▒ ▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒▒▒░░░░▒▒▒▒▒▒▓▓▓▓▓▓ █▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ▒▒▒▒░░░▒▒▒▒▒▒▒▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒ + ▒▒▒▒▓▓ ▓▒▒▓▓▓▓ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▓ ▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓ + ░░░░░░░░░░░▒▒▒▒ ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓█ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓▓ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓ + ░▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓░ ░▓███▓ + ▒▒░░░░░░░░░░▒▒▒▒▒▓▓░ ▒▓▓▓▒▒▒ ░▒▒▒▓ ████████████ + ▒▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▒▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒░ ░███ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ███ + ▒▒░░░░░░░░░░▒▒▒▒▒▒▓▓ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ▓██ + ▒░░░░░░░░░░░▒▒▒▒▒▓▓ ▓▓▓▓▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▓ ▓██ + ▒▒░░░▒▒▒░░░▒▒░▒▒▒▓▓▒ ▒▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒ ███ + ░▒▓ ░▓▓▓▓▒▒▒▒▒▒▒▒░░░░▒▒▒▒▓ ▓██ +╔────────────────────────────────────────────────────────────────▀▀▀─────────│─╗ +│ cosmopolitan § new technology » windows ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +#define NT_WM_NULL 0x0000 +#define NT_WM_CREATE 0x0001 +#define NT_WM_DESTROY 0x0002 +#define NT_WM_MOVE 0x0003 +#define NT_WM_SIZE 0x0005 +#define NT_WM_ACTIVATE 0x0006 +#define NT_WA_INACTIVE 0 +#define NT_WA_ACTIVE 1 +#define NT_WA_CLICKACTIVE 2 +#define NT_WM_SETFOCUS 0x0007 +#define NT_WM_KILLFOCUS 0x0008 +#define NT_WM_ENABLE 0x000A +#define NT_WM_SETREDRAW 0x000B +#define NT_WM_SETTEXT 0x000C +#define NT_WM_GETTEXT 0x000D +#define NT_WM_GETTEXTLENGTH 0x000E +#define NT_WM_PAINT 0x000F +#define NT_WM_CLOSE 0x0010 +#define NT_WM_QUIT 0x0012 +#define NT_WM_ERASEBKGND 0x0014 +#define NT_WM_SYSCOLORCHANGE 0x0015 +#define NT_WM_SHOWWINDOW 0x0018 +#define NT_WM_WININICHANGE 0x001A +#define NT_WM_SETTINGCHANGE WM_WININICHANGE +#define NT_WM_DEVMODECHANGE 0x001B +#define NT_WM_ACTIVATEAPP 0x001C +#define NT_WM_FONTCHANGE 0x001D +#define NT_WM_TIMECHANGE 0x001E +#define NT_WM_CANCELMODE 0x001F +#define NT_WM_SETCURSOR 0x0020 +#define NT_WM_MOUSEACTIVATE 0x0021 +#define NT_WM_CHILDACTIVATE 0x0022 +#define NT_WM_QUEUESYNC 0x0023 +#define NT_WM_GETMINMAXINFO 0x0024 + +#define NT_WS_OVERLAPPED 0x00000000 +#define NT_WS_POPUP 0x80000000 +#define NT_WS_CHILD 0x40000000 +#define NT_WS_MINIMIZE 0x20000000 +#define NT_WS_VISIBLE 0x10000000 +#define NT_WS_DISABLED 0x08000000 +#define NT_WS_CLIPSIBLINGS 0x04000000 +#define NT_WS_CLIPCHILDREN 0x02000000 +#define NT_WS_MAXIMIZE 0x01000000 +#define NT_WS_CAPTION 0x00C00000 +#define NT_WS_BORDER 0x00800000 +#define NT_WS_DLGFRAME 0x00400000 +#define NT_WS_VSCROLL 0x00200000 +#define NT_WS_HSCROLL 0x00100000 +#define NT_WS_SYSMENU 0x00080000 +#define NT_WS_THICKFRAME 0x00040000 +#define NT_WS_GROUP 0x00020000 +#define NT_WS_TABSTOP 0x00010000 +#define NT_WS_MINIMIZEBOX 0x00020000 +#define NT_WS_MAXIMIZEBOX 0x00010000 +#define NT_WS_TILED WS_OVERLAPPED +#define NT_WS_ICONIC WS_MINIMIZE +#define NT_WS_SIZEBOX WS_THICKFRAME +#define NT_WS_TILEDWINDOW WS_OVERLAPPEDWINDOW +#define NT_WS_OVERLAPPEDWINDOW \ + (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | \ + WS_MAXIMIZEBOX) +#define NT_WS_POPUPWINDOW (WS_POPUP | WS_BORDER | WS_SYSMENU) +#define NT_WS_CHILDWINDOW (WS_CHILD) + +#define NT_WS_EX_DLGMODALFRAME 0x00000001 +#define NT_WS_EX_NOPARENTNOTIFY 0x00000004 +#define NT_WS_EX_TOPMOST 0x00000008 +#define NT_WS_EX_ACCEPTFILES 0x00000010 +#define NT_WS_EX_TRANSPARENT 0x00000020 +#define NT_WS_EX_MDICHILD 0x00000040 +#define NT_WS_EX_TOOLWINDOW 0x00000080 +#define NT_WS_EX_WINDOWEDGE 0x00000100 +#define NT_WS_EX_CLIENTEDGE 0x00000200 +#define NT_WS_EX_CONTEXTHELP 0x00000400 +#define NT_WS_EX_RIGHT 0x00001000 +#define NT_WS_EX_LEFT 0x00000000 +#define NT_WS_EX_RTLREADING 0x00002000 +#define NT_WS_EX_LTRREADING 0x00000000 +#define NT_WS_EX_LEFTSCROLLBAR 0x00004000 +#define NT_WS_EX_RIGHTSCROLLBAR 0x00000000 +#define NT_WS_EX_CONTROLPARENT 0x00010000 +#define NT_WS_EX_STATICEDGE 0x00020000 +#define NT_WS_EX_APPWINDOW 0x00040000 +#define NT_WS_EX_OVERLAPPEDWINDOW (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE) +#define NT_WS_EX_PALETTEWINDOW \ + (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST) +#define NT_WS_EX_LAYERED 0x00080000 +#define NT_WS_EX_NOINHERITLAYOUT 0x00100000 +#define NT_WS_EX_LAYOUTRTL 0x00400000 +#define NT_WS_EX_COMPOSITED 0x02000000 +#define NT_WS_EX_NOACTIVATE 0x08000000 + +#define NT_CS_VREDRAW 0x0001 +#define NT_CS_HREDRAW 0x0002 +#define NT_CS_DBLCLKS 0x0008 +#define NT_CS_OWNDC 0x0020 +#define NT_CS_CLASSDC 0x0040 +#define NT_CS_PARENTDC 0x0080 +#define NT_CS_NOCLOSE 0x0200 +#define NT_CS_SAVEBITS 0x0800 +#define NT_CS_BYTEALIGNCLIENT 0x1000 +#define NT_CS_BYTEALIGNWINDOW 0x2000 +#define NT_CS_GLOBALCLASS 0x4000 +#define NT_CS_IME 0x00010000 +#define NT_CS_DROPSHADOW 0x00020000 + +#define NT_SWP_NOSIZE 0x0001 +#define NT_SWP_NOMOVE 0x0002 +#define NT_SWP_NOZORDER 0x0004 +#define NT_SWP_NOREDRAW 0x0008 +#define NT_SWP_NOACTIVATE 0x0010 +#define NT_SWP_FRAMECHANGED 0x0020 +#define NT_SWP_SHOWWINDOW 0x0040 +#define NT_SWP_HIDEWINDOW 0x0080 +#define NT_SWP_NOCOPYBITS 0x0100 +#define NT_SWP_NOOWNERZORDER 0x0200 +#define NT_SWP_NOSENDCHANGING 0x0400 +#define NT_SWP_DRAWFRAME SWP_FRAMECHANGED +#define NT_SWP_NOREPOSITION SWP_NOOWNERZORDER +#define NT_SWP_DEFERERASE 0x2000 +#define NT_SWP_ASYNCWINDOWPOS 0x4000 + +#define NT_RI_MOUSE_LEFT_BUTTON_DOWN 0x0001 +#define NT_RI_MOUSE_LEFT_BUTTON_UP 0x0002 +#define NT_RI_MOUSE_RIGHT_BUTTON_DOWN 0x0004 +#define NT_RI_MOUSE_RIGHT_BUTTON_UP 0x0008 +#define NT_RI_MOUSE_MIDDLE_BUTTON_DOWN 0x0010 +#define NT_RI_MOUSE_MIDDLE_BUTTON_UP 0x0020 +#define NT_RI_MOUSE_BUTTON_1_DOWN RI_MOUSE_LEFT_BUTTON_DOWN +#define NT_RI_MOUSE_BUTTON_1_UP RI_MOUSE_LEFT_BUTTON_UP +#define NT_RI_MOUSE_BUTTON_2_DOWN RI_MOUSE_RIGHT_BUTTON_DOWN +#define NT_RI_MOUSE_BUTTON_2_UP RI_MOUSE_RIGHT_BUTTON_UP +#define NT_RI_MOUSE_BUTTON_3_DOWN RI_MOUSE_MIDDLE_BUTTON_DOWN +#define NT_RI_MOUSE_BUTTON_3_UP RI_MOUSE_MIDDLE_BUTTON_UP +#define NT_RI_MOUSE_BUTTON_4_DOWN 0x0040 +#define NT_RI_MOUSE_BUTTON_4_UP 0x0080 +#define NT_RI_MOUSE_BUTTON_5_DOWN 0x0100 +#define NT_RI_MOUSE_BUTTON_5_UP 0x0200 +#define NT_RI_MOUSE_WHEEL 0x0400 +#define NT_MOUSE_MOVE_RELATIVE 0 +#define NT_MOUSE_MOVE_ABSOLUTE 1 +#define NT_MOUSE_VIRTUAL_DESKTOP 0x02 +#define NT_MOUSE_ATTRIBUTES_CHANGED 0x04 + +#define NT_STATE_SYSTEM_UNAVAILABLE 0x00000001 +#define NT_STATE_SYSTEM_SELECTED 0x00000002 +#define NT_STATE_SYSTEM_FOCUSED 0x00000004 +#define NT_STATE_SYSTEM_PRESSED 0x00000008 +#define NT_STATE_SYSTEM_CHECKED 0x00000010 +#define NT_STATE_SYSTEM_MIXED 0x00000020 +#define NT_STATE_SYSTEM_INDETERMINATE STATE_SYSTEM_MIXED +#define NT_STATE_SYSTEM_READONLY 0x00000040 +#define NT_STATE_SYSTEM_HOTTRACKED 0x00000080 +#define NT_STATE_SYSTEM_DEFAULT 0x00000100 +#define NT_STATE_SYSTEM_EXPANDED 0x00000200 +#define NT_STATE_SYSTEM_COLLAPSED 0x00000400 +#define NT_STATE_SYSTEM_BUSY 0x00000800 +#define NT_STATE_SYSTEM_FLOATING 0x00001000 +#define NT_STATE_SYSTEM_MARQUEED 0x00002000 +#define NT_STATE_SYSTEM_ANIMATED 0x00004000 +#define NT_STATE_SYSTEM_INVISIBLE 0x00008000 +#define NT_STATE_SYSTEM_OFFSCREEN 0x00010000 +#define NT_STATE_SYSTEM_SIZEABLE 0x00020000 +#define NT_STATE_SYSTEM_MOVEABLE 0x00040000 +#define NT_STATE_SYSTEM_SELFVOICING 0x00080000 +#define NT_STATE_SYSTEM_FOCUSABLE 0x00100000 +#define NT_STATE_SYSTEM_SELECTABLE 0x00200000 +#define NT_STATE_SYSTEM_LINKED 0x00400000 +#define NT_STATE_SYSTEM_TRAVERSED 0x00800000 +#define NT_STATE_SYSTEM_MULTISELECTABLE 0x01000000 +#define NT_STATE_SYSTEM_EXTSELECTABLE 0x02000000 +#define NT_STATE_SYSTEM_ALERT_LOW 0x04000000 +#define NT_STATE_SYSTEM_ALERT_MEDIUM 0x08000000 +#define NT_STATE_SYSTEM_ALERT_HIGH 0x10000000 +#define NT_STATE_SYSTEM_PROTECTED 0x20000000 +#define NT_STATE_SYSTEM_VALID 0x3FFFFFFF + +#define NT_IDH_NO_HELP 28440 +#define NT_IDH_MISSING_CONTEXT 28441 +#define NT_IDH_GENERIC_HELP_BUTTON 28442 +#define NT_IDH_OK 28443 +#define NT_IDH_CANCEL 28444 +#define NT_IDH_HELP 28445 + +#define NT_SS_LEFT 0x00000000 +#define NT_SS_CENTER 0x00000001 +#define NT_SS_RIGHT 0x00000002 +#define NT_SS_ICON 0x00000003 +#define NT_SS_BLACKRECT 0x00000004 +#define NT_SS_GRAYRECT 0x00000005 +#define NT_SS_WHITERECT 0x00000006 +#define NT_SS_BLACKFRAME 0x00000007 +#define NT_SS_GRAYFRAME 0x00000008 +#define NT_SS_WHITEFRAME 0x00000009 +#define NT_SS_USERITEM 0x0000000A +#define NT_SS_SIMPLE 0x0000000B +#define NT_SS_LEFTNOWORDWRAP 0x0000000C +#define NT_SS_OWNERDRAW 0x0000000D +#define NT_SS_BITMAP 0x0000000E +#define NT_SS_ENHMETAFILE 0x0000000F +#define NT_SS_ETCHEDHORZ 0x00000010 +#define NT_SS_ETCHEDVERT 0x00000011 +#define NT_SS_ETCHEDFRAME 0x00000012 +#define NT_SS_TYPEMASK 0x0000001F +#define NT_SS_REALSIZECONTROL 0x00000040 +#define NT_SS_NOPREFIX 0x00000080 +#define NT_SS_NOTIFY 0x00000100 +#define NT_SS_CENTERIMAGE 0x00000200 +#define NT_SS_RIGHTJUST 0x00000400 +#define NT_SS_REALSIZEIMAGE 0x00000800 +#define NT_SS_SUNKEN 0x00001000 +#define NT_SS_EDITCONTROL 0x00002000 +#define NT_SS_ENDELLIPSIS 0x00004000 +#define NT_SS_PATHELLIPSIS 0x00008000 +#define NT_SS_WORDELLIPSIS 0x0000C000 +#define NT_SS_ELLIPSISMASK 0x0000C000 + +#define NT_BST_UNCHECKED 0x0000 +#define NT_BST_CHECKED 0x0001 +#define NT_BST_INDETERMINATE 0x0002 +#define NT_BST_PUSHED 0x0004 +#define NT_BST_FOCUS 0x0008 + +#define NT_BS_PUSHBUTTON 0x00000000 +#define NT_BS_DEFPUSHBUTTON 0x00000001 +#define NT_BS_CHECKBOX 0x00000002 +#define NT_BS_AUTOCHECKBOX 0x00000003 +#define NT_BS_RADIOBUTTON 0x00000004 +#define NT_BS_3STATE 0x00000005 +#define NT_BS_AUTO3STATE 0x00000006 +#define NT_BS_GROUPBOX 0x00000007 +#define NT_BS_USERBUTTON 0x00000008 +#define NT_BS_AUTORADIOBUTTON 0x00000009 +#define NT_BS_PUSHBOX 0x0000000A +#define NT_BS_OWNERDRAW 0x0000000B +#define NT_BS_TYPEMASK 0x0000000F +#define NT_BS_LEFTTEXT 0x00000020 +#define NT_BS_TEXT 0x00000000 +#define NT_BS_ICON 0x00000040 +#define NT_BS_BITMAP 0x00000080 +#define NT_BS_LEFT 0x00000100 +#define NT_BS_RIGHT 0x00000200 +#define NT_BS_CENTER 0x00000300 +#define NT_BS_TOP 0x00000400 +#define NT_BS_BOTTOM 0x00000800 +#define NT_BS_VCENTER 0x00000C00 +#define NT_BS_PUSHLIKE 0x00001000 +#define NT_BS_MULTILINE 0x00002000 +#define NT_BS_NOTIFY 0x00004000 +#define NT_BS_FLAT 0x00008000 +#define NT_BS_RIGHTBUTTON BS_LEFTTEXT + +#define NT_BN_CLICKED 0 +#define NT_BN_PAINT 1 +#define NT_BN_HILITE 2 +#define NT_BN_UNHILITE 3 +#define NT_BN_DISABLE 4 +#define NT_BN_DOUBLECLICKED 5 +#define NT_BN_PUSHED BN_HILITE +#define NT_BN_UNPUSHED BN_UNHILITE +#define NT_BN_DBLCLK BN_DOUBLECLICKED +#define NT_BN_SETFOCUS 6 +#define NT_BN_KILLFOCUS 7 + +#define NT_BM_GETCHECK 0x00F0 +#define NT_BM_SETCHECK 0x00F1 +#define NT_BM_GETSTATE 0x00F2 +#define NT_BM_SETSTATE 0x00F3 +#define NT_BM_SETSTYLE 0x00F4 +#define NT_BM_CLICK 0x00F5 +#define NT_BM_GETIMAGE 0x00F6 +#define NT_BM_SETIMAGE 0x00F7 + +#define NT_GUI_CARETBLINKING 0x00000001 +#define NT_GUI_INMOVESIZE 0x00000002 +#define NT_GUI_INMENUMODE 0x00000004 +#define NT_GUI_SYSTEMMENUMODE 0x00000008 +#define NT_GUI_POPUPMENUMODE 0x00000010 +#define NT_GUI_16BITTASK 0x00000020 + +#define NT_ALERT_SYSTEM_INFORMATIONAL 1 +#define NT_ALERT_SYSTEM_WARNING 2 +#define NT_ALERT_SYSTEM_ERROR 3 +#define NT_ALERT_SYSTEM_QUERY 4 +#define NT_ALERT_SYSTEM_CRITICAL 5 + +#define NT_SOUND_SYSTEM_STARTUP 1 +#define NT_SOUND_SYSTEM_SHUTDOWN 2 +#define NT_SOUND_SYSTEM_BEEP 3 +#define NT_SOUND_SYSTEM_ERROR 4 +#define NT_SOUND_SYSTEM_QUESTION 5 +#define NT_SOUND_SYSTEM_WARNING 6 +#define NT_SOUND_SYSTEM_INFORMATION 7 +#define NT_SOUND_SYSTEM_MAXIMIZE 8 +#define NT_SOUND_SYSTEM_MINIMIZE 9 +#define NT_SOUND_SYSTEM_RESTOREUP 10 +#define NT_SOUND_SYSTEM_RESTOREDOWN 11 +#define NT_SOUND_SYSTEM_APPSTART 12 +#define NT_SOUND_SYSTEM_FAULT 13 +#define NT_SOUND_SYSTEM_APPEND 14 +#define NT_SOUND_SYSTEM_MENUCOMMAND 15 +#define NT_SOUND_SYSTEM_MENUPOPUP 16 +#define NT_CSOUND_SYSTEM 16 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +int64_t CreateWindowEx(uint32_t dwExStyle, const char16_t *lpClassName, + const char16_t *lpWindowName, uint32_t dwStyle, int X, + int Y, int nWidth, int nHeight, int64_t hWndParent, + int64_t hMenu, int64_t hInstance, void *lpParam); +int32_t CloseWindow(int64_t hWnd); +int32_t DestroyWindow(int64_t hWnd); +int32_t ShowWindow(int64_t hWnd, int nCmdShow); +int32_t AnimateWindow(int64_t hWnd, uint32_t dwTime, uint32_t dwFlags); +int64_t LoadIcon(int64_t hInstance, const char16_t *lpIconName); +int32_t IsWindow(int64_t hWnd); +int32_t IsMenu(int64_t hMenu); +int32_t IsChild(int64_t hWndParent, int64_t hWnd); +int32_t MoveWindow(int64_t hWnd, int X, int Y, int nWidth, int nHeight, + bool32 bRepaint); +int32_t BringWindowToTop(int64_t hWnd); +int32_t IsWindowVisible(int64_t hWnd); +int32_t IsZoomed(int64_t hWnd); +int32_t SetWindowText(int64_t hWnd, const char16_t *lpString); +int32_t GetWindowText(int64_t hWnd, char16_t *lpString, int nMaxCount); +int32_t SetWindowPos(int64_t hWnd, int64_t hWndInsertAfter, int X, int Y, + int cx, int cy, uint32_t uFlags); + +uintptr_t SetTimer(int64_t opt_hWnd, uintptr_t nIDEvent, uint32_t uElapseMs, + NtTimerProc lpTimerFunc); +int KillTimer(int64_t hWnd, uintptr_t uIDEvent); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_WINDOWS_H_ */ diff --git a/libc/nt/winsock.h b/libc/nt/winsock.h new file mode 100644 index 00000000..f20cce11 --- /dev/null +++ b/libc/nt/winsock.h @@ -0,0 +1,519 @@ +#ifndef COSMOPOLITAN_LIBC_NT_WINSOCK_H_ +#define COSMOPOLITAN_LIBC_NT_WINSOCK_H_ +#include "libc/nt/struct/overlapped.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/* ░▓█████████████████████████████████████████████▓▒ + ░█▓░░░░░░░░░▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓██▓▒░ + ░█▓░ ░▒▒▒▒ ▓██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██▓▒▒ + ░█▓░ ░▓▓▓▒ ▓██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██▓▒▒ + ░█▓░ ░▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓██▓▒▒ + ░███████████████████████████████████████████████▓▒▒ + ░█▓░ ▒█▓▒▒ + ░█▓░ ▒█▓▒▒ + ░█▓░ ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ ▒█▓▒▒ + ░█▓░ ░▒░ ▒█▓░ ▒█▓▒▒ + ░█▓░ ░░░░ ░░░░░░░░ ▒▓▓▓▒░ ▒█▓▒▒ + ░█▓░ ░░░░ ░░░░░▒▒▓███▓░░░░░░░░▒▓▓▓▓▒ ▒█▓▒▒ + ░█▓░ ░▒▒ ░░░░░░░▒▒████▓░░░░░░░░░░▒██▓ ▒█▓▒▒ + ░█▓░ ░▒▒ ░░░░░░░▒▒▓▓▓▓▓░░░░░░░░░▒▒██▓ ▒█▓▒▒ + ░█▓░ ░▒▒ ░░▒▒▒▒░░░░░ ░▒▒▒▒░░░░░▒▒██▓ ▒█▓▒▒ + ░█▓░ ░▒▒ ░░▒▓█▓░░░░░░░▒▓██▓░░░░▒▒██▓ ▒█▓▒▒ + ░█▓░ ░▒▒ ░░▒▓█▓░░░░░░░▒▓██▓░░░░▒▒██▓ ▒█▓▒▒ + ░█▓░ ░▒▒ ░░▒▓█▓░░░░░░░▒▓██▓░░░░▒▒██▓ ░▓█▓▒▒▒▒ + ░█▓░ ░▒▒ ░░▒▓█▓░░░░░░░▒▓██▓░░░░░▒██▓ ░████▓▒░ + ░█▓░ ░░░░░░░░▒▒░░░░░░░░░▒▒░░░▒▒▓▓▒░░ ░░▓███▓▒░ + ░█▓░ ░░░░░░░░░░░░░░░░░░░░░░▒▓▓▓▒░ ▒████▓▒░░░░░░ + ░█▓░ ░░▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒░░ ░▓▓▓▓██▒░░░░░░░░ + ░█▓░ ▒█████████████████▒ ▓█▓▒░ ▒█▓ ░█▓ ░▓▓░ + ░█▓░ ░▓████▒░ ▒█▓▒░ ░░░░░░░ ▓█▓░ + ░█▓░ ░▓████▒░ ░▒░ ░░░░░░░░░░░ ░█▓ + ░█▓ ▒███▓▒▒░ ░░░░░░░░░░░░░░░ ▒▓▓ + ░██████████████████████████████████████▓▒▓█▓░ ░░░░░░░░░░░░░░░░░░ ▒█▓ + ▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒░ ░░░░░░░░░░░░░░░░░░░░▒█▓ + ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒██▒▒▒░░░░░░░░░░░░░░░░░░░░░▒█▓ + ░██▒▒▒▒▒░░░░░░░░░░░░░░░░░░░▒█▓ + ░▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░▒▓█▓ + ░▓▓▓▒▒▒▒▒▒░░░░░░░░░░░▒▒▒▒▓▓▒ + ░██▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ░█▓ + ▒█▓▒▒▒▒▒▒▒▒▒▒▒██▓▒░ ░█▓ + ▒█████████████▓▒▒░ ░██▒ +╔────────────────────────────────────────────────────────────────▀▀▀▀───▀▀▀▀─│─╗ +│ cosmopolitan § new technology » winsock ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#endif + +#define kNtSioSocketCloseNotify 0x9800000Du +#define kNtSioUdpConnreset 0x9800000Cu +#define kNtSioUdpNetreset 0x9800000F + +#define kNtTfDisconnect 0x01 +#define kNtTfReuseSocket 0x02 +#define kNtTfWriteBehind 0x04 +#define kNtTfUseDefaultWorker 0x00 +#define kNtTfUseSystemThread 0x10 +#define kNtTfUseKernelApc 0x20 + +struct sockaddr; +struct sockaddr_in; +struct pollfd$nt; + +enum NtWsaEComparator { COMP_EQUAL, COMP_NOTLESS }; + +enum NtWsaCompletionType { + kNtNspNotifyImmediately = 0, + kNtNspNotifyHwnd, + kNtNspNotifyEvent, + kNtNspNotifyPort, + kNtNspNotifyApc, +}; + +struct timeval$nt { + int32_t tv_sec; /* [sic] */ + int32_t tv_usec; +}; + +struct iovec$nt { + uint32_t len; + char *buf; +}; + +struct msghdr$nt { + struct sockaddr *name; + int32_t namelen; + struct iovec$nt *lpBuffers; + uint32_t dwBufferCount; + struct iovec$nt Control; + uint32_t dwFlags; +}; + +struct NtWsaData { + uint16_t wVersion; + uint16_t wHighVersion; + uint16_t iMaxSockets; + uint16_t iMaxUdpDg; + char *lpVendorInfo; + char szDescription[257]; + char szSystemStatus[129]; +}; + +struct NtGuid { + uint32_t Data1; + uint16_t Data2; + uint16_t Data3; + uint8_t Data4[8]; +}; + +struct NtSocketAddress { + struct sockaddr *lpSockaddr; + int32_t iSockaddrLength; +}; + +struct NtSocketAddressList { + int32_t iAddressCount; + struct NtSocketAddress Address[1]; +}; + +struct NtAddrInfoEx { /* win8+ */ + int32_t ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */ + int32_t ai_family; /* PF_XXX */ + int32_t ai_socktype; /* SOCK_XXX */ + int32_t ai_protocol; + uint64_t ai_addrlen; + char16_t *ai_canonname; + struct sockaddr *ai_addr; + void *ai_blob; + uint64_t ai_bloblen; + struct NtGuid *ai_provider; + struct NtAddrInfoEx *ai_next; + int32_t ai_version; /* v2 */ + char16_t *ai_fqdn; /* v2 */ + int32_t ai_interfaceindex; /* v3 */ + int64_t ai_resolutionhandle; /* v4 */ +}; + +struct NtWsaProtocolChain { + int32_t ChainLen; + uint32_t ChainEntries[7]; +}; + +struct NtWsaProtocolInfo { + uint32_t dwServiceFlags1; + uint32_t dwServiceFlags2; + uint32_t dwServiceFlags3; + uint32_t dwServiceFlags4; + uint32_t dwProviderFlags; + struct NtGuid ProviderId; + uint32_t dwCatalogEntryId; + struct NtWsaProtocolChain ProtocolChain; + int32_t iVersion; + int32_t iAddressFamily; + int32_t iMaxSockAddr; + int32_t iMinSockAddr; + int32_t iSocketType; + int32_t iProtocol; + int32_t iProtocolMaxOffset; + int32_t iNetworkByteOrder; + int32_t iSecurityScheme; + uint32_t dwMessageSize; + uint32_t dwProviderReserved; + char16_t szProtocol[256]; +}; + +struct NtFlowSpec { + uint32_t TokenRate; /* bytes/sec */ + uint32_t TokenBucketSize; /* bytes */ + uint32_t PeakBandwidth; /* bytes/sec */ + uint32_t Latency; /* µs */ + uint32_t DelayVariation; /* µs */ + uint32_t ServiceType; /* kNtServicetypeXxx */ + uint32_t MaxSduSize; /* bytes */ + uint32_t MinimumPolicedSize; /* bytes */ +}; + +struct NtQos { + struct NtFlowSpec SendingFlowspec; + struct NtFlowSpec ReceivingFlowspec; + struct iovec$nt ProviderSpecific; +}; + +struct NtWsaVersion { + uint32_t dwVersion; + enum NtWsaEComparator ecHow; +}; + +struct NtAfProtocols { + int32_t iAddressFamily; + int32_t iProtocol; +}; + +struct NtBlob { + uint32_t cbSize; + uint8_t pBlobData; +}; + +struct NtCsAddrInfo { + struct NtSocketAddress LocalAddr; + struct NtSocketAddress RemoteAddr; + int32_t iSocketType; + int32_t iProtocol; +}; + +struct NtWsaQuerySet { + uint32_t dwSize; /* of this */ + char16_t *lpszServiceInstanceName; + struct NtGuid *lpServiceClassId; + struct NtWsaVersion *lpVersion; + char16_t *lpszComment; + uint32_t dwNameSpace; + struct NtGuid *lpNSProviderId; + char16_t *lpszContext; + uint32_t dwNumberOfProtocols; + struct NtAfProtocols *lpafpProtocols /*[dwNumberOfProtocols]*/; + char16_t *lpszQueryString; + uint32_t dwNumberOfCsAddrs; + struct NtCsAddrInfo *lpcsaBuffer /*[dwNumberOfCsAddrs]*/; + uint32_t dwOutputFlags; + struct NtBlob *lpBlob; +}; + +struct NtWsaNamespaceInfoEx { + struct NtGuid NSProviderId; + uint32_t dwNameSpace; + bool32 fActive; + uint32_t dwVersion; + char16_t *lpszIdentifier; + struct NtBlob *ProviderSpecific; +}; + +struct NtWsansClassInfo { + char16_t *lpszName; + uint32_t dwNameSpace; + uint32_t dwValueType; + uint32_t dwValueSize; + void *lpValue; +}; + +struct NtWsaServiceClassInfo { + struct NtGuid *lpServiceClassId; + char16_t *lpszServiceClassName; + uint32_t dwCount; + struct NtWsansClassInfo *lpClassInfos; +}; + +struct NtWsaNetworkEvents { + int32_t lNetworkEvents; + int32_t iErrorCode[10]; +}; + +struct NtTransmitFileBuffers { + void *Head; + uint32_t HeadLength; + void *Tail; + uint32_t TailLength; +}; + +typedef int (*NtConditionProc)( + const struct iovec$nt *lpCallerId, const struct iovec$nt *lpCallerData, + struct NtQos *inout_lpSQOS, struct NtQos *inout_lpGQOS, + const struct iovec$nt *lpCalleeId, const struct iovec$nt *lpCalleeData, + uint32_t *out_group, const uint32_t *dwCallbackData); + +typedef void (*NtWsaOverlappedCompletionRoutine)( + uint32_t dwError, uint32_t cbTransferred, + const struct NtOverlapped *lpOverlapped, uint32_t dwFlags); + +struct NtWsaCompletion { + enum NtWsaCompletionType Type; + union { + struct { + int64_t hWnd; + uint32_t uMsg; + uintptr_t context; + } WindowMessage; + struct { + struct NtOverlapped *lpOverlapped; + } Event; + struct { + struct NtOverlapped *lpOverlapped; + NtWsaOverlappedCompletionRoutine lpfnCompletionProc; + } Apc; + struct { + struct NtOverlapped *lpOverlapped; + int64_t hPort; + uint32_t Key; + } Port; + } Parameters; +}; + +/** + * Winsock2 prototypes. + * + * @note Some of the functions exported by WS2_32.DLL, e.g. bind(), + * overlap with the names used by System V. Prototypes for these + * functions are declared within their respective wrappers. + */ + +nodiscard int32_t WSAStartup(uint16_t wVersionRequested, + struct NtWsaData *lpWSAData) paramsnonnull(); + +int WSACleanup(void); +int WSAGetLastError(void); +void WSASetLastError(int); + +int __bind$nt(uint64_t, const void *, int); +int __closesocket$nt(uint64_t); +int __getpeername$nt(uint64_t, void *, uint32_t *); +int __getsockname$nt(uint64_t, void *, uint32_t *); +int __getsockopt$nt(uint64_t, int, int, void *, uint32_t *); +int __ioctlsocket$nt(uint64_t, int32_t, uint32_t *); +int __listen$nt(uint64_t, int); +int __setsockopt$nt(uint64_t, int, int, const void *, int); +int __shutdown$nt(uint64_t, int); + +nodiscard uint64_t WSASocket(int af, int type, int protocol, + const struct NtWsaProtocolInfo *opt_lpProtocolInfo, + const uint32_t opt_group, uint32_t dwFlags); + +int WSAConnect(uint64_t s, const struct sockaddr *name, const int namelen, + const struct iovec$nt *opt_lpCallerData, + struct iovec$nt *opt_out_lpCalleeData, + const struct NtQos *opt_lpSQOS, const struct NtQos *opt_lpGQOS) + paramsnonnull((2)); + +bool32 WSAConnectByName(uint64_t s, const char16_t *nodename, + const char16_t *servicename, + uint32_t *opt_inout_LocalAddressLength, + struct sockaddr *out_LocalAddress, + uint32_t *opt_inout_RemoteAddressLength, + struct sockaddr *out_RemoteAddress, + const struct timeval$nt *opt_timeout, + struct NtOverlapped *__Reserved) paramsnonnull((2, 3)); + +bool32 WSAConnectByList(uint64_t s, + const struct NtSocketAddressList *SocketAddress, + uint32_t *opt_inout_LocalAddressLength, + struct sockaddr *out_LocalAddress, + uint32_t *opt_inout_RemoteAddressLength, + struct sockaddr *out_RemoteAddress, + const struct timeval$nt *opt_timeout, + struct NtOverlapped *__Reserved) paramsnonnull((2)); + +nodiscard int64_t WSAAccept(uint64_t s, struct sockaddr *out_addr, + int32_t *opt_inout_addrlen, + const NtConditionProc opt_lpfnCondition, + const uint32_t *opt_dwCallbackData) + paramsnonnull((2)); + +int WSASend(uint64_t s, const struct iovec$nt *lpBuffers, + uint32_t dwBufferCount, uint32_t *opt_out_lpNumberOfBytesSent, + uint32_t dwFlags, struct NtOverlapped *opt_inout_lpOverlapped, + const NtWsaOverlappedCompletionRoutine opt_lpCompletionRoutine) + paramsnonnull((2)); + +int WSASendMsg(int64_t Handle, const struct msghdr$nt *lpMsg, uint32_t dwFlags, + uint32_t *opt_out_lpNumberOfBytesSent, + struct NtOverlapped *opt_inout_lpOverlapped, + const NtWsaOverlappedCompletionRoutine opt_lpCompletionRoutine) + paramsnonnull((2)); + +int WSASendTo(uint64_t s, const struct iovec$nt *lpBuffers, + uint32_t dwBufferCount, + uint32_t *opt_out_lpNumberOfBytesSent /* opt if !overlapped */, + uint32_t dwFlags, const void *opt_tosockaddr, + int32_t tosockaddrlen, + struct NtOverlapped *opt_inout_lpOverlapped, + const NtWsaOverlappedCompletionRoutine opt_lpCompletionRoutine) + paramsnonnull((2)); + +int WSAPoll(struct pollfd$nt *inout_fdArray, uint32_t nfds, signed timeout_ms) + paramsnonnull(); + +int WSARecv(uint64_t s, const struct iovec$nt *out_lpBuffers, + uint32_t dwBufferCount, uint32_t *opt_out_lpNumberOfBytesRecvd, + uint32_t *inout_lpFlags, + struct NtOverlapped *opt_inout_lpOverlapped, + const NtWsaOverlappedCompletionRoutine opt_lpCompletionRoutine) + paramsnonnull((2, 5)); + +int WSARecvFrom(uint64_t s, const struct iovec$nt *out_lpBuffers, + uint32_t dwBufferCount, uint32_t *opt_out_lpNumberOfBytesRecvd, + uint32_t *inout_lpFlags, void *out_fromsockaddr, + uint32_t *inout_fromsockaddrlen, + struct NtOverlapped *opt_inout_lpOverlapped, + const NtWsaOverlappedCompletionRoutine opt_lpCompletionRoutine) + paramsnonnull((2, 5, 6, 7)); + +int WSARecvDisconnect(uint64_t s, + const struct iovec$nt *opt_lpInboundDisconnectData); + +int WSADuplicateSocket(uint64_t s, uint32_t dwProcessId, + struct NtWsaProtocolInfo *out_lpProtocolInfo) + paramsnonnull((3)); + +int WSAIoctl(uint64_t s, uint32_t dwIoControlCode, const void *lpvInBuffer, + uint32_t cbInBuffer, void *out_lpvOutBuffer, uint32_t cbOutBuffer, + uint32_t *out_lpcbBytesReturned, + struct NtOverlapped *opt_inout_lpOverlapped, + const NtWsaOverlappedCompletionRoutine opt_lpCompletionRoutine) + paramsnonnull((3, 5, 7)); + +int WSANSPIoctl(int64_t hLookup, uint32_t dwControlCode, + const void *lpvInBuffer, uint32_t cbInBuffer, + void *out_lpvOutBuffer, uint32_t cbOutBuffer, + uint32_t *out_lpcbBytesReturned, + const struct NtWsaCompletion *opt_lpCompletion) + paramsnonnull((3, 5, 7)); + +nodiscard int64_t WSACreateEvent(void); +bool32 WSACloseEvent(const int64_t hEvent); +bool32 WSAResetEvent(const int64_t hEvent); +bool32 WSASetEvent(const int64_t hEvent); + +int WSAEventSelect(uint64_t s, const int64_t opt_hEventObject, + long lNetworkEvents); + +uint32_t WSAWaitForMultipleEvents(uint32_t cEvents, const int64_t *lphEvents, + bool32 fWaitAll, uint32_t dwTimeout_ms, + bool32 fAlertable) paramsnonnull(); + +int WSAEnumNetworkEvents(uint64_t s, const int64_t hEventObject, + struct NtWsaNetworkEvents *out_lpNetworkEvents) + paramsnonnull(); + +bool32 WSAGetOverlappedResult(uint64_t s, + const struct NtOverlapped *lpOverlapped, + uint32_t *out_lpcbTransfer, bool32 fWait, + uint32_t *out_lpdwFlags) paramsnonnull(); + +int WSAEnumProtocols(const int32_t *opt_lpiProtocols, + struct NtWsaProtocolInfo *out_lpProtocolBuffer, + uint32_t *inout_lpdwBufferLength) paramsnonnull(); + +bool32 WSAGetQOSByName(uint64_t s, const struct iovec$nt *lpQOSName, + struct NtQos *out_lpQOS) paramsnonnull(); + +uint64_t WSAJoinLeaf(uint64_t s, const struct sockaddr *name, const int namelen, + const struct iovec$nt *opt_lpCallerData, + struct iovec$nt *opt_out_lpCalleeData, + const struct NtQos *opt_lpSQOS, + const struct NtQos *opt_lpGQOS, uint32_t dwFlags) + paramsnonnull((2, 4)); + +int WSALookupServiceBegin(const struct NtWsaQuerySet *lpqsRestrictions, + uint32_t dwControlFlags, int64_t *out_lphLookup) + paramsnonnull(); + +int WSALookupServiceNext(const int64_t hLookup, uint32_t dwControlFlags, + uint32_t *inout_lpdwBufferLength, + struct NtWsaQuerySet *out_lpqsResults) paramsnonnull(); + +int WSALookupServiceEnd(int64_t hLookup); + +int WSAAddressToString(const struct sockaddr *lpsaAddress, + uint32_t dwAddressLength, + const struct NtWsaProtocolInfo *opt_lpProtocolInfo, + char16_t *out_lpszAddressString, + uint32_t *inout_lpdwAddressStringLength) + paramsnonnull((1, 4, 5)); + +int WSAStringToAddress(const char16_t *AddressString, int AddressFamily, + const struct NtWsaProtocolInfo *opt_lpProtocolInfo, + struct sockaddr *out_lpAddress, + int *inout_lpAddressLength) paramsnonnull((1, 3, 4)); + +int WSAEnumNameSpaceProvidersEx(uint32_t *inout_lpdwBufferLength, + struct NtWsaNamespaceInfoEx *out_lpnspBuffer) + paramsnonnull(); + +int WSAProviderConfigChange( + int64_t *inout_lpNotificationHandle, + struct NtOverlapped *opt_inout_lpOverlapped, + NtWsaOverlappedCompletionRoutine opt_lpCompletionRoutine) + paramsnonnull((1)); + +int WSAInstallServiceClass( + const struct NtWsaServiceClassInfo *lpServiceClassInfo) paramsnonnull(); + +int WSARemoveServiceClass(const struct NtGuid *lpServiceClassId) + paramsnonnull(); + +int WSAGetServiceClassInfo(const struct NtGuid *lpProviderId, + const struct NtGuid *lpServiceClassId, + uint32_t *inout_lpdwBufSize, + struct NtWsaServiceClassInfo *out_lpServiceClassInfo) + paramsnonnull((1, 2, 3)); + +int WSASetService(const struct NtWsaQuerySet *lpqsRegInfo, int essoperation, + uint32_t dwControlFlags) paramsnonnull(); + +int /* success==0 */ WSAGetServiceClassNameByClassId( + const struct NtGuid *lpServiceClassId, char16_t *out_lpszServiceClassName, + uint32_t *inout_lpdwBufferLength) paramsnonnull(); + +bool32 TransmitFile(int64_t hSocket, int64_t hFile, + uint32_t opt_nNumberOfBytesToWrite, + uint32_t opt_nNumberOfBytesPerSend, + struct NtOverlapped *opt_inout_lpOverlapped, + const struct NtTransmitFileBuffers *opt_lpTransmitBuffers, + uint32_t dwReserved); + +bool32 AcceptEx(int64_t sListenSocket, int64_t sAcceptSocket, + void *out_lpOutputBuffer /*[recvlen+local+remoteaddrlen]*/, + uint32_t dwReceiveDataLength, uint32_t dwLocalAddressLength, + uint32_t dwRemoteAddressLength, uint32_t *out_lpdwBytesReceived, + struct NtOverlapped inout_lpOverlapped); + +void GetAcceptExSockaddrs( + const void *lpOutputBuffer /*[recvsize+addrsize+addrlen]*/, + uint32_t dwReceiveDataLength, uint32_t dwLocalAddressLength, + uint32_t dwRemoteAddressLength, + struct sockaddr **out_LocalSockaddr /*[*LocalSockaddrLength]*/, + int *out_LocalSockaddrLength, + struct sockaddr **out_RemoteSockaddr /*[*RemoteSockaddrLength]*/, + int *out_RemoteSockaddrLength); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_WINSOCK_H_ */ diff --git a/libc/nt/ws2_32/FreeAddrInfoExW.s b/libc/nt/ws2_32/FreeAddrInfoExW.s new file mode 100644 index 00000000..2632bbcc --- /dev/null +++ b/libc/nt/ws2_32/FreeAddrInfoExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_FreeAddrInfoExW,FreeAddrInfoExW,26 diff --git a/libc/nt/ws2_32/FreeAddrInfoW.s b/libc/nt/ws2_32/FreeAddrInfoW.s new file mode 100644 index 00000000..3eb3ba0a --- /dev/null +++ b/libc/nt/ws2_32/FreeAddrInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_FreeAddrInfoW,FreeAddrInfoW,27 diff --git a/libc/nt/ws2_32/GetAddrInfoExA.s b/libc/nt/ws2_32/GetAddrInfoExA.s new file mode 100644 index 00000000..f82df9e8 --- /dev/null +++ b/libc/nt/ws2_32/GetAddrInfoExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_GetAddrInfoExA,GetAddrInfoExA,28 diff --git a/libc/nt/ws2_32/GetAddrInfoExCancel.s b/libc/nt/ws2_32/GetAddrInfoExCancel.s new file mode 100644 index 00000000..26c3f210 --- /dev/null +++ b/libc/nt/ws2_32/GetAddrInfoExCancel.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_GetAddrInfoExCancel,GetAddrInfoExCancel,29 diff --git a/libc/nt/ws2_32/GetAddrInfoExOverlappedResult.s b/libc/nt/ws2_32/GetAddrInfoExOverlappedResult.s new file mode 100644 index 00000000..ecc018e1 --- /dev/null +++ b/libc/nt/ws2_32/GetAddrInfoExOverlappedResult.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_GetAddrInfoExOverlappedResult,GetAddrInfoExOverlappedResult,30 diff --git a/libc/nt/ws2_32/GetAddrInfoExW.s b/libc/nt/ws2_32/GetAddrInfoExW.s new file mode 100644 index 00000000..a38009ab --- /dev/null +++ b/libc/nt/ws2_32/GetAddrInfoExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_GetAddrInfoExW,GetAddrInfoExW,31 diff --git a/libc/nt/ws2_32/GetAddrInfoW.s b/libc/nt/ws2_32/GetAddrInfoW.s new file mode 100644 index 00000000..555724a6 --- /dev/null +++ b/libc/nt/ws2_32/GetAddrInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_GetAddrInfoW,GetAddrInfoW,32 diff --git a/libc/nt/ws2_32/GetHostNameW.s b/libc/nt/ws2_32/GetHostNameW.s new file mode 100644 index 00000000..80c9b385 --- /dev/null +++ b/libc/nt/ws2_32/GetHostNameW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_GetHostNameW,GetHostNameW,33 diff --git a/libc/nt/ws2_32/GetNameInfoW.s b/libc/nt/ws2_32/GetNameInfoW.s new file mode 100644 index 00000000..5282af10 --- /dev/null +++ b/libc/nt/ws2_32/GetNameInfoW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_GetNameInfoW,GetNameInfoW,34 diff --git a/libc/nt/ws2_32/InetNtopW.s b/libc/nt/ws2_32/InetNtopW.s new file mode 100644 index 00000000..0dd92927 --- /dev/null +++ b/libc/nt/ws2_32/InetNtopW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_InetNtopW,InetNtopW,35 diff --git a/libc/nt/ws2_32/InetPtonW.s b/libc/nt/ws2_32/InetPtonW.s new file mode 100644 index 00000000..c01ac598 --- /dev/null +++ b/libc/nt/ws2_32/InetPtonW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_InetPtonW,InetPtonW,36 diff --git a/libc/nt/ws2_32/SetAddrInfoExA.s b/libc/nt/ws2_32/SetAddrInfoExA.s new file mode 100644 index 00000000..f16c0ff1 --- /dev/null +++ b/libc/nt/ws2_32/SetAddrInfoExA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_SetAddrInfoExA,SetAddrInfoExA,37 diff --git a/libc/nt/ws2_32/SetAddrInfoExW.s b/libc/nt/ws2_32/SetAddrInfoExW.s new file mode 100644 index 00000000..b9b0ad93 --- /dev/null +++ b/libc/nt/ws2_32/SetAddrInfoExW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_SetAddrInfoExW,SetAddrInfoExW,38 diff --git a/libc/nt/ws2_32/WEP.s b/libc/nt/ws2_32/WEP.s new file mode 100644 index 00000000..67475c3f --- /dev/null +++ b/libc/nt/ws2_32/WEP.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WEP,WEP,500 diff --git a/libc/nt/ws2_32/WPUCompleteOverlappedRequest.s b/libc/nt/ws2_32/WPUCompleteOverlappedRequest.s new file mode 100644 index 00000000..f7cb885b --- /dev/null +++ b/libc/nt/ws2_32/WPUCompleteOverlappedRequest.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WPUCompleteOverlappedRequest,WPUCompleteOverlappedRequest,39 diff --git a/libc/nt/ws2_32/WPUGetProviderPathEx.s b/libc/nt/ws2_32/WPUGetProviderPathEx.s new file mode 100644 index 00000000..597207d1 --- /dev/null +++ b/libc/nt/ws2_32/WPUGetProviderPathEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WPUGetProviderPathEx,WPUGetProviderPathEx,40 diff --git a/libc/nt/ws2_32/WSAAccept.s b/libc/nt/ws2_32/WSAAccept.s new file mode 100644 index 00000000..64a30bf5 --- /dev/null +++ b/libc/nt/ws2_32/WSAAccept.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAAccept,WSAAccept,41 + + .text.windows +WSAAccept: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAAccept(%rip),%rax + jmp __sysv2nt6 + .endfn WSAAccept,globl + .previous diff --git a/libc/nt/ws2_32/WSAAddressToStringA.s b/libc/nt/ws2_32/WSAAddressToStringA.s new file mode 100644 index 00000000..e394acb0 --- /dev/null +++ b/libc/nt/ws2_32/WSAAddressToStringA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAAddressToStringA,WSAAddressToStringA,42 + + .text.windows +WSAAddressToStringA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAAddressToStringA(%rip),%rax + jmp __sysv2nt6 + .endfn WSAAddressToStringA,globl + .previous diff --git a/libc/nt/ws2_32/WSAAddressToStringW.s b/libc/nt/ws2_32/WSAAddressToStringW.s new file mode 100644 index 00000000..1a1688ed --- /dev/null +++ b/libc/nt/ws2_32/WSAAddressToStringW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAAddressToStringW,WSAAddressToStringW,43 + + .text.windows +WSAAddressToString: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAAddressToStringW(%rip),%rax + jmp __sysv2nt6 + .endfn WSAAddressToString,globl + .previous diff --git a/libc/nt/ws2_32/WSAAdvertiseProvider.s b/libc/nt/ws2_32/WSAAdvertiseProvider.s new file mode 100644 index 00000000..e2862fdc --- /dev/null +++ b/libc/nt/ws2_32/WSAAdvertiseProvider.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAAdvertiseProvider,WSAAdvertiseProvider,44 diff --git a/libc/nt/ws2_32/WSAAsyncGetHostByAddr.s b/libc/nt/ws2_32/WSAAsyncGetHostByAddr.s new file mode 100644 index 00000000..03f44b28 --- /dev/null +++ b/libc/nt/ws2_32/WSAAsyncGetHostByAddr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAAsyncGetHostByAddr,WSAAsyncGetHostByAddr,102 diff --git a/libc/nt/ws2_32/WSAAsyncGetHostByName.s b/libc/nt/ws2_32/WSAAsyncGetHostByName.s new file mode 100644 index 00000000..e8f72e41 --- /dev/null +++ b/libc/nt/ws2_32/WSAAsyncGetHostByName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAAsyncGetHostByName,WSAAsyncGetHostByName,103 diff --git a/libc/nt/ws2_32/WSAAsyncGetProtoByName.s b/libc/nt/ws2_32/WSAAsyncGetProtoByName.s new file mode 100644 index 00000000..22a983fc --- /dev/null +++ b/libc/nt/ws2_32/WSAAsyncGetProtoByName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAAsyncGetProtoByName,WSAAsyncGetProtoByName,105 diff --git a/libc/nt/ws2_32/WSAAsyncGetProtoByNumber.s b/libc/nt/ws2_32/WSAAsyncGetProtoByNumber.s new file mode 100644 index 00000000..0263e0d1 --- /dev/null +++ b/libc/nt/ws2_32/WSAAsyncGetProtoByNumber.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAAsyncGetProtoByNumber,WSAAsyncGetProtoByNumber,104 diff --git a/libc/nt/ws2_32/WSAAsyncGetServByName.s b/libc/nt/ws2_32/WSAAsyncGetServByName.s new file mode 100644 index 00000000..2c0139bc --- /dev/null +++ b/libc/nt/ws2_32/WSAAsyncGetServByName.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAAsyncGetServByName,WSAAsyncGetServByName,107 diff --git a/libc/nt/ws2_32/WSAAsyncGetServByPort.s b/libc/nt/ws2_32/WSAAsyncGetServByPort.s new file mode 100644 index 00000000..ea9a229d --- /dev/null +++ b/libc/nt/ws2_32/WSAAsyncGetServByPort.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAAsyncGetServByPort,WSAAsyncGetServByPort,106 diff --git a/libc/nt/ws2_32/WSAAsyncSelect.s b/libc/nt/ws2_32/WSAAsyncSelect.s new file mode 100644 index 00000000..a83e37f4 --- /dev/null +++ b/libc/nt/ws2_32/WSAAsyncSelect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAAsyncSelect,WSAAsyncSelect,101 diff --git a/libc/nt/ws2_32/WSACancelAsyncRequest.s b/libc/nt/ws2_32/WSACancelAsyncRequest.s new file mode 100644 index 00000000..5f65429a --- /dev/null +++ b/libc/nt/ws2_32/WSACancelAsyncRequest.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSACancelAsyncRequest,WSACancelAsyncRequest,108 diff --git a/libc/nt/ws2_32/WSACancelBlockingCall.s b/libc/nt/ws2_32/WSACancelBlockingCall.s new file mode 100644 index 00000000..aed60a7e --- /dev/null +++ b/libc/nt/ws2_32/WSACancelBlockingCall.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSACancelBlockingCall,WSACancelBlockingCall,113 diff --git a/libc/nt/ws2_32/WSACleanup.s b/libc/nt/ws2_32/WSACleanup.s new file mode 100644 index 00000000..c7933b82 --- /dev/null +++ b/libc/nt/ws2_32/WSACleanup.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSACleanup,WSACleanup,116 + + .text.windows +WSACleanup: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_WSACleanup(%rip) + leave + ret + .endfn WSACleanup,globl + .previous diff --git a/libc/nt/ws2_32/WSACloseEvent.s b/libc/nt/ws2_32/WSACloseEvent.s new file mode 100644 index 00000000..9efebb56 --- /dev/null +++ b/libc/nt/ws2_32/WSACloseEvent.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSACloseEvent,WSACloseEvent,45 + + .text.windows +WSACloseEvent: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_WSACloseEvent(%rip) + leave + ret + .endfn WSACloseEvent,globl + .previous diff --git a/libc/nt/ws2_32/WSAConnect.s b/libc/nt/ws2_32/WSAConnect.s new file mode 100644 index 00000000..b7bfe37b --- /dev/null +++ b/libc/nt/ws2_32/WSAConnect.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAConnect,WSAConnect,46 + + .text.windows +WSAConnect: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAConnect(%rip),%rax + jmp __sysv2nt8 + .endfn WSAConnect,globl + .previous diff --git a/libc/nt/ws2_32/WSAConnectByList.s b/libc/nt/ws2_32/WSAConnectByList.s new file mode 100644 index 00000000..18a3314b --- /dev/null +++ b/libc/nt/ws2_32/WSAConnectByList.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAConnectByList,WSAConnectByList,47 + + .text.windows +WSAConnectByList: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAConnectByList(%rip),%rax + jmp __sysv2nt8 + .endfn WSAConnectByList,globl + .previous diff --git a/libc/nt/ws2_32/WSAConnectByNameA.s b/libc/nt/ws2_32/WSAConnectByNameA.s new file mode 100644 index 00000000..306f9686 --- /dev/null +++ b/libc/nt/ws2_32/WSAConnectByNameA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAConnectByNameA,WSAConnectByNameA,48 + + .text.windows +WSAConnectByNameA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAConnectByNameA(%rip),%rax + jmp __sysv2nt10 + .endfn WSAConnectByNameA,globl + .previous diff --git a/libc/nt/ws2_32/WSAConnectByNameW.s b/libc/nt/ws2_32/WSAConnectByNameW.s new file mode 100644 index 00000000..43b9feda --- /dev/null +++ b/libc/nt/ws2_32/WSAConnectByNameW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAConnectByNameW,WSAConnectByNameW,49 + + .text.windows +WSAConnectByName: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAConnectByNameW(%rip),%rax + jmp __sysv2nt10 + .endfn WSAConnectByName,globl + .previous diff --git a/libc/nt/ws2_32/WSACreateEvent.s b/libc/nt/ws2_32/WSACreateEvent.s new file mode 100644 index 00000000..6e012e86 --- /dev/null +++ b/libc/nt/ws2_32/WSACreateEvent.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSACreateEvent,WSACreateEvent,50 + + .text.windows +WSACreateEvent: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_WSACreateEvent(%rip) + leave + ret + .endfn WSACreateEvent,globl + .previous diff --git a/libc/nt/ws2_32/WSADuplicateSocketA.s b/libc/nt/ws2_32/WSADuplicateSocketA.s new file mode 100644 index 00000000..e303b41c --- /dev/null +++ b/libc/nt/ws2_32/WSADuplicateSocketA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSADuplicateSocketA,WSADuplicateSocketA,58 + + .text.windows +WSADuplicateSocketA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSADuplicateSocketA(%rip),%rax + jmp __sysv2nt + .endfn WSADuplicateSocketA,globl + .previous diff --git a/libc/nt/ws2_32/WSADuplicateSocketW.s b/libc/nt/ws2_32/WSADuplicateSocketW.s new file mode 100644 index 00000000..760a7889 --- /dev/null +++ b/libc/nt/ws2_32/WSADuplicateSocketW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSADuplicateSocketW,WSADuplicateSocketW,59 + + .text.windows +WSADuplicateSocket: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSADuplicateSocketW(%rip),%rax + jmp __sysv2nt + .endfn WSADuplicateSocket,globl + .previous diff --git a/libc/nt/ws2_32/WSAEnumNameSpaceProvidersA.s b/libc/nt/ws2_32/WSAEnumNameSpaceProvidersA.s new file mode 100644 index 00000000..41fe7cde --- /dev/null +++ b/libc/nt/ws2_32/WSAEnumNameSpaceProvidersA.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAEnumNameSpaceProvidersA,WSAEnumNameSpaceProvidersA,60 diff --git a/libc/nt/ws2_32/WSAEnumNameSpaceProvidersExA.s b/libc/nt/ws2_32/WSAEnumNameSpaceProvidersExA.s new file mode 100644 index 00000000..689d45a1 --- /dev/null +++ b/libc/nt/ws2_32/WSAEnumNameSpaceProvidersExA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAEnumNameSpaceProvidersExA,WSAEnumNameSpaceProvidersExA,61 + + .text.windows +WSAEnumNameSpaceProvidersExA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAEnumNameSpaceProvidersExA(%rip),%rax + jmp __sysv2nt + .endfn WSAEnumNameSpaceProvidersExA,globl + .previous diff --git a/libc/nt/ws2_32/WSAEnumNameSpaceProvidersExW.s b/libc/nt/ws2_32/WSAEnumNameSpaceProvidersExW.s new file mode 100644 index 00000000..558c8a2f --- /dev/null +++ b/libc/nt/ws2_32/WSAEnumNameSpaceProvidersExW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAEnumNameSpaceProvidersExW,WSAEnumNameSpaceProvidersExW,62 + + .text.windows +WSAEnumNameSpaceProvidersEx: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAEnumNameSpaceProvidersExW(%rip),%rax + jmp __sysv2nt + .endfn WSAEnumNameSpaceProvidersEx,globl + .previous diff --git a/libc/nt/ws2_32/WSAEnumNameSpaceProvidersW.s b/libc/nt/ws2_32/WSAEnumNameSpaceProvidersW.s new file mode 100644 index 00000000..3537e5d6 --- /dev/null +++ b/libc/nt/ws2_32/WSAEnumNameSpaceProvidersW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAEnumNameSpaceProvidersW,WSAEnumNameSpaceProvidersW,63 diff --git a/libc/nt/ws2_32/WSAEnumNetworkEvents.s b/libc/nt/ws2_32/WSAEnumNetworkEvents.s new file mode 100644 index 00000000..51e61850 --- /dev/null +++ b/libc/nt/ws2_32/WSAEnumNetworkEvents.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAEnumNetworkEvents,WSAEnumNetworkEvents,64 + + .text.windows +WSAEnumNetworkEvents: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAEnumNetworkEvents(%rip),%rax + jmp __sysv2nt + .endfn WSAEnumNetworkEvents,globl + .previous diff --git a/libc/nt/ws2_32/WSAEnumProtocolsA.s b/libc/nt/ws2_32/WSAEnumProtocolsA.s new file mode 100644 index 00000000..91265c01 --- /dev/null +++ b/libc/nt/ws2_32/WSAEnumProtocolsA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAEnumProtocolsA,WSAEnumProtocolsA,65 + + .text.windows +WSAEnumProtocolsA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAEnumProtocolsA(%rip),%rax + jmp __sysv2nt + .endfn WSAEnumProtocolsA,globl + .previous diff --git a/libc/nt/ws2_32/WSAEnumProtocolsW.s b/libc/nt/ws2_32/WSAEnumProtocolsW.s new file mode 100644 index 00000000..30cd96d4 --- /dev/null +++ b/libc/nt/ws2_32/WSAEnumProtocolsW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAEnumProtocolsW,WSAEnumProtocolsW,66 + + .text.windows +WSAEnumProtocols: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAEnumProtocolsW(%rip),%rax + jmp __sysv2nt + .endfn WSAEnumProtocols,globl + .previous diff --git a/libc/nt/ws2_32/WSAEventSelect.s b/libc/nt/ws2_32/WSAEventSelect.s new file mode 100644 index 00000000..1f48263c --- /dev/null +++ b/libc/nt/ws2_32/WSAEventSelect.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAEventSelect,WSAEventSelect,67 + + .text.windows +WSAEventSelect: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAEventSelect(%rip),%rax + jmp __sysv2nt + .endfn WSAEventSelect,globl + .previous diff --git a/libc/nt/ws2_32/WSAGetLastError.s b/libc/nt/ws2_32/WSAGetLastError.s new file mode 100644 index 00000000..c176b347 --- /dev/null +++ b/libc/nt/ws2_32/WSAGetLastError.s @@ -0,0 +1,14 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAGetLastError,WSAGetLastError,111 + + .text.windows +WSAGetLastError: + push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + call *__imp_WSAGetLastError(%rip) + leave + ret + .endfn WSAGetLastError,globl + .previous diff --git a/libc/nt/ws2_32/WSAGetOverlappedResult.s b/libc/nt/ws2_32/WSAGetOverlappedResult.s new file mode 100644 index 00000000..f41e3152 --- /dev/null +++ b/libc/nt/ws2_32/WSAGetOverlappedResult.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAGetOverlappedResult,WSAGetOverlappedResult,68 + + .text.windows +WSAGetOverlappedResult: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAGetOverlappedResult(%rip),%rax + jmp __sysv2nt6 + .endfn WSAGetOverlappedResult,globl + .previous diff --git a/libc/nt/ws2_32/WSAGetQOSByName.s b/libc/nt/ws2_32/WSAGetQOSByName.s new file mode 100644 index 00000000..362d2c7b --- /dev/null +++ b/libc/nt/ws2_32/WSAGetQOSByName.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAGetQOSByName,WSAGetQOSByName,69 + + .text.windows +WSAGetQOSByName: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAGetQOSByName(%rip),%rax + jmp __sysv2nt + .endfn WSAGetQOSByName,globl + .previous diff --git a/libc/nt/ws2_32/WSAGetServiceClassInfoA.s b/libc/nt/ws2_32/WSAGetServiceClassInfoA.s new file mode 100644 index 00000000..3bdca9d3 --- /dev/null +++ b/libc/nt/ws2_32/WSAGetServiceClassInfoA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAGetServiceClassInfoA,WSAGetServiceClassInfoA,70 + + .text.windows +WSAGetServiceClassInfoA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAGetServiceClassInfoA(%rip),%rax + jmp __sysv2nt + .endfn WSAGetServiceClassInfoA,globl + .previous diff --git a/libc/nt/ws2_32/WSAGetServiceClassInfoW.s b/libc/nt/ws2_32/WSAGetServiceClassInfoW.s new file mode 100644 index 00000000..33ae1b94 --- /dev/null +++ b/libc/nt/ws2_32/WSAGetServiceClassInfoW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAGetServiceClassInfoW,WSAGetServiceClassInfoW,71 + + .text.windows +WSAGetServiceClassInfo: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAGetServiceClassInfoW(%rip),%rax + jmp __sysv2nt + .endfn WSAGetServiceClassInfo,globl + .previous diff --git a/libc/nt/ws2_32/WSAGetServiceClassNameByClassIdA.s b/libc/nt/ws2_32/WSAGetServiceClassNameByClassIdA.s new file mode 100644 index 00000000..201b3514 --- /dev/null +++ b/libc/nt/ws2_32/WSAGetServiceClassNameByClassIdA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAGetServiceClassNameByClassIdA,WSAGetServiceClassNameByClassIdA,72 + + .text.windows +WSAGetServiceClassNameByClassIdA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAGetServiceClassNameByClassIdA(%rip),%rax + jmp __sysv2nt + .endfn WSAGetServiceClassNameByClassIdA,globl + .previous diff --git a/libc/nt/ws2_32/WSAGetServiceClassNameByClassIdW.s b/libc/nt/ws2_32/WSAGetServiceClassNameByClassIdW.s new file mode 100644 index 00000000..28ad1262 --- /dev/null +++ b/libc/nt/ws2_32/WSAGetServiceClassNameByClassIdW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAGetServiceClassNameByClassIdW,WSAGetServiceClassNameByClassIdW,73 + + .text.windows +WSAGetServiceClassNameByClassId: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAGetServiceClassNameByClassIdW(%rip),%rax + jmp __sysv2nt + .endfn WSAGetServiceClassNameByClassId,globl + .previous diff --git a/libc/nt/ws2_32/WSAHtonl.s b/libc/nt/ws2_32/WSAHtonl.s new file mode 100644 index 00000000..6e574392 --- /dev/null +++ b/libc/nt/ws2_32/WSAHtonl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAHtonl,WSAHtonl,74 diff --git a/libc/nt/ws2_32/WSAHtons.s b/libc/nt/ws2_32/WSAHtons.s new file mode 100644 index 00000000..838e6bc6 --- /dev/null +++ b/libc/nt/ws2_32/WSAHtons.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAHtons,WSAHtons,75 diff --git a/libc/nt/ws2_32/WSAInstallServiceClassA.s b/libc/nt/ws2_32/WSAInstallServiceClassA.s new file mode 100644 index 00000000..d64e25b9 --- /dev/null +++ b/libc/nt/ws2_32/WSAInstallServiceClassA.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAInstallServiceClassA,WSAInstallServiceClassA,76 + + .text.windows +WSAInstallServiceClassA: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_WSAInstallServiceClassA(%rip) + leave + ret + .endfn WSAInstallServiceClassA,globl + .previous diff --git a/libc/nt/ws2_32/WSAInstallServiceClassW.s b/libc/nt/ws2_32/WSAInstallServiceClassW.s new file mode 100644 index 00000000..c4b2a3c4 --- /dev/null +++ b/libc/nt/ws2_32/WSAInstallServiceClassW.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAInstallServiceClassW,WSAInstallServiceClassW,77 + + .text.windows +WSAInstallServiceClass: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_WSAInstallServiceClassW(%rip) + leave + ret + .endfn WSAInstallServiceClass,globl + .previous diff --git a/libc/nt/ws2_32/WSAIoctl.s b/libc/nt/ws2_32/WSAIoctl.s new file mode 100644 index 00000000..f4ea8c38 --- /dev/null +++ b/libc/nt/ws2_32/WSAIoctl.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAIoctl,WSAIoctl,78 + + .text.windows +WSAIoctl: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAIoctl(%rip),%rax + jmp __sysv2nt10 + .endfn WSAIoctl,globl + .previous diff --git a/libc/nt/ws2_32/WSAIsBlocking.s b/libc/nt/ws2_32/WSAIsBlocking.s new file mode 100644 index 00000000..37e8ed2a --- /dev/null +++ b/libc/nt/ws2_32/WSAIsBlocking.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAIsBlocking,WSAIsBlocking,114 diff --git a/libc/nt/ws2_32/WSAJoinLeaf.s b/libc/nt/ws2_32/WSAJoinLeaf.s new file mode 100644 index 00000000..c35dc9e1 --- /dev/null +++ b/libc/nt/ws2_32/WSAJoinLeaf.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAJoinLeaf,WSAJoinLeaf,79 + + .text.windows +WSAJoinLeaf: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAJoinLeaf(%rip),%rax + jmp __sysv2nt8 + .endfn WSAJoinLeaf,globl + .previous diff --git a/libc/nt/ws2_32/WSALookupServiceBeginA.s b/libc/nt/ws2_32/WSALookupServiceBeginA.s new file mode 100644 index 00000000..cf969b31 --- /dev/null +++ b/libc/nt/ws2_32/WSALookupServiceBeginA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSALookupServiceBeginA,WSALookupServiceBeginA,80 + + .text.windows +WSALookupServiceBeginA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSALookupServiceBeginA(%rip),%rax + jmp __sysv2nt + .endfn WSALookupServiceBeginA,globl + .previous diff --git a/libc/nt/ws2_32/WSALookupServiceBeginW.s b/libc/nt/ws2_32/WSALookupServiceBeginW.s new file mode 100644 index 00000000..3ca91804 --- /dev/null +++ b/libc/nt/ws2_32/WSALookupServiceBeginW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSALookupServiceBeginW,WSALookupServiceBeginW,81 + + .text.windows +WSALookupServiceBegin: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSALookupServiceBeginW(%rip),%rax + jmp __sysv2nt + .endfn WSALookupServiceBegin,globl + .previous diff --git a/libc/nt/ws2_32/WSALookupServiceEnd.s b/libc/nt/ws2_32/WSALookupServiceEnd.s new file mode 100644 index 00000000..9264c540 --- /dev/null +++ b/libc/nt/ws2_32/WSALookupServiceEnd.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSALookupServiceEnd,WSALookupServiceEnd,82 + + .text.windows +WSALookupServiceEnd: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_WSALookupServiceEnd(%rip) + leave + ret + .endfn WSALookupServiceEnd,globl + .previous diff --git a/libc/nt/ws2_32/WSALookupServiceNextA.s b/libc/nt/ws2_32/WSALookupServiceNextA.s new file mode 100644 index 00000000..493b8978 --- /dev/null +++ b/libc/nt/ws2_32/WSALookupServiceNextA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSALookupServiceNextA,WSALookupServiceNextA,83 + + .text.windows +WSALookupServiceNextA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSALookupServiceNextA(%rip),%rax + jmp __sysv2nt + .endfn WSALookupServiceNextA,globl + .previous diff --git a/libc/nt/ws2_32/WSALookupServiceNextW.s b/libc/nt/ws2_32/WSALookupServiceNextW.s new file mode 100644 index 00000000..bee47ae1 --- /dev/null +++ b/libc/nt/ws2_32/WSALookupServiceNextW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSALookupServiceNextW,WSALookupServiceNextW,84 + + .text.windows +WSALookupServiceNext: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSALookupServiceNextW(%rip),%rax + jmp __sysv2nt + .endfn WSALookupServiceNext,globl + .previous diff --git a/libc/nt/ws2_32/WSANSPIoctl.s b/libc/nt/ws2_32/WSANSPIoctl.s new file mode 100644 index 00000000..2fd75469 --- /dev/null +++ b/libc/nt/ws2_32/WSANSPIoctl.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSANSPIoctl,WSANSPIoctl,85 + + .text.windows +WSANSPIoctl: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSANSPIoctl(%rip),%rax + jmp __sysv2nt8 + .endfn WSANSPIoctl,globl + .previous diff --git a/libc/nt/ws2_32/WSANtohl.s b/libc/nt/ws2_32/WSANtohl.s new file mode 100644 index 00000000..5f7c9a05 --- /dev/null +++ b/libc/nt/ws2_32/WSANtohl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSANtohl,WSANtohl,86 diff --git a/libc/nt/ws2_32/WSANtohs.s b/libc/nt/ws2_32/WSANtohs.s new file mode 100644 index 00000000..c5b5fb9e --- /dev/null +++ b/libc/nt/ws2_32/WSANtohs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSANtohs,WSANtohs,87 diff --git a/libc/nt/ws2_32/WSAPoll.s b/libc/nt/ws2_32/WSAPoll.s new file mode 100644 index 00000000..d415967e --- /dev/null +++ b/libc/nt/ws2_32/WSAPoll.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAPoll,WSAPoll,88 + + .text.windows +WSAPoll: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAPoll(%rip),%rax + jmp __sysv2nt + .endfn WSAPoll,globl + .previous diff --git a/libc/nt/ws2_32/WSAProviderCompleteAsyncCall.s b/libc/nt/ws2_32/WSAProviderCompleteAsyncCall.s new file mode 100644 index 00000000..9835d47f --- /dev/null +++ b/libc/nt/ws2_32/WSAProviderCompleteAsyncCall.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAProviderCompleteAsyncCall,WSAProviderCompleteAsyncCall,89 diff --git a/libc/nt/ws2_32/WSAProviderConfigChange.s b/libc/nt/ws2_32/WSAProviderConfigChange.s new file mode 100644 index 00000000..4651635f --- /dev/null +++ b/libc/nt/ws2_32/WSAProviderConfigChange.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAProviderConfigChange,WSAProviderConfigChange,90 + + .text.windows +WSAProviderConfigChange: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAProviderConfigChange(%rip),%rax + jmp __sysv2nt + .endfn WSAProviderConfigChange,globl + .previous diff --git a/libc/nt/ws2_32/WSARecv.s b/libc/nt/ws2_32/WSARecv.s new file mode 100644 index 00000000..eab2a8f2 --- /dev/null +++ b/libc/nt/ws2_32/WSARecv.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSARecv,WSARecv,91 + + .text.windows +WSARecv: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSARecv(%rip),%rax + jmp __sysv2nt8 + .endfn WSARecv,globl + .previous diff --git a/libc/nt/ws2_32/WSARecvDisconnect.s b/libc/nt/ws2_32/WSARecvDisconnect.s new file mode 100644 index 00000000..e8f611a7 --- /dev/null +++ b/libc/nt/ws2_32/WSARecvDisconnect.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSARecvDisconnect,WSARecvDisconnect,92 + + .text.windows +WSARecvDisconnect: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSARecvDisconnect(%rip),%rax + jmp __sysv2nt + .endfn WSARecvDisconnect,globl + .previous diff --git a/libc/nt/ws2_32/WSARecvFrom.s b/libc/nt/ws2_32/WSARecvFrom.s new file mode 100644 index 00000000..dfacf2c9 --- /dev/null +++ b/libc/nt/ws2_32/WSARecvFrom.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSARecvFrom,WSARecvFrom,93 + + .text.windows +WSARecvFrom: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSARecvFrom(%rip),%rax + jmp __sysv2nt10 + .endfn WSARecvFrom,globl + .previous diff --git a/libc/nt/ws2_32/WSARemoveServiceClass.s b/libc/nt/ws2_32/WSARemoveServiceClass.s new file mode 100644 index 00000000..225e5f84 --- /dev/null +++ b/libc/nt/ws2_32/WSARemoveServiceClass.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSARemoveServiceClass,WSARemoveServiceClass,94 + + .text.windows +WSARemoveServiceClass: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_WSARemoveServiceClass(%rip) + leave + ret + .endfn WSARemoveServiceClass,globl + .previous diff --git a/libc/nt/ws2_32/WSAResetEvent.s b/libc/nt/ws2_32/WSAResetEvent.s new file mode 100644 index 00000000..bd363c4b --- /dev/null +++ b/libc/nt/ws2_32/WSAResetEvent.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAResetEvent,WSAResetEvent,95 + + .text.windows +WSAResetEvent: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_WSAResetEvent(%rip) + leave + ret + .endfn WSAResetEvent,globl + .previous diff --git a/libc/nt/ws2_32/WSASend.s b/libc/nt/ws2_32/WSASend.s new file mode 100644 index 00000000..f17f6406 --- /dev/null +++ b/libc/nt/ws2_32/WSASend.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSASend,WSASend,96 + + .text.windows +WSASend: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSASend(%rip),%rax + jmp __sysv2nt8 + .endfn WSASend,globl + .previous diff --git a/libc/nt/ws2_32/WSASendDisconnect.s b/libc/nt/ws2_32/WSASendDisconnect.s new file mode 100644 index 00000000..50870e34 --- /dev/null +++ b/libc/nt/ws2_32/WSASendDisconnect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSASendDisconnect,WSASendDisconnect,97 diff --git a/libc/nt/ws2_32/WSASendMsg.s b/libc/nt/ws2_32/WSASendMsg.s new file mode 100644 index 00000000..637f43b3 --- /dev/null +++ b/libc/nt/ws2_32/WSASendMsg.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSASendMsg,WSASendMsg,98 + + .text.windows +WSASendMsg: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSASendMsg(%rip),%rax + jmp __sysv2nt6 + .endfn WSASendMsg,globl + .previous diff --git a/libc/nt/ws2_32/WSASendTo.s b/libc/nt/ws2_32/WSASendTo.s new file mode 100644 index 00000000..9e9f3dd2 --- /dev/null +++ b/libc/nt/ws2_32/WSASendTo.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSASendTo,WSASendTo,99 + + .text.windows +WSASendTo: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSASendTo(%rip),%rax + jmp __sysv2nt10 + .endfn WSASendTo,globl + .previous diff --git a/libc/nt/ws2_32/WSASetBlockingHook.s b/libc/nt/ws2_32/WSASetBlockingHook.s new file mode 100644 index 00000000..f3a408c0 --- /dev/null +++ b/libc/nt/ws2_32/WSASetBlockingHook.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSASetBlockingHook,WSASetBlockingHook,109 diff --git a/libc/nt/ws2_32/WSASetEvent.s b/libc/nt/ws2_32/WSASetEvent.s new file mode 100644 index 00000000..62db2de9 --- /dev/null +++ b/libc/nt/ws2_32/WSASetEvent.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSASetEvent,WSASetEvent,100 + + .text.windows +WSASetEvent: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_WSASetEvent(%rip) + leave + ret + .endfn WSASetEvent,globl + .previous diff --git a/libc/nt/ws2_32/WSASetLastError.s b/libc/nt/ws2_32/WSASetLastError.s new file mode 100644 index 00000000..d49c8e6a --- /dev/null +++ b/libc/nt/ws2_32/WSASetLastError.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSASetLastError,WSASetLastError,112 + + .text.windows +WSASetLastError: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_WSASetLastError(%rip) + leave + ret + .endfn WSASetLastError,globl + .previous diff --git a/libc/nt/ws2_32/WSASetServiceA.s b/libc/nt/ws2_32/WSASetServiceA.s new file mode 100644 index 00000000..a6ce4e66 --- /dev/null +++ b/libc/nt/ws2_32/WSASetServiceA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSASetServiceA,WSASetServiceA,117 + + .text.windows +WSASetServiceA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSASetServiceA(%rip),%rax + jmp __sysv2nt + .endfn WSASetServiceA,globl + .previous diff --git a/libc/nt/ws2_32/WSASetServiceW.s b/libc/nt/ws2_32/WSASetServiceW.s new file mode 100644 index 00000000..7fdc84bb --- /dev/null +++ b/libc/nt/ws2_32/WSASetServiceW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSASetServiceW,WSASetServiceW,118 + + .text.windows +WSASetService: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSASetServiceW(%rip),%rax + jmp __sysv2nt + .endfn WSASetService,globl + .previous diff --git a/libc/nt/ws2_32/WSASocketA.s b/libc/nt/ws2_32/WSASocketA.s new file mode 100644 index 00000000..6ee0ee9d --- /dev/null +++ b/libc/nt/ws2_32/WSASocketA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSASocketA,WSASocketA,119 + + .text.windows +WSASocketA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSASocketA(%rip),%rax + jmp __sysv2nt6 + .endfn WSASocketA,globl + .previous diff --git a/libc/nt/ws2_32/WSASocketW.s b/libc/nt/ws2_32/WSASocketW.s new file mode 100644 index 00000000..03da8d43 --- /dev/null +++ b/libc/nt/ws2_32/WSASocketW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSASocketW,WSASocketW,120 + + .text.windows +WSASocket: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSASocketW(%rip),%rax + jmp __sysv2nt6 + .endfn WSASocket,globl + .previous diff --git a/libc/nt/ws2_32/WSAStartup.s b/libc/nt/ws2_32/WSAStartup.s new file mode 100644 index 00000000..4da01081 --- /dev/null +++ b/libc/nt/ws2_32/WSAStartup.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAStartup,WSAStartup,115 + + .text.windows +WSAStartup: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAStartup(%rip),%rax + jmp __sysv2nt + .endfn WSAStartup,globl + .previous diff --git a/libc/nt/ws2_32/WSAStringToAddressA.s b/libc/nt/ws2_32/WSAStringToAddressA.s new file mode 100644 index 00000000..8650a7ff --- /dev/null +++ b/libc/nt/ws2_32/WSAStringToAddressA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAStringToAddressA,WSAStringToAddressA,121 + + .text.windows +WSAStringToAddressA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAStringToAddressA(%rip),%rax + jmp __sysv2nt6 + .endfn WSAStringToAddressA,globl + .previous diff --git a/libc/nt/ws2_32/WSAStringToAddressW.s b/libc/nt/ws2_32/WSAStringToAddressW.s new file mode 100644 index 00000000..045d61c5 --- /dev/null +++ b/libc/nt/ws2_32/WSAStringToAddressW.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAStringToAddressW,WSAStringToAddressW,122 diff --git a/libc/nt/ws2_32/WSAUnadvertiseProvider.s b/libc/nt/ws2_32/WSAUnadvertiseProvider.s new file mode 100644 index 00000000..27b8d9c6 --- /dev/null +++ b/libc/nt/ws2_32/WSAUnadvertiseProvider.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAUnadvertiseProvider,WSAUnadvertiseProvider,123 diff --git a/libc/nt/ws2_32/WSAUnhookBlockingHook.s b/libc/nt/ws2_32/WSAUnhookBlockingHook.s new file mode 100644 index 00000000..cd6540f7 --- /dev/null +++ b/libc/nt/ws2_32/WSAUnhookBlockingHook.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAUnhookBlockingHook,WSAUnhookBlockingHook,110 diff --git a/libc/nt/ws2_32/WSAWaitForMultipleEvents.s b/libc/nt/ws2_32/WSAWaitForMultipleEvents.s new file mode 100644 index 00000000..36e963b1 --- /dev/null +++ b/libc/nt/ws2_32/WSAWaitForMultipleEvents.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSAWaitForMultipleEvents,WSAWaitForMultipleEvents,124 + + .text.windows +WSAWaitForMultipleEvents: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_WSAWaitForMultipleEvents(%rip),%rax + jmp __sysv2nt6 + .endfn WSAWaitForMultipleEvents,globl + .previous diff --git a/libc/nt/ws2_32/WSApSetPostRoutine.s b/libc/nt/ws2_32/WSApSetPostRoutine.s new file mode 100644 index 00000000..9c9e8f97 --- /dev/null +++ b/libc/nt/ws2_32/WSApSetPostRoutine.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSApSetPostRoutine,WSApSetPostRoutine,24 diff --git a/libc/nt/ws2_32/WSCDeinstallProvider.s b/libc/nt/ws2_32/WSCDeinstallProvider.s new file mode 100644 index 00000000..31e853c4 --- /dev/null +++ b/libc/nt/ws2_32/WSCDeinstallProvider.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCDeinstallProvider,WSCDeinstallProvider,125 diff --git a/libc/nt/ws2_32/WSCDeinstallProvider32.s b/libc/nt/ws2_32/WSCDeinstallProvider32.s new file mode 100644 index 00000000..d96eb0b2 --- /dev/null +++ b/libc/nt/ws2_32/WSCDeinstallProvider32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCDeinstallProvider32,WSCDeinstallProvider32,126 diff --git a/libc/nt/ws2_32/WSCDeinstallProviderEx.s b/libc/nt/ws2_32/WSCDeinstallProviderEx.s new file mode 100644 index 00000000..b089b888 --- /dev/null +++ b/libc/nt/ws2_32/WSCDeinstallProviderEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCDeinstallProviderEx,WSCDeinstallProviderEx,127 diff --git a/libc/nt/ws2_32/WSCEnableNSProvider.s b/libc/nt/ws2_32/WSCEnableNSProvider.s new file mode 100644 index 00000000..56b8a169 --- /dev/null +++ b/libc/nt/ws2_32/WSCEnableNSProvider.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCEnableNSProvider,WSCEnableNSProvider,128 diff --git a/libc/nt/ws2_32/WSCEnableNSProvider32.s b/libc/nt/ws2_32/WSCEnableNSProvider32.s new file mode 100644 index 00000000..1fd61cc8 --- /dev/null +++ b/libc/nt/ws2_32/WSCEnableNSProvider32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCEnableNSProvider32,WSCEnableNSProvider32,129 diff --git a/libc/nt/ws2_32/WSCEnumNameSpaceProviders32.s b/libc/nt/ws2_32/WSCEnumNameSpaceProviders32.s new file mode 100644 index 00000000..6f1f512a --- /dev/null +++ b/libc/nt/ws2_32/WSCEnumNameSpaceProviders32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCEnumNameSpaceProviders32,WSCEnumNameSpaceProviders32,130 diff --git a/libc/nt/ws2_32/WSCEnumNameSpaceProvidersEx32.s b/libc/nt/ws2_32/WSCEnumNameSpaceProvidersEx32.s new file mode 100644 index 00000000..eae2d76c --- /dev/null +++ b/libc/nt/ws2_32/WSCEnumNameSpaceProvidersEx32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCEnumNameSpaceProvidersEx32,WSCEnumNameSpaceProvidersEx32,131 diff --git a/libc/nt/ws2_32/WSCEnumProtocols.s b/libc/nt/ws2_32/WSCEnumProtocols.s new file mode 100644 index 00000000..0385e8ef --- /dev/null +++ b/libc/nt/ws2_32/WSCEnumProtocols.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCEnumProtocols,WSCEnumProtocols,132 diff --git a/libc/nt/ws2_32/WSCEnumProtocols32.s b/libc/nt/ws2_32/WSCEnumProtocols32.s new file mode 100644 index 00000000..64e788bf --- /dev/null +++ b/libc/nt/ws2_32/WSCEnumProtocols32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCEnumProtocols32,WSCEnumProtocols32,133 diff --git a/libc/nt/ws2_32/WSCEnumProtocolsEx.s b/libc/nt/ws2_32/WSCEnumProtocolsEx.s new file mode 100644 index 00000000..371d1dcd --- /dev/null +++ b/libc/nt/ws2_32/WSCEnumProtocolsEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCEnumProtocolsEx,WSCEnumProtocolsEx,134 diff --git a/libc/nt/ws2_32/WSCGetApplicationCategory.s b/libc/nt/ws2_32/WSCGetApplicationCategory.s new file mode 100644 index 00000000..43a2e34b --- /dev/null +++ b/libc/nt/ws2_32/WSCGetApplicationCategory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCGetApplicationCategory,WSCGetApplicationCategory,135 diff --git a/libc/nt/ws2_32/WSCGetApplicationCategoryEx.s b/libc/nt/ws2_32/WSCGetApplicationCategoryEx.s new file mode 100644 index 00000000..44bd2c46 --- /dev/null +++ b/libc/nt/ws2_32/WSCGetApplicationCategoryEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCGetApplicationCategoryEx,WSCGetApplicationCategoryEx,136 diff --git a/libc/nt/ws2_32/WSCGetProviderInfo.s b/libc/nt/ws2_32/WSCGetProviderInfo.s new file mode 100644 index 00000000..39c118e2 --- /dev/null +++ b/libc/nt/ws2_32/WSCGetProviderInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCGetProviderInfo,WSCGetProviderInfo,137 diff --git a/libc/nt/ws2_32/WSCGetProviderInfo32.s b/libc/nt/ws2_32/WSCGetProviderInfo32.s new file mode 100644 index 00000000..c86b2ed8 --- /dev/null +++ b/libc/nt/ws2_32/WSCGetProviderInfo32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCGetProviderInfo32,WSCGetProviderInfo32,138 diff --git a/libc/nt/ws2_32/WSCGetProviderPath.s b/libc/nt/ws2_32/WSCGetProviderPath.s new file mode 100644 index 00000000..763c8bd1 --- /dev/null +++ b/libc/nt/ws2_32/WSCGetProviderPath.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCGetProviderPath,WSCGetProviderPath,139 diff --git a/libc/nt/ws2_32/WSCGetProviderPath32.s b/libc/nt/ws2_32/WSCGetProviderPath32.s new file mode 100644 index 00000000..b07c6bb6 --- /dev/null +++ b/libc/nt/ws2_32/WSCGetProviderPath32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCGetProviderPath32,WSCGetProviderPath32,140 diff --git a/libc/nt/ws2_32/WSCInstallNameSpace.s b/libc/nt/ws2_32/WSCInstallNameSpace.s new file mode 100644 index 00000000..7a5d5a69 --- /dev/null +++ b/libc/nt/ws2_32/WSCInstallNameSpace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCInstallNameSpace,WSCInstallNameSpace,141 diff --git a/libc/nt/ws2_32/WSCInstallNameSpace32.s b/libc/nt/ws2_32/WSCInstallNameSpace32.s new file mode 100644 index 00000000..5a2043c4 --- /dev/null +++ b/libc/nt/ws2_32/WSCInstallNameSpace32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCInstallNameSpace32,WSCInstallNameSpace32,142 diff --git a/libc/nt/ws2_32/WSCInstallNameSpaceEx.s b/libc/nt/ws2_32/WSCInstallNameSpaceEx.s new file mode 100644 index 00000000..60529f3d --- /dev/null +++ b/libc/nt/ws2_32/WSCInstallNameSpaceEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCInstallNameSpaceEx,WSCInstallNameSpaceEx,143 diff --git a/libc/nt/ws2_32/WSCInstallNameSpaceEx2.s b/libc/nt/ws2_32/WSCInstallNameSpaceEx2.s new file mode 100644 index 00000000..44f65e67 --- /dev/null +++ b/libc/nt/ws2_32/WSCInstallNameSpaceEx2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCInstallNameSpaceEx2,WSCInstallNameSpaceEx2,144 diff --git a/libc/nt/ws2_32/WSCInstallNameSpaceEx32.s b/libc/nt/ws2_32/WSCInstallNameSpaceEx32.s new file mode 100644 index 00000000..0cc97f92 --- /dev/null +++ b/libc/nt/ws2_32/WSCInstallNameSpaceEx32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCInstallNameSpaceEx32,WSCInstallNameSpaceEx32,145 diff --git a/libc/nt/ws2_32/WSCInstallProvider.s b/libc/nt/ws2_32/WSCInstallProvider.s new file mode 100644 index 00000000..88dbe688 --- /dev/null +++ b/libc/nt/ws2_32/WSCInstallProvider.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCInstallProvider,WSCInstallProvider,146 diff --git a/libc/nt/ws2_32/WSCInstallProvider64_32.s b/libc/nt/ws2_32/WSCInstallProvider64_32.s new file mode 100644 index 00000000..75b9da18 --- /dev/null +++ b/libc/nt/ws2_32/WSCInstallProvider64_32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCInstallProvider64_32,WSCInstallProvider64_32,147 diff --git a/libc/nt/ws2_32/WSCInstallProviderAndChains64_32.s b/libc/nt/ws2_32/WSCInstallProviderAndChains64_32.s new file mode 100644 index 00000000..76a26373 --- /dev/null +++ b/libc/nt/ws2_32/WSCInstallProviderAndChains64_32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCInstallProviderAndChains64_32,WSCInstallProviderAndChains64_32,148 diff --git a/libc/nt/ws2_32/WSCInstallProviderEx.s b/libc/nt/ws2_32/WSCInstallProviderEx.s new file mode 100644 index 00000000..77520542 --- /dev/null +++ b/libc/nt/ws2_32/WSCInstallProviderEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCInstallProviderEx,WSCInstallProviderEx,149 diff --git a/libc/nt/ws2_32/WSCSetApplicationCategory.s b/libc/nt/ws2_32/WSCSetApplicationCategory.s new file mode 100644 index 00000000..37373132 --- /dev/null +++ b/libc/nt/ws2_32/WSCSetApplicationCategory.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCSetApplicationCategory,WSCSetApplicationCategory,150 diff --git a/libc/nt/ws2_32/WSCSetApplicationCategoryEx.s b/libc/nt/ws2_32/WSCSetApplicationCategoryEx.s new file mode 100644 index 00000000..7c3f3f5b --- /dev/null +++ b/libc/nt/ws2_32/WSCSetApplicationCategoryEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCSetApplicationCategoryEx,WSCSetApplicationCategoryEx,152 diff --git a/libc/nt/ws2_32/WSCSetProviderInfo.s b/libc/nt/ws2_32/WSCSetProviderInfo.s new file mode 100644 index 00000000..6e689f81 --- /dev/null +++ b/libc/nt/ws2_32/WSCSetProviderInfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCSetProviderInfo,WSCSetProviderInfo,153 diff --git a/libc/nt/ws2_32/WSCSetProviderInfo32.s b/libc/nt/ws2_32/WSCSetProviderInfo32.s new file mode 100644 index 00000000..b621e567 --- /dev/null +++ b/libc/nt/ws2_32/WSCSetProviderInfo32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCSetProviderInfo32,WSCSetProviderInfo32,154 diff --git a/libc/nt/ws2_32/WSCUnInstallNameSpace.s b/libc/nt/ws2_32/WSCUnInstallNameSpace.s new file mode 100644 index 00000000..5140a894 --- /dev/null +++ b/libc/nt/ws2_32/WSCUnInstallNameSpace.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCUnInstallNameSpace,WSCUnInstallNameSpace,155 diff --git a/libc/nt/ws2_32/WSCUnInstallNameSpace32.s b/libc/nt/ws2_32/WSCUnInstallNameSpace32.s new file mode 100644 index 00000000..19ceef95 --- /dev/null +++ b/libc/nt/ws2_32/WSCUnInstallNameSpace32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCUnInstallNameSpace32,WSCUnInstallNameSpace32,156 diff --git a/libc/nt/ws2_32/WSCUnInstallNameSpaceEx2.s b/libc/nt/ws2_32/WSCUnInstallNameSpaceEx2.s new file mode 100644 index 00000000..6f93347b --- /dev/null +++ b/libc/nt/ws2_32/WSCUnInstallNameSpaceEx2.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCUnInstallNameSpaceEx2,WSCUnInstallNameSpaceEx2,157 diff --git a/libc/nt/ws2_32/WSCUpdateProvider.s b/libc/nt/ws2_32/WSCUpdateProvider.s new file mode 100644 index 00000000..c40337e7 --- /dev/null +++ b/libc/nt/ws2_32/WSCUpdateProvider.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCUpdateProvider,WSCUpdateProvider,158 diff --git a/libc/nt/ws2_32/WSCUpdateProvider32.s b/libc/nt/ws2_32/WSCUpdateProvider32.s new file mode 100644 index 00000000..d8fbdfd6 --- /dev/null +++ b/libc/nt/ws2_32/WSCUpdateProvider32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCUpdateProvider32,WSCUpdateProvider32,159 diff --git a/libc/nt/ws2_32/WSCUpdateProviderEx.s b/libc/nt/ws2_32/WSCUpdateProviderEx.s new file mode 100644 index 00000000..a5ee15df --- /dev/null +++ b/libc/nt/ws2_32/WSCUpdateProviderEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCUpdateProviderEx,WSCUpdateProviderEx,160 diff --git a/libc/nt/ws2_32/WSCWriteNameSpaceOrder.s b/libc/nt/ws2_32/WSCWriteNameSpaceOrder.s new file mode 100644 index 00000000..45de63ef --- /dev/null +++ b/libc/nt/ws2_32/WSCWriteNameSpaceOrder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCWriteNameSpaceOrder,WSCWriteNameSpaceOrder,161 diff --git a/libc/nt/ws2_32/WSCWriteNameSpaceOrder32.s b/libc/nt/ws2_32/WSCWriteNameSpaceOrder32.s new file mode 100644 index 00000000..5ae23b8a --- /dev/null +++ b/libc/nt/ws2_32/WSCWriteNameSpaceOrder32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCWriteNameSpaceOrder32,WSCWriteNameSpaceOrder32,162 diff --git a/libc/nt/ws2_32/WSCWriteProviderOrder.s b/libc/nt/ws2_32/WSCWriteProviderOrder.s new file mode 100644 index 00000000..c49abd12 --- /dev/null +++ b/libc/nt/ws2_32/WSCWriteProviderOrder.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCWriteProviderOrder,WSCWriteProviderOrder,163 diff --git a/libc/nt/ws2_32/WSCWriteProviderOrder32.s b/libc/nt/ws2_32/WSCWriteProviderOrder32.s new file mode 100644 index 00000000..08586603 --- /dev/null +++ b/libc/nt/ws2_32/WSCWriteProviderOrder32.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCWriteProviderOrder32,WSCWriteProviderOrder32,164 diff --git a/libc/nt/ws2_32/WSCWriteProviderOrderEx.s b/libc/nt/ws2_32/WSCWriteProviderOrderEx.s new file mode 100644 index 00000000..35d2176f --- /dev/null +++ b/libc/nt/ws2_32/WSCWriteProviderOrderEx.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WSCWriteProviderOrderEx,WSCWriteProviderOrderEx,165 diff --git a/libc/nt/ws2_32/WahCloseApcHelper.s b/libc/nt/ws2_32/WahCloseApcHelper.s new file mode 100644 index 00000000..d54329ec --- /dev/null +++ b/libc/nt/ws2_32/WahCloseApcHelper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahCloseApcHelper,WahCloseApcHelper,166 diff --git a/libc/nt/ws2_32/WahCloseHandleHelper.s b/libc/nt/ws2_32/WahCloseHandleHelper.s new file mode 100644 index 00000000..eaed0138 --- /dev/null +++ b/libc/nt/ws2_32/WahCloseHandleHelper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahCloseHandleHelper,WahCloseHandleHelper,167 diff --git a/libc/nt/ws2_32/WahCloseNotificationHandleHelper.s b/libc/nt/ws2_32/WahCloseNotificationHandleHelper.s new file mode 100644 index 00000000..08159132 --- /dev/null +++ b/libc/nt/ws2_32/WahCloseNotificationHandleHelper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahCloseNotificationHandleHelper,WahCloseNotificationHandleHelper,168 diff --git a/libc/nt/ws2_32/WahCloseSocketHandle.s b/libc/nt/ws2_32/WahCloseSocketHandle.s new file mode 100644 index 00000000..3bc65ba8 --- /dev/null +++ b/libc/nt/ws2_32/WahCloseSocketHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahCloseSocketHandle,WahCloseSocketHandle,169 diff --git a/libc/nt/ws2_32/WahCloseThread.s b/libc/nt/ws2_32/WahCloseThread.s new file mode 100644 index 00000000..e51b5427 --- /dev/null +++ b/libc/nt/ws2_32/WahCloseThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahCloseThread,WahCloseThread,170 diff --git a/libc/nt/ws2_32/WahCompleteRequest.s b/libc/nt/ws2_32/WahCompleteRequest.s new file mode 100644 index 00000000..0d70c222 --- /dev/null +++ b/libc/nt/ws2_32/WahCompleteRequest.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahCompleteRequest,WahCompleteRequest,171 diff --git a/libc/nt/ws2_32/WahCreateHandleContextTable.s b/libc/nt/ws2_32/WahCreateHandleContextTable.s new file mode 100644 index 00000000..64760609 --- /dev/null +++ b/libc/nt/ws2_32/WahCreateHandleContextTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahCreateHandleContextTable,WahCreateHandleContextTable,172 diff --git a/libc/nt/ws2_32/WahCreateNotificationHandle.s b/libc/nt/ws2_32/WahCreateNotificationHandle.s new file mode 100644 index 00000000..6da9cd91 --- /dev/null +++ b/libc/nt/ws2_32/WahCreateNotificationHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahCreateNotificationHandle,WahCreateNotificationHandle,173 diff --git a/libc/nt/ws2_32/WahCreateSocketHandle.s b/libc/nt/ws2_32/WahCreateSocketHandle.s new file mode 100644 index 00000000..6d6bd47a --- /dev/null +++ b/libc/nt/ws2_32/WahCreateSocketHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahCreateSocketHandle,WahCreateSocketHandle,174 diff --git a/libc/nt/ws2_32/WahDestroyHandleContextTable.s b/libc/nt/ws2_32/WahDestroyHandleContextTable.s new file mode 100644 index 00000000..7bb7529e --- /dev/null +++ b/libc/nt/ws2_32/WahDestroyHandleContextTable.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahDestroyHandleContextTable,WahDestroyHandleContextTable,175 diff --git a/libc/nt/ws2_32/WahDisableNonIFSHandleSupport.s b/libc/nt/ws2_32/WahDisableNonIFSHandleSupport.s new file mode 100644 index 00000000..39400bc5 --- /dev/null +++ b/libc/nt/ws2_32/WahDisableNonIFSHandleSupport.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahDisableNonIFSHandleSupport,WahDisableNonIFSHandleSupport,176 diff --git a/libc/nt/ws2_32/WahEnableNonIFSHandleSupport.s b/libc/nt/ws2_32/WahEnableNonIFSHandleSupport.s new file mode 100644 index 00000000..45247076 --- /dev/null +++ b/libc/nt/ws2_32/WahEnableNonIFSHandleSupport.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahEnableNonIFSHandleSupport,WahEnableNonIFSHandleSupport,177 diff --git a/libc/nt/ws2_32/WahEnumerateHandleContexts.s b/libc/nt/ws2_32/WahEnumerateHandleContexts.s new file mode 100644 index 00000000..4e1ace5b --- /dev/null +++ b/libc/nt/ws2_32/WahEnumerateHandleContexts.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahEnumerateHandleContexts,WahEnumerateHandleContexts,178 diff --git a/libc/nt/ws2_32/WahInsertHandleContext.s b/libc/nt/ws2_32/WahInsertHandleContext.s new file mode 100644 index 00000000..828784d7 --- /dev/null +++ b/libc/nt/ws2_32/WahInsertHandleContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahInsertHandleContext,WahInsertHandleContext,179 diff --git a/libc/nt/ws2_32/WahNotifyAllProcesses.s b/libc/nt/ws2_32/WahNotifyAllProcesses.s new file mode 100644 index 00000000..f857aca6 --- /dev/null +++ b/libc/nt/ws2_32/WahNotifyAllProcesses.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahNotifyAllProcesses,WahNotifyAllProcesses,180 diff --git a/libc/nt/ws2_32/WahOpenApcHelper.s b/libc/nt/ws2_32/WahOpenApcHelper.s new file mode 100644 index 00000000..30cc5264 --- /dev/null +++ b/libc/nt/ws2_32/WahOpenApcHelper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahOpenApcHelper,WahOpenApcHelper,181 diff --git a/libc/nt/ws2_32/WahOpenCurrentThread.s b/libc/nt/ws2_32/WahOpenCurrentThread.s new file mode 100644 index 00000000..cd32c323 --- /dev/null +++ b/libc/nt/ws2_32/WahOpenCurrentThread.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahOpenCurrentThread,WahOpenCurrentThread,182 diff --git a/libc/nt/ws2_32/WahOpenHandleHelper.s b/libc/nt/ws2_32/WahOpenHandleHelper.s new file mode 100644 index 00000000..ed001860 --- /dev/null +++ b/libc/nt/ws2_32/WahOpenHandleHelper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahOpenHandleHelper,WahOpenHandleHelper,183 diff --git a/libc/nt/ws2_32/WahOpenNotificationHandleHelper.s b/libc/nt/ws2_32/WahOpenNotificationHandleHelper.s new file mode 100644 index 00000000..153ff26c --- /dev/null +++ b/libc/nt/ws2_32/WahOpenNotificationHandleHelper.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahOpenNotificationHandleHelper,WahOpenNotificationHandleHelper,184 diff --git a/libc/nt/ws2_32/WahQueueUserApc.s b/libc/nt/ws2_32/WahQueueUserApc.s new file mode 100644 index 00000000..3f45bb17 --- /dev/null +++ b/libc/nt/ws2_32/WahQueueUserApc.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahQueueUserApc,WahQueueUserApc,185 diff --git a/libc/nt/ws2_32/WahReferenceContextByHandle.s b/libc/nt/ws2_32/WahReferenceContextByHandle.s new file mode 100644 index 00000000..e614159f --- /dev/null +++ b/libc/nt/ws2_32/WahReferenceContextByHandle.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahReferenceContextByHandle,WahReferenceContextByHandle,186 diff --git a/libc/nt/ws2_32/WahRemoveHandleContext.s b/libc/nt/ws2_32/WahRemoveHandleContext.s new file mode 100644 index 00000000..558baf1f --- /dev/null +++ b/libc/nt/ws2_32/WahRemoveHandleContext.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahRemoveHandleContext,WahRemoveHandleContext,187 diff --git a/libc/nt/ws2_32/WahWaitForNotification.s b/libc/nt/ws2_32/WahWaitForNotification.s new file mode 100644 index 00000000..09b13aba --- /dev/null +++ b/libc/nt/ws2_32/WahWaitForNotification.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahWaitForNotification,WahWaitForNotification,188 diff --git a/libc/nt/ws2_32/WahWriteLSPEvent.s b/libc/nt/ws2_32/WahWriteLSPEvent.s new file mode 100644 index 00000000..b16af195 --- /dev/null +++ b/libc/nt/ws2_32/WahWriteLSPEvent.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_WahWriteLSPEvent,WahWriteLSPEvent,189 diff --git a/libc/nt/ws2_32/accept.s b/libc/nt/ws2_32/accept.s new file mode 100644 index 00000000..cb18ee70 --- /dev/null +++ b/libc/nt/ws2_32/accept.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_accept,accept,1 diff --git a/libc/nt/ws2_32/bind.s b/libc/nt/ws2_32/bind.s new file mode 100644 index 00000000..f41c85c0 --- /dev/null +++ b/libc/nt/ws2_32/bind.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_bind,bind,2 + + .text.windows +__bind$nt: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_bind(%rip),%rax + jmp __sysv2nt + .endfn __bind$nt,globl + .previous diff --git a/libc/nt/ws2_32/closesocket.s b/libc/nt/ws2_32/closesocket.s new file mode 100644 index 00000000..dd333138 --- /dev/null +++ b/libc/nt/ws2_32/closesocket.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_closesocket,closesocket,3 + + .text.windows +__closesocket$nt: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_closesocket(%rip) + leave + ret + .endfn __closesocket$nt,globl + .previous diff --git a/libc/nt/ws2_32/connect.s b/libc/nt/ws2_32/connect.s new file mode 100644 index 00000000..c57f4ba9 --- /dev/null +++ b/libc/nt/ws2_32/connect.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_connect,connect,4 diff --git a/libc/nt/ws2_32/freeaddrinfo.s b/libc/nt/ws2_32/freeaddrinfo.s new file mode 100644 index 00000000..3f697465 --- /dev/null +++ b/libc/nt/ws2_32/freeaddrinfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_freeaddrinfo,freeaddrinfo,190 diff --git a/libc/nt/ws2_32/getaddrinfo.s b/libc/nt/ws2_32/getaddrinfo.s new file mode 100644 index 00000000..cc0f4bdf --- /dev/null +++ b/libc/nt/ws2_32/getaddrinfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_getaddrinfo,getaddrinfo,191 diff --git a/libc/nt/ws2_32/gethostbyaddr.s b/libc/nt/ws2_32/gethostbyaddr.s new file mode 100644 index 00000000..b7fb55d2 --- /dev/null +++ b/libc/nt/ws2_32/gethostbyaddr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_gethostbyaddr,gethostbyaddr,51 diff --git a/libc/nt/ws2_32/gethostbyname.s b/libc/nt/ws2_32/gethostbyname.s new file mode 100644 index 00000000..fb1a9450 --- /dev/null +++ b/libc/nt/ws2_32/gethostbyname.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_gethostbyname,gethostbyname,52 diff --git a/libc/nt/ws2_32/gethostname.s b/libc/nt/ws2_32/gethostname.s new file mode 100644 index 00000000..5023e9e3 --- /dev/null +++ b/libc/nt/ws2_32/gethostname.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_gethostname,gethostname,57 diff --git a/libc/nt/ws2_32/getnameinfo.s b/libc/nt/ws2_32/getnameinfo.s new file mode 100644 index 00000000..537759c1 --- /dev/null +++ b/libc/nt/ws2_32/getnameinfo.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_getnameinfo,getnameinfo,192 diff --git a/libc/nt/ws2_32/getpeername.s b/libc/nt/ws2_32/getpeername.s new file mode 100644 index 00000000..3bcc0b0c --- /dev/null +++ b/libc/nt/ws2_32/getpeername.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_getpeername,getpeername,5 + + .text.windows +__getpeername$nt: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_getpeername(%rip),%rax + jmp __sysv2nt + .endfn __getpeername$nt,globl + .previous diff --git a/libc/nt/ws2_32/getprotobyname.s b/libc/nt/ws2_32/getprotobyname.s new file mode 100644 index 00000000..c0ac98e9 --- /dev/null +++ b/libc/nt/ws2_32/getprotobyname.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_getprotobyname,getprotobyname,53 diff --git a/libc/nt/ws2_32/getprotobynumber.s b/libc/nt/ws2_32/getprotobynumber.s new file mode 100644 index 00000000..5df81140 --- /dev/null +++ b/libc/nt/ws2_32/getprotobynumber.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_getprotobynumber,getprotobynumber,54 diff --git a/libc/nt/ws2_32/getservbyname.s b/libc/nt/ws2_32/getservbyname.s new file mode 100644 index 00000000..c04e111f --- /dev/null +++ b/libc/nt/ws2_32/getservbyname.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_getservbyname,getservbyname,55 diff --git a/libc/nt/ws2_32/getservbyport.s b/libc/nt/ws2_32/getservbyport.s new file mode 100644 index 00000000..a99c2f26 --- /dev/null +++ b/libc/nt/ws2_32/getservbyport.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_getservbyport,getservbyport,56 diff --git a/libc/nt/ws2_32/getsockname.s b/libc/nt/ws2_32/getsockname.s new file mode 100644 index 00000000..b3e87886 --- /dev/null +++ b/libc/nt/ws2_32/getsockname.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_getsockname,getsockname,6 + + .text.windows +__getsockname$nt: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_getsockname(%rip),%rax + jmp __sysv2nt + .endfn __getsockname$nt,globl + .previous diff --git a/libc/nt/ws2_32/getsockopt.s b/libc/nt/ws2_32/getsockopt.s new file mode 100644 index 00000000..fe9d7b5d --- /dev/null +++ b/libc/nt/ws2_32/getsockopt.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_getsockopt,getsockopt,7 + + .text.windows +__getsockopt$nt: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_getsockopt(%rip),%rax + jmp __sysv2nt6 + .endfn __getsockopt$nt,globl + .previous diff --git a/libc/nt/ws2_32/htonl.s b/libc/nt/ws2_32/htonl.s new file mode 100644 index 00000000..0e2ce8ec --- /dev/null +++ b/libc/nt/ws2_32/htonl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_htonl,htonl,8 diff --git a/libc/nt/ws2_32/htons.s b/libc/nt/ws2_32/htons.s new file mode 100644 index 00000000..651a21c3 --- /dev/null +++ b/libc/nt/ws2_32/htons.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_htons,htons,9 diff --git a/libc/nt/ws2_32/inet_addr.s b/libc/nt/ws2_32/inet_addr.s new file mode 100644 index 00000000..4665fbd9 --- /dev/null +++ b/libc/nt/ws2_32/inet_addr.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_inet_addr,inet_addr,11 diff --git a/libc/nt/ws2_32/inet_ntoa.s b/libc/nt/ws2_32/inet_ntoa.s new file mode 100644 index 00000000..9ffc86f6 --- /dev/null +++ b/libc/nt/ws2_32/inet_ntoa.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_inet_ntoa,inet_ntoa,12 diff --git a/libc/nt/ws2_32/inet_ntop.s b/libc/nt/ws2_32/inet_ntop.s new file mode 100644 index 00000000..1ad0aaea --- /dev/null +++ b/libc/nt/ws2_32/inet_ntop.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_inet_ntop,inet_ntop,193 diff --git a/libc/nt/ws2_32/inet_pton.s b/libc/nt/ws2_32/inet_pton.s new file mode 100644 index 00000000..853936d2 --- /dev/null +++ b/libc/nt/ws2_32/inet_pton.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_inet_pton,inet_pton,194 diff --git a/libc/nt/ws2_32/ioctlsocket.s b/libc/nt/ws2_32/ioctlsocket.s new file mode 100644 index 00000000..008b1099 --- /dev/null +++ b/libc/nt/ws2_32/ioctlsocket.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_ioctlsocket,ioctlsocket,10 + + .text.windows +__ioctlsocket$nt: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_ioctlsocket(%rip),%rax + jmp __sysv2nt + .endfn __ioctlsocket$nt,globl + .previous diff --git a/libc/nt/ws2_32/listen.s b/libc/nt/ws2_32/listen.s new file mode 100644 index 00000000..ffebfa4d --- /dev/null +++ b/libc/nt/ws2_32/listen.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_listen,listen,13 + + .text.windows +__listen$nt: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_listen(%rip),%rax + jmp __sysv2nt + .endfn __listen$nt,globl + .previous diff --git a/libc/nt/ws2_32/ntohl.s b/libc/nt/ws2_32/ntohl.s new file mode 100644 index 00000000..334821f3 --- /dev/null +++ b/libc/nt/ws2_32/ntohl.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_ntohl,ntohl,14 diff --git a/libc/nt/ws2_32/ntohs.s b/libc/nt/ws2_32/ntohs.s new file mode 100644 index 00000000..d61c94c4 --- /dev/null +++ b/libc/nt/ws2_32/ntohs.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_ntohs,ntohs,15 diff --git a/libc/nt/ws2_32/recv.s b/libc/nt/ws2_32/recv.s new file mode 100644 index 00000000..a4ed1fc2 --- /dev/null +++ b/libc/nt/ws2_32/recv.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_recv,recv,16 diff --git a/libc/nt/ws2_32/recvfrom.s b/libc/nt/ws2_32/recvfrom.s new file mode 100644 index 00000000..fbe79e66 --- /dev/null +++ b/libc/nt/ws2_32/recvfrom.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_recvfrom,recvfrom,17 diff --git a/libc/nt/ws2_32/select.s b/libc/nt/ws2_32/select.s new file mode 100644 index 00000000..d8b67566 --- /dev/null +++ b/libc/nt/ws2_32/select.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_select,select,18 diff --git a/libc/nt/ws2_32/send.s b/libc/nt/ws2_32/send.s new file mode 100644 index 00000000..012a81e5 --- /dev/null +++ b/libc/nt/ws2_32/send.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_send,send,19 diff --git a/libc/nt/ws2_32/sendto.s b/libc/nt/ws2_32/sendto.s new file mode 100644 index 00000000..35192d29 --- /dev/null +++ b/libc/nt/ws2_32/sendto.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_sendto,sendto,20 diff --git a/libc/nt/ws2_32/setsockopt.s b/libc/nt/ws2_32/setsockopt.s new file mode 100644 index 00000000..a334f22b --- /dev/null +++ b/libc/nt/ws2_32/setsockopt.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_setsockopt,setsockopt,21 + + .text.windows +__setsockopt$nt: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_setsockopt(%rip),%rax + jmp __sysv2nt6 + .endfn __setsockopt$nt,globl + .previous diff --git a/libc/nt/ws2_32/shutdown.s b/libc/nt/ws2_32/shutdown.s new file mode 100644 index 00000000..5f5233aa --- /dev/null +++ b/libc/nt/ws2_32/shutdown.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_shutdown,shutdown,22 + + .text.windows +__shutdown$nt: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_shutdown(%rip),%rax + jmp __sysv2nt + .endfn __shutdown$nt,globl + .previous diff --git a/libc/nt/ws2_32/socket.s b/libc/nt/ws2_32/socket.s new file mode 100644 index 00000000..8372b3b6 --- /dev/null +++ b/libc/nt/ws2_32/socket.s @@ -0,0 +1,2 @@ +.include "o/libc/nt/codegen.inc" +.imp ws2_32,__imp_socket,socket,23 diff --git a/libc/paths.h b/libc/paths.h new file mode 100644 index 00000000..17a48dfb --- /dev/null +++ b/libc/paths.h @@ -0,0 +1,31 @@ +#ifndef COSMOPOLITAN_LIBC_PATHS_H_ +#define COSMOPOLITAN_LIBC_PATHS_H_ + +#define _PATH_DEFPATH "/usr/local/bin:/bin:/usr/bin" +#define _PATH_STDPATH "/bin:/usr/bin:/sbin:/usr/sbin" + +#define _PATH_BSHELL "/bin/sh" +#define _PATH_CONSOLE "/dev/console" +#define _PATH_DEVNULL "/dev/null" +#define _PATH_KLOG "/proc/kmsg" +#define _PATH_LASTLOG "/var/log/lastlog" +#define _PATH_MAILDIR "/var/mail" +#define _PATH_MAN "/usr/share/man" +#define _PATH_MNTTAB "/etc/fstab" +#define _PATH_MOUNTED "/etc/mtab" +#define _PATH_NOLOGIN "/etc/nologin" +#define _PATH_SENDMAIL "/usr/sbin/sendmail" +#define _PATH_SHADOW "/etc/shadow" +#define _PATH_SHELLS "/etc/shells" +#define _PATH_TTY "/dev/tty" +#define _PATH_UTMP "/dev/null/utmp" +#define _PATH_VI "/usr/bin/vi" +#define _PATH_WTMP "/dev/null/wtmp" + +#define _PATH_DEV "/dev/" +#define _PATH_TMP "/tmp/" +#define _PATH_VARDB "/var/lib/misc/" +#define _PATH_VARRUN "/var/run/" +#define _PATH_VARTMP "/var/tmp/" + +#endif /* COSMOPOLITAN_LIBC_PATHS_H_ */ diff --git a/libc/pe.h b/libc/pe.h new file mode 100644 index 00000000..b9b0239d --- /dev/null +++ b/libc/pe.h @@ -0,0 +1,28 @@ +#ifndef COSMOPOLITAN_LIBC_PE_H_ +#define COSMOPOLITAN_LIBC_PE_H_ +#include "libc/dce.h" +#include "libc/nt/pedef.h" +#include "libc/nt/struct/imagedosheader.h" +#include "libc/runtime/runtime.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +forceinline void *pecheckaddress(struct NtImageDosHeader *mz, size_t mzsize, + void *addr, uint32_t addrsize) { +#if !(TRUSTWORTHY + PE_TRUSTWORTHY + 0) + if ((intptr_t)addr < (intptr_t)mz || + (intptr_t)addr + addrsize > (intptr_t)mz + mzsize) { + abort(); + } +#endif + return addr; +} + +forceinline void *pecomputerva(struct NtImageDosHeader *mz, size_t mzsize, + uint32_t reladdr, uint32_t addrsize) { + return pecheckaddress(mz, mzsize, (void *)((intptr_t)mz + reladdr), addrsize); +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_PE_H_ */ diff --git a/libc/rand/devrand.c b/libc/rand/devrand.c new file mode 100644 index 00000000..6ac42b88 --- /dev/null +++ b/libc/rand/devrand.c @@ -0,0 +1,54 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/dce.h" +#include "libc/rand/rand.h" +#include "libc/str/str.h" +#include "libc/calls/internal.h" +#include "libc/calls/calls.h" +#include "libc/sysv/errfuns.h" +#include "libc/sysv/consts/at.h" +#include "libc/sysv/consts/nr.h" +#include "libc/sysv/consts/o.h" + +/** + * Reads random bytes from system pseudo random number api. + * @return 0 on success or -1 w/ errno + */ +int devrand(void *buf, size_t size) { + int fd; + size_t got; + ssize_t rc; + unsigned char *p, *pe; + fd = -1; + if (IsWindows()) return enosys(); + if ((fd = openat$sysv(AT_FDCWD, "/dev/urandom", O_RDONLY, 0)) == -1) { + return -1; + } + p = buf; + pe = p + size; + while (p < pe) { + if ((rc = read$sysv(fd, p, pe - p)) == -1) break; + if (!(got = (size_t)rc)) break; + p += got; + } + close$sysv(fd); + return p == pe ? 0 : -1; +} diff --git a/libc/rand/g_rando.S b/libc/rand/g_rando.S new file mode 100644 index 00000000..2e6e728d --- /dev/null +++ b/libc/rand/g_rando.S @@ -0,0 +1,32 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +#include "libc/notice.inc" +.yoink __FILE__ + + .bss + .align 8 +g_rando:.quad 0 + .endobj g_rando,globl,hidden + .previous + + .init.start 100,_init_g_rando + movq $1,g_rando(%rip) + .init.end 100,_init_g_rando diff --git a/libc/rand/g_rando32.c b/libc/rand/g_rando32.c new file mode 100644 index 00000000..422a816e --- /dev/null +++ b/libc/rand/g_rando32.c @@ -0,0 +1,48 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/dce.h" +#include "libc/rand/rand.h" +#include "libc/rand/xorshift.h" +#include "libc/sysv/consts/auxv.h" + +hidden uint32_t g_rando32; + +textstartup static void g_rando32_init() { + register intptr_t *auxv asm("r15"); /* @see libc/crt/crt.S */ + asm volatile("" : "=r"(auxv)); + if (!IsXnu() && !IsWindows()) { + for (intptr_t *auxvp = auxv; auxvp[0]; auxvp += 2) { + if (auxvp[0] == AT_RANDOM) { + uint8_t(*sysrandseed)[16] = (uint8_t(*)[16])auxvp[1]; + if (sysrandseed) g_rando32 ^= read32le(&(*sysrandseed)[8]); + return; + } + } + } + g_rando32 ^= kMarsagliaXorshift32Seed; + if (IsWindows()) { + g_rando32 ^= winrandish(); + } else { + devrand(&g_rando32, sizeof(g_rando32)); + } +} + +const void *const g_rando32_ctor[] initarray = {g_rando32_init}; diff --git a/libc/rand/g_rando64.c b/libc/rand/g_rando64.c new file mode 100644 index 00000000..0fd88bf7 --- /dev/null +++ b/libc/rand/g_rando64.c @@ -0,0 +1,48 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/dce.h" +#include "libc/rand/rand.h" +#include "libc/rand/xorshift.h" +#include "libc/sysv/consts/auxv.h" + +hidden uint64_t g_rando64; + +textstartup static void g_rando64_init() { + register intptr_t *auxv asm("r15"); /* @see libc/crt/crt.S */ + asm volatile("" : "=r"(auxv)); + if (!IsXnu() && !IsWindows()) { + for (intptr_t *auxvp = auxv; auxvp[0]; auxvp += 2) { + if (auxvp[0] == AT_RANDOM) { + uint8_t(*sysrandseed)[16] = (uint8_t(*)[16])auxvp[1]; + if (sysrandseed) g_rando64 ^= read64le(&(*sysrandseed)[0]); + return; + } + } + } + g_rando64 ^= kMarsagliaXorshift64Seed; + if (IsWindows()) { + g_rando64 ^= winrandish(); + } else { + devrand(&g_rando64, sizeof(g_rando64)); + } +} + +const void *const g_rando64_ctor[] initarray = {g_rando64_init}; diff --git a/libc/rand/getentropy.c b/libc/rand/getentropy.c new file mode 100644 index 00000000..ebe58a11 --- /dev/null +++ b/libc/rand/getentropy.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/rand/rand.h" +#include "libc/sysv/consts/grnd.h" + +/** + * Returns random seeding bytes, the XNU/OpenBSD way. + * @see getrandom() + */ +int getentropy(void *buf, size_t size) { + return getrandom(buf, size, GRND_RANDOM); +} diff --git a/libc/rand/getrandom.c b/libc/rand/getrandom.c new file mode 100644 index 00000000..57ab998e --- /dev/null +++ b/libc/rand/getrandom.c @@ -0,0 +1,51 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/calls/internal.h" +#include "libc/errno.h" +#include "libc/rand/rand.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" + +/** + * Returns random bytes appropriate for random seeding. + * + * @param size should be the smallest value that meets your requirements + * @param flags may be GRND_{RANDOM,NONBLOCK} + * @return number of bytes copied on success; or -1 w/ errno, which + * indicates only that the request couldn't be serviced by the host + * kernel; this wrapper will still fill the buffer with random bytes + * from fallback sources no matter what + */ +ssize_t getrandom(void *buf, size_t size, unsigned flags) { + ssize_t rc = getrandom$sysv(buf, size, flags); + size_t i = rc == -1 ? 0 : (size_t)rc; + if (i > size) abort(); + if (i < size) { + unsigned char *p = buf; + int olderr = errno; + do { + uint64_t i64 = rand64(); + memcpy(&p[i], &i64, min(sizeof(i64), size - i)); + } while ((i += sizeof(uint64_t)) < size); + errno = olderr; + } + return rc; +} diff --git a/libc/rand/internal.h b/libc/rand/internal.h new file mode 100644 index 00000000..e2b4cf1e --- /dev/null +++ b/libc/rand/internal.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_RAND_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_RAND_INTERNAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern uint64_t g_rando; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_RAND_INTERNAL_H_ */ diff --git a/libc/rand/lcg.h b/libc/rand/lcg.h new file mode 100644 index 00000000..e6ac7f7b --- /dev/null +++ b/libc/rand/lcg.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_LCG_H_ +#define COSMOPOLITAN_LIBC_LCG_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +forceinline uint64_t KnuthLinearCongruentialGenerator(uint64_t prev[1]) { + /* Knuth, D.E., "The Art of Computer Programming," Vol 2, + Seminumerical Algorithms, Third Edition, Addison-Wesley, 1998, + p. 106 (line 26) & p. 108 */ + prev[0] = prev[0] * 6364136223846793005 + 1442695040888963407; + return prev[0]; +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_LCG_H_ */ diff --git a/libc/rand/poz.c b/libc/rand/poz.c new file mode 100644 index 00000000..d7c254d4 --- /dev/null +++ b/libc/rand/poz.c @@ -0,0 +1,142 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8 -*-│ +│vi: set et ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│ +╚─────────────────────────────────────────────────────────────────────────────*/ +/* clang-format off */ +/* + + Compute probability of measured Chi Square value. + + This code was developed by Gary Perlman of the Wang + Institute (full citation below) and has been minimally + modified for use in this program. + +*/ + +#include "libc/math.h" + +/*HEADER + Module: z.c + Purpose: compute approximations to normal z distribution probabilities + Programmer: Gary Perlman + Organization: Wang Institute, Tyngsboro, MA 01879 + Copyright: none + Tabstops: 4 +*/ + +#define Z_MAX 6.0 /* maximum meaningful z value */ + +/*FUNCTION poz: probability of normal z value */ +/*ALGORITHM + Adapted from a polynomial approximation in: + Ibbetson D, Algorithm 209 + Collected Algorithms of the CACM 1963 p. 616 + Note: + This routine has six digit accuracy, so it is only useful for absolute + z values < 6. For z values >= to 6.0, poz() returns 0.0. +*/ +static double /*VAR returns cumulative probability from -oo to z */ +poz(const double z) /*VAR normal z value */ +{ + double y, x, w; + + if (z == 0.0) { + x = 0.0; + } else { + y = 0.5 * fabs(z); + if (y >= (Z_MAX * 0.5)) { + x = 1.0; + } else if (y < 1.0) { + w = y * y; + x = ((((((((0.000124818987 * w + -0.001075204047) * w +0.005198775019) * w + -0.019198292004) * w +0.059054035642) * w + -0.151968751364) * w +0.319152932694) * w + -0.531923007300) * w +0.797884560593) * y * 2.0; + } else { + y -= 2.0; + x = (((((((((((((-0.000045255659 * y + +0.000152529290) * y -0.000019538132) * y + -0.000676904986) * y +0.001390604284) * y + -0.000794620820) * y -0.002034254874) * y + +0.006549791214) * y -0.010557625006) * y + +0.011630447319) * y -0.009279453341) * y + +0.005353579108) * y -0.002141268741) * y + +0.000535310849) * y +0.999936657524; + } + } + return (z > 0.0 ? ((x + 1.0) * 0.5) : ((1.0 - x) * 0.5)); +} + +/* + Module: chisq.c + Purpose: compute approximations to chisquare distribution probabilities + Contents: pochisq() + Uses: poz() in z.c (Algorithm 209) + Programmer: Gary Perlman + Organization: Wang Institute, Tyngsboro, MA 01879 + Copyright: none + Tabstops: 4 +*/ + +#define LOG_SQRT_PI 0.5723649429247000870717135 /* log (sqrt (pi)) */ +#define I_SQRT_PI 0.5641895835477562869480795 /* 1 / sqrt (pi) */ +#define BIGX 20.0 /* max value to represent exp (x) */ +#define ex(x) (((x) < -BIGX) ? 0.0 : exp(x)) + +/*FUNCTION pochisq: probability of chi sqaure value */ +/*ALGORITHM Compute probability of chi square value. + Adapted from: + Hill, I. D. and Pike, M. C. Algorithm 299 + Collected Algorithms for the CACM 1967 p. 243 + Updated for rounding errors based on remark in + ACM TOMS June 1985, page 185 +*/ + +double pochisq( + const double ax, /* obtained chi-square value */ + const int df /* degrees of freedom */ + ) +{ + double x = ax; + double a, y, s; + double e, c, z; + int even; /* true if df is an even number */ + + y = 0.0; /* XXX: blind modification due to GCC error */ + + if (x <= 0.0 || df < 1) { + return 1.0; + } + + a = 0.5 * x; + even = (2 * (df / 2)) == df; + if (df > 1) { + y = ex(-a); + } + s = (even ? y : (2.0 * poz(-sqrt(x)))); + if (df > 2) { + x = 0.5 * (df - 1.0); + z = (even ? 1.0 : 0.5); + if (a > BIGX) { + e = (even ? 0.0 : LOG_SQRT_PI); + c = log(a); + while (z <= x) { + e = log(z) + e; + s += ex(c * z - a - e); + z += 1.0; + } + return (s); + } else { + e = (even ? 1.0 : (I_SQRT_PI / sqrt(a))); + c = 0.0; + while (z <= x) { + e = e * (a / z); + c = c + e; + z += 1.0; + } + return (c * y + s); + } + } else { + return s; + } +} diff --git a/libc/rand/rand.h b/libc/rand/rand.h new file mode 100644 index 00000000..92b7e0d8 --- /dev/null +++ b/libc/rand/rand.h @@ -0,0 +1,36 @@ +#ifndef COSMOPOLITAN_LIBC_RAND_RAND_H_ +#define COSMOPOLITAN_LIBC_RAND_RAND_H_ +#include "libc/ncabi.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § random ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define RAND_MAX __INT_MAX__ /* only applies to rand() */ +void srand(uint64_t) nothrow nocallback; /* seeds rand() only */ +int rand(void) nothrow nocallback; /* ≥0 unseeded lcg prng */ +uint32_t rand32(void) nothrow nocallback; /* random as possible rng */ +uint64_t rand64(void) nothrow nocallback; /* random as possible rng */ +double poz(double); /* verify our claims */ +double pochisq(double, int); +void rt_init(int); +void rt_add(void *, int); +void rt_end(double *, double *, double *, double *, double *); +void *rngset(void *, size_t, uint64_t (*)(void), size_t) paramsnonnull(); +char *strfry(char *); +int getentropy(void *, size_t); +ssize_t getrandom(void *, size_t, unsigned); +int devrand(void *, size_t); +int64_t winrandish(void); +uint64_t rdrand(void); +float randf(void); + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +NCABI_DECLARE_0(NCABI_NOPRUNE, int, __rand, "rand") +#define rand() __rand() +#endif + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_RAND_RAND_H_ */ diff --git a/libc/rand/rand.mk b/libc/rand/rand.mk new file mode 100644 index 00000000..d8f37d8e --- /dev/null +++ b/libc/rand/rand.mk @@ -0,0 +1,54 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += LIBC_RAND + +LIBC_RAND_ARTIFACTS += LIBC_RAND_A +LIBC_RAND = $(LIBC_RAND_A_DEPS) $(LIBC_RAND_A) +LIBC_RAND_A = o/$(MODE)/libc/rand/rand.a +LIBC_RAND_A_FILES := $(wildcard libc/rand/*) +LIBC_RAND_A_HDRS = $(filter %.h,$(LIBC_RAND_A_FILES)) +LIBC_RAND_A_SRCS_S = $(filter %.S,$(LIBC_RAND_A_FILES)) +LIBC_RAND_A_SRCS_C = $(filter %.c,$(LIBC_RAND_A_FILES)) + +LIBC_RAND_A_SRCS = \ + $(LIBC_RAND_A_SRCS_S) \ + $(LIBC_RAND_A_SRCS_C) + +LIBC_RAND_A_OBJS = \ + $(LIBC_RAND_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_RAND_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_RAND_A_SRCS_C:%.c=o/$(MODE)/%.o) + +LIBC_RAND_A_CHECKS = \ + $(LIBC_RAND_A).pkg \ + $(LIBC_RAND_A_HDRS:%=o/$(MODE)/%.ok) + +LIBC_RAND_A_DIRECTDEPS = \ + LIBC_STUBS \ + LIBC_TINYMATH \ + LIBC_NEXGEN32E \ + LIBC_NT_KERNELBASE \ + LIBC_SYSV_CALLS \ + LIBC_SYSV + +LIBC_RAND_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_RAND_A_DIRECTDEPS),$($(x)))) + +$(LIBC_RAND_A): libc/rand/ \ + $(LIBC_RAND_A).pkg \ + $(LIBC_RAND_A_OBJS) + +$(LIBC_RAND_A).pkg: \ + $(LIBC_RAND_A_OBJS) \ + $(foreach x,$(LIBC_RAND_A_DIRECTDEPS),$($(x)_A).pkg) + +LIBC_RAND_LIBS = $(foreach x,$(LIBC_RAND_ARTIFACTS),$($(x))) +LIBC_RAND_SRCS = $(foreach x,$(LIBC_RAND_ARTIFACTS),$($(x)_SRCS)) +LIBC_RAND_HDRS = $(foreach x,$(LIBC_RAND_ARTIFACTS),$($(x)_HDRS)) +LIBC_RAND_CHECKS = $(foreach x,$(LIBC_RAND_ARTIFACTS),$($(x)_CHECKS)) +LIBC_RAND_OBJS = $(foreach x,$(LIBC_RAND_ARTIFACTS),$($(x)_OBJS)) +$(LIBC_RAND_OBJS): $(BUILD_FILES) libc/rand/rand.mk + +.PHONY: o/$(MODE)/libc/rand +o/$(MODE)/libc/rand: $(LIBC_RAND_CHECKS) diff --git a/libc/rand/rand.ncabi.c b/libc/rand/rand.ncabi.c new file mode 100644 index 00000000..6255a04f --- /dev/null +++ b/libc/rand/rand.ncabi.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/rand/internal.h" +#include "libc/rand/lcg.h" +#include "libc/rand/rand.h" + +/** + * Returns 31-bit random number using a linear congruential generator. + * + * Please note that, unlike rand32(), the rand() function uses the same + * seed at startup by default, unless srand() is called. This makes it + * useful in cases where deterministic behavior is needed. + */ +int(rand)(void) { return KnuthLinearCongruentialGenerator(&g_rando) >> 33; } diff --git a/libc/rand/rand32.c b/libc/rand/rand32.c new file mode 100644 index 00000000..d8b65c64 --- /dev/null +++ b/libc/rand/rand32.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/rand/rand.h" +#include "libc/rand/xorshift.h" + +/** + * This function is an independent 32-bit clone of rand64(). + */ +nodebuginfo uint32_t(rand32)(void) { + uint32_t res; + if (X86_HAVE(RDRND)) { + res = rdrand(); + } else { + if (IsWindows()) { + res = kMarsagliaXorshift32Seed ^ winrandish(); + } else { + devrand(&res, sizeof(res)); + } + hidden extern uint32_t g_rando32; + res ^= MarsagliaXorshift32(&g_rando32); + } + return res; +} diff --git a/libc/rand/rand64.c b/libc/rand/rand64.c new file mode 100644 index 00000000..52a04275 --- /dev/null +++ b/libc/rand/rand64.c @@ -0,0 +1,49 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/rand/rand.h" +#include "libc/rand/xorshift.h" + +/** + * Returns nondeterministic random number. + * + * This function uses a good random source if it's available, which + * takes ~400 cycles (~99ns). Otherwise it's seeded at program start + * with the system provided random value and may perform a few + * microseconds worth of system calls to get a good value. + * + * @see rngset() + */ +nodebuginfo uint64_t(rand64)(void) { + uint64_t res; + if (X86_HAVE(RDRND)) { + res = rdrand(); + } else { + if (IsWindows()) { + res = winrandish(); + } else { + devrand(&res, sizeof(res)); + } + hidden extern uint64_t g_rando64; + res ^= MarsagliaXorshift64(&g_rando64); + } + return res; +} diff --git a/libc/rand/randf.c b/libc/rand/randf.c new file mode 100644 index 00000000..e269fc1d --- /dev/null +++ b/libc/rand/randf.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/limits.h" +#include "libc/rand/internal.h" +#include "libc/rand/lcg.h" +#include "libc/rand/rand.h" + +float randf(void) { + return (float)(int)(KnuthLinearCongruentialGenerator(&g_rando) >> 32) / + INT_MAX; +} diff --git a/libc/rand/rando.c b/libc/rand/rando.c new file mode 100644 index 00000000..926744d5 --- /dev/null +++ b/libc/rand/rando.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/rand/internal.h" + +uint64_t g_rando; diff --git a/libc/rand/randtest.c b/libc/rand/randtest.c new file mode 100644 index 00000000..b4dff4b0 --- /dev/null +++ b/libc/rand/randtest.c @@ -0,0 +1,184 @@ +/* clang-format off */ +/* + + Apply various randomness tests to a stream of bytes + + by John Walker -- September 1996 + http://www.fourmilab.ch/ + +*/ + +#include "libc/math.h" + +#define FALSE 0 +#define TRUE 1 + +#define log2of10 3.32192809488736234787 + +static int binary = FALSE; /* Treat input as a bitstream */ + +static long ccount[256], /* Bins to count occurrences of values */ + totalc = 0; /* Total bytes counted */ +static double prob[256]; /* Probabilities per bin for entropy */ + +/* RT_LOG2 -- Calculate log to the base 2 */ + +static double rt_log2(double x) +{ + return log2of10 * log10(x); +} + +#define MONTEN 6 /* Bytes used as Monte Carlo + co-ordinates. This should be no more + bits than the mantissa of your + "double" floating point type. */ + +static int mp, sccfirst; +static unsigned int monte[MONTEN]; +static long inmont, mcount; +static double cexp_, incirc, montex, montey, montepi, + scc, sccun, sccu0, scclast, scct1, scct2, scct3, + ent, chisq, datasum; + +/* RT_INIT -- Initialise random test counters. */ + +void rt_init(int binmode) +{ + int i; + + binary = binmode; /* Set binary / byte mode */ + + /* Initialise for calculations */ + + ent = 0.0; /* Clear entropy accumulator */ + chisq = 0.0; /* Clear Chi-Square */ + datasum = 0.0; /* Clear sum of bytes for arithmetic mean */ + + mp = 0; /* Reset Monte Carlo accumulator pointer */ + mcount = 0; /* Clear Monte Carlo tries */ + inmont = 0; /* Clear Monte Carlo inside count */ + incirc = 65535.0 * 65535.0;/* In-circle distance for Monte Carlo */ + + sccfirst = TRUE; /* Mark first time for serial correlation */ + scct1 = scct2 = scct3 = 0.0; /* Clear serial correlation terms */ + + incirc = pow(pow(256.0, (double) (MONTEN / 2)) - 1, 2.0); + + for (i = 0; i < 256; i++) { + ccount[i] = 0; + } + totalc = 0; +} + +/* RT_ADD -- Add one or more bytes to accumulation. */ + +void rt_add(void *buf, int bufl) +{ + unsigned char *bp = buf; + int oc, c, bean; + + while (bean = 0, (bufl-- > 0)) { + oc = *bp++; + + do { + if (binary) { + c = !!(oc & 0x80); + } else { + c = oc; + } + ccount[c]++; /* Update counter for this bin */ + totalc++; + + /* Update inside / outside circle counts for Monte Carlo + computation of PI */ + + if (bean == 0) { + monte[mp++] = oc; /* Save character for Monte Carlo */ + if (mp >= MONTEN) { /* Calculate every MONTEN character */ + int mj; + + mp = 0; + mcount++; + montex = montey = 0; + for (mj = 0; mj < MONTEN / 2; mj++) { + montex = (montex * 256.0) + monte[mj]; + montey = (montey * 256.0) + monte[(MONTEN / 2) + mj]; + } + if ((montex * montex + montey * montey) <= incirc) { + inmont++; + } + } + } + + /* Update calculation of serial correlation coefficient */ + + sccun = c; + if (sccfirst) { + sccfirst = FALSE; + scclast = 0; + sccu0 = sccun; + } else { + scct1 = scct1 + scclast * sccun; + } + scct2 = scct2 + sccun; + scct3 = scct3 + (sccun * sccun); + scclast = sccun; + oc <<= 1; + } while (binary && (++bean < 8)); + } +} + +/* RT_END -- Complete calculation and return results. */ + +void rt_end(double *r_ent, double *r_chisq, double *r_mean, + double *r_montepicalc, double *r_scc) +{ + int i; + + /* Complete calculation of serial correlation coefficient */ + + scct1 = scct1 + scclast * sccu0; + scct2 = scct2 * scct2; + scc = totalc * scct3 - scct2; + if (scc == 0.0) { + scc = -100000; + } else { + scc = (totalc * scct1 - scct2) / scc; + } + + /* Scan bins and calculate probability for each bin and + Chi-Square distribution. The probability will be reused + in the entropy calculation below. While we're at it, + we sum of all the data which will be used to compute the + mean. */ + + cexp_ = totalc / (binary ? 2.0 : 256.0); /* Expected count per bin */ + for (i = 0; i < (binary ? 2 : 256); i++) { + double a = ccount[i] - cexp_; + + prob[i] = ((double) ccount[i]) / totalc; + chisq += (a * a) / cexp_; + datasum += ((double) i) * ccount[i]; + } + + /* Calculate entropy */ + + for (i = 0; i < (binary ? 2 : 256); i++) { + if (prob[i] > 0.0) { + ent += prob[i] * rt_log2(1 / prob[i]); + } + } + + /* Calculate Monte Carlo value for PI from percentage of hits + within the circle */ + + montepi = 4.0 * (((double) inmont) / mcount); + + /* Return results through arguments */ + + *r_ent = ent; + *r_chisq = chisq; + *r_mean = datasum / totalc; + *r_montepicalc = montepi; + *r_scc = scc; +} diff --git a/libc/rand/rdrand.c b/libc/rand/rdrand.c new file mode 100644 index 00000000..e359265d --- /dev/null +++ b/libc/rand/rdrand.c @@ -0,0 +1,47 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/rand/rand.h" + +/** + * Intel Secure Key Digital Random Number Generator + * Introduced w/ Ivy Bridge c. 2013 and Excavator c. 2015 + * @see rand32(), rand64(), and randcpy() + */ +uint64_t rdrand(void) { + char cf; + size_t i; + uint64_t res; + assert(X86_HAVE(RDRND)); + for (;;) { + for (i = 0; i < 10; ++i) { + /* CF=1: Destination register valid. Quoth Intel DRNG-SIG 4.1.3 */ + asm volatile(CFLAG("rdrand\t%1") + : CF(cf), "=r"(res) + : /* no inputs */ + : "cc"); + if (cf) return res; + } + asm volatile("rep nop"); /* unlikely 140 cycle spin */ + } +} diff --git a/libc/rand/rngset.c b/libc/rand/rngset.c new file mode 100644 index 00000000..57b95bef --- /dev/null +++ b/libc/rand/rngset.c @@ -0,0 +1,54 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/rand/rand.h" +#include "libc/rand/xorshift.h" +#include "libc/str/str.h" + +/** + * Fills memory with random bytes. + * + * @param seed can be rand64 + * @param reseed is number of bytes between seed() calls + * @return buf + */ +void *rngset(void *buf, size_t size, uint64_t (*seed)(void), size_t reseed) { + unsigned char *p; + uint64_t i, x, state; + i = 0; + p = buf; + state = seed(); + for (i = 0; size - i >= sizeof(x); i += sizeof(x)) { + x = MarsagliaXorshift64(&state); + memcpy(p + i, &x, sizeof(x)); + if (i >= reseed) { + state = seed(); + p += i; + size -= i; + i = 0; + } + } + if (i < size) { + x = MarsagliaXorshift64(&state); + for (; i < size; ++i, x >>= 8) { + p[i] = x & 0xff; + } + } + return buf; +} diff --git a/libc/rand/srand.c b/libc/rand/srand.c new file mode 100644 index 00000000..2e7759ee --- /dev/null +++ b/libc/rand/srand.c @@ -0,0 +1,27 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/rand/rand.h" + +extern uint64_t g_rando; + +/** + * Seeds random number generator that's used by rand(). + */ +void(srand)(uint64_t seed) { g_rando = seed; } diff --git a/libc/rand/strfry.c b/libc/rand/strfry.c new file mode 100644 index 00000000..96bf35b4 --- /dev/null +++ b/libc/rand/strfry.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/shuffle.h" +#include "libc/rand/rand.h" +#include "libc/str/str.h" + +/** + * Jumbles up string. + */ +char *strfry(char *s) { + shuffle(rand, s, strlen(s)); + return s; +} diff --git a/libc/rand/winrandish.c b/libc/rand/winrandish.c new file mode 100644 index 00000000..2a55b47b --- /dev/null +++ b/libc/rand/winrandish.c @@ -0,0 +1,44 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/nexgen32e/rdtsc.h" +#include "libc/nt/dll.h" +#include "libc/nt/events.h" +#include "libc/nt/struct/point.h" +#include "libc/nt/struct/teb.h" +#include "libc/rand/rand.h" + +/** + * Returns somewhat randomish number on Windows. + */ +textwindows int64_t winrandish(void) { + int64_t res; + struct NtPoint point; + res = ((int64_t)NtGetPid() << 17) ^ NtGetTid() ^ rdtsc(); + /* + * This function is intended for older CPUs built before 2012, so + * let's avoid having our CUI apps yoink USER32.DLL until we're + * certain we need it, thus avoiding a hundred lines of noise in + * NtTrace.exe output. + */ + typeof(GetCursorPos) *GetCursorPos_ = + GetProcAddress(GetModuleHandle("user32.dll"), "GetCursorPos"); + if (GetCursorPos_ && GetCursorPos_(&point)) res ^= point.x * point.y; + return res; +} diff --git a/libc/rand/xorshift.h b/libc/rand/xorshift.h new file mode 100644 index 00000000..b98d8bbb --- /dev/null +++ b/libc/rand/xorshift.h @@ -0,0 +1,28 @@ +#ifndef COSMOPOLITAN_LIBC_RAND_XORSHIFT_H_ +#define COSMOPOLITAN_LIBC_RAND_XORSHIFT_H_ + +#define kMarsagliaXorshift64Seed 88172645463325252 +#define kMarsagliaXorshift32Seed 2463534242 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +forceinline uint64_t MarsagliaXorshift64(uint64_t state[hasatleast 1]) { + uint64_t x = state[0]; + x ^= x << 13; + x ^= x >> 7; + x ^= x << 17; + state[0] = x; + return x; +} + +forceinline uint32_t MarsagliaXorshift32(uint32_t state[hasatleast 1]) { + uint32_t x = state[0]; + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + state[0] = x; + return x; +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_RAND_XORSHIFT_H_ */ diff --git a/libc/runtime/_exit.S b/libc/runtime/_exit.S new file mode 100644 index 00000000..bd5f4723 --- /dev/null +++ b/libc/runtime/_exit.S @@ -0,0 +1,52 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/runtime/internal.h" +#include "libc/macros.h" +.privileged +.yoink __FILE__ + +/ Terminates process, ignoring destructors and atexit() handlers. +/ +/ Normally exit() or quick_exit() is better. This won't even flush +/ stdio streams. Sometimes that makes sense, like after fork(). +/ +/ @param edi is exit code ∈ [0,256) +/ @note _exit() is same thing +/ @asyncsignalsafe +_Exit: orl $RUNSTATE_TERMINATE,g_runstate(%rip) +#if SupportsWindows() + testb IsWindows() + jz 1f + movzbl %dil,%ecx # %ERRORLEVEL% is limitless +4: call *__imp_ExitProcess(%rip) + jmp 4b +0: int3 # @see setjmp() in WinMain() +#endif +1: mov __NR_exit(%rip),%eax + syscall + cli + lidt 3f +2: hlt + jmp 2b +3: .quad 0 + .endfn _Exit,globl,protected + .hidden __NR_exit + .hidden g_runstate diff --git a/libc/runtime/abort.S b/libc/runtime/abort.S new file mode 100644 index 00000000..2528abec --- /dev/null +++ b/libc/runtime/abort.S @@ -0,0 +1,64 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/runtime/internal.h" +#include "libc/sysv/consts/sig.h" +#include "libc/sysv/consts/nr.h" +#include "libc/macros.h" +.real +.yoink __FILE__ + +/ Terminates program abnormally. +/ +/ This function first tries to trigger your SIGABRT handler. If +/ there isn't one or execution resumes, then abort() terminates +/ the program using an escalating variety methods of increasing +/ brutality. +/ +/ @forcealignargpointer +/ @asyncsignalsafe +/ @noreturn +abort: push %rbp + mov %rsp,%rbp + and $-16,%rsp + sub $16,%rsp + orl $RUNSTATE_BROKEN,g_runstate(%rip) + testb IsWindows() + jnz 2f + mov SIG_SETMASK,%edi + mov %rsp,%rsi + push $0xffffffffffffffdf # all bits blocked but SIGABRT + push $0xffffffffffffffff # assumes von neum. arithmetic + pop 8(%rsi) + pop (%rsi) + xor %edx,%edx # don't care about old sigmask + pushpop 4*4,%r10 # sizeof(sigset_t) for systemd + mov __NR_sigprocmask,%eax # sigprocmask$sysv is hookable + syscall + mov __NR_getpid,%eax + syscall + mov %eax,%edi + mov SIGABRT,%esi + mov __NR_kill,%eax + syscall # avoid hook and less bt noise +2: mov $134,%edi # exit(128+SIGABRT) [bash-ism] + call _Exit + .endfn abort,globl,protected + .hidden g_runstate diff --git a/libc/runtime/arch_prctl.c b/libc/runtime/arch_prctl.c new file mode 100644 index 00000000..c7711bb6 --- /dev/null +++ b/libc/runtime/arch_prctl.c @@ -0,0 +1,184 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/dce.h" +#include "libc/nexgen32e/msr.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/runtime/interruptiblecall.h" +#include "libc/sysv/consts/sig.h" +#include "libc/sysv/errfuns.h" + +/** + * @fileoverview Memory segmentation system calls. + * + * This whole file basically does: + * + * mov foo,%fs + * mov foo,%gs + * mov %fs,foo + * mov %gs,foo + * + * Which is nontrivial due to the limitless authoritarianism of + * operating systems. + */ + +int arch_prctl$sysv(int, int64_t) hidden; + +static inline int arch_prctl$fsgsbase(int code, int64_t addr) { + switch (code) { + case ARCH_SET_GS: + asm volatile("wrgsbase\t%0" : /* no outputs */ : "r"(addr)); + return 0; + case ARCH_SET_FS: + asm volatile("wrfsbase\t%0" : /* no outputs */ : "r"(addr)); + return 0; + case ARCH_GET_GS: + asm volatile("rdgsbase\t%0" : "=r"(*(int64_t *)addr)); + return 0; + case ARCH_GET_FS: + asm volatile("rdfsbase\t%0" : "=r"(*(int64_t *)addr)); + return 0; + default: + return einval(); + } +} + +static int arch_prctl$msr(int code, int64_t addr) { + switch (code) { + case ARCH_SET_GS: + wrmsr(MSR_IA32_GS_BASE, addr); + return 0; + case ARCH_SET_FS: + wrmsr(MSR_IA32_FS_BASE, addr); + return 0; + case ARCH_GET_GS: + *(int64_t *)addr = rdmsr(MSR_IA32_GS_BASE); + return 0; + case ARCH_GET_FS: + *(int64_t *)addr = rdmsr(MSR_IA32_FS_BASE); + return 0; + default: + return einval(); + } +} + +static int arch_prctl$freebsd(int code, int64_t addr) { + switch (code) { + case ARCH_GET_FS: + return arch_prctl$sysv(128, addr); + case ARCH_SET_FS: + return arch_prctl$sysv(129, addr); + case ARCH_GET_GS: + return arch_prctl$sysv(130, addr); + case ARCH_SET_GS: + return arch_prctl$sysv(131, addr); + default: + return einval(); + } +} + +static int arch_prctl$xnu(int code, int64_t addr) { + int ax; + switch (code) { + case ARCH_SET_GS: + asm volatile("syscall" + : "=a"(ax) + : "0"(0x3000003), "D"(addr - 0x8a0 /* wat */) + : "rcx", "r11", "memory", "cc"); + return ax; + case ARCH_GET_FS: + case ARCH_SET_FS: + case ARCH_GET_GS: + return enosys(); + default: + return einval(); + } +} + +static int arch_prctl$openbsd(int code, int64_t addr) { + int64_t rax; + switch (code) { + case ARCH_GET_FS: + asm volatile("syscall" + : "=a"(rax) + : "0"(0x014a /* __get_tcb */) + : "rcx", "r11", "cc", "memory"); + *(int64_t *)addr = rax; + return 0; + case ARCH_SET_FS: + asm volatile("syscall" + : "=a"(rax) + : "0"(0x0149 /* __set_tcb */), "D"(addr) + : "rcx", "r11", "cc", "memory"); + return 0; + case ARCH_GET_GS: + case ARCH_SET_GS: + return enosys(); + default: + return einval(); + } +} + +static char g_fsgs_once; +static struct InterruptibleCall g_fsgs_icall; + +/** + * Don't bother. + */ +int arch_prctl(int code, int64_t addr) { + void *fn = arch_prctl$fsgsbase; + if (!g_fsgs_once) { + g_fsgs_once = true; + if (X86_HAVE(FSGSBASE)) { + g_fsgs_icall.sig = SIGILL; + if (interruptiblecall(&g_fsgs_icall, fn, code, addr, 0, 0) != -1 && + g_fsgs_icall.returnval != -1) { + /* ivybridge+ (2012) lets us change segment registers without + needing a 700ns system call. cpuid and /proc/cpuinfo will both + report it's available; unfortunately, operating systems have an + added ability to restrict this feature in %cr4, which we're not + even allowed to read lool */ + g_fsgs_once = 2; + return 0; + } + } + } + if (g_fsgs_once == 2) { + return arch_prctl$fsgsbase(code, addr); + } + switch (hostos) { + case METAL: + return arch_prctl$msr(code, addr); + case FREEBSD: + /* claims support but it appears not */ + return arch_prctl$freebsd(code, addr); + case OPENBSD: + return arch_prctl$openbsd(code, addr); + case LINUX: + return arch_prctl$sysv(code, addr); + case XNU: + /* probably won't work */ + return arch_prctl$xnu(code, addr); + default: + return enosys(); + } +} diff --git a/libc/runtime/asan.greg.c b/libc/runtime/asan.greg.c new file mode 100644 index 00000000..968cd9ca --- /dev/null +++ b/libc/runtime/asan.greg.c @@ -0,0 +1,75 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/fileno.h" + +privileged void __asan_init(void) { +} + +privileged void __asan_register_globals(uintptr_t a, uintptr_t b) { +} + +privileged void __asan_unregister_globals(uintptr_t a, uintptr_t b) { +} + +privileged void __asan_loadN(uintptr_t ptr, size_t size) { + dprintf(STDERR_FILENO, "load %p %zu"); +} + +privileged void __asan_storeN(uintptr_t ptr, size_t size) { + dprintf(STDERR_FILENO, "store %p %zu"); +} + +privileged void __asan_report_load_n(uintptr_t ptr, size_t size) { + dprintf(STDERR_FILENO, "%s%zu%s%#p", "asan: load ", size, " bytes at ", ptr); +} + +privileged void __asan_report_store_n(uintptr_t ptr, size_t size) { + dprintf(STDERR_FILENO, "%s%zu%s%#p", "asan: store ", size, " bytes at ", ptr); +} + +privileged uintptr_t __asan_stack_malloc(size_t size, int classid) { + return 0; +} + +privileged void __asan_stack_free(uintptr_t ptr, size_t size, int classid) { +} + +privileged void __asan_handle_no_return(void) { +} + +privileged void __asan_version_mismatch_check_v8(void) { +} + +privileged void __asan_alloca_poison(uintptr_t addr, uintptr_t size) { +} + +privileged void __asan_allocas_unpoison(uintptr_t top, uintptr_t bottom) { +} + +privileged void *__asan_addr_is_in_fake_stack(void *fakestack, void *addr, + void **beg, void **end) { + return NULL; +} + +privileged void *__asan_get_current_fake_stack(void) { + return NULL; +} diff --git a/libc/runtime/assertfail.c b/libc/runtime/assertfail.c new file mode 100644 index 00000000..f4643161 --- /dev/null +++ b/libc/runtime/assertfail.c @@ -0,0 +1,55 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/log/log.h" +#include "libc/macros.h" +#include "libc/mem/alloca.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/fileno.h" + +/** + * Handles failure of assert() macro. + */ +relegated void __assert_fail(const char *expr, const char *file, int line) { + static bool once; + char *msg, *p, linebuf[16]; + unsigned i, exprlen, filelen; + if (!once) { + once = true; + exprlen = expr ? strlen(expr) : 0; + filelen = file ? strlen(file) : 0; + p = msg = alloca(MIN(512, exprlen + filelen + 64)); + p = mempcpy(p, file, filelen); + p = stpcpy(p, ":"); + if (line < 1) line = 1; + for (i = 0; line; line /= 10) linebuf[i++] = '0' + line % 10; + while (i) *p++ = linebuf[--i]; + p = stpcpy(p, ":"); + p = mempcpy(p, expr, exprlen); + p = stpcpy(p, "\r\n"); + write(STDERR_FILENO, msg, p - msg); + if (weaken(die)) weaken(die)(); + } + abort(); + unreachable; +} diff --git a/libc/runtime/balloc.c b/libc/runtime/balloc.c new file mode 100644 index 00000000..377d73b0 --- /dev/null +++ b/libc/runtime/balloc.c @@ -0,0 +1,90 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/runtime/buffer.h" +#include "libc/runtime/mappings.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/prot.h" + +#define kGuard PAGESIZE +#define kGrain FRAMESIZE + +/** + * Allocates page-guarded buffer. + * + * ┌─────────────────────────────────────┬s─i─g─s─e─g─v┐ + * │ 𝑣₀..𝑣ₙ₋₁ │𝑣ₙ..𝑣ₙ₊₄₀₉₆₋₁│ + * └─────────────────────────────────────┴s─i─g─s─e─g─v┘ + * + * @param b is metadata object owned by caller, initialized to zero for + * first call; subsequent calls will resize + * @param a is alignment requirement in bytes, e.g. 1,2,4,8,16,... + * @param n is buffer size in bytes + * @return b->p + * @see ralloc() + */ +void *balloc(struct GuardedBuffer *b, unsigned a, size_t n) { + int rc; + char *p; + size_t mi, need; + struct AddrSize az; + struct MemoryCoord mc; + + assert(a >= 1); + assert(a <= kGuard); + assert(kGuard < kGrain); + assert(popcount(a) == 1); + assert(popcount(kGuard) == 1); + assert(popcount(kGrain) == 1); + assert(n < 0x800000000000ul - kGrain - kGuard); + + if (n) { + az.addr = 0; + az.size = 0; + n = roundup(n, a); + need = roundup(n + kGuard, kGrain); + if (b->p) { + mc = ADDRSIZE_TO_COORD(b->p, 1); + mi = findmapping(mc.y); + if (mi && ISOVERLAPPING(mc, _mm.p[mi - 1])) { + az = COORD_TO_ADDRSIZE(_mm.p[mi - 1]); + if (az.size < need) { + rc = munmap(az.addr, az.size); + assert(rc != -1); + az.addr = NULL; + az.size = 0; + } + } + } + if (!az.size) { + if ((p = mapanon(need)) == MAP_FAILED) abort(); + if (mprotect(p + need - kGuard, kGuard, PROT_NONE) == -1) abort(); + } else { + p = az.addr; + } + b->p = p + need - kGuard - n; + } + + return b->p; +} diff --git a/libc/runtime/bfree.c b/libc/runtime/bfree.c new file mode 100644 index 00000000..9913494d --- /dev/null +++ b/libc/runtime/bfree.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/calls.h" +#include "libc/runtime/buffer.h" +#include "libc/runtime/mappings.h" + +void bfree(struct GuardedBuffer *b) { + int mr; + size_t mi; + struct AddrSize az; + struct MemoryCoord mc; + if (b->p) { + mc = ADDRSIZE_TO_COORD(b->p, 1); + mi = findmapping(mc.y); + assert(mi > 0); + assert(ISOVERLAPPING(mc, _mm.p[mi - 1])); + az = COORD_TO_ADDRSIZE(_mm.p[mi - 1]); + mr = munmap(az.addr, az.size); + assert(mr != -1); + b->p = NULL; + } +} diff --git a/libc/runtime/buffer.h b/libc/runtime/buffer.h new file mode 100644 index 00000000..c81dde25 --- /dev/null +++ b/libc/runtime/buffer.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_RUNTIME_BUFFER_H_ +#define COSMOPOLITAN_LIBC_RUNTIME_BUFFER_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct GuardedBuffer { + void *p; +}; + +void *balloc(struct GuardedBuffer *, unsigned, size_t); +void bfree(struct GuardedBuffer *); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_RUNTIME_BUFFER_H_ */ diff --git a/libc/runtime/clearenv.c b/libc/runtime/clearenv.c new file mode 100644 index 00000000..5cdc0674 --- /dev/null +++ b/libc/runtime/clearenv.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/runtime.h" + +/** + * Removes all environment variables. + */ +int clearenv(void) { + environ = NULL; + return 0; +} diff --git a/libc/runtime/close_s.c b/libc/runtime/close_s.c new file mode 100644 index 00000000..021e5a66 --- /dev/null +++ b/libc/runtime/close_s.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/runtime/mappings.h" +#include "libc/runtime/runtime.h" + +/** + * Closes file descriptor. + * + * The caller's variable is made -1. Note that close(-1) is a no-op. + * + * @return 0 on success, or -1 w/ errno + * @asyncsignalsafe + */ +int close_s(int *fdp) { + int fd = -1; + return close(lockxchg(fdp, &fd)); +} diff --git a/libc/runtime/closesymboltable.c b/libc/runtime/closesymboltable.c new file mode 100644 index 00000000..74e55179 --- /dev/null +++ b/libc/runtime/closesymboltable.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/ezmap.h" +#include "libc/runtime/symbols.h" +#include "libc/calls/calls.h" + +/** + * Frees symbol table. + * @return 0 on success or -1 on system error + */ +int closesymboltable(struct SymbolTable **table) { + int rc = 0; + if (*table && (intptr_t)*table != (intptr_t)-1) { + struct SymbolTable *t = *table; + *table = NULL; + if (unmapfile(&t->mf) == -1) rc = -1; + if (munmap(t, t->scratch) == -1) rc = -1; + } + return rc; +} diff --git a/libc/runtime/cxaatexit.S b/libc/runtime/cxaatexit.S new file mode 100644 index 00000000..d2108fd3 --- /dev/null +++ b/libc/runtime/cxaatexit.S @@ -0,0 +1,181 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/relocations.h" +#include "libc/macros.h" +.section .text.exit,"ax",@progbits +.yoink __FILE__ + +/ Delegates to __cxa_atexit(). +/ +/ @param rdi callback typed void(*)(void) (nullable) +/ @return 0 on success or nonzero if out of space +atexit: xor %esi,%esi + xor %edx,%edx +/ 𝑠𝑙𝑖𝑑𝑒 + +/ Registers destructor to be called upon exit(). +/ +/ Destructors are called in reverse order. They won't be called +/ if the program aborts or _exit() is called. Invocations of this +/ function are usually generated by the C++ compiler. +/ +/ @param rdi callback typed void(*)(T) (nullable) +/ @param rsi callback arg typed T (nullable) +/ @param rdx dso handle (nullable) +/ @return 0 on success or nonzero if out of space +/ @note folks have forked libc in past just to unbloat atexit() +/ @see news.ycombinator.com/item?id=20228082 +/ @preinitsafe +__cxa_atexit: + push %rbp + mov %rsp,%rbp + .profilable + push %r15 + ezlea g_cxa,cx + mov %rcx,%r15 + mov (%r15),%rax # get state->block + mov 8(%r15),%rcx # get state->offset + test %rcx,%rcx + jz 2f +0: sub $24,%rcx + mov %rdx,(%rax,%rcx) # set cb->dso + mov %rsi,8(%rax,%rcx) # set cb->arg + mov %rdi,16(%rax,%rcx) # set cb->fn + mov %rcx,8(%r15) # set state->offset + xor %eax,%eax # success +1: pop %r15 + pop %rbp + ret +2: .weak calloc + ezlea calloc,cx + test %rcx,%rcx + jz 1b # fail (no malloc) + push %rax + push %rdi + push %rsi + pushpop ATEXIT_MAX+1,%rdi + pushpop 16,%rsi + call *%rcx + pop %rsi + pop %rdi + pop %rcx # rax=new rcx=old + test %rax,%rax + jz 1b # fail (no memory) + mov $ATEXIT_MAX*8*3,%r8 + mov %rax,(%r15) # set state->block + mov %rcx,(%rax,%r8) # set block->next + mov %r8,%rcx + jmp 0b + .endfn __cxa_atexit,globl + .endfn atexit,globl + +/ Triggers destructors. +/ +/ This implementation supports DSO handles, but is optimized for +/ cases when it's called only once by exit(). +/ +/ @param rdi is dso predicate or null to destroy all +/ @see libc/exit.c +__cxa_finalize: + push %rbp + mov %rsp,%rbp + .profilable + push %r14 + push %r13 + push %r12 + mov g_cxa(%rip),%rsi + mov %rdi,%r14 +0: mov %rsi,%r12 # loop through blocks + pushpop ATEXIT_MAX,%rcx +1: lodsq #→ dso # loop through callbacks + xchg %rax,%rdx + lodsq #→ arg + xchg %rax,%rdi + lodsq #→ fn + test %rax,%rax + jz 2f # ignore empty slots + test %r14,%r14 + jmp 5f # null predicate match all + cmp %r14,%rdx + jne 2f # predicate mismatch +5: push %rsi + push %rcx + push %rcx + call *%rax + pop %rcx + pop %rcx + pop %rsi + xor %eax,%eax # clear slot (never reused) + mov %rax,-8(%rsi) +2: loop 1b + lodsq # get next block ptr + test %rax,%rax # don't free static block no. 1 + jz 3f # which always has next == NULL + test %r14,%r14 + jz 1f # don't free anything if just one dso + push %rax + mov %r12,%rdi + .weak free + call free # can't panic due to earlier test +1: pop %rsi + jmp 0b +3: pop %r12 # align stack for next call + test %r14,%r14 # no static dtor for dso exit + jnz 9f + ezlea __fini_array_end,ax # static dtors in reverse order + .weak __fini_array_end # could be called multiple times + ezlea __fini_array_start,cx # idempotency recommended + .weak __fini_array_start # or consider atexit() +8: sub $8,%rax # @see ape/ape.lds + cmp %rcx,%rax + jl 9f + push %rax + push %rcx + call *(%rax) + pop %rcx + pop %rax + jmp 8b +9: pop %r13 + pop %r14 + pop %rbp + ret + .endfn __cxa_finalize,globl,hidden + + .bss + .align 16 # static/dynamic hybrid linked list +g_cxa: .quad 0 # last block ptr: (long (*)[32][3]) + .quad 0 # block byte offset moves backwards + .endobj g_cxa +g_cxa_static: + .rept ATEXIT_MAX + .quad 0 # dso + .quad 0 # arg + .quad 0 # fn (or NULL for empty) + .endr + .quad 0 # next (always NULL in static block) + .endobj g_cxa_static + .previous + + .init.start 300,_init_g_cxa + ezlea g_cxa,cx + lea g_cxa_static-g_cxa(%rcx),%rax + mov %rax,(%rcx) + movl $ATEXIT_MAX*8*3,8(%rcx) + .init.end 300,_init_g_cxa diff --git a/libc/runtime/defer.greg.c b/libc/runtime/defer.greg.c new file mode 100644 index 00000000..6128971d --- /dev/null +++ b/libc/runtime/defer.greg.c @@ -0,0 +1,63 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/arraylist.h" +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/mem/mem.h" +#include "libc/nexgen32e/gc.h" +#include "libc/runtime/gc.h" +#include "libc/runtime/runtime.h" + +forceinline bool PointerNotOwnedByParentStackFrame(struct StackFrame *frame, + struct StackFrame *parent, + void *ptr) { + return !(((intptr_t)ptr > (intptr_t)frame) && + ((intptr_t)ptr < (intptr_t)parent)); +} + +/** + * Adds destructor to garbage shadow stack. + * + * @param frame is passed automatically by wrapper macro + * @param fn takes one argument + * @param arg is passed to fn(arg) + * @return arg + */ +void __defer(struct StackFrame *frame, void *fn, void *arg) { + struct StackFrame *frame2; + /* + * To avoid an API requiring dlmalloc dependency, say: + * defer(free_s, &ptr_not_owned_by_current_frame) + * Rather than: + * defer(weak(free), ptr) + */ + if (!arg) return; + frame2 = __builtin_frame_address(0); + assert(frame2->next == frame); + assert(PointerNotOwnedByParentStackFrame(frame2, frame, arg)); + if (append(&__garbage, + (&(const struct Garbage){frame->next, (intptr_t)fn, (intptr_t)arg, + frame->addr})) != -1) { + atomic_store(&frame->addr, (intptr_t)&__gc); + } else { + abort(); + } +} diff --git a/libc/runtime/describeos.c b/libc/runtime/describeos.c new file mode 100644 index 00000000..e485a563 --- /dev/null +++ b/libc/runtime/describeos.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" + +char *describeos(char *buf, size_t size) { + const char *s; + if (IsLinux()) { + s = "gnu/systemd"; + } else if (IsXnu()) { + s = "xnu's not unix"; + } else if (IsFreebsd()) { + s = "freebesiyatadishmaya"; + } else if (IsOpenbsd()) { + s = "openbsd"; + } else if (IsWindows()) { + s = "the new technology"; + } else { + s = "wut"; + } + return memccpy(buf, s, '\0', size); +} diff --git a/libc/runtime/dsohandle.S b/libc/runtime/dsohandle.S new file mode 100644 index 00000000..0f8394c7 --- /dev/null +++ b/libc/runtime/dsohandle.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +#include "libc/notice.inc" +.yoink __FILE__ + +/ Uniquely identifies each artifact linked in an address space. +__dso_handle: + .quad __dso_handle + .endobj __dso_handle,globl,hidden diff --git a/libc/runtime/enableavx.greg.c b/libc/runtime/enableavx.greg.c new file mode 100644 index 00000000..528b18de --- /dev/null +++ b/libc/runtime/enableavx.greg.c @@ -0,0 +1,71 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" +#include "libc/dce.h" +#include "libc/nexgen32e/nexgen32e.h" +#include "libc/nt/struct/context.h" +#include "libc/nt/thunk/msabi.h" + +#define kNtContextXstate 0x00100040 +#define kNtXstateAvx 2 +#define kNtXstateMaskAvx (1ull << kNtXstateAvx) + +static void EnableAvx(void) { + asm volatile("mov\t%%cr4,%%rax\n\t" + "or\t%0,%%rax\n\t" + "mov\t%%rax,%%cr4\n\t" + "xor\t%%ecx,%%ecx\n\t" + "xgetbv\n\t" + "or\t%1,%%eax\n\t" + "xsetbv" + : /* no outputs */ + : "i"(CR4_OSXSAVE), "i"(XCR0_X87 | XCR0_SSE | XCR0_AVX) + : "rax", "rcx", "rdx", "memory", "cc"); +} + +static void EnableAvxOnWindows(void) { + /* typedef uint64_t (*getenabledxstatefeatures_f)(void) __msabi; */ + /* typedef bool32 (*initializecontext_f)(void *buffer, uint32_t flags, */ + /* struct NtContext **out_context, */ + /* uint32_t *inout_buffersize) __msabi; + */ + /* typedef bool32 (*getxstatefeaturesmask_f)(struct NtContext * context, */ + /* uint64_t * out_featuremask) + * __msabi; */ + /* typedef bool32 (*setxstatefeaturesmask_f)(struct NtContext * context, */ + /* uint64_t featuremask) __msabi; */ + /* getenabledxstatefeatures_f GetEnabledXStateFeatures; */ + /* initializecontext_f InitializeContext; */ + /* getxstatefeaturesmask_f GetXStateFeaturesMask; */ + /* setxstatefeaturesmask_f SetXStateFeaturesMask; */ +} + +/** + * Requests authorization from operating system to do 256-bit math. + * @assume avx cpuid check performed by caller + */ +int _init_enableavx(void) { + if (IsMetal()) { + EnableAvx(); + } else if (IsWindows()) { + EnableAvxOnWindows(); + } + return 0; +} diff --git a/libc/runtime/exit.c b/libc/runtime/exit.c new file mode 100644 index 00000000..083cb574 --- /dev/null +++ b/libc/runtime/exit.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/internal.h" +#include "libc/runtime/runtime.h" + +/** + * Exits program with grace. + */ +noreturn textexit void exit(int rc) { + __cxa_finalize(NULL); + _exit(rc); + unreachable; +} diff --git a/libc/runtime/ezmap.c b/libc/runtime/ezmap.c new file mode 100644 index 00000000..2ea74b29 --- /dev/null +++ b/libc/runtime/ezmap.c @@ -0,0 +1,58 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/limits.h" +#include "libc/runtime/ezmap.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/prot.h" + +/** + * Memory-maps file for reading. + * An internal veneer for a common mmap() use-case. + */ +int mapfileread(const char *filename, struct MappedFile *mf) { + mf->addr = MAP_FAILED; + if ((mf->fd = open(filename, O_RDONLY)) != -1 && + (mf->size = getfiledescriptorsize(mf->fd)) < INT_MAX && + (mf->addr = mf->size + ? mmap(NULL, mf->size, PROT_READ, MAP_SHARED, mf->fd, 0) + : NULL) != MAP_FAILED) { + return 0; + } else { + unmapfile(mf); + return -1; + } +} + +/** + * Releases resource returned by mapfileread(). + */ +int unmapfile(struct MappedFile *mf) { + int rc = 0; + rc |= munmap(mf->addr, mf->size); + rc |= close(mf->fd); + mf->fd = -1; + mf->addr = MAP_FAILED; + mf->size = 0; + return rc; +} diff --git a/libc/runtime/ezmap.h b/libc/runtime/ezmap.h new file mode 100644 index 00000000..9db11de4 --- /dev/null +++ b/libc/runtime/ezmap.h @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#ifndef COSMOPOLITAN_LIBC_EZMAP_H_ +#define COSMOPOLITAN_LIBC_EZMAP_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct MappedFile { + int64_t fd; + void *addr; + size_t size; +}; + +int mapfileread(const char *filename, struct MappedFile *mf) hidden; +int unmapfile(struct MappedFile *mf) hidden; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_EZMAP_H_ */ diff --git a/libc/runtime/fastmath.S b/libc/runtime/fastmath.S new file mode 100644 index 00000000..7809d228 --- /dev/null +++ b/libc/runtime/fastmath.S @@ -0,0 +1,46 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +#include "libc/notice.inc" +.text.startup +.yoink __FILE__ + +/ Intel Manual V.1 §10.2.3 - MXCSR Control and Status Register +#define MXCSR_DE (1 << 1) /* Denormal Flag */ +#define MXCSR_DAZ (1 << 6) /* Denormals Are Zeros */ +#define MXCSR_DM (1 << 8) /* Denormal Operation Mask */ +#define MXCSR_FTZ (1 << 15) /* Flush to Zero */ + +/ Initializes fast math. +/ +/ “Seymour Cray didn't care that 81.0/3.0 did not give exactly +/ 27.0 on the CDC 6000 class machines, and he was universally +/ respected for making the fastest machines around. +/ ──Linus Torvalds +__fast_math: + push %rbp + mov %rsp,%rbp + push %rax + stmxcsr (%rsp) + orl $MXCSR_FTZ+MXCSR_DAZ,(%rsp) + ldmxcsr (%rsp) + leave + ret + .endfn __fast_math,globl diff --git a/libc/runtime/findcombinary.c b/libc/runtime/findcombinary.c new file mode 100644 index 00000000..e62f56b0 --- /dev/null +++ b/libc/runtime/findcombinary.c @@ -0,0 +1,52 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/auxv.h" + +struct FindComBinary { + bool once; + const char *res; + char buf[PATH_MAX]; +}; + +static struct FindComBinary findcombinary_; + +/** + * Returns path of binary without debug information, or null. + * + * @return path to non-debug binary, or -1 w/ errno + */ +const char *findcombinary(void) { + size_t len; + const char *p; + if (!findcombinary_.once) { + findcombinary_.once = true; + if ((p = (const char *)getauxval(AT_EXECFN)) && + (len = strlen(p)) < ARRAYLEN(findcombinary_.buf)) { + findcombinary_.res = memcpy(findcombinary_.buf, p, len + 1); + if (len > 4 && memcmp(&findcombinary_.buf[len - 4], ".dbg", 4) == 0) { + findcombinary_.buf[len - 4] = '\0'; + } + } + } + return findcombinary_.res; +} diff --git a/libc/runtime/finddebugbinary.c b/libc/runtime/finddebugbinary.c new file mode 100644 index 00000000..f3a9a909 --- /dev/null +++ b/libc/runtime/finddebugbinary.c @@ -0,0 +1,52 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/errno.h" +#include "libc/macros.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/symbols.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/auxv.h" + +/** + * Returns path of binary with the debug information, or null. + * + * @return path to debug binary, or -1 w/ errno + */ +const char *finddebugbinary(void) { + static char buf[PATH_MAX]; + if (buf[0]) return &buf[0]; + const char *const trybins[] = {program_invocation_name, + (const char *)getauxval(AT_EXECFN)}; + for (unsigned i = 0; i < ARRAYLEN(trybins); ++i) { + const char *res = trybins[i]; + unsigned len = strlen(res); + if (4 < len && len < sizeof(buf) - 5) { + if (strcmp(res + len - 4, ".dbg") == 0) return res; + /* try suffixing extension, e.g. .com → .com.dbg */ + memcpy(mempcpy(buf, res, len), ".dbg", 5); + if (fileexists(buf)) return &buf[0]; + buf[0] = '\0'; + } + } + errno = ENOENT; + return NULL; +} diff --git a/libc/runtime/findmapping.c b/libc/runtime/findmapping.c new file mode 100644 index 00000000..cd4ba45b --- /dev/null +++ b/libc/runtime/findmapping.c @@ -0,0 +1,49 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/mappings.h" + +size_t findmapping_(int32_t k, const struct MemoryCoord *coords, size_t count) { + size_t l, r, m; + l = 0; + r = count; + while (l < r) { + m = (l + r) >> 1; + if (coords[m].x > k) { + r = m; + } else { + l = m + 1; + } + } + return l; +} + +/** + * Returns appropriate rightmost index. + */ +size_t findmapping(int32_t k) { + return findmapping_(k, _mm.p, _mm.i); +} + +/** + * Returns appropriate rightmost index. + */ +size_t pickmapping(int32_t k) { + return findmapping_(k, _mm.p, _mm.i); +} diff --git a/libc/runtime/fpreset.S b/libc/runtime/fpreset.S new file mode 100644 index 00000000..7b7c8f45 --- /dev/null +++ b/libc/runtime/fpreset.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Re-initializes FPU. +fpreset: +_fpreset: + .leafprologue + .profilable + finit + .leafepilogue + .endfn _fpreset,globl + .endfn fpreset,globl diff --git a/libc/runtime/free_s.c b/libc/runtime/free_s.c new file mode 100644 index 00000000..5562e438 --- /dev/null +++ b/libc/runtime/free_s.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/mem/mem.h" +#include "libc/runtime/mappings.h" +#include "libc/runtime/runtime.h" + +/** + * Frees memory, the Cosmopolitan way. + * + * The caller's pointer is zeroed. Stack and static memory is ignored. + * This doesn't require a dependency on malloc(). + */ +void free_s(void *v) { + void **pp = (void **)v; + void *p = NULL; + lockxchg(pp, &p); + if (isheap(p)) weakfree(p); +} diff --git a/libc/runtime/ftrace.greg.c b/libc/runtime/ftrace.greg.c new file mode 100644 index 00000000..5907e9f1 --- /dev/null +++ b/libc/runtime/ftrace.greg.c @@ -0,0 +1,213 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/bisectcarleft.h" +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/sigset.h" +#include "libc/dce.h" +#include "libc/macros.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" +#include "libc/nt/thunk/msabi.h" +#include "libc/runtime/internal.h" +#include "libc/runtime/missioncritical.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/symbols.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/nr.h" +#include "libc/sysv/consts/prot.h" +#include "libc/sysv/consts/sig.h" + +/** + * @fileoverview Plain-text function call logging. + * + * Able to log ~2 million function calls per second, which is mostly + * bottlenecked by system call overhead. Log size is reasonable if piped + * into gzip. + */ + +static char g_buf[512]; +static const char *g_lastsymbol; +static struct SymbolTable *g_symbols; + +forceinline int getnestinglevel(struct StackFrame *frame) { + int nesting = -2; + while (frame) { + ++nesting; + frame = frame->next; + } + return max(0, nesting); +} + +/** + * Prints name of function being called. + * + * We insert CALL instructions that point to this function, in the + * prologues of other functions. We assume those functions behave + * according to the System Five NexGen32e ABI. + */ +privileged interruptfn void ftrace_hook(void) { + size_t i, j, nesting; + const char *symbol; + struct StackFrame *frame; + LOAD_DEFAULT_RBX(); + if (g_symbols && !(g_runstate & RUNSTATE_BROKEN)) { + frame = __builtin_frame_address(0); + symbol = + &g_symbols->name_base[g_symbols + ->symbols[bisectcarleft( + (const int32_t(*)[2])g_symbols->symbols, + g_symbols->count, + frame->addr - g_symbols->addr_base)] + .name_rva]; + if (symbol != g_lastsymbol && + (nesting = getnestinglevel(frame)) * 2 < ARRAYLEN(g_buf) - 3) { + i = 2; + j = 0; + while (nesting--) { + g_buf[i++] = ' '; + g_buf[i++] = ' '; + } + while (i < ARRAYLEN(g_buf) - 2 && symbol[j]) { + g_buf[i++] = symbol[j++]; + } + g_buf[i++] = '\n'; + __print(g_buf, i); + } + g_lastsymbol = symbol; + } + RESTORE_RBX(); +} + +/** + * Rewrites code in memory to log function calls. + * + * We do this by searching each function for the nop instruction + * inserted by GCC when we use the -pg -mnop-mcount flags. There's no + * risk of corrupting data since the linker scripts won't mix code and + * data. + * + * Modules built with -O3 and without the profiling flags might have + * these same nop instructions, but that shouldn't be problematic since + * they're only there for the puposes of aligning jumps, and therefore + * aren't actually executed. However codebases that use huge function + * alignments with wide-nop slides could pose minor issues. Further note + * that Cosmopolitan sources are almost never intentionally written to + * use code alignment, since we've only seen a few cases where it helps. + * + * @see ape/ape.lds + */ +privileged void ftrace_install(void) { + /* TODO(jart): Is -fschedule-insns2 so aggro that we need XED here? */ + size_t i; + intptr_t addr; + sigset_t oldmask; + uint64_t code, mcode; + unsigned char *p, *pe; + const intptr_t kMcount = (intptr_t)&mcount; + const intptr_t kFtraceHook = (intptr_t)&ftrace_hook; + const intptr_t kProgramCodeStart = (intptr_t)&_ereal; + const intptr_t kPrivilegedStart = (intptr_t)&__privileged_start; + const bool kIsBinaryAligned = !(kPrivilegedStart & (PAGESIZE - 1)); + g_buf[0] = '+'; + g_buf[1] = ' '; + sigprocmask(SIG_BLOCK, &kSigsetFull, &oldmask); + if (__mprotect((void *)g_symbols->addr_base, + kPrivilegedStart - g_symbols->addr_base, + kIsBinaryAligned ? PROT_READ | PROT_WRITE + : PROT_READ | PROT_WRITE | PROT_EXEC) != -1) { + for (i = 0; i < g_symbols->count - 1; ++i) { + if (g_symbols->addr_base + g_symbols->symbols[i].addr_rva < + kProgramCodeStart) { + continue; /* skip over real mode symbols */ + } + if (g_symbols->addr_base + g_symbols->symbols[i].addr_rva >= + kPrivilegedStart) { + break; /* stop before privileged symbols */ + } + for (p = (unsigned char *)(g_symbols->addr_base + + g_symbols->symbols[i].addr_rva), + pe = (unsigned char *)(g_symbols->addr_base + + g_symbols->symbols[i + 1].addr_rva); + p < pe - 8; ++p) { + code = read64le(p); + + /* + * Test for -mrecord-mcount (w/ -fpie or -fpic) + * + * nopw 0x00(%rax,%rax,1) ← morphed by package.com + * call *mcount(%rip) ← linked w/o -static + * addr32 call mcount ← relaxed w/ -static + * addr32 call mcount ← relaxed w/ -static + * + * Note that gcc refuses to insert the six byte nop. + */ + if ((code & 0x0000FFFFFFFFFFFF) == 0x0000441F0F66 || + (code & 0x0000FFFFFFFFFFFF) == + ((((kMcount - ((intptr_t)&p[2] + 4)) << 16) | 0xE867) & + 0x0000FFFFFFFFFFFF) || + (code & 0x0000FFFFFFFFFFFF) == + ((((kMcount - ((intptr_t)&p[2] + 4)) << 16) | 0xFF15) & + 0x0000FFFFFFFFFFFF)) { + p[0] = 0x67; + p[1] = 0xE8; + addr = kFtraceHook - ((intptr_t)&p[2] + 4); + p[2] = addr >> 000; + p[3] = addr >> 010; + p[4] = addr >> 020; + p[5] = addr >> 030; + break; + } + + /* + * Test for -mnop-mcount (w/ -fno-pie) + */ + mcode = code & 0x000000FFFFFFFFFF; + if ((mcode == 0x00441F0F /* nopl 0x00(%eax,%eax,1) [canonical] */) || + (mcode == 0x00041F0F67 /* nopl (%eax,%eax,1) [older gcc] */)) { + if (p[-1] != 0x66 /* nopw 0x0(%rax,%rax,1) [donotwant] */) { + p[0] = 0xE8 /* call Jvds */; + addr = kFtraceHook - ((intptr_t)&p[1] + 4); + p[1] = addr >> 000; + p[2] = addr >> 010; + p[3] = addr >> 020; + p[4] = addr >> 030; + } + break; + } + } + } + __mprotect((void *)g_symbols->addr_base, + kPrivilegedStart - g_symbols->addr_base, PROT_READ | PROT_EXEC); + } + sigprocmask(SIG_SETMASK, &oldmask, NULL); +} + +/** + * Installs plaintext function tracer. Do not call. + * @see libc/runtime/_init.S for documentation + */ +textstartup void ftrace_init(void) { + if ((g_symbols = opensymboltable(finddebugbinary()))) { + ftrace_install(); + } +} diff --git a/libc/runtime/g_argc.S b/libc/runtime/g_argc.S new file mode 100644 index 00000000..924da7be --- /dev/null +++ b/libc/runtime/g_argc.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + + .initbss 300,_init_g_argc +g_argc: .quad 0 + .endobj g_argc,globl,hidden + .previous + + .init.start 300,_init_g_argc + mov %r12,%rax + stosq + .init.end 300,_init_g_argc diff --git a/libc/runtime/gc.h b/libc/runtime/gc.h new file mode 100644 index 00000000..e054d587 --- /dev/null +++ b/libc/runtime/gc.h @@ -0,0 +1,48 @@ +#ifndef COSMOPOLITAN_LIBC_RUNTIME_GC_H_ +#define COSMOPOLITAN_LIBC_RUNTIME_GC_H_ +#include "libc/calls/calls.h" +#include "libc/runtime/runtime.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * @fileoverview Cosmopolitan Return-Oriented Garbage Collector. + * + * This is the same thing as {@code std::unique_ptr<>} in C++ or the + * {@code defer} keyword in Go. We harness the power of ROP for good + * using very few lines of code. + */ + +struct StackFrame; + +/** + * Releases resource when function returns. + * + * @warning do not return a gc()'d pointer + * @warning do not realloc() with gc()'d pointer + */ +#define gc(THING) defer(weakfree, (THING)) + +/** + * Same as longjmp() but runs gc() / defer() destructors. + */ +void gclongjmp(jmp_buf, int) nothrow noreturn paramsnonnull(); + +/** + * Calls FN(ARG) when function returns. + */ +#define defer(FN, ARG) \ + ({ \ + autotype(ARG) Arg = (ARG); \ + /* prevent weird opts like tail call */ \ + asm volatile("" : "+g"(Arg) : : "memory"); \ + __defer(__builtin_frame_address(0), FN, Arg); \ + asm volatile("" : "+g"(Arg) : : "memory"); \ + Arg; \ + }) + +void __defer(struct StackFrame *, void *, void *) hidden paramsnonnull((1, 2)); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_RUNTIME_GC_H_ */ diff --git a/libc/runtime/getdosargv.c b/libc/runtime/getdosargv.c new file mode 100644 index 00000000..c4983400 --- /dev/null +++ b/libc/runtime/getdosargv.c @@ -0,0 +1,115 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/pushpop.h" +#include "libc/bits/safemacros.h" +#include "libc/runtime/internal.h" +#include "libc/str/appendchar.h" +#include "libc/str/str.h" + +/* TODO(jart): Make early-stage data structures happen. */ +#undef isspace +#undef iswspace +#define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r') +#define iswspace(c) isspace(c) + +struct DosArgv { + const char16_t *s; + char *p; + char *pe; + wint_t wc; +}; + +static textwindows void decodedosargv(struct DosArgv *st) { + st->s += getutf16(st->s, &st->wc); +} + +static textwindows void appenddosargv(struct DosArgv *st, wint_t wc) { + if (st->p < st->pe) { + st->p += tpencode(st->p, st->pe - st->p, wc, false); + } +} + +/** + * Tokenizes and transcodes Windows NT CLI args, thus avoiding + * CommandLineToArgv() schlepping in forty megs of dependencies. + * + * @param s is the command line string provided by the executive + * @param buf is where we'll store double-NUL-terminated decoded args + * @param size is how many bytes are available in buf + * @param argv is where we'll store the decoded arg pointer array, which + * is guaranteed to be NULL-terminated if max>0 + * @param max specifies the item capacity of argv, or 0 to do scanning + * @return number of args written, excluding the NULL-terminator; or, + * if the output buffer wasn't passed, or was too short, then the + * number of args that *would* have been written is returned; and + * there are currently no failure conditions that would have this + * return -1 since it doesn't do system calls + * @see test/libc/dosarg_test.c + * @see libc/runtime/ntspawn.c + * @note kudos to Simon Tatham for figuring out quoting behavior + */ +textwindows int getdosargv(const char16_t *cmdline, char *buf, size_t size, + char **argv, size_t max) { + bool inquote; + size_t i, argc, slashes, quotes; + struct DosArgv st; + st.s = cmdline; + st.p = buf; + st.pe = buf + size; + argc = 0; + decodedosargv(&st); + while (st.wc) { + while (st.wc && iswspace(st.wc)) decodedosargv(&st); + if (!st.wc) break; + if (++argc < max) { + argv[argc - 1] = st.p < st.pe ? st.p : NULL; + } + inquote = false; + while (st.wc) { + if (!inquote && isspace(st.wc)) break; + if (st.wc == '"' || st.wc == '\\') { + slashes = 0; + quotes = 0; + while (st.wc == '\\') decodedosargv(&st), slashes++; + while (st.wc == '"') decodedosargv(&st), quotes++; + if (!quotes) { + while (slashes--) appenddosargv(&st, '\\'); + } else { + while (slashes >= 2) appenddosargv(&st, '\\'), slashes -= 2; + if (slashes) appenddosargv(&st, '"'), quotes--; + if (quotes > 0) { + if (!inquote) quotes--; + for (i = 3; i <= quotes + 1; i += 3) appenddosargv(&st, '"'); + inquote = (quotes % 3 == 0); + } + } + } else { + appenddosargv(&st, st.wc); + decodedosargv(&st); + } + } + appenddosargv(&st, '\0'); + } + appenddosargv(&st, '\0'); + if (size) buf[min(st.p - buf, size - 1)] = '\0'; + if (max) argv[min(argc, max - 1)] = NULL; + return argc; +} diff --git a/libc/runtime/getdosenviron.h b/libc/runtime/getdosenviron.h new file mode 100644 index 00000000..ea5d1c6b --- /dev/null +++ b/libc/runtime/getdosenviron.h @@ -0,0 +1,67 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#ifndef COSMOPOLITAN_LIBC_DOSENVIRON_H_ +#define COSMOPOLITAN_LIBC_DOSENVIRON_H_ +#include "libc/bits/safemacros.h" +#include "libc/str/appendchar.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * Transcodes NT environment variable block from UTF-16 to UTF-8. + * + * @param env is a double NUL-terminated block of key=values + * @param buf is the new environment + * @param size is the byte capacity of buf + * @param envp stores NULL-terminated string pointer list + * @param max is the pointer count capacity of envp + * @return number of variables decoded, excluding NULL-terminator + */ +static inline int getdosenviron(const char16_t *env, char *buf, size_t size, + char **envp, size_t max) { + const char16_t *s = env; + size_t envc = 0; + if (size) { + wint_t wc; + char *p = buf; + char *pe = buf + size - 1; + if (p < pe) { + s += getutf16(s, &wc); + while (wc) { + if (++envc < max) { + envp[envc - 1] = p < pe ? p : NULL; + } + bool endstring; + do { + AppendChar(&p, pe, wc); + endstring = !wc; + s += getutf16(s, &wc); + } while (!endstring); + buf[min(p - buf, size - 2)] = u'\0'; + } + } + AppendChar(&p, pe, '\0'); + buf[min(p - buf, size - 1)] = u'\0'; + } + if (max) envp[min(envc, max - 1)] = NULL; + return envc; +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_DOSENVIRON_H_ */ diff --git a/libc/runtime/getpagesize.S b/libc/runtime/getpagesize.S new file mode 100644 index 00000000..f7c801f7 --- /dev/null +++ b/libc/runtime/getpagesize.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns granularity of memory manager. +getpagesize: + .leafprologue + .profilable + mov $FRAMESIZE,%eax + .leafepilogue + .endfn getpagesize,globl diff --git a/libc/runtime/gothere.greg.c b/libc/runtime/gothere.greg.c new file mode 100644 index 00000000..c591b968 --- /dev/null +++ b/libc/runtime/gothere.greg.c @@ -0,0 +1,54 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/itoa.h" +#include "libc/runtime/missioncritical.h" + +/** + * Debugs super low-level stuff, e.g. + * + * void GOT_HERE(int); + * INITIALIZER(100, _init_got_here_100, GOT_HERE(100)); + * INITIALIZER(200, _init_got_here_200, GOT_HERE(200)); + * INITIALIZER(300, _init_got_here_300, GOT_HERE(300)); + * INITIALIZER(400, _init_got_here_400, GOT_HERE(400)); + * INITIALIZER(500, _init_got_here_500, GOT_HERE(500)); + * INITIALIZER(600, _init_got_here_600, GOT_HERE(600)); + * INITIALIZER(700, _init_got_here_700, GOT_HERE(700)); + * INITIALIZER(800, _init_got_here_800, GOT_HERE(800)); + * + */ +privileged interruptfn void GOT_HERE(long num) { + size_t len; + char msg[48]; + len = 0; + msg[len++] = 'g'; + msg[len++] = 'o'; + msg[len++] = 't'; + msg[len++] = ' '; + msg[len++] = 'h'; + msg[len++] = 'e'; + msg[len++] = 'r'; + msg[len++] = 'e'; + msg[len++] = ' '; + len += int64toarray_radix10(num, &msg[len]); + msg[len++] = '\n'; + msg[len] = '\0'; + __print(msg, len); +} diff --git a/libc/runtime/grow.c b/libc/runtime/grow.c new file mode 100644 index 00000000..85c88302 --- /dev/null +++ b/libc/runtime/grow.c @@ -0,0 +1,88 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/conv/conv.h" +#include "libc/conv/sizemultiply.h" +#include "libc/macros.h" +#include "libc/mem/mem.h" +#include "libc/runtime/mappings.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +#define GUARANTEE_TERMINATOR 1 +#define INITIAL_CAPACITY (32 - GUARANTEE_TERMINATOR) + +/** + * Grows array, The Cosmopolitan Way. + * + * This function may be called once an array has run out of space. If p + * is NULL, a new array is allocated; otherwise, the array's made 1.5x + * bigger. It has been written that this amortizes list appends down to + * constant-time. Extended memory is zeroed. Growth is monotonic. + * + * If p points to to static memory or something on the stack, it'll be + * converted to dynamic memory automatically. This can make algorithms + * faster when the average case is a small amount of data. It also means + * functions using this (and free_s()) won't have a hard-requirement on + * malloc(). + * + * Consider trying the higher-level append() and concat() APIs (defined + * in libc/alg/arraylist.h) as an alternative to directly using grow(). + * + * @param pp points to pointer holding memory address + * @param capacity tracks maximum items that can be stored in p + * can only be 0 if p is NULL (see reallocarray() for non-monotonic) + * @param itemsize is the sizeof each item + * @return true on success, or false w/ errno and *p is NOT free()'d + * @error ENOMEM if realloc() not linked or mmap() failed + * @note tiny programs might need to explicitly YOINK(realloc) + * @see test/libc/runtime/grow_test.c + */ +bool grow(void *pp, size_t *capacity, size_t itemsize, size_t extra) { + void **p, *p1, *p2; + size_t n1, n2; /* item counts */ + size_t t1, t2; /* byte counts */ + extra += GUARANTEE_TERMINATOR; /* p ⊃ p[𝑖]==0 */ + p = (void **)pp; + assert(itemsize); + assert((*p && *capacity) || (!*p && !*capacity)); + assert(!isheap(*p) || ((intptr_t)*p & 15) == 0); + p1 = isheap(*p) ? *p : NULL; + p2 = NULL; + n1 = *capacity; + n2 = (*p ? n1 + (n1 >> 1) : max(4, INITIAL_CAPACITY / itemsize)) + extra; + if (sizemultiply(&t1, n1, itemsize) && sizemultiply(&t2, n2, itemsize)) { + if (weaken(realloc) && (p2 = weaken(realloc)(p1, ROUNDUP(t2, 32)))) { + if (!p1 && *p) memcpy(p2, *p, t1); + memset((char *)p2 + t1, 0, t2 - t1); + *capacity = n2; + *p = p2; + return true; + } else { + enomem(); + } + } else { + eoverflow(); + } + return false; +} diff --git a/libc/runtime/heapsortcar.c b/libc/runtime/heapsortcar.c new file mode 100644 index 00000000..1bdaa16c --- /dev/null +++ b/libc/runtime/heapsortcar.c @@ -0,0 +1,66 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/str/str.h" + +static unsigned heapsortmax(int32_t (*A)[2], unsigned n, unsigned i, unsigned j, + unsigned k) { + unsigned m = i; + if (j < n && A[j][0] > A[m][0]) m = j; + if (k < n && A[k][0] > A[m][0]) m = k; + return m; +} + +static void heapsortdown(int32_t (*A)[2], unsigned n, unsigned i) { + unsigned j; + int32_t t[2]; + for (;;) { + unsigned j = heapsortmax(A, n, i, 2 * i + 1, 2 * i + 2); + if (j == i) break; + memcpy(t, A[i], sizeof(t)); + memcpy(A[i], A[j], sizeof(t)); + memcpy(A[j], t, sizeof(t)); + i = j; + } +} + +/** + * Sorts key-values. + * + * heapsortcar is a linearithmic / constant-memory / non-stable sorting + * function that's a tenth the size of the more generalized qsort() API. + * It can only sort arrays of 64-bit values, and comparisons happen by + * treating the lower 32-bits as a signed integer. + * + * @see test/libc/alg/heapsortcar_test.c + */ +void heapsortcar(int32_t (*A)[2], unsigned n) { + unsigned i; + int32_t t[2]; + for (i = ((n - 2) / 2) + 1; i > 0; i--) { + heapsortdown(A, n, i - 1); + } + for (i = 0; i < n; i++) { + memcpy(t, A[n - i - 1], sizeof(t)); + memcpy(A[n - i - 1], A[0], sizeof(t)); + memcpy(A[0], t, sizeof(t)); + heapsortdown(A, n - i - 1, 0); + } +} diff --git a/libc/runtime/init.S b/libc/runtime/init.S new file mode 100644 index 00000000..14673e0e --- /dev/null +++ b/libc/runtime/init.S @@ -0,0 +1,145 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +#include "libc/runtime/internal.h" +#include "libc/sysv/consts/prot.h" +#include "libc/dce.h" +.yoink __FILE__ + +/ Decentralized function for process initialization. +/ +/ Modules may inject cheap data structure initialization code into +/ this function using the .init.start and .init.end macros. That +/ code can use the LODS and STOS instructions to initialize memory +/ that's restricted to read-only after initialization by PIRO. +/ +/ This is fast, since the linker is able to roll-up initialization +/ for large codebases comprised of many modules, into a perfectly +/ linear order. It also enables a common pattern we use, which we +/ call “Referencing Is Initialization” (RII). +/ +/ C/C++ code should favor using ordinary constructors, since under +/ normal circumstances the compiler will clobber RDI and RSI which +/ are granted special meanings within this function. +/ +/ @param r12 is argc (still callee saved) +/ @param r13 is argv (still callee saved) +/ @param r14 is envp (still callee saved) +/ @param r15 is envp (still callee saved) +/ @note rdi is __init_bss_start (callee monotonic lockstep) +/ @note rsi is __init_rodata_start (callee monotonic lockstep) +/ @see .init.start & .init.end (libc/macros.inc) +/ @see ape/ape.lds + .section .initprologue,"ax",@progbits + .type _init,@function + .globl _init + .comm g_runstate,4 +_init: push %rbp + mov %rsp,%rbp + .profilable + ezlea __init_bss_start,di + ezlea __init_rodata_start,si + .previous/* + ... + decentralized content + ... + */.section .initepilogue,"ax",@progbits +#if IsModeDbg() +_init_check_rdi_rsi: + jmp 2f +1: call abort +2: ezlea __init_bss_end,ax + cmp %rax,%rdi + jne 1b + ezlea __init_rodata_end,ax + cmp %rax,%rsi + jne 1b +3: .endfn _init_check_rdi_rsi +#endif +_woot: leave + ret + .previous + +/ Decentralized section for packed data structures & initializers. +/ +/ @see .initro (libc/macros.inc) +/ @see ape/ape.lds + .section .initroprologue,"a",@progbits + .type __init_rodata_start,@object + .type __init_rodata_end,@object + .globl __init_rodata_start,__init_rodata_end + .hidden __init_rodata_start,__init_rodata_end + .align __SIZEOF_POINTER__ +__init_rodata_start: + .previous/* + ... + decentralized content + ... + */.section .initroepilogue,"a",@progbits +__init_rodata_end: + .byte 0x90 + .previous + +/ Decentralized section for unpacked data structures. +/ +/ Data in this section becomes read-only after initialization. +/ +/ @see .piro.bss.init (libc/macros.inc) +/ @see libc/runtime/piro.c +/ @see ape/ape.lds + .section .piro.bss.init.1,"aw",@nobits + .type __init_bss_start,@object + .type __init_bss_end,@object + .globl __init_bss_start,__init_bss_end + .hidden __init_bss_start,__init_bss_end + .align __SIZEOF_POINTER__ +__init_bss_start: + .previous/* + ... + decentralized content + ... + */.section .piro.bss.init.3,"aw",@nobits +__init_bss_end: + .byte 0 + .previous + +/ Special area for Windows NT support code. +/ +/ Isolating this code adds value for Windows users by minimizing +/ page faults through improved locality. On System Five the PIRO +/ runtime can unmap these pages. +/ +/ @see libc/runtime/piro.c +/ @see ape/ape.lds + .section .textwindowsprologue,"ax",@progbits + .type __text_windows_start,@object + .type __text_windows_end,@object + .globl __text_windows_start,__text_windows_end + .hidden __text_windows_start,__text_windows_end + int3 +__text_windows_start: + .previous/* + ... + decentralized content + ... + */.section .textwindowsepilogue,"ax",@progbits +__text_windows_end: + int3 + .previous diff --git a/libc/runtime/internal.h b/libc/runtime/internal.h new file mode 100644 index 00000000..d9968d62 --- /dev/null +++ b/libc/runtime/internal.h @@ -0,0 +1,35 @@ +#ifndef COSMOPOLITAN_LIBC_RUNTIME_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_RUNTIME_INTERNAL_H_ +#include "libc/dce.h" +#include "libc/runtime/runtime.h" + +#define RUNSTATE_INITIALIZED (1 << 0) +#define RUNSTATE_BROKEN (1 << 1) +#define RUNSTATE_TERMINATE (1 << 2) + +#define STACK_CEIL 0x700000000000ul +#define STACK_SIZE FRAMESIZE + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern char **g_freebsdhint; +hidden extern unsigned g_runstate; +hidden extern void *g_stacktop; + +void _init(void) hidden; +void __piro(int) hidden; +void *__cxa_finalize(void *) hidden; +int getdosargv(const char16_t *, char *, size_t, char **, size_t) hidden; +void __stack_chk_fail(void) noreturn relegated; +void __stack_chk_fail_local(void) noreturn relegated hidden; + +forceinline void AssertNeverCalledWhileTerminating(void) { + if (!NoDebug() && (g_runstate & RUNSTATE_TERMINATE)) { + abort(); + } +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_RUNTIME_INTERNAL_H_ */ diff --git a/libc/runtime/interruptiblecall.c b/libc/runtime/interruptiblecall.c new file mode 100644 index 00000000..76a09028 --- /dev/null +++ b/libc/runtime/interruptiblecall.c @@ -0,0 +1,75 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/progn.h" +#include "libc/bits/safemacros.h" +#include "libc/mem/mem.h" +#include "libc/runtime/interruptiblecall.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/sa.h" +#include "libc/sysv/consts/sig.h" + +STATIC_YOINK("_init_onntconsoleevent"); + +static struct InterruptibleCall *g_interruptiblecall; + +noreturn static void interruptcall(int sig) { + longjmp(g_interruptiblecall->jb, 1); + unreachable; +} + +/** + * Calls function that may be cancelled by a signal. + * + * @param state is allocated and zero'd by the caller; state→sig and + * state→sa_new.sa_mask may be set; it may be re-used w/o + * reinitializing; it may be static or heap memory; it may be stack + * memory if re-entrant behavior isn't needed + * @return the value returned by callback or -1 on interrupt; they may + * be differentiated using the state→returnval filed, which is only + * modified by this function when callbacks succeed + */ +intptr_t interruptiblecall(struct InterruptibleCall *icall, + intptr_t callback(intptr_t p1, intptr_t p2, + intptr_t p3, intptr_t p4), + intptr_t p1, intptr_t p2, intptr_t p3, intptr_t p4) { + intptr_t rc; + if (!icall->sig) icall->sig = SIGINT; + icall->sa_new.sa_handler = interruptcall; + icall->sa_new.sa_flags |= SA_RESTART | SA_RESETHAND; + if ((rc = (sigaction)(icall->sig, &icall->sa_new, &icall->sa_old)) != -1) { + g_interruptiblecall = PROGN((icall->prev = g_interruptiblecall), icall); + if (!setjmp(icall->jb)) { + icall->returnval = rc = callback(p1, p2, p3, p4); + } else { + rc = -1; + } + asm volatile("" ::: "memory"); + struct InterruptibleCall *unwind; + for (;;) { + unwind = g_interruptiblecall; + (sigaction)(unwind->sig, &unwind->sa_old, NULL); + g_interruptiblecall = unwind->prev; + if (unwind == icall) break; + free_s(&unwind); + } + icall->prev = NULL; + } + return rc; +} diff --git a/libc/runtime/interruptiblecall.h b/libc/runtime/interruptiblecall.h new file mode 100644 index 00000000..d53444eb --- /dev/null +++ b/libc/runtime/interruptiblecall.h @@ -0,0 +1,26 @@ +#ifndef COSMOPOLITAN_LIBC_RUNTIME_INTERRUPTIBLECALL_H_ +#define COSMOPOLITAN_LIBC_RUNTIME_INTERRUPTIBLECALL_H_ +#include "libc/runtime/runtime.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/calls/calls.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct InterruptibleCall { + struct InterruptibleCall *prev; + intptr_t returnval; + int sig; + int flags; + jmp_buf jb; + struct sigaction sa_new; + struct sigaction sa_old; +}; + +intptr_t interruptiblecall(struct InterruptibleCall *state, + intptr_t callback(intptr_t p1, intptr_t p2, + intptr_t p3, intptr_t p4), + intptr_t p1, intptr_t p2, intptr_t p3, intptr_t p4); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_RUNTIME_INTERRUPTIBLECALL_H_ */ diff --git a/libc/runtime/isheap.c b/libc/runtime/isheap.c new file mode 100644 index 00000000..c83e6b7a --- /dev/null +++ b/libc/runtime/isheap.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/mappings.h" + +/** + * Returns false if address can't be heap memory. + */ +bool isheap(void *p) { + size_t i; + struct MemoryCoord c; + if (!(kStackBottom <= (intptr_t)p && (intptr_t)p < kStackCeiling)) { + c = ADDRSIZE_TO_COORD(p, FRAMESIZE); + if ((i = findmapping(c.x))) { + return ISOVERLAPPING(_mm.p[i - 1], c); + } else { + return false; + } + } else { + return false; + } +} diff --git a/libc/runtime/issetugid.c b/libc/runtime/issetugid.c new file mode 100644 index 00000000..923007e7 --- /dev/null +++ b/libc/runtime/issetugid.c @@ -0,0 +1,23 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/auxv.h" + +int issetugid(void) { return !!getauxval(AT_SECURE); } diff --git a/libc/runtime/kntsystemdirectory.S b/libc/runtime/kntsystemdirectory.S new file mode 100644 index 00000000..0a4850a8 --- /dev/null +++ b/libc/runtime/kntsystemdirectory.S @@ -0,0 +1,38 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +#define BYTES 64 + +/ RII constant holding 'C:/WINDOWS/SYSTEM32' directory. +/ +/ @note guarantees trailing slash if non-empty + .initbss 300,_init_kNtSystemDirectory +kNtSystemDirectory: + .zero BYTES + .endobj kNtSystemDirectory,globl + .previous + + .init.start 300,_init_kNtSystemDirectory + pushpop BYTES,%rdx + mov __imp_GetSystemDirectoryA(%rip),%rax + call __getntsyspath + .init.end 300,_init_kNtSystemDirectory diff --git a/libc/runtime/kntwindowsdirectory.S b/libc/runtime/kntwindowsdirectory.S new file mode 100644 index 00000000..567c7aad --- /dev/null +++ b/libc/runtime/kntwindowsdirectory.S @@ -0,0 +1,38 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +#define BYTES 64 + +/ RII constant holding 'C:/WINDOWS' directory. +/ +/ @note guarantees trailing slash if non-empty + .initbss 300,_init_kNtWindowsDirectory +kNtWindowsDirectory: + .zero BYTES + .endobj kNtWindowsDirectory,globl + .previous + + .init.start 300,_init_kNtWindowsDirectory + pushpop BYTES,%rdx + mov __imp_GetWindowsDirectoryA(%rip),%rax + call __getntsyspath + .init.end 300,_init_kNtWindowsDirectory diff --git a/libc/runtime/mapanon-thunk.S b/libc/runtime/mapanon-thunk.S new file mode 100644 index 00000000..3b553d6c --- /dev/null +++ b/libc/runtime/mapanon-thunk.S @@ -0,0 +1,33 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +mapanon:push %rbp + mov %rsp,%rbp + push %rbx + push %rbx + ezlea _base,bx + call __mapanon + pop %rbx + pop %rbx + pop %rbp + ret + .endfn mapanon,globl diff --git a/libc/runtime/mapanon.c b/libc/runtime/mapanon.c new file mode 100644 index 00000000..e32c4814 --- /dev/null +++ b/libc/runtime/mapanon.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" + +void *__mapanon(size_t mapsize) { + return mmap(NULL, mapsize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_NONBLOCK | MAP_ANONYMOUS, -1, 0); +} diff --git a/libc/runtime/mapelfread.c b/libc/runtime/mapelfread.c new file mode 100644 index 00000000..6a59ed39 --- /dev/null +++ b/libc/runtime/mapelfread.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/elf/def.h" +#include "libc/elf/elf.h" +#include "libc/runtime/ezmap.h" + +Elf64_Ehdr *mapelfread(const char *filename, struct MappedFile *mf) { + if (mapfileread(filename, mf) != -1 && iself64binary(mf->addr, mf->size)) { + return mf->addr; + } else { + unmapfile(mf); + return NULL; + } +} diff --git a/libc/runtime/mappings.c b/libc/runtime/mappings.c new file mode 100644 index 00000000..92eeaf55 --- /dev/null +++ b/libc/runtime/mappings.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/mappings.h" + +struct Mappings _mm; diff --git a/libc/runtime/mappings.h b/libc/runtime/mappings.h new file mode 100644 index 00000000..c8814b1a --- /dev/null +++ b/libc/runtime/mappings.h @@ -0,0 +1,78 @@ +#ifndef COSMOPOLITAN_LIBC_RUNTIME_MAPPINGS_H_ +#define COSMOPOLITAN_LIBC_RUNTIME_MAPPINGS_H_ +#include "libc/dce.h" +#include "libc/macros.h" +#include "libc/runtime/runtime.h" + +#define MMAP_MAX 300 /* TODO: crunch */ + +#define kStackCeiling 0x0000700000000000L +#define kStackBottom 0x0000600000000000L + +#define kFixedMappingsStart 0x0000100000000000L /* cosmo won't auto-assign */ +#define kFixedMappingsSize 0x0000100000000000L /* 16TB */ + +#define kMappingsStart 0x0000200000000000L /* cosmo auto-assigns here */ +#define kMappingsSize 0x0000100000000000L /* 16TB */ + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define ISOVERLAPPING(C1, C2) \ + (((C1).x >= (C2).x && (C1).x <= (C2).y) || \ + ((C1).y >= (C2).x && (C1).y <= (C2).y)) + +#define ADDR_TO_COORD(ADDR) \ + (int)(((intptr_t)(ADDR) & ~(FRAMESIZE - 1)) / FRAMESIZE) + +#define COORD_TO_ADDR(COORD) (void *)((intptr_t)(COORD)*FRAMESIZE) +#define COORD_TO_SIZE(COORD) (void *)((intptr_t)(COORD)*FRAMESIZE) + +#define ADDRSIZE_TO_COORD(ADDR, SIZE) \ + ((struct MemoryCoord){ \ + .x = ADDR_TO_COORD(ADDR), \ + .y = ADDR_TO_COORD(ADDR) + \ + ((unsigned)(ROUNDUP((SIZE), FRAMESIZE) / FRAMESIZE) - 1)}) + +#define COORD_TO_ADDRSIZE(COORD) \ + ((struct AddrSize){ \ + .addr = COORD_TO_ADDR((COORD).x), \ + .size = ((size_t)((COORD).y - (COORD).x + 1) * FRAMESIZE)}) + +#define GRANULATE_ADDRSIZE(ADDR, SIZE) \ + do { \ + struct AddrSize AdSiz; \ + struct MemoryCoord MemCo; \ + MemCo = ADDRSIZE_TO_COORD(*(ADDR), *(SIZE)); \ + AdSiz = COORD_TO_ADDRSIZE(MemCo); \ + *(ADDR) = AdSiz.addr; \ + *(SIZE) = AdSiz.size; \ + } while (0) + +struct AddrSize { + void *addr; + size_t size; +}; + +/** + * Ordered inclusive 64kb-granular ranges on NexGen32e w/o PML5. + * c.𝑥 ≤ c.𝑦 so say c all. + * cₙ.𝑥 ≤ cₙ₊₁.𝑥 so say c all. + */ +struct Mappings { + size_t i; + struct MemoryCoord { + int32_t x, y; + } p[MMAP_MAX]; + int64_t h[MMAP_MAX]; +}; + +extern struct Mappings _mm; + +bool isheap(void *); +size_t findmapping(int32_t); +size_t findmapping_(int32_t, const struct MemoryCoord *, size_t); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_RUNTIME_MAPPINGS_H_ */ diff --git a/libc/runtime/mergepages.S b/libc/runtime/mergepages.S new file mode 100644 index 00000000..6315b402 --- /dev/null +++ b/libc/runtime/mergepages.S @@ -0,0 +1,46 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/sysv/consts/madv.h" +#include "libc/sysv/consts/nr.h" +#include "libc/macros.h" +.text.startup +.yoink __FILE__ + +/ Merges page table entries for pages with identical content. +/ +/ This is a hint. It can help trim physical memory for things +/ like extremely sparse data. +/ +/ @param rdi is base address +/ @param rsi is byte length +mergepages: + .leafprologue + .profilable + mov $-PAGESIZE,%rax + and %rax,%rdi + and %rax,%rsi + mov __NR_madvise,%eax + mov MADV_MERGEABLE,%edx + test %edx,%edx + jz 1f + syscall +1: .leafepilogue + .endfn mergepages,globl diff --git a/libc/runtime/missioncritical.h b/libc/runtime/missioncritical.h new file mode 100644 index 00000000..bbb9b33a --- /dev/null +++ b/libc/runtime/missioncritical.h @@ -0,0 +1,143 @@ +#ifndef COSMOPOLITAN_LIBC_INTERNAL_MISSIONCRITICAL_H_ +#define COSMOPOLITAN_LIBC_INTERNAL_MISSIONCRITICAL_H_ +#include "libc/bits/bits.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/nexgen32e/nexgen32e.h" +#include "libc/nt/console.h" +#include "libc/nt/enum/version.h" +#include "libc/nt/ntdll.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/teb.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/nr.h" +#include "libc/sysv/consts/sig.h" +#include "libc/sysv/errfuns.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * @fileoverview Mission critical system calls. + */ + +#define PRINT(STR) __print(STR, tinystrlen(STR)) + +#define NT_HAVE_IMPORT(SLOT) \ + ((void *)*SLOT && *SLOT != (void *)&missingno /* see libc/crt/crt.S */) + +#define _EXIT(rc) \ + ({ \ + int ExitAx; \ + asm volatile("syscall" \ + : "=a"(ExitAx) \ + : "0"(__NR_exit), "D"(rc) \ + : "rcx", "r11", "cc", "memory"); \ + ExitAx; \ + }) + +#define GETPID() \ + ({ \ + int Res; \ + asm("syscall" : "=a"(Res) : "0"(__NR_getpid) : "rcx", "r11", "cc"); \ + Res; \ + }) + +#define KILL(pid, sig) \ + ({ \ + int KillAx; \ + unsigned char Cf; \ + asm volatile(CFLAG("clc\n\t" \ + "syscall") \ + : CF(Cf), "=a"(KillAx) \ + : "1"(__NR_kill), "D"(pid), "S"(sig) \ + : "rcx", "r11", "cc", "memory"); \ + Cf ? -KillAx : KillAx; \ + }) + +#define RAISE(SIG) \ + ({ \ + int RaiseAx = -1; \ + int Sig = (SIG); \ + if (Sig == SIGTRAP) { \ + DebugBreak(); \ + } else if (!IsWindows()) { \ + RaiseAx = KILL(GETPID(), Sig); \ + } else { \ + switch (Sig) { \ + case SIGINT: \ + GenerateConsoleCtrlEvent(kNtCtrlCEvent, 0); \ + break; \ + case SIGHUP: \ + GenerateConsoleCtrlEvent(kNtCtrlCloseEvent, 0); \ + break; \ + case SIGQUIT: \ + GenerateConsoleCtrlEvent(kNtCtrlBreakEvent, 0); \ + break; \ + default: \ + for (;;) TerminateProcess(GetCurrentProcess(), 128 + Sig); \ + } \ + } \ + RaiseAx; \ + }) + +#define SCHED_YIELD() \ + ({ \ + int64_t SyAx; \ + if (!IsWindows()) { \ + asm volatile("syscall" \ + : "=a"(SyAx) \ + : "0"(__NR_sched_yield) \ + : "rcx", "r11", "cc", "memory"); \ + } else { \ + NtYieldExecution(); \ + } \ + 0; \ + }) + +#define WAIT4(PID, OPT_OUT_WSTATUS, OPTIONS, OPT_OUT_RUSAGE) \ + ({ \ + int64_t WaAx; \ + if (!IsWindows()) { \ + register void *Reg10 asm("r10") = (OPT_OUT_RUSAGE); \ + asm volatile("syscall" \ + : "=a"(WaAx) \ + : "0"(__NR_wait4), "D"(PID), "S"(OPT_OUT_WSTATUS), \ + "d"(OPTIONS), "r"(Reg10) \ + : "rcx", "r11", "cc", "memory"); \ + } else { \ + WaAx = wait4$nt(PID, OPT_OUT_WSTATUS, OPTIONS, OPT_OUT_RUSAGE); \ + } \ + WaAx; \ + }) + +#if 0 +/** + * Exits on Windows the hard way. + */ +#endif +#define NT_TERMINATE_PROCESS() \ + do \ + if (NtGetVersion() < kNtVersionFuture) { \ + int64_t ax, cx; \ + do \ + asm volatile( \ + "syscall" /* hook THIS system call */ \ + : "=a"(ax), "=c"(cx) \ + : "0"(NtGetVersion() < kNtVersionWindows8 \ + ? 0x0029 \ + : NtGetVersion() < kNtVersionWindows81 \ + ? 0x002a \ + : NtGetVersion() < kNtVersionWindows10 ? 0x002b \ + : 0x002c), \ + "1"(-1L /* GetCurrentProcess() */), "d"(42) \ + : "r11", "cc", "memory"); \ + while (!ax); \ + } \ + while (0) + +interruptfn void __print(const void *, size_t); + +#define LOAD_DEFAULT_RBX() /* disabled for now b/c clang */ +#define RESTORE_RBX() /* disabled for now b/c clang */ + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_INTERNAL_MISSIONCRITICAL_H_ */ diff --git a/libc/runtime/mmap.c b/libc/runtime/mmap.c new file mode 100644 index 00000000..b9ed6d28 --- /dev/null +++ b/libc/runtime/mmap.c @@ -0,0 +1,155 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/macros.h" +#include "libc/nt/memory.h" +#include "libc/nt/runtime.h" +#include "libc/runtime/mappings.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/errfuns.h" + +#define VIP(X) (void *)(intptr_t)(X) + +struct DirectMap { + void *addr; + int64_t maphandle; +}; + +static textwindows struct DirectMap directmap$nt(void *addr, size_t size, + unsigned prot, unsigned flags, + int fd, int64_t off) { + struct DirectMap res; + if ((res.maphandle = CreateFileMappingNuma( + fd != -1 ? g_fds.p[fd].handle : kNtInvalidHandleValue, + &kNtIsInheritable, prot2nt(prot, flags), size >> 32, size, NULL, + kNtNumaNoPreferredNode))) { + if (!(res.addr = MapViewOfFileExNuma(res.maphandle, fprot2nt(prot, flags), + off >> 32, off, size, addr, + kNtNumaNoPreferredNode))) { + CloseHandle(res.maphandle); + res.maphandle = kNtInvalidHandleValue; + res.addr = VIP(winerr()); + } + } else { + res.maphandle = kNtInvalidHandleValue; + res.addr = VIP(winerr()); + } + return res; +} + +static struct DirectMap directmap(void *addr, size_t size, unsigned prot, + unsigned flags, int fd, int64_t off) { + if (!IsWindows()) { + return (struct DirectMap){mmap$sysv(addr, size, prot, flags, fd, off), + kNtInvalidHandleValue}; + } else { + return directmap$nt(addr, size, prot, flags, fd, off); + } +} + +/** + * Beseeches system for page-table entries. + * + * @param addr optionally requests a particular virtual base address, + * which needs to be 64kb aligned if passed (for NT compatibility) + * @param size should be >0 and multiple of PAGESIZE + * @param prot can have PROT_READ, PROT_WRITE, PROT_EXEC, PROT_NONE, etc. + * @param flags can have MAP_ANONYMOUS, MAP_SHARED, MAP_PRIVATE, etc. + * @param fd is an open()'d file descriptor whose contents shall be + * mapped, and is ignored if MAP_ANONYMOUS is specified + * @param offset specifies absolute byte index of fd's file for mapping, + * and should be zero if MAP_ANONYMOUS is specified + * @return virtual base address of new mapping, or MAP_FAILED w/ errno + */ +void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) { + size_t i; + intptr_t p; + struct DirectMap dm; + struct MemoryCoord c; + p = (intptr_t)addr; + + assert(!(0 < p && p < 0x200000)); + assert(-0x800000000000L <= p && p <= 0x7fffffffffffL); + assert((flags & MAP_PRIVATE) ^ (flags & MAP_SHARED)); + assert((flags & MAP_ANONYMOUS) ^ (fd != -1)); + assert(off % PAGESIZE == 0); + assert(size > 0); + + if (!(IsWindows() && fd != -1)) { + size = ROUNDUP(size, FRAMESIZE); + } + + if (flags & MAP_FIXED) { + assert(addr != NULL); + assert((intptr_t)addr % FRAMESIZE == 0); + } else { + if (!addr) { + if (_mm.i) { + addr = COORD_TO_ADDR(_mm.p[_mm.i - 1].y + 1); + for (i = _mm.i; i; --i) { + if (_mm.p[i - 1].y + 1 + size / FRAMESIZE <= + ADDR_TO_COORD(kMappingsStart + kMappingsSize) && + _mm.p[i - 1].y + 1 >= ADDR_TO_COORD(kMappingsStart)) { + addr = COORD_TO_ADDR(_mm.p[i - 1].y + 1); + break; + } + } + } else { + addr = VIP(kMappingsStart); + } + } + addr = (void *)ROUNDDOWN((intptr_t)addr, FRAMESIZE); + } + + if (_mm.i == MMAP_MAX) { + return VIP(enomem()); + } + + if (flags & MAP_FIXED) { + munmap(addr, size); + } else { + c = ADDRSIZE_TO_COORD(addr, size); + if ((i = findmapping(c.y)) && ISOVERLAPPING(c, _mm.p[i - 1])) { + return VIP(einval()); + } + } + + dm = directmap(addr, size, prot, flags | MAP_FIXED, fd, off); + if (dm.addr == MAP_FAILED) return MAP_FAILED; + + i = findmapping(ADDR_TO_COORD(dm.addr)); + if (i < _mm.i) { + memmove(&_mm.p[i + 1], &_mm.p[i], + (intptr_t)&_mm.p[_mm.i] - (intptr_t)&_mm.p[i]); + memmove(&_mm.h[i + 1], &_mm.h[i], + (intptr_t)&_mm.h[_mm.i] - (intptr_t)&_mm.h[i]); + } + + _mm.p[i] = ADDRSIZE_TO_COORD(dm.addr, size); + _mm.h[i] = dm.maphandle; + _mm.i++; + + assert((intptr_t)dm.addr % __BIGGEST_ALIGNMENT__ == 0); + return dm.addr; +} diff --git a/libc/runtime/mremap.c b/libc/runtime/mremap.c new file mode 100644 index 00000000..22eeda26 --- /dev/null +++ b/libc/runtime/mremap.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/sysv/errfuns.h" + +void *mremap(void *old_address, size_t old_size, size_t new_size, int flags, + void *new_address) { + return (void *)(intptr_t)enosys(); +} diff --git a/libc/runtime/msync-nt.c b/libc/runtime/msync-nt.c new file mode 100644 index 00000000..55a30cbc --- /dev/null +++ b/libc/runtime/msync-nt.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/files.h" +#include "libc/nt/memory.h" +#include "libc/runtime/mappings.h" + +textwindows int msync$nt(void *addr, size_t size, int flags) { + size_t i, j; + struct MemoryCoord c; + if (!FlushViewOfFile(addr, size)) return winerr(); + j = findmapping(ADDR_TO_COORD(addr)); + c = ADDRSIZE_TO_COORD(addr, size); + for (i = j; i; --i) { + if (!ISOVERLAPPING(_mm.p[i - 1], c)) break; + FlushFileBuffers(_mm.h[i - 1]); + } + return 0; +} diff --git a/libc/runtime/msync.c b/libc/runtime/msync.c new file mode 100644 index 00000000..f02f1f01 --- /dev/null +++ b/libc/runtime/msync.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/macros.h" +#include "libc/runtime/mappings.h" +#include "libc/sysv/consts/msync.h" + +/** + * Synchronize memory mapping changes to disk. + * + * @param flags needs MS_SYNC or MS_ASYNC and can have MS_INVALIDATE + * @return 0 on success or -1 w/ errno + */ +int msync(void *addr, size_t size, int flags) { + assert(((flags & MS_SYNC) ^ (flags & MS_ASYNC)) || !(MS_SYNC && MS_ASYNC)); + if (!IsWindows()) { + return msync$sysv(addr, size, flags); + } else { + return msync$nt(addr, size, flags); + } +} diff --git a/libc/runtime/munmap-thunk.S b/libc/runtime/munmap-thunk.S new file mode 100644 index 00000000..5b9b5ce0 --- /dev/null +++ b/libc/runtime/munmap-thunk.S @@ -0,0 +1,33 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +munmap: push %rbp + mov %rsp,%rbp + push %rbx + push %rbx + ezlea _base,bx + call __munmap + pop %rbx + pop %rbx + pop %rbp + ret + .endfn munmap,globl diff --git a/libc/runtime/munmap.c b/libc/runtime/munmap.c new file mode 100644 index 00000000..e7865cc2 --- /dev/null +++ b/libc/runtime/munmap.c @@ -0,0 +1,106 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/nt/memory.h" +#include "libc/nt/runtime.h" +#include "libc/runtime/mappings.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/fileno.h" + +/** + * Releases memory pages. + * + * @param addr is a pointer within any memory mapped region the process + * has permission to control, such as address ranges returned by + * mmap(), the program image itself, etc. + * @param size is the amount of memory to unmap, which should be a + * multiple of PAGESIZE, and may be a subset of that which was + * mapped previously + * @return 0 on success, or -1 w/ errno + */ +int __munmap(void *addr, size_t size) { + int rc; + intptr_t p; + size_t i, j; + struct AddrSize a; + struct MemoryCoord c, m; + + p = (intptr_t)addr; + assert(!(0 < p && p < 0x200000)); + assert(-0x800000000000L <= p && p <= 0x7fffffffffffL); + + if (!size) return 0; + if (!addr || addr == MAP_FAILED) return 0; + if (addr == NULL && size <= 0x200000) return 0; + + addr = (void *)ROUNDDOWN((intptr_t)addr, FRAMESIZE); + size = ROUNDUP(size, FRAMESIZE); + + rc = 0; + c = ADDRSIZE_TO_COORD(addr, size); + j = findmapping(c.y); + for (i = j; i; --i) { + m = _mm.p[i - 1]; + assert(m.x <= m.y); + assert(c.y >= m.x); + if (c.x > m.y) { + break; + } else if (c.x > m.x && c.y < m.y) { + /* remove middle portion */ + assert(!"map hole punching not implemented"); + } else if (c.x > m.x && c.y >= m.y) { + /* remove righthand portion */ + assert(!"map hole punching not implemented"); + /* _mm.p[i - 1].y = c.x - 1; */ + /* i++; */ + /* break; */ + } else if (c.x <= m.x && c.y < m.y) { + /* remove lefthand portion */ + assert(!"map hole punching not implemented"); + /* _mm.p[i - 1].x = c.y + 1; */ + /* j--; */ + } else if ((m.x >= c.x && m.x <= c.y) && (m.y >= c.x && m.y <= c.y)) { + a = COORD_TO_ADDRSIZE(m); + if (!IsWindows()) { + rc |= munmap$sysv(a.addr, a.size); + } else { + if (!UnmapViewOfFile(a.addr)) rc = -1; + if (!CloseHandle(_mm.h[i - 1])) rc = -1; + } + } else { + assert(!"wut"); + } + } + + if (i < j) { + if (j < _mm.i) { + memmove(&_mm.p[i], &_mm.p[j], + (intptr_t)&_mm.p[_mm.i] - (intptr_t)&_mm.p[j]); + memmove(&_mm.h[i], &_mm.h[j], + (intptr_t)&_mm.h[_mm.i] - (intptr_t)&_mm.h[j]); + } + _mm.i -= j - i; + } + + return rc; +} diff --git a/libc/runtime/munmap_s.c b/libc/runtime/munmap_s.c new file mode 100644 index 00000000..fe7097df --- /dev/null +++ b/libc/runtime/munmap_s.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/pushpop.h" +#include "libc/calls/calls.h" +#include "libc/runtime/mappings.h" +#include "libc/runtime/runtime.h" + +/** + * Closes memory mapping, the Cosmopolitan way. + * + * The caller's address holder is set to MAP_FAILED (-1) which is a + * no-op for subsequent invocations. + * + * @return 0 on success, or -1 w/ errno + */ +int munmap_s(void *addrp, uint64_t size) { + void **addrpp = (void **)addrp; + void *addr = (void *)pushpop(-1L); + return munmap(lockxchg(addrpp, &addr), size); +} diff --git a/libc/runtime/ntgetmodule.c b/libc/runtime/ntgetmodule.c new file mode 100644 index 00000000..6b2342c0 --- /dev/null +++ b/libc/runtime/ntgetmodule.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/nt/ntdll.h" +#include "libc/nt/struct/ldr.h" +#include "libc/nt/struct/ldrdatatableentry.h" +#include "libc/nt/struct/linkedlist.h" +#include "libc/nt/struct/teb.h" +#include "libc/str/str.h" + +textwindows const struct NtLdrDataTableEntry *NtGetModule( + const char *basename) { + struct NtLinkedList *head = &NtGetPeb()->Ldr->InLoadOrderModuleList; + struct NtLinkedList *ldr = head->Next; + do { + const struct NtLdrDataTableEntry *dll = + (const struct NtLdrDataTableEntry *)ldr; + if (strcasecmp8to16(basename, dll->BaseDllName.Data) == 0) return dll; + } while ((ldr = ldr->Next) && ldr != head); + return NULL; +} diff --git a/libc/runtime/opensymboltable.c b/libc/runtime/opensymboltable.c new file mode 100644 index 00000000..8033753d --- /dev/null +++ b/libc/runtime/opensymboltable.c @@ -0,0 +1,60 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/calls/calls.h" +#include "libc/elf/def.h" +#include "libc/elf/elf.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/symbols.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" + +/** + * Maps debuggable binary into memory and indexes symbol addresses. + * + * @return object freeable with closesymboltable(), or NULL w/ errno + */ +struct SymbolTable *opensymboltable(const char *filename) { + struct SymbolTable *t = MAP_FAILED; + const Elf64_Sym *symtab; + if (filename && (t = mapanon(BIGPAGESIZE)) != MAP_FAILED && + mapelfread(filename, &t->mf) && + (t->name_base = getelfstringtable(t->elf, t->elfsize)) != NULL && + (symtab = getelfsymboltable(t->elf, t->elfsize, &t->count)) && + sizeof(struct SymbolTable) + sizeof(struct Symbol) * t->count < + (t->scratch = BIGPAGESIZE)) { + unsigned j = 0; + getelfvirtualaddressrange(t->elf, t->elfsize, &t->addr_base, &t->addr_end); + for (unsigned i = 0; i < t->count; ++i) { + const Elf64_Sym *sym = &symtab[i]; + if (iselfsymbolcontent(sym) && + (sym->st_value >= t->addr_base && sym->st_value <= t->addr_end)) { + t->symbols[j].addr_rva = (unsigned)(sym->st_value - t->addr_base); + t->symbols[j].name_rva = sym->st_name; + j++; + } + } + t->count = j; + heapsortcar((int32_t(*)[2])t->symbols, t->count); + } else { + closesymboltable(&t); + } + return t == MAP_FAILED ? NULL : t; +} diff --git a/libc/runtime/peekall.S b/libc/runtime/peekall.S new file mode 100644 index 00000000..2aedba12 --- /dev/null +++ b/libc/runtime/peekall.S @@ -0,0 +1,33 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/relocations.h" +#include "libc/macros.h" +.yoink __FILE__ + +/ Loads all pages from program image into memory. +peekall:.leafprologue + ezlea _base,si + ezlea _end,cx +0: mov (%rsi),%eax + add $PAGESIZE,%rsi + cmp %rcx,%rsi + jb 0b + .leafepilogue + .endfn peekall,globl diff --git a/libc/runtime/piro.c b/libc/runtime/piro.c new file mode 100644 index 00000000..84f2791d --- /dev/null +++ b/libc/runtime/piro.c @@ -0,0 +1,71 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╠──────────────────────────────────────────────────────────────────────────────╣ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█▀█░▀█▀░█░█░█▀█░█░░░█░░░█░█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█░▄░░█░░█░█░█▀█░█░░░█░░░▀█▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░▀░▀░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀░░▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀█░█▀█░█▀█░▀█▀░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀▀░█ █░██▀░░█░░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░▀░░░▀▀▀░▀░▀░░▀░░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░█▀▀░█░█░█▀▀░█▀█░█░█░▀█▀░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░▄▄░░░▐█░░│ +│░░░░░░░█▀▀░▄▀▄░█▀▀░█░▄░█░█░░█░░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░▄▄▄░░░▄██▄░░█▀░░░█░▄░│ +│░░░░░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░▀░░▀░▀░▀▀▀░▀▀░▀▀▀░░░░░░░░░░▄██▀█▌░██▄▄░░▐█▀▄░▐█▀░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▐█▀▀▌░░░▄▀▌░▌░█░▌░░▌░▌░░│ +╠──────────────────────────────────────────────────────▌▀▄─▐──▀▄─▐▄─▐▄▐▄─▐▄─▐▄─│ +│ αcτµαlly pδrταblε εxεcµταblε § post-initialization read-only │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/dce.h" +#include "libc/runtime/internal.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/prot.h" + +#define getaddr(section) ((intptr_t)weakaddr(section)) + +static textstartup void __piro_protect(intptr_t start, intptr_t end, int prot) { + ssize_t len = end - start; + if (len > 0 && start && start % PAGESIZE == 0 && len % PAGESIZE == 0) { + if (mprotect((void *)(unsigned long)start, len, prot) == -1) abort(); + } +} + +/** + * Protects memory initialized at startup. + * e.g. function hooks, unpacked data structures, etc. + * + * This is only performed for executables of nontrivial size. It won't + * break the build if the αpε linker script wasn't used. Test code is + * protected too, so we don't end up like Knight Capital. + * + * @param prot can have PROT_{NONE,READ,WRITE,EXEC} + * @see ape/ape.lds + * @see libc/_start.S + */ +textstartup void __piro(int prot) { + if (getaddr("main") < getaddr("__test_start")) { + __piro_protect(getaddr("__test_start"), getaddr("__test_end"), PROT_NONE); + } + __piro_protect(getaddr("__ro"), getaddr("_etext"), PROT_READ); + __piro_protect(getaddr("__piro_start"), getaddr("__piro_end"), prot); +} diff --git a/libc/runtime/print.greg.c b/libc/runtime/print.greg.c new file mode 100644 index 00000000..c6d80841 --- /dev/null +++ b/libc/runtime/print.greg.c @@ -0,0 +1,71 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#define ShouldUseMsabiAttribute() 1 +#include "libc/dce.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" +#include "libc/runtime/missioncritical.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/nr.h" + +static privileged void __print$nt(const void *data, size_t len) { + int64_t hand; + uint32_t wrote; + char xmm[256] aligned(16); + savexmm(&xmm[128]); + hand = __imp_GetStdHandle(kNtStdErrorHandle); + __imp_WriteFile(hand, data, len, &wrote, NULL); + __imp_FlushFileBuffers(hand); + loadxmm(&xmm[128]); +} + +/** + * Prints string, by any means necessary. + * + * This function offers a subset of write(STDERR_FILENO) functionality. + * It's designed to work even when the runtime hasn't initialized, e.g. + * before _init() gets called. + * + * @param len can be computed w/ tinystrlen() + * @clob nothing except flags + * @see PRINT() + */ +privileged interruptfn void __print(const void *data, size_t len) { + int64_t ax, ordinal; + LOAD_DEFAULT_RBX(); + if (NT_HAVE_IMPORT(__imp_WriteFile)) { + __print$nt(data, len); + } else { + ordinal = __NR_write > 0 ? __NR_write : IsXnu() ? 0x2000004 : 4; + asm volatile("syscall" + : "=a"(ax) + : "0"(ordinal), "D"(STDERR_FILENO), "S"(data), "d"(len) + : "rcx", "r11", "memory", "cc"); + if (ax == -1 && !hostos && !__NR_write) { + asm volatile("syscall" + : "=a"(ax) + : "0"(ordinal), "D"(STDERR_FILENO), "S"(data), "d"(len) + : "rcx", "r11", "memory", "cc"); + } + } + RESTORE_RBX(); +} diff --git a/libc/runtime/progname.S b/libc/runtime/progname.S new file mode 100644 index 00000000..b13d9faf --- /dev/null +++ b/libc/runtime/progname.S @@ -0,0 +1,33 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Provides argv[0] The BSD Way. + .initbss 300,_init___progname +__progname: + .quad 0 + .endobj __progname,globl,hidden + .previous + + .init.start 300,_init___progname + mov %r13,%rax + stosq + .init.end 300,_init___progname diff --git a/libc/runtime/program_invocation_short_name.S b/libc/runtime/program_invocation_short_name.S new file mode 100644 index 00000000..9c59b9d5 --- /dev/null +++ b/libc/runtime/program_invocation_short_name.S @@ -0,0 +1,38 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Supplies basename(argv[0]) The GNU Way. + .initbss 400,_init_program_invocation_short_name +program_invocation_short_name: + .quad 0 + .endobj program_invocation_short_name,globl + .previous + + .init.start 400,_init_program_invocation_short_name + push %rdi + push %rsi + mov (%r13),%rdi + call basename + pop %rsi + pop %rdi + stosq + .init.end 400,_init_program_invocation_short_name diff --git a/libc/runtime/quick_exit.c b/libc/runtime/quick_exit.c new file mode 100644 index 00000000..a45e0bcc --- /dev/null +++ b/libc/runtime/quick_exit.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" + +/** + * Terminates process normally, running minimal cleanup. + * @noreturn + */ +noreturn textexit void quick_exit(int rc) { + if (weaken(fflush)) { + if (weaken(stdout)) weaken(fflush)(*weaken(stdout)); + if (weaken(stderr)) weaken(fflush)(*weaken(stderr)); + } + _Exit(rc); +} diff --git a/libc/runtime/rbx.h b/libc/runtime/rbx.h new file mode 100644 index 00000000..289e171e --- /dev/null +++ b/libc/runtime/rbx.h @@ -0,0 +1,21 @@ +#ifndef COSMOPOLITAN_LIBC_RUNTIME_RBX_H_ +#define COSMOPOLITAN_LIBC_RUNTIME_RBX_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#if 0 +#ifndef __llvm__ +register uint8_t *__rbx asm("rbx"); +#else +#define __rbx \ + ({ \ + register uint8_t *Rbx asm("rbx"); \ + asm("" : "=r"(Rbx)); \ + Rbx; \ + }) +#endif +#endif + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_RUNTIME_RBX_H_ */ diff --git a/libc/runtime/ring.h b/libc/runtime/ring.h new file mode 100644 index 00000000..22a591b5 --- /dev/null +++ b/libc/runtime/ring.h @@ -0,0 +1,17 @@ +#ifndef COSMOPOLITAN_LIBC_RUNTIME_RING_H_ +#define COSMOPOLITAN_LIBC_RUNTIME_RING_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct RingBuffer { + void *p; + char *_addr; + size_t _size; +}; + +void *ringalloc(struct RingBuffer *, size_t); +int ringfree(struct RingBuffer *); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_RUNTIME_RING_H_ */ diff --git a/libc/runtime/ringalloc.c b/libc/runtime/ringalloc.c new file mode 100644 index 00000000..ade57207 --- /dev/null +++ b/libc/runtime/ringalloc.c @@ -0,0 +1,74 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/calls.h" +#include "libc/dce.h" +#include "libc/limits.h" +#include "libc/macros.h" +#include "libc/runtime/ring.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" + +/** + * Allocates ring buffer. + * + * Reads/writes wrap around on overflow. + * + * ┌────────────┐ + * │ 𝑓₀..𝑓ₙ₋₁ │ + * └┬┬──────────┘ + * │└────────────┐ + * ┌┴────────────┬┴────────────┐ + * │ 𝑣₀..𝑣ₙ₋₁ │ 𝑣ₙ..𝑣ₙ*₂₋₁ │ + * └─────────────┴─────────────┘ + * + * @param r is metadata object owned by caller, initialized to zero + * @param n is byte length + * @return r->p, or NULL w/ errno + * @see ringfree(), balloc() + */ +void *ringalloc(struct RingBuffer *r, size_t n) { + void *a2; + int fd, rc; + size_t grain; + assert(!r->p); + assert(n > 0); + assert(n <= (INT_MAX - FRAMESIZE + 1) / 2); + if ((fd = openanon("ring", 0)) != -1) { + grain = ROUNDUP(n, FRAMESIZE); + rc = ftruncate(fd, grain * 2); + assert(rc != -1); + r->_size = grain * 2; + r->_addr = mmap(NULL, grain, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (r->_addr != MAP_FAILED) { + a2 = mmap(r->_addr + grain, grain, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_FIXED, fd, grain - n); + assert(a2 != MAP_FAILED); + r->p = r->_addr + grain - n; + if (IsWindows()) { + memset(r->p, 0, n); /* @see ftruncate() */ + } + } + } + rc = close(fd); + assert(rc != -1); + return r->p; +} diff --git a/libc/runtime/ringfree.c b/libc/runtime/ringfree.c new file mode 100644 index 00000000..22666052 --- /dev/null +++ b/libc/runtime/ringfree.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/runtime/ring.h" + +/** + * Frees ring buffer. + * + * @return 0 on success, or -1 w/ errno + */ +int ringfree(struct RingBuffer *r) { + if (r->p) { + r->p = NULL; + return munmap(r->_addr, r->_size); + } else { + return 0; + } +} diff --git a/libc/runtime/runtime.h b/libc/runtime/runtime.h new file mode 100644 index 00000000..4fab1cf1 --- /dev/null +++ b/libc/runtime/runtime.h @@ -0,0 +1,83 @@ +#ifndef COSMOPOLITAN_LIBC_RUNTIME_RUNTIME_H_ +#define COSMOPOLITAN_LIBC_RUNTIME_RUNTIME_H_ +#include "libc/dce.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § runtime ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +struct StackFrame { + struct StackFrame *next; + intptr_t addr; +}; + +typedef long jmp_buf[8] aligned(CACHELINE); + +extern int g_argc; /* CRT */ +extern char **g_argv; /* CRT */ +extern char **environ; /* CRT */ +extern unsigned long *g_auxv; /* CRT */ +extern jmp_buf g_winmain; /* CRT */ +extern char *program_invocation_name; /* RII */ +extern char *program_invocation_short_name; /* RII */ +extern uint64_t g_syscount; /* RII */ +extern const uint64_t kStartTsc; /* RII */ +extern const char kTmpPath[]; /* RII */ +extern const char kNtSystemDirectory[]; /* RII */ +extern const char kNtWindowsDirectory[]; /* RII */ +extern unsigned char _base[] aligned(PAGESIZE); /* αpε */ +extern char _ehead aligned(PAGESIZE); /* αpε */ +extern char _ereal; /* αpε */ +extern char __privileged_start; /* αpε */ +extern char __test_start; /* αpε */ +extern char __ro; /* αpε */ +extern char _etext aligned(PAGESIZE); /* αpε */ +extern char __piro_start; /* αpε */ +extern char _edata aligned(PAGESIZE); /* αpε */ +extern char __piro_end; /* αpε */ +extern char _end aligned(PAGESIZE); /* αpε */ +extern uint8_t __zip_start[]; /* αpε */ +extern uint8_t __zip_end[]; /* αpε */ + +long missingno(); +void mcount(void); +unsigned long getauxval(unsigned long); +void *mapanon(size_t) vallocesque attributeallocsize((1)); +int setjmp(jmp_buf) libcesque returnstwice paramsnonnull(); +void longjmp(jmp_buf, int) libcesque noreturn paramsnonnull(); +void exit(int) noreturn; +void quick_exit(int) noreturn; +void _exit(int) libcesque noreturn; +void _Exit(int) libcesque noreturn; +void abort(void) noreturn noinstrument forcealignargpointer; +void abort_(void) asm("abort") noreturn noinstrument privileged; +void panic(void) noreturn noinstrument privileged; +void triplf(void) noreturn noinstrument privileged; +int __cxa_atexit(void *, void *, void *) libcesque; +int atfork(void *, void *) libcesque; +int atexit(void (*)(void)) libcesque; +void free_s(void *) paramsnonnull() libcesque; +int close_s(int *) paramsnonnull() libcesque; +char *getenv(const char *) paramsnonnull() nosideeffect libcesque; +int putenv(char *) paramsnonnull(); +int setenv(const char *, const char *, int) paramsnonnull(); +int unsetenv(const char *); +int clearenv(void); +void __fast_math(void); +void fpreset(void); +void savexmm(void *); +void loadxmm(void *); +void peekall(void); +int issetugid(void); +void weakfree(void *) libcesque; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § runtime » optimizations ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define _exit(RC) _Exit(RC) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_RUNTIME_RUNTIME_H_ */ diff --git a/libc/runtime/runtime.mk b/libc/runtime/runtime.mk new file mode 100644 index 00000000..a34c41bd --- /dev/null +++ b/libc/runtime/runtime.mk @@ -0,0 +1,84 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ +# +# SYNOPSIS +# +# Cosmopolitan Runtime +# +# DESCRIPTION +# +# This package exports essential routines for userspace process +# initialization. + +PKGS += LIBC_RUNTIME + +LIBC_RUNTIME = $(LIBC_RUNTIME_A_DEPS) $(LIBC_RUNTIME_A) +LIBC_RUNTIME_ARTIFACTS += LIBC_RUNTIME_A +LIBC_RUNTIME_A = o/$(MODE)/libc/runtime/runtime.a +LIBC_RUNTIME_A_FILES := $(wildcard libc/runtime/*) +LIBC_RUNTIME_A_HDRS = $(filter %.h,$(LIBC_RUNTIME_A_FILES)) +LIBC_RUNTIME_A_SRCS_S = $(filter %.S,$(LIBC_RUNTIME_A_FILES)) +LIBC_RUNTIME_A_SRCS_C = $(filter %.c,$(LIBC_RUNTIME_A_FILES)) + +LIBC_RUNTIME_A_SRCS = \ + $(LIBC_RUNTIME_A_SRCS_S) \ + $(LIBC_RUNTIME_A_SRCS_C) + +LIBC_RUNTIME_A_OBJS = \ + $(LIBC_RUNTIME_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_RUNTIME_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_RUNTIME_A_SRCS_C:%.c=o/$(MODE)/%.o) + +LIBC_RUNTIME_A_CHECKS = \ + $(LIBC_RUNTIME_A).pkg \ + $(LIBC_RUNTIME_A_HDRS:%=o/$(MODE)/%.ok) + +LIBC_RUNTIME_A_DIRECTDEPS = \ + LIBC_BITS \ + LIBC_CALLS \ + LIBC_CONV \ + LIBC_ELF \ + LIBC_FMT \ + LIBC_NEXGEN32E \ + LIBC_NT_KERNELBASE \ + LIBC_RAND \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_SYSV_CALLS + +LIBC_RUNTIME_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_RUNTIME_A_DIRECTDEPS),$($(x)))) + +$(LIBC_RUNTIME_A): \ + libc/runtime/ \ + $(LIBC_RUNTIME_A).pkg \ + $(LIBC_RUNTIME_A_OBJS) + +$(LIBC_RUNTIME_A).pkg: \ + $(LIBC_RUNTIME_A_OBJS) \ + $(foreach x,$(LIBC_RUNTIME_A_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/libc/runtime/asan.greg.o \ +o/$(MODE)/libc/runtime/shadowargs.o \ +o/$(MODE)/libc/runtime/__stack_chk_fail.o \ +o/$(MODE)/libc/runtime/__stack_chk_guard.o: \ + OVERRIDE_COPTS += \ + $(NO_MAGIC) + +# @see ape/ape.s for tuning parameters that make this safe +o/$(MODE)/libc/runtime/winmain.greg.o: \ + DEFAULT_CPPFLAGS += \ + -DSTACK_FRAME_UNLIMITED + +LIBC_RUNTIME_LIBS = $(foreach x,$(LIBC_RUNTIME_ARTIFACTS),$($(x))) +LIBC_RUNTIME_SRCS = $(foreach x,$(LIBC_RUNTIME_ARTIFACTS),$($(x)_SRCS)) +LIBC_RUNTIME_HDRS = $(foreach x,$(LIBC_RUNTIME_ARTIFACTS),$($(x)_HDRS)) +LIBC_RUNTIME_BINS = $(foreach x,$(LIBC_RUNTIME_ARTIFACTS),$($(x)_BINS)) +LIBC_RUNTIME_CHECKS = $(foreach x,$(LIBC_RUNTIME_ARTIFACTS),$($(x)_CHECKS)) +LIBC_RUNTIME_OBJS = $(foreach x,$(LIBC_RUNTIME_ARTIFACTS),$($(x)_OBJS)) +LIBC_RUNTIME_TESTS = $(foreach x,$(LIBC_RUNTIME_ARTIFACTS),$($(x)_TESTS)) +$(LIBC_RUNTIME_OBJS): $(BUILD_FILES) libc/runtime/runtime.mk + +.PHONY: o/$(MODE)/libc/runtime +o/$(MODE)/libc/runtime: $(LIBC_RUNTIME_CHECKS) diff --git a/libc/runtime/stackchkfail.c b/libc/runtime/stackchkfail.c new file mode 100644 index 00000000..94a7b3eb --- /dev/null +++ b/libc/runtime/stackchkfail.c @@ -0,0 +1,61 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/config.h" +#include "libc/bits/bits.h" +#include "libc/bits/pushpop.h" +#include "libc/nt/process.h" +#include "libc/runtime/internal.h" +#include "libc/runtime/missioncritical.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/nr.h" + +#define STACK_SMASH_MESSAGE "stack smashed\n" + +/** + * Aborts program under enemy fire to avoid being taken alive. + */ +void __stack_chk_fail(void) { + if (!IsWindows()) { + const char *const msg = STACK_SMASH_MESSAGE; + const size_t len = pushpop(sizeof(STACK_SMASH_MESSAGE) - 1); + if (!IsMetal()) { + unsigned ax; + asm volatile("syscall" + : "=a"(ax) + : "0"(__NR_write), "D"(pushpop(STDERR_FILENO)), "S"(msg), + "d"(len) + : "rcx", "r11", "cc", "memory"); + asm volatile("syscall" + : "=a"(ax) + : "0"(__NR_exit), "D"(pushpop(88)) + : "rcx", "r11", "cc", "memory"); + } + short(*ttys)[4] = (short(*)[4])XLM(BIOS_DATA_AREA); + unsigned long si; + unsigned cx; + asm volatile("rep outsb" + : "=S"(si), "=c"(cx) + : "0"(msg), "1"(len), "d"((*ttys)[1 /*COM2*/]) + : "memory"); + triplf(); + } + NT_TERMINATE_PROCESS(); + for (;;) TerminateProcess(GetCurrentProcess(), 42); +} diff --git a/libc/runtime/stackchkfaillocal.c b/libc/runtime/stackchkfaillocal.c new file mode 100644 index 00000000..9da0b7d4 --- /dev/null +++ b/libc/runtime/stackchkfaillocal.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/internal.h" + +void __stack_chk_fail_local(void) { __stack_chk_fail(); } diff --git a/libc/runtime/startmain.S b/libc/runtime/startmain.S new file mode 100644 index 00000000..7571e453 --- /dev/null +++ b/libc/runtime/startmain.S @@ -0,0 +1,148 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/macros.h" +#include "libc/notice.inc" +#include "libc/runtime/internal.h" +#include "libc/sysv/consts/map.h" +#include "libc/dce.h" +#include "libc/runtime/mappings.h" +#include "libc/sysv/consts/prot.h" +.text.startup +.yoink __FILE__ + +/ Cosmopolitan process entrypoint. +/ +/ @param r12 is argc +/ @param r13 is argv +/ @param r14 is environ +/ @param r15 is auxv +/ @noreturn +__executive: + .frame0 + ezlea _base,bx + +#ifdef __FAST_MATH__ + call __fast_math +#endif + call _init +#if IsModeDbg() + call _init # _init() is idempotent +#endif + +/* +#if !IsTiny() +/ “Memory obfuscation for glibc, not for we” +/ +/ 64kb stack w/ 4kb guard alongside tuning in libc/integral/c.inc +/ e.g. -Werror=frame-larger-than=4096 is intended to guarantee no +/ stack overflow possible. We like malloc and only cleverly avoid +/ its use at the lowest levels of the runtime stack, without MMU. +/ We like this practicee because it's how Google runs production. + mov $kStackCeiling-STACKSIZE,%rdi + mov $STACKSIZE,%esi + mov $PROT_READ|PROT_WRITE,%edx + mov MAP_ANONYMOUS,%ecx + or MAP_FIXED,%ecx + or MAP_PRIVATE,%ecx + mov $-1,%r8d + xor %r9d,%r9d + call mmap + cmp $-1,%eax + je abort + lea STACKSIZE(%rax),%rsp + xor %ebp,%ebp + mov %rax,%rdi + mov $PAGESIZE,%esi + mov $PROT_NONE,%edx + call mprotect + cmp $-1,%eax + je abort +#endif +*/ + + orl $RUNSTATE_INITIALIZED,g_runstate(%rip) + ezlea __init_array_start,ax # static ctors in forward order + .weak __init_array_start # could be called multiple times + ezlea __init_array_end,cx # idempotency recommended + .weak __init_array_end # @see ape/ape.lds +1: cmp %rax,%rcx + je 2f + push %rax + push %rcx + call *(%rax) + pop %rcx + pop %rax + add $8,%rax + jmp 1b +2: nop +#if !IsTrustworthy() + mov $PROT_READ,%edi + call __piro +#endif + mov %r12,%rdi + mov %r13,%rsi + mov %r14,%rdx + .weak main + call main + mov %eax,%edi + call exit + .endfn __executive,weak,hidden + +#ifdef __PG__ +/ Enables plaintext function tracing if --ftrace flag passed. +/ +/ The --ftrace CLI arg is removed before main() is called. This +/ code is intended for diagnostic purposes and assumes binaries +/ are trustworthy and stack isn't corrupted. Logging plain text +/ allows program structure to easily be visualized and hotspots +/ identified w/ sed | sort | uniq -c | sort. A compressed trace +/ can be made by appending --ftrace 2>&1 | gzip -4 >trace.gz to +/ the CLI arguments. Have fun. +/ +/ @see libc/runtime/ftrace.greg.c +/ @see libc/crt/crt.S + .init.start 800,_init_ftrace + push %rdi + push %rsi + xor %edx,%edx + loadstr "--ftrace",di + xor %ecx,%ecx +0: inc %ecx + mov (%r13,%rcx,8),%rsi + test %edx,%edx + jz 1f + mov %rsi,-8(%r13,%rcx,8) +1: test %rsi,%rsi + jz 2f + test %edx,%edx + jnz 0b + call tinystrcmp + test %eax,%eax + setz %dl + jmp 0b +2: sub %rdx,%r12 + test %edx,%edx + jz 2f + call ftrace_init +2: pop %rsi + pop %rdi + .init.end 800,_init_ftrace +#endif /* -pg */ diff --git a/libc/runtime/symbolic.h b/libc/runtime/symbolic.h new file mode 100644 index 00000000..8a6280a8 --- /dev/null +++ b/libc/runtime/symbolic.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_RUNTIME_SYMBOLIC_H_ +#define COSMOPOLITAN_LIBC_RUNTIME_SYMBOLIC_H_ + +#ifdef __ASSEMBLER__ +/* clang-format off */ +#define SYMBOLIC(NAME) NAME(%rip) +#define LITERALLY(NAME) $NAME +/* clang-format on */ +#else +#define SYMBOLIC(NAME) NAME +#define LITERALLY(NAME) NAME +#endif + +#endif /* COSMOPOLITAN_LIBC_RUNTIME_SYMBOLIC_H_ */ diff --git a/libc/runtime/symbols.h b/libc/runtime/symbols.h new file mode 100644 index 00000000..552ba5b0 --- /dev/null +++ b/libc/runtime/symbols.h @@ -0,0 +1,59 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#ifndef COSMOPOLITAN_LIBC_SYMBOLS_H_ +#define COSMOPOLITAN_LIBC_SYMBOLS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +#include "libc/elf/elf.h" +#include "libc/runtime/ezmap.h" +COSMOPOLITAN_C_START_ + +struct Symbol { + unsigned addr_rva; + unsigned name_rva; +}; + +struct SymbolTable { + union { + struct MappedFile mf; + struct { + int64_t fd; + struct Elf64_Ehdr *elf; + size_t elfsize; + }; + }; + size_t scratch; + size_t count; + intptr_t addr_base; + intptr_t addr_end; + const char *name_base; + struct Symbol symbols[]; +}; + +struct SymbolTable *getsymboltable(void); +const char *findcombinary(void); +const char *finddebugbinary(void); +struct SymbolTable *opensymboltable(const char *) nodiscard; +int closesymboltable(struct SymbolTable **); +const struct Symbol *bisectsymbol(struct SymbolTable *, intptr_t, int64_t *); +const char *getsymbolname(struct SymbolTable *, const struct Symbol *); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYMBOLS_H_ */ diff --git a/libc/runtime/sysconf.c b/libc/runtime/sysconf.c new file mode 100644 index 00000000..ec01c7de --- /dev/null +++ b/libc/runtime/sysconf.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/sysconf.h" + +/** + * Returns configuration value about system. + * @param thing can be _SC_XXX + */ +long(sysconf)(int thing) { return __sysconf(thing); } diff --git a/libc/runtime/sysconf.h b/libc/runtime/sysconf.h new file mode 100644 index 00000000..b7d7b6f9 --- /dev/null +++ b/libc/runtime/sysconf.h @@ -0,0 +1,37 @@ +#ifndef COSMOPOLITAN_LIBC_RUNTIME_SYSCONF_H_ +#define COSMOPOLITAN_LIBC_RUNTIME_SYSCONF_H_ +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/auxv.h" + +#define _SC_ARG_MAX 0 +#define _SC_CLK_TCK 2 +#define _SC_PAGESIZE 30 +#define _SC_PAGE_SIZE 30 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +long sysconf(int); + +#define sysconf(X) __sysconf(X) + +forceinline long __sysconf(int thing) { + switch (thing) { + case _SC_ARG_MAX: + return ARG_MAX; + case _SC_CLK_TCK: { + extern const long __AT_CLKTCK asm("AT_CLKTCK"); + long res = getauxval(__AT_CLKTCK); + if (!res) res = 100; + return res; + } + case _SC_PAGESIZE: + return FRAMESIZE; + default: + return -1; + } +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_RUNTIME_SYSCONF_H_ */ diff --git a/libc/runtime/unsetenv.c b/libc/runtime/unsetenv.c new file mode 100644 index 00000000..455e1c04 --- /dev/null +++ b/libc/runtime/unsetenv.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +/** + * Removes environment variable. + */ +int unsetenv(const char *name) { + if (isempty(name) || strchr(name, '=')) return einval(); + if (environ) { + char **ep = environ; + size_t removed = 0; + size_t namelen = strlen(name); + do { + if (*ep && strncmp(*ep, name, namelen) == 0 && (*ep)[namelen] == '=') { + --removed; + } else if (removed) { + ep[removed] = *ep; + } + } while (*ep++); + } + return 0; +} diff --git a/libc/runtime/weakfree.S b/libc/runtime/weakfree.S new file mode 100644 index 00000000..5c4a3319 --- /dev/null +++ b/libc/runtime/weakfree.S @@ -0,0 +1,36 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Thunks free() if it's linked, otherwise do nothing. +/ +/ @see free_s() which can ignore static/stack and clear refs +weakfree: + push %rbp + mov %rsp,%rbp + .weak free + ezlea free,ax + test %rax,%rax + jz 1f + call free +1: pop %rbp + ret + .endfn weakfree,globl diff --git a/libc/runtime/winmain.greg.c b/libc/runtime/winmain.greg.c new file mode 100644 index 00000000..3bd64bc4 --- /dev/null +++ b/libc/runtime/winmain.greg.c @@ -0,0 +1,62 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/pushpop.h" +#include "libc/dce.h" +#include "libc/nt/console.h" +#include "libc/nt/enum/loadlibrarysearch.h" +#include "libc/nt/runtime.h" +#include "libc/runtime/getdosenviron.h" +#include "libc/runtime/internal.h" + +static void LoadFasterAndPreventHijacking(void) { + unsigned wrote; + if (!SetDefaultDllDirectories(kNtLoadLibrarySearchSearchSystem32)) { + WriteFile(GetStdHandle(kNtStdErrorHandle), "nodll\n", 6, &wrote, NULL); + ExitProcess(1); + } +} + +noreturn textwindows int WinMain(void *hInstance, void *hPrevInstance, + const char *lpCmdLine, int nCmdShow) { + int i, count; + const char16_t *cmd16, *env16; + long auxarray[][2] = {{pushpop(0L), pushpop(0L)}}; + char envblock[ENV_MAX], *envarray[512], argblock[ARG_MAX], *argarray[512]; + LoadFasterAndPreventHijacking(); + *(/*unconst*/ int *)&__hostos = pushpop(WINDOWS); + cmd16 = GetCommandLine(); + env16 = GetEnvironmentStrings(); + count = getdosargv(cmd16, argblock, ARG_MAX, argarray, 512); + for (i = 0; argarray[0][i]; ++i) { + if (argarray[0][i] == '\\') argarray[0][i] = '/'; + } + getdosenviron(env16, envblock, ENV_MAX, envarray, 512); + FreeEnvironmentStrings(env16); + register int argc asm("r12") = count; + register char **argv asm("r13") = argarray; + register char **envp asm("r14") = envarray; + register long(*auxv)[2] asm("r15") = auxarray; + asm volatile("jmp\t__executive" + : /* no outputs */ + : "r"(argc), "r"(argv), "r"(envp), "r"(auxv) + : "memory", "cc"); + unreachable; +} diff --git a/libc/sock/accept-nt.c b/libc/sock/accept-nt.c new file mode 100644 index 00000000..0fb01eac --- /dev/null +++ b/libc/sock/accept-nt.c @@ -0,0 +1,53 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/internal.h" +#include "libc/nt/files.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sysv/consts/fio.h" +#include "libc/sysv/consts/sock.h" +#include "libc/sysv/errfuns.h" + +textwindows int accept$nt(struct Fd *fd, void *addr, uint32_t *addrsize, + int flags) { + int client; + uint32_t yes; + assert(fd->kind == kFdSocket); + if ((client = createfd()) == -1) return -1; + if ((g_fds.p[client].handle = WSAAccept(fd->handle, addr, (int32_t *)addrsize, + NULL, NULL)) != -1) { + if (flags & SOCK_CLOEXEC) { + SetHandleInformation(g_fds.p[client].handle, kNtHandleFlagInherit, 0); + } + if (flags & SOCK_NONBLOCK) { + yes = 1; + if (__ioctlsocket$nt(g_fds.p[client].handle, FIONBIO, &yes) == -1) { + __closesocket$nt(g_fds.p[client].handle); + return winsockerr(); + } + } + g_fds.p[client].kind = kFdSocket; + g_fds.p[client].flags = flags; + return client; + } else { + return winsockerr(); + } +} diff --git a/libc/sock/accept-sysv.c b/libc/sock/accept-sysv.c new file mode 100644 index 00000000..51de1e49 --- /dev/null +++ b/libc/sock/accept-sysv.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/sock/internal.h" + +int accept$sysv(int server, void *addr, uint32_t *addrsize) { + int client; + if ((client = __accept$sysv(server, addr, addrsize)) != -1 && IsBsd()) { + sockaddr2linux(addr); + } + return client; +} diff --git a/libc/sock/accept.c b/libc/sock/accept.c new file mode 100644 index 00000000..46b6e995 --- /dev/null +++ b/libc/sock/accept.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/sysv/errfuns.h" + +/** + * Creates client socket file descriptor for incoming connection. + * + * @param fd is the server socket file descriptor + * @param out_addr will receive the remote address + * @param inout_addrsize provides and receives addr's byte length + * @return client fd which needs close(), or -1 w/ errno + * @asyncsignalsafe + */ +int accept(int fd, void *out_addr, uint32_t *inout_addrsize) { + if (!IsWindows()) { + return accept$sysv(fd, out_addr, inout_addrsize); + } else if (isfdkind(fd, kFdSocket)) { + return accept$nt(&g_fds.p[fd], out_addr, inout_addrsize, 0); + } else { + return ebadf(); + } +} diff --git a/libc/sock/accept4-sysv.c b/libc/sock/accept4-sysv.c new file mode 100644 index 00000000..da691f33 --- /dev/null +++ b/libc/sock/accept4-sysv.c @@ -0,0 +1,48 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" + +#define __NR_accept4_linux 0x0120 /* rhel5:enosysevil */ + +int accept4$sysv(int server, void *addr, uint32_t *addrsize, int flags) { + static bool once, demodernize; + int olderr, client; + if (!flags || demodernize) goto TriedAndTrue; + olderr = errno; + client = __accept4$sysv(server, addr, addrsize, flags); + if (client == -1 && errno == ENOSYS) { + errno = olderr; + TriedAndTrue: + client = fixupnewsockfd$sysv(__accept$sysv(server, addr, addrsize), flags); + } else if (SupportsLinux() && !once) { + once = true; + if (client == __NR_accept4_linux) { + demodernize = true; + goto TriedAndTrue; + } + } + if (client != -1 && IsBsd()) { + sockaddr2linux(addr); + } + return client; +} diff --git a/libc/sock/accept4.c b/libc/sock/accept4.c new file mode 100644 index 00000000..a428ba3e --- /dev/null +++ b/libc/sock/accept4.c @@ -0,0 +1,44 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/sysv/errfuns.h" + +/** + * Creates client socket file descriptor for incoming connection. + * + * @param fd is the server socket file descriptor + * @param out_addr will receive the remote address + * @param inout_addrsize provides and receives out_addr's byte length + * @param flags can have SOCK_{CLOEXEC,NONBLOCK}, which may apply to + * both the newly created socket and the server one + * @return client fd which needs close(), or -1 w/ errno + */ +int accept4(int fd, void *out_addr, uint32_t *inout_addrsize, int flags) { + if (!IsWindows()) { + return accept4$sysv(fd, out_addr, inout_addrsize, flags); + } else if (isfdkind(fd, kFdSocket)) { + return accept$nt(&g_fds.p[fd], out_addr, inout_addrsize, flags); + } else { + return ebadf(); + } +} diff --git a/libc/sock/bind-nt.c b/libc/sock/bind-nt.c new file mode 100644 index 00000000..9d1d2ee5 --- /dev/null +++ b/libc/sock/bind-nt.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/internal.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sysv/errfuns.h" + +/** + * Assigns local address and port number to socket. + * + * @param fd is the file descriptor returned by socket() + * @param addr is usually the binary-encoded ip:port on which to listen + * @param addrsize is the byte-length of addr's true polymorphic form + * @return socket file descriptor or -1 w/ errno + * @error ENETDOWN, EPFNOSUPPORT, etc. + * @asyncsignalsafe + */ +textwindows int bind$nt(struct Fd *fd, const void *addr, uint32_t addrsize) { + assert(fd->kind == kFdSocket); + if (__bind$nt(fd->handle, addr, addrsize) != -1) { + return 0; + } else { + return winsockerr(); + } +} diff --git a/libc/sock/bind.c b/libc/sock/bind.c new file mode 100644 index 00000000..8fa42a76 --- /dev/null +++ b/libc/sock/bind.c @@ -0,0 +1,58 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +/** + * Assigns local address and port number to socket. + * + * @param fd is the file descriptor returned by socket() + * @param addr is usually the binary-encoded ip:port on which to listen + * @param addrsize is the byte-length of addr's true polymorphic form + * @return socket file descriptor or -1 w/ errno + * @error ENETDOWN, EPFNOSUPPORT, etc. + * @asyncsignalsafe + */ +int bind(int fd, const void *addr, uint32_t addrsize) { + if (addrsize == sizeof(struct sockaddr_in)) { + if (!IsWindows()) { + if (!IsBsd()) { + return bind$sysv(fd, addr, addrsize); + } else { + struct sockaddr_in$bsd addr2; + static_assert(sizeof(struct sockaddr_in) == + sizeof(struct sockaddr_in$bsd)); + memcpy(&addr2, addr, sizeof(struct sockaddr_in)); + sockaddr2bsd(&addr2); + return bind$sysv(fd, &addr2, addrsize); + } + } else if (isfdkind(fd, kFdSocket)) { + return bind$nt(&g_fds.p[fd], addr, addrsize); + } else { + return ebadf(); + } + } else { + return einval(); + } +} diff --git a/libc/sock/closesocket-nt.c b/libc/sock/closesocket-nt.c new file mode 100644 index 00000000..f835c00c --- /dev/null +++ b/libc/sock/closesocket-nt.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/calls/internal.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sysv/errfuns.h" + +textwindows int closesocket$nt(int fd) { + int rc; + if (!isfdkind(fd, kFdSocket)) return ebadf(); + rc = __closesocket$nt(g_fds.p[fd].handle) ? 0 : winsockerr(); + removefd(fd); + return rc; +} diff --git a/libc/sock/connect-nt.c b/libc/sock/connect-nt.c new file mode 100644 index 00000000..628d22a6 --- /dev/null +++ b/libc/sock/connect-nt.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/internal.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sysv/errfuns.h" + +textwindows int connect$nt(struct Fd *fd, const void *addr, uint32_t addrsize) { + assert(fd->kind == kFdSocket); + return winsockblock( + fd->handle, FD_CONNECT_BIT, + WSAConnect(fd->handle, addr, addrsize, NULL, NULL, NULL, NULL)); +} diff --git a/libc/sock/connect-sysv.c b/libc/sock/connect-sysv.c new file mode 100644 index 00000000..b8b188bd --- /dev/null +++ b/libc/sock/connect-sysv.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/sock/internal.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +int connect$sysv(int fd, const void *addr, uint32_t addrsize) { + if (addrsize != sizeof(struct sockaddr_in)) return einval(); + if (!IsBsd()) { + return __connect$sysv(fd, addr, addrsize); + } else { + struct sockaddr_in$bsd addr2; + static_assert(sizeof(struct sockaddr_in) == sizeof(struct sockaddr_in$bsd)); + memcpy(&addr2, addr, sizeof(struct sockaddr_in)); + sockaddr2bsd(&addr2); + return connect$sysv(fd, &addr2, addrsize); + } +} diff --git a/libc/sock/connect.c b/libc/sock/connect.c new file mode 100644 index 00000000..1c3a6bf3 --- /dev/null +++ b/libc/sock/connect.c @@ -0,0 +1,44 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/sysv/errfuns.h" + +/** + * Connects socket to remote end. + * + * ProTip: Connectionless sockets, e.g. UDP, can be connected too. The + * benefit is not needing to specify the remote address on each send. It + * also means getsockname() can be called to retrieve routing details. + * + * @return 0 on success or -1 w/ errno + * @asyncsignalsafe + */ +int connect(int fd, const void *addr, uint32_t addrsize) { + if (!IsWindows()) { + return connect$sysv(fd, addr, addrsize); + } else if (isfdkind(fd, kFdSocket)) { + return connect$nt(&g_fds.p[fd], addr, addrsize); + } else { + return ebadf(); + } +} diff --git a/libc/sock/fixupnewsockfd.c b/libc/sock/fixupnewsockfd.c new file mode 100644 index 00000000..fe965986 --- /dev/null +++ b/libc/sock/fixupnewsockfd.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/calls/internal.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/sock.h" + +/** + * Applies non-atomic file descriptor fixups on XNU or ancient Linux. + * + * @param fd of -1 means no-op + */ +int fixupnewsockfd$sysv(int fd, int flags) { + return fixupnewfd$sysv(fd, (((flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0) | + ((flags & SOCK_NONBLOCK) ? O_NONBLOCK : 0))); +} diff --git a/libc/sock/getpeername-nt.c b/libc/sock/getpeername-nt.c new file mode 100644 index 00000000..b481b9fb --- /dev/null +++ b/libc/sock/getpeername-nt.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sysv/errfuns.h" + +textwindows int getpeername$nt(struct Fd *fd, void *out_addr, + uint32_t *out_addrsize) { + assert(fd->kind == kFdSocket); + if (__getpeername$nt(fd->handle, out_addr, out_addrsize) != -1) { + return 0; + } else { + return winsockerr(); + } +} diff --git a/libc/sock/getpeername-sysv.c b/libc/sock/getpeername-sysv.c new file mode 100644 index 00000000..9bcb9379 --- /dev/null +++ b/libc/sock/getpeername-sysv.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/sock/internal.h" + +int getpeername$sysv(int fd, void *out_addr, uint32_t *out_addrsize) { + int rc = __getpeername$sysv(fd, out_addr, out_addrsize); + if (rc != -1 && IsBsd()) { + sockaddr2linux(out_addr); + } + return rc; +} diff --git a/libc/sock/getpeername.c b/libc/sock/getpeername.c new file mode 100644 index 00000000..08fd89f2 --- /dev/null +++ b/libc/sock/getpeername.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/sysv/errfuns.h" + +/** + * Returns details about remote end of connected socket. + * @return 0 on success or -1 w/ errno + * @see getsockname() + */ +int getpeername(int fd, void *out_addr, uint32_t *out_addrsize) { + if (!IsWindows()) { + return getpeername$sysv(fd, out_addr, out_addrsize); + } else if (isfdkind(fd, kFdSocket)) { + return getpeername$nt(&g_fds.p[fd], out_addr, out_addrsize); + } else { + return ebadf(); + } +} diff --git a/libc/sock/getsockname-nt.c b/libc/sock/getsockname-nt.c new file mode 100644 index 00000000..3e85749e --- /dev/null +++ b/libc/sock/getsockname-nt.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sysv/errfuns.h" + +textwindows int getsockname$nt(struct Fd *fd, void *out_addr, + uint32_t *out_addrsize) { + assert(fd->kind == kFdSocket); + if (__getsockname$nt(fd->handle, out_addr, out_addrsize) != -1) { + return 0; + } else { + return winsockerr(); + } +} diff --git a/libc/sock/getsockname-sysv.c b/libc/sock/getsockname-sysv.c new file mode 100644 index 00000000..36f0848e --- /dev/null +++ b/libc/sock/getsockname-sysv.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/sock/internal.h" + +int getsockname$sysv(int fd, void *out_addr, uint32_t *out_addrsize) { + int rc = __getsockname$sysv(fd, out_addr, out_addrsize); + if (rc != -1 && IsBsd()) { + sockaddr2linux(out_addr); + } + return rc; +} diff --git a/libc/sock/getsockname.c b/libc/sock/getsockname.c new file mode 100644 index 00000000..7b6b9e4a --- /dev/null +++ b/libc/sock/getsockname.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/sysv/errfuns.h" + +/** + * Returns details about network interface kernel granted socket. + * @return 0 on success or -1 w/ errno + * @see getpeername() + */ +int getsockname(int fd, void *out_addr, uint32_t *out_addrsize) { + if (!IsWindows()) { + return getsockname$sysv(fd, out_addr, out_addrsize); + } else if (isfdkind(fd, kFdSocket)) { + return getsockname$nt(&g_fds.p[fd], out_addr, out_addrsize); + } else { + return ebadf(); + } +} diff --git a/libc/sock/getsockopt-nt.c b/libc/sock/getsockopt-nt.c new file mode 100644 index 00000000..4a9feb58 --- /dev/null +++ b/libc/sock/getsockopt-nt.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/internal.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sysv/errfuns.h" + +textwindows int getsockopt$nt(struct Fd *fd, int level, int optname, + void *out_opt_optval, uint32_t *out_optlen) { + /* TODO(jart): Use WSAIoctl? */ + assert(fd->kind == kFdSocket); + if (__getsockopt$nt(fd->handle, level, optname, out_opt_optval, out_optlen) != + -1) { + return 0; + } else { + return winsockerr(); + } +} diff --git a/libc/sock/getsockopt.c b/libc/sock/getsockopt.c new file mode 100644 index 00000000..db9096bc --- /dev/null +++ b/libc/sock/getsockopt.c @@ -0,0 +1,48 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/sysv/errfuns.h" + +/** + * Retrieves socket setting. + * + * @param level can be SOL_SOCKET, IPPROTO_TCP, etc. + * @param optname can be SO_{REUSE{PORT,ADDR},KEEPALIVE,etc.} etc. + * @return 0 on success, or -1 w/ errno + * @error ENOPROTOOPT for unknown (level,optname) + * @see libc/sysv/consts.sh for tuning catalogue + * @see setsockopt() + */ +int getsockopt(int fd, int level, int optname, void *out_opt_optval, + uint32_t *out_optlen) { + if (!level || !optname) return enoprotoopt(); /* our sysvconsts definition */ + if (optname == -1) return 0; /* our sysvconsts definition */ + if (!IsWindows()) { + return getsockopt$sysv(fd, level, optname, out_opt_optval, out_optlen); + } else if (isfdkind(fd, kFdSocket)) { + return getsockopt$nt(&g_fds.p[fd], level, optname, out_opt_optval, + out_optlen); + } else { + return ebadf(); + } +} diff --git a/libc/sock/inet_ntop.c b/libc/sock/inet_ntop.c new file mode 100644 index 00000000..cd776e06 --- /dev/null +++ b/libc/sock/inet_ntop.c @@ -0,0 +1,53 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/fmt/fmt.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/sysv/errfuns.h" +#include "libc/sysv/consts/af.h" + +/** + * Formats internet address to string. + * + * @param af can be AF_INET + * @param src is the binary-encoded address, e.g. &addr->sin_addr + * @param dst is the output string buffer + * @param size is bytes in dst, which needs 16+ for IPv4 + * @return dst on success or NULL w/ errno + */ +const char *inet_ntop(int af, const void *src, char *dst, uint32_t size) { + if (src) { + if (af == AF_INET) { + unsigned char *p = (unsigned char *)src; + if (snprintf(dst, size, "%hhu.%hhu.%hhu.%hhu", p[0], p[1], p[2], p[3]) < + size) { + return dst; + } else { + enospc(); + } + } else { + eafnosupport(); + } + } else { + einval(); + } + if (size) dst[0] = '\0'; + return NULL; +} diff --git a/libc/sock/inet_pton.c b/libc/sock/inet_pton.c new file mode 100644 index 00000000..46041b74 --- /dev/null +++ b/libc/sock/inet_pton.c @@ -0,0 +1,48 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/fmt/fmt.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/sysv/errfuns.h" +#include "libc/sysv/consts/af.h" +#include "libc/sysv/consts/inaddr.h" + +/** + * Converts internet address string to binary. + * + * @param af can be AF_INET + * @param src is the ASCII-encoded address + * @param dst is where the binary-encoded net-order address goes + * @return 1 on success, 0 on src malformed, or -1 w/ errno + */ +int inet_pton(int af, const char *src, void *dst) { + if (af == AF_INET) { + unsigned char *p = (unsigned char *)dst; + if (sscanf(src, "%hhu.%hhu.%hhu.%hhu", &p[0], &p[1], &p[2], &p[3]) == 4) { + return 1; + } else { + *(uint32_t *)dst = htonl(INADDR_TESTNET3); + return 0; + } + } else { + *(uint32_t *)dst = htonl(INADDR_TESTNET3); + return eafnosupport(); + } +} diff --git a/libc/sock/internal.h b/libc/sock/internal.h new file mode 100644 index 00000000..089c43bb --- /dev/null +++ b/libc/sock/internal.h @@ -0,0 +1,148 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#ifndef COSMOPOLITAN_LIBC_SOCK_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_SOCK_INTERNAL_H_ +#include "libc/bits/bits.h" +#include "libc/nt/winsock.h" +#include "libc/sock/sock.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define FD_READ (1 << FD_READ_BIT) +#define FD_READ_BIT 0 +#define FD_WRITE (1 << FD_WRITE_BIT) +#define FD_WRITE_BIT 1 +#define FD_OOB (1 << FD_OOB_BIT) +#define FD_OOB_BIT 2 +#define FD_ACCEPT (1 << FD_ACCEPT_BIT) +#define FD_ACCEPT_BIT 3 +#define FD_CONNECT (1 << FD_CONNECT_BIT) +#define FD_CONNECT_BIT 4 +#define FD_CLOSE (1 << FD_CLOSE_BIT) +#define FD_CLOSE_BIT 5 + +struct Fd; +struct iovec; +struct timeval; + +struct sockaddr$bsd { + uint8_t sa_len; /* « different type */ + uint8_t sa_family; /* « different type */ + char sa_data[14]; +}; + +struct sockaddr_in$bsd { + uint8_t sin_len; /* « different type */ + uint8_t sin_family; /* « different type */ + uint16_t sin_port; + struct in_addr sin_addr; + uint8_t sin_zero[8]; +}; + +struct msghdr$bsd { + void *msg_name; + uint32_t msg_namelen; + struct iovec *msg_iov; + uint32_t msg_iovlen; /* « different type */ + void *msg_control; + uint64_t msg_controllen; + uint32_t msg_flags; /* « different type */ +}; + +int32_t __accept$sysv(int32_t, void *, uint32_t *) nodiscard hidden; +int32_t __accept4$sysv(int32_t, void *, uint32_t *, int) nodiscard hidden; +int32_t __connect$sysv(int32_t, const void *, uint32_t) hidden; +int32_t __socket$sysv(int32_t, int32_t, int32_t) hidden; +int32_t __getsockname$sysv(int32_t, void *, uint32_t *) hidden; +int32_t __getpeername$sysv(int32_t, void *, uint32_t *) hidden; + +int32_t select$sysv(int32_t, fd_set *, fd_set *, fd_set *, struct timeval *); +int32_t setsockopt$sysv(int32_t, int32_t, int32_t, const void *, + uint32_t) hidden; +int32_t accept4$sysv(int32_t, void *, uint32_t *, int) nodiscard hidden; +int32_t accept$sysv(int32_t, void *, uint32_t *) hidden; +int32_t bind$sysv(int32_t, const void *, uint32_t) hidden; +int32_t connect$sysv(int32_t, const void *, uint32_t) hidden; +int32_t getsockopt$sysv(int32_t, int32_t, int32_t, void *, uint32_t *) hidden; +int32_t listen$sysv(int32_t, int32_t) hidden; +int32_t getsockname$sysv(int32_t, void *, uint32_t *) hidden; +int32_t getpeername$sysv(int32_t, void *, uint32_t *) hidden; +int32_t poll$sysv(struct pollfd *, uint64_t, signed) hidden; +int32_t shutdown$sysv(int32_t, int32_t) hidden; +int32_t socket$sysv(int32_t, int32_t, int32_t) hidden; +int64_t readv$sysv(int32_t, const struct iovec *, int32_t) hidden; +int64_t writev$sysv(int32_t, const struct iovec *, int32_t) hidden; +ssize_t recvfrom$sysv(int, void *, size_t, int, void *, uint32_t *) hidden; +ssize_t sendto$sysv(int, const void *, size_t, int, const void *, + uint32_t) hidden; + +int poll$nt(struct pollfd *, uint64_t, int32_t) hidden; +int getsockopt$nt(struct Fd *, int, int, void *, uint32_t *) hidden; +int getsockname$nt(struct Fd *, void *, uint32_t *) hidden; +int getpeername$nt(struct Fd *, void *, uint32_t *) hidden; +int listen$nt(struct Fd *, int) hidden; +int connect$nt(struct Fd *, const void *, uint32_t) hidden; +int bind$nt(struct Fd *, const void *, uint32_t); +int accept$nt(struct Fd *, void *, uint32_t *, int) hidden; +int closesocket$nt(int) hidden; +int socket$nt(int, int, int) hidden; + +size_t iovec2nt(struct iovec$nt[hasatleast 16], const struct iovec *, + size_t) hidden; +ssize_t sendto$nt(struct Fd *, const struct iovec *, size_t, uint32_t, void *, + uint32_t *) hidden; +ssize_t recvfrom$nt(struct Fd *, const struct iovec *, size_t, uint32_t, void *, + uint32_t *) hidden; + +int64_t winsockerr(void) nocallback hidden; +int fixupnewsockfd$sysv(int, int) hidden; +ssize_t WinSendRecv(int64_t, void *, size_t, uint32_t, struct sockaddr *, + uint32_t *, bool) hidden; +int64_t winsockblock(int64_t, unsigned, int64_t) hidden; + +/** + * Converts sockaddr (Linux/Windows) → sockaddr$bsd (XNU/BSD). + */ +forceinline void sockaddr2bsd(void *saddr) { + uint8_t *p; + uint16_t fam; + if (saddr) { + p = saddr; + fam = read16le(p); + p[0] = sizeof(struct sockaddr_in$bsd); + p[1] = fam; + } +} + +/** + * Converts sockaddr_in$bsd (XNU/BSD) → sockaddr (Linux/Windows). + */ +forceinline void sockaddr2linux(void *saddr) { + uint8_t *p, fam; + if (saddr) { + p = saddr; + fam = p[1]; + WRITE16LE(p, fam); + } +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SOCK_INTERNAL_H_ */ diff --git a/libc/sock/iovec2nt.c b/libc/sock/iovec2nt.c new file mode 100644 index 00000000..5821bfd9 --- /dev/null +++ b/libc/sock/iovec2nt.c @@ -0,0 +1,45 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/struct/iovec.h" +#include "libc/macros.h" +#include "libc/sock/internal.h" +#include "libc/sysv/consts/iov.h" + +/** + * Converts I/O vector from System Five to WIN32 ABI. + * + * @return effective iovlen + * @see IOV_MAX + */ +textwindows size_t iovec2nt(struct iovec$nt iovnt[hasatleast 16], + const struct iovec *iov, size_t iovlen) { + size_t i, limit; + for (limit = 0x7ffff000, i = 0; i < MIN(16, iovlen); ++i) { + iovnt[i].buf = iov[i].iov_base; + if (iov[i].iov_len < limit) { + limit -= (iovnt[i].len = iov[i].iov_len); + } else { + iovnt[i].len = limit; + break; + } + } + return i; +} diff --git a/libc/sock/ipclassify.h b/libc/sock/ipclassify.h new file mode 100644 index 00000000..69c9db2b --- /dev/null +++ b/libc/sock/ipclassify.h @@ -0,0 +1,68 @@ +#ifndef COSMOPOLITAN_LIBC_SOCK_IPCLASSIFY_H_ +#define COSMOPOLITAN_LIBC_SOCK_IPCLASSIFY_H_ +#include "libc/sock/sock.h" +#include "libc/sysv/errfuns.h" +#include "libc/sysv/consts/af.h" +#include "libc/sysv/consts/inaddr.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * Returns true if address is part of standardized test-only subnet. + */ +forceinline bool istestip(int sin_family, void *sin_addr) { + if (sin_family == AF_INET) { + uint32_t ip4net24 = ntohl(*(const uint32_t *)sin_addr) & 0xffffff00u; + if (ip4net24 == INADDR_TESTNET1 || ip4net24 == INADDR_TESTNET2 || + ip4net24 == INADDR_TESTNET3) { + return true; + } + } else { + eafnosupport(); + } + return false; +} + +/** + * Returns true if address is part of a local-only subnet. + */ +forceinline bool islocalip(int sin_family, void *sin_addr) { + if (sin_family == AF_INET) { + uint32_t ip4net8 = ntohl(*(const uint32_t *)sin_addr) & 0xff000000u; + if (ip4net8 == 0x7f000000u) { + return true; + } + } else { + eafnosupport(); + } + return false; +} + +/** + * Returns true if address is part of a well-known private subnet. + */ +forceinline bool isprivateip(int sin_family, void *sin_addr) { + if (sin_family == AF_INET) { + uint32_t ip4 = ntohl(*(const uint32_t *)sin_addr); + if ((0x0a000000u <= ip4 && ip4 <= 0x0affffffu) /* 10.0.0.0/8 */ || + (0xac100000u <= ip4 && ip4 <= 0xac1fffffu) /* 172.16.0.0/12 */ || + (0xc0a80000u <= ip4 && ip4 <= 0xc0a8ffffu) /* 192.168.0.0/16 */) { + return true; + } + } else { + eafnosupport(); + } + return false; +} + +/** + * Returns true if address is most likely part of the public Internet. + */ +forceinline bool ispublicip(int sin_family, void *sin_addr) { + return !islocalip(sin_family, sin_addr) && + !isprivateip(sin_family, sin_addr) && !istestip(sin_family, sin_addr); +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SOCK_IPCLASSIFY_H_ */ diff --git a/libc/sock/kntwsadata.c b/libc/sock/kntwsadata.c new file mode 100644 index 00000000..7f81fb13 --- /dev/null +++ b/libc/sock/kntwsadata.c @@ -0,0 +1,47 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/nt/winsock.h" +#include "libc/runtime/runtime.h" +#include "libc/sock/internal.h" + +#define VERSION 0x0202 /* Windows Vista+ */ + +/** + * Information about underyling Windows Sockets implemmentation. + * + * Cosmopolitan automatically calls YOINK() on this symbol when its + * Berkeley Socket wrappers are linked. The latest version of Winsock + * was introduced alongside x64, so this should never fail. + */ +struct NtWsaData kNtWsaData; + +textwindows static void winsockfini(void) { WSACleanup(); } +textstartup static void winsockinit(void) { + if (!IsWindows()) return; + atexit(winsockfini); + int rc; + if ((rc = WSAStartup(VERSION, &kNtWsaData)) != 0 || + kNtWsaData.wVersion != VERSION) { + abort(); + } +} + +const void *const winsockctor[] initarray = {winsockinit}; diff --git a/libc/sock/listen-nt.c b/libc/sock/listen-nt.c new file mode 100644 index 00000000..05928c66 --- /dev/null +++ b/libc/sock/listen-nt.c @@ -0,0 +1,33 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/internal.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sysv/errfuns.h" + +textwindows int listen$nt(struct Fd *fd, int backlog) { + assert(fd->kind == kFdSocket); + if (__listen$nt(fd->handle, backlog) != -1) { + return 0; + } else { + return winsockerr(); + } +} diff --git a/libc/sock/listen.c b/libc/sock/listen.c new file mode 100644 index 00000000..9d0af994 --- /dev/null +++ b/libc/sock/listen.c @@ -0,0 +1,45 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/sysv/errfuns.h" + +/** + * Asks system to accept incoming connections on socket. + * + * The socket() and bind() functions need to be called beforehand. Once + * this function is called, accept() is used to wait for connections. + * Using this on connectionless sockets will allow it to receive packets + * on a designated address. + * + * @param backlog <= SOMAXCONN + * @return 0 on success or -1 w/ errno + */ +int listen(int fd, int backlog) { + if (!IsWindows()) { + return listen$sysv(fd, backlog); + } else if (isfdkind(fd, kFdSocket)) { + return listen$nt(&g_fds.p[fd], backlog); + } else { + return ebadf(); + } +} diff --git a/libc/sock/parseport.c b/libc/sock/parseport.c new file mode 100644 index 00000000..2bc9ef70 --- /dev/null +++ b/libc/sock/parseport.c @@ -0,0 +1,27 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/sock/sock.h" +#include "libc/sysv/errfuns.h" + +int parseport(const char *service) { + int port = atoi(service); + return (0 <= port && port <= 65535) ? port : einval(); +} diff --git a/libc/sock/poll-nt.c b/libc/sock/poll-nt.c new file mode 100644 index 00000000..7e28f5cd --- /dev/null +++ b/libc/sock/poll-nt.c @@ -0,0 +1,45 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/struct/pollfd.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sysv/consts/poll.h" +#include "libc/sysv/errfuns.h" + +textwindows int poll$nt(struct pollfd *fds, uint64_t nfds, int32_t timeout_ms) { + int got; + size_t i; + struct pollfd$nt ntfds[64]; + if (nfds > 64) return einval(); + for (i = 0; i < nfds; ++i) { + if (!isfdkind(fds[i].fd, kFdSocket)) return ebadf(); + ntfds[i].handle = g_fds.p[fds[i].fd].handle; + ntfds[i].events = fds[i].events & (POLLPRI | POLLIN | POLLOUT); + } + if ((got = WSAPoll(ntfds, nfds, timeout_ms)) != -1) { + for (i = 0; i < nfds; ++i) { + fds[i].revents = ntfds[i].revents; + } + return got; + } else { + return winsockerr(); + } +} diff --git a/libc/sock/poll.c b/libc/sock/poll.c new file mode 100644 index 00000000..5998d48c --- /dev/null +++ b/libc/sock/poll.c @@ -0,0 +1,46 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" + +/** + * Waits for something to happen on multiple file descriptors at once. + * + * @param fds[𝑖].fd should have been created with SOCK_NONBLOCK passed + * to socket() or accept4() + * @param fds[𝑖].events flags can have POLL{IN,OUT,PRI} + * @param timeout_ms if 0 means don't wait and -1 means wait forever + * @return number of items fds whose revents field has been set to + * nonzero to describe its events, or -1 w/ errno + * @return fds[𝑖].revents flags can have: + * (fds[𝑖].events & POLL{IN,OUT,PRI,HUP,ERR,NVAL}) + * @asyncsignalsafe + * @see ppoll() + */ +int poll(struct pollfd *fds, uint64_t nfds, int32_t timeout_ms) { + if (!IsWindows()) { + return poll$sysv(fds, nfds, timeout_ms); + } else { + return poll$nt(fds, nfds, timeout_ms); + } +} diff --git a/libc/sock/recv.c b/libc/sock/recv.c new file mode 100644 index 00000000..4c37db1c --- /dev/null +++ b/libc/sock/recv.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/sock/sock.h" + +/** + * Receives data from network socket. + * + * @param fd is the file descriptor returned by socket() + * @param buf is where received network data gets copied + * @param size is the byte capacity of buf + * @param flags can have MSG_{WAITALL,PEEK,OOB}, etc. + * @return number of bytes received, 0 on remote close, or -1 w/ errno + * @error EINTR, EHOSTUNREACH, ECONNRESET (UDP ICMP Port Unreachable), + * EPIPE (if MSG_NOSIGNAL), EMSGSIZE, ENOTSOCK, EFAULT, etc. + * @asyncsignalsafe + */ +ssize_t recv(int fd, void *buf, size_t size, int flags) { + return recvfrom(fd, buf, size, flags, NULL, 0); +} diff --git a/libc/sock/recvfrom-nt.c b/libc/sock/recvfrom-nt.c new file mode 100644 index 00000000..e9c7994b --- /dev/null +++ b/libc/sock/recvfrom-nt.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/internal.h" +#include "libc/sock/internal.h" + +/** + * Performs recv(), recvfrom(), or readv() on Windows NT. + * + * @param fd must be a socket + * @return number of bytes received, or -1 w/ errno + */ +textwindows ssize_t recvfrom$nt(struct Fd *fd, const struct iovec *iov, + size_t iovlen, uint32_t flags, + void *opt_out_srcaddr, + uint32_t *opt_inout_srcaddrsize) { + uint32_t got; + struct iovec$nt iovnt[16]; + got = 0; + if (WSARecvFrom(fd->handle, iovnt, iovec2nt(iovnt, iov, iovlen), &got, &flags, + opt_out_srcaddr, opt_inout_srcaddrsize, NULL, NULL) != -1) { + return got; + } else { + return winsockerr(); + } +} diff --git a/libc/sock/recvfrom.c b/libc/sock/recvfrom.c new file mode 100644 index 00000000..06c98b4e --- /dev/null +++ b/libc/sock/recvfrom.c @@ -0,0 +1,60 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/dce.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/sysv/errfuns.h" + +/** + * Receives data from network. + * + * This function blocks unless MSG_DONTWAIT is passed. + * + * @param fd is the file descriptor returned by socket() + * @param buf is where received network data gets copied + * @param size is the byte capacity of buf + * @param flags can have MSG_{WAITALL,DONTROUTE,PEEK,OOB}, etc. + * @param opt_out_srcaddr receives the binary ip:port of the data's origin + * @param opt_inout_srcaddrsize is srcaddr capacity which gets updated + * @return number of bytes received, 0 on remote close, or -1 w/ errno + * @error EINTR, EHOSTUNREACH, ECONNRESET (UDP ICMP Port Unreachable), + * EPIPE (if MSG_NOSIGNAL), EMSGSIZE, ENOTSOCK, EFAULT, etc. + * @asyncsignalsafe + */ +ssize_t recvfrom(int fd, void *buf, size_t size, uint32_t flags, + void *opt_out_srcaddr, uint32_t *opt_inout_srcaddrsize) { + ssize_t got; + if (!IsWindows()) { + got = recvfrom$sysv(fd, buf, size, flags, opt_out_srcaddr, + opt_inout_srcaddrsize); + if (opt_out_srcaddr && IsBsd() && got != -1) { + sockaddr2linux(opt_out_srcaddr); + } + return got; + } else if (isfdkind(fd, kFdSocket)) { + return recvfrom$nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, flags, + opt_out_srcaddr, opt_inout_srcaddrsize); + } else { + return ebadf(); + } +} diff --git a/libc/sock/select.c b/libc/sock/select.c new file mode 100644 index 00000000..22e3c1c6 --- /dev/null +++ b/libc/sock/select.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/struct/timeval.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" + +int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct timeval *timeout) { + /* TODO(jart): Windows */ + return select$sysv(nfds, readfds, writefds, exceptfds, timeout); +} diff --git a/libc/sock/send.c b/libc/sock/send.c new file mode 100644 index 00000000..9f7ebbde --- /dev/null +++ b/libc/sock/send.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/sock/sock.h" + +/** + * Sends data to network socket. + * + * @param fd is the file descriptor returned by socket() + * @param buf is the data to send, which we'll copy if necessary + * @param size is the byte-length of buf + * @param flags MSG_OOB, MSG_DONTROUTE, MSG_PARTIAL, MSG_NOSIGNAL, etc. + * @return number of bytes transmitted, or -1 w/ errno + * @error EINTR, EHOSTUNREACH, ECONNRESET (UDP ICMP Port Unreachable), + * EPIPE (if MSG_NOSIGNAL), EMSGSIZE, ENOTSOCK, EFAULT, etc. + * @asyncsignalsafe + */ +ssize_t send(int fd, const void *buf, size_t size, int flags) { + return sendto(fd, buf, size, flags, NULL, 0); +} diff --git a/libc/sock/sendfile.c b/libc/sock/sendfile.c new file mode 100644 index 00000000..a065bafd --- /dev/null +++ b/libc/sock/sendfile.c @@ -0,0 +1,101 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +static textwindows ssize_t sendfile$linux2nt(int outfd, int infd, + int64_t *inout_opt_inoffset, + size_t uptobytes) { + struct NtOverlapped Overlapped; + struct NtOverlapped *lpOverlapped; + if (!isfdkind(outfd, kFdSocket) || !isfdkind(outfd, kFdFile)) return ebadf(); + if (inout_opt_inoffset) { + memset(&Overlapped, 0, sizeof(Overlapped)); + Overlapped.Pointer = (void *)(intptr_t)(*inout_opt_inoffset); + lpOverlapped = &Overlapped; + } else { + lpOverlapped = NULL; + } + /* TODO(jart): Fetch this on a per-socket basis via GUID. */ + if (TransmitFile(g_fds.p[outfd].handle, g_fds.p[infd].handle, uptobytes, 0, + lpOverlapped, NULL, 0)) { + return uptobytes; + } else { + return winsockerr(); + } +} + +static ssize_t sendfile$linux2netflix(int outfd, int infd, + int64_t *inout_opt_inoffset, + size_t uptobytes) { + int sendfile$netflix(int32_t infd, int32_t outfd, int64_t offset, + size_t nbytes, const void *opt_hdtr, + int64_t *out_opt_sbytes, + int32_t flags) asm("sendfile$sysv") hidden; + int rc; + int64_t offset, sbytes; + if (inout_opt_inoffset) { + offset = *inout_opt_inoffset; + } else if ((offset = lseek$sysv(infd, 0, SEEK_CUR)) == -1) { + return -1; + } + if ((rc = sendfile$netflix(infd, outfd, offset, uptobytes, NULL, &sbytes, + 0)) != -1) { + if (inout_opt_inoffset) *inout_opt_inoffset += sbytes; + return sbytes; + } else { + return -1; + } +} + +/** + * Transfers data from file to network. + * + * @param outfd needs to be a socket + * @param infd needs to be a file + * @param inout_opt_inoffset may be specified for pread()-like behavior + * @param uptobytes is usually the number of bytes remaining in file; it + * can't exceed INT_MAX-1; some platforms block until everything's + * sent, whereas others won't; zero isn't allowed + * @return number of bytes transmitted which may be fewer than requested + * @see copy_file_range() for file ↔ file + * @see splice() for fd ↔ pipe + */ +ssize_t sendfile(int outfd, int infd, int64_t *inout_opt_inoffset, + size_t uptobytes) { + if (!uptobytes) return einval(); + if (uptobytes > 0x7ffffffe /* Microsoft's off-by-one */) return eoverflow(); + if (IsModeDbg() && uptobytes > 1) uptobytes >>= 1; + if (IsLinux()) { + return sendfile$sysv(outfd, infd, inout_opt_inoffset, uptobytes); + } else if (IsFreebsd() || IsXnu()) { + return sendfile$linux2netflix(outfd, infd, inout_opt_inoffset, uptobytes); + } else if (IsWindows()) { + return sendfile$linux2nt(outfd, infd, inout_opt_inoffset, uptobytes); + } else { + return copyfd(infd, inout_opt_inoffset, outfd, NULL, uptobytes, 0); + } +} diff --git a/libc/sock/sendto-nt.c b/libc/sock/sendto-nt.c new file mode 100644 index 00000000..540e2cc2 --- /dev/null +++ b/libc/sock/sendto-nt.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/internal.h" +#include "libc/sock/internal.h" + +/** + * Performs send(), sendto(), or writev() on Windows NT. + * + * @param fd must be a socket + * @return number of bytes handed off, or -1 w/ errno + */ +textwindows ssize_t sendto$nt(struct Fd *fd, const struct iovec *iov, + size_t iovlen, uint32_t flags, void *opt_in_addr, + uint32_t *in_addrsize) { + uint32_t sent; + struct iovec$nt iovnt[16]; + if (WSASendTo(fd->handle, iovnt, iovec2nt(iovnt, iov, iovlen), &sent, flags, + opt_in_addr, *in_addrsize, NULL, NULL) != -1) { + return sent; + } else { + return winsockerr(); + } +} diff --git a/libc/sock/sendto.c b/libc/sock/sendto.c new file mode 100644 index 00000000..0a75bb5c --- /dev/null +++ b/libc/sock/sendto.c @@ -0,0 +1,67 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/dce.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +/** + * Sends data over network. + * + * This function blocks unless MSG_DONTWAIT is passed. In that case, the + * non-error EWOULDBLOCK might be returned. It basically means we didn't + * wait around to learn an amount of bytes were written that we know in + * advance are guaranteed to be atomic. + * + * @param fd is the file descriptor returned by socket() + * @param buf is the data to send, which we'll copy if necessary + * @param size is the byte-length of buf + * @param flags MSG_OOB, MSG_DONTROUTE, MSG_PARTIAL, MSG_NOSIGNAL, etc. + * @param opt_addr is a binary ip:port destination override, which is + * mandatory for UDP if connect() wasn't called + * @param addrsize is the byte-length of addr's true polymorphic form + * @return number of bytes transmitted, or -1 w/ errno + * @error EINTR, EHOSTUNREACH, ECONNRESET (UDP ICMP Port Unreachable), + * EPIPE (if MSG_NOSIGNAL), EMSGSIZE, ENOTSOCK, EFAULT, etc. + * @asyncsignalsafe + */ +ssize_t sendto(int fd, const void *buf, size_t size, uint32_t flags, + const void *opt_addr, uint32_t addrsize) { + static_assert(sizeof(struct sockaddr_in) == sizeof(struct sockaddr_in$bsd)); + if (!IsWindows()) { + if (!IsBsd() || !opt_addr) { + return sendto$sysv(fd, buf, size, flags, opt_addr, addrsize); + } else { + struct sockaddr_in$bsd addr2; + if (addrsize != sizeof(addr2)) return einval(); + memcpy(&addr2, opt_addr, sizeof(struct sockaddr_in)); + sockaddr2bsd(&addr2); + return sendto$sysv(fd, buf, size, flags, &addr2, addrsize); + } + } else if (isfdkind(fd, kFdSocket)) { + return sendto$nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, flags, + opt_addr, &addrsize); + } else { + return ebadf(); + } +} diff --git a/libc/sock/setsockopt.c b/libc/sock/setsockopt.c new file mode 100644 index 00000000..d09bc1c6 --- /dev/null +++ b/libc/sock/setsockopt.c @@ -0,0 +1,77 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/sysv/consts/so.h" +#include "libc/sysv/errfuns.h" + +static bool setsockopt_polyfill(int *optname) { + if (errno == ENOPROTOOPT && *optname == SO_REUSEPORT /* RHEL5 */) { + *optname = SO_REUSEADDR; /* close enough */ + return true; /* fudges errno */ + } + return false; +} + +static textwindows int setsockopt$nt(struct Fd *fd, int level, int optname, + const void *optval, uint32_t optlen) { + if (__setsockopt$nt(fd->handle, level, optname, optval, optlen) != -1) { + return 0; + } else { + return winsockerr(); + } +} + +/** + * Modifies socket settings. + * + * This function is the ultimate rabbit hole. Basic usage: + * + * int yes = 1; + * setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)); + * + * @param level can be SOL_SOCKET, IPPROTO_TCP, etc. + * @param optname can be SO_{REUSE{PORT,ADDR},KEEPALIVE,etc.} etc. + * @return 0 on success, or -1 w/ errno + * @error ENOPROTOOPT for unknown (level,optname) + * @see libc/sysv/consts.sh for tuning catalogue + * @see getsockopt() + */ +int setsockopt(int fd, int level, int optname, const void *optval, + uint32_t optlen) { + if (!level || !optname) return enoprotoopt(); /* our sysvconsts definition */ + if (optname == -1) return 0; /* our sysvconsts definition */ + if (!IsWindows()) { + do { + if (setsockopt$sysv(fd, level, optname, optval, optlen) != -1) { + return 0; + } + } while (setsockopt_polyfill(&optname)); + return -1; + } else if (isfdkind(fd, kFdSocket)) { + return setsockopt$nt(&g_fds.p[fd], level, optname, optval, optlen); + } else { + return ebadf(); + } +} diff --git a/libc/sock/shutdown.c b/libc/sock/shutdown.c new file mode 100644 index 00000000..cd6bece0 --- /dev/null +++ b/libc/sock/shutdown.c @@ -0,0 +1,56 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/sysv/errfuns.h" + +static int shutdown$nt(struct Fd *fd, int how) { + if (__shutdown$nt(fd->handle, how) != -1) { + return 0; + } else { + return winsockerr(); + } +} + +/** + * Disables sends or receives on a socket, without closing. + * + * @param fd is the open file descriptor for the socket + * @param how can be SHUT_RD, SHUT_WR, or SHUT_RDWR + * @return 0 on success or -1 on error + * @asyncsignalsafe + */ +int shutdown(int fd, int how) { + if (!IsWindows()) { + if (!IsXnu()) { + return shutdown$sysv(fd, how); + } else { + /* TODO(jart): What's wrong with XNU shutdown()? */ + return 0; + } + } else if (isfdkind(fd, kFdSocket)) { + return shutdown$nt(&g_fds.p[fd], how); + } else { + return ebadf(); + } +} diff --git a/libc/sock/sock.h b/libc/sock/sock.h new file mode 100644 index 00000000..082ecd94 --- /dev/null +++ b/libc/sock/sock.h @@ -0,0 +1,99 @@ +#ifndef COSMOPOLITAN_LIBC_SOCK_SOCK_H_ +#define COSMOPOLITAN_LIBC_SOCK_SOCK_H_ +#include "libc/bits/bits.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § system api » berkeley sockets ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define INET_ADDRSTRLEN 22 + +#define NI_DGRAM 0x10 +#define NI_MAXSERV 0x20 + +#define htons(u16) bswap_16(u16) +#define ntohs(u16) bswap_16(u16) +#define htonl(u32) bswap_32(u32) +#define ntohl(u32) bswap_32(u32) + +struct iovec; +struct sigset; +struct timespec; +struct timeval; +struct addrinfo; + +struct in_addr { /* ARPA ABI */ + /* e.g. 127|0<<8|0<<16|1<<24 or inet_pton(AF_INET, "127.0.0.1", &s_addr) */ + uint32_t s_addr; +}; + +struct sockaddr { /* Linux+NT ABI */ + uint16_t sa_family; /* AF_XXX */ + char sa_data[14]; +}; + +struct sockaddr_in { /* Linux+NT ABI */ + uint16_t sin_family; /* AF_XXX */ + uint16_t sin_port; /* htons(XXX) i.e. big endian */ + struct in_addr sin_addr; + uint8_t sin_zero[8]; +}; + +struct pollfd { + int32_t fd; + int16_t events; + int16_t revents; +}; + +struct msghdr { /* Linux+NT ABI */ + void *msg_name; /* optional address */ + int32_t msg_namelen; /* size of msg_name */ + struct iovec *msg_iov; /* scatter/gather array */ + uint64_t msg_iovlen; /* iovec count */ + void *msg_control; /* credentials and stuff */ + uint64_t msg_controllen; /* size of msg_control */ + uint32_t msg_flags; /* MSG_XXX */ +}; + +const char *inet_ntop(int, const void *, char *, uint32_t); +int inet_pton(int af, const char *, void *); +int parseport(const char *); + +int socket(int, int, int) nodiscard; +int accept(int, void *, uint32_t *) paramsnonnull() nodiscard; +int accept4(int, void *, uint32_t *, int) paramsnonnull() nodiscard; +int bind(int, const void *, uint32_t) paramsnonnull(); +int connect(int, const void *, uint32_t) paramsnonnull(); +int socketconnect(const struct addrinfo *, int); +int listen(int, int); +int shutdown(int, int); +int getsockname(int, void *, uint32_t *) paramsnonnull(); +int getpeername(int, void *, uint32_t *) paramsnonnull(); +ssize_t send(int, const void *, size_t, int) paramsnonnull(); +ssize_t recv(int, void *, size_t, int); +ssize_t recvmsg(int, struct msghdr *, uint32_t) paramsnonnull(); +ssize_t recvfrom(int, void *, size_t, uint32_t, void *, uint32_t *); +ssize_t sendmsg(int, const struct msghdr *, int) paramsnonnull(); +ssize_t readv(int, const struct iovec *, int); +ssize_t writev(int, const struct iovec *, int); +ssize_t sendfile(int, int, int64_t *, size_t); +int getsockopt(int, int, int, void *, uint32_t *) paramsnonnull((5)); +int setsockopt(int, int, int, const void *, uint32_t) paramsnonnull(); +int socketpair(int, int, int, int64_t[2]) paramsnonnull(); +int poll(struct pollfd *, uint64_t, int32_t) paramsnonnull(); +int ppoll(struct pollfd *, uint64_t, const struct timespec *, + const struct sigset *) paramsnonnull((1, 4)); +ssize_t sendto(int, const void *, size_t, uint32_t, const void *, uint32_t) + paramsnonnull((2)); + +typedef int64_t fd_set; +#define FD_CLR(FD, SET) btr(SET, FD) +#define FD_ISSET(FD, SET) bt(SET, FD) +#define FD_SET(FD, SET) bts(SET, FD) +#define FD_ZERO(SET) *(SET) = 0 +int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SOCK_SOCK_H_ */ diff --git a/libc/sock/sock.mk b/libc/sock/sock.mk new file mode 100644 index 00000000..7f7925fd --- /dev/null +++ b/libc/sock/sock.mk @@ -0,0 +1,55 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += LIBC_SOCK + +LIBC_SOCK_ARTIFACTS += LIBC_SOCK_A +LIBC_SOCK = $(LIBC_SOCK_A_DEPS) $(LIBC_SOCK_A) +LIBC_SOCK_A = o/$(MODE)/libc/sock/sock.a +LIBC_SOCK_A_FILES := $(wildcard libc/sock/*) +LIBC_SOCK_A_HDRS = $(filter %.h,$(LIBC_SOCK_A_FILES)) +LIBC_SOCK_A_SRCS = $(filter %.c,$(LIBC_SOCK_A_FILES)) + +LIBC_SOCK_A_OBJS = \ + $(LIBC_SOCK_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_SOCK_A_SRCS:%.c=o/$(MODE)/%.o) + +LIBC_SOCK_A_CHECKS = \ + $(LIBC_SOCK_A).pkg \ + $(LIBC_SOCK_A_HDRS:%=o/$(MODE)/%.ok) + +LIBC_SOCK_A_DIRECTDEPS = \ + LIBC_CALLS \ + LIBC_CONV \ + LIBC_FMT \ + LIBC_MEM \ + LIBC_RUNTIME \ + LIBC_STDIO \ + LIBC_STUBS \ + LIBC_NT_KERNELBASE \ + LIBC_NT_WS2_32 \ + LIBC_NT_MSWSOCK \ + LIBC_NEXGEN32E \ + LIBC_SYSV_CALLS \ + LIBC_SYSV + +LIBC_SOCK_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_SOCK_A_DIRECTDEPS),$($(x)))) + +$(LIBC_SOCK_A): libc/sock/ \ + $(LIBC_SOCK_A).pkg \ + $(LIBC_SOCK_A_OBJS) + +$(LIBC_SOCK_A).pkg: \ + $(LIBC_SOCK_A_OBJS) \ + $(foreach x,$(LIBC_SOCK_A_DIRECTDEPS),$($(x)_A).pkg) + +LIBC_SOCK_LIBS = $(foreach x,$(LIBC_SOCK_ARTIFACTS),$($(x))) +LIBC_SOCK_SRCS = $(foreach x,$(LIBC_SOCK_ARTIFACTS),$($(x)_SRCS)) +LIBC_SOCK_HDRS = $(foreach x,$(LIBC_SOCK_ARTIFACTS),$($(x)_HDRS)) +LIBC_SOCK_CHECKS = $(foreach x,$(LIBC_SOCK_ARTIFACTS),$($(x)_CHECKS)) +LIBC_SOCK_OBJS = $(foreach x,$(LIBC_SOCK_ARTIFACTS),$($(x)_OBJS)) +$(LIBC_SOCK_OBJS): $(BUILD_FILES) libc/sock/sock.mk + +.PHONY: o/$(MODE)/libc/sock +o/$(MODE)/libc/sock: $(LIBC_SOCK_CHECKS) diff --git a/libc/sock/socket-nt.c b/libc/sock/socket-nt.c new file mode 100644 index 00000000..d0211b3e --- /dev/null +++ b/libc/sock/socket-nt.c @@ -0,0 +1,50 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sysv/consts/fio.h" +#include "libc/sysv/consts/sock.h" + +STATIC_YOINK("closesocket$nt"); +STATIC_YOINK("kNtWsaData"); +STATIC_YOINK("recvfrom$nt"); +STATIC_YOINK("sendto$nt"); + +textwindows int socket$nt(int family, int type, int protocol) { + int fd; + if ((fd = createfd()) == -1) return -1; + if ((g_fds.p[fd].handle = + WSASocket(family, type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK), protocol, + NULL, 0, (type & SOCK_CLOEXEC))) != -1) { + if (type & SOCK_NONBLOCK) { + uint32_t yes = 1; + if (__ioctlsocket$nt(g_fds.p[fd].handle, FIONBIO, &yes) == -1) { + __closesocket$nt(g_fds.p[fd].handle); + return winsockerr(); + } + } + g_fds.p[fd].kind = kFdSocket; + g_fds.p[fd].flags = type; + return fd; + } else { + return winsockerr(); + } +} diff --git a/libc/sock/socket-sysv.c b/libc/sock/socket-sysv.c new file mode 100644 index 00000000..002e6be9 --- /dev/null +++ b/libc/sock/socket-sysv.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/sock/internal.h" +#include "libc/sysv/consts/sock.h" + +int socket$sysv(int family, int type, int protocol) { + int rc, olderr, modernflags; + olderr = errno; + rc = __socket$sysv(family, type, protocol); + if ((SupportsLinux() || SupportsXnu()) && + (rc == -1 && errno == EINVAL /* rhel5 behavior */) && + (modernflags = (type & (SOCK_CLOEXEC | SOCK_NONBLOCK)))) { + errno = olderr; + rc = fixupnewsockfd$sysv( + __socket$sysv(family, type & ~modernflags, protocol), modernflags); + } + return rc; +} diff --git a/libc/sock/socket.c b/libc/sock/socket.c new file mode 100644 index 00000000..9df55fe6 --- /dev/null +++ b/libc/sock/socket.c @@ -0,0 +1,53 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/sysv/consts/af.h" +#include "libc/sysv/errfuns.h" + +/** + * Creates new system resource for network communication. + * + * @param family can be AF_UNIX, AF_INET, etc. + * @param type can be SOCK_STREAM (for TCP), SOCK_DGRAM (e.g. UDP), or + * SOCK_RAW (IP) so long as IP_HDRINCL was passed to setsockopt(); + * and additionally, may be or'd with SOCK_NONBLOCK, SOCK_CLOEXEC + * @param protocol can be IPPROTO_TCP, IPPROTO_UDP, or IPPROTO_ICMP + * @return socket file descriptor or -1 w/ errno + * @error ENETDOWN, EPFNOSUPPORT, etc. + * @see libc/sysv/consts.sh + * @asyncsignalsafe + */ +int socket(int family, int type, int protocol) { + if (family == AF_UNSPEC) { + family = AF_INET; + } else if (family == AF_INET6) { + /* Recommend IPv6 on frontend serving infrastructure only. That's + what Google Cloud does. It's more secure. It also means poll() + will work on Windows, which doesn't allow mixing third layers. */ + return epfnosupport(); + } + if (!IsWindows()) { + return socket$sysv(family, type, protocol); + } else { + return socket$nt(family, type, protocol); + } +} diff --git a/libc/sock/socketconnect.c b/libc/sock/socketconnect.c new file mode 100644 index 00000000..a9532194 --- /dev/null +++ b/libc/sock/socketconnect.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/dns/dns.h" +#include "libc/errno.h" +#include "libc/sock/sock.h" + +/** + * Opens socket client connection. + * + * @param ai can be obtained via getaddrinfo() + * @return socket file descriptor, or -1 w/ errno + */ +int socketconnect(const struct addrinfo *ai, int flags) { + int fd; + fd = socket(ai->ai_family, ai->ai_socktype | flags, ai->ai_protocol); + if (fd != -1) { + if (connect(fd, ai->ai_addr, ai->ai_addrlen) != -1 || + errno == EINPROGRESS) { + return fd; + } + close(fd); + } + return -1; +} diff --git a/libc/sock/winsockblock.c b/libc/sock/winsockblock.c new file mode 100644 index 00000000..d0c65ac1 --- /dev/null +++ b/libc/sock/winsockblock.c @@ -0,0 +1,46 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/errno.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" +#include "libc/sock/sock.h" +#include "libc/str/str.h" + +textwindows int64_t winsockblock(int64_t fh, unsigned eventbit, int64_t rc) { + int64_t eh; + struct NtWsaNetworkEvents ev; + if (rc != -1) return rc; + if (WSAGetLastError() != EWOULDBLOCK) return winsockerr(); + eh = WSACreateEvent(); + memset(&ev, 0, sizeof(ev)); + if (WSAEventSelect(fh, eh, 1u << eventbit) != -1 && + WSAEnumNetworkEvents(fh, eh, &ev) != -1) { + if (!ev.iErrorCode[eventbit]) { + rc = 0; + } else { + errno = ev.iErrorCode[eventbit]; + } + } else { + winsockerr(); + } + WSACloseEvent(eh); + return rc; +} diff --git a/libc/sock/winsockerr.c b/libc/sock/winsockerr.c new file mode 100644 index 00000000..fbf616e9 --- /dev/null +++ b/libc/sock/winsockerr.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/errno.h" +#include "libc/nt/winsock.h" +#include "libc/sock/internal.h" + +/** + * Error return path for winsock wrappers. + */ +textwindows int64_t winsockerr(void) { + errno = WSAGetLastError(); + return -1; +} diff --git a/libc/sock/xinet_ntop.c b/libc/sock/xinet_ntop.c new file mode 100644 index 00000000..ef007d4e --- /dev/null +++ b/libc/sock/xinet_ntop.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/sock/sock.h" + +/** + * Formats internet address to string, or dies. + * + * @param af can be AF_INET, e.g. addr->sin_family + * @param src is the binary-encoded address, e.g. &addr->sin_addr + * @return allocated IP address string, which must be free()'d + */ +char *xinet_ntop(int af, const void *src) { + char *res, ip[16]; + if (inet_ntop(af, src, ip, sizeof(ip)) && (res = strdup(ip))) { + return res; + } else { + if (weaken(die)) weaken(die)(); + abort(); + unreachable; + } +} diff --git a/libc/stdio/clearerr.c b/libc/stdio/clearerr.c new file mode 100644 index 00000000..e0bc3f33 --- /dev/null +++ b/libc/stdio/clearerr.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" + +void clearerr(FILE *f) { + f->state = 0; +} diff --git a/libc/stdio/favail.c b/libc/stdio/favail.c new file mode 100644 index 00000000..09f69d07 --- /dev/null +++ b/libc/stdio/favail.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" + +/** + * Returns number of bytes available in stream buffer. + */ +unsigned favail(FILE *f) { + if (f->beg == f->end) return f->size; + if (f->end > f->beg) return f->end - f->beg; + return (f->size - f->beg) + f->end; +} diff --git a/libc/stdio/fclose.c b/libc/stdio/fclose.c new file mode 100644 index 00000000..3daf83af --- /dev/null +++ b/libc/stdio/fclose.c @@ -0,0 +1,58 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/calls.h" +#include "libc/errno.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/internal.h" +#include "libc/stdio/stdio.h" + +/** + * Closes standard i/o stream and its underlying thing. + * + * @param f is the file object, which is always free if it's heap, + * otherwise its resources are released and fields updated + * @return 0 on success or -1 on error, which can be a trick for + * differentiating between EOF and real errors during previous + * i/o calls, without needing to call ferror() + * @see fclose_s() + */ +int fclose(FILE *f) { + int rc; + if (!f) return 0; /* good java behavior; glibc crashes */ + fflushunregister(f); + fflush(f); + free_s(&f->buf); + f->state = EOF; + if (f->noclose) { + f->fd = -1; + } else if (close_s(&f->fd) == -1) { + f->state = errno; + } + if (f->state == EOF) { + rc = 0; + } else { + errno = f->state; + rc = EOF; + } + free_s(&f); + return rc; +} diff --git a/libc/stdio/fclose_s.c b/libc/stdio/fclose_s.c new file mode 100644 index 00000000..c50ba0be --- /dev/null +++ b/libc/stdio/fclose_s.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/runtime/mappings.h" +#include "libc/stdio/stdio.h" + +/** + * Closes standard i/o stream and its underlying thing. + * + * @param f is the heap file object pointer, to close+free+clear + * @return 0 on success or -1 on error, which can be a trick for + * differentiating between EOF and real errors during previous + * i/o calls, without needing to call ferror() + */ +int fclose_s(FILE **fp) { + FILE *f = NULL; + return fclose(lockxchg(fp, &f)); +} diff --git a/libc/stdio/fdopen.c b/libc/stdio/fdopen.c new file mode 100644 index 00000000..a1101f73 --- /dev/null +++ b/libc/stdio/fdopen.c @@ -0,0 +1,44 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/internal.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/errfuns.h" + +/** + * Allocates stream object for already-opened file descriptor. + * + * @param fd existing file descriptor or -1 for plain old buffer + * @param mode is passed to fopenflags() + * @return new stream or NULL w/ errno + * @error ENOMEM + */ +FILE *fdopen(int fd, const char *mode) { + FILE *res; + if ((res = fmemopen(NULL, BUFSIZ, mode))) { + res->fd = fd; + res->reader = freadbuf; + res->writer = fwritebuf; + if ((res->iomode & O_ACCMODE) != O_RDONLY) { + fflushregister(res); + } + } + return res; +} diff --git a/libc/stdio/feof.c b/libc/stdio/feof.c new file mode 100644 index 00000000..fe615b09 --- /dev/null +++ b/libc/stdio/feof.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" + +int feof(FILE *f) { + return f->state == -1; +} diff --git a/libc/stdio/ferror.c b/libc/stdio/ferror.c new file mode 100644 index 00000000..0aa250f5 --- /dev/null +++ b/libc/stdio/ferror.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" + +/** + * Returns nonzero if stream is in error state. + * + * @note EOF doesn't count + * @see feof() + */ +errno_t ferror(FILE *f) { + return f->state > 0 ? f->state : 0; +} diff --git a/libc/stdio/fflush.c b/libc/stdio/fflush.c new file mode 100644 index 00000000..bfa8a763 --- /dev/null +++ b/libc/stdio/fflush.c @@ -0,0 +1,112 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/arraylist.h" +#include "libc/bits/bits.h" +#include "libc/bits/pushpop.h" +#include "libc/calls/calls.h" +#include "libc/macros.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/internal.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/o.h" + +struct StdioFlushHandles { + size_t i, n; + FILE **p; +}; + +struct StdioFlush { + struct StdioFlushHandles handles; + FILE *handles_initmem[8]; +}; + +static struct StdioFlush g_fflush; + +/** + * Blocks until data from stream buffer is written out. + * + * @param f is the stream handle + * @return number of bytes written or -1 on error + * @see fwritebuf + */ +int fflush(FILE *f) { + size_t i; + int res, wrote; + res = 0; + if (!f) { + for (i = g_fflush.handles.i; i; --i) { + if ((f = g_fflush.handles.p[i - 1])) { + if ((wrote = fflush(f)) != -1) { + res += wrote; + } else { + res = -1; + break; + } + } + } + } else if (f->fd != -1 && (f->iomode & O_WRONLY)) { + if (!f->state) { + while (f->beg != f->end) { + if ((wrote = fwritebuf(f)) != -1) { + res += wrote; + } else { + res = -1; + break; + } + } + } else if (f->state != -1) { + res = fseterr(f, f->state); + } + } + return res; +} + +int fflushregister(FILE *f) { + size_t i; + struct StdioFlush *sf; + sf = &g_fflush; + sf = sf; + if (!sf->handles.p) { + sf->handles.p = &sf->handles_initmem[0]; + pushmov(&sf->handles.n, ARRAYLEN(sf->handles_initmem)); + __cxa_atexit(fflush, NULL, NULL); + } + for (i = sf->handles.i; i; --i) { + if (!sf->handles.p[i - 1]) { + sf->handles.p[i - 1] = f; + return 0; + } + } + return append(&sf->handles, &f); +} + +void fflushunregister(FILE *f) { + size_t i; + struct StdioFlush *sf; + sf = &g_fflush; + sf = pushpop(sf); + for (i = sf->handles.i; i; --i) { + if (sf->handles.p[i - 1] == f) { + pushmov(&sf->handles.p[i - 1], NULL); + return; + } + } +} diff --git a/libc/stdio/fgetc.c b/libc/stdio/fgetc.c new file mode 100644 index 00000000..fbaf3a33 --- /dev/null +++ b/libc/stdio/fgetc.c @@ -0,0 +1,27 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" + +/** + * Reads uint8_t from stream. + */ +int fgetc(FILE *f) { + return getc(f); +} diff --git a/libc/stdio/fgethex.c b/libc/stdio/fgethex.c new file mode 100644 index 00000000..d7af6776 --- /dev/null +++ b/libc/stdio/fgethex.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +int fgethex(FILE *f) { + int o, t = -1; + while (!((o = fgetc(f)) & ~0xFF)) { + switch (t) { + case -1: + t = isxdigit(o) ? hextoint(o) : -1; + break; + default: + if (isxdigit(o)) { + return t * 16 + hextoint(o); + } + break; + } + } + if (t >= 0) return einval(); + return -1; +} diff --git a/libc/stdio/fgetpos.c b/libc/stdio/fgetpos.c new file mode 100644 index 00000000..768bf9c1 --- /dev/null +++ b/libc/stdio/fgetpos.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" + +int fgetpos(FILE *stream, fpos_t *pos) { + long res; + if ((res = ftell(stream)) != -1) { + *pos = res; + return 0; + } else { + return -1; + } +} diff --git a/libc/stdio/fgets.c b/libc/stdio/fgets.c new file mode 100644 index 00000000..8236caa4 --- /dev/null +++ b/libc/stdio/fgets.c @@ -0,0 +1,47 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/errno.h" +#include "libc/stdio/stdio.h" + +/** + * Reads content from stream. + * + * This function is similar to getline() except it'll truncate lines + * exceeding size. The line ending marker is included and may be removed + * using chomp(). + */ +char *fgets(char *s, int size, FILE *f) { + int c; + char *p; + p = s; + if (size > 0) { + while (--size > 0) { + if ((c = getc(f)) == -1) { + if (ferror(f) == EINTR) continue; + break; + } + *p++ = c & 0xff; + if (c == '\n') break; + } + *p = '\0'; + } + return p > s ? s : NULL; +} diff --git a/libc/stdio/fgetwc.c b/libc/stdio/fgetwc.c new file mode 100644 index 00000000..83652c5e --- /dev/null +++ b/libc/stdio/fgetwc.c @@ -0,0 +1,33 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" +#include "libc/str/tpdecodecb.h" + +/** + * Reads UTF-8 character from stream. + * + * @return wide character or -1 on EOF or error + */ +wint_t fgetwc(FILE *f) { + wint_t res; + res = -1; + tpdecodecb(&res, fgetc(f), (void *)fgetc, f); + return res; +} diff --git a/libc/stdio/fgetws.c b/libc/stdio/fgetws.c new file mode 100644 index 00000000..d40770ad --- /dev/null +++ b/libc/stdio/fgetws.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/errno.h" +#include "libc/stdio/stdio.h" + +/** + * Reads UTF-8 content from stream into UTF-32 buffer. + */ +wchar_t *fgetws(wchar_t *s, int size, FILE *f) { + wchar_t *p = s; + if (size > 0) { + while (--size > 0) { + wint_t c; + if ((c = fgetwc(f)) == -1) { + if (ferror(f) == EINTR) continue; + break; + } + *p++ = c; + if (c == '\n') break; + } + *p = '\0'; + } + return (intptr_t)p > (intptr_t)s ? s : NULL; +} diff --git a/libc/stdio/fileno.c b/libc/stdio/fileno.c new file mode 100644 index 00000000..919dff08 --- /dev/null +++ b/libc/stdio/fileno.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" +#include "libc/sysv/errfuns.h" + +/** + * Returns file descriptor associated with stream. + */ +int fileno(FILE *f) { + if (f->fd != -1) { + return f->fd; + } else { + return ebadf(); + } +} diff --git a/libc/stdio/fmemopen.c b/libc/stdio/fmemopen.c new file mode 100644 index 00000000..16e5705c --- /dev/null +++ b/libc/stdio/fmemopen.c @@ -0,0 +1,75 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/errno.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/errfuns.h" + +/** + * Opens buffer as stream. + * + * This function is the heart of the streams implementation, and it's + * truly magnificent for unit testing. + * + * @param buf becomes owned by this function, and is allocated if NULL + * @return new stream or NULL w/ errno + * @error ENOMEM, EINVAL + */ +FILE *fmemopen(void *buf, size_t size, const char *mode) { + FILE *res; + unsigned flags; + + if (buf && !size) { + einval(); + return NULL; + } + + if (size && popcount(size) != 1) { + einval(); + return NULL; + } + + if (!(res = calloc(1, sizeof(FILE)))) { + return NULL; + } + + if (!buf) { + if (!size) size = FRAMESIZE; + if (!(buf = valloc(size))) { + free(res); + return NULL; + } + } + + res->fd = -1; + setbuffer(res, buf, size); + res->bufmode = res->buf ? _IOFBF : _IONBF; + flags = fopenflags(mode); + res->iomode = (flags & O_ACCMODE) == O_RDWR + ? O_RDWR + : (flags & O_ACCMODE) == O_WRONLY ? O_WRONLY : O_RDONLY; + + return res; +} diff --git a/libc/stdio/fopen.c b/libc/stdio/fopen.c new file mode 100644 index 00000000..fcab8832 --- /dev/null +++ b/libc/stdio/fopen.c @@ -0,0 +1,75 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/mem/mem.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/o.h" + +static const char *fixpathname(const char *pathname, int flags) { + if ((flags & O_ACCMODE) == O_RDONLY && strcmp(pathname, "-") == 0) { + return "/dev/stdin"; + } else if ((flags & O_ACCMODE) == O_WRONLY && strcmp(pathname, "-") == 0) { + return "/dev/stdout"; + } else { + return pathname; + } +} + +static int openpathname(const char *pathname, int flags, bool *out_noclose) { + if ((flags & O_ACCMODE) == O_RDONLY && strcmp(pathname, "/dev/stdin") == 0) { + *out_noclose = true; + return fileno(stdin); + } else if ((flags & O_ACCMODE) == O_WRONLY && + strcmp(pathname, "/dev/stdout") == 0) { + *out_noclose = true; + return fileno(stdout); + } else { + *out_noclose = false; + return open(pathname, flags, 0666); + } +} + +/** + * Opens file as stream object. + * + * @param pathname is a utf-8 ideally relative filename + * @param mode is the string mode/flag DSL see fopenflags() + * @return new object to be free'd by fclose() or NULL w/ errno + * @note microsoft unilaterally deprecated this function lool + */ +FILE *fopen(const char *pathname, const char *mode) { + FILE *f; + bool noclose; + int fd, flags; + flags = fopenflags(mode); + pathname = fixpathname(pathname, flags); + if ((fd = openpathname(pathname, flags, &noclose)) != -1) { + if ((f = fdopen(fd, mode)) != NULL) { + f->noclose = noclose; + return f; + } else { + if (!noclose) close(fd); + return NULL; + } + } else { + return NULL; + } +} diff --git a/libc/stdio/fopenflags.c b/libc/stdio/fopenflags.c new file mode 100644 index 00000000..fd89e86b --- /dev/null +++ b/libc/stdio/fopenflags.c @@ -0,0 +1,45 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" +#include "libc/calls/calls.h" +#include "libc/sysv/consts/o.h" + +/** + * Turns stdio flags description string into bitmask. + */ +int fopenflags(const char *mode) { + unsigned flags = 0; + do { + if (*mode == 'r') { + flags |= O_RDONLY; + } else if (*mode == 'w') { + flags |= O_WRONLY | O_CREAT | O_TRUNC; + } else if (*mode == 'a') { + flags |= O_WRONLY | O_CREAT | O_APPEND; + } else if (*mode == '+') { + flags |= O_RDWR; + } else if (*mode == 'x') { + flags |= O_EXCL; + } else if (*mode == 'e') { + flags |= O_CLOEXEC; + } + } while (*mode++); + return flags; +} diff --git a/libc/stdio/fprintf.c b/libc/stdio/fprintf.c new file mode 100644 index 00000000..3b2b6c40 --- /dev/null +++ b/libc/stdio/fprintf.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" + +int(fprintf)(FILE *f, const char *fmt, ...) { + int rc; + va_list va; + va_start(va, fmt); + rc = (vfprintf)(f, fmt, va); + va_end(va); + return rc; +} diff --git a/libc/stdio/fputc.c b/libc/stdio/fputc.c new file mode 100644 index 00000000..551a3bac --- /dev/null +++ b/libc/stdio/fputc.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/fputc.h" +#include "libc/stdio/stdio.h" + +/** + * Writes byte to stream. + * + * @return c (as unsigned char) if written or -1 w/ errno + */ +int fputc(int c, FILE *f) { return __fputc(c, f); } diff --git a/libc/stdio/fputc.h b/libc/stdio/fputc.h new file mode 100644 index 00000000..e996e644 --- /dev/null +++ b/libc/stdio/fputc.h @@ -0,0 +1,36 @@ +#ifndef COSMOPOLITAN_LIBC_STDIO_FPUTC_H_ +#define COSMOPOLITAN_LIBC_STDIO_FPUTC_H_ +#include "libc/assert.h" +#include "libc/calls/calls.h" +#include "libc/stdio/internal.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/o.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * Writes byte to stream. + * + * @return c (as unsigned char) if written or -1 w/ errno + */ +forceinline int __fputc(int c, FILE *f) { + /* assert((f->iomode & O_ACCMODE) != O_RDONLY); */ + if (c != -1) { + unsigned char ch = (unsigned char)c; + f->buf[f->end] = ch; + f->end = (f->end + 1) & (f->size - 1); + if (f->beg == f->end || f->bufmode == _IONBF || + (f->bufmode == _IOLBF && ch == '\n')) { + if (f->writer) { + return f->writer(f); + } else if (f->beg == f->end) { + return fseteof(f); + } + } + return ch; + } else { + return fseteof(f); + } +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_STDIO_FPUTC_H_ */ diff --git a/libc/stdio/fputhex.c b/libc/stdio/fputhex.c new file mode 100644 index 00000000..0f9fd394 --- /dev/null +++ b/libc/stdio/fputhex.c @@ -0,0 +1,27 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" + +int fputhex(int c, FILE *f) { + return (fputc("0123456789ABCDEF"[(c / 16) & 0xF], f) >= 0 && + fputc("0123456789ABCDEF"[(c % 16) & 0xF], f) >= 0) + ? c + : -1; +} diff --git a/libc/stdio/fputs.c b/libc/stdio/fputs.c new file mode 100644 index 00000000..2c1181af --- /dev/null +++ b/libc/stdio/fputs.c @@ -0,0 +1,47 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/errno.h" +#include "libc/stdio/fputc.h" +#include "libc/stdio/stdio.h" + +/** + * Writes string to stream. + * + * Writing stops at the NUL-terminator, which isn't included in output. + * This function blocks until the full string is written, unless an + * unrecoverable error happens. + * + * @param s is a NUL-terminated string that's non-NULL + * @param f is an open stream + * @return strlen(s) or -1 w/ errno on error + */ +int fputs(const char *s, FILE *f) { + unsigned char *p = (unsigned char *)s; + int res = 0; + while (*p) { + if (__fputc(*p++, f) == -1) { + if (ferror(f) == EINTR) continue; + if (feof(f)) errno = f->state = EPIPE; + return -1; + } + ++res; + } + return ++res; +} diff --git a/libc/stdio/fputwc.c b/libc/stdio/fputwc.c new file mode 100644 index 00000000..7c99f6b6 --- /dev/null +++ b/libc/stdio/fputwc.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/limits.h" +#include "libc/stdio/fputc.h" +#include "libc/stdio/internal.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" + +/** + * Writes wide character to stream. + * + * @return wc if written or -1 w/ errno + */ +wint_t fputwc(wchar_t wc, FILE *f) { + char buf[MB_LEN_MAX]; + unsigned len, i; + if (wc != -1) { + len = tpencode(buf, sizeof(buf), wc, false); + for (i = 0; i < len; ++i) { + if (__fputc(buf[i], f) == -1) return -1; + } + return wc; + } else { + return fseteof(f); + } +} diff --git a/libc/stdio/fputws.c b/libc/stdio/fputws.c new file mode 100644 index 00000000..d8e65069 --- /dev/null +++ b/libc/stdio/fputws.c @@ -0,0 +1,45 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/errno.h" +#include "libc/stdio/stdio.h" + +/** + * Writes wide character string to stream. + * + * Writing stops at the NUL-terminator, which isn't included in output. + * This function blocks until the full string is written, unless an + * unrecoverable error happens. + * + * @param s is a NUL-terminated string that's non-NULL + * @param f is an open stream + * @return strlen(s) or -1 w/ errno on error + */ +int fputws(const wchar_t *s, FILE *f) { + int res = 0; + while (*s) { + if (fputwc(*s++, f) == -1) { + if (ferror(f) == EINTR) continue; + if (feof(f)) errno = f->state = EPIPE; + return -1; + } + ++res; + } + return ++res; +} diff --git a/libc/stdio/fread.c b/libc/stdio/fread.c new file mode 100644 index 00000000..f9c3ea47 --- /dev/null +++ b/libc/stdio/fread.c @@ -0,0 +1,50 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/conv/sizemultiply.h" +#include "libc/errno.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/internal.h" +#include "libc/stdio/stdio.h" +#include "libc/str/internal.h" + +/** + * Reads data to stream. + * + * @param stride specifies the size of individual items + * @param count is the number of strides to fetch + * @return count on success, [0,count) on eof, or 0 on error or count==0 + */ +size_t fread(void *buf, size_t stride, size_t count, FILE *f) { + int c; + size_t i, bytes; + unsigned char *p; + if (!sizemultiply(&bytes, stride, count)) { + return fseterr(f, EOVERFLOW); + } + for (p = buf, i = 0; i < bytes; ++i) { + if ((c = fgetc(f)) == -1) { + if (i % stride != 0) abort(); /* todo(jart) */ + return i / stride; + } + p[i] = (unsigned char)c; + } + return count; +} diff --git a/libc/stdio/freadbuf.c b/libc/stdio/freadbuf.c new file mode 100644 index 00000000..76b9f043 --- /dev/null +++ b/libc/stdio/freadbuf.c @@ -0,0 +1,33 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/internal.h" +#include "libc/stdio/stdio.h" + +int freadbuf(FILE *f) { + ssize_t got; + got = read(f->fd, f->buf, f->size - 1); + if (got == -1) return fseterrno(f); + if (got == 0) return fseteof(f); + f->beg = 0; + f->end = got & (f->size - 1); + return got; +} diff --git a/libc/stdio/freopen.c b/libc/stdio/freopen.c new file mode 100644 index 00000000..91be142c --- /dev/null +++ b/libc/stdio/freopen.c @@ -0,0 +1,92 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/nt/enum/fileflagandattributes.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/f.h" +#include "libc/sysv/consts/fd.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/o.h" + +/** + * Overwrites existing stream. + * + * This function can be used in two ways. The first is sort of a + * mutating assignment. The second behavior, if pathname is NULL, is + * just changing the mode of an already open file descriptor. + * + * @param pathname is the file to open or NULL + * @param mode is the mode string flags, see fopenflags() + * @param stream is the existing allocated stream memory, which is + * flushed and closed if already open + * @return stream object if successful, or NULL w/ errno + */ +FILE *freopen(const char *pathname, const char *mode, FILE *stream) { + int fd; + unsigned flags; + flags = fopenflags(mode); + fflush(stream); + if (pathname) { + /* open new stream, overwriting existing alloc */ + if ((fd = open(pathname, flags, 0666)) != -1) { + if (!IsWindows()) { + dup3(fd, stream->fd, (flags & O_CLOEXEC)); + close(fd); + } else { + g_fds.p[stream->fd].handle = g_fds.p[fd].handle; + g_fds.p[fd].kind = kFdEmpty; + } + stream->iomode = flags; + return stream; + } else { + return NULL; + } + } else { + /* change mode of open file */ + if (!IsWindows()) { + if (flags & O_CLOEXEC) { + if (fcntl$sysv(stream->fd, F_SETFD, FD_CLOEXEC) == -1) return NULL; + flags &= ~O_CLOEXEC; + } + if (flags) { + if (fcntl$sysv(stream->fd, F_SETFL, flags) == -1) return NULL; + } + return stream; + } else { + if (ReOpenFile( + stream->fd, + (flags & O_RDWR) == O_RDWR ? kNtGenericWrite : kNtGenericRead, + (flags & O_EXCL) == O_EXCL + ? kNtFileShareExclusive + : kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete, + kNtFileAttributeNormal)) { + return stream; + } else { + winerr(); + return NULL; + } + } + } +} diff --git a/libc/stdio/freplenish.c b/libc/stdio/freplenish.c new file mode 100644 index 00000000..2eaa90ac --- /dev/null +++ b/libc/stdio/freplenish.c @@ -0,0 +1,70 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/struct/iovec.h" +#include "libc/errno.h" +#include "libc/sock/sock.h" +#include "libc/stdio/internal.h" +#include "libc/stdio/stdio.h" + +/** + * Fills empty space in buffer with whatever's available. + * + * This can be used alongside functions like select() or poll() to + * perform reads at opportune moments, thereby minimizing latency. + */ +int freplenish(FILE *f) { + ssize_t rc; + size_t got; + struct iovec iov[2]; + + if (f->beg == f->end) { + f->beg = f->end = 0; + } + + if (f->beg <= f->end) { + if (f->beg) { + iov[0].iov_base = f->buf + f->end; + iov[0].iov_len = f->size - f->end; + iov[1].iov_base = f->buf; + iov[1].iov_len = f->beg - 1; + rc = readv(f->fd, iov, 2); + } else { + rc = read(f->fd, f->buf, f->size - (f->end - f->beg) - 1); + } + } else { + if (f->end + 1 == f->beg) return 0; + rc = read(f->fd, f->buf + f->end, f->beg - f->end - 1); + } + + if (rc != -1) { + if (rc) { + got = rc; + f->end = (f->end + got) & (f->size - 1); + return got; + } else { + return fseteof(f); + } + } else if (errno == EINTR || errno == EAGAIN) { + return 0; + } else { + return fseterrno(f); + } +} diff --git a/libc/stdio/fscanf.c b/libc/stdio/fscanf.c new file mode 100644 index 00000000..b136c07b --- /dev/null +++ b/libc/stdio/fscanf.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/fmt/fmt.h" +#include "libc/stdio/stdio.h" + +/** + * Stream decoder. + * @see libc/fmt/vcscanf.h + */ +int(fscanf)(FILE *stream, const char *fmt, ...) { + int rc; + va_list va; + va_start(va, fmt); + rc = (vcscanf)((int (*)(void *))fgetc, stream, fmt, va); + va_end(va); + return rc; +} diff --git a/libc/stdio/fseek.c b/libc/stdio/fseek.c new file mode 100644 index 00000000..fe582477 --- /dev/null +++ b/libc/stdio/fseek.c @@ -0,0 +1,48 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/errno.h" +#include "libc/stdio/stdio.h" + +/** + * Repositions open file stream. + * + * This function flushes the buffer (unless it's currently in the EOF + * state) and then calls lseek() on the underlying file. If the stream + * is in the EOF state, this function can be used to restore it without + * needing to reopen the file. + * + * @param stream is a non-null stream handle + * @param offset is the byte delta + * @param whence can be SEET_SET, SEEK_CUR, or SEEK_END + * @returns new offset or -1 on error + */ +long fseek(FILE *stream, long offset, int whence) { + int skew = fflush(stream); + if (whence == SEEK_CUR && skew != -1) offset -= skew; + int64_t newpos; + if ((newpos = lseek(stream->fd, offset, whence)) != -1) { + stream->state = 0; + return newpos; + } else { + stream->state = errno == ESPIPE ? EBADF : errno; + return -1; + } +} diff --git a/libc/stdio/fseeko.S b/libc/stdio/fseeko.S new file mode 100644 index 00000000..379bad7a --- /dev/null +++ b/libc/stdio/fseeko.S @@ -0,0 +1,24 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +fseeko: jmp fseek + .endfn fseeko,globl diff --git a/libc/stdio/fseteof.c b/libc/stdio/fseteof.c new file mode 100644 index 00000000..41a246b3 --- /dev/null +++ b/libc/stdio/fseteof.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/internal.h" + +long fseteof(FILE *f) { return fseterr(f, -1); } diff --git a/libc/stdio/fseterr.c b/libc/stdio/fseterr.c new file mode 100644 index 00000000..cce329bc --- /dev/null +++ b/libc/stdio/fseterr.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/errno.h" +#include "libc/stdio/internal.h" + +long fseterr(FILE *f, int err) { + if (!err) err = -1; + f->state = f->state <= 0 ? err : f->state; + if (err > 0) errno = err; + return -1; +} diff --git a/libc/stdio/fseterrno.c b/libc/stdio/fseterrno.c new file mode 100644 index 00000000..f4f68f0e --- /dev/null +++ b/libc/stdio/fseterrno.c @@ -0,0 +1,23 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/errno.h" +#include "libc/stdio/internal.h" + +long fseterrno(FILE *f) { return fseterr(f, errno); } diff --git a/libc/stdio/fsetpos.c b/libc/stdio/fsetpos.c new file mode 100644 index 00000000..5fdc5a1e --- /dev/null +++ b/libc/stdio/fsetpos.c @@ -0,0 +1,25 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" +#include "libc/calls/calls.h" + +int fsetpos(FILE *stream, const fpos_t *pos) { + return fseek(stream, *pos, SEEK_SET); +} diff --git a/libc/stdio/ftell.c b/libc/stdio/ftell.c new file mode 100644 index 00000000..988b858d --- /dev/null +++ b/libc/stdio/ftell.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/stdio/stdio.h" + +/** + * Returns current position of stream. + * + * @param stream is a non-null stream handle + * @returns current byte offset from beginning of file, or -1 + */ +long ftell(FILE *stream) { return fseek(stream, 0, SEEK_CUR); } diff --git a/libc/stdio/ftello.S b/libc/stdio/ftello.S new file mode 100644 index 00000000..83e511ac --- /dev/null +++ b/libc/stdio/ftello.S @@ -0,0 +1,24 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +ftello: jmp ftell + .endfn ftello,globl diff --git a/libc/stdio/fwrite.c b/libc/stdio/fwrite.c new file mode 100644 index 00000000..23ac489f --- /dev/null +++ b/libc/stdio/fwrite.c @@ -0,0 +1,46 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/sizemultiply.h" +#include "libc/errno.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/fputc.h" +#include "libc/stdio/internal.h" +#include "libc/stdio/stdio.h" + +/** + * Writes data to stream. + * + * @param stride specifies the size of individual items + * @param count is the number of strides to fetch + * @return count on success, [0,count) on EOF, 0 on error or count==0 + */ +size_t fwrite(const void *data, size_t stride, size_t count, FILE *f) { + int rc; + size_t i, bytes; + const unsigned char *p = (const unsigned char *)data; + if (!sizemultiply(&bytes, stride, count)) return fseterr(f, EOVERFLOW); + for (i = 0; i < bytes; ++i) { + if ((rc = __fputc(p[i], f)) == -1) { + if (i % stride != 0) abort(); /* todo(jart) */ + return i / stride; + } + } + return count; +} diff --git a/libc/stdio/fwritebuf.c b/libc/stdio/fwritebuf.c new file mode 100644 index 00000000..6368fa0a --- /dev/null +++ b/libc/stdio/fwritebuf.c @@ -0,0 +1,44 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/nt/files.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/internal.h" +#include "libc/stdio/stdio.h" + +/** + * One-shot writes data from stream buffer to underlying file or device. + * + * @param f is a non-null open stream handle + * @return number of bytes written or -1 on error + */ +int fwritebuf(FILE *f) { + ssize_t put; + unsigned bytes; + bytes = (f->beg < f->end ? f->end : f->size) - f->beg; + if ((put = write(f->fd, &f->buf[f->beg], bytes)) == -1) { + return (int)fseterrno(f); + } + f->beg = (unsigned)((f->beg + put) & (f->size - 1)); + return bytes; +} diff --git a/libc/stdio/g_stdbuf.c b/libc/stdio/g_stdbuf.c new file mode 100644 index 00000000..e1fc72eb --- /dev/null +++ b/libc/stdio/g_stdbuf.c @@ -0,0 +1,23 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/internal.h" + +alignas(PAGESIZE) unsigned char g_stdoutbuf[BUFSIZ]; +alignas(PAGESIZE) unsigned char g_stderrbuf[BUFSIZ]; diff --git a/libc/stdio/g_stderr.c b/libc/stdio/g_stderr.c new file mode 100644 index 00000000..903ed519 --- /dev/null +++ b/libc/stdio/g_stderr.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/internal.h" +#include "libc/stdio/stdio.h" + +STATIC_YOINK("_init_g_stderr"); + +FILE *stderr; +hidden FILE g_stderr; +hidden unsigned char g_stderr_buf[BUFSIZ] aligned(PAGESIZE); + +static textstartup void g_stderr_init() { + fflushregister(stderr); +} +const void *const g_stderr_ctor[] initarray = {g_stderr_init}; diff --git a/libc/stdio/g_stderr_init.S b/libc/stdio/g_stderr_init.S new file mode 100644 index 00000000..da4b5143 --- /dev/null +++ b/libc/stdio/g_stderr_init.S @@ -0,0 +1,44 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/sysv/consts/o.h" +#include "libc/dce.h" +#include "libc/calls/calls.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/macros.h" +.yoink __FILE__ + + .init.start 400,_init_g_stderr + lea g_stderr(%rip),%rax + push $_IOLBF + pop (%rax) #→ f.fd + push STDERR_FILENO + pop 12(%rax) + mov O_WRONLY,%edx + mov %edx,4(%rax) #→ f.iomode + lea g_stderr_buf(%rip),%rcx + mov %rcx,24(%rax) #→ f.buf + movl $BUFSIZ,32(%rax) #→ f.size + lea fwritebuf(%rip),%rcx + lea fswritebuf(%rip),%rdx + testb IsMetal() + cmove %rcx,%rdx + mov %rdx,48(%rax) #→ f.writer + mov %rax,stderr(%rip) + .init.end 400,_init_g_stderr,globl,hidden diff --git a/libc/stdio/g_stdin.c b/libc/stdio/g_stdin.c new file mode 100644 index 00000000..0829e6d9 --- /dev/null +++ b/libc/stdio/g_stdin.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/internal.h" +#include "libc/stdio/stdio.h" + +STATIC_YOINK("_init_g_stdin"); + +FILE *stdin; +hidden FILE g_stdin; +hidden unsigned char g_stdin_buf[BUFSIZ] aligned(PAGESIZE); + +static textstartup void g_stdin_init() { + fflushregister(stdin); +} +const void *const g_stdin_ctor[] initarray = {g_stdin_init}; diff --git a/libc/stdio/g_stdin_init.S b/libc/stdio/g_stdin_init.S new file mode 100644 index 00000000..901c7deb --- /dev/null +++ b/libc/stdio/g_stdin_init.S @@ -0,0 +1,40 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/sysv/consts/o.h" +#include "libc/dce.h" +#include "libc/calls/calls.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/macros.h" +.yoink __FILE__ + + .init.start 400,_init_g_stdin + lea g_stdin(%rip),%rax + mov O_RDONLY,%edx + mov %edx,4(%rax) #→ f.iomode + lea g_stdin_buf(%rip),%rcx + mov %rcx,24(%rax) #→ f.buf + movl $BUFSIZ,32(%rax) #→ f.size + lea freadbuf(%rip),%rcx + lea fsreadbuf(%rip),%rdx + testb IsMetal() + cmove %rcx,%rdx + mov %rdx,40(%rax) #→ f.reader + mov %rax,stdin(%rip) + .init.end 400,_init_g_stdin,globl,hidden diff --git a/libc/stdio/g_stdio.c b/libc/stdio/g_stdio.c new file mode 100644 index 00000000..e578aa97 --- /dev/null +++ b/libc/stdio/g_stdio.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/internal.h" + +FILE g_stdio[3]; diff --git a/libc/stdio/g_stdout.c b/libc/stdio/g_stdout.c new file mode 100644 index 00000000..af23b5fd --- /dev/null +++ b/libc/stdio/g_stdout.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/pushpop.h" +#include "libc/calls/calls.h" +#include "libc/dce.h" +#include "libc/stdio/internal.h" +#include "libc/stdio/stdio.h" + +STATIC_YOINK("_init_g_stdout"); + +FILE *stdout; +hidden FILE g_stdout; +hidden unsigned char g_stdout_buf[BUFSIZ] aligned(PAGESIZE); + +static textstartup void g_stdout_init() { + struct FILE *sf; + sf = stdout; + asm("" : "+r"(sf)); + if (IsWindows() || ischardev(pushpop(sf->fd))) { + sf->bufmode = _IOLBF; + } + fflushregister(sf); +} + +const void *const g_stdout_ctor[] initarray = {g_stdout_init}; diff --git a/libc/stdio/g_stdout_init.S b/libc/stdio/g_stdout_init.S new file mode 100644 index 00000000..1a51909f --- /dev/null +++ b/libc/stdio/g_stdout_init.S @@ -0,0 +1,42 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/sysv/consts/o.h" +#include "libc/dce.h" +#include "libc/calls/calls.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/macros.h" +.yoink __FILE__ + + .init.start 400,_init_g_stdout + lea g_stdout(%rip),%rax + push STDOUT_FILENO + pop 12(%rax) #→ f.fd + mov O_WRONLY,%edx + mov %edx,4(%rax) #→ f.iomode + lea g_stdout_buf(%rip),%rcx + mov %rcx,24(%rax) #→ f.buf + movl $BUFSIZ,32(%rax) #→ f.size + lea fwritebuf(%rip),%rcx + lea fswritebuf(%rip),%rdx + testb IsMetal() + cmovz %rcx,%rdx + mov %rdx,48(%rax) #→ f.writer + mov %rax,stdout(%rip) + .init.end 400,_init_g_stdout,globl,hidden diff --git a/libc/stdio/getc.S b/libc/stdio/getc.S new file mode 100644 index 00000000..ef8bb3f3 --- /dev/null +++ b/libc/stdio/getc.S @@ -0,0 +1,25 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +#include "libc/notice.inc" +.yoink __FILE__ + +getc: jmp fgetc + .endfn getc,globl diff --git a/libc/stdio/getchar.S b/libc/stdio/getchar.S new file mode 100644 index 00000000..504d20d2 --- /dev/null +++ b/libc/stdio/getchar.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Reads uint8_t from standard input. +/ @return %al has result w/ rest of %rax cleared +getchar:mov stdin(%rip),%rdi + jmp fgetc + .endfn getchar,globl diff --git a/libc/stdio/getcmoar.c b/libc/stdio/getcmoar.c new file mode 100644 index 00000000..9bf51d6f --- /dev/null +++ b/libc/stdio/getcmoar.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/internal.h" +#include "libc/stdio/stdio.h" + +int __getc_moar(FILE *f) { + int b; + if (f->beg == f->end) { + if (!f->reader) return fseteof(f); + if (f->reader(f) == -1) return -1; + } + b = f->buf[f->beg]; + f->beg = (f->beg + 1) & (f->size - 1); + return b; +} diff --git a/libc/stdio/getdelim.c b/libc/stdio/getdelim.c new file mode 100644 index 00000000..3479cbf9 --- /dev/null +++ b/libc/stdio/getdelim.c @@ -0,0 +1,64 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/errno.h" +#include "libc/mem/mem.h" +#include "libc/stdio/internal.h" +#include "libc/stdio/stdio.h" + +#define GETDELIM_MAX 65536 + +/** + * Reads string from stream. + * + * @param line is the caller's buffer (in/out) which is extended + * automatically. *line may be NULL but only if *n is 0; + * NUL-termination is guaranteed FTMP + * @param n is the capacity of line (in/out) + * @param delim is the stop char (and NUL is implicitly too) + * @return number of bytes read, including delim, excluding NUL, or -1 + * w/ errno on EOF or error; see ferror() and feof() + * @note this function can't punt EINTR to caller + * @see getline(), gettok_r() + */ +ssize_t getdelim(char **line, size_t *n, int delim, FILE *f) { + STATIC_YOINK("realloc"); + assert((*line && *n) || (!*line && !*n)); + ssize_t rc = -1; + size_t i = 0; + int c; + for (;;) { + if ((c = getc(f)) == -1) { + if (ferror(f) == EINTR) continue; + if (feof(f) && i) rc = i; + break; + } + if (i + 2 >= *n && !grow(line, n, 1, 0)) { + fseterrno(f); + break; + } + if (((*line)[i++] = c) == delim) { + rc = i; + break; + } + } + if (*line && i < *n) (*line)[i] = '\0'; + return rc; +} diff --git a/libc/stdio/getline.c b/libc/stdio/getline.c new file mode 100644 index 00000000..669bda7e --- /dev/null +++ b/libc/stdio/getline.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" + +/** + * Reads line from stream. + * + * This function delegates to getdelim(), which provides further + * documentation. Concerning lines, please note the \n or \r\n are + * included in results, and can be removed with chomp(). + * + * @param line is the caller's buffer (in/out) which is extended + * automatically. *line may be NULL but only if *n is 0; + * NUL-termination is guaranteed FTMP + * @return number of bytes read, including delim, excluding NUL, or -1 + * w/ errno on EOF or error; see ferror() and feof() + * @see xgetline(), getdelim(), gettok_r() + */ +ssize_t getline(char **line, size_t *n, FILE *f) { + return getdelim(line, n, '\n', f); +} diff --git a/libc/stdio/gets.c b/libc/stdio/gets.c new file mode 100644 index 00000000..d85a7fb5 --- /dev/null +++ b/libc/stdio/gets.c @@ -0,0 +1,25 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/limits.h" +#include "libc/stdio/stdio.h" + +compatfn char *gets(char *s) { + return fgets(s, INT_MAX, stdin); +} diff --git a/libc/stdio/getwc.S b/libc/stdio/getwc.S new file mode 100644 index 00000000..94ed4346 --- /dev/null +++ b/libc/stdio/getwc.S @@ -0,0 +1,24 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +getwc: jmp fgetwc + .endfn getwc,globl diff --git a/libc/stdio/getwchar.S b/libc/stdio/getwchar.S new file mode 100644 index 00000000..e9d9e6f4 --- /dev/null +++ b/libc/stdio/getwchar.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Reads Thompson-Pike encoded varint from standard input. +/ @return %eax has result w/ rest of %rax cleared +getwchar: + mov stdin(%rip),%rdi + jmp fgetwc + .endfn getwchar,globl diff --git a/libc/stdio/internal.h b/libc/stdio/internal.h new file mode 100644 index 00000000..c57e872e --- /dev/null +++ b/libc/stdio/internal.h @@ -0,0 +1,25 @@ +#ifndef COSMOPOLITAN_LIBC_STDIO_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_STDIO_INTERNAL_H_ +#include "libc/stdio/stdio.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +extern FILE g_stdio[3]; +extern unsigned char g_stdinbuf[BUFSIZ]; +extern unsigned char g_stdoutbuf[BUFSIZ]; +extern unsigned char g_stderrbuf[BUFSIZ]; + +int fflushregister(FILE *) hidden; +void fflushunregister(FILE *) hidden; + +int freadbuf(FILE *f) hidden; +int fwritebuf(FILE *f) hidden; +int fsreadbuf(FILE *f) hidden; +int fswritebuf(FILE *f) hidden; +long fseteof(FILE *f) hidden; +long fseterrno(FILE *f) hidden; +long fseterr(FILE *f, int err) hidden; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_STDIO_INTERNAL_H_ */ diff --git a/libc/stdio/mkostemp.c b/libc/stdio/mkostemp.c new file mode 100644 index 00000000..61eaf48a --- /dev/null +++ b/libc/stdio/mkostemp.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/temp.h" + +int mkostemp(char *template, unsigned flags) { + return mkostempsm(template, 0, flags, 0600); +} diff --git a/libc/stdio/mkostemps.c b/libc/stdio/mkostemps.c new file mode 100644 index 00000000..a2b29278 --- /dev/null +++ b/libc/stdio/mkostemps.c @@ -0,0 +1,27 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/temp.h" + +/** + * Delegates to mkotempsm() w/ owner-only non-execute access. + */ +nodiscard int mkostemps(char *template, int suffixlen, unsigned flags) { + return mkostempsm(template, suffixlen, flags, 0600); +} diff --git a/libc/stdio/mkostempsm.c b/libc/stdio/mkostempsm.c new file mode 100644 index 00000000..1690b526 --- /dev/null +++ b/libc/stdio/mkostempsm.c @@ -0,0 +1,82 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/calls.h" +#include "libc/errno.h" +#include "libc/rand/lcg.h" +#include "libc/rand/rand.h" +#include "libc/stdio/temp.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/errfuns.h" + +#define RESEED 1024 +#define ATTEMPTS 10 +#define WILDCARD "XXXXXX" + +int mkostempsmi(char *tpl, int slen, unsigned flags, uint64_t *rando, int mode, + int openit(const char *file, int flags, ...)) { + size_t len = strlen(tpl); + size_t wildlen = strlen(WILDCARD); + if (len < wildlen || slen > len - wildlen) { + return einval(); + } + char *ss = tpl + len - wildlen - slen; + assert(memcmp(ss, WILDCARD, wildlen) == 0); + flags = (flags & ~(flags & O_ACCMODE)) | O_RDWR | O_CREAT | O_EXCL; + unsigned attempts = ATTEMPTS; + do { + char *p = ss; + uint32_t num = KnuthLinearCongruentialGenerator(rando) >> 32; + for (unsigned i = 0; i < wildlen; ++i) { + p[i] = "0123456789abcdefghijklmnopqrstuvwxyz"[num & 31]; + num >>= 5; + } + int fd; + if ((fd = openit(tpl, flags, 0600)) != -1) return fd; + } while (--attempts && errno == EEXIST); + memcpy(ss, WILDCARD, wildlen); + return -1; +} + +static uint64_t g_mkostemps_rand; +static uint64_t g_mkostemps_reseed; + +/** + * Opens unique temporary file. + * + * The substring XXXXXX is replaced with a pseudorandom number that's + * seeded automatically and grants 30 bits of randomness to each value. + * Retries are made in the unlikely event of collisions. + * + * @param template is a pathname relative to current directory by default, + * that needs to have "XXXXXX" at the end of the string + * @param suffixlen may be nonzero to permit characters after the XXXXXX + * @param flags can have O_APPEND, O_CLOEXEC, etc. + * @param mode is conventionally 0600, for owner-only non-exec access + * @return exclusive open file descriptor for generated pathname, + * or -1 w/ errno + * @see kTmpPath + */ +nodiscard int mkostempsm(char *template, int suffixlen, unsigned flags, + int mode) { + if (g_mkostemps_reseed++ % RESEED == 0) g_mkostemps_rand = rand64(); + return mkostempsmi(template, suffixlen, flags, &g_mkostemps_rand, mode, open); +} diff --git a/libc/stdio/mkstemp.c b/libc/stdio/mkstemp.c new file mode 100644 index 00000000..a2103175 --- /dev/null +++ b/libc/stdio/mkstemp.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/temp.h" + +int mkstemp(char *template) { return mkostempsm(template, 0, 0, 0600); } diff --git a/libc/stdio/mkstemps.c b/libc/stdio/mkstemps.c new file mode 100644 index 00000000..85bf0f7f --- /dev/null +++ b/libc/stdio/mkstemps.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/temp.h" + +int mkstemps(char *template, int suffixlen) { + return mkostempsm(template, suffixlen, 0, 0600); +} diff --git a/libc/stdio/mktemp.c b/libc/stdio/mktemp.c new file mode 100644 index 00000000..07234759 --- /dev/null +++ b/libc/stdio/mktemp.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/stdio/temp.h" +#include "libc/sysv/errfuns.h" + +/** + * Generates unique filename. + * + * This function is usually frowned upon, since it's been known to + * create nasty opportunities for race conditions. Our implementation + * reflects that; consider using mkostemps(). + */ +char *mktemp(char *template) { + int fd; + if ((fd = mkostemps(template, 0, 0)) != -1) { + close(fd); + unlink(template); + } else { + template[0] = '\0'; + } + return template; +} diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c new file mode 100644 index 00000000..4d6b8f3e --- /dev/null +++ b/libc/stdio/printf.c @@ -0,0 +1,71 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" + +/** + * Formats and writes string to stdout. + * + * Cosmopolitan supports most of the standard formatting behaviors + * described by `man 3 printf`, in addition to the following: + * + * - %jd, %jx, etc. are {,u}intmax_t which in Cosmopolitan is 128-bit. + * + * - %'d or %,d may be used to insert thousands separators. The prior is + * consistent with C; the latter is consistent with Python. + * + * - %m inserts strerror(errno) into the formatted output. This is + * consistent with glibc, musl, and uclibc. + * + * - %n inserts "\n" on non-Windows and "\r\n" on Windows. This is the + * same behavior as Java. It's incompatible with glibc's behavior, + * since that's problematic according to Android's security team. + * + * - %hs converts UTF-16/UCS-2 → UTF-8, which can be helpful on Windows. + * Formatting (e.g. %-10hs) will use monospace display width rather + * than string length or codepoint count. + * + * - %ls (or %Ls) converts UTF-32 → UTF-8. Formatting (e.g. %-10ls) will + * use monospace display width rather than string length. + * + * - The %#s and %#c alternate forms display values using the standard + * IBM standard 256-letter alphabet. Using %#.*s to specify length + * will allow true binary (i.e. with NULs) to be formatted. + * + * - The %'s and %'c alternate forms are Cosmopolitan extensions for + * escaping string literals for C/C++ and Python. The outer quotation + * marks can be added automatically using %`s. If constexpr format + * strings are used, we can avoid linking cescapec() too. + * + * - The backtick modifier (%`s and %`c) and repr() directive (%r) both + * ask the formatting machine to represent values as real code rather + * than using arbitrary traditions for displaying values. This means + * it implies the quoting modifier, wraps the value with {,u,L}['"] + * quotes, displays NULL as "NULL" rather than "(null)", etc. + * + * @see {,v}{,s{,n},{,{,x}as},f,d}printf + */ +int(printf)(const char* fmt, ...) { + int rc; + va_list va; + va_start(va, fmt); + rc = (vfprintf)(stdout, fmt, va); + va_end(va); + return rc; +} diff --git a/libc/stdio/putc.S b/libc/stdio/putc.S new file mode 100644 index 00000000..dd32608d --- /dev/null +++ b/libc/stdio/putc.S @@ -0,0 +1,24 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.inc" +.yoink __FILE__ + +putc: jmp fputc + .endfn putc,globl diff --git a/libc/stdio/putchar.c b/libc/stdio/putchar.c new file mode 100644 index 00000000..ac7cfcd8 --- /dev/null +++ b/libc/stdio/putchar.c @@ -0,0 +1,27 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" + +/** + * Writes byte to stdout. + * + * @return c (as unsigned char) if written or -1 w/ errno + */ +int putchar(int c) { return fputc(c, stdout); } diff --git a/libc/stdio/puts.c b/libc/stdio/puts.c new file mode 100644 index 00000000..d9b84ead --- /dev/null +++ b/libc/stdio/puts.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/fputc.h" +#include "libc/stdio/stdio.h" + +/** + * Writes string w/ trailing newline to stdout. + */ +int puts(const char *s) { + FILE *f = stdout; + int rc, res; + if ((res = rc = fputs(s, f)) == -1) return -1; + if ((rc = fputc('\n', f)) == -1) return -1; + return res + 1; +} diff --git a/libc/stdio/putwc.S b/libc/stdio/putwc.S new file mode 100644 index 00000000..5611de50 --- /dev/null +++ b/libc/stdio/putwc.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.inc" +.yoink __FILE__ + +/ Writes wide character to stream. +/ @param %edi is the wide character +/ @param %rsi is the FILE stream pointer +/ @return %eax is set to %edi param or -1 on error +putwc: jmp fputwc + .endfn putwc,globl diff --git a/libc/stdio/putwchar.c b/libc/stdio/putwchar.c new file mode 100644 index 00000000..0ce595da --- /dev/null +++ b/libc/stdio/putwchar.c @@ -0,0 +1,27 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" + +/** + * Writes wide character to stdout. + * + * @return wc if written or -1 w/ errno + */ +wint_t putwchar(wchar_t wc) { return fputwc(wc, stdout); } diff --git a/libc/stdio/rewind.c b/libc/stdio/rewind.c new file mode 100644 index 00000000..0469bde4 --- /dev/null +++ b/libc/stdio/rewind.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/stdio/stdio.h" + +/** + * Moves standard i/o stream to beginning of file. + * + * Like fseek(), this function can be used to restore a stream from the + * EOF state, without reopening it. + */ +void rewind(FILE *stream) { + fseek(stream, 0, SEEK_SET); +} diff --git a/libc/stdio/scanf.c b/libc/stdio/scanf.c new file mode 100644 index 00000000..708a3ff6 --- /dev/null +++ b/libc/stdio/scanf.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/fmt/fmt.h" +#include "libc/stdio/stdio.h" + +/** + * Standard input decoder. + * @see libc/fmt/vcscanf.h + */ +int(scanf)(const char *fmt, ...) { + int rc; + va_list va; + va_start(va, fmt); + rc = (vcscanf)((int (*)(void *))fgetc, stdin, fmt, va); + va_end(va); + return rc; +} diff --git a/libc/stdio/serialstdio.c b/libc/stdio/serialstdio.c new file mode 100644 index 00000000..4b1b93c2 --- /dev/null +++ b/libc/stdio/serialstdio.c @@ -0,0 +1,51 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" +#include "libc/nexgen32e/uart.h" +#include "libc/stdio/internal.h" +#include "libc/stdio/stdio.h" + +static void fin(FILE *f) { + f->buf[f->end] = inb(f->fd); + f->end = (f->end + 1) & (f->size - 1); +} + +static void fout(FILE *f) { + outb(f->fd, f->buf[f->beg]); + f->beg = (f->beg + 1) & (f->size - 1); +} + +static int serialstdio(FILE *f, unsigned char status, void action(FILE *f)) { + int block = 1; + unsigned tally = 0; + while (f->end != f->beg) { + if (!(inb(f->fd + UART_LSR) & status)) { + if (!block) break; + asm("pause"); + } else { + action(f); + tally++; + } + } + return (int)tally; +} + +int fsreadbuf(FILE *f) { return serialstdio(f, UART_TTYDA, fin); } +int fswritebuf(FILE *f) { return serialstdio(f, UART_TTYTXR, fout); } diff --git a/libc/stdio/setbuf.c b/libc/stdio/setbuf.c new file mode 100644 index 00000000..6133c187 --- /dev/null +++ b/libc/stdio/setbuf.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" +#include "libc/sysv/errfuns.h" + +/** + * Sets buffer on stdio stream. + */ +void setbuf(FILE *f, char *buf) { setbuffer(f, buf, BUFSIZ); } diff --git a/libc/stdio/setbuffer.c b/libc/stdio/setbuffer.c new file mode 100644 index 00000000..0fe48231 --- /dev/null +++ b/libc/stdio/setbuffer.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/errfuns.h" + +/** + * Sets buffer on stdio stream. + */ +void setbuffer(FILE *f, char *buf, size_t size) { + if (size && popcount(size) != 1) abort(); + if (buf && f->buf != (unsigned char *)buf) { + free_s(&f->buf); + if (!size) size = BUFSIZ; + f->buf = (unsigned char *)buf; + } + if (size) { + f->size = size; + } +} diff --git a/libc/stdio/setvbuf.c b/libc/stdio/setvbuf.c new file mode 100644 index 00000000..bcf5dc8d --- /dev/null +++ b/libc/stdio/setvbuf.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/errfuns.h" + +/** + * Tunes buffering settings for an stdio stream. + * + * @param mode may be _IOFBF, _IOLBF, or _IONBF + * @param buf may optionally be non-NULL to set the stream's underlying + * buffer, which the stream will own, but won't free + * @param size must be a two power if buf is provided + * @return 0 on success or -1 on error + */ +int setvbuf(FILE *f, char *buf, int mode, size_t size) { + if (size && popcount(size) != 1) return einval(); + setbuffer(f, buf, size); + f->bufmode = mode; + return 0; +} diff --git a/libc/stdio/stdio.h b/libc/stdio/stdio.h new file mode 100644 index 00000000..cad7d06c --- /dev/null +++ b/libc/stdio/stdio.h @@ -0,0 +1,129 @@ +#ifndef COSMOPOLITAN_LIBC_STDIO_STDIO_H_ +#define COSMOPOLITAN_LIBC_STDIO_STDIO_H_ +#include "libc/fmt/pflink.h" +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § standard i/o ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +typedef struct FILE { + uint8_t bufmode; /* 0: _IOFBF, etc. (ignored if fd is -1) */ + bool noclose; /* 1: for fake dup() */ + uint32_t iomode; /* 4: O_RDONLY, etc. (ignored if fd is -1) */ + int32_t state; /* 8: 0=OK, -1=EOF, >0=errno */ + int fd; /* 12: ≥0=fd, -1=closed|buffer */ + uint32_t beg; /* 16 */ + uint32_t end; /* 20 */ + uint8_t *buf; /* 24 */ + size_t size; /* 32 */ + int (*reader)(struct FILE *f); /* 40 */ + int (*writer)(struct FILE *f); /* 48 */ +} FILE; + +extern FILE *stdin; +extern FILE *stdout; +extern FILE *stderr; + +errno_t ferror(FILE *) paramsnonnull(); +void clearerr(FILE *) paramsnonnull(); +int feof(FILE *) paramsnonnull(); +int getc(FILE *) paramsnonnull(); +int putc(int, FILE *) paramsnonnull(); +int fflush(FILE *); +int fgetc(FILE *) paramsnonnull(); +int ungetc(int, FILE *) paramsnonnull(); +int fileno(FILE *) paramsnonnull(); +int fputc(int, FILE *) paramsnonnull(); +int fputs(const char *, FILE *) paramsnonnull(); +int fputws(const wchar_t *, FILE *) paramsnonnull(); +char *fgets(char *, int, FILE *) paramsnonnull(); +wchar_t *fgetws(wchar_t *, int, FILE *) paramsnonnull(); +wint_t fputwc(wchar_t, FILE *) paramsnonnull(); +wint_t putwchar(wchar_t); +wint_t getwchar(void); +wint_t fgetwc(FILE *) paramsnonnull(); +int getchar(void); +int putchar(int); +int puts(const char *) paramsnonnull(); +ssize_t getline(char **, size_t *, FILE *) paramsnonnull(); +ssize_t getdelim(char **, size_t *, int, FILE *) paramsnonnull(); +int fputhex(int, FILE *) paramsnonnull(); +int fgethex(FILE *) paramsnonnull(); +FILE *fopen(const char *, const char *) paramsnonnull() nodiscard; +FILE *fdopen(int, const char *) paramsnonnull() nodiscard; +FILE *fmemopen(void *, size_t, const char *) paramsnonnull((3)) nodiscard; +FILE *freopen(const char *, const char *, FILE *) paramsnonnull((2, 3)); +size_t fread(void *, size_t, size_t, FILE *) paramsnonnull(); +size_t fwrite(const void *, size_t, size_t, FILE *) paramsnonnull(); +int freplenish(FILE *) paramsnonnull(); +int fclose(FILE *); +int fclose_s(FILE **) paramsnonnull(); +long fseek(FILE *, long, int) paramsnonnull(); +long ftell(FILE *) paramsnonnull(); +void rewind(FILE *) paramsnonnull(); +int fopenflags(const char *) paramsnonnull(); +unsigned favail(FILE *); +void setbuf(FILE *, char *); +void setbuffer(FILE *, char *, size_t); +int setvbuf(FILE *, char *, int, size_t); + +typedef uint64_t fpos_t; +compatfn char *gets(char *) paramsnonnull(); +compatfn int fgetpos(FILE *, fpos_t *) paramsnonnull(); +compatfn int fsetpos(FILE *, const fpos_t *) paramsnonnull(); +compatfn int64_t fseeko(FILE *, long, int) paramsnonnull(); +compatfn int64_t ftello(FILE *) paramsnonnull(); + +int system(const char *); +int systemecho(const char *); + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § standard i/o » formatting ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +int printf(const char *, ...) printfesque(1) + paramsnonnull((1)) nothrow nocallback; +int vprintf(const char *, va_list) paramsnonnull() nothrow nocallback; +int fprintf(FILE *, const char *, ...) printfesque(2) + paramsnonnull((1, 2)) nothrow nocallback; +int vfprintf(FILE *, const char *, va_list) paramsnonnull() nothrow nocallback; +int scanf(const char *, ...) scanfesque(1); +int vscanf(const char *, va_list); +int fscanf(FILE *, const char *, ...) scanfesque(2); +int vfscanf(FILE *, const char *, va_list); + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § standard i/o » optimizations ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +int __getc_moar(FILE *); + +#define putc(c, f) fputc(c, f) +#define getc(f) (f->beg + 1 < f->end ? f->buf[f->beg++] : __getc_moar(f)) + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +#define printf(FMT, ...) (printf)(PFLINK(FMT), ##__VA_ARGS__) +#define vprintf(FMT, VA) (vprintf)(PFLINK(FMT), VA) +#define fprintf(F, FMT, ...) (fprintf)(F, PFLINK(FMT), ##__VA_ARGS__) +#define vfprintf(F, FMT, VA) (vfprintf)(F, PFLINK(FMT), VA) +#define vscanf(FMT, VA) (vscanf)(SFLINK(FMT), VA) +#define scanf(FMT, ...) (scanf)(SFLINK(FMT), ##__VA_ARGS__) +#define fscanf(F, FMT, ...) (fscanf)(F, SFLINK(FMT), ##__VA_ARGS__) +#define vfscanf(F, FMT, VA) (vfscanf)(F, SFLINK(FMT), VA) +#endif + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § standard i/o » definitions for assembler fans ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define stdin SYMBOLIC(stdin) +#define stdout SYMBOLIC(stdout) +#define stderr SYMBOLIC(stderr) + +#endif /* COSMOPOLITAN_LIBC_STDIO_STDIO_H_ */ diff --git a/libc/stdio/stdio.mk b/libc/stdio/stdio.mk new file mode 100644 index 00000000..4fe66068 --- /dev/null +++ b/libc/stdio/stdio.mk @@ -0,0 +1,64 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += LIBC_STDIO + +LIBC_STDIO_ARTIFACTS += LIBC_STDIO_A +LIBC_STDIO = $(LIBC_STDIO_A_DEPS) $(LIBC_STDIO_A) +LIBC_STDIO_A = o/$(MODE)/libc/stdio/stdio.a +LIBC_STDIO_A_FILES := $(wildcard libc/stdio/*) $(wildcard libc/stdio/unlocked/*) +LIBC_STDIO_A_HDRS = $(filter %.h,$(LIBC_STDIO_A_FILES)) +LIBC_STDIO_A_SRCS_S = $(filter %.S,$(LIBC_STDIO_A_FILES)) +LIBC_STDIO_A_SRCS_C = $(filter %.c,$(LIBC_STDIO_A_FILES)) + +LIBC_STDIO_A_SRCS = \ + $(LIBC_STDIO_A_SRCS_S) \ + $(LIBC_STDIO_A_SRCS_C) + +LIBC_STDIO_A_OBJS = \ + $(LIBC_STDIO_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_STDIO_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_STDIO_A_SRCS_C:%.c=o/$(MODE)/%.o) + +LIBC_STDIO_A_CHECKS = \ + $(LIBC_STDIO_A).pkg \ + $(LIBC_STDIO_A_HDRS:%=o/$(MODE)/%.ok) + +LIBC_STDIO_A_DIRECTDEPS = \ + LIBC_ALG \ + LIBC_BITS \ + LIBC_CALLS \ + LIBC_CALLS_HEFTY \ + LIBC_CONV \ + LIBC_ESCAPE \ + LIBC_FMT \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_STUBS \ + LIBC_STR \ + LIBC_RAND \ + LIBC_RUNTIME \ + LIBC_NT_KERNELBASE \ + LIBC_SYSV \ + LIBC_SYSV_CALLS + +LIBC_STDIO_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_STDIO_A_DIRECTDEPS),$($(x)))) + +$(LIBC_STDIO_A):libc/stdio/ \ + $(LIBC_STDIO_A).pkg \ + $(LIBC_STDIO_A_OBJS) + +$(LIBC_STDIO_A).pkg: \ + $(LIBC_STDIO_A_OBJS) \ + $(foreach x,$(LIBC_STDIO_A_DIRECTDEPS),$($(x)_A).pkg) + +LIBC_STDIO_LIBS = $(foreach x,$(LIBC_STDIO_ARTIFACTS),$($(x))) +LIBC_STDIO_SRCS = $(foreach x,$(LIBC_STDIO_ARTIFACTS),$($(x)_SRCS)) +LIBC_STDIO_HDRS = $(foreach x,$(LIBC_STDIO_ARTIFACTS),$($(x)_HDRS)) +LIBC_STDIO_CHECKS = $(foreach x,$(LIBC_STDIO_ARTIFACTS),$($(x)_CHECKS)) +LIBC_STDIO_OBJS = $(foreach x,$(LIBC_STDIO_ARTIFACTS),$($(x)_OBJS)) +$(LIBC_STDIO_OBJS): $(BUILD_FILES) libc/stdio/stdio.mk + +.PHONY: o/$(MODE)/libc/stdio +o/$(MODE)/libc/stdio: $(LIBC_STDIO_CHECKS) diff --git a/libc/stdio/system.c b/libc/stdio/system.c new file mode 100644 index 00000000..84fb9081 --- /dev/null +++ b/libc/stdio/system.c @@ -0,0 +1,158 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/calls/hefty/ntspawn.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/escape/escape.h" +#include "libc/mem/mem.h" +#include "libc/nt/accounting.h" +#include "libc/nt/enum/startf.h" +#include "libc/nt/enum/status.h" +#include "libc/nt/files.h" +#include "libc/nt/process.h" +#include "libc/nt/runtime.h" +#include "libc/nt/startupinfo.h" +#include "libc/nt/struct/processinformation.h" +#include "libc/nt/synchronization.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/errfuns.h" +#include "libc/x/x.h" + +#define SHELL_BIN "/bin/sh" +#define SHELL_ARG "-c" +#define CMD_C "CMD /C " + +static int system$sysv(const char *cmdline) { + if (cmdline != NULL) { + int pid = fork$sysv(); + if (pid == 0) { + struct mem { + char shell[sizeof(SHELL_BIN)]; + char arg[sizeof(SHELL_ARG)]; + char *args[4]; + char cmdline[]; + } *mem = malloc(sizeof(struct mem) + (strlen(cmdline) + 1)); + if (!mem) return enomem(); + strcpy(mem->shell, SHELL_BIN); + strcpy(mem->arg, SHELL_ARG); + mem->args[0] = mem->shell; + mem->args[1] = mem->arg; + mem->args[2] = mem->cmdline; + mem->args[3] = NULL; + strcpy(mem->cmdline, cmdline); + execve$sysv(mem->shell, mem->args, environ); + abort(); + } + int rc; + int wstatus; + if ((rc = wait4$sysv(pid, &wstatus, 0, NULL)) != -1) rc = wstatus; + return rc; + } else { + return fileexists(SHELL_BIN); + } +} + +static textwindows noinline int system$nt(const char *cmdline) { + if (cmdline != NULL) { + int rc = -1; + unsigned dosquotemultiplier = 2; + unsigned len = strlen(cmdline); + unsigned cmdline16bytes = (len + 1) * sizeof(uint16_t); + unsigned quotedcmdline16bytes = + strlen(CMD_C) * sizeof(uint16_t) + cmdline16bytes * dosquotemultiplier; + void *mem = malloc(sizeof(struct NtProcessInformation) + cmdline16bytes + + quotedcmdline16bytes); + if (mem == NULL) return enomem(); + struct NtProcessInformation *info = mem; + uint16_t *cmdline16 = + (uint16_t *)((char *)mem + sizeof(struct NtProcessInformation)); + uint16_t *quotedcmdline16 = + (uint16_t *)((char *)mem + sizeof(struct NtProcessInformation) + + cmdline16bytes); + strcpyzbw(cmdline16, cmdline); + strcpyzbw(quotedcmdline16, CMD_C); + if (escapedos(quotedcmdline16 + strlen(CMD_C), len * dosquotemultiplier, + cmdline16, len)) { + struct NtStartupInfo startinfo; + memset(&startinfo, 0, sizeof(startinfo)); + startinfo.cb = sizeof(struct NtStartupInfo); + startinfo.dwFlags = kNtStartfUsestdhandles; + startinfo.hStdInput = STDIN_FILENO; + startinfo.hStdOutput = STDOUT_FILENO; + startinfo.hStdError = STDERR_FILENO; + if (CreateProcess( + /* lpApplicationName */ NULL, + /* lpCommandLine */ quotedcmdline16, + /* lpProcessAttributes */ NULL, + /* lpThreadAttributes */ NULL, + /* bInheritHandles */ true, + /* dwCreationFlags */ kNtCreateNoWindow, + /* lpEnvironment */ NULL, + /* lpCurrentDirectory */ NULL, + /* lpStartupInfo */ &startinfo, + /* lpProcessInformation */ info)) { + uint32_t dwExitCode = kNtStillActive; + int status; + do { + WaitForSingleObject(info->hProcess, 0xffffffff); + } while ((status = GetExitCodeProcess(info->hProcess, &dwExitCode)) && + dwExitCode == kNtStillActive); + if (weaken(fflush)) { + weaken(fflush)(*weaken(stderr)); + } + rc = (dwExitCode & 0xff) << 8; /* @see WEXITSTATUS() */ + CloseHandle(info->hProcess); + CloseHandle(info->hThread); + } else { + rc = winerr(); + } + } else { + rc = einval(); + } + free(mem), mem = NULL; + return rc; + } else { + /* how could cmd.exe not exist? */ + return true; + } +} + +/** + * Launches program with system command interpreter. + * + * @param cmdline is an interpreted Turing-complete command + * @return -1 if child process couldn't be created, otherwise a wait + * status that can be accessed using macros like WEXITSTATUS(s) + */ +int system(const char *cmdline) { + int rc; + if (weaken(fflush)) weaken(fflush)(NULL); + if (!IsWindows()) { + rc = system$sysv(cmdline); + } else { + rc = system$nt(cmdline); + } + return rc; +} diff --git a/libc/stdio/systemecho.c b/libc/stdio/systemecho.c new file mode 100644 index 00000000..3e867bb8 --- /dev/null +++ b/libc/stdio/systemecho.c @@ -0,0 +1,25 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" + +int systemecho(const char *cmd) { + fprintf(stderr, "+ %s\n", cmd); + return system(cmd); +} diff --git a/libc/stdio/temp.h b/libc/stdio/temp.h new file mode 100644 index 00000000..722dc40e --- /dev/null +++ b/libc/stdio/temp.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_STDIO_TEMP_H_ +#define COSMOPOLITAN_LIBC_STDIO_TEMP_H_ +#include "libc/stdio/stdio.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +nodiscard FILE *tmpfile(void); +nodiscard int mkstemp(char *); +nodiscard int mkostemp(char *, unsigned); +nodiscard int mkstemps(char *, int); +nodiscard int mkostemps(char *, int, unsigned); +nodiscard int mkostempsm(char *, int, unsigned, int); +compatfn char *mktemp(char *); + +int mkostempsmi(char *, int, unsigned, uint64_t *, int, + int openit(const char *, int, ...)) hidden nodiscard; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_STDIO_TEMP_H_ */ diff --git a/libc/stdio/tmpfile.c b/libc/stdio/tmpfile.c new file mode 100644 index 00000000..b382d729 --- /dev/null +++ b/libc/stdio/tmpfile.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/fmt/fmt.h" +#include "libc/stdio/stdio.h" +#include "libc/stdio/temp.h" + +/** + * Creates a temporary file. + * + * @see mkostempsm(), kTmpPath + */ +FILE *tmpfile(void) { + int fd; + if ((fd = mkostemps("/tmp/tmp.XXXXXX", 0, 0)) == -1) return NULL; + return fdopen(fd, "w+"); +} diff --git a/libc/stdio/ungetc.c b/libc/stdio/ungetc.c new file mode 100644 index 00000000..8f53ba5a --- /dev/null +++ b/libc/stdio/ungetc.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" + +int ungetc(int c, FILE *f) { + f->buf[f->beg] = c; + f->beg = (f->beg - 1u) & (f->size - 1); + return c; +} diff --git a/libc/stdio/unlocked.h b/libc/stdio/unlocked.h new file mode 100644 index 00000000..f6e7330b --- /dev/null +++ b/libc/stdio/unlocked.h @@ -0,0 +1,33 @@ +#ifndef COSMOPOLITAN_LIBC_STDIO_UNLOCKED_H_ +#define COSMOPOLITAN_LIBC_STDIO_UNLOCKED_H_ +#include "libc/stdio/stdio.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +int getc_unlocked(FILE *f) paramsnonnull(); +int getchar_unlocked(void); +int putc_unlocked(int c, FILE *f) paramsnonnull(); +int putchar_unlocked(int c); +void clearerr_unlocked(FILE *f); +int feof_unlocked(FILE *f); +int ferror_unlocked(FILE *f); +int fileno_unlocked(FILE *f); +int fflush_unlocked(FILE *f); +int fgetc_unlocked(FILE *f); +int fputc_unlocked(int c, FILE *f); +size_t fread_unlocked(void *ptr, size_t size, size_t n, FILE *f); +size_t fwrite_unlocked(const void *ptr, size_t size, size_t n, FILE *f); +char *fgets_unlocked(char *s, int n, FILE *f); +int fputs_unlocked(const char *s, FILE *f); +wint_t getwc_unlocked(FILE *f); +wint_t getwchar_unlocked(void); +wint_t fgetwc_unlocked(FILE *f); +wint_t fputwc_unlocked(wchar_t wc, FILE *f); +wint_t putwc_unlocked(wchar_t wc, FILE *f); +wint_t putwchar_unlocked(wchar_t wc); +wchar_t *fgetws_unlocked(wchar_t *ws, int n, FILE *f); +int fputws_unlocked(const wchar_t *ws, FILE *f); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_STDIO_UNLOCKED_H_ */ diff --git a/libc/stdio/unlocked/clearerr_unlocked.S b/libc/stdio/unlocked/clearerr_unlocked.S new file mode 100644 index 00000000..c93e8e68 --- /dev/null +++ b/libc/stdio/unlocked/clearerr_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +clearerr_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call clearerr + .leafepilogue + .endfn clearerr_unlocked,globl diff --git a/libc/stdio/unlocked/feof_unlocked.S b/libc/stdio/unlocked/feof_unlocked.S new file mode 100644 index 00000000..61402fb2 --- /dev/null +++ b/libc/stdio/unlocked/feof_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +feof_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call feof + .leafepilogue + .endfn feof_unlocked,globl diff --git a/libc/stdio/unlocked/ferror_unlocked.S b/libc/stdio/unlocked/ferror_unlocked.S new file mode 100644 index 00000000..d620a0c3 --- /dev/null +++ b/libc/stdio/unlocked/ferror_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +ferror_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call ferror + .leafepilogue + .endfn ferror_unlocked,globl diff --git a/libc/stdio/unlocked/fflush_unlocked.S b/libc/stdio/unlocked/fflush_unlocked.S new file mode 100644 index 00000000..1d026b51 --- /dev/null +++ b/libc/stdio/unlocked/fflush_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +fflush_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call fflush + .leafepilogue + .endfn fflush_unlocked,globl diff --git a/libc/stdio/unlocked/fgetc_unlocked.S b/libc/stdio/unlocked/fgetc_unlocked.S new file mode 100644 index 00000000..dde34fbc --- /dev/null +++ b/libc/stdio/unlocked/fgetc_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +fgetc_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call fgetc + .leafepilogue + .endfn fgetc_unlocked,globl diff --git a/libc/stdio/unlocked/fgets_unlocked.S b/libc/stdio/unlocked/fgets_unlocked.S new file mode 100644 index 00000000..03b14548 --- /dev/null +++ b/libc/stdio/unlocked/fgets_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +fgets_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call fgets + .leafepilogue + .endfn fgets_unlocked,globl diff --git a/libc/stdio/unlocked/fgetwc_unlocked.S b/libc/stdio/unlocked/fgetwc_unlocked.S new file mode 100644 index 00000000..d7a682aa --- /dev/null +++ b/libc/stdio/unlocked/fgetwc_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +fgetwc_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call fgetwc + .leafepilogue + .endfn fgetwc_unlocked,globl diff --git a/libc/stdio/unlocked/fgetws_unlocked.S b/libc/stdio/unlocked/fgetws_unlocked.S new file mode 100644 index 00000000..83d589d5 --- /dev/null +++ b/libc/stdio/unlocked/fgetws_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +fgetws_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call fgetws + .leafepilogue + .endfn fgetws_unlocked,globl diff --git a/libc/stdio/unlocked/fileno_unlocked.S b/libc/stdio/unlocked/fileno_unlocked.S new file mode 100644 index 00000000..1653507d --- /dev/null +++ b/libc/stdio/unlocked/fileno_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +fileno_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call fileno + .leafepilogue + .endfn fileno_unlocked,globl diff --git a/libc/stdio/unlocked/fputc_unlocked.S b/libc/stdio/unlocked/fputc_unlocked.S new file mode 100644 index 00000000..f077d0ba --- /dev/null +++ b/libc/stdio/unlocked/fputc_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +fputc_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call fputc + .leafepilogue + .endfn fputc_unlocked,globl diff --git a/libc/stdio/unlocked/fputs_unlocked.S b/libc/stdio/unlocked/fputs_unlocked.S new file mode 100644 index 00000000..260d907c --- /dev/null +++ b/libc/stdio/unlocked/fputs_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +fputs_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call fputs + .leafepilogue + .endfn fputs_unlocked,globl diff --git a/libc/stdio/unlocked/fputwc_unlocked.S b/libc/stdio/unlocked/fputwc_unlocked.S new file mode 100644 index 00000000..f53c4fa6 --- /dev/null +++ b/libc/stdio/unlocked/fputwc_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +fputwc_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call fputwc + .leafepilogue + .endfn fputwc_unlocked,globl diff --git a/libc/stdio/unlocked/fputws_unlocked.S b/libc/stdio/unlocked/fputws_unlocked.S new file mode 100644 index 00000000..03ba73df --- /dev/null +++ b/libc/stdio/unlocked/fputws_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +fputws_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call fputws + .leafepilogue + .endfn fputws_unlocked,globl diff --git a/libc/stdio/unlocked/fread_unlocked.S b/libc/stdio/unlocked/fread_unlocked.S new file mode 100644 index 00000000..c1914067 --- /dev/null +++ b/libc/stdio/unlocked/fread_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +fread_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call fread + .leafepilogue + .endfn fread_unlocked,globl diff --git a/libc/stdio/unlocked/fwrite_unlocked.S b/libc/stdio/unlocked/fwrite_unlocked.S new file mode 100644 index 00000000..8101b4f7 --- /dev/null +++ b/libc/stdio/unlocked/fwrite_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +fwrite_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call fwrite + .leafepilogue + .endfn fwrite_unlocked,globl diff --git a/libc/stdio/unlocked/getc_unlocked.S b/libc/stdio/unlocked/getc_unlocked.S new file mode 100644 index 00000000..0c3afcf6 --- /dev/null +++ b/libc/stdio/unlocked/getc_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +getc_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call getc + .leafepilogue + .endfn getc_unlocked,globl diff --git a/libc/stdio/unlocked/getchar_unlocked.S b/libc/stdio/unlocked/getchar_unlocked.S new file mode 100644 index 00000000..2c28604a --- /dev/null +++ b/libc/stdio/unlocked/getchar_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +getchar_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call getchar + .leafepilogue + .endfn getchar_unlocked,globl diff --git a/libc/stdio/unlocked/getwc_unlocked.S b/libc/stdio/unlocked/getwc_unlocked.S new file mode 100644 index 00000000..1aa735fb --- /dev/null +++ b/libc/stdio/unlocked/getwc_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +getwc_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call fgetwc_unlocked + .leafepilogue + .endfn getwc_unlocked,globl diff --git a/libc/stdio/unlocked/getwchar_unlocked.S b/libc/stdio/unlocked/getwchar_unlocked.S new file mode 100644 index 00000000..05b9a9ee --- /dev/null +++ b/libc/stdio/unlocked/getwchar_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +getwchar_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call getwchar + .leafepilogue + .endfn getwchar_unlocked,globl diff --git a/libc/stdio/unlocked/putc_unlocked.S b/libc/stdio/unlocked/putc_unlocked.S new file mode 100644 index 00000000..4ea2e5dd --- /dev/null +++ b/libc/stdio/unlocked/putc_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +putc_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call putc + .leafepilogue + .endfn putc_unlocked,globl diff --git a/libc/stdio/unlocked/putchar_unlocked.S b/libc/stdio/unlocked/putchar_unlocked.S new file mode 100644 index 00000000..ba62c3db --- /dev/null +++ b/libc/stdio/unlocked/putchar_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +putchar_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call putchar + .leafepilogue + .endfn putchar_unlocked,globl diff --git a/libc/stdio/unlocked/putwc_unlocked.S b/libc/stdio/unlocked/putwc_unlocked.S new file mode 100644 index 00000000..ab5f4daa --- /dev/null +++ b/libc/stdio/unlocked/putwc_unlocked.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +putwc_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call fputwc_unlocked + .leafepilogue + .endfn putwc_unlocked,globl diff --git a/libc/stdio/unlocked/putwchar_unlocked.S b/libc/stdio/unlocked/putwchar_unlocked.S new file mode 100644 index 00000000..46a5d5ea --- /dev/null +++ b/libc/stdio/unlocked/putwchar_unlocked.S @@ -0,0 +1,29 @@ + +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +putwchar_unlocked: + .leafprologue + .profilable # so we can fix code supporting this abomination + call putwchar + .leafepilogue + .endfn putwchar_unlocked,globl diff --git a/libc/stdio/vfprintf.c b/libc/stdio/vfprintf.c new file mode 100644 index 00000000..7b2b8620 --- /dev/null +++ b/libc/stdio/vfprintf.c @@ -0,0 +1,47 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/fmt/fmt.h" +#include "libc/limits.h" +#include "libc/stdio/fputc.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/errfuns.h" + +struct state { + FILE *const f; + unsigned toto; +}; + +static int vfprintfputchar(int c, struct state *st) { + if (st->toto <= INT_MAX) { + st->toto++; + return __fputc(c, st->f); + } else { + return eoverflow(); + } +} + +int(vfprintf)(FILE *f, const char *fmt, va_list va) { + struct state st[1] = {{f, 0}}; + if (palandprintf(vfprintfputchar, st, fmt, va) != -1) { + return st->toto; + } else { + return -1; + } +} diff --git a/libc/stdio/vfscanf.c b/libc/stdio/vfscanf.c new file mode 100644 index 00000000..33730b76 --- /dev/null +++ b/libc/stdio/vfscanf.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/fmt/fmt.h" +#include "libc/stdio/stdio.h" + +/** + * Stream decoder. + * @see libc/fmt/vcscanf.h + */ +int(vfscanf)(FILE *stream, const char *fmt, va_list ap) { + return (vcscanf)((int (*)(void *))fgetc, stream, fmt, ap); +} diff --git a/libc/stdio/vprintf.c b/libc/stdio/vprintf.c new file mode 100644 index 00000000..2cd753a5 --- /dev/null +++ b/libc/stdio/vprintf.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" + +int(vprintf)(const char* fmt, va_list va) { + return (vfprintf)(stdout, fmt, va); +} diff --git a/libc/stdio/vscanf.c b/libc/stdio/vscanf.c new file mode 100644 index 00000000..f5415a3e --- /dev/null +++ b/libc/stdio/vscanf.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/fmt/fmt.h" +#include "libc/stdio/stdio.h" + +/** + * String decoder. + * @see libc/fmt/vcscanf.h + */ +int(vscanf)(const char *fmt, va_list ap) { + return (vcscanf)((int (*)(void *))fgetc, stdin, fmt, ap); +} diff --git a/libc/str/appendchar.h b/libc/str/appendchar.h new file mode 100644 index 00000000..cec840c4 --- /dev/null +++ b/libc/str/appendchar.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_RUNTIME_APPENDCHAR_H_ +#define COSMOPOLITAN_LIBC_RUNTIME_APPENDCHAR_H_ +#include "libc/str/str.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +forceinline void AppendChar(char **p, char *pe, wint_t c) { + if (*p < pe) *p += tpencode(*p, pe - *p, c, false); +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_RUNTIME_APPENDCHAR_H_ */ diff --git a/libc/str/chomp.c b/libc/str/chomp.c new file mode 100644 index 00000000..3b25df8d --- /dev/null +++ b/libc/str/chomp.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Mutates line to remove line-ending characters. + * + * @param line is NULL-propagating + * @see getline + */ +char *(chomp)(char *line) { + if (line) line[strcspn(line, "\r\n")] = '\0'; + return line; +} diff --git a/libc/str/chomp16.c b/libc/str/chomp16.c new file mode 100644 index 00000000..a12185d2 --- /dev/null +++ b/libc/str/chomp16.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Mutates line to remove line-ending characters. + * + * @param line is NULL-propagating + * @see getline + */ +char16_t *chomp16(char16_t *line) { + if (line) line[strcspn(line, u"\r\n")] = '\0'; + return line; +} diff --git a/libc/str/endswith.c b/libc/str/endswith.c new file mode 100644 index 00000000..22605cae --- /dev/null +++ b/libc/str/endswith.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Returns true if s has suffix. + * + * @param s is a NUL-terminated string + * @param suffix is also NUL-terminated + */ +bool(endswith)(const char *s, const char *suffix) { + size_t l1, l2; + if (s == suffix) return true; + l1 = strlen(s); + l2 = strnlen(suffix, l1); + if (l2 > l1) return false; + return memcmp(s + (l1 - l2) * sizeof(char), suffix, l2 * sizeof(char)) == 0; +} diff --git a/libc/str/endswith16.c b/libc/str/endswith16.c new file mode 100644 index 00000000..de930973 --- /dev/null +++ b/libc/str/endswith16.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +#undef char +#undef endswith +#undef strlen +#undef strnlen + +#define char char16_t +#define endswith endswith16 +#define strlen strlen16 +#define strnlen strnlen16 + +#include "libc/str/endswith.c" diff --git a/libc/str/getkvlin.c b/libc/str/getkvlin.c new file mode 100644 index 00000000..b09cc4a9 --- /dev/null +++ b/libc/str/getkvlin.c @@ -0,0 +1,33 @@ +/*-*- mode:c; indent-tabs-mode:nil; tab-width:2; coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +int getkvlin(const char *name, const char *const unsorted[]) { + if (unsorted) { + unsigned namelen = strlen(name); + for (int i = 0; unsorted[i]; ++i) { + if (strncmp(unsorted[i], name, namelen) == 0 && + unsorted[i][namelen] == '=') { + return i; + } + } + } + return -1; +} diff --git a/libc/str/getutf16.ncabi.c b/libc/str/getutf16.ncabi.c new file mode 100644 index 00000000..6e5570e8 --- /dev/null +++ b/libc/str/getutf16.ncabi.c @@ -0,0 +1,45 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/errno.h" +#include "libc/str/str.h" + +/** + * Decodes UTF-16 character. + * + * @param s is a NUL-terminated string + * @return number of bytes (NUL counts as 1) or -1 w/ errno + * @note synchronization is performed to skip leading continuations; + * canonicalization and validation are performed to some extent + */ +unsigned(getutf16)(const char16_t *p, wint_t *wc) { + unsigned skip = 0; + while ((p[skip] & UTF16_MASK) == UTF16_CONT) skip++; + if ((p[skip] & UTF16_MASK) != UTF16_MOAR) { + *wc = p[skip]; + return skip + 1; + } else if ((p[skip + 1] & UTF16_MASK) != UTF16_CONT) { + *wc = INVALID_CODEPOINT; + return -1; + } else { + *wc = 0x10000 + ((((unsigned)p[skip + 0] - 0xd800) << 10) + + ((unsigned)p[skip + 1] - 0xdc00)); + return skip + 2; + } +} diff --git a/libc/str/indexdoublenulstring.c b/libc/str/indexdoublenulstring.c new file mode 100644 index 00000000..43d0821e --- /dev/null +++ b/libc/str/indexdoublenulstring.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +const char *indexdoublenulstring(const char *p, unsigned i) { + while (i--) { + const char *p2 = rawmemchr(p, '\0'); + if (p2 == p) return NULL; + p = p2 + 1; + } + return p; +} diff --git a/libc/str/internal.h b/libc/str/internal.h new file mode 100644 index 00000000..ec6ab016 --- /dev/null +++ b/libc/str/internal.h @@ -0,0 +1,63 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#ifndef COSMOPOLITAN_LIBC_STR_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_STR_INTERNAL_H_ +#include "libc/str/str.h" + +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +hidden extern const uint32_t kSha256Tab[64]; + +extern const struct TpEncode { + uint8_t mark; + uint8_t len; +} kTpDecoderRing[32]; + +forceinline struct TpEncode UseTpDecoderRing(wint_t c) { + unsigned msb; + if (c) { + asm("bsr\t%1,%0" : "=r"(msb) : "rm"(c) : "cc"); + } else { + msb = 0; + } + return kTpDecoderRing[msb]; +} + +nodebuginfo forceinline bool32 ismoar(wint_t c) { + return (c & 0b11000000) == 0b11000000; +} + +nodebuginfo forceinline bool32 iscont(wint_t c) { + return (c & 0b11000000) == 0b10000000; +} + +extern const uint32_t kCrc32Tab[256]; + +char *strstr$sse42(const char *, const char *) strlenesque hidden; +char16_t *strstr16$sse42(const char16_t *, const char16_t *) strlenesque hidden; +void *memmem$sse42(const void *, size_t, const void *, + size_t) strlenesque hidden; +uint32_t crc32c$sse42(uint32_t, const void *, size_t) strlenesque hidden; +uint32_t crc32$pclmul(uint32_t, const void *, size_t) hidden; +void sha256$x86(uint32_t[hasatleast 8], const uint8_t[hasatleast 64], + uint32_t) hidden; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_STR_INTERNAL_H_ */ diff --git a/libc/str/isnotplaintext.c b/libc/str/isnotplaintext.c new file mode 100644 index 00000000..19f5af2d --- /dev/null +++ b/libc/str/isnotplaintext.c @@ -0,0 +1,64 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +/** + * Checks if memory address contains non-plain text. + * + * @param data points to memory that's interpreted as char + * @param size is usually strlen(data) and provided by caller + * @return NULL if plain text, or pointer to first non-text datum + * @type char may be 6/7/8/16/32/64-bit signed/unsigned single/multi + * @author Justine Alexandra Roberts Tunney + * @see ASA X3.4, ISO/IEC 646, ITU T.50, ANSI X3.64-1979 + * @perf 27gBps on i7-6700 w/ -O3 -mavx2 + * @cost 143 bytes of code w/ -Os + */ +void *isnotplaintext(const void *data, size_t size) { + /* + * ASCII, EBCDIC, UNICODE, ISO IR-67, etc. all agree upon the + * encoding of the NUL, SOH, STX, and ETX characters due to a + * longstanding human tradition of using them for the purpose + * of delimiting text from non-text, b/c fixed width integers + * makes their presence in binary formats nearly unavoidable. + */ +#define isnotplain(C) (0 <= (C) && (C) < 4) + char no; + unsigned i; + const char *p, *pe; + if (CHAR_BIT > 6) { + p = (const char *)data; + pe = (const char *)(p + size); + for (; ((intptr_t)p & 31) && p < pe; ++p) { + if (isnotplain(*p)) return p; + } + for (; p + 64 < pe; p += 64) { + no = 0; + for (i = 0; i < 64; ++i) { + no |= isnotplain(p[i]); + } + if (no & 1) break; + } + for (; p < pe; ++p) { + if (isnotplain(*p)) return p; + } + } + return 0; +#undef isnotplain +} diff --git a/libc/str/iswctype.c b/libc/str/iswctype.c new file mode 100644 index 00000000..a4a48ab0 --- /dev/null +++ b/libc/str/iswctype.c @@ -0,0 +1,52 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +#include "libc/str/str.h" + +static const struct WcTypes { + char name[8]; + wctype_t type; +} wctypes[] = {{"alnum", 0x006}, {"alpha", 0x002}, {"blank", 0x080}, + {"cntrl", 0x100}, {"digit", 0x004}, {"graph", 0x200}, + {"lower", 0x020}, {"print", 0x010}, {"punct", 0x300}, + {"space", 0x001}, {"upper", 0x040}, {"xdigit", 0x008}}; + +wctype_t wctype(const char *s) { + char name[8]; + strncpy(name, s, sizeof(name)); + for (unsigned i = 0; i < ARRAYLEN(wctypes); ++i) { + if (memcmp(name, wctypes[i].name, sizeof(name)) == 0) { + return wctypes[i].type; + } + } + return 0; +} + +int iswctype(wint_t c, wctype_t type) { + if (c < 128) { + if (!(type & ~0xff)) { + return kCtype[(unsigned char)type]; + } + if (type == 0x100) return iscntrl((unsigned char)c); + if (type == 0x200) return isgraph((unsigned char)c); + if (type == 0x300) return ispunct((unsigned char)c); + } + return 0; +} diff --git a/libc/str/knuthmultiplicativehash.h b/libc/str/knuthmultiplicativehash.h new file mode 100644 index 00000000..5e0fc8d7 --- /dev/null +++ b/libc/str/knuthmultiplicativehash.h @@ -0,0 +1,26 @@ +#ifndef COSMOPOLITAN_LIBC_STR_KNUTHMULTIPLICATIVEHASH_H_ +#define COSMOPOLITAN_LIBC_STR_KNUTHMULTIPLICATIVEHASH_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +forceinline uint32_t KnuthMultiplicativeHash32(const void *buf, size_t size) { + /* frozen due to presence in sqlite & promise in libc/getuid.c */ + const unsigned char *const p = (const unsigned char *)buf; + uint32_t hash = 0, kPhiPrime = 0x9e3779b1; + size_t i; + for (i = 0; i < size; i++) hash = (p[i] + hash) * kPhiPrime; + return hash; +} + +forceinline uint64_t KnuthMultiplicativeHash(const void *buf, size_t size) { + /* TODO(jart): verify w/ primary source */ + const unsigned char *const p = (const unsigned char *)buf; + uint64_t hash = 0, kPhiPrime = 0x9e3779b9925d4c17; + size_t i; + for (i = 0; i < size; i++) hash = (p[i] + hash) * kPhiPrime; + return hash; +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_STR_KNUTHMULTIPLICATIVEHASH_H_ */ diff --git a/libc/str/ktpdecoderring.S b/libc/str/ktpdecoderring.S new file mode 100644 index 00000000..3101d3b7 --- /dev/null +++ b/libc/str/ktpdecoderring.S @@ -0,0 +1,56 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Thompson-Pike Decoder Ring. +/ +/ The IA-32 BSR instruction can be used to turn a 32-bit +/ number into an index for this table. +/ +/ @see libc/str/internal.h + .rodata + .align 2 +kTpDecoderRing: + .rept 7 # MSB≤6 (0x7F) + .byte 0b00000000,1 # mark,len +/ 0b11000000 # mask + .endr + .rept 4 # MSB≤10 (0x7FF) + .byte 0b11000000,2 # mark,len +/ 0b11100000 # mask + .endr + .rept 5 # MSB≤15 (0xFFFF) + .byte 0b11100000,3 # mark,len +/ 0b11110000 # mask + .endr + .rept 5 # MSB≤20 (0x1FFFFF) + .byte 0b11110000,4 # mark,len +/ 0b11111000 # mask + .endr + .rept 5 # MSB≤25 (0x3FFFFFF) + .byte 0b11111000,5 # mark,len +/ 0b11111100 # mask + .endr + .rept 6 # MSB≤31 (0xffffffff) + .byte 0b11111100,6 # mark,len + .endr + .endobj kTpDecoderRing,globl,hidden + .previous diff --git a/libc/str/mbtowc.c b/libc/str/mbtowc.c new file mode 100644 index 00000000..31c778a4 --- /dev/null +++ b/libc/str/mbtowc.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/limits.h" +#include "libc/macros.h" +#include "libc/str/str.h" + +compatfn int mbtowc(wchar_t *wc, const char *s, size_t n) { + if (!s) return 0; + alignas(8) char alt[ROUNDUP(MB_CUR_MAX, 8)]; + if (n < MB_CUR_MAX) { + memset(alt, 0, sizeof(alt)); + memcpy(alt, s, n); + s = &alt[0]; + } + wint_t wi; + int rc = tpdecode(s, &wi); + if (wc) *wc = (wchar_t)wi; + return rc; +} diff --git a/libc/str/memccpy.c b/libc/str/memccpy.c new file mode 100644 index 00000000..5569c4f6 --- /dev/null +++ b/libc/str/memccpy.c @@ -0,0 +1,55 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Copies at most 𝑛 bytes from 𝑠 to 𝑑 until 𝑐 is encountered. + * + * This is little-known C Standard Library approach, dating back to the + * Fourth Edition of System Five, for copying a C strings to fixed-width + * buffers, with added generality. + * + * For example, strictly: + * + * char buf[16]; + * CHECK_NOTNULL(memccpy(buf, s, '\0', sizeof(buf))); + * + * Or unstrictly: + * + * if (!memccpy(buf, s, '\0', sizeof(buf))) strcpy(buf, "?"); + * + * Are usually more sensible than the following: + * + * char cstrbuf[16]; + * snprintf(cstrbuf, sizeof(cstrbuf), "%s", CSTR); + * + * @return 𝑑 + idx(𝑐) + 1, or NULL if 𝑐 ∉ 𝑠₀․․ₙ₋₁ + * @note 𝑑 and 𝑠 can't overlap + * @asyncsignalsafe + */ +void *memccpy(void *d, const void *s, int c, size_t n) { + const char *p, *pe; + if ((pe = memchr((p = s), c, n))) { + return mempcpy(d, s, pe - p + 1); + } else { + memcpy(d, s, n); + return NULL; + } +} diff --git a/libc/str/memfrob.c b/libc/str/memfrob.c new file mode 100644 index 00000000..45ebbc0b --- /dev/null +++ b/libc/str/memfrob.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Memfrob implements a crypto algorithm proven to be unbreakable, + * without meeting its requirements concerning secrecy or length. + */ +void *memfrob(void *buf, size_t size) { + unsigned char *p = (unsigned char *)buf; + for (size_t i = 0; i < size; ++i) p[i] ^= '*'; + return buf; +} diff --git a/libc/str/pututf16.ncabi.c b/libc/str/pututf16.ncabi.c new file mode 100644 index 00000000..9bcbe1e7 --- /dev/null +++ b/libc/str/pututf16.ncabi.c @@ -0,0 +1,57 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Encodes character to string as UTF-16. + * + * Implementation Details: The header macro should ensure this function + * is only called for truly huge codepoints. Plus this function makes a + * promise to not clobber any registers but %rax. + * + * @param s is what ch gets encoded to + * @param size is the number of shorts available in s + * @param awesome enables numbers the IETF unilaterally banned + * @return number of shorts written or -1 w/ errno + */ +int(pututf16)(char16_t *s, size_t size, wint_t wc, bool awesome) { + wint_t wc2; + if (size) { + if ((0 <= wc && wc < 32) && awesome && size >= 2) { + s[0] = 0xd800; + s[1] = 0xdc00 | wc; + return 2; + } + if ((0 <= wc && wc <= 0xD7FF) || (0xE000 <= wc && wc <= 0xFFFF)) { + s[0] = wc; + return 1; + } else if (0x10000 <= wc && wc <= 0x10FFFF && size >= 2) { + wc2 = wc - 0x10000; + s[0] = (wc2 >> 10) + 0xd800; + s[1] = (wc2 & 1023) + 0xdc00; + return 2; + } else { + s[0] = INVALID_CODEPOINT; + return -1; + } + } else { + return 0; + } +} diff --git a/libc/str/rindex.S b/libc/str/rindex.S new file mode 100644 index 00000000..8a33ce9e --- /dev/null +++ b/libc/str/rindex.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns pointer to last instance of character the BSD way. +/ +/ @param rdi is a non-null NUL-terminated string pointer +/ @param esi is the search byte +/ @return rax points to result, or NULL if not found +rindex: jmp strrchr + .endfn rindex,globl diff --git a/libc/str/sha256.c b/libc/str/sha256.c new file mode 100644 index 00000000..59ebc021 --- /dev/null +++ b/libc/str/sha256.c @@ -0,0 +1,135 @@ +/********************************************************************* +* Filename: sha256.c +* Author: Brad Conte (brad AT bradconte.com) +* Copyright: +* Disclaimer: This code is presented "as is" without any guarantees. +* Details: Implementation of the SHA-256 hashing algorithm. + SHA-256 is one of the three algorithms in the SHA2 + specification. The others, SHA-384 and SHA-512, are not + offered in this implementation. + Algorithm specification can be found here: + * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf + This implementation uses little endian byte order. +*********************************************************************/ +#include "libc/bits/safemacros.h" +#include "libc/dce.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/str/internal.h" +#include "libc/str/str.h" + +#define ROTLEFT(a, b) (((a) << (b)) | ((a) >> (32 - (b)))) +#define ROTRIGHT(a, b) (((a) >> (b)) | ((a) << (32 - (b)))) +#define CH(x, y, z) (((x) & (y)) ^ (~(x) & (z))) +#define MAJ(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) +#define EP0(x) (ROTRIGHT(x, 2) ^ ROTRIGHT(x, 13) ^ ROTRIGHT(x, 22)) +#define EP1(x) (ROTRIGHT(x, 6) ^ ROTRIGHT(x, 11) ^ ROTRIGHT(x, 25)) +#define SIG0(x) (ROTRIGHT(x, 7) ^ ROTRIGHT(x, 18) ^ ((x) >> 3)) +#define SIG1(x) (ROTRIGHT(x, 17) ^ ROTRIGHT(x, 19) ^ ((x) >> 10)) + +static void sha256_transform(uint32_t state[hasatleast 8], + const uint8_t data[hasatleast 64]) { + size_t i; + uint32_t a, b, c, d, e, f, g, h, t1, t2, m[64]; + for (i = 0; i < 16; ++i, data += 4) { + m[i] = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; + } + for (; i < 64; ++i) { + m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; + } + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + for (i = 0; i < 64; ++i) { + t1 = h + EP1(e) + CH(e, f, g) + kSha256Tab[i] + m[i]; + t2 = EP0(a) + MAJ(a, b, c); + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; +} + +void sha256_init(struct Sha256Ctx *ctx) { + ctx->datalen = 0; + ctx->bitlen = 0; + ctx->state[0] = 0x6a09e667; + ctx->state[1] = 0xbb67ae85; + ctx->state[2] = 0x3c6ef372; + ctx->state[3] = 0xa54ff53a; + ctx->state[4] = 0x510e527f; + ctx->state[5] = 0x9b05688c; + ctx->state[6] = 0x1f83d9ab; + ctx->state[7] = 0x5be0cd19; +} + +void sha256_update(struct Sha256Ctx *ctx, const uint8_t *data, size_t size) { + size_t i; + i = 0; +#if 0 + if (!IsTiny() && size >= 64 && + (X86_HAVE(SHA) && X86_HAVE(SSE4_1) && X86_HAVE(SSSE3))) { + sha256$x86(ctx->state, data, size); + i += rounddown(size, 16); + } +#endif + for (; i < size; ++i) { + ctx->data[ctx->datalen] = data[i]; + ctx->datalen++; + if (ctx->datalen == 64) { + sha256_transform(ctx->state, ctx->data); + ctx->bitlen += 512; + ctx->datalen = 0; + } + } +} + +void sha256_final(struct Sha256Ctx *ctx, uint8_t *hash) { + size_t i; + i = ctx->datalen; + if (ctx->datalen < 56) { + ctx->data[i++] = 0x80; + while (i < 56) ctx->data[i++] = 0x00; + } else { + ctx->data[i++] = 0x80; + while (i < 64) ctx->data[i++] = 0x00; + sha256_transform(ctx->state, ctx->data); + memset(ctx->data, 0, 56); + } + ctx->bitlen += ctx->datalen * 8; + ctx->data[63] = ctx->bitlen; + ctx->data[62] = ctx->bitlen >> 8; + ctx->data[61] = ctx->bitlen >> 16; + ctx->data[60] = ctx->bitlen >> 24; + ctx->data[59] = ctx->bitlen >> 32; + ctx->data[58] = ctx->bitlen >> 40; + ctx->data[57] = ctx->bitlen >> 48; + ctx->data[56] = ctx->bitlen >> 56; + sha256_transform(ctx->state, ctx->data); + for (i = 0; i < 4; ++i) { + hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; + hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; + hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; + hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; + hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; + hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff; + hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff; + hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff; + } +} diff --git a/libc/str/startswith.c b/libc/str/startswith.c new file mode 100644 index 00000000..5513b571 --- /dev/null +++ b/libc/str/startswith.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Returns true if s has prefix. + * @param s is a NUL-terminated string + * @param prefix is also NUL-terminated + */ +bool(startswith)(const char *s, const char *prefix) { + return strncmp(s, prefix, strlen(prefix)) == 0; +} diff --git a/libc/str/startswith16.c b/libc/str/startswith16.c new file mode 100644 index 00000000..af0d17b6 --- /dev/null +++ b/libc/str/startswith16.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +#undef char +#undef startswith +#undef strlen +#undef strncmp + +#define char char16_t +#define startswith startswith16 +#define strlen strlen16 +#define strncmp strncmp16 + +#include "libc/str/startswith.c" diff --git a/libc/str/stpcpy.c b/libc/str/stpcpy.c new file mode 100644 index 00000000..949240f4 --- /dev/null +++ b/libc/str/stpcpy.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Copies string, returning pointer to where copying ended. + * @see strcpy(), mempcpy() + * @asyncsignalsafe + */ +char *stpcpy(char *dst, const char *src) { + return (char *)mempcpy(dst, src, strlen(src) + 1) - 1; +} diff --git a/libc/str/stpncpy.c b/libc/str/stpncpy.c new file mode 100644 index 00000000..41f17de0 --- /dev/null +++ b/libc/str/stpncpy.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Prepares static search buffer. + * + * 1. If SRC is too long, it's truncated and *not* NUL-terminated. + * 2. If SRC is too short, the remainder is zero-filled. + * + * Please note this function isn't designed to prevent untrustworthy + * data from modifying memory without authorization. Consider trying + * memccpy() for that purpose. + * + * @return dest + stride + * @see stncpy(), memccpy() + * @asyncsignalsafe + */ +char *stpncpy(char *dest, const char *src, size_t stride) { + char *p; + if ((p = memccpy(dest, src, '\0', stride))) { + memset(p, 0, dest + stride - p); + } + return dest + stride; +} diff --git a/libc/str/str.h b/libc/str/str.h new file mode 100644 index 00000000..8616f474 --- /dev/null +++ b/libc/str/str.h @@ -0,0 +1,683 @@ +#ifndef COSMOPOLITAN_LIBC_STR_STR_H_ +#define COSMOPOLITAN_LIBC_STR_STR_H_ +#include "libc/bits/bits.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § characters » asa x3.4-1967 ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + fourth age telecommunications */ + +extern const uint8_t gperf_downcase[256]; +extern const uint8_t kCtype[256]; +extern const uint8_t kToLower[256]; +extern const uint8_t kToUpper[256]; +extern const uint16_t kToLower16[256]; +extern const uint8_t kBase36[256]; +extern const char16_t kCp437[256]; /** IBM Code Page 437 */ + +int isascii(int); +int isspace(int); +int isalpha(int); +int isdigit(int); +int isalnum(int); +int isxdigit(int); +int isprint(int); +int islower(int); +int isupper(int); +int isblank(int); +int iscntrl(int); +int isgraph(int); +int tolower(int); +int ispunct(int); +int toupper(int); +int hextoint(int); + +void *isnotplaintext(const void *, size_t) nothrow nocallback nosideeffect; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § characters » thompson-pike encoding ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + fifth age telecommunications + + 0123456789abcdef + ┌0─ ☺☻♥♦♣♠•◘○◙♂♀♪♫☼┬───Control + └1─►◄↕‼¶§▬↨↑↓→←∟↔▲▼┘ + ┌2─ !"#$%&'()*+,-./┐ + │3 0123456789:;<=>?│ + │4 @ABCDEFGHIJKLMNO├───ASA x3.4-1967 + │5 PQRSTUVWXYZ[\]^_│ + │6 `abcdefghijklmno│ + └7─pqrstuvwxyz{|}~⌂┘ + ┌8─ÇüéâäàåçêëèïîìÄÅ┐ + │9 ÉæÆôöòûùÿÖÜ¢£¥€ƒ├───Thompson-Pike Continuation + │a á¡óúñѪº¿⌐¬½¼¡«»│ (not really characters) + └b─░▒▓│┤╡╢╖╕╣║╗╝╜╛┐┘ + ┌c─└┴┬├─┼╞╟╚╔╩╦╠═╬╧┬───1 Continuation will follow + └d─╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀┘ + ─e─αßΓπΣσμτΦΘΩδ∞φε∩────2 Continuations will follow + f─≡±≥≤⌠⌡÷≈°∙·√ⁿ²■λ + │ ││ │││└┤ + │ ││ │└┤ └───5 Continuations follow (and is negative) + │ │└─┬┘ └─────5 Continuations follow (note: -1=λ┐┐┐┐┐) + └───┬──┘ └────────4 Continuations follow + └──────────────3 Continuations follow */ + +#define INVALID_CODEPOINT 0xfffd +#define UTF16_MASK 0b1111110000000000 +#define UTF16_MOAR 0b1101100000000000 /* 0xD800..0xDBFF */ +#define UTF16_CONT 0b1101110000000000 /* 0xDC00..0xDBFF */ + +unsigned tpencode(char *buf, size_t size, wint_t c, bool32 awesome) + paramsnonnull() libcesque; +int tpdecode(const char *s, wint_t *out) paramsnonnull((1)) libcesque; +unsigned getutf16(const char16_t *p, wint_t *wc); +int pututf16(char16_t *s, size_t size, wint_t wc, bool awesome); +int iswalnum(wint_t); +int iswalpha(wint_t); +int iswblank(wint_t); +int iswcntrl(wint_t); +int iswdigit(wint_t); +int iswgraph(wint_t); +int iswlower(wint_t); +int iswspace(wint_t); +int iswupper(wint_t); +int iswxdigit(wint_t); +int iswpunct(wint_t); +int iswprint(wint_t); +unsigned towlower(unsigned); +unsigned towupper(unsigned); + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § strings ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +void *memset(void *, int, size_t) memcpyesque; +void *memcpy(void *restrict, const void *restrict, size_t) memcpyesque; +void *mempcpy(void *restrict, const void *restrict, size_t) memcpyesque; +void *memccpy(void *restrict, const void *restrict, int, size_t) memcpyesque; +void *memmove(void *, const void *, size_t) memcpyesque; +void *memeqmask(void *, const void *, const void *, size_t) memcpyesque; + +size_t strlen(const char *) strlenesque; +size_t strnlen(const char *, size_t) strlenesque; +size_t strnlen_s(const char *, size_t); +char *strchr(const char *, int) strlenesque; +char *index(const char *, int) strlenesque; +void *memchr(const void *, int, size_t) strlenesque; +char *strchrnul(const char *, int) strlenesque returnsnonnull; +void *rawmemchr(const void *, int) strlenesque returnsnonnull; +void bzero(void *, size_t) paramsnonnull() libcesque; +size_t strlen16(const char16_t *) strlenesque; +size_t strnlen16(const char16_t *, size_t) strlenesque; +size_t strnlen16_s(const char16_t *, size_t); +char16_t *strchr16(const char16_t *, int) strlenesque; +void *memchr16(const void *, int, size_t) strlenesque; +char16_t *strchrnul16(const char16_t *, int) strlenesque returnsnonnull; +void *rawmemchr16(const void *, int) strlenesque returnsnonnull; +size_t wcslen(const wchar_t *) strlenesque; +size_t wcsnlen(const wchar_t *, size_t) strlenesque; +size_t wcsnlen_s(const wchar_t *, size_t); +wchar_t *wcschr(const wchar_t *, wchar_t) strlenesque; +wchar_t *wmemchr(const wchar_t *, wchar_t, size_t) strlenesque; +wchar_t *wcschrnul(const wchar_t *, wchar_t) strlenesque returnsnonnull; +char *strstr(const char *, const char *) strlenesque; +char16_t *strstr16(const char16_t *, const char16_t *) strlenesque; +wchar_t *wcsstr(const wchar_t *, const wchar_t *) strlenesque; +void *rawwmemchr(const void *, wchar_t) strlenesque returnsnonnull; +int memcmp(const void *, const void *, size_t) strlenesque; +int strcmp(const char *, const char *) strlenesque; +int strncmp(const char *, const char *, size_t) strlenesque; +int strcmp16(const char16_t *, const char16_t *) strlenesque; +int strncmp16(const char16_t *, const char16_t *, size_t) strlenesque; +int wcscmp(const wchar_t *, const wchar_t *) strlenesque; +int wcsncmp(const wchar_t *, const wchar_t *, size_t) strlenesque; +int wmemcmp(const wchar_t *, const wchar_t *, size_t) strlenesque; +int strcasecmp(const char *, const char *) strlenesque; +int strcasecmp16(const char16_t *, const char16_t *) strlenesque; +int wcscasecmp(const wchar_t *, const wchar_t *) strlenesque; +int strncasecmp(const char *, const char *, size_t) strlenesque; +int strncasecmp16(const char16_t *, const char16_t *, size_t) strlenesque; +int wcsncasecmp(const wchar_t *, const wchar_t *, size_t) strlenesque; +char *strrchr(const char *, int) strlenesque; +void *memrchr(const void *, int, size_t) strlenesque; +char16_t *strrchr16(const char16_t *, int) strlenesque; +void *memrchr16(const void *, int, size_t) strlenesque; +wchar_t *wcsrchr(const wchar_t *, int) strlenesque; +void *wmemrchr(const void *, wchar_t, size_t) strlenesque; +char *strpbrk(const char *, const char *) strlenesque; +char16_t *strpbrk16(const char16_t *, const char16_t *) strlenesque; +wchar_t *wcspbrk(const wchar_t *, const wchar_t *) strlenesque; +size_t strspn(const char *, const char *) strlenesque; +size_t strspn16(const char16_t *, const char16_t *) strlenesque; +size_t wcsspn(const wchar_t *, const wchar_t *) strlenesque; +size_t strcspn(const char *, const char *) strlenesque; +size_t strcspn16(const char16_t *, const char16_t *) strlenesque; +size_t wcscspn(const wchar_t *, const wchar_t *) strlenesque; +void *memfrob(void *, size_t) memcpyesque; +int strcoll(const char *, const char *) strlenesque; +char *strsep(char **, const char *) paramsnonnull(); +int strcmpzbw(const uint16_t *, const char *) strlenesque; +int strcasecmpzbw(const uint16_t *, const char *) strlenesque; +char *stpcpy(char *, const char *) memcpyesque; +char *stpncpy(char *, const char *, size_t) memcpyesque; +char *strcat(char *, const char *) memcpyesque; +size_t strlcpy(char *, const char *, size_t); +size_t strlcat(char *, const char *, size_t); +char *strcpy(char *, const char *) memcpyesque; +char16_t *strcpy16(char16_t *, const char16_t *) memcpyesque; +char *strncat(char *, const char *, size_t) memcpyesque; +char *strncpy(char *, const char *, size_t) memcpyesque; +char *_strncpy(char *, const char *, size_t) asm("strncpy") memcpyesque; +char *strtok(char *, const char *) paramsnonnull((2)) libcesque; +char *strtok_r(char *, const char *, char **) paramsnonnull((2, 3)); +uint16_t *strcpyzbw(uint16_t *, const char *) memcpyesque; +char *wstrtrunc(uint16_t *) memcpyesque; +char *wstrntrunc(uint16_t *, size_t) memcpyesque; +bool startswith(const char *, const char *) strlenesque; +bool startswith16(const char16_t *, const char16_t *) strlenesque; +bool wcsstartswith(const wchar_t *, const wchar_t *) strlenesque; +bool endswith(const char *, const char *) strlenesque; +bool endswith16(const char16_t *, const char16_t *) strlenesque; +bool wcsendswith(const wchar_t *, const wchar_t *) strlenesque; +const char *indexdoublenulstring(const char *, unsigned) strlenesque; +int getkvlin(const char *, const char *const[]); +void crc32init(uint32_t[hasatleast 256], uint32_t); +wchar_t *wmemset(wchar_t *, wchar_t, size_t) memcpyesque; +char16_t *memset16(char16_t *, char16_t, size_t) memcpyesque; +compatfn wchar_t *wmemcpy(wchar_t *, const wchar_t *, size_t) memcpyesque; +compatfn wchar_t *wmempcpy(wchar_t *, const wchar_t *, size_t) memcpyesque; +compatfn wchar_t *wmemmove(wchar_t *, const wchar_t *, size_t) memcpyesque; + +char *tinystrstr(const char *, const char *) strlenesque; +char16_t *tinystrstr16(const char16_t *, const char16_t *) strlenesque; +void *tinymemmem(const void *, size_t, const void *, size_t) strlenesque; + +void *memtolower(void *p, size_t n); +char *strntolower(char *s, size_t n); +char *strtolower(char *s) paramsnonnull(); +char *strntoupper(char *s, size_t n); +char *strtoupper(char *s) paramsnonnull(); +char *chomp(char *line); +char16_t *chomp16(char16_t *line); +wchar_t *wchomp(wchar_t *line); + +/* gcc -Werror=stringop-truncation misunderstands strncpy() api */ +#define strncpy(DEST, SRC, N) _strncpy(DEST, SRC, N) + +#define explicit_bzero(STR, BYTES) \ + do { \ + void *Str; \ + size_t Bytes; \ + asm volatile("call\texplicit_bzero" \ + : "=D"(Str), "=S"(Bytes) \ + : "0"(STR), "1"(BYTES) \ + : "rax", "rcx", "rdx", "r8", "r9", "r10", "r11", "memory", \ + "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); \ + } while (0) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § strings » multibyte ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +typedef unsigned mbstate_t; + +size_t tprecode8to16(char16_t *, size_t, const char *); +size_t tprecode16to8(char *, size_t, const char16_t *); +int strcmp8to16(const char *, const char16_t *) strlenesque; +int strncmp8to16(const char *, const char16_t *, size_t) strlenesque; +int strcasecmp8to16(const char *, const char16_t *) strlenesque; +int strncasecmp8to16(const char *, const char16_t *, size_t) strlenesque; +int strcmp16to8(const char16_t *, const char *) strlenesque; +int strncmp16to8(const char16_t *, const char *, size_t) strlenesque; +int strcasecmp16to8(const char16_t *, const char *) strlenesque; +int strncasecmp16to8(const char16_t *, const char *, size_t) strlenesque; +wchar_t *wcsncpy(wchar_t *, const wchar_t *, size_t); +int mbtowc(wchar_t *, const char *, size_t); +size_t mbrtowc(wchar_t *, const char *, size_t, mbstate_t *); +size_t mbsrtowcs(wchar_t *, const char **, size_t, mbstate_t *); +size_t mbstowcs(wchar_t *, const char *, size_t); +size_t wcstombs(char *, const wchar_t *, size_t); +size_t wcsrtombs(char *, const wchar_t **, size_t, mbstate_t *); +size_t wcrtomb(char *, wchar_t, mbstate_t *); +int wctomb(char *, wchar_t); +int wctob(wint_t); + +size_t strclen(const char *) nosideeffect; +size_t strnclen(const char *, size_t) nosideeffect; +size_t strclen16(const char16_t *) nosideeffect; +size_t strnclen16(const char16_t *, size_t) nosideeffect; + +typedef unsigned wctype_t; +wctype_t wctype(const char *name) strlenesque; +int iswctype(wint_t c, wctype_t type) pureconst; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § strings » hashing ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define SHA256_BLOCK_SIZE 32 + +struct Sha256Ctx { + uint8_t data[64]; + uint32_t datalen; + uint64_t bitlen; + uint32_t state[8]; +}; + +uint32_t crc32_z(uint32_t, const void *, size_t); +extern uint32_t (*const crc32c)(uint32_t, const void *, size_t) paramsnonnull(); + +void sha256_init(struct Sha256Ctx *); +void sha256_update(struct Sha256Ctx *, const uint8_t *, size_t); +void sha256_final(struct Sha256Ctx *, uint8_t *); + +bool luhn(const char *); + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § strings » system ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +char *strsignal(int) returnsnonnull libcesque; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § strings » hooks ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +extern int (*const hook$strcmp16)(const char16_t *, const char16_t *); +extern int (*const hook$strncmp16)(const char16_t *, const char16_t *, size_t); +extern int (*const hook$wcscmp)(const wchar_t *, const wchar_t *); +extern int (*const hook$wcsncmp)(const wchar_t *, const wchar_t *, size_t); +#define __STR_HOOK(SYMBOL) hook$##SYMBOL +#else +#define __STR_HOOK(SYMBOL) SYMBOL +#endif /* GNUC && !ANSI */ + +/* TODO(jart): Use @gotpcrel. */ +#undef __STR_HOOK +#define __STR_HOOK(SYMBOL) SYMBOL + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § strings » generic typing ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#if __STDC_VERSION__ + 0 >= 201112 + +#define strstr(haystack, needle) \ + _Generic(*(haystack), wchar_t \ + : wcsstr, char16_t \ + : strstr16, default \ + : strstr)(haystack, needle) + +#define strchr(s, c) \ + _Generic(*(s), wchar_t \ + : wcschr, char16_t \ + : strchr16, default \ + : (isconstant(s) && isconstant(c) ? __builtin_strchr : _strchr))(s, \ + c) + +#define strrchr(s, c) \ + _Generic(*(s), wchar_t \ + : wcsrchr, char16_t \ + : strrchr16, default \ + : strrchr)(s, c) + +#define strchrnul(s, c) \ + _Generic(*(s), wchar_t \ + : wcschrnul, char16_t \ + : strchrnul16, default \ + : strchrnul)(s, c) + +#define strnlen(s, n) \ + _Generic(*(s), wchar_t \ + : wcsnlen, char16_t \ + : strnlen16, default \ + : strnlen)(s, n) + +#define strnlen_s(s, n) \ + _Generic(*(s), wchar_t \ + : wcsnlen_s, char16_t \ + : strnlen16_s, default \ + : strnlen_s)(s, n) + +#define strpbrk(s, c) \ + _Generic(*(s), wchar_t \ + : wcspbrk, char16_t \ + : strpbrk16, default \ + : strpbrk)(s, c) + +#define strspn(s, c) \ + _Generic(*(s), wchar_t : wcsspn, char16_t : strspn16, default : strspn)(s, c) + +#define strcspn(s, c) \ + _Generic(*(s), wchar_t \ + : wcscspn, char16_t \ + : strcspn16, default \ + : strcspn)(s, c) + +/* clang-format off */ +#define strcmp(s1, s2) \ + _Generic((s1)[0], \ + wchar_t: __STR_HOOK(wcscmp), \ + char16_t: _Generic(*(s2), \ + char: strcmp16to8, \ + default: __STR_HOOK(strcmp16)), \ + default: _Generic(*(s2), \ + char16_t: strcmp8to16, \ + default: strcmp))(s1, s2) +/* clang-format on */ + +#define strncmp(s1, s2, n) \ + _Generic(*(s1), wchar_t \ + : __STR_HOOK(wcsncmp), char16_t \ + : _Generic(*(s2), char \ + : strncmp16to8, default \ + : __STR_HOOK(strncmp16)), \ + default \ + : _Generic(*(s2), char16_t \ + : strncmp8to16, default \ + : strncmp))(s1, s2, n) + +#define strcasecmp(s1, s2) \ + _Generic(*(s1), wchar_t \ + : wcscasecmp, char16_t \ + : strcasecmp16, default \ + : strcasecmp)(s1, s2) + +#define strncasecmp(s1, s2, n) \ + _Generic(*(s1), wchar_t \ + : wcsncasecmp, char16_t \ + : strncasecmp16, default \ + : strncasecmp)(s1, s2, n) + +#define startswith(s, c) \ + _Generic(*(s), wchar_t \ + : wcsstartswith, char16_t \ + : startswith16, default \ + : startswith)(s, c) + +#define endswith(s, c) \ + _Generic(*(s), wchar_t \ + : wcsendswith, char16_t \ + : endswith16, default \ + : endswith)(s, c) + +#define strclen(s) \ + _Generic(*(s), wchar_t : wcslen, char16_t : strclen16, default : strclen)(s) + +#define strnclen(s, n) \ + _Generic(*(s), wchar_t \ + : wcslen, char16_t \ + : strnclen16, default \ + : strnclen)(s, n) + +#define chomp(s) \ + _Generic(*(s), wchar_t : wchomp, char16_t : chomp16, default : chomp)(s) + +#endif /* C11 */ + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § strings » optimizations ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) + +#ifdef UNBLOAT_STDARG +#define __STR_XMM_CLOBBER +#else +#define __STR_XMM_CLOBBER "xmm3", +#endif + +#define __memcpy_isgoodsize(SIZE) \ + (isconstant(SIZE) && ((SIZE) <= __BIGGEST_ALIGNMENT__ * 2 && \ + __builtin_popcount((unsigned)(SIZE)) == 1)) + +#define __memset_isgoodsize(SIZE) \ + (isconstant(SIZE) && (((SIZE) <= __BIGGEST_ALIGNMENT__ && \ + __builtin_popcount((unsigned)(SIZE)) == 1) || \ + ((SIZE) % __BIGGEST_ALIGNMENT__ == 0 && \ + (SIZE) / __BIGGEST_ALIGNMENT__ <= 3))) + +#define memcpy(DEST, SRC, SIZE) \ + (__memcpy_isgoodsize(SIZE) ? __builtin_memcpy(DEST, SRC, SIZE) \ + : __memcpy("_memcpy", DEST, SRC, SIZE)) + +#define memset(DEST, BYTE, SIZE) \ + (__memset_isgoodsize(SIZE) ? __builtin_memset(DEST, BYTE, SIZE) \ + : __memset(DEST, BYTE, SIZE)) + +#if defined(__STDC_HOSTED__) && (defined(__SSE2__) || defined(UNBLOAT_STDARG)) + +#define memmove(DEST, SRC, SIZE) __memcpy("_memmove", (DEST), (SRC), (SIZE)) +#define __memcpy(FN, DEST, SRC, SIZE) \ + ({ \ + void *DeSt = (DEST); \ + const void *SrC = (SRC); \ + size_t SiZe = (SIZE); \ + asm("call\t" FN \ + : "=m"(*(char(*)[SiZe])(DeSt)) \ + : "D"(DeSt), "S"(SrC), "d"(SiZe), "m"(*(const char(*)[SiZe])(SrC)) \ + : __STR_XMM_CLOBBER "cc"); \ + DeSt; \ + }) +#define mempcpy(DEST, SRC, SIZE) \ + ({ \ + size_t SIze = (SIZE); \ + (void *)((char *)memcpy((DEST), (SRC), SIze) + SIze); \ + }) +#define __memset(DEST, BYTE, SIZE) \ + ({ \ + void *DeSt = (DEST); \ + size_t SiZe = (SIZE); \ + asm("call\t_memset" \ + : "=m"(*(char(*)[SiZe])(DeSt)) \ + : "D"(DeSt), "S"(BYTE), "d"(SiZe) \ + : __STR_XMM_CLOBBER "cc"); \ + DeSt; \ + }) + +#else /* hosted/sse2/unbloat */ + +#define memmove(DEST, SRC, SIZE) __memcpy((DEST), (SRC), (SIZE)) +#define mempcpy(DEST, SRC, SIZE) \ + ({ \ + void *Rdi, *Dest = (DEST); \ + const void *Rsi, *Src = (SRC); \ + size_t SiZe = (SIZE); \ + size_t Rcx; \ + asm("rep movsb" \ + : "=D"(Rdi), "=S"(Rsi), "=D"(Rcx), "=m"(*(char(*)[SiZe])(Dest)) \ + : "0"(Dest), "1"(Src), "2"(SiZe), "m"(*(const char(*)[SiZe])(Src)) \ + : "cc"); \ + Rdi; \ + }) +#define __memcpy(FN, DEST, SRC, SIZE) \ + ({ \ + void *Rdi, *Dest = (DEST); \ + const void *Rsi, *Src = (SRC); \ + size_t SiZe = (SIZE); \ + size_t Rcx; \ + asm("rep movsb" \ + : "=D"(Rdi), "=S"(Rsi), "=c"(Rcx), "=m"(*(char(*)[SiZe])(Dest)) \ + : "0"(Dest), "1"(Src), "2"(SiZe), "m"(*(const char(*)[SiZe])(Src)) \ + : "cc"); \ + Dest; \ + }) +#define __memset(DEST, BYTE, SIZE) \ + ({ \ + void *Rdi, *Dest = (DEST); \ + size_t SiZe = (SIZE); \ + size_t Rcx; \ + asm("rep stosb" \ + : "=D"(Rdi), "=c"(Rcx), "=m"(*(char(*)[SiZe])(Dest)) \ + : "0"(Dest), "1"(SiZe), "S"(BYTE) \ + : "cc"); \ + Dest; \ + }) + +#endif /* hosted/sse2/unbloat */ + +#if __STDC_VERSION__ + 0 >= 201112 +#define strlen(s) \ + chooseexpr((typescompatible(typeof(s), const char[]) && \ + isconstant(((const char *)(s))[0])), \ + sizeof(s) - 1, \ + _Generic(*(s), wchar_t \ + : wcslen, char16_t \ + : strlen16, default \ + : _strlen)(s)) +#else +#define strlen(s) \ + chooseexpr(isconstant(s) && typescompatible(typeof(s), const char[]), \ + __builtin_strlen(s), _strlen(s)) +#endif /* C11+ */ + +#define tpencode(BUF, SIZE, CH, AWESOME) __tpencode(BUF, SIZE, CH, AWESOME) +#define pututf16(BUF, SIZE, CH, AWESOME) __pututf16(BUF, SIZE, CH, AWESOME) +#define getutf16(BUF, CHPTR) __getutf16(BUF, CHPTR) +#define tpdecode(S, OUT) __tpdecode(S, OUT) +size_t _strlen(const char *s) asm("strlen") strlenesque; +char *_strchr(const char *, int) asm("strchr") strlenesque; +void *_memchr(const void *, int, size_t) asm("memchr") strlenesque; +forceinline unsigned __tpencode(char *s, size_t size, wint_t wc, + bool32 awesome) { + unsigned char *p = (unsigned char *)s; + if (size >= 1 && (0x00 <= wc && wc <= 0x7f)) { + if (wc >= 32 || !awesome) { + p[0] = (unsigned char)wc; + return 1; + } else if (size >= 2) { + p[0] = 0xc0; + p[1] = 0x80 | (unsigned char)wc; + return 2; + } + } + unsigned ax; + asm("call\ttpencode" + : "=a"(ax), "=m"(*(char(*)[size])s) + : "D"(s), "S"(size), "d"(wc) + : "cc"); + return ax; +} +forceinline int __tpdecode(const char *s, wint_t *out) { + if (0 <= *s && *s <= 0x7f) { + *out = *s; + return 1; + } + int ax; + asm("call\ttpdecode" + : "=a"(ax), "=m"(*(char(*)[6])s) + : "D"(s), "S"(out) + : "cc"); + return ax; +} +forceinline int __pututf16(char16_t *s, size_t size, wint_t wc, + bool32 awesome) { + if (size >= 1 && (0x00 <= wc && wc <= 0xD7FF)) { + if (wc >= 32 || !awesome) { + s[0] = (char16_t)wc; + return 1; + } else if (size >= 2) { + s[0] = 0xd800; + s[1] = 0xdc00 | (char16_t)wc; + return 2; + } + } + int ax; + asm("call\tpututf16" + : "=a"(ax), "=m"(*(char16_t(*)[size])s) + : "D"(s), "S"(size), "d"(wc) + : "cc"); + return ax; +} +forceinline unsigned __getutf16(const char16_t *s, wint_t *wc) { + if ((0x00 <= s[0] && s[0] <= 0xD7FF)) { + *wc = s[0]; + return 1; + } + unsigned ax; + asm("call\tgetutf16" : "=a"(ax), "=m"(*wc) : "D"(s), "S"(wc), "m"(*s) : "cc"); + return ax; +} + +/* + * GCC has builtins for these, that only do things for literals. They + * also cause the compiler to whine in a kafkaesque way when flags like + * -Werror=shadow and -Werror=implicit-function-declaration are passed. + */ +#define isascii(c) isascii_(c) +#define isspace(c) isspace_(c) +#define isalpha(c) isalpha_(c) +#define isdigit(c) isdigit_(c) +#define isalnum(c) isalnum_(c) +#define isxdigit(c) isxdigit_(c) +#define isprint(c) isprint_(c) +#define islower(c) islower_(c) +#define isupper(c) isupper_(c) +#define isblank(c) isblank_(c) +#define iscntrl(c) iscntrl_(c) +#define isgraph(c) isgraph_(c) +#define tolower(c) tolower_(c) +#define ispunct(c) ispunct_(c) +#define toupper(c) toupper_(c) +#define hextoint(c) hextoint_(c) +#define DECLARE_CTYPE(NAME, EXPR) \ + pureconst forceinline nodebuginfo int NAME(int i) { \ + unsigned char c = (unsigned char)i; \ + return (EXPR); \ + } +DECLARE_CTYPE(isascii_, 0 <= c && c <= 0x7f) +DECLARE_CTYPE(isspace_, kCtype[c] & 0x01) +DECLARE_CTYPE(isalpha_, kCtype[c] & 0x02) +DECLARE_CTYPE(isdigit_, '0' <= c && c <= '9') +DECLARE_CTYPE(isalnum_, kCtype[c] & 0x06) +DECLARE_CTYPE(isxdigit_, kCtype[c] & 0x08) +DECLARE_CTYPE(isprint_, kCtype[c] & 0x10) +DECLARE_CTYPE(islower_, 'a' <= c && c <= 'z') +DECLARE_CTYPE(isupper_, 'A' <= c && c <= 'Z') +DECLARE_CTYPE(isblank_, kCtype[c] & 0x80) +DECLARE_CTYPE(iscntrl_, !isprint_(c)) +DECLARE_CTYPE(isgraph_, isprint_(c) && (c) != ' ') +DECLARE_CTYPE(tolower_, kToLower[c]) +DECLARE_CTYPE(ispunct_, isprint(c) && !(kCtype[c] & 0x07)) +DECLARE_CTYPE(toupper_, kToUpper[c]) +DECLARE_CTYPE(hextoint_, (c + 9 * (1 & (SAR(c, 6)))) & 0xf) +#undef DECLARE_CTYPE +#define iswalnum(c) iswalnum_(c) +#define iswalpha(c) iswalpha_(c) +#define iswblank(c) iswblank_(c) +#define iswcntrl(c) iswcntrl_(c) +#define iswdigit(c) iswdigit_(c) +#define iswgraph(c) iswgraph_(c) +#define iswlower(c) iswlower_(c) +#define iswspace(c) iswspace_(c) +#define iswupper(c) iswupper_(c) +#define iswxdigit(c) iswxdigit_(c) +#define iswpunct(c) iswpunct_(c) +#define iswprint(c) iswprint_(c) +#define towlower(c) towlower_(c) +#define towupper(c) towupper_(c) +#define DECLARE_WCTYPE(R, NAME, T, EXPR) \ + forceinline nodebuginfo R NAME(T c) { \ + return EXPR; \ + } +DECLARE_WCTYPE(int, iswalnum_, wint_t, isascii(c) ? isalnum(c) : c) +DECLARE_WCTYPE(int, iswalpha_, wint_t, isascii(c) ? isalpha(c) : c) +DECLARE_WCTYPE(int, iswblank_, wint_t, isascii(c) ? isblank(c) : c) +DECLARE_WCTYPE(int, iswcntrl_, wint_t, isascii(c) ? iscntrl(c) : c) +DECLARE_WCTYPE(int, iswdigit_, wint_t, isascii(c) ? isdigit(c) : c) +DECLARE_WCTYPE(int, iswgraph_, wint_t, isascii(c) ? isgraph(c) : c) +DECLARE_WCTYPE(int, iswlower_, wint_t, isascii(c) ? islower(c) : c) +DECLARE_WCTYPE(int, iswspace_, wint_t, isascii(c) ? isspace(c) : c) +DECLARE_WCTYPE(int, iswupper_, wint_t, isascii(c) ? isupper(c) : c) +DECLARE_WCTYPE(int, iswxdigit_, wint_t, isascii(c) ? isxdigit(c) : c) +DECLARE_WCTYPE(int, iswpunct_, wint_t, !isascii(c) || ispunct(c)) +DECLARE_WCTYPE(int, iswprint_, wint_t, !isascii(c) || isprint(c)) +DECLARE_WCTYPE(unsigned, towlower_, unsigned, isascii(c) ? tolower(c) : c) +DECLARE_WCTYPE(unsigned, towupper_, unsigned, isascii(c) ? toupper(c) : c) +#undef DECLARE_WCTYPE + +#endif /* __GNUC__ && !__STRICT_ANSI__ */ +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_STR_STR_H_ */ diff --git a/libc/str/str.mk b/libc/str/str.mk new file mode 100644 index 00000000..498c44e0 --- /dev/null +++ b/libc/str/str.mk @@ -0,0 +1,55 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += LIBC_STR + +LIBC_STR_ARTIFACTS += LIBC_STR_A +LIBC_STR = $(LIBC_STR_A_DEPS) $(LIBC_STR_A) +LIBC_STR_A = o/$(MODE)/libc/str/str.a +LIBC_STR_A_FILES := $(wildcard libc/str/*) +LIBC_STR_A_HDRS = $(filter %.h,$(LIBC_STR_A_FILES)) +LIBC_STR_A_SRCS_A = $(filter %.s,$(LIBC_STR_A_FILES)) +LIBC_STR_A_SRCS_S = $(filter %.S,$(LIBC_STR_A_FILES)) +LIBC_STR_A_SRCS_C = $(filter %.c,$(LIBC_STR_A_FILES)) + +LIBC_STR_A_SRCS = \ + $(LIBC_STR_A_SRCS_A) \ + $(LIBC_STR_A_SRCS_S) \ + $(LIBC_STR_A_SRCS_C) + +LIBC_STR_A_OBJS = \ + $(LIBC_STR_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_STR_A_SRCS_A:%.s=o/$(MODE)/%.o) \ + $(LIBC_STR_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_STR_A_SRCS_C:%.c=o/$(MODE)/%.o) + +LIBC_STR_A_CHECKS = \ + $(LIBC_STR_A).pkg \ + $(LIBC_STR_A_HDRS:%=o/$(MODE)/%.ok) + +LIBC_STR_A_DIRECTDEPS = \ + LIBC_STUBS \ + LIBC_NEXGEN32E + +LIBC_STR_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_STR_A_DIRECTDEPS),$($(x)))) + +$(LIBC_STR_A): libc/str/ \ + $(LIBC_STR_A).pkg \ + $(LIBC_STR_A_OBJS) + +$(LIBC_STR_A).pkg: \ + $(LIBC_STR_A_OBJS) \ + $(foreach x,$(LIBC_STR_A_DIRECTDEPS),$($(x)_A).pkg) + +LIBC_STR_LIBS = $(foreach x,$(LIBC_STR_ARTIFACTS),$($(x))) +LIBC_STR_SRCS = $(foreach x,$(LIBC_STR_ARTIFACTS),$($(x)_SRCS)) +LIBC_STR_HDRS = $(foreach x,$(LIBC_STR_ARTIFACTS),$($(x)_HDRS)) +LIBC_STR_BINS = $(foreach x,$(LIBC_STR_ARTIFACTS),$($(x)_BINS)) +LIBC_STR_CHECKS = $(foreach x,$(LIBC_STR_ARTIFACTS),$($(x)_CHECKS)) +LIBC_STR_OBJS = $(foreach x,$(LIBC_STR_ARTIFACTS),$($(x)_OBJS)) +LIBC_STR_TESTS = $(foreach x,$(LIBC_STR_ARTIFACTS),$($(x)_TESTS)) +$(LIBC_STR_OBJS): $(BUILD_FILES) libc/str/str.mk + +.PHONY: o/$(MODE)/libc/str +o/$(MODE)/libc/str: $(LIBC_STR_CHECKS) diff --git a/libc/str/strcasecmp8to16.c b/libc/str/strcasecmp8to16.c new file mode 100644 index 00000000..da18b109 --- /dev/null +++ b/libc/str/strcasecmp8to16.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/internal.h" +#include "libc/str/strcmp8to16i.h" + +/** + * Compares UTF-8 and UTF-16 strings, ignoring case. + */ +int strcasecmp8to16(const char *s1, const char16_t *s2) { + return strcmp8to16i(s1, s2, -1ul, towlower); +} + +int strcasecmp16to8(const char16_t *s1, const char *s2) { + return -strcasecmp8to16(s2, s1); +} diff --git a/libc/str/strcat.c b/libc/str/strcat.c new file mode 100644 index 00000000..9c6217db --- /dev/null +++ b/libc/str/strcat.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Appends 𝑠 to 𝑑. + * + * @param 𝑑 is a NUL-terminated string buffer + * @param 𝑠 is a NUL-terminated string + * @return 𝑑 + * @asyncsignalsafe + */ +char *strcat(char *d, const char *s) { return strcpy(d + strlen(d), s); } diff --git a/libc/str/strclen.c b/libc/str/strclen.c new file mode 100644 index 00000000..4647bdaf --- /dev/null +++ b/libc/str/strclen.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/internal.h" +#include "libc/str/str.h" + +/** + * Returns number of characters in UTF-8 string. + */ +size_t(strclen)(const char *s) { return strnclen(s, -1ull); } + +noinline size_t(strnclen)(const char *s, size_t n) { + const unsigned char *p = (const unsigned char *)s; + size_t l = 0; + if (n) { + while (*p && n && iscont(*p)) ++p, --n; + while (*p) { + if (!iscont(*p++)) l++; + if (!--n) break; + } + } + return l; +} diff --git a/libc/str/strclen16.c b/libc/str/strclen16.c new file mode 100644 index 00000000..eea41bbd --- /dev/null +++ b/libc/str/strclen16.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Returns number of characters in UTF-16 or UCS-2 string. + */ +size_t strclen16(const char16_t *s) { return strnclen16(s, -1ull); } + +noinline size_t strnclen16(const char16_t *p, size_t n) { + size_t l = 0; + if (n) { + while (*p) { + if ((*p++ & UTF16_MASK) != UTF16_CONT) l++; + if (!--n) break; + } + } + return l; +} diff --git a/libc/str/strcmp8to16.c b/libc/str/strcmp8to16.c new file mode 100644 index 00000000..566798f3 --- /dev/null +++ b/libc/str/strcmp8to16.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/internal.h" +#include "libc/str/strcmp8to16i.h" + +forceinline unsigned identity32u(unsigned x) { return x; } + +/** + * Compares UTF-8 and UTF-16 strings. + */ +int strcmp8to16(const char *s1, const char16_t *s2) { + return strcmp8to16i(s1, s2, -1ul, identity32u); +} + +int strcmp16to8(const char16_t *s1, const char *s2) { + return -strcmp8to16(s2, s1); +} diff --git a/libc/str/strcmp8to16i.h b/libc/str/strcmp8to16i.h new file mode 100644 index 00000000..279910ab --- /dev/null +++ b/libc/str/strcmp8to16i.h @@ -0,0 +1,24 @@ +#ifndef COSMOPOLITAN_LIBC_STR_STRCMP8TO16I_H_ +#define COSMOPOLITAN_LIBC_STR_STRCMP8TO16I_H_ +#include "libc/conv/conv.h" +#include "libc/str/str.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +forceinline int strcmp8to16i(const char *s1, const char16_t *s2, size_t n, + unsigned xlat(unsigned)) { + int res = 0; + if (n) { + do { + wint_t wc1, wc2; + s1 += abs(tpdecode(s1, &wc1)); + s2 += abs(getutf16(s2, &wc2)); + if ((res = xlat(wc1) - xlat(wc2)) || !wc1) break; + } while (n == -1ul || --n); + } + return res; +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_STR_STRCMP8TO16I_H_ */ diff --git a/libc/str/strcpy.c b/libc/str/strcpy.c new file mode 100644 index 00000000..fc9a23f4 --- /dev/null +++ b/libc/str/strcpy.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/limits.h" +#include "libc/str/str.h" + +/** + * Copies bytes from 𝑠 to 𝑑 until a NUL is encountered. + * + * @param 𝑑 is destination memory + * @param 𝑠 is a NUL-terminated string + * @note 𝑑 and 𝑠 can't overlap + * @return original dest + * @see memccpy() + * @asyncsignalsafe + */ +char *strcpy(char *d, const char *s) { + memccpy(d, s, '\0', SIZE_MAX); + return d; +} diff --git a/libc/str/strcpy16.c b/libc/str/strcpy16.c new file mode 100644 index 00000000..7b7a9aec --- /dev/null +++ b/libc/str/strcpy16.c @@ -0,0 +1,33 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Copies NUL-terminated UCS-2 or UTF-16 string. + * + * DEST and SRC must not overlap unless DEST ≤ SRC. + * + * @param dest is destination memory + * @param src is a NUL-terminated 16-bit string + * @return original dest + */ +char16_t *strcpy16(char16_t *dest, const char16_t *src) { + return memcpy(dest, src, (strlen16(src) + 1) << 1); +} diff --git a/libc/str/strlcat.c b/libc/str/strlcat.c new file mode 100644 index 00000000..4e8fd972 --- /dev/null +++ b/libc/str/strlcat.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/str/str.h" + +/** + * Appends string SRC to DEST, the BSD way. + * + * @param dest is a buffer holding a NUL-terminated string + * @param src is a NUL-terminated string + * @param size is byte capacity of dest + * @return strlen(dest) + strlen(src) + * @note dest and src can't overlap + * @see strncat() + */ +size_t strlcat(char *dest, const char *src, size_t size) { + size_t destlen = strnlen(dest, size); + size_t srclen = strlen(src); + if (size) { + memcpy(&dest[destlen], src, min(srclen, size - destlen)); + dest[min(destlen + srclen, size - 1)] = '\0'; + } + return destlen + srclen; +} diff --git a/libc/str/strlcpy.c b/libc/str/strlcpy.c new file mode 100644 index 00000000..fd006389 --- /dev/null +++ b/libc/str/strlcpy.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/str/str.h" + +/** + * Copies string, the BSD way. + * + * @param d is buffer which needn't be initialized + * @param s is a NUL-terminated string + * @param n is byte capacity of d + * @return strlen(s) + * @note d and s can't overlap + * @note we prefer memccpy() + */ +size_t strlcpy(char *d, const char *s, size_t n) { + size_t slen, actual; + slen = strlen(s); + if (n) { + actual = min(n, slen); + memcpy(d, s, actual); + d[actual] = '\0'; + } + return slen; +} diff --git a/libc/str/strncasecmp8to16.c b/libc/str/strncasecmp8to16.c new file mode 100644 index 00000000..ed390902 --- /dev/null +++ b/libc/str/strncasecmp8to16.c @@ -0,0 +1,33 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/internal.h" +#include "libc/str/strcmp8to16i.h" + +/** + * Compares UTF-8 and UTF-16 strings, ignoring case, with limit. + */ +int strncasecmp8to16(const char *s1, const char16_t *s2, size_t n) { + assume(n != -1ul); + return strcmp8to16i(s1, s2, n, towlower); +} + +int strncasecmp16to8(const char16_t *s1, const char *s2, size_t n) { + return -strncasecmp8to16(s2, s1, n); +} diff --git a/libc/str/strncat.c b/libc/str/strncat.c new file mode 100644 index 00000000..b62fd282 --- /dev/null +++ b/libc/str/strncat.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +#include "libc/str/str.h" + +/** + * Appends at most 𝑛 bytes from 𝑠 to 𝑑. + * + * @param 𝑑 is both a NUL-terminated string and a buffer, needing + * an ARRAYLEN() of at least strlen(𝑑)+strnlen(𝑠,𝑛)+1 + * @param 𝑠 is character array which needn't be NUL-terminated + * @param 𝑛 is maximum number of characters from s to copy + * @return 𝑑 + * @note 𝑑 and 𝑠 can't overlap + * @asyncsignaslenafe + */ +char *strncat(char *d, const char *s, size_t n) { + size_t o; + if (!memccpy(d + (o = strlen(d)), s, '\0', n)) { + d[o + n] = '\0'; + } + return d; +} diff --git a/libc/str/strncmp8to16.c b/libc/str/strncmp8to16.c new file mode 100644 index 00000000..879d74c2 --- /dev/null +++ b/libc/str/strncmp8to16.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/internal.h" +#include "libc/str/strcmp8to16i.h" + +forceinline unsigned identity32u(unsigned x) { return x; } + +/** + * Compares UTF-8 and UTF-16 strings, with limit. + */ +int strncmp8to16(const char *s1, const char16_t *s2, size_t n) { + assume(n != -1ul); + return strcmp8to16i(s1, s2, n, identity32u); +} + +int strncmp16to8(const char16_t *s1, const char *s2, size_t n) { + return -strncmp8to16(s2, s1, n); +} diff --git a/libc/str/strncpy.c b/libc/str/strncpy.c new file mode 100644 index 00000000..32c29cd0 --- /dev/null +++ b/libc/str/strncpy.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Prepares static search buffer. + * + * 1. If SRC is too long, it's truncated and *not* NUL-terminated. + * 2. If SRC is too short, the remainder is zero-filled. + * + * Please note this function isn't designed to prevent untrustworthy + * data from modifying memory without authorization; the memccpy() + * function can be used for that purpose. + * + * @return dest + * @see stpncpy(), memccpy() + * @asyncsignalsafe + */ +char *(strncpy)(char *dest, const char *src, size_t stride) { + char *p; + if ((p = memccpy(dest, src, '\0', stride))) { + memset(p, 0, dest + stride - p); + } + return dest; +} diff --git a/libc/str/strntolower.c b/libc/str/strntolower.c new file mode 100644 index 00000000..e5b4e07d --- /dev/null +++ b/libc/str/strntolower.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +char *strntolower(char *s, size_t n) { + unsigned char *p = (unsigned char *)s; + for (;;) { + if (n-- && *p) { + if ('A' <= *p && *p <= 'Z') { + *p += 'a' - 'A'; + } + ++p; + } else { + break; + } + } + return s; +} diff --git a/libc/str/strntoupper.c b/libc/str/strntoupper.c new file mode 100644 index 00000000..2cd1893d --- /dev/null +++ b/libc/str/strntoupper.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +char *strntoupper(char *s, size_t n) { + unsigned char *p = (unsigned char *)s; + for (;;) { + if (n-- && *p) { + if ('a' <= *p && *p <= 'z') { + *p -= 'a' - 'A'; + } + ++p; + } else { + break; + } + } + return s; +} diff --git a/libc/str/strrchr.c b/libc/str/strrchr.c new file mode 100644 index 00000000..62e5586b --- /dev/null +++ b/libc/str/strrchr.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Searches for last instance of character in string. + * + * @param s is NUL-terminated string to search + * @param c is treated as unsigned char + * @return address of last c in s, or NULL if not found + * @asyncsignalsafe + */ +char *(strrchr)(const char *s, int c) { return memrchr(s, c, strlen(s)); } diff --git a/libc/str/strrchr16.c b/libc/str/strrchr16.c new file mode 100644 index 00000000..596984aa --- /dev/null +++ b/libc/str/strrchr16.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Searches for last instance of char16_t in string. + * + * @param s is NUL-terminated char16_t string to search + * @param c is treated as char16_t + * @return address of last c in s, or NULL if not found + * @asyncsignalsafe + */ +char16_t *strrchr16(const char16_t *s, int c) { + return memrchr16(s, c, strlen16(s)); +} diff --git a/libc/str/strsep.c b/libc/str/strsep.c new file mode 100644 index 00000000..056d8af0 --- /dev/null +++ b/libc/str/strsep.c @@ -0,0 +1,49 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Tokenizes string. + * + * This works by mutating the caller's pointer and the string itself. + * The returned value is the next available token, or NULL if we've + * reached the end. Upon each call, *str is updated to point past the + * terminator we inserted. Multiple delimiter bytes may be passed, which + * are treated as a set of characters, not a substring. + * + * @param str on first call points to var holding string to be tokenized + * and is used by this function to track state on subsequent calls + * @param delim is a set of characters that constitute separators + * @return next token or NULL when we've reached the end or *str==NULL + * @note unlike strtok() this does empty tokens and is re-entrant + */ +char *strsep(char **str, const char *delim) { + char *token = *str; + if (token) { + size_t i = strcspn(token, delim); + char *next = NULL; + if (token[i]) { + token[i] = '\0'; + next = &token[i + 1]; + } + *str = next; + } + return token; +} diff --git a/libc/str/strsignal.c b/libc/str/strsignal.c new file mode 100644 index 00000000..24d6ee98 --- /dev/null +++ b/libc/str/strsignal.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/macros.h" +#include "libc/str/str.h" + +static const char kSig[4] = "SIG"; +static const char kUnknown[8] = "UNKNOWN"; +alignas(1) static const char kStrSignals[][8] = { + "EXIT", "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "BUS", + "FPE", "KILL", "USR1", "SEGV", "USR2", "PIPE", "ALRM", "TERM", + "STKFLT", "CHLD", "CONT", "STOP", "TSTP", "TTIN", "TTOU", "URG", + "XCPU", "XFSZ", "VTALRM", "PROF", "WINCH", "IO", "PWR", "SYS"}; + +static char g_strsignal[4 + 8]; + +char *strsignal(int sig) { + if (0 <= sig && (unsigned)sig < ARRAYLEN(kStrSignals)) { + memcpy(g_strsignal, kSig, 4); + memcpy(&g_strsignal[3], kStrSignals[sig], 8); + } else { + memcpy(g_strsignal, &kUnknown, 8); + } + return g_strsignal; +} diff --git a/libc/str/strstr.c b/libc/str/strstr.c new file mode 100644 index 00000000..2b523e1f --- /dev/null +++ b/libc/str/strstr.c @@ -0,0 +1,57 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/dce.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/str/internal.h" +#include "libc/str/str.h" + +/** + * Searches for substring. + * + * @param haystack is the search area, as a NUL-terminated string + * @param needle is the desired substring, also NUL-terminated + * @return pointer to first substring within haystack, or NULL + * @asyncsignalsafe + * @see memmem() + */ +char *(strstr)(const char *haystack, const char *needle) { + if (needle[0]) { + if (needle[1]) { + if (!((intptr_t)needle & 0xf) && X86_HAVE(SSE4_2) && !IsTiny()) { + return strstr$sse42(haystack, needle); + } else { + size_t needlelen; + alignas(16) char needle2[64]; + needlelen = strlen(needle); + if (needlelen < 64 && X86_HAVE(SSE4_2) && !IsTiny()) { + memcpy(needle2, needle, (needlelen + 1) * sizeof(char)); + return strstr$sse42(haystack, needle2); + } else { + return tinystrstr(haystack, needle); + } + } + } else { + return strchr(haystack, needle[0]); + } + } else { + return haystack; + } +} diff --git a/libc/str/strstr16.c b/libc/str/strstr16.c new file mode 100644 index 00000000..3ab5fedd --- /dev/null +++ b/libc/str/strstr16.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/dce.h" +#include "libc/str/internal.h" +#include "libc/str/str.h" + +#undef memmem +#undef strlen +#undef strstr +#undef strchr + +#define char char16_t +#define memmem memmem16 +#define strlen strlen16 +#define strstr strstr16 +#define strchr strchr16 +#define strstr$sse42 strstr16$sse42 +#define tinystrstr tinystrstr16 + +#include "libc/str/strstr.c" diff --git a/libc/str/strtok.c b/libc/str/strtok.c new file mode 100644 index 00000000..6fb54038 --- /dev/null +++ b/libc/str/strtok.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Extracts non-empty tokens from string. + * + * @param s is mutated and should be NULL on subsequent calls + * @param sep is a NUL-terminated set of bytes to consider separators + * @return pointer to next token or NULL for end + * @see strtok_r() and strsep() for superior functions + * @notasyncsignalsafe + */ +char *strtok(char *s, const char *sep) { + static char *state; + return strtok_r(s, sep, &state); +} diff --git a/libc/str/strtok_r.c b/libc/str/strtok_r.c new file mode 100644 index 00000000..2e05b418 --- /dev/null +++ b/libc/str/strtok_r.c @@ -0,0 +1,54 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Extracts non-empty tokens from string. + * + * @param s is mutated and should be NULL on subsequent calls + * @param sep is a NUL-terminated set of bytes to consider separators + * @param state tracks progress between calls + * @return pointer to next token or NULL for end + * @see strsep() which is similar + * @asyncsignalsafe + */ +char *strtok_r(char *s, const char *sep, char **state) { + if (!s) { + s = *state; + if (!s) { + return NULL; + } + } + size_t leadingseps = strspn(s, sep); + s += leadingseps; + if (*s) { + size_t tokenlen = strcspn(s, sep); + if (s[tokenlen]) { + s[tokenlen] = '\0'; + *state = &s[tokenlen + 1]; + return s; + } else if (tokenlen) { + s[tokenlen] = '\0'; + *state = NULL; + return s; + } + } + return (*state = NULL); +} diff --git a/libc/str/tinymemmem.c b/libc/str/tinymemmem.c new file mode 100644 index 00000000..4fb74ecd --- /dev/null +++ b/libc/str/tinymemmem.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" +#include "libc/str/tinymemmem.h" + +/** + * Naïve substring search implementation. + * @see libc/alg/memmem.c + */ +void *tinymemmem(const void *haystk, size_t haystksize, const void *needle, + size_t needlesize) { + return (/*unconst*/ void *)tinymemmemi( + (const unsigned char *)haystk, haystksize, (const unsigned char *)needle, + needlesize); +} diff --git a/libc/str/tinymemmem.h b/libc/str/tinymemmem.h new file mode 100644 index 00000000..1f8f89cd --- /dev/null +++ b/libc/str/tinymemmem.h @@ -0,0 +1,24 @@ +#ifndef COSMOPOLITAN_LIBC_STR_TINYSTRSTR_H_ +#define COSMOPOLITAN_LIBC_STR_TINYSTRSTR_H_ +#include "libc/str/str.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +forceinline void *tinymemmemi(const void *haystk, size_t haystksize, + const void *needle, size_t needlesize) { + const char *p = haystk; + const char *pe = p + haystksize; + while (p < pe) { + size_t i = 0; + ++p; + for (;;) { + ++i; + if (i > needlesize) return (/*unconst*/ char *)(p - 1); + if (p == pe) break; + if (((const char *)needle)[i - 1] != (p - 1)[i - 1]) break; + } + } + return (/*unconst*/ char *)(!haystksize && !needlesize ? haystk : NULL); +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_STR_TINYMEMMEM_H_ */ diff --git a/libc/str/tinystrstr.c b/libc/str/tinystrstr.c new file mode 100644 index 00000000..ea36afe3 --- /dev/null +++ b/libc/str/tinystrstr.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/internal.h" +#include "libc/str/tinystrstr.h" + +/** + * Naïve substring search implementation. + * @see libc/str/strstr.c + * @asyncsignalsafe + */ +char *(tinystrstr)(const char *haystack, const char *needle) { + return (/*unconst*/ char *)tinystrstr(haystack, needle); +} diff --git a/libc/str/tinystrstr.h b/libc/str/tinystrstr.h new file mode 100644 index 00000000..3c050339 --- /dev/null +++ b/libc/str/tinystrstr.h @@ -0,0 +1,26 @@ +#ifndef COSMOPOLITAN_LIBC_STR_TINYSTRSTR_H_ +#define COSMOPOLITAN_LIBC_STR_TINYSTRSTR_H_ +#include "libc/str/str.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define tinystrstr(HAYSTACK, NEEDLE) \ + ({ \ + autotype(HAYSTACK) Haystack = (HAYSTACK); \ + typeof(Haystack) Needle = (NEEDLE); \ + for (;;) { \ + size_t i = 0; \ + for (;;) { \ + if (!Needle[i]) goto Found; \ + if (!Haystack[i]) break; \ + if (Needle[i] != Haystack[i]) break; \ + ++i; \ + } \ + if (!*Haystack++) break; \ + } \ + Haystack = NULL; \ + Found: \ + Haystack; \ + }) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_STR_TINYSTRSTR_H_ */ diff --git a/libc/str/tinystrstr16.c b/libc/str/tinystrstr16.c new file mode 100644 index 00000000..ba34770d --- /dev/null +++ b/libc/str/tinystrstr16.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/internal.h" +#include "libc/str/tinystrstr.h" + +/** + * Naïve substring search implementation. + * @see libc/str/strstr.c + * @asyncsignalsafe + */ +char16_t *tinystrstr16(const char16_t *haystack, const char16_t *needle) { + return (/*unconst*/ char16_t *)tinystrstr(haystack, needle); +} diff --git a/libc/str/tpdecode.ncabi.c b/libc/str/tpdecode.ncabi.c new file mode 100644 index 00000000..ab5a3d0c --- /dev/null +++ b/libc/str/tpdecode.ncabi.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/errno.h" +#include "libc/str/str.h" +#include "libc/str/tpdecodecb.h" + +forceinline int getbyte(void *arg, uint32_t i) { + return ((const unsigned char *)arg)[i]; +} + +/** + * Thompson-Pike Varint Decoder. + * + * @param s is a NUL-terminated string + * @return number of bytes successfully consumed or -1 w/ errno + * @note synchronization is performed + * @see libc/str/tpdecodecb.h (for implementation) + */ +int(tpdecode)(const char *s, wint_t *out) { + return tpdecodecb(out, (unsigned char)s[0], getbyte, (void *)s); +} diff --git a/libc/str/tpdecodecb.h b/libc/str/tpdecodecb.h new file mode 100644 index 00000000..09cb926c --- /dev/null +++ b/libc/str/tpdecodecb.h @@ -0,0 +1,56 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#ifndef COSMOPOLITAN_LIBC_STR_TPDECODECB_H_ +#define COSMOPOLITAN_LIBC_STR_TPDECODECB_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * Generic Thompson-Pike Varint Decoder. + * @return number of bytes successfully consumed or -1 w/ errno + * @note synchronization is performed + */ +forceinline int tpdecodecb(wint_t *out, int first, + int get(void *arg, uint32_t i), void *arg) { + uint32_t wc, cb, need, msb, i = 1; + if ((wc = first) == -1) return -1; + while ((wc & 0b11000000) == 0b10000000) { + if ((wc = get(arg, i++)) == -1) return -1; + } + if ((wc & 0b10000000) == 0b10000000) { + asm("bsr\t%1,%0" : "=r"(msb) : "rm"(~wc & 0xff) : "cc"); + if (!msb) msb = 1; + need = 7 - msb; + wc &= ((1u << msb) - 1) | 0b00000011; + for (uint32_t j = 1; j < need; ++j) { + if ((cb = get(arg, i++)) == -1) return -1; + if ((cb & 0b11000000) == 0b10000000) { + wc = wc << 6 | (cb & 0b00111111); + } else { + if (out) *out = u'�'; + return -1; + } + } + } + if (out) *out = (wint_t)wc; + return i; +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_STR_TPDECODECB_H_ */ diff --git a/libc/str/tpenc.S b/libc/str/tpenc.S new file mode 100644 index 00000000..0bfc5c7c --- /dev/null +++ b/libc/str/tpenc.S @@ -0,0 +1,71 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Encodes Thompson-Pike varint. +/ +/ @param edi is int to encode +/ @return rax is word-encoded byte buffer +/ @clob edi,rax,flags +/ @note invented on a napkin in a new jersey diner +tpenc: .leafprologue + .profilable + push %rcx + push %rdx + mov %edi,%edi + xor %eax,%eax + cmp $127,%edi + jbe 3f + bsr %edi,%ecx + ezlea kTpenc,dx + mov -7*(1+1)(%rdx,%rcx,2),%ecx +1: mov %edi,%edx + shr $6,%edi + and $0b00111111,%dl + or $0b10000000,%al + or %dl,%al + shl $8,%rax + dec %cl + jnz 1b +2: or %ch,%al +3: or %rdi,%rax + pop %rdx + pop %rcx + .leafepilogue + .endfn tpenc,globl + + .rodata +kTpenc: .rept 4 # MSB≤10 (0x7FF) + .byte 1,0b11000000 # len,mark + .endr + .rept 5 # MSB≤15 (0xFFFF) + .byte 2,0b11100000 # len,mark + .endr + .rept 5 # MSB≤20 (0x1FFFFF) + .byte 3,0b11110000 # len,mark + .endr + .rept 5 # MSB≤25 (0x3FFFFFF) + .byte 4,0b11111000 # len,mark + .endr + .rept 6 # MSB≤31 (0xffffffff) + .byte 5,0b11111100 # len,mark + .endr + .endobj kTpenc diff --git a/libc/str/tpenc.h b/libc/str/tpenc.h new file mode 100644 index 00000000..5fd0a220 --- /dev/null +++ b/libc/str/tpenc.h @@ -0,0 +1,23 @@ +#ifndef COSMOPOLITAN_LIBC_STR_TPENC_H_ +#define COSMOPOLITAN_LIBC_STR_TPENC_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +uint64_t tpenc(int32_t) pureconst; +uint64_t tpenc2(int32_t) pureconst; + +#define tpenc(CODE) \ + ({ \ + unsigned long Buf; \ + int Di, Code = (CODE); \ + if (0 <= Code && Code <= 127) { \ + Buf = Code; \ + } else { \ + asm("call\ttpenc" : "=a"(Buf), "=D"(Di) : "1"(CODE) : "cc"); \ + } \ + Buf; \ + }) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_STR_TPENC_H_ */ diff --git a/libc/str/tpencode.ncabi.c b/libc/str/tpencode.ncabi.c new file mode 100644 index 00000000..6d236dc4 --- /dev/null +++ b/libc/str/tpencode.ncabi.c @@ -0,0 +1,55 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/internal.h" +#include "libc/str/str.h" + +/** + * Thompson-Pike Varint Encoder. + * + * Implementation Details: The header macro should ensure this function + * is only called for non-ASCII, or DCE'd entirely. In addition to that + * this function makes a promise to not clobber any registers but %rax. + * + * @param buf is what ch gets encoded to + * @param size is the number of bytes available in buf + * @param ch is a 32-bit integer + * @param awesome mode enables numbers the IETF unilaterally banned + * @return number of bytes written + * @note this encoding was designed on a napkin in a new jersey diner + */ +unsigned(tpencode)(char *buf, size_t size, wint_t ch, bool32 awesome) { + unsigned char *p = (unsigned char *)buf; + if ((0 <= ch && ch < 32) && awesome && size >= 2) { + p[0] = 0xc0; + p[1] = 0x80 | (unsigned char)ch; + return 2; + } + struct TpEncode op = UseTpDecoderRing(ch); + size_t i = op.len; + if (op.len <= size) { + for (;;) { + p[--i] = (unsigned char)(0b10000000 | (ch & 0b00111111)); + if (!i) break; + ch >>= 6; + } + p[0] = op.mark | (unsigned char)ch; + } + return op.len; +} diff --git a/libc/str/tprecode16to8.c b/libc/str/tprecode16to8.c new file mode 100644 index 00000000..a1380af4 --- /dev/null +++ b/libc/str/tprecode16to8.c @@ -0,0 +1,47 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/str/str.h" + +/** + * Transcodes UTF-16 to UTF-8. + * + * @param dst is output buffer + * @param dstsize is bytes in dst + * @param src is NUL-terminated UTF-16 input string + * @return number of bytes written excluding NUL + */ +size_t tprecode16to8(char *dst, size_t dstsize, const char16_t *src) { + size_t i = 0; + if (dstsize) { + for (;;) { + wint_t wc; + src += abs(getutf16(src, &wc)); + if (!wc || dstsize == 1) { + dst[i] = '\0'; + break; + } + size_t got = abs(tpencode(&dst[i], dstsize, wc, false)); + dstsize -= got; + i += got; + } + } + return i; +} diff --git a/libc/str/tprecode8to16.c b/libc/str/tprecode8to16.c new file mode 100644 index 00000000..99406568 --- /dev/null +++ b/libc/str/tprecode8to16.c @@ -0,0 +1,47 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/str/str.h" + +/** + * Transcodes UTF-8 to UTF-16. + * + * @param dst is output buffer + * @param dstsize is shorts in dst + * @param src is NUL-terminated UTF-8 input string + * @return number of shorts written excluding NUL + */ +size_t tprecode8to16(char16_t *dst, size_t dstsize, const char *src) { + size_t i = 0; + if (dstsize) { + for (;;) { + wint_t wc; + src += abs(tpdecode(src, &wc)); + if (!wc || dstsize == 1) { + dst[i] = u'\0'; + break; + } + size_t got = abs(pututf16(&dst[i], dstsize, wc, false)); + dstsize -= got; + i += got; + } + } + return i; +} diff --git a/libc/str/undeflate.c b/libc/str/undeflate.c new file mode 100644 index 00000000..0c2e8fe6 --- /dev/null +++ b/libc/str/undeflate.c @@ -0,0 +1,260 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/intrin/repmovsb.h" +#include "libc/macros.h" +#include "libc/nexgen32e/kompressor.h" +#include "libc/str/str.h" +#include "libc/str/undeflate.h" + +#define kDeflateCompressionTypeNone 0b00 +#define kDeflateCompressionTypeFixedHuffman 0b01 +#define kDeflateCompressionTypeDynamicHuffman 0b10 + +#define kDeflateCodeLengthCopyPrevious3To6Times 16 +#define kDeflateCodeLengthRepeatZero3To10Times 17 +#define kDeflateCodeLengthRepeatZero11To138Times 18 + +#define CONSUME(BITS) \ + hold.word >>= BITS; \ + hold.bits -= BITS + +#define MOAR(BITS) \ + while (hold.bits < BITS) { \ + al = *ip++; \ + hold.word |= (size_t)al << hold.bits; \ + hold.bits += 8; \ + } + +struct DeflateHold { + size_t word; + size_t bits; +}; + +static const struct DeflateConsts { + uint16_t lenbase[32]; + uint16_t distbase[32]; + uint8_t lenbits[32]; + uint8_t distbits[32]; + uint8_t orders[19]; + struct RlDecode lensrl[6]; +} kDeflate = { + {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, + 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258}, + {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, + 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, + 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}, + {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, + 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}, + {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, + 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}, + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}, + {{144, 8}, {112, 9}, {24, 7}, {8, 8}, {32, 5}, {0, 0}}, +}; + +static uint32_t undeflatetree(struct DeflateState *ds, uint32_t *tree, + const uint8_t *lens, size_t symcount) { + size_t i, len; + uint32_t code, slot; + uint16_t codes[16], first[16], counts[16]; + memset(counts, 0, sizeof(counts)); + for (i = 0; i < symcount; i++) { + counts[lens[i]]++; + } + codes[0] = 0; + first[0] = 0; + counts[0] = 0; + for (i = 1; i < ARRAYLEN(codes); i++) { + codes[i] = (codes[i - 1] + counts[i - 1]) << 1; + first[i] = first[i - 1] + counts[i - 1]; + } + assert(first[15] + counts[15] <= symcount); + for (i = 0; i < symcount; i++) { + if ((len = lens[i])) { + code = codes[len]++; + slot = first[len]++; + tree[slot] = code << (32 - len) | i << 4 | len; + } + } + return first[15]; +} + +static struct DeflateHold undeflatesymbol(struct DeflateHold hold, + const uint32_t *tree, + size_t treecount, + uint32_t *out_symbol) { + size_t left, right, m; + uint32_t search, key; + left = 0; + right = treecount; + search = bitreverse16(hold.word); + search <<= 16; + search |= 0xffff; + while (left < right) { /* TODO(jart): Make this O(1) like Zlib. */ + m = (left + right) >> 1; + if (search < tree[m]) { + right = m; + } else { + left = m + 1; + } + } + key = tree[left - 1]; + assert(!((search ^ key) >> (32 - (key & 0xf)))); + *out_symbol = (key >> 4) & 0xfff; + CONSUME(key & 0xf); + return hold; +} + +/** + * Decompresses raw DEFLATE data. + * + * This is 10x smaller and 10x slower than chromium zlib. + * + * @param output should be followed by a single guard page, and have + * 36kb of guard pages preceding it too + * @note h/t Phil Katz, David Huffman, Claude Shannon + */ +ssize_t undeflate(void *output, size_t outputsize, void *input, + size_t inputsize, struct DeflateState *ds) { + struct DeflateHold hold; + bool isfinalblock; + size_t i, nlit, ndist; + uint8_t *ip, *op, *si, b, al, last, compressiontype; + uint32_t j, l, len, sym, tlit, tdist, tlen, nlen; + + op = output; + ip = input; + hold.word = 0; + hold.bits = 0; + isfinalblock = 0; + + while (!isfinalblock) { + MOAR(3); + isfinalblock = hold.word & 0b1; + CONSUME(1); + compressiontype = hold.word & 0b11; + CONSUME(2); + + switch (compressiontype) { + case kDeflateCompressionTypeNone: + CONSUME(hold.bits & 7); + MOAR(32); + len = hold.word & 0xffff; + nlen = (hold.word >> 16) & 0xffff; + assert(len == ~nlen); + CONSUME(32); + while (len--) { + if (hold.bits) { + *op++ = hold.word; + CONSUME(8); + } else { + *op++ = *ip++; + } + } + continue; + + case kDeflateCompressionTypeFixedHuffman: + nlit = 288; + ndist = 32; + rldecode(ds->lens, kDeflate.lensrl); + break; + + case kDeflateCompressionTypeDynamicHuffman: + MOAR(5 + 5 + 4); + nlit = (hold.word & 0b11111) + 257; + CONSUME(5); + ndist = (hold.word & 0b11111) + 1; + CONSUME(5); + nlen = (hold.word & 0b1111) + 4; + CONSUME(4); + for (i = 0; i < nlen; i++) { + MOAR(3); + ds->lenlens[kDeflate.orders[i]] = hold.word & 0b111; + CONSUME(3); + } + for (; i < ARRAYLEN(ds->lenlens); i++) { + ds->lenlens[kDeflate.orders[i]] = 0; + } + tlen = + undeflatetree(ds, ds->lencodes, ds->lenlens, ARRAYLEN(ds->lenlens)); + i = 0; + last = 0; + while (i < nlit + ndist) { + MOAR(16); + hold = undeflatesymbol(hold, ds->lencodes, tlen, &sym); + b = 2; + j = 1; + switch (sym) { + case kDeflateCodeLengthRepeatZero11To138Times: + b += 4; + j += 8; + /* fallthrough */ + case kDeflateCodeLengthRepeatZero3To10Times: + b += 1; + last = 0; + /* fallthrough */ + case kDeflateCodeLengthCopyPrevious3To6Times: + MOAR(b); + j += (hold.word & ((1u << b) - 1u)) + 2u; + CONSUME(b); + break; + default: + last = sym; + break; + } + while (j--) { + ds->lens[i++] = last; + } + } + break; + default: + return -1; + } + + tlit = undeflatetree(ds, ds->litcodes, ds->lens, nlit); + tdist = undeflatetree(ds, ds->distcodes, &ds->lens[nlit], ndist); + + do { + MOAR(16); + hold = undeflatesymbol(hold, ds->litcodes, tlit, &sym); + if (sym < 256) { + *op++ = sym; + } else if (sym > 256) { + sym -= 257; + b = kDeflate.lenbits[sym]; + MOAR(b); + l = kDeflate.lenbase[sym] + (hold.word & ((1u << b) - 1)); + CONSUME(b); + MOAR(16); + hold = undeflatesymbol(hold, ds->distcodes, tdist, &sym); + b = kDeflate.distbits[sym]; + MOAR(b); + /* max readback: 24577 + 2**13-1 = 32768 */ + si = op - ((uint32_t)kDeflate.distbase[sym] + + (uint32_t)(hold.word & ((1u << b) - 1))); + CONSUME(b); + repmovsb(&op, &si, l); + } + } while (sym != 256); + } + + return 0; +} diff --git a/libc/str/undeflate.h b/libc/str/undeflate.h new file mode 100644 index 00000000..440ad0c4 --- /dev/null +++ b/libc/str/undeflate.h @@ -0,0 +1,19 @@ +#ifndef COSMOPOLITAN_LIBC_STR_UNDEFLATE_H_ +#define COSMOPOLITAN_LIBC_STR_UNDEFLATE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct DeflateState { + uint8_t lenlens[19]; + uint32_t lencodes[19]; + uint32_t distcodes[32]; + uint32_t litcodes[288]; + uint8_t lens[288 + 32]; +}; + +ssize_t undeflate(void *output, size_t outputsize, void *input, + size_t inputsize, struct DeflateState *ds); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_STR_UNDEFLATE_H_ */ diff --git a/libc/str/varint.h b/libc/str/varint.h new file mode 100644 index 00000000..a0b753dc --- /dev/null +++ b/libc/str/varint.h @@ -0,0 +1,87 @@ +#ifndef COSMOPOLITAN_LIBC_VARINT_H_ +#define COSMOPOLITAN_LIBC_VARINT_H_ +#include "libc/limits.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define unzigzag(x) ((x >> 1) ^ -(x & 1)) +#define zigzag(x) _Generic((x), int32_t : zigzag32, default : zigzag64)(x) + +forceinline int32_t zigzag32(int32_t x) { + return (int64_t)((uint64_t)x << 1) ^ (x >> 31); +} + +forceinline int64_t zigzag64(int64_t x) { + return (int64_t)((uint64_t)x << 1) ^ (x >> 63); +} + +/** + * Copies variable-length integer to buffer. + * + * @param p needs 10+ bytes for 64-bit and 5+ for 32-bit + * @param x is unsigned number to encode + * @return pointer past last written byte + * @see writesint() which has more efficient encoding for signed numbers + */ +forceinline uint8_t *writevint(uint8_t *p, uint64_t x) { + do { + *p++ = (uint8_t)(x | 0x80); + x >>= 7; + } while (x > 0); + p[-1] &= 0x7f; + return p; +} + +/** + * Copies variable-length signed integer to buffer. + * + * @param p needs 10+ bytes for 64-bit and 5+ for 32-bit + * @param x is unsigned number to encode + * @return pointer past last written byte + */ +forceinline uint8_t *writesint(uint8_t *p, int64_t x) { + return writevint(p, zigzag(x)); +} + +/** + * Reads variable-length integer from buffer. + * + * @param x is unsigned number to encode + * @return pointer past last read byte or -1ul on error + */ +forceinline uint8_t *readvint(uint8_t *p, uint8_t *pe, uint64_t *res) { + uint8_t b; + uint64_t x, o; + x = 0; + b = 0; + while (p < pe) { + o = *p++; + x |= ((uint64_t)o & 0x7f) << b; + if (!(o & 0x80)) { + *res = x; + return p; + } + if ((b += 7) > 64) { + break; + } + } + return (uint8_t *)-1ul; +} + +/** + * Reads variable-length zig-zagged integer from buffer. + * + * @param x is unsigned number to encode + * @return pointer past last read byte or -1ul on error + */ +forceinline uint8_t *readsint(uint8_t *p, uint8_t *pe, int64_t *res) { + uint64_t u; + if ((p = readvint(p, pe, &u)) != (uint8_t *)-1ul) { + *res = unzigzag((int64_t)u); + return p; + } else { + return (uint8_t *)-1ul; + } +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_VARINT_H_ */ diff --git a/libc/str/wchomp.c b/libc/str/wchomp.c new file mode 100644 index 00000000..7348a4b1 --- /dev/null +++ b/libc/str/wchomp.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Mutates line to remove line-ending characters. + * + * @param line is NULL-propagating + * @see getline + */ +wchar_t *wchomp(wchar_t *line) { + if (line) line[strcspn(line, L"\r\n")] = '\0'; + return line; +} diff --git a/libc/str/wcrtomb.c b/libc/str/wcrtomb.c new file mode 100644 index 00000000..564ef267 --- /dev/null +++ b/libc/str/wcrtomb.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/limits.h" +#include "libc/str/str.h" + +size_t wcrtomb(char *s, wchar_t wc, mbstate_t *st) { + if (!s) return 1; + return tpencode(s, MB_CUR_MAX, wc, false); +} diff --git a/libc/str/wcsendswith.c b/libc/str/wcsendswith.c new file mode 100644 index 00000000..045a8edd --- /dev/null +++ b/libc/str/wcsendswith.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +#undef char +#undef endswith +#undef strlen +#undef strnlen + +#define char wchar_t +#define endswith wcsendswith +#define strlen wcslen +#define strnlen wcsnlen + +#include "libc/str/endswith.c" diff --git a/libc/str/wcsncpy.c b/libc/str/wcsncpy.c new file mode 100644 index 00000000..79599ffd --- /dev/null +++ b/libc/str/wcsncpy.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +wchar_t *wcsncpy(wchar_t *d, const wchar_t *s, size_t n) { + wchar_t *a; + for (a = d; n && *s; --n) { + *d++ = *s++; + } + wmemset(d, 0, n); + return a; +} diff --git a/libc/str/wcsrchr.c b/libc/str/wcsrchr.c new file mode 100644 index 00000000..09813092 --- /dev/null +++ b/libc/str/wcsrchr.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Searches for last instance of wchar_t in string. + * + * @param s is NUL-terminated wchar_t string to search + * @param c is the needle + * @return address of last c in s, or NULL if not found + * @asyncsignalsafe + */ +wchar_t *wcsrchr(const wchar_t *s, wchar_t c) { + return wmemrchr(s, c, wcslen(s)); +} diff --git a/libc/str/wcsrtombs.c b/libc/str/wcsrtombs.c new file mode 100644 index 00000000..1f256e76 --- /dev/null +++ b/libc/str/wcsrtombs.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/str/str.h" + +size_t wcsrtombs(char *dest, const wchar_t **src, size_t len, mbstate_t *ps) { + /* TODO(jart): broken broken broken insane api */ + size_t i = 0; + if (len) { + for (;;) { + if (!**src || len == 1) { + dest[i] = '\0'; + break; + } + size_t got = abs(tpencode(&dest[i], len, **src, false)); + len -= got; + i += got; + *src += 1; + } + } + return i; +} diff --git a/libc/str/wcsstartswith.c b/libc/str/wcsstartswith.c new file mode 100644 index 00000000..50c1e5c9 --- /dev/null +++ b/libc/str/wcsstartswith.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +#undef char +#undef startswith +#undef strlen +#undef strncmp + +#define char wchar_t +#define startswith wcsstartswith +#define strlen wcslen +#define strncmp wcsncmp + +#include "libc/str/startswith.c" diff --git a/libc/str/wcstombs.c b/libc/str/wcstombs.c new file mode 100644 index 00000000..f1c8eebb --- /dev/null +++ b/libc/str/wcstombs.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +size_t wcstombs(char *s, const wchar_t *ws, size_t n) { + return wcsrtombs(s, &(const wchar_t *){ws}, n, 0); +} diff --git a/libc/str/wctob.c b/libc/str/wctob.c new file mode 100644 index 00000000..c0403785 --- /dev/null +++ b/libc/str/wctob.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/str/str.h" + +int wctob(wint_t c) { + if (0 <= c && c <= 127) { + return c; + } else { + return EOF; + } +} diff --git a/libc/str/wctomb.c b/libc/str/wctomb.c new file mode 100644 index 00000000..2cb8d1fd --- /dev/null +++ b/libc/str/wctomb.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/limits.h" +#include "libc/str/str.h" + +int wctomb(char *s, wchar_t wc) { + if (!s) return 0; + return tpencode(s, MB_CUR_MAX, wc, false); +} diff --git a/libc/str/wmemcpy.c b/libc/str/wmemcpy.c new file mode 100644 index 00000000..c327ea7d --- /dev/null +++ b/libc/str/wmemcpy.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +compatfn wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, size_t count) { + return memcpy(dest, src, count * sizeof(wchar_t)); +} diff --git a/libc/str/wmemmove.c b/libc/str/wmemmove.c new file mode 100644 index 00000000..975c5e21 --- /dev/null +++ b/libc/str/wmemmove.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +compatfn wchar_t *wmemmove(wchar_t *dest, const wchar_t *src, size_t count) { + return memmove(dest, src, count * sizeof(wchar_t)); +} diff --git a/libc/str/wmempcpy.c b/libc/str/wmempcpy.c new file mode 100644 index 00000000..b97da7e5 --- /dev/null +++ b/libc/str/wmempcpy.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +compatfn wchar_t *wmempcpy(wchar_t *dest, const wchar_t *src, size_t count) { + return mempcpy(dest, src, count * sizeof(wchar_t)); +} diff --git a/libc/str/zipfindcentraldir.c b/libc/str/zipfindcentraldir.c new file mode 100644 index 00000000..bc091ab6 --- /dev/null +++ b/libc/str/zipfindcentraldir.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/zip.h" + +uint8_t *zipfindcentraldir(const uint8_t *map, size_t mapsize) { + const uint8_t *p, *pe; + for (p = map + mapsize - kZipCdirHdrMinSize, + pe = mapsize > 65536 + kZipCdirHdrMinSize + ? map + mapsize - 65536 - kZipCdirHdrMinSize + : map; + p >= pe; --p) { + if (ZIP_CDIR_MAGIC(p) == kZipCdirHdrMagic) { + return (/*unconst*/ uint8_t *)p; + } + } + return NULL; +} diff --git a/libc/stubs/abort.S b/libc/stubs/abort.S new file mode 100644 index 00000000..6f186435 --- /dev/null +++ b/libc/stubs/abort.S @@ -0,0 +1,32 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/macros.h" +.real +.code16 # ∩ .code32 ∩ .code64 + +/ Most basic tier of program self-termination. +/ +/ @mode long,legacy,real +abort: push %bp + mov %sp,%bp + rlcall panic + int3 + .endfn abort,weak,protected + .yoink __FILE__ diff --git a/libc/stubs/addvdi3.S b/libc/stubs/addvdi3.S new file mode 100644 index 00000000..d36f369d --- /dev/null +++ b/libc/stubs/addvdi3.S @@ -0,0 +1,41 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.align 16 +.text.likely + +/ Returns 𝑥+𝑦, aborting on overflow. +/ +/ @param rdi is int64 𝑥 +/ @param rsi is int64 𝑦 +/ @return rax is 𝑥+𝑦 +/ @see -ftrapv +__addvdi3: + mov %rdi,%rax + add %rsi,%rax + jo 1f + ret +1: push %rbp + mov %rsp,%rbp + call __on_arithmetic_overflow + pop %rbp + ret + .endfn __addvdi3,globl + .yoink __FILE__ diff --git a/libc/stubs/addvsi3.S b/libc/stubs/addvsi3.S new file mode 100644 index 00000000..1a639e8a --- /dev/null +++ b/libc/stubs/addvsi3.S @@ -0,0 +1,41 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.align 16 +.text.likely +.yoink __FILE__ + +/ Returns 𝑥+𝑦, aborting on overflow. +/ +/ @param edi is int32 𝑥 +/ @param esi is int32 𝑦 +/ @return eax is 𝑥+𝑦 +/ @see -ftrapv +__addvsi3: + mov %edi,%eax + add %esi,%eax + jo 1f + ret +1: push %rbp + mov %rsp,%rbp + call __on_arithmetic_overflow + pop %rbp + ret + .endfn __addvsi3,globl diff --git a/libc/stubs/addvti3.S b/libc/stubs/addvti3.S new file mode 100644 index 00000000..474d234e --- /dev/null +++ b/libc/stubs/addvti3.S @@ -0,0 +1,42 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.align 16 +.text.likely +.yoink __FILE__ + +/ Returns 𝑥+𝑦, aborting on overflow. +/ +/ @param rdi:rsi is int128 𝑥 +/ @param rdx:rcx is int128 𝑦 +/ @return rdx:rax is 𝑥+𝑦 +/ @see -ftrapv +__addvti3: + mov %rdi,%rax + add %rsi,%rax + adc %rdi,%rdx + jo 1f + ret +1: push %rbp + mov %rsp,%rbp + call __on_arithmetic_overflow + pop %rbp + ret + .endfn __addvti3,globl diff --git a/libc/stubs/asan.greg.S b/libc/stubs/asan.greg.S new file mode 100644 index 00000000..904bcde8 --- /dev/null +++ b/libc/stubs/asan.greg.S @@ -0,0 +1,54 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +__asan_addr_is_in_fake_stack: +__asan_alloca_poison: +__asan_allocas_unpoison: +__asan_get_current_fake_stack: +__asan_handle_no_return: +__asan_init: +__asan_loadN: +__asan_register_globals: +__asan_report_load_n: +__asan_report_store_n: +__asan_stack_free: +__asan_stack_malloc: +__asan_storeN: +__asan_unregister_globals: +__asan_version_mismatch_check_v8: + xor %eax,%eax + ret + .endfn __asan_addr_is_in_fake_stack,globl,weak + .endfn __asan_alloca_poison,globl,weak + .endfn __asan_allocas_unpoison,globl,weak + .endfn __asan_get_current_fake_stack,globl,weak + .endfn __asan_handle_no_return,globl,weak + .endfn __asan_init,globl,weak + .endfn __asan_loadN,globl,weak + .endfn __asan_register_globals,globl,weak + .endfn __asan_report_load_n,globl,weak + .endfn __asan_report_store_n,globl,weak + .endfn __asan_stack_free,globl,weak + .endfn __asan_stack_malloc,globl,weak + .endfn __asan_storeN,globl,weak + .endfn __asan_unregister_globals,globl,weak + .endfn __asan_version_mismatch_check_v8,globl,weak diff --git a/libc/stubs/asanjmp.greg.S b/libc/stubs/asanjmp.greg.S new file mode 100644 index 00000000..e4de81ef --- /dev/null +++ b/libc/stubs/asanjmp.greg.S @@ -0,0 +1,260 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.privileged +.yoink __FILE__ + +__asan_load1: + push $1 + jmp OnLoad + .endfn __asan_load1,globl +__asan_load2: + push $2 + jmp OnLoad + .endfn __asan_load2,globl +__asan_load4: + push $4 + jmp OnLoad + .endfn __asan_load4,globl +__asan_load8: + push $8 + jmp OnLoad + .endfn __asan_load8,globl +__asan_load16: + push $16 + jmp OnLoad + .endfn __asan_load16,globl +__asan_load32: + push $32 +/ fallthrough + .endfn __asan_load32,globl +OnLoad: pop %rsi + .globl __asan_loadN + .weak __asan_loadN + ezlea __asan_loadN,ax + jmp OnAsan + .endfn OnStore + +__asan_store1: + push $1 + jmp OnStore + .endfn __asan_store1,globl +__asan_store2: + push $2 + jmp OnStore + .endfn __asan_store2,globl +__asan_store4: + push $4 + jmp OnStore + .endfn __asan_store4,globl +__asan_store8: + push $8 + jmp OnStore + .endfn __asan_store8,globl +__asan_store16: + push $16 + jmp OnStore + .endfn __asan_store16,globl +__asan_store32: + push $32 +/ fallthrough + .endfn __asan_store32,globl +OnStore:pop %rsi + .globl __asan_storeN + .weak __asan_storeN + ezlea __asan_storeN,ax + jmp OnAsan + .endfn OnStore + +__asan_report_load1: + push $1 + jmp OnReportLoad + .endfn __asan_report_load1,globl +__asan_report_load2: + push $2 + jmp OnReportLoad + .endfn __asan_report_load2,globl +__asan_report_load4: + push $4 + jmp OnReportLoad + .endfn __asan_report_load4,globl +__asan_report_load8: + push $8 + jmp OnReportLoad + .endfn __asan_report_load8,globl +__asan_report_load16: + push $16 +/ fallthrough + .endfn __asan_report_load16,globl +OnReportLoad: + pop %rsi + .globl __asan_report_load_n + .weak __asan_report_load_n + ezlea __asan_report_load_n,ax + jmp OnAsan + .endfn OnReportLoad + +__asan_report_store1: + push $1 + jmp ReportStore + .endfn __asan_report_store1,globl +__asan_report_store2: + push $2 + jmp ReportStore + .endfn __asan_report_store2,globl +__asan_report_store4: + push $4 + jmp ReportStore + .endfn __asan_report_store4,globl +__asan_report_store8: + push $8 + jmp ReportStore + .endfn __asan_report_store8,globl +__asan_report_store16: + push $16 + jmp ReportStore + .endfn __asan_report_store16,globl +__asan_report_store32: + push $32 +/ fallthrough + .endfn __asan_report_store32,globl +ReportStore: + pop %rsi + .globl __asan_report_store_n + .weak __asan_report_store_n + ezlea __asan_report_store_n,ax +/ fallthrough + .endfn ReportStore + +OnAsan: test %rax,%rax + jz 1f + jmp *%rax +1: ret + .endfn OnAsan + +__asan_stack_free_0: + push $0 +/ fallthrough + .endfn __asan_stack_free_0,globl +OnStackFree: + pop %rdx + .globl __asan_stack_free + .weak __asan_stack_free + ezlea __asan_stack_free,ax + jmp OnAsan + .endfn OnStackFree +__asan_stack_free_1: + push $1 + jmp OnStackFree + .endfn __asan_stack_free_1,globl +__asan_stack_free_2: + push $2 + jmp OnStackFree + .endfn __asan_stack_free_2,globl +__asan_stack_free_3: + push $3 + jmp OnStackFree + .endfn __asan_stack_free_3,globl +__asan_stack_free_4: + push $4 + jmp OnStackFree + .endfn __asan_stack_free_4,globl +__asan_stack_free_5: + push $5 + jmp OnStackFree + .endfn __asan_stack_free_5,globl +__asan_stack_free_6: + push $6 + jmp OnStackFree + .endfn __asan_stack_free_6,globl +__asan_stack_free_7: + push $7 + jmp OnStackFree + .endfn __asan_stack_free_7,globl +__asan_stack_free_8: + push $8 + jmp OnStackFree + .endfn __asan_stack_free_8,globl +__asan_stack_free_9: + push $9 + jmp OnStackFree + .endfn __asan_stack_free_9,globl +__asan_stack_free_10: + push $10 + jmp OnStackFree + .endfn __asan_stack_free_10,globl + +__asan_stack_malloc_0: + push $0 +/ fallthrough + .endfn __asan_stack_malloc_0,globl +OnStackMalloc: + pop %rsi + .globl __asan_stack_malloc + .weak __asan_stack_malloc + ezlea __asan_stack_malloc,ax + jmp OnAsan + .endfn OnStackMalloc +__asan_stack_malloc_1: + push $1 + jmp OnStackMalloc + .endfn __asan_stack_malloc_1,globl +__asan_stack_malloc_2: + push $2 + jmp OnStackMalloc + .endfn __asan_stack_malloc_2,globl +__asan_stack_malloc_3: + push $3 + jmp OnStackMalloc + .endfn __asan_stack_malloc_3,globl +__asan_stack_malloc_4: + push $4 + jmp OnStackMalloc + .endfn __asan_stack_malloc_4,globl +__asan_stack_malloc_5: + push $5 + jmp OnStackMalloc + .endfn __asan_stack_malloc_5,globl +__asan_stack_malloc_6: + push $6 + jmp OnStackMalloc + .endfn __asan_stack_malloc_6,globl +__asan_stack_malloc_7: + push $7 + jmp OnStackMalloc + .endfn __asan_stack_malloc_7,globl +__asan_stack_malloc_8: + push $8 + jmp OnStackMalloc + .endfn __asan_stack_malloc_8,globl +__asan_stack_malloc_9: + push $9 + jmp OnStackMalloc + .endfn __asan_stack_malloc_9,globl +__asan_stack_malloc_10: + push $10 + jmp OnStackMalloc + .endfn __asan_stack_malloc_10,globl + + .rodata.cst4 +__asan_option_detect_stack_use_after_return: + .long 1 + .endobj __asan_option_detect_stack_use_after_return,globl + .previous diff --git a/libc/stubs/assertfail.S b/libc/stubs/assertfail.S new file mode 100644 index 00000000..1fe7fc34 --- /dev/null +++ b/libc/stubs/assertfail.S @@ -0,0 +1,35 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/macros.h" +.real +.yoink __FILE__ +.code16 # ∩ .code32 ∩ .code64 + +/ Lightweight universal overridable assert() macro support. +/ +/ @see libc/log/__assert_fail.c +/ @mode long,legacy,real +/ @noreturn +__assert_fail: + push %bp + mov %sp,%bp + rlcall panic + int3 + .endfn __assert_fail,weak diff --git a/libc/stubs/cxapurevirtual.S b/libc/stubs/cxapurevirtual.S new file mode 100644 index 00000000..50441671 --- /dev/null +++ b/libc/stubs/cxapurevirtual.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Did you call a virtual method from a destructor? +__cxa_pure_virtual: + push %rbp + mov %rsp,%rbp + .profilable + call abort + pop %rbp + ret + .endfn __cxa_pure_virtual,globl diff --git a/libc/stubs/debugbreak.S b/libc/stubs/debugbreak.S new file mode 100644 index 00000000..0ef274fb --- /dev/null +++ b/libc/stubs/debugbreak.S @@ -0,0 +1,33 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.inc" +.real +.yoink __FILE__ +.code16 # ∩ .code32 ∩ .code64 + +/ Triggers breakpoint in software debugger. +/ +/ This should work with GDB, Bochs, WinDbg, etc. +/ +/ @mode long,legacy,real +DebugBreak: + .softicebp + ret + .endfn DebugBreak,weak diff --git a/libc/stubs/errno.S b/libc/stubs/errno.S new file mode 100644 index 00000000..7d868e43 --- /dev/null +++ b/libc/stubs/errno.S @@ -0,0 +1,37 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.inc" +.yoink __FILE__ + +/ Global variable for last error. +/ +/ The system call wrappers update this with WIN32 error codes. +/ Unlike traditional libraries, Cosmopolitan error codes are +/ defined as variables. By convention, system calls and other +/ functions do not update this variable when nothing's broken. +/ +/ @see libc/sysv/consts.sh +/ @see libc/sysv/errfuns.h +/ @see __errno_location() stable abi + .bss + .align 4 +errno: .long 0 + .endobj errno,globl + yoink __errno_location diff --git a/libc/stubs/errnolocation.S b/libc/stubs/errnolocation.S new file mode 100644 index 00000000..db89a061 --- /dev/null +++ b/libc/stubs/errnolocation.S @@ -0,0 +1,30 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ +.keep.text # gdb needs it + +/ Returns address of errno variable. +/ @note this isn't a universal definition +__errno_location: + .leafprologue + lea errno(%rip),%rax + .leafepilogue + .endfn __errno_location,globl,hidden diff --git a/libc/stubs/exit.S b/libc/stubs/exit.S new file mode 100644 index 00000000..96b6fa24 --- /dev/null +++ b/libc/stubs/exit.S @@ -0,0 +1,37 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/macros.h" +.real +.yoink __FILE__ +.code16 # ∩ .code32 ∩ .code64 + +/ Linkable delegate for traditional Unix user process termination. +/ +/ @param edi is exit code ∈ [0,256) +/ @note cosmopolitan headers obfuscate this indirection +/ @see libc/runtime/runtime.h +/ @mode long,legacy,real +/ @asyncsignalsafe +/ @noreturn +_exit: push %bp + mov %sp,%bp + rlcall _Exit + int3 + .endfn _exit,weak,protected diff --git a/libc/stubs/exit11.S b/libc/stubs/exit11.S new file mode 100644 index 00000000..0092a31e --- /dev/null +++ b/libc/stubs/exit11.S @@ -0,0 +1,36 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/macros.h" +.real +.yoink __FILE__ +.code16 # ∩ .code32 ∩ .code64 + +/ Thrice re-imagined Unix user process termination API stub. +/ +/ @param edi is exit code ∈ [0,256) +/ @see libc/runtime/_exit.c +/ @mode long,legacy,real +/ @asyncsignalsafe +/ @noreturn +_Exit: push %bp + mov %sp,%bp + rlcall panic + int3 + .endfn _Exit,weak,protected diff --git a/libc/stubs/fentry.S b/libc/stubs/fentry.S new file mode 100644 index 00000000..0a859055 --- /dev/null +++ b/libc/stubs/fentry.S @@ -0,0 +1,32 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.inc" +.real +.yoink __FILE__ +.code16 # ∩ .code32 ∩ .code64 + +/ Function entry hook stub. +/ +/ @note cc -pg -mfentry adds this to the start of every function +/ @see libc/log/shadowargs.ncabi.c +/ @mode long,legacy,real +__fentry__: + ret + .endfn __fentry__,weak diff --git a/libc/stubs/gcov.S b/libc/stubs/gcov.S new file mode 100644 index 00000000..6091fb40 --- /dev/null +++ b/libc/stubs/gcov.S @@ -0,0 +1,63 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Magic words to unbreak build if GCOV flags are passed. + +__gcov_init: + ret + .endfn __gcov_init,globl,weak + +__gcov_exit: + ret + .endfn __gcov_exit,globl,weak + +__gcov_merge_add: + ret + .endfn __gcov_merge_add,globl,weak + +__gcov_fork: + ret + .endfn __gcov_fork,globl,weak + +__gcov_execle: + ret + .endfn __gcov_execle,globl,weak + +__gcov_execlp: + ret + .endfn __gcov_execlp,globl,weak + +__gcov_execl: + ret + .endfn __gcov_execl,globl,weak + +__gcov_execv: + ret + .endfn __gcov_execv,globl,weak + +__gcov_execvp: + ret + .endfn __gcov_execvp,globl,weak + +__gcov_execve: + ret + .endfn __gcov_execve,globl,weak diff --git a/libc/stubs/instrumentation.S b/libc/stubs/instrumentation.S new file mode 100644 index 00000000..1b4edae2 --- /dev/null +++ b/libc/stubs/instrumentation.S @@ -0,0 +1,34 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.inc" +.yoink __FILE__ + +/ @fileoverview Function Instrumentation No-Op Runtime +/ +/ The compiler generates synthetic calls to these functions when +/ the -finstrument-functions flag is passed. + +__cyg_profile_func_enter: + ret + .endfn __cyg_profile_func_enter,weak + +__cyg_profile_func_exit: + ret + .endfn __cyg_profile_func_exit,weak diff --git a/libc/stubs/ld.S b/libc/stubs/ld.S new file mode 100644 index 00000000..e8c89ff4 --- /dev/null +++ b/libc/stubs/ld.S @@ -0,0 +1,67 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +/ Traditional executable boundaries defined by linker. +/ @see man etext + _etext = 0 + _edata = 0 + _end = 0 + +/ Cosmopolitan executable boundaries defined by linker script. +/ @see libc/elf/elf.lds +/ @see ape/ape.lds + _base = 0 + ape.xlm = 0 + _ehead = 0 + _ereal = 0 + __privileged_start = 0 + __test_start = 0 + __ro = 0 + __piro_start = 0 + __relo_end = 0 + __piro_end = 0 + + .globl _base + .globl ape.xlm + .globl __piro_start + .globl __relo_end + .globl __piro_end + .globl __privileged_start + .globl __ro + .globl __test_start + .globl _edata + .globl _ehead + .globl _end + .globl _ereal + .globl _etext + + .weak _base + .weak ape.xlm + .weak __piro_start + .weak __relo_end + .weak __piro_end + .weak __privileged_start + .weak __ro + .weak __test_start + .weak _edata + .weak _ehead + .weak _end + .weak _ereal + .weak _etext diff --git a/libc/stubs/mcount.S b/libc/stubs/mcount.S new file mode 100644 index 00000000..cf78a45a --- /dev/null +++ b/libc/stubs/mcount.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.inc" +.real +.yoink __FILE__ +.code16 # ∩ .code32 ∩ .code64 + +/ Function Profiling Hook. +/ cc -pg adds this to the start of global functions. +mcount: ret + .endfn mcount,weak diff --git a/libc/stubs/missingno.S b/libc/stubs/missingno.S new file mode 100644 index 00000000..b9ef3bd7 --- /dev/null +++ b/libc/stubs/missingno.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.inc" +.real +.yoink __FILE__ +.code16 # ∩ .code32 ∩ .code64 + +/ Optional function stub. +missingno: + xor %ax,%ax + ret + .endfn missingno,globl,hidden diff --git a/libc/stubs/mulvdi3.S b/libc/stubs/mulvdi3.S new file mode 100644 index 00000000..f7f3e791 --- /dev/null +++ b/libc/stubs/mulvdi3.S @@ -0,0 +1,36 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.align 16 +.text.likely +.yoink __FILE__ + +/ Returns 𝑥*𝑦, aborting on overflow. +/ +/ @param rdi is int64 𝑥 +/ @param rdi is int64 𝑦 +/ @return rax is 𝑥*𝑦 +/ @see -ftrapv +__mulvdi3: + mov %rdi,%rax + imul %rsi + jc __on_arithmetic_overflow + ret + .endfn __mulvdi3,globl diff --git a/libc/stubs/mulvsi3.S b/libc/stubs/mulvsi3.S new file mode 100644 index 00000000..bb0f9937 --- /dev/null +++ b/libc/stubs/mulvsi3.S @@ -0,0 +1,36 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.align 16 +.text.likely +.yoink __FILE__ + +/ Returns 𝑥*𝑦, aborting on overflow. +/ +/ @param edi is int32 𝑥 +/ @param esi is int32 𝑦 +/ @return eax is 𝑥*𝑦 +/ @see -ftrapv +__mulvsi3: + mov %edi,%eax + imul %esi + jc __on_arithmetic_overflow + ret + .endfn __mulvsi3,globl diff --git a/libc/stubs/mulvti3.S b/libc/stubs/mulvti3.S new file mode 100644 index 00000000..7c68a5b3 --- /dev/null +++ b/libc/stubs/mulvti3.S @@ -0,0 +1,44 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.align 16 +.text.likely +.yoink __FILE__ + +/ Returns 𝑥*𝑦, aborting on overflow. +/ +/ TODO(jart): is this ok? +/ +/ @param rdi:rsi is int128 𝑥 +/ @param rdx:rcx is int128 𝑦 +/ @return rdx:rax is 𝑥*𝑦 +/ @see -ftrapv +__mulvti3: + mov %rdi,%rax + imul %rdx,%rsi + imul %rdi,%rcx + add %rsi,%rcx + mul %rdx + jc 1f + add %rcx,%rdx + jo 1f + ret +1: jmp __on_arithmetic_overflow + .endfn __mulvti3,globl diff --git a/libc/stubs/negvdi2.S b/libc/stubs/negvdi2.S new file mode 100644 index 00000000..8e5220c1 --- /dev/null +++ b/libc/stubs/negvdi2.S @@ -0,0 +1,40 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.align 16 +.text.likely +.yoink __FILE__ + +/ Returns -𝑥, aborting on overflow (two's complement bane). +/ +/ @param rdi is int64 𝑥 +/ @return rax is -𝑥 +/ @see -ftrapv +__negvdi2: + mov %rdi,%rax + neg %rax + jo 1f + ret +1: push %rbp + mov %rsp,%rbp + call __on_arithmetic_overflow + pop %rbp + ret + .endfn __negvdi2,globl diff --git a/libc/stubs/negvsi2.S b/libc/stubs/negvsi2.S new file mode 100644 index 00000000..41432eeb --- /dev/null +++ b/libc/stubs/negvsi2.S @@ -0,0 +1,40 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.align 16 +.text.likely +.yoink __FILE__ + +/ Returns -𝑥, aborting on overflow (two's complement bane). +/ +/ @param edi is int32 𝑥 +/ @return eax is -𝑥 +/ @see -ftrapv +__negvsi2: + mov %edi,%eax + neg %eax + jo 1f + ret +1: push %rbp + mov %rsp,%rbp + call __on_arithmetic_overflow + pop %rbp + ret + .endfn __negvsi2,globl diff --git a/libc/stubs/negvti2.S b/libc/stubs/negvti2.S new file mode 100644 index 00000000..5f58fa4a --- /dev/null +++ b/libc/stubs/negvti2.S @@ -0,0 +1,41 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.align 16 +.text.likely +.yoink __FILE__ + +/ Returns -𝑥, aborting on overflow. +/ +/ @param rdi:rsi is int128 𝑥 +/ @return rdx:rax is -𝑥 +/ @see -ftrapv +__negvti2: + mov %rdi,%rax + mov %rsi,%rdx + neg %rax + adc $0,%rdx +/ TODO(jart): Make sure this is correct. + jo 1f + neg %rdx + jo 1f + ret +1: jmp __on_arithmetic_overflow + .endfn __negvti2,globl diff --git a/libc/stubs/onarithmeticoverflow.S b/libc/stubs/onarithmeticoverflow.S new file mode 100644 index 00000000..d304d2fc --- /dev/null +++ b/libc/stubs/onarithmeticoverflow.S @@ -0,0 +1,33 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.text.unlikely +.yoink __FILE__ + +/ Arithmetic overflow handler. +/ +/ @see libc/testlib/arithmeticoverflowhook.S +/ @see -ftrapv +__on_arithmetic_overflow: + push %rbp + mov %rsp,%rbp + int3 + call abort + .endfn __on_arithmetic_overflow,weak diff --git a/libc/stubs/panic.S b/libc/stubs/panic.S new file mode 100644 index 00000000..b29a5f6e --- /dev/null +++ b/libc/stubs/panic.S @@ -0,0 +1,33 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.inc" +.real +.yoink __FILE__ +.code16 # ∩ .code32 ∩ .code64 + +/ Aborts or hard blocks instruction pointer. +/ @mode long,legacy,real +panic: push %bp + mov %sp,%bp + .softicebp + cli +1: hlt + jmp 1b + .endfn panic,weak,protected diff --git a/libc/stubs/stackguard.S b/libc/stubs/stackguard.S new file mode 100644 index 00000000..4f2d6825 --- /dev/null +++ b/libc/stubs/stackguard.S @@ -0,0 +1,46 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/macros.h" +.real +.yoink __FILE__ +.code16 # ∩ .code32 ∩ .code64 + +/** + * @fileoverview Overridable stubs for synthetic stack protector calls. + */ + +__stack_chk_fail_local: + nop +/ fallthrough + .endfn __stack_chk_fail_local,weak,hidden + +__stack_chk_fail: + push %bp + mov %sp,%bp + rlcall abort + nop + .endfn __stack_chk_fail,weak + + .bss + .align 8 +__stack_chk_guard: + .quad 0 + .endobj __stack_chk_guard,weak + .previous diff --git a/libc/stubs/stubs.mk b/libc/stubs/stubs.mk new file mode 100644 index 00000000..397eefda --- /dev/null +++ b/libc/stubs/stubs.mk @@ -0,0 +1,53 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ +# +# SYNOPSIS +# +# Universally Linkable Weak Functions +# +# DESCRIPTION +# +# This package contains no-op implementations for (1) synthetic +# compiler surprises and (2) mission-critical core functions, e.g. +# abort(). These functions are designed to work in all addressing +# modes, including real mode. Every package links this. It's at the +# base of the topological order of things. + +PKGS += LIBC_STUBS + +LIBC_STUBS_ARTIFACTS += LIBC_STUBS_A +LIBC_STUBS = $(LIBC_STUBS_A) +LIBC_STUBS_A = o/libc/stubs/stubs.a +LIBC_STUBS_A_FILES := $(wildcard libc/stubs/*.S) + +LIBC_STUBS_A_HDRS = \ + $(filter %.h,$(LIBC_STUBS_A_FILES)) + +LIBC_STUBS_A_SRCS = \ + $(filter %.S,$(LIBC_STUBS_A_FILES)) + +LIBC_STUBS_A_OBJS = \ + $(LIBC_STUBS_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_STUBS_A_SRCS:%.S=o/%.o) + +LIBC_STUBS_A_CHECKS = \ + $(LIBC_STUBS_A).pkg \ + $(LIBC_STUBS_A_HDRS:%=o/%.ok) + +$(LIBC_STUBS_A): \ + libc/stubs/ \ + $(LIBC_STUBS_A).pkg \ + $(LIBC_STUBS_A_OBJS) + +$(LIBC_STUBS_A).pkg: \ + $(LIBC_STUBS_A_OBJS) \ + $(foreach x,$(LIBC_STUBS_A_DIRECTDEPS),$($(x)_A).pkg) + +LIBC_STUBS_LIBS = $(foreach x,$(LIBC_STUBS_ARTIFACTS),$($(x))) +LIBC_STUBS_SRCS = $(foreach x,$(LIBC_STUBS_ARTIFACTS),$($(x)_SRCS)) +LIBC_STUBS_CHECKS = $(foreach x,$(LIBC_STUBS_ARTIFACTS),$($(x)_CHECKS)) +LIBC_STUBS_OBJS = $(foreach x,$(LIBC_STUBS_ARTIFACTS),$($(x)_OBJS)) +$(LIBC_STUBS_OBJS): $(BUILD_FILES) libc/stubs/stubs.mk + +.PHONY: o/libc/stubs +o/libc/stubs: $(LIBC_STUBS_CHECKS) diff --git a/libc/stubs/subvdi3.S b/libc/stubs/subvdi3.S new file mode 100644 index 00000000..10deb8e3 --- /dev/null +++ b/libc/stubs/subvdi3.S @@ -0,0 +1,41 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.align 16 +.text.likely +.yoink __FILE__ + +/ Returns 𝑥-𝑦, aborting on overflow. +/ +/ @param rdi is int64 𝑥 +/ @param rsi is int64 𝑦 +/ @return rax is 𝑥-𝑦 +/ @see -ftrapv +__subvdi3: + mov %rdi,%rax + sub %rsi,%rax + jo 1f + ret +1: push %rbp + mov %rsp,%rbp + call __on_arithmetic_overflow + pop %rbp + ret + .endfn __subvdi3,globl diff --git a/libc/stubs/subvsi3.S b/libc/stubs/subvsi3.S new file mode 100644 index 00000000..b0e463b8 --- /dev/null +++ b/libc/stubs/subvsi3.S @@ -0,0 +1,40 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.align 16 +.text.likely +.yoink __FILE__ + +/ Returns 𝑥-𝑦, aborting on overflow. +/ +/ @param edi is int32 𝑥 +/ @param esi is int32 𝑦 +/ @see -ftrapv +__subvsi3: + mov %edi,%eax + sub %esi,%eax + jo 1f + ret +1: push %rbp + mov %rsp,%rbp + call __on_arithmetic_overflow + pop %rbp + ret + .endfn __subvsi3,globl diff --git a/libc/stubs/subvti3.S b/libc/stubs/subvti3.S new file mode 100644 index 00000000..ef8276a6 --- /dev/null +++ b/libc/stubs/subvti3.S @@ -0,0 +1,42 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.align 16 +.text.likely +.yoink __FILE__ + +/ Returns 𝑥-𝑦, aborting on overflow. +/ +/ @param rdi:rsi is int128 𝑥 +/ @param rdx:rcx is int128 𝑦 +/ @return rdx:rax is 𝑥-𝑦 +/ @see -ftrapv +__subvti3: + mov %rdi,%rax + sub %rsi,%rax + sbb %rdi,%rdx + jo 1f + ret +1: push %rbp + mov %rsp,%rbp + call __on_arithmetic_overflow + pop %rbp + ret + .endfn __subvti3,globl diff --git a/libc/stubs/triplf.S b/libc/stubs/triplf.S new file mode 100644 index 00000000..2cf883a1 --- /dev/null +++ b/libc/stubs/triplf.S @@ -0,0 +1,42 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/macros.h" +#include "ape/config.h" +.real +.yoink __FILE__ +.code16 # ∩ .code32 ∩ .code64 + +/ Hoses interrupt descriptor table and triple-faults the system. +/ +/ @see youtu.be/GIKfEAF2Yhw?t=67 +/ @mode long,legacy,real +triplf: push %bp + mov %sp,%bp + sub $8,%sp + movpp %bp,%si + lea -8(%bp),%di + pushpop 8,%cx + xor %ax,%ax + rep stosb +0: cli + lidt -8(%bp) + ud2 + jmp 0b + .endfn triplf,globl,protected diff --git a/libc/stubs/typeinfo.S b/libc/stubs/typeinfo.S new file mode 100644 index 00000000..e5a84d48 --- /dev/null +++ b/libc/stubs/typeinfo.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +/ __cxxabiv1::__function_type_info (?) +/ Because Clang in MODE=dbg doesn't respect -fno-rtti + .align 8 +_ZTVN10__cxxabiv120__function_type_infoE: + .quad 0 + .endobj _ZTVN10__cxxabiv120__function_type_infoE,globl + .yoink __FILE__ diff --git a/libc/stubs/ubsan.S b/libc/stubs/ubsan.S new file mode 100644 index 00000000..34afbbaa --- /dev/null +++ b/libc/stubs/ubsan.S @@ -0,0 +1,312 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/macros.h" +.real +.code16 # ∩ .code32 ∩ .code64 +.yoink __FILE__ + +/** + * @fileoverview Overridable stubs for synthetic sanitizer calls. + */ + +__ubsan_default_options: + ret + .endfn __ubsan_default_options,weak + +__ubsan_get_current_report_data: + ret + .endfn __ubsan_get_current_report_data,weak + +__ubsan_handle_add_overflow: + nop +/ fallthrough + .endfn __ubsan_handle_add_overflow,weak + +__ubsan_handle_add_overflow_abort: + nop +/ fallthrough + .endfn __ubsan_handle_add_overflow_abort,weak + +__ubsan_handle_alignment_assumption: + nop +/ fallthrough + .endfn __ubsan_handle_alignment_assumption,weak + +__ubsan_handle_alignment_assumption_abort: + nop +/ fallthrough + .endfn __ubsan_handle_alignment_assumption_abort,weak + +__ubsan_handle_builtin_unreachable: + nop +/ fallthrough + .endfn __ubsan_handle_builtin_unreachable,weak + +__ubsan_handle_builtin_unreachable_abort: + nop +/ fallthrough + .endfn __ubsan_handle_builtin_unreachable_abort,weak + +__ubsan_handle_cfi_bad_type: + nop +/ fallthrough + .endfn __ubsan_handle_cfi_bad_type,weak + +__ubsan_handle_cfi_bad_type_abort: + nop +/ fallthrough + .endfn __ubsan_handle_cfi_bad_type_abort,weak + +__ubsan_handle_cfi_check_fail: + nop +/ fallthrough + .endfn __ubsan_handle_cfi_check_fail,weak + +__ubsan_handle_cfi_check_fail_abort: + nop +/ fallthrough + .endfn __ubsan_handle_cfi_check_fail_abort,weak + +__ubsan_handle_divrem_overflow: + nop +/ fallthrough + .endfn __ubsan_handle_divrem_overflow,weak + +__ubsan_handle_divrem_overflow_abort: + nop +/ fallthrough + .endfn __ubsan_handle_divrem_overflow_abort,weak + +__ubsan_handle_dynamic_type_cache_miss: + nop +/ fallthrough + .endfn __ubsan_handle_dynamic_type_cache_miss,weak + +__ubsan_handle_dynamic_type_cache_miss_abort: + nop +/ fallthrough + .endfn __ubsan_handle_dynamic_type_cache_miss_abort,weak + +__ubsan_handle_float_cast_overflow: + nop +/ fallthrough + .endfn __ubsan_handle_float_cast_overflow,weak + +__ubsan_handle_float_cast_overflow_abort: + nop +/ fallthrough + .endfn __ubsan_handle_float_cast_overflow_abort,weak + +__ubsan_handle_function_type_mismatch: + nop +/ fallthrough + .endfn __ubsan_handle_function_type_mismatch,weak + +__ubsan_handle_function_type_mismatch_abort: + nop +/ fallthrough + .endfn __ubsan_handle_function_type_mismatch_abort,weak + +__ubsan_handle_implicit_conversion: + nop +/ fallthrough + .endfn __ubsan_handle_implicit_conversion,weak + +__ubsan_handle_implicit_conversion_abort: + nop +/ fallthrough + .endfn __ubsan_handle_implicit_conversion_abort,weak + +__ubsan_handle_invalid_builtin: + nop +/ fallthrough + .endfn __ubsan_handle_invalid_builtin,weak + +__ubsan_handle_invalid_builtin_abort: + nop +/ fallthrough + .endfn __ubsan_handle_invalid_builtin_abort,weak + +__ubsan_handle_load_invalid_value: + nop +/ fallthrough + .endfn __ubsan_handle_load_invalid_value,weak + +__ubsan_handle_load_invalid_value_abort: + nop +/ fallthrough + .endfn __ubsan_handle_load_invalid_value_abort,weak + +__ubsan_handle_missing_return: + nop +/ fallthrough + .endfn __ubsan_handle_missing_return,weak + +__ubsan_handle_missing_return_abort: + nop +/ fallthrough + .endfn __ubsan_handle_missing_return_abort,weak + +__ubsan_handle_mul_overflow: + nop +/ fallthrough + .endfn __ubsan_handle_mul_overflow,weak + +__ubsan_handle_mul_overflow_abort: + nop +/ fallthrough + .endfn __ubsan_handle_mul_overflow_abort,weak + +__ubsan_handle_negate_overflow: + nop +/ fallthrough + .endfn __ubsan_handle_negate_overflow,weak + +__ubsan_handle_negate_overflow_abort: + nop +/ fallthrough + .endfn __ubsan_handle_negate_overflow_abort,weak + +__ubsan_handle_nonnull_arg: + nop +/ fallthrough + .endfn __ubsan_handle_nonnull_arg,weak + +__ubsan_handle_nonnull_arg_abort: + nop +/ fallthrough + .endfn __ubsan_handle_nonnull_arg_abort,weak + +__ubsan_handle_nonnull_return: + nop +/ fallthrough + .endfn __ubsan_handle_nonnull_return,weak + +__ubsan_handle_nonnull_return_abort: + nop +/ fallthrough + .endfn __ubsan_handle_nonnull_return_abort,weak + +__ubsan_handle_nonnull_return_v1: + nop +/ fallthrough + .endfn __ubsan_handle_nonnull_return_v1,weak + +__ubsan_handle_nonnull_return_v1_abort: + nop +/ fallthrough + .endfn __ubsan_handle_nonnull_return_v1_abort,weak + +__ubsan_handle_nullability_arg: + nop +/ fallthrough + .endfn __ubsan_handle_nullability_arg,weak + +__ubsan_handle_nullability_arg_abort: + nop +/ fallthrough + .endfn __ubsan_handle_nullability_arg_abort,weak + +__ubsan_handle_nullability_return_v1: + nop +/ fallthrough + .endfn __ubsan_handle_nullability_return_v1,weak + +__ubsan_handle_nullability_return_v1_abort: + nop +/ fallthrough + .endfn __ubsan_handle_nullability_return_v1_abort,weak + +__ubsan_handle_out_of_bounds: + nop +/ fallthrough + .endfn __ubsan_handle_out_of_bounds,weak + +__ubsan_handle_out_of_bounds_abort: + nop +/ fallthrough + .endfn __ubsan_handle_out_of_bounds_abort,weak + +__ubsan_handle_pointer_overflow: + nop +/ fallthrough + .endfn __ubsan_handle_pointer_overflow,weak + +__ubsan_handle_pointer_overflow_abort: + nop +/ fallthrough + .endfn __ubsan_handle_pointer_overflow_abort,weak + +__ubsan_handle_shift_out_of_bounds: + nop +/ fallthrough + .endfn __ubsan_handle_shift_out_of_bounds,weak + +__ubsan_handle_shift_out_of_bounds_abort: + nop +/ fallthrough + .endfn __ubsan_handle_shift_out_of_bounds_abort,weak + +__ubsan_handle_sub_overflow: + nop +/ fallthrough + .endfn __ubsan_handle_sub_overflow,weak + +__ubsan_handle_sub_overflow_abort: + nop +/ fallthrough + .endfn __ubsan_handle_sub_overflow_abort,weak + +__ubsan_handle_type_mismatch: + nop +/ fallthrough + .endfn __ubsan_handle_type_mismatch,weak + +__ubsan_handle_type_mismatch_abort: + nop +/ fallthrough + .endfn __ubsan_handle_type_mismatch_abort,weak + +__ubsan_handle_type_mismatch_v1: + nop +/ fallthrough + .endfn __ubsan_handle_type_mismatch_v1,weak + +__ubsan_handle_type_mismatch_v1_abort: + nop +/ fallthrough + .endfn __ubsan_handle_type_mismatch_v1_abort,weak + +__ubsan_handle_vla_bound_not_positive: + nop +/ fallthrough + .endfn __ubsan_handle_vla_bound_not_positive,weak + +__ubsan_handle_vla_bound_not_positive_abort: + nop +/ fallthrough + .endfn __ubsan_handle_vla_bound_not_positive_abort,weak + +__ubsan_abort_stub: + push %bp + mov %sp,%bp +1: int3 + jmp 1b + .endfn __ubsan_abort_stub diff --git a/libc/stubs/unprovable.S b/libc/stubs/unprovable.S new file mode 100644 index 00000000..2495bc52 --- /dev/null +++ b/libc/stubs/unprovable.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.inc" +.real +.code16 # ∩ .code32 ∩ .code64 + +__unprovable: + push %bp + mov %sp,%bp + .softicebp + pop %bp + ret + .endfn __unprovable,globl,hidden + .yoink __FILE__ diff --git a/libc/stubs/xnu.S b/libc/stubs/xnu.S new file mode 100644 index 00000000..2359180a --- /dev/null +++ b/libc/stubs/xnu.S @@ -0,0 +1,25 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +_start_xnu: + jmp abort + .endfn _start_xnu,weak + .yoink __FILE__ diff --git a/libc/stubs/zip.S b/libc/stubs/zip.S new file mode 100644 index 00000000..7012451d --- /dev/null +++ b/libc/stubs/zip.S @@ -0,0 +1,26 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +__zip_start: + .endfn __zip_start,weak + +__zip_end: + .endfn __zip_end,weak diff --git a/libc/sysv/README.md b/libc/sysv/README.md new file mode 100644 index 00000000..a37c6dab --- /dev/null +++ b/libc/sysv/README.md @@ -0,0 +1,24 @@ +SYNOPSIS + + System Five Import Libraries + +OVERVIEW + + Bell System Five is the umbrella term we use to describe Linux, + FreeBSD, OpenBSD, and Mac OS X which all have nearly-identical + application binary interfaces that stood the test of time, having + definitions nearly the same as those of AT&T back in the 1980's. + + Cosmopolitan aims to help you build apps that can endure over the + course of decades, just like these systems have: without needing to + lift a finger for maintenance churn, broken builds, broken hearts. + + The challenge to System V binary compatibility basically boils down + to numbers. All these systems agree on what services are provided, + but tend to grant them wildly different numbers. + + We address this by putting all the numbers in a couple big shell + scripts, ask the GNU Assembler to encode them into binaries using an + efficient LEB128 encoding, unpacked by _init(), and ref'd via extern + const. It gives us good debuggability, and any costs are gained back + by fewer branches in wrapper functions.z diff --git a/libc/sysv/calls/__accept-sysv.s b/libc/sysv/calls/__accept-sysv.s new file mode 100644 index 00000000..24938f0e --- /dev/null +++ b/libc/sysv/calls/__accept-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __accept$sysv 0x001e0063201e002b globl hidden diff --git a/libc/sysv/calls/__accept4-sysv.s b/libc/sysv/calls/__accept4-sysv.s new file mode 100644 index 00000000..e5677585 --- /dev/null +++ b/libc/sysv/calls/__accept4-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __accept4$sysv 0x005d021dffff0120 globl hidden diff --git a/libc/sysv/calls/__acl_aclcheck_fd.s b/libc/sysv/calls/__acl_aclcheck_fd.s new file mode 100644 index 00000000..e9c4527f --- /dev/null +++ b/libc/sysv/calls/__acl_aclcheck_fd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __acl_aclcheck_fd 0xffff0162ffffffff globl diff --git a/libc/sysv/calls/__acl_aclcheck_file.s b/libc/sysv/calls/__acl_aclcheck_file.s new file mode 100644 index 00000000..19a97a47 --- /dev/null +++ b/libc/sysv/calls/__acl_aclcheck_file.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __acl_aclcheck_file 0xffff0161ffffffff globl diff --git a/libc/sysv/calls/__acl_aclcheck_link.s b/libc/sysv/calls/__acl_aclcheck_link.s new file mode 100644 index 00000000..c9e50402 --- /dev/null +++ b/libc/sysv/calls/__acl_aclcheck_link.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __acl_aclcheck_link 0xffff01acffffffff globl diff --git a/libc/sysv/calls/__acl_delete_fd.s b/libc/sysv/calls/__acl_delete_fd.s new file mode 100644 index 00000000..cca5435e --- /dev/null +++ b/libc/sysv/calls/__acl_delete_fd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __acl_delete_fd 0xffff0160ffffffff globl diff --git a/libc/sysv/calls/__acl_delete_file.s b/libc/sysv/calls/__acl_delete_file.s new file mode 100644 index 00000000..0b8ab1fb --- /dev/null +++ b/libc/sysv/calls/__acl_delete_file.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __acl_delete_file 0xffff015fffffffff globl diff --git a/libc/sysv/calls/__acl_delete_link.s b/libc/sysv/calls/__acl_delete_link.s new file mode 100644 index 00000000..64373be3 --- /dev/null +++ b/libc/sysv/calls/__acl_delete_link.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __acl_delete_link 0xffff01abffffffff globl diff --git a/libc/sysv/calls/__acl_get_fd.s b/libc/sysv/calls/__acl_get_fd.s new file mode 100644 index 00000000..3536e66c --- /dev/null +++ b/libc/sysv/calls/__acl_get_fd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __acl_get_fd 0xffff015dffffffff globl diff --git a/libc/sysv/calls/__acl_get_file.s b/libc/sysv/calls/__acl_get_file.s new file mode 100644 index 00000000..2d63ba16 --- /dev/null +++ b/libc/sysv/calls/__acl_get_file.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __acl_get_file 0xffff015bffffffff globl diff --git a/libc/sysv/calls/__acl_get_link.s b/libc/sysv/calls/__acl_get_link.s new file mode 100644 index 00000000..ed283e15 --- /dev/null +++ b/libc/sysv/calls/__acl_get_link.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __acl_get_link 0xffff01a9ffffffff globl diff --git a/libc/sysv/calls/__acl_set_fd.s b/libc/sysv/calls/__acl_set_fd.s new file mode 100644 index 00000000..87049b86 --- /dev/null +++ b/libc/sysv/calls/__acl_set_fd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __acl_set_fd 0xffff015effffffff globl diff --git a/libc/sysv/calls/__acl_set_file.s b/libc/sysv/calls/__acl_set_file.s new file mode 100644 index 00000000..b4daa111 --- /dev/null +++ b/libc/sysv/calls/__acl_set_file.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __acl_set_file 0xffff015cffffffff globl diff --git a/libc/sysv/calls/__acl_set_link.s b/libc/sysv/calls/__acl_set_link.s new file mode 100644 index 00000000..a33716c9 --- /dev/null +++ b/libc/sysv/calls/__acl_set_link.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __acl_set_link 0xffff01aaffffffff globl diff --git a/libc/sysv/calls/__cap_rights_get.s b/libc/sysv/calls/__cap_rights_get.s new file mode 100644 index 00000000..5810f39d --- /dev/null +++ b/libc/sysv/calls/__cap_rights_get.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __cap_rights_get 0xffff0203ffffffff globl diff --git a/libc/sysv/calls/__connect-sysv.s b/libc/sysv/calls/__connect-sysv.s new file mode 100644 index 00000000..5df70c9f --- /dev/null +++ b/libc/sysv/calls/__connect-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __connect$sysv 0x006200622062002a globl hidden diff --git a/libc/sysv/calls/__disable_threadsignal.s b/libc/sysv/calls/__disable_threadsignal.s new file mode 100644 index 00000000..8c202c3d --- /dev/null +++ b/libc/sysv/calls/__disable_threadsignal.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __disable_threadsignal 0xffffffff214bffff globl diff --git a/libc/sysv/calls/__dup3-sysv.s b/libc/sysv/calls/__dup3-sysv.s new file mode 100644 index 00000000..0e0a25f3 --- /dev/null +++ b/libc/sysv/calls/__dup3-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __dup3$sysv 0x0066ffffffff0124 globl hidden diff --git a/libc/sysv/calls/__fstat-sysv.s b/libc/sysv/calls/__fstat-sysv.s new file mode 100644 index 00000000..0d661a3a --- /dev/null +++ b/libc/sysv/calls/__fstat-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __fstat$sysv 0x0035022721530005 globl hidden diff --git a/libc/sysv/calls/__fstatat-sysv.s b/libc/sysv/calls/__fstatat-sysv.s new file mode 100644 index 00000000..7725d914 --- /dev/null +++ b/libc/sysv/calls/__fstatat-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __fstatat$sysv 0x002a022821d60106 globl hidden diff --git a/libc/sysv/calls/__ftruncate-sysv.s b/libc/sysv/calls/__ftruncate-sysv.s new file mode 100644 index 00000000..97d900b1 --- /dev/null +++ b/libc/sysv/calls/__ftruncate-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __ftruncate$sysv 0x00c901e020c9004d globl hidden diff --git a/libc/sysv/calls/__get_tcb.s b/libc/sysv/calls/__get_tcb.s new file mode 100644 index 00000000..09851767 --- /dev/null +++ b/libc/sysv/calls/__get_tcb.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __get_tcb 0x014affffffffffff globl diff --git a/libc/sysv/calls/__getpeername-sysv.s b/libc/sysv/calls/__getpeername-sysv.s new file mode 100644 index 00000000..7854f80b --- /dev/null +++ b/libc/sysv/calls/__getpeername-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __getpeername$sysv 0x001f008d201f0034 globl hidden diff --git a/libc/sysv/calls/__getsockname-sysv.s b/libc/sysv/calls/__getsockname-sysv.s new file mode 100644 index 00000000..4b5ebc73 --- /dev/null +++ b/libc/sysv/calls/__getsockname-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __getsockname$sysv 0x0020002020200033 globl hidden diff --git a/libc/sysv/calls/__gettimeofday-sysv.s b/libc/sysv/calls/__gettimeofday-sysv.s new file mode 100644 index 00000000..0d48433b --- /dev/null +++ b/libc/sysv/calls/__gettimeofday-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __gettimeofday$sysv 0x0043007420740060 globl hidden diff --git a/libc/sysv/calls/__lseek-sysv.s b/libc/sysv/calls/__lseek-sysv.s new file mode 100644 index 00000000..5fcb3aa7 --- /dev/null +++ b/libc/sysv/calls/__lseek-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __lseek$sysv 0x00c701de20c70008 globl hidden diff --git a/libc/sysv/calls/__lstat-sysv.s b/libc/sysv/calls/__lstat-sysv.s new file mode 100644 index 00000000..1c3372a8 --- /dev/null +++ b/libc/sysv/calls/__lstat-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __lstat$sysv 0x0028002821540006 globl hidden diff --git a/libc/sysv/calls/__mac_execve.s b/libc/sysv/calls/__mac_execve.s new file mode 100644 index 00000000..143e7f87 --- /dev/null +++ b/libc/sysv/calls/__mac_execve.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __mac_execve 0xffff019f217cffff globl diff --git a/libc/sysv/calls/__mac_get_fd.s b/libc/sysv/calls/__mac_get_fd.s new file mode 100644 index 00000000..aa92441c --- /dev/null +++ b/libc/sysv/calls/__mac_get_fd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __mac_get_fd 0xffff01822184ffff globl diff --git a/libc/sysv/calls/__mac_get_file.s b/libc/sysv/calls/__mac_get_file.s new file mode 100644 index 00000000..6f1f4f36 --- /dev/null +++ b/libc/sysv/calls/__mac_get_file.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __mac_get_file 0xffff0183217effff globl diff --git a/libc/sysv/calls/__mac_get_link.s b/libc/sysv/calls/__mac_get_link.s new file mode 100644 index 00000000..23020063 --- /dev/null +++ b/libc/sysv/calls/__mac_get_link.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __mac_get_link 0xffff019a2180ffff globl diff --git a/libc/sysv/calls/__mac_get_mount.s b/libc/sysv/calls/__mac_get_mount.s new file mode 100644 index 00000000..b8f3e247 --- /dev/null +++ b/libc/sysv/calls/__mac_get_mount.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __mac_get_mount 0xffffffff21a9ffff globl diff --git a/libc/sysv/calls/__mac_get_pid.s b/libc/sysv/calls/__mac_get_pid.s new file mode 100644 index 00000000..9d70088a --- /dev/null +++ b/libc/sysv/calls/__mac_get_pid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __mac_get_pid 0xffff01992186ffff globl diff --git a/libc/sysv/calls/__mac_get_proc.s b/libc/sysv/calls/__mac_get_proc.s new file mode 100644 index 00000000..6c9f1eb3 --- /dev/null +++ b/libc/sysv/calls/__mac_get_proc.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __mac_get_proc 0xffff01802182ffff globl diff --git a/libc/sysv/calls/__mac_getfsstat.s b/libc/sysv/calls/__mac_getfsstat.s new file mode 100644 index 00000000..8f130a9e --- /dev/null +++ b/libc/sysv/calls/__mac_getfsstat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __mac_getfsstat 0xffffffff21aaffff globl diff --git a/libc/sysv/calls/__mac_mount.s b/libc/sysv/calls/__mac_mount.s new file mode 100644 index 00000000..c9e62ece --- /dev/null +++ b/libc/sysv/calls/__mac_mount.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __mac_mount 0xffffffff21a8ffff globl diff --git a/libc/sysv/calls/__mac_set_fd.s b/libc/sysv/calls/__mac_set_fd.s new file mode 100644 index 00000000..b6d45299 --- /dev/null +++ b/libc/sysv/calls/__mac_set_fd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __mac_set_fd 0xffff01842185ffff globl diff --git a/libc/sysv/calls/__mac_set_file.s b/libc/sysv/calls/__mac_set_file.s new file mode 100644 index 00000000..b7cbbb1c --- /dev/null +++ b/libc/sysv/calls/__mac_set_file.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __mac_set_file 0xffff0185217fffff globl diff --git a/libc/sysv/calls/__mac_set_link.s b/libc/sysv/calls/__mac_set_link.s new file mode 100644 index 00000000..953a8b9f --- /dev/null +++ b/libc/sysv/calls/__mac_set_link.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __mac_set_link 0xffff019b2181ffff globl diff --git a/libc/sysv/calls/__mac_set_proc.s b/libc/sysv/calls/__mac_set_proc.s new file mode 100644 index 00000000..786e5219 --- /dev/null +++ b/libc/sysv/calls/__mac_set_proc.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __mac_set_proc 0xffff01812183ffff globl diff --git a/libc/sysv/calls/__mac_syscall.s b/libc/sysv/calls/__mac_syscall.s new file mode 100644 index 00000000..b3c2e0a9 --- /dev/null +++ b/libc/sysv/calls/__mac_syscall.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __mac_syscall 0xffffffff217dffff globl diff --git a/libc/sysv/calls/__mmap-sysv.s b/libc/sysv/calls/__mmap-sysv.s new file mode 100644 index 00000000..5fa51eb4 --- /dev/null +++ b/libc/sysv/calls/__mmap-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __mmap$sysv 0x00c501dd20c50009 globl hidden diff --git a/libc/sysv/calls/__old_semwait_signal.s b/libc/sysv/calls/__old_semwait_signal.s new file mode 100644 index 00000000..ca6a8449 --- /dev/null +++ b/libc/sysv/calls/__old_semwait_signal.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __old_semwait_signal 0xffffffff2172ffff globl diff --git a/libc/sysv/calls/__old_semwait_signal_nocancel.s b/libc/sysv/calls/__old_semwait_signal_nocancel.s new file mode 100644 index 00000000..b2d16b4f --- /dev/null +++ b/libc/sysv/calls/__old_semwait_signal_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __old_semwait_signal_nocancel 0xffffffff2173ffff globl diff --git a/libc/sysv/calls/__pipe-sysv.s b/libc/sysv/calls/__pipe-sysv.s new file mode 100644 index 00000000..f5bb6c9a --- /dev/null +++ b/libc/sysv/calls/__pipe-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __pipe$sysv 0x0107021e202a0016 globl hidden diff --git a/libc/sysv/calls/__pipe2-sysv.s b/libc/sysv/calls/__pipe2-sysv.s new file mode 100644 index 00000000..5a96ea9f --- /dev/null +++ b/libc/sysv/calls/__pipe2-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __pipe2$sysv 0x0065021effff0125 globl hidden diff --git a/libc/sysv/calls/__pread-sysv.s b/libc/sysv/calls/__pread-sysv.s new file mode 100644 index 00000000..0b6e8c30 --- /dev/null +++ b/libc/sysv/calls/__pread-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __pread$sysv 0x00ad01db20990011 globl hidden diff --git a/libc/sysv/calls/__preadv-sysv.s b/libc/sysv/calls/__preadv-sysv.s new file mode 100644 index 00000000..43d90984 --- /dev/null +++ b/libc/sysv/calls/__preadv-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __preadv$sysv 0x010b0121ffff0127 globl hidden diff --git a/libc/sysv/calls/__pthread_canceled.s b/libc/sysv/calls/__pthread_canceled.s new file mode 100644 index 00000000..50e24ae4 --- /dev/null +++ b/libc/sysv/calls/__pthread_canceled.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __pthread_canceled 0xffffffff214dffff globl diff --git a/libc/sysv/calls/__pthread_chdir.s b/libc/sysv/calls/__pthread_chdir.s new file mode 100644 index 00000000..ddd9b195 --- /dev/null +++ b/libc/sysv/calls/__pthread_chdir.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __pthread_chdir 0xffffffff215cffff globl diff --git a/libc/sysv/calls/__pthread_fchdir.s b/libc/sysv/calls/__pthread_fchdir.s new file mode 100644 index 00000000..9c4569bf --- /dev/null +++ b/libc/sysv/calls/__pthread_fchdir.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __pthread_fchdir 0xffffffff215dffff globl diff --git a/libc/sysv/calls/__pthread_kill.s b/libc/sysv/calls/__pthread_kill.s new file mode 100644 index 00000000..c6b870af --- /dev/null +++ b/libc/sysv/calls/__pthread_kill.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __pthread_kill 0xffffffff2148ffff globl diff --git a/libc/sysv/calls/__pthread_markcancel.s b/libc/sysv/calls/__pthread_markcancel.s new file mode 100644 index 00000000..4d8c5920 --- /dev/null +++ b/libc/sysv/calls/__pthread_markcancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __pthread_markcancel 0xffffffff214cffff globl diff --git a/libc/sysv/calls/__pthread_sigmask.s b/libc/sysv/calls/__pthread_sigmask.s new file mode 100644 index 00000000..bf0d528f --- /dev/null +++ b/libc/sysv/calls/__pthread_sigmask.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __pthread_sigmask 0xffffffff2149ffff globl diff --git a/libc/sysv/calls/__pwrite-sysv.s b/libc/sysv/calls/__pwrite-sysv.s new file mode 100644 index 00000000..49eb9201 --- /dev/null +++ b/libc/sysv/calls/__pwrite-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __pwrite$sysv 0x00ae01dc209a0012 globl hidden diff --git a/libc/sysv/calls/__pwritev-sysv.s b/libc/sysv/calls/__pwritev-sysv.s new file mode 100644 index 00000000..ec07936b --- /dev/null +++ b/libc/sysv/calls/__pwritev-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __pwritev$sysv 0x010c0122ffff0128 globl hidden diff --git a/libc/sysv/calls/__semwait_signal.s b/libc/sysv/calls/__semwait_signal.s new file mode 100644 index 00000000..783ababb --- /dev/null +++ b/libc/sysv/calls/__semwait_signal.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __semwait_signal 0xffffffff214effff globl diff --git a/libc/sysv/calls/__semwait_signal_nocancel.s b/libc/sysv/calls/__semwait_signal_nocancel.s new file mode 100644 index 00000000..4fb43ceb --- /dev/null +++ b/libc/sysv/calls/__semwait_signal_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __semwait_signal_nocancel 0xffffffff21a7ffff globl diff --git a/libc/sysv/calls/__set_tcb.s b/libc/sysv/calls/__set_tcb.s new file mode 100644 index 00000000..51ceeaba --- /dev/null +++ b/libc/sysv/calls/__set_tcb.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __set_tcb 0x0149ffffffffffff globl diff --git a/libc/sysv/calls/__setegid-bsd.s b/libc/sysv/calls/__setegid-bsd.s new file mode 100644 index 00000000..014087d3 --- /dev/null +++ b/libc/sysv/calls/__setegid-bsd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __setegid$bsd 0x00b600b620b6ffff globl hidden diff --git a/libc/sysv/calls/__seteuid-bsd.s b/libc/sysv/calls/__seteuid-bsd.s new file mode 100644 index 00000000..5efa0976 --- /dev/null +++ b/libc/sysv/calls/__seteuid-bsd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __seteuid$bsd 0x00b700b720b7ffff globl hidden diff --git a/libc/sysv/calls/__setugid.s b/libc/sysv/calls/__setugid.s new file mode 100644 index 00000000..42eda081 --- /dev/null +++ b/libc/sysv/calls/__setugid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __setugid 0xffff0176ffffffff globl diff --git a/libc/sysv/calls/__sigwait_nocancel.s b/libc/sysv/calls/__sigwait_nocancel.s new file mode 100644 index 00000000..c1e03e34 --- /dev/null +++ b/libc/sysv/calls/__sigwait_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __sigwait_nocancel 0xffffffff21a6ffff globl diff --git a/libc/sysv/calls/__socket-sysv.s b/libc/sysv/calls/__socket-sysv.s new file mode 100644 index 00000000..f1356256 --- /dev/null +++ b/libc/sysv/calls/__socket-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __socket$sysv 0x0061006120610029 globl hidden diff --git a/libc/sysv/calls/__stat-sysv.s b/libc/sysv/calls/__stat-sysv.s new file mode 100644 index 00000000..ff1415ae --- /dev/null +++ b/libc/sysv/calls/__stat-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __stat$sysv 0x0026ffff21520004 globl hidden diff --git a/libc/sysv/calls/__syscall.s b/libc/sysv/calls/__syscall.s new file mode 100644 index 00000000..050d13c8 --- /dev/null +++ b/libc/sysv/calls/__syscall.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __syscall 0x00c6ffffffffffff globl diff --git a/libc/sysv/calls/__sysctl.s b/libc/sysv/calls/__sysctl.s new file mode 100644 index 00000000..eca78a8e --- /dev/null +++ b/libc/sysv/calls/__sysctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __sysctl 0xffff00caffffffff globl diff --git a/libc/sysv/calls/__tfork.s b/libc/sysv/calls/__tfork.s new file mode 100644 index 00000000..df70f349 --- /dev/null +++ b/libc/sysv/calls/__tfork.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __tfork 0x0008ffffffffffff globl diff --git a/libc/sysv/calls/__threxit.s b/libc/sysv/calls/__threxit.s new file mode 100644 index 00000000..332c8e95 --- /dev/null +++ b/libc/sysv/calls/__threxit.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __threxit 0x012effffffffffff globl diff --git a/libc/sysv/calls/__thrsigdivert.s b/libc/sysv/calls/__thrsigdivert.s new file mode 100644 index 00000000..23bd5a13 --- /dev/null +++ b/libc/sysv/calls/__thrsigdivert.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __thrsigdivert 0x012fffffffffffff globl diff --git a/libc/sysv/calls/__thrsleep.s b/libc/sysv/calls/__thrsleep.s new file mode 100644 index 00000000..af5718b2 --- /dev/null +++ b/libc/sysv/calls/__thrsleep.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __thrsleep 0x005effffffffffff globl diff --git a/libc/sysv/calls/__thrwakeup.s b/libc/sysv/calls/__thrwakeup.s new file mode 100644 index 00000000..4c04d6a7 --- /dev/null +++ b/libc/sysv/calls/__thrwakeup.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __thrwakeup 0x012dffffffffffff globl diff --git a/libc/sysv/calls/__truncate-sysv.s b/libc/sysv/calls/__truncate-sysv.s new file mode 100644 index 00000000..341c8923 --- /dev/null +++ b/libc/sysv/calls/__truncate-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall __truncate$sysv 0x00c801df20c8004c globl hidden diff --git a/libc/sysv/calls/_sysctl.s b/libc/sysv/calls/_sysctl.s new file mode 100644 index 00000000..af01f739 --- /dev/null +++ b/libc/sysv/calls/_sysctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _sysctl 0xffffffffffff009c globl diff --git a/libc/sysv/calls/_umtx_op.s b/libc/sysv/calls/_umtx_op.s new file mode 100644 index 00000000..dc6e0f3c --- /dev/null +++ b/libc/sysv/calls/_umtx_op.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _umtx_op 0xffff01c6ffffffff globl diff --git a/libc/sysv/calls/abort2.s b/libc/sysv/calls/abort2.s new file mode 100644 index 00000000..96c9dab6 --- /dev/null +++ b/libc/sysv/calls/abort2.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall abort2 0xffff01cfffffffff globl diff --git a/libc/sysv/calls/abort_with_payload.s b/libc/sysv/calls/abort_with_payload.s new file mode 100644 index 00000000..4c80db5a --- /dev/null +++ b/libc/sysv/calls/abort_with_payload.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall abort_with_payload 0xffffffff2209ffff globl diff --git a/libc/sysv/calls/accept_nocancel.s b/libc/sysv/calls/accept_nocancel.s new file mode 100644 index 00000000..bd6d72d5 --- /dev/null +++ b/libc/sysv/calls/accept_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall accept_nocancel 0xffffffff2194ffff globl diff --git a/libc/sysv/calls/access-sysv.s b/libc/sysv/calls/access-sysv.s new file mode 100644 index 00000000..84c72491 --- /dev/null +++ b/libc/sysv/calls/access-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall access$sysv 0x0021002120210015 globl hidden diff --git a/libc/sysv/calls/access_extended.s b/libc/sysv/calls/access_extended.s new file mode 100644 index 00000000..2cf2a0e5 --- /dev/null +++ b/libc/sysv/calls/access_extended.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall access_extended 0xffffffff211cffff globl diff --git a/libc/sysv/calls/acct.s b/libc/sysv/calls/acct.s new file mode 100644 index 00000000..247a22ce --- /dev/null +++ b/libc/sysv/calls/acct.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall acct 0x00330033203300a3 globl diff --git a/libc/sysv/calls/add_key.s b/libc/sysv/calls/add_key.s new file mode 100644 index 00000000..6574ac2d --- /dev/null +++ b/libc/sysv/calls/add_key.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall add_key 0xffffffffffff00f8 globl diff --git a/libc/sysv/calls/adjfreq.s b/libc/sysv/calls/adjfreq.s new file mode 100644 index 00000000..bb0118c1 --- /dev/null +++ b/libc/sysv/calls/adjfreq.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall adjfreq 0x0131ffffffffffff globl diff --git a/libc/sysv/calls/adjtime.s b/libc/sysv/calls/adjtime.s new file mode 100644 index 00000000..ed960d1a --- /dev/null +++ b/libc/sysv/calls/adjtime.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall adjtime 0x008c008c208cffff globl diff --git a/libc/sysv/calls/adjtimex.s b/libc/sysv/calls/adjtimex.s new file mode 100644 index 00000000..fba3c64b --- /dev/null +++ b/libc/sysv/calls/adjtimex.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall adjtimex 0xffffffffffff009f globl diff --git a/libc/sysv/calls/afs3_syscall.s b/libc/sysv/calls/afs3_syscall.s new file mode 100644 index 00000000..eca0e4b1 --- /dev/null +++ b/libc/sysv/calls/afs3_syscall.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall afs3_syscall 0xffff0179ffffffff globl diff --git a/libc/sysv/calls/aio_cancel.s b/libc/sysv/calls/aio_cancel.s new file mode 100644 index 00000000..c2da242e --- /dev/null +++ b/libc/sysv/calls/aio_cancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall aio_cancel 0xffff013c213cffff globl diff --git a/libc/sysv/calls/aio_error.s b/libc/sysv/calls/aio_error.s new file mode 100644 index 00000000..029d06b0 --- /dev/null +++ b/libc/sysv/calls/aio_error.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall aio_error 0xffff013d213dffff globl diff --git a/libc/sysv/calls/aio_fsync.s b/libc/sysv/calls/aio_fsync.s new file mode 100644 index 00000000..16b632b0 --- /dev/null +++ b/libc/sysv/calls/aio_fsync.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall aio_fsync 0xffff01d12139ffff globl diff --git a/libc/sysv/calls/aio_mlock.s b/libc/sysv/calls/aio_mlock.s new file mode 100644 index 00000000..6e97ca05 --- /dev/null +++ b/libc/sysv/calls/aio_mlock.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall aio_mlock 0xffff021fffffffff globl diff --git a/libc/sysv/calls/aio_read.s b/libc/sysv/calls/aio_read.s new file mode 100644 index 00000000..e29d91c8 --- /dev/null +++ b/libc/sysv/calls/aio_read.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall aio_read 0xffff013e213effff globl diff --git a/libc/sysv/calls/aio_return.s b/libc/sysv/calls/aio_return.s new file mode 100644 index 00000000..3ae0dc72 --- /dev/null +++ b/libc/sysv/calls/aio_return.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall aio_return 0xffff013a213affff globl diff --git a/libc/sysv/calls/aio_suspend.s b/libc/sysv/calls/aio_suspend.s new file mode 100644 index 00000000..20b1c17b --- /dev/null +++ b/libc/sysv/calls/aio_suspend.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall aio_suspend 0xffff013b213bffff globl diff --git a/libc/sysv/calls/aio_suspend_nocancel.s b/libc/sysv/calls/aio_suspend_nocancel.s new file mode 100644 index 00000000..992ca014 --- /dev/null +++ b/libc/sysv/calls/aio_suspend_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall aio_suspend_nocancel 0xffffffff21a5ffff globl diff --git a/libc/sysv/calls/aio_waitcomplete.s b/libc/sysv/calls/aio_waitcomplete.s new file mode 100644 index 00000000..bcecf718 --- /dev/null +++ b/libc/sysv/calls/aio_waitcomplete.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall aio_waitcomplete 0xffff0167ffffffff globl diff --git a/libc/sysv/calls/aio_write.s b/libc/sysv/calls/aio_write.s new file mode 100644 index 00000000..a1529bd6 --- /dev/null +++ b/libc/sysv/calls/aio_write.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall aio_write 0xffff013f213fffff globl diff --git a/libc/sysv/calls/alarm-sysv.s b/libc/sysv/calls/alarm-sysv.s new file mode 100644 index 00000000..81a4805c --- /dev/null +++ b/libc/sysv/calls/alarm-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall alarm$sysv 0xffffffffffff0025 globl hidden diff --git a/libc/sysv/calls/arch_prctl-sysv.s b/libc/sysv/calls/arch_prctl-sysv.s new file mode 100644 index 00000000..0c67bb32 --- /dev/null +++ b/libc/sysv/calls/arch_prctl-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall arch_prctl$sysv 0x00a500a5ffff009e globl hidden diff --git a/libc/sysv/calls/audit.s b/libc/sysv/calls/audit.s new file mode 100644 index 00000000..34a08ee4 --- /dev/null +++ b/libc/sysv/calls/audit.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall audit 0xffff01bd215effff globl diff --git a/libc/sysv/calls/audit_session_join.s b/libc/sysv/calls/audit_session_join.s new file mode 100644 index 00000000..64e35f12 --- /dev/null +++ b/libc/sysv/calls/audit_session_join.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall audit_session_join 0xffffffff21adffff globl diff --git a/libc/sysv/calls/audit_session_port.s b/libc/sysv/calls/audit_session_port.s new file mode 100644 index 00000000..3a230240 --- /dev/null +++ b/libc/sysv/calls/audit_session_port.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall audit_session_port 0xffffffff21b0ffff globl diff --git a/libc/sysv/calls/audit_session_self.s b/libc/sysv/calls/audit_session_self.s new file mode 100644 index 00000000..4f2337aa --- /dev/null +++ b/libc/sysv/calls/audit_session_self.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall audit_session_self 0xffffffff21acffff globl diff --git a/libc/sysv/calls/auditctl.s b/libc/sysv/calls/auditctl.s new file mode 100644 index 00000000..d1897331 --- /dev/null +++ b/libc/sysv/calls/auditctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall auditctl 0xffff01c52167ffff globl diff --git a/libc/sysv/calls/auditon.s b/libc/sysv/calls/auditon.s new file mode 100644 index 00000000..b0b37a48 --- /dev/null +++ b/libc/sysv/calls/auditon.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall auditon 0xffff01be215fffff globl diff --git a/libc/sysv/calls/bind-sysv.s b/libc/sysv/calls/bind-sysv.s new file mode 100644 index 00000000..bea10dfa --- /dev/null +++ b/libc/sysv/calls/bind-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall bind$sysv 0x0068006820680031 globl hidden diff --git a/libc/sysv/calls/bindat.s b/libc/sysv/calls/bindat.s new file mode 100644 index 00000000..cf5842a4 --- /dev/null +++ b/libc/sysv/calls/bindat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall bindat 0xffff021affffffff globl diff --git a/libc/sysv/calls/bpf.s b/libc/sysv/calls/bpf.s new file mode 100644 index 00000000..690f3f3f --- /dev/null +++ b/libc/sysv/calls/bpf.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall bpf 0xffffffffffff0141 globl diff --git a/libc/sysv/calls/break.s b/libc/sysv/calls/break.s new file mode 100644 index 00000000..8007c78a --- /dev/null +++ b/libc/sysv/calls/break.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall break 0xffff0011ffffffff globl diff --git a/libc/sysv/calls/bsdthread_create.s b/libc/sysv/calls/bsdthread_create.s new file mode 100644 index 00000000..1177e5ea --- /dev/null +++ b/libc/sysv/calls/bsdthread_create.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall bsdthread_create 0xffffffff2168ffff globl diff --git a/libc/sysv/calls/bsdthread_ctl.s b/libc/sysv/calls/bsdthread_ctl.s new file mode 100644 index 00000000..db13b0dc --- /dev/null +++ b/libc/sysv/calls/bsdthread_ctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall bsdthread_ctl 0xffffffff21deffff globl diff --git a/libc/sysv/calls/bsdthread_register.s b/libc/sysv/calls/bsdthread_register.s new file mode 100644 index 00000000..910c6965 --- /dev/null +++ b/libc/sysv/calls/bsdthread_register.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall bsdthread_register 0xffffffff216effff globl diff --git a/libc/sysv/calls/bsdthread_terminate.s b/libc/sysv/calls/bsdthread_terminate.s new file mode 100644 index 00000000..4ed60b23 --- /dev/null +++ b/libc/sysv/calls/bsdthread_terminate.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall bsdthread_terminate 0xffffffff2169ffff globl diff --git a/libc/sysv/calls/cap_enter.s b/libc/sysv/calls/cap_enter.s new file mode 100644 index 00000000..a79d380e --- /dev/null +++ b/libc/sysv/calls/cap_enter.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall cap_enter 0xffff0204ffffffff globl diff --git a/libc/sysv/calls/cap_fcntls_get.s b/libc/sysv/calls/cap_fcntls_get.s new file mode 100644 index 00000000..3b08dd76 --- /dev/null +++ b/libc/sysv/calls/cap_fcntls_get.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall cap_fcntls_get 0xffff0219ffffffff globl diff --git a/libc/sysv/calls/cap_fcntls_limit.s b/libc/sysv/calls/cap_fcntls_limit.s new file mode 100644 index 00000000..5df406f4 --- /dev/null +++ b/libc/sysv/calls/cap_fcntls_limit.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall cap_fcntls_limit 0xffff0218ffffffff globl diff --git a/libc/sysv/calls/cap_getmode.s b/libc/sysv/calls/cap_getmode.s new file mode 100644 index 00000000..0f0cdc6b --- /dev/null +++ b/libc/sysv/calls/cap_getmode.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall cap_getmode 0xffff0205ffffffff globl diff --git a/libc/sysv/calls/cap_ioctls_get.s b/libc/sysv/calls/cap_ioctls_get.s new file mode 100644 index 00000000..f9c51a07 --- /dev/null +++ b/libc/sysv/calls/cap_ioctls_get.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall cap_ioctls_get 0xffff0217ffffffff globl diff --git a/libc/sysv/calls/cap_ioctls_limit.s b/libc/sysv/calls/cap_ioctls_limit.s new file mode 100644 index 00000000..94eea939 --- /dev/null +++ b/libc/sysv/calls/cap_ioctls_limit.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall cap_ioctls_limit 0xffff0216ffffffff globl diff --git a/libc/sysv/calls/cap_rights_limit.s b/libc/sysv/calls/cap_rights_limit.s new file mode 100644 index 00000000..fbc21bd4 --- /dev/null +++ b/libc/sysv/calls/cap_rights_limit.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall cap_rights_limit 0xffff0215ffffffff globl diff --git a/libc/sysv/calls/capget.s b/libc/sysv/calls/capget.s new file mode 100644 index 00000000..90cf90ed --- /dev/null +++ b/libc/sysv/calls/capget.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall capget 0xffffffffffff007d globl diff --git a/libc/sysv/calls/capset.s b/libc/sysv/calls/capset.s new file mode 100644 index 00000000..3d6303b0 --- /dev/null +++ b/libc/sysv/calls/capset.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall capset 0xffffffffffff007e globl diff --git a/libc/sysv/calls/change_fdguard_np.s b/libc/sysv/calls/change_fdguard_np.s new file mode 100644 index 00000000..ba4427b6 --- /dev/null +++ b/libc/sysv/calls/change_fdguard_np.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall change_fdguard_np 0xffffffff21bcffff globl diff --git a/libc/sysv/calls/chdir-sysv.s b/libc/sysv/calls/chdir-sysv.s new file mode 100644 index 00000000..aa7a801f --- /dev/null +++ b/libc/sysv/calls/chdir-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall chdir$sysv 0x000c000c200c0050 globl hidden diff --git a/libc/sysv/calls/chflags.s b/libc/sysv/calls/chflags.s new file mode 100644 index 00000000..bfef77cc --- /dev/null +++ b/libc/sysv/calls/chflags.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall chflags 0x002200222022ffff globl diff --git a/libc/sysv/calls/chflagsat.s b/libc/sysv/calls/chflagsat.s new file mode 100644 index 00000000..a37a00bb --- /dev/null +++ b/libc/sysv/calls/chflagsat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall chflagsat 0x006b021cffffffff globl diff --git a/libc/sysv/calls/chmod-sysv.s b/libc/sysv/calls/chmod-sysv.s new file mode 100644 index 00000000..35e562a6 --- /dev/null +++ b/libc/sysv/calls/chmod-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall chmod$sysv 0x000f000f200f005a globl hidden diff --git a/libc/sysv/calls/chmod_extended.s b/libc/sysv/calls/chmod_extended.s new file mode 100644 index 00000000..c55fcd44 --- /dev/null +++ b/libc/sysv/calls/chmod_extended.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall chmod_extended 0xffffffff211affff globl diff --git a/libc/sysv/calls/chown-sysv.s b/libc/sysv/calls/chown-sysv.s new file mode 100644 index 00000000..150d37e5 --- /dev/null +++ b/libc/sysv/calls/chown-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall chown$sysv 0x001000102010005c globl hidden diff --git a/libc/sysv/calls/chroot.s b/libc/sysv/calls/chroot.s new file mode 100644 index 00000000..e7970f20 --- /dev/null +++ b/libc/sysv/calls/chroot.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall chroot 0x003d003d203d00a1 globl diff --git a/libc/sysv/calls/clock_adjtime.s b/libc/sysv/calls/clock_adjtime.s new file mode 100644 index 00000000..3218bf00 --- /dev/null +++ b/libc/sysv/calls/clock_adjtime.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall clock_adjtime 0xffffffffffff0131 globl diff --git a/libc/sysv/calls/clock_getcpuclockid2.s b/libc/sysv/calls/clock_getcpuclockid2.s new file mode 100644 index 00000000..c823a4d5 --- /dev/null +++ b/libc/sysv/calls/clock_getcpuclockid2.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall clock_getcpuclockid2 0xffff00f7ffffffff globl diff --git a/libc/sysv/calls/clock_getres.s b/libc/sysv/calls/clock_getres.s new file mode 100644 index 00000000..361536d8 --- /dev/null +++ b/libc/sysv/calls/clock_getres.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall clock_getres 0x005900eaffff00e5 globl diff --git a/libc/sysv/calls/clock_gettime-sysv.s b/libc/sysv/calls/clock_gettime-sysv.s new file mode 100644 index 00000000..bfbe894c --- /dev/null +++ b/libc/sysv/calls/clock_gettime-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall clock_gettime$sysv 0x005700e8ffff00e4 globl hidden diff --git a/libc/sysv/calls/clock_nanosleep.s b/libc/sysv/calls/clock_nanosleep.s new file mode 100644 index 00000000..c046bfa9 --- /dev/null +++ b/libc/sysv/calls/clock_nanosleep.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall clock_nanosleep 0xffff00f4ffff00e6 globl diff --git a/libc/sysv/calls/clock_settime.s b/libc/sysv/calls/clock_settime.s new file mode 100644 index 00000000..9942418d --- /dev/null +++ b/libc/sysv/calls/clock_settime.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall clock_settime 0x005800e9ffff00e3 globl diff --git a/libc/sysv/calls/clone.s b/libc/sysv/calls/clone.s new file mode 100644 index 00000000..cafc75ed --- /dev/null +++ b/libc/sysv/calls/clone.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall clone 0xffffffffffff0038 globl diff --git a/libc/sysv/calls/clonefileat.s b/libc/sysv/calls/clonefileat.s new file mode 100644 index 00000000..98c42955 --- /dev/null +++ b/libc/sysv/calls/clonefileat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall clonefileat 0xffffffff21ceffff globl diff --git a/libc/sysv/calls/close-sysv.s b/libc/sysv/calls/close-sysv.s new file mode 100644 index 00000000..387b8fec --- /dev/null +++ b/libc/sysv/calls/close-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall close$sysv 0x0006000620060003 globl hidden diff --git a/libc/sysv/calls/close_nocancel.s b/libc/sysv/calls/close_nocancel.s new file mode 100644 index 00000000..87d36d5c --- /dev/null +++ b/libc/sysv/calls/close_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall close_nocancel 0xffffffff218fffff globl diff --git a/libc/sysv/calls/closefrom.s b/libc/sysv/calls/closefrom.s new file mode 100644 index 00000000..72945ed0 --- /dev/null +++ b/libc/sysv/calls/closefrom.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall closefrom 0x011f01fdffffffff globl diff --git a/libc/sysv/calls/coalition.s b/libc/sysv/calls/coalition.s new file mode 100644 index 00000000..c27ba670 --- /dev/null +++ b/libc/sysv/calls/coalition.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall coalition 0xffffffff21caffff globl diff --git a/libc/sysv/calls/coalition_info.s b/libc/sysv/calls/coalition_info.s new file mode 100644 index 00000000..01028766 --- /dev/null +++ b/libc/sysv/calls/coalition_info.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall coalition_info 0xffffffff21cbffff globl diff --git a/libc/sysv/calls/connect_nocancel.s b/libc/sysv/calls/connect_nocancel.s new file mode 100644 index 00000000..a6613130 --- /dev/null +++ b/libc/sysv/calls/connect_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall connect_nocancel 0xffffffff2199ffff globl diff --git a/libc/sysv/calls/connectat.s b/libc/sysv/calls/connectat.s new file mode 100644 index 00000000..3a01db0b --- /dev/null +++ b/libc/sysv/calls/connectat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall connectat 0xffff021bffffffff globl diff --git a/libc/sysv/calls/connectx.s b/libc/sysv/calls/connectx.s new file mode 100644 index 00000000..3fdf83f3 --- /dev/null +++ b/libc/sysv/calls/connectx.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall connectx 0xffffffff21bfffff globl diff --git a/libc/sysv/calls/copy_file_range-sysv.s b/libc/sysv/calls/copy_file_range-sysv.s new file mode 100644 index 00000000..8bd1d64a --- /dev/null +++ b/libc/sysv/calls/copy_file_range-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall copy_file_range$sysv 0xffffffffffff0146 globl hidden diff --git a/libc/sysv/calls/copyfile.s b/libc/sysv/calls/copyfile.s new file mode 100644 index 00000000..a06221ae --- /dev/null +++ b/libc/sysv/calls/copyfile.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall copyfile 0xffffffff20e3ffff globl diff --git a/libc/sysv/calls/cpuset.s b/libc/sysv/calls/cpuset.s new file mode 100644 index 00000000..91882735 --- /dev/null +++ b/libc/sysv/calls/cpuset.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall cpuset 0xffff01e4ffffffff globl diff --git a/libc/sysv/calls/cpuset_getaffinity.s b/libc/sysv/calls/cpuset_getaffinity.s new file mode 100644 index 00000000..5ed22e52 --- /dev/null +++ b/libc/sysv/calls/cpuset_getaffinity.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall cpuset_getaffinity 0xffff01e7ffffffff globl diff --git a/libc/sysv/calls/cpuset_getdomain.s b/libc/sysv/calls/cpuset_getdomain.s new file mode 100644 index 00000000..727faebc --- /dev/null +++ b/libc/sysv/calls/cpuset_getdomain.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall cpuset_getdomain 0xffff0231ffffffff globl diff --git a/libc/sysv/calls/cpuset_getid.s b/libc/sysv/calls/cpuset_getid.s new file mode 100644 index 00000000..500b338c --- /dev/null +++ b/libc/sysv/calls/cpuset_getid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall cpuset_getid 0xffff01e6ffffffff globl diff --git a/libc/sysv/calls/cpuset_setaffinity.s b/libc/sysv/calls/cpuset_setaffinity.s new file mode 100644 index 00000000..9c880a50 --- /dev/null +++ b/libc/sysv/calls/cpuset_setaffinity.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall cpuset_setaffinity 0xffff01e8ffffffff globl diff --git a/libc/sysv/calls/cpuset_setdomain.s b/libc/sysv/calls/cpuset_setdomain.s new file mode 100644 index 00000000..30dfc0bd --- /dev/null +++ b/libc/sysv/calls/cpuset_setdomain.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall cpuset_setdomain 0xffff0232ffffffff globl diff --git a/libc/sysv/calls/cpuset_setid.s b/libc/sysv/calls/cpuset_setid.s new file mode 100644 index 00000000..4ee0d87e --- /dev/null +++ b/libc/sysv/calls/cpuset_setid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall cpuset_setid 0xffff01e5ffffffff globl diff --git a/libc/sysv/calls/creat-sysv.s b/libc/sysv/calls/creat-sysv.s new file mode 100644 index 00000000..c781bd8b --- /dev/null +++ b/libc/sysv/calls/creat-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall creat$sysv 0xffff0008ffff0055 globl hidden diff --git a/libc/sysv/calls/csops.s b/libc/sysv/calls/csops.s new file mode 100644 index 00000000..1c52051a --- /dev/null +++ b/libc/sysv/calls/csops.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall csops 0xffffffff20a9ffff globl diff --git a/libc/sysv/calls/csops_audittoken.s b/libc/sysv/calls/csops_audittoken.s new file mode 100644 index 00000000..b53f3323 --- /dev/null +++ b/libc/sysv/calls/csops_audittoken.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall csops_audittoken 0xffffffff20aaffff globl diff --git a/libc/sysv/calls/csrctl.s b/libc/sysv/calls/csrctl.s new file mode 100644 index 00000000..727f6463 --- /dev/null +++ b/libc/sysv/calls/csrctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall csrctl 0xffffffff21e3ffff globl diff --git a/libc/sysv/calls/delete.s b/libc/sysv/calls/delete.s new file mode 100644 index 00000000..04c2a3db --- /dev/null +++ b/libc/sysv/calls/delete.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall delete 0xffffffff20e2ffff globl diff --git a/libc/sysv/calls/delete_module.s b/libc/sysv/calls/delete_module.s new file mode 100644 index 00000000..8468bb7a --- /dev/null +++ b/libc/sysv/calls/delete_module.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall delete_module 0xffffffffffff00b0 globl diff --git a/libc/sysv/calls/disconnectx.s b/libc/sysv/calls/disconnectx.s new file mode 100644 index 00000000..80164d9b --- /dev/null +++ b/libc/sysv/calls/disconnectx.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall disconnectx 0xffffffff21c0ffff globl diff --git a/libc/sysv/calls/dup-sysv.s b/libc/sysv/calls/dup-sysv.s new file mode 100644 index 00000000..2cd1b046 --- /dev/null +++ b/libc/sysv/calls/dup-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall dup$sysv 0x0029002920290020 globl hidden diff --git a/libc/sysv/calls/dup2-sysv.s b/libc/sysv/calls/dup2-sysv.s new file mode 100644 index 00000000..6e96ba4e --- /dev/null +++ b/libc/sysv/calls/dup2-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall dup2$sysv 0x005a005a205a0021 globl hidden diff --git a/libc/sysv/calls/eaccess.s b/libc/sysv/calls/eaccess.s new file mode 100644 index 00000000..c4d7f3ce --- /dev/null +++ b/libc/sysv/calls/eaccess.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall eaccess 0xffff0178ffffffff globl diff --git a/libc/sysv/calls/epoll_create.s b/libc/sysv/calls/epoll_create.s new file mode 100644 index 00000000..b2360a0c --- /dev/null +++ b/libc/sysv/calls/epoll_create.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall epoll_create 0xffffffffffff00d5 globl diff --git a/libc/sysv/calls/epoll_create1.s b/libc/sysv/calls/epoll_create1.s new file mode 100644 index 00000000..10949f86 --- /dev/null +++ b/libc/sysv/calls/epoll_create1.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall epoll_create1 0xffffffffffff0123 globl diff --git a/libc/sysv/calls/epoll_ctl.s b/libc/sysv/calls/epoll_ctl.s new file mode 100644 index 00000000..905e1bbd --- /dev/null +++ b/libc/sysv/calls/epoll_ctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall epoll_ctl 0xffffffffffff00e9 globl diff --git a/libc/sysv/calls/epoll_pwait.s b/libc/sysv/calls/epoll_pwait.s new file mode 100644 index 00000000..9bd9ca86 --- /dev/null +++ b/libc/sysv/calls/epoll_pwait.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall epoll_pwait 0xffffffffffff0119 globl diff --git a/libc/sysv/calls/epoll_wait.s b/libc/sysv/calls/epoll_wait.s new file mode 100644 index 00000000..7863fee5 --- /dev/null +++ b/libc/sysv/calls/epoll_wait.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall epoll_wait 0xffffffffffff00e8 globl diff --git a/libc/sysv/calls/eventfd.s b/libc/sysv/calls/eventfd.s new file mode 100644 index 00000000..7ef19342 --- /dev/null +++ b/libc/sysv/calls/eventfd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall eventfd 0xffffffffffff011c globl diff --git a/libc/sysv/calls/eventfd2.s b/libc/sysv/calls/eventfd2.s new file mode 100644 index 00000000..df0ed9d8 --- /dev/null +++ b/libc/sysv/calls/eventfd2.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall eventfd2 0xffffffffffff0122 globl diff --git a/libc/sysv/calls/exchangedata.s b/libc/sysv/calls/exchangedata.s new file mode 100644 index 00000000..84e89a42 --- /dev/null +++ b/libc/sysv/calls/exchangedata.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall exchangedata 0xffffffff20dfffff globl diff --git a/libc/sysv/calls/execve-sysv.s b/libc/sysv/calls/execve-sysv.s new file mode 100644 index 00000000..98b73a5f --- /dev/null +++ b/libc/sysv/calls/execve-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall execve$sysv 0x003b003b203b003b globl hidden diff --git a/libc/sysv/calls/execveat.s b/libc/sysv/calls/execveat.s new file mode 100644 index 00000000..46d589b4 --- /dev/null +++ b/libc/sysv/calls/execveat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall execveat 0xffffffffffff0142 globl diff --git a/libc/sysv/calls/exit-sysv.s b/libc/sysv/calls/exit-sysv.s new file mode 100644 index 00000000..39c845a1 --- /dev/null +++ b/libc/sysv/calls/exit-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall exit$sysv 0x00010001200100e7 globl hidden diff --git a/libc/sysv/calls/extattr_delete_fd.s b/libc/sysv/calls/extattr_delete_fd.s new file mode 100644 index 00000000..5f3f13c7 --- /dev/null +++ b/libc/sysv/calls/extattr_delete_fd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall extattr_delete_fd 0xffff0175ffffffff globl diff --git a/libc/sysv/calls/extattr_delete_file.s b/libc/sysv/calls/extattr_delete_file.s new file mode 100644 index 00000000..9d725cc3 --- /dev/null +++ b/libc/sysv/calls/extattr_delete_file.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall extattr_delete_file 0xffff0166ffffffff globl diff --git a/libc/sysv/calls/extattr_delete_link.s b/libc/sysv/calls/extattr_delete_link.s new file mode 100644 index 00000000..063cd29c --- /dev/null +++ b/libc/sysv/calls/extattr_delete_link.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall extattr_delete_link 0xffff019effffffff globl diff --git a/libc/sysv/calls/extattr_get_fd.s b/libc/sysv/calls/extattr_get_fd.s new file mode 100644 index 00000000..87ce786f --- /dev/null +++ b/libc/sysv/calls/extattr_get_fd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall extattr_get_fd 0xffff0174ffffffff globl diff --git a/libc/sysv/calls/extattr_get_file.s b/libc/sysv/calls/extattr_get_file.s new file mode 100644 index 00000000..06cfeecb --- /dev/null +++ b/libc/sysv/calls/extattr_get_file.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall extattr_get_file 0xffff0165ffffffff globl diff --git a/libc/sysv/calls/extattr_get_link.s b/libc/sysv/calls/extattr_get_link.s new file mode 100644 index 00000000..8dcbe1ce --- /dev/null +++ b/libc/sysv/calls/extattr_get_link.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall extattr_get_link 0xffff019dffffffff globl diff --git a/libc/sysv/calls/extattr_list_fd.s b/libc/sysv/calls/extattr_list_fd.s new file mode 100644 index 00000000..b337bbbf --- /dev/null +++ b/libc/sysv/calls/extattr_list_fd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall extattr_list_fd 0xffff01b5ffffffff globl diff --git a/libc/sysv/calls/extattr_list_file.s b/libc/sysv/calls/extattr_list_file.s new file mode 100644 index 00000000..c9ce6112 --- /dev/null +++ b/libc/sysv/calls/extattr_list_file.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall extattr_list_file 0xffff01b6ffffffff globl diff --git a/libc/sysv/calls/extattr_list_link.s b/libc/sysv/calls/extattr_list_link.s new file mode 100644 index 00000000..07a0ef68 --- /dev/null +++ b/libc/sysv/calls/extattr_list_link.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall extattr_list_link 0xffff01b7ffffffff globl diff --git a/libc/sysv/calls/extattr_set_fd.s b/libc/sysv/calls/extattr_set_fd.s new file mode 100644 index 00000000..adad82ba --- /dev/null +++ b/libc/sysv/calls/extattr_set_fd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall extattr_set_fd 0xffff0173ffffffff globl diff --git a/libc/sysv/calls/extattr_set_file.s b/libc/sysv/calls/extattr_set_file.s new file mode 100644 index 00000000..e981a189 --- /dev/null +++ b/libc/sysv/calls/extattr_set_file.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall extattr_set_file 0xffff0164ffffffff globl diff --git a/libc/sysv/calls/extattr_set_link.s b/libc/sysv/calls/extattr_set_link.s new file mode 100644 index 00000000..d262d975 --- /dev/null +++ b/libc/sysv/calls/extattr_set_link.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall extattr_set_link 0xffff019cffffffff globl diff --git a/libc/sysv/calls/extattrctl.s b/libc/sysv/calls/extattrctl.s new file mode 100644 index 00000000..bd1db1fe --- /dev/null +++ b/libc/sysv/calls/extattrctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall extattrctl 0xffff0163ffffffff globl diff --git a/libc/sysv/calls/faccessat-sysv.s b/libc/sysv/calls/faccessat-sysv.s new file mode 100644 index 00000000..7b221073 --- /dev/null +++ b/libc/sysv/calls/faccessat-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall faccessat$sysv 0x013901e921d2010d globl hidden diff --git a/libc/sysv/calls/fadvise-sysv.s b/libc/sysv/calls/fadvise-sysv.s new file mode 100644 index 00000000..e9ed00f0 --- /dev/null +++ b/libc/sysv/calls/fadvise-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fadvise$sysv 0xffff0213ffff00dd globl hidden diff --git a/libc/sysv/calls/fallocate-sysv.s b/libc/sysv/calls/fallocate-sysv.s new file mode 100644 index 00000000..924e0324 --- /dev/null +++ b/libc/sysv/calls/fallocate-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fallocate$sysv 0xffffffffffff011d globl hidden diff --git a/libc/sysv/calls/fanotify_init.s b/libc/sysv/calls/fanotify_init.s new file mode 100644 index 00000000..c5e4f3b6 --- /dev/null +++ b/libc/sysv/calls/fanotify_init.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fanotify_init 0xffffffffffff012c globl diff --git a/libc/sysv/calls/fanotify_mark.s b/libc/sysv/calls/fanotify_mark.s new file mode 100644 index 00000000..ddfdedcb --- /dev/null +++ b/libc/sysv/calls/fanotify_mark.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fanotify_mark 0xffffffffffff012d globl diff --git a/libc/sysv/calls/fchdir.s b/libc/sysv/calls/fchdir.s new file mode 100644 index 00000000..9c6ccf31 --- /dev/null +++ b/libc/sysv/calls/fchdir.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fchdir 0x000d000d200d0051 globl diff --git a/libc/sysv/calls/fchflags.s b/libc/sysv/calls/fchflags.s new file mode 100644 index 00000000..890d81bb --- /dev/null +++ b/libc/sysv/calls/fchflags.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fchflags 0x002300232023ffff globl diff --git a/libc/sysv/calls/fchmod-sysv.s b/libc/sysv/calls/fchmod-sysv.s new file mode 100644 index 00000000..7c331a19 --- /dev/null +++ b/libc/sysv/calls/fchmod-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fchmod$sysv 0x007c007c207c005b globl hidden diff --git a/libc/sysv/calls/fchmod_extended.s b/libc/sysv/calls/fchmod_extended.s new file mode 100644 index 00000000..fa77ebcf --- /dev/null +++ b/libc/sysv/calls/fchmod_extended.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fchmod_extended 0xffffffff211bffff globl diff --git a/libc/sysv/calls/fchmodat-sysv.s b/libc/sysv/calls/fchmodat-sysv.s new file mode 100644 index 00000000..d16551a9 --- /dev/null +++ b/libc/sysv/calls/fchmodat-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fchmodat$sysv 0x013a01ea21d3010c globl hidden diff --git a/libc/sysv/calls/fchown-sysv.s b/libc/sysv/calls/fchown-sysv.s new file mode 100644 index 00000000..6cfbd231 --- /dev/null +++ b/libc/sysv/calls/fchown-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fchown$sysv 0x007b007b207b005d globl hidden diff --git a/libc/sysv/calls/fchownat-sysv.s b/libc/sysv/calls/fchownat-sysv.s new file mode 100644 index 00000000..f437092a --- /dev/null +++ b/libc/sysv/calls/fchownat-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fchownat$sysv 0x013b01eb21d40104 globl hidden diff --git a/libc/sysv/calls/fclonefileat.s b/libc/sysv/calls/fclonefileat.s new file mode 100644 index 00000000..bf451a75 --- /dev/null +++ b/libc/sysv/calls/fclonefileat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fclonefileat 0xffffffff2205ffff globl diff --git a/libc/sysv/calls/fcntl-sysv.s b/libc/sysv/calls/fcntl-sysv.s new file mode 100644 index 00000000..84ed5190 --- /dev/null +++ b/libc/sysv/calls/fcntl-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fcntl$sysv 0x005c005c205c0048 globl hidden diff --git a/libc/sysv/calls/fcntl_nocancel.s b/libc/sysv/calls/fcntl_nocancel.s new file mode 100644 index 00000000..cd37c849 --- /dev/null +++ b/libc/sysv/calls/fcntl_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fcntl_nocancel 0xffffffff2196ffff globl diff --git a/libc/sysv/calls/fdatasync-sysv.s b/libc/sysv/calls/fdatasync-sysv.s new file mode 100644 index 00000000..2f8c6007 --- /dev/null +++ b/libc/sysv/calls/fdatasync-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fdatasync$sysv 0x005f022620bb004b globl hidden diff --git a/libc/sysv/calls/fexecve.s b/libc/sysv/calls/fexecve.s new file mode 100644 index 00000000..8555e037 --- /dev/null +++ b/libc/sysv/calls/fexecve.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fexecve 0xffff01ecffffffff globl diff --git a/libc/sysv/calls/ffclock_getcounter.s b/libc/sysv/calls/ffclock_getcounter.s new file mode 100644 index 00000000..e7442e31 --- /dev/null +++ b/libc/sysv/calls/ffclock_getcounter.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ffclock_getcounter 0xffff00f1ffffffff globl diff --git a/libc/sysv/calls/ffclock_getestimate.s b/libc/sysv/calls/ffclock_getestimate.s new file mode 100644 index 00000000..b56d0d11 --- /dev/null +++ b/libc/sysv/calls/ffclock_getestimate.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ffclock_getestimate 0xffff00f3ffffffff globl diff --git a/libc/sysv/calls/ffclock_setestimate.s b/libc/sysv/calls/ffclock_setestimate.s new file mode 100644 index 00000000..82687834 --- /dev/null +++ b/libc/sysv/calls/ffclock_setestimate.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ffclock_setestimate 0xffff00f2ffffffff globl diff --git a/libc/sysv/calls/ffsctl.s b/libc/sysv/calls/ffsctl.s new file mode 100644 index 00000000..eed80b71 --- /dev/null +++ b/libc/sysv/calls/ffsctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ffsctl 0xffffffff20f5ffff globl diff --git a/libc/sysv/calls/fgetattrlist.s b/libc/sysv/calls/fgetattrlist.s new file mode 100644 index 00000000..b256949d --- /dev/null +++ b/libc/sysv/calls/fgetattrlist.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fgetattrlist 0xffffffff20e4ffff globl diff --git a/libc/sysv/calls/fgetxattr.s b/libc/sysv/calls/fgetxattr.s new file mode 100644 index 00000000..fb70c0ef --- /dev/null +++ b/libc/sysv/calls/fgetxattr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fgetxattr 0xffffffff20eb00c1 globl diff --git a/libc/sysv/calls/fhlink.s b/libc/sysv/calls/fhlink.s new file mode 100644 index 00000000..23e35143 --- /dev/null +++ b/libc/sysv/calls/fhlink.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fhlink 0xffff0235ffffffff globl diff --git a/libc/sysv/calls/fhlinkat.s b/libc/sysv/calls/fhlinkat.s new file mode 100644 index 00000000..759b19c6 --- /dev/null +++ b/libc/sysv/calls/fhlinkat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fhlinkat 0xffff0236ffffffff globl diff --git a/libc/sysv/calls/fhopen.s b/libc/sysv/calls/fhopen.s new file mode 100644 index 00000000..83128f12 --- /dev/null +++ b/libc/sysv/calls/fhopen.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fhopen 0x0108012a20f8ffff globl diff --git a/libc/sysv/calls/fhreadlink.s b/libc/sysv/calls/fhreadlink.s new file mode 100644 index 00000000..0b1d03e7 --- /dev/null +++ b/libc/sysv/calls/fhreadlink.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fhreadlink 0xffff0237ffffffff globl diff --git a/libc/sysv/calls/fhstat.s b/libc/sysv/calls/fhstat.s new file mode 100644 index 00000000..a58a42ff --- /dev/null +++ b/libc/sysv/calls/fhstat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fhstat 0x01260229ffffffff globl diff --git a/libc/sysv/calls/fhstatfs.s b/libc/sysv/calls/fhstatfs.s new file mode 100644 index 00000000..eb77c659 --- /dev/null +++ b/libc/sysv/calls/fhstatfs.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fhstatfs 0x0041022effffffff globl diff --git a/libc/sysv/calls/fileport_makefd.s b/libc/sysv/calls/fileport_makefd.s new file mode 100644 index 00000000..997155eb --- /dev/null +++ b/libc/sysv/calls/fileport_makefd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fileport_makefd 0xffffffff21afffff globl diff --git a/libc/sysv/calls/fileport_makeport.s b/libc/sysv/calls/fileport_makeport.s new file mode 100644 index 00000000..f78f8561 --- /dev/null +++ b/libc/sysv/calls/fileport_makeport.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fileport_makeport 0xffffffff21aeffff globl diff --git a/libc/sysv/calls/finit_module.s b/libc/sysv/calls/finit_module.s new file mode 100644 index 00000000..f8762f47 --- /dev/null +++ b/libc/sysv/calls/finit_module.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall finit_module 0xffffffffffff0139 globl diff --git a/libc/sysv/calls/flistxattr.s b/libc/sysv/calls/flistxattr.s new file mode 100644 index 00000000..a2befa86 --- /dev/null +++ b/libc/sysv/calls/flistxattr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall flistxattr 0xffffffff20f100c4 globl diff --git a/libc/sysv/calls/flock-sysv.s b/libc/sysv/calls/flock-sysv.s new file mode 100644 index 00000000..4ef34530 --- /dev/null +++ b/libc/sysv/calls/flock-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall flock$sysv 0x0083008320830049 globl hidden diff --git a/libc/sysv/calls/fmount.s b/libc/sysv/calls/fmount.s new file mode 100644 index 00000000..de21ac7b --- /dev/null +++ b/libc/sysv/calls/fmount.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fmount 0xffffffff220effff globl diff --git a/libc/sysv/calls/fork-sysv.s b/libc/sysv/calls/fork-sysv.s new file mode 100644 index 00000000..8f2e855b --- /dev/null +++ b/libc/sysv/calls/fork-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fork$sysv 0x0002000220020039 globl hidden diff --git a/libc/sysv/calls/fpathconf.s b/libc/sysv/calls/fpathconf.s new file mode 100644 index 00000000..23f33984 --- /dev/null +++ b/libc/sysv/calls/fpathconf.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fpathconf 0x00c000c020c0ffff globl diff --git a/libc/sysv/calls/fremovexattr.s b/libc/sysv/calls/fremovexattr.s new file mode 100644 index 00000000..39889028 --- /dev/null +++ b/libc/sysv/calls/fremovexattr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fremovexattr 0xffffffff20ef00c7 globl diff --git a/libc/sysv/calls/fs_snapshot.s b/libc/sysv/calls/fs_snapshot.s new file mode 100644 index 00000000..5e10eb17 --- /dev/null +++ b/libc/sysv/calls/fs_snapshot.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fs_snapshot 0xffffffff2206ffff globl diff --git a/libc/sysv/calls/fsctl.s b/libc/sysv/calls/fsctl.s new file mode 100644 index 00000000..569ffc20 --- /dev/null +++ b/libc/sysv/calls/fsctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fsctl 0xffffffff20f2ffff globl diff --git a/libc/sysv/calls/fsetattrlist.s b/libc/sysv/calls/fsetattrlist.s new file mode 100644 index 00000000..bbbfe492 --- /dev/null +++ b/libc/sysv/calls/fsetattrlist.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fsetattrlist 0xffffffff20e5ffff globl diff --git a/libc/sysv/calls/fsetxattr.s b/libc/sysv/calls/fsetxattr.s new file mode 100644 index 00000000..c803d2db --- /dev/null +++ b/libc/sysv/calls/fsetxattr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fsetxattr 0xffffffff20ed00be globl diff --git a/libc/sysv/calls/fstat_extended.s b/libc/sysv/calls/fstat_extended.s new file mode 100644 index 00000000..6a402895 --- /dev/null +++ b/libc/sysv/calls/fstat_extended.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fstat_extended 0xffffffff2119ffff globl diff --git a/libc/sysv/calls/fstatfs.s b/libc/sysv/calls/fstatfs.s new file mode 100644 index 00000000..c5671e5b --- /dev/null +++ b/libc/sysv/calls/fstatfs.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fstatfs 0x0040022c215a008a globl diff --git a/libc/sysv/calls/fsync-sysv.s b/libc/sysv/calls/fsync-sysv.s new file mode 100644 index 00000000..25d6f892 --- /dev/null +++ b/libc/sysv/calls/fsync-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fsync$sysv 0x005f005f205f004a globl hidden diff --git a/libc/sysv/calls/fsync_nocancel.s b/libc/sysv/calls/fsync_nocancel.s new file mode 100644 index 00000000..c4f2a498 --- /dev/null +++ b/libc/sysv/calls/fsync_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall fsync_nocancel 0xffffffff2198ffff globl diff --git a/libc/sysv/calls/futex.s b/libc/sysv/calls/futex.s new file mode 100644 index 00000000..ee16804f --- /dev/null +++ b/libc/sysv/calls/futex.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall futex 0x0053ffffffff00ca globl diff --git a/libc/sysv/calls/futimens.s b/libc/sysv/calls/futimens.s new file mode 100644 index 00000000..f4df3fb1 --- /dev/null +++ b/libc/sysv/calls/futimens.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall futimens 0x00550222ffffffff globl diff --git a/libc/sysv/calls/futimes.s b/libc/sysv/calls/futimes.s new file mode 100644 index 00000000..d4e0336c --- /dev/null +++ b/libc/sysv/calls/futimes.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall futimes 0x004d00ce208bffff globl diff --git a/libc/sysv/calls/futimesat.s b/libc/sysv/calls/futimesat.s new file mode 100644 index 00000000..59605f0e --- /dev/null +++ b/libc/sysv/calls/futimesat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall futimesat 0xffff01eeffff0105 globl hidden diff --git a/libc/sysv/calls/get_mempolicy.s b/libc/sysv/calls/get_mempolicy.s new file mode 100644 index 00000000..c46b7b15 --- /dev/null +++ b/libc/sysv/calls/get_mempolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall get_mempolicy 0xffffffffffff00ef globl diff --git a/libc/sysv/calls/get_robust_list.s b/libc/sysv/calls/get_robust_list.s new file mode 100644 index 00000000..a36d0b6e --- /dev/null +++ b/libc/sysv/calls/get_robust_list.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall get_robust_list 0xffffffffffff0112 globl diff --git a/libc/sysv/calls/getattrlist.s b/libc/sysv/calls/getattrlist.s new file mode 100644 index 00000000..c935d48c --- /dev/null +++ b/libc/sysv/calls/getattrlist.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getattrlist 0xffffffff20dcffff globl diff --git a/libc/sysv/calls/getattrlistat.s b/libc/sysv/calls/getattrlistat.s new file mode 100644 index 00000000..38a754a0 --- /dev/null +++ b/libc/sysv/calls/getattrlistat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getattrlistat 0xffffffff21dcffff globl diff --git a/libc/sysv/calls/getattrlistbulk.s b/libc/sysv/calls/getattrlistbulk.s new file mode 100644 index 00000000..adeb9ccf --- /dev/null +++ b/libc/sysv/calls/getattrlistbulk.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getattrlistbulk 0xffffffff21cdffff globl diff --git a/libc/sysv/calls/getaudit.s b/libc/sysv/calls/getaudit.s new file mode 100644 index 00000000..307b22d3 --- /dev/null +++ b/libc/sysv/calls/getaudit.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getaudit 0xffff01c1ffffffff globl diff --git a/libc/sysv/calls/getaudit_addr.s b/libc/sysv/calls/getaudit_addr.s new file mode 100644 index 00000000..9f34ef08 --- /dev/null +++ b/libc/sysv/calls/getaudit_addr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getaudit_addr 0xffff01c32165ffff globl diff --git a/libc/sysv/calls/getauid.s b/libc/sysv/calls/getauid.s new file mode 100644 index 00000000..948f077f --- /dev/null +++ b/libc/sysv/calls/getauid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getauid 0xffff01bf2161ffff globl diff --git a/libc/sysv/calls/getcontext.s b/libc/sysv/calls/getcontext.s new file mode 100644 index 00000000..660323d0 --- /dev/null +++ b/libc/sysv/calls/getcontext.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getcontext 0xffff01a5ffffffff globl diff --git a/libc/sysv/calls/getcpu.s b/libc/sysv/calls/getcpu.s new file mode 100644 index 00000000..82b6efb5 --- /dev/null +++ b/libc/sysv/calls/getcpu.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getcpu 0xffffffffffff0135 globl diff --git a/libc/sysv/calls/getcwd-sysv.s b/libc/sysv/calls/getcwd-sysv.s new file mode 100644 index 00000000..b93255dd --- /dev/null +++ b/libc/sysv/calls/getcwd-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getcwd$sysv 0x01300146ffff004f globl hidden diff --git a/libc/sysv/calls/getdents.s b/libc/sysv/calls/getdents.s new file mode 100644 index 00000000..84ca32e9 --- /dev/null +++ b/libc/sysv/calls/getdents.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getdents 0x00630110ffff004e globl hidden diff --git a/libc/sysv/calls/getdirentries.s b/libc/sysv/calls/getdirentries.s new file mode 100644 index 00000000..e32b4e1a --- /dev/null +++ b/libc/sysv/calls/getdirentries.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getdirentries 0xffff022a2158ffff globl diff --git a/libc/sysv/calls/getdirentriesattr.s b/libc/sysv/calls/getdirentriesattr.s new file mode 100644 index 00000000..4c97067c --- /dev/null +++ b/libc/sysv/calls/getdirentriesattr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getdirentriesattr 0xffffffff20deffff globl diff --git a/libc/sysv/calls/getdomainname.s b/libc/sysv/calls/getdomainname.s new file mode 100644 index 00000000..ea6d3967 --- /dev/null +++ b/libc/sysv/calls/getdomainname.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getdomainname 0xffff00a2ffffffff globl diff --git a/libc/sysv/calls/getdtablecount.s b/libc/sysv/calls/getdtablecount.s new file mode 100644 index 00000000..6b96f453 --- /dev/null +++ b/libc/sysv/calls/getdtablecount.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getdtablecount 0x0012ffffffffffff globl diff --git a/libc/sysv/calls/getdtablesize.s b/libc/sysv/calls/getdtablesize.s new file mode 100644 index 00000000..d416099d --- /dev/null +++ b/libc/sysv/calls/getdtablesize.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getdtablesize 0xffff00592059ffff globl diff --git a/libc/sysv/calls/getegid.s b/libc/sysv/calls/getegid.s new file mode 100644 index 00000000..0a1896fb --- /dev/null +++ b/libc/sysv/calls/getegid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getegid 0x002b002b202b006c globl diff --git a/libc/sysv/calls/geteuid.s b/libc/sysv/calls/geteuid.s new file mode 100644 index 00000000..29cc4d9d --- /dev/null +++ b/libc/sysv/calls/geteuid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall geteuid 0x001900192019006b globl diff --git a/libc/sysv/calls/getfh.s b/libc/sysv/calls/getfh.s new file mode 100644 index 00000000..256772cc --- /dev/null +++ b/libc/sysv/calls/getfh.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getfh 0x00a100a120a1ffff globl diff --git a/libc/sysv/calls/getfhat.s b/libc/sysv/calls/getfhat.s new file mode 100644 index 00000000..3fe7ae07 --- /dev/null +++ b/libc/sysv/calls/getfhat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getfhat 0xffff0234ffffffff globl diff --git a/libc/sysv/calls/getfsstat.s b/libc/sysv/calls/getfsstat.s new file mode 100644 index 00000000..f033c260 --- /dev/null +++ b/libc/sysv/calls/getfsstat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getfsstat 0x003e022d215bffff globl diff --git a/libc/sysv/calls/getgid-sysv.s b/libc/sysv/calls/getgid-sysv.s new file mode 100644 index 00000000..2158fb09 --- /dev/null +++ b/libc/sysv/calls/getgid-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getgid$sysv 0x002f002f202f0068 globl hidden diff --git a/libc/sysv/calls/getgroups.s b/libc/sysv/calls/getgroups.s new file mode 100644 index 00000000..0e6439d8 --- /dev/null +++ b/libc/sysv/calls/getgroups.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getgroups 0x004f004f204f0073 globl diff --git a/libc/sysv/calls/gethostid.s b/libc/sysv/calls/gethostid.s new file mode 100644 index 00000000..0f9afb46 --- /dev/null +++ b/libc/sysv/calls/gethostid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall gethostid 0xffff008effffffff globl diff --git a/libc/sysv/calls/gethostname.s b/libc/sysv/calls/gethostname.s new file mode 100644 index 00000000..10dcf7ff --- /dev/null +++ b/libc/sysv/calls/gethostname.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall gethostname 0xffff0057ffffffff globl diff --git a/libc/sysv/calls/gethostuuid.s b/libc/sysv/calls/gethostuuid.s new file mode 100644 index 00000000..7408d6f3 --- /dev/null +++ b/libc/sysv/calls/gethostuuid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall gethostuuid 0xffffffff208effff globl diff --git a/libc/sysv/calls/getitimer-sysv.s b/libc/sysv/calls/getitimer-sysv.s new file mode 100644 index 00000000..921684c3 --- /dev/null +++ b/libc/sysv/calls/getitimer-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getitimer$sysv 0x0046005620560024 globl hidden diff --git a/libc/sysv/calls/getkerninfo.s b/libc/sysv/calls/getkerninfo.s new file mode 100644 index 00000000..c38535dc --- /dev/null +++ b/libc/sysv/calls/getkerninfo.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getkerninfo 0xffff003fffffffff globl diff --git a/libc/sysv/calls/getlogin.s b/libc/sysv/calls/getlogin.s new file mode 100644 index 00000000..43fc501f --- /dev/null +++ b/libc/sysv/calls/getlogin.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getlogin 0xffff00312031ffff globl diff --git a/libc/sysv/calls/getlogin_r.s b/libc/sysv/calls/getlogin_r.s new file mode 100644 index 00000000..7c743e05 --- /dev/null +++ b/libc/sysv/calls/getlogin_r.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getlogin_r 0x008dffffffffffff globl diff --git a/libc/sysv/calls/getloginclass.s b/libc/sysv/calls/getloginclass.s new file mode 100644 index 00000000..bd3550c3 --- /dev/null +++ b/libc/sysv/calls/getloginclass.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getloginclass 0xffff020bffffffff globl diff --git a/libc/sysv/calls/getpagesize-freebsd.s b/libc/sysv/calls/getpagesize-freebsd.s new file mode 100644 index 00000000..2e625541 --- /dev/null +++ b/libc/sysv/calls/getpagesize-freebsd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getpagesize$freebsd 0xffff0040ffffffff globl hidden diff --git a/libc/sysv/calls/getpgid.s b/libc/sysv/calls/getpgid.s new file mode 100644 index 00000000..a6d80074 --- /dev/null +++ b/libc/sysv/calls/getpgid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getpgid 0x00cf00cf20970079 globl diff --git a/libc/sysv/calls/getpgrp.s b/libc/sysv/calls/getpgrp.s new file mode 100644 index 00000000..2a5248d2 --- /dev/null +++ b/libc/sysv/calls/getpgrp.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getpgrp 0x005100512051006f globl diff --git a/libc/sysv/calls/getpid-sysv.s b/libc/sysv/calls/getpid-sysv.s new file mode 100644 index 00000000..e3cdabf9 --- /dev/null +++ b/libc/sysv/calls/getpid-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getpid$sysv 0x0014001420140027 globl hidden diff --git a/libc/sysv/calls/getppid-sysv.s b/libc/sysv/calls/getppid-sysv.s new file mode 100644 index 00000000..d7fa7a21 --- /dev/null +++ b/libc/sysv/calls/getppid-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getppid$sysv 0x002700272027006e globl hidden diff --git a/libc/sysv/calls/getpriority-sysv.s b/libc/sysv/calls/getpriority-sysv.s new file mode 100644 index 00000000..02e0f7a5 --- /dev/null +++ b/libc/sysv/calls/getpriority-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getpriority$sysv 0x006400642064008c globl hidden diff --git a/libc/sysv/calls/getrandom-sysv.s b/libc/sysv/calls/getrandom-sysv.s new file mode 100644 index 00000000..bd7164ca --- /dev/null +++ b/libc/sysv/calls/getrandom-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getrandom$sysv 0x0007023321f4013e globl hidden diff --git a/libc/sysv/calls/getresgid.s b/libc/sysv/calls/getresgid.s new file mode 100644 index 00000000..0b85c215 --- /dev/null +++ b/libc/sysv/calls/getresgid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getresgid 0x011b0169ffff0078 globl diff --git a/libc/sysv/calls/getresuid.s b/libc/sysv/calls/getresuid.s new file mode 100644 index 00000000..668d1785 --- /dev/null +++ b/libc/sysv/calls/getresuid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getresuid 0x01190168ffff0076 globl diff --git a/libc/sysv/calls/getrlimit-sysv.s b/libc/sysv/calls/getrlimit-sysv.s new file mode 100644 index 00000000..d50c3a1f --- /dev/null +++ b/libc/sysv/calls/getrlimit-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getrlimit$sysv 0x00c200c220c20061 globl hidden diff --git a/libc/sysv/calls/getrtable.s b/libc/sysv/calls/getrtable.s new file mode 100644 index 00000000..b0afeca8 --- /dev/null +++ b/libc/sysv/calls/getrtable.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getrtable 0x0137ffffffffffff globl diff --git a/libc/sysv/calls/getrusage-sysv.s b/libc/sysv/calls/getrusage-sysv.s new file mode 100644 index 00000000..cf7de169 --- /dev/null +++ b/libc/sysv/calls/getrusage-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getrusage$sysv 0x0013007520750062 globl hidden diff --git a/libc/sysv/calls/getsgroups.s b/libc/sysv/calls/getsgroups.s new file mode 100644 index 00000000..c9cd0d06 --- /dev/null +++ b/libc/sysv/calls/getsgroups.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getsgroups 0xffffffff2120ffff globl diff --git a/libc/sysv/calls/getsid.s b/libc/sysv/calls/getsid.s new file mode 100644 index 00000000..2c3340d0 --- /dev/null +++ b/libc/sysv/calls/getsid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getsid 0x00ff01362136007c globl diff --git a/libc/sysv/calls/getsockopt-sysv.s b/libc/sysv/calls/getsockopt-sysv.s new file mode 100644 index 00000000..44fdc7c2 --- /dev/null +++ b/libc/sysv/calls/getsockopt-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getsockopt$sysv 0x0076007620760037 globl hidden diff --git a/libc/sysv/calls/getthrid.s b/libc/sysv/calls/getthrid.s new file mode 100644 index 00000000..925ef4aa --- /dev/null +++ b/libc/sysv/calls/getthrid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getthrid 0x012bffffffffffff globl diff --git a/libc/sysv/calls/gettid-sysv.s b/libc/sysv/calls/gettid-sysv.s new file mode 100644 index 00000000..ecbde41e --- /dev/null +++ b/libc/sysv/calls/gettid-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall gettid$sysv 0xffffffff211e00ba globl hidden diff --git a/libc/sysv/calls/getuid-sysv.s b/libc/sysv/calls/getuid-sysv.s new file mode 100644 index 00000000..bb447c48 --- /dev/null +++ b/libc/sysv/calls/getuid-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getuid$sysv 0x0018001820180066 globl hidden diff --git a/libc/sysv/calls/getwgroups.s b/libc/sysv/calls/getwgroups.s new file mode 100644 index 00000000..e4792afd --- /dev/null +++ b/libc/sysv/calls/getwgroups.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getwgroups 0xffffffff2122ffff globl diff --git a/libc/sysv/calls/getxattr.s b/libc/sysv/calls/getxattr.s new file mode 100644 index 00000000..c4d5fbd7 --- /dev/null +++ b/libc/sysv/calls/getxattr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall getxattr 0xffffffff20ea00bf globl diff --git a/libc/sysv/calls/grab_pgo_data.s b/libc/sysv/calls/grab_pgo_data.s new file mode 100644 index 00000000..5c41705a --- /dev/null +++ b/libc/sysv/calls/grab_pgo_data.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall grab_pgo_data 0xffffffff21edffff globl diff --git a/libc/sysv/calls/gssd_syscall.s b/libc/sysv/calls/gssd_syscall.s new file mode 100644 index 00000000..e7771a47 --- /dev/null +++ b/libc/sysv/calls/gssd_syscall.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall gssd_syscall 0xffff01f9ffffffff globl diff --git a/libc/sysv/calls/guarded_close_np.s b/libc/sysv/calls/guarded_close_np.s new file mode 100644 index 00000000..cc860812 --- /dev/null +++ b/libc/sysv/calls/guarded_close_np.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall guarded_close_np 0xffffffff21baffff globl diff --git a/libc/sysv/calls/guarded_kqueue_np.s b/libc/sysv/calls/guarded_kqueue_np.s new file mode 100644 index 00000000..096934bc --- /dev/null +++ b/libc/sysv/calls/guarded_kqueue_np.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall guarded_kqueue_np 0xffffffff21bbffff globl diff --git a/libc/sysv/calls/guarded_open_dprotected_np.s b/libc/sysv/calls/guarded_open_dprotected_np.s new file mode 100644 index 00000000..fe43226b --- /dev/null +++ b/libc/sysv/calls/guarded_open_dprotected_np.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall guarded_open_dprotected_np 0xffffffff21e4ffff globl diff --git a/libc/sysv/calls/guarded_open_np.s b/libc/sysv/calls/guarded_open_np.s new file mode 100644 index 00000000..c5db6fec --- /dev/null +++ b/libc/sysv/calls/guarded_open_np.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall guarded_open_np 0xffffffff21b9ffff globl diff --git a/libc/sysv/calls/guarded_pwrite_np.s b/libc/sysv/calls/guarded_pwrite_np.s new file mode 100644 index 00000000..2419bc57 --- /dev/null +++ b/libc/sysv/calls/guarded_pwrite_np.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall guarded_pwrite_np 0xffffffff21e6ffff globl diff --git a/libc/sysv/calls/guarded_write_np.s b/libc/sysv/calls/guarded_write_np.s new file mode 100644 index 00000000..9070b296 --- /dev/null +++ b/libc/sysv/calls/guarded_write_np.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall guarded_write_np 0xffffffff21e5ffff globl diff --git a/libc/sysv/calls/guarded_writev_np.s b/libc/sysv/calls/guarded_writev_np.s new file mode 100644 index 00000000..83dfce4f --- /dev/null +++ b/libc/sysv/calls/guarded_writev_np.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall guarded_writev_np 0xffffffff21e7ffff globl diff --git a/libc/sysv/calls/identitysvc.s b/libc/sysv/calls/identitysvc.s new file mode 100644 index 00000000..7ad32156 --- /dev/null +++ b/libc/sysv/calls/identitysvc.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall identitysvc 0xffffffff2125ffff globl diff --git a/libc/sysv/calls/init_module.s b/libc/sysv/calls/init_module.s new file mode 100644 index 00000000..0992dc29 --- /dev/null +++ b/libc/sysv/calls/init_module.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall init_module 0xffffffffffff00af globl diff --git a/libc/sysv/calls/initgroups.s b/libc/sysv/calls/initgroups.s new file mode 100644 index 00000000..b6ae3d63 --- /dev/null +++ b/libc/sysv/calls/initgroups.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall initgroups 0xffffffff20f3ffff globl diff --git a/libc/sysv/calls/inotify_add_watch.s b/libc/sysv/calls/inotify_add_watch.s new file mode 100644 index 00000000..76b353cb --- /dev/null +++ b/libc/sysv/calls/inotify_add_watch.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall inotify_add_watch 0xffffffffffff00fe globl diff --git a/libc/sysv/calls/inotify_init.s b/libc/sysv/calls/inotify_init.s new file mode 100644 index 00000000..6984e84c --- /dev/null +++ b/libc/sysv/calls/inotify_init.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall inotify_init 0xffffffffffff00fd globl diff --git a/libc/sysv/calls/inotify_init1.s b/libc/sysv/calls/inotify_init1.s new file mode 100644 index 00000000..329b313b --- /dev/null +++ b/libc/sysv/calls/inotify_init1.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall inotify_init1 0xffffffffffff0126 globl diff --git a/libc/sysv/calls/inotify_rm_watch.s b/libc/sysv/calls/inotify_rm_watch.s new file mode 100644 index 00000000..5c50dd53 --- /dev/null +++ b/libc/sysv/calls/inotify_rm_watch.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall inotify_rm_watch 0xffffffffffff00ff globl diff --git a/libc/sysv/calls/io_cancel.s b/libc/sysv/calls/io_cancel.s new file mode 100644 index 00000000..611e00c3 --- /dev/null +++ b/libc/sysv/calls/io_cancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall io_cancel 0xffffffffffff00d2 globl diff --git a/libc/sysv/calls/io_destroy.s b/libc/sysv/calls/io_destroy.s new file mode 100644 index 00000000..b51e5cbf --- /dev/null +++ b/libc/sysv/calls/io_destroy.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall io_destroy 0xffffffffffff00cf globl diff --git a/libc/sysv/calls/io_getevents.s b/libc/sysv/calls/io_getevents.s new file mode 100644 index 00000000..3cf8976d --- /dev/null +++ b/libc/sysv/calls/io_getevents.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall io_getevents 0xffffffffffff00d0 globl diff --git a/libc/sysv/calls/io_pgetevents.s b/libc/sysv/calls/io_pgetevents.s new file mode 100644 index 00000000..e508249a --- /dev/null +++ b/libc/sysv/calls/io_pgetevents.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall io_pgetevents 0xffffffffffff014d globl diff --git a/libc/sysv/calls/io_setup.s b/libc/sysv/calls/io_setup.s new file mode 100644 index 00000000..1c8c8fbc --- /dev/null +++ b/libc/sysv/calls/io_setup.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall io_setup 0xffffffffffff00ce globl diff --git a/libc/sysv/calls/io_submit.s b/libc/sysv/calls/io_submit.s new file mode 100644 index 00000000..37d5c3ca --- /dev/null +++ b/libc/sysv/calls/io_submit.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall io_submit 0xffffffffffff00d1 globl diff --git a/libc/sysv/calls/io_uring_enter.s b/libc/sysv/calls/io_uring_enter.s new file mode 100644 index 00000000..0386cfe5 --- /dev/null +++ b/libc/sysv/calls/io_uring_enter.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall io_uring_enter 0xffffffffffff01aa globl diff --git a/libc/sysv/calls/io_uring_register.s b/libc/sysv/calls/io_uring_register.s new file mode 100644 index 00000000..31b335fd --- /dev/null +++ b/libc/sysv/calls/io_uring_register.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall io_uring_register 0xffffffffffff01ab globl diff --git a/libc/sysv/calls/io_uring_setup.s b/libc/sysv/calls/io_uring_setup.s new file mode 100644 index 00000000..17e8fb2c --- /dev/null +++ b/libc/sysv/calls/io_uring_setup.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall io_uring_setup 0xffffffffffff01a9 globl diff --git a/libc/sysv/calls/ioctl-sysv.s b/libc/sysv/calls/ioctl-sysv.s new file mode 100644 index 00000000..9d1343b5 --- /dev/null +++ b/libc/sysv/calls/ioctl-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ioctl$sysv 0x0036003620360010 globl hidden diff --git a/libc/sysv/calls/ioperm.s b/libc/sysv/calls/ioperm.s new file mode 100644 index 00000000..feebdf33 --- /dev/null +++ b/libc/sysv/calls/ioperm.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ioperm 0xffffffffffff00ad globl diff --git a/libc/sysv/calls/iopl.s b/libc/sysv/calls/iopl.s new file mode 100644 index 00000000..f703df99 --- /dev/null +++ b/libc/sysv/calls/iopl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall iopl 0xffffffffffff00ac globl diff --git a/libc/sysv/calls/iopolicysys.s b/libc/sysv/calls/iopolicysys.s new file mode 100644 index 00000000..e83beee3 --- /dev/null +++ b/libc/sysv/calls/iopolicysys.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall iopolicysys 0xffffffff2142ffff globl diff --git a/libc/sysv/calls/ioprio_get.s b/libc/sysv/calls/ioprio_get.s new file mode 100644 index 00000000..9d1ba63b --- /dev/null +++ b/libc/sysv/calls/ioprio_get.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ioprio_get 0xffffffffffff00fc globl diff --git a/libc/sysv/calls/ioprio_set.s b/libc/sysv/calls/ioprio_set.s new file mode 100644 index 00000000..ca4f9509 --- /dev/null +++ b/libc/sysv/calls/ioprio_set.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ioprio_set 0xffffffffffff00fb globl diff --git a/libc/sysv/calls/issetugid.s b/libc/sysv/calls/issetugid.s new file mode 100644 index 00000000..ae906354 --- /dev/null +++ b/libc/sysv/calls/issetugid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall issetugid 0x00fd00fd2147ffff globl diff --git a/libc/sysv/calls/jail.s b/libc/sysv/calls/jail.s new file mode 100644 index 00000000..e15d9de4 --- /dev/null +++ b/libc/sysv/calls/jail.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall jail 0xffff0152ffffffff globl diff --git a/libc/sysv/calls/jail_attach.s b/libc/sysv/calls/jail_attach.s new file mode 100644 index 00000000..e6f7dacf --- /dev/null +++ b/libc/sysv/calls/jail_attach.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall jail_attach 0xffff01b4ffffffff globl diff --git a/libc/sysv/calls/jail_get.s b/libc/sysv/calls/jail_get.s new file mode 100644 index 00000000..abce4695 --- /dev/null +++ b/libc/sysv/calls/jail_get.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall jail_get 0xffff01faffffffff globl diff --git a/libc/sysv/calls/jail_remove.s b/libc/sysv/calls/jail_remove.s new file mode 100644 index 00000000..41c8e994 --- /dev/null +++ b/libc/sysv/calls/jail_remove.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall jail_remove 0xffff01fcffffffff globl diff --git a/libc/sysv/calls/jail_set.s b/libc/sysv/calls/jail_set.s new file mode 100644 index 00000000..eb2566e5 --- /dev/null +++ b/libc/sysv/calls/jail_set.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall jail_set 0xffff01fbffffffff globl diff --git a/libc/sysv/calls/kas_info.s b/libc/sysv/calls/kas_info.s new file mode 100644 index 00000000..432b35fb --- /dev/null +++ b/libc/sysv/calls/kas_info.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kas_info 0xffffffff21b7ffff globl diff --git a/libc/sysv/calls/kbind.s b/libc/sysv/calls/kbind.s new file mode 100644 index 00000000..b0859d23 --- /dev/null +++ b/libc/sysv/calls/kbind.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kbind 0x0056ffffffffffff globl diff --git a/libc/sysv/calls/kcmp.s b/libc/sysv/calls/kcmp.s new file mode 100644 index 00000000..6b9ffa80 --- /dev/null +++ b/libc/sysv/calls/kcmp.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kcmp 0xffffffffffff0138 globl diff --git a/libc/sysv/calls/kdebug_trace.s b/libc/sysv/calls/kdebug_trace.s new file mode 100644 index 00000000..a3df5229 --- /dev/null +++ b/libc/sysv/calls/kdebug_trace.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kdebug_trace 0xffffffff20b3ffff globl diff --git a/libc/sysv/calls/kdebug_trace_string.s b/libc/sysv/calls/kdebug_trace_string.s new file mode 100644 index 00000000..152681d9 --- /dev/null +++ b/libc/sysv/calls/kdebug_trace_string.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kdebug_trace_string 0xffffffff20b2ffff globl diff --git a/libc/sysv/calls/kdebug_typefilter.s b/libc/sysv/calls/kdebug_typefilter.s new file mode 100644 index 00000000..eea54bb6 --- /dev/null +++ b/libc/sysv/calls/kdebug_typefilter.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kdebug_typefilter 0xffffffff20b1ffff globl diff --git a/libc/sysv/calls/kenv.s b/libc/sysv/calls/kenv.s new file mode 100644 index 00000000..846d3f9d --- /dev/null +++ b/libc/sysv/calls/kenv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kenv 0xffff0186ffffffff globl diff --git a/libc/sysv/calls/kevent.s b/libc/sysv/calls/kevent.s new file mode 100644 index 00000000..5a6100c1 --- /dev/null +++ b/libc/sysv/calls/kevent.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kevent 0x004802302171ffff globl diff --git a/libc/sysv/calls/kevent_id.s b/libc/sysv/calls/kevent_id.s new file mode 100644 index 00000000..1cff8d5a --- /dev/null +++ b/libc/sysv/calls/kevent_id.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kevent_id 0xffffffff2177ffff globl diff --git a/libc/sysv/calls/kevent_qos.s b/libc/sysv/calls/kevent_qos.s new file mode 100644 index 00000000..dd70067e --- /dev/null +++ b/libc/sysv/calls/kevent_qos.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kevent_qos 0xffffffff2176ffff globl diff --git a/libc/sysv/calls/kexec_file_load.s b/libc/sysv/calls/kexec_file_load.s new file mode 100644 index 00000000..2ec76639 --- /dev/null +++ b/libc/sysv/calls/kexec_file_load.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kexec_file_load 0xffffffffffff0140 globl diff --git a/libc/sysv/calls/kexec_load.s b/libc/sysv/calls/kexec_load.s new file mode 100644 index 00000000..9a1cad89 --- /dev/null +++ b/libc/sysv/calls/kexec_load.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kexec_load 0xffffffffffff00f6 globl diff --git a/libc/sysv/calls/keyctl.s b/libc/sysv/calls/keyctl.s new file mode 100644 index 00000000..48ef3868 --- /dev/null +++ b/libc/sysv/calls/keyctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall keyctl 0xffffffffffff00fa globl diff --git a/libc/sysv/calls/kill-sysv.s b/libc/sysv/calls/kill-sysv.s new file mode 100644 index 00000000..fd20773c --- /dev/null +++ b/libc/sysv/calls/kill-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kill$sysv 0x007a00252025003e globl hidden diff --git a/libc/sysv/calls/killpg-sysv.s b/libc/sysv/calls/killpg-sysv.s new file mode 100644 index 00000000..72dfe451 --- /dev/null +++ b/libc/sysv/calls/killpg-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall killpg$sysv 0xffff0092ffffffff globl hidden diff --git a/libc/sysv/calls/kldfind.s b/libc/sysv/calls/kldfind.s new file mode 100644 index 00000000..ae2e0a9b --- /dev/null +++ b/libc/sysv/calls/kldfind.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kldfind 0xffff0132ffffffff globl diff --git a/libc/sysv/calls/kldfirstmod.s b/libc/sysv/calls/kldfirstmod.s new file mode 100644 index 00000000..99e37629 --- /dev/null +++ b/libc/sysv/calls/kldfirstmod.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kldfirstmod 0xffff0135ffffffff globl diff --git a/libc/sysv/calls/kldload.s b/libc/sysv/calls/kldload.s new file mode 100644 index 00000000..28d90888 --- /dev/null +++ b/libc/sysv/calls/kldload.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kldload 0xffff0130ffffffff globl diff --git a/libc/sysv/calls/kldnext.s b/libc/sysv/calls/kldnext.s new file mode 100644 index 00000000..96323172 --- /dev/null +++ b/libc/sysv/calls/kldnext.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kldnext 0xffff0133ffffffff globl diff --git a/libc/sysv/calls/kldstat.s b/libc/sysv/calls/kldstat.s new file mode 100644 index 00000000..f72c90c3 --- /dev/null +++ b/libc/sysv/calls/kldstat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kldstat 0xffff0134ffffffff globl diff --git a/libc/sysv/calls/kldsym.s b/libc/sysv/calls/kldsym.s new file mode 100644 index 00000000..6ddf5d03 --- /dev/null +++ b/libc/sysv/calls/kldsym.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kldsym 0xffff0151ffffffff globl diff --git a/libc/sysv/calls/kldunload.s b/libc/sysv/calls/kldunload.s new file mode 100644 index 00000000..7cffaf72 --- /dev/null +++ b/libc/sysv/calls/kldunload.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kldunload 0xffff0131ffffffff globl diff --git a/libc/sysv/calls/kldunloadf.s b/libc/sysv/calls/kldunloadf.s new file mode 100644 index 00000000..87319d1c --- /dev/null +++ b/libc/sysv/calls/kldunloadf.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kldunloadf 0xffff01bcffffffff globl diff --git a/libc/sysv/calls/kmq_notify.s b/libc/sysv/calls/kmq_notify.s new file mode 100644 index 00000000..e42e8329 --- /dev/null +++ b/libc/sysv/calls/kmq_notify.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kmq_notify 0xffff01cdffffffff globl diff --git a/libc/sysv/calls/kmq_setattr.s b/libc/sysv/calls/kmq_setattr.s new file mode 100644 index 00000000..5d930cdc --- /dev/null +++ b/libc/sysv/calls/kmq_setattr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kmq_setattr 0xffff01caffffffff globl diff --git a/libc/sysv/calls/kmq_timedreceive.s b/libc/sysv/calls/kmq_timedreceive.s new file mode 100644 index 00000000..d4e25dcf --- /dev/null +++ b/libc/sysv/calls/kmq_timedreceive.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kmq_timedreceive 0xffff01cbffffffff globl diff --git a/libc/sysv/calls/kmq_timedsend.s b/libc/sysv/calls/kmq_timedsend.s new file mode 100644 index 00000000..f36ba520 --- /dev/null +++ b/libc/sysv/calls/kmq_timedsend.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kmq_timedsend 0xffff01ccffffffff globl diff --git a/libc/sysv/calls/kmq_unlink.s b/libc/sysv/calls/kmq_unlink.s new file mode 100644 index 00000000..fadaf42c --- /dev/null +++ b/libc/sysv/calls/kmq_unlink.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kmq_unlink 0xffff01ceffffffff globl diff --git a/libc/sysv/calls/kqueue.s b/libc/sysv/calls/kqueue.s new file mode 100644 index 00000000..ace6b0d0 --- /dev/null +++ b/libc/sysv/calls/kqueue.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall kqueue 0x010d016a216affff globl diff --git a/libc/sysv/calls/ksem_close.s b/libc/sysv/calls/ksem_close.s new file mode 100644 index 00000000..0dc07a7f --- /dev/null +++ b/libc/sysv/calls/ksem_close.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ksem_close 0xffff0190ffffffff globl diff --git a/libc/sysv/calls/ksem_destroy.s b/libc/sysv/calls/ksem_destroy.s new file mode 100644 index 00000000..7475e8fe --- /dev/null +++ b/libc/sysv/calls/ksem_destroy.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ksem_destroy 0xffff0198ffffffff globl diff --git a/libc/sysv/calls/ksem_getvalue.s b/libc/sysv/calls/ksem_getvalue.s new file mode 100644 index 00000000..5693965b --- /dev/null +++ b/libc/sysv/calls/ksem_getvalue.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ksem_getvalue 0xffff0197ffffffff globl diff --git a/libc/sysv/calls/ksem_init.s b/libc/sysv/calls/ksem_init.s new file mode 100644 index 00000000..87abc10c --- /dev/null +++ b/libc/sysv/calls/ksem_init.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ksem_init 0xffff0194ffffffff globl diff --git a/libc/sysv/calls/ksem_open.s b/libc/sysv/calls/ksem_open.s new file mode 100644 index 00000000..745d537d --- /dev/null +++ b/libc/sysv/calls/ksem_open.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ksem_open 0xffff0195ffffffff globl diff --git a/libc/sysv/calls/ksem_post.s b/libc/sysv/calls/ksem_post.s new file mode 100644 index 00000000..a1812733 --- /dev/null +++ b/libc/sysv/calls/ksem_post.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ksem_post 0xffff0191ffffffff globl diff --git a/libc/sysv/calls/ksem_timedwait.s b/libc/sysv/calls/ksem_timedwait.s new file mode 100644 index 00000000..1573fe73 --- /dev/null +++ b/libc/sysv/calls/ksem_timedwait.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ksem_timedwait 0xffff01b9ffffffff globl diff --git a/libc/sysv/calls/ksem_trywait.s b/libc/sysv/calls/ksem_trywait.s new file mode 100644 index 00000000..3fe36859 --- /dev/null +++ b/libc/sysv/calls/ksem_trywait.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ksem_trywait 0xffff0193ffffffff globl diff --git a/libc/sysv/calls/ksem_unlink.s b/libc/sysv/calls/ksem_unlink.s new file mode 100644 index 00000000..dcfd7aca --- /dev/null +++ b/libc/sysv/calls/ksem_unlink.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ksem_unlink 0xffff0196ffffffff globl diff --git a/libc/sysv/calls/ksem_wait.s b/libc/sysv/calls/ksem_wait.s new file mode 100644 index 00000000..34196916 --- /dev/null +++ b/libc/sysv/calls/ksem_wait.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ksem_wait 0xffff0192ffffffff globl diff --git a/libc/sysv/calls/ktimer_create.s b/libc/sysv/calls/ktimer_create.s new file mode 100644 index 00000000..c15b4431 --- /dev/null +++ b/libc/sysv/calls/ktimer_create.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ktimer_create 0xffff00ebffffffff globl diff --git a/libc/sysv/calls/ktimer_delete.s b/libc/sysv/calls/ktimer_delete.s new file mode 100644 index 00000000..e57a7480 --- /dev/null +++ b/libc/sysv/calls/ktimer_delete.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ktimer_delete 0xffff00ecffffffff globl diff --git a/libc/sysv/calls/ktimer_getoverrun.s b/libc/sysv/calls/ktimer_getoverrun.s new file mode 100644 index 00000000..4518fab3 --- /dev/null +++ b/libc/sysv/calls/ktimer_getoverrun.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ktimer_getoverrun 0xffff00efffffffff globl diff --git a/libc/sysv/calls/ktimer_gettime.s b/libc/sysv/calls/ktimer_gettime.s new file mode 100644 index 00000000..bf42c7e9 --- /dev/null +++ b/libc/sysv/calls/ktimer_gettime.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ktimer_gettime 0xffff00eeffffffff globl diff --git a/libc/sysv/calls/ktimer_settime.s b/libc/sysv/calls/ktimer_settime.s new file mode 100644 index 00000000..517c8331 --- /dev/null +++ b/libc/sysv/calls/ktimer_settime.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ktimer_settime 0xffff00edffffffff globl diff --git a/libc/sysv/calls/ktrace.s b/libc/sysv/calls/ktrace.s new file mode 100644 index 00000000..d1fbb44b --- /dev/null +++ b/libc/sysv/calls/ktrace.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ktrace 0x002d002dffffffff globl diff --git a/libc/sysv/calls/lchflags.s b/libc/sysv/calls/lchflags.s new file mode 100644 index 00000000..e83b91dc --- /dev/null +++ b/libc/sysv/calls/lchflags.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall lchflags 0xffff0187ffffffff globl diff --git a/libc/sysv/calls/lchmod.s b/libc/sysv/calls/lchmod.s new file mode 100644 index 00000000..d885a158 --- /dev/null +++ b/libc/sysv/calls/lchmod.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall lchmod 0xffff0112ffffffff globl diff --git a/libc/sysv/calls/lchown-sysv.s b/libc/sysv/calls/lchown-sysv.s new file mode 100644 index 00000000..3ac67cde --- /dev/null +++ b/libc/sysv/calls/lchown-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall lchown$sysv 0x00fe00fe216c005e globl hidden diff --git a/libc/sysv/calls/ledger.s b/libc/sysv/calls/ledger.s new file mode 100644 index 00000000..9310c57a --- /dev/null +++ b/libc/sysv/calls/ledger.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ledger 0xffffffff2175ffff globl diff --git a/libc/sysv/calls/lgetfh.s b/libc/sysv/calls/lgetfh.s new file mode 100644 index 00000000..410ebaa4 --- /dev/null +++ b/libc/sysv/calls/lgetfh.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall lgetfh 0xffff00a0ffffffff globl diff --git a/libc/sysv/calls/lgetxattr.s b/libc/sysv/calls/lgetxattr.s new file mode 100644 index 00000000..fcb074a8 --- /dev/null +++ b/libc/sysv/calls/lgetxattr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall lgetxattr 0xffffffffffff00c0 globl diff --git a/libc/sysv/calls/link-sysv.s b/libc/sysv/calls/link-sysv.s new file mode 100644 index 00000000..2cf648b7 --- /dev/null +++ b/libc/sysv/calls/link-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall link$sysv 0x0009000920090056 globl hidden diff --git a/libc/sysv/calls/linkat-sysv.s b/libc/sysv/calls/linkat-sysv.s new file mode 100644 index 00000000..9ab40429 --- /dev/null +++ b/libc/sysv/calls/linkat-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall linkat$sysv 0x013d01ef21d70109 globl hidden diff --git a/libc/sysv/calls/lio_listio.s b/libc/sysv/calls/lio_listio.s new file mode 100644 index 00000000..ebbdcb6b --- /dev/null +++ b/libc/sysv/calls/lio_listio.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall lio_listio 0xffff01402140ffff globl diff --git a/libc/sysv/calls/listen-sysv.s b/libc/sysv/calls/listen-sysv.s new file mode 100644 index 00000000..276bf0a7 --- /dev/null +++ b/libc/sysv/calls/listen-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall listen$sysv 0x006a006a206a0032 globl hidden diff --git a/libc/sysv/calls/listxattr.s b/libc/sysv/calls/listxattr.s new file mode 100644 index 00000000..67a1d481 --- /dev/null +++ b/libc/sysv/calls/listxattr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall listxattr 0xffffffff20f000c2 globl diff --git a/libc/sysv/calls/llistxattr.s b/libc/sysv/calls/llistxattr.s new file mode 100644 index 00000000..3488862a --- /dev/null +++ b/libc/sysv/calls/llistxattr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall llistxattr 0xffffffffffff00c3 globl diff --git a/libc/sysv/calls/lookup_dcookie.s b/libc/sysv/calls/lookup_dcookie.s new file mode 100644 index 00000000..cd342dcc --- /dev/null +++ b/libc/sysv/calls/lookup_dcookie.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall lookup_dcookie 0xffffffffffff00d4 globl diff --git a/libc/sysv/calls/lpathconf.s b/libc/sysv/calls/lpathconf.s new file mode 100644 index 00000000..a725bd42 --- /dev/null +++ b/libc/sysv/calls/lpathconf.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall lpathconf 0xffff0201ffffffff globl diff --git a/libc/sysv/calls/lremovexattr.s b/libc/sysv/calls/lremovexattr.s new file mode 100644 index 00000000..8db86bf0 --- /dev/null +++ b/libc/sysv/calls/lremovexattr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall lremovexattr 0xffffffffffff00c6 globl diff --git a/libc/sysv/calls/lsetxattr.s b/libc/sysv/calls/lsetxattr.s new file mode 100644 index 00000000..e497200e --- /dev/null +++ b/libc/sysv/calls/lsetxattr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall lsetxattr 0xffffffffffff00bd globl diff --git a/libc/sysv/calls/lstat_extended.s b/libc/sysv/calls/lstat_extended.s new file mode 100644 index 00000000..4c524f4e --- /dev/null +++ b/libc/sysv/calls/lstat_extended.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall lstat_extended 0xffffffff2156ffff globl diff --git a/libc/sysv/calls/lutimes.s b/libc/sysv/calls/lutimes.s new file mode 100644 index 00000000..7c2b271c --- /dev/null +++ b/libc/sysv/calls/lutimes.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall lutimes 0xffff0114ffffffff globl diff --git a/libc/sysv/calls/mac_syscall.s b/libc/sysv/calls/mac_syscall.s new file mode 100644 index 00000000..197ba52f --- /dev/null +++ b/libc/sysv/calls/mac_syscall.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mac_syscall 0xffff018affffffff globl diff --git a/libc/sysv/calls/madvise-sysv.s b/libc/sysv/calls/madvise-sysv.s new file mode 100644 index 00000000..c0113490 --- /dev/null +++ b/libc/sysv/calls/madvise-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall madvise$sysv 0x004b004b204b001c globl hidden diff --git a/libc/sysv/calls/mbind.s b/libc/sysv/calls/mbind.s new file mode 100644 index 00000000..13365e8a --- /dev/null +++ b/libc/sysv/calls/mbind.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mbind 0xffffffffffff00ed globl diff --git a/libc/sysv/calls/membarrier.s b/libc/sysv/calls/membarrier.s new file mode 100644 index 00000000..7b430745 --- /dev/null +++ b/libc/sysv/calls/membarrier.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall membarrier 0xffffffffffff0144 globl diff --git a/libc/sysv/calls/memfd_create.s b/libc/sysv/calls/memfd_create.s new file mode 100644 index 00000000..f00861df --- /dev/null +++ b/libc/sysv/calls/memfd_create.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall memfd_create 0xffffffffffff013f globl diff --git a/libc/sysv/calls/memorystatus_control.s b/libc/sysv/calls/memorystatus_control.s new file mode 100644 index 00000000..70336fa6 --- /dev/null +++ b/libc/sysv/calls/memorystatus_control.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall memorystatus_control 0xffffffff21b8ffff globl diff --git a/libc/sysv/calls/memorystatus_get_level.s b/libc/sysv/calls/memorystatus_get_level.s new file mode 100644 index 00000000..b7d6e0cf --- /dev/null +++ b/libc/sysv/calls/memorystatus_get_level.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall memorystatus_get_level 0xffffffff21c5ffff globl diff --git a/libc/sysv/calls/microstackshot.s b/libc/sysv/calls/microstackshot.s new file mode 100644 index 00000000..a19c5da6 --- /dev/null +++ b/libc/sysv/calls/microstackshot.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall microstackshot 0xffffffff21ecffff globl diff --git a/libc/sysv/calls/migrate_pages.s b/libc/sysv/calls/migrate_pages.s new file mode 100644 index 00000000..52c636bc --- /dev/null +++ b/libc/sysv/calls/migrate_pages.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall migrate_pages 0xffffffffffff0100 globl diff --git a/libc/sysv/calls/mincore.s b/libc/sysv/calls/mincore.s new file mode 100644 index 00000000..21a9f38f --- /dev/null +++ b/libc/sysv/calls/mincore.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mincore 0x004e004e204e001b globl diff --git a/libc/sysv/calls/minherit.s b/libc/sysv/calls/minherit.s new file mode 100644 index 00000000..50019725 --- /dev/null +++ b/libc/sysv/calls/minherit.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall minherit 0x00fa00fa20faffff globl diff --git a/libc/sysv/calls/mkdir-sysv.s b/libc/sysv/calls/mkdir-sysv.s new file mode 100644 index 00000000..be4a639b --- /dev/null +++ b/libc/sysv/calls/mkdir-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mkdir$sysv 0x0088008820880053 globl hidden diff --git a/libc/sysv/calls/mkdir_extended.s b/libc/sysv/calls/mkdir_extended.s new file mode 100644 index 00000000..8cfbb893 --- /dev/null +++ b/libc/sysv/calls/mkdir_extended.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mkdir_extended 0xffffffff2124ffff globl diff --git a/libc/sysv/calls/mkdirat-sysv.s b/libc/sysv/calls/mkdirat-sysv.s new file mode 100644 index 00000000..01412b86 --- /dev/null +++ b/libc/sysv/calls/mkdirat-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mkdirat$sysv 0x013e01f021db0102 globl hidden diff --git a/libc/sysv/calls/mkfifo-sysv.s b/libc/sysv/calls/mkfifo-sysv.s new file mode 100644 index 00000000..fee1c875 --- /dev/null +++ b/libc/sysv/calls/mkfifo-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mkfifo$sysv 0x008400842084ffff globl hidden diff --git a/libc/sysv/calls/mkfifo_extended.s b/libc/sysv/calls/mkfifo_extended.s new file mode 100644 index 00000000..33b7ef61 --- /dev/null +++ b/libc/sysv/calls/mkfifo_extended.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mkfifo_extended 0xffffffff2123ffff globl diff --git a/libc/sysv/calls/mkfifoat.s b/libc/sysv/calls/mkfifoat.s new file mode 100644 index 00000000..a8f779ca --- /dev/null +++ b/libc/sysv/calls/mkfifoat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mkfifoat 0x013f01f1ffffffff globl diff --git a/libc/sysv/calls/mknod-sysv.s b/libc/sysv/calls/mknod-sysv.s new file mode 100644 index 00000000..24084e3b --- /dev/null +++ b/libc/sysv/calls/mknod-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mknod$sysv 0x000e000e200e0085 globl hidden diff --git a/libc/sysv/calls/mknodat.s b/libc/sysv/calls/mknodat.s new file mode 100644 index 00000000..7fb86718 --- /dev/null +++ b/libc/sysv/calls/mknodat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mknodat 0x014022ffffff0103 globl diff --git a/libc/sysv/calls/mlock.s b/libc/sysv/calls/mlock.s new file mode 100644 index 00000000..d91d2b20 --- /dev/null +++ b/libc/sysv/calls/mlock.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mlock 0x00cb00cb20cb0095 globl diff --git a/libc/sysv/calls/mlock2.s b/libc/sysv/calls/mlock2.s new file mode 100644 index 00000000..b7c9f8d5 --- /dev/null +++ b/libc/sysv/calls/mlock2.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mlock2 0xffffffffffff0145 globl diff --git a/libc/sysv/calls/mlockall.s b/libc/sysv/calls/mlockall.s new file mode 100644 index 00000000..223957ab --- /dev/null +++ b/libc/sysv/calls/mlockall.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mlockall 0x010f014421440097 globl diff --git a/libc/sysv/calls/modfind.s b/libc/sysv/calls/modfind.s new file mode 100644 index 00000000..2cace045 --- /dev/null +++ b/libc/sysv/calls/modfind.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall modfind 0xffff012fffffffff globl diff --git a/libc/sysv/calls/modfnext.s b/libc/sysv/calls/modfnext.s new file mode 100644 index 00000000..5cc72f25 --- /dev/null +++ b/libc/sysv/calls/modfnext.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall modfnext 0xffff012effffffff globl diff --git a/libc/sysv/calls/modify_ldt.s b/libc/sysv/calls/modify_ldt.s new file mode 100644 index 00000000..0ea9798c --- /dev/null +++ b/libc/sysv/calls/modify_ldt.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall modify_ldt 0xffffffffffff009a globl diff --git a/libc/sysv/calls/modnext.s b/libc/sysv/calls/modnext.s new file mode 100644 index 00000000..0bcccdc7 --- /dev/null +++ b/libc/sysv/calls/modnext.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall modnext 0xffff012cffffffff globl diff --git a/libc/sysv/calls/modstat.s b/libc/sysv/calls/modstat.s new file mode 100644 index 00000000..de58ae98 --- /dev/null +++ b/libc/sysv/calls/modstat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall modstat 0xffff012dffffffff globl diff --git a/libc/sysv/calls/modwatch.s b/libc/sysv/calls/modwatch.s new file mode 100644 index 00000000..fdcae7e5 --- /dev/null +++ b/libc/sysv/calls/modwatch.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall modwatch 0xffffffff20e9ffff globl diff --git a/libc/sysv/calls/mount.s b/libc/sysv/calls/mount.s new file mode 100644 index 00000000..71442a13 --- /dev/null +++ b/libc/sysv/calls/mount.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mount 0x0015001520a700a5 globl diff --git a/libc/sysv/calls/move_pages.s b/libc/sysv/calls/move_pages.s new file mode 100644 index 00000000..791506fd --- /dev/null +++ b/libc/sysv/calls/move_pages.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall move_pages 0xffffffffffff0117 globl diff --git a/libc/sysv/calls/mprotect-sysv.s b/libc/sysv/calls/mprotect-sysv.s new file mode 100644 index 00000000..9e9ab8e9 --- /dev/null +++ b/libc/sysv/calls/mprotect-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mprotect$sysv 0x004a004a204a000a globl hidden diff --git a/libc/sysv/calls/mq_getsetattr.s b/libc/sysv/calls/mq_getsetattr.s new file mode 100644 index 00000000..7d9924d4 --- /dev/null +++ b/libc/sysv/calls/mq_getsetattr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mq_getsetattr 0xffffffffffff00f5 globl diff --git a/libc/sysv/calls/mq_notify.s b/libc/sysv/calls/mq_notify.s new file mode 100644 index 00000000..8b6c0d5e --- /dev/null +++ b/libc/sysv/calls/mq_notify.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mq_notify 0xffffffffffff00f4 globl diff --git a/libc/sysv/calls/mq_open.s b/libc/sysv/calls/mq_open.s new file mode 100644 index 00000000..61aafc76 --- /dev/null +++ b/libc/sysv/calls/mq_open.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mq_open 0xffffffffffff00f0 globl diff --git a/libc/sysv/calls/mq_timedreceive.s b/libc/sysv/calls/mq_timedreceive.s new file mode 100644 index 00000000..007ee947 --- /dev/null +++ b/libc/sysv/calls/mq_timedreceive.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mq_timedreceive 0xffffffffffff00f3 globl diff --git a/libc/sysv/calls/mq_timedsend.s b/libc/sysv/calls/mq_timedsend.s new file mode 100644 index 00000000..a213ba39 --- /dev/null +++ b/libc/sysv/calls/mq_timedsend.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mq_timedsend 0xffffffffffff00f2 globl diff --git a/libc/sysv/calls/mq_unlink.s b/libc/sysv/calls/mq_unlink.s new file mode 100644 index 00000000..c5d22197 --- /dev/null +++ b/libc/sysv/calls/mq_unlink.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mq_unlink 0xffffffffffff00f1 globl diff --git a/libc/sysv/calls/mquery.s b/libc/sysv/calls/mquery.s new file mode 100644 index 00000000..23d71702 --- /dev/null +++ b/libc/sysv/calls/mquery.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mquery 0x011effffffffffff globl diff --git a/libc/sysv/calls/mremap-sysv.s b/libc/sysv/calls/mremap-sysv.s new file mode 100644 index 00000000..bc822e0f --- /dev/null +++ b/libc/sysv/calls/mremap-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mremap$sysv 0xffffffffffff0019 globl hidden diff --git a/libc/sysv/calls/mremap_encrypted.s b/libc/sysv/calls/mremap_encrypted.s new file mode 100644 index 00000000..cb236414 --- /dev/null +++ b/libc/sysv/calls/mremap_encrypted.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mremap_encrypted 0xffffffff21e9ffff globl diff --git a/libc/sysv/calls/msgctl.s b/libc/sysv/calls/msgctl.s new file mode 100644 index 00000000..124c4d30 --- /dev/null +++ b/libc/sysv/calls/msgctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall msgctl 0x012901ff21020047 globl diff --git a/libc/sysv/calls/msgget.s b/libc/sysv/calls/msgget.s new file mode 100644 index 00000000..5d72de64 --- /dev/null +++ b/libc/sysv/calls/msgget.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall msgget 0x00e100e121030044 globl diff --git a/libc/sysv/calls/msgrcv.s b/libc/sysv/calls/msgrcv.s new file mode 100644 index 00000000..9cc60e42 --- /dev/null +++ b/libc/sysv/calls/msgrcv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall msgrcv 0x00e300e321050046 globl diff --git a/libc/sysv/calls/msgrcv_nocancel.s b/libc/sysv/calls/msgrcv_nocancel.s new file mode 100644 index 00000000..142449f8 --- /dev/null +++ b/libc/sysv/calls/msgrcv_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall msgrcv_nocancel 0xffffffff21a3ffff globl diff --git a/libc/sysv/calls/msgsnd.s b/libc/sysv/calls/msgsnd.s new file mode 100644 index 00000000..378d6490 --- /dev/null +++ b/libc/sysv/calls/msgsnd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall msgsnd 0x00e200e221040045 globl diff --git a/libc/sysv/calls/msgsnd_nocancel.s b/libc/sysv/calls/msgsnd_nocancel.s new file mode 100644 index 00000000..cd452e25 --- /dev/null +++ b/libc/sysv/calls/msgsnd_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall msgsnd_nocancel 0xffffffff21a2ffff globl diff --git a/libc/sysv/calls/msgsys.s b/libc/sysv/calls/msgsys.s new file mode 100644 index 00000000..e21f3d8d --- /dev/null +++ b/libc/sysv/calls/msgsys.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall msgsys 0xffff00aa20fcffff globl diff --git a/libc/sysv/calls/msync-sysv.s b/libc/sysv/calls/msync-sysv.s new file mode 100644 index 00000000..ca4efad2 --- /dev/null +++ b/libc/sysv/calls/msync-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall msync$sysv 0x010000412041001a globl hidden diff --git a/libc/sysv/calls/msync_nocancel.s b/libc/sysv/calls/msync_nocancel.s new file mode 100644 index 00000000..00f28381 --- /dev/null +++ b/libc/sysv/calls/msync_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall msync_nocancel 0xffffffff2195ffff globl diff --git a/libc/sysv/calls/munlock.s b/libc/sysv/calls/munlock.s new file mode 100644 index 00000000..81335b29 --- /dev/null +++ b/libc/sysv/calls/munlock.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall munlock 0x00cc00cc20cc0096 globl diff --git a/libc/sysv/calls/munlockall.s b/libc/sysv/calls/munlockall.s new file mode 100644 index 00000000..602318f8 --- /dev/null +++ b/libc/sysv/calls/munlockall.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall munlockall 0x0110014521450098 globl diff --git a/libc/sysv/calls/munmap-sysv.s b/libc/sysv/calls/munmap-sysv.s new file mode 100644 index 00000000..3639b704 --- /dev/null +++ b/libc/sysv/calls/munmap-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall munmap$sysv 0x004900492049000b globl hidden diff --git a/libc/sysv/calls/name_to_handle_at.s b/libc/sysv/calls/name_to_handle_at.s new file mode 100644 index 00000000..0b1684a8 --- /dev/null +++ b/libc/sysv/calls/name_to_handle_at.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall name_to_handle_at 0xffffffffffff012f globl diff --git a/libc/sysv/calls/nanosleep-sysv.s b/libc/sysv/calls/nanosleep-sysv.s new file mode 100644 index 00000000..84439159 --- /dev/null +++ b/libc/sysv/calls/nanosleep-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall nanosleep$sysv 0x005b00f0ffff0023 globl hidden diff --git a/libc/sysv/calls/necp_client_action.s b/libc/sysv/calls/necp_client_action.s new file mode 100644 index 00000000..a5790b84 --- /dev/null +++ b/libc/sysv/calls/necp_client_action.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall necp_client_action 0xffffffff21f6ffff globl diff --git a/libc/sysv/calls/necp_match_policy.s b/libc/sysv/calls/necp_match_policy.s new file mode 100644 index 00000000..87674229 --- /dev/null +++ b/libc/sysv/calls/necp_match_policy.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall necp_match_policy 0xffffffff21ccffff globl diff --git a/libc/sysv/calls/necp_open.s b/libc/sysv/calls/necp_open.s new file mode 100644 index 00000000..3539cb56 --- /dev/null +++ b/libc/sysv/calls/necp_open.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall necp_open 0xffffffff21f5ffff globl diff --git a/libc/sysv/calls/necp_session_action.s b/libc/sysv/calls/necp_session_action.s new file mode 100644 index 00000000..68b32519 --- /dev/null +++ b/libc/sysv/calls/necp_session_action.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall necp_session_action 0xffffffff220bffff globl diff --git a/libc/sysv/calls/necp_session_open.s b/libc/sysv/calls/necp_session_open.s new file mode 100644 index 00000000..c5fa367c --- /dev/null +++ b/libc/sysv/calls/necp_session_open.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall necp_session_open 0xffffffff220affff globl diff --git a/libc/sysv/calls/net_qos_guideline.s b/libc/sysv/calls/net_qos_guideline.s new file mode 100644 index 00000000..b7b3e9e3 --- /dev/null +++ b/libc/sysv/calls/net_qos_guideline.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall net_qos_guideline 0xffffffff220dffff globl diff --git a/libc/sysv/calls/netagent_trigger.s b/libc/sysv/calls/netagent_trigger.s new file mode 100644 index 00000000..45d223f3 --- /dev/null +++ b/libc/sysv/calls/netagent_trigger.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall netagent_trigger 0xffffffff21eaffff globl diff --git a/libc/sysv/calls/nfsclnt.s b/libc/sysv/calls/nfsclnt.s new file mode 100644 index 00000000..f3ac87cd --- /dev/null +++ b/libc/sysv/calls/nfsclnt.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall nfsclnt 0xffffffff20f7ffff globl diff --git a/libc/sysv/calls/nfssvc.s b/libc/sysv/calls/nfssvc.s new file mode 100644 index 00000000..975826c0 --- /dev/null +++ b/libc/sysv/calls/nfssvc.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall nfssvc 0x009b009b209bffff globl diff --git a/libc/sysv/calls/nfstat.s b/libc/sysv/calls/nfstat.s new file mode 100644 index 00000000..9acc3fc1 --- /dev/null +++ b/libc/sysv/calls/nfstat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall nfstat 0xffff0117ffffffff globl diff --git a/libc/sysv/calls/nlm_syscall.s b/libc/sysv/calls/nlm_syscall.s new file mode 100644 index 00000000..19c629d9 --- /dev/null +++ b/libc/sysv/calls/nlm_syscall.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall nlm_syscall 0xffff009affffffff globl diff --git a/libc/sysv/calls/nlstat.s b/libc/sysv/calls/nlstat.s new file mode 100644 index 00000000..a1351b75 --- /dev/null +++ b/libc/sysv/calls/nlstat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall nlstat 0xffff0118ffffffff globl diff --git a/libc/sysv/calls/nmount.s b/libc/sysv/calls/nmount.s new file mode 100644 index 00000000..cbc84c25 --- /dev/null +++ b/libc/sysv/calls/nmount.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall nmount 0xffff017affffffff globl diff --git a/libc/sysv/calls/nnpfs_syscall.s b/libc/sysv/calls/nnpfs_syscall.s new file mode 100644 index 00000000..c49ee217 --- /dev/null +++ b/libc/sysv/calls/nnpfs_syscall.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall nnpfs_syscall 0xffff0153ffffffff globl diff --git a/libc/sysv/calls/nstat.s b/libc/sysv/calls/nstat.s new file mode 100644 index 00000000..e393c005 --- /dev/null +++ b/libc/sysv/calls/nstat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall nstat 0xffff0116ffffffff globl diff --git a/libc/sysv/calls/ntp_adjtime.s b/libc/sysv/calls/ntp_adjtime.s new file mode 100644 index 00000000..a4c53949 --- /dev/null +++ b/libc/sysv/calls/ntp_adjtime.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ntp_adjtime 0xffff00b0220fffff globl diff --git a/libc/sysv/calls/ntp_gettime.s b/libc/sysv/calls/ntp_gettime.s new file mode 100644 index 00000000..1a6f97ba --- /dev/null +++ b/libc/sysv/calls/ntp_gettime.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ntp_gettime 0xffff00f82210ffff globl diff --git a/libc/sysv/calls/obreak.s b/libc/sysv/calls/obreak.s new file mode 100644 index 00000000..cbf83c63 --- /dev/null +++ b/libc/sysv/calls/obreak.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall obreak 0x0011ffffffffffff globl diff --git a/libc/sysv/calls/open-sysv.s b/libc/sysv/calls/open-sysv.s new file mode 100644 index 00000000..724a61ab --- /dev/null +++ b/libc/sysv/calls/open-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall open$sysv 0x0005000520050002 globl hidden diff --git a/libc/sysv/calls/open_by_handle_at.s b/libc/sysv/calls/open_by_handle_at.s new file mode 100644 index 00000000..59e58542 --- /dev/null +++ b/libc/sysv/calls/open_by_handle_at.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall open_by_handle_at 0xffffffffffff0130 globl diff --git a/libc/sysv/calls/open_dprotected_np.s b/libc/sysv/calls/open_dprotected_np.s new file mode 100644 index 00000000..b3323d1c --- /dev/null +++ b/libc/sysv/calls/open_dprotected_np.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall open_dprotected_np 0xffffffff20d8ffff globl diff --git a/libc/sysv/calls/open_extended.s b/libc/sysv/calls/open_extended.s new file mode 100644 index 00000000..ab387a8d --- /dev/null +++ b/libc/sysv/calls/open_extended.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall open_extended 0xffffffff2115ffff globl diff --git a/libc/sysv/calls/open_nocancel.s b/libc/sysv/calls/open_nocancel.s new file mode 100644 index 00000000..92e3079e --- /dev/null +++ b/libc/sysv/calls/open_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall open_nocancel 0xffffffff218effff globl diff --git a/libc/sysv/calls/openat-sysv.s b/libc/sysv/calls/openat-sysv.s new file mode 100644 index 00000000..3328c9bd --- /dev/null +++ b/libc/sysv/calls/openat-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall openat$sysv 0x014101f321cf0101 globl hidden diff --git a/libc/sysv/calls/openat_nocancel.s b/libc/sysv/calls/openat_nocancel.s new file mode 100644 index 00000000..eeafbca7 --- /dev/null +++ b/libc/sysv/calls/openat_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall openat_nocancel 0xffffffff21d0ffff globl diff --git a/libc/sysv/calls/openbyid_np.s b/libc/sysv/calls/openbyid_np.s new file mode 100644 index 00000000..2bed67ab --- /dev/null +++ b/libc/sysv/calls/openbyid_np.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall openbyid_np 0xffffffff21dfffff globl diff --git a/libc/sysv/calls/os_fault_with_payload.s b/libc/sysv/calls/os_fault_with_payload.s new file mode 100644 index 00000000..9e786a26 --- /dev/null +++ b/libc/sysv/calls/os_fault_with_payload.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall os_fault_with_payload 0xffffffff2211ffff globl diff --git a/libc/sysv/calls/pathconf.s b/libc/sysv/calls/pathconf.s new file mode 100644 index 00000000..193007d0 --- /dev/null +++ b/libc/sysv/calls/pathconf.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pathconf 0x00bf00bf20bfffff globl diff --git a/libc/sysv/calls/pause-sysv.s b/libc/sysv/calls/pause-sysv.s new file mode 100644 index 00000000..0c491fd4 --- /dev/null +++ b/libc/sysv/calls/pause-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pause$sysv 0xffffffffffff0022 globl hidden diff --git a/libc/sysv/calls/pdfork.s b/libc/sysv/calls/pdfork.s new file mode 100644 index 00000000..1f9ab24d --- /dev/null +++ b/libc/sysv/calls/pdfork.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pdfork 0xffff0206ffffffff globl diff --git a/libc/sysv/calls/pdgetpid.s b/libc/sysv/calls/pdgetpid.s new file mode 100644 index 00000000..c8ebd86e --- /dev/null +++ b/libc/sysv/calls/pdgetpid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pdgetpid 0xffff0208ffffffff globl diff --git a/libc/sysv/calls/pdkill.s b/libc/sysv/calls/pdkill.s new file mode 100644 index 00000000..7ee65a73 --- /dev/null +++ b/libc/sysv/calls/pdkill.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pdkill 0xffff0207ffffffff globl diff --git a/libc/sysv/calls/peeloff.s b/libc/sysv/calls/peeloff.s new file mode 100644 index 00000000..fd184d6b --- /dev/null +++ b/libc/sysv/calls/peeloff.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall peeloff 0xffffffff21c1ffff globl diff --git a/libc/sysv/calls/perf_event_open.s b/libc/sysv/calls/perf_event_open.s new file mode 100644 index 00000000..b5500de8 --- /dev/null +++ b/libc/sysv/calls/perf_event_open.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall perf_event_open 0xffffffffffff012a globl diff --git a/libc/sysv/calls/persona.s b/libc/sysv/calls/persona.s new file mode 100644 index 00000000..da697a71 --- /dev/null +++ b/libc/sysv/calls/persona.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall persona 0xffffffff21eeffff globl diff --git a/libc/sysv/calls/personality.s b/libc/sysv/calls/personality.s new file mode 100644 index 00000000..36cade3a --- /dev/null +++ b/libc/sysv/calls/personality.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall personality 0xffffffffffff0087 globl diff --git a/libc/sysv/calls/pid_hibernate.s b/libc/sysv/calls/pid_hibernate.s new file mode 100644 index 00000000..697bbdce --- /dev/null +++ b/libc/sysv/calls/pid_hibernate.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pid_hibernate 0xffffffff21b3ffff globl diff --git a/libc/sysv/calls/pid_resume.s b/libc/sysv/calls/pid_resume.s new file mode 100644 index 00000000..d2157cbf --- /dev/null +++ b/libc/sysv/calls/pid_resume.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pid_resume 0xffffffff21b2ffff globl diff --git a/libc/sysv/calls/pid_shutdown_sockets.s b/libc/sysv/calls/pid_shutdown_sockets.s new file mode 100644 index 00000000..d92440ef --- /dev/null +++ b/libc/sysv/calls/pid_shutdown_sockets.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pid_shutdown_sockets 0xffffffff21b4ffff globl diff --git a/libc/sysv/calls/pid_suspend.s b/libc/sysv/calls/pid_suspend.s new file mode 100644 index 00000000..33b25927 --- /dev/null +++ b/libc/sysv/calls/pid_suspend.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pid_suspend 0xffffffff21b1ffff globl diff --git a/libc/sysv/calls/pidfd_send_signal.s b/libc/sysv/calls/pidfd_send_signal.s new file mode 100644 index 00000000..ae0714ee --- /dev/null +++ b/libc/sysv/calls/pidfd_send_signal.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pidfd_send_signal 0xffffffffffff01a8 globl diff --git a/libc/sysv/calls/pivot_root.s b/libc/sysv/calls/pivot_root.s new file mode 100644 index 00000000..6b91b74c --- /dev/null +++ b/libc/sysv/calls/pivot_root.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pivot_root 0xffffffffffff009b globl diff --git a/libc/sysv/calls/pkey_alloc.s b/libc/sysv/calls/pkey_alloc.s new file mode 100644 index 00000000..9f92fde6 --- /dev/null +++ b/libc/sysv/calls/pkey_alloc.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pkey_alloc 0xffffffffffff014a globl diff --git a/libc/sysv/calls/pkey_free.s b/libc/sysv/calls/pkey_free.s new file mode 100644 index 00000000..8d05e030 --- /dev/null +++ b/libc/sysv/calls/pkey_free.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pkey_free 0xffffffffffff014b globl diff --git a/libc/sysv/calls/pkey_mprotect.s b/libc/sysv/calls/pkey_mprotect.s new file mode 100644 index 00000000..b3ea8695 --- /dev/null +++ b/libc/sysv/calls/pkey_mprotect.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pkey_mprotect 0xffffffffffff0149 globl diff --git a/libc/sysv/calls/pledge.s b/libc/sysv/calls/pledge.s new file mode 100644 index 00000000..55301f78 --- /dev/null +++ b/libc/sysv/calls/pledge.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pledge 0x006cffffffffffff globl diff --git a/libc/sysv/calls/poll-sysv.s b/libc/sysv/calls/poll-sysv.s new file mode 100644 index 00000000..a40153e1 --- /dev/null +++ b/libc/sysv/calls/poll-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall poll$sysv 0x00fc00d120e60007 globl hidden diff --git a/libc/sysv/calls/poll_nocancel.s b/libc/sysv/calls/poll_nocancel.s new file mode 100644 index 00000000..498204f2 --- /dev/null +++ b/libc/sysv/calls/poll_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall poll_nocancel 0xffffffff21a1ffff globl diff --git a/libc/sysv/calls/posix_fallocate-sysv.s b/libc/sysv/calls/posix_fallocate-sysv.s new file mode 100644 index 00000000..73d508e7 --- /dev/null +++ b/libc/sysv/calls/posix_fallocate-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall posix_fallocate$sysv 0xffff0212ffffffff globl hidden diff --git a/libc/sysv/calls/posix_openpt-sysv.s b/libc/sysv/calls/posix_openpt-sysv.s new file mode 100644 index 00000000..cf1a664f --- /dev/null +++ b/libc/sysv/calls/posix_openpt-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall posix_openpt$sysv 0xffff01f8ffffffff globl hidden diff --git a/libc/sysv/calls/posix_spawn.s b/libc/sysv/calls/posix_spawn.s new file mode 100644 index 00000000..c04c991a --- /dev/null +++ b/libc/sysv/calls/posix_spawn.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall posix_spawn 0xffffffff20f4ffff globl hidden diff --git a/libc/sysv/calls/ppoll-sysv.s b/libc/sysv/calls/ppoll-sysv.s new file mode 100644 index 00000000..b9b5d52c --- /dev/null +++ b/libc/sysv/calls/ppoll-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ppoll$sysv 0x006d0221ffff010f globl hidden diff --git a/libc/sysv/calls/prctl.s b/libc/sysv/calls/prctl.s new file mode 100644 index 00000000..456666cd --- /dev/null +++ b/libc/sysv/calls/prctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall prctl 0xffffffffffff009d globl diff --git a/libc/sysv/calls/pread_nocancel.s b/libc/sysv/calls/pread_nocancel.s new file mode 100644 index 00000000..664071f1 --- /dev/null +++ b/libc/sysv/calls/pread_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pread_nocancel 0xffffffff219effff globl diff --git a/libc/sysv/calls/preadv2.s b/libc/sysv/calls/preadv2.s new file mode 100644 index 00000000..b1c3b8fc --- /dev/null +++ b/libc/sysv/calls/preadv2.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall preadv2 0xffffffffffff0147 globl diff --git a/libc/sysv/calls/prlimit.s b/libc/sysv/calls/prlimit.s new file mode 100644 index 00000000..9f30dfd5 --- /dev/null +++ b/libc/sysv/calls/prlimit.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall prlimit 0xffffffffffff012e globl diff --git a/libc/sysv/calls/proc_info.s b/libc/sysv/calls/proc_info.s new file mode 100644 index 00000000..78f79a62 --- /dev/null +++ b/libc/sysv/calls/proc_info.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall proc_info 0xffffffff2150ffff globl diff --git a/libc/sysv/calls/proc_rlimit_control.s b/libc/sysv/calls/proc_rlimit_control.s new file mode 100644 index 00000000..0c1ca75f --- /dev/null +++ b/libc/sysv/calls/proc_rlimit_control.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall proc_rlimit_control 0xffffffff21beffff globl diff --git a/libc/sysv/calls/proc_trace_log.s b/libc/sysv/calls/proc_trace_log.s new file mode 100644 index 00000000..639d9251 --- /dev/null +++ b/libc/sysv/calls/proc_trace_log.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall proc_trace_log 0xffffffff21ddffff globl diff --git a/libc/sysv/calls/proc_uuid_policy.s b/libc/sysv/calls/proc_uuid_policy.s new file mode 100644 index 00000000..3ad74c46 --- /dev/null +++ b/libc/sysv/calls/proc_uuid_policy.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall proc_uuid_policy 0xffffffff21c4ffff globl diff --git a/libc/sysv/calls/procctl.s b/libc/sysv/calls/procctl.s new file mode 100644 index 00000000..448fa9c0 --- /dev/null +++ b/libc/sysv/calls/procctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall procctl 0xffff0220ffffffff globl diff --git a/libc/sysv/calls/process_policy.s b/libc/sysv/calls/process_policy.s new file mode 100644 index 00000000..c59fecab --- /dev/null +++ b/libc/sysv/calls/process_policy.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall process_policy 0xffffffff2143ffff globl diff --git a/libc/sysv/calls/process_vm_readv.s b/libc/sysv/calls/process_vm_readv.s new file mode 100644 index 00000000..8d14e68b --- /dev/null +++ b/libc/sysv/calls/process_vm_readv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall process_vm_readv 0xffffffffffff0136 globl diff --git a/libc/sysv/calls/process_vm_writev.s b/libc/sysv/calls/process_vm_writev.s new file mode 100644 index 00000000..96459816 --- /dev/null +++ b/libc/sysv/calls/process_vm_writev.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall process_vm_writev 0xffffffffffff0137 globl diff --git a/libc/sysv/calls/profil.s b/libc/sysv/calls/profil.s new file mode 100644 index 00000000..4eb5e967 --- /dev/null +++ b/libc/sysv/calls/profil.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall profil 0x002c002cffffffff globl diff --git a/libc/sysv/calls/pselect.s b/libc/sysv/calls/pselect.s new file mode 100644 index 00000000..91dd9143 --- /dev/null +++ b/libc/sysv/calls/pselect.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pselect 0x006e020a218affff globl diff --git a/libc/sysv/calls/pselect6.s b/libc/sysv/calls/pselect6.s new file mode 100644 index 00000000..c39ab14e --- /dev/null +++ b/libc/sysv/calls/pselect6.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pselect6 0xffffffffffff010e globl diff --git a/libc/sysv/calls/pselect_nocancel.s b/libc/sysv/calls/pselect_nocancel.s new file mode 100644 index 00000000..2028d643 --- /dev/null +++ b/libc/sysv/calls/pselect_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pselect_nocancel 0xffffffff218bffff globl diff --git a/libc/sysv/calls/psynch_cvbroad.s b/libc/sysv/calls/psynch_cvbroad.s new file mode 100644 index 00000000..c11dd8d0 --- /dev/null +++ b/libc/sysv/calls/psynch_cvbroad.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall psynch_cvbroad 0xffffffff212fffff globl diff --git a/libc/sysv/calls/psynch_cvclrprepost.s b/libc/sysv/calls/psynch_cvclrprepost.s new file mode 100644 index 00000000..00c9a7f2 --- /dev/null +++ b/libc/sysv/calls/psynch_cvclrprepost.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall psynch_cvclrprepost 0xffffffff2138ffff globl diff --git a/libc/sysv/calls/psynch_cvsignal.s b/libc/sysv/calls/psynch_cvsignal.s new file mode 100644 index 00000000..df8ff368 --- /dev/null +++ b/libc/sysv/calls/psynch_cvsignal.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall psynch_cvsignal 0xffffffff2130ffff globl diff --git a/libc/sysv/calls/psynch_cvwait.s b/libc/sysv/calls/psynch_cvwait.s new file mode 100644 index 00000000..2054052f --- /dev/null +++ b/libc/sysv/calls/psynch_cvwait.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall psynch_cvwait 0xffffffff2131ffff globl diff --git a/libc/sysv/calls/psynch_mutexdrop.s b/libc/sysv/calls/psynch_mutexdrop.s new file mode 100644 index 00000000..f2270dd0 --- /dev/null +++ b/libc/sysv/calls/psynch_mutexdrop.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall psynch_mutexdrop 0xffffffff212effff globl diff --git a/libc/sysv/calls/psynch_mutexwait.s b/libc/sysv/calls/psynch_mutexwait.s new file mode 100644 index 00000000..bdca772b --- /dev/null +++ b/libc/sysv/calls/psynch_mutexwait.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall psynch_mutexwait 0xffffffff212dffff globl diff --git a/libc/sysv/calls/psynch_rw_downgrade.s b/libc/sysv/calls/psynch_rw_downgrade.s new file mode 100644 index 00000000..f4daa10f --- /dev/null +++ b/libc/sysv/calls/psynch_rw_downgrade.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall psynch_rw_downgrade 0xffffffff212bffff globl diff --git a/libc/sysv/calls/psynch_rw_longrdlock.s b/libc/sysv/calls/psynch_rw_longrdlock.s new file mode 100644 index 00000000..7c55caf5 --- /dev/null +++ b/libc/sysv/calls/psynch_rw_longrdlock.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall psynch_rw_longrdlock 0xffffffff2129ffff globl diff --git a/libc/sysv/calls/psynch_rw_rdlock.s b/libc/sysv/calls/psynch_rw_rdlock.s new file mode 100644 index 00000000..22a7fa0b --- /dev/null +++ b/libc/sysv/calls/psynch_rw_rdlock.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall psynch_rw_rdlock 0xffffffff2132ffff globl diff --git a/libc/sysv/calls/psynch_rw_unlock.s b/libc/sysv/calls/psynch_rw_unlock.s new file mode 100644 index 00000000..2474cc9c --- /dev/null +++ b/libc/sysv/calls/psynch_rw_unlock.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall psynch_rw_unlock 0xffffffff2134ffff globl diff --git a/libc/sysv/calls/psynch_rw_unlock2.s b/libc/sysv/calls/psynch_rw_unlock2.s new file mode 100644 index 00000000..9e58f7ae --- /dev/null +++ b/libc/sysv/calls/psynch_rw_unlock2.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall psynch_rw_unlock2 0xffffffff2135ffff globl diff --git a/libc/sysv/calls/psynch_rw_upgrade.s b/libc/sysv/calls/psynch_rw_upgrade.s new file mode 100644 index 00000000..923d81cc --- /dev/null +++ b/libc/sysv/calls/psynch_rw_upgrade.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall psynch_rw_upgrade 0xffffffff212cffff globl diff --git a/libc/sysv/calls/psynch_rw_wrlock.s b/libc/sysv/calls/psynch_rw_wrlock.s new file mode 100644 index 00000000..79404be0 --- /dev/null +++ b/libc/sysv/calls/psynch_rw_wrlock.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall psynch_rw_wrlock 0xffffffff2133ffff globl diff --git a/libc/sysv/calls/psynch_rw_yieldwrlock.s b/libc/sysv/calls/psynch_rw_yieldwrlock.s new file mode 100644 index 00000000..99286e0b --- /dev/null +++ b/libc/sysv/calls/psynch_rw_yieldwrlock.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall psynch_rw_yieldwrlock 0xffffffff212affff globl diff --git a/libc/sysv/calls/ptrace.s b/libc/sysv/calls/ptrace.s new file mode 100644 index 00000000..a87cca4c --- /dev/null +++ b/libc/sysv/calls/ptrace.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ptrace 0x001a001a201a0065 globl diff --git a/libc/sysv/calls/pwrite_nocancel.s b/libc/sysv/calls/pwrite_nocancel.s new file mode 100644 index 00000000..6c0fbd36 --- /dev/null +++ b/libc/sysv/calls/pwrite_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pwrite_nocancel 0xffffffff219fffff globl diff --git a/libc/sysv/calls/pwritev2.s b/libc/sysv/calls/pwritev2.s new file mode 100644 index 00000000..d9c74fc0 --- /dev/null +++ b/libc/sysv/calls/pwritev2.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pwritev2 0xffffffffffff0148 globl diff --git a/libc/sysv/calls/quota.s b/libc/sysv/calls/quota.s new file mode 100644 index 00000000..1d8f2490 --- /dev/null +++ b/libc/sysv/calls/quota.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall quota 0xffff0095ffffffff globl diff --git a/libc/sysv/calls/quotactl.s b/libc/sysv/calls/quotactl.s new file mode 100644 index 00000000..614f700a --- /dev/null +++ b/libc/sysv/calls/quotactl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall quotactl 0x0094009420a500b3 globl diff --git a/libc/sysv/calls/rctl_add_rule.s b/libc/sysv/calls/rctl_add_rule.s new file mode 100644 index 00000000..026d297c --- /dev/null +++ b/libc/sysv/calls/rctl_add_rule.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall rctl_add_rule 0xffff0210ffffffff globl diff --git a/libc/sysv/calls/rctl_get_limits.s b/libc/sysv/calls/rctl_get_limits.s new file mode 100644 index 00000000..2ec50b4c --- /dev/null +++ b/libc/sysv/calls/rctl_get_limits.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall rctl_get_limits 0xffff020fffffffff globl diff --git a/libc/sysv/calls/rctl_get_racct.s b/libc/sysv/calls/rctl_get_racct.s new file mode 100644 index 00000000..d668276c --- /dev/null +++ b/libc/sysv/calls/rctl_get_racct.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall rctl_get_racct 0xffff020dffffffff globl diff --git a/libc/sysv/calls/rctl_get_rules.s b/libc/sysv/calls/rctl_get_rules.s new file mode 100644 index 00000000..40b659b1 --- /dev/null +++ b/libc/sysv/calls/rctl_get_rules.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall rctl_get_rules 0xffff020effffffff globl diff --git a/libc/sysv/calls/rctl_remove_rule.s b/libc/sysv/calls/rctl_remove_rule.s new file mode 100644 index 00000000..52a6576f --- /dev/null +++ b/libc/sysv/calls/rctl_remove_rule.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall rctl_remove_rule 0xffff0211ffffffff globl diff --git a/libc/sysv/calls/read-sysv.s b/libc/sysv/calls/read-sysv.s new file mode 100644 index 00000000..bf0d36de --- /dev/null +++ b/libc/sysv/calls/read-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall read$sysv 0x0003000320030000 globl hidden diff --git a/libc/sysv/calls/read_nocancel.s b/libc/sysv/calls/read_nocancel.s new file mode 100644 index 00000000..00f1b82a --- /dev/null +++ b/libc/sysv/calls/read_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall read_nocancel 0xffffffff218cffff globl diff --git a/libc/sysv/calls/readahead.s b/libc/sysv/calls/readahead.s new file mode 100644 index 00000000..2cd10057 --- /dev/null +++ b/libc/sysv/calls/readahead.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall readahead 0xffffffffffff00bb globl diff --git a/libc/sysv/calls/readlink.s b/libc/sysv/calls/readlink.s new file mode 100644 index 00000000..1fdb38fb --- /dev/null +++ b/libc/sysv/calls/readlink.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall readlink 0x003a003a203a0059 globl diff --git a/libc/sysv/calls/readlinkat-sysv.s b/libc/sysv/calls/readlinkat-sysv.s new file mode 100644 index 00000000..102387ef --- /dev/null +++ b/libc/sysv/calls/readlinkat-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall readlinkat$sysv 0x014201f421d9010b globl hidden diff --git a/libc/sysv/calls/readv-sysv.s b/libc/sysv/calls/readv-sysv.s new file mode 100644 index 00000000..d2ec9b02 --- /dev/null +++ b/libc/sysv/calls/readv-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall readv$sysv 0x0078007820780013 globl hidden diff --git a/libc/sysv/calls/readv_nocancel.s b/libc/sysv/calls/readv_nocancel.s new file mode 100644 index 00000000..71e5da8e --- /dev/null +++ b/libc/sysv/calls/readv_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall readv_nocancel 0xffffffff219bffff globl diff --git a/libc/sysv/calls/reboot.s b/libc/sysv/calls/reboot.s new file mode 100644 index 00000000..b8e24c6d --- /dev/null +++ b/libc/sysv/calls/reboot.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall reboot 0x00370037203700a9 globl diff --git a/libc/sysv/calls/recv.s b/libc/sysv/calls/recv.s new file mode 100644 index 00000000..41b4144b --- /dev/null +++ b/libc/sysv/calls/recv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall recv 0xffff0066ffffffff globl diff --git a/libc/sysv/calls/recvfrom-sysv.s b/libc/sysv/calls/recvfrom-sysv.s new file mode 100644 index 00000000..d3f69b58 --- /dev/null +++ b/libc/sysv/calls/recvfrom-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall recvfrom$sysv 0x001d001d201d002d globl hidden diff --git a/libc/sysv/calls/recvfrom_nocancel.s b/libc/sysv/calls/recvfrom_nocancel.s new file mode 100644 index 00000000..81191d93 --- /dev/null +++ b/libc/sysv/calls/recvfrom_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall recvfrom_nocancel 0xffffffff2193ffff globl diff --git a/libc/sysv/calls/recvmmsg.s b/libc/sysv/calls/recvmmsg.s new file mode 100644 index 00000000..a8245e2e --- /dev/null +++ b/libc/sysv/calls/recvmmsg.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall recvmmsg 0xffffffffffff012b globl diff --git a/libc/sysv/calls/recvmsg-sysv.s b/libc/sysv/calls/recvmsg-sysv.s new file mode 100644 index 00000000..b25d9822 --- /dev/null +++ b/libc/sysv/calls/recvmsg-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall recvmsg$sysv 0x001b001b201b002f globl hidden diff --git a/libc/sysv/calls/recvmsg_nocancel.s b/libc/sysv/calls/recvmsg_nocancel.s new file mode 100644 index 00000000..4bb7e5d7 --- /dev/null +++ b/libc/sysv/calls/recvmsg_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall recvmsg_nocancel 0xffffffff2191ffff globl diff --git a/libc/sysv/calls/recvmsg_x.s b/libc/sysv/calls/recvmsg_x.s new file mode 100644 index 00000000..c24bce4b --- /dev/null +++ b/libc/sysv/calls/recvmsg_x.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall recvmsg_x 0xffffffff21e0ffff globl diff --git a/libc/sysv/calls/removexattr.s b/libc/sysv/calls/removexattr.s new file mode 100644 index 00000000..0b3bfb6c --- /dev/null +++ b/libc/sysv/calls/removexattr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall removexattr 0xffffffff20ee00c5 globl diff --git a/libc/sysv/calls/rename-sysv.s b/libc/sysv/calls/rename-sysv.s new file mode 100644 index 00000000..e6ed5555 --- /dev/null +++ b/libc/sysv/calls/rename-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall rename$sysv 0x0080008020800052 globl hidden diff --git a/libc/sysv/calls/renameat-sysv.s b/libc/sysv/calls/renameat-sysv.s new file mode 100644 index 00000000..db15e7b5 --- /dev/null +++ b/libc/sysv/calls/renameat-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall renameat$sysv 0x014301f521d10108 globl hidden diff --git a/libc/sysv/calls/renameat2.s b/libc/sysv/calls/renameat2.s new file mode 100644 index 00000000..ebfd5327 --- /dev/null +++ b/libc/sysv/calls/renameat2.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall renameat2 0xffffffffffff013c globl diff --git a/libc/sysv/calls/renameatx_np.s b/libc/sysv/calls/renameatx_np.s new file mode 100644 index 00000000..d8ee7619 --- /dev/null +++ b/libc/sysv/calls/renameatx_np.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall renameatx_np 0xffffffff21e8ffff globl diff --git a/libc/sysv/calls/request_key.s b/libc/sysv/calls/request_key.s new file mode 100644 index 00000000..1aae0c2c --- /dev/null +++ b/libc/sysv/calls/request_key.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall request_key 0xffffffffffff00f9 globl diff --git a/libc/sysv/calls/restart_syscall.s b/libc/sysv/calls/restart_syscall.s new file mode 100644 index 00000000..b7f0f3e0 --- /dev/null +++ b/libc/sysv/calls/restart_syscall.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall restart_syscall 0xffffffffffff00db globl diff --git a/libc/sysv/calls/revoke.s b/libc/sysv/calls/revoke.s new file mode 100644 index 00000000..f2923abc --- /dev/null +++ b/libc/sysv/calls/revoke.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall revoke 0x003800382038ffff globl diff --git a/libc/sysv/calls/rfork.s b/libc/sysv/calls/rfork.s new file mode 100644 index 00000000..58d10bb4 --- /dev/null +++ b/libc/sysv/calls/rfork.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall rfork 0xffff00fbffffffff globl diff --git a/libc/sysv/calls/rmdir-sysv.s b/libc/sysv/calls/rmdir-sysv.s new file mode 100644 index 00000000..fa0b8c66 --- /dev/null +++ b/libc/sysv/calls/rmdir-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall rmdir$sysv 0x0089008920890054 globl hidden diff --git a/libc/sysv/calls/rseq.s b/libc/sysv/calls/rseq.s new file mode 100644 index 00000000..29ac9dcd --- /dev/null +++ b/libc/sysv/calls/rseq.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall rseq 0xffffffffffff014e globl diff --git a/libc/sysv/calls/rt_sigqueueinfo.s b/libc/sysv/calls/rt_sigqueueinfo.s new file mode 100644 index 00000000..25459559 --- /dev/null +++ b/libc/sysv/calls/rt_sigqueueinfo.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall rt_sigqueueinfo 0xffffffffffff0081 globl diff --git a/libc/sysv/calls/rt_tgsigqueueinfo.s b/libc/sysv/calls/rt_tgsigqueueinfo.s new file mode 100644 index 00000000..15428c74 --- /dev/null +++ b/libc/sysv/calls/rt_tgsigqueueinfo.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall rt_tgsigqueueinfo 0xffffffffffff0129 globl diff --git a/libc/sysv/calls/rtprio.s b/libc/sysv/calls/rtprio.s new file mode 100644 index 00000000..f11ed875 --- /dev/null +++ b/libc/sysv/calls/rtprio.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall rtprio 0xffff00a6ffffffff globl diff --git a/libc/sysv/calls/rtprio_thread.s b/libc/sysv/calls/rtprio_thread.s new file mode 100644 index 00000000..aed0e10f --- /dev/null +++ b/libc/sysv/calls/rtprio_thread.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall rtprio_thread 0xffff01d2ffffffff globl diff --git a/libc/sysv/calls/sched_get_priority_max.s b/libc/sysv/calls/sched_get_priority_max.s new file mode 100644 index 00000000..931736a0 --- /dev/null +++ b/libc/sysv/calls/sched_get_priority_max.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sched_get_priority_max 0xffff014cffff0092 globl diff --git a/libc/sysv/calls/sched_get_priority_min.s b/libc/sysv/calls/sched_get_priority_min.s new file mode 100644 index 00000000..bb32e2ce --- /dev/null +++ b/libc/sysv/calls/sched_get_priority_min.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sched_get_priority_min 0xffff014dffff0093 globl diff --git a/libc/sysv/calls/sched_getaffinity.s b/libc/sysv/calls/sched_getaffinity.s new file mode 100644 index 00000000..dee47837 --- /dev/null +++ b/libc/sysv/calls/sched_getaffinity.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sched_getaffinity 0xffffffffffff00cc globl diff --git a/libc/sysv/calls/sched_getattr.s b/libc/sysv/calls/sched_getattr.s new file mode 100644 index 00000000..8d65afb5 --- /dev/null +++ b/libc/sysv/calls/sched_getattr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sched_getattr 0xffffffffffff013b globl diff --git a/libc/sysv/calls/sched_getparam.s b/libc/sysv/calls/sched_getparam.s new file mode 100644 index 00000000..abe3f0c4 --- /dev/null +++ b/libc/sysv/calls/sched_getparam.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sched_getparam 0xffff0148ffff008f globl diff --git a/libc/sysv/calls/sched_getscheduler.s b/libc/sysv/calls/sched_getscheduler.s new file mode 100644 index 00000000..f3e54878 --- /dev/null +++ b/libc/sysv/calls/sched_getscheduler.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sched_getscheduler 0xffff014affff0091 globl diff --git a/libc/sysv/calls/sched_rr_get_interval.s b/libc/sysv/calls/sched_rr_get_interval.s new file mode 100644 index 00000000..ccd6d165 --- /dev/null +++ b/libc/sysv/calls/sched_rr_get_interval.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sched_rr_get_interval 0xffff014effff0094 globl diff --git a/libc/sysv/calls/sched_setaffinity-sysv.s b/libc/sysv/calls/sched_setaffinity-sysv.s new file mode 100644 index 00000000..b1202f7a --- /dev/null +++ b/libc/sysv/calls/sched_setaffinity-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sched_setaffinity$sysv 0xffffffffffff00cb globl hidden diff --git a/libc/sysv/calls/sched_setattr.s b/libc/sysv/calls/sched_setattr.s new file mode 100644 index 00000000..f7806711 --- /dev/null +++ b/libc/sysv/calls/sched_setattr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sched_setattr 0xffffffffffff013a globl diff --git a/libc/sysv/calls/sched_setparam.s b/libc/sysv/calls/sched_setparam.s new file mode 100644 index 00000000..ef0bafc9 --- /dev/null +++ b/libc/sysv/calls/sched_setparam.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sched_setparam 0xffff0147ffff008e globl diff --git a/libc/sysv/calls/sched_setscheduler.s b/libc/sysv/calls/sched_setscheduler.s new file mode 100644 index 00000000..f86379ee --- /dev/null +++ b/libc/sysv/calls/sched_setscheduler.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sched_setscheduler 0xffff0149ffff0090 globl diff --git a/libc/sysv/calls/sched_yield-sysv.s b/libc/sysv/calls/sched_yield-sysv.s new file mode 100644 index 00000000..b736edcf --- /dev/null +++ b/libc/sysv/calls/sched_yield-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sched_yield$sysv 0x012a014b103c0018 globl hidden diff --git a/libc/sysv/calls/sctp_generic_recvmsg.s b/libc/sysv/calls/sctp_generic_recvmsg.s new file mode 100644 index 00000000..26f5f05f --- /dev/null +++ b/libc/sysv/calls/sctp_generic_recvmsg.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sctp_generic_recvmsg 0xffff01daffffffff globl diff --git a/libc/sysv/calls/sctp_generic_sendmsg.s b/libc/sysv/calls/sctp_generic_sendmsg.s new file mode 100644 index 00000000..9e121511 --- /dev/null +++ b/libc/sysv/calls/sctp_generic_sendmsg.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sctp_generic_sendmsg 0xffff01d8ffffffff globl diff --git a/libc/sysv/calls/sctp_generic_sendmsg_iov.s b/libc/sysv/calls/sctp_generic_sendmsg_iov.s new file mode 100644 index 00000000..8d076822 --- /dev/null +++ b/libc/sysv/calls/sctp_generic_sendmsg_iov.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sctp_generic_sendmsg_iov 0xffff01d9ffffffff globl diff --git a/libc/sysv/calls/sctp_peeloff.s b/libc/sysv/calls/sctp_peeloff.s new file mode 100644 index 00000000..45696024 --- /dev/null +++ b/libc/sysv/calls/sctp_peeloff.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sctp_peeloff 0xffff01d7ffffffff globl diff --git a/libc/sysv/calls/searchfs.s b/libc/sysv/calls/searchfs.s new file mode 100644 index 00000000..5fa3a45b --- /dev/null +++ b/libc/sysv/calls/searchfs.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall searchfs 0xffffffff20e1ffff globl diff --git a/libc/sysv/calls/seccomp.s b/libc/sysv/calls/seccomp.s new file mode 100644 index 00000000..73e1cf59 --- /dev/null +++ b/libc/sysv/calls/seccomp.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall seccomp 0xffffffffffff013d globl diff --git a/libc/sysv/calls/select-sysv.s b/libc/sysv/calls/select-sysv.s new file mode 100644 index 00000000..8ebd6701 --- /dev/null +++ b/libc/sysv/calls/select-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall select$sysv 0x0047005d205d0017 globl hidden diff --git a/libc/sysv/calls/select_nocancel.s b/libc/sysv/calls/select_nocancel.s new file mode 100644 index 00000000..cbda66ad --- /dev/null +++ b/libc/sysv/calls/select_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall select_nocancel 0xffffffff2197ffff globl diff --git a/libc/sysv/calls/sem_close.s b/libc/sysv/calls/sem_close.s new file mode 100644 index 00000000..235c44d8 --- /dev/null +++ b/libc/sysv/calls/sem_close.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sem_close 0xffffffff210dffff globl diff --git a/libc/sysv/calls/sem_open.s b/libc/sysv/calls/sem_open.s new file mode 100644 index 00000000..4fbfc757 --- /dev/null +++ b/libc/sysv/calls/sem_open.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sem_open 0xffffffff210cffff globl diff --git a/libc/sysv/calls/sem_post.s b/libc/sysv/calls/sem_post.s new file mode 100644 index 00000000..999c6290 --- /dev/null +++ b/libc/sysv/calls/sem_post.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sem_post 0xffffffff2111ffff globl diff --git a/libc/sysv/calls/sem_trywait.s b/libc/sysv/calls/sem_trywait.s new file mode 100644 index 00000000..f0eb78e5 --- /dev/null +++ b/libc/sysv/calls/sem_trywait.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sem_trywait 0xffffffff2110ffff globl diff --git a/libc/sysv/calls/sem_unlink.s b/libc/sysv/calls/sem_unlink.s new file mode 100644 index 00000000..ff642535 --- /dev/null +++ b/libc/sysv/calls/sem_unlink.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sem_unlink 0xffffffff210effff globl diff --git a/libc/sysv/calls/sem_wait.s b/libc/sysv/calls/sem_wait.s new file mode 100644 index 00000000..a1f970e3 --- /dev/null +++ b/libc/sysv/calls/sem_wait.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sem_wait 0xffffffff210fffff globl diff --git a/libc/sysv/calls/sem_wait_nocancel.s b/libc/sysv/calls/sem_wait_nocancel.s new file mode 100644 index 00000000..557b1fbf --- /dev/null +++ b/libc/sysv/calls/sem_wait_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sem_wait_nocancel 0xffffffff21a4ffff globl diff --git a/libc/sysv/calls/semctl.s b/libc/sysv/calls/semctl.s new file mode 100644 index 00000000..412d6231 --- /dev/null +++ b/libc/sysv/calls/semctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall semctl 0x012701fe20fe0042 globl diff --git a/libc/sysv/calls/semget.s b/libc/sysv/calls/semget.s new file mode 100644 index 00000000..f529e23e --- /dev/null +++ b/libc/sysv/calls/semget.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall semget 0x00dd00dd20ff0040 globl diff --git a/libc/sysv/calls/semop.s b/libc/sysv/calls/semop.s new file mode 100644 index 00000000..a76eaf04 --- /dev/null +++ b/libc/sysv/calls/semop.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall semop 0x012200de21000041 globl diff --git a/libc/sysv/calls/semsys.s b/libc/sysv/calls/semsys.s new file mode 100644 index 00000000..0ecac32e --- /dev/null +++ b/libc/sysv/calls/semsys.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall semsys 0xffff00a920fbffff globl diff --git a/libc/sysv/calls/semtimedop.s b/libc/sysv/calls/semtimedop.s new file mode 100644 index 00000000..398f4d29 --- /dev/null +++ b/libc/sysv/calls/semtimedop.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall semtimedop 0xffffffffffff00dc globl diff --git a/libc/sysv/calls/send.s b/libc/sysv/calls/send.s new file mode 100644 index 00000000..07464d3e --- /dev/null +++ b/libc/sysv/calls/send.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall send 0xffff0065ffffffff globl diff --git a/libc/sysv/calls/sendfile-sysv.s b/libc/sysv/calls/sendfile-sysv.s new file mode 100644 index 00000000..a53b4d13 --- /dev/null +++ b/libc/sysv/calls/sendfile-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sendfile$sysv 0xffff018921510028 globl hidden diff --git a/libc/sysv/calls/sendmmsg.s b/libc/sysv/calls/sendmmsg.s new file mode 100644 index 00000000..f46545b7 --- /dev/null +++ b/libc/sysv/calls/sendmmsg.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sendmmsg 0xffffffffffff0133 globl diff --git a/libc/sysv/calls/sendmsg-sysv.s b/libc/sysv/calls/sendmsg-sysv.s new file mode 100644 index 00000000..cf989b52 --- /dev/null +++ b/libc/sysv/calls/sendmsg-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sendmsg$sysv 0x001c001c201c002e globl hidden diff --git a/libc/sysv/calls/sendmsg_nocancel.s b/libc/sysv/calls/sendmsg_nocancel.s new file mode 100644 index 00000000..7751b865 --- /dev/null +++ b/libc/sysv/calls/sendmsg_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sendmsg_nocancel 0xffffffff2192ffff globl diff --git a/libc/sysv/calls/sendmsg_x.s b/libc/sysv/calls/sendmsg_x.s new file mode 100644 index 00000000..37e261b9 --- /dev/null +++ b/libc/sysv/calls/sendmsg_x.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sendmsg_x 0xffffffff21e1ffff globl diff --git a/libc/sysv/calls/sendsyslog.s b/libc/sysv/calls/sendsyslog.s new file mode 100644 index 00000000..0f5839c4 --- /dev/null +++ b/libc/sysv/calls/sendsyslog.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sendsyslog 0x0070ffffffffffff globl diff --git a/libc/sysv/calls/sendto-sysv.s b/libc/sysv/calls/sendto-sysv.s new file mode 100644 index 00000000..60031f4f --- /dev/null +++ b/libc/sysv/calls/sendto-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sendto$sysv 0x008500852085002c globl hidden diff --git a/libc/sysv/calls/sendto_nocancel.s b/libc/sysv/calls/sendto_nocancel.s new file mode 100644 index 00000000..97d520ff --- /dev/null +++ b/libc/sysv/calls/sendto_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sendto_nocancel 0xffffffff219dffff globl diff --git a/libc/sysv/calls/set_mempolicy.s b/libc/sysv/calls/set_mempolicy.s new file mode 100644 index 00000000..87c378f7 --- /dev/null +++ b/libc/sysv/calls/set_mempolicy.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall set_mempolicy 0xffffffffffff00ee globl diff --git a/libc/sysv/calls/set_robust_list.s b/libc/sysv/calls/set_robust_list.s new file mode 100644 index 00000000..8d7b87ef --- /dev/null +++ b/libc/sysv/calls/set_robust_list.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall set_robust_list 0xffffffffffff0111 globl diff --git a/libc/sysv/calls/set_tid_address.s b/libc/sysv/calls/set_tid_address.s new file mode 100644 index 00000000..5f9827a8 --- /dev/null +++ b/libc/sysv/calls/set_tid_address.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall set_tid_address 0xffffffffffff00da globl diff --git a/libc/sysv/calls/setattrlist.s b/libc/sysv/calls/setattrlist.s new file mode 100644 index 00000000..5c6d8e2b --- /dev/null +++ b/libc/sysv/calls/setattrlist.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setattrlist 0xffffffff20ddffff globl diff --git a/libc/sysv/calls/setattrlistat.s b/libc/sysv/calls/setattrlistat.s new file mode 100644 index 00000000..08eb3cba --- /dev/null +++ b/libc/sysv/calls/setattrlistat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setattrlistat 0xffffffff220cffff globl diff --git a/libc/sysv/calls/setaudit.s b/libc/sysv/calls/setaudit.s new file mode 100644 index 00000000..69a6b2ac --- /dev/null +++ b/libc/sysv/calls/setaudit.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setaudit 0xffff01c2ffffffff globl diff --git a/libc/sysv/calls/setaudit_addr.s b/libc/sysv/calls/setaudit_addr.s new file mode 100644 index 00000000..f9fa6bfb --- /dev/null +++ b/libc/sysv/calls/setaudit_addr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setaudit_addr 0xffff01c42166ffff globl diff --git a/libc/sysv/calls/setauid.s b/libc/sysv/calls/setauid.s new file mode 100644 index 00000000..46877b8a --- /dev/null +++ b/libc/sysv/calls/setauid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setauid 0xffff01c02162ffff globl diff --git a/libc/sysv/calls/setcontext.s b/libc/sysv/calls/setcontext.s new file mode 100644 index 00000000..56071a1d --- /dev/null +++ b/libc/sysv/calls/setcontext.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setcontext 0xffff01a6ffffffff globl diff --git a/libc/sysv/calls/setdomainname.s b/libc/sysv/calls/setdomainname.s new file mode 100644 index 00000000..c9d08121 --- /dev/null +++ b/libc/sysv/calls/setdomainname.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setdomainname 0xffff00a3ffff00ab globl diff --git a/libc/sysv/calls/setfib.s b/libc/sysv/calls/setfib.s new file mode 100644 index 00000000..44c3672f --- /dev/null +++ b/libc/sysv/calls/setfib.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setfib 0xffff00afffffffff globl diff --git a/libc/sysv/calls/setfsgid.s b/libc/sysv/calls/setfsgid.s new file mode 100644 index 00000000..eadca3a1 --- /dev/null +++ b/libc/sysv/calls/setfsgid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setfsgid 0xffffffffffff007b globl diff --git a/libc/sysv/calls/setfsuid.s b/libc/sysv/calls/setfsuid.s new file mode 100644 index 00000000..48253183 --- /dev/null +++ b/libc/sysv/calls/setfsuid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setfsuid 0xffffffffffff007a globl diff --git a/libc/sysv/calls/setgid.s b/libc/sysv/calls/setgid.s new file mode 100644 index 00000000..7c8780a4 --- /dev/null +++ b/libc/sysv/calls/setgid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setgid 0x00b500b520b5006a globl diff --git a/libc/sysv/calls/setgroups.s b/libc/sysv/calls/setgroups.s new file mode 100644 index 00000000..7592b8be --- /dev/null +++ b/libc/sysv/calls/setgroups.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setgroups 0x0050005020500074 globl diff --git a/libc/sysv/calls/sethostid.s b/libc/sysv/calls/sethostid.s new file mode 100644 index 00000000..023d6d06 --- /dev/null +++ b/libc/sysv/calls/sethostid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sethostid 0xffff008fffffffff globl diff --git a/libc/sysv/calls/sethostname.s b/libc/sysv/calls/sethostname.s new file mode 100644 index 00000000..36d0d9c8 --- /dev/null +++ b/libc/sysv/calls/sethostname.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sethostname 0xffff0058ffff00aa globl diff --git a/libc/sysv/calls/setitimer-sysv.s b/libc/sysv/calls/setitimer-sysv.s new file mode 100644 index 00000000..410b7308 --- /dev/null +++ b/libc/sysv/calls/setitimer-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setitimer$sysv 0x0045005320530026 globl hidden diff --git a/libc/sysv/calls/setlogin.s b/libc/sysv/calls/setlogin.s new file mode 100644 index 00000000..b24a827f --- /dev/null +++ b/libc/sysv/calls/setlogin.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setlogin 0x003200322032ffff globl diff --git a/libc/sysv/calls/setloginclass.s b/libc/sysv/calls/setloginclass.s new file mode 100644 index 00000000..4c6d0e1a --- /dev/null +++ b/libc/sysv/calls/setloginclass.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setloginclass 0xffff020cffffffff globl diff --git a/libc/sysv/calls/setns.s b/libc/sysv/calls/setns.s new file mode 100644 index 00000000..3ebee268 --- /dev/null +++ b/libc/sysv/calls/setns.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setns 0xffffffffffff0134 globl diff --git a/libc/sysv/calls/setpgid.s b/libc/sysv/calls/setpgid.s new file mode 100644 index 00000000..5c103412 --- /dev/null +++ b/libc/sysv/calls/setpgid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setpgid 0x005200522052006d globl diff --git a/libc/sysv/calls/setpriority-sysv.s b/libc/sysv/calls/setpriority-sysv.s new file mode 100644 index 00000000..b038e93a --- /dev/null +++ b/libc/sysv/calls/setpriority-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setpriority$sysv 0x006000602060008d globl hidden diff --git a/libc/sysv/calls/setprivexec.s b/libc/sysv/calls/setprivexec.s new file mode 100644 index 00000000..4fcfe0f5 --- /dev/null +++ b/libc/sysv/calls/setprivexec.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setprivexec 0xffffffff2098ffff globl diff --git a/libc/sysv/calls/setregid.s b/libc/sysv/calls/setregid.s new file mode 100644 index 00000000..6a1f3481 --- /dev/null +++ b/libc/sysv/calls/setregid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setregid 0x007f007f207f0072 globl diff --git a/libc/sysv/calls/setresgid-sysv.s b/libc/sysv/calls/setresgid-sysv.s new file mode 100644 index 00000000..5beac95e --- /dev/null +++ b/libc/sysv/calls/setresgid-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setresgid$sysv 0x011c0138ffff0077 globl hidden diff --git a/libc/sysv/calls/setresuid-sysv.s b/libc/sysv/calls/setresuid-sysv.s new file mode 100644 index 00000000..be8f25b0 --- /dev/null +++ b/libc/sysv/calls/setresuid-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setresuid$sysv 0x011a0137ffff0075 globl hidden diff --git a/libc/sysv/calls/setreuid.s b/libc/sysv/calls/setreuid.s new file mode 100644 index 00000000..beddadc6 --- /dev/null +++ b/libc/sysv/calls/setreuid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setreuid 0x007e007e207e0071 globl diff --git a/libc/sysv/calls/setrlimit-sysv.s b/libc/sysv/calls/setrlimit-sysv.s new file mode 100644 index 00000000..62fc6903 --- /dev/null +++ b/libc/sysv/calls/setrlimit-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setrlimit$sysv 0x00c300c320c300a0 globl hidden diff --git a/libc/sysv/calls/setrtable.s b/libc/sysv/calls/setrtable.s new file mode 100644 index 00000000..59ec691b --- /dev/null +++ b/libc/sysv/calls/setrtable.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setrtable 0x0136ffffffffffff globl diff --git a/libc/sysv/calls/setsgroups.s b/libc/sysv/calls/setsgroups.s new file mode 100644 index 00000000..62056f6d --- /dev/null +++ b/libc/sysv/calls/setsgroups.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setsgroups 0xffffffff211fffff globl diff --git a/libc/sysv/calls/setsid.s b/libc/sysv/calls/setsid.s new file mode 100644 index 00000000..6aff18ac --- /dev/null +++ b/libc/sysv/calls/setsid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setsid 0x0093009320930070 globl diff --git a/libc/sysv/calls/setsockopt-sysv.s b/libc/sysv/calls/setsockopt-sysv.s new file mode 100644 index 00000000..bcc142e7 --- /dev/null +++ b/libc/sysv/calls/setsockopt-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setsockopt$sysv 0x0069006920690036 globl hidden diff --git a/libc/sysv/calls/settid.s b/libc/sysv/calls/settid.s new file mode 100644 index 00000000..3358577b --- /dev/null +++ b/libc/sysv/calls/settid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall settid 0xffffffff211dffff globl diff --git a/libc/sysv/calls/settid_with_pid.s b/libc/sysv/calls/settid_with_pid.s new file mode 100644 index 00000000..80658db5 --- /dev/null +++ b/libc/sysv/calls/settid_with_pid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall settid_with_pid 0xffffffff2137ffff globl diff --git a/libc/sysv/calls/settimeofday.s b/libc/sysv/calls/settimeofday.s new file mode 100644 index 00000000..231ea0b0 --- /dev/null +++ b/libc/sysv/calls/settimeofday.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall settimeofday 0x0044007a207a00a4 globl diff --git a/libc/sysv/calls/setuid.s b/libc/sysv/calls/setuid.s new file mode 100644 index 00000000..38b6b717 --- /dev/null +++ b/libc/sysv/calls/setuid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setuid 0x0017001720170069 globl diff --git a/libc/sysv/calls/setwgroups.s b/libc/sysv/calls/setwgroups.s new file mode 100644 index 00000000..a5f8f764 --- /dev/null +++ b/libc/sysv/calls/setwgroups.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setwgroups 0xffffffff2121ffff globl diff --git a/libc/sysv/calls/setxattr.s b/libc/sysv/calls/setxattr.s new file mode 100644 index 00000000..de5feeb8 --- /dev/null +++ b/libc/sysv/calls/setxattr.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall setxattr 0xffffffff20ec00bc globl diff --git a/libc/sysv/calls/sfi_ctl.s b/libc/sysv/calls/sfi_ctl.s new file mode 100644 index 00000000..a321a52a --- /dev/null +++ b/libc/sysv/calls/sfi_ctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sfi_ctl 0xffffffff21c8ffff globl diff --git a/libc/sysv/calls/sfi_pidctl.s b/libc/sysv/calls/sfi_pidctl.s new file mode 100644 index 00000000..aa5c628f --- /dev/null +++ b/libc/sysv/calls/sfi_pidctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sfi_pidctl 0xffffffff21c9ffff globl diff --git a/libc/sysv/calls/shared_region_check_np.s b/libc/sysv/calls/shared_region_check_np.s new file mode 100644 index 00000000..710b3ce4 --- /dev/null +++ b/libc/sysv/calls/shared_region_check_np.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall shared_region_check_np 0xffffffff2126ffff globl diff --git a/libc/sysv/calls/shared_region_map_and_slide_np.s b/libc/sysv/calls/shared_region_map_and_slide_np.s new file mode 100644 index 00000000..1a6d388a --- /dev/null +++ b/libc/sysv/calls/shared_region_map_and_slide_np.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall shared_region_map_and_slide_np 0xffffffff21b6ffff globl diff --git a/libc/sysv/calls/shm_open.s b/libc/sysv/calls/shm_open.s new file mode 100644 index 00000000..b8ec9634 --- /dev/null +++ b/libc/sysv/calls/shm_open.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall shm_open 0xffff01e2210affff globl diff --git a/libc/sysv/calls/shm_unlink.s b/libc/sysv/calls/shm_unlink.s new file mode 100644 index 00000000..83a6bc7a --- /dev/null +++ b/libc/sysv/calls/shm_unlink.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall shm_unlink 0xffff01e3210bffff globl diff --git a/libc/sysv/calls/shmat.s b/libc/sysv/calls/shmat.s new file mode 100644 index 00000000..f5b8db7c --- /dev/null +++ b/libc/sysv/calls/shmat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall shmat 0x00e400e42106001e globl diff --git a/libc/sysv/calls/shmctl.s b/libc/sysv/calls/shmctl.s new file mode 100644 index 00000000..52b7881d --- /dev/null +++ b/libc/sysv/calls/shmctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall shmctl 0x012802002107001f globl diff --git a/libc/sysv/calls/shmdt.s b/libc/sysv/calls/shmdt.s new file mode 100644 index 00000000..20fb07f4 --- /dev/null +++ b/libc/sysv/calls/shmdt.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall shmdt 0x00e600e621080043 globl diff --git a/libc/sysv/calls/shmget.s b/libc/sysv/calls/shmget.s new file mode 100644 index 00000000..7008c312 --- /dev/null +++ b/libc/sysv/calls/shmget.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall shmget 0x012100e72109001d globl diff --git a/libc/sysv/calls/shmsys.s b/libc/sysv/calls/shmsys.s new file mode 100644 index 00000000..e588b44d --- /dev/null +++ b/libc/sysv/calls/shmsys.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall shmsys 0xffff00ab20fdffff globl diff --git a/libc/sysv/calls/shutdown-sysv.s b/libc/sysv/calls/shutdown-sysv.s new file mode 100644 index 00000000..74306766 --- /dev/null +++ b/libc/sysv/calls/shutdown-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall shutdown$sysv 0x0086008620860030 globl hidden diff --git a/libc/sysv/calls/sigaction-sysv.s b/libc/sysv/calls/sigaction-sysv.s new file mode 100644 index 00000000..1bf1636c --- /dev/null +++ b/libc/sysv/calls/sigaction-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sigaction$sysv 0x002e01a0202e000d globl hidden diff --git a/libc/sysv/calls/sigaltstack.s b/libc/sysv/calls/sigaltstack.s new file mode 100644 index 00000000..c9d5302a --- /dev/null +++ b/libc/sysv/calls/sigaltstack.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sigaltstack 0x0120003520350083 globl diff --git a/libc/sysv/calls/sigblock.s b/libc/sysv/calls/sigblock.s new file mode 100644 index 00000000..38517109 --- /dev/null +++ b/libc/sysv/calls/sigblock.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sigblock 0xffff006dffffffff globl diff --git a/libc/sysv/calls/signalfd.s b/libc/sysv/calls/signalfd.s new file mode 100644 index 00000000..9503b739 --- /dev/null +++ b/libc/sysv/calls/signalfd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall signalfd 0xffffffffffff011a globl diff --git a/libc/sysv/calls/signalfd4.s b/libc/sysv/calls/signalfd4.s new file mode 100644 index 00000000..29df581d --- /dev/null +++ b/libc/sysv/calls/signalfd4.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall signalfd4 0xffffffffffff0121 globl diff --git a/libc/sysv/calls/sigpending.s b/libc/sysv/calls/sigpending.s new file mode 100644 index 00000000..dfc8a2de --- /dev/null +++ b/libc/sysv/calls/sigpending.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sigpending 0x003400342034007f globl diff --git a/libc/sysv/calls/sigprocmask-sysv.s b/libc/sysv/calls/sigprocmask-sysv.s new file mode 100644 index 00000000..c1fdfac1 --- /dev/null +++ b/libc/sysv/calls/sigprocmask-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sigprocmask$sysv 0x003001542030000e globl hidden diff --git a/libc/sysv/calls/sigqueue.s b/libc/sysv/calls/sigqueue.s new file mode 100644 index 00000000..bd8c6b0e --- /dev/null +++ b/libc/sysv/calls/sigqueue.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sigqueue 0xffff01c8ffffffff globl diff --git a/libc/sysv/calls/sigsetmask.s b/libc/sysv/calls/sigsetmask.s new file mode 100644 index 00000000..813b64f0 --- /dev/null +++ b/libc/sysv/calls/sigsetmask.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sigsetmask 0xffff006effffffff globl diff --git a/libc/sysv/calls/sigstack.s b/libc/sysv/calls/sigstack.s new file mode 100644 index 00000000..e782f40e --- /dev/null +++ b/libc/sysv/calls/sigstack.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sigstack 0xffff0070ffffffff globl diff --git a/libc/sysv/calls/sigsuspend-sysv.s b/libc/sysv/calls/sigsuspend-sysv.s new file mode 100644 index 00000000..1a67afd0 --- /dev/null +++ b/libc/sysv/calls/sigsuspend-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sigsuspend$sysv 0x006f0155206f0082 globl hidden diff --git a/libc/sysv/calls/sigsuspend_nocancel.s b/libc/sysv/calls/sigsuspend_nocancel.s new file mode 100644 index 00000000..20ee0601 --- /dev/null +++ b/libc/sysv/calls/sigsuspend_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sigsuspend_nocancel 0xffffffff219affff globl diff --git a/libc/sysv/calls/sigtimedwait.s b/libc/sysv/calls/sigtimedwait.s new file mode 100644 index 00000000..a89de9e8 --- /dev/null +++ b/libc/sysv/calls/sigtimedwait.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sigtimedwait 0xffff0159ffff0080 globl diff --git a/libc/sysv/calls/sigvec.s b/libc/sysv/calls/sigvec.s new file mode 100644 index 00000000..94615ab0 --- /dev/null +++ b/libc/sysv/calls/sigvec.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sigvec 0xffff006cffffffff globl diff --git a/libc/sysv/calls/sigwait.s b/libc/sysv/calls/sigwait.s new file mode 100644 index 00000000..1fcff738 --- /dev/null +++ b/libc/sysv/calls/sigwait.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sigwait 0xffff01ad214affff globl diff --git a/libc/sysv/calls/sigwaitinfo.s b/libc/sysv/calls/sigwaitinfo.s new file mode 100644 index 00000000..9b87be9b --- /dev/null +++ b/libc/sysv/calls/sigwaitinfo.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sigwaitinfo 0xffff015affffffff globl diff --git a/libc/sysv/calls/socket_delegate.s b/libc/sysv/calls/socket_delegate.s new file mode 100644 index 00000000..af93c535 --- /dev/null +++ b/libc/sysv/calls/socket_delegate.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall socket_delegate 0xffffffff21c2ffff globl diff --git a/libc/sysv/calls/socketpair-sysv.s b/libc/sysv/calls/socketpair-sysv.s new file mode 100644 index 00000000..86eca85b --- /dev/null +++ b/libc/sysv/calls/socketpair-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall socketpair$sysv 0x0087008720870035 globl hidden diff --git a/libc/sysv/calls/splice-sysv.s b/libc/sysv/calls/splice-sysv.s new file mode 100644 index 00000000..9cda0140 --- /dev/null +++ b/libc/sysv/calls/splice-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall splice$sysv 0xffffffffffff0113 globl hidden diff --git a/libc/sysv/calls/sstk.s b/libc/sysv/calls/sstk.s new file mode 100644 index 00000000..48c96aa6 --- /dev/null +++ b/libc/sysv/calls/sstk.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sstk 0xffff0046ffffffff globl diff --git a/libc/sysv/calls/stack_snapshot_with_config.s b/libc/sysv/calls/stack_snapshot_with_config.s new file mode 100644 index 00000000..1352ca00 --- /dev/null +++ b/libc/sysv/calls/stack_snapshot_with_config.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall stack_snapshot_with_config 0xffffffff21ebffff globl diff --git a/libc/sysv/calls/stat_extended.s b/libc/sysv/calls/stat_extended.s new file mode 100644 index 00000000..ce0b7ca7 --- /dev/null +++ b/libc/sysv/calls/stat_extended.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall stat_extended 0xffffffff2155ffff globl diff --git a/libc/sysv/calls/statfs.s b/libc/sysv/calls/statfs.s new file mode 100644 index 00000000..c7bfc25d --- /dev/null +++ b/libc/sysv/calls/statfs.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall statfs 0x003f022b21590089 globl diff --git a/libc/sysv/calls/statx.s b/libc/sysv/calls/statx.s new file mode 100644 index 00000000..c7be94f7 --- /dev/null +++ b/libc/sysv/calls/statx.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall statx 0xffffffffffff014c globl diff --git a/libc/sysv/calls/swapcontext.s b/libc/sysv/calls/swapcontext.s new file mode 100644 index 00000000..fd723614 --- /dev/null +++ b/libc/sysv/calls/swapcontext.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall swapcontext 0xffff01a7ffffffff globl diff --git a/libc/sysv/calls/swapctl.s b/libc/sysv/calls/swapctl.s new file mode 100644 index 00000000..caf6f0d1 --- /dev/null +++ b/libc/sysv/calls/swapctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall swapctl 0x00c1ffffffffffff globl diff --git a/libc/sysv/calls/swapoff.s b/libc/sysv/calls/swapoff.s new file mode 100644 index 00000000..a68f5f61 --- /dev/null +++ b/libc/sysv/calls/swapoff.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall swapoff 0xffff01a8ffff00a8 globl diff --git a/libc/sysv/calls/swapon.s b/libc/sysv/calls/swapon.s new file mode 100644 index 00000000..6feb07ae --- /dev/null +++ b/libc/sysv/calls/swapon.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall swapon 0xffff0055205500a7 globl diff --git a/libc/sysv/calls/symlink-sysv.s b/libc/sysv/calls/symlink-sysv.s new file mode 100644 index 00000000..bdd9a98e --- /dev/null +++ b/libc/sysv/calls/symlink-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall symlink$sysv 0x0039003920390058 globl hidden diff --git a/libc/sysv/calls/symlinkat-sysv.s b/libc/sysv/calls/symlinkat-sysv.s new file mode 100644 index 00000000..bb12c039 --- /dev/null +++ b/libc/sysv/calls/symlinkat-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall symlinkat$sysv 0x014401f621da010a globl hidden diff --git a/libc/sysv/calls/sync.s b/libc/sysv/calls/sync.s new file mode 100644 index 00000000..133639cc --- /dev/null +++ b/libc/sysv/calls/sync.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sync 0x00240024202400a2 globl diff --git a/libc/sysv/calls/sync_file_range-sysv.s b/libc/sysv/calls/sync_file_range-sysv.s new file mode 100644 index 00000000..576c08fe --- /dev/null +++ b/libc/sysv/calls/sync_file_range-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sync_file_range$sysv 0xffffffffffff0115 globl hidden diff --git a/libc/sysv/calls/syncfs.s b/libc/sysv/calls/syncfs.s new file mode 100644 index 00000000..84d28579 --- /dev/null +++ b/libc/sysv/calls/syncfs.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall syncfs 0xffffffffffff0132 globl diff --git a/libc/sysv/calls/sysctl.s b/libc/sysv/calls/sysctl.s new file mode 100644 index 00000000..1eaaf18a --- /dev/null +++ b/libc/sysv/calls/sysctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sysctl 0x00caffff20caffff globl diff --git a/libc/sysv/calls/sysctlbyname.s b/libc/sysv/calls/sysctlbyname.s new file mode 100644 index 00000000..5837096a --- /dev/null +++ b/libc/sysv/calls/sysctlbyname.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sysctlbyname 0xffffffff2112ffff globl diff --git a/libc/sysv/calls/sysfs.s b/libc/sysv/calls/sysfs.s new file mode 100644 index 00000000..80f4fb50 --- /dev/null +++ b/libc/sysv/calls/sysfs.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sysfs 0xffffffffffff008b globl diff --git a/libc/sysv/calls/sysinfo-sysv.s b/libc/sysv/calls/sysinfo-sysv.s new file mode 100644 index 00000000..c58d7870 --- /dev/null +++ b/libc/sysv/calls/sysinfo-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall sysinfo$sysv 0xffffffffffff0063 globl hidden diff --git a/libc/sysv/calls/syslog.s b/libc/sysv/calls/syslog.s new file mode 100644 index 00000000..72fab33c --- /dev/null +++ b/libc/sysv/calls/syslog.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall syslog 0xffffffffffff0067 globl diff --git a/libc/sysv/calls/system_override.s b/libc/sysv/calls/system_override.s new file mode 100644 index 00000000..7a8cfc4c --- /dev/null +++ b/libc/sysv/calls/system_override.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall system_override 0xffffffff21c6ffff globl diff --git a/libc/sysv/calls/tee.s b/libc/sysv/calls/tee.s new file mode 100644 index 00000000..e1744530 --- /dev/null +++ b/libc/sysv/calls/tee.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall tee 0xffffffffffff0114 globl diff --git a/libc/sysv/calls/telemetry.s b/libc/sysv/calls/telemetry.s new file mode 100644 index 00000000..93de62be --- /dev/null +++ b/libc/sysv/calls/telemetry.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall telemetry 0xffffffff21c3ffff globl diff --git a/libc/sysv/calls/terminate_with_payload.s b/libc/sysv/calls/terminate_with_payload.s new file mode 100644 index 00000000..eac5a8a2 --- /dev/null +++ b/libc/sysv/calls/terminate_with_payload.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall terminate_with_payload 0xffffffff2208ffff globl diff --git a/libc/sysv/calls/tgkill.s b/libc/sysv/calls/tgkill.s new file mode 100644 index 00000000..cf168ce3 --- /dev/null +++ b/libc/sysv/calls/tgkill.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall tgkill 0xffffffffffff00ea globl diff --git a/libc/sysv/calls/thr_create.s b/libc/sysv/calls/thr_create.s new file mode 100644 index 00000000..6da132a4 --- /dev/null +++ b/libc/sysv/calls/thr_create.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall thr_create 0xffff01aeffffffff globl diff --git a/libc/sysv/calls/thr_exit.s b/libc/sysv/calls/thr_exit.s new file mode 100644 index 00000000..66628c0b --- /dev/null +++ b/libc/sysv/calls/thr_exit.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall thr_exit 0xffff01afffffffff globl diff --git a/libc/sysv/calls/thr_kill.s b/libc/sysv/calls/thr_kill.s new file mode 100644 index 00000000..9c7858b6 --- /dev/null +++ b/libc/sysv/calls/thr_kill.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall thr_kill 0xffff01b1ffffffff globl diff --git a/libc/sysv/calls/thr_kill2.s b/libc/sysv/calls/thr_kill2.s new file mode 100644 index 00000000..21dfab63 --- /dev/null +++ b/libc/sysv/calls/thr_kill2.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall thr_kill2 0xffff01e1ffffffff globl diff --git a/libc/sysv/calls/thr_new.s b/libc/sysv/calls/thr_new.s new file mode 100644 index 00000000..1733d426 --- /dev/null +++ b/libc/sysv/calls/thr_new.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall thr_new 0xffff01c7ffffffff globl diff --git a/libc/sysv/calls/thr_self.s b/libc/sysv/calls/thr_self.s new file mode 100644 index 00000000..51eb18c7 --- /dev/null +++ b/libc/sysv/calls/thr_self.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall thr_self 0xffff01b0ffffffff globl diff --git a/libc/sysv/calls/thr_set_name.s b/libc/sysv/calls/thr_set_name.s new file mode 100644 index 00000000..64d0860e --- /dev/null +++ b/libc/sysv/calls/thr_set_name.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall thr_set_name 0xffff01d0ffffffff globl diff --git a/libc/sysv/calls/thr_suspend.s b/libc/sysv/calls/thr_suspend.s new file mode 100644 index 00000000..1fa1a0b6 --- /dev/null +++ b/libc/sysv/calls/thr_suspend.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall thr_suspend 0xffff01baffffffff globl diff --git a/libc/sysv/calls/thr_wake.s b/libc/sysv/calls/thr_wake.s new file mode 100644 index 00000000..97fcbac9 --- /dev/null +++ b/libc/sysv/calls/thr_wake.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall thr_wake 0xffff01bbffffffff globl diff --git a/libc/sysv/calls/thread_selfcounts.s b/libc/sysv/calls/thread_selfcounts.s new file mode 100644 index 00000000..b2453f64 --- /dev/null +++ b/libc/sysv/calls/thread_selfcounts.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall thread_selfcounts 0xffffffff20baffff globl diff --git a/libc/sysv/calls/thread_selfid.s b/libc/sysv/calls/thread_selfid.s new file mode 100644 index 00000000..3f651dbf --- /dev/null +++ b/libc/sysv/calls/thread_selfid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall thread_selfid 0xffffffff2174ffff globl diff --git a/libc/sysv/calls/thread_selfusage.s b/libc/sysv/calls/thread_selfusage.s new file mode 100644 index 00000000..a1ce2f98 --- /dev/null +++ b/libc/sysv/calls/thread_selfusage.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall thread_selfusage 0xffffffff21e2ffff globl diff --git a/libc/sysv/calls/thrkill.s b/libc/sysv/calls/thrkill.s new file mode 100644 index 00000000..b297418c --- /dev/null +++ b/libc/sysv/calls/thrkill.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall thrkill 0x0077ffffffffffff globl diff --git a/libc/sysv/calls/timer_create.s b/libc/sysv/calls/timer_create.s new file mode 100644 index 00000000..c61b756a --- /dev/null +++ b/libc/sysv/calls/timer_create.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall timer_create 0xffffffffffff00de globl diff --git a/libc/sysv/calls/timer_delete.s b/libc/sysv/calls/timer_delete.s new file mode 100644 index 00000000..973b84ec --- /dev/null +++ b/libc/sysv/calls/timer_delete.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall timer_delete 0xffffffffffff00e2 globl diff --git a/libc/sysv/calls/timer_getoverrun.s b/libc/sysv/calls/timer_getoverrun.s new file mode 100644 index 00000000..bea91288 --- /dev/null +++ b/libc/sysv/calls/timer_getoverrun.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall timer_getoverrun 0xffffffffffff00e1 globl diff --git a/libc/sysv/calls/timer_gettime.s b/libc/sysv/calls/timer_gettime.s new file mode 100644 index 00000000..ba50f46d --- /dev/null +++ b/libc/sysv/calls/timer_gettime.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall timer_gettime 0xffffffffffff00e0 globl diff --git a/libc/sysv/calls/timer_settime.s b/libc/sysv/calls/timer_settime.s new file mode 100644 index 00000000..04aebc6d --- /dev/null +++ b/libc/sysv/calls/timer_settime.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall timer_settime 0xffffffffffff00df globl diff --git a/libc/sysv/calls/timerfd_create.s b/libc/sysv/calls/timerfd_create.s new file mode 100644 index 00000000..15a4db70 --- /dev/null +++ b/libc/sysv/calls/timerfd_create.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall timerfd_create 0xffffffffffff011b globl diff --git a/libc/sysv/calls/timerfd_gettime.s b/libc/sysv/calls/timerfd_gettime.s new file mode 100644 index 00000000..07369763 --- /dev/null +++ b/libc/sysv/calls/timerfd_gettime.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall timerfd_gettime 0xffffffffffff011f globl diff --git a/libc/sysv/calls/timerfd_settime.s b/libc/sysv/calls/timerfd_settime.s new file mode 100644 index 00000000..dd489f2d --- /dev/null +++ b/libc/sysv/calls/timerfd_settime.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall timerfd_settime 0xffffffffffff011e globl diff --git a/libc/sysv/calls/times-sysv.s b/libc/sysv/calls/times-sysv.s new file mode 100644 index 00000000..02c341c6 --- /dev/null +++ b/libc/sysv/calls/times-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall times$sysv 0xffffffffffff0064 globl hidden diff --git a/libc/sysv/calls/tkill.s b/libc/sysv/calls/tkill.s new file mode 100644 index 00000000..3f5db9d4 --- /dev/null +++ b/libc/sysv/calls/tkill.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall tkill 0xffffffffffff00c8 globl diff --git a/libc/sysv/calls/ulock_wait.s b/libc/sysv/calls/ulock_wait.s new file mode 100644 index 00000000..50d1e774 --- /dev/null +++ b/libc/sysv/calls/ulock_wait.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ulock_wait 0xffffffff2203ffff globl diff --git a/libc/sysv/calls/ulock_wake.s b/libc/sysv/calls/ulock_wake.s new file mode 100644 index 00000000..fbde6955 --- /dev/null +++ b/libc/sysv/calls/ulock_wake.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ulock_wake 0xffffffff2204ffff globl diff --git a/libc/sysv/calls/umask.s b/libc/sysv/calls/umask.s new file mode 100644 index 00000000..652f4cc2 --- /dev/null +++ b/libc/sysv/calls/umask.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall umask 0x003c003c203c005f globl diff --git a/libc/sysv/calls/umask_extended.s b/libc/sysv/calls/umask_extended.s new file mode 100644 index 00000000..1f30803f --- /dev/null +++ b/libc/sysv/calls/umask_extended.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall umask_extended 0xffffffff2116ffff globl diff --git a/libc/sysv/calls/umount2.s b/libc/sysv/calls/umount2.s new file mode 100644 index 00000000..ab49bc3c --- /dev/null +++ b/libc/sysv/calls/umount2.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall umount2 0xffffffffffff00a6 globl diff --git a/libc/sysv/calls/uname-sysv.s b/libc/sysv/calls/uname-sysv.s new file mode 100644 index 00000000..03fec287 --- /dev/null +++ b/libc/sysv/calls/uname-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall uname$sysv 0xffff00a4ffff003f globl hidden diff --git a/libc/sysv/calls/undelete.s b/libc/sysv/calls/undelete.s new file mode 100644 index 00000000..b9e71aec --- /dev/null +++ b/libc/sysv/calls/undelete.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall undelete 0xffff00cd20cdffff globl diff --git a/libc/sysv/calls/unlink-sysv.s b/libc/sysv/calls/unlink-sysv.s new file mode 100644 index 00000000..ce28e817 --- /dev/null +++ b/libc/sysv/calls/unlink-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall unlink$sysv 0x000a000a200a0057 globl hidden diff --git a/libc/sysv/calls/unlinkat-sysv.s b/libc/sysv/calls/unlinkat-sysv.s new file mode 100644 index 00000000..75273f75 --- /dev/null +++ b/libc/sysv/calls/unlinkat-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall unlinkat$sysv 0x014501f721d80107 globl hidden diff --git a/libc/sysv/calls/unmount.s b/libc/sysv/calls/unmount.s new file mode 100644 index 00000000..80d8c57c --- /dev/null +++ b/libc/sysv/calls/unmount.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall unmount 0x00160016209fffff globl diff --git a/libc/sysv/calls/unshare.s b/libc/sysv/calls/unshare.s new file mode 100644 index 00000000..678858da --- /dev/null +++ b/libc/sysv/calls/unshare.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall unshare 0xffffffffffff0110 globl diff --git a/libc/sysv/calls/unveil.s b/libc/sysv/calls/unveil.s new file mode 100644 index 00000000..27f23ac3 --- /dev/null +++ b/libc/sysv/calls/unveil.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall unveil 0x0072ffffffffffff globl diff --git a/libc/sysv/calls/userfaultfd.s b/libc/sysv/calls/userfaultfd.s new file mode 100644 index 00000000..6a67b755 --- /dev/null +++ b/libc/sysv/calls/userfaultfd.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall userfaultfd 0xffffffffffff0143 globl diff --git a/libc/sysv/calls/usrctl.s b/libc/sysv/calls/usrctl.s new file mode 100644 index 00000000..2a2450db --- /dev/null +++ b/libc/sysv/calls/usrctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall usrctl 0xffffffff21bdffff globl diff --git a/libc/sysv/calls/ustat.s b/libc/sysv/calls/ustat.s new file mode 100644 index 00000000..b51ce3fe --- /dev/null +++ b/libc/sysv/calls/ustat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall ustat 0xffffffffffff0088 globl diff --git a/libc/sysv/calls/utime-sysv.s b/libc/sysv/calls/utime-sysv.s new file mode 100644 index 00000000..9e6438cd --- /dev/null +++ b/libc/sysv/calls/utime-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall utime$sysv 0xffffffffffff0084 globl hidden diff --git a/libc/sysv/calls/utimensat.s b/libc/sysv/calls/utimensat.s new file mode 100644 index 00000000..89fe6103 --- /dev/null +++ b/libc/sysv/calls/utimensat.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall utimensat 0x00540223ffff0118 globl hidden diff --git a/libc/sysv/calls/utimes-sysv.s b/libc/sysv/calls/utimes-sysv.s new file mode 100644 index 00000000..0ed1173d --- /dev/null +++ b/libc/sysv/calls/utimes-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall utimes$sysv 0x004c008a208a00eb globl hidden diff --git a/libc/sysv/calls/utrace.s b/libc/sysv/calls/utrace.s new file mode 100644 index 00000000..6a4b0aee --- /dev/null +++ b/libc/sysv/calls/utrace.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall utrace 0x00d1014fffffffff globl diff --git a/libc/sysv/calls/uuidgen.s b/libc/sysv/calls/uuidgen.s new file mode 100644 index 00000000..ea0affc0 --- /dev/null +++ b/libc/sysv/calls/uuidgen.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall uuidgen 0xffff0188ffffffff globl diff --git a/libc/sysv/calls/vadvise.s b/libc/sysv/calls/vadvise.s new file mode 100644 index 00000000..9ab4cff7 --- /dev/null +++ b/libc/sysv/calls/vadvise.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall vadvise 0xffff0048ffffffff globl diff --git a/libc/sysv/calls/vfork.s b/libc/sysv/calls/vfork.s new file mode 100644 index 00000000..54431877 --- /dev/null +++ b/libc/sysv/calls/vfork.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall vfork 0x004200422042003a globl diff --git a/libc/sysv/calls/vfs_purge.s b/libc/sysv/calls/vfs_purge.s new file mode 100644 index 00000000..c097b921 --- /dev/null +++ b/libc/sysv/calls/vfs_purge.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall vfs_purge 0xffffffff21c7ffff globl diff --git a/libc/sysv/calls/vhangup.s b/libc/sysv/calls/vhangup.s new file mode 100644 index 00000000..c00d2114 --- /dev/null +++ b/libc/sysv/calls/vhangup.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall vhangup 0xffffffffffff0099 globl diff --git a/libc/sysv/calls/vm_pressure_monitor.s b/libc/sysv/calls/vm_pressure_monitor.s new file mode 100644 index 00000000..0caa5644 --- /dev/null +++ b/libc/sysv/calls/vm_pressure_monitor.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall vm_pressure_monitor 0xffffffff2128ffff globl diff --git a/libc/sysv/calls/vmsplice-sysv.s b/libc/sysv/calls/vmsplice-sysv.s new file mode 100644 index 00000000..d9462bfe --- /dev/null +++ b/libc/sysv/calls/vmsplice-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall vmsplice$sysv 0xffffffffffff0116 globl hidden diff --git a/libc/sysv/calls/wait.s b/libc/sysv/calls/wait.s new file mode 100644 index 00000000..d96ec67e --- /dev/null +++ b/libc/sysv/calls/wait.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall wait 0xffff0054ffffffff globl diff --git a/libc/sysv/calls/wait4-sysv.s b/libc/sysv/calls/wait4-sysv.s new file mode 100644 index 00000000..948937d2 --- /dev/null +++ b/libc/sysv/calls/wait4-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall wait4$sysv 0x000b00072007003d globl hidden diff --git a/libc/sysv/calls/wait4_nocancel.s b/libc/sysv/calls/wait4_nocancel.s new file mode 100644 index 00000000..4e021835 --- /dev/null +++ b/libc/sysv/calls/wait4_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall wait4_nocancel 0xffffffff2190ffff globl diff --git a/libc/sysv/calls/wait6.s b/libc/sysv/calls/wait6.s new file mode 100644 index 00000000..231fa12b --- /dev/null +++ b/libc/sysv/calls/wait6.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall wait6 0xffff0214ffffffff globl diff --git a/libc/sysv/calls/waitevent.s b/libc/sysv/calls/waitevent.s new file mode 100644 index 00000000..2a7cf8f0 --- /dev/null +++ b/libc/sysv/calls/waitevent.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall waitevent 0xffffffff20e8ffff globl diff --git a/libc/sysv/calls/waitid.s b/libc/sysv/calls/waitid.s new file mode 100644 index 00000000..e34cad6a --- /dev/null +++ b/libc/sysv/calls/waitid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall waitid 0xffffffff20ad00f7 globl diff --git a/libc/sysv/calls/waitid_nocancel.s b/libc/sysv/calls/waitid_nocancel.s new file mode 100644 index 00000000..e434c632 --- /dev/null +++ b/libc/sysv/calls/waitid_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall waitid_nocancel 0xffffffff21a0ffff globl diff --git a/libc/sysv/calls/watchevent.s b/libc/sysv/calls/watchevent.s new file mode 100644 index 00000000..f0b7bebc --- /dev/null +++ b/libc/sysv/calls/watchevent.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall watchevent 0xffffffff20e7ffff globl diff --git a/libc/sysv/calls/work_interval_ctl.s b/libc/sysv/calls/work_interval_ctl.s new file mode 100644 index 00000000..5e6ee26a --- /dev/null +++ b/libc/sysv/calls/work_interval_ctl.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall work_interval_ctl 0xffffffff21f3ffff globl diff --git a/libc/sysv/calls/workq_kernreturn.s b/libc/sysv/calls/workq_kernreturn.s new file mode 100644 index 00000000..5f674b56 --- /dev/null +++ b/libc/sysv/calls/workq_kernreturn.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall workq_kernreturn 0xffffffff2170ffff globl diff --git a/libc/sysv/calls/workq_open.s b/libc/sysv/calls/workq_open.s new file mode 100644 index 00000000..68468928 --- /dev/null +++ b/libc/sysv/calls/workq_open.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall workq_open 0xffffffff216fffff globl diff --git a/libc/sysv/calls/write-sysv.s b/libc/sysv/calls/write-sysv.s new file mode 100644 index 00000000..18803d9f --- /dev/null +++ b/libc/sysv/calls/write-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall write$sysv 0x0004000420040001 globl hidden diff --git a/libc/sysv/calls/write_nocancel.s b/libc/sysv/calls/write_nocancel.s new file mode 100644 index 00000000..9e16fb4b --- /dev/null +++ b/libc/sysv/calls/write_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall write_nocancel 0xffffffff218dffff globl diff --git a/libc/sysv/calls/writev-sysv.s b/libc/sysv/calls/writev-sysv.s new file mode 100644 index 00000000..330633f3 --- /dev/null +++ b/libc/sysv/calls/writev-sysv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall writev$sysv 0x0079007920790014 globl hidden diff --git a/libc/sysv/calls/writev_nocancel.s b/libc/sysv/calls/writev_nocancel.s new file mode 100644 index 00000000..86ea0255 --- /dev/null +++ b/libc/sysv/calls/writev_nocancel.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall writev_nocancel 0xffffffff219cffff globl diff --git a/libc/sysv/calls/yield.s b/libc/sysv/calls/yield.s new file mode 100644 index 00000000..b23f3ec3 --- /dev/null +++ b/libc/sysv/calls/yield.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall yield 0xffff0141ffffffff globl diff --git a/libc/sysv/consensus.py b/libc/sysv/consensus.py new file mode 100755 index 00000000..a910923d --- /dev/null +++ b/libc/sysv/consensus.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +import sys + +lineno = 0 + +def atoi(s): + try: + if s == '0': + return 0 + elif s.startswith('0x'): + return int(s[2:], 16) + elif s.startswith('0b'): + return int(s[2:], 2) + elif s.startswith('0'): + return int(s[1:], 8) + return int(s) + except ValueError: + sys.stderr.write('error: %s on line %d\n' % (s, lineno)) + sys.exit(1) + +for line in open('consts.sh'): + f = line.split() + lineno = lineno + 1 + if len(f) >= 8 and f[0] == 'syscon': + linux = atoi(f[3]) + xnu = atoi(f[4]) + freebsd = atoi(f[5]) + openbsd = atoi(f[6]) + windows = atoi(f[7]) + if linux == xnu and xnu == freebsd and freebsd == openbsd and openbsd == windows: + sys.stdout.write('%s\t%s\n' % (f[1], f[2])) diff --git a/libc/sysv/consts.sh b/libc/sysv/consts.sh new file mode 100755 index 00000000..9a265f3a --- /dev/null +++ b/libc/sysv/consts.sh @@ -0,0 +1,2809 @@ +/*bin/echo ' -*- mode:sh; indent-tabs-mode:nil; tab-width:8; coding:utf-8 -*-│ +│vi: set net ft=sh ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚────────────────────────────────────────────────────────────────'>/dev/null #*/ +dir=libc/sysv/consts +. libc/sysv/gen.sh + +# The Fifth Bell System, Community Edition +# » catalogue of carnage +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon errno ENOSYS 38 78 78 78 1 # bsd consensus & kNtErrorInvalidFunction +syscon errno EPERM 1 1 1 1 12 # unix consensus & kNtErrorInvalidAccess (should be kNtErrorNotOwner but is that mutex only??) +syscon errno ENOENT 2 2 2 2 2 # unix consensus & kNtErrorFileNot_FOUND +syscon errno ESRCH 3 3 3 3 566 # "no such process" & kNtErrorThreadNotInProcess (cf. kNtErrorInvalidHandle) +syscon errno EINTR 4 4 4 4 10004 # unix consensus & WSAEINTR +syscon errno EIO 5 5 5 5 1117 # unix consensus & kNtErrorIoDevice +syscon errno ENXIO 6 6 6 6 1112 # unix consensus & kNtErrorNoMediaInDrive +syscon errno E2BIG 7 7 7 7 1639 # unix consensus & kNtErrorInvalidCommandLine +syscon errno ENOEXEC 8 8 8 8 193 # unix consensus & kNtErrorBadExeFormat +syscon errno EBADF 9 9 9 9 6 # bad file descriptor; cf. EBADFD; unix consensus & kNtErrorInvalidHandle +syscon errno ECHILD 10 10 10 10 128 # unix consensus & kNtErrorWaitNoChildren +syscon errno EAGAIN 11 35 35 35 0x2733 # bsd consensus +syscon errno EWOULDBLOCK 11 35 35 35 0x2733 # bsd consensus +syscon errno ENOMEM 12 12 12 12 14 # unix consensus & kNtErrorOutofmemory +syscon errno EACCES 13 13 13 13 5 # unix consensus & kNtErrorAccessDenied +syscon errno EFAULT 14 14 14 14 487 # unix consensus & kNtErrorInvalidAddress +syscon errno ENOTBLK 15 15 15 15 26 # unix consensus & kNtErrorNotDosDisk +syscon errno EBUSY 16 16 16 16 170 # unix consensus & kNtErrorBusy +syscon errno EEXIST 17 17 17 17 183 # unix consensus & kNtErrorAlreadyExists (should be kNtErrorFileExists too) +syscon errno EXDEV 18 18 18 18 -1 # unix consensus +syscon errno ENODEV 19 19 19 19 1200 # unix consensus & kNtErrorBadDevice +syscon errno ENOTDIR 20 20 20 20 3 # unix consensus & kNtErrorPathNotFound +syscon errno EISDIR 21 21 21 21 267 # unix consensus & kNtErrorDirectoryNotSupported +syscon errno EINVAL 22 22 22 22 87 # unix consensus & kNtErrorInvalidParameter +syscon errno ENFILE 23 23 23 23 331 # unix consensus & kNtErrorTooManyDescriptors +syscon errno EMFILE 24 24 24 24 336 # unix consensus & kNtErrorTooManyOpenFiles +syscon errno ENOTTY 25 25 25 25 1118 # unix consensus & kNtErrorSerialNoDevice +syscon errno ETXTBSY 26 26 26 26 148 # unix consensus & kNtErrorPathBusy +syscon errno EFBIG 27 27 27 27 223 # unix consensus & kNtErrorFileTooLarge +syscon errno ENOSPC 28 28 28 28 39 # unix consensus & kNtErrorDiskFull +syscon errno EDQUOT 122 69 69 69 0x2755 # bsd consensus +syscon errno ESPIPE 29 29 29 29 25 # unix consensus & kNtErrorSeek +syscon errno EROFS 30 30 30 30 6009 # unix consensus & kNtErrorFileReadOnly +syscon errno EMLINK 31 31 31 31 4 # unix consensus & kNtErrorTooManyLinks +syscon errno EPIPE 32 32 32 32 109 # unix consensus & kNtErrorBrokenPipe +syscon errno EDOM 33 33 33 33 -1 # bsd consensus +syscon errno ERANGE 34 34 34 34 -1 # bsd consensus +syscon errno EDEADLK 35 11 11 11 1131 # bsd consensus & kNtErrorPossibleDeadlock +syscon errno ENAMETOOLONG 36 63 63 63 0x274f # bsd consensus +syscon errno ENOLCK 37 77 77 77 -1 # bsd consensus +syscon errno ENOTEMPTY 39 66 66 66 0x2752 # bsd consensus +syscon errno ELOOP 40 62 62 62 0x274e # bsd consensus +syscon errno ENOMSG 42 91 83 90 -1 +syscon errno EIDRM 43 90 82 89 -1 +syscon errno EUSERS 87 68 68 68 0x2754 # bsd consensus +syscon errno ENOTSOCK 88 38 38 38 0x2736 # bsd consensus +syscon errno EDESTADDRREQ 89 39 39 39 0x2737 # bsd consensus +syscon errno EMSGSIZE 90 40 40 40 0x2738 # bsd consensus & WSAEMSGSIZE +syscon errno EPROTOTYPE 91 41 41 41 0x2739 # bsd consensus +syscon errno ENOPROTOOPT 92 42 42 42 0x273a # bsd consensus +syscon errno EPROTONOSUPPORT 93 43 43 43 0x273b # bsd consensus +syscon errno ESOCKTNOSUPPORT 94 44 44 44 0x273c # bsd consensus +syscon errno ENOTSUP 95 45 45 91 0x273d +syscon errno EOPNOTSUPP 95 102 45 45 0x273d +syscon errno EPFNOSUPPORT 96 46 46 46 0x273e # bsd consensus +syscon errno EAFNOSUPPORT 97 47 47 47 0x273f # bsd consensus +syscon errno EADDRINUSE 98 48 48 48 0x2740 # bsd consensus +syscon errno EADDRNOTAVAIL 99 49 49 49 0x2741 # bsd consensus +syscon errno ENETDOWN 100 50 50 50 0x2742 # bsd consensus +syscon errno ENETUNREACH 101 51 51 51 0x2743 # bsd consensus +syscon errno ENETRESET 102 52 52 52 0x2744 # bsd consensus +syscon errno ECONNABORTED 103 53 53 53 0x2745 # bsd consensus +syscon errno ECONNRESET 104 54 54 54 0x2746 # bsd consensus & WSAECONNRESET +syscon errno ENOBUFS 105 55 55 55 0x2747 # bsd consensus +syscon errno EISCONN 106 56 56 56 0x2748 # bsd consensus +syscon errno ENOTCONN 107 57 57 57 0x2749 # bsd consensus +syscon errno ESHUTDOWN 108 58 58 58 0x274a # bsd consensus +syscon errno ETOOMANYREFS 109 59 59 59 0x274b # bsd consensus +syscon errno ETIMEDOUT 110 60 60 60 0x274c # bsd consensus +syscon errno ECONNREFUSED 111 61 61 61 0x274d # bsd consensus +syscon errno EHOSTDOWN 112 64 64 64 0x2750 # bsd consensus +syscon errno EHOSTUNREACH 113 65 65 65 0x2751 # bsd consensus +syscon errno EALREADY 114 37 37 37 0x2735 # bsd consensus +syscon errno EINPROGRESS 115 36 36 36 0x2734 # bsd consensus +syscon errno ESTALE 116 70 70 70 0x2756 # bsd consensus +syscon errno ECHRNG 44 -1 -1 -1 -1 # bsd consensus +syscon errno EL2NSYNC 45 -1 -1 -1 -1 # bsd consensus +syscon errno EL3HLT 46 -1 -1 -1 -1 # bsd consensus +syscon errno EL3RST 47 -1 -1 -1 -1 # bsd consensus +syscon errno ELNRNG 48 -1 -1 -1 -1 # bsd consensus +syscon errno EUNATCH 49 -1 -1 -1 -1 # bsd consensus +syscon errno ENOCSI 50 -1 -1 -1 -1 # bsd consensus +syscon errno EL2HLT 51 -1 -1 -1 -1 # bsd consensus +syscon errno EBADE 52 -1 -1 -1 -1 # bsd consensus +syscon errno EBADR 53 -1 -1 -1 -1 # bsd consensus +syscon errno EXFULL 54 -1 -1 -1 -1 # bsd consensus +syscon errno ENOANO 55 -1 -1 -1 -1 # bsd consensus +syscon errno EBADRQC 56 -1 -1 -1 -1 # bsd consensus +syscon errno EBADSLT 57 -1 -1 -1 -1 # bsd consensus +syscon errno EBFONT 59 -1 -1 -1 -1 # bsd consensus +syscon errno ENOSTR 60 99 -1 -1 -1 +syscon errno ENODATA 61 96 -1 -1 -1 +syscon errno ETIME 62 101 -1 -1 -1 +syscon errno ENOSR 63 98 -1 -1 -1 +syscon errno ENONET 64 -1 -1 -1 -1 # bsd consensus +syscon errno ENOPKG 65 -1 -1 -1 -1 # bsd consensus +syscon errno EREMOTE 66 71 71 71 0x2757 # bsd consensus +syscon errno ENOLINK 67 97 91 -1 -1 +syscon errno EADV 68 -1 -1 -1 -1 # bsd consensus +syscon errno ESRMNT 69 -1 -1 -1 -1 # bsd consensus +syscon errno ECOMM 70 -1 -1 -1 -1 # bsd consensus +syscon errno EPROTO 71 100 92 95 -1 +syscon errno EMULTIHOP 72 95 90 -1 -1 +syscon errno EDOTDOT 73 -1 -1 -1 -1 # bsd consensus +syscon errno EBADMSG 74 94 89 92 -1 +syscon errno EOVERFLOW 75 84 84 87 -1 +syscon errno ENOTUNIQ 76 -1 -1 -1 -1 # bsd consensus +syscon errno EBADFD 77 9 9 9 6 # file descriptor in bad state; cf. EBADF; fudged on non-Linux +syscon errno EREMCHG 78 -1 -1 -1 -1 # bsd consensus +syscon errno ELIBACC 79 -1 -1 -1 -1 # bsd consensus +syscon errno ELIBBAD 80 -1 -1 -1 -1 # bsd consensus +syscon errno ELIBSCN 81 -1 -1 -1 -1 # bsd consensus +syscon errno ELIBMAX 82 -1 -1 -1 -1 # bsd consensus +syscon errno ELIBEXEC 83 -1 -1 -1 -1 # bsd consensus +syscon errno EILSEQ 84 92 86 84 -1 +syscon errno ERESTART 85 -1 -1 -1 -1 # bsd consensus +syscon errno ESTRPIPE 86 -1 -1 -1 -1 # bsd consensus +syscon errno EUCLEAN 117 -1 -1 -1 -1 # bsd consensus +syscon errno ENOTNAM 118 -1 -1 -1 -1 # bsd consensus +syscon errno ENAVAIL 119 -1 -1 -1 -1 # bsd consensus +syscon errno EISNAM 120 -1 -1 -1 -1 # bsd consensus +syscon errno EREMOTEIO 121 -1 -1 -1 -1 # bsd consensus +syscon errno ENOMEDIUM 123 -1 -1 85 -1 +syscon errno EMEDIUMTYPE 124 -1 -1 86 -1 +syscon errno ECANCELED 125 89 85 88 -1 +syscon errno ENOKEY 126 -1 -1 -1 -1 # bsd consensus +syscon errno EKEYEXPIRED 127 -1 -1 -1 -1 # bsd consensus +syscon errno EKEYREVOKED 128 -1 -1 -1 -1 # bsd consensus +syscon errno EKEYREJECTED 129 -1 -1 -1 -1 # bsd consensus +syscon errno EOWNERDEAD 130 105 96 94 -1 +syscon errno ENOTRECOVERABLE 131 104 95 93 -1 +syscon errno ERFKILL 132 -1 -1 -1 -1 # bsd consensus +syscon errno EHWPOISON 133 -1 -1 -1 -1 # bsd consensus + +# signals +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon sig SIGHUP 1 1 1 1 1 # unix consensus & faked on nt +syscon sig SIGINT 2 2 2 2 2 # unix consensus & faked on nt +syscon sig SIGQUIT 3 3 3 3 3 # unix consensus & faked on nt +syscon sig SIGILL 4 4 4 4 4 # unix consensus & faked on nt +syscon sig SIGTRAP 5 5 5 5 5 # unix consensus & faked on nt +syscon sig SIGABRT 6 6 6 6 6 # unix consensus & faked on nt +syscon sig SIGIOT 6 6 6 6 6 # unix consensus & faked on nt +syscon sig SIGFPE 8 8 8 8 8 # unix consensus & faked on nt +syscon sig SIGKILL 9 9 9 9 9 # unix consensus & faked on nt +syscon sig SIGSEGV 11 11 11 11 11 # unix consensus & faked on nt +syscon sig SIGPIPE 13 13 13 13 13 # unix consensus & faked on nt +syscon sig SIGALRM 14 14 14 14 14 # unix consensus & faked on nt +syscon sig SIGTERM 15 15 15 15 15 # unix consensus & faked on nt +syscon sig SIGTTIN 21 21 21 21 21 # unix consensus & faked on nt +syscon sig SIGTTOU 22 22 22 22 22 # unix consensus & faked on nt +syscon sig SIGXCPU 24 24 24 24 24 # unix consensus & faked on nt +syscon sig SIGXFSZ 25 25 25 25 25 # unix consensus & faked on nt +syscon sig SIGVTALRM 26 26 26 26 26 # unix consensus & faked on nt +syscon sig SIGPROF 27 27 27 27 27 # unix consensus & faked on nt +syscon sig SIGWINCH 28 28 28 28 28 # unix consensus & faked on nt +syscon sig SIGBUS 7 10 10 10 0 # bsd consensus +syscon sig SIGUSR1 10 30 30 30 0 # bsd consensus +syscon sig SIGCHLD 17 20 20 20 0 # bsd consensus +syscon sig SIGCONT 18 19 19 19 0 # bsd consensus +syscon sig SIGIO 29 23 23 23 0 # bsd consensus +syscon sig SIGSTOP 19 17 17 17 0 # bsd consensus +syscon sig SIGSYS 31 12 12 12 0 # bsd consensus +syscon sig SIGTSTP 20 18 18 18 0 # bsd consensus +syscon sig SIGURG 23 0x10 0x10 0x10 0 # bsd consensus +syscon sig SIGUSR2 12 31 31 31 0 # bsd consensus +syscon sig SIGSTKSZ 0x2000 0x020000 0x8800 0x7000 0 +syscon sig SIGPOLL 29 0 0 0 0 +syscon sig SIGPWR 30 0 0 0 0 +syscon sig SIGSTKFLT 0x10 0 0 0 0 +syscon sig SIGUNUSED 31 0 0 0 0 +syscon sig SIGRTMAX 0 0 126 0 0 +syscon sig SIGRTMIN 0 0 65 0 0 + +# open() flags ┌──────hoo boy +# ┌──────┐ +# │┌─<<8─┴───dwFlagsAndAttributes +# ┌││─────┐ +# │││ │ ┌┴───dwDesiredAccess +# N │││ │ │ +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD T │││┌─┴┐│ Commentary +syscon open O_RDONLY 0 0 0 0 0x80000000 # unix consensus & kNtGenericRead +syscon open O_WRONLY 1 1 1 1 0x40000000 # unix consensus & kNtGenericWrite +syscon open O_RDWR 2 2 2 2 0xc0000000 # unix consensus & kNtGenericRead|kNtGenericWrite +syscon open O_ACCMODE 3 3 3 3 0xc0000000 # O_RDONLY|O_WRONLY|O_RDWR +syscon open O_APPEND 0x0400 8 8 8 0x00000004 # bsd consensus & kNtFileAppendData; won't pose issues w/ mknod(S_IFIFO) +syscon open O_CREAT 0x40 0x0200 0x0200 0x0200 0x00000040 # bsd consensus & NT faked as Linux +syscon open O_EXCL 0x80 0x0800 0x0800 0x0800 0x00000080 # bsd consensus & NT faked as Linux +syscon open O_TRUNC 0x0200 0x0400 0x0400 0x0400 0x00000200 # bsd consensus & NT faked as Linux +syscon open O_DIRECT 0x4000 0 0x010000 0 0x00200000 # kNtFileFlagNoBuffering>>8 +syscon open O_NDELAY 0x0800 4 4 4 0 # bsd consensus & kNtFileFlagWriteThrough>>8 → 0x00800000 (???) +syscon open O_NONBLOCK 0x0800 4 4 4 0 # bsd consensus +syscon open O_CLOEXEC 0x080000 0x01000000 0x100000 0x010000 0x00080000 # NT faked as Linux +syscon open O_SPARSE 0 0 0 0 0x00040000 # we invented it +syscon open O_TMPFILE 0x410000 0 0 0 0x04000100 # Linux 3.11+ (c. 2013) & kNtFileAttributeTemporary|kNtFileFlagDeleteOnClose +syscon open O_ASYNC 0x2000 0x40 0x40 0x40 0 # bsd consensus +syscon open O_NOFOLLOW 0x020000 0x0100 0x0100 0x0100 0 # bsd consensus +syscon open O_SYNC 0x101000 0x80 0x80 0x80 0 # bsd consensus +syscon open O_DIRECTORY 0x010000 0x100000 0x020000 0x020000 0 +syscon open O_NOCTTY 0x0100 0x020000 0x8000 0x8000 0 # used for remote viewing (default behavior on freebsd) +syscon open O_DSYNC 0x1000 0x400000 0 0x80 0 +syscon open O_RSYNC 0x101000 0 0 0x80 0 +syscon open O_NOATIME 0x040000 0 0 0 0 +syscon open O_PATH 0x200000 0 0 0 0 +syscon open O_EXEC 0 0 0x040000 0 0 +syscon open O_TTY_INIT 0 0 0x080000 0 0 +syscon compat O_LARGEFILE 0 0 0 0 0 + +syscon compat MAP_FILE 0 0 0 0 0 # consensus +syscon mmap MAP_SHARED 1 1 1 1 1 # forced consensus & faked nt +syscon mmap MAP_PRIVATE 2 2 2 2 2 # forced consensus & faked nt +syscon mmap MAP_FIXED 16 16 16 16 16 # unix consensus; openbsd appears to forbid; faked nt +syscon mmap MAP_ANONYMOUS 0x20 0x1000 0x1000 0x1000 0x20 # bsd consensus; faked nt +syscon compat MAP_ANON 0x20 0x1000 0x1000 0x1000 0x20 # bsd consensus; faked nt +syscon mmap MAP_NORESERVE 0x4000 0x40 0 0 0 # Linux calls it "reserve"; NT calls it "commit"? which is default? +syscon mmap MAP_GROWSDOWN 0x0100 0 0x0400 0x0400 0x100000 # MAP_STACK on BSD; MEM_TOP_DOWN on NT +syscon compat MAP_STACK 0x020000 0 0x0400 0x4000 0x100000 +syscon mmap MAP_HUGETLB 0x040000 0 0 0 0x80000000 # kNtSecLargePages +syscon mmap MAP_HUGE_MASK 63 0 0 0 0 +syscon mmap MAP_HUGE_SHIFT 26 0 0 0 0 +syscon mmap MAP_LOCKED 0x2000 0 0 0 0 +syscon mmap MAP_NONBLOCK 0x010000 0 0 0 0 +syscon mmap MAP_POPULATE 0x8000 0 0 0 0 +syscon mmap MAP_TYPE 15 0 0 0 0 # what is it +syscon compat MAP_EXECUTABLE 0x1000 0 0 0 0 # ignored +syscon compat MAP_DENYWRITE 0x0800 0 0 0 0 +syscon compat MAP_32BIT 0x40 0 0x080000 0 0 # iffy + +syscon madv MADV_NORMAL 0 0 0 0 0x00000080 # consensus & kNtFileAttributeNormal +syscon compat POSIX_FADV_NORMAL 0 0 0 0 0x00000080 # consensus & kNtFileAttributeNormal +syscon compat POSIX_MADV_NORMAL 0 0 0 0 0x00000080 # consensus & kNtFileAttributeNormal +syscon madv MADV_DONTNEED 4 4 4 4 0 # TODO(jart): weird nt decommit thing? +syscon compat POSIX_MADV_DONTNEED 4 4 4 4 0 # unix consensus +syscon compat POSIX_FADV_DONTNEED 4 0 4 4 0 # unix consensus +syscon madv MADV_RANDOM 1 1 1 1 0x10000000 # unix consensus & kNtFileFlagRandomAccess +syscon compat POSIX_MADV_RANDOM 1 1 1 1 0x10000000 # unix consensus & kNtFileFlagRandomAccess +syscon compat POSIX_FADV_RANDOM 1 0 1 1 0x10000000 # unix consensus & kNtFileFlagRandomAccess +syscon madv MADV_SEQUENTIAL 2 2 2 2 0x8000000 # unix consensus & kNtFileFlagSequentialScan +syscon compat POSIX_MADV_SEQUENTIAL 2 2 2 2 0x8000000 # unix consensus +syscon compat POSIX_FADV_SEQUENTIAL 2 0 2 2 0x8000000 # TODO(jart): double check xnu +syscon madv MADV_WILLNEED 3 3 3 3 3 # unix consensus (faked on NT) +syscon compat POSIX_MADV_WILLNEED 3 3 3 3 3 # unix consensus +syscon compat POSIX_FADV_WILLNEED 3 0 3 3 3 # TODO(jart): double check xnu +syscon madv MADV_MERGEABLE 12 0 0 0 0 # turns on (private anon range) page scanning and merging service (linux only) +syscon madv MADV_UNMERGEABLE 13 0 0 0 0 # turns off mergeable (linux only) +syscon madv MADV_FREE 8 5 5 6 8 # Linux 4.5+ (c. 2016) / NT Faked → VMOfferPriorityNormal (Win8+) +syscon madv MADV_HUGEPAGE 14 0 0 0 0 # TODO(jart): why would we need it? +syscon madv MADV_NOHUGEPAGE 15 0 0 0 0 # TODO(jart): why would we need it? +syscon madv MADV_DODUMP 17 0 0 0 0 # TODO(jart): what is it? +syscon madv MADV_DOFORK 11 0 0 0 0 # TODO(jart): what is it? +syscon madv MADV_DONTDUMP 0x10 0 0 0 0 # TODO(jart): what is it? +syscon madv MADV_DONTFORK 10 0 0 0 0 # TODO(jart): what is it? +syscon madv MADV_HWPOISON 100 0 0 0 0 # TODO(jart): what is it? +syscon madv MADV_REMOVE 9 0 0 0 0 # TODO(jart): what is it? +syscon fadv POSIX_FADV_NOREUSE 5 0 5 0 0 # wut + +# posix_spawn() +# only native on xnu +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon spawn POSIX_SPAWN_RESETIDS 1 1 1 1 0 # unix consensus +syscon spawn POSIX_SPAWN_SETPGROUP 2 2 2 2 0 # unix consensus +syscon spawn POSIX_SPAWN_SETSIGDEF 4 4 0x10 0x10 0 +syscon spawn POSIX_SPAWN_SETSIGMASK 8 8 0x20 0x20 0 +syscon spawn POSIX_SPAWN_SETSCHEDPARAM 0x10 0 4 4 0 +syscon spawn POSIX_SPAWN_SETSCHEDULER 0x20 0 8 8 0 +syscon spawn POSIX_SPAWN_USEVFORK 0x40 0 0 0 0 + +# mprotect(), etc. +# digital restrictions management for the people +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon mprot PROT_NONE 0 0 0 0 0 # unix consensus (nt needs special business logic here) +syscon mprot PROT_READ 1 1 1 1 1 # unix consensus +syscon mprot PROT_WRITE 2 2 2 2 2 # unix consensus +syscon mprot PROT_EXEC 4 4 4 4 4 # unix consensus +syscon mprot PROT_GROWSDOWN 0x01000000 0 0 0 0x01000000 # bsd consensus +syscon mprot PROT_GROWSUP 0x02000000 0 0 0 0 + +syscon mremap MREMAP_MAYMOVE 1 1 1 1 1 # faked non-linux (b/c linux only) +syscon mremap MREMAP_FIXED 2 2 2 2 2 # faked non-linux (b/c linux only) + +syscon splice SPLICE_F_MOVE 1 0 0 0 0 # can be safely ignored by polyfill; it's a hint +syscon splice SPLICE_F_NONBLOCK 2 0 0 0 0 # can be safely ignored by polyfill, since linux says it doesn't apply to underlying FDs +syscon splice SPLICE_F_MORE 4 0 0 0 0 # can be safely ignored by polyfill; it's a hint +syscon splice SPLICE_F_GIFT 8 0 0 0 0 # can probably be ignored by polyfill + +# access() flags +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon access F_OK 0 0 0 0 0 # consensus +syscon access X_OK 1 1 1 1 0xa0000000 # unix consensus and kNtGenericExecute | kNtGenericRead +syscon access W_OK 2 2 2 2 0x40000000 # unix consensus and kNtGenericWrite +syscon access R_OK 4 4 4 4 0x80000000 # unix consensus and kNtGenericRead + +# stat::st_mode constants +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon stat S_IFREG 0100000 0100000 0100000 0100000 0100000 +syscon stat S_IFBLK 0060000 0060000 0060000 0060000 0060000 +syscon stat S_IFCHR 0020000 0020000 0020000 0020000 0020000 +syscon stat S_IFDIR 0040000 0040000 0040000 0040000 0040000 +syscon stat S_IFIFO 0010000 0010000 0010000 0010000 0010000 +syscon stat S_IFMT 0170000 0170000 0170000 0170000 0170000 +syscon stat S_IFLNK 0120000 0120000 0120000 0120000 0120000 +syscon stat S_IFSOCK 0140000 0140000 0140000 0140000 0140000 + +# chmod() permission flag constants +# consider just typing the octal codes +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon stat S_ISVTX 01000 01000 01000 01000 01000 # unix consensus STICKY BIT +syscon stat S_ISGID 02000 02000 02000 02000 02000 # unix consensus a.k.a. setgid bit +syscon stat S_ISUID 04000 04000 04000 04000 04000 # unix consensus a.k.a. setuid bit + +syscon stat S_IEXEC 00100 00100 00100 00100 00100 # unix consensus +syscon stat S_IWRITE 00200 00200 00200 00200 00200 # unix consensus +syscon stat S_IREAD 00400 00400 00400 00400 00400 # unix consensus + +syscon stat S_IXUSR 00100 00100 00100 00100 00100 # unix consensus +syscon stat S_IWUSR 00200 00200 00200 00200 00200 # unix consensus +syscon stat S_IRUSR 00400 00400 00400 00400 00400 # unix consensus +syscon stat S_IRWXU 00700 00700 00700 00700 00700 # unix consensus + +syscon stat S_IXGRP 00010 00010 00010 00010 00010 # unix consensus +syscon stat S_IWGRP 00020 00020 00020 00020 00020 # unix consensus +syscon stat S_IRGRP 00040 00040 00040 00040 00040 # unix consensus +syscon stat S_IRWXG 00070 00070 00070 00070 00070 # unix consensus + +syscon stat S_IXOTH 00001 00001 00001 00001 00001 # unix consensus +syscon stat S_IWOTH 00002 00002 00002 00002 00002 # unix consensus +syscon stat S_IROTH 00004 00004 00004 00004 00004 # unix consensus +syscon stat S_IRWXO 00007 00007 00007 00007 00007 # unix consensus + +# fcntl() +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon fcntl2 F_DUPFD 0 0 0 0 0 # consensus + +syscon fcntl2 F_GETFD 1 1 1 1 1 # unix consensus & faked nt +syscon fcntl2 F_SETFD 2 2 2 2 2 # unix consensus & faked nt +syscon fcntl3 FD_CLOEXEC 1 1 1 1 1 # unix consensus & inverse nt (kNtHandleFlagInherit) + +syscon fcntl2 F_GETFL 3 3 3 3 3 # unix consensus & faked nt +syscon fcntl2 F_SETFL 4 4 4 4 4 # (unix consensus & faked nt) +# fcntl3 O_NONBLOCK +# fcntl3 O_APPEND +# fcntl3 O_ASYNC +# fcntl3 O_DIRECT +# fcntl3 O_NOATIME + +syscon fcntl2 F_SETOWN 8 6 6 6 0 # bsd consensus +syscon fcntl2 F_GETOWN 9 5 5 5 0 # bsd consensus + +syscon fcntl F_ULOCK 0 0 0 0 0 # consensus +syscon fcntl F_RDLCK 0 1 1 1 0 # bsd consensus +syscon fcntl F_LOCK 1 1 1 1 0 # unix consensus +syscon fcntl F_WRLCK 1 3 3 3 0 # bsd consensus +syscon fcntl F_TLOCK 2 2 2 2 0 # unix consensus +syscon fcntl F_UNLCK 2 2 2 2 0 # unix consensus +syscon fcntl F_TEST 3 3 3 3 0 # unix consensus +syscon fcntl F_GETLK 5 7 11 7 0 +syscon fcntl F_GETLK64 5 0 0 0 0 +syscon fcntl F_SETLK 6 8 12 8 0 +syscon fcntl F_SETLK64 6 0 0 0 0 +syscon fcntl F_SETLKW 7 9 13 9 0 +syscon fcntl F_SETLKW64 7 0 0 0 0 +syscon fcntl F_SETSIG 10 0 0 0 0 +syscon fcntl F_GETSIG 11 0 0 0 0 +syscon fcntl F_SETOWN_EX 15 0 0 0 0 +syscon fcntl F_GETOWN_EX 0x10 0 0 0 0 +syscon fcntl F_OFD_GETLK 36 0 0 0 0 +syscon fcntl F_OFD_SETLK 37 0 0 0 0 +syscon fcntl F_OFD_SETLKW 38 0 0 0 0 +syscon fcntl F_SETLEASE 0x0400 0 0 0 0 +syscon fcntl F_GETLEASE 0x0401 0 0 0 0 +syscon fcntl F_NOTIFY 0x0402 0 0 0 0 +syscon fcntl F_DUPFD_CLOEXEC 0x0406 67 17 10 0 +syscon fcntl F_SETPIPE_SZ 0x0407 0 0 0 0 +syscon fcntl F_GETPIPE_SZ 0x0408 0 0 0 0 + +# openat(), fstatat(), linkat(), etc. magnums +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon at AT_FDCWD -100 -2 -100 -100 -100 # faked nt +syscon at AT_SYMLINK_FOLLOW 0x0400 0x40 0x0400 4 0 +syscon at AT_SYMLINK_NOFOLLOW 0x0100 0x20 0x0200 2 0 # TODO(jart): What should NT do? +syscon at AT_REMOVEDIR 0x0200 0x80 0x0800 8 0x0200 # faked nt +syscon at AT_EACCESS 0x0200 0x10 0x0100 1 0 +syscon at AT_EMPTY_PATH 0x1000 0 0 0 0 # linux 2.6.39+; see unlink, O_TMPFILE, etc. + +syscon memfd MFD_CLOEXEC 1 0 0 0 0 +syscon memfd MFD_ALLOW_SEALING 2 0 0 0 0 + +# getauxval() keys +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon auxv AT_EXECFD 2 0 2 0 0 +syscon auxv AT_PHDR 3 0 3 0 0 +syscon auxv AT_PHENT 4 0 4 0 0 +syscon auxv AT_PHNUM 5 0 5 0 0 +syscon auxv AT_PAGESZ 6 0 6 0 0 +syscon auxv AT_BASE 7 0 7 0 0 +syscon auxv AT_ENTRY 9 0 9 0 0 +syscon auxv AT_NOTELF 10 0 10 0 0 +syscon auxv AT_OSRELDATE 0 0 18 0 0 +syscon auxv AT_UID 11 0 0 0 0 +syscon auxv AT_EUID 12 0 0 0 0 +syscon auxv AT_GID 13 0 0 0 0 +syscon auxv AT_EGID 14 0 0 0 0 +syscon auxv AT_PLATFORM 15 0 0 0 0 # RHEL5.0 limit +syscon auxv AT_CLKTCK 17 0 0 0 0 +syscon auxv AT_DCACHEBSIZE 19 0 0 0 0 +syscon auxv AT_ICACHEBSIZE 20 0 0 0 0 +syscon auxv AT_UCACHEBSIZE 21 0 0 0 0 +syscon auxv AT_SECURE 23 0 0 0 0 +syscon auxv AT_BASE_PLATFORM 24 0 0 0 0 +syscon auxv AT_RANDOM 25 0 0 0 0 +syscon auxv AT_EXECFN 31 999 999 999 999 # faked on non-linux +syscon auxv AT_SYSINFO_EHDR 33 0 0 0 0 +syscon auxv AT_NO_AUTOMOUNT 0x0800 0 0 0 0 + +syscon sigact SA_RESTORER 0x04000000 0 0 0 0 +syscon sigact SA_ONSTACK 0x08000000 1 1 1 0 # bsd consensus +syscon sigact SA_RESTART 0x10000000 2 2 2 0 # bsd consensus +syscon sigact SA_NOCLDSTOP 1 8 8 8 0 # bsd consensus +syscon sigact SA_NOCLDWAIT 2 0x20 0x20 0x20 0 # bsd consensus +syscon sigact SA_SIGINFO 4 0x40 0x40 0x40 0 # bsd consensus +syscon sigact SA_NODEFER 0x40000000 0x10 0x10 0x10 0 # bsd consensus +syscon sigact SA_NOMASK 0x40000000 0x10 0x10 0x10 0 # linux/obsolete +syscon sigact SA_RESETHAND 0x80000000 4 4 4 0 # bsd consensus +syscon sigact SA_ONESHOT 0x80000000 0 0 0 0 + +syscon clock CLOCK_REALTIME 0 0 0 0 0 # consensus +syscon clock CLOCK_PROCESS_CPUTIME_ID 2 -1 15 2 0 +syscon clock CLOCK_THREAD_CPUTIME_ID 3 -1 14 4 0 +syscon clock CLOCK_MONOTONIC 4 1 4 3 1 # XNU/NT faked +syscon clock CLOCK_MONOTONIC_RAW 4 4 0x4000 0x4000 4 # XNU/NT/FreeBSD/OpenBSD faked +syscon clock CLOCK_REALTIME_COARSE 5 -1 0 0 0 # bsd consensus +syscon clock CLOCK_MONOTONIC_COARSE 6 -1 0 0 0 # bsd consensus +syscon clock CLOCK_BOOTTIME 7 -1 0 6 0 +syscon clock CLOCK_REALTIME_ALARM 8 -1 0 0 0 # bsd consensus +syscon clock CLOCK_BOOTTIME_ALARM 9 -1 0 0 0 # bsd consensus +syscon clock CLOCK_TAI 11 -1 0 0 0 # bsd consensus + +syscon epoll EPOLLIN 1 0 0 0 0 +syscon epoll EPOLL_CTL_ADD 1 0 0 0 0 +syscon epoll EPOLLPRI 2 0 0 0 0 +syscon epoll EPOLL_CTL_DEL 2 0 0 0 0 +syscon epoll EPOLL_CTL_MOD 3 0 0 0 0 +syscon epoll EPOLLOUT 4 0 0 0 0 +syscon epoll EPOLLERR 8 0 0 0 0 +syscon epoll EPOLLHUP 0x10 0 0 0 0 +syscon epoll EPOLLRDNORM 0x40 0 0 0 0 +syscon epoll EPOLLRDBAND 0x80 0 0 0 0 +syscon epoll EPOLLWRNORM 0x0100 0 0 0 0 +syscon epoll EPOLLWRBAND 0x0200 0 0 0 0 +syscon epoll EPOLLMSG 0x0400 0 0 0 0 +syscon epoll EPOLLRDHUP 0x2000 0 0 0 0 +syscon epoll EPOLL_CLOEXEC 0x080000 0 0 0 0 +syscon epoll EPOLLEXCLUSIVE 0x10000000 0 0 0 0 +syscon epoll EPOLLWAKEUP 0x20000000 0 0 0 0 +syscon epoll EPOLLONESHOT 0x40000000 0 0 0 0 +syscon epoll EPOLLET 0x80000000 0 0 0 0 + +# {set,get}sockopt(fd, level=SOL_SOCKET, X, ...) +# +# * 0 we define as EINVAL +# * -1 we define as no-op +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon so SO_REUSEPORT 15 0x0200 0x0200 0x0200 4 # bsd consensus (NT calls it SO_REUSEADDR) +syscon so SO_REUSEADDR 2 4 4 4 -1 # bsd consensus (default behavior on NT) +syscon so SO_KEEPALIVE 9 8 8 8 8 # bsd consensus +syscon so SO_DONTROUTE 5 0x10 0x10 0x10 0x10 # bsd consensus +syscon so SO_BROADCAST 6 0x20 0x20 0x20 0x20 # bsd consensus +syscon so SO_LINGER 13 0x80 0x80 0x80 0x80 # bsd consensus +syscon so SO_DEBUG 1 1 1 1 1 # consensus +syscon so SO_ACCEPTCONN 30 2 2 2 2 # bsd consensus +syscon so SO_ERROR 4 0x1007 0x1007 0x1007 0x1007 # bsd consensus +syscon so SO_OOBINLINE 10 0x0100 0x0100 0x0100 0x0100 # bsd consensus +syscon so SO_SNDBUF 7 0x1001 0x1001 0x1001 0x1001 # bsd consensus +syscon so SO_RCVBUF 8 0x1002 0x1002 0x1002 0x1002 # bsd consensus +syscon so SO_RCVLOWAT 18 0x1004 0x1004 0x1004 0x1004 # bsd consensus +syscon so SO_RCVTIMEO 20 0x1006 0x1006 0x1006 0x1006 # bsd consensus +syscon so SO_EXCLUSIVEADDRUSE -1 -1 -1 -1 0xfffffffb # hoo boy +syscon so SO_SNDLOWAT 19 0x1003 0x1003 0x1003 0x1003 # bsd consensus +syscon so SO_SNDTIMEO 21 0x1005 0x1005 0x1005 0x1005 # bsd consensus +syscon so SO_TYPE 3 0x1008 0x1008 0x1008 0x1008 # bsd consensus +syscon so SO_TIMESTAMP 29 0x0400 0x0400 0x0800 0 +syscon so SO_DOMAIN 39 0 0x1019 0 0 +syscon so SO_MAX_PACING_RATE 47 0 0x1018 0 0 +syscon so SO_PEERCRED 17 0 0 0x1022 0 +syscon so SO_PROTOCOL 38 0 0x1016 0 0 +syscon so SO_ATTACH_BPF 50 0 0 0 0 +syscon so SO_ATTACH_FILTER 26 0 0 0 0 +syscon so SO_ATTACH_REUSEPORT_CBPF 51 0 0 0 0 +syscon so SO_ATTACH_REUSEPORT_EBPF 52 0 0 0 0 +syscon so SO_BINDTODEVICE 25 0 0 0 0 +syscon so SO_BPF_EXTENSIONS 48 0 0 0 0 +syscon so SO_BSDCOMPAT 14 0 0 0 0 +syscon so SO_BUSY_POLL 46 0 0 0 0 +syscon so SO_CNX_ADVICE 53 0 0 0 0 +syscon so SO_DETACH_BPF 27 0 0 0 0 +syscon so SO_DETACH_FILTER 27 0 0 0 0 +syscon so SO_GET_FILTER 26 0 0 0 0 +syscon so SO_INCOMING_CPU 49 0 0 0 0 +syscon so SO_LOCK_FILTER 44 0 0 0 0 +syscon so SO_MARK 36 0 0 0 0 +syscon so SO_NOFCS 43 0 0 0 0 +syscon so SO_NO_CHECK 11 0 0 0 0 +syscon so SO_PASSCRED 0x10 0 0 0 0 +syscon so SO_PASSSEC 34 0 0 0 0 +syscon so SO_PEEK_OFF 42 0 0 0 0 +syscon so SO_PEERNAME 28 0 0 0 0 +syscon so SO_PEERSEC 31 0 0 0 0 +syscon so SO_PRIORITY 12 0 0 0 0 +syscon so SO_RCVBUFFORCE 33 0 0 0 0 +syscon so SO_RXQ_OVFL 40 0 0 0 0 +syscon so SO_SECURITY_AUTHENTICATION 22 0 0 0 0 +syscon so SO_SECURITY_ENCRYPTION_NETWORK 24 0 0 0 0 +syscon so SO_SECURITY_ENCRYPTION_TRANSPORT 23 0 0 0 0 +syscon so SO_SELECT_ERR_QUEUE 45 0 0 0 0 +syscon so SO_SNDBUFFORCE 0x20 0 0 0 0 +syscon so SO_TIMESTAMPING 37 0 0 0 0 +syscon so SO_TIMESTAMPNS 35 0 0 0 0 +syscon so SO_WIFI_STATUS 41 0 0 0 0 + +# {set,get}sockopt(fd, level=IPPROTO_TCP, X, ...) +# » most elite of all tuning groups +# +# * 0 we define as EINVAL +# * -1 we define as no-op +# +# @see https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt +# @see https://www.iana.org/assignments/tcp-parameters/tcp-parameters.txt +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon tcp TCP_NODELAY 1 1 1 1 1 # consensus +syscon tcp TCP_MAXSEG 2 2 2 2 0 # reduces tcp segment size; see also tcp offloading +syscon tcp TCP_FASTOPEN 23 261 0x0401 0 15 # reduces roundtrips; for listener; Linux 3.7+ (c. 2012) / or is windows it 0x22? /proc/sys/net/ipv4/tcp_fastopen TODO(jart): MSG_FASTOPEN +syscon tcp TCP_KEEPIDLE 4 0 0x100 0 0 # keepalives +syscon tcp TCP_KEEPINTVL 5 0x101 0x200 0 0 # keepalives +syscon tcp TCP_KEEPCNT 6 0x102 0x400 0 0 # keepalives +syscon tcp TCP_SYNCNT 7 0 0 0 0 # how hard to syn packet the enemy +syscon tcp TCP_COOKIE_TRANSACTIONS 15 0 0 0 0 # defense against the syn packets +syscon tcp TCP_LINGER2 8 0 0 0 0 # orphaned fin-wait-2 lifetime cf. net.ipv4.tcp_fin_timeout see cloudflare blog +syscon tcp TCP_CORK 3 0 0 0 0 # linux tries to automate iovec +syscon tcp TCP_NOTSENT_LOWAT 25 513 0 0 0 # limit unset byte queue +syscon tcp TCP_INFO 11 0 0x20 0 0 # get connection info +syscon tcp TCP_CC_INFO 26 0 0 0 0 # get congestion control info +syscon tcp TCP_CONGESTION 13 0 0x40 0 0 # set traffic control +syscon tcp TCP_MD5SIG 14 0 0x10 4 0 # what is it (rfc2385) +syscon tcp TCP_MD5SIG_MAXKEYLEN 80 0 0 0 0 # what is it +syscon tcp TCP_TIMESTAMP 24 0 0 0 0 # what is it +syscon tcp TCP_USER_TIMEOUT 18 0 0 0 0 # what is it +syscon tcp TCP_QUICKACK 12 0 0 0 0 # what is it +syscon tcp TCP_SAVE_SYN 27 0 0 0 0 # record syn packets +syscon tcp TCP_SAVED_SYN 28 0 0 0 0 # get recorded syn packets +syscon tcp TCP_THIN_DUPACK 17 0 0 0 0 # what is it +syscon tcp TCP_QUEUE_SEQ 21 0 0 0 0 # what is it +syscon tcp TCP_WINDOW_CLAMP 10 0 0 0 0 # what is it +syscon tcp TCP_DEFER_ACCEPT 9 0 0 0 0 # what is it +syscon tcp TCP_REPAIR 19 0 0 0 0 # what is it +syscon tcp TCP_REPAIR_OPTIONS 22 0 0 0 0 # what is it +syscon tcp TCP_REPAIR_QUEUE 20 0 0 0 0 # what is it +syscon tcp TCP_THIN_LINEAR_TIMEOUTS 16 0 0 0 0 # what is it + +syscon misc EXTA 14 0x4b00 0x4b00 0x4b00 0 # bsd consensus +syscon misc EXTB 15 0x9600 0x9600 0x9600 0 # bsd consensus +syscon misc ERA 0x02002c 45 45 0 0 +syscon misc EMPTY 0 0 0 0 0 # consensus + +syscon pr PR_SET_PTRACER_ANY -1 0 0 0 0 +syscon pr PR_ENDIAN_BIG 0 0 0 0 0 # consensus +syscon pr PR_FP_EXC_DISABLED 0 0 0 0 0 # consensus +syscon pr PR_MCE_KILL_CLEAR 0 0 0 0 0 # consensus +syscon pr PR_MCE_KILL_LATE 0 0 0 0 0 # consensus +syscon pr PR_SPEC_NOT_AFFECTED 0 0 0 0 0 # consensus +syscon pr PR_SPEC_STORE_BYPASS 0 0 0 0 0 # consensus +syscon pr PR_TIMING_STATISTICAL 0 0 0 0 0 # consensus +syscon pr PR_CAP_AMBIENT_IS_SET 1 0 0 0 0 +syscon pr PR_ENDIAN_LITTLE 1 0 0 0 0 +syscon pr PR_FPEMU_NOPRINT 1 0 0 0 0 +syscon pr PR_FP_EXC_NONRECOV 1 0 0 0 0 +syscon pr PR_FP_MODE_FR 1 0 0 0 0 +syscon pr PR_MCE_KILL_EARLY 1 0 0 0 0 +syscon pr PR_MCE_KILL_SET 1 0 0 0 0 +syscon pr PR_SET_MM_START_CODE 1 0 0 0 0 +syscon pr PR_SET_PDEATHSIG 1 0 0 0 0 +syscon pr PR_SPEC_PRCTL 1 0 0 0 0 +syscon pr PR_TIMING_TIMESTAMP 1 0 0 0 0 +syscon pr PR_TSC_ENABLE 1 0 0 0 0 +syscon pr PR_UNALIGN_NOPRINT 1 0 0 0 0 +syscon pr PR_CAP_AMBIENT_RAISE 2 0 0 0 0 +syscon pr PR_ENDIAN_PPC_LITTLE 2 0 0 0 0 +syscon pr PR_FPEMU_SIGFPE 2 0 0 0 0 +syscon pr PR_FP_EXC_ASYNC 2 0 0 0 0 +syscon pr PR_FP_MODE_FRE 2 0 0 0 0 +syscon pr PR_GET_PDEATHSIG 2 0 0 0 0 +syscon pr PR_MCE_KILL_DEFAULT 2 0 0 0 0 +syscon pr PR_SET_MM_END_CODE 2 0 0 0 0 +syscon pr PR_SPEC_ENABLE 2 0 0 0 0 +syscon pr PR_TSC_SIGSEGV 2 0 0 0 0 +syscon pr PR_UNALIGN_SIGBUS 2 0 0 0 0 +syscon pr PR_CAP_AMBIENT_LOWER 3 0 0 0 0 +syscon pr PR_FP_EXC_PRECISE 3 0 0 0 0 +syscon pr PR_GET_DUMPABLE 3 0 0 0 0 +syscon pr PR_SET_MM_START_DATA 3 0 0 0 0 +syscon pr PR_CAP_AMBIENT_CLEAR_ALL 4 0 0 0 0 +syscon pr PR_SET_DUMPABLE 4 0 0 0 0 +syscon pr PR_SET_MM_END_DATA 4 0 0 0 0 +syscon pr PR_SPEC_DISABLE 4 0 0 0 0 +syscon pr PR_GET_UNALIGN 5 0 0 0 0 +syscon pr PR_SET_MM_START_STACK 5 0 0 0 0 +syscon pr PR_SET_MM_START_BRK 6 0 0 0 0 +syscon pr PR_SET_UNALIGN 6 0 0 0 0 +syscon pr PR_GET_KEEPCAPS 7 0 0 0 0 +syscon pr PR_SET_MM_BRK 7 0 0 0 0 +syscon pr PR_SET_KEEPCAPS 8 0 0 0 0 +syscon pr PR_SET_MM_ARG_START 8 0 0 0 0 +syscon pr PR_SPEC_FORCE_DISABLE 8 0 0 0 0 +syscon pr PR_GET_FPEMU 9 0 0 0 0 +syscon pr PR_SET_MM_ARG_END 9 0 0 0 0 +syscon pr PR_SET_FPEMU 10 0 0 0 0 +syscon pr PR_SET_MM_ENV_START 10 0 0 0 0 +syscon pr PR_GET_FPEXC 11 0 0 0 0 +syscon pr PR_SET_MM_ENV_END 11 0 0 0 0 +syscon pr PR_SET_FPEXC 12 0 0 0 0 +syscon pr PR_SET_MM_AUXV 12 0 0 0 0 +syscon pr PR_GET_TIMING 13 0 0 0 0 +syscon pr PR_SET_MM_EXE_FILE 13 0 0 0 0 +syscon pr PR_SET_MM_MAP 14 0 0 0 0 +syscon pr PR_SET_TIMING 14 0 0 0 0 +syscon pr PR_SET_MM_MAP_SIZE 15 0 0 0 0 +syscon pr PR_SET_NAME 15 0 0 0 0 +syscon pr PR_GET_NAME 0x10 0 0 0 0 +syscon pr PR_GET_ENDIAN 19 0 0 0 0 +syscon pr PR_SET_ENDIAN 20 0 0 0 0 +syscon pr PR_GET_SECCOMP 21 0 0 0 0 +syscon pr PR_SET_SECCOMP 22 0 0 0 0 +syscon pr PR_CAPBSET_READ 23 0 0 0 0 +syscon pr PR_CAPBSET_DROP 24 0 0 0 0 +syscon pr PR_GET_TSC 25 0 0 0 0 +syscon pr PR_SET_TSC 26 0 0 0 0 +syscon pr PR_GET_SECUREBITS 27 0 0 0 0 +syscon pr PR_SET_SECUREBITS 28 0 0 0 0 +syscon pr PR_SET_TIMERSLACK 29 0 0 0 0 +syscon pr PR_GET_TIMERSLACK 30 0 0 0 0 +syscon pr PR_TASK_PERF_EVENTS_DISABLE 31 0 0 0 0 +syscon pr PR_TASK_PERF_EVENTS_ENABLE 0x20 0 0 0 0 +syscon pr PR_MCE_KILL 33 0 0 0 0 +syscon pr PR_MCE_KILL_GET 34 0 0 0 0 +syscon pr PR_SET_MM 35 0 0 0 0 +syscon pr PR_SET_CHILD_SUBREAPER 36 0 0 0 0 +syscon pr PR_GET_CHILD_SUBREAPER 37 0 0 0 0 +syscon pr PR_SET_NO_NEW_PRIVS 38 0 0 0 0 +syscon pr PR_GET_NO_NEW_PRIVS 39 0 0 0 0 +syscon pr PR_GET_TID_ADDRESS 40 0 0 0 0 +syscon pr PR_SET_THP_DISABLE 41 0 0 0 0 +syscon pr PR_GET_THP_DISABLE 42 0 0 0 0 +syscon pr PR_MPX_ENABLE_MANAGEMENT 43 0 0 0 0 +syscon pr PR_MPX_DISABLE_MANAGEMENT 44 0 0 0 0 +syscon pr PR_SET_FP_MODE 45 0 0 0 0 +syscon pr PR_GET_FP_MODE 46 0 0 0 0 +syscon pr PR_CAP_AMBIENT 47 0 0 0 0 +syscon pr PR_GET_SPECULATION_CTRL 52 0 0 0 0 +syscon pr PR_SET_SPECULATION_CTRL 53 0 0 0 0 +syscon pr PR_FP_EXC_SW_ENABLE 0x80 0 0 0 0 +syscon pr PR_FP_EXC_DIV 0x010000 0 0 0 0 +syscon pr PR_FP_EXC_OVF 0x020000 0 0 0 0 +syscon pr PR_FP_EXC_UND 0x040000 0 0 0 0 +syscon pr PR_FP_EXC_RES 0x080000 0 0 0 0 +syscon pr PR_FP_EXC_INV 0x100000 0 0 0 0 +syscon pr PR_SET_PTRACER 0x59616d61 0 0 0 0 + +syscon log LOG_EMERG 0 0 0 0 0 # consensus +syscon log LOG_KERN 0 0 0 0 0 # consensus +syscon log LOG_ALERT 1 1 1 1 0 # unix consensus +syscon log LOG_PID 1 1 1 1 0 # unix consensus +syscon log LOG_CONS 2 2 2 2 0 # unix consensus +syscon log LOG_CRIT 2 2 2 2 0 # unix consensus +syscon log LOG_ERR 3 3 3 3 0 # unix consensus +syscon log LOG_ODELAY 4 4 4 4 0 # unix consensus +syscon log LOG_WARNING 4 4 4 4 0 # unix consensus +syscon log LOG_NOTICE 5 5 5 5 0 # unix consensus +syscon log LOG_INFO 6 6 6 6 0 # unix consensus +syscon log LOG_DEBUG 7 7 7 7 0 # unix consensus +syscon log LOG_PRIMASK 7 7 7 7 0 # unix consensus +syscon log LOG_NDELAY 8 8 8 8 0 # unix consensus +syscon log LOG_USER 8 8 8 8 0 # unix consensus +syscon log LOG_MAIL 0x10 0x10 0x10 0x10 0 # unix consensus +syscon log LOG_NOWAIT 0x10 0x10 0x10 0x10 0 # unix consensus +syscon log LOG_DAEMON 24 24 24 24 0 # unix consensus +syscon log LOG_NFACILITIES 24 25 24 24 0 +syscon log LOG_AUTH 0x20 0x20 0x20 0x20 0 # unix consensus +syscon log LOG_PERROR 0x20 0x20 0x20 0x20 0 # unix consensus +syscon log LOG_SYSLOG 40 40 40 40 0 # unix consensus +syscon log LOG_LPR 48 48 48 48 0 # unix consensus +syscon log LOG_NEWS 56 56 56 56 0 # unix consensus +syscon log LOG_UUCP 0x40 0x40 0x40 0x40 0 # unix consensus +syscon log LOG_CRON 72 72 72 72 0 # unix consensus +syscon log LOG_SELECT 76 0 0 0 0 +syscon log LOG_SENSE 77 0 0 0 0 +syscon log LOG_LOCAL0 0x80 0x80 0x80 0x80 0 # unix consensus +syscon log LOG_LOCAL1 136 136 136 136 0 # unix consensus +syscon log LOG_LOCAL2 144 144 144 144 0 # unix consensus +syscon log LOG_LOCAL3 152 152 152 152 0 # unix consensus +syscon log LOG_LOCAL4 160 160 160 160 0 # unix consensus +syscon log LOG_LOCAL5 168 168 168 168 0 # unix consensus +syscon log LOG_LOCAL6 176 176 176 176 0 # unix consensus +syscon log LOG_LOCAL7 184 184 184 184 0 # unix consensus +syscon log LOG_FACMASK 0x03f8 0x03f8 0x03f8 0x03f8 0 # unix consensus + +syscon sg SG_DXFER_TO_FROM_DEV -4 0 0 0 0 +syscon sg SG_DXFER_FROM_DEV -3 0 0 0 0 +syscon sg SG_DXFER_TO_DEV -2 0 0 0 0 +syscon sg SG_DXFER_NONE -1 0 0 0 0 +syscon sg SG_DEF_COMMAND_Q 0 0 0 0 0 # consensus +syscon sg SG_DEF_FORCE_LOW_DMA 0 0 0 0 0 # consensus +syscon sg SG_DEF_FORCE_PACK_ID 0 0 0 0 0 # consensus +syscon sg SG_DEF_KEEP_ORPHAN 0 0 0 0 0 # consensus +syscon sg SG_DEF_UNDERRUN_FLAG 0 0 0 0 0 # consensus +syscon sg SG_INFO_INDIRECT_IO 0 0 0 0 0 # consensus +syscon sg SG_INFO_OK 0 0 0 0 0 # consensus +syscon sg SG_SCSI_RESET_NOTHING 0 0 0 0 0 # consensus +syscon sg SG_DEFAULT_RETRIES 1 0 0 0 0 +syscon sg SG_FLAG_DIRECT_IO 1 0 0 0 0 +syscon sg SG_INFO_CHECK 1 0 0 0 0 +syscon sg SG_INFO_OK_MASK 1 0 0 0 0 +syscon sg SG_SCSI_RESET_DEVICE 1 0 0 0 0 +syscon sg SG_FLAG_LUN_INHIBIT 2 0 0 0 0 +syscon sg SG_INFO_DIRECT_IO 2 0 0 0 0 +syscon sg SG_SCSI_RESET_BUS 2 0 0 0 0 +syscon sg SG_SCSI_RESET_HOST 3 0 0 0 0 +syscon sg SG_INFO_MIXED_IO 4 0 0 0 0 +syscon sg SG_INFO_DIRECT_IO_MASK 6 0 0 0 0 +syscon misc VOLUME_OVERFLOW 13 0 0 0 0 +syscon sg SG_MAX_QUEUE 0x10 0 0 0 0 +syscon sg SG_MAX_SENSE 0x10 0 0 0 0 +syscon sg SG_DEFAULT_TIMEOUT 0x1770 0 0 0 0 +syscon sg SG_SET_TIMEOUT 0x2201 0 0 0 0 +syscon sg SG_GET_TIMEOUT 0x2202 0 0 0 0 +syscon sg SG_EMULATED_HOST 0x2203 0 0 0 0 +syscon sg SG_SET_TRANSFORM 0x2204 0 0 0 0 +syscon sg SG_GET_TRANSFORM 0x2205 0 0 0 0 +syscon sg SG_GET_COMMAND_Q 0x2270 0 0 0 0 +syscon sg SG_SET_COMMAND_Q 0x2271 0 0 0 0 +syscon sg SG_GET_RESERVED_SIZE 0x2272 0 0 0 0 +syscon sg SG_SET_RESERVED_SIZE 0x2275 0 0 0 0 +syscon sg SG_GET_SCSI_ID 0x2276 0 0 0 0 +syscon sg SG_SET_FORCE_LOW_DMA 0x2279 0 0 0 0 +syscon sg SG_GET_LOW_DMA 0x227a 0 0 0 0 +syscon sg SG_SET_FORCE_PACK_ID 0x227b 0 0 0 0 +syscon sg SG_GET_PACK_ID 0x227c 0 0 0 0 +syscon sg SG_GET_NUM_WAITING 0x227d 0 0 0 0 +syscon sg SG_SET_DEBUG 0x227e 0 0 0 0 +syscon sg SG_GET_SG_TABLESIZE 0x227f 0 0 0 0 +syscon sg SG_GET_VERSION_NUM 0x2282 0 0 0 0 +syscon sg SG_NEXT_CMD_LEN 0x2283 0 0 0 0 +syscon sg SG_SCSI_RESET 0x2284 0 0 0 0 +syscon sg SG_IO 0x2285 0 0 0 0 +syscon sg SG_GET_REQUEST_TABLE 0x2286 0 0 0 0 +syscon sg SG_SET_KEEP_ORPHAN 0x2287 0 0 0 0 +syscon sg SG_GET_KEEP_ORPHAN 0x2288 0 0 0 0 +syscon sg SG_BIG_BUFF 0x8000 0 0 0 0 +syscon sg SG_DEF_RESERVED_SIZE 0x8000 0 0 0 0 +syscon sg SG_SCATTER_SZ 0x8000 0 0 0 0 +syscon sg SG_FLAG_NO_DXFER 0x010000 0 0 0 0 + +syscon posix _POSIX_ARG_MAX 0x1000 0x1000 0x1000 0x1000 0 # unix consensus +syscon posix _POSIX_CHILD_MAX 25 25 25 25 0 # unix consensus +syscon posix _POSIX_HOST_NAME_MAX 255 255 255 255 0 # unix consensus +syscon posix _POSIX_LINK_MAX 8 8 8 8 0 # unix consensus +syscon posix _POSIX_LOGIN_NAME_MAX 9 9 9 9 0 # unix consensus +syscon posix _POSIX_MAX_CANON 255 255 255 255 0 # unix consensus +syscon posix _POSIX_MAX_INPUT 255 255 255 255 0 # unix consensus +syscon posix _POSIX_NAME_MAX 14 14 14 14 14 # forced consensus +syscon posix _POSIX_NGROUPS_MAX 8 8 8 8 0 # unix consensus +syscon posix _POSIX_OPEN_MAX 20 20 20 20 20 # forced consensus +syscon posix _POSIX_PATH_MAX 255 255 255 255 255 # forced consensus +syscon posix _POSIX_PIPE_BUF 0x0200 0x0200 0x0200 0x0200 0 # unix consensus +syscon posix _POSIX_RE_DUP_MAX 255 255 255 255 0 # unix consensus +syscon posix _POSIX_SEM_NSEMS_MAX 0x0100 0x0100 0x0100 0x0100 0 # unix consensus +syscon posix _POSIX_SEM_VALUE_MAX 0x7fff 0x7fff 0x7fff 0x7fff 0 # unix consensus +syscon posix _POSIX_SSIZE_MAX 0x7fff 0x7fff 0x7fff 0x7fff 0 # unix consensus +syscon posix _POSIX_STREAM_MAX 8 8 8 8 0 # unix consensus +syscon posix _POSIX_SYMLINK_MAX 255 255 255 255 0 # unix consensus +syscon posix _POSIX_SYMLOOP_MAX 8 8 8 8 0 # unix consensus +syscon posix _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 4 4 4 0 # unix consensus +syscon posix _POSIX_THREAD_KEYS_MAX 0x80 0x80 0x80 0x80 0 # unix consensus +syscon posix _POSIX_TTY_NAME_MAX 9 9 9 9 0 # unix consensus +syscon posix _POSIX_TZNAME_MAX 6 6 6 6 0 # unix consensus +syscon posix _POSIX_CLOCK_SELECTION 0x031069 -1 -1 -1 0 # bsd consensus +syscon posix _POSIX_FSYNC 0x031069 0x030db0 0x030db0 0x030db0 0 # bsd consensus +syscon posix _POSIX_MAPPED_FILES 0x031069 0x030db0 0x030db0 0x030db0 0 # bsd consensus +syscon posix _POSIX_MEMORY_PROTECTION 0x031069 0x030db0 0x030db0 0x030db0 0 # bsd consensus +syscon posix _POSIX_READER_WRITER_LOCKS 0x031069 0x030db0 0x030db0 0x030db0 0 # bsd consensus +syscon posix _POSIX_THREADS 0x031069 0x030db0 0x030db0 0x030db0 0 # bsd consensus +syscon posix _POSIX_THREAD_ATTR_STACKADDR 0x031069 0x030db0 0x030db0 0x030db0 0 # bsd consensus +syscon posix _POSIX_THREAD_ATTR_STACKSIZE 0x031069 0x030db0 0x030db0 0x030db0 0 # bsd consensus +syscon posix _POSIX_ADVISORY_INFO 0x031069 -1 0x030db0 -1 0 +syscon posix _POSIX_ASYNCHRONOUS_IO 0x031069 -1 0x030db0 -1 0 +syscon posix _POSIX_BARRIERS 0x031069 -1 0x030db0 0x030db0 0 +syscon posix _POSIX_JOB_CONTROL 1 0x030db0 1 1 0 +syscon posix _POSIX_MEMLOCK 0x031069 -1 -1 0x030db0 0 +syscon posix _POSIX_MEMLOCK_RANGE 0x031069 -1 0x030db0 0x030db0 0 +syscon posix _POSIX_MESSAGE_PASSING 0x031069 -1 0x030db0 -1 0 +syscon posix _POSIX_NO_TRUNC 1 0x030db0 1 1 0 +syscon posix _POSIX_RAW_SOCKETS 0x031069 -1 0x030db0 0x030db0 0 +syscon posix _POSIX_REALTIME_SIGNALS 0x031069 -1 0x030db0 -1 0 +syscon posix _POSIX_REGEXP 1 0x030db0 1 1 0 +syscon posix _POSIX_SEMAPHORES 0x031069 -1 0x030db0 0x030db0 0 +syscon posix _POSIX_SHARED_MEMORY_OBJECTS 0x031069 -1 0x030db0 0x031069 0 +syscon posix _POSIX_SHELL 1 0x030db0 1 1 0 +syscon posix _POSIX_SPAWN 0x031069 -1 0x030db0 0x030db0 0 +syscon posix _POSIX_SPIN_LOCKS 0x031069 -1 0x030db0 0x030db0 0 +syscon posix _POSIX_THREAD_PRIORITY_SCHEDULING 0x031069 -1 0x030db0 -1 0 +syscon posix _POSIX_THREAD_PROCESS_SHARED 0x031069 0x030db0 0x030db0 -1 0 +syscon posix _POSIX_THREAD_SAFE_FUNCTIONS 0x031069 0x030db0 -1 0x030db0 0 +syscon posix _POSIX_THREAD_THREADS_MAX 0x40 0x40 0x40 4 0 +syscon posix _POSIX_TIMEOUTS 0x031069 -1 0x030db0 0x030db0 0 +syscon posix _POSIX_TIMERS 0x031069 -1 0x030db0 -1 0 +syscon posix _POSIX_VERSION 0x031069 0x030db0 0x030db0 0x031069 0 +syscon posix _POSIX_VDISABLE 0 255 255 255 0 # bsd consensus +syscon posix _POSIX_AIO_LISTIO_MAX 2 2 2 0 0 +syscon posix _POSIX_AIO_MAX 1 1 1 0 0 +syscon posix _POSIX_CHOWN_RESTRICTED 0 0x030db0 1 1 0 +syscon posix _POSIX_CLOCKRES_MIN 0x01312d00 0 0x01312d00 0x01312d00 0 +syscon posix _POSIX_CPUTIME 0 -1 0x030db0 0x031069 0 +syscon posix _POSIX_DELAYTIMER_MAX 0x20 0x20 0x20 0 0 +syscon posix _POSIX_MONOTONIC_CLOCK 0 -1 0x030db0 0x030db0 0 +syscon posix _POSIX_MQ_OPEN_MAX 8 8 8 0 0 +syscon posix _POSIX_MQ_PRIO_MAX 0x20 0x20 0x20 0 0 +syscon posix _POSIX_RTSIG_MAX 8 8 8 0 0 +syscon posix _POSIX_SAVED_IDS 1 0x030db0 0 1 0 +syscon posix _POSIX_SIGQUEUE_MAX 0x20 0x20 0x20 0 0 +syscon posix _POSIX_THREAD_CPUTIME 0 -1 0x030db0 0x031069 0 +syscon posix _POSIX_TIMER_MAX 0x20 0x20 0x20 0 0 +syscon posix _POSIX_IPV6 0x031069 0x030db0 0 0 0 +syscon posix _POSIX_SS_REPL_MAX 0 4 4 0 0 +syscon posix _POSIX_TRACE_EVENT_NAME_MAX 0 30 30 0 0 +syscon posix _POSIX_TRACE_NAME_MAX 0 8 8 0 0 +syscon posix _POSIX_TRACE_SYS_MAX 0 8 8 0 0 +syscon posix _POSIX_TRACE_USER_EVENT_MAX 0 0x20 0x20 0 0 +syscon posix _POSIX_V6_LP64_OFF64 1 1 0 0 0 +syscon posix _POSIX_V7_LP64_OFF64 1 1 0 0 0 + +syscon icmp6 ICMP6_DST_UNREACH_NOROUTE 0 0 0 0 0 # consensus +syscon icmp6 ICMP6_PARAMPROB_HEADER 0 0 0 0 0 # consensus +syscon icmp6 ICMP6_TIME_EXCEED_TRANSIT 0 0 0 0 0 # consensus +syscon icmp6 ICMP6_DST_UNREACH_ADMIN 1 1 1 1 1 # consensus +syscon icmp6 ICMP6_PARAMPROB_NEXTHEADER 1 1 1 1 1 # consensus +syscon icmp6 ICMP6_TIME_EXCEED_REASSEMBLY 1 1 1 1 1 # consensus +syscon icmp6 ICMP6_DST_UNREACH 1 1 1 1 0 # unix consensus +syscon icmp6 ICMP6_FILTER 1 18 18 18 0 # bsd consensus +syscon icmp6 ICMP6_DST_UNREACH_BEYONDSCOPE 2 2 2 2 2 # consensus +syscon icmp6 ICMP6_PARAMPROB_OPTION 2 2 2 2 2 # consensus +syscon icmp6 ICMP6_PACKET_TOO_BIG 2 2 2 2 0 # unix consensus +syscon icmp6 ICMP6_DST_UNREACH_ADDR 3 3 3 3 3 # consensus +syscon icmp6 ICMP6_TIME_EXCEEDED 3 3 3 3 0 # unix consensus +syscon icmp6 ICMP6_DST_UNREACH_NOPORT 4 4 4 4 4 # consensus +syscon icmp6 ICMP6_PARAM_PROB 4 4 4 4 0 # unix consensus +syscon icmp6 ICMP6_RR_FLAGS_PREVDONE 8 8 8 8 0 # unix consensus +syscon icmp6 ICMP6_RR_FLAGS_SPECSITE 0x10 0x10 0x10 0x10 0 # unix consensus +syscon icmp6 ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x10 0x40 0x40 0x40 0 # bsd consensus +syscon icmp6 ICMP6_RR_FLAGS_FORCEAPPLY 0x20 0x20 0x20 0x20 0 # unix consensus +syscon icmp6 ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x20 0x80 0x80 0x80 0 # bsd consensus +syscon icmp6 ICMP6_RR_FLAGS_REQRESULT 0x40 0x40 0x40 0x40 0 # unix consensus +syscon icmp6 ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40 0x40 0x40 0x40 0 # unix consensus +syscon icmp6 ICMP6_INFOMSG_MASK 0x80 0x80 0x80 0x80 0x80 # consensus +syscon icmp6 ICMP6_ECHO_REQUEST 0x80 0x80 0x80 0x80 0 # unix consensus +syscon icmp6 ICMP6_RR_FLAGS_TEST 0x80 0x80 0x80 0x80 0 # unix consensus +syscon icmp6 ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80 0x80 0x80 0x80 0 # unix consensus +syscon icmp6 ICMP6_ECHO_REPLY 129 129 129 129 0 # unix consensus +syscon icmp6 ICMP6_ROUTER_RENUMBERING 138 138 138 138 0 # unix consensus +syscon icmp6 ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100 0x0100 0x0100 0x0100 0 # unix consensus +syscon icmp6 ICMP6_RR_RESULT_FLAGS_OOB 0x0200 0x0200 0x0200 0x0200 0 # unix consensus + +syscon iproto IPPROTO_HOPOPTS 0 0 0 0 0 # consensus +syscon iproto IPPROTO_ICMP 1 1 1 1 1 # consensus +syscon iproto IPPROTO_IDP 22 22 22 22 22 # consensus +syscon iproto IPPROTO_IGMP 2 2 2 2 2 # consensus +syscon iproto IPPROTO_IP 0 0 0 0 0 # consensus +syscon iproto IPPROTO_PUP 12 12 12 12 12 # consensus +syscon iproto IPPROTO_RAW 255 255 255 255 255 # consensus +syscon iproto IPPROTO_TCP 6 6 6 6 6 # consensus +syscon iproto IPPROTO_UDP 17 17 17 17 17 # consensus +syscon iproto IPPROTO_AH 51 51 51 51 0 # unix consensus +syscon iproto IPPROTO_DSTOPTS 60 60 60 60 0 # unix consensus +syscon iproto IPPROTO_EGP 8 8 8 8 0 # unix consensus +syscon iproto IPPROTO_ENCAP 98 98 98 98 0 # unix consensus +syscon iproto IPPROTO_ESP 50 50 50 50 0 # unix consensus +syscon iproto IPPROTO_FRAGMENT 44 44 44 44 0 # unix consensus +syscon iproto IPPROTO_GRE 47 47 47 47 0 # unix consensus +syscon iproto IPPROTO_ICMPV6 58 58 58 58 0 # unix consensus +syscon iproto IPPROTO_IPIP 4 4 4 4 0 # unix consensus +syscon iproto IPPROTO_IPV6 41 41 41 41 0 # unix consensus +syscon iproto IPPROTO_NONE 59 59 59 59 0 # unix consensus +syscon iproto IPPROTO_PIM 103 103 103 103 0 # unix consensus +syscon iproto IPPROTO_ROUTING 43 43 43 43 0 # unix consensus +syscon iproto IPPROTO_RSVP 46 46 46 46 0 # unix consensus +syscon iproto IPPROTO_TP 29 29 29 29 0 # unix consensus +syscon iproto IPPROTO_MPLS 137 0 137 137 0 +syscon iproto IPPROTO_MTP 92 92 92 0 0 +syscon iproto IPPROTO_SCTP 132 132 132 0 0 +syscon iproto IPPROTO_MH 135 0 135 0 0 +syscon iproto IPPROTO_UDPLITE 136 0 136 0 0 +syscon iproto IPPROTO_BEETPH 94 0 0 0 0 +syscon iproto IPPROTO_COMP 108 0 0 0 0 +syscon iproto IPPROTO_DCCP 33 0 0 0 0 + +syscon sio SIOCADDMULTI 0x8931 0x80206931 0x80206931 0x80206931 0 # bsd consensus +syscon sio SIOCATMARK 0x8905 0x40047307 0x40047307 0x40047307 0 # bsd consensus +syscon sio SIOCDELMULTI 0x8932 0x80206932 0x80206932 0x80206932 0 # bsd consensus +syscon sio SIOCDIFADDR 0x8936 0x80206919 0x80206919 0x80206919 0 # bsd consensus +syscon sio SIOCGIFADDR 0x8915 0xc0206921 0xc0206921 0xc0206921 0 # bsd consensus +syscon sio SIOCGIFBRDADDR 0x8919 0xc0206923 0xc0206923 0xc0206923 0 # bsd consensus +syscon sio SIOCGIFDSTADDR 0x8917 0xc0206922 0xc0206922 0xc0206922 0 # bsd consensus +syscon sio SIOCGIFFLAGS 0x8913 0xc0206911 0xc0206911 0xc0206911 0 # bsd consensus +syscon sio SIOCGIFMETRIC 0x891d 0xc0206917 0xc0206917 0xc0206917 0 # bsd consensus +syscon sio SIOCGIFNETMASK 0x891b 0xc0206925 0xc0206925 0xc0206925 0 # bsd consensus +syscon sio SIOCGPGRP 0x8904 0x40047309 0x40047309 0x40047309 0 # bsd consensus +syscon sio SIOCSIFADDR 0x8916 0x8020690c 0x8020690c 0x8020690c 0 # bsd consensus +syscon sio SIOCSIFBRDADDR 0x891a 0x80206913 0x80206913 0x80206913 0 # bsd consensus +syscon sio SIOCSIFDSTADDR 0x8918 0x8020690e 0x8020690e 0x8020690e 0 # bsd consensus +syscon sio SIOCSIFFLAGS 0x8914 0x80206910 0x80206910 0x80206910 0 # bsd consensus +syscon sio SIOCSIFMETRIC 0x891e 0x80206918 0x80206918 0x80206918 0 # bsd consensus +syscon sio SIOCSIFNETMASK 0x891c 0x80206916 0x80206916 0x80206916 0 # bsd consensus +syscon sio SIOCSPGRP 0x8902 0x80047308 0x80047308 0x80047308 0 # bsd consensus +syscon sio SIOCGIFCONF 0x8912 0xc00c6924 0xc0106924 0xc0106924 0 +syscon sio SIOCGIFMTU 0x8921 0xc0206933 0xc0206933 0xc020697e 0 +syscon sio SIOCSIFMTU 0x8922 0x80206934 0x80206934 0x8020697f 0 +syscon sio SIOCGIFINDEX 0x8933 0 0xc0206920 0 0 +syscon sio SIOCSIFNAME 0x8923 0 0x80206928 0 0 +syscon sio SIOCADDDLCI 0x8980 0 0 0 0 +syscon sio SIOCADDRT 0x890b 0 0 0 0 +syscon sio SIOCDARP 0x8953 0 0 0 0 +syscon sio SIOCDELDLCI 0x8981 0 0 0 0 +syscon sio SIOCDELRT 0x890c 0 0 0 0 +syscon sio SIOCDEVPRIVATE 0x89f0 0 0 0 0 +syscon sio SIOCDRARP 0x8960 0 0 0 0 +syscon sio SIOCGARP 0x8954 0 0 0 0 +syscon sio SIOCGIFBR 0x8940 0 0 0 0 +syscon sio SIOCGIFCOUNT 0x8938 0 0 0 0 +syscon sio SIOCGIFENCAP 0x8925 0 0 0 0 +syscon sio SIOCGIFHWADDR 0x8927 0 0 0 0 +syscon sio SIOCGIFMAP 0x8970 0 0 0 0 +syscon sio SIOCGIFMEM 0x891f 0 0 0 0 +syscon sio SIOCGIFNAME 0x8910 0 0 0 0 +syscon sio SIOCGIFPFLAGS 0x8935 0 0 0 0 +syscon sio SIOCGIFSLAVE 0x8929 0 0 0 0 +syscon sio SIOCGIFTXQLEN 0x8942 0 0 0 0 +syscon sio SIOCGRARP 0x8961 0 0 0 0 +syscon sio SIOCGSTAMP 0x8906 0 0 0 0 +syscon sio SIOCGSTAMPNS 0x8907 0 0 0 0 +syscon sio SIOCPROTOPRIVATE 0x89e0 0 0 0 0 +syscon sio SIOCRTMSG 0x890d 0 0 0 0 +syscon sio SIOCSARP 0x8955 0 0 0 0 +syscon sio SIOCSIFBR 0x8941 0 0 0 0 +syscon sio SIOCSIFENCAP 0x8926 0 0 0 0 +syscon sio SIOCSIFHWADDR 0x8924 0 0 0 0 +syscon sio SIOCSIFHWBROADCAST 0x8937 0 0 0 0 +syscon sio SIOCSIFLINK 0x8911 0 0 0 0 +syscon sio SIOCSIFMAP 0x8971 0 0 0 0 +syscon sio SIOCSIFMEM 0x8920 0 0 0 0 +syscon sio SIOCSIFPFLAGS 0x8934 0 0 0 0 +syscon sio SIOCSIFSLAVE 0x8930 0 0 0 0 +syscon sio SIOCSIFTXQLEN 0x8943 0 0 0 0 +syscon sio SIOCSRARP 0x8962 0 0 0 0 +syscon sio SIOGIFINDEX 0x8933 0 0 0 0 + +syscon af AF_UNSPEC 0 0 0 0 0 # consensus +syscon af AF_UNIX 1 1 1 1 1 # consensus +syscon af AF_LOCAL 1 1 1 1 0 # unix consensus +syscon af AF_FILE 1 0 0 0 0 +syscon af AF_INET 2 2 2 2 2 # consensus +syscon af AF_AX25 3 0 0 0 0 +syscon af AF_IPX 4 23 23 23 0 # bsd consensus +syscon af AF_APPLETALK 5 0x10 0x10 0x10 0x10 # bsd consensus +syscon af AF_NETROM 6 0 0 0 0 +syscon af AF_BRIDGE 7 0 0 0 0 +syscon af AF_ATMPVC 8 0 0 0 0 +syscon af AF_X25 9 0 0 0 0 +syscon af AF_INET6 10 30 28 24 23 +syscon af AF_ROSE 11 0 0 0 0 +syscon af AF_NETBEUI 13 0 0 0 0 +syscon af AF_SECURITY 14 0 0 0 0 +syscon af AF_KEY 15 0 0 30 0 +syscon af AF_ROUTE 16 17 17 17 0 # bsd consensus +syscon af AF_NETLINK 16 0 0 0 0 +syscon af AF_PACKET 17 0 0 0 0 +syscon af AF_ASH 18 0 0 0 0 +syscon af AF_ECONET 19 0 0 0 0 +syscon af AF_ATMSVC 20 0 0 0 0 +syscon af AF_RDS 21 0 0 0 0 +syscon af AF_SNA 22 11 11 11 11 # bsd consensus +syscon af AF_IRDA 23 0 0 0 0 +syscon af AF_PPPOX 24 0 0 0 0 +syscon af AF_WANPIPE 25 0 0 0 0 +syscon af AF_LLC 26 0 0 0 0 +syscon af AF_IB 27 0 0 0 0 +syscon af AF_MPLS 28 0 0 33 0 +syscon af AF_CAN 29 0 0 0 0 +syscon af AF_TIPC 30 0 0 0 0 +syscon af AF_BLUETOOTH 31 0 36 0x20 0 +syscon af AF_IUCV 0x20 0 0 0 0 +syscon af AF_RXRPC 33 0 0 0 0 +syscon af AF_ISDN 34 28 26 26 0 +syscon af AF_PHONET 35 0 0 0 0 +syscon af AF_IEEE802154 36 0 0 0 0 +syscon af AF_CAIF 37 0 0 0 0 +syscon af AF_ALG 38 0 0 0 0 +syscon af AF_NFC 39 0 0 0 0 +syscon af AF_VSOCK 40 0 0 0 0 +syscon af AF_KCM 41 0 0 0 0 +syscon af AF_MAX 42 40 42 36 35 + + +syscon pf PF_UNIX 1 1 1 1 1 # consensus +syscon pf PF_UNSPEC 0 0 0 0 0 # consensus +syscon pf PF_APPLETALK 5 0x10 0x10 0x10 0x10 # bsd consensus +syscon pf PF_SNA 22 11 11 11 11 # bsd consensus +syscon pf PF_INET6 10 30 28 24 23 +syscon pf PF_MAX 42 40 42 36 35 +syscon pf PF_INET 2 2 2 2 0 # unix consensus +syscon pf PF_LOCAL 1 1 1 1 0 # unix consensus +syscon pf PF_IPX 4 23 23 23 0 # bsd consensus +syscon pf PF_ROUTE 0x10 17 17 17 0 # bsd consensus +syscon pf PF_ISDN 34 28 26 26 0 +syscon pf PF_KEY 15 29 27 30 0 +syscon pf PF_BLUETOOTH 31 0 36 0x20 0 +syscon pf PF_MPLS 28 0 0 33 0 +syscon pf PF_ALG 38 0 0 0 0 +syscon pf PF_ASH 18 0 0 0 0 +syscon pf PF_ATMPVC 8 0 0 0 0 +syscon pf PF_ATMSVC 20 0 0 0 0 +syscon pf PF_AX25 3 0 0 0 0 +syscon pf PF_BRIDGE 7 0 0 0 0 +syscon pf PF_CAIF 37 0 0 0 0 +syscon pf PF_CAN 29 0 0 0 0 +syscon pf PF_ECONET 19 0 0 0 0 +syscon pf PF_FILE 1 0 0 0 0 +syscon pf PF_IB 27 0 0 0 0 +syscon pf PF_IEEE802154 36 0 0 0 0 +syscon pf PF_IRDA 23 0 0 0 0 +syscon pf PF_IUCV 0x20 0 0 0 0 +syscon pf PF_KCM 41 0 0 0 0 +syscon pf PF_LLC 26 0 0 0 0 +syscon pf PF_NETBEUI 13 0 0 0 0 +syscon pf PF_NETLINK 0x10 0 0 0 0 +syscon pf PF_NETROM 6 0 0 0 0 +syscon pf PF_NFC 39 0 0 0 0 +syscon pf PF_PACKET 17 0 0 0 0 +syscon pf PF_PHONET 35 0 0 0 0 +syscon pf PF_PPPOX 24 0 0 0 0 +syscon pf PF_RDS 21 0 0 0 0 +syscon pf PF_ROSE 11 0 0 0 0 +syscon pf PF_RXRPC 33 0 0 0 0 +syscon pf PF_SECURITY 14 0 0 0 0 +syscon pf PF_TIPC 30 0 0 0 0 +syscon pf PF_VSOCK 40 0 0 0 0 +syscon pf PF_WANPIPE 25 0 0 0 0 +syscon pf PF_X25 9 0 0 0 0 + +syscon ip IP_DEFAULT_MULTICAST_LOOP 1 1 1 1 1 # consensus +syscon ip IP_DEFAULT_MULTICAST_TTL 1 1 1 1 1 # consensus +syscon ip IP_PMTUDISC_DONT 0 0 0 0 0 # consensus +syscon ip IP_HDRINCL 3 2 2 2 2 # bsd consensus +syscon ip IP_MAX_MEMBERSHIPS 20 0x0fff 0x0fff 0x0fff 20 # bsd consensus +syscon ip IP_OPTIONS 4 1 1 1 1 # bsd consensus +syscon ip IP_TOS 1 3 3 3 8 # bsd consensus +syscon ip IP_RECVTTL 12 24 65 31 21 +syscon ip IP_ADD_MEMBERSHIP 35 12 12 12 0 # bsd consensus +syscon ip IP_DROP_MEMBERSHIP 36 13 13 13 0 # bsd consensus +syscon ip IP_MULTICAST_IF 0x20 9 9 9 0 # bsd consensus +syscon ip IP_MULTICAST_LOOP 34 11 11 11 0 # bsd consensus +syscon ip IP_MULTICAST_TTL 33 10 10 10 0 # bsd consensus +syscon ip IP_RECVOPTS 6 5 5 5 0 # bsd consensus +syscon ip IP_RECVRETOPTS 7 6 6 6 0 # bsd consensus +syscon ip IP_RETOPTS 7 8 8 8 0 # bsd consensus +syscon ip IP_TTL 2 4 4 4 0 # bsd consensus +syscon ip IP_ADD_SOURCE_MEMBERSHIP 39 70 70 0 15 +syscon ip IP_BLOCK_SOURCE 38 72 72 0 17 +syscon ip IP_DROP_SOURCE_MEMBERSHIP 40 71 71 0 0x10 +syscon ip IP_UNBLOCK_SOURCE 37 73 73 0 18 +syscon ip IP_IPSEC_POLICY 0x10 21 21 0 0 +syscon ip IP_MINTTL 21 0 66 0x20 0 +syscon ip IP_MSFILTER 41 74 74 0 0 +syscon ip IP_PKTINFO 8 26 0 0 19 +syscon ip IP_RECVTOS 13 0 68 0 40 +syscon ip IP_MTU 14 0 0 0 73 # bsd consensus +syscon ip IP_MTU_DISCOVER 10 0 0 0 71 # bsd consensus +syscon ip IP_RECVERR 11 0 0 0 75 # bsd consensus +syscon ip IP_UNICAST_IF 50 0 0 0 31 # bsd consensus +syscon ip IP_ORIGDSTADDR 20 0 27 0 0 +syscon ip IP_RECVORIGDSTADDR 20 0 27 0 0 +syscon ip IP_BIND_ADDRESS_NO_PORT 24 0 0 0 0 +syscon ip IP_CHECKSUM 23 0 0 0 0 +syscon ip IP_FREEBIND 15 0 0 0 0 +syscon ip IP_MULTICAST_ALL 49 0 0 0 0 +syscon ip IP_NODEFRAG 22 0 0 0 0 +syscon ip IP_PASSSEC 18 0 0 0 0 +syscon ip IP_PKTOPTIONS 9 0 0 0 0 +syscon ip IP_PMTUDISC 10 0 0 0 0 +syscon ip IP_PMTUDISC_DO 2 0 0 0 0 +syscon ip IP_PMTUDISC_INTERFACE 4 0 0 0 0 +syscon ip IP_PMTUDISC_OMIT 5 0 0 0 0 +syscon ip IP_PMTUDISC_PROBE 3 0 0 0 0 +syscon ip IP_PMTUDISC_WANT 1 0 0 0 0 +syscon ip IP_ROUTER_ALERT 5 0 0 0 0 +syscon ip IP_TRANSPARENT 19 0 0 0 0 +syscon ip IP_XFRM_POLICY 17 0 0 0 0 +syscon ip INET_ADDRSTRLEN 0x10 0x10 0x10 0x10 22 # unix consensus + +syscon ipv6 IPV6_PMTUDISC_DONT 0 0 0 0 0 # consensus +syscon ipv6 IPV6_RTHDR_LOOSE 0 0 0 0 0 # consensus +syscon ipv6 IPV6_RTHDR_TYPE_0 0 0 0 0 0 # consensus +syscon ipv6 IPV6_CHECKSUM 7 26 26 26 26 # bsd consensus +syscon ipv6 IPV6_JOIN_GROUP 20 12 12 12 12 # bsd consensus +syscon ipv6 IPV6_LEAVE_GROUP 21 13 13 13 13 # bsd consensus +syscon ipv6 IPV6_MULTICAST_HOPS 18 10 10 10 10 # bsd consensus +syscon ipv6 IPV6_MULTICAST_IF 17 9 9 9 9 # bsd consensus +syscon ipv6 IPV6_MULTICAST_LOOP 19 11 11 11 11 # bsd consensus +syscon ipv6 IPV6_UNICAST_HOPS 0x10 4 4 4 4 # bsd consensus +syscon ipv6 IPV6_V6ONLY 26 27 27 27 27 # bsd consensus +syscon ipv6 IPV6_RECVTCLASS 66 35 57 57 40 +syscon ipv6 IPV6_TCLASS 67 36 61 61 39 +syscon ipv6 IPV6_DONTFRAG 62 0 62 62 14 +syscon ipv6 IPV6_HOPLIMIT 52 0 47 47 21 +syscon ipv6 IPV6_HOPOPTS 54 0 49 49 1 +syscon ipv6 IPV6_PKTINFO 50 0 46 46 19 +syscon ipv6 IPV6_RECVRTHDR 56 0 38 38 38 +syscon ipv6 IPV6_RTHDR 57 0 51 51 0x20 +syscon ipv6 IPV6_DSTOPTS 59 0 50 50 0 +syscon ipv6 IPV6_IPSEC_POLICY 34 28 28 0 0 +syscon ipv6 IPV6_NEXTHOP 9 0 48 48 0 +syscon ipv6 IPV6_PATHMTU 61 0 44 44 0 +syscon ipv6 IPV6_RECVDSTOPTS 58 0 40 40 0 +syscon ipv6 IPV6_RECVHOPLIMIT 51 0 37 37 0 +syscon ipv6 IPV6_RECVHOPOPTS 53 0 39 39 0 +syscon ipv6 IPV6_RECVPATHMTU 60 0 43 43 0 +syscon ipv6 IPV6_RECVPKTINFO 49 0 36 36 0 +syscon ipv6 IPV6_RTHDRDSTOPTS 55 0 35 35 0 +syscon ipv6 IPV6_RTHDR_STRICT 1 1 1 0 0 +syscon ipv6 IPV6_ADD_MEMBERSHIP 20 0 0 0 12 # bsd consensus +syscon ipv6 IPV6_DROP_MEMBERSHIP 21 0 0 0 13 # bsd consensus +syscon ipv6 IPV6_HDRINCL 36 0 0 0 2 # bsd consensus +syscon ipv6 IPV6_MTU 24 0 0 0 72 # bsd consensus +syscon ipv6 IPV6_MTU_DISCOVER 23 0 0 0 71 # bsd consensus +syscon ipv6 IPV6_RECVERR 25 0 0 0 75 # bsd consensus +syscon ipv6 IPV6_2292DSTOPTS 4 23 0 0 0 +syscon ipv6 IPV6_2292HOPLIMIT 8 20 0 0 0 +syscon ipv6 IPV6_2292HOPOPTS 3 22 0 0 0 +syscon ipv6 IPV6_2292PKTINFO 2 19 0 0 0 +syscon ipv6 IPV6_2292PKTOPTIONS 6 25 0 0 0 +syscon ipv6 IPV6_2292RTHDR 5 24 0 0 0 +syscon ipv6 IPV6_AUTOFLOWLABEL 0 0 59 59 0 +syscon ipv6 IPV6_ADDRFORM 1 0 0 0 0 +syscon ipv6 IPV6_AUTHHDR 10 0 0 0 0 +syscon ipv6 IPV6_JOIN_ANYCAST 27 0 0 0 0 +syscon ipv6 IPV6_LEAVE_ANYCAST 28 0 0 0 0 +syscon ipv6 IPV6_PMTUDISC_DO 2 0 0 0 0 +syscon ipv6 IPV6_PMTUDISC_INTERFACE 4 0 0 0 0 +syscon ipv6 IPV6_PMTUDISC_OMIT 5 0 0 0 0 +syscon ipv6 IPV6_PMTUDISC_PROBE 3 0 0 0 0 +syscon ipv6 IPV6_PMTUDISC_WANT 1 0 0 0 0 +syscon ipv6 IPV6_ROUTER_ALERT 22 0 0 0 0 +syscon ipv6 IPV6_RXDSTOPTS 59 0 0 0 0 +syscon ipv6 IPV6_RXHOPOPTS 54 0 0 0 0 +syscon ipv6 IPV6_XFRM_POLICY 35 0 0 0 0 +syscon ipv6 IPV6_MINHOPCOUNT 0 0 0 65 0 +syscon ipv6 IPV6_ORIGDSTADDR 0 0 72 0 0 +syscon ipv6 IPV6_RECVORIGDSTADDR 0 0 72 0 0 +syscon ipv6 INET6_ADDRSTRLEN 46 46 46 46 65 # unix consensus + +syscon poll POLLIN 1 1 1 1 0x300 # unix consensus +syscon poll POLLPRI 2 2 2 2 0x0400 # unix consensus +syscon poll POLLOUT 4 4 4 4 0x10 # unix consensus +syscon poll POLLERR 8 8 8 8 1 # unix consensus +syscon poll POLLHUP 0x10 0x10 0x10 0x10 2 # unix consensus +syscon poll POLLNVAL 0x20 0x20 0x20 0x20 4 # unix consensus +syscon poll POLLRDBAND 0x80 0x80 0x80 0x80 0x0200 # unix consensus +syscon poll POLLRDNORM 0x40 0x40 0x40 0x40 0x0100 # unix consensus +syscon poll POLLWRBAND 0x0200 0x0100 0x0100 0x0100 0x20 # bsd consensus +syscon poll POLLWRNORM 0x0100 4 4 4 0x10 # bsd consensus +syscon poll POLLRDHUP 0x2000 0x10 0x10 0x10 2 # bsd consensus (POLLHUP on non-Linux) + +syscon sigpoll POLL_ERR 4 4 4 0 0 +syscon sigpoll POLL_HUP 6 6 6 0 0 +syscon sigpoll POLL_IN 1 1 1 0 0 +syscon sigpoll POLL_MSG 3 3 3 0 0 +syscon sigpoll POLL_OUT 2 2 2 0 0 +syscon sigpoll POLL_PRI 5 5 5 0 0 + +syscon c C_IXOTH 0000001 0000001 0000001 0000001 0 # unix consensus +syscon c C_IWOTH 0000002 0000002 0000002 0000002 0 # unix consensus +syscon c C_IROTH 0000004 0000004 0000004 0000004 0 # unix consensus +syscon c C_IXGRP 0000010 0000010 0000010 0000010 0 # unix consensus +syscon c C_IWGRP 0000020 0000020 0000020 0000020 0 # unix consensus +syscon c C_IRGRP 0000040 0000040 0000040 0000040 0 # unix consensus +syscon c C_IXUSR 0000100 0000100 0000100 0000100 0 # unix consensus +syscon c C_IWUSR 0000200 0000200 0000200 0000200 0 # unix consensus +syscon c C_IRUSR 0000400 0000400 0000400 0000400 0 # unix consensus +syscon c C_ISVTX 0001000 0001000 0001000 0001000 0 # unix consensus +syscon c C_ISGID 0002000 0002000 0002000 0002000 0 # unix consensus +syscon c C_ISUID 0004000 0004000 0004000 0004000 0 # unix consensus +syscon c C_ISFIFO 0010000 0010000 0010000 0010000 0 # unix consensus +syscon c C_ISCHR 0020000 0020000 0020000 0020000 0 # unix consensus +syscon c C_ISDIR 0040000 0040000 0040000 0040000 0 # unix consensus +syscon c C_ISBLK 0060000 0060000 0060000 0060000 0 # unix consensus +syscon c C_ISREG 0100000 0100000 0100000 0100000 0 # unix consensus +syscon c C_ISCTG 0110000 0110000 0110000 0110000 0 # unix consensus +syscon c C_ISLNK 0120000 0120000 0120000 0120000 0 # unix consensus +syscon c C_ISSOCK 0140000 0140000 0140000 0140000 0 # unix consensus + +syscon fan FAN_CLASS_NOTIF 0 0 0 0 0 # consensus +syscon fan FAN_ACCESS 1 0 0 0 0 +syscon fan FAN_ACCESS_PERM 0x020000 0 0 0 0 +syscon fan FAN_ALLOW 1 0 0 0 0 +syscon fan FAN_ALL_CLASS_BITS 12 0 0 0 0 +syscon fan FAN_ALL_EVENTS 59 0 0 0 0 +syscon fan FAN_ALL_INIT_FLAGS 63 0 0 0 0 +syscon fan FAN_ALL_MARK_FLAGS 255 0 0 0 0 +syscon fan FAN_ALL_OUTGOING_EVENTS 0x03403b 0 0 0 0 +syscon fan FAN_ALL_PERM_EVENTS 0x030000 0 0 0 0 +syscon fan FAN_CLASS_CONTENT 4 0 0 0 0 +syscon fan FAN_CLASS_PRE_CONTENT 8 0 0 0 0 +syscon fan FAN_CLOEXEC 1 0 0 0 0 +syscon fan FAN_CLOSE 24 0 0 0 0 +syscon fan FAN_CLOSE_NOWRITE 0x10 0 0 0 0 +syscon fan FAN_CLOSE_WRITE 8 0 0 0 0 +syscon fan FAN_DENY 2 0 0 0 0 +syscon fan FAN_EVENT_METADATA_LEN 24 0 0 0 0 +syscon fan FAN_EVENT_ON_CHILD 0x08000000 0 0 0 0 +syscon fan FAN_MARK_ADD 1 0 0 0 0 +syscon fan FAN_MARK_DONT_FOLLOW 4 0 0 0 0 +syscon fan FAN_MARK_FLUSH 0x80 0 0 0 0 +syscon fan FAN_MARK_IGNORED_MASK 0x20 0 0 0 0 +syscon fan FAN_MARK_IGNORED_SURV_MODIFY 0x40 0 0 0 0 +syscon fan FAN_MARK_MOUNT 0x10 0 0 0 0 +syscon fan FAN_MARK_ONLYDIR 8 0 0 0 0 +syscon fan FAN_MARK_REMOVE 2 0 0 0 0 +syscon fan FAN_MODIFY 2 0 0 0 0 +syscon fan FAN_NOFD -1 0 0 0 0 +syscon fan FAN_NONBLOCK 2 0 0 0 0 +syscon fan FAN_ONDIR 0x40000000 0 0 0 0 +syscon fan FAN_OPEN 0x20 0 0 0 0 +syscon fan FAN_OPEN_PERM 0x010000 0 0 0 0 +syscon fan FAN_Q_OVERFLOW 0x4000 0 0 0 0 +syscon fan FAN_UNLIMITED_MARKS 0x20 0 0 0 0 +syscon fan FAN_UNLIMITED_QUEUE 0x10 0 0 0 0 + +syscon exit EXIT_SUCCESS 0 0 0 0 0 # consensus +syscon exit EXIT_FAILURE 1 1 1 1 1 # consensus + +# Eric Allman's exit() codes +# +# - Broadly supported style guideline; +# - Dating back to 1980 in 4.0BSD; +# - That won't be standardized. +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon ex EX_OK 0 0 0 0 0 # consensus +syscon ex EX_USAGE 64 64 64 64 64 # unix consensus & force NT +syscon ex EX_DATAERR 65 65 65 65 65 # unix consensus & force NT +syscon ex EX_NOINPUT 66 66 66 66 66 # unix consensus & force NT +syscon ex EX_NOUSER 67 67 67 67 67 # unix consensus & force NT +syscon ex EX_NOHOST 68 68 68 68 68 # unix consensus & force NT +syscon ex EX_UNAVAILABLE 69 69 69 69 69 # unix consensus & force NT +syscon ex EX_SOFTWARE 70 70 70 70 70 # unix consensus & force NT +syscon ex EX_OSERR 71 71 71 71 71 # unix consensus & force NT +syscon ex EX_OSFILE 72 72 72 72 72 # unix consensus & force NT +syscon ex EX_CANTCREAT 73 73 73 73 73 # unix consensus & force NT +syscon ex EX_IOERR 74 74 74 74 74 # unix consensus & force NT +syscon ex EX_TEMPFAIL 75 75 75 75 75 # unix consensus & force NT +syscon ex EX_PROTOCOL 76 76 76 76 76 # unix consensus & force NT +syscon ex EX_NOPERM 77 77 77 77 77 # unix consensus & force NT +syscon ex EX_CONFIG 78 78 78 78 78 # unix consensus & force NT +syscon ex EX__BASE 64 64 64 64 64 # unix consensus & force NT +syscon ex EX__MAX 78 78 78 78 78 # unix consensus & force NT + +# msync() flags +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon ms MS_SYNC 4 16 0 2 4 # faked nt +syscon ms MS_ASYNC 1 1 1 1 1 # consensus (faked nt) +syscon ms MS_INVALIDATE 2 2 2 4 0 + +# mount flags +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon mount MS_ACTIVE 0x40000000 0 0 0 0 +syscon mount MS_BIND 0x1000 0 0 0 0 +syscon mount MS_DIRSYNC 0x80 0 0 0 0 +syscon mount MS_I_VERSION 0x800000 0 0 0 0 +syscon mount MS_KERNMOUNT 0x400000 0 0 0 0 +syscon mount MS_LAZYTIME 0x02000000 0 0 0 0 +syscon mount MS_MANDLOCK 0x40 0 0 0 0 +syscon mount MS_MGC_VAL 0xc0ed0000 0 0 0 0 +syscon mount MS_MOVE 0x2000 0 0 0 0 +syscon mount MS_NOATIME 0x0400 0 0 0 0 +syscon mount MS_NODEV 4 0 0 0 0 +syscon mount MS_NODIRATIME 0x0800 0 0 0 0 +syscon mount MS_NOEXEC 8 0 0 0 0 +syscon mount MS_NOSUID 2 0 0 0 0 +syscon mount MS_NOUSER -2147483648 0 0 0 0 +syscon mount MS_POSIXACL 0x010000 0 0 0 0 +syscon mount MS_PRIVATE 0x040000 0 0 0 0 +syscon mount MS_RDONLY 1 0 0 0 0 +syscon mount MS_REC 0x4000 0 0 0 0 +syscon mount MS_RELATIME 0x200000 0 0 0 0 +syscon mount MS_REMOUNT 0x20 0 0 0 0 +syscon mount MS_RMT_MASK 0x02800051 0 0 0 0 +syscon mount MS_SHARED 0x100000 0 0 0 0 +syscon mount MS_SILENT 0x8000 0 0 0 0 +syscon mount MS_SLAVE 0x080000 0 0 0 0 +syscon mount MS_STRICTATIME 0x01000000 0 0 0 0 +syscon mount MS_SYNCHRONOUS 0x10 0 0 0 0 +syscon mount MS_UNBINDABLE 0x020000 0 0 0 0 +syscon mount MS_MGC_MSK 0xffff0000 0 0 0 0 + +# TODO(jart): MSG_ZEROCOPY +syscon msg MSG_OOB 1 1 1 1 1 # consensus +syscon msg MSG_PEEK 2 2 2 2 2 # consensus +syscon msg MSG_DONTROUTE 4 4 4 4 4 # consensus +syscon msg MSG_FASTOPEN 0x20000000 0 0 0 0 # TODO +syscon msg MSG_WAITALL 0x0100 0x40 0x40 0x40 8 # bsd consensus +syscon msg MSG_TRUNC 0x20 0x10 0x10 0x10 0x0100 # bsd consensus +syscon msg MSG_CTRUNC 8 0x20 0x20 0x20 0x0200 # bsd consensus +syscon msg MSG_ERRQUEUE 0x2000 0 0 0 0x1000 # bsd consensus +syscon msg MSG_NOERROR 0x1000 0x1000 0x1000 0x1000 0 # unix consensus +syscon msg MSG_DONTWAIT 0x40 0x80 0x80 0x80 0 # bsd consensus +syscon msg MSG_EOR 0x80 8 8 8 0 # bsd consensus +syscon msg MSG_CMSG_CLOEXEC 0x40000000 0 0x040000 0x0800 0 +syscon msg MSG_NOSIGNAL 0x4000 0 0x020000 0x0400 0 +syscon msg MSG_WAITFORONE 0x010000 0 0x080000 0 0 +syscon msg MSG_BATCH 0x040000 0 0 0 0 +syscon msg MSG_CONFIRM 0x0800 0 0 0 0 +syscon msg MSG_EXCEPT 0x2000 0 0 0 0 +syscon msg MSG_FIN 0x0200 0 0 0 0 +syscon msg MSG_INFO 12 0 0 0 0 +syscon msg MSG_MORE 0x8000 0 0 0 0 +syscon msg MSG_PARITY_ERROR 9 0 0 0 0 +syscon msg MSG_PROXY 0x10 0 0 0 0 +syscon msg MSG_RST 0x1000 0 0 0 0 +syscon msg MSG_STAT 11 0 0 0 0 +syscon msg MSG_SYN 0x0400 0 0 0 0 + +syscon sol SOL_IP 0 0 0 0 0 # consensus +syscon sol SOL_SOCKET 1 0xffff 0xffff 0xffff 0xffff # bsd+nt consensus +syscon sol SOL_AAL 265 0 0 0 0 +syscon sol SOL_ALG 279 0 0 0 0 +syscon sol SOL_ATM 264 0 0 0 0 +syscon sol SOL_BLUETOOTH 274 0 0 0 0 +syscon sol SOL_CAIF 278 0 0 0 0 +syscon sol SOL_DCCP 269 0 0 0 0 +syscon sol SOL_DECNET 261 0 0 0 0 +syscon sol SOL_ICMPV6 58 0 0 0 0 +syscon sol SOL_IPV6 41 0 0 0 0 +syscon sol SOL_IRDA 266 0 0 0 0 +syscon sol SOL_IUCV 277 0 0 0 0 +syscon sol SOL_KCM 281 0 0 0 0 +syscon sol SOL_LLC 268 0 0 0 0 +syscon sol SOL_NETBEUI 267 0 0 0 0 +syscon sol SOL_NETLINK 270 0 0 0 0 +syscon sol SOL_NFC 280 0 0 0 0 +syscon sol SOL_PACKET 263 0 0 0 0 +syscon sol SOL_PNPIPE 275 0 0 0 0 +syscon sol SOL_PPPOL2TP 273 0 0 0 0 +syscon sol SOL_RAW 255 0 0 0 0 +syscon sol SOL_RDS 276 0 0 0 0 +syscon sol SOL_RXRPC 272 0 0 0 0 +syscon sol SOL_TCP 6 0 0 0 0 +syscon sol SOL_TIPC 271 0 0 0 0 +syscon sol SOL_UDP 17 0 0 0 0 +syscon sol SOL_X25 262 0 0 0 0 + +syscon in IN_LOOPBACKNET 127 127 127 127 0 # unix consensus +syscon in IN_ACCESS 1 0 0 0 0 +syscon in IN_ALL_EVENTS 0x0fff 0 0 0 0 +syscon in IN_ATTRIB 4 0 0 0 0 +syscon in IN_CLOEXEC 0x080000 0 0 0 0 +syscon in IN_CLOSE 24 0 0 0 0 +syscon in IN_CLOSE_NOWRITE 0x10 0 0 0 0 +syscon in IN_CLOSE_WRITE 8 0 0 0 0 +syscon in IN_CREATE 0x0100 0 0 0 0 +syscon in IN_DELETE 0x0200 0 0 0 0 +syscon in IN_DELETE_SELF 0x0400 0 0 0 0 +syscon in IN_DONT_FOLLOW 0x02000000 0 0 0 0 +syscon in IN_EXCL_UNLINK 0x04000000 0 0 0 0 +syscon in IN_IGNORED 0x8000 0 0 0 0 +syscon in IN_ISDIR 0x40000000 0 0 0 0 +syscon in IN_MASK_ADD 0x20000000 0 0 0 0 +syscon in IN_MODIFY 2 0 0 0 0 +syscon in IN_MOVE 192 0 0 0 0 +syscon in IN_MOVED_FROM 0x40 0 0 0 0 +syscon in IN_MOVED_TO 0x80 0 0 0 0 +syscon in IN_MOVE_SELF 0x0800 0 0 0 0 +syscon in IN_NONBLOCK 0x0800 0 0 0 0 +syscon in IN_ONESHOT 0x80000000 0 0 0 0 +syscon in IN_ONLYDIR 0x01000000 0 0 0 0 +syscon in IN_OPEN 0x20 0 0 0 0 +syscon in IN_Q_OVERFLOW 0x4000 0 0 0 0 +syscon in IN_UNMOUNT 0x2000 0 0 0 0 + +syscon pt PT_TRACE_ME 0 0 0 0 0 # consensus +syscon pt PT_CONTINUE 7 7 7 7 0 # unix consensus +syscon pt PT_KILL 8 8 8 8 0 # unix consensus +syscon pt PT_READ_D 2 2 2 2 0 # unix consensus +syscon pt PT_READ_I 1 1 1 1 0 # unix consensus +syscon pt PT_WRITE_D 5 5 5 5 0 # unix consensus +syscon pt PT_WRITE_I 4 4 4 4 0 # unix consensus +syscon pt PT_ATTACH 0x10 10 10 9 0 +syscon pt PT_DETACH 17 11 11 10 0 +syscon pt PT_STEP 9 9 9 0x20 0 +syscon pt PT_GETFPREGS 14 0 35 35 0 +syscon pt PT_GETREGS 12 0 33 33 0 +syscon pt PT_SETFPREGS 15 0 36 36 0 +syscon pt PT_SETREGS 13 0 34 34 0 +syscon pt PT_READ_U 3 3 0 0 0 +syscon pt PT_SYSCALL 24 0 22 0 0 +syscon pt PT_WRITE_U 6 6 0 0 0 +syscon pt PT_GETEVENTMSG 0x4201 0 0 0 0 +syscon pt PT_GETFPXREGS 18 0 0 0 0 +syscon pt PT_GETSIGINFO 0x4202 0 0 0 0 +syscon pt PT_SETFPXREGS 19 0 0 0 0 +syscon pt PT_SETOPTIONS 0x4200 0 0 0 0 +syscon pt PT_SETSIGINFO 0x4203 0 0 0 0 + +syscon iff IFF_BROADCAST 2 2 2 2 2 # consensus +syscon iff IFF_LOOPBACK 8 8 8 8 4 # unix consensus +syscon iff IFF_MULTICAST 0x1000 0x8000 0x8000 0x8000 0x10 # bsd consensus +syscon iff IFF_ALLMULTI 0x0200 0x0200 0x0200 0x0200 0 # unix consensus +syscon iff IFF_DEBUG 4 4 4 4 0 # unix consensus +syscon iff IFF_NOARP 0x80 0x80 0x80 0x80 0 # unix consensus +syscon iff IFF_POINTOPOINT 0x10 0x10 0x10 0x10 0 # unix consensus +syscon iff IFF_PROIFF 0x0100 0x0100 0x0100 0x0100 0 # unix consensus +syscon iff IFF_RUNNING 0x40 0x40 0x40 0x40 0 # unix consensus +syscon iff IFF_NOTRAILERS 0x20 0x20 0 0 0 +syscon iff IFF_AUTOMEDIA 0x4000 0 0 0 0 +syscon iff IFF_DYNAMIC 0x8000 0 0 0 0 +syscon iff IFF_MASTER 0x0400 0 0 0 0 +syscon iff IFF_PORTSEL 0x2000 0 0 0 0 +syscon iff IFF_SLAVE 0x0800 0 0 0 0 + +syscon nd ND_RA_FLAG_MANAGED 0x80 0x80 0x80 0x80 0x80 # consensus +syscon nd ND_RA_FLAG_OTHER 0x40 0x40 0x40 0x40 0x40 # consensus +syscon nd ND_NA_FLAG_OVERRIDE 0x20 0x20 0x20 0x20 0x20000000 # unix consensus +syscon nd ND_NA_FLAG_ROUTER 0x80 0x80 0x80 0x80 0x80000000 # unix consensus +syscon nd ND_NA_FLAG_SOLICITED 0x40 0x40 0x40 0x40 0x40000000 # unix consensus +syscon nd ND_NEIGHBOR_ADVERT 136 136 136 136 0 # unix consensus +syscon nd ND_NEIGHBOR_SOLICIT 135 135 135 135 0 # unix consensus +syscon nd ND_REDIRECT 137 137 137 137 0 # unix consensus +syscon nd ND_ROUTER_ADVERT 134 134 134 134 0 # unix consensus +syscon nd ND_ROUTER_SOLICIT 133 133 133 133 0 # unix consensus +syscon nd ND_RA_FLAG_HOME_AGENT 0x20 0 0 0 0x20 # bsd consensus + +syscon rlim RLIMIT_CPU 0 0 0 0 -1 # unix consensus +syscon rlim RLIMIT_FSIZE 1 1 1 1 -1 # unix consensus +syscon rlim RLIMIT_DATA 2 2 2 2 -1 # unix consensus +syscon rlim RLIMIT_STACK 3 3 3 3 -1 # unix consensus +syscon rlim RLIMIT_CORE 4 4 4 4 -1 # unix consensus +syscon rlim RLIMIT_RSS 5 5 5 5 -1 # unix consensus +syscon rlim RLIMIT_NPROC 6 7 7 7 -1 # bsd consensus +syscon rlim RLIMIT_NOFILE 7 8 8 8 -1 # bsd consensus +syscon rlim RLIMIT_MEMLOCK 8 6 6 6 -1 # bsd consensus +syscon rlim RLIMIT_AS 9 5 10 -1 -1 +syscon rlim RLIMIT_LOCKS 10 -1 -1 -1 -1 # bsd consensus +syscon rlim RLIMIT_SIGPENDING 11 -1 -1 -1 -1 # bsd consensus +syscon rlim RLIMIT_MSGQUEUE 12 -1 -1 -1 -1 # bsd consensus +syscon rlim RLIMIT_NICE 13 -1 -1 -1 -1 # bsd consensus +syscon rlim RLIMIT_RTPRIO 14 -1 -1 -1 -1 # bsd consensus +syscon rlim RLIMIT_NLIMITS 16 -1 -1 -1 -1 # bsd consensus + +syscon misc TCFLSH 0x540b 0 0 0 0 +syscon misc TCIFLUSH 0 1 1 1 0 # bsd consensus +syscon misc TCIOFF 2 3 3 3 0 # bsd consensus +syscon misc TCIOFLUSH 2 3 3 3 0 # bsd consensus +syscon misc TCION 3 4 4 4 0 # bsd consensus +syscon misc TCOFLUSH 1 2 2 2 0 # bsd consensus +syscon misc TCOOFF 0 1 1 1 0 # bsd consensus +syscon misc TCOON 1 2 2 2 0 # bsd consensus + +syscon misc FE_TONEAREST 0 0 0 0 0 # consensus +syscon misc FE_DIVBYZERO 4 4 4 4 0 # unix consensus +syscon misc FE_DOWNWARD 0x0400 0x0400 0x0400 0x0400 0 # unix consensus +syscon misc FE_INEXACT 0x20 0x20 0x20 0x20 0 # unix consensus +syscon misc FE_INVALID 1 1 1 1 0 # unix consensus +syscon misc FE_OVERFLOW 8 8 8 8 0 # unix consensus +syscon misc FE_TOWARDZERO 0x0c00 0x0c00 0x0c00 0x0c00 0 # unix consensus +syscon misc FE_UNDERFLOW 0x10 0x10 0x10 0x10 0 # unix consensus +syscon misc FE_UPWARD 0x0800 0x0800 0x0800 0x0800 0 # unix consensus +syscon misc FE_ALL_EXCEPT 61 63 63 63 0 # bsd consensus + +syscon misc TYPE_DISK 0 0 0 0 0 # consensus +syscon misc TYPE_A 1 1 1 1 0 # unix consensus +syscon misc TYPE_E 2 2 2 2 0 # unix consensus +syscon misc TYPE_I 3 3 3 3 0 # unix consensus +syscon misc TYPE_L 4 4 4 4 0 # unix consensus +syscon misc TYPE_ENCLOSURE 13 0 0 0 0 +syscon misc TYPE_MEDIUM_CHANGER 8 0 0 0 0 +syscon misc TYPE_MOD 7 0 0 0 0 +syscon misc TYPE_NO_LUN 127 0 0 0 0 +syscon misc TYPE_PROCESSOR 3 0 0 0 0 +syscon misc TYPE_ROM 5 0 0 0 0 +syscon misc TYPE_SCANNER 6 0 0 0 0 +syscon misc TYPE_TAPE 1 0 0 0 0 +syscon misc TYPE_WORM 4 0 0 0 0 + +syscon misc _POSIX2_BC_BASE_MAX 99 99 99 99 0 # unix consensus +syscon misc _POSIX2_BC_DIM_MAX 0x0800 0x0800 0x0800 0x0800 0 # unix consensus +syscon misc _POSIX2_BC_SCALE_MAX 99 99 99 99 0 # unix consensus +syscon misc _POSIX2_BC_STRING_MAX 0x03e8 0x03e8 0x03e8 0x03e8 0 # unix consensus +syscon misc _POSIX2_CHARCLASS_NAME_MAX 14 14 14 14 0 # unix consensus +syscon misc _POSIX2_COLL_WEIGHTS_MAX 2 2 2 2 0 # unix consensus +syscon misc _POSIX2_EXPR_NEST_MAX 0x20 0x20 0x20 0x20 0 # unix consensus +syscon misc _POSIX2_LINE_MAX 0x0800 0x0800 0x0800 0x0800 0 # unix consensus +syscon misc _POSIX2_RE_DUP_MAX 255 255 255 255 0 # unix consensus +syscon misc _POSIX2_C_BIND 0x031069 0x030db0 0x030db0 0x030db0 0 # bsd consensus +syscon misc _POSIX2_VERSION 0x031069 0x030db0 0x030a2c 0x031069 0 + +syscon misc PTHREAD_MUTEX_STALLED 0 0 0 0 0 # consensus +syscon misc PTHREAD_PRIO_NONE 0 0 0 0 0 # consensus +syscon misc PTHREAD_PRIO_INHERIT 0 1 1 1 0 # bsd consensus +syscon misc PTHREAD_PRIO_PROTECT 0 2 2 2 0 # bsd consensus +syscon misc PTHREAD_DESTRUCTOR_ITERATIONS 4 4 4 4 0 # unix consensus +syscon misc PTHREAD_PROCESS_SHARED 1 1 1 1 0 # unix consensus +syscon misc PTHREAD_CREATE_DETACHED 1 2 1 1 0 +syscon misc PTHREAD_KEYS_MAX 0x0400 0x0200 0x0100 0x0100 0 +syscon misc PTHREAD_STACK_MIN 0x4000 0x2000 0x0800 0x1000 0 +syscon misc PTHREAD_BARRIER_SERIAL_THREAD -1 0 -1 -1 0 +syscon misc PTHREAD_CANCEL_ASYNCHRONOUS 1 0 2 2 0 +syscon misc PTHREAD_CANCEL_DISABLE 1 0 1 1 0 +syscon misc PTHREAD_INHERIT_SCHED 0 1 4 4 0 +syscon misc PTHREAD_SCOPE_SYSTEM 0 1 2 2 0 +syscon misc PTHREAD_EXPLICIT_SCHED 1 2 0 0 0 +syscon misc PTHREAD_MUTEX_DEFAULT 0 0 1 4 0 +syscon misc PTHREAD_MUTEX_ERRORCHECK 0 1 0 1 0 +syscon misc PTHREAD_MUTEX_RECURSIVE 0 2 0 2 0 +syscon misc PTHREAD_SCOPE_PROCESS 1 2 0 0 0 +syscon misc PTHREAD_CANCEL_DEFERRED 0 2 0 0 0 +syscon misc PTHREAD_CANCEL_ENABLE 0 1 0 0 0 +syscon misc PTHREAD_CREATE_JOINABLE 0 1 0 0 0 +syscon misc PTHREAD_MUTEX_NORMAL 0 0 0 3 0 +syscon misc PTHREAD_MUTEX_ROBUST 0 0 1 0 0 +syscon misc PTHREAD_PROCESS_PRIVATE 0 2 0 0 0 + +syscon misc FTW_F 0 0 0 0 0 # consensus +syscon misc FTW_D 1 1 1 1 0 # unix consensus +syscon misc FTW_DNR 2 2 2 2 0 # unix consensus +syscon misc FTW_MOUNT 2 2 2 2 0 # unix consensus +syscon misc FTW_PHYS 1 1 1 1 0 # unix consensus +syscon misc FTW_SLN 6 6 6 6 0 # unix consensus +syscon misc FTW_CHDIR 4 8 8 8 0 # bsd consensus +syscon misc FTW_DEPTH 8 4 4 4 0 # bsd consensus +syscon misc FTW_DP 5 3 3 3 0 # bsd consensus +syscon misc FTW_NS 3 4 4 4 0 # bsd consensus +syscon misc FTW_SL 4 5 5 5 0 # bsd consensus + +syscon misc N_TTY 0 0 0 0 0 # consensus +syscon misc N_6PACK 7 0 0 0 0 +syscon misc N_AX25 5 0 0 0 0 +syscon misc N_HCI 15 0 0 0 0 +syscon misc N_HDLC 13 0 0 0 0 +syscon misc N_IRDA 11 0 0 0 0 +syscon misc N_MASC 8 0 0 0 0 +syscon misc N_MOUSE 2 0 0 0 0 +syscon misc N_PPP 3 0 0 0 0 +syscon misc N_PROFIBUS_FDL 10 0 0 0 0 +syscon misc N_R3964 9 0 0 0 0 +syscon misc N_SLIP 1 0 0 0 0 +syscon misc N_SMSBLOCK 12 0 0 0 0 +syscon misc N_STRIP 4 0 0 0 0 +syscon misc N_SYNC_PPP 14 0 0 0 0 +syscon misc N_X25 6 0 0 0 0 + +syscon sock SOCK_STREAM 1 1 1 1 1 # consensus +syscon sock SOCK_DGRAM 2 2 2 2 2 # consensus +syscon sock SOCK_RAW 3 3 3 3 3 # consensus +syscon sock SOCK_RDM 4 4 4 4 4 # consensus +syscon sock SOCK_SEQPACKET 5 5 5 5 5 # consensus +syscon sock SOCK_CLOEXEC 0x080000 0x080000 0x10000000 0x8000 0x80 # faked xnu & WSA_FLAG_NO_HANDLE_INHERIT +syscon sock SOCK_NONBLOCK 0x0800 0x0800 0x20000000 0x4000 0x0800 # faked xnu; faked nt; socket() will ioctl(FIONBIO=1) +syscon sock SOCK_DCCP 6 0 0 0 0 # what is it? +syscon sock SOCK_PACKET 10 0 0 0 0 # what is it? + +syscon prsnlty ADDR_COMPAT_LAYOUT 0x0200000 -1 -1 -1 -1 # linux only +syscon prsnlty READ_IMPLIES_EXEC 0x0400000 -1 -1 -1 -1 # linux only +syscon prsnlty ADDR_LIMIT_3GB 0x8000000 -1 -1 -1 -1 # linux only +syscon prsnlty FDPIC_FUNCPTRS 0x0080000 -1 -1 -1 -1 # linux only +syscon prsnlty STICKY_TIMEOUTS 0x4000000 -1 -1 -1 -1 # linux only +syscon prsnlty MMAP_PAGE_ZERO 0x0100000 -1 -1 -1 -1 # linux only +syscon prsnlty ADDR_LIMIT_32BIT 0x0800000 -1 -1 -1 -1 # linux only +syscon prsnlty WHOLE_SECONDS 0x2000000 -1 -1 -1 -1 # linux only +syscon prsnlty ADDR_NO_RANDOMIZE 0x0040000 -1 -1 -1 -1 # linux only +syscon prsnlty SHORT_INODE 0x1000000 -1 -1 -1 -1 # linux only +syscon prsnlty UNAME26 0x0020000 -1 -1 -1 -1 # linux only + +syscon misc INADDR_ANY 0 0 0 0 0 # consensus +syscon misc INADDR_BROADCAST 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff # consensus +syscon misc INADDR_NONE 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff # consensus +syscon misc INADDR_ALLHOSTS_GROUP 0xe0000001 0xe0000001 0xe0000001 0xe0000001 0 # unix consensus +syscon misc INADDR_LOOPBACK 0x7f000001 0x7f000001 0x7f000001 0x7f000001 0x7f000001 # consensus +syscon misc INADDR_MAX_LOCAL_GROUP 0xe00000ff 0xe00000ff 0xe00000ff 0xe00000ff 0 # unix consensus +syscon misc INADDR_UNSPEC_GROUP 0xe0000000 0xe0000000 0xe0000000 0xe0000000 0 # unix consensus +syscon misc INADDR_ALLRTRS_GROUP 0xe0000002 0xe0000002 0xe0000002 0 0 + +syscon misc BLKTYPE 52 52 52 52 0 # unix consensus +syscon misc BLKBSZGET 0x80081270 0 0 0 0 +syscon misc BLKBSZSET 0x40081271 0 0 0 0 +syscon misc BLKFLSBUF 0x1261 0 0 0 0 +syscon misc BLKFRAGET 0x1265 0 0 0 0 +syscon misc BLKFRASET 0x1264 0 0 0 0 +syscon misc BLKGETSIZE 0x1260 0 0 0 0 +syscon misc BLKGETSIZE64 0x80081272 0 0 0 0 +syscon misc BLKRAGET 0x1263 0 0 0 0 +syscon misc BLKRASET 0x1262 0 0 0 0 +syscon misc BLKROGET 0x125e 0 0 0 0 +syscon misc BLKROSET 0x125d 0 0 0 0 +syscon misc BLKRRPART 0x125f 0 0 0 0 +syscon misc BLKSECTGET 0x1267 0 0 0 0 +syscon misc BLKSECTSET 0x1266 0 0 0 0 +syscon misc BLKSSZGET 0x1268 0 0 0 0 + +syscon misc DT_UNKNOWN 0 0 0 0 0 # consensus +syscon misc DT_BLK 6 6 6 6 0 # unix consensus +syscon misc DT_CHR 2 2 2 2 0 # unix consensus +syscon misc DT_DIR 4 4 4 4 0 # unix consensus +syscon misc DT_FIFO 1 1 1 1 0 # unix consensus +syscon misc DT_LNK 10 10 10 10 0 # unix consensus +syscon misc DT_REG 8 8 8 8 0 # unix consensus +syscon misc DT_SOCK 12 12 12 12 0 # unix consensus + +syscon misc TH_FIN 1 1 1 1 1 # consensus +syscon misc TH_SYN 2 2 2 2 2 # consensus +syscon misc TH_RST 4 4 4 4 4 # consensus +syscon misc TH_PUSH 8 8 8 8 0 # unix consensus +syscon misc TH_URG 32 32 32 32 32 # consensus +syscon misc TH_ACK 16 16 16 16 16 # consensus + +syscon misc IPC_PRIVATE 0 0 0 0 0 # consensus +syscon misc IPC_RMID 0 0 0 0 0 # consensus +syscon misc IPC_CREAT 0x0200 0x0200 0x0200 0x0200 0 # unix consensus +syscon misc IPC_EXCL 0x0400 0x0400 0x0400 0x0400 0 # unix consensus +syscon misc IPC_NOWAIT 0x0800 0x0800 0x0800 0x0800 0 # unix consensus +syscon misc IPC_SET 1 1 1 1 0 # unix consensus +syscon misc IPC_STAT 2 2 2 2 0 # unix consensus +syscon misc IPC_INFO 3 0 3 0 0 + +syscon shm SHM_R 0x0100 0x0100 0x0100 0x0100 0 # unix consensus +syscon shm SHM_RDONLY 0x1000 0x1000 0x1000 0x1000 0 # unix consensus +syscon shm SHM_RND 0x2000 0x2000 0x2000 0x2000 0 # unix consensus +syscon shm SHM_W 0x80 0x80 0x80 0x80 0 # unix consensus +syscon shm SHM_LOCK 11 0 11 3 0 +syscon shm SHM_UNLOCK 12 0 12 4 0 +syscon shm SHM_INFO 14 0 14 0 0 +syscon shm SHM_STAT 13 0 13 0 0 +syscon shm SHM_DEST 0x0200 0 0 0 0 +syscon shm SHM_EXEC 0x8000 0 0 0 0 +syscon shm SHM_HUGETLB 0x0800 0 0 0 0 +syscon shm SHM_LOCKED 0x0400 0 0 0 0 +syscon shm SHM_NORESERVE 0x1000 0 0 0 0 +syscon shm SHM_REMAP 0x4000 0 0 0 0 + +syscon misc TCPOPT_EOL 0 0 0 0 0 # consensus +syscon misc TCPOPT_MAXSEG 2 2 2 2 0 # unix consensus +syscon misc TCPOPT_NOP 1 1 1 1 0 # unix consensus +syscon misc TCPOPT_SACK 5 5 5 5 0 # unix consensus +syscon misc TCPOPT_SACK_PERMITTED 4 4 4 4 0 # unix consensus +syscon misc TCPOPT_TIMESTAMP 8 8 8 8 0 # unix consensus +syscon misc TCPOPT_WINDOW 3 3 3 3 0 # unix consensus + +syscon misc ETH_P_CUST 0x6006 0 0 0 0 +syscon misc ETH_P_DDCMP 6 0 0 0 0 +syscon misc ETH_P_DEC 0x6000 0 0 0 0 +syscon misc ETH_P_DIAG 0x6005 0 0 0 0 +syscon misc ETH_P_DNA_DL 0x6001 0 0 0 0 +syscon misc ETH_P_DNA_RC 0x6002 0 0 0 0 +syscon misc ETH_P_DNA_RT 0x6003 0 0 0 0 +syscon misc ETH_P_IEEE802154 246 0 0 0 0 +syscon misc ETH_P_LAT 0x6004 0 0 0 0 +syscon misc ETH_P_LOCALTALK 9 0 0 0 0 +syscon misc ETH_P_PPP_MP 8 0 0 0 0 +syscon misc ETH_P_RARP 0x8035 0 0 0 0 +syscon misc ETH_P_SCA 0x6007 0 0 0 0 +syscon misc ETH_P_WAN_PPP 7 0 0 0 0 + +syscon misc ST_NOSUID 2 2 2 2 0 # unix consensus +syscon misc ST_RDONLY 1 1 1 1 0 # unix consensus +syscon misc ST_APPEND 0x0100 0 0 0 0 +syscon misc ST_IMMUTABLE 0x0200 0 0 0 0 +syscon misc ST_MANDLOCK 0x40 0 0 0 0 +syscon misc ST_NOATIME 0x0400 0 0 0 0 +syscon misc ST_NODEV 4 0 0 0 0 +syscon misc ST_NODIRATIME 0x0800 0 0 0 0 +syscon misc ST_NOEXEC 8 0 0 0 0 +syscon misc ST_RELATIME 0x1000 0 0 0 0 +syscon misc ST_SYNCHRONOUS 0x10 0 0 0 0 +syscon misc ST_WRITE 0x80 0 0 0 0 + +syscon misc SCSI_IOCTL_BENCHMARK_COMMAND 3 0 0 0 0 +syscon misc SCSI_IOCTL_DOORLOCK 0x5380 0 0 0 0 +syscon misc SCSI_IOCTL_DOORUNLOCK 0x5381 0 0 0 0 +syscon misc SCSI_IOCTL_GET_BUS_NUMBER 0x5386 0 0 0 0 +syscon misc SCSI_IOCTL_GET_IDLUN 0x5382 0 0 0 0 +syscon misc SCSI_IOCTL_PROBE_HOST 0x5385 0 0 0 0 +syscon misc SCSI_IOCTL_SEND_COMMAND 1 0 0 0 0 +syscon misc SCSI_IOCTL_START_UNIT 5 0 0 0 0 +syscon misc SCSI_IOCTL_STOP_UNIT 6 0 0 0 0 +syscon misc SCSI_IOCTL_SYNC 4 0 0 0 0 +syscon misc SCSI_IOCTL_TAGGED_DISABLE 0x5384 0 0 0 0 +syscon misc SCSI_IOCTL_TAGGED_ENABLE 0x5383 0 0 0 0 +syscon misc SCSI_IOCTL_TEST_UNIT_READY 2 0 0 0 0 + +syscon misc CLD_CONTINUED 6 6 6 6 0 # unix consensus +syscon misc CLD_DUMPED 3 3 3 3 0 # unix consensus +syscon misc CLD_EXITED 1 1 1 1 0 # unix consensus +syscon misc CLD_KILLED 2 2 2 2 0 # unix consensus +syscon misc CLD_STOPPED 5 5 5 5 0 # unix consensus +syscon misc CLD_TRAPPED 4 4 4 4 0 # unix consensus + +syscon misc READ_10 40 0 0 0 0 +syscon misc READ_12 168 0 0 0 0 +syscon misc READ_6 8 0 0 0 0 +syscon misc READ_BLOCK_LIMITS 5 0 0 0 0 +syscon misc READ_BUFFER 60 0 0 0 0 +syscon misc READ_CAPACITY 37 0 0 0 0 +syscon misc READ_DEFECT_DATA 55 0 0 0 0 +syscon misc READ_ELEMENT_STATUS 184 0 0 0 0 +syscon misc READ_LONG 62 0 0 0 0 +syscon misc READ_POSITION 52 0 0 0 0 +syscon misc READ_REVERSE 15 0 0 0 0 +syscon misc READ_TOC 67 0 0 0 0 + +syscon glob GLOB_NOCHECK 0x10 0x10 0x10 0x10 0 # unix consensus +syscon glob GLOB_ABORTED 2 -2 -2 -2 0 # bsd consensus +syscon glob GLOB_APPEND 0x20 1 1 1 0 # bsd consensus +syscon glob GLOB_DOOFFS 8 2 2 2 0 # bsd consensus +syscon glob GLOB_ERR 1 4 4 4 0 # bsd consensus +syscon glob GLOB_MARK 2 8 8 8 0 # bsd consensus +syscon glob GLOB_NOMATCH 3 -3 -3 -3 0 # bsd consensus +syscon glob GLOB_NOSORT 4 0x20 0x20 0x20 0 # bsd consensus +syscon glob GLOB_NOSPACE 1 -1 -1 -1 0 # bsd consensus +syscon glob GLOB_NOSYS 4 -4 -4 -4 0 # bsd consensus +syscon glob GLOB_NOESCAPE 0x40 0x2000 0x2000 0x1000 0 + +# getpriority() / setpriority() magnums (a.k.a. nice) +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon prio PRIO_PROCESS 0 0 0 0 0 # consensus / poly nt +syscon prio PRIO_PGRP 1 1 1 1 1 # unix consensus / poly nt +syscon prio PRIO_USER 2 2 2 2 2 # unix consensus / poly nt +syscon prio PRIO_MIN -20 -20 -20 -20 -20 # unix consensus / poly nt +syscon prio PRIO_MAX 20 20 20 20 20 # unix consensus / poly nt +syscon prio NZERO 20 20 20 20 20 # unix consensus / polyfilled nt + +# getaddrinfo() flags +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon gai AI_PASSIVE 1 1 1 1 1 # consensus +syscon gai AI_CANONNAME 2 2 2 2 2 # consensus +syscon gai AI_NUMERICHOST 4 4 4 4 4 # consensus +syscon gai AI_ADDRCONFIG 0x20 0x0400 0x0400 0x40 0x0400 +syscon gai AI_NUMERICSERV 0x0400 0x1000 8 0x10 8 +syscon gai AI_ALL 0x10 0x0100 0x0100 0 0x0100 +syscon gai AI_V4MAPPED 8 0x0800 0x0800 0 0x0800 + +# getaddrinfo() return codes +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon eai EAI_SUCCESS 0 0 0 0 0 +syscon eai EAI_BADFLAGS -1 3 3 -1 0x2726 +syscon eai EAI_NONAME -2 8 8 -2 0x2af9 +syscon eai EAI_AGAIN -3 2 2 -3 0x2afa +syscon eai EAI_FAIL -4 4 4 -4 0x2afb +syscon eai EAI_FAMILY -6 5 5 -6 0x273f +syscon eai EAI_MEMORY -10 6 6 -10 0x2747 +syscon eai EAI_SERVICE -8 9 9 -8 0x277d +syscon eai EAI_SOCKTYPE -7 10 10 -7 0x273c +syscon eai EAI_NODATA -5 7 0 -5 0x2af9 +syscon eai EAI_OVERFLOW -12 14 14 -14 -12 +syscon eai EAI_SYSTEM -11 11 11 -11 -11 +syscon eai EAI_ADDRFAMILY -9 1 0 -9 -9 +syscon eai EAI_ALLDONE -103 -103 -103 -103 -103 # copying from linux +syscon eai EAI_CANCELED -101 -101 -101 -101 -101 # copying from linux +syscon eai EAI_IDN_ENCODE -105 -105 -105 -105 -105 # copying from linux +syscon eai EAI_INPROGRESS -100 -100 -100 -100 -100 # copying from linux +syscon eai EAI_INTR -104 -104 -104 -104 -104 # copying from linux +syscon eai EAI_NOTCANCELED -102 -102 -102 -102 -102 # copying from linux + +syscon misc BLK_BYTECOUNT 2 2 2 2 0 # unix consensus +syscon misc BLK_EOF 0x40 0x40 0x40 0x40 0 # unix consensus +syscon misc BLK_EOR 0x80 0x80 0x80 0x80 0 # unix consensus +syscon misc BLK_ERRORS 0x20 0x20 0x20 0x20 0 # unix consensus +syscon misc BLK_RESTART 0x10 0x10 0x10 0x10 0 # unix consensus + +syscon misc MODE_B 2 2 2 2 0 # unix consensus +syscon misc MODE_C 3 3 3 3 0 # unix consensus +syscon misc MODE_S 1 1 1 1 0 # unix consensus +syscon misc MODE_SELECT 21 0 0 0 0 +syscon misc MODE_SELECT_10 85 0 0 0 0 +syscon misc MODE_SENSE 26 0 0 0 0 +syscon misc MODE_SENSE_10 90 0 0 0 0 + +syscon misc WRITE_10 42 0 0 0 0 +syscon misc WRITE_12 170 0 0 0 0 +syscon misc WRITE_6 10 0 0 0 0 +syscon misc WRITE_BUFFER 59 0 0 0 0 +syscon misc WRITE_FILEMARKS 0x10 0 0 0 0 +syscon misc WRITE_LONG 63 0 0 0 0 +syscon misc WRITE_LONG_2 234 0 0 0 0 +syscon misc WRITE_SAME 65 0 0 0 0 +syscon misc WRITE_VERIFY 46 0 0 0 0 +syscon misc WRITE_VERIFY_12 174 0 0 0 0 + +syscon misc ILL_BADSTK 8 8 8 8 0 # unix consensus +syscon misc ILL_COPROC 7 7 7 7 0 # unix consensus +syscon misc ILL_ILLOPC 1 1 1 1 0 # unix consensus +syscon misc ILL_PRVREG 6 6 6 6 0 # unix consensus +syscon misc ILL_ILLADR 3 5 3 3 0 +syscon misc ILL_ILLOPN 2 4 2 2 0 +syscon misc ILL_ILLTRP 4 2 4 4 0 +syscon misc ILL_PRVOPC 5 3 5 5 0 + +syscon misc LC_CTYPE 0 2 2 2 0 # bsd consensus +syscon misc LC_NUMERIC 1 4 4 4 0 # bsd consensus +syscon misc LC_CTYPE_MASK 1 0 2 4 0 +syscon misc LC_TIME 2 5 5 5 0 # bsd consensus +syscon misc LC_NUMERIC_MASK 2 0 8 0x10 0 +syscon misc LC_COLLATE 3 1 1 1 0 # bsd consensus +syscon misc LC_MONETARY 4 3 3 3 0 # bsd consensus +syscon misc LC_TIME_MASK 4 0 0x10 0x20 0 +syscon misc LC_MESSAGES 5 6 6 6 0 # bsd consensus +syscon misc LC_ALL 6 0 0 0 0 +syscon misc LC_COLLATE_MASK 8 0 1 2 0 +syscon misc LC_MONETARY_MASK 0x10 0 4 8 0 +syscon misc LC_MESSAGES_MASK 0x20 0 0x20 0x40 0 +syscon misc LC_ALL_MASK 0x1fbf 0 63 126 0 + + +syscon ptrace PTRACE_GETREGSET 0x4204 0 0 0 0 +syscon ptrace PTRACE_GETSIGMASK 0x420a 0 0 0 0 +syscon ptrace PTRACE_INTERRUPT 0x4207 0 0 0 0 +syscon ptrace PTRACE_LISTEN 0x4208 0 0 0 0 +syscon ptrace PTRACE_PEEKSIGINFO 0x4209 0 0 0 0 +syscon ptrace PTRACE_SECCOMP_GET_FILTER 0x420c 0 0 0 0 +syscon ptrace PTRACE_SEIZE 0x4206 0 0 0 0 +syscon ptrace PTRACE_SETREGSET 0x4205 0 0 0 0 +syscon ptrace PTRACE_SETSIGMASK 0x420b 0 0 0 0 +syscon ptrace PTRACE_SYSCALL 0 0 6 0 0 + +syscon misc ARPHRD_ETHER 1 1 1 1 0 # unix consensus +syscon misc ARPHRD_FCFABRIC 787 0 0 0 0 +syscon misc ARPHRD_IEEE80211 801 0 0 0 0 +syscon misc ARPHRD_IEEE80211_PRISM 802 0 0 0 0 +syscon misc ARPHRD_IEEE80211_RADIOTAP 803 0 0 0 0 +syscon misc ARPHRD_IEEE802154 804 0 0 0 0 +syscon misc ARPHRD_IEEE802_TR 800 0 0 0 0 +syscon misc ARPHRD_LOCALTLK 773 0 0 0 0 + +syscon misc BUS_ADRALN 1 1 1 1 0 # unix consensus +syscon misc BUS_ADRERR 2 2 2 2 0 # unix consensus +syscon misc BUS_OBJERR 3 3 3 3 0 # unix consensus +syscon misc BUS_DEVICE_RESET 12 0 0 0 0 +syscon misc BUS_MCEERR_AO 5 0 0 0 0 +syscon misc BUS_MCEERR_AR 4 0 0 0 0 + +syscon misc IP6F_MORE_FRAG 0x0100 0x0100 0x0100 0x0100 0x0100 # consensus +syscon misc IP6F_OFF_MASK 0xf8ff 0xf8ff 0xf8ff 0xf8ff 0xf8ff # consensus +syscon misc IP6F_RESERVED_MASK 0x0600 0x0600 0x0600 0x0600 0x0600 # consensus + +syscon lock LOCK_SH 1 1 1 1 0 # unix consensus +syscon lock LOCK_EX 2 2 2 2 2 # consensus! +syscon lock LOCK_NB 4 4 4 4 1 # unix consensus +syscon lock LOCK_UN 8 8 8 8 8 # unix consensus & faked NT +syscon lock LOCK_UNLOCK_CACHE 54 0 0 0 0 + +syscon misc NO_SENSE 0 0 0 0 0 # consensus +syscon misc NO_ADDRESS 4 4 4 4 0x2afc # unix consensus +syscon misc NO_DATA 4 4 4 4 0x2afc # unix consensus +syscon misc NO_RECOVERY 3 3 3 3 0x2afb # unix consensus + +syscon misc RB_DISABLE_CAD 0 0 0 0 0 # consensus +syscon misc RB_AUTOBOOT 0x01234567 0 0 0 0 +syscon misc RB_ENABLE_CAD 0x89abcdef 0 0 0 0 +syscon misc RB_HALT_SYSTEM 0xcdef0123 0 0 0 0 +syscon misc RB_KEXEC 0x45584543 0 0 0 0 +syscon misc RB_POWER_OFF 0x4321fedc 0 0 0 0 +syscon misc RB_SW_SUSPEND 0xd000fce2 0 0 0 0 + +syscon misc NI_DGRAM 0x10 0x10 0x10 0x10 0x10 # consensus +syscon misc NI_MAXSERV 0x20 0x20 0x20 0x20 0x20 # consensus +syscon misc NI_MAXHOST 0x0401 0x0401 0x0401 0x0100 0x0401 +syscon misc NI_NAMEREQD 8 4 4 8 4 +syscon misc NI_NOFQDN 4 1 1 4 1 +syscon misc NI_NUMERICHOST 1 2 2 1 2 +syscon misc NI_NUMERICSERV 2 8 8 2 8 +syscon misc NI_NUMERICSCOPE 0 0 0x20 0 0 + +syscon misc TCPOLEN_MAXSEG 4 4 4 4 0 # unix consensus +syscon misc TCPOLEN_SACK_PERMITTED 2 2 2 2 0 # unix consensus +syscon misc TCPOLEN_TIMESTAMP 10 10 10 10 0 # unix consensus +syscon misc TCPOLEN_WINDOW 3 3 3 3 0 # unix consensus + +syscon misc TELOPT_NAOL 8 8 8 8 0 # unix consensus +syscon misc TELOPT_NAOP 9 9 9 9 0 # unix consensus +syscon misc TELOPT_NEW_ENVIRON 39 39 39 39 0 # unix consensus +syscon misc TELOPT_OLD_ENVIRON 36 36 36 36 0 # unix consensus + +syscon misc EXTENDED_MODIFY_DATA_POINTER 0 0 0 0 0 # consensus +syscon misc EXTENDED_EXTENDED_IDENTIFY 2 0 0 0 0 +syscon misc EXTENDED_MESSAGE 1 0 0 0 0 +syscon misc EXTENDED_SDTR 1 0 0 0 0 +syscon misc EXTENDED_WDTR 3 0 0 0 0 + +syscon misc ITIMER_REAL 0 0 0 0 0 # consensus +syscon misc ITIMER_VIRTUAL 1 1 1 1 1 # unix consensus (force win) +syscon misc ITIMER_PROF 2 2 2 2 2 # unix consensus (force win) + +syscon misc L_SET 0 0 0 0 0 # consensus +syscon misc L_INCR 1 1 1 1 0 # unix consensus +syscon misc L_XTND 2 2 2 2 0 # unix consensus + +syscon misc SHUT_RD 0 0 0 0 0 # consensus (SD_RECEIVE) +syscon misc SHUT_WR 1 1 1 1 1 # consensus (SD_SEND) +syscon misc SHUT_RDWR 2 2 2 2 2 # consensus (SD_BOTH) + +syscon misc Q_QUOTAOFF 0x800003 0x0200 0x0200 0x0200 0 # bsd consensus +syscon misc Q_QUOTAON 0x800002 0x0100 0x0100 0x0100 0 # bsd consensus +syscon misc Q_SYNC 0x800001 0x0600 0x0600 0x0600 0 # bsd consensus +syscon misc Q_GETQUOTA 0x800007 768 0x0700 768 0 +syscon misc Q_SETQUOTA 0x800008 0x0400 0x0800 0x0400 0 +syscon misc Q_GETFMT 0x800004 0 0 0 0 +syscon misc Q_GETINFO 0x800005 0 0 0 0 +syscon misc Q_SETINFO 0x800006 0 0 0 0 + +syscon misc SCM_RIGHTS 1 1 1 1 0 # unix consensus +syscon misc SCM_TIMESTAMP 29 2 2 4 0 +syscon misc SCM_CREDENTIALS 2 0 0 0 0 +syscon misc SCM_TIMESTAMPING 37 0 0 0 0 +syscon misc SCM_TIMESTAMPNS 35 0 0 0 0 +syscon misc SCM_WIFI_STATUS 41 0 0 0 0 + +syscon misc FORM_C 3 3 3 3 0 # unix consensus +syscon misc FORM_N 1 1 1 1 0 # unix consensus +syscon misc FORM_T 2 2 2 2 0 # unix consensus + +syscon misc REC_EOF 2 2 2 2 0 # unix consensus +syscon misc REC_EOR 1 1 1 1 0 # unix consensus +syscon misc REC_ESC -1 -1 -1 -1 0 # unix consensus + +syscon misc RPM_PCO_ADD 1 1 1 1 0 # unix consensus +syscon misc RPM_PCO_CHANGE 2 2 2 2 0 # unix consensus +syscon misc RPM_PCO_SETGLOBAL 3 3 3 3 0 # unix consensus + +syscon misc SEARCH_EQUAL 49 0 0 0 0 +syscon misc SEARCH_EQUAL_12 177 0 0 0 0 +syscon misc SEARCH_HIGH 48 0 0 0 0 +syscon misc SEARCH_HIGH_12 176 0 0 0 0 +syscon misc SEARCH_LOW 50 0 0 0 0 +syscon misc SEARCH_LOW_12 178 0 0 0 0 + +syscon misc SI_QUEUE -1 0x010002 0x010002 -2 0 +syscon misc SI_TIMER -2 0x010003 0x010003 -3 0 +syscon misc SI_ASYNCIO -4 0x010004 0x010004 0 0 +syscon misc SI_MESGQ -3 0x010005 0x010005 0 0 +syscon misc SI_KERNEL 0x80 0 0x010006 0 0 +syscon misc SI_USER 0 0x010001 0x010001 0 0 +syscon misc SI_ASYNCNL -60 0 0 0 0 +syscon misc SI_LOAD_SHIFT 0x10 0 0 0 0 +syscon misc SI_SIGIO -5 0 0 0 0 +syscon misc SI_TKILL -6 0 0 0 0 + +syscon misc STRU_F 1 1 1 1 0 # unix consensus +syscon misc STRU_P 3 3 3 3 0 # unix consensus +syscon misc STRU_R 2 2 2 2 0 # unix consensus + +syscon misc _XOPEN_IOV_MAX 0x10 0x10 0x10 0x10 0 # unix consensus +syscon misc _XOPEN_ENH_I18N 1 1 -1 -1 0 +syscon misc _XOPEN_UNIX 1 1 -1 -1 0 +syscon misc _XOPEN_NAME_MAX 63 63 63 63 63 # forced consensus +syscon misc _XOPEN_PATH_MAX 255 255 255 255 255 # forced consensus +syscon misc _XOPEN_VERSION 700 600 0 0 0 +syscon misc _XOPEN_SOURCE 700 0 0 0 0 + +syscon misc NL_CAT_LOCALE 1 1 1 1 0 # unix consensus +syscon misc NL_MSGMAX 0x7fffffff 0x7fff 0x7fff 0x7fff 0 # bsd consensus +syscon misc NL_SETMAX 0x7fffffff 255 255 255 0 # bsd consensus +syscon misc NL_ARGMAX 0x1000 9 0x1000 9 0 +syscon misc NL_LANGMAX 0x0800 14 31 14 0 +syscon misc NL_TEXTMAX 0x7fffffff 0x0800 0x0800 255 0 +syscon misc NL_NMAX 0x7fffffff 1 1 0 0 +syscon misc NL_SETD 1 1 0 1 0 + +syscon misc RTLD_LAZY 1 1 1 1 0 # unix consensus +syscon misc RTLD_NOW 2 2 2 2 0 # unix consensus +syscon misc RTLD_GLOBAL 0x0100 8 0x0100 0x0100 0 +syscon misc RTLD_NODELETE 0x1000 0x80 0x1000 0 0 +syscon misc RTLD_NOLOAD 4 0x10 0x2000 0 0 +syscon misc RTLD_DI_LINKMAP 0 0 2 0 0 +syscon misc RTLD_LOCAL 0 4 0 0 0 + +syscon misc RUSAGE_SELF 0 0 0 0 0 # unix consensus & faked nt +syscon misc RUSAGE_CHILDREN -1 -1 -1 -1 99 # unix consensus & unavailable on nt +syscon misc RUSAGE_THREAD 1 99 1 1 1 # faked nt & unavailable on xnu + +syscon misc FSETLOCKING_QUERY 0 0 0 0 0 # consensus +syscon misc FSETLOCKING_BYCALLER 2 0 0 0 0 +syscon misc FSETLOCKING_INTERNAL 1 0 0 0 0 + +syscon misc MAX_DQ_TIME 0x093a80 0x093a80 0x093a80 0x093a80 0 # unix consensus +syscon misc MAX_IQ_TIME 0x093a80 0x093a80 0x093a80 0x093a80 0 # unix consensus +syscon misc MAX_HANDLE_SZ 0x80 0 0 0 0 + +syscon mlock MCL_CURRENT 1 1 1 1 0 # unix consensus +syscon mlock MCL_FUTURE 2 2 2 2 0 # unix consensus +syscon mlock MCL_ONFAULT 4 0 0 0 0 + +syscon misc NS_DSA_MAX_BYTES 405 405 405 0 0 +syscon misc NS_DSA_MIN_SIZE 213 213 213 0 0 +syscon misc NS_DSA_SIG_SIZE 41 41 41 0 0 +syscon misc NS_KEY_PROT_DNSSEC 3 3 3 0 0 +syscon misc NS_KEY_PROT_EMAIL 2 2 2 0 0 +syscon misc NS_KEY_PROT_IPSEC 4 4 4 0 0 +syscon misc NS_KEY_PROT_TLS 1 1 1 0 0 +syscon misc NS_KEY_RESERVED_BITMASK2 0xffff 0xffff 0xffff 0 0 +syscon misc NS_NXT_MAX 127 127 127 0 0 +syscon misc NS_OPT_DNSSEC_OK 0x8000 0x8000 0x8000 0 0 +syscon misc NS_TSIG_ERROR_FORMERR -12 -12 -12 0 0 +syscon misc NS_TSIG_ERROR_NO_SPACE -11 -11 -11 0 0 +syscon misc NS_TSIG_ERROR_NO_TSIG -10 -10 -10 0 0 +syscon misc NS_TSIG_FUDGE 300 300 300 0 0 +syscon misc NS_TSIG_TCP_COUNT 100 100 100 0 0 + +syscon misc _IOC_NONE 0 0 0 0 0 # consensus +syscon misc _IOC_READ 2 0 0 0 0 +syscon misc _IOC_WRITE 1 0 0 0 0 + +syscon misc MLD_LISTENER_QUERY 130 130 130 130 0 # unix consensus +syscon misc MLD_LISTENER_REPORT 131 131 131 131 0 # unix consensus +syscon misc MLD_LISTENER_REDUCTION 132 132 132 0 0 + +syscon misc TTYDEF_CFLAG 0x05a0 0x4b00 0x4b00 0x4b00 0 # bsd consensus +syscon misc TTYDEF_IFLAG 0x2d22 0x2b02 0x2b02 0x2b02 0 # bsd consensus +syscon misc TTYDEF_LFLAG 0x8a1b 0x05cb 0x05cb 0x05cb 0 # bsd consensus +syscon misc TTYDEF_SPEED 13 0x2580 0x2580 0x2580 0 # bsd consensus +syscon misc TTYDEF_OFLAG 0x1805 3 3 7 0 + +syscon misc ACCT_BYTEORDER 0 0 0 0 0 # consensus +syscon misc ACCT_COMM 0x10 0 0 0 0 + +syscon misc COMMAND_COMPLETE 0 0 0 0 0 # consensus +syscon misc COMMAND_TERMINATED 17 0 0 0 0 + +syscon select FD_SETSIZE 0x0400 0x0400 0x0400 0x0400 0x0400 # forced consensus (0x40 on NT) + +syscon misc MATH_ERREXCEPT 2 2 2 2 0 # unix consensus +syscon misc MATH_ERRNO 1 1 1 1 0 # unix consensus + +syscon misc SCHED_FIFO 1 4 1 1 0 +syscon misc SCHED_RR 2 2 3 3 0 +syscon misc SCHED_OTHER 0 1 2 2 0 +syscon misc SCHED_BATCH 3 0 0 0 0 +syscon misc SCHED_IDLE 5 0 0 0 0 +syscon misc SCHED_RESET_ON_FORK 0x40000000 0 0 0 0 + +syscon misc SEGV_ACCERR 2 2 2 2 0 # unix consensus +syscon misc SEGV_MAPERR 1 1 1 1 0 # unix consensus + +syscon misc TRAP_BRKPT 1 1 1 1 0 # unix consensus +syscon misc TRAP_TRACE 2 2 2 2 0 # unix consensus + +syscon misc WRDE_APPEND 0 1 1 0 0 +syscon misc WRDE_BADCHAR 0 1 1 0 0 +syscon misc WRDE_BADVAL 0 2 2 0 0 +syscon misc WRDE_CMDSUB 0 3 3 0 0 +syscon misc WRDE_DOOFFS 0 2 2 0 0 +syscon misc WRDE_NOCMD 0 4 4 0 0 +syscon misc WRDE_NOSPACE 0 4 4 0 0 +syscon misc WRDE_NOSYS 0 5 5 0 0 +syscon misc WRDE_REUSE 0 8 8 0 0 +syscon misc WRDE_SHOWERR 0 0x10 0x10 0 0 +syscon misc WRDE_SYNTAX 0 6 6 0 0 +syscon misc WRDE_UNDEF 0 0x20 0x20 0 0 + +syscon misc MCAST_BLOCK_SOURCE 43 84 84 0 43 +syscon misc MCAST_JOIN_GROUP 42 80 80 0 41 +syscon misc MCAST_JOIN_SOURCE_GROUP 46 82 82 0 45 +syscon misc MCAST_LEAVE_GROUP 45 81 81 0 42 +syscon misc MCAST_LEAVE_SOURCE_GROUP 47 83 83 0 46 +syscon misc MCAST_UNBLOCK_SOURCE 44 85 85 0 44 +syscon misc MCAST_INCLUDE 1 1 1 0 0 +syscon misc MCAST_EXCLUDE 0 2 2 0 0 +syscon misc MCAST_MSFILTER 48 0 0 0 0 + +syscon misc SIG_SETMASK 2 3 3 3 0 # bsd consensus +syscon misc SIG_UNBLOCK 1 2 2 2 0 # bsd consensus +syscon misc SIG_ATOMIC_MIN -2147483648 -2147483648 -9223372036854775808 -2147483648 0 +syscon misc SIG_BLOCK 0 1 1 1 0 # bsd consensus + +syscon misc AREGTYPE 0 0 0 0 0 # consensus +syscon misc B0 0 0 0 0 0 # consensus +syscon misc CS5 0 0 0 0 0 # consensus +syscon misc CTIME 0 0 0 0 0 # consensus +syscon misc EFD_CLOEXEC 0x080000 0 0 0 0 +syscon misc EFD_NONBLOCK 0x0800 0 0 0 0 +syscon misc EFD_SEMAPHORE 1 0 0 0 0 + +syscon misc GOOD 0 0 0 0 0 # consensus +syscon misc IPPORT_RESERVED 0x0400 0x0400 0x0400 0x0400 0x0400 # consensus +syscon misc MTRESET 0 0 0 0 0 # consensus +syscon misc MT_ST_CAN_PARTITIONS 0x0400 0 0 0 0 +syscon misc MT_ST_HPLOADER_OFFSET 0x2710 0 0 0 0 +syscon misc MT_ST_SCSI2LOGICAL 0x0800 0 0 0 0 + +syscon misc SS_ONSTACK 1 1 1 1 0 # unix consensus +syscon misc SS_DISABLE 2 4 4 4 0 # bsd consensus + +syscon misc SYNC_FILE_RANGE_WAIT_AFTER 4 0 0 0 0 +syscon misc SYNC_FILE_RANGE_WAIT_BEFORE 1 0 0 0 0 +syscon misc SYNC_FILE_RANGE_WRITE 2 0 0 0 0 + +syscon misc TEST_UNIT_READY 0 0 0 0 0 +syscon misc TFD_CLOEXEC 0x080000 0 0 0 0 +syscon misc TFD_NONBLOCK 0x0800 0 0 0 0 +syscon misc TFD_TIMER_ABSTIME 1 0 0 0 0 + +syscon misc USRQUOTA 0 0 0 0 0 +syscon misc FPE_FLTDIV 3 1 3 3 0 +syscon misc FPE_FLTINV 7 5 7 7 0 +syscon misc FPE_FLTOVF 4 2 4 4 0 +syscon misc FPE_FLTRES 6 4 6 6 0 +syscon misc FPE_FLTSUB 8 6 8 8 0 +syscon misc FPE_FLTUND 5 3 5 5 0 +syscon misc FPE_INTDIV 1 7 2 1 0 +syscon misc FPE_INTOVF 2 8 1 2 0 + +syscon misc ABDAY_1 0x020000 14 14 13 0 +syscon misc ABDAY_2 0x020001 15 15 14 0 +syscon misc ABDAY_3 0x020002 0x10 0x10 15 0 +syscon misc ABDAY_4 0x020003 17 17 0x10 0 +syscon misc ABDAY_5 0x020004 18 18 17 0 +syscon misc ABDAY_6 0x020005 19 19 18 0 +syscon misc ABDAY_7 0x020006 20 20 19 0 + +syscon misc DAY_1 0x020007 7 7 6 0 +syscon misc DAY_2 0x020008 8 8 7 0 +syscon misc DAY_3 0x020009 9 9 8 0 +syscon misc DAY_4 0x02000a 10 10 9 0 +syscon misc DAY_5 0x02000b 11 11 10 0 +syscon misc DAY_6 0x02000c 12 12 11 0 +syscon misc DAY_7 0x02000d 13 13 12 0 + +syscon misc FUTEX_PRIVATE_FLAG 0 0 0 0x80 0 +syscon misc FUTEX_REQUEUE 0 0 0 3 0 +syscon misc FUTEX_REQUEUE_PRIVATE 0 0 0 131 0 +syscon misc FUTEX_WAIT 0 0 0 1 0 +syscon misc FUTEX_WAIT_PRIVATE 0 0 0 129 0 +syscon misc FUTEX_WAKE 0 0 0 2 0 +syscon misc FUTEX_WAKE_PRIVATE 0 0 0 130 0 + +syscon misc HOST_NOT_FOUND 1 1 1 1 0x2af9 # unix consensus +syscon misc HOST_NAME_MAX 0x40 0 0 255 0 + +syscon misc LIO_WRITE 1 2 1 0 0 +syscon misc LIO_NOWAIT 1 1 0 0 0 +syscon misc LIO_READ 0 1 2 0 0 +syscon misc LIO_WAIT 0 2 1 0 0 +syscon misc LIO_NOP 2 0 0 0 0 + +syscon misc MNT_FORCE 1 0x080000 0 0x080000 0 +syscon misc MNT_DETACH 2 0 0 0 0 +syscon misc MNT_EXPIRE 4 0 0 0 0 + +syscon misc UDP_ENCAP_ESPINUDP_NON_IKE 1 0 1 0 0 +syscon misc UDP_NO_CHECK6_RX 102 0 0 0 0 +syscon misc UDP_NO_CHECK6_TX 101 0 0 0 0 + +syscon misc ACK 4 4 4 4 0 # unix consensus +syscon misc BIG_ENDIAN 0x10e1 0x10e1 0x10e1 0x10e1 0 # unix consensus +syscon misc CDISCARD 15 15 15 15 0 # unix consensus +syscon misc CDSUSP 25 25 25 25 0 # unix consensus +syscon misc CEOF 4 4 4 4 0 # unix consensus +syscon misc CEOT 4 4 4 4 0 # unix consensus +syscon misc CERASE 127 127 127 127 0 # unix consensus +syscon misc CFLUSH 15 15 15 15 0 # unix consensus +syscon misc CHRTYPE 51 51 51 51 0 # unix consensus +syscon misc CINTR 3 3 3 3 0 # unix consensus +syscon misc CKILL 21 21 21 21 0 # unix consensus +syscon misc CLNEXT 22 22 22 22 0 # unix consensus +syscon misc CMIN 1 1 1 1 0 # unix consensus +syscon misc COMPLETE 2 2 2 2 0 # unix consensus +syscon misc CONTINUE 3 3 3 3 0 # unix consensus +syscon misc CONTTYPE 55 55 55 55 0 # unix consensus +syscon misc COPY_ABORTED 10 0 0 0 0 +syscon misc COPY_VERIFY 58 0 0 0 0 + +syscon misc CQUIT 28 28 28 28 0 # unix consensus +syscon misc CREPRINT 18 18 18 18 0 # unix consensus +syscon misc CRPRNT 18 18 18 18 0 # unix consensus +syscon misc CSTART 17 17 17 17 0 # unix consensus +syscon misc CSTOP 19 19 19 19 0 # unix consensus +syscon misc CSUSP 26 26 26 26 0 # unix consensus +syscon misc CWERASE 23 23 23 23 0 # unix consensus +syscon misc DATA 3 3 3 3 0 # unix consensus +syscon misc DEV_BSIZE 0x0200 0x0200 0x0200 0x0200 0 # unix consensus +syscon misc DIRTYPE 53 53 53 53 0 # unix consensus +syscon misc ELF_NGREG 27 0 0 0 0 +syscon misc ELF_PRARGSZ 80 0 0 0 0 + +syscon misc EM_ALTERA_NIOS2 113 0 0 0 0 +syscon misc EM_LATTICEMICO32 138 0 0 0 0 + +syscon misc EXPR_NEST_MAX 0x20 0x20 0x20 0x20 0 # unix consensus + +# fallocate() flags (posix_fallocate() doesn't have these) +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon misc FALLOC_FL_KEEP_SIZE 0x01 -1 -1 -1 -1 # bsd consensus +syscon misc FALLOC_FL_PUNCH_HOLE 0x02 -1 -1 -1 -1 # bsd consensus +syscon misc FALLOC_FL_NO_HIDE_STALE 0x04 -1 -1 -1 -1 # bsd consensus +syscon misc FALLOC_FL_COLLAPSE_RANGE 0x08 -1 -1 -1 -1 # bsd consensus +syscon misc FALLOC_FL_ZERO_RANGE 0x10 -1 -1 -1 0x000980C8 # bsd consensus & kNtFsctlSetZeroData +syscon misc FALLOC_FL_INSERT_RANGE 0x20 -1 -1 -1 -1 # bsd consensus +syscon misc FALLOC_FL_UNSHARE_RANGE 0x40 -1 -1 -1 -1 # bsd consensus + +syscon misc FIFOTYPE 54 54 54 54 0 # unix consensus +syscon misc GRPQUOTA 1 1 1 1 0 # unix consensus +syscon misc IF_NAMESIZE 0x10 0x10 0x10 0x10 0 # unix consensus +syscon misc INTERMEDIATE_C_GOOD 10 0 0 0 0 +syscon misc INTERMEDIATE_GOOD 8 0 0 0 0 + +syscon misc IOV_MAX 0x0400 0x0400 0x0400 0x0400 16 # unix consensus & MSG_MAXIOVLEN +syscon misc LINE_MAX 0x0800 0x0800 0x0800 0x0800 0 # unix consensus +syscon misc LINKED_CMD_COMPLETE 10 0 0 0 0 +syscon misc LINKED_FLG_CMD_COMPLETE 11 0 0 0 0 + +syscon misc LITTLE_ENDIAN 0x04d2 0x04d2 0x04d2 0x04d2 0 # unix consensus +syscon misc LNKTYPE 49 49 49 49 0 # unix consensus +syscon misc MAXNAMLEN 255 255 255 255 0 # unix consensus +syscon misc MAXQUOTAS 2 2 2 2 0 # unix consensus +syscon misc MEDIUM_ERROR 3 0 0 0 0 +syscon misc MEDIUM_SCAN 56 0 0 0 0 + +syscon misc NBBY 8 8 8 8 0 # unix consensus +syscon misc NR_DQHASH 43 0 0 0 0 +syscon misc NR_DQUOTS 0x0100 0 0 0 0 + +syscon misc PERSISTENT_RESERVE_IN 94 0 0 0 0 +syscon misc PERSISTENT_RESERVE_OUT 95 0 0 0 0 + +syscon misc PRELIM 1 1 1 1 0 # unix consensus +syscon misc REGTYPE 48 48 48 48 0 # unix consensus +syscon misc RES_PRF_CLASS 4 4 4 4 0 # unix consensus +syscon misc RHF_GUARANTEE_START_INIT 0x80 0 0 0 0 +syscon misc RHF_NO_LIBRARY_REPLACEMENT 4 0 0 0 0 + +syscon misc RRQ 1 1 1 1 0 # unix consensus +syscon misc RTF_NOFORWARD 0x1000 0 0 0 0 +syscon misc RTF_NOPMTUDISC 0x4000 0 0 0 0 + +syscon misc SARMAG 8 8 8 8 0 # unix consensus +syscon misc SEGSIZE 0x0200 0x0200 0x0200 0x0200 0 # unix consensus +syscon misc SEND_DIAGNOSTIC 29 0 0 0 0 +syscon misc SEND_VOLUME_TAG 182 0 0 0 0 + +syscon misc SET_LIMITS 51 0 0 0 0 +syscon misc SET_WINDOW 36 0 0 0 0 + +syscon misc SFD_CLOEXEC 0x080000 0 0 0 0 +syscon misc SFD_NONBLOCK 0x0800 0 0 0 0 + +syscon misc SOMAXCONN 0x80 0x80 0x80 0x80 0x7fffffff # unix consensus +syscon misc SUBCMDMASK 255 255 255 255 0 # unix consensus +syscon misc SUBCMDSHIFT 8 8 8 8 0 # unix consensus +syscon misc SYMTYPE 50 50 50 50 0 # unix consensus +syscon misc TGEXEC 8 8 8 8 0 # unix consensus +syscon misc TGREAD 0x20 0x20 0x20 0x20 0 # unix consensus +syscon misc TGWRITE 0x10 0x10 0x10 0x10 0 # unix consensus +syscon misc TMAGLEN 6 6 6 6 0 # unix consensus +syscon misc TOEXEC 1 1 1 1 0 # unix consensus +syscon misc TOREAD 4 4 4 4 0 # unix consensus +syscon misc TOWRITE 2 2 2 2 0 # unix consensus +syscon misc TRANSIENT 4 4 4 4 0 # unix consensus +syscon misc TRY_AGAIN 2 2 2 2 0x2afa # unix consensus +syscon misc TSGID 0x0400 0x0400 0x0400 0x0400 0 # unix consensus +syscon misc TSUID 0x0800 0x0800 0x0800 0x0800 0 # unix consensus +syscon misc TSVTX 0x0200 0x0200 0x0200 0x0200 0 # unix consensus +syscon misc TUEXEC 0x40 0x40 0x40 0x40 0 # unix consensus +syscon misc TUREAD 0x0100 0x0100 0x0100 0x0100 0 # unix consensus +syscon misc TUWRITE 0x80 0x80 0x80 0x80 0 # unix consensus +syscon misc TVERSLEN 2 2 2 2 0 # unix consensus +syscon misc WNOHANG 1 1 1 1 0 # unix consensus +syscon misc WORD_BIT 0x20 0x20 0x20 0x20 0 # unix consensus +syscon misc WRQ 2 2 2 2 0 # unix consensus +syscon misc WUNTRACED 2 2 2 2 0 # unix consensus +syscon misc SIGEV_THREAD 2 3 2 0 0 +syscon misc SIGEV_SIGNAL 0 1 1 0 0 +syscon misc SIGEV_NONE 1 0 0 0 0 + +syscon misc BC_BASE_MAX 99 99 99 0x7fffffff 0 +syscon misc BC_DIM_MAX 0x0800 0x0800 0x0800 0xffff 0 +syscon misc BC_SCALE_MAX 99 99 99 0x7fffffff 0 +syscon misc BC_STRING_MAX 0x03e8 0x03e8 0x03e8 0x7fffffff 0 + +syscon misc RLIM_NLIMITS 0x10 9 15 9 0 +syscon misc RLIM_INFINITY -1 0 0x7fffffffffffffff 0 0 +syscon misc RLIM_SAVED_CUR -1 0 0x7fffffffffffffff 0 0 +syscon misc RLIM_SAVED_MAX -1 0 0x7fffffffffffffff 0 0 + +syscon misc ABORTED_COMMAND 11 0 0 0 0 +syscon misc ACORE 0 8 8 8 0 # bsd consensus +syscon misc AFORK 0 1 1 1 0 # bsd consensus +syscon misc AIO_ALLDONE 2 1 3 0 0 +syscon misc AIO_NOTCANCELED 1 4 2 0 0 +syscon misc AIO_CANCELED 0 2 1 0 0 + +syscon misc ALLOW_MEDIUM_REMOVAL 30 0 0 0 0 +syscon misc ASU 0 2 2 2 0 # bsd consensus +syscon misc ATF_NETMASK 0x20 0 0 0 0 +syscon misc AXSIG 0 0x10 0x10 0x10 0 # bsd consensus +syscon misc B1000000 0x1008 0 0 0 0 +syscon misc B110 3 110 110 110 0 # bsd consensus +syscon misc B115200 0x1002 0x01c200 0x01c200 0x01c200 0 # bsd consensus +syscon misc B1152000 0x1009 0 0 0 0 +syscon misc B1200 9 0x04b0 0x04b0 0x04b0 0 # bsd consensus +syscon misc B134 4 134 134 134 0 # bsd consensus +syscon misc B150 5 150 150 150 0 # bsd consensus +syscon misc B1500000 0x100a 0 0 0 0 +syscon misc B1800 10 0x0708 0x0708 0x0708 0 # bsd consensus +syscon misc B19200 14 0x4b00 0x4b00 0x4b00 0 # bsd consensus +syscon misc B200 6 200 200 200 0 # bsd consensus +syscon misc B2000000 0x100b 0 0 0 0 +syscon misc B230400 0x1003 0x038400 0x038400 0x038400 0 # bsd consensus +syscon misc B2400 11 0x0960 0x0960 0x0960 0 # bsd consensus +syscon misc B2500000 0x100c 0 0 0 0 +syscon misc B300 7 300 300 300 0 # bsd consensus +syscon misc B3000000 0x100d 0 0 0 0 +syscon misc B3500000 0x100e 0 0 0 0 +syscon misc B38400 15 0x9600 0x9600 0x9600 0 # bsd consensus +syscon misc B4000000 0x100f 0 0 0 0 +syscon misc B4800 12 0x12c0 0x12c0 0x12c0 0 # bsd consensus +syscon misc B50 1 50 50 50 0 # bsd consensus +syscon misc B500000 0x1005 0 0 0 0 +syscon misc B57600 0x1001 0xe100 0xe100 0xe100 0 # bsd consensus +syscon misc B576000 0x1006 0 0 0 0 +syscon misc B600 8 600 600 600 0 # bsd consensus +syscon misc B75 2 75 75 75 0 # bsd consensus +syscon misc B9600 13 0x2580 0x2580 0x2580 0 # bsd consensus +syscon misc BITSPERBYTE 8 0 0 0 0 +syscon misc BLANK_CHECK 8 0 0 0 0 +syscon misc CHANGE_DEFINITION 0x40 0 0 0 0 +syscon misc CHARBITS 8 0 0 0 0 +syscon misc CHECK_CONDITION 1 0 0 0 0 +syscon misc CONDITION_GOOD 2 0 0 0 0 +syscon misc CREAD 0x80 0x0800 0x0800 0x0800 0 # bsd consensus +syscon misc CSTOPB 0x40 0x0400 0x0400 0x0400 0 # bsd consensus +syscon misc DATA_PROTECT 7 0 0 0 0 +syscon misc DELAYTIMER_MAX 0x7fffffff 0 0 0 0 +syscon misc DMAXEXP 0x0400 0 0 0 0 +syscon misc DMINEXP -1021 0 0 0 0 +syscon misc DOUBLEBITS 0x40 0 0 0 0 +syscon misc ERA_D_FMT 0x02002e 46 46 0 0 +syscon misc ERA_D_T_FMT 0x020030 47 47 0 0 +syscon misc ERA_T_FMT 0x020031 48 48 0 0 + +# Teletypewriter Control, e.g. +# +# TCSETS → About 70,800 results (0.31 seconds) +# = TCSETNOW → About 47,700 results (0.31 seconds) +# ≈ TCSETA → About 12,600 results (0.32 seconds) +# = TIOCSETA → About 3,110 results (0.41 seconds) +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon termios TCGETS 0x5401 0x40487413 0x402c7413 0x402c7413 -1 # Gets console settings; tcgetattr(tty, argp) → ioctl(tty, TCGETS, struct termios *argp); polyfilled NT +syscon compat TIOCGETA 0x5401 0x40487413 0x402c7413 0x402c7413 -1 # Gets console settings; = tcgetattr(tty, struct termios *argp) +#syscon compat TCGETA 0x5405 -1 -1 -1 -1 # Gets console settings; ≈ ioctl(fd, TCGETA, struct termio *argp) +syscon termios TCSANOW 0 0 0 0 0 # Sets console settings; tcsetattr(fd, TCSANOW, argp); polyfilled NT +syscon termios TCSETS 0x5402 0x80487414 0x802c7414 0x802c7414 0x5402 # Sets console settings; = ioctl(tty, TCSETS, const struct termios *argp); polyfilled NT +syscon compat TIOCSETA 0x5402 0x80487414 0x802c7414 0x802c7414 0x5402 # Sets console settings; = ioctl(tty, TIOCSETA, const struct termios *argp); polyfilled NT +#syscon compat TCSETA 0x5402 0x80487414 0x802c7414 0x802c7414 0x5402 # Sets console settings; ≈ ioctl(tty, TCSETA, const struct termio *argp); polyfilled NT +syscon termios TCSADRAIN 1 1 1 1 1 # Drains output & sets console settings; tcsetawttr(fd, TCSADRAIN, argp); polyfilled NT +syscon termios TCSETSW 0x5403 0x80487415 0x802c7415 0x802c7415 0x5403 # Drains output & sets console settings; = ioctl(tty, TCSETSW, const struct termios *argp); polyfilled NT +syscon compat TIOCSETAW 0x5403 0x80487415 0x802c7415 0x802c7415 0x5403 # Drains output & sets console settings; = ioctl(tty, TIOCSETAW, const struct termios *argp); polyfilled NT +#syscon compat TCSETAW 0x5403 0x80487415 0x802c7415 0x802c7415 0x5403 # Drains output & sets console settings; ≈ ioctl(tty, TCSETAW, const struct termio *argp); polyfilled NT +syscon termios TCSAFLUSH 2 2 2 2 2 # Drops input & drains output & sets console settings; tcsetafttr(fd, TCSAFLUSH, argp); polyfilled NT +syscon termios TCSETSF 0x5404 0x80487416 0x802c7416 0x802c7416 0x5404 # Drops input & drains output & sets console settings; = ioctl(tty, TCSETSF, const struct termios *argp); polyfilled NT +syscon compat TIOCSETAF 0x5404 0x80487416 0x802c7416 0x802c7416 0x5402 # Drops input & drains output & sets console settings; = ioctl(tty, TIOCSETAF, const struct termios *argp); polyfilled NT +#syscon compat TCSETAF 0x5404 0x80487416 0x802c7416 0x802c7416 0x5402 # Drops input & drains output & sets console settings; ≈ ioctl(tty, TCSETAF, const struct termio *argp); polyfilled NT +syscon termios TIOCGWINSZ 0x5413 1074295912 1074295912 1074295912 0x5413 # ioctl(tty, TIOCGWINSZ, struct winsize *argp); polyfilled NT +syscon termios TIOCSWINSZ 0x5414 0x80087467 0x80087467 0x80087467 0x5414 # ioctl(tty, TIOCSWINSZ, const struct winsize *argp) (faked NT) +syscon termios TIOCOUTQ 0x5411 0x40047473 0x40047473 0x40047473 -1 # get # bytes queued in TTY's output buffer ioctl(tty, TIOCSWINSZ, const struct winsize *argp) +syscon termios TIOCCBRK 0x5428 0x2000747a 0x2000747a 0x2000747a -1 # boop +syscon termios TIOCCONS 0x541d 0x80047462 0x80047462 0x80047462 -1 # boop +syscon termios TIOCGETD 0x5424 0x4004741a 0x4004741a 0x4004741a -1 # boop +syscon termios TIOCGPGRP 0x540f 0x40047477 0x40047477 0x40047477 -1 # boop +syscon termios TIOCNOTTY 0x5422 0x20007471 0x20007471 0x20007471 -1 # boop +syscon termios TIOCNXCL 0x540d 0x2000740e 0x2000740e 0x2000740e -1 # boop +syscon termios TIOCSBRK 0x5427 0x2000747b 0x2000747b 0x2000747b -1 # boop +syscon termios TIOCSCTTY 0x540e 0x20007461 0x20007461 0x20007461 -1 # boop +syscon termios TIOCSETD 0x5423 0x8004741b 0x8004741b 0x8004741b -1 # boop +syscon termios TIOCSIG 0x40045436 0x2000745f 0x2004745f 0x8004745f -1 # boop +syscon termios TIOCSPGRP 0x5410 0x80047476 0x80047476 0x80047476 -1 # boop +syscon termios TIOCSTI 0x5412 0x80017472 0x80017472 0 -1 # boop +syscon termios TIOCGPTN 0x80045430 0 0x4004740f 0 -1 # boop +syscon termios TIOCGSID 0x5429 0 0x40047463 0x40047463 -1 # boop +syscon termios TABLDISC 0 0x3 0 0x3 -1 # boop +syscon termios SLIPDISC 0 0x4 0x4 0x4 -1 # boop +syscon termios PPPDISC 0 0x5 0x5 0x5 -1 # boop +syscon termios TIOCDRAIN 0 0x2000745e 0x2000745e 0x2000745e -1 # boop +syscon termios TIOCSTAT 0 0x20007465 0x20007465 0x20007465 -1 # boop +syscon termios TIOCSTART 0 0x2000746e 0x2000746e 0x2000746e -1 # boop +syscon termios TIOCCDTR 0 0x20007478 0x20007478 0x20007478 -1 # boop +syscon termios TIOCSDTR 0 0x20007479 0x20007479 0x20007479 -1 # boop +syscon termios TIOCFLUSH 0 0x80047410 0x80047410 0x80047410 -1 # boop +syscon termios TIOCEXT 0 0x80047460 0x80047460 0x80047460 -1 # boop +syscon termios TIOCGDRAINWAIT 0 0x40047456 0x40047456 0 -1 # boop +syscon termios TIOCTIMESTAMP 0 0x40107459 0x40107459 0 -1 # boop +syscon termios TIOCSDRAINWAIT 0 0x80047457 0x80047457 0 -1 # boop +syscon termios TIOCREMOTE 0 0x80047469 0 0x80047469 -1 # boop +syscon termios TTYDISC 0 0 0 0 -1 # boop +syscon termios TIOCFLAG_SOFTCAR 0 0 0 0x1 -1 # boop +syscon termios TIOCFLAG_PPS 0 0 0 0x10 -1 # boop +syscon termios TIOCFLAG_CLOCAL 0 0 0 0x2 -1 # boop +syscon termios TIOCCHKVERAUTH 0 0 0 0x2000741e -1 # boop +syscon termios TIOCGFLAGS 0 0 0 0x4004745d -1 # boop +syscon termios TIOCGTSTAMP 0 0 0 0x4010745b -1 # boop +syscon termios STRIPDISC 0 0 0 0x6 -1 # boop +syscon termios NMEADISC 0 0 0 0x7 -1 # boop +syscon termios TIOCUCNTL_CBRK 0 0 0 0x7a -1 # boop +syscon termios TIOCFLAG_MDMBUF 0 0 0 0x8 -1 # boop +syscon termios TIOCSETVERAUTH 0 0 0 0x8004741c -1 # boop +syscon termios TIOCSFLAGS 0 0 0 0x8004745c -1 # boop +syscon termios TIOCSTSTAMP 0 0 0 0x8008745a -1 # boop +syscon termios ENDRUNDISC 0 0 0 0x9 -1 # boop +syscon termios TIOCPTMASTER 0 0 0x2000741c 0 -1 # boop +syscon termios NETGRAPHDISC 0 0 0x6 0 -1 # boop +syscon termios H4DISC 0 0 0x7 0 -1 # boop + +syscon termios ISIG 0b0000000000000001 0b0000000010000000 0b0000000010000000 0b0000000010000000 0b0000000000000001 # termios.c_lflag|=ISIG makes Ctrl-C, Ctrl-\, etc. generate signals +syscon termios ICANON 0b0000000000000010 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000000000010 # termios.c_lflag&=~ICANON disables 1960's version of gnu readline +syscon termios XCASE 0b0000000000000100 0 0 16777216 0b0000000000000100 # termios.c_lflag +syscon termios ECHO 0b0000000000001000 0b0000000000001000 0b0000000000001000 0b0000000000001000 0b0000000000001000 # termios.c_lflag&=~ECHO is for passwords +syscon termios ECHOE 0b0000000000010000 0b0000000000000010 0b0000000000000010 0b0000000000000010 0b0000000000010000 # termios.c_lflag +syscon termios ECHOK 0b0000000000100000 0b0000000000000100 0b0000000000000100 0b0000000000000100 0b0000000000100000 # termios.c_lflag +syscon termios ECHONL 0b0000000001000000 0b0000000000010000 0b0000000000010000 0b0000000000010000 0b0000000001000000 # termios.c_lflag +syscon termios NOFLSH 0b0000000010000000 2147483648 2147483648 2147483648 0b0000000010000000 # termios.c_lflag|=NOFLSH means don't flush on INT/QUIT/SUSP +syscon termios TOSTOP 0b0000000100000000 4194304 4194304 4194304 0b0000000100000000 # termios.c_lflag|=TOSTOP raises SIGTTOU to process group if background job tries to write to controlling terminal +syscon termios ECHOCTL 0b0000001000000000 0b0000000001000000 0b0000000001000000 0b0000000001000000 0b0000001000000000 # termios.c_lflag|=ECHOCTL prints ^𝑥 codes for monotonic motion +syscon termios ECHOPRT 0b0000010000000000 0b0000000000100000 0b0000000000100000 0b0000000000100000 0b0000010000000000 # termios.c_lflag|=ECHOPRT includes the parity bit +syscon termios ECHOKE 0b0000100000000000 0b0000000000000001 0b0000000000000001 0b0000000000000001 0b0000100000000000 # termios.c_lflag +syscon termios FLUSHO 0b0001000000000000 8388608 8388608 8388608 0b0001000000000000 # termios.c_lflag +syscon termios PENDIN 0b0100000000000000 536870912 536870912 536870912 0b0100000000000000 # termios.c_lflag +syscon termios IEXTEN 0b1000000000000000 0b0000010000000000 0b0000010000000000 0b0000010000000000 0b1000000000000000 # termios.c_lflag&=~IEXTEN disables platform input processing magic +syscon termios EXTPROC 65536 0b0000100000000000 0b0000100000000000 0b0000100000000000 65536 # termios.c_lflag + +syscon termios IGNBRK 0b0000000000000001 0b0000000000000001 0b0000000000000001 0b0000000000000001 0b0000000000000001 # termios.c_iflag it's complicated UNIXCONSENSUS +syscon termios BRKINT 0b0000000000000010 0b0000000000000010 0b0000000000000010 0b0000000000000010 0b0000000000000010 # termios.c_iflag it's complicated UNIXCONSENSUS +syscon termios IGNPAR 0b0000000000000100 0b0000000000000100 0b0000000000000100 0b0000000000000100 0b0000000000000100 # termios.c_iflag|=IGNPAR ignores parity and framing errors; see PARMRK UNIXCONSENSUS +syscon termios PARMRK 0b0000000000001000 0b0000000000001000 0b0000000000001000 0b0000000000001000 0b0000000000001000 # termios.c_iflag|=PARMRK passes-through parity bit UNIXCONSENSUS +syscon termios INPCK 0b0000000000010000 0b0000000000010000 0b0000000000010000 0b0000000000010000 0b0000000000010000 # termios.c_iflag|=INPCK enables parity checking UNIXCONSENSUS +syscon termios ISTRIP 0b0000000000100000 0b0000000000100000 0b0000000000100000 0b0000000000100000 0b0000000000100000 # termios.c_iflag|=ISTRIP automates read(1)&0x7f UNIXCONSENSUS +syscon termios INLCR 0b0000000001000000 0b0000000001000000 0b0000000001000000 0b0000000001000000 0b0000000001000000 # termios.c_iflag|=INLCR maps \n → \r input UNIXCONSENSUS +syscon termios IGNCR 0b0000000010000000 0b0000000010000000 0b0000000010000000 0b0000000010000000 0b0000000010000000 # termios.c_iflag|=IGNCR maps \r → ∅ input UNIXCONSENSUS +syscon termios ICRNL 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000100000000 # termios.c_iflag|=ICRNL maps \r → \n input UNIXCONSENSUS +syscon termios IUCLC 0b0000001000000000 0 0 0b0001000000000000 0b0000001000000000 # termios.c_iflag|=IUCLC maps A-Z → a-z input +syscon termios IXON 0b0000010000000000 0b0000001000000000 0b0000001000000000 0b0000001000000000 0b0000010000000000 # termios.c_iflag|=IXON enables flow rida +syscon termios IXANY 0b0000100000000000 0b0000100000000000 0b0000100000000000 0b0000100000000000 0b0000100000000000 # termios.c_iflag|=IXANY tying will un-stuck teletype UNIXCONSENSUS +syscon termios IXOFF 0b0001000000000000 0b0000010000000000 0b0000010000000000 0b0000010000000000 0b0001000000000000 # termios.c_iflag|=IXOFF disables annoying display freeze keys +syscon termios IMAXBEL 0b0010000000000000 0b0010000000000000 0b0010000000000000 0b0010000000000000 0b0010000000000000 # termios.c_iflag|=IMAXBEL rings when queue full UNIXCONSENSUS +syscon termios IUTF8 0b0100000000000000 0b0100000000000000 0 0 0b0100000000000000 # termios.c_iflag|=IUTF8 helps w/ rubout on UTF-8 input + +syscon termios OPOST 0b0000000000000001 0b000000000000000001 0b000000000000000001 0b0000000000000001 0b0000000000000001 # termios.c_oflag&=~OPOST disables output processing magic +syscon termios OLCUC 0b0000000000000010 0b000000000000000000 0 0b0000000000100000 0b0000000000000010 # termios.c_oflag|=OLCUC maps a-z → A-Z output +syscon termios ONLCR 0b0000000000000100 0b000000000000000010 0b000000000000000010 0b0000000000000010 0b0000000000000100 # termios.c_oflag|=ONLCR maps \n → \r\n output +syscon termios OCRNL 0b0000000000001000 0b000000000000010000 0b000000000000010000 0b0000000000010000 0b0000000000001000 # termios.c_oflag|=OCRNL maps \r → \n output +syscon termios ONOCR 0b0000000000010000 0b000000000000100000 0b000000000000100000 0b0000000001000000 0b0000000000010000 # termios.c_oflag|=ONOCR maps \r → ∅ output iff column 0 +syscon termios ONLRET 0b0000000000100000 0b000000000001000000 0b000000000001000000 0b0000000010000000 0b0000000000100000 # termios.c_oflag|=ONLRET maps \r → ∅ output +syscon termios OFILL 0b0000000001000000 0b000000000010000000 0 0 0b0000000001000000 # termios.c_oflag +syscon termios OFDEL 0b0000000010000000 0b100000000000000000 0 0 0b0000000010000000 # termios.c_oflag +syscon termios NLDLY 0b0000000100000000 0b000000001100000000 0b000000001100000000 0 0b0000000100000000 # (termios.c_oflag & NLDLY) ∈ {NL0,NL1,NL2,NL3} +syscon termios NL0 0b0000000000000000 0b000000000000000000 0b000000000000000000 0 0b0000000000000000 # (termios.c_oflag & NLDLY) == NL0 +syscon termios NL1 0b0000000100000000 0b000000000100000000 0b000000000100000000 0 0b0000000100000000 # (termios.c_oflag & NLDLY) == NL1 +syscon termios NL2 0 0b000000001000000000 0b000000001000000000 0 0 # (termios.c_oflag & NLDLY) == NL2 +syscon termios NL3 0 0b000000001100000000 0b000000001100000000 0 0 # (termios.c_oflag & NLDLY) == NL3 +syscon termios CRDLY 0b0000011000000000 0b000011000000000000 0b000011000000000000 0 0b0000011000000000 # (termios.c_oflag & CRDLY) ∈ {CR0,CR1,CR2,CR3} +syscon termios CR0 0b0000000000000000 0b000000000000000000 0b000000000000000000 0x0 0b0000000000000000 # (termios.c_oflag & CRDLY) == CR0 +syscon termios CR1 0b0000001000000000 0b000001000000000000 0b000001000000000000 0x0 0b0000001000000000 # (termios.c_oflag & CRDLY) == CR1 +syscon termios CR2 0b0000010000000000 0b000010000000000000 0b000010000000000000 0x0 0b0000010000000000 # (termios.c_oflag & CRDLY) == CR2 +syscon termios CR3 0b0000011000000000 0b000011000000000000 0b000011000000000000 0x0 0b0000011000000000 # (termios.c_oflag & CRDLY) == CR3 +syscon termios TABDLY 0b0001100000000000 0b000000110000000100 0b000000000000000100 0 0b0001100000000000 # (termios.c_oflag & TABDLY) ∈ {TAB0,TAB1,TAB2,TAB3,XTABS} +syscon termios TAB0 0b0000000000000000 0b000000000000000000 0b000000000000000000 0 0b0000000000000000 # (termios.c_oflag & TABDLY) == TAB0 +syscon termios TAB1 0b0000100000000000 0b000000010000000000 0b000000010000000000 0 0b0000100000000000 # (termios.c_oflag & TABDLY) == TAB1 +syscon termios TAB2 0b0001000000000000 0b000000100000000000 0b000000100000000000 0 0b0001000000000000 # (termios.c_oflag & TABDLY) == TAB2 +syscon termios TAB3 0b0001100000000000 0b000000000000000100 0b000000000000000100 0 0b0001100000000000 # (termios.c_oflag & TABDLY) == TAB3 +syscon termios XTABS 0b0001100000000000 0b000000000000000000 0b000000110000000000 0 0b0001100000000000 # (termios.c_oflag & TABDLY) == XTABS +syscon termios BSDLY 0b0010000000000000 0b001000000000000000 0b001000000000000000 0 0b0010000000000000 # termios.c_oflag +syscon termios BS0 0b0000000000000000 0b000000000000000000 0b000000000000000000 0 0b0000000000000000 # termios.c_oflag +syscon termios BS1 0b0010000000000000 0b001000000000000000 0b001000000000000000 0 0b0010000000000000 # termios.c_oflag +syscon termios VTDLY 0b0100000000000000 0b010000000000000000 0b010000000000000000 0 0b0100000000000000 # termios.c_oflag +syscon termios VT0 0b0000000000000000 0b000000000000000000 0b000000000000000000 0 0b0000000000000000 # termios.c_oflag +syscon termios VT1 0b0100000000000000 0b010000000000000000 0b010000000000000000 0 0b0100000000000000 # termios.c_oflag +syscon termios FFDLY 0b1000000000000000 0b000100000000000000 0b000100000000000000 0 0b1000000000000000 # termios.c_oflag +syscon termios FF0 0b0000000000000000 0b000000000000000000 0b000000000000000000 0 0b0000000000000000 # termios.c_oflag +syscon termios FF1 0b1000000000000000 0b000100000000000000 0b000100000000000000 0 0b1000000000000000 # termios.c_oflag + +syscon termios CS6 0b0000000000010000 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000000010000 # termios.c_cflag flag for 6-bit characters +syscon termios CS7 0b0000000000100000 0b0000001000000000 0b0000001000000000 0b0000001000000000 0b0000000000100000 # termios.c_cflag flag for 7-bit characters +syscon termios CS8 0b0000000000110000 0b0000001100000000 0b0000001100000000 0b0000001100000000 0b0000000000110000 # termios.c_cflag flag for 8-bit characters +syscon termios CSIZE 0b0000000000110000 0b0000001100000000 0b0000001100000000 0b0000001100000000 0b0000000000110000 # mask for CS𝑥 flags + +syscon termios NCCS 32 32 32 32 32 # ARRAYLEN(termios.c_cc); faked xnu/freebsd/openbsd (originally 20) and faked nt +syscon termios VINTR 0 8 8 8 0 # termios.c_cc[VINTR]=𝑥 +syscon termios VQUIT 1 9 9 9 0 # termios.c_cc[VQUIT]=𝑥 +syscon termios VERASE 2 3 3 3 0 # termios.c_cc[VERASE]=𝑥 +syscon termios VKILL 3 5 5 5 0 # termios.c_cc[VKILL]=𝑥 +syscon termios VEOF 4 0 0 0 0 # termios.c_cc[VEOF]=𝑥 +syscon termios VTIME 5 17 17 17 0 # termios.c_cc[VTIME]=𝑥 yields 𝑥×𝟷𝟶𝟶ms non-canonical read timeout +syscon termios VMIN 6 16 16 16 0 # termios.c_cc[VMIN]=𝑥 +syscon termios VSWTC 7 0 0 0 0 # termios.c_cc[VSWTC]=𝑥 +syscon termios VSTART 8 12 12 12 0 # termios.c_cc[VSTART]=𝑥 +syscon termios VSTOP 9 13 13 13 0 # termios.c_cc[VSTOP]=𝑥 +syscon termios VSUSP 10 10 10 10 0 # termios.c_cc[VSUSP]=𝑥 defines suspend, i.e. Ctrl-Z (a.k.a. →, ^Z, SUB, 26, 032, 0x1A, ord('Z')^0b01000000); unix consensus +syscon termios VEOL 11 1 1 1 0 # termios.c_cc[VEOL]=𝑥 +syscon termios VEOL2 16 2 2 2 0 # termios.c_cc[VEOL2]=𝑥 +syscon termios VREPRINT 12 6 6 6 0 # termios.c_cc[VREPRINT]=𝑥 +syscon termios VDISCARD 13 15 15 15 0 # termios.c_cc[VDISCARD]=𝑥 +syscon termios VWERASE 14 4 4 4 0 # termios.c_cc[VWERASE]=𝑥 +syscon termios VLNEXT 15 14 14 14 0 # termios.c_cc[VLNEXT]=𝑥 + +syscon termios TIOCSERGETLSR 0x5459 0 0 0 0 # +syscon termios TIOCSERGETMULTI 0x545a 0 0 0 0 # +syscon termios TIOCSERSETMULTI 0x545b 0 0 0 0 # +syscon termios TIOCSER_TEMT 1 0 0 0 0 # +syscon termios VERIFY 47 0 0 0 0 +syscon termios PARENB 0x0100 0x1000 0x1000 0x1000 0 # +syscon termios PARODD 0x0200 0x2000 0x2000 0x2000 0 # +syscon termios CIBAUD 0x100f0000 0 0 0 0 +syscon termios CLOCAL 0x0800 0x8000 0x8000 0x8000 0 # +syscon termios CMSPAR 0x40000000 0 0 0 0 +syscon termios BUSY 4 0 0 0 0 +syscon termios CANBSIZ 255 0 0 0 0 +syscon termios CBAUD 0x100f 0 0 0 0 +syscon termios CBAUDEX 0x1000 0 0 0 0 +syscon termios CBRK 0 255 255 255 0 # +syscon termios CEOL 0 255 255 255 0 # + +# Pseudoteletypewriter Control +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon pty TIOCPKT 0x5420 0x80047470 0x80047470 0x80047470 -1 # boop +syscon pty TIOCPKT_DATA 0 0 0 0 0 # consensus +syscon pty TIOCPKT_FLUSHREAD 1 1 1 1 1 # unix consensus +syscon pty TIOCPKT_FLUSHWRITE 2 2 2 2 2 # unix consensus +syscon pty TIOCPKT_STOP 4 4 4 4 4 # unix consensus +syscon pty TIOCPKT_START 8 8 8 8 8 # unix consensus +syscon pty TIOCPKT_NOSTOP 16 16 16 16 16 # unix consensus +syscon pty TIOCPKT_DOSTOP 32 32 32 32 32 # unix consensus +syscon pty TIOCPKT_IOCTL 64 64 64 64 64 # unix consensus +syscon pty TIOCSPTLCK 0x40045431 0 0 0 -1 # boop +syscon pty PTMGET 0 0 0 0x40287401 -1 # for /dev/ptm + +# Modem Control +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary +syscon modem TIOCMGET 0x5415 0x4004746a 0x4004746a 0x4004746a -1 # get status of modem bits; ioctl(fd, TIOCMGET, int *argp) +syscon modem TIOCMSET 0x5418 0x8004746d 0x8004746d 0x8004746d -1 # set status of modem bits; ioctl(fd, TIOCMSET, const int *argp) +syscon modem TIOCMBIC 0x5417 0x8004746b 0x8004746b 0x8004746b -1 # clear indicated modem bits; ioctl(fd, TIOCMBIC, int *argp) +syscon modem TIOCMBIS 0x5416 0x8004746c 0x8004746c 0x8004746c -1 # set indicated modem bits; ioctl(fd, TIOCMBIS, int *argp) +syscon modem TIOCM_LE 0b0000000000000001 0b0000000000000001 0b0000000000000001 0b0000000000000001 0b0000000000000001 # consensus +syscon modem TIOCM_DTR 0b0000000000000010 0b0000000000000010 0b0000000000000010 0b0000000000000010 0b0000000000000010 # consensus +syscon modem TIOCM_RTS 0b0000000000000100 0b0000000000000100 0b0000000000000100 0b0000000000000100 0b0000000000000100 # consensus +syscon modem TIOCM_ST 0b0000000000001000 0b0000000000001000 0b0000000000001000 0b0000000000001000 0b0000000000001000 # consensus +syscon modem TIOCM_SR 0b0000000000010000 0b0000000000010000 0b0000000000010000 0b0000000000010000 0b0000000000010000 # consensus +syscon modem TIOCM_CTS 0b0000000000100000 0b0000000000100000 0b0000000000100000 0b0000000000100000 0b0000000000100000 # consensus +syscon modem TIOCM_CAR 0b0000000001000000 0b0000000001000000 0b0000000001000000 0b0000000001000000 0b0000000001000000 # consensus +syscon modem TIOCM_CD 0b0000000001000000 0b0000000001000000 0b0000000001000000 0b0000000001000000 0b0000000001000000 # boop +syscon modem TIOCM_RI 0b0000000010000000 0b0000000010000000 0b0000000010000000 0b0000000010000000 0b0000000010000000 # boop +syscon modem TIOCM_RNG 0b0000000010000000 0b0000000010000000 0b0000000010000000 0b0000000010000000 0b0000000010000000 # boop +syscon modem TIOCM_DSR 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000100000000 # consensus +syscon modem TIOCM_DCD 0 0 0x40 0 -1 # wut +syscon modem TIOCMODG 0 0x40047403 0 0x4004746a -1 # wut +syscon modem TIOCMODS 0 0x80047404 0 0x8004746d -1 # wut +syscon modem TIOCMSDTRWAIT 0 0x8004745b 0x8004745b 0 -1 # wut + +syscon ioctl FIONBIO 0x5421 0x8004667e 0x8004667e 0x8004667e 0x8004667e # BSD-Windows consensus; FIONBIO is traditional O_NONBLOCK; see F_SETFL for re-imagined api +syscon ioctl FIOASYNC 0x5452 0x8004667d 0x8004667d 0x8004667d 0x8004667d # BSD-Windows consensus +syscon ioctl FIONREAD 0x541b 0x4004667f 0x4004667f 0x4004667f 0x4004667f # BSD-Windows consensus; bytes waiting in FD's input buffer +#syscon ioctl FIONWRITE 0x0 0x0 0x40046677 0x0 -1 # [FreeBSD Generalization] bytes queued in FD's output buffer (same as TIOCOUTQ for TTY FDs; see also SO_SNDBUF) +#syscon ioctl FIONSPACE 0x0 0x0 0x40046676 0x0 -1 # [FreeBSD Generalization] capacity of FD's output buffer, e.g. equivalent to TIOCGSERIAL w/ UART +syscon ioctl TIOCINQ 0x541b 0x4004667f 0x4004667f 0x4004667f 0x4004667f # [Linuxism] same as FIONREAD +syscon ioctl TIOCOUTQ 0x5411 0x40047473 0x40047473 0x40047473 -1 # bytes queued in TTY's output buffer + +syscon misc FANOTIFY_METADATA_VERSION 3 0 0 0 0 +syscon misc FAPPEND 0x0400 8 8 8 0 # bsd consensus +syscon misc FASYNC 0x2000 0x40 0x40 0x40 0 # bsd consensus +syscon misc FFSYNC 0x101000 0x80 0x80 0x80 0 # bsd consensus +syscon misc FILENAME_MAX 0x1000 0x0400 0x0400 0x0400 0 # bsd consensus +syscon misc FIOGETOWN 0x8903 0x4004667b 0x4004667b 0x4004667b 0 # bsd consensus +syscon misc FIOSETOWN 0x8901 0x8004667c 0x8004667c 0x8004667c 0 # bsd consensus +syscon misc FMAXEXP 0x80 0 0 0 0 +syscon misc FMINEXP -125 0 0 0 0 +syscon misc FNDELAY 0x0800 4 4 4 0 # bsd consensus +syscon misc FNONBLOCK 0x0800 4 4 4 0 # bsd consensus +syscon misc FOPEN_MAX 0x10 20 20 20 0 # bsd consensus +syscon misc FORMAT_UNIT 4 0 0 0 0 +syscon misc HARDWARE_ERROR 4 0 0 0 0 +syscon misc HEAD_OF_QUEUE_TAG 33 0 0 0 0 +syscon misc HUPCL 0x0400 0x4000 0x4000 0x4000 0 # bsd consensus +syscon misc IGMP_MEMBERSHIP_QUERY 17 0 0 0 0 +syscon misc ILLEGAL_REQUEST 5 0 0 0 0 +syscon misc INITIATE_RECOVERY 15 0 0 0 0 +syscon misc INITIATOR_ERROR 5 0 0 0 0 +syscon misc INQUIRY 18 0 0 0 0 +syscon misc MAXHOSTNAMELEN 0x40 0x0100 0x0100 0x0100 0 # bsd consensus +syscon misc MAXPATHLEN 255 255 255 255 255 # forced consensus +syscon misc MAXSYMLINKS 20 0x20 0x20 0x20 0 # bsd consensus +syscon misc MESSAGE_REJECT 7 0 0 0 0 +syscon misc MISCOMPARE 14 0 0 0 0 +syscon misc MOVE_MEDIUM 165 0 0 0 0 +syscon misc MTCOMPRESSION 0x20 0 0 0 0 +syscon misc MTFSFM 11 0 0 0 0 +syscon misc MTLOCK 28 0 0 0 0 +syscon misc MTMKPART 34 0 0 0 0 +syscon misc MTRAS1 14 0 0 0 0 +syscon misc MTRAS3 0x10 0 0 0 0 +syscon misc MTSETBLK 20 0 0 0 0 +syscon misc MTSETDENSITY 21 0 0 0 0 +syscon misc MTSETDRVBUFFER 24 0 0 0 0 +syscon misc MTSETPART 33 0 0 0 0 +syscon misc MTUNLOAD 31 0 0 0 0 +syscon misc MTUNLOCK 29 0 0 0 0 +syscon misc NCARGS 0x020000 0x040000 0x040000 0x040000 0 # bsd consensus +syscon misc NGREG 23 0 0 0 0 +syscon misc NOGROUP -1 0xffff 0xffff 0xffff 0 # bsd consensus +syscon misc ORDERED_QUEUE_TAG 34 0 0 0 0 +syscon misc ORIG_RAX 15 0 0 0 0 +syscon misc PIPE_BUF 0x1000 0x0200 0x0200 0x0200 0 # bsd consensus +syscon misc PRE_FETCH 52 0 0 0 0 +syscon misc QUEUE_FULL 20 0 0 0 0 +syscon misc REASSIGN_BLOCKS 7 0 0 0 0 +syscon misc RECEIVE_DIAGNOSTIC 28 0 0 0 0 +syscon misc RECOVERED_ERROR 1 0 0 0 0 +syscon misc RECOVER_BUFFERED_DATA 20 0 0 0 0 +syscon misc RELEASE_RECOVERY 0x10 0 0 0 0 +syscon misc REQUEST_SENSE 3 0 0 0 0 +syscon misc RESERVATION_CONFLICT 12 0 0 0 0 +syscon misc RESERVE 22 0 0 0 0 +syscon misc RESERVE_10 86 0 0 0 0 +syscon misc RESTORE_POINTERS 3 0 0 0 0 +syscon misc REZERO_UNIT 1 0 0 0 0 +syscon misc RE_DUP_MAX 0x7fff 255 255 255 0 # bsd consensus +syscon misc RTCF_DOREDIRECT 0x01000000 0 0 0 0 +syscon misc SAVE_POINTERS 2 0 0 0 0 +syscon misc SEM_VALUE_MAX 0x7fffffff 0x7fff 0x7fffffff 0xffffffff 0 +syscon misc SEM_INFO 19 0 11 0 0 +syscon misc SEM_STAT 18 0 10 0 0 + +syscon misc SHMLBA 0 0x1000 0x1000 0x1000 0 # bsd consensus +syscon misc SIMPLE_QUEUE_TAG 0x20 0 0 0 0 +syscon misc SPACE 17 0 0 0 0 +syscon misc START_STOP 27 0 0 0 0 +syscon misc STATUS_MASK 62 0 0 0 0 +syscon misc SWAP_FLAG_DISCARD 0x010000 0 0 0 0 +syscon misc SYNCHRONIZE_CACHE 53 0 0 0 0 +syscon misc UMOUNT_NOFOLLOW 8 0 0 0 0 +syscon misc UNIT_ATTENTION 6 0 0 0 0 +syscon misc UPDATE_BLOCK 61 0 0 0 0 +syscon misc UT_HOSTSIZE 0x0100 0x10 0 0x0100 0 +syscon misc UT_LINESIZE 0x20 8 0 8 0 +syscon misc UT_NAMESIZE 0x20 8 0 0x20 0 + +syscon misc WEOF 0xffffffff -1 -1 -1 -1 # bsd consensus (win fake) +syscon misc _LINUX_QUOTA_VERSION 2 0 0 0 0 +syscon misc _SEM_SEMUN_UNDEFINED 1 0 0 0 0 +syscon misc D_FMT 0x020029 2 2 1 0 +syscon misc D_T_FMT 0x020028 1 1 0 0 + +syscon misc LOGIN_PROCESS 6 6 6 0 0 +syscon misc LOGIN_NAME_MAX 0x0100 0 0 0x20 0 + +syscon misc T_FMT 0x02002a 3 3 2 0 +syscon misc T_FMT_AMPM 0x02002b 4 4 3 0 + +syscon misc UL_GETFSIZE 1 1 1 0 0 +syscon misc UL_SETFSIZE 2 2 2 0 0 + +syscon misc UTIME_NOW 0x3fffffff 0 -1 -2 0 +syscon misc UTIME_OMIT 0x3ffffffe 0 -2 -1 0 + +syscon misc XATTR_CREATE 1 2 0 0 0 +syscon misc XATTR_REPLACE 2 4 0 0 0 + +syscon misc ACCOUNTING 9 9 0 0 0 +syscon misc AHZ 100 0x40 0 0x40 0 +syscon misc ALT_DIGITS 0x02002f 49 49 0 0 +syscon misc AM_STR 0x020026 5 5 4 0 +syscon misc B460800 0x1004 0 0x070800 0 0 +syscon misc B921600 0x1007 0 0x0e1000 0 0 +syscon misc BOOT_TIME 2 2 1 0 0 +syscon misc CHARCLASS_NAME_MAX 0x0800 14 14 0 0 +syscon misc CLOCKS_PER_SEC 1000000 1000000 0x80 100 10000000 +syscon misc CODESET 14 0 0 51 0 +syscon misc COLL_WEIGHTS_MAX 255 2 10 2 0 +syscon misc CPU_SETSIZE 0x0400 0 0x0100 0 0 +syscon misc CRNCYSTR 0x04000f 56 56 50 0 +syscon misc CRTSCTS 0x80000000 0x030000 0x030000 0x010000 0 +syscon misc CSTATUS 0 20 20 255 0 +syscon misc DEAD_PROCESS 8 8 7 0 0 +syscon misc FNM_NOSYS -1 -1 -1 2 0 +syscon misc INIT_PROCESS 5 5 5 0 0 +syscon misc MINSIGSTKSZ 0x0800 0x8000 0x0800 0x3000 0 +syscon misc MQ_PRIO_MAX 0x8000 0 0x40 0 0 +syscon misc MTERASE 13 0 12 9 0 +syscon misc MTLOAD 30 0 19 0 0 +syscon misc MTRETEN 9 0 0 8 0 +syscon misc NEW_TIME 3 4 3 0 0 +syscon misc NFDBITS 0x40 0x20 0x40 0x20 0 +syscon misc NGROUPS 0x010000 0x10 0x0400 0x10 0 +syscon misc NGROUPS_MAX 0x010000 0x10 0x03ff 0x10 0 +syscon misc NOEXPR 0x050001 53 53 49 0 +syscon misc NOFILE 0x0100 0x0100 0x40 0x40 0 +syscon misc NOSTR 0x050003 55 55 48 0 +syscon misc OLD_TIME 4 3 2 0 0 +syscon misc PM_STR 0x020027 6 6 5 0 +syscon misc RADIXCHAR 0x010000 50 50 44 0 +syscon misc RUN_LVL 1 1 0 0 0 +syscon misc STA_RONLY 0xff00 0 0xff00 0 0 +syscon misc SYMLOOP_MAX 0 0 0 0x20 0 +syscon misc THOUSEP 0x010001 51 51 45 0 +syscon misc TIMER_ABSTIME 1 0 1 1 0 +syscon misc TIME_UTC 1 0 1 0 0 +syscon misc TMP_MAX 0x03a2f8 0x1269ae40 0x1269ae40 0x7fffffff 0 +syscon misc TSS_DTOR_ITERATIONS 0 0 4 0 0 +syscon misc TTY_NAME_MAX 0x20 0 0 260 0 +syscon misc UIO_MAXIOV 0x0400 0 0 0x0400 0 +syscon misc USER_PROCESS 7 7 4 0 0 +syscon misc WCONTINUED 8 0x10 4 8 0 +syscon misc WEXITED 4 4 0x10 0 0 +syscon misc WNOWAIT 0x01000000 0x20 8 0 0 +syscon misc WSTOPPED 2 8 2 0 0 +syscon misc YESEXPR 0x050000 52 52 47 0 +syscon misc YESSTR 0x050002 54 54 46 0 + +# System Call Numbers. +# +# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX +syscon nr __NR_getpid 0x0027 0x2000014 0x0014 0x0014 -1 +syscon nr __NR_kill 0x003e 0x2000025 0x0025 0x007a -1 +syscon nr __NR_exit 0x00e7 0x2000001 0x0001 0x0001 -1 +syscon nr __NR_read 0x0000 0x2000003 0x0003 0x0003 -1 +syscon nr __NR_write 0x0001 0x2000004 0x0004 0x0004 -1 +syscon nr __NR_open 0x0002 0x2000005 0x0005 0x0005 -1 +syscon nr __NR_close 0x0003 0x2000006 0x0006 0x0006 -1 +syscon nr __NR_wait4 0x003d 0x1000007 0x0007 0x000b -1 +syscon nr __NR_stat 0x0004 0x2000152 0x00bc 0x0026 -1 +syscon nr __NR_fstat 0x0005 0x2000153 0x0227 0x0035 -1 +syscon nr __NR_lstat 0x0006 0x2000154 0x0028 0x0028 -1 +syscon nr __NR_mmap 0x0009 0x20000c5 0x01dd 0x00c5 -1 +syscon nr __NR_mprotect 0x000a 0x200004a 0x004a 0x004a -1 +syscon nr __NR_munmap 0x000b 0x2000049 0x0049 0x0049 -1 +syscon nr __NR_sigaction 0x000d 0x200002e 0x01a0 0x002e -1 +syscon nr __NR_pread 0x0011 0x2000099 0x01db 0x00ad -1 +syscon nr __NR_pwrite 0x0012 0x200009a 0x01dc 0x00ae -1 +syscon nr __NR_access 0x0015 0x2000021 0x0021 0x0021 -1 +syscon nr __NR_sched_yield 0x0018 0x100003c 0x014b 0x012a -1 +syscon nr __NR_sendfile 0x0028 0x2000151 0x0189 0xffff -1 +syscon nr __NR_fork 0x0039 0x2000002 0x0002 0x0002 -1 +syscon nr __NR_gettimeofday 0x0060 0x2000074 0x0074 0x0043 -1 +syscon nr __NR_arch_prctl 0x009e 0x000ffff 0x00a5 0x00a5 -1 +syscon nr __NR_gettid 0x00ba 0x200011e 0xffff 0xffff -1 +syscon nr __NR_fadvise 0x00dd 0x000ffff 0x0213 0xffff -1 +syscon nr __NR_clock_gettime 0x00e4 0x000ffff 0x00e8 0x0057 -1 +syscon nr __NR_getuid 0x0066 0x2000018 0x0018 0x0018 -1 +syscon nr __NR_getgid 0x0068 0x200002f 0x002f 0x002f -1 +syscon nr __NR_geteuid 0x006b 0x2000019 0x0019 0x0019 -1 +syscon nr __NR_getegid 0x006c 0x200002b 0x002b 0x002b -1 +syscon nr __NR_madvise 0x001c 0x200004b 0x004b 0x004b -1 +syscon nr __NR_sigprocmask 0x000e 0x2000030 0x0154 0x0030 -1 + +# https://youtu.be/GUQUD3IMbb4?t=85 diff --git a/libc/sysv/consts/ABDAY_1.s b/libc/sysv/consts/ABDAY_1.s new file mode 100644 index 00000000..219f72f1 --- /dev/null +++ b/libc/sysv/consts/ABDAY_1.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ABDAY_1 0x020000 14 14 13 0 diff --git a/libc/sysv/consts/ABDAY_2.s b/libc/sysv/consts/ABDAY_2.s new file mode 100644 index 00000000..f22ed679 --- /dev/null +++ b/libc/sysv/consts/ABDAY_2.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ABDAY_2 0x020001 15 15 14 0 diff --git a/libc/sysv/consts/ABDAY_3.s b/libc/sysv/consts/ABDAY_3.s new file mode 100644 index 00000000..af32816f --- /dev/null +++ b/libc/sysv/consts/ABDAY_3.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ABDAY_3 0x020002 0x10 0x10 15 0 diff --git a/libc/sysv/consts/ABDAY_4.s b/libc/sysv/consts/ABDAY_4.s new file mode 100644 index 00000000..43beac7b --- /dev/null +++ b/libc/sysv/consts/ABDAY_4.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ABDAY_4 0x020003 17 17 0x10 0 diff --git a/libc/sysv/consts/ABDAY_5.s b/libc/sysv/consts/ABDAY_5.s new file mode 100644 index 00000000..ea300d47 --- /dev/null +++ b/libc/sysv/consts/ABDAY_5.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ABDAY_5 0x020004 18 18 17 0 diff --git a/libc/sysv/consts/ABDAY_6.s b/libc/sysv/consts/ABDAY_6.s new file mode 100644 index 00000000..15365842 --- /dev/null +++ b/libc/sysv/consts/ABDAY_6.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ABDAY_6 0x020005 19 19 18 0 diff --git a/libc/sysv/consts/ABDAY_7.s b/libc/sysv/consts/ABDAY_7.s new file mode 100644 index 00000000..9fcba98b --- /dev/null +++ b/libc/sysv/consts/ABDAY_7.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ABDAY_7 0x020006 20 20 19 0 diff --git a/libc/sysv/consts/ABORTED_COMMAND.s b/libc/sysv/consts/ABORTED_COMMAND.s new file mode 100644 index 00000000..33f146f1 --- /dev/null +++ b/libc/sysv/consts/ABORTED_COMMAND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ABORTED_COMMAND 11 0 0 0 0 diff --git a/libc/sysv/consts/ACCOUNTING.s b/libc/sysv/consts/ACCOUNTING.s new file mode 100644 index 00000000..e61f840c --- /dev/null +++ b/libc/sysv/consts/ACCOUNTING.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ACCOUNTING 9 9 0 0 0 diff --git a/libc/sysv/consts/ACCT_BYTEORDER.s b/libc/sysv/consts/ACCT_BYTEORDER.s new file mode 100644 index 00000000..c731c88a --- /dev/null +++ b/libc/sysv/consts/ACCT_BYTEORDER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ACCT_BYTEORDER 0 0 0 0 0 diff --git a/libc/sysv/consts/ACCT_COMM.s b/libc/sysv/consts/ACCT_COMM.s new file mode 100644 index 00000000..d456dea4 --- /dev/null +++ b/libc/sysv/consts/ACCT_COMM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ACCT_COMM 0x10 0 0 0 0 diff --git a/libc/sysv/consts/ACK.s b/libc/sysv/consts/ACK.s new file mode 100644 index 00000000..50bb9a1f --- /dev/null +++ b/libc/sysv/consts/ACK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ACK 4 4 4 4 0 diff --git a/libc/sysv/consts/ACORE.s b/libc/sysv/consts/ACORE.s new file mode 100644 index 00000000..265c0449 --- /dev/null +++ b/libc/sysv/consts/ACORE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ACORE 0 8 8 8 0 diff --git a/libc/sysv/consts/ADDR_COMPAT_LAYOUT.s b/libc/sysv/consts/ADDR_COMPAT_LAYOUT.s new file mode 100644 index 00000000..fc726362 --- /dev/null +++ b/libc/sysv/consts/ADDR_COMPAT_LAYOUT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon prsnlty ADDR_COMPAT_LAYOUT 0x0200000 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ADDR_LIMIT_32BIT.s b/libc/sysv/consts/ADDR_LIMIT_32BIT.s new file mode 100644 index 00000000..d1e7c997 --- /dev/null +++ b/libc/sysv/consts/ADDR_LIMIT_32BIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon prsnlty ADDR_LIMIT_32BIT 0x0800000 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ADDR_LIMIT_3GB.s b/libc/sysv/consts/ADDR_LIMIT_3GB.s new file mode 100644 index 00000000..8651ec7f --- /dev/null +++ b/libc/sysv/consts/ADDR_LIMIT_3GB.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon prsnlty ADDR_LIMIT_3GB 0x8000000 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ADDR_NO_RANDOMIZE.s b/libc/sysv/consts/ADDR_NO_RANDOMIZE.s new file mode 100644 index 00000000..6d3b3205 --- /dev/null +++ b/libc/sysv/consts/ADDR_NO_RANDOMIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon prsnlty ADDR_NO_RANDOMIZE 0x0040000 -1 -1 -1 -1 diff --git a/libc/sysv/consts/AFORK.s b/libc/sysv/consts/AFORK.s new file mode 100644 index 00000000..97760d8d --- /dev/null +++ b/libc/sysv/consts/AFORK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc AFORK 0 1 1 1 0 diff --git a/libc/sysv/consts/AF_ALG.s b/libc/sysv/consts/AF_ALG.s new file mode 100644 index 00000000..87bf398a --- /dev/null +++ b/libc/sysv/consts/AF_ALG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_ALG 38 0 0 0 0 diff --git a/libc/sysv/consts/AF_APPLETALK.s b/libc/sysv/consts/AF_APPLETALK.s new file mode 100644 index 00000000..8ed1b31b --- /dev/null +++ b/libc/sysv/consts/AF_APPLETALK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_APPLETALK 5 0x10 0x10 0x10 0x10 diff --git a/libc/sysv/consts/AF_ASH.s b/libc/sysv/consts/AF_ASH.s new file mode 100644 index 00000000..2b93ea36 --- /dev/null +++ b/libc/sysv/consts/AF_ASH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_ASH 18 0 0 0 0 diff --git a/libc/sysv/consts/AF_ATMPVC.s b/libc/sysv/consts/AF_ATMPVC.s new file mode 100644 index 00000000..64abb3b6 --- /dev/null +++ b/libc/sysv/consts/AF_ATMPVC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_ATMPVC 8 0 0 0 0 diff --git a/libc/sysv/consts/AF_ATMSVC.s b/libc/sysv/consts/AF_ATMSVC.s new file mode 100644 index 00000000..71f05df5 --- /dev/null +++ b/libc/sysv/consts/AF_ATMSVC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_ATMSVC 20 0 0 0 0 diff --git a/libc/sysv/consts/AF_AX25.s b/libc/sysv/consts/AF_AX25.s new file mode 100644 index 00000000..6bf9e542 --- /dev/null +++ b/libc/sysv/consts/AF_AX25.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_AX25 3 0 0 0 0 diff --git a/libc/sysv/consts/AF_BLUETOOTH.s b/libc/sysv/consts/AF_BLUETOOTH.s new file mode 100644 index 00000000..20c4a722 --- /dev/null +++ b/libc/sysv/consts/AF_BLUETOOTH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_BLUETOOTH 31 0 36 0x20 0 diff --git a/libc/sysv/consts/AF_BRIDGE.s b/libc/sysv/consts/AF_BRIDGE.s new file mode 100644 index 00000000..6769a52e --- /dev/null +++ b/libc/sysv/consts/AF_BRIDGE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_BRIDGE 7 0 0 0 0 diff --git a/libc/sysv/consts/AF_CAIF.s b/libc/sysv/consts/AF_CAIF.s new file mode 100644 index 00000000..f62a0bf4 --- /dev/null +++ b/libc/sysv/consts/AF_CAIF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_CAIF 37 0 0 0 0 diff --git a/libc/sysv/consts/AF_CAN.s b/libc/sysv/consts/AF_CAN.s new file mode 100644 index 00000000..b1552062 --- /dev/null +++ b/libc/sysv/consts/AF_CAN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_CAN 29 0 0 0 0 diff --git a/libc/sysv/consts/AF_ECONET.s b/libc/sysv/consts/AF_ECONET.s new file mode 100644 index 00000000..c73acc9d --- /dev/null +++ b/libc/sysv/consts/AF_ECONET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_ECONET 19 0 0 0 0 diff --git a/libc/sysv/consts/AF_FILE.s b/libc/sysv/consts/AF_FILE.s new file mode 100644 index 00000000..706ea265 --- /dev/null +++ b/libc/sysv/consts/AF_FILE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_FILE 1 0 0 0 0 diff --git a/libc/sysv/consts/AF_IB.s b/libc/sysv/consts/AF_IB.s new file mode 100644 index 00000000..79898aea --- /dev/null +++ b/libc/sysv/consts/AF_IB.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_IB 27 0 0 0 0 diff --git a/libc/sysv/consts/AF_IEEE802154.s b/libc/sysv/consts/AF_IEEE802154.s new file mode 100644 index 00000000..94884868 --- /dev/null +++ b/libc/sysv/consts/AF_IEEE802154.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_IEEE802154 36 0 0 0 0 diff --git a/libc/sysv/consts/AF_INET.s b/libc/sysv/consts/AF_INET.s new file mode 100644 index 00000000..2e73582b --- /dev/null +++ b/libc/sysv/consts/AF_INET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_INET 2 2 2 2 2 diff --git a/libc/sysv/consts/AF_INET6.s b/libc/sysv/consts/AF_INET6.s new file mode 100644 index 00000000..c1401398 --- /dev/null +++ b/libc/sysv/consts/AF_INET6.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_INET6 10 30 28 24 23 diff --git a/libc/sysv/consts/AF_IPX.s b/libc/sysv/consts/AF_IPX.s new file mode 100644 index 00000000..838a2564 --- /dev/null +++ b/libc/sysv/consts/AF_IPX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_IPX 4 23 23 23 0 diff --git a/libc/sysv/consts/AF_IRDA.s b/libc/sysv/consts/AF_IRDA.s new file mode 100644 index 00000000..e007407f --- /dev/null +++ b/libc/sysv/consts/AF_IRDA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_IRDA 23 0 0 0 0 diff --git a/libc/sysv/consts/AF_ISDN.s b/libc/sysv/consts/AF_ISDN.s new file mode 100644 index 00000000..ba6fd3d8 --- /dev/null +++ b/libc/sysv/consts/AF_ISDN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_ISDN 34 28 26 26 0 diff --git a/libc/sysv/consts/AF_IUCV.s b/libc/sysv/consts/AF_IUCV.s new file mode 100644 index 00000000..7cac3f74 --- /dev/null +++ b/libc/sysv/consts/AF_IUCV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_IUCV 0x20 0 0 0 0 diff --git a/libc/sysv/consts/AF_KCM.s b/libc/sysv/consts/AF_KCM.s new file mode 100644 index 00000000..634cb4ba --- /dev/null +++ b/libc/sysv/consts/AF_KCM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_KCM 41 0 0 0 0 diff --git a/libc/sysv/consts/AF_KEY.s b/libc/sysv/consts/AF_KEY.s new file mode 100644 index 00000000..1e586ca8 --- /dev/null +++ b/libc/sysv/consts/AF_KEY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_KEY 15 0 0 30 0 diff --git a/libc/sysv/consts/AF_LLC.s b/libc/sysv/consts/AF_LLC.s new file mode 100644 index 00000000..e7e58e25 --- /dev/null +++ b/libc/sysv/consts/AF_LLC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_LLC 26 0 0 0 0 diff --git a/libc/sysv/consts/AF_LOCAL.s b/libc/sysv/consts/AF_LOCAL.s new file mode 100644 index 00000000..8666b72f --- /dev/null +++ b/libc/sysv/consts/AF_LOCAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_LOCAL 1 1 1 1 0 diff --git a/libc/sysv/consts/AF_MAX.s b/libc/sysv/consts/AF_MAX.s new file mode 100644 index 00000000..44b45c52 --- /dev/null +++ b/libc/sysv/consts/AF_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_MAX 42 40 42 36 35 diff --git a/libc/sysv/consts/AF_MPLS.s b/libc/sysv/consts/AF_MPLS.s new file mode 100644 index 00000000..0bb81821 --- /dev/null +++ b/libc/sysv/consts/AF_MPLS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_MPLS 28 0 0 33 0 diff --git a/libc/sysv/consts/AF_NETBEUI.s b/libc/sysv/consts/AF_NETBEUI.s new file mode 100644 index 00000000..4771eaf4 --- /dev/null +++ b/libc/sysv/consts/AF_NETBEUI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_NETBEUI 13 0 0 0 0 diff --git a/libc/sysv/consts/AF_NETLINK.s b/libc/sysv/consts/AF_NETLINK.s new file mode 100644 index 00000000..c657a27a --- /dev/null +++ b/libc/sysv/consts/AF_NETLINK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_NETLINK 16 0 0 0 0 diff --git a/libc/sysv/consts/AF_NETROM.s b/libc/sysv/consts/AF_NETROM.s new file mode 100644 index 00000000..e6f5e508 --- /dev/null +++ b/libc/sysv/consts/AF_NETROM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_NETROM 6 0 0 0 0 diff --git a/libc/sysv/consts/AF_NFC.s b/libc/sysv/consts/AF_NFC.s new file mode 100644 index 00000000..9344dcd8 --- /dev/null +++ b/libc/sysv/consts/AF_NFC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_NFC 39 0 0 0 0 diff --git a/libc/sysv/consts/AF_PACKET.s b/libc/sysv/consts/AF_PACKET.s new file mode 100644 index 00000000..8812930f --- /dev/null +++ b/libc/sysv/consts/AF_PACKET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_PACKET 17 0 0 0 0 diff --git a/libc/sysv/consts/AF_PHONET.s b/libc/sysv/consts/AF_PHONET.s new file mode 100644 index 00000000..681c7911 --- /dev/null +++ b/libc/sysv/consts/AF_PHONET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_PHONET 35 0 0 0 0 diff --git a/libc/sysv/consts/AF_PPPOX.s b/libc/sysv/consts/AF_PPPOX.s new file mode 100644 index 00000000..15730351 --- /dev/null +++ b/libc/sysv/consts/AF_PPPOX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_PPPOX 24 0 0 0 0 diff --git a/libc/sysv/consts/AF_RDS.s b/libc/sysv/consts/AF_RDS.s new file mode 100644 index 00000000..24f2e1ba --- /dev/null +++ b/libc/sysv/consts/AF_RDS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_RDS 21 0 0 0 0 diff --git a/libc/sysv/consts/AF_ROSE.s b/libc/sysv/consts/AF_ROSE.s new file mode 100644 index 00000000..a8142e4a --- /dev/null +++ b/libc/sysv/consts/AF_ROSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_ROSE 11 0 0 0 0 diff --git a/libc/sysv/consts/AF_ROUTE.s b/libc/sysv/consts/AF_ROUTE.s new file mode 100644 index 00000000..71e38688 --- /dev/null +++ b/libc/sysv/consts/AF_ROUTE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_ROUTE 16 17 17 17 0 diff --git a/libc/sysv/consts/AF_RXRPC.s b/libc/sysv/consts/AF_RXRPC.s new file mode 100644 index 00000000..29c7e72d --- /dev/null +++ b/libc/sysv/consts/AF_RXRPC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_RXRPC 33 0 0 0 0 diff --git a/libc/sysv/consts/AF_SECURITY.s b/libc/sysv/consts/AF_SECURITY.s new file mode 100644 index 00000000..675b0720 --- /dev/null +++ b/libc/sysv/consts/AF_SECURITY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_SECURITY 14 0 0 0 0 diff --git a/libc/sysv/consts/AF_SNA.s b/libc/sysv/consts/AF_SNA.s new file mode 100644 index 00000000..da645073 --- /dev/null +++ b/libc/sysv/consts/AF_SNA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_SNA 22 11 11 11 11 diff --git a/libc/sysv/consts/AF_TIPC.s b/libc/sysv/consts/AF_TIPC.s new file mode 100644 index 00000000..edf96f1e --- /dev/null +++ b/libc/sysv/consts/AF_TIPC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_TIPC 30 0 0 0 0 diff --git a/libc/sysv/consts/AF_UNIX.s b/libc/sysv/consts/AF_UNIX.s new file mode 100644 index 00000000..b385a055 --- /dev/null +++ b/libc/sysv/consts/AF_UNIX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_UNIX 1 1 1 1 1 diff --git a/libc/sysv/consts/AF_UNSPEC.s b/libc/sysv/consts/AF_UNSPEC.s new file mode 100644 index 00000000..00325cbb --- /dev/null +++ b/libc/sysv/consts/AF_UNSPEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_UNSPEC 0 0 0 0 0 diff --git a/libc/sysv/consts/AF_VSOCK.s b/libc/sysv/consts/AF_VSOCK.s new file mode 100644 index 00000000..b36451d9 --- /dev/null +++ b/libc/sysv/consts/AF_VSOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_VSOCK 40 0 0 0 0 diff --git a/libc/sysv/consts/AF_WANPIPE.s b/libc/sysv/consts/AF_WANPIPE.s new file mode 100644 index 00000000..17d18ec5 --- /dev/null +++ b/libc/sysv/consts/AF_WANPIPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_WANPIPE 25 0 0 0 0 diff --git a/libc/sysv/consts/AF_X25.s b/libc/sysv/consts/AF_X25.s new file mode 100644 index 00000000..0c9bac7d --- /dev/null +++ b/libc/sysv/consts/AF_X25.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon af AF_X25 9 0 0 0 0 diff --git a/libc/sysv/consts/AHZ.s b/libc/sysv/consts/AHZ.s new file mode 100644 index 00000000..df56d62b --- /dev/null +++ b/libc/sysv/consts/AHZ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc AHZ 100 0x40 0 0x40 0 diff --git a/libc/sysv/consts/AIO_ALLDONE.s b/libc/sysv/consts/AIO_ALLDONE.s new file mode 100644 index 00000000..16a9dc85 --- /dev/null +++ b/libc/sysv/consts/AIO_ALLDONE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc AIO_ALLDONE 2 1 3 0 0 diff --git a/libc/sysv/consts/AIO_CANCELED.s b/libc/sysv/consts/AIO_CANCELED.s new file mode 100644 index 00000000..ae55d286 --- /dev/null +++ b/libc/sysv/consts/AIO_CANCELED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc AIO_CANCELED 0 2 1 0 0 diff --git a/libc/sysv/consts/AIO_NOTCANCELED.s b/libc/sysv/consts/AIO_NOTCANCELED.s new file mode 100644 index 00000000..29436e47 --- /dev/null +++ b/libc/sysv/consts/AIO_NOTCANCELED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc AIO_NOTCANCELED 1 4 2 0 0 diff --git a/libc/sysv/consts/AI_ADDRCONFIG.s b/libc/sysv/consts/AI_ADDRCONFIG.s new file mode 100644 index 00000000..a22e4f21 --- /dev/null +++ b/libc/sysv/consts/AI_ADDRCONFIG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon gai AI_ADDRCONFIG 0x20 0x0400 0x0400 0x40 0x0400 diff --git a/libc/sysv/consts/AI_ALL.s b/libc/sysv/consts/AI_ALL.s new file mode 100644 index 00000000..0914579f --- /dev/null +++ b/libc/sysv/consts/AI_ALL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon gai AI_ALL 0x10 0x0100 0x0100 0 0x0100 diff --git a/libc/sysv/consts/AI_CANONNAME.s b/libc/sysv/consts/AI_CANONNAME.s new file mode 100644 index 00000000..2b8fbdf4 --- /dev/null +++ b/libc/sysv/consts/AI_CANONNAME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon gai AI_CANONNAME 2 2 2 2 2 diff --git a/libc/sysv/consts/AI_NUMERICHOST.s b/libc/sysv/consts/AI_NUMERICHOST.s new file mode 100644 index 00000000..20b9a933 --- /dev/null +++ b/libc/sysv/consts/AI_NUMERICHOST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon gai AI_NUMERICHOST 4 4 4 4 4 diff --git a/libc/sysv/consts/AI_NUMERICSERV.s b/libc/sysv/consts/AI_NUMERICSERV.s new file mode 100644 index 00000000..d000edea --- /dev/null +++ b/libc/sysv/consts/AI_NUMERICSERV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon gai AI_NUMERICSERV 0x0400 0x1000 8 0x10 8 diff --git a/libc/sysv/consts/AI_PASSIVE.s b/libc/sysv/consts/AI_PASSIVE.s new file mode 100644 index 00000000..fabf5552 --- /dev/null +++ b/libc/sysv/consts/AI_PASSIVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon gai AI_PASSIVE 1 1 1 1 1 diff --git a/libc/sysv/consts/AI_V4MAPPED.s b/libc/sysv/consts/AI_V4MAPPED.s new file mode 100644 index 00000000..d012f7ed --- /dev/null +++ b/libc/sysv/consts/AI_V4MAPPED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon gai AI_V4MAPPED 8 0x0800 0x0800 0 0x0800 diff --git a/libc/sysv/consts/ALLOW_MEDIUM_REMOVAL.s b/libc/sysv/consts/ALLOW_MEDIUM_REMOVAL.s new file mode 100644 index 00000000..37c3f5e4 --- /dev/null +++ b/libc/sysv/consts/ALLOW_MEDIUM_REMOVAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ALLOW_MEDIUM_REMOVAL 30 0 0 0 0 diff --git a/libc/sysv/consts/ALT_DIGITS.s b/libc/sysv/consts/ALT_DIGITS.s new file mode 100644 index 00000000..81b2c008 --- /dev/null +++ b/libc/sysv/consts/ALT_DIGITS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ALT_DIGITS 0x02002f 49 49 0 0 diff --git a/libc/sysv/consts/AM_STR.s b/libc/sysv/consts/AM_STR.s new file mode 100644 index 00000000..73d763d8 --- /dev/null +++ b/libc/sysv/consts/AM_STR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc AM_STR 0x020026 5 5 4 0 diff --git a/libc/sysv/consts/AREGTYPE.s b/libc/sysv/consts/AREGTYPE.s new file mode 100644 index 00000000..080e8ae5 --- /dev/null +++ b/libc/sysv/consts/AREGTYPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc AREGTYPE 0 0 0 0 0 diff --git a/libc/sysv/consts/ARPHRD_ETHER.s b/libc/sysv/consts/ARPHRD_ETHER.s new file mode 100644 index 00000000..a877799b --- /dev/null +++ b/libc/sysv/consts/ARPHRD_ETHER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ARPHRD_ETHER 1 1 1 1 0 diff --git a/libc/sysv/consts/ARPHRD_FCFABRIC.s b/libc/sysv/consts/ARPHRD_FCFABRIC.s new file mode 100644 index 00000000..8347a1fe --- /dev/null +++ b/libc/sysv/consts/ARPHRD_FCFABRIC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ARPHRD_FCFABRIC 787 0 0 0 0 diff --git a/libc/sysv/consts/ARPHRD_IEEE80211.s b/libc/sysv/consts/ARPHRD_IEEE80211.s new file mode 100644 index 00000000..aade2837 --- /dev/null +++ b/libc/sysv/consts/ARPHRD_IEEE80211.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ARPHRD_IEEE80211 801 0 0 0 0 diff --git a/libc/sysv/consts/ARPHRD_IEEE80211_PRISM.s b/libc/sysv/consts/ARPHRD_IEEE80211_PRISM.s new file mode 100644 index 00000000..e85fbe15 --- /dev/null +++ b/libc/sysv/consts/ARPHRD_IEEE80211_PRISM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ARPHRD_IEEE80211_PRISM 802 0 0 0 0 diff --git a/libc/sysv/consts/ARPHRD_IEEE80211_RADIOTAP.s b/libc/sysv/consts/ARPHRD_IEEE80211_RADIOTAP.s new file mode 100644 index 00000000..c3961d46 --- /dev/null +++ b/libc/sysv/consts/ARPHRD_IEEE80211_RADIOTAP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ARPHRD_IEEE80211_RADIOTAP 803 0 0 0 0 diff --git a/libc/sysv/consts/ARPHRD_IEEE802154.s b/libc/sysv/consts/ARPHRD_IEEE802154.s new file mode 100644 index 00000000..c50e3754 --- /dev/null +++ b/libc/sysv/consts/ARPHRD_IEEE802154.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ARPHRD_IEEE802154 804 0 0 0 0 diff --git a/libc/sysv/consts/ARPHRD_IEEE802_TR.s b/libc/sysv/consts/ARPHRD_IEEE802_TR.s new file mode 100644 index 00000000..70c940d5 --- /dev/null +++ b/libc/sysv/consts/ARPHRD_IEEE802_TR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ARPHRD_IEEE802_TR 800 0 0 0 0 diff --git a/libc/sysv/consts/ARPHRD_LOCALTLK.s b/libc/sysv/consts/ARPHRD_LOCALTLK.s new file mode 100644 index 00000000..76ee0e04 --- /dev/null +++ b/libc/sysv/consts/ARPHRD_LOCALTLK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ARPHRD_LOCALTLK 773 0 0 0 0 diff --git a/libc/sysv/consts/ASU.s b/libc/sysv/consts/ASU.s new file mode 100644 index 00000000..be66314a --- /dev/null +++ b/libc/sysv/consts/ASU.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ASU 0 2 2 2 0 diff --git a/libc/sysv/consts/ATF_NETMASK.s b/libc/sysv/consts/ATF_NETMASK.s new file mode 100644 index 00000000..46c1c513 --- /dev/null +++ b/libc/sysv/consts/ATF_NETMASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ATF_NETMASK 0x20 0 0 0 0 diff --git a/libc/sysv/consts/AT_BASE.s b/libc/sysv/consts/AT_BASE.s new file mode 100644 index 00000000..f9c374bb --- /dev/null +++ b/libc/sysv/consts/AT_BASE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_BASE 7 0 7 0 0 diff --git a/libc/sysv/consts/AT_BASE_PLATFORM.s b/libc/sysv/consts/AT_BASE_PLATFORM.s new file mode 100644 index 00000000..e8253228 --- /dev/null +++ b/libc/sysv/consts/AT_BASE_PLATFORM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_BASE_PLATFORM 24 0 0 0 0 diff --git a/libc/sysv/consts/AT_CLKTCK.s b/libc/sysv/consts/AT_CLKTCK.s new file mode 100644 index 00000000..45cbad31 --- /dev/null +++ b/libc/sysv/consts/AT_CLKTCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_CLKTCK 17 0 0 0 0 diff --git a/libc/sysv/consts/AT_DCACHEBSIZE.s b/libc/sysv/consts/AT_DCACHEBSIZE.s new file mode 100644 index 00000000..e0685a62 --- /dev/null +++ b/libc/sysv/consts/AT_DCACHEBSIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_DCACHEBSIZE 19 0 0 0 0 diff --git a/libc/sysv/consts/AT_EACCESS.s b/libc/sysv/consts/AT_EACCESS.s new file mode 100644 index 00000000..89bb0eaa --- /dev/null +++ b/libc/sysv/consts/AT_EACCESS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon at AT_EACCESS 0x0200 0x10 0x0100 1 0 diff --git a/libc/sysv/consts/AT_EGID.s b/libc/sysv/consts/AT_EGID.s new file mode 100644 index 00000000..2439acb0 --- /dev/null +++ b/libc/sysv/consts/AT_EGID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_EGID 14 0 0 0 0 diff --git a/libc/sysv/consts/AT_EMPTY_PATH.s b/libc/sysv/consts/AT_EMPTY_PATH.s new file mode 100644 index 00000000..3c02ce46 --- /dev/null +++ b/libc/sysv/consts/AT_EMPTY_PATH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon at AT_EMPTY_PATH 0x1000 0 0 0 0 diff --git a/libc/sysv/consts/AT_ENTRY.s b/libc/sysv/consts/AT_ENTRY.s new file mode 100644 index 00000000..cfa148c3 --- /dev/null +++ b/libc/sysv/consts/AT_ENTRY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_ENTRY 9 0 9 0 0 diff --git a/libc/sysv/consts/AT_EUID.s b/libc/sysv/consts/AT_EUID.s new file mode 100644 index 00000000..241b2548 --- /dev/null +++ b/libc/sysv/consts/AT_EUID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_EUID 12 0 0 0 0 diff --git a/libc/sysv/consts/AT_EXECFD.s b/libc/sysv/consts/AT_EXECFD.s new file mode 100644 index 00000000..b34c7175 --- /dev/null +++ b/libc/sysv/consts/AT_EXECFD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_EXECFD 2 0 2 0 0 diff --git a/libc/sysv/consts/AT_EXECFN.s b/libc/sysv/consts/AT_EXECFN.s new file mode 100644 index 00000000..621655d9 --- /dev/null +++ b/libc/sysv/consts/AT_EXECFN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_EXECFN 31 999 999 999 999 diff --git a/libc/sysv/consts/AT_FDCWD.s b/libc/sysv/consts/AT_FDCWD.s new file mode 100644 index 00000000..7e91d76b --- /dev/null +++ b/libc/sysv/consts/AT_FDCWD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon at AT_FDCWD -100 -2 -100 -100 -100 diff --git a/libc/sysv/consts/AT_GID.s b/libc/sysv/consts/AT_GID.s new file mode 100644 index 00000000..4ef1e191 --- /dev/null +++ b/libc/sysv/consts/AT_GID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_GID 13 0 0 0 0 diff --git a/libc/sysv/consts/AT_ICACHEBSIZE.s b/libc/sysv/consts/AT_ICACHEBSIZE.s new file mode 100644 index 00000000..4ef616ae --- /dev/null +++ b/libc/sysv/consts/AT_ICACHEBSIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_ICACHEBSIZE 20 0 0 0 0 diff --git a/libc/sysv/consts/AT_NOTELF.s b/libc/sysv/consts/AT_NOTELF.s new file mode 100644 index 00000000..35094a7d --- /dev/null +++ b/libc/sysv/consts/AT_NOTELF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_NOTELF 10 0 10 0 0 diff --git a/libc/sysv/consts/AT_NO_AUTOMOUNT.s b/libc/sysv/consts/AT_NO_AUTOMOUNT.s new file mode 100644 index 00000000..427e7b39 --- /dev/null +++ b/libc/sysv/consts/AT_NO_AUTOMOUNT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_NO_AUTOMOUNT 0x0800 0 0 0 0 diff --git a/libc/sysv/consts/AT_OSRELDATE.s b/libc/sysv/consts/AT_OSRELDATE.s new file mode 100644 index 00000000..91eb8548 --- /dev/null +++ b/libc/sysv/consts/AT_OSRELDATE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_OSRELDATE 0 0 18 0 0 diff --git a/libc/sysv/consts/AT_PAGESZ.s b/libc/sysv/consts/AT_PAGESZ.s new file mode 100644 index 00000000..e390da14 --- /dev/null +++ b/libc/sysv/consts/AT_PAGESZ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_PAGESZ 6 0 6 0 0 diff --git a/libc/sysv/consts/AT_PHDR.s b/libc/sysv/consts/AT_PHDR.s new file mode 100644 index 00000000..5bc69a91 --- /dev/null +++ b/libc/sysv/consts/AT_PHDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_PHDR 3 0 3 0 0 diff --git a/libc/sysv/consts/AT_PHENT.s b/libc/sysv/consts/AT_PHENT.s new file mode 100644 index 00000000..202b5a99 --- /dev/null +++ b/libc/sysv/consts/AT_PHENT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_PHENT 4 0 4 0 0 diff --git a/libc/sysv/consts/AT_PHNUM.s b/libc/sysv/consts/AT_PHNUM.s new file mode 100644 index 00000000..97b4b668 --- /dev/null +++ b/libc/sysv/consts/AT_PHNUM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_PHNUM 5 0 5 0 0 diff --git a/libc/sysv/consts/AT_PLATFORM.s b/libc/sysv/consts/AT_PLATFORM.s new file mode 100644 index 00000000..20a93b53 --- /dev/null +++ b/libc/sysv/consts/AT_PLATFORM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_PLATFORM 15 0 0 0 0 diff --git a/libc/sysv/consts/AT_RANDOM.s b/libc/sysv/consts/AT_RANDOM.s new file mode 100644 index 00000000..f5ccb86b --- /dev/null +++ b/libc/sysv/consts/AT_RANDOM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_RANDOM 25 0 0 0 0 diff --git a/libc/sysv/consts/AT_REMOVEDIR.s b/libc/sysv/consts/AT_REMOVEDIR.s new file mode 100644 index 00000000..e650fe71 --- /dev/null +++ b/libc/sysv/consts/AT_REMOVEDIR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon at AT_REMOVEDIR 0x0200 0x80 0x0800 8 0x0200 diff --git a/libc/sysv/consts/AT_SECURE.s b/libc/sysv/consts/AT_SECURE.s new file mode 100644 index 00000000..f47fe493 --- /dev/null +++ b/libc/sysv/consts/AT_SECURE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_SECURE 23 0 0 0 0 diff --git a/libc/sysv/consts/AT_SYMLINK_FOLLOW.s b/libc/sysv/consts/AT_SYMLINK_FOLLOW.s new file mode 100644 index 00000000..8c74bbdd --- /dev/null +++ b/libc/sysv/consts/AT_SYMLINK_FOLLOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon at AT_SYMLINK_FOLLOW 0x0400 0x40 0x0400 4 0 diff --git a/libc/sysv/consts/AT_SYMLINK_NOFOLLOW.s b/libc/sysv/consts/AT_SYMLINK_NOFOLLOW.s new file mode 100644 index 00000000..fc8d86a8 --- /dev/null +++ b/libc/sysv/consts/AT_SYMLINK_NOFOLLOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon at AT_SYMLINK_NOFOLLOW 0x0100 0x20 0x0200 2 0 diff --git a/libc/sysv/consts/AT_SYSINFO_EHDR.s b/libc/sysv/consts/AT_SYSINFO_EHDR.s new file mode 100644 index 00000000..0bcc5f10 --- /dev/null +++ b/libc/sysv/consts/AT_SYSINFO_EHDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_SYSINFO_EHDR 33 0 0 0 0 diff --git a/libc/sysv/consts/AT_UCACHEBSIZE.s b/libc/sysv/consts/AT_UCACHEBSIZE.s new file mode 100644 index 00000000..15f86562 --- /dev/null +++ b/libc/sysv/consts/AT_UCACHEBSIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_UCACHEBSIZE 21 0 0 0 0 diff --git a/libc/sysv/consts/AT_UID.s b/libc/sysv/consts/AT_UID.s new file mode 100644 index 00000000..ddc2ef63 --- /dev/null +++ b/libc/sysv/consts/AT_UID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon auxv AT_UID 11 0 0 0 0 diff --git a/libc/sysv/consts/AXSIG.s b/libc/sysv/consts/AXSIG.s new file mode 100644 index 00000000..f38320f0 --- /dev/null +++ b/libc/sysv/consts/AXSIG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc AXSIG 0 0x10 0x10 0x10 0 diff --git a/libc/sysv/consts/B0.s b/libc/sysv/consts/B0.s new file mode 100644 index 00000000..bb97f639 --- /dev/null +++ b/libc/sysv/consts/B0.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B0 0 0 0 0 0 diff --git a/libc/sysv/consts/B1000000.s b/libc/sysv/consts/B1000000.s new file mode 100644 index 00000000..c6be45e5 --- /dev/null +++ b/libc/sysv/consts/B1000000.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B1000000 0x1008 0 0 0 0 diff --git a/libc/sysv/consts/B110.s b/libc/sysv/consts/B110.s new file mode 100644 index 00000000..c1375074 --- /dev/null +++ b/libc/sysv/consts/B110.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B110 3 110 110 110 0 diff --git a/libc/sysv/consts/B115200.s b/libc/sysv/consts/B115200.s new file mode 100644 index 00000000..9bd3f557 --- /dev/null +++ b/libc/sysv/consts/B115200.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B115200 0x1002 0x01c200 0x01c200 0x01c200 0 diff --git a/libc/sysv/consts/B1152000.s b/libc/sysv/consts/B1152000.s new file mode 100644 index 00000000..08e24bde --- /dev/null +++ b/libc/sysv/consts/B1152000.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B1152000 0x1009 0 0 0 0 diff --git a/libc/sysv/consts/B1200.s b/libc/sysv/consts/B1200.s new file mode 100644 index 00000000..8ce8b0c1 --- /dev/null +++ b/libc/sysv/consts/B1200.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B1200 9 0x04b0 0x04b0 0x04b0 0 diff --git a/libc/sysv/consts/B134.s b/libc/sysv/consts/B134.s new file mode 100644 index 00000000..0befb0f1 --- /dev/null +++ b/libc/sysv/consts/B134.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B134 4 134 134 134 0 diff --git a/libc/sysv/consts/B150.s b/libc/sysv/consts/B150.s new file mode 100644 index 00000000..a631da94 --- /dev/null +++ b/libc/sysv/consts/B150.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B150 5 150 150 150 0 diff --git a/libc/sysv/consts/B1500000.s b/libc/sysv/consts/B1500000.s new file mode 100644 index 00000000..58dd05ec --- /dev/null +++ b/libc/sysv/consts/B1500000.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B1500000 0x100a 0 0 0 0 diff --git a/libc/sysv/consts/B1800.s b/libc/sysv/consts/B1800.s new file mode 100644 index 00000000..43455ad9 --- /dev/null +++ b/libc/sysv/consts/B1800.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B1800 10 0x0708 0x0708 0x0708 0 diff --git a/libc/sysv/consts/B19200.s b/libc/sysv/consts/B19200.s new file mode 100644 index 00000000..5af921d7 --- /dev/null +++ b/libc/sysv/consts/B19200.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B19200 14 0x4b00 0x4b00 0x4b00 0 diff --git a/libc/sysv/consts/B200.s b/libc/sysv/consts/B200.s new file mode 100644 index 00000000..1559cf5a --- /dev/null +++ b/libc/sysv/consts/B200.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B200 6 200 200 200 0 diff --git a/libc/sysv/consts/B2000000.s b/libc/sysv/consts/B2000000.s new file mode 100644 index 00000000..4d155dec --- /dev/null +++ b/libc/sysv/consts/B2000000.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B2000000 0x100b 0 0 0 0 diff --git a/libc/sysv/consts/B230400.s b/libc/sysv/consts/B230400.s new file mode 100644 index 00000000..d13fec88 --- /dev/null +++ b/libc/sysv/consts/B230400.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B230400 0x1003 0x038400 0x038400 0x038400 0 diff --git a/libc/sysv/consts/B2400.s b/libc/sysv/consts/B2400.s new file mode 100644 index 00000000..d2909787 --- /dev/null +++ b/libc/sysv/consts/B2400.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B2400 11 0x0960 0x0960 0x0960 0 diff --git a/libc/sysv/consts/B2500000.s b/libc/sysv/consts/B2500000.s new file mode 100644 index 00000000..b990dab0 --- /dev/null +++ b/libc/sysv/consts/B2500000.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B2500000 0x100c 0 0 0 0 diff --git a/libc/sysv/consts/B300.s b/libc/sysv/consts/B300.s new file mode 100644 index 00000000..1ca19f67 --- /dev/null +++ b/libc/sysv/consts/B300.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B300 7 300 300 300 0 diff --git a/libc/sysv/consts/B3000000.s b/libc/sysv/consts/B3000000.s new file mode 100644 index 00000000..bd04c99e --- /dev/null +++ b/libc/sysv/consts/B3000000.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B3000000 0x100d 0 0 0 0 diff --git a/libc/sysv/consts/B3500000.s b/libc/sysv/consts/B3500000.s new file mode 100644 index 00000000..3b66747c --- /dev/null +++ b/libc/sysv/consts/B3500000.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B3500000 0x100e 0 0 0 0 diff --git a/libc/sysv/consts/B38400.s b/libc/sysv/consts/B38400.s new file mode 100644 index 00000000..70ba6de2 --- /dev/null +++ b/libc/sysv/consts/B38400.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B38400 15 0x9600 0x9600 0x9600 0 diff --git a/libc/sysv/consts/B4000000.s b/libc/sysv/consts/B4000000.s new file mode 100644 index 00000000..eaaba1e4 --- /dev/null +++ b/libc/sysv/consts/B4000000.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B4000000 0x100f 0 0 0 0 diff --git a/libc/sysv/consts/B460800.s b/libc/sysv/consts/B460800.s new file mode 100644 index 00000000..cbb5ba75 --- /dev/null +++ b/libc/sysv/consts/B460800.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B460800 0x1004 0 0x070800 0 0 diff --git a/libc/sysv/consts/B4800.s b/libc/sysv/consts/B4800.s new file mode 100644 index 00000000..cb7632af --- /dev/null +++ b/libc/sysv/consts/B4800.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B4800 12 0x12c0 0x12c0 0x12c0 0 diff --git a/libc/sysv/consts/B50.s b/libc/sysv/consts/B50.s new file mode 100644 index 00000000..423dd2ec --- /dev/null +++ b/libc/sysv/consts/B50.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B50 1 50 50 50 0 diff --git a/libc/sysv/consts/B500000.s b/libc/sysv/consts/B500000.s new file mode 100644 index 00000000..dce4276c --- /dev/null +++ b/libc/sysv/consts/B500000.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B500000 0x1005 0 0 0 0 diff --git a/libc/sysv/consts/B57600.s b/libc/sysv/consts/B57600.s new file mode 100644 index 00000000..cbe138a1 --- /dev/null +++ b/libc/sysv/consts/B57600.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B57600 0x1001 0xe100 0xe100 0xe100 0 diff --git a/libc/sysv/consts/B576000.s b/libc/sysv/consts/B576000.s new file mode 100644 index 00000000..fe3c0c7c --- /dev/null +++ b/libc/sysv/consts/B576000.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B576000 0x1006 0 0 0 0 diff --git a/libc/sysv/consts/B600.s b/libc/sysv/consts/B600.s new file mode 100644 index 00000000..91263c49 --- /dev/null +++ b/libc/sysv/consts/B600.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B600 8 600 600 600 0 diff --git a/libc/sysv/consts/B75.s b/libc/sysv/consts/B75.s new file mode 100644 index 00000000..84bd3746 --- /dev/null +++ b/libc/sysv/consts/B75.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B75 2 75 75 75 0 diff --git a/libc/sysv/consts/B921600.s b/libc/sysv/consts/B921600.s new file mode 100644 index 00000000..e51e887d --- /dev/null +++ b/libc/sysv/consts/B921600.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B921600 0x1007 0 0x0e1000 0 0 diff --git a/libc/sysv/consts/B9600.s b/libc/sysv/consts/B9600.s new file mode 100644 index 00000000..7e283b0b --- /dev/null +++ b/libc/sysv/consts/B9600.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc B9600 13 0x2580 0x2580 0x2580 0 diff --git a/libc/sysv/consts/BC_BASE_MAX.s b/libc/sysv/consts/BC_BASE_MAX.s new file mode 100644 index 00000000..8570f77b --- /dev/null +++ b/libc/sysv/consts/BC_BASE_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BC_BASE_MAX 99 99 99 0x7fffffff 0 diff --git a/libc/sysv/consts/BC_DIM_MAX.s b/libc/sysv/consts/BC_DIM_MAX.s new file mode 100644 index 00000000..43058744 --- /dev/null +++ b/libc/sysv/consts/BC_DIM_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BC_DIM_MAX 0x0800 0x0800 0x0800 0xffff 0 diff --git a/libc/sysv/consts/BC_SCALE_MAX.s b/libc/sysv/consts/BC_SCALE_MAX.s new file mode 100644 index 00000000..7d6de753 --- /dev/null +++ b/libc/sysv/consts/BC_SCALE_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BC_SCALE_MAX 99 99 99 0x7fffffff 0 diff --git a/libc/sysv/consts/BC_STRING_MAX.s b/libc/sysv/consts/BC_STRING_MAX.s new file mode 100644 index 00000000..e61e50b0 --- /dev/null +++ b/libc/sysv/consts/BC_STRING_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BC_STRING_MAX 0x03e8 0x03e8 0x03e8 0x7fffffff 0 diff --git a/libc/sysv/consts/BIG_ENDIAN.s b/libc/sysv/consts/BIG_ENDIAN.s new file mode 100644 index 00000000..a6ff0b83 --- /dev/null +++ b/libc/sysv/consts/BIG_ENDIAN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BIG_ENDIAN 0x10e1 0x10e1 0x10e1 0x10e1 0 diff --git a/libc/sysv/consts/BITSPERBYTE.s b/libc/sysv/consts/BITSPERBYTE.s new file mode 100644 index 00000000..b64e8d41 --- /dev/null +++ b/libc/sysv/consts/BITSPERBYTE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BITSPERBYTE 8 0 0 0 0 diff --git a/libc/sysv/consts/BLANK_CHECK.s b/libc/sysv/consts/BLANK_CHECK.s new file mode 100644 index 00000000..34d36e53 --- /dev/null +++ b/libc/sysv/consts/BLANK_CHECK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLANK_CHECK 8 0 0 0 0 diff --git a/libc/sysv/consts/BLKBSZGET.s b/libc/sysv/consts/BLKBSZGET.s new file mode 100644 index 00000000..8e863456 --- /dev/null +++ b/libc/sysv/consts/BLKBSZGET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLKBSZGET 0x80081270 0 0 0 0 diff --git a/libc/sysv/consts/BLKBSZSET.s b/libc/sysv/consts/BLKBSZSET.s new file mode 100644 index 00000000..8d425117 --- /dev/null +++ b/libc/sysv/consts/BLKBSZSET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLKBSZSET 0x40081271 0 0 0 0 diff --git a/libc/sysv/consts/BLKFLSBUF.s b/libc/sysv/consts/BLKFLSBUF.s new file mode 100644 index 00000000..6e0673ed --- /dev/null +++ b/libc/sysv/consts/BLKFLSBUF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLKFLSBUF 0x1261 0 0 0 0 diff --git a/libc/sysv/consts/BLKFRAGET.s b/libc/sysv/consts/BLKFRAGET.s new file mode 100644 index 00000000..bfc3317f --- /dev/null +++ b/libc/sysv/consts/BLKFRAGET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLKFRAGET 0x1265 0 0 0 0 diff --git a/libc/sysv/consts/BLKFRASET.s b/libc/sysv/consts/BLKFRASET.s new file mode 100644 index 00000000..40d6e7c4 --- /dev/null +++ b/libc/sysv/consts/BLKFRASET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLKFRASET 0x1264 0 0 0 0 diff --git a/libc/sysv/consts/BLKGETSIZE.s b/libc/sysv/consts/BLKGETSIZE.s new file mode 100644 index 00000000..10736636 --- /dev/null +++ b/libc/sysv/consts/BLKGETSIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLKGETSIZE 0x1260 0 0 0 0 diff --git a/libc/sysv/consts/BLKGETSIZE64.s b/libc/sysv/consts/BLKGETSIZE64.s new file mode 100644 index 00000000..626fb0f1 --- /dev/null +++ b/libc/sysv/consts/BLKGETSIZE64.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLKGETSIZE64 0x80081272 0 0 0 0 diff --git a/libc/sysv/consts/BLKRAGET.s b/libc/sysv/consts/BLKRAGET.s new file mode 100644 index 00000000..140da54f --- /dev/null +++ b/libc/sysv/consts/BLKRAGET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLKRAGET 0x1263 0 0 0 0 diff --git a/libc/sysv/consts/BLKRASET.s b/libc/sysv/consts/BLKRASET.s new file mode 100644 index 00000000..3c2b2ab4 --- /dev/null +++ b/libc/sysv/consts/BLKRASET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLKRASET 0x1262 0 0 0 0 diff --git a/libc/sysv/consts/BLKROGET.s b/libc/sysv/consts/BLKROGET.s new file mode 100644 index 00000000..0152fafa --- /dev/null +++ b/libc/sysv/consts/BLKROGET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLKROGET 0x125e 0 0 0 0 diff --git a/libc/sysv/consts/BLKROSET.s b/libc/sysv/consts/BLKROSET.s new file mode 100644 index 00000000..db946df0 --- /dev/null +++ b/libc/sysv/consts/BLKROSET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLKROSET 0x125d 0 0 0 0 diff --git a/libc/sysv/consts/BLKRRPART.s b/libc/sysv/consts/BLKRRPART.s new file mode 100644 index 00000000..6fc03934 --- /dev/null +++ b/libc/sysv/consts/BLKRRPART.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLKRRPART 0x125f 0 0 0 0 diff --git a/libc/sysv/consts/BLKSECTGET.s b/libc/sysv/consts/BLKSECTGET.s new file mode 100644 index 00000000..9b77f201 --- /dev/null +++ b/libc/sysv/consts/BLKSECTGET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLKSECTGET 0x1267 0 0 0 0 diff --git a/libc/sysv/consts/BLKSECTSET.s b/libc/sysv/consts/BLKSECTSET.s new file mode 100644 index 00000000..dc61a38f --- /dev/null +++ b/libc/sysv/consts/BLKSECTSET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLKSECTSET 0x1266 0 0 0 0 diff --git a/libc/sysv/consts/BLKSSZGET.s b/libc/sysv/consts/BLKSSZGET.s new file mode 100644 index 00000000..6ba5dbe4 --- /dev/null +++ b/libc/sysv/consts/BLKSSZGET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLKSSZGET 0x1268 0 0 0 0 diff --git a/libc/sysv/consts/BLKTYPE.s b/libc/sysv/consts/BLKTYPE.s new file mode 100644 index 00000000..af689210 --- /dev/null +++ b/libc/sysv/consts/BLKTYPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLKTYPE 52 52 52 52 0 diff --git a/libc/sysv/consts/BLK_BYTECOUNT.s b/libc/sysv/consts/BLK_BYTECOUNT.s new file mode 100644 index 00000000..5ee91268 --- /dev/null +++ b/libc/sysv/consts/BLK_BYTECOUNT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLK_BYTECOUNT 2 2 2 2 0 diff --git a/libc/sysv/consts/BLK_EOF.s b/libc/sysv/consts/BLK_EOF.s new file mode 100644 index 00000000..cc3e0f12 --- /dev/null +++ b/libc/sysv/consts/BLK_EOF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLK_EOF 0x40 0x40 0x40 0x40 0 diff --git a/libc/sysv/consts/BLK_EOR.s b/libc/sysv/consts/BLK_EOR.s new file mode 100644 index 00000000..e6b56dec --- /dev/null +++ b/libc/sysv/consts/BLK_EOR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLK_EOR 0x80 0x80 0x80 0x80 0 diff --git a/libc/sysv/consts/BLK_ERRORS.s b/libc/sysv/consts/BLK_ERRORS.s new file mode 100644 index 00000000..14faef7d --- /dev/null +++ b/libc/sysv/consts/BLK_ERRORS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLK_ERRORS 0x20 0x20 0x20 0x20 0 diff --git a/libc/sysv/consts/BLK_RESTART.s b/libc/sysv/consts/BLK_RESTART.s new file mode 100644 index 00000000..dab583bc --- /dev/null +++ b/libc/sysv/consts/BLK_RESTART.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BLK_RESTART 0x10 0x10 0x10 0x10 0 diff --git a/libc/sysv/consts/BOOT_TIME.s b/libc/sysv/consts/BOOT_TIME.s new file mode 100644 index 00000000..d9856653 --- /dev/null +++ b/libc/sysv/consts/BOOT_TIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BOOT_TIME 2 2 1 0 0 diff --git a/libc/sysv/consts/BRKINT.s b/libc/sysv/consts/BRKINT.s new file mode 100644 index 00000000..843a9dd8 --- /dev/null +++ b/libc/sysv/consts/BRKINT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios BRKINT 0b0000000000000010 0b0000000000000010 0b0000000000000010 0b0000000000000010 0b0000000000000010 diff --git a/libc/sysv/consts/BS0.s b/libc/sysv/consts/BS0.s new file mode 100644 index 00000000..901f592e --- /dev/null +++ b/libc/sysv/consts/BS0.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios BS0 0b0000000000000000 0b000000000000000000 0b000000000000000000 0 0b0000000000000000 diff --git a/libc/sysv/consts/BS1.s b/libc/sysv/consts/BS1.s new file mode 100644 index 00000000..44c202d5 --- /dev/null +++ b/libc/sysv/consts/BS1.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios BS1 0b0010000000000000 0b001000000000000000 0b001000000000000000 0 0b0010000000000000 diff --git a/libc/sysv/consts/BSDLY.s b/libc/sysv/consts/BSDLY.s new file mode 100644 index 00000000..b662bc63 --- /dev/null +++ b/libc/sysv/consts/BSDLY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios BSDLY 0b0010000000000000 0b001000000000000000 0b001000000000000000 0 0b0010000000000000 diff --git a/libc/sysv/consts/BUSY.s b/libc/sysv/consts/BUSY.s new file mode 100644 index 00000000..955d8646 --- /dev/null +++ b/libc/sysv/consts/BUSY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios BUSY 4 0 0 0 0 diff --git a/libc/sysv/consts/BUS_ADRALN.s b/libc/sysv/consts/BUS_ADRALN.s new file mode 100644 index 00000000..239b717f --- /dev/null +++ b/libc/sysv/consts/BUS_ADRALN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BUS_ADRALN 1 1 1 1 0 diff --git a/libc/sysv/consts/BUS_ADRERR.s b/libc/sysv/consts/BUS_ADRERR.s new file mode 100644 index 00000000..549708a4 --- /dev/null +++ b/libc/sysv/consts/BUS_ADRERR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BUS_ADRERR 2 2 2 2 0 diff --git a/libc/sysv/consts/BUS_DEVICE_RESET.s b/libc/sysv/consts/BUS_DEVICE_RESET.s new file mode 100644 index 00000000..aa28ee35 --- /dev/null +++ b/libc/sysv/consts/BUS_DEVICE_RESET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BUS_DEVICE_RESET 12 0 0 0 0 diff --git a/libc/sysv/consts/BUS_MCEERR_AO.s b/libc/sysv/consts/BUS_MCEERR_AO.s new file mode 100644 index 00000000..aa07a9b9 --- /dev/null +++ b/libc/sysv/consts/BUS_MCEERR_AO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BUS_MCEERR_AO 5 0 0 0 0 diff --git a/libc/sysv/consts/BUS_MCEERR_AR.s b/libc/sysv/consts/BUS_MCEERR_AR.s new file mode 100644 index 00000000..be6036b0 --- /dev/null +++ b/libc/sysv/consts/BUS_MCEERR_AR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BUS_MCEERR_AR 4 0 0 0 0 diff --git a/libc/sysv/consts/BUS_OBJERR.s b/libc/sysv/consts/BUS_OBJERR.s new file mode 100644 index 00000000..117e1a1a --- /dev/null +++ b/libc/sysv/consts/BUS_OBJERR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc BUS_OBJERR 3 3 3 3 0 diff --git a/libc/sysv/consts/CANBSIZ.s b/libc/sysv/consts/CANBSIZ.s new file mode 100644 index 00000000..62fcdc91 --- /dev/null +++ b/libc/sysv/consts/CANBSIZ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios CANBSIZ 255 0 0 0 0 diff --git a/libc/sysv/consts/CBAUD.s b/libc/sysv/consts/CBAUD.s new file mode 100644 index 00000000..4cd071ae --- /dev/null +++ b/libc/sysv/consts/CBAUD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios CBAUD 0x100f 0 0 0 0 diff --git a/libc/sysv/consts/CBAUDEX.s b/libc/sysv/consts/CBAUDEX.s new file mode 100644 index 00000000..63e60156 --- /dev/null +++ b/libc/sysv/consts/CBAUDEX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios CBAUDEX 0x1000 0 0 0 0 diff --git a/libc/sysv/consts/CBRK.s b/libc/sysv/consts/CBRK.s new file mode 100644 index 00000000..7ab58ca1 --- /dev/null +++ b/libc/sysv/consts/CBRK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios CBRK 0 255 255 255 0 diff --git a/libc/sysv/consts/CDISCARD.s b/libc/sysv/consts/CDISCARD.s new file mode 100644 index 00000000..c08a30f0 --- /dev/null +++ b/libc/sysv/consts/CDISCARD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CDISCARD 15 15 15 15 0 diff --git a/libc/sysv/consts/CDSUSP.s b/libc/sysv/consts/CDSUSP.s new file mode 100644 index 00000000..6ec04218 --- /dev/null +++ b/libc/sysv/consts/CDSUSP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CDSUSP 25 25 25 25 0 diff --git a/libc/sysv/consts/CEOF.s b/libc/sysv/consts/CEOF.s new file mode 100644 index 00000000..320da981 --- /dev/null +++ b/libc/sysv/consts/CEOF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CEOF 4 4 4 4 0 diff --git a/libc/sysv/consts/CEOL.s b/libc/sysv/consts/CEOL.s new file mode 100644 index 00000000..67324c2a --- /dev/null +++ b/libc/sysv/consts/CEOL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios CEOL 0 255 255 255 0 diff --git a/libc/sysv/consts/CEOT.s b/libc/sysv/consts/CEOT.s new file mode 100644 index 00000000..3bd43cc3 --- /dev/null +++ b/libc/sysv/consts/CEOT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CEOT 4 4 4 4 0 diff --git a/libc/sysv/consts/CERASE.s b/libc/sysv/consts/CERASE.s new file mode 100644 index 00000000..6d1e7feb --- /dev/null +++ b/libc/sysv/consts/CERASE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CERASE 127 127 127 127 0 diff --git a/libc/sysv/consts/CFLUSH.s b/libc/sysv/consts/CFLUSH.s new file mode 100644 index 00000000..7cb226ba --- /dev/null +++ b/libc/sysv/consts/CFLUSH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CFLUSH 15 15 15 15 0 diff --git a/libc/sysv/consts/CHANGE_DEFINITION.s b/libc/sysv/consts/CHANGE_DEFINITION.s new file mode 100644 index 00000000..cb38ffb4 --- /dev/null +++ b/libc/sysv/consts/CHANGE_DEFINITION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CHANGE_DEFINITION 0x40 0 0 0 0 diff --git a/libc/sysv/consts/CHARBITS.s b/libc/sysv/consts/CHARBITS.s new file mode 100644 index 00000000..a685212c --- /dev/null +++ b/libc/sysv/consts/CHARBITS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CHARBITS 8 0 0 0 0 diff --git a/libc/sysv/consts/CHARCLASS_NAME_MAX.s b/libc/sysv/consts/CHARCLASS_NAME_MAX.s new file mode 100644 index 00000000..14f2abda --- /dev/null +++ b/libc/sysv/consts/CHARCLASS_NAME_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CHARCLASS_NAME_MAX 0x0800 14 14 0 0 diff --git a/libc/sysv/consts/CHECK_CONDITION.s b/libc/sysv/consts/CHECK_CONDITION.s new file mode 100644 index 00000000..fc7ce28b --- /dev/null +++ b/libc/sysv/consts/CHECK_CONDITION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CHECK_CONDITION 1 0 0 0 0 diff --git a/libc/sysv/consts/CHRTYPE.s b/libc/sysv/consts/CHRTYPE.s new file mode 100644 index 00000000..2687e1a5 --- /dev/null +++ b/libc/sysv/consts/CHRTYPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CHRTYPE 51 51 51 51 0 diff --git a/libc/sysv/consts/CIBAUD.s b/libc/sysv/consts/CIBAUD.s new file mode 100644 index 00000000..9cee3e71 --- /dev/null +++ b/libc/sysv/consts/CIBAUD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios CIBAUD 0x100f0000 0 0 0 0 diff --git a/libc/sysv/consts/CINTR.s b/libc/sysv/consts/CINTR.s new file mode 100644 index 00000000..0f50d40b --- /dev/null +++ b/libc/sysv/consts/CINTR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CINTR 3 3 3 3 0 diff --git a/libc/sysv/consts/CKILL.s b/libc/sysv/consts/CKILL.s new file mode 100644 index 00000000..7284db8b --- /dev/null +++ b/libc/sysv/consts/CKILL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CKILL 21 21 21 21 0 diff --git a/libc/sysv/consts/CLD_CONTINUED.s b/libc/sysv/consts/CLD_CONTINUED.s new file mode 100644 index 00000000..8ba22c58 --- /dev/null +++ b/libc/sysv/consts/CLD_CONTINUED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CLD_CONTINUED 6 6 6 6 0 diff --git a/libc/sysv/consts/CLD_DUMPED.s b/libc/sysv/consts/CLD_DUMPED.s new file mode 100644 index 00000000..7cbb4569 --- /dev/null +++ b/libc/sysv/consts/CLD_DUMPED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CLD_DUMPED 3 3 3 3 0 diff --git a/libc/sysv/consts/CLD_EXITED.s b/libc/sysv/consts/CLD_EXITED.s new file mode 100644 index 00000000..72cef528 --- /dev/null +++ b/libc/sysv/consts/CLD_EXITED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CLD_EXITED 1 1 1 1 0 diff --git a/libc/sysv/consts/CLD_KILLED.s b/libc/sysv/consts/CLD_KILLED.s new file mode 100644 index 00000000..2248c965 --- /dev/null +++ b/libc/sysv/consts/CLD_KILLED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CLD_KILLED 2 2 2 2 0 diff --git a/libc/sysv/consts/CLD_STOPPED.s b/libc/sysv/consts/CLD_STOPPED.s new file mode 100644 index 00000000..61c367db --- /dev/null +++ b/libc/sysv/consts/CLD_STOPPED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CLD_STOPPED 5 5 5 5 0 diff --git a/libc/sysv/consts/CLD_TRAPPED.s b/libc/sysv/consts/CLD_TRAPPED.s new file mode 100644 index 00000000..1ee4e1a8 --- /dev/null +++ b/libc/sysv/consts/CLD_TRAPPED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CLD_TRAPPED 4 4 4 4 0 diff --git a/libc/sysv/consts/CLNEXT.s b/libc/sysv/consts/CLNEXT.s new file mode 100644 index 00000000..cf6e3ac0 --- /dev/null +++ b/libc/sysv/consts/CLNEXT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CLNEXT 22 22 22 22 0 diff --git a/libc/sysv/consts/CLOCAL.s b/libc/sysv/consts/CLOCAL.s new file mode 100644 index 00000000..c124ebcb --- /dev/null +++ b/libc/sysv/consts/CLOCAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios CLOCAL 0x0800 0x8000 0x8000 0x8000 0 diff --git a/libc/sysv/consts/CLOCKS_PER_SEC.s b/libc/sysv/consts/CLOCKS_PER_SEC.s new file mode 100644 index 00000000..a5366b6f --- /dev/null +++ b/libc/sysv/consts/CLOCKS_PER_SEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CLOCKS_PER_SEC 1000000 1000000 0x80 100 10000000 diff --git a/libc/sysv/consts/CLOCK_BOOTTIME.s b/libc/sysv/consts/CLOCK_BOOTTIME.s new file mode 100644 index 00000000..fa87492d --- /dev/null +++ b/libc/sysv/consts/CLOCK_BOOTTIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon clock CLOCK_BOOTTIME 7 -1 0 6 0 diff --git a/libc/sysv/consts/CLOCK_BOOTTIME_ALARM.s b/libc/sysv/consts/CLOCK_BOOTTIME_ALARM.s new file mode 100644 index 00000000..42c8bc5b --- /dev/null +++ b/libc/sysv/consts/CLOCK_BOOTTIME_ALARM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon clock CLOCK_BOOTTIME_ALARM 9 -1 0 0 0 diff --git a/libc/sysv/consts/CLOCK_MONOTONIC.s b/libc/sysv/consts/CLOCK_MONOTONIC.s new file mode 100644 index 00000000..2d42bac4 --- /dev/null +++ b/libc/sysv/consts/CLOCK_MONOTONIC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon clock CLOCK_MONOTONIC 4 1 4 3 1 diff --git a/libc/sysv/consts/CLOCK_MONOTONIC_COARSE.s b/libc/sysv/consts/CLOCK_MONOTONIC_COARSE.s new file mode 100644 index 00000000..a5bcccf6 --- /dev/null +++ b/libc/sysv/consts/CLOCK_MONOTONIC_COARSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon clock CLOCK_MONOTONIC_COARSE 6 -1 0 0 0 diff --git a/libc/sysv/consts/CLOCK_MONOTONIC_RAW.s b/libc/sysv/consts/CLOCK_MONOTONIC_RAW.s new file mode 100644 index 00000000..bafb0353 --- /dev/null +++ b/libc/sysv/consts/CLOCK_MONOTONIC_RAW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon clock CLOCK_MONOTONIC_RAW 4 4 0x4000 0x4000 4 diff --git a/libc/sysv/consts/CLOCK_PROCESS_CPUTIME_ID.s b/libc/sysv/consts/CLOCK_PROCESS_CPUTIME_ID.s new file mode 100644 index 00000000..fb0df119 --- /dev/null +++ b/libc/sysv/consts/CLOCK_PROCESS_CPUTIME_ID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon clock CLOCK_PROCESS_CPUTIME_ID 2 -1 15 2 0 diff --git a/libc/sysv/consts/CLOCK_REALTIME.s b/libc/sysv/consts/CLOCK_REALTIME.s new file mode 100644 index 00000000..042585be --- /dev/null +++ b/libc/sysv/consts/CLOCK_REALTIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon clock CLOCK_REALTIME 0 0 0 0 0 diff --git a/libc/sysv/consts/CLOCK_REALTIME_ALARM.s b/libc/sysv/consts/CLOCK_REALTIME_ALARM.s new file mode 100644 index 00000000..53991658 --- /dev/null +++ b/libc/sysv/consts/CLOCK_REALTIME_ALARM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon clock CLOCK_REALTIME_ALARM 8 -1 0 0 0 diff --git a/libc/sysv/consts/CLOCK_REALTIME_COARSE.s b/libc/sysv/consts/CLOCK_REALTIME_COARSE.s new file mode 100644 index 00000000..8116649c --- /dev/null +++ b/libc/sysv/consts/CLOCK_REALTIME_COARSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon clock CLOCK_REALTIME_COARSE 5 -1 0 0 0 diff --git a/libc/sysv/consts/CLOCK_TAI.s b/libc/sysv/consts/CLOCK_TAI.s new file mode 100644 index 00000000..65ac517f --- /dev/null +++ b/libc/sysv/consts/CLOCK_TAI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon clock CLOCK_TAI 11 -1 0 0 0 diff --git a/libc/sysv/consts/CLOCK_THREAD_CPUTIME_ID.s b/libc/sysv/consts/CLOCK_THREAD_CPUTIME_ID.s new file mode 100644 index 00000000..fcb1d0a5 --- /dev/null +++ b/libc/sysv/consts/CLOCK_THREAD_CPUTIME_ID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon clock CLOCK_THREAD_CPUTIME_ID 3 -1 14 4 0 diff --git a/libc/sysv/consts/CMIN.s b/libc/sysv/consts/CMIN.s new file mode 100644 index 00000000..19f287eb --- /dev/null +++ b/libc/sysv/consts/CMIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CMIN 1 1 1 1 0 diff --git a/libc/sysv/consts/CMSPAR.s b/libc/sysv/consts/CMSPAR.s new file mode 100644 index 00000000..013ae7a0 --- /dev/null +++ b/libc/sysv/consts/CMSPAR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios CMSPAR 0x40000000 0 0 0 0 diff --git a/libc/sysv/consts/CODESET.s b/libc/sysv/consts/CODESET.s new file mode 100644 index 00000000..2d0fd7e4 --- /dev/null +++ b/libc/sysv/consts/CODESET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CODESET 14 0 0 51 0 diff --git a/libc/sysv/consts/COLL_WEIGHTS_MAX.s b/libc/sysv/consts/COLL_WEIGHTS_MAX.s new file mode 100644 index 00000000..44c09b10 --- /dev/null +++ b/libc/sysv/consts/COLL_WEIGHTS_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc COLL_WEIGHTS_MAX 255 2 10 2 0 diff --git a/libc/sysv/consts/COMMAND_COMPLETE.s b/libc/sysv/consts/COMMAND_COMPLETE.s new file mode 100644 index 00000000..94f14168 --- /dev/null +++ b/libc/sysv/consts/COMMAND_COMPLETE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc COMMAND_COMPLETE 0 0 0 0 0 diff --git a/libc/sysv/consts/COMMAND_TERMINATED.s b/libc/sysv/consts/COMMAND_TERMINATED.s new file mode 100644 index 00000000..7ddc750b --- /dev/null +++ b/libc/sysv/consts/COMMAND_TERMINATED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc COMMAND_TERMINATED 17 0 0 0 0 diff --git a/libc/sysv/consts/COMPLETE.s b/libc/sysv/consts/COMPLETE.s new file mode 100644 index 00000000..574d3566 --- /dev/null +++ b/libc/sysv/consts/COMPLETE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc COMPLETE 2 2 2 2 0 diff --git a/libc/sysv/consts/CONDITION_GOOD.s b/libc/sysv/consts/CONDITION_GOOD.s new file mode 100644 index 00000000..db5091ba --- /dev/null +++ b/libc/sysv/consts/CONDITION_GOOD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CONDITION_GOOD 2 0 0 0 0 diff --git a/libc/sysv/consts/CONTINUE.s b/libc/sysv/consts/CONTINUE.s new file mode 100644 index 00000000..5eeffd50 --- /dev/null +++ b/libc/sysv/consts/CONTINUE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CONTINUE 3 3 3 3 0 diff --git a/libc/sysv/consts/CONTTYPE.s b/libc/sysv/consts/CONTTYPE.s new file mode 100644 index 00000000..c009e66b --- /dev/null +++ b/libc/sysv/consts/CONTTYPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CONTTYPE 55 55 55 55 0 diff --git a/libc/sysv/consts/COPY_ABORTED.s b/libc/sysv/consts/COPY_ABORTED.s new file mode 100644 index 00000000..95ee2d88 --- /dev/null +++ b/libc/sysv/consts/COPY_ABORTED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc COPY_ABORTED 10 0 0 0 0 diff --git a/libc/sysv/consts/COPY_VERIFY.s b/libc/sysv/consts/COPY_VERIFY.s new file mode 100644 index 00000000..a4e775f4 --- /dev/null +++ b/libc/sysv/consts/COPY_VERIFY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc COPY_VERIFY 58 0 0 0 0 diff --git a/libc/sysv/consts/CPU_SETSIZE.s b/libc/sysv/consts/CPU_SETSIZE.s new file mode 100644 index 00000000..d55ac385 --- /dev/null +++ b/libc/sysv/consts/CPU_SETSIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CPU_SETSIZE 0x0400 0 0x0100 0 0 diff --git a/libc/sysv/consts/CQUIT.s b/libc/sysv/consts/CQUIT.s new file mode 100644 index 00000000..ef6d55c7 --- /dev/null +++ b/libc/sysv/consts/CQUIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CQUIT 28 28 28 28 0 diff --git a/libc/sysv/consts/CR0.s b/libc/sysv/consts/CR0.s new file mode 100644 index 00000000..38bf4596 --- /dev/null +++ b/libc/sysv/consts/CR0.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios CR0 0b0000000000000000 0b000000000000000000 0b000000000000000000 0x0 0b0000000000000000 diff --git a/libc/sysv/consts/CR1.s b/libc/sysv/consts/CR1.s new file mode 100644 index 00000000..0d4b7eb6 --- /dev/null +++ b/libc/sysv/consts/CR1.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios CR1 0b0000001000000000 0b000001000000000000 0b000001000000000000 0x0 0b0000001000000000 diff --git a/libc/sysv/consts/CR2.s b/libc/sysv/consts/CR2.s new file mode 100644 index 00000000..7a6c5b17 --- /dev/null +++ b/libc/sysv/consts/CR2.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios CR2 0b0000010000000000 0b000010000000000000 0b000010000000000000 0x0 0b0000010000000000 diff --git a/libc/sysv/consts/CR3.s b/libc/sysv/consts/CR3.s new file mode 100644 index 00000000..fd31feb0 --- /dev/null +++ b/libc/sysv/consts/CR3.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios CR3 0b0000011000000000 0b000011000000000000 0b000011000000000000 0x0 0b0000011000000000 diff --git a/libc/sysv/consts/CRDLY.s b/libc/sysv/consts/CRDLY.s new file mode 100644 index 00000000..5629b42a --- /dev/null +++ b/libc/sysv/consts/CRDLY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios CRDLY 0b0000011000000000 0b000011000000000000 0b000011000000000000 0 0b0000011000000000 diff --git a/libc/sysv/consts/CREAD.s b/libc/sysv/consts/CREAD.s new file mode 100644 index 00000000..28f4b03d --- /dev/null +++ b/libc/sysv/consts/CREAD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CREAD 0x80 0x0800 0x0800 0x0800 0 diff --git a/libc/sysv/consts/CREPRINT.s b/libc/sysv/consts/CREPRINT.s new file mode 100644 index 00000000..22842774 --- /dev/null +++ b/libc/sysv/consts/CREPRINT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CREPRINT 18 18 18 18 0 diff --git a/libc/sysv/consts/CRNCYSTR.s b/libc/sysv/consts/CRNCYSTR.s new file mode 100644 index 00000000..0bc1b208 --- /dev/null +++ b/libc/sysv/consts/CRNCYSTR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CRNCYSTR 0x04000f 56 56 50 0 diff --git a/libc/sysv/consts/CRPRNT.s b/libc/sysv/consts/CRPRNT.s new file mode 100644 index 00000000..6e12abe5 --- /dev/null +++ b/libc/sysv/consts/CRPRNT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CRPRNT 18 18 18 18 0 diff --git a/libc/sysv/consts/CRTSCTS.s b/libc/sysv/consts/CRTSCTS.s new file mode 100644 index 00000000..60908fb4 --- /dev/null +++ b/libc/sysv/consts/CRTSCTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CRTSCTS 0x80000000 0x030000 0x030000 0x010000 0 diff --git a/libc/sysv/consts/CS5.s b/libc/sysv/consts/CS5.s new file mode 100644 index 00000000..dcbb044e --- /dev/null +++ b/libc/sysv/consts/CS5.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CS5 0 0 0 0 0 diff --git a/libc/sysv/consts/CS6.s b/libc/sysv/consts/CS6.s new file mode 100644 index 00000000..00efefa4 --- /dev/null +++ b/libc/sysv/consts/CS6.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios CS6 0b0000000000010000 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000000010000 diff --git a/libc/sysv/consts/CS7.s b/libc/sysv/consts/CS7.s new file mode 100644 index 00000000..a2ea3f28 --- /dev/null +++ b/libc/sysv/consts/CS7.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios CS7 0b0000000000100000 0b0000001000000000 0b0000001000000000 0b0000001000000000 0b0000000000100000 diff --git a/libc/sysv/consts/CS8.s b/libc/sysv/consts/CS8.s new file mode 100644 index 00000000..3972cbfa --- /dev/null +++ b/libc/sysv/consts/CS8.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios CS8 0b0000000000110000 0b0000001100000000 0b0000001100000000 0b0000001100000000 0b0000000000110000 diff --git a/libc/sysv/consts/CSIZE.s b/libc/sysv/consts/CSIZE.s new file mode 100644 index 00000000..fb75351c --- /dev/null +++ b/libc/sysv/consts/CSIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios CSIZE 0b0000000000110000 0b0000001100000000 0b0000001100000000 0b0000001100000000 0b0000000000110000 diff --git a/libc/sysv/consts/CSTART.s b/libc/sysv/consts/CSTART.s new file mode 100644 index 00000000..260b7bda --- /dev/null +++ b/libc/sysv/consts/CSTART.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CSTART 17 17 17 17 0 diff --git a/libc/sysv/consts/CSTATUS.s b/libc/sysv/consts/CSTATUS.s new file mode 100644 index 00000000..436ef8ad --- /dev/null +++ b/libc/sysv/consts/CSTATUS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CSTATUS 0 20 20 255 0 diff --git a/libc/sysv/consts/CSTOP.s b/libc/sysv/consts/CSTOP.s new file mode 100644 index 00000000..5ec5df5e --- /dev/null +++ b/libc/sysv/consts/CSTOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CSTOP 19 19 19 19 0 diff --git a/libc/sysv/consts/CSTOPB.s b/libc/sysv/consts/CSTOPB.s new file mode 100644 index 00000000..aa3c0d27 --- /dev/null +++ b/libc/sysv/consts/CSTOPB.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CSTOPB 0x40 0x0400 0x0400 0x0400 0 diff --git a/libc/sysv/consts/CSUSP.s b/libc/sysv/consts/CSUSP.s new file mode 100644 index 00000000..29627100 --- /dev/null +++ b/libc/sysv/consts/CSUSP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CSUSP 26 26 26 26 0 diff --git a/libc/sysv/consts/CTIME.s b/libc/sysv/consts/CTIME.s new file mode 100644 index 00000000..80523357 --- /dev/null +++ b/libc/sysv/consts/CTIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CTIME 0 0 0 0 0 diff --git a/libc/sysv/consts/CWERASE.s b/libc/sysv/consts/CWERASE.s new file mode 100644 index 00000000..54faff4c --- /dev/null +++ b/libc/sysv/consts/CWERASE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc CWERASE 23 23 23 23 0 diff --git a/libc/sysv/consts/C_IRGRP.s b/libc/sysv/consts/C_IRGRP.s new file mode 100644 index 00000000..b973b12d --- /dev/null +++ b/libc/sysv/consts/C_IRGRP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_IRGRP 0000040 0000040 0000040 0000040 0 diff --git a/libc/sysv/consts/C_IROTH.s b/libc/sysv/consts/C_IROTH.s new file mode 100644 index 00000000..260b2849 --- /dev/null +++ b/libc/sysv/consts/C_IROTH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_IROTH 0000004 0000004 0000004 0000004 0 diff --git a/libc/sysv/consts/C_IRUSR.s b/libc/sysv/consts/C_IRUSR.s new file mode 100644 index 00000000..19b9e2b6 --- /dev/null +++ b/libc/sysv/consts/C_IRUSR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_IRUSR 0000400 0000400 0000400 0000400 0 diff --git a/libc/sysv/consts/C_ISBLK.s b/libc/sysv/consts/C_ISBLK.s new file mode 100644 index 00000000..3241a268 --- /dev/null +++ b/libc/sysv/consts/C_ISBLK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_ISBLK 0060000 0060000 0060000 0060000 0 diff --git a/libc/sysv/consts/C_ISCHR.s b/libc/sysv/consts/C_ISCHR.s new file mode 100644 index 00000000..9f0d077e --- /dev/null +++ b/libc/sysv/consts/C_ISCHR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_ISCHR 0020000 0020000 0020000 0020000 0 diff --git a/libc/sysv/consts/C_ISCTG.s b/libc/sysv/consts/C_ISCTG.s new file mode 100644 index 00000000..0e461729 --- /dev/null +++ b/libc/sysv/consts/C_ISCTG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_ISCTG 0110000 0110000 0110000 0110000 0 diff --git a/libc/sysv/consts/C_ISDIR.s b/libc/sysv/consts/C_ISDIR.s new file mode 100644 index 00000000..ab50dfc9 --- /dev/null +++ b/libc/sysv/consts/C_ISDIR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_ISDIR 0040000 0040000 0040000 0040000 0 diff --git a/libc/sysv/consts/C_ISFIFO.s b/libc/sysv/consts/C_ISFIFO.s new file mode 100644 index 00000000..e7145ddb --- /dev/null +++ b/libc/sysv/consts/C_ISFIFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_ISFIFO 0010000 0010000 0010000 0010000 0 diff --git a/libc/sysv/consts/C_ISGID.s b/libc/sysv/consts/C_ISGID.s new file mode 100644 index 00000000..d31e7fe1 --- /dev/null +++ b/libc/sysv/consts/C_ISGID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_ISGID 0002000 0002000 0002000 0002000 0 diff --git a/libc/sysv/consts/C_ISLNK.s b/libc/sysv/consts/C_ISLNK.s new file mode 100644 index 00000000..19faf7d5 --- /dev/null +++ b/libc/sysv/consts/C_ISLNK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_ISLNK 0120000 0120000 0120000 0120000 0 diff --git a/libc/sysv/consts/C_ISREG.s b/libc/sysv/consts/C_ISREG.s new file mode 100644 index 00000000..9879ca6a --- /dev/null +++ b/libc/sysv/consts/C_ISREG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_ISREG 0100000 0100000 0100000 0100000 0 diff --git a/libc/sysv/consts/C_ISSOCK.s b/libc/sysv/consts/C_ISSOCK.s new file mode 100644 index 00000000..03d143ac --- /dev/null +++ b/libc/sysv/consts/C_ISSOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_ISSOCK 0140000 0140000 0140000 0140000 0 diff --git a/libc/sysv/consts/C_ISUID.s b/libc/sysv/consts/C_ISUID.s new file mode 100644 index 00000000..95c6d1c5 --- /dev/null +++ b/libc/sysv/consts/C_ISUID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_ISUID 0004000 0004000 0004000 0004000 0 diff --git a/libc/sysv/consts/C_ISVTX.s b/libc/sysv/consts/C_ISVTX.s new file mode 100644 index 00000000..f5b1233c --- /dev/null +++ b/libc/sysv/consts/C_ISVTX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_ISVTX 0001000 0001000 0001000 0001000 0 diff --git a/libc/sysv/consts/C_IWGRP.s b/libc/sysv/consts/C_IWGRP.s new file mode 100644 index 00000000..4bedc2a3 --- /dev/null +++ b/libc/sysv/consts/C_IWGRP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_IWGRP 0000020 0000020 0000020 0000020 0 diff --git a/libc/sysv/consts/C_IWOTH.s b/libc/sysv/consts/C_IWOTH.s new file mode 100644 index 00000000..f0c27124 --- /dev/null +++ b/libc/sysv/consts/C_IWOTH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_IWOTH 0000002 0000002 0000002 0000002 0 diff --git a/libc/sysv/consts/C_IWUSR.s b/libc/sysv/consts/C_IWUSR.s new file mode 100644 index 00000000..84742c82 --- /dev/null +++ b/libc/sysv/consts/C_IWUSR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_IWUSR 0000200 0000200 0000200 0000200 0 diff --git a/libc/sysv/consts/C_IXGRP.s b/libc/sysv/consts/C_IXGRP.s new file mode 100644 index 00000000..25c15853 --- /dev/null +++ b/libc/sysv/consts/C_IXGRP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_IXGRP 0000010 0000010 0000010 0000010 0 diff --git a/libc/sysv/consts/C_IXOTH.s b/libc/sysv/consts/C_IXOTH.s new file mode 100644 index 00000000..c2390565 --- /dev/null +++ b/libc/sysv/consts/C_IXOTH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_IXOTH 0000001 0000001 0000001 0000001 0 diff --git a/libc/sysv/consts/C_IXUSR.s b/libc/sysv/consts/C_IXUSR.s new file mode 100644 index 00000000..e3e8ea09 --- /dev/null +++ b/libc/sysv/consts/C_IXUSR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon c C_IXUSR 0000100 0000100 0000100 0000100 0 diff --git a/libc/sysv/consts/DATA.s b/libc/sysv/consts/DATA.s new file mode 100644 index 00000000..dc7d52e6 --- /dev/null +++ b/libc/sysv/consts/DATA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DATA 3 3 3 3 0 diff --git a/libc/sysv/consts/DATA_PROTECT.s b/libc/sysv/consts/DATA_PROTECT.s new file mode 100644 index 00000000..cbc34cab --- /dev/null +++ b/libc/sysv/consts/DATA_PROTECT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DATA_PROTECT 7 0 0 0 0 diff --git a/libc/sysv/consts/DAY_1.s b/libc/sysv/consts/DAY_1.s new file mode 100644 index 00000000..9de251d5 --- /dev/null +++ b/libc/sysv/consts/DAY_1.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DAY_1 0x020007 7 7 6 0 diff --git a/libc/sysv/consts/DAY_2.s b/libc/sysv/consts/DAY_2.s new file mode 100644 index 00000000..a7b3dbae --- /dev/null +++ b/libc/sysv/consts/DAY_2.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DAY_2 0x020008 8 8 7 0 diff --git a/libc/sysv/consts/DAY_3.s b/libc/sysv/consts/DAY_3.s new file mode 100644 index 00000000..821ae5c7 --- /dev/null +++ b/libc/sysv/consts/DAY_3.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DAY_3 0x020009 9 9 8 0 diff --git a/libc/sysv/consts/DAY_4.s b/libc/sysv/consts/DAY_4.s new file mode 100644 index 00000000..9936be60 --- /dev/null +++ b/libc/sysv/consts/DAY_4.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DAY_4 0x02000a 10 10 9 0 diff --git a/libc/sysv/consts/DAY_5.s b/libc/sysv/consts/DAY_5.s new file mode 100644 index 00000000..2a1a4992 --- /dev/null +++ b/libc/sysv/consts/DAY_5.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DAY_5 0x02000b 11 11 10 0 diff --git a/libc/sysv/consts/DAY_6.s b/libc/sysv/consts/DAY_6.s new file mode 100644 index 00000000..341249bd --- /dev/null +++ b/libc/sysv/consts/DAY_6.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DAY_6 0x02000c 12 12 11 0 diff --git a/libc/sysv/consts/DAY_7.s b/libc/sysv/consts/DAY_7.s new file mode 100644 index 00000000..6ee749c6 --- /dev/null +++ b/libc/sysv/consts/DAY_7.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DAY_7 0x02000d 13 13 12 0 diff --git a/libc/sysv/consts/DEAD_PROCESS.s b/libc/sysv/consts/DEAD_PROCESS.s new file mode 100644 index 00000000..23b2c035 --- /dev/null +++ b/libc/sysv/consts/DEAD_PROCESS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DEAD_PROCESS 8 8 7 0 0 diff --git a/libc/sysv/consts/DELAYTIMER_MAX.s b/libc/sysv/consts/DELAYTIMER_MAX.s new file mode 100644 index 00000000..d65a600a --- /dev/null +++ b/libc/sysv/consts/DELAYTIMER_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DELAYTIMER_MAX 0x7fffffff 0 0 0 0 diff --git a/libc/sysv/consts/DEV_BSIZE.s b/libc/sysv/consts/DEV_BSIZE.s new file mode 100644 index 00000000..746025db --- /dev/null +++ b/libc/sysv/consts/DEV_BSIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DEV_BSIZE 0x0200 0x0200 0x0200 0x0200 0 diff --git a/libc/sysv/consts/DIRTYPE.s b/libc/sysv/consts/DIRTYPE.s new file mode 100644 index 00000000..023b8916 --- /dev/null +++ b/libc/sysv/consts/DIRTYPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DIRTYPE 53 53 53 53 0 diff --git a/libc/sysv/consts/DMAXEXP.s b/libc/sysv/consts/DMAXEXP.s new file mode 100644 index 00000000..6f43d152 --- /dev/null +++ b/libc/sysv/consts/DMAXEXP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DMAXEXP 0x0400 0 0 0 0 diff --git a/libc/sysv/consts/DMINEXP.s b/libc/sysv/consts/DMINEXP.s new file mode 100644 index 00000000..253b7ee4 --- /dev/null +++ b/libc/sysv/consts/DMINEXP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DMINEXP -1021 0 0 0 0 diff --git a/libc/sysv/consts/DOUBLEBITS.s b/libc/sysv/consts/DOUBLEBITS.s new file mode 100644 index 00000000..561aa675 --- /dev/null +++ b/libc/sysv/consts/DOUBLEBITS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DOUBLEBITS 0x40 0 0 0 0 diff --git a/libc/sysv/consts/DT_BLK.s b/libc/sysv/consts/DT_BLK.s new file mode 100644 index 00000000..9c10b60e --- /dev/null +++ b/libc/sysv/consts/DT_BLK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DT_BLK 6 6 6 6 0 diff --git a/libc/sysv/consts/DT_CHR.s b/libc/sysv/consts/DT_CHR.s new file mode 100644 index 00000000..3c277524 --- /dev/null +++ b/libc/sysv/consts/DT_CHR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DT_CHR 2 2 2 2 0 diff --git a/libc/sysv/consts/DT_DIR.s b/libc/sysv/consts/DT_DIR.s new file mode 100644 index 00000000..4b34a24a --- /dev/null +++ b/libc/sysv/consts/DT_DIR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DT_DIR 4 4 4 4 0 diff --git a/libc/sysv/consts/DT_FIFO.s b/libc/sysv/consts/DT_FIFO.s new file mode 100644 index 00000000..abb5616f --- /dev/null +++ b/libc/sysv/consts/DT_FIFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DT_FIFO 1 1 1 1 0 diff --git a/libc/sysv/consts/DT_LNK.s b/libc/sysv/consts/DT_LNK.s new file mode 100644 index 00000000..caf63f84 --- /dev/null +++ b/libc/sysv/consts/DT_LNK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DT_LNK 10 10 10 10 0 diff --git a/libc/sysv/consts/DT_REG.s b/libc/sysv/consts/DT_REG.s new file mode 100644 index 00000000..5d9c25aa --- /dev/null +++ b/libc/sysv/consts/DT_REG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DT_REG 8 8 8 8 0 diff --git a/libc/sysv/consts/DT_SOCK.s b/libc/sysv/consts/DT_SOCK.s new file mode 100644 index 00000000..fe48b611 --- /dev/null +++ b/libc/sysv/consts/DT_SOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DT_SOCK 12 12 12 12 0 diff --git a/libc/sysv/consts/DT_UNKNOWN.s b/libc/sysv/consts/DT_UNKNOWN.s new file mode 100644 index 00000000..479505d5 --- /dev/null +++ b/libc/sysv/consts/DT_UNKNOWN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc DT_UNKNOWN 0 0 0 0 0 diff --git a/libc/sysv/consts/D_FMT.s b/libc/sysv/consts/D_FMT.s new file mode 100644 index 00000000..0f2fdde7 --- /dev/null +++ b/libc/sysv/consts/D_FMT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc D_FMT 0x020029 2 2 1 0 diff --git a/libc/sysv/consts/D_T_FMT.s b/libc/sysv/consts/D_T_FMT.s new file mode 100644 index 00000000..29478d28 --- /dev/null +++ b/libc/sysv/consts/D_T_FMT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc D_T_FMT 0x020028 1 1 0 0 diff --git a/libc/sysv/consts/E2BIG.s b/libc/sysv/consts/E2BIG.s new file mode 100644 index 00000000..b165e906 --- /dev/null +++ b/libc/sysv/consts/E2BIG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno E2BIG 7 7 7 7 1639 diff --git a/libc/sysv/consts/EACCES.s b/libc/sysv/consts/EACCES.s new file mode 100644 index 00000000..105b818e --- /dev/null +++ b/libc/sysv/consts/EACCES.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EACCES 13 13 13 13 5 diff --git a/libc/sysv/consts/EADDRINUSE.s b/libc/sysv/consts/EADDRINUSE.s new file mode 100644 index 00000000..1648aa1e --- /dev/null +++ b/libc/sysv/consts/EADDRINUSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EADDRINUSE 98 48 48 48 0x2740 diff --git a/libc/sysv/consts/EADDRNOTAVAIL.s b/libc/sysv/consts/EADDRNOTAVAIL.s new file mode 100644 index 00000000..ca326184 --- /dev/null +++ b/libc/sysv/consts/EADDRNOTAVAIL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EADDRNOTAVAIL 99 49 49 49 0x2741 diff --git a/libc/sysv/consts/EADV.s b/libc/sysv/consts/EADV.s new file mode 100644 index 00000000..caf78f0e --- /dev/null +++ b/libc/sysv/consts/EADV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EADV 68 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EAFNOSUPPORT.s b/libc/sysv/consts/EAFNOSUPPORT.s new file mode 100644 index 00000000..f863a10f --- /dev/null +++ b/libc/sysv/consts/EAFNOSUPPORT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EAFNOSUPPORT 97 47 47 47 0x273f diff --git a/libc/sysv/consts/EAGAIN.s b/libc/sysv/consts/EAGAIN.s new file mode 100644 index 00000000..fac22c24 --- /dev/null +++ b/libc/sysv/consts/EAGAIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EAGAIN 11 35 35 35 0x2733 diff --git a/libc/sysv/consts/EAI_ADDRFAMILY.s b/libc/sysv/consts/EAI_ADDRFAMILY.s new file mode 100644 index 00000000..0dfbef69 --- /dev/null +++ b/libc/sysv/consts/EAI_ADDRFAMILY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_ADDRFAMILY -9 1 0 -9 -9 diff --git a/libc/sysv/consts/EAI_AGAIN.s b/libc/sysv/consts/EAI_AGAIN.s new file mode 100644 index 00000000..b8f578df --- /dev/null +++ b/libc/sysv/consts/EAI_AGAIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_AGAIN -3 2 2 -3 0x2afa diff --git a/libc/sysv/consts/EAI_ALLDONE.s b/libc/sysv/consts/EAI_ALLDONE.s new file mode 100644 index 00000000..0407855c --- /dev/null +++ b/libc/sysv/consts/EAI_ALLDONE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_ALLDONE -103 -103 -103 -103 -103 diff --git a/libc/sysv/consts/EAI_BADFLAGS.s b/libc/sysv/consts/EAI_BADFLAGS.s new file mode 100644 index 00000000..2c2f486c --- /dev/null +++ b/libc/sysv/consts/EAI_BADFLAGS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_BADFLAGS -1 3 3 -1 0x2726 diff --git a/libc/sysv/consts/EAI_CANCELED.s b/libc/sysv/consts/EAI_CANCELED.s new file mode 100644 index 00000000..66b239b0 --- /dev/null +++ b/libc/sysv/consts/EAI_CANCELED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_CANCELED -101 -101 -101 -101 -101 diff --git a/libc/sysv/consts/EAI_FAIL.s b/libc/sysv/consts/EAI_FAIL.s new file mode 100644 index 00000000..97173ead --- /dev/null +++ b/libc/sysv/consts/EAI_FAIL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_FAIL -4 4 4 -4 0x2afb diff --git a/libc/sysv/consts/EAI_FAMILY.s b/libc/sysv/consts/EAI_FAMILY.s new file mode 100644 index 00000000..defda633 --- /dev/null +++ b/libc/sysv/consts/EAI_FAMILY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_FAMILY -6 5 5 -6 0x273f diff --git a/libc/sysv/consts/EAI_IDN_ENCODE.s b/libc/sysv/consts/EAI_IDN_ENCODE.s new file mode 100644 index 00000000..fddc4189 --- /dev/null +++ b/libc/sysv/consts/EAI_IDN_ENCODE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_IDN_ENCODE -105 -105 -105 -105 -105 diff --git a/libc/sysv/consts/EAI_INPROGRESS.s b/libc/sysv/consts/EAI_INPROGRESS.s new file mode 100644 index 00000000..58d459bd --- /dev/null +++ b/libc/sysv/consts/EAI_INPROGRESS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_INPROGRESS -100 -100 -100 -100 -100 diff --git a/libc/sysv/consts/EAI_INTR.s b/libc/sysv/consts/EAI_INTR.s new file mode 100644 index 00000000..34b89a24 --- /dev/null +++ b/libc/sysv/consts/EAI_INTR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_INTR -104 -104 -104 -104 -104 diff --git a/libc/sysv/consts/EAI_MEMORY.s b/libc/sysv/consts/EAI_MEMORY.s new file mode 100644 index 00000000..9245a2a9 --- /dev/null +++ b/libc/sysv/consts/EAI_MEMORY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_MEMORY -10 6 6 -10 0x2747 diff --git a/libc/sysv/consts/EAI_NODATA.s b/libc/sysv/consts/EAI_NODATA.s new file mode 100644 index 00000000..788ac4cf --- /dev/null +++ b/libc/sysv/consts/EAI_NODATA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_NODATA -5 7 0 -5 0x2af9 diff --git a/libc/sysv/consts/EAI_NONAME.s b/libc/sysv/consts/EAI_NONAME.s new file mode 100644 index 00000000..46f51dd4 --- /dev/null +++ b/libc/sysv/consts/EAI_NONAME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_NONAME -2 8 8 -2 0x2af9 diff --git a/libc/sysv/consts/EAI_NOTCANCELED.s b/libc/sysv/consts/EAI_NOTCANCELED.s new file mode 100644 index 00000000..51151c68 --- /dev/null +++ b/libc/sysv/consts/EAI_NOTCANCELED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_NOTCANCELED -102 -102 -102 -102 -102 diff --git a/libc/sysv/consts/EAI_OVERFLOW.s b/libc/sysv/consts/EAI_OVERFLOW.s new file mode 100644 index 00000000..7e87f4c9 --- /dev/null +++ b/libc/sysv/consts/EAI_OVERFLOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_OVERFLOW -12 14 14 -14 -12 diff --git a/libc/sysv/consts/EAI_SERVICE.s b/libc/sysv/consts/EAI_SERVICE.s new file mode 100644 index 00000000..cb93165b --- /dev/null +++ b/libc/sysv/consts/EAI_SERVICE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_SERVICE -8 9 9 -8 0x277d diff --git a/libc/sysv/consts/EAI_SOCKTYPE.s b/libc/sysv/consts/EAI_SOCKTYPE.s new file mode 100644 index 00000000..841e28e6 --- /dev/null +++ b/libc/sysv/consts/EAI_SOCKTYPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_SOCKTYPE -7 10 10 -7 0x273c diff --git a/libc/sysv/consts/EAI_SUCCESS.s b/libc/sysv/consts/EAI_SUCCESS.s new file mode 100644 index 00000000..83463b3a --- /dev/null +++ b/libc/sysv/consts/EAI_SUCCESS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_SUCCESS 0 0 0 0 0 diff --git a/libc/sysv/consts/EAI_SYSTEM.s b/libc/sysv/consts/EAI_SYSTEM.s new file mode 100644 index 00000000..ca1bfbea --- /dev/null +++ b/libc/sysv/consts/EAI_SYSTEM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon eai EAI_SYSTEM -11 11 11 -11 -11 diff --git a/libc/sysv/consts/EALREADY.s b/libc/sysv/consts/EALREADY.s new file mode 100644 index 00000000..845733eb --- /dev/null +++ b/libc/sysv/consts/EALREADY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EALREADY 114 37 37 37 0x2735 diff --git a/libc/sysv/consts/EBADE.s b/libc/sysv/consts/EBADE.s new file mode 100644 index 00000000..70cbd0ff --- /dev/null +++ b/libc/sysv/consts/EBADE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EBADE 52 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EBADF.s b/libc/sysv/consts/EBADF.s new file mode 100644 index 00000000..f21112b0 --- /dev/null +++ b/libc/sysv/consts/EBADF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EBADF 9 9 9 9 6 diff --git a/libc/sysv/consts/EBADFD.s b/libc/sysv/consts/EBADFD.s new file mode 100644 index 00000000..f9dbc22d --- /dev/null +++ b/libc/sysv/consts/EBADFD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EBADFD 77 9 9 9 6 diff --git a/libc/sysv/consts/EBADMSG.s b/libc/sysv/consts/EBADMSG.s new file mode 100644 index 00000000..932e38ed --- /dev/null +++ b/libc/sysv/consts/EBADMSG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EBADMSG 74 94 89 92 -1 diff --git a/libc/sysv/consts/EBADR.s b/libc/sysv/consts/EBADR.s new file mode 100644 index 00000000..79616b92 --- /dev/null +++ b/libc/sysv/consts/EBADR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EBADR 53 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EBADRQC.s b/libc/sysv/consts/EBADRQC.s new file mode 100644 index 00000000..6e815b9e --- /dev/null +++ b/libc/sysv/consts/EBADRQC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EBADRQC 56 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EBADSLT.s b/libc/sysv/consts/EBADSLT.s new file mode 100644 index 00000000..0ea7ff24 --- /dev/null +++ b/libc/sysv/consts/EBADSLT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EBADSLT 57 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EBFONT.s b/libc/sysv/consts/EBFONT.s new file mode 100644 index 00000000..44ea5518 --- /dev/null +++ b/libc/sysv/consts/EBFONT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EBFONT 59 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EBUSY.s b/libc/sysv/consts/EBUSY.s new file mode 100644 index 00000000..904f4ab1 --- /dev/null +++ b/libc/sysv/consts/EBUSY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EBUSY 16 16 16 16 170 diff --git a/libc/sysv/consts/ECANCELED.s b/libc/sysv/consts/ECANCELED.s new file mode 100644 index 00000000..14155806 --- /dev/null +++ b/libc/sysv/consts/ECANCELED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ECANCELED 125 89 85 88 -1 diff --git a/libc/sysv/consts/ECHILD.s b/libc/sysv/consts/ECHILD.s new file mode 100644 index 00000000..52d24ec4 --- /dev/null +++ b/libc/sysv/consts/ECHILD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ECHILD 10 10 10 10 128 diff --git a/libc/sysv/consts/ECHO.s b/libc/sysv/consts/ECHO.s new file mode 100644 index 00000000..c87363b2 --- /dev/null +++ b/libc/sysv/consts/ECHO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios ECHO 0b0000000000001000 0b0000000000001000 0b0000000000001000 0b0000000000001000 0b0000000000001000 diff --git a/libc/sysv/consts/ECHOCTL.s b/libc/sysv/consts/ECHOCTL.s new file mode 100644 index 00000000..c046f746 --- /dev/null +++ b/libc/sysv/consts/ECHOCTL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios ECHOCTL 0b0000001000000000 0b0000000001000000 0b0000000001000000 0b0000000001000000 0b0000001000000000 diff --git a/libc/sysv/consts/ECHOE.s b/libc/sysv/consts/ECHOE.s new file mode 100644 index 00000000..6df3526b --- /dev/null +++ b/libc/sysv/consts/ECHOE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios ECHOE 0b0000000000010000 0b0000000000000010 0b0000000000000010 0b0000000000000010 0b0000000000010000 diff --git a/libc/sysv/consts/ECHOK.s b/libc/sysv/consts/ECHOK.s new file mode 100644 index 00000000..2fedcad5 --- /dev/null +++ b/libc/sysv/consts/ECHOK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios ECHOK 0b0000000000100000 0b0000000000000100 0b0000000000000100 0b0000000000000100 0b0000000000100000 diff --git a/libc/sysv/consts/ECHOKE.s b/libc/sysv/consts/ECHOKE.s new file mode 100644 index 00000000..49f37d84 --- /dev/null +++ b/libc/sysv/consts/ECHOKE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios ECHOKE 0b0000100000000000 0b0000000000000001 0b0000000000000001 0b0000000000000001 0b0000100000000000 diff --git a/libc/sysv/consts/ECHONL.s b/libc/sysv/consts/ECHONL.s new file mode 100644 index 00000000..c6e8b31f --- /dev/null +++ b/libc/sysv/consts/ECHONL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios ECHONL 0b0000000001000000 0b0000000000010000 0b0000000000010000 0b0000000000010000 0b0000000001000000 diff --git a/libc/sysv/consts/ECHOPRT.s b/libc/sysv/consts/ECHOPRT.s new file mode 100644 index 00000000..7cb90d69 --- /dev/null +++ b/libc/sysv/consts/ECHOPRT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios ECHOPRT 0b0000010000000000 0b0000000000100000 0b0000000000100000 0b0000000000100000 0b0000010000000000 diff --git a/libc/sysv/consts/ECHRNG.s b/libc/sysv/consts/ECHRNG.s new file mode 100644 index 00000000..452b1d3d --- /dev/null +++ b/libc/sysv/consts/ECHRNG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ECHRNG 44 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ECOMM.s b/libc/sysv/consts/ECOMM.s new file mode 100644 index 00000000..ec6eb531 --- /dev/null +++ b/libc/sysv/consts/ECOMM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ECOMM 70 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ECONNABORTED.s b/libc/sysv/consts/ECONNABORTED.s new file mode 100644 index 00000000..d958a3d6 --- /dev/null +++ b/libc/sysv/consts/ECONNABORTED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ECONNABORTED 103 53 53 53 0x2745 diff --git a/libc/sysv/consts/ECONNREFUSED.s b/libc/sysv/consts/ECONNREFUSED.s new file mode 100644 index 00000000..a8befc7b --- /dev/null +++ b/libc/sysv/consts/ECONNREFUSED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ECONNREFUSED 111 61 61 61 0x274d diff --git a/libc/sysv/consts/ECONNRESET.s b/libc/sysv/consts/ECONNRESET.s new file mode 100644 index 00000000..7c12124b --- /dev/null +++ b/libc/sysv/consts/ECONNRESET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ECONNRESET 104 54 54 54 0x2746 diff --git a/libc/sysv/consts/EDEADLK.s b/libc/sysv/consts/EDEADLK.s new file mode 100644 index 00000000..0f6e7da6 --- /dev/null +++ b/libc/sysv/consts/EDEADLK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EDEADLK 35 11 11 11 1131 diff --git a/libc/sysv/consts/EDESTADDRREQ.s b/libc/sysv/consts/EDESTADDRREQ.s new file mode 100644 index 00000000..b028baf1 --- /dev/null +++ b/libc/sysv/consts/EDESTADDRREQ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EDESTADDRREQ 89 39 39 39 0x2737 diff --git a/libc/sysv/consts/EDOM.s b/libc/sysv/consts/EDOM.s new file mode 100644 index 00000000..c1b45372 --- /dev/null +++ b/libc/sysv/consts/EDOM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EDOM 33 33 33 33 -1 diff --git a/libc/sysv/consts/EDOTDOT.s b/libc/sysv/consts/EDOTDOT.s new file mode 100644 index 00000000..0036e071 --- /dev/null +++ b/libc/sysv/consts/EDOTDOT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EDOTDOT 73 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EDQUOT.s b/libc/sysv/consts/EDQUOT.s new file mode 100644 index 00000000..b60229c0 --- /dev/null +++ b/libc/sysv/consts/EDQUOT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EDQUOT 122 69 69 69 0x2755 diff --git a/libc/sysv/consts/EEXIST.s b/libc/sysv/consts/EEXIST.s new file mode 100644 index 00000000..dc34a558 --- /dev/null +++ b/libc/sysv/consts/EEXIST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EEXIST 17 17 17 17 183 diff --git a/libc/sysv/consts/EFAULT.s b/libc/sysv/consts/EFAULT.s new file mode 100644 index 00000000..69944bc4 --- /dev/null +++ b/libc/sysv/consts/EFAULT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EFAULT 14 14 14 14 487 diff --git a/libc/sysv/consts/EFBIG.s b/libc/sysv/consts/EFBIG.s new file mode 100644 index 00000000..28dfa960 --- /dev/null +++ b/libc/sysv/consts/EFBIG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EFBIG 27 27 27 27 223 diff --git a/libc/sysv/consts/EFD_CLOEXEC.s b/libc/sysv/consts/EFD_CLOEXEC.s new file mode 100644 index 00000000..ce89ac02 --- /dev/null +++ b/libc/sysv/consts/EFD_CLOEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc EFD_CLOEXEC 0x080000 0 0 0 0 diff --git a/libc/sysv/consts/EFD_NONBLOCK.s b/libc/sysv/consts/EFD_NONBLOCK.s new file mode 100644 index 00000000..be33f2e4 --- /dev/null +++ b/libc/sysv/consts/EFD_NONBLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc EFD_NONBLOCK 0x0800 0 0 0 0 diff --git a/libc/sysv/consts/EFD_SEMAPHORE.s b/libc/sysv/consts/EFD_SEMAPHORE.s new file mode 100644 index 00000000..ab7b717f --- /dev/null +++ b/libc/sysv/consts/EFD_SEMAPHORE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc EFD_SEMAPHORE 1 0 0 0 0 diff --git a/libc/sysv/consts/EHOSTDOWN.s b/libc/sysv/consts/EHOSTDOWN.s new file mode 100644 index 00000000..5da90405 --- /dev/null +++ b/libc/sysv/consts/EHOSTDOWN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EHOSTDOWN 112 64 64 64 0x2750 diff --git a/libc/sysv/consts/EHOSTUNREACH.s b/libc/sysv/consts/EHOSTUNREACH.s new file mode 100644 index 00000000..f7307f37 --- /dev/null +++ b/libc/sysv/consts/EHOSTUNREACH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EHOSTUNREACH 113 65 65 65 0x2751 diff --git a/libc/sysv/consts/EHWPOISON.s b/libc/sysv/consts/EHWPOISON.s new file mode 100644 index 00000000..7b99d263 --- /dev/null +++ b/libc/sysv/consts/EHWPOISON.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EHWPOISON 133 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EIDRM.s b/libc/sysv/consts/EIDRM.s new file mode 100644 index 00000000..e7509bfb --- /dev/null +++ b/libc/sysv/consts/EIDRM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EIDRM 43 90 82 89 -1 diff --git a/libc/sysv/consts/EILSEQ.s b/libc/sysv/consts/EILSEQ.s new file mode 100644 index 00000000..994c00f2 --- /dev/null +++ b/libc/sysv/consts/EILSEQ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EILSEQ 84 92 86 84 -1 diff --git a/libc/sysv/consts/EINPROGRESS.s b/libc/sysv/consts/EINPROGRESS.s new file mode 100644 index 00000000..b205c960 --- /dev/null +++ b/libc/sysv/consts/EINPROGRESS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EINPROGRESS 115 36 36 36 0x2734 diff --git a/libc/sysv/consts/EINTR.s b/libc/sysv/consts/EINTR.s new file mode 100644 index 00000000..7db6569a --- /dev/null +++ b/libc/sysv/consts/EINTR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EINTR 4 4 4 4 10004 diff --git a/libc/sysv/consts/EINVAL.s b/libc/sysv/consts/EINVAL.s new file mode 100644 index 00000000..f5714ca3 --- /dev/null +++ b/libc/sysv/consts/EINVAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EINVAL 22 22 22 22 87 diff --git a/libc/sysv/consts/EIO.s b/libc/sysv/consts/EIO.s new file mode 100644 index 00000000..741f067b --- /dev/null +++ b/libc/sysv/consts/EIO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EIO 5 5 5 5 1117 diff --git a/libc/sysv/consts/EISCONN.s b/libc/sysv/consts/EISCONN.s new file mode 100644 index 00000000..c670234e --- /dev/null +++ b/libc/sysv/consts/EISCONN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EISCONN 106 56 56 56 0x2748 diff --git a/libc/sysv/consts/EISDIR.s b/libc/sysv/consts/EISDIR.s new file mode 100644 index 00000000..3106b043 --- /dev/null +++ b/libc/sysv/consts/EISDIR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EISDIR 21 21 21 21 267 diff --git a/libc/sysv/consts/EISNAM.s b/libc/sysv/consts/EISNAM.s new file mode 100644 index 00000000..c77dae6f --- /dev/null +++ b/libc/sysv/consts/EISNAM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EISNAM 120 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EKEYEXPIRED.s b/libc/sysv/consts/EKEYEXPIRED.s new file mode 100644 index 00000000..f1657d34 --- /dev/null +++ b/libc/sysv/consts/EKEYEXPIRED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EKEYEXPIRED 127 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EKEYREJECTED.s b/libc/sysv/consts/EKEYREJECTED.s new file mode 100644 index 00000000..a907a682 --- /dev/null +++ b/libc/sysv/consts/EKEYREJECTED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EKEYREJECTED 129 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EKEYREVOKED.s b/libc/sysv/consts/EKEYREVOKED.s new file mode 100644 index 00000000..702459b9 --- /dev/null +++ b/libc/sysv/consts/EKEYREVOKED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EKEYREVOKED 128 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EL2HLT.s b/libc/sysv/consts/EL2HLT.s new file mode 100644 index 00000000..966e98d7 --- /dev/null +++ b/libc/sysv/consts/EL2HLT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EL2HLT 51 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EL2NSYNC.s b/libc/sysv/consts/EL2NSYNC.s new file mode 100644 index 00000000..37b30005 --- /dev/null +++ b/libc/sysv/consts/EL2NSYNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EL2NSYNC 45 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EL3HLT.s b/libc/sysv/consts/EL3HLT.s new file mode 100644 index 00000000..552d4d27 --- /dev/null +++ b/libc/sysv/consts/EL3HLT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EL3HLT 46 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EL3RST.s b/libc/sysv/consts/EL3RST.s new file mode 100644 index 00000000..74210889 --- /dev/null +++ b/libc/sysv/consts/EL3RST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EL3RST 47 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ELF_NGREG.s b/libc/sysv/consts/ELF_NGREG.s new file mode 100644 index 00000000..35661c42 --- /dev/null +++ b/libc/sysv/consts/ELF_NGREG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ELF_NGREG 27 0 0 0 0 diff --git a/libc/sysv/consts/ELF_PRARGSZ.s b/libc/sysv/consts/ELF_PRARGSZ.s new file mode 100644 index 00000000..cfa84f55 --- /dev/null +++ b/libc/sysv/consts/ELF_PRARGSZ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ELF_PRARGSZ 80 0 0 0 0 diff --git a/libc/sysv/consts/ELIBACC.s b/libc/sysv/consts/ELIBACC.s new file mode 100644 index 00000000..ed62a585 --- /dev/null +++ b/libc/sysv/consts/ELIBACC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ELIBACC 79 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ELIBBAD.s b/libc/sysv/consts/ELIBBAD.s new file mode 100644 index 00000000..33ef5cac --- /dev/null +++ b/libc/sysv/consts/ELIBBAD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ELIBBAD 80 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ELIBEXEC.s b/libc/sysv/consts/ELIBEXEC.s new file mode 100644 index 00000000..7f4371e3 --- /dev/null +++ b/libc/sysv/consts/ELIBEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ELIBEXEC 83 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ELIBMAX.s b/libc/sysv/consts/ELIBMAX.s new file mode 100644 index 00000000..05e56150 --- /dev/null +++ b/libc/sysv/consts/ELIBMAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ELIBMAX 82 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ELIBSCN.s b/libc/sysv/consts/ELIBSCN.s new file mode 100644 index 00000000..07916c97 --- /dev/null +++ b/libc/sysv/consts/ELIBSCN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ELIBSCN 81 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ELNRNG.s b/libc/sysv/consts/ELNRNG.s new file mode 100644 index 00000000..adeff949 --- /dev/null +++ b/libc/sysv/consts/ELNRNG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ELNRNG 48 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ELOOP.s b/libc/sysv/consts/ELOOP.s new file mode 100644 index 00000000..fe47e3b6 --- /dev/null +++ b/libc/sysv/consts/ELOOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ELOOP 40 62 62 62 0x274e diff --git a/libc/sysv/consts/EMEDIUMTYPE.s b/libc/sysv/consts/EMEDIUMTYPE.s new file mode 100644 index 00000000..25ec010e --- /dev/null +++ b/libc/sysv/consts/EMEDIUMTYPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EMEDIUMTYPE 124 -1 -1 86 -1 diff --git a/libc/sysv/consts/EMFILE.s b/libc/sysv/consts/EMFILE.s new file mode 100644 index 00000000..958ff77c --- /dev/null +++ b/libc/sysv/consts/EMFILE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EMFILE 24 24 24 24 336 diff --git a/libc/sysv/consts/EMLINK.s b/libc/sysv/consts/EMLINK.s new file mode 100644 index 00000000..fe9007fd --- /dev/null +++ b/libc/sysv/consts/EMLINK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EMLINK 31 31 31 31 4 diff --git a/libc/sysv/consts/EMPTY.s b/libc/sysv/consts/EMPTY.s new file mode 100644 index 00000000..78e8d315 --- /dev/null +++ b/libc/sysv/consts/EMPTY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc EMPTY 0 0 0 0 0 diff --git a/libc/sysv/consts/EMSGSIZE.s b/libc/sysv/consts/EMSGSIZE.s new file mode 100644 index 00000000..1785ff45 --- /dev/null +++ b/libc/sysv/consts/EMSGSIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EMSGSIZE 90 40 40 40 0x2738 diff --git a/libc/sysv/consts/EMULTIHOP.s b/libc/sysv/consts/EMULTIHOP.s new file mode 100644 index 00000000..46c8f39a --- /dev/null +++ b/libc/sysv/consts/EMULTIHOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EMULTIHOP 72 95 90 -1 -1 diff --git a/libc/sysv/consts/EM_ALTERA_NIOS2.s b/libc/sysv/consts/EM_ALTERA_NIOS2.s new file mode 100644 index 00000000..50530a01 --- /dev/null +++ b/libc/sysv/consts/EM_ALTERA_NIOS2.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc EM_ALTERA_NIOS2 113 0 0 0 0 diff --git a/libc/sysv/consts/EM_LATTICEMICO32.s b/libc/sysv/consts/EM_LATTICEMICO32.s new file mode 100644 index 00000000..8c16a35a --- /dev/null +++ b/libc/sysv/consts/EM_LATTICEMICO32.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc EM_LATTICEMICO32 138 0 0 0 0 diff --git a/libc/sysv/consts/ENAMETOOLONG.s b/libc/sysv/consts/ENAMETOOLONG.s new file mode 100644 index 00000000..19e47e8c --- /dev/null +++ b/libc/sysv/consts/ENAMETOOLONG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENAMETOOLONG 36 63 63 63 0x274f diff --git a/libc/sysv/consts/ENAVAIL.s b/libc/sysv/consts/ENAVAIL.s new file mode 100644 index 00000000..1bd522a9 --- /dev/null +++ b/libc/sysv/consts/ENAVAIL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENAVAIL 119 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ENDRUNDISC.s b/libc/sysv/consts/ENDRUNDISC.s new file mode 100644 index 00000000..1f668b07 --- /dev/null +++ b/libc/sysv/consts/ENDRUNDISC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios ENDRUNDISC 0 0 0 0x9 -1 diff --git a/libc/sysv/consts/ENETDOWN.s b/libc/sysv/consts/ENETDOWN.s new file mode 100644 index 00000000..38d5767c --- /dev/null +++ b/libc/sysv/consts/ENETDOWN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENETDOWN 100 50 50 50 0x2742 diff --git a/libc/sysv/consts/ENETRESET.s b/libc/sysv/consts/ENETRESET.s new file mode 100644 index 00000000..1dbb5414 --- /dev/null +++ b/libc/sysv/consts/ENETRESET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENETRESET 102 52 52 52 0x2744 diff --git a/libc/sysv/consts/ENETUNREACH.s b/libc/sysv/consts/ENETUNREACH.s new file mode 100644 index 00000000..413544ab --- /dev/null +++ b/libc/sysv/consts/ENETUNREACH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENETUNREACH 101 51 51 51 0x2743 diff --git a/libc/sysv/consts/ENFILE.s b/libc/sysv/consts/ENFILE.s new file mode 100644 index 00000000..9780d08c --- /dev/null +++ b/libc/sysv/consts/ENFILE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENFILE 23 23 23 23 331 diff --git a/libc/sysv/consts/ENOANO.s b/libc/sysv/consts/ENOANO.s new file mode 100644 index 00000000..9f5b2f5a --- /dev/null +++ b/libc/sysv/consts/ENOANO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOANO 55 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ENOBUFS.s b/libc/sysv/consts/ENOBUFS.s new file mode 100644 index 00000000..f645a951 --- /dev/null +++ b/libc/sysv/consts/ENOBUFS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOBUFS 105 55 55 55 0x2747 diff --git a/libc/sysv/consts/ENOCSI.s b/libc/sysv/consts/ENOCSI.s new file mode 100644 index 00000000..d43a2711 --- /dev/null +++ b/libc/sysv/consts/ENOCSI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOCSI 50 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ENODATA.s b/libc/sysv/consts/ENODATA.s new file mode 100644 index 00000000..184def16 --- /dev/null +++ b/libc/sysv/consts/ENODATA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENODATA 61 96 -1 -1 -1 diff --git a/libc/sysv/consts/ENODEV.s b/libc/sysv/consts/ENODEV.s new file mode 100644 index 00000000..eb7dfecd --- /dev/null +++ b/libc/sysv/consts/ENODEV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENODEV 19 19 19 19 1200 diff --git a/libc/sysv/consts/ENOENT.s b/libc/sysv/consts/ENOENT.s new file mode 100644 index 00000000..8c34565c --- /dev/null +++ b/libc/sysv/consts/ENOENT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOENT 2 2 2 2 2 diff --git a/libc/sysv/consts/ENOEXEC.s b/libc/sysv/consts/ENOEXEC.s new file mode 100644 index 00000000..78b5924a --- /dev/null +++ b/libc/sysv/consts/ENOEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOEXEC 8 8 8 8 193 diff --git a/libc/sysv/consts/ENOKEY.s b/libc/sysv/consts/ENOKEY.s new file mode 100644 index 00000000..c942cd3e --- /dev/null +++ b/libc/sysv/consts/ENOKEY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOKEY 126 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ENOLCK.s b/libc/sysv/consts/ENOLCK.s new file mode 100644 index 00000000..77e61a0a --- /dev/null +++ b/libc/sysv/consts/ENOLCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOLCK 37 77 77 77 -1 diff --git a/libc/sysv/consts/ENOLINK.s b/libc/sysv/consts/ENOLINK.s new file mode 100644 index 00000000..1bde040d --- /dev/null +++ b/libc/sysv/consts/ENOLINK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOLINK 67 97 91 -1 -1 diff --git a/libc/sysv/consts/ENOMEDIUM.s b/libc/sysv/consts/ENOMEDIUM.s new file mode 100644 index 00000000..225c97d8 --- /dev/null +++ b/libc/sysv/consts/ENOMEDIUM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOMEDIUM 123 -1 -1 85 -1 diff --git a/libc/sysv/consts/ENOMEM.s b/libc/sysv/consts/ENOMEM.s new file mode 100644 index 00000000..742f0bb9 --- /dev/null +++ b/libc/sysv/consts/ENOMEM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOMEM 12 12 12 12 14 diff --git a/libc/sysv/consts/ENOMSG.s b/libc/sysv/consts/ENOMSG.s new file mode 100644 index 00000000..11b7d135 --- /dev/null +++ b/libc/sysv/consts/ENOMSG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOMSG 42 91 83 90 -1 diff --git a/libc/sysv/consts/ENONET.s b/libc/sysv/consts/ENONET.s new file mode 100644 index 00000000..2180227d --- /dev/null +++ b/libc/sysv/consts/ENONET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENONET 64 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ENOPKG.s b/libc/sysv/consts/ENOPKG.s new file mode 100644 index 00000000..51c1eb38 --- /dev/null +++ b/libc/sysv/consts/ENOPKG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOPKG 65 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ENOPROTOOPT.s b/libc/sysv/consts/ENOPROTOOPT.s new file mode 100644 index 00000000..4e4a14a5 --- /dev/null +++ b/libc/sysv/consts/ENOPROTOOPT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOPROTOOPT 92 42 42 42 0x273a diff --git a/libc/sysv/consts/ENOSPC.s b/libc/sysv/consts/ENOSPC.s new file mode 100644 index 00000000..5b2817dc --- /dev/null +++ b/libc/sysv/consts/ENOSPC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOSPC 28 28 28 28 39 diff --git a/libc/sysv/consts/ENOSR.s b/libc/sysv/consts/ENOSR.s new file mode 100644 index 00000000..b1407fcd --- /dev/null +++ b/libc/sysv/consts/ENOSR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOSR 63 98 -1 -1 -1 diff --git a/libc/sysv/consts/ENOSTR.s b/libc/sysv/consts/ENOSTR.s new file mode 100644 index 00000000..6c942dc9 --- /dev/null +++ b/libc/sysv/consts/ENOSTR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOSTR 60 99 -1 -1 -1 diff --git a/libc/sysv/consts/ENOSYS.s b/libc/sysv/consts/ENOSYS.s new file mode 100644 index 00000000..cdbe5b21 --- /dev/null +++ b/libc/sysv/consts/ENOSYS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOSYS 38 78 78 78 1 diff --git a/libc/sysv/consts/ENOTBLK.s b/libc/sysv/consts/ENOTBLK.s new file mode 100644 index 00000000..ebda13cd --- /dev/null +++ b/libc/sysv/consts/ENOTBLK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOTBLK 15 15 15 15 26 diff --git a/libc/sysv/consts/ENOTCONN.s b/libc/sysv/consts/ENOTCONN.s new file mode 100644 index 00000000..65e710d3 --- /dev/null +++ b/libc/sysv/consts/ENOTCONN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOTCONN 107 57 57 57 0x2749 diff --git a/libc/sysv/consts/ENOTDIR.s b/libc/sysv/consts/ENOTDIR.s new file mode 100644 index 00000000..f77f9f23 --- /dev/null +++ b/libc/sysv/consts/ENOTDIR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOTDIR 20 20 20 20 3 diff --git a/libc/sysv/consts/ENOTEMPTY.s b/libc/sysv/consts/ENOTEMPTY.s new file mode 100644 index 00000000..9d069b87 --- /dev/null +++ b/libc/sysv/consts/ENOTEMPTY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOTEMPTY 39 66 66 66 0x2752 diff --git a/libc/sysv/consts/ENOTNAM.s b/libc/sysv/consts/ENOTNAM.s new file mode 100644 index 00000000..d6520d1a --- /dev/null +++ b/libc/sysv/consts/ENOTNAM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOTNAM 118 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ENOTRECOVERABLE.s b/libc/sysv/consts/ENOTRECOVERABLE.s new file mode 100644 index 00000000..c532c64c --- /dev/null +++ b/libc/sysv/consts/ENOTRECOVERABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOTRECOVERABLE 131 104 95 93 -1 diff --git a/libc/sysv/consts/ENOTSOCK.s b/libc/sysv/consts/ENOTSOCK.s new file mode 100644 index 00000000..2201cd54 --- /dev/null +++ b/libc/sysv/consts/ENOTSOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOTSOCK 88 38 38 38 0x2736 diff --git a/libc/sysv/consts/ENOTSUP.s b/libc/sysv/consts/ENOTSUP.s new file mode 100644 index 00000000..8b1eff71 --- /dev/null +++ b/libc/sysv/consts/ENOTSUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOTSUP 95 45 45 91 0x273d diff --git a/libc/sysv/consts/ENOTTY.s b/libc/sysv/consts/ENOTTY.s new file mode 100644 index 00000000..8568c14f --- /dev/null +++ b/libc/sysv/consts/ENOTTY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOTTY 25 25 25 25 1118 diff --git a/libc/sysv/consts/ENOTUNIQ.s b/libc/sysv/consts/ENOTUNIQ.s new file mode 100644 index 00000000..40d8dad5 --- /dev/null +++ b/libc/sysv/consts/ENOTUNIQ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENOTUNIQ 76 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ENXIO.s b/libc/sysv/consts/ENXIO.s new file mode 100644 index 00000000..8f80e478 --- /dev/null +++ b/libc/sysv/consts/ENXIO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ENXIO 6 6 6 6 1112 diff --git a/libc/sysv/consts/EOPNOTSUPP.s b/libc/sysv/consts/EOPNOTSUPP.s new file mode 100644 index 00000000..840c92e3 --- /dev/null +++ b/libc/sysv/consts/EOPNOTSUPP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EOPNOTSUPP 95 102 45 45 0x273d diff --git a/libc/sysv/consts/EOVERFLOW.s b/libc/sysv/consts/EOVERFLOW.s new file mode 100644 index 00000000..778f2e0e --- /dev/null +++ b/libc/sysv/consts/EOVERFLOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EOVERFLOW 75 84 84 87 -1 diff --git a/libc/sysv/consts/EOWNERDEAD.s b/libc/sysv/consts/EOWNERDEAD.s new file mode 100644 index 00000000..e5f4f9b6 --- /dev/null +++ b/libc/sysv/consts/EOWNERDEAD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EOWNERDEAD 130 105 96 94 -1 diff --git a/libc/sysv/consts/EPERM.s b/libc/sysv/consts/EPERM.s new file mode 100644 index 00000000..ea7aa643 --- /dev/null +++ b/libc/sysv/consts/EPERM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EPERM 1 1 1 1 12 diff --git a/libc/sysv/consts/EPFNOSUPPORT.s b/libc/sysv/consts/EPFNOSUPPORT.s new file mode 100644 index 00000000..3209d89d --- /dev/null +++ b/libc/sysv/consts/EPFNOSUPPORT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EPFNOSUPPORT 96 46 46 46 0x273e diff --git a/libc/sysv/consts/EPIPE.s b/libc/sysv/consts/EPIPE.s new file mode 100644 index 00000000..37a35666 --- /dev/null +++ b/libc/sysv/consts/EPIPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EPIPE 32 32 32 32 109 diff --git a/libc/sysv/consts/EPOLLERR.s b/libc/sysv/consts/EPOLLERR.s new file mode 100644 index 00000000..83377ce1 --- /dev/null +++ b/libc/sysv/consts/EPOLLERR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLLERR 8 0 0 0 0 diff --git a/libc/sysv/consts/EPOLLET.s b/libc/sysv/consts/EPOLLET.s new file mode 100644 index 00000000..4ca1ee3e --- /dev/null +++ b/libc/sysv/consts/EPOLLET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLLET 0x80000000 0 0 0 0 diff --git a/libc/sysv/consts/EPOLLEXCLUSIVE.s b/libc/sysv/consts/EPOLLEXCLUSIVE.s new file mode 100644 index 00000000..1a736b54 --- /dev/null +++ b/libc/sysv/consts/EPOLLEXCLUSIVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLLEXCLUSIVE 0x10000000 0 0 0 0 diff --git a/libc/sysv/consts/EPOLLHUP.s b/libc/sysv/consts/EPOLLHUP.s new file mode 100644 index 00000000..b51205a3 --- /dev/null +++ b/libc/sysv/consts/EPOLLHUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLLHUP 0x10 0 0 0 0 diff --git a/libc/sysv/consts/EPOLLIN.s b/libc/sysv/consts/EPOLLIN.s new file mode 100644 index 00000000..e644a80c --- /dev/null +++ b/libc/sysv/consts/EPOLLIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLLIN 1 0 0 0 0 diff --git a/libc/sysv/consts/EPOLLMSG.s b/libc/sysv/consts/EPOLLMSG.s new file mode 100644 index 00000000..65efc02c --- /dev/null +++ b/libc/sysv/consts/EPOLLMSG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLLMSG 0x0400 0 0 0 0 diff --git a/libc/sysv/consts/EPOLLONESHOT.s b/libc/sysv/consts/EPOLLONESHOT.s new file mode 100644 index 00000000..28cb2cc7 --- /dev/null +++ b/libc/sysv/consts/EPOLLONESHOT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLLONESHOT 0x40000000 0 0 0 0 diff --git a/libc/sysv/consts/EPOLLOUT.s b/libc/sysv/consts/EPOLLOUT.s new file mode 100644 index 00000000..dc1a59a3 --- /dev/null +++ b/libc/sysv/consts/EPOLLOUT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLLOUT 4 0 0 0 0 diff --git a/libc/sysv/consts/EPOLLPRI.s b/libc/sysv/consts/EPOLLPRI.s new file mode 100644 index 00000000..e93cbb55 --- /dev/null +++ b/libc/sysv/consts/EPOLLPRI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLLPRI 2 0 0 0 0 diff --git a/libc/sysv/consts/EPOLLRDBAND.s b/libc/sysv/consts/EPOLLRDBAND.s new file mode 100644 index 00000000..e68e983e --- /dev/null +++ b/libc/sysv/consts/EPOLLRDBAND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLLRDBAND 0x80 0 0 0 0 diff --git a/libc/sysv/consts/EPOLLRDHUP.s b/libc/sysv/consts/EPOLLRDHUP.s new file mode 100644 index 00000000..932b4605 --- /dev/null +++ b/libc/sysv/consts/EPOLLRDHUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLLRDHUP 0x2000 0 0 0 0 diff --git a/libc/sysv/consts/EPOLLRDNORM.s b/libc/sysv/consts/EPOLLRDNORM.s new file mode 100644 index 00000000..43e20c05 --- /dev/null +++ b/libc/sysv/consts/EPOLLRDNORM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLLRDNORM 0x40 0 0 0 0 diff --git a/libc/sysv/consts/EPOLLWAKEUP.s b/libc/sysv/consts/EPOLLWAKEUP.s new file mode 100644 index 00000000..8e0b821d --- /dev/null +++ b/libc/sysv/consts/EPOLLWAKEUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLLWAKEUP 0x20000000 0 0 0 0 diff --git a/libc/sysv/consts/EPOLLWRBAND.s b/libc/sysv/consts/EPOLLWRBAND.s new file mode 100644 index 00000000..9484dfa9 --- /dev/null +++ b/libc/sysv/consts/EPOLLWRBAND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLLWRBAND 0x0200 0 0 0 0 diff --git a/libc/sysv/consts/EPOLLWRNORM.s b/libc/sysv/consts/EPOLLWRNORM.s new file mode 100644 index 00000000..22a14d40 --- /dev/null +++ b/libc/sysv/consts/EPOLLWRNORM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLLWRNORM 0x0100 0 0 0 0 diff --git a/libc/sysv/consts/EPOLL_CLOEXEC.s b/libc/sysv/consts/EPOLL_CLOEXEC.s new file mode 100644 index 00000000..8b6c6d78 --- /dev/null +++ b/libc/sysv/consts/EPOLL_CLOEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLL_CLOEXEC 0x080000 0 0 0 0 diff --git a/libc/sysv/consts/EPOLL_CTL_ADD.s b/libc/sysv/consts/EPOLL_CTL_ADD.s new file mode 100644 index 00000000..aba831c8 --- /dev/null +++ b/libc/sysv/consts/EPOLL_CTL_ADD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLL_CTL_ADD 1 0 0 0 0 diff --git a/libc/sysv/consts/EPOLL_CTL_DEL.s b/libc/sysv/consts/EPOLL_CTL_DEL.s new file mode 100644 index 00000000..52b96a93 --- /dev/null +++ b/libc/sysv/consts/EPOLL_CTL_DEL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLL_CTL_DEL 2 0 0 0 0 diff --git a/libc/sysv/consts/EPOLL_CTL_MOD.s b/libc/sysv/consts/EPOLL_CTL_MOD.s new file mode 100644 index 00000000..10fdbdd2 --- /dev/null +++ b/libc/sysv/consts/EPOLL_CTL_MOD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon epoll EPOLL_CTL_MOD 3 0 0 0 0 diff --git a/libc/sysv/consts/EPROTO.s b/libc/sysv/consts/EPROTO.s new file mode 100644 index 00000000..28aa9982 --- /dev/null +++ b/libc/sysv/consts/EPROTO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EPROTO 71 100 92 95 -1 diff --git a/libc/sysv/consts/EPROTONOSUPPORT.s b/libc/sysv/consts/EPROTONOSUPPORT.s new file mode 100644 index 00000000..49c0a99e --- /dev/null +++ b/libc/sysv/consts/EPROTONOSUPPORT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EPROTONOSUPPORT 93 43 43 43 0x273b diff --git a/libc/sysv/consts/EPROTOTYPE.s b/libc/sysv/consts/EPROTOTYPE.s new file mode 100644 index 00000000..0a122735 --- /dev/null +++ b/libc/sysv/consts/EPROTOTYPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EPROTOTYPE 91 41 41 41 0x2739 diff --git a/libc/sysv/consts/ERA.s b/libc/sysv/consts/ERA.s new file mode 100644 index 00000000..9ad3bda2 --- /dev/null +++ b/libc/sysv/consts/ERA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ERA 0x02002c 45 45 0 0 diff --git a/libc/sysv/consts/ERANGE.s b/libc/sysv/consts/ERANGE.s new file mode 100644 index 00000000..75166fab --- /dev/null +++ b/libc/sysv/consts/ERANGE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ERANGE 34 34 34 34 -1 diff --git a/libc/sysv/consts/ERA_D_FMT.s b/libc/sysv/consts/ERA_D_FMT.s new file mode 100644 index 00000000..e134b33a --- /dev/null +++ b/libc/sysv/consts/ERA_D_FMT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ERA_D_FMT 0x02002e 46 46 0 0 diff --git a/libc/sysv/consts/ERA_D_T_FMT.s b/libc/sysv/consts/ERA_D_T_FMT.s new file mode 100644 index 00000000..f715f727 --- /dev/null +++ b/libc/sysv/consts/ERA_D_T_FMT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ERA_D_T_FMT 0x020030 47 47 0 0 diff --git a/libc/sysv/consts/ERA_T_FMT.s b/libc/sysv/consts/ERA_T_FMT.s new file mode 100644 index 00000000..e798e7bc --- /dev/null +++ b/libc/sysv/consts/ERA_T_FMT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ERA_T_FMT 0x020031 48 48 0 0 diff --git a/libc/sysv/consts/EREMCHG.s b/libc/sysv/consts/EREMCHG.s new file mode 100644 index 00000000..0f3605b4 --- /dev/null +++ b/libc/sysv/consts/EREMCHG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EREMCHG 78 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EREMOTE.s b/libc/sysv/consts/EREMOTE.s new file mode 100644 index 00000000..b20d635a --- /dev/null +++ b/libc/sysv/consts/EREMOTE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EREMOTE 66 71 71 71 0x2757 diff --git a/libc/sysv/consts/EREMOTEIO.s b/libc/sysv/consts/EREMOTEIO.s new file mode 100644 index 00000000..b340ccd8 --- /dev/null +++ b/libc/sysv/consts/EREMOTEIO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EREMOTEIO 121 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ERESTART.s b/libc/sysv/consts/ERESTART.s new file mode 100644 index 00000000..032ba37d --- /dev/null +++ b/libc/sysv/consts/ERESTART.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ERESTART 85 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ERFKILL.s b/libc/sysv/consts/ERFKILL.s new file mode 100644 index 00000000..2152bcea --- /dev/null +++ b/libc/sysv/consts/ERFKILL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ERFKILL 132 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EROFS.s b/libc/sysv/consts/EROFS.s new file mode 100644 index 00000000..a16eef20 --- /dev/null +++ b/libc/sysv/consts/EROFS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EROFS 30 30 30 30 6009 diff --git a/libc/sysv/consts/ESHUTDOWN.s b/libc/sysv/consts/ESHUTDOWN.s new file mode 100644 index 00000000..033eab15 --- /dev/null +++ b/libc/sysv/consts/ESHUTDOWN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ESHUTDOWN 108 58 58 58 0x274a diff --git a/libc/sysv/consts/ESOCKTNOSUPPORT.s b/libc/sysv/consts/ESOCKTNOSUPPORT.s new file mode 100644 index 00000000..ba5f2474 --- /dev/null +++ b/libc/sysv/consts/ESOCKTNOSUPPORT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ESOCKTNOSUPPORT 94 44 44 44 0x273c diff --git a/libc/sysv/consts/ESPIPE.s b/libc/sysv/consts/ESPIPE.s new file mode 100644 index 00000000..681879fe --- /dev/null +++ b/libc/sysv/consts/ESPIPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ESPIPE 29 29 29 29 25 diff --git a/libc/sysv/consts/ESRCH.s b/libc/sysv/consts/ESRCH.s new file mode 100644 index 00000000..a020f20e --- /dev/null +++ b/libc/sysv/consts/ESRCH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ESRCH 3 3 3 3 566 diff --git a/libc/sysv/consts/ESRMNT.s b/libc/sysv/consts/ESRMNT.s new file mode 100644 index 00000000..a5241eb8 --- /dev/null +++ b/libc/sysv/consts/ESRMNT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ESRMNT 69 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ESTALE.s b/libc/sysv/consts/ESTALE.s new file mode 100644 index 00000000..4ee310c2 --- /dev/null +++ b/libc/sysv/consts/ESTALE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ESTALE 116 70 70 70 0x2756 diff --git a/libc/sysv/consts/ESTRPIPE.s b/libc/sysv/consts/ESTRPIPE.s new file mode 100644 index 00000000..93aa68ed --- /dev/null +++ b/libc/sysv/consts/ESTRPIPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ESTRPIPE 86 -1 -1 -1 -1 diff --git a/libc/sysv/consts/ETH_P_CUST.s b/libc/sysv/consts/ETH_P_CUST.s new file mode 100644 index 00000000..8a6b4722 --- /dev/null +++ b/libc/sysv/consts/ETH_P_CUST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ETH_P_CUST 0x6006 0 0 0 0 diff --git a/libc/sysv/consts/ETH_P_DDCMP.s b/libc/sysv/consts/ETH_P_DDCMP.s new file mode 100644 index 00000000..ba919452 --- /dev/null +++ b/libc/sysv/consts/ETH_P_DDCMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ETH_P_DDCMP 6 0 0 0 0 diff --git a/libc/sysv/consts/ETH_P_DEC.s b/libc/sysv/consts/ETH_P_DEC.s new file mode 100644 index 00000000..fbfc8d50 --- /dev/null +++ b/libc/sysv/consts/ETH_P_DEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ETH_P_DEC 0x6000 0 0 0 0 diff --git a/libc/sysv/consts/ETH_P_DIAG.s b/libc/sysv/consts/ETH_P_DIAG.s new file mode 100644 index 00000000..37d12015 --- /dev/null +++ b/libc/sysv/consts/ETH_P_DIAG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ETH_P_DIAG 0x6005 0 0 0 0 diff --git a/libc/sysv/consts/ETH_P_DNA_DL.s b/libc/sysv/consts/ETH_P_DNA_DL.s new file mode 100644 index 00000000..4bad522e --- /dev/null +++ b/libc/sysv/consts/ETH_P_DNA_DL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ETH_P_DNA_DL 0x6001 0 0 0 0 diff --git a/libc/sysv/consts/ETH_P_DNA_RC.s b/libc/sysv/consts/ETH_P_DNA_RC.s new file mode 100644 index 00000000..bbf7f936 --- /dev/null +++ b/libc/sysv/consts/ETH_P_DNA_RC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ETH_P_DNA_RC 0x6002 0 0 0 0 diff --git a/libc/sysv/consts/ETH_P_DNA_RT.s b/libc/sysv/consts/ETH_P_DNA_RT.s new file mode 100644 index 00000000..c0406ebe --- /dev/null +++ b/libc/sysv/consts/ETH_P_DNA_RT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ETH_P_DNA_RT 0x6003 0 0 0 0 diff --git a/libc/sysv/consts/ETH_P_IEEE802154.s b/libc/sysv/consts/ETH_P_IEEE802154.s new file mode 100644 index 00000000..2d8af0bb --- /dev/null +++ b/libc/sysv/consts/ETH_P_IEEE802154.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ETH_P_IEEE802154 246 0 0 0 0 diff --git a/libc/sysv/consts/ETH_P_LAT.s b/libc/sysv/consts/ETH_P_LAT.s new file mode 100644 index 00000000..f2b0ee0b --- /dev/null +++ b/libc/sysv/consts/ETH_P_LAT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ETH_P_LAT 0x6004 0 0 0 0 diff --git a/libc/sysv/consts/ETH_P_LOCALTALK.s b/libc/sysv/consts/ETH_P_LOCALTALK.s new file mode 100644 index 00000000..d83b2e5a --- /dev/null +++ b/libc/sysv/consts/ETH_P_LOCALTALK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ETH_P_LOCALTALK 9 0 0 0 0 diff --git a/libc/sysv/consts/ETH_P_PPP_MP.s b/libc/sysv/consts/ETH_P_PPP_MP.s new file mode 100644 index 00000000..8ba5597b --- /dev/null +++ b/libc/sysv/consts/ETH_P_PPP_MP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ETH_P_PPP_MP 8 0 0 0 0 diff --git a/libc/sysv/consts/ETH_P_RARP.s b/libc/sysv/consts/ETH_P_RARP.s new file mode 100644 index 00000000..6e728558 --- /dev/null +++ b/libc/sysv/consts/ETH_P_RARP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ETH_P_RARP 0x8035 0 0 0 0 diff --git a/libc/sysv/consts/ETH_P_SCA.s b/libc/sysv/consts/ETH_P_SCA.s new file mode 100644 index 00000000..ccbf5bb3 --- /dev/null +++ b/libc/sysv/consts/ETH_P_SCA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ETH_P_SCA 0x6007 0 0 0 0 diff --git a/libc/sysv/consts/ETH_P_WAN_PPP.s b/libc/sysv/consts/ETH_P_WAN_PPP.s new file mode 100644 index 00000000..648d03eb --- /dev/null +++ b/libc/sysv/consts/ETH_P_WAN_PPP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ETH_P_WAN_PPP 7 0 0 0 0 diff --git a/libc/sysv/consts/ETIME.s b/libc/sysv/consts/ETIME.s new file mode 100644 index 00000000..f3379b36 --- /dev/null +++ b/libc/sysv/consts/ETIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ETIME 62 101 -1 -1 -1 diff --git a/libc/sysv/consts/ETIMEDOUT.s b/libc/sysv/consts/ETIMEDOUT.s new file mode 100644 index 00000000..b4aee40f --- /dev/null +++ b/libc/sysv/consts/ETIMEDOUT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ETIMEDOUT 110 60 60 60 0x274c diff --git a/libc/sysv/consts/ETOOMANYREFS.s b/libc/sysv/consts/ETOOMANYREFS.s new file mode 100644 index 00000000..67cd3045 --- /dev/null +++ b/libc/sysv/consts/ETOOMANYREFS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ETOOMANYREFS 109 59 59 59 0x274b diff --git a/libc/sysv/consts/ETXTBSY.s b/libc/sysv/consts/ETXTBSY.s new file mode 100644 index 00000000..3d02ca49 --- /dev/null +++ b/libc/sysv/consts/ETXTBSY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno ETXTBSY 26 26 26 26 148 diff --git a/libc/sysv/consts/EUCLEAN.s b/libc/sysv/consts/EUCLEAN.s new file mode 100644 index 00000000..c2ff303b --- /dev/null +++ b/libc/sysv/consts/EUCLEAN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EUCLEAN 117 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EUNATCH.s b/libc/sysv/consts/EUNATCH.s new file mode 100644 index 00000000..86ec2eac --- /dev/null +++ b/libc/sysv/consts/EUNATCH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EUNATCH 49 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EUSERS.s b/libc/sysv/consts/EUSERS.s new file mode 100644 index 00000000..06d7d887 --- /dev/null +++ b/libc/sysv/consts/EUSERS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EUSERS 87 68 68 68 0x2754 diff --git a/libc/sysv/consts/EWOULDBLOCK.s b/libc/sysv/consts/EWOULDBLOCK.s new file mode 100644 index 00000000..4c56bf3d --- /dev/null +++ b/libc/sysv/consts/EWOULDBLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EWOULDBLOCK 11 35 35 35 0x2733 diff --git a/libc/sysv/consts/EXDEV.s b/libc/sysv/consts/EXDEV.s new file mode 100644 index 00000000..38789785 --- /dev/null +++ b/libc/sysv/consts/EXDEV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EXDEV 18 18 18 18 -1 diff --git a/libc/sysv/consts/EXFULL.s b/libc/sysv/consts/EXFULL.s new file mode 100644 index 00000000..ef91b90d --- /dev/null +++ b/libc/sysv/consts/EXFULL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon errno EXFULL 54 -1 -1 -1 -1 diff --git a/libc/sysv/consts/EXIT_FAILURE.s b/libc/sysv/consts/EXIT_FAILURE.s new file mode 100644 index 00000000..e570ddd1 --- /dev/null +++ b/libc/sysv/consts/EXIT_FAILURE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon exit EXIT_FAILURE 1 1 1 1 1 diff --git a/libc/sysv/consts/EXIT_SUCCESS.s b/libc/sysv/consts/EXIT_SUCCESS.s new file mode 100644 index 00000000..90f084e9 --- /dev/null +++ b/libc/sysv/consts/EXIT_SUCCESS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon exit EXIT_SUCCESS 0 0 0 0 0 diff --git a/libc/sysv/consts/EXPR_NEST_MAX.s b/libc/sysv/consts/EXPR_NEST_MAX.s new file mode 100644 index 00000000..a0d737cd --- /dev/null +++ b/libc/sysv/consts/EXPR_NEST_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc EXPR_NEST_MAX 0x20 0x20 0x20 0x20 0 diff --git a/libc/sysv/consts/EXTA.s b/libc/sysv/consts/EXTA.s new file mode 100644 index 00000000..7e252a7b --- /dev/null +++ b/libc/sysv/consts/EXTA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc EXTA 14 0x4b00 0x4b00 0x4b00 0 diff --git a/libc/sysv/consts/EXTB.s b/libc/sysv/consts/EXTB.s new file mode 100644 index 00000000..df08d823 --- /dev/null +++ b/libc/sysv/consts/EXTB.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc EXTB 15 0x9600 0x9600 0x9600 0 diff --git a/libc/sysv/consts/EXTENDED_EXTENDED_IDENTIFY.s b/libc/sysv/consts/EXTENDED_EXTENDED_IDENTIFY.s new file mode 100644 index 00000000..221b265d --- /dev/null +++ b/libc/sysv/consts/EXTENDED_EXTENDED_IDENTIFY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc EXTENDED_EXTENDED_IDENTIFY 2 0 0 0 0 diff --git a/libc/sysv/consts/EXTENDED_MESSAGE.s b/libc/sysv/consts/EXTENDED_MESSAGE.s new file mode 100644 index 00000000..a02e7312 --- /dev/null +++ b/libc/sysv/consts/EXTENDED_MESSAGE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc EXTENDED_MESSAGE 1 0 0 0 0 diff --git a/libc/sysv/consts/EXTENDED_MODIFY_DATA_POINTER.s b/libc/sysv/consts/EXTENDED_MODIFY_DATA_POINTER.s new file mode 100644 index 00000000..8112f6c4 --- /dev/null +++ b/libc/sysv/consts/EXTENDED_MODIFY_DATA_POINTER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc EXTENDED_MODIFY_DATA_POINTER 0 0 0 0 0 diff --git a/libc/sysv/consts/EXTENDED_SDTR.s b/libc/sysv/consts/EXTENDED_SDTR.s new file mode 100644 index 00000000..a4b6386e --- /dev/null +++ b/libc/sysv/consts/EXTENDED_SDTR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc EXTENDED_SDTR 1 0 0 0 0 diff --git a/libc/sysv/consts/EXTENDED_WDTR.s b/libc/sysv/consts/EXTENDED_WDTR.s new file mode 100644 index 00000000..7ec50439 --- /dev/null +++ b/libc/sysv/consts/EXTENDED_WDTR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc EXTENDED_WDTR 3 0 0 0 0 diff --git a/libc/sysv/consts/EXTPROC.s b/libc/sysv/consts/EXTPROC.s new file mode 100644 index 00000000..01d406ad --- /dev/null +++ b/libc/sysv/consts/EXTPROC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios EXTPROC 65536 0b0000100000000000 0b0000100000000000 0b0000100000000000 65536 diff --git a/libc/sysv/consts/EX_CANTCREAT.s b/libc/sysv/consts/EX_CANTCREAT.s new file mode 100644 index 00000000..1f4bc993 --- /dev/null +++ b/libc/sysv/consts/EX_CANTCREAT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX_CANTCREAT 73 73 73 73 73 diff --git a/libc/sysv/consts/EX_CONFIG.s b/libc/sysv/consts/EX_CONFIG.s new file mode 100644 index 00000000..1e5e74da --- /dev/null +++ b/libc/sysv/consts/EX_CONFIG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX_CONFIG 78 78 78 78 78 diff --git a/libc/sysv/consts/EX_DATAERR.s b/libc/sysv/consts/EX_DATAERR.s new file mode 100644 index 00000000..a742ebdd --- /dev/null +++ b/libc/sysv/consts/EX_DATAERR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX_DATAERR 65 65 65 65 65 diff --git a/libc/sysv/consts/EX_IOERR.s b/libc/sysv/consts/EX_IOERR.s new file mode 100644 index 00000000..3ecc4228 --- /dev/null +++ b/libc/sysv/consts/EX_IOERR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX_IOERR 74 74 74 74 74 diff --git a/libc/sysv/consts/EX_NOHOST.s b/libc/sysv/consts/EX_NOHOST.s new file mode 100644 index 00000000..d81366ae --- /dev/null +++ b/libc/sysv/consts/EX_NOHOST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX_NOHOST 68 68 68 68 68 diff --git a/libc/sysv/consts/EX_NOINPUT.s b/libc/sysv/consts/EX_NOINPUT.s new file mode 100644 index 00000000..a9cf0f7d --- /dev/null +++ b/libc/sysv/consts/EX_NOINPUT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX_NOINPUT 66 66 66 66 66 diff --git a/libc/sysv/consts/EX_NOPERM.s b/libc/sysv/consts/EX_NOPERM.s new file mode 100644 index 00000000..b0407693 --- /dev/null +++ b/libc/sysv/consts/EX_NOPERM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX_NOPERM 77 77 77 77 77 diff --git a/libc/sysv/consts/EX_NOUSER.s b/libc/sysv/consts/EX_NOUSER.s new file mode 100644 index 00000000..3ec775de --- /dev/null +++ b/libc/sysv/consts/EX_NOUSER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX_NOUSER 67 67 67 67 67 diff --git a/libc/sysv/consts/EX_OK.s b/libc/sysv/consts/EX_OK.s new file mode 100644 index 00000000..aef05e54 --- /dev/null +++ b/libc/sysv/consts/EX_OK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX_OK 0 0 0 0 0 diff --git a/libc/sysv/consts/EX_OSERR.s b/libc/sysv/consts/EX_OSERR.s new file mode 100644 index 00000000..a7557ddd --- /dev/null +++ b/libc/sysv/consts/EX_OSERR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX_OSERR 71 71 71 71 71 diff --git a/libc/sysv/consts/EX_OSFILE.s b/libc/sysv/consts/EX_OSFILE.s new file mode 100644 index 00000000..010d5dec --- /dev/null +++ b/libc/sysv/consts/EX_OSFILE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX_OSFILE 72 72 72 72 72 diff --git a/libc/sysv/consts/EX_PROTOCOL.s b/libc/sysv/consts/EX_PROTOCOL.s new file mode 100644 index 00000000..77168e3c --- /dev/null +++ b/libc/sysv/consts/EX_PROTOCOL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX_PROTOCOL 76 76 76 76 76 diff --git a/libc/sysv/consts/EX_SOFTWARE.s b/libc/sysv/consts/EX_SOFTWARE.s new file mode 100644 index 00000000..d3a62c8f --- /dev/null +++ b/libc/sysv/consts/EX_SOFTWARE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX_SOFTWARE 70 70 70 70 70 diff --git a/libc/sysv/consts/EX_TEMPFAIL.s b/libc/sysv/consts/EX_TEMPFAIL.s new file mode 100644 index 00000000..fd0176cc --- /dev/null +++ b/libc/sysv/consts/EX_TEMPFAIL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX_TEMPFAIL 75 75 75 75 75 diff --git a/libc/sysv/consts/EX_UNAVAILABLE.s b/libc/sysv/consts/EX_UNAVAILABLE.s new file mode 100644 index 00000000..d62a522d --- /dev/null +++ b/libc/sysv/consts/EX_UNAVAILABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX_UNAVAILABLE 69 69 69 69 69 diff --git a/libc/sysv/consts/EX_USAGE.s b/libc/sysv/consts/EX_USAGE.s new file mode 100644 index 00000000..9bd3a468 --- /dev/null +++ b/libc/sysv/consts/EX_USAGE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX_USAGE 64 64 64 64 64 diff --git a/libc/sysv/consts/EX__BASE.s b/libc/sysv/consts/EX__BASE.s new file mode 100644 index 00000000..7b709152 --- /dev/null +++ b/libc/sysv/consts/EX__BASE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX__BASE 64 64 64 64 64 diff --git a/libc/sysv/consts/EX__MAX.s b/libc/sysv/consts/EX__MAX.s new file mode 100644 index 00000000..254959a6 --- /dev/null +++ b/libc/sysv/consts/EX__MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ex EX__MAX 78 78 78 78 78 diff --git a/libc/sysv/consts/FALLOC_FL_COLLAPSE_RANGE.s b/libc/sysv/consts/FALLOC_FL_COLLAPSE_RANGE.s new file mode 100644 index 00000000..dc7e8fa8 --- /dev/null +++ b/libc/sysv/consts/FALLOC_FL_COLLAPSE_RANGE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FALLOC_FL_COLLAPSE_RANGE 0x08 -1 -1 -1 -1 diff --git a/libc/sysv/consts/FALLOC_FL_INSERT_RANGE.s b/libc/sysv/consts/FALLOC_FL_INSERT_RANGE.s new file mode 100644 index 00000000..775bea9c --- /dev/null +++ b/libc/sysv/consts/FALLOC_FL_INSERT_RANGE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FALLOC_FL_INSERT_RANGE 0x20 -1 -1 -1 -1 diff --git a/libc/sysv/consts/FALLOC_FL_KEEP_SIZE.s b/libc/sysv/consts/FALLOC_FL_KEEP_SIZE.s new file mode 100644 index 00000000..d9403c17 --- /dev/null +++ b/libc/sysv/consts/FALLOC_FL_KEEP_SIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FALLOC_FL_KEEP_SIZE 0x01 -1 -1 -1 -1 diff --git a/libc/sysv/consts/FALLOC_FL_NO_HIDE_STALE.s b/libc/sysv/consts/FALLOC_FL_NO_HIDE_STALE.s new file mode 100644 index 00000000..600ac5f0 --- /dev/null +++ b/libc/sysv/consts/FALLOC_FL_NO_HIDE_STALE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FALLOC_FL_NO_HIDE_STALE 0x04 -1 -1 -1 -1 diff --git a/libc/sysv/consts/FALLOC_FL_PUNCH_HOLE.s b/libc/sysv/consts/FALLOC_FL_PUNCH_HOLE.s new file mode 100644 index 00000000..4a4f7ff0 --- /dev/null +++ b/libc/sysv/consts/FALLOC_FL_PUNCH_HOLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FALLOC_FL_PUNCH_HOLE 0x02 -1 -1 -1 -1 diff --git a/libc/sysv/consts/FALLOC_FL_UNSHARE_RANGE.s b/libc/sysv/consts/FALLOC_FL_UNSHARE_RANGE.s new file mode 100644 index 00000000..c15572cb --- /dev/null +++ b/libc/sysv/consts/FALLOC_FL_UNSHARE_RANGE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FALLOC_FL_UNSHARE_RANGE 0x40 -1 -1 -1 -1 diff --git a/libc/sysv/consts/FALLOC_FL_ZERO_RANGE.s b/libc/sysv/consts/FALLOC_FL_ZERO_RANGE.s new file mode 100644 index 00000000..bd956ef7 --- /dev/null +++ b/libc/sysv/consts/FALLOC_FL_ZERO_RANGE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FALLOC_FL_ZERO_RANGE 0x10 -1 -1 -1 0x000980C8 diff --git a/libc/sysv/consts/FANOTIFY_METADATA_VERSION.s b/libc/sysv/consts/FANOTIFY_METADATA_VERSION.s new file mode 100644 index 00000000..4086c97f --- /dev/null +++ b/libc/sysv/consts/FANOTIFY_METADATA_VERSION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FANOTIFY_METADATA_VERSION 3 0 0 0 0 diff --git a/libc/sysv/consts/FAN_ACCESS.s b/libc/sysv/consts/FAN_ACCESS.s new file mode 100644 index 00000000..c27b5b7d --- /dev/null +++ b/libc/sysv/consts/FAN_ACCESS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_ACCESS 1 0 0 0 0 diff --git a/libc/sysv/consts/FAN_ACCESS_PERM.s b/libc/sysv/consts/FAN_ACCESS_PERM.s new file mode 100644 index 00000000..2b1a8705 --- /dev/null +++ b/libc/sysv/consts/FAN_ACCESS_PERM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_ACCESS_PERM 0x020000 0 0 0 0 diff --git a/libc/sysv/consts/FAN_ALLOW.s b/libc/sysv/consts/FAN_ALLOW.s new file mode 100644 index 00000000..8b20b554 --- /dev/null +++ b/libc/sysv/consts/FAN_ALLOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_ALLOW 1 0 0 0 0 diff --git a/libc/sysv/consts/FAN_ALL_CLASS_BITS.s b/libc/sysv/consts/FAN_ALL_CLASS_BITS.s new file mode 100644 index 00000000..df3429f4 --- /dev/null +++ b/libc/sysv/consts/FAN_ALL_CLASS_BITS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_ALL_CLASS_BITS 12 0 0 0 0 diff --git a/libc/sysv/consts/FAN_ALL_EVENTS.s b/libc/sysv/consts/FAN_ALL_EVENTS.s new file mode 100644 index 00000000..bf110d81 --- /dev/null +++ b/libc/sysv/consts/FAN_ALL_EVENTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_ALL_EVENTS 59 0 0 0 0 diff --git a/libc/sysv/consts/FAN_ALL_INIT_FLAGS.s b/libc/sysv/consts/FAN_ALL_INIT_FLAGS.s new file mode 100644 index 00000000..c4faaa07 --- /dev/null +++ b/libc/sysv/consts/FAN_ALL_INIT_FLAGS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_ALL_INIT_FLAGS 63 0 0 0 0 diff --git a/libc/sysv/consts/FAN_ALL_MARK_FLAGS.s b/libc/sysv/consts/FAN_ALL_MARK_FLAGS.s new file mode 100644 index 00000000..6143eaa3 --- /dev/null +++ b/libc/sysv/consts/FAN_ALL_MARK_FLAGS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_ALL_MARK_FLAGS 255 0 0 0 0 diff --git a/libc/sysv/consts/FAN_ALL_OUTGOING_EVENTS.s b/libc/sysv/consts/FAN_ALL_OUTGOING_EVENTS.s new file mode 100644 index 00000000..aa176244 --- /dev/null +++ b/libc/sysv/consts/FAN_ALL_OUTGOING_EVENTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_ALL_OUTGOING_EVENTS 0x03403b 0 0 0 0 diff --git a/libc/sysv/consts/FAN_ALL_PERM_EVENTS.s b/libc/sysv/consts/FAN_ALL_PERM_EVENTS.s new file mode 100644 index 00000000..434aa6fc --- /dev/null +++ b/libc/sysv/consts/FAN_ALL_PERM_EVENTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_ALL_PERM_EVENTS 0x030000 0 0 0 0 diff --git a/libc/sysv/consts/FAN_CLASS_CONTENT.s b/libc/sysv/consts/FAN_CLASS_CONTENT.s new file mode 100644 index 00000000..804ab235 --- /dev/null +++ b/libc/sysv/consts/FAN_CLASS_CONTENT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_CLASS_CONTENT 4 0 0 0 0 diff --git a/libc/sysv/consts/FAN_CLASS_NOTIF.s b/libc/sysv/consts/FAN_CLASS_NOTIF.s new file mode 100644 index 00000000..842b919b --- /dev/null +++ b/libc/sysv/consts/FAN_CLASS_NOTIF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_CLASS_NOTIF 0 0 0 0 0 diff --git a/libc/sysv/consts/FAN_CLASS_PRE_CONTENT.s b/libc/sysv/consts/FAN_CLASS_PRE_CONTENT.s new file mode 100644 index 00000000..c37f828d --- /dev/null +++ b/libc/sysv/consts/FAN_CLASS_PRE_CONTENT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_CLASS_PRE_CONTENT 8 0 0 0 0 diff --git a/libc/sysv/consts/FAN_CLOEXEC.s b/libc/sysv/consts/FAN_CLOEXEC.s new file mode 100644 index 00000000..9085e607 --- /dev/null +++ b/libc/sysv/consts/FAN_CLOEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_CLOEXEC 1 0 0 0 0 diff --git a/libc/sysv/consts/FAN_CLOSE.s b/libc/sysv/consts/FAN_CLOSE.s new file mode 100644 index 00000000..145f4ca1 --- /dev/null +++ b/libc/sysv/consts/FAN_CLOSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_CLOSE 24 0 0 0 0 diff --git a/libc/sysv/consts/FAN_CLOSE_NOWRITE.s b/libc/sysv/consts/FAN_CLOSE_NOWRITE.s new file mode 100644 index 00000000..7c4aec12 --- /dev/null +++ b/libc/sysv/consts/FAN_CLOSE_NOWRITE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_CLOSE_NOWRITE 0x10 0 0 0 0 diff --git a/libc/sysv/consts/FAN_CLOSE_WRITE.s b/libc/sysv/consts/FAN_CLOSE_WRITE.s new file mode 100644 index 00000000..7af5fe84 --- /dev/null +++ b/libc/sysv/consts/FAN_CLOSE_WRITE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_CLOSE_WRITE 8 0 0 0 0 diff --git a/libc/sysv/consts/FAN_DENY.s b/libc/sysv/consts/FAN_DENY.s new file mode 100644 index 00000000..546f2733 --- /dev/null +++ b/libc/sysv/consts/FAN_DENY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_DENY 2 0 0 0 0 diff --git a/libc/sysv/consts/FAN_EVENT_METADATA_LEN.s b/libc/sysv/consts/FAN_EVENT_METADATA_LEN.s new file mode 100644 index 00000000..e698c27c --- /dev/null +++ b/libc/sysv/consts/FAN_EVENT_METADATA_LEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_EVENT_METADATA_LEN 24 0 0 0 0 diff --git a/libc/sysv/consts/FAN_EVENT_ON_CHILD.s b/libc/sysv/consts/FAN_EVENT_ON_CHILD.s new file mode 100644 index 00000000..fc568fb3 --- /dev/null +++ b/libc/sysv/consts/FAN_EVENT_ON_CHILD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_EVENT_ON_CHILD 0x08000000 0 0 0 0 diff --git a/libc/sysv/consts/FAN_MARK_ADD.s b/libc/sysv/consts/FAN_MARK_ADD.s new file mode 100644 index 00000000..7324132c --- /dev/null +++ b/libc/sysv/consts/FAN_MARK_ADD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_MARK_ADD 1 0 0 0 0 diff --git a/libc/sysv/consts/FAN_MARK_DONT_FOLLOW.s b/libc/sysv/consts/FAN_MARK_DONT_FOLLOW.s new file mode 100644 index 00000000..f8285f99 --- /dev/null +++ b/libc/sysv/consts/FAN_MARK_DONT_FOLLOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_MARK_DONT_FOLLOW 4 0 0 0 0 diff --git a/libc/sysv/consts/FAN_MARK_FLUSH.s b/libc/sysv/consts/FAN_MARK_FLUSH.s new file mode 100644 index 00000000..8fe990d6 --- /dev/null +++ b/libc/sysv/consts/FAN_MARK_FLUSH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_MARK_FLUSH 0x80 0 0 0 0 diff --git a/libc/sysv/consts/FAN_MARK_IGNORED_MASK.s b/libc/sysv/consts/FAN_MARK_IGNORED_MASK.s new file mode 100644 index 00000000..c686abb7 --- /dev/null +++ b/libc/sysv/consts/FAN_MARK_IGNORED_MASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_MARK_IGNORED_MASK 0x20 0 0 0 0 diff --git a/libc/sysv/consts/FAN_MARK_IGNORED_SURV_MODIFY.s b/libc/sysv/consts/FAN_MARK_IGNORED_SURV_MODIFY.s new file mode 100644 index 00000000..335c81dd --- /dev/null +++ b/libc/sysv/consts/FAN_MARK_IGNORED_SURV_MODIFY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_MARK_IGNORED_SURV_MODIFY 0x40 0 0 0 0 diff --git a/libc/sysv/consts/FAN_MARK_MOUNT.s b/libc/sysv/consts/FAN_MARK_MOUNT.s new file mode 100644 index 00000000..ef3a433f --- /dev/null +++ b/libc/sysv/consts/FAN_MARK_MOUNT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_MARK_MOUNT 0x10 0 0 0 0 diff --git a/libc/sysv/consts/FAN_MARK_ONLYDIR.s b/libc/sysv/consts/FAN_MARK_ONLYDIR.s new file mode 100644 index 00000000..4ff7e24f --- /dev/null +++ b/libc/sysv/consts/FAN_MARK_ONLYDIR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_MARK_ONLYDIR 8 0 0 0 0 diff --git a/libc/sysv/consts/FAN_MARK_REMOVE.s b/libc/sysv/consts/FAN_MARK_REMOVE.s new file mode 100644 index 00000000..9eb01c97 --- /dev/null +++ b/libc/sysv/consts/FAN_MARK_REMOVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_MARK_REMOVE 2 0 0 0 0 diff --git a/libc/sysv/consts/FAN_MODIFY.s b/libc/sysv/consts/FAN_MODIFY.s new file mode 100644 index 00000000..4b23d73f --- /dev/null +++ b/libc/sysv/consts/FAN_MODIFY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_MODIFY 2 0 0 0 0 diff --git a/libc/sysv/consts/FAN_NOFD.s b/libc/sysv/consts/FAN_NOFD.s new file mode 100644 index 00000000..001f9523 --- /dev/null +++ b/libc/sysv/consts/FAN_NOFD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_NOFD -1 0 0 0 0 diff --git a/libc/sysv/consts/FAN_NONBLOCK.s b/libc/sysv/consts/FAN_NONBLOCK.s new file mode 100644 index 00000000..8bcf4321 --- /dev/null +++ b/libc/sysv/consts/FAN_NONBLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_NONBLOCK 2 0 0 0 0 diff --git a/libc/sysv/consts/FAN_ONDIR.s b/libc/sysv/consts/FAN_ONDIR.s new file mode 100644 index 00000000..7f70e2a2 --- /dev/null +++ b/libc/sysv/consts/FAN_ONDIR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_ONDIR 0x40000000 0 0 0 0 diff --git a/libc/sysv/consts/FAN_OPEN.s b/libc/sysv/consts/FAN_OPEN.s new file mode 100644 index 00000000..cb232338 --- /dev/null +++ b/libc/sysv/consts/FAN_OPEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_OPEN 0x20 0 0 0 0 diff --git a/libc/sysv/consts/FAN_OPEN_PERM.s b/libc/sysv/consts/FAN_OPEN_PERM.s new file mode 100644 index 00000000..90d9c859 --- /dev/null +++ b/libc/sysv/consts/FAN_OPEN_PERM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_OPEN_PERM 0x010000 0 0 0 0 diff --git a/libc/sysv/consts/FAN_Q_OVERFLOW.s b/libc/sysv/consts/FAN_Q_OVERFLOW.s new file mode 100644 index 00000000..c23361cf --- /dev/null +++ b/libc/sysv/consts/FAN_Q_OVERFLOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_Q_OVERFLOW 0x4000 0 0 0 0 diff --git a/libc/sysv/consts/FAN_UNLIMITED_MARKS.s b/libc/sysv/consts/FAN_UNLIMITED_MARKS.s new file mode 100644 index 00000000..896d50f6 --- /dev/null +++ b/libc/sysv/consts/FAN_UNLIMITED_MARKS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_UNLIMITED_MARKS 0x20 0 0 0 0 diff --git a/libc/sysv/consts/FAN_UNLIMITED_QUEUE.s b/libc/sysv/consts/FAN_UNLIMITED_QUEUE.s new file mode 100644 index 00000000..4ed7accc --- /dev/null +++ b/libc/sysv/consts/FAN_UNLIMITED_QUEUE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fan FAN_UNLIMITED_QUEUE 0x10 0 0 0 0 diff --git a/libc/sysv/consts/FAPPEND.s b/libc/sysv/consts/FAPPEND.s new file mode 100644 index 00000000..8cbcd26e --- /dev/null +++ b/libc/sysv/consts/FAPPEND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FAPPEND 0x0400 8 8 8 0 diff --git a/libc/sysv/consts/FASYNC.s b/libc/sysv/consts/FASYNC.s new file mode 100644 index 00000000..56ba34bf --- /dev/null +++ b/libc/sysv/consts/FASYNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FASYNC 0x2000 0x40 0x40 0x40 0 diff --git a/libc/sysv/consts/FDPIC_FUNCPTRS.s b/libc/sysv/consts/FDPIC_FUNCPTRS.s new file mode 100644 index 00000000..99e29705 --- /dev/null +++ b/libc/sysv/consts/FDPIC_FUNCPTRS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon prsnlty FDPIC_FUNCPTRS 0x0080000 -1 -1 -1 -1 diff --git a/libc/sysv/consts/FD_CLOEXEC.s b/libc/sysv/consts/FD_CLOEXEC.s new file mode 100644 index 00000000..c936e139 --- /dev/null +++ b/libc/sysv/consts/FD_CLOEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl3 FD_CLOEXEC 1 1 1 1 1 diff --git a/libc/sysv/consts/FD_SETSIZE.s b/libc/sysv/consts/FD_SETSIZE.s new file mode 100644 index 00000000..b0afcd76 --- /dev/null +++ b/libc/sysv/consts/FD_SETSIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon select FD_SETSIZE 0x0400 0x0400 0x0400 0x0400 0x0400 diff --git a/libc/sysv/consts/FE_ALL_EXCEPT.s b/libc/sysv/consts/FE_ALL_EXCEPT.s new file mode 100644 index 00000000..0a4d348b --- /dev/null +++ b/libc/sysv/consts/FE_ALL_EXCEPT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FE_ALL_EXCEPT 61 63 63 63 0 diff --git a/libc/sysv/consts/FE_DIVBYZERO.s b/libc/sysv/consts/FE_DIVBYZERO.s new file mode 100644 index 00000000..92f4cbe3 --- /dev/null +++ b/libc/sysv/consts/FE_DIVBYZERO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FE_DIVBYZERO 4 4 4 4 0 diff --git a/libc/sysv/consts/FE_DOWNWARD.s b/libc/sysv/consts/FE_DOWNWARD.s new file mode 100644 index 00000000..7d0b30bb --- /dev/null +++ b/libc/sysv/consts/FE_DOWNWARD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FE_DOWNWARD 0x0400 0x0400 0x0400 0x0400 0 diff --git a/libc/sysv/consts/FE_INEXACT.s b/libc/sysv/consts/FE_INEXACT.s new file mode 100644 index 00000000..ebc1da30 --- /dev/null +++ b/libc/sysv/consts/FE_INEXACT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FE_INEXACT 0x20 0x20 0x20 0x20 0 diff --git a/libc/sysv/consts/FE_INVALID.s b/libc/sysv/consts/FE_INVALID.s new file mode 100644 index 00000000..7ff01cdc --- /dev/null +++ b/libc/sysv/consts/FE_INVALID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FE_INVALID 1 1 1 1 0 diff --git a/libc/sysv/consts/FE_OVERFLOW.s b/libc/sysv/consts/FE_OVERFLOW.s new file mode 100644 index 00000000..747ebdb2 --- /dev/null +++ b/libc/sysv/consts/FE_OVERFLOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FE_OVERFLOW 8 8 8 8 0 diff --git a/libc/sysv/consts/FE_TONEAREST.s b/libc/sysv/consts/FE_TONEAREST.s new file mode 100644 index 00000000..ef56cbbe --- /dev/null +++ b/libc/sysv/consts/FE_TONEAREST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FE_TONEAREST 0 0 0 0 0 diff --git a/libc/sysv/consts/FE_TOWARDZERO.s b/libc/sysv/consts/FE_TOWARDZERO.s new file mode 100644 index 00000000..ffb54c75 --- /dev/null +++ b/libc/sysv/consts/FE_TOWARDZERO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FE_TOWARDZERO 0x0c00 0x0c00 0x0c00 0x0c00 0 diff --git a/libc/sysv/consts/FE_UNDERFLOW.s b/libc/sysv/consts/FE_UNDERFLOW.s new file mode 100644 index 00000000..a680d118 --- /dev/null +++ b/libc/sysv/consts/FE_UNDERFLOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FE_UNDERFLOW 0x10 0x10 0x10 0x10 0 diff --git a/libc/sysv/consts/FE_UPWARD.s b/libc/sysv/consts/FE_UPWARD.s new file mode 100644 index 00000000..250db60d --- /dev/null +++ b/libc/sysv/consts/FE_UPWARD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FE_UPWARD 0x0800 0x0800 0x0800 0x0800 0 diff --git a/libc/sysv/consts/FF0.s b/libc/sysv/consts/FF0.s new file mode 100644 index 00000000..10c991f5 --- /dev/null +++ b/libc/sysv/consts/FF0.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios FF0 0b0000000000000000 0b000000000000000000 0b000000000000000000 0 0b0000000000000000 diff --git a/libc/sysv/consts/FF1.s b/libc/sysv/consts/FF1.s new file mode 100644 index 00000000..0545cca2 --- /dev/null +++ b/libc/sysv/consts/FF1.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios FF1 0b1000000000000000 0b000100000000000000 0b000100000000000000 0 0b1000000000000000 diff --git a/libc/sysv/consts/FFDLY.s b/libc/sysv/consts/FFDLY.s new file mode 100644 index 00000000..7e7af9c8 --- /dev/null +++ b/libc/sysv/consts/FFDLY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios FFDLY 0b1000000000000000 0b000100000000000000 0b000100000000000000 0 0b1000000000000000 diff --git a/libc/sysv/consts/FFSYNC.s b/libc/sysv/consts/FFSYNC.s new file mode 100644 index 00000000..b8899b04 --- /dev/null +++ b/libc/sysv/consts/FFSYNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FFSYNC 0x101000 0x80 0x80 0x80 0 diff --git a/libc/sysv/consts/FIFOTYPE.s b/libc/sysv/consts/FIFOTYPE.s new file mode 100644 index 00000000..0edbd61d --- /dev/null +++ b/libc/sysv/consts/FIFOTYPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FIFOTYPE 54 54 54 54 0 diff --git a/libc/sysv/consts/FILENAME_MAX.s b/libc/sysv/consts/FILENAME_MAX.s new file mode 100644 index 00000000..de6014c3 --- /dev/null +++ b/libc/sysv/consts/FILENAME_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FILENAME_MAX 0x1000 0x0400 0x0400 0x0400 0 diff --git a/libc/sysv/consts/FIOASYNC.s b/libc/sysv/consts/FIOASYNC.s new file mode 100644 index 00000000..d48558a8 --- /dev/null +++ b/libc/sysv/consts/FIOASYNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ioctl FIOASYNC 0x5452 0x8004667d 0x8004667d 0x8004667d 0x8004667d diff --git a/libc/sysv/consts/FIOGETOWN.s b/libc/sysv/consts/FIOGETOWN.s new file mode 100644 index 00000000..1373cafb --- /dev/null +++ b/libc/sysv/consts/FIOGETOWN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FIOGETOWN 0x8903 0x4004667b 0x4004667b 0x4004667b 0 diff --git a/libc/sysv/consts/FIONBIO.s b/libc/sysv/consts/FIONBIO.s new file mode 100644 index 00000000..b4eef920 --- /dev/null +++ b/libc/sysv/consts/FIONBIO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ioctl FIONBIO 0x5421 0x8004667e 0x8004667e 0x8004667e 0x8004667e diff --git a/libc/sysv/consts/FIONREAD.s b/libc/sysv/consts/FIONREAD.s new file mode 100644 index 00000000..cef1e2d5 --- /dev/null +++ b/libc/sysv/consts/FIONREAD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ioctl FIONREAD 0x541b 0x4004667f 0x4004667f 0x4004667f 0x4004667f diff --git a/libc/sysv/consts/FIOSETOWN.s b/libc/sysv/consts/FIOSETOWN.s new file mode 100644 index 00000000..6dbc244c --- /dev/null +++ b/libc/sysv/consts/FIOSETOWN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FIOSETOWN 0x8901 0x8004667c 0x8004667c 0x8004667c 0 diff --git a/libc/sysv/consts/FLUSHO.s b/libc/sysv/consts/FLUSHO.s new file mode 100644 index 00000000..267e7b2f --- /dev/null +++ b/libc/sysv/consts/FLUSHO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios FLUSHO 0b0001000000000000 8388608 8388608 8388608 0b0001000000000000 diff --git a/libc/sysv/consts/FMAXEXP.s b/libc/sysv/consts/FMAXEXP.s new file mode 100644 index 00000000..053bb79b --- /dev/null +++ b/libc/sysv/consts/FMAXEXP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FMAXEXP 0x80 0 0 0 0 diff --git a/libc/sysv/consts/FMINEXP.s b/libc/sysv/consts/FMINEXP.s new file mode 100644 index 00000000..9e60b443 --- /dev/null +++ b/libc/sysv/consts/FMINEXP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FMINEXP -125 0 0 0 0 diff --git a/libc/sysv/consts/FNDELAY.s b/libc/sysv/consts/FNDELAY.s new file mode 100644 index 00000000..e0bf79fa --- /dev/null +++ b/libc/sysv/consts/FNDELAY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FNDELAY 0x0800 4 4 4 0 diff --git a/libc/sysv/consts/FNM_NOSYS.s b/libc/sysv/consts/FNM_NOSYS.s new file mode 100644 index 00000000..62ccf674 --- /dev/null +++ b/libc/sysv/consts/FNM_NOSYS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FNM_NOSYS -1 -1 -1 2 0 diff --git a/libc/sysv/consts/FNONBLOCK.s b/libc/sysv/consts/FNONBLOCK.s new file mode 100644 index 00000000..35158cfc --- /dev/null +++ b/libc/sysv/consts/FNONBLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FNONBLOCK 0x0800 4 4 4 0 diff --git a/libc/sysv/consts/FOPEN_MAX.s b/libc/sysv/consts/FOPEN_MAX.s new file mode 100644 index 00000000..e9a111fe --- /dev/null +++ b/libc/sysv/consts/FOPEN_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FOPEN_MAX 0x10 20 20 20 0 diff --git a/libc/sysv/consts/FORMAT_UNIT.s b/libc/sysv/consts/FORMAT_UNIT.s new file mode 100644 index 00000000..3c5aa15d --- /dev/null +++ b/libc/sysv/consts/FORMAT_UNIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FORMAT_UNIT 4 0 0 0 0 diff --git a/libc/sysv/consts/FORM_C.s b/libc/sysv/consts/FORM_C.s new file mode 100644 index 00000000..c97a51c1 --- /dev/null +++ b/libc/sysv/consts/FORM_C.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FORM_C 3 3 3 3 0 diff --git a/libc/sysv/consts/FORM_N.s b/libc/sysv/consts/FORM_N.s new file mode 100644 index 00000000..50df33db --- /dev/null +++ b/libc/sysv/consts/FORM_N.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FORM_N 1 1 1 1 0 diff --git a/libc/sysv/consts/FORM_T.s b/libc/sysv/consts/FORM_T.s new file mode 100644 index 00000000..1f5f9ab5 --- /dev/null +++ b/libc/sysv/consts/FORM_T.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FORM_T 2 2 2 2 0 diff --git a/libc/sysv/consts/FPE_FLTDIV.s b/libc/sysv/consts/FPE_FLTDIV.s new file mode 100644 index 00000000..d55e34d8 --- /dev/null +++ b/libc/sysv/consts/FPE_FLTDIV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FPE_FLTDIV 3 1 3 3 0 diff --git a/libc/sysv/consts/FPE_FLTINV.s b/libc/sysv/consts/FPE_FLTINV.s new file mode 100644 index 00000000..7d1ae9f4 --- /dev/null +++ b/libc/sysv/consts/FPE_FLTINV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FPE_FLTINV 7 5 7 7 0 diff --git a/libc/sysv/consts/FPE_FLTOVF.s b/libc/sysv/consts/FPE_FLTOVF.s new file mode 100644 index 00000000..d1294364 --- /dev/null +++ b/libc/sysv/consts/FPE_FLTOVF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FPE_FLTOVF 4 2 4 4 0 diff --git a/libc/sysv/consts/FPE_FLTRES.s b/libc/sysv/consts/FPE_FLTRES.s new file mode 100644 index 00000000..3cae8905 --- /dev/null +++ b/libc/sysv/consts/FPE_FLTRES.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FPE_FLTRES 6 4 6 6 0 diff --git a/libc/sysv/consts/FPE_FLTSUB.s b/libc/sysv/consts/FPE_FLTSUB.s new file mode 100644 index 00000000..98811b75 --- /dev/null +++ b/libc/sysv/consts/FPE_FLTSUB.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FPE_FLTSUB 8 6 8 8 0 diff --git a/libc/sysv/consts/FPE_FLTUND.s b/libc/sysv/consts/FPE_FLTUND.s new file mode 100644 index 00000000..0bb4427f --- /dev/null +++ b/libc/sysv/consts/FPE_FLTUND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FPE_FLTUND 5 3 5 5 0 diff --git a/libc/sysv/consts/FPE_INTDIV.s b/libc/sysv/consts/FPE_INTDIV.s new file mode 100644 index 00000000..9638c7ee --- /dev/null +++ b/libc/sysv/consts/FPE_INTDIV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FPE_INTDIV 1 7 2 1 0 diff --git a/libc/sysv/consts/FPE_INTOVF.s b/libc/sysv/consts/FPE_INTOVF.s new file mode 100644 index 00000000..a2dfcc73 --- /dev/null +++ b/libc/sysv/consts/FPE_INTOVF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FPE_INTOVF 2 8 1 2 0 diff --git a/libc/sysv/consts/FSETLOCKING_BYCALLER.s b/libc/sysv/consts/FSETLOCKING_BYCALLER.s new file mode 100644 index 00000000..bf4b9549 --- /dev/null +++ b/libc/sysv/consts/FSETLOCKING_BYCALLER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FSETLOCKING_BYCALLER 2 0 0 0 0 diff --git a/libc/sysv/consts/FSETLOCKING_INTERNAL.s b/libc/sysv/consts/FSETLOCKING_INTERNAL.s new file mode 100644 index 00000000..6bbbf322 --- /dev/null +++ b/libc/sysv/consts/FSETLOCKING_INTERNAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FSETLOCKING_INTERNAL 1 0 0 0 0 diff --git a/libc/sysv/consts/FSETLOCKING_QUERY.s b/libc/sysv/consts/FSETLOCKING_QUERY.s new file mode 100644 index 00000000..4ac351f5 --- /dev/null +++ b/libc/sysv/consts/FSETLOCKING_QUERY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FSETLOCKING_QUERY 0 0 0 0 0 diff --git a/libc/sysv/consts/FTW_CHDIR.s b/libc/sysv/consts/FTW_CHDIR.s new file mode 100644 index 00000000..e9a32439 --- /dev/null +++ b/libc/sysv/consts/FTW_CHDIR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FTW_CHDIR 4 8 8 8 0 diff --git a/libc/sysv/consts/FTW_D.s b/libc/sysv/consts/FTW_D.s new file mode 100644 index 00000000..858addc3 --- /dev/null +++ b/libc/sysv/consts/FTW_D.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FTW_D 1 1 1 1 0 diff --git a/libc/sysv/consts/FTW_DEPTH.s b/libc/sysv/consts/FTW_DEPTH.s new file mode 100644 index 00000000..768154f6 --- /dev/null +++ b/libc/sysv/consts/FTW_DEPTH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FTW_DEPTH 8 4 4 4 0 diff --git a/libc/sysv/consts/FTW_DNR.s b/libc/sysv/consts/FTW_DNR.s new file mode 100644 index 00000000..32a875c4 --- /dev/null +++ b/libc/sysv/consts/FTW_DNR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FTW_DNR 2 2 2 2 0 diff --git a/libc/sysv/consts/FTW_DP.s b/libc/sysv/consts/FTW_DP.s new file mode 100644 index 00000000..41332d29 --- /dev/null +++ b/libc/sysv/consts/FTW_DP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FTW_DP 5 3 3 3 0 diff --git a/libc/sysv/consts/FTW_F.s b/libc/sysv/consts/FTW_F.s new file mode 100644 index 00000000..fa05e208 --- /dev/null +++ b/libc/sysv/consts/FTW_F.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FTW_F 0 0 0 0 0 diff --git a/libc/sysv/consts/FTW_MOUNT.s b/libc/sysv/consts/FTW_MOUNT.s new file mode 100644 index 00000000..880dfe23 --- /dev/null +++ b/libc/sysv/consts/FTW_MOUNT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FTW_MOUNT 2 2 2 2 0 diff --git a/libc/sysv/consts/FTW_NS.s b/libc/sysv/consts/FTW_NS.s new file mode 100644 index 00000000..d8e9ab15 --- /dev/null +++ b/libc/sysv/consts/FTW_NS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FTW_NS 3 4 4 4 0 diff --git a/libc/sysv/consts/FTW_PHYS.s b/libc/sysv/consts/FTW_PHYS.s new file mode 100644 index 00000000..ec30bb93 --- /dev/null +++ b/libc/sysv/consts/FTW_PHYS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FTW_PHYS 1 1 1 1 0 diff --git a/libc/sysv/consts/FTW_SL.s b/libc/sysv/consts/FTW_SL.s new file mode 100644 index 00000000..e03233d6 --- /dev/null +++ b/libc/sysv/consts/FTW_SL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FTW_SL 4 5 5 5 0 diff --git a/libc/sysv/consts/FTW_SLN.s b/libc/sysv/consts/FTW_SLN.s new file mode 100644 index 00000000..91ac90db --- /dev/null +++ b/libc/sysv/consts/FTW_SLN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FTW_SLN 6 6 6 6 0 diff --git a/libc/sysv/consts/FUTEX_PRIVATE_FLAG.s b/libc/sysv/consts/FUTEX_PRIVATE_FLAG.s new file mode 100644 index 00000000..d29d53fb --- /dev/null +++ b/libc/sysv/consts/FUTEX_PRIVATE_FLAG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FUTEX_PRIVATE_FLAG 0 0 0 0x80 0 diff --git a/libc/sysv/consts/FUTEX_REQUEUE.s b/libc/sysv/consts/FUTEX_REQUEUE.s new file mode 100644 index 00000000..2efe8ff8 --- /dev/null +++ b/libc/sysv/consts/FUTEX_REQUEUE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FUTEX_REQUEUE 0 0 0 3 0 diff --git a/libc/sysv/consts/FUTEX_REQUEUE_PRIVATE.s b/libc/sysv/consts/FUTEX_REQUEUE_PRIVATE.s new file mode 100644 index 00000000..593f460e --- /dev/null +++ b/libc/sysv/consts/FUTEX_REQUEUE_PRIVATE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FUTEX_REQUEUE_PRIVATE 0 0 0 131 0 diff --git a/libc/sysv/consts/FUTEX_WAIT.s b/libc/sysv/consts/FUTEX_WAIT.s new file mode 100644 index 00000000..629812eb --- /dev/null +++ b/libc/sysv/consts/FUTEX_WAIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FUTEX_WAIT 0 0 0 1 0 diff --git a/libc/sysv/consts/FUTEX_WAIT_PRIVATE.s b/libc/sysv/consts/FUTEX_WAIT_PRIVATE.s new file mode 100644 index 00000000..3b018ba0 --- /dev/null +++ b/libc/sysv/consts/FUTEX_WAIT_PRIVATE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FUTEX_WAIT_PRIVATE 0 0 0 129 0 diff --git a/libc/sysv/consts/FUTEX_WAKE.s b/libc/sysv/consts/FUTEX_WAKE.s new file mode 100644 index 00000000..3e6d571b --- /dev/null +++ b/libc/sysv/consts/FUTEX_WAKE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FUTEX_WAKE 0 0 0 2 0 diff --git a/libc/sysv/consts/FUTEX_WAKE_PRIVATE.s b/libc/sysv/consts/FUTEX_WAKE_PRIVATE.s new file mode 100644 index 00000000..ec3e0955 --- /dev/null +++ b/libc/sysv/consts/FUTEX_WAKE_PRIVATE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc FUTEX_WAKE_PRIVATE 0 0 0 130 0 diff --git a/libc/sysv/consts/F_DUPFD.s b/libc/sysv/consts/F_DUPFD.s new file mode 100644 index 00000000..a32d5144 --- /dev/null +++ b/libc/sysv/consts/F_DUPFD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl2 F_DUPFD 0 0 0 0 0 diff --git a/libc/sysv/consts/F_DUPFD_CLOEXEC.s b/libc/sysv/consts/F_DUPFD_CLOEXEC.s new file mode 100644 index 00000000..8d2fee6d --- /dev/null +++ b/libc/sysv/consts/F_DUPFD_CLOEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_DUPFD_CLOEXEC 0x0406 67 17 10 0 diff --git a/libc/sysv/consts/F_GETFD.s b/libc/sysv/consts/F_GETFD.s new file mode 100644 index 00000000..79344d5d --- /dev/null +++ b/libc/sysv/consts/F_GETFD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl2 F_GETFD 1 1 1 1 1 diff --git a/libc/sysv/consts/F_GETFL.s b/libc/sysv/consts/F_GETFL.s new file mode 100644 index 00000000..38457279 --- /dev/null +++ b/libc/sysv/consts/F_GETFL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl2 F_GETFL 3 3 3 3 3 diff --git a/libc/sysv/consts/F_GETLEASE.s b/libc/sysv/consts/F_GETLEASE.s new file mode 100644 index 00000000..da07befd --- /dev/null +++ b/libc/sysv/consts/F_GETLEASE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_GETLEASE 0x0401 0 0 0 0 diff --git a/libc/sysv/consts/F_GETLK.s b/libc/sysv/consts/F_GETLK.s new file mode 100644 index 00000000..4eab3fab --- /dev/null +++ b/libc/sysv/consts/F_GETLK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_GETLK 5 7 11 7 0 diff --git a/libc/sysv/consts/F_GETLK64.s b/libc/sysv/consts/F_GETLK64.s new file mode 100644 index 00000000..f4d03322 --- /dev/null +++ b/libc/sysv/consts/F_GETLK64.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_GETLK64 5 0 0 0 0 diff --git a/libc/sysv/consts/F_GETOWN.s b/libc/sysv/consts/F_GETOWN.s new file mode 100644 index 00000000..a84db7b7 --- /dev/null +++ b/libc/sysv/consts/F_GETOWN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl2 F_GETOWN 9 5 5 5 0 diff --git a/libc/sysv/consts/F_GETOWN_EX.s b/libc/sysv/consts/F_GETOWN_EX.s new file mode 100644 index 00000000..c22818d6 --- /dev/null +++ b/libc/sysv/consts/F_GETOWN_EX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_GETOWN_EX 0x10 0 0 0 0 diff --git a/libc/sysv/consts/F_GETPIPE_SZ.s b/libc/sysv/consts/F_GETPIPE_SZ.s new file mode 100644 index 00000000..b3735fd9 --- /dev/null +++ b/libc/sysv/consts/F_GETPIPE_SZ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_GETPIPE_SZ 0x0408 0 0 0 0 diff --git a/libc/sysv/consts/F_GETSIG.s b/libc/sysv/consts/F_GETSIG.s new file mode 100644 index 00000000..b0874e4b --- /dev/null +++ b/libc/sysv/consts/F_GETSIG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_GETSIG 11 0 0 0 0 diff --git a/libc/sysv/consts/F_LOCK.s b/libc/sysv/consts/F_LOCK.s new file mode 100644 index 00000000..66914073 --- /dev/null +++ b/libc/sysv/consts/F_LOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_LOCK 1 1 1 1 0 diff --git a/libc/sysv/consts/F_NOTIFY.s b/libc/sysv/consts/F_NOTIFY.s new file mode 100644 index 00000000..72ab2f5b --- /dev/null +++ b/libc/sysv/consts/F_NOTIFY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_NOTIFY 0x0402 0 0 0 0 diff --git a/libc/sysv/consts/F_OFD_GETLK.s b/libc/sysv/consts/F_OFD_GETLK.s new file mode 100644 index 00000000..7a101f16 --- /dev/null +++ b/libc/sysv/consts/F_OFD_GETLK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_OFD_GETLK 36 0 0 0 0 diff --git a/libc/sysv/consts/F_OFD_SETLK.s b/libc/sysv/consts/F_OFD_SETLK.s new file mode 100644 index 00000000..907cd722 --- /dev/null +++ b/libc/sysv/consts/F_OFD_SETLK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_OFD_SETLK 37 0 0 0 0 diff --git a/libc/sysv/consts/F_OFD_SETLKW.s b/libc/sysv/consts/F_OFD_SETLKW.s new file mode 100644 index 00000000..a2f8e1fe --- /dev/null +++ b/libc/sysv/consts/F_OFD_SETLKW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_OFD_SETLKW 38 0 0 0 0 diff --git a/libc/sysv/consts/F_OK.s b/libc/sysv/consts/F_OK.s new file mode 100644 index 00000000..4b806f76 --- /dev/null +++ b/libc/sysv/consts/F_OK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon access F_OK 0 0 0 0 0 diff --git a/libc/sysv/consts/F_RDLCK.s b/libc/sysv/consts/F_RDLCK.s new file mode 100644 index 00000000..c878f431 --- /dev/null +++ b/libc/sysv/consts/F_RDLCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_RDLCK 0 1 1 1 0 diff --git a/libc/sysv/consts/F_SETFD.s b/libc/sysv/consts/F_SETFD.s new file mode 100644 index 00000000..014d8359 --- /dev/null +++ b/libc/sysv/consts/F_SETFD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl2 F_SETFD 2 2 2 2 2 diff --git a/libc/sysv/consts/F_SETFL.s b/libc/sysv/consts/F_SETFL.s new file mode 100644 index 00000000..8d3c9be1 --- /dev/null +++ b/libc/sysv/consts/F_SETFL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl2 F_SETFL 4 4 4 4 4 diff --git a/libc/sysv/consts/F_SETLEASE.s b/libc/sysv/consts/F_SETLEASE.s new file mode 100644 index 00000000..ed52d95c --- /dev/null +++ b/libc/sysv/consts/F_SETLEASE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_SETLEASE 0x0400 0 0 0 0 diff --git a/libc/sysv/consts/F_SETLK.s b/libc/sysv/consts/F_SETLK.s new file mode 100644 index 00000000..da367f80 --- /dev/null +++ b/libc/sysv/consts/F_SETLK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_SETLK 6 8 12 8 0 diff --git a/libc/sysv/consts/F_SETLK64.s b/libc/sysv/consts/F_SETLK64.s new file mode 100644 index 00000000..32df50a4 --- /dev/null +++ b/libc/sysv/consts/F_SETLK64.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_SETLK64 6 0 0 0 0 diff --git a/libc/sysv/consts/F_SETLKW.s b/libc/sysv/consts/F_SETLKW.s new file mode 100644 index 00000000..89ef6a45 --- /dev/null +++ b/libc/sysv/consts/F_SETLKW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_SETLKW 7 9 13 9 0 diff --git a/libc/sysv/consts/F_SETLKW64.s b/libc/sysv/consts/F_SETLKW64.s new file mode 100644 index 00000000..d791b2a4 --- /dev/null +++ b/libc/sysv/consts/F_SETLKW64.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_SETLKW64 7 0 0 0 0 diff --git a/libc/sysv/consts/F_SETOWN.s b/libc/sysv/consts/F_SETOWN.s new file mode 100644 index 00000000..436d273b --- /dev/null +++ b/libc/sysv/consts/F_SETOWN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl2 F_SETOWN 8 6 6 6 0 diff --git a/libc/sysv/consts/F_SETOWN_EX.s b/libc/sysv/consts/F_SETOWN_EX.s new file mode 100644 index 00000000..3570c540 --- /dev/null +++ b/libc/sysv/consts/F_SETOWN_EX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_SETOWN_EX 15 0 0 0 0 diff --git a/libc/sysv/consts/F_SETPIPE_SZ.s b/libc/sysv/consts/F_SETPIPE_SZ.s new file mode 100644 index 00000000..71246be0 --- /dev/null +++ b/libc/sysv/consts/F_SETPIPE_SZ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_SETPIPE_SZ 0x0407 0 0 0 0 diff --git a/libc/sysv/consts/F_SETSIG.s b/libc/sysv/consts/F_SETSIG.s new file mode 100644 index 00000000..11468144 --- /dev/null +++ b/libc/sysv/consts/F_SETSIG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_SETSIG 10 0 0 0 0 diff --git a/libc/sysv/consts/F_TEST.s b/libc/sysv/consts/F_TEST.s new file mode 100644 index 00000000..c2d60690 --- /dev/null +++ b/libc/sysv/consts/F_TEST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_TEST 3 3 3 3 0 diff --git a/libc/sysv/consts/F_TLOCK.s b/libc/sysv/consts/F_TLOCK.s new file mode 100644 index 00000000..727d14c1 --- /dev/null +++ b/libc/sysv/consts/F_TLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_TLOCK 2 2 2 2 0 diff --git a/libc/sysv/consts/F_ULOCK.s b/libc/sysv/consts/F_ULOCK.s new file mode 100644 index 00000000..93c0bec0 --- /dev/null +++ b/libc/sysv/consts/F_ULOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_ULOCK 0 0 0 0 0 diff --git a/libc/sysv/consts/F_UNLCK.s b/libc/sysv/consts/F_UNLCK.s new file mode 100644 index 00000000..4f8973ad --- /dev/null +++ b/libc/sysv/consts/F_UNLCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_UNLCK 2 2 2 2 0 diff --git a/libc/sysv/consts/F_WRLCK.s b/libc/sysv/consts/F_WRLCK.s new file mode 100644 index 00000000..12d4df4f --- /dev/null +++ b/libc/sysv/consts/F_WRLCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fcntl F_WRLCK 1 3 3 3 0 diff --git a/libc/sysv/consts/GLOB_ABORTED.s b/libc/sysv/consts/GLOB_ABORTED.s new file mode 100644 index 00000000..2c5a7356 --- /dev/null +++ b/libc/sysv/consts/GLOB_ABORTED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon glob GLOB_ABORTED 2 -2 -2 -2 0 diff --git a/libc/sysv/consts/GLOB_APPEND.s b/libc/sysv/consts/GLOB_APPEND.s new file mode 100644 index 00000000..51eb9235 --- /dev/null +++ b/libc/sysv/consts/GLOB_APPEND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon glob GLOB_APPEND 0x20 1 1 1 0 diff --git a/libc/sysv/consts/GLOB_DOOFFS.s b/libc/sysv/consts/GLOB_DOOFFS.s new file mode 100644 index 00000000..21265c62 --- /dev/null +++ b/libc/sysv/consts/GLOB_DOOFFS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon glob GLOB_DOOFFS 8 2 2 2 0 diff --git a/libc/sysv/consts/GLOB_ERR.s b/libc/sysv/consts/GLOB_ERR.s new file mode 100644 index 00000000..54e71bfd --- /dev/null +++ b/libc/sysv/consts/GLOB_ERR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon glob GLOB_ERR 1 4 4 4 0 diff --git a/libc/sysv/consts/GLOB_MARK.s b/libc/sysv/consts/GLOB_MARK.s new file mode 100644 index 00000000..e59b22a4 --- /dev/null +++ b/libc/sysv/consts/GLOB_MARK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon glob GLOB_MARK 2 8 8 8 0 diff --git a/libc/sysv/consts/GLOB_NOCHECK.s b/libc/sysv/consts/GLOB_NOCHECK.s new file mode 100644 index 00000000..fd1e2341 --- /dev/null +++ b/libc/sysv/consts/GLOB_NOCHECK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon glob GLOB_NOCHECK 0x10 0x10 0x10 0x10 0 diff --git a/libc/sysv/consts/GLOB_NOESCAPE.s b/libc/sysv/consts/GLOB_NOESCAPE.s new file mode 100644 index 00000000..649644ae --- /dev/null +++ b/libc/sysv/consts/GLOB_NOESCAPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon glob GLOB_NOESCAPE 0x40 0x2000 0x2000 0x1000 0 diff --git a/libc/sysv/consts/GLOB_NOMATCH.s b/libc/sysv/consts/GLOB_NOMATCH.s new file mode 100644 index 00000000..19cba762 --- /dev/null +++ b/libc/sysv/consts/GLOB_NOMATCH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon glob GLOB_NOMATCH 3 -3 -3 -3 0 diff --git a/libc/sysv/consts/GLOB_NOSORT.s b/libc/sysv/consts/GLOB_NOSORT.s new file mode 100644 index 00000000..67112d81 --- /dev/null +++ b/libc/sysv/consts/GLOB_NOSORT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon glob GLOB_NOSORT 4 0x20 0x20 0x20 0 diff --git a/libc/sysv/consts/GLOB_NOSPACE.s b/libc/sysv/consts/GLOB_NOSPACE.s new file mode 100644 index 00000000..15e3a0e8 --- /dev/null +++ b/libc/sysv/consts/GLOB_NOSPACE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon glob GLOB_NOSPACE 1 -1 -1 -1 0 diff --git a/libc/sysv/consts/GLOB_NOSYS.s b/libc/sysv/consts/GLOB_NOSYS.s new file mode 100644 index 00000000..2d74a61d --- /dev/null +++ b/libc/sysv/consts/GLOB_NOSYS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon glob GLOB_NOSYS 4 -4 -4 -4 0 diff --git a/libc/sysv/consts/GOOD.s b/libc/sysv/consts/GOOD.s new file mode 100644 index 00000000..23cc789a --- /dev/null +++ b/libc/sysv/consts/GOOD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc GOOD 0 0 0 0 0 diff --git a/libc/sysv/consts/GRPQUOTA.s b/libc/sysv/consts/GRPQUOTA.s new file mode 100644 index 00000000..a327c318 --- /dev/null +++ b/libc/sysv/consts/GRPQUOTA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc GRPQUOTA 1 1 1 1 0 diff --git a/libc/sysv/consts/H4DISC.s b/libc/sysv/consts/H4DISC.s new file mode 100644 index 00000000..c38bcfd1 --- /dev/null +++ b/libc/sysv/consts/H4DISC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios H4DISC 0 0 0x7 0 -1 diff --git a/libc/sysv/consts/HARDWARE_ERROR.s b/libc/sysv/consts/HARDWARE_ERROR.s new file mode 100644 index 00000000..ded9750a --- /dev/null +++ b/libc/sysv/consts/HARDWARE_ERROR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc HARDWARE_ERROR 4 0 0 0 0 diff --git a/libc/sysv/consts/HEAD_OF_QUEUE_TAG.s b/libc/sysv/consts/HEAD_OF_QUEUE_TAG.s new file mode 100644 index 00000000..5cf4071a --- /dev/null +++ b/libc/sysv/consts/HEAD_OF_QUEUE_TAG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc HEAD_OF_QUEUE_TAG 33 0 0 0 0 diff --git a/libc/sysv/consts/HOST_NAME_MAX.s b/libc/sysv/consts/HOST_NAME_MAX.s new file mode 100644 index 00000000..ec1459b7 --- /dev/null +++ b/libc/sysv/consts/HOST_NAME_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc HOST_NAME_MAX 0x40 0 0 255 0 diff --git a/libc/sysv/consts/HOST_NOT_FOUND.s b/libc/sysv/consts/HOST_NOT_FOUND.s new file mode 100644 index 00000000..70e93597 --- /dev/null +++ b/libc/sysv/consts/HOST_NOT_FOUND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc HOST_NOT_FOUND 1 1 1 1 0x2af9 diff --git a/libc/sysv/consts/HUPCL.s b/libc/sysv/consts/HUPCL.s new file mode 100644 index 00000000..bde6fa0a --- /dev/null +++ b/libc/sysv/consts/HUPCL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc HUPCL 0x0400 0x4000 0x4000 0x4000 0 diff --git a/libc/sysv/consts/ICANON.s b/libc/sysv/consts/ICANON.s new file mode 100644 index 00000000..9ffbf8ce --- /dev/null +++ b/libc/sysv/consts/ICANON.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios ICANON 0b0000000000000010 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000000000010 diff --git a/libc/sysv/consts/ICMP6_DST_UNREACH.s b/libc/sysv/consts/ICMP6_DST_UNREACH.s new file mode 100644 index 00000000..82a8a1db --- /dev/null +++ b/libc/sysv/consts/ICMP6_DST_UNREACH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_DST_UNREACH 1 1 1 1 0 diff --git a/libc/sysv/consts/ICMP6_DST_UNREACH_ADDR.s b/libc/sysv/consts/ICMP6_DST_UNREACH_ADDR.s new file mode 100644 index 00000000..6dda91a2 --- /dev/null +++ b/libc/sysv/consts/ICMP6_DST_UNREACH_ADDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_DST_UNREACH_ADDR 3 3 3 3 3 diff --git a/libc/sysv/consts/ICMP6_DST_UNREACH_ADMIN.s b/libc/sysv/consts/ICMP6_DST_UNREACH_ADMIN.s new file mode 100644 index 00000000..bc138d9a --- /dev/null +++ b/libc/sysv/consts/ICMP6_DST_UNREACH_ADMIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_DST_UNREACH_ADMIN 1 1 1 1 1 diff --git a/libc/sysv/consts/ICMP6_DST_UNREACH_BEYONDSCOPE.s b/libc/sysv/consts/ICMP6_DST_UNREACH_BEYONDSCOPE.s new file mode 100644 index 00000000..4a10c6f0 --- /dev/null +++ b/libc/sysv/consts/ICMP6_DST_UNREACH_BEYONDSCOPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_DST_UNREACH_BEYONDSCOPE 2 2 2 2 2 diff --git a/libc/sysv/consts/ICMP6_DST_UNREACH_NOPORT.s b/libc/sysv/consts/ICMP6_DST_UNREACH_NOPORT.s new file mode 100644 index 00000000..2bc0973e --- /dev/null +++ b/libc/sysv/consts/ICMP6_DST_UNREACH_NOPORT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_DST_UNREACH_NOPORT 4 4 4 4 4 diff --git a/libc/sysv/consts/ICMP6_DST_UNREACH_NOROUTE.s b/libc/sysv/consts/ICMP6_DST_UNREACH_NOROUTE.s new file mode 100644 index 00000000..4d1c9c4c --- /dev/null +++ b/libc/sysv/consts/ICMP6_DST_UNREACH_NOROUTE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_DST_UNREACH_NOROUTE 0 0 0 0 0 diff --git a/libc/sysv/consts/ICMP6_ECHO_REPLY.s b/libc/sysv/consts/ICMP6_ECHO_REPLY.s new file mode 100644 index 00000000..937b873e --- /dev/null +++ b/libc/sysv/consts/ICMP6_ECHO_REPLY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_ECHO_REPLY 129 129 129 129 0 diff --git a/libc/sysv/consts/ICMP6_ECHO_REQUEST.s b/libc/sysv/consts/ICMP6_ECHO_REQUEST.s new file mode 100644 index 00000000..9834807b --- /dev/null +++ b/libc/sysv/consts/ICMP6_ECHO_REQUEST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_ECHO_REQUEST 0x80 0x80 0x80 0x80 0 diff --git a/libc/sysv/consts/ICMP6_FILTER.s b/libc/sysv/consts/ICMP6_FILTER.s new file mode 100644 index 00000000..6f866f78 --- /dev/null +++ b/libc/sysv/consts/ICMP6_FILTER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_FILTER 1 18 18 18 0 diff --git a/libc/sysv/consts/ICMP6_INFOMSG_MASK.s b/libc/sysv/consts/ICMP6_INFOMSG_MASK.s new file mode 100644 index 00000000..5dbfabff --- /dev/null +++ b/libc/sysv/consts/ICMP6_INFOMSG_MASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_INFOMSG_MASK 0x80 0x80 0x80 0x80 0x80 diff --git a/libc/sysv/consts/ICMP6_PACKET_TOO_BIG.s b/libc/sysv/consts/ICMP6_PACKET_TOO_BIG.s new file mode 100644 index 00000000..b4b84a86 --- /dev/null +++ b/libc/sysv/consts/ICMP6_PACKET_TOO_BIG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_PACKET_TOO_BIG 2 2 2 2 0 diff --git a/libc/sysv/consts/ICMP6_PARAMPROB_HEADER.s b/libc/sysv/consts/ICMP6_PARAMPROB_HEADER.s new file mode 100644 index 00000000..69617fff --- /dev/null +++ b/libc/sysv/consts/ICMP6_PARAMPROB_HEADER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_PARAMPROB_HEADER 0 0 0 0 0 diff --git a/libc/sysv/consts/ICMP6_PARAMPROB_NEXTHEADER.s b/libc/sysv/consts/ICMP6_PARAMPROB_NEXTHEADER.s new file mode 100644 index 00000000..c5ef82cb --- /dev/null +++ b/libc/sysv/consts/ICMP6_PARAMPROB_NEXTHEADER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_PARAMPROB_NEXTHEADER 1 1 1 1 1 diff --git a/libc/sysv/consts/ICMP6_PARAMPROB_OPTION.s b/libc/sysv/consts/ICMP6_PARAMPROB_OPTION.s new file mode 100644 index 00000000..ca71738c --- /dev/null +++ b/libc/sysv/consts/ICMP6_PARAMPROB_OPTION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_PARAMPROB_OPTION 2 2 2 2 2 diff --git a/libc/sysv/consts/ICMP6_PARAM_PROB.s b/libc/sysv/consts/ICMP6_PARAM_PROB.s new file mode 100644 index 00000000..aba781d8 --- /dev/null +++ b/libc/sysv/consts/ICMP6_PARAM_PROB.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_PARAM_PROB 4 4 4 4 0 diff --git a/libc/sysv/consts/ICMP6_ROUTER_RENUMBERING.s b/libc/sysv/consts/ICMP6_ROUTER_RENUMBERING.s new file mode 100644 index 00000000..23d0527e --- /dev/null +++ b/libc/sysv/consts/ICMP6_ROUTER_RENUMBERING.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_ROUTER_RENUMBERING 138 138 138 138 0 diff --git a/libc/sysv/consts/ICMP6_RR_FLAGS_FORCEAPPLY.s b/libc/sysv/consts/ICMP6_RR_FLAGS_FORCEAPPLY.s new file mode 100644 index 00000000..1c6a815c --- /dev/null +++ b/libc/sysv/consts/ICMP6_RR_FLAGS_FORCEAPPLY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_RR_FLAGS_FORCEAPPLY 0x20 0x20 0x20 0x20 0 diff --git a/libc/sysv/consts/ICMP6_RR_FLAGS_PREVDONE.s b/libc/sysv/consts/ICMP6_RR_FLAGS_PREVDONE.s new file mode 100644 index 00000000..d728587a --- /dev/null +++ b/libc/sysv/consts/ICMP6_RR_FLAGS_PREVDONE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_RR_FLAGS_PREVDONE 8 8 8 8 0 diff --git a/libc/sysv/consts/ICMP6_RR_FLAGS_REQRESULT.s b/libc/sysv/consts/ICMP6_RR_FLAGS_REQRESULT.s new file mode 100644 index 00000000..97a59b14 --- /dev/null +++ b/libc/sysv/consts/ICMP6_RR_FLAGS_REQRESULT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_RR_FLAGS_REQRESULT 0x40 0x40 0x40 0x40 0 diff --git a/libc/sysv/consts/ICMP6_RR_FLAGS_SPECSITE.s b/libc/sysv/consts/ICMP6_RR_FLAGS_SPECSITE.s new file mode 100644 index 00000000..ecc34b81 --- /dev/null +++ b/libc/sysv/consts/ICMP6_RR_FLAGS_SPECSITE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_RR_FLAGS_SPECSITE 0x10 0x10 0x10 0x10 0 diff --git a/libc/sysv/consts/ICMP6_RR_FLAGS_TEST.s b/libc/sysv/consts/ICMP6_RR_FLAGS_TEST.s new file mode 100644 index 00000000..42c883d1 --- /dev/null +++ b/libc/sysv/consts/ICMP6_RR_FLAGS_TEST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_RR_FLAGS_TEST 0x80 0x80 0x80 0x80 0 diff --git a/libc/sysv/consts/ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME.s b/libc/sysv/consts/ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME.s new file mode 100644 index 00000000..1a8a309e --- /dev/null +++ b/libc/sysv/consts/ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40 0x40 0x40 0x40 0 diff --git a/libc/sysv/consts/ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME.s b/libc/sysv/consts/ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME.s new file mode 100644 index 00000000..385e7145 --- /dev/null +++ b/libc/sysv/consts/ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80 0x80 0x80 0x80 0 diff --git a/libc/sysv/consts/ICMP6_RR_PCOUSE_RAFLAGS_AUTO.s b/libc/sysv/consts/ICMP6_RR_PCOUSE_RAFLAGS_AUTO.s new file mode 100644 index 00000000..4686cdae --- /dev/null +++ b/libc/sysv/consts/ICMP6_RR_PCOUSE_RAFLAGS_AUTO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x10 0x40 0x40 0x40 0 diff --git a/libc/sysv/consts/ICMP6_RR_PCOUSE_RAFLAGS_ONLINK.s b/libc/sysv/consts/ICMP6_RR_PCOUSE_RAFLAGS_ONLINK.s new file mode 100644 index 00000000..a6bdee86 --- /dev/null +++ b/libc/sysv/consts/ICMP6_RR_PCOUSE_RAFLAGS_ONLINK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x20 0x80 0x80 0x80 0 diff --git a/libc/sysv/consts/ICMP6_RR_RESULT_FLAGS_FORBIDDEN.s b/libc/sysv/consts/ICMP6_RR_RESULT_FLAGS_FORBIDDEN.s new file mode 100644 index 00000000..61e7caae --- /dev/null +++ b/libc/sysv/consts/ICMP6_RR_RESULT_FLAGS_FORBIDDEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100 0x0100 0x0100 0x0100 0 diff --git a/libc/sysv/consts/ICMP6_RR_RESULT_FLAGS_OOB.s b/libc/sysv/consts/ICMP6_RR_RESULT_FLAGS_OOB.s new file mode 100644 index 00000000..69b96d78 --- /dev/null +++ b/libc/sysv/consts/ICMP6_RR_RESULT_FLAGS_OOB.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_RR_RESULT_FLAGS_OOB 0x0200 0x0200 0x0200 0x0200 0 diff --git a/libc/sysv/consts/ICMP6_TIME_EXCEEDED.s b/libc/sysv/consts/ICMP6_TIME_EXCEEDED.s new file mode 100644 index 00000000..95bc2ced --- /dev/null +++ b/libc/sysv/consts/ICMP6_TIME_EXCEEDED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_TIME_EXCEEDED 3 3 3 3 0 diff --git a/libc/sysv/consts/ICMP6_TIME_EXCEED_REASSEMBLY.s b/libc/sysv/consts/ICMP6_TIME_EXCEED_REASSEMBLY.s new file mode 100644 index 00000000..6864638a --- /dev/null +++ b/libc/sysv/consts/ICMP6_TIME_EXCEED_REASSEMBLY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_TIME_EXCEED_REASSEMBLY 1 1 1 1 1 diff --git a/libc/sysv/consts/ICMP6_TIME_EXCEED_TRANSIT.s b/libc/sysv/consts/ICMP6_TIME_EXCEED_TRANSIT.s new file mode 100644 index 00000000..ee4449a7 --- /dev/null +++ b/libc/sysv/consts/ICMP6_TIME_EXCEED_TRANSIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon icmp6 ICMP6_TIME_EXCEED_TRANSIT 0 0 0 0 0 diff --git a/libc/sysv/consts/ICRNL.s b/libc/sysv/consts/ICRNL.s new file mode 100644 index 00000000..e1ebb122 --- /dev/null +++ b/libc/sysv/consts/ICRNL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios ICRNL 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000100000000 diff --git a/libc/sysv/consts/IEXTEN.s b/libc/sysv/consts/IEXTEN.s new file mode 100644 index 00000000..66457bc1 --- /dev/null +++ b/libc/sysv/consts/IEXTEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios IEXTEN 0b1000000000000000 0b0000010000000000 0b0000010000000000 0b0000010000000000 0b1000000000000000 diff --git a/libc/sysv/consts/IFF_ALLMULTI.s b/libc/sysv/consts/IFF_ALLMULTI.s new file mode 100644 index 00000000..93009e95 --- /dev/null +++ b/libc/sysv/consts/IFF_ALLMULTI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iff IFF_ALLMULTI 0x0200 0x0200 0x0200 0x0200 0 diff --git a/libc/sysv/consts/IFF_AUTOMEDIA.s b/libc/sysv/consts/IFF_AUTOMEDIA.s new file mode 100644 index 00000000..5d9306ff --- /dev/null +++ b/libc/sysv/consts/IFF_AUTOMEDIA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iff IFF_AUTOMEDIA 0x4000 0 0 0 0 diff --git a/libc/sysv/consts/IFF_BROADCAST.s b/libc/sysv/consts/IFF_BROADCAST.s new file mode 100644 index 00000000..268ed0b2 --- /dev/null +++ b/libc/sysv/consts/IFF_BROADCAST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iff IFF_BROADCAST 2 2 2 2 2 diff --git a/libc/sysv/consts/IFF_DEBUG.s b/libc/sysv/consts/IFF_DEBUG.s new file mode 100644 index 00000000..70542209 --- /dev/null +++ b/libc/sysv/consts/IFF_DEBUG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iff IFF_DEBUG 4 4 4 4 0 diff --git a/libc/sysv/consts/IFF_DYNAMIC.s b/libc/sysv/consts/IFF_DYNAMIC.s new file mode 100644 index 00000000..8e7b6648 --- /dev/null +++ b/libc/sysv/consts/IFF_DYNAMIC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iff IFF_DYNAMIC 0x8000 0 0 0 0 diff --git a/libc/sysv/consts/IFF_LOOPBACK.s b/libc/sysv/consts/IFF_LOOPBACK.s new file mode 100644 index 00000000..ca13075c --- /dev/null +++ b/libc/sysv/consts/IFF_LOOPBACK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iff IFF_LOOPBACK 8 8 8 8 4 diff --git a/libc/sysv/consts/IFF_MASTER.s b/libc/sysv/consts/IFF_MASTER.s new file mode 100644 index 00000000..f63e1bd5 --- /dev/null +++ b/libc/sysv/consts/IFF_MASTER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iff IFF_MASTER 0x0400 0 0 0 0 diff --git a/libc/sysv/consts/IFF_MULTICAST.s b/libc/sysv/consts/IFF_MULTICAST.s new file mode 100644 index 00000000..1fb6088d --- /dev/null +++ b/libc/sysv/consts/IFF_MULTICAST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iff IFF_MULTICAST 0x1000 0x8000 0x8000 0x8000 0x10 diff --git a/libc/sysv/consts/IFF_NOARP.s b/libc/sysv/consts/IFF_NOARP.s new file mode 100644 index 00000000..3e87b9b3 --- /dev/null +++ b/libc/sysv/consts/IFF_NOARP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iff IFF_NOARP 0x80 0x80 0x80 0x80 0 diff --git a/libc/sysv/consts/IFF_NOTRAILERS.s b/libc/sysv/consts/IFF_NOTRAILERS.s new file mode 100644 index 00000000..99f75be9 --- /dev/null +++ b/libc/sysv/consts/IFF_NOTRAILERS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iff IFF_NOTRAILERS 0x20 0x20 0 0 0 diff --git a/libc/sysv/consts/IFF_POINTOPOINT.s b/libc/sysv/consts/IFF_POINTOPOINT.s new file mode 100644 index 00000000..982fa243 --- /dev/null +++ b/libc/sysv/consts/IFF_POINTOPOINT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iff IFF_POINTOPOINT 0x10 0x10 0x10 0x10 0 diff --git a/libc/sysv/consts/IFF_PORTSEL.s b/libc/sysv/consts/IFF_PORTSEL.s new file mode 100644 index 00000000..6cf9d69e --- /dev/null +++ b/libc/sysv/consts/IFF_PORTSEL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iff IFF_PORTSEL 0x2000 0 0 0 0 diff --git a/libc/sysv/consts/IFF_PROIFF.s b/libc/sysv/consts/IFF_PROIFF.s new file mode 100644 index 00000000..9ca5bda4 --- /dev/null +++ b/libc/sysv/consts/IFF_PROIFF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iff IFF_PROIFF 0x0100 0x0100 0x0100 0x0100 0 diff --git a/libc/sysv/consts/IFF_RUNNING.s b/libc/sysv/consts/IFF_RUNNING.s new file mode 100644 index 00000000..f0547c1e --- /dev/null +++ b/libc/sysv/consts/IFF_RUNNING.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iff IFF_RUNNING 0x40 0x40 0x40 0x40 0 diff --git a/libc/sysv/consts/IFF_SLAVE.s b/libc/sysv/consts/IFF_SLAVE.s new file mode 100644 index 00000000..2454ef60 --- /dev/null +++ b/libc/sysv/consts/IFF_SLAVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iff IFF_SLAVE 0x0800 0 0 0 0 diff --git a/libc/sysv/consts/IF_NAMESIZE.s b/libc/sysv/consts/IF_NAMESIZE.s new file mode 100644 index 00000000..75a17931 --- /dev/null +++ b/libc/sysv/consts/IF_NAMESIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc IF_NAMESIZE 0x10 0x10 0x10 0x10 0 diff --git a/libc/sysv/consts/IGMP_MEMBERSHIP_QUERY.s b/libc/sysv/consts/IGMP_MEMBERSHIP_QUERY.s new file mode 100644 index 00000000..e464a689 --- /dev/null +++ b/libc/sysv/consts/IGMP_MEMBERSHIP_QUERY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc IGMP_MEMBERSHIP_QUERY 17 0 0 0 0 diff --git a/libc/sysv/consts/IGNBRK.s b/libc/sysv/consts/IGNBRK.s new file mode 100644 index 00000000..20acf440 --- /dev/null +++ b/libc/sysv/consts/IGNBRK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios IGNBRK 0b0000000000000001 0b0000000000000001 0b0000000000000001 0b0000000000000001 0b0000000000000001 diff --git a/libc/sysv/consts/IGNCR.s b/libc/sysv/consts/IGNCR.s new file mode 100644 index 00000000..c48d14ea --- /dev/null +++ b/libc/sysv/consts/IGNCR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios IGNCR 0b0000000010000000 0b0000000010000000 0b0000000010000000 0b0000000010000000 0b0000000010000000 diff --git a/libc/sysv/consts/IGNPAR.s b/libc/sysv/consts/IGNPAR.s new file mode 100644 index 00000000..3cb660c9 --- /dev/null +++ b/libc/sysv/consts/IGNPAR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios IGNPAR 0b0000000000000100 0b0000000000000100 0b0000000000000100 0b0000000000000100 0b0000000000000100 diff --git a/libc/sysv/consts/ILLEGAL_REQUEST.s b/libc/sysv/consts/ILLEGAL_REQUEST.s new file mode 100644 index 00000000..3f0c75f2 --- /dev/null +++ b/libc/sysv/consts/ILLEGAL_REQUEST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ILLEGAL_REQUEST 5 0 0 0 0 diff --git a/libc/sysv/consts/ILL_BADSTK.s b/libc/sysv/consts/ILL_BADSTK.s new file mode 100644 index 00000000..f6b25927 --- /dev/null +++ b/libc/sysv/consts/ILL_BADSTK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ILL_BADSTK 8 8 8 8 0 diff --git a/libc/sysv/consts/ILL_COPROC.s b/libc/sysv/consts/ILL_COPROC.s new file mode 100644 index 00000000..dfecd7fe --- /dev/null +++ b/libc/sysv/consts/ILL_COPROC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ILL_COPROC 7 7 7 7 0 diff --git a/libc/sysv/consts/ILL_ILLADR.s b/libc/sysv/consts/ILL_ILLADR.s new file mode 100644 index 00000000..9357babb --- /dev/null +++ b/libc/sysv/consts/ILL_ILLADR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ILL_ILLADR 3 5 3 3 0 diff --git a/libc/sysv/consts/ILL_ILLOPC.s b/libc/sysv/consts/ILL_ILLOPC.s new file mode 100644 index 00000000..8629dbc1 --- /dev/null +++ b/libc/sysv/consts/ILL_ILLOPC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ILL_ILLOPC 1 1 1 1 0 diff --git a/libc/sysv/consts/ILL_ILLOPN.s b/libc/sysv/consts/ILL_ILLOPN.s new file mode 100644 index 00000000..25c58bb7 --- /dev/null +++ b/libc/sysv/consts/ILL_ILLOPN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ILL_ILLOPN 2 4 2 2 0 diff --git a/libc/sysv/consts/ILL_ILLTRP.s b/libc/sysv/consts/ILL_ILLTRP.s new file mode 100644 index 00000000..6541654b --- /dev/null +++ b/libc/sysv/consts/ILL_ILLTRP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ILL_ILLTRP 4 2 4 4 0 diff --git a/libc/sysv/consts/ILL_PRVOPC.s b/libc/sysv/consts/ILL_PRVOPC.s new file mode 100644 index 00000000..8bc1304e --- /dev/null +++ b/libc/sysv/consts/ILL_PRVOPC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ILL_PRVOPC 5 3 5 5 0 diff --git a/libc/sysv/consts/ILL_PRVREG.s b/libc/sysv/consts/ILL_PRVREG.s new file mode 100644 index 00000000..0314592e --- /dev/null +++ b/libc/sysv/consts/ILL_PRVREG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ILL_PRVREG 6 6 6 6 0 diff --git a/libc/sysv/consts/IMAXBEL.s b/libc/sysv/consts/IMAXBEL.s new file mode 100644 index 00000000..e7755bf3 --- /dev/null +++ b/libc/sysv/consts/IMAXBEL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios IMAXBEL 0b0010000000000000 0b0010000000000000 0b0010000000000000 0b0010000000000000 0b0010000000000000 diff --git a/libc/sysv/consts/INADDR_ALLHOSTS_GROUP.s b/libc/sysv/consts/INADDR_ALLHOSTS_GROUP.s new file mode 100644 index 00000000..2adf919e --- /dev/null +++ b/libc/sysv/consts/INADDR_ALLHOSTS_GROUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc INADDR_ALLHOSTS_GROUP 0xe0000001 0xe0000001 0xe0000001 0xe0000001 0 diff --git a/libc/sysv/consts/INADDR_ALLRTRS_GROUP.s b/libc/sysv/consts/INADDR_ALLRTRS_GROUP.s new file mode 100644 index 00000000..b85b96af --- /dev/null +++ b/libc/sysv/consts/INADDR_ALLRTRS_GROUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc INADDR_ALLRTRS_GROUP 0xe0000002 0xe0000002 0xe0000002 0 0 diff --git a/libc/sysv/consts/INADDR_ANY.s b/libc/sysv/consts/INADDR_ANY.s new file mode 100644 index 00000000..77eea3ad --- /dev/null +++ b/libc/sysv/consts/INADDR_ANY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc INADDR_ANY 0 0 0 0 0 diff --git a/libc/sysv/consts/INADDR_BROADCAST.s b/libc/sysv/consts/INADDR_BROADCAST.s new file mode 100644 index 00000000..3c1de538 --- /dev/null +++ b/libc/sysv/consts/INADDR_BROADCAST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc INADDR_BROADCAST 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff diff --git a/libc/sysv/consts/INADDR_LOOPBACK.s b/libc/sysv/consts/INADDR_LOOPBACK.s new file mode 100644 index 00000000..b1e4402a --- /dev/null +++ b/libc/sysv/consts/INADDR_LOOPBACK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc INADDR_LOOPBACK 0x7f000001 0x7f000001 0x7f000001 0x7f000001 0x7f000001 diff --git a/libc/sysv/consts/INADDR_MAX_LOCAL_GROUP.s b/libc/sysv/consts/INADDR_MAX_LOCAL_GROUP.s new file mode 100644 index 00000000..c2d2bc4d --- /dev/null +++ b/libc/sysv/consts/INADDR_MAX_LOCAL_GROUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc INADDR_MAX_LOCAL_GROUP 0xe00000ff 0xe00000ff 0xe00000ff 0xe00000ff 0 diff --git a/libc/sysv/consts/INADDR_NONE.s b/libc/sysv/consts/INADDR_NONE.s new file mode 100644 index 00000000..16c6bcef --- /dev/null +++ b/libc/sysv/consts/INADDR_NONE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc INADDR_NONE 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff diff --git a/libc/sysv/consts/INADDR_UNSPEC_GROUP.s b/libc/sysv/consts/INADDR_UNSPEC_GROUP.s new file mode 100644 index 00000000..361e9813 --- /dev/null +++ b/libc/sysv/consts/INADDR_UNSPEC_GROUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc INADDR_UNSPEC_GROUP 0xe0000000 0xe0000000 0xe0000000 0xe0000000 0 diff --git a/libc/sysv/consts/INET6_ADDRSTRLEN.s b/libc/sysv/consts/INET6_ADDRSTRLEN.s new file mode 100644 index 00000000..c2b99677 --- /dev/null +++ b/libc/sysv/consts/INET6_ADDRSTRLEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 INET6_ADDRSTRLEN 46 46 46 46 65 diff --git a/libc/sysv/consts/INET_ADDRSTRLEN.s b/libc/sysv/consts/INET_ADDRSTRLEN.s new file mode 100644 index 00000000..27a567b5 --- /dev/null +++ b/libc/sysv/consts/INET_ADDRSTRLEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip INET_ADDRSTRLEN 0x10 0x10 0x10 0x10 22 diff --git a/libc/sysv/consts/INITIATE_RECOVERY.s b/libc/sysv/consts/INITIATE_RECOVERY.s new file mode 100644 index 00000000..4a378635 --- /dev/null +++ b/libc/sysv/consts/INITIATE_RECOVERY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc INITIATE_RECOVERY 15 0 0 0 0 diff --git a/libc/sysv/consts/INITIATOR_ERROR.s b/libc/sysv/consts/INITIATOR_ERROR.s new file mode 100644 index 00000000..27920a40 --- /dev/null +++ b/libc/sysv/consts/INITIATOR_ERROR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc INITIATOR_ERROR 5 0 0 0 0 diff --git a/libc/sysv/consts/INIT_PROCESS.s b/libc/sysv/consts/INIT_PROCESS.s new file mode 100644 index 00000000..02a7bd98 --- /dev/null +++ b/libc/sysv/consts/INIT_PROCESS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc INIT_PROCESS 5 5 5 0 0 diff --git a/libc/sysv/consts/INLCR.s b/libc/sysv/consts/INLCR.s new file mode 100644 index 00000000..56748cd3 --- /dev/null +++ b/libc/sysv/consts/INLCR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios INLCR 0b0000000001000000 0b0000000001000000 0b0000000001000000 0b0000000001000000 0b0000000001000000 diff --git a/libc/sysv/consts/INPCK.s b/libc/sysv/consts/INPCK.s new file mode 100644 index 00000000..8a4c66e8 --- /dev/null +++ b/libc/sysv/consts/INPCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios INPCK 0b0000000000010000 0b0000000000010000 0b0000000000010000 0b0000000000010000 0b0000000000010000 diff --git a/libc/sysv/consts/INQUIRY.s b/libc/sysv/consts/INQUIRY.s new file mode 100644 index 00000000..8de1f5e0 --- /dev/null +++ b/libc/sysv/consts/INQUIRY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc INQUIRY 18 0 0 0 0 diff --git a/libc/sysv/consts/INTERMEDIATE_C_GOOD.s b/libc/sysv/consts/INTERMEDIATE_C_GOOD.s new file mode 100644 index 00000000..c46d3f6b --- /dev/null +++ b/libc/sysv/consts/INTERMEDIATE_C_GOOD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc INTERMEDIATE_C_GOOD 10 0 0 0 0 diff --git a/libc/sysv/consts/INTERMEDIATE_GOOD.s b/libc/sysv/consts/INTERMEDIATE_GOOD.s new file mode 100644 index 00000000..84bdc06f --- /dev/null +++ b/libc/sysv/consts/INTERMEDIATE_GOOD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc INTERMEDIATE_GOOD 8 0 0 0 0 diff --git a/libc/sysv/consts/IN_ACCESS.s b/libc/sysv/consts/IN_ACCESS.s new file mode 100644 index 00000000..a497b716 --- /dev/null +++ b/libc/sysv/consts/IN_ACCESS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_ACCESS 1 0 0 0 0 diff --git a/libc/sysv/consts/IN_ALL_EVENTS.s b/libc/sysv/consts/IN_ALL_EVENTS.s new file mode 100644 index 00000000..92bbff30 --- /dev/null +++ b/libc/sysv/consts/IN_ALL_EVENTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_ALL_EVENTS 0x0fff 0 0 0 0 diff --git a/libc/sysv/consts/IN_ATTRIB.s b/libc/sysv/consts/IN_ATTRIB.s new file mode 100644 index 00000000..b2577703 --- /dev/null +++ b/libc/sysv/consts/IN_ATTRIB.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_ATTRIB 4 0 0 0 0 diff --git a/libc/sysv/consts/IN_CLOEXEC.s b/libc/sysv/consts/IN_CLOEXEC.s new file mode 100644 index 00000000..71f51714 --- /dev/null +++ b/libc/sysv/consts/IN_CLOEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_CLOEXEC 0x080000 0 0 0 0 diff --git a/libc/sysv/consts/IN_CLOSE.s b/libc/sysv/consts/IN_CLOSE.s new file mode 100644 index 00000000..d9157274 --- /dev/null +++ b/libc/sysv/consts/IN_CLOSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_CLOSE 24 0 0 0 0 diff --git a/libc/sysv/consts/IN_CLOSE_NOWRITE.s b/libc/sysv/consts/IN_CLOSE_NOWRITE.s new file mode 100644 index 00000000..6378f66b --- /dev/null +++ b/libc/sysv/consts/IN_CLOSE_NOWRITE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_CLOSE_NOWRITE 0x10 0 0 0 0 diff --git a/libc/sysv/consts/IN_CLOSE_WRITE.s b/libc/sysv/consts/IN_CLOSE_WRITE.s new file mode 100644 index 00000000..18649502 --- /dev/null +++ b/libc/sysv/consts/IN_CLOSE_WRITE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_CLOSE_WRITE 8 0 0 0 0 diff --git a/libc/sysv/consts/IN_CREATE.s b/libc/sysv/consts/IN_CREATE.s new file mode 100644 index 00000000..f01ca6b2 --- /dev/null +++ b/libc/sysv/consts/IN_CREATE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_CREATE 0x0100 0 0 0 0 diff --git a/libc/sysv/consts/IN_DELETE.s b/libc/sysv/consts/IN_DELETE.s new file mode 100644 index 00000000..4925012f --- /dev/null +++ b/libc/sysv/consts/IN_DELETE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_DELETE 0x0200 0 0 0 0 diff --git a/libc/sysv/consts/IN_DELETE_SELF.s b/libc/sysv/consts/IN_DELETE_SELF.s new file mode 100644 index 00000000..05795287 --- /dev/null +++ b/libc/sysv/consts/IN_DELETE_SELF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_DELETE_SELF 0x0400 0 0 0 0 diff --git a/libc/sysv/consts/IN_DONT_FOLLOW.s b/libc/sysv/consts/IN_DONT_FOLLOW.s new file mode 100644 index 00000000..34f3b8fa --- /dev/null +++ b/libc/sysv/consts/IN_DONT_FOLLOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_DONT_FOLLOW 0x02000000 0 0 0 0 diff --git a/libc/sysv/consts/IN_EXCL_UNLINK.s b/libc/sysv/consts/IN_EXCL_UNLINK.s new file mode 100644 index 00000000..86fcf7d8 --- /dev/null +++ b/libc/sysv/consts/IN_EXCL_UNLINK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_EXCL_UNLINK 0x04000000 0 0 0 0 diff --git a/libc/sysv/consts/IN_IGNORED.s b/libc/sysv/consts/IN_IGNORED.s new file mode 100644 index 00000000..f0d17c40 --- /dev/null +++ b/libc/sysv/consts/IN_IGNORED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_IGNORED 0x8000 0 0 0 0 diff --git a/libc/sysv/consts/IN_ISDIR.s b/libc/sysv/consts/IN_ISDIR.s new file mode 100644 index 00000000..f67d2b41 --- /dev/null +++ b/libc/sysv/consts/IN_ISDIR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_ISDIR 0x40000000 0 0 0 0 diff --git a/libc/sysv/consts/IN_LOOPBACKNET.s b/libc/sysv/consts/IN_LOOPBACKNET.s new file mode 100644 index 00000000..417b4153 --- /dev/null +++ b/libc/sysv/consts/IN_LOOPBACKNET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_LOOPBACKNET 127 127 127 127 0 diff --git a/libc/sysv/consts/IN_MASK_ADD.s b/libc/sysv/consts/IN_MASK_ADD.s new file mode 100644 index 00000000..62661d17 --- /dev/null +++ b/libc/sysv/consts/IN_MASK_ADD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_MASK_ADD 0x20000000 0 0 0 0 diff --git a/libc/sysv/consts/IN_MODIFY.s b/libc/sysv/consts/IN_MODIFY.s new file mode 100644 index 00000000..a3862415 --- /dev/null +++ b/libc/sysv/consts/IN_MODIFY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_MODIFY 2 0 0 0 0 diff --git a/libc/sysv/consts/IN_MOVE.s b/libc/sysv/consts/IN_MOVE.s new file mode 100644 index 00000000..e6a4845b --- /dev/null +++ b/libc/sysv/consts/IN_MOVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_MOVE 192 0 0 0 0 diff --git a/libc/sysv/consts/IN_MOVED_FROM.s b/libc/sysv/consts/IN_MOVED_FROM.s new file mode 100644 index 00000000..27dd33e2 --- /dev/null +++ b/libc/sysv/consts/IN_MOVED_FROM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_MOVED_FROM 0x40 0 0 0 0 diff --git a/libc/sysv/consts/IN_MOVED_TO.s b/libc/sysv/consts/IN_MOVED_TO.s new file mode 100644 index 00000000..6c387bdb --- /dev/null +++ b/libc/sysv/consts/IN_MOVED_TO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_MOVED_TO 0x80 0 0 0 0 diff --git a/libc/sysv/consts/IN_MOVE_SELF.s b/libc/sysv/consts/IN_MOVE_SELF.s new file mode 100644 index 00000000..cee60020 --- /dev/null +++ b/libc/sysv/consts/IN_MOVE_SELF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_MOVE_SELF 0x0800 0 0 0 0 diff --git a/libc/sysv/consts/IN_NONBLOCK.s b/libc/sysv/consts/IN_NONBLOCK.s new file mode 100644 index 00000000..1c1e70fc --- /dev/null +++ b/libc/sysv/consts/IN_NONBLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_NONBLOCK 0x0800 0 0 0 0 diff --git a/libc/sysv/consts/IN_ONESHOT.s b/libc/sysv/consts/IN_ONESHOT.s new file mode 100644 index 00000000..d26f13c4 --- /dev/null +++ b/libc/sysv/consts/IN_ONESHOT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_ONESHOT 0x80000000 0 0 0 0 diff --git a/libc/sysv/consts/IN_ONLYDIR.s b/libc/sysv/consts/IN_ONLYDIR.s new file mode 100644 index 00000000..0bee2515 --- /dev/null +++ b/libc/sysv/consts/IN_ONLYDIR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_ONLYDIR 0x01000000 0 0 0 0 diff --git a/libc/sysv/consts/IN_OPEN.s b/libc/sysv/consts/IN_OPEN.s new file mode 100644 index 00000000..2f0192bd --- /dev/null +++ b/libc/sysv/consts/IN_OPEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_OPEN 0x20 0 0 0 0 diff --git a/libc/sysv/consts/IN_Q_OVERFLOW.s b/libc/sysv/consts/IN_Q_OVERFLOW.s new file mode 100644 index 00000000..de417d9d --- /dev/null +++ b/libc/sysv/consts/IN_Q_OVERFLOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_Q_OVERFLOW 0x4000 0 0 0 0 diff --git a/libc/sysv/consts/IN_UNMOUNT.s b/libc/sysv/consts/IN_UNMOUNT.s new file mode 100644 index 00000000..3fa1ac59 --- /dev/null +++ b/libc/sysv/consts/IN_UNMOUNT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon in IN_UNMOUNT 0x2000 0 0 0 0 diff --git a/libc/sysv/consts/IOV_MAX.s b/libc/sysv/consts/IOV_MAX.s new file mode 100644 index 00000000..3747ed72 --- /dev/null +++ b/libc/sysv/consts/IOV_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc IOV_MAX 0x0400 0x0400 0x0400 0x0400 16 diff --git a/libc/sysv/consts/IP6F_MORE_FRAG.s b/libc/sysv/consts/IP6F_MORE_FRAG.s new file mode 100644 index 00000000..6dac5904 --- /dev/null +++ b/libc/sysv/consts/IP6F_MORE_FRAG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc IP6F_MORE_FRAG 0x0100 0x0100 0x0100 0x0100 0x0100 diff --git a/libc/sysv/consts/IP6F_OFF_MASK.s b/libc/sysv/consts/IP6F_OFF_MASK.s new file mode 100644 index 00000000..d20d3a87 --- /dev/null +++ b/libc/sysv/consts/IP6F_OFF_MASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc IP6F_OFF_MASK 0xf8ff 0xf8ff 0xf8ff 0xf8ff 0xf8ff diff --git a/libc/sysv/consts/IP6F_RESERVED_MASK.s b/libc/sysv/consts/IP6F_RESERVED_MASK.s new file mode 100644 index 00000000..8fd6d46a --- /dev/null +++ b/libc/sysv/consts/IP6F_RESERVED_MASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc IP6F_RESERVED_MASK 0x0600 0x0600 0x0600 0x0600 0x0600 diff --git a/libc/sysv/consts/IPC_CREAT.s b/libc/sysv/consts/IPC_CREAT.s new file mode 100644 index 00000000..c032eb00 --- /dev/null +++ b/libc/sysv/consts/IPC_CREAT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc IPC_CREAT 0x0200 0x0200 0x0200 0x0200 0 diff --git a/libc/sysv/consts/IPC_EXCL.s b/libc/sysv/consts/IPC_EXCL.s new file mode 100644 index 00000000..83b72869 --- /dev/null +++ b/libc/sysv/consts/IPC_EXCL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc IPC_EXCL 0x0400 0x0400 0x0400 0x0400 0 diff --git a/libc/sysv/consts/IPC_INFO.s b/libc/sysv/consts/IPC_INFO.s new file mode 100644 index 00000000..ec3ec92c --- /dev/null +++ b/libc/sysv/consts/IPC_INFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc IPC_INFO 3 0 3 0 0 diff --git a/libc/sysv/consts/IPC_NOWAIT.s b/libc/sysv/consts/IPC_NOWAIT.s new file mode 100644 index 00000000..15161176 --- /dev/null +++ b/libc/sysv/consts/IPC_NOWAIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc IPC_NOWAIT 0x0800 0x0800 0x0800 0x0800 0 diff --git a/libc/sysv/consts/IPC_PRIVATE.s b/libc/sysv/consts/IPC_PRIVATE.s new file mode 100644 index 00000000..dc6b4cb2 --- /dev/null +++ b/libc/sysv/consts/IPC_PRIVATE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc IPC_PRIVATE 0 0 0 0 0 diff --git a/libc/sysv/consts/IPC_RMID.s b/libc/sysv/consts/IPC_RMID.s new file mode 100644 index 00000000..833825ee --- /dev/null +++ b/libc/sysv/consts/IPC_RMID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc IPC_RMID 0 0 0 0 0 diff --git a/libc/sysv/consts/IPC_SET.s b/libc/sysv/consts/IPC_SET.s new file mode 100644 index 00000000..1523d604 --- /dev/null +++ b/libc/sysv/consts/IPC_SET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc IPC_SET 1 1 1 1 0 diff --git a/libc/sysv/consts/IPC_STAT.s b/libc/sysv/consts/IPC_STAT.s new file mode 100644 index 00000000..d420bfac --- /dev/null +++ b/libc/sysv/consts/IPC_STAT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc IPC_STAT 2 2 2 2 0 diff --git a/libc/sysv/consts/IPPORT_RESERVED.s b/libc/sysv/consts/IPPORT_RESERVED.s new file mode 100644 index 00000000..1d96178a --- /dev/null +++ b/libc/sysv/consts/IPPORT_RESERVED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc IPPORT_RESERVED 0x0400 0x0400 0x0400 0x0400 0x0400 diff --git a/libc/sysv/consts/IPPROTO_AH.s b/libc/sysv/consts/IPPROTO_AH.s new file mode 100644 index 00000000..08697557 --- /dev/null +++ b/libc/sysv/consts/IPPROTO_AH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_AH 51 51 51 51 0 diff --git a/libc/sysv/consts/IPPROTO_BEETPH.s b/libc/sysv/consts/IPPROTO_BEETPH.s new file mode 100644 index 00000000..4b7b16bc --- /dev/null +++ b/libc/sysv/consts/IPPROTO_BEETPH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_BEETPH 94 0 0 0 0 diff --git a/libc/sysv/consts/IPPROTO_COMP.s b/libc/sysv/consts/IPPROTO_COMP.s new file mode 100644 index 00000000..2d2e3ba4 --- /dev/null +++ b/libc/sysv/consts/IPPROTO_COMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_COMP 108 0 0 0 0 diff --git a/libc/sysv/consts/IPPROTO_DCCP.s b/libc/sysv/consts/IPPROTO_DCCP.s new file mode 100644 index 00000000..fad4bc0e --- /dev/null +++ b/libc/sysv/consts/IPPROTO_DCCP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_DCCP 33 0 0 0 0 diff --git a/libc/sysv/consts/IPPROTO_DSTOPTS.s b/libc/sysv/consts/IPPROTO_DSTOPTS.s new file mode 100644 index 00000000..f1dbadef --- /dev/null +++ b/libc/sysv/consts/IPPROTO_DSTOPTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_DSTOPTS 60 60 60 60 0 diff --git a/libc/sysv/consts/IPPROTO_EGP.s b/libc/sysv/consts/IPPROTO_EGP.s new file mode 100644 index 00000000..f8f66902 --- /dev/null +++ b/libc/sysv/consts/IPPROTO_EGP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_EGP 8 8 8 8 0 diff --git a/libc/sysv/consts/IPPROTO_ENCAP.s b/libc/sysv/consts/IPPROTO_ENCAP.s new file mode 100644 index 00000000..2c6a2354 --- /dev/null +++ b/libc/sysv/consts/IPPROTO_ENCAP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_ENCAP 98 98 98 98 0 diff --git a/libc/sysv/consts/IPPROTO_ESP.s b/libc/sysv/consts/IPPROTO_ESP.s new file mode 100644 index 00000000..98a889d6 --- /dev/null +++ b/libc/sysv/consts/IPPROTO_ESP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_ESP 50 50 50 50 0 diff --git a/libc/sysv/consts/IPPROTO_FRAGMENT.s b/libc/sysv/consts/IPPROTO_FRAGMENT.s new file mode 100644 index 00000000..d2bbd51e --- /dev/null +++ b/libc/sysv/consts/IPPROTO_FRAGMENT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_FRAGMENT 44 44 44 44 0 diff --git a/libc/sysv/consts/IPPROTO_GRE.s b/libc/sysv/consts/IPPROTO_GRE.s new file mode 100644 index 00000000..edf276ec --- /dev/null +++ b/libc/sysv/consts/IPPROTO_GRE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_GRE 47 47 47 47 0 diff --git a/libc/sysv/consts/IPPROTO_HOPOPTS.s b/libc/sysv/consts/IPPROTO_HOPOPTS.s new file mode 100644 index 00000000..678df20f --- /dev/null +++ b/libc/sysv/consts/IPPROTO_HOPOPTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_HOPOPTS 0 0 0 0 0 diff --git a/libc/sysv/consts/IPPROTO_ICMP.s b/libc/sysv/consts/IPPROTO_ICMP.s new file mode 100644 index 00000000..de7746c5 --- /dev/null +++ b/libc/sysv/consts/IPPROTO_ICMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_ICMP 1 1 1 1 1 diff --git a/libc/sysv/consts/IPPROTO_ICMPV6.s b/libc/sysv/consts/IPPROTO_ICMPV6.s new file mode 100644 index 00000000..2c00d4df --- /dev/null +++ b/libc/sysv/consts/IPPROTO_ICMPV6.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_ICMPV6 58 58 58 58 0 diff --git a/libc/sysv/consts/IPPROTO_IDP.s b/libc/sysv/consts/IPPROTO_IDP.s new file mode 100644 index 00000000..8e68a863 --- /dev/null +++ b/libc/sysv/consts/IPPROTO_IDP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_IDP 22 22 22 22 22 diff --git a/libc/sysv/consts/IPPROTO_IGMP.s b/libc/sysv/consts/IPPROTO_IGMP.s new file mode 100644 index 00000000..3e3fa67c --- /dev/null +++ b/libc/sysv/consts/IPPROTO_IGMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_IGMP 2 2 2 2 2 diff --git a/libc/sysv/consts/IPPROTO_IP.s b/libc/sysv/consts/IPPROTO_IP.s new file mode 100644 index 00000000..9f66ce5f --- /dev/null +++ b/libc/sysv/consts/IPPROTO_IP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_IP 0 0 0 0 0 diff --git a/libc/sysv/consts/IPPROTO_IPIP.s b/libc/sysv/consts/IPPROTO_IPIP.s new file mode 100644 index 00000000..8697cdb0 --- /dev/null +++ b/libc/sysv/consts/IPPROTO_IPIP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_IPIP 4 4 4 4 0 diff --git a/libc/sysv/consts/IPPROTO_IPV6.s b/libc/sysv/consts/IPPROTO_IPV6.s new file mode 100644 index 00000000..25b81e73 --- /dev/null +++ b/libc/sysv/consts/IPPROTO_IPV6.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_IPV6 41 41 41 41 0 diff --git a/libc/sysv/consts/IPPROTO_MH.s b/libc/sysv/consts/IPPROTO_MH.s new file mode 100644 index 00000000..1315d827 --- /dev/null +++ b/libc/sysv/consts/IPPROTO_MH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_MH 135 0 135 0 0 diff --git a/libc/sysv/consts/IPPROTO_MPLS.s b/libc/sysv/consts/IPPROTO_MPLS.s new file mode 100644 index 00000000..bb25f6dc --- /dev/null +++ b/libc/sysv/consts/IPPROTO_MPLS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_MPLS 137 0 137 137 0 diff --git a/libc/sysv/consts/IPPROTO_MTP.s b/libc/sysv/consts/IPPROTO_MTP.s new file mode 100644 index 00000000..f8bddc19 --- /dev/null +++ b/libc/sysv/consts/IPPROTO_MTP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_MTP 92 92 92 0 0 diff --git a/libc/sysv/consts/IPPROTO_NONE.s b/libc/sysv/consts/IPPROTO_NONE.s new file mode 100644 index 00000000..0e01569b --- /dev/null +++ b/libc/sysv/consts/IPPROTO_NONE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_NONE 59 59 59 59 0 diff --git a/libc/sysv/consts/IPPROTO_PIM.s b/libc/sysv/consts/IPPROTO_PIM.s new file mode 100644 index 00000000..b9312306 --- /dev/null +++ b/libc/sysv/consts/IPPROTO_PIM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_PIM 103 103 103 103 0 diff --git a/libc/sysv/consts/IPPROTO_PUP.s b/libc/sysv/consts/IPPROTO_PUP.s new file mode 100644 index 00000000..ef88a8eb --- /dev/null +++ b/libc/sysv/consts/IPPROTO_PUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_PUP 12 12 12 12 12 diff --git a/libc/sysv/consts/IPPROTO_RAW.s b/libc/sysv/consts/IPPROTO_RAW.s new file mode 100644 index 00000000..fad8f4d0 --- /dev/null +++ b/libc/sysv/consts/IPPROTO_RAW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_RAW 255 255 255 255 255 diff --git a/libc/sysv/consts/IPPROTO_ROUTING.s b/libc/sysv/consts/IPPROTO_ROUTING.s new file mode 100644 index 00000000..c46c03da --- /dev/null +++ b/libc/sysv/consts/IPPROTO_ROUTING.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_ROUTING 43 43 43 43 0 diff --git a/libc/sysv/consts/IPPROTO_RSVP.s b/libc/sysv/consts/IPPROTO_RSVP.s new file mode 100644 index 00000000..d5441a72 --- /dev/null +++ b/libc/sysv/consts/IPPROTO_RSVP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_RSVP 46 46 46 46 0 diff --git a/libc/sysv/consts/IPPROTO_SCTP.s b/libc/sysv/consts/IPPROTO_SCTP.s new file mode 100644 index 00000000..de4c9b27 --- /dev/null +++ b/libc/sysv/consts/IPPROTO_SCTP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_SCTP 132 132 132 0 0 diff --git a/libc/sysv/consts/IPPROTO_TCP.s b/libc/sysv/consts/IPPROTO_TCP.s new file mode 100644 index 00000000..48c2887d --- /dev/null +++ b/libc/sysv/consts/IPPROTO_TCP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_TCP 6 6 6 6 6 diff --git a/libc/sysv/consts/IPPROTO_TP.s b/libc/sysv/consts/IPPROTO_TP.s new file mode 100644 index 00000000..af4be751 --- /dev/null +++ b/libc/sysv/consts/IPPROTO_TP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_TP 29 29 29 29 0 diff --git a/libc/sysv/consts/IPPROTO_UDP.s b/libc/sysv/consts/IPPROTO_UDP.s new file mode 100644 index 00000000..2b0f1f2e --- /dev/null +++ b/libc/sysv/consts/IPPROTO_UDP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_UDP 17 17 17 17 17 diff --git a/libc/sysv/consts/IPPROTO_UDPLITE.s b/libc/sysv/consts/IPPROTO_UDPLITE.s new file mode 100644 index 00000000..dbf54db8 --- /dev/null +++ b/libc/sysv/consts/IPPROTO_UDPLITE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon iproto IPPROTO_UDPLITE 136 0 136 0 0 diff --git a/libc/sysv/consts/IPV6_2292DSTOPTS.s b/libc/sysv/consts/IPV6_2292DSTOPTS.s new file mode 100644 index 00000000..f17f7297 --- /dev/null +++ b/libc/sysv/consts/IPV6_2292DSTOPTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_2292DSTOPTS 4 23 0 0 0 diff --git a/libc/sysv/consts/IPV6_2292HOPLIMIT.s b/libc/sysv/consts/IPV6_2292HOPLIMIT.s new file mode 100644 index 00000000..cb6217fc --- /dev/null +++ b/libc/sysv/consts/IPV6_2292HOPLIMIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_2292HOPLIMIT 8 20 0 0 0 diff --git a/libc/sysv/consts/IPV6_2292HOPOPTS.s b/libc/sysv/consts/IPV6_2292HOPOPTS.s new file mode 100644 index 00000000..bbd1f640 --- /dev/null +++ b/libc/sysv/consts/IPV6_2292HOPOPTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_2292HOPOPTS 3 22 0 0 0 diff --git a/libc/sysv/consts/IPV6_2292PKTINFO.s b/libc/sysv/consts/IPV6_2292PKTINFO.s new file mode 100644 index 00000000..bcfcdba5 --- /dev/null +++ b/libc/sysv/consts/IPV6_2292PKTINFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_2292PKTINFO 2 19 0 0 0 diff --git a/libc/sysv/consts/IPV6_2292PKTOPTIONS.s b/libc/sysv/consts/IPV6_2292PKTOPTIONS.s new file mode 100644 index 00000000..33217dfb --- /dev/null +++ b/libc/sysv/consts/IPV6_2292PKTOPTIONS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_2292PKTOPTIONS 6 25 0 0 0 diff --git a/libc/sysv/consts/IPV6_2292RTHDR.s b/libc/sysv/consts/IPV6_2292RTHDR.s new file mode 100644 index 00000000..f895f912 --- /dev/null +++ b/libc/sysv/consts/IPV6_2292RTHDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_2292RTHDR 5 24 0 0 0 diff --git a/libc/sysv/consts/IPV6_ADDRFORM.s b/libc/sysv/consts/IPV6_ADDRFORM.s new file mode 100644 index 00000000..ec2042a7 --- /dev/null +++ b/libc/sysv/consts/IPV6_ADDRFORM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_ADDRFORM 1 0 0 0 0 diff --git a/libc/sysv/consts/IPV6_ADD_MEMBERSHIP.s b/libc/sysv/consts/IPV6_ADD_MEMBERSHIP.s new file mode 100644 index 00000000..832ddaf7 --- /dev/null +++ b/libc/sysv/consts/IPV6_ADD_MEMBERSHIP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_ADD_MEMBERSHIP 20 0 0 0 12 diff --git a/libc/sysv/consts/IPV6_AUTHHDR.s b/libc/sysv/consts/IPV6_AUTHHDR.s new file mode 100644 index 00000000..7281d5b8 --- /dev/null +++ b/libc/sysv/consts/IPV6_AUTHHDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_AUTHHDR 10 0 0 0 0 diff --git a/libc/sysv/consts/IPV6_AUTOFLOWLABEL.s b/libc/sysv/consts/IPV6_AUTOFLOWLABEL.s new file mode 100644 index 00000000..24f97253 --- /dev/null +++ b/libc/sysv/consts/IPV6_AUTOFLOWLABEL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_AUTOFLOWLABEL 0 0 59 59 0 diff --git a/libc/sysv/consts/IPV6_CHECKSUM.s b/libc/sysv/consts/IPV6_CHECKSUM.s new file mode 100644 index 00000000..a5118397 --- /dev/null +++ b/libc/sysv/consts/IPV6_CHECKSUM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_CHECKSUM 7 26 26 26 26 diff --git a/libc/sysv/consts/IPV6_DONTFRAG.s b/libc/sysv/consts/IPV6_DONTFRAG.s new file mode 100644 index 00000000..481f0d90 --- /dev/null +++ b/libc/sysv/consts/IPV6_DONTFRAG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_DONTFRAG 62 0 62 62 14 diff --git a/libc/sysv/consts/IPV6_DROP_MEMBERSHIP.s b/libc/sysv/consts/IPV6_DROP_MEMBERSHIP.s new file mode 100644 index 00000000..d9431f83 --- /dev/null +++ b/libc/sysv/consts/IPV6_DROP_MEMBERSHIP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_DROP_MEMBERSHIP 21 0 0 0 13 diff --git a/libc/sysv/consts/IPV6_DSTOPTS.s b/libc/sysv/consts/IPV6_DSTOPTS.s new file mode 100644 index 00000000..ea23b3b3 --- /dev/null +++ b/libc/sysv/consts/IPV6_DSTOPTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_DSTOPTS 59 0 50 50 0 diff --git a/libc/sysv/consts/IPV6_HDRINCL.s b/libc/sysv/consts/IPV6_HDRINCL.s new file mode 100644 index 00000000..d0e9fac3 --- /dev/null +++ b/libc/sysv/consts/IPV6_HDRINCL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_HDRINCL 36 0 0 0 2 diff --git a/libc/sysv/consts/IPV6_HOPLIMIT.s b/libc/sysv/consts/IPV6_HOPLIMIT.s new file mode 100644 index 00000000..1363ea28 --- /dev/null +++ b/libc/sysv/consts/IPV6_HOPLIMIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_HOPLIMIT 52 0 47 47 21 diff --git a/libc/sysv/consts/IPV6_HOPOPTS.s b/libc/sysv/consts/IPV6_HOPOPTS.s new file mode 100644 index 00000000..6e7e4439 --- /dev/null +++ b/libc/sysv/consts/IPV6_HOPOPTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_HOPOPTS 54 0 49 49 1 diff --git a/libc/sysv/consts/IPV6_IPSEC_POLICY.s b/libc/sysv/consts/IPV6_IPSEC_POLICY.s new file mode 100644 index 00000000..2180009f --- /dev/null +++ b/libc/sysv/consts/IPV6_IPSEC_POLICY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_IPSEC_POLICY 34 28 28 0 0 diff --git a/libc/sysv/consts/IPV6_JOIN_ANYCAST.s b/libc/sysv/consts/IPV6_JOIN_ANYCAST.s new file mode 100644 index 00000000..af4d801a --- /dev/null +++ b/libc/sysv/consts/IPV6_JOIN_ANYCAST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_JOIN_ANYCAST 27 0 0 0 0 diff --git a/libc/sysv/consts/IPV6_JOIN_GROUP.s b/libc/sysv/consts/IPV6_JOIN_GROUP.s new file mode 100644 index 00000000..9186b0e9 --- /dev/null +++ b/libc/sysv/consts/IPV6_JOIN_GROUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_JOIN_GROUP 20 12 12 12 12 diff --git a/libc/sysv/consts/IPV6_LEAVE_ANYCAST.s b/libc/sysv/consts/IPV6_LEAVE_ANYCAST.s new file mode 100644 index 00000000..dc34bbcb --- /dev/null +++ b/libc/sysv/consts/IPV6_LEAVE_ANYCAST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_LEAVE_ANYCAST 28 0 0 0 0 diff --git a/libc/sysv/consts/IPV6_LEAVE_GROUP.s b/libc/sysv/consts/IPV6_LEAVE_GROUP.s new file mode 100644 index 00000000..ff67f899 --- /dev/null +++ b/libc/sysv/consts/IPV6_LEAVE_GROUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_LEAVE_GROUP 21 13 13 13 13 diff --git a/libc/sysv/consts/IPV6_MINHOPCOUNT.s b/libc/sysv/consts/IPV6_MINHOPCOUNT.s new file mode 100644 index 00000000..e0fe89f0 --- /dev/null +++ b/libc/sysv/consts/IPV6_MINHOPCOUNT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_MINHOPCOUNT 0 0 0 65 0 diff --git a/libc/sysv/consts/IPV6_MTU.s b/libc/sysv/consts/IPV6_MTU.s new file mode 100644 index 00000000..2503ea20 --- /dev/null +++ b/libc/sysv/consts/IPV6_MTU.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_MTU 24 0 0 0 72 diff --git a/libc/sysv/consts/IPV6_MTU_DISCOVER.s b/libc/sysv/consts/IPV6_MTU_DISCOVER.s new file mode 100644 index 00000000..94fdfe9d --- /dev/null +++ b/libc/sysv/consts/IPV6_MTU_DISCOVER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_MTU_DISCOVER 23 0 0 0 71 diff --git a/libc/sysv/consts/IPV6_MULTICAST_HOPS.s b/libc/sysv/consts/IPV6_MULTICAST_HOPS.s new file mode 100644 index 00000000..51b84ede --- /dev/null +++ b/libc/sysv/consts/IPV6_MULTICAST_HOPS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_MULTICAST_HOPS 18 10 10 10 10 diff --git a/libc/sysv/consts/IPV6_MULTICAST_IF.s b/libc/sysv/consts/IPV6_MULTICAST_IF.s new file mode 100644 index 00000000..639bc118 --- /dev/null +++ b/libc/sysv/consts/IPV6_MULTICAST_IF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_MULTICAST_IF 17 9 9 9 9 diff --git a/libc/sysv/consts/IPV6_MULTICAST_LOOP.s b/libc/sysv/consts/IPV6_MULTICAST_LOOP.s new file mode 100644 index 00000000..0a0f0df7 --- /dev/null +++ b/libc/sysv/consts/IPV6_MULTICAST_LOOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_MULTICAST_LOOP 19 11 11 11 11 diff --git a/libc/sysv/consts/IPV6_NEXTHOP.s b/libc/sysv/consts/IPV6_NEXTHOP.s new file mode 100644 index 00000000..c5b553bd --- /dev/null +++ b/libc/sysv/consts/IPV6_NEXTHOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_NEXTHOP 9 0 48 48 0 diff --git a/libc/sysv/consts/IPV6_ORIGDSTADDR.s b/libc/sysv/consts/IPV6_ORIGDSTADDR.s new file mode 100644 index 00000000..b2297d5d --- /dev/null +++ b/libc/sysv/consts/IPV6_ORIGDSTADDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_ORIGDSTADDR 0 0 72 0 0 diff --git a/libc/sysv/consts/IPV6_PATHMTU.s b/libc/sysv/consts/IPV6_PATHMTU.s new file mode 100644 index 00000000..534f4471 --- /dev/null +++ b/libc/sysv/consts/IPV6_PATHMTU.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_PATHMTU 61 0 44 44 0 diff --git a/libc/sysv/consts/IPV6_PKTINFO.s b/libc/sysv/consts/IPV6_PKTINFO.s new file mode 100644 index 00000000..bdd5434f --- /dev/null +++ b/libc/sysv/consts/IPV6_PKTINFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_PKTINFO 50 0 46 46 19 diff --git a/libc/sysv/consts/IPV6_PMTUDISC_DO.s b/libc/sysv/consts/IPV6_PMTUDISC_DO.s new file mode 100644 index 00000000..188787e8 --- /dev/null +++ b/libc/sysv/consts/IPV6_PMTUDISC_DO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_PMTUDISC_DO 2 0 0 0 0 diff --git a/libc/sysv/consts/IPV6_PMTUDISC_DONT.s b/libc/sysv/consts/IPV6_PMTUDISC_DONT.s new file mode 100644 index 00000000..75484f88 --- /dev/null +++ b/libc/sysv/consts/IPV6_PMTUDISC_DONT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_PMTUDISC_DONT 0 0 0 0 0 diff --git a/libc/sysv/consts/IPV6_PMTUDISC_INTERFACE.s b/libc/sysv/consts/IPV6_PMTUDISC_INTERFACE.s new file mode 100644 index 00000000..d7a8f786 --- /dev/null +++ b/libc/sysv/consts/IPV6_PMTUDISC_INTERFACE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_PMTUDISC_INTERFACE 4 0 0 0 0 diff --git a/libc/sysv/consts/IPV6_PMTUDISC_OMIT.s b/libc/sysv/consts/IPV6_PMTUDISC_OMIT.s new file mode 100644 index 00000000..19a505e8 --- /dev/null +++ b/libc/sysv/consts/IPV6_PMTUDISC_OMIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_PMTUDISC_OMIT 5 0 0 0 0 diff --git a/libc/sysv/consts/IPV6_PMTUDISC_PROBE.s b/libc/sysv/consts/IPV6_PMTUDISC_PROBE.s new file mode 100644 index 00000000..3decbdb8 --- /dev/null +++ b/libc/sysv/consts/IPV6_PMTUDISC_PROBE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_PMTUDISC_PROBE 3 0 0 0 0 diff --git a/libc/sysv/consts/IPV6_PMTUDISC_WANT.s b/libc/sysv/consts/IPV6_PMTUDISC_WANT.s new file mode 100644 index 00000000..5152d538 --- /dev/null +++ b/libc/sysv/consts/IPV6_PMTUDISC_WANT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_PMTUDISC_WANT 1 0 0 0 0 diff --git a/libc/sysv/consts/IPV6_RECVDSTOPTS.s b/libc/sysv/consts/IPV6_RECVDSTOPTS.s new file mode 100644 index 00000000..6abd8933 --- /dev/null +++ b/libc/sysv/consts/IPV6_RECVDSTOPTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_RECVDSTOPTS 58 0 40 40 0 diff --git a/libc/sysv/consts/IPV6_RECVERR.s b/libc/sysv/consts/IPV6_RECVERR.s new file mode 100644 index 00000000..f6a5d794 --- /dev/null +++ b/libc/sysv/consts/IPV6_RECVERR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_RECVERR 25 0 0 0 75 diff --git a/libc/sysv/consts/IPV6_RECVHOPLIMIT.s b/libc/sysv/consts/IPV6_RECVHOPLIMIT.s new file mode 100644 index 00000000..1626a2b1 --- /dev/null +++ b/libc/sysv/consts/IPV6_RECVHOPLIMIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_RECVHOPLIMIT 51 0 37 37 0 diff --git a/libc/sysv/consts/IPV6_RECVHOPOPTS.s b/libc/sysv/consts/IPV6_RECVHOPOPTS.s new file mode 100644 index 00000000..7aa2db62 --- /dev/null +++ b/libc/sysv/consts/IPV6_RECVHOPOPTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_RECVHOPOPTS 53 0 39 39 0 diff --git a/libc/sysv/consts/IPV6_RECVORIGDSTADDR.s b/libc/sysv/consts/IPV6_RECVORIGDSTADDR.s new file mode 100644 index 00000000..18af27f3 --- /dev/null +++ b/libc/sysv/consts/IPV6_RECVORIGDSTADDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_RECVORIGDSTADDR 0 0 72 0 0 diff --git a/libc/sysv/consts/IPV6_RECVPATHMTU.s b/libc/sysv/consts/IPV6_RECVPATHMTU.s new file mode 100644 index 00000000..f0f8c66c --- /dev/null +++ b/libc/sysv/consts/IPV6_RECVPATHMTU.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_RECVPATHMTU 60 0 43 43 0 diff --git a/libc/sysv/consts/IPV6_RECVPKTINFO.s b/libc/sysv/consts/IPV6_RECVPKTINFO.s new file mode 100644 index 00000000..2987a228 --- /dev/null +++ b/libc/sysv/consts/IPV6_RECVPKTINFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_RECVPKTINFO 49 0 36 36 0 diff --git a/libc/sysv/consts/IPV6_RECVRTHDR.s b/libc/sysv/consts/IPV6_RECVRTHDR.s new file mode 100644 index 00000000..e6e3e442 --- /dev/null +++ b/libc/sysv/consts/IPV6_RECVRTHDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_RECVRTHDR 56 0 38 38 38 diff --git a/libc/sysv/consts/IPV6_RECVTCLASS.s b/libc/sysv/consts/IPV6_RECVTCLASS.s new file mode 100644 index 00000000..0de82210 --- /dev/null +++ b/libc/sysv/consts/IPV6_RECVTCLASS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_RECVTCLASS 66 35 57 57 40 diff --git a/libc/sysv/consts/IPV6_ROUTER_ALERT.s b/libc/sysv/consts/IPV6_ROUTER_ALERT.s new file mode 100644 index 00000000..bc67a2eb --- /dev/null +++ b/libc/sysv/consts/IPV6_ROUTER_ALERT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_ROUTER_ALERT 22 0 0 0 0 diff --git a/libc/sysv/consts/IPV6_RTHDR.s b/libc/sysv/consts/IPV6_RTHDR.s new file mode 100644 index 00000000..56d3bf89 --- /dev/null +++ b/libc/sysv/consts/IPV6_RTHDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_RTHDR 57 0 51 51 0x20 diff --git a/libc/sysv/consts/IPV6_RTHDRDSTOPTS.s b/libc/sysv/consts/IPV6_RTHDRDSTOPTS.s new file mode 100644 index 00000000..e3a6b4e2 --- /dev/null +++ b/libc/sysv/consts/IPV6_RTHDRDSTOPTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_RTHDRDSTOPTS 55 0 35 35 0 diff --git a/libc/sysv/consts/IPV6_RTHDR_LOOSE.s b/libc/sysv/consts/IPV6_RTHDR_LOOSE.s new file mode 100644 index 00000000..5adf2f09 --- /dev/null +++ b/libc/sysv/consts/IPV6_RTHDR_LOOSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_RTHDR_LOOSE 0 0 0 0 0 diff --git a/libc/sysv/consts/IPV6_RTHDR_STRICT.s b/libc/sysv/consts/IPV6_RTHDR_STRICT.s new file mode 100644 index 00000000..e510b407 --- /dev/null +++ b/libc/sysv/consts/IPV6_RTHDR_STRICT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_RTHDR_STRICT 1 1 1 0 0 diff --git a/libc/sysv/consts/IPV6_RTHDR_TYPE_0.s b/libc/sysv/consts/IPV6_RTHDR_TYPE_0.s new file mode 100644 index 00000000..4f15a3a4 --- /dev/null +++ b/libc/sysv/consts/IPV6_RTHDR_TYPE_0.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_RTHDR_TYPE_0 0 0 0 0 0 diff --git a/libc/sysv/consts/IPV6_RXDSTOPTS.s b/libc/sysv/consts/IPV6_RXDSTOPTS.s new file mode 100644 index 00000000..b599b729 --- /dev/null +++ b/libc/sysv/consts/IPV6_RXDSTOPTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_RXDSTOPTS 59 0 0 0 0 diff --git a/libc/sysv/consts/IPV6_RXHOPOPTS.s b/libc/sysv/consts/IPV6_RXHOPOPTS.s new file mode 100644 index 00000000..5ca6eca5 --- /dev/null +++ b/libc/sysv/consts/IPV6_RXHOPOPTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_RXHOPOPTS 54 0 0 0 0 diff --git a/libc/sysv/consts/IPV6_TCLASS.s b/libc/sysv/consts/IPV6_TCLASS.s new file mode 100644 index 00000000..0a945582 --- /dev/null +++ b/libc/sysv/consts/IPV6_TCLASS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_TCLASS 67 36 61 61 39 diff --git a/libc/sysv/consts/IPV6_UNICAST_HOPS.s b/libc/sysv/consts/IPV6_UNICAST_HOPS.s new file mode 100644 index 00000000..ef64a305 --- /dev/null +++ b/libc/sysv/consts/IPV6_UNICAST_HOPS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_UNICAST_HOPS 0x10 4 4 4 4 diff --git a/libc/sysv/consts/IPV6_V6ONLY.s b/libc/sysv/consts/IPV6_V6ONLY.s new file mode 100644 index 00000000..a221005c --- /dev/null +++ b/libc/sysv/consts/IPV6_V6ONLY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_V6ONLY 26 27 27 27 27 diff --git a/libc/sysv/consts/IPV6_XFRM_POLICY.s b/libc/sysv/consts/IPV6_XFRM_POLICY.s new file mode 100644 index 00000000..ba3677c7 --- /dev/null +++ b/libc/sysv/consts/IPV6_XFRM_POLICY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ipv6 IPV6_XFRM_POLICY 35 0 0 0 0 diff --git a/libc/sysv/consts/IP_ADD_MEMBERSHIP.s b/libc/sysv/consts/IP_ADD_MEMBERSHIP.s new file mode 100644 index 00000000..21efd9ed --- /dev/null +++ b/libc/sysv/consts/IP_ADD_MEMBERSHIP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_ADD_MEMBERSHIP 35 12 12 12 0 diff --git a/libc/sysv/consts/IP_ADD_SOURCE_MEMBERSHIP.s b/libc/sysv/consts/IP_ADD_SOURCE_MEMBERSHIP.s new file mode 100644 index 00000000..8f7277d8 --- /dev/null +++ b/libc/sysv/consts/IP_ADD_SOURCE_MEMBERSHIP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_ADD_SOURCE_MEMBERSHIP 39 70 70 0 15 diff --git a/libc/sysv/consts/IP_BIND_ADDRESS_NO_PORT.s b/libc/sysv/consts/IP_BIND_ADDRESS_NO_PORT.s new file mode 100644 index 00000000..da2327bf --- /dev/null +++ b/libc/sysv/consts/IP_BIND_ADDRESS_NO_PORT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_BIND_ADDRESS_NO_PORT 24 0 0 0 0 diff --git a/libc/sysv/consts/IP_BLOCK_SOURCE.s b/libc/sysv/consts/IP_BLOCK_SOURCE.s new file mode 100644 index 00000000..10a2ca25 --- /dev/null +++ b/libc/sysv/consts/IP_BLOCK_SOURCE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_BLOCK_SOURCE 38 72 72 0 17 diff --git a/libc/sysv/consts/IP_CHECKSUM.s b/libc/sysv/consts/IP_CHECKSUM.s new file mode 100644 index 00000000..0da72946 --- /dev/null +++ b/libc/sysv/consts/IP_CHECKSUM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_CHECKSUM 23 0 0 0 0 diff --git a/libc/sysv/consts/IP_DEFAULT_MULTICAST_LOOP.s b/libc/sysv/consts/IP_DEFAULT_MULTICAST_LOOP.s new file mode 100644 index 00000000..a38b731f --- /dev/null +++ b/libc/sysv/consts/IP_DEFAULT_MULTICAST_LOOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_DEFAULT_MULTICAST_LOOP 1 1 1 1 1 diff --git a/libc/sysv/consts/IP_DEFAULT_MULTICAST_TTL.s b/libc/sysv/consts/IP_DEFAULT_MULTICAST_TTL.s new file mode 100644 index 00000000..8308b430 --- /dev/null +++ b/libc/sysv/consts/IP_DEFAULT_MULTICAST_TTL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_DEFAULT_MULTICAST_TTL 1 1 1 1 1 diff --git a/libc/sysv/consts/IP_DROP_MEMBERSHIP.s b/libc/sysv/consts/IP_DROP_MEMBERSHIP.s new file mode 100644 index 00000000..a7b6aad6 --- /dev/null +++ b/libc/sysv/consts/IP_DROP_MEMBERSHIP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_DROP_MEMBERSHIP 36 13 13 13 0 diff --git a/libc/sysv/consts/IP_DROP_SOURCE_MEMBERSHIP.s b/libc/sysv/consts/IP_DROP_SOURCE_MEMBERSHIP.s new file mode 100644 index 00000000..5ea733b3 --- /dev/null +++ b/libc/sysv/consts/IP_DROP_SOURCE_MEMBERSHIP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_DROP_SOURCE_MEMBERSHIP 40 71 71 0 0x10 diff --git a/libc/sysv/consts/IP_FREEBIND.s b/libc/sysv/consts/IP_FREEBIND.s new file mode 100644 index 00000000..7a26cda2 --- /dev/null +++ b/libc/sysv/consts/IP_FREEBIND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_FREEBIND 15 0 0 0 0 diff --git a/libc/sysv/consts/IP_HDRINCL.s b/libc/sysv/consts/IP_HDRINCL.s new file mode 100644 index 00000000..252eb82a --- /dev/null +++ b/libc/sysv/consts/IP_HDRINCL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_HDRINCL 3 2 2 2 2 diff --git a/libc/sysv/consts/IP_IPSEC_POLICY.s b/libc/sysv/consts/IP_IPSEC_POLICY.s new file mode 100644 index 00000000..eb9f945b --- /dev/null +++ b/libc/sysv/consts/IP_IPSEC_POLICY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_IPSEC_POLICY 0x10 21 21 0 0 diff --git a/libc/sysv/consts/IP_MAX_MEMBERSHIPS.s b/libc/sysv/consts/IP_MAX_MEMBERSHIPS.s new file mode 100644 index 00000000..836d7a62 --- /dev/null +++ b/libc/sysv/consts/IP_MAX_MEMBERSHIPS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_MAX_MEMBERSHIPS 20 0x0fff 0x0fff 0x0fff 20 diff --git a/libc/sysv/consts/IP_MINTTL.s b/libc/sysv/consts/IP_MINTTL.s new file mode 100644 index 00000000..2d9b27ac --- /dev/null +++ b/libc/sysv/consts/IP_MINTTL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_MINTTL 21 0 66 0x20 0 diff --git a/libc/sysv/consts/IP_MSFILTER.s b/libc/sysv/consts/IP_MSFILTER.s new file mode 100644 index 00000000..bb8a6028 --- /dev/null +++ b/libc/sysv/consts/IP_MSFILTER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_MSFILTER 41 74 74 0 0 diff --git a/libc/sysv/consts/IP_MTU.s b/libc/sysv/consts/IP_MTU.s new file mode 100644 index 00000000..d21b914a --- /dev/null +++ b/libc/sysv/consts/IP_MTU.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_MTU 14 0 0 0 73 diff --git a/libc/sysv/consts/IP_MTU_DISCOVER.s b/libc/sysv/consts/IP_MTU_DISCOVER.s new file mode 100644 index 00000000..0c718584 --- /dev/null +++ b/libc/sysv/consts/IP_MTU_DISCOVER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_MTU_DISCOVER 10 0 0 0 71 diff --git a/libc/sysv/consts/IP_MULTICAST_ALL.s b/libc/sysv/consts/IP_MULTICAST_ALL.s new file mode 100644 index 00000000..3fbcfba7 --- /dev/null +++ b/libc/sysv/consts/IP_MULTICAST_ALL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_MULTICAST_ALL 49 0 0 0 0 diff --git a/libc/sysv/consts/IP_MULTICAST_IF.s b/libc/sysv/consts/IP_MULTICAST_IF.s new file mode 100644 index 00000000..27049841 --- /dev/null +++ b/libc/sysv/consts/IP_MULTICAST_IF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_MULTICAST_IF 0x20 9 9 9 0 diff --git a/libc/sysv/consts/IP_MULTICAST_LOOP.s b/libc/sysv/consts/IP_MULTICAST_LOOP.s new file mode 100644 index 00000000..6aa1d0a3 --- /dev/null +++ b/libc/sysv/consts/IP_MULTICAST_LOOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_MULTICAST_LOOP 34 11 11 11 0 diff --git a/libc/sysv/consts/IP_MULTICAST_TTL.s b/libc/sysv/consts/IP_MULTICAST_TTL.s new file mode 100644 index 00000000..dc690e5f --- /dev/null +++ b/libc/sysv/consts/IP_MULTICAST_TTL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_MULTICAST_TTL 33 10 10 10 0 diff --git a/libc/sysv/consts/IP_NODEFRAG.s b/libc/sysv/consts/IP_NODEFRAG.s new file mode 100644 index 00000000..5548929f --- /dev/null +++ b/libc/sysv/consts/IP_NODEFRAG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_NODEFRAG 22 0 0 0 0 diff --git a/libc/sysv/consts/IP_OPTIONS.s b/libc/sysv/consts/IP_OPTIONS.s new file mode 100644 index 00000000..1a6a159c --- /dev/null +++ b/libc/sysv/consts/IP_OPTIONS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_OPTIONS 4 1 1 1 1 diff --git a/libc/sysv/consts/IP_ORIGDSTADDR.s b/libc/sysv/consts/IP_ORIGDSTADDR.s new file mode 100644 index 00000000..3ef8356d --- /dev/null +++ b/libc/sysv/consts/IP_ORIGDSTADDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_ORIGDSTADDR 20 0 27 0 0 diff --git a/libc/sysv/consts/IP_PASSSEC.s b/libc/sysv/consts/IP_PASSSEC.s new file mode 100644 index 00000000..19f2f4fd --- /dev/null +++ b/libc/sysv/consts/IP_PASSSEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_PASSSEC 18 0 0 0 0 diff --git a/libc/sysv/consts/IP_PKTINFO.s b/libc/sysv/consts/IP_PKTINFO.s new file mode 100644 index 00000000..eb83872a --- /dev/null +++ b/libc/sysv/consts/IP_PKTINFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_PKTINFO 8 26 0 0 19 diff --git a/libc/sysv/consts/IP_PKTOPTIONS.s b/libc/sysv/consts/IP_PKTOPTIONS.s new file mode 100644 index 00000000..7d39fe74 --- /dev/null +++ b/libc/sysv/consts/IP_PKTOPTIONS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_PKTOPTIONS 9 0 0 0 0 diff --git a/libc/sysv/consts/IP_PMTUDISC.s b/libc/sysv/consts/IP_PMTUDISC.s new file mode 100644 index 00000000..a5b037ee --- /dev/null +++ b/libc/sysv/consts/IP_PMTUDISC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_PMTUDISC 10 0 0 0 0 diff --git a/libc/sysv/consts/IP_PMTUDISC_DO.s b/libc/sysv/consts/IP_PMTUDISC_DO.s new file mode 100644 index 00000000..0fce070f --- /dev/null +++ b/libc/sysv/consts/IP_PMTUDISC_DO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_PMTUDISC_DO 2 0 0 0 0 diff --git a/libc/sysv/consts/IP_PMTUDISC_DONT.s b/libc/sysv/consts/IP_PMTUDISC_DONT.s new file mode 100644 index 00000000..b31562d2 --- /dev/null +++ b/libc/sysv/consts/IP_PMTUDISC_DONT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_PMTUDISC_DONT 0 0 0 0 0 diff --git a/libc/sysv/consts/IP_PMTUDISC_INTERFACE.s b/libc/sysv/consts/IP_PMTUDISC_INTERFACE.s new file mode 100644 index 00000000..50ff25cd --- /dev/null +++ b/libc/sysv/consts/IP_PMTUDISC_INTERFACE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_PMTUDISC_INTERFACE 4 0 0 0 0 diff --git a/libc/sysv/consts/IP_PMTUDISC_OMIT.s b/libc/sysv/consts/IP_PMTUDISC_OMIT.s new file mode 100644 index 00000000..47ce295f --- /dev/null +++ b/libc/sysv/consts/IP_PMTUDISC_OMIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_PMTUDISC_OMIT 5 0 0 0 0 diff --git a/libc/sysv/consts/IP_PMTUDISC_PROBE.s b/libc/sysv/consts/IP_PMTUDISC_PROBE.s new file mode 100644 index 00000000..7a3a769f --- /dev/null +++ b/libc/sysv/consts/IP_PMTUDISC_PROBE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_PMTUDISC_PROBE 3 0 0 0 0 diff --git a/libc/sysv/consts/IP_PMTUDISC_WANT.s b/libc/sysv/consts/IP_PMTUDISC_WANT.s new file mode 100644 index 00000000..8908c7e1 --- /dev/null +++ b/libc/sysv/consts/IP_PMTUDISC_WANT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_PMTUDISC_WANT 1 0 0 0 0 diff --git a/libc/sysv/consts/IP_RECVERR.s b/libc/sysv/consts/IP_RECVERR.s new file mode 100644 index 00000000..3951f802 --- /dev/null +++ b/libc/sysv/consts/IP_RECVERR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_RECVERR 11 0 0 0 75 diff --git a/libc/sysv/consts/IP_RECVOPTS.s b/libc/sysv/consts/IP_RECVOPTS.s new file mode 100644 index 00000000..522bf739 --- /dev/null +++ b/libc/sysv/consts/IP_RECVOPTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_RECVOPTS 6 5 5 5 0 diff --git a/libc/sysv/consts/IP_RECVORIGDSTADDR.s b/libc/sysv/consts/IP_RECVORIGDSTADDR.s new file mode 100644 index 00000000..d821453f --- /dev/null +++ b/libc/sysv/consts/IP_RECVORIGDSTADDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_RECVORIGDSTADDR 20 0 27 0 0 diff --git a/libc/sysv/consts/IP_RECVRETOPTS.s b/libc/sysv/consts/IP_RECVRETOPTS.s new file mode 100644 index 00000000..e18697f2 --- /dev/null +++ b/libc/sysv/consts/IP_RECVRETOPTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_RECVRETOPTS 7 6 6 6 0 diff --git a/libc/sysv/consts/IP_RECVTOS.s b/libc/sysv/consts/IP_RECVTOS.s new file mode 100644 index 00000000..f293ca07 --- /dev/null +++ b/libc/sysv/consts/IP_RECVTOS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_RECVTOS 13 0 68 0 40 diff --git a/libc/sysv/consts/IP_RECVTTL.s b/libc/sysv/consts/IP_RECVTTL.s new file mode 100644 index 00000000..97362933 --- /dev/null +++ b/libc/sysv/consts/IP_RECVTTL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_RECVTTL 12 24 65 31 21 diff --git a/libc/sysv/consts/IP_RETOPTS.s b/libc/sysv/consts/IP_RETOPTS.s new file mode 100644 index 00000000..8c2b41a6 --- /dev/null +++ b/libc/sysv/consts/IP_RETOPTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_RETOPTS 7 8 8 8 0 diff --git a/libc/sysv/consts/IP_ROUTER_ALERT.s b/libc/sysv/consts/IP_ROUTER_ALERT.s new file mode 100644 index 00000000..df0ee5e2 --- /dev/null +++ b/libc/sysv/consts/IP_ROUTER_ALERT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_ROUTER_ALERT 5 0 0 0 0 diff --git a/libc/sysv/consts/IP_TOS.s b/libc/sysv/consts/IP_TOS.s new file mode 100644 index 00000000..82d41d2e --- /dev/null +++ b/libc/sysv/consts/IP_TOS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_TOS 1 3 3 3 8 diff --git a/libc/sysv/consts/IP_TRANSPARENT.s b/libc/sysv/consts/IP_TRANSPARENT.s new file mode 100644 index 00000000..d5735d81 --- /dev/null +++ b/libc/sysv/consts/IP_TRANSPARENT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_TRANSPARENT 19 0 0 0 0 diff --git a/libc/sysv/consts/IP_TTL.s b/libc/sysv/consts/IP_TTL.s new file mode 100644 index 00000000..51c6be05 --- /dev/null +++ b/libc/sysv/consts/IP_TTL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_TTL 2 4 4 4 0 diff --git a/libc/sysv/consts/IP_UNBLOCK_SOURCE.s b/libc/sysv/consts/IP_UNBLOCK_SOURCE.s new file mode 100644 index 00000000..09542890 --- /dev/null +++ b/libc/sysv/consts/IP_UNBLOCK_SOURCE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_UNBLOCK_SOURCE 37 73 73 0 18 diff --git a/libc/sysv/consts/IP_UNICAST_IF.s b/libc/sysv/consts/IP_UNICAST_IF.s new file mode 100644 index 00000000..dd6b7040 --- /dev/null +++ b/libc/sysv/consts/IP_UNICAST_IF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_UNICAST_IF 50 0 0 0 31 diff --git a/libc/sysv/consts/IP_XFRM_POLICY.s b/libc/sysv/consts/IP_XFRM_POLICY.s new file mode 100644 index 00000000..1549f38c --- /dev/null +++ b/libc/sysv/consts/IP_XFRM_POLICY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ip IP_XFRM_POLICY 17 0 0 0 0 diff --git a/libc/sysv/consts/ISIG.s b/libc/sysv/consts/ISIG.s new file mode 100644 index 00000000..42e5cb34 --- /dev/null +++ b/libc/sysv/consts/ISIG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios ISIG 0b0000000000000001 0b0000000010000000 0b0000000010000000 0b0000000010000000 0b0000000000000001 diff --git a/libc/sysv/consts/ISTRIP.s b/libc/sysv/consts/ISTRIP.s new file mode 100644 index 00000000..53965f28 --- /dev/null +++ b/libc/sysv/consts/ISTRIP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios ISTRIP 0b0000000000100000 0b0000000000100000 0b0000000000100000 0b0000000000100000 0b0000000000100000 diff --git a/libc/sysv/consts/ITIMER_PROF.s b/libc/sysv/consts/ITIMER_PROF.s new file mode 100644 index 00000000..b30b66aa --- /dev/null +++ b/libc/sysv/consts/ITIMER_PROF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ITIMER_PROF 2 2 2 2 2 diff --git a/libc/sysv/consts/ITIMER_REAL.s b/libc/sysv/consts/ITIMER_REAL.s new file mode 100644 index 00000000..4938e759 --- /dev/null +++ b/libc/sysv/consts/ITIMER_REAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ITIMER_REAL 0 0 0 0 0 diff --git a/libc/sysv/consts/ITIMER_VIRTUAL.s b/libc/sysv/consts/ITIMER_VIRTUAL.s new file mode 100644 index 00000000..761c7f5d --- /dev/null +++ b/libc/sysv/consts/ITIMER_VIRTUAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ITIMER_VIRTUAL 1 1 1 1 1 diff --git a/libc/sysv/consts/IUCLC.s b/libc/sysv/consts/IUCLC.s new file mode 100644 index 00000000..e41be21e --- /dev/null +++ b/libc/sysv/consts/IUCLC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios IUCLC 0b0000001000000000 0 0 0b0001000000000000 0b0000001000000000 diff --git a/libc/sysv/consts/IUTF8.s b/libc/sysv/consts/IUTF8.s new file mode 100644 index 00000000..3dfd83e8 --- /dev/null +++ b/libc/sysv/consts/IUTF8.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios IUTF8 0b0100000000000000 0b0100000000000000 0 0 0b0100000000000000 diff --git a/libc/sysv/consts/IXANY.s b/libc/sysv/consts/IXANY.s new file mode 100644 index 00000000..9b09d451 --- /dev/null +++ b/libc/sysv/consts/IXANY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios IXANY 0b0000100000000000 0b0000100000000000 0b0000100000000000 0b0000100000000000 0b0000100000000000 diff --git a/libc/sysv/consts/IXOFF.s b/libc/sysv/consts/IXOFF.s new file mode 100644 index 00000000..923d31b4 --- /dev/null +++ b/libc/sysv/consts/IXOFF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios IXOFF 0b0001000000000000 0b0000010000000000 0b0000010000000000 0b0000010000000000 0b0001000000000000 diff --git a/libc/sysv/consts/IXON.s b/libc/sysv/consts/IXON.s new file mode 100644 index 00000000..987b2fc7 --- /dev/null +++ b/libc/sysv/consts/IXON.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios IXON 0b0000010000000000 0b0000001000000000 0b0000001000000000 0b0000001000000000 0b0000010000000000 diff --git a/libc/sysv/consts/LC_ALL.s b/libc/sysv/consts/LC_ALL.s new file mode 100644 index 00000000..a7c02de1 --- /dev/null +++ b/libc/sysv/consts/LC_ALL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LC_ALL 6 0 0 0 0 diff --git a/libc/sysv/consts/LC_ALL_MASK.s b/libc/sysv/consts/LC_ALL_MASK.s new file mode 100644 index 00000000..d71f7912 --- /dev/null +++ b/libc/sysv/consts/LC_ALL_MASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LC_ALL_MASK 0x1fbf 0 63 126 0 diff --git a/libc/sysv/consts/LC_COLLATE.s b/libc/sysv/consts/LC_COLLATE.s new file mode 100644 index 00000000..3a0b1dd2 --- /dev/null +++ b/libc/sysv/consts/LC_COLLATE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LC_COLLATE 3 1 1 1 0 diff --git a/libc/sysv/consts/LC_COLLATE_MASK.s b/libc/sysv/consts/LC_COLLATE_MASK.s new file mode 100644 index 00000000..a4a46178 --- /dev/null +++ b/libc/sysv/consts/LC_COLLATE_MASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LC_COLLATE_MASK 8 0 1 2 0 diff --git a/libc/sysv/consts/LC_CTYPE.s b/libc/sysv/consts/LC_CTYPE.s new file mode 100644 index 00000000..6e8fe4f5 --- /dev/null +++ b/libc/sysv/consts/LC_CTYPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LC_CTYPE 0 2 2 2 0 diff --git a/libc/sysv/consts/LC_CTYPE_MASK.s b/libc/sysv/consts/LC_CTYPE_MASK.s new file mode 100644 index 00000000..44cfb4c0 --- /dev/null +++ b/libc/sysv/consts/LC_CTYPE_MASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LC_CTYPE_MASK 1 0 2 4 0 diff --git a/libc/sysv/consts/LC_MESSAGES.s b/libc/sysv/consts/LC_MESSAGES.s new file mode 100644 index 00000000..bd7445d2 --- /dev/null +++ b/libc/sysv/consts/LC_MESSAGES.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LC_MESSAGES 5 6 6 6 0 diff --git a/libc/sysv/consts/LC_MESSAGES_MASK.s b/libc/sysv/consts/LC_MESSAGES_MASK.s new file mode 100644 index 00000000..c34f4fe7 --- /dev/null +++ b/libc/sysv/consts/LC_MESSAGES_MASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LC_MESSAGES_MASK 0x20 0 0x20 0x40 0 diff --git a/libc/sysv/consts/LC_MONETARY.s b/libc/sysv/consts/LC_MONETARY.s new file mode 100644 index 00000000..fd7e9134 --- /dev/null +++ b/libc/sysv/consts/LC_MONETARY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LC_MONETARY 4 3 3 3 0 diff --git a/libc/sysv/consts/LC_MONETARY_MASK.s b/libc/sysv/consts/LC_MONETARY_MASK.s new file mode 100644 index 00000000..2aec4613 --- /dev/null +++ b/libc/sysv/consts/LC_MONETARY_MASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LC_MONETARY_MASK 0x10 0 4 8 0 diff --git a/libc/sysv/consts/LC_NUMERIC.s b/libc/sysv/consts/LC_NUMERIC.s new file mode 100644 index 00000000..74296d5b --- /dev/null +++ b/libc/sysv/consts/LC_NUMERIC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LC_NUMERIC 1 4 4 4 0 diff --git a/libc/sysv/consts/LC_NUMERIC_MASK.s b/libc/sysv/consts/LC_NUMERIC_MASK.s new file mode 100644 index 00000000..4ce30676 --- /dev/null +++ b/libc/sysv/consts/LC_NUMERIC_MASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LC_NUMERIC_MASK 2 0 8 0x10 0 diff --git a/libc/sysv/consts/LC_TIME.s b/libc/sysv/consts/LC_TIME.s new file mode 100644 index 00000000..b16d86f3 --- /dev/null +++ b/libc/sysv/consts/LC_TIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LC_TIME 2 5 5 5 0 diff --git a/libc/sysv/consts/LC_TIME_MASK.s b/libc/sysv/consts/LC_TIME_MASK.s new file mode 100644 index 00000000..87b9fd99 --- /dev/null +++ b/libc/sysv/consts/LC_TIME_MASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LC_TIME_MASK 4 0 0x10 0x20 0 diff --git a/libc/sysv/consts/LINE_MAX.s b/libc/sysv/consts/LINE_MAX.s new file mode 100644 index 00000000..00ce1187 --- /dev/null +++ b/libc/sysv/consts/LINE_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LINE_MAX 0x0800 0x0800 0x0800 0x0800 0 diff --git a/libc/sysv/consts/LINKED_CMD_COMPLETE.s b/libc/sysv/consts/LINKED_CMD_COMPLETE.s new file mode 100644 index 00000000..47fa83cb --- /dev/null +++ b/libc/sysv/consts/LINKED_CMD_COMPLETE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LINKED_CMD_COMPLETE 10 0 0 0 0 diff --git a/libc/sysv/consts/LINKED_FLG_CMD_COMPLETE.s b/libc/sysv/consts/LINKED_FLG_CMD_COMPLETE.s new file mode 100644 index 00000000..a4c80b03 --- /dev/null +++ b/libc/sysv/consts/LINKED_FLG_CMD_COMPLETE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LINKED_FLG_CMD_COMPLETE 11 0 0 0 0 diff --git a/libc/sysv/consts/LIO_NOP.s b/libc/sysv/consts/LIO_NOP.s new file mode 100644 index 00000000..c729a3bb --- /dev/null +++ b/libc/sysv/consts/LIO_NOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LIO_NOP 2 0 0 0 0 diff --git a/libc/sysv/consts/LIO_NOWAIT.s b/libc/sysv/consts/LIO_NOWAIT.s new file mode 100644 index 00000000..aa3f7c8c --- /dev/null +++ b/libc/sysv/consts/LIO_NOWAIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LIO_NOWAIT 1 1 0 0 0 diff --git a/libc/sysv/consts/LIO_READ.s b/libc/sysv/consts/LIO_READ.s new file mode 100644 index 00000000..966f2127 --- /dev/null +++ b/libc/sysv/consts/LIO_READ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LIO_READ 0 1 2 0 0 diff --git a/libc/sysv/consts/LIO_WAIT.s b/libc/sysv/consts/LIO_WAIT.s new file mode 100644 index 00000000..a21893aa --- /dev/null +++ b/libc/sysv/consts/LIO_WAIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LIO_WAIT 0 2 1 0 0 diff --git a/libc/sysv/consts/LIO_WRITE.s b/libc/sysv/consts/LIO_WRITE.s new file mode 100644 index 00000000..5e70cd2a --- /dev/null +++ b/libc/sysv/consts/LIO_WRITE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LIO_WRITE 1 2 1 0 0 diff --git a/libc/sysv/consts/LITTLE_ENDIAN.s b/libc/sysv/consts/LITTLE_ENDIAN.s new file mode 100644 index 00000000..45633723 --- /dev/null +++ b/libc/sysv/consts/LITTLE_ENDIAN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LITTLE_ENDIAN 0x04d2 0x04d2 0x04d2 0x04d2 0 diff --git a/libc/sysv/consts/LNKTYPE.s b/libc/sysv/consts/LNKTYPE.s new file mode 100644 index 00000000..d6399fd5 --- /dev/null +++ b/libc/sysv/consts/LNKTYPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LNKTYPE 49 49 49 49 0 diff --git a/libc/sysv/consts/LOCK_EX.s b/libc/sysv/consts/LOCK_EX.s new file mode 100644 index 00000000..0fd29d05 --- /dev/null +++ b/libc/sysv/consts/LOCK_EX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon lock LOCK_EX 2 2 2 2 2 diff --git a/libc/sysv/consts/LOCK_NB.s b/libc/sysv/consts/LOCK_NB.s new file mode 100644 index 00000000..b7c903fd --- /dev/null +++ b/libc/sysv/consts/LOCK_NB.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon lock LOCK_NB 4 4 4 4 1 diff --git a/libc/sysv/consts/LOCK_SH.s b/libc/sysv/consts/LOCK_SH.s new file mode 100644 index 00000000..0a9308f0 --- /dev/null +++ b/libc/sysv/consts/LOCK_SH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon lock LOCK_SH 1 1 1 1 0 diff --git a/libc/sysv/consts/LOCK_UN.s b/libc/sysv/consts/LOCK_UN.s new file mode 100644 index 00000000..e9aeb8ec --- /dev/null +++ b/libc/sysv/consts/LOCK_UN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon lock LOCK_UN 8 8 8 8 8 diff --git a/libc/sysv/consts/LOCK_UNLOCK_CACHE.s b/libc/sysv/consts/LOCK_UNLOCK_CACHE.s new file mode 100644 index 00000000..e5ba4669 --- /dev/null +++ b/libc/sysv/consts/LOCK_UNLOCK_CACHE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon lock LOCK_UNLOCK_CACHE 54 0 0 0 0 diff --git a/libc/sysv/consts/LOGIN_NAME_MAX.s b/libc/sysv/consts/LOGIN_NAME_MAX.s new file mode 100644 index 00000000..f3f3135c --- /dev/null +++ b/libc/sysv/consts/LOGIN_NAME_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LOGIN_NAME_MAX 0x0100 0 0 0x20 0 diff --git a/libc/sysv/consts/LOGIN_PROCESS.s b/libc/sysv/consts/LOGIN_PROCESS.s new file mode 100644 index 00000000..0ce32bec --- /dev/null +++ b/libc/sysv/consts/LOGIN_PROCESS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc LOGIN_PROCESS 6 6 6 0 0 diff --git a/libc/sysv/consts/LOG_ALERT.s b/libc/sysv/consts/LOG_ALERT.s new file mode 100644 index 00000000..fc3b39d3 --- /dev/null +++ b/libc/sysv/consts/LOG_ALERT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_ALERT 1 1 1 1 0 diff --git a/libc/sysv/consts/LOG_AUTH.s b/libc/sysv/consts/LOG_AUTH.s new file mode 100644 index 00000000..7d2ec0ac --- /dev/null +++ b/libc/sysv/consts/LOG_AUTH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_AUTH 0x20 0x20 0x20 0x20 0 diff --git a/libc/sysv/consts/LOG_CONS.s b/libc/sysv/consts/LOG_CONS.s new file mode 100644 index 00000000..f0763054 --- /dev/null +++ b/libc/sysv/consts/LOG_CONS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_CONS 2 2 2 2 0 diff --git a/libc/sysv/consts/LOG_CRIT.s b/libc/sysv/consts/LOG_CRIT.s new file mode 100644 index 00000000..d848003a --- /dev/null +++ b/libc/sysv/consts/LOG_CRIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_CRIT 2 2 2 2 0 diff --git a/libc/sysv/consts/LOG_CRON.s b/libc/sysv/consts/LOG_CRON.s new file mode 100644 index 00000000..d4c69b60 --- /dev/null +++ b/libc/sysv/consts/LOG_CRON.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_CRON 72 72 72 72 0 diff --git a/libc/sysv/consts/LOG_DAEMON.s b/libc/sysv/consts/LOG_DAEMON.s new file mode 100644 index 00000000..00558448 --- /dev/null +++ b/libc/sysv/consts/LOG_DAEMON.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_DAEMON 24 24 24 24 0 diff --git a/libc/sysv/consts/LOG_DEBUG.s b/libc/sysv/consts/LOG_DEBUG.s new file mode 100644 index 00000000..e9a38b3d --- /dev/null +++ b/libc/sysv/consts/LOG_DEBUG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_DEBUG 7 7 7 7 0 diff --git a/libc/sysv/consts/LOG_EMERG.s b/libc/sysv/consts/LOG_EMERG.s new file mode 100644 index 00000000..2522b088 --- /dev/null +++ b/libc/sysv/consts/LOG_EMERG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_EMERG 0 0 0 0 0 diff --git a/libc/sysv/consts/LOG_ERR.s b/libc/sysv/consts/LOG_ERR.s new file mode 100644 index 00000000..622047a2 --- /dev/null +++ b/libc/sysv/consts/LOG_ERR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_ERR 3 3 3 3 0 diff --git a/libc/sysv/consts/LOG_FACMASK.s b/libc/sysv/consts/LOG_FACMASK.s new file mode 100644 index 00000000..4f680f0c --- /dev/null +++ b/libc/sysv/consts/LOG_FACMASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_FACMASK 0x03f8 0x03f8 0x03f8 0x03f8 0 diff --git a/libc/sysv/consts/LOG_INFO.s b/libc/sysv/consts/LOG_INFO.s new file mode 100644 index 00000000..21d61653 --- /dev/null +++ b/libc/sysv/consts/LOG_INFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_INFO 6 6 6 6 0 diff --git a/libc/sysv/consts/LOG_KERN.s b/libc/sysv/consts/LOG_KERN.s new file mode 100644 index 00000000..ce91d5bd --- /dev/null +++ b/libc/sysv/consts/LOG_KERN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_KERN 0 0 0 0 0 diff --git a/libc/sysv/consts/LOG_LOCAL0.s b/libc/sysv/consts/LOG_LOCAL0.s new file mode 100644 index 00000000..84d037b5 --- /dev/null +++ b/libc/sysv/consts/LOG_LOCAL0.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_LOCAL0 0x80 0x80 0x80 0x80 0 diff --git a/libc/sysv/consts/LOG_LOCAL1.s b/libc/sysv/consts/LOG_LOCAL1.s new file mode 100644 index 00000000..f48482a6 --- /dev/null +++ b/libc/sysv/consts/LOG_LOCAL1.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_LOCAL1 136 136 136 136 0 diff --git a/libc/sysv/consts/LOG_LOCAL2.s b/libc/sysv/consts/LOG_LOCAL2.s new file mode 100644 index 00000000..6d90598c --- /dev/null +++ b/libc/sysv/consts/LOG_LOCAL2.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_LOCAL2 144 144 144 144 0 diff --git a/libc/sysv/consts/LOG_LOCAL3.s b/libc/sysv/consts/LOG_LOCAL3.s new file mode 100644 index 00000000..abaa9dd0 --- /dev/null +++ b/libc/sysv/consts/LOG_LOCAL3.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_LOCAL3 152 152 152 152 0 diff --git a/libc/sysv/consts/LOG_LOCAL4.s b/libc/sysv/consts/LOG_LOCAL4.s new file mode 100644 index 00000000..6febf25b --- /dev/null +++ b/libc/sysv/consts/LOG_LOCAL4.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_LOCAL4 160 160 160 160 0 diff --git a/libc/sysv/consts/LOG_LOCAL5.s b/libc/sysv/consts/LOG_LOCAL5.s new file mode 100644 index 00000000..0c3fbdff --- /dev/null +++ b/libc/sysv/consts/LOG_LOCAL5.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_LOCAL5 168 168 168 168 0 diff --git a/libc/sysv/consts/LOG_LOCAL6.s b/libc/sysv/consts/LOG_LOCAL6.s new file mode 100644 index 00000000..e80e9920 --- /dev/null +++ b/libc/sysv/consts/LOG_LOCAL6.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_LOCAL6 176 176 176 176 0 diff --git a/libc/sysv/consts/LOG_LOCAL7.s b/libc/sysv/consts/LOG_LOCAL7.s new file mode 100644 index 00000000..6917a4c7 --- /dev/null +++ b/libc/sysv/consts/LOG_LOCAL7.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_LOCAL7 184 184 184 184 0 diff --git a/libc/sysv/consts/LOG_LPR.s b/libc/sysv/consts/LOG_LPR.s new file mode 100644 index 00000000..fcd6dda4 --- /dev/null +++ b/libc/sysv/consts/LOG_LPR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_LPR 48 48 48 48 0 diff --git a/libc/sysv/consts/LOG_MAIL.s b/libc/sysv/consts/LOG_MAIL.s new file mode 100644 index 00000000..0daeffbb --- /dev/null +++ b/libc/sysv/consts/LOG_MAIL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_MAIL 0x10 0x10 0x10 0x10 0 diff --git a/libc/sysv/consts/LOG_NDELAY.s b/libc/sysv/consts/LOG_NDELAY.s new file mode 100644 index 00000000..d1e7bf6b --- /dev/null +++ b/libc/sysv/consts/LOG_NDELAY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_NDELAY 8 8 8 8 0 diff --git a/libc/sysv/consts/LOG_NEWS.s b/libc/sysv/consts/LOG_NEWS.s new file mode 100644 index 00000000..7016d0f3 --- /dev/null +++ b/libc/sysv/consts/LOG_NEWS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_NEWS 56 56 56 56 0 diff --git a/libc/sysv/consts/LOG_NFACILITIES.s b/libc/sysv/consts/LOG_NFACILITIES.s new file mode 100644 index 00000000..2484ab80 --- /dev/null +++ b/libc/sysv/consts/LOG_NFACILITIES.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_NFACILITIES 24 25 24 24 0 diff --git a/libc/sysv/consts/LOG_NOTICE.s b/libc/sysv/consts/LOG_NOTICE.s new file mode 100644 index 00000000..ab13babe --- /dev/null +++ b/libc/sysv/consts/LOG_NOTICE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_NOTICE 5 5 5 5 0 diff --git a/libc/sysv/consts/LOG_NOWAIT.s b/libc/sysv/consts/LOG_NOWAIT.s new file mode 100644 index 00000000..72c31a5d --- /dev/null +++ b/libc/sysv/consts/LOG_NOWAIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_NOWAIT 0x10 0x10 0x10 0x10 0 diff --git a/libc/sysv/consts/LOG_ODELAY.s b/libc/sysv/consts/LOG_ODELAY.s new file mode 100644 index 00000000..c9ab86d7 --- /dev/null +++ b/libc/sysv/consts/LOG_ODELAY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_ODELAY 4 4 4 4 0 diff --git a/libc/sysv/consts/LOG_PERROR.s b/libc/sysv/consts/LOG_PERROR.s new file mode 100644 index 00000000..8c433d14 --- /dev/null +++ b/libc/sysv/consts/LOG_PERROR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_PERROR 0x20 0x20 0x20 0x20 0 diff --git a/libc/sysv/consts/LOG_PID.s b/libc/sysv/consts/LOG_PID.s new file mode 100644 index 00000000..7c221c48 --- /dev/null +++ b/libc/sysv/consts/LOG_PID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_PID 1 1 1 1 0 diff --git a/libc/sysv/consts/LOG_PRIMASK.s b/libc/sysv/consts/LOG_PRIMASK.s new file mode 100644 index 00000000..903030ab --- /dev/null +++ b/libc/sysv/consts/LOG_PRIMASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_PRIMASK 7 7 7 7 0 diff --git a/libc/sysv/consts/LOG_SELECT.s b/libc/sysv/consts/LOG_SELECT.s new file mode 100644 index 00000000..0a68b95e --- /dev/null +++ b/libc/sysv/consts/LOG_SELECT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_SELECT 76 0 0 0 0 diff --git a/libc/sysv/consts/LOG_SENSE.s b/libc/sysv/consts/LOG_SENSE.s new file mode 100644 index 00000000..bf13067a --- /dev/null +++ b/libc/sysv/consts/LOG_SENSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_SENSE 77 0 0 0 0 diff --git a/libc/sysv/consts/LOG_SYSLOG.s b/libc/sysv/consts/LOG_SYSLOG.s new file mode 100644 index 00000000..178a0139 --- /dev/null +++ b/libc/sysv/consts/LOG_SYSLOG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_SYSLOG 40 40 40 40 0 diff --git a/libc/sysv/consts/LOG_USER.s b/libc/sysv/consts/LOG_USER.s new file mode 100644 index 00000000..b718ca12 --- /dev/null +++ b/libc/sysv/consts/LOG_USER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_USER 8 8 8 8 0 diff --git a/libc/sysv/consts/LOG_UUCP.s b/libc/sysv/consts/LOG_UUCP.s new file mode 100644 index 00000000..2c26b554 --- /dev/null +++ b/libc/sysv/consts/LOG_UUCP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_UUCP 0x40 0x40 0x40 0x40 0 diff --git a/libc/sysv/consts/LOG_WARNING.s b/libc/sysv/consts/LOG_WARNING.s new file mode 100644 index 00000000..1608461e --- /dev/null +++ b/libc/sysv/consts/LOG_WARNING.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon log LOG_WARNING 4 4 4 4 0 diff --git a/libc/sysv/consts/L_INCR.s b/libc/sysv/consts/L_INCR.s new file mode 100644 index 00000000..5f8162cb --- /dev/null +++ b/libc/sysv/consts/L_INCR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc L_INCR 1 1 1 1 0 diff --git a/libc/sysv/consts/L_SET.s b/libc/sysv/consts/L_SET.s new file mode 100644 index 00000000..2ba39d98 --- /dev/null +++ b/libc/sysv/consts/L_SET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc L_SET 0 0 0 0 0 diff --git a/libc/sysv/consts/L_XTND.s b/libc/sysv/consts/L_XTND.s new file mode 100644 index 00000000..a42ad28a --- /dev/null +++ b/libc/sysv/consts/L_XTND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc L_XTND 2 2 2 2 0 diff --git a/libc/sysv/consts/MADV_DODUMP.s b/libc/sysv/consts/MADV_DODUMP.s new file mode 100644 index 00000000..bbe212ac --- /dev/null +++ b/libc/sysv/consts/MADV_DODUMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon madv MADV_DODUMP 17 0 0 0 0 diff --git a/libc/sysv/consts/MADV_DOFORK.s b/libc/sysv/consts/MADV_DOFORK.s new file mode 100644 index 00000000..bc991415 --- /dev/null +++ b/libc/sysv/consts/MADV_DOFORK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon madv MADV_DOFORK 11 0 0 0 0 diff --git a/libc/sysv/consts/MADV_DONTDUMP.s b/libc/sysv/consts/MADV_DONTDUMP.s new file mode 100644 index 00000000..09606244 --- /dev/null +++ b/libc/sysv/consts/MADV_DONTDUMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon madv MADV_DONTDUMP 0x10 0 0 0 0 diff --git a/libc/sysv/consts/MADV_DONTFORK.s b/libc/sysv/consts/MADV_DONTFORK.s new file mode 100644 index 00000000..2e4815e5 --- /dev/null +++ b/libc/sysv/consts/MADV_DONTFORK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon madv MADV_DONTFORK 10 0 0 0 0 diff --git a/libc/sysv/consts/MADV_DONTNEED.s b/libc/sysv/consts/MADV_DONTNEED.s new file mode 100644 index 00000000..cf5181da --- /dev/null +++ b/libc/sysv/consts/MADV_DONTNEED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon madv MADV_DONTNEED 4 4 4 4 0 diff --git a/libc/sysv/consts/MADV_FREE.s b/libc/sysv/consts/MADV_FREE.s new file mode 100644 index 00000000..b3b7d2c1 --- /dev/null +++ b/libc/sysv/consts/MADV_FREE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon madv MADV_FREE 8 5 5 6 8 diff --git a/libc/sysv/consts/MADV_HUGEPAGE.s b/libc/sysv/consts/MADV_HUGEPAGE.s new file mode 100644 index 00000000..ed97e0d1 --- /dev/null +++ b/libc/sysv/consts/MADV_HUGEPAGE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon madv MADV_HUGEPAGE 14 0 0 0 0 diff --git a/libc/sysv/consts/MADV_HWPOISON.s b/libc/sysv/consts/MADV_HWPOISON.s new file mode 100644 index 00000000..9a5e0cfa --- /dev/null +++ b/libc/sysv/consts/MADV_HWPOISON.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon madv MADV_HWPOISON 100 0 0 0 0 diff --git a/libc/sysv/consts/MADV_MERGEABLE.s b/libc/sysv/consts/MADV_MERGEABLE.s new file mode 100644 index 00000000..906c72c4 --- /dev/null +++ b/libc/sysv/consts/MADV_MERGEABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon madv MADV_MERGEABLE 12 0 0 0 0 diff --git a/libc/sysv/consts/MADV_NOHUGEPAGE.s b/libc/sysv/consts/MADV_NOHUGEPAGE.s new file mode 100644 index 00000000..7e64c61a --- /dev/null +++ b/libc/sysv/consts/MADV_NOHUGEPAGE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon madv MADV_NOHUGEPAGE 15 0 0 0 0 diff --git a/libc/sysv/consts/MADV_NORMAL.s b/libc/sysv/consts/MADV_NORMAL.s new file mode 100644 index 00000000..ac6e615d --- /dev/null +++ b/libc/sysv/consts/MADV_NORMAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon madv MADV_NORMAL 0 0 0 0 0x00000080 diff --git a/libc/sysv/consts/MADV_RANDOM.s b/libc/sysv/consts/MADV_RANDOM.s new file mode 100644 index 00000000..bbf26f97 --- /dev/null +++ b/libc/sysv/consts/MADV_RANDOM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon madv MADV_RANDOM 1 1 1 1 0x10000000 diff --git a/libc/sysv/consts/MADV_REMOVE.s b/libc/sysv/consts/MADV_REMOVE.s new file mode 100644 index 00000000..747758b2 --- /dev/null +++ b/libc/sysv/consts/MADV_REMOVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon madv MADV_REMOVE 9 0 0 0 0 diff --git a/libc/sysv/consts/MADV_SEQUENTIAL.s b/libc/sysv/consts/MADV_SEQUENTIAL.s new file mode 100644 index 00000000..3a3fcada --- /dev/null +++ b/libc/sysv/consts/MADV_SEQUENTIAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon madv MADV_SEQUENTIAL 2 2 2 2 0x8000000 diff --git a/libc/sysv/consts/MADV_UNMERGEABLE.s b/libc/sysv/consts/MADV_UNMERGEABLE.s new file mode 100644 index 00000000..0323dff4 --- /dev/null +++ b/libc/sysv/consts/MADV_UNMERGEABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon madv MADV_UNMERGEABLE 13 0 0 0 0 diff --git a/libc/sysv/consts/MADV_WILLNEED.s b/libc/sysv/consts/MADV_WILLNEED.s new file mode 100644 index 00000000..f292aabd --- /dev/null +++ b/libc/sysv/consts/MADV_WILLNEED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon madv MADV_WILLNEED 3 3 3 3 3 diff --git a/libc/sysv/consts/MAP_32BIT.s b/libc/sysv/consts/MAP_32BIT.s new file mode 100644 index 00000000..cc4b1cee --- /dev/null +++ b/libc/sysv/consts/MAP_32BIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat MAP_32BIT 0x40 0 0x080000 0 0 diff --git a/libc/sysv/consts/MAP_ANON.s b/libc/sysv/consts/MAP_ANON.s new file mode 100644 index 00000000..27e8bec9 --- /dev/null +++ b/libc/sysv/consts/MAP_ANON.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat MAP_ANON 0x20 0x1000 0x1000 0x1000 0x20 diff --git a/libc/sysv/consts/MAP_ANONYMOUS.s b/libc/sysv/consts/MAP_ANONYMOUS.s new file mode 100644 index 00000000..048c3c5c --- /dev/null +++ b/libc/sysv/consts/MAP_ANONYMOUS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mmap MAP_ANONYMOUS 0x20 0x1000 0x1000 0x1000 0x20 diff --git a/libc/sysv/consts/MAP_DENYWRITE.s b/libc/sysv/consts/MAP_DENYWRITE.s new file mode 100644 index 00000000..1222d9cf --- /dev/null +++ b/libc/sysv/consts/MAP_DENYWRITE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat MAP_DENYWRITE 0x0800 0 0 0 0 diff --git a/libc/sysv/consts/MAP_EXECUTABLE.s b/libc/sysv/consts/MAP_EXECUTABLE.s new file mode 100644 index 00000000..7d4abfc9 --- /dev/null +++ b/libc/sysv/consts/MAP_EXECUTABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat MAP_EXECUTABLE 0x1000 0 0 0 0 diff --git a/libc/sysv/consts/MAP_FILE.s b/libc/sysv/consts/MAP_FILE.s new file mode 100644 index 00000000..ace0f9cc --- /dev/null +++ b/libc/sysv/consts/MAP_FILE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat MAP_FILE 0 0 0 0 0 diff --git a/libc/sysv/consts/MAP_FIXED.s b/libc/sysv/consts/MAP_FIXED.s new file mode 100644 index 00000000..59e0fca5 --- /dev/null +++ b/libc/sysv/consts/MAP_FIXED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mmap MAP_FIXED 16 16 16 16 16 diff --git a/libc/sysv/consts/MAP_GROWSDOWN.s b/libc/sysv/consts/MAP_GROWSDOWN.s new file mode 100644 index 00000000..984d336a --- /dev/null +++ b/libc/sysv/consts/MAP_GROWSDOWN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mmap MAP_GROWSDOWN 0x0100 0 0x0400 0x0400 0x100000 diff --git a/libc/sysv/consts/MAP_HUGETLB.s b/libc/sysv/consts/MAP_HUGETLB.s new file mode 100644 index 00000000..a928f3a1 --- /dev/null +++ b/libc/sysv/consts/MAP_HUGETLB.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mmap MAP_HUGETLB 0x040000 0 0 0 0x80000000 diff --git a/libc/sysv/consts/MAP_HUGE_MASK.s b/libc/sysv/consts/MAP_HUGE_MASK.s new file mode 100644 index 00000000..98d89942 --- /dev/null +++ b/libc/sysv/consts/MAP_HUGE_MASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mmap MAP_HUGE_MASK 63 0 0 0 0 diff --git a/libc/sysv/consts/MAP_HUGE_SHIFT.s b/libc/sysv/consts/MAP_HUGE_SHIFT.s new file mode 100644 index 00000000..d7358d9a --- /dev/null +++ b/libc/sysv/consts/MAP_HUGE_SHIFT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mmap MAP_HUGE_SHIFT 26 0 0 0 0 diff --git a/libc/sysv/consts/MAP_LOCKED.s b/libc/sysv/consts/MAP_LOCKED.s new file mode 100644 index 00000000..49733ef4 --- /dev/null +++ b/libc/sysv/consts/MAP_LOCKED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mmap MAP_LOCKED 0x2000 0 0 0 0 diff --git a/libc/sysv/consts/MAP_NONBLOCK.s b/libc/sysv/consts/MAP_NONBLOCK.s new file mode 100644 index 00000000..57a313de --- /dev/null +++ b/libc/sysv/consts/MAP_NONBLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mmap MAP_NONBLOCK 0x010000 0 0 0 0 diff --git a/libc/sysv/consts/MAP_NORESERVE.s b/libc/sysv/consts/MAP_NORESERVE.s new file mode 100644 index 00000000..b28bf022 --- /dev/null +++ b/libc/sysv/consts/MAP_NORESERVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mmap MAP_NORESERVE 0x4000 0x40 0 0 0 diff --git a/libc/sysv/consts/MAP_POPULATE.s b/libc/sysv/consts/MAP_POPULATE.s new file mode 100644 index 00000000..8c7c83da --- /dev/null +++ b/libc/sysv/consts/MAP_POPULATE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mmap MAP_POPULATE 0x8000 0 0 0 0 diff --git a/libc/sysv/consts/MAP_PRIVATE.s b/libc/sysv/consts/MAP_PRIVATE.s new file mode 100644 index 00000000..56d81e92 --- /dev/null +++ b/libc/sysv/consts/MAP_PRIVATE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mmap MAP_PRIVATE 2 2 2 2 2 diff --git a/libc/sysv/consts/MAP_SHARED.s b/libc/sysv/consts/MAP_SHARED.s new file mode 100644 index 00000000..2d670312 --- /dev/null +++ b/libc/sysv/consts/MAP_SHARED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mmap MAP_SHARED 1 1 1 1 1 diff --git a/libc/sysv/consts/MAP_STACK.s b/libc/sysv/consts/MAP_STACK.s new file mode 100644 index 00000000..1dca4e2f --- /dev/null +++ b/libc/sysv/consts/MAP_STACK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat MAP_STACK 0x020000 0 0x0400 0x4000 0x100000 diff --git a/libc/sysv/consts/MAP_TYPE.s b/libc/sysv/consts/MAP_TYPE.s new file mode 100644 index 00000000..d9592720 --- /dev/null +++ b/libc/sysv/consts/MAP_TYPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mmap MAP_TYPE 15 0 0 0 0 diff --git a/libc/sysv/consts/MATH_ERREXCEPT.s b/libc/sysv/consts/MATH_ERREXCEPT.s new file mode 100644 index 00000000..2b46e208 --- /dev/null +++ b/libc/sysv/consts/MATH_ERREXCEPT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MATH_ERREXCEPT 2 2 2 2 0 diff --git a/libc/sysv/consts/MATH_ERRNO.s b/libc/sysv/consts/MATH_ERRNO.s new file mode 100644 index 00000000..b4912412 --- /dev/null +++ b/libc/sysv/consts/MATH_ERRNO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MATH_ERRNO 1 1 1 1 0 diff --git a/libc/sysv/consts/MAXHOSTNAMELEN.s b/libc/sysv/consts/MAXHOSTNAMELEN.s new file mode 100644 index 00000000..1086779a --- /dev/null +++ b/libc/sysv/consts/MAXHOSTNAMELEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MAXHOSTNAMELEN 0x40 0x0100 0x0100 0x0100 0 diff --git a/libc/sysv/consts/MAXNAMLEN.s b/libc/sysv/consts/MAXNAMLEN.s new file mode 100644 index 00000000..55709081 --- /dev/null +++ b/libc/sysv/consts/MAXNAMLEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MAXNAMLEN 255 255 255 255 0 diff --git a/libc/sysv/consts/MAXPATHLEN.s b/libc/sysv/consts/MAXPATHLEN.s new file mode 100644 index 00000000..7ca37a45 --- /dev/null +++ b/libc/sysv/consts/MAXPATHLEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MAXPATHLEN 255 255 255 255 255 diff --git a/libc/sysv/consts/MAXQUOTAS.s b/libc/sysv/consts/MAXQUOTAS.s new file mode 100644 index 00000000..a6a6a798 --- /dev/null +++ b/libc/sysv/consts/MAXQUOTAS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MAXQUOTAS 2 2 2 2 0 diff --git a/libc/sysv/consts/MAXSYMLINKS.s b/libc/sysv/consts/MAXSYMLINKS.s new file mode 100644 index 00000000..94f79202 --- /dev/null +++ b/libc/sysv/consts/MAXSYMLINKS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MAXSYMLINKS 20 0x20 0x20 0x20 0 diff --git a/libc/sysv/consts/MAX_DQ_TIME.s b/libc/sysv/consts/MAX_DQ_TIME.s new file mode 100644 index 00000000..8f098b68 --- /dev/null +++ b/libc/sysv/consts/MAX_DQ_TIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MAX_DQ_TIME 0x093a80 0x093a80 0x093a80 0x093a80 0 diff --git a/libc/sysv/consts/MAX_HANDLE_SZ.s b/libc/sysv/consts/MAX_HANDLE_SZ.s new file mode 100644 index 00000000..e78b62d2 --- /dev/null +++ b/libc/sysv/consts/MAX_HANDLE_SZ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MAX_HANDLE_SZ 0x80 0 0 0 0 diff --git a/libc/sysv/consts/MAX_IQ_TIME.s b/libc/sysv/consts/MAX_IQ_TIME.s new file mode 100644 index 00000000..fdacbc8c --- /dev/null +++ b/libc/sysv/consts/MAX_IQ_TIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MAX_IQ_TIME 0x093a80 0x093a80 0x093a80 0x093a80 0 diff --git a/libc/sysv/consts/MCAST_BLOCK_SOURCE.s b/libc/sysv/consts/MCAST_BLOCK_SOURCE.s new file mode 100644 index 00000000..9a6db5ef --- /dev/null +++ b/libc/sysv/consts/MCAST_BLOCK_SOURCE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MCAST_BLOCK_SOURCE 43 84 84 0 43 diff --git a/libc/sysv/consts/MCAST_EXCLUDE.s b/libc/sysv/consts/MCAST_EXCLUDE.s new file mode 100644 index 00000000..657acb63 --- /dev/null +++ b/libc/sysv/consts/MCAST_EXCLUDE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MCAST_EXCLUDE 0 2 2 0 0 diff --git a/libc/sysv/consts/MCAST_INCLUDE.s b/libc/sysv/consts/MCAST_INCLUDE.s new file mode 100644 index 00000000..41123237 --- /dev/null +++ b/libc/sysv/consts/MCAST_INCLUDE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MCAST_INCLUDE 1 1 1 0 0 diff --git a/libc/sysv/consts/MCAST_JOIN_GROUP.s b/libc/sysv/consts/MCAST_JOIN_GROUP.s new file mode 100644 index 00000000..cd2dd678 --- /dev/null +++ b/libc/sysv/consts/MCAST_JOIN_GROUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MCAST_JOIN_GROUP 42 80 80 0 41 diff --git a/libc/sysv/consts/MCAST_JOIN_SOURCE_GROUP.s b/libc/sysv/consts/MCAST_JOIN_SOURCE_GROUP.s new file mode 100644 index 00000000..73e66cb4 --- /dev/null +++ b/libc/sysv/consts/MCAST_JOIN_SOURCE_GROUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MCAST_JOIN_SOURCE_GROUP 46 82 82 0 45 diff --git a/libc/sysv/consts/MCAST_LEAVE_GROUP.s b/libc/sysv/consts/MCAST_LEAVE_GROUP.s new file mode 100644 index 00000000..4916fe5a --- /dev/null +++ b/libc/sysv/consts/MCAST_LEAVE_GROUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MCAST_LEAVE_GROUP 45 81 81 0 42 diff --git a/libc/sysv/consts/MCAST_LEAVE_SOURCE_GROUP.s b/libc/sysv/consts/MCAST_LEAVE_SOURCE_GROUP.s new file mode 100644 index 00000000..9a83d03a --- /dev/null +++ b/libc/sysv/consts/MCAST_LEAVE_SOURCE_GROUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MCAST_LEAVE_SOURCE_GROUP 47 83 83 0 46 diff --git a/libc/sysv/consts/MCAST_MSFILTER.s b/libc/sysv/consts/MCAST_MSFILTER.s new file mode 100644 index 00000000..41ee5730 --- /dev/null +++ b/libc/sysv/consts/MCAST_MSFILTER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MCAST_MSFILTER 48 0 0 0 0 diff --git a/libc/sysv/consts/MCAST_UNBLOCK_SOURCE.s b/libc/sysv/consts/MCAST_UNBLOCK_SOURCE.s new file mode 100644 index 00000000..7827e232 --- /dev/null +++ b/libc/sysv/consts/MCAST_UNBLOCK_SOURCE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MCAST_UNBLOCK_SOURCE 44 85 85 0 44 diff --git a/libc/sysv/consts/MCL_CURRENT.s b/libc/sysv/consts/MCL_CURRENT.s new file mode 100644 index 00000000..2fe8b22d --- /dev/null +++ b/libc/sysv/consts/MCL_CURRENT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mlock MCL_CURRENT 1 1 1 1 0 diff --git a/libc/sysv/consts/MCL_FUTURE.s b/libc/sysv/consts/MCL_FUTURE.s new file mode 100644 index 00000000..0a63806d --- /dev/null +++ b/libc/sysv/consts/MCL_FUTURE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mlock MCL_FUTURE 2 2 2 2 0 diff --git a/libc/sysv/consts/MCL_ONFAULT.s b/libc/sysv/consts/MCL_ONFAULT.s new file mode 100644 index 00000000..8690ee9e --- /dev/null +++ b/libc/sysv/consts/MCL_ONFAULT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mlock MCL_ONFAULT 4 0 0 0 0 diff --git a/libc/sysv/consts/MEDIUM_ERROR.s b/libc/sysv/consts/MEDIUM_ERROR.s new file mode 100644 index 00000000..3339592b --- /dev/null +++ b/libc/sysv/consts/MEDIUM_ERROR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MEDIUM_ERROR 3 0 0 0 0 diff --git a/libc/sysv/consts/MEDIUM_SCAN.s b/libc/sysv/consts/MEDIUM_SCAN.s new file mode 100644 index 00000000..73fa4eb0 --- /dev/null +++ b/libc/sysv/consts/MEDIUM_SCAN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MEDIUM_SCAN 56 0 0 0 0 diff --git a/libc/sysv/consts/MESSAGE_REJECT.s b/libc/sysv/consts/MESSAGE_REJECT.s new file mode 100644 index 00000000..6078c21a --- /dev/null +++ b/libc/sysv/consts/MESSAGE_REJECT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MESSAGE_REJECT 7 0 0 0 0 diff --git a/libc/sysv/consts/MFD_ALLOW_SEALING.s b/libc/sysv/consts/MFD_ALLOW_SEALING.s new file mode 100644 index 00000000..9e4635ea --- /dev/null +++ b/libc/sysv/consts/MFD_ALLOW_SEALING.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon memfd MFD_ALLOW_SEALING 2 0 0 0 0 diff --git a/libc/sysv/consts/MFD_CLOEXEC.s b/libc/sysv/consts/MFD_CLOEXEC.s new file mode 100644 index 00000000..184ba683 --- /dev/null +++ b/libc/sysv/consts/MFD_CLOEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon memfd MFD_CLOEXEC 1 0 0 0 0 diff --git a/libc/sysv/consts/MINSIGSTKSZ.s b/libc/sysv/consts/MINSIGSTKSZ.s new file mode 100644 index 00000000..d5e78244 --- /dev/null +++ b/libc/sysv/consts/MINSIGSTKSZ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MINSIGSTKSZ 0x0800 0x8000 0x0800 0x3000 0 diff --git a/libc/sysv/consts/MISCOMPARE.s b/libc/sysv/consts/MISCOMPARE.s new file mode 100644 index 00000000..3fa7de3a --- /dev/null +++ b/libc/sysv/consts/MISCOMPARE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MISCOMPARE 14 0 0 0 0 diff --git a/libc/sysv/consts/MLD_LISTENER_QUERY.s b/libc/sysv/consts/MLD_LISTENER_QUERY.s new file mode 100644 index 00000000..e8b84c4d --- /dev/null +++ b/libc/sysv/consts/MLD_LISTENER_QUERY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MLD_LISTENER_QUERY 130 130 130 130 0 diff --git a/libc/sysv/consts/MLD_LISTENER_REDUCTION.s b/libc/sysv/consts/MLD_LISTENER_REDUCTION.s new file mode 100644 index 00000000..0a74730b --- /dev/null +++ b/libc/sysv/consts/MLD_LISTENER_REDUCTION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MLD_LISTENER_REDUCTION 132 132 132 0 0 diff --git a/libc/sysv/consts/MLD_LISTENER_REPORT.s b/libc/sysv/consts/MLD_LISTENER_REPORT.s new file mode 100644 index 00000000..6b9298bb --- /dev/null +++ b/libc/sysv/consts/MLD_LISTENER_REPORT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MLD_LISTENER_REPORT 131 131 131 131 0 diff --git a/libc/sysv/consts/MMAP_PAGE_ZERO.s b/libc/sysv/consts/MMAP_PAGE_ZERO.s new file mode 100644 index 00000000..7f63d154 --- /dev/null +++ b/libc/sysv/consts/MMAP_PAGE_ZERO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon prsnlty MMAP_PAGE_ZERO 0x0100000 -1 -1 -1 -1 diff --git a/libc/sysv/consts/MNT_DETACH.s b/libc/sysv/consts/MNT_DETACH.s new file mode 100644 index 00000000..b4eb5e76 --- /dev/null +++ b/libc/sysv/consts/MNT_DETACH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MNT_DETACH 2 0 0 0 0 diff --git a/libc/sysv/consts/MNT_EXPIRE.s b/libc/sysv/consts/MNT_EXPIRE.s new file mode 100644 index 00000000..7cb098f8 --- /dev/null +++ b/libc/sysv/consts/MNT_EXPIRE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MNT_EXPIRE 4 0 0 0 0 diff --git a/libc/sysv/consts/MNT_FORCE.s b/libc/sysv/consts/MNT_FORCE.s new file mode 100644 index 00000000..8d32675b --- /dev/null +++ b/libc/sysv/consts/MNT_FORCE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MNT_FORCE 1 0x080000 0 0x080000 0 diff --git a/libc/sysv/consts/MODE_B.s b/libc/sysv/consts/MODE_B.s new file mode 100644 index 00000000..5a3fdbc7 --- /dev/null +++ b/libc/sysv/consts/MODE_B.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MODE_B 2 2 2 2 0 diff --git a/libc/sysv/consts/MODE_C.s b/libc/sysv/consts/MODE_C.s new file mode 100644 index 00000000..20480dae --- /dev/null +++ b/libc/sysv/consts/MODE_C.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MODE_C 3 3 3 3 0 diff --git a/libc/sysv/consts/MODE_S.s b/libc/sysv/consts/MODE_S.s new file mode 100644 index 00000000..604d01eb --- /dev/null +++ b/libc/sysv/consts/MODE_S.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MODE_S 1 1 1 1 0 diff --git a/libc/sysv/consts/MODE_SELECT.s b/libc/sysv/consts/MODE_SELECT.s new file mode 100644 index 00000000..5770927e --- /dev/null +++ b/libc/sysv/consts/MODE_SELECT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MODE_SELECT 21 0 0 0 0 diff --git a/libc/sysv/consts/MODE_SELECT_10.s b/libc/sysv/consts/MODE_SELECT_10.s new file mode 100644 index 00000000..e4f7f03a --- /dev/null +++ b/libc/sysv/consts/MODE_SELECT_10.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MODE_SELECT_10 85 0 0 0 0 diff --git a/libc/sysv/consts/MODE_SENSE.s b/libc/sysv/consts/MODE_SENSE.s new file mode 100644 index 00000000..38d11b8e --- /dev/null +++ b/libc/sysv/consts/MODE_SENSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MODE_SENSE 26 0 0 0 0 diff --git a/libc/sysv/consts/MODE_SENSE_10.s b/libc/sysv/consts/MODE_SENSE_10.s new file mode 100644 index 00000000..362229d1 --- /dev/null +++ b/libc/sysv/consts/MODE_SENSE_10.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MODE_SENSE_10 90 0 0 0 0 diff --git a/libc/sysv/consts/MOVE_MEDIUM.s b/libc/sysv/consts/MOVE_MEDIUM.s new file mode 100644 index 00000000..765156a6 --- /dev/null +++ b/libc/sysv/consts/MOVE_MEDIUM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MOVE_MEDIUM 165 0 0 0 0 diff --git a/libc/sysv/consts/MQ_PRIO_MAX.s b/libc/sysv/consts/MQ_PRIO_MAX.s new file mode 100644 index 00000000..0382a359 --- /dev/null +++ b/libc/sysv/consts/MQ_PRIO_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MQ_PRIO_MAX 0x8000 0 0x40 0 0 diff --git a/libc/sysv/consts/MREMAP_FIXED.s b/libc/sysv/consts/MREMAP_FIXED.s new file mode 100644 index 00000000..be085add --- /dev/null +++ b/libc/sysv/consts/MREMAP_FIXED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mremap MREMAP_FIXED 2 2 2 2 2 diff --git a/libc/sysv/consts/MREMAP_MAYMOVE.s b/libc/sysv/consts/MREMAP_MAYMOVE.s new file mode 100644 index 00000000..434bba8c --- /dev/null +++ b/libc/sysv/consts/MREMAP_MAYMOVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mremap MREMAP_MAYMOVE 1 1 1 1 1 diff --git a/libc/sysv/consts/MSG_BATCH.s b/libc/sysv/consts/MSG_BATCH.s new file mode 100644 index 00000000..86496c42 --- /dev/null +++ b/libc/sysv/consts/MSG_BATCH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_BATCH 0x040000 0 0 0 0 diff --git a/libc/sysv/consts/MSG_CMSG_CLOEXEC.s b/libc/sysv/consts/MSG_CMSG_CLOEXEC.s new file mode 100644 index 00000000..006d3216 --- /dev/null +++ b/libc/sysv/consts/MSG_CMSG_CLOEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_CMSG_CLOEXEC 0x40000000 0 0x040000 0x0800 0 diff --git a/libc/sysv/consts/MSG_CONFIRM.s b/libc/sysv/consts/MSG_CONFIRM.s new file mode 100644 index 00000000..9ddf1ed6 --- /dev/null +++ b/libc/sysv/consts/MSG_CONFIRM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_CONFIRM 0x0800 0 0 0 0 diff --git a/libc/sysv/consts/MSG_CTRUNC.s b/libc/sysv/consts/MSG_CTRUNC.s new file mode 100644 index 00000000..4fc9cd6d --- /dev/null +++ b/libc/sysv/consts/MSG_CTRUNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_CTRUNC 8 0x20 0x20 0x20 0x0200 diff --git a/libc/sysv/consts/MSG_DONTROUTE.s b/libc/sysv/consts/MSG_DONTROUTE.s new file mode 100644 index 00000000..9fed0a65 --- /dev/null +++ b/libc/sysv/consts/MSG_DONTROUTE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_DONTROUTE 4 4 4 4 4 diff --git a/libc/sysv/consts/MSG_DONTWAIT.s b/libc/sysv/consts/MSG_DONTWAIT.s new file mode 100644 index 00000000..402cac9d --- /dev/null +++ b/libc/sysv/consts/MSG_DONTWAIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_DONTWAIT 0x40 0x80 0x80 0x80 0 diff --git a/libc/sysv/consts/MSG_EOR.s b/libc/sysv/consts/MSG_EOR.s new file mode 100644 index 00000000..bfbca95b --- /dev/null +++ b/libc/sysv/consts/MSG_EOR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_EOR 0x80 8 8 8 0 diff --git a/libc/sysv/consts/MSG_ERRQUEUE.s b/libc/sysv/consts/MSG_ERRQUEUE.s new file mode 100644 index 00000000..b7086dae --- /dev/null +++ b/libc/sysv/consts/MSG_ERRQUEUE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_ERRQUEUE 0x2000 0 0 0 0x1000 diff --git a/libc/sysv/consts/MSG_EXCEPT.s b/libc/sysv/consts/MSG_EXCEPT.s new file mode 100644 index 00000000..5095a73f --- /dev/null +++ b/libc/sysv/consts/MSG_EXCEPT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_EXCEPT 0x2000 0 0 0 0 diff --git a/libc/sysv/consts/MSG_FASTOPEN.s b/libc/sysv/consts/MSG_FASTOPEN.s new file mode 100644 index 00000000..dc053bd3 --- /dev/null +++ b/libc/sysv/consts/MSG_FASTOPEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_FASTOPEN 0x20000000 0 0 0 0 diff --git a/libc/sysv/consts/MSG_FIN.s b/libc/sysv/consts/MSG_FIN.s new file mode 100644 index 00000000..e56149d0 --- /dev/null +++ b/libc/sysv/consts/MSG_FIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_FIN 0x0200 0 0 0 0 diff --git a/libc/sysv/consts/MSG_INFO.s b/libc/sysv/consts/MSG_INFO.s new file mode 100644 index 00000000..7fe99bee --- /dev/null +++ b/libc/sysv/consts/MSG_INFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_INFO 12 0 0 0 0 diff --git a/libc/sysv/consts/MSG_MORE.s b/libc/sysv/consts/MSG_MORE.s new file mode 100644 index 00000000..8913d31c --- /dev/null +++ b/libc/sysv/consts/MSG_MORE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_MORE 0x8000 0 0 0 0 diff --git a/libc/sysv/consts/MSG_NOERROR.s b/libc/sysv/consts/MSG_NOERROR.s new file mode 100644 index 00000000..f28c1528 --- /dev/null +++ b/libc/sysv/consts/MSG_NOERROR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_NOERROR 0x1000 0x1000 0x1000 0x1000 0 diff --git a/libc/sysv/consts/MSG_NOSIGNAL.s b/libc/sysv/consts/MSG_NOSIGNAL.s new file mode 100644 index 00000000..c19a28f8 --- /dev/null +++ b/libc/sysv/consts/MSG_NOSIGNAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_NOSIGNAL 0x4000 0 0x020000 0x0400 0 diff --git a/libc/sysv/consts/MSG_OOB.s b/libc/sysv/consts/MSG_OOB.s new file mode 100644 index 00000000..dbc0289e --- /dev/null +++ b/libc/sysv/consts/MSG_OOB.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_OOB 1 1 1 1 1 diff --git a/libc/sysv/consts/MSG_PARITY_ERROR.s b/libc/sysv/consts/MSG_PARITY_ERROR.s new file mode 100644 index 00000000..a57a0627 --- /dev/null +++ b/libc/sysv/consts/MSG_PARITY_ERROR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_PARITY_ERROR 9 0 0 0 0 diff --git a/libc/sysv/consts/MSG_PEEK.s b/libc/sysv/consts/MSG_PEEK.s new file mode 100644 index 00000000..bfeb3e82 --- /dev/null +++ b/libc/sysv/consts/MSG_PEEK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_PEEK 2 2 2 2 2 diff --git a/libc/sysv/consts/MSG_PROXY.s b/libc/sysv/consts/MSG_PROXY.s new file mode 100644 index 00000000..bb1f550f --- /dev/null +++ b/libc/sysv/consts/MSG_PROXY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_PROXY 0x10 0 0 0 0 diff --git a/libc/sysv/consts/MSG_RST.s b/libc/sysv/consts/MSG_RST.s new file mode 100644 index 00000000..230b04e8 --- /dev/null +++ b/libc/sysv/consts/MSG_RST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_RST 0x1000 0 0 0 0 diff --git a/libc/sysv/consts/MSG_STAT.s b/libc/sysv/consts/MSG_STAT.s new file mode 100644 index 00000000..a3c856dd --- /dev/null +++ b/libc/sysv/consts/MSG_STAT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_STAT 11 0 0 0 0 diff --git a/libc/sysv/consts/MSG_SYN.s b/libc/sysv/consts/MSG_SYN.s new file mode 100644 index 00000000..46deead7 --- /dev/null +++ b/libc/sysv/consts/MSG_SYN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_SYN 0x0400 0 0 0 0 diff --git a/libc/sysv/consts/MSG_TRUNC.s b/libc/sysv/consts/MSG_TRUNC.s new file mode 100644 index 00000000..10783841 --- /dev/null +++ b/libc/sysv/consts/MSG_TRUNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_TRUNC 0x20 0x10 0x10 0x10 0x0100 diff --git a/libc/sysv/consts/MSG_WAITALL.s b/libc/sysv/consts/MSG_WAITALL.s new file mode 100644 index 00000000..0051cfc4 --- /dev/null +++ b/libc/sysv/consts/MSG_WAITALL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_WAITALL 0x0100 0x40 0x40 0x40 8 diff --git a/libc/sysv/consts/MSG_WAITFORONE.s b/libc/sysv/consts/MSG_WAITFORONE.s new file mode 100644 index 00000000..5094452a --- /dev/null +++ b/libc/sysv/consts/MSG_WAITFORONE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon msg MSG_WAITFORONE 0x010000 0 0x080000 0 0 diff --git a/libc/sysv/consts/MS_ACTIVE.s b/libc/sysv/consts/MS_ACTIVE.s new file mode 100644 index 00000000..91046f02 --- /dev/null +++ b/libc/sysv/consts/MS_ACTIVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_ACTIVE 0x40000000 0 0 0 0 diff --git a/libc/sysv/consts/MS_ASYNC.s b/libc/sysv/consts/MS_ASYNC.s new file mode 100644 index 00000000..40a839a1 --- /dev/null +++ b/libc/sysv/consts/MS_ASYNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ms MS_ASYNC 1 1 1 1 1 diff --git a/libc/sysv/consts/MS_BIND.s b/libc/sysv/consts/MS_BIND.s new file mode 100644 index 00000000..8620f303 --- /dev/null +++ b/libc/sysv/consts/MS_BIND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_BIND 0x1000 0 0 0 0 diff --git a/libc/sysv/consts/MS_DIRSYNC.s b/libc/sysv/consts/MS_DIRSYNC.s new file mode 100644 index 00000000..1130e67a --- /dev/null +++ b/libc/sysv/consts/MS_DIRSYNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_DIRSYNC 0x80 0 0 0 0 diff --git a/libc/sysv/consts/MS_INVALIDATE.s b/libc/sysv/consts/MS_INVALIDATE.s new file mode 100644 index 00000000..79d8529b --- /dev/null +++ b/libc/sysv/consts/MS_INVALIDATE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ms MS_INVALIDATE 2 2 2 4 0 diff --git a/libc/sysv/consts/MS_I_VERSION.s b/libc/sysv/consts/MS_I_VERSION.s new file mode 100644 index 00000000..05d7ec2c --- /dev/null +++ b/libc/sysv/consts/MS_I_VERSION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_I_VERSION 0x800000 0 0 0 0 diff --git a/libc/sysv/consts/MS_KERNMOUNT.s b/libc/sysv/consts/MS_KERNMOUNT.s new file mode 100644 index 00000000..e6a65fe9 --- /dev/null +++ b/libc/sysv/consts/MS_KERNMOUNT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_KERNMOUNT 0x400000 0 0 0 0 diff --git a/libc/sysv/consts/MS_LAZYTIME.s b/libc/sysv/consts/MS_LAZYTIME.s new file mode 100644 index 00000000..dcf97450 --- /dev/null +++ b/libc/sysv/consts/MS_LAZYTIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_LAZYTIME 0x02000000 0 0 0 0 diff --git a/libc/sysv/consts/MS_MANDLOCK.s b/libc/sysv/consts/MS_MANDLOCK.s new file mode 100644 index 00000000..096673a0 --- /dev/null +++ b/libc/sysv/consts/MS_MANDLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_MANDLOCK 0x40 0 0 0 0 diff --git a/libc/sysv/consts/MS_MGC_MSK.s b/libc/sysv/consts/MS_MGC_MSK.s new file mode 100644 index 00000000..3c465e5d --- /dev/null +++ b/libc/sysv/consts/MS_MGC_MSK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_MGC_MSK 0xffff0000 0 0 0 0 diff --git a/libc/sysv/consts/MS_MGC_VAL.s b/libc/sysv/consts/MS_MGC_VAL.s new file mode 100644 index 00000000..b029839f --- /dev/null +++ b/libc/sysv/consts/MS_MGC_VAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_MGC_VAL 0xc0ed0000 0 0 0 0 diff --git a/libc/sysv/consts/MS_MOVE.s b/libc/sysv/consts/MS_MOVE.s new file mode 100644 index 00000000..1fdf7d06 --- /dev/null +++ b/libc/sysv/consts/MS_MOVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_MOVE 0x2000 0 0 0 0 diff --git a/libc/sysv/consts/MS_NOATIME.s b/libc/sysv/consts/MS_NOATIME.s new file mode 100644 index 00000000..c795dbe2 --- /dev/null +++ b/libc/sysv/consts/MS_NOATIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_NOATIME 0x0400 0 0 0 0 diff --git a/libc/sysv/consts/MS_NODEV.s b/libc/sysv/consts/MS_NODEV.s new file mode 100644 index 00000000..e43823d5 --- /dev/null +++ b/libc/sysv/consts/MS_NODEV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_NODEV 4 0 0 0 0 diff --git a/libc/sysv/consts/MS_NODIRATIME.s b/libc/sysv/consts/MS_NODIRATIME.s new file mode 100644 index 00000000..878545a4 --- /dev/null +++ b/libc/sysv/consts/MS_NODIRATIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_NODIRATIME 0x0800 0 0 0 0 diff --git a/libc/sysv/consts/MS_NOEXEC.s b/libc/sysv/consts/MS_NOEXEC.s new file mode 100644 index 00000000..999b75c8 --- /dev/null +++ b/libc/sysv/consts/MS_NOEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_NOEXEC 8 0 0 0 0 diff --git a/libc/sysv/consts/MS_NOSUID.s b/libc/sysv/consts/MS_NOSUID.s new file mode 100644 index 00000000..565d1490 --- /dev/null +++ b/libc/sysv/consts/MS_NOSUID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_NOSUID 2 0 0 0 0 diff --git a/libc/sysv/consts/MS_NOUSER.s b/libc/sysv/consts/MS_NOUSER.s new file mode 100644 index 00000000..bee6ac28 --- /dev/null +++ b/libc/sysv/consts/MS_NOUSER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_NOUSER -2147483648 0 0 0 0 diff --git a/libc/sysv/consts/MS_POSIXACL.s b/libc/sysv/consts/MS_POSIXACL.s new file mode 100644 index 00000000..9f9e11ba --- /dev/null +++ b/libc/sysv/consts/MS_POSIXACL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_POSIXACL 0x010000 0 0 0 0 diff --git a/libc/sysv/consts/MS_PRIVATE.s b/libc/sysv/consts/MS_PRIVATE.s new file mode 100644 index 00000000..e9d5f376 --- /dev/null +++ b/libc/sysv/consts/MS_PRIVATE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_PRIVATE 0x040000 0 0 0 0 diff --git a/libc/sysv/consts/MS_RDONLY.s b/libc/sysv/consts/MS_RDONLY.s new file mode 100644 index 00000000..129b52e7 --- /dev/null +++ b/libc/sysv/consts/MS_RDONLY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_RDONLY 1 0 0 0 0 diff --git a/libc/sysv/consts/MS_REC.s b/libc/sysv/consts/MS_REC.s new file mode 100644 index 00000000..fb9e2cd1 --- /dev/null +++ b/libc/sysv/consts/MS_REC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_REC 0x4000 0 0 0 0 diff --git a/libc/sysv/consts/MS_RELATIME.s b/libc/sysv/consts/MS_RELATIME.s new file mode 100644 index 00000000..6f1d4557 --- /dev/null +++ b/libc/sysv/consts/MS_RELATIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_RELATIME 0x200000 0 0 0 0 diff --git a/libc/sysv/consts/MS_REMOUNT.s b/libc/sysv/consts/MS_REMOUNT.s new file mode 100644 index 00000000..4457bc8b --- /dev/null +++ b/libc/sysv/consts/MS_REMOUNT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_REMOUNT 0x20 0 0 0 0 diff --git a/libc/sysv/consts/MS_RMT_MASK.s b/libc/sysv/consts/MS_RMT_MASK.s new file mode 100644 index 00000000..6045d0c9 --- /dev/null +++ b/libc/sysv/consts/MS_RMT_MASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_RMT_MASK 0x02800051 0 0 0 0 diff --git a/libc/sysv/consts/MS_SHARED.s b/libc/sysv/consts/MS_SHARED.s new file mode 100644 index 00000000..8f756e5a --- /dev/null +++ b/libc/sysv/consts/MS_SHARED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_SHARED 0x100000 0 0 0 0 diff --git a/libc/sysv/consts/MS_SILENT.s b/libc/sysv/consts/MS_SILENT.s new file mode 100644 index 00000000..b91dd347 --- /dev/null +++ b/libc/sysv/consts/MS_SILENT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_SILENT 0x8000 0 0 0 0 diff --git a/libc/sysv/consts/MS_SLAVE.s b/libc/sysv/consts/MS_SLAVE.s new file mode 100644 index 00000000..d948c291 --- /dev/null +++ b/libc/sysv/consts/MS_SLAVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_SLAVE 0x080000 0 0 0 0 diff --git a/libc/sysv/consts/MS_STRICTATIME.s b/libc/sysv/consts/MS_STRICTATIME.s new file mode 100644 index 00000000..3307fc27 --- /dev/null +++ b/libc/sysv/consts/MS_STRICTATIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_STRICTATIME 0x01000000 0 0 0 0 diff --git a/libc/sysv/consts/MS_SYNC.s b/libc/sysv/consts/MS_SYNC.s new file mode 100644 index 00000000..90d5d6db --- /dev/null +++ b/libc/sysv/consts/MS_SYNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ms MS_SYNC 4 16 0 2 4 diff --git a/libc/sysv/consts/MS_SYNCHRONOUS.s b/libc/sysv/consts/MS_SYNCHRONOUS.s new file mode 100644 index 00000000..f653c16d --- /dev/null +++ b/libc/sysv/consts/MS_SYNCHRONOUS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_SYNCHRONOUS 0x10 0 0 0 0 diff --git a/libc/sysv/consts/MS_UNBINDABLE.s b/libc/sysv/consts/MS_UNBINDABLE.s new file mode 100644 index 00000000..ecc655a9 --- /dev/null +++ b/libc/sysv/consts/MS_UNBINDABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mount MS_UNBINDABLE 0x020000 0 0 0 0 diff --git a/libc/sysv/consts/MTCOMPRESSION.s b/libc/sysv/consts/MTCOMPRESSION.s new file mode 100644 index 00000000..8851e19a --- /dev/null +++ b/libc/sysv/consts/MTCOMPRESSION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MTCOMPRESSION 0x20 0 0 0 0 diff --git a/libc/sysv/consts/MTERASE.s b/libc/sysv/consts/MTERASE.s new file mode 100644 index 00000000..f3b06bb1 --- /dev/null +++ b/libc/sysv/consts/MTERASE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MTERASE 13 0 12 9 0 diff --git a/libc/sysv/consts/MTFSFM.s b/libc/sysv/consts/MTFSFM.s new file mode 100644 index 00000000..b4c0eea7 --- /dev/null +++ b/libc/sysv/consts/MTFSFM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MTFSFM 11 0 0 0 0 diff --git a/libc/sysv/consts/MTLOAD.s b/libc/sysv/consts/MTLOAD.s new file mode 100644 index 00000000..1e76f211 --- /dev/null +++ b/libc/sysv/consts/MTLOAD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MTLOAD 30 0 19 0 0 diff --git a/libc/sysv/consts/MTLOCK.s b/libc/sysv/consts/MTLOCK.s new file mode 100644 index 00000000..d33fea9a --- /dev/null +++ b/libc/sysv/consts/MTLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MTLOCK 28 0 0 0 0 diff --git a/libc/sysv/consts/MTMKPART.s b/libc/sysv/consts/MTMKPART.s new file mode 100644 index 00000000..6e86ad22 --- /dev/null +++ b/libc/sysv/consts/MTMKPART.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MTMKPART 34 0 0 0 0 diff --git a/libc/sysv/consts/MTRAS1.s b/libc/sysv/consts/MTRAS1.s new file mode 100644 index 00000000..285128e3 --- /dev/null +++ b/libc/sysv/consts/MTRAS1.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MTRAS1 14 0 0 0 0 diff --git a/libc/sysv/consts/MTRAS3.s b/libc/sysv/consts/MTRAS3.s new file mode 100644 index 00000000..423c66c6 --- /dev/null +++ b/libc/sysv/consts/MTRAS3.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MTRAS3 0x10 0 0 0 0 diff --git a/libc/sysv/consts/MTRESET.s b/libc/sysv/consts/MTRESET.s new file mode 100644 index 00000000..e371485a --- /dev/null +++ b/libc/sysv/consts/MTRESET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MTRESET 0 0 0 0 0 diff --git a/libc/sysv/consts/MTRETEN.s b/libc/sysv/consts/MTRETEN.s new file mode 100644 index 00000000..4475d6ec --- /dev/null +++ b/libc/sysv/consts/MTRETEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MTRETEN 9 0 0 8 0 diff --git a/libc/sysv/consts/MTSETBLK.s b/libc/sysv/consts/MTSETBLK.s new file mode 100644 index 00000000..4dee8a01 --- /dev/null +++ b/libc/sysv/consts/MTSETBLK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MTSETBLK 20 0 0 0 0 diff --git a/libc/sysv/consts/MTSETDENSITY.s b/libc/sysv/consts/MTSETDENSITY.s new file mode 100644 index 00000000..699b6f46 --- /dev/null +++ b/libc/sysv/consts/MTSETDENSITY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MTSETDENSITY 21 0 0 0 0 diff --git a/libc/sysv/consts/MTSETDRVBUFFER.s b/libc/sysv/consts/MTSETDRVBUFFER.s new file mode 100644 index 00000000..12799e28 --- /dev/null +++ b/libc/sysv/consts/MTSETDRVBUFFER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MTSETDRVBUFFER 24 0 0 0 0 diff --git a/libc/sysv/consts/MTSETPART.s b/libc/sysv/consts/MTSETPART.s new file mode 100644 index 00000000..acccc0fb --- /dev/null +++ b/libc/sysv/consts/MTSETPART.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MTSETPART 33 0 0 0 0 diff --git a/libc/sysv/consts/MTUNLOAD.s b/libc/sysv/consts/MTUNLOAD.s new file mode 100644 index 00000000..432770b5 --- /dev/null +++ b/libc/sysv/consts/MTUNLOAD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MTUNLOAD 31 0 0 0 0 diff --git a/libc/sysv/consts/MTUNLOCK.s b/libc/sysv/consts/MTUNLOCK.s new file mode 100644 index 00000000..7c5748c1 --- /dev/null +++ b/libc/sysv/consts/MTUNLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MTUNLOCK 29 0 0 0 0 diff --git a/libc/sysv/consts/MT_ST_CAN_PARTITIONS.s b/libc/sysv/consts/MT_ST_CAN_PARTITIONS.s new file mode 100644 index 00000000..4c8acfa3 --- /dev/null +++ b/libc/sysv/consts/MT_ST_CAN_PARTITIONS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MT_ST_CAN_PARTITIONS 0x0400 0 0 0 0 diff --git a/libc/sysv/consts/MT_ST_HPLOADER_OFFSET.s b/libc/sysv/consts/MT_ST_HPLOADER_OFFSET.s new file mode 100644 index 00000000..23732ec7 --- /dev/null +++ b/libc/sysv/consts/MT_ST_HPLOADER_OFFSET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MT_ST_HPLOADER_OFFSET 0x2710 0 0 0 0 diff --git a/libc/sysv/consts/MT_ST_SCSI2LOGICAL.s b/libc/sysv/consts/MT_ST_SCSI2LOGICAL.s new file mode 100644 index 00000000..a63a82aa --- /dev/null +++ b/libc/sysv/consts/MT_ST_SCSI2LOGICAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc MT_ST_SCSI2LOGICAL 0x0800 0 0 0 0 diff --git a/libc/sysv/consts/NBBY.s b/libc/sysv/consts/NBBY.s new file mode 100644 index 00000000..b9d2d802 --- /dev/null +++ b/libc/sysv/consts/NBBY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NBBY 8 8 8 8 0 diff --git a/libc/sysv/consts/NCARGS.s b/libc/sysv/consts/NCARGS.s new file mode 100644 index 00000000..f597706c --- /dev/null +++ b/libc/sysv/consts/NCARGS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NCARGS 0x020000 0x040000 0x040000 0x040000 0 diff --git a/libc/sysv/consts/NCCS.s b/libc/sysv/consts/NCCS.s new file mode 100644 index 00000000..c09b7ede --- /dev/null +++ b/libc/sysv/consts/NCCS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios NCCS 32 32 32 32 32 diff --git a/libc/sysv/consts/ND_NA_FLAG_OVERRIDE.s b/libc/sysv/consts/ND_NA_FLAG_OVERRIDE.s new file mode 100644 index 00000000..42837e0d --- /dev/null +++ b/libc/sysv/consts/ND_NA_FLAG_OVERRIDE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nd ND_NA_FLAG_OVERRIDE 0x20 0x20 0x20 0x20 0x20000000 diff --git a/libc/sysv/consts/ND_NA_FLAG_ROUTER.s b/libc/sysv/consts/ND_NA_FLAG_ROUTER.s new file mode 100644 index 00000000..9fc2b3d2 --- /dev/null +++ b/libc/sysv/consts/ND_NA_FLAG_ROUTER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nd ND_NA_FLAG_ROUTER 0x80 0x80 0x80 0x80 0x80000000 diff --git a/libc/sysv/consts/ND_NA_FLAG_SOLICITED.s b/libc/sysv/consts/ND_NA_FLAG_SOLICITED.s new file mode 100644 index 00000000..9fafa66f --- /dev/null +++ b/libc/sysv/consts/ND_NA_FLAG_SOLICITED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nd ND_NA_FLAG_SOLICITED 0x40 0x40 0x40 0x40 0x40000000 diff --git a/libc/sysv/consts/ND_NEIGHBOR_ADVERT.s b/libc/sysv/consts/ND_NEIGHBOR_ADVERT.s new file mode 100644 index 00000000..5868710f --- /dev/null +++ b/libc/sysv/consts/ND_NEIGHBOR_ADVERT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nd ND_NEIGHBOR_ADVERT 136 136 136 136 0 diff --git a/libc/sysv/consts/ND_NEIGHBOR_SOLICIT.s b/libc/sysv/consts/ND_NEIGHBOR_SOLICIT.s new file mode 100644 index 00000000..61697ca5 --- /dev/null +++ b/libc/sysv/consts/ND_NEIGHBOR_SOLICIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nd ND_NEIGHBOR_SOLICIT 135 135 135 135 0 diff --git a/libc/sysv/consts/ND_RA_FLAG_HOME_AGENT.s b/libc/sysv/consts/ND_RA_FLAG_HOME_AGENT.s new file mode 100644 index 00000000..fc72b9e3 --- /dev/null +++ b/libc/sysv/consts/ND_RA_FLAG_HOME_AGENT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nd ND_RA_FLAG_HOME_AGENT 0x20 0 0 0 0x20 diff --git a/libc/sysv/consts/ND_RA_FLAG_MANAGED.s b/libc/sysv/consts/ND_RA_FLAG_MANAGED.s new file mode 100644 index 00000000..1b502333 --- /dev/null +++ b/libc/sysv/consts/ND_RA_FLAG_MANAGED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nd ND_RA_FLAG_MANAGED 0x80 0x80 0x80 0x80 0x80 diff --git a/libc/sysv/consts/ND_RA_FLAG_OTHER.s b/libc/sysv/consts/ND_RA_FLAG_OTHER.s new file mode 100644 index 00000000..1c7bdb66 --- /dev/null +++ b/libc/sysv/consts/ND_RA_FLAG_OTHER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nd ND_RA_FLAG_OTHER 0x40 0x40 0x40 0x40 0x40 diff --git a/libc/sysv/consts/ND_REDIRECT.s b/libc/sysv/consts/ND_REDIRECT.s new file mode 100644 index 00000000..8c0fd82a --- /dev/null +++ b/libc/sysv/consts/ND_REDIRECT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nd ND_REDIRECT 137 137 137 137 0 diff --git a/libc/sysv/consts/ND_ROUTER_ADVERT.s b/libc/sysv/consts/ND_ROUTER_ADVERT.s new file mode 100644 index 00000000..8cb77903 --- /dev/null +++ b/libc/sysv/consts/ND_ROUTER_ADVERT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nd ND_ROUTER_ADVERT 134 134 134 134 0 diff --git a/libc/sysv/consts/ND_ROUTER_SOLICIT.s b/libc/sysv/consts/ND_ROUTER_SOLICIT.s new file mode 100644 index 00000000..78e96a54 --- /dev/null +++ b/libc/sysv/consts/ND_ROUTER_SOLICIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nd ND_ROUTER_SOLICIT 133 133 133 133 0 diff --git a/libc/sysv/consts/NETGRAPHDISC.s b/libc/sysv/consts/NETGRAPHDISC.s new file mode 100644 index 00000000..035486b2 --- /dev/null +++ b/libc/sysv/consts/NETGRAPHDISC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios NETGRAPHDISC 0 0 0x6 0 -1 diff --git a/libc/sysv/consts/NEW_TIME.s b/libc/sysv/consts/NEW_TIME.s new file mode 100644 index 00000000..9e4ca718 --- /dev/null +++ b/libc/sysv/consts/NEW_TIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NEW_TIME 3 4 3 0 0 diff --git a/libc/sysv/consts/NFDBITS.s b/libc/sysv/consts/NFDBITS.s new file mode 100644 index 00000000..3745c67e --- /dev/null +++ b/libc/sysv/consts/NFDBITS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NFDBITS 0x40 0x20 0x40 0x20 0 diff --git a/libc/sysv/consts/NGREG.s b/libc/sysv/consts/NGREG.s new file mode 100644 index 00000000..8dd9b8ed --- /dev/null +++ b/libc/sysv/consts/NGREG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NGREG 23 0 0 0 0 diff --git a/libc/sysv/consts/NGROUPS.s b/libc/sysv/consts/NGROUPS.s new file mode 100644 index 00000000..062481a3 --- /dev/null +++ b/libc/sysv/consts/NGROUPS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NGROUPS 0x010000 0x10 0x0400 0x10 0 diff --git a/libc/sysv/consts/NGROUPS_MAX.s b/libc/sysv/consts/NGROUPS_MAX.s new file mode 100644 index 00000000..e153de27 --- /dev/null +++ b/libc/sysv/consts/NGROUPS_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NGROUPS_MAX 0x010000 0x10 0x03ff 0x10 0 diff --git a/libc/sysv/consts/NI_DGRAM.s b/libc/sysv/consts/NI_DGRAM.s new file mode 100644 index 00000000..249806ba --- /dev/null +++ b/libc/sysv/consts/NI_DGRAM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NI_DGRAM 0x10 0x10 0x10 0x10 0x10 diff --git a/libc/sysv/consts/NI_MAXHOST.s b/libc/sysv/consts/NI_MAXHOST.s new file mode 100644 index 00000000..cf0b12ed --- /dev/null +++ b/libc/sysv/consts/NI_MAXHOST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NI_MAXHOST 0x0401 0x0401 0x0401 0x0100 0x0401 diff --git a/libc/sysv/consts/NI_MAXSERV.s b/libc/sysv/consts/NI_MAXSERV.s new file mode 100644 index 00000000..15502b5e --- /dev/null +++ b/libc/sysv/consts/NI_MAXSERV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NI_MAXSERV 0x20 0x20 0x20 0x20 0x20 diff --git a/libc/sysv/consts/NI_NAMEREQD.s b/libc/sysv/consts/NI_NAMEREQD.s new file mode 100644 index 00000000..beaf6f40 --- /dev/null +++ b/libc/sysv/consts/NI_NAMEREQD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NI_NAMEREQD 8 4 4 8 4 diff --git a/libc/sysv/consts/NI_NOFQDN.s b/libc/sysv/consts/NI_NOFQDN.s new file mode 100644 index 00000000..eb6ce004 --- /dev/null +++ b/libc/sysv/consts/NI_NOFQDN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NI_NOFQDN 4 1 1 4 1 diff --git a/libc/sysv/consts/NI_NUMERICHOST.s b/libc/sysv/consts/NI_NUMERICHOST.s new file mode 100644 index 00000000..d3e78b94 --- /dev/null +++ b/libc/sysv/consts/NI_NUMERICHOST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NI_NUMERICHOST 1 2 2 1 2 diff --git a/libc/sysv/consts/NI_NUMERICSCOPE.s b/libc/sysv/consts/NI_NUMERICSCOPE.s new file mode 100644 index 00000000..8c4cc493 --- /dev/null +++ b/libc/sysv/consts/NI_NUMERICSCOPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NI_NUMERICSCOPE 0 0 0x20 0 0 diff --git a/libc/sysv/consts/NI_NUMERICSERV.s b/libc/sysv/consts/NI_NUMERICSERV.s new file mode 100644 index 00000000..01830a59 --- /dev/null +++ b/libc/sysv/consts/NI_NUMERICSERV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NI_NUMERICSERV 2 8 8 2 8 diff --git a/libc/sysv/consts/NL0.s b/libc/sysv/consts/NL0.s new file mode 100644 index 00000000..00ead766 --- /dev/null +++ b/libc/sysv/consts/NL0.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios NL0 0b0000000000000000 0b000000000000000000 0b000000000000000000 0 0b0000000000000000 diff --git a/libc/sysv/consts/NL1.s b/libc/sysv/consts/NL1.s new file mode 100644 index 00000000..71a5c296 --- /dev/null +++ b/libc/sysv/consts/NL1.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios NL1 0b0000000100000000 0b000000000100000000 0b000000000100000000 0 0b0000000100000000 diff --git a/libc/sysv/consts/NL2.s b/libc/sysv/consts/NL2.s new file mode 100644 index 00000000..e45cdaaa --- /dev/null +++ b/libc/sysv/consts/NL2.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios NL2 0 0b000000001000000000 0b000000001000000000 0 0 diff --git a/libc/sysv/consts/NL3.s b/libc/sysv/consts/NL3.s new file mode 100644 index 00000000..9d4a07cd --- /dev/null +++ b/libc/sysv/consts/NL3.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios NL3 0 0b000000001100000000 0b000000001100000000 0 0 diff --git a/libc/sysv/consts/NLDLY.s b/libc/sysv/consts/NLDLY.s new file mode 100644 index 00000000..be274617 --- /dev/null +++ b/libc/sysv/consts/NLDLY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios NLDLY 0b0000000100000000 0b000000001100000000 0b000000001100000000 0 0b0000000100000000 diff --git a/libc/sysv/consts/NL_ARGMAX.s b/libc/sysv/consts/NL_ARGMAX.s new file mode 100644 index 00000000..76648ea2 --- /dev/null +++ b/libc/sysv/consts/NL_ARGMAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NL_ARGMAX 0x1000 9 0x1000 9 0 diff --git a/libc/sysv/consts/NL_CAT_LOCALE.s b/libc/sysv/consts/NL_CAT_LOCALE.s new file mode 100644 index 00000000..25759415 --- /dev/null +++ b/libc/sysv/consts/NL_CAT_LOCALE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NL_CAT_LOCALE 1 1 1 1 0 diff --git a/libc/sysv/consts/NL_LANGMAX.s b/libc/sysv/consts/NL_LANGMAX.s new file mode 100644 index 00000000..d84bb146 --- /dev/null +++ b/libc/sysv/consts/NL_LANGMAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NL_LANGMAX 0x0800 14 31 14 0 diff --git a/libc/sysv/consts/NL_MSGMAX.s b/libc/sysv/consts/NL_MSGMAX.s new file mode 100644 index 00000000..7c1eecfb --- /dev/null +++ b/libc/sysv/consts/NL_MSGMAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NL_MSGMAX 0x7fffffff 0x7fff 0x7fff 0x7fff 0 diff --git a/libc/sysv/consts/NL_NMAX.s b/libc/sysv/consts/NL_NMAX.s new file mode 100644 index 00000000..aa57278e --- /dev/null +++ b/libc/sysv/consts/NL_NMAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NL_NMAX 0x7fffffff 1 1 0 0 diff --git a/libc/sysv/consts/NL_SETD.s b/libc/sysv/consts/NL_SETD.s new file mode 100644 index 00000000..249d2136 --- /dev/null +++ b/libc/sysv/consts/NL_SETD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NL_SETD 1 1 0 1 0 diff --git a/libc/sysv/consts/NL_SETMAX.s b/libc/sysv/consts/NL_SETMAX.s new file mode 100644 index 00000000..f7c77b02 --- /dev/null +++ b/libc/sysv/consts/NL_SETMAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NL_SETMAX 0x7fffffff 255 255 255 0 diff --git a/libc/sysv/consts/NL_TEXTMAX.s b/libc/sysv/consts/NL_TEXTMAX.s new file mode 100644 index 00000000..0e78baf9 --- /dev/null +++ b/libc/sysv/consts/NL_TEXTMAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NL_TEXTMAX 0x7fffffff 0x0800 0x0800 255 0 diff --git a/libc/sysv/consts/NMEADISC.s b/libc/sysv/consts/NMEADISC.s new file mode 100644 index 00000000..d5a39582 --- /dev/null +++ b/libc/sysv/consts/NMEADISC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios NMEADISC 0 0 0 0x7 -1 diff --git a/libc/sysv/consts/NOEXPR.s b/libc/sysv/consts/NOEXPR.s new file mode 100644 index 00000000..d9f63c69 --- /dev/null +++ b/libc/sysv/consts/NOEXPR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NOEXPR 0x050001 53 53 49 0 diff --git a/libc/sysv/consts/NOFILE.s b/libc/sysv/consts/NOFILE.s new file mode 100644 index 00000000..0a6c1bc4 --- /dev/null +++ b/libc/sysv/consts/NOFILE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NOFILE 0x0100 0x0100 0x40 0x40 0 diff --git a/libc/sysv/consts/NOFLSH.s b/libc/sysv/consts/NOFLSH.s new file mode 100644 index 00000000..a472f853 --- /dev/null +++ b/libc/sysv/consts/NOFLSH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios NOFLSH 0b0000000010000000 2147483648 2147483648 2147483648 0b0000000010000000 diff --git a/libc/sysv/consts/NOGROUP.s b/libc/sysv/consts/NOGROUP.s new file mode 100644 index 00000000..b5576654 --- /dev/null +++ b/libc/sysv/consts/NOGROUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NOGROUP -1 0xffff 0xffff 0xffff 0 diff --git a/libc/sysv/consts/NOSTR.s b/libc/sysv/consts/NOSTR.s new file mode 100644 index 00000000..4e97a24e --- /dev/null +++ b/libc/sysv/consts/NOSTR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NOSTR 0x050003 55 55 48 0 diff --git a/libc/sysv/consts/NO_ADDRESS.s b/libc/sysv/consts/NO_ADDRESS.s new file mode 100644 index 00000000..d0b47d78 --- /dev/null +++ b/libc/sysv/consts/NO_ADDRESS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NO_ADDRESS 4 4 4 4 0x2afc diff --git a/libc/sysv/consts/NO_DATA.s b/libc/sysv/consts/NO_DATA.s new file mode 100644 index 00000000..d89530b2 --- /dev/null +++ b/libc/sysv/consts/NO_DATA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NO_DATA 4 4 4 4 0x2afc diff --git a/libc/sysv/consts/NO_RECOVERY.s b/libc/sysv/consts/NO_RECOVERY.s new file mode 100644 index 00000000..df4b4078 --- /dev/null +++ b/libc/sysv/consts/NO_RECOVERY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NO_RECOVERY 3 3 3 3 0x2afb diff --git a/libc/sysv/consts/NO_SENSE.s b/libc/sysv/consts/NO_SENSE.s new file mode 100644 index 00000000..cbce28e6 --- /dev/null +++ b/libc/sysv/consts/NO_SENSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NO_SENSE 0 0 0 0 0 diff --git a/libc/sysv/consts/NR_DQHASH.s b/libc/sysv/consts/NR_DQHASH.s new file mode 100644 index 00000000..405d60d1 --- /dev/null +++ b/libc/sysv/consts/NR_DQHASH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NR_DQHASH 43 0 0 0 0 diff --git a/libc/sysv/consts/NR_DQUOTS.s b/libc/sysv/consts/NR_DQUOTS.s new file mode 100644 index 00000000..33e8de66 --- /dev/null +++ b/libc/sysv/consts/NR_DQUOTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NR_DQUOTS 0x0100 0 0 0 0 diff --git a/libc/sysv/consts/NS_DSA_MAX_BYTES.s b/libc/sysv/consts/NS_DSA_MAX_BYTES.s new file mode 100644 index 00000000..9e4033d1 --- /dev/null +++ b/libc/sysv/consts/NS_DSA_MAX_BYTES.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NS_DSA_MAX_BYTES 405 405 405 0 0 diff --git a/libc/sysv/consts/NS_DSA_MIN_SIZE.s b/libc/sysv/consts/NS_DSA_MIN_SIZE.s new file mode 100644 index 00000000..791c8603 --- /dev/null +++ b/libc/sysv/consts/NS_DSA_MIN_SIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NS_DSA_MIN_SIZE 213 213 213 0 0 diff --git a/libc/sysv/consts/NS_DSA_SIG_SIZE.s b/libc/sysv/consts/NS_DSA_SIG_SIZE.s new file mode 100644 index 00000000..060e73b7 --- /dev/null +++ b/libc/sysv/consts/NS_DSA_SIG_SIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NS_DSA_SIG_SIZE 41 41 41 0 0 diff --git a/libc/sysv/consts/NS_KEY_PROT_DNSSEC.s b/libc/sysv/consts/NS_KEY_PROT_DNSSEC.s new file mode 100644 index 00000000..f9c42741 --- /dev/null +++ b/libc/sysv/consts/NS_KEY_PROT_DNSSEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NS_KEY_PROT_DNSSEC 3 3 3 0 0 diff --git a/libc/sysv/consts/NS_KEY_PROT_EMAIL.s b/libc/sysv/consts/NS_KEY_PROT_EMAIL.s new file mode 100644 index 00000000..0efbd488 --- /dev/null +++ b/libc/sysv/consts/NS_KEY_PROT_EMAIL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NS_KEY_PROT_EMAIL 2 2 2 0 0 diff --git a/libc/sysv/consts/NS_KEY_PROT_IPSEC.s b/libc/sysv/consts/NS_KEY_PROT_IPSEC.s new file mode 100644 index 00000000..6d235689 --- /dev/null +++ b/libc/sysv/consts/NS_KEY_PROT_IPSEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NS_KEY_PROT_IPSEC 4 4 4 0 0 diff --git a/libc/sysv/consts/NS_KEY_PROT_TLS.s b/libc/sysv/consts/NS_KEY_PROT_TLS.s new file mode 100644 index 00000000..e9e26281 --- /dev/null +++ b/libc/sysv/consts/NS_KEY_PROT_TLS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NS_KEY_PROT_TLS 1 1 1 0 0 diff --git a/libc/sysv/consts/NS_KEY_RESERVED_BITMASK2.s b/libc/sysv/consts/NS_KEY_RESERVED_BITMASK2.s new file mode 100644 index 00000000..858c953e --- /dev/null +++ b/libc/sysv/consts/NS_KEY_RESERVED_BITMASK2.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NS_KEY_RESERVED_BITMASK2 0xffff 0xffff 0xffff 0 0 diff --git a/libc/sysv/consts/NS_NXT_MAX.s b/libc/sysv/consts/NS_NXT_MAX.s new file mode 100644 index 00000000..7270536f --- /dev/null +++ b/libc/sysv/consts/NS_NXT_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NS_NXT_MAX 127 127 127 0 0 diff --git a/libc/sysv/consts/NS_OPT_DNSSEC_OK.s b/libc/sysv/consts/NS_OPT_DNSSEC_OK.s new file mode 100644 index 00000000..e2708a3d --- /dev/null +++ b/libc/sysv/consts/NS_OPT_DNSSEC_OK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NS_OPT_DNSSEC_OK 0x8000 0x8000 0x8000 0 0 diff --git a/libc/sysv/consts/NS_TSIG_ERROR_FORMERR.s b/libc/sysv/consts/NS_TSIG_ERROR_FORMERR.s new file mode 100644 index 00000000..84faa52d --- /dev/null +++ b/libc/sysv/consts/NS_TSIG_ERROR_FORMERR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NS_TSIG_ERROR_FORMERR -12 -12 -12 0 0 diff --git a/libc/sysv/consts/NS_TSIG_ERROR_NO_SPACE.s b/libc/sysv/consts/NS_TSIG_ERROR_NO_SPACE.s new file mode 100644 index 00000000..5c718d60 --- /dev/null +++ b/libc/sysv/consts/NS_TSIG_ERROR_NO_SPACE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NS_TSIG_ERROR_NO_SPACE -11 -11 -11 0 0 diff --git a/libc/sysv/consts/NS_TSIG_ERROR_NO_TSIG.s b/libc/sysv/consts/NS_TSIG_ERROR_NO_TSIG.s new file mode 100644 index 00000000..c4ba84ea --- /dev/null +++ b/libc/sysv/consts/NS_TSIG_ERROR_NO_TSIG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NS_TSIG_ERROR_NO_TSIG -10 -10 -10 0 0 diff --git a/libc/sysv/consts/NS_TSIG_FUDGE.s b/libc/sysv/consts/NS_TSIG_FUDGE.s new file mode 100644 index 00000000..242fe02b --- /dev/null +++ b/libc/sysv/consts/NS_TSIG_FUDGE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NS_TSIG_FUDGE 300 300 300 0 0 diff --git a/libc/sysv/consts/NS_TSIG_TCP_COUNT.s b/libc/sysv/consts/NS_TSIG_TCP_COUNT.s new file mode 100644 index 00000000..5554f787 --- /dev/null +++ b/libc/sysv/consts/NS_TSIG_TCP_COUNT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc NS_TSIG_TCP_COUNT 100 100 100 0 0 diff --git a/libc/sysv/consts/NZERO.s b/libc/sysv/consts/NZERO.s new file mode 100644 index 00000000..9864a9b9 --- /dev/null +++ b/libc/sysv/consts/NZERO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon prio NZERO 20 20 20 20 20 diff --git a/libc/sysv/consts/N_6PACK.s b/libc/sysv/consts/N_6PACK.s new file mode 100644 index 00000000..5eddb6ac --- /dev/null +++ b/libc/sysv/consts/N_6PACK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc N_6PACK 7 0 0 0 0 diff --git a/libc/sysv/consts/N_AX25.s b/libc/sysv/consts/N_AX25.s new file mode 100644 index 00000000..4ddac44b --- /dev/null +++ b/libc/sysv/consts/N_AX25.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc N_AX25 5 0 0 0 0 diff --git a/libc/sysv/consts/N_HCI.s b/libc/sysv/consts/N_HCI.s new file mode 100644 index 00000000..bb82146a --- /dev/null +++ b/libc/sysv/consts/N_HCI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc N_HCI 15 0 0 0 0 diff --git a/libc/sysv/consts/N_HDLC.s b/libc/sysv/consts/N_HDLC.s new file mode 100644 index 00000000..18f321a3 --- /dev/null +++ b/libc/sysv/consts/N_HDLC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc N_HDLC 13 0 0 0 0 diff --git a/libc/sysv/consts/N_IRDA.s b/libc/sysv/consts/N_IRDA.s new file mode 100644 index 00000000..f9ddd4ff --- /dev/null +++ b/libc/sysv/consts/N_IRDA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc N_IRDA 11 0 0 0 0 diff --git a/libc/sysv/consts/N_MASC.s b/libc/sysv/consts/N_MASC.s new file mode 100644 index 00000000..412e6920 --- /dev/null +++ b/libc/sysv/consts/N_MASC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc N_MASC 8 0 0 0 0 diff --git a/libc/sysv/consts/N_MOUSE.s b/libc/sysv/consts/N_MOUSE.s new file mode 100644 index 00000000..aa59cd51 --- /dev/null +++ b/libc/sysv/consts/N_MOUSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc N_MOUSE 2 0 0 0 0 diff --git a/libc/sysv/consts/N_PPP.s b/libc/sysv/consts/N_PPP.s new file mode 100644 index 00000000..1d3f15ff --- /dev/null +++ b/libc/sysv/consts/N_PPP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc N_PPP 3 0 0 0 0 diff --git a/libc/sysv/consts/N_PROFIBUS_FDL.s b/libc/sysv/consts/N_PROFIBUS_FDL.s new file mode 100644 index 00000000..9e2088cb --- /dev/null +++ b/libc/sysv/consts/N_PROFIBUS_FDL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc N_PROFIBUS_FDL 10 0 0 0 0 diff --git a/libc/sysv/consts/N_R3964.s b/libc/sysv/consts/N_R3964.s new file mode 100644 index 00000000..48c1232a --- /dev/null +++ b/libc/sysv/consts/N_R3964.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc N_R3964 9 0 0 0 0 diff --git a/libc/sysv/consts/N_SLIP.s b/libc/sysv/consts/N_SLIP.s new file mode 100644 index 00000000..192c4eaa --- /dev/null +++ b/libc/sysv/consts/N_SLIP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc N_SLIP 1 0 0 0 0 diff --git a/libc/sysv/consts/N_SMSBLOCK.s b/libc/sysv/consts/N_SMSBLOCK.s new file mode 100644 index 00000000..07d99c89 --- /dev/null +++ b/libc/sysv/consts/N_SMSBLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc N_SMSBLOCK 12 0 0 0 0 diff --git a/libc/sysv/consts/N_STRIP.s b/libc/sysv/consts/N_STRIP.s new file mode 100644 index 00000000..f46b6193 --- /dev/null +++ b/libc/sysv/consts/N_STRIP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc N_STRIP 4 0 0 0 0 diff --git a/libc/sysv/consts/N_SYNC_PPP.s b/libc/sysv/consts/N_SYNC_PPP.s new file mode 100644 index 00000000..95ba3e3a --- /dev/null +++ b/libc/sysv/consts/N_SYNC_PPP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc N_SYNC_PPP 14 0 0 0 0 diff --git a/libc/sysv/consts/N_TTY.s b/libc/sysv/consts/N_TTY.s new file mode 100644 index 00000000..8e70accf --- /dev/null +++ b/libc/sysv/consts/N_TTY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc N_TTY 0 0 0 0 0 diff --git a/libc/sysv/consts/N_X25.s b/libc/sysv/consts/N_X25.s new file mode 100644 index 00000000..d1aa3515 --- /dev/null +++ b/libc/sysv/consts/N_X25.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc N_X25 6 0 0 0 0 diff --git a/libc/sysv/consts/OCRNL.s b/libc/sysv/consts/OCRNL.s new file mode 100644 index 00000000..878c58c0 --- /dev/null +++ b/libc/sysv/consts/OCRNL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios OCRNL 0b0000000000001000 0b000000000000010000 0b000000000000010000 0b0000000000010000 0b0000000000001000 diff --git a/libc/sysv/consts/OFDEL.s b/libc/sysv/consts/OFDEL.s new file mode 100644 index 00000000..8298a1f6 --- /dev/null +++ b/libc/sysv/consts/OFDEL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios OFDEL 0b0000000010000000 0b100000000000000000 0 0 0b0000000010000000 diff --git a/libc/sysv/consts/OFILL.s b/libc/sysv/consts/OFILL.s new file mode 100644 index 00000000..254b1874 --- /dev/null +++ b/libc/sysv/consts/OFILL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios OFILL 0b0000000001000000 0b000000000010000000 0 0 0b0000000001000000 diff --git a/libc/sysv/consts/OLCUC.s b/libc/sysv/consts/OLCUC.s new file mode 100644 index 00000000..0bc7375a --- /dev/null +++ b/libc/sysv/consts/OLCUC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios OLCUC 0b0000000000000010 0b000000000000000000 0 0b0000000000100000 0b0000000000000010 diff --git a/libc/sysv/consts/OLD_TIME.s b/libc/sysv/consts/OLD_TIME.s new file mode 100644 index 00000000..08dc9d14 --- /dev/null +++ b/libc/sysv/consts/OLD_TIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc OLD_TIME 4 3 2 0 0 diff --git a/libc/sysv/consts/ONLCR.s b/libc/sysv/consts/ONLCR.s new file mode 100644 index 00000000..e6cd7c31 --- /dev/null +++ b/libc/sysv/consts/ONLCR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios ONLCR 0b0000000000000100 0b000000000000000010 0b000000000000000010 0b0000000000000010 0b0000000000000100 diff --git a/libc/sysv/consts/ONLRET.s b/libc/sysv/consts/ONLRET.s new file mode 100644 index 00000000..a3d5f669 --- /dev/null +++ b/libc/sysv/consts/ONLRET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios ONLRET 0b0000000000100000 0b000000000001000000 0b000000000001000000 0b0000000010000000 0b0000000000100000 diff --git a/libc/sysv/consts/ONOCR.s b/libc/sysv/consts/ONOCR.s new file mode 100644 index 00000000..a61333d9 --- /dev/null +++ b/libc/sysv/consts/ONOCR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios ONOCR 0b0000000000010000 0b000000000000100000 0b000000000000100000 0b0000000001000000 0b0000000000010000 diff --git a/libc/sysv/consts/OPOST.s b/libc/sysv/consts/OPOST.s new file mode 100644 index 00000000..6cb75d46 --- /dev/null +++ b/libc/sysv/consts/OPOST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios OPOST 0b0000000000000001 0b000000000000000001 0b000000000000000001 0b0000000000000001 0b0000000000000001 diff --git a/libc/sysv/consts/ORDERED_QUEUE_TAG.s b/libc/sysv/consts/ORDERED_QUEUE_TAG.s new file mode 100644 index 00000000..f27059df --- /dev/null +++ b/libc/sysv/consts/ORDERED_QUEUE_TAG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ORDERED_QUEUE_TAG 34 0 0 0 0 diff --git a/libc/sysv/consts/ORIG_RAX.s b/libc/sysv/consts/ORIG_RAX.s new file mode 100644 index 00000000..366b4ff0 --- /dev/null +++ b/libc/sysv/consts/ORIG_RAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ORIG_RAX 15 0 0 0 0 diff --git a/libc/sysv/consts/O_ACCMODE.s b/libc/sysv/consts/O_ACCMODE.s new file mode 100644 index 00000000..ae0a401e --- /dev/null +++ b/libc/sysv/consts/O_ACCMODE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_ACCMODE 3 3 3 3 0xc0000000 diff --git a/libc/sysv/consts/O_APPEND.s b/libc/sysv/consts/O_APPEND.s new file mode 100644 index 00000000..fb91c070 --- /dev/null +++ b/libc/sysv/consts/O_APPEND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_APPEND 0x0400 8 8 8 0x00000004 diff --git a/libc/sysv/consts/O_ASYNC.s b/libc/sysv/consts/O_ASYNC.s new file mode 100644 index 00000000..6f233ec7 --- /dev/null +++ b/libc/sysv/consts/O_ASYNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_ASYNC 0x2000 0x40 0x40 0x40 0 diff --git a/libc/sysv/consts/O_CLOEXEC.s b/libc/sysv/consts/O_CLOEXEC.s new file mode 100644 index 00000000..0390887f --- /dev/null +++ b/libc/sysv/consts/O_CLOEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_CLOEXEC 0x080000 0x01000000 0x100000 0x010000 0x00080000 diff --git a/libc/sysv/consts/O_CREAT.s b/libc/sysv/consts/O_CREAT.s new file mode 100644 index 00000000..43c53e0a --- /dev/null +++ b/libc/sysv/consts/O_CREAT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_CREAT 0x40 0x0200 0x0200 0x0200 0x00000040 diff --git a/libc/sysv/consts/O_DIRECT.s b/libc/sysv/consts/O_DIRECT.s new file mode 100644 index 00000000..dd8868e7 --- /dev/null +++ b/libc/sysv/consts/O_DIRECT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_DIRECT 0x4000 0 0x010000 0 0x00200000 diff --git a/libc/sysv/consts/O_DIRECTORY.s b/libc/sysv/consts/O_DIRECTORY.s new file mode 100644 index 00000000..7d95cf9b --- /dev/null +++ b/libc/sysv/consts/O_DIRECTORY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_DIRECTORY 0x010000 0x100000 0x020000 0x020000 0 diff --git a/libc/sysv/consts/O_DSYNC.s b/libc/sysv/consts/O_DSYNC.s new file mode 100644 index 00000000..bf1907ee --- /dev/null +++ b/libc/sysv/consts/O_DSYNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_DSYNC 0x1000 0x400000 0 0x80 0 diff --git a/libc/sysv/consts/O_EXCL.s b/libc/sysv/consts/O_EXCL.s new file mode 100644 index 00000000..46cd799d --- /dev/null +++ b/libc/sysv/consts/O_EXCL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_EXCL 0x80 0x0800 0x0800 0x0800 0x00000080 diff --git a/libc/sysv/consts/O_EXEC.s b/libc/sysv/consts/O_EXEC.s new file mode 100644 index 00000000..4597d724 --- /dev/null +++ b/libc/sysv/consts/O_EXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_EXEC 0 0 0x040000 0 0 diff --git a/libc/sysv/consts/O_LARGEFILE.s b/libc/sysv/consts/O_LARGEFILE.s new file mode 100644 index 00000000..a2d61c0a --- /dev/null +++ b/libc/sysv/consts/O_LARGEFILE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat O_LARGEFILE 0 0 0 0 0 diff --git a/libc/sysv/consts/O_NDELAY.s b/libc/sysv/consts/O_NDELAY.s new file mode 100644 index 00000000..d1218aa8 --- /dev/null +++ b/libc/sysv/consts/O_NDELAY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_NDELAY 0x0800 4 4 4 0 diff --git a/libc/sysv/consts/O_NOATIME.s b/libc/sysv/consts/O_NOATIME.s new file mode 100644 index 00000000..5f5d01ab --- /dev/null +++ b/libc/sysv/consts/O_NOATIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_NOATIME 0x040000 0 0 0 0 diff --git a/libc/sysv/consts/O_NOCTTY.s b/libc/sysv/consts/O_NOCTTY.s new file mode 100644 index 00000000..b85a89b0 --- /dev/null +++ b/libc/sysv/consts/O_NOCTTY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_NOCTTY 0x0100 0x020000 0x8000 0x8000 0 diff --git a/libc/sysv/consts/O_NOFOLLOW.s b/libc/sysv/consts/O_NOFOLLOW.s new file mode 100644 index 00000000..90c3a09f --- /dev/null +++ b/libc/sysv/consts/O_NOFOLLOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_NOFOLLOW 0x020000 0x0100 0x0100 0x0100 0 diff --git a/libc/sysv/consts/O_NONBLOCK.s b/libc/sysv/consts/O_NONBLOCK.s new file mode 100644 index 00000000..da0bd835 --- /dev/null +++ b/libc/sysv/consts/O_NONBLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_NONBLOCK 0x0800 4 4 4 0 diff --git a/libc/sysv/consts/O_PATH.s b/libc/sysv/consts/O_PATH.s new file mode 100644 index 00000000..2f01f35f --- /dev/null +++ b/libc/sysv/consts/O_PATH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_PATH 0x200000 0 0 0 0 diff --git a/libc/sysv/consts/O_RDONLY.s b/libc/sysv/consts/O_RDONLY.s new file mode 100644 index 00000000..b6ca5801 --- /dev/null +++ b/libc/sysv/consts/O_RDONLY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_RDONLY 0 0 0 0 0x80000000 diff --git a/libc/sysv/consts/O_RDWR.s b/libc/sysv/consts/O_RDWR.s new file mode 100644 index 00000000..b9894542 --- /dev/null +++ b/libc/sysv/consts/O_RDWR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_RDWR 2 2 2 2 0xc0000000 diff --git a/libc/sysv/consts/O_RSYNC.s b/libc/sysv/consts/O_RSYNC.s new file mode 100644 index 00000000..550d9761 --- /dev/null +++ b/libc/sysv/consts/O_RSYNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_RSYNC 0x101000 0 0 0x80 0 diff --git a/libc/sysv/consts/O_SPARSE.s b/libc/sysv/consts/O_SPARSE.s new file mode 100644 index 00000000..cfe68fcd --- /dev/null +++ b/libc/sysv/consts/O_SPARSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_SPARSE 0 0 0 0 0x00040000 diff --git a/libc/sysv/consts/O_SYNC.s b/libc/sysv/consts/O_SYNC.s new file mode 100644 index 00000000..43da10c5 --- /dev/null +++ b/libc/sysv/consts/O_SYNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_SYNC 0x101000 0x80 0x80 0x80 0 diff --git a/libc/sysv/consts/O_TMPFILE.s b/libc/sysv/consts/O_TMPFILE.s new file mode 100644 index 00000000..719d64c4 --- /dev/null +++ b/libc/sysv/consts/O_TMPFILE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_TMPFILE 0x410000 0 0 0 0x04000100 diff --git a/libc/sysv/consts/O_TRUNC.s b/libc/sysv/consts/O_TRUNC.s new file mode 100644 index 00000000..2b670c05 --- /dev/null +++ b/libc/sysv/consts/O_TRUNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_TRUNC 0x0200 0x0400 0x0400 0x0400 0x00000200 diff --git a/libc/sysv/consts/O_TTY_INIT.s b/libc/sysv/consts/O_TTY_INIT.s new file mode 100644 index 00000000..8b645f4f --- /dev/null +++ b/libc/sysv/consts/O_TTY_INIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_TTY_INIT 0 0 0x080000 0 0 diff --git a/libc/sysv/consts/O_WRONLY.s b/libc/sysv/consts/O_WRONLY.s new file mode 100644 index 00000000..3ec7a951 --- /dev/null +++ b/libc/sysv/consts/O_WRONLY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon open O_WRONLY 1 1 1 1 0x40000000 diff --git a/libc/sysv/consts/PARENB.s b/libc/sysv/consts/PARENB.s new file mode 100644 index 00000000..251c1824 --- /dev/null +++ b/libc/sysv/consts/PARENB.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios PARENB 0x0100 0x1000 0x1000 0x1000 0 diff --git a/libc/sysv/consts/PARMRK.s b/libc/sysv/consts/PARMRK.s new file mode 100644 index 00000000..d418978b --- /dev/null +++ b/libc/sysv/consts/PARMRK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios PARMRK 0b0000000000001000 0b0000000000001000 0b0000000000001000 0b0000000000001000 0b0000000000001000 diff --git a/libc/sysv/consts/PARODD.s b/libc/sysv/consts/PARODD.s new file mode 100644 index 00000000..636f7140 --- /dev/null +++ b/libc/sysv/consts/PARODD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios PARODD 0x0200 0x2000 0x2000 0x2000 0 diff --git a/libc/sysv/consts/PENDIN.s b/libc/sysv/consts/PENDIN.s new file mode 100644 index 00000000..fbdc4414 --- /dev/null +++ b/libc/sysv/consts/PENDIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios PENDIN 0b0100000000000000 536870912 536870912 536870912 0b0100000000000000 diff --git a/libc/sysv/consts/PERSISTENT_RESERVE_IN.s b/libc/sysv/consts/PERSISTENT_RESERVE_IN.s new file mode 100644 index 00000000..c0b8a244 --- /dev/null +++ b/libc/sysv/consts/PERSISTENT_RESERVE_IN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PERSISTENT_RESERVE_IN 94 0 0 0 0 diff --git a/libc/sysv/consts/PERSISTENT_RESERVE_OUT.s b/libc/sysv/consts/PERSISTENT_RESERVE_OUT.s new file mode 100644 index 00000000..9d8b05a7 --- /dev/null +++ b/libc/sysv/consts/PERSISTENT_RESERVE_OUT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PERSISTENT_RESERVE_OUT 95 0 0 0 0 diff --git a/libc/sysv/consts/PF_ALG.s b/libc/sysv/consts/PF_ALG.s new file mode 100644 index 00000000..9927a384 --- /dev/null +++ b/libc/sysv/consts/PF_ALG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_ALG 38 0 0 0 0 diff --git a/libc/sysv/consts/PF_APPLETALK.s b/libc/sysv/consts/PF_APPLETALK.s new file mode 100644 index 00000000..a391534a --- /dev/null +++ b/libc/sysv/consts/PF_APPLETALK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_APPLETALK 5 0x10 0x10 0x10 0x10 diff --git a/libc/sysv/consts/PF_ASH.s b/libc/sysv/consts/PF_ASH.s new file mode 100644 index 00000000..07584ef0 --- /dev/null +++ b/libc/sysv/consts/PF_ASH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_ASH 18 0 0 0 0 diff --git a/libc/sysv/consts/PF_ATMPVC.s b/libc/sysv/consts/PF_ATMPVC.s new file mode 100644 index 00000000..b7ccacdf --- /dev/null +++ b/libc/sysv/consts/PF_ATMPVC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_ATMPVC 8 0 0 0 0 diff --git a/libc/sysv/consts/PF_ATMSVC.s b/libc/sysv/consts/PF_ATMSVC.s new file mode 100644 index 00000000..8b2b3a9e --- /dev/null +++ b/libc/sysv/consts/PF_ATMSVC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_ATMSVC 20 0 0 0 0 diff --git a/libc/sysv/consts/PF_AX25.s b/libc/sysv/consts/PF_AX25.s new file mode 100644 index 00000000..44481f66 --- /dev/null +++ b/libc/sysv/consts/PF_AX25.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_AX25 3 0 0 0 0 diff --git a/libc/sysv/consts/PF_BLUETOOTH.s b/libc/sysv/consts/PF_BLUETOOTH.s new file mode 100644 index 00000000..41013a11 --- /dev/null +++ b/libc/sysv/consts/PF_BLUETOOTH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_BLUETOOTH 31 0 36 0x20 0 diff --git a/libc/sysv/consts/PF_BRIDGE.s b/libc/sysv/consts/PF_BRIDGE.s new file mode 100644 index 00000000..4567cc7f --- /dev/null +++ b/libc/sysv/consts/PF_BRIDGE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_BRIDGE 7 0 0 0 0 diff --git a/libc/sysv/consts/PF_CAIF.s b/libc/sysv/consts/PF_CAIF.s new file mode 100644 index 00000000..1d0519af --- /dev/null +++ b/libc/sysv/consts/PF_CAIF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_CAIF 37 0 0 0 0 diff --git a/libc/sysv/consts/PF_CAN.s b/libc/sysv/consts/PF_CAN.s new file mode 100644 index 00000000..100d6212 --- /dev/null +++ b/libc/sysv/consts/PF_CAN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_CAN 29 0 0 0 0 diff --git a/libc/sysv/consts/PF_ECONET.s b/libc/sysv/consts/PF_ECONET.s new file mode 100644 index 00000000..ceb313cc --- /dev/null +++ b/libc/sysv/consts/PF_ECONET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_ECONET 19 0 0 0 0 diff --git a/libc/sysv/consts/PF_FILE.s b/libc/sysv/consts/PF_FILE.s new file mode 100644 index 00000000..d3d97874 --- /dev/null +++ b/libc/sysv/consts/PF_FILE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_FILE 1 0 0 0 0 diff --git a/libc/sysv/consts/PF_IB.s b/libc/sysv/consts/PF_IB.s new file mode 100644 index 00000000..a97c54a9 --- /dev/null +++ b/libc/sysv/consts/PF_IB.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_IB 27 0 0 0 0 diff --git a/libc/sysv/consts/PF_IEEE802154.s b/libc/sysv/consts/PF_IEEE802154.s new file mode 100644 index 00000000..7a669e6a --- /dev/null +++ b/libc/sysv/consts/PF_IEEE802154.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_IEEE802154 36 0 0 0 0 diff --git a/libc/sysv/consts/PF_INET.s b/libc/sysv/consts/PF_INET.s new file mode 100644 index 00000000..b1462bb2 --- /dev/null +++ b/libc/sysv/consts/PF_INET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_INET 2 2 2 2 0 diff --git a/libc/sysv/consts/PF_INET6.s b/libc/sysv/consts/PF_INET6.s new file mode 100644 index 00000000..16690feb --- /dev/null +++ b/libc/sysv/consts/PF_INET6.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_INET6 10 30 28 24 23 diff --git a/libc/sysv/consts/PF_IPX.s b/libc/sysv/consts/PF_IPX.s new file mode 100644 index 00000000..8731d656 --- /dev/null +++ b/libc/sysv/consts/PF_IPX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_IPX 4 23 23 23 0 diff --git a/libc/sysv/consts/PF_IRDA.s b/libc/sysv/consts/PF_IRDA.s new file mode 100644 index 00000000..f28cb719 --- /dev/null +++ b/libc/sysv/consts/PF_IRDA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_IRDA 23 0 0 0 0 diff --git a/libc/sysv/consts/PF_ISDN.s b/libc/sysv/consts/PF_ISDN.s new file mode 100644 index 00000000..e0894fff --- /dev/null +++ b/libc/sysv/consts/PF_ISDN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_ISDN 34 28 26 26 0 diff --git a/libc/sysv/consts/PF_IUCV.s b/libc/sysv/consts/PF_IUCV.s new file mode 100644 index 00000000..74d521fe --- /dev/null +++ b/libc/sysv/consts/PF_IUCV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_IUCV 0x20 0 0 0 0 diff --git a/libc/sysv/consts/PF_KCM.s b/libc/sysv/consts/PF_KCM.s new file mode 100644 index 00000000..b4e9c857 --- /dev/null +++ b/libc/sysv/consts/PF_KCM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_KCM 41 0 0 0 0 diff --git a/libc/sysv/consts/PF_KEY.s b/libc/sysv/consts/PF_KEY.s new file mode 100644 index 00000000..4063d073 --- /dev/null +++ b/libc/sysv/consts/PF_KEY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_KEY 15 29 27 30 0 diff --git a/libc/sysv/consts/PF_LLC.s b/libc/sysv/consts/PF_LLC.s new file mode 100644 index 00000000..78a310e1 --- /dev/null +++ b/libc/sysv/consts/PF_LLC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_LLC 26 0 0 0 0 diff --git a/libc/sysv/consts/PF_LOCAL.s b/libc/sysv/consts/PF_LOCAL.s new file mode 100644 index 00000000..334c0aa7 --- /dev/null +++ b/libc/sysv/consts/PF_LOCAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_LOCAL 1 1 1 1 0 diff --git a/libc/sysv/consts/PF_MAX.s b/libc/sysv/consts/PF_MAX.s new file mode 100644 index 00000000..a36a1438 --- /dev/null +++ b/libc/sysv/consts/PF_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_MAX 42 40 42 36 35 diff --git a/libc/sysv/consts/PF_MPLS.s b/libc/sysv/consts/PF_MPLS.s new file mode 100644 index 00000000..6e267d95 --- /dev/null +++ b/libc/sysv/consts/PF_MPLS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_MPLS 28 0 0 33 0 diff --git a/libc/sysv/consts/PF_NETBEUI.s b/libc/sysv/consts/PF_NETBEUI.s new file mode 100644 index 00000000..3657f259 --- /dev/null +++ b/libc/sysv/consts/PF_NETBEUI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_NETBEUI 13 0 0 0 0 diff --git a/libc/sysv/consts/PF_NETLINK.s b/libc/sysv/consts/PF_NETLINK.s new file mode 100644 index 00000000..163056a9 --- /dev/null +++ b/libc/sysv/consts/PF_NETLINK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_NETLINK 0x10 0 0 0 0 diff --git a/libc/sysv/consts/PF_NETROM.s b/libc/sysv/consts/PF_NETROM.s new file mode 100644 index 00000000..8a306025 --- /dev/null +++ b/libc/sysv/consts/PF_NETROM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_NETROM 6 0 0 0 0 diff --git a/libc/sysv/consts/PF_NFC.s b/libc/sysv/consts/PF_NFC.s new file mode 100644 index 00000000..4f20d555 --- /dev/null +++ b/libc/sysv/consts/PF_NFC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_NFC 39 0 0 0 0 diff --git a/libc/sysv/consts/PF_PACKET.s b/libc/sysv/consts/PF_PACKET.s new file mode 100644 index 00000000..6edd3d73 --- /dev/null +++ b/libc/sysv/consts/PF_PACKET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_PACKET 17 0 0 0 0 diff --git a/libc/sysv/consts/PF_PHONET.s b/libc/sysv/consts/PF_PHONET.s new file mode 100644 index 00000000..37fe30de --- /dev/null +++ b/libc/sysv/consts/PF_PHONET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_PHONET 35 0 0 0 0 diff --git a/libc/sysv/consts/PF_PPPOX.s b/libc/sysv/consts/PF_PPPOX.s new file mode 100644 index 00000000..9394a0f5 --- /dev/null +++ b/libc/sysv/consts/PF_PPPOX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_PPPOX 24 0 0 0 0 diff --git a/libc/sysv/consts/PF_RDS.s b/libc/sysv/consts/PF_RDS.s new file mode 100644 index 00000000..1ed719bb --- /dev/null +++ b/libc/sysv/consts/PF_RDS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_RDS 21 0 0 0 0 diff --git a/libc/sysv/consts/PF_ROSE.s b/libc/sysv/consts/PF_ROSE.s new file mode 100644 index 00000000..4bd31b22 --- /dev/null +++ b/libc/sysv/consts/PF_ROSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_ROSE 11 0 0 0 0 diff --git a/libc/sysv/consts/PF_ROUTE.s b/libc/sysv/consts/PF_ROUTE.s new file mode 100644 index 00000000..e39e5b31 --- /dev/null +++ b/libc/sysv/consts/PF_ROUTE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_ROUTE 0x10 17 17 17 0 diff --git a/libc/sysv/consts/PF_RXRPC.s b/libc/sysv/consts/PF_RXRPC.s new file mode 100644 index 00000000..0363b3f0 --- /dev/null +++ b/libc/sysv/consts/PF_RXRPC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_RXRPC 33 0 0 0 0 diff --git a/libc/sysv/consts/PF_SECURITY.s b/libc/sysv/consts/PF_SECURITY.s new file mode 100644 index 00000000..ebdf7b56 --- /dev/null +++ b/libc/sysv/consts/PF_SECURITY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_SECURITY 14 0 0 0 0 diff --git a/libc/sysv/consts/PF_SNA.s b/libc/sysv/consts/PF_SNA.s new file mode 100644 index 00000000..fd6efc4d --- /dev/null +++ b/libc/sysv/consts/PF_SNA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_SNA 22 11 11 11 11 diff --git a/libc/sysv/consts/PF_TIPC.s b/libc/sysv/consts/PF_TIPC.s new file mode 100644 index 00000000..545cdb5a --- /dev/null +++ b/libc/sysv/consts/PF_TIPC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_TIPC 30 0 0 0 0 diff --git a/libc/sysv/consts/PF_UNIX.s b/libc/sysv/consts/PF_UNIX.s new file mode 100644 index 00000000..c9f8c84c --- /dev/null +++ b/libc/sysv/consts/PF_UNIX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_UNIX 1 1 1 1 1 diff --git a/libc/sysv/consts/PF_UNSPEC.s b/libc/sysv/consts/PF_UNSPEC.s new file mode 100644 index 00000000..3dc1510b --- /dev/null +++ b/libc/sysv/consts/PF_UNSPEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_UNSPEC 0 0 0 0 0 diff --git a/libc/sysv/consts/PF_VSOCK.s b/libc/sysv/consts/PF_VSOCK.s new file mode 100644 index 00000000..0f1c5fac --- /dev/null +++ b/libc/sysv/consts/PF_VSOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_VSOCK 40 0 0 0 0 diff --git a/libc/sysv/consts/PF_WANPIPE.s b/libc/sysv/consts/PF_WANPIPE.s new file mode 100644 index 00000000..68e89a51 --- /dev/null +++ b/libc/sysv/consts/PF_WANPIPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_WANPIPE 25 0 0 0 0 diff --git a/libc/sysv/consts/PF_X25.s b/libc/sysv/consts/PF_X25.s new file mode 100644 index 00000000..2c13ca72 --- /dev/null +++ b/libc/sysv/consts/PF_X25.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pf PF_X25 9 0 0 0 0 diff --git a/libc/sysv/consts/PIPE_BUF.s b/libc/sysv/consts/PIPE_BUF.s new file mode 100644 index 00000000..d7c41afa --- /dev/null +++ b/libc/sysv/consts/PIPE_BUF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PIPE_BUF 0x1000 0x0200 0x0200 0x0200 0 diff --git a/libc/sysv/consts/PM_STR.s b/libc/sysv/consts/PM_STR.s new file mode 100644 index 00000000..0bc25e00 --- /dev/null +++ b/libc/sysv/consts/PM_STR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PM_STR 0x020027 6 6 5 0 diff --git a/libc/sysv/consts/POLLERR.s b/libc/sysv/consts/POLLERR.s new file mode 100644 index 00000000..e407418e --- /dev/null +++ b/libc/sysv/consts/POLLERR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon poll POLLERR 8 8 8 8 1 diff --git a/libc/sysv/consts/POLLHUP.s b/libc/sysv/consts/POLLHUP.s new file mode 100644 index 00000000..a5e32108 --- /dev/null +++ b/libc/sysv/consts/POLLHUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon poll POLLHUP 0x10 0x10 0x10 0x10 2 diff --git a/libc/sysv/consts/POLLIN.s b/libc/sysv/consts/POLLIN.s new file mode 100644 index 00000000..4d46e8d9 --- /dev/null +++ b/libc/sysv/consts/POLLIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon poll POLLIN 1 1 1 1 0x300 diff --git a/libc/sysv/consts/POLLNVAL.s b/libc/sysv/consts/POLLNVAL.s new file mode 100644 index 00000000..0f1fe07b --- /dev/null +++ b/libc/sysv/consts/POLLNVAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon poll POLLNVAL 0x20 0x20 0x20 0x20 4 diff --git a/libc/sysv/consts/POLLOUT.s b/libc/sysv/consts/POLLOUT.s new file mode 100644 index 00000000..304864c5 --- /dev/null +++ b/libc/sysv/consts/POLLOUT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon poll POLLOUT 4 4 4 4 0x10 diff --git a/libc/sysv/consts/POLLPRI.s b/libc/sysv/consts/POLLPRI.s new file mode 100644 index 00000000..1b3fadcb --- /dev/null +++ b/libc/sysv/consts/POLLPRI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon poll POLLPRI 2 2 2 2 0x0400 diff --git a/libc/sysv/consts/POLLRDBAND.s b/libc/sysv/consts/POLLRDBAND.s new file mode 100644 index 00000000..fce65c8e --- /dev/null +++ b/libc/sysv/consts/POLLRDBAND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon poll POLLRDBAND 0x80 0x80 0x80 0x80 0x0200 diff --git a/libc/sysv/consts/POLLRDHUP.s b/libc/sysv/consts/POLLRDHUP.s new file mode 100644 index 00000000..3e3a4f7d --- /dev/null +++ b/libc/sysv/consts/POLLRDHUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon poll POLLRDHUP 0x2000 0x10 0x10 0x10 2 diff --git a/libc/sysv/consts/POLLRDNORM.s b/libc/sysv/consts/POLLRDNORM.s new file mode 100644 index 00000000..93afdc21 --- /dev/null +++ b/libc/sysv/consts/POLLRDNORM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon poll POLLRDNORM 0x40 0x40 0x40 0x40 0x0100 diff --git a/libc/sysv/consts/POLLWRBAND.s b/libc/sysv/consts/POLLWRBAND.s new file mode 100644 index 00000000..485d871c --- /dev/null +++ b/libc/sysv/consts/POLLWRBAND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon poll POLLWRBAND 0x0200 0x0100 0x0100 0x0100 0x20 diff --git a/libc/sysv/consts/POLLWRNORM.s b/libc/sysv/consts/POLLWRNORM.s new file mode 100644 index 00000000..4df8e731 --- /dev/null +++ b/libc/sysv/consts/POLLWRNORM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon poll POLLWRNORM 0x0100 4 4 4 0x10 diff --git a/libc/sysv/consts/POLL_ERR.s b/libc/sysv/consts/POLL_ERR.s new file mode 100644 index 00000000..7ef3813d --- /dev/null +++ b/libc/sysv/consts/POLL_ERR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sigpoll POLL_ERR 4 4 4 0 0 diff --git a/libc/sysv/consts/POLL_HUP.s b/libc/sysv/consts/POLL_HUP.s new file mode 100644 index 00000000..4644c096 --- /dev/null +++ b/libc/sysv/consts/POLL_HUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sigpoll POLL_HUP 6 6 6 0 0 diff --git a/libc/sysv/consts/POLL_IN.s b/libc/sysv/consts/POLL_IN.s new file mode 100644 index 00000000..1e64e247 --- /dev/null +++ b/libc/sysv/consts/POLL_IN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sigpoll POLL_IN 1 1 1 0 0 diff --git a/libc/sysv/consts/POLL_MSG.s b/libc/sysv/consts/POLL_MSG.s new file mode 100644 index 00000000..30e52641 --- /dev/null +++ b/libc/sysv/consts/POLL_MSG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sigpoll POLL_MSG 3 3 3 0 0 diff --git a/libc/sysv/consts/POLL_OUT.s b/libc/sysv/consts/POLL_OUT.s new file mode 100644 index 00000000..154b0247 --- /dev/null +++ b/libc/sysv/consts/POLL_OUT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sigpoll POLL_OUT 2 2 2 0 0 diff --git a/libc/sysv/consts/POLL_PRI.s b/libc/sysv/consts/POLL_PRI.s new file mode 100644 index 00000000..f1a3d5a5 --- /dev/null +++ b/libc/sysv/consts/POLL_PRI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sigpoll POLL_PRI 5 5 5 0 0 diff --git a/libc/sysv/consts/POSIX_FADV_DONTNEED.s b/libc/sysv/consts/POSIX_FADV_DONTNEED.s new file mode 100644 index 00000000..71d5969e --- /dev/null +++ b/libc/sysv/consts/POSIX_FADV_DONTNEED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat POSIX_FADV_DONTNEED 4 0 4 4 0 diff --git a/libc/sysv/consts/POSIX_FADV_NOREUSE.s b/libc/sysv/consts/POSIX_FADV_NOREUSE.s new file mode 100644 index 00000000..53511449 --- /dev/null +++ b/libc/sysv/consts/POSIX_FADV_NOREUSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon fadv POSIX_FADV_NOREUSE 5 0 5 0 0 diff --git a/libc/sysv/consts/POSIX_FADV_NORMAL.s b/libc/sysv/consts/POSIX_FADV_NORMAL.s new file mode 100644 index 00000000..cda98ae1 --- /dev/null +++ b/libc/sysv/consts/POSIX_FADV_NORMAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat POSIX_FADV_NORMAL 0 0 0 0 0x00000080 diff --git a/libc/sysv/consts/POSIX_FADV_RANDOM.s b/libc/sysv/consts/POSIX_FADV_RANDOM.s new file mode 100644 index 00000000..eb0ed0de --- /dev/null +++ b/libc/sysv/consts/POSIX_FADV_RANDOM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat POSIX_FADV_RANDOM 1 0 1 1 0x10000000 diff --git a/libc/sysv/consts/POSIX_FADV_SEQUENTIAL.s b/libc/sysv/consts/POSIX_FADV_SEQUENTIAL.s new file mode 100644 index 00000000..e9817e5e --- /dev/null +++ b/libc/sysv/consts/POSIX_FADV_SEQUENTIAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat POSIX_FADV_SEQUENTIAL 2 0 2 2 0x8000000 diff --git a/libc/sysv/consts/POSIX_FADV_WILLNEED.s b/libc/sysv/consts/POSIX_FADV_WILLNEED.s new file mode 100644 index 00000000..b9046c12 --- /dev/null +++ b/libc/sysv/consts/POSIX_FADV_WILLNEED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat POSIX_FADV_WILLNEED 3 0 3 3 3 diff --git a/libc/sysv/consts/POSIX_MADV_DONTNEED.s b/libc/sysv/consts/POSIX_MADV_DONTNEED.s new file mode 100644 index 00000000..64a2305e --- /dev/null +++ b/libc/sysv/consts/POSIX_MADV_DONTNEED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat POSIX_MADV_DONTNEED 4 4 4 4 0 diff --git a/libc/sysv/consts/POSIX_MADV_NORMAL.s b/libc/sysv/consts/POSIX_MADV_NORMAL.s new file mode 100644 index 00000000..e5a3be4a --- /dev/null +++ b/libc/sysv/consts/POSIX_MADV_NORMAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat POSIX_MADV_NORMAL 0 0 0 0 0x00000080 diff --git a/libc/sysv/consts/POSIX_MADV_RANDOM.s b/libc/sysv/consts/POSIX_MADV_RANDOM.s new file mode 100644 index 00000000..36c82066 --- /dev/null +++ b/libc/sysv/consts/POSIX_MADV_RANDOM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat POSIX_MADV_RANDOM 1 1 1 1 0x10000000 diff --git a/libc/sysv/consts/POSIX_MADV_SEQUENTIAL.s b/libc/sysv/consts/POSIX_MADV_SEQUENTIAL.s new file mode 100644 index 00000000..c67d9b7f --- /dev/null +++ b/libc/sysv/consts/POSIX_MADV_SEQUENTIAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat POSIX_MADV_SEQUENTIAL 2 2 2 2 0x8000000 diff --git a/libc/sysv/consts/POSIX_MADV_WILLNEED.s b/libc/sysv/consts/POSIX_MADV_WILLNEED.s new file mode 100644 index 00000000..24cb2b7c --- /dev/null +++ b/libc/sysv/consts/POSIX_MADV_WILLNEED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat POSIX_MADV_WILLNEED 3 3 3 3 3 diff --git a/libc/sysv/consts/POSIX_SPAWN_RESETIDS.s b/libc/sysv/consts/POSIX_SPAWN_RESETIDS.s new file mode 100644 index 00000000..fb41004b --- /dev/null +++ b/libc/sysv/consts/POSIX_SPAWN_RESETIDS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon spawn POSIX_SPAWN_RESETIDS 1 1 1 1 0 diff --git a/libc/sysv/consts/POSIX_SPAWN_SETPGROUP.s b/libc/sysv/consts/POSIX_SPAWN_SETPGROUP.s new file mode 100644 index 00000000..7d1cb651 --- /dev/null +++ b/libc/sysv/consts/POSIX_SPAWN_SETPGROUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon spawn POSIX_SPAWN_SETPGROUP 2 2 2 2 0 diff --git a/libc/sysv/consts/POSIX_SPAWN_SETSCHEDPARAM.s b/libc/sysv/consts/POSIX_SPAWN_SETSCHEDPARAM.s new file mode 100644 index 00000000..7c73533f --- /dev/null +++ b/libc/sysv/consts/POSIX_SPAWN_SETSCHEDPARAM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon spawn POSIX_SPAWN_SETSCHEDPARAM 0x10 0 4 4 0 diff --git a/libc/sysv/consts/POSIX_SPAWN_SETSCHEDULER.s b/libc/sysv/consts/POSIX_SPAWN_SETSCHEDULER.s new file mode 100644 index 00000000..a26af3fe --- /dev/null +++ b/libc/sysv/consts/POSIX_SPAWN_SETSCHEDULER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon spawn POSIX_SPAWN_SETSCHEDULER 0x20 0 8 8 0 diff --git a/libc/sysv/consts/POSIX_SPAWN_SETSIGDEF.s b/libc/sysv/consts/POSIX_SPAWN_SETSIGDEF.s new file mode 100644 index 00000000..7941dcaf --- /dev/null +++ b/libc/sysv/consts/POSIX_SPAWN_SETSIGDEF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon spawn POSIX_SPAWN_SETSIGDEF 4 4 0x10 0x10 0 diff --git a/libc/sysv/consts/POSIX_SPAWN_SETSIGMASK.s b/libc/sysv/consts/POSIX_SPAWN_SETSIGMASK.s new file mode 100644 index 00000000..87788e65 --- /dev/null +++ b/libc/sysv/consts/POSIX_SPAWN_SETSIGMASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon spawn POSIX_SPAWN_SETSIGMASK 8 8 0x20 0x20 0 diff --git a/libc/sysv/consts/POSIX_SPAWN_USEVFORK.s b/libc/sysv/consts/POSIX_SPAWN_USEVFORK.s new file mode 100644 index 00000000..eef33de2 --- /dev/null +++ b/libc/sysv/consts/POSIX_SPAWN_USEVFORK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon spawn POSIX_SPAWN_USEVFORK 0x40 0 0 0 0 diff --git a/libc/sysv/consts/PPPDISC.s b/libc/sysv/consts/PPPDISC.s new file mode 100644 index 00000000..43c16da5 --- /dev/null +++ b/libc/sysv/consts/PPPDISC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios PPPDISC 0 0x5 0x5 0x5 -1 diff --git a/libc/sysv/consts/PRELIM.s b/libc/sysv/consts/PRELIM.s new file mode 100644 index 00000000..78e75ad8 --- /dev/null +++ b/libc/sysv/consts/PRELIM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PRELIM 1 1 1 1 0 diff --git a/libc/sysv/consts/PRE_FETCH.s b/libc/sysv/consts/PRE_FETCH.s new file mode 100644 index 00000000..54700a13 --- /dev/null +++ b/libc/sysv/consts/PRE_FETCH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PRE_FETCH 52 0 0 0 0 diff --git a/libc/sysv/consts/PRIO_MAX.s b/libc/sysv/consts/PRIO_MAX.s new file mode 100644 index 00000000..5859f72e --- /dev/null +++ b/libc/sysv/consts/PRIO_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon prio PRIO_MAX 20 20 20 20 20 diff --git a/libc/sysv/consts/PRIO_MIN.s b/libc/sysv/consts/PRIO_MIN.s new file mode 100644 index 00000000..9a896509 --- /dev/null +++ b/libc/sysv/consts/PRIO_MIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon prio PRIO_MIN -20 -20 -20 -20 -20 diff --git a/libc/sysv/consts/PRIO_PGRP.s b/libc/sysv/consts/PRIO_PGRP.s new file mode 100644 index 00000000..dee566fb --- /dev/null +++ b/libc/sysv/consts/PRIO_PGRP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon prio PRIO_PGRP 1 1 1 1 1 diff --git a/libc/sysv/consts/PRIO_PROCESS.s b/libc/sysv/consts/PRIO_PROCESS.s new file mode 100644 index 00000000..e2d1105d --- /dev/null +++ b/libc/sysv/consts/PRIO_PROCESS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon prio PRIO_PROCESS 0 0 0 0 0 diff --git a/libc/sysv/consts/PRIO_USER.s b/libc/sysv/consts/PRIO_USER.s new file mode 100644 index 00000000..c640b881 --- /dev/null +++ b/libc/sysv/consts/PRIO_USER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon prio PRIO_USER 2 2 2 2 2 diff --git a/libc/sysv/consts/PROT_EXEC.s b/libc/sysv/consts/PROT_EXEC.s new file mode 100644 index 00000000..28608a6c --- /dev/null +++ b/libc/sysv/consts/PROT_EXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mprot PROT_EXEC 4 4 4 4 4 diff --git a/libc/sysv/consts/PROT_GROWSDOWN.s b/libc/sysv/consts/PROT_GROWSDOWN.s new file mode 100644 index 00000000..510b7ed8 --- /dev/null +++ b/libc/sysv/consts/PROT_GROWSDOWN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mprot PROT_GROWSDOWN 0x01000000 0 0 0 0x01000000 diff --git a/libc/sysv/consts/PROT_GROWSUP.s b/libc/sysv/consts/PROT_GROWSUP.s new file mode 100644 index 00000000..9a6df123 --- /dev/null +++ b/libc/sysv/consts/PROT_GROWSUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mprot PROT_GROWSUP 0x02000000 0 0 0 0 diff --git a/libc/sysv/consts/PROT_NONE.s b/libc/sysv/consts/PROT_NONE.s new file mode 100644 index 00000000..182d68bf --- /dev/null +++ b/libc/sysv/consts/PROT_NONE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mprot PROT_NONE 0 0 0 0 0 diff --git a/libc/sysv/consts/PROT_READ.s b/libc/sysv/consts/PROT_READ.s new file mode 100644 index 00000000..ed096d35 --- /dev/null +++ b/libc/sysv/consts/PROT_READ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mprot PROT_READ 1 1 1 1 1 diff --git a/libc/sysv/consts/PROT_WRITE.s b/libc/sysv/consts/PROT_WRITE.s new file mode 100644 index 00000000..98582ac1 --- /dev/null +++ b/libc/sysv/consts/PROT_WRITE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mprot PROT_WRITE 2 2 2 2 2 diff --git a/libc/sysv/consts/PR_CAPBSET_DROP.s b/libc/sysv/consts/PR_CAPBSET_DROP.s new file mode 100644 index 00000000..159947c0 --- /dev/null +++ b/libc/sysv/consts/PR_CAPBSET_DROP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_CAPBSET_DROP 24 0 0 0 0 diff --git a/libc/sysv/consts/PR_CAPBSET_READ.s b/libc/sysv/consts/PR_CAPBSET_READ.s new file mode 100644 index 00000000..daa5e38f --- /dev/null +++ b/libc/sysv/consts/PR_CAPBSET_READ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_CAPBSET_READ 23 0 0 0 0 diff --git a/libc/sysv/consts/PR_CAP_AMBIENT.s b/libc/sysv/consts/PR_CAP_AMBIENT.s new file mode 100644 index 00000000..a0226800 --- /dev/null +++ b/libc/sysv/consts/PR_CAP_AMBIENT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_CAP_AMBIENT 47 0 0 0 0 diff --git a/libc/sysv/consts/PR_CAP_AMBIENT_CLEAR_ALL.s b/libc/sysv/consts/PR_CAP_AMBIENT_CLEAR_ALL.s new file mode 100644 index 00000000..ddf03789 --- /dev/null +++ b/libc/sysv/consts/PR_CAP_AMBIENT_CLEAR_ALL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_CAP_AMBIENT_CLEAR_ALL 4 0 0 0 0 diff --git a/libc/sysv/consts/PR_CAP_AMBIENT_IS_SET.s b/libc/sysv/consts/PR_CAP_AMBIENT_IS_SET.s new file mode 100644 index 00000000..3ad982a4 --- /dev/null +++ b/libc/sysv/consts/PR_CAP_AMBIENT_IS_SET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_CAP_AMBIENT_IS_SET 1 0 0 0 0 diff --git a/libc/sysv/consts/PR_CAP_AMBIENT_LOWER.s b/libc/sysv/consts/PR_CAP_AMBIENT_LOWER.s new file mode 100644 index 00000000..2ea60874 --- /dev/null +++ b/libc/sysv/consts/PR_CAP_AMBIENT_LOWER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_CAP_AMBIENT_LOWER 3 0 0 0 0 diff --git a/libc/sysv/consts/PR_CAP_AMBIENT_RAISE.s b/libc/sysv/consts/PR_CAP_AMBIENT_RAISE.s new file mode 100644 index 00000000..ab3cf945 --- /dev/null +++ b/libc/sysv/consts/PR_CAP_AMBIENT_RAISE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_CAP_AMBIENT_RAISE 2 0 0 0 0 diff --git a/libc/sysv/consts/PR_ENDIAN_BIG.s b/libc/sysv/consts/PR_ENDIAN_BIG.s new file mode 100644 index 00000000..310fca8a --- /dev/null +++ b/libc/sysv/consts/PR_ENDIAN_BIG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_ENDIAN_BIG 0 0 0 0 0 diff --git a/libc/sysv/consts/PR_ENDIAN_LITTLE.s b/libc/sysv/consts/PR_ENDIAN_LITTLE.s new file mode 100644 index 00000000..345e1f72 --- /dev/null +++ b/libc/sysv/consts/PR_ENDIAN_LITTLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_ENDIAN_LITTLE 1 0 0 0 0 diff --git a/libc/sysv/consts/PR_ENDIAN_PPC_LITTLE.s b/libc/sysv/consts/PR_ENDIAN_PPC_LITTLE.s new file mode 100644 index 00000000..0a343107 --- /dev/null +++ b/libc/sysv/consts/PR_ENDIAN_PPC_LITTLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_ENDIAN_PPC_LITTLE 2 0 0 0 0 diff --git a/libc/sysv/consts/PR_FPEMU_NOPRINT.s b/libc/sysv/consts/PR_FPEMU_NOPRINT.s new file mode 100644 index 00000000..04fecb2a --- /dev/null +++ b/libc/sysv/consts/PR_FPEMU_NOPRINT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_FPEMU_NOPRINT 1 0 0 0 0 diff --git a/libc/sysv/consts/PR_FPEMU_SIGFPE.s b/libc/sysv/consts/PR_FPEMU_SIGFPE.s new file mode 100644 index 00000000..749e6f78 --- /dev/null +++ b/libc/sysv/consts/PR_FPEMU_SIGFPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_FPEMU_SIGFPE 2 0 0 0 0 diff --git a/libc/sysv/consts/PR_FP_EXC_ASYNC.s b/libc/sysv/consts/PR_FP_EXC_ASYNC.s new file mode 100644 index 00000000..49dc6622 --- /dev/null +++ b/libc/sysv/consts/PR_FP_EXC_ASYNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_FP_EXC_ASYNC 2 0 0 0 0 diff --git a/libc/sysv/consts/PR_FP_EXC_DISABLED.s b/libc/sysv/consts/PR_FP_EXC_DISABLED.s new file mode 100644 index 00000000..64bef263 --- /dev/null +++ b/libc/sysv/consts/PR_FP_EXC_DISABLED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_FP_EXC_DISABLED 0 0 0 0 0 diff --git a/libc/sysv/consts/PR_FP_EXC_DIV.s b/libc/sysv/consts/PR_FP_EXC_DIV.s new file mode 100644 index 00000000..62a41789 --- /dev/null +++ b/libc/sysv/consts/PR_FP_EXC_DIV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_FP_EXC_DIV 0x010000 0 0 0 0 diff --git a/libc/sysv/consts/PR_FP_EXC_INV.s b/libc/sysv/consts/PR_FP_EXC_INV.s new file mode 100644 index 00000000..c6fc7772 --- /dev/null +++ b/libc/sysv/consts/PR_FP_EXC_INV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_FP_EXC_INV 0x100000 0 0 0 0 diff --git a/libc/sysv/consts/PR_FP_EXC_NONRECOV.s b/libc/sysv/consts/PR_FP_EXC_NONRECOV.s new file mode 100644 index 00000000..8717c25e --- /dev/null +++ b/libc/sysv/consts/PR_FP_EXC_NONRECOV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_FP_EXC_NONRECOV 1 0 0 0 0 diff --git a/libc/sysv/consts/PR_FP_EXC_OVF.s b/libc/sysv/consts/PR_FP_EXC_OVF.s new file mode 100644 index 00000000..8741a70f --- /dev/null +++ b/libc/sysv/consts/PR_FP_EXC_OVF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_FP_EXC_OVF 0x020000 0 0 0 0 diff --git a/libc/sysv/consts/PR_FP_EXC_PRECISE.s b/libc/sysv/consts/PR_FP_EXC_PRECISE.s new file mode 100644 index 00000000..004c09a1 --- /dev/null +++ b/libc/sysv/consts/PR_FP_EXC_PRECISE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_FP_EXC_PRECISE 3 0 0 0 0 diff --git a/libc/sysv/consts/PR_FP_EXC_RES.s b/libc/sysv/consts/PR_FP_EXC_RES.s new file mode 100644 index 00000000..a60bb428 --- /dev/null +++ b/libc/sysv/consts/PR_FP_EXC_RES.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_FP_EXC_RES 0x080000 0 0 0 0 diff --git a/libc/sysv/consts/PR_FP_EXC_SW_ENABLE.s b/libc/sysv/consts/PR_FP_EXC_SW_ENABLE.s new file mode 100644 index 00000000..8a66f55f --- /dev/null +++ b/libc/sysv/consts/PR_FP_EXC_SW_ENABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_FP_EXC_SW_ENABLE 0x80 0 0 0 0 diff --git a/libc/sysv/consts/PR_FP_EXC_UND.s b/libc/sysv/consts/PR_FP_EXC_UND.s new file mode 100644 index 00000000..6ea0d945 --- /dev/null +++ b/libc/sysv/consts/PR_FP_EXC_UND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_FP_EXC_UND 0x040000 0 0 0 0 diff --git a/libc/sysv/consts/PR_FP_MODE_FR.s b/libc/sysv/consts/PR_FP_MODE_FR.s new file mode 100644 index 00000000..a883bab6 --- /dev/null +++ b/libc/sysv/consts/PR_FP_MODE_FR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_FP_MODE_FR 1 0 0 0 0 diff --git a/libc/sysv/consts/PR_FP_MODE_FRE.s b/libc/sysv/consts/PR_FP_MODE_FRE.s new file mode 100644 index 00000000..bc41751c --- /dev/null +++ b/libc/sysv/consts/PR_FP_MODE_FRE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_FP_MODE_FRE 2 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_CHILD_SUBREAPER.s b/libc/sysv/consts/PR_GET_CHILD_SUBREAPER.s new file mode 100644 index 00000000..625ed9bd --- /dev/null +++ b/libc/sysv/consts/PR_GET_CHILD_SUBREAPER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_CHILD_SUBREAPER 37 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_DUMPABLE.s b/libc/sysv/consts/PR_GET_DUMPABLE.s new file mode 100644 index 00000000..70c3df11 --- /dev/null +++ b/libc/sysv/consts/PR_GET_DUMPABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_DUMPABLE 3 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_ENDIAN.s b/libc/sysv/consts/PR_GET_ENDIAN.s new file mode 100644 index 00000000..fdf5ec1a --- /dev/null +++ b/libc/sysv/consts/PR_GET_ENDIAN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_ENDIAN 19 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_FPEMU.s b/libc/sysv/consts/PR_GET_FPEMU.s new file mode 100644 index 00000000..aa6406ba --- /dev/null +++ b/libc/sysv/consts/PR_GET_FPEMU.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_FPEMU 9 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_FPEXC.s b/libc/sysv/consts/PR_GET_FPEXC.s new file mode 100644 index 00000000..c03ed3c8 --- /dev/null +++ b/libc/sysv/consts/PR_GET_FPEXC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_FPEXC 11 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_FP_MODE.s b/libc/sysv/consts/PR_GET_FP_MODE.s new file mode 100644 index 00000000..3c71ef63 --- /dev/null +++ b/libc/sysv/consts/PR_GET_FP_MODE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_FP_MODE 46 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_KEEPCAPS.s b/libc/sysv/consts/PR_GET_KEEPCAPS.s new file mode 100644 index 00000000..79d01d73 --- /dev/null +++ b/libc/sysv/consts/PR_GET_KEEPCAPS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_KEEPCAPS 7 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_NAME.s b/libc/sysv/consts/PR_GET_NAME.s new file mode 100644 index 00000000..9890bd7f --- /dev/null +++ b/libc/sysv/consts/PR_GET_NAME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_NAME 0x10 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_NO_NEW_PRIVS.s b/libc/sysv/consts/PR_GET_NO_NEW_PRIVS.s new file mode 100644 index 00000000..dc08f3b5 --- /dev/null +++ b/libc/sysv/consts/PR_GET_NO_NEW_PRIVS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_NO_NEW_PRIVS 39 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_PDEATHSIG.s b/libc/sysv/consts/PR_GET_PDEATHSIG.s new file mode 100644 index 00000000..3d2b6e60 --- /dev/null +++ b/libc/sysv/consts/PR_GET_PDEATHSIG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_PDEATHSIG 2 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_SECCOMP.s b/libc/sysv/consts/PR_GET_SECCOMP.s new file mode 100644 index 00000000..8ebb5a8b --- /dev/null +++ b/libc/sysv/consts/PR_GET_SECCOMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_SECCOMP 21 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_SECUREBITS.s b/libc/sysv/consts/PR_GET_SECUREBITS.s new file mode 100644 index 00000000..229f79c8 --- /dev/null +++ b/libc/sysv/consts/PR_GET_SECUREBITS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_SECUREBITS 27 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_SPECULATION_CTRL.s b/libc/sysv/consts/PR_GET_SPECULATION_CTRL.s new file mode 100644 index 00000000..1eede9e2 --- /dev/null +++ b/libc/sysv/consts/PR_GET_SPECULATION_CTRL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_SPECULATION_CTRL 52 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_THP_DISABLE.s b/libc/sysv/consts/PR_GET_THP_DISABLE.s new file mode 100644 index 00000000..adbb4816 --- /dev/null +++ b/libc/sysv/consts/PR_GET_THP_DISABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_THP_DISABLE 42 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_TID_ADDRESS.s b/libc/sysv/consts/PR_GET_TID_ADDRESS.s new file mode 100644 index 00000000..0a9791bd --- /dev/null +++ b/libc/sysv/consts/PR_GET_TID_ADDRESS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_TID_ADDRESS 40 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_TIMERSLACK.s b/libc/sysv/consts/PR_GET_TIMERSLACK.s new file mode 100644 index 00000000..3b4f4bab --- /dev/null +++ b/libc/sysv/consts/PR_GET_TIMERSLACK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_TIMERSLACK 30 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_TIMING.s b/libc/sysv/consts/PR_GET_TIMING.s new file mode 100644 index 00000000..c649405f --- /dev/null +++ b/libc/sysv/consts/PR_GET_TIMING.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_TIMING 13 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_TSC.s b/libc/sysv/consts/PR_GET_TSC.s new file mode 100644 index 00000000..d751d058 --- /dev/null +++ b/libc/sysv/consts/PR_GET_TSC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_TSC 25 0 0 0 0 diff --git a/libc/sysv/consts/PR_GET_UNALIGN.s b/libc/sysv/consts/PR_GET_UNALIGN.s new file mode 100644 index 00000000..c904cd2f --- /dev/null +++ b/libc/sysv/consts/PR_GET_UNALIGN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_GET_UNALIGN 5 0 0 0 0 diff --git a/libc/sysv/consts/PR_MCE_KILL.s b/libc/sysv/consts/PR_MCE_KILL.s new file mode 100644 index 00000000..4000ddf2 --- /dev/null +++ b/libc/sysv/consts/PR_MCE_KILL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_MCE_KILL 33 0 0 0 0 diff --git a/libc/sysv/consts/PR_MCE_KILL_CLEAR.s b/libc/sysv/consts/PR_MCE_KILL_CLEAR.s new file mode 100644 index 00000000..1835fede --- /dev/null +++ b/libc/sysv/consts/PR_MCE_KILL_CLEAR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_MCE_KILL_CLEAR 0 0 0 0 0 diff --git a/libc/sysv/consts/PR_MCE_KILL_DEFAULT.s b/libc/sysv/consts/PR_MCE_KILL_DEFAULT.s new file mode 100644 index 00000000..3db684e1 --- /dev/null +++ b/libc/sysv/consts/PR_MCE_KILL_DEFAULT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_MCE_KILL_DEFAULT 2 0 0 0 0 diff --git a/libc/sysv/consts/PR_MCE_KILL_EARLY.s b/libc/sysv/consts/PR_MCE_KILL_EARLY.s new file mode 100644 index 00000000..6512b2e8 --- /dev/null +++ b/libc/sysv/consts/PR_MCE_KILL_EARLY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_MCE_KILL_EARLY 1 0 0 0 0 diff --git a/libc/sysv/consts/PR_MCE_KILL_GET.s b/libc/sysv/consts/PR_MCE_KILL_GET.s new file mode 100644 index 00000000..fe0fa6ba --- /dev/null +++ b/libc/sysv/consts/PR_MCE_KILL_GET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_MCE_KILL_GET 34 0 0 0 0 diff --git a/libc/sysv/consts/PR_MCE_KILL_LATE.s b/libc/sysv/consts/PR_MCE_KILL_LATE.s new file mode 100644 index 00000000..f8723392 --- /dev/null +++ b/libc/sysv/consts/PR_MCE_KILL_LATE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_MCE_KILL_LATE 0 0 0 0 0 diff --git a/libc/sysv/consts/PR_MCE_KILL_SET.s b/libc/sysv/consts/PR_MCE_KILL_SET.s new file mode 100644 index 00000000..9a191acf --- /dev/null +++ b/libc/sysv/consts/PR_MCE_KILL_SET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_MCE_KILL_SET 1 0 0 0 0 diff --git a/libc/sysv/consts/PR_MPX_DISABLE_MANAGEMENT.s b/libc/sysv/consts/PR_MPX_DISABLE_MANAGEMENT.s new file mode 100644 index 00000000..b724f55b --- /dev/null +++ b/libc/sysv/consts/PR_MPX_DISABLE_MANAGEMENT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_MPX_DISABLE_MANAGEMENT 44 0 0 0 0 diff --git a/libc/sysv/consts/PR_MPX_ENABLE_MANAGEMENT.s b/libc/sysv/consts/PR_MPX_ENABLE_MANAGEMENT.s new file mode 100644 index 00000000..7c186834 --- /dev/null +++ b/libc/sysv/consts/PR_MPX_ENABLE_MANAGEMENT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_MPX_ENABLE_MANAGEMENT 43 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_CHILD_SUBREAPER.s b/libc/sysv/consts/PR_SET_CHILD_SUBREAPER.s new file mode 100644 index 00000000..e03cf9e6 --- /dev/null +++ b/libc/sysv/consts/PR_SET_CHILD_SUBREAPER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_CHILD_SUBREAPER 36 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_DUMPABLE.s b/libc/sysv/consts/PR_SET_DUMPABLE.s new file mode 100644 index 00000000..c737c23d --- /dev/null +++ b/libc/sysv/consts/PR_SET_DUMPABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_DUMPABLE 4 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_ENDIAN.s b/libc/sysv/consts/PR_SET_ENDIAN.s new file mode 100644 index 00000000..0533b9f0 --- /dev/null +++ b/libc/sysv/consts/PR_SET_ENDIAN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_ENDIAN 20 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_FPEMU.s b/libc/sysv/consts/PR_SET_FPEMU.s new file mode 100644 index 00000000..c554b141 --- /dev/null +++ b/libc/sysv/consts/PR_SET_FPEMU.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_FPEMU 10 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_FPEXC.s b/libc/sysv/consts/PR_SET_FPEXC.s new file mode 100644 index 00000000..d7ed5bde --- /dev/null +++ b/libc/sysv/consts/PR_SET_FPEXC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_FPEXC 12 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_FP_MODE.s b/libc/sysv/consts/PR_SET_FP_MODE.s new file mode 100644 index 00000000..68403310 --- /dev/null +++ b/libc/sysv/consts/PR_SET_FP_MODE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_FP_MODE 45 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_KEEPCAPS.s b/libc/sysv/consts/PR_SET_KEEPCAPS.s new file mode 100644 index 00000000..8c55945c --- /dev/null +++ b/libc/sysv/consts/PR_SET_KEEPCAPS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_KEEPCAPS 8 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_MM.s b/libc/sysv/consts/PR_SET_MM.s new file mode 100644 index 00000000..7d2a4219 --- /dev/null +++ b/libc/sysv/consts/PR_SET_MM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_MM 35 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_MM_ARG_END.s b/libc/sysv/consts/PR_SET_MM_ARG_END.s new file mode 100644 index 00000000..9c2d9132 --- /dev/null +++ b/libc/sysv/consts/PR_SET_MM_ARG_END.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_MM_ARG_END 9 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_MM_ARG_START.s b/libc/sysv/consts/PR_SET_MM_ARG_START.s new file mode 100644 index 00000000..48d80c18 --- /dev/null +++ b/libc/sysv/consts/PR_SET_MM_ARG_START.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_MM_ARG_START 8 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_MM_AUXV.s b/libc/sysv/consts/PR_SET_MM_AUXV.s new file mode 100644 index 00000000..a9fb7e89 --- /dev/null +++ b/libc/sysv/consts/PR_SET_MM_AUXV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_MM_AUXV 12 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_MM_BRK.s b/libc/sysv/consts/PR_SET_MM_BRK.s new file mode 100644 index 00000000..bc858125 --- /dev/null +++ b/libc/sysv/consts/PR_SET_MM_BRK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_MM_BRK 7 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_MM_END_CODE.s b/libc/sysv/consts/PR_SET_MM_END_CODE.s new file mode 100644 index 00000000..b2f5eed4 --- /dev/null +++ b/libc/sysv/consts/PR_SET_MM_END_CODE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_MM_END_CODE 2 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_MM_END_DATA.s b/libc/sysv/consts/PR_SET_MM_END_DATA.s new file mode 100644 index 00000000..d798408f --- /dev/null +++ b/libc/sysv/consts/PR_SET_MM_END_DATA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_MM_END_DATA 4 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_MM_ENV_END.s b/libc/sysv/consts/PR_SET_MM_ENV_END.s new file mode 100644 index 00000000..7f815f7d --- /dev/null +++ b/libc/sysv/consts/PR_SET_MM_ENV_END.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_MM_ENV_END 11 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_MM_ENV_START.s b/libc/sysv/consts/PR_SET_MM_ENV_START.s new file mode 100644 index 00000000..7ef70b49 --- /dev/null +++ b/libc/sysv/consts/PR_SET_MM_ENV_START.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_MM_ENV_START 10 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_MM_EXE_FILE.s b/libc/sysv/consts/PR_SET_MM_EXE_FILE.s new file mode 100644 index 00000000..ff951cc9 --- /dev/null +++ b/libc/sysv/consts/PR_SET_MM_EXE_FILE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_MM_EXE_FILE 13 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_MM_MAP.s b/libc/sysv/consts/PR_SET_MM_MAP.s new file mode 100644 index 00000000..b63b3c77 --- /dev/null +++ b/libc/sysv/consts/PR_SET_MM_MAP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_MM_MAP 14 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_MM_MAP_SIZE.s b/libc/sysv/consts/PR_SET_MM_MAP_SIZE.s new file mode 100644 index 00000000..30db96d6 --- /dev/null +++ b/libc/sysv/consts/PR_SET_MM_MAP_SIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_MM_MAP_SIZE 15 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_MM_START_BRK.s b/libc/sysv/consts/PR_SET_MM_START_BRK.s new file mode 100644 index 00000000..e8e80b2b --- /dev/null +++ b/libc/sysv/consts/PR_SET_MM_START_BRK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_MM_START_BRK 6 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_MM_START_CODE.s b/libc/sysv/consts/PR_SET_MM_START_CODE.s new file mode 100644 index 00000000..ba2d6121 --- /dev/null +++ b/libc/sysv/consts/PR_SET_MM_START_CODE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_MM_START_CODE 1 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_MM_START_DATA.s b/libc/sysv/consts/PR_SET_MM_START_DATA.s new file mode 100644 index 00000000..003ba9c6 --- /dev/null +++ b/libc/sysv/consts/PR_SET_MM_START_DATA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_MM_START_DATA 3 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_MM_START_STACK.s b/libc/sysv/consts/PR_SET_MM_START_STACK.s new file mode 100644 index 00000000..f82e74cd --- /dev/null +++ b/libc/sysv/consts/PR_SET_MM_START_STACK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_MM_START_STACK 5 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_NAME.s b/libc/sysv/consts/PR_SET_NAME.s new file mode 100644 index 00000000..7b37e146 --- /dev/null +++ b/libc/sysv/consts/PR_SET_NAME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_NAME 15 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_NO_NEW_PRIVS.s b/libc/sysv/consts/PR_SET_NO_NEW_PRIVS.s new file mode 100644 index 00000000..0a4f3499 --- /dev/null +++ b/libc/sysv/consts/PR_SET_NO_NEW_PRIVS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_NO_NEW_PRIVS 38 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_PDEATHSIG.s b/libc/sysv/consts/PR_SET_PDEATHSIG.s new file mode 100644 index 00000000..9412a621 --- /dev/null +++ b/libc/sysv/consts/PR_SET_PDEATHSIG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_PDEATHSIG 1 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_PTRACER.s b/libc/sysv/consts/PR_SET_PTRACER.s new file mode 100644 index 00000000..7dd4ecff --- /dev/null +++ b/libc/sysv/consts/PR_SET_PTRACER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_PTRACER 0x59616d61 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_PTRACER_ANY.s b/libc/sysv/consts/PR_SET_PTRACER_ANY.s new file mode 100644 index 00000000..4144ffc1 --- /dev/null +++ b/libc/sysv/consts/PR_SET_PTRACER_ANY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_PTRACER_ANY -1 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_SECCOMP.s b/libc/sysv/consts/PR_SET_SECCOMP.s new file mode 100644 index 00000000..ce3e4c21 --- /dev/null +++ b/libc/sysv/consts/PR_SET_SECCOMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_SECCOMP 22 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_SECUREBITS.s b/libc/sysv/consts/PR_SET_SECUREBITS.s new file mode 100644 index 00000000..cfad2f6f --- /dev/null +++ b/libc/sysv/consts/PR_SET_SECUREBITS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_SECUREBITS 28 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_SPECULATION_CTRL.s b/libc/sysv/consts/PR_SET_SPECULATION_CTRL.s new file mode 100644 index 00000000..dcfd7659 --- /dev/null +++ b/libc/sysv/consts/PR_SET_SPECULATION_CTRL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_SPECULATION_CTRL 53 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_THP_DISABLE.s b/libc/sysv/consts/PR_SET_THP_DISABLE.s new file mode 100644 index 00000000..6bbb4d4a --- /dev/null +++ b/libc/sysv/consts/PR_SET_THP_DISABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_THP_DISABLE 41 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_TIMERSLACK.s b/libc/sysv/consts/PR_SET_TIMERSLACK.s new file mode 100644 index 00000000..3f71ab88 --- /dev/null +++ b/libc/sysv/consts/PR_SET_TIMERSLACK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_TIMERSLACK 29 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_TIMING.s b/libc/sysv/consts/PR_SET_TIMING.s new file mode 100644 index 00000000..ad462d75 --- /dev/null +++ b/libc/sysv/consts/PR_SET_TIMING.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_TIMING 14 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_TSC.s b/libc/sysv/consts/PR_SET_TSC.s new file mode 100644 index 00000000..9aad89c1 --- /dev/null +++ b/libc/sysv/consts/PR_SET_TSC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_TSC 26 0 0 0 0 diff --git a/libc/sysv/consts/PR_SET_UNALIGN.s b/libc/sysv/consts/PR_SET_UNALIGN.s new file mode 100644 index 00000000..59c26224 --- /dev/null +++ b/libc/sysv/consts/PR_SET_UNALIGN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SET_UNALIGN 6 0 0 0 0 diff --git a/libc/sysv/consts/PR_SPEC_DISABLE.s b/libc/sysv/consts/PR_SPEC_DISABLE.s new file mode 100644 index 00000000..49b86dfa --- /dev/null +++ b/libc/sysv/consts/PR_SPEC_DISABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SPEC_DISABLE 4 0 0 0 0 diff --git a/libc/sysv/consts/PR_SPEC_ENABLE.s b/libc/sysv/consts/PR_SPEC_ENABLE.s new file mode 100644 index 00000000..f0716991 --- /dev/null +++ b/libc/sysv/consts/PR_SPEC_ENABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SPEC_ENABLE 2 0 0 0 0 diff --git a/libc/sysv/consts/PR_SPEC_FORCE_DISABLE.s b/libc/sysv/consts/PR_SPEC_FORCE_DISABLE.s new file mode 100644 index 00000000..ced34b81 --- /dev/null +++ b/libc/sysv/consts/PR_SPEC_FORCE_DISABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SPEC_FORCE_DISABLE 8 0 0 0 0 diff --git a/libc/sysv/consts/PR_SPEC_NOT_AFFECTED.s b/libc/sysv/consts/PR_SPEC_NOT_AFFECTED.s new file mode 100644 index 00000000..b4bb35fc --- /dev/null +++ b/libc/sysv/consts/PR_SPEC_NOT_AFFECTED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SPEC_NOT_AFFECTED 0 0 0 0 0 diff --git a/libc/sysv/consts/PR_SPEC_PRCTL.s b/libc/sysv/consts/PR_SPEC_PRCTL.s new file mode 100644 index 00000000..89bbb1ec --- /dev/null +++ b/libc/sysv/consts/PR_SPEC_PRCTL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SPEC_PRCTL 1 0 0 0 0 diff --git a/libc/sysv/consts/PR_SPEC_STORE_BYPASS.s b/libc/sysv/consts/PR_SPEC_STORE_BYPASS.s new file mode 100644 index 00000000..f289b76f --- /dev/null +++ b/libc/sysv/consts/PR_SPEC_STORE_BYPASS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_SPEC_STORE_BYPASS 0 0 0 0 0 diff --git a/libc/sysv/consts/PR_TASK_PERF_EVENTS_DISABLE.s b/libc/sysv/consts/PR_TASK_PERF_EVENTS_DISABLE.s new file mode 100644 index 00000000..4f109ff6 --- /dev/null +++ b/libc/sysv/consts/PR_TASK_PERF_EVENTS_DISABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_TASK_PERF_EVENTS_DISABLE 31 0 0 0 0 diff --git a/libc/sysv/consts/PR_TASK_PERF_EVENTS_ENABLE.s b/libc/sysv/consts/PR_TASK_PERF_EVENTS_ENABLE.s new file mode 100644 index 00000000..54329c7e --- /dev/null +++ b/libc/sysv/consts/PR_TASK_PERF_EVENTS_ENABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_TASK_PERF_EVENTS_ENABLE 0x20 0 0 0 0 diff --git a/libc/sysv/consts/PR_TIMING_STATISTICAL.s b/libc/sysv/consts/PR_TIMING_STATISTICAL.s new file mode 100644 index 00000000..f0c7e5bd --- /dev/null +++ b/libc/sysv/consts/PR_TIMING_STATISTICAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_TIMING_STATISTICAL 0 0 0 0 0 diff --git a/libc/sysv/consts/PR_TIMING_TIMESTAMP.s b/libc/sysv/consts/PR_TIMING_TIMESTAMP.s new file mode 100644 index 00000000..a468444f --- /dev/null +++ b/libc/sysv/consts/PR_TIMING_TIMESTAMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_TIMING_TIMESTAMP 1 0 0 0 0 diff --git a/libc/sysv/consts/PR_TSC_ENABLE.s b/libc/sysv/consts/PR_TSC_ENABLE.s new file mode 100644 index 00000000..a34f1910 --- /dev/null +++ b/libc/sysv/consts/PR_TSC_ENABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_TSC_ENABLE 1 0 0 0 0 diff --git a/libc/sysv/consts/PR_TSC_SIGSEGV.s b/libc/sysv/consts/PR_TSC_SIGSEGV.s new file mode 100644 index 00000000..363f4955 --- /dev/null +++ b/libc/sysv/consts/PR_TSC_SIGSEGV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_TSC_SIGSEGV 2 0 0 0 0 diff --git a/libc/sysv/consts/PR_UNALIGN_NOPRINT.s b/libc/sysv/consts/PR_UNALIGN_NOPRINT.s new file mode 100644 index 00000000..e1a580bc --- /dev/null +++ b/libc/sysv/consts/PR_UNALIGN_NOPRINT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_UNALIGN_NOPRINT 1 0 0 0 0 diff --git a/libc/sysv/consts/PR_UNALIGN_SIGBUS.s b/libc/sysv/consts/PR_UNALIGN_SIGBUS.s new file mode 100644 index 00000000..c1135deb --- /dev/null +++ b/libc/sysv/consts/PR_UNALIGN_SIGBUS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pr PR_UNALIGN_SIGBUS 2 0 0 0 0 diff --git a/libc/sysv/consts/PTHREAD_BARRIER_SERIAL_THREAD.s b/libc/sysv/consts/PTHREAD_BARRIER_SERIAL_THREAD.s new file mode 100644 index 00000000..ad3572bb --- /dev/null +++ b/libc/sysv/consts/PTHREAD_BARRIER_SERIAL_THREAD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_BARRIER_SERIAL_THREAD -1 0 -1 -1 0 diff --git a/libc/sysv/consts/PTHREAD_CANCEL_ASYNCHRONOUS.s b/libc/sysv/consts/PTHREAD_CANCEL_ASYNCHRONOUS.s new file mode 100644 index 00000000..37e6bbba --- /dev/null +++ b/libc/sysv/consts/PTHREAD_CANCEL_ASYNCHRONOUS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_CANCEL_ASYNCHRONOUS 1 0 2 2 0 diff --git a/libc/sysv/consts/PTHREAD_CANCEL_DEFERRED.s b/libc/sysv/consts/PTHREAD_CANCEL_DEFERRED.s new file mode 100644 index 00000000..bfa18321 --- /dev/null +++ b/libc/sysv/consts/PTHREAD_CANCEL_DEFERRED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_CANCEL_DEFERRED 0 2 0 0 0 diff --git a/libc/sysv/consts/PTHREAD_CANCEL_DISABLE.s b/libc/sysv/consts/PTHREAD_CANCEL_DISABLE.s new file mode 100644 index 00000000..7643ce89 --- /dev/null +++ b/libc/sysv/consts/PTHREAD_CANCEL_DISABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_CANCEL_DISABLE 1 0 1 1 0 diff --git a/libc/sysv/consts/PTHREAD_CANCEL_ENABLE.s b/libc/sysv/consts/PTHREAD_CANCEL_ENABLE.s new file mode 100644 index 00000000..fe4f6325 --- /dev/null +++ b/libc/sysv/consts/PTHREAD_CANCEL_ENABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_CANCEL_ENABLE 0 1 0 0 0 diff --git a/libc/sysv/consts/PTHREAD_CREATE_DETACHED.s b/libc/sysv/consts/PTHREAD_CREATE_DETACHED.s new file mode 100644 index 00000000..46f45fec --- /dev/null +++ b/libc/sysv/consts/PTHREAD_CREATE_DETACHED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_CREATE_DETACHED 1 2 1 1 0 diff --git a/libc/sysv/consts/PTHREAD_CREATE_JOINABLE.s b/libc/sysv/consts/PTHREAD_CREATE_JOINABLE.s new file mode 100644 index 00000000..79d48b6b --- /dev/null +++ b/libc/sysv/consts/PTHREAD_CREATE_JOINABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_CREATE_JOINABLE 0 1 0 0 0 diff --git a/libc/sysv/consts/PTHREAD_DESTRUCTOR_ITERATIONS.s b/libc/sysv/consts/PTHREAD_DESTRUCTOR_ITERATIONS.s new file mode 100644 index 00000000..9d626362 --- /dev/null +++ b/libc/sysv/consts/PTHREAD_DESTRUCTOR_ITERATIONS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_DESTRUCTOR_ITERATIONS 4 4 4 4 0 diff --git a/libc/sysv/consts/PTHREAD_EXPLICIT_SCHED.s b/libc/sysv/consts/PTHREAD_EXPLICIT_SCHED.s new file mode 100644 index 00000000..3427a95d --- /dev/null +++ b/libc/sysv/consts/PTHREAD_EXPLICIT_SCHED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_EXPLICIT_SCHED 1 2 0 0 0 diff --git a/libc/sysv/consts/PTHREAD_INHERIT_SCHED.s b/libc/sysv/consts/PTHREAD_INHERIT_SCHED.s new file mode 100644 index 00000000..f798ec4f --- /dev/null +++ b/libc/sysv/consts/PTHREAD_INHERIT_SCHED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_INHERIT_SCHED 0 1 4 4 0 diff --git a/libc/sysv/consts/PTHREAD_KEYS_MAX.s b/libc/sysv/consts/PTHREAD_KEYS_MAX.s new file mode 100644 index 00000000..c8c4d188 --- /dev/null +++ b/libc/sysv/consts/PTHREAD_KEYS_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_KEYS_MAX 0x0400 0x0200 0x0100 0x0100 0 diff --git a/libc/sysv/consts/PTHREAD_MUTEX_DEFAULT.s b/libc/sysv/consts/PTHREAD_MUTEX_DEFAULT.s new file mode 100644 index 00000000..36b9443b --- /dev/null +++ b/libc/sysv/consts/PTHREAD_MUTEX_DEFAULT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_MUTEX_DEFAULT 0 0 1 4 0 diff --git a/libc/sysv/consts/PTHREAD_MUTEX_ERRORCHECK.s b/libc/sysv/consts/PTHREAD_MUTEX_ERRORCHECK.s new file mode 100644 index 00000000..98849ba2 --- /dev/null +++ b/libc/sysv/consts/PTHREAD_MUTEX_ERRORCHECK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_MUTEX_ERRORCHECK 0 1 0 1 0 diff --git a/libc/sysv/consts/PTHREAD_MUTEX_NORMAL.s b/libc/sysv/consts/PTHREAD_MUTEX_NORMAL.s new file mode 100644 index 00000000..beea84b6 --- /dev/null +++ b/libc/sysv/consts/PTHREAD_MUTEX_NORMAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_MUTEX_NORMAL 0 0 0 3 0 diff --git a/libc/sysv/consts/PTHREAD_MUTEX_RECURSIVE.s b/libc/sysv/consts/PTHREAD_MUTEX_RECURSIVE.s new file mode 100644 index 00000000..b8dd8381 --- /dev/null +++ b/libc/sysv/consts/PTHREAD_MUTEX_RECURSIVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_MUTEX_RECURSIVE 0 2 0 2 0 diff --git a/libc/sysv/consts/PTHREAD_MUTEX_ROBUST.s b/libc/sysv/consts/PTHREAD_MUTEX_ROBUST.s new file mode 100644 index 00000000..280c7880 --- /dev/null +++ b/libc/sysv/consts/PTHREAD_MUTEX_ROBUST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_MUTEX_ROBUST 0 0 1 0 0 diff --git a/libc/sysv/consts/PTHREAD_MUTEX_STALLED.s b/libc/sysv/consts/PTHREAD_MUTEX_STALLED.s new file mode 100644 index 00000000..8b3ef128 --- /dev/null +++ b/libc/sysv/consts/PTHREAD_MUTEX_STALLED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_MUTEX_STALLED 0 0 0 0 0 diff --git a/libc/sysv/consts/PTHREAD_PRIO_INHERIT.s b/libc/sysv/consts/PTHREAD_PRIO_INHERIT.s new file mode 100644 index 00000000..6832d50e --- /dev/null +++ b/libc/sysv/consts/PTHREAD_PRIO_INHERIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_PRIO_INHERIT 0 1 1 1 0 diff --git a/libc/sysv/consts/PTHREAD_PRIO_NONE.s b/libc/sysv/consts/PTHREAD_PRIO_NONE.s new file mode 100644 index 00000000..a809c290 --- /dev/null +++ b/libc/sysv/consts/PTHREAD_PRIO_NONE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_PRIO_NONE 0 0 0 0 0 diff --git a/libc/sysv/consts/PTHREAD_PRIO_PROTECT.s b/libc/sysv/consts/PTHREAD_PRIO_PROTECT.s new file mode 100644 index 00000000..0ef1b062 --- /dev/null +++ b/libc/sysv/consts/PTHREAD_PRIO_PROTECT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_PRIO_PROTECT 0 2 2 2 0 diff --git a/libc/sysv/consts/PTHREAD_PROCESS_PRIVATE.s b/libc/sysv/consts/PTHREAD_PROCESS_PRIVATE.s new file mode 100644 index 00000000..37c211e4 --- /dev/null +++ b/libc/sysv/consts/PTHREAD_PROCESS_PRIVATE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_PROCESS_PRIVATE 0 2 0 0 0 diff --git a/libc/sysv/consts/PTHREAD_PROCESS_SHARED.s b/libc/sysv/consts/PTHREAD_PROCESS_SHARED.s new file mode 100644 index 00000000..15696862 --- /dev/null +++ b/libc/sysv/consts/PTHREAD_PROCESS_SHARED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_PROCESS_SHARED 1 1 1 1 0 diff --git a/libc/sysv/consts/PTHREAD_SCOPE_PROCESS.s b/libc/sysv/consts/PTHREAD_SCOPE_PROCESS.s new file mode 100644 index 00000000..6b1c0446 --- /dev/null +++ b/libc/sysv/consts/PTHREAD_SCOPE_PROCESS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_SCOPE_PROCESS 1 2 0 0 0 diff --git a/libc/sysv/consts/PTHREAD_SCOPE_SYSTEM.s b/libc/sysv/consts/PTHREAD_SCOPE_SYSTEM.s new file mode 100644 index 00000000..7dde92da --- /dev/null +++ b/libc/sysv/consts/PTHREAD_SCOPE_SYSTEM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_SCOPE_SYSTEM 0 1 2 2 0 diff --git a/libc/sysv/consts/PTHREAD_STACK_MIN.s b/libc/sysv/consts/PTHREAD_STACK_MIN.s new file mode 100644 index 00000000..3c24944c --- /dev/null +++ b/libc/sysv/consts/PTHREAD_STACK_MIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc PTHREAD_STACK_MIN 0x4000 0x2000 0x0800 0x1000 0 diff --git a/libc/sysv/consts/PTMGET.s b/libc/sysv/consts/PTMGET.s new file mode 100644 index 00000000..6e7c37a5 --- /dev/null +++ b/libc/sysv/consts/PTMGET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pty PTMGET 0 0 0 0x40287401 -1 diff --git a/libc/sysv/consts/PTRACE_GETREGSET.s b/libc/sysv/consts/PTRACE_GETREGSET.s new file mode 100644 index 00000000..2f37ad75 --- /dev/null +++ b/libc/sysv/consts/PTRACE_GETREGSET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ptrace PTRACE_GETREGSET 0x4204 0 0 0 0 diff --git a/libc/sysv/consts/PTRACE_GETSIGMASK.s b/libc/sysv/consts/PTRACE_GETSIGMASK.s new file mode 100644 index 00000000..00ec0497 --- /dev/null +++ b/libc/sysv/consts/PTRACE_GETSIGMASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ptrace PTRACE_GETSIGMASK 0x420a 0 0 0 0 diff --git a/libc/sysv/consts/PTRACE_INTERRUPT.s b/libc/sysv/consts/PTRACE_INTERRUPT.s new file mode 100644 index 00000000..6d8d7d49 --- /dev/null +++ b/libc/sysv/consts/PTRACE_INTERRUPT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ptrace PTRACE_INTERRUPT 0x4207 0 0 0 0 diff --git a/libc/sysv/consts/PTRACE_LISTEN.s b/libc/sysv/consts/PTRACE_LISTEN.s new file mode 100644 index 00000000..83c8fb8f --- /dev/null +++ b/libc/sysv/consts/PTRACE_LISTEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ptrace PTRACE_LISTEN 0x4208 0 0 0 0 diff --git a/libc/sysv/consts/PTRACE_PEEKSIGINFO.s b/libc/sysv/consts/PTRACE_PEEKSIGINFO.s new file mode 100644 index 00000000..028e6b20 --- /dev/null +++ b/libc/sysv/consts/PTRACE_PEEKSIGINFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ptrace PTRACE_PEEKSIGINFO 0x4209 0 0 0 0 diff --git a/libc/sysv/consts/PTRACE_SECCOMP_GET_FILTER.s b/libc/sysv/consts/PTRACE_SECCOMP_GET_FILTER.s new file mode 100644 index 00000000..6c7b8a3c --- /dev/null +++ b/libc/sysv/consts/PTRACE_SECCOMP_GET_FILTER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ptrace PTRACE_SECCOMP_GET_FILTER 0x420c 0 0 0 0 diff --git a/libc/sysv/consts/PTRACE_SEIZE.s b/libc/sysv/consts/PTRACE_SEIZE.s new file mode 100644 index 00000000..9e5510c7 --- /dev/null +++ b/libc/sysv/consts/PTRACE_SEIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ptrace PTRACE_SEIZE 0x4206 0 0 0 0 diff --git a/libc/sysv/consts/PTRACE_SETREGSET.s b/libc/sysv/consts/PTRACE_SETREGSET.s new file mode 100644 index 00000000..ee13c650 --- /dev/null +++ b/libc/sysv/consts/PTRACE_SETREGSET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ptrace PTRACE_SETREGSET 0x4205 0 0 0 0 diff --git a/libc/sysv/consts/PTRACE_SETSIGMASK.s b/libc/sysv/consts/PTRACE_SETSIGMASK.s new file mode 100644 index 00000000..f9e4cb9b --- /dev/null +++ b/libc/sysv/consts/PTRACE_SETSIGMASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ptrace PTRACE_SETSIGMASK 0x420b 0 0 0 0 diff --git a/libc/sysv/consts/PTRACE_SYSCALL.s b/libc/sysv/consts/PTRACE_SYSCALL.s new file mode 100644 index 00000000..731496b5 --- /dev/null +++ b/libc/sysv/consts/PTRACE_SYSCALL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ptrace PTRACE_SYSCALL 0 0 6 0 0 diff --git a/libc/sysv/consts/PT_ATTACH.s b/libc/sysv/consts/PT_ATTACH.s new file mode 100644 index 00000000..88e925b6 --- /dev/null +++ b/libc/sysv/consts/PT_ATTACH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_ATTACH 0x10 10 10 9 0 diff --git a/libc/sysv/consts/PT_CONTINUE.s b/libc/sysv/consts/PT_CONTINUE.s new file mode 100644 index 00000000..3c1e2f1a --- /dev/null +++ b/libc/sysv/consts/PT_CONTINUE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_CONTINUE 7 7 7 7 0 diff --git a/libc/sysv/consts/PT_DETACH.s b/libc/sysv/consts/PT_DETACH.s new file mode 100644 index 00000000..eb53d167 --- /dev/null +++ b/libc/sysv/consts/PT_DETACH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_DETACH 17 11 11 10 0 diff --git a/libc/sysv/consts/PT_GETEVENTMSG.s b/libc/sysv/consts/PT_GETEVENTMSG.s new file mode 100644 index 00000000..09e5afd4 --- /dev/null +++ b/libc/sysv/consts/PT_GETEVENTMSG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_GETEVENTMSG 0x4201 0 0 0 0 diff --git a/libc/sysv/consts/PT_GETFPREGS.s b/libc/sysv/consts/PT_GETFPREGS.s new file mode 100644 index 00000000..50611075 --- /dev/null +++ b/libc/sysv/consts/PT_GETFPREGS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_GETFPREGS 14 0 35 35 0 diff --git a/libc/sysv/consts/PT_GETFPXREGS.s b/libc/sysv/consts/PT_GETFPXREGS.s new file mode 100644 index 00000000..c9be44e9 --- /dev/null +++ b/libc/sysv/consts/PT_GETFPXREGS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_GETFPXREGS 18 0 0 0 0 diff --git a/libc/sysv/consts/PT_GETREGS.s b/libc/sysv/consts/PT_GETREGS.s new file mode 100644 index 00000000..f1631c5a --- /dev/null +++ b/libc/sysv/consts/PT_GETREGS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_GETREGS 12 0 33 33 0 diff --git a/libc/sysv/consts/PT_GETSIGINFO.s b/libc/sysv/consts/PT_GETSIGINFO.s new file mode 100644 index 00000000..0e35a3f4 --- /dev/null +++ b/libc/sysv/consts/PT_GETSIGINFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_GETSIGINFO 0x4202 0 0 0 0 diff --git a/libc/sysv/consts/PT_KILL.s b/libc/sysv/consts/PT_KILL.s new file mode 100644 index 00000000..05a0754c --- /dev/null +++ b/libc/sysv/consts/PT_KILL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_KILL 8 8 8 8 0 diff --git a/libc/sysv/consts/PT_READ_D.s b/libc/sysv/consts/PT_READ_D.s new file mode 100644 index 00000000..721bbbb5 --- /dev/null +++ b/libc/sysv/consts/PT_READ_D.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_READ_D 2 2 2 2 0 diff --git a/libc/sysv/consts/PT_READ_I.s b/libc/sysv/consts/PT_READ_I.s new file mode 100644 index 00000000..df66fb49 --- /dev/null +++ b/libc/sysv/consts/PT_READ_I.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_READ_I 1 1 1 1 0 diff --git a/libc/sysv/consts/PT_READ_U.s b/libc/sysv/consts/PT_READ_U.s new file mode 100644 index 00000000..095b0f52 --- /dev/null +++ b/libc/sysv/consts/PT_READ_U.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_READ_U 3 3 0 0 0 diff --git a/libc/sysv/consts/PT_SETFPREGS.s b/libc/sysv/consts/PT_SETFPREGS.s new file mode 100644 index 00000000..0df23c2e --- /dev/null +++ b/libc/sysv/consts/PT_SETFPREGS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_SETFPREGS 15 0 36 36 0 diff --git a/libc/sysv/consts/PT_SETFPXREGS.s b/libc/sysv/consts/PT_SETFPXREGS.s new file mode 100644 index 00000000..8f4963b2 --- /dev/null +++ b/libc/sysv/consts/PT_SETFPXREGS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_SETFPXREGS 19 0 0 0 0 diff --git a/libc/sysv/consts/PT_SETOPTIONS.s b/libc/sysv/consts/PT_SETOPTIONS.s new file mode 100644 index 00000000..d5ffd24f --- /dev/null +++ b/libc/sysv/consts/PT_SETOPTIONS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_SETOPTIONS 0x4200 0 0 0 0 diff --git a/libc/sysv/consts/PT_SETREGS.s b/libc/sysv/consts/PT_SETREGS.s new file mode 100644 index 00000000..9496a820 --- /dev/null +++ b/libc/sysv/consts/PT_SETREGS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_SETREGS 13 0 34 34 0 diff --git a/libc/sysv/consts/PT_SETSIGINFO.s b/libc/sysv/consts/PT_SETSIGINFO.s new file mode 100644 index 00000000..55918484 --- /dev/null +++ b/libc/sysv/consts/PT_SETSIGINFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_SETSIGINFO 0x4203 0 0 0 0 diff --git a/libc/sysv/consts/PT_STEP.s b/libc/sysv/consts/PT_STEP.s new file mode 100644 index 00000000..0f514018 --- /dev/null +++ b/libc/sysv/consts/PT_STEP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_STEP 9 9 9 0x20 0 diff --git a/libc/sysv/consts/PT_SYSCALL.s b/libc/sysv/consts/PT_SYSCALL.s new file mode 100644 index 00000000..5ad7ca0f --- /dev/null +++ b/libc/sysv/consts/PT_SYSCALL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_SYSCALL 24 0 22 0 0 diff --git a/libc/sysv/consts/PT_TRACE_ME.s b/libc/sysv/consts/PT_TRACE_ME.s new file mode 100644 index 00000000..7ca997c2 --- /dev/null +++ b/libc/sysv/consts/PT_TRACE_ME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_TRACE_ME 0 0 0 0 0 diff --git a/libc/sysv/consts/PT_WRITE_D.s b/libc/sysv/consts/PT_WRITE_D.s new file mode 100644 index 00000000..a6a0ffdc --- /dev/null +++ b/libc/sysv/consts/PT_WRITE_D.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_WRITE_D 5 5 5 5 0 diff --git a/libc/sysv/consts/PT_WRITE_I.s b/libc/sysv/consts/PT_WRITE_I.s new file mode 100644 index 00000000..ff1f1b7b --- /dev/null +++ b/libc/sysv/consts/PT_WRITE_I.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_WRITE_I 4 4 4 4 0 diff --git a/libc/sysv/consts/PT_WRITE_U.s b/libc/sysv/consts/PT_WRITE_U.s new file mode 100644 index 00000000..366253cf --- /dev/null +++ b/libc/sysv/consts/PT_WRITE_U.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pt PT_WRITE_U 6 6 0 0 0 diff --git a/libc/sysv/consts/QUEUE_FULL.s b/libc/sysv/consts/QUEUE_FULL.s new file mode 100644 index 00000000..3612ce94 --- /dev/null +++ b/libc/sysv/consts/QUEUE_FULL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc QUEUE_FULL 20 0 0 0 0 diff --git a/libc/sysv/consts/Q_GETFMT.s b/libc/sysv/consts/Q_GETFMT.s new file mode 100644 index 00000000..ee877475 --- /dev/null +++ b/libc/sysv/consts/Q_GETFMT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc Q_GETFMT 0x800004 0 0 0 0 diff --git a/libc/sysv/consts/Q_GETINFO.s b/libc/sysv/consts/Q_GETINFO.s new file mode 100644 index 00000000..457f2b99 --- /dev/null +++ b/libc/sysv/consts/Q_GETINFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc Q_GETINFO 0x800005 0 0 0 0 diff --git a/libc/sysv/consts/Q_GETQUOTA.s b/libc/sysv/consts/Q_GETQUOTA.s new file mode 100644 index 00000000..f09ed381 --- /dev/null +++ b/libc/sysv/consts/Q_GETQUOTA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc Q_GETQUOTA 0x800007 768 0x0700 768 0 diff --git a/libc/sysv/consts/Q_QUOTAOFF.s b/libc/sysv/consts/Q_QUOTAOFF.s new file mode 100644 index 00000000..6107c893 --- /dev/null +++ b/libc/sysv/consts/Q_QUOTAOFF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc Q_QUOTAOFF 0x800003 0x0200 0x0200 0x0200 0 diff --git a/libc/sysv/consts/Q_QUOTAON.s b/libc/sysv/consts/Q_QUOTAON.s new file mode 100644 index 00000000..7ebe831c --- /dev/null +++ b/libc/sysv/consts/Q_QUOTAON.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc Q_QUOTAON 0x800002 0x0100 0x0100 0x0100 0 diff --git a/libc/sysv/consts/Q_SETINFO.s b/libc/sysv/consts/Q_SETINFO.s new file mode 100644 index 00000000..018615e5 --- /dev/null +++ b/libc/sysv/consts/Q_SETINFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc Q_SETINFO 0x800006 0 0 0 0 diff --git a/libc/sysv/consts/Q_SETQUOTA.s b/libc/sysv/consts/Q_SETQUOTA.s new file mode 100644 index 00000000..868a4126 --- /dev/null +++ b/libc/sysv/consts/Q_SETQUOTA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc Q_SETQUOTA 0x800008 0x0400 0x0800 0x0400 0 diff --git a/libc/sysv/consts/Q_SYNC.s b/libc/sysv/consts/Q_SYNC.s new file mode 100644 index 00000000..8d02c34f --- /dev/null +++ b/libc/sysv/consts/Q_SYNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc Q_SYNC 0x800001 0x0600 0x0600 0x0600 0 diff --git a/libc/sysv/consts/RADIXCHAR.s b/libc/sysv/consts/RADIXCHAR.s new file mode 100644 index 00000000..e03afb0c --- /dev/null +++ b/libc/sysv/consts/RADIXCHAR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RADIXCHAR 0x010000 50 50 44 0 diff --git a/libc/sysv/consts/RB_AUTOBOOT.s b/libc/sysv/consts/RB_AUTOBOOT.s new file mode 100644 index 00000000..bc3cd0c6 --- /dev/null +++ b/libc/sysv/consts/RB_AUTOBOOT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RB_AUTOBOOT 0x01234567 0 0 0 0 diff --git a/libc/sysv/consts/RB_DISABLE_CAD.s b/libc/sysv/consts/RB_DISABLE_CAD.s new file mode 100644 index 00000000..4a38fa9b --- /dev/null +++ b/libc/sysv/consts/RB_DISABLE_CAD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RB_DISABLE_CAD 0 0 0 0 0 diff --git a/libc/sysv/consts/RB_ENABLE_CAD.s b/libc/sysv/consts/RB_ENABLE_CAD.s new file mode 100644 index 00000000..0697f6d4 --- /dev/null +++ b/libc/sysv/consts/RB_ENABLE_CAD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RB_ENABLE_CAD 0x89abcdef 0 0 0 0 diff --git a/libc/sysv/consts/RB_HALT_SYSTEM.s b/libc/sysv/consts/RB_HALT_SYSTEM.s new file mode 100644 index 00000000..38f0dbb5 --- /dev/null +++ b/libc/sysv/consts/RB_HALT_SYSTEM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RB_HALT_SYSTEM 0xcdef0123 0 0 0 0 diff --git a/libc/sysv/consts/RB_KEXEC.s b/libc/sysv/consts/RB_KEXEC.s new file mode 100644 index 00000000..9feae9d4 --- /dev/null +++ b/libc/sysv/consts/RB_KEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RB_KEXEC 0x45584543 0 0 0 0 diff --git a/libc/sysv/consts/RB_POWER_OFF.s b/libc/sysv/consts/RB_POWER_OFF.s new file mode 100644 index 00000000..ffcf1074 --- /dev/null +++ b/libc/sysv/consts/RB_POWER_OFF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RB_POWER_OFF 0x4321fedc 0 0 0 0 diff --git a/libc/sysv/consts/RB_SW_SUSPEND.s b/libc/sysv/consts/RB_SW_SUSPEND.s new file mode 100644 index 00000000..679cb88a --- /dev/null +++ b/libc/sysv/consts/RB_SW_SUSPEND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RB_SW_SUSPEND 0xd000fce2 0 0 0 0 diff --git a/libc/sysv/consts/READ_10.s b/libc/sysv/consts/READ_10.s new file mode 100644 index 00000000..e6aae029 --- /dev/null +++ b/libc/sysv/consts/READ_10.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc READ_10 40 0 0 0 0 diff --git a/libc/sysv/consts/READ_12.s b/libc/sysv/consts/READ_12.s new file mode 100644 index 00000000..03fa39cb --- /dev/null +++ b/libc/sysv/consts/READ_12.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc READ_12 168 0 0 0 0 diff --git a/libc/sysv/consts/READ_6.s b/libc/sysv/consts/READ_6.s new file mode 100644 index 00000000..2d5f7add --- /dev/null +++ b/libc/sysv/consts/READ_6.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc READ_6 8 0 0 0 0 diff --git a/libc/sysv/consts/READ_BLOCK_LIMITS.s b/libc/sysv/consts/READ_BLOCK_LIMITS.s new file mode 100644 index 00000000..b6c5d3b8 --- /dev/null +++ b/libc/sysv/consts/READ_BLOCK_LIMITS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc READ_BLOCK_LIMITS 5 0 0 0 0 diff --git a/libc/sysv/consts/READ_BUFFER.s b/libc/sysv/consts/READ_BUFFER.s new file mode 100644 index 00000000..6ffd7027 --- /dev/null +++ b/libc/sysv/consts/READ_BUFFER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc READ_BUFFER 60 0 0 0 0 diff --git a/libc/sysv/consts/READ_CAPACITY.s b/libc/sysv/consts/READ_CAPACITY.s new file mode 100644 index 00000000..5a8f6745 --- /dev/null +++ b/libc/sysv/consts/READ_CAPACITY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc READ_CAPACITY 37 0 0 0 0 diff --git a/libc/sysv/consts/READ_DEFECT_DATA.s b/libc/sysv/consts/READ_DEFECT_DATA.s new file mode 100644 index 00000000..57bb23a8 --- /dev/null +++ b/libc/sysv/consts/READ_DEFECT_DATA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc READ_DEFECT_DATA 55 0 0 0 0 diff --git a/libc/sysv/consts/READ_ELEMENT_STATUS.s b/libc/sysv/consts/READ_ELEMENT_STATUS.s new file mode 100644 index 00000000..7ac7678e --- /dev/null +++ b/libc/sysv/consts/READ_ELEMENT_STATUS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc READ_ELEMENT_STATUS 184 0 0 0 0 diff --git a/libc/sysv/consts/READ_IMPLIES_EXEC.s b/libc/sysv/consts/READ_IMPLIES_EXEC.s new file mode 100644 index 00000000..665b6037 --- /dev/null +++ b/libc/sysv/consts/READ_IMPLIES_EXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon prsnlty READ_IMPLIES_EXEC 0x0400000 -1 -1 -1 -1 diff --git a/libc/sysv/consts/READ_LONG.s b/libc/sysv/consts/READ_LONG.s new file mode 100644 index 00000000..1f0c5893 --- /dev/null +++ b/libc/sysv/consts/READ_LONG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc READ_LONG 62 0 0 0 0 diff --git a/libc/sysv/consts/READ_POSITION.s b/libc/sysv/consts/READ_POSITION.s new file mode 100644 index 00000000..710cbe5d --- /dev/null +++ b/libc/sysv/consts/READ_POSITION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc READ_POSITION 52 0 0 0 0 diff --git a/libc/sysv/consts/READ_REVERSE.s b/libc/sysv/consts/READ_REVERSE.s new file mode 100644 index 00000000..3bda8796 --- /dev/null +++ b/libc/sysv/consts/READ_REVERSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc READ_REVERSE 15 0 0 0 0 diff --git a/libc/sysv/consts/READ_TOC.s b/libc/sysv/consts/READ_TOC.s new file mode 100644 index 00000000..b7f1a365 --- /dev/null +++ b/libc/sysv/consts/READ_TOC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc READ_TOC 67 0 0 0 0 diff --git a/libc/sysv/consts/REASSIGN_BLOCKS.s b/libc/sysv/consts/REASSIGN_BLOCKS.s new file mode 100644 index 00000000..a7f03a32 --- /dev/null +++ b/libc/sysv/consts/REASSIGN_BLOCKS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc REASSIGN_BLOCKS 7 0 0 0 0 diff --git a/libc/sysv/consts/RECEIVE_DIAGNOSTIC.s b/libc/sysv/consts/RECEIVE_DIAGNOSTIC.s new file mode 100644 index 00000000..e7c3af49 --- /dev/null +++ b/libc/sysv/consts/RECEIVE_DIAGNOSTIC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RECEIVE_DIAGNOSTIC 28 0 0 0 0 diff --git a/libc/sysv/consts/RECOVERED_ERROR.s b/libc/sysv/consts/RECOVERED_ERROR.s new file mode 100644 index 00000000..654bda36 --- /dev/null +++ b/libc/sysv/consts/RECOVERED_ERROR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RECOVERED_ERROR 1 0 0 0 0 diff --git a/libc/sysv/consts/RECOVER_BUFFERED_DATA.s b/libc/sysv/consts/RECOVER_BUFFERED_DATA.s new file mode 100644 index 00000000..aa2e668b --- /dev/null +++ b/libc/sysv/consts/RECOVER_BUFFERED_DATA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RECOVER_BUFFERED_DATA 20 0 0 0 0 diff --git a/libc/sysv/consts/REC_EOF.s b/libc/sysv/consts/REC_EOF.s new file mode 100644 index 00000000..30a30499 --- /dev/null +++ b/libc/sysv/consts/REC_EOF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc REC_EOF 2 2 2 2 0 diff --git a/libc/sysv/consts/REC_EOR.s b/libc/sysv/consts/REC_EOR.s new file mode 100644 index 00000000..08a30138 --- /dev/null +++ b/libc/sysv/consts/REC_EOR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc REC_EOR 1 1 1 1 0 diff --git a/libc/sysv/consts/REC_ESC.s b/libc/sysv/consts/REC_ESC.s new file mode 100644 index 00000000..ec341ba7 --- /dev/null +++ b/libc/sysv/consts/REC_ESC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc REC_ESC -1 -1 -1 -1 0 diff --git a/libc/sysv/consts/REGTYPE.s b/libc/sysv/consts/REGTYPE.s new file mode 100644 index 00000000..d3a241e1 --- /dev/null +++ b/libc/sysv/consts/REGTYPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc REGTYPE 48 48 48 48 0 diff --git a/libc/sysv/consts/RELEASE_RECOVERY.s b/libc/sysv/consts/RELEASE_RECOVERY.s new file mode 100644 index 00000000..cc77283b --- /dev/null +++ b/libc/sysv/consts/RELEASE_RECOVERY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RELEASE_RECOVERY 0x10 0 0 0 0 diff --git a/libc/sysv/consts/REQUEST_SENSE.s b/libc/sysv/consts/REQUEST_SENSE.s new file mode 100644 index 00000000..6e95ee25 --- /dev/null +++ b/libc/sysv/consts/REQUEST_SENSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc REQUEST_SENSE 3 0 0 0 0 diff --git a/libc/sysv/consts/RESERVATION_CONFLICT.s b/libc/sysv/consts/RESERVATION_CONFLICT.s new file mode 100644 index 00000000..a66777b8 --- /dev/null +++ b/libc/sysv/consts/RESERVATION_CONFLICT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RESERVATION_CONFLICT 12 0 0 0 0 diff --git a/libc/sysv/consts/RESERVE.s b/libc/sysv/consts/RESERVE.s new file mode 100644 index 00000000..5c1a9d8e --- /dev/null +++ b/libc/sysv/consts/RESERVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RESERVE 22 0 0 0 0 diff --git a/libc/sysv/consts/RESERVE_10.s b/libc/sysv/consts/RESERVE_10.s new file mode 100644 index 00000000..ecfe6caa --- /dev/null +++ b/libc/sysv/consts/RESERVE_10.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RESERVE_10 86 0 0 0 0 diff --git a/libc/sysv/consts/RESTORE_POINTERS.s b/libc/sysv/consts/RESTORE_POINTERS.s new file mode 100644 index 00000000..e5141215 --- /dev/null +++ b/libc/sysv/consts/RESTORE_POINTERS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RESTORE_POINTERS 3 0 0 0 0 diff --git a/libc/sysv/consts/RES_PRF_CLASS.s b/libc/sysv/consts/RES_PRF_CLASS.s new file mode 100644 index 00000000..23137443 --- /dev/null +++ b/libc/sysv/consts/RES_PRF_CLASS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RES_PRF_CLASS 4 4 4 4 0 diff --git a/libc/sysv/consts/REZERO_UNIT.s b/libc/sysv/consts/REZERO_UNIT.s new file mode 100644 index 00000000..2004a847 --- /dev/null +++ b/libc/sysv/consts/REZERO_UNIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc REZERO_UNIT 1 0 0 0 0 diff --git a/libc/sysv/consts/RE_DUP_MAX.s b/libc/sysv/consts/RE_DUP_MAX.s new file mode 100644 index 00000000..a29a3679 --- /dev/null +++ b/libc/sysv/consts/RE_DUP_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RE_DUP_MAX 0x7fff 255 255 255 0 diff --git a/libc/sysv/consts/RHF_GUARANTEE_START_INIT.s b/libc/sysv/consts/RHF_GUARANTEE_START_INIT.s new file mode 100644 index 00000000..46b1e534 --- /dev/null +++ b/libc/sysv/consts/RHF_GUARANTEE_START_INIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RHF_GUARANTEE_START_INIT 0x80 0 0 0 0 diff --git a/libc/sysv/consts/RHF_NO_LIBRARY_REPLACEMENT.s b/libc/sysv/consts/RHF_NO_LIBRARY_REPLACEMENT.s new file mode 100644 index 00000000..2b3d3f72 --- /dev/null +++ b/libc/sysv/consts/RHF_NO_LIBRARY_REPLACEMENT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RHF_NO_LIBRARY_REPLACEMENT 4 0 0 0 0 diff --git a/libc/sysv/consts/RLIMIT_AS.s b/libc/sysv/consts/RLIMIT_AS.s new file mode 100644 index 00000000..a559be94 --- /dev/null +++ b/libc/sysv/consts/RLIMIT_AS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon rlim RLIMIT_AS 9 5 10 -1 -1 diff --git a/libc/sysv/consts/RLIMIT_CORE.s b/libc/sysv/consts/RLIMIT_CORE.s new file mode 100644 index 00000000..88b7cd5f --- /dev/null +++ b/libc/sysv/consts/RLIMIT_CORE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon rlim RLIMIT_CORE 4 4 4 4 -1 diff --git a/libc/sysv/consts/RLIMIT_CPU.s b/libc/sysv/consts/RLIMIT_CPU.s new file mode 100644 index 00000000..6635bff4 --- /dev/null +++ b/libc/sysv/consts/RLIMIT_CPU.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon rlim RLIMIT_CPU 0 0 0 0 -1 diff --git a/libc/sysv/consts/RLIMIT_DATA.s b/libc/sysv/consts/RLIMIT_DATA.s new file mode 100644 index 00000000..b4e29317 --- /dev/null +++ b/libc/sysv/consts/RLIMIT_DATA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon rlim RLIMIT_DATA 2 2 2 2 -1 diff --git a/libc/sysv/consts/RLIMIT_FSIZE.s b/libc/sysv/consts/RLIMIT_FSIZE.s new file mode 100644 index 00000000..509cbd75 --- /dev/null +++ b/libc/sysv/consts/RLIMIT_FSIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon rlim RLIMIT_FSIZE 1 1 1 1 -1 diff --git a/libc/sysv/consts/RLIMIT_LOCKS.s b/libc/sysv/consts/RLIMIT_LOCKS.s new file mode 100644 index 00000000..c8428434 --- /dev/null +++ b/libc/sysv/consts/RLIMIT_LOCKS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon rlim RLIMIT_LOCKS 10 -1 -1 -1 -1 diff --git a/libc/sysv/consts/RLIMIT_MEMLOCK.s b/libc/sysv/consts/RLIMIT_MEMLOCK.s new file mode 100644 index 00000000..d464e863 --- /dev/null +++ b/libc/sysv/consts/RLIMIT_MEMLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon rlim RLIMIT_MEMLOCK 8 6 6 6 -1 diff --git a/libc/sysv/consts/RLIMIT_MSGQUEUE.s b/libc/sysv/consts/RLIMIT_MSGQUEUE.s new file mode 100644 index 00000000..392be10e --- /dev/null +++ b/libc/sysv/consts/RLIMIT_MSGQUEUE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon rlim RLIMIT_MSGQUEUE 12 -1 -1 -1 -1 diff --git a/libc/sysv/consts/RLIMIT_NICE.s b/libc/sysv/consts/RLIMIT_NICE.s new file mode 100644 index 00000000..b1ee6135 --- /dev/null +++ b/libc/sysv/consts/RLIMIT_NICE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon rlim RLIMIT_NICE 13 -1 -1 -1 -1 diff --git a/libc/sysv/consts/RLIMIT_NLIMITS.s b/libc/sysv/consts/RLIMIT_NLIMITS.s new file mode 100644 index 00000000..a1b78f2d --- /dev/null +++ b/libc/sysv/consts/RLIMIT_NLIMITS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon rlim RLIMIT_NLIMITS 16 -1 -1 -1 -1 diff --git a/libc/sysv/consts/RLIMIT_NOFILE.s b/libc/sysv/consts/RLIMIT_NOFILE.s new file mode 100644 index 00000000..30c03455 --- /dev/null +++ b/libc/sysv/consts/RLIMIT_NOFILE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon rlim RLIMIT_NOFILE 7 8 8 8 -1 diff --git a/libc/sysv/consts/RLIMIT_NPROC.s b/libc/sysv/consts/RLIMIT_NPROC.s new file mode 100644 index 00000000..3313c228 --- /dev/null +++ b/libc/sysv/consts/RLIMIT_NPROC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon rlim RLIMIT_NPROC 6 7 7 7 -1 diff --git a/libc/sysv/consts/RLIMIT_RSS.s b/libc/sysv/consts/RLIMIT_RSS.s new file mode 100644 index 00000000..2bc0d92c --- /dev/null +++ b/libc/sysv/consts/RLIMIT_RSS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon rlim RLIMIT_RSS 5 5 5 5 -1 diff --git a/libc/sysv/consts/RLIMIT_RTPRIO.s b/libc/sysv/consts/RLIMIT_RTPRIO.s new file mode 100644 index 00000000..4dec9e6b --- /dev/null +++ b/libc/sysv/consts/RLIMIT_RTPRIO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon rlim RLIMIT_RTPRIO 14 -1 -1 -1 -1 diff --git a/libc/sysv/consts/RLIMIT_SIGPENDING.s b/libc/sysv/consts/RLIMIT_SIGPENDING.s new file mode 100644 index 00000000..c869191f --- /dev/null +++ b/libc/sysv/consts/RLIMIT_SIGPENDING.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon rlim RLIMIT_SIGPENDING 11 -1 -1 -1 -1 diff --git a/libc/sysv/consts/RLIMIT_STACK.s b/libc/sysv/consts/RLIMIT_STACK.s new file mode 100644 index 00000000..33eb1750 --- /dev/null +++ b/libc/sysv/consts/RLIMIT_STACK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon rlim RLIMIT_STACK 3 3 3 3 -1 diff --git a/libc/sysv/consts/RLIM_INFINITY.s b/libc/sysv/consts/RLIM_INFINITY.s new file mode 100644 index 00000000..16dbbf9a --- /dev/null +++ b/libc/sysv/consts/RLIM_INFINITY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RLIM_INFINITY -1 0 0x7fffffffffffffff 0 0 diff --git a/libc/sysv/consts/RLIM_NLIMITS.s b/libc/sysv/consts/RLIM_NLIMITS.s new file mode 100644 index 00000000..b4ccd8ab --- /dev/null +++ b/libc/sysv/consts/RLIM_NLIMITS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RLIM_NLIMITS 0x10 9 15 9 0 diff --git a/libc/sysv/consts/RLIM_SAVED_CUR.s b/libc/sysv/consts/RLIM_SAVED_CUR.s new file mode 100644 index 00000000..567d7d99 --- /dev/null +++ b/libc/sysv/consts/RLIM_SAVED_CUR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RLIM_SAVED_CUR -1 0 0x7fffffffffffffff 0 0 diff --git a/libc/sysv/consts/RLIM_SAVED_MAX.s b/libc/sysv/consts/RLIM_SAVED_MAX.s new file mode 100644 index 00000000..12ae5e32 --- /dev/null +++ b/libc/sysv/consts/RLIM_SAVED_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RLIM_SAVED_MAX -1 0 0x7fffffffffffffff 0 0 diff --git a/libc/sysv/consts/RPM_PCO_ADD.s b/libc/sysv/consts/RPM_PCO_ADD.s new file mode 100644 index 00000000..c6036029 --- /dev/null +++ b/libc/sysv/consts/RPM_PCO_ADD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RPM_PCO_ADD 1 1 1 1 0 diff --git a/libc/sysv/consts/RPM_PCO_CHANGE.s b/libc/sysv/consts/RPM_PCO_CHANGE.s new file mode 100644 index 00000000..3f40740e --- /dev/null +++ b/libc/sysv/consts/RPM_PCO_CHANGE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RPM_PCO_CHANGE 2 2 2 2 0 diff --git a/libc/sysv/consts/RPM_PCO_SETGLOBAL.s b/libc/sysv/consts/RPM_PCO_SETGLOBAL.s new file mode 100644 index 00000000..485bd1ae --- /dev/null +++ b/libc/sysv/consts/RPM_PCO_SETGLOBAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RPM_PCO_SETGLOBAL 3 3 3 3 0 diff --git a/libc/sysv/consts/RRQ.s b/libc/sysv/consts/RRQ.s new file mode 100644 index 00000000..a5468b01 --- /dev/null +++ b/libc/sysv/consts/RRQ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RRQ 1 1 1 1 0 diff --git a/libc/sysv/consts/RTCF_DOREDIRECT.s b/libc/sysv/consts/RTCF_DOREDIRECT.s new file mode 100644 index 00000000..d812b81d --- /dev/null +++ b/libc/sysv/consts/RTCF_DOREDIRECT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RTCF_DOREDIRECT 0x01000000 0 0 0 0 diff --git a/libc/sysv/consts/RTF_NOFORWARD.s b/libc/sysv/consts/RTF_NOFORWARD.s new file mode 100644 index 00000000..2768d667 --- /dev/null +++ b/libc/sysv/consts/RTF_NOFORWARD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RTF_NOFORWARD 0x1000 0 0 0 0 diff --git a/libc/sysv/consts/RTF_NOPMTUDISC.s b/libc/sysv/consts/RTF_NOPMTUDISC.s new file mode 100644 index 00000000..1224dbe4 --- /dev/null +++ b/libc/sysv/consts/RTF_NOPMTUDISC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RTF_NOPMTUDISC 0x4000 0 0 0 0 diff --git a/libc/sysv/consts/RTLD_DI_LINKMAP.s b/libc/sysv/consts/RTLD_DI_LINKMAP.s new file mode 100644 index 00000000..7a105724 --- /dev/null +++ b/libc/sysv/consts/RTLD_DI_LINKMAP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RTLD_DI_LINKMAP 0 0 2 0 0 diff --git a/libc/sysv/consts/RTLD_GLOBAL.s b/libc/sysv/consts/RTLD_GLOBAL.s new file mode 100644 index 00000000..1051e738 --- /dev/null +++ b/libc/sysv/consts/RTLD_GLOBAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RTLD_GLOBAL 0x0100 8 0x0100 0x0100 0 diff --git a/libc/sysv/consts/RTLD_LAZY.s b/libc/sysv/consts/RTLD_LAZY.s new file mode 100644 index 00000000..e98c5edd --- /dev/null +++ b/libc/sysv/consts/RTLD_LAZY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RTLD_LAZY 1 1 1 1 0 diff --git a/libc/sysv/consts/RTLD_LOCAL.s b/libc/sysv/consts/RTLD_LOCAL.s new file mode 100644 index 00000000..459d02f9 --- /dev/null +++ b/libc/sysv/consts/RTLD_LOCAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RTLD_LOCAL 0 4 0 0 0 diff --git a/libc/sysv/consts/RTLD_NODELETE.s b/libc/sysv/consts/RTLD_NODELETE.s new file mode 100644 index 00000000..bc55f91f --- /dev/null +++ b/libc/sysv/consts/RTLD_NODELETE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RTLD_NODELETE 0x1000 0x80 0x1000 0 0 diff --git a/libc/sysv/consts/RTLD_NOLOAD.s b/libc/sysv/consts/RTLD_NOLOAD.s new file mode 100644 index 00000000..1304d822 --- /dev/null +++ b/libc/sysv/consts/RTLD_NOLOAD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RTLD_NOLOAD 4 0x10 0x2000 0 0 diff --git a/libc/sysv/consts/RTLD_NOW.s b/libc/sysv/consts/RTLD_NOW.s new file mode 100644 index 00000000..e61c9547 --- /dev/null +++ b/libc/sysv/consts/RTLD_NOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RTLD_NOW 2 2 2 2 0 diff --git a/libc/sysv/consts/RUN_LVL.s b/libc/sysv/consts/RUN_LVL.s new file mode 100644 index 00000000..cd44fca7 --- /dev/null +++ b/libc/sysv/consts/RUN_LVL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RUN_LVL 1 1 0 0 0 diff --git a/libc/sysv/consts/RUSAGE_CHILDREN.s b/libc/sysv/consts/RUSAGE_CHILDREN.s new file mode 100644 index 00000000..d497cad0 --- /dev/null +++ b/libc/sysv/consts/RUSAGE_CHILDREN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RUSAGE_CHILDREN -1 -1 -1 -1 99 diff --git a/libc/sysv/consts/RUSAGE_SELF.s b/libc/sysv/consts/RUSAGE_SELF.s new file mode 100644 index 00000000..36a353cb --- /dev/null +++ b/libc/sysv/consts/RUSAGE_SELF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RUSAGE_SELF 0 0 0 0 0 diff --git a/libc/sysv/consts/RUSAGE_THREAD.s b/libc/sysv/consts/RUSAGE_THREAD.s new file mode 100644 index 00000000..248fa9d0 --- /dev/null +++ b/libc/sysv/consts/RUSAGE_THREAD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc RUSAGE_THREAD 1 99 1 1 1 diff --git a/libc/sysv/consts/R_OK.s b/libc/sysv/consts/R_OK.s new file mode 100644 index 00000000..2353a9cf --- /dev/null +++ b/libc/sysv/consts/R_OK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon access R_OK 4 4 4 4 0x80000000 diff --git a/libc/sysv/consts/SARMAG.s b/libc/sysv/consts/SARMAG.s new file mode 100644 index 00000000..b3cae7a1 --- /dev/null +++ b/libc/sysv/consts/SARMAG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SARMAG 8 8 8 8 0 diff --git a/libc/sysv/consts/SAVE_POINTERS.s b/libc/sysv/consts/SAVE_POINTERS.s new file mode 100644 index 00000000..ea0d10fd --- /dev/null +++ b/libc/sysv/consts/SAVE_POINTERS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SAVE_POINTERS 2 0 0 0 0 diff --git a/libc/sysv/consts/SA_NOCLDSTOP.s b/libc/sysv/consts/SA_NOCLDSTOP.s new file mode 100644 index 00000000..ed4733d6 --- /dev/null +++ b/libc/sysv/consts/SA_NOCLDSTOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sigact SA_NOCLDSTOP 1 8 8 8 0 diff --git a/libc/sysv/consts/SA_NOCLDWAIT.s b/libc/sysv/consts/SA_NOCLDWAIT.s new file mode 100644 index 00000000..90910f7a --- /dev/null +++ b/libc/sysv/consts/SA_NOCLDWAIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sigact SA_NOCLDWAIT 2 0x20 0x20 0x20 0 diff --git a/libc/sysv/consts/SA_NODEFER.s b/libc/sysv/consts/SA_NODEFER.s new file mode 100644 index 00000000..3522c99f --- /dev/null +++ b/libc/sysv/consts/SA_NODEFER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sigact SA_NODEFER 0x40000000 0x10 0x10 0x10 0 diff --git a/libc/sysv/consts/SA_NOMASK.s b/libc/sysv/consts/SA_NOMASK.s new file mode 100644 index 00000000..3beb654d --- /dev/null +++ b/libc/sysv/consts/SA_NOMASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sigact SA_NOMASK 0x40000000 0x10 0x10 0x10 0 diff --git a/libc/sysv/consts/SA_ONESHOT.s b/libc/sysv/consts/SA_ONESHOT.s new file mode 100644 index 00000000..152d612f --- /dev/null +++ b/libc/sysv/consts/SA_ONESHOT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sigact SA_ONESHOT 0x80000000 0 0 0 0 diff --git a/libc/sysv/consts/SA_ONSTACK.s b/libc/sysv/consts/SA_ONSTACK.s new file mode 100644 index 00000000..fbfefb27 --- /dev/null +++ b/libc/sysv/consts/SA_ONSTACK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sigact SA_ONSTACK 0x08000000 1 1 1 0 diff --git a/libc/sysv/consts/SA_RESETHAND.s b/libc/sysv/consts/SA_RESETHAND.s new file mode 100644 index 00000000..e4a67f55 --- /dev/null +++ b/libc/sysv/consts/SA_RESETHAND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sigact SA_RESETHAND 0x80000000 4 4 4 0 diff --git a/libc/sysv/consts/SA_RESTART.s b/libc/sysv/consts/SA_RESTART.s new file mode 100644 index 00000000..c0174b17 --- /dev/null +++ b/libc/sysv/consts/SA_RESTART.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sigact SA_RESTART 0x10000000 2 2 2 0 diff --git a/libc/sysv/consts/SA_RESTORER.s b/libc/sysv/consts/SA_RESTORER.s new file mode 100644 index 00000000..196cb7b3 --- /dev/null +++ b/libc/sysv/consts/SA_RESTORER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sigact SA_RESTORER 0x04000000 0 0 0 0 diff --git a/libc/sysv/consts/SA_SIGINFO.s b/libc/sysv/consts/SA_SIGINFO.s new file mode 100644 index 00000000..1518b6ab --- /dev/null +++ b/libc/sysv/consts/SA_SIGINFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sigact SA_SIGINFO 4 0x40 0x40 0x40 0 diff --git a/libc/sysv/consts/SCHED_BATCH.s b/libc/sysv/consts/SCHED_BATCH.s new file mode 100644 index 00000000..04c881fb --- /dev/null +++ b/libc/sysv/consts/SCHED_BATCH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCHED_BATCH 3 0 0 0 0 diff --git a/libc/sysv/consts/SCHED_FIFO.s b/libc/sysv/consts/SCHED_FIFO.s new file mode 100644 index 00000000..d5482c91 --- /dev/null +++ b/libc/sysv/consts/SCHED_FIFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCHED_FIFO 1 4 1 1 0 diff --git a/libc/sysv/consts/SCHED_IDLE.s b/libc/sysv/consts/SCHED_IDLE.s new file mode 100644 index 00000000..838d16cb --- /dev/null +++ b/libc/sysv/consts/SCHED_IDLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCHED_IDLE 5 0 0 0 0 diff --git a/libc/sysv/consts/SCHED_OTHER.s b/libc/sysv/consts/SCHED_OTHER.s new file mode 100644 index 00000000..85a27da9 --- /dev/null +++ b/libc/sysv/consts/SCHED_OTHER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCHED_OTHER 0 1 2 2 0 diff --git a/libc/sysv/consts/SCHED_RESET_ON_FORK.s b/libc/sysv/consts/SCHED_RESET_ON_FORK.s new file mode 100644 index 00000000..5f3c678d --- /dev/null +++ b/libc/sysv/consts/SCHED_RESET_ON_FORK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCHED_RESET_ON_FORK 0x40000000 0 0 0 0 diff --git a/libc/sysv/consts/SCHED_RR.s b/libc/sysv/consts/SCHED_RR.s new file mode 100644 index 00000000..fbbb0a84 --- /dev/null +++ b/libc/sysv/consts/SCHED_RR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCHED_RR 2 2 3 3 0 diff --git a/libc/sysv/consts/SCM_CREDENTIALS.s b/libc/sysv/consts/SCM_CREDENTIALS.s new file mode 100644 index 00000000..212b253a --- /dev/null +++ b/libc/sysv/consts/SCM_CREDENTIALS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCM_CREDENTIALS 2 0 0 0 0 diff --git a/libc/sysv/consts/SCM_RIGHTS.s b/libc/sysv/consts/SCM_RIGHTS.s new file mode 100644 index 00000000..db6e8bd9 --- /dev/null +++ b/libc/sysv/consts/SCM_RIGHTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCM_RIGHTS 1 1 1 1 0 diff --git a/libc/sysv/consts/SCM_TIMESTAMP.s b/libc/sysv/consts/SCM_TIMESTAMP.s new file mode 100644 index 00000000..e63f7844 --- /dev/null +++ b/libc/sysv/consts/SCM_TIMESTAMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCM_TIMESTAMP 29 2 2 4 0 diff --git a/libc/sysv/consts/SCM_TIMESTAMPING.s b/libc/sysv/consts/SCM_TIMESTAMPING.s new file mode 100644 index 00000000..18a1b492 --- /dev/null +++ b/libc/sysv/consts/SCM_TIMESTAMPING.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCM_TIMESTAMPING 37 0 0 0 0 diff --git a/libc/sysv/consts/SCM_TIMESTAMPNS.s b/libc/sysv/consts/SCM_TIMESTAMPNS.s new file mode 100644 index 00000000..3481ef45 --- /dev/null +++ b/libc/sysv/consts/SCM_TIMESTAMPNS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCM_TIMESTAMPNS 35 0 0 0 0 diff --git a/libc/sysv/consts/SCM_WIFI_STATUS.s b/libc/sysv/consts/SCM_WIFI_STATUS.s new file mode 100644 index 00000000..1c0c2487 --- /dev/null +++ b/libc/sysv/consts/SCM_WIFI_STATUS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCM_WIFI_STATUS 41 0 0 0 0 diff --git a/libc/sysv/consts/SCSI_IOCTL_BENCHMARK_COMMAND.s b/libc/sysv/consts/SCSI_IOCTL_BENCHMARK_COMMAND.s new file mode 100644 index 00000000..a83fc717 --- /dev/null +++ b/libc/sysv/consts/SCSI_IOCTL_BENCHMARK_COMMAND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCSI_IOCTL_BENCHMARK_COMMAND 3 0 0 0 0 diff --git a/libc/sysv/consts/SCSI_IOCTL_DOORLOCK.s b/libc/sysv/consts/SCSI_IOCTL_DOORLOCK.s new file mode 100644 index 00000000..87b6c794 --- /dev/null +++ b/libc/sysv/consts/SCSI_IOCTL_DOORLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCSI_IOCTL_DOORLOCK 0x5380 0 0 0 0 diff --git a/libc/sysv/consts/SCSI_IOCTL_DOORUNLOCK.s b/libc/sysv/consts/SCSI_IOCTL_DOORUNLOCK.s new file mode 100644 index 00000000..f35d0118 --- /dev/null +++ b/libc/sysv/consts/SCSI_IOCTL_DOORUNLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCSI_IOCTL_DOORUNLOCK 0x5381 0 0 0 0 diff --git a/libc/sysv/consts/SCSI_IOCTL_GET_BUS_NUMBER.s b/libc/sysv/consts/SCSI_IOCTL_GET_BUS_NUMBER.s new file mode 100644 index 00000000..588c3a30 --- /dev/null +++ b/libc/sysv/consts/SCSI_IOCTL_GET_BUS_NUMBER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCSI_IOCTL_GET_BUS_NUMBER 0x5386 0 0 0 0 diff --git a/libc/sysv/consts/SCSI_IOCTL_GET_IDLUN.s b/libc/sysv/consts/SCSI_IOCTL_GET_IDLUN.s new file mode 100644 index 00000000..059462b1 --- /dev/null +++ b/libc/sysv/consts/SCSI_IOCTL_GET_IDLUN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCSI_IOCTL_GET_IDLUN 0x5382 0 0 0 0 diff --git a/libc/sysv/consts/SCSI_IOCTL_PROBE_HOST.s b/libc/sysv/consts/SCSI_IOCTL_PROBE_HOST.s new file mode 100644 index 00000000..8aada19e --- /dev/null +++ b/libc/sysv/consts/SCSI_IOCTL_PROBE_HOST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCSI_IOCTL_PROBE_HOST 0x5385 0 0 0 0 diff --git a/libc/sysv/consts/SCSI_IOCTL_SEND_COMMAND.s b/libc/sysv/consts/SCSI_IOCTL_SEND_COMMAND.s new file mode 100644 index 00000000..e022a5e2 --- /dev/null +++ b/libc/sysv/consts/SCSI_IOCTL_SEND_COMMAND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCSI_IOCTL_SEND_COMMAND 1 0 0 0 0 diff --git a/libc/sysv/consts/SCSI_IOCTL_START_UNIT.s b/libc/sysv/consts/SCSI_IOCTL_START_UNIT.s new file mode 100644 index 00000000..6c3b424f --- /dev/null +++ b/libc/sysv/consts/SCSI_IOCTL_START_UNIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCSI_IOCTL_START_UNIT 5 0 0 0 0 diff --git a/libc/sysv/consts/SCSI_IOCTL_STOP_UNIT.s b/libc/sysv/consts/SCSI_IOCTL_STOP_UNIT.s new file mode 100644 index 00000000..a64ebaa7 --- /dev/null +++ b/libc/sysv/consts/SCSI_IOCTL_STOP_UNIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCSI_IOCTL_STOP_UNIT 6 0 0 0 0 diff --git a/libc/sysv/consts/SCSI_IOCTL_SYNC.s b/libc/sysv/consts/SCSI_IOCTL_SYNC.s new file mode 100644 index 00000000..24858c7d --- /dev/null +++ b/libc/sysv/consts/SCSI_IOCTL_SYNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCSI_IOCTL_SYNC 4 0 0 0 0 diff --git a/libc/sysv/consts/SCSI_IOCTL_TAGGED_DISABLE.s b/libc/sysv/consts/SCSI_IOCTL_TAGGED_DISABLE.s new file mode 100644 index 00000000..4fe15586 --- /dev/null +++ b/libc/sysv/consts/SCSI_IOCTL_TAGGED_DISABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCSI_IOCTL_TAGGED_DISABLE 0x5384 0 0 0 0 diff --git a/libc/sysv/consts/SCSI_IOCTL_TAGGED_ENABLE.s b/libc/sysv/consts/SCSI_IOCTL_TAGGED_ENABLE.s new file mode 100644 index 00000000..1ee525b1 --- /dev/null +++ b/libc/sysv/consts/SCSI_IOCTL_TAGGED_ENABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCSI_IOCTL_TAGGED_ENABLE 0x5383 0 0 0 0 diff --git a/libc/sysv/consts/SCSI_IOCTL_TEST_UNIT_READY.s b/libc/sysv/consts/SCSI_IOCTL_TEST_UNIT_READY.s new file mode 100644 index 00000000..dfd80a04 --- /dev/null +++ b/libc/sysv/consts/SCSI_IOCTL_TEST_UNIT_READY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SCSI_IOCTL_TEST_UNIT_READY 2 0 0 0 0 diff --git a/libc/sysv/consts/SEARCH_EQUAL.s b/libc/sysv/consts/SEARCH_EQUAL.s new file mode 100644 index 00000000..27ee0521 --- /dev/null +++ b/libc/sysv/consts/SEARCH_EQUAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SEARCH_EQUAL 49 0 0 0 0 diff --git a/libc/sysv/consts/SEARCH_EQUAL_12.s b/libc/sysv/consts/SEARCH_EQUAL_12.s new file mode 100644 index 00000000..ac455b30 --- /dev/null +++ b/libc/sysv/consts/SEARCH_EQUAL_12.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SEARCH_EQUAL_12 177 0 0 0 0 diff --git a/libc/sysv/consts/SEARCH_HIGH.s b/libc/sysv/consts/SEARCH_HIGH.s new file mode 100644 index 00000000..0381f76c --- /dev/null +++ b/libc/sysv/consts/SEARCH_HIGH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SEARCH_HIGH 48 0 0 0 0 diff --git a/libc/sysv/consts/SEARCH_HIGH_12.s b/libc/sysv/consts/SEARCH_HIGH_12.s new file mode 100644 index 00000000..f9327f66 --- /dev/null +++ b/libc/sysv/consts/SEARCH_HIGH_12.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SEARCH_HIGH_12 176 0 0 0 0 diff --git a/libc/sysv/consts/SEARCH_LOW.s b/libc/sysv/consts/SEARCH_LOW.s new file mode 100644 index 00000000..ec9aa162 --- /dev/null +++ b/libc/sysv/consts/SEARCH_LOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SEARCH_LOW 50 0 0 0 0 diff --git a/libc/sysv/consts/SEARCH_LOW_12.s b/libc/sysv/consts/SEARCH_LOW_12.s new file mode 100644 index 00000000..94424c7b --- /dev/null +++ b/libc/sysv/consts/SEARCH_LOW_12.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SEARCH_LOW_12 178 0 0 0 0 diff --git a/libc/sysv/consts/SEGSIZE.s b/libc/sysv/consts/SEGSIZE.s new file mode 100644 index 00000000..c8bebdc8 --- /dev/null +++ b/libc/sysv/consts/SEGSIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SEGSIZE 0x0200 0x0200 0x0200 0x0200 0 diff --git a/libc/sysv/consts/SEGV_ACCERR.s b/libc/sysv/consts/SEGV_ACCERR.s new file mode 100644 index 00000000..27171660 --- /dev/null +++ b/libc/sysv/consts/SEGV_ACCERR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SEGV_ACCERR 2 2 2 2 0 diff --git a/libc/sysv/consts/SEGV_MAPERR.s b/libc/sysv/consts/SEGV_MAPERR.s new file mode 100644 index 00000000..906326d8 --- /dev/null +++ b/libc/sysv/consts/SEGV_MAPERR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SEGV_MAPERR 1 1 1 1 0 diff --git a/libc/sysv/consts/SEM_INFO.s b/libc/sysv/consts/SEM_INFO.s new file mode 100644 index 00000000..2c273007 --- /dev/null +++ b/libc/sysv/consts/SEM_INFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SEM_INFO 19 0 11 0 0 diff --git a/libc/sysv/consts/SEM_STAT.s b/libc/sysv/consts/SEM_STAT.s new file mode 100644 index 00000000..aa3aeb06 --- /dev/null +++ b/libc/sysv/consts/SEM_STAT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SEM_STAT 18 0 10 0 0 diff --git a/libc/sysv/consts/SEM_VALUE_MAX.s b/libc/sysv/consts/SEM_VALUE_MAX.s new file mode 100644 index 00000000..eb761571 --- /dev/null +++ b/libc/sysv/consts/SEM_VALUE_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SEM_VALUE_MAX 0x7fffffff 0x7fff 0x7fffffff 0xffffffff 0 diff --git a/libc/sysv/consts/SEND_DIAGNOSTIC.s b/libc/sysv/consts/SEND_DIAGNOSTIC.s new file mode 100644 index 00000000..a41711e9 --- /dev/null +++ b/libc/sysv/consts/SEND_DIAGNOSTIC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SEND_DIAGNOSTIC 29 0 0 0 0 diff --git a/libc/sysv/consts/SEND_VOLUME_TAG.s b/libc/sysv/consts/SEND_VOLUME_TAG.s new file mode 100644 index 00000000..f3d767ee --- /dev/null +++ b/libc/sysv/consts/SEND_VOLUME_TAG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SEND_VOLUME_TAG 182 0 0 0 0 diff --git a/libc/sysv/consts/SET_LIMITS.s b/libc/sysv/consts/SET_LIMITS.s new file mode 100644 index 00000000..f0fefc1c --- /dev/null +++ b/libc/sysv/consts/SET_LIMITS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SET_LIMITS 51 0 0 0 0 diff --git a/libc/sysv/consts/SET_WINDOW.s b/libc/sysv/consts/SET_WINDOW.s new file mode 100644 index 00000000..4be13b1c --- /dev/null +++ b/libc/sysv/consts/SET_WINDOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SET_WINDOW 36 0 0 0 0 diff --git a/libc/sysv/consts/SFD_CLOEXEC.s b/libc/sysv/consts/SFD_CLOEXEC.s new file mode 100644 index 00000000..880bd703 --- /dev/null +++ b/libc/sysv/consts/SFD_CLOEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SFD_CLOEXEC 0x080000 0 0 0 0 diff --git a/libc/sysv/consts/SFD_NONBLOCK.s b/libc/sysv/consts/SFD_NONBLOCK.s new file mode 100644 index 00000000..c7067021 --- /dev/null +++ b/libc/sysv/consts/SFD_NONBLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SFD_NONBLOCK 0x0800 0 0 0 0 diff --git a/libc/sysv/consts/SG_BIG_BUFF.s b/libc/sysv/consts/SG_BIG_BUFF.s new file mode 100644 index 00000000..a7729f50 --- /dev/null +++ b/libc/sysv/consts/SG_BIG_BUFF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_BIG_BUFF 0x8000 0 0 0 0 diff --git a/libc/sysv/consts/SG_DEFAULT_RETRIES.s b/libc/sysv/consts/SG_DEFAULT_RETRIES.s new file mode 100644 index 00000000..61bf0907 --- /dev/null +++ b/libc/sysv/consts/SG_DEFAULT_RETRIES.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_DEFAULT_RETRIES 1 0 0 0 0 diff --git a/libc/sysv/consts/SG_DEFAULT_TIMEOUT.s b/libc/sysv/consts/SG_DEFAULT_TIMEOUT.s new file mode 100644 index 00000000..4590501d --- /dev/null +++ b/libc/sysv/consts/SG_DEFAULT_TIMEOUT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_DEFAULT_TIMEOUT 0x1770 0 0 0 0 diff --git a/libc/sysv/consts/SG_DEF_COMMAND_Q.s b/libc/sysv/consts/SG_DEF_COMMAND_Q.s new file mode 100644 index 00000000..01d34dca --- /dev/null +++ b/libc/sysv/consts/SG_DEF_COMMAND_Q.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_DEF_COMMAND_Q 0 0 0 0 0 diff --git a/libc/sysv/consts/SG_DEF_FORCE_LOW_DMA.s b/libc/sysv/consts/SG_DEF_FORCE_LOW_DMA.s new file mode 100644 index 00000000..eea64990 --- /dev/null +++ b/libc/sysv/consts/SG_DEF_FORCE_LOW_DMA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_DEF_FORCE_LOW_DMA 0 0 0 0 0 diff --git a/libc/sysv/consts/SG_DEF_FORCE_PACK_ID.s b/libc/sysv/consts/SG_DEF_FORCE_PACK_ID.s new file mode 100644 index 00000000..740c162a --- /dev/null +++ b/libc/sysv/consts/SG_DEF_FORCE_PACK_ID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_DEF_FORCE_PACK_ID 0 0 0 0 0 diff --git a/libc/sysv/consts/SG_DEF_KEEP_ORPHAN.s b/libc/sysv/consts/SG_DEF_KEEP_ORPHAN.s new file mode 100644 index 00000000..8c965ca2 --- /dev/null +++ b/libc/sysv/consts/SG_DEF_KEEP_ORPHAN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_DEF_KEEP_ORPHAN 0 0 0 0 0 diff --git a/libc/sysv/consts/SG_DEF_RESERVED_SIZE.s b/libc/sysv/consts/SG_DEF_RESERVED_SIZE.s new file mode 100644 index 00000000..5cd90d6f --- /dev/null +++ b/libc/sysv/consts/SG_DEF_RESERVED_SIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_DEF_RESERVED_SIZE 0x8000 0 0 0 0 diff --git a/libc/sysv/consts/SG_DEF_UNDERRUN_FLAG.s b/libc/sysv/consts/SG_DEF_UNDERRUN_FLAG.s new file mode 100644 index 00000000..ae512de3 --- /dev/null +++ b/libc/sysv/consts/SG_DEF_UNDERRUN_FLAG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_DEF_UNDERRUN_FLAG 0 0 0 0 0 diff --git a/libc/sysv/consts/SG_DXFER_FROM_DEV.s b/libc/sysv/consts/SG_DXFER_FROM_DEV.s new file mode 100644 index 00000000..67851bb7 --- /dev/null +++ b/libc/sysv/consts/SG_DXFER_FROM_DEV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_DXFER_FROM_DEV -3 0 0 0 0 diff --git a/libc/sysv/consts/SG_DXFER_NONE.s b/libc/sysv/consts/SG_DXFER_NONE.s new file mode 100644 index 00000000..c0977a1c --- /dev/null +++ b/libc/sysv/consts/SG_DXFER_NONE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_DXFER_NONE -1 0 0 0 0 diff --git a/libc/sysv/consts/SG_DXFER_TO_DEV.s b/libc/sysv/consts/SG_DXFER_TO_DEV.s new file mode 100644 index 00000000..55e13d2e --- /dev/null +++ b/libc/sysv/consts/SG_DXFER_TO_DEV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_DXFER_TO_DEV -2 0 0 0 0 diff --git a/libc/sysv/consts/SG_DXFER_TO_FROM_DEV.s b/libc/sysv/consts/SG_DXFER_TO_FROM_DEV.s new file mode 100644 index 00000000..47d0c50f --- /dev/null +++ b/libc/sysv/consts/SG_DXFER_TO_FROM_DEV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_DXFER_TO_FROM_DEV -4 0 0 0 0 diff --git a/libc/sysv/consts/SG_EMULATED_HOST.s b/libc/sysv/consts/SG_EMULATED_HOST.s new file mode 100644 index 00000000..a3d85eb5 --- /dev/null +++ b/libc/sysv/consts/SG_EMULATED_HOST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_EMULATED_HOST 0x2203 0 0 0 0 diff --git a/libc/sysv/consts/SG_FLAG_DIRECT_IO.s b/libc/sysv/consts/SG_FLAG_DIRECT_IO.s new file mode 100644 index 00000000..fe3c41af --- /dev/null +++ b/libc/sysv/consts/SG_FLAG_DIRECT_IO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_FLAG_DIRECT_IO 1 0 0 0 0 diff --git a/libc/sysv/consts/SG_FLAG_LUN_INHIBIT.s b/libc/sysv/consts/SG_FLAG_LUN_INHIBIT.s new file mode 100644 index 00000000..fbc73639 --- /dev/null +++ b/libc/sysv/consts/SG_FLAG_LUN_INHIBIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_FLAG_LUN_INHIBIT 2 0 0 0 0 diff --git a/libc/sysv/consts/SG_FLAG_NO_DXFER.s b/libc/sysv/consts/SG_FLAG_NO_DXFER.s new file mode 100644 index 00000000..75b4359a --- /dev/null +++ b/libc/sysv/consts/SG_FLAG_NO_DXFER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_FLAG_NO_DXFER 0x010000 0 0 0 0 diff --git a/libc/sysv/consts/SG_GET_COMMAND_Q.s b/libc/sysv/consts/SG_GET_COMMAND_Q.s new file mode 100644 index 00000000..e6750205 --- /dev/null +++ b/libc/sysv/consts/SG_GET_COMMAND_Q.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_GET_COMMAND_Q 0x2270 0 0 0 0 diff --git a/libc/sysv/consts/SG_GET_KEEP_ORPHAN.s b/libc/sysv/consts/SG_GET_KEEP_ORPHAN.s new file mode 100644 index 00000000..8d6fa5d3 --- /dev/null +++ b/libc/sysv/consts/SG_GET_KEEP_ORPHAN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_GET_KEEP_ORPHAN 0x2288 0 0 0 0 diff --git a/libc/sysv/consts/SG_GET_LOW_DMA.s b/libc/sysv/consts/SG_GET_LOW_DMA.s new file mode 100644 index 00000000..96db553e --- /dev/null +++ b/libc/sysv/consts/SG_GET_LOW_DMA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_GET_LOW_DMA 0x227a 0 0 0 0 diff --git a/libc/sysv/consts/SG_GET_NUM_WAITING.s b/libc/sysv/consts/SG_GET_NUM_WAITING.s new file mode 100644 index 00000000..e9e3be4b --- /dev/null +++ b/libc/sysv/consts/SG_GET_NUM_WAITING.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_GET_NUM_WAITING 0x227d 0 0 0 0 diff --git a/libc/sysv/consts/SG_GET_PACK_ID.s b/libc/sysv/consts/SG_GET_PACK_ID.s new file mode 100644 index 00000000..fc815535 --- /dev/null +++ b/libc/sysv/consts/SG_GET_PACK_ID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_GET_PACK_ID 0x227c 0 0 0 0 diff --git a/libc/sysv/consts/SG_GET_REQUEST_TABLE.s b/libc/sysv/consts/SG_GET_REQUEST_TABLE.s new file mode 100644 index 00000000..3b9dfea0 --- /dev/null +++ b/libc/sysv/consts/SG_GET_REQUEST_TABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_GET_REQUEST_TABLE 0x2286 0 0 0 0 diff --git a/libc/sysv/consts/SG_GET_RESERVED_SIZE.s b/libc/sysv/consts/SG_GET_RESERVED_SIZE.s new file mode 100644 index 00000000..412a2993 --- /dev/null +++ b/libc/sysv/consts/SG_GET_RESERVED_SIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_GET_RESERVED_SIZE 0x2272 0 0 0 0 diff --git a/libc/sysv/consts/SG_GET_SCSI_ID.s b/libc/sysv/consts/SG_GET_SCSI_ID.s new file mode 100644 index 00000000..1ceaec83 --- /dev/null +++ b/libc/sysv/consts/SG_GET_SCSI_ID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_GET_SCSI_ID 0x2276 0 0 0 0 diff --git a/libc/sysv/consts/SG_GET_SG_TABLESIZE.s b/libc/sysv/consts/SG_GET_SG_TABLESIZE.s new file mode 100644 index 00000000..790fa013 --- /dev/null +++ b/libc/sysv/consts/SG_GET_SG_TABLESIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_GET_SG_TABLESIZE 0x227f 0 0 0 0 diff --git a/libc/sysv/consts/SG_GET_TIMEOUT.s b/libc/sysv/consts/SG_GET_TIMEOUT.s new file mode 100644 index 00000000..9c61b854 --- /dev/null +++ b/libc/sysv/consts/SG_GET_TIMEOUT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_GET_TIMEOUT 0x2202 0 0 0 0 diff --git a/libc/sysv/consts/SG_GET_TRANSFORM.s b/libc/sysv/consts/SG_GET_TRANSFORM.s new file mode 100644 index 00000000..d5fb9441 --- /dev/null +++ b/libc/sysv/consts/SG_GET_TRANSFORM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_GET_TRANSFORM 0x2205 0 0 0 0 diff --git a/libc/sysv/consts/SG_GET_VERSION_NUM.s b/libc/sysv/consts/SG_GET_VERSION_NUM.s new file mode 100644 index 00000000..2cf8330d --- /dev/null +++ b/libc/sysv/consts/SG_GET_VERSION_NUM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_GET_VERSION_NUM 0x2282 0 0 0 0 diff --git a/libc/sysv/consts/SG_INFO_CHECK.s b/libc/sysv/consts/SG_INFO_CHECK.s new file mode 100644 index 00000000..44539a62 --- /dev/null +++ b/libc/sysv/consts/SG_INFO_CHECK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_INFO_CHECK 1 0 0 0 0 diff --git a/libc/sysv/consts/SG_INFO_DIRECT_IO.s b/libc/sysv/consts/SG_INFO_DIRECT_IO.s new file mode 100644 index 00000000..da0ce750 --- /dev/null +++ b/libc/sysv/consts/SG_INFO_DIRECT_IO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_INFO_DIRECT_IO 2 0 0 0 0 diff --git a/libc/sysv/consts/SG_INFO_DIRECT_IO_MASK.s b/libc/sysv/consts/SG_INFO_DIRECT_IO_MASK.s new file mode 100644 index 00000000..96b23603 --- /dev/null +++ b/libc/sysv/consts/SG_INFO_DIRECT_IO_MASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_INFO_DIRECT_IO_MASK 6 0 0 0 0 diff --git a/libc/sysv/consts/SG_INFO_INDIRECT_IO.s b/libc/sysv/consts/SG_INFO_INDIRECT_IO.s new file mode 100644 index 00000000..c3d561d5 --- /dev/null +++ b/libc/sysv/consts/SG_INFO_INDIRECT_IO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_INFO_INDIRECT_IO 0 0 0 0 0 diff --git a/libc/sysv/consts/SG_INFO_MIXED_IO.s b/libc/sysv/consts/SG_INFO_MIXED_IO.s new file mode 100644 index 00000000..e1df200e --- /dev/null +++ b/libc/sysv/consts/SG_INFO_MIXED_IO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_INFO_MIXED_IO 4 0 0 0 0 diff --git a/libc/sysv/consts/SG_INFO_OK.s b/libc/sysv/consts/SG_INFO_OK.s new file mode 100644 index 00000000..bb5b6f26 --- /dev/null +++ b/libc/sysv/consts/SG_INFO_OK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_INFO_OK 0 0 0 0 0 diff --git a/libc/sysv/consts/SG_INFO_OK_MASK.s b/libc/sysv/consts/SG_INFO_OK_MASK.s new file mode 100644 index 00000000..1929854e --- /dev/null +++ b/libc/sysv/consts/SG_INFO_OK_MASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_INFO_OK_MASK 1 0 0 0 0 diff --git a/libc/sysv/consts/SG_IO.s b/libc/sysv/consts/SG_IO.s new file mode 100644 index 00000000..638a0bea --- /dev/null +++ b/libc/sysv/consts/SG_IO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_IO 0x2285 0 0 0 0 diff --git a/libc/sysv/consts/SG_MAX_QUEUE.s b/libc/sysv/consts/SG_MAX_QUEUE.s new file mode 100644 index 00000000..945c955c --- /dev/null +++ b/libc/sysv/consts/SG_MAX_QUEUE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_MAX_QUEUE 0x10 0 0 0 0 diff --git a/libc/sysv/consts/SG_MAX_SENSE.s b/libc/sysv/consts/SG_MAX_SENSE.s new file mode 100644 index 00000000..6f09a685 --- /dev/null +++ b/libc/sysv/consts/SG_MAX_SENSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_MAX_SENSE 0x10 0 0 0 0 diff --git a/libc/sysv/consts/SG_NEXT_CMD_LEN.s b/libc/sysv/consts/SG_NEXT_CMD_LEN.s new file mode 100644 index 00000000..7340fbb3 --- /dev/null +++ b/libc/sysv/consts/SG_NEXT_CMD_LEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_NEXT_CMD_LEN 0x2283 0 0 0 0 diff --git a/libc/sysv/consts/SG_SCATTER_SZ.s b/libc/sysv/consts/SG_SCATTER_SZ.s new file mode 100644 index 00000000..57705ee8 --- /dev/null +++ b/libc/sysv/consts/SG_SCATTER_SZ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_SCATTER_SZ 0x8000 0 0 0 0 diff --git a/libc/sysv/consts/SG_SCSI_RESET.s b/libc/sysv/consts/SG_SCSI_RESET.s new file mode 100644 index 00000000..351d567f --- /dev/null +++ b/libc/sysv/consts/SG_SCSI_RESET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_SCSI_RESET 0x2284 0 0 0 0 diff --git a/libc/sysv/consts/SG_SCSI_RESET_BUS.s b/libc/sysv/consts/SG_SCSI_RESET_BUS.s new file mode 100644 index 00000000..46afe0e2 --- /dev/null +++ b/libc/sysv/consts/SG_SCSI_RESET_BUS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_SCSI_RESET_BUS 2 0 0 0 0 diff --git a/libc/sysv/consts/SG_SCSI_RESET_DEVICE.s b/libc/sysv/consts/SG_SCSI_RESET_DEVICE.s new file mode 100644 index 00000000..4bdada0b --- /dev/null +++ b/libc/sysv/consts/SG_SCSI_RESET_DEVICE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_SCSI_RESET_DEVICE 1 0 0 0 0 diff --git a/libc/sysv/consts/SG_SCSI_RESET_HOST.s b/libc/sysv/consts/SG_SCSI_RESET_HOST.s new file mode 100644 index 00000000..a604470d --- /dev/null +++ b/libc/sysv/consts/SG_SCSI_RESET_HOST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_SCSI_RESET_HOST 3 0 0 0 0 diff --git a/libc/sysv/consts/SG_SCSI_RESET_NOTHING.s b/libc/sysv/consts/SG_SCSI_RESET_NOTHING.s new file mode 100644 index 00000000..f5b362c5 --- /dev/null +++ b/libc/sysv/consts/SG_SCSI_RESET_NOTHING.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_SCSI_RESET_NOTHING 0 0 0 0 0 diff --git a/libc/sysv/consts/SG_SET_COMMAND_Q.s b/libc/sysv/consts/SG_SET_COMMAND_Q.s new file mode 100644 index 00000000..00b6b4d3 --- /dev/null +++ b/libc/sysv/consts/SG_SET_COMMAND_Q.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_SET_COMMAND_Q 0x2271 0 0 0 0 diff --git a/libc/sysv/consts/SG_SET_DEBUG.s b/libc/sysv/consts/SG_SET_DEBUG.s new file mode 100644 index 00000000..fa6b7f3f --- /dev/null +++ b/libc/sysv/consts/SG_SET_DEBUG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_SET_DEBUG 0x227e 0 0 0 0 diff --git a/libc/sysv/consts/SG_SET_FORCE_LOW_DMA.s b/libc/sysv/consts/SG_SET_FORCE_LOW_DMA.s new file mode 100644 index 00000000..a38728fd --- /dev/null +++ b/libc/sysv/consts/SG_SET_FORCE_LOW_DMA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_SET_FORCE_LOW_DMA 0x2279 0 0 0 0 diff --git a/libc/sysv/consts/SG_SET_FORCE_PACK_ID.s b/libc/sysv/consts/SG_SET_FORCE_PACK_ID.s new file mode 100644 index 00000000..8b995734 --- /dev/null +++ b/libc/sysv/consts/SG_SET_FORCE_PACK_ID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_SET_FORCE_PACK_ID 0x227b 0 0 0 0 diff --git a/libc/sysv/consts/SG_SET_KEEP_ORPHAN.s b/libc/sysv/consts/SG_SET_KEEP_ORPHAN.s new file mode 100644 index 00000000..346f618d --- /dev/null +++ b/libc/sysv/consts/SG_SET_KEEP_ORPHAN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_SET_KEEP_ORPHAN 0x2287 0 0 0 0 diff --git a/libc/sysv/consts/SG_SET_RESERVED_SIZE.s b/libc/sysv/consts/SG_SET_RESERVED_SIZE.s new file mode 100644 index 00000000..74683101 --- /dev/null +++ b/libc/sysv/consts/SG_SET_RESERVED_SIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_SET_RESERVED_SIZE 0x2275 0 0 0 0 diff --git a/libc/sysv/consts/SG_SET_TIMEOUT.s b/libc/sysv/consts/SG_SET_TIMEOUT.s new file mode 100644 index 00000000..e150c15e --- /dev/null +++ b/libc/sysv/consts/SG_SET_TIMEOUT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_SET_TIMEOUT 0x2201 0 0 0 0 diff --git a/libc/sysv/consts/SG_SET_TRANSFORM.s b/libc/sysv/consts/SG_SET_TRANSFORM.s new file mode 100644 index 00000000..693c0249 --- /dev/null +++ b/libc/sysv/consts/SG_SET_TRANSFORM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sg SG_SET_TRANSFORM 0x2204 0 0 0 0 diff --git a/libc/sysv/consts/SHMLBA.s b/libc/sysv/consts/SHMLBA.s new file mode 100644 index 00000000..80ad6059 --- /dev/null +++ b/libc/sysv/consts/SHMLBA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SHMLBA 0 0x1000 0x1000 0x1000 0 diff --git a/libc/sysv/consts/SHM_DEST.s b/libc/sysv/consts/SHM_DEST.s new file mode 100644 index 00000000..0d8c7d6f --- /dev/null +++ b/libc/sysv/consts/SHM_DEST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon shm SHM_DEST 0x0200 0 0 0 0 diff --git a/libc/sysv/consts/SHM_EXEC.s b/libc/sysv/consts/SHM_EXEC.s new file mode 100644 index 00000000..3e7f7907 --- /dev/null +++ b/libc/sysv/consts/SHM_EXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon shm SHM_EXEC 0x8000 0 0 0 0 diff --git a/libc/sysv/consts/SHM_HUGETLB.s b/libc/sysv/consts/SHM_HUGETLB.s new file mode 100644 index 00000000..46d06ad1 --- /dev/null +++ b/libc/sysv/consts/SHM_HUGETLB.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon shm SHM_HUGETLB 0x0800 0 0 0 0 diff --git a/libc/sysv/consts/SHM_INFO.s b/libc/sysv/consts/SHM_INFO.s new file mode 100644 index 00000000..480b5ca0 --- /dev/null +++ b/libc/sysv/consts/SHM_INFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon shm SHM_INFO 14 0 14 0 0 diff --git a/libc/sysv/consts/SHM_LOCK.s b/libc/sysv/consts/SHM_LOCK.s new file mode 100644 index 00000000..bccbc57f --- /dev/null +++ b/libc/sysv/consts/SHM_LOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon shm SHM_LOCK 11 0 11 3 0 diff --git a/libc/sysv/consts/SHM_LOCKED.s b/libc/sysv/consts/SHM_LOCKED.s new file mode 100644 index 00000000..ba3d877f --- /dev/null +++ b/libc/sysv/consts/SHM_LOCKED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon shm SHM_LOCKED 0x0400 0 0 0 0 diff --git a/libc/sysv/consts/SHM_NORESERVE.s b/libc/sysv/consts/SHM_NORESERVE.s new file mode 100644 index 00000000..99a13802 --- /dev/null +++ b/libc/sysv/consts/SHM_NORESERVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon shm SHM_NORESERVE 0x1000 0 0 0 0 diff --git a/libc/sysv/consts/SHM_R.s b/libc/sysv/consts/SHM_R.s new file mode 100644 index 00000000..0b0c4440 --- /dev/null +++ b/libc/sysv/consts/SHM_R.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon shm SHM_R 0x0100 0x0100 0x0100 0x0100 0 diff --git a/libc/sysv/consts/SHM_RDONLY.s b/libc/sysv/consts/SHM_RDONLY.s new file mode 100644 index 00000000..ee446259 --- /dev/null +++ b/libc/sysv/consts/SHM_RDONLY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon shm SHM_RDONLY 0x1000 0x1000 0x1000 0x1000 0 diff --git a/libc/sysv/consts/SHM_REMAP.s b/libc/sysv/consts/SHM_REMAP.s new file mode 100644 index 00000000..ad429e0c --- /dev/null +++ b/libc/sysv/consts/SHM_REMAP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon shm SHM_REMAP 0x4000 0 0 0 0 diff --git a/libc/sysv/consts/SHM_RND.s b/libc/sysv/consts/SHM_RND.s new file mode 100644 index 00000000..b51e60d0 --- /dev/null +++ b/libc/sysv/consts/SHM_RND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon shm SHM_RND 0x2000 0x2000 0x2000 0x2000 0 diff --git a/libc/sysv/consts/SHM_STAT.s b/libc/sysv/consts/SHM_STAT.s new file mode 100644 index 00000000..4e6eadcf --- /dev/null +++ b/libc/sysv/consts/SHM_STAT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon shm SHM_STAT 13 0 13 0 0 diff --git a/libc/sysv/consts/SHM_UNLOCK.s b/libc/sysv/consts/SHM_UNLOCK.s new file mode 100644 index 00000000..975272aa --- /dev/null +++ b/libc/sysv/consts/SHM_UNLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon shm SHM_UNLOCK 12 0 12 4 0 diff --git a/libc/sysv/consts/SHM_W.s b/libc/sysv/consts/SHM_W.s new file mode 100644 index 00000000..1e609a91 --- /dev/null +++ b/libc/sysv/consts/SHM_W.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon shm SHM_W 0x80 0x80 0x80 0x80 0 diff --git a/libc/sysv/consts/SHORT_INODE.s b/libc/sysv/consts/SHORT_INODE.s new file mode 100644 index 00000000..e3fc4176 --- /dev/null +++ b/libc/sysv/consts/SHORT_INODE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon prsnlty SHORT_INODE 0x1000000 -1 -1 -1 -1 diff --git a/libc/sysv/consts/SHUT_RD.s b/libc/sysv/consts/SHUT_RD.s new file mode 100644 index 00000000..0187100e --- /dev/null +++ b/libc/sysv/consts/SHUT_RD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SHUT_RD 0 0 0 0 0 diff --git a/libc/sysv/consts/SHUT_RDWR.s b/libc/sysv/consts/SHUT_RDWR.s new file mode 100644 index 00000000..3f20b04d --- /dev/null +++ b/libc/sysv/consts/SHUT_RDWR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SHUT_RDWR 2 2 2 2 2 diff --git a/libc/sysv/consts/SHUT_WR.s b/libc/sysv/consts/SHUT_WR.s new file mode 100644 index 00000000..116578a3 --- /dev/null +++ b/libc/sysv/consts/SHUT_WR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SHUT_WR 1 1 1 1 1 diff --git a/libc/sysv/consts/SIGABRT.s b/libc/sysv/consts/SIGABRT.s new file mode 100644 index 00000000..bb158e1a --- /dev/null +++ b/libc/sysv/consts/SIGABRT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGABRT 6 6 6 6 6 diff --git a/libc/sysv/consts/SIGALRM.s b/libc/sysv/consts/SIGALRM.s new file mode 100644 index 00000000..4f6fec11 --- /dev/null +++ b/libc/sysv/consts/SIGALRM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGALRM 14 14 14 14 14 diff --git a/libc/sysv/consts/SIGBUS.s b/libc/sysv/consts/SIGBUS.s new file mode 100644 index 00000000..b34442fc --- /dev/null +++ b/libc/sysv/consts/SIGBUS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGBUS 7 10 10 10 0 diff --git a/libc/sysv/consts/SIGCHLD.s b/libc/sysv/consts/SIGCHLD.s new file mode 100644 index 00000000..3a25f5cc --- /dev/null +++ b/libc/sysv/consts/SIGCHLD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGCHLD 17 20 20 20 0 diff --git a/libc/sysv/consts/SIGCONT.s b/libc/sysv/consts/SIGCONT.s new file mode 100644 index 00000000..00452577 --- /dev/null +++ b/libc/sysv/consts/SIGCONT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGCONT 18 19 19 19 0 diff --git a/libc/sysv/consts/SIGEV_NONE.s b/libc/sysv/consts/SIGEV_NONE.s new file mode 100644 index 00000000..3e3b62c5 --- /dev/null +++ b/libc/sysv/consts/SIGEV_NONE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SIGEV_NONE 1 0 0 0 0 diff --git a/libc/sysv/consts/SIGEV_SIGNAL.s b/libc/sysv/consts/SIGEV_SIGNAL.s new file mode 100644 index 00000000..1f8ed663 --- /dev/null +++ b/libc/sysv/consts/SIGEV_SIGNAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SIGEV_SIGNAL 0 1 1 0 0 diff --git a/libc/sysv/consts/SIGEV_THREAD.s b/libc/sysv/consts/SIGEV_THREAD.s new file mode 100644 index 00000000..6769e91a --- /dev/null +++ b/libc/sysv/consts/SIGEV_THREAD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SIGEV_THREAD 2 3 2 0 0 diff --git a/libc/sysv/consts/SIGFPE.s b/libc/sysv/consts/SIGFPE.s new file mode 100644 index 00000000..845a92b1 --- /dev/null +++ b/libc/sysv/consts/SIGFPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGFPE 8 8 8 8 8 diff --git a/libc/sysv/consts/SIGHUP.s b/libc/sysv/consts/SIGHUP.s new file mode 100644 index 00000000..32b77730 --- /dev/null +++ b/libc/sysv/consts/SIGHUP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGHUP 1 1 1 1 1 diff --git a/libc/sysv/consts/SIGILL.s b/libc/sysv/consts/SIGILL.s new file mode 100644 index 00000000..58df857c --- /dev/null +++ b/libc/sysv/consts/SIGILL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGILL 4 4 4 4 4 diff --git a/libc/sysv/consts/SIGINT.s b/libc/sysv/consts/SIGINT.s new file mode 100644 index 00000000..a5bdf21e --- /dev/null +++ b/libc/sysv/consts/SIGINT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGINT 2 2 2 2 2 diff --git a/libc/sysv/consts/SIGIO.s b/libc/sysv/consts/SIGIO.s new file mode 100644 index 00000000..8a64d2bc --- /dev/null +++ b/libc/sysv/consts/SIGIO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGIO 29 23 23 23 0 diff --git a/libc/sysv/consts/SIGIOT.s b/libc/sysv/consts/SIGIOT.s new file mode 100644 index 00000000..8c7d6efd --- /dev/null +++ b/libc/sysv/consts/SIGIOT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGIOT 6 6 6 6 6 diff --git a/libc/sysv/consts/SIGKILL.s b/libc/sysv/consts/SIGKILL.s new file mode 100644 index 00000000..7f4defa2 --- /dev/null +++ b/libc/sysv/consts/SIGKILL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGKILL 9 9 9 9 9 diff --git a/libc/sysv/consts/SIGPIPE.s b/libc/sysv/consts/SIGPIPE.s new file mode 100644 index 00000000..e1b23179 --- /dev/null +++ b/libc/sysv/consts/SIGPIPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGPIPE 13 13 13 13 13 diff --git a/libc/sysv/consts/SIGPOLL.s b/libc/sysv/consts/SIGPOLL.s new file mode 100644 index 00000000..7f88e1a2 --- /dev/null +++ b/libc/sysv/consts/SIGPOLL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGPOLL 29 0 0 0 0 diff --git a/libc/sysv/consts/SIGPROF.s b/libc/sysv/consts/SIGPROF.s new file mode 100644 index 00000000..a44e2347 --- /dev/null +++ b/libc/sysv/consts/SIGPROF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGPROF 27 27 27 27 27 diff --git a/libc/sysv/consts/SIGPWR.s b/libc/sysv/consts/SIGPWR.s new file mode 100644 index 00000000..9fcfab49 --- /dev/null +++ b/libc/sysv/consts/SIGPWR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGPWR 30 0 0 0 0 diff --git a/libc/sysv/consts/SIGQUIT.s b/libc/sysv/consts/SIGQUIT.s new file mode 100644 index 00000000..657fc205 --- /dev/null +++ b/libc/sysv/consts/SIGQUIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGQUIT 3 3 3 3 3 diff --git a/libc/sysv/consts/SIGRTMAX.s b/libc/sysv/consts/SIGRTMAX.s new file mode 100644 index 00000000..e3edcadb --- /dev/null +++ b/libc/sysv/consts/SIGRTMAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGRTMAX 0 0 126 0 0 diff --git a/libc/sysv/consts/SIGRTMIN.s b/libc/sysv/consts/SIGRTMIN.s new file mode 100644 index 00000000..ca89bfd6 --- /dev/null +++ b/libc/sysv/consts/SIGRTMIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGRTMIN 0 0 65 0 0 diff --git a/libc/sysv/consts/SIGSEGV.s b/libc/sysv/consts/SIGSEGV.s new file mode 100644 index 00000000..4f8da8b5 --- /dev/null +++ b/libc/sysv/consts/SIGSEGV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGSEGV 11 11 11 11 11 diff --git a/libc/sysv/consts/SIGSTKFLT.s b/libc/sysv/consts/SIGSTKFLT.s new file mode 100644 index 00000000..fbc25618 --- /dev/null +++ b/libc/sysv/consts/SIGSTKFLT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGSTKFLT 0x10 0 0 0 0 diff --git a/libc/sysv/consts/SIGSTKSZ.s b/libc/sysv/consts/SIGSTKSZ.s new file mode 100644 index 00000000..c0410eae --- /dev/null +++ b/libc/sysv/consts/SIGSTKSZ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGSTKSZ 0x2000 0x020000 0x8800 0x7000 0 diff --git a/libc/sysv/consts/SIGSTOP.s b/libc/sysv/consts/SIGSTOP.s new file mode 100644 index 00000000..23999663 --- /dev/null +++ b/libc/sysv/consts/SIGSTOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGSTOP 19 17 17 17 0 diff --git a/libc/sysv/consts/SIGSYS.s b/libc/sysv/consts/SIGSYS.s new file mode 100644 index 00000000..67768e78 --- /dev/null +++ b/libc/sysv/consts/SIGSYS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGSYS 31 12 12 12 0 diff --git a/libc/sysv/consts/SIGTERM.s b/libc/sysv/consts/SIGTERM.s new file mode 100644 index 00000000..2ba40385 --- /dev/null +++ b/libc/sysv/consts/SIGTERM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGTERM 15 15 15 15 15 diff --git a/libc/sysv/consts/SIGTRAP.s b/libc/sysv/consts/SIGTRAP.s new file mode 100644 index 00000000..5dc5770b --- /dev/null +++ b/libc/sysv/consts/SIGTRAP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGTRAP 5 5 5 5 5 diff --git a/libc/sysv/consts/SIGTSTP.s b/libc/sysv/consts/SIGTSTP.s new file mode 100644 index 00000000..c70d3b33 --- /dev/null +++ b/libc/sysv/consts/SIGTSTP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGTSTP 20 18 18 18 0 diff --git a/libc/sysv/consts/SIGTTIN.s b/libc/sysv/consts/SIGTTIN.s new file mode 100644 index 00000000..5a71fb70 --- /dev/null +++ b/libc/sysv/consts/SIGTTIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGTTIN 21 21 21 21 21 diff --git a/libc/sysv/consts/SIGTTOU.s b/libc/sysv/consts/SIGTTOU.s new file mode 100644 index 00000000..35538d06 --- /dev/null +++ b/libc/sysv/consts/SIGTTOU.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGTTOU 22 22 22 22 22 diff --git a/libc/sysv/consts/SIGUNUSED.s b/libc/sysv/consts/SIGUNUSED.s new file mode 100644 index 00000000..2a5c092c --- /dev/null +++ b/libc/sysv/consts/SIGUNUSED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGUNUSED 31 0 0 0 0 diff --git a/libc/sysv/consts/SIGURG.s b/libc/sysv/consts/SIGURG.s new file mode 100644 index 00000000..f07d8610 --- /dev/null +++ b/libc/sysv/consts/SIGURG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGURG 23 0x10 0x10 0x10 0 diff --git a/libc/sysv/consts/SIGUSR1.s b/libc/sysv/consts/SIGUSR1.s new file mode 100644 index 00000000..bf64e733 --- /dev/null +++ b/libc/sysv/consts/SIGUSR1.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGUSR1 10 30 30 30 0 diff --git a/libc/sysv/consts/SIGUSR2.s b/libc/sysv/consts/SIGUSR2.s new file mode 100644 index 00000000..16792d04 --- /dev/null +++ b/libc/sysv/consts/SIGUSR2.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGUSR2 12 31 31 31 0 diff --git a/libc/sysv/consts/SIGVTALRM.s b/libc/sysv/consts/SIGVTALRM.s new file mode 100644 index 00000000..06cccbef --- /dev/null +++ b/libc/sysv/consts/SIGVTALRM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGVTALRM 26 26 26 26 26 diff --git a/libc/sysv/consts/SIGWINCH.s b/libc/sysv/consts/SIGWINCH.s new file mode 100644 index 00000000..0f7c0b83 --- /dev/null +++ b/libc/sysv/consts/SIGWINCH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGWINCH 28 28 28 28 28 diff --git a/libc/sysv/consts/SIGXCPU.s b/libc/sysv/consts/SIGXCPU.s new file mode 100644 index 00000000..09387e86 --- /dev/null +++ b/libc/sysv/consts/SIGXCPU.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGXCPU 24 24 24 24 24 diff --git a/libc/sysv/consts/SIGXFSZ.s b/libc/sysv/consts/SIGXFSZ.s new file mode 100644 index 00000000..46395b3d --- /dev/null +++ b/libc/sysv/consts/SIGXFSZ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sig SIGXFSZ 25 25 25 25 25 diff --git a/libc/sysv/consts/SIG_ATOMIC_MIN.s b/libc/sysv/consts/SIG_ATOMIC_MIN.s new file mode 100644 index 00000000..411c5090 --- /dev/null +++ b/libc/sysv/consts/SIG_ATOMIC_MIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SIG_ATOMIC_MIN -2147483648 -2147483648 -9223372036854775808 -2147483648 0 diff --git a/libc/sysv/consts/SIG_BLOCK.s b/libc/sysv/consts/SIG_BLOCK.s new file mode 100644 index 00000000..cab61db3 --- /dev/null +++ b/libc/sysv/consts/SIG_BLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SIG_BLOCK 0 1 1 1 0 diff --git a/libc/sysv/consts/SIG_SETMASK.s b/libc/sysv/consts/SIG_SETMASK.s new file mode 100644 index 00000000..a5350d2a --- /dev/null +++ b/libc/sysv/consts/SIG_SETMASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SIG_SETMASK 2 3 3 3 0 diff --git a/libc/sysv/consts/SIG_UNBLOCK.s b/libc/sysv/consts/SIG_UNBLOCK.s new file mode 100644 index 00000000..841e946c --- /dev/null +++ b/libc/sysv/consts/SIG_UNBLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SIG_UNBLOCK 1 2 2 2 0 diff --git a/libc/sysv/consts/SIMPLE_QUEUE_TAG.s b/libc/sysv/consts/SIMPLE_QUEUE_TAG.s new file mode 100644 index 00000000..7c1df949 --- /dev/null +++ b/libc/sysv/consts/SIMPLE_QUEUE_TAG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SIMPLE_QUEUE_TAG 0x20 0 0 0 0 diff --git a/libc/sysv/consts/SIOCADDDLCI.s b/libc/sysv/consts/SIOCADDDLCI.s new file mode 100644 index 00000000..6a2a21e8 --- /dev/null +++ b/libc/sysv/consts/SIOCADDDLCI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCADDDLCI 0x8980 0 0 0 0 diff --git a/libc/sysv/consts/SIOCADDMULTI.s b/libc/sysv/consts/SIOCADDMULTI.s new file mode 100644 index 00000000..68f99041 --- /dev/null +++ b/libc/sysv/consts/SIOCADDMULTI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCADDMULTI 0x8931 0x80206931 0x80206931 0x80206931 0 diff --git a/libc/sysv/consts/SIOCADDRT.s b/libc/sysv/consts/SIOCADDRT.s new file mode 100644 index 00000000..5902e46c --- /dev/null +++ b/libc/sysv/consts/SIOCADDRT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCADDRT 0x890b 0 0 0 0 diff --git a/libc/sysv/consts/SIOCATMARK.s b/libc/sysv/consts/SIOCATMARK.s new file mode 100644 index 00000000..590c9338 --- /dev/null +++ b/libc/sysv/consts/SIOCATMARK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCATMARK 0x8905 0x40047307 0x40047307 0x40047307 0 diff --git a/libc/sysv/consts/SIOCDARP.s b/libc/sysv/consts/SIOCDARP.s new file mode 100644 index 00000000..20f89c31 --- /dev/null +++ b/libc/sysv/consts/SIOCDARP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCDARP 0x8953 0 0 0 0 diff --git a/libc/sysv/consts/SIOCDELDLCI.s b/libc/sysv/consts/SIOCDELDLCI.s new file mode 100644 index 00000000..d15cb689 --- /dev/null +++ b/libc/sysv/consts/SIOCDELDLCI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCDELDLCI 0x8981 0 0 0 0 diff --git a/libc/sysv/consts/SIOCDELMULTI.s b/libc/sysv/consts/SIOCDELMULTI.s new file mode 100644 index 00000000..874f8cad --- /dev/null +++ b/libc/sysv/consts/SIOCDELMULTI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCDELMULTI 0x8932 0x80206932 0x80206932 0x80206932 0 diff --git a/libc/sysv/consts/SIOCDELRT.s b/libc/sysv/consts/SIOCDELRT.s new file mode 100644 index 00000000..5d59f01f --- /dev/null +++ b/libc/sysv/consts/SIOCDELRT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCDELRT 0x890c 0 0 0 0 diff --git a/libc/sysv/consts/SIOCDEVPRIVATE.s b/libc/sysv/consts/SIOCDEVPRIVATE.s new file mode 100644 index 00000000..ef507654 --- /dev/null +++ b/libc/sysv/consts/SIOCDEVPRIVATE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCDEVPRIVATE 0x89f0 0 0 0 0 diff --git a/libc/sysv/consts/SIOCDIFADDR.s b/libc/sysv/consts/SIOCDIFADDR.s new file mode 100644 index 00000000..dfefd0c5 --- /dev/null +++ b/libc/sysv/consts/SIOCDIFADDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCDIFADDR 0x8936 0x80206919 0x80206919 0x80206919 0 diff --git a/libc/sysv/consts/SIOCDRARP.s b/libc/sysv/consts/SIOCDRARP.s new file mode 100644 index 00000000..ae34fd87 --- /dev/null +++ b/libc/sysv/consts/SIOCDRARP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCDRARP 0x8960 0 0 0 0 diff --git a/libc/sysv/consts/SIOCGARP.s b/libc/sysv/consts/SIOCGARP.s new file mode 100644 index 00000000..7bb28050 --- /dev/null +++ b/libc/sysv/consts/SIOCGARP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGARP 0x8954 0 0 0 0 diff --git a/libc/sysv/consts/SIOCGIFADDR.s b/libc/sysv/consts/SIOCGIFADDR.s new file mode 100644 index 00000000..2e3e35d4 --- /dev/null +++ b/libc/sysv/consts/SIOCGIFADDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFADDR 0x8915 0xc0206921 0xc0206921 0xc0206921 0 diff --git a/libc/sysv/consts/SIOCGIFBR.s b/libc/sysv/consts/SIOCGIFBR.s new file mode 100644 index 00000000..11d4680d --- /dev/null +++ b/libc/sysv/consts/SIOCGIFBR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFBR 0x8940 0 0 0 0 diff --git a/libc/sysv/consts/SIOCGIFBRDADDR.s b/libc/sysv/consts/SIOCGIFBRDADDR.s new file mode 100644 index 00000000..13719a77 --- /dev/null +++ b/libc/sysv/consts/SIOCGIFBRDADDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFBRDADDR 0x8919 0xc0206923 0xc0206923 0xc0206923 0 diff --git a/libc/sysv/consts/SIOCGIFCONF.s b/libc/sysv/consts/SIOCGIFCONF.s new file mode 100644 index 00000000..3bde4794 --- /dev/null +++ b/libc/sysv/consts/SIOCGIFCONF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFCONF 0x8912 0xc00c6924 0xc0106924 0xc0106924 0 diff --git a/libc/sysv/consts/SIOCGIFCOUNT.s b/libc/sysv/consts/SIOCGIFCOUNT.s new file mode 100644 index 00000000..1f5636e8 --- /dev/null +++ b/libc/sysv/consts/SIOCGIFCOUNT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFCOUNT 0x8938 0 0 0 0 diff --git a/libc/sysv/consts/SIOCGIFDSTADDR.s b/libc/sysv/consts/SIOCGIFDSTADDR.s new file mode 100644 index 00000000..9b942851 --- /dev/null +++ b/libc/sysv/consts/SIOCGIFDSTADDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFDSTADDR 0x8917 0xc0206922 0xc0206922 0xc0206922 0 diff --git a/libc/sysv/consts/SIOCGIFENCAP.s b/libc/sysv/consts/SIOCGIFENCAP.s new file mode 100644 index 00000000..7361e2d8 --- /dev/null +++ b/libc/sysv/consts/SIOCGIFENCAP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFENCAP 0x8925 0 0 0 0 diff --git a/libc/sysv/consts/SIOCGIFFLAGS.s b/libc/sysv/consts/SIOCGIFFLAGS.s new file mode 100644 index 00000000..f967074e --- /dev/null +++ b/libc/sysv/consts/SIOCGIFFLAGS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFFLAGS 0x8913 0xc0206911 0xc0206911 0xc0206911 0 diff --git a/libc/sysv/consts/SIOCGIFHWADDR.s b/libc/sysv/consts/SIOCGIFHWADDR.s new file mode 100644 index 00000000..b0224254 --- /dev/null +++ b/libc/sysv/consts/SIOCGIFHWADDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFHWADDR 0x8927 0 0 0 0 diff --git a/libc/sysv/consts/SIOCGIFINDEX.s b/libc/sysv/consts/SIOCGIFINDEX.s new file mode 100644 index 00000000..816ffd22 --- /dev/null +++ b/libc/sysv/consts/SIOCGIFINDEX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFINDEX 0x8933 0 0xc0206920 0 0 diff --git a/libc/sysv/consts/SIOCGIFMAP.s b/libc/sysv/consts/SIOCGIFMAP.s new file mode 100644 index 00000000..4dfa6d7d --- /dev/null +++ b/libc/sysv/consts/SIOCGIFMAP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFMAP 0x8970 0 0 0 0 diff --git a/libc/sysv/consts/SIOCGIFMEM.s b/libc/sysv/consts/SIOCGIFMEM.s new file mode 100644 index 00000000..bbef59f5 --- /dev/null +++ b/libc/sysv/consts/SIOCGIFMEM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFMEM 0x891f 0 0 0 0 diff --git a/libc/sysv/consts/SIOCGIFMETRIC.s b/libc/sysv/consts/SIOCGIFMETRIC.s new file mode 100644 index 00000000..eb2d3875 --- /dev/null +++ b/libc/sysv/consts/SIOCGIFMETRIC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFMETRIC 0x891d 0xc0206917 0xc0206917 0xc0206917 0 diff --git a/libc/sysv/consts/SIOCGIFMTU.s b/libc/sysv/consts/SIOCGIFMTU.s new file mode 100644 index 00000000..b5718bbf --- /dev/null +++ b/libc/sysv/consts/SIOCGIFMTU.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFMTU 0x8921 0xc0206933 0xc0206933 0xc020697e 0 diff --git a/libc/sysv/consts/SIOCGIFNAME.s b/libc/sysv/consts/SIOCGIFNAME.s new file mode 100644 index 00000000..9f3a8582 --- /dev/null +++ b/libc/sysv/consts/SIOCGIFNAME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFNAME 0x8910 0 0 0 0 diff --git a/libc/sysv/consts/SIOCGIFNETMASK.s b/libc/sysv/consts/SIOCGIFNETMASK.s new file mode 100644 index 00000000..45442abe --- /dev/null +++ b/libc/sysv/consts/SIOCGIFNETMASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFNETMASK 0x891b 0xc0206925 0xc0206925 0xc0206925 0 diff --git a/libc/sysv/consts/SIOCGIFPFLAGS.s b/libc/sysv/consts/SIOCGIFPFLAGS.s new file mode 100644 index 00000000..6b8f95ce --- /dev/null +++ b/libc/sysv/consts/SIOCGIFPFLAGS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFPFLAGS 0x8935 0 0 0 0 diff --git a/libc/sysv/consts/SIOCGIFSLAVE.s b/libc/sysv/consts/SIOCGIFSLAVE.s new file mode 100644 index 00000000..94a38d9e --- /dev/null +++ b/libc/sysv/consts/SIOCGIFSLAVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFSLAVE 0x8929 0 0 0 0 diff --git a/libc/sysv/consts/SIOCGIFTXQLEN.s b/libc/sysv/consts/SIOCGIFTXQLEN.s new file mode 100644 index 00000000..0508bd5d --- /dev/null +++ b/libc/sysv/consts/SIOCGIFTXQLEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGIFTXQLEN 0x8942 0 0 0 0 diff --git a/libc/sysv/consts/SIOCGPGRP.s b/libc/sysv/consts/SIOCGPGRP.s new file mode 100644 index 00000000..db113e3e --- /dev/null +++ b/libc/sysv/consts/SIOCGPGRP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGPGRP 0x8904 0x40047309 0x40047309 0x40047309 0 diff --git a/libc/sysv/consts/SIOCGRARP.s b/libc/sysv/consts/SIOCGRARP.s new file mode 100644 index 00000000..82723f11 --- /dev/null +++ b/libc/sysv/consts/SIOCGRARP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGRARP 0x8961 0 0 0 0 diff --git a/libc/sysv/consts/SIOCGSTAMP.s b/libc/sysv/consts/SIOCGSTAMP.s new file mode 100644 index 00000000..10091037 --- /dev/null +++ b/libc/sysv/consts/SIOCGSTAMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGSTAMP 0x8906 0 0 0 0 diff --git a/libc/sysv/consts/SIOCGSTAMPNS.s b/libc/sysv/consts/SIOCGSTAMPNS.s new file mode 100644 index 00000000..f34696ae --- /dev/null +++ b/libc/sysv/consts/SIOCGSTAMPNS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCGSTAMPNS 0x8907 0 0 0 0 diff --git a/libc/sysv/consts/SIOCPROTOPRIVATE.s b/libc/sysv/consts/SIOCPROTOPRIVATE.s new file mode 100644 index 00000000..783d85b9 --- /dev/null +++ b/libc/sysv/consts/SIOCPROTOPRIVATE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCPROTOPRIVATE 0x89e0 0 0 0 0 diff --git a/libc/sysv/consts/SIOCRTMSG.s b/libc/sysv/consts/SIOCRTMSG.s new file mode 100644 index 00000000..ed3e7b52 --- /dev/null +++ b/libc/sysv/consts/SIOCRTMSG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCRTMSG 0x890d 0 0 0 0 diff --git a/libc/sysv/consts/SIOCSARP.s b/libc/sysv/consts/SIOCSARP.s new file mode 100644 index 00000000..238141af --- /dev/null +++ b/libc/sysv/consts/SIOCSARP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSARP 0x8955 0 0 0 0 diff --git a/libc/sysv/consts/SIOCSIFADDR.s b/libc/sysv/consts/SIOCSIFADDR.s new file mode 100644 index 00000000..ae2c9069 --- /dev/null +++ b/libc/sysv/consts/SIOCSIFADDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFADDR 0x8916 0x8020690c 0x8020690c 0x8020690c 0 diff --git a/libc/sysv/consts/SIOCSIFBR.s b/libc/sysv/consts/SIOCSIFBR.s new file mode 100644 index 00000000..4a12a8fd --- /dev/null +++ b/libc/sysv/consts/SIOCSIFBR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFBR 0x8941 0 0 0 0 diff --git a/libc/sysv/consts/SIOCSIFBRDADDR.s b/libc/sysv/consts/SIOCSIFBRDADDR.s new file mode 100644 index 00000000..d679b101 --- /dev/null +++ b/libc/sysv/consts/SIOCSIFBRDADDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFBRDADDR 0x891a 0x80206913 0x80206913 0x80206913 0 diff --git a/libc/sysv/consts/SIOCSIFDSTADDR.s b/libc/sysv/consts/SIOCSIFDSTADDR.s new file mode 100644 index 00000000..7788e223 --- /dev/null +++ b/libc/sysv/consts/SIOCSIFDSTADDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFDSTADDR 0x8918 0x8020690e 0x8020690e 0x8020690e 0 diff --git a/libc/sysv/consts/SIOCSIFENCAP.s b/libc/sysv/consts/SIOCSIFENCAP.s new file mode 100644 index 00000000..88c0f046 --- /dev/null +++ b/libc/sysv/consts/SIOCSIFENCAP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFENCAP 0x8926 0 0 0 0 diff --git a/libc/sysv/consts/SIOCSIFFLAGS.s b/libc/sysv/consts/SIOCSIFFLAGS.s new file mode 100644 index 00000000..41d9bc52 --- /dev/null +++ b/libc/sysv/consts/SIOCSIFFLAGS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFFLAGS 0x8914 0x80206910 0x80206910 0x80206910 0 diff --git a/libc/sysv/consts/SIOCSIFHWADDR.s b/libc/sysv/consts/SIOCSIFHWADDR.s new file mode 100644 index 00000000..f1ad854c --- /dev/null +++ b/libc/sysv/consts/SIOCSIFHWADDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFHWADDR 0x8924 0 0 0 0 diff --git a/libc/sysv/consts/SIOCSIFHWBROADCAST.s b/libc/sysv/consts/SIOCSIFHWBROADCAST.s new file mode 100644 index 00000000..bad5efe5 --- /dev/null +++ b/libc/sysv/consts/SIOCSIFHWBROADCAST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFHWBROADCAST 0x8937 0 0 0 0 diff --git a/libc/sysv/consts/SIOCSIFLINK.s b/libc/sysv/consts/SIOCSIFLINK.s new file mode 100644 index 00000000..fedb8a38 --- /dev/null +++ b/libc/sysv/consts/SIOCSIFLINK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFLINK 0x8911 0 0 0 0 diff --git a/libc/sysv/consts/SIOCSIFMAP.s b/libc/sysv/consts/SIOCSIFMAP.s new file mode 100644 index 00000000..e23fb663 --- /dev/null +++ b/libc/sysv/consts/SIOCSIFMAP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFMAP 0x8971 0 0 0 0 diff --git a/libc/sysv/consts/SIOCSIFMEM.s b/libc/sysv/consts/SIOCSIFMEM.s new file mode 100644 index 00000000..afd8a95b --- /dev/null +++ b/libc/sysv/consts/SIOCSIFMEM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFMEM 0x8920 0 0 0 0 diff --git a/libc/sysv/consts/SIOCSIFMETRIC.s b/libc/sysv/consts/SIOCSIFMETRIC.s new file mode 100644 index 00000000..db78ed65 --- /dev/null +++ b/libc/sysv/consts/SIOCSIFMETRIC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFMETRIC 0x891e 0x80206918 0x80206918 0x80206918 0 diff --git a/libc/sysv/consts/SIOCSIFMTU.s b/libc/sysv/consts/SIOCSIFMTU.s new file mode 100644 index 00000000..a18a2b88 --- /dev/null +++ b/libc/sysv/consts/SIOCSIFMTU.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFMTU 0x8922 0x80206934 0x80206934 0x8020697f 0 diff --git a/libc/sysv/consts/SIOCSIFNAME.s b/libc/sysv/consts/SIOCSIFNAME.s new file mode 100644 index 00000000..eac538cd --- /dev/null +++ b/libc/sysv/consts/SIOCSIFNAME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFNAME 0x8923 0 0x80206928 0 0 diff --git a/libc/sysv/consts/SIOCSIFNETMASK.s b/libc/sysv/consts/SIOCSIFNETMASK.s new file mode 100644 index 00000000..33ebc0c5 --- /dev/null +++ b/libc/sysv/consts/SIOCSIFNETMASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFNETMASK 0x891c 0x80206916 0x80206916 0x80206916 0 diff --git a/libc/sysv/consts/SIOCSIFPFLAGS.s b/libc/sysv/consts/SIOCSIFPFLAGS.s new file mode 100644 index 00000000..845b43e2 --- /dev/null +++ b/libc/sysv/consts/SIOCSIFPFLAGS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFPFLAGS 0x8934 0 0 0 0 diff --git a/libc/sysv/consts/SIOCSIFSLAVE.s b/libc/sysv/consts/SIOCSIFSLAVE.s new file mode 100644 index 00000000..0d7e24b0 --- /dev/null +++ b/libc/sysv/consts/SIOCSIFSLAVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFSLAVE 0x8930 0 0 0 0 diff --git a/libc/sysv/consts/SIOCSIFTXQLEN.s b/libc/sysv/consts/SIOCSIFTXQLEN.s new file mode 100644 index 00000000..eeae72f7 --- /dev/null +++ b/libc/sysv/consts/SIOCSIFTXQLEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSIFTXQLEN 0x8943 0 0 0 0 diff --git a/libc/sysv/consts/SIOCSPGRP.s b/libc/sysv/consts/SIOCSPGRP.s new file mode 100644 index 00000000..211bf409 --- /dev/null +++ b/libc/sysv/consts/SIOCSPGRP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSPGRP 0x8902 0x80047308 0x80047308 0x80047308 0 diff --git a/libc/sysv/consts/SIOCSRARP.s b/libc/sysv/consts/SIOCSRARP.s new file mode 100644 index 00000000..229bdbdb --- /dev/null +++ b/libc/sysv/consts/SIOCSRARP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOCSRARP 0x8962 0 0 0 0 diff --git a/libc/sysv/consts/SIOGIFINDEX.s b/libc/sysv/consts/SIOGIFINDEX.s new file mode 100644 index 00000000..f9f40bc0 --- /dev/null +++ b/libc/sysv/consts/SIOGIFINDEX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sio SIOGIFINDEX 0x8933 0 0 0 0 diff --git a/libc/sysv/consts/SI_ASYNCIO.s b/libc/sysv/consts/SI_ASYNCIO.s new file mode 100644 index 00000000..438bf1c7 --- /dev/null +++ b/libc/sysv/consts/SI_ASYNCIO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SI_ASYNCIO -4 0x010004 0x010004 0 0 diff --git a/libc/sysv/consts/SI_ASYNCNL.s b/libc/sysv/consts/SI_ASYNCNL.s new file mode 100644 index 00000000..3dc927f0 --- /dev/null +++ b/libc/sysv/consts/SI_ASYNCNL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SI_ASYNCNL -60 0 0 0 0 diff --git a/libc/sysv/consts/SI_KERNEL.s b/libc/sysv/consts/SI_KERNEL.s new file mode 100644 index 00000000..db25b059 --- /dev/null +++ b/libc/sysv/consts/SI_KERNEL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SI_KERNEL 0x80 0 0x010006 0 0 diff --git a/libc/sysv/consts/SI_LOAD_SHIFT.s b/libc/sysv/consts/SI_LOAD_SHIFT.s new file mode 100644 index 00000000..3366521f --- /dev/null +++ b/libc/sysv/consts/SI_LOAD_SHIFT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SI_LOAD_SHIFT 0x10 0 0 0 0 diff --git a/libc/sysv/consts/SI_MESGQ.s b/libc/sysv/consts/SI_MESGQ.s new file mode 100644 index 00000000..021115ac --- /dev/null +++ b/libc/sysv/consts/SI_MESGQ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SI_MESGQ -3 0x010005 0x010005 0 0 diff --git a/libc/sysv/consts/SI_QUEUE.s b/libc/sysv/consts/SI_QUEUE.s new file mode 100644 index 00000000..23e73d2a --- /dev/null +++ b/libc/sysv/consts/SI_QUEUE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SI_QUEUE -1 0x010002 0x010002 -2 0 diff --git a/libc/sysv/consts/SI_SIGIO.s b/libc/sysv/consts/SI_SIGIO.s new file mode 100644 index 00000000..0d518e88 --- /dev/null +++ b/libc/sysv/consts/SI_SIGIO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SI_SIGIO -5 0 0 0 0 diff --git a/libc/sysv/consts/SI_TIMER.s b/libc/sysv/consts/SI_TIMER.s new file mode 100644 index 00000000..53371f17 --- /dev/null +++ b/libc/sysv/consts/SI_TIMER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SI_TIMER -2 0x010003 0x010003 -3 0 diff --git a/libc/sysv/consts/SI_TKILL.s b/libc/sysv/consts/SI_TKILL.s new file mode 100644 index 00000000..3160046e --- /dev/null +++ b/libc/sysv/consts/SI_TKILL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SI_TKILL -6 0 0 0 0 diff --git a/libc/sysv/consts/SI_USER.s b/libc/sysv/consts/SI_USER.s new file mode 100644 index 00000000..8159c151 --- /dev/null +++ b/libc/sysv/consts/SI_USER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SI_USER 0 0x010001 0x010001 0 0 diff --git a/libc/sysv/consts/SLIPDISC.s b/libc/sysv/consts/SLIPDISC.s new file mode 100644 index 00000000..275be5d8 --- /dev/null +++ b/libc/sysv/consts/SLIPDISC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios SLIPDISC 0 0x4 0x4 0x4 -1 diff --git a/libc/sysv/consts/SOCK_CLOEXEC.s b/libc/sysv/consts/SOCK_CLOEXEC.s new file mode 100644 index 00000000..001a21ed --- /dev/null +++ b/libc/sysv/consts/SOCK_CLOEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sock SOCK_CLOEXEC 0x080000 0x080000 0x10000000 0x8000 0x80 diff --git a/libc/sysv/consts/SOCK_DCCP.s b/libc/sysv/consts/SOCK_DCCP.s new file mode 100644 index 00000000..8793b3ae --- /dev/null +++ b/libc/sysv/consts/SOCK_DCCP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sock SOCK_DCCP 6 0 0 0 0 diff --git a/libc/sysv/consts/SOCK_DGRAM.s b/libc/sysv/consts/SOCK_DGRAM.s new file mode 100644 index 00000000..53cefd09 --- /dev/null +++ b/libc/sysv/consts/SOCK_DGRAM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sock SOCK_DGRAM 2 2 2 2 2 diff --git a/libc/sysv/consts/SOCK_NONBLOCK.s b/libc/sysv/consts/SOCK_NONBLOCK.s new file mode 100644 index 00000000..2ab79e6e --- /dev/null +++ b/libc/sysv/consts/SOCK_NONBLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sock SOCK_NONBLOCK 0x0800 0x0800 0x20000000 0x4000 0x0800 diff --git a/libc/sysv/consts/SOCK_PACKET.s b/libc/sysv/consts/SOCK_PACKET.s new file mode 100644 index 00000000..092a43fb --- /dev/null +++ b/libc/sysv/consts/SOCK_PACKET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sock SOCK_PACKET 10 0 0 0 0 diff --git a/libc/sysv/consts/SOCK_RAW.s b/libc/sysv/consts/SOCK_RAW.s new file mode 100644 index 00000000..e2cb216d --- /dev/null +++ b/libc/sysv/consts/SOCK_RAW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sock SOCK_RAW 3 3 3 3 3 diff --git a/libc/sysv/consts/SOCK_RDM.s b/libc/sysv/consts/SOCK_RDM.s new file mode 100644 index 00000000..d70ee75f --- /dev/null +++ b/libc/sysv/consts/SOCK_RDM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sock SOCK_RDM 4 4 4 4 4 diff --git a/libc/sysv/consts/SOCK_SEQPACKET.s b/libc/sysv/consts/SOCK_SEQPACKET.s new file mode 100644 index 00000000..1d8314c3 --- /dev/null +++ b/libc/sysv/consts/SOCK_SEQPACKET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sock SOCK_SEQPACKET 5 5 5 5 5 diff --git a/libc/sysv/consts/SOCK_STREAM.s b/libc/sysv/consts/SOCK_STREAM.s new file mode 100644 index 00000000..541a4dfa --- /dev/null +++ b/libc/sysv/consts/SOCK_STREAM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sock SOCK_STREAM 1 1 1 1 1 diff --git a/libc/sysv/consts/SOL_AAL.s b/libc/sysv/consts/SOL_AAL.s new file mode 100644 index 00000000..6064525e --- /dev/null +++ b/libc/sysv/consts/SOL_AAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_AAL 265 0 0 0 0 diff --git a/libc/sysv/consts/SOL_ALG.s b/libc/sysv/consts/SOL_ALG.s new file mode 100644 index 00000000..1abc6d5a --- /dev/null +++ b/libc/sysv/consts/SOL_ALG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_ALG 279 0 0 0 0 diff --git a/libc/sysv/consts/SOL_ATM.s b/libc/sysv/consts/SOL_ATM.s new file mode 100644 index 00000000..a314d7ba --- /dev/null +++ b/libc/sysv/consts/SOL_ATM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_ATM 264 0 0 0 0 diff --git a/libc/sysv/consts/SOL_BLUETOOTH.s b/libc/sysv/consts/SOL_BLUETOOTH.s new file mode 100644 index 00000000..58e9e802 --- /dev/null +++ b/libc/sysv/consts/SOL_BLUETOOTH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_BLUETOOTH 274 0 0 0 0 diff --git a/libc/sysv/consts/SOL_CAIF.s b/libc/sysv/consts/SOL_CAIF.s new file mode 100644 index 00000000..81921176 --- /dev/null +++ b/libc/sysv/consts/SOL_CAIF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_CAIF 278 0 0 0 0 diff --git a/libc/sysv/consts/SOL_DCCP.s b/libc/sysv/consts/SOL_DCCP.s new file mode 100644 index 00000000..73eec471 --- /dev/null +++ b/libc/sysv/consts/SOL_DCCP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_DCCP 269 0 0 0 0 diff --git a/libc/sysv/consts/SOL_DECNET.s b/libc/sysv/consts/SOL_DECNET.s new file mode 100644 index 00000000..4fc51acd --- /dev/null +++ b/libc/sysv/consts/SOL_DECNET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_DECNET 261 0 0 0 0 diff --git a/libc/sysv/consts/SOL_ICMPV6.s b/libc/sysv/consts/SOL_ICMPV6.s new file mode 100644 index 00000000..0d516de3 --- /dev/null +++ b/libc/sysv/consts/SOL_ICMPV6.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_ICMPV6 58 0 0 0 0 diff --git a/libc/sysv/consts/SOL_IP.s b/libc/sysv/consts/SOL_IP.s new file mode 100644 index 00000000..25886172 --- /dev/null +++ b/libc/sysv/consts/SOL_IP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_IP 0 0 0 0 0 diff --git a/libc/sysv/consts/SOL_IPV6.s b/libc/sysv/consts/SOL_IPV6.s new file mode 100644 index 00000000..a464ad56 --- /dev/null +++ b/libc/sysv/consts/SOL_IPV6.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_IPV6 41 0 0 0 0 diff --git a/libc/sysv/consts/SOL_IRDA.s b/libc/sysv/consts/SOL_IRDA.s new file mode 100644 index 00000000..1a3a1ce7 --- /dev/null +++ b/libc/sysv/consts/SOL_IRDA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_IRDA 266 0 0 0 0 diff --git a/libc/sysv/consts/SOL_IUCV.s b/libc/sysv/consts/SOL_IUCV.s new file mode 100644 index 00000000..47d21502 --- /dev/null +++ b/libc/sysv/consts/SOL_IUCV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_IUCV 277 0 0 0 0 diff --git a/libc/sysv/consts/SOL_KCM.s b/libc/sysv/consts/SOL_KCM.s new file mode 100644 index 00000000..3d15625c --- /dev/null +++ b/libc/sysv/consts/SOL_KCM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_KCM 281 0 0 0 0 diff --git a/libc/sysv/consts/SOL_LLC.s b/libc/sysv/consts/SOL_LLC.s new file mode 100644 index 00000000..bcf9a459 --- /dev/null +++ b/libc/sysv/consts/SOL_LLC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_LLC 268 0 0 0 0 diff --git a/libc/sysv/consts/SOL_NETBEUI.s b/libc/sysv/consts/SOL_NETBEUI.s new file mode 100644 index 00000000..6ceab1e9 --- /dev/null +++ b/libc/sysv/consts/SOL_NETBEUI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_NETBEUI 267 0 0 0 0 diff --git a/libc/sysv/consts/SOL_NETLINK.s b/libc/sysv/consts/SOL_NETLINK.s new file mode 100644 index 00000000..306930be --- /dev/null +++ b/libc/sysv/consts/SOL_NETLINK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_NETLINK 270 0 0 0 0 diff --git a/libc/sysv/consts/SOL_NFC.s b/libc/sysv/consts/SOL_NFC.s new file mode 100644 index 00000000..5a9bbfed --- /dev/null +++ b/libc/sysv/consts/SOL_NFC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_NFC 280 0 0 0 0 diff --git a/libc/sysv/consts/SOL_PACKET.s b/libc/sysv/consts/SOL_PACKET.s new file mode 100644 index 00000000..55567308 --- /dev/null +++ b/libc/sysv/consts/SOL_PACKET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_PACKET 263 0 0 0 0 diff --git a/libc/sysv/consts/SOL_PNPIPE.s b/libc/sysv/consts/SOL_PNPIPE.s new file mode 100644 index 00000000..c3a8e7dc --- /dev/null +++ b/libc/sysv/consts/SOL_PNPIPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_PNPIPE 275 0 0 0 0 diff --git a/libc/sysv/consts/SOL_PPPOL2TP.s b/libc/sysv/consts/SOL_PPPOL2TP.s new file mode 100644 index 00000000..04b984b8 --- /dev/null +++ b/libc/sysv/consts/SOL_PPPOL2TP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_PPPOL2TP 273 0 0 0 0 diff --git a/libc/sysv/consts/SOL_RAW.s b/libc/sysv/consts/SOL_RAW.s new file mode 100644 index 00000000..ec01f99a --- /dev/null +++ b/libc/sysv/consts/SOL_RAW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_RAW 255 0 0 0 0 diff --git a/libc/sysv/consts/SOL_RDS.s b/libc/sysv/consts/SOL_RDS.s new file mode 100644 index 00000000..50947278 --- /dev/null +++ b/libc/sysv/consts/SOL_RDS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_RDS 276 0 0 0 0 diff --git a/libc/sysv/consts/SOL_RXRPC.s b/libc/sysv/consts/SOL_RXRPC.s new file mode 100644 index 00000000..d068f0c0 --- /dev/null +++ b/libc/sysv/consts/SOL_RXRPC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_RXRPC 272 0 0 0 0 diff --git a/libc/sysv/consts/SOL_SOCKET.s b/libc/sysv/consts/SOL_SOCKET.s new file mode 100644 index 00000000..854a42af --- /dev/null +++ b/libc/sysv/consts/SOL_SOCKET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_SOCKET 1 0xffff 0xffff 0xffff 0xffff diff --git a/libc/sysv/consts/SOL_TCP.s b/libc/sysv/consts/SOL_TCP.s new file mode 100644 index 00000000..fc721924 --- /dev/null +++ b/libc/sysv/consts/SOL_TCP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_TCP 6 0 0 0 0 diff --git a/libc/sysv/consts/SOL_TIPC.s b/libc/sysv/consts/SOL_TIPC.s new file mode 100644 index 00000000..a7428ac2 --- /dev/null +++ b/libc/sysv/consts/SOL_TIPC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_TIPC 271 0 0 0 0 diff --git a/libc/sysv/consts/SOL_UDP.s b/libc/sysv/consts/SOL_UDP.s new file mode 100644 index 00000000..0c321632 --- /dev/null +++ b/libc/sysv/consts/SOL_UDP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_UDP 17 0 0 0 0 diff --git a/libc/sysv/consts/SOL_X25.s b/libc/sysv/consts/SOL_X25.s new file mode 100644 index 00000000..f2930acd --- /dev/null +++ b/libc/sysv/consts/SOL_X25.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon sol SOL_X25 262 0 0 0 0 diff --git a/libc/sysv/consts/SOMAXCONN.s b/libc/sysv/consts/SOMAXCONN.s new file mode 100644 index 00000000..73f63945 --- /dev/null +++ b/libc/sysv/consts/SOMAXCONN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SOMAXCONN 0x80 0x80 0x80 0x80 0x7fffffff diff --git a/libc/sysv/consts/SO_ACCEPTCONN.s b/libc/sysv/consts/SO_ACCEPTCONN.s new file mode 100644 index 00000000..b377ebea --- /dev/null +++ b/libc/sysv/consts/SO_ACCEPTCONN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_ACCEPTCONN 30 2 2 2 2 diff --git a/libc/sysv/consts/SO_ATTACH_BPF.s b/libc/sysv/consts/SO_ATTACH_BPF.s new file mode 100644 index 00000000..323cb580 --- /dev/null +++ b/libc/sysv/consts/SO_ATTACH_BPF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_ATTACH_BPF 50 0 0 0 0 diff --git a/libc/sysv/consts/SO_ATTACH_FILTER.s b/libc/sysv/consts/SO_ATTACH_FILTER.s new file mode 100644 index 00000000..e7d9f68d --- /dev/null +++ b/libc/sysv/consts/SO_ATTACH_FILTER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_ATTACH_FILTER 26 0 0 0 0 diff --git a/libc/sysv/consts/SO_ATTACH_REUSEPORT_CBPF.s b/libc/sysv/consts/SO_ATTACH_REUSEPORT_CBPF.s new file mode 100644 index 00000000..8c74dba6 --- /dev/null +++ b/libc/sysv/consts/SO_ATTACH_REUSEPORT_CBPF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_ATTACH_REUSEPORT_CBPF 51 0 0 0 0 diff --git a/libc/sysv/consts/SO_ATTACH_REUSEPORT_EBPF.s b/libc/sysv/consts/SO_ATTACH_REUSEPORT_EBPF.s new file mode 100644 index 00000000..c6622194 --- /dev/null +++ b/libc/sysv/consts/SO_ATTACH_REUSEPORT_EBPF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_ATTACH_REUSEPORT_EBPF 52 0 0 0 0 diff --git a/libc/sysv/consts/SO_BINDTODEVICE.s b/libc/sysv/consts/SO_BINDTODEVICE.s new file mode 100644 index 00000000..b6c824ff --- /dev/null +++ b/libc/sysv/consts/SO_BINDTODEVICE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_BINDTODEVICE 25 0 0 0 0 diff --git a/libc/sysv/consts/SO_BPF_EXTENSIONS.s b/libc/sysv/consts/SO_BPF_EXTENSIONS.s new file mode 100644 index 00000000..55d46986 --- /dev/null +++ b/libc/sysv/consts/SO_BPF_EXTENSIONS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_BPF_EXTENSIONS 48 0 0 0 0 diff --git a/libc/sysv/consts/SO_BROADCAST.s b/libc/sysv/consts/SO_BROADCAST.s new file mode 100644 index 00000000..e7a5cef4 --- /dev/null +++ b/libc/sysv/consts/SO_BROADCAST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_BROADCAST 6 0x20 0x20 0x20 0x20 diff --git a/libc/sysv/consts/SO_BSDCOMPAT.s b/libc/sysv/consts/SO_BSDCOMPAT.s new file mode 100644 index 00000000..1ca56c25 --- /dev/null +++ b/libc/sysv/consts/SO_BSDCOMPAT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_BSDCOMPAT 14 0 0 0 0 diff --git a/libc/sysv/consts/SO_BUSY_POLL.s b/libc/sysv/consts/SO_BUSY_POLL.s new file mode 100644 index 00000000..d9ac8d1f --- /dev/null +++ b/libc/sysv/consts/SO_BUSY_POLL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_BUSY_POLL 46 0 0 0 0 diff --git a/libc/sysv/consts/SO_CNX_ADVICE.s b/libc/sysv/consts/SO_CNX_ADVICE.s new file mode 100644 index 00000000..ef8742b5 --- /dev/null +++ b/libc/sysv/consts/SO_CNX_ADVICE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_CNX_ADVICE 53 0 0 0 0 diff --git a/libc/sysv/consts/SO_DEBUG.s b/libc/sysv/consts/SO_DEBUG.s new file mode 100644 index 00000000..7ef09d66 --- /dev/null +++ b/libc/sysv/consts/SO_DEBUG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_DEBUG 1 1 1 1 1 diff --git a/libc/sysv/consts/SO_DETACH_BPF.s b/libc/sysv/consts/SO_DETACH_BPF.s new file mode 100644 index 00000000..ed1a4feb --- /dev/null +++ b/libc/sysv/consts/SO_DETACH_BPF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_DETACH_BPF 27 0 0 0 0 diff --git a/libc/sysv/consts/SO_DETACH_FILTER.s b/libc/sysv/consts/SO_DETACH_FILTER.s new file mode 100644 index 00000000..e90bd1ce --- /dev/null +++ b/libc/sysv/consts/SO_DETACH_FILTER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_DETACH_FILTER 27 0 0 0 0 diff --git a/libc/sysv/consts/SO_DOMAIN.s b/libc/sysv/consts/SO_DOMAIN.s new file mode 100644 index 00000000..44409a84 --- /dev/null +++ b/libc/sysv/consts/SO_DOMAIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_DOMAIN 39 0 0x1019 0 0 diff --git a/libc/sysv/consts/SO_DONTROUTE.s b/libc/sysv/consts/SO_DONTROUTE.s new file mode 100644 index 00000000..88dd2266 --- /dev/null +++ b/libc/sysv/consts/SO_DONTROUTE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_DONTROUTE 5 0x10 0x10 0x10 0x10 diff --git a/libc/sysv/consts/SO_ERROR.s b/libc/sysv/consts/SO_ERROR.s new file mode 100644 index 00000000..a525771c --- /dev/null +++ b/libc/sysv/consts/SO_ERROR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_ERROR 4 0x1007 0x1007 0x1007 0x1007 diff --git a/libc/sysv/consts/SO_EXCLUSIVEADDRUSE.s b/libc/sysv/consts/SO_EXCLUSIVEADDRUSE.s new file mode 100644 index 00000000..7c4f540e --- /dev/null +++ b/libc/sysv/consts/SO_EXCLUSIVEADDRUSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_EXCLUSIVEADDRUSE -1 -1 -1 -1 0xfffffffb diff --git a/libc/sysv/consts/SO_GET_FILTER.s b/libc/sysv/consts/SO_GET_FILTER.s new file mode 100644 index 00000000..8a1586b5 --- /dev/null +++ b/libc/sysv/consts/SO_GET_FILTER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_GET_FILTER 26 0 0 0 0 diff --git a/libc/sysv/consts/SO_INCOMING_CPU.s b/libc/sysv/consts/SO_INCOMING_CPU.s new file mode 100644 index 00000000..9d3565de --- /dev/null +++ b/libc/sysv/consts/SO_INCOMING_CPU.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_INCOMING_CPU 49 0 0 0 0 diff --git a/libc/sysv/consts/SO_KEEPALIVE.s b/libc/sysv/consts/SO_KEEPALIVE.s new file mode 100644 index 00000000..58dafcae --- /dev/null +++ b/libc/sysv/consts/SO_KEEPALIVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_KEEPALIVE 9 8 8 8 8 diff --git a/libc/sysv/consts/SO_LINGER.s b/libc/sysv/consts/SO_LINGER.s new file mode 100644 index 00000000..8fa70192 --- /dev/null +++ b/libc/sysv/consts/SO_LINGER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_LINGER 13 0x80 0x80 0x80 0x80 diff --git a/libc/sysv/consts/SO_LOCK_FILTER.s b/libc/sysv/consts/SO_LOCK_FILTER.s new file mode 100644 index 00000000..0594486b --- /dev/null +++ b/libc/sysv/consts/SO_LOCK_FILTER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_LOCK_FILTER 44 0 0 0 0 diff --git a/libc/sysv/consts/SO_MARK.s b/libc/sysv/consts/SO_MARK.s new file mode 100644 index 00000000..fdc8143b --- /dev/null +++ b/libc/sysv/consts/SO_MARK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_MARK 36 0 0 0 0 diff --git a/libc/sysv/consts/SO_MAX_PACING_RATE.s b/libc/sysv/consts/SO_MAX_PACING_RATE.s new file mode 100644 index 00000000..ecc16172 --- /dev/null +++ b/libc/sysv/consts/SO_MAX_PACING_RATE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_MAX_PACING_RATE 47 0 0x1018 0 0 diff --git a/libc/sysv/consts/SO_NOFCS.s b/libc/sysv/consts/SO_NOFCS.s new file mode 100644 index 00000000..061a0103 --- /dev/null +++ b/libc/sysv/consts/SO_NOFCS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_NOFCS 43 0 0 0 0 diff --git a/libc/sysv/consts/SO_NO_CHECK.s b/libc/sysv/consts/SO_NO_CHECK.s new file mode 100644 index 00000000..96ec45a1 --- /dev/null +++ b/libc/sysv/consts/SO_NO_CHECK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_NO_CHECK 11 0 0 0 0 diff --git a/libc/sysv/consts/SO_OOBINLINE.s b/libc/sysv/consts/SO_OOBINLINE.s new file mode 100644 index 00000000..e4d03093 --- /dev/null +++ b/libc/sysv/consts/SO_OOBINLINE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_OOBINLINE 10 0x0100 0x0100 0x0100 0x0100 diff --git a/libc/sysv/consts/SO_PASSCRED.s b/libc/sysv/consts/SO_PASSCRED.s new file mode 100644 index 00000000..a4aaf66f --- /dev/null +++ b/libc/sysv/consts/SO_PASSCRED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_PASSCRED 0x10 0 0 0 0 diff --git a/libc/sysv/consts/SO_PASSSEC.s b/libc/sysv/consts/SO_PASSSEC.s new file mode 100644 index 00000000..e1780378 --- /dev/null +++ b/libc/sysv/consts/SO_PASSSEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_PASSSEC 34 0 0 0 0 diff --git a/libc/sysv/consts/SO_PEEK_OFF.s b/libc/sysv/consts/SO_PEEK_OFF.s new file mode 100644 index 00000000..1912a6b6 --- /dev/null +++ b/libc/sysv/consts/SO_PEEK_OFF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_PEEK_OFF 42 0 0 0 0 diff --git a/libc/sysv/consts/SO_PEERCRED.s b/libc/sysv/consts/SO_PEERCRED.s new file mode 100644 index 00000000..b4bbc831 --- /dev/null +++ b/libc/sysv/consts/SO_PEERCRED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_PEERCRED 17 0 0 0x1022 0 diff --git a/libc/sysv/consts/SO_PEERNAME.s b/libc/sysv/consts/SO_PEERNAME.s new file mode 100644 index 00000000..8e163d71 --- /dev/null +++ b/libc/sysv/consts/SO_PEERNAME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_PEERNAME 28 0 0 0 0 diff --git a/libc/sysv/consts/SO_PEERSEC.s b/libc/sysv/consts/SO_PEERSEC.s new file mode 100644 index 00000000..ff5eccd4 --- /dev/null +++ b/libc/sysv/consts/SO_PEERSEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_PEERSEC 31 0 0 0 0 diff --git a/libc/sysv/consts/SO_PRIORITY.s b/libc/sysv/consts/SO_PRIORITY.s new file mode 100644 index 00000000..6550adfb --- /dev/null +++ b/libc/sysv/consts/SO_PRIORITY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_PRIORITY 12 0 0 0 0 diff --git a/libc/sysv/consts/SO_PROTOCOL.s b/libc/sysv/consts/SO_PROTOCOL.s new file mode 100644 index 00000000..f067605c --- /dev/null +++ b/libc/sysv/consts/SO_PROTOCOL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_PROTOCOL 38 0 0x1016 0 0 diff --git a/libc/sysv/consts/SO_RCVBUF.s b/libc/sysv/consts/SO_RCVBUF.s new file mode 100644 index 00000000..367c3331 --- /dev/null +++ b/libc/sysv/consts/SO_RCVBUF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_RCVBUF 8 0x1002 0x1002 0x1002 0x1002 diff --git a/libc/sysv/consts/SO_RCVBUFFORCE.s b/libc/sysv/consts/SO_RCVBUFFORCE.s new file mode 100644 index 00000000..665fb0f1 --- /dev/null +++ b/libc/sysv/consts/SO_RCVBUFFORCE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_RCVBUFFORCE 33 0 0 0 0 diff --git a/libc/sysv/consts/SO_RCVLOWAT.s b/libc/sysv/consts/SO_RCVLOWAT.s new file mode 100644 index 00000000..4b7105d4 --- /dev/null +++ b/libc/sysv/consts/SO_RCVLOWAT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_RCVLOWAT 18 0x1004 0x1004 0x1004 0x1004 diff --git a/libc/sysv/consts/SO_RCVTIMEO.s b/libc/sysv/consts/SO_RCVTIMEO.s new file mode 100644 index 00000000..317777f2 --- /dev/null +++ b/libc/sysv/consts/SO_RCVTIMEO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_RCVTIMEO 20 0x1006 0x1006 0x1006 0x1006 diff --git a/libc/sysv/consts/SO_REUSEADDR.s b/libc/sysv/consts/SO_REUSEADDR.s new file mode 100644 index 00000000..503f3b27 --- /dev/null +++ b/libc/sysv/consts/SO_REUSEADDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_REUSEADDR 2 4 4 4 -1 diff --git a/libc/sysv/consts/SO_REUSEPORT.s b/libc/sysv/consts/SO_REUSEPORT.s new file mode 100644 index 00000000..bc3edc8c --- /dev/null +++ b/libc/sysv/consts/SO_REUSEPORT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_REUSEPORT 15 0x0200 0x0200 0x0200 4 diff --git a/libc/sysv/consts/SO_RXQ_OVFL.s b/libc/sysv/consts/SO_RXQ_OVFL.s new file mode 100644 index 00000000..d9ff0ca7 --- /dev/null +++ b/libc/sysv/consts/SO_RXQ_OVFL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_RXQ_OVFL 40 0 0 0 0 diff --git a/libc/sysv/consts/SO_SECURITY_AUTHENTICATION.s b/libc/sysv/consts/SO_SECURITY_AUTHENTICATION.s new file mode 100644 index 00000000..eda21f2b --- /dev/null +++ b/libc/sysv/consts/SO_SECURITY_AUTHENTICATION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_SECURITY_AUTHENTICATION 22 0 0 0 0 diff --git a/libc/sysv/consts/SO_SECURITY_ENCRYPTION_NETWORK.s b/libc/sysv/consts/SO_SECURITY_ENCRYPTION_NETWORK.s new file mode 100644 index 00000000..e2107e2c --- /dev/null +++ b/libc/sysv/consts/SO_SECURITY_ENCRYPTION_NETWORK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_SECURITY_ENCRYPTION_NETWORK 24 0 0 0 0 diff --git a/libc/sysv/consts/SO_SECURITY_ENCRYPTION_TRANSPORT.s b/libc/sysv/consts/SO_SECURITY_ENCRYPTION_TRANSPORT.s new file mode 100644 index 00000000..ce16be29 --- /dev/null +++ b/libc/sysv/consts/SO_SECURITY_ENCRYPTION_TRANSPORT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_SECURITY_ENCRYPTION_TRANSPORT 23 0 0 0 0 diff --git a/libc/sysv/consts/SO_SELECT_ERR_QUEUE.s b/libc/sysv/consts/SO_SELECT_ERR_QUEUE.s new file mode 100644 index 00000000..13fea5cc --- /dev/null +++ b/libc/sysv/consts/SO_SELECT_ERR_QUEUE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_SELECT_ERR_QUEUE 45 0 0 0 0 diff --git a/libc/sysv/consts/SO_SNDBUF.s b/libc/sysv/consts/SO_SNDBUF.s new file mode 100644 index 00000000..d9ceafa1 --- /dev/null +++ b/libc/sysv/consts/SO_SNDBUF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_SNDBUF 7 0x1001 0x1001 0x1001 0x1001 diff --git a/libc/sysv/consts/SO_SNDBUFFORCE.s b/libc/sysv/consts/SO_SNDBUFFORCE.s new file mode 100644 index 00000000..90e65b1a --- /dev/null +++ b/libc/sysv/consts/SO_SNDBUFFORCE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_SNDBUFFORCE 0x20 0 0 0 0 diff --git a/libc/sysv/consts/SO_SNDLOWAT.s b/libc/sysv/consts/SO_SNDLOWAT.s new file mode 100644 index 00000000..708a693e --- /dev/null +++ b/libc/sysv/consts/SO_SNDLOWAT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_SNDLOWAT 19 0x1003 0x1003 0x1003 0x1003 diff --git a/libc/sysv/consts/SO_SNDTIMEO.s b/libc/sysv/consts/SO_SNDTIMEO.s new file mode 100644 index 00000000..f528c5ee --- /dev/null +++ b/libc/sysv/consts/SO_SNDTIMEO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_SNDTIMEO 21 0x1005 0x1005 0x1005 0x1005 diff --git a/libc/sysv/consts/SO_TIMESTAMP.s b/libc/sysv/consts/SO_TIMESTAMP.s new file mode 100644 index 00000000..0b130c1b --- /dev/null +++ b/libc/sysv/consts/SO_TIMESTAMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_TIMESTAMP 29 0x0400 0x0400 0x0800 0 diff --git a/libc/sysv/consts/SO_TIMESTAMPING.s b/libc/sysv/consts/SO_TIMESTAMPING.s new file mode 100644 index 00000000..039a9078 --- /dev/null +++ b/libc/sysv/consts/SO_TIMESTAMPING.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_TIMESTAMPING 37 0 0 0 0 diff --git a/libc/sysv/consts/SO_TIMESTAMPNS.s b/libc/sysv/consts/SO_TIMESTAMPNS.s new file mode 100644 index 00000000..bb7c021c --- /dev/null +++ b/libc/sysv/consts/SO_TIMESTAMPNS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_TIMESTAMPNS 35 0 0 0 0 diff --git a/libc/sysv/consts/SO_TYPE.s b/libc/sysv/consts/SO_TYPE.s new file mode 100644 index 00000000..e03d84d5 --- /dev/null +++ b/libc/sysv/consts/SO_TYPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_TYPE 3 0x1008 0x1008 0x1008 0x1008 diff --git a/libc/sysv/consts/SO_WIFI_STATUS.s b/libc/sysv/consts/SO_WIFI_STATUS.s new file mode 100644 index 00000000..51aac8ad --- /dev/null +++ b/libc/sysv/consts/SO_WIFI_STATUS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon so SO_WIFI_STATUS 41 0 0 0 0 diff --git a/libc/sysv/consts/SPACE.s b/libc/sysv/consts/SPACE.s new file mode 100644 index 00000000..0814ebcc --- /dev/null +++ b/libc/sysv/consts/SPACE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SPACE 17 0 0 0 0 diff --git a/libc/sysv/consts/SPLICE_F_GIFT.s b/libc/sysv/consts/SPLICE_F_GIFT.s new file mode 100644 index 00000000..c3fc7cb8 --- /dev/null +++ b/libc/sysv/consts/SPLICE_F_GIFT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon splice SPLICE_F_GIFT 8 0 0 0 0 diff --git a/libc/sysv/consts/SPLICE_F_MORE.s b/libc/sysv/consts/SPLICE_F_MORE.s new file mode 100644 index 00000000..4abf5354 --- /dev/null +++ b/libc/sysv/consts/SPLICE_F_MORE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon splice SPLICE_F_MORE 4 0 0 0 0 diff --git a/libc/sysv/consts/SPLICE_F_MOVE.s b/libc/sysv/consts/SPLICE_F_MOVE.s new file mode 100644 index 00000000..fec501b6 --- /dev/null +++ b/libc/sysv/consts/SPLICE_F_MOVE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon splice SPLICE_F_MOVE 1 0 0 0 0 diff --git a/libc/sysv/consts/SPLICE_F_NONBLOCK.s b/libc/sysv/consts/SPLICE_F_NONBLOCK.s new file mode 100644 index 00000000..7c5fee50 --- /dev/null +++ b/libc/sysv/consts/SPLICE_F_NONBLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon splice SPLICE_F_NONBLOCK 2 0 0 0 0 diff --git a/libc/sysv/consts/SS_DISABLE.s b/libc/sysv/consts/SS_DISABLE.s new file mode 100644 index 00000000..ed9195ee --- /dev/null +++ b/libc/sysv/consts/SS_DISABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SS_DISABLE 2 4 4 4 0 diff --git a/libc/sysv/consts/SS_ONSTACK.s b/libc/sysv/consts/SS_ONSTACK.s new file mode 100644 index 00000000..62f06488 --- /dev/null +++ b/libc/sysv/consts/SS_ONSTACK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SS_ONSTACK 1 1 1 1 0 diff --git a/libc/sysv/consts/START_STOP.s b/libc/sysv/consts/START_STOP.s new file mode 100644 index 00000000..573ff5a1 --- /dev/null +++ b/libc/sysv/consts/START_STOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc START_STOP 27 0 0 0 0 diff --git a/libc/sysv/consts/STATUS_MASK.s b/libc/sysv/consts/STATUS_MASK.s new file mode 100644 index 00000000..445ff1f9 --- /dev/null +++ b/libc/sysv/consts/STATUS_MASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc STATUS_MASK 62 0 0 0 0 diff --git a/libc/sysv/consts/STA_RONLY.s b/libc/sysv/consts/STA_RONLY.s new file mode 100644 index 00000000..a2e06350 --- /dev/null +++ b/libc/sysv/consts/STA_RONLY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc STA_RONLY 0xff00 0 0xff00 0 0 diff --git a/libc/sysv/consts/STICKY_TIMEOUTS.s b/libc/sysv/consts/STICKY_TIMEOUTS.s new file mode 100644 index 00000000..83e9fbb2 --- /dev/null +++ b/libc/sysv/consts/STICKY_TIMEOUTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon prsnlty STICKY_TIMEOUTS 0x4000000 -1 -1 -1 -1 diff --git a/libc/sysv/consts/STRIPDISC.s b/libc/sysv/consts/STRIPDISC.s new file mode 100644 index 00000000..017bd418 --- /dev/null +++ b/libc/sysv/consts/STRIPDISC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios STRIPDISC 0 0 0 0x6 -1 diff --git a/libc/sysv/consts/STRU_F.s b/libc/sysv/consts/STRU_F.s new file mode 100644 index 00000000..b995ce4f --- /dev/null +++ b/libc/sysv/consts/STRU_F.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc STRU_F 1 1 1 1 0 diff --git a/libc/sysv/consts/STRU_P.s b/libc/sysv/consts/STRU_P.s new file mode 100644 index 00000000..372dc373 --- /dev/null +++ b/libc/sysv/consts/STRU_P.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc STRU_P 3 3 3 3 0 diff --git a/libc/sysv/consts/STRU_R.s b/libc/sysv/consts/STRU_R.s new file mode 100644 index 00000000..71814a2e --- /dev/null +++ b/libc/sysv/consts/STRU_R.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc STRU_R 2 2 2 2 0 diff --git a/libc/sysv/consts/ST_APPEND.s b/libc/sysv/consts/ST_APPEND.s new file mode 100644 index 00000000..4030aa76 --- /dev/null +++ b/libc/sysv/consts/ST_APPEND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ST_APPEND 0x0100 0 0 0 0 diff --git a/libc/sysv/consts/ST_IMMUTABLE.s b/libc/sysv/consts/ST_IMMUTABLE.s new file mode 100644 index 00000000..17cef171 --- /dev/null +++ b/libc/sysv/consts/ST_IMMUTABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ST_IMMUTABLE 0x0200 0 0 0 0 diff --git a/libc/sysv/consts/ST_MANDLOCK.s b/libc/sysv/consts/ST_MANDLOCK.s new file mode 100644 index 00000000..a2fce105 --- /dev/null +++ b/libc/sysv/consts/ST_MANDLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ST_MANDLOCK 0x40 0 0 0 0 diff --git a/libc/sysv/consts/ST_NOATIME.s b/libc/sysv/consts/ST_NOATIME.s new file mode 100644 index 00000000..e6ed74e2 --- /dev/null +++ b/libc/sysv/consts/ST_NOATIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ST_NOATIME 0x0400 0 0 0 0 diff --git a/libc/sysv/consts/ST_NODEV.s b/libc/sysv/consts/ST_NODEV.s new file mode 100644 index 00000000..2a1b081a --- /dev/null +++ b/libc/sysv/consts/ST_NODEV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ST_NODEV 4 0 0 0 0 diff --git a/libc/sysv/consts/ST_NODIRATIME.s b/libc/sysv/consts/ST_NODIRATIME.s new file mode 100644 index 00000000..f74791c4 --- /dev/null +++ b/libc/sysv/consts/ST_NODIRATIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ST_NODIRATIME 0x0800 0 0 0 0 diff --git a/libc/sysv/consts/ST_NOEXEC.s b/libc/sysv/consts/ST_NOEXEC.s new file mode 100644 index 00000000..f44763e2 --- /dev/null +++ b/libc/sysv/consts/ST_NOEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ST_NOEXEC 8 0 0 0 0 diff --git a/libc/sysv/consts/ST_NOSUID.s b/libc/sysv/consts/ST_NOSUID.s new file mode 100644 index 00000000..b5cbdb62 --- /dev/null +++ b/libc/sysv/consts/ST_NOSUID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ST_NOSUID 2 2 2 2 0 diff --git a/libc/sysv/consts/ST_RDONLY.s b/libc/sysv/consts/ST_RDONLY.s new file mode 100644 index 00000000..503ec2af --- /dev/null +++ b/libc/sysv/consts/ST_RDONLY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ST_RDONLY 1 1 1 1 0 diff --git a/libc/sysv/consts/ST_RELATIME.s b/libc/sysv/consts/ST_RELATIME.s new file mode 100644 index 00000000..787b5268 --- /dev/null +++ b/libc/sysv/consts/ST_RELATIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ST_RELATIME 0x1000 0 0 0 0 diff --git a/libc/sysv/consts/ST_SYNCHRONOUS.s b/libc/sysv/consts/ST_SYNCHRONOUS.s new file mode 100644 index 00000000..528923db --- /dev/null +++ b/libc/sysv/consts/ST_SYNCHRONOUS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ST_SYNCHRONOUS 0x10 0 0 0 0 diff --git a/libc/sysv/consts/ST_WRITE.s b/libc/sysv/consts/ST_WRITE.s new file mode 100644 index 00000000..e545f3cb --- /dev/null +++ b/libc/sysv/consts/ST_WRITE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc ST_WRITE 0x80 0 0 0 0 diff --git a/libc/sysv/consts/SUBCMDMASK.s b/libc/sysv/consts/SUBCMDMASK.s new file mode 100644 index 00000000..413bd512 --- /dev/null +++ b/libc/sysv/consts/SUBCMDMASK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SUBCMDMASK 255 255 255 255 0 diff --git a/libc/sysv/consts/SUBCMDSHIFT.s b/libc/sysv/consts/SUBCMDSHIFT.s new file mode 100644 index 00000000..2a769479 --- /dev/null +++ b/libc/sysv/consts/SUBCMDSHIFT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SUBCMDSHIFT 8 8 8 8 0 diff --git a/libc/sysv/consts/SWAP_FLAG_DISCARD.s b/libc/sysv/consts/SWAP_FLAG_DISCARD.s new file mode 100644 index 00000000..4eab8786 --- /dev/null +++ b/libc/sysv/consts/SWAP_FLAG_DISCARD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SWAP_FLAG_DISCARD 0x010000 0 0 0 0 diff --git a/libc/sysv/consts/SYMLOOP_MAX.s b/libc/sysv/consts/SYMLOOP_MAX.s new file mode 100644 index 00000000..6f194943 --- /dev/null +++ b/libc/sysv/consts/SYMLOOP_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SYMLOOP_MAX 0 0 0 0x20 0 diff --git a/libc/sysv/consts/SYMTYPE.s b/libc/sysv/consts/SYMTYPE.s new file mode 100644 index 00000000..e20dcacc --- /dev/null +++ b/libc/sysv/consts/SYMTYPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SYMTYPE 50 50 50 50 0 diff --git a/libc/sysv/consts/SYNCHRONIZE_CACHE.s b/libc/sysv/consts/SYNCHRONIZE_CACHE.s new file mode 100644 index 00000000..915182d5 --- /dev/null +++ b/libc/sysv/consts/SYNCHRONIZE_CACHE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SYNCHRONIZE_CACHE 53 0 0 0 0 diff --git a/libc/sysv/consts/SYNC_FILE_RANGE_WAIT_AFTER.s b/libc/sysv/consts/SYNC_FILE_RANGE_WAIT_AFTER.s new file mode 100644 index 00000000..4b46fd6a --- /dev/null +++ b/libc/sysv/consts/SYNC_FILE_RANGE_WAIT_AFTER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SYNC_FILE_RANGE_WAIT_AFTER 4 0 0 0 0 diff --git a/libc/sysv/consts/SYNC_FILE_RANGE_WAIT_BEFORE.s b/libc/sysv/consts/SYNC_FILE_RANGE_WAIT_BEFORE.s new file mode 100644 index 00000000..03bb3408 --- /dev/null +++ b/libc/sysv/consts/SYNC_FILE_RANGE_WAIT_BEFORE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SYNC_FILE_RANGE_WAIT_BEFORE 1 0 0 0 0 diff --git a/libc/sysv/consts/SYNC_FILE_RANGE_WRITE.s b/libc/sysv/consts/SYNC_FILE_RANGE_WRITE.s new file mode 100644 index 00000000..fc310f58 --- /dev/null +++ b/libc/sysv/consts/SYNC_FILE_RANGE_WRITE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc SYNC_FILE_RANGE_WRITE 2 0 0 0 0 diff --git a/libc/sysv/consts/S_IEXEC.s b/libc/sysv/consts/S_IEXEC.s new file mode 100644 index 00000000..9e238581 --- /dev/null +++ b/libc/sysv/consts/S_IEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IEXEC 00100 00100 00100 00100 00100 diff --git a/libc/sysv/consts/S_IFBLK.s b/libc/sysv/consts/S_IFBLK.s new file mode 100644 index 00000000..2358c53b --- /dev/null +++ b/libc/sysv/consts/S_IFBLK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IFBLK 0060000 0060000 0060000 0060000 0060000 diff --git a/libc/sysv/consts/S_IFCHR.s b/libc/sysv/consts/S_IFCHR.s new file mode 100644 index 00000000..ad661d02 --- /dev/null +++ b/libc/sysv/consts/S_IFCHR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IFCHR 0020000 0020000 0020000 0020000 0020000 diff --git a/libc/sysv/consts/S_IFDIR.s b/libc/sysv/consts/S_IFDIR.s new file mode 100644 index 00000000..819d9c0b --- /dev/null +++ b/libc/sysv/consts/S_IFDIR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IFDIR 0040000 0040000 0040000 0040000 0040000 diff --git a/libc/sysv/consts/S_IFIFO.s b/libc/sysv/consts/S_IFIFO.s new file mode 100644 index 00000000..ed197b43 --- /dev/null +++ b/libc/sysv/consts/S_IFIFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IFIFO 0010000 0010000 0010000 0010000 0010000 diff --git a/libc/sysv/consts/S_IFLNK.s b/libc/sysv/consts/S_IFLNK.s new file mode 100644 index 00000000..805dc596 --- /dev/null +++ b/libc/sysv/consts/S_IFLNK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IFLNK 0120000 0120000 0120000 0120000 0120000 diff --git a/libc/sysv/consts/S_IFMT.s b/libc/sysv/consts/S_IFMT.s new file mode 100644 index 00000000..36b21d68 --- /dev/null +++ b/libc/sysv/consts/S_IFMT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IFMT 0170000 0170000 0170000 0170000 0170000 diff --git a/libc/sysv/consts/S_IFREG.s b/libc/sysv/consts/S_IFREG.s new file mode 100644 index 00000000..8c1f30fb --- /dev/null +++ b/libc/sysv/consts/S_IFREG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IFREG 0100000 0100000 0100000 0100000 0100000 diff --git a/libc/sysv/consts/S_IFSOCK.s b/libc/sysv/consts/S_IFSOCK.s new file mode 100644 index 00000000..325b213c --- /dev/null +++ b/libc/sysv/consts/S_IFSOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IFSOCK 0140000 0140000 0140000 0140000 0140000 diff --git a/libc/sysv/consts/S_IREAD.s b/libc/sysv/consts/S_IREAD.s new file mode 100644 index 00000000..8b3c4ac7 --- /dev/null +++ b/libc/sysv/consts/S_IREAD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IREAD 00400 00400 00400 00400 00400 diff --git a/libc/sysv/consts/S_IRGRP.s b/libc/sysv/consts/S_IRGRP.s new file mode 100644 index 00000000..a28a4e96 --- /dev/null +++ b/libc/sysv/consts/S_IRGRP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IRGRP 00040 00040 00040 00040 00040 diff --git a/libc/sysv/consts/S_IROTH.s b/libc/sysv/consts/S_IROTH.s new file mode 100644 index 00000000..d26604e7 --- /dev/null +++ b/libc/sysv/consts/S_IROTH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IROTH 00004 00004 00004 00004 00004 diff --git a/libc/sysv/consts/S_IRUSR.s b/libc/sysv/consts/S_IRUSR.s new file mode 100644 index 00000000..93e907a3 --- /dev/null +++ b/libc/sysv/consts/S_IRUSR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IRUSR 00400 00400 00400 00400 00400 diff --git a/libc/sysv/consts/S_IRWXG.s b/libc/sysv/consts/S_IRWXG.s new file mode 100644 index 00000000..2fa3beec --- /dev/null +++ b/libc/sysv/consts/S_IRWXG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IRWXG 00070 00070 00070 00070 00070 diff --git a/libc/sysv/consts/S_IRWXO.s b/libc/sysv/consts/S_IRWXO.s new file mode 100644 index 00000000..e8988952 --- /dev/null +++ b/libc/sysv/consts/S_IRWXO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IRWXO 00007 00007 00007 00007 00007 diff --git a/libc/sysv/consts/S_IRWXU.s b/libc/sysv/consts/S_IRWXU.s new file mode 100644 index 00000000..a8dac457 --- /dev/null +++ b/libc/sysv/consts/S_IRWXU.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IRWXU 00700 00700 00700 00700 00700 diff --git a/libc/sysv/consts/S_ISGID.s b/libc/sysv/consts/S_ISGID.s new file mode 100644 index 00000000..1a0ffff5 --- /dev/null +++ b/libc/sysv/consts/S_ISGID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_ISGID 02000 02000 02000 02000 02000 diff --git a/libc/sysv/consts/S_ISUID.s b/libc/sysv/consts/S_ISUID.s new file mode 100644 index 00000000..e45853e3 --- /dev/null +++ b/libc/sysv/consts/S_ISUID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_ISUID 04000 04000 04000 04000 04000 diff --git a/libc/sysv/consts/S_ISVTX.s b/libc/sysv/consts/S_ISVTX.s new file mode 100644 index 00000000..32209799 --- /dev/null +++ b/libc/sysv/consts/S_ISVTX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_ISVTX 01000 01000 01000 01000 01000 diff --git a/libc/sysv/consts/S_IWGRP.s b/libc/sysv/consts/S_IWGRP.s new file mode 100644 index 00000000..e6bde2d2 --- /dev/null +++ b/libc/sysv/consts/S_IWGRP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IWGRP 00020 00020 00020 00020 00020 diff --git a/libc/sysv/consts/S_IWOTH.s b/libc/sysv/consts/S_IWOTH.s new file mode 100644 index 00000000..ee021292 --- /dev/null +++ b/libc/sysv/consts/S_IWOTH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IWOTH 00002 00002 00002 00002 00002 diff --git a/libc/sysv/consts/S_IWRITE.s b/libc/sysv/consts/S_IWRITE.s new file mode 100644 index 00000000..475fbeeb --- /dev/null +++ b/libc/sysv/consts/S_IWRITE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IWRITE 00200 00200 00200 00200 00200 diff --git a/libc/sysv/consts/S_IWUSR.s b/libc/sysv/consts/S_IWUSR.s new file mode 100644 index 00000000..40173209 --- /dev/null +++ b/libc/sysv/consts/S_IWUSR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IWUSR 00200 00200 00200 00200 00200 diff --git a/libc/sysv/consts/S_IXGRP.s b/libc/sysv/consts/S_IXGRP.s new file mode 100644 index 00000000..65b5013e --- /dev/null +++ b/libc/sysv/consts/S_IXGRP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IXGRP 00010 00010 00010 00010 00010 diff --git a/libc/sysv/consts/S_IXOTH.s b/libc/sysv/consts/S_IXOTH.s new file mode 100644 index 00000000..4d1c3aeb --- /dev/null +++ b/libc/sysv/consts/S_IXOTH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IXOTH 00001 00001 00001 00001 00001 diff --git a/libc/sysv/consts/S_IXUSR.s b/libc/sysv/consts/S_IXUSR.s new file mode 100644 index 00000000..c6730c85 --- /dev/null +++ b/libc/sysv/consts/S_IXUSR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon stat S_IXUSR 00100 00100 00100 00100 00100 diff --git a/libc/sysv/consts/TAB0.s b/libc/sysv/consts/TAB0.s new file mode 100644 index 00000000..796290a8 --- /dev/null +++ b/libc/sysv/consts/TAB0.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TAB0 0b0000000000000000 0b000000000000000000 0b000000000000000000 0 0b0000000000000000 diff --git a/libc/sysv/consts/TAB1.s b/libc/sysv/consts/TAB1.s new file mode 100644 index 00000000..fb8a213b --- /dev/null +++ b/libc/sysv/consts/TAB1.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TAB1 0b0000100000000000 0b000000010000000000 0b000000010000000000 0 0b0000100000000000 diff --git a/libc/sysv/consts/TAB2.s b/libc/sysv/consts/TAB2.s new file mode 100644 index 00000000..cd494dd9 --- /dev/null +++ b/libc/sysv/consts/TAB2.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TAB2 0b0001000000000000 0b000000100000000000 0b000000100000000000 0 0b0001000000000000 diff --git a/libc/sysv/consts/TAB3.s b/libc/sysv/consts/TAB3.s new file mode 100644 index 00000000..45091001 --- /dev/null +++ b/libc/sysv/consts/TAB3.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TAB3 0b0001100000000000 0b000000000000000100 0b000000000000000100 0 0b0001100000000000 diff --git a/libc/sysv/consts/TABDLY.s b/libc/sysv/consts/TABDLY.s new file mode 100644 index 00000000..bb01ba86 --- /dev/null +++ b/libc/sysv/consts/TABDLY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TABDLY 0b0001100000000000 0b000000110000000100 0b000000000000000100 0 0b0001100000000000 diff --git a/libc/sysv/consts/TABLDISC.s b/libc/sysv/consts/TABLDISC.s new file mode 100644 index 00000000..9b461430 --- /dev/null +++ b/libc/sysv/consts/TABLDISC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TABLDISC 0 0x3 0 0x3 -1 diff --git a/libc/sysv/consts/TCFLSH.s b/libc/sysv/consts/TCFLSH.s new file mode 100644 index 00000000..339a0bc2 --- /dev/null +++ b/libc/sysv/consts/TCFLSH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCFLSH 0x540b 0 0 0 0 diff --git a/libc/sysv/consts/TCGETS.s b/libc/sysv/consts/TCGETS.s new file mode 100644 index 00000000..c5e42233 --- /dev/null +++ b/libc/sysv/consts/TCGETS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TCGETS 0x5401 0x40487413 0x402c7413 0x402c7413 -1 diff --git a/libc/sysv/consts/TCIFLUSH.s b/libc/sysv/consts/TCIFLUSH.s new file mode 100644 index 00000000..24aba687 --- /dev/null +++ b/libc/sysv/consts/TCIFLUSH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCIFLUSH 0 1 1 1 0 diff --git a/libc/sysv/consts/TCIOFF.s b/libc/sysv/consts/TCIOFF.s new file mode 100644 index 00000000..226b82a7 --- /dev/null +++ b/libc/sysv/consts/TCIOFF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCIOFF 2 3 3 3 0 diff --git a/libc/sysv/consts/TCIOFLUSH.s b/libc/sysv/consts/TCIOFLUSH.s new file mode 100644 index 00000000..f5318909 --- /dev/null +++ b/libc/sysv/consts/TCIOFLUSH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCIOFLUSH 2 3 3 3 0 diff --git a/libc/sysv/consts/TCION.s b/libc/sysv/consts/TCION.s new file mode 100644 index 00000000..3809b979 --- /dev/null +++ b/libc/sysv/consts/TCION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCION 3 4 4 4 0 diff --git a/libc/sysv/consts/TCOFLUSH.s b/libc/sysv/consts/TCOFLUSH.s new file mode 100644 index 00000000..184766d7 --- /dev/null +++ b/libc/sysv/consts/TCOFLUSH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCOFLUSH 1 2 2 2 0 diff --git a/libc/sysv/consts/TCOOFF.s b/libc/sysv/consts/TCOOFF.s new file mode 100644 index 00000000..639bdad4 --- /dev/null +++ b/libc/sysv/consts/TCOOFF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCOOFF 0 1 1 1 0 diff --git a/libc/sysv/consts/TCOON.s b/libc/sysv/consts/TCOON.s new file mode 100644 index 00000000..a573703f --- /dev/null +++ b/libc/sysv/consts/TCOON.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCOON 1 2 2 2 0 diff --git a/libc/sysv/consts/TCPOLEN_MAXSEG.s b/libc/sysv/consts/TCPOLEN_MAXSEG.s new file mode 100644 index 00000000..72ca1f1f --- /dev/null +++ b/libc/sysv/consts/TCPOLEN_MAXSEG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCPOLEN_MAXSEG 4 4 4 4 0 diff --git a/libc/sysv/consts/TCPOLEN_SACK_PERMITTED.s b/libc/sysv/consts/TCPOLEN_SACK_PERMITTED.s new file mode 100644 index 00000000..bbe9ab04 --- /dev/null +++ b/libc/sysv/consts/TCPOLEN_SACK_PERMITTED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCPOLEN_SACK_PERMITTED 2 2 2 2 0 diff --git a/libc/sysv/consts/TCPOLEN_TIMESTAMP.s b/libc/sysv/consts/TCPOLEN_TIMESTAMP.s new file mode 100644 index 00000000..2ee2ec4d --- /dev/null +++ b/libc/sysv/consts/TCPOLEN_TIMESTAMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCPOLEN_TIMESTAMP 10 10 10 10 0 diff --git a/libc/sysv/consts/TCPOLEN_WINDOW.s b/libc/sysv/consts/TCPOLEN_WINDOW.s new file mode 100644 index 00000000..f431a4e5 --- /dev/null +++ b/libc/sysv/consts/TCPOLEN_WINDOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCPOLEN_WINDOW 3 3 3 3 0 diff --git a/libc/sysv/consts/TCPOPT_EOL.s b/libc/sysv/consts/TCPOPT_EOL.s new file mode 100644 index 00000000..4e073f96 --- /dev/null +++ b/libc/sysv/consts/TCPOPT_EOL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCPOPT_EOL 0 0 0 0 0 diff --git a/libc/sysv/consts/TCPOPT_MAXSEG.s b/libc/sysv/consts/TCPOPT_MAXSEG.s new file mode 100644 index 00000000..a7b58421 --- /dev/null +++ b/libc/sysv/consts/TCPOPT_MAXSEG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCPOPT_MAXSEG 2 2 2 2 0 diff --git a/libc/sysv/consts/TCPOPT_NOP.s b/libc/sysv/consts/TCPOPT_NOP.s new file mode 100644 index 00000000..2fd8efe1 --- /dev/null +++ b/libc/sysv/consts/TCPOPT_NOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCPOPT_NOP 1 1 1 1 0 diff --git a/libc/sysv/consts/TCPOPT_SACK.s b/libc/sysv/consts/TCPOPT_SACK.s new file mode 100644 index 00000000..9a61a999 --- /dev/null +++ b/libc/sysv/consts/TCPOPT_SACK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCPOPT_SACK 5 5 5 5 0 diff --git a/libc/sysv/consts/TCPOPT_SACK_PERMITTED.s b/libc/sysv/consts/TCPOPT_SACK_PERMITTED.s new file mode 100644 index 00000000..f756072c --- /dev/null +++ b/libc/sysv/consts/TCPOPT_SACK_PERMITTED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCPOPT_SACK_PERMITTED 4 4 4 4 0 diff --git a/libc/sysv/consts/TCPOPT_TIMESTAMP.s b/libc/sysv/consts/TCPOPT_TIMESTAMP.s new file mode 100644 index 00000000..316d6bf0 --- /dev/null +++ b/libc/sysv/consts/TCPOPT_TIMESTAMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCPOPT_TIMESTAMP 8 8 8 8 0 diff --git a/libc/sysv/consts/TCPOPT_WINDOW.s b/libc/sysv/consts/TCPOPT_WINDOW.s new file mode 100644 index 00000000..6f0de30c --- /dev/null +++ b/libc/sysv/consts/TCPOPT_WINDOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TCPOPT_WINDOW 3 3 3 3 0 diff --git a/libc/sysv/consts/TCP_CC_INFO.s b/libc/sysv/consts/TCP_CC_INFO.s new file mode 100644 index 00000000..4d2b1346 --- /dev/null +++ b/libc/sysv/consts/TCP_CC_INFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_CC_INFO 26 0 0 0 0 diff --git a/libc/sysv/consts/TCP_CONGESTION.s b/libc/sysv/consts/TCP_CONGESTION.s new file mode 100644 index 00000000..f13290fd --- /dev/null +++ b/libc/sysv/consts/TCP_CONGESTION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_CONGESTION 13 0 0x40 0 0 diff --git a/libc/sysv/consts/TCP_COOKIE_TRANSACTIONS.s b/libc/sysv/consts/TCP_COOKIE_TRANSACTIONS.s new file mode 100644 index 00000000..b931f12b --- /dev/null +++ b/libc/sysv/consts/TCP_COOKIE_TRANSACTIONS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_COOKIE_TRANSACTIONS 15 0 0 0 0 diff --git a/libc/sysv/consts/TCP_CORK.s b/libc/sysv/consts/TCP_CORK.s new file mode 100644 index 00000000..b6c397db --- /dev/null +++ b/libc/sysv/consts/TCP_CORK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_CORK 3 0 0 0 0 diff --git a/libc/sysv/consts/TCP_DEFER_ACCEPT.s b/libc/sysv/consts/TCP_DEFER_ACCEPT.s new file mode 100644 index 00000000..7ec13074 --- /dev/null +++ b/libc/sysv/consts/TCP_DEFER_ACCEPT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_DEFER_ACCEPT 9 0 0 0 0 diff --git a/libc/sysv/consts/TCP_FASTOPEN.s b/libc/sysv/consts/TCP_FASTOPEN.s new file mode 100644 index 00000000..44d9b32a --- /dev/null +++ b/libc/sysv/consts/TCP_FASTOPEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_FASTOPEN 23 261 0x0401 0 15 diff --git a/libc/sysv/consts/TCP_INFO.s b/libc/sysv/consts/TCP_INFO.s new file mode 100644 index 00000000..3fc31e2f --- /dev/null +++ b/libc/sysv/consts/TCP_INFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_INFO 11 0 0x20 0 0 diff --git a/libc/sysv/consts/TCP_KEEPCNT.s b/libc/sysv/consts/TCP_KEEPCNT.s new file mode 100644 index 00000000..ca7d3b28 --- /dev/null +++ b/libc/sysv/consts/TCP_KEEPCNT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_KEEPCNT 6 0x102 0x400 0 0 diff --git a/libc/sysv/consts/TCP_KEEPIDLE.s b/libc/sysv/consts/TCP_KEEPIDLE.s new file mode 100644 index 00000000..6bfe73d4 --- /dev/null +++ b/libc/sysv/consts/TCP_KEEPIDLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_KEEPIDLE 4 0 0x100 0 0 diff --git a/libc/sysv/consts/TCP_KEEPINTVL.s b/libc/sysv/consts/TCP_KEEPINTVL.s new file mode 100644 index 00000000..21c804e6 --- /dev/null +++ b/libc/sysv/consts/TCP_KEEPINTVL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_KEEPINTVL 5 0x101 0x200 0 0 diff --git a/libc/sysv/consts/TCP_LINGER2.s b/libc/sysv/consts/TCP_LINGER2.s new file mode 100644 index 00000000..26a6091c --- /dev/null +++ b/libc/sysv/consts/TCP_LINGER2.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_LINGER2 8 0 0 0 0 diff --git a/libc/sysv/consts/TCP_MAXSEG.s b/libc/sysv/consts/TCP_MAXSEG.s new file mode 100644 index 00000000..53945906 --- /dev/null +++ b/libc/sysv/consts/TCP_MAXSEG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_MAXSEG 2 2 2 2 0 diff --git a/libc/sysv/consts/TCP_MD5SIG.s b/libc/sysv/consts/TCP_MD5SIG.s new file mode 100644 index 00000000..6ba95fad --- /dev/null +++ b/libc/sysv/consts/TCP_MD5SIG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_MD5SIG 14 0 0x10 4 0 diff --git a/libc/sysv/consts/TCP_MD5SIG_MAXKEYLEN.s b/libc/sysv/consts/TCP_MD5SIG_MAXKEYLEN.s new file mode 100644 index 00000000..88ee62f4 --- /dev/null +++ b/libc/sysv/consts/TCP_MD5SIG_MAXKEYLEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_MD5SIG_MAXKEYLEN 80 0 0 0 0 diff --git a/libc/sysv/consts/TCP_NODELAY.s b/libc/sysv/consts/TCP_NODELAY.s new file mode 100644 index 00000000..1d06769d --- /dev/null +++ b/libc/sysv/consts/TCP_NODELAY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_NODELAY 1 1 1 1 1 diff --git a/libc/sysv/consts/TCP_NOTSENT_LOWAT.s b/libc/sysv/consts/TCP_NOTSENT_LOWAT.s new file mode 100644 index 00000000..fbb6c19f --- /dev/null +++ b/libc/sysv/consts/TCP_NOTSENT_LOWAT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_NOTSENT_LOWAT 25 513 0 0 0 diff --git a/libc/sysv/consts/TCP_QUEUE_SEQ.s b/libc/sysv/consts/TCP_QUEUE_SEQ.s new file mode 100644 index 00000000..73595e73 --- /dev/null +++ b/libc/sysv/consts/TCP_QUEUE_SEQ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_QUEUE_SEQ 21 0 0 0 0 diff --git a/libc/sysv/consts/TCP_QUICKACK.s b/libc/sysv/consts/TCP_QUICKACK.s new file mode 100644 index 00000000..a542b4cc --- /dev/null +++ b/libc/sysv/consts/TCP_QUICKACK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_QUICKACK 12 0 0 0 0 diff --git a/libc/sysv/consts/TCP_REPAIR.s b/libc/sysv/consts/TCP_REPAIR.s new file mode 100644 index 00000000..2814a734 --- /dev/null +++ b/libc/sysv/consts/TCP_REPAIR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_REPAIR 19 0 0 0 0 diff --git a/libc/sysv/consts/TCP_REPAIR_OPTIONS.s b/libc/sysv/consts/TCP_REPAIR_OPTIONS.s new file mode 100644 index 00000000..2a064d04 --- /dev/null +++ b/libc/sysv/consts/TCP_REPAIR_OPTIONS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_REPAIR_OPTIONS 22 0 0 0 0 diff --git a/libc/sysv/consts/TCP_REPAIR_QUEUE.s b/libc/sysv/consts/TCP_REPAIR_QUEUE.s new file mode 100644 index 00000000..b8e798ba --- /dev/null +++ b/libc/sysv/consts/TCP_REPAIR_QUEUE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_REPAIR_QUEUE 20 0 0 0 0 diff --git a/libc/sysv/consts/TCP_SAVED_SYN.s b/libc/sysv/consts/TCP_SAVED_SYN.s new file mode 100644 index 00000000..9a9461b9 --- /dev/null +++ b/libc/sysv/consts/TCP_SAVED_SYN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_SAVED_SYN 28 0 0 0 0 diff --git a/libc/sysv/consts/TCP_SAVE_SYN.s b/libc/sysv/consts/TCP_SAVE_SYN.s new file mode 100644 index 00000000..8511583f --- /dev/null +++ b/libc/sysv/consts/TCP_SAVE_SYN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_SAVE_SYN 27 0 0 0 0 diff --git a/libc/sysv/consts/TCP_SYNCNT.s b/libc/sysv/consts/TCP_SYNCNT.s new file mode 100644 index 00000000..3db9733b --- /dev/null +++ b/libc/sysv/consts/TCP_SYNCNT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_SYNCNT 7 0 0 0 0 diff --git a/libc/sysv/consts/TCP_THIN_DUPACK.s b/libc/sysv/consts/TCP_THIN_DUPACK.s new file mode 100644 index 00000000..bdeebfa5 --- /dev/null +++ b/libc/sysv/consts/TCP_THIN_DUPACK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_THIN_DUPACK 17 0 0 0 0 diff --git a/libc/sysv/consts/TCP_THIN_LINEAR_TIMEOUTS.s b/libc/sysv/consts/TCP_THIN_LINEAR_TIMEOUTS.s new file mode 100644 index 00000000..b9f4c2ce --- /dev/null +++ b/libc/sysv/consts/TCP_THIN_LINEAR_TIMEOUTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_THIN_LINEAR_TIMEOUTS 16 0 0 0 0 diff --git a/libc/sysv/consts/TCP_TIMESTAMP.s b/libc/sysv/consts/TCP_TIMESTAMP.s new file mode 100644 index 00000000..6ea9f891 --- /dev/null +++ b/libc/sysv/consts/TCP_TIMESTAMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_TIMESTAMP 24 0 0 0 0 diff --git a/libc/sysv/consts/TCP_USER_TIMEOUT.s b/libc/sysv/consts/TCP_USER_TIMEOUT.s new file mode 100644 index 00000000..87c072cd --- /dev/null +++ b/libc/sysv/consts/TCP_USER_TIMEOUT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_USER_TIMEOUT 18 0 0 0 0 diff --git a/libc/sysv/consts/TCP_WINDOW_CLAMP.s b/libc/sysv/consts/TCP_WINDOW_CLAMP.s new file mode 100644 index 00000000..3a5f39f2 --- /dev/null +++ b/libc/sysv/consts/TCP_WINDOW_CLAMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon tcp TCP_WINDOW_CLAMP 10 0 0 0 0 diff --git a/libc/sysv/consts/TCSADRAIN.s b/libc/sysv/consts/TCSADRAIN.s new file mode 100644 index 00000000..5c3a686c --- /dev/null +++ b/libc/sysv/consts/TCSADRAIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TCSADRAIN 1 1 1 1 1 diff --git a/libc/sysv/consts/TCSAFLUSH.s b/libc/sysv/consts/TCSAFLUSH.s new file mode 100644 index 00000000..43b5d3b8 --- /dev/null +++ b/libc/sysv/consts/TCSAFLUSH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TCSAFLUSH 2 2 2 2 2 diff --git a/libc/sysv/consts/TCSANOW.s b/libc/sysv/consts/TCSANOW.s new file mode 100644 index 00000000..bc95b30f --- /dev/null +++ b/libc/sysv/consts/TCSANOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TCSANOW 0 0 0 0 0 diff --git a/libc/sysv/consts/TCSETS.s b/libc/sysv/consts/TCSETS.s new file mode 100644 index 00000000..d4b16eb6 --- /dev/null +++ b/libc/sysv/consts/TCSETS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TCSETS 0x5402 0x80487414 0x802c7414 0x802c7414 0x5402 diff --git a/libc/sysv/consts/TCSETSF.s b/libc/sysv/consts/TCSETSF.s new file mode 100644 index 00000000..2efecba4 --- /dev/null +++ b/libc/sysv/consts/TCSETSF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TCSETSF 0x5404 0x80487416 0x802c7416 0x802c7416 0x5404 diff --git a/libc/sysv/consts/TCSETSW.s b/libc/sysv/consts/TCSETSW.s new file mode 100644 index 00000000..76105c63 --- /dev/null +++ b/libc/sysv/consts/TCSETSW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TCSETSW 0x5403 0x80487415 0x802c7415 0x802c7415 0x5403 diff --git a/libc/sysv/consts/TELOPT_NAOL.s b/libc/sysv/consts/TELOPT_NAOL.s new file mode 100644 index 00000000..84a35ac6 --- /dev/null +++ b/libc/sysv/consts/TELOPT_NAOL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TELOPT_NAOL 8 8 8 8 0 diff --git a/libc/sysv/consts/TELOPT_NAOP.s b/libc/sysv/consts/TELOPT_NAOP.s new file mode 100644 index 00000000..bea28cd9 --- /dev/null +++ b/libc/sysv/consts/TELOPT_NAOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TELOPT_NAOP 9 9 9 9 0 diff --git a/libc/sysv/consts/TELOPT_NEW_ENVIRON.s b/libc/sysv/consts/TELOPT_NEW_ENVIRON.s new file mode 100644 index 00000000..04269d90 --- /dev/null +++ b/libc/sysv/consts/TELOPT_NEW_ENVIRON.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TELOPT_NEW_ENVIRON 39 39 39 39 0 diff --git a/libc/sysv/consts/TELOPT_OLD_ENVIRON.s b/libc/sysv/consts/TELOPT_OLD_ENVIRON.s new file mode 100644 index 00000000..fd5399c6 --- /dev/null +++ b/libc/sysv/consts/TELOPT_OLD_ENVIRON.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TELOPT_OLD_ENVIRON 36 36 36 36 0 diff --git a/libc/sysv/consts/TEST_UNIT_READY.s b/libc/sysv/consts/TEST_UNIT_READY.s new file mode 100644 index 00000000..a3c846fc --- /dev/null +++ b/libc/sysv/consts/TEST_UNIT_READY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TEST_UNIT_READY 0 0 0 0 0 diff --git a/libc/sysv/consts/TFD_CLOEXEC.s b/libc/sysv/consts/TFD_CLOEXEC.s new file mode 100644 index 00000000..dbd2d84f --- /dev/null +++ b/libc/sysv/consts/TFD_CLOEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TFD_CLOEXEC 0x080000 0 0 0 0 diff --git a/libc/sysv/consts/TFD_NONBLOCK.s b/libc/sysv/consts/TFD_NONBLOCK.s new file mode 100644 index 00000000..c4b766c5 --- /dev/null +++ b/libc/sysv/consts/TFD_NONBLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TFD_NONBLOCK 0x0800 0 0 0 0 diff --git a/libc/sysv/consts/TFD_TIMER_ABSTIME.s b/libc/sysv/consts/TFD_TIMER_ABSTIME.s new file mode 100644 index 00000000..c5aaca5a --- /dev/null +++ b/libc/sysv/consts/TFD_TIMER_ABSTIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TFD_TIMER_ABSTIME 1 0 0 0 0 diff --git a/libc/sysv/consts/TGEXEC.s b/libc/sysv/consts/TGEXEC.s new file mode 100644 index 00000000..75acd1e9 --- /dev/null +++ b/libc/sysv/consts/TGEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TGEXEC 8 8 8 8 0 diff --git a/libc/sysv/consts/TGREAD.s b/libc/sysv/consts/TGREAD.s new file mode 100644 index 00000000..c39e5ed9 --- /dev/null +++ b/libc/sysv/consts/TGREAD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TGREAD 0x20 0x20 0x20 0x20 0 diff --git a/libc/sysv/consts/TGWRITE.s b/libc/sysv/consts/TGWRITE.s new file mode 100644 index 00000000..268eba07 --- /dev/null +++ b/libc/sysv/consts/TGWRITE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TGWRITE 0x10 0x10 0x10 0x10 0 diff --git a/libc/sysv/consts/THOUSEP.s b/libc/sysv/consts/THOUSEP.s new file mode 100644 index 00000000..323ab47c --- /dev/null +++ b/libc/sysv/consts/THOUSEP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc THOUSEP 0x010001 51 51 45 0 diff --git a/libc/sysv/consts/TH_ACK.s b/libc/sysv/consts/TH_ACK.s new file mode 100644 index 00000000..638f3e9c --- /dev/null +++ b/libc/sysv/consts/TH_ACK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TH_ACK 16 16 16 16 16 diff --git a/libc/sysv/consts/TH_FIN.s b/libc/sysv/consts/TH_FIN.s new file mode 100644 index 00000000..eab04751 --- /dev/null +++ b/libc/sysv/consts/TH_FIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TH_FIN 1 1 1 1 1 diff --git a/libc/sysv/consts/TH_PUSH.s b/libc/sysv/consts/TH_PUSH.s new file mode 100644 index 00000000..33145621 --- /dev/null +++ b/libc/sysv/consts/TH_PUSH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TH_PUSH 8 8 8 8 0 diff --git a/libc/sysv/consts/TH_RST.s b/libc/sysv/consts/TH_RST.s new file mode 100644 index 00000000..d8dbf32c --- /dev/null +++ b/libc/sysv/consts/TH_RST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TH_RST 4 4 4 4 4 diff --git a/libc/sysv/consts/TH_SYN.s b/libc/sysv/consts/TH_SYN.s new file mode 100644 index 00000000..46c3b0d3 --- /dev/null +++ b/libc/sysv/consts/TH_SYN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TH_SYN 2 2 2 2 2 diff --git a/libc/sysv/consts/TH_URG.s b/libc/sysv/consts/TH_URG.s new file mode 100644 index 00000000..d22ab921 --- /dev/null +++ b/libc/sysv/consts/TH_URG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TH_URG 32 32 32 32 32 diff --git a/libc/sysv/consts/TIMER_ABSTIME.s b/libc/sysv/consts/TIMER_ABSTIME.s new file mode 100644 index 00000000..99029305 --- /dev/null +++ b/libc/sysv/consts/TIMER_ABSTIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TIMER_ABSTIME 1 0 1 1 0 diff --git a/libc/sysv/consts/TIME_UTC.s b/libc/sysv/consts/TIME_UTC.s new file mode 100644 index 00000000..df67fd6e --- /dev/null +++ b/libc/sysv/consts/TIME_UTC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TIME_UTC 1 0 1 0 0 diff --git a/libc/sysv/consts/TIOCCBRK.s b/libc/sysv/consts/TIOCCBRK.s new file mode 100644 index 00000000..e7ccd231 --- /dev/null +++ b/libc/sysv/consts/TIOCCBRK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCCBRK 0x5428 0x2000747a 0x2000747a 0x2000747a -1 diff --git a/libc/sysv/consts/TIOCCDTR.s b/libc/sysv/consts/TIOCCDTR.s new file mode 100644 index 00000000..8e3592a2 --- /dev/null +++ b/libc/sysv/consts/TIOCCDTR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCCDTR 0 0x20007478 0x20007478 0x20007478 -1 diff --git a/libc/sysv/consts/TIOCCHKVERAUTH.s b/libc/sysv/consts/TIOCCHKVERAUTH.s new file mode 100644 index 00000000..06ef8a28 --- /dev/null +++ b/libc/sysv/consts/TIOCCHKVERAUTH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCCHKVERAUTH 0 0 0 0x2000741e -1 diff --git a/libc/sysv/consts/TIOCCONS.s b/libc/sysv/consts/TIOCCONS.s new file mode 100644 index 00000000..2e187c36 --- /dev/null +++ b/libc/sysv/consts/TIOCCONS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCCONS 0x541d 0x80047462 0x80047462 0x80047462 -1 diff --git a/libc/sysv/consts/TIOCDRAIN.s b/libc/sysv/consts/TIOCDRAIN.s new file mode 100644 index 00000000..de2c685a --- /dev/null +++ b/libc/sysv/consts/TIOCDRAIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCDRAIN 0 0x2000745e 0x2000745e 0x2000745e -1 diff --git a/libc/sysv/consts/TIOCEXT.s b/libc/sysv/consts/TIOCEXT.s new file mode 100644 index 00000000..273adb5d --- /dev/null +++ b/libc/sysv/consts/TIOCEXT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCEXT 0 0x80047460 0x80047460 0x80047460 -1 diff --git a/libc/sysv/consts/TIOCFLAG_CLOCAL.s b/libc/sysv/consts/TIOCFLAG_CLOCAL.s new file mode 100644 index 00000000..168be03a --- /dev/null +++ b/libc/sysv/consts/TIOCFLAG_CLOCAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCFLAG_CLOCAL 0 0 0 0x2 -1 diff --git a/libc/sysv/consts/TIOCFLAG_MDMBUF.s b/libc/sysv/consts/TIOCFLAG_MDMBUF.s new file mode 100644 index 00000000..2bf31a85 --- /dev/null +++ b/libc/sysv/consts/TIOCFLAG_MDMBUF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCFLAG_MDMBUF 0 0 0 0x8 -1 diff --git a/libc/sysv/consts/TIOCFLAG_PPS.s b/libc/sysv/consts/TIOCFLAG_PPS.s new file mode 100644 index 00000000..2933d552 --- /dev/null +++ b/libc/sysv/consts/TIOCFLAG_PPS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCFLAG_PPS 0 0 0 0x10 -1 diff --git a/libc/sysv/consts/TIOCFLAG_SOFTCAR.s b/libc/sysv/consts/TIOCFLAG_SOFTCAR.s new file mode 100644 index 00000000..887e4c16 --- /dev/null +++ b/libc/sysv/consts/TIOCFLAG_SOFTCAR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCFLAG_SOFTCAR 0 0 0 0x1 -1 diff --git a/libc/sysv/consts/TIOCFLUSH.s b/libc/sysv/consts/TIOCFLUSH.s new file mode 100644 index 00000000..f860d648 --- /dev/null +++ b/libc/sysv/consts/TIOCFLUSH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCFLUSH 0 0x80047410 0x80047410 0x80047410 -1 diff --git a/libc/sysv/consts/TIOCGDRAINWAIT.s b/libc/sysv/consts/TIOCGDRAINWAIT.s new file mode 100644 index 00000000..a68c7319 --- /dev/null +++ b/libc/sysv/consts/TIOCGDRAINWAIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCGDRAINWAIT 0 0x40047456 0x40047456 0 -1 diff --git a/libc/sysv/consts/TIOCGETA.s b/libc/sysv/consts/TIOCGETA.s new file mode 100644 index 00000000..6e208f99 --- /dev/null +++ b/libc/sysv/consts/TIOCGETA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat TIOCGETA 0x5401 0x40487413 0x402c7413 0x402c7413 -1 diff --git a/libc/sysv/consts/TIOCGETD.s b/libc/sysv/consts/TIOCGETD.s new file mode 100644 index 00000000..2097273c --- /dev/null +++ b/libc/sysv/consts/TIOCGETD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCGETD 0x5424 0x4004741a 0x4004741a 0x4004741a -1 diff --git a/libc/sysv/consts/TIOCGFLAGS.s b/libc/sysv/consts/TIOCGFLAGS.s new file mode 100644 index 00000000..5800eedd --- /dev/null +++ b/libc/sysv/consts/TIOCGFLAGS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCGFLAGS 0 0 0 0x4004745d -1 diff --git a/libc/sysv/consts/TIOCGPGRP.s b/libc/sysv/consts/TIOCGPGRP.s new file mode 100644 index 00000000..563054f7 --- /dev/null +++ b/libc/sysv/consts/TIOCGPGRP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCGPGRP 0x540f 0x40047477 0x40047477 0x40047477 -1 diff --git a/libc/sysv/consts/TIOCGPTN.s b/libc/sysv/consts/TIOCGPTN.s new file mode 100644 index 00000000..c78d9532 --- /dev/null +++ b/libc/sysv/consts/TIOCGPTN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCGPTN 0x80045430 0 0x4004740f 0 -1 diff --git a/libc/sysv/consts/TIOCGSID.s b/libc/sysv/consts/TIOCGSID.s new file mode 100644 index 00000000..0389957a --- /dev/null +++ b/libc/sysv/consts/TIOCGSID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCGSID 0x5429 0 0x40047463 0x40047463 -1 diff --git a/libc/sysv/consts/TIOCGTSTAMP.s b/libc/sysv/consts/TIOCGTSTAMP.s new file mode 100644 index 00000000..3fdef4b9 --- /dev/null +++ b/libc/sysv/consts/TIOCGTSTAMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCGTSTAMP 0 0 0 0x4010745b -1 diff --git a/libc/sysv/consts/TIOCGWINSZ.s b/libc/sysv/consts/TIOCGWINSZ.s new file mode 100644 index 00000000..8419f528 --- /dev/null +++ b/libc/sysv/consts/TIOCGWINSZ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCGWINSZ 0x5413 1074295912 1074295912 1074295912 0x5413 diff --git a/libc/sysv/consts/TIOCINQ.s b/libc/sysv/consts/TIOCINQ.s new file mode 100644 index 00000000..5aaaa0af --- /dev/null +++ b/libc/sysv/consts/TIOCINQ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ioctl TIOCINQ 0x541b 0x4004667f 0x4004667f 0x4004667f 0x4004667f diff --git a/libc/sysv/consts/TIOCMBIC.s b/libc/sysv/consts/TIOCMBIC.s new file mode 100644 index 00000000..00312a6c --- /dev/null +++ b/libc/sysv/consts/TIOCMBIC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCMBIC 0x5417 0x8004746b 0x8004746b 0x8004746b -1 diff --git a/libc/sysv/consts/TIOCMBIS.s b/libc/sysv/consts/TIOCMBIS.s new file mode 100644 index 00000000..7faec84f --- /dev/null +++ b/libc/sysv/consts/TIOCMBIS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCMBIS 0x5416 0x8004746c 0x8004746c 0x8004746c -1 diff --git a/libc/sysv/consts/TIOCMGET.s b/libc/sysv/consts/TIOCMGET.s new file mode 100644 index 00000000..db6612dc --- /dev/null +++ b/libc/sysv/consts/TIOCMGET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCMGET 0x5415 0x4004746a 0x4004746a 0x4004746a -1 diff --git a/libc/sysv/consts/TIOCMODG.s b/libc/sysv/consts/TIOCMODG.s new file mode 100644 index 00000000..d27e37ba --- /dev/null +++ b/libc/sysv/consts/TIOCMODG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCMODG 0 0x40047403 0 0x4004746a -1 diff --git a/libc/sysv/consts/TIOCMODS.s b/libc/sysv/consts/TIOCMODS.s new file mode 100644 index 00000000..a376f743 --- /dev/null +++ b/libc/sysv/consts/TIOCMODS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCMODS 0 0x80047404 0 0x8004746d -1 diff --git a/libc/sysv/consts/TIOCMSDTRWAIT.s b/libc/sysv/consts/TIOCMSDTRWAIT.s new file mode 100644 index 00000000..dd0ae413 --- /dev/null +++ b/libc/sysv/consts/TIOCMSDTRWAIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCMSDTRWAIT 0 0x8004745b 0x8004745b 0 -1 diff --git a/libc/sysv/consts/TIOCMSET.s b/libc/sysv/consts/TIOCMSET.s new file mode 100644 index 00000000..7a80f02e --- /dev/null +++ b/libc/sysv/consts/TIOCMSET.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCMSET 0x5418 0x8004746d 0x8004746d 0x8004746d -1 diff --git a/libc/sysv/consts/TIOCM_CAR.s b/libc/sysv/consts/TIOCM_CAR.s new file mode 100644 index 00000000..5a19a7f2 --- /dev/null +++ b/libc/sysv/consts/TIOCM_CAR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCM_CAR 0b0000000001000000 0b0000000001000000 0b0000000001000000 0b0000000001000000 0b0000000001000000 diff --git a/libc/sysv/consts/TIOCM_CD.s b/libc/sysv/consts/TIOCM_CD.s new file mode 100644 index 00000000..9ae781dd --- /dev/null +++ b/libc/sysv/consts/TIOCM_CD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCM_CD 0b0000000001000000 0b0000000001000000 0b0000000001000000 0b0000000001000000 0b0000000001000000 diff --git a/libc/sysv/consts/TIOCM_CTS.s b/libc/sysv/consts/TIOCM_CTS.s new file mode 100644 index 00000000..3939a89d --- /dev/null +++ b/libc/sysv/consts/TIOCM_CTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCM_CTS 0b0000000000100000 0b0000000000100000 0b0000000000100000 0b0000000000100000 0b0000000000100000 diff --git a/libc/sysv/consts/TIOCM_DCD.s b/libc/sysv/consts/TIOCM_DCD.s new file mode 100644 index 00000000..99a4967b --- /dev/null +++ b/libc/sysv/consts/TIOCM_DCD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCM_DCD 0 0 0x40 0 -1 diff --git a/libc/sysv/consts/TIOCM_DSR.s b/libc/sysv/consts/TIOCM_DSR.s new file mode 100644 index 00000000..2c7cc1a8 --- /dev/null +++ b/libc/sysv/consts/TIOCM_DSR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCM_DSR 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000100000000 0b0000000100000000 diff --git a/libc/sysv/consts/TIOCM_DTR.s b/libc/sysv/consts/TIOCM_DTR.s new file mode 100644 index 00000000..fd0c6c3d --- /dev/null +++ b/libc/sysv/consts/TIOCM_DTR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCM_DTR 0b0000000000000010 0b0000000000000010 0b0000000000000010 0b0000000000000010 0b0000000000000010 diff --git a/libc/sysv/consts/TIOCM_LE.s b/libc/sysv/consts/TIOCM_LE.s new file mode 100644 index 00000000..cb97e4a2 --- /dev/null +++ b/libc/sysv/consts/TIOCM_LE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCM_LE 0b0000000000000001 0b0000000000000001 0b0000000000000001 0b0000000000000001 0b0000000000000001 diff --git a/libc/sysv/consts/TIOCM_RI.s b/libc/sysv/consts/TIOCM_RI.s new file mode 100644 index 00000000..a52bcea6 --- /dev/null +++ b/libc/sysv/consts/TIOCM_RI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCM_RI 0b0000000010000000 0b0000000010000000 0b0000000010000000 0b0000000010000000 0b0000000010000000 diff --git a/libc/sysv/consts/TIOCM_RNG.s b/libc/sysv/consts/TIOCM_RNG.s new file mode 100644 index 00000000..814701b3 --- /dev/null +++ b/libc/sysv/consts/TIOCM_RNG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCM_RNG 0b0000000010000000 0b0000000010000000 0b0000000010000000 0b0000000010000000 0b0000000010000000 diff --git a/libc/sysv/consts/TIOCM_RTS.s b/libc/sysv/consts/TIOCM_RTS.s new file mode 100644 index 00000000..e98e432c --- /dev/null +++ b/libc/sysv/consts/TIOCM_RTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCM_RTS 0b0000000000000100 0b0000000000000100 0b0000000000000100 0b0000000000000100 0b0000000000000100 diff --git a/libc/sysv/consts/TIOCM_SR.s b/libc/sysv/consts/TIOCM_SR.s new file mode 100644 index 00000000..6fa7c3ba --- /dev/null +++ b/libc/sysv/consts/TIOCM_SR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCM_SR 0b0000000000010000 0b0000000000010000 0b0000000000010000 0b0000000000010000 0b0000000000010000 diff --git a/libc/sysv/consts/TIOCM_ST.s b/libc/sysv/consts/TIOCM_ST.s new file mode 100644 index 00000000..ac2acf33 --- /dev/null +++ b/libc/sysv/consts/TIOCM_ST.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon modem TIOCM_ST 0b0000000000001000 0b0000000000001000 0b0000000000001000 0b0000000000001000 0b0000000000001000 diff --git a/libc/sysv/consts/TIOCNOTTY.s b/libc/sysv/consts/TIOCNOTTY.s new file mode 100644 index 00000000..f6d1f260 --- /dev/null +++ b/libc/sysv/consts/TIOCNOTTY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCNOTTY 0x5422 0x20007471 0x20007471 0x20007471 -1 diff --git a/libc/sysv/consts/TIOCNXCL.s b/libc/sysv/consts/TIOCNXCL.s new file mode 100644 index 00000000..723dbced --- /dev/null +++ b/libc/sysv/consts/TIOCNXCL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCNXCL 0x540d 0x2000740e 0x2000740e 0x2000740e -1 diff --git a/libc/sysv/consts/TIOCOUTQ.s b/libc/sysv/consts/TIOCOUTQ.s new file mode 100644 index 00000000..2dffa16a --- /dev/null +++ b/libc/sysv/consts/TIOCOUTQ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon ioctl TIOCOUTQ 0x5411 0x40047473 0x40047473 0x40047473 -1 diff --git a/libc/sysv/consts/TIOCPKT.s b/libc/sysv/consts/TIOCPKT.s new file mode 100644 index 00000000..f7baf555 --- /dev/null +++ b/libc/sysv/consts/TIOCPKT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pty TIOCPKT 0x5420 0x80047470 0x80047470 0x80047470 -1 diff --git a/libc/sysv/consts/TIOCPKT_DATA.s b/libc/sysv/consts/TIOCPKT_DATA.s new file mode 100644 index 00000000..55816735 --- /dev/null +++ b/libc/sysv/consts/TIOCPKT_DATA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pty TIOCPKT_DATA 0 0 0 0 0 diff --git a/libc/sysv/consts/TIOCPKT_DOSTOP.s b/libc/sysv/consts/TIOCPKT_DOSTOP.s new file mode 100644 index 00000000..c61f2939 --- /dev/null +++ b/libc/sysv/consts/TIOCPKT_DOSTOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pty TIOCPKT_DOSTOP 32 32 32 32 32 diff --git a/libc/sysv/consts/TIOCPKT_FLUSHREAD.s b/libc/sysv/consts/TIOCPKT_FLUSHREAD.s new file mode 100644 index 00000000..dc60a2ef --- /dev/null +++ b/libc/sysv/consts/TIOCPKT_FLUSHREAD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pty TIOCPKT_FLUSHREAD 1 1 1 1 1 diff --git a/libc/sysv/consts/TIOCPKT_FLUSHWRITE.s b/libc/sysv/consts/TIOCPKT_FLUSHWRITE.s new file mode 100644 index 00000000..a3ba7aa8 --- /dev/null +++ b/libc/sysv/consts/TIOCPKT_FLUSHWRITE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pty TIOCPKT_FLUSHWRITE 2 2 2 2 2 diff --git a/libc/sysv/consts/TIOCPKT_IOCTL.s b/libc/sysv/consts/TIOCPKT_IOCTL.s new file mode 100644 index 00000000..6e79b5c5 --- /dev/null +++ b/libc/sysv/consts/TIOCPKT_IOCTL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pty TIOCPKT_IOCTL 64 64 64 64 64 diff --git a/libc/sysv/consts/TIOCPKT_NOSTOP.s b/libc/sysv/consts/TIOCPKT_NOSTOP.s new file mode 100644 index 00000000..41218954 --- /dev/null +++ b/libc/sysv/consts/TIOCPKT_NOSTOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pty TIOCPKT_NOSTOP 16 16 16 16 16 diff --git a/libc/sysv/consts/TIOCPKT_START.s b/libc/sysv/consts/TIOCPKT_START.s new file mode 100644 index 00000000..aa807a6c --- /dev/null +++ b/libc/sysv/consts/TIOCPKT_START.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pty TIOCPKT_START 8 8 8 8 8 diff --git a/libc/sysv/consts/TIOCPKT_STOP.s b/libc/sysv/consts/TIOCPKT_STOP.s new file mode 100644 index 00000000..1b2bb758 --- /dev/null +++ b/libc/sysv/consts/TIOCPKT_STOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pty TIOCPKT_STOP 4 4 4 4 4 diff --git a/libc/sysv/consts/TIOCPTMASTER.s b/libc/sysv/consts/TIOCPTMASTER.s new file mode 100644 index 00000000..8fd2cbee --- /dev/null +++ b/libc/sysv/consts/TIOCPTMASTER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCPTMASTER 0 0 0x2000741c 0 -1 diff --git a/libc/sysv/consts/TIOCREMOTE.s b/libc/sysv/consts/TIOCREMOTE.s new file mode 100644 index 00000000..0edb3999 --- /dev/null +++ b/libc/sysv/consts/TIOCREMOTE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCREMOTE 0 0x80047469 0 0x80047469 -1 diff --git a/libc/sysv/consts/TIOCSBRK.s b/libc/sysv/consts/TIOCSBRK.s new file mode 100644 index 00000000..e398bfa7 --- /dev/null +++ b/libc/sysv/consts/TIOCSBRK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSBRK 0x5427 0x2000747b 0x2000747b 0x2000747b -1 diff --git a/libc/sysv/consts/TIOCSCTTY.s b/libc/sysv/consts/TIOCSCTTY.s new file mode 100644 index 00000000..b868a1e2 --- /dev/null +++ b/libc/sysv/consts/TIOCSCTTY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSCTTY 0x540e 0x20007461 0x20007461 0x20007461 -1 diff --git a/libc/sysv/consts/TIOCSDRAINWAIT.s b/libc/sysv/consts/TIOCSDRAINWAIT.s new file mode 100644 index 00000000..6c0dfa47 --- /dev/null +++ b/libc/sysv/consts/TIOCSDRAINWAIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSDRAINWAIT 0 0x80047457 0x80047457 0 -1 diff --git a/libc/sysv/consts/TIOCSDTR.s b/libc/sysv/consts/TIOCSDTR.s new file mode 100644 index 00000000..c2716ff6 --- /dev/null +++ b/libc/sysv/consts/TIOCSDTR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSDTR 0 0x20007479 0x20007479 0x20007479 -1 diff --git a/libc/sysv/consts/TIOCSERGETLSR.s b/libc/sysv/consts/TIOCSERGETLSR.s new file mode 100644 index 00000000..e096f351 --- /dev/null +++ b/libc/sysv/consts/TIOCSERGETLSR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSERGETLSR 0x5459 0 0 0 0 diff --git a/libc/sysv/consts/TIOCSERGETMULTI.s b/libc/sysv/consts/TIOCSERGETMULTI.s new file mode 100644 index 00000000..f4927e88 --- /dev/null +++ b/libc/sysv/consts/TIOCSERGETMULTI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSERGETMULTI 0x545a 0 0 0 0 diff --git a/libc/sysv/consts/TIOCSERSETMULTI.s b/libc/sysv/consts/TIOCSERSETMULTI.s new file mode 100644 index 00000000..95b2626e --- /dev/null +++ b/libc/sysv/consts/TIOCSERSETMULTI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSERSETMULTI 0x545b 0 0 0 0 diff --git a/libc/sysv/consts/TIOCSER_TEMT.s b/libc/sysv/consts/TIOCSER_TEMT.s new file mode 100644 index 00000000..b412417b --- /dev/null +++ b/libc/sysv/consts/TIOCSER_TEMT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSER_TEMT 1 0 0 0 0 diff --git a/libc/sysv/consts/TIOCSETA.s b/libc/sysv/consts/TIOCSETA.s new file mode 100644 index 00000000..6706f696 --- /dev/null +++ b/libc/sysv/consts/TIOCSETA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat TIOCSETA 0x5402 0x80487414 0x802c7414 0x802c7414 0x5402 diff --git a/libc/sysv/consts/TIOCSETAF.s b/libc/sysv/consts/TIOCSETAF.s new file mode 100644 index 00000000..5f75db0c --- /dev/null +++ b/libc/sysv/consts/TIOCSETAF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat TIOCSETAF 0x5404 0x80487416 0x802c7416 0x802c7416 0x5402 diff --git a/libc/sysv/consts/TIOCSETAW.s b/libc/sysv/consts/TIOCSETAW.s new file mode 100644 index 00000000..5197487d --- /dev/null +++ b/libc/sysv/consts/TIOCSETAW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat TIOCSETAW 0x5403 0x80487415 0x802c7415 0x802c7415 0x5403 diff --git a/libc/sysv/consts/TIOCSETD.s b/libc/sysv/consts/TIOCSETD.s new file mode 100644 index 00000000..0d641869 --- /dev/null +++ b/libc/sysv/consts/TIOCSETD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSETD 0x5423 0x8004741b 0x8004741b 0x8004741b -1 diff --git a/libc/sysv/consts/TIOCSETVERAUTH.s b/libc/sysv/consts/TIOCSETVERAUTH.s new file mode 100644 index 00000000..b8501fde --- /dev/null +++ b/libc/sysv/consts/TIOCSETVERAUTH.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSETVERAUTH 0 0 0 0x8004741c -1 diff --git a/libc/sysv/consts/TIOCSFLAGS.s b/libc/sysv/consts/TIOCSFLAGS.s new file mode 100644 index 00000000..65b3773d --- /dev/null +++ b/libc/sysv/consts/TIOCSFLAGS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSFLAGS 0 0 0 0x8004745c -1 diff --git a/libc/sysv/consts/TIOCSIG.s b/libc/sysv/consts/TIOCSIG.s new file mode 100644 index 00000000..d20070b4 --- /dev/null +++ b/libc/sysv/consts/TIOCSIG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSIG 0x40045436 0x2000745f 0x2004745f 0x8004745f -1 diff --git a/libc/sysv/consts/TIOCSPGRP.s b/libc/sysv/consts/TIOCSPGRP.s new file mode 100644 index 00000000..d8b6f2b7 --- /dev/null +++ b/libc/sysv/consts/TIOCSPGRP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSPGRP 0x5410 0x80047476 0x80047476 0x80047476 -1 diff --git a/libc/sysv/consts/TIOCSPTLCK.s b/libc/sysv/consts/TIOCSPTLCK.s new file mode 100644 index 00000000..68d4107a --- /dev/null +++ b/libc/sysv/consts/TIOCSPTLCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon pty TIOCSPTLCK 0x40045431 0 0 0 -1 diff --git a/libc/sysv/consts/TIOCSTART.s b/libc/sysv/consts/TIOCSTART.s new file mode 100644 index 00000000..1162777c --- /dev/null +++ b/libc/sysv/consts/TIOCSTART.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSTART 0 0x2000746e 0x2000746e 0x2000746e -1 diff --git a/libc/sysv/consts/TIOCSTAT.s b/libc/sysv/consts/TIOCSTAT.s new file mode 100644 index 00000000..1e7ac40e --- /dev/null +++ b/libc/sysv/consts/TIOCSTAT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSTAT 0 0x20007465 0x20007465 0x20007465 -1 diff --git a/libc/sysv/consts/TIOCSTI.s b/libc/sysv/consts/TIOCSTI.s new file mode 100644 index 00000000..54e48a33 --- /dev/null +++ b/libc/sysv/consts/TIOCSTI.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSTI 0x5412 0x80017472 0x80017472 0 -1 diff --git a/libc/sysv/consts/TIOCSTSTAMP.s b/libc/sysv/consts/TIOCSTSTAMP.s new file mode 100644 index 00000000..794b98f4 --- /dev/null +++ b/libc/sysv/consts/TIOCSTSTAMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSTSTAMP 0 0 0 0x8008745a -1 diff --git a/libc/sysv/consts/TIOCSWINSZ.s b/libc/sysv/consts/TIOCSWINSZ.s new file mode 100644 index 00000000..fd5ac68f --- /dev/null +++ b/libc/sysv/consts/TIOCSWINSZ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCSWINSZ 0x5414 0x80087467 0x80087467 0x80087467 0x5414 diff --git a/libc/sysv/consts/TIOCTIMESTAMP.s b/libc/sysv/consts/TIOCTIMESTAMP.s new file mode 100644 index 00000000..45c35c6e --- /dev/null +++ b/libc/sysv/consts/TIOCTIMESTAMP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCTIMESTAMP 0 0x40107459 0x40107459 0 -1 diff --git a/libc/sysv/consts/TIOCUCNTL_CBRK.s b/libc/sysv/consts/TIOCUCNTL_CBRK.s new file mode 100644 index 00000000..c9c695a5 --- /dev/null +++ b/libc/sysv/consts/TIOCUCNTL_CBRK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TIOCUCNTL_CBRK 0 0 0 0x7a -1 diff --git a/libc/sysv/consts/TMAGLEN.s b/libc/sysv/consts/TMAGLEN.s new file mode 100644 index 00000000..833da763 --- /dev/null +++ b/libc/sysv/consts/TMAGLEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TMAGLEN 6 6 6 6 0 diff --git a/libc/sysv/consts/TMP_MAX.s b/libc/sysv/consts/TMP_MAX.s new file mode 100644 index 00000000..a42dcd6c --- /dev/null +++ b/libc/sysv/consts/TMP_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TMP_MAX 0x03a2f8 0x1269ae40 0x1269ae40 0x7fffffff 0 diff --git a/libc/sysv/consts/TOEXEC.s b/libc/sysv/consts/TOEXEC.s new file mode 100644 index 00000000..6cbe33bc --- /dev/null +++ b/libc/sysv/consts/TOEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TOEXEC 1 1 1 1 0 diff --git a/libc/sysv/consts/TOREAD.s b/libc/sysv/consts/TOREAD.s new file mode 100644 index 00000000..4225031b --- /dev/null +++ b/libc/sysv/consts/TOREAD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TOREAD 4 4 4 4 0 diff --git a/libc/sysv/consts/TOSTOP.s b/libc/sysv/consts/TOSTOP.s new file mode 100644 index 00000000..0a595ed1 --- /dev/null +++ b/libc/sysv/consts/TOSTOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TOSTOP 0b0000000100000000 4194304 4194304 4194304 0b0000000100000000 diff --git a/libc/sysv/consts/TOWRITE.s b/libc/sysv/consts/TOWRITE.s new file mode 100644 index 00000000..d3718aa7 --- /dev/null +++ b/libc/sysv/consts/TOWRITE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TOWRITE 2 2 2 2 0 diff --git a/libc/sysv/consts/TRANSIENT.s b/libc/sysv/consts/TRANSIENT.s new file mode 100644 index 00000000..f9414a7c --- /dev/null +++ b/libc/sysv/consts/TRANSIENT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TRANSIENT 4 4 4 4 0 diff --git a/libc/sysv/consts/TRAP_BRKPT.s b/libc/sysv/consts/TRAP_BRKPT.s new file mode 100644 index 00000000..61085617 --- /dev/null +++ b/libc/sysv/consts/TRAP_BRKPT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TRAP_BRKPT 1 1 1 1 0 diff --git a/libc/sysv/consts/TRAP_TRACE.s b/libc/sysv/consts/TRAP_TRACE.s new file mode 100644 index 00000000..80857996 --- /dev/null +++ b/libc/sysv/consts/TRAP_TRACE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TRAP_TRACE 2 2 2 2 0 diff --git a/libc/sysv/consts/TRY_AGAIN.s b/libc/sysv/consts/TRY_AGAIN.s new file mode 100644 index 00000000..0e98c99e --- /dev/null +++ b/libc/sysv/consts/TRY_AGAIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TRY_AGAIN 2 2 2 2 0x2afa diff --git a/libc/sysv/consts/TSGID.s b/libc/sysv/consts/TSGID.s new file mode 100644 index 00000000..29b6c5a2 --- /dev/null +++ b/libc/sysv/consts/TSGID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TSGID 0x0400 0x0400 0x0400 0x0400 0 diff --git a/libc/sysv/consts/TSS_DTOR_ITERATIONS.s b/libc/sysv/consts/TSS_DTOR_ITERATIONS.s new file mode 100644 index 00000000..59349b5a --- /dev/null +++ b/libc/sysv/consts/TSS_DTOR_ITERATIONS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TSS_DTOR_ITERATIONS 0 0 4 0 0 diff --git a/libc/sysv/consts/TSUID.s b/libc/sysv/consts/TSUID.s new file mode 100644 index 00000000..ae7a78ed --- /dev/null +++ b/libc/sysv/consts/TSUID.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TSUID 0x0800 0x0800 0x0800 0x0800 0 diff --git a/libc/sysv/consts/TSVTX.s b/libc/sysv/consts/TSVTX.s new file mode 100644 index 00000000..eb18f1a4 --- /dev/null +++ b/libc/sysv/consts/TSVTX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TSVTX 0x0200 0x0200 0x0200 0x0200 0 diff --git a/libc/sysv/consts/TTYDEF_CFLAG.s b/libc/sysv/consts/TTYDEF_CFLAG.s new file mode 100644 index 00000000..e14dc258 --- /dev/null +++ b/libc/sysv/consts/TTYDEF_CFLAG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TTYDEF_CFLAG 0x05a0 0x4b00 0x4b00 0x4b00 0 diff --git a/libc/sysv/consts/TTYDEF_IFLAG.s b/libc/sysv/consts/TTYDEF_IFLAG.s new file mode 100644 index 00000000..266163aa --- /dev/null +++ b/libc/sysv/consts/TTYDEF_IFLAG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TTYDEF_IFLAG 0x2d22 0x2b02 0x2b02 0x2b02 0 diff --git a/libc/sysv/consts/TTYDEF_LFLAG.s b/libc/sysv/consts/TTYDEF_LFLAG.s new file mode 100644 index 00000000..a2a3a506 --- /dev/null +++ b/libc/sysv/consts/TTYDEF_LFLAG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TTYDEF_LFLAG 0x8a1b 0x05cb 0x05cb 0x05cb 0 diff --git a/libc/sysv/consts/TTYDEF_OFLAG.s b/libc/sysv/consts/TTYDEF_OFLAG.s new file mode 100644 index 00000000..11d9a405 --- /dev/null +++ b/libc/sysv/consts/TTYDEF_OFLAG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TTYDEF_OFLAG 0x1805 3 3 7 0 diff --git a/libc/sysv/consts/TTYDEF_SPEED.s b/libc/sysv/consts/TTYDEF_SPEED.s new file mode 100644 index 00000000..f9f8c0f1 --- /dev/null +++ b/libc/sysv/consts/TTYDEF_SPEED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TTYDEF_SPEED 13 0x2580 0x2580 0x2580 0 diff --git a/libc/sysv/consts/TTYDISC.s b/libc/sysv/consts/TTYDISC.s new file mode 100644 index 00000000..cf8f666f --- /dev/null +++ b/libc/sysv/consts/TTYDISC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios TTYDISC 0 0 0 0 -1 diff --git a/libc/sysv/consts/TTY_NAME_MAX.s b/libc/sysv/consts/TTY_NAME_MAX.s new file mode 100644 index 00000000..f28e7235 --- /dev/null +++ b/libc/sysv/consts/TTY_NAME_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TTY_NAME_MAX 0x20 0 0 260 0 diff --git a/libc/sysv/consts/TUEXEC.s b/libc/sysv/consts/TUEXEC.s new file mode 100644 index 00000000..8a83f847 --- /dev/null +++ b/libc/sysv/consts/TUEXEC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TUEXEC 0x40 0x40 0x40 0x40 0 diff --git a/libc/sysv/consts/TUREAD.s b/libc/sysv/consts/TUREAD.s new file mode 100644 index 00000000..aca55bf1 --- /dev/null +++ b/libc/sysv/consts/TUREAD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TUREAD 0x0100 0x0100 0x0100 0x0100 0 diff --git a/libc/sysv/consts/TUWRITE.s b/libc/sysv/consts/TUWRITE.s new file mode 100644 index 00000000..34582bb0 --- /dev/null +++ b/libc/sysv/consts/TUWRITE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TUWRITE 0x80 0x80 0x80 0x80 0 diff --git a/libc/sysv/consts/TVERSLEN.s b/libc/sysv/consts/TVERSLEN.s new file mode 100644 index 00000000..c9aecb0a --- /dev/null +++ b/libc/sysv/consts/TVERSLEN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TVERSLEN 2 2 2 2 0 diff --git a/libc/sysv/consts/TYPE_A.s b/libc/sysv/consts/TYPE_A.s new file mode 100644 index 00000000..31558886 --- /dev/null +++ b/libc/sysv/consts/TYPE_A.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TYPE_A 1 1 1 1 0 diff --git a/libc/sysv/consts/TYPE_DISK.s b/libc/sysv/consts/TYPE_DISK.s new file mode 100644 index 00000000..08c0ef77 --- /dev/null +++ b/libc/sysv/consts/TYPE_DISK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TYPE_DISK 0 0 0 0 0 diff --git a/libc/sysv/consts/TYPE_E.s b/libc/sysv/consts/TYPE_E.s new file mode 100644 index 00000000..057a5a48 --- /dev/null +++ b/libc/sysv/consts/TYPE_E.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TYPE_E 2 2 2 2 0 diff --git a/libc/sysv/consts/TYPE_ENCLOSURE.s b/libc/sysv/consts/TYPE_ENCLOSURE.s new file mode 100644 index 00000000..fef74cae --- /dev/null +++ b/libc/sysv/consts/TYPE_ENCLOSURE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TYPE_ENCLOSURE 13 0 0 0 0 diff --git a/libc/sysv/consts/TYPE_I.s b/libc/sysv/consts/TYPE_I.s new file mode 100644 index 00000000..a3177ced --- /dev/null +++ b/libc/sysv/consts/TYPE_I.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TYPE_I 3 3 3 3 0 diff --git a/libc/sysv/consts/TYPE_L.s b/libc/sysv/consts/TYPE_L.s new file mode 100644 index 00000000..913b8a22 --- /dev/null +++ b/libc/sysv/consts/TYPE_L.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TYPE_L 4 4 4 4 0 diff --git a/libc/sysv/consts/TYPE_MEDIUM_CHANGER.s b/libc/sysv/consts/TYPE_MEDIUM_CHANGER.s new file mode 100644 index 00000000..87ed0a14 --- /dev/null +++ b/libc/sysv/consts/TYPE_MEDIUM_CHANGER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TYPE_MEDIUM_CHANGER 8 0 0 0 0 diff --git a/libc/sysv/consts/TYPE_MOD.s b/libc/sysv/consts/TYPE_MOD.s new file mode 100644 index 00000000..6e00a261 --- /dev/null +++ b/libc/sysv/consts/TYPE_MOD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TYPE_MOD 7 0 0 0 0 diff --git a/libc/sysv/consts/TYPE_NO_LUN.s b/libc/sysv/consts/TYPE_NO_LUN.s new file mode 100644 index 00000000..07921e64 --- /dev/null +++ b/libc/sysv/consts/TYPE_NO_LUN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TYPE_NO_LUN 127 0 0 0 0 diff --git a/libc/sysv/consts/TYPE_PROCESSOR.s b/libc/sysv/consts/TYPE_PROCESSOR.s new file mode 100644 index 00000000..9eb87b5c --- /dev/null +++ b/libc/sysv/consts/TYPE_PROCESSOR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TYPE_PROCESSOR 3 0 0 0 0 diff --git a/libc/sysv/consts/TYPE_ROM.s b/libc/sysv/consts/TYPE_ROM.s new file mode 100644 index 00000000..525ae35e --- /dev/null +++ b/libc/sysv/consts/TYPE_ROM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TYPE_ROM 5 0 0 0 0 diff --git a/libc/sysv/consts/TYPE_SCANNER.s b/libc/sysv/consts/TYPE_SCANNER.s new file mode 100644 index 00000000..5f6f68ba --- /dev/null +++ b/libc/sysv/consts/TYPE_SCANNER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TYPE_SCANNER 6 0 0 0 0 diff --git a/libc/sysv/consts/TYPE_TAPE.s b/libc/sysv/consts/TYPE_TAPE.s new file mode 100644 index 00000000..fc4dbc10 --- /dev/null +++ b/libc/sysv/consts/TYPE_TAPE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TYPE_TAPE 1 0 0 0 0 diff --git a/libc/sysv/consts/TYPE_WORM.s b/libc/sysv/consts/TYPE_WORM.s new file mode 100644 index 00000000..29d6cc6e --- /dev/null +++ b/libc/sysv/consts/TYPE_WORM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc TYPE_WORM 4 0 0 0 0 diff --git a/libc/sysv/consts/T_FMT.s b/libc/sysv/consts/T_FMT.s new file mode 100644 index 00000000..e206f9b9 --- /dev/null +++ b/libc/sysv/consts/T_FMT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc T_FMT 0x02002a 3 3 2 0 diff --git a/libc/sysv/consts/T_FMT_AMPM.s b/libc/sysv/consts/T_FMT_AMPM.s new file mode 100644 index 00000000..b347deb9 --- /dev/null +++ b/libc/sysv/consts/T_FMT_AMPM.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc T_FMT_AMPM 0x02002b 4 4 3 0 diff --git a/libc/sysv/consts/UDP_ENCAP_ESPINUDP_NON_IKE.s b/libc/sysv/consts/UDP_ENCAP_ESPINUDP_NON_IKE.s new file mode 100644 index 00000000..86dcb206 --- /dev/null +++ b/libc/sysv/consts/UDP_ENCAP_ESPINUDP_NON_IKE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc UDP_ENCAP_ESPINUDP_NON_IKE 1 0 1 0 0 diff --git a/libc/sysv/consts/UDP_NO_CHECK6_RX.s b/libc/sysv/consts/UDP_NO_CHECK6_RX.s new file mode 100644 index 00000000..a6dad40e --- /dev/null +++ b/libc/sysv/consts/UDP_NO_CHECK6_RX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc UDP_NO_CHECK6_RX 102 0 0 0 0 diff --git a/libc/sysv/consts/UDP_NO_CHECK6_TX.s b/libc/sysv/consts/UDP_NO_CHECK6_TX.s new file mode 100644 index 00000000..b2bf12d1 --- /dev/null +++ b/libc/sysv/consts/UDP_NO_CHECK6_TX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc UDP_NO_CHECK6_TX 101 0 0 0 0 diff --git a/libc/sysv/consts/UIO_MAXIOV.s b/libc/sysv/consts/UIO_MAXIOV.s new file mode 100644 index 00000000..5f0883aa --- /dev/null +++ b/libc/sysv/consts/UIO_MAXIOV.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc UIO_MAXIOV 0x0400 0 0 0x0400 0 diff --git a/libc/sysv/consts/UL_GETFSIZE.s b/libc/sysv/consts/UL_GETFSIZE.s new file mode 100644 index 00000000..486db9a9 --- /dev/null +++ b/libc/sysv/consts/UL_GETFSIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc UL_GETFSIZE 1 1 1 0 0 diff --git a/libc/sysv/consts/UL_SETFSIZE.s b/libc/sysv/consts/UL_SETFSIZE.s new file mode 100644 index 00000000..5d1b2159 --- /dev/null +++ b/libc/sysv/consts/UL_SETFSIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc UL_SETFSIZE 2 2 2 0 0 diff --git a/libc/sysv/consts/UMOUNT_NOFOLLOW.s b/libc/sysv/consts/UMOUNT_NOFOLLOW.s new file mode 100644 index 00000000..e3dac741 --- /dev/null +++ b/libc/sysv/consts/UMOUNT_NOFOLLOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc UMOUNT_NOFOLLOW 8 0 0 0 0 diff --git a/libc/sysv/consts/UNAME26.s b/libc/sysv/consts/UNAME26.s new file mode 100644 index 00000000..f168a638 --- /dev/null +++ b/libc/sysv/consts/UNAME26.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon prsnlty UNAME26 0x0020000 -1 -1 -1 -1 diff --git a/libc/sysv/consts/UNIT_ATTENTION.s b/libc/sysv/consts/UNIT_ATTENTION.s new file mode 100644 index 00000000..f1e89adb --- /dev/null +++ b/libc/sysv/consts/UNIT_ATTENTION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc UNIT_ATTENTION 6 0 0 0 0 diff --git a/libc/sysv/consts/UPDATE_BLOCK.s b/libc/sysv/consts/UPDATE_BLOCK.s new file mode 100644 index 00000000..223a487a --- /dev/null +++ b/libc/sysv/consts/UPDATE_BLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc UPDATE_BLOCK 61 0 0 0 0 diff --git a/libc/sysv/consts/USER_PROCESS.s b/libc/sysv/consts/USER_PROCESS.s new file mode 100644 index 00000000..c735c3a9 --- /dev/null +++ b/libc/sysv/consts/USER_PROCESS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc USER_PROCESS 7 7 4 0 0 diff --git a/libc/sysv/consts/USRQUOTA.s b/libc/sysv/consts/USRQUOTA.s new file mode 100644 index 00000000..2e5309d0 --- /dev/null +++ b/libc/sysv/consts/USRQUOTA.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc USRQUOTA 0 0 0 0 0 diff --git a/libc/sysv/consts/UTIME_NOW.s b/libc/sysv/consts/UTIME_NOW.s new file mode 100644 index 00000000..509c2643 --- /dev/null +++ b/libc/sysv/consts/UTIME_NOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc UTIME_NOW 0x3fffffff 0 -1 -2 0 diff --git a/libc/sysv/consts/UTIME_OMIT.s b/libc/sysv/consts/UTIME_OMIT.s new file mode 100644 index 00000000..db949173 --- /dev/null +++ b/libc/sysv/consts/UTIME_OMIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc UTIME_OMIT 0x3ffffffe 0 -2 -1 0 diff --git a/libc/sysv/consts/UT_HOSTSIZE.s b/libc/sysv/consts/UT_HOSTSIZE.s new file mode 100644 index 00000000..d6482ae9 --- /dev/null +++ b/libc/sysv/consts/UT_HOSTSIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc UT_HOSTSIZE 0x0100 0x10 0 0x0100 0 diff --git a/libc/sysv/consts/UT_LINESIZE.s b/libc/sysv/consts/UT_LINESIZE.s new file mode 100644 index 00000000..983c7c8e --- /dev/null +++ b/libc/sysv/consts/UT_LINESIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc UT_LINESIZE 0x20 8 0 8 0 diff --git a/libc/sysv/consts/UT_NAMESIZE.s b/libc/sysv/consts/UT_NAMESIZE.s new file mode 100644 index 00000000..53183f3b --- /dev/null +++ b/libc/sysv/consts/UT_NAMESIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc UT_NAMESIZE 0x20 8 0 0x20 0 diff --git a/libc/sysv/consts/VDISCARD.s b/libc/sysv/consts/VDISCARD.s new file mode 100644 index 00000000..866ee704 --- /dev/null +++ b/libc/sysv/consts/VDISCARD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VDISCARD 13 15 15 15 0 diff --git a/libc/sysv/consts/VEOF.s b/libc/sysv/consts/VEOF.s new file mode 100644 index 00000000..578cd150 --- /dev/null +++ b/libc/sysv/consts/VEOF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VEOF 4 0 0 0 0 diff --git a/libc/sysv/consts/VEOL.s b/libc/sysv/consts/VEOL.s new file mode 100644 index 00000000..55454584 --- /dev/null +++ b/libc/sysv/consts/VEOL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VEOL 11 1 1 1 0 diff --git a/libc/sysv/consts/VEOL2.s b/libc/sysv/consts/VEOL2.s new file mode 100644 index 00000000..eae1cd06 --- /dev/null +++ b/libc/sysv/consts/VEOL2.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VEOL2 16 2 2 2 0 diff --git a/libc/sysv/consts/VERASE.s b/libc/sysv/consts/VERASE.s new file mode 100644 index 00000000..4e0fa78d --- /dev/null +++ b/libc/sysv/consts/VERASE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VERASE 2 3 3 3 0 diff --git a/libc/sysv/consts/VERIFY.s b/libc/sysv/consts/VERIFY.s new file mode 100644 index 00000000..a0cae527 --- /dev/null +++ b/libc/sysv/consts/VERIFY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VERIFY 47 0 0 0 0 diff --git a/libc/sysv/consts/VINTR.s b/libc/sysv/consts/VINTR.s new file mode 100644 index 00000000..e1c52a12 --- /dev/null +++ b/libc/sysv/consts/VINTR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VINTR 0 8 8 8 0 diff --git a/libc/sysv/consts/VKILL.s b/libc/sysv/consts/VKILL.s new file mode 100644 index 00000000..adb9809e --- /dev/null +++ b/libc/sysv/consts/VKILL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VKILL 3 5 5 5 0 diff --git a/libc/sysv/consts/VLNEXT.s b/libc/sysv/consts/VLNEXT.s new file mode 100644 index 00000000..7f956ce3 --- /dev/null +++ b/libc/sysv/consts/VLNEXT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VLNEXT 15 14 14 14 0 diff --git a/libc/sysv/consts/VMIN.s b/libc/sysv/consts/VMIN.s new file mode 100644 index 00000000..0c29076d --- /dev/null +++ b/libc/sysv/consts/VMIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VMIN 6 16 16 16 0 diff --git a/libc/sysv/consts/VOLUME_OVERFLOW.s b/libc/sysv/consts/VOLUME_OVERFLOW.s new file mode 100644 index 00000000..7a55dd9e --- /dev/null +++ b/libc/sysv/consts/VOLUME_OVERFLOW.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc VOLUME_OVERFLOW 13 0 0 0 0 diff --git a/libc/sysv/consts/VQUIT.s b/libc/sysv/consts/VQUIT.s new file mode 100644 index 00000000..c8ee8e9c --- /dev/null +++ b/libc/sysv/consts/VQUIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VQUIT 1 9 9 9 0 diff --git a/libc/sysv/consts/VREPRINT.s b/libc/sysv/consts/VREPRINT.s new file mode 100644 index 00000000..2c631e31 --- /dev/null +++ b/libc/sysv/consts/VREPRINT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VREPRINT 12 6 6 6 0 diff --git a/libc/sysv/consts/VSTART.s b/libc/sysv/consts/VSTART.s new file mode 100644 index 00000000..b5879e61 --- /dev/null +++ b/libc/sysv/consts/VSTART.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VSTART 8 12 12 12 0 diff --git a/libc/sysv/consts/VSTOP.s b/libc/sysv/consts/VSTOP.s new file mode 100644 index 00000000..abeae143 --- /dev/null +++ b/libc/sysv/consts/VSTOP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VSTOP 9 13 13 13 0 diff --git a/libc/sysv/consts/VSUSP.s b/libc/sysv/consts/VSUSP.s new file mode 100644 index 00000000..e2ecefa6 --- /dev/null +++ b/libc/sysv/consts/VSUSP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VSUSP 10 10 10 10 0 diff --git a/libc/sysv/consts/VSWTC.s b/libc/sysv/consts/VSWTC.s new file mode 100644 index 00000000..2b141c48 --- /dev/null +++ b/libc/sysv/consts/VSWTC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VSWTC 7 0 0 0 0 diff --git a/libc/sysv/consts/VT0.s b/libc/sysv/consts/VT0.s new file mode 100644 index 00000000..42169c6c --- /dev/null +++ b/libc/sysv/consts/VT0.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VT0 0b0000000000000000 0b000000000000000000 0b000000000000000000 0 0b0000000000000000 diff --git a/libc/sysv/consts/VT1.s b/libc/sysv/consts/VT1.s new file mode 100644 index 00000000..4d107bc0 --- /dev/null +++ b/libc/sysv/consts/VT1.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VT1 0b0100000000000000 0b010000000000000000 0b010000000000000000 0 0b0100000000000000 diff --git a/libc/sysv/consts/VTDLY.s b/libc/sysv/consts/VTDLY.s new file mode 100644 index 00000000..3b7b2314 --- /dev/null +++ b/libc/sysv/consts/VTDLY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VTDLY 0b0100000000000000 0b010000000000000000 0b010000000000000000 0 0b0100000000000000 diff --git a/libc/sysv/consts/VTIME.s b/libc/sysv/consts/VTIME.s new file mode 100644 index 00000000..a3050039 --- /dev/null +++ b/libc/sysv/consts/VTIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VTIME 5 17 17 17 0 diff --git a/libc/sysv/consts/VWERASE.s b/libc/sysv/consts/VWERASE.s new file mode 100644 index 00000000..18cfe82a --- /dev/null +++ b/libc/sysv/consts/VWERASE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios VWERASE 14 4 4 4 0 diff --git a/libc/sysv/consts/WCONTINUED.s b/libc/sysv/consts/WCONTINUED.s new file mode 100644 index 00000000..b1023eb2 --- /dev/null +++ b/libc/sysv/consts/WCONTINUED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WCONTINUED 8 0x10 4 8 0 diff --git a/libc/sysv/consts/WEOF.s b/libc/sysv/consts/WEOF.s new file mode 100644 index 00000000..44d934dd --- /dev/null +++ b/libc/sysv/consts/WEOF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WEOF 0xffffffff -1 -1 -1 -1 diff --git a/libc/sysv/consts/WEXITED.s b/libc/sysv/consts/WEXITED.s new file mode 100644 index 00000000..3e0360dc --- /dev/null +++ b/libc/sysv/consts/WEXITED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WEXITED 4 4 0x10 0 0 diff --git a/libc/sysv/consts/WHOLE_SECONDS.s b/libc/sysv/consts/WHOLE_SECONDS.s new file mode 100644 index 00000000..5638d489 --- /dev/null +++ b/libc/sysv/consts/WHOLE_SECONDS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon prsnlty WHOLE_SECONDS 0x2000000 -1 -1 -1 -1 diff --git a/libc/sysv/consts/WNOHANG.s b/libc/sysv/consts/WNOHANG.s new file mode 100644 index 00000000..9be7b428 --- /dev/null +++ b/libc/sysv/consts/WNOHANG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WNOHANG 1 1 1 1 0 diff --git a/libc/sysv/consts/WNOWAIT.s b/libc/sysv/consts/WNOWAIT.s new file mode 100644 index 00000000..e3a4dddb --- /dev/null +++ b/libc/sysv/consts/WNOWAIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WNOWAIT 0x01000000 0x20 8 0 0 diff --git a/libc/sysv/consts/WORD_BIT.s b/libc/sysv/consts/WORD_BIT.s new file mode 100644 index 00000000..2159fa86 --- /dev/null +++ b/libc/sysv/consts/WORD_BIT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WORD_BIT 0x20 0x20 0x20 0x20 0 diff --git a/libc/sysv/consts/WRDE_APPEND.s b/libc/sysv/consts/WRDE_APPEND.s new file mode 100644 index 00000000..54657b2d --- /dev/null +++ b/libc/sysv/consts/WRDE_APPEND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRDE_APPEND 0 1 1 0 0 diff --git a/libc/sysv/consts/WRDE_BADCHAR.s b/libc/sysv/consts/WRDE_BADCHAR.s new file mode 100644 index 00000000..4d66371b --- /dev/null +++ b/libc/sysv/consts/WRDE_BADCHAR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRDE_BADCHAR 0 1 1 0 0 diff --git a/libc/sysv/consts/WRDE_BADVAL.s b/libc/sysv/consts/WRDE_BADVAL.s new file mode 100644 index 00000000..c5b0950f --- /dev/null +++ b/libc/sysv/consts/WRDE_BADVAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRDE_BADVAL 0 2 2 0 0 diff --git a/libc/sysv/consts/WRDE_CMDSUB.s b/libc/sysv/consts/WRDE_CMDSUB.s new file mode 100644 index 00000000..6c0f67b4 --- /dev/null +++ b/libc/sysv/consts/WRDE_CMDSUB.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRDE_CMDSUB 0 3 3 0 0 diff --git a/libc/sysv/consts/WRDE_DOOFFS.s b/libc/sysv/consts/WRDE_DOOFFS.s new file mode 100644 index 00000000..8465bc34 --- /dev/null +++ b/libc/sysv/consts/WRDE_DOOFFS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRDE_DOOFFS 0 2 2 0 0 diff --git a/libc/sysv/consts/WRDE_NOCMD.s b/libc/sysv/consts/WRDE_NOCMD.s new file mode 100644 index 00000000..333ef0da --- /dev/null +++ b/libc/sysv/consts/WRDE_NOCMD.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRDE_NOCMD 0 4 4 0 0 diff --git a/libc/sysv/consts/WRDE_NOSPACE.s b/libc/sysv/consts/WRDE_NOSPACE.s new file mode 100644 index 00000000..c8d504cb --- /dev/null +++ b/libc/sysv/consts/WRDE_NOSPACE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRDE_NOSPACE 0 4 4 0 0 diff --git a/libc/sysv/consts/WRDE_NOSYS.s b/libc/sysv/consts/WRDE_NOSYS.s new file mode 100644 index 00000000..dd55320a --- /dev/null +++ b/libc/sysv/consts/WRDE_NOSYS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRDE_NOSYS 0 5 5 0 0 diff --git a/libc/sysv/consts/WRDE_REUSE.s b/libc/sysv/consts/WRDE_REUSE.s new file mode 100644 index 00000000..bc63e009 --- /dev/null +++ b/libc/sysv/consts/WRDE_REUSE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRDE_REUSE 0 8 8 0 0 diff --git a/libc/sysv/consts/WRDE_SHOWERR.s b/libc/sysv/consts/WRDE_SHOWERR.s new file mode 100644 index 00000000..8d508f2c --- /dev/null +++ b/libc/sysv/consts/WRDE_SHOWERR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRDE_SHOWERR 0 0x10 0x10 0 0 diff --git a/libc/sysv/consts/WRDE_SYNTAX.s b/libc/sysv/consts/WRDE_SYNTAX.s new file mode 100644 index 00000000..97775b5b --- /dev/null +++ b/libc/sysv/consts/WRDE_SYNTAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRDE_SYNTAX 0 6 6 0 0 diff --git a/libc/sysv/consts/WRDE_UNDEF.s b/libc/sysv/consts/WRDE_UNDEF.s new file mode 100644 index 00000000..f1192b19 --- /dev/null +++ b/libc/sysv/consts/WRDE_UNDEF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRDE_UNDEF 0 0x20 0x20 0 0 diff --git a/libc/sysv/consts/WRITE_10.s b/libc/sysv/consts/WRITE_10.s new file mode 100644 index 00000000..48073a97 --- /dev/null +++ b/libc/sysv/consts/WRITE_10.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRITE_10 42 0 0 0 0 diff --git a/libc/sysv/consts/WRITE_12.s b/libc/sysv/consts/WRITE_12.s new file mode 100644 index 00000000..9af0c633 --- /dev/null +++ b/libc/sysv/consts/WRITE_12.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRITE_12 170 0 0 0 0 diff --git a/libc/sysv/consts/WRITE_6.s b/libc/sysv/consts/WRITE_6.s new file mode 100644 index 00000000..9bb2c0eb --- /dev/null +++ b/libc/sysv/consts/WRITE_6.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRITE_6 10 0 0 0 0 diff --git a/libc/sysv/consts/WRITE_BUFFER.s b/libc/sysv/consts/WRITE_BUFFER.s new file mode 100644 index 00000000..63afd038 --- /dev/null +++ b/libc/sysv/consts/WRITE_BUFFER.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRITE_BUFFER 59 0 0 0 0 diff --git a/libc/sysv/consts/WRITE_FILEMARKS.s b/libc/sysv/consts/WRITE_FILEMARKS.s new file mode 100644 index 00000000..8b4d08ff --- /dev/null +++ b/libc/sysv/consts/WRITE_FILEMARKS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRITE_FILEMARKS 0x10 0 0 0 0 diff --git a/libc/sysv/consts/WRITE_LONG.s b/libc/sysv/consts/WRITE_LONG.s new file mode 100644 index 00000000..ab5e3828 --- /dev/null +++ b/libc/sysv/consts/WRITE_LONG.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRITE_LONG 63 0 0 0 0 diff --git a/libc/sysv/consts/WRITE_LONG_2.s b/libc/sysv/consts/WRITE_LONG_2.s new file mode 100644 index 00000000..44923403 --- /dev/null +++ b/libc/sysv/consts/WRITE_LONG_2.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRITE_LONG_2 234 0 0 0 0 diff --git a/libc/sysv/consts/WRITE_SAME.s b/libc/sysv/consts/WRITE_SAME.s new file mode 100644 index 00000000..a1112131 --- /dev/null +++ b/libc/sysv/consts/WRITE_SAME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRITE_SAME 65 0 0 0 0 diff --git a/libc/sysv/consts/WRITE_VERIFY.s b/libc/sysv/consts/WRITE_VERIFY.s new file mode 100644 index 00000000..b6d1de67 --- /dev/null +++ b/libc/sysv/consts/WRITE_VERIFY.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRITE_VERIFY 46 0 0 0 0 diff --git a/libc/sysv/consts/WRITE_VERIFY_12.s b/libc/sysv/consts/WRITE_VERIFY_12.s new file mode 100644 index 00000000..37a96789 --- /dev/null +++ b/libc/sysv/consts/WRITE_VERIFY_12.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRITE_VERIFY_12 174 0 0 0 0 diff --git a/libc/sysv/consts/WRQ.s b/libc/sysv/consts/WRQ.s new file mode 100644 index 00000000..11962583 --- /dev/null +++ b/libc/sysv/consts/WRQ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WRQ 2 2 2 2 0 diff --git a/libc/sysv/consts/WSTOPPED.s b/libc/sysv/consts/WSTOPPED.s new file mode 100644 index 00000000..b9a41834 --- /dev/null +++ b/libc/sysv/consts/WSTOPPED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WSTOPPED 2 8 2 0 0 diff --git a/libc/sysv/consts/WUNTRACED.s b/libc/sysv/consts/WUNTRACED.s new file mode 100644 index 00000000..4f8480c6 --- /dev/null +++ b/libc/sysv/consts/WUNTRACED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc WUNTRACED 2 2 2 2 0 diff --git a/libc/sysv/consts/W_OK.s b/libc/sysv/consts/W_OK.s new file mode 100644 index 00000000..e9c15762 --- /dev/null +++ b/libc/sysv/consts/W_OK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon access W_OK 2 2 2 2 0x40000000 diff --git a/libc/sysv/consts/XATTR_CREATE.s b/libc/sysv/consts/XATTR_CREATE.s new file mode 100644 index 00000000..6b73bd55 --- /dev/null +++ b/libc/sysv/consts/XATTR_CREATE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc XATTR_CREATE 1 2 0 0 0 diff --git a/libc/sysv/consts/XATTR_REPLACE.s b/libc/sysv/consts/XATTR_REPLACE.s new file mode 100644 index 00000000..36747f7c --- /dev/null +++ b/libc/sysv/consts/XATTR_REPLACE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc XATTR_REPLACE 2 4 0 0 0 diff --git a/libc/sysv/consts/XCASE.s b/libc/sysv/consts/XCASE.s new file mode 100644 index 00000000..59b228bc --- /dev/null +++ b/libc/sysv/consts/XCASE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios XCASE 0b0000000000000100 0 0 16777216 0b0000000000000100 diff --git a/libc/sysv/consts/XTABS.s b/libc/sysv/consts/XTABS.s new file mode 100644 index 00000000..d9aad583 --- /dev/null +++ b/libc/sysv/consts/XTABS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon termios XTABS 0b0001100000000000 0b000000000000000000 0b000000110000000000 0 0b0001100000000000 diff --git a/libc/sysv/consts/X_OK.s b/libc/sysv/consts/X_OK.s new file mode 100644 index 00000000..470d18aa --- /dev/null +++ b/libc/sysv/consts/X_OK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon access X_OK 1 1 1 1 0xa0000000 diff --git a/libc/sysv/consts/YESEXPR.s b/libc/sysv/consts/YESEXPR.s new file mode 100644 index 00000000..85a61e00 --- /dev/null +++ b/libc/sysv/consts/YESEXPR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc YESEXPR 0x050000 52 52 47 0 diff --git a/libc/sysv/consts/YESSTR.s b/libc/sysv/consts/YESSTR.s new file mode 100644 index 00000000..01f2a4f4 --- /dev/null +++ b/libc/sysv/consts/YESSTR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc YESSTR 0x050002 54 54 46 0 diff --git a/libc/sysv/consts/_IOC_NONE.s b/libc/sysv/consts/_IOC_NONE.s new file mode 100644 index 00000000..a71298ff --- /dev/null +++ b/libc/sysv/consts/_IOC_NONE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _IOC_NONE 0 0 0 0 0 diff --git a/libc/sysv/consts/_IOC_READ.s b/libc/sysv/consts/_IOC_READ.s new file mode 100644 index 00000000..d32687d7 --- /dev/null +++ b/libc/sysv/consts/_IOC_READ.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _IOC_READ 2 0 0 0 0 diff --git a/libc/sysv/consts/_IOC_WRITE.s b/libc/sysv/consts/_IOC_WRITE.s new file mode 100644 index 00000000..72a73b2a --- /dev/null +++ b/libc/sysv/consts/_IOC_WRITE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _IOC_WRITE 1 0 0 0 0 diff --git a/libc/sysv/consts/_LINUX_QUOTA_VERSION.s b/libc/sysv/consts/_LINUX_QUOTA_VERSION.s new file mode 100644 index 00000000..69a84ae6 --- /dev/null +++ b/libc/sysv/consts/_LINUX_QUOTA_VERSION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _LINUX_QUOTA_VERSION 2 0 0 0 0 diff --git a/libc/sysv/consts/_POSIX2_BC_BASE_MAX.s b/libc/sysv/consts/_POSIX2_BC_BASE_MAX.s new file mode 100644 index 00000000..2179d49d --- /dev/null +++ b/libc/sysv/consts/_POSIX2_BC_BASE_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _POSIX2_BC_BASE_MAX 99 99 99 99 0 diff --git a/libc/sysv/consts/_POSIX2_BC_DIM_MAX.s b/libc/sysv/consts/_POSIX2_BC_DIM_MAX.s new file mode 100644 index 00000000..9327500d --- /dev/null +++ b/libc/sysv/consts/_POSIX2_BC_DIM_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _POSIX2_BC_DIM_MAX 0x0800 0x0800 0x0800 0x0800 0 diff --git a/libc/sysv/consts/_POSIX2_BC_SCALE_MAX.s b/libc/sysv/consts/_POSIX2_BC_SCALE_MAX.s new file mode 100644 index 00000000..62ce1e1c --- /dev/null +++ b/libc/sysv/consts/_POSIX2_BC_SCALE_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _POSIX2_BC_SCALE_MAX 99 99 99 99 0 diff --git a/libc/sysv/consts/_POSIX2_BC_STRING_MAX.s b/libc/sysv/consts/_POSIX2_BC_STRING_MAX.s new file mode 100644 index 00000000..b028f0a0 --- /dev/null +++ b/libc/sysv/consts/_POSIX2_BC_STRING_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _POSIX2_BC_STRING_MAX 0x03e8 0x03e8 0x03e8 0x03e8 0 diff --git a/libc/sysv/consts/_POSIX2_CHARCLASS_NAME_MAX.s b/libc/sysv/consts/_POSIX2_CHARCLASS_NAME_MAX.s new file mode 100644 index 00000000..25d07863 --- /dev/null +++ b/libc/sysv/consts/_POSIX2_CHARCLASS_NAME_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _POSIX2_CHARCLASS_NAME_MAX 14 14 14 14 0 diff --git a/libc/sysv/consts/_POSIX2_COLL_WEIGHTS_MAX.s b/libc/sysv/consts/_POSIX2_COLL_WEIGHTS_MAX.s new file mode 100644 index 00000000..50f4f6a3 --- /dev/null +++ b/libc/sysv/consts/_POSIX2_COLL_WEIGHTS_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _POSIX2_COLL_WEIGHTS_MAX 2 2 2 2 0 diff --git a/libc/sysv/consts/_POSIX2_C_BIND.s b/libc/sysv/consts/_POSIX2_C_BIND.s new file mode 100644 index 00000000..e6718534 --- /dev/null +++ b/libc/sysv/consts/_POSIX2_C_BIND.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _POSIX2_C_BIND 0x031069 0x030db0 0x030db0 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX2_EXPR_NEST_MAX.s b/libc/sysv/consts/_POSIX2_EXPR_NEST_MAX.s new file mode 100644 index 00000000..cfce9973 --- /dev/null +++ b/libc/sysv/consts/_POSIX2_EXPR_NEST_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _POSIX2_EXPR_NEST_MAX 0x20 0x20 0x20 0x20 0 diff --git a/libc/sysv/consts/_POSIX2_LINE_MAX.s b/libc/sysv/consts/_POSIX2_LINE_MAX.s new file mode 100644 index 00000000..1934c2c1 --- /dev/null +++ b/libc/sysv/consts/_POSIX2_LINE_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _POSIX2_LINE_MAX 0x0800 0x0800 0x0800 0x0800 0 diff --git a/libc/sysv/consts/_POSIX2_RE_DUP_MAX.s b/libc/sysv/consts/_POSIX2_RE_DUP_MAX.s new file mode 100644 index 00000000..9258b9cf --- /dev/null +++ b/libc/sysv/consts/_POSIX2_RE_DUP_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _POSIX2_RE_DUP_MAX 255 255 255 255 0 diff --git a/libc/sysv/consts/_POSIX2_VERSION.s b/libc/sysv/consts/_POSIX2_VERSION.s new file mode 100644 index 00000000..ffdd9d8b --- /dev/null +++ b/libc/sysv/consts/_POSIX2_VERSION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _POSIX2_VERSION 0x031069 0x030db0 0x030a2c 0x031069 0 diff --git a/libc/sysv/consts/_POSIX_ADVISORY_INFO.s b/libc/sysv/consts/_POSIX_ADVISORY_INFO.s new file mode 100644 index 00000000..05721bb6 --- /dev/null +++ b/libc/sysv/consts/_POSIX_ADVISORY_INFO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_ADVISORY_INFO 0x031069 -1 0x030db0 -1 0 diff --git a/libc/sysv/consts/_POSIX_AIO_LISTIO_MAX.s b/libc/sysv/consts/_POSIX_AIO_LISTIO_MAX.s new file mode 100644 index 00000000..1fa223af --- /dev/null +++ b/libc/sysv/consts/_POSIX_AIO_LISTIO_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_AIO_LISTIO_MAX 2 2 2 0 0 diff --git a/libc/sysv/consts/_POSIX_AIO_MAX.s b/libc/sysv/consts/_POSIX_AIO_MAX.s new file mode 100644 index 00000000..09488733 --- /dev/null +++ b/libc/sysv/consts/_POSIX_AIO_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_AIO_MAX 1 1 1 0 0 diff --git a/libc/sysv/consts/_POSIX_ARG_MAX.s b/libc/sysv/consts/_POSIX_ARG_MAX.s new file mode 100644 index 00000000..94bc014b --- /dev/null +++ b/libc/sysv/consts/_POSIX_ARG_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_ARG_MAX 0x1000 0x1000 0x1000 0x1000 0 diff --git a/libc/sysv/consts/_POSIX_ASYNCHRONOUS_IO.s b/libc/sysv/consts/_POSIX_ASYNCHRONOUS_IO.s new file mode 100644 index 00000000..26ef4c34 --- /dev/null +++ b/libc/sysv/consts/_POSIX_ASYNCHRONOUS_IO.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_ASYNCHRONOUS_IO 0x031069 -1 0x030db0 -1 0 diff --git a/libc/sysv/consts/_POSIX_BARRIERS.s b/libc/sysv/consts/_POSIX_BARRIERS.s new file mode 100644 index 00000000..363268a9 --- /dev/null +++ b/libc/sysv/consts/_POSIX_BARRIERS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_BARRIERS 0x031069 -1 0x030db0 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX_CHILD_MAX.s b/libc/sysv/consts/_POSIX_CHILD_MAX.s new file mode 100644 index 00000000..077a4988 --- /dev/null +++ b/libc/sysv/consts/_POSIX_CHILD_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_CHILD_MAX 25 25 25 25 0 diff --git a/libc/sysv/consts/_POSIX_CHOWN_RESTRICTED.s b/libc/sysv/consts/_POSIX_CHOWN_RESTRICTED.s new file mode 100644 index 00000000..cca770dd --- /dev/null +++ b/libc/sysv/consts/_POSIX_CHOWN_RESTRICTED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_CHOWN_RESTRICTED 0 0x030db0 1 1 0 diff --git a/libc/sysv/consts/_POSIX_CLOCKRES_MIN.s b/libc/sysv/consts/_POSIX_CLOCKRES_MIN.s new file mode 100644 index 00000000..9c72496d --- /dev/null +++ b/libc/sysv/consts/_POSIX_CLOCKRES_MIN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_CLOCKRES_MIN 0x01312d00 0 0x01312d00 0x01312d00 0 diff --git a/libc/sysv/consts/_POSIX_CLOCK_SELECTION.s b/libc/sysv/consts/_POSIX_CLOCK_SELECTION.s new file mode 100644 index 00000000..83421ef7 --- /dev/null +++ b/libc/sysv/consts/_POSIX_CLOCK_SELECTION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_CLOCK_SELECTION 0x031069 -1 -1 -1 0 diff --git a/libc/sysv/consts/_POSIX_CPUTIME.s b/libc/sysv/consts/_POSIX_CPUTIME.s new file mode 100644 index 00000000..1eedf341 --- /dev/null +++ b/libc/sysv/consts/_POSIX_CPUTIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_CPUTIME 0 -1 0x030db0 0x031069 0 diff --git a/libc/sysv/consts/_POSIX_DELAYTIMER_MAX.s b/libc/sysv/consts/_POSIX_DELAYTIMER_MAX.s new file mode 100644 index 00000000..eb22be0c --- /dev/null +++ b/libc/sysv/consts/_POSIX_DELAYTIMER_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_DELAYTIMER_MAX 0x20 0x20 0x20 0 0 diff --git a/libc/sysv/consts/_POSIX_FSYNC.s b/libc/sysv/consts/_POSIX_FSYNC.s new file mode 100644 index 00000000..3fe9a49a --- /dev/null +++ b/libc/sysv/consts/_POSIX_FSYNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_FSYNC 0x031069 0x030db0 0x030db0 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX_HOST_NAME_MAX.s b/libc/sysv/consts/_POSIX_HOST_NAME_MAX.s new file mode 100644 index 00000000..62dfd04a --- /dev/null +++ b/libc/sysv/consts/_POSIX_HOST_NAME_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_HOST_NAME_MAX 255 255 255 255 0 diff --git a/libc/sysv/consts/_POSIX_IPV6.s b/libc/sysv/consts/_POSIX_IPV6.s new file mode 100644 index 00000000..14347752 --- /dev/null +++ b/libc/sysv/consts/_POSIX_IPV6.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_IPV6 0x031069 0x030db0 0 0 0 diff --git a/libc/sysv/consts/_POSIX_JOB_CONTROL.s b/libc/sysv/consts/_POSIX_JOB_CONTROL.s new file mode 100644 index 00000000..187f7734 --- /dev/null +++ b/libc/sysv/consts/_POSIX_JOB_CONTROL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_JOB_CONTROL 1 0x030db0 1 1 0 diff --git a/libc/sysv/consts/_POSIX_LINK_MAX.s b/libc/sysv/consts/_POSIX_LINK_MAX.s new file mode 100644 index 00000000..48aae2df --- /dev/null +++ b/libc/sysv/consts/_POSIX_LINK_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_LINK_MAX 8 8 8 8 0 diff --git a/libc/sysv/consts/_POSIX_LOGIN_NAME_MAX.s b/libc/sysv/consts/_POSIX_LOGIN_NAME_MAX.s new file mode 100644 index 00000000..9c95b05a --- /dev/null +++ b/libc/sysv/consts/_POSIX_LOGIN_NAME_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_LOGIN_NAME_MAX 9 9 9 9 0 diff --git a/libc/sysv/consts/_POSIX_MAPPED_FILES.s b/libc/sysv/consts/_POSIX_MAPPED_FILES.s new file mode 100644 index 00000000..3671666d --- /dev/null +++ b/libc/sysv/consts/_POSIX_MAPPED_FILES.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_MAPPED_FILES 0x031069 0x030db0 0x030db0 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX_MAX_CANON.s b/libc/sysv/consts/_POSIX_MAX_CANON.s new file mode 100644 index 00000000..5491ad42 --- /dev/null +++ b/libc/sysv/consts/_POSIX_MAX_CANON.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_MAX_CANON 255 255 255 255 0 diff --git a/libc/sysv/consts/_POSIX_MAX_INPUT.s b/libc/sysv/consts/_POSIX_MAX_INPUT.s new file mode 100644 index 00000000..144a6377 --- /dev/null +++ b/libc/sysv/consts/_POSIX_MAX_INPUT.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_MAX_INPUT 255 255 255 255 0 diff --git a/libc/sysv/consts/_POSIX_MEMLOCK.s b/libc/sysv/consts/_POSIX_MEMLOCK.s new file mode 100644 index 00000000..a609d255 --- /dev/null +++ b/libc/sysv/consts/_POSIX_MEMLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_MEMLOCK 0x031069 -1 -1 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX_MEMLOCK_RANGE.s b/libc/sysv/consts/_POSIX_MEMLOCK_RANGE.s new file mode 100644 index 00000000..3d86891c --- /dev/null +++ b/libc/sysv/consts/_POSIX_MEMLOCK_RANGE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_MEMLOCK_RANGE 0x031069 -1 0x030db0 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX_MEMORY_PROTECTION.s b/libc/sysv/consts/_POSIX_MEMORY_PROTECTION.s new file mode 100644 index 00000000..f551795f --- /dev/null +++ b/libc/sysv/consts/_POSIX_MEMORY_PROTECTION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_MEMORY_PROTECTION 0x031069 0x030db0 0x030db0 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX_MESSAGE_PASSING.s b/libc/sysv/consts/_POSIX_MESSAGE_PASSING.s new file mode 100644 index 00000000..2edb2c91 --- /dev/null +++ b/libc/sysv/consts/_POSIX_MESSAGE_PASSING.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_MESSAGE_PASSING 0x031069 -1 0x030db0 -1 0 diff --git a/libc/sysv/consts/_POSIX_MONOTONIC_CLOCK.s b/libc/sysv/consts/_POSIX_MONOTONIC_CLOCK.s new file mode 100644 index 00000000..ca235d9f --- /dev/null +++ b/libc/sysv/consts/_POSIX_MONOTONIC_CLOCK.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_MONOTONIC_CLOCK 0 -1 0x030db0 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX_MQ_OPEN_MAX.s b/libc/sysv/consts/_POSIX_MQ_OPEN_MAX.s new file mode 100644 index 00000000..6fcb512a --- /dev/null +++ b/libc/sysv/consts/_POSIX_MQ_OPEN_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_MQ_OPEN_MAX 8 8 8 0 0 diff --git a/libc/sysv/consts/_POSIX_MQ_PRIO_MAX.s b/libc/sysv/consts/_POSIX_MQ_PRIO_MAX.s new file mode 100644 index 00000000..8a59f20a --- /dev/null +++ b/libc/sysv/consts/_POSIX_MQ_PRIO_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_MQ_PRIO_MAX 0x20 0x20 0x20 0 0 diff --git a/libc/sysv/consts/_POSIX_NAME_MAX.s b/libc/sysv/consts/_POSIX_NAME_MAX.s new file mode 100644 index 00000000..1bf0744e --- /dev/null +++ b/libc/sysv/consts/_POSIX_NAME_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_NAME_MAX 14 14 14 14 14 diff --git a/libc/sysv/consts/_POSIX_NGROUPS_MAX.s b/libc/sysv/consts/_POSIX_NGROUPS_MAX.s new file mode 100644 index 00000000..6b905459 --- /dev/null +++ b/libc/sysv/consts/_POSIX_NGROUPS_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_NGROUPS_MAX 8 8 8 8 0 diff --git a/libc/sysv/consts/_POSIX_NO_TRUNC.s b/libc/sysv/consts/_POSIX_NO_TRUNC.s new file mode 100644 index 00000000..32997386 --- /dev/null +++ b/libc/sysv/consts/_POSIX_NO_TRUNC.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_NO_TRUNC 1 0x030db0 1 1 0 diff --git a/libc/sysv/consts/_POSIX_OPEN_MAX.s b/libc/sysv/consts/_POSIX_OPEN_MAX.s new file mode 100644 index 00000000..6e2f8a72 --- /dev/null +++ b/libc/sysv/consts/_POSIX_OPEN_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_OPEN_MAX 20 20 20 20 20 diff --git a/libc/sysv/consts/_POSIX_PATH_MAX.s b/libc/sysv/consts/_POSIX_PATH_MAX.s new file mode 100644 index 00000000..1f14a108 --- /dev/null +++ b/libc/sysv/consts/_POSIX_PATH_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_PATH_MAX 255 255 255 255 255 diff --git a/libc/sysv/consts/_POSIX_PIPE_BUF.s b/libc/sysv/consts/_POSIX_PIPE_BUF.s new file mode 100644 index 00000000..d3b7db7f --- /dev/null +++ b/libc/sysv/consts/_POSIX_PIPE_BUF.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_PIPE_BUF 0x0200 0x0200 0x0200 0x0200 0 diff --git a/libc/sysv/consts/_POSIX_RAW_SOCKETS.s b/libc/sysv/consts/_POSIX_RAW_SOCKETS.s new file mode 100644 index 00000000..8fbcab73 --- /dev/null +++ b/libc/sysv/consts/_POSIX_RAW_SOCKETS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_RAW_SOCKETS 0x031069 -1 0x030db0 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX_READER_WRITER_LOCKS.s b/libc/sysv/consts/_POSIX_READER_WRITER_LOCKS.s new file mode 100644 index 00000000..f22c0884 --- /dev/null +++ b/libc/sysv/consts/_POSIX_READER_WRITER_LOCKS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_READER_WRITER_LOCKS 0x031069 0x030db0 0x030db0 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX_REALTIME_SIGNALS.s b/libc/sysv/consts/_POSIX_REALTIME_SIGNALS.s new file mode 100644 index 00000000..1f5832a2 --- /dev/null +++ b/libc/sysv/consts/_POSIX_REALTIME_SIGNALS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_REALTIME_SIGNALS 0x031069 -1 0x030db0 -1 0 diff --git a/libc/sysv/consts/_POSIX_REGEXP.s b/libc/sysv/consts/_POSIX_REGEXP.s new file mode 100644 index 00000000..3f52cb50 --- /dev/null +++ b/libc/sysv/consts/_POSIX_REGEXP.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_REGEXP 1 0x030db0 1 1 0 diff --git a/libc/sysv/consts/_POSIX_RE_DUP_MAX.s b/libc/sysv/consts/_POSIX_RE_DUP_MAX.s new file mode 100644 index 00000000..4bc31b1e --- /dev/null +++ b/libc/sysv/consts/_POSIX_RE_DUP_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_RE_DUP_MAX 255 255 255 255 0 diff --git a/libc/sysv/consts/_POSIX_RTSIG_MAX.s b/libc/sysv/consts/_POSIX_RTSIG_MAX.s new file mode 100644 index 00000000..f86a9f07 --- /dev/null +++ b/libc/sysv/consts/_POSIX_RTSIG_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_RTSIG_MAX 8 8 8 0 0 diff --git a/libc/sysv/consts/_POSIX_SAVED_IDS.s b/libc/sysv/consts/_POSIX_SAVED_IDS.s new file mode 100644 index 00000000..8c682112 --- /dev/null +++ b/libc/sysv/consts/_POSIX_SAVED_IDS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_SAVED_IDS 1 0x030db0 0 1 0 diff --git a/libc/sysv/consts/_POSIX_SEMAPHORES.s b/libc/sysv/consts/_POSIX_SEMAPHORES.s new file mode 100644 index 00000000..5133b691 --- /dev/null +++ b/libc/sysv/consts/_POSIX_SEMAPHORES.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_SEMAPHORES 0x031069 -1 0x030db0 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX_SEM_NSEMS_MAX.s b/libc/sysv/consts/_POSIX_SEM_NSEMS_MAX.s new file mode 100644 index 00000000..c057b192 --- /dev/null +++ b/libc/sysv/consts/_POSIX_SEM_NSEMS_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_SEM_NSEMS_MAX 0x0100 0x0100 0x0100 0x0100 0 diff --git a/libc/sysv/consts/_POSIX_SEM_VALUE_MAX.s b/libc/sysv/consts/_POSIX_SEM_VALUE_MAX.s new file mode 100644 index 00000000..1f6c3d99 --- /dev/null +++ b/libc/sysv/consts/_POSIX_SEM_VALUE_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_SEM_VALUE_MAX 0x7fff 0x7fff 0x7fff 0x7fff 0 diff --git a/libc/sysv/consts/_POSIX_SHARED_MEMORY_OBJECTS.s b/libc/sysv/consts/_POSIX_SHARED_MEMORY_OBJECTS.s new file mode 100644 index 00000000..03696846 --- /dev/null +++ b/libc/sysv/consts/_POSIX_SHARED_MEMORY_OBJECTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_SHARED_MEMORY_OBJECTS 0x031069 -1 0x030db0 0x031069 0 diff --git a/libc/sysv/consts/_POSIX_SHELL.s b/libc/sysv/consts/_POSIX_SHELL.s new file mode 100644 index 00000000..42939f85 --- /dev/null +++ b/libc/sysv/consts/_POSIX_SHELL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_SHELL 1 0x030db0 1 1 0 diff --git a/libc/sysv/consts/_POSIX_SIGQUEUE_MAX.s b/libc/sysv/consts/_POSIX_SIGQUEUE_MAX.s new file mode 100644 index 00000000..86511914 --- /dev/null +++ b/libc/sysv/consts/_POSIX_SIGQUEUE_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_SIGQUEUE_MAX 0x20 0x20 0x20 0 0 diff --git a/libc/sysv/consts/_POSIX_SPAWN.s b/libc/sysv/consts/_POSIX_SPAWN.s new file mode 100644 index 00000000..a7816462 --- /dev/null +++ b/libc/sysv/consts/_POSIX_SPAWN.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_SPAWN 0x031069 -1 0x030db0 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX_SPIN_LOCKS.s b/libc/sysv/consts/_POSIX_SPIN_LOCKS.s new file mode 100644 index 00000000..0c22d3ca --- /dev/null +++ b/libc/sysv/consts/_POSIX_SPIN_LOCKS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_SPIN_LOCKS 0x031069 -1 0x030db0 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX_SSIZE_MAX.s b/libc/sysv/consts/_POSIX_SSIZE_MAX.s new file mode 100644 index 00000000..37d55b74 --- /dev/null +++ b/libc/sysv/consts/_POSIX_SSIZE_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_SSIZE_MAX 0x7fff 0x7fff 0x7fff 0x7fff 0 diff --git a/libc/sysv/consts/_POSIX_SS_REPL_MAX.s b/libc/sysv/consts/_POSIX_SS_REPL_MAX.s new file mode 100644 index 00000000..52822883 --- /dev/null +++ b/libc/sysv/consts/_POSIX_SS_REPL_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_SS_REPL_MAX 0 4 4 0 0 diff --git a/libc/sysv/consts/_POSIX_STREAM_MAX.s b/libc/sysv/consts/_POSIX_STREAM_MAX.s new file mode 100644 index 00000000..3de97c6e --- /dev/null +++ b/libc/sysv/consts/_POSIX_STREAM_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_STREAM_MAX 8 8 8 8 0 diff --git a/libc/sysv/consts/_POSIX_SYMLINK_MAX.s b/libc/sysv/consts/_POSIX_SYMLINK_MAX.s new file mode 100644 index 00000000..93cce4a2 --- /dev/null +++ b/libc/sysv/consts/_POSIX_SYMLINK_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_SYMLINK_MAX 255 255 255 255 0 diff --git a/libc/sysv/consts/_POSIX_SYMLOOP_MAX.s b/libc/sysv/consts/_POSIX_SYMLOOP_MAX.s new file mode 100644 index 00000000..25c79517 --- /dev/null +++ b/libc/sysv/consts/_POSIX_SYMLOOP_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_SYMLOOP_MAX 8 8 8 8 0 diff --git a/libc/sysv/consts/_POSIX_THREADS.s b/libc/sysv/consts/_POSIX_THREADS.s new file mode 100644 index 00000000..e9a8ad0d --- /dev/null +++ b/libc/sysv/consts/_POSIX_THREADS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_THREADS 0x031069 0x030db0 0x030db0 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX_THREAD_ATTR_STACKADDR.s b/libc/sysv/consts/_POSIX_THREAD_ATTR_STACKADDR.s new file mode 100644 index 00000000..4670e65e --- /dev/null +++ b/libc/sysv/consts/_POSIX_THREAD_ATTR_STACKADDR.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_THREAD_ATTR_STACKADDR 0x031069 0x030db0 0x030db0 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX_THREAD_ATTR_STACKSIZE.s b/libc/sysv/consts/_POSIX_THREAD_ATTR_STACKSIZE.s new file mode 100644 index 00000000..5c0bafaf --- /dev/null +++ b/libc/sysv/consts/_POSIX_THREAD_ATTR_STACKSIZE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_THREAD_ATTR_STACKSIZE 0x031069 0x030db0 0x030db0 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX_THREAD_CPUTIME.s b/libc/sysv/consts/_POSIX_THREAD_CPUTIME.s new file mode 100644 index 00000000..975369aa --- /dev/null +++ b/libc/sysv/consts/_POSIX_THREAD_CPUTIME.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_THREAD_CPUTIME 0 -1 0x030db0 0x031069 0 diff --git a/libc/sysv/consts/_POSIX_THREAD_DESTRUCTOR_ITERATIONS.s b/libc/sysv/consts/_POSIX_THREAD_DESTRUCTOR_ITERATIONS.s new file mode 100644 index 00000000..e1afebfc --- /dev/null +++ b/libc/sysv/consts/_POSIX_THREAD_DESTRUCTOR_ITERATIONS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 4 4 4 0 diff --git a/libc/sysv/consts/_POSIX_THREAD_KEYS_MAX.s b/libc/sysv/consts/_POSIX_THREAD_KEYS_MAX.s new file mode 100644 index 00000000..93e6f99e --- /dev/null +++ b/libc/sysv/consts/_POSIX_THREAD_KEYS_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_THREAD_KEYS_MAX 0x80 0x80 0x80 0x80 0 diff --git a/libc/sysv/consts/_POSIX_THREAD_PRIORITY_SCHEDULING.s b/libc/sysv/consts/_POSIX_THREAD_PRIORITY_SCHEDULING.s new file mode 100644 index 00000000..be8d3f03 --- /dev/null +++ b/libc/sysv/consts/_POSIX_THREAD_PRIORITY_SCHEDULING.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_THREAD_PRIORITY_SCHEDULING 0x031069 -1 0x030db0 -1 0 diff --git a/libc/sysv/consts/_POSIX_THREAD_PROCESS_SHARED.s b/libc/sysv/consts/_POSIX_THREAD_PROCESS_SHARED.s new file mode 100644 index 00000000..58896f0b --- /dev/null +++ b/libc/sysv/consts/_POSIX_THREAD_PROCESS_SHARED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_THREAD_PROCESS_SHARED 0x031069 0x030db0 0x030db0 -1 0 diff --git a/libc/sysv/consts/_POSIX_THREAD_SAFE_FUNCTIONS.s b/libc/sysv/consts/_POSIX_THREAD_SAFE_FUNCTIONS.s new file mode 100644 index 00000000..43c528c9 --- /dev/null +++ b/libc/sysv/consts/_POSIX_THREAD_SAFE_FUNCTIONS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_THREAD_SAFE_FUNCTIONS 0x031069 0x030db0 -1 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX_THREAD_THREADS_MAX.s b/libc/sysv/consts/_POSIX_THREAD_THREADS_MAX.s new file mode 100644 index 00000000..b19e90cb --- /dev/null +++ b/libc/sysv/consts/_POSIX_THREAD_THREADS_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_THREAD_THREADS_MAX 0x40 0x40 0x40 4 0 diff --git a/libc/sysv/consts/_POSIX_TIMEOUTS.s b/libc/sysv/consts/_POSIX_TIMEOUTS.s new file mode 100644 index 00000000..f6161dd6 --- /dev/null +++ b/libc/sysv/consts/_POSIX_TIMEOUTS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_TIMEOUTS 0x031069 -1 0x030db0 0x030db0 0 diff --git a/libc/sysv/consts/_POSIX_TIMERS.s b/libc/sysv/consts/_POSIX_TIMERS.s new file mode 100644 index 00000000..2408b763 --- /dev/null +++ b/libc/sysv/consts/_POSIX_TIMERS.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_TIMERS 0x031069 -1 0x030db0 -1 0 diff --git a/libc/sysv/consts/_POSIX_TIMER_MAX.s b/libc/sysv/consts/_POSIX_TIMER_MAX.s new file mode 100644 index 00000000..7d74ac34 --- /dev/null +++ b/libc/sysv/consts/_POSIX_TIMER_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_TIMER_MAX 0x20 0x20 0x20 0 0 diff --git a/libc/sysv/consts/_POSIX_TRACE_EVENT_NAME_MAX.s b/libc/sysv/consts/_POSIX_TRACE_EVENT_NAME_MAX.s new file mode 100644 index 00000000..b32644c9 --- /dev/null +++ b/libc/sysv/consts/_POSIX_TRACE_EVENT_NAME_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_TRACE_EVENT_NAME_MAX 0 30 30 0 0 diff --git a/libc/sysv/consts/_POSIX_TRACE_NAME_MAX.s b/libc/sysv/consts/_POSIX_TRACE_NAME_MAX.s new file mode 100644 index 00000000..db988a09 --- /dev/null +++ b/libc/sysv/consts/_POSIX_TRACE_NAME_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_TRACE_NAME_MAX 0 8 8 0 0 diff --git a/libc/sysv/consts/_POSIX_TRACE_SYS_MAX.s b/libc/sysv/consts/_POSIX_TRACE_SYS_MAX.s new file mode 100644 index 00000000..d456fc8d --- /dev/null +++ b/libc/sysv/consts/_POSIX_TRACE_SYS_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_TRACE_SYS_MAX 0 8 8 0 0 diff --git a/libc/sysv/consts/_POSIX_TRACE_USER_EVENT_MAX.s b/libc/sysv/consts/_POSIX_TRACE_USER_EVENT_MAX.s new file mode 100644 index 00000000..babb65a1 --- /dev/null +++ b/libc/sysv/consts/_POSIX_TRACE_USER_EVENT_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_TRACE_USER_EVENT_MAX 0 0x20 0x20 0 0 diff --git a/libc/sysv/consts/_POSIX_TTY_NAME_MAX.s b/libc/sysv/consts/_POSIX_TTY_NAME_MAX.s new file mode 100644 index 00000000..bcedd20a --- /dev/null +++ b/libc/sysv/consts/_POSIX_TTY_NAME_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_TTY_NAME_MAX 9 9 9 9 0 diff --git a/libc/sysv/consts/_POSIX_TZNAME_MAX.s b/libc/sysv/consts/_POSIX_TZNAME_MAX.s new file mode 100644 index 00000000..afbe8b73 --- /dev/null +++ b/libc/sysv/consts/_POSIX_TZNAME_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_TZNAME_MAX 6 6 6 6 0 diff --git a/libc/sysv/consts/_POSIX_V6_LP64_OFF64.s b/libc/sysv/consts/_POSIX_V6_LP64_OFF64.s new file mode 100644 index 00000000..97ab1b02 --- /dev/null +++ b/libc/sysv/consts/_POSIX_V6_LP64_OFF64.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_V6_LP64_OFF64 1 1 0 0 0 diff --git a/libc/sysv/consts/_POSIX_V7_LP64_OFF64.s b/libc/sysv/consts/_POSIX_V7_LP64_OFF64.s new file mode 100644 index 00000000..7424cddc --- /dev/null +++ b/libc/sysv/consts/_POSIX_V7_LP64_OFF64.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_V7_LP64_OFF64 1 1 0 0 0 diff --git a/libc/sysv/consts/_POSIX_VDISABLE.s b/libc/sysv/consts/_POSIX_VDISABLE.s new file mode 100644 index 00000000..ec31f1d3 --- /dev/null +++ b/libc/sysv/consts/_POSIX_VDISABLE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_VDISABLE 0 255 255 255 0 diff --git a/libc/sysv/consts/_POSIX_VERSION.s b/libc/sysv/consts/_POSIX_VERSION.s new file mode 100644 index 00000000..f7e4e3d8 --- /dev/null +++ b/libc/sysv/consts/_POSIX_VERSION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon posix _POSIX_VERSION 0x031069 0x030db0 0x030db0 0x031069 0 diff --git a/libc/sysv/consts/_SEM_SEMUN_UNDEFINED.s b/libc/sysv/consts/_SEM_SEMUN_UNDEFINED.s new file mode 100644 index 00000000..569e402f --- /dev/null +++ b/libc/sysv/consts/_SEM_SEMUN_UNDEFINED.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _SEM_SEMUN_UNDEFINED 1 0 0 0 0 diff --git a/libc/sysv/consts/_XOPEN_ENH_I18N.s b/libc/sysv/consts/_XOPEN_ENH_I18N.s new file mode 100644 index 00000000..33a29454 --- /dev/null +++ b/libc/sysv/consts/_XOPEN_ENH_I18N.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _XOPEN_ENH_I18N 1 1 -1 -1 0 diff --git a/libc/sysv/consts/_XOPEN_IOV_MAX.s b/libc/sysv/consts/_XOPEN_IOV_MAX.s new file mode 100644 index 00000000..98a903d2 --- /dev/null +++ b/libc/sysv/consts/_XOPEN_IOV_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _XOPEN_IOV_MAX 0x10 0x10 0x10 0x10 0 diff --git a/libc/sysv/consts/_XOPEN_NAME_MAX.s b/libc/sysv/consts/_XOPEN_NAME_MAX.s new file mode 100644 index 00000000..dd8aa9d9 --- /dev/null +++ b/libc/sysv/consts/_XOPEN_NAME_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _XOPEN_NAME_MAX 63 63 63 63 63 diff --git a/libc/sysv/consts/_XOPEN_PATH_MAX.s b/libc/sysv/consts/_XOPEN_PATH_MAX.s new file mode 100644 index 00000000..d07af13a --- /dev/null +++ b/libc/sysv/consts/_XOPEN_PATH_MAX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _XOPEN_PATH_MAX 255 255 255 255 255 diff --git a/libc/sysv/consts/_XOPEN_SOURCE.s b/libc/sysv/consts/_XOPEN_SOURCE.s new file mode 100644 index 00000000..1e94f0c2 --- /dev/null +++ b/libc/sysv/consts/_XOPEN_SOURCE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _XOPEN_SOURCE 700 0 0 0 0 diff --git a/libc/sysv/consts/_XOPEN_UNIX.s b/libc/sysv/consts/_XOPEN_UNIX.s new file mode 100644 index 00000000..d72ca5d7 --- /dev/null +++ b/libc/sysv/consts/_XOPEN_UNIX.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _XOPEN_UNIX 1 1 -1 -1 0 diff --git a/libc/sysv/consts/_XOPEN_VERSION.s b/libc/sysv/consts/_XOPEN_VERSION.s new file mode 100644 index 00000000..a77f95fd --- /dev/null +++ b/libc/sysv/consts/_XOPEN_VERSION.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon misc _XOPEN_VERSION 700 600 0 0 0 diff --git a/libc/sysv/consts/__NR_access.s b/libc/sysv/consts/__NR_access.s new file mode 100644 index 00000000..afca0fcf --- /dev/null +++ b/libc/sysv/consts/__NR_access.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_access 0x0015 0x2000021 0x0021 0x0021 -1 diff --git a/libc/sysv/consts/__NR_arch_prctl.s b/libc/sysv/consts/__NR_arch_prctl.s new file mode 100644 index 00000000..edaf6663 --- /dev/null +++ b/libc/sysv/consts/__NR_arch_prctl.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_arch_prctl 0x009e 0x000ffff 0x00a5 0x00a5 -1 diff --git a/libc/sysv/consts/__NR_clock_gettime.s b/libc/sysv/consts/__NR_clock_gettime.s new file mode 100644 index 00000000..d03f8976 --- /dev/null +++ b/libc/sysv/consts/__NR_clock_gettime.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_clock_gettime 0x00e4 0x000ffff 0x00e8 0x0057 -1 diff --git a/libc/sysv/consts/__NR_close.s b/libc/sysv/consts/__NR_close.s new file mode 100644 index 00000000..795f2302 --- /dev/null +++ b/libc/sysv/consts/__NR_close.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_close 0x0003 0x2000006 0x0006 0x0006 -1 diff --git a/libc/sysv/consts/__NR_exit.s b/libc/sysv/consts/__NR_exit.s new file mode 100644 index 00000000..020dc751 --- /dev/null +++ b/libc/sysv/consts/__NR_exit.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_exit 0x00e7 0x2000001 0x0001 0x0001 -1 diff --git a/libc/sysv/consts/__NR_fadvise.s b/libc/sysv/consts/__NR_fadvise.s new file mode 100644 index 00000000..5ad3384b --- /dev/null +++ b/libc/sysv/consts/__NR_fadvise.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_fadvise 0x00dd 0x000ffff 0x0213 0xffff -1 diff --git a/libc/sysv/consts/__NR_fork.s b/libc/sysv/consts/__NR_fork.s new file mode 100644 index 00000000..5d03652e --- /dev/null +++ b/libc/sysv/consts/__NR_fork.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_fork 0x0039 0x2000002 0x0002 0x0002 -1 diff --git a/libc/sysv/consts/__NR_fstat.s b/libc/sysv/consts/__NR_fstat.s new file mode 100644 index 00000000..8aeb4bdb --- /dev/null +++ b/libc/sysv/consts/__NR_fstat.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_fstat 0x0005 0x2000153 0x0227 0x0035 -1 diff --git a/libc/sysv/consts/__NR_getegid.s b/libc/sysv/consts/__NR_getegid.s new file mode 100644 index 00000000..0f083f83 --- /dev/null +++ b/libc/sysv/consts/__NR_getegid.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_getegid 0x006c 0x200002b 0x002b 0x002b -1 diff --git a/libc/sysv/consts/__NR_geteuid.s b/libc/sysv/consts/__NR_geteuid.s new file mode 100644 index 00000000..2768ceda --- /dev/null +++ b/libc/sysv/consts/__NR_geteuid.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_geteuid 0x006b 0x2000019 0x0019 0x0019 -1 diff --git a/libc/sysv/consts/__NR_getgid.s b/libc/sysv/consts/__NR_getgid.s new file mode 100644 index 00000000..090b690e --- /dev/null +++ b/libc/sysv/consts/__NR_getgid.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_getgid 0x0068 0x200002f 0x002f 0x002f -1 diff --git a/libc/sysv/consts/__NR_getpid.s b/libc/sysv/consts/__NR_getpid.s new file mode 100644 index 00000000..d3918d8e --- /dev/null +++ b/libc/sysv/consts/__NR_getpid.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_getpid 0x0027 0x2000014 0x0014 0x0014 -1 diff --git a/libc/sysv/consts/__NR_gettid.s b/libc/sysv/consts/__NR_gettid.s new file mode 100644 index 00000000..ac05fda1 --- /dev/null +++ b/libc/sysv/consts/__NR_gettid.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_gettid 0x00ba 0x200011e 0xffff 0xffff -1 diff --git a/libc/sysv/consts/__NR_gettimeofday.s b/libc/sysv/consts/__NR_gettimeofday.s new file mode 100644 index 00000000..8e377f6b --- /dev/null +++ b/libc/sysv/consts/__NR_gettimeofday.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_gettimeofday 0x0060 0x2000074 0x0074 0x0043 -1 diff --git a/libc/sysv/consts/__NR_getuid.s b/libc/sysv/consts/__NR_getuid.s new file mode 100644 index 00000000..d430fb74 --- /dev/null +++ b/libc/sysv/consts/__NR_getuid.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_getuid 0x0066 0x2000018 0x0018 0x0018 -1 diff --git a/libc/sysv/consts/__NR_kill.s b/libc/sysv/consts/__NR_kill.s new file mode 100644 index 00000000..91fd86b2 --- /dev/null +++ b/libc/sysv/consts/__NR_kill.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_kill 0x003e 0x2000025 0x0025 0x007a -1 diff --git a/libc/sysv/consts/__NR_lstat.s b/libc/sysv/consts/__NR_lstat.s new file mode 100644 index 00000000..7241038d --- /dev/null +++ b/libc/sysv/consts/__NR_lstat.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_lstat 0x0006 0x2000154 0x0028 0x0028 -1 diff --git a/libc/sysv/consts/__NR_madvise.s b/libc/sysv/consts/__NR_madvise.s new file mode 100644 index 00000000..6d3c88c9 --- /dev/null +++ b/libc/sysv/consts/__NR_madvise.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_madvise 0x001c 0x200004b 0x004b 0x004b -1 diff --git a/libc/sysv/consts/__NR_mmap.s b/libc/sysv/consts/__NR_mmap.s new file mode 100644 index 00000000..c3693955 --- /dev/null +++ b/libc/sysv/consts/__NR_mmap.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_mmap 0x0009 0x20000c5 0x01dd 0x00c5 -1 diff --git a/libc/sysv/consts/__NR_mprotect.s b/libc/sysv/consts/__NR_mprotect.s new file mode 100644 index 00000000..98dbb7d8 --- /dev/null +++ b/libc/sysv/consts/__NR_mprotect.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_mprotect 0x000a 0x200004a 0x004a 0x004a -1 diff --git a/libc/sysv/consts/__NR_munmap.s b/libc/sysv/consts/__NR_munmap.s new file mode 100644 index 00000000..a1f044d7 --- /dev/null +++ b/libc/sysv/consts/__NR_munmap.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_munmap 0x000b 0x2000049 0x0049 0x0049 -1 diff --git a/libc/sysv/consts/__NR_open.s b/libc/sysv/consts/__NR_open.s new file mode 100644 index 00000000..472136e7 --- /dev/null +++ b/libc/sysv/consts/__NR_open.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_open 0x0002 0x2000005 0x0005 0x0005 -1 diff --git a/libc/sysv/consts/__NR_pread.s b/libc/sysv/consts/__NR_pread.s new file mode 100644 index 00000000..bb4b5e46 --- /dev/null +++ b/libc/sysv/consts/__NR_pread.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_pread 0x0011 0x2000099 0x01db 0x00ad -1 diff --git a/libc/sysv/consts/__NR_pwrite.s b/libc/sysv/consts/__NR_pwrite.s new file mode 100644 index 00000000..514e2aad --- /dev/null +++ b/libc/sysv/consts/__NR_pwrite.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_pwrite 0x0012 0x200009a 0x01dc 0x00ae -1 diff --git a/libc/sysv/consts/__NR_read.s b/libc/sysv/consts/__NR_read.s new file mode 100644 index 00000000..aeae1cd3 --- /dev/null +++ b/libc/sysv/consts/__NR_read.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_read 0x0000 0x2000003 0x0003 0x0003 -1 diff --git a/libc/sysv/consts/__NR_sched_yield.s b/libc/sysv/consts/__NR_sched_yield.s new file mode 100644 index 00000000..3075031a --- /dev/null +++ b/libc/sysv/consts/__NR_sched_yield.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_sched_yield 0x0018 0x100003c 0x014b 0x012a -1 diff --git a/libc/sysv/consts/__NR_sendfile.s b/libc/sysv/consts/__NR_sendfile.s new file mode 100644 index 00000000..fee67f0c --- /dev/null +++ b/libc/sysv/consts/__NR_sendfile.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_sendfile 0x0028 0x2000151 0x0189 0xffff -1 diff --git a/libc/sysv/consts/__NR_sigaction.s b/libc/sysv/consts/__NR_sigaction.s new file mode 100644 index 00000000..c7ab43ea --- /dev/null +++ b/libc/sysv/consts/__NR_sigaction.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_sigaction 0x000d 0x200002e 0x01a0 0x002e -1 diff --git a/libc/sysv/consts/__NR_sigprocmask.s b/libc/sysv/consts/__NR_sigprocmask.s new file mode 100644 index 00000000..57d8246c --- /dev/null +++ b/libc/sysv/consts/__NR_sigprocmask.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_sigprocmask 0x000e 0x2000030 0x0154 0x0030 -1 diff --git a/libc/sysv/consts/__NR_stat.s b/libc/sysv/consts/__NR_stat.s new file mode 100644 index 00000000..3830dd2b --- /dev/null +++ b/libc/sysv/consts/__NR_stat.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_stat 0x0004 0x2000152 0x00bc 0x0026 -1 diff --git a/libc/sysv/consts/__NR_wait4.s b/libc/sysv/consts/__NR_wait4.s new file mode 100644 index 00000000..3d233242 --- /dev/null +++ b/libc/sysv/consts/__NR_wait4.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_wait4 0x003d 0x1000007 0x0007 0x000b -1 diff --git a/libc/sysv/consts/__NR_write.s b/libc/sysv/consts/__NR_write.s new file mode 100644 index 00000000..421b07e2 --- /dev/null +++ b/libc/sysv/consts/__NR_write.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_write 0x0001 0x2000004 0x0004 0x0004 -1 diff --git a/libc/sysv/consts/_posix.h b/libc/sysv/consts/_posix.h new file mode 100644 index 00000000..54752d69 --- /dev/null +++ b/libc/sysv/consts/_posix.h @@ -0,0 +1,168 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS__POSIX_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS__POSIX_H_ +#include "libc/runtime/symbolic.h" + +#define _POSIX_ADVISORY_INFO SYMBOLIC(_POSIX_ADVISORY_INFO) +#define _POSIX_AIO_LISTIO_MAX SYMBOLIC(_POSIX_AIO_LISTIO_MAX) +#define _POSIX_AIO_MAX SYMBOLIC(_POSIX_AIO_MAX) +#define _POSIX_ARG_MAX SYMBOLIC(_POSIX_ARG_MAX) +#define _POSIX_ASYNCHRONOUS_IO SYMBOLIC(_POSIX_ASYNCHRONOUS_IO) +#define _POSIX_BARRIERS SYMBOLIC(_POSIX_BARRIERS) +#define _POSIX_CHILD_MAX SYMBOLIC(_POSIX_CHILD_MAX) +#define _POSIX_CHOWN_RESTRICTED SYMBOLIC(_POSIX_CHOWN_RESTRICTED) +#define _POSIX_CLOCKRES_MIN SYMBOLIC(_POSIX_CLOCKRES_MIN) +#define _POSIX_CLOCK_SELECTION SYMBOLIC(_POSIX_CLOCK_SELECTION) +#define _POSIX_CPUTIME SYMBOLIC(_POSIX_CPUTIME) +#define _POSIX_DELAYTIMER_MAX SYMBOLIC(_POSIX_DELAYTIMER_MAX) +#define _POSIX_FSYNC SYMBOLIC(_POSIX_FSYNC) +#define _POSIX_HOST_NAME_MAX SYMBOLIC(_POSIX_HOST_NAME_MAX) +#define _POSIX_IPV6 SYMBOLIC(_POSIX_IPV6) +#define _POSIX_JOB_CONTROL SYMBOLIC(_POSIX_JOB_CONTROL) +#define _POSIX_LINK_MAX SYMBOLIC(_POSIX_LINK_MAX) +#define _POSIX_LOGIN_NAME_MAX SYMBOLIC(_POSIX_LOGIN_NAME_MAX) +#define _POSIX_MAPPED_FILES SYMBOLIC(_POSIX_MAPPED_FILES) +#define _POSIX_MAX_CANON SYMBOLIC(_POSIX_MAX_CANON) +#define _POSIX_MAX_INPUT SYMBOLIC(_POSIX_MAX_INPUT) +#define _POSIX_MEMLOCK SYMBOLIC(_POSIX_MEMLOCK) +#define _POSIX_MEMLOCK_RANGE SYMBOLIC(_POSIX_MEMLOCK_RANGE) +#define _POSIX_MEMORY_PROTECTION SYMBOLIC(_POSIX_MEMORY_PROTECTION) +#define _POSIX_MESSAGE_PASSING SYMBOLIC(_POSIX_MESSAGE_PASSING) +#define _POSIX_MONOTONIC_CLOCK SYMBOLIC(_POSIX_MONOTONIC_CLOCK) +#define _POSIX_MQ_OPEN_MAX SYMBOLIC(_POSIX_MQ_OPEN_MAX) +#define _POSIX_MQ_PRIO_MAX SYMBOLIC(_POSIX_MQ_PRIO_MAX) +#define _POSIX_NAME_MAX SYMBOLIC(_POSIX_NAME_MAX) +#define _POSIX_NGROUPS_MAX SYMBOLIC(_POSIX_NGROUPS_MAX) +#define _POSIX_NO_TRUNC SYMBOLIC(_POSIX_NO_TRUNC) +#define _POSIX_OPEN_MAX SYMBOLIC(_POSIX_OPEN_MAX) +#define _POSIX_PATH_MAX SYMBOLIC(_POSIX_PATH_MAX) +#define _POSIX_PIPE_BUF SYMBOLIC(_POSIX_PIPE_BUF) +#define _POSIX_RAW_SOCKETS SYMBOLIC(_POSIX_RAW_SOCKETS) +#define _POSIX_READER_WRITER_LOCKS SYMBOLIC(_POSIX_READER_WRITER_LOCKS) +#define _POSIX_REALTIME_SIGNALS SYMBOLIC(_POSIX_REALTIME_SIGNALS) +#define _POSIX_REGEXP SYMBOLIC(_POSIX_REGEXP) +#define _POSIX_RE_DUP_MAX SYMBOLIC(_POSIX_RE_DUP_MAX) +#define _POSIX_RTSIG_MAX SYMBOLIC(_POSIX_RTSIG_MAX) +#define _POSIX_SAVED_IDS SYMBOLIC(_POSIX_SAVED_IDS) +#define _POSIX_SEMAPHORES SYMBOLIC(_POSIX_SEMAPHORES) +#define _POSIX_SEM_NSEMS_MAX SYMBOLIC(_POSIX_SEM_NSEMS_MAX) +#define _POSIX_SEM_VALUE_MAX SYMBOLIC(_POSIX_SEM_VALUE_MAX) +#define _POSIX_SHARED_MEMORY_OBJECTS SYMBOLIC(_POSIX_SHARED_MEMORY_OBJECTS) +#define _POSIX_SHELL SYMBOLIC(_POSIX_SHELL) +#define _POSIX_SIGQUEUE_MAX SYMBOLIC(_POSIX_SIGQUEUE_MAX) +#define _POSIX_SPAWN SYMBOLIC(_POSIX_SPAWN) +#define _POSIX_SPIN_LOCKS SYMBOLIC(_POSIX_SPIN_LOCKS) +#define _POSIX_SSIZE_MAX SYMBOLIC(_POSIX_SSIZE_MAX) +#define _POSIX_SS_REPL_MAX SYMBOLIC(_POSIX_SS_REPL_MAX) +#define _POSIX_STREAM_MAX SYMBOLIC(_POSIX_STREAM_MAX) +#define _POSIX_SYMLINK_MAX SYMBOLIC(_POSIX_SYMLINK_MAX) +#define _POSIX_SYMLOOP_MAX SYMBOLIC(_POSIX_SYMLOOP_MAX) +#define _POSIX_THREADS SYMBOLIC(_POSIX_THREADS) +#define _POSIX_THREAD_ATTR_STACKADDR SYMBOLIC(_POSIX_THREAD_ATTR_STACKADDR) +#define _POSIX_THREAD_ATTR_STACKSIZE SYMBOLIC(_POSIX_THREAD_ATTR_STACKSIZE) +#define _POSIX_THREAD_CPUTIME SYMBOLIC(_POSIX_THREAD_CPUTIME) +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS \ + SYMBOLIC(_POSIX_THREAD_DESTRUCTOR_ITERATIONS) +#define _POSIX_THREAD_KEYS_MAX SYMBOLIC(_POSIX_THREAD_KEYS_MAX) +#define _POSIX_THREAD_PRIORITY_SCHEDULING \ + SYMBOLIC(_POSIX_THREAD_PRIORITY_SCHEDULING) +#define _POSIX_THREAD_PROCESS_SHARED SYMBOLIC(_POSIX_THREAD_PROCESS_SHARED) +#define _POSIX_THREAD_SAFE_FUNCTIONS SYMBOLIC(_POSIX_THREAD_SAFE_FUNCTIONS) +#define _POSIX_THREAD_THREADS_MAX SYMBOLIC(_POSIX_THREAD_THREADS_MAX) +#define _POSIX_TIMEOUTS SYMBOLIC(_POSIX_TIMEOUTS) +#define _POSIX_TIMERS SYMBOLIC(_POSIX_TIMERS) +#define _POSIX_TIMER_MAX SYMBOLIC(_POSIX_TIMER_MAX) +#define _POSIX_TRACE_EVENT_NAME_MAX SYMBOLIC(_POSIX_TRACE_EVENT_NAME_MAX) +#define _POSIX_TRACE_NAME_MAX SYMBOLIC(_POSIX_TRACE_NAME_MAX) +#define _POSIX_TRACE_SYS_MAX SYMBOLIC(_POSIX_TRACE_SYS_MAX) +#define _POSIX_TRACE_USER_EVENT_MAX SYMBOLIC(_POSIX_TRACE_USER_EVENT_MAX) +#define _POSIX_TTY_NAME_MAX SYMBOLIC(_POSIX_TTY_NAME_MAX) +#define _POSIX_TZNAME_MAX SYMBOLIC(_POSIX_TZNAME_MAX) +#define _POSIX_V6_LP64_OFF64 SYMBOLIC(_POSIX_V6_LP64_OFF64) +#define _POSIX_V7_LP64_OFF64 SYMBOLIC(_POSIX_V7_LP64_OFF64) +#define _POSIX_VDISABLE SYMBOLIC(_POSIX_VDISABLE) +#define _POSIX_VERSION SYMBOLIC(_POSIX_VERSION) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long _POSIX_ADVISORY_INFO; +hidden extern const long _POSIX_AIO_LISTIO_MAX; +hidden extern const long _POSIX_AIO_MAX; +hidden extern const long _POSIX_ARG_MAX; +hidden extern const long _POSIX_ASYNCHRONOUS_IO; +hidden extern const long _POSIX_BARRIERS; +hidden extern const long _POSIX_CHILD_MAX; +hidden extern const long _POSIX_CHOWN_RESTRICTED; +hidden extern const long _POSIX_CLOCKRES_MIN; +hidden extern const long _POSIX_CLOCK_SELECTION; +hidden extern const long _POSIX_CPUTIME; +hidden extern const long _POSIX_DELAYTIMER_MAX; +hidden extern const long _POSIX_FSYNC; +hidden extern const long _POSIX_HOST_NAME_MAX; +hidden extern const long _POSIX_IPV6; +hidden extern const long _POSIX_JOB_CONTROL; +hidden extern const long _POSIX_LINK_MAX; +hidden extern const long _POSIX_LOGIN_NAME_MAX; +hidden extern const long _POSIX_MAPPED_FILES; +hidden extern const long _POSIX_MAX_CANON; +hidden extern const long _POSIX_MAX_INPUT; +hidden extern const long _POSIX_MEMLOCK; +hidden extern const long _POSIX_MEMLOCK_RANGE; +hidden extern const long _POSIX_MEMORY_PROTECTION; +hidden extern const long _POSIX_MESSAGE_PASSING; +hidden extern const long _POSIX_MONOTONIC_CLOCK; +hidden extern const long _POSIX_MQ_OPEN_MAX; +hidden extern const long _POSIX_MQ_PRIO_MAX; +hidden extern const long _POSIX_NAME_MAX; +hidden extern const long _POSIX_NGROUPS_MAX; +hidden extern const long _POSIX_NO_TRUNC; +hidden extern const long _POSIX_OPEN_MAX; +hidden extern const long _POSIX_PATH_MAX; +hidden extern const long _POSIX_PIPE_BUF; +hidden extern const long _POSIX_RAW_SOCKETS; +hidden extern const long _POSIX_READER_WRITER_LOCKS; +hidden extern const long _POSIX_REALTIME_SIGNALS; +hidden extern const long _POSIX_REGEXP; +hidden extern const long _POSIX_RE_DUP_MAX; +hidden extern const long _POSIX_RTSIG_MAX; +hidden extern const long _POSIX_SAVED_IDS; +hidden extern const long _POSIX_SEMAPHORES; +hidden extern const long _POSIX_SEM_NSEMS_MAX; +hidden extern const long _POSIX_SEM_VALUE_MAX; +hidden extern const long _POSIX_SHARED_MEMORY_OBJECTS; +hidden extern const long _POSIX_SHELL; +hidden extern const long _POSIX_SIGQUEUE_MAX; +hidden extern const long _POSIX_SPAWN; +hidden extern const long _POSIX_SPIN_LOCKS; +hidden extern const long _POSIX_SSIZE_MAX; +hidden extern const long _POSIX_SS_REPL_MAX; +hidden extern const long _POSIX_STREAM_MAX; +hidden extern const long _POSIX_SYMLINK_MAX; +hidden extern const long _POSIX_SYMLOOP_MAX; +hidden extern const long _POSIX_THREADS; +hidden extern const long _POSIX_THREAD_ATTR_STACKADDR; +hidden extern const long _POSIX_THREAD_ATTR_STACKSIZE; +hidden extern const long _POSIX_THREAD_CPUTIME; +hidden extern const long _POSIX_THREAD_DESTRUCTOR_ITERATIONS; +hidden extern const long _POSIX_THREAD_KEYS_MAX; +hidden extern const long _POSIX_THREAD_PRIORITY_SCHEDULING; +hidden extern const long _POSIX_THREAD_PROCESS_SHARED; +hidden extern const long _POSIX_THREAD_SAFE_FUNCTIONS; +hidden extern const long _POSIX_THREAD_THREADS_MAX; +hidden extern const long _POSIX_TIMEOUTS; +hidden extern const long _POSIX_TIMERS; +hidden extern const long _POSIX_TIMER_MAX; +hidden extern const long _POSIX_TRACE_EVENT_NAME_MAX; +hidden extern const long _POSIX_TRACE_NAME_MAX; +hidden extern const long _POSIX_TRACE_SYS_MAX; +hidden extern const long _POSIX_TRACE_USER_EVENT_MAX; +hidden extern const long _POSIX_TTY_NAME_MAX; +hidden extern const long _POSIX_TZNAME_MAX; +hidden extern const long _POSIX_V6_LP64_OFF64; +hidden extern const long _POSIX_V7_LP64_OFF64; +hidden extern const long _POSIX_VDISABLE; +hidden extern const long _POSIX_VERSION; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS__POSIX_H_ */ diff --git a/libc/sysv/consts/_posix2.h b/libc/sysv/consts/_posix2.h new file mode 100644 index 00000000..a0326a0d --- /dev/null +++ b/libc/sysv/consts/_posix2.h @@ -0,0 +1,34 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS__POSIX2_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS__POSIX2_H_ +#include "libc/runtime/symbolic.h" + +#define _POSIX2_BC_BASE_MAX SYMBOLIC(_POSIX2_BC_BASE_MAX) +#define _POSIX2_BC_DIM_MAX SYMBOLIC(_POSIX2_BC_DIM_MAX) +#define _POSIX2_BC_SCALE_MAX SYMBOLIC(_POSIX2_BC_SCALE_MAX) +#define _POSIX2_BC_STRING_MAX SYMBOLIC(_POSIX2_BC_STRING_MAX) +#define _POSIX2_CHARCLASS_NAME_MAX SYMBOLIC(_POSIX2_CHARCLASS_NAME_MAX) +#define _POSIX2_COLL_WEIGHTS_MAX SYMBOLIC(_POSIX2_COLL_WEIGHTS_MAX) +#define _POSIX2_C_BIND SYMBOLIC(_POSIX2_C_BIND) +#define _POSIX2_EXPR_NEST_MAX SYMBOLIC(_POSIX2_EXPR_NEST_MAX) +#define _POSIX2_LINE_MAX SYMBOLIC(_POSIX2_LINE_MAX) +#define _POSIX2_RE_DUP_MAX SYMBOLIC(_POSIX2_RE_DUP_MAX) +#define _POSIX2_VERSION SYMBOLIC(_POSIX2_VERSION) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long _POSIX2_BC_BASE_MAX; +hidden extern const long _POSIX2_BC_DIM_MAX; +hidden extern const long _POSIX2_BC_SCALE_MAX; +hidden extern const long _POSIX2_BC_STRING_MAX; +hidden extern const long _POSIX2_CHARCLASS_NAME_MAX; +hidden extern const long _POSIX2_COLL_WEIGHTS_MAX; +hidden extern const long _POSIX2_C_BIND; +hidden extern const long _POSIX2_EXPR_NEST_MAX; +hidden extern const long _POSIX2_LINE_MAX; +hidden extern const long _POSIX2_RE_DUP_MAX; +hidden extern const long _POSIX2_VERSION; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS__POSIX2_H_ */ diff --git a/libc/sysv/consts/af.h b/libc/sysv/consts/af.h new file mode 100644 index 00000000..46b178f6 --- /dev/null +++ b/libc/sysv/consts/af.h @@ -0,0 +1,102 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_AF_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_AF_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long AF_ALG; +hidden extern const long AF_APPLETALK; +hidden extern const long AF_ASH; +hidden extern const long AF_ATMPVC; +hidden extern const long AF_ATMSVC; +hidden extern const long AF_AX25; +hidden extern const long AF_BLUETOOTH; +hidden extern const long AF_BRIDGE; +hidden extern const long AF_CAIF; +hidden extern const long AF_CAN; +hidden extern const long AF_ECONET; +hidden extern const long AF_FILE; +hidden extern const long AF_IB; +hidden extern const long AF_IEEE802154; +hidden extern const long AF_INET6; +hidden extern const long AF_INET; +hidden extern const long AF_IPX; +hidden extern const long AF_IRDA; +hidden extern const long AF_ISDN; +hidden extern const long AF_IUCV; +hidden extern const long AF_KCM; +hidden extern const long AF_KEY; +hidden extern const long AF_LLC; +hidden extern const long AF_LOCAL; +hidden extern const long AF_MAX; +hidden extern const long AF_MPLS; +hidden extern const long AF_NETBEUI; +hidden extern const long AF_NETLINK; +hidden extern const long AF_NETROM; +hidden extern const long AF_NFC; +hidden extern const long AF_PACKET; +hidden extern const long AF_PHONET; +hidden extern const long AF_PPPOX; +hidden extern const long AF_RDS; +hidden extern const long AF_ROSE; +hidden extern const long AF_ROUTE; +hidden extern const long AF_RXRPC; +hidden extern const long AF_SECURITY; +hidden extern const long AF_SNA; +hidden extern const long AF_TIPC; +hidden extern const long AF_UNIX; +hidden extern const long AF_UNSPEC; +hidden extern const long AF_VSOCK; +hidden extern const long AF_WANPIPE; +hidden extern const long AF_X25; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define AF_ALG SYMBOLIC(AF_ALG) +#define AF_APPLETALK SYMBOLIC(AF_APPLETALK) +#define AF_ASH SYMBOLIC(AF_ASH) +#define AF_ATMPVC SYMBOLIC(AF_ATMPVC) +#define AF_ATMSVC SYMBOLIC(AF_ATMSVC) +#define AF_AX25 SYMBOLIC(AF_AX25) +#define AF_BLUETOOTH SYMBOLIC(AF_BLUETOOTH) +#define AF_BRIDGE SYMBOLIC(AF_BRIDGE) +#define AF_CAIF SYMBOLIC(AF_CAIF) +#define AF_CAN SYMBOLIC(AF_CAN) +#define AF_ECONET SYMBOLIC(AF_ECONET) +#define AF_FILE SYMBOLIC(AF_FILE) +#define AF_IB SYMBOLIC(AF_IB) +#define AF_IEEE802154 SYMBOLIC(AF_IEEE802154) +#define AF_INET LITERALLY(2) +#define AF_INET6 SYMBOLIC(AF_INET6) +#define AF_IPX SYMBOLIC(AF_IPX) +#define AF_IRDA SYMBOLIC(AF_IRDA) +#define AF_ISDN SYMBOLIC(AF_ISDN) +#define AF_IUCV SYMBOLIC(AF_IUCV) +#define AF_KCM SYMBOLIC(AF_KCM) +#define AF_KEY SYMBOLIC(AF_KEY) +#define AF_LLC SYMBOLIC(AF_LLC) +#define AF_LOCAL SYMBOLIC(AF_LOCAL) +#define AF_MAX SYMBOLIC(AF_MAX) +#define AF_MPLS SYMBOLIC(AF_MPLS) +#define AF_NETBEUI SYMBOLIC(AF_NETBEUI) +#define AF_NETLINK SYMBOLIC(AF_NETLINK) +#define AF_NETROM SYMBOLIC(AF_NETROM) +#define AF_NFC SYMBOLIC(AF_NFC) +#define AF_PACKET SYMBOLIC(AF_PACKET) +#define AF_PHONET SYMBOLIC(AF_PHONET) +#define AF_PPPOX SYMBOLIC(AF_PPPOX) +#define AF_RDS SYMBOLIC(AF_RDS) +#define AF_ROSE SYMBOLIC(AF_ROSE) +#define AF_ROUTE SYMBOLIC(AF_ROUTE) +#define AF_RXRPC SYMBOLIC(AF_RXRPC) +#define AF_SECURITY SYMBOLIC(AF_SECURITY) +#define AF_SNA SYMBOLIC(AF_SNA) +#define AF_TIPC SYMBOLIC(AF_TIPC) +#define AF_UNIX LITERALLY(1) +#define AF_UNSPEC LITERALLY(0) +#define AF_VSOCK SYMBOLIC(AF_VSOCK) +#define AF_WANPIPE SYMBOLIC(AF_WANPIPE) +#define AF_X25 SYMBOLIC(AF_X25) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_AF_H_ */ diff --git a/libc/sysv/consts/ai.h b/libc/sysv/consts/ai.h new file mode 100644 index 00000000..f700aa84 --- /dev/null +++ b/libc/sysv/consts/ai.h @@ -0,0 +1,26 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_AI_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_AI_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long AI_ADDRCONFIG; +hidden extern const long AI_ALL; +hidden extern const long AI_CANONNAME; +hidden extern const long AI_NUMERICHOST; +hidden extern const long AI_NUMERICSERV; +hidden extern const long AI_PASSIVE; +hidden extern const long AI_V4MAPPED; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define AI_ADDRCONFIG SYMBOLIC(AI_ADDRCONFIG) +#define AI_ALL SYMBOLIC(AI_ALL) +#define AI_CANONNAME LITERALLY(2) +#define AI_NUMERICHOST LITERALLY(4) +#define AI_NUMERICSERV SYMBOLIC(AI_NUMERICSERV) +#define AI_PASSIVE LITERALLY(1) +#define AI_V4MAPPED SYMBOLIC(AI_V4MAPPED) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_AI_H_ */ diff --git a/libc/sysv/consts/arphrd.h b/libc/sysv/consts/arphrd.h new file mode 100644 index 00000000..a3819251 --- /dev/null +++ b/libc/sysv/consts/arphrd.h @@ -0,0 +1,28 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_ARPHRD_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_ARPHRD_H_ +#include "libc/runtime/symbolic.h" + +#define ARPHRD_ETHER SYMBOLIC(ARPHRD_ETHER) +#define ARPHRD_FCFABRIC SYMBOLIC(ARPHRD_FCFABRIC) +#define ARPHRD_IEEE80211 SYMBOLIC(ARPHRD_IEEE80211) +#define ARPHRD_IEEE80211_PRISM SYMBOLIC(ARPHRD_IEEE80211_PRISM) +#define ARPHRD_IEEE80211_RADIOTAP SYMBOLIC(ARPHRD_IEEE80211_RADIOTAP) +#define ARPHRD_IEEE802154 SYMBOLIC(ARPHRD_IEEE802154) +#define ARPHRD_IEEE802_TR SYMBOLIC(ARPHRD_IEEE802_TR) +#define ARPHRD_LOCALTLK SYMBOLIC(ARPHRD_LOCALTLK) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long ARPHRD_ETHER; +hidden extern const long ARPHRD_FCFABRIC; +hidden extern const long ARPHRD_IEEE80211; +hidden extern const long ARPHRD_IEEE80211_PRISM; +hidden extern const long ARPHRD_IEEE80211_RADIOTAP; +hidden extern const long ARPHRD_IEEE802154; +hidden extern const long ARPHRD_IEEE802_TR; +hidden extern const long ARPHRD_LOCALTLK; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_ARPHRD_H_ */ diff --git a/libc/sysv/consts/at.h b/libc/sysv/consts/at.h new file mode 100644 index 00000000..5503c6d7 --- /dev/null +++ b/libc/sysv/consts/at.h @@ -0,0 +1,27 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_AT_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_AT_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * @fileoverview AT_xxx constants for fcntl(), fopenat(), etc.. + * @see libc/sysv/consts/auxv.h for getauxval() constants + */ + +hidden extern const long AT_FDCWD; +hidden extern const long AT_SYMLINK_FOLLOW; +hidden extern const long AT_SYMLINK_NOFOLLOW; +hidden extern const long AT_REMOVEDIR; +hidden extern const long AT_EACCESS; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define AT_FDCWD SYMBOLIC(AT_FDCWD) +#define AT_SYMLINK_FOLLOW SYMBOLIC(AT_SYMLINK_FOLLOW) +#define AT_SYMLINK_NOFOLLOW SYMBOLIC(AT_SYMLINK_NOFOLLOW) +#define AT_REMOVEDIR SYMBOLIC(AT_REMOVEDIR) +#define AT_EACCESS SYMBOLIC(AT_EACCESS) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_AT_H_ */ diff --git a/libc/sysv/consts/auxv.h b/libc/sysv/consts/auxv.h new file mode 100644 index 00000000..7c2a9435 --- /dev/null +++ b/libc/sysv/consts/auxv.h @@ -0,0 +1,62 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_AUXV_H_ +#define COSMOPOLITAN_LIBC_CALLS_AUXV_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long AT_BASE; +hidden extern const long AT_BASE_PLATFORM; +hidden extern const long AT_CLKTCK; +hidden extern const long AT_DCACHEBSIZE; +hidden extern const long AT_EGID; +hidden extern const long AT_EMPTY_PATH; +hidden extern const long AT_ENTRY; +hidden extern const long AT_EUID; +hidden extern const long AT_EXECFD; +hidden extern const long AT_EXECFN; +hidden extern const long AT_GID; +hidden extern const long AT_ICACHEBSIZE; +hidden extern const long AT_NOTELF; +hidden extern const long AT_NO_AUTOMOUNT; +hidden extern const long AT_OSRELDATE; +hidden extern const long AT_PAGESZ; +hidden extern const long AT_PHDR; +hidden extern const long AT_PHENT; +hidden extern const long AT_PHNUM; +hidden extern const long AT_PLATFORM; +hidden extern const long AT_RANDOM; +hidden extern const long AT_SECURE; +hidden extern const long AT_SYSINFO_EHDR; +hidden extern const long AT_UCACHEBSIZE; +hidden extern const long AT_UID; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define AT_BASE SYMBOLIC(AT_BASE) +#define AT_BASE_PLATFORM SYMBOLIC(AT_BASE_PLATFORM) +#define AT_CLKTCK SYMBOLIC(AT_CLKTCK) +#define AT_DCACHEBSIZE SYMBOLIC(AT_DCACHEBSIZE) +#define AT_EGID SYMBOLIC(AT_EGID) +#define AT_EMPTY_PATH SYMBOLIC(AT_EMPTY_PATH) +#define AT_ENTRY SYMBOLIC(AT_ENTRY) +#define AT_EUID SYMBOLIC(AT_EUID) +#define AT_EXECFD SYMBOLIC(AT_EXECFD) +#define AT_EXECFN SYMBOLIC(AT_EXECFN) +#define AT_GID SYMBOLIC(AT_GID) +#define AT_ICACHEBSIZE SYMBOLIC(AT_ICACHEBSIZE) +#define AT_NOTELF SYMBOLIC(AT_NOTELF) +#define AT_NO_AUTOMOUNT SYMBOLIC(AT_NO_AUTOMOUNT) +#define AT_OSRELDATE SYMBOLIC(AT_OSRELDATE) +#define AT_PAGESZ SYMBOLIC(AT_PAGESZ) +#define AT_PHDR SYMBOLIC(AT_PHDR) +#define AT_PHENT SYMBOLIC(AT_PHENT) +#define AT_PHNUM SYMBOLIC(AT_PHNUM) +#define AT_PLATFORM SYMBOLIC(AT_PLATFORM) +#define AT_RANDOM SYMBOLIC(AT_RANDOM) +#define AT_SECURE SYMBOLIC(AT_SECURE) +#define AT_SYSINFO_EHDR SYMBOLIC(AT_SYSINFO_EHDR) +#define AT_UCACHEBSIZE SYMBOLIC(AT_UCACHEBSIZE) +#define AT_UID SYMBOLIC(AT_UID) + +#endif /* COSMOPOLITAN_LIBC_CALLS_AUXV_H_ */ diff --git a/libc/sysv/consts/blk.h b/libc/sysv/consts/blk.h new file mode 100644 index 00000000..70b22c61 --- /dev/null +++ b/libc/sysv/consts/blk.h @@ -0,0 +1,56 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_BLK_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_BLK_H_ +#include "libc/runtime/symbolic.h" + +#define BLK_BYTECOUNT SYMBOLIC(BLK_BYTECOUNT) +#define BLK_EOF SYMBOLIC(BLK_EOF) +#define BLK_EOR SYMBOLIC(BLK_EOR) +#define BLK_ERRORS SYMBOLIC(BLK_ERRORS) +#define BLK_RESTART SYMBOLIC(BLK_RESTART) + +#define BLKBSZGET SYMBOLIC(BLKBSZGET) +#define BLKBSZSET SYMBOLIC(BLKBSZSET) +#define BLKFLSBUF SYMBOLIC(BLKFLSBUF) +#define BLKFRAGET SYMBOLIC(BLKFRAGET) +#define BLKFRASET SYMBOLIC(BLKFRASET) +#define BLKGETSIZE SYMBOLIC(BLKGETSIZE) +#define BLKGETSIZE64 SYMBOLIC(BLKGETSIZE64) +#define BLKRAGET SYMBOLIC(BLKRAGET) +#define BLKRASET SYMBOLIC(BLKRASET) +#define BLKROGET SYMBOLIC(BLKROGET) +#define BLKROSET SYMBOLIC(BLKROSET) +#define BLKRRPART SYMBOLIC(BLKRRPART) +#define BLKSECTGET SYMBOLIC(BLKSECTGET) +#define BLKSECTSET SYMBOLIC(BLKSECTSET) +#define BLKSSZGET SYMBOLIC(BLKSSZGET) +#define BLKTYPE SYMBOLIC(BLKTYPE) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long BLK_BYTECOUNT; +hidden extern const long BLK_EOF; +hidden extern const long BLK_EOR; +hidden extern const long BLK_ERRORS; +hidden extern const long BLK_RESTART; + +hidden extern const long BLKBSZGET; +hidden extern const long BLKBSZSET; +hidden extern const long BLKFLSBUF; +hidden extern const long BLKFRAGET; +hidden extern const long BLKFRASET; +hidden extern const long BLKGETSIZE64; +hidden extern const long BLKGETSIZE; +hidden extern const long BLKRAGET; +hidden extern const long BLKRASET; +hidden extern const long BLKROGET; +hidden extern const long BLKROSET; +hidden extern const long BLKRRPART; +hidden extern const long BLKSECTGET; +hidden extern const long BLKSECTSET; +hidden extern const long BLKSSZGET; +hidden extern const long BLKTYPE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_BLK_H_ */ diff --git a/libc/sysv/consts/bus.h b/libc/sysv/consts/bus.h new file mode 100644 index 00000000..a9047208 --- /dev/null +++ b/libc/sysv/consts/bus.h @@ -0,0 +1,24 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_BUS_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_BUS_H_ +#include "libc/runtime/symbolic.h" + +#define BUS_ADRALN SYMBOLIC(BUS_ADRALN) +#define BUS_ADRERR SYMBOLIC(BUS_ADRERR) +#define BUS_DEVICE_RESET SYMBOLIC(BUS_DEVICE_RESET) +#define BUS_MCEERR_AO SYMBOLIC(BUS_MCEERR_AO) +#define BUS_MCEERR_AR SYMBOLIC(BUS_MCEERR_AR) +#define BUS_OBJERR SYMBOLIC(BUS_OBJERR) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long BUS_ADRALN; +hidden extern const long BUS_ADRERR; +hidden extern const long BUS_DEVICE_RESET; +hidden extern const long BUS_MCEERR_AO; +hidden extern const long BUS_MCEERR_AR; +hidden extern const long BUS_OBJERR; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_BUS_H_ */ diff --git a/libc/sysv/consts/c.h b/libc/sysv/consts/c.h new file mode 100644 index 00000000..39da7649 --- /dev/null +++ b/libc/sysv/consts/c.h @@ -0,0 +1,52 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_C_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_C_H_ +#include "libc/runtime/symbolic.h" + +#define C_IRGRP SYMBOLIC(C_IRGRP) +#define C_IROTH SYMBOLIC(C_IROTH) +#define C_IRUSR SYMBOLIC(C_IRUSR) +#define C_ISBLK SYMBOLIC(C_ISBLK) +#define C_ISCHR SYMBOLIC(C_ISCHR) +#define C_ISCTG SYMBOLIC(C_ISCTG) +#define C_ISDIR SYMBOLIC(C_ISDIR) +#define C_ISFIFO SYMBOLIC(C_ISFIFO) +#define C_ISGID SYMBOLIC(C_ISGID) +#define C_ISLNK SYMBOLIC(C_ISLNK) +#define C_ISREG SYMBOLIC(C_ISREG) +#define C_ISSOCK SYMBOLIC(C_ISSOCK) +#define C_ISUID SYMBOLIC(C_ISUID) +#define C_ISVTX SYMBOLIC(C_ISVTX) +#define C_IWGRP SYMBOLIC(C_IWGRP) +#define C_IWOTH SYMBOLIC(C_IWOTH) +#define C_IWUSR SYMBOLIC(C_IWUSR) +#define C_IXGRP SYMBOLIC(C_IXGRP) +#define C_IXOTH SYMBOLIC(C_IXOTH) +#define C_IXUSR SYMBOLIC(C_IXUSR) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long C_IRGRP; +hidden extern const long C_IROTH; +hidden extern const long C_IRUSR; +hidden extern const long C_ISBLK; +hidden extern const long C_ISCHR; +hidden extern const long C_ISCTG; +hidden extern const long C_ISDIR; +hidden extern const long C_ISFIFO; +hidden extern const long C_ISGID; +hidden extern const long C_ISLNK; +hidden extern const long C_ISREG; +hidden extern const long C_ISSOCK; +hidden extern const long C_ISUID; +hidden extern const long C_ISVTX; +hidden extern const long C_IWGRP; +hidden extern const long C_IWOTH; +hidden extern const long C_IWUSR; +hidden extern const long C_IXGRP; +hidden extern const long C_IXOTH; +hidden extern const long C_IXUSR; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_C_H_ */ diff --git a/libc/sysv/consts/cld.h b/libc/sysv/consts/cld.h new file mode 100644 index 00000000..5f7411e8 --- /dev/null +++ b/libc/sysv/consts/cld.h @@ -0,0 +1,24 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_CLD_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_CLD_H_ +#include "libc/runtime/symbolic.h" + +#define CLD_CONTINUED SYMBOLIC(CLD_CONTINUED) +#define CLD_DUMPED SYMBOLIC(CLD_DUMPED) +#define CLD_EXITED SYMBOLIC(CLD_EXITED) +#define CLD_KILLED SYMBOLIC(CLD_KILLED) +#define CLD_STOPPED SYMBOLIC(CLD_STOPPED) +#define CLD_TRAPPED SYMBOLIC(CLD_TRAPPED) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long CLD_CONTINUED; +hidden extern const long CLD_DUMPED; +hidden extern const long CLD_EXITED; +hidden extern const long CLD_KILLED; +hidden extern const long CLD_STOPPED; +hidden extern const long CLD_TRAPPED; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_CLD_H_ */ diff --git a/libc/sysv/consts/clock.h b/libc/sysv/consts/clock.h new file mode 100644 index 00000000..3f3f10f7 --- /dev/null +++ b/libc/sysv/consts/clock.h @@ -0,0 +1,34 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_CLOCK_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_CLOCK_H_ +#include "libc/runtime/symbolic.h" + +#define CLOCK_BOOTTIME SYMBOLIC(CLOCK_BOOTTIME) +#define CLOCK_BOOTTIME_ALARM SYMBOLIC(CLOCK_BOOTTIME_ALARM) +#define CLOCK_MONOTONIC SYMBOLIC(CLOCK_MONOTONIC) +#define CLOCK_MONOTONIC_COARSE SYMBOLIC(CLOCK_MONOTONIC_COARSE) +#define CLOCK_MONOTONIC_RAW SYMBOLIC(CLOCK_MONOTONIC_RAW) +#define CLOCK_PROCESS_CPUTIME_ID SYMBOLIC(CLOCK_PROCESS_CPUTIME_ID) +#define CLOCK_REALTIME SYMBOLIC(CLOCK_REALTIME) +#define CLOCK_REALTIME_ALARM SYMBOLIC(CLOCK_REALTIME_ALARM) +#define CLOCK_REALTIME_COARSE SYMBOLIC(CLOCK_REALTIME_COARSE) +#define CLOCK_TAI SYMBOLIC(CLOCK_TAI) +#define CLOCK_THREAD_CPUTIME_ID SYMBOLIC(CLOCK_THREAD_CPUTIME_ID) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long CLOCK_BOOTTIME; +hidden extern const long CLOCK_BOOTTIME_ALARM; +hidden extern const long CLOCK_MONOTONIC; +hidden extern const long CLOCK_MONOTONIC_COARSE; +hidden extern const long CLOCK_MONOTONIC_RAW; +hidden extern const long CLOCK_PROCESS_CPUTIME_ID; +hidden extern const long CLOCK_REALTIME; +hidden extern const long CLOCK_REALTIME_ALARM; +hidden extern const long CLOCK_REALTIME_COARSE; +hidden extern const long CLOCK_TAI; +hidden extern const long CLOCK_THREAD_CPUTIME_ID; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_CLOCK_H_ */ diff --git a/libc/sysv/consts/dt.h b/libc/sysv/consts/dt.h new file mode 100644 index 00000000..8eb049d5 --- /dev/null +++ b/libc/sysv/consts/dt.h @@ -0,0 +1,28 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_DT_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_DT_H_ +#include "libc/runtime/symbolic.h" + +#define DT_BLK SYMBOLIC(DT_BLK) +#define DT_CHR SYMBOLIC(DT_CHR) +#define DT_DIR SYMBOLIC(DT_DIR) +#define DT_FIFO SYMBOLIC(DT_FIFO) +#define DT_LNK SYMBOLIC(DT_LNK) +#define DT_REG SYMBOLIC(DT_REG) +#define DT_SOCK SYMBOLIC(DT_SOCK) +#define DT_UNKNOWN SYMBOLIC(DT_UNKNOWN) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long DT_BLK; +hidden extern const long DT_CHR; +hidden extern const long DT_DIR; +hidden extern const long DT_FIFO; +hidden extern const long DT_LNK; +hidden extern const long DT_REG; +hidden extern const long DT_SOCK; +hidden extern const long DT_UNKNOWN; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_DT_H_ */ diff --git a/libc/sysv/consts/eai.h b/libc/sysv/consts/eai.h new file mode 100644 index 00000000..c37313a2 --- /dev/null +++ b/libc/sysv/consts/eai.h @@ -0,0 +1,49 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_EAI_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_EAI_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long EAI_ADDRFAMILY; +hidden extern const long EAI_AGAIN; +hidden extern const long EAI_ALLDONE; +hidden extern const long EAI_BADFLAGS; +hidden extern const long EAI_CANCELED; +hidden extern const long EAI_FAIL; +hidden extern const long EAI_FAMILY; +hidden extern const long EAI_IDN_ENCODE; +hidden extern const long EAI_INPROGRESS; +hidden extern const long EAI_INTR; +hidden extern const long EAI_MEMORY; +hidden extern const long EAI_NODATA; +hidden extern const long EAI_NONAME; +hidden extern const long EAI_NOTCANCELED; +hidden extern const long EAI_OVERFLOW; +hidden extern const long EAI_SERVICE; +hidden extern const long EAI_SOCKTYPE; +hidden extern const long EAI_SYSTEM; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define EAI_ADDRFAMILY SYMBOLIC(EAI_ADDRFAMILY) +#define EAI_AGAIN SYMBOLIC(EAI_AGAIN) +#define EAI_ALLDONE SYMBOLIC(EAI_ALLDONE) +#define EAI_BADFLAGS SYMBOLIC(EAI_BADFLAGS) +#define EAI_CANCELED SYMBOLIC(EAI_CANCELED) +#define EAI_FAIL SYMBOLIC(EAI_FAIL) +#define EAI_FAMILY SYMBOLIC(EAI_FAMILY) +#define EAI_IDN_ENCODE SYMBOLIC(EAI_IDN_ENCODE) +#define EAI_INPROGRESS SYMBOLIC(EAI_INPROGRESS) +#define EAI_INTR SYMBOLIC(EAI_INTR) +#define EAI_MEMORY SYMBOLIC(EAI_MEMORY) +#define EAI_NODATA SYMBOLIC(EAI_NODATA) +#define EAI_NONAME SYMBOLIC(EAI_NONAME) +#define EAI_NOTCANCELED SYMBOLIC(EAI_NOTCANCELED) +#define EAI_OVERFLOW SYMBOLIC(EAI_OVERFLOW) +#define EAI_SERVICE SYMBOLIC(EAI_SERVICE) +#define EAI_SOCKTYPE SYMBOLIC(EAI_SOCKTYPE) +#define EAI_SUCCESS LITERALLY(0) +#define EAI_SYSTEM SYMBOLIC(EAI_SYSTEM) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_EAI_H_ */ diff --git a/libc/sysv/consts/eth.h b/libc/sysv/consts/eth.h new file mode 100644 index 00000000..19e8e753 --- /dev/null +++ b/libc/sysv/consts/eth.h @@ -0,0 +1,40 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_ETH_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_ETH_H_ +#include "libc/runtime/symbolic.h" + +#define ETH_P_CUST SYMBOLIC(ETH_P_CUST) +#define ETH_P_DDCMP SYMBOLIC(ETH_P_DDCMP) +#define ETH_P_DEC SYMBOLIC(ETH_P_DEC) +#define ETH_P_DIAG SYMBOLIC(ETH_P_DIAG) +#define ETH_P_DNA_DL SYMBOLIC(ETH_P_DNA_DL) +#define ETH_P_DNA_RC SYMBOLIC(ETH_P_DNA_RC) +#define ETH_P_DNA_RT SYMBOLIC(ETH_P_DNA_RT) +#define ETH_P_IEEE802154 SYMBOLIC(ETH_P_IEEE802154) +#define ETH_P_LAT SYMBOLIC(ETH_P_LAT) +#define ETH_P_LOCALTALK SYMBOLIC(ETH_P_LOCALTALK) +#define ETH_P_PPP_MP SYMBOLIC(ETH_P_PPP_MP) +#define ETH_P_RARP SYMBOLIC(ETH_P_RARP) +#define ETH_P_SCA SYMBOLIC(ETH_P_SCA) +#define ETH_P_WAN_PPP SYMBOLIC(ETH_P_WAN_PPP) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long ETH_P_CUST; +hidden extern const long ETH_P_DDCMP; +hidden extern const long ETH_P_DEC; +hidden extern const long ETH_P_DIAG; +hidden extern const long ETH_P_DNA_DL; +hidden extern const long ETH_P_DNA_RC; +hidden extern const long ETH_P_DNA_RT; +hidden extern const long ETH_P_IEEE802154; +hidden extern const long ETH_P_LAT; +hidden extern const long ETH_P_LOCALTALK; +hidden extern const long ETH_P_PPP_MP; +hidden extern const long ETH_P_RARP; +hidden extern const long ETH_P_SCA; +hidden extern const long ETH_P_WAN_PPP; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_ETH_H_ */ diff --git a/libc/sysv/consts/ex.h b/libc/sysv/consts/ex.h new file mode 100644 index 00000000..d6a3908e --- /dev/null +++ b/libc/sysv/consts/ex.h @@ -0,0 +1,48 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_EX_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_EX_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long EX_CANTCREAT; +hidden extern const long EX_CONFIG; +hidden extern const long EX_DATAERR; +hidden extern const long EX_IOERR; +hidden extern const long EX_NOHOST; +hidden extern const long EX_NOINPUT; +hidden extern const long EX_NOPERM; +hidden extern const long EX_NOUSER; +hidden extern const long EX_OK; +hidden extern const long EX_OSERR; +hidden extern const long EX_OSFILE; +hidden extern const long EX_PROTOCOL; +hidden extern const long EX_SOFTWARE; +hidden extern const long EX_TEMPFAIL; +hidden extern const long EX_UNAVAILABLE; +hidden extern const long EX_USAGE; +hidden extern const long EX__BASE; +hidden extern const long EX__MAX; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define EX_CANTCREAT LITERALLY(73) +#define EX_CONFIG LITERALLY(78) +#define EX_DATAERR LITERALLY(65) +#define EX_IOERR LITERALLY(74) +#define EX_NOHOST LITERALLY(68) +#define EX_NOINPUT LITERALLY(66) +#define EX_NOPERM LITERALLY(77) +#define EX_NOUSER LITERALLY(67) +#define EX_OK LITERALLY(0) +#define EX_OSERR LITERALLY(71) +#define EX_OSFILE LITERALLY(72) +#define EX_PROTOCOL LITERALLY(76) +#define EX_SOFTWARE LITERALLY(70) +#define EX_TEMPFAIL LITERALLY(75) +#define EX_UNAVAILABLE LITERALLY(69) +#define EX_USAGE LITERALLY(64) +#define EX__BASE LITERALLY(64) +#define EX__MAX LITERALLY(78) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_EX_H_ */ diff --git a/libc/sysv/consts/exit.h b/libc/sysv/consts/exit.h new file mode 100644 index 00000000..2ad4ad8b --- /dev/null +++ b/libc/sysv/consts/exit.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_EXIT_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_EXIT_H_ +#include "libc/runtime/symbolic.h" + +#define EXIT_FAILURE SYMBOLIC(EXIT_FAILURE) +#define EXIT_SUCCESS SYMBOLIC(EXIT_SUCCESS) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long EXIT_FAILURE; +hidden extern const long EXIT_SUCCESS; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_EXIT_H_ */ diff --git a/libc/sysv/consts/f.h b/libc/sysv/consts/f.h new file mode 100644 index 00000000..1f46aa18 --- /dev/null +++ b/libc/sysv/consts/f.h @@ -0,0 +1,79 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_F_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_F_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long F_DUPFD; +hidden extern const long F_DUPFD_CLOEXEC; +hidden extern const long F_GETFD; +hidden extern const long F_GETFL; +hidden extern const long F_GETLEASE; +hidden extern const long F_GETLK64; +hidden extern const long F_GETLK; +hidden extern const long F_GETOWN; +hidden extern const long F_GETOWN_EX; +hidden extern const long F_GETPIPE_SZ; +hidden extern const long F_GETSIG; +hidden extern const long F_LOCK; +hidden extern const long F_NOTIFY; +hidden extern const long F_OFD_GETLK; +hidden extern const long F_OFD_SETLK; +hidden extern const long F_OFD_SETLKW; +hidden extern const long F_RDLCK; +hidden extern const long F_SETFD; +hidden extern const long F_SETFL; +hidden extern const long F_SETLEASE; +hidden extern const long F_SETLK64; +hidden extern const long F_SETLK; +hidden extern const long F_SETLKW64; +hidden extern const long F_SETLKW; +hidden extern const long F_SETOWN; +hidden extern const long F_SETOWN_EX; +hidden extern const long F_SETPIPE_SZ; +hidden extern const long F_SETSIG; +hidden extern const long F_TEST; +hidden extern const long F_TLOCK; +hidden extern const long F_ULOCK; +hidden extern const long F_UNLCK; +hidden extern const long F_WRLCK; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define F_GETFD LITERALLY(1) +#define F_SETFD LITERALLY(2) +#define F_GETFL LITERALLY(3) +#define F_SETFL LITERALLY(4) + +#define F_DUPFD SYMBOLIC(F_DUPFD) +#define F_DUPFD_CLOEXEC SYMBOLIC(F_DUPFD_CLOEXEC) +#define F_GETLEASE SYMBOLIC(F_GETLEASE) +#define F_GETLK SYMBOLIC(F_GETLK) +#define F_GETLK64 SYMBOLIC(F_GETLK64) +#define F_GETOWN SYMBOLIC(F_GETOWN) +#define F_GETOWN_EX SYMBOLIC(F_GETOWN_EX) +#define F_GETPIPE_SZ SYMBOLIC(F_GETPIPE_SZ) +#define F_GETSIG SYMBOLIC(F_GETSIG) +#define F_LOCK SYMBOLIC(F_LOCK) +#define F_NOTIFY SYMBOLIC(F_NOTIFY) +#define F_OFD_GETLK SYMBOLIC(F_OFD_GETLK) +#define F_OFD_SETLK SYMBOLIC(F_OFD_SETLK) +#define F_OFD_SETLKW SYMBOLIC(F_OFD_SETLKW) +#define F_RDLCK SYMBOLIC(F_RDLCK) +#define F_SETLEASE SYMBOLIC(F_SETLEASE) +#define F_SETLK SYMBOLIC(F_SETLK) +#define F_SETLK64 SYMBOLIC(F_SETLK64) +#define F_SETLKW SYMBOLIC(F_SETLKW) +#define F_SETLKW64 SYMBOLIC(F_SETLKW64) +#define F_SETOWN SYMBOLIC(F_SETOWN) +#define F_SETOWN_EX SYMBOLIC(F_SETOWN_EX) +#define F_SETPIPE_SZ SYMBOLIC(F_SETPIPE_SZ) +#define F_SETSIG SYMBOLIC(F_SETSIG) +#define F_TEST SYMBOLIC(F_TEST) +#define F_TLOCK SYMBOLIC(F_TLOCK) +#define F_ULOCK SYMBOLIC(F_ULOCK) +#define F_UNLCK SYMBOLIC(F_UNLCK) +#define F_WRLCK SYMBOLIC(F_WRLCK) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_F_H_ */ diff --git a/libc/sysv/consts/falloc.h b/libc/sysv/consts/falloc.h new file mode 100644 index 00000000..4a33fd60 --- /dev/null +++ b/libc/sysv/consts/falloc.h @@ -0,0 +1,26 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_FALLOC_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_FALLOC_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long FALLOC_FL_KEEP_SIZE; +hidden extern const long FALLOC_FL_PUNCH_HOLE; +hidden extern const long FALLOC_FL_NO_HIDE_STALE; +hidden extern const long FALLOC_FL_COLLAPSE_RANGE; +hidden extern const long FALLOC_FL_ZERO_RANGE; +hidden extern const long FALLOC_FL_INSERT_RANGE; +hidden extern const long FALLOC_FL_UNSHARE_RANGE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define FALLOC_FL_KEEP_SIZE SYMBOLIC(FALLOC_FL_KEEP_SIZE) +#define FALLOC_FL_PUNCH_HOLE SYMBOLIC(FALLOC_FL_PUNCH_HOLE) +#define FALLOC_FL_NO_HIDE_STALE SYMBOLIC(FALLOC_FL_NO_HIDE_STALE) +#define FALLOC_FL_COLLAPSE_RANGE SYMBOLIC(FALLOC_FL_COLLAPSE_RANGE) +#define FALLOC_FL_ZERO_RANGE SYMBOLIC(FALLOC_FL_ZERO_RANGE) +#define FALLOC_FL_INSERT_RANGE SYMBOLIC(FALLOC_FL_INSERT_RANGE) +#define FALLOC_FL_UNSHARE_RANGE SYMBOLIC(FALLOC_FL_UNSHARE_RANGE) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_FALLOC_H_ */ diff --git a/libc/sysv/consts/fan.h b/libc/sysv/consts/fan.h new file mode 100644 index 00000000..591b4ff3 --- /dev/null +++ b/libc/sysv/consts/fan.h @@ -0,0 +1,84 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_FAN_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_FAN_H_ +#include "libc/runtime/symbolic.h" + +#define FAN_ACCESS SYMBOLIC(FAN_ACCESS) +#define FAN_ACCESS_PERM SYMBOLIC(FAN_ACCESS_PERM) +#define FAN_ALLOW SYMBOLIC(FAN_ALLOW) +#define FAN_ALL_CLASS_BITS SYMBOLIC(FAN_ALL_CLASS_BITS) +#define FAN_ALL_EVENTS SYMBOLIC(FAN_ALL_EVENTS) +#define FAN_ALL_INIT_FLAGS SYMBOLIC(FAN_ALL_INIT_FLAGS) +#define FAN_ALL_MARK_FLAGS SYMBOLIC(FAN_ALL_MARK_FLAGS) +#define FAN_ALL_OUTGOING_EVENTS SYMBOLIC(FAN_ALL_OUTGOING_EVENTS) +#define FAN_ALL_PERM_EVENTS SYMBOLIC(FAN_ALL_PERM_EVENTS) +#define FAN_CLASS_CONTENT SYMBOLIC(FAN_CLASS_CONTENT) +#define FAN_CLASS_NOTIF SYMBOLIC(FAN_CLASS_NOTIF) +#define FAN_CLASS_PRE_CONTENT SYMBOLIC(FAN_CLASS_PRE_CONTENT) +#define FAN_CLOEXEC SYMBOLIC(FAN_CLOEXEC) +#define FAN_CLOSE SYMBOLIC(FAN_CLOSE) +#define FAN_CLOSE_NOWRITE SYMBOLIC(FAN_CLOSE_NOWRITE) +#define FAN_CLOSE_WRITE SYMBOLIC(FAN_CLOSE_WRITE) +#define FAN_DENY SYMBOLIC(FAN_DENY) +#define FAN_EVENT_METADATA_LEN SYMBOLIC(FAN_EVENT_METADATA_LEN) +#define FAN_EVENT_ON_CHILD SYMBOLIC(FAN_EVENT_ON_CHILD) +#define FAN_MARK_ADD SYMBOLIC(FAN_MARK_ADD) +#define FAN_MARK_DONT_FOLLOW SYMBOLIC(FAN_MARK_DONT_FOLLOW) +#define FAN_MARK_FLUSH SYMBOLIC(FAN_MARK_FLUSH) +#define FAN_MARK_IGNORED_MASK SYMBOLIC(FAN_MARK_IGNORED_MASK) +#define FAN_MARK_IGNORED_SURV_MODIFY SYMBOLIC(FAN_MARK_IGNORED_SURV_MODIFY) +#define FAN_MARK_MOUNT SYMBOLIC(FAN_MARK_MOUNT) +#define FAN_MARK_ONLYDIR SYMBOLIC(FAN_MARK_ONLYDIR) +#define FAN_MARK_REMOVE SYMBOLIC(FAN_MARK_REMOVE) +#define FAN_MODIFY SYMBOLIC(FAN_MODIFY) +#define FAN_NOFD SYMBOLIC(FAN_NOFD) +#define FAN_NONBLOCK SYMBOLIC(FAN_NONBLOCK) +#define FAN_ONDIR SYMBOLIC(FAN_ONDIR) +#define FAN_OPEN SYMBOLIC(FAN_OPEN) +#define FAN_OPEN_PERM SYMBOLIC(FAN_OPEN_PERM) +#define FAN_Q_OVERFLOW SYMBOLIC(FAN_Q_OVERFLOW) +#define FAN_UNLIMITED_MARKS SYMBOLIC(FAN_UNLIMITED_MARKS) +#define FAN_UNLIMITED_QUEUE SYMBOLIC(FAN_UNLIMITED_QUEUE) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long FAN_ACCESS; +hidden extern const long FAN_ACCESS_PERM; +hidden extern const long FAN_ALLOW; +hidden extern const long FAN_ALL_CLASS_BITS; +hidden extern const long FAN_ALL_EVENTS; +hidden extern const long FAN_ALL_INIT_FLAGS; +hidden extern const long FAN_ALL_MARK_FLAGS; +hidden extern const long FAN_ALL_OUTGOING_EVENTS; +hidden extern const long FAN_ALL_PERM_EVENTS; +hidden extern const long FAN_CLASS_CONTENT; +hidden extern const long FAN_CLASS_NOTIF; +hidden extern const long FAN_CLASS_PRE_CONTENT; +hidden extern const long FAN_CLOEXEC; +hidden extern const long FAN_CLOSE; +hidden extern const long FAN_CLOSE_NOWRITE; +hidden extern const long FAN_CLOSE_WRITE; +hidden extern const long FAN_DENY; +hidden extern const long FAN_EVENT_METADATA_LEN; +hidden extern const long FAN_EVENT_ON_CHILD; +hidden extern const long FAN_MARK_ADD; +hidden extern const long FAN_MARK_DONT_FOLLOW; +hidden extern const long FAN_MARK_FLUSH; +hidden extern const long FAN_MARK_IGNORED_MASK; +hidden extern const long FAN_MARK_IGNORED_SURV_MODIFY; +hidden extern const long FAN_MARK_MOUNT; +hidden extern const long FAN_MARK_ONLYDIR; +hidden extern const long FAN_MARK_REMOVE; +hidden extern const long FAN_MODIFY; +hidden extern const long FAN_NOFD; +hidden extern const long FAN_NONBLOCK; +hidden extern const long FAN_ONDIR; +hidden extern const long FAN_OPEN; +hidden extern const long FAN_OPEN_PERM; +hidden extern const long FAN_Q_OVERFLOW; +hidden extern const long FAN_UNLIMITED_MARKS; +hidden extern const long FAN_UNLIMITED_QUEUE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_FAN_H_ */ diff --git a/libc/sysv/consts/fd.h b/libc/sysv/consts/fd.h new file mode 100644 index 00000000..efad3f88 --- /dev/null +++ b/libc/sysv/consts/fd.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_FD_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_FD_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long FD_CLOEXEC; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define FD_CLOEXEC LITERALLY(1) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_FD_H_ */ diff --git a/libc/sysv/consts/fe.h b/libc/sysv/consts/fe.h new file mode 100644 index 00000000..3419607c --- /dev/null +++ b/libc/sysv/consts/fe.h @@ -0,0 +1,32 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_FE_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_FE_H_ +#include "libc/runtime/symbolic.h" + +#define FE_ALL_EXCEPT SYMBOLIC(FE_ALL_EXCEPT) +#define FE_DIVBYZERO SYMBOLIC(FE_DIVBYZERO) +#define FE_DOWNWARD SYMBOLIC(FE_DOWNWARD) +#define FE_INEXACT SYMBOLIC(FE_INEXACT) +#define FE_INVALID SYMBOLIC(FE_INVALID) +#define FE_OVERFLOW SYMBOLIC(FE_OVERFLOW) +#define FE_TONEAREST SYMBOLIC(FE_TONEAREST) +#define FE_TOWARDZERO SYMBOLIC(FE_TOWARDZERO) +#define FE_UNDERFLOW SYMBOLIC(FE_UNDERFLOW) +#define FE_UPWARD SYMBOLIC(FE_UPWARD) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long FE_ALL_EXCEPT; +hidden extern const long FE_DIVBYZERO; +hidden extern const long FE_DOWNWARD; +hidden extern const long FE_INEXACT; +hidden extern const long FE_INVALID; +hidden extern const long FE_OVERFLOW; +hidden extern const long FE_TONEAREST; +hidden extern const long FE_TOWARDZERO; +hidden extern const long FE_UNDERFLOW; +hidden extern const long FE_UPWARD; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_FE_H_ */ diff --git a/libc/sysv/consts/fileno.h b/libc/sysv/consts/fileno.h new file mode 100644 index 00000000..54cc4ee2 --- /dev/null +++ b/libc/sysv/consts/fileno.h @@ -0,0 +1,9 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_FILENO_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_FILENO_H_ +#include "libc/runtime/symbolic.h" + +#define STDIN_FILENO LITERALLY(0) +#define STDOUT_FILENO LITERALLY(1) +#define STDERR_FILENO LITERALLY(2) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_FILENO_H_ */ diff --git a/libc/sysv/consts/fio.h b/libc/sysv/consts/fio.h new file mode 100644 index 00000000..5b6d79f3 --- /dev/null +++ b/libc/sysv/consts/fio.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_FIO_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_FIO_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long FIONBIO; +hidden extern const long FIONREAD; +hidden extern const long FIOASYNC; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define FIONBIO SYMBOLIC(FIONBIO) +#define FIONREAD SYMBOLIC(FIONREAD) +#define FIOASYNC SYMBOLIC(FIOASYNC) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_FIO_H_ */ diff --git a/libc/sysv/consts/ftw.h b/libc/sysv/consts/ftw.h new file mode 100644 index 00000000..89bd5092 --- /dev/null +++ b/libc/sysv/consts/ftw.h @@ -0,0 +1,34 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_FTW_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_FTW_H_ +#include "libc/runtime/symbolic.h" + +#define FTW_CHDIR SYMBOLIC(FTW_CHDIR) +#define FTW_D SYMBOLIC(FTW_D) +#define FTW_DEPTH SYMBOLIC(FTW_DEPTH) +#define FTW_DNR SYMBOLIC(FTW_DNR) +#define FTW_DP SYMBOLIC(FTW_DP) +#define FTW_F SYMBOLIC(FTW_F) +#define FTW_MOUNT SYMBOLIC(FTW_MOUNT) +#define FTW_NS SYMBOLIC(FTW_NS) +#define FTW_PHYS SYMBOLIC(FTW_PHYS) +#define FTW_SL SYMBOLIC(FTW_SL) +#define FTW_SLN SYMBOLIC(FTW_SLN) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long FTW_CHDIR; +hidden extern const long FTW_D; +hidden extern const long FTW_DEPTH; +hidden extern const long FTW_DNR; +hidden extern const long FTW_DP; +hidden extern const long FTW_F; +hidden extern const long FTW_MOUNT; +hidden extern const long FTW_NS; +hidden extern const long FTW_PHYS; +hidden extern const long FTW_SL; +hidden extern const long FTW_SLN; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_FTW_H_ */ diff --git a/libc/sysv/consts/futex.h b/libc/sysv/consts/futex.h new file mode 100644 index 00000000..da9448f6 --- /dev/null +++ b/libc/sysv/consts/futex.h @@ -0,0 +1,26 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_FUTEX_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_FUTEX_H_ +#include "libc/runtime/symbolic.h" + +#define FUTEX_PRIVATE_FLAG SYMBOLIC(FUTEX_PRIVATE_FLAG) +#define FUTEX_REQUEUE SYMBOLIC(FUTEX_REQUEUE) +#define FUTEX_REQUEUE_PRIVATE SYMBOLIC(FUTEX_REQUEUE_PRIVATE) +#define FUTEX_WAIT SYMBOLIC(FUTEX_WAIT) +#define FUTEX_WAIT_PRIVATE SYMBOLIC(FUTEX_WAIT_PRIVATE) +#define FUTEX_WAKE SYMBOLIC(FUTEX_WAKE) +#define FUTEX_WAKE_PRIVATE SYMBOLIC(FUTEX_WAKE_PRIVATE) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long FUTEX_PRIVATE_FLAG; +hidden extern const long FUTEX_REQUEUE; +hidden extern const long FUTEX_REQUEUE_PRIVATE; +hidden extern const long FUTEX_WAIT; +hidden extern const long FUTEX_WAIT_PRIVATE; +hidden extern const long FUTEX_WAKE; +hidden extern const long FUTEX_WAKE_PRIVATE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_FUTEX_H_ */ diff --git a/libc/sysv/consts/glob.h b/libc/sysv/consts/glob.h new file mode 100644 index 00000000..20052227 --- /dev/null +++ b/libc/sysv/consts/glob.h @@ -0,0 +1,34 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_GLOB_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_GLOB_H_ +#include "libc/runtime/symbolic.h" + +#define GLOB_ABORTED SYMBOLIC(GLOB_ABORTED) +#define GLOB_APPEND SYMBOLIC(GLOB_APPEND) +#define GLOB_DOOFFS SYMBOLIC(GLOB_DOOFFS) +#define GLOB_ERR SYMBOLIC(GLOB_ERR) +#define GLOB_MARK SYMBOLIC(GLOB_MARK) +#define GLOB_NOCHECK SYMBOLIC(GLOB_NOCHECK) +#define GLOB_NOESCAPE SYMBOLIC(GLOB_NOESCAPE) +#define GLOB_NOMATCH SYMBOLIC(GLOB_NOMATCH) +#define GLOB_NOSORT SYMBOLIC(GLOB_NOSORT) +#define GLOB_NOSPACE SYMBOLIC(GLOB_NOSPACE) +#define GLOB_NOSYS SYMBOLIC(GLOB_NOSYS) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long GLOB_ABORTED; +hidden extern const long GLOB_APPEND; +hidden extern const long GLOB_DOOFFS; +hidden extern const long GLOB_ERR; +hidden extern const long GLOB_MARK; +hidden extern const long GLOB_NOCHECK; +hidden extern const long GLOB_NOESCAPE; +hidden extern const long GLOB_NOMATCH; +hidden extern const long GLOB_NOSORT; +hidden extern const long GLOB_NOSPACE; +hidden extern const long GLOB_NOSYS; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_GLOB_H_ */ diff --git a/libc/sysv/consts/grnd.h b/libc/sysv/consts/grnd.h new file mode 100644 index 00000000..f9eba918 --- /dev/null +++ b/libc/sysv/consts/grnd.h @@ -0,0 +1,8 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_GRND_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_GRND_H_ +#include "libc/runtime/symbolic.h" + +#define GRND_NONBLOCK LITERALLY(1) +#define GRND_RANDOM LITERALLY(2) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_GRND_H_ */ diff --git a/libc/sysv/consts/icmp6.h b/libc/sysv/consts/icmp6.h new file mode 100644 index 00000000..3d88655b --- /dev/null +++ b/libc/sysv/consts/icmp6.h @@ -0,0 +1,75 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_ICMP6_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_ICMP6_H_ +#include "libc/runtime/symbolic.h" + +#define ICMP6_DST_UNREACH SYMBOLIC(ICMP6_DST_UNREACH) +#define ICMP6_DST_UNREACH_ADDR SYMBOLIC(ICMP6_DST_UNREACH_ADDR) +#define ICMP6_DST_UNREACH_ADMIN SYMBOLIC(ICMP6_DST_UNREACH_ADMIN) +#define ICMP6_DST_UNREACH_BEYONDSCOPE SYMBOLIC(ICMP6_DST_UNREACH_BEYONDSCOPE) +#define ICMP6_DST_UNREACH_NOPORT SYMBOLIC(ICMP6_DST_UNREACH_NOPORT) +#define ICMP6_DST_UNREACH_NOROUTE SYMBOLIC(ICMP6_DST_UNREACH_NOROUTE) +#define ICMP6_ECHO_REPLY SYMBOLIC(ICMP6_ECHO_REPLY) +#define ICMP6_ECHO_REQUEST SYMBOLIC(ICMP6_ECHO_REQUEST) +#define ICMP6_FILTER SYMBOLIC(ICMP6_FILTER) +#define ICMP6_INFOMSG_MASK SYMBOLIC(ICMP6_INFOMSG_MASK) +#define ICMP6_PACKET_TOO_BIG SYMBOLIC(ICMP6_PACKET_TOO_BIG) +#define ICMP6_PARAMPROB_HEADER SYMBOLIC(ICMP6_PARAMPROB_HEADER) +#define ICMP6_PARAMPROB_NEXTHEADER SYMBOLIC(ICMP6_PARAMPROB_NEXTHEADER) +#define ICMP6_PARAMPROB_OPTION SYMBOLIC(ICMP6_PARAMPROB_OPTION) +#define ICMP6_PARAM_PROB SYMBOLIC(ICMP6_PARAM_PROB) +#define ICMP6_ROUTER_RENUMBERING SYMBOLIC(ICMP6_ROUTER_RENUMBERING) +#define ICMP6_RR_FLAGS_FORCEAPPLY SYMBOLIC(ICMP6_RR_FLAGS_FORCEAPPLY) +#define ICMP6_RR_FLAGS_PREVDONE SYMBOLIC(ICMP6_RR_FLAGS_PREVDONE) +#define ICMP6_RR_FLAGS_REQRESULT SYMBOLIC(ICMP6_RR_FLAGS_REQRESULT) +#define ICMP6_RR_FLAGS_SPECSITE SYMBOLIC(ICMP6_RR_FLAGS_SPECSITE) +#define ICMP6_RR_FLAGS_TEST SYMBOLIC(ICMP6_RR_FLAGS_TEST) +#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME \ + SYMBOLIC(ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME) +#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME \ + SYMBOLIC(ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME) +#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO SYMBOLIC(ICMP6_RR_PCOUSE_RAFLAGS_AUTO) +#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK SYMBOLIC(ICMP6_RR_PCOUSE_RAFLAGS_ONLINK) +#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN \ + SYMBOLIC(ICMP6_RR_RESULT_FLAGS_FORBIDDEN) +#define ICMP6_RR_RESULT_FLAGS_OOB SYMBOLIC(ICMP6_RR_RESULT_FLAGS_OOB) +#define ICMP6_TIME_EXCEEDED SYMBOLIC(ICMP6_TIME_EXCEEDED) +#define ICMP6_TIME_EXCEED_REASSEMBLY SYMBOLIC(ICMP6_TIME_EXCEED_REASSEMBLY) +#define ICMP6_TIME_EXCEED_TRANSIT SYMBOLIC(ICMP6_TIME_EXCEED_TRANSIT) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long ICMP6_DST_UNREACH; +hidden extern const long ICMP6_DST_UNREACH_ADDR; +hidden extern const long ICMP6_DST_UNREACH_ADMIN; +hidden extern const long ICMP6_DST_UNREACH_BEYONDSCOPE; +hidden extern const long ICMP6_DST_UNREACH_NOPORT; +hidden extern const long ICMP6_DST_UNREACH_NOROUTE; +hidden extern const long ICMP6_ECHO_REPLY; +hidden extern const long ICMP6_ECHO_REQUEST; +hidden extern const long ICMP6_FILTER; +hidden extern const long ICMP6_INFOMSG_MASK; +hidden extern const long ICMP6_PACKET_TOO_BIG; +hidden extern const long ICMP6_PARAMPROB_HEADER; +hidden extern const long ICMP6_PARAMPROB_NEXTHEADER; +hidden extern const long ICMP6_PARAMPROB_OPTION; +hidden extern const long ICMP6_PARAM_PROB; +hidden extern const long ICMP6_ROUTER_RENUMBERING; +hidden extern const long ICMP6_RR_FLAGS_FORCEAPPLY; +hidden extern const long ICMP6_RR_FLAGS_PREVDONE; +hidden extern const long ICMP6_RR_FLAGS_REQRESULT; +hidden extern const long ICMP6_RR_FLAGS_SPECSITE; +hidden extern const long ICMP6_RR_FLAGS_TEST; +hidden extern const long ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME; +hidden extern const long ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME; +hidden extern const long ICMP6_RR_PCOUSE_RAFLAGS_AUTO; +hidden extern const long ICMP6_RR_PCOUSE_RAFLAGS_ONLINK; +hidden extern const long ICMP6_RR_RESULT_FLAGS_FORBIDDEN; +hidden extern const long ICMP6_RR_RESULT_FLAGS_OOB; +hidden extern const long ICMP6_TIME_EXCEEDED; +hidden extern const long ICMP6_TIME_EXCEED_REASSEMBLY; +hidden extern const long ICMP6_TIME_EXCEED_TRANSIT; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_ICMP6_H_ */ diff --git a/libc/sysv/consts/iff.h b/libc/sysv/consts/iff.h new file mode 100644 index 00000000..6b46fc6f --- /dev/null +++ b/libc/sysv/consts/iff.h @@ -0,0 +1,42 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_IFF_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_IFF_H_ +#include "libc/runtime/symbolic.h" + +#define IFF_ALLMULTI SYMBOLIC(IFF_ALLMULTI) +#define IFF_AUTOMEDIA SYMBOLIC(IFF_AUTOMEDIA) +#define IFF_BROADCAST SYMBOLIC(IFF_BROADCAST) +#define IFF_DEBUG SYMBOLIC(IFF_DEBUG) +#define IFF_DYNAMIC SYMBOLIC(IFF_DYNAMIC) +#define IFF_LOOPBACK SYMBOLIC(IFF_LOOPBACK) +#define IFF_MASTER SYMBOLIC(IFF_MASTER) +#define IFF_MULTICAST SYMBOLIC(IFF_MULTICAST) +#define IFF_NOARP SYMBOLIC(IFF_NOARP) +#define IFF_NOTRAILERS SYMBOLIC(IFF_NOTRAILERS) +#define IFF_POINTOPOINT SYMBOLIC(IFF_POINTOPOINT) +#define IFF_PORTSEL SYMBOLIC(IFF_PORTSEL) +#define IFF_PROMISC SYMBOLIC(IFF_PROMISC) +#define IFF_RUNNING SYMBOLIC(IFF_RUNNING) +#define IFF_SLAVE SYMBOLIC(IFF_SLAVE) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long IFF_ALLMULTI; +hidden extern const long IFF_AUTOMEDIA; +hidden extern const long IFF_BROADCAST; +hidden extern const long IFF_DEBUG; +hidden extern const long IFF_DYNAMIC; +hidden extern const long IFF_LOOPBACK; +hidden extern const long IFF_MASTER; +hidden extern const long IFF_MULTICAST; +hidden extern const long IFF_NOARP; +hidden extern const long IFF_NOTRAILERS; +hidden extern const long IFF_POINTOPOINT; +hidden extern const long IFF_PORTSEL; +hidden extern const long IFF_PROMISC; +hidden extern const long IFF_RUNNING; +hidden extern const long IFF_SLAVE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_IFF_H_ */ diff --git a/libc/sysv/consts/ill.h b/libc/sysv/consts/ill.h new file mode 100644 index 00000000..1543414b --- /dev/null +++ b/libc/sysv/consts/ill.h @@ -0,0 +1,28 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_ILL_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_ILL_H_ +#include "libc/runtime/symbolic.h" + +#define ILL_BADSTK SYMBOLIC(ILL_BADSTK) +#define ILL_COPROC SYMBOLIC(ILL_COPROC) +#define ILL_ILLADR SYMBOLIC(ILL_ILLADR) +#define ILL_ILLOPC SYMBOLIC(ILL_ILLOPC) +#define ILL_ILLOPN SYMBOLIC(ILL_ILLOPN) +#define ILL_ILLTRP SYMBOLIC(ILL_ILLTRP) +#define ILL_PRVOPC SYMBOLIC(ILL_PRVOPC) +#define ILL_PRVREG SYMBOLIC(ILL_PRVREG) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long ILL_BADSTK; +hidden extern const long ILL_COPROC; +hidden extern const long ILL_ILLADR; +hidden extern const long ILL_ILLOPC; +hidden extern const long ILL_ILLOPN; +hidden extern const long ILL_ILLTRP; +hidden extern const long ILL_PRVOPC; +hidden extern const long ILL_PRVREG; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_ILL_H_ */ diff --git a/libc/sysv/consts/in.h b/libc/sysv/consts/in.h new file mode 100644 index 00000000..52a5703a --- /dev/null +++ b/libc/sysv/consts/in.h @@ -0,0 +1,66 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_IN_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_IN_H_ +#include "libc/runtime/symbolic.h" + +#define IN_ACCESS SYMBOLIC(IN_ACCESS) +#define IN_ALL_EVENTS SYMBOLIC(IN_ALL_EVENTS) +#define IN_ATTRIB SYMBOLIC(IN_ATTRIB) +#define IN_CLOEXEC SYMBOLIC(IN_CLOEXEC) +#define IN_CLOSE SYMBOLIC(IN_CLOSE) +#define IN_CLOSE_NOWRITE SYMBOLIC(IN_CLOSE_NOWRITE) +#define IN_CLOSE_WRITE SYMBOLIC(IN_CLOSE_WRITE) +#define IN_CREATE SYMBOLIC(IN_CREATE) +#define IN_DELETE SYMBOLIC(IN_DELETE) +#define IN_DELETE_SELF SYMBOLIC(IN_DELETE_SELF) +#define IN_DONT_FOLLOW SYMBOLIC(IN_DONT_FOLLOW) +#define IN_EXCL_UNLINK SYMBOLIC(IN_EXCL_UNLINK) +#define IN_IGNORED SYMBOLIC(IN_IGNORED) +#define IN_ISDIR SYMBOLIC(IN_ISDIR) +#define IN_LOOPBACKNET SYMBOLIC(IN_LOOPBACKNET) +#define IN_MASK_ADD SYMBOLIC(IN_MASK_ADD) +#define IN_MODIFY SYMBOLIC(IN_MODIFY) +#define IN_MOVE SYMBOLIC(IN_MOVE) +#define IN_MOVED_FROM SYMBOLIC(IN_MOVED_FROM) +#define IN_MOVED_TO SYMBOLIC(IN_MOVED_TO) +#define IN_MOVE_SELF SYMBOLIC(IN_MOVE_SELF) +#define IN_NONBLOCK SYMBOLIC(IN_NONBLOCK) +#define IN_ONESHOT SYMBOLIC(IN_ONESHOT) +#define IN_ONLYDIR SYMBOLIC(IN_ONLYDIR) +#define IN_OPEN SYMBOLIC(IN_OPEN) +#define IN_Q_OVERFLOW SYMBOLIC(IN_Q_OVERFLOW) +#define IN_UNMOUNT SYMBOLIC(IN_UNMOUNT) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long IN_ACCESS; +hidden extern const long IN_ALL_EVENTS; +hidden extern const long IN_ATTRIB; +hidden extern const long IN_CLOEXEC; +hidden extern const long IN_CLOSE; +hidden extern const long IN_CLOSE_NOWRITE; +hidden extern const long IN_CLOSE_WRITE; +hidden extern const long IN_CREATE; +hidden extern const long IN_DELETE; +hidden extern const long IN_DELETE_SELF; +hidden extern const long IN_DONT_FOLLOW; +hidden extern const long IN_EXCL_UNLINK; +hidden extern const long IN_IGNORED; +hidden extern const long IN_ISDIR; +hidden extern const long IN_LOOPBACKNET; +hidden extern const long IN_MASK_ADD; +hidden extern const long IN_MODIFY; +hidden extern const long IN_MOVE; +hidden extern const long IN_MOVED_FROM; +hidden extern const long IN_MOVED_TO; +hidden extern const long IN_MOVE_SELF; +hidden extern const long IN_NONBLOCK; +hidden extern const long IN_ONESHOT; +hidden extern const long IN_ONLYDIR; +hidden extern const long IN_OPEN; +hidden extern const long IN_Q_OVERFLOW; +hidden extern const long IN_UNMOUNT; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_IN_H_ */ diff --git a/libc/sysv/consts/inaddr.h b/libc/sysv/consts/inaddr.h new file mode 100644 index 00000000..67a51636 --- /dev/null +++ b/libc/sysv/consts/inaddr.h @@ -0,0 +1,40 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_INADDR_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_INADDR_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * @fileoverview Well-known Internet addresses. + * These need to be hard-coded as little-endian, so htonl() is needed. + */ + +hidden extern const long INADDR_ALLHOSTS_GROUP; +hidden extern const long INADDR_ALLRTRS_GROUP; +hidden extern const long INADDR_ANY; +hidden extern const long INADDR_BROADCAST; +hidden extern const long INADDR_LOOPBACK; +hidden extern const long INADDR_MAX_LOCAL_GROUP; +hidden extern const long INADDR_NONE; +hidden extern const long INADDR_TESTNET1; +hidden extern const long INADDR_TESTNET2; +hidden extern const long INADDR_TESTNET3; +hidden extern const long INADDR_UNSPEC_GROUP; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define INADDR_ANY LITERALLY(0x00000000u) /* 0.0.0.0 */ +#define INADDR_BROADCAST LITERALLY(0xffffffffu) /* 255.255.255.255 */ +#define INADDR_NONE LITERALLY(0xffffffffu) /* 255.255.255.255 */ +#define INADDR_LOOPBACK LITERALLY(0x7f000001u) /* 127.0.0.1 */ +#define INADDR_TESTNET1 LITERALLY(0xc0000200u) /* 192.0.2.0/24 (RFC5737§3) */ +#define INADDR_TESTNET2 LITERALLY(0xc6336400u) /* 198.51.100.0/24 */ +#define INADDR_TESTNET3 LITERALLY(0xcb007100u) /* 203.0.113.0/24 */ + +#define INADDR_ALLHOSTS_GROUP SYMBOLIC(INADDR_ALLHOSTS_GROUP) +#define INADDR_ALLRTRS_GROUP SYMBOLIC(INADDR_ALLRTRS_GROUP) +#define INADDR_MAX_LOCAL_GROUP SYMBOLIC(INADDR_MAX_LOCAL_GROUP) +#define INADDR_UNSPEC_GROUP SYMBOLIC(INADDR_UNSPEC_GROUP) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_INADDR_H_ */ diff --git a/libc/sysv/consts/iov.h b/libc/sysv/consts/iov.h new file mode 100644 index 00000000..24ed282a --- /dev/null +++ b/libc/sysv/consts/iov.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_IOV_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_IOV_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long IOV_MAX; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define IOV_MAX SYMBOLIC(IOV_MAX) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_IOV_H_ */ diff --git a/libc/sysv/consts/ip.h b/libc/sysv/consts/ip.h new file mode 100644 index 00000000..cd820dee --- /dev/null +++ b/libc/sysv/consts/ip.h @@ -0,0 +1,108 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_IP_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_IP_H_ +#include "libc/runtime/symbolic.h" + +#define IP_ADD_MEMBERSHIP SYMBOLIC(IP_ADD_MEMBERSHIP) +#define IP_ADD_SOURCE_MEMBERSHIP SYMBOLIC(IP_ADD_SOURCE_MEMBERSHIP) +#define IP_BIND_ADDRESS_NO_PORT SYMBOLIC(IP_BIND_ADDRESS_NO_PORT) +#define IP_BLOCK_SOURCE SYMBOLIC(IP_BLOCK_SOURCE) +#define IP_CHECKSUM SYMBOLIC(IP_CHECKSUM) +#define IP_DEFAULT_MULTICAST_LOOP SYMBOLIC(IP_DEFAULT_MULTICAST_LOOP) +#define IP_DEFAULT_MULTICAST_TTL SYMBOLIC(IP_DEFAULT_MULTICAST_TTL) +#define IP_DROP_MEMBERSHIP SYMBOLIC(IP_DROP_MEMBERSHIP) +#define IP_DROP_SOURCE_MEMBERSHIP SYMBOLIC(IP_DROP_SOURCE_MEMBERSHIP) +#define IP_FREEBIND SYMBOLIC(IP_FREEBIND) +#define IP_HDRINCL SYMBOLIC(IP_HDRINCL) +#define IP_IPSEC_POLICY SYMBOLIC(IP_IPSEC_POLICY) +#define IP_MAX_MEMBERSHIPS SYMBOLIC(IP_MAX_MEMBERSHIPS) +#define IP_MINTTL SYMBOLIC(IP_MINTTL) +#define IP_MSFILTER SYMBOLIC(IP_MSFILTER) +#define IP_MTU SYMBOLIC(IP_MTU) +#define IP_MTU_DISCOVER SYMBOLIC(IP_MTU_DISCOVER) +#define IP_MULTICAST_ALL SYMBOLIC(IP_MULTICAST_ALL) +#define IP_MULTICAST_IF SYMBOLIC(IP_MULTICAST_IF) +#define IP_MULTICAST_LOOP SYMBOLIC(IP_MULTICAST_LOOP) +#define IP_MULTICAST_TTL SYMBOLIC(IP_MULTICAST_TTL) +#define IP_NODEFRAG SYMBOLIC(IP_NODEFRAG) +#define IP_OPTIONS SYMBOLIC(IP_OPTIONS) +#define IP_ORIGDSTADDR SYMBOLIC(IP_ORIGDSTADDR) +#define IP_PASSSEC SYMBOLIC(IP_PASSSEC) +#define IP_PKTINFO SYMBOLIC(IP_PKTINFO) +#define IP_PKTOPTIONS SYMBOLIC(IP_PKTOPTIONS) +#define IP_PMTUDISC SYMBOLIC(IP_PMTUDISC) +#define IP_PMTUDISC_DO SYMBOLIC(IP_PMTUDISC_DO) +#define IP_PMTUDISC_DONT SYMBOLIC(IP_PMTUDISC_DONT) +#define IP_PMTUDISC_INTERFACE SYMBOLIC(IP_PMTUDISC_INTERFACE) +#define IP_PMTUDISC_OMIT SYMBOLIC(IP_PMTUDISC_OMIT) +#define IP_PMTUDISC_PROBE SYMBOLIC(IP_PMTUDISC_PROBE) +#define IP_PMTUDISC_WANT SYMBOLIC(IP_PMTUDISC_WANT) +#define IP_RECVERR SYMBOLIC(IP_RECVERR) +#define IP_RECVOPTS SYMBOLIC(IP_RECVOPTS) +#define IP_RECVORIGDSTADDR SYMBOLIC(IP_RECVORIGDSTADDR) +#define IP_RECVRETOPTS SYMBOLIC(IP_RECVRETOPTS) +#define IP_RECVTOS SYMBOLIC(IP_RECVTOS) +#define IP_RECVTTL SYMBOLIC(IP_RECVTTL) +#define IP_RETOPTS SYMBOLIC(IP_RETOPTS) +#define IP_ROUTER_ALERT SYMBOLIC(IP_ROUTER_ALERT) +#define IP_TOS SYMBOLIC(IP_TOS) +#define IP_TRANSPARENT SYMBOLIC(IP_TRANSPARENT) +#define IP_TTL SYMBOLIC(IP_TTL) +#define IP_UNBLOCK_SOURCE SYMBOLIC(IP_UNBLOCK_SOURCE) +#define IP_UNICAST_IF SYMBOLIC(IP_UNICAST_IF) +#define IP_XFRM_POLICY SYMBOLIC(IP_XFRM_POLICY) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long IP_ADD_MEMBERSHIP; +hidden extern const long IP_ADD_SOURCE_MEMBERSHIP; +hidden extern const long IP_BIND_ADDRESS_NO_PORT; +hidden extern const long IP_BLOCK_SOURCE; +hidden extern const long IP_CHECKSUM; +hidden extern const long IP_DEFAULT_MULTICAST_LOOP; +hidden extern const long IP_DEFAULT_MULTICAST_TTL; +hidden extern const long IP_DROP_MEMBERSHIP; +hidden extern const long IP_DROP_SOURCE_MEMBERSHIP; +hidden extern const long IP_FREEBIND; +hidden extern const long IP_HDRINCL; +hidden extern const long IP_IPSEC_POLICY; +hidden extern const long IP_MAX_MEMBERSHIPS; +hidden extern const long IP_MINTTL; +hidden extern const long IP_MSFILTER; +hidden extern const long IP_MTU; +hidden extern const long IP_MTU_DISCOVER; +hidden extern const long IP_MULTICAST_ALL; +hidden extern const long IP_MULTICAST_IF; +hidden extern const long IP_MULTICAST_LOOP; +hidden extern const long IP_MULTICAST_TTL; +hidden extern const long IP_NODEFRAG; +hidden extern const long IP_OPTIONS; +hidden extern const long IP_ORIGDSTADDR; +hidden extern const long IP_PASSSEC; +hidden extern const long IP_PKTINFO; +hidden extern const long IP_PKTOPTIONS; +hidden extern const long IP_PMTUDISC; +hidden extern const long IP_PMTUDISC_DO; +hidden extern const long IP_PMTUDISC_DONT; +hidden extern const long IP_PMTUDISC_INTERFACE; +hidden extern const long IP_PMTUDISC_OMIT; +hidden extern const long IP_PMTUDISC_PROBE; +hidden extern const long IP_PMTUDISC_WANT; +hidden extern const long IP_RECVERR; +hidden extern const long IP_RECVOPTS; +hidden extern const long IP_RECVORIGDSTADDR; +hidden extern const long IP_RECVRETOPTS; +hidden extern const long IP_RECVTOS; +hidden extern const long IP_RECVTTL; +hidden extern const long IP_RETOPTS; +hidden extern const long IP_ROUTER_ALERT; +hidden extern const long IP_TOS; +hidden extern const long IP_TRANSPARENT; +hidden extern const long IP_TTL; +hidden extern const long IP_UNBLOCK_SOURCE; +hidden extern const long IP_UNICAST_IF; +hidden extern const long IP_XFRM_POLICY; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_IP_H_ */ diff --git a/libc/sysv/consts/ipc.h b/libc/sysv/consts/ipc.h new file mode 100644 index 00000000..83ec129a --- /dev/null +++ b/libc/sysv/consts/ipc.h @@ -0,0 +1,28 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_IPC_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_IPC_H_ +#include "libc/runtime/symbolic.h" + +#define IPC_CREAT SYMBOLIC(IPC_CREAT) +#define IPC_EXCL SYMBOLIC(IPC_EXCL) +#define IPC_INFO SYMBOLIC(IPC_INFO) +#define IPC_NOWAIT SYMBOLIC(IPC_NOWAIT) +#define IPC_PRIVATE SYMBOLIC(IPC_PRIVATE) +#define IPC_RMID SYMBOLIC(IPC_RMID) +#define IPC_SET SYMBOLIC(IPC_SET) +#define IPC_STAT SYMBOLIC(IPC_STAT) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long IPC_CREAT; +hidden extern const long IPC_EXCL; +hidden extern const long IPC_INFO; +hidden extern const long IPC_NOWAIT; +hidden extern const long IPC_PRIVATE; +hidden extern const long IPC_RMID; +hidden extern const long IPC_SET; +hidden extern const long IPC_STAT; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_IPC_H_ */ diff --git a/libc/sysv/consts/ipport.h b/libc/sysv/consts/ipport.h new file mode 100644 index 00000000..d8d00ae6 --- /dev/null +++ b/libc/sysv/consts/ipport.h @@ -0,0 +1,61 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_IPPORT_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_IPPORT_H_ + +/** + * ARPA network ports. + */ +#define IPPORT_ECHO 7 +#define IPPORT_DISCARD 9 +#define IPPORT_SYSTAT 11 +#define IPPORT_DAYTIME 13 +#define IPPORT_NETSTAT 15 +#define IPPORT_FTP 21 +#define IPPORT_TELNET 23 +#define IPPORT_SMTP 25 +#define IPPORT_TIMESERVER 37 +#define IPPORT_NAMESERVER 42 +#define IPPORT_WHOIS 43 +#define IPPORT_MTP 57 +#define IPPORT_TFTP 69 +#define IPPORT_RJE 77 +#define IPPORT_FINGER 79 +#define IPPORT_TTYLINK 87 +#define IPPORT_SUPDUP 95 +#define IPPORT_EXECSERVER 512 +#define IPPORT_LOGINSERVER 513 +#define IPPORT_CMDSERVER 514 +#define IPPORT_EFSSERVER 520 +#define IPPORT_BIFFUDP 512 +#define IPPORT_WHOSERVER 513 +#define IPPORT_ROUTESERVER 520 +#define IPPORT_RESERVED 1024 +#define IPPORT_USERRESERVED 5000 + +/** + * Modern network ports. + */ +#define IPPORT_SSH 22 +#define IPPORT_DOMAIN 53 +#define IPPORT_HTTP 80 +#define IPPORT_POP3 110 +#define IPPORT_SFTP 115 +#define IPPORT_NTP 123 +#define IPPORT_IMAP2 143 +#define IPPORT_NETBIOS_NS 137 +#define IPPORT_NETBIOS_DGM 138 +#define IPPORT_NETBIOS_SSN 139 +#define IPPORT_BGP 179 +#define IPPORT_IRC 194 +#define IPPORT_HTTPS 443 +#define IPPORT_PRINTER 515 +#define IPPORT_NFS 2049 +#define IPPORT_DISTCC 3632 +#define IPPORT_SIP 5060 +#define IPPORT_POSTGRESQL 5432 +#define IPPORT_X11 6000 +#define IPPORT_GIT 9418 +#define IPPORT_IRCD 6667 +#define IPPORT_IMAPS 993 +#define IPPORT_POP3S 995 + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_IPPORT_H_ */ diff --git a/libc/sysv/consts/ipproto.h b/libc/sysv/consts/ipproto.h new file mode 100644 index 00000000..08527221 --- /dev/null +++ b/libc/sysv/consts/ipproto.h @@ -0,0 +1,78 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_IPPROTO_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_IPPROTO_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long IPPROTO_AH; +hidden extern const long IPPROTO_BEETPH; +hidden extern const long IPPROTO_COMP; +hidden extern const long IPPROTO_DCCP; +hidden extern const long IPPROTO_DSTOPTS; +hidden extern const long IPPROTO_EGP; +hidden extern const long IPPROTO_ENCAP; +hidden extern const long IPPROTO_ESP; +hidden extern const long IPPROTO_FRAGMENT; +hidden extern const long IPPROTO_GRE; +hidden extern const long IPPROTO_HOPOPTS; +hidden extern const long IPPROTO_ICMP; +hidden extern const long IPPROTO_ICMPV6; +hidden extern const long IPPROTO_IDP; +hidden extern const long IPPROTO_IGMP; +hidden extern const long IPPROTO_IP; +hidden extern const long IPPROTO_IPIP; +hidden extern const long IPPROTO_IPV6; +hidden extern const long IPPROTO_MAX; +hidden extern const long IPPROTO_MH; +hidden extern const long IPPROTO_MPLS; +hidden extern const long IPPROTO_MTP; +hidden extern const long IPPROTO_NONE; +hidden extern const long IPPROTO_PIM; +hidden extern const long IPPROTO_PUP; +hidden extern const long IPPROTO_RAW; +hidden extern const long IPPROTO_ROUTING; +hidden extern const long IPPROTO_RSVP; +hidden extern const long IPPROTO_SCTP; +hidden extern const long IPPROTO_TCP; +hidden extern const long IPPROTO_TP; +hidden extern const long IPPROTO_UDP; +hidden extern const long IPPROTO_UDPLITE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define IPPROTO_AH SYMBOLIC(IPPROTO_AH) +#define IPPROTO_BEETPH SYMBOLIC(IPPROTO_BEETPH) +#define IPPROTO_COMP SYMBOLIC(IPPROTO_COMP) +#define IPPROTO_DCCP SYMBOLIC(IPPROTO_DCCP) +#define IPPROTO_DSTOPTS SYMBOLIC(IPPROTO_DSTOPTS) +#define IPPROTO_EGP SYMBOLIC(IPPROTO_EGP) +#define IPPROTO_ENCAP SYMBOLIC(IPPROTO_ENCAP) +#define IPPROTO_ESP SYMBOLIC(IPPROTO_ESP) +#define IPPROTO_FRAGMENT SYMBOLIC(IPPROTO_FRAGMENT) +#define IPPROTO_GRE SYMBOLIC(IPPROTO_GRE) +#define IPPROTO_HOPOPTS SYMBOLIC(IPPROTO_HOPOPTS) +#define IPPROTO_ICMP LITERALLY(1) +#define IPPROTO_ICMPV6 SYMBOLIC(IPPROTO_ICMPV6) +#define IPPROTO_IDP SYMBOLIC(IPPROTO_IDP) +#define IPPROTO_IGMP SYMBOLIC(IPPROTO_IGMP) +#define IPPROTO_IP LITERALLY(0) +#define IPPROTO_IPIP SYMBOLIC(IPPROTO_IPIP) +#define IPPROTO_IPV6 SYMBOLIC(IPPROTO_IPV6) +#define IPPROTO_MAX SYMBOLIC(IPPROTO_MAX) +#define IPPROTO_MH SYMBOLIC(IPPROTO_MH) +#define IPPROTO_MPLS SYMBOLIC(IPPROTO_MPLS) +#define IPPROTO_MTP SYMBOLIC(IPPROTO_MTP) +#define IPPROTO_NONE SYMBOLIC(IPPROTO_NONE) +#define IPPROTO_PIM SYMBOLIC(IPPROTO_PIM) +#define IPPROTO_PUP SYMBOLIC(IPPROTO_PUP) +#define IPPROTO_RAW LITERALLY(255) +#define IPPROTO_ROUTING SYMBOLIC(IPPROTO_ROUTING) +#define IPPROTO_RSVP SYMBOLIC(IPPROTO_RSVP) +#define IPPROTO_SCTP SYMBOLIC(IPPROTO_SCTP) +#define IPPROTO_TCP LITERALLY(6) +#define IPPROTO_TP SYMBOLIC(IPPROTO_TP) +#define IPPROTO_UDP LITERALLY(17) +#define IPPROTO_UDPLITE SYMBOLIC(IPPROTO_UDPLITE) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_IPPROTO_H_ */ diff --git a/libc/sysv/consts/ipv6.h b/libc/sysv/consts/ipv6.h new file mode 100644 index 00000000..e9ae2c78 --- /dev/null +++ b/libc/sysv/consts/ipv6.h @@ -0,0 +1,130 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_IPV6_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_IPV6_H_ +#include "libc/runtime/symbolic.h" + +#define IPV6_2292DSTOPTS SYMBOLIC(IPV6_2292DSTOPTS) +#define IPV6_2292HOPLIMIT SYMBOLIC(IPV6_2292HOPLIMIT) +#define IPV6_2292HOPOPTS SYMBOLIC(IPV6_2292HOPOPTS) +#define IPV6_2292PKTINFO SYMBOLIC(IPV6_2292PKTINFO) +#define IPV6_2292PKTOPTIONS SYMBOLIC(IPV6_2292PKTOPTIONS) +#define IPV6_2292RTHDR SYMBOLIC(IPV6_2292RTHDR) +#define IPV6_ADDRFORM SYMBOLIC(IPV6_ADDRFORM) +#define IPV6_ADD_MEMBERSHIP SYMBOLIC(IPV6_ADD_MEMBERSHIP) +#define IPV6_AUTHHDR SYMBOLIC(IPV6_AUTHHDR) +#define IPV6_AUTOFLOWLABEL SYMBOLIC(IPV6_AUTOFLOWLABEL) +#define IPV6_CHECKSUM SYMBOLIC(IPV6_CHECKSUM) +#define IPV6_DONTFRAG SYMBOLIC(IPV6_DONTFRAG) +#define IPV6_DROP_MEMBERSHIP SYMBOLIC(IPV6_DROP_MEMBERSHIP) +#define IPV6_DSTOPTS SYMBOLIC(IPV6_DSTOPTS) +#define IPV6_HDRINCL SYMBOLIC(IPV6_HDRINCL) +#define IPV6_HOPLIMIT SYMBOLIC(IPV6_HOPLIMIT) +#define IPV6_HOPOPTS SYMBOLIC(IPV6_HOPOPTS) +#define IPV6_IPSEC_POLICY SYMBOLIC(IPV6_IPSEC_POLICY) +#define IPV6_JOIN_ANYCAST SYMBOLIC(IPV6_JOIN_ANYCAST) +#define IPV6_JOIN_GROUP SYMBOLIC(IPV6_JOIN_GROUP) +#define IPV6_LEAVE_ANYCAST SYMBOLIC(IPV6_LEAVE_ANYCAST) +#define IPV6_LEAVE_GROUP SYMBOLIC(IPV6_LEAVE_GROUP) +#define IPV6_MINHOPCOUNT SYMBOLIC(IPV6_MINHOPCOUNT) +#define IPV6_MTU SYMBOLIC(IPV6_MTU) +#define IPV6_MTU_DISCOVER SYMBOLIC(IPV6_MTU_DISCOVER) +#define IPV6_MULTICAST_HOPS SYMBOLIC(IPV6_MULTICAST_HOPS) +#define IPV6_MULTICAST_IF SYMBOLIC(IPV6_MULTICAST_IF) +#define IPV6_MULTICAST_LOOP SYMBOLIC(IPV6_MULTICAST_LOOP) +#define IPV6_NEXTHOP SYMBOLIC(IPV6_NEXTHOP) +#define IPV6_ORIGDSTADDR SYMBOLIC(IPV6_ORIGDSTADDR) +#define IPV6_PATHMTU SYMBOLIC(IPV6_PATHMTU) +#define IPV6_PKTINFO SYMBOLIC(IPV6_PKTINFO) +#define IPV6_PMTUDISC_DO SYMBOLIC(IPV6_PMTUDISC_DO) +#define IPV6_PMTUDISC_DONT SYMBOLIC(IPV6_PMTUDISC_DONT) +#define IPV6_PMTUDISC_INTERFACE SYMBOLIC(IPV6_PMTUDISC_INTERFACE) +#define IPV6_PMTUDISC_OMIT SYMBOLIC(IPV6_PMTUDISC_OMIT) +#define IPV6_PMTUDISC_PROBE SYMBOLIC(IPV6_PMTUDISC_PROBE) +#define IPV6_PMTUDISC_WANT SYMBOLIC(IPV6_PMTUDISC_WANT) +#define IPV6_RECVDSTOPTS SYMBOLIC(IPV6_RECVDSTOPTS) +#define IPV6_RECVERR SYMBOLIC(IPV6_RECVERR) +#define IPV6_RECVHOPLIMIT SYMBOLIC(IPV6_RECVHOPLIMIT) +#define IPV6_RECVHOPOPTS SYMBOLIC(IPV6_RECVHOPOPTS) +#define IPV6_RECVORIGDSTADDR SYMBOLIC(IPV6_RECVORIGDSTADDR) +#define IPV6_RECVPATHMTU SYMBOLIC(IPV6_RECVPATHMTU) +#define IPV6_RECVPKTINFO SYMBOLIC(IPV6_RECVPKTINFO) +#define IPV6_RECVRTHDR SYMBOLIC(IPV6_RECVRTHDR) +#define IPV6_RECVTCLASS SYMBOLIC(IPV6_RECVTCLASS) +#define IPV6_ROUTER_ALERT SYMBOLIC(IPV6_ROUTER_ALERT) +#define IPV6_RTHDR SYMBOLIC(IPV6_RTHDR) +#define IPV6_RTHDRDSTOPTS SYMBOLIC(IPV6_RTHDRDSTOPTS) +#define IPV6_RTHDR_LOOSE SYMBOLIC(IPV6_RTHDR_LOOSE) +#define IPV6_RTHDR_STRICT SYMBOLIC(IPV6_RTHDR_STRICT) +#define IPV6_RTHDR_TYPE_0 SYMBOLIC(IPV6_RTHDR_TYPE_0) +#define IPV6_RXDSTOPTS SYMBOLIC(IPV6_RXDSTOPTS) +#define IPV6_RXHOPOPTS SYMBOLIC(IPV6_RXHOPOPTS) +#define IPV6_TCLASS SYMBOLIC(IPV6_TCLASS) +#define IPV6_UNICAST_HOPS SYMBOLIC(IPV6_UNICAST_HOPS) +#define IPV6_V6ONLY SYMBOLIC(IPV6_V6ONLY) +#define IPV6_XFRM_POLICY SYMBOLIC(IPV6_XFRM_POLICY) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long IPV6_2292DSTOPTS; +hidden extern const long IPV6_2292HOPLIMIT; +hidden extern const long IPV6_2292HOPOPTS; +hidden extern const long IPV6_2292PKTINFO; +hidden extern const long IPV6_2292PKTOPTIONS; +hidden extern const long IPV6_2292RTHDR; +hidden extern const long IPV6_ADDRFORM; +hidden extern const long IPV6_ADD_MEMBERSHIP; +hidden extern const long IPV6_AUTHHDR; +hidden extern const long IPV6_AUTOFLOWLABEL; +hidden extern const long IPV6_CHECKSUM; +hidden extern const long IPV6_DONTFRAG; +hidden extern const long IPV6_DROP_MEMBERSHIP; +hidden extern const long IPV6_DSTOPTS; +hidden extern const long IPV6_HDRINCL; +hidden extern const long IPV6_HOPLIMIT; +hidden extern const long IPV6_HOPOPTS; +hidden extern const long IPV6_IPSEC_POLICY; +hidden extern const long IPV6_JOIN_ANYCAST; +hidden extern const long IPV6_JOIN_GROUP; +hidden extern const long IPV6_LEAVE_ANYCAST; +hidden extern const long IPV6_LEAVE_GROUP; +hidden extern const long IPV6_MINHOPCOUNT; +hidden extern const long IPV6_MTU; +hidden extern const long IPV6_MTU_DISCOVER; +hidden extern const long IPV6_MULTICAST_HOPS; +hidden extern const long IPV6_MULTICAST_IF; +hidden extern const long IPV6_MULTICAST_LOOP; +hidden extern const long IPV6_NEXTHOP; +hidden extern const long IPV6_ORIGDSTADDR; +hidden extern const long IPV6_PATHMTU; +hidden extern const long IPV6_PKTINFO; +hidden extern const long IPV6_PMTUDISC_DO; +hidden extern const long IPV6_PMTUDISC_DONT; +hidden extern const long IPV6_PMTUDISC_INTERFACE; +hidden extern const long IPV6_PMTUDISC_OMIT; +hidden extern const long IPV6_PMTUDISC_PROBE; +hidden extern const long IPV6_PMTUDISC_WANT; +hidden extern const long IPV6_RECVDSTOPTS; +hidden extern const long IPV6_RECVERR; +hidden extern const long IPV6_RECVHOPLIMIT; +hidden extern const long IPV6_RECVHOPOPTS; +hidden extern const long IPV6_RECVORIGDSTADDR; +hidden extern const long IPV6_RECVPATHMTU; +hidden extern const long IPV6_RECVPKTINFO; +hidden extern const long IPV6_RECVRTHDR; +hidden extern const long IPV6_RECVTCLASS; +hidden extern const long IPV6_ROUTER_ALERT; +hidden extern const long IPV6_RTHDR; +hidden extern const long IPV6_RTHDRDSTOPTS; +hidden extern const long IPV6_RTHDR_LOOSE; +hidden extern const long IPV6_RTHDR_STRICT; +hidden extern const long IPV6_RTHDR_TYPE_0; +hidden extern const long IPV6_RXDSTOPTS; +hidden extern const long IPV6_RXHOPOPTS; +hidden extern const long IPV6_TCLASS; +hidden extern const long IPV6_UNICAST_HOPS; +hidden extern const long IPV6_V6ONLY; +hidden extern const long IPV6_XFRM_POLICY; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_IPV6_H_ */ diff --git a/libc/sysv/consts/itimer.h b/libc/sysv/consts/itimer.h new file mode 100644 index 00000000..c7847e66 --- /dev/null +++ b/libc/sysv/consts/itimer.h @@ -0,0 +1,9 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_ITIMER_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_ITIMER_H_ +#include "libc/runtime/symbolic.h" + +#define ITIMER_REAL 0 +#define ITIMER_VIRTUAL 1 +#define ITIMER_PROF 2 + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_ITIMER_H_ */ diff --git a/libc/sysv/consts/lc.h b/libc/sysv/consts/lc.h new file mode 100644 index 00000000..532f0897 --- /dev/null +++ b/libc/sysv/consts/lc.h @@ -0,0 +1,40 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_LC_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_LC_H_ +#include "libc/runtime/symbolic.h" + +#define LC_ALL SYMBOLIC(LC_ALL) +#define LC_ALL_MASK SYMBOLIC(LC_ALL_MASK) +#define LC_COLLATE SYMBOLIC(LC_COLLATE) +#define LC_COLLATE_MASK SYMBOLIC(LC_COLLATE_MASK) +#define LC_CTYPE SYMBOLIC(LC_CTYPE) +#define LC_CTYPE_MASK SYMBOLIC(LC_CTYPE_MASK) +#define LC_MESSAGES SYMBOLIC(LC_MESSAGES) +#define LC_MESSAGES_MASK SYMBOLIC(LC_MESSAGES_MASK) +#define LC_MONETARY SYMBOLIC(LC_MONETARY) +#define LC_MONETARY_MASK SYMBOLIC(LC_MONETARY_MASK) +#define LC_NUMERIC SYMBOLIC(LC_NUMERIC) +#define LC_NUMERIC_MASK SYMBOLIC(LC_NUMERIC_MASK) +#define LC_TIME SYMBOLIC(LC_TIME) +#define LC_TIME_MASK SYMBOLIC(LC_TIME_MASK) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long LC_ALL; +hidden extern const long LC_ALL_MASK; +hidden extern const long LC_COLLATE; +hidden extern const long LC_COLLATE_MASK; +hidden extern const long LC_CTYPE; +hidden extern const long LC_CTYPE_MASK; +hidden extern const long LC_MESSAGES; +hidden extern const long LC_MESSAGES_MASK; +hidden extern const long LC_MONETARY; +hidden extern const long LC_MONETARY_MASK; +hidden extern const long LC_NUMERIC; +hidden extern const long LC_NUMERIC_MASK; +hidden extern const long LC_TIME; +hidden extern const long LC_TIME_MASK; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_LC_H_ */ diff --git a/libc/sysv/consts/limits.h b/libc/sysv/consts/limits.h new file mode 100644 index 00000000..f2599ee4 --- /dev/null +++ b/libc/sysv/consts/limits.h @@ -0,0 +1,14 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_LIMITS_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_LIMITS_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long PIPE_BUF; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define PIPE_BUF SYMBOLIC(PIPE_BUF) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_LIMITS_H_ */ diff --git a/libc/sysv/consts/lio.h b/libc/sysv/consts/lio.h new file mode 100644 index 00000000..b3bf11dd --- /dev/null +++ b/libc/sysv/consts/lio.h @@ -0,0 +1,22 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_LIO_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_LIO_H_ +#include "libc/runtime/symbolic.h" + +#define LIO_NOP SYMBOLIC(LIO_NOP) +#define LIO_NOWAIT SYMBOLIC(LIO_NOWAIT) +#define LIO_READ SYMBOLIC(LIO_READ) +#define LIO_WAIT SYMBOLIC(LIO_WAIT) +#define LIO_WRITE SYMBOLIC(LIO_WRITE) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long LIO_NOP; +hidden extern const long LIO_NOWAIT; +hidden extern const long LIO_READ; +hidden extern const long LIO_WAIT; +hidden extern const long LIO_WRITE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_LIO_H_ */ diff --git a/libc/sysv/consts/lock.h b/libc/sysv/consts/lock.h new file mode 100644 index 00000000..d85c7399 --- /dev/null +++ b/libc/sysv/consts/lock.h @@ -0,0 +1,22 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_LOCK_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_LOCK_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long LOCK_EX; +hidden extern const long LOCK_NB; +hidden extern const long LOCK_SH; +hidden extern const long LOCK_UN; +hidden extern const long LOCK_UNLOCK_CACHE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define LOCK_EX LITERALLY(2) +#define LOCK_NB SYMBOLIC(LOCK_NB) +#define LOCK_SH SYMBOLIC(LOCK_SH) +#define LOCK_UN SYMBOLIC(LOCK_UN) +#define LOCK_UNLOCK_CACHE SYMBOLIC(LOCK_UNLOCK_CACHE) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_LOCK_H_ */ diff --git a/libc/sysv/consts/log.h b/libc/sysv/consts/log.h new file mode 100644 index 00000000..3f8ebe39 --- /dev/null +++ b/libc/sysv/consts/log.h @@ -0,0 +1,86 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_LOG_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_LOG_H_ +#include "libc/runtime/symbolic.h" + +#define LOG_ALERT SYMBOLIC(LOG_ALERT) +#define LOG_AUTH SYMBOLIC(LOG_AUTH) +#define LOG_CONS SYMBOLIC(LOG_CONS) +#define LOG_CRIT SYMBOLIC(LOG_CRIT) +#define LOG_CRON SYMBOLIC(LOG_CRON) +#define LOG_DAEMON SYMBOLIC(LOG_DAEMON) +#define LOG_DEBUG SYMBOLIC(LOG_DEBUG) +#define LOG_EMERG SYMBOLIC(LOG_EMERG) +#define LOG_ERR SYMBOLIC(LOG_ERR) +#define LOG_FACMASK SYMBOLIC(LOG_FACMASK) +#define LOG_INFO SYMBOLIC(LOG_INFO) +#define LOG_KERN SYMBOLIC(LOG_KERN) +#define LOG_LOCAL0 SYMBOLIC(LOG_LOCAL0) +#define LOG_LOCAL1 SYMBOLIC(LOG_LOCAL1) +#define LOG_LOCAL2 SYMBOLIC(LOG_LOCAL2) +#define LOG_LOCAL3 SYMBOLIC(LOG_LOCAL3) +#define LOG_LOCAL4 SYMBOLIC(LOG_LOCAL4) +#define LOG_LOCAL5 SYMBOLIC(LOG_LOCAL5) +#define LOG_LOCAL6 SYMBOLIC(LOG_LOCAL6) +#define LOG_LOCAL7 SYMBOLIC(LOG_LOCAL7) +#define LOG_LPR SYMBOLIC(LOG_LPR) +#define LOG_MAIL SYMBOLIC(LOG_MAIL) +#define LOG_NDELAY SYMBOLIC(LOG_NDELAY) +#define LOG_NEWS SYMBOLIC(LOG_NEWS) +#define LOG_NFACILITIES SYMBOLIC(LOG_NFACILITIES) +#define LOG_NOTICE SYMBOLIC(LOG_NOTICE) +#define LOG_NOWAIT SYMBOLIC(LOG_NOWAIT) +#define LOG_ODELAY SYMBOLIC(LOG_ODELAY) +#define LOG_PERROR SYMBOLIC(LOG_PERROR) +#define LOG_PID SYMBOLIC(LOG_PID) +#define LOG_PRIMASK SYMBOLIC(LOG_PRIMASK) +#define LOG_SELECT SYMBOLIC(LOG_SELECT) +#define LOG_SENSE SYMBOLIC(LOG_SENSE) +#define LOG_SYSLOG SYMBOLIC(LOG_SYSLOG) +#define LOG_USER SYMBOLIC(LOG_USER) +#define LOG_UUCP SYMBOLIC(LOG_UUCP) +#define LOG_WARNING SYMBOLIC(LOG_WARNING) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long LOG_ALERT; +hidden extern const long LOG_AUTH; +hidden extern const long LOG_CONS; +hidden extern const long LOG_CRIT; +hidden extern const long LOG_CRON; +hidden extern const long LOG_DAEMON; +hidden extern const long LOG_DEBUG; +hidden extern const long LOG_EMERG; +hidden extern const long LOG_ERR; +hidden extern const long LOG_FACMASK; +hidden extern const long LOG_INFO; +hidden extern const long LOG_KERN; +hidden extern const long LOG_LOCAL0; +hidden extern const long LOG_LOCAL1; +hidden extern const long LOG_LOCAL2; +hidden extern const long LOG_LOCAL3; +hidden extern const long LOG_LOCAL4; +hidden extern const long LOG_LOCAL5; +hidden extern const long LOG_LOCAL6; +hidden extern const long LOG_LOCAL7; +hidden extern const long LOG_LPR; +hidden extern const long LOG_MAIL; +hidden extern const long LOG_NDELAY; +hidden extern const long LOG_NEWS; +hidden extern const long LOG_NFACILITIES; +hidden extern const long LOG_NOTICE; +hidden extern const long LOG_NOWAIT; +hidden extern const long LOG_ODELAY; +hidden extern const long LOG_PERROR; +hidden extern const long LOG_PID; +hidden extern const long LOG_PRIMASK; +hidden extern const long LOG_SELECT; +hidden extern const long LOG_SENSE; +hidden extern const long LOG_SYSLOG; +hidden extern const long LOG_USER; +hidden extern const long LOG_UUCP; +hidden extern const long LOG_WARNING; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_LOG_H_ */ diff --git a/libc/sysv/consts/madv.h b/libc/sysv/consts/madv.h new file mode 100644 index 00000000..bc1ee463 --- /dev/null +++ b/libc/sysv/consts/madv.h @@ -0,0 +1,44 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_MADV_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_MADV_H_ +#include "libc/runtime/symbolic.h" + +#define MADV_DODUMP SYMBOLIC(MADV_DODUMP) +#define MADV_DOFORK SYMBOLIC(MADV_DOFORK) +#define MADV_DONTDUMP SYMBOLIC(MADV_DONTDUMP) +#define MADV_DONTFORK SYMBOLIC(MADV_DONTFORK) +#define MADV_DONTNEED SYMBOLIC(MADV_DONTNEED) +#define MADV_FREE SYMBOLIC(MADV_FREE) +#define MADV_HUGEPAGE SYMBOLIC(MADV_HUGEPAGE) +#define MADV_HWPOISON SYMBOLIC(MADV_HWPOISON) +#define MADV_MERGEABLE SYMBOLIC(MADV_MERGEABLE) +#define MADV_NOHUGEPAGE SYMBOLIC(MADV_NOHUGEPAGE) +#define MADV_NORMAL SYMBOLIC(MADV_NORMAL) +#define MADV_RANDOM SYMBOLIC(MADV_RANDOM) +#define MADV_REMOVE SYMBOLIC(MADV_REMOVE) +#define MADV_SEQUENTIAL SYMBOLIC(MADV_SEQUENTIAL) +#define MADV_UNMERGEABLE SYMBOLIC(MADV_UNMERGEABLE) +#define MADV_WILLNEED SYMBOLIC(MADV_WILLNEED) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long MADV_DODUMP; +hidden extern const long MADV_DOFORK; +hidden extern const long MADV_DONTDUMP; +hidden extern const long MADV_DONTFORK; +hidden extern const long MADV_DONTNEED; +hidden extern const long MADV_FREE; +hidden extern const long MADV_HUGEPAGE; +hidden extern const long MADV_HWPOISON; +hidden extern const long MADV_MERGEABLE; +hidden extern const long MADV_NOHUGEPAGE; +hidden extern const long MADV_NORMAL; +hidden extern const long MADV_RANDOM; +hidden extern const long MADV_REMOVE; +hidden extern const long MADV_SEQUENTIAL; +hidden extern const long MADV_UNMERGEABLE; +hidden extern const long MADV_WILLNEED; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_MADV_H_ */ diff --git a/libc/sysv/consts/map.h b/libc/sysv/consts/map.h new file mode 100644 index 00000000..0c07414d --- /dev/null +++ b/libc/sysv/consts/map.h @@ -0,0 +1,52 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_MAP_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_MAP_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long MAP_32BIT; +hidden extern const long MAP_ANON; +hidden extern const long MAP_ANONYMOUS; +hidden extern const long MAP_DENYWRITE; +hidden extern const long MAP_EXECUTABLE; +hidden extern const long MAP_FILE; +hidden extern const long MAP_FIXED; +hidden extern const long MAP_GROWSDOWN; +hidden extern const long MAP_HUGETLB; +hidden extern const long MAP_HUGE_MASK; +hidden extern const long MAP_HUGE_SHIFT; +hidden extern const long MAP_LOCKED; +hidden extern const long MAP_NONBLOCK; +hidden extern const long MAP_NORESERVE; +hidden extern const long MAP_POPULATE; +hidden extern const long MAP_PRIVATE; +hidden extern const long MAP_SHARED; +hidden extern const long MAP_STACK; +hidden extern const long MAP_TYPE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define MAP_FILE LITERALLY(0) +#define MAP_SHARED LITERALLY(1) +#define MAP_PRIVATE LITERALLY(2) +#define MAP_FIXED LITERALLY(16) + +#define MAP_32BIT SYMBOLIC(MAP_32BIT) +#define MAP_ANONYMOUS SYMBOLIC(MAP_ANONYMOUS) +#define MAP_DENYWRITE SYMBOLIC(MAP_DENYWRITE) +#define MAP_EXECUTABLE SYMBOLIC(MAP_EXECUTABLE) +#define MAP_GROWSDOWN SYMBOLIC(MAP_GROWSDOWN) +#define MAP_HUGETLB SYMBOLIC(MAP_HUGETLB) +#define MAP_HUGE_MASK SYMBOLIC(MAP_HUGE_MASK) +#define MAP_HUGE_SHIFT SYMBOLIC(MAP_HUGE_SHIFT) +#define MAP_LOCKED SYMBOLIC(MAP_LOCKED) +#define MAP_NONBLOCK SYMBOLIC(MAP_NONBLOCK) +#define MAP_NORESERVE SYMBOLIC(MAP_NORESERVE) +#define MAP_POPULATE SYMBOLIC(MAP_POPULATE) +#define MAP_TYPE SYMBOLIC(MAP_TYPE) + +#define MAP_ANON MAP_ANONYMOUS +#define MAP_STACK MAP_GROWSDOWN + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_MAP_H_ */ diff --git a/libc/sysv/consts/mcast.h b/libc/sysv/consts/mcast.h new file mode 100644 index 00000000..d3d76f35 --- /dev/null +++ b/libc/sysv/consts/mcast.h @@ -0,0 +1,30 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_MCAST_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_MCAST_H_ +#include "libc/runtime/symbolic.h" + +#define MCAST_BLOCK_SOURCE SYMBOLIC(MCAST_BLOCK_SOURCE) +#define MCAST_EXCLUDE SYMBOLIC(MCAST_EXCLUDE) +#define MCAST_INCLUDE SYMBOLIC(MCAST_INCLUDE) +#define MCAST_JOIN_GROUP SYMBOLIC(MCAST_JOIN_GROUP) +#define MCAST_JOIN_SOURCE_GROUP SYMBOLIC(MCAST_JOIN_SOURCE_GROUP) +#define MCAST_LEAVE_GROUP SYMBOLIC(MCAST_LEAVE_GROUP) +#define MCAST_LEAVE_SOURCE_GROUP SYMBOLIC(MCAST_LEAVE_SOURCE_GROUP) +#define MCAST_MSFILTER SYMBOLIC(MCAST_MSFILTER) +#define MCAST_UNBLOCK_SOURCE SYMBOLIC(MCAST_UNBLOCK_SOURCE) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long MCAST_BLOCK_SOURCE; +hidden extern const long MCAST_EXCLUDE; +hidden extern const long MCAST_INCLUDE; +hidden extern const long MCAST_JOIN_GROUP; +hidden extern const long MCAST_JOIN_SOURCE_GROUP; +hidden extern const long MCAST_LEAVE_GROUP; +hidden extern const long MCAST_LEAVE_SOURCE_GROUP; +hidden extern const long MCAST_MSFILTER; +hidden extern const long MCAST_UNBLOCK_SOURCE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_MCAST_H_ */ diff --git a/libc/sysv/consts/mfd.h b/libc/sysv/consts/mfd.h new file mode 100644 index 00000000..4a5d8132 --- /dev/null +++ b/libc/sysv/consts/mfd.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_MFD_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_MFD_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long MFD_CLOEXEC; +hidden extern const long MFD_ALLOW_SEALING; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define MFD_CLOEXEC SYMBOLIC(MFD_CLOEXEC) +#define MFD_ALLOW_SEALING SYMBOLIC(MFD_ALLOW_SEALING) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_MFD_H_ */ diff --git a/libc/sysv/consts/mlock.h b/libc/sysv/consts/mlock.h new file mode 100644 index 00000000..af980993 --- /dev/null +++ b/libc/sysv/consts/mlock.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_MLOCK_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_MLOCK_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long MCL_CURRENT; +hidden extern const long MCL_FUTURE; +hidden extern const long MCL_ONFAULT; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define MCL_CURRENT LITERALLY(1) +#define MCL_FUTURE LITERALLY(2) +#define MCL_ONFAULT SYMBOLIC(MCL_ONFAULT) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_MLOCK_H_ */ diff --git a/libc/sysv/consts/mnt.h b/libc/sysv/consts/mnt.h new file mode 100644 index 00000000..2a857036 --- /dev/null +++ b/libc/sysv/consts/mnt.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_MNT_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_MNT_H_ +#include "libc/runtime/symbolic.h" + +#define MNT_DETACH SYMBOLIC(MNT_DETACH) +#define MNT_EXPIRE SYMBOLIC(MNT_EXPIRE) +#define MNT_FORCE SYMBOLIC(MNT_FORCE) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long MNT_DETACH; +hidden extern const long MNT_EXPIRE; +hidden extern const long MNT_FORCE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_MNT_H_ */ diff --git a/libc/sysv/consts/modem.h b/libc/sysv/consts/modem.h new file mode 100644 index 00000000..1cc79dd2 --- /dev/null +++ b/libc/sysv/consts/modem.h @@ -0,0 +1,44 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_MODEM_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_MODEM_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long TIOCMGET; +hidden extern const long TIOCMSET; +hidden extern const long TIOCMBIC; +hidden extern const long TIOCMBIS; + +hidden extern const long TIOCM_CAR; +hidden extern const long TIOCM_CD; +hidden extern const long TIOCM_CTS; +hidden extern const long TIOCM_DSR; +hidden extern const long TIOCM_DTR; +hidden extern const long TIOCM_LE; +hidden extern const long TIOCM_RI; +hidden extern const long TIOCM_RNG; +hidden extern const long TIOCM_RTS; +hidden extern const long TIOCM_SR; +hidden extern const long TIOCM_ST; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define TIOCMGET SYMBOLIC(TIOCMGET) +#define TIOCMSET SYMBOLIC(TIOCMSET) +#define TIOCMBIC SYMBOLIC(TIOCMBIC) +#define TIOCMBIS SYMBOLIC(TIOCMBIS) + +#define TIOCM_LE LITERALLY(0b0000000000000001) +#define TIOCM_DTR LITERALLY(0b0000000000000010) +#define TIOCM_RTS LITERALLY(0b0000000000000100) +#define TIOCM_ST LITERALLY(0b0000000000001000) +#define TIOCM_SR LITERALLY(0b0000000000010000) +#define TIOCM_CTS LITERALLY(0b0000000000100000) +#define TIOCM_CAR LITERALLY(0b0000000001000000) +#define TIOCM_CD LITERALLY(0b0000000001000000) +#define TIOCM_RI LITERALLY(0b0000000010000000) +#define TIOCM_RNG LITERALLY(0b0000000010000000) +#define TIOCM_DSR LITERALLY(0b0000000100000000) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_MODEM_H_ */ diff --git a/libc/sysv/consts/mount.h b/libc/sysv/consts/mount.h new file mode 100644 index 00000000..a3d75db7 --- /dev/null +++ b/libc/sysv/consts/mount.h @@ -0,0 +1,70 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_MOUNT_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_MOUNT_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long MS_ACTIVE; +hidden extern const long MS_BIND; +hidden extern const long MS_DIRSYNC; +hidden extern const long MS_I_VERSION; +hidden extern const long MS_KERNMOUNT; +hidden extern const long MS_LAZYTIME; +hidden extern const long MS_MANDLOCK; +hidden extern const long MS_MGC_MSK; +hidden extern const long MS_MGC_VAL; +hidden extern const long MS_MOVE; +hidden extern const long MS_NOATIME; +hidden extern const long MS_NODEV; +hidden extern const long MS_NODIRATIME; +hidden extern const long MS_NOEXEC; +hidden extern const long MS_NOSUID; +hidden extern const long MS_NOUSER; +hidden extern const long MS_POSIXACL; +hidden extern const long MS_PRIVATE; +hidden extern const long MS_RDONLY; +hidden extern const long MS_REC; +hidden extern const long MS_RELATIME; +hidden extern const long MS_REMOUNT; +hidden extern const long MS_RMT_MASK; +hidden extern const long MS_SHARED; +hidden extern const long MS_SILENT; +hidden extern const long MS_SLAVE; +hidden extern const long MS_STRICTATIME; +hidden extern const long MS_SYNCHRONOUS; +hidden extern const long MS_UNBINDABLE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define MS_ACTIVE SYMBOLIC(MS_ACTIVE) +#define MS_BIND SYMBOLIC(MS_BIND) +#define MS_DIRSYNC SYMBOLIC(MS_DIRSYNC) +#define MS_I_VERSION SYMBOLIC(MS_I_VERSION) +#define MS_KERNMOUNT SYMBOLIC(MS_KERNMOUNT) +#define MS_LAZYTIME SYMBOLIC(MS_LAZYTIME) +#define MS_MANDLOCK SYMBOLIC(MS_MANDLOCK) +#define MS_MGC_MSK SYMBOLIC(MS_MGC_MSK) +#define MS_MGC_VAL SYMBOLIC(MS_MGC_VAL) +#define MS_MOVE SYMBOLIC(MS_MOVE) +#define MS_NOATIME SYMBOLIC(MS_NOATIME) +#define MS_NODEV SYMBOLIC(MS_NODEV) +#define MS_NODIRATIME SYMBOLIC(MS_NODIRATIME) +#define MS_NOEXEC SYMBOLIC(MS_NOEXEC) +#define MS_NOSUID SYMBOLIC(MS_NOSUID) +#define MS_NOUSER SYMBOLIC(MS_NOUSER) +#define MS_POSIXACL SYMBOLIC(MS_POSIXACL) +#define MS_PRIVATE SYMBOLIC(MS_PRIVATE) +#define MS_RDONLY SYMBOLIC(MS_RDONLY) +#define MS_REC SYMBOLIC(MS_REC) +#define MS_RELATIME SYMBOLIC(MS_RELATIME) +#define MS_REMOUNT SYMBOLIC(MS_REMOUNT) +#define MS_RMT_MASK SYMBOLIC(MS_RMT_MASK) +#define MS_SHARED SYMBOLIC(MS_SHARED) +#define MS_SILENT SYMBOLIC(MS_SILENT) +#define MS_SLAVE SYMBOLIC(MS_SLAVE) +#define MS_STRICTATIME SYMBOLIC(MS_STRICTATIME) +#define MS_SYNCHRONOUS SYMBOLIC(MS_SYNCHRONOUS) +#define MS_UNBINDABLE SYMBOLIC(MS_UNBINDABLE) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_MOUNT_H_ */ diff --git a/libc/sysv/consts/mremap.h b/libc/sysv/consts/mremap.h new file mode 100644 index 00000000..8480bbd5 --- /dev/null +++ b/libc/sysv/consts/mremap.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_MREMAP_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_MREMAP_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long MREMAP_FIXED; +hidden extern const long MREMAP_MAYMOVE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define MREMAP_MAYMOVE LITERALLY(1) +#define MREMAP_FIXED LITERALLY(2) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_MREMAP_H_ */ diff --git a/libc/sysv/consts/msg.h b/libc/sysv/consts/msg.h new file mode 100644 index 00000000..4bf8b57f --- /dev/null +++ b/libc/sysv/consts/msg.h @@ -0,0 +1,62 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_MSG_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_MSG_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long MSG_BATCH; +hidden extern const long MSG_CMSG_CLOEXEC; +hidden extern const long MSG_CONFIRM; +hidden extern const long MSG_CTRUNC; +hidden extern const long MSG_DONTROUTE; +hidden extern const long MSG_DONTWAIT; +hidden extern const long MSG_EOR; +hidden extern const long MSG_ERRQUEUE; +hidden extern const long MSG_EXCEPT; +hidden extern const long MSG_FASTOPEN; +hidden extern const long MSG_FIN; +hidden extern const long MSG_INFO; +hidden extern const long MSG_MORE; +hidden extern const long MSG_NOERROR; +hidden extern const long MSG_NOSIGNAL; +hidden extern const long MSG_OOB; +hidden extern const long MSG_PARITY_ERROR; +hidden extern const long MSG_PEEK; +hidden extern const long MSG_PROXY; +hidden extern const long MSG_RST; +hidden extern const long MSG_STAT; +hidden extern const long MSG_SYN; +hidden extern const long MSG_TRUNC; +hidden extern const long MSG_WAITALL; +hidden extern const long MSG_WAITFORONE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define MSG_BATCH SYMBOLIC(MSG_BATCH) +#define MSG_CMSG_CLOEXEC SYMBOLIC(MSG_CMSG_CLOEXEC) +#define MSG_CONFIRM SYMBOLIC(MSG_CONFIRM) +#define MSG_CTRUNC SYMBOLIC(MSG_CTRUNC) +#define MSG_DONTROUTE LITERALLY(4) +#define MSG_DONTWAIT SYMBOLIC(MSG_DONTWAIT) +#define MSG_EOR SYMBOLIC(MSG_EOR) +#define MSG_ERRQUEUE SYMBOLIC(MSG_ERRQUEUE) +#define MSG_EXCEPT SYMBOLIC(MSG_EXCEPT) +#define MSG_FASTOPEN SYMBOLIC(MSG_FASTOPEN) +#define MSG_FIN SYMBOLIC(MSG_FIN) +#define MSG_INFO SYMBOLIC(MSG_INFO) +#define MSG_MORE SYMBOLIC(MSG_MORE) +#define MSG_NOERROR SYMBOLIC(MSG_NOERROR) +#define MSG_NOSIGNAL SYMBOLIC(MSG_NOSIGNAL) +#define MSG_OOB LITERALLY(1) +#define MSG_PARITY_ERROR SYMBOLIC(MSG_PARITY_ERROR) +#define MSG_PEEK LITERALLY(2) +#define MSG_PROXY SYMBOLIC(MSG_PROXY) +#define MSG_RST SYMBOLIC(MSG_RST) +#define MSG_STAT SYMBOLIC(MSG_STAT) +#define MSG_SYN SYMBOLIC(MSG_SYN) +#define MSG_TRUNC SYMBOLIC(MSG_TRUNC) +#define MSG_WAITALL SYMBOLIC(MSG_WAITALL) +#define MSG_WAITFORONE SYMBOLIC(MSG_WAITFORONE) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_MSG_H_ */ diff --git a/libc/sysv/consts/msync.h b/libc/sysv/consts/msync.h new file mode 100644 index 00000000..79a3843c --- /dev/null +++ b/libc/sysv/consts/msync.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_MSYNC_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_MSYNC_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long MS_SYNC; +hidden extern const long MS_ASYNC; +hidden extern const long MS_INVALIDATE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define MS_SYNC SYMBOLIC(MS_SYNC) +#define MS_ASYNC LITERALLY(1) +#define MS_INVALIDATE SYMBOLIC(MS_INVALIDATE) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_MSYNC_H_ */ diff --git a/libc/sysv/consts/n.h b/libc/sysv/consts/n.h new file mode 100644 index 00000000..97a8f575 --- /dev/null +++ b/libc/sysv/consts/n.h @@ -0,0 +1,44 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_N_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_N_H_ +#include "libc/runtime/symbolic.h" + +#define N_6PACK SYMBOLIC(N_6PACK) +#define N_AX25 SYMBOLIC(N_AX25) +#define N_HCI SYMBOLIC(N_HCI) +#define N_HDLC SYMBOLIC(N_HDLC) +#define N_IRDA SYMBOLIC(N_IRDA) +#define N_MASC SYMBOLIC(N_MASC) +#define N_MOUSE SYMBOLIC(N_MOUSE) +#define N_PPP SYMBOLIC(N_PPP) +#define N_PROFIBUS_FDL SYMBOLIC(N_PROFIBUS_FDL) +#define N_R3964 SYMBOLIC(N_R3964) +#define N_SLIP SYMBOLIC(N_SLIP) +#define N_SMSBLOCK SYMBOLIC(N_SMSBLOCK) +#define N_STRIP SYMBOLIC(N_STRIP) +#define N_SYNC_PPP SYMBOLIC(N_SYNC_PPP) +#define N_TTY SYMBOLIC(N_TTY) +#define N_X25 SYMBOLIC(N_X25) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long N_6PACK; +hidden extern const long N_AX25; +hidden extern const long N_HCI; +hidden extern const long N_HDLC; +hidden extern const long N_IRDA; +hidden extern const long N_MASC; +hidden extern const long N_MOUSE; +hidden extern const long N_PPP; +hidden extern const long N_PROFIBUS_FDL; +hidden extern const long N_R3964; +hidden extern const long N_SLIP; +hidden extern const long N_SMSBLOCK; +hidden extern const long N_STRIP; +hidden extern const long N_SYNC_PPP; +hidden extern const long N_TTY; +hidden extern const long N_X25; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_N_H_ */ diff --git a/libc/sysv/consts/nd.h b/libc/sysv/consts/nd.h new file mode 100644 index 00000000..f05988f2 --- /dev/null +++ b/libc/sysv/consts/nd.h @@ -0,0 +1,34 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_ND_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_ND_H_ +#include "libc/runtime/symbolic.h" + +#define ND_NA_FLAG_OVERRIDE SYMBOLIC(ND_NA_FLAG_OVERRIDE) +#define ND_NA_FLAG_ROUTER SYMBOLIC(ND_NA_FLAG_ROUTER) +#define ND_NA_FLAG_SOLICITED SYMBOLIC(ND_NA_FLAG_SOLICITED) +#define ND_NEIGHBOR_ADVERT SYMBOLIC(ND_NEIGHBOR_ADVERT) +#define ND_NEIGHBOR_SOLICIT SYMBOLIC(ND_NEIGHBOR_SOLICIT) +#define ND_RA_FLAG_HOME_AGENT SYMBOLIC(ND_RA_FLAG_HOME_AGENT) +#define ND_RA_FLAG_MANAGED SYMBOLIC(ND_RA_FLAG_MANAGED) +#define ND_RA_FLAG_OTHER SYMBOLIC(ND_RA_FLAG_OTHER) +#define ND_REDIRECT SYMBOLIC(ND_REDIRECT) +#define ND_ROUTER_ADVERT SYMBOLIC(ND_ROUTER_ADVERT) +#define ND_ROUTER_SOLICIT SYMBOLIC(ND_ROUTER_SOLICIT) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long ND_NA_FLAG_OVERRIDE; +hidden extern const long ND_NA_FLAG_ROUTER; +hidden extern const long ND_NA_FLAG_SOLICITED; +hidden extern const long ND_NEIGHBOR_ADVERT; +hidden extern const long ND_NEIGHBOR_SOLICIT; +hidden extern const long ND_RA_FLAG_HOME_AGENT; +hidden extern const long ND_RA_FLAG_MANAGED; +hidden extern const long ND_RA_FLAG_OTHER; +hidden extern const long ND_REDIRECT; +hidden extern const long ND_ROUTER_ADVERT; +hidden extern const long ND_ROUTER_SOLICIT; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_ND_H_ */ diff --git a/libc/sysv/consts/nr.h b/libc/sysv/consts/nr.h new file mode 100644 index 00000000..2c3a196f --- /dev/null +++ b/libc/sysv/consts/nr.h @@ -0,0 +1,68 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_NR_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_NR_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long __NR_access; +hidden extern const long __NR_arch_prctl; +hidden extern const long __NR_clock_gettime; +hidden extern const long __NR_close; +hidden extern const long __NR_exit; +hidden extern const long __NR_fadvise; +hidden extern const long __NR_fork; +hidden extern const long __NR_fstat; +hidden extern const long __NR_getpid; +hidden extern const long __NR_gettid; +hidden extern const long __NR_gettimeofday; +hidden extern const long __NR_kill; +hidden extern const long __NR_lstat; +hidden extern const long __NR_madvise; +hidden extern const long __NR_mmap; +hidden extern const long __NR_mprotect; +hidden extern const long __NR_munmap; +hidden extern const long __NR_open; +hidden extern const long __NR_pread; +hidden extern const long __NR_pwrite; +hidden extern const long __NR_read; +hidden extern const long __NR_sched_yield; +hidden extern const long __NR_sendfile; +hidden extern const long __NR_sigaction; +hidden extern const long __NR_sigprocmask; +hidden extern const long __NR_stat; +hidden extern const long __NR_write; +hidden extern const long __NR_wait4; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define __NR_access SYMBOLIC(__NR_access) +#define __NR_arch_prctl SYMBOLIC(__NR_arch_prctl) +#define __NR_clock_gettime SYMBOLIC(__NR_clock_gettime) +#define __NR_close SYMBOLIC(__NR_close) +#define __NR_exit SYMBOLIC(__NR_exit) +#define __NR_fadvise SYMBOLIC(__NR_fadvise) +#define __NR_fork SYMBOLIC(__NR_fork) +#define __NR_fstat SYMBOLIC(__NR_fstat) +#define __NR_getpid SYMBOLIC(__NR_getpid) +#define __NR_gettid SYMBOLIC(__NR_gettid) +#define __NR_gettimeofday SYMBOLIC(__NR_gettimeofday) +#define __NR_kill SYMBOLIC(__NR_kill) +#define __NR_lstat SYMBOLIC(__NR_lstat) +#define __NR_madvise SYMBOLIC(__NR_madvise) +#define __NR_mmap SYMBOLIC(__NR_mmap) +#define __NR_mprotect SYMBOLIC(__NR_mprotect) +#define __NR_munmap SYMBOLIC(__NR_munmap) +#define __NR_open SYMBOLIC(__NR_open) +#define __NR_pread SYMBOLIC(__NR_pread) +#define __NR_pwrite SYMBOLIC(__NR_pwrite) +#define __NR_read SYMBOLIC(__NR_read) +#define __NR_sched_yield SYMBOLIC(__NR_sched_yield) +#define __NR_sendfile SYMBOLIC(__NR_sendfile) +#define __NR_sigaction SYMBOLIC(__NR_sigaction) +#define __NR_sigprocmask SYMBOLIC(__NR_sigprocmask) +#define __NR_stat SYMBOLIC(__NR_stat) +#define __NR_write SYMBOLIC(__NR_write) +#define __NR_wait4 SYMBOLIC(__NR_wait4) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_NR_H_ */ diff --git a/libc/sysv/consts/o.h b/libc/sysv/consts/o.h new file mode 100644 index 00000000..a6090f55 --- /dev/null +++ b/libc/sysv/consts/o.h @@ -0,0 +1,64 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_O_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_O_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long O_ACCMODE; +hidden extern const long O_APPEND; +hidden extern const long O_ASYNC; +hidden extern const long O_CLOEXEC; +hidden extern const long O_CREAT; +hidden extern const long O_DIRECT; +hidden extern const long O_DIRECTORY; +hidden extern const long O_DSYNC; +hidden extern const long O_EXCL; +hidden extern const long O_EXEC; +hidden extern const long O_LARGEFILE; +hidden extern const long O_NDELAY; +hidden extern const long O_NOATIME; +hidden extern const long O_NOCTTY; +hidden extern const long O_NOFOLLOW; +hidden extern const long O_NONBLOCK; +hidden extern const long O_PATH; +hidden extern const long O_RDONLY; +hidden extern const long O_RDWR; +hidden extern const long O_RSYNC; +hidden extern const long O_SPARSE; +hidden extern const long O_SYNC; +hidden extern const long O_TMPFILE; +hidden extern const long O_TRUNC; +hidden extern const long O_TTY_INIT; +hidden extern const long O_WRONLY; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define O_ACCMODE SYMBOLIC(O_ACCMODE) +#define O_APPEND SYMBOLIC(O_APPEND) +#define O_ASYNC SYMBOLIC(O_ASYNC) +#define O_CLOEXEC SYMBOLIC(O_CLOEXEC) +#define O_CREAT SYMBOLIC(O_CREAT) +#define O_DIRECT SYMBOLIC(O_DIRECT) +#define O_DIRECTORY SYMBOLIC(O_DIRECTORY) +#define O_DSYNC SYMBOLIC(O_DSYNC) +#define O_EXCL SYMBOLIC(O_EXCL) +#define O_EXEC SYMBOLIC(O_EXEC) +#define O_LARGEFILE SYMBOLIC(O_LARGEFILE) +#define O_NDELAY SYMBOLIC(O_NDELAY) +#define O_NOATIME SYMBOLIC(O_NOATIME) +#define O_NOCTTY SYMBOLIC(O_NOCTTY) +#define O_NOFOLLOW SYMBOLIC(O_NOFOLLOW) +#define O_NONBLOCK SYMBOLIC(O_NONBLOCK) +#define O_PATH SYMBOLIC(O_PATH) +#define O_RDONLY SYMBOLIC(O_RDONLY) +#define O_RDWR SYMBOLIC(O_RDWR) +#define O_RSYNC SYMBOLIC(O_RSYNC) +#define O_SPARSE SYMBOLIC(O_SPARSE) +#define O_SYNC SYMBOLIC(O_SYNC) +#define O_TMPFILE SYMBOLIC(O_TMPFILE) +#define O_TRUNC SYMBOLIC(O_TRUNC) +#define O_TTY_INIT SYMBOLIC(O_TTY_INIT) +#define O_WRONLY SYMBOLIC(O_WRONLY) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_O_H_ */ diff --git a/libc/sysv/consts/ok.h b/libc/sysv/consts/ok.h new file mode 100644 index 00000000..6470b2b1 --- /dev/null +++ b/libc/sysv/consts/ok.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_OK_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_OK_H_ +#include "libc/runtime/symbolic.h" + +#define F_OK SYMBOLIC(F_OK) +#define R_OK SYMBOLIC(R_OK) +#define W_OK SYMBOLIC(W_OK) +#define X_OK SYMBOLIC(X_OK) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long F_OK; +hidden extern const long R_OK; +hidden extern const long W_OK; +hidden extern const long X_OK; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_OK_H_ */ diff --git a/libc/sysv/consts/personality.h b/libc/sysv/consts/personality.h new file mode 100644 index 00000000..a0f5dfcc --- /dev/null +++ b/libc/sysv/consts/personality.h @@ -0,0 +1,34 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_PERSONALITY_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_PERSONALITY_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long ADDR_COMPAT_LAYOUT; +hidden extern const long READ_IMPLIES_EXEC; +hidden extern const long ADDR_LIMIT_3GB; +hidden extern const long FDPIC_FUNCPTRS; +hidden extern const long STICKY_TIMEOUTS; +hidden extern const long MMAP_PAGE_ZERO; +hidden extern const long ADDR_LIMIT_32BIT; +hidden extern const long WHOLE_SECONDS; +hidden extern const long ADDR_NO_RANDOMIZE; +hidden extern const long SHORT_INODE; +hidden extern const long UNAME26; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define ADDR_COMPAT_LAYOUT SYMBOLIC(ADDR_COMPAT_LAYOUT) +#define READ_IMPLIES_EXEC SYMBOLIC(READ_IMPLIES_EXEC) +#define ADDR_LIMIT_3GB SYMBOLIC(ADDR_LIMIT_3GB) +#define FDPIC_FUNCPTRS SYMBOLIC(FDPIC_FUNCPTRS) +#define STICKY_TIMEOUTS SYMBOLIC(STICKY_TIMEOUTS) +#define MMAP_PAGE_ZERO SYMBOLIC(MMAP_PAGE_ZERO) +#define ADDR_LIMIT_32BIT SYMBOLIC(ADDR_LIMIT_32BIT) +#define WHOLE_SECONDS SYMBOLIC(WHOLE_SECONDS) +#define ADDR_NO_RANDOMIZE SYMBOLIC(ADDR_NO_RANDOMIZE) +#define SHORT_INODE SYMBOLIC(SHORT_INODE) +#define UNAME26 SYMBOLIC(UNAME26) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_PERSONALITY_H_ */ diff --git a/libc/sysv/consts/pf.h b/libc/sysv/consts/pf.h new file mode 100644 index 00000000..9f75780a --- /dev/null +++ b/libc/sysv/consts/pf.h @@ -0,0 +1,102 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_PF_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_PF_H_ +#include "libc/runtime/symbolic.h" + +#define PF_ALG SYMBOLIC(PF_ALG) +#define PF_APPLETALK SYMBOLIC(PF_APPLETALK) +#define PF_ASH SYMBOLIC(PF_ASH) +#define PF_ATMPVC SYMBOLIC(PF_ATMPVC) +#define PF_ATMSVC SYMBOLIC(PF_ATMSVC) +#define PF_AX25 SYMBOLIC(PF_AX25) +#define PF_BLUETOOTH SYMBOLIC(PF_BLUETOOTH) +#define PF_BRIDGE SYMBOLIC(PF_BRIDGE) +#define PF_CAIF SYMBOLIC(PF_CAIF) +#define PF_CAN SYMBOLIC(PF_CAN) +#define PF_ECONET SYMBOLIC(PF_ECONET) +#define PF_FILE SYMBOLIC(PF_FILE) +#define PF_IB SYMBOLIC(PF_IB) +#define PF_IEEE802154 SYMBOLIC(PF_IEEE802154) +#define PF_INET SYMBOLIC(PF_INET) +#define PF_INET6 SYMBOLIC(PF_INET6) +#define PF_IPX SYMBOLIC(PF_IPX) +#define PF_IRDA SYMBOLIC(PF_IRDA) +#define PF_ISDN SYMBOLIC(PF_ISDN) +#define PF_IUCV SYMBOLIC(PF_IUCV) +#define PF_KCM SYMBOLIC(PF_KCM) +#define PF_KEY SYMBOLIC(PF_KEY) +#define PF_LLC SYMBOLIC(PF_LLC) +#define PF_LOCAL SYMBOLIC(PF_LOCAL) +#define PF_MAX SYMBOLIC(PF_MAX) +#define PF_MPLS SYMBOLIC(PF_MPLS) +#define PF_NETBEUI SYMBOLIC(PF_NETBEUI) +#define PF_NETLINK SYMBOLIC(PF_NETLINK) +#define PF_NETROM SYMBOLIC(PF_NETROM) +#define PF_NFC SYMBOLIC(PF_NFC) +#define PF_PACKET SYMBOLIC(PF_PACKET) +#define PF_PHONET SYMBOLIC(PF_PHONET) +#define PF_PPPOX SYMBOLIC(PF_PPPOX) +#define PF_RDS SYMBOLIC(PF_RDS) +#define PF_ROSE SYMBOLIC(PF_ROSE) +#define PF_ROUTE SYMBOLIC(PF_ROUTE) +#define PF_RXRPC SYMBOLIC(PF_RXRPC) +#define PF_SECURITY SYMBOLIC(PF_SECURITY) +#define PF_SNA SYMBOLIC(PF_SNA) +#define PF_TIPC SYMBOLIC(PF_TIPC) +#define PF_UNIX SYMBOLIC(PF_UNIX) +#define PF_UNSPEC SYMBOLIC(PF_UNSPEC) +#define PF_VSOCK SYMBOLIC(PF_VSOCK) +#define PF_WANPIPE SYMBOLIC(PF_WANPIPE) +#define PF_X25 SYMBOLIC(PF_X25) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long PF_ALG; +hidden extern const long PF_APPLETALK; +hidden extern const long PF_ASH; +hidden extern const long PF_ATMPVC; +hidden extern const long PF_ATMSVC; +hidden extern const long PF_AX25; +hidden extern const long PF_BLUETOOTH; +hidden extern const long PF_BRIDGE; +hidden extern const long PF_CAIF; +hidden extern const long PF_CAN; +hidden extern const long PF_ECONET; +hidden extern const long PF_FILE; +hidden extern const long PF_IB; +hidden extern const long PF_IEEE802154; +hidden extern const long PF_INET6; +hidden extern const long PF_INET; +hidden extern const long PF_IPX; +hidden extern const long PF_IRDA; +hidden extern const long PF_ISDN; +hidden extern const long PF_IUCV; +hidden extern const long PF_KCM; +hidden extern const long PF_KEY; +hidden extern const long PF_LLC; +hidden extern const long PF_LOCAL; +hidden extern const long PF_MAX; +hidden extern const long PF_MPLS; +hidden extern const long PF_NETBEUI; +hidden extern const long PF_NETLINK; +hidden extern const long PF_NETROM; +hidden extern const long PF_NFC; +hidden extern const long PF_PACKET; +hidden extern const long PF_PHONET; +hidden extern const long PF_PPPOX; +hidden extern const long PF_RDS; +hidden extern const long PF_ROSE; +hidden extern const long PF_ROUTE; +hidden extern const long PF_RXRPC; +hidden extern const long PF_SECURITY; +hidden extern const long PF_SNA; +hidden extern const long PF_TIPC; +hidden extern const long PF_UNIX; +hidden extern const long PF_UNSPEC; +hidden extern const long PF_VSOCK; +hidden extern const long PF_WANPIPE; +hidden extern const long PF_X25; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_PF_H_ */ diff --git a/libc/sysv/consts/poll.h b/libc/sysv/consts/poll.h new file mode 100644 index 00000000..605841d1 --- /dev/null +++ b/libc/sysv/consts/poll.h @@ -0,0 +1,34 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_POLL_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_POLL_H_ +#include "libc/runtime/symbolic.h" + +#define POLLERR SYMBOLIC(POLLERR) +#define POLLHUP SYMBOLIC(POLLHUP) +#define POLLIN SYMBOLIC(POLLIN) +#define POLLNVAL SYMBOLIC(POLLNVAL) +#define POLLOUT SYMBOLIC(POLLOUT) +#define POLLPRI SYMBOLIC(POLLPRI) +#define POLLRDBAND SYMBOLIC(POLLRDBAND) +#define POLLRDHUP SYMBOLIC(POLLRDHUP) +#define POLLRDNORM SYMBOLIC(POLLRDNORM) +#define POLLWRBAND SYMBOLIC(POLLWRBAND) +#define POLLWRNORM SYMBOLIC(POLLWRNORM) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long POLLERR; +hidden extern const long POLLHUP; +hidden extern const long POLLIN; +hidden extern const long POLLNVAL; +hidden extern const long POLLOUT; +hidden extern const long POLLPRI; +hidden extern const long POLLRDBAND; +hidden extern const long POLLRDHUP; +hidden extern const long POLLRDNORM; +hidden extern const long POLLWRBAND; +hidden extern const long POLLWRNORM; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_POLL_H_ */ diff --git a/libc/sysv/consts/posix.h b/libc/sysv/consts/posix.h new file mode 100644 index 00000000..36bec0bb --- /dev/null +++ b/libc/sysv/consts/posix.h @@ -0,0 +1,48 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_POSIX_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_POSIX_H_ +#include "libc/runtime/symbolic.h" + +#define POSIX_FADV_DONTNEED SYMBOLIC(POSIX_FADV_DONTNEED) +#define POSIX_FADV_NOREUSE SYMBOLIC(POSIX_FADV_NOREUSE) +#define POSIX_FADV_NORMAL SYMBOLIC(POSIX_FADV_NORMAL) +#define POSIX_FADV_RANDOM SYMBOLIC(POSIX_FADV_RANDOM) +#define POSIX_FADV_SEQUENTIAL SYMBOLIC(POSIX_FADV_SEQUENTIAL) +#define POSIX_FADV_WILLNEED SYMBOLIC(POSIX_FADV_WILLNEED) +#define POSIX_MADV_DONTNEED SYMBOLIC(POSIX_MADV_DONTNEED) +#define POSIX_MADV_NORMAL SYMBOLIC(POSIX_MADV_NORMAL) +#define POSIX_MADV_RANDOM SYMBOLIC(POSIX_MADV_RANDOM) +#define POSIX_MADV_SEQUENTIAL SYMBOLIC(POSIX_MADV_SEQUENTIAL) +#define POSIX_MADV_WILLNEED SYMBOLIC(POSIX_MADV_WILLNEED) +#define POSIX_SPAWN_RESETIDS SYMBOLIC(POSIX_SPAWN_RESETIDS) +#define POSIX_SPAWN_SETPGROUP SYMBOLIC(POSIX_SPAWN_SETPGROUP) +#define POSIX_SPAWN_SETSCHEDPARAM SYMBOLIC(POSIX_SPAWN_SETSCHEDPARAM) +#define POSIX_SPAWN_SETSCHEDULER SYMBOLIC(POSIX_SPAWN_SETSCHEDULER) +#define POSIX_SPAWN_SETSIGDEF SYMBOLIC(POSIX_SPAWN_SETSIGDEF) +#define POSIX_SPAWN_SETSIGMASK SYMBOLIC(POSIX_SPAWN_SETSIGMASK) +#define POSIX_SPAWN_USEVFORK SYMBOLIC(POSIX_SPAWN_USEVFORK) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long POSIX_FADV_DONTNEED; +hidden extern const long POSIX_FADV_NOREUSE; +hidden extern const long POSIX_FADV_NORMAL; +hidden extern const long POSIX_FADV_RANDOM; +hidden extern const long POSIX_FADV_SEQUENTIAL; +hidden extern const long POSIX_FADV_WILLNEED; +hidden extern const long POSIX_MADV_DONTNEED; +hidden extern const long POSIX_MADV_NORMAL; +hidden extern const long POSIX_MADV_RANDOM; +hidden extern const long POSIX_MADV_SEQUENTIAL; +hidden extern const long POSIX_MADV_WILLNEED; +hidden extern const long POSIX_SPAWN_RESETIDS; +hidden extern const long POSIX_SPAWN_SETPGROUP; +hidden extern const long POSIX_SPAWN_SETSCHEDPARAM; +hidden extern const long POSIX_SPAWN_SETSCHEDULER; +hidden extern const long POSIX_SPAWN_SETSIGDEF; +hidden extern const long POSIX_SPAWN_SETSIGMASK; +hidden extern const long POSIX_SPAWN_USEVFORK; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_POSIX_H_ */ diff --git a/libc/sysv/consts/pr.h b/libc/sysv/consts/pr.h new file mode 100644 index 00000000..d58cea5c --- /dev/null +++ b/libc/sysv/consts/pr.h @@ -0,0 +1,216 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_PR_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_PR_H_ +#include "libc/runtime/symbolic.h" + +#define PR_CAPBSET_DROP SYMBOLIC(PR_CAPBSET_DROP) +#define PR_CAPBSET_READ SYMBOLIC(PR_CAPBSET_READ) +#define PR_CAP_AMBIENT SYMBOLIC(PR_CAP_AMBIENT) +#define PR_CAP_AMBIENT_CLEAR_ALL SYMBOLIC(PR_CAP_AMBIENT_CLEAR_ALL) +#define PR_CAP_AMBIENT_IS_SET SYMBOLIC(PR_CAP_AMBIENT_IS_SET) +#define PR_CAP_AMBIENT_LOWER SYMBOLIC(PR_CAP_AMBIENT_LOWER) +#define PR_CAP_AMBIENT_RAISE SYMBOLIC(PR_CAP_AMBIENT_RAISE) +#define PR_ENDIAN_BIG SYMBOLIC(PR_ENDIAN_BIG) +#define PR_ENDIAN_LITTLE SYMBOLIC(PR_ENDIAN_LITTLE) +#define PR_ENDIAN_PPC_LITTLE SYMBOLIC(PR_ENDIAN_PPC_LITTLE) +#define PR_FPEMU_NOPRINT SYMBOLIC(PR_FPEMU_NOPRINT) +#define PR_FPEMU_SIGFPE SYMBOLIC(PR_FPEMU_SIGFPE) +#define PR_FP_EXC_ASYNC SYMBOLIC(PR_FP_EXC_ASYNC) +#define PR_FP_EXC_DISABLED SYMBOLIC(PR_FP_EXC_DISABLED) +#define PR_FP_EXC_DIV SYMBOLIC(PR_FP_EXC_DIV) +#define PR_FP_EXC_INV SYMBOLIC(PR_FP_EXC_INV) +#define PR_FP_EXC_NONRECOV SYMBOLIC(PR_FP_EXC_NONRECOV) +#define PR_FP_EXC_OVF SYMBOLIC(PR_FP_EXC_OVF) +#define PR_FP_EXC_PRECISE SYMBOLIC(PR_FP_EXC_PRECISE) +#define PR_FP_EXC_RES SYMBOLIC(PR_FP_EXC_RES) +#define PR_FP_EXC_SW_ENABLE SYMBOLIC(PR_FP_EXC_SW_ENABLE) +#define PR_FP_EXC_UND SYMBOLIC(PR_FP_EXC_UND) +#define PR_FP_MODE_FR SYMBOLIC(PR_FP_MODE_FR) +#define PR_FP_MODE_FRE SYMBOLIC(PR_FP_MODE_FRE) +#define PR_GET_CHILD_SUBREAPER SYMBOLIC(PR_GET_CHILD_SUBREAPER) +#define PR_GET_DUMPABLE SYMBOLIC(PR_GET_DUMPABLE) +#define PR_GET_ENDIAN SYMBOLIC(PR_GET_ENDIAN) +#define PR_GET_FPEMU SYMBOLIC(PR_GET_FPEMU) +#define PR_GET_FPEXC SYMBOLIC(PR_GET_FPEXC) +#define PR_GET_FP_MODE SYMBOLIC(PR_GET_FP_MODE) +#define PR_GET_KEEPCAPS SYMBOLIC(PR_GET_KEEPCAPS) +#define PR_GET_NAME SYMBOLIC(PR_GET_NAME) +#define PR_GET_NO_NEW_PRIVS SYMBOLIC(PR_GET_NO_NEW_PRIVS) +#define PR_GET_PDEATHSIG SYMBOLIC(PR_GET_PDEATHSIG) +#define PR_GET_SECCOMP SYMBOLIC(PR_GET_SECCOMP) +#define PR_GET_SECUREBITS SYMBOLIC(PR_GET_SECUREBITS) +#define PR_GET_SPECULATION_CTRL SYMBOLIC(PR_GET_SPECULATION_CTRL) +#define PR_GET_THP_DISABLE SYMBOLIC(PR_GET_THP_DISABLE) +#define PR_GET_TID_ADDRESS SYMBOLIC(PR_GET_TID_ADDRESS) +#define PR_GET_TIMERSLACK SYMBOLIC(PR_GET_TIMERSLACK) +#define PR_GET_TIMING SYMBOLIC(PR_GET_TIMING) +#define PR_GET_TSC SYMBOLIC(PR_GET_TSC) +#define PR_GET_UNALIGN SYMBOLIC(PR_GET_UNALIGN) +#define PR_MCE_KILL SYMBOLIC(PR_MCE_KILL) +#define PR_MCE_KILL_CLEAR SYMBOLIC(PR_MCE_KILL_CLEAR) +#define PR_MCE_KILL_DEFAULT SYMBOLIC(PR_MCE_KILL_DEFAULT) +#define PR_MCE_KILL_EARLY SYMBOLIC(PR_MCE_KILL_EARLY) +#define PR_MCE_KILL_GET SYMBOLIC(PR_MCE_KILL_GET) +#define PR_MCE_KILL_LATE SYMBOLIC(PR_MCE_KILL_LATE) +#define PR_MCE_KILL_SET SYMBOLIC(PR_MCE_KILL_SET) +#define PR_MPX_DISABLE_MANAGEMENT SYMBOLIC(PR_MPX_DISABLE_MANAGEMENT) +#define PR_MPX_ENABLE_MANAGEMENT SYMBOLIC(PR_MPX_ENABLE_MANAGEMENT) +#define PR_SET_CHILD_SUBREAPER SYMBOLIC(PR_SET_CHILD_SUBREAPER) +#define PR_SET_DUMPABLE SYMBOLIC(PR_SET_DUMPABLE) +#define PR_SET_ENDIAN SYMBOLIC(PR_SET_ENDIAN) +#define PR_SET_FPEMU SYMBOLIC(PR_SET_FPEMU) +#define PR_SET_FPEXC SYMBOLIC(PR_SET_FPEXC) +#define PR_SET_FP_MODE SYMBOLIC(PR_SET_FP_MODE) +#define PR_SET_KEEPCAPS SYMBOLIC(PR_SET_KEEPCAPS) +#define PR_SET_MM SYMBOLIC(PR_SET_MM) +#define PR_SET_MM_ARG_END SYMBOLIC(PR_SET_MM_ARG_END) +#define PR_SET_MM_ARG_START SYMBOLIC(PR_SET_MM_ARG_START) +#define PR_SET_MM_AUXV SYMBOLIC(PR_SET_MM_AUXV) +#define PR_SET_MM_BRK SYMBOLIC(PR_SET_MM_BRK) +#define PR_SET_MM_END_CODE SYMBOLIC(PR_SET_MM_END_CODE) +#define PR_SET_MM_END_DATA SYMBOLIC(PR_SET_MM_END_DATA) +#define PR_SET_MM_ENV_END SYMBOLIC(PR_SET_MM_ENV_END) +#define PR_SET_MM_ENV_START SYMBOLIC(PR_SET_MM_ENV_START) +#define PR_SET_MM_EXE_FILE SYMBOLIC(PR_SET_MM_EXE_FILE) +#define PR_SET_MM_MAP SYMBOLIC(PR_SET_MM_MAP) +#define PR_SET_MM_MAP_SIZE SYMBOLIC(PR_SET_MM_MAP_SIZE) +#define PR_SET_MM_START_BRK SYMBOLIC(PR_SET_MM_START_BRK) +#define PR_SET_MM_START_CODE SYMBOLIC(PR_SET_MM_START_CODE) +#define PR_SET_MM_START_DATA SYMBOLIC(PR_SET_MM_START_DATA) +#define PR_SET_MM_START_STACK SYMBOLIC(PR_SET_MM_START_STACK) +#define PR_SET_NAME SYMBOLIC(PR_SET_NAME) +#define PR_SET_NO_NEW_PRIVS SYMBOLIC(PR_SET_NO_NEW_PRIVS) +#define PR_SET_PDEATHSIG SYMBOLIC(PR_SET_PDEATHSIG) +#define PR_SET_PTRACER SYMBOLIC(PR_SET_PTRACER) +#define PR_SET_PTRACER_ANY SYMBOLIC(PR_SET_PTRACER_ANY) +#define PR_SET_SECCOMP SYMBOLIC(PR_SET_SECCOMP) +#define PR_SET_SECUREBITS SYMBOLIC(PR_SET_SECUREBITS) +#define PR_SET_SPECULATION_CTRL SYMBOLIC(PR_SET_SPECULATION_CTRL) +#define PR_SET_THP_DISABLE SYMBOLIC(PR_SET_THP_DISABLE) +#define PR_SET_TIMERSLACK SYMBOLIC(PR_SET_TIMERSLACK) +#define PR_SET_TIMING SYMBOLIC(PR_SET_TIMING) +#define PR_SET_TSC SYMBOLIC(PR_SET_TSC) +#define PR_SET_UNALIGN SYMBOLIC(PR_SET_UNALIGN) +#define PR_SPEC_DISABLE SYMBOLIC(PR_SPEC_DISABLE) +#define PR_SPEC_ENABLE SYMBOLIC(PR_SPEC_ENABLE) +#define PR_SPEC_FORCE_DISABLE SYMBOLIC(PR_SPEC_FORCE_DISABLE) +#define PR_SPEC_NOT_AFFECTED SYMBOLIC(PR_SPEC_NOT_AFFECTED) +#define PR_SPEC_PRCTL SYMBOLIC(PR_SPEC_PRCTL) +#define PR_SPEC_STORE_BYPASS SYMBOLIC(PR_SPEC_STORE_BYPASS) +#define PR_TASK_PERF_EVENTS_DISABLE SYMBOLIC(PR_TASK_PERF_EVENTS_DISABLE) +#define PR_TASK_PERF_EVENTS_ENABLE SYMBOLIC(PR_TASK_PERF_EVENTS_ENABLE) +#define PR_TIMING_STATISTICAL SYMBOLIC(PR_TIMING_STATISTICAL) +#define PR_TIMING_TIMESTAMP SYMBOLIC(PR_TIMING_TIMESTAMP) +#define PR_TSC_ENABLE SYMBOLIC(PR_TSC_ENABLE) +#define PR_TSC_SIGSEGV SYMBOLIC(PR_TSC_SIGSEGV) +#define PR_UNALIGN_NOPRINT SYMBOLIC(PR_UNALIGN_NOPRINT) +#define PR_UNALIGN_SIGBUS SYMBOLIC(PR_UNALIGN_SIGBUS) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long PR_CAPBSET_DROP; +hidden extern const long PR_CAPBSET_READ; +hidden extern const long PR_CAP_AMBIENT; +hidden extern const long PR_CAP_AMBIENT_CLEAR_ALL; +hidden extern const long PR_CAP_AMBIENT_IS_SET; +hidden extern const long PR_CAP_AMBIENT_LOWER; +hidden extern const long PR_CAP_AMBIENT_RAISE; +hidden extern const long PR_ENDIAN_BIG; +hidden extern const long PR_ENDIAN_LITTLE; +hidden extern const long PR_ENDIAN_PPC_LITTLE; +hidden extern const long PR_FPEMU_NOPRINT; +hidden extern const long PR_FPEMU_SIGFPE; +hidden extern const long PR_FP_EXC_ASYNC; +hidden extern const long PR_FP_EXC_DISABLED; +hidden extern const long PR_FP_EXC_DIV; +hidden extern const long PR_FP_EXC_INV; +hidden extern const long PR_FP_EXC_NONRECOV; +hidden extern const long PR_FP_EXC_OVF; +hidden extern const long PR_FP_EXC_PRECISE; +hidden extern const long PR_FP_EXC_RES; +hidden extern const long PR_FP_EXC_SW_ENABLE; +hidden extern const long PR_FP_EXC_UND; +hidden extern const long PR_FP_MODE_FR; +hidden extern const long PR_FP_MODE_FRE; +hidden extern const long PR_GET_CHILD_SUBREAPER; +hidden extern const long PR_GET_DUMPABLE; +hidden extern const long PR_GET_ENDIAN; +hidden extern const long PR_GET_FPEMU; +hidden extern const long PR_GET_FPEXC; +hidden extern const long PR_GET_FP_MODE; +hidden extern const long PR_GET_KEEPCAPS; +hidden extern const long PR_GET_NAME; +hidden extern const long PR_GET_NO_NEW_PRIVS; +hidden extern const long PR_GET_PDEATHSIG; +hidden extern const long PR_GET_SECCOMP; +hidden extern const long PR_GET_SECUREBITS; +hidden extern const long PR_GET_SPECULATION_CTRL; +hidden extern const long PR_GET_THP_DISABLE; +hidden extern const long PR_GET_TID_ADDRESS; +hidden extern const long PR_GET_TIMERSLACK; +hidden extern const long PR_GET_TIMING; +hidden extern const long PR_GET_TSC; +hidden extern const long PR_GET_UNALIGN; +hidden extern const long PR_MCE_KILL; +hidden extern const long PR_MCE_KILL_CLEAR; +hidden extern const long PR_MCE_KILL_DEFAULT; +hidden extern const long PR_MCE_KILL_EARLY; +hidden extern const long PR_MCE_KILL_GET; +hidden extern const long PR_MCE_KILL_LATE; +hidden extern const long PR_MCE_KILL_SET; +hidden extern const long PR_MPX_DISABLE_MANAGEMENT; +hidden extern const long PR_MPX_ENABLE_MANAGEMENT; +hidden extern const long PR_SET_CHILD_SUBREAPER; +hidden extern const long PR_SET_DUMPABLE; +hidden extern const long PR_SET_ENDIAN; +hidden extern const long PR_SET_FPEMU; +hidden extern const long PR_SET_FPEXC; +hidden extern const long PR_SET_FP_MODE; +hidden extern const long PR_SET_KEEPCAPS; +hidden extern const long PR_SET_MM; +hidden extern const long PR_SET_MM_ARG_END; +hidden extern const long PR_SET_MM_ARG_START; +hidden extern const long PR_SET_MM_AUXV; +hidden extern const long PR_SET_MM_BRK; +hidden extern const long PR_SET_MM_END_CODE; +hidden extern const long PR_SET_MM_END_DATA; +hidden extern const long PR_SET_MM_ENV_END; +hidden extern const long PR_SET_MM_ENV_START; +hidden extern const long PR_SET_MM_EXE_FILE; +hidden extern const long PR_SET_MM_MAP; +hidden extern const long PR_SET_MM_MAP_SIZE; +hidden extern const long PR_SET_MM_START_BRK; +hidden extern const long PR_SET_MM_START_CODE; +hidden extern const long PR_SET_MM_START_DATA; +hidden extern const long PR_SET_MM_START_STACK; +hidden extern const long PR_SET_NAME; +hidden extern const long PR_SET_NO_NEW_PRIVS; +hidden extern const long PR_SET_PDEATHSIG; +hidden extern const long PR_SET_PTRACER; +hidden extern const long PR_SET_PTRACER_ANY; +hidden extern const long PR_SET_SECCOMP; +hidden extern const long PR_SET_SECUREBITS; +hidden extern const long PR_SET_SPECULATION_CTRL; +hidden extern const long PR_SET_THP_DISABLE; +hidden extern const long PR_SET_TIMERSLACK; +hidden extern const long PR_SET_TIMING; +hidden extern const long PR_SET_TSC; +hidden extern const long PR_SET_UNALIGN; +hidden extern const long PR_SPEC_DISABLE; +hidden extern const long PR_SPEC_ENABLE; +hidden extern const long PR_SPEC_FORCE_DISABLE; +hidden extern const long PR_SPEC_NOT_AFFECTED; +hidden extern const long PR_SPEC_PRCTL; +hidden extern const long PR_SPEC_STORE_BYPASS; +hidden extern const long PR_TASK_PERF_EVENTS_DISABLE; +hidden extern const long PR_TASK_PERF_EVENTS_ENABLE; +hidden extern const long PR_TIMING_STATISTICAL; +hidden extern const long PR_TIMING_TIMESTAMP; +hidden extern const long PR_TSC_ENABLE; +hidden extern const long PR_TSC_SIGSEGV; +hidden extern const long PR_UNALIGN_NOPRINT; +hidden extern const long PR_UNALIGN_SIGBUS; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_PR_H_ */ diff --git a/libc/sysv/consts/prio.h b/libc/sysv/consts/prio.h new file mode 100644 index 00000000..57b4e424 --- /dev/null +++ b/libc/sysv/consts/prio.h @@ -0,0 +1,24 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_PRIO_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_PRIO_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long PRIO_MAX; +hidden extern const long PRIO_MIN; +hidden extern const long PRIO_PGRP; +hidden extern const long PRIO_PROCESS; +hidden extern const long PRIO_USER; +hidden extern const long NZERO; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define PRIO_PROCESS LITERALLY(0) +#define PRIO_PGRP LITERALLY(1) +#define PRIO_USER LITERALLY(2) +#define PRIO_MIN LITERALLY(-20) +#define PRIO_MAX LITERALLY(20) +#define NZERO LITERALLY(20) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_PRIO_H_ */ diff --git a/libc/sysv/consts/prot.h b/libc/sysv/consts/prot.h new file mode 100644 index 00000000..1b37bb98 --- /dev/null +++ b/libc/sysv/consts/prot.h @@ -0,0 +1,24 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_PROT_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_PROT_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long PROT_NONE; +hidden extern const long PROT_READ; +hidden extern const long PROT_WRITE; +hidden extern const long PROT_EXEC; +hidden extern const long PROT_GROWSDOWN; +hidden extern const long PROT_GROWSUP; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define PROT_NONE 0 +#define PROT_READ 1 +#define PROT_WRITE 2 +#define PROT_EXEC 4 +#define PROT_GROWSDOWN SYMBOLIC(PROT_GROWSDOWN) +#define PROT_GROWSUP SYMBOLIC(PROT_GROWSUP) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_PROT_H_ */ diff --git a/libc/sysv/consts/pt.h b/libc/sysv/consts/pt.h new file mode 100644 index 00000000..a21d98ff --- /dev/null +++ b/libc/sysv/consts/pt.h @@ -0,0 +1,58 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_PT_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_PT_H_ +#include "libc/runtime/symbolic.h" + +#define PT_ATTACH SYMBOLIC(PT_ATTACH) +#define PT_CONTINUE SYMBOLIC(PT_CONTINUE) +#define PT_DETACH SYMBOLIC(PT_DETACH) +#define PT_GETEVENTMSG SYMBOLIC(PT_GETEVENTMSG) +#define PT_GETFPREGS SYMBOLIC(PT_GETFPREGS) +#define PT_GETFPXREGS SYMBOLIC(PT_GETFPXREGS) +#define PT_GETREGS SYMBOLIC(PT_GETREGS) +#define PT_GETSIGINFO SYMBOLIC(PT_GETSIGINFO) +#define PT_KILL SYMBOLIC(PT_KILL) +#define PT_READ_D SYMBOLIC(PT_READ_D) +#define PT_READ_I SYMBOLIC(PT_READ_I) +#define PT_READ_U SYMBOLIC(PT_READ_U) +#define PT_SETFPREGS SYMBOLIC(PT_SETFPREGS) +#define PT_SETFPXREGS SYMBOLIC(PT_SETFPXREGS) +#define PT_SETOPTIONS SYMBOLIC(PT_SETOPTIONS) +#define PT_SETREGS SYMBOLIC(PT_SETREGS) +#define PT_SETSIGINFO SYMBOLIC(PT_SETSIGINFO) +#define PT_STEP SYMBOLIC(PT_STEP) +#define PT_SYSCALL SYMBOLIC(PT_SYSCALL) +#define PT_TRACE_ME SYMBOLIC(PT_TRACE_ME) +#define PT_WRITE_D SYMBOLIC(PT_WRITE_D) +#define PT_WRITE_I SYMBOLIC(PT_WRITE_I) +#define PT_WRITE_U SYMBOLIC(PT_WRITE_U) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long PT_ATTACH; +hidden extern const long PT_CONTINUE; +hidden extern const long PT_DETACH; +hidden extern const long PT_GETEVENTMSG; +hidden extern const long PT_GETFPREGS; +hidden extern const long PT_GETFPXREGS; +hidden extern const long PT_GETREGS; +hidden extern const long PT_GETSIGINFO; +hidden extern const long PT_KILL; +hidden extern const long PT_READ_D; +hidden extern const long PT_READ_I; +hidden extern const long PT_READ_U; +hidden extern const long PT_SETFPREGS; +hidden extern const long PT_SETFPXREGS; +hidden extern const long PT_SETOPTIONS; +hidden extern const long PT_SETREGS; +hidden extern const long PT_SETSIGINFO; +hidden extern const long PT_STEP; +hidden extern const long PT_SYSCALL; +hidden extern const long PT_TRACE_ME; +hidden extern const long PT_WRITE_D; +hidden extern const long PT_WRITE_I; +hidden extern const long PT_WRITE_U; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_PT_H_ */ diff --git a/libc/sysv/consts/ptrace.h b/libc/sysv/consts/ptrace.h new file mode 100644 index 00000000..b2ec1f62 --- /dev/null +++ b/libc/sysv/consts/ptrace.h @@ -0,0 +1,32 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_PTRACE_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_PTRACE_H_ +#include "libc/runtime/symbolic.h" + +#define PTRACE_GETREGSET SYMBOLIC(PTRACE_GETREGSET) +#define PTRACE_GETSIGMASK SYMBOLIC(PTRACE_GETSIGMASK) +#define PTRACE_INTERRUPT SYMBOLIC(PTRACE_INTERRUPT) +#define PTRACE_LISTEN SYMBOLIC(PTRACE_LISTEN) +#define PTRACE_PEEKSIGINFO SYMBOLIC(PTRACE_PEEKSIGINFO) +#define PTRACE_SECCOMP_GET_FILTER SYMBOLIC(PTRACE_SECCOMP_GET_FILTER) +#define PTRACE_SEIZE SYMBOLIC(PTRACE_SEIZE) +#define PTRACE_SETREGSET SYMBOLIC(PTRACE_SETREGSET) +#define PTRACE_SETSIGMASK SYMBOLIC(PTRACE_SETSIGMASK) +#define PTRACE_SYSCALL SYMBOLIC(PTRACE_SYSCALL) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long PTRACE_GETREGSET; +hidden extern const long PTRACE_GETSIGMASK; +hidden extern const long PTRACE_INTERRUPT; +hidden extern const long PTRACE_LISTEN; +hidden extern const long PTRACE_PEEKSIGINFO; +hidden extern const long PTRACE_SECCOMP_GET_FILTER; +hidden extern const long PTRACE_SEIZE; +hidden extern const long PTRACE_SETREGSET; +hidden extern const long PTRACE_SETSIGMASK; +hidden extern const long PTRACE_SYSCALL; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_PTRACE_H_ */ diff --git a/libc/sysv/consts/pty.h b/libc/sysv/consts/pty.h new file mode 100644 index 00000000..71bf17f9 --- /dev/null +++ b/libc/sysv/consts/pty.h @@ -0,0 +1,34 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_PTY_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_PTY_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long TIOCPKT; +hidden extern const long TIOCPKT_DATA; +hidden extern const long TIOCPKT_DOSTOP; +hidden extern const long TIOCPKT_FLUSHREAD; +hidden extern const long TIOCPKT_FLUSHWRITE; +hidden extern const long TIOCPKT_IOCTL; +hidden extern const long TIOCPKT_NOSTOP; +hidden extern const long TIOCPKT_START; +hidden extern const long TIOCPKT_STOP; +hidden extern const long TIOCSPTLCK; +hidden extern const long PTMGET; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define TIOCPKT SYMBOLIC(TIOCPKT) +#define TIOCSPTLCK SYMBOLIC(TIOCSPTLCK) +#define PTMGET SYMBOLIC(PTMGET) +#define TIOCPKT_DATA LITERALLY(0b0000000000000000) +#define TIOCPKT_DOSTOP LITERALLY(0b0000000000000001) +#define TIOCPKT_FLUSHREAD LITERALLY(0b0000000000000010) +#define TIOCPKT_FLUSHWRITE LITERALLY(0b0000000000000100) +#define TIOCPKT_IOCTL LITERALLY(0b0000000000001000) +#define TIOCPKT_NOSTOP LITERALLY(0b0000000000010000) +#define TIOCPKT_START LITERALLY(0b0000000000100000) +#define TIOCPKT_STOP LITERALLY(0b0000000001000000) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_PTY_H_ */ diff --git a/libc/sysv/consts/read.h b/libc/sysv/consts/read.h new file mode 100644 index 00000000..3aab5cb8 --- /dev/null +++ b/libc/sysv/consts/read.h @@ -0,0 +1,36 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_READ_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_READ_H_ +#include "libc/runtime/symbolic.h" + +#define READ_10 SYMBOLIC(READ_10) +#define READ_12 SYMBOLIC(READ_12) +#define READ_6 SYMBOLIC(READ_6) +#define READ_BLOCK_LIMITS SYMBOLIC(READ_BLOCK_LIMITS) +#define READ_BUFFER SYMBOLIC(READ_BUFFER) +#define READ_CAPACITY SYMBOLIC(READ_CAPACITY) +#define READ_DEFECT_DATA SYMBOLIC(READ_DEFECT_DATA) +#define READ_ELEMENT_STATUS SYMBOLIC(READ_ELEMENT_STATUS) +#define READ_LONG SYMBOLIC(READ_LONG) +#define READ_POSITION SYMBOLIC(READ_POSITION) +#define READ_REVERSE SYMBOLIC(READ_REVERSE) +#define READ_TOC SYMBOLIC(READ_TOC) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long READ_10; +hidden extern const long READ_12; +hidden extern const long READ_6; +hidden extern const long READ_BLOCK_LIMITS; +hidden extern const long READ_BUFFER; +hidden extern const long READ_CAPACITY; +hidden extern const long READ_DEFECT_DATA; +hidden extern const long READ_ELEMENT_STATUS; +hidden extern const long READ_LONG; +hidden extern const long READ_POSITION; +hidden extern const long READ_REVERSE; +hidden extern const long READ_TOC; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_READ_H_ */ diff --git a/libc/sysv/consts/rlim.h b/libc/sysv/consts/rlim.h new file mode 100644 index 00000000..75e1f8e5 --- /dev/null +++ b/libc/sysv/consts/rlim.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_RLIM_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_RLIM_H_ +#include "libc/runtime/symbolic.h" + +#define RLIM_INFINITY SYMBOLIC(RLIM_INFINITY) +#define RLIM_NLIMITS SYMBOLIC(RLIM_NLIMITS) +#define RLIM_SAVED_CUR SYMBOLIC(RLIM_SAVED_CUR) +#define RLIM_SAVED_MAX SYMBOLIC(RLIM_SAVED_MAX) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long RLIM_INFINITY; +hidden extern const long RLIM_NLIMITS; +hidden extern const long RLIM_SAVED_CUR; +hidden extern const long RLIM_SAVED_MAX; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_RLIM_H_ */ diff --git a/libc/sysv/consts/rlimit.h b/libc/sysv/consts/rlimit.h new file mode 100644 index 00000000..7eaa140e --- /dev/null +++ b/libc/sysv/consts/rlimit.h @@ -0,0 +1,44 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_RLIMIT_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_RLIMIT_H_ +#include "libc/runtime/symbolic.h" + +#define RLIMIT_AS SYMBOLIC(RLIMIT_AS) +#define RLIMIT_CORE SYMBOLIC(RLIMIT_CORE) +#define RLIMIT_CPU SYMBOLIC(RLIMIT_CPU) +#define RLIMIT_DATA SYMBOLIC(RLIMIT_DATA) +#define RLIMIT_FSIZE SYMBOLIC(RLIMIT_FSIZE) +#define RLIMIT_LOCKS SYMBOLIC(RLIMIT_LOCKS) +#define RLIMIT_MEMLOCK SYMBOLIC(RLIMIT_MEMLOCK) +#define RLIMIT_MSGQUEUE SYMBOLIC(RLIMIT_MSGQUEUE) +#define RLIMIT_NICE SYMBOLIC(RLIMIT_NICE) +#define RLIMIT_NLIMITS SYMBOLIC(RLIMIT_NLIMITS) +#define RLIMIT_NOFILE SYMBOLIC(RLIMIT_NOFILE) +#define RLIMIT_NPROC SYMBOLIC(RLIMIT_NPROC) +#define RLIMIT_RSS SYMBOLIC(RLIMIT_RSS) +#define RLIMIT_RTPRIO SYMBOLIC(RLIMIT_RTPRIO) +#define RLIMIT_SIGPENDING SYMBOLIC(RLIMIT_SIGPENDING) +#define RLIMIT_STACK SYMBOLIC(RLIMIT_STACK) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long RLIMIT_AS; +hidden extern const long RLIMIT_CORE; +hidden extern const long RLIMIT_CPU; +hidden extern const long RLIMIT_DATA; +hidden extern const long RLIMIT_FSIZE; +hidden extern const long RLIMIT_LOCKS; +hidden extern const long RLIMIT_MEMLOCK; +hidden extern const long RLIMIT_MSGQUEUE; +hidden extern const long RLIMIT_NICE; +hidden extern const long RLIMIT_NLIMITS; +hidden extern const long RLIMIT_NOFILE; +hidden extern const long RLIMIT_NPROC; +hidden extern const long RLIMIT_RSS; +hidden extern const long RLIMIT_RTPRIO; +hidden extern const long RLIMIT_SIGPENDING; +hidden extern const long RLIMIT_STACK; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_RLIMIT_H_ */ diff --git a/libc/sysv/consts/rtld.h b/libc/sysv/consts/rtld.h new file mode 100644 index 00000000..b89c1bf9 --- /dev/null +++ b/libc/sysv/consts/rtld.h @@ -0,0 +1,26 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_RTLD_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_RTLD_H_ +#include "libc/runtime/symbolic.h" + +#define RTLD_DI_LINKMAP SYMBOLIC(RTLD_DI_LINKMAP) +#define RTLD_GLOBAL SYMBOLIC(RTLD_GLOBAL) +#define RTLD_LAZY SYMBOLIC(RTLD_LAZY) +#define RTLD_LOCAL SYMBOLIC(RTLD_LOCAL) +#define RTLD_NODELETE SYMBOLIC(RTLD_NODELETE) +#define RTLD_NOLOAD SYMBOLIC(RTLD_NOLOAD) +#define RTLD_NOW SYMBOLIC(RTLD_NOW) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long RTLD_DI_LINKMAP; +hidden extern const long RTLD_GLOBAL; +hidden extern const long RTLD_LAZY; +hidden extern const long RTLD_LOCAL; +hidden extern const long RTLD_NODELETE; +hidden extern const long RTLD_NOLOAD; +hidden extern const long RTLD_NOW; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_RTLD_H_ */ diff --git a/libc/sysv/consts/rusage.h b/libc/sysv/consts/rusage.h new file mode 100644 index 00000000..786afac3 --- /dev/null +++ b/libc/sysv/consts/rusage.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_RUSAGE_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_RUSAGE_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long RUSAGE_CHILDREN; +hidden extern const long RUSAGE_SELF; +hidden extern const long RUSAGE_THREAD; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define RUSAGE_SELF LITERALLY(0) +#define RUSAGE_CHILDREN SYMBOLIC(RUSAGE_CHILDREN) +#define RUSAGE_THREAD SYMBOLIC(RUSAGE_THREAD) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_RUSAGE_H_ */ diff --git a/libc/sysv/consts/s.h b/libc/sysv/consts/s.h new file mode 100644 index 00000000..38464c0c --- /dev/null +++ b/libc/sysv/consts/s.h @@ -0,0 +1,64 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_S_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_S_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long S_IEXEC; +hidden extern const long S_IFBLK; +hidden extern const long S_IFCHR; +hidden extern const long S_IFDIR; +hidden extern const long S_IFIFO; +hidden extern const long S_IFLNK; +hidden extern const long S_IFMT; +hidden extern const long S_IFREG; +hidden extern const long S_IFSOCK; +hidden extern const long S_IREAD; +hidden extern const long S_IRGRP; +hidden extern const long S_IROTH; +hidden extern const long S_IRUSR; +hidden extern const long S_IRWXG; +hidden extern const long S_IRWXO; +hidden extern const long S_IRWXU; +hidden extern const long S_ISGID; +hidden extern const long S_ISUID; +hidden extern const long S_ISVTX; +hidden extern const long S_IWGRP; +hidden extern const long S_IWOTH; +hidden extern const long S_IWRITE; +hidden extern const long S_IWUSR; +hidden extern const long S_IXGRP; +hidden extern const long S_IXOTH; +hidden extern const long S_IXUSR; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define S_IFREG LITERALLY(0100000) +#define S_IFBLK LITERALLY(0060000) +#define S_IFCHR LITERALLY(0020000) +#define S_IFDIR LITERALLY(0040000) +#define S_IFIFO LITERALLY(0010000) +#define S_IFMT LITERALLY(0170000) +#define S_IFLNK LITERALLY(0120000) +#define S_IFSOCK LITERALLY(0140000) +#define S_ISVTX LITERALLY(01000) +#define S_ISGID LITERALLY(02000) +#define S_ISUID LITERALLY(04000) +#define S_IEXEC LITERALLY(00100) +#define S_IWRITE LITERALLY(00200) +#define S_IREAD LITERALLY(00400) +#define S_IXUSR LITERALLY(00100) +#define S_IWUSR LITERALLY(00200) +#define S_IRUSR LITERALLY(00400) +#define S_IRWXU LITERALLY(00700) +#define S_IXGRP LITERALLY(00010) +#define S_IWGRP LITERALLY(00020) +#define S_IRGRP LITERALLY(00040) +#define S_IRWXG LITERALLY(00070) +#define S_IXOTH LITERALLY(00001) +#define S_IWOTH LITERALLY(00002) +#define S_IROTH LITERALLY(00004) +#define S_IRWXO LITERALLY(00007) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_S_H_ */ diff --git a/libc/sysv/consts/sa.h b/libc/sysv/consts/sa.h new file mode 100644 index 00000000..134f6288 --- /dev/null +++ b/libc/sysv/consts/sa.h @@ -0,0 +1,32 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SA_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SA_H_ +#include "libc/runtime/symbolic.h" + +#define SA_NOCLDSTOP SYMBOLIC(SA_NOCLDSTOP) +#define SA_NOCLDWAIT SYMBOLIC(SA_NOCLDWAIT) +#define SA_NODEFER SYMBOLIC(SA_NODEFER) +#define SA_NOMASK SYMBOLIC(SA_NOMASK) +#define SA_ONESHOT SYMBOLIC(SA_ONESHOT) +#define SA_ONSTACK SYMBOLIC(SA_ONSTACK) +#define SA_RESETHAND SYMBOLIC(SA_RESETHAND) +#define SA_RESTART SYMBOLIC(SA_RESTART) +#define SA_RESTORER SYMBOLIC(SA_RESTORER) +#define SA_SIGINFO SYMBOLIC(SA_SIGINFO) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long SA_NOCLDSTOP; +hidden extern const long SA_NOCLDWAIT; +hidden extern const long SA_NODEFER; +hidden extern const long SA_NOMASK; +hidden extern const long SA_ONESHOT; +hidden extern const long SA_ONSTACK; +hidden extern const long SA_RESETHAND; +hidden extern const long SA_RESTART; +hidden extern const long SA_RESTORER; +hidden extern const long SA_SIGINFO; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SA_H_ */ diff --git a/libc/sysv/consts/sched.h b/libc/sysv/consts/sched.h new file mode 100644 index 00000000..5e7c5bed --- /dev/null +++ b/libc/sysv/consts/sched.h @@ -0,0 +1,24 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SCHED_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SCHED_H_ +#include "libc/runtime/symbolic.h" + +#define SCHED_BATCH SYMBOLIC(SCHED_BATCH) +#define SCHED_FIFO SYMBOLIC(SCHED_FIFO) +#define SCHED_IDLE SYMBOLIC(SCHED_IDLE) +#define SCHED_OTHER SYMBOLIC(SCHED_OTHER) +#define SCHED_RESET_ON_FORK SYMBOLIC(SCHED_RESET_ON_FORK) +#define SCHED_RR SYMBOLIC(SCHED_RR) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long SCHED_BATCH; +hidden extern const long SCHED_FIFO; +hidden extern const long SCHED_IDLE; +hidden extern const long SCHED_OTHER; +hidden extern const long SCHED_RESET_ON_FORK; +hidden extern const long SCHED_RR; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SCHED_H_ */ diff --git a/libc/sysv/consts/scsi.h b/libc/sysv/consts/scsi.h new file mode 100644 index 00000000..dc90406e --- /dev/null +++ b/libc/sysv/consts/scsi.h @@ -0,0 +1,38 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SCSI_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SCSI_H_ +#include "libc/runtime/symbolic.h" + +#define SCSI_IOCTL_BENCHMARK_COMMAND SYMBOLIC(SCSI_IOCTL_BENCHMARK_COMMAND) +#define SCSI_IOCTL_DOORLOCK SYMBOLIC(SCSI_IOCTL_DOORLOCK) +#define SCSI_IOCTL_DOORUNLOCK SYMBOLIC(SCSI_IOCTL_DOORUNLOCK) +#define SCSI_IOCTL_GET_BUS_NUMBER SYMBOLIC(SCSI_IOCTL_GET_BUS_NUMBER) +#define SCSI_IOCTL_GET_IDLUN SYMBOLIC(SCSI_IOCTL_GET_IDLUN) +#define SCSI_IOCTL_PROBE_HOST SYMBOLIC(SCSI_IOCTL_PROBE_HOST) +#define SCSI_IOCTL_SEND_COMMAND SYMBOLIC(SCSI_IOCTL_SEND_COMMAND) +#define SCSI_IOCTL_START_UNIT SYMBOLIC(SCSI_IOCTL_START_UNIT) +#define SCSI_IOCTL_STOP_UNIT SYMBOLIC(SCSI_IOCTL_STOP_UNIT) +#define SCSI_IOCTL_SYNC SYMBOLIC(SCSI_IOCTL_SYNC) +#define SCSI_IOCTL_TAGGED_DISABLE SYMBOLIC(SCSI_IOCTL_TAGGED_DISABLE) +#define SCSI_IOCTL_TAGGED_ENABLE SYMBOLIC(SCSI_IOCTL_TAGGED_ENABLE) +#define SCSI_IOCTL_TEST_UNIT_READY SYMBOLIC(SCSI_IOCTL_TEST_UNIT_READY) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long SCSI_IOCTL_BENCHMARK_COMMAND; +hidden extern const long SCSI_IOCTL_DOORLOCK; +hidden extern const long SCSI_IOCTL_DOORUNLOCK; +hidden extern const long SCSI_IOCTL_GET_BUS_NUMBER; +hidden extern const long SCSI_IOCTL_GET_IDLUN; +hidden extern const long SCSI_IOCTL_PROBE_HOST; +hidden extern const long SCSI_IOCTL_SEND_COMMAND; +hidden extern const long SCSI_IOCTL_START_UNIT; +hidden extern const long SCSI_IOCTL_STOP_UNIT; +hidden extern const long SCSI_IOCTL_SYNC; +hidden extern const long SCSI_IOCTL_TAGGED_DISABLE; +hidden extern const long SCSI_IOCTL_TAGGED_ENABLE; +hidden extern const long SCSI_IOCTL_TEST_UNIT_READY; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SCSI_H_ */ diff --git a/libc/sysv/consts/segv.h b/libc/sysv/consts/segv.h new file mode 100644 index 00000000..bbd928ca --- /dev/null +++ b/libc/sysv/consts/segv.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SEGV_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SEGV_H_ +#include "libc/runtime/symbolic.h" + +#define SEGV_ACCERR SYMBOLIC(SEGV_ACCERR) +#define SEGV_MAPERR SYMBOLIC(SEGV_MAPERR) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long SEGV_ACCERR; +hidden extern const long SEGV_MAPERR; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SEGV_H_ */ diff --git a/libc/sysv/consts/sg.h b/libc/sysv/consts/sg.h new file mode 100644 index 00000000..8e7be19f --- /dev/null +++ b/libc/sysv/consts/sg.h @@ -0,0 +1,120 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SG_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SG_H_ +#include "libc/runtime/symbolic.h" + +#define SG_BIG_BUFF SYMBOLIC(SG_BIG_BUFF) +#define SG_DEFAULT_RETRIES SYMBOLIC(SG_DEFAULT_RETRIES) +#define SG_DEFAULT_TIMEOUT SYMBOLIC(SG_DEFAULT_TIMEOUT) +#define SG_DEF_COMMAND_Q SYMBOLIC(SG_DEF_COMMAND_Q) +#define SG_DEF_FORCE_LOW_DMA SYMBOLIC(SG_DEF_FORCE_LOW_DMA) +#define SG_DEF_FORCE_PACK_ID SYMBOLIC(SG_DEF_FORCE_PACK_ID) +#define SG_DEF_KEEP_ORPHAN SYMBOLIC(SG_DEF_KEEP_ORPHAN) +#define SG_DEF_RESERVED_SIZE SYMBOLIC(SG_DEF_RESERVED_SIZE) +#define SG_DEF_UNDERRUN_FLAG SYMBOLIC(SG_DEF_UNDERRUN_FLAG) +#define SG_DXFER_FROM_DEV SYMBOLIC(SG_DXFER_FROM_DEV) +#define SG_DXFER_NONE SYMBOLIC(SG_DXFER_NONE) +#define SG_DXFER_TO_DEV SYMBOLIC(SG_DXFER_TO_DEV) +#define SG_DXFER_TO_FROM_DEV SYMBOLIC(SG_DXFER_TO_FROM_DEV) +#define SG_EMULATED_HOST SYMBOLIC(SG_EMULATED_HOST) +#define SG_FLAG_DIRECT_IO SYMBOLIC(SG_FLAG_DIRECT_IO) +#define SG_FLAG_LUN_INHIBIT SYMBOLIC(SG_FLAG_LUN_INHIBIT) +#define SG_FLAG_NO_DXFER SYMBOLIC(SG_FLAG_NO_DXFER) +#define SG_GET_COMMAND_Q SYMBOLIC(SG_GET_COMMAND_Q) +#define SG_GET_KEEP_ORPHAN SYMBOLIC(SG_GET_KEEP_ORPHAN) +#define SG_GET_LOW_DMA SYMBOLIC(SG_GET_LOW_DMA) +#define SG_GET_NUM_WAITING SYMBOLIC(SG_GET_NUM_WAITING) +#define SG_GET_PACK_ID SYMBOLIC(SG_GET_PACK_ID) +#define SG_GET_REQUEST_TABLE SYMBOLIC(SG_GET_REQUEST_TABLE) +#define SG_GET_RESERVED_SIZE SYMBOLIC(SG_GET_RESERVED_SIZE) +#define SG_GET_SCSI_ID SYMBOLIC(SG_GET_SCSI_ID) +#define SG_GET_SG_TABLESIZE SYMBOLIC(SG_GET_SG_TABLESIZE) +#define SG_GET_TIMEOUT SYMBOLIC(SG_GET_TIMEOUT) +#define SG_GET_TRANSFORM SYMBOLIC(SG_GET_TRANSFORM) +#define SG_GET_VERSION_NUM SYMBOLIC(SG_GET_VERSION_NUM) +#define SG_INFO_CHECK SYMBOLIC(SG_INFO_CHECK) +#define SG_INFO_DIRECT_IO SYMBOLIC(SG_INFO_DIRECT_IO) +#define SG_INFO_DIRECT_IO_MASK SYMBOLIC(SG_INFO_DIRECT_IO_MASK) +#define SG_INFO_INDIRECT_IO SYMBOLIC(SG_INFO_INDIRECT_IO) +#define SG_INFO_MIXED_IO SYMBOLIC(SG_INFO_MIXED_IO) +#define SG_INFO_OK SYMBOLIC(SG_INFO_OK) +#define SG_INFO_OK_MASK SYMBOLIC(SG_INFO_OK_MASK) +#define SG_IO SYMBOLIC(SG_IO) +#define SG_MAX_QUEUE SYMBOLIC(SG_MAX_QUEUE) +#define SG_MAX_SENSE SYMBOLIC(SG_MAX_SENSE) +#define SG_NEXT_CMD_LEN SYMBOLIC(SG_NEXT_CMD_LEN) +#define SG_SCATTER_SZ SYMBOLIC(SG_SCATTER_SZ) +#define SG_SCSI_RESET SYMBOLIC(SG_SCSI_RESET) +#define SG_SCSI_RESET_BUS SYMBOLIC(SG_SCSI_RESET_BUS) +#define SG_SCSI_RESET_DEVICE SYMBOLIC(SG_SCSI_RESET_DEVICE) +#define SG_SCSI_RESET_HOST SYMBOLIC(SG_SCSI_RESET_HOST) +#define SG_SCSI_RESET_NOTHING SYMBOLIC(SG_SCSI_RESET_NOTHING) +#define SG_SET_COMMAND_Q SYMBOLIC(SG_SET_COMMAND_Q) +#define SG_SET_DEBUG SYMBOLIC(SG_SET_DEBUG) +#define SG_SET_FORCE_LOW_DMA SYMBOLIC(SG_SET_FORCE_LOW_DMA) +#define SG_SET_FORCE_PACK_ID SYMBOLIC(SG_SET_FORCE_PACK_ID) +#define SG_SET_KEEP_ORPHAN SYMBOLIC(SG_SET_KEEP_ORPHAN) +#define SG_SET_RESERVED_SIZE SYMBOLIC(SG_SET_RESERVED_SIZE) +#define SG_SET_TIMEOUT SYMBOLIC(SG_SET_TIMEOUT) +#define SG_SET_TRANSFORM SYMBOLIC(SG_SET_TRANSFORM) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long SG_BIG_BUFF; +hidden extern const long SG_DEFAULT_RETRIES; +hidden extern const long SG_DEFAULT_TIMEOUT; +hidden extern const long SG_DEF_COMMAND_Q; +hidden extern const long SG_DEF_FORCE_LOW_DMA; +hidden extern const long SG_DEF_FORCE_PACK_ID; +hidden extern const long SG_DEF_KEEP_ORPHAN; +hidden extern const long SG_DEF_RESERVED_SIZE; +hidden extern const long SG_DEF_UNDERRUN_FLAG; +hidden extern const long SG_DXFER_FROM_DEV; +hidden extern const long SG_DXFER_NONE; +hidden extern const long SG_DXFER_TO_DEV; +hidden extern const long SG_DXFER_TO_FROM_DEV; +hidden extern const long SG_EMULATED_HOST; +hidden extern const long SG_FLAG_DIRECT_IO; +hidden extern const long SG_FLAG_LUN_INHIBIT; +hidden extern const long SG_FLAG_NO_DXFER; +hidden extern const long SG_GET_COMMAND_Q; +hidden extern const long SG_GET_KEEP_ORPHAN; +hidden extern const long SG_GET_LOW_DMA; +hidden extern const long SG_GET_NUM_WAITING; +hidden extern const long SG_GET_PACK_ID; +hidden extern const long SG_GET_REQUEST_TABLE; +hidden extern const long SG_GET_RESERVED_SIZE; +hidden extern const long SG_GET_SCSI_ID; +hidden extern const long SG_GET_SG_TABLESIZE; +hidden extern const long SG_GET_TIMEOUT; +hidden extern const long SG_GET_TRANSFORM; +hidden extern const long SG_GET_VERSION_NUM; +hidden extern const long SG_INFO_CHECK; +hidden extern const long SG_INFO_DIRECT_IO; +hidden extern const long SG_INFO_DIRECT_IO_MASK; +hidden extern const long SG_INFO_INDIRECT_IO; +hidden extern const long SG_INFO_MIXED_IO; +hidden extern const long SG_INFO_OK; +hidden extern const long SG_INFO_OK_MASK; +hidden extern const long SG_IO; +hidden extern const long SG_MAX_QUEUE; +hidden extern const long SG_MAX_SENSE; +hidden extern const long SG_NEXT_CMD_LEN; +hidden extern const long SG_SCATTER_SZ; +hidden extern const long SG_SCSI_RESET; +hidden extern const long SG_SCSI_RESET_BUS; +hidden extern const long SG_SCSI_RESET_DEVICE; +hidden extern const long SG_SCSI_RESET_HOST; +hidden extern const long SG_SCSI_RESET_NOTHING; +hidden extern const long SG_SET_COMMAND_Q; +hidden extern const long SG_SET_DEBUG; +hidden extern const long SG_SET_FORCE_LOW_DMA; +hidden extern const long SG_SET_FORCE_PACK_ID; +hidden extern const long SG_SET_KEEP_ORPHAN; +hidden extern const long SG_SET_RESERVED_SIZE; +hidden extern const long SG_SET_TIMEOUT; +hidden extern const long SG_SET_TRANSFORM; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SG_H_ */ diff --git a/libc/sysv/consts/shm.h b/libc/sysv/consts/shm.h new file mode 100644 index 00000000..eb681ca0 --- /dev/null +++ b/libc/sysv/consts/shm.h @@ -0,0 +1,40 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SHM_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SHM_H_ +#include "libc/runtime/symbolic.h" + +#define SHM_DEST SYMBOLIC(SHM_DEST) +#define SHM_EXEC SYMBOLIC(SHM_EXEC) +#define SHM_HUGETLB SYMBOLIC(SHM_HUGETLB) +#define SHM_INFO SYMBOLIC(SHM_INFO) +#define SHM_LOCK SYMBOLIC(SHM_LOCK) +#define SHM_LOCKED SYMBOLIC(SHM_LOCKED) +#define SHM_NORESERVE SYMBOLIC(SHM_NORESERVE) +#define SHM_R SYMBOLIC(SHM_R) +#define SHM_RDONLY SYMBOLIC(SHM_RDONLY) +#define SHM_REMAP SYMBOLIC(SHM_REMAP) +#define SHM_RND SYMBOLIC(SHM_RND) +#define SHM_STAT SYMBOLIC(SHM_STAT) +#define SHM_UNLOCK SYMBOLIC(SHM_UNLOCK) +#define SHM_W SYMBOLIC(SHM_W) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long SHM_DEST; +hidden extern const long SHM_EXEC; +hidden extern const long SHM_HUGETLB; +hidden extern const long SHM_INFO; +hidden extern const long SHM_LOCK; +hidden extern const long SHM_LOCKED; +hidden extern const long SHM_NORESERVE; +hidden extern const long SHM_R; +hidden extern const long SHM_RDONLY; +hidden extern const long SHM_REMAP; +hidden extern const long SHM_RND; +hidden extern const long SHM_STAT; +hidden extern const long SHM_UNLOCK; +hidden extern const long SHM_W; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SHM_H_ */ diff --git a/libc/sysv/consts/shut.h b/libc/sysv/consts/shut.h new file mode 100644 index 00000000..3989f6e2 --- /dev/null +++ b/libc/sysv/consts/shut.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SHUT_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SHUT_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long SHUT_RD; +hidden extern const long SHUT_RDWR; +hidden extern const long SHUT_WR; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define SHUT_RD LITERALLY(0) +#define SHUT_RDWR LITERALLY(2) +#define SHUT_WR LITERALLY(1) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SHUT_H_ */ diff --git a/libc/sysv/consts/sig.h b/libc/sysv/consts/sig.h new file mode 100644 index 00000000..7053fa7c --- /dev/null +++ b/libc/sysv/consts/sig.h @@ -0,0 +1,96 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SIG_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SIG_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long SIGABRT; +hidden extern const long SIGALRM; +hidden extern const long SIGBUS; +hidden extern const long SIGCHLD; +hidden extern const long SIGCONT; +hidden extern const long SIGFPE; +hidden extern const long SIGHUP; +hidden extern const long SIGILL; +hidden extern const long SIGINT; +hidden extern const long SIGIO; +hidden extern const long SIGIOT; +hidden extern const long SIGKILL; +hidden extern const long SIGPIPE; +hidden extern const long SIGPOLL; +hidden extern const long SIGPROF; +hidden extern const long SIGPWR; +hidden extern const long SIGQUIT; +hidden extern const long SIGRTMAX; +hidden extern const long SIGRTMIN; +hidden extern const long SIGSEGV; +hidden extern const long SIGSTKFLT; +hidden extern const long SIGSTKSZ; +hidden extern const long SIGSTOP; +hidden extern const long SIGSYS; +hidden extern const long SIGTERM; +hidden extern const long SIGTRAP; +hidden extern const long SIGTSTP; +hidden extern const long SIGTTIN; +hidden extern const long SIGTTOU; +hidden extern const long SIGUNUSED; +hidden extern const long SIGURG; +hidden extern const long SIGUSR1; +hidden extern const long SIGUSR2; +hidden extern const long SIGVTALRM; +hidden extern const long SIGWINCH; +hidden extern const long SIGXCPU; +hidden extern const long SIGXFSZ; + +hidden extern const long SIG_ATOMIC_MIN; +hidden extern const long SIG_BLOCK; +hidden extern const long SIG_SETMASK; +hidden extern const long SIG_UNBLOCK; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define SIGABRT LITERALLY(6) +#define SIGALRM LITERALLY(14) +#define SIGBUS SYMBOLIC(SIGBUS) +#define SIGCHLD SYMBOLIC(SIGCHLD) +#define SIGCONT SYMBOLIC(SIGCONT) +#define SIGFPE LITERALLY(8) +#define SIGHUP LITERALLY(1) +#define SIGILL LITERALLY(4) +#define SIGINT LITERALLY(2) +#define SIGIO SYMBOLIC(SIGIO) +#define SIGIOT LITERALLY(6) +#define SIGKILL LITERALLY(9) +#define SIGPIPE LITERALLY(13) +#define SIGPOLL SYMBOLIC(SIGPOLL) +#define SIGPROF LITERALLY(27) +#define SIGPWR SYMBOLIC(SIGPWR) +#define SIGQUIT LITERALLY(3) +#define SIGRTMAX SYMBOLIC(SIGRTMAX) +#define SIGRTMIN SYMBOLIC(SIGRTMIN) +#define SIGSEGV LITERALLY(11) +#define SIGSTKFLT SYMBOLIC(SIGSTKFLT) +#define SIGSTKSZ SYMBOLIC(SIGSTKSZ) +#define SIGSTOP SYMBOLIC(SIGSTOP) +#define SIGSYS SYMBOLIC(SIGSYS) +#define SIGTERM LITERALLY(15) +#define SIGTRAP LITERALLY(5) +#define SIGTSTP SYMBOLIC(SIGTSTP) +#define SIGTTIN LITERALLY(21) +#define SIGTTOU LITERALLY(22) +#define SIGUNUSED SYMBOLIC(SIGUNUSED) +#define SIGURG SYMBOLIC(SIGURG) +#define SIGUSR1 SYMBOLIC(SIGUSR1) +#define SIGUSR2 SYMBOLIC(SIGUSR2) +#define SIGVTALRM LITERALLY(26) +#define SIGWINCH LITERALLY(28) +#define SIGXCPU LITERALLY(24) +#define SIGXFSZ LITERALLY(25) + +#define SIG_ATOMIC_MIN SYMBOLIC(SIG_ATOMIC_MIN) +#define SIG_BLOCK SYMBOLIC(SIG_BLOCK) +#define SIG_SETMASK SYMBOLIC(SIG_SETMASK) +#define SIG_UNBLOCK SYMBOLIC(SIG_UNBLOCK) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SIG_H_ */ diff --git a/libc/sysv/consts/sigpoll.h b/libc/sysv/consts/sigpoll.h new file mode 100644 index 00000000..cfbf1847 --- /dev/null +++ b/libc/sysv/consts/sigpoll.h @@ -0,0 +1,24 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_POLL_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_POLL_H_ +#include "libc/runtime/symbolic.h" + +#define POLL_ERR SYMBOLIC(POLL_ERR) +#define POLL_HUP SYMBOLIC(POLL_HUP) +#define POLL_IN SYMBOLIC(POLL_IN) +#define POLL_MSG SYMBOLIC(POLL_MSG) +#define POLL_OUT SYMBOLIC(POLL_OUT) +#define POLL_PRI SYMBOLIC(POLL_PRI) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long POLL_ERR; +hidden extern const long POLL_HUP; +hidden extern const long POLL_IN; +hidden extern const long POLL_MSG; +hidden extern const long POLL_OUT; +hidden extern const long POLL_PRI; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_POLL_H_ */ diff --git a/libc/sysv/consts/sio.h b/libc/sysv/consts/sio.h new file mode 100644 index 00000000..b4af7121 --- /dev/null +++ b/libc/sysv/consts/sio.h @@ -0,0 +1,130 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SIO_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SIO_H_ +#include "libc/runtime/symbolic.h" + +#define SIOCADDDLCI SYMBOLIC(SIOCADDDLCI) +#define SIOCADDMULTI SYMBOLIC(SIOCADDMULTI) +#define SIOCADDRT SYMBOLIC(SIOCADDRT) +#define SIOCATMARK SYMBOLIC(SIOCATMARK) +#define SIOCDARP SYMBOLIC(SIOCDARP) +#define SIOCDELDLCI SYMBOLIC(SIOCDELDLCI) +#define SIOCDELMULTI SYMBOLIC(SIOCDELMULTI) +#define SIOCDELRT SYMBOLIC(SIOCDELRT) +#define SIOCDEVPRIVATE SYMBOLIC(SIOCDEVPRIVATE) +#define SIOCDIFADDR SYMBOLIC(SIOCDIFADDR) +#define SIOCDRARP SYMBOLIC(SIOCDRARP) +#define SIOCGARP SYMBOLIC(SIOCGARP) +#define SIOCGIFADDR SYMBOLIC(SIOCGIFADDR) +#define SIOCGIFBR SYMBOLIC(SIOCGIFBR) +#define SIOCGIFBRDADDR SYMBOLIC(SIOCGIFBRDADDR) +#define SIOCGIFCONF SYMBOLIC(SIOCGIFCONF) +#define SIOCGIFCOUNT SYMBOLIC(SIOCGIFCOUNT) +#define SIOCGIFDSTADDR SYMBOLIC(SIOCGIFDSTADDR) +#define SIOCGIFENCAP SYMBOLIC(SIOCGIFENCAP) +#define SIOCGIFFLAGS SYMBOLIC(SIOCGIFFLAGS) +#define SIOCGIFHWADDR SYMBOLIC(SIOCGIFHWADDR) +#define SIOCGIFINDEX SYMBOLIC(SIOCGIFINDEX) +#define SIOCGIFMAP SYMBOLIC(SIOCGIFMAP) +#define SIOCGIFMEM SYMBOLIC(SIOCGIFMEM) +#define SIOCGIFMETRIC SYMBOLIC(SIOCGIFMETRIC) +#define SIOCGIFMTU SYMBOLIC(SIOCGIFMTU) +#define SIOCGIFNAME SYMBOLIC(SIOCGIFNAME) +#define SIOCGIFNETMASK SYMBOLIC(SIOCGIFNETMASK) +#define SIOCGIFPFLAGS SYMBOLIC(SIOCGIFPFLAGS) +#define SIOCGIFSLAVE SYMBOLIC(SIOCGIFSLAVE) +#define SIOCGIFTXQLEN SYMBOLIC(SIOCGIFTXQLEN) +#define SIOCGPGRP SYMBOLIC(SIOCGPGRP) +#define SIOCGRARP SYMBOLIC(SIOCGRARP) +#define SIOCGSTAMP SYMBOLIC(SIOCGSTAMP) +#define SIOCGSTAMPNS SYMBOLIC(SIOCGSTAMPNS) +#define SIOCPROTOPRIVATE SYMBOLIC(SIOCPROTOPRIVATE) +#define SIOCRTMSG SYMBOLIC(SIOCRTMSG) +#define SIOCSARP SYMBOLIC(SIOCSARP) +#define SIOCSIFADDR SYMBOLIC(SIOCSIFADDR) +#define SIOCSIFBR SYMBOLIC(SIOCSIFBR) +#define SIOCSIFBRDADDR SYMBOLIC(SIOCSIFBRDADDR) +#define SIOCSIFDSTADDR SYMBOLIC(SIOCSIFDSTADDR) +#define SIOCSIFENCAP SYMBOLIC(SIOCSIFENCAP) +#define SIOCSIFFLAGS SYMBOLIC(SIOCSIFFLAGS) +#define SIOCSIFHWADDR SYMBOLIC(SIOCSIFHWADDR) +#define SIOCSIFHWBROADCAST SYMBOLIC(SIOCSIFHWBROADCAST) +#define SIOCSIFLINK SYMBOLIC(SIOCSIFLINK) +#define SIOCSIFMAP SYMBOLIC(SIOCSIFMAP) +#define SIOCSIFMEM SYMBOLIC(SIOCSIFMEM) +#define SIOCSIFMETRIC SYMBOLIC(SIOCSIFMETRIC) +#define SIOCSIFMTU SYMBOLIC(SIOCSIFMTU) +#define SIOCSIFNAME SYMBOLIC(SIOCSIFNAME) +#define SIOCSIFNETMASK SYMBOLIC(SIOCSIFNETMASK) +#define SIOCSIFPFLAGS SYMBOLIC(SIOCSIFPFLAGS) +#define SIOCSIFSLAVE SYMBOLIC(SIOCSIFSLAVE) +#define SIOCSIFTXQLEN SYMBOLIC(SIOCSIFTXQLEN) +#define SIOCSPGRP SYMBOLIC(SIOCSPGRP) +#define SIOCSRARP SYMBOLIC(SIOCSRARP) +#define SIOGIFINDEX SYMBOLIC(SIOGIFINDEX) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long SIOCADDDLCI; +hidden extern const long SIOCADDMULTI; +hidden extern const long SIOCADDRT; +hidden extern const long SIOCATMARK; +hidden extern const long SIOCDARP; +hidden extern const long SIOCDELDLCI; +hidden extern const long SIOCDELMULTI; +hidden extern const long SIOCDELRT; +hidden extern const long SIOCDEVPRIVATE; +hidden extern const long SIOCDIFADDR; +hidden extern const long SIOCDRARP; +hidden extern const long SIOCGARP; +hidden extern const long SIOCGIFADDR; +hidden extern const long SIOCGIFBR; +hidden extern const long SIOCGIFBRDADDR; +hidden extern const long SIOCGIFCONF; +hidden extern const long SIOCGIFCOUNT; +hidden extern const long SIOCGIFDSTADDR; +hidden extern const long SIOCGIFENCAP; +hidden extern const long SIOCGIFFLAGS; +hidden extern const long SIOCGIFHWADDR; +hidden extern const long SIOCGIFINDEX; +hidden extern const long SIOCGIFMAP; +hidden extern const long SIOCGIFMEM; +hidden extern const long SIOCGIFMETRIC; +hidden extern const long SIOCGIFMTU; +hidden extern const long SIOCGIFNAME; +hidden extern const long SIOCGIFNETMASK; +hidden extern const long SIOCGIFPFLAGS; +hidden extern const long SIOCGIFSLAVE; +hidden extern const long SIOCGIFTXQLEN; +hidden extern const long SIOCGPGRP; +hidden extern const long SIOCGRARP; +hidden extern const long SIOCGSTAMP; +hidden extern const long SIOCGSTAMPNS; +hidden extern const long SIOCPROTOPRIVATE; +hidden extern const long SIOCRTMSG; +hidden extern const long SIOCSARP; +hidden extern const long SIOCSIFADDR; +hidden extern const long SIOCSIFBR; +hidden extern const long SIOCSIFBRDADDR; +hidden extern const long SIOCSIFDSTADDR; +hidden extern const long SIOCSIFENCAP; +hidden extern const long SIOCSIFFLAGS; +hidden extern const long SIOCSIFHWADDR; +hidden extern const long SIOCSIFHWBROADCAST; +hidden extern const long SIOCSIFLINK; +hidden extern const long SIOCSIFMAP; +hidden extern const long SIOCSIFMEM; +hidden extern const long SIOCSIFMETRIC; +hidden extern const long SIOCSIFMTU; +hidden extern const long SIOCSIFNAME; +hidden extern const long SIOCSIFNETMASK; +hidden extern const long SIOCSIFPFLAGS; +hidden extern const long SIOCSIFSLAVE; +hidden extern const long SIOCSIFTXQLEN; +hidden extern const long SIOCSPGRP; +hidden extern const long SIOCSRARP; +hidden extern const long SIOGIFINDEX; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SIO_H_ */ diff --git a/libc/sysv/consts/so.h b/libc/sysv/consts/so.h new file mode 100644 index 00000000..92449199 --- /dev/null +++ b/libc/sysv/consts/so.h @@ -0,0 +1,124 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SO_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SO_H_ +#include "libc/runtime/symbolic.h" + +#define SO_ACCEPTCONN SYMBOLIC(SO_ACCEPTCONN) +#define SO_ATTACH_BPF SYMBOLIC(SO_ATTACH_BPF) +#define SO_ATTACH_FILTER SYMBOLIC(SO_ATTACH_FILTER) +#define SO_ATTACH_REUSEPORT_CBPF SYMBOLIC(SO_ATTACH_REUSEPORT_CBPF) +#define SO_ATTACH_REUSEPORT_EBPF SYMBOLIC(SO_ATTACH_REUSEPORT_EBPF) +#define SO_BINDTODEVICE SYMBOLIC(SO_BINDTODEVICE) +#define SO_BPF_EXTENSIONS SYMBOLIC(SO_BPF_EXTENSIONS) +#define SO_BROADCAST SYMBOLIC(SO_BROADCAST) +#define SO_BSDCOMPAT SYMBOLIC(SO_BSDCOMPAT) +#define SO_BUSY_POLL SYMBOLIC(SO_BUSY_POLL) +#define SO_CNX_ADVICE SYMBOLIC(SO_CNX_ADVICE) +#define SO_DEBUG SYMBOLIC(SO_DEBUG) +#define SO_DETACH_BPF SYMBOLIC(SO_DETACH_BPF) +#define SO_DETACH_FILTER SYMBOLIC(SO_DETACH_FILTER) +#define SO_DOMAIN SYMBOLIC(SO_DOMAIN) +#define SO_DONTROUTE SYMBOLIC(SO_DONTROUTE) +#define SO_ERROR SYMBOLIC(SO_ERROR) +#define SO_EXCLUSIVEADDRUSE SYMBOLIC(SO_EXCLUSIVEADDRUSE) +#define SO_GET_FILTER SYMBOLIC(SO_GET_FILTER) +#define SO_INCOMING_CPU SYMBOLIC(SO_INCOMING_CPU) +#define SO_KEEPALIVE SYMBOLIC(SO_KEEPALIVE) +#define SO_LINGER SYMBOLIC(SO_LINGER) +#define SO_LOCK_FILTER SYMBOLIC(SO_LOCK_FILTER) +#define SO_MARK SYMBOLIC(SO_MARK) +#define SO_MAX_PACING_RATE SYMBOLIC(SO_MAX_PACING_RATE) +#define SO_NOFCS SYMBOLIC(SO_NOFCS) +#define SO_NO_CHECK SYMBOLIC(SO_NO_CHECK) +#define SO_OOBINLINE SYMBOLIC(SO_OOBINLINE) +#define SO_PASSCRED SYMBOLIC(SO_PASSCRED) +#define SO_PASSSEC SYMBOLIC(SO_PASSSEC) +#define SO_PEEK_OFF SYMBOLIC(SO_PEEK_OFF) +#define SO_PEERCRED SYMBOLIC(SO_PEERCRED) +#define SO_PEERNAME SYMBOLIC(SO_PEERNAME) +#define SO_PEERSEC SYMBOLIC(SO_PEERSEC) +#define SO_PRIORITY SYMBOLIC(SO_PRIORITY) +#define SO_PROTOCOL SYMBOLIC(SO_PROTOCOL) +#define SO_RCVBUF SYMBOLIC(SO_RCVBUF) +#define SO_RCVBUFFORCE SYMBOLIC(SO_RCVBUFFORCE) +#define SO_RCVLOWAT SYMBOLIC(SO_RCVLOWAT) +#define SO_RCVTIMEO SYMBOLIC(SO_RCVTIMEO) +#define SO_REUSEADDR SYMBOLIC(SO_REUSEADDR) +#define SO_REUSEPORT SYMBOLIC(SO_REUSEPORT) +#define SO_RXQ_OVFL SYMBOLIC(SO_RXQ_OVFL) +#define SO_SECURITY_AUTHENTICATION SYMBOLIC(SO_SECURITY_AUTHENTICATION) +#define SO_SECURITY_ENCRYPTION_NETWORK SYMBOLIC(SO_SECURITY_ENCRYPTION_NETWORK) +#define SO_SECURITY_ENCRYPTION_TRANSPORT SYMBOLIC(SO_SECURITY_ENCRYPTION_TRANSPORT) +#define SO_SELECT_ERR_QUEUE SYMBOLIC(SO_SELECT_ERR_QUEUE) +#define SO_SNDBUF SYMBOLIC(SO_SNDBUF) +#define SO_SNDBUFFORCE SYMBOLIC(SO_SNDBUFFORCE) +#define SO_SNDLOWAT SYMBOLIC(SO_SNDLOWAT) +#define SO_SNDTIMEO SYMBOLIC(SO_SNDTIMEO) +#define SO_TIMESTAMP SYMBOLIC(SO_TIMESTAMP) +#define SO_TIMESTAMPING SYMBOLIC(SO_TIMESTAMPING) +#define SO_TIMESTAMPNS SYMBOLIC(SO_TIMESTAMPNS) +#define SO_TYPE SYMBOLIC(SO_TYPE) +#define SO_WIFI_STATUS SYMBOLIC(SO_WIFI_STATUS) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long SO_ACCEPTCONN; +hidden extern const long SO_ATTACH_BPF; +hidden extern const long SO_ATTACH_FILTER; +hidden extern const long SO_ATTACH_REUSEPORT_CBPF; +hidden extern const long SO_ATTACH_REUSEPORT_EBPF; +hidden extern const long SO_BINDTODEVICE; +hidden extern const long SO_BPF_EXTENSIONS; +hidden extern const long SO_BROADCAST; +hidden extern const long SO_BSDCOMPAT; +hidden extern const long SO_BUSY_POLL; +hidden extern const long SO_CNX_ADVICE; +hidden extern const long SO_DEBUG; +hidden extern const long SO_DETACH_BPF; +hidden extern const long SO_DETACH_FILTER; +hidden extern const long SO_DOMAIN; +hidden extern const long SO_DONTROUTE; +hidden extern const long SO_ERROR; +hidden extern const long SO_EXCLUSIVEADDRUSE; +hidden extern const long SO_GET_FILTER; +hidden extern const long SO_INCOMING_CPU; +hidden extern const long SO_KEEPALIVE; +hidden extern const long SO_LINGER; +hidden extern const long SO_LOCK_FILTER; +hidden extern const long SO_MARK; +hidden extern const long SO_MAX_PACING_RATE; +hidden extern const long SO_NOFCS; +hidden extern const long SO_NO_CHECK; +hidden extern const long SO_OOBINLINE; +hidden extern const long SO_PASSCRED; +hidden extern const long SO_PASSSEC; +hidden extern const long SO_PEEK_OFF; +hidden extern const long SO_PEERCRED; +hidden extern const long SO_PEERNAME; +hidden extern const long SO_PEERSEC; +hidden extern const long SO_PRIORITY; +hidden extern const long SO_PROTOCOL; +hidden extern const long SO_RCVBUF; +hidden extern const long SO_RCVBUFFORCE; +hidden extern const long SO_RCVLOWAT; +hidden extern const long SO_RCVTIMEO; +hidden extern const long SO_REUSEADDR; +hidden extern const long SO_REUSEPORT; +hidden extern const long SO_RXQ_OVFL; +hidden extern const long SO_SECURITY_AUTHENTICATION; +hidden extern const long SO_SECURITY_ENCRYPTION_NETWORK; +hidden extern const long SO_SECURITY_ENCRYPTION_TRANSPORT; +hidden extern const long SO_SELECT_ERR_QUEUE; +hidden extern const long SO_SNDBUF; +hidden extern const long SO_SNDBUFFORCE; +hidden extern const long SO_SNDLOWAT; +hidden extern const long SO_SNDTIMEO; +hidden extern const long SO_TIMESTAMP; +hidden extern const long SO_TIMESTAMPING; +hidden extern const long SO_TIMESTAMPNS; +hidden extern const long SO_TYPE; +hidden extern const long SO_WIFI_STATUS; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SO_H_ */ diff --git a/libc/sysv/consts/sock.h b/libc/sysv/consts/sock.h new file mode 100644 index 00000000..14e2cd0d --- /dev/null +++ b/libc/sysv/consts/sock.h @@ -0,0 +1,30 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SOCK_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SOCK_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long SOCK_CLOEXEC; +hidden extern const long SOCK_DCCP; +hidden extern const long SOCK_DGRAM; +hidden extern const long SOCK_NONBLOCK; +hidden extern const long SOCK_PACKET; +hidden extern const long SOCK_RAW; +hidden extern const long SOCK_RDM; +hidden extern const long SOCK_SEQPACKET; +hidden extern const long SOCK_STREAM; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define SOCK_CLOEXEC SYMBOLIC(SOCK_CLOEXEC) +#define SOCK_DCCP SYMBOLIC(SOCK_DCCP) +#define SOCK_DGRAM LITERALLY(2) +#define SOCK_NONBLOCK SYMBOLIC(SOCK_NONBLOCK) +#define SOCK_PACKET SYMBOLIC(SOCK_PACKET) +#define SOCK_RAW LITERALLY(3) +#define SOCK_RDM LITERALLY(4) +#define SOCK_SEQPACKET LITERALLY(5) +#define SOCK_STREAM LITERALLY(1) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SOCK_H_ */ diff --git a/libc/sysv/consts/sol.h b/libc/sysv/consts/sol.h new file mode 100644 index 00000000..c31b166a --- /dev/null +++ b/libc/sysv/consts/sol.h @@ -0,0 +1,68 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SOL_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SOL_H_ +#include "libc/runtime/symbolic.h" + +#define SOL_AAL SYMBOLIC(SOL_AAL) +#define SOL_ALG SYMBOLIC(SOL_ALG) +#define SOL_ATM SYMBOLIC(SOL_ATM) +#define SOL_BLUETOOTH SYMBOLIC(SOL_BLUETOOTH) +#define SOL_CAIF SYMBOLIC(SOL_CAIF) +#define SOL_DCCP SYMBOLIC(SOL_DCCP) +#define SOL_DECNET SYMBOLIC(SOL_DECNET) +#define SOL_ICMPV6 SYMBOLIC(SOL_ICMPV6) +#define SOL_IP SYMBOLIC(SOL_IP) +#define SOL_IPV6 SYMBOLIC(SOL_IPV6) +#define SOL_IRDA SYMBOLIC(SOL_IRDA) +#define SOL_IUCV SYMBOLIC(SOL_IUCV) +#define SOL_KCM SYMBOLIC(SOL_KCM) +#define SOL_LLC SYMBOLIC(SOL_LLC) +#define SOL_NETBEUI SYMBOLIC(SOL_NETBEUI) +#define SOL_NETLINK SYMBOLIC(SOL_NETLINK) +#define SOL_NFC SYMBOLIC(SOL_NFC) +#define SOL_PACKET SYMBOLIC(SOL_PACKET) +#define SOL_PNPIPE SYMBOLIC(SOL_PNPIPE) +#define SOL_PPPOL2TP SYMBOLIC(SOL_PPPOL2TP) +#define SOL_RAW SYMBOLIC(SOL_RAW) +#define SOL_RDS SYMBOLIC(SOL_RDS) +#define SOL_RXRPC SYMBOLIC(SOL_RXRPC) +#define SOL_SOCKET SYMBOLIC(SOL_SOCKET) +#define SOL_TCP SYMBOLIC(SOL_TCP) +#define SOL_TIPC SYMBOLIC(SOL_TIPC) +#define SOL_UDP SYMBOLIC(SOL_UDP) +#define SOL_X25 SYMBOLIC(SOL_X25) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long SOL_AAL; +hidden extern const long SOL_ALG; +hidden extern const long SOL_ATM; +hidden extern const long SOL_BLUETOOTH; +hidden extern const long SOL_CAIF; +hidden extern const long SOL_DCCP; +hidden extern const long SOL_DECNET; +hidden extern const long SOL_ICMPV6; +hidden extern const long SOL_IP; +hidden extern const long SOL_IPV6; +hidden extern const long SOL_IRDA; +hidden extern const long SOL_IUCV; +hidden extern const long SOL_KCM; +hidden extern const long SOL_LLC; +hidden extern const long SOL_NETBEUI; +hidden extern const long SOL_NETLINK; +hidden extern const long SOL_NFC; +hidden extern const long SOL_PACKET; +hidden extern const long SOL_PNPIPE; +hidden extern const long SOL_PPPOL2TP; +hidden extern const long SOL_RAW; +hidden extern const long SOL_RDS; +hidden extern const long SOL_RXRPC; +hidden extern const long SOL_SOCKET; +hidden extern const long SOL_TCP; +hidden extern const long SOL_TIPC; +hidden extern const long SOL_UDP; +hidden extern const long SOL_X25; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SOL_H_ */ diff --git a/libc/sysv/consts/splice.h b/libc/sysv/consts/splice.h new file mode 100644 index 00000000..4f1c0756 --- /dev/null +++ b/libc/sysv/consts/splice.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SPLICE_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SPLICE_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long SPLICE_F_GIFT; +hidden extern const long SPLICE_F_MORE; +hidden extern const long SPLICE_F_MOVE; +hidden extern const long SPLICE_F_NONBLOCK; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define SPLICE_F_GIFT SYMBOLIC(SPLICE_F_GIFT) +#define SPLICE_F_MORE SYMBOLIC(SPLICE_F_MORE) +#define SPLICE_F_MOVE SYMBOLIC(SPLICE_F_MOVE) +#define SPLICE_F_NONBLOCK SYMBOLIC(SPLICE_F_NONBLOCK) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SPLICE_H_ */ diff --git a/libc/sysv/consts/st.h b/libc/sysv/consts/st.h new file mode 100644 index 00000000..751ebec0 --- /dev/null +++ b/libc/sysv/consts/st.h @@ -0,0 +1,36 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_ST_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_ST_H_ +#include "libc/runtime/symbolic.h" + +#define ST_APPEND SYMBOLIC(ST_APPEND) +#define ST_IMMUTABLE SYMBOLIC(ST_IMMUTABLE) +#define ST_MANDLOCK SYMBOLIC(ST_MANDLOCK) +#define ST_NOATIME SYMBOLIC(ST_NOATIME) +#define ST_NODEV SYMBOLIC(ST_NODEV) +#define ST_NODIRATIME SYMBOLIC(ST_NODIRATIME) +#define ST_NOEXEC SYMBOLIC(ST_NOEXEC) +#define ST_NOSUID SYMBOLIC(ST_NOSUID) +#define ST_RDONLY SYMBOLIC(ST_RDONLY) +#define ST_RELATIME SYMBOLIC(ST_RELATIME) +#define ST_SYNCHRONOUS SYMBOLIC(ST_SYNCHRONOUS) +#define ST_WRITE SYMBOLIC(ST_WRITE) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long ST_APPEND; +hidden extern const long ST_IMMUTABLE; +hidden extern const long ST_MANDLOCK; +hidden extern const long ST_NOATIME; +hidden extern const long ST_NODEV; +hidden extern const long ST_NODIRATIME; +hidden extern const long ST_NOEXEC; +hidden extern const long ST_NOSUID; +hidden extern const long ST_RDONLY; +hidden extern const long ST_RELATIME; +hidden extern const long ST_SYNCHRONOUS; +hidden extern const long ST_WRITE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_ST_H_ */ diff --git a/libc/sysv/consts/syscon.inc b/libc/sysv/consts/syscon.inc new file mode 100644 index 00000000..1c9f3947 --- /dev/null +++ b/libc/sysv/consts/syscon.inc @@ -0,0 +1,44 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +/* clang-format off */ +.include "libc/macros.inc" + +.macro .syscon group:req name:req linux:req xnu:req freebsd:req openbsd:req windows:req + yoink _init_systemfive + .section .piro.bss.sort.syscon.2.\group\().\name,"aw",@nobits +\name: .quad 0 + .endobj \name,globl,hidden + .previous + .section .sort.rodata.syscon.linux.2.\group\().\name,"a",@progbits + .sleb128 \linux + .previous + .section .sort.rodata.syscon.xnu.2.\group\().\name,"a",@progbits + .sleb128 \xnu + .previous + .section .sort.rodata.syscon.freebsd.2.\group\().\name,"a",@progbits + .sleb128 \freebsd + .previous + .section .sort.rodata.syscon.openbsd.2.\group\().\name,"a",@progbits + .sleb128 \openbsd + .previous + .section .sort.rodata.syscon.windows.2.\group\().\name,"a",@progbits + .sleb128 \windows + .previous +.endm diff --git a/libc/sysv/consts/tcp.h b/libc/sysv/consts/tcp.h new file mode 100644 index 00000000..a70b05fa --- /dev/null +++ b/libc/sysv/consts/tcp.h @@ -0,0 +1,70 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_TCP_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_TCP_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long TCP_CC_INFO; +hidden extern const long TCP_CONGESTION; +hidden extern const long TCP_COOKIE_TRANSACTIONS; +hidden extern const long TCP_CORK; +hidden extern const long TCP_DEFER_ACCEPT; +hidden extern const long TCP_FASTOPEN; +hidden extern const long TCP_INFO; +hidden extern const long TCP_KEEPCNT; +hidden extern const long TCP_KEEPIDLE; +hidden extern const long TCP_KEEPINTVL; +hidden extern const long TCP_LINGER2; +hidden extern const long TCP_MAXSEG; +hidden extern const long TCP_MD5SIG; +hidden extern const long TCP_MD5SIG_MAXKEYLEN; +hidden extern const long TCP_NODELAY; +hidden extern const long TCP_NOTSENT_LOWAT; +hidden extern const long TCP_QUEUE_SEQ; +hidden extern const long TCP_QUICKACK; +hidden extern const long TCP_REPAIR; +hidden extern const long TCP_REPAIR_OPTIONS; +hidden extern const long TCP_REPAIR_QUEUE; +hidden extern const long TCP_SAVED_SYN; +hidden extern const long TCP_SAVE_SYN; +hidden extern const long TCP_SYNCNT; +hidden extern const long TCP_THIN_DUPACK; +hidden extern const long TCP_THIN_LINEAR_TIMEOUTS; +hidden extern const long TCP_TIMESTAMP; +hidden extern const long TCP_USER_TIMEOUT; +hidden extern const long TCP_WINDOW_CLAMP; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define TCP_CC_INFO SYMBOLIC(TCP_CC_INFO) +#define TCP_CONGESTION SYMBOLIC(TCP_CONGESTION) +#define TCP_COOKIE_TRANSACTIONS SYMBOLIC(TCP_COOKIE_TRANSACTIONS) +#define TCP_CORK SYMBOLIC(TCP_CORK) +#define TCP_DEFER_ACCEPT SYMBOLIC(TCP_DEFER_ACCEPT) +#define TCP_FASTOPEN SYMBOLIC(TCP_FASTOPEN) +#define TCP_INFO SYMBOLIC(TCP_INFO) +#define TCP_KEEPCNT SYMBOLIC(TCP_KEEPCNT) +#define TCP_KEEPIDLE SYMBOLIC(TCP_KEEPIDLE) +#define TCP_KEEPINTVL SYMBOLIC(TCP_KEEPINTVL) +#define TCP_LINGER2 SYMBOLIC(TCP_LINGER2) +#define TCP_MAXSEG SYMBOLIC(TCP_MAXSEG) +#define TCP_MD5SIG SYMBOLIC(TCP_MD5SIG) +#define TCP_MD5SIG_MAXKEYLEN SYMBOLIC(TCP_MD5SIG_MAXKEYLEN) +#define TCP_NODELAY LITERALLY(1) +#define TCP_NOTSENT_LOWAT SYMBOLIC(TCP_NOTSENT_LOWAT) +#define TCP_QUEUE_SEQ SYMBOLIC(TCP_QUEUE_SEQ) +#define TCP_QUICKACK SYMBOLIC(TCP_QUICKACK) +#define TCP_REPAIR SYMBOLIC(TCP_REPAIR) +#define TCP_REPAIR_OPTIONS SYMBOLIC(TCP_REPAIR_OPTIONS) +#define TCP_REPAIR_QUEUE SYMBOLIC(TCP_REPAIR_QUEUE) +#define TCP_SAVED_SYN SYMBOLIC(TCP_SAVED_SYN) +#define TCP_SAVE_SYN SYMBOLIC(TCP_SAVE_SYN) +#define TCP_SYNCNT SYMBOLIC(TCP_SYNCNT) +#define TCP_THIN_DUPACK SYMBOLIC(TCP_THIN_DUPACK) +#define TCP_THIN_LINEAR_TIMEOUTS SYMBOLIC(TCP_THIN_LINEAR_TIMEOUTS) +#define TCP_TIMESTAMP SYMBOLIC(TCP_TIMESTAMP) +#define TCP_USER_TIMEOUT SYMBOLIC(TCP_USER_TIMEOUT) +#define TCP_WINDOW_CLAMP SYMBOLIC(TCP_WINDOW_CLAMP) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_TCP_H_ */ diff --git a/libc/sysv/consts/tcpopt.h b/libc/sysv/consts/tcpopt.h new file mode 100644 index 00000000..14f259b6 --- /dev/null +++ b/libc/sysv/consts/tcpopt.h @@ -0,0 +1,26 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_TCPOPT_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_TCPOPT_H_ +#include "libc/runtime/symbolic.h" + +#define TCPOPT_EOL SYMBOLIC(TCPOPT_EOL) +#define TCPOPT_MAXSEG SYMBOLIC(TCPOPT_MAXSEG) +#define TCPOPT_NOP SYMBOLIC(TCPOPT_NOP) +#define TCPOPT_SACK SYMBOLIC(TCPOPT_SACK) +#define TCPOPT_SACK_PERMITTED SYMBOLIC(TCPOPT_SACK_PERMITTED) +#define TCPOPT_TIMESTAMP SYMBOLIC(TCPOPT_TIMESTAMP) +#define TCPOPT_WINDOW SYMBOLIC(TCPOPT_WINDOW) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long TCPOPT_EOL; +hidden extern const long TCPOPT_MAXSEG; +hidden extern const long TCPOPT_NOP; +hidden extern const long TCPOPT_SACK; +hidden extern const long TCPOPT_SACK_PERMITTED; +hidden extern const long TCPOPT_TIMESTAMP; +hidden extern const long TCPOPT_WINDOW; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_TCPOPT_H_ */ diff --git a/libc/sysv/consts/termios.h b/libc/sysv/consts/termios.h new file mode 100644 index 00000000..4016e14d --- /dev/null +++ b/libc/sysv/consts/termios.h @@ -0,0 +1,314 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_TERMIOS_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_TERMIOS_H_ +#include "libc/runtime/symbolic.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long BRKINT; +hidden extern const long BSDLY; +hidden extern const long BUSY; +hidden extern const long CANBSIZ; +hidden extern const long CBAUD; +hidden extern const long CBAUDEX; +hidden extern const long CBRK; +hidden extern const long CEOL; +hidden extern const long CIBAUD; +hidden extern const long CLOCAL; +hidden extern const long CMSPAR; +hidden extern const long CRDLY; +hidden extern const long CS6; +hidden extern const long CS7; +hidden extern const long CS8; +hidden extern const long CSIZE; +hidden extern const long ECHO; +hidden extern const long ECHOCTL; +hidden extern const long ECHOE; +hidden extern const long ECHOK; +hidden extern const long ECHOKE; +hidden extern const long ECHONL; +hidden extern const long ECHOPRT; +hidden extern const long ENDRUNDISC; +hidden extern const long EXTPROC; +hidden extern const long FFDLY; +hidden extern const long FLUSHO; +hidden extern const long H4DISC; +hidden extern const long ICANON; +hidden extern const long ICRNL; +hidden extern const long IEXTEN; +hidden extern const long IGNBRK; +hidden extern const long IGNCR; +hidden extern const long IGNPAR; +hidden extern const long IMAXBEL; +hidden extern const long INLCR; +hidden extern const long INPCK; +hidden extern const long ISIG; +hidden extern const long ISTRIP; +hidden extern const long IUCLC; +hidden extern const long IUTF8; +hidden extern const long IXANY; +hidden extern const long IXOFF; +hidden extern const long IXON; +hidden extern const long NCCS; +hidden extern const long NETGRAPHDISC; +hidden extern const long NLDLY; +hidden extern const long NMEADISC; +hidden extern const long NOFLSH; +hidden extern const long OCRNL; +hidden extern const long OFDEL; +hidden extern const long OFILL; +hidden extern const long OLCUC; +hidden extern const long ONLCR; +hidden extern const long ONLRET; +hidden extern const long ONOCR; +hidden extern const long OPOST; +hidden extern const long PARENB; +hidden extern const long PARMRK; +hidden extern const long PARODD; +hidden extern const long PENDIN; +hidden extern const long PPPDISC; +hidden extern const long SLIPDISC; +hidden extern const long STRIPDISC; +hidden extern const long TABDLY; +hidden extern const long TABLDISC; +hidden extern const long TCGETS; +hidden extern const long TCSADRAIN; +hidden extern const long TCSAFLUSH; +hidden extern const long TCSANOW; +hidden extern const long TCSETS; +hidden extern const long TCSETSF; +hidden extern const long TCSETSW; +hidden extern const long TIOCCBRK; +hidden extern const long TIOCCDTR; +hidden extern const long TIOCCHKVERAUTH; +hidden extern const long TIOCCONS; +hidden extern const long TIOCDRAIN; +hidden extern const long TIOCEXT; +hidden extern const long TIOCFLAG_CLOCAL; +hidden extern const long TIOCFLAG_MDMBUF; +hidden extern const long TIOCFLAG_PPS; +hidden extern const long TIOCFLAG_SOFTCAR; +hidden extern const long TIOCFLUSH; +hidden extern const long TIOCGDRAINWAIT; +hidden extern const long TIOCGETD; +hidden extern const long TIOCGFLAGS; +hidden extern const long TIOCGPGRP; +hidden extern const long TIOCGPTN; +hidden extern const long TIOCGSID; +hidden extern const long TIOCGTSTAMP; +hidden extern const long TIOCGWINSZ; +hidden extern const long TIOCNOTTY; +hidden extern const long TIOCNXCL; +hidden extern const long TIOCOUTQ; +hidden extern const long TIOCPTMASTER; +hidden extern const long TIOCREMOTE; +hidden extern const long TIOCSBRK; +hidden extern const long TIOCSCTTY; +hidden extern const long TIOCSDRAINWAIT; +hidden extern const long TIOCSDTR; +hidden extern const long TIOCSERGETLSR; +hidden extern const long TIOCSERGETMULTI; +hidden extern const long TIOCSERSETMULTI; +hidden extern const long TIOCSER_TEMT; +hidden extern const long TIOCSETD; +hidden extern const long TIOCSETVERAUTH; +hidden extern const long TIOCSFLAGS; +hidden extern const long TIOCSIG; +hidden extern const long TIOCSPGRP; +hidden extern const long TIOCSTART; +hidden extern const long TIOCSTAT; +hidden extern const long TIOCSTI; +hidden extern const long TIOCSTSTAMP; +hidden extern const long TIOCSWINSZ; +hidden extern const long TIOCTIMESTAMP; +hidden extern const long TIOCUCNTL_CBRK; +hidden extern const long TOSTOP; +hidden extern const long TTYDISC; +hidden extern const long VDISCARD; +hidden extern const long VEOF; +hidden extern const long VEOL; +hidden extern const long VEOL2; +hidden extern const long VERASE; +hidden extern const long VERIFY; +hidden extern const long VINTR; +hidden extern const long VKILL; +hidden extern const long VLNEXT; +hidden extern const long VMIN; +hidden extern const long VQUIT; +hidden extern const long VREPRINT; +hidden extern const long VSTART; +hidden extern const long VSTOP; +hidden extern const long VSUSP; +hidden extern const long VSWTC; +hidden extern const long VTDLY; +hidden extern const long VTIME; +hidden extern const long VWERASE; +hidden extern const long XCASE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ + +#define IGNBRK LITERALLY(0b0000000000000001) +#define BRKINT LITERALLY(0b0000000000000010) +#define IGNPAR LITERALLY(0b0000000000000100) +#define PARMRK LITERALLY(0b0000000000001000) +#define INPCK LITERALLY(0b0000000000010000) +#define ISTRIP LITERALLY(0b0000000000100000) +#define INLCR LITERALLY(0b0000000001000000) +#define IGNCR LITERALLY(0b0000000010000000) +#define ICRNL LITERALLY(0b0000000100000000) +#define IXANY LITERALLY(0b0000100000000000) +#define IMAXBEL LITERALLY(0b0010000000000000) +#define OPOST LITERALLY(0b0000000000000001) + +#define NLDLY SYMBOLIC(NLDLY) +#define NL0 LITERALLY(0) +#define NL1 SYMBOLIC(NL1) +#define NL2 SYMBOLIC(NL2) +#define NL3 SYMBOLIC(NL3) +#define CRDLY SYMBOLIC(CRDLY) +#define CR0 LITERALLY(0) +#define CR1 SYMBOLIC(CR1) +#define CR2 SYMBOLIC(CR2) +#define CR3 SYMBOLIC(CR3) +#define TABDLY SYMBOLIC(TABDLY) +#define TAB0 LITERALLY(0) +#define TAB1 SYMBOLIC(TAB1) +#define TAB2 SYMBOLIC(TAB2) +#define TAB3 SYMBOLIC(TAB3) +#define XTABS SYMBOLIC(XTABS) +#define BSDLY SYMBOLIC(BSDLY) +#define BS0 LITERALLY(0) +#define BS1 SYMBOLIC(BS1) +#define BS2 SYMBOLIC(BS2) +#define VTDLY SYMBOLIC(VTDLY) +#define VT0 LITERALLY(0) +#define VT1 SYMBOLIC(VT1) +#define VT2 SYMBOLIC(VT2) +#define FFDLY SYMBOLIC(FFDLY) +#define FF0 LITERALLY(0) +#define FF1 SYMBOLIC(FF1) +#define FF2 SYMBOLIC(FF2) + +#define BUSY SYMBOLIC(BUSY) +#define CANBSIZ SYMBOLIC(CANBSIZ) +#define CBAUD SYMBOLIC(CBAUD) +#define CBAUDEX SYMBOLIC(CBAUDEX) +#define CBRK SYMBOLIC(CBRK) +#define CEOL SYMBOLIC(CEOL) +#define CIBAUD SYMBOLIC(CIBAUD) +#define CLOCAL SYMBOLIC(CLOCAL) +#define CMSPAR SYMBOLIC(CMSPAR) +#define CS6 SYMBOLIC(CS6) +#define CS7 SYMBOLIC(CS7) +#define CS8 SYMBOLIC(CS8) +#define CSIZE SYMBOLIC(CSIZE) +#define ECHO LITERALLY(8) +#define ECHOCTL SYMBOLIC(ECHOCTL) +#define ECHOE SYMBOLIC(ECHOE) +#define ECHOK SYMBOLIC(ECHOK) +#define ECHOKE SYMBOLIC(ECHOKE) +#define ECHONL SYMBOLIC(ECHONL) +#define ECHOPRT SYMBOLIC(ECHOPRT) +#define ENDRUNDISC SYMBOLIC(ENDRUNDISC) +#define EXTPROC SYMBOLIC(EXTPROC) +#define FLUSHO SYMBOLIC(FLUSHO) +#define H4DISC SYMBOLIC(H4DISC) +#define ICANON SYMBOLIC(ICANON) +#define IEXTEN SYMBOLIC(IEXTEN) +#define ISIG SYMBOLIC(ISIG) +#define IUCLC SYMBOLIC(IUCLC) +#define IUTF8 SYMBOLIC(IUTF8) +#define IXOFF SYMBOLIC(IXOFF) +#define IXON SYMBOLIC(IXON) +#define NCCS LITERALLY(32) +#define NETGRAPHDISC SYMBOLIC(NETGRAPHDISC) +#define NMEADISC SYMBOLIC(NMEADISC) +#define NOFLSH SYMBOLIC(NOFLSH) +#define OCRNL SYMBOLIC(OCRNL) +#define OFDEL SYMBOLIC(OFDEL) +#define OFILL SYMBOLIC(OFILL) +#define OLCUC SYMBOLIC(OLCUC) +#define ONLCR SYMBOLIC(ONLCR) +#define ONLRET SYMBOLIC(ONLRET) +#define ONOCR SYMBOLIC(ONOCR) +#define PARENB SYMBOLIC(PARENB) +#define PARODD SYMBOLIC(PARODD) +#define PENDIN SYMBOLIC(PENDIN) +#define PPPDISC SYMBOLIC(PPPDISC) +#define SLIPDISC SYMBOLIC(SLIPDISC) +#define STRIPDISC SYMBOLIC(STRIPDISC) +#define TABLDISC SYMBOLIC(TABLDISC) +#define TCGETS SYMBOLIC(TCGETS) +#define TCSANOW LITERALLY(0) +#define TCSADRAIN LITERALLY(1) +#define TCSAFLUSH LITERALLY(2) +#define TCSETS SYMBOLIC(TCSETS) +#define TCSETSF SYMBOLIC(TCSETSF) +#define TCSETSW SYMBOLIC(TCSETSW) +#define TIOCCBRK SYMBOLIC(TIOCCBRK) +#define TIOCCDTR SYMBOLIC(TIOCCDTR) +#define TIOCCHKVERAUTH SYMBOLIC(TIOCCHKVERAUTH) +#define TIOCCONS SYMBOLIC(TIOCCONS) +#define TIOCDRAIN SYMBOLIC(TIOCDRAIN) +#define TIOCEXT SYMBOLIC(TIOCEXT) +#define TIOCFLAG_CLOCAL SYMBOLIC(TIOCFLAG_CLOCAL) +#define TIOCFLAG_MDMBUF SYMBOLIC(TIOCFLAG_MDMBUF) +#define TIOCFLAG_PPS SYMBOLIC(TIOCFLAG_PPS) +#define TIOCFLAG_SOFTCAR SYMBOLIC(TIOCFLAG_SOFTCAR) +#define TIOCFLUSH SYMBOLIC(TIOCFLUSH) +#define TIOCGDRAINWAIT SYMBOLIC(TIOCGDRAINWAIT) +#define TIOCGETD SYMBOLIC(TIOCGETD) +#define TIOCGFLAGS SYMBOLIC(TIOCGFLAGS) +#define TIOCGPGRP SYMBOLIC(TIOCGPGRP) +#define TIOCGPTN SYMBOLIC(TIOCGPTN) +#define TIOCGSID SYMBOLIC(TIOCGSID) +#define TIOCGTSTAMP SYMBOLIC(TIOCGTSTAMP) +#define TIOCGWINSZ SYMBOLIC(TIOCGWINSZ) +#define TIOCNOTTY SYMBOLIC(TIOCNOTTY) +#define TIOCNXCL SYMBOLIC(TIOCNXCL) +#define TIOCOUTQ SYMBOLIC(TIOCOUTQ) +#define TIOCPTMASTER SYMBOLIC(TIOCPTMASTER) +#define TIOCREMOTE SYMBOLIC(TIOCREMOTE) +#define TIOCSBRK SYMBOLIC(TIOCSBRK) +#define TIOCSCTTY SYMBOLIC(TIOCSCTTY) +#define TIOCSDRAINWAIT SYMBOLIC(TIOCSDRAINWAIT) +#define TIOCSDTR SYMBOLIC(TIOCSDTR) +#define TIOCSERGETLSR SYMBOLIC(TIOCSERGETLSR) +#define TIOCSERGETMULTI SYMBOLIC(TIOCSERGETMULTI) +#define TIOCSERSETMULTI SYMBOLIC(TIOCSERSETMULTI) +#define TIOCSER_TEMT SYMBOLIC(TIOCSER_TEMT) +#define TIOCSETD SYMBOLIC(TIOCSETD) +#define TIOCSETVERAUTH SYMBOLIC(TIOCSETVERAUTH) +#define TIOCSFLAGS SYMBOLIC(TIOCSFLAGS) +#define TIOCSIG SYMBOLIC(TIOCSIG) +#define TIOCSPGRP SYMBOLIC(TIOCSPGRP) +#define TIOCSTART SYMBOLIC(TIOCSTART) +#define TIOCSTAT SYMBOLIC(TIOCSTAT) +#define TIOCSTI SYMBOLIC(TIOCSTI) +#define TIOCSTSTAMP SYMBOLIC(TIOCSTSTAMP) +#define TIOCSWINSZ SYMBOLIC(TIOCSWINSZ) +#define TIOCTIMESTAMP SYMBOLIC(TIOCTIMESTAMP) +#define TIOCUCNTL_CBRK SYMBOLIC(TIOCUCNTL_CBRK) +#define TOSTOP SYMBOLIC(TOSTOP) +#define TTYDISC SYMBOLIC(TTYDISC) +#define VDISCARD SYMBOLIC(VDISCARD) +#define VEOF SYMBOLIC(VEOF) +#define VEOL SYMBOLIC(VEOL) +#define VEOL2 SYMBOLIC(VEOL2) +#define VERASE SYMBOLIC(VERASE) +#define VERIFY SYMBOLIC(VERIFY) +#define VINTR SYMBOLIC(VINTR) +#define VKILL SYMBOLIC(VKILL) +#define VLNEXT SYMBOLIC(VLNEXT) +#define VMIN SYMBOLIC(VMIN) +#define VQUIT SYMBOLIC(VQUIT) +#define VREPRINT SYMBOLIC(VREPRINT) +#define VSTART SYMBOLIC(VSTART) +#define VSTOP SYMBOLIC(VSTOP) +#define VSUSP SYMBOLIC(VSUSP) +#define VSWTC SYMBOLIC(VSWTC) +#define VTIME SYMBOLIC(VTIME) +#define VWERASE SYMBOLIC(VWERASE) +#define XCASE SYMBOLIC(XCASE) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_TERMIOS_H_ */ diff --git a/libc/sysv/consts/th.h b/libc/sysv/consts/th.h new file mode 100644 index 00000000..4808b3eb --- /dev/null +++ b/libc/sysv/consts/th.h @@ -0,0 +1,24 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_TH_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_TH_H_ +#include "libc/runtime/symbolic.h" + +#define TH_ACK SYMBOLIC(TH_ACK) +#define TH_FIN SYMBOLIC(TH_FIN) +#define TH_PUSH SYMBOLIC(TH_PUSH) +#define TH_RST SYMBOLIC(TH_RST) +#define TH_SYN SYMBOLIC(TH_SYN) +#define TH_URG SYMBOLIC(TH_URG) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long TH_ACK; +hidden extern const long TH_FIN; +hidden extern const long TH_PUSH; +hidden extern const long TH_RST; +hidden extern const long TH_SYN; +hidden extern const long TH_URG; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_TH_H_ */ diff --git a/libc/sysv/consts/trap.h b/libc/sysv/consts/trap.h new file mode 100644 index 00000000..8a4a3d9f --- /dev/null +++ b/libc/sysv/consts/trap.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_TRAP_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_TRAP_H_ +#include "libc/runtime/symbolic.h" + +#define TRAP_BRKPT SYMBOLIC(TRAP_BRKPT) +#define TRAP_TRACE SYMBOLIC(TRAP_TRACE) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long TRAP_BRKPT; +hidden extern const long TRAP_TRACE; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_TRAP_H_ */ diff --git a/libc/sysv/consts/type.h b/libc/sysv/consts/type.h new file mode 100644 index 00000000..71be7288 --- /dev/null +++ b/libc/sysv/consts/type.h @@ -0,0 +1,40 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_TYPE_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_TYPE_H_ +#include "libc/runtime/symbolic.h" + +#define TYPE_A SYMBOLIC(TYPE_A) +#define TYPE_DISK SYMBOLIC(TYPE_DISK) +#define TYPE_E SYMBOLIC(TYPE_E) +#define TYPE_ENCLOSURE SYMBOLIC(TYPE_ENCLOSURE) +#define TYPE_I SYMBOLIC(TYPE_I) +#define TYPE_L SYMBOLIC(TYPE_L) +#define TYPE_MEDIUM_CHANGER SYMBOLIC(TYPE_MEDIUM_CHANGER) +#define TYPE_MOD SYMBOLIC(TYPE_MOD) +#define TYPE_NO_LUN SYMBOLIC(TYPE_NO_LUN) +#define TYPE_PROCESSOR SYMBOLIC(TYPE_PROCESSOR) +#define TYPE_ROM SYMBOLIC(TYPE_ROM) +#define TYPE_SCANNER SYMBOLIC(TYPE_SCANNER) +#define TYPE_TAPE SYMBOLIC(TYPE_TAPE) +#define TYPE_WORM SYMBOLIC(TYPE_WORM) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long TYPE_A; +hidden extern const long TYPE_DISK; +hidden extern const long TYPE_E; +hidden extern const long TYPE_ENCLOSURE; +hidden extern const long TYPE_I; +hidden extern const long TYPE_L; +hidden extern const long TYPE_MEDIUM_CHANGER; +hidden extern const long TYPE_MOD; +hidden extern const long TYPE_NO_LUN; +hidden extern const long TYPE_PROCESSOR; +hidden extern const long TYPE_ROM; +hidden extern const long TYPE_SCANNER; +hidden extern const long TYPE_TAPE; +hidden extern const long TYPE_WORM; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_TYPE_H_ */ diff --git a/libc/sysv/consts/w.h b/libc/sysv/consts/w.h new file mode 100644 index 00000000..d3b6a400 --- /dev/null +++ b/libc/sysv/consts/w.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_W_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_W_H_ +#include "libc/runtime/symbolic.h" + +#define WNOHANG SYMBOLIC(WNOHANG) +#define WUNTRACED SYMBOLIC(WUNTRACED) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +hidden extern const long WNOHANG; +hidden extern const long WUNTRACED; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_W_H_ */ diff --git a/libc/sysv/errfuns.h b/libc/sysv/errfuns.h new file mode 100644 index 00000000..90805b52 --- /dev/null +++ b/libc/sysv/errfuns.h @@ -0,0 +1,165 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_ERRFUNS_H_ +#define COSMOPOLITAN_LIBC_SYSV_ERRFUNS_H_ +#include "libc/errno.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * @fileoverview Optimized error return paths. + * + * Saying this: + * + * return einval(); + * + * Instead of this: + * + * errno = EINVAL; + * return -1; + * + * Allows the compiler to generate 11 fewer bytes of code each time. + * + * @return always -1 + * @see libc/sysv/errfuns.inc (for implementation) + */ + +#define __ERRFUN(FUNC) \ + ({ \ + intptr_t NegOne; \ + asm("call\t" FUNC : "=a"(NegOne), "=m"(errno)); \ + NegOne; \ + }) + +int einval(void) relegated; + +#define eperm() __ERRFUN("eperm") +#define enoent() __ERRFUN("enoent") +#define esrch() __ERRFUN("esrch") +#define eintr() __ERRFUN("eintr") +#define eio() __ERRFUN("eio") +#define enxio() __ERRFUN("enxio") +#define e2big() __ERRFUN("e2big") +#define enoexec() __ERRFUN("enoexec") +#define ebadf() __ERRFUN("ebadf") +#define echild() __ERRFUN("echild") +#define eagain() __ERRFUN("eagain") +#define enomem() __ERRFUN("enomem") +#define eacces() __ERRFUN("eacces") +#define efault() __ERRFUN("efault") +#define enotblk() __ERRFUN("enotblk") +#define ebusy() __ERRFUN("ebusy") +#define eexist() __ERRFUN("eexist") +#define exdev() __ERRFUN("exdev") +#define enodev() __ERRFUN("enodev") +#define enotdir() __ERRFUN("enotdir") +#define eisdir() __ERRFUN("eisdir") +#define enfile() __ERRFUN("enfile") +#define emfile() __ERRFUN("emfile") +#define enotty() __ERRFUN("enotty") +#define enotsup() __ERRFUN("enotsup") +#define etxtbsy() __ERRFUN("etxtbsy") +#define efbig() __ERRFUN("efbig") +#define enospc() __ERRFUN("enospc") +#define espipe() __ERRFUN("espipe") +#define erofs() __ERRFUN("erofs") +#define emlink() __ERRFUN("emlink") +#define epipe() __ERRFUN("epipe") +#define edom() __ERRFUN("edom") +#define erange() __ERRFUN("erange") +#define edeadlk() __ERRFUN("edeadlk") +#define enametoolong() __ERRFUN("enametoolong") +#define enolck() __ERRFUN("enolck") +#define enosys() __ERRFUN("enosys") +#define enotempty() __ERRFUN("enotempty") +#define eloop() __ERRFUN("eloop") +#define enomsg() __ERRFUN("enomsg") +#define eidrm() __ERRFUN("eidrm") +#define echrng() __ERRFUN("echrng") +#define el2nsync() __ERRFUN("el2nsync") +#define el3hlt() __ERRFUN("el3hlt") +#define el3rst() __ERRFUN("el3rst") +#define elnrng() __ERRFUN("elnrng") +#define eunatch() __ERRFUN("eunatch") +#define enocsi() __ERRFUN("enocsi") +#define el2hlt() __ERRFUN("el2hlt") +#define ebade() __ERRFUN("ebade") +#define ebadr() __ERRFUN("ebadr") +#define exfull() __ERRFUN("exfull") +#define enoano() __ERRFUN("enoano") +#define ebadrqc() __ERRFUN("ebadrqc") +#define ebadslt() __ERRFUN("ebadslt") +#define enostr() __ERRFUN("enostr") +#define enodata() __ERRFUN("enodata") +#define etime() __ERRFUN("etime") +#define enosr() __ERRFUN("enosr") +#define enonet() __ERRFUN("enonet") +#define enopkg() __ERRFUN("enopkg") +#define eremote() __ERRFUN("eremote") +#define enolink() __ERRFUN("enolink") +#define eadv() __ERRFUN("eadv") +#define esrmnt() __ERRFUN("esrmnt") +#define ecomm() __ERRFUN("ecomm") +#define eproto() __ERRFUN("eproto") +#define emultihop() __ERRFUN("emultihop") +#define edotdot() __ERRFUN("edotdot") +#define ebadmsg() __ERRFUN("ebadmsg") +#define eoverflow() __ERRFUN("eoverflow") +#define enotuniq() __ERRFUN("enotuniq") +#define ebadfd() __ERRFUN("ebadfd") +#define eremchg() __ERRFUN("eremchg") +#define elibacc() __ERRFUN("elibacc") +#define elibbad() __ERRFUN("elibbad") +#define elibscn() __ERRFUN("elibscn") +#define elibmax() __ERRFUN("elibmax") +#define elibexec() __ERRFUN("elibexec") +#define eilseq() __ERRFUN("eilseq") +#define erestart() __ERRFUN("erestart") +#define estrpipe() __ERRFUN("estrpipe") +#define eusers() __ERRFUN("eusers") +#define enotsock() __ERRFUN("enotsock") +#define edestaddrreq() __ERRFUN("edestaddrreq") +#define emsgsize() __ERRFUN("emsgsize") +#define eprototype() __ERRFUN("eprototype") +#define enoprotoopt() __ERRFUN("enoprotoopt") +#define eprotonosupport() __ERRFUN("eprotonosupport") +#define esocktnosupport() __ERRFUN("esocktnosupport") +#define eopnotsupp() __ERRFUN("eopnotsupp") +#define epfnosupport() __ERRFUN("epfnosupport") +#define eafnosupport() __ERRFUN("eafnosupport") +#define eaddrinuse() __ERRFUN("eaddrinuse") +#define eaddrnotavail() __ERRFUN("eaddrnotavail") +#define enetdown() __ERRFUN("enetdown") +#define enetunreach() __ERRFUN("enetunreach") +#define enetreset() __ERRFUN("enetreset") +#define econnaborted() __ERRFUN("econnaborted") +#define econnreset() __ERRFUN("econnreset") +#define enobufs() __ERRFUN("enobufs") +#define eisconn() __ERRFUN("eisconn") +#define enotconn() __ERRFUN("enotconn") +#define eshutdown() __ERRFUN("eshutdown") +#define etoomanyrefs() __ERRFUN("etoomanyrefs") +#define etimedout() __ERRFUN("etimedout") +#define econnrefused() __ERRFUN("econnrefused") +#define ehostdown() __ERRFUN("ehostdown") +#define ehostunreach() __ERRFUN("ehostunreach") +#define ealready() __ERRFUN("ealready") +#define einprogress() __ERRFUN("einprogress") +#define estale() __ERRFUN("estale") +#define euclean() __ERRFUN("euclean") +#define enotnam() __ERRFUN("enotnam") +#define enavail() __ERRFUN("enavail") +#define eisnam() __ERRFUN("eisnam") +#define eremoteio() __ERRFUN("eremoteio") +#define edquot() __ERRFUN("edquot") +#define enomedium() __ERRFUN("enomedium") +#define emediumtype() __ERRFUN("emediumtype") +#define ecanceled() __ERRFUN("ecanceled") +#define enokey() __ERRFUN("enokey") +#define ekeyexpired() __ERRFUN("ekeyexpired") +#define ekeyrevoked() __ERRFUN("ekeyrevoked") +#define ekeyrejected() __ERRFUN("ekeyrejected") +#define eownerdead() __ERRFUN("eownerdead") +#define enotrecoverable() __ERRFUN("enotrecoverable") +#define erfkill() __ERRFUN("erfkill") +#define ehwpoison() __ERRFUN("ehwpoison") + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_SYSV_ERRFUNS_H_ */ diff --git a/libc/sysv/errfuns.sh b/libc/sysv/errfuns.sh new file mode 100755 index 00000000..2bc411e1 --- /dev/null +++ b/libc/sysv/errfuns.sh @@ -0,0 +1,153 @@ +/*bin/echo ' -*- mode:sh; indent-tabs-mode:nil; tab-width:8; coding:utf-8 -*-│ +│vi: set net ft=sh ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚────────────────────────────────────────────────────────────────'>/dev/null #*/ +dir=libc/sysv/errfuns +. libc/sysv/gen.sh + +errfun eperm EPERM +errfun enoent ENOENT +errfun esrch ESRCH +errfun eintr EINTR +errfun eio EIO +errfun enxio ENXIO +errfun e2big E2BIG +errfun enoexec ENOEXEC +errfun ebadf EBADF +errfun echild ECHILD +errfun eagain EAGAIN +errfun enomem ENOMEM +errfun eacces EACCES +errfun efault EFAULT +errfun enotblk ENOTBLK +errfun ebusy EBUSY +errfun eexist EEXIST +errfun exdev EXDEV +errfun enodev ENODEV +errfun enotdir ENOTDIR +errfun eisdir EISDIR +errfun einval EINVAL +errfun enfile ENFILE +errfun emfile EMFILE +errfun enotty ENOTTY +errfun enotsup ENOTSUP +errfun etxtbsy ETXTBSY +errfun efbig EFBIG +errfun enospc ENOSPC +errfun espipe ESPIPE +errfun erofs EROFS +errfun emlink EMLINK +errfun epipe EPIPE +errfun edom EDOM +errfun erange ERANGE +errfun edeadlk EDEADLK +errfun enametoolong ENAMETOOLONG +errfun enolck ENOLCK +errfun enosys ENOSYS +errfun enotempty ENOTEMPTY +errfun eloop ELOOP +errfun enomsg ENOMSG +errfun eidrm EIDRM +errfun echrng ECHRNG +errfun el2nsync EL2NSYNC +errfun el3hlt EL3HLT +errfun el3rst EL3RST +errfun elnrng ELNRNG +errfun eunatch EUNATCH +errfun enocsi ENOCSI +errfun el2hlt EL2HLT +errfun ebade EBADE +errfun ebadr EBADR +errfun exfull EXFULL +errfun enoano ENOANO +errfun ebadrqc EBADRQC +errfun ebadslt EBADSLT +errfun enostr ENOSTR +errfun enodata ENODATA +errfun etime ETIME +errfun enosr ENOSR +errfun enonet ENONET +errfun enopkg ENOPKG +errfun eremote EREMOTE +errfun enolink ENOLINK +errfun eadv EADV +errfun esrmnt ESRMNT +errfun ecomm ECOMM +errfun eproto EPROTO +errfun emultihop EMULTIHOP +errfun edotdot EDOTDOT +errfun ebadmsg EBADMSG +errfun eoverflow EOVERFLOW +errfun enotuniq ENOTUNIQ +errfun ebadfd EBADFD +errfun eremchg EREMCHG +errfun elibacc ELIBACC +errfun elibbad ELIBBAD +errfun elibscn ELIBSCN +errfun elibmax ELIBMAX +errfun elibexec ELIBEXEC +errfun eilseq EILSEQ +errfun erestart ERESTART +errfun estrpipe ESTRPIPE +errfun eusers EUSERS +errfun enotsock ENOTSOCK +errfun edestaddrreq EDESTADDRREQ +errfun emsgsize EMSGSIZE +errfun eprototype EPROTOTYPE +errfun enoprotoopt ENOPROTOOPT +errfun eprotonosupport EPROTONOSUPPORT +errfun esocktnosupport ESOCKTNOSUPPORT +errfun eopnotsupp EOPNOTSUPP +errfun epfnosupport EPFNOSUPPORT +errfun eafnosupport EAFNOSUPPORT +errfun eaddrinuse EADDRINUSE +errfun eaddrnotavail EADDRNOTAVAIL +errfun enetdown ENETDOWN +errfun enetunreach ENETUNREACH +errfun enetreset ENETRESET +errfun econnaborted ECONNABORTED +errfun econnreset ECONNRESET +errfun enobufs ENOBUFS +errfun eisconn EISCONN +errfun enotconn ENOTCONN +errfun eshutdown ESHUTDOWN +errfun etoomanyrefs ETOOMANYREFS +errfun etimedout ETIMEDOUT +errfun econnrefused ECONNREFUSED +errfun ehostdown EHOSTDOWN +errfun ehostunreach EHOSTUNREACH +errfun ealready EALREADY +errfun einprogress EINPROGRESS +errfun estale ESTALE +errfun euclean EUCLEAN +errfun enotnam ENOTNAM +errfun enavail ENAVAIL +errfun eisnam EISNAM +errfun eremoteio EREMOTEIO +errfun edquot EDQUOT +errfun enomedium ENOMEDIUM +errfun emediumtype EMEDIUMTYPE +errfun ecanceled ECANCELED +errfun enokey ENOKEY +errfun ekeyexpired EKEYEXPIRED +errfun ekeyrevoked EKEYREVOKED +errfun ekeyrejected EKEYREJECTED +errfun eownerdead EOWNERDEAD +errfun enotrecoverable ENOTRECOVERABLE +errfun erfkill ERFKILL +errfun ehwpoison EHWPOISON diff --git a/libc/sysv/errfuns/e2big.S b/libc/sysv/errfuns/e2big.S new file mode 100644 index 00000000..c897e206 --- /dev/null +++ b/libc/sysv/errfuns/e2big.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +e2big: .leafprologue + .profilable + mov E2BIG(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn e2big,globl,hidden diff --git a/libc/sysv/errfuns/eacces.S b/libc/sysv/errfuns/eacces.S new file mode 100644 index 00000000..c44933cf --- /dev/null +++ b/libc/sysv/errfuns/eacces.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +eacces: .leafprologue + .profilable + mov EACCES(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eacces,globl,hidden diff --git a/libc/sysv/errfuns/eaddrinuse.S b/libc/sysv/errfuns/eaddrinuse.S new file mode 100644 index 00000000..b5f98231 --- /dev/null +++ b/libc/sysv/errfuns/eaddrinuse.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +eaddrinuse: + .leafprologue + .profilable + mov EADDRINUSE(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eaddrinuse,globl,hidden diff --git a/libc/sysv/errfuns/eaddrnotavail.S b/libc/sysv/errfuns/eaddrnotavail.S new file mode 100644 index 00000000..81ff87bd --- /dev/null +++ b/libc/sysv/errfuns/eaddrnotavail.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +eaddrnotavail: + .leafprologue + .profilable + mov EADDRNOTAVAIL(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eaddrnotavail,globl,hidden diff --git a/libc/sysv/errfuns/eadv.S b/libc/sysv/errfuns/eadv.S new file mode 100644 index 00000000..98f7e5c3 --- /dev/null +++ b/libc/sysv/errfuns/eadv.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +eadv: .leafprologue + .profilable + mov EADV(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eadv,globl,hidden diff --git a/libc/sysv/errfuns/eafnosupport.S b/libc/sysv/errfuns/eafnosupport.S new file mode 100644 index 00000000..23b73cf5 --- /dev/null +++ b/libc/sysv/errfuns/eafnosupport.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +eafnosupport: + .leafprologue + .profilable + mov EAFNOSUPPORT(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eafnosupport,globl,hidden diff --git a/libc/sysv/errfuns/eagain.S b/libc/sysv/errfuns/eagain.S new file mode 100644 index 00000000..cc58aec9 --- /dev/null +++ b/libc/sysv/errfuns/eagain.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +eagain: .leafprologue + .profilable + mov EAGAIN(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eagain,globl,hidden diff --git a/libc/sysv/errfuns/ealready.S b/libc/sysv/errfuns/ealready.S new file mode 100644 index 00000000..e9a0c7c3 --- /dev/null +++ b/libc/sysv/errfuns/ealready.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +ealready: + .leafprologue + .profilable + mov EALREADY(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn ealready,globl,hidden diff --git a/libc/sysv/errfuns/ebade.S b/libc/sysv/errfuns/ebade.S new file mode 100644 index 00000000..6bb9f353 --- /dev/null +++ b/libc/sysv/errfuns/ebade.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +ebade: .leafprologue + .profilable + mov EBADE(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn ebade,globl,hidden diff --git a/libc/sysv/errfuns/ebadf.S b/libc/sysv/errfuns/ebadf.S new file mode 100644 index 00000000..a2fffa1b --- /dev/null +++ b/libc/sysv/errfuns/ebadf.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +ebadf: .leafprologue + .profilable + mov EBADF(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn ebadf,globl,hidden diff --git a/libc/sysv/errfuns/ebadfd.S b/libc/sysv/errfuns/ebadfd.S new file mode 100644 index 00000000..0e574a88 --- /dev/null +++ b/libc/sysv/errfuns/ebadfd.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +ebadfd: .leafprologue + .profilable + mov EBADFD(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn ebadfd,globl,hidden diff --git a/libc/sysv/errfuns/ebadmsg.S b/libc/sysv/errfuns/ebadmsg.S new file mode 100644 index 00000000..6ba760be --- /dev/null +++ b/libc/sysv/errfuns/ebadmsg.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +ebadmsg: + .leafprologue + .profilable + mov EBADMSG(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn ebadmsg,globl,hidden diff --git a/libc/sysv/errfuns/ebadr.S b/libc/sysv/errfuns/ebadr.S new file mode 100644 index 00000000..5480f512 --- /dev/null +++ b/libc/sysv/errfuns/ebadr.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +ebadr: .leafprologue + .profilable + mov EBADR(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn ebadr,globl,hidden diff --git a/libc/sysv/errfuns/ebadrqc.S b/libc/sysv/errfuns/ebadrqc.S new file mode 100644 index 00000000..4298c908 --- /dev/null +++ b/libc/sysv/errfuns/ebadrqc.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +ebadrqc: + .leafprologue + .profilable + mov EBADRQC(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn ebadrqc,globl,hidden diff --git a/libc/sysv/errfuns/ebadslt.S b/libc/sysv/errfuns/ebadslt.S new file mode 100644 index 00000000..bba860a0 --- /dev/null +++ b/libc/sysv/errfuns/ebadslt.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +ebadslt: + .leafprologue + .profilable + mov EBADSLT(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn ebadslt,globl,hidden diff --git a/libc/sysv/errfuns/ebusy.S b/libc/sysv/errfuns/ebusy.S new file mode 100644 index 00000000..edebc47f --- /dev/null +++ b/libc/sysv/errfuns/ebusy.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +ebusy: .leafprologue + .profilable + mov EBUSY(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn ebusy,globl,hidden diff --git a/libc/sysv/errfuns/ecanceled.S b/libc/sysv/errfuns/ecanceled.S new file mode 100644 index 00000000..6ca71ea4 --- /dev/null +++ b/libc/sysv/errfuns/ecanceled.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +ecanceled: + .leafprologue + .profilable + mov ECANCELED(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn ecanceled,globl,hidden diff --git a/libc/sysv/errfuns/echild.S b/libc/sysv/errfuns/echild.S new file mode 100644 index 00000000..a2f10ed4 --- /dev/null +++ b/libc/sysv/errfuns/echild.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +echild: .leafprologue + .profilable + mov ECHILD(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn echild,globl,hidden diff --git a/libc/sysv/errfuns/echrng.S b/libc/sysv/errfuns/echrng.S new file mode 100644 index 00000000..29a8a092 --- /dev/null +++ b/libc/sysv/errfuns/echrng.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +echrng: .leafprologue + .profilable + mov ECHRNG(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn echrng,globl,hidden diff --git a/libc/sysv/errfuns/ecomm.S b/libc/sysv/errfuns/ecomm.S new file mode 100644 index 00000000..b256f9c3 --- /dev/null +++ b/libc/sysv/errfuns/ecomm.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +ecomm: .leafprologue + .profilable + mov ECOMM(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn ecomm,globl,hidden diff --git a/libc/sysv/errfuns/econnaborted.S b/libc/sysv/errfuns/econnaborted.S new file mode 100644 index 00000000..687b2bda --- /dev/null +++ b/libc/sysv/errfuns/econnaborted.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +econnaborted: + .leafprologue + .profilable + mov ECONNABORTED(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn econnaborted,globl,hidden diff --git a/libc/sysv/errfuns/econnrefused.S b/libc/sysv/errfuns/econnrefused.S new file mode 100644 index 00000000..9065beb3 --- /dev/null +++ b/libc/sysv/errfuns/econnrefused.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +econnrefused: + .leafprologue + .profilable + mov ECONNREFUSED(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn econnrefused,globl,hidden diff --git a/libc/sysv/errfuns/econnreset.S b/libc/sysv/errfuns/econnreset.S new file mode 100644 index 00000000..1d5f4afa --- /dev/null +++ b/libc/sysv/errfuns/econnreset.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +econnreset: + .leafprologue + .profilable + mov ECONNRESET(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn econnreset,globl,hidden diff --git a/libc/sysv/errfuns/edeadlk.S b/libc/sysv/errfuns/edeadlk.S new file mode 100644 index 00000000..2ec5d81d --- /dev/null +++ b/libc/sysv/errfuns/edeadlk.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +edeadlk: + .leafprologue + .profilable + mov EDEADLK(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn edeadlk,globl,hidden diff --git a/libc/sysv/errfuns/edestaddrreq.S b/libc/sysv/errfuns/edestaddrreq.S new file mode 100644 index 00000000..400aabed --- /dev/null +++ b/libc/sysv/errfuns/edestaddrreq.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +edestaddrreq: + .leafprologue + .profilable + mov EDESTADDRREQ(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn edestaddrreq,globl,hidden diff --git a/libc/sysv/errfuns/edom.S b/libc/sysv/errfuns/edom.S new file mode 100644 index 00000000..35cf7b3c --- /dev/null +++ b/libc/sysv/errfuns/edom.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +edom: .leafprologue + .profilable + mov EDOM(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn edom,globl,hidden diff --git a/libc/sysv/errfuns/edotdot.S b/libc/sysv/errfuns/edotdot.S new file mode 100644 index 00000000..ef5cad2b --- /dev/null +++ b/libc/sysv/errfuns/edotdot.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +edotdot: + .leafprologue + .profilable + mov EDOTDOT(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn edotdot,globl,hidden diff --git a/libc/sysv/errfuns/edquot.S b/libc/sysv/errfuns/edquot.S new file mode 100644 index 00000000..01bfce66 --- /dev/null +++ b/libc/sysv/errfuns/edquot.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +edquot: .leafprologue + .profilable + mov EDQUOT(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn edquot,globl,hidden diff --git a/libc/sysv/errfuns/eexist.S b/libc/sysv/errfuns/eexist.S new file mode 100644 index 00000000..6fe7e525 --- /dev/null +++ b/libc/sysv/errfuns/eexist.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +eexist: .leafprologue + .profilable + mov EEXIST(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eexist,globl,hidden diff --git a/libc/sysv/errfuns/efault.S b/libc/sysv/errfuns/efault.S new file mode 100644 index 00000000..6f77c7eb --- /dev/null +++ b/libc/sysv/errfuns/efault.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +efault: .leafprologue + .profilable + mov EFAULT(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn efault,globl,hidden diff --git a/libc/sysv/errfuns/efbig.S b/libc/sysv/errfuns/efbig.S new file mode 100644 index 00000000..07cc1e71 --- /dev/null +++ b/libc/sysv/errfuns/efbig.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +efbig: .leafprologue + .profilable + mov EFBIG(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn efbig,globl,hidden diff --git a/libc/sysv/errfuns/ehostdown.S b/libc/sysv/errfuns/ehostdown.S new file mode 100644 index 00000000..34916f59 --- /dev/null +++ b/libc/sysv/errfuns/ehostdown.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +ehostdown: + .leafprologue + .profilable + mov EHOSTDOWN(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn ehostdown,globl,hidden diff --git a/libc/sysv/errfuns/ehostunreach.S b/libc/sysv/errfuns/ehostunreach.S new file mode 100644 index 00000000..abebdfa1 --- /dev/null +++ b/libc/sysv/errfuns/ehostunreach.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +ehostunreach: + .leafprologue + .profilable + mov EHOSTUNREACH(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn ehostunreach,globl,hidden diff --git a/libc/sysv/errfuns/ehwpoison.S b/libc/sysv/errfuns/ehwpoison.S new file mode 100644 index 00000000..c62f349c --- /dev/null +++ b/libc/sysv/errfuns/ehwpoison.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +ehwpoison: + .leafprologue + .profilable + mov EHWPOISON(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn ehwpoison,globl,hidden diff --git a/libc/sysv/errfuns/eidrm.S b/libc/sysv/errfuns/eidrm.S new file mode 100644 index 00000000..a0012a17 --- /dev/null +++ b/libc/sysv/errfuns/eidrm.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +eidrm: .leafprologue + .profilable + mov EIDRM(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eidrm,globl,hidden diff --git a/libc/sysv/errfuns/eilseq.S b/libc/sysv/errfuns/eilseq.S new file mode 100644 index 00000000..83c094f6 --- /dev/null +++ b/libc/sysv/errfuns/eilseq.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +eilseq: .leafprologue + .profilable + mov EILSEQ(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eilseq,globl,hidden diff --git a/libc/sysv/errfuns/einprogress.S b/libc/sysv/errfuns/einprogress.S new file mode 100644 index 00000000..ba8565c2 --- /dev/null +++ b/libc/sysv/errfuns/einprogress.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +einprogress: + .leafprologue + .profilable + mov EINPROGRESS(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn einprogress,globl,hidden diff --git a/libc/sysv/errfuns/eintr.S b/libc/sysv/errfuns/eintr.S new file mode 100644 index 00000000..ae9586a5 --- /dev/null +++ b/libc/sysv/errfuns/eintr.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +eintr: .leafprologue + .profilable + mov EINTR(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eintr,globl,hidden diff --git a/libc/sysv/errfuns/einval.S b/libc/sysv/errfuns/einval.S new file mode 100644 index 00000000..524b377f --- /dev/null +++ b/libc/sysv/errfuns/einval.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +einval: .leafprologue + .profilable + mov EINVAL(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn einval,globl,hidden diff --git a/libc/sysv/errfuns/eio.S b/libc/sysv/errfuns/eio.S new file mode 100644 index 00000000..7c3a77e1 --- /dev/null +++ b/libc/sysv/errfuns/eio.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +eio: .leafprologue + .profilable + mov EIO(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eio,globl,hidden diff --git a/libc/sysv/errfuns/eisconn.S b/libc/sysv/errfuns/eisconn.S new file mode 100644 index 00000000..237e28ea --- /dev/null +++ b/libc/sysv/errfuns/eisconn.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +eisconn: + .leafprologue + .profilable + mov EISCONN(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eisconn,globl,hidden diff --git a/libc/sysv/errfuns/eisdir.S b/libc/sysv/errfuns/eisdir.S new file mode 100644 index 00000000..60569871 --- /dev/null +++ b/libc/sysv/errfuns/eisdir.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +eisdir: .leafprologue + .profilable + mov EISDIR(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eisdir,globl,hidden diff --git a/libc/sysv/errfuns/eisnam.S b/libc/sysv/errfuns/eisnam.S new file mode 100644 index 00000000..770d4d1f --- /dev/null +++ b/libc/sysv/errfuns/eisnam.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +eisnam: .leafprologue + .profilable + mov EISNAM(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eisnam,globl,hidden diff --git a/libc/sysv/errfuns/ekeyexpired.S b/libc/sysv/errfuns/ekeyexpired.S new file mode 100644 index 00000000..2de69c5c --- /dev/null +++ b/libc/sysv/errfuns/ekeyexpired.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +ekeyexpired: + .leafprologue + .profilable + mov EKEYEXPIRED(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn ekeyexpired,globl,hidden diff --git a/libc/sysv/errfuns/ekeyrejected.S b/libc/sysv/errfuns/ekeyrejected.S new file mode 100644 index 00000000..e1037488 --- /dev/null +++ b/libc/sysv/errfuns/ekeyrejected.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +ekeyrejected: + .leafprologue + .profilable + mov EKEYREJECTED(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn ekeyrejected,globl,hidden diff --git a/libc/sysv/errfuns/ekeyrevoked.S b/libc/sysv/errfuns/ekeyrevoked.S new file mode 100644 index 00000000..c22dfedb --- /dev/null +++ b/libc/sysv/errfuns/ekeyrevoked.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +ekeyrevoked: + .leafprologue + .profilable + mov EKEYREVOKED(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn ekeyrevoked,globl,hidden diff --git a/libc/sysv/errfuns/el2hlt.S b/libc/sysv/errfuns/el2hlt.S new file mode 100644 index 00000000..2b5d46bd --- /dev/null +++ b/libc/sysv/errfuns/el2hlt.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +el2hlt: .leafprologue + .profilable + mov EL2HLT(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn el2hlt,globl,hidden diff --git a/libc/sysv/errfuns/el2nsync.S b/libc/sysv/errfuns/el2nsync.S new file mode 100644 index 00000000..f3861319 --- /dev/null +++ b/libc/sysv/errfuns/el2nsync.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +el2nsync: + .leafprologue + .profilable + mov EL2NSYNC(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn el2nsync,globl,hidden diff --git a/libc/sysv/errfuns/el3hlt.S b/libc/sysv/errfuns/el3hlt.S new file mode 100644 index 00000000..c24f2d43 --- /dev/null +++ b/libc/sysv/errfuns/el3hlt.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +el3hlt: .leafprologue + .profilable + mov EL3HLT(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn el3hlt,globl,hidden diff --git a/libc/sysv/errfuns/el3rst.S b/libc/sysv/errfuns/el3rst.S new file mode 100644 index 00000000..2dd7efb2 --- /dev/null +++ b/libc/sysv/errfuns/el3rst.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +el3rst: .leafprologue + .profilable + mov EL3RST(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn el3rst,globl,hidden diff --git a/libc/sysv/errfuns/elibacc.S b/libc/sysv/errfuns/elibacc.S new file mode 100644 index 00000000..5c3368d3 --- /dev/null +++ b/libc/sysv/errfuns/elibacc.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +elibacc: + .leafprologue + .profilable + mov ELIBACC(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn elibacc,globl,hidden diff --git a/libc/sysv/errfuns/elibbad.S b/libc/sysv/errfuns/elibbad.S new file mode 100644 index 00000000..2c5ac728 --- /dev/null +++ b/libc/sysv/errfuns/elibbad.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +elibbad: + .leafprologue + .profilable + mov ELIBBAD(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn elibbad,globl,hidden diff --git a/libc/sysv/errfuns/elibexec.S b/libc/sysv/errfuns/elibexec.S new file mode 100644 index 00000000..996db5e0 --- /dev/null +++ b/libc/sysv/errfuns/elibexec.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +elibexec: + .leafprologue + .profilable + mov ELIBEXEC(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn elibexec,globl,hidden diff --git a/libc/sysv/errfuns/elibmax.S b/libc/sysv/errfuns/elibmax.S new file mode 100644 index 00000000..2ec5bd91 --- /dev/null +++ b/libc/sysv/errfuns/elibmax.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +elibmax: + .leafprologue + .profilable + mov ELIBMAX(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn elibmax,globl,hidden diff --git a/libc/sysv/errfuns/elibscn.S b/libc/sysv/errfuns/elibscn.S new file mode 100644 index 00000000..b996f70e --- /dev/null +++ b/libc/sysv/errfuns/elibscn.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +elibscn: + .leafprologue + .profilable + mov ELIBSCN(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn elibscn,globl,hidden diff --git a/libc/sysv/errfuns/elnrng.S b/libc/sysv/errfuns/elnrng.S new file mode 100644 index 00000000..aa57cf5a --- /dev/null +++ b/libc/sysv/errfuns/elnrng.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +elnrng: .leafprologue + .profilable + mov ELNRNG(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn elnrng,globl,hidden diff --git a/libc/sysv/errfuns/eloop.S b/libc/sysv/errfuns/eloop.S new file mode 100644 index 00000000..d8708bd5 --- /dev/null +++ b/libc/sysv/errfuns/eloop.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +eloop: .leafprologue + .profilable + mov ELOOP(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eloop,globl,hidden diff --git a/libc/sysv/errfuns/emediumtype.S b/libc/sysv/errfuns/emediumtype.S new file mode 100644 index 00000000..886b0b4c --- /dev/null +++ b/libc/sysv/errfuns/emediumtype.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +emediumtype: + .leafprologue + .profilable + mov EMEDIUMTYPE(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn emediumtype,globl,hidden diff --git a/libc/sysv/errfuns/emfile.S b/libc/sysv/errfuns/emfile.S new file mode 100644 index 00000000..9972d483 --- /dev/null +++ b/libc/sysv/errfuns/emfile.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +emfile: .leafprologue + .profilable + mov EMFILE(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn emfile,globl,hidden diff --git a/libc/sysv/errfuns/emlink.S b/libc/sysv/errfuns/emlink.S new file mode 100644 index 00000000..e8cd47f3 --- /dev/null +++ b/libc/sysv/errfuns/emlink.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +emlink: .leafprologue + .profilable + mov EMLINK(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn emlink,globl,hidden diff --git a/libc/sysv/errfuns/emsgsize.S b/libc/sysv/errfuns/emsgsize.S new file mode 100644 index 00000000..00c7362d --- /dev/null +++ b/libc/sysv/errfuns/emsgsize.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +emsgsize: + .leafprologue + .profilable + mov EMSGSIZE(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn emsgsize,globl,hidden diff --git a/libc/sysv/errfuns/emultihop.S b/libc/sysv/errfuns/emultihop.S new file mode 100644 index 00000000..ae6682b5 --- /dev/null +++ b/libc/sysv/errfuns/emultihop.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +emultihop: + .leafprologue + .profilable + mov EMULTIHOP(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn emultihop,globl,hidden diff --git a/libc/sysv/errfuns/enametoolong.S b/libc/sysv/errfuns/enametoolong.S new file mode 100644 index 00000000..4e5f5425 --- /dev/null +++ b/libc/sysv/errfuns/enametoolong.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enametoolong: + .leafprologue + .profilable + mov ENAMETOOLONG(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enametoolong,globl,hidden diff --git a/libc/sysv/errfuns/enavail.S b/libc/sysv/errfuns/enavail.S new file mode 100644 index 00000000..ac0e2c8a --- /dev/null +++ b/libc/sysv/errfuns/enavail.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enavail: + .leafprologue + .profilable + mov ENAVAIL(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enavail,globl,hidden diff --git a/libc/sysv/errfuns/enetdown.S b/libc/sysv/errfuns/enetdown.S new file mode 100644 index 00000000..ccf5100e --- /dev/null +++ b/libc/sysv/errfuns/enetdown.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enetdown: + .leafprologue + .profilable + mov ENETDOWN(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enetdown,globl,hidden diff --git a/libc/sysv/errfuns/enetreset.S b/libc/sysv/errfuns/enetreset.S new file mode 100644 index 00000000..36a662b9 --- /dev/null +++ b/libc/sysv/errfuns/enetreset.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enetreset: + .leafprologue + .profilable + mov ENETRESET(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enetreset,globl,hidden diff --git a/libc/sysv/errfuns/enetunreach.S b/libc/sysv/errfuns/enetunreach.S new file mode 100644 index 00000000..9210508c --- /dev/null +++ b/libc/sysv/errfuns/enetunreach.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enetunreach: + .leafprologue + .profilable + mov ENETUNREACH(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enetunreach,globl,hidden diff --git a/libc/sysv/errfuns/enfile.S b/libc/sysv/errfuns/enfile.S new file mode 100644 index 00000000..90115f4a --- /dev/null +++ b/libc/sysv/errfuns/enfile.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +enfile: .leafprologue + .profilable + mov ENFILE(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enfile,globl,hidden diff --git a/libc/sysv/errfuns/enoano.S b/libc/sysv/errfuns/enoano.S new file mode 100644 index 00000000..4d44cb3b --- /dev/null +++ b/libc/sysv/errfuns/enoano.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +enoano: .leafprologue + .profilable + mov ENOANO(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enoano,globl,hidden diff --git a/libc/sysv/errfuns/enobufs.S b/libc/sysv/errfuns/enobufs.S new file mode 100644 index 00000000..69550b42 --- /dev/null +++ b/libc/sysv/errfuns/enobufs.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enobufs: + .leafprologue + .profilable + mov ENOBUFS(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enobufs,globl,hidden diff --git a/libc/sysv/errfuns/enocsi.S b/libc/sysv/errfuns/enocsi.S new file mode 100644 index 00000000..d883cb1b --- /dev/null +++ b/libc/sysv/errfuns/enocsi.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +enocsi: .leafprologue + .profilable + mov ENOCSI(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enocsi,globl,hidden diff --git a/libc/sysv/errfuns/enodata.S b/libc/sysv/errfuns/enodata.S new file mode 100644 index 00000000..0e1bf0f4 --- /dev/null +++ b/libc/sysv/errfuns/enodata.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enodata: + .leafprologue + .profilable + mov ENODATA(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enodata,globl,hidden diff --git a/libc/sysv/errfuns/enodev.S b/libc/sysv/errfuns/enodev.S new file mode 100644 index 00000000..8c5af55c --- /dev/null +++ b/libc/sysv/errfuns/enodev.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +enodev: .leafprologue + .profilable + mov ENODEV(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enodev,globl,hidden diff --git a/libc/sysv/errfuns/enoent.S b/libc/sysv/errfuns/enoent.S new file mode 100644 index 00000000..5ca75730 --- /dev/null +++ b/libc/sysv/errfuns/enoent.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +enoent: .leafprologue + .profilable + mov ENOENT(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enoent,globl,hidden diff --git a/libc/sysv/errfuns/enoexec.S b/libc/sysv/errfuns/enoexec.S new file mode 100644 index 00000000..88fdd4fd --- /dev/null +++ b/libc/sysv/errfuns/enoexec.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enoexec: + .leafprologue + .profilable + mov ENOEXEC(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enoexec,globl,hidden diff --git a/libc/sysv/errfuns/enokey.S b/libc/sysv/errfuns/enokey.S new file mode 100644 index 00000000..5cff9fba --- /dev/null +++ b/libc/sysv/errfuns/enokey.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +enokey: .leafprologue + .profilable + mov ENOKEY(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enokey,globl,hidden diff --git a/libc/sysv/errfuns/enolck.S b/libc/sysv/errfuns/enolck.S new file mode 100644 index 00000000..0ec78654 --- /dev/null +++ b/libc/sysv/errfuns/enolck.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +enolck: .leafprologue + .profilable + mov ENOLCK(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enolck,globl,hidden diff --git a/libc/sysv/errfuns/enolink.S b/libc/sysv/errfuns/enolink.S new file mode 100644 index 00000000..99aa12cf --- /dev/null +++ b/libc/sysv/errfuns/enolink.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enolink: + .leafprologue + .profilable + mov ENOLINK(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enolink,globl,hidden diff --git a/libc/sysv/errfuns/enomedium.S b/libc/sysv/errfuns/enomedium.S new file mode 100644 index 00000000..33e54d91 --- /dev/null +++ b/libc/sysv/errfuns/enomedium.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enomedium: + .leafprologue + .profilable + mov ENOMEDIUM(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enomedium,globl,hidden diff --git a/libc/sysv/errfuns/enomem.S b/libc/sysv/errfuns/enomem.S new file mode 100644 index 00000000..3fe37508 --- /dev/null +++ b/libc/sysv/errfuns/enomem.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +enomem: .leafprologue + .profilable + mov ENOMEM(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enomem,globl,hidden diff --git a/libc/sysv/errfuns/enomsg.S b/libc/sysv/errfuns/enomsg.S new file mode 100644 index 00000000..757aea3a --- /dev/null +++ b/libc/sysv/errfuns/enomsg.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +enomsg: .leafprologue + .profilable + mov ENOMSG(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enomsg,globl,hidden diff --git a/libc/sysv/errfuns/enonet.S b/libc/sysv/errfuns/enonet.S new file mode 100644 index 00000000..d8082af4 --- /dev/null +++ b/libc/sysv/errfuns/enonet.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +enonet: .leafprologue + .profilable + mov ENONET(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enonet,globl,hidden diff --git a/libc/sysv/errfuns/enopkg.S b/libc/sysv/errfuns/enopkg.S new file mode 100644 index 00000000..1f26a26e --- /dev/null +++ b/libc/sysv/errfuns/enopkg.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +enopkg: .leafprologue + .profilable + mov ENOPKG(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enopkg,globl,hidden diff --git a/libc/sysv/errfuns/enoprotoopt.S b/libc/sysv/errfuns/enoprotoopt.S new file mode 100644 index 00000000..d67e4811 --- /dev/null +++ b/libc/sysv/errfuns/enoprotoopt.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enoprotoopt: + .leafprologue + .profilable + mov ENOPROTOOPT(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enoprotoopt,globl,hidden diff --git a/libc/sysv/errfuns/enospc.S b/libc/sysv/errfuns/enospc.S new file mode 100644 index 00000000..6a3452d0 --- /dev/null +++ b/libc/sysv/errfuns/enospc.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +enospc: .leafprologue + .profilable + mov ENOSPC(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enospc,globl,hidden diff --git a/libc/sysv/errfuns/enosr.S b/libc/sysv/errfuns/enosr.S new file mode 100644 index 00000000..4f94e227 --- /dev/null +++ b/libc/sysv/errfuns/enosr.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +enosr: .leafprologue + .profilable + mov ENOSR(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enosr,globl,hidden diff --git a/libc/sysv/errfuns/enostr.S b/libc/sysv/errfuns/enostr.S new file mode 100644 index 00000000..008ebf24 --- /dev/null +++ b/libc/sysv/errfuns/enostr.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +enostr: .leafprologue + .profilable + mov ENOSTR(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enostr,globl,hidden diff --git a/libc/sysv/errfuns/enosys.S b/libc/sysv/errfuns/enosys.S new file mode 100644 index 00000000..89da367e --- /dev/null +++ b/libc/sysv/errfuns/enosys.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +enosys: .leafprologue + .profilable + mov ENOSYS(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enosys,globl,hidden diff --git a/libc/sysv/errfuns/enotblk.S b/libc/sysv/errfuns/enotblk.S new file mode 100644 index 00000000..943c87e7 --- /dev/null +++ b/libc/sysv/errfuns/enotblk.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enotblk: + .leafprologue + .profilable + mov ENOTBLK(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enotblk,globl,hidden diff --git a/libc/sysv/errfuns/enotconn.S b/libc/sysv/errfuns/enotconn.S new file mode 100644 index 00000000..c1010f10 --- /dev/null +++ b/libc/sysv/errfuns/enotconn.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enotconn: + .leafprologue + .profilable + mov ENOTCONN(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enotconn,globl,hidden diff --git a/libc/sysv/errfuns/enotdir.S b/libc/sysv/errfuns/enotdir.S new file mode 100644 index 00000000..e204f392 --- /dev/null +++ b/libc/sysv/errfuns/enotdir.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enotdir: + .leafprologue + .profilable + mov ENOTDIR(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enotdir,globl,hidden diff --git a/libc/sysv/errfuns/enotempty.S b/libc/sysv/errfuns/enotempty.S new file mode 100644 index 00000000..20ed8e51 --- /dev/null +++ b/libc/sysv/errfuns/enotempty.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enotempty: + .leafprologue + .profilable + mov ENOTEMPTY(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enotempty,globl,hidden diff --git a/libc/sysv/errfuns/enotnam.S b/libc/sysv/errfuns/enotnam.S new file mode 100644 index 00000000..23628f84 --- /dev/null +++ b/libc/sysv/errfuns/enotnam.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enotnam: + .leafprologue + .profilable + mov ENOTNAM(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enotnam,globl,hidden diff --git a/libc/sysv/errfuns/enotrecoverable.S b/libc/sysv/errfuns/enotrecoverable.S new file mode 100644 index 00000000..dcffb12e --- /dev/null +++ b/libc/sysv/errfuns/enotrecoverable.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enotrecoverable: + .leafprologue + .profilable + mov ENOTRECOVERABLE(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enotrecoverable,globl,hidden diff --git a/libc/sysv/errfuns/enotsock.S b/libc/sysv/errfuns/enotsock.S new file mode 100644 index 00000000..b917618e --- /dev/null +++ b/libc/sysv/errfuns/enotsock.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enotsock: + .leafprologue + .profilable + mov ENOTSOCK(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enotsock,globl,hidden diff --git a/libc/sysv/errfuns/enotsup.S b/libc/sysv/errfuns/enotsup.S new file mode 100644 index 00000000..a64b84ac --- /dev/null +++ b/libc/sysv/errfuns/enotsup.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enotsup: + .leafprologue + .profilable + mov ENOTSUP(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enotsup,globl,hidden diff --git a/libc/sysv/errfuns/enotty.S b/libc/sysv/errfuns/enotty.S new file mode 100644 index 00000000..a53172d2 --- /dev/null +++ b/libc/sysv/errfuns/enotty.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +enotty: .leafprologue + .profilable + mov ENOTTY(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enotty,globl,hidden diff --git a/libc/sysv/errfuns/enotuniq.S b/libc/sysv/errfuns/enotuniq.S new file mode 100644 index 00000000..d361c48e --- /dev/null +++ b/libc/sysv/errfuns/enotuniq.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +enotuniq: + .leafprologue + .profilable + mov ENOTUNIQ(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enotuniq,globl,hidden diff --git a/libc/sysv/errfuns/enxio.S b/libc/sysv/errfuns/enxio.S new file mode 100644 index 00000000..ec2a8a23 --- /dev/null +++ b/libc/sysv/errfuns/enxio.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +enxio: .leafprologue + .profilable + mov ENXIO(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn enxio,globl,hidden diff --git a/libc/sysv/errfuns/eopnotsupp.S b/libc/sysv/errfuns/eopnotsupp.S new file mode 100644 index 00000000..0312b76c --- /dev/null +++ b/libc/sysv/errfuns/eopnotsupp.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +eopnotsupp: + .leafprologue + .profilable + mov EOPNOTSUPP(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eopnotsupp,globl,hidden diff --git a/libc/sysv/errfuns/eoverflow.S b/libc/sysv/errfuns/eoverflow.S new file mode 100644 index 00000000..5d63b71c --- /dev/null +++ b/libc/sysv/errfuns/eoverflow.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +eoverflow: + .leafprologue + .profilable + mov EOVERFLOW(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eoverflow,globl,hidden diff --git a/libc/sysv/errfuns/eownerdead.S b/libc/sysv/errfuns/eownerdead.S new file mode 100644 index 00000000..5c4845ac --- /dev/null +++ b/libc/sysv/errfuns/eownerdead.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +eownerdead: + .leafprologue + .profilable + mov EOWNERDEAD(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eownerdead,globl,hidden diff --git a/libc/sysv/errfuns/eperm.S b/libc/sysv/errfuns/eperm.S new file mode 100644 index 00000000..9e1719dd --- /dev/null +++ b/libc/sysv/errfuns/eperm.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +eperm: .leafprologue + .profilable + mov EPERM(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eperm,globl,hidden diff --git a/libc/sysv/errfuns/epfnosupport.S b/libc/sysv/errfuns/epfnosupport.S new file mode 100644 index 00000000..dade790f --- /dev/null +++ b/libc/sysv/errfuns/epfnosupport.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +epfnosupport: + .leafprologue + .profilable + mov EPFNOSUPPORT(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn epfnosupport,globl,hidden diff --git a/libc/sysv/errfuns/epipe.S b/libc/sysv/errfuns/epipe.S new file mode 100644 index 00000000..f0eb5a08 --- /dev/null +++ b/libc/sysv/errfuns/epipe.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +epipe: .leafprologue + .profilable + mov EPIPE(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn epipe,globl,hidden diff --git a/libc/sysv/errfuns/eproto.S b/libc/sysv/errfuns/eproto.S new file mode 100644 index 00000000..65ac042c --- /dev/null +++ b/libc/sysv/errfuns/eproto.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +eproto: .leafprologue + .profilable + mov EPROTO(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eproto,globl,hidden diff --git a/libc/sysv/errfuns/eprotonosupport.S b/libc/sysv/errfuns/eprotonosupport.S new file mode 100644 index 00000000..2968aae4 --- /dev/null +++ b/libc/sysv/errfuns/eprotonosupport.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +eprotonosupport: + .leafprologue + .profilable + mov EPROTONOSUPPORT(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eprotonosupport,globl,hidden diff --git a/libc/sysv/errfuns/eprototype.S b/libc/sysv/errfuns/eprototype.S new file mode 100644 index 00000000..78cefc6c --- /dev/null +++ b/libc/sysv/errfuns/eprototype.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +eprototype: + .leafprologue + .profilable + mov EPROTOTYPE(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eprototype,globl,hidden diff --git a/libc/sysv/errfuns/erange.S b/libc/sysv/errfuns/erange.S new file mode 100644 index 00000000..fd72d11a --- /dev/null +++ b/libc/sysv/errfuns/erange.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +erange: .leafprologue + .profilable + mov ERANGE(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn erange,globl,hidden diff --git a/libc/sysv/errfuns/eremchg.S b/libc/sysv/errfuns/eremchg.S new file mode 100644 index 00000000..3f681ebe --- /dev/null +++ b/libc/sysv/errfuns/eremchg.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +eremchg: + .leafprologue + .profilable + mov EREMCHG(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eremchg,globl,hidden diff --git a/libc/sysv/errfuns/eremote.S b/libc/sysv/errfuns/eremote.S new file mode 100644 index 00000000..ee74ad58 --- /dev/null +++ b/libc/sysv/errfuns/eremote.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +eremote: + .leafprologue + .profilable + mov EREMOTE(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eremote,globl,hidden diff --git a/libc/sysv/errfuns/eremoteio.S b/libc/sysv/errfuns/eremoteio.S new file mode 100644 index 00000000..a57e5f30 --- /dev/null +++ b/libc/sysv/errfuns/eremoteio.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +eremoteio: + .leafprologue + .profilable + mov EREMOTEIO(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eremoteio,globl,hidden diff --git a/libc/sysv/errfuns/erestart.S b/libc/sysv/errfuns/erestart.S new file mode 100644 index 00000000..d06e1f01 --- /dev/null +++ b/libc/sysv/errfuns/erestart.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +erestart: + .leafprologue + .profilable + mov ERESTART(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn erestart,globl,hidden diff --git a/libc/sysv/errfuns/erfkill.S b/libc/sysv/errfuns/erfkill.S new file mode 100644 index 00000000..ae50849c --- /dev/null +++ b/libc/sysv/errfuns/erfkill.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +erfkill: + .leafprologue + .profilable + mov ERFKILL(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn erfkill,globl,hidden diff --git a/libc/sysv/errfuns/erofs.S b/libc/sysv/errfuns/erofs.S new file mode 100644 index 00000000..c3e08ca6 --- /dev/null +++ b/libc/sysv/errfuns/erofs.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +erofs: .leafprologue + .profilable + mov EROFS(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn erofs,globl,hidden diff --git a/libc/sysv/errfuns/eshutdown.S b/libc/sysv/errfuns/eshutdown.S new file mode 100644 index 00000000..225826f9 --- /dev/null +++ b/libc/sysv/errfuns/eshutdown.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +eshutdown: + .leafprologue + .profilable + mov ESHUTDOWN(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eshutdown,globl,hidden diff --git a/libc/sysv/errfuns/esocktnosupport.S b/libc/sysv/errfuns/esocktnosupport.S new file mode 100644 index 00000000..bedd8787 --- /dev/null +++ b/libc/sysv/errfuns/esocktnosupport.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +esocktnosupport: + .leafprologue + .profilable + mov ESOCKTNOSUPPORT(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn esocktnosupport,globl,hidden diff --git a/libc/sysv/errfuns/espipe.S b/libc/sysv/errfuns/espipe.S new file mode 100644 index 00000000..8de24faf --- /dev/null +++ b/libc/sysv/errfuns/espipe.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +espipe: .leafprologue + .profilable + mov ESPIPE(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn espipe,globl,hidden diff --git a/libc/sysv/errfuns/esrch.S b/libc/sysv/errfuns/esrch.S new file mode 100644 index 00000000..234b1efc --- /dev/null +++ b/libc/sysv/errfuns/esrch.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +esrch: .leafprologue + .profilable + mov ESRCH(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn esrch,globl,hidden diff --git a/libc/sysv/errfuns/esrmnt.S b/libc/sysv/errfuns/esrmnt.S new file mode 100644 index 00000000..f5b84b31 --- /dev/null +++ b/libc/sysv/errfuns/esrmnt.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +esrmnt: .leafprologue + .profilable + mov ESRMNT(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn esrmnt,globl,hidden diff --git a/libc/sysv/errfuns/estale.S b/libc/sysv/errfuns/estale.S new file mode 100644 index 00000000..333c02be --- /dev/null +++ b/libc/sysv/errfuns/estale.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +estale: .leafprologue + .profilable + mov ESTALE(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn estale,globl,hidden diff --git a/libc/sysv/errfuns/estrpipe.S b/libc/sysv/errfuns/estrpipe.S new file mode 100644 index 00000000..7808a413 --- /dev/null +++ b/libc/sysv/errfuns/estrpipe.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +estrpipe: + .leafprologue + .profilable + mov ESTRPIPE(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn estrpipe,globl,hidden diff --git a/libc/sysv/errfuns/etime.S b/libc/sysv/errfuns/etime.S new file mode 100644 index 00000000..69025d51 --- /dev/null +++ b/libc/sysv/errfuns/etime.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +etime: .leafprologue + .profilable + mov ETIME(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn etime,globl,hidden diff --git a/libc/sysv/errfuns/etimedout.S b/libc/sysv/errfuns/etimedout.S new file mode 100644 index 00000000..d15262af --- /dev/null +++ b/libc/sysv/errfuns/etimedout.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +etimedout: + .leafprologue + .profilable + mov ETIMEDOUT(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn etimedout,globl,hidden diff --git a/libc/sysv/errfuns/etoomanyrefs.S b/libc/sysv/errfuns/etoomanyrefs.S new file mode 100644 index 00000000..676bec0f --- /dev/null +++ b/libc/sysv/errfuns/etoomanyrefs.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +etoomanyrefs: + .leafprologue + .profilable + mov ETOOMANYREFS(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn etoomanyrefs,globl,hidden diff --git a/libc/sysv/errfuns/etxtbsy.S b/libc/sysv/errfuns/etxtbsy.S new file mode 100644 index 00000000..a2714716 --- /dev/null +++ b/libc/sysv/errfuns/etxtbsy.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +etxtbsy: + .leafprologue + .profilable + mov ETXTBSY(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn etxtbsy,globl,hidden diff --git a/libc/sysv/errfuns/euclean.S b/libc/sysv/errfuns/euclean.S new file mode 100644 index 00000000..75d57259 --- /dev/null +++ b/libc/sysv/errfuns/euclean.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +euclean: + .leafprologue + .profilable + mov EUCLEAN(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn euclean,globl,hidden diff --git a/libc/sysv/errfuns/eunatch.S b/libc/sysv/errfuns/eunatch.S new file mode 100644 index 00000000..bea1f37c --- /dev/null +++ b/libc/sysv/errfuns/eunatch.S @@ -0,0 +1,12 @@ +#include "libc/macros.h" +.text.unlikely + +eunatch: + .leafprologue + .profilable + mov EUNATCH(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eunatch,globl,hidden diff --git a/libc/sysv/errfuns/eusers.S b/libc/sysv/errfuns/eusers.S new file mode 100644 index 00000000..de6b3e7b --- /dev/null +++ b/libc/sysv/errfuns/eusers.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +eusers: .leafprologue + .profilable + mov EUSERS(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn eusers,globl,hidden diff --git a/libc/sysv/errfuns/exdev.S b/libc/sysv/errfuns/exdev.S new file mode 100644 index 00000000..030ff539 --- /dev/null +++ b/libc/sysv/errfuns/exdev.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +exdev: .leafprologue + .profilable + mov EXDEV(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn exdev,globl,hidden diff --git a/libc/sysv/errfuns/exfull.S b/libc/sysv/errfuns/exfull.S new file mode 100644 index 00000000..5a0365af --- /dev/null +++ b/libc/sysv/errfuns/exfull.S @@ -0,0 +1,11 @@ +#include "libc/macros.h" +.text.unlikely + +exfull: .leafprologue + .profilable + mov EXFULL(%rip),%eax + mov %eax,errno(%rip) + push $-1 + pop %rax + .leafepilogue + .endfn exfull,globl,hidden diff --git a/libc/sysv/g_syscount.S b/libc/sysv/g_syscount.S new file mode 100644 index 00000000..ea0db96b --- /dev/null +++ b/libc/sysv/g_syscount.S @@ -0,0 +1,53 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ RII System Five system call counter. +/ +/ Referencing this symbol will cause systemfive() to be hooked +/ for the purpose of counting non-Windows system calls. Please +/ note wrappers may still short circuit calls sometimes, which +/ wouldn't impact this counter. + .bss + .align 8 +g_syscount: + .quad 0 + .endobj g_syscount,globl + .previous + + .initbss 701,_init_g_syscount +g_syscount_next: + .quad 0 + .endobj g_syscount_next + .previous + +syscount: + incq g_syscount(%rip) + jmp *g_syscount_next(%rip) + .endfn syscount + .previous + + .init.start 701,_init_g_syscount + mov systemfive(%rip),%rax + stosq + ezlea syscount,ax + mov %rax,systemfive(%rip) + .init.end 701,_init_g_syscount diff --git a/libc/sysv/gen.sh b/libc/sysv/gen.sh new file mode 100644 index 00000000..f8368ba3 --- /dev/null +++ b/libc/sysv/gen.sh @@ -0,0 +1,63 @@ +/*bin/echo ' -*- mode:sh; indent-tabs-mode:nil; tab-width:8; coding:utf-8 -*-│ +│vi: set net ft=sh ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚────────────────────────────────────────────────────────────────'>/dev/null #*/ +mkdir -p $dir +rm -f $dir/*.s $dir/*.S + +scall() { + { + echo ".include \"o/libc/sysv/macros.inc\"" + echo ".scall" "$@" + } >"$dir/${1/$/-}.s" +} + +syscon() { + { + echo ".include \"libc/sysv/consts/syscon.inc\"" + echo ".syscon" "$@" + } >"$dir/${2/$/-}.s" +} + +sysstr() { + { + echo ".include \"o/libc/sysv/macros.inc\"" + echo ".sysstr $1 \"$2\"" + } >"$dir/${1/$/-}.s" +} + +errfun() { + NAME="$1" + ERRNO="$2" + { + printf '#include "libc/macros.h"\n.text.unlikely\n\n' + printf '%s:' "$NAME" + if [ "${#NAME}" -gt 6 ]; then + printf '\n' + fi + printf ' .leafprologue + .profilable + mov %s(%%rip),%%eax + mov %%eax,errno(%%rip) + push $-1 + pop %%rax + .leafepilogue + .endfn %s,globl,hidden +' "$ERRNO" "$NAME" + } >"$dir/${1/$/-}.S" +} diff --git a/libc/sysv/machcalls.sh b/libc/sysv/machcalls.sh new file mode 100755 index 00000000..cccf20a2 --- /dev/null +++ b/libc/sysv/machcalls.sh @@ -0,0 +1,83 @@ +/*bin/echo ' -*- mode:sh; indent-tabs-mode:nil; tab-width:8; coding:utf-8 -*-│ +│vi: set net ft=sh ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚────────────────────────────────────────────────────────────────'>/dev/null #*/ +dir=libc/sysv/machcalls +. libc/sysv/gen.sh + +# NeXSTEP Carnegie Melon Mach Microkernel +# » so many context switches GNU/Systemd┐ +# Mac OS X┐ │ +# FreeBSD┐ │ │ +# OpenBSD┐ │ ┌─│───│── XnuClass{1:Mach,2:Unix} +# ┌─┴┐┌─┴┐│┌┴┐┌─┴┐ +scall _kernelrpc_mach_vm_allocate_trap 0xffffffff100affff globl +scall _kernelrpc_mach_vm_purgable_control_trap 0xffffffff100bffff globl +scall _kernelrpc_mach_vm_deallocate_trap 0xffffffff100cffff globl +scall _kernelrpc_mach_vm_protect_trap 0xffffffff100effff globl +scall _kernelrpc_mach_vm_map_trap 0xffffffff100fffff globl +scall _kernelrpc_mach_port_allocate_trap 0xffffffff1010ffff globl +scall _kernelrpc_mach_port_destroy_trap 0xffffffff1011ffff globl +scall _kernelrpc_mach_port_deallocate_trap 0xffffffff1012ffff globl +scall _kernelrpc_mach_port_mod_refs_trap 0xffffffff1013ffff globl +scall _kernelrpc_mach_port_move_member_trap 0xffffffff1014ffff globl +scall _kernelrpc_mach_port_insert_right_trap 0xffffffff1015ffff globl +scall _kernelrpc_mach_port_insert_member_trap 0xffffffff1016ffff globl +scall _kernelrpc_mach_port_extract_member_trap 0xffffffff1017ffff globl +scall _kernelrpc_mach_port_construct_trap 0xffffffff1018ffff globl +scall _kernelrpc_mach_port_destruct_trap 0xffffffff1019ffff globl +scall mach_reply_port 0xffffffff101affff globl +scall thread_self_trap 0xffffffff101bffff globl +scall task_self_trap 0xffffffff101cffff globl +scall host_self_trap 0xffffffff101dffff globl +scall mach_msg_trap 0xffffffff101fffff globl +scall mach_msg_overwrite_trap 0xffffffff1020ffff globl +scall semaphore_signal_trap 0xffffffff1021ffff globl +scall semaphore_signal_all_trap 0xffffffff1022ffff globl +scall semaphore_signal_thread_trap 0xffffffff1023ffff globl +scall semaphore_wait_trap 0xffffffff1024ffff globl +scall semaphore_wait_signal_trap 0xffffffff1025ffff globl +scall semaphore_timedwait_trap 0xffffffff1026ffff globl +scall semaphore_timedwait_signal_trap 0xffffffff1027ffff globl +scall _kernelrpc_mach_port_guard_trap 0xffffffff1029ffff globl +scall _kernelrpc_mach_port_unguard_trap 0xffffffff102affff globl +scall mach_generate_activity_id 0xffffffff102bffff globl +scall task_name_for_pid 0xffffffff102cffff globl +scall task_for_pid 0xffffffff102dffff globl +scall pid_for_task 0xffffffff102effff globl +scall macx_swapon 0xffffffff1030ffff globl +scall macx_swapoff 0xffffffff1031ffff globl +scall thread_get_special_reply_port 0xffffffff1032ffff globl +scall macx_triggers 0xffffffff1033ffff globl +scall macx_backing_store_suspend 0xffffffff1034ffff globl +scall macx_backing_store_recovery 0xffffffff1035ffff globl +scall pfz_exit 0xffffffff103affff globl +scall swtch_pri 0xffffffff103bffff globl +scall swtch 0xffffffff103cffff globl +scall thread_switch 0xffffffff103dffff globl +scall clock_sleep_trap 0xffffffff103effff globl +scall host_create_mach_voucher_trap 0xffffffff1046ffff globl +scall mach_voucher_extract_attr_recipe_trap 0xffffffff1048ffff globl +scall mach_timebase_info_trap 0xffffffff1059ffff globl +scall mach_wait_until_trap 0xffffffff105affff globl +scall mk_timer_create_trap 0xffffffff105bffff globl +scall mk_timer_destroy_trap 0xffffffff105cffff globl +scall mk_timer_arm_trap 0xffffffff105dffff globl +scall mk_timer_cancel_trap 0xffffffff105effff globl +scall mk_timer_arm_leeway_trap 0xffffffff105fffff globl +scall iokit_user_client_trap 0xffffffff1064ffff globl diff --git a/libc/sysv/machcalls/_kernelrpc_mach_port_allocate_trap.s b/libc/sysv/machcalls/_kernelrpc_mach_port_allocate_trap.s new file mode 100644 index 00000000..f0beebe3 --- /dev/null +++ b/libc/sysv/machcalls/_kernelrpc_mach_port_allocate_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _kernelrpc_mach_port_allocate_trap 0xffffffff1010ffff globl diff --git a/libc/sysv/machcalls/_kernelrpc_mach_port_construct_trap.s b/libc/sysv/machcalls/_kernelrpc_mach_port_construct_trap.s new file mode 100644 index 00000000..d4a8ad2f --- /dev/null +++ b/libc/sysv/machcalls/_kernelrpc_mach_port_construct_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _kernelrpc_mach_port_construct_trap 0xffffffff1018ffff globl diff --git a/libc/sysv/machcalls/_kernelrpc_mach_port_deallocate_trap.s b/libc/sysv/machcalls/_kernelrpc_mach_port_deallocate_trap.s new file mode 100644 index 00000000..f6990261 --- /dev/null +++ b/libc/sysv/machcalls/_kernelrpc_mach_port_deallocate_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _kernelrpc_mach_port_deallocate_trap 0xffffffff1012ffff globl diff --git a/libc/sysv/machcalls/_kernelrpc_mach_port_destroy_trap.s b/libc/sysv/machcalls/_kernelrpc_mach_port_destroy_trap.s new file mode 100644 index 00000000..5c54d82d --- /dev/null +++ b/libc/sysv/machcalls/_kernelrpc_mach_port_destroy_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _kernelrpc_mach_port_destroy_trap 0xffffffff1011ffff globl diff --git a/libc/sysv/machcalls/_kernelrpc_mach_port_destruct_trap.s b/libc/sysv/machcalls/_kernelrpc_mach_port_destruct_trap.s new file mode 100644 index 00000000..c5ec66e4 --- /dev/null +++ b/libc/sysv/machcalls/_kernelrpc_mach_port_destruct_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _kernelrpc_mach_port_destruct_trap 0xffffffff1019ffff globl diff --git a/libc/sysv/machcalls/_kernelrpc_mach_port_extract_member_trap.s b/libc/sysv/machcalls/_kernelrpc_mach_port_extract_member_trap.s new file mode 100644 index 00000000..0dc3f05f --- /dev/null +++ b/libc/sysv/machcalls/_kernelrpc_mach_port_extract_member_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _kernelrpc_mach_port_extract_member_trap 0xffffffff1017ffff globl diff --git a/libc/sysv/machcalls/_kernelrpc_mach_port_guard_trap.s b/libc/sysv/machcalls/_kernelrpc_mach_port_guard_trap.s new file mode 100644 index 00000000..48ec6d72 --- /dev/null +++ b/libc/sysv/machcalls/_kernelrpc_mach_port_guard_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _kernelrpc_mach_port_guard_trap 0xffffffff1029ffff globl diff --git a/libc/sysv/machcalls/_kernelrpc_mach_port_insert_member_trap.s b/libc/sysv/machcalls/_kernelrpc_mach_port_insert_member_trap.s new file mode 100644 index 00000000..bd5ef3da --- /dev/null +++ b/libc/sysv/machcalls/_kernelrpc_mach_port_insert_member_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _kernelrpc_mach_port_insert_member_trap 0xffffffff1016ffff globl diff --git a/libc/sysv/machcalls/_kernelrpc_mach_port_insert_right_trap.s b/libc/sysv/machcalls/_kernelrpc_mach_port_insert_right_trap.s new file mode 100644 index 00000000..db08f732 --- /dev/null +++ b/libc/sysv/machcalls/_kernelrpc_mach_port_insert_right_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _kernelrpc_mach_port_insert_right_trap 0xffffffff1015ffff globl diff --git a/libc/sysv/machcalls/_kernelrpc_mach_port_mod_refs_trap.s b/libc/sysv/machcalls/_kernelrpc_mach_port_mod_refs_trap.s new file mode 100644 index 00000000..c1fd2845 --- /dev/null +++ b/libc/sysv/machcalls/_kernelrpc_mach_port_mod_refs_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _kernelrpc_mach_port_mod_refs_trap 0xffffffff1013ffff globl diff --git a/libc/sysv/machcalls/_kernelrpc_mach_port_move_member_trap.s b/libc/sysv/machcalls/_kernelrpc_mach_port_move_member_trap.s new file mode 100644 index 00000000..7ad4e042 --- /dev/null +++ b/libc/sysv/machcalls/_kernelrpc_mach_port_move_member_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _kernelrpc_mach_port_move_member_trap 0xffffffff1014ffff globl diff --git a/libc/sysv/machcalls/_kernelrpc_mach_port_unguard_trap.s b/libc/sysv/machcalls/_kernelrpc_mach_port_unguard_trap.s new file mode 100644 index 00000000..346a8e90 --- /dev/null +++ b/libc/sysv/machcalls/_kernelrpc_mach_port_unguard_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _kernelrpc_mach_port_unguard_trap 0xffffffff102affff globl diff --git a/libc/sysv/machcalls/_kernelrpc_mach_vm_allocate_trap.s b/libc/sysv/machcalls/_kernelrpc_mach_vm_allocate_trap.s new file mode 100644 index 00000000..a98ebfc3 --- /dev/null +++ b/libc/sysv/machcalls/_kernelrpc_mach_vm_allocate_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _kernelrpc_mach_vm_allocate_trap 0xffffffff100affff globl diff --git a/libc/sysv/machcalls/_kernelrpc_mach_vm_deallocate_trap.s b/libc/sysv/machcalls/_kernelrpc_mach_vm_deallocate_trap.s new file mode 100644 index 00000000..6fce9c85 --- /dev/null +++ b/libc/sysv/machcalls/_kernelrpc_mach_vm_deallocate_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _kernelrpc_mach_vm_deallocate_trap 0xffffffff100cffff globl diff --git a/libc/sysv/machcalls/_kernelrpc_mach_vm_map_trap.s b/libc/sysv/machcalls/_kernelrpc_mach_vm_map_trap.s new file mode 100644 index 00000000..e85d65e8 --- /dev/null +++ b/libc/sysv/machcalls/_kernelrpc_mach_vm_map_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _kernelrpc_mach_vm_map_trap 0xffffffff100fffff globl diff --git a/libc/sysv/machcalls/_kernelrpc_mach_vm_protect_trap.s b/libc/sysv/machcalls/_kernelrpc_mach_vm_protect_trap.s new file mode 100644 index 00000000..e49e397c --- /dev/null +++ b/libc/sysv/machcalls/_kernelrpc_mach_vm_protect_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _kernelrpc_mach_vm_protect_trap 0xffffffff100effff globl diff --git a/libc/sysv/machcalls/_kernelrpc_mach_vm_purgable_control_trap.s b/libc/sysv/machcalls/_kernelrpc_mach_vm_purgable_control_trap.s new file mode 100644 index 00000000..8282997b --- /dev/null +++ b/libc/sysv/machcalls/_kernelrpc_mach_vm_purgable_control_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall _kernelrpc_mach_vm_purgable_control_trap 0xffffffff100bffff globl diff --git a/libc/sysv/machcalls/clock_sleep_trap.s b/libc/sysv/machcalls/clock_sleep_trap.s new file mode 100644 index 00000000..a0133c56 --- /dev/null +++ b/libc/sysv/machcalls/clock_sleep_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall clock_sleep_trap 0xffffffff103effff globl diff --git a/libc/sysv/machcalls/host_create_mach_voucher_trap.s b/libc/sysv/machcalls/host_create_mach_voucher_trap.s new file mode 100644 index 00000000..48f54eb2 --- /dev/null +++ b/libc/sysv/machcalls/host_create_mach_voucher_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall host_create_mach_voucher_trap 0xffffffff1046ffff globl diff --git a/libc/sysv/machcalls/host_self_trap.s b/libc/sysv/machcalls/host_self_trap.s new file mode 100644 index 00000000..78adbeab --- /dev/null +++ b/libc/sysv/machcalls/host_self_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall host_self_trap 0xffffffff101dffff globl diff --git a/libc/sysv/machcalls/iokit_user_client_trap.s b/libc/sysv/machcalls/iokit_user_client_trap.s new file mode 100644 index 00000000..4060cc2e --- /dev/null +++ b/libc/sysv/machcalls/iokit_user_client_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall iokit_user_client_trap 0xffffffff1064ffff globl diff --git a/libc/sysv/machcalls/mach_generate_activity_id.s b/libc/sysv/machcalls/mach_generate_activity_id.s new file mode 100644 index 00000000..0d47ab18 --- /dev/null +++ b/libc/sysv/machcalls/mach_generate_activity_id.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mach_generate_activity_id 0xffffffff102bffff globl diff --git a/libc/sysv/machcalls/mach_msg_overwrite_trap.s b/libc/sysv/machcalls/mach_msg_overwrite_trap.s new file mode 100644 index 00000000..0bd8fb3e --- /dev/null +++ b/libc/sysv/machcalls/mach_msg_overwrite_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mach_msg_overwrite_trap 0xffffffff1020ffff globl diff --git a/libc/sysv/machcalls/mach_msg_trap.s b/libc/sysv/machcalls/mach_msg_trap.s new file mode 100644 index 00000000..4b91fc70 --- /dev/null +++ b/libc/sysv/machcalls/mach_msg_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mach_msg_trap 0xffffffff101fffff globl diff --git a/libc/sysv/machcalls/mach_reply_port.s b/libc/sysv/machcalls/mach_reply_port.s new file mode 100644 index 00000000..519a321e --- /dev/null +++ b/libc/sysv/machcalls/mach_reply_port.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mach_reply_port 0xffffffff101affff globl diff --git a/libc/sysv/machcalls/mach_timebase_info_trap.s b/libc/sysv/machcalls/mach_timebase_info_trap.s new file mode 100644 index 00000000..37bf47c0 --- /dev/null +++ b/libc/sysv/machcalls/mach_timebase_info_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mach_timebase_info_trap 0xffffffff1059ffff globl diff --git a/libc/sysv/machcalls/mach_voucher_extract_attr_recipe_trap.s b/libc/sysv/machcalls/mach_voucher_extract_attr_recipe_trap.s new file mode 100644 index 00000000..bf311967 --- /dev/null +++ b/libc/sysv/machcalls/mach_voucher_extract_attr_recipe_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mach_voucher_extract_attr_recipe_trap 0xffffffff1048ffff globl diff --git a/libc/sysv/machcalls/mach_wait_until_trap.s b/libc/sysv/machcalls/mach_wait_until_trap.s new file mode 100644 index 00000000..a26ffa75 --- /dev/null +++ b/libc/sysv/machcalls/mach_wait_until_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mach_wait_until_trap 0xffffffff105affff globl diff --git a/libc/sysv/machcalls/macx_backing_store_recovery.s b/libc/sysv/machcalls/macx_backing_store_recovery.s new file mode 100644 index 00000000..78ad96af --- /dev/null +++ b/libc/sysv/machcalls/macx_backing_store_recovery.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall macx_backing_store_recovery 0xffffffff1035ffff globl diff --git a/libc/sysv/machcalls/macx_backing_store_suspend.s b/libc/sysv/machcalls/macx_backing_store_suspend.s new file mode 100644 index 00000000..0fedb665 --- /dev/null +++ b/libc/sysv/machcalls/macx_backing_store_suspend.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall macx_backing_store_suspend 0xffffffff1034ffff globl diff --git a/libc/sysv/machcalls/macx_swapoff.s b/libc/sysv/machcalls/macx_swapoff.s new file mode 100644 index 00000000..eb40cd90 --- /dev/null +++ b/libc/sysv/machcalls/macx_swapoff.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall macx_swapoff 0xffffffff1031ffff globl diff --git a/libc/sysv/machcalls/macx_swapon.s b/libc/sysv/machcalls/macx_swapon.s new file mode 100644 index 00000000..b1962565 --- /dev/null +++ b/libc/sysv/machcalls/macx_swapon.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall macx_swapon 0xffffffff1030ffff globl diff --git a/libc/sysv/machcalls/macx_triggers.s b/libc/sysv/machcalls/macx_triggers.s new file mode 100644 index 00000000..f5757765 --- /dev/null +++ b/libc/sysv/machcalls/macx_triggers.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall macx_triggers 0xffffffff1033ffff globl diff --git a/libc/sysv/machcalls/mk_timer_arm_leeway_trap.s b/libc/sysv/machcalls/mk_timer_arm_leeway_trap.s new file mode 100644 index 00000000..d78d2c82 --- /dev/null +++ b/libc/sysv/machcalls/mk_timer_arm_leeway_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mk_timer_arm_leeway_trap 0xffffffff105fffff globl diff --git a/libc/sysv/machcalls/mk_timer_arm_trap.s b/libc/sysv/machcalls/mk_timer_arm_trap.s new file mode 100644 index 00000000..c53b66d1 --- /dev/null +++ b/libc/sysv/machcalls/mk_timer_arm_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mk_timer_arm_trap 0xffffffff105dffff globl diff --git a/libc/sysv/machcalls/mk_timer_cancel_trap.s b/libc/sysv/machcalls/mk_timer_cancel_trap.s new file mode 100644 index 00000000..42516d6c --- /dev/null +++ b/libc/sysv/machcalls/mk_timer_cancel_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mk_timer_cancel_trap 0xffffffff105effff globl diff --git a/libc/sysv/machcalls/mk_timer_create_trap.s b/libc/sysv/machcalls/mk_timer_create_trap.s new file mode 100644 index 00000000..0dbe04af --- /dev/null +++ b/libc/sysv/machcalls/mk_timer_create_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mk_timer_create_trap 0xffffffff105bffff globl diff --git a/libc/sysv/machcalls/mk_timer_destroy_trap.s b/libc/sysv/machcalls/mk_timer_destroy_trap.s new file mode 100644 index 00000000..83cd71d3 --- /dev/null +++ b/libc/sysv/machcalls/mk_timer_destroy_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall mk_timer_destroy_trap 0xffffffff105cffff globl diff --git a/libc/sysv/machcalls/pfz_exit.s b/libc/sysv/machcalls/pfz_exit.s new file mode 100644 index 00000000..e1ee6405 --- /dev/null +++ b/libc/sysv/machcalls/pfz_exit.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pfz_exit 0xffffffff103affff globl diff --git a/libc/sysv/machcalls/pid_for_task.s b/libc/sysv/machcalls/pid_for_task.s new file mode 100644 index 00000000..19561af1 --- /dev/null +++ b/libc/sysv/machcalls/pid_for_task.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall pid_for_task 0xffffffff102effff globl diff --git a/libc/sysv/machcalls/semaphore_signal_all_trap.s b/libc/sysv/machcalls/semaphore_signal_all_trap.s new file mode 100644 index 00000000..a45d4df2 --- /dev/null +++ b/libc/sysv/machcalls/semaphore_signal_all_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall semaphore_signal_all_trap 0xffffffff1022ffff globl diff --git a/libc/sysv/machcalls/semaphore_signal_thread_trap.s b/libc/sysv/machcalls/semaphore_signal_thread_trap.s new file mode 100644 index 00000000..adbeba7f --- /dev/null +++ b/libc/sysv/machcalls/semaphore_signal_thread_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall semaphore_signal_thread_trap 0xffffffff1023ffff globl diff --git a/libc/sysv/machcalls/semaphore_signal_trap.s b/libc/sysv/machcalls/semaphore_signal_trap.s new file mode 100644 index 00000000..2fcffaac --- /dev/null +++ b/libc/sysv/machcalls/semaphore_signal_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall semaphore_signal_trap 0xffffffff1021ffff globl diff --git a/libc/sysv/machcalls/semaphore_timedwait_signal_trap.s b/libc/sysv/machcalls/semaphore_timedwait_signal_trap.s new file mode 100644 index 00000000..1911f7fd --- /dev/null +++ b/libc/sysv/machcalls/semaphore_timedwait_signal_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall semaphore_timedwait_signal_trap 0xffffffff1027ffff globl diff --git a/libc/sysv/machcalls/semaphore_timedwait_trap.s b/libc/sysv/machcalls/semaphore_timedwait_trap.s new file mode 100644 index 00000000..4fd568d6 --- /dev/null +++ b/libc/sysv/machcalls/semaphore_timedwait_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall semaphore_timedwait_trap 0xffffffff1026ffff globl diff --git a/libc/sysv/machcalls/semaphore_wait_signal_trap.s b/libc/sysv/machcalls/semaphore_wait_signal_trap.s new file mode 100644 index 00000000..438a741b --- /dev/null +++ b/libc/sysv/machcalls/semaphore_wait_signal_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall semaphore_wait_signal_trap 0xffffffff1025ffff globl diff --git a/libc/sysv/machcalls/semaphore_wait_trap.s b/libc/sysv/machcalls/semaphore_wait_trap.s new file mode 100644 index 00000000..047952ab --- /dev/null +++ b/libc/sysv/machcalls/semaphore_wait_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall semaphore_wait_trap 0xffffffff1024ffff globl diff --git a/libc/sysv/machcalls/swtch.s b/libc/sysv/machcalls/swtch.s new file mode 100644 index 00000000..2d6c7b42 --- /dev/null +++ b/libc/sysv/machcalls/swtch.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall swtch 0xffffffff103cffff globl diff --git a/libc/sysv/machcalls/swtch_pri.s b/libc/sysv/machcalls/swtch_pri.s new file mode 100644 index 00000000..0128c6f0 --- /dev/null +++ b/libc/sysv/machcalls/swtch_pri.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall swtch_pri 0xffffffff103bffff globl diff --git a/libc/sysv/machcalls/task_for_pid.s b/libc/sysv/machcalls/task_for_pid.s new file mode 100644 index 00000000..fb93ebb1 --- /dev/null +++ b/libc/sysv/machcalls/task_for_pid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall task_for_pid 0xffffffff102dffff globl diff --git a/libc/sysv/machcalls/task_name_for_pid.s b/libc/sysv/machcalls/task_name_for_pid.s new file mode 100644 index 00000000..68443f7c --- /dev/null +++ b/libc/sysv/machcalls/task_name_for_pid.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall task_name_for_pid 0xffffffff102cffff globl diff --git a/libc/sysv/machcalls/task_self_trap.s b/libc/sysv/machcalls/task_self_trap.s new file mode 100644 index 00000000..b2ec0796 --- /dev/null +++ b/libc/sysv/machcalls/task_self_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall task_self_trap 0xffffffff101cffff globl diff --git a/libc/sysv/machcalls/thread_get_special_reply_port.s b/libc/sysv/machcalls/thread_get_special_reply_port.s new file mode 100644 index 00000000..b548a292 --- /dev/null +++ b/libc/sysv/machcalls/thread_get_special_reply_port.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall thread_get_special_reply_port 0xffffffff1032ffff globl diff --git a/libc/sysv/machcalls/thread_self_trap.s b/libc/sysv/machcalls/thread_self_trap.s new file mode 100644 index 00000000..619f15a4 --- /dev/null +++ b/libc/sysv/machcalls/thread_self_trap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall thread_self_trap 0xffffffff101bffff globl diff --git a/libc/sysv/machcalls/thread_switch.s b/libc/sysv/machcalls/thread_switch.s new file mode 100644 index 00000000..25670036 --- /dev/null +++ b/libc/sysv/machcalls/thread_switch.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.inc" +.scall thread_switch 0xffffffff103dffff globl diff --git a/libc/sysv/macros.h b/libc/sysv/macros.h new file mode 100644 index 00000000..ba1712ae --- /dev/null +++ b/libc/sysv/macros.h @@ -0,0 +1,57 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#ifndef COSMOPOLITAN_LIBC_SYSV_MACROS_H_ +#define COSMOPOLITAN_LIBC_SYSV_MACROS_H_ +#ifdef __ASSEMBLER__ +#include "libc/macros.inc" +/* clang-format off */ + +/** + * @fileoverview System Five jump slot generator. + * + * We need to pass a magic number to the SYSCALL instruction in %rax. + * That's only possible to do in C using asm() macro wrappers, like in + * Chromium's "System Call Support" library. This technique is simpler + * to implement, gains us object-level ABI compatibility, hookability, + * and the ability to support significantly more functions, without the + * risk of slowing down builds too much with complicated headers. + */ + +.macro .scall name:req num:req kw1 kw2 + .ifnb \kw2 + .align 16 +\name: movabs $\num,%rax + jmp *systemfive(%rip) + .else +\name: push %rbp + mov %rsp,%rbp + movabs $\num,%rax + .hookable + call *systemfive(%rip) + pop %rbp + ret + .endif + .endfn \name,\kw1,\kw2 + .previous +.endm + +/* clang-format on */ +#endif /* __ASSEMBLER__ */ +#endif /* COSMOPOLITAN_LIBC_SYSV_MACROS_H_ */ diff --git a/libc/sysv/restorert.S b/libc/sysv/restorert.S new file mode 100644 index 00000000..8af49144 --- /dev/null +++ b/libc/sysv/restorert.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.inc" + +/ Linux Signal Trampoline (HOLY CODE) + .align 16 +__restore_rt: # @see gdb/amd64-linux-tdep.c + mov $0x000f,%rax # [sic] + syscall + .align 16 + .endfn __restore_rt,globl,hidden + .yoink __FILE__ diff --git a/libc/sysv/stackchkguard.S b/libc/sysv/stackchkguard.S new file mode 100644 index 00000000..49b25468 --- /dev/null +++ b/libc/sysv/stackchkguard.S @@ -0,0 +1,51 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +#include "libc/notice.inc" +#include "libc/sysv/consts/auxv.h" +.yoink __FILE__ + +/ Canary for -fstack-protector. +/ +/ This global is referenced by synthetic code generated by GCC. +/ The -mstack-protector-guard=global flag might need to be passed. +/ +/ @note this value is protected by piro + .initbss 301,_init___stack_chk_guard +__stack_chk_guard: + .quad 0 + .endobj __stack_chk_guard,globl + .previous + + .init.start 301,_init___stack_chk_guard + mov kStartTsc(%rip),%rax + mov AT_RANDOM,%edx # modern linux provides this + test %edx,%edx + jz 1f + pushpop -16,%rcx +0: add $16,%rcx # ax ^= di[1][0] if di[0]=AT_RANDOM + cmpq $0,(%r15,%rcx) # %r15 is qword(*auxv)[2] + jz 1f # @see libc/crt/crt.S + cmp %rdx,(%r15,%rcx) + jne 0b + mov 8(%r15,%rcx),%rcx + xor (%rcx),%rax +1: stosq + .init.end 301,_init___stack_chk_guard diff --git a/libc/sysv/stubs/free.S b/libc/sysv/stubs/free.S new file mode 100644 index 00000000..d4698261 --- /dev/null +++ b/libc/sysv/stubs/free.S @@ -0,0 +1,24 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +#include "libc/notice.inc" + +free: ret + .endfn free,weak diff --git a/libc/sysv/stubs/malloc.S b/libc/sysv/stubs/malloc.S new file mode 100644 index 00000000..9523953e --- /dev/null +++ b/libc/sysv/stubs/malloc.S @@ -0,0 +1,30 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +#include "libc/notice.inc" + +malloc: push %rbp + mov %rsp,%rbp + mov ENOMEM(%rip),%eax + mov %eax,errno(%rip) + pushpop -1,%rax + pop %rbp + ret + .endfn malloc,weak diff --git a/libc/sysv/stubs/realloc.S b/libc/sysv/stubs/realloc.S new file mode 100644 index 00000000..5c7f2b6d --- /dev/null +++ b/libc/sysv/stubs/realloc.S @@ -0,0 +1,30 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +#include "libc/notice.inc" + +realloc:push %rbp + mov %rsp,%rbp + mov ENOMEM(%rip),%eax + mov %eax,errno(%rip) + pushpop -1,%rax + pop %rbp + ret + .endfn realloc,weak diff --git a/libc/sysv/syscall.S b/libc/sysv/syscall.S new file mode 100644 index 00000000..7a6bf912 --- /dev/null +++ b/libc/sysv/syscall.S @@ -0,0 +1,44 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +/ Performs raw System Five system call. +/ +/ This function provides a direct path into system call support +/ that's friendly to C code, since it doesn't need an intermediate +/ thunk. It only supports arities up to six, since there's no way +/ to do more safely; this isn't a problem with Linux, although +/ certain BSD calls may not be available. +/ +/ @param %rdi is system call ordinal, which isn't translated, +/ and must be correct for the underlying host system +/ @param %rsi,%rdx,%rcx,%r8,%r9 may supply parameters 1 through 5 +/ @param sixth is optionally pushed on the stack before call +/ @return %rax has result, or -1 w/ errno on failure +syscall:mov %rdi,%rax + mov %rsi,%rdi + mov %rdx,%rsi + mov %rcx,%rdx + mov %r8,%rcx # ← intended + mov %r9,%r8 + mov 8(%rsp),%r9 + jmp *systemfive(%rip) + .endfn syscall,globl + .yoink __FILE__ diff --git a/libc/sysv/syscalls.sh b/libc/sysv/syscalls.sh new file mode 100755 index 00000000..87a37ffc --- /dev/null +++ b/libc/sysv/syscalls.sh @@ -0,0 +1,825 @@ +/*bin/echo ' -*- mode:sh; indent-tabs-mode:nil; tab-width:8; coding:utf-8 -*-│ +│vi: set net ft=sh ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚────────────────────────────────────────────────────────────────'>/dev/null #*/ +dir=libc/sysv/calls +. libc/sysv/gen.sh + +# The Fifth Bell System Interface, Community Edition ┌─────────────────────────┐ +# » so many numbers │ legend │ +# ├─────────────────────────┤ +# Systemd┐ │ ffff │ unavailable │ +# 2.6.18+│ │ $ │ wrapped │ +# Mac OS X┐ │ │ __ │ wrapped twice │ +# 15.6+│ │ └─────────────────────────┘ +# FreeBSD┐ │ │ +# 12+│ ┌─│───│── XnuClass{1:Mach,2:Unix} +# OpenBSD┐ │ │ │ │ +# 6.4│ │ │ │ │ +# Symbol ┌─┴┐┌─┴┐│┬┴┐┌─┴┐ Directives & Commentary +scall 'exit$sysv' 0x00010001200100e7 globl hidden # a.k.a. exit_group +scall 'read$sysv' 0x0003000320030000 globl hidden +scall 'write$sysv' 0x0004000420040001 globl hidden +scall 'open$sysv' 0x0005000520050002 globl hidden +scall 'close$sysv' 0x0006000620060003 globl hidden +scall '__stat$sysv' 0x0026ffff21520004 globl hidden # FreeBSD 11→12 fumble; use fstatat$sysv(); blocked on Android +scall '__fstat$sysv' 0x0035022721530005 globl hidden # needs stat2linux() +scall '__lstat$sysv' 0x0028002821540006 globl hidden # needs stat2linux(); blocked on Android +scall 'poll$sysv' 0x00fc00d120e60007 globl hidden +scall 'ppoll$sysv' 0x006d0221ffff010f globl hidden # consider INTON/INTOFF tutorial in examples/unbourne.c +scall '__lseek$sysv' 0x00c701de20c70008 globl hidden # openbsd:evilpad +scall '__mmap$sysv' 0x00c501dd20c50009 globl hidden # openbsd:pad +scall 'msync$sysv' 0x010000412041001a globl hidden +scall 'mprotect$sysv' 0x004a004a204a000a globl hidden +scall 'munmap$sysv' 0x004900492049000b globl hidden +scall 'sigaction$sysv' 0x002e01a0202e000d globl hidden # rt_sigaction on Lunix +scall 'sigprocmask$sysv' 0x003001542030000e globl hidden # a.k.a. rt_sigprocmask +scall 'ioctl$sysv' 0x0036003620360010 globl hidden +scall '__pread$sysv' 0x00ad01db20990011 globl hidden # a.k.a. pread64; openbsd:pad +scall '__pwrite$sysv' 0x00ae01dc209a0012 globl hidden # a.k.a. pwrite64; openbsd:pad +scall 'readv$sysv' 0x0078007820780013 globl hidden +scall 'writev$sysv' 0x0079007920790014 globl hidden +scall 'access$sysv' 0x0021002120210015 globl hidden +scall '__pipe$sysv' 0x0107021e202a0016 globl hidden # NOTE: pipe2() on FreeBSD; XNU is pipe(void)→eax:edx +scall 'select$sysv' 0x0047005d205d0017 globl hidden +scall pselect 0x006e020a218affff globl +scall pselect6 0xffffffffffff010e globl +scall 'sched_yield$sysv' 0x012a014b103c0018 globl hidden # swtch() on xnu +scall 'mremap$sysv' 0xffffffffffff0019 globl hidden +scall mincore 0x004e004e204e001b globl +scall 'madvise$sysv' 0x004b004b204b001c globl hidden +scall shmget 0x012100e72109001d globl # consider mmap +scall shmat 0x00e400e42106001e globl # consider mmap +scall shmctl 0x012802002107001f globl # consider mmap +scall 'dup$sysv' 0x0029002920290020 globl hidden +scall 'dup2$sysv' 0x005a005a205a0021 globl hidden +scall 'pause$sysv' 0xffffffffffff0022 globl hidden +scall 'nanosleep$sysv' 0x005b00f0ffff0023 globl hidden +scall 'getitimer$sysv' 0x0046005620560024 globl hidden +scall 'setitimer$sysv' 0x0045005320530026 globl hidden +scall 'alarm$sysv' 0xffffffffffff0025 globl hidden +scall 'getpid$sysv' 0x0014001420140027 globl hidden +scall 'sendfile$sysv' 0xffff018921510028 globl hidden # Linux vs. XNU/BSD ABIs very different +scall '__socket$sysv' 0x0061006120610029 globl hidden +scall '__connect$sysv' 0x006200622062002a globl hidden +scall '__accept$sysv' 0x001e0063201e002b globl hidden +scall 'sendto$sysv' 0x008500852085002c globl hidden +scall 'recvfrom$sysv' 0x001d001d201d002d globl hidden +scall 'sendmsg$sysv' 0x001c001c201c002e globl hidden +scall 'recvmsg$sysv' 0x001b001b201b002f globl hidden +scall 'shutdown$sysv' 0x0086008620860030 globl hidden +scall 'bind$sysv' 0x0068006820680031 globl hidden +scall 'listen$sysv' 0x006a006a206a0032 globl hidden +scall '__getsockname$sysv' 0x0020002020200033 globl hidden +scall '__getpeername$sysv' 0x001f008d201f0034 globl hidden +scall 'socketpair$sysv' 0x0087008720870035 globl hidden +scall 'setsockopt$sysv' 0x0069006920690036 globl hidden +scall 'getsockopt$sysv' 0x0076007620760037 globl hidden +scall 'fork$sysv' 0x0002000220020039 globl hidden +scall vfork 0x004200422042003a globl +scall posix_spawn 0xffffffff20f4ffff globl hidden # TODO: put in spawnve() +scall 'execve$sysv' 0x003b003b203b003b globl hidden +scall 'wait4$sysv' 0x000b00072007003d globl hidden +scall 'kill$sysv' 0x007a00252025003e globl hidden # kill(pid, sig, 1) b/c xnu +scall 'killpg$sysv' 0xffff0092ffffffff globl hidden +scall clone 0xffffffffffff0038 globl +scall tkill 0xffffffffffff00c8 globl +scall futex 0x0053ffffffff00ca globl +scall set_robust_list 0xffffffffffff0111 globl +scall get_robust_list 0xffffffffffff0112 globl +scall 'uname$sysv' 0xffff00a4ffff003f globl hidden +scall semget 0x00dd00dd20ff0040 globl # won't polyfill for windows +scall semop 0x012200de21000041 globl # won't polyfill for windows +scall semctl 0x012701fe20fe0042 globl # won't polyfill for windows +scall shmdt 0x00e600e621080043 globl # won't polyfill for windows +scall msgget 0x00e100e121030044 globl # won't polyfill for windows +scall msgsnd 0x00e200e221040045 globl # won't polyfill for windows +scall msgrcv 0x00e300e321050046 globl # won't polyfill for windows +scall msgctl 0x012901ff21020047 globl # won't polyfill for windows +scall 'fcntl$sysv' 0x005c005c205c0048 globl hidden +scall 'flock$sysv' 0x0083008320830049 globl hidden +scall 'fsync$sysv' 0x005f005f205f004a globl hidden +scall 'fdatasync$sysv' 0x005f022620bb004b globl hidden # fsync() on openbsd +scall '__truncate$sysv' 0x00c801df20c8004c globl hidden # openbsd:pad +scall '__ftruncate$sysv' 0x00c901e020c9004d globl hidden # openbsd:pad +scall 'getcwd$sysv' 0x01300146ffff004f globl hidden +scall 'chdir$sysv' 0x000c000c200c0050 globl hidden +scall fchdir 0x000d000d200d0051 globl +scall 'rename$sysv' 0x0080008020800052 globl hidden +scall 'mkdir$sysv' 0x0088008820880053 globl hidden +scall 'rmdir$sysv' 0x0089008920890054 globl hidden +scall 'creat$sysv' 0xffff0008ffff0055 globl hidden +scall 'link$sysv' 0x0009000920090056 globl hidden +scall 'unlink$sysv' 0x000a000a200a0057 globl hidden +scall 'symlink$sysv' 0x0039003920390058 globl hidden +scall readlink 0x003a003a203a0059 globl # usually an anti-pattern +scall 'chmod$sysv' 0x000f000f200f005a globl hidden +scall 'fchmod$sysv' 0x007c007c207c005b globl hidden +scall 'chown$sysv' 0x001000102010005c globl hidden # impl. w/ fchownat() @asyncsignalsafe +scall 'fchown$sysv' 0x007b007b207b005d globl hidden # @asyncsignalsafe +scall 'lchown$sysv' 0x00fe00fe216c005e globl hidden # impl. w/ fchownat() +scall umask 0x003c003c203c005f globl +scall '__gettimeofday$sysv' 0x0043007420740060 globl hidden # xnu esi/edx=0 +scall 'getrlimit$sysv' 0x00c200c220c20061 globl hidden +scall 'getrusage$sysv' 0x0013007520750062 globl hidden +scall 'sysinfo$sysv' 0xffffffffffff0063 globl hidden +scall 'times$sysv' 0xffffffffffff0064 globl hidden +scall ptrace 0x001a001a201a0065 globl +scall syslog 0xffffffffffff0067 globl +scall 'getuid$sysv' 0x0018001820180066 globl hidden +scall 'getgid$sysv' 0x002f002f202f0068 globl hidden +scall 'getppid$sysv' 0x002700272027006e globl hidden +scall getpgrp 0x005100512051006f globl +scall setsid 0x0093009320930070 globl +scall getsid 0x00ff01362136007c globl +scall getpgid 0x00cf00cf20970079 globl +scall setpgid 0x005200522052006d globl +scall geteuid 0x001900192019006b globl +scall getegid 0x002b002b202b006c globl +scall getgroups 0x004f004f204f0073 globl +scall setgroups 0x0050005020500074 globl +scall setreuid 0x007e007e207e0071 globl +scall setregid 0x007f007f207f0072 globl +scall setuid 0x0017001720170069 globl +scall setgid 0x00b500b520b5006a globl +scall 'setresuid$sysv' 0x011a0137ffff0075 globl hidden # polyfilled for xnu +scall 'setresgid$sysv' 0x011c0138ffff0077 globl hidden # polyfilled for xnu +scall getresuid 0x01190168ffff0076 globl # semantics aren't well-defined +scall getresgid 0x011b0169ffff0078 globl # semantics aren't well-defined +scall sigpending 0x003400342034007f globl +scall 'sigsuspend$sysv' 0x006f0155206f0082 globl hidden +scall sigaltstack 0x0120003520350083 globl +scall 'mknod$sysv' 0x000e000e200e0085 globl hidden +scall mknodat 0x014022ffffff0103 globl # FreeBSD 12+ +scall 'mkfifo$sysv' 0x008400842084ffff globl hidden +scall mkfifoat 0x013f01f1ffffffff globl +scall statfs 0x003f022b21590089 globl +scall fstatfs 0x0040022c215a008a globl +scall 'getpriority$sysv' 0x006400642064008c globl hidden +scall 'setpriority$sysv' 0x006000602060008d globl hidden # modern nice() +scall mlock 0x00cb00cb20cb0095 globl +scall munlock 0x00cc00cc20cc0096 globl +scall mlockall 0x010f014421440097 globl +scall munlockall 0x0110014521450098 globl +scall 'setrlimit$sysv' 0x00c300c320c300a0 globl hidden +scall chroot 0x003d003d203d00a1 globl +scall sync 0x00240024202400a2 globl +scall acct 0x00330033203300a3 globl +scall settimeofday 0x0044007a207a00a4 globl +scall mount 0x0015001520a700a5 globl +scall reboot 0x00370037203700a9 globl +scall quotactl 0x0094009420a500b3 globl +scall 'utime$sysv' 0xffffffffffff0084 globl hidden +scall 'utimes$sysv' 0x004c008a208a00eb globl hidden +scall setfsuid 0xffffffffffff007a globl +scall setfsgid 0xffffffffffff007b globl +scall capget 0xffffffffffff007d globl +scall capset 0xffffffffffff007e globl +scall sigtimedwait 0xffff0159ffff0080 globl +scall rt_sigqueueinfo 0xffffffffffff0081 globl +scall personality 0xffffffffffff0087 globl +scall ustat 0xffffffffffff0088 globl +scall sysfs 0xffffffffffff008b globl +scall sched_setparam 0xffff0147ffff008e globl +scall sched_getparam 0xffff0148ffff008f globl +scall sched_setscheduler 0xffff0149ffff0090 globl +scall sched_getscheduler 0xffff014affff0091 globl +scall sched_get_priority_max 0xffff014cffff0092 globl +scall sched_get_priority_min 0xffff014dffff0093 globl +scall sched_rr_get_interval 0xffff014effff0094 globl +scall vhangup 0xffffffffffff0099 globl +scall modify_ldt 0xffffffffffff009a globl +scall pivot_root 0xffffffffffff009b globl +scall _sysctl 0xffffffffffff009c globl +scall prctl 0xffffffffffff009d globl +scall 'arch_prctl$sysv' 0x00a500a5ffff009e globl hidden # sysarch() on bsd +scall adjtimex 0xffffffffffff009f globl +scall umount2 0xffffffffffff00a6 globl +scall swapon 0xffff0055205500a7 globl +scall swapoff 0xffff01a8ffff00a8 globl +scall sethostname 0xffff0058ffff00aa globl +scall setdomainname 0xffff00a3ffff00ab globl +scall iopl 0xffffffffffff00ac globl +scall ioperm 0xffffffffffff00ad globl +scall init_module 0xffffffffffff00af globl +scall delete_module 0xffffffffffff00b0 globl +scall 'gettid$sysv' 0xffffffff211e00ba globl hidden +scall readahead 0xffffffffffff00bb globl # consider fadvise() / madvise() +scall setxattr 0xffffffff20ec00bc globl +scall fsetxattr 0xffffffff20ed00be globl +scall getxattr 0xffffffff20ea00bf globl +scall fgetxattr 0xffffffff20eb00c1 globl +scall listxattr 0xffffffff20f000c2 globl +scall flistxattr 0xffffffff20f100c4 globl +scall removexattr 0xffffffff20ee00c5 globl +scall fremovexattr 0xffffffff20ef00c7 globl +scall lsetxattr 0xffffffffffff00bd globl +scall lgetxattr 0xffffffffffff00c0 globl +scall llistxattr 0xffffffffffff00c3 globl +scall lremovexattr 0xffffffffffff00c6 globl +scall 'sched_setaffinity$sysv' 0xffffffffffff00cb globl hidden +scall sched_getaffinity 0xffffffffffff00cc globl +scall cpuset_getaffinity 0xffff01e7ffffffff globl +scall cpuset_setaffinity 0xffff01e8ffffffff globl +scall io_setup 0xffffffffffff00ce globl +scall io_destroy 0xffffffffffff00cf globl +scall io_getevents 0xffffffffffff00d0 globl +scall io_submit 0xffffffffffff00d1 globl +scall io_cancel 0xffffffffffff00d2 globl +scall lookup_dcookie 0xffffffffffff00d4 globl +scall epoll_create 0xffffffffffff00d5 globl +scall epoll_wait 0xffffffffffff00e8 globl +scall epoll_ctl 0xffffffffffff00e9 globl +scall getdents 0x00630110ffff004e globl hidden +scall set_tid_address 0xffffffffffff00da globl +scall restart_syscall 0xffffffffffff00db globl +scall semtimedop 0xffffffffffff00dc globl +scall 'fadvise$sysv' 0xffff0213ffff00dd globl hidden +scall timer_create 0xffffffffffff00de globl +scall timer_settime 0xffffffffffff00df globl +scall timer_gettime 0xffffffffffff00e0 globl +scall timer_getoverrun 0xffffffffffff00e1 globl +scall timer_delete 0xffffffffffff00e2 globl +scall clock_settime 0x005800e9ffff00e3 globl +scall 'clock_gettime$sysv' 0x005700e8ffff00e4 globl hidden # Linux 2.6+ (c. 2003); XNU uses magic address +scall clock_getres 0x005900eaffff00e5 globl +scall clock_nanosleep 0xffff00f4ffff00e6 globl +scall tgkill 0xffffffffffff00ea globl +scall mbind 0xffffffffffff00ed globl +scall set_mempolicy 0xffffffffffff00ee globl +scall get_mempolicy 0xffffffffffff00ef globl +scall mq_open 0xffffffffffff00f0 globl # won't polyfill +scall mq_unlink 0xffffffffffff00f1 globl # won't polyfill +scall mq_timedsend 0xffffffffffff00f2 globl # won't polyfill +scall mq_timedreceive 0xffffffffffff00f3 globl # won't polyfill +scall mq_notify 0xffffffffffff00f4 globl # won't polyfill +scall mq_getsetattr 0xffffffffffff00f5 globl # won't polyfill +scall kexec_load 0xffffffffffff00f6 globl +scall waitid 0xffffffff20ad00f7 globl # Linux 2.6.9+ +scall add_key 0xffffffffffff00f8 globl +scall request_key 0xffffffffffff00f9 globl +scall keyctl 0xffffffffffff00fa globl +scall ioprio_set 0xffffffffffff00fb globl +scall ioprio_get 0xffffffffffff00fc globl +scall inotify_init 0xffffffffffff00fd globl # wicked +scall inotify_add_watch 0xffffffffffff00fe globl +scall inotify_rm_watch 0xffffffffffff00ff globl +scall 'openat$sysv' 0x014101f321cf0101 globl hidden # Linux 2.6.16+ (c. 2007) +scall 'mkdirat$sysv' 0x013e01f021db0102 globl hidden +scall 'fchownat$sysv' 0x013b01eb21d40104 globl hidden # @asyncsignalsafe +scall futimesat 0xffff01eeffff0105 globl hidden # @asyncsignalsafe +scall '__fstatat$sysv' 0x002a022821d60106 globl hidden # a.k.a. newfstatat(); FreeBSD 12+; needs stat2linux() +scall 'unlinkat$sysv' 0x014501f721d80107 globl hidden +scall 'renameat$sysv' 0x014301f521d10108 globl hidden +scall 'linkat$sysv' 0x013d01ef21d70109 globl hidden +scall 'symlinkat$sysv' 0x014401f621da010a globl hidden +scall 'readlinkat$sysv' 0x014201f421d9010b globl hidden +scall 'fchmodat$sysv' 0x013a01ea21d3010c globl hidden +scall 'faccessat$sysv' 0x013901e921d2010d globl hidden +scall unshare 0xffffffffffff0110 globl +scall 'splice$sysv' 0xffffffffffff0113 globl hidden # Linux 2.6.17+ (c. 2007) +scall tee 0xffffffffffff0114 globl # Linux 2.6.17+ +scall 'sync_file_range$sysv' 0xffffffffffff0115 globl hidden # Linux 2.6.17+ +scall 'vmsplice$sysv' 0xffffffffffff0116 globl hidden +scall migrate_pages 0xffffffffffff0100 globl # numa numa yay +scall move_pages 0xffffffffffff0117 globl # NOTE: We view Red Hat versions as "epochs" for all distros. +#──────────────────────RHEL 5.0 LIMIT──────────────────────── # ←┬─ last gplv2 distro w/ sysv init was rhel5 c. 2007 +scall '__preadv$sysv' 0x010b0121ffff0127 globl hidden # ├─ cosmopolitan at minimum requires rhel5 +scall '__pwritev$sysv' 0x010c0122ffff0128 globl hidden # ├─ python modules need to work on this (pep513) +scall utimensat 0x00540223ffff0118 globl hidden # └─ end of life 2020-11-30 (extended) +scall 'fallocate$sysv' 0xffffffffffff011d globl hidden +scall 'posix_fallocate$sysv' 0xffff0212ffffffff globl hidden +scall '__accept4$sysv' 0x005d021dffff0120 globl hidden # Linux 2.6.28+ +scall '__dup3$sysv' 0x0066ffffffff0124 globl hidden # Linux 2.6.27+ +scall '__pipe2$sysv' 0x0065021effff0125 globl hidden # Linux 2.6.27+ +scall epoll_pwait 0xffffffffffff0119 globl +scall epoll_create1 0xffffffffffff0123 globl +scall perf_event_open 0xffffffffffff012a globl +scall inotify_init1 0xffffffffffff0126 globl +scall rt_tgsigqueueinfo 0xffffffffffff0129 globl +scall signalfd 0xffffffffffff011a globl # won't polyfill; see INTON/INTOFF tutorial in examples/unbourne.c +scall signalfd4 0xffffffffffff0121 globl # won't polyfill; see INTON/INTOFF tutorial in examples/unbourne.c +scall eventfd 0xffffffffffff011c globl # won't polyfill; see INTON/INTOFF tutorial in examples/unbourne.c +scall eventfd2 0xffffffffffff0122 globl # won't polyfill; see INTON/INTOFF tutorial in examples/unbourne.c +scall timerfd_create 0xffffffffffff011b globl # won't polyfill; see INTON/INTOFF tutorial in examples/unbourne.c +scall timerfd_settime 0xffffffffffff011e globl # won't polyfill; see INTON/INTOFF tutorial in examples/unbourne.c +scall timerfd_gettime 0xffffffffffff011f globl # won't polyfill; see INTON/INTOFF tutorial in examples/unbourne.c +#──────────────────────RHEL 6.0 LIMIT──────────────────────── # ←┬─ modern glibc at minimum requires rhel6+ +scall recvmmsg 0xffffffffffff012b globl # └─ end of life 2024-06-30 (extended) +scall fanotify_init 0xffffffffffff012c globl +scall fanotify_mark 0xffffffffffff012d globl +scall prlimit 0xffffffffffff012e globl +scall name_to_handle_at 0xffffffffffff012f globl +scall open_by_handle_at 0xffffffffffff0130 globl +scall clock_adjtime 0xffffffffffff0131 globl +scall syncfs 0xffffffffffff0132 globl +scall sendmmsg 0xffffffffffff0133 globl +scall setns 0xffffffffffff0134 globl +scall getcpu 0xffffffffffff0135 globl +scall process_vm_readv 0xffffffffffff0136 globl +scall process_vm_writev 0xffffffffffff0137 globl +scall kcmp 0xffffffffffff0138 globl +scall finit_module 0xffffffffffff0139 globl +#──────────────────────RHEL 7.0 LIMIT──────────────────────── # ←┬─ distros switched to systemd +scall sched_setattr 0xffffffffffff013a globl # └─ C++11 needs this +scall sched_getattr 0xffffffffffff013b globl +scall renameat2 0xffffffffffff013c globl +scall seccomp 0xffffffffffff013d globl +scall 'getrandom$sysv' 0x0007023321f4013e globl hidden # Linux 3.17+ and getentropy() on XNU/OpenBSD +scall memfd_create 0xffffffffffff013f globl # wut +scall kexec_file_load 0xffffffffffff0140 globl +scall bpf 0xffffffffffff0141 globl +scall execveat 0xffffffffffff0142 globl +scall userfaultfd 0xffffffffffff0143 globl # Linux 4.3+ (c. 2015) +scall membarrier 0xffffffffffff0144 globl # Linux 4.3+ (c. 2015) +scall mlock2 0xffffffffffff0145 globl # Linux 4.5+ (c. 2016) +scall 'copy_file_range$sysv' 0xffffffffffff0146 globl hidden # Linux 4.5+ (c. 2016) +scall preadv2 0xffffffffffff0147 globl +scall pwritev2 0xffffffffffff0148 globl +scall pkey_mprotect 0xffffffffffff0149 globl +scall pkey_alloc 0xffffffffffff014a globl +scall pkey_free 0xffffffffffff014b globl +scall statx 0xffffffffffff014c globl # lool https://lkml.org/lkml/2010/7/22/249 +scall io_pgetevents 0xffffffffffff014d globl +scall rseq 0xffffffffffff014e globl # Linux 4.18+ (c. 2018) +#──────────────────────LINUX 4.18 LIMIT────────────────────── # ← last kernel buildable w/ gplv2 libraries +scall pidfd_send_signal 0xffffffffffff01a8 globl # won't polyfill; see INTON/INTOFF tutorial in examples/unbourne.c +scall io_uring_setup 0xffffffffffff01a9 globl # Linux 5.1+ (c. 2019) +scall io_uring_enter 0xffffffffffff01aa globl # Linux 5.1+ (c. 2019) +scall io_uring_register 0xffffffffffff01ab globl # Linux 5.1+ (c. 2019) +scall pledge 0x006cffffffffffff globl # it's cross-platorm if you ignore the return code + +# The Fifth Bell System Interface, Community Edition +# » besiyata dishmaya +# GNU/Systemd┐ +# Mac OS X┐ │ +# FreeBSD┐ │ │ +# OpenBSD┐ │ ┌─│───│── XnuClass{1:Mach,2:Unix} +# ┌─┴┐┌─┴┐│┌┴┐┌─┴┐ +scall ktrace 0x002d002dffffffff globl +scall kqueue 0x010d016a216affff globl +scall kevent 0x004802302171ffff globl +scall revoke 0x003800382038ffff globl +scall setlogin 0x003200322032ffff globl +scall getfh 0x00a100a120a1ffff globl +scall chflags 0x002200222022ffff globl +scall getfsstat 0x003e022d215bffff globl +scall nfssvc 0x009b009b209bffff globl +scall futimes 0x004d00ce208bffff globl +scall adjtime 0x008c008c208cffff globl +scall fchflags 0x002300232023ffff globl +scall '__seteuid$bsd' 0x00b700b720b7ffff globl hidden # wrapped via setreuid() +scall '__setegid$bsd' 0x00b600b620b6ffff globl hidden # wrapped via setregid() +scall fpathconf 0x00c000c020c0ffff globl +scall fhopen 0x0108012a20f8ffff globl +scall unmount 0x00160016209fffff globl +scall issetugid 0x00fd00fd2147ffff globl +scall minherit 0x00fa00fa20faffff globl +scall pathconf 0x00bf00bf20bfffff globl +scall sysctl 0x00caffff20caffff globl +#───────────────────────XNU & FREEBSD──────────────────────── +scall ntp_adjtime 0xffff00b0220fffff globl +scall ntp_gettime 0xffff00f82210ffff globl +scall shm_unlink 0xffff01e3210bffff globl +scall shm_open 0xffff01e2210affff globl +scall aio_read 0xffff013e213effff globl +scall aio_suspend 0xffff013b213bffff globl +scall aio_cancel 0xffff013c213cffff globl +scall aio_fsync 0xffff01d12139ffff globl +scall aio_error 0xffff013d213dffff globl +scall aio_return 0xffff013a213affff globl +scall aio_write 0xffff013f213fffff globl +scall aio_waitcomplete 0xffff0167ffffffff globl +scall aio_suspend_nocancel 0xffffffff21a5ffff globl +scall aio_mlock 0xffff021fffffffff globl +scall sigwait 0xffff01ad214affff globl +scall undelete 0xffff00cd20cdffff globl +scall getlogin 0xffff00312031ffff globl +scall getdtablesize 0xffff00592059ffff globl +scall setauid 0xffff01c02162ffff globl +scall audit 0xffff01bd215effff globl +scall auditctl 0xffff01c52167ffff globl +scall getaudit_addr 0xffff01c32165ffff globl +scall getdirentries 0xffff022a2158ffff globl +scall lio_listio 0xffff01402140ffff globl +scall setaudit_addr 0xffff01c42166ffff globl +scall getauid 0xffff01bf2161ffff globl +scall semsys 0xffff00a920fbffff globl +scall auditon 0xffff01be215fffff globl +scall msgsys 0xffff00aa20fcffff globl +scall shmsys 0xffff00ab20fdffff globl +#─────────────────────FREEBSD & OPENBSD────────────────────── +scall futimens 0x00550222ffffffff globl +scall fhstat 0x01260229ffffffff globl +scall chflagsat 0x006b021cffffffff globl +scall profil 0x002c002cffffffff globl +scall fhstatfs 0x0041022effffffff globl +scall utrace 0x00d1014fffffffff globl +scall closefrom 0x011f01fdffffffff globl +#───────────────────────────XNU────────────────────────────── +scall __pthread_markcancel 0xffffffff214cffff globl +scall __pthread_kill 0xffffffff2148ffff globl +scall __pthread_fchdir 0xffffffff215dffff globl +scall __pthread_sigmask 0xffffffff2149ffff globl +scall __pthread_chdir 0xffffffff215cffff globl +scall __pthread_canceled 0xffffffff214dffff globl +scall __disable_threadsignal 0xffffffff214bffff globl +scall abort_with_payload 0xffffffff2209ffff globl +scall accept_nocancel 0xffffffff2194ffff globl +scall access_extended 0xffffffff211cffff globl +scall audit_session_join 0xffffffff21adffff globl +scall audit_session_port 0xffffffff21b0ffff globl +scall audit_session_self 0xffffffff21acffff globl +scall bsdthread_create 0xffffffff2168ffff globl +scall bsdthread_ctl 0xffffffff21deffff globl +scall bsdthread_register 0xffffffff216effff globl +scall bsdthread_terminate 0xffffffff2169ffff globl +scall change_fdguard_np 0xffffffff21bcffff globl +scall chmod_extended 0xffffffff211affff globl +scall clonefileat 0xffffffff21ceffff globl +scall close_nocancel 0xffffffff218fffff globl +scall coalition 0xffffffff21caffff globl +scall coalition_info 0xffffffff21cbffff globl +scall connect_nocancel 0xffffffff2199ffff globl +scall connectx 0xffffffff21bfffff globl +scall copyfile 0xffffffff20e3ffff globl +scall csops 0xffffffff20a9ffff globl +scall csops_audittoken 0xffffffff20aaffff globl +scall csrctl 0xffffffff21e3ffff globl +scall delete 0xffffffff20e2ffff globl +scall disconnectx 0xffffffff21c0ffff globl +scall exchangedata 0xffffffff20dfffff globl +scall fchmod_extended 0xffffffff211bffff globl +scall fclonefileat 0xffffffff2205ffff globl +scall fcntl_nocancel 0xffffffff2196ffff globl +scall ffsctl 0xffffffff20f5ffff globl +scall fgetattrlist 0xffffffff20e4ffff globl +scall fileport_makefd 0xffffffff21afffff globl +scall fileport_makeport 0xffffffff21aeffff globl +scall fmount 0xffffffff220effff globl +scall fs_snapshot 0xffffffff2206ffff globl +scall fsctl 0xffffffff20f2ffff globl +scall fsetattrlist 0xffffffff20e5ffff globl +scall fstat_extended 0xffffffff2119ffff globl +scall fsync_nocancel 0xffffffff2198ffff globl +scall getattrlist 0xffffffff20dcffff globl +scall getattrlistat 0xffffffff21dcffff globl +scall getattrlistbulk 0xffffffff21cdffff globl +scall getdirentriesattr 0xffffffff20deffff globl +scall gethostuuid 0xffffffff208effff globl +scall getsgroups 0xffffffff2120ffff globl +scall getwgroups 0xffffffff2122ffff globl +scall grab_pgo_data 0xffffffff21edffff globl +scall guarded_close_np 0xffffffff21baffff globl +scall guarded_kqueue_np 0xffffffff21bbffff globl +scall guarded_open_np 0xffffffff21b9ffff globl +scall guarded_pwrite_np 0xffffffff21e6ffff globl +scall guarded_write_np 0xffffffff21e5ffff globl +scall guarded_writev_np 0xffffffff21e7ffff globl +scall identitysvc 0xffffffff2125ffff globl +scall initgroups 0xffffffff20f3ffff globl +scall iopolicysys 0xffffffff2142ffff globl +scall kas_info 0xffffffff21b7ffff globl +scall kdebug_trace 0xffffffff20b3ffff globl +scall kdebug_trace_string 0xffffffff20b2ffff globl +scall kdebug_typefilter 0xffffffff20b1ffff globl +scall kevent_id 0xffffffff2177ffff globl +scall kevent_qos 0xffffffff2176ffff globl +scall ledger 0xffffffff2175ffff globl +scall lstat_extended 0xffffffff2156ffff globl +scall memorystatus_control 0xffffffff21b8ffff globl +scall memorystatus_get_level 0xffffffff21c5ffff globl +scall microstackshot 0xffffffff21ecffff globl +scall mkdir_extended 0xffffffff2124ffff globl +scall mkfifo_extended 0xffffffff2123ffff globl +scall modwatch 0xffffffff20e9ffff globl +scall mremap_encrypted 0xffffffff21e9ffff globl +scall msgrcv_nocancel 0xffffffff21a3ffff globl +scall msgsnd_nocancel 0xffffffff21a2ffff globl +scall msync_nocancel 0xffffffff2195ffff globl +scall necp_client_action 0xffffffff21f6ffff globl +scall necp_match_policy 0xffffffff21ccffff globl +scall necp_open 0xffffffff21f5ffff globl +scall necp_session_action 0xffffffff220bffff globl +scall necp_session_open 0xffffffff220affff globl +scall net_qos_guideline 0xffffffff220dffff globl +scall netagent_trigger 0xffffffff21eaffff globl +scall nfsclnt 0xffffffff20f7ffff globl +scall open_dprotected_np 0xffffffff20d8ffff globl +scall open_extended 0xffffffff2115ffff globl +scall open_nocancel 0xffffffff218effff globl +scall openat_nocancel 0xffffffff21d0ffff globl +scall openbyid_np 0xffffffff21dfffff globl +scall os_fault_with_payload 0xffffffff2211ffff globl +scall peeloff 0xffffffff21c1ffff globl +scall persona 0xffffffff21eeffff globl +scall pid_hibernate 0xffffffff21b3ffff globl +scall pid_resume 0xffffffff21b2ffff globl +scall pid_shutdown_sockets 0xffffffff21b4ffff globl +scall pid_suspend 0xffffffff21b1ffff globl +scall poll_nocancel 0xffffffff21a1ffff globl +scall pread_nocancel 0xffffffff219effff globl +scall proc_info 0xffffffff2150ffff globl +scall proc_rlimit_control 0xffffffff21beffff globl +scall proc_trace_log 0xffffffff21ddffff globl +scall proc_uuid_policy 0xffffffff21c4ffff globl +scall process_policy 0xffffffff2143ffff globl +scall pselect_nocancel 0xffffffff218bffff globl +scall psynch_cvbroad 0xffffffff212fffff globl +scall psynch_cvclrprepost 0xffffffff2138ffff globl +scall psynch_cvsignal 0xffffffff2130ffff globl +scall psynch_mutexdrop 0xffffffff212effff globl +scall psynch_mutexwait 0xffffffff212dffff globl +scall psynch_rw_downgrade 0xffffffff212bffff globl +scall psynch_rw_longrdlock 0xffffffff2129ffff globl +scall psynch_rw_rdlock 0xffffffff2132ffff globl +scall psynch_rw_unlock 0xffffffff2134ffff globl +scall psynch_rw_unlock2 0xffffffff2135ffff globl +scall psynch_rw_upgrade 0xffffffff212cffff globl +scall psynch_rw_wrlock 0xffffffff2133ffff globl +scall psynch_rw_yieldwrlock 0xffffffff212affff globl +scall pwrite_nocancel 0xffffffff219fffff globl +scall read_nocancel 0xffffffff218cffff globl +scall readv_nocancel 0xffffffff219bffff globl +scall recvfrom_nocancel 0xffffffff2193ffff globl +scall recvmsg_nocancel 0xffffffff2191ffff globl +scall recvmsg_x 0xffffffff21e0ffff globl +scall renameatx_np 0xffffffff21e8ffff globl +scall searchfs 0xffffffff20e1ffff globl +scall select_nocancel 0xffffffff2197ffff globl +scall sem_close 0xffffffff210dffff globl +scall sem_open 0xffffffff210cffff globl +scall sem_post 0xffffffff2111ffff globl +scall sem_trywait 0xffffffff2110ffff globl +scall sem_unlink 0xffffffff210effff globl +scall sem_wait 0xffffffff210fffff globl +scall sem_wait_nocancel 0xffffffff21a4ffff globl +scall sendmsg_nocancel 0xffffffff2192ffff globl +scall sendmsg_x 0xffffffff21e1ffff globl +scall sendto_nocancel 0xffffffff219dffff globl +scall setattrlist 0xffffffff20ddffff globl +scall setattrlistat 0xffffffff220cffff globl +scall setprivexec 0xffffffff2098ffff globl +scall setsgroups 0xffffffff211fffff globl +scall settid 0xffffffff211dffff globl +scall settid_with_pid 0xffffffff2137ffff globl +scall setwgroups 0xffffffff2121ffff globl +scall sfi_ctl 0xffffffff21c8ffff globl +scall sfi_pidctl 0xffffffff21c9ffff globl +scall shared_region_check_np 0xffffffff2126ffff globl +scall sigsuspend_nocancel 0xffffffff219affff globl +scall socket_delegate 0xffffffff21c2ffff globl +scall stat_extended 0xffffffff2155ffff globl +scall sysctlbyname 0xffffffff2112ffff globl +scall system_override 0xffffffff21c6ffff globl +scall telemetry 0xffffffff21c3ffff globl +scall terminate_with_payload 0xffffffff2208ffff globl +scall thread_selfcounts 0xffffffff20baffff globl +scall thread_selfid 0xffffffff2174ffff globl +scall thread_selfusage 0xffffffff21e2ffff globl +scall ulock_wait 0xffffffff2203ffff globl +scall ulock_wake 0xffffffff2204ffff globl +scall umask_extended 0xffffffff2116ffff globl +scall usrctl 0xffffffff21bdffff globl +scall vfs_purge 0xffffffff21c7ffff globl +scall vm_pressure_monitor 0xffffffff2128ffff globl +scall wait4_nocancel 0xffffffff2190ffff globl +scall waitevent 0xffffffff20e8ffff globl +scall waitid_nocancel 0xffffffff21a0ffff globl +scall watchevent 0xffffffff20e7ffff globl +scall work_interval_ctl 0xffffffff21f3ffff globl +scall workq_kernreturn 0xffffffff2170ffff globl +scall workq_open 0xffffffff216fffff globl +scall write_nocancel 0xffffffff218dffff globl +scall writev_nocancel 0xffffffff219cffff globl +#──────────────────────────FREEBSD─────────────────────────── +scall abort2 0xffff01cfffffffff globl +scall afs3_syscall 0xffff0179ffffffff globl +scall bindat 0xffff021affffffff globl +scall break 0xffff0011ffffffff globl +scall cap_enter 0xffff0204ffffffff globl +scall cap_fcntls_get 0xffff0219ffffffff globl +scall cap_fcntls_limit 0xffff0218ffffffff globl +scall cap_getmode 0xffff0205ffffffff globl +scall cap_ioctls_get 0xffff0217ffffffff globl +scall cap_ioctls_limit 0xffff0216ffffffff globl +scall cap_rights_limit 0xffff0215ffffffff globl +scall clock_getcpuclockid2 0xffff00f7ffffffff globl +scall connectat 0xffff021bffffffff globl +scall cpuset 0xffff01e4ffffffff globl +scall cpuset_getdomain 0xffff0231ffffffff globl +scall cpuset_getid 0xffff01e6ffffffff globl +scall cpuset_setdomain 0xffff0232ffffffff globl +scall cpuset_setid 0xffff01e5ffffffff globl +scall eaccess 0xffff0178ffffffff globl +scall extattr_delete_fd 0xffff0175ffffffff globl +scall extattr_delete_file 0xffff0166ffffffff globl +scall extattr_delete_link 0xffff019effffffff globl +scall extattr_get_fd 0xffff0174ffffffff globl +scall extattr_get_file 0xffff0165ffffffff globl +scall extattr_get_link 0xffff019dffffffff globl +scall extattr_list_fd 0xffff01b5ffffffff globl +scall extattr_list_file 0xffff01b6ffffffff globl +scall extattr_list_link 0xffff01b7ffffffff globl +scall extattr_set_fd 0xffff0173ffffffff globl +scall extattr_set_file 0xffff0164ffffffff globl +scall extattr_set_link 0xffff019cffffffff globl +scall extattrctl 0xffff0163ffffffff globl +scall fexecve 0xffff01ecffffffff globl +scall ffclock_getcounter 0xffff00f1ffffffff globl +scall ffclock_getestimate 0xffff00f3ffffffff globl +scall ffclock_setestimate 0xffff00f2ffffffff globl +scall fhlink 0xffff0235ffffffff globl +scall fhlinkat 0xffff0236ffffffff globl +scall fhreadlink 0xffff0237ffffffff globl +scall getaudit 0xffff01c1ffffffff globl +scall getcontext 0xffff01a5ffffffff globl +scall getdomainname 0xffff00a2ffffffff globl +scall getfhat 0xffff0234ffffffff globl +scall gethostid 0xffff008effffffff globl +scall gethostname 0xffff0057ffffffff globl +scall getkerninfo 0xffff003fffffffff globl +scall getloginclass 0xffff020bffffffff globl +scall 'getpagesize$freebsd' 0xffff0040ffffffff globl hidden +scall gssd_syscall 0xffff01f9ffffffff globl +scall jail 0xffff0152ffffffff globl +scall jail_attach 0xffff01b4ffffffff globl +scall jail_get 0xffff01faffffffff globl +scall jail_remove 0xffff01fcffffffff globl +scall jail_set 0xffff01fbffffffff globl +scall kenv 0xffff0186ffffffff globl +scall kldfind 0xffff0132ffffffff globl +scall kldfirstmod 0xffff0135ffffffff globl +scall kldload 0xffff0130ffffffff globl +scall kldnext 0xffff0133ffffffff globl +scall kldstat 0xffff0134ffffffff globl +scall kldsym 0xffff0151ffffffff globl +scall kldunload 0xffff0131ffffffff globl +scall kldunloadf 0xffff01bcffffffff globl +scall kmq_notify 0xffff01cdffffffff globl +scall kmq_setattr 0xffff01caffffffff globl +scall kmq_timedreceive 0xffff01cbffffffff globl +scall kmq_timedsend 0xffff01ccffffffff globl +scall kmq_unlink 0xffff01ceffffffff globl +scall ksem_close 0xffff0190ffffffff globl +scall ksem_destroy 0xffff0198ffffffff globl +scall ksem_getvalue 0xffff0197ffffffff globl +scall ksem_init 0xffff0194ffffffff globl +scall ksem_open 0xffff0195ffffffff globl +scall ksem_post 0xffff0191ffffffff globl +scall ksem_timedwait 0xffff01b9ffffffff globl +scall ksem_trywait 0xffff0193ffffffff globl +scall ksem_unlink 0xffff0196ffffffff globl +scall ksem_wait 0xffff0192ffffffff globl +scall ktimer_create 0xffff00ebffffffff globl +scall ktimer_delete 0xffff00ecffffffff globl +scall ktimer_getoverrun 0xffff00efffffffff globl +scall ktimer_gettime 0xffff00eeffffffff globl +scall ktimer_settime 0xffff00edffffffff globl +scall lchflags 0xffff0187ffffffff globl +scall lchmod 0xffff0112ffffffff globl +scall lgetfh 0xffff00a0ffffffff globl +scall lpathconf 0xffff0201ffffffff globl +scall lutimes 0xffff0114ffffffff globl +scall mac_syscall 0xffff018affffffff globl +scall modfind 0xffff012fffffffff globl +scall modfnext 0xffff012effffffff globl +scall modnext 0xffff012cffffffff globl +scall modstat 0xffff012dffffffff globl +scall nfstat 0xffff0117ffffffff globl +scall nlm_syscall 0xffff009affffffff globl +scall nlstat 0xffff0118ffffffff globl +scall nmount 0xffff017affffffff globl +scall nnpfs_syscall 0xffff0153ffffffff globl +scall nstat 0xffff0116ffffffff globl +scall pdfork 0xffff0206ffffffff globl +scall pdgetpid 0xffff0208ffffffff globl +scall pdkill 0xffff0207ffffffff globl +scall 'posix_openpt$sysv' 0xffff01f8ffffffff globl hidden +scall procctl 0xffff0220ffffffff globl +scall psynch_cvwait 0xffffffff2131ffff globl +scall quota 0xffff0095ffffffff globl +scall rctl_add_rule 0xffff0210ffffffff globl +scall rctl_get_limits 0xffff020fffffffff globl +scall rctl_get_racct 0xffff020dffffffff globl +scall rctl_get_rules 0xffff020effffffff globl +scall rctl_remove_rule 0xffff0211ffffffff globl +scall recv 0xffff0066ffffffff globl +scall rfork 0xffff00fbffffffff globl +scall rtprio 0xffff00a6ffffffff globl +scall rtprio_thread 0xffff01d2ffffffff globl +scall send 0xffff0065ffffffff globl +scall setaudit 0xffff01c2ffffffff globl +scall setcontext 0xffff01a6ffffffff globl +scall setfib 0xffff00afffffffff globl +scall sethostid 0xffff008fffffffff globl +scall setloginclass 0xffff020cffffffff globl +scall sigblock 0xffff006dffffffff globl +scall sigqueue 0xffff01c8ffffffff globl +scall sigsetmask 0xffff006effffffff globl +scall sigstack 0xffff0070ffffffff globl +scall sigvec 0xffff006cffffffff globl +scall sigwaitinfo 0xffff015affffffff globl +scall sstk 0xffff0046ffffffff globl +scall swapcontext 0xffff01a7ffffffff globl +scall thr_create 0xffff01aeffffffff globl +scall thr_exit 0xffff01afffffffff globl +scall thr_kill 0xffff01b1ffffffff globl +scall thr_kill2 0xffff01e1ffffffff globl +scall thr_new 0xffff01c7ffffffff globl +scall thr_self 0xffff01b0ffffffff globl +scall thr_set_name 0xffff01d0ffffffff globl +scall thr_suspend 0xffff01baffffffff globl +scall thr_wake 0xffff01bbffffffff globl +scall uuidgen 0xffff0188ffffffff globl +scall vadvise 0xffff0048ffffffff globl +scall wait 0xffff0054ffffffff globl +scall wait6 0xffff0214ffffffff globl +scall yield 0xffff0141ffffffff globl +#──────────────────────────OPENBSD─────────────────────────── +scall __tfork 0x0008ffffffffffff globl +scall __thrsleep 0x005effffffffffff globl +scall __thrwakeup 0x012dffffffffffff globl +scall __threxit 0x012effffffffffff globl +scall __thrsigdivert 0x012fffffffffffff globl +scall __set_tcb 0x0149ffffffffffff globl +scall __get_tcb 0x014affffffffffff globl +scall adjfreq 0x0131ffffffffffff globl +scall getdtablecount 0x0012ffffffffffff globl +scall getlogin_r 0x008dffffffffffff globl +scall getrtable 0x0137ffffffffffff globl +scall getthrid 0x012bffffffffffff globl +scall kbind 0x0056ffffffffffff globl +scall mquery 0x011effffffffffff globl # openbsd:pad +scall obreak 0x0011ffffffffffff globl +scall sendsyslog 0x0070ffffffffffff globl +scall setrtable 0x0136ffffffffffff globl +scall swapctl 0x00c1ffffffffffff globl +scall thrkill 0x0077ffffffffffff globl +scall unveil 0x0072ffffffffffff globl + +# The Fifth Bell System Interface, Community Edition +# » beyond the pale +# GNU/Systemd┐ +# Mac OS X┐ │ +# FreeBSD┐ │ │ +# OpenBSD┐ │ ┌─│───│── XnuClass{1:Mach,2:Unix} +# ┌─┴┐┌─┴┐│┌┴┐┌─┴┐ +scall __mac_get_link 0xffff019a2180ffff globl +scall __mac_set_link 0xffff019b2181ffff globl +scall __mac_get_fd 0xffff01822184ffff globl +scall __mac_get_file 0xffff0183217effff globl +scall __mac_get_proc 0xffff01802182ffff globl +scall __mac_set_fd 0xffff01842185ffff globl +scall __mac_get_pid 0xffff01992186ffff globl +scall __mac_set_proc 0xffff01812183ffff globl +scall __mac_set_file 0xffff0185217fffff globl +scall __mac_execve 0xffff019f217cffff globl +scall __acl_get_link 0xffff01a9ffffffff globl +scall __sigwait_nocancel 0xffffffff21a6ffff globl +scall __cap_rights_get 0xffff0203ffffffff globl +scall __semwait_signal 0xffffffff214effff globl +scall __acl_set_link 0xffff01aaffffffff globl +scall __acl_set_fd 0xffff015effffffff globl +scall __old_semwait_signal 0xffffffff2172ffff globl +scall __setugid 0xffff0176ffffffff globl +scall __acl_aclcheck_fd 0xffff0162ffffffff globl +scall __acl_get_fd 0xffff015dffffffff globl +scall __sysctl 0xffff00caffffffff globl +scall __mac_getfsstat 0xffffffff21aaffff globl +scall __mac_get_mount 0xffffffff21a9ffff globl +scall __acl_delete_link 0xffff01abffffffff globl +scall __mac_mount 0xffffffff21a8ffff globl +scall __acl_get_file 0xffff015bffffffff globl +scall __acl_aclcheck_file 0xffff0161ffffffff globl +scall __acl_delete_fd 0xffff0160ffffffff globl +scall __acl_aclcheck_link 0xffff01acffffffff globl +scall __mac_syscall 0xffffffff217dffff globl +scall __acl_set_file 0xffff015cffffffff globl +scall __acl_delete_file 0xffff015fffffffff globl +scall __syscall 0x00c6ffffffffffff globl +scall _umtx_op 0xffff01c6ffffffff globl +scall __semwait_signal_nocancel 0xffffffff21a7ffff globl +scall __old_semwait_signal_nocancel 0xffffffff2173ffff globl +scall sctp_peeloff 0xffff01d7ffffffff globl +scall sctp_generic_recvmsg 0xffff01daffffffff globl +scall sctp_generic_sendmsg 0xffff01d8ffffffff globl +scall sctp_generic_sendmsg_iov 0xffff01d9ffffffff globl +scall shared_region_map_and_slide_np 0xffffffff21b6ffff globl +scall guarded_open_dprotected_np 0xffffffff21e4ffff globl +scall stack_snapshot_with_config 0xffffffff21ebffff globl diff --git a/libc/sysv/systemfive.S b/libc/sysv/systemfive.S new file mode 100644 index 00000000..ae4dfec5 --- /dev/null +++ b/libc/sysv/systemfive.S @@ -0,0 +1,284 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/macros.h" +.yoink __FILE__ + +/* ▄▄▄ + ▄▄▄ ▀▓▓▒▄ + ▄▓▒▒░ ▀▓▒▒▒▄ + ▄▓▓▓▒▀ ▄▄▄▄ ▒▓▒▒░▒▄ + ▄▓▓▓▒▓ ▄▄▓██▓▓▓▓▒▒▒▒▓▓▄▄▓▓▒▒▒░░▒ + ▓▓▓▓▒▒▒▄▄ ░▒█▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▓▒░░▒░ + ██▓▓▓▒▒░░▒▒▒▒▓▓▓▓▓▓▒▓▒░▒▒░▀▒▒▒▒░▀░▒▒▒░▒ + ▓▓▓▓▓▓▓▒▒▒▒▒▒▓▓▒▓▓▒▒▒░▒▒░░ ░▒▒░ ░▒▒▒▒ + ▀▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░▒░░ ░▒▒ ░ ▀▒▒ + ▀▓▓█▓▓▓▓▓▓▓▓▓▓▒▒░░▒▒░░ ░░░▓░ ▓░░░▒ + ▀▀█▓███▓▓▓▓▓▒▒░░░▒░░ ░█▓░█▓░█▓▓▄▒░ + ░▓██▓▓▓▓▓▒▒░░░▒░░ ░████▓▒▓█▓▀░▀▄ + ░▓██▓▓▓▓▓▒▒▒░░░▒░░ ▒██▓▒▒▒▒▒▒░░░▒ + ████▓▓▓▓▓▒▒▒▒▒▒▒▒▒░░▒▓▓▒░░░░▒░░░▒░ ░░░░░ + ░▓███▓▓▓▓▓▒▒░░░░░░░▒▒▒▒▒▒▒▒▒▒▒░░░ ░░░░░ ░ + ▓███▓▓▓▓▓▒▓▒▒▒▒░░░░░░░░░▒▓▒▒░▀ ░░░ ░░░░░ + ▀▒██▓▓▓▓▒▒▒▓▓▓▓▒▒▒▒▒▒▒▓▀▀░ ░░░░░░░░░ ░ + ▓▓▓▓▓▓▓▒▓▒▒▒▒▓▓▓▒▀░ ░░░░░▄░░░ ░░░ ░░░░░░ + ▓▓▓▒▒▒▒▒▒▒▒▒▒▒▓ █▓▒░░▒░░░░ ░░░░░░░░ + ▄▓▓▓▒▒▒▒▒░░░░░░░▒▄▄▄░▒▓▓▒▒░▀░ + ░▓█▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▒░░░▒ besiyata + ▓▓█▓▓▒▓▓▓▒▒▒░░░░░░▒▓▓▓▓▒▒▒▒▒░ dishmaya + ▓▓█▓▓▓▓▓▓▒▒▒░░░░░░░▒▓▓▒▀▀▀ + ▓▓██▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▀ + █▓▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀ + ▒▓▓▓▓▀░░▒▓▓▓▓▓▓▓▓▒▒░░▒ + ▄▓▓▀░░░▄▓▓▓▓▒▒▒▒▒░░░░▄░ + ▄███▄▄▓▓▓▓▓▓▓▒▒▒▒▒░░▒▒░ + ▄▓▓▓█▓█▓▓███▓▓▓▓▓▓▓▓▓▓▓░ + ▄░▓▓▓▓▓▓▀▒▓▓▓▒▒▓▒░░░▒▓▒░░░▓ + ▄▄▄░▒▓▓▓▓▓▓░▀▀ ▓▓▒░▓▒▒▒▒▒▒▒▒▒▒▄░░▀▀░░ ▄▄▄▄ + ▄▄▄▒▒▓▓█▓▓▓▓▓▀▀▀▀▀ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▀░░▀░░▒▒▒░░░ ░░░░░ + ▄▓▓▓▒▀▀ ▓▒▓▓▓▓▓▒▒▒▒▒▒▒▒▓░░░ ▒▒▒░░░░░░░░▒ + █▓▓▒ ▄▄▄ ▀▓▒▓▒▒▒▓▓▓▓▓▓▒▒▒░░░░░░░░░▒▒░░░░░░░ + ▀▓▓▓▓▒▄▄▒▒▒▒▒▒▄▄ ▀▀▀▀░░▒▒▒▒░░░░░░ + ▀▀▀▓▓▓▓▒▒▒▒▒▓▓▄▄ +╔────────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § bell system five » system call support ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +/ Performs System Five System Call. +/ +/ Cosmopolitan is designed to delegate all function calls into the +/ Linux, FreeBSD, OpenBSD, and XNU kernels through this function, +/ with few exceptions. This function is intended to be called via +/ generated thunks in the libc/sysv/syscalls/ directory. +/ +/ It's safe to call this function on Windows, where it'll always +/ return -1 w/ errno == ENOSYS. Further note that -1 is the only +/ return value that means error, a common anti-pattern is to check +/ for values less than 0 (which is more problematic on 32-bit). +/ +/ It's important to consider that system calls are an order of a +/ magnitude more expensive than normal function calls. For example +/ getpid() on Linux usually takes 500ns, and cached i/o calls will +/ take 1µs or more. +/ +/ @param %rax function ordinal supplied by jump slot +/ @param %rdi,%rsi,%rdx,%rcx,%r8,%r9 and rest on stack +/ @return %rax:%rdx is result, or -1 w/ errno on error +/ @clob %rcx,%r10,%r11 +/ @see syscalls.sh + .initbss 300,_init_systemfive +hostos: .quad 0 + .endobj hostos,globl,hidden +systemfive: + .quad 0 + .endobj systemfive,globl,hidden + .previous + +.Lanchorpoint: +systemfive.linux: + movswl %ax,%eax + test %eax,%eax + js systemfive.enosys + mov %rcx,%r10 + syscall + cmp $-4095,%rax + jae systemfive.error + ret +systemfive.error: + neg %eax +/ 𝑠𝑙𝑖𝑑𝑒 +systemfive.errno: + mov %eax,errno(%rip) + pushpop -1,%rax + stc + ret +systemfive.enosys: + mov ENOSYS(%rip),%eax + jmp systemfive.errno +systemfive.openbsd: + shr $48,%rax + jmp systemfive.bsd +systemfive.freebsd: + shr $32,%rax + movzwl %ax,%eax +/ 𝑠𝑙𝑖𝑑𝑒 +systemfive.bsd: + cmp $0xfff,%ax + jae systemfive.enosys + mov %rcx,%r10 + syscall + jc systemfive.errno + ret +systemfive.xnu: +/ Do this +/ 0x35022721530005 +/ │└┴┴─┐ +/ └┐ ├┬┐ +/ 0x00000002000153 + mov %eax,%r11d + shr $0x10,%eax + and $0xfff,%eax + shr $0x1c,%r11d + shl $0x18,%r11d + or %r11d,%eax + jmp systemfive.bsd + .endfn systemfive.errno,globl,hidden + .endfn systemfive.error,globl,hidden + .endfn systemfive.enosys,globl,hidden + .endfn systemfive.xnu,globl,hidden + .endfn systemfive.freebsd,globl,hidden + .endfn systemfive.openbsd,globl,hidden + .endfn systemfive.linux,globl,hidden + .previous + +/ Initializes System Five system call support. +/ +/ (1) Extracts parameters passed by kernel, +/ (2) Detects O/S without issuing system calls, +/ (3) Unpacks numbers. +/ +/ @param %r15 is auxv +/ @note OpenBSD devs: let us know if you start using auxv + .init.start 300,_init_systemfive + push %rbx + push %rsi + testb $XNU,(%rdi) # @see libc/crt/crt.S + jnz .Lsystemfive.init.xnu + testb $FREEBSD,(%rdi) # @see libc/crt/crt.S + jnz .Lsystemfive.init.freebsd + testb $WINDOWS,(%rdi) # @see libc/runtime/winmain.c + jnz .Lsystemfive.init.windows + cmpq $0,(%r15) # OpenBSD doesn't have auxv + je .Lsystemfive.init.openbsd +/ default state is safe state +/ 𝑠𝑙𝑖𝑑𝑒 +.Lsystemfive.init.linux: + pushb systemfive.linux-.Lanchorpoint + push $LINUX + ezlea syscon.linux,si + jmp .Lsystemfive.init.os +.Lsystemfive.init.windows: + pushb systemfive.enosys-.Lanchorpoint + push $WINDOWS + ezlea syscon.windows,si + jmp .Lsystemfive.init.os +.Lsystemfive.init.freebsd: + pushb systemfive.freebsd-.Lanchorpoint + push $FREEBSD + ezlea syscon.freebsd,si + jmp .Lsystemfive.init.os +.Lsystemfive.init.openbsd: + pushb systemfive.openbsd-.Lanchorpoint + push $OPENBSD + ezlea syscon.openbsd,si + jmp .Lsystemfive.init.os +.Lsystemfive.init.xnu: + pushb systemfive.xnu-.Lanchorpoint + push $XNU + ezlea syscon.xnu,si +/ 𝑠𝑙𝑖𝑑𝑒 +.Lsystemfive.init.os: + ezlea .Lanchorpoint,cx + pop %rax + stosq #→ hostos + pop %rax + add %rcx,%rax + stosq #→ systemfive +.Lsystemfive.sleb128unpacker: + push %rdi + ezlea .Lsyscon.start,di + orq $-1,%r9 + ezlea .Lsyscon.end,bx +2: cmp %rbx,%rdi + jnb 5f + xor %ecx,%ecx + xor %edx,%edx +3: lodsb + mov %rax,%r8 + and $127,%r8d + sal %cl,%r8 + add $7,%ecx + or %r8,%rdx + test %al,%al + js 3b + test $64,%al + je 4f + mov %r9,%rax + sal %cl,%rax + or %rax,%rdx +4: mov %rdx,%rax + cmpq $0,(%rdi) # don't change consts already set + cmovne (%rdi),%rax # @see WinMain() for example + stosq + jmp 2b +5: pop %rdi +/ 𝑠𝑙𝑖𝑑𝑒 +.Lsystemfive.init.done: + pop %rsi + pop %rbx + .init.end 300,_init_systemfive,globl,hidden + +/ Sections for varint encoded numbers. +/ +/ These sections are all ordered by (group_name, constant_name). +/ They're populated by modules simply referencing the symbols. +/ +/ @see libc/sysv/consts.sh +/ @see libc/sysv/consts/syscon.h + .section .piro.bss.sort.syscon.1,"aw",@nobits + .align 8 +.Lsyscon.start:/* + ...decentralized quadwords... + */.previous + .section .piro.bss.sort.syscon.3,"aw",@nobits +.Lsyscon.end: + .previous + .section .sort.rodata.syscon.linux.1,"a",@progbits + .align 1 +syscon.linux:/* + ...decentralized leb128... + */.previous + .section .sort.rodata.syscon.xnu.1,"a",@progbits + .align 1 +syscon.xnu:/* + ...decentralized leb128... + */.previous + .section .sort.rodata.syscon.freebsd.1,"a",@progbits + .align 1 +syscon.freebsd:/* + ...decentralized leb128... + */.previous + .section .sort.rodata.syscon.openbsd.1,"a",@progbits + .align 1 +syscon.openbsd:/* + ...decentralized leb128... + */.previous + .section .sort.rodata.syscon.windows.1,"a",@progbits + .align 1 +syscon.windows:/* + ...decentralized leb128... + */.previous + .type .Lsyscon.start,@object + .type .Lsyscon.end,@object + .type syscon.linux,@object + .type syscon.xnu,@object + .type syscon.freebsd,@object + .type syscon.openbsd,@object + .type syscon.windows,@object diff --git a/libc/sysv/sysv.mk b/libc/sysv/sysv.mk new file mode 100644 index 00000000..b42b2ae4 --- /dev/null +++ b/libc/sysv/sysv.mk @@ -0,0 +1,136 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += LIBC_SYSV +LIBC_SYSV_LIBS = $(foreach x,$(LIBC_SYSV_ARTIFACTS),$($(x)_A)) +LIBC_SYSV_ARCHIVES = $(foreach x,$(LIBC_SYSV_ARTIFACTS),$($(x)_A)) +LIBC_SYSV_HDRS = $(foreach x,$(LIBC_SYSV_ARTIFACTS),$($(x)_HDRS)) +LIBC_SYSV_BINS = $(foreach x,$(LIBC_SYSV_ARTIFACTS),$($(x)_BINS)) +LIBC_SYSV_CHECKS = $(foreach x,$(LIBC_SYSV_ARTIFACTS),$($(x)_CHECKS)) +LIBC_SYSV_OBJS = $(foreach x,$(LIBC_SYSV_ARTIFACTS),$($(x)_OBJS)) +LIBC_SYSV_TESTS = $(foreach x,$(LIBC_SYSV_ARTIFACTS),$($(x)_TESTS)) +LIBC_SYSV_SRCS = $(foreach x,$(LIBC_SYSV_ARTIFACTS),$($(x)_SRCS)) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_SYSV = \ + $(LIBC_SYSV_A_DEPS) \ + $(LIBC_SYSV_A) + +LIBC_SYSV_ARTIFACTS += LIBC_SYSV_A +LIBC_SYSV_A = o/$(MODE)/libc/sysv/sysv.a +LIBC_SYSV_A_HDRS = $(filter %.h,$(LIBC_SYSV_A_FILES)) +LIBC_SYSV_A_SRCS_A = $(filter %.s,$(LIBC_SYSV_A_FILES)) +LIBC_SYSV_A_SRCS_S = $(filter %.S,$(LIBC_SYSV_A_FILES)) +LIBC_SYSV_A_CHECKS = $(LIBC_SYSV_A).pkg + +LIBC_SYSV_A_DIRECTDEPS = \ + LIBC_STUBS \ + LIBC_NEXGEN32E + +LIBC_SYSV_A_FILES := \ + libc/sysv/macros.h \ + libc/sysv/errfuns.h \ + libc/sysv/g_syscount.S \ + libc/sysv/restorert.S \ + libc/sysv/stackchkguard.S \ + libc/sysv/syscall.S \ + libc/sysv/systemfive.S \ + $(wildcard libc/sysv/stubs/*) \ + $(wildcard libc/sysv/consts/*) \ + $(wildcard libc/sysv/errfuns/*) + +LIBC_SYSV_A_SRCS = \ + $(LIBC_SYSV_A_SRCS_A) \ + $(LIBC_SYSV_A_SRCS_S) + +LIBC_SYSV_A_OBJS = \ + $(LIBC_SYSV_A_SRCS_A:%.s=o/%.o) \ + $(LIBC_SYSV_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_SYSV_A_SRCS:%=o/$(MODE)/%.zip.o) + +LIBC_SYSV_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_SYSV_A_DIRECTDEPS),$($(x)))) + +$(LIBC_SYSV_A): libc/sysv/ \ + libc/sysv/consts/ \ + $(LIBC_SYSV_A).pkg \ + $(LIBC_SYSV_A_OBJS) + +$(LIBC_SYSV_A).pkg: \ + $(LIBC_SYSV_A_OBJS) \ + $(foreach x,$(LIBC_SYSV_A_DIRECTDEPS),$($(x)_A).pkg) + +$(LIBC_SYSV_A_OBJS): \ + libc/sysv/consts/syscon.inc \ + libc/sysv/sysv.mk + +libc/sysv/consts/syscon.inc: libc/macros.inc + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_SYSV_CALLS = \ + $(LIBC_SYSV_CALLS_A_DEPS) \ + $(LIBC_SYSV_CALLS_A) + +LIBC_SYSV_ARTIFACTS += LIBC_SYSV_CALLS_A +LIBC_SYSV_CALLS_A = o/libc/sysv/calls.a +LIBC_SYSV_CALLS_A_SRCS := $(wildcard libc/sysv/calls/*.s) +LIBC_SYSV_CALLS_A_OBJS = $(LIBC_SYSV_CALLS_A_SRCS:%.s=o/%.o) +LIBC_SYSV_CALLS_A_CHECKS = $(LIBC_SYSV_CALLS_A).pkg + +LIBC_SYSV_CALLS_A_DIRECTDEPS = \ + LIBC_SYSV + +LIBC_SYSV_CALLS_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_SYSV_CALLS_A_DIRECTDEPS),$($(x)))) + +$(LIBC_SYSV_CALLS_A): \ + libc/sysv/calls/ \ + $(LIBC_SYSV_CALLS_A).pkg \ + $(LIBC_SYSV_CALLS_A_OBJS) + +$(LIBC_SYSV_CALLS_A).pkg: \ + $(LIBC_SYSV_CALLS_A_OBJS) \ + $(foreach x,$(LIBC_SYSV_CALLS_A_DIRECTDEPS),$($(x)_A).pkg) + +$(LIBC_SYSV_CALLS_A_OBJS): \ + o/libc/sysv/macros.inc + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_SYSV_MACHCALLS = \ + $(LIBC_SYSV_MACHCALLS_A_DEPS) \ + $(LIBC_SYSV_MACHCALLS_A) + +LIBC_SYSV_ARTIFACTS += LIBC_SYSV_MACHCALLS_A +LIBC_SYSV_MACHCALLS_A = o/libc/sysv/machcalls.a +LIBC_SYSV_MACHCALLS_A_SRCS := $(wildcard libc/sysv/machcalls/*.s) +LIBC_SYSV_MACHCALLS_A_OBJS = $(LIBC_SYSV_MACHCALLS_A_SRCS:%.s=o/%.o) +LIBC_SYSV_MACHCALLS_A_CHECKS = $(LIBC_SYSV_MACHCALLS_A).pkg + +LIBC_SYSV_MACHCALLS_A_DIRECTDEPS = \ + LIBC_SYSV + +LIBC_SYSV_MACHCALLS_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_SYSV_MACHCALLS_A_DIRECTDEPS),$($(x)))) + +$(LIBC_SYSV_MACHCALLS_A): \ + libc/sysv/machcalls/ \ + $(LIBC_SYSV_MACHCALLS_A).pkg \ + $(LIBC_SYSV_MACHCALLS_A_OBJS) + +$(LIBC_SYSV_MACHCALLS_A).pkg: \ + $(LIBC_SYSV_MACHCALLS_A_OBJS) \ + $(foreach x,$(LIBC_SYSV_MACHCALLS_A_DIRECTDEPS),$($(x)_A).pkg) + +$(LIBC_SYSV_MACHCALLS_A_OBJS): \ + o/libc/sysv/macros.inc + +#─────────────────────────────────────────────────────────────────────────────── + +.PHONY: o/libc/sysv +o/libc/sysv: $(LIBC_SYSV_CHECKS) + +.PHONY: o/$(MODE)/libc/sysv +o/$(MODE)/libc/sysv: $(LIBC_SYSV_CHECKS) diff --git a/libc/sysv/versions.txt b/libc/sysv/versions.txt new file mode 100644 index 00000000..a99dd23e --- /dev/null +++ b/libc/sysv/versions.txt @@ -0,0 +1,12 @@ +1993 FreeBSD 1.o +1994 FreeBSD 2 +1998 FreeBSD 3 +2000 FreeBSD 4 (EOL 2007) +2003 FreeBSD 5 +2005 FreeBSD 6 +2008 FreeBSD 7 (EOL 2013) +2009 FreeBSD 8 (EOL 2015) +2012 FreeBSD 9 (EOL 2016) +2014 FreeBSD 10 (EOL 2018) +2016 FreeBSD 11 +2018 FreeBSD 12 diff --git a/libc/testlib/almostequal.c b/libc/testlib/almostequal.c new file mode 100644 index 00000000..d4aa7791 --- /dev/null +++ b/libc/testlib/almostequal.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/testlib.h" + +/* ┌sign + │ ┌exponent + │ │ ┌fraction + │ │ │ + │┌┴────────┐┌┴─────────────────────────────────────────────────┐*/ +#define SGN 0b1000000000000000000000000000000000000000000000000000000000000000lu +#define EXP 0b0111111111110000000000000000000000000000000000000000000000000000lu +#define FAC 0b0000000000001111111111111111111111111111111111111111111111111111lu diff --git a/libc/testlib/almostequalf.c b/libc/testlib/almostequalf.c new file mode 100644 index 00000000..1a5af332 --- /dev/null +++ b/libc/testlib/almostequalf.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/testlib.h" + +/* ┌sign + │ ┌exponent + │ │ ┌fraction + │ │ │ + │┌┴─────┐┌┴────────────────────┐*/ +#define BINARY32_SIGN 0b10000000000000000000000000000000u +#define BINARY32_EXPO 0b01111111100000000000000000000000u +#define BINARY32_FRAC 0b00000000011111111111111111111111u diff --git a/libc/testlib/almostequallongdouble.c b/libc/testlib/almostequallongdouble.c new file mode 100644 index 00000000..bfa974ef --- /dev/null +++ b/libc/testlib/almostequallongdouble.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/testlib/testlib.h" + +#define EPSILON 0.0000000000001L + +testonly bool testlib_almostequallongdouble(long double x, long double y) { + /* TODO(jart): This algorithm has to be binary. */ + if (isnan(x) || isnan(y)) return false; + return fabsl(x - y) <= EPSILON; +} diff --git a/libc/testlib/bench.S b/libc/testlib/bench.S new file mode 100644 index 00000000..5ab5c1a4 --- /dev/null +++ b/libc/testlib/bench.S @@ -0,0 +1,43 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + + yoink __FILE__ + yoink testlib_runallbenchmarks + +/ Decentralized section for benchmark registration. +/ +/ @see ape/ape.lds + .section .piro.relo.sort.bench.1,"aw",@nobits + .type __bench_start,@object + .type __bench_end,@object + .globl __bench_start,__bench_end + .hidden __bench_start,__bench_end + .byte 0 + .align __SIZEOF_POINTER__ +__bench_start: + .previous/* + ... + decentralized content + ... + */.section .piro.relo.sort.bench.3,"aw",@nobits +__bench_end: + .quad 0 + .previous diff --git a/libc/testlib/bench.h b/libc/testlib/bench.h new file mode 100644 index 00000000..bb6d0f4d --- /dev/null +++ b/libc/testlib/bench.h @@ -0,0 +1,29 @@ +#ifndef COSMOPOLITAN_LIBC_BENCH_H_ +#define COSMOPOLITAN_LIBC_BENCH_H_ +#include "libc/bits/safemacros.h" +#include "libc/nexgen32e/bench.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * @fileoverview Microbenchmarking tools. + */ + +#define BENCHLOOP(START, STOP, N, INIT, EXPR) \ + ({ \ + int Iter, Count; \ + long double Average, Sample, Time1, Time2; \ + for (Average = 1.0, Iter = 1, Count = (N); Iter < Count; ++Iter) { \ + INIT; \ + Time1 = START(); \ + EXPR; \ + Time2 = STOP(); \ + Sample = Time2 - Time1; \ + Average += (Sample - Average) / Iter; \ + } \ + Average; \ + }) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_BENCH_H_ */ diff --git a/libc/testlib/benchrunner.c b/libc/testlib/benchrunner.c new file mode 100644 index 00000000..201b945a --- /dev/null +++ b/libc/testlib/benchrunner.c @@ -0,0 +1,60 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/kntprioritycombos.h" +#include "libc/log/log.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/mlock.h" +#include "libc/testlib/testlib.h" + +double g_avx2_juiceup_doubles_[4] aligned(32); +unsigned long long g_avx2_juiceup_quadwords_[4] aligned(32); + +void testlib_benchwarmup(void) { + /* get mathematical parts of cpu juiced up */ + if (X86_HAVE(AVX2) && X86_HAVE(FMA)) { + asm("vmovdqa\t%1,%%ymm0\n\t" + "vpmaddwd\t(%2),%%ymm0,%%ymm0\n\t" + "vmovdqa\t%%ymm0,%0\n\t" + "vzeroall" + : "=m"(g_avx2_juiceup_quadwords_) + : "m"(g_avx2_juiceup_quadwords_), "r"(&_base[0])); + asm("vmovapd\t%1,%%ymm1\n\t" + "vfmadd132pd\t(%2),%%ymm1,%%ymm1\n\t" + "vmovapd\t%%ymm1,%0\n\t" + "vzeroall" + : "=m"(g_avx2_juiceup_doubles_) + : "m"(g_avx2_juiceup_doubles_), "r"(&_base[32])); + } +} + +/** + * Runs all benchmark functions in sorted order. + * + * @see BENCH() + */ +void testlib_runallbenchmarks(void) { + peekall(); + mlockall(MCL_CURRENT); + nice(-1); + g_loglevel = kLogWarn; + testlib_runtestcases(__bench_start, __bench_end, testlib_benchwarmup); +} diff --git a/libc/testlib/binequals.c b/libc/testlib/binequals.c new file mode 100644 index 00000000..33d0af3c --- /dev/null +++ b/libc/testlib/binequals.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +/** + * Tests that raw memory is equal to visual representation, e.g. + * + * testlib_binequals(u" ☺☻♥", "\0\1\2\3", -1ul); + * + * @see libc/nexgen32e/kCp437.S + */ +testonly bool testlib_binequals(const char16_t *want, const void *got, + size_t n) { + size_t i; + const unsigned char *p = (const unsigned char *)got; + if (!got) return false; + for (i = 0; i < n; ++i) { + if (!want[i]) break; + if (i == n) break; + if (want[i] != kCp437[p[i]]) return false; + } + return true; +} diff --git a/libc/testlib/combo.S b/libc/testlib/combo.S new file mode 100644 index 00000000..dd93dbae --- /dev/null +++ b/libc/testlib/combo.S @@ -0,0 +1,41 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Decentralized section for test combo registration. +/ +/ @see ape/ape.lds + .section .piro.relo.sort.combo.1,"aw",@nobits + .type __combo_start,@object + .type __combo_end,@object + .globl __combo_start,__combo_end + .hidden __combo_start,__combo_end + .byte 0 + .align __SIZEOF_POINTER__ +__combo_start: + .previous/* + ... + decentralized content + ... + */.section .piro.relo.sort.combo.3,"aw",@nobits +__combo_end: + .quad 0 + .previous diff --git a/libc/testlib/comborunner.c b/libc/testlib/comborunner.c new file mode 100644 index 00000000..59f919e4 --- /dev/null +++ b/libc/testlib/comborunner.c @@ -0,0 +1,100 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/fmt/fmt.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +struct ComboGroup { + unsigned entry; + unsigned i; + unsigned n; +}; + +struct ComboProduct { + unsigned n; + struct ComboGroup groups[]; +}; + +mallocesque testonly struct ComboProduct *testlib_setupcomboproduct( + const struct TestFixture *start, const struct TestFixture *end) { + unsigned i, j, entrycount; + struct ComboProduct *product; + entrycount = testlib_countfixtures(start, end); + product = calloc( + sizeof(struct ComboProduct) + entrycount * sizeof(struct ComboGroup), 1); + for (j = i = 0; i < entrycount; ++i) { + if (j && strcmp(start[product->groups[j - 1].entry].group, + start[i].group) == 0) { + product->groups[j - 1].n++; + } else { + ++j; + product->groups[j - 1].entry = i; + product->groups[j - 1].n = 1; + } + } + product->n = j; + return product; +} + +static testonly void testlib_describecombo(struct ComboProduct *product, + const struct TestFixture *combos) { + char *p = &g_fixturename[0]; + char *pe = p + sizeof(g_fixturename); + for (unsigned i = 0; i < product->n && p < pe; ++i) { + const char *sep = i ? ", " : ""; + const struct TestFixture *e = + &combos[product->groups[i].entry + product->groups[i].i]; + p += max(0, snprintf(p, pe - p, "%s%s=%s", sep, e->group, e->name)); + } +} + +static testonly void testlib_callcombos(struct ComboProduct *product, + const struct TestFixture *combos, + testfn_t *test_start, + testfn_t *test_end) { + for (;;) { + testlib_describecombo(product, combos); + for (unsigned i = 0; i < product->n; ++i) { + combos[product->groups[i].entry + product->groups[i].i].fn(); + } + for (unsigned i = product->n;; --i) { + if (!i) return; + if (++product->groups[i - 1].i < product->groups[i - 1].n) break; + product->groups[i - 1].i = 0; + } + testlib_runtestcases(test_start, test_end, NULL); + } +} + +/** + * Runs Cartesian product of COMBO() fixtures registered with linker. + * @see ape/ape.lds + * @see libc/testlib/testlib.h + */ +testonly void testlib_runcombos(testfn_t *test_start, testfn_t *test_end, + const struct TestFixture *combo_start, + const struct TestFixture *combo_end) { + struct ComboProduct *product; + product = testlib_setupcomboproduct(combo_start, combo_end); + testlib_callcombos(product, combo_start, test_start, test_end); + free(product); +} diff --git a/libc/testlib/contains.c b/libc/testlib/contains.c new file mode 100644 index 00000000..da26392c --- /dev/null +++ b/libc/testlib/contains.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +testonly bool testlib_contains(size_t cw, const void *s, const void *needle) { + if (s == needle) return true; + if (!s || !needle) return false; + return sizeof(cw) == sizeof(char16_t) ? !!strstr16(s, needle) + : !!strstr(s, needle); +} diff --git a/libc/testlib/endswith.c b/libc/testlib/endswith.c new file mode 100644 index 00000000..c1286d72 --- /dev/null +++ b/libc/testlib/endswith.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +testonly bool testlib_endswith(size_t cw, const void *s, const void *suffix) { + if (s == suffix) return true; + if (!s || !suffix) return false; + return cw == sizeof(wchar_t) ? wcsendswith(s, suffix) + : cw == sizeof(char16_t) ? endswith16(s, suffix) + : endswith(s, suffix); +} diff --git a/libc/testlib/ezbench.h b/libc/testlib/ezbench.h new file mode 100644 index 00000000..a7286234 --- /dev/null +++ b/libc/testlib/ezbench.h @@ -0,0 +1,29 @@ +#ifndef COSMOPOLITAN_LIBC_TESTLIB_EZBENCH_H_ +#define COSMOPOLITAN_LIBC_TESTLIB_EZBENCH_H_ +#include "libc/macros.h" +#include "libc/testlib/bench.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define EZBENCH(INIT, EXPR) EZBENCH2(#EXPR, INIT, EXPR) +#define EZBENCH2(NAME, INIT, EXPR) \ + do { \ + uint64_t Control, Speculative, MemoryStrict; \ + Control = __testlib_ezbenchcontrol(); \ + INIT; \ + EXPR; \ + Speculative = BENCHLOOP(__startbench, __endbench, 128, INIT, (EXPR)); \ + MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, 8, ({ \ + INIT; \ + thrashcodecache(); \ + }), \ + (EXPR)); \ + Control = MIN(Control, MIN(Speculative, MemoryStrict)); \ + __testlib_ezbenchreport(NAME, Speculative - Control, \ + MemoryStrict - Control); \ + } while (0) + +void __testlib_ezbenchreport(const char *, uint64_t, uint64_t); +uint64_t __testlib_ezbenchcontrol(void); + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_TESTLIB_EZBENCH_H_ */ diff --git a/libc/testlib/ezbenchcontrol.c b/libc/testlib/ezbenchcontrol.c new file mode 100644 index 00000000..d90eb92c --- /dev/null +++ b/libc/testlib/ezbenchcontrol.c @@ -0,0 +1,25 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/bench.h" +#include "libc/testlib/testlib.h" + +uint64_t __testlib_ezbenchcontrol(void) { + return BENCHLOOP(__startbench, __endbench, 128, donothing, (void)0); +} diff --git a/libc/testlib/ezbenchreport.c b/libc/testlib/ezbenchreport.c new file mode 100644 index 00000000..713abdae --- /dev/null +++ b/libc/testlib/ezbenchreport.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/stdio/stdio.h" +#include "libc/testlib/testlib.h" +#include "libc/time/time.h" + +STATIC_YOINK("ntoa"); +STATIC_YOINK("stoa"); + +void __testlib_ezbenchreport(const char *form, uint64_t c1, uint64_t c2) { + uint64_t ns1, ns2; + ns1 = lrintl(converttickstonanos(c1)); + ns2 = lrintl(converttickstonanos(c2)); + (fprintf)(stderr, + VEIL("r", "%-30s l: %,10lu𝑐 %,10lu𝑛𝑠 m: %,10lu𝑐 %,10lu𝑛𝑠\n"), + form, c1, ns1, c2, ns2); +} diff --git a/libc/testlib/fixture.S b/libc/testlib/fixture.S new file mode 100644 index 00000000..cf5ac3dd --- /dev/null +++ b/libc/testlib/fixture.S @@ -0,0 +1,41 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Decentralized section for test fixture registration. +/ +/ @see ape/ape.lds + .section .piro.relo.sort.fixture.1,"aw",@nobits + .type __fixture_start,@object + .type __fixture_end,@object + .globl __fixture_start,__fixture_end + .hidden __fixture_start,__fixture_end + .byte 0 + .align __SIZEOF_POINTER__ +__fixture_start: + .previous/* + ... + decentralized content + ... + */.section .piro.relo.sort.fixture.3,"aw",@nobits +__fixture_end: + .quad 0 + .previous diff --git a/libc/testlib/fixturerunner.c b/libc/testlib/fixturerunner.c new file mode 100644 index 00000000..e282219b --- /dev/null +++ b/libc/testlib/fixturerunner.c @@ -0,0 +1,48 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/fmt/fmt.h" +#include "libc/runtime/internal.h" +#include "libc/sysv/consts/prot.h" +#include "libc/testlib/testlib.h" + +testonly int testlib_countfixtures(const struct TestFixture *start, + const struct TestFixture *end) { + return ((intptr_t)end - (intptr_t)start) / sizeof(struct TestFixture); +} + +/** + * Runs test cases for each FIXTURE() registered with the linker. + * @see ape/ape.lds + * @see libc/testlib/testlib.h + */ +testonly void testlib_runfixtures(testfn_t *test_start, testfn_t *test_end, + const struct TestFixture *fixture_start, + const struct TestFixture *fixture_end) { + unsigned i, count; + count = testlib_countfixtures(fixture_start, fixture_end); + for (i = 0; i < count && !g_testlib_failed; ++i) { + snprintf(g_fixturename, sizeof(g_fixturename), "%s_%s", + fixture_start[i].group, fixture_start[i].name); + __piro(PROT_READ | PROT_WRITE); + fixture_start[i].fn(); + __piro(PROT_READ); + testlib_runtestcases(test_start, test_end, NULL); + } +} diff --git a/libc/testlib/formatbinaryasglyphs.c b/libc/testlib/formatbinaryasglyphs.c new file mode 100644 index 00000000..076b2ae7 --- /dev/null +++ b/libc/testlib/formatbinaryasglyphs.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +testonly void testlib_formatbinaryasglyphs(const char16_t *want, + const void *got, size_t n, + char **out_v1, char **out_v2) { + if (n == -1ul) n = strlen(want); + *out_v1 = xasprintf("%`#.*hs", n, want); + *out_v2 = xasprintf(" %`'#.*s", n, got); +} diff --git a/libc/testlib/formatbinaryashex.c b/libc/testlib/formatbinaryashex.c new file mode 100644 index 00000000..b2cbd041 --- /dev/null +++ b/libc/testlib/formatbinaryashex.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/mem/mem.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +testonly void testlib_formatbinaryashex(const char *want, const void *got, + size_t n, char **out_v1, + char **out_v2) { + size_t i; + uint8_t b; + char *gothex; + if (n == -1ul) n = strlen(want) / 2; + gothex = xmalloc(n * 2 + 1); + gothex[n * 2] = '\0'; + for (i = 0; i < n; ++i) { + b = ((uint8_t *)got)[i]; + gothex[i * 2 + 0] = "0123456789abcdef"[(b >> 4) & 0xf]; + gothex[i * 2 + 1] = "0123456789abcdef"[(b >> 0) & 0xf]; + } + *out_v1 = strdup(want); + *out_v2 = gothex; +} diff --git a/libc/testlib/formatbool.c b/libc/testlib/formatbool.c new file mode 100644 index 00000000..ba6dd752 --- /dev/null +++ b/libc/testlib/formatbool.c @@ -0,0 +1,27 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/testlib.h" + +static const char kTrueStr[] = "true"; +static const char kFalseStr[] = "false"; + +char *testlib_formatbool(bool v) { + return (/*unconst*/ char *)(v ? kTrueStr : kFalseStr); +} diff --git a/libc/testlib/formatfloat.c b/libc/testlib/formatfloat.c new file mode 100644 index 00000000..18cd5dde --- /dev/null +++ b/libc/testlib/formatfloat.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/fmt/fmt.h" +#include "libc/mem/mem.h" +#include "libc/testlib/testlib.h" +#include "third_party/dtoa/dtoa.h" + +testonly char *testlib_formatfloat(long double x) { + char dtoabuf[32]; + char *str = malloc(256); + sprintf(str, "%Lf (%s)", x, g_fmt(dtoabuf, x)); + return str; +} diff --git a/libc/testlib/formatint.c b/libc/testlib/formatint.c new file mode 100644 index 00000000..b398552e --- /dev/null +++ b/libc/testlib/formatint.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/fmt/fmt.h" +#include "libc/macros.h" +#include "libc/mem/mem.h" +#include "libc/testlib/testlib.h" + +static size_t sbufi_; +static char sbufs_[2][256]; + +nodiscard testonly char *testlib_formatint(intmax_t x) { + char *str = sbufi_ < ARRAYLEN(sbufs_) ? sbufs_[sbufi_++] : malloc(256); + char *p = str; + p += sprintf(p, "%jd\t(or %#jx", x, x); + if (0 <= x && x < 256) { + p += sprintf(p, " or %#`c", (unsigned char)x); + } + *p++ = ')'; + *p++ = '\0'; + return str; +} diff --git a/libc/testlib/formatrange.c b/libc/testlib/formatrange.c new file mode 100644 index 00000000..1d0242ed --- /dev/null +++ b/libc/testlib/formatrange.c @@ -0,0 +1,25 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +nodiscard testonly char *testlib_formatrange(intmax_t beg, intmax_t end) { + return xasprintf("[%#jx,%#jx]", beg, end); +} diff --git a/libc/testlib/formatstr.c b/libc/testlib/formatstr.c new file mode 100644 index 00000000..a766699f --- /dev/null +++ b/libc/testlib/formatstr.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/progn.h" +#include "libc/bits/safemacros.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +/** + * Turns string into code. + */ +nodiscard testonly char *testlib_formatstr(size_t cw, const void *s, int n) { + switch (cw) { + case 1: + if (n == -1) n = s ? strlen(s) : 0; + return xasprintf("%`'.*s", n, s); + case 2: + if (n == -1) n = s ? strlen16(s) : 0; + return xasprintf("%`'.*hs", n, s); + case 4: + if (n == -1) n = s ? wcslen(s) : 0; + return xasprintf("%`'.*ls", n, s); + default: + abort(); + } +} diff --git a/libc/testlib/globals.c b/libc/testlib/globals.c new file mode 100644 index 00000000..24da12c6 --- /dev/null +++ b/libc/testlib/globals.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/testlib.h" + +char g_fixturename[256]; +unsigned g_testlib_ran; +unsigned g_testlib_failed; diff --git a/libc/testlib/hexequals.c b/libc/testlib/hexequals.c new file mode 100644 index 00000000..4860941f --- /dev/null +++ b/libc/testlib/hexequals.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +/** + * Tests that raw memory is equal to numeric representation, e.g. + * + * testlib_hexequals("00010203", "\0\1\2\3", -1ul); + * + * @see unhexstr() + */ +testonly bool testlib_hexequals(const char *want, const void *got, size_t n) { + size_t i; + const unsigned char *p = (const unsigned char *)got; + if (!got) return false; + for (i = 0; i < n; ++i) { + if (!want[i * 2]) break; + if (i == n) break; + if (p[i] != (unsigned char)(hextoint(want[i * 2 + 0]) * 16 + + hextoint(want[i * 2 + 1]))) { + return false; + } + } + return true; +} diff --git a/libc/testlib/hyperion.S b/libc/testlib/hyperion.S new file mode 100644 index 00000000..29769a20 --- /dev/null +++ b/libc/testlib/hyperion.S @@ -0,0 +1,34 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.rodata +.yoink __FILE__ + +/ Nontrivial NUL-terminated string test vector. + .align 1 +kHyperion: +0: .incbin "libc/testlib/hyperion.txt" +1: .byte 0 + .endobj kHyperion,globl + + .align 8 +kHyperionSize: + .quad 1b-0b + .endobj kHyperionSize,globl diff --git a/libc/testlib/hyperion.h b/libc/testlib/hyperion.h new file mode 100644 index 00000000..1132f0c1 --- /dev/null +++ b/libc/testlib/hyperion.h @@ -0,0 +1,12 @@ +#ifndef COSMOPOLITAN_LIBC_TESTLIB_HYPERION_H_ +#define COSMOPOLITAN_LIBC_TESTLIB_HYPERION_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +extern size_t kHyperionSize; +extern char kHyperion[]; +extern uint8_t kHyperionZip[]; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_TESTLIB_HYPERION_H_ */ diff --git a/libc/testlib/hyperion.txt b/libc/testlib/hyperion.txt new file mode 100644 index 00000000..715437cb --- /dev/null +++ b/libc/testlib/hyperion.txt @@ -0,0 +1,547 @@ +The fall of Hyperion - a Dream +John Keats + + +CANTO I + +Fanatics have their dreams, wherewith they weave +A paradise for a sect; the savage too +From forth the loftiest fashion of his sleep +Guesses at Heaven; pity these have not +Trac'd upon vellum or wild Indian leaf +The shadows of melodious utterance. +But bare of laurel they live, dream, and die; +For Poesy alone can tell her dreams, +With the fine spell of words alone can save +Imagination from the sable charm +And dumb enchantment. Who alive can say, +'Thou art no Poet may'st not tell thy dreams?' +Since every man whose soul is not a clod +Hath visions, and would speak, if he had loved +And been well nurtured in his mother tongue. +Whether the dream now purpos'd to rehearse +Be poet's or fanatic's will be known +When this warm scribe my hand is in the grave. + +Methought I stood where trees of every clime, +Palm, myrtle, oak, and sycamore, and beech, +With plantain, and spice blossoms, made a screen; +In neighbourhood of fountains, by the noise +Soft showering in my ears, and, by the touch +Of scent, not far from roses. Turning round +I saw an arbour with a drooping roof +Of trellis vines, and bells, and larger blooms, +Like floral censers swinging light in air; +Before its wreathed doorway, on a mound +Of moss, was spread a feast of summer fruits, +Which, nearer seen, seem'd refuse of a meal +By angel tasted or our Mother Eve; +For empty shells were scattered on the grass, +And grape stalks but half bare, and remnants more, +Sweet smelling, whose pure kinds I could not know. +Still was more plenty than the fabled horn +Thrice emptied could pour forth, at banqueting +For Proserpine return'd to her own fields, +Where the white heifers low. And appetite +More yearning than on earth I ever felt +Growing within, I ate deliciously; +And, after not long, thirsted, for thereby +Stood a cool vessel of transparent juice +Sipp'd by the wander'd bee, the which I took, +And, pledging all the mortals of the world, +And all the dead whose names are in our lips, +Drank. That full draught is parent of my theme. +No Asian poppy nor elixir fine +Of the soon fading jealous Caliphat, +No poison gender'd in close monkish cell +To thin the scarlet conclave of old men, +Could so have rapt unwilling life away. +Among the fragrant husks and berries crush'd, +Upon the grass I struggled hard against +The domineering potion; but in vain: +The cloudy swoon came on, and down I sunk +Like a Silenus on an antique vase. +How long I slumber'd 'tis a chance to guess. +When sense of life return'd, I started up +As if with wings; but the fair trees were gone, +The mossy mound and arbour were no more: +I look'd around upon the carved sides +Of an old sanctuary with roof august, +Builded so high, it seem'd that filmed clouds +Might spread beneath, as o'er the stars of heaven; +So old the place was, I remember'd none +The like upon the earth: what I had seen +Of grey cathedrals, buttress'd walls, rent towers, +The superannuations of sunk realms, +Or Nature's rocks toil'd hard in waves and winds, +Seem'd but the faulture of decrepit things +To that eternal domed monument. +Upon the marble at my feet there lay +Store of strange vessels and large draperies, +Which needs had been of dyed asbestos wove, +Or in that place the moth could not corrupt, +So white the linen, so, in some, distinct +Ran imageries from a sombre loom. +All in a mingled heap confus'd there lay +Robes, golden tongs, censer and chafing dish, +Girdles, and chains, and holy jewelries. + +Turning from these with awe, once more I rais'd +My eyes to fathom the space every way; +The embossed roof, the silent massy range +Of columns north and south, ending in mist +Of nothing, then to eastward, where black gates +Were shut against the sunrise evermore. +Then to the west I look'd, and saw far off +An image, huge of feature as a cloud, +At level of whose feet an altar slept, +To be approach'd on either side by steps, +And marble balustrade, and patient travail +To count with toil the innumerable degrees. +Towards the altar sober paced I went, +Repressing haste, as too unholy there; +And, coming nearer, saw beside the shrine +One minist'ring; and there arose a flame. +When in mid May the sickening East wind +Shifts sudden to the south, the small warm rain +Melts out the frozen incense from all flowers, +And fills the air with so much pleasant health +That even the dying man forgets his shroud; +Even so that lofty sacrificial fire, +Sending forth Maian incense, spread around +Forgetfulness of everything but bliss, +And clouded all the altar with soft smoke, +From whose white fragrant curtains thus I heard +Language pronounc'd: 'If thou canst not ascend +'These steps, die on that marble where thou art. +'Thy flesh, near cousin to the common dust, +'Will parch for lack of nutriment thy bones +'Will wither in few years, and vanish so +'That not the quickest eye could find a grain +'Of what thou now art on that pavement cold. +'The sands of thy short life are spent this hour, +'And no hand in the universe can turn +'Thy hourglass, if these gummed leaves be burnt +'Ere thou canst mount up these immortal steps.' +I heard, I look'd: two senses both at once, +So fine, so subtle, felt the tyranny +Of that fierce threat and the hard task proposed. +Prodigious seem'd the toil, the leaves were yet +Burning when suddenly a palsied chill +Struck from the paved level up my limbs, +And was ascending quick to put cold grasp +Upon those streams that pulse beside the throat: +I shriek'd; and the sharp anguish of my shriek +Stung my own ears I strove hard to escape +The numbness; strove to gain the lowest step. +Slow, heavy, deadly was my pace: the cold +Grew stifling, suffocating, at the heart; +And when I clasp'd my hands I felt them not. +One minute before death, my iced foot touch'd +The lowest stair; and as it touch'd, life seem'd +To pour in at the toes: I mounted up, +As once fair angels on a ladder flew +From the green turf to Heaven. 'Holy Power,' +Cried I, approaching near the horned shrine, +'What am I that should so be saved from death? +'What am I that another death come not +'To choke my utterance sacrilegious here?' +Then said the veiled shadow 'Thou hast felt +'What 'tis to die and live again before +'Thy fated hour. That thou hadst power to do so +'Is thy own safety; thou hast dated on +'Thy doom.' 'High Prophetess,' said I, 'purge off, +'Benign, if so it please thee, my mind's film.' +'None can usurp this height,' return'd that shade, +'But those to whom the miseries of the world +'Are misery, and will not let them rest. +'All else who find a haven in the world, +'Where they may thoughtless sleep away their days, +'If by a chance into this fane they come, +'Rot on the pavement where thou rottedst half.' +'Are there not thousands in the world,' said I, +Encourag'd by the sooth voice of the shade, +'Who love their fellows even to the death; +'Who feel the giant agony of the world; +'And more, like slaves to poor humanity, +'Labour for mortal good? I sure should see +'Other men here; but I am here alone.' +'Those whom thou spak'st of are no vision'ries,' +Rejoin'd that voice; 'they are no dreamers weak; +'They seek no wonder but the human face, +'No music but a happy noted voice; +'They come not here, they have no thought to come; +'And thou art here, for thou art less than they: +'What benefit canst thou do, or all thy tribe, +'To the great world? Thou art a dreaming thing, +'A fever of thyself think of the Earth; +'What bliss even in hope is there for thee? +'What haven? every creature hath its home; +'Every sole man hath days of joy and pain, +'Whether his labours be sublime or low +'The pain alone; the joy alone; distinct: +'Only the dreamer venoms all his days, +'Bearing more woe than all his sins deserve. +'Therefore, that happiness be somewhat shar'd, +'Such things as thou art are admitted oft +'Into like gardens thou didst pass erewhile, +'And suffer'd in these temples: for that cause +'Thou standest safe beneath this statue's knees.' +'That I am favour'd for unworthiness, +'By such propitious parley medicin'd +'In sickness not ignoble, I rejoice, +'Aye, and could weep for love of such award.' +So answer'd I, continuing, 'If it please, +'Majestic shadow, tell me: sure not all +'Those melodies sung into the world's ear +'Are useless: sure a poet is a sage; +'A humanist, physician to all men. +'That I am none I feel, as vultures feel +'They are no birds when eagles are abroad. +'What am I then? Thou spakest of my tribe: +'What tribe?' The tall shade veil'd in drooping white +Then spake, so much more earnest, that the breath +Moved the thin linen folds that drooping hung +About a golden censer from the hand +Pendent. 'Art thou not of the dreamer tribe? +'The poet and the dreamer are distinct, +'Diverse, sheer opposite, antipodes. +'The one pours out a balm upon the world, +'The other vexes it.' Then shouted I +Spite of myself, and with a Pythia's spleen, +'Apollo! faded! O far flown Apollo! +'Where is thy misty pestilence to creep +'Into the dwellings, through the door crannies +'Of all mock lyrists, large self worshipers, +'And careless Hectorers in proud bad verse. +'Though I breathe death with them it will be life +'To see them sprawl before me into graves. +'Majestic shadow, tell me where I am, +'Whose altar this; for whom this incense curls; +'What image this whose face I cannot see, +'For the broad marble knees; and who thou art, +'Of accent feminine so courteous?' + +Then the tall shade, in drooping linens veil'd, +Spoke out, so much more earnest, that her breath +Stirr'd the thin folds of gauze that drooping hung +About a golden censer from her hand +Pendent; and by her voice I knew she shed +Long treasured tears. 'This temple, sad and lone, +'Is all spar'd from the thunder of a war +'Foughten long since by giant hierarchy +'Against rebellion: this old image here, +'Whose carved features wrinkled as he fell, +'Is Saturn's; I Moneta, left supreme +'Sole priestess of this desolation.' +I had no words to answer, for my tongue, +Useless, could find about its roofed home +No syllable of a fit majesty +To make rejoinder to Moneta's mourn. +There was a silence, while the altar's blaze +Was fainting for sweet food: I look'd thereon, +And on the paved floor, where nigh were piled +Faggots of cinnamon, and many heaps +Of other crisped spice wood then again +I look'd upon the altar, and its horns +Whiten'd with ashes, and its lang'rous flame, +And then upon the offerings again; +And so by turns till sad Moneta cried, +'The sacrifice is done, but not the less +'Will I be kind to thee for thy good will. +'My power, which to me is still a curse, +'Shall be to thee a wonder; for the scenes +'Still swooning vivid through my globed brain +'With an electral changing misery +'Thou shalt with those dull mortal eyes behold, +'Free from all pain, if wonder pain thee not.' +As near as an immortal's sphered words +Could to a mother's soften, were these last: +And yet I had a terror of her robes, +And chiefly of the veils, that from her brow +Hung pale, and curtain'd her in mysteries +That made my heart too small to hold its blood. +This saw that G-ddess, and with sacred hand +Parted the veils. Then saw I a wan face, +Not pin'd by human sorrows, but bright blanch'd +By an immortal sickness which kills not; +It works a constant change, which happy death +Can put no end to; deathwards progressing +To no death was that visage; it had pass'd +The lily and the snow; and beyond these +I must not think now, though I saw that face +But for her eyes I should have fled away. +They held me back, with a benignant light +Soft mitigated by divinest lids +Half closed, and visionless entire they seem'd +Of all external things; they saw me not, +But in blank splendour beam'd like the mild moon, +Who comforts those she sees not, who knows not +What eyes are upward cast. As I had found +A grain of gold upon a mountain side, +And twing'd with avarice strain'd out my eyes +To search its sullen entrails rich with ore, +So at the view of sad Moneta's brow +I ach'd to see what things the hollow brain +Behind enwombed: what high tragedy +In the dark secret chambers of her skull +Was acting, that could give so dread a stress +To her cold lips, and fill with such a light +Her planetary eyes, and touch her voice +With such a sorrow 'Shade of Memory!' +Cried I, with act adorant at her feet, +'By all the gloom hung round thy fallen house, +'By this last temple, by the golden age, +'By great Apollo, thy dear Foster Child, +'And by thyself, forlorn divinity, +'The pale Omega of a withered race, +'Let me behold, according as thou saidst, +'What in thy brain so ferments to and fro!' +No sooner had this conjuration pass'd +My devout lips, than side by side we stood +(Like a stunt bramble by a solemn pine) +Deep in the shady sadness of a vale, +Far sunken from the healthy breath of morn, +Far from the fiery noon and eve's one star. +Onward I look'd beneath the gloomy boughs, +And saw, what first I thought an image huge, +Like to the image pedestal'd so high +In Saturn's temple. Then Moneta's voice +Came brief upon mine ear 'So Saturn sat +When he had lost his realms ' whereon there grew +A power within me of enormous ken +To see as a g-d sees, and take the depth +Of things as nimbly as the outward eye +Can size and shape pervade. The lofty theme +At those few words hung vast before my mind, +With half unravel'd web. I set myself +Upon an eagle's watch, that I might see, +And seeing ne'er forget. No stir of life +Was in this shrouded vale, not so much air +As in the zoning of a summer's day +Robs not one light seed from the feather'd grass, +But where the dead leaf fell there did it rest. +A stream went voiceless by, still deaden'd more +By reason of the fallen divinity +Spreading more shade; the Naiad 'mid her reeds +Press'd her cold finger closer to her lips. +Along the margin sand large footmarks went +No farther than to where old Saturn's feet +Had rested, and there slept, how long a sleep! +Degraded, cold, upon the sodden ground +His old right hand lay nerveless, listless, dead, +Unsceptred; and his realmless eyes were clos'd, +While his bow'd head seem'd listening to the Earth, +His ancient mother, for some comfort yet. + +It seem'd no force could wake him from his place; +But there came one who with a kindred hand +Touch'd his wide shoulders after bending low +With reverence, though to one who knew it not. +Then came the griev'd voice of Mnemosyne, +And griev'd I hearken'd. 'That divinity +'Whom thou saw'st step from yon forlornest wood, +'And with slow pace approach our fallen King, +'Is Thea, softest natur'd of our brood.' +I mark'd the G-ddess in fair statuary +Surpassing wan Moneta by the head, +And in her sorrow nearer woman's tears. +There was a listening fear in her regard, +As if calamity had but begun; +As if the vanward clouds of evil days +Had spent their malice, and the sullen rear +Was with its stored thunder labouring up. +One hand she press'd upon that aching spot +Where beats the human heart, as if just there, +Though an immortal, she felt cruel pain; +The other upon Saturn's bended neck +She laid, and to the level of his hollow ear +Leaning with parted lips, some words she spake +In solemn tenor and deep organ tune; +Some mourning words, which in our feeble tongue +Would come in this like accenting; how frail +To that large utterance of the early G-ds! +'Saturn! look up and for what, poor lost King? +'I have no comfort for thee; no not one; +'I cannot cry, Wherefore thus sleepest thou? +'For Heaven is parted from thee, and the Earth +'Knows thee not, so afflicted, for a G-d; +'And Ocean too, with all its solemn noise, +'Has from thy sceptre pass'd, and all the air +'Is emptied of thine hoary majesty: +'Thy thunder, captious at the new command, +'Rumbles reluctant o'er our fallen house; +'And thy sharp lightning, in unpracticed hands, +'Scorches and burns our once serene domain. +'With such remorseless speed still come new woes, +'That unbelief has not a space to breathe. +'Saturn! sleep on: Me thoughtless, why should I +'Thus violate thy slumbrous solitude? +'Why should I ope thy melancholy eyes? +'Saturn, sleep on, while at thy feet I weep.' + +As when upon a tranced summer night +Forests, branch charmed by the earnest stars, +Dream, and so dream all night without a noise, +Save from one gradual solitary gust, +Swelling upon the silence; dying off; +As if the ebbing air had but one wave; +So came these words, and went; the while in tears +She press'd her fair large forehead to the earth, +Just where her fallen hair might spread in curls +A soft and silken mat for Saturn's feet. +Long, long those two were postured motionless, +Like sculpture builded up upon the grave +Of their own power. A long awful time +I look'd upon them: still they were the same; +The frozen G-d still bending to the earth, +And the sad G-ddess weeping at his feet, +Moneta silent. Without stay or prop +But my own weak mortality, I bore +The load of this eternal quietude, +The unchanging gloom, and the three fixed shapes +Ponderous upon my senses, a whole moon. +For by my burning brain I measured sure +Her silver seasons shedded on the night, +And ever day by day methought I grew +More gaunt and ghostly. Oftentimes I pray'd +Intense, that Death would take me from the vale +And all its burthens gasping with despair +Of change, hour after hour I curs'd myself; +Until old Saturn rais'd his faded eyes, +And look'd around and saw his kingdom gone, +And all the gloom and sorrow of the place, +And that fair kneeling G-ddess at his feet. +As the moist scent of flowers, and grass, and leaves +Fills forest dells with a pervading air, +Known to the woodland nostril, so the words +Of Saturn fill'd the mossy glooms around, +Even to the hollows of time eaten oaks +And to the windings of the foxes' hole, +With sad low tones, while thus he spake, and sent +Strange musings to the solitary Pan. +'Moan, brethren, moan; for we are swallow'd up +'And buried from all G-dlike exercise +'Of influence benign on planets pale, +'And peaceful sway above man's harvesting, +'And all those acts which Deity supreme +'Doth ease its heart of love in. Moan and wail, +'Moan, brethren, moan; for lo, the rebel spheres +'Spin round, the stars their ancient courses keep, +'Clouds still with shadowy moisture haunt the earth, +'Still suck their fill of light from sun and moon, +'Still buds the tree, and still the sea shores murmur; +'There is no death in all the Universe, +'No smell of death there shall be death Moan, moan, +'Moan, Cybele, moan; for thy pernicious babes +'Have changed a G-d into a shaking Palsy. +'Moan, brethren, moan, for I have no strength left, +'Weak as the reed weak feeble as my voice +'O, O, the pain, the pain of feebleness. +'Moan, moan, for still I thaw or give me help; +'Throw down those imps, and give me victory. +'Let me hear other groans, and trumpets blown +'Of triumph calm, and hymns of festival +'From the gold peaks of Heaven's high piled clouds; +'Voices of soft proclaim, and silver stir +'Of strings in hollow shells; and let there be +'Beautiful things made new, for the surprise +'Of the sky children.' So he feebly ceas'd, +With such a poor and sickly sounding pause, +Methought I heard some old man of the earth +Bewailing earthly loss; nor could my eyes +And ears act with that pleasant unison of sense +Which marries sweet sound with the grace of form, +And dolorous accent from a tragic harp +With large limb'd visions. More I scrutinized: +Still fix'd he sat beneath the sable trees, +Whose arms spread straggling in wild serpent forms, +With leaves all hush'd; his awful presence there +(Now all was silent) gave a deadly lie +To what I erewhile heard only his lips +Trembled amid the white curls of his beard. +They told the truth, though, round, the snowy locks +Hung nobly, as upon the face of heaven +A mid day fleece of clouds. Thea arose, +And stretched her white arm through the hollow dark, +Pointing some whither: whereat he too rose +Like a vast giant, seen by men at sea +To grow pale from the waves at dull midnight. +They melted from my sight into the woods; +Ere I could turn, Moneta cried, 'These twain +'Are speeding to the families of grief, +'Where roof'd in by black rocks they waste, in pain +'And darkness, for no hope.' And she spake on, +As ye may read who can unwearied pass +Onward from the antechamber of this dream, +Where even at the open doors awhile +I must delay, and glean my memory +Of her high phrase: perhaps no further dare. + + +CANTO II + +'Mortal, that thou may'st understand aright, +'I humanize my sayings to thine ear, +'Making comparisons of earthly things; +'Or thou might'st better listen to the wind, +'Whose language is to thee a barren noise, +'Though it blows legend laden through the trees. +'In melancholy realms big tears are shed, +'More sorrow like to this, and such like woe, +'Too huge for mortal tongue, or pen of scribe. +'The Titans fierce, self hid or prison bound, +'Groan for the old allegiance once more, +'Listening in their doom for Saturn's voice. +'But one of our whole eagle brood still keeps +'His sov'reignty, and rule, and majesty; +'Blazing Hyperion on his orbed fire +'Still sits, still snuffs the incense teeming up +'From man to the sun's G-d: yet unsecure, +'For as upon the earth dire prodigies +'Fright and perplex, so also shudders he: +'Nor at dog's howl or gloom bird's Even screech, +'Or the familiar visitings of one +'Upon the first toll of his passing bell: +'But horrors, portioned to a giant nerve, +'Make great Hyperion ache. His palace bright, +'Bastion'd with pyramids of glowing gold, +'And touch'd with shade of bronzed obelisks, +'Glares a blood red through all the thousand courts, +'Arches, and domes, and fiery galleries: +'And all its curtains of Aurorian clouds +'Flush angerly; when he would taste the wreaths +'Of incense breath'd aloft from sacred hills, +'Instead of sweets his ample palate takes +'Savour of poisonous brass and metals sick. +'Wherefore when harbour'd in the sleepy West, +'After the full completion of fair day, +'For rest divine upon exalted couch +'And slumber in the arms of melody, +'He paces through the pleasant hours of ease +'With strides colossal, on from hall to hall; +'While far within each aisle and deep recess +'His winged minions in close clusters stand +'Amaz'd, and full of fear; like anxious men, +'Who on a wide plain gather in sad troops, +'When earthquakes jar their battlements and towers. +'Even now, while Saturn, roused from icy trance, +'Goes step for step with Thea from yon woods, +'Hyperion, leaving twilight in the rear, +'Is sloping to the threshold of the West. +'Thither we tend.' Now in clear light I stood, +Reliev'd from the dusk vale. Mnemosyne +Was sitting on a square edg'd polish'd stone, +That in its lucid depth reflected pure +Her priestess garments. My quick eyes ran on +From stately nave to nave, from vault to vault, +Through bow'rs of fragrant and enwreathed light +And diamond paved lustrous long arcades. +Anon rush'd by the bright Hyperion; +His flaming robes stream'd out beyond his heels, +And gave a roar, as if of earthly fire, +That scared away the meek ethereal hours +And made their dove wings tremble. On he flared. + + +THE END diff --git a/libc/testlib/incrementfailed.c b/libc/testlib/incrementfailed.c new file mode 100644 index 00000000..0182b0a2 --- /dev/null +++ b/libc/testlib/incrementfailed.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" +#include "libc/testlib/testlib.h" + +void testlib_incrementfailed(void) { + if (++g_testlib_failed > 23) { + fprintf(stderr, "too many failures, aborting\n"); + testlib_abort(); + } +} diff --git a/libc/testlib/runner.c b/libc/testlib/runner.c new file mode 100644 index 00000000..ed0081be --- /dev/null +++ b/libc/testlib/runner.c @@ -0,0 +1,45 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/log/log.h" +#include "libc/nexgen32e/nexgen32e.h" +#include "libc/runtime/missioncritical.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/testlib/testlib.h" + +/** + * Runs all TEST(), FIXTURE(), etc. recorded by ld. + * @see libc/testlib/testlib.h + * @see ape/ape.lds + */ +testonly void testlib_runalltests(void) { + if ((intptr_t)__testcase_end > (intptr_t)__testcase_start) { + if (testlib_countfixtures(__combo_start, __combo_end)) { + testlib_runcombos(__testcase_start, __testcase_end, __combo_start, + __combo_end); + } else { + testlib_runtestcases(__testcase_start, __testcase_end, NULL); + testlib_runfixtures(__testcase_start, __testcase_end, __fixture_start, + __fixture_end); + testlib_finish(); + } + } +} diff --git a/libc/testlib/shoulddebugbreak.c b/libc/testlib/shoulddebugbreak.c new file mode 100644 index 00000000..202c471a --- /dev/null +++ b/libc/testlib/shoulddebugbreak.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/testlib.h" + +bool g_testlib_shoulddebugbreak; diff --git a/libc/testlib/showerror.c b/libc/testlib/showerror.c new file mode 100644 index 00000000..811b4ed0 --- /dev/null +++ b/libc/testlib/showerror.c @@ -0,0 +1,49 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/errno.h" +#include "libc/fmt/fmt.h" +#include "libc/log/internal.h" +#include "libc/log/log.h" +#include "libc/math.h" +#include "libc/nt/runtime.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/testlib/testlib.h" + +testonly void testlib_showerror(const char *file, int line, const char *func, + const char *method, const char *symbol, + const char *code, char *v1, char *v2) { + /* TODO(jart): Pay off tech debt re duplication */ + getpid$sysv(); /* make strace easier to read */ + getpid$sysv(); + fprintf(stderr, + "%s%s%s%s:%s:%d%s: %s() %s %s(%s)\n" + "\t%s\n" + "\t\t%s %s %s\n" + "\t\t%s %s\n" + "\t%s%s\n" + "\t%s%s\n", + RED2, "error", UNBOLD, BLUE1, file, line, RESET, method, "in", func, + g_fixturename, code, "want", v1, symbol, " got", v2, SUBTLE, + strerror(errno), program_invocation_name, RESET); + free_s(&v1); + free_s(&v2); +} diff --git a/libc/testlib/showerror_.c b/libc/testlib/showerror_.c new file mode 100644 index 00000000..82b21810 --- /dev/null +++ b/libc/testlib/showerror_.c @@ -0,0 +1,90 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/calls/internal.h" +#include "libc/errno.h" +#include "libc/fmt/fmt.h" +#include "libc/log/internal.h" +#include "libc/log/log.h" +#include "libc/math.h" +#include "libc/nt/runtime.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/testlib/testlib.h" + +STATIC_YOINK("isfdkind"); + +const char *testlib_showerror_errno; +const char *testlib_showerror_file; +const char *testlib_showerror_func; +const char *testlib_showerror_isfatal; +const char *testlib_showerror_macro; +const char *testlib_showerror_symbol; + +testonly void testlib_showerror_(int line, const char *wantcode, + const char *gotcode, char *FREED_want, + char *FREED_got, const char *fmt, ...) { + va_list va; + + getpid$sysv(); /* make strace easier to read */ + getpid$sysv(); + + fflush(stdout); + fflush(stderr); + + /* TODO(jart): Pay off tech debt re duplication */ + + fprintf(stderr, "%s%s%s%s:%s:%d%s: %s(%s)\n\t%s(%s", RED2, "error", UNBOLD, + BLUE1, testlib_showerror_file, line, RESET, testlib_showerror_func, + g_fixturename, testlib_showerror_macro, wantcode); + + if (wantcode) { + fprintf(stderr, + ", %s)\n" + "\t\t%s %s %s\n" + "\t\t%s %s\n", + gotcode, "want", FREED_want, testlib_showerror_symbol, " got", + FREED_got); + } else { + fprintf(stderr, + ", %s)\n" + "\t\t→ %s%s\n", + gotcode, testlib_showerror_symbol, FREED_want); + } + + if (!isempty(fmt)) { + fputc('\t', stderr); + va_start(va, fmt); + vfprintf(stderr, fmt, va); + va_end(va); + fputc('\n', stderr); + } + + fprintf(stderr, + "\t%s%s\n" + "\t%s%s\n", + SUBTLE, strerror(errno), program_invocation_name, RESET); + + free_s(&FREED_want); + free_s(&FREED_got); + + ++g_testlib_failed; + if (testlib_showerror_isfatal) testlib_abort(); +} diff --git a/libc/testlib/startswith.c b/libc/testlib/startswith.c new file mode 100644 index 00000000..f2191d57 --- /dev/null +++ b/libc/testlib/startswith.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +testonly bool testlib_startswith(size_t cw, const void *s, const void *prefix) { + if (s == prefix) return true; + if (!s || !prefix) return false; + return cw == sizeof(wchar_t) + ? wcsstartswith(s, prefix) + : cw == sizeof(char16_t) ? startswith16(s, prefix) + : startswith(s, prefix); +} diff --git a/libc/testlib/strcaseequals.c b/libc/testlib/strcaseequals.c new file mode 100644 index 00000000..0bc1b8cd --- /dev/null +++ b/libc/testlib/strcaseequals.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/limits.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +testonly bool testlib_strcaseequals(size_t cw, const void *s1, const void *s2) { + return testlib_strncaseequals(cw, s1, s2, SIZE_MAX); +} + +testonly bool testlib_strncaseequals(size_t cw, const void *s1, const void *s2, + size_t n) { + if (s1 == s2) return true; + if (!s1 || !s2) return false; + return (cw == sizeof(wchar_t) + ? wcsncasecmp(s1, s2, n) + : cw == sizeof(char16_t) ? strncasecmp16(s1, s2, n) + : strncasecmp(s1, s2, n)) == 0; +} diff --git a/libc/testlib/strequals.c b/libc/testlib/strequals.c new file mode 100644 index 00000000..ab38375b --- /dev/null +++ b/libc/testlib/strequals.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/limits.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +testonly bool testlib_strequals(size_t cw, const void *s1, const void *s2) { + return testlib_strnequals(cw, s1, s2, SIZE_MAX); +} + +testonly bool testlib_strnequals(size_t cw, const void *s1, const void *s2, + size_t n) { + if (s1 == s2) return true; + if (!s1 || !s2) return false; + return (cw == sizeof(wchar_t) + ? wcsncmp(s1, s2, n) + : cw == sizeof(char16_t) ? strncmp16(s1, s2, n) + : strncmp(s1, s2, n)) == 0; +} diff --git a/libc/testlib/testcase.S b/libc/testlib/testcase.S new file mode 100644 index 00000000..8cdd1757 --- /dev/null +++ b/libc/testlib/testcase.S @@ -0,0 +1,41 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Decentralized section for test testcase registration. +/ +/ @see ape/ape.lds + .section .piro.relo.sort.testcase.1,"aw",@nobits + .type __testcase_start,@object + .type __testcase_end,@object + .globl __testcase_start,__testcase_end + .hidden __testcase_start,__testcase_end + .byte 0 + .align __SIZEOF_POINTER__ +__testcase_start: + .previous/* + ... + decentralized content + ... + */.section .piro.relo.sort.testcase.3,"aw",@nobits +__testcase_end: + .quad 0 + .previous diff --git a/libc/testlib/testlib.h b/libc/testlib/testlib.h new file mode 100644 index 00000000..7c81ccae --- /dev/null +++ b/libc/testlib/testlib.h @@ -0,0 +1,631 @@ +#ifndef COSMOPOLITAN_LIBC_TESTLIB_H_ +#define COSMOPOLITAN_LIBC_TESTLIB_H_ +#include "libc/bits/bits.h" +#include "libc/runtime/gc.h" +#include "libc/testlib/ugly.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § testing library ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +/** + * Declares test case function. + * + * Test cases are guaranteed by the linker to be run in order, sorted by + * the (SUITE, NAME) tuple passed here. + */ +#define TEST(SUITE, NAME) __TEST_PROTOTYPE(SUITE, NAME, __TEST_ARRAY) + +/** + * Declares function that globally modifies program state. + * + * All tests will be run an additional time, for each fixture. Fixtures + * are useful, for example, when multiple implementations of a function + * exist. Memory protections, on sections such as .initbss, are removed + * temorarilly by the runtime while calling fixture functions. Fixtures + * are also guaranteed by the linker to be run in sorted order. + */ +#define FIXTURE(SUITE, NAME) __FIXTURE("fixture", SUITE, NAME) + +/** + * Registers explosive fixture with linker. + * + * All tests will run an additional time for each set of entries in the + * Cartesian product of groups. That makes this similar to fixture, but + * more appropriate for testing pure code (i.e. no syscalls) like math. + */ +#define COMBO(GROUP, ENTRY) __FIXTURE("combo", GROUP, ENTRY) + +/** + * Declares benchmark function. + * + * These only run if (1) the -b flag is passed to the FOO_test.com; and + * (2) the unit tests passed. It's just an ordinary function, that gets + * registered with the linker. It should print things to stdout. + * + * @see EZBENCH() + */ +#define BENCH(SUITE, NAME) \ + STATIC_YOINK("__bench_start"); \ + __TEST_PROTOTYPE(SUITE, NAME, __BENCH_ARRAY) + +#define ASSERT_GE(C, X) _TEST2("ASSERT_GE", C, >=, (X), #C, " ≥ ", #X, 1) +#define ASSERT_GT(C, X) _TEST2("ASSERT_GT", C, >, (X), #C, " > ", #X, 1) +#define ASSERT_LE(C, X) _TEST2("ASSERT_LE", C, <=, (X), #C, " ≤ ", #X, 1) +#define ASSERT_LT(C, X) _TEST2("ASSERT_LT", C, <, (X), #C, " < ", #X, 1) +#define EXPECT_GE(C, X) _TEST2("EXPECT_GE", C, >=, (X), #C, " ≥ ", #X, 0) +#define EXPECT_GT(C, X) _TEST2("EXPECT_GT", C, >, (X), #C, " > ", #X, 0) +#define EXPECT_LE(C, X) _TEST2("EXPECT_LE", C, <=, (X), #C, " ≤ ", #X, 0) +#define EXPECT_LT(C, X) _TEST2("EXPECT_LT", C, <, (X), #C, " < ", #X, 0) + +#define _TEST2(NAME, WANT, OP, GOT, WANTCODE, OPSTR, GOTCODE, ISFATAL) \ + do { \ + autotype(WANT) Want = (WANT); \ + autotype(GOT) Got = (GOT); \ + if (!(Want OP Got)) { \ + testlib_showerror(FILIFU NAME, OPSTR, WANTCODE OPSTR GOTCODE, \ + testlib_formatint(Want), testlib_formatint(Got)); \ + testlib_onfail2(ISFATAL); \ + } \ + } while (0) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § testing library » assert or die ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define EXPECT_TRUE(X) _TEST2("EXPECT_TRUE", true, ==, (X), #X, "", "", 0) +#define EXPECT_FALSE(X) _TEST2("EXPECT_FALSE", false, ==, (X), #X, "", "", 0) +#define ASSERT_TRUE(X) _TEST2("ASSERT_TRUE", true, ==, (X), #X, "", "", 1) +#define ASSERT_FALSE(X) _TEST2("ASSERT_FALSE", false, ==, (X), #X, "", "", 1) + +#define ASSERT_EQ(WANT, GOT, ...) \ + __TEST_EQ(assert, __FILE__, __LINE__, __FUNCTION__, #WANT, #GOT, WANT, GOT, \ + __VA_ARGS__) +#define EXPECT_EQ(WANT, GOT, ...) \ + __TEST_EQ(expect, __FILE__, __LINE__, __FUNCTION__, #WANT, #GOT, WANT, GOT, \ + __VA_ARGS__) +#define __TEST_EQ(KIND, FILE, LINE, FUNC, WANTCODE, GOTCODE, WANT, GOT, ...) \ + ({ \ + autotype(GOT) Got = _I(GOT); \ + typeof(Got) Want = _I(WANT); \ + testlib_ontest(); \ + if (Want != Got) { \ + TESTLIB_ONFAIL(FILE, FUNC); \ + TESTLIB_SHOWERROR(testlib_showerror_##KIND##_eq, LINE, WANTCODE, \ + GOTCODE, testlib_formatint(_I(Want)), \ + testlib_formatint(_I(Got)), "" __VA_ARGS__); \ + } \ + (void)0; \ + }) + +#define ASSERT_NE(WANT, GOT, ...) \ + __TEST_NE(assert, __FILE__, __LINE__, __FUNCTION__, #WANT, #GOT, WANT, GOT, \ + __VA_ARGS__) +#define EXPECT_NE(WANT, GOT, ...) \ + __TEST_NE(expect, __FILE__, __LINE__, __FUNCTION__, #WANT, #GOT, WANT, GOT, \ + __VA_ARGS__) +#define __TEST_NE(KIND, FILE, LINE, FUNC, WANTCODE, GOTCODE, WANT, GOT, ...) \ + ({ \ + autotype(GOT) Got = (GOT); \ + typeof(Got) Want = (WANT); \ + testlib_ontest(); \ + if (Want == Got) { \ + TESTLIB_ONFAIL(FILE, FUNC); \ + TESTLIB_SHOWERROR(testlib_showerror_##KIND##_ne, LINE, WANTCODE, \ + GOTCODE, testlib_formatint(_I(Want)), \ + testlib_formatint(_I(Got)), "" __VA_ARGS__); \ + } \ + (void)0; \ + }) + +#define ASSERT_BETWEEN(BEG, END, GOT) \ + assertBetween(FILIFU _I(BEG), _I(END), _I(GOT), \ + #BEG " <= " #GOT " <= " #END, true) +#define ASSERT_STREQ(WANT, GOT) \ + assertStringEquals(FILIFU sizeof(*(WANT)), WANT, GOT, #GOT, true) +#define ASSERT_STRNE(NOPE, GOT) \ + assertStringNotEquals(FILIFU sizeof(*(NOPE)), NOPE, GOT, #GOT, true) +#define ASSERT_STREQN(WANT, GOT, N) \ + assertStrnEquals(FILIFU sizeof(*(WANT)), WANT, GOT, N, #GOT, true) +#define ASSERT_STRNEN(NOPE, GOT, N) \ + assertStrnNotEquals(FILIFU sizeof(*(NOPE)), NOPE, GOT, N, #GOT, true) +#define ASSERT_STRCASEEQ(WANT, GOT) \ + assertStringCaseEquals(FILIFU sizeof(*(WANT)), WANT, GOT, #GOT, true) +#define ASSERT_STRCASENE(NOPE, GOT) \ + assertStringCaseNotEquals(FILIFU sizeof(*(NOPE)), NOPE, GOT, #GOT, true) +#define ASSERT_STRNCASEEQ(WANT, GOT, N) \ + assertStrnCaseEquals(FILIFU sizeof(*(WANT)), WANT, GOT, N, #GOT, true) +#define ASSERT_STRNCASENE(NOPE, GOT, N) \ + assertStrnCaseNotEquals(FILIFU sizeof(*(NOPE)), NOPE, GOT, N, #GOT, true) +#define ASSERT_STARTSWITH(PREFIX, GOT) \ + assertStartsWith(FILIFU sizeof(*(PREFIX)), PREFIX, GOT, #GOT, true) +#define ASSERT_ENDSWITH(SUFFIX, GOT) \ + assertEndsWith(FILIFU sizeof(*(SUFFIX)), SUFFIX, GOT, #GOT, true) +#define ASSERT_IN(NEEDLE, GOT) \ + assertContains(FILIFU sizeof(*(NEEDLE)), NEEDLE, GOT, #GOT, true) + +#define ASSERT_BINEQ(WANT, GOT) \ + _Generic((WANT)[0], char \ + : assertBinaryEquals$hex, default \ + : assertBinaryEquals$cp437)(FILIFU WANT, GOT, -1, #GOT, true) +#define ASSERT_BINNE(NOPE, GOT) \ + _Generic((NOPE)[0], char \ + : assertBinaryNotEquals$hex, default \ + : assertBinaryNotEquals$cp437)(FILIFU NOPE, GOT, -1, #GOT, true) +#define ASSERT_BINEQN(WANT, GOT, N) \ + _Generic((WANT)[0], char \ + : assertBinaryEquals$hex, default \ + : assertBinaryEquals$cp437)(FILIFU WANT, GOT, N, #GOT, true) +#define ASSERT_BINNEN(NOPE, GOT, N) \ + _Generic((NOPE)[0], char \ + : assertBinaryNotEquals$hex, default \ + : assertBinaryNotEquals$cp437)(FILIFU NOPE, GOT, -1, #GOT, true) + +#define ASSERT_FLOAT_EQ(WANT, GOT) \ + assertLongDoubleEquals(FILIFU WANT, GOT, #GOT, true) +#define ASSERT_DOUBLE_EQ(WANT, GOT) \ + assertLongDoubleEquals(FILIFU WANT, GOT, #GOT, true) +#define ASSERT_LDBL_EQ(WANT, GOT) \ + assertLongDoubleEquals(FILIFU WANT, GOT, #GOT, true) +#define ASSERT_LDBL_GT(VAL, GOT) \ + assertLongDoubleGreaterThan(VAL, GOT, #VAL " > " #GOT, true) +#define ASSERT_LDBL_LT(VAL, GOT) \ + assertLongDoubleLessThan(VAL, GOT, #VAL " < " #GOT, true) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § testing library » assert or log ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define EXPECT_BETWEEN(BEG, END, GOT) \ + assertBetween(FILIFU _I(BEG), _I(END), _I(GOT), \ + #BEG " <= " #GOT " <= " #END, false) +#define EXPECT_STREQ(WANT, GOT) \ + assertStringEquals(FILIFU sizeof(*(WANT)), WANT, GOT, #GOT, false) +#define EXPECT_STRNE(NOPE, GOT) \ + assertStringNotEquals(FILIFU sizeof(*(NOPE)), NOPE, GOT, #GOT, false) +#define EXPECT_STREQN(WANT, GOT, N) \ + assertStrnEquals(FILIFU sizeof(*(WANT)), WANT, GOT, N, #GOT, false) +#define EXPECT_STRNEN(NOPE, GOT, N) \ + assertStrnNotEquals(FILIFU sizeof(*(NOPE)), NOPE, GOT, N, #GOT, false) +#define EXPECT_STRCASEEQ(WANT, GOT) \ + assertStringCaseEquals(FILIFU sizeof(*(WANT)), WANT, GOT, #GOT, false) +#define EXPECT_STRCASENE(NOPE, GOT) \ + assertStringCaseNotEquals(FILIFU sizeof(*(NOPE)), NOPE, GOT, #GOT, false) +#define EXPECT_STRNCASEEQ(WANT, GOT, N) \ + assertStrnCaseEquals(FILIFU sizeof(*(WANT)), WANT, GOT, N, #GOT, false) +#define EXPECT_STRNCASENE(NOPE, GOT, N) \ + assertStrnCaseNotEquals(FILIFU sizeof(*(NOPE)), NOPE, GOT, N, #GOT, false) +#define EXPECT_STARTSWITH(PREFIX, GOT) \ + assertStartsWith(FILIFU sizeof(*(PREFIX)), PREFIX, GOT, #GOT, false) +#define EXPECT_ENDSWITH(SUFFIX, GOT) \ + assertEndsWith(FILIFU sizeof(*(SUFFIX)), SUFFIX, GOT, #GOT, false) +#define EXPECT_IN(NEEDLE, GOT) \ + assertContains(FILIFU sizeof(*(NEEDLE)), NEEDLE, GOT, #GOT, false) + +#define EXPECT_BINEQ(WANT, GOT) \ + _Generic((WANT)[0], char \ + : assertBinaryEquals$hex, default \ + : assertBinaryEquals$cp437)(FILIFU WANT, GOT, -1, #GOT, false) +#define EXPECT_BINNE(NOPE, GOT) \ + _Generic((NOPE)[0], char \ + : assertBinaryNotEquals$hex, default \ + : assertBinaryNotEquals$cp437)(FILIFU NOPE, GOT, -1, #GOT, false) +#define EXPECT_BINEQN(WANT, GOT, N) \ + _Generic((WANT)[0], char \ + : assertBinaryEquals$hex, default \ + : assertBinaryEquals$cp437)(FILIFU WANT, GOT, N, #GOT, false) +#define EXPECT_BINNEN(NOPE, GOT, N) \ + _Generic((NOPE)[0], char \ + : assertBinaryNotEquals$hex, default \ + : assertBinaryNotEquals$cp437)(FILIFU NOPE, GOT, -1, #GOT, false) + +#define EXPECT_FLOAT_EQ(WANT, GOT) \ + assertLongDoubleEquals(FILIFU WANT, GOT, #GOT, false) +#define EXPECT_DOUBLE_EQ(WANT, GOT) \ + assertLongDoubleEquals(FILIFU WANT, GOT, #GOT, false) +#define EXPECT_LDBL_EQ(WANT, GOT) \ + assertLongDoubleEquals(FILIFU WANT, GOT, #GOT, false) +#define EXPECT_LGBL_GT(VAL, GOT) \ + expectLongDoubleGreaterThan(VAL, GOT, #VAL " > " #GOT, false) +#define EXPECT_LGBL_LT(VAL, GOT) \ + expectLongDoubleLessThan(VAL, GOT, #VAL " < " #GOT, false) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § testing library » hardware-accelerated memory safety ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +typedef void (*testfn_t)(void); + +struct TestFixture { + const char *group; + const char *name; + testfn_t fn; +}; + +struct TestAllocation { + void *mapaddr; + size_t mapsize; + void *useraddr; + size_t usersize; +}; + +struct TestMemoryStack { + size_t i; + size_t n; + struct TestAllocation *p; +}; + +extern struct TestMemoryStack g_testmem; + +void tfree(void *) paramsnonnull(); +void *tmalloc(size_t) returnsnonnull returnspointerwithnoaliases nodiscard + attributeallocsize((1)) returnsaligned((1)); +void *tmemalign(size_t, + size_t) returnsnonnull returnspointerwithnoaliases nodiscard + attributeallocsize((2)) libcesque attributeallocalign((1)); +char *tstrdup(const char *) returnsnonnull returnspointerwithnoaliases nodiscard + returnsaligned((1)); +void *tunbing(const char16_t *) + paramsnonnull() returnsnonnull returnspointerwithnoaliases nodiscard + returnsaligned((1)); +void *tunbinga(size_t, const char16_t *) + paramsnonnull() returnsnonnull returnspointerwithnoaliases nodiscard + attributeallocalign((1)); + +#define tgc(TMEM) \ + ({ \ + void *Res; \ + /* volatile b/c testmem only lifo atm */ \ + asm volatile("" ::: "memory"); \ + Res = defer((tfree), (TMEM)); \ + asm volatile("" ::: "memory"); \ + Res; \ + }) + +#define tfree(P) \ + do { \ + __tfree_check(P); \ + (tfree)(P); \ + } while (0) + +#define __tfree_check(P) \ + ASSERT_BETWEEN(g_testmem.p[g_testmem.i - 1].useraddr, \ + ((char *)g_testmem.p[g_testmem.i - 1].useraddr + \ + g_testmem.p[g_testmem.i - 1].usersize), \ + P) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § testing library » implementation details ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define FILIFU __FILE__, __LINE__, __FUNCTION__, +#define FILIFU_OBJ(...) __FILE__, __LINE__, ##__VA_ARGS__ +#define FILIFU_ARGS const char *file, int line, const char *func, +#define FILIFU_FROM(OBJ) (OBJ)->file, (OBJ)->line, __FUNCTION__, +#define FILIFU_FIELDS \ + const char *file; \ + int line + +extern char g_fixturename[256]; +extern bool g_testlib_shoulddebugbreak; /* set by testmain */ +extern unsigned g_testlib_ran; /* set by wrappers */ +extern unsigned g_testlib_failed; /* set by wrappers */ +extern const char *testlib_showerror_errno; /* set by macros */ +extern const char *testlib_showerror_file; /* set by macros */ +extern const char *testlib_showerror_func; /* set by macros */ +extern const testfn_t __bench_start[], __bench_end[]; +extern const testfn_t __testcase_start[], __testcase_end[]; +extern const struct TestFixture __fixture_start[], __fixture_end[]; +extern const struct TestFixture __combo_start[], __combo_end[]; + +#define TESTLIB_ONFAIL(FILE, FUNC) \ + if (g_testlib_shoulddebugbreak) DebugBreak(); \ + testlib_showerror_file = FILE; \ + testlib_showerror_func = FUNC + +#define TESTLIB_SHOWERROR(THUNK, ...) \ + (((typeof(&testlib_showerror_))strongaddr(#THUNK)))(__VA_ARGS__) + +void testlib_showerror_(int line, const char *wantcode, const char *gotcode, + char *FREED_want, char *FREED_got, const char *fmt, + ...) relegated; + +void testlib_showerror(const char *file, int line, const char *func, + const char *method, const char *symbol, const char *code, + char *v1, char *v2); + +void thrashcodecache(void); + +void testlib_finish(void); +void testlib_runalltests(void); +void testlib_runallbenchmarks(void); +void testlib_runtestcases(testfn_t *, testfn_t *, testfn_t); +void testlib_runcombos(testfn_t *, testfn_t *, const struct TestFixture *, + const struct TestFixture *); +void testlib_runfixtures(testfn_t *, testfn_t *, const struct TestFixture *, + const struct TestFixture *); +int testlib_countfixtures(const struct TestFixture *, + const struct TestFixture *); +void testlib_abort(void) noreturn relegated; +bool testlib_strequals(size_t, const void *, const void *) nosideeffect; +bool testlib_strnequals(size_t, const void *, const void *, + size_t) nosideeffect; +bool testlib_strcaseequals(size_t, const void *, const void *) nosideeffect; +bool testlib_strncaseequals(size_t, const void *, const void *, + size_t) nosideeffect; +void testlib_free(void *); +bool testlib_binequals(const char16_t *, const void *, size_t) nosideeffect; +bool testlib_hexequals(const char *, const void *, size_t) nosideeffect; +bool testlib_startswith(size_t, const void *, const void *) nosideeffect; +bool testlib_endswith(size_t, const void *, const void *) nosideeffect; +bool testlib_contains(size_t, const void *, const void *) nosideeffect; +char *testlib_formatrange(intmax_t, intmax_t) mallocesque; +char *testlib_formatstr(size_t, const void *, int) mallocesque; +char *testlib_formatint(intmax_t) mallocesque; +char *testlib_formatbool(bool); +char *testlib_formatfloat(long double) mallocesque; +void testlib_formatbinaryashex(const char *, const void *, size_t, char **, + char **); +void testlib_formatbinaryasglyphs(const char16_t *, const void *, size_t, + char **, char **); +bool testlib_almostequallongdouble(long double, long double); +void testlib_incrementfailed(void); + +forceinline void testlib_ontest() { + YOINK(__testcase_start); + YOINK(__fixture_start); + YOINK(__combo_start); + ++g_testlib_ran; +} + +forceinline void testlib_onfail2(bool isfatal) { + testlib_incrementfailed(); + if (isfatal) testlib_abort(); +} + +forceinline void assertNotEquals(FILIFU_ARGS intmax_t donotwant, intmax_t got, + const char *gotcode, bool isfatal) { + ++g_testlib_ran; + if (got != donotwant) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_showerror(file, line, func, "assertNotEquals", "=", gotcode, + testlib_formatint(got), testlib_formatint(donotwant)); + testlib_onfail2(isfatal); +} + +#define assertLongDoubleGreaterThan(a, b, code, isfatal) \ + ({ \ + autotype(a) a_ = (a); \ + autotype(b) b_ = (b); \ + if (a_ <= b_) { \ + testlib_showerror(FILIFU "assertLongDoubleGreaterThan", ">", code, \ + testlib_formatfloat(a_), testlib_formatfloat(b_)); \ + testlib_onfail2(isfatal); \ + } \ + (void)0; \ + }) + +#define assertLongDoubleLessThan(a, b, code, isfatal) \ + ({ \ + autotype(a) a_ = (a); \ + autotype(b) b_ = (b); \ + if (a_ >= b_) { \ + testlib_showerror(FILIFU "assertLongDoubleLessThan", "<", code, \ + testlib_formatfloat(a_), testlib_formatfloat(b_)); \ + testlib_onfail2(isfatal); \ + } \ + (void)0; \ + }) + +forceinline void assertBetween(FILIFU_ARGS intmax_t beg, intmax_t end, + intmax_t got, const char *gotcode, + bool isfatal) { + ++g_testlib_ran; + if (beg <= got && got <= end) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_showerror(file, line, func, "assertBetween", "∉", gotcode, + testlib_formatint(got), testlib_formatrange(beg, end)); + testlib_onfail2(isfatal); +} + +forceinline void assertStringEquals(FILIFU_ARGS size_t cw, const void *want, + const void *got, const char *gotcode, + bool isfatal) { + ++g_testlib_ran; + if (testlib_strequals(cw, want, got)) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_showerror(file, line, func, "assertStringEquals", "≠", gotcode, + testlib_formatstr(cw, want, -1), + testlib_formatstr(cw, got, -1)); + testlib_onfail2(isfatal); +} + +forceinline void assertStringNotEquals(FILIFU_ARGS size_t cw, const void *want, + const void *got, const char *gotcode, + bool isfatal) { + ++g_testlib_ran; + if (!testlib_strequals(cw, want, got)) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_showerror(file, line, func, "assertStringNotEquals", "=", gotcode, + testlib_formatstr(cw, want, -1), + testlib_formatstr(cw, got, -1)); + testlib_onfail2(isfatal); +} + +forceinline void assertStrnEquals(FILIFU_ARGS size_t cw, const void *want, + const void *got, size_t n, + const char *gotcode, bool isfatal) { + ++g_testlib_ran; + if (testlib_strnequals(cw, want, got, n)) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_showerror(file, line, func, "assertStrnEquals", "≠", gotcode, + testlib_formatstr(cw, got, n), + testlib_formatstr(cw, want, n)); + testlib_onfail2(isfatal); +} + +forceinline void assertStrnNotEquals(FILIFU_ARGS size_t cw, const void *want, + const void *got, size_t n, + const char *gotcode, bool isfatal) { + ++g_testlib_ran; + if (!testlib_strnequals(cw, want, got, n)) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_showerror(file, line, func, "assertStrnNotEquals", "=", gotcode, + testlib_formatstr(cw, got, n), + testlib_formatstr(cw, want, n)); + testlib_onfail2(isfatal); +} + +forceinline void assertStringCaseEquals(FILIFU_ARGS size_t cw, const void *want, + const void *got, const char *gotcode, + bool isfatal) { + ++g_testlib_ran; + if (testlib_strcaseequals(cw, want, got)) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_showerror(file, line, func, "assertStringCaseEquals", "≠", gotcode, + testlib_formatstr(cw, got, -1), + testlib_formatstr(cw, want, -1)); + testlib_onfail2(isfatal); +} + +forceinline void assertStringCaseNotEquals(FILIFU_ARGS size_t cw, + const void *want, const void *got, + const char *gotcode, bool isfatal) { + ++g_testlib_ran; + if (!testlib_strcaseequals(cw, want, got)) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_showerror(file, line, func, "assertStringCaseNotEquals", "=", gotcode, + testlib_formatstr(cw, got, -1), + testlib_formatstr(cw, want, -1)); + testlib_onfail2(isfatal); +} + +forceinline void assertStrnCaseEquals(FILIFU_ARGS size_t cw, const void *want, + const void *got, size_t n, + const char *gotcode, bool isfatal) { + ++g_testlib_ran; + if (testlib_strncaseequals(cw, want, got, n)) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_showerror(file, line, func, "assertStrnCaseEquals", "≠", gotcode, + testlib_formatstr(cw, got, n), + testlib_formatstr(cw, want, n)); + testlib_onfail2(isfatal); +} + +forceinline void assertStrnCaseNotEquals(FILIFU_ARGS size_t cw, + const void *want, const void *got, + size_t n, const char *gotcode, + bool isfatal) { + ++g_testlib_ran; + if (!testlib_strncaseequals(cw, want, got, n)) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_showerror(file, line, func, "assertStrnCaseNotEquals", "=", gotcode, + testlib_formatstr(cw, got, n), + testlib_formatstr(cw, want, n)); + testlib_onfail2(isfatal); +} + +forceinline void assertStartsWith(FILIFU_ARGS size_t cw, const char *prefix, + const char *s, const char *gotcode, + bool isfatal) { + ++g_testlib_ran; + if (testlib_startswith(cw, s, prefix)) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_showerror(file, line, func, "assertStartsWith", "≠", gotcode, + testlib_formatstr(1, s, -1), + testlib_formatstr(1, prefix, -1)); + testlib_onfail2(isfatal); +} + +forceinline void assertEndsWith(FILIFU_ARGS size_t cw, const char *suffix, + const char *s, const char *gotcode, + bool isfatal) { + ++g_testlib_ran; + if (testlib_endswith(cw, s, suffix)) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_showerror(file, line, func, "assertEndsWith", "≠", gotcode, + testlib_formatstr(1, s, -1), + testlib_formatstr(1, suffix, -1)); + testlib_onfail2(isfatal); +} + +forceinline void assertContains(FILIFU_ARGS size_t cw, const char *needle, + const char *s, const char *gotcode, + bool isfatal) { + ++g_testlib_ran; + if (testlib_contains(cw, s, needle)) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_showerror(file, line, func, "assertContains", "∉", gotcode, + testlib_formatstr(1, s, -1), + testlib_formatstr(1, needle, -1)); + testlib_onfail2(isfatal); +} + +forceinline void assertBinaryEquals$cp437(FILIFU_ARGS const char16_t *want, + const void *got, size_t n, + const char *gotcode, bool isfatal) { + ++g_testlib_ran; + char *v1, *v2; + if (testlib_binequals(want, got, n)) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_formatbinaryasglyphs(want, got, n, &v1, &v2); + testlib_showerror(file, line, func, "assertBinaryEquals", "≠", gotcode, v1, + v2); + testlib_onfail2(isfatal); +} + +forceinline void assertBinaryEquals$hex(FILIFU_ARGS const char *want, + const void *got, size_t n, + const char *gotcode, bool isfatal) { + ++g_testlib_ran; + char *v1, *v2; + if (testlib_hexequals(want, got, n)) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_formatbinaryashex(want, got, n, &v1, &v2); + testlib_showerror(file, line, func, "assertBinaryEquals", "≠", gotcode, v1, + v2); + testlib_onfail2(isfatal); +} + +forceinline void assertBinaryNotEquals$cp437(FILIFU_ARGS const char16_t *want, + const void *got, size_t n, + const char *gotcode, + bool isfatal) { + ++g_testlib_ran; + char *v1, *v2; + if (!testlib_binequals(want, got, n)) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_formatbinaryasglyphs(want, got, n, &v1, &v2); + testlib_showerror(file, line, func, "assertBinaryNotEquals", "=", gotcode, v1, + v2); + testlib_onfail2(isfatal); +} + +forceinline void assertBinaryNotEquals$hex(FILIFU_ARGS const char *want, + const void *got, size_t n, + const char *gotcode, bool isfatal) { + ++g_testlib_ran; + char *v1, *v2; + if (!testlib_hexequals(want, got, n)) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_formatbinaryashex(want, got, n, &v1, &v2); + testlib_showerror(file, line, func, "assertBinaryNotEquals", "=", gotcode, v1, + v2); + testlib_onfail2(isfatal); +} + +forceinline void assertLongDoubleEquals(FILIFU_ARGS long double want, + long double got, const char *gotcode, + bool isfatal) { + ++g_testlib_ran; + if (testlib_almostequallongdouble(want, got)) return; + if (g_testlib_shoulddebugbreak) DebugBreak(); + testlib_showerror(file, line, func, "assertLongDoubleEquals", "≠", gotcode, + testlib_formatfloat(want), testlib_formatfloat(got)); + testlib_onfail2(isfatal); +} + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_TESTLIB_H_ */ diff --git a/libc/testlib/testlib.mk b/libc/testlib/testlib.mk new file mode 100644 index 00000000..6c038c4b --- /dev/null +++ b/libc/testlib/testlib.mk @@ -0,0 +1,197 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ +# Description: +# Cosmopolitan Testing Library. + +PKGS += LIBC_TESTLIB + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_TESTLIB_ARTIFACTS += LIBC_TESTLIB_A +LIBC_TESTLIB = $(LIBC_TESTLIB_A_DEPS) $(LIBC_TESTLIB_A) +LIBC_TESTLIB_A = o/$(MODE)/libc/testlib/testlib.a +LIBC_TESTLIB_A_CHECKS = $(LIBC_TESTLIB_A).pkg + +LIBC_TESTLIB_A_ASSETS = \ + libc/testlib/hyperion.txt + +LIBC_TESTLIB_A_HDRS = \ + libc/testlib/bench.h \ + libc/testlib/ezbench.h \ + libc/testlib/hyperion.h \ + libc/testlib/testlib.h + +LIBC_TESTLIB_A_SRCS_S = \ + libc/testlib/bench.S \ + libc/testlib/combo.S \ + libc/testlib/fixture.S \ + libc/testlib/hyperion.S \ + libc/testlib/testcase.S \ + libc/testlib/thrashcodecache.S \ + libc/testlib/thunks/assert_eq.S \ + libc/testlib/thunks/assert_false.S \ + libc/testlib/thunks/assert_ne.S \ + libc/testlib/thunks/assert_true.S \ + libc/testlib/thunks/expect_eq.S \ + libc/testlib/thunks/expect_false.S \ + libc/testlib/thunks/expect_ne.S \ + libc/testlib/thunks/expect_true.S \ + libc/testlib/thunks/free.S \ + libc/testlib/thunks/jump.S + +LIBC_TESTLIB_A_SRCS_C = \ + libc/testlib/almostequallongdouble.c \ + libc/testlib/hexequals.c \ + libc/testlib/binequals.c \ + libc/testlib/formatbool.c \ + libc/testlib/formatrange.c \ + libc/testlib/globals.c \ + libc/testlib/incrementfailed.c \ + libc/testlib/formatfloat.c \ + libc/testlib/formatbinaryasglyphs.c \ + libc/testlib/formatbinaryashex.c \ + libc/testlib/formatint.c \ + libc/testlib/formatstr.c \ + libc/testlib/shoulddebugbreak.c \ + libc/testlib/showerror.c \ + libc/testlib/showerror_.c \ + libc/testlib/testmem.c \ + libc/testlib/strequals.c \ + libc/testlib/startswith.c \ + libc/testlib/endswith.c \ + libc/testlib/contains.c \ + libc/testlib/strcaseequals.c \ + libc/testlib/benchrunner.c \ + libc/testlib/testrunner.c \ + libc/testlib/comborunner.c \ + libc/testlib/fixturerunner.c \ + libc/testlib/ezbenchreport.c \ + libc/testlib/ezbenchcontrol.c + +LIBC_TESTLIB_A_SRCS = \ + $(LIBC_TESTLIB_A_SRCS_S) \ + $(LIBC_TESTLIB_A_SRCS_C) + +LIBC_TESTLIB_A_OBJS = \ + $(LIBC_TESTLIB_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_TESTLIB_A_SRCS_C:%.c=o/$(MODE)/%.o) \ + $(LIBC_TESTLIB_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_TESTLIB_A_ASSETS:%=o/$(MODE)/%.zip.o) + +LIBC_TESTLIB_A_DIRECTDEPS = \ + APE_LIB \ + LIBC_ALG \ + LIBC_CALLS \ + LIBC_FMT \ + LIBC_LOG \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_NT_KERNEL32 \ + LIBC_RAND \ + LIBC_RUNTIME \ + LIBC_STDIO \ + LIBC_STR \ + LIBC_TIME \ + LIBC_TINYMATH \ + LIBC_STUBS \ + LIBC_SYSV_CALLS \ + LIBC_UNICODE \ + LIBC_X \ + LIBC_ZIPOS \ + THIRD_PARTY_DTOA + +LIBC_TESTLIB_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_TESTLIB_A_DIRECTDEPS),$($(x)))) + +$(LIBC_TESTLIB_A): \ + libc/testlib/ \ + $(LIBC_TESTLIB_A).pkg \ + $(LIBC_TESTLIB_A_OBJS) + +$(LIBC_TESTLIB_A).pkg: \ + $(LIBC_TESTLIB_A_OBJS) \ + $(foreach x,$(LIBC_TESTLIB_A_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_TESTLIB_ARTIFACTS += LIBC_TESTLIB_RUNNER_A +LIBC_TESTLIB_RUNNER = $(LIBC_TESTLIB_RUNNER_A_DEPS) $(LIBC_TESTLIB_RUNNER_A) +LIBC_TESTLIB_RUNNER_A = o/$(MODE)/libc/testlib/runner.a +LIBC_TESTLIB_RUNNER_A_SRCS = libc/testlib/runner.c +LIBC_TESTLIB_RUNNER_A_CHECKS = $(LIBC_TESTLIB_RUNNER_A).pkg + +LIBC_TESTLIB_RUNNER_A_OBJS = \ + $(LIBC_TESTLIB_RUNNER_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_TESTLIB_RUNNER_A_SRCS:%.c=o/$(MODE)/%.o) + +LIBC_TESTLIB_RUNNER_A_DIRECTDEPS = \ + LIBC_FMT \ + LIBC_RUNTIME \ + LIBC_NEXGEN32E \ + LIBC_STDIO \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_TESTLIB + +LIBC_TESTLIB_RUNNER_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_TESTLIB_RUNNER_A_DIRECTDEPS),$($(x)))) + +$(LIBC_TESTLIB_RUNNER_A): \ + libc/testlib/ \ + $(LIBC_TESTLIB_RUNNER_A).pkg \ + $(LIBC_TESTLIB_RUNNER_A_OBJS) + +$(LIBC_TESTLIB_RUNNER_A).pkg: \ + $(LIBC_TESTLIB_RUNNER_A_OBJS) \ + $(foreach x,$(LIBC_TESTLIB_RUNNER_A_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_TESTLIB_ARTIFACTS += LIBC_TESTMAIN + +LIBC_TESTMAIN = \ + $(LIBC_TESTMAIN_DEPS) \ + $(LIBC_TESTMAIN_OBJS) + +LIBC_TESTMAIN_CHECKS = \ + o/$(MODE)/libc/testlib/testmain.pkg + +LIBC_TESTMAIN_SRCS = \ + libc/testlib/testmain.c + +LIBC_TESTMAIN_OBJS = \ + $(LIBC_TESTMAIN_SRCS:%=o/$(MODE)/%.zip.o) \ + o/$(MODE)/libc/testlib/testmain.o + +LIBC_TESTMAIN_DIRECTDEPS = \ + LIBC_CALLS \ + LIBC_LOG \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_STDIO \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_SYSV_CALLS \ + LIBC_TESTLIB \ + LIBC_TESTLIB_RUNNER \ + THIRD_PARTY_GETOPT + +LIBC_TESTMAIN_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_TESTMAIN_DIRECTDEPS),$($(x)))) + +o/$(MODE)/libc/testlib/testmain.pkg: \ + $(LIBC_TESTMAIN_OBJS) \ + $(foreach x,$(LIBC_TESTMAIN_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + +LIBC_TESTLIB_LIBS = $(foreach x,$(LIBC_TESTLIB_ARTIFACTS),$($(x)_A)) +LIBC_TESTLIB_ARCHIVES = $(foreach x,$(LIBC_TESTLIB_ARTIFACTS),$($(x)_A)) +LIBC_TESTLIB_SRCS = $(foreach x,$(LIBC_TESTLIB_ARTIFACTS),$($(x)_SRCS)) +LIBC_TESTLIB_HDRS = $(foreach x,$(LIBC_TESTLIB_ARTIFACTS),$($(x)_HDRS)) +LIBC_TESTLIB_CHECKS = $(foreach x,$(LIBC_TESTLIB_ARTIFACTS),$($(x)_CHECKS)) +LIBC_TESTLIB_OBJS = $(foreach x,$(LIBC_TESTLIB_ARTIFACTS),$($(x)_OBJS)) +$(LIBC_TESTLIB_OBJS): $(BUILD_FILES) libc/libc.mk + +.PHONY: o/$(MODE)/libc/testlib +o/$(MODE)/libc/testlib: $(LIBC_TESTLIB_LIBS) $(LIBC_TESTLIB_CHECKS) diff --git a/libc/testlib/testmain.c b/libc/testlib/testmain.c new file mode 100644 index 00000000..69e6491a --- /dev/null +++ b/libc/testlib/testmain.c @@ -0,0 +1,82 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/internal.h" +#include "libc/log/log.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/runtime/rbx.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/ex.h" +#include "libc/sysv/consts/exit.h" +#include "libc/testlib/testlib.h" +#include "third_party/getopt/getopt.h" + +#define USAGE \ + " [FLAGS]\n\ +\n\ +Flags:\n\ +\n\ + -b run benchmarks if tests pass\n\ + -h show this information\n\ +\n" + +STATIC_YOINK("die"); + +static bool runbenchmarks_; + +static testonly void PrintUsage(int rc, FILE *f) { + fputs("Usage: ", f); + fputs(program_invocation_name, f); + fputs(USAGE, f); + exit(rc); +} + +static testonly void GetOpts(int argc, char *argv[]) { + int opt; + while ((opt = getopt(argc, argv, "?hb")) != -1) { + switch (opt) { + case 'b': + runbenchmarks_ = true; + break; + case '?': + case 'h': + PrintUsage(EXIT_SUCCESS, stdout); + default: + PrintUsage(EX_USAGE, stderr); + } + } +} + +/** + * Generic test program main function. + */ +testonly int main(int argc, char *argv[]) { + g_loglevel = kLogInfo; + GetOpts(argc, argv); + showcrashreports(); + g_testlib_shoulddebugbreak = IsDebuggerPresent(false); + getpid$sysv(); /* make strace easier to read */ + testlib_runalltests(); + if (!g_testlib_failed && runbenchmarks_ && weaken(testlib_runallbenchmarks)) { + weaken(testlib_runallbenchmarks)(); + } + return min(255, g_testlib_failed); +} diff --git a/libc/testlib/testmem.c b/libc/testlib/testmem.c new file mode 100644 index 00000000..e95356b1 --- /dev/null +++ b/libc/testlib/testmem.c @@ -0,0 +1,185 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/dce.h" +#include "libc/fmt/bing.h" +#include "libc/limits.h" +#include "libc/log/check.h" +#include "libc/log/log.h" +#include "libc/macros.h" +#include "libc/mem/mem.h" +#include "libc/runtime/sysconf.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" +#include "libc/testlib/testlib.h" + +struct TestMemoryStack g_testmem; +struct TestMemoryStack g_testmem_trash; +static struct TestAllocation g_testmem_scratch[2][8]; +static const char kMemZero[1]; +static bool g_atstartofpage; + +static struct TestAllocation testmem_push(struct TestMemoryStack *stack, + struct TestAllocation entry) { + if (stack->i == stack->n) { + if (!grow(&stack->p, &stack->n, sizeof(struct TestAllocation), 0)) abort(); + } + return (stack->p[stack->i++] = entry); +} + +static struct TestAllocation testmem_pop(struct TestMemoryStack *stack) { + assert(stack->i > 0); + struct TestAllocation res = stack->p[--stack->i]; + return res; +} + +static void testmem_destroy(struct TestAllocation alloc) { + if (munmap(alloc.mapaddr, alloc.mapsize) == -1) perror("munmap"), die(); +} + +static struct TestAllocation talloc(size_t n) { + struct TestAllocation alloc; + if (n) { + while (g_testmem_trash.i) { + struct TestAllocation trash = testmem_pop(&g_testmem_trash); + if (n <= trash.usersize) { + return trash; + } else { + testmem_destroy(trash); + } + } + alloc.mapsize = ROUNDUP(n + PAGESIZE * 2, FRAMESIZE); + CHECK_NE(MAP_FAILED, (alloc.mapaddr = mapanon(alloc.mapsize))); + CHECK_NE(-1, mprotect(alloc.mapaddr, PAGESIZE, PROT_NONE)); + CHECK_NE(-1, mprotect((char *)alloc.mapaddr + alloc.mapsize - PAGESIZE, + PAGESIZE, PROT_NONE)); + alloc.useraddr = (char *)alloc.mapaddr + PAGESIZE; + alloc.usersize = alloc.mapsize - PAGESIZE * 2; + CHECK_GE(alloc.usersize, n); + return alloc; + } else { + alloc.mapaddr = (/*unconst*/ void *)kMemZero; + alloc.mapsize = 0; + alloc.useraddr = (/*unconst*/ void *)kMemZero; + alloc.usersize = 0; + return alloc; + } +} + +static void testmem_fini(void) { + CHECK_EQ(0, g_testmem.i); + free_s(&g_testmem.p); + while (g_testmem_trash.i) { + testmem_destroy(testmem_pop(&g_testmem_trash)); + } +} + +static void testmem_init(void) { + atexit(testmem_fini); + g_testmem.p = g_testmem_scratch[0]; + g_testmem.n = ARRAYLEN(g_testmem_scratch[0]); + g_testmem_trash.p = g_testmem_scratch[1]; + g_testmem_trash.n = ARRAYLEN(g_testmem_scratch[1]); +} + +const void *const testmem_ctor[] initarray = {testmem_init}; + +FIXTURE(testmemory, triggerOffByOneArrayErrors) { + /* automate testing buffer overflows *and* underflows */ + g_atstartofpage = true; +} + +/** + * Allocates memory with properties useful for testing. + * + * This returns a pointer 𝑝 where reading or writing to either 𝑝[-1] or + * 𝑝[𝑛+𝟷] will immediately trigger a segmentation fault; and bytes are + * initialized to 10100101 (A5). + * + * Implementation Details: Accomplishing this entails two things. First, + * we grant each allocation a page granular memory mapping, with access + * to the two adjacent pages disabled. Second, since hardware memory + * protection isn't 1-byte granular, we add a fixture so each test runs + * a second time; the first call we return a pointer where the data is + * placed on the righthand side, and the second call we return the data + * on the lefthand side, thereby allowing both underflow/overflow + * off-by-one out-of-bounds accesses to be detected. + */ +void *tmalloc(size_t n) { + struct TestAllocation alloc = talloc(n); + memset(alloc.useraddr, 0xa5, alloc.usersize); + testmem_push(&g_testmem, alloc); + return (char *)alloc.useraddr + (g_atstartofpage ? 0 : alloc.usersize - n); +} + +/** + * Same as tmalloc() but guarantees a specific alignment. + * + * Reading or writing to either 𝑝[-1] or 𝑝[roundup(𝑛+𝟷,𝑎)] will + * immediately trigger a segmentation fault. + * + * @param 𝑎 is alignment in bytes, e.g. 16 + * @param 𝑛 is number of bytes + */ +void *tmemalign(size_t a, size_t n) { + /* TODO(jart): ASAN detect 𝑝[𝑛+𝟷] */ + return tmalloc(ROUNDUP(n, a)); +} + +/** + * Same as tunbing() w/ alignment guarantee. + */ +void *tunbinga(size_t a, const char16_t *binglyphs) { + size_t size; + EXPECT_NE(0, (size = strlen16(binglyphs))); + return unbingbuf(tmemalign(a, size), size, binglyphs, -1); +} + +/** + * Decodes CP437 glyphs to bounds-checked binary buffer, e.g. + * + * char *mem = tunbing(u" ☺☻♥♦"); + * EXPECT_EQ(0, memcmp("\0\1\2\3\4", mem, 5)); + * tfree(mem); + * + * @see tunbing(), unbingstr(), unbing() + */ +void *tunbing(const char16_t *binglyphs) { + return tunbinga(1, binglyphs); +} + +/** + * Frees memory allocated with tmalloc(). + * This needs to be called in LIFO order. + * @param + */ +void(tfree)(void *p) { + struct TestAllocation alloc; + __tfree_check(p); + alloc = testmem_pop(&g_testmem); + if (alloc.mapsize) testmem_push(&g_testmem_trash, alloc); +} + +char *tstrdup(const char *s) { + return strcpy(tmalloc(strlen(s) + 1), s); +} diff --git a/libc/testlib/testrunner.c b/libc/testlib/testrunner.c new file mode 100644 index 00000000..025b5e80 --- /dev/null +++ b/libc/testlib/testrunner.c @@ -0,0 +1,77 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/internal.h" +#include "libc/errno.h" +#include "libc/nt/process.h" +#include "libc/stdio/stdio.h" +#include "libc/testlib/testlib.h" + +void SetUp(void); +void TearDown(void); + +void testlib_finish(void) { + if (g_testlib_failed) { + fprintf(stderr, "%u / %u %s\n", g_testlib_failed, g_testlib_ran, + "tests failed"); + } +} + +noreturn void testlib_abort(void) { + int rc; + testlib_finish(); + rc = min(255, g_testlib_failed); + quick_exit(rc); /* so we don't run __testmemory_fini() */ + unreachable; +} + +/** + * Runs all test case functions in sorted order. + */ +testonly void testlib_runtestcases(testfn_t *start, testfn_t *end, + testfn_t warmup) { + /** + * getpid() calls are inserted to help visually see tests in traces + * which can be performed on Linux, FreeBSD, OpenBSD, and XNU: + * + * strace -f o/default/test.com |& less + * truss o/default/test.com |& less + * ktrace -f trace o/default/test.com 5000000)); + } +} diff --git a/libc/time/asctime.c b/libc/time/asctime.c new file mode 100644 index 00000000..fbd5b3db --- /dev/null +++ b/libc/time/asctime.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/time/time.h" + +static char g_asctime_buf[64]; + +char *asctime(const struct tm *date) { return asctime_r(date, g_asctime_buf); } diff --git a/libc/time/asctime_r.c b/libc/time/asctime_r.c new file mode 100644 index 00000000..047a2045 --- /dev/null +++ b/libc/time/asctime_r.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/fmt/fmt.h" +#include "libc/time/struct/tm.h" +#include "libc/time/time.h" + +STATIC_YOINK("ntoa"); +STATIC_YOINK("stoa"); + +static unsigned clip(unsigned index, unsigned count) { + return index < count ? index : 0; +} + +char *asctime_r(const struct tm *date, char *buf /*[64]*/) { + (snprintf)(buf, 64, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n", + kWeekdayNameShort[clip(date->tm_wday, 7)], + kMonthNameShort[clip(date->tm_mon, 12)], date->tm_mday, + date->tm_hour, date->tm_min, date->tm_sec, 1900 + date->tm_year); + return buf; +} diff --git a/libc/time/clock.c b/libc/time/clock.c new file mode 100644 index 00000000..80daf04e --- /dev/null +++ b/libc/time/clock.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/struct/timespec.h" +#include "libc/sysv/consts/clock.h" +#include "libc/time/time.h" + +/** + * Returns how much CPU program has consumed on time-sharing system. + * + * @return value that can be divided by CLOCKS_PER_SEC, or -1 w/ errno + */ +int64_t clock(void) { + struct timespec ts; + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == -1) return -1; + return ts.tv_sec * CLOCKS_PER_SEC + + ts.tv_nsec / (1000000000 / CLOCKS_PER_SEC); +} diff --git a/libc/time/clock_gettime.c b/libc/time/clock_gettime.c new file mode 100644 index 00000000..56004bb2 --- /dev/null +++ b/libc/time/clock_gettime.c @@ -0,0 +1,76 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/timespec.h" +#include "libc/calls/struct/timeval.h" +#include "libc/conv/conv.h" +#include "libc/dce.h" +#include "libc/mach.h" +#include "libc/nt/struct/filetime.h" +#include "libc/nt/struct/systemtime.h" +#include "libc/nt/synchronization.h" +#include "libc/sysv/consts/clock.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/errfuns.h" +#include "libc/time/time.h" + +/** + * Returns nanosecond time. + * + * This is a high-precision timer that supports multiple definitions of + * time. Among the more popular is CLOCK_MONOTONIC. This function has a + * zero syscall implementation of that on modern x86. + * + * @param clockid can be CLOCK_REALTIME, CLOCK_MONOTONIC, etc. noting + * that on Linux CLOCK_MONOTONIC is redefined to use the monotonic + * clock that's actually monotonic lool + * @param out_ts is where the nanoseconds are stored + * @return 0 on success or -1 w/ errno on error + * @error ENOSYS if clockid isn't available; in which case this function + * guarantees an ordinary timestamp is still stored to out_ts; and + * errno isn't restored to its original value, to detect prec. loss + * @see strftime(), gettimeofday() + * @asyncsignalsafe + */ +int clock_gettime(int clockid, struct timespec *out_ts) { + /* TODO(jart): Just ignore O/S for MONOTONIC and measure RDTSC on start */ + if (!IsWindows()) { + if (!IsXnu()) { + out_ts->tv_sec = 0; + out_ts->tv_nsec = 0; + return clock_gettime$sysv(clockid, out_ts); + } else { + static_assert(sizeof(struct timeval) == sizeof(struct timespec)); + out_ts->tv_sec = 0; + out_ts->tv_nsec = 0; + int rc = gettimeofday$sysv((struct timeval *)out_ts, NULL); + out_ts->tv_nsec *= 1000; + return rc; + } + } else { + struct NtFileTime ft; + GetSystemTimeAsFileTime(&ft); + filetimetotimespec(out_ts, ft); + return 0; + } +} diff --git a/libc/time/ctime.c b/libc/time/ctime.c new file mode 100644 index 00000000..c79b323b --- /dev/null +++ b/libc/time/ctime.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/time/time.h" + +char *ctime(const int64_t *timep) { return asctime(localtime(timep)); } diff --git a/libc/time/ctime_r.c b/libc/time/ctime_r.c new file mode 100644 index 00000000..1b543bee --- /dev/null +++ b/libc/time/ctime_r.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/time/struct/tm.h" +#include "libc/time/time.h" + +char *ctime_r(const int64_t *timep, char *buf /*[64]*/) { + struct tm date[1]; + return asctime_r(localtime_r(timep, date), buf); +} diff --git a/libc/time/difftime.c b/libc/time/difftime.c new file mode 100644 index 00000000..8fa93a15 --- /dev/null +++ b/libc/time/difftime.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/time/time.h" + +double difftime(int64_t x, int64_t y) { return x - y; } diff --git a/libc/time/dsleep.c b/libc/time/dsleep.c new file mode 100644 index 00000000..c9cb1858 --- /dev/null +++ b/libc/time/dsleep.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/struct/timespec.h" +#include "libc/math.h" +#include "libc/nexgen32e/nexgen32e.h" +#include "libc/time/time.h" + +/** + * Sleeps w/ higher precision. + */ +long double dsleep(long double secs) { + struct timespec dur, rem; + dur.tv_sec = secs; + dur.tv_nsec = secs * 1e9; + dur.tv_nsec = mod1000000000int64(dur.tv_nsec); + if (secs > 1e-6) { + nanosleep(&dur, &rem); + secs = rem.tv_nsec; + secs *= 1 / 1e9; + secs += rem.tv_sec; + return secs; + } else { + return 0; + } +} diff --git a/libc/time/dtime.c b/libc/time/dtime.c new file mode 100644 index 00000000..5d064111 --- /dev/null +++ b/libc/time/dtime.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/struct/timespec.h" +#include "libc/str/str.h" +#include "libc/time/time.h" + +/** + * Returns seconds since epoch w/ high-precision. + * @param clockid can be CLOCK_{REALTIME,MONOTONIC}, etc. + */ +long double dtime(int clockid) { + long double secs; + struct timespec tv; + clock_gettime(clockid, &tv); + secs = tv.tv_nsec; + secs *= 1 / 1e9; + secs += tv.tv_sec; + return secs; +} diff --git a/libc/time/getitimer.c b/libc/time/getitimer.c new file mode 100644 index 00000000..4e5f4393 --- /dev/null +++ b/libc/time/getitimer.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/sysv/errfuns.h" +#include "libc/time/time.h" + +/** + * Retrieves last setitimer() value, correcting for remaining time. + * + * @param which can be ITIMER_REAL, ITIMER_VIRTUAL, etc. + * @return 0 on success or -1 w/ errno + */ +int getitimer(int which, struct itimerval *curvalue) { + if (!IsWindows()) { + int getitimer$sysv(int, struct itimerval *) hidden; + return getitimer$sysv(which, curvalue); + } else { + return enosys(); /* TODO(jart): Implement me! */ + } +} diff --git a/libc/time/gettimeofday-nt.c b/libc/time/gettimeofday-nt.c new file mode 100644 index 00000000..03f78700 --- /dev/null +++ b/libc/time/gettimeofday-nt.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/struct/timeval.h" +#include "libc/conv/conv.h" +#include "libc/nt/struct/filetime.h" +#include "libc/nt/struct/systemtime.h" +#include "libc/nt/synchronization.h" +#include "libc/str/str.h" +#include "libc/time/struct/timezone.h" + +int gettimeofday$nt(struct timeval *tv, struct timezone *tz) { + struct NtFileTime ft; + GetSystemTimeAsFileTime(&ft); + filetimetotimeval(tv, ft); + if (tz) memset(tz, 0, sizeof(*tz)); + return 0; +} diff --git a/libc/time/gettimeofday-sysv.S b/libc/time/gettimeofday-sysv.S new file mode 100644 index 00000000..17ec1f6f --- /dev/null +++ b/libc/time/gettimeofday-sysv.S @@ -0,0 +1,54 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/macros.h" + +/ Returns system wall time in microseconds. +/ +/ @param rdi points to timeval that receives result +/ @param rsi receives UTC timezone if non-NULL +/ @return always zero +/ @see clock_gettime() for nanosecond precision +/ @see strftime() for string formatting +gettimeofday$sysv: + push %rbp + mov %rsp,%rbp + .profilable + test %rsi,%rsi + jz 1f + push $0 + pop (%rsi) +1: xor %esi,%esi # no one zones this way. + xor %edx,%edx # i64*mach_absolute_time + call __gettimeofday$sysv +#if SupportsXnu() + testb IsXnu() # XNU might do %rax:%rdx + jz 1f + test %rdi,%rdi + jz 1f + test %rax,%rax + jz 1f + mov %rax,(%rdi) + mov %rdx,8(%rdi) +#endif +1: xor %eax,%eax # nevar fail + pop %rbp + ret + .endfn gettimeofday$sysv,globl,hidden diff --git a/libc/time/gettimeofday.c b/libc/time/gettimeofday.c new file mode 100644 index 00000000..8d74e360 --- /dev/null +++ b/libc/time/gettimeofday.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/time/time.h" + +/** + * Returns system wall time in microseconds. + * + * @param tv points to timeval that receives result + * @param tz receives UTC timezone if non-NULL + * @return always zero + * @see clock_gettime() for nanosecond precision + * @see strftime() for string formatting + */ +int gettimeofday(struct timeval *tv, struct timezone *tz) { + if (!IsWindows()) { + return gettimeofday$sysv(tv, tz); + } else { + return gettimeofday$nt(tv, tz); + } +} diff --git a/libc/time/kmonthname.S b/libc/time/kmonthname.S new file mode 100644 index 00000000..8d538103 --- /dev/null +++ b/libc/time/kmonthname.S @@ -0,0 +1,28 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/macros.inc" + +/ extern const char kMonthName[12][10]; + .section .rodata,"aS",@progbits +kMonthName: + .ascin "January",10 + .ascin "February",10 + .ascin "March",10 + .ascin "April",10 + .ascin "May",10 + .ascin "June",10 + .ascin "July",10 + .ascin "August",10 + .ascin "September",10 + .ascin "October",10 + .ascin "November",10 + .ascin "December",10 + .endobj kMonthName,globl + .previous diff --git a/libc/time/kmonthnameshort.S b/libc/time/kmonthnameshort.S new file mode 100644 index 00000000..3a90b2ae --- /dev/null +++ b/libc/time/kmonthnameshort.S @@ -0,0 +1,34 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/macros.inc" + +/ Type #1: +/ - Indexable C-String Array +/ - extern const char kMonthNameShort[12][4]; +/ Type #2: +/ - Double-NUL Terminated String +/ - extern const char kMonthNameShort[]; + .section .rodata,"aS",@progbits +kMonthNameShort: + .ascin "Jan",4 + .ascin "Feb",4 + .ascin "Mar",4 + .ascin "Apr",4 + .ascin "May",4 + .ascin "Jun",4 + .ascin "Jul",4 + .ascin "Aug",4 + .ascin "Sep",4 + .ascin "Oct",4 + .ascin "Nov",4 + .ascin "Dec",4 + .byte 0 + .endobj kMonthNameShort,globl + .previous diff --git a/libc/time/kweekdayname.S b/libc/time/kweekdayname.S new file mode 100644 index 00000000..b3c552fa --- /dev/null +++ b/libc/time/kweekdayname.S @@ -0,0 +1,23 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/macros.inc" + +/ extern const char kWeekdayName[7][10]; + .section .rodata,"aS",@progbits +kWeekdayName: + .ascin "Sunday",10 + .ascin "Monday",10 + .ascin "Tuesday",10 + .ascin "Wednesday",10 + .ascin "Thursday",10 + .ascin "Friday",10 + .ascin "Saturday",10 + .endobj kWeekdayName,globl + .previous diff --git a/libc/time/kweekdaynameshort.S b/libc/time/kweekdaynameshort.S new file mode 100644 index 00000000..4ac02d26 --- /dev/null +++ b/libc/time/kweekdaynameshort.S @@ -0,0 +1,29 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/macros.inc" + +/ Type #1: +/ - Indexable C-String Array +/ - extern const char kWeekdayNameShort[7][4]; +/ Type #2: +/ - Double-NUL Terminated String +/ - extern const char kWeekdayNameShort[]; + .section .rodata,"aS",@progbits +kWeekdayNameShort: + .asciz "Sun" + .asciz "Mon" + .asciz "Tue" + .asciz "Wed" + .asciz "Thu" + .asciz "Fri" + .asciz "Sat" + .byte 0 + .endobj kWeekdayNameShort,globl + .previous diff --git a/libc/time/localtime.c b/libc/time/localtime.c new file mode 100644 index 00000000..302fe321 --- /dev/null +++ b/libc/time/localtime.c @@ -0,0 +1,2045 @@ +#include "libc/calls/calls.h" +#include "libc/macros.h" +#include "libc/math.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/o.h" +#include "libc/time/struct/tm.h" +#include "libc/time/time.h" +#include "libc/tzfile.h" + +#define ALL_STATE + +#define P(x) x +#define time_t int64_t +#define int_fast64_t int64_t +#define int_fast32_t int32_t +#define GRANDPARENTED "local time zone must be set" +#define AVGSECSPERYEAR 31556952L +#define SECSPERREPEAT \ + ((int_fast64_t)YEARSPERREPEAT * (int_fast64_t)AVGSECSPERYEAR) +#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */ +#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */ +#define TM_ZONE tm_zone +#define INITIALIZE(x) x = 0 +static int is_digit(int c) { + return isdigit(c); +} + +asm(".ident\t\"\\n\\n\ +localtime (Public Domain)\\n\ +Credit: Arthur David Olson\""); + +STATIC_YOINK("usr/share/zoneinfo/GST"); + +/* clang-format off */ +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson. +*/ + +/* #ifndef lint */ +/* #ifndef NOID */ +/* static char elsieid[] = "@(#)localtime.c 8.3"; */ +/* #endif /\* !defined NOID *\/ */ +/* #endif /\* !defined lint *\/ */ + +/* +** Leap second handling from Bradley White. +** POSIX-style TZ environment variable handling from Guy Harris. +*/ + +#ifndef TZ_ABBR_MAX_LEN +#define TZ_ABBR_MAX_LEN 16 +#endif /* !defined TZ_ABBR_MAX_LEN */ + +#ifndef TZ_ABBR_CHAR_SET +#define TZ_ABBR_CHAR_SET \ + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._" +#endif /* !defined TZ_ABBR_CHAR_SET */ + +#ifndef TZ_ABBR_ERR_CHAR +#define TZ_ABBR_ERR_CHAR '_' +#endif /* !defined TZ_ABBR_ERR_CHAR */ + +#ifndef WILDABBR +/* +** Someone might make incorrect use of a time zone abbreviation: +** 1. They might reference tzname[0] before calling tzset (explicitly +** or implicitly). +** 2. They might reference tzname[1] before calling tzset (explicitly +** or implicitly). +** 3. They might reference tzname[1] after setting to a time zone +** in which Daylight Saving Time is never observed. +** 4. They might reference tzname[0] after setting to a time zone +** in which Standard Time is never observed. +** 5. They might reference tm.TM_ZONE after calling offtime. +** What's best to do in the above cases is open to debate; +** for now, we just set things up so that in any of the five cases +** WILDABBR is used. Another possibility: initialize tzname[0] to the +** string "tzname[0] used before set", and similarly for the other cases. +** And another: initialize tzname[0] to "ERA", with an explanation in the +** manual page of what this "time zone abbreviation" means (doing this so +** that tzname[0] has the "normal" length of three characters). +*/ +#define WILDABBR " " +#endif /* !defined WILDABBR */ + +static const char wildabbr[] = WILDABBR; +static char wildabbr2[sizeof(WILDABBR)]; + +static const char gmt[] = "UTC"; + +/* +** The DST rules to use if TZ has no rules and we can't load TZDEFRULES. +** We default to US rules as of 1999-08-17. +** POSIX 1003.1 section 8.1.1 says that the default DST rules are +** implementation dependent; for historical reasons, US rules are a +** common default. +*/ +#ifndef TZDEFRULESTRING +#define TZDEFRULESTRING ",M4.1.0,M10.5.0" +#endif /* !defined TZDEFDST */ + +struct ttinfo { /* time type information */ + long tt_gmtoff; /* UTC offset in seconds */ + int tt_isdst; /* used to set tm_isdst */ + int tt_abbrind; /* abbreviation list index */ + int tt_ttisstd; /* TRUE if transition is std time */ + int tt_ttisgmt; /* TRUE if transition is UTC */ +}; + +struct lsinfo { /* leap second information */ + time_t ls_trans; /* transition time */ + long ls_corr; /* correction to apply */ +}; + +#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b)) + +#ifdef TZNAME_MAX +#define MY_TZNAME_MAX TZNAME_MAX +#endif /* defined TZNAME_MAX */ +#ifndef TZNAME_MAX +#define MY_TZNAME_MAX 255 +#endif /* !defined TZNAME_MAX */ + +struct state { + int leapcnt; + int timecnt; + int typecnt; + int charcnt; + int goback; + int goahead; + time_t ats[TZ_MAX_TIMES]; + unsigned char types[TZ_MAX_TIMES]; + struct ttinfo ttis[TZ_MAX_TYPES]; + char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt), + (2 * (MY_TZNAME_MAX + 1)))]; + struct lsinfo lsis[TZ_MAX_LEAPS]; +}; + +struct rule { + int r_type; /* type of rule--see below */ + int r_day; /* day number of rule */ + int r_week; /* week number of rule */ + int r_mon; /* month number of rule */ + int32_t r_time; /* transition time of rule */ +}; + +#define JULIAN_DAY 0 /* Jn - Julian day */ +#define DAY_OF_YEAR 1 /* n - day of year */ +#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */ + +/* +** Prototypes for static functions. +*/ + +static int32_t detzcode P((const char * codep)); +static time_t detzcode64 P((const char * codep)); +static int differ_by_repeat P((time_t t1, time_t t0)); +static const char * getzname P((const char * strp)); +static const char * getqzname P((const char * strp, const int delim)); +static const char * getnum P((const char * strp, int * nump, int min, + int max)); +static const char * getsecs P((const char * strp, int32_t * secsp)); +static const char * getoffset P((const char * strp, int32_t * offsetp)); +static const char * getrule P((const char * strp, struct rule * rulep)); +static void gmtload P((struct state * sp)); +static struct tm * gmtsub P((const time_t * timep, int32_t offset, + struct tm * tmp)); +static struct tm * localsub P((const time_t * timep, int32_t offset, + struct tm * tmp)); +static int increment_overflow P((int * number, int delta)); +static int leaps_thru_end_of P((int y)); +static int normalize_overflow P((int * tensptr, int * unitsptr, + int base)); +static void settzname P((void)); +static time_t time1 P((struct tm * tmp, + struct tm * (*funcp) P((const time_t *, + int32_t, struct tm *)), + int32_t offset)); +static time_t time2 P((struct tm *tmp, + struct tm * (*funcp) P((const time_t *, + int32_t, struct tm*)), + int32_t offset, int * okayp)); +static time_t time2sub P((struct tm *tmp, + struct tm * (*funcp) P((const time_t *, + int32_t, struct tm*)), + int32_t offset, int * okayp, int do_norm_secs)); +static struct tm * timesub P((const time_t * timep, int32_t offset, + const struct state * sp, struct tm * tmp)); +static int tmcomp P((const struct tm * atmp, + const struct tm * btmp)); +static time_t transtime P((time_t janfirst, int year, + const struct rule * rulep, int32_t offset)); +static int tzload P((const char * name, struct state * sp, + int doextend)); +static int tzparse P((const char * name, struct state * sp, + int lastditch)); + +#ifdef ALL_STATE +static struct state * lclptr; +static struct state * gmtptr; +#endif /* defined ALL_STATE */ + +#ifndef ALL_STATE +static struct state lclmem; +static struct state gmtmem; +#define lclptr (&lclmem) +#define gmtptr (&gmtmem) +#endif /* State Farm */ + +#ifndef TZ_STRLEN_MAX +#define TZ_STRLEN_MAX 255 +#endif /* !defined TZ_STRLEN_MAX */ + +static char lcl_TZname[TZ_STRLEN_MAX + 1]; +static int lcl_is_set; +static int gmt_is_set; + +char * tzname[2] /* = { */ +/* wildabbr, */ +/* wildabbr */ +/* } */; + +INITIALIZER(400, _init_localtime, { + memcpy(wildabbr2, wildabbr, sizeof(WILDABBR)); + tzname[0] = wildabbr2; + tzname[1] = wildabbr2; +}) + +/* +** Section 4.12.3 of X3.159-1989 requires that +** Except for the strftime function, these functions [asctime, +** ctime, gmtime, localtime] return values in one of two static +** objects: a broken-down time structure and an array of char. +** Thanks to Paul Eggert for noting this. +*/ + +static struct tm tm; + +#ifdef USG_COMPAT +time_t timezone = 0; +int daylight = 0; +#endif /* defined USG_COMPAT */ + +#ifdef ALTZONE +time_t altzone = 0; +#endif /* defined ALTZONE */ + +static int32_t +detzcode(codep) +const char * const codep; +{ + register int32_t result; + register int i; + + result = (codep[0] & 0x80) ? ~0L : 0; + for (i = 0; i < 4; ++i) + result = ((unsigned)result << 8) | (codep[i] & 0xff); + return result; +} + +static time_t +detzcode64(codep) +const char * const codep; +{ + register time_t result; + register int i; + + result = (codep[0] & 0x80) ? (~(int_fast64_t) 0) : 0; + for (i = 0; i < 8; ++i) + result = result * 256 + (codep[i] & 0xff); + return result; +} + +static void +settzname P((void)) +{ + register struct state * const sp = lclptr; + register int i; + + tzname[0] = wildabbr2; + tzname[1] = wildabbr2; +#ifdef USG_COMPAT + daylight = 0; + timezone = 0; +#endif /* defined USG_COMPAT */ +#ifdef ALTZONE + altzone = 0; +#endif /* defined ALTZONE */ +#ifdef ALL_STATE + if (sp == NULL) { + tzname[0] = tzname[1] = gmt; + return; + } +#endif /* defined ALL_STATE */ + for (i = 0; i < sp->typecnt; ++i) { + register const struct ttinfo * const ttisp = &sp->ttis[i]; + + tzname[ttisp->tt_isdst] = + &sp->chars[ttisp->tt_abbrind]; +#ifdef USG_COMPAT + if (ttisp->tt_isdst) + daylight = 1; + if (i == 0 || !ttisp->tt_isdst) + timezone = -(ttisp->tt_gmtoff); +#endif /* defined USG_COMPAT */ +#ifdef ALTZONE + if (i == 0 || ttisp->tt_isdst) + altzone = -(ttisp->tt_gmtoff); +#endif /* defined ALTZONE */ + } + /* + ** And to get the latest zone names into tzname. . . + */ + for (i = 0; i < sp->timecnt; ++i) { + register const struct ttinfo * const ttisp = + &sp->ttis[ + sp->types[i]]; + + tzname[ttisp->tt_isdst] = + &sp->chars[ttisp->tt_abbrind]; + } + /* + ** Finally, scrub the abbreviations. + ** First, replace bogus characters. + */ + for (i = 0; i < sp->charcnt; ++i) + if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL) + sp->chars[i] = TZ_ABBR_ERR_CHAR; + /* + ** Second, truncate long abbreviations. + */ + for (i = 0; i < sp->typecnt; ++i) { + register const struct ttinfo * const ttisp = &sp->ttis[i]; + register char * cp = &sp->chars[ttisp->tt_abbrind]; + + if (strlen(cp) > TZ_ABBR_MAX_LEN && + strcmp(cp, GRANDPARENTED) != 0) + *(cp + TZ_ABBR_MAX_LEN) = '\0'; + } +} + +forceinline int +differ_by_repeat(t1, t0) +const time_t t1; +const time_t t0; +{ + if (TYPE_INTEGRAL(time_t) && + TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS) + return 0; + return (t1 - t0) == SECSPERREPEAT; +} + +/* static int toint(unsigned char *s) { */ +/* return (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3]; */ +/* } */ + +static int +typesequiv(sp, a, b) + int a, b; + const struct state *sp; +{ + int result; + if (sp == NULL || + a < 0 || a >= sp->typecnt || + b < 0 || b >= sp->typecnt) + result = FALSE; + else { + const struct ttinfo * ap = &sp->ttis[a]; + const struct ttinfo * bp = &sp->ttis[b]; + result = ap->tt_gmtoff == bp->tt_gmtoff && + ap->tt_isdst == bp->tt_isdst && + ap->tt_ttisstd == bp->tt_ttisstd && + ap->tt_ttisgmt == bp->tt_ttisgmt && + strcmp(&sp->chars[ap->tt_abbrind], + &sp->chars[bp->tt_abbrind]) == 0; + } + return result; +} + +static int +tzload(name, sp, doextend) +register const char * name; +register struct state * const sp; +register const int doextend; +{ + register const char * p; + register int i; + register int fid; + register int stored; + register int nread; + union { + struct tzhead tzhead; + char buf[2 * sizeof(struct tzhead) + + 2 * sizeof *sp + + 4 * TZ_MAX_TIMES]; + } * up; + char fullname[PATH_MAX]; + + up = calloc(1, sizeof *up); + if (up == NULL) + return -1; + + sp->goback = sp->goahead = FALSE; + if (name != NULL /* && issetugid() != 0 */) { + if ((name[0] == ':' && (strchr(name, '/'))) || + name[0] == '/' || strchr(name, '.')) + name = NULL; + } + if (name == NULL && (name = TZDEFAULT) == NULL) + goto oops; + + if (name[0] == ':') + ++name; + if (name[0] != '/') { + if ((p = TZDIR) == NULL) + goto oops; + if ((strlen(p) + strlen(name) + 1) >= sizeof fullname) + goto oops; + strlcpy(fullname, p, sizeof fullname); + strlcat(fullname, "/", sizeof fullname); + strlcat(fullname, name, sizeof fullname); + name = fullname; + } + if ((fid = open(name, O_RDONLY)) == -1) + goto oops; + + nread = read(fid, up->buf, sizeof up->buf); + if (close(fid) < 0 || nread <= 0) + goto oops; + for (stored = 4; stored <= 8; stored *= 2) { + int ttisstdcnt; + int ttisgmtcnt; + + ttisstdcnt = (int) detzcode(up->tzhead.tzh_ttisstdcnt); + ttisgmtcnt = (int) detzcode(up->tzhead.tzh_ttisgmtcnt); + sp->leapcnt = (int) detzcode(up->tzhead.tzh_leapcnt); + sp->timecnt = (int) detzcode(up->tzhead.tzh_timecnt); + sp->typecnt = (int) detzcode(up->tzhead.tzh_typecnt); + sp->charcnt = (int) detzcode(up->tzhead.tzh_charcnt); + p = up->tzhead.tzh_charcnt + sizeof up->tzhead.tzh_charcnt; + if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS || + sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES || + sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES || + sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS || + (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) || + (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0)) + goto oops; + if (nread - (p - up->buf) < + sp->timecnt * stored + /* ats */ + sp->timecnt + /* types */ + sp->typecnt * 6 + /* ttinfos */ + sp->charcnt + /* chars */ + sp->leapcnt * (stored + 4) + /* lsinfos */ + ttisstdcnt + /* ttisstds */ + ttisgmtcnt) /* ttisgmts */ + goto oops; + for (i = 0; i < sp->timecnt; ++i) { + sp->ats[i] = (stored == 4) ? + detzcode(p) : detzcode64(p); + p += stored; + } + for (i = 0; i < sp->timecnt; ++i) { + sp->types[i] = (unsigned char) *p++; + if (sp->types[i] >= sp->typecnt) + goto oops; + } + for (i = 0; i < sp->typecnt; ++i) { + struct ttinfo * ttisp; + + ttisp = &sp->ttis[i]; + ttisp->tt_gmtoff = detzcode(p); + p += 4; + ttisp->tt_isdst = (unsigned char) *p++; + if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1) + goto oops; + ttisp->tt_abbrind = (unsigned char) *p++; + if (ttisp->tt_abbrind < 0 || + ttisp->tt_abbrind > sp->charcnt) + goto oops; + } + for (i = 0; i < sp->charcnt; ++i) + sp->chars[i] = *p++; + sp->chars[i] = '\0'; /* ensure '\0' at end */ + for (i = 0; i < sp->leapcnt; ++i) { + struct lsinfo * lsisp; + + lsisp = &sp->lsis[i]; + lsisp->ls_trans = (stored == 4) ? + detzcode(p) : detzcode64(p); + p += stored; + lsisp->ls_corr = detzcode(p); + p += 4; + } + for (i = 0; i < sp->typecnt; ++i) { + struct ttinfo * ttisp; + + ttisp = &sp->ttis[i]; + if (ttisstdcnt == 0) + ttisp->tt_ttisstd = FALSE; + else { + ttisp->tt_ttisstd = *p++; + if (ttisp->tt_ttisstd != TRUE && + ttisp->tt_ttisstd != FALSE) + goto oops; + } + } + for (i = 0; i < sp->typecnt; ++i) { + struct ttinfo * ttisp; + + ttisp = &sp->ttis[i]; + if (ttisgmtcnt == 0) + ttisp->tt_ttisgmt = FALSE; + else { + ttisp->tt_ttisgmt = *p++; + if (ttisp->tt_ttisgmt != TRUE && + ttisp->tt_ttisgmt != FALSE) + goto oops; + } + } + /* + ** Out-of-sort ats should mean we're running on a + ** signed time_t system but using a data file with + ** unsigned values (or vice versa). + */ + for (i = 0; i < sp->timecnt - 2; ++i) + if (sp->ats[i] > sp->ats[i + 1]) { + ++i; + /* + ** Ignore the end (easy). + */ + sp->timecnt = i; + break; + } + /* + ** If this is an old file, we're done. + */ + if (up->tzhead.tzh_version[0] == '\0') + break; + nread -= p - up->buf; + for (i = 0; i < nread; ++i) + up->buf[i] = p[i]; + /* + ** If this is a narrow integer time_t system, we're done. + */ + if (stored >= sizeof(time_t)) + break; + } + if (doextend && nread > 2 && + up->buf[0] == '\n' && up->buf[nread - 1] == '\n' && + sp->typecnt + 2 <= TZ_MAX_TYPES) { + struct state *ts; + int result; + ts = calloc(1, sizeof(struct state)); + if (!ts) abort(); + up->buf[nread - 1] = '\0'; + result = tzparse(&up->buf[1], ts, FALSE); + if (result == 0 && ts->typecnt == 2 && + sp->charcnt + ts->charcnt <= TZ_MAX_CHARS) { + for (i = 0; i < 2; ++i) + ts->ttis[i].tt_abbrind += + sp->charcnt; + for (i = 0; i < ts->charcnt; ++i) + sp->chars[sp->charcnt++] = + ts->chars[i]; + i = 0; + while (i < ts->timecnt && + ts->ats[i] <= + sp->ats[sp->timecnt - 1]) + ++i; + while (i < ts->timecnt && + sp->timecnt < TZ_MAX_TIMES) { + sp->ats[sp->timecnt] = + ts->ats[i]; + sp->types[sp->timecnt] = + sp->typecnt + + ts->types[i]; + ++sp->timecnt; + ++i; + } + sp->ttis[sp->typecnt++] = ts->ttis[0]; + sp->ttis[sp->typecnt++] = ts->ttis[1]; + } + free(ts); + } + if (sp->timecnt > 1) { + for (i = 1; i < sp->timecnt; ++i) { + if (typesequiv(sp, sp->types[i], sp->types[0]) && + differ_by_repeat(sp->ats[i], sp->ats[0])) { + sp->goback = TRUE; + break; + } + } + for (i = sp->timecnt - 2; i >= 0; --i) { + if (typesequiv(sp, sp->types[sp->timecnt - 1], + sp->types[i]) && + differ_by_repeat(sp->ats[sp->timecnt - 1], + sp->ats[i])) { + sp->goahead = TRUE; + break; + } + } + } + free(up); + return 0; +oops: + free(up); + return -1; +} + +static const int mon_lengths[2][MONSPERYEAR] = { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +}; + +static const int year_lengths[2] = { + DAYSPERNYEAR, DAYSPERLYEAR +}; + +/* +** Given a pointer into a time zone string, scan until a character that is not +** a valid character in a zone name is found. Return a pointer to that +** character. +*/ + +static const char * +getzname(strp) +register const char * strp; +{ + register char c; + + while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && + c != '+') + ++strp; + return strp; +} + +/* +** Given a pointer into an extended time zone string, scan until the ending +** delimiter of the zone name is located. Return a pointer to the delimiter. +** +** As with getzname above, the legal character set is actually quite +** restricted, with other characters producing undefined results. +** We don't do any checking here; checking is done later in common-case code. +*/ + +static const char * +getqzname(register const char *strp, const int delim) +{ + register int c; + + while ((c = *strp) != '\0' && c != delim) + ++strp; + return strp; +} + +/* +** Given a pointer into a time zone string, extract a number from that string. +** Check that the number is within a specified range; if it is not, return +** NULL. +** Otherwise, return a pointer to the first character not part of the number. +*/ + +static const char * +getnum(strp, nump, min, max) +register const char * strp; +int * const nump; +const int min; +const int max; +{ + register char c; + register int num; + + if (strp == NULL || !is_digit(c = *strp)) + return NULL; + num = 0; + do { + num = num * 10 + (c - '0'); + if (num > max) + return NULL; /* illegal value */ + c = *++strp; + } while (is_digit(c)); + if (num < min) + return NULL; /* illegal value */ + *nump = num; + return strp; +} + +/* +** Given a pointer into a time zone string, extract a number of seconds, +** in hh[:mm[:ss]] form, from the string. +** If any error occurs, return NULL. +** Otherwise, return a pointer to the first character not part of the number +** of seconds. +*/ + +static const char * +getsecs(strp, secsp) +register const char * strp; +int32_t * const secsp; +{ + int num; + + /* + ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like + ** "M10.4.6/26", which does not conform to Posix, + ** but which specifies the equivalent of + ** ``02:00 on the first Sunday on or after 23 Oct''. + */ + strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); + if (strp == NULL) + return NULL; + *secsp = num * (int32_t) SECSPERHOUR; + if (*strp == ':') { + ++strp; + strp = getnum(strp, &num, 0, MINSPERHOUR - 1); + if (strp == NULL) + return NULL; + *secsp += num * SECSPERMIN; + if (*strp == ':') { + ++strp; + /* `SECSPERMIN' allows for leap seconds. */ + strp = getnum(strp, &num, 0, SECSPERMIN); + if (strp == NULL) + return NULL; + *secsp += num; + } + } + return strp; +} + +/* +** Given a pointer into a time zone string, extract an offset, in +** [+-]hh[:mm[:ss]] form, from the string. +** If any error occurs, return NULL. +** Otherwise, return a pointer to the first character not part of the time. +*/ + +static const char * +getoffset(strp, offsetp) +register const char * strp; +int32_t * const offsetp; +{ + register int neg = 0; + + if (*strp == '-') { + neg = 1; + ++strp; + } else if (*strp == '+') + ++strp; + strp = getsecs(strp, offsetp); + if (strp == NULL) + return NULL; /* illegal time */ + if (neg) + *offsetp = -*offsetp; + return strp; +} + +/* +** Given a pointer into a time zone string, extract a rule in the form +** date[/time]. See POSIX section 8 for the format of "date" and "time". +** If a valid rule is not found, return NULL. +** Otherwise, return a pointer to the first character not part of the rule. +*/ + +static const char * +getrule(strp, rulep) +const char * strp; +register struct rule * const rulep; +{ + if (*strp == 'J') { + /* + ** Julian day. + */ + rulep->r_type = JULIAN_DAY; + ++strp; + strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); + } else if (*strp == 'M') { + /* + ** Month, week, day. + */ + rulep->r_type = MONTH_NTH_DAY_OF_WEEK; + ++strp; + strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); + if (strp == NULL) + return NULL; + if (*strp++ != '.') + return NULL; + strp = getnum(strp, &rulep->r_week, 1, 5); + if (strp == NULL) + return NULL; + if (*strp++ != '.') + return NULL; + strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); + } else if (is_digit(*strp)) { + /* + ** Day of year. + */ + rulep->r_type = DAY_OF_YEAR; + strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); + } else return NULL; /* invalid format */ + if (strp == NULL) + return NULL; + if (*strp == '/') { + /* + ** Time specified. + */ + ++strp; + strp = getsecs(strp, &rulep->r_time); + } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ + return strp; +} + +/* +** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the +** year, a rule, and the offset from UTC at the time that rule takes effect, +** calculate the Epoch-relative time that rule takes effect. +*/ + +static time_t +transtime(janfirst, year, rulep, offset) +const time_t janfirst; +const int year; +register const struct rule * const rulep; +const int32_t offset; +{ + register int leapyear; + register time_t value; + register int i; + int d, m1, yy0, yy1, yy2, dow; + + INITIALIZE(value); + leapyear = isleap(year); + switch (rulep->r_type) { + + case JULIAN_DAY: + /* + ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap + ** years. + ** In non-leap years, or if the day number is 59 or less, just + ** add SECSPERDAY times the day number-1 to the time of + ** January 1, midnight, to get the day. + */ + value = janfirst + (rulep->r_day - 1) * SECSPERDAY; + if (leapyear && rulep->r_day >= 60) + value += SECSPERDAY; + break; + + case DAY_OF_YEAR: + /* + ** n - day of year. + ** Just add SECSPERDAY times the day number to the time of + ** January 1, midnight, to get the day. + */ + value = janfirst + rulep->r_day * SECSPERDAY; + break; + + case MONTH_NTH_DAY_OF_WEEK: + /* + ** Mm.n.d - nth "dth day" of month m. + */ + value = janfirst; + for (i = 0; i < rulep->r_mon - 1; ++i) + value += mon_lengths[leapyear][i] * SECSPERDAY; + + /* + ** Use Zeller's Congruence to get day-of-week of first day of + ** month. + */ + m1 = (rulep->r_mon + 9) % 12 + 1; + yy0 = (rulep->r_mon <= 2) ? (year - 1) : year; + yy1 = yy0 / 100; + yy2 = yy0 % 100; + dow = ((26 * m1 - 2) / 10 + + 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; + if (dow < 0) + dow += DAYSPERWEEK; + + /* + ** "dow" is the day-of-week of the first day of the month. Get + ** the day-of-month (zero-origin) of the first "dow" day of the + ** month. + */ + d = rulep->r_day - dow; + if (d < 0) + d += DAYSPERWEEK; + for (i = 1; i < rulep->r_week; ++i) { + if (d + DAYSPERWEEK >= + mon_lengths[leapyear][rulep->r_mon - 1]) + break; + d += DAYSPERWEEK; + } + + /* + ** "d" is the day-of-month (zero-origin) of the day we want. + */ + value += d * SECSPERDAY; + break; + } + + /* + ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in + ** question. To get the Epoch-relative time of the specified local + ** time on that day, add the transition time and the current offset + ** from UTC. + */ + return value + rulep->r_time + offset; +} + +/* +** Given a POSIX section 8-style TZ string, fill in the rule tables as +** appropriate. +*/ + +static int +tzparse(name, sp, lastditch) + const char * name; + register struct state * const sp; + const int lastditch; +{ + const char * stdname; + const char * dstname; + size_t stdlen; + size_t dstlen; + int32_t stdoffset; + int32_t dstoffset; + register time_t * atp; + register unsigned char * typep; + register char * cp; + register int load_result; + + INITIALIZE(dstname); + stdname = name; + if (lastditch) { + stdlen = strlen(name); /* length of standard zone name */ + name += stdlen; + if (stdlen >= sizeof sp->chars) + stdlen = (sizeof sp->chars) - 1; + stdoffset = 0; + } else { + if (*name == '<') { + name++; + stdname = name; + name = getqzname(name, '>'); + if (*name != '>') + return (-1); + stdlen = name - stdname; + name++; + } else { + name = getzname(name); + stdlen = name - stdname; + } + if (*name == '\0') + return -1; + name = getoffset(name, &stdoffset); + if (name == NULL) + return -1; + } + load_result = tzload(TZDEFRULES, sp, FALSE); + if (load_result != 0) + sp->leapcnt = 0; /* so, we're off a little */ + sp->timecnt = 0; + if (*name != '\0') { + if (*name == '<') { + dstname = ++name; + name = getqzname(name, '>'); + if (*name != '>') + return -1; + dstlen = name - dstname; + name++; + } else { + dstname = name; + name = getzname(name); + dstlen = name - dstname; /* length of DST zone name */ + } + if (*name != '\0' && *name != ',' && *name != ';') { + name = getoffset(name, &dstoffset); + if (name == NULL) + return -1; + } else dstoffset = stdoffset - SECSPERHOUR; + if (*name == '\0' && load_result != 0) + name = TZDEFRULESTRING; + if (*name == ',' || *name == ';') { + struct rule start; + struct rule end; + register int year; + register time_t janfirst; + time_t starttime; + time_t endtime; + + ++name; + if ((name = getrule(name, &start)) == NULL) + return -1; + if (*name++ != ',') + return -1; + if ((name = getrule(name, &end)) == NULL) + return -1; + if (*name != '\0') + return -1; + sp->typecnt = 2; /* standard time and DST */ + /* + ** Two transitions per year, from EPOCH_YEAR forward. + */ + sp->ttis[0].tt_gmtoff = -dstoffset; + sp->ttis[0].tt_isdst = 1; + sp->ttis[0].tt_abbrind = stdlen + 1; + sp->ttis[1].tt_gmtoff = -stdoffset; + sp->ttis[1].tt_isdst = 0; + sp->ttis[1].tt_abbrind = 0; + atp = sp->ats; + typep = sp->types; + janfirst = 0; + for (year = EPOCH_YEAR; + sp->timecnt + 2 <= TZ_MAX_TIMES; + ++year) { + time_t newfirst; + + starttime = transtime(janfirst, year, &start, + stdoffset); + endtime = transtime(janfirst, year, &end, + dstoffset); + if (starttime > endtime) { + *atp++ = endtime; + *typep++ = 1; /* DST ends */ + *atp++ = starttime; + *typep++ = 0; /* DST begins */ + } else { + *atp++ = starttime; + *typep++ = 0; /* DST begins */ + *atp++ = endtime; + *typep++ = 1; /* DST ends */ + } + sp->timecnt += 2; + newfirst = janfirst; + newfirst += year_lengths[isleap(year)] * + SECSPERDAY; + if (newfirst <= janfirst) + break; + janfirst = newfirst; + } + } else { + register int32_t theirstdoffset; + register int32_t theirdstoffset; + register int32_t theiroffset; + register int isdst; + register int i; + register int j; + + if (*name != '\0') + return -1; + /* + ** Initial values of theirstdoffset and theirdstoffset. + */ + theirstdoffset = 0; + for (i = 0; i < sp->timecnt; ++i) { + j = sp->types[i]; + if (!sp->ttis[j].tt_isdst) { + theirstdoffset = + -sp->ttis[j].tt_gmtoff; + break; + } + } + theirdstoffset = 0; + for (i = 0; i < sp->timecnt; ++i) { + j = sp->types[i]; + if (sp->ttis[j].tt_isdst) { + theirdstoffset = + -sp->ttis[j].tt_gmtoff; + break; + } + } + /* + ** Initially we're assumed to be in standard time. + */ + isdst = FALSE; + theiroffset = theirstdoffset; + /* + ** Now juggle transition times and types + ** tracking offsets as you do. + */ + for (i = 0; i < sp->timecnt; ++i) { + j = sp->types[i]; + sp->types[i] = sp->ttis[j].tt_isdst; + if (sp->ttis[j].tt_ttisgmt) { + /* No adjustment to transition time */ + } else { + /* + ** If summer time is in effect, and the + ** transition time was not specified as + ** standard time, add the summer time + ** offset to the transition time; + ** otherwise, add the standard time + ** offset to the transition time. + */ + /* + ** Transitions from DST to DDST + ** will effectively disappear since + ** POSIX provides for only one DST + ** offset. + */ + if (isdst && !sp->ttis[j].tt_ttisstd) { + sp->ats[i] += dstoffset - + theirdstoffset; + } else { + sp->ats[i] += stdoffset - + theirstdoffset; + } + } + theiroffset = -sp->ttis[j].tt_gmtoff; + if (sp->ttis[j].tt_isdst) + theirdstoffset = theiroffset; + else theirstdoffset = theiroffset; + } + /* + ** Finally, fill in ttis. + ** ttisstd and ttisgmt need not be handled. + */ + sp->ttis[0].tt_gmtoff = -stdoffset; + sp->ttis[0].tt_isdst = FALSE; + sp->ttis[0].tt_abbrind = 0; + sp->ttis[1].tt_gmtoff = -dstoffset; + sp->ttis[1].tt_isdst = TRUE; + sp->ttis[1].tt_abbrind = stdlen + 1; + sp->typecnt = 2; + } + } else { + dstlen = 0; + sp->typecnt = 1; /* only standard time */ + sp->timecnt = 0; + sp->ttis[0].tt_gmtoff = -stdoffset; + sp->ttis[0].tt_isdst = 0; + sp->ttis[0].tt_abbrind = 0; + } + sp->charcnt = stdlen + 1; + if (dstlen != 0) + sp->charcnt += dstlen + 1; + if ((size_t) sp->charcnt > sizeof sp->chars) + return -1; + cp = sp->chars; + (void) strncpy(cp, stdname, stdlen); + cp += stdlen; + *cp++ = '\0'; + if (dstlen != 0) { + (void) strncpy(cp, dstname, dstlen); + *(cp + dstlen) = '\0'; + } + return 0; +} + +static void +gmtload(sp) +struct state * const sp; +{ + if (tzload(gmt, sp, TRUE) != 0) + (void) tzparse(gmt, sp, TRUE); +} + +#ifndef STD_INSPIRED +/* +** A non-static declaration of tzsetwall in a system header file +** may cause a warning about this upcoming static declaration... +*/ +static +#endif /* !defined STD_INSPIRED */ +void +tzsetwall P((void)) +{ + if (lcl_is_set < 0) + return; + lcl_is_set = -1; + +#ifdef ALL_STATE + if (lclptr == NULL) { + lclptr = (struct state *) malloc(sizeof *lclptr); + if (lclptr == NULL) { + settzname(); /* all we can do */ + return; + } + } +#endif /* defined ALL_STATE */ + if (tzload((char *) NULL, lclptr, TRUE) != 0) + gmtload(lclptr); + settzname(); +} + +void +tzset P((void)) +{ + register const char * name = NULL; + /* static char buf[PROP_VALUE_MAX]; */ + + name = getenv("TZ"); + + /* // try the "persist.sys.timezone" system property first */ + /* if (name == NULL && __system_property_get("persist.sys.timezone", buf) > 0) */ + /* name = buf; */ + + if (name == NULL) { + tzsetwall(); + return; + } + + if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0) + return; + lcl_is_set = strlen(name) < sizeof lcl_TZname; + if (lcl_is_set) + (void) strcpy(lcl_TZname, name); + +#ifdef ALL_STATE + if (lclptr == NULL) { + lclptr = (struct state *) malloc(sizeof *lclptr); + if (lclptr == NULL) { + settzname(); /* all we can do */ + return; + } + } +#endif /* defined ALL_STATE */ + if (*name == '\0') { + /* + ** User wants it fast rather than right. + */ + lclptr->leapcnt = 0; /* so, we're off a little */ + lclptr->timecnt = 0; + lclptr->typecnt = 0; + lclptr->ttis[0].tt_isdst = 0; + lclptr->ttis[0].tt_gmtoff = 0; + lclptr->ttis[0].tt_abbrind = 0; + (void) strcpy(lclptr->chars, gmt); + } else if (tzload(name, lclptr, TRUE) != 0) + if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0) + (void) gmtload(lclptr); + settzname(); +} + +/* +** The easy way to behave "as if no library function calls" localtime +** is to not call it--so we drop its guts into "localsub", which can be +** freely called. (And no, the PANS doesn't require the above behavior-- +** but it *is* desirable.) +** +** The unused offset argument is for the benefit of mktime variants. +*/ + +/*ARGSUSED*/ +static struct tm * +localsub(timep, offset, tmp) +const time_t * const timep; +const int32_t offset; +struct tm * const tmp; +{ + register struct state * sp; + register const struct ttinfo * ttisp; + register int i; + register struct tm * result; + const time_t t = *timep; + + sp = lclptr; +#ifdef ALL_STATE + if (sp == NULL) + return gmtsub(timep, offset, tmp); +#endif /* defined ALL_STATE */ + if ((sp->goback && t < sp->ats[0]) || + (sp->goahead && t > sp->ats[sp->timecnt - 1])) { + time_t newt = t; + register time_t seconds; + register time_t tcycles; + register int_fast64_t icycles; + + if (t < sp->ats[0]) + seconds = sp->ats[0] - t; + else seconds = t - sp->ats[sp->timecnt - 1]; + --seconds; + tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR; + ++tcycles; + icycles = tcycles; + if (tcycles - icycles >= 1 || icycles - tcycles >= 1) + return NULL; + seconds = icycles; + seconds *= YEARSPERREPEAT; + seconds *= AVGSECSPERYEAR; + if (t < sp->ats[0]) + newt += seconds; + else newt -= seconds; + if (newt < sp->ats[0] || + newt > sp->ats[sp->timecnt - 1]) + return NULL; /* "cannot happen" */ + result = localsub(&newt, offset, tmp); + if (result == tmp) { + register time_t newy; + + newy = tmp->tm_year; + if (t < sp->ats[0]) + newy -= icycles * YEARSPERREPEAT; + else newy += icycles * YEARSPERREPEAT; + tmp->tm_year = newy; + if (tmp->tm_year != newy) + return NULL; + } + return result; + } + if (sp->timecnt == 0 || t < sp->ats[0]) { + i = 0; + while (sp->ttis[i].tt_isdst) + if (++i >= sp->typecnt) { + i = 0; + break; + } + } else { + register int lo = 1; + register int hi = sp->timecnt; + + while (lo < hi) { + register int mid = (lo + hi) >> 1; + + if (t < sp->ats[mid]) + hi = mid; + else lo = mid + 1; + } + i = (int) sp->types[lo - 1]; + } + ttisp = &sp->ttis[i]; + /* + ** To get (wrong) behavior that's compatible with System V Release 2.0 + ** you'd replace the statement below with + ** t += ttisp->tt_gmtoff; + ** timesub(&t, 0L, sp, tmp); + */ + result = timesub(&t, ttisp->tt_gmtoff, sp, tmp); + tmp->tm_isdst = ttisp->tt_isdst; + tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind]; +#ifdef TM_ZONE + tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind]; +#endif /* defined TM_ZONE */ + return result; +} + +struct tm * +localtime(timep) +const time_t * const timep; +{ + tzset(); + return localsub(timep, 0L, &tm); +} + +/* +** Re-entrant version of localtime. +*/ + +struct tm * +localtime_r(timep, tmp) +const time_t * const timep; +struct tm * tmp; +{ + tzset(); + return localsub(timep, 0L, tmp); +} + +/* +** gmtsub is to gmtime as localsub is to localtime. +*/ + +static struct tm * +gmtsub(timep, offset, tmp) +const time_t * const timep; +const int32_t offset; +struct tm * const tmp; +{ + register struct tm * result; + + if (!gmt_is_set) { + gmt_is_set = TRUE; +#ifdef ALL_STATE + gmtptr = (struct state *) malloc(sizeof *gmtptr); + if (gmtptr != NULL) +#endif /* defined ALL_STATE */ + gmtload(gmtptr); + } + result = timesub(timep, offset, gmtptr, tmp); +#ifdef TM_ZONE + /* + ** Could get fancy here and deliver something such as + ** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero, + ** but this is no time for a treasure hunt. + */ + if (offset != 0) + tmp->TM_ZONE = wildabbr; + else { +#ifdef ALL_STATE + if (gmtptr == NULL) + tmp->TM_ZONE = gmt; + else tmp->TM_ZONE = gmtptr->chars; +#endif /* defined ALL_STATE */ +#ifndef ALL_STATE + tmp->TM_ZONE = gmtptr->chars; +#endif /* State Farm */ + } +#endif /* defined TM_ZONE */ + return result; +} + +struct tm * +gmtime(timep) +const time_t * const timep; +{ + return gmtsub(timep, 0L, &tm); +} + +/* +* Re-entrant version of gmtime. +*/ + +struct tm * +gmtime_r(timep, tmp) +const time_t * const timep; +struct tm * tmp; +{ + return gmtsub(timep, 0L, tmp); +} + +#ifdef STD_INSPIRED + +struct tm * +offtime(timep, offset) +const time_t * const timep; +const int32_t offset; +{ + return gmtsub(timep, offset, &tm); +} + +#endif /* defined STD_INSPIRED */ + +/* +** Return the number of leap years through the end of the given year +** where, to make the math easy, the answer for year zero is defined as zero. +*/ + +pureconst static int +leaps_thru_end_of(y) +register const int y; +{ + return (y >= 0) ? (y / 4 - y / 100 + y / 400) : + -(leaps_thru_end_of(-(y + 1)) + 1); +} + +static struct tm * +timesub(timep, offset, sp, tmp) +const time_t * const timep; +const int32_t offset; +register const struct state * const sp; +register struct tm * const tmp; +{ + register const struct lsinfo * lp; + register time_t tdays; + register int idays; /* unsigned would be so 2003 */ + register long rem; /* ^wut */ + int y; + register const int * ip; + register long corr; + register int hit; + register int i; + + corr = 0; + hit = 0; +#ifdef ALL_STATE + i = (sp == NULL) ? 0 : sp->leapcnt; +#endif /* defined ALL_STATE */ +#ifndef ALL_STATE + i = sp->leapcnt; +#endif /* State Farm */ + while (--i >= 0) { + lp = &sp->lsis[i]; + if (*timep >= lp->ls_trans) { + if (*timep == lp->ls_trans) { + hit = ((i == 0 && lp->ls_corr > 0) || + lp->ls_corr > sp->lsis[i - 1].ls_corr); + if (hit) + while (i > 0 && + sp->lsis[i].ls_trans == + sp->lsis[i - 1].ls_trans + 1 && + sp->lsis[i].ls_corr == + sp->lsis[i - 1].ls_corr + 1) { + ++hit; + --i; + } + } + corr = lp->ls_corr; + break; + } + } + y = EPOCH_YEAR; + tdays = *timep / SECSPERDAY; + rem = *timep - tdays * SECSPERDAY; + while (tdays < 0 || tdays >= year_lengths[isleap(y)]) { + int newy; + register time_t tdelta; + register int idelta; + register int leapdays; + + tdelta = tdays / DAYSPERLYEAR; + idelta = tdelta; + if (tdelta - idelta >= 1 || idelta - tdelta >= 1) + return NULL; + if (idelta == 0) + idelta = (tdays < 0) ? -1 : 1; + newy = y; + if (increment_overflow(&newy, idelta)) + return NULL; + leapdays = leaps_thru_end_of(newy - 1) - + leaps_thru_end_of(y - 1); + tdays -= ((time_t) newy - y) * DAYSPERNYEAR; + tdays -= leapdays; + y = newy; + } + { + register long seconds; + + seconds = tdays * SECSPERDAY + 0.5; + tdays = seconds / SECSPERDAY; + rem += seconds - tdays * SECSPERDAY; + } + /* + ** Given the range, we can now fearlessly cast... + */ + idays = tdays; + rem += offset - corr; + while (rem < 0) { + rem += SECSPERDAY; + --idays; + } + while (rem >= SECSPERDAY) { + rem -= SECSPERDAY; + ++idays; + } + while (idays < 0) { + if (increment_overflow(&y, -1)) + return NULL; + idays += year_lengths[isleap(y)]; + } + while (idays >= year_lengths[isleap(y)]) { + idays -= year_lengths[isleap(y)]; + if (increment_overflow(&y, 1)) + return NULL; + } + tmp->tm_year = y; + if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE)) + return NULL; + tmp->tm_yday = idays; + /* + ** The "extra" mods below avoid overflow problems. + */ + tmp->tm_wday = EPOCH_WDAY + + ((y - EPOCH_YEAR) % DAYSPERWEEK) * + (DAYSPERNYEAR % DAYSPERWEEK) + + leaps_thru_end_of(y - 1) - + leaps_thru_end_of(EPOCH_YEAR - 1) + + idays; + tmp->tm_wday %= DAYSPERWEEK; + if (tmp->tm_wday < 0) + tmp->tm_wday += DAYSPERWEEK; + tmp->tm_hour = (int) (rem / SECSPERHOUR); + rem %= SECSPERHOUR; + tmp->tm_min = (int) (rem / SECSPERMIN); + /* + ** A positive leap second requires a special + ** representation. This uses "... ??:59:60" et seq. + */ + tmp->tm_sec = (int) (rem % SECSPERMIN) + hit; + ip = mon_lengths[isleap(y)]; + for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) + idays -= ip[tmp->tm_mon]; + tmp->tm_mday = (int) (idays + 1); + tmp->tm_isdst = 0; +#ifdef TM_GMTOFF + tmp->TM_GMTOFF = offset; +#endif /* defined TM_GMTOFF */ + return tmp; +} + +/* char * */ +/* ctime(timep) */ +/* const time_t * const timep; */ +/* { */ +/* /\* */ +/* ** Section 4.12.3.2 of X3.159-1989 requires that */ +/* ** The ctime function converts the calendar time pointed to by timer */ +/* ** to local time in the form of a string. It is equivalent to */ +/* ** asctime(localtime(timer)) */ +/* *\/ */ +/* return asctime(localtime(timep)); */ +/* } */ + +/* char * */ +/* ctime_r(timep, buf) */ +/* const time_t * const timep; */ +/* char * buf; */ +/* { */ +/* struct tm mytm; */ +/* return asctime_r(localtime_r(timep, &mytm), buf); */ +/* } */ + +/* +** Adapted from code provided by Robert Elz, who writes: +** The "best" way to do mktime I think is based on an idea of Bob +** Kridle's (so its said...) from a long time ago. +** It does a binary search of the time_t space. Since time_t's are +** just 32 bits, its a max of 32 iterations (even at 64 bits it +** would still be very reasonable). +*/ + +#ifndef WRONG +#define WRONG (-1) +#endif /* !defined WRONG */ + +/* +** Simplified normalize logic courtesy Paul Eggert. +*/ + +static int +increment_overflow(number, delta) +int * number; +int delta; +{ + int number0; + + number0 = *number; + *number += delta; + return (*number < number0) != (delta < 0); +} + +static int +normalize_overflow(tensptr, unitsptr, base) +int * const tensptr; +int * const unitsptr; +const int base; +{ + register int tensdelta; + + tensdelta = (*unitsptr >= 0) ? + (*unitsptr / base) : + (-1 - (-1 - *unitsptr) / base); + *unitsptr -= tensdelta * base; + return increment_overflow(tensptr, tensdelta); +} + +static int +tmcomp(atmp, btmp) +register const struct tm * const atmp; +register const struct tm * const btmp; +{ + register int result; + + if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && + (result = (atmp->tm_mon - btmp->tm_mon)) == 0 && + (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && + (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && + (result = (atmp->tm_min - btmp->tm_min)) == 0) + result = atmp->tm_sec - btmp->tm_sec; + return result; +} + +static time_t +time2sub(tmp, funcp, offset, okayp, do_norm_secs) +struct tm * const tmp; +struct tm * (* const funcp) P((const time_t*, int32_t, struct tm*)); +const int32_t offset; +int * const okayp; +const int do_norm_secs; +{ + register const struct state * sp; + register int dir; + register int i, j; + register int saved_seconds; + register long li; + register time_t lo; + register time_t hi; + int32_t y; + time_t newt; + time_t t; + struct tm yourtm, mytm; + + *okayp = FALSE; + yourtm = *tmp; + if (do_norm_secs) { + if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec, + SECSPERMIN)) + return WRONG; + } + if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR)) + return WRONG; + if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) + return WRONG; + y = yourtm.tm_year; + if (normalize_overflow(&y, &yourtm.tm_mon, MONSPERYEAR)) + return WRONG; + /* + ** Turn y into an actual year number for now. + ** It is converted back to an offset from TM_YEAR_BASE later. + */ + if (increment_overflow(&y, TM_YEAR_BASE)) + return WRONG; + while (yourtm.tm_mday <= 0) { + if (increment_overflow(&y, -1)) + return WRONG; + li = y + (1 < yourtm.tm_mon); + yourtm.tm_mday += year_lengths[isleap(li)]; + } + while (yourtm.tm_mday > DAYSPERLYEAR) { + li = y + (1 < yourtm.tm_mon); + yourtm.tm_mday -= year_lengths[isleap(li)]; + if (increment_overflow(&y, 1)) + return WRONG; + } + for ( ; ; ) { + i = mon_lengths[isleap(y)][yourtm.tm_mon]; + if (yourtm.tm_mday <= i) + break; + yourtm.tm_mday -= i; + if (++yourtm.tm_mon >= MONSPERYEAR) { + yourtm.tm_mon = 0; + if (increment_overflow(&y, 1)) + return WRONG; + } + } + if (increment_overflow(&y, -TM_YEAR_BASE)) + return WRONG; + yourtm.tm_year = y; + if (yourtm.tm_year != y) + return WRONG; + if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) + saved_seconds = 0; + else if (y + TM_YEAR_BASE < EPOCH_YEAR) { + /* + ** We can't set tm_sec to 0, because that might push the + ** time below the minimum representable time. + ** Set tm_sec to 59 instead. + ** This assumes that the minimum representable time is + ** not in the same minute that a leap second was deleted from, + ** which is a safer assumption than using 58 would be. + */ + if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN)) + return WRONG; + saved_seconds = yourtm.tm_sec; + yourtm.tm_sec = SECSPERMIN - 1; + } else { + saved_seconds = yourtm.tm_sec; + yourtm.tm_sec = 0; + } + /* + ** Do a binary search (this works whatever time_t's type is). + */ + if (!TYPE_SIGNED(time_t)) { + lo = 0; + hi = lo - 1; + } else if (!TYPE_INTEGRAL(time_t)) { + if (sizeof(time_t) > sizeof(float)) + hi = (time_t) DBL_MAX; + else hi = (time_t) FLT_MAX; + lo = -hi; + } else { + lo = 1; + for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i) + lo *= 2; + hi = -(lo + 1); + } + for ( ; ; ) { + t = lo / 2 + hi / 2; + if (t < lo) + t = lo; + else if (t > hi) + t = hi; + if ((*funcp)(&t, offset, &mytm) == NULL) { + /* + ** Assume that t is too extreme to be represented in + ** a struct tm; arrange things so that it is less + ** extreme on the next pass. + */ + dir = (t > 0) ? 1 : -1; + } else dir = tmcomp(&mytm, &yourtm); + if (dir != 0) { + if (t == lo) { + ++t; + if (t <= lo) + return WRONG; + ++lo; + } else if (t == hi) { + --t; + if (t >= hi) + return WRONG; + --hi; + } + if (lo > hi) + return WRONG; + if (dir > 0) + hi = t; + else lo = t; + continue; + } + if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) + break; + /* + ** Right time, wrong type. + ** Hunt for right time, right type. + ** It's okay to guess wrong since the guess + ** gets checked. + */ + /* + ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's. + */ + sp = (const struct state *) + (((void *) funcp == (void *) localsub) ? + lclptr : gmtptr); +#ifdef ALL_STATE + if (sp == NULL) + return WRONG; +#endif /* defined ALL_STATE */ + for (i = sp->typecnt - 1; i >= 0; --i) { + if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) + continue; + for (j = sp->typecnt - 1; j >= 0; --j) { + if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) + continue; + newt = t + sp->ttis[j].tt_gmtoff - + sp->ttis[i].tt_gmtoff; + if ((*funcp)(&newt, offset, &mytm) == NULL) + continue; + if (tmcomp(&mytm, &yourtm) != 0) + continue; + if (mytm.tm_isdst != yourtm.tm_isdst) + continue; + /* + ** We have a match. + */ + t = newt; + goto label; + } + } + return WRONG; + } +label: + newt = t + saved_seconds; + if ((newt < t) != (saved_seconds < 0)) + return WRONG; + t = newt; + if ((*funcp)(&t, offset, tmp)) + *okayp = TRUE; + return t; +} + +static time_t +time2(tmp, funcp, offset, okayp) +struct tm * const tmp; +struct tm * (* const funcp) P((const time_t*, int32_t, struct tm*)); +const int32_t offset; +int * const okayp; +{ + time_t t; + + /* + ** First try without normalization of seconds + ** (in case tm_sec contains a value associated with a leap second). + ** If that fails, try with normalization of seconds. + */ + t = time2sub(tmp, funcp, offset, okayp, FALSE); + return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE); +} + +static time_t +time1(tmp, funcp, offset) +struct tm * const tmp; +struct tm * (* const funcp) P((const time_t *, int32_t, struct tm *)); +const int32_t offset; +{ + register time_t t; + register const struct state * sp; + register int samei, otheri; + register int sameind, otherind; + register int i; + register int nseen; + int seen[TZ_MAX_TYPES]; + int types[TZ_MAX_TYPES]; + int okay; + + if (tmp->tm_isdst > 1) + tmp->tm_isdst = 1; + t = time2(tmp, funcp, offset, &okay); +#ifdef PCTS + /* + ** PCTS code courtesy Grant Sullivan. + */ + if (okay) + return t; + if (tmp->tm_isdst < 0) + tmp->tm_isdst = 0; /* reset to std and try again */ +#endif /* defined PCTS */ +#ifndef PCTS + if (okay || tmp->tm_isdst < 0) + return t; +#endif /* !defined PCTS */ + /* + ** We're supposed to assume that somebody took a time of one type + ** and did some math on it that yielded a "struct tm" that's bad. + ** We try to divine the type they started from and adjust to the + ** type they need. + */ + /* + ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's. + */ + sp = (const struct state *) (((void *) funcp == (void *) localsub) ? + lclptr : gmtptr); +#ifdef ALL_STATE + if (sp == NULL) + return WRONG; +#endif /* defined ALL_STATE */ + for (i = 0; i < sp->typecnt; ++i) + seen[i] = FALSE; + nseen = 0; + for (i = sp->timecnt - 1; i >= 0; --i) + if (!seen[sp->types[i]]) { + seen[sp->types[i]] = TRUE; + types[nseen++] = sp->types[i]; + } + for (sameind = 0; sameind < nseen; ++sameind) { + samei = types[sameind]; + if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) + continue; + for (otherind = 0; otherind < nseen; ++otherind) { + otheri = types[otherind]; + if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) + continue; + tmp->tm_sec += sp->ttis[otheri].tt_gmtoff - + sp->ttis[samei].tt_gmtoff; + tmp->tm_isdst = !tmp->tm_isdst; + t = time2(tmp, funcp, offset, &okay); + if (okay) + return t; + tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff - + sp->ttis[samei].tt_gmtoff; + tmp->tm_isdst = !tmp->tm_isdst; + } + } + return WRONG; +} + +time_t +mktime(tmp) +struct tm * const tmp; +{ + tzset(); + return time1(tmp, localsub, 0L); +} + +time_t +timelocal(tmp) +struct tm * const tmp; +{ + tmp->tm_isdst = -1; /* in case it wasn't initialized */ + return mktime(tmp); +} + +time_t +timegm(tmp) +struct tm * const tmp; +{ + tmp->tm_isdst = 0; + return time1(tmp, gmtsub, 0L); +} + +time_t +timeoff(tmp, offset) +struct tm * const tmp; +const long offset; +{ + tmp->tm_isdst = 0; + return time1(tmp, gmtsub, offset); +} + +/* +** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599 +** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which +** is not the case if we are accounting for leap seconds. +** So, we provide the following conversion routines for use +** when exchanging timestamps with POSIX conforming systems. +*/ + +static long +leapcorr(timep) +time_t * timep; +{ + register struct state * sp; + register struct lsinfo * lp; + register int i; + + sp = lclptr; + i = sp->leapcnt; + while (--i >= 0) { + lp = &sp->lsis[i]; + if (*timep >= lp->ls_trans) + return lp->ls_corr; + } + return 0; +} + +pureconst time_t +time2posix(t) +time_t t; +{ + tzset(); + return t - leapcorr(&t); +} + +pureconst time_t +posix2time(t) +time_t t; +{ + time_t x; + time_t y; + + tzset(); + /* + ** For a positive leap second hit, the result + ** is not unique. For a negative leap second + ** hit, the corresponding time doesn't exist, + ** so we return an adjacent second. + */ + x = t + leapcorr(&t); + y = x - leapcorr(&x); + if (y < t) { + do { + x++; + y = x - leapcorr(&x); + } while (y < t); + if (t != y) + return x - 1; + } else if (y > t) { + do { + --x; + y = x - leapcorr(&x); + } while (y > t); + if (t != y) + return x + 1; + } + return x; +} diff --git a/libc/time/nanosleep.c b/libc/time/nanosleep.c new file mode 100644 index 00000000..2d364b7d --- /dev/null +++ b/libc/time/nanosleep.c @@ -0,0 +1,58 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/struct/timespec.h" +#include "libc/calls/struct/timeval.h" +#include "libc/conv/conv.h" +#include "libc/dce.h" +#include "libc/macros.h" +#include "libc/nt/enum/status.h" +#include "libc/nt/errors.h" +#include "libc/nt/nt/time.h" +#include "libc/nt/synchronization.h" +#include "libc/sock/internal.h" +#include "libc/sysv/errfuns.h" + +/** + * Sleeps for a particular amount of time. + */ +int nanosleep(const struct timespec *req, struct timespec *rem) { + long res, millis, hectonanos; + if (!IsWindows()) { + if (!IsXnu()) { + return nanosleep$sysv(req, rem); + } else { + return select$sysv(0, 0, 0, 0, /* lool */ + &(struct timeval){req->tv_sec, req->tv_nsec / 1000}); + } + } else { + if (req->tv_sec && req->tv_nsec) { + hectonanos = MAX(1, req->tv_sec * 10000000L + req->tv_nsec / 100L); + } else { + hectonanos = 1; + } + if (NtError(NtDelayExecution(true, &hectonanos))) { + millis = hectonanos / 10000; + res = SleepEx(millis, true); + if (res == kNtWaitIoCompletion) return eintr(); + } + return 0; + } +} diff --git a/libc/time/now.c b/libc/time/now.c new file mode 100644 index 00000000..928fec00 --- /dev/null +++ b/libc/time/now.c @@ -0,0 +1,89 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/dce.h" +#include "libc/nexgen32e/rdtsc.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/sysv/consts/clock.h" +#include "libc/time/time.h" + +static struct Now { + uint64_t k0; + long double r0, cpn; +} now_; + +/** + * Returns timestamp without needing system calls. + * @note uses microsecond scale fallback on k8 or vm + */ +long double (*nowl)(void); + +long double converttickstonanos(uint64_t ticks) { + return ticks * now_.cpn; /* pico scale */ +} + +long double converttickstoseconds(uint64_t ticks) { + return 1 / 1e9 * converttickstonanos(ticks); +} + +static long double nowl$sys(void) { + return dtime(CLOCK_REALTIME); +} + +static long double nowl$art(void) { + uint64_t ticks; + ticks = unsignedsubtract(rdtsc(), now_.k0); + return now_.r0 + converttickstoseconds(ticks); +} + +static long double GetSample(void) { + uint64_t tick1, tick2; + long double time1, time2; + sched_yield(); + time1 = dtime(CLOCK_MONOTONIC); + tick1 = rdtsc(); + nanosleep(&(struct timespec){0, 100000}, NULL); + time2 = dtime(CLOCK_MONOTONIC); + tick2 = rdtsc(); + return (time2 - time1) * 1e9 / (tick2 - tick1); +} + +static long double MeasureNanosPerCycle(void) { + int i; + long double avg, samp; + for (avg = 1.0L, i = 1; i < 5; ++i) { + samp = GetSample(); + avg += (samp - avg) / i; + } + return avg; +} + +INITIALIZER(301, _init_time, { + if (X86_HAVE(INVTSC)) { + now_.cpn = MeasureNanosPerCycle(); + now_.r0 = dtime(CLOCK_REALTIME); + now_.k0 = rdtsc(); + nowl = nowl$art; + } else { + nowl = nowl$sys; + } +}) diff --git a/libc/time/setitimer.c b/libc/time/setitimer.c new file mode 100644 index 00000000..395d4460 --- /dev/null +++ b/libc/time/setitimer.c @@ -0,0 +1,54 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/struct/itimerval.h" +#include "libc/dce.h" +#include "libc/sysv/errfuns.h" +#include "libc/time/time.h" + +/** + * Schedules delivery of one-shot or intermittent wakeup signal, e.g. + * + * CHECK_NE(-1, sigaction(SIGALRM, + * &(struct sigaction){.sa_sigaction = missingno, + * .sa_flags = SA_RESETHAND}, + * NULL)); + * CHECK_NE(-1, setitimer(ITIMER_REAL, + * &(const struct itimerval){{0, 0}, {0, 50000}}, + * NULL)); + * if (connect(...) == -1 && errno == EINTR) { ... } + * CHECK_NE(-1, setitimer(ITIMER_REAL, + * &(const struct itimerval){{0, 0}, {0, 0}}, + * NULL)); + * + * @param which can be ITIMER_REAL, ITIMER_VIRTUAL, etc. + * @param newvalue specifies the interval ({0,0} means one-shot) and + * duration ({0,0} means disarm) in microseconds + * @param out_opt_old may receive remainder of previous op (if any) + * @return 0 on success or -1 w/ errno + */ +int setitimer(int which, const struct itimerval *newvalue, + struct itimerval *out_opt_oldvalue) { + if (!IsWindows()) { + return setitimer$sysv(which, newvalue, out_opt_oldvalue); + } else { + return enosys(); /* TODO(jart): Implement me! */ + } +} diff --git a/libc/time/sleep.c b/libc/time/sleep.c new file mode 100644 index 00000000..36abbf33 --- /dev/null +++ b/libc/time/sleep.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/struct/timespec.h" +#include "libc/time/time.h" + +/** + * Sleeps for a particular amount of time. + * @asyncsignalsafe + */ +int sleep(uint32_t seconds) { + return nanosleep(&(struct timespec){seconds, 0}, NULL); +} diff --git a/libc/time/strftime.c b/libc/time/strftime.c new file mode 100644 index 00000000..07c76c31 --- /dev/null +++ b/libc/time/strftime.c @@ -0,0 +1,380 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright (c) 1989 The Regents of the University of California. │ +│ All rights reserved. │ +│ │ +│ Redistribution and use in source and binary forms are permitted │ +│ provided that the above copyright notice and this paragraph are │ +│ duplicated in all such forms and that any documentation, │ +│ advertising materials, and other materials related to such │ +│ distribution and use acknowledge that the software was developed │ +│ by the University of California, Berkeley. The name of the │ +│ University may not be used to endorse or promote products derived │ +│ from this software without specific prior written permission. │ +│ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR │ +│ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/fmt/fmt.h" +#include "libc/macros.h" +#include "libc/time/struct/tm.h" +#include "libc/time/time.h" +#include "libc/tzfile.h" + +STATIC_YOINK("ntoa"); + +asm(".ident\t\"\\n\\n\ +strftime (BSD-3)\\n\ +Copyright 1989 The Regents of the University of California\""); +asm(".include \"libc/disclaimer.inc\""); + +static char *strftime_add(char *pt, const char *ptlim, const char *str) { + while (pt < ptlim && (*pt = *str++) != '\0') ++pt; + return pt; +} + +static char *strftime_conv(char *pt, const char *ptlim, int n, + const char *format) { + char buf[INT_STRLEN_MAXIMUM(int) + 1]; + (snprintf)(buf, sizeof(buf), format, n); + return strftime_add(pt, ptlim, buf); +} + +static char *strftime_secs(char *pt, const char *ptlim, const struct tm *t) { + static char buf[INT_STRLEN_MAXIMUM(int) + 1]; + struct tm tmp; + int64_t s; + tmp = *t; /* Make a copy, mktime(3) modifies the tm struct. */ + s = mktime(&tmp); + (snprintf)(buf, sizeof(buf), "%ld", s); + return strftime_add(pt, ptlim, buf); +} + +static char *strftime_timefmt(char *pt, const char *ptlim, const char *format, + const struct tm *t) { + int i; + long diff; + char const *sign; + /* size_t z1, z2, z3; */ + for (; *format; ++format) { + if (*format == '%') { + label: + switch (*++format) { + case '\0': + --format; + break; + case 'A': + pt = strftime_add(pt, ptlim, + (t->tm_wday < 0 || t->tm_wday > 6) + ? "?" + : kWeekdayName[t->tm_wday]); + continue; + case 'a': + pt = strftime_add(pt, ptlim, + (t->tm_wday < 0 || t->tm_wday > 6) + ? "?" + : kWeekdayNameShort[t->tm_wday]); + continue; + case 'B': + pt = strftime_add( + pt, ptlim, + (t->tm_mon < 0 || t->tm_mon > 11) ? "?" : kMonthName[t->tm_mon]); + continue; + case 'b': + case 'h': + pt = strftime_add(pt, ptlim, + (t->tm_mon < 0 || t->tm_mon > 11) + ? "?" + : kMonthNameShort[t->tm_mon]); + continue; + case 'c': + pt = strftime_timefmt(pt, ptlim, "%D %X", t); + continue; + case 'C': + /* + ** %C used to do a... + ** strftime_timefmt("%a %b %e %X %Y", t); + ** ...whereas now POSIX 1003.2 calls for + ** something completely different. + ** (ado, 5/24/93) + */ + pt = strftime_conv(pt, ptlim, (t->tm_year + TM_YEAR_BASE) / 100, + "%02d"); + continue; + case 'D': + pt = strftime_timefmt(pt, ptlim, "%m/%d/%y", t); + continue; + case 'x': + /* + ** Version 3.0 of strftime from Arnold Robbins + ** (arnold@skeeve.atl.ga.us) does the + ** equivalent of... + ** strftime_timefmt("%a %b %e %Y"); + ** ...for %x; since the X3J11 C language + ** standard calls for "date, using locale's + ** date format," anything goes. Using just + ** numbers (as here) makes Quakers happier. + ** Word from Paul Eggert (eggert@twinsun.com) + ** is that %Y-%m-%d is the ISO standard date + ** format, specified in ISO 2014 and later + ** ISO 8601:1988, with a summary available in + ** pub/doc/ISO/english/ISO8601.ps.Z on + ** ftp.uni-erlangen.de. + ** (ado, 5/30/93) + */ + pt = strftime_timefmt(pt, ptlim, "%m/%d/%y", t); + continue; + case 'd': + pt = strftime_conv(pt, ptlim, t->tm_mday, "%02d"); + continue; + case 'E': + case 'O': + /* + ** POSIX locale extensions, a la + ** Arnold Robbins' strftime version 3.0. + ** The sequences + ** %Ec %EC %Ex %Ey %EY + ** %Od %oe %OH %OI %Om %OM + ** %OS %Ou %OU %OV %Ow %OW %Oy + ** are supposed to provide alternate + ** representations. + ** (ado, 5/24/93) + */ + goto label; + case 'e': + pt = strftime_conv(pt, ptlim, t->tm_mday, "%2d"); + continue; + case 'H': + pt = strftime_conv(pt, ptlim, t->tm_hour, "%02d"); + continue; + case 'I': + pt = strftime_conv( + pt, ptlim, (t->tm_hour % 12) ? (t->tm_hour % 12) : 12, "%02d"); + continue; + case 'j': + pt = strftime_conv(pt, ptlim, t->tm_yday + 1, "%03d"); + continue; + case 'k': + /* + ** This used to be... + ** strftime_conv(t->tm_hour % 12 ? + ** t->tm_hour % 12 : 12, 2, ' '); + ** ...and has been changed to the below to + ** match SunOS 4.1.1 and Arnold Robbins' + ** strftime version 3.0. That is, "%k" and + ** "%l" have been swapped. + ** (ado, 5/24/93) + */ + pt = strftime_conv(pt, ptlim, t->tm_hour, "%2d"); + continue; +#ifdef KITCHEN_SINK + case 'K': + /* + ** After all this time, still unclaimed! + */ + pt = strftime_add(pt, ptlim, "kitchen sink"); + continue; +#endif /* defined KITCHEN_SINK */ + case 'l': + /* + ** This used to be... + ** strftime_conv(t->tm_hour, 2, ' '); + ** ...and has been changed to the below to + ** match SunOS 4.1.1 and Arnold Robbin's + ** strftime version 3.0. That is, "%k" and + ** "%l" have been swapped. + ** (ado, 5/24/93) + */ + pt = strftime_conv(pt, ptlim, + (t->tm_hour % 12) ? (t->tm_hour % 12) : 12, "%2d"); + continue; + case 'M': + pt = strftime_conv(pt, ptlim, t->tm_min, "%02d"); + continue; + case 'm': + pt = strftime_conv(pt, ptlim, t->tm_mon + 1, "%02d"); + continue; + case 'n': + pt = strftime_add(pt, ptlim, "\n"); + continue; + case 'p': + pt = strftime_add(pt, ptlim, t->tm_hour >= 12 ? "PM" : "AM"); + continue; + case 'R': + pt = strftime_timefmt(pt, ptlim, "%H:%M", t); + continue; + case 'r': + pt = strftime_timefmt(pt, ptlim, "%I:%M:%S %p", t); + continue; + case 'S': + pt = strftime_conv(pt, ptlim, t->tm_sec, "%02d"); + continue; + case 's': + pt = strftime_secs(pt, ptlim, t); + continue; + case 'T': + case 'X': + pt = strftime_timefmt(pt, ptlim, "%H:%M:%S", t); + continue; + case 't': + pt = strftime_add(pt, ptlim, "\t"); + continue; + case 'U': + pt = strftime_conv(pt, ptlim, (t->tm_yday + 7 - t->tm_wday) / 7, + "%02d"); + continue; + case 'u': + /* + ** From Arnold Robbins' strftime version 3.0: + ** "ISO 8601: Weekday as a decimal number + ** [1 (Monday) - 7]" + ** (ado, 5/24/93) + */ + pt = strftime_conv(pt, ptlim, (t->tm_wday == 0) ? 7 : t->tm_wday, + "%d"); + continue; + case 'V': + /* + ** From Arnold Robbins' strftime version 3.0: + ** "the week number of the year (the first + ** Monday as the first day of week 1) as a + ** decimal number (01-53). The method for + ** determining the week number is as specified + ** by ISO 8601 (to wit: if the week containing + ** January 1 has four or more days in the new + ** year, then it is week 1, otherwise it is + ** week 53 of the previous year and the next + ** week is week 1)." + ** (ado, 5/24/93) + */ + /* + ** XXX--If January 1 falls on a Friday, + ** January 1-3 are part of week 53 of the + ** previous year. By analogy, if January + ** 1 falls on a Thursday, are December 29-31 + ** of the PREVIOUS year part of week 1??? + ** (ado 5/24/93) + ** + ** You are understood not to expect this. + */ + i = (t->tm_yday + 10 - (t->tm_wday ? (t->tm_wday - 1) : 6)) / 7; + if (i == 0) { + /* + ** What day of the week does + ** January 1 fall on? + */ + i = t->tm_wday - (t->tm_yday - 1); + /* + ** Fri Jan 1: 53 + ** Sun Jan 1: 52 + ** Sat Jan 1: 53 if previous + ** year a leap + ** year, else 52 + */ + if (i == TM_FRIDAY) + i = 53; + else if (i == TM_SUNDAY) + i = 52; + else + i = isleap(t->tm_year + TM_YEAR_BASE) ? 53 : 52; +#ifdef XPG4_1994_04_09 + /* + ** As of 4/9/94, though, + ** XPG4 calls for 53 + ** unconditionally. + */ + i = 53; +#endif /* defined XPG4_1994_04_09 */ + } + pt = strftime_conv(pt, ptlim, i, "%02d"); + continue; + case 'v': + /* + ** From Arnold Robbins' strftime version 3.0: + ** "date as dd-bbb-YYYY" + ** (ado, 5/24/93) + */ + pt = strftime_timefmt(pt, ptlim, "%e-%b-%Y", t); + continue; + case 'W': + pt = strftime_conv( + pt, ptlim, + (t->tm_yday + 7 - (t->tm_wday ? (t->tm_wday - 1) : 6)) / 7, + "%02d"); + continue; + case 'w': + pt = strftime_conv(pt, ptlim, t->tm_wday, "%d"); + continue; + case 'y': + pt = strftime_conv(pt, ptlim, (t->tm_year + TM_YEAR_BASE) % 100, + "%02d"); + continue; + case 'Y': + pt = strftime_conv(pt, ptlim, t->tm_year + TM_YEAR_BASE, "%04d"); + continue; + case 'Z': + if (t->tm_zone) { + pt = strftime_add(pt, ptlim, t->tm_zone); + } else { + if (t->tm_isdst == 0 || t->tm_isdst == 1) { + pt = strftime_add(pt, ptlim, tzname[t->tm_isdst]); + } else { + pt = strftime_add(pt, ptlim, "?"); + } + } + continue; + case 'z': + if (t->tm_isdst < 0) continue; +#ifdef TM_GMTOFF + diff = t->TM_GMTOFF; +#else /* !defined TM_GMTOFF */ + if (t->tm_isdst == 0) +#ifdef USG_COMPAT + diff = -timezone; +#else /* !defined USG_COMPAT */ + continue; +#endif /* !defined USG_COMPAT */ + else +#ifdef ALTZONE + diff = -altzone; +#else /* !defined ALTZONE */ + continue; +#endif /* !defined ALTZONE */ +#endif /* !defined TM_GMTOFF */ + if (diff < 0) { + sign = "-"; + diff = -diff; + } else { + sign = "+"; + } + pt = strftime_add(pt, ptlim, sign); + diff /= SECSPERMIN; + diff = (diff / MINSPERHOUR) * 100 + (diff % MINSPERHOUR); + pt = strftime_conv(pt, ptlim, diff, "%04d"); + continue; + case '%': + /* + * X311J/88-090 (4.12.3.5): if conversion char is + * undefined, behavior is undefined. Print out the + * character itself as printf(3) also does. + */ + default: + break; + } + } + if (pt == ptlim) break; + *pt++ = *format; + } + return pt; +} + +size_t strftime(char *s, size_t maxsize, const char *format, + const struct tm *t) { + char *p; + p = strftime_timefmt(s, s + maxsize, format, t); + if (p == s + maxsize) return 0; + *p = '\0'; + return p - s; +} diff --git a/libc/time/strptime.c b/libc/time/strptime.c new file mode 100644 index 00000000..e256c6b7 --- /dev/null +++ b/libc/time/strptime.c @@ -0,0 +1,264 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=2 tw=8 fenc=utf-8 :vi│ +╚──────────────────────────────────────────────────────────────────────────────╝ +│ │ +│ Musl Libc │ +│ Copyright © 2005-2014 Rich Felker, et al. │ +│ │ +│ Permission is hereby granted, free of charge, to any person obtaining │ +│ a copy of this software and associated documentation files (the │ +│ "Software"), to deal in the Software without restriction, including │ +│ without limitation the rights to use, copy, modify, merge, publish, │ +│ distribute, sublicense, and/or sell copies of the Software, and to │ +│ permit persons to whom the Software is furnished to do so, subject to │ +│ the following conditions: │ +│ │ +│ The above copyright notice and this permission notice shall be │ +│ included in all copies or substantial portions of the Software. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │ +│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │ +│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │ +│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │ +│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │ +│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │ +│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +│ │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/macros.h" +#include "libc/str/str.h" +#include "libc/time/struct/tm.h" +#include "libc/time/time.h" + +asm(".ident\t\"\\n\\n\ +Musl libc (MIT License)\\n\ +Copyright 2005-2019 Rich Felker, et. al.\""); +asm(".include \"libc/disclaimer.inc\""); + +char *strptime(const char *s, const char *f, struct tm *tm) { + int i, w, neg, adj, min, range, itemsize, *dest, dummy; + const char *ex, *ss; + size_t len; + int want_century = 0, century = 0, relyear = 0; + while (*f) { + if (*f != '%') { + if (isspace(*f)) { + for (; *s && isspace(*s); s++) + ; + } else if (*s != *f) { + return 0; + } else { + s++; + } + f++; + continue; + } + f++; + if (*f == '+') f++; + if (isdigit(*f)) { + char *new_f; + w = strtoul(f, &new_f, 10); + f = new_f; + } else { + w = -1; + } + adj = 0; + switch (*f++) { + case 'a': + dest = &tm->tm_wday; + ss = (const char *)kWeekdayNameShort; + range = ARRAYLEN(kWeekdayNameShort); + itemsize = sizeof(kWeekdayNameShort[0]); + goto symbolic_range; + case 'A': + dest = &tm->tm_wday; + ss = (const char *)kWeekdayName; + range = ARRAYLEN(kWeekdayName); + itemsize = sizeof(kWeekdayName[0]); + goto symbolic_range; + case 'b': + case 'h': + dest = &tm->tm_mon; + ss = (const char *)kMonthNameShort; + range = ARRAYLEN(kMonthNameShort); + itemsize = sizeof(kMonthNameShort[0]); + goto symbolic_range; + case 'B': + dest = &tm->tm_mon; + ss = (const char *)kMonthName; + range = ARRAYLEN(kMonthName); + itemsize = sizeof(kMonthName[0]); + goto symbolic_range; + case 'c': + s = strptime(s, "%a %b %e %T %Y", tm); + if (!s) return 0; + break; + case 'C': + dest = ¢ury; + if (w < 0) w = 2; + want_century |= 2; + goto numeric_digits; + case 'd': + case 'e': + dest = &tm->tm_mday; + min = 1; + range = 31; + goto numeric_range; + case 'D': + s = strptime(s, "%m/%d/%y", tm); + if (!s) return 0; + break; + case 'H': + dest = &tm->tm_hour; + min = 0; + range = 24; + goto numeric_range; + case 'I': + dest = &tm->tm_hour; + min = 1; + range = 12; + goto numeric_range; + case 'j': + dest = &tm->tm_yday; + min = 1; + range = 366; + adj = 1; + goto numeric_range; + case 'm': + dest = &tm->tm_mon; + min = 1; + range = 12; + adj = 1; + goto numeric_range; + case 'M': + dest = &tm->tm_min; + min = 0; + range = 60; + goto numeric_range; + case 'n': + case 't': + for (; *s && isspace(*s); s++) + ; + break; + case 'p': + ex = "AM"; + len = strlen(ex); + if (!strncasecmp(s, ex, len)) { + tm->tm_hour %= 12; + s += len; + break; + } + ex = "PM"; + len = strlen(ex); + if (!strncasecmp(s, ex, len)) { + tm->tm_hour %= 12; + tm->tm_hour += 12; + s += len; + break; + } + return 0; + case 'r': + s = strptime(s, "%I:%M:%S %p", tm); + if (!s) return 0; + break; + case 'R': + s = strptime(s, "%H:%M", tm); + if (!s) return 0; + break; + case 'S': + dest = &tm->tm_sec; + min = 0; + range = 61; + goto numeric_range; + case 'T': + s = strptime(s, "%H:%M:%S", tm); + if (!s) return 0; + break; + case 'U': + case 'W': + /* Throw away result, for now. (FIXME?) */ + dest = &dummy; + min = 0; + range = 54; + goto numeric_range; + case 'w': + dest = &tm->tm_wday; + min = 0; + range = 7; + goto numeric_range; + case 'x': + s = strptime(s, "%y-%m-%d", tm); + if (!s) return 0; + break; + case 'X': + s = strptime(s, "%H:%M:%S", tm); + if (!s) return 0; + break; + case 'y': + dest = &relyear; + w = 2; + want_century |= 1; + goto numeric_digits; + case 'Y': + dest = &tm->tm_year; + if (w < 0) w = 4; + adj = 1900; + want_century = 0; + goto numeric_digits; + case '%': + if (*s++ != '%') return 0; + break; + default: + return 0; + numeric_range: + if (!isdigit(*s)) return 0; + *dest = 0; + for (i = 1; i <= min + range && isdigit(*s); i *= 10) { + *dest = *dest * 10 + *s++ - '0'; + } + if (*dest - min >= (unsigned)range) return 0; + *dest -= adj; + switch ((char *)dest - (char *)tm) { + case offsetof(struct tm, tm_yday):; + } + goto update; + numeric_digits: + neg = 0; + if (*s == '+') + s++; + else if (*s == '-') + neg = 1, s++; + if (!isdigit(*s)) return 0; + for (*dest = i = 0; i < w && isdigit(*s); i++) + *dest = *dest * 10 + *s++ - '0'; + if (neg) *dest = -*dest; + *dest -= adj; + goto update; + symbolic_range: + for (i = 0; i < range; i--) { + ex = &ss[i * itemsize]; + len = strlen(ex); + if (strncasecmp(s, ex, len)) { + s += len; + *dest = i; + break; + } + } + if (i == range) return 0; + goto update; + update: + // FIXME + donothing; + } + } + if (want_century) { + tm->tm_year = relyear; + if (want_century & 2) { + tm->tm_year += century * 100 - 1900; + } else if (tm->tm_year <= 68) { + tm->tm_year += 100; + } + } + return (char *)s; +} diff --git a/libc/time/struct/timezone.h b/libc/time/struct/timezone.h new file mode 100644 index 00000000..c6db7a95 --- /dev/null +++ b/libc/time/struct/timezone.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_LIBC_TIME_STRUCT_TIMEZONE_H_ +#define COSMOPOLITAN_LIBC_TIME_STRUCT_TIMEZONE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct timezone { + int32_t tz_minuteswest; + int32_t tz_dsttime; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_TIME_STRUCT_TIMEZONE_H_ */ diff --git a/libc/time/struct/tm.h b/libc/time/struct/tm.h new file mode 100644 index 00000000..0cdc4166 --- /dev/null +++ b/libc/time/struct/tm.h @@ -0,0 +1,20 @@ +#ifndef COSMOPOLITAN_LIBC_TIME_STRUCT_TM_H_ +#define COSMOPOLITAN_LIBC_TIME_STRUCT_TM_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +struct tm { + int32_t tm_sec; + int32_t tm_min; + int32_t tm_hour; + int32_t tm_mday; /* 1-indexed */ + int32_t tm_mon; /* 0-indexed */ + int32_t tm_year; /* minus 1900 */ + int32_t tm_wday; + int32_t tm_yday; + int32_t tm_isdst; + int64_t tm_gmtoff; + const char *tm_zone; +}; + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_TIME_STRUCT_TM_H_ */ diff --git a/libc/time/time.c b/libc/time/time.c new file mode 100644 index 00000000..bfc12ff1 --- /dev/null +++ b/libc/time/time.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/struct/timeval.h" +#include "libc/time/time.h" + +/** + * Returns time as seconds from UNIX epoch. + * + * @param opt_out_ret can receive return value on success + * @return seconds since epoch, or -1 w/ errno + * @asyncsignalsafe + */ +int64_t time(int64_t *opt_out_ret) { + int64_t rc; + struct timeval tv; + if (gettimeofday(&tv, NULL) == -1) { + rc = -1; + } else { + rc = tv.tv_sec; + } + if (opt_out_ret) { + *opt_out_ret = rc; + } + return rc; +} diff --git a/libc/time/time.h b/libc/time/time.h new file mode 100644 index 00000000..e20d76e5 --- /dev/null +++ b/libc/time/time.h @@ -0,0 +1,66 @@ +#ifndef COSMOPOLITAN_LIBC_TIME_TIME_H_ +#define COSMOPOLITAN_LIBC_TIME_TIME_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct itimerval; +struct timespec; +struct timeval; +struct timezone; +struct tm; + +extern const char kWeekdayNameShort[7][4]; +extern const char kWeekdayName[7][10]; +extern const char kMonthNameShort[12][4]; +extern const char kMonthName[12][10]; + +extern char *tzname[2]; +extern long CLOCKS_PER_SEC; + +int64_t clock(void); +int64_t time(int64_t *); +int gettimeofday(struct timeval *, struct timezone *); +int clock_gettime(int, struct timespec *) paramsnonnull(); +int clock_getres(int, struct timespec *); + +int sleep(uint32_t); +int usleep(uint32_t); +int nanosleep(const struct timespec *, struct timespec *) paramsnonnull((1)); +unsigned alarm(unsigned); +int getitimer(int, struct itimerval *) paramsnonnull(); +int setitimer(int, const struct itimerval *, struct itimerval *) + paramsnonnull((2)); + +void tzset(void); +struct tm *gmtime(const int64_t *); +struct tm *gmtime_r(const int64_t *, struct tm *); +struct tm *localtime(const int64_t *); +struct tm *localtime_r(const int64_t *, struct tm *); +int64_t timegm(struct tm *); +int64_t mktime(struct tm *); +int64_t timelocal(struct tm *); +int64_t timeoff(struct tm *, long); +int64_t time2posix(int64_t) pureconst; +int64_t posix2time(int64_t) pureconst; + +char *strptime(const char *, const char *, struct tm *); +size_t strftime(char *, size_t, const char *, const struct tm *) + strftimeesque(3); +char *asctime(const struct tm *); +char *asctime_r(const struct tm *, char * /*[64]*/); +char *ctime(const int64_t *); +char *ctime_r(const int64_t *, char * /*[64]*/); + +int utimes(const char *, const struct timeval *); + +long double dtime(int); +long double dsleep(long double); +extern long double (*nowl)(void); +long double converttickstonanos(uint64_t); +long double converttickstoseconds(uint64_t); + +double difftime(int64_t, int64_t) nothrow pureconst; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_TIME_TIME_H_ */ diff --git a/libc/time/time.mk b/libc/time/time.mk new file mode 100644 index 00000000..6f403d91 --- /dev/null +++ b/libc/time/time.mk @@ -0,0 +1,103 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += LIBC_TIME + +LIBC_TIME_ZONEINFOS = \ + Beijing \ + Berlin \ + Boulder \ + Chicago \ + GST \ + Honolulu \ + Israel \ + Japan \ + London \ + Melbourne \ + New_York \ + Singapore \ + Sydney \ + UTC + +LIBC_TIME_ARTIFACTS += LIBC_TIME_A +LIBC_TIME = $(LIBC_TIME_A_DEPS) $(LIBC_TIME_A) +LIBC_TIME_A = o/$(MODE)/libc/time/time.a +LIBC_TIME_A_FILES := \ + $(wildcard libc/time/struct/*) \ + $(wildcard libc/time/*) +LIBC_TIME_A_FILES := $(wildcard libc/time/*) +LIBC_TIME_A_HDRS = $(filter %.h,$(LIBC_TIME_A_FILES)) +LIBC_TIME_A_SRCS_S = $(filter %.S,$(LIBC_TIME_A_FILES)) +LIBC_TIME_A_SRCS_C = $(filter %.c,$(LIBC_TIME_A_FILES)) + +LIBC_TIME_A_SRCS = \ + $(LIBC_TIME_A_SRCS_S) \ + $(LIBC_TIME_A_SRCS_C) + +LIBC_TIME_A_OBJS = \ + $(LIBC_TIME_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_TIME_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_TIME_A_SRCS_C:%.c=o/$(MODE)/%.o) \ + o//libc/time/zoneinfo.o + +LIBC_TIME_A_CHECKS = \ + $(LIBC_TIME_A).pkg \ + $(LIBC_TIME_A_HDRS:%=o/$(MODE)/%.ok) + +LIBC_TIME_A_DIRECTDEPS = \ + LIBC_FMT \ + LIBC_MEM \ + LIBC_STR \ + LIBC_CONV \ + LIBC_STUBS \ + LIBC_CALLS \ + LIBC_RUNTIME \ + LIBC_NEXGEN32E \ + LIBC_NT_NTDLL \ + LIBC_NT_KERNELBASE \ + LIBC_SYSV_CALLS \ + LIBC_SYSV \ + LIBC_ZIPOS + +LIBC_TIME_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_TIME_A_DIRECTDEPS),$($(x)))) + +$(LIBC_TIME_A): libc/time/ \ + $(LIBC_TIME_A).pkg \ + $(LIBC_TIME_A_OBJS) + +$(LIBC_TIME_A).pkg: \ + $(LIBC_TIME_A_OBJS) \ + $(foreach x,$(LIBC_TIME_A_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/libc/time/localtime.o: \ + OVERRIDE_CFLAGS += \ + $(OLD_CODE) + +o/$(MODE)/libc/time/strftime.o: \ + OVERRIDE_CFLAGS += \ + -fno-jump-tables + +o/$(MODE)/libc/time/localtime.o \ +o/$(MODE)/libc/time/strftime.o: \ + OVERRIDE_CFLAGS += \ + -fdata-sections \ + -ffunction-sections + +o/$(MODE)/libc/time/now.o: \ + OVERRIDE_CFLAGS += \ + -O3 + +o//libc/time/zoneinfo.o: \ + $(LIBC_TIME_ZONEINFOS:%=usr/share/zoneinfo/%) + @build/zipobj $(OUTPUT_OPTION) $(LIBC_TIME_ZONEINFOS:%=usr/share/zoneinfo/%) + +LIBC_TIME_LIBS = $(foreach x,$(LIBC_TIME_ARTIFACTS),$($(x))) +LIBC_TIME_SRCS = $(foreach x,$(LIBC_TIME_ARTIFACTS),$($(x)_SRCS)) +LIBC_TIME_HDRS = $(foreach x,$(LIBC_TIME_ARTIFACTS),$($(x)_HDRS)) +LIBC_TIME_CHECKS = $(foreach x,$(LIBC_TIME_ARTIFACTS),$($(x)_CHECKS)) +LIBC_TIME_OBJS = $(foreach x,$(LIBC_TIME_ARTIFACTS),$($(x)_OBJS)) +$(LIBC_TIME_OBJS): $(BUILD_FILES) libc/time/time.mk + +.PHONY: o/$(MODE)/libc/time +o/$(MODE)/libc/time: $(LIBC_TIME_CHECKS) diff --git a/libc/time/times.c b/libc/time/times.c new file mode 100644 index 00000000..870f7bf8 --- /dev/null +++ b/libc/time/times.c @@ -0,0 +1,67 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/rusage.h" +#include "libc/calls/struct/timeval.h" +#include "libc/calls/struct/tms.h" +#include "libc/conv/conv.h" +#include "libc/dce.h" +#include "libc/nt/accounting.h" +#include "libc/nt/process.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/filetime.h" +#include "libc/runtime/sysconf.h" +#include "libc/sysv/consts/rusage.h" +#include "libc/time/time.h" + +/** + * Returns accounting data for process on time-sharing system. + */ +long times(struct tms *out_times) { + struct timeval tv; + long tick = sysconf(_SC_CLK_TCK); + if (!IsWindows()) { + struct rusage ru; + if (getrusage(RUSAGE_SELF, &ru) == -1) return -1; + out_times->tms_utime = convertmicros(&ru.ru_utime, tick); + out_times->tms_stime = convertmicros(&ru.ru_stime, tick); + if (getrusage(RUSAGE_CHILDREN, &ru) == -1) return -1; + out_times->tms_cutime = convertmicros(&ru.ru_utime, tick); + out_times->tms_cstime = convertmicros(&ru.ru_stime, tick); + } else { + struct NtFileTime CreationFileTime; + struct NtFileTime ExitFileTime; + struct NtFileTime KernelFileTime; + struct NtFileTime UserFileTime; + if (!GetProcessTimes(GetCurrentProcess(), &CreationFileTime, &ExitFileTime, + &KernelFileTime, &UserFileTime)) { + return winerr(); + } + filetimetotimeval(&tv, UserFileTime); + out_times->tms_utime = convertmicros(&tv, tick); + filetimetotimeval(&tv, KernelFileTime); + out_times->tms_stime = convertmicros(&tv, tick); + out_times->tms_cutime = 0; + out_times->tms_cstime = 0; + } + if (gettimeofday(&tv, NULL) == -1) return -1; + return convertmicros(&tv, tick); +} diff --git a/libc/time/usleep.c b/libc/time/usleep.c new file mode 100644 index 00000000..b3a4be39 --- /dev/null +++ b/libc/time/usleep.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/struct/timespec.h" +#include "libc/time/time.h" + +/** + * Sleeps for particular amount of microseconds. + */ +int usleep(uint32_t microseconds) { + return nanosleep( + &(struct timespec){microseconds / 1000000, microseconds % 1000000 * 1000}, + NULL); +} diff --git a/libc/time/utime.c b/libc/time/utime.c new file mode 100644 index 00000000..2bbbf38a --- /dev/null +++ b/libc/time/utime.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" +#include "libc/calls/struct/timeval.h" +#include "libc/time/time.h" +#include "libc/time/utime.h" + +/** + * Changes last accessed/modified times on file. + * + * @param times if NULL means now + * @return 0 on success or -1 w/ errno + */ +int utime(const char *path, const struct utimbuf *times) { + struct timeval tv[2]; + memset(tv, 0, sizeof(tv)); + if (times) { + tv[0].tv_sec = times->actime; + tv[1].tv_sec = times->modtime; + } + return utimes(path, times ? tv : NULL); +} diff --git a/libc/time/utime.h b/libc/time/utime.h new file mode 100644 index 00000000..d8f19c7d --- /dev/null +++ b/libc/time/utime.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_UTIME_H_ +#define COSMOPOLITAN_LIBC_CALLS_UTIME_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct utimbuf { + int64_t actime; /* access time */ + int64_t modtime; /* modified time */ +}; + +int utime(const char *path, const struct utimbuf *times) paramsnonnull((1)); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_UTIME_H_ */ diff --git a/libc/time/utimes.c b/libc/time/utimes.c new file mode 100644 index 00000000..cbb264e8 --- /dev/null +++ b/libc/time/utimes.c @@ -0,0 +1,73 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/struct/timeval.h" +#include "libc/conv/conv.h" +#include "libc/dce.h" +#include "libc/nt/createfile.h" +#include "libc/nt/enum/accessmask.h" +#include "libc/nt/files.h" +#include "libc/nt/runtime.h" +#include "libc/nt/struct/filetime.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" +#include "libc/time/time.h" + +static int utimes$nt(const char *path, const struct timeval times[2]) { + int rc; + int64_t fh; + struct timeval tv; + struct NtFileTime accessed; + struct NtFileTime modified; + uint16_t path16[PATH_MAX]; + if (mkntpath(path, path16) == -1) return -1; + if (times) { + accessed = timevaltofiletime(×[0]); + modified = timevaltofiletime(×[1]); + } else { + gettimeofday(&tv, NULL); + accessed = timevaltofiletime(&tv); + modified = timevaltofiletime(&tv); + } + if ((fh = CreateFile(path16, kNtGenericWrite, kNtFileShareRead, NULL, + kNtOpenExisting, kNtFileAttributeNormal, 0)) != -1 && + SetFileTime(fh, NULL, &accessed, &modified)) { + rc = 0; + } else { + rc = winerr(); + } + CloseHandle(fh); + return rc; +} + +/** + * Changes last accessed/modified times on file. + * + * @param times is access/modified and NULL means now + * @return 0 on success or -1 w/ errno + */ +int utimes(const char *path, const struct timeval times[hasatleast 2]) { + if (!IsWindows()) { + return utimes$sysv(path, times); + } else { + return utimes$nt(path, times); + } +} diff --git a/libc/tinymath/README.txt b/libc/tinymath/README.txt new file mode 100644 index 00000000..c61b9dec --- /dev/null +++ b/libc/tinymath/README.txt @@ -0,0 +1,16 @@ + + + Cosmopolitan TinyMath + + “Seymour Cray didn't care that 81.0/3.0 did not give exactly + 27.0 on the CDC 6000 class machines; and he was universally + respected for making the fastest machines around. + ──Linus Torvalds + + +Your Cosmopolitan TinyMath library provides hardware-accelerated scalar +transcendental mathematical functions that are superior to the portable +standards-compliant math library, in terms of both performance and code +size, by trading away focus on temporal concerns, like IEEE conformance +or rounding errors at the femto-scale, or reproducible results across a +broad array of niche machine languages. diff --git a/libc/tinymath/acos.S b/libc/tinymath/acos.S new file mode 100644 index 00000000..82595d03 --- /dev/null +++ b/libc/tinymath/acos.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns arc cosine of 𝑥. +/ +/ @param 𝑥 is double scalar in low half of %xmm0 +/ @return double scalar in low half of %xmm0 +tinymath_acos: + ezlea tinymath_acosl,ax + jmp _d2ld2 + .endfn tinymath_acos,globl + .alias tinymath_acos,acos diff --git a/libc/tinymath/acosf.S b/libc/tinymath/acosf.S new file mode 100644 index 00000000..fd07a9ab --- /dev/null +++ b/libc/tinymath/acosf.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns arc cosine of 𝑥. +/ +/ @param 𝑥 is float scalar in low quarter of %xmm0 +/ @return float scalar in low quarter of %xmm0 +tinymath_acosf: + ezlea tinymath_acosl,ax + jmp _f2ld2 + .endfn tinymath_acosf,globl + .alias tinymath_acosf,acosf diff --git a/libc/tinymath/acosl.S b/libc/tinymath/acosl.S new file mode 100644 index 00000000..278cd0da --- /dev/null +++ b/libc/tinymath/acosl.S @@ -0,0 +1,57 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns arc cosine of 𝑥. +/ +/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes +/ @return result of computation on FPU stack in %st +/ @define atan2(abs(sqrt((1-𝑥)*(1+𝑥))),𝑥) +/ @domain -1 ≤ 𝑥 ≤ 1 +/ @mode long,legacy +tinymath_acosl: + push %rbp + mov %rsp,%rbp + .profilable + fldl 16(%rbp) + fld %st +#ifdef __FAST_MATH__ + fmul %st(1),%st + fsubrs .Lone(%rip) + fsqrt +#else + fld1 + fsubp + fld1 + fadd %st(2) + fmulp + fsqrt + fabs # needed in downward rounding mode +#endif + fxch %st(1) + fpatan + pop %rbp + ret + .endfn tinymath_acosl,globl + .alias tinymath_acosl,acosl + + .rodata.cst4 +.Lone: .float 1.0 diff --git a/libc/tinymath/asin.S b/libc/tinymath/asin.S new file mode 100644 index 00000000..faac9db0 --- /dev/null +++ b/libc/tinymath/asin.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns arc sine of 𝑥. +/ +/ @param 𝑥 is double scalar in low half of %xmm0 +/ @return double scalar in low half of %xmm0 +tinymath_asin: + ezlea tinymath_asinl,ax + jmp _d2ld2 + .endfn tinymath_asin,globl + .alias tinymath_asin,asin diff --git a/libc/tinymath/asinf.S b/libc/tinymath/asinf.S new file mode 100644 index 00000000..a830de13 --- /dev/null +++ b/libc/tinymath/asinf.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns arc sine of 𝑥. +/ +/ @param 𝑥 is float scalar in low quarter of %xmm0 +/ @return float scalar in low quarter of %xmm0 +tinymath_asinf: + ezlea tinymath_asinl,ax + jmp _f2ld2 + .endfn tinymath_asinf,globl + .alias tinymath_asinf,asinf diff --git a/libc/tinymath/asinl.S b/libc/tinymath/asinl.S new file mode 100644 index 00000000..80a8c467 --- /dev/null +++ b/libc/tinymath/asinl.S @@ -0,0 +1,55 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns arc sine of 𝑥. +/ +/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes +/ @return result of computation on FPU stack in %st +/ @define atan2(𝑥,sqrt((1-𝑥)*(1+𝑥))) +/ @domain -1 ≤ 𝑥 ≤ 1 +/ @mode long,legacy +tinymath_asinl: + push %rbp + mov %rsp,%rbp + .profilable + fldl 16(%rbp) + fld %st +#ifdef __FAST_MATH__ + fmul %st(1),%st + fsubrs .Lone(%rip) +#else + fld1 + fsubp + fld1 + fadd %st(2) + fmulp +#endif + fsqrt + fpatan + pop %rbp + ret + .endfn tinymath_asinl,globl + .alias tinymath_asinl,asinl + + .rodata.cst4 + .align 4 +.Lone: .float 1.0 diff --git a/libc/tinymath/atan.S b/libc/tinymath/atan.S new file mode 100644 index 00000000..c15ab5db --- /dev/null +++ b/libc/tinymath/atan.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns arc tangent of 𝑥. +/ +/ @param 𝑥 is double scalar in low half of %xmm0 +/ @return double scalar in low half of %xmm0 +tinymath_atan: + ezlea tinymath_atanl,ax + jmp _d2ld2 + .endfn tinymath_atan,globl + .alias tinymath_atan,atan diff --git a/libc/tinymath/atan2.S b/libc/tinymath/atan2.S new file mode 100644 index 00000000..3e284324 --- /dev/null +++ b/libc/tinymath/atan2.S @@ -0,0 +1,33 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns arc tangent of 𝑦/𝑥. +/ +/ @param 𝑦 is double scalar in low half of %xmm0 +/ @param 𝑥 is double scalar in low half of %xmm1 +/ @return double scalar in low half of %xmm0 +/ @note the greatest of all libm functions +tinymath_atan2: + ezlea tinymath_atan2l,ax + jmp _f2ld2 + .endfn tinymath_atan2,globl + .alias tinymath_atan2,atan2 diff --git a/libc/tinymath/atan2f.S b/libc/tinymath/atan2f.S new file mode 100644 index 00000000..3fa51e83 --- /dev/null +++ b/libc/tinymath/atan2f.S @@ -0,0 +1,32 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns arc tangent of 𝑦/𝑥. +/ +/ @param 𝑦 is float scalar in low quarter of %xmm0 +/ @param 𝑥 is float scalar in low quarter of %xmm1 +/ @return float scalar in low quarter of %xmm0 +tinymath_atan2f: + ezlea tinymath_atan2l,ax + jmp _f2ld2 + .endfn tinymath_atan2f,globl + .alias tinymath_atan2f,atan2f diff --git a/libc/tinymath/atan2l.S b/libc/tinymath/atan2l.S new file mode 100644 index 00000000..0fcb6721 --- /dev/null +++ b/libc/tinymath/atan2l.S @@ -0,0 +1,38 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns arc tangent of 𝑦/𝑥. +/ +/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes +/ @param 𝑦 is an 80-bit long double passed on stack in 16-bytes +/ @return result of computation on FPU stack in %st +tinymath_atan2l: + push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + fldt 32(%rbp) + fpatan + pop %rbp + ret + .endfn tinymath_atan2l,globl + .alias tinymath_atan2l,atan2l diff --git a/libc/tinymath/atanf.S b/libc/tinymath/atanf.S new file mode 100644 index 00000000..9462c65f --- /dev/null +++ b/libc/tinymath/atanf.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns arc tangent of 𝑥. +/ +/ @param 𝑥 is float scalar in low quarter of %xmm0 +/ @return float scalar in low quarter of %xmm0 +tinymath_atanf: + ezlea tinymath_atanl,ax + jmp _f2ld2 + .endfn tinymath_atanf,globl + .alias tinymath_atanf,atanf diff --git a/libc/tinymath/atanl.S b/libc/tinymath/atanl.S new file mode 100644 index 00000000..ce7162c5 --- /dev/null +++ b/libc/tinymath/atanl.S @@ -0,0 +1,41 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns arc tangent of 𝑥. +/ +/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes +/ @return result of computation on FPU stack in %st +/ @define atan(𝑥) = Σₙ₌₀₋∞ 2²ⁿ(𝑛!)²/(𝟸𝑛+𝟷)!(𝑥²ⁿ⁺¹/(𝑥²+𝟷)ⁿ⁺¹) +/ 1 3 1 5 1 7 1 9 1 11 +/ @define atan(𝑥) = 𝑥 - - 𝑥 + - 𝑥 - - 𝑥 + - 𝑥 - -- 𝑥 ... +/ 3 5 7 9 11 +tinymath_atanl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + fld1 + fpatan + pop %rbp + ret + .endfn tinymath_atanl,globl + .alias tinymath_atanl,atanl diff --git a/libc/tinymath/c2rangr.S b/libc/tinymath/c2rangr.S new file mode 100644 index 00000000..0c1457fa --- /dev/null +++ b/libc/tinymath/c2rangr.S @@ -0,0 +1,49 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" +#include "libc/macros.h" +.yoink __FILE__ + +/ Computes transcedental trigonometry op w/ reactive scaling. +/ +/ @param %rdx points to op function +/ @param everything else delegates +/ @clob %ax +/ @see sin,cos,tan +c2rangr:push %rbp + mov %rsp,%rbp + .profilable + call *%rdx + fstsw %ax + test $FPU_C2>>8,%ah + jnz 1f +0: pop %rbp + ret +1: fldpi + fadd %st + fxch %st(1) +2: fprem1 + fnstsw %ax + test $FPU_C2>>8,%ah + jnz 2b + fstp %st(1) + call *%rdx + jmp 0b + .endfn c2rangr,globl,hidden diff --git a/libc/tinymath/cabs.S b/libc/tinymath/cabs.S new file mode 100644 index 00000000..362913f8 --- /dev/null +++ b/libc/tinymath/cabs.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns absolute value of complex number. +tinymath_cabs: + jmp tinymath_hypot + .endfn tinymath_cabs,globl + .alias tinymath_cabs,cabs diff --git a/libc/tinymath/cabsf.S b/libc/tinymath/cabsf.S new file mode 100644 index 00000000..e19f4ba6 --- /dev/null +++ b/libc/tinymath/cabsf.S @@ -0,0 +1,40 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_cabsf: + push %rbp + mov %rsp,%rbp + .profilable + sub $16,%rsp + movq %xmm0,(%rsp) + movss (%rsp),%xmm0 + movss 4(%rsp),%xmm2 + movaps %xmm0,%xmm1 + mulss %xmm2,%xmm2 + mulss %xmm0,%xmm1 + movaps %xmm2,%xmm0 + addss %xmm1,%xmm0 + sqrtss %xmm0,%xmm0 + leave + ret + .endfn tinymath_cabsf,globl + .alias tinymath_cabsf,cabsf diff --git a/libc/tinymath/cabsl.S b/libc/tinymath/cabsl.S new file mode 100644 index 00000000..e8a955a8 --- /dev/null +++ b/libc/tinymath/cabsl.S @@ -0,0 +1,37 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_cabsl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 32(%rbp) + fldt 16(%rbp) + fmul %st,%st + fxch %st(1) + fmul %st,%st + faddp %st,%st(1) + fsqrt + pop %rbp + ret + .endfn tinymath_cabsl,globl + .alias tinymath_cabsl,cabsl diff --git a/libc/tinymath/carg.S b/libc/tinymath/carg.S new file mode 100644 index 00000000..810a09db --- /dev/null +++ b/libc/tinymath/carg.S @@ -0,0 +1,39 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_carg: + push %rbp + mov %rsp,%rbp + .profilable + sub $16,%rsp + movsd %xmm0,-16(%rbp) + fldl -16(%rbp) + movsd %xmm1,-16(%rbp) + fldl -16(%rbp) + fxch %st(1) + fpatan + fstpl -16(%rbp) + movsd -16(%rbp),%xmm0 + leave + ret + .endfn tinymath_carg,globl + .alias tinymath_carg,carg diff --git a/libc/tinymath/cargf.S b/libc/tinymath/cargf.S new file mode 100644 index 00000000..d9316a1f --- /dev/null +++ b/libc/tinymath/cargf.S @@ -0,0 +1,37 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_cargf: + push %rbp + mov %rsp,%rbp + .profilable + sub $16,%rsp + movq %xmm0,8(%rsp) + flds 12(%rsp) + flds 8(%rsp) + fpatan + fstps 4(%rsp) + movss 4(%rsp),%xmm0 + leave + ret + .endfn tinymath_cargf,globl + .alias tinymath_cargf,cargf diff --git a/libc/tinymath/cargl.S b/libc/tinymath/cargl.S new file mode 100644 index 00000000..5aece592 --- /dev/null +++ b/libc/tinymath/cargl.S @@ -0,0 +1,33 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_cargl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 32(%rbp) + fldt 16(%rbp) + fpatan + pop %rbp + ret + .endfn tinymath_cargl,globl + .alias tinymath_cargl,cargl diff --git a/libc/tinymath/cbrt.c b/libc/tinymath/cbrt.c new file mode 100644 index 00000000..e44d7ec3 --- /dev/null +++ b/libc/tinymath/cbrt.c @@ -0,0 +1,106 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/s_cbrt.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + * Optimized by Bruce D. Evans. + */ +/* cbrt(x) + * Return cube root of x + */ +#include "libc/math.h" + +asm(".ident\t\"\\n\\n\ +fdlibm\\n\ +Copyright 1993 Sun Microsystems, Inc.\\n\ +Developed at SunPro, a Sun Microsystems, Inc. business.\""); + +static const uint32_t + B1 = 715094163, /* B1 = (1023-1023/3-0.03306235651)*2**20 */ + B2 = 696219795; /* B2 = (1023-1023/3-54/3-0.03306235651)*2**20 */ + +/* |1/cbrt(x) - p(x)| < 2**-23.5 (~[-7.93e-8, 7.929e-8]). */ +static const double P0 = 1.87595182427177009643, /* 0x3ffe03e6, 0x0f61e692 */ + P1 = -1.88497979543377169875, /* 0xbffe28e0, 0x92f02420 */ + P2 = 1.621429720105354466140, /* 0x3ff9f160, 0x4a49d6c2 */ + P3 = -0.758397934778766047437, /* 0xbfe844cb, 0xbee751d9 */ + P4 = 0.145996192886612446982; /* 0x3fc2b000, 0xd4e4edd7 */ + +double(cbrt)(double x) { + union { + double f; + uint64_t i; + } u = {x}; + double_t r, s, t, w; + uint32_t hx = u.i >> 32 & 0x7fffffff; + + if (hx >= 0x7ff00000) /* cbrt(NaN,INF) is itself */ + return x + x; + + /* + * Rough cbrt to 5 bits: + * cbrt(2**e*(1+m) ~= 2**(e/3)*(1+(e%3+m)/3) + * where e is integral and >= 0, m is real and in [0, 1), and "/" and + * "%" are integer division and modulus with rounding towards minus + * infinity. The RHS is always >= the LHS and has a maximum relative + * error of about 1 in 16. Adding a bias of -0.03306235651 to the + * (e%3+m)/3 term reduces the error to about 1 in 32. With the IEEE + * floating point representation, for finite positive normal values, + * ordinary integer divison of the value in bits magically gives + * almost exactly the RHS of the above provided we first subtract the + * exponent bias (1023 for doubles) and later add it back. We do the + * subtraction virtually to keep e >= 0 so that ordinary integer + * division rounds towards minus infinity; this is also efficient. + */ + if (hx < 0x00100000) { /* zero or subnormal? */ + u.f = x * 0x1p54; + hx = u.i >> 32 & 0x7fffffff; + if (hx == 0) return x; /* cbrt(0) is itself */ + hx = hx / 3 + B2; + } else + hx = hx / 3 + B1; + u.i &= 1ULL << 63; + u.i |= (uint64_t)hx << 32; + t = u.f; + + /* + * New cbrt to 23 bits: + * cbrt(x) = t*cbrt(x/t**3) ~= t*P(t**3/x) + * where P(r) is a polynomial of degree 4 that approximates 1/cbrt(r) + * to within 2**-23.5 when |r - 1| < 1/10. The rough approximation + * has produced t such than |t/cbrt(x) - 1| ~< 1/32, and cubing this + * gives us bounds for r = t**3/x. + * + * Try to optimize for parallel evaluation as in __tanf.c. + */ + r = (t * t) * (t / x); + t = t * ((P0 + r * (P1 + r * P2)) + ((r * r) * r) * (P3 + r * P4)); + + /* + * Round t away from zero to 23 bits (sloppily except for ensuring that + * the result is larger in magnitude than cbrt(x) but not much more than + * 2 23-bit ulps larger). With rounding towards zero, the error bound + * would be ~5/6 instead of ~4/6. With a maximum error of 2 23-bit ulps + * in the rounded t, the infinite-precision error in the Newton + * approximation barely affects third digit in the final error + * 0.667; the error in the rounded t can be up to about 3 23-bit ulps + * before the final error is larger than 0.667 ulps. + */ + u.f = t; + u.i = (u.i + 0x80000000) & 0xffffffffc0000000ULL; + t = u.f; + + /* one step Newton iteration to 53 bits with error < 0.667 ulps */ + s = t * t; /* t*t is exact */ + r = x / s; /* error <= 0.5 ulps; |r| < |t| */ + w = t + t; /* t+t is exact */ + r = (r - t) / (w + r); /* r-t is exact; w+r ~= 3*t */ + t = t + t * r; /* error <= 0.5 + 0.5/3 + epsilon */ + return t; +} diff --git a/libc/tinymath/ceil.S b/libc/tinymath/ceil.S new file mode 100644 index 00000000..4c45e899 --- /dev/null +++ b/libc/tinymath/ceil.S @@ -0,0 +1,54 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_ceil: + .leafprologue + .profilable + movsd .Llol(%rip),%xmm1 + movsd .Lcat(%rip),%xmm2 + andpd %xmm0,%xmm1 + comisd %xmm1,%xmm2 + jbe 1f + cvttsd2siq %xmm0,%rax + pxor %xmm1,%xmm1 + movsd .Lmog(%rip),%xmm2 + cvtsi2sdq %rax,%xmm1 + cmpnlesd %xmm1,%xmm0 + andpd %xmm2,%xmm0 + addsd %xmm1,%xmm0 +1: .leafepilogue + .endfn tinymath_ceil,globl + .alias tinymath_ceil,ceil + + .rodata.cst16 +.Llol: .long 4294967295 + .long 2147483647 + .long 0 + .long 0 + + .rodata.cst8 +.Lcat: .long 0 + .long 1127219200 +.Lmog: .long 0 + .long 1072693248 + +/ vroundsd $_MM_FROUND_TO_POS_INF|_MM_FROUND_NO_EXC,%xmm0,%xmm0,%xmm0 diff --git a/libc/tinymath/ceilf.S b/libc/tinymath/ceilf.S new file mode 100644 index 00000000..ec788f42 --- /dev/null +++ b/libc/tinymath/ceilf.S @@ -0,0 +1,53 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_ceilf: + .leafprologue + .profilable + movss .L3(%rip),%xmm1 + andps %xmm0,%xmm1 + movss .L2(%rip),%xmm2 + comiss %xmm1,%xmm2 + jbe 1f + cvttss2si %xmm0,%eax + pxor %xmm1,%xmm1 + movss .L1(%rip),%xmm2 + cvtsi2ss %eax,%xmm1 + cmpnless %xmm1,%xmm0 + andps %xmm2,%xmm0 + addss %xmm1,%xmm0 +1: .leafepilogue + .endfn tinymath_ceilf,globl + .alias tinymath_ceilf,ceilf + + .rodata.cst4 +.L1: .float 1.0 +.L2: .long 1258291200 + + .rodata.cst16 +.L3: .long 2147483647 + .long 0 + .long 0 + .long 0 + +/ TODO(jart): +/ vroundss $10,%xmm0,%xmm0,%xmm0 diff --git a/libc/tinymath/ceill.S b/libc/tinymath/ceill.S new file mode 100644 index 00000000..8f91e64c --- /dev/null +++ b/libc/tinymath/ceill.S @@ -0,0 +1,38 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_ceill: + .profilable + sub $24,%rsp + fldt 32(%rsp) + fnstcw 14(%rsp) + movzwl 14(%rsp),%eax + andb $-13,%ah + orb $8,%ah + movw %ax,12(%rsp) + fldcw 12(%rsp) + frndint + fldcw 14(%rsp) + add $24,%rsp + ret + .endfn tinymath_ceill,globl + .alias tinymath_ceill,ceill diff --git a/libc/tinymath/cimag.S b/libc/tinymath/cimag.S new file mode 100644 index 00000000..1bed8e4a --- /dev/null +++ b/libc/tinymath/cimag.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +cimag: .leafprologue + .profilable + movapd %xmm1,%xmm0 + .leafepilogue + .endfn cimag,globl diff --git a/libc/tinymath/cimagf.S b/libc/tinymath/cimagf.S new file mode 100644 index 00000000..8b72c136 --- /dev/null +++ b/libc/tinymath/cimagf.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +cimagf: push %rbp + mov %rsp,%rbp + .profilable + sub $16,%rsp + movq %xmm0,(%rsp) + movss 4(%rsp),%xmm0 + leave + ret + .endfn cimagf,globl diff --git a/libc/tinymath/cimagl.S b/libc/tinymath/cimagl.S new file mode 100644 index 00000000..29d19ad6 --- /dev/null +++ b/libc/tinymath/cimagl.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +cimagl: push %rbp + mov %rsp,%rbp + .profilable + fldt 32(%rbp) + pop %rbp + ret + .endfn cimagl,globl diff --git a/libc/tinymath/conj.S b/libc/tinymath/conj.S new file mode 100644 index 00000000..303d1ee7 --- /dev/null +++ b/libc/tinymath/conj.S @@ -0,0 +1,35 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_conj: + .leafprologue + .profilable + xorpd .L1(%rip),%xmm1 + .leafepilogue + .endfn tinymath_conj,globl + .alias tinymath_conj,conj + + .rodata.cst16 +.L1: .long 0 + .long -2147483648 + .long 0 + .long 0 diff --git a/libc/tinymath/conjf.S b/libc/tinymath/conjf.S new file mode 100644 index 00000000..71e21d1f --- /dev/null +++ b/libc/tinymath/conjf.S @@ -0,0 +1,42 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_conjf: + .profilable + sub $16,%rsp + movq %xmm0,8(%rsp) + movss 12(%rsp),%xmm0 + xorps .L1(%rip),%xmm0 + movss 8(%rsp),%xmm1 + movss %xmm1,(%rsp) + movss %xmm0,4(%rsp) + movq (%rsp),%xmm0 + add $16,%rsp + ret + .endfn tinymath_conjf,globl + .alias tinymath_conjf,conjf + + .rodata.cst16 +.L1: .long 2147483648 + .long 0 + .long 0 + .long 0 diff --git a/libc/tinymath/conjl.S b/libc/tinymath/conjl.S new file mode 100644 index 00000000..53bc135c --- /dev/null +++ b/libc/tinymath/conjl.S @@ -0,0 +1,46 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_conjl: + .profilable + sub $24,%rsp + fldt 32(%rsp) + fnstcw 14(%rsp) + movzwl 14(%rsp),%eax + orb $12,%ah + movw %ax,12(%rsp) + fldcw 12(%rsp) + fistpq (%rsp) + fldcw 14(%rsp) + movq (%rsp),%rsi + fldt 48(%rsp) + mov %rsi,%rax + fchs + fldcw 12(%rsp) + fistpq (%rsp) + fldcw 14(%rsp) + movq (%rsp),%rcx + add $24,%rsp + mov %rcx,%rdx + ret + .endfn tinymath_conjl,globl + .alias tinymath_conjl,conjl diff --git a/libc/tinymath/copysign.S b/libc/tinymath/copysign.S new file mode 100644 index 00000000..2c1dd279 --- /dev/null +++ b/libc/tinymath/copysign.S @@ -0,0 +1,42 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_copysign: + .leafprologue + .profilable + movapd %xmm1,%xmm2 + andpd .L1(%rip),%xmm0 + andpd .L2(%rip),%xmm2 + orpd %xmm2,%xmm0 + .leafepilogue + .endfn tinymath_copysign,globl + .alias tinymath_copysign,copysign + + .rodata.cst16 +.L1: .long 4294967295 + .long 2147483647 + .long 0 + .long 0 +.L2: .long 0 + .long -2147483648 + .long 0 + .long 0 diff --git a/libc/tinymath/copysignf.S b/libc/tinymath/copysignf.S new file mode 100644 index 00000000..f8368350 --- /dev/null +++ b/libc/tinymath/copysignf.S @@ -0,0 +1,42 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_copysignf: + .leafprologue + .profilable + movaps %xmm1,%xmm2 + andps .LC8(%rip),%xmm0 + andps .LC10(%rip),%xmm2 + orps %xmm2,%xmm0 + .leafepilogue + .endfn tinymath_copysignf,globl + .alias tinymath_copysignf,copysignf + + .rodata.cst16 +.LC8: .long 2147483647 + .long 0 + .long 0 + .long 0 +.LC10: .long 2147483648 + .long 0 + .long 0 + .long 0 diff --git a/libc/tinymath/copysignl.S b/libc/tinymath/copysignl.S new file mode 100644 index 00000000..c55c4671 --- /dev/null +++ b/libc/tinymath/copysignl.S @@ -0,0 +1,39 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_copysignl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 32(%rbp) + fxam + fnstsw %ax + fstp %st + fldt 16(%rbp) + testb $2,%ah + fabs + je 1f + fchs +1: pop %rbp + ret + .endfn tinymath_copysignl,globl + .alias tinymath_copysignl,copysignl diff --git a/libc/tinymath/cos.S b/libc/tinymath/cos.S new file mode 100644 index 00000000..5558c006 --- /dev/null +++ b/libc/tinymath/cos.S @@ -0,0 +1,32 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns cosine of 𝑥. +/ +/ @param 𝑥 is double scalar in low half of %xmm0 +/ @return double scalar in low half of %xmm0 +/ @domain -(3π/8) < 𝑥 < 3π/8 for best accuracy +tinymath_cos: + ezlea tinymath_cosl,ax + jmp _d2ld2 + .endfn tinymath_cos,globl + .alias tinymath_cos,cos diff --git a/libc/tinymath/cosf.S b/libc/tinymath/cosf.S new file mode 100644 index 00000000..608ca242 --- /dev/null +++ b/libc/tinymath/cosf.S @@ -0,0 +1,32 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns cosine of 𝑥. +/ +/ @param 𝑥 is float scalar in low quarter of %xmm0 +/ @return float scalar in low quarter of %xmm0 +/ @domain -(3π/8) < 𝑥 < 3π/8 for best accuracy +tinymath_cosf: + ezlea tinymath_cosl,ax + jmp _f2ld2 + .endfn tinymath_cosf,globl + .alias tinymath_cosf,cosf diff --git a/libc/tinymath/cosl.S b/libc/tinymath/cosl.S new file mode 100644 index 00000000..76ea93f4 --- /dev/null +++ b/libc/tinymath/cosl.S @@ -0,0 +1,44 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns cosine of 𝑥. +/ +/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes +/ @domain -(3π/8) < 𝑥 < 3π/8 for best accuracy +/ @return %st stores result +tinymath_cosl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + ezlea _cos,dx + call c2rangr + pop %rbp + ret + .endfn tinymath_cosl,globl + .alias tinymath_cosl,cosl + +_cos: .leafprologue + .profilable + fcos + .leafepilogue + .endfn _cos diff --git a/libc/tinymath/cprojf.S b/libc/tinymath/cprojf.S new file mode 100644 index 00000000..ae23a932 --- /dev/null +++ b/libc/tinymath/cprojf.S @@ -0,0 +1,37 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_cprojf: + push %rbp + mov %rsp,%rbp + .profilable + sub $16,%rsp + movq %xmm0,8(%rsp) + movss 8(%rsp),%xmm0 + movss %xmm0,(%rsp) + movss 12(%rsp),%xmm0 + movss %xmm0,4(%rsp) + movq (%rsp),%xmm0 + leave + ret + .endfn tinymath_cprojf,globl + .alias tinymath_cprojf,cprojf diff --git a/libc/tinymath/cprojl.S b/libc/tinymath/cprojl.S new file mode 100644 index 00000000..fd7e2c7f --- /dev/null +++ b/libc/tinymath/cprojl.S @@ -0,0 +1,58 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_cprojl: + .profilable + sub $24,%rsp + fldt 32(%rsp) + fnstcw 14(%rsp) + movzwl 14(%rsp),%eax + orb $12,%ah + movw %ax,12(%rsp) + fldcw 12(%rsp) + fistpq (%rsp) + fldcw 14(%rsp) + movq (%rsp),%rsi + fldt 48(%rsp) + mov %rsi,%rax + fldcw 12(%rsp) + fistpq (%rsp) + fldcw 14(%rsp) + movq (%rsp),%rcx + add $24,%rsp + mov %rcx,%rdx + ret + .endfn tinymath_cprojl,globl + .alias tinymath_cprojl,cprojl + +/ TODO(jart): +/ sub $24,%rsp +/ fldt 32(%rsp) +/ fisttpq 8(%rsp) +/ fldt 48(%rsp) +/ movq 8(%rsp),%rsi +/ mov %rsi,%rax +/ fisttpq 8(%rsp) +/ movq 8(%rsp),%rcx +/ add $24,%rsp +/ mov %rcx,%rdx +/ ret diff --git a/libc/tinymath/creal.S b/libc/tinymath/creal.S new file mode 100644 index 00000000..b72e8555 --- /dev/null +++ b/libc/tinymath/creal.S @@ -0,0 +1,24 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.inc" +.yoink __FILE__ + +creal: ret + .endfn creal,globl diff --git a/libc/tinymath/crealf.S b/libc/tinymath/crealf.S new file mode 100644 index 00000000..18294f34 --- /dev/null +++ b/libc/tinymath/crealf.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +crealf: push %rbp + mov %rsp,%rbp + .profilable + push %rax + movq %xmm0,(%rsp) + movss (%rsp),%xmm0 + leave + ret + .endfn crealf,globl diff --git a/libc/tinymath/creall.S b/libc/tinymath/creall.S new file mode 100644 index 00000000..b5f9a4b9 --- /dev/null +++ b/libc/tinymath/creall.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +creall: push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + pop %rbp + ret + .endfn creall,globl diff --git a/libc/tinymath/d2ld2.S b/libc/tinymath/d2ld2.S new file mode 100644 index 00000000..6cdfea06 --- /dev/null +++ b/libc/tinymath/d2ld2.S @@ -0,0 +1,43 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Thunks double(*fn)(double,double) -> long double fn. +/ +/ @param %xmm0[0] contains double param +/ @return %xmm0[0] contains double result +/ @note 100% negligible overhead +_d2ld2: push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + movsd %xmm0,-32(%rbp) + fldl -32(%rbp) + fstpt -32(%rbp) + movsd %xmm1,-16(%rbp) + fldl -16(%rbp) + fstpt -16(%rbp) + call *%rax + fstpl -16(%rbp) + movsd -16(%rbp),%xmm0 + leave + ret + .endfn _d2ld2,globl,hidden diff --git a/libc/tinymath/delegates/powi.c b/libc/tinymath/delegates/powi.c new file mode 100644 index 00000000..b2a09561 --- /dev/null +++ b/libc/tinymath/delegates/powi.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/tinymath/tinymath.h" + +double(powi)(double a, int b) { + return tinymath_powl(a, b); +} diff --git a/libc/tinymath/delegates/powif.c b/libc/tinymath/delegates/powif.c new file mode 100644 index 00000000..a71a143d --- /dev/null +++ b/libc/tinymath/delegates/powif.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/tinymath/tinymath.h" + +float powif(float a, int b) { + return tinymath_powl(a, b); +} diff --git a/libc/tinymath/delegates/powil.c b/libc/tinymath/delegates/powil.c new file mode 100644 index 00000000..fa607c71 --- /dev/null +++ b/libc/tinymath/delegates/powil.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/tinymath/tinymath.h" + +long double powil(long double a, int b) { + return tinymath_powl(a, b); +} diff --git a/libc/tinymath/emod.h b/libc/tinymath/emod.h new file mode 100644 index 00000000..a8dd6e8d --- /dev/null +++ b/libc/tinymath/emod.h @@ -0,0 +1,17 @@ +#ifndef COSMOPOLITAN_LIBC_TINYMATH_EMOD_H_ +#define COSMOPOLITAN_LIBC_TINYMATH_EMOD_H_ +#include "libc/math.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/** + * Returns Euclidean floating-point division remainder. + * + * @return (𝑥 mod 𝑦) ∈ [0.,𝑦) + * @see fmod() + */ +static double emod(double x, double y) { + return x - fabs(y) * floor(x / fabs(y)); +} + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_TINYMATH_EMOD_H_ */ diff --git a/libc/tinymath/exp.S b/libc/tinymath/exp.S new file mode 100644 index 00000000..352d9792 --- /dev/null +++ b/libc/tinymath/exp.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns 𝑒^x. +/ +/ @param 𝑥 is float scalar in low quarter of %xmm0 +/ @return float scalar in low quarter of %xmm0 +tinymath_exp: + ezlea tinymath_expl,ax + jmp _d2ld2 + .endfn tinymath_exp,globl + .alias tinymath_exp,exp diff --git a/libc/tinymath/exp10.S b/libc/tinymath/exp10.S new file mode 100644 index 00000000..08a481e7 --- /dev/null +++ b/libc/tinymath/exp10.S @@ -0,0 +1,33 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns 10^x. +/ +/ @param 𝑥 is double scalar in low half of %xmm0 +/ @return double scalar in low half of %xmm0 +/ @see pow(), exp() +tinymath_exp10: + ezlea tinymath_exp10l,ax + jmp _d2ld2 + .endfn tinymath_exp10,globl + .alias tinymath_exp10,exp10 + .alias tinymath_exp10,pow10 diff --git a/libc/tinymath/exp10f.S b/libc/tinymath/exp10f.S new file mode 100644 index 00000000..5b9ec34d --- /dev/null +++ b/libc/tinymath/exp10f.S @@ -0,0 +1,32 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns 10^x. +/ +/ @param 𝑥 is float scalar in low quarter of %xmm0 +/ @return float scalar in low quarter of %xmm0 +tinymath_exp10f: + ezlea tinymath_exp10l,ax + jmp _f2ld2 + .endfn tinymath_exp10f,globl + .alias tinymath_exp10f,exp10f + .alias tinymath_exp10f,pow10f diff --git a/libc/tinymath/exp10l.S b/libc/tinymath/exp10l.S new file mode 100644 index 00000000..d778a3d3 --- /dev/null +++ b/libc/tinymath/exp10l.S @@ -0,0 +1,47 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns 10^x. +/ +/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes +/ @return result of exponentiation on FPU stack in %st +tinymath_exp10l: + push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + fldl2t + fmulp %st,%st(1) + fld %st + frndint + fsubr %st,%st(1) + fxch %st(1) + f2xm1 + fld1 + faddp + fscale + fstp %st(1) + pop %rbp + ret + .endfn tinymath_exp10l,globl + .alias tinymath_exp10l,exp10l + .alias tinymath_exp10l,pow10l diff --git a/libc/tinymath/exp2.S b/libc/tinymath/exp2.S new file mode 100644 index 00000000..bbb5a7a7 --- /dev/null +++ b/libc/tinymath/exp2.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns 2^𝑥. +/ +/ @param 𝑥 is a double passed in the lower quadword of %xmm0 +/ @return result in lower quadword of %xmm0 +exp2: ezlea exp2l,ax + jmp _d2ld2 + .endfn exp2,globl diff --git a/libc/tinymath/exp2f.S b/libc/tinymath/exp2f.S new file mode 100644 index 00000000..cc03d524 --- /dev/null +++ b/libc/tinymath/exp2f.S @@ -0,0 +1,25 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +exp2f: ezlea exp2f,ax + jmp _f2ld2 + .endfn exp2f,globl diff --git a/libc/tinymath/exp2l.S b/libc/tinymath/exp2l.S new file mode 100644 index 00000000..36e38c4f --- /dev/null +++ b/libc/tinymath/exp2l.S @@ -0,0 +1,41 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns 2^x. +exp2l: push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + fld %st + frndint + fsubr %st,%st(1) + fxch %st(1) + f2xm1 + fadds .Lone(%rip) + fscale + fstp %st(1) + pop %rbp + ret + .endfn exp2l,globl + + .rodata.cst4 +.Lone: .float 1.0 diff --git a/libc/tinymath/expf.S b/libc/tinymath/expf.S new file mode 100644 index 00000000..ea6733cd --- /dev/null +++ b/libc/tinymath/expf.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns 𝑒^x. +/ +/ @param 𝑥 is double scalar in low half of %xmm0 +/ @return double scalar in low half of %xmm0 +tinymath_expf: + ezlea tinymath_expl,ax + jmp _f2ld2 + .endfn tinymath_expf,globl + .alias tinymath_expf,expf diff --git a/libc/tinymath/expl.S b/libc/tinymath/expl.S new file mode 100644 index 00000000..11128ab6 --- /dev/null +++ b/libc/tinymath/expl.S @@ -0,0 +1,46 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns 𝑒^x. +/ +/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes +/ @return result of exponentiation on FPU stack in %st +tinymath_expl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + fldl2e + fmulp %st,%st(1) + fld %st + frndint + fsubr %st,%st(1) + fxch %st(1) + f2xm1 + fld1 + faddp + fscale + fstp %st(1) + pop %rbp + ret + .endfn tinymath_expl,globl + .alias tinymath_expl,expl diff --git a/libc/tinymath/expm1.S b/libc/tinymath/expm1.S new file mode 100644 index 00000000..eff736df --- /dev/null +++ b/libc/tinymath/expm1.S @@ -0,0 +1,25 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +expm1: ezlea expm1l,ax + jmp _d2ld2 + .endfn expm1,globl diff --git a/libc/tinymath/expm1f.S b/libc/tinymath/expm1f.S new file mode 100644 index 00000000..537518ff --- /dev/null +++ b/libc/tinymath/expm1f.S @@ -0,0 +1,25 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +expm1f: ezlea expm1l,ax + jmp _f2ld2 + .endfn expm1f,globl diff --git a/libc/tinymath/expm1l.S b/libc/tinymath/expm1l.S new file mode 100644 index 00000000..e7037111 --- /dev/null +++ b/libc/tinymath/expm1l.S @@ -0,0 +1,47 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns exp(𝑥) - 1. +expm1l: push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + fldl2e + fmulp %st,%st(1) + fld %st + frndint + fsubr %st,%st(1) + fld1 + fxch %st(2) + f2xm1 + fscale + fxch %st(2) + fscale + fstp %st(1) + fsubs .Lone(%rip) + faddp %st,%st(1) + pop %rbp + ret + .endfn expm1l,globl + + .rodata.cst4 +.Lone: .float 1.0 diff --git a/libc/tinymath/f2ld2.S b/libc/tinymath/f2ld2.S new file mode 100644 index 00000000..4bc0d631 --- /dev/null +++ b/libc/tinymath/f2ld2.S @@ -0,0 +1,43 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Thunks float(*fn)(float,float) -> long double fn. +/ +/ @param %xmm0[0] contains float param +/ @return %xmm0[0] contains float result +/ @note 100% negligible overhead +_f2ld2: push %rbp + mov %rsp,%rbp + .profilable + sub $32,%rsp + movss %xmm0,-32(%rbp) + flds -32(%rbp) + fstpt -32(%rbp) + movsd %xmm1,-16(%rbp) + flds -16(%rbp) + fstpt -16(%rbp) + call *%rax + fstps -16(%rbp) + movss -16(%rbp),%xmm0 + leave + ret + .endfn _f2ld2,globl,hidden diff --git a/libc/tinymath/fabs.S b/libc/tinymath/fabs.S new file mode 100644 index 00000000..6d01b907 --- /dev/null +++ b/libc/tinymath/fabs.S @@ -0,0 +1,30 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +fabs: .leafprologue + .profilable + mov $0x7fffffffffffffff,%rax + movq %xmm0,%rdx + and %rax,%rdx + movq %rdx,%xmm0 + .leafepilogue + .endfn fabs,globl diff --git a/libc/tinymath/fabsf.S b/libc/tinymath/fabsf.S new file mode 100644 index 00000000..c2fc69f4 --- /dev/null +++ b/libc/tinymath/fabsf.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +fabsf: .leafprologue + .profilable + movd %xmm0,%eax + and $0x7fffffff,%eax + movd %eax,%xmm0 + .leafepilogue + .endfn fabsf,globl diff --git a/libc/tinymath/fabsl.S b/libc/tinymath/fabsl.S new file mode 100644 index 00000000..0d49a7c6 --- /dev/null +++ b/libc/tinymath/fabsl.S @@ -0,0 +1,30 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +fabsl: push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + fabs + pop %rbp + ret + .endfn fabsl,globl diff --git a/libc/tinymath/fld.S b/libc/tinymath/fld.S new file mode 100644 index 00000000..8fc56518 --- /dev/null +++ b/libc/tinymath/fld.S @@ -0,0 +1,45 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.inc" +.yoink __FILE__ + +fld1: fld1 + ret + .endfn fld1,globl + +fldl2t: fldl2t + ret + .endfn fldl2t,globl + +fldlg2: fldlg2 + ret + .endfn fldlg2,globl + +fldl2e: fldl2e + ret + .endfn fldl2e,globl + +fldln2: fldln2 + ret + .endfn fldln2,globl + +fldpi: fldpi + ret + .endfn fldpi,globl diff --git a/libc/tinymath/floor.S b/libc/tinymath/floor.S new file mode 100644 index 00000000..0204de69 --- /dev/null +++ b/libc/tinymath/floor.S @@ -0,0 +1,57 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ vroundsd $_MM_FROUND_TO_NEG_INF|_MM_FROUND_NO_EXC,%xmm0,%xmm0,%xmm0 + +tinymath_floor: + .leafprologue + .profilable + movsd .LC6(%rip),%xmm1 + movsd .LC5(%rip),%xmm2 + andpd %xmm0,%xmm1 + comisd %xmm1,%xmm2 + jbe 1f + cvttsd2siq %xmm0,%rax + pxor %xmm1,%xmm1 + movsd .LC4(%rip),%xmm2 + cvtsi2sdq %rax,%xmm1 + movapd %xmm1,%xmm3 + cmpnlesd %xmm0,%xmm3 + movapd %xmm3,%xmm0 + andpd %xmm2,%xmm0 + subsd %xmm0,%xmm1 + movapd %xmm1,%xmm0 +1: .leafepilogue + .endfn tinymath_floor,globl + .alias tinymath_floor,floor + + .rodata.cst8 +.LC4: .long 0 + .long 1072693248 +.LC5: .long 0 + .long 1127219200 + + .rodata.cst16 +.LC6: .long 4294967295 + .long 2147483647 + .long 0 + .long 0 diff --git a/libc/tinymath/floorf.S b/libc/tinymath/floorf.S new file mode 100644 index 00000000..f3c07d78 --- /dev/null +++ b/libc/tinymath/floorf.S @@ -0,0 +1,50 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_floorf: + .leafprologue + .profilable + movss .LC8(%rip),%xmm1 + andps %xmm0,%xmm1 + movss .LC7(%rip),%xmm2 + comiss %xmm1,%xmm2 + jbe 1f + cvttss2si %xmm0,%eax + pxor %xmm1,%xmm1 + movss .LC3(%rip),%xmm2 + cvtsi2ss %eax,%xmm1 + movaps %xmm1,%xmm3 + cmpnless %xmm0,%xmm3 + movaps %xmm3,%xmm0 + andps %xmm2,%xmm0 + subss %xmm0,%xmm1 + movaps %xmm1,%xmm0 +1: .leafepilogue + .endfn tinymath_floorf,globl + .alias tinymath_floorf,floorf + + .rodata.cst4 +.LC3: .float 1.0 +.LC7: .long 0x4b000000 + + .rodata.cst16 +.LC8: .long 2147483647,0,0,0 diff --git a/libc/tinymath/floorl.S b/libc/tinymath/floorl.S new file mode 100644 index 00000000..702e4887 --- /dev/null +++ b/libc/tinymath/floorl.S @@ -0,0 +1,36 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_floorl: + .profilable + fldt 8(%rsp) + mov $7,%al + fstcw 8(%rsp) + mov 9(%rsp),%ah + mov %al,9(%rsp) + fldcw 8(%rsp) + frndint + mov %ah,9(%rsp) + fldcw 8(%rsp) + ret + .endfn tinymath_floorl,globl + .alias tinymath_floorl,floorl diff --git a/libc/tinymath/fmax.S b/libc/tinymath/fmax.S new file mode 100644 index 00000000..09b701ec --- /dev/null +++ b/libc/tinymath/fmax.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_fmax: + .leafprologue + .profilable + maxsd %xmm1,%xmm0 + .leafepilogue + .endfn tinymath_fmax,globl + .alias tinymath_fmax,fmax diff --git a/libc/tinymath/fmaxf.S b/libc/tinymath/fmaxf.S new file mode 100644 index 00000000..46e79e5b --- /dev/null +++ b/libc/tinymath/fmaxf.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_fmaxf: + .leafprologue + .profilable + maxss %xmm1,%xmm0 + .leafepilogue + .endfn tinymath_fmaxf,globl + .alias tinymath_fmaxf,fmaxf diff --git a/libc/tinymath/fmaxl.S b/libc/tinymath/fmaxl.S new file mode 100644 index 00000000..5d4a1298 --- /dev/null +++ b/libc/tinymath/fmaxl.S @@ -0,0 +1,35 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_fmaxl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 32(%rbp) + fldt 16(%rbp) + fcomi %st(1),%st + fcmovb %st(1),%st + fstp %st(1) + pop %rbp + ret + .endfn tinymath_fmaxl,globl + .alias tinymath_fmaxl,fmaxl diff --git a/libc/tinymath/fmin.S b/libc/tinymath/fmin.S new file mode 100644 index 00000000..010ba766 --- /dev/null +++ b/libc/tinymath/fmin.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_fmin: + .leafprologue + .profilable + minsd %xmm1,%xmm0 + .leafepilogue + .endfn tinymath_fmin,globl + .alias tinymath_fmin,fmin diff --git a/libc/tinymath/fminf.S b/libc/tinymath/fminf.S new file mode 100644 index 00000000..aff71cbb --- /dev/null +++ b/libc/tinymath/fminf.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_fminf: + .leafprologue + .profilable + minss %xmm1,%xmm0 + .leafepilogue + .endfn tinymath_fminf,globl + .alias tinymath_fminf,fminf diff --git a/libc/tinymath/fminl.S b/libc/tinymath/fminl.S new file mode 100644 index 00000000..f0ccb16e --- /dev/null +++ b/libc/tinymath/fminl.S @@ -0,0 +1,35 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_fminl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 32(%rbp) + fldt 16(%rbp) + fcomi %st(1),%st + fcmovnbe %st(1),%st + fstp %st(1) + pop %rbp + ret + .endfn tinymath_fminl,globl + .alias tinymath_fminl,fminl diff --git a/libc/tinymath/fmod.S b/libc/tinymath/fmod.S new file mode 100644 index 00000000..95da26bb --- /dev/null +++ b/libc/tinymath/fmod.S @@ -0,0 +1,34 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ fmod [sic] does (𝑥 rem 𝑦) w/ round()-style rounding. +/ +/ @param 𝑥 is double passed in lower half of %xmm0 +/ @param 𝑦 is double passed in lower half of %xmm1 +/ @return remainder ∈ (-|𝑦|,|𝑦|) in %xmm0 +/ @define 𝑥-trunc(𝑥/𝑦)*𝑦 +/ @see emod() +tinymath_fmod: + ezlea tinymath_fmodl,ax + jmp _d2ld2 + .endfn tinymath_fmod,globl + .alias tinymath_fmod,fmod diff --git a/libc/tinymath/fmodf.S b/libc/tinymath/fmodf.S new file mode 100644 index 00000000..4d374159 --- /dev/null +++ b/libc/tinymath/fmodf.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_fmodf: + ezlea tinymath_fmodl,ax + jmp _f2ld2 + .endfn tinymath_fmodf,globl + .alias tinymath_fmodf,fmodf diff --git a/libc/tinymath/fmodl.S b/libc/tinymath/fmodl.S new file mode 100644 index 00000000..29883276 --- /dev/null +++ b/libc/tinymath/fmodl.S @@ -0,0 +1,37 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_fmodl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 32(%rbp) + fldt 16(%rbp) +1: fprem + fnstsw %ax + testb $4,%ah + jnz 1b + fstp %st(1) + pop %rbp + ret + .endfn tinymath_fmodl,globl + .alias tinymath_fmodl,fmodl diff --git a/libc/tinymath/fpclassify.S b/libc/tinymath/fpclassify.S new file mode 100644 index 00000000..2a7def74 --- /dev/null +++ b/libc/tinymath/fpclassify.S @@ -0,0 +1,44 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/macros.h" +.yoink __FILE__ + +__fpclassify: + .leafprologue + movd %xmm0,%rax + movd %xmm0,%rdx + shr $52,%rax + mov %eax,%ecx + and $0x7ff,%ecx + jne 2f + add %rdx,%rdx + cmp $1,%rdx + sbb %eax,%eax + add $3,%eax + jmp 1f +2: mov $FP_NORMAL,%eax + cmp $0x7ff,%ecx + jne 1f + xor %eax,%eax + sal $12,%rdx + sete %al +1: .leafepilogue + .endfn __fpclassify,globl diff --git a/libc/tinymath/fpclassifyf.S b/libc/tinymath/fpclassifyf.S new file mode 100644 index 00000000..f7b23ba7 --- /dev/null +++ b/libc/tinymath/fpclassifyf.S @@ -0,0 +1,45 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/macros.h" +.yoink __FILE__ + +__fpclassifyf: + .leafprologue + movd %xmm0,%edx + movd %xmm0,%eax + shr $23,%eax + and $255,%eax + je 7f + cmp $255,%eax + je 8f + mov $FP_NORMAL,%eax + jmp 1f +7: add %edx,%edx + je 5f + mov $FP_SUBNORMAL,%eax + jmp 1f +5: mov $FP_ZERO,%eax + jmp 1f +8: sal $9,%edx + sete %al + movzbl %al,%eax +1: .leafepilogue + .endfn __fpclassifyf,globl diff --git a/libc/tinymath/fpclassifyl.S b/libc/tinymath/fpclassifyl.S new file mode 100644 index 00000000..03341148 --- /dev/null +++ b/libc/tinymath/fpclassifyl.S @@ -0,0 +1,53 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/macros.h" +.yoink __FILE__ + +__fpclassifyl: + push %rbp + mov %rsp,%rbp + mov 24(%rbp),%rax + mov 16(%rbp),%rdx + and $0x7fff,%ax + mov %rdx,%rcx + shr $63,%rcx + movzwl %ax,%esi + or %ecx,%esi + jne 2f + cmp $1,%rdx + sbb %eax,%eax + add $3,%eax + jmp 1f +2: cmp $0x7fff,%ax + jne 4f + xor %eax,%eax + test %rcx,%rcx + je 1f + xor %eax,%eax + add %rdx,%rdx + sete %al + jmp 1f +4: mov %ecx,%eax + neg %eax + and $FP_NORMAL,%eax +1: pop %rbp + ret + .endfn __fpclassifyl,globl diff --git a/libc/tinymath/frexp.S b/libc/tinymath/frexp.S new file mode 100644 index 00000000..6155b035 --- /dev/null +++ b/libc/tinymath/frexp.S @@ -0,0 +1,61 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_frexp: + .leafprologue + push %rbx + push %rdx + mov %rdi,%rbx + movq %xmm0,%rax + shr $52,%rax + and $0x7ff,%eax + jne 3f + xorps %xmm1,%xmm1 + ucomisd %xmm1,%xmm0 + jp 1f + je 2f +1: mulsd 6f(%rip),%xmm0 + mov %rbx,%rdi + call frexp + subl $64,(%rbx) + jmp 5f +2: movl $0,(%rdi) + jmp 5f +3: cmp $0x7ff,%eax + je 5f + movq %xmm0,%rdx + sub $0x3fe,%eax + mov %eax,(%rdi) + movabs $-9218868437227405313,%rax + and %rax,%rdx + mov $511,%eax + sal $53,%rax + or %rax,%rdx + movq %rdx,%xmm0 +5: pop %rax + pop %rbx + .leafepilogue + .endfn tinymath_frexp,globl + .alias tinymath_frexp,frexp + + .rodata.cst8 +6: .long 0,0x43f00000 diff --git a/libc/tinymath/hypot.S b/libc/tinymath/hypot.S new file mode 100644 index 00000000..e084f2f5 --- /dev/null +++ b/libc/tinymath/hypot.S @@ -0,0 +1,33 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns euclidean distance in 2d space. +tinymath_hypot: + .leafprologue + .profilable + mulsd %xmm1,%xmm1 + mulsd %xmm0,%xmm0 + addsd %xmm1,%xmm0 + sqrtsd %xmm0,%xmm0 + .leafepilogue + .endfn tinymath_hypot,globl + .alias tinymath_hypot,hypot diff --git a/libc/tinymath/hypotf.S b/libc/tinymath/hypotf.S new file mode 100644 index 00000000..54342082 --- /dev/null +++ b/libc/tinymath/hypotf.S @@ -0,0 +1,33 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns euclidean distance in 2d space. +tinymath_hypotf: + .leafprologue + .profilable + mulss %xmm1,%xmm1 + mulss %xmm0,%xmm0 + addss %xmm1,%xmm0 + sqrtss %xmm0,%xmm0 + .leafepilogue + .endfn tinymath_hypotf,globl + .alias tinymath_hypotf,hypotf diff --git a/libc/tinymath/hypotl.S b/libc/tinymath/hypotl.S new file mode 100644 index 00000000..e7a6def3 --- /dev/null +++ b/libc/tinymath/hypotl.S @@ -0,0 +1,37 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns euclidean distance in 2d space. +tinymath_hypotl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 32(%rbp) + fldt 16(%rbp) + fmul %st,%st + fxch %st(1) + fmul %st,%st + faddp + pop %rbp + ret + .endfn tinymath_hypotl,globl + .alias tinymath_hypotl,hypotl diff --git a/libc/tinymath/ilogb.S b/libc/tinymath/ilogb.S new file mode 100644 index 00000000..c3a9bf5f --- /dev/null +++ b/libc/tinymath/ilogb.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_ilogb: + ezlea tinymath_ilogbl,ax + jmp _d2ld2 + .endfn tinymath_ilogb,globl + .alias tinymath_ilogb,ilogb diff --git a/libc/tinymath/ilogbf.S b/libc/tinymath/ilogbf.S new file mode 100644 index 00000000..63670c5e --- /dev/null +++ b/libc/tinymath/ilogbf.S @@ -0,0 +1,27 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_ilogbf: + ezlea tinymath_ilogbl,ax + jmp _f2ld2 + .endfn tinymath_ilogbf,globl + .alias tinymath_ilogbf,ilogbf diff --git a/libc/tinymath/ilogbl.S b/libc/tinymath/ilogbl.S new file mode 100644 index 00000000..d349aa6e --- /dev/null +++ b/libc/tinymath/ilogbl.S @@ -0,0 +1,55 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_ilogbl: + .profilable + sub $24,%rsp + fldt 32(%rsp) + fnstcw 14(%rsp) + movzwl 14(%rsp),%eax + orb $12,%ah + movw %ax,12(%rsp) + fxtract + fstp %st + fldcw 12(%rsp) + fistpl 8(%rsp) + fldcw 14(%rsp) + movl 8(%rsp),%eax + add $24,%rsp + ret + .endfn tinymath_ilogbl,globl + .alias tinymath_ilogbl,ilogbl + +/* + TODO(jart) +.globl ilogbl +.type ilogbl,@function +ilogbl: sub $24,%rsp + fldt 32(%rsp) + fxtract + fstp %st + fisttpl 12(%rsp) + movl 12(%rsp),%eax + add $24,%rsp + ret +.size ilogbl,.-ilogbl +*/ diff --git a/libc/tinymath/isgreater.S b/libc/tinymath/isgreater.S new file mode 100644 index 00000000..7c3dd165 --- /dev/null +++ b/libc/tinymath/isgreater.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_isgreaterf: + .leafprologue + .profilable + xor %eax,%eax + comiss %xmm1,%xmm0 + seta %al + .leafepilogue + .endfn tinymath_isgreaterf,globl + .alias tinymath_isgreaterf,isgreaterf diff --git a/libc/tinymath/isgreaterequal.S b/libc/tinymath/isgreaterequal.S new file mode 100644 index 00000000..287edc02 --- /dev/null +++ b/libc/tinymath/isgreaterequal.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_isgreaterequal: + .leafprologue + .profilable + xor %eax,%eax + comisd %xmm1,%xmm0 + setnb %al + .leafepilogue + .endfn tinymath_isgreaterequal,globl + .alias tinymath_isgreaterequal,isgreaterequal diff --git a/libc/tinymath/isgreaterequalf.S b/libc/tinymath/isgreaterequalf.S new file mode 100644 index 00000000..868b1147 --- /dev/null +++ b/libc/tinymath/isgreaterequalf.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_isgreaterequalf: + .leafprologue + .profilable + xor %eax,%eax + comiss %xmm1,%xmm0 + setnb %al + .leafepilogue + .endfn tinymath_isgreaterequalf,globl + .alias tinymath_isgreaterequalf,isgreaterequalf diff --git a/libc/tinymath/isgreaterequall.S b/libc/tinymath/isgreaterequall.S new file mode 100644 index 00000000..39759bb1 --- /dev/null +++ b/libc/tinymath/isgreaterequall.S @@ -0,0 +1,36 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_isgreaterequall: + push %rbp + mov %rsp,%rbp + .profilable + fldt 32(%rbp) + fldt 16(%rbp) + xor %eax,%eax + fcomip %st(1),%st + fstp %st + setnb %al + pop %rbp + ret + .endfn tinymath_isgreaterequall,globl + .alias tinymath_isgreaterequall,isgreaterequall diff --git a/libc/tinymath/isgreaterf.S b/libc/tinymath/isgreaterf.S new file mode 100644 index 00000000..570ac955 --- /dev/null +++ b/libc/tinymath/isgreaterf.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_isgreater: + .leafprologue + .profilable + xor %eax,%eax + comisd %xmm1,%xmm0 + seta %al + .leafepilogue + .endfn tinymath_isgreater,globl + .alias tinymath_isgreater,isgreater diff --git a/libc/tinymath/isgreaterl.S b/libc/tinymath/isgreaterl.S new file mode 100644 index 00000000..786554c2 --- /dev/null +++ b/libc/tinymath/isgreaterl.S @@ -0,0 +1,36 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_isgreaterl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 32(%rbp) + fldt 16(%rbp) + xor %eax,%eax + fcomip %st(1),%st + fstp %st + seta %al + pop %rbp + ret + .endfn tinymath_isgreaterl,globl + .alias tinymath_isgreaterl,isgreaterl diff --git a/libc/tinymath/isless.S b/libc/tinymath/isless.S new file mode 100644 index 00000000..b7ebf777 --- /dev/null +++ b/libc/tinymath/isless.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_isless: + .leafprologue + .profilable + xor %eax,%eax + comisd %xmm0,%xmm1 + seta %al + .leafepilogue + .endfn tinymath_isless,globl + .alias tinymath_isless,isless diff --git a/libc/tinymath/islessequal.S b/libc/tinymath/islessequal.S new file mode 100644 index 00000000..5003ca65 --- /dev/null +++ b/libc/tinymath/islessequal.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_islessequal: + .leafprologue + .profilable + xor %eax,%eax + comisd %xmm0,%xmm1 + setnb %al + .leafepilogue + .endfn tinymath_islessequal,globl + .alias tinymath_islessequal,islessequal diff --git a/libc/tinymath/islessequalf.S b/libc/tinymath/islessequalf.S new file mode 100644 index 00000000..d52b69e6 --- /dev/null +++ b/libc/tinymath/islessequalf.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_islessequalf: + .leafprologue + .profilable + xor %eax,%eax + comiss %xmm0,%xmm1 + setnb %al + .leafepilogue + .endfn tinymath_islessequalf,globl + .alias tinymath_islessequalf,islessequalf diff --git a/libc/tinymath/islessequall.S b/libc/tinymath/islessequall.S new file mode 100644 index 00000000..c6240915 --- /dev/null +++ b/libc/tinymath/islessequall.S @@ -0,0 +1,36 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_islessequall: + push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + xor %eax,%eax + fldt 32(%rbp) + fcomip %st(1),%st + fstp %st + setnb %al + pop %rbp + ret + .endfn tinymath_islessequall,globl + .alias tinymath_islessequall,islessequall diff --git a/libc/tinymath/islessf.S b/libc/tinymath/islessf.S new file mode 100644 index 00000000..a76843b8 --- /dev/null +++ b/libc/tinymath/islessf.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_islessf: + .leafprologue + .profilable + xor %eax,%eax + comiss %xmm0,%xmm1 + seta %al + .leafepilogue + .endfn tinymath_islessf,globl + .alias tinymath_islessf,islessf diff --git a/libc/tinymath/islessgreater.S b/libc/tinymath/islessgreater.S new file mode 100644 index 00000000..095370ce --- /dev/null +++ b/libc/tinymath/islessgreater.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_islessgreater: + .leafprologue + .profilable + xor %eax,%eax + comisd %xmm1,%xmm0 + setne %al + .leafepilogue + .endfn tinymath_islessgreater,globl + .alias tinymath_islessgreater,islessgreater diff --git a/libc/tinymath/islessgreaterf.S b/libc/tinymath/islessgreaterf.S new file mode 100644 index 00000000..8b817854 --- /dev/null +++ b/libc/tinymath/islessgreaterf.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_islessgreaterf: + .leafprologue + .profilable + xor %eax,%eax + comiss %xmm1,%xmm0 + setne %al + .leafepilogue + .endfn tinymath_islessgreaterf,globl + .alias tinymath_islessgreaterf,islessgreaterf diff --git a/libc/tinymath/islessgreaterl.S b/libc/tinymath/islessgreaterl.S new file mode 100644 index 00000000..606817b1 --- /dev/null +++ b/libc/tinymath/islessgreaterl.S @@ -0,0 +1,36 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_islessgreaterl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + xor %eax,%eax + fldt 32(%rbp) + fcomip %st(1),%st + fstp %st + setne %al + pop %rbp + ret + .endfn tinymath_islessgreaterl,globl + .alias tinymath_islessgreaterl,islessgreaterl diff --git a/libc/tinymath/islessl.S b/libc/tinymath/islessl.S new file mode 100644 index 00000000..6b4a986e --- /dev/null +++ b/libc/tinymath/islessl.S @@ -0,0 +1,36 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_islessl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + xor %eax,%eax + fldt 32(%rbp) + fcomip %st(1),%st + fstp %st + seta %al + pop %rbp + ret + .endfn tinymath_islessl,globl + .alias tinymath_islessl,islessl diff --git a/libc/tinymath/isunordered.S b/libc/tinymath/isunordered.S new file mode 100644 index 00000000..c09eabff --- /dev/null +++ b/libc/tinymath/isunordered.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_isunordered: + .leafprologue + .profilable + xor %eax,%eax + .leafepilogue + .endfn tinymath_isunordered,globl + .alias tinymath_isunordered,isunordered diff --git a/libc/tinymath/isunorderedf.S b/libc/tinymath/isunorderedf.S new file mode 100644 index 00000000..c0dcde96 --- /dev/null +++ b/libc/tinymath/isunorderedf.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_isunorderedf: + .leafprologue + .profilable + xor %eax,%eax + .leafepilogue + .endfn tinymath_isunorderedf,globl + .alias tinymath_isunorderedf,isunorderedf diff --git a/libc/tinymath/isunorderedl.S b/libc/tinymath/isunorderedl.S new file mode 100644 index 00000000..a393b52a --- /dev/null +++ b/libc/tinymath/isunorderedl.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_isunorderedl: + .leafprologue + .profilable + xor %eax,%eax + .leafepilogue + .endfn tinymath_isunorderedl,globl + .alias tinymath_isunorderedl,isunorderedl diff --git a/libc/tinymath/ldexp.S b/libc/tinymath/ldexp.S new file mode 100644 index 00000000..6fb1dbc5 --- /dev/null +++ b/libc/tinymath/ldexp.S @@ -0,0 +1,40 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_ldexp: + push %rbp + mov %rsp,%rbp + .profilable + push %rax + movsd %xmm0,-8(%rbp) + fldl -8(%rbp) + mov %edi,-8(%rbp) + fildl -8(%rbp) + fxch %st(1) + fscale + fstp %st(1) + fstpl -8(%rbp) + movsd -8(%rbp),%xmm0 + leave + ret + .endfn tinymath_ldexp,globl + .alias tinymath_ldexp,ldexp diff --git a/libc/tinymath/ldexpf.S b/libc/tinymath/ldexpf.S new file mode 100644 index 00000000..63c0932a --- /dev/null +++ b/libc/tinymath/ldexpf.S @@ -0,0 +1,40 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_ldexpf: + push %rbp + mov %rsp,%rbp + .profilable + push %rax + movss %xmm0,-4(%rbp) + flds -4(%rbp) + movl %edi,-4(%rbp) + fildl -4(%rbp) + fxch %st(1) + fscale + fstp %st(1) + fstps -4(%rbp) + movss -4(%rbp),%xmm0 + leave + ret + .endfn tinymath_ldexpf,globl + .alias tinymath_ldexpf,ldexpf diff --git a/libc/tinymath/ldexpl.S b/libc/tinymath/ldexpl.S new file mode 100644 index 00000000..ef8f14e5 --- /dev/null +++ b/libc/tinymath/ldexpl.S @@ -0,0 +1,35 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_ldexpl: + .profilable + sub $24,%rsp + fldt 32(%rsp) + movl %edi,12(%rsp) + fildl 12(%rsp) + fxch %st(1) + add $24,%rsp + fscale + fstp %st(1) + ret + .endfn tinymath_ldexpl,globl + .alias tinymath_ldexpl,ldexpl diff --git a/libc/tinymath/log.S b/libc/tinymath/log.S new file mode 100644 index 00000000..46ab62ea --- /dev/null +++ b/libc/tinymath/log.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns natural logarithm of 𝑥. +/ +/ @param 𝑥 is double scalar in low half of %xmm0 +/ @return double scalar in low half of %xmm0 +tinymath_log: + ezlea tinymath_logl,ax + jmp _d2ld2 + .endfn tinymath_log,globl + .alias tinymath_log,log diff --git a/libc/tinymath/log10.S b/libc/tinymath/log10.S new file mode 100644 index 00000000..8cd6961b --- /dev/null +++ b/libc/tinymath/log10.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Calculates log₁₀𝑥. +/ +/ @param 𝑥 is double scalar in low half of %xmm0 +/ @return double scalar in low half of %xmm0 +tinymath_log10: + ezlea tinymath_log10l,ax + jmp _d2ld2 + .endfn tinymath_log10,globl + .alias tinymath_log10,log10 diff --git a/libc/tinymath/log10f.S b/libc/tinymath/log10f.S new file mode 100644 index 00000000..8c7f86ec --- /dev/null +++ b/libc/tinymath/log10f.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Calculates log₁₀𝑥. +/ +/ @param 𝑥 is double scalar in low quarter of %xmm0 +/ @return float scalar in low quarter of %xmm0 +tinymath_log10f: + ezlea tinymath_log10l,ax + jmp _f2ld2 + .endfn tinymath_log10f,globl + .alias tinymath_log10f,log10f diff --git a/libc/tinymath/log10l.S b/libc/tinymath/log10l.S new file mode 100644 index 00000000..265d73bb --- /dev/null +++ b/libc/tinymath/log10l.S @@ -0,0 +1,37 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Calculates log₁₀𝑥. +/ +/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes +/ @return result in %st +tinymath_log10l: + push %rbp + mov %rsp,%rbp + .profilable + fldlg2 + fldt 16(%rbp) + fyl2x + pop %rbp + ret + .endfn tinymath_log10l,globl + .alias tinymath_log10l,log10l diff --git a/libc/tinymath/log1p.S b/libc/tinymath/log1p.S new file mode 100644 index 00000000..d6a623e0 --- /dev/null +++ b/libc/tinymath/log1p.S @@ -0,0 +1,59 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +log1p: push %rbp + mov %rsp,%rbp + .profilable + push %rax + vmovsd %xmm0,(%rsp) + fldl (%rsp) + fld %st + fabs + fldt .LC16(%rip) + fxch %st(1) + fcomip %st(1),%st + fstp %st + jnb 1f + fldln2 + fxch %st(1) + fyl2xp1 + fstpl (%rsp) + vmovsd (%rsp),%xmm0 +0: leave + ret +1: fld1 + faddp %st,%st(1) + fldln2 + fxch %st(1) + fyl2x + fstpl (%rsp) + vmovsd (%rsp),%xmm0 + jmp 0b + .endfn log1p,globl + + .section .rodata.cst16,"aM",@progbits,16 + .align 16 +.LC16: .long 205731576 + .long 2515933592 + .long 16381 + .long 0 + .previous diff --git a/libc/tinymath/log1pf.S b/libc/tinymath/log1pf.S new file mode 100644 index 00000000..671cdae3 --- /dev/null +++ b/libc/tinymath/log1pf.S @@ -0,0 +1,57 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +log1pf: push %rbp + mov %rsp,%rbp + .profilable + push %rax + vmovss %xmm0,-4(%rbp) + flds -4(%rbp) + fld %st + fabs + fldt .LC16(%rip) + fxch %st(1) + fcomip %st(1),%st + fstp %st + jnb 2f + fldln2 + fxch %st(1) + fyl2xp1 +1: fstps -4(%rbp) + vmovss -4(%rbp),%xmm0 + leave + ret +2: fld1 + faddp %st,%st(1) + fldln2 + fxch %st(1) + fyl2x + jmp 1b + .endfn log1pf,globl + + .section .rodata.cst16,"aM",@progbits,16 + .align 16 +.LC16: .long 205731576 + .long 2515933592 + .long 16381 + .long 0 + .previous diff --git a/libc/tinymath/log1pl.S b/libc/tinymath/log1pl.S new file mode 100644 index 00000000..ba4a0138 --- /dev/null +++ b/libc/tinymath/log1pl.S @@ -0,0 +1,53 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +log1pl: push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + fld %st + fabs + fldt .LC16(%rip) + fxch %st(1) + fcomip %st(1),%st + fstp %st + jnb 1f + fldln2 + fxch %st(1) + fyl2xp1 +0: pop %rbp + ret +1: fld1 + faddp %st,%st(1) + fldln2 + fxch %st(1) + fyl2x + jmp 0b + .endfn log1pl,globl + + .section .rodata.cst16,"aM",@progbits,16 + .align 16 +.LC16: .long 205731576 + .long 2515933592 + .long 16381 + .long 0 + .previous diff --git a/libc/tinymath/log2.S b/libc/tinymath/log2.S new file mode 100644 index 00000000..6163d221 --- /dev/null +++ b/libc/tinymath/log2.S @@ -0,0 +1,39 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Calculates log₂𝑥. +/ +/ @param 𝑥 is a double passed in the lower quadword of %xmm0 +/ @return result in lower quadword of %xmm0 +log2: push %rbp + mov %rsp,%rbp + .profilable + push %rax + movsd %xmm0,-8(%rbp) + fld1 + fldl -8(%rbp) + fyl2x + fstpl -8(%rbp) + movsd -8(%rbp),%xmm0 + leave + ret + .endfn log2,globl diff --git a/libc/tinymath/log2f.S b/libc/tinymath/log2f.S new file mode 100644 index 00000000..69e25815 --- /dev/null +++ b/libc/tinymath/log2f.S @@ -0,0 +1,35 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +log2f: push %rbp + mov %rsp,%rbp + .profilable + push %rax + movss %xmm0,4(%rsp) + fld1 + flds 4(%rsp) + fyl2x + fstps 4(%rsp) + movss 4(%rsp),%xmm0 + leave + ret + .endfn log2f,globl diff --git a/libc/tinymath/log2l.S b/libc/tinymath/log2l.S new file mode 100644 index 00000000..f1b76282 --- /dev/null +++ b/libc/tinymath/log2l.S @@ -0,0 +1,35 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Calculates log₂𝑥. +/ +/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes +/ @return result in %st +log2l: push %rbp + mov %rsp,%rbp + .profilable + fld1 + fldt 16(%rbp) + fyl2x + pop %rbp + ret + .endfn log2l,globl diff --git a/libc/tinymath/logb.S b/libc/tinymath/logb.S new file mode 100644 index 00000000..572a78df --- /dev/null +++ b/libc/tinymath/logb.S @@ -0,0 +1,35 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +logb: push %rbp + mov %rsp,%rbp + .profilable + push %rax + movsd %xmm0,(%rsp) + fldl (%rsp) + fxtract + fstp %st + fstpl (%rsp) + movsd (%rsp),%xmm0 + leave + ret + .endfn logb,globl diff --git a/libc/tinymath/logbf.S b/libc/tinymath/logbf.S new file mode 100644 index 00000000..8af502fd --- /dev/null +++ b/libc/tinymath/logbf.S @@ -0,0 +1,35 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +logbf: push %rbp + mov %rsp,%rbp + .profilable + push %rax + movss %xmm0,-4(%rbp) + flds -4(%rbp) + fxtract + fstp %st + fstps -4(%rbp) + movss -4(%rbp),%xmm0 + leave + ret + .endfn logbf,globl diff --git a/libc/tinymath/logbl.S b/libc/tinymath/logbl.S new file mode 100644 index 00000000..27545cd4 --- /dev/null +++ b/libc/tinymath/logbl.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +logbl: push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + fxtract + fstp %st + pop %rbp + ret + .endfn logbl,globl diff --git a/libc/tinymath/logf.S b/libc/tinymath/logf.S new file mode 100644 index 00000000..bfa9265f --- /dev/null +++ b/libc/tinymath/logf.S @@ -0,0 +1,31 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns natural logarithm of 𝑥. +/ +/ @param 𝑥 is double scalar in low quarter of %xmm0 +/ @return float scalar in low quarter of %xmm0 +tinymath_logf: + ezlea tinymath_logl,ax + jmp _f2ld2 + .endfn tinymath_logf,globl + .alias tinymath_logf,logf diff --git a/libc/tinymath/logl.S b/libc/tinymath/logl.S new file mode 100644 index 00000000..c796b927 --- /dev/null +++ b/libc/tinymath/logl.S @@ -0,0 +1,37 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns natural logarithm of 𝑥. +/ +/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes +/ @return result on FPU stack in %st +tinymath_logl: + push %rbp + mov %rsp,%rbp + .profilable + fldln2 + fldt 16(%rbp) + fyl2x + pop %rbp + ret + .endfn tinymath_logl,globl + .alias tinymath_logl,logl diff --git a/libc/tinymath/lrint.S b/libc/tinymath/lrint.S new file mode 100644 index 00000000..b0c836e7 --- /dev/null +++ b/libc/tinymath/lrint.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_lrint: + cvtsd2siq %xmm0,%rax + ret + .endfn tinymath_lrint,globl + .alias tinymath_lrint,lrint + .alias tinymath_lrint,llrint diff --git a/libc/tinymath/lrintf.S b/libc/tinymath/lrintf.S new file mode 100644 index 00000000..3d313c88 --- /dev/null +++ b/libc/tinymath/lrintf.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_lrintf: + cvtss2siq %xmm0,%rax + ret + .endfn tinymath_lrintf,globl + .alias tinymath_lrintf,lrintf + .alias tinymath_lrintf,llrintf diff --git a/libc/tinymath/lrintl.S b/libc/tinymath/lrintl.S new file mode 100644 index 00000000..e469a2bf --- /dev/null +++ b/libc/tinymath/lrintl.S @@ -0,0 +1,34 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_lrintl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + fistpll 16(%rbp) + mov 16(%rbp),%rax + pop %rbp + ret + .endfn tinymath_lrintl,globl + .alias tinymath_lrintl,lrintl + .alias tinymath_lrintl,llrintl diff --git a/libc/tinymath/lround.S b/libc/tinymath/lround.S new file mode 100644 index 00000000..b37d8303 --- /dev/null +++ b/libc/tinymath/lround.S @@ -0,0 +1,44 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Rounds to nearest integer, away from zero. +/ +/ @param 𝑥 is double scalar in low half of %xmm0 +/ @return 64-bit signed integer in %rax +/ @see round(), lrint() +tinymath_lround: + .leafprologue + .profilable + movsd A(%rip),%xmm2 + movsd B(%rip),%xmm1 + andpd %xmm0,%xmm2 + orpd %xmm2,%xmm1 + addsd %xmm0,%xmm1 + cvttsd2siq %xmm1,%rax + .leafepilogue + .endfn tinymath_lround,globl + .alias tinymath_lround,lround + .alias tinymath_lround,llround + + .rodata.cst16 +A: .quad 0x8000000000000000,0 +B: .quad 0x3fdfffffffffffff,0 diff --git a/libc/tinymath/lroundf.S b/libc/tinymath/lroundf.S new file mode 100644 index 00000000..f4489773 --- /dev/null +++ b/libc/tinymath/lroundf.S @@ -0,0 +1,45 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Rounds to nearest integer, away from zero. +/ +/ @param 𝑥 is float scalar in low quarter of %xmm0 +/ @return 64-bit signed integer in %rax +/ @see round() +tinymath_lroundf: + .leafprologue + .profilable + movss A(%rip),%xmm1 + movss B(%rip),%xmm2 + andps %xmm0,%xmm2 + orps %xmm2,%xmm1 + addss %xmm0,%xmm1 + cvttss2siq %xmm1,%rax + .leafepilogue + .endfn tinymath_lroundf,globl + .alias tinymath_lroundf,lroundf + .alias tinymath_lroundf,llroundf + + .rodata.cst4 +A: .long 0x3effffff + .rodata.cst16 +B: .long 0x80000000,0,0,0 diff --git a/libc/tinymath/lroundl.S b/libc/tinymath/lroundl.S new file mode 100644 index 00000000..86b1cda8 --- /dev/null +++ b/libc/tinymath/lroundl.S @@ -0,0 +1,54 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_lroundl: + push %rbp + mov %rsp,%rbp + .profilable + push %rax + push %rax + fldt 16(%rbp) + fnstcw -8(%rbp) + movzwl -8(%rbp),%edx + and $0b11110011,%dh # RC (Rounding Control) + or $0b00000100,%dh # →-∞ + mov %dx,-4(%rbp) + fxam + fnstsw %ax + fabs + test $FPU_C1>>8,%ah + fadds .Lhalf(%rip) + fldcw -4(%rbp) + fistpq -16(%rbp) + fldcw -8(%rbp) + mov -16(%rbp),%rax + je 1f + neg %rax +1: leave + ret + .endfn tinymath_lroundl,globl + .alias tinymath_lroundl,lroundl + .alias tinymath_lroundl,llroundl + + .rodata.cst4 +.Lhalf: .float .5 diff --git a/libc/tinymath/nearbyint.S b/libc/tinymath/nearbyint.S new file mode 100644 index 00000000..e4d93369 --- /dev/null +++ b/libc/tinymath/nearbyint.S @@ -0,0 +1,41 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_nearbyint: + .profilable + sub $16,%rsp + movsd %xmm0,(%rsp) + fnstcw 14(%rsp) + movzwl 14(%rsp),%eax + fldl (%rsp) + orl $32,%eax + movw %ax,12(%rsp) + fldcw 12(%rsp) + frndint + fclex + fldcw 14(%rsp) + fstpl (%rsp) + movsd (%rsp),%xmm0 + add $16,%rsp + ret + .endfn tinymath_nearbyint,globl + .alias tinymath_nearbyint,nearbyint diff --git a/libc/tinymath/nearbyintf.S b/libc/tinymath/nearbyintf.S new file mode 100644 index 00000000..2831ecc8 --- /dev/null +++ b/libc/tinymath/nearbyintf.S @@ -0,0 +1,41 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_nearbyintf: + .profilable + sub $8,%rsp + movss %xmm0,(%rsp) + fnstcw 6(%rsp) + movzwl 6(%rsp),%eax + flds (%rsp) + orl $32,%eax + movw %ax,4(%rsp) + fldcw 4(%rsp) + frndint + fclex + fldcw 6(%rsp) + fstps (%rsp) + movss (%rsp),%xmm0 + add $8,%rsp + ret + .endfn tinymath_nearbyintf,globl + .alias tinymath_nearbyintf,nearbyintf diff --git a/libc/tinymath/nearbyintl.S b/libc/tinymath/nearbyintl.S new file mode 100644 index 00000000..2a012aa8 --- /dev/null +++ b/libc/tinymath/nearbyintl.S @@ -0,0 +1,38 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_nearbyintl: + .profilable + sub $24,%rsp + fldt 32(%rsp) + fnstcw 14(%rsp) + movzwl 14(%rsp),%eax + orl $32,%eax + movw %ax,12(%rsp) + fldcw 12(%rsp) + frndint + fclex + fldcw 14(%rsp) + add $24,%rsp + ret + .endfn tinymath_nearbyintl,globl + .alias tinymath_nearbyintl,nearbyintl diff --git a/libc/tinymath/pow.S b/libc/tinymath/pow.S new file mode 100644 index 00000000..1928569f --- /dev/null +++ b/libc/tinymath/pow.S @@ -0,0 +1,33 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns 𝑥^𝑦. +/ +/ @param 𝑦 is double scalar in low half of %xmm0 +/ @param 𝑥 is double scalar in low half of %xmm1 +/ @return double scalar in low half of %xmm0 +tinymath_pow: + ezlea tinymath_powl,ax + jmp _d2ld2 + .endfn tinymath_pow,globl + .alias tinymath_pow,pow + .alias tinymath_pow,__pow_finite diff --git a/libc/tinymath/powf.S b/libc/tinymath/powf.S new file mode 100644 index 00000000..bd38fc72 --- /dev/null +++ b/libc/tinymath/powf.S @@ -0,0 +1,33 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns 𝑥^𝑦. +/ +/ @param 𝑦 is float scalar in low quarter of %xmm0 +/ @param 𝑥 is float scalar in low quarter of %xmm1 +/ @return float scalar in low quarter of %xmm0 +tinymath_powf: + ezlea tinymath_powl,ax + jmp _f2ld2 + .endfn tinymath_powf,globl + .alias tinymath_powf,powf + .alias tinymath_powf,__powf_finite diff --git a/libc/tinymath/powl.S b/libc/tinymath/powl.S new file mode 100644 index 00000000..090c0786 --- /dev/null +++ b/libc/tinymath/powl.S @@ -0,0 +1,48 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns 𝑥^𝑦. +/ +/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes +/ @param 𝑦 is the power, also pushed on stack, in reverse order +/ @return result of exponentiation on FPU stack in %st +/ @note Sun's fdlibm needs 2kLOC to do this for RISC lool +tinymath_powl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 32(%rbp) + fldt 16(%rbp) + fyl2x + fld1 + fld %st(1) + fprem + f2xm1 + faddp + fscale + fxch %st(1) + fstp %st + pop %rbp + ret + .endfn tinymath_powl,globl + .alias tinymath_powl,powl + .alias tinymath_powl,__powl_finite diff --git a/libc/tinymath/remainder.S b/libc/tinymath/remainder.S new file mode 100644 index 00000000..83af0d4e --- /dev/null +++ b/libc/tinymath/remainder.S @@ -0,0 +1,35 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ remainder(𝑥,𝑦) means (𝑥 rem 𝑦) w/ rint()-style rounding. +/ +/ @param 𝑥 is double passed in lower half of %xmm0 +/ @param 𝑦 is double passed in lower half of %xmm1 +/ @return remainder ∈ (-|𝑦|,|𝑦|) in %xmm0 +/ @define 𝑥-rint(𝑥/𝑦)*𝑦 +/ @see fmod(), emod(), operator% +tinymath_remainder: + ezlea tinymath_remainderl,ax + jmp _d2ld2 + .endfn tinymath_remainder,globl + .alias tinymath_remainder,remainder + .alias tinymath_remainder,drem diff --git a/libc/tinymath/remainderf.S b/libc/tinymath/remainderf.S new file mode 100644 index 00000000..c0857b94 --- /dev/null +++ b/libc/tinymath/remainderf.S @@ -0,0 +1,28 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_remainderf: + ezlea tinymath_remainderl,ax + jmp _f2ld2 + .endfn tinymath_remainderf,globl + .alias tinymath_remainderf,remainderf + .alias tinymath_remainderf,dremf diff --git a/libc/tinymath/remainderl.S b/libc/tinymath/remainderl.S new file mode 100644 index 00000000..146314d9 --- /dev/null +++ b/libc/tinymath/remainderl.S @@ -0,0 +1,39 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_remainderl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 32(%rbp) + fldt 16(%rbp) +1: fprem1 + fnstsw %ax + test $FPU_C2>>8,%ah + jne 1b + fstp %st(1) + pop %rbp + ret + .endfn tinymath_remainderl,globl + .alias tinymath_remainderl,remainderl + .alias tinymath_remainderl,dreml diff --git a/libc/tinymath/rint.S b/libc/tinymath/rint.S new file mode 100644 index 00000000..43487d08 --- /dev/null +++ b/libc/tinymath/rint.S @@ -0,0 +1,65 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/nexgen32e/x86feature.h" +#include "libc/bits/smmintrin.h" +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_rint: +#if !X86_NEED(SSE4_2) + testb X86_HAVE(SSE4_2)+kCpuids(%rip) + jz tinymath_rint$k8 + .text.antiquity +tinymath_rint$k8: +0: movq %xmm0,%rax + movq %xmm0,%rdx + shr $52,%rdx + and $2047,%edx + cmp $1074,%edx + jg 2f + movsd mmm(%rip),%xmm1 + shr $63,%rax + jne 3f + addsd %xmm1,%xmm0 + subsd %xmm1,%xmm0 +1: pxor %xmm2,%xmm2 + ucomisd %xmm2,%xmm0 + jp 2f + jne 2f + movsd sgn(%rip),%xmm0 + test %rax,%rax + je 4f +2: ret +3: subsd %xmm1,%xmm0 + addsd %xmm1,%xmm0 + jmp 1b +4: pxor %xmm0,%xmm0 + ret + .endfn tinymath_rint$k8,globl,hidden + .previous + .rodata.cst8 +sgn: .quad 0x8000000000000000 +mmm: .quad 0x4330000000000000 + .previous +#endif + roundsd $_MM_FROUND_RINT,%xmm0,%xmm0 + ret + .endfn tinymath_rint,globl + .alias tinymath_rint,rint diff --git a/libc/tinymath/rintf.S b/libc/tinymath/rintf.S new file mode 100644 index 00000000..c30f204c --- /dev/null +++ b/libc/tinymath/rintf.S @@ -0,0 +1,51 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_rintf: + .leafprologue + .profilable + movaps %xmm0,%xmm1 + movss .LC8(%rip),%xmm2 + andps %xmm2,%xmm1 + movss .LC7(%rip),%xmm3 + comiss %xmm1,%xmm3 + jbe 1f + addss %xmm3,%xmm1 + andnps %xmm0,%xmm2 + movaps %xmm2,%xmm0 + subss %xmm3,%xmm1 + orps %xmm1,%xmm0 +1: .leafepilogue + .endfn tinymath_rintf,globl + .alias tinymath_rintf,rintf + + .rodata.cst4 +.LC7: .long 1258291200 + + .rodata.cst16 +.LC8: .long 2147483647 + .long 0 + .long 0 + .long 0 + +/ TODO(jart): +/ vroundss $4,%xmm0,%xmm0,%xmm0 diff --git a/libc/tinymath/rintl.S b/libc/tinymath/rintl.S new file mode 100644 index 00000000..6e29dc5b --- /dev/null +++ b/libc/tinymath/rintl.S @@ -0,0 +1,32 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_rintl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + frndint + pop %rbp + ret + .endfn tinymath_rintl,globl + .alias tinymath_rintl,rintl diff --git a/libc/tinymath/round.S b/libc/tinymath/round.S new file mode 100644 index 00000000..b2a7b13e --- /dev/null +++ b/libc/tinymath/round.S @@ -0,0 +1,71 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +#include "libc/bits/smmintrin.h" +#include "libc/nexgen32e/x86feature.h" +.yoink __FILE__ + +/ Rounds to nearest integer, away from zero. +/ +/ @param 𝑥 is double scalar in low half of %xmm0 +/ @return double scalar in low half of %xmm0 +/ @define round(𝑥) = copysign(floor(fabs(𝑥)+.5),𝑥) +/ round(𝑥) = trunc(𝑥+copysign(.5,𝑥)) +tinymath_round: +#if !X86_NEED(SSE4_2) + testb X86_HAVE(SSE4_2)+kCpuids(%rip) + jz tinymath_round$k8 + .text.antiquity +tinymath_round$k8: + .leafprologue + .profilable + movapd %xmm0,%xmm1 + movsd D(%rip),%xmm2 + movsd C(%rip),%xmm3 + andpd %xmm2,%xmm1 + ucomisd %xmm1,%xmm3 + jbe 2f + addsd A(%rip),%xmm1 + andnpd %xmm0,%xmm2 + movapd %xmm2,%xmm0 + cvttsd2siq %xmm1,%rax + pxor %xmm1,%xmm1 + cvtsi2sdq %rax,%xmm1 + orpd %xmm1,%xmm0 +2: .leafepilogue + .endfn tinymath_round$k8,globl,hidden + .previous + .rodata.cst16 +C: .quad 0x4330000000000000,0 +D: .quad 0x7fffffffffffffff,0 + .previous +#endif + movapd %xmm0,%xmm1 + andpd B(%rip),%xmm0 + orpd A(%rip),%xmm0 + addsd %xmm1,%xmm0 + roundsd $_MM_FROUND_TO_ZERO,%xmm0,%xmm0 + ret + .endfn tinymath_round,globl + .alias tinymath_round,round + + .rodata.cst16 +A: .quad 0x3fdfffffffffffff,0 +B: .quad 0x8000000000000000,0 diff --git a/libc/tinymath/roundf.S b/libc/tinymath/roundf.S new file mode 100644 index 00000000..a6a98be9 --- /dev/null +++ b/libc/tinymath/roundf.S @@ -0,0 +1,69 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +#include "libc/bits/smmintrin.h" +#include "libc/nexgen32e/x86feature.h" +.yoink __FILE__ + +/ Rounds to nearest integer, away from zero. +/ +/ @param 𝑥 is float scalar in low quarter of %xmm0 +/ @return float scalar in low quarter of %xmm0 +tinymath_roundf: +#if !X86_NEED(SSE4_2) + testb X86_HAVE(SSE4_2)+kCpuids(%rip) + jz tinymath_roundf$k8 + .text.antiquity +tinymath_roundf$k8: + .leafprologue + .profilable + movaps %xmm0,%xmm1 + movss D(%rip),%xmm2 + movss C(%rip),%xmm3 + andps %xmm2,%xmm1 + ucomiss %xmm1,%xmm3 + jbe 2f + addss A(%rip),%xmm1 + cvttss2sil %xmm1,%eax + pxor %xmm1,%xmm1 + cvtsi2ssl %eax,%xmm1 + andnps %xmm0,%xmm2 + movaps %xmm2,%xmm0 + orps %xmm1,%xmm0 +2: .leafepilogue + .endfn tinymath_roundf$k8,globl,hidden + .previous + .rodata.cst16 +C: .long 0x4b000000,0,0,0 +D: .long 0x7fffffff,0,0,0 + .previous +#endif + movaps %xmm0,%xmm1 + andps B(%rip),%xmm0 + orps A(%rip),%xmm0 + addss %xmm1,%xmm0 + roundss $_MM_FROUND_TO_ZERO,%xmm0,%xmm0 + ret + .endfn tinymath_roundf,globl + .alias tinymath_roundf,roundf + + .rodata.cst16 +A: .long 0x3effffff,0,0,0 +B: .long 0x80000000,0,0,0 diff --git a/libc/tinymath/roundl.S b/libc/tinymath/roundl.S new file mode 100644 index 00000000..24917a50 --- /dev/null +++ b/libc/tinymath/roundl.S @@ -0,0 +1,51 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_roundl: + push %rbp + mov %rsp,%rbp + .profilable + push %rax + fldt 16(%rbp) + fnstcw -8(%rbp) + movzwl -8(%rbp),%edx + and $0b11110011,%dh # RC (Rounding Control) + or $0b00000100,%dh # →-∞ + mov %dx,-4(%rbp) + fxam + fnstsw %ax + fabs + test $FPU_C1>>8,%ah + fadds .Lhalf(%rip) + fldcw -4(%rbp) + frndint + fldcw -8(%rbp) + je 1f + fchs +1: leave + ret + .endfn tinymath_roundl,globl + .alias tinymath_roundl,roundl + + .rodata.cst4 +.Lhalf: .float .5 diff --git a/libc/tinymath/scalb.S b/libc/tinymath/scalb.S new file mode 100644 index 00000000..96de7090 --- /dev/null +++ b/libc/tinymath/scalb.S @@ -0,0 +1,40 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_scalb: + push %rbp + mov %rsp,%rbp + .profilable + push %rax + movsd %xmm0,(%rsp) + fldl (%rsp) + movsd %xmm1,(%rsp) + fldl (%rsp) + fxch %st(1) + fscale + fstp %st(1) + fstpl (%rsp) + movsd (%rsp),%xmm0 + leave + ret + .endfn tinymath_scalb,globl + .alias tinymath_scalb,scalb diff --git a/libc/tinymath/scalbf.S b/libc/tinymath/scalbf.S new file mode 100644 index 00000000..21dacc92 --- /dev/null +++ b/libc/tinymath/scalbf.S @@ -0,0 +1,40 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_scalbf: + push %rbp + mov %rsp,%rbp + .profilable + push %rax + movss %xmm0,-4(%rbp) + flds -4(%rbp) + movss %xmm1,-4(%rbp) + flds -4(%rbp) + fxch %st(1) + fscale + fstp %st(1) + fstps -4(%rbp) + movss -4(%rbp),%xmm0 + leave + ret + .endfn tinymath_scalbf,globl + .alias tinymath_scalbf,scalbf diff --git a/libc/tinymath/scalbl.S b/libc/tinymath/scalbl.S new file mode 100644 index 00000000..2e70e07e --- /dev/null +++ b/libc/tinymath/scalbl.S @@ -0,0 +1,34 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_scalbl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 32(%rbp) + fldt 16(%rbp) + fscale + fstp %st(1) + pop %rbp + ret + .endfn tinymath_scalbl,globl + .alias tinymath_scalbl,scalbl diff --git a/libc/tinymath/scalbln.S b/libc/tinymath/scalbln.S new file mode 100644 index 00000000..72673446 --- /dev/null +++ b/libc/tinymath/scalbln.S @@ -0,0 +1,40 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_scalbln: + push %rbp + mov %rsp,%rbp + .profilable + push %rax + movsd %xmm0,-8(%rbp) + fldl -8(%rbp) + movq %rdi,-8(%rbp) + fildl -8(%rbp) + fxch %st(1) + fscale + fstp %st(1) + fstpl -8(%rbp) + movsd -8(%rbp),%xmm0 + leave + ret + .endfn tinymath_scalbln,globl + .alias tinymath_scalbln,scalbln diff --git a/libc/tinymath/scalblnl.S b/libc/tinymath/scalblnl.S new file mode 100644 index 00000000..1e8ce10b --- /dev/null +++ b/libc/tinymath/scalblnl.S @@ -0,0 +1,40 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_scalblnf: + push %rbp + mov %rsp,%rbp + .profilable + push %rax + movss %xmm0,(%rsp) + flds (%rsp) + movq %rdi,(%rsp) + fildl (%rsp) + fxch %st(1) + fscale + fstp %st(1) + fstps (%rsp) + movss (%rsp),%xmm0 + leave + ret + .endfn tinymath_scalblnf,globl + .alias tinymath_scalblnf,scalblnf diff --git a/libc/tinymath/scalbn.S b/libc/tinymath/scalbn.S new file mode 100644 index 00000000..89cacb2f --- /dev/null +++ b/libc/tinymath/scalbn.S @@ -0,0 +1,40 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_scalbn: + push %rbp + mov %rsp,%rbp + .profilable + push %rax + movsd %xmm0,-8(%rbp) + fldl -8(%rbp) + movl %edi,-8(%rbp) + fildl -8(%rbp) + fxch %st(1) + fscale + fstp %st(1) + fstpl -8(%rbp) + movsd -8(%rbp),%xmm0 + leave + ret + .endfn tinymath_scalbn,globl + .alias tinymath_scalbn,scalbn diff --git a/libc/tinymath/scalbnf.S b/libc/tinymath/scalbnf.S new file mode 100644 index 00000000..30d6075f --- /dev/null +++ b/libc/tinymath/scalbnf.S @@ -0,0 +1,35 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_scalbnl: + .profilable + sub $24,%rsp + fldt 32(%rsp) + movl %edi,12(%rsp) + fildl 12(%rsp) + fxch %st(1) + add $24,%rsp + fscale + fstp %st(1) + ret + .endfn tinymath_scalbnl,globl + .alias tinymath_scalbnl,scalbnl diff --git a/libc/tinymath/scalbnl.S b/libc/tinymath/scalbnl.S new file mode 100644 index 00000000..fc538eac --- /dev/null +++ b/libc/tinymath/scalbnl.S @@ -0,0 +1,40 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_scalbnf: + push %rbp + mov %rsp,%rbp + .profilable + push %rax + movss %xmm0,-4(%rbp) + flds -4(%rbp) + movl %edi,-4(%rbp) + fildl -4(%rbp) + fxch %st(1) + fscale + fstp %st(1) + fstps -4(%rbp) + movss -4(%rbp),%xmm0 + leave + ret + .endfn tinymath_scalbnf,globl + .alias tinymath_scalbnf,scalbnf diff --git a/libc/tinymath/signbit.S b/libc/tinymath/signbit.S new file mode 100644 index 00000000..c91459a7 --- /dev/null +++ b/libc/tinymath/signbit.S @@ -0,0 +1,32 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_signbit: + .leafprologue + .profilable + pxor %xmm1,%xmm1 + xor %eax,%eax + comisd %xmm0,%xmm1 + seta %al + .leafepilogue + .endfn tinymath_signbit,globl + .alias tinymath_signbit,signbit diff --git a/libc/tinymath/signbitf.S b/libc/tinymath/signbitf.S new file mode 100644 index 00000000..f0f8f9b4 --- /dev/null +++ b/libc/tinymath/signbitf.S @@ -0,0 +1,32 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_signbitf: + .leafprologue + .profilable + pxor %xmm1,%xmm1 + xor %eax,%eax + comiss %xmm0,%xmm1 + seta %al + .leafepilogue + .endfn tinymath_signbitf,globl + .alias tinymath_signbitf,signbitf diff --git a/libc/tinymath/signbitl.S b/libc/tinymath/signbitl.S new file mode 100644 index 00000000..630a3f41 --- /dev/null +++ b/libc/tinymath/signbitl.S @@ -0,0 +1,36 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_signbitl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + xor %eax,%eax + fldz + fcomip %st(1),%st + fstp %st + seta %al + pop %rbp + ret + .endfn tinymath_signbitl,globl + .alias tinymath_signbitl,signbitl diff --git a/libc/tinymath/significand.S b/libc/tinymath/significand.S new file mode 100644 index 00000000..24552ca7 --- /dev/null +++ b/libc/tinymath/significand.S @@ -0,0 +1,37 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_significand: + push %rbp + mov %rsp,%rbp + .profilable + push %rax + movsd %xmm0,(%rsp) + fldl (%rsp) + fxtract + fstp %st(1) + fstpl (%rsp) + movsd (%rsp),%xmm0 + leave + ret + .endfn tinymath_significand,globl + .alias tinymath_significand,significand diff --git a/libc/tinymath/significandf.S b/libc/tinymath/significandf.S new file mode 100644 index 00000000..4622c63f --- /dev/null +++ b/libc/tinymath/significandf.S @@ -0,0 +1,37 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_significandf: + push %rbp + mov %rsp,%rbp + .profilable + push %rax + movss %xmm0,-4(%rbp) + flds -4(%rbp) + fxtract + fstp %st(1) + fstps -4(%rbp) + movss -4(%rbp),%xmm0 + leave + ret + .endfn tinymath_significandf,globl + .alias tinymath_significandf,significandf diff --git a/libc/tinymath/significandl.S b/libc/tinymath/significandl.S new file mode 100644 index 00000000..71b755a6 --- /dev/null +++ b/libc/tinymath/significandl.S @@ -0,0 +1,33 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_significandl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + fxtract + fstp %st(1) + pop %rbp + ret + .endfn tinymath_significandl,globl + .alias tinymath_significandl,significandl diff --git a/libc/tinymath/sin.S b/libc/tinymath/sin.S new file mode 100644 index 00000000..713550dc --- /dev/null +++ b/libc/tinymath/sin.S @@ -0,0 +1,32 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns sine of 𝑥. +/ +/ @param 𝑥 is double scalar in low half of %xmm0 +/ @return double scalar in low half of %xmm0 +/ @domain -(3π/8) < 𝑥 < 3π/8 for best accuracy +tinymath_sin: + ezlea tinymath_sinl,ax + jmp _d2ld2 + .endfn tinymath_sin,globl + .alias tinymath_sin,sin diff --git a/libc/tinymath/sincos.S b/libc/tinymath/sincos.S new file mode 100644 index 00000000..fe0a5294 --- /dev/null +++ b/libc/tinymath/sincos.S @@ -0,0 +1,43 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns sine and cosine of 𝑥. +/ +/ @param 𝑥 is double scalar in low half of %xmm0 +/ @param %rdi is double *out_sin +/ @param %rsi is double *out_cos +/ @domain -(3π/8) < 𝑥 < 3π/8 for best accuracy +tinymath_sincos: + push %rbp + mov %rsp,%rbp + .profilable + push %rax + movsd %xmm0,-8(%rbp) + fldl -8(%rbp) + fsincos + fxch %st(1) + fstpl (%rdi) + fstpl (%rsi) + leave + ret + .endfn tinymath_sincos,globl + .alias tinymath_sincos,sincos diff --git a/libc/tinymath/sincosf.S b/libc/tinymath/sincosf.S new file mode 100644 index 00000000..2aac57fa --- /dev/null +++ b/libc/tinymath/sincosf.S @@ -0,0 +1,43 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns sine and cosine of 𝑥. +/ +/ @param 𝑥 is float scalar in low quarter of %xmm0 +/ @param %rdi is float *out_sin +/ @param %rsi is float *out_cos +/ @domain -(3π/8) < 𝑥 < 3π/8 for best accuracy +tinymath_sincosf: + push %rbp + mov %rsp,%rbp + .profilable + push %rax + movss %xmm0,4(%rsp) + flds 4(%rsp) + fsincos + fxch %st(1) + fstps (%rdi) + fstps (%rsi) + leave + ret + .endfn tinymath_sincosf,globl + .alias tinymath_sincosf,sincosf diff --git a/libc/tinymath/sincosl.S b/libc/tinymath/sincosl.S new file mode 100644 index 00000000..faf4d5ba --- /dev/null +++ b/libc/tinymath/sincosl.S @@ -0,0 +1,40 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns sine and cosine of 𝑥. +/ +/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes +/ @param %rdi is long double *out_sin +/ @param %rsi is long double *out_cos +/ @domain -(3π/8) < 𝑥 < 3π/8 for best accuracy +tinymath_sincosl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + fsincos + fstpt (%rsi) + fstpt (%rdi) + pop %rbp + ret + .endfn tinymath_sincosl,globl + .alias tinymath_sincosl,sincosl diff --git a/libc/tinymath/sinf.S b/libc/tinymath/sinf.S new file mode 100644 index 00000000..ed5c9a00 --- /dev/null +++ b/libc/tinymath/sinf.S @@ -0,0 +1,32 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns sine of 𝑥. +/ +/ @param 𝑥 is float scalar in low quarter of %xmm0 +/ @return float scalar in low quarter of %xmm0 +/ @domain -(3π/8) < 𝑥 < 3π/8 for best accuracy +tinymath_sinf: + ezlea tinymath_sinl,ax + jmp _f2ld2 + .endfn tinymath_sinf,globl + .alias tinymath_sinf,sinf diff --git a/libc/tinymath/sinl.S b/libc/tinymath/sinl.S new file mode 100644 index 00000000..7afde135 --- /dev/null +++ b/libc/tinymath/sinl.S @@ -0,0 +1,44 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns sine of 𝑥. +/ +/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes +/ @domain -(3π/8) < 𝑥 < 3π/8 for best accuracy +/ @return %st stores result +tinymath_sinl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + ezlea fsin,dx + call c2rangr + pop %rbp + ret + .endfn tinymath_sinl,globl + .alias tinymath_sinl,sinl + +fsin: .leafprologue + .profilable + fsin + .leafepilogue + .endfn fsin diff --git a/libc/tinymath/sqrt.S b/libc/tinymath/sqrt.S new file mode 100644 index 00000000..83f072bf --- /dev/null +++ b/libc/tinymath/sqrt.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_sqrt: + .leafprologue + .profilable + sqrtsd %xmm0,%xmm0 + .leafepilogue + .endfn tinymath_sqrt,globl + .alias tinymath_sqrt,sqrt diff --git a/libc/tinymath/sqrtf.S b/libc/tinymath/sqrtf.S new file mode 100644 index 00000000..06810380 --- /dev/null +++ b/libc/tinymath/sqrtf.S @@ -0,0 +1,29 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_sqrtf: + .leafprologue + .profilable + sqrtss %xmm0,%xmm0 + .leafepilogue + .endfn tinymath_sqrtf,globl + .alias tinymath_sqrtf,sqrtf diff --git a/libc/tinymath/sqrtl.S b/libc/tinymath/sqrtl.S new file mode 100644 index 00000000..5095b44f --- /dev/null +++ b/libc/tinymath/sqrtl.S @@ -0,0 +1,36 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns square root of 𝑥. +/ +/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes +/ @return result on FPU stack in %st +tinymath_sqrtl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + fsqrt + pop %rbp + ret + .endfn tinymath_sqrtl,globl + .alias tinymath_sqrtl,sqrtl diff --git a/libc/tinymath/tan.S b/libc/tinymath/tan.S new file mode 100644 index 00000000..06829d60 --- /dev/null +++ b/libc/tinymath/tan.S @@ -0,0 +1,32 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns tangent of 𝑥. +/ +/ @param 𝑥 is double scalar in low half of %xmm0 +/ @return double scalar in low half of %xmm0 +/ @domain -(3π/8) < 𝑥 < 3π/8 for best accuracy +tinymath_tan: + ezlea tinymath_tanl,ax + jmp _d2ld2 + .endfn tinymath_tan,globl + .alias tinymath_tan,tan diff --git a/libc/tinymath/tanf.S b/libc/tinymath/tanf.S new file mode 100644 index 00000000..1f96d83c --- /dev/null +++ b/libc/tinymath/tanf.S @@ -0,0 +1,32 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns tangent of 𝑥. +/ +/ @param 𝑥 is float scalar in low quarter of %xmm0 +/ @return float scalar in low quarter of %xmm0 +/ @domain -(3π/8) < 𝑥 < 3π/8 for best accuracy +tinymath_tanf: + ezlea tinymath_tanl,ax + jmp _f2ld2 + .endfn tinymath_tanf,globl + .alias tinymath_tanf,tanf diff --git a/libc/tinymath/tanl.S b/libc/tinymath/tanl.S new file mode 100644 index 00000000..4ecc9b01 --- /dev/null +++ b/libc/tinymath/tanl.S @@ -0,0 +1,45 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" +#include "libc/macros.h" +.yoink __FILE__ + +/ Returns tangent of 𝑥. +/ +/ @param 𝑥 is an 80-bit long double passed on stack in 16-bytes +/ @return %st stores result +tinymath_tanl: + push %rbp + mov %rsp,%rbp + .profilable + fldt 16(%rbp) + ezlea fptan,dx + call c2rangr + fstp %st + pop %rbp + ret + .endfn tinymath_tanl,globl + .alias tinymath_tanl,tanl + +fptan: .leafprologue + .profilable + fptan + .leafepilogue + .endfn fptan diff --git a/libc/tinymath/tinymath.h b/libc/tinymath/tinymath.h new file mode 100644 index 00000000..311cae3d --- /dev/null +++ b/libc/tinymath/tinymath.h @@ -0,0 +1,100 @@ +#ifndef COSMOPOLITAN_LIBC_TINYMATH_TINYMATH_H_ +#define COSMOPOLITAN_LIBC_TINYMATH_TINYMATH_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +float tinymath_powf(float, float) libcesque pureconst; +double tinymath_pow(double, double) libcesque pureconst; +long double tinymath_powl(long double, long double) libcesque pureconst; + +float tinymath_expf(float) libcesque pureconst; +double tinymath_exp(double) libcesque pureconst; +long double tinymath_expl(long double) libcesque pureconst; + +float tinymath_exp10f(float) libcesque pureconst; +double tinymath_exp10(double) libcesque pureconst; +long double tinymath_exp10l(long double) libcesque pureconst; + +float tinymath_logf(float) libcesque pureconst; +double tinymath_log(double) libcesque pureconst; +long double tinymath_logl(long double) libcesque pureconst; + +float tinymath_log10f(float) libcesque pureconst; +double tinymath_log10(double) libcesque pureconst; +long double tinymath_log10l(long double) libcesque pureconst; + +float tinymath_ldexpf(float, int) libcesque pureconst; +double tinymath_ldexp(double, int) libcesque pureconst; +long double tinymath_ldexpl(long double, int) libcesque pureconst; + +float tinymath_asinf(float) libcesque pureconst; +double tinymath_asin(double) libcesque pureconst; +long double tinymath_asinl(long double) libcesque pureconst; + +float tinymath_acosf(float) libcesque pureconst; +double tinymath_acos(double) libcesque pureconst; +long double tinymath_acosl(long double) libcesque pureconst; + +float tinymath_atanf(float) libcesque pureconst; +double tinymath_atan(double) libcesque pureconst; +long double tinymath_atanl(long double) libcesque pureconst; + +float tinymath_atan2f(float, float) libcesque pureconst; +double tinymath_atan2(double, double) libcesque pureconst; +long double tinymath_atan2l(long double, long double) libcesque pureconst; + +float tinymath_sinf(float) libcesque pureconst; +double tinymath_sin(double) libcesque pureconst; +long double tinymath_sinl(long double) libcesque pureconst; + +float tinymath_cosf(float) libcesque pureconst; +double tinymath_cos(double) libcesque pureconst; +long double tinymath_cosl(long double) libcesque pureconst; + +float tinymath_tanf(float) libcesque pureconst; +double tinymath_tan(double) libcesque pureconst; +long double tinymath_tanl(long double) libcesque pureconst; + +void tinymath_sincosf(float, float *, float *) libcesque; +void tinymath_sincos(double, double *, double *) libcesque; +void tinymath_sincosl(long double, long double *, long double *) libcesque; + +long tinymath_lroundf(float) libcesque pureconst; +long tinymath_lround(double) libcesque pureconst; +long tinymath_lroundl(long double) libcesque pureconst; + +float tinymath_roundf(float) libcesque pureconst; +double tinymath_round(double) libcesque pureconst; +long double tinymath_roundl(long double) libcesque pureconst; + +float tinymath_rintf(float) libcesque pureconst; +double tinymath_rint(double) libcesque pureconst; +long double tinymath_rintl(long double) libcesque pureconst; + +float tinymath_nearbyintf(float) libcesque pureconst; +double tinymath_nearbyint(double) libcesque pureconst; +long double tinymath_nearbyintl(long double) libcesque pureconst; + +float tinymath_truncf(float) libcesque pureconst; +double tinymath_trunc(double) libcesque pureconst; +long double tinymath_truncl(long double) libcesque pureconst; + +float tinymath_floorf(float) libcesque pureconst; +double tinymath_floor(double) libcesque pureconst; +long double tinymath_floorl(long double) libcesque pureconst; + +float tinymath_ceilf(float) libcesque pureconst; +double tinymath_ceil(double) libcesque pureconst; +long double tinymath_ceill(long double) libcesque pureconst; + +float tinymath_remainderf(float, float) libcesque pureconst; +double tinymath_remainder(double, double) libcesque pureconst; +long double tinymath_remainderl(long double, long double) libcesque pureconst; + +float tinymath_fmodf(float, float) libcesque pureconst; +double tinymath_fmod(double, double) libcesque pureconst; +long double tinymath_fmodl(long double, long double) libcesque pureconst; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_TINYMATH_TINYMATH_H_ */ diff --git a/libc/tinymath/tinymath.mk b/libc/tinymath/tinymath.mk new file mode 100644 index 00000000..a3c8d594 --- /dev/null +++ b/libc/tinymath/tinymath.mk @@ -0,0 +1,55 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += LIBC_TINYMATH + +LIBC_TINYMATH_ARTIFACTS += LIBC_TINYMATH_A +LIBC_TINYMATH = $(LIBC_TINYMATH_A_DEPS) $(LIBC_TINYMATH_A) +LIBC_TINYMATH_A = o/$(MODE)/libc/tinymath/tinymath.a +LIBC_TINYMATH_A_HDRS = $(filter %.h,$(LIBC_TINYMATH_A_FILES)) +LIBC_TINYMATH_A_SRCS_A = $(filter %.s,$(LIBC_TINYMATH_A_FILES)) +LIBC_TINYMATH_A_SRCS_S = $(filter %.S,$(LIBC_TINYMATH_A_FILES)) +LIBC_TINYMATH_A_SRCS_C = $(filter %.c,$(LIBC_TINYMATH_A_FILES)) +LIBC_TINYMATH_A_SRCS = $(LIBC_TINYMATH_A_SRCS_S) $(LIBC_TINYMATH_A_SRCS_C) +LIBC_TINYMATH_A_CHECKS = $(LIBC_TINYMATH_A).pkg + +LIBC_TINYMATH_A_FILES := \ + $(wildcard libc/tinymath/*) \ + $(wildcard libc/tinymath/delegates/*) + +LIBC_TINYMATH_A_OBJS = \ + $(LIBC_TINYMATH_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_TINYMATH_A_SRCS_A:%.s=o/$(MODE)/%.o) \ + $(LIBC_TINYMATH_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_TINYMATH_A_SRCS_C:%.c=o/$(MODE)/%.o) + +LIBC_TINYMATH_A_CHECKS = \ + $(LIBC_TINYMATH_A).pkg \ + $(LIBC_TINYMATH_A_HDRS:%=o/$(MODE)/%.ok) + +LIBC_TINYMATH_A_DIRECTDEPS = \ + LIBC_STUBS \ + LIBC_NEXGEN32E + +LIBC_TINYMATH_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_TINYMATH_A_DIRECTDEPS),$($(x)))) + +$(LIBC_TINYMATH_A): \ + libc/tinymath/ \ + $(LIBC_TINYMATH_A).pkg \ + $(LIBC_TINYMATH_A_OBJS) + +$(LIBC_TINYMATH_A).pkg: \ + $(LIBC_TINYMATH_A_OBJS) \ + $(foreach x,$(LIBC_TINYMATH_A_DIRECTDEPS),$($(x)_A).pkg) + +LIBC_TINYMATH_LIBS = $(foreach x,$(LIBC_TINYMATH_ARTIFACTS),$($(x))) +LIBC_TINYMATH_HDRS = $(foreach x,$(LIBC_TINYMATH_ARTIFACTS),$($(x)_HDRS)) +LIBC_TINYMATH_SRCS = $(foreach x,$(LIBC_TINYMATH_ARTIFACTS),$($(x)_SRCS)) +LIBC_TINYMATH_CHECKS = $(foreach x,$(LIBC_TINYMATH_ARTIFACTS),$($(x)_CHECKS)) +LIBC_TINYMATH_OBJS = $(foreach x,$(LIBC_TINYMATH_ARTIFACTS),$($(x)_OBJS)) +LIBC_TINYMATH_CHECKS = $(LIBC_TINYMATH_HDRS:%=o/$(MODE)/%.ok) +$(LIBC_TINYMATH_OBJS): $(BUILD_FILES) libc/tinymath/tinymath.mk + +.PHONY: o/$(MODE)/libc/tinymath +o/$(MODE)/libc/tinymath: $(LIBC_TINYMATH_CHECKS) diff --git a/libc/tinymath/trunc.S b/libc/tinymath/trunc.S new file mode 100644 index 00000000..8117dfd5 --- /dev/null +++ b/libc/tinymath/trunc.S @@ -0,0 +1,53 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +/ Rounds to integer, toward zero. +/ +/ @param 𝑥 is double scalar in low half of %xmm0 +/ @return double scalar in low half of %xmm0 +/ @define trunc(𝑥+copysign(.5,𝑥)) +/ @see round(),rint(),nearbyint() +/ @see roundsd $_MM_FROUND_TO_ZERO|_MM_FROUND_NO_EXC,%xmm0,%xmm0 +tinymath_trunc: + .leafprologue + .profilable + movsd 3f(%rip),%xmm1 + movsd 2f(%rip),%xmm2 + andpd %xmm0,%xmm1 + comisd %xmm1,%xmm2 + jbe 1f + cvttsd2siq %xmm0,%rax + pxor %xmm0,%xmm0 + cvtsi2sdq %rax,%xmm0 +1: .leafepilogue + .endfn tinymath_trunc,globl + .alias tinymath_trunc,trunc + + .rodata.cst8 +2: .long 0 + .long 1127219200 + + .rodata.cst16 +3: .long 4294967295 + .long 2147483647 + .long 0 + .long 0 diff --git a/libc/tinymath/truncf.S b/libc/tinymath/truncf.S new file mode 100644 index 00000000..99ba9acf --- /dev/null +++ b/libc/tinymath/truncf.S @@ -0,0 +1,44 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_truncf: + .leafprologue + .profilable + movss 3f(%rip),%xmm1 + andps %xmm0,%xmm1 + movss 2f(%rip),%xmm2 + comiss %xmm1,%xmm2 + jbe 1f + cvttss2si %xmm0,%eax + pxor %xmm0,%xmm0 + cvtsi2ss %eax,%xmm0 +1: .leafepilogue + .endfn tinymath_truncf,globl + .alias tinymath_truncf,truncf + + .rodata.cst4 +2: .long 0x4b000000 + .rodata.cst16 +3: .long 0x7fffffff,0,0,0 + +/ TODO(jart) +/ roundss $_MM_FROUND_TO_ZERO|_MM_FROUND_NO_EXC,%xmm0,%xmm0 diff --git a/libc/tinymath/truncl.S b/libc/tinymath/truncl.S new file mode 100644 index 00000000..c70ff4e7 --- /dev/null +++ b/libc/tinymath/truncl.S @@ -0,0 +1,37 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +.yoink __FILE__ + +tinymath_truncl: + .profilable + sub $24,%rsp + fldt 32(%rsp) + fnstcw 14(%rsp) + movzwl 14(%rsp),%eax + or $12,%ah + mov %ax,12(%rsp) + fldcw 12(%rsp) + frndint + fldcw 14(%rsp) + add $24,%rsp + ret + .endfn tinymath_truncl,globl + .alias tinymath_truncl,truncl diff --git a/libc/typename.h b/libc/typename.h new file mode 100644 index 00000000..e6d7358d --- /dev/null +++ b/libc/typename.h @@ -0,0 +1,30 @@ +#ifndef COSMOPOLITAN_LIBC_TYPENAME_H_ +#define COSMOPOLITAN_LIBC_TYPENAME_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * Returns string identifier for scalar type of expression. + * + * @see TYPE_FMT() + */ +#define TYPE_NAME(X) \ + _Generic((X), long double \ + : "long double", double \ + : "double", float \ + : "float", char \ + : "char", signed char \ + : "signed char", unsigned char \ + : "unsigned char", short \ + : "short", unsigned short \ + : "unsigned short", int \ + : "int", unsigned \ + : "unsigned", long \ + : "long", unsigned long \ + : "unsigned long long", long long \ + : "long long", unsigned long long \ + : "unsigned long long") + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_TYPENAME_H_ */ diff --git a/libc/tzfile.h b/libc/tzfile.h new file mode 100644 index 00000000..0f054156 --- /dev/null +++ b/libc/tzfile.h @@ -0,0 +1,163 @@ +#ifndef TZFILE_H +#define TZFILE_H + +#define TM_ZONE tm_zone +#define TM_GMTOFF tm_gmtoff + +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson. +*/ + +/* +** Information about time zone files. +*/ + +#ifndef TZDIR +#define TZDIR "zip:usr/share/zoneinfo" +#endif + +#ifndef TZDEFAULT +#define TZDEFAULT "GST" +#endif + +#ifndef TZDEFRULES +#define TZDEFRULES "New_York" +#endif + +/* +** Each file begins with. . . +*/ + +#define TZ_MAGIC "TZif" + +struct tzhead { + char tzh_magic[4]; /* TZ_MAGIC */ + char tzh_version[1]; /* '\0' or '2' or '3' as of 2013 */ + char tzh_reserved[15]; /* reserved; must be zero */ + char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */ + char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ + char tzh_leapcnt[4]; /* coded number of leap seconds */ + char tzh_timecnt[4]; /* coded number of transition times */ + char tzh_typecnt[4]; /* coded number of local time types */ + char tzh_charcnt[4]; /* coded number of abbr. chars */ +}; + +/* +** . . .followed by. . . +** +** tzh_timecnt (char [4])s coded transition times a la time(2) +** tzh_timecnt (unsigned char)s types of local time starting at above +** tzh_typecnt repetitions of +** one (char [4]) coded UT offset in seconds +** one (unsigned char) used to set tm_isdst +** one (unsigned char) that's an abbreviation list index +** tzh_charcnt (char)s '\0'-terminated zone abbreviations +** tzh_leapcnt repetitions of +** one (char [4]) coded leap second transition times +** one (char [4]) total correction after above +** tzh_ttisstdcnt (char)s indexed by type; if 1, transition +** time is standard time, if 0, +** transition time is wall clock time +** if absent, transition times are +** assumed to be wall clock time +** tzh_ttisgmtcnt (char)s indexed by type; if 1, transition +** time is UT, if 0, +** transition time is local time +** if absent, transition times are +** assumed to be local time +*/ + +/* +** If tzh_version is '2' or greater, the above is followed by a second instance +** of tzhead and a second instance of the data in which each coded transition +** time uses 8 rather than 4 chars, +** then a POSIX-TZ-environment-variable-style string for use in handling +** instants after the last transition time stored in the file +** (with nothing between the newlines if there is no POSIX representation for +** such instants). +** +** If tz_version is '3' or greater, the above is extended as follows. +** First, the POSIX TZ string's hour offset may range from -167 +** through 167 as compared to the POSIX-required 0 through 24. +** Second, its DST start time may be January 1 at 00:00 and its stop +** time December 31 at 24:00 plus the difference between DST and +** standard time, indicating DST all year. +*/ + +/* +** In the current implementation, "tzset()" refuses to deal with files that +** exceed any of the limits below. +*/ + +#ifndef TZ_MAX_TIMES +#define TZ_MAX_TIMES 2000 +#endif /* !defined TZ_MAX_TIMES */ + +#ifndef TZ_MAX_TYPES +/* This must be at least 17 for Europe/Samara and Europe/Vilnius. */ +#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */ +#endif /* !defined TZ_MAX_TYPES */ + +#ifndef TZ_MAX_CHARS +#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */ + /* (limited by what unsigned chars can hold) */ +#endif /* !defined TZ_MAX_CHARS */ + +#ifndef TZ_MAX_LEAPS +#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */ +#endif /* !defined TZ_MAX_LEAPS */ + +#define SECSPERMIN 60 +#define MINSPERHOUR 60 +#define HOURSPERDAY 24 +#define DAYSPERWEEK 7 +#define DAYSPERNYEAR 365 +#define DAYSPERLYEAR 366 +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#define SECSPERDAY ((int_fast32_t)SECSPERHOUR * HOURSPERDAY) +#define MONSPERYEAR 12 + +#define TM_SUNDAY 0 +#define TM_MONDAY 1 +#define TM_TUESDAY 2 +#define TM_WEDNESDAY 3 +#define TM_THURSDAY 4 +#define TM_FRIDAY 5 +#define TM_SATURDAY 6 + +#define TM_JANUARY 0 +#define TM_FEBRUARY 1 +#define TM_MARCH 2 +#define TM_APRIL 3 +#define TM_MAY 4 +#define TM_JUNE 5 +#define TM_JULY 6 +#define TM_AUGUST 7 +#define TM_SEPTEMBER 8 +#define TM_OCTOBER 9 +#define TM_NOVEMBER 10 +#define TM_DECEMBER 11 + +#define TM_YEAR_BASE 1900 + +#define EPOCH_YEAR 1970 +#define EPOCH_WDAY TM_THURSDAY + +#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) + +/* +** Since everything in isleap is modulo 400 (or a factor of 400), we know that +** isleap(y) == isleap(y % 400) +** and so +** isleap(a + b) == isleap((a + b) % 400) +** or +** isleap(a + b) == isleap(a % 400 + b % 400) +** This is true even if % means modulo rather than Fortran remainder +** (which is allowed by C89 but not C99). +** We use this to avoid addition overflow problems. +*/ + +#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) + +#endif /* !defined TZFILE_H */ diff --git a/libc/unicode/eastasianwidth.txt b/libc/unicode/eastasianwidth.txt new file mode 100644 index 00000000..94d55d66 --- /dev/null +++ b/libc/unicode/eastasianwidth.txt @@ -0,0 +1,2473 @@ +# EastAsianWidth-12.1.0.txt +# Date: 2019-03-31, 22:01:58 GMT [KW, LI] +# © 2019 Unicode®, Inc. +# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# Unicode Character Database +# For documentation, see http://www.unicode.org/reports/tr44/ +# +# East_Asian_Width Property +# +# This file is an informative contributory data file in the +# Unicode Character Database. +# +# The format is two fields separated by a semicolon. +# Field 0: Unicode code point value or range of code point values +# Field 1: East_Asian_Width property, consisting of one of the following values: +# "A", "F", "H", "N", "Na", "W" +# - All code points, assigned or unassigned, that are not listed +# explicitly are given the value "N". +# - The unassigned code points in the following blocks default to "W": +# CJK Unified Ideographs Extension A: U+3400..U+4DBF +# CJK Unified Ideographs: U+4E00..U+9FFF +# CJK Compatibility Ideographs: U+F900..U+FAFF +# - All undesignated code points in Planes 2 and 3, whether inside or +# outside of allocated blocks, default to "W": +# Plane 2: U+20000..U+2FFFD +# Plane 3: U+30000..U+3FFFD +# +# Character ranges are specified as for other property files in the +# Unicode Character Database. +# +# For legacy reasons, there are no spaces before or after the semicolon +# which separates the two fields. The comments following the number sign +# "#" list the General_Category property value or the L& alias of the +# derived value LC, the Unicode character name or names, and, in lines +# with ranges of code points, the code point count in square brackets. +# +# For more information, see UAX #11: East Asian Width, +# at http://www.unicode.org/reports/tr11/ +# +# @missing: 0000..10FFFF; N +0000..001F;N # Cc [32] .. +0020;Na # Zs SPACE +0021..0023;Na # Po [3] EXCLAMATION MARK..NUMBER SIGN +0024;Na # Sc DOLLAR SIGN +0025..0027;Na # Po [3] PERCENT SIGN..APOSTROPHE +0028;Na # Ps LEFT PARENTHESIS +0029;Na # Pe RIGHT PARENTHESIS +002A;Na # Po ASTERISK +002B;Na # Sm PLUS SIGN +002C;Na # Po COMMA +002D;Na # Pd HYPHEN-MINUS +002E..002F;Na # Po [2] FULL STOP..SOLIDUS +0030..0039;Na # Nd [10] DIGIT ZERO..DIGIT NINE +003A..003B;Na # Po [2] COLON..SEMICOLON +003C..003E;Na # Sm [3] LESS-THAN SIGN..GREATER-THAN SIGN +003F..0040;Na # Po [2] QUESTION MARK..COMMERCIAL AT +0041..005A;Na # Lu [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z +005B;Na # Ps LEFT SQUARE BRACKET +005C;Na # Po REVERSE SOLIDUS +005D;Na # Pe RIGHT SQUARE BRACKET +005E;Na # Sk CIRCUMFLEX ACCENT +005F;Na # Pc LOW LINE +0060;Na # Sk GRAVE ACCENT +0061..007A;Na # Ll [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z +007B;Na # Ps LEFT CURLY BRACKET +007C;Na # Sm VERTICAL LINE +007D;Na # Pe RIGHT CURLY BRACKET +007E;Na # Sm TILDE +007F;N # Cc +0080..009F;N # Cc [32] .. +00A0;N # Zs NO-BREAK SPACE +00A1;A # Po INVERTED EXCLAMATION MARK +00A2..00A3;Na # Sc [2] CENT SIGN..POUND SIGN +00A4;A # Sc CURRENCY SIGN +00A5;Na # Sc YEN SIGN +00A6;Na # So BROKEN BAR +00A7;A # Po SECTION SIGN +00A8;A # Sk DIAERESIS +00A9;N # So COPYRIGHT SIGN +00AA;A # Lo FEMININE ORDINAL INDICATOR +00AB;N # Pi LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +00AC;Na # Sm NOT SIGN +00AD;A # Cf SOFT HYPHEN +00AE;A # So REGISTERED SIGN +00AF;Na # Sk MACRON +00B0;A # So DEGREE SIGN +00B1;A # Sm PLUS-MINUS SIGN +00B2..00B3;A # No [2] SUPERSCRIPT TWO..SUPERSCRIPT THREE +00B4;A # Sk ACUTE ACCENT +00B5;N # Ll MICRO SIGN +00B6..00B7;A # Po [2] PILCROW SIGN..MIDDLE DOT +00B8;A # Sk CEDILLA +00B9;A # No SUPERSCRIPT ONE +00BA;A # Lo MASCULINE ORDINAL INDICATOR +00BB;N # Pf RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +00BC..00BE;A # No [3] VULGAR FRACTION ONE QUARTER..VULGAR FRACTION THREE QUARTERS +00BF;A # Po INVERTED QUESTION MARK +00C0..00C5;N # Lu [6] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER A WITH RING ABOVE +00C6;A # Lu LATIN CAPITAL LETTER AE +00C7..00CF;N # Lu [9] LATIN CAPITAL LETTER C WITH CEDILLA..LATIN CAPITAL LETTER I WITH DIAERESIS +00D0;A # Lu LATIN CAPITAL LETTER ETH +00D1..00D6;N # Lu [6] LATIN CAPITAL LETTER N WITH TILDE..LATIN CAPITAL LETTER O WITH DIAERESIS +00D7;A # Sm MULTIPLICATION SIGN +00D8;A # Lu LATIN CAPITAL LETTER O WITH STROKE +00D9..00DD;N # Lu [5] LATIN CAPITAL LETTER U WITH GRAVE..LATIN CAPITAL LETTER Y WITH ACUTE +00DE..00E1;A # L& [4] LATIN CAPITAL LETTER THORN..LATIN SMALL LETTER A WITH ACUTE +00E2..00E5;N # Ll [4] LATIN SMALL LETTER A WITH CIRCUMFLEX..LATIN SMALL LETTER A WITH RING ABOVE +00E6;A # Ll LATIN SMALL LETTER AE +00E7;N # Ll LATIN SMALL LETTER C WITH CEDILLA +00E8..00EA;A # Ll [3] LATIN SMALL LETTER E WITH GRAVE..LATIN SMALL LETTER E WITH CIRCUMFLEX +00EB;N # Ll LATIN SMALL LETTER E WITH DIAERESIS +00EC..00ED;A # Ll [2] LATIN SMALL LETTER I WITH GRAVE..LATIN SMALL LETTER I WITH ACUTE +00EE..00EF;N # Ll [2] LATIN SMALL LETTER I WITH CIRCUMFLEX..LATIN SMALL LETTER I WITH DIAERESIS +00F0;A # Ll LATIN SMALL LETTER ETH +00F1;N # Ll LATIN SMALL LETTER N WITH TILDE +00F2..00F3;A # Ll [2] LATIN SMALL LETTER O WITH GRAVE..LATIN SMALL LETTER O WITH ACUTE +00F4..00F6;N # Ll [3] LATIN SMALL LETTER O WITH CIRCUMFLEX..LATIN SMALL LETTER O WITH DIAERESIS +00F7;A # Sm DIVISION SIGN +00F8..00FA;A # Ll [3] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER U WITH ACUTE +00FB;N # Ll LATIN SMALL LETTER U WITH CIRCUMFLEX +00FC;A # Ll LATIN SMALL LETTER U WITH DIAERESIS +00FD;N # Ll LATIN SMALL LETTER Y WITH ACUTE +00FE;A # Ll LATIN SMALL LETTER THORN +00FF;N # Ll LATIN SMALL LETTER Y WITH DIAERESIS +0100;N # Lu LATIN CAPITAL LETTER A WITH MACRON +0101;A # Ll LATIN SMALL LETTER A WITH MACRON +0102..0110;N # L& [15] LATIN CAPITAL LETTER A WITH BREVE..LATIN CAPITAL LETTER D WITH STROKE +0111;A # Ll LATIN SMALL LETTER D WITH STROKE +0112;N # Lu LATIN CAPITAL LETTER E WITH MACRON +0113;A # Ll LATIN SMALL LETTER E WITH MACRON +0114..011A;N # L& [7] LATIN CAPITAL LETTER E WITH BREVE..LATIN CAPITAL LETTER E WITH CARON +011B;A # Ll LATIN SMALL LETTER E WITH CARON +011C..0125;N # L& [10] LATIN CAPITAL LETTER G WITH CIRCUMFLEX..LATIN SMALL LETTER H WITH CIRCUMFLEX +0126..0127;A # L& [2] LATIN CAPITAL LETTER H WITH STROKE..LATIN SMALL LETTER H WITH STROKE +0128..012A;N # L& [3] LATIN CAPITAL LETTER I WITH TILDE..LATIN CAPITAL LETTER I WITH MACRON +012B;A # Ll LATIN SMALL LETTER I WITH MACRON +012C..0130;N # L& [5] LATIN CAPITAL LETTER I WITH BREVE..LATIN CAPITAL LETTER I WITH DOT ABOVE +0131..0133;A # L& [3] LATIN SMALL LETTER DOTLESS I..LATIN SMALL LIGATURE IJ +0134..0137;N # L& [4] LATIN CAPITAL LETTER J WITH CIRCUMFLEX..LATIN SMALL LETTER K WITH CEDILLA +0138;A # Ll LATIN SMALL LETTER KRA +0139..013E;N # L& [6] LATIN CAPITAL LETTER L WITH ACUTE..LATIN SMALL LETTER L WITH CARON +013F..0142;A # L& [4] LATIN CAPITAL LETTER L WITH MIDDLE DOT..LATIN SMALL LETTER L WITH STROKE +0143;N # Lu LATIN CAPITAL LETTER N WITH ACUTE +0144;A # Ll LATIN SMALL LETTER N WITH ACUTE +0145..0147;N # L& [3] LATIN CAPITAL LETTER N WITH CEDILLA..LATIN CAPITAL LETTER N WITH CARON +0148..014B;A # L& [4] LATIN SMALL LETTER N WITH CARON..LATIN SMALL LETTER ENG +014C;N # Lu LATIN CAPITAL LETTER O WITH MACRON +014D;A # Ll LATIN SMALL LETTER O WITH MACRON +014E..0151;N # L& [4] LATIN CAPITAL LETTER O WITH BREVE..LATIN SMALL LETTER O WITH DOUBLE ACUTE +0152..0153;A # L& [2] LATIN CAPITAL LIGATURE OE..LATIN SMALL LIGATURE OE +0154..0165;N # L& [18] LATIN CAPITAL LETTER R WITH ACUTE..LATIN SMALL LETTER T WITH CARON +0166..0167;A # L& [2] LATIN CAPITAL LETTER T WITH STROKE..LATIN SMALL LETTER T WITH STROKE +0168..016A;N # L& [3] LATIN CAPITAL LETTER U WITH TILDE..LATIN CAPITAL LETTER U WITH MACRON +016B;A # Ll LATIN SMALL LETTER U WITH MACRON +016C..017F;N # L& [20] LATIN CAPITAL LETTER U WITH BREVE..LATIN SMALL LETTER LONG S +0180..01BA;N # L& [59] LATIN SMALL LETTER B WITH STROKE..LATIN SMALL LETTER EZH WITH TAIL +01BB;N # Lo LATIN LETTER TWO WITH STROKE +01BC..01BF;N # L& [4] LATIN CAPITAL LETTER TONE FIVE..LATIN LETTER WYNN +01C0..01C3;N # Lo [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK +01C4..01CD;N # L& [10] LATIN CAPITAL LETTER DZ WITH CARON..LATIN CAPITAL LETTER A WITH CARON +01CE;A # Ll LATIN SMALL LETTER A WITH CARON +01CF;N # Lu LATIN CAPITAL LETTER I WITH CARON +01D0;A # Ll LATIN SMALL LETTER I WITH CARON +01D1;N # Lu LATIN CAPITAL LETTER O WITH CARON +01D2;A # Ll LATIN SMALL LETTER O WITH CARON +01D3;N # Lu LATIN CAPITAL LETTER U WITH CARON +01D4;A # Ll LATIN SMALL LETTER U WITH CARON +01D5;N # Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON +01D6;A # Ll LATIN SMALL LETTER U WITH DIAERESIS AND MACRON +01D7;N # Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE +01D8;A # Ll LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE +01D9;N # Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON +01DA;A # Ll LATIN SMALL LETTER U WITH DIAERESIS AND CARON +01DB;N # Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE +01DC;A # Ll LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE +01DD..024F;N # L& [115] LATIN SMALL LETTER TURNED E..LATIN SMALL LETTER Y WITH STROKE +0250;N # Ll LATIN SMALL LETTER TURNED A +0251;A # Ll LATIN SMALL LETTER ALPHA +0252..0260;N # Ll [15] LATIN SMALL LETTER TURNED ALPHA..LATIN SMALL LETTER G WITH HOOK +0261;A # Ll LATIN SMALL LETTER SCRIPT G +0262..0293;N # Ll [50] LATIN LETTER SMALL CAPITAL G..LATIN SMALL LETTER EZH WITH CURL +0294;N # Lo LATIN LETTER GLOTTAL STOP +0295..02AF;N # Ll [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL +02B0..02C1;N # Lm [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP +02C2..02C3;N # Sk [2] MODIFIER LETTER LEFT ARROWHEAD..MODIFIER LETTER RIGHT ARROWHEAD +02C4;A # Sk MODIFIER LETTER UP ARROWHEAD +02C5;N # Sk MODIFIER LETTER DOWN ARROWHEAD +02C6;N # Lm MODIFIER LETTER CIRCUMFLEX ACCENT +02C7;A # Lm CARON +02C8;N # Lm MODIFIER LETTER VERTICAL LINE +02C9..02CB;A # Lm [3] MODIFIER LETTER MACRON..MODIFIER LETTER GRAVE ACCENT +02CC;N # Lm MODIFIER LETTER LOW VERTICAL LINE +02CD;A # Lm MODIFIER LETTER LOW MACRON +02CE..02CF;N # Lm [2] MODIFIER LETTER LOW GRAVE ACCENT..MODIFIER LETTER LOW ACUTE ACCENT +02D0;A # Lm MODIFIER LETTER TRIANGULAR COLON +02D1;N # Lm MODIFIER LETTER HALF TRIANGULAR COLON +02D2..02D7;N # Sk [6] MODIFIER LETTER CENTRED RIGHT HALF RING..MODIFIER LETTER MINUS SIGN +02D8..02DB;A # Sk [4] BREVE..OGONEK +02DC;N # Sk SMALL TILDE +02DD;A # Sk DOUBLE ACUTE ACCENT +02DE;N # Sk MODIFIER LETTER RHOTIC HOOK +02DF;A # Sk MODIFIER LETTER CROSS ACCENT +02E0..02E4;N # Lm [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP +02E5..02EB;N # Sk [7] MODIFIER LETTER EXTRA-HIGH TONE BAR..MODIFIER LETTER YANG DEPARTING TONE MARK +02EC;N # Lm MODIFIER LETTER VOICING +02ED;N # Sk MODIFIER LETTER UNASPIRATED +02EE;N # Lm MODIFIER LETTER DOUBLE APOSTROPHE +02EF..02FF;N # Sk [17] MODIFIER LETTER LOW DOWN ARROWHEAD..MODIFIER LETTER LOW LEFT ARROW +0300..036F;A # Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X +0370..0373;N # L& [4] GREEK CAPITAL LETTER HETA..GREEK SMALL LETTER ARCHAIC SAMPI +0374;N # Lm GREEK NUMERAL SIGN +0375;N # Sk GREEK LOWER NUMERAL SIGN +0376..0377;N # L& [2] GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA..GREEK SMALL LETTER PAMPHYLIAN DIGAMMA +037A;N # Lm GREEK YPOGEGRAMMENI +037B..037D;N # Ll [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL +037E;N # Po GREEK QUESTION MARK +037F;N # Lu GREEK CAPITAL LETTER YOT +0384..0385;N # Sk [2] GREEK TONOS..GREEK DIALYTIKA TONOS +0386;N # Lu GREEK CAPITAL LETTER ALPHA WITH TONOS +0387;N # Po GREEK ANO TELEIA +0388..038A;N # Lu [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS +038C;N # Lu GREEK CAPITAL LETTER OMICRON WITH TONOS +038E..0390;N # L& [3] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +0391..03A1;A # Lu [17] GREEK CAPITAL LETTER ALPHA..GREEK CAPITAL LETTER RHO +03A3..03A9;A # Lu [7] GREEK CAPITAL LETTER SIGMA..GREEK CAPITAL LETTER OMEGA +03AA..03B0;N # L& [7] GREEK CAPITAL LETTER IOTA WITH DIALYTIKA..GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +03B1..03C1;A # Ll [17] GREEK SMALL LETTER ALPHA..GREEK SMALL LETTER RHO +03C2;N # Ll GREEK SMALL LETTER FINAL SIGMA +03C3..03C9;A # Ll [7] GREEK SMALL LETTER SIGMA..GREEK SMALL LETTER OMEGA +03CA..03F5;N # L& [44] GREEK SMALL LETTER IOTA WITH DIALYTIKA..GREEK LUNATE EPSILON SYMBOL +03F6;N # Sm GREEK REVERSED LUNATE EPSILON SYMBOL +03F7..03FF;N # L& [9] GREEK CAPITAL LETTER SHO..GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL +0400;N # Lu CYRILLIC CAPITAL LETTER IE WITH GRAVE +0401;A # Lu CYRILLIC CAPITAL LETTER IO +0402..040F;N # Lu [14] CYRILLIC CAPITAL LETTER DJE..CYRILLIC CAPITAL LETTER DZHE +0410..044F;A # L& [64] CYRILLIC CAPITAL LETTER A..CYRILLIC SMALL LETTER YA +0450;N # Ll CYRILLIC SMALL LETTER IE WITH GRAVE +0451;A # Ll CYRILLIC SMALL LETTER IO +0452..0481;N # L& [48] CYRILLIC SMALL LETTER DJE..CYRILLIC SMALL LETTER KOPPA +0482;N # So CYRILLIC THOUSANDS SIGN +0483..0487;N # Mn [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE +0488..0489;N # Me [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN +048A..04FF;N # L& [118] CYRILLIC CAPITAL LETTER SHORT I WITH TAIL..CYRILLIC SMALL LETTER HA WITH STROKE +0500..052F;N # L& [48] CYRILLIC CAPITAL LETTER KOMI DE..CYRILLIC SMALL LETTER EL WITH DESCENDER +0531..0556;N # Lu [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH +0559;N # Lm ARMENIAN MODIFIER LETTER LEFT HALF RING +055A..055F;N # Po [6] ARMENIAN APOSTROPHE..ARMENIAN ABBREVIATION MARK +0560..0588;N # Ll [41] ARMENIAN SMALL LETTER TURNED AYB..ARMENIAN SMALL LETTER YI WITH STROKE +0589;N # Po ARMENIAN FULL STOP +058A;N # Pd ARMENIAN HYPHEN +058D..058E;N # So [2] RIGHT-FACING ARMENIAN ETERNITY SIGN..LEFT-FACING ARMENIAN ETERNITY SIGN +058F;N # Sc ARMENIAN DRAM SIGN +0591..05BD;N # Mn [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG +05BE;N # Pd HEBREW PUNCTUATION MAQAF +05BF;N # Mn HEBREW POINT RAFE +05C0;N # Po HEBREW PUNCTUATION PASEQ +05C1..05C2;N # Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT +05C3;N # Po HEBREW PUNCTUATION SOF PASUQ +05C4..05C5;N # Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT +05C6;N # Po HEBREW PUNCTUATION NUN HAFUKHA +05C7;N # Mn HEBREW POINT QAMATS QATAN +05D0..05EA;N # Lo [27] HEBREW LETTER ALEF..HEBREW LETTER TAV +05EF..05F2;N # Lo [4] HEBREW YOD TRIANGLE..HEBREW LIGATURE YIDDISH DOUBLE YOD +05F3..05F4;N # Po [2] HEBREW PUNCTUATION GERESH..HEBREW PUNCTUATION GERSHAYIM +0600..0605;N # Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE +0606..0608;N # Sm [3] ARABIC-INDIC CUBE ROOT..ARABIC RAY +0609..060A;N # Po [2] ARABIC-INDIC PER MILLE SIGN..ARABIC-INDIC PER TEN THOUSAND SIGN +060B;N # Sc AFGHANI SIGN +060C..060D;N # Po [2] ARABIC COMMA..ARABIC DATE SEPARATOR +060E..060F;N # So [2] ARABIC POETIC VERSE SIGN..ARABIC SIGN MISRA +0610..061A;N # Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA +061B;N # Po ARABIC SEMICOLON +061C;N # Cf ARABIC LETTER MARK +061E..061F;N # Po [2] ARABIC TRIPLE DOT PUNCTUATION MARK..ARABIC QUESTION MARK +0620..063F;N # Lo [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE +0640;N # Lm ARABIC TATWEEL +0641..064A;N # Lo [10] ARABIC LETTER FEH..ARABIC LETTER YEH +064B..065F;N # Mn [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW +0660..0669;N # Nd [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE +066A..066D;N # Po [4] ARABIC PERCENT SIGN..ARABIC FIVE POINTED STAR +066E..066F;N # Lo [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF +0670;N # Mn ARABIC LETTER SUPERSCRIPT ALEF +0671..06D3;N # Lo [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE +06D4;N # Po ARABIC FULL STOP +06D5;N # Lo ARABIC LETTER AE +06D6..06DC;N # Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN +06DD;N # Cf ARABIC END OF AYAH +06DE;N # So ARABIC START OF RUB EL HIZB +06DF..06E4;N # Mn [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA +06E5..06E6;N # Lm [2] ARABIC SMALL WAW..ARABIC SMALL YEH +06E7..06E8;N # Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON +06E9;N # So ARABIC PLACE OF SAJDAH +06EA..06ED;N # Mn [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM +06EE..06EF;N # Lo [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V +06F0..06F9;N # Nd [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE +06FA..06FC;N # Lo [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW +06FD..06FE;N # So [2] ARABIC SIGN SINDHI AMPERSAND..ARABIC SIGN SINDHI POSTPOSITION MEN +06FF;N # Lo ARABIC LETTER HEH WITH INVERTED V +0700..070D;N # Po [14] SYRIAC END OF PARAGRAPH..SYRIAC HARKLEAN ASTERISCUS +070F;N # Cf SYRIAC ABBREVIATION MARK +0710;N # Lo SYRIAC LETTER ALAPH +0711;N # Mn SYRIAC LETTER SUPERSCRIPT ALAPH +0712..072F;N # Lo [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH +0730..074A;N # Mn [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH +074D..074F;N # Lo [3] SYRIAC LETTER SOGDIAN ZHAIN..SYRIAC LETTER SOGDIAN FE +0750..077F;N # Lo [48] ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS ABOVE +0780..07A5;N # Lo [38] THAANA LETTER HAA..THAANA LETTER WAAVU +07A6..07B0;N # Mn [11] THAANA ABAFILI..THAANA SUKUN +07B1;N # Lo THAANA LETTER NAA +07C0..07C9;N # Nd [10] NKO DIGIT ZERO..NKO DIGIT NINE +07CA..07EA;N # Lo [33] NKO LETTER A..NKO LETTER JONA RA +07EB..07F3;N # Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE +07F4..07F5;N # Lm [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE +07F6;N # So NKO SYMBOL OO DENNEN +07F7..07F9;N # Po [3] NKO SYMBOL GBAKURUNEN..NKO EXCLAMATION MARK +07FA;N # Lm NKO LAJANYALAN +07FD;N # Mn NKO DANTAYALAN +07FE..07FF;N # Sc [2] NKO DOROME SIGN..NKO TAMAN SIGN +0800..0815;N # Lo [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF +0816..0819;N # Mn [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH +081A;N # Lm SAMARITAN MODIFIER LETTER EPENTHETIC YUT +081B..0823;N # Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A +0824;N # Lm SAMARITAN MODIFIER LETTER SHORT A +0825..0827;N # Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U +0828;N # Lm SAMARITAN MODIFIER LETTER I +0829..082D;N # Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA +0830..083E;N # Po [15] SAMARITAN PUNCTUATION NEQUDAA..SAMARITAN PUNCTUATION ANNAAU +0840..0858;N # Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN +0859..085B;N # Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK +085E;N # Po MANDAIC PUNCTUATION +0860..086A;N # Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA +08A0..08B4;N # Lo [21] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER KAF WITH DOT BELOW +08B6..08BD;N # Lo [8] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER AFRICAN NOON +08D3..08E1;N # Mn [15] ARABIC SMALL LOW WAW..ARABIC SMALL HIGH SIGN SAFHA +08E2;N # Cf ARABIC DISPUTED END OF AYAH +08E3..08FF;N # Mn [29] ARABIC TURNED DAMMA BELOW..ARABIC MARK SIDEWAYS NOON GHUNNA +0900..0902;N # Mn [3] DEVANAGARI SIGN INVERTED CANDRABINDU..DEVANAGARI SIGN ANUSVARA +0903;N # Mc DEVANAGARI SIGN VISARGA +0904..0939;N # Lo [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA +093A;N # Mn DEVANAGARI VOWEL SIGN OE +093B;N # Mc DEVANAGARI VOWEL SIGN OOE +093C;N # Mn DEVANAGARI SIGN NUKTA +093D;N # Lo DEVANAGARI SIGN AVAGRAHA +093E..0940;N # Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II +0941..0948;N # Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI +0949..094C;N # Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU +094D;N # Mn DEVANAGARI SIGN VIRAMA +094E..094F;N # Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW +0950;N # Lo DEVANAGARI OM +0951..0957;N # Mn [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE +0958..0961;N # Lo [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL +0962..0963;N # Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL +0964..0965;N # Po [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA +0966..096F;N # Nd [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE +0970;N # Po DEVANAGARI ABBREVIATION SIGN +0971;N # Lm DEVANAGARI SIGN HIGH SPACING DOT +0972..097F;N # Lo [14] DEVANAGARI LETTER CANDRA A..DEVANAGARI LETTER BBA +0980;N # Lo BENGALI ANJI +0981;N # Mn BENGALI SIGN CANDRABINDU +0982..0983;N # Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA +0985..098C;N # Lo [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L +098F..0990;N # Lo [2] BENGALI LETTER E..BENGALI LETTER AI +0993..09A8;N # Lo [22] BENGALI LETTER O..BENGALI LETTER NA +09AA..09B0;N # Lo [7] BENGALI LETTER PA..BENGALI LETTER RA +09B2;N # Lo BENGALI LETTER LA +09B6..09B9;N # Lo [4] BENGALI LETTER SHA..BENGALI LETTER HA +09BC;N # Mn BENGALI SIGN NUKTA +09BD;N # Lo BENGALI SIGN AVAGRAHA +09BE..09C0;N # Mc [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II +09C1..09C4;N # Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR +09C7..09C8;N # Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI +09CB..09CC;N # Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU +09CD;N # Mn BENGALI SIGN VIRAMA +09CE;N # Lo BENGALI LETTER KHANDA TA +09D7;N # Mc BENGALI AU LENGTH MARK +09DC..09DD;N # Lo [2] BENGALI LETTER RRA..BENGALI LETTER RHA +09DF..09E1;N # Lo [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL +09E2..09E3;N # Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL +09E6..09EF;N # Nd [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE +09F0..09F1;N # Lo [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL +09F2..09F3;N # Sc [2] BENGALI RUPEE MARK..BENGALI RUPEE SIGN +09F4..09F9;N # No [6] BENGALI CURRENCY NUMERATOR ONE..BENGALI CURRENCY DENOMINATOR SIXTEEN +09FA;N # So BENGALI ISSHAR +09FB;N # Sc BENGALI GANDA MARK +09FC;N # Lo BENGALI LETTER VEDIC ANUSVARA +09FD;N # Po BENGALI ABBREVIATION SIGN +09FE;N # Mn BENGALI SANDHI MARK +0A01..0A02;N # Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI +0A03;N # Mc GURMUKHI SIGN VISARGA +0A05..0A0A;N # Lo [6] GURMUKHI LETTER A..GURMUKHI LETTER UU +0A0F..0A10;N # Lo [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI +0A13..0A28;N # Lo [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA +0A2A..0A30;N # Lo [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA +0A32..0A33;N # Lo [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA +0A35..0A36;N # Lo [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA +0A38..0A39;N # Lo [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA +0A3C;N # Mn GURMUKHI SIGN NUKTA +0A3E..0A40;N # Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II +0A41..0A42;N # Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU +0A47..0A48;N # Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI +0A4B..0A4D;N # Mn [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA +0A51;N # Mn GURMUKHI SIGN UDAAT +0A59..0A5C;N # Lo [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA +0A5E;N # Lo GURMUKHI LETTER FA +0A66..0A6F;N # Nd [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE +0A70..0A71;N # Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK +0A72..0A74;N # Lo [3] GURMUKHI IRI..GURMUKHI EK ONKAR +0A75;N # Mn GURMUKHI SIGN YAKASH +0A76;N # Po GURMUKHI ABBREVIATION SIGN +0A81..0A82;N # Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA +0A83;N # Mc GUJARATI SIGN VISARGA +0A85..0A8D;N # Lo [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E +0A8F..0A91;N # Lo [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O +0A93..0AA8;N # Lo [22] GUJARATI LETTER O..GUJARATI LETTER NA +0AAA..0AB0;N # Lo [7] GUJARATI LETTER PA..GUJARATI LETTER RA +0AB2..0AB3;N # Lo [2] GUJARATI LETTER LA..GUJARATI LETTER LLA +0AB5..0AB9;N # Lo [5] GUJARATI LETTER VA..GUJARATI LETTER HA +0ABC;N # Mn GUJARATI SIGN NUKTA +0ABD;N # Lo GUJARATI SIGN AVAGRAHA +0ABE..0AC0;N # Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II +0AC1..0AC5;N # Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E +0AC7..0AC8;N # Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI +0AC9;N # Mc GUJARATI VOWEL SIGN CANDRA O +0ACB..0ACC;N # Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU +0ACD;N # Mn GUJARATI SIGN VIRAMA +0AD0;N # Lo GUJARATI OM +0AE0..0AE1;N # Lo [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL +0AE2..0AE3;N # Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL +0AE6..0AEF;N # Nd [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE +0AF0;N # Po GUJARATI ABBREVIATION SIGN +0AF1;N # Sc GUJARATI RUPEE SIGN +0AF9;N # Lo GUJARATI LETTER ZHA +0AFA..0AFF;N # Mn [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE +0B01;N # Mn ORIYA SIGN CANDRABINDU +0B02..0B03;N # Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA +0B05..0B0C;N # Lo [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L +0B0F..0B10;N # Lo [2] ORIYA LETTER E..ORIYA LETTER AI +0B13..0B28;N # Lo [22] ORIYA LETTER O..ORIYA LETTER NA +0B2A..0B30;N # Lo [7] ORIYA LETTER PA..ORIYA LETTER RA +0B32..0B33;N # Lo [2] ORIYA LETTER LA..ORIYA LETTER LLA +0B35..0B39;N # Lo [5] ORIYA LETTER VA..ORIYA LETTER HA +0B3C;N # Mn ORIYA SIGN NUKTA +0B3D;N # Lo ORIYA SIGN AVAGRAHA +0B3E;N # Mc ORIYA VOWEL SIGN AA +0B3F;N # Mn ORIYA VOWEL SIGN I +0B40;N # Mc ORIYA VOWEL SIGN II +0B41..0B44;N # Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR +0B47..0B48;N # Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI +0B4B..0B4C;N # Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU +0B4D;N # Mn ORIYA SIGN VIRAMA +0B56;N # Mn ORIYA AI LENGTH MARK +0B57;N # Mc ORIYA AU LENGTH MARK +0B5C..0B5D;N # Lo [2] ORIYA LETTER RRA..ORIYA LETTER RHA +0B5F..0B61;N # Lo [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL +0B62..0B63;N # Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL +0B66..0B6F;N # Nd [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE +0B70;N # So ORIYA ISSHAR +0B71;N # Lo ORIYA LETTER WA +0B72..0B77;N # No [6] ORIYA FRACTION ONE QUARTER..ORIYA FRACTION THREE SIXTEENTHS +0B82;N # Mn TAMIL SIGN ANUSVARA +0B83;N # Lo TAMIL SIGN VISARGA +0B85..0B8A;N # Lo [6] TAMIL LETTER A..TAMIL LETTER UU +0B8E..0B90;N # Lo [3] TAMIL LETTER E..TAMIL LETTER AI +0B92..0B95;N # Lo [4] TAMIL LETTER O..TAMIL LETTER KA +0B99..0B9A;N # Lo [2] TAMIL LETTER NGA..TAMIL LETTER CA +0B9C;N # Lo TAMIL LETTER JA +0B9E..0B9F;N # Lo [2] TAMIL LETTER NYA..TAMIL LETTER TTA +0BA3..0BA4;N # Lo [2] TAMIL LETTER NNA..TAMIL LETTER TA +0BA8..0BAA;N # Lo [3] TAMIL LETTER NA..TAMIL LETTER PA +0BAE..0BB9;N # Lo [12] TAMIL LETTER MA..TAMIL LETTER HA +0BBE..0BBF;N # Mc [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I +0BC0;N # Mn TAMIL VOWEL SIGN II +0BC1..0BC2;N # Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU +0BC6..0BC8;N # Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI +0BCA..0BCC;N # Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU +0BCD;N # Mn TAMIL SIGN VIRAMA +0BD0;N # Lo TAMIL OM +0BD7;N # Mc TAMIL AU LENGTH MARK +0BE6..0BEF;N # Nd [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE +0BF0..0BF2;N # No [3] TAMIL NUMBER TEN..TAMIL NUMBER ONE THOUSAND +0BF3..0BF8;N # So [6] TAMIL DAY SIGN..TAMIL AS ABOVE SIGN +0BF9;N # Sc TAMIL RUPEE SIGN +0BFA;N # So TAMIL NUMBER SIGN +0C00;N # Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE +0C01..0C03;N # Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA +0C04;N # Mn TELUGU SIGN COMBINING ANUSVARA ABOVE +0C05..0C0C;N # Lo [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L +0C0E..0C10;N # Lo [3] TELUGU LETTER E..TELUGU LETTER AI +0C12..0C28;N # Lo [23] TELUGU LETTER O..TELUGU LETTER NA +0C2A..0C39;N # Lo [16] TELUGU LETTER PA..TELUGU LETTER HA +0C3D;N # Lo TELUGU SIGN AVAGRAHA +0C3E..0C40;N # Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II +0C41..0C44;N # Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR +0C46..0C48;N # Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI +0C4A..0C4D;N # Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA +0C55..0C56;N # Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK +0C58..0C5A;N # Lo [3] TELUGU LETTER TSA..TELUGU LETTER RRRA +0C60..0C61;N # Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL +0C62..0C63;N # Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL +0C66..0C6F;N # Nd [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE +0C77;N # Po TELUGU SIGN SIDDHAM +0C78..0C7E;N # No [7] TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR..TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR +0C7F;N # So TELUGU SIGN TUUMU +0C80;N # Lo KANNADA SIGN SPACING CANDRABINDU +0C81;N # Mn KANNADA SIGN CANDRABINDU +0C82..0C83;N # Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA +0C84;N # Po KANNADA SIGN SIDDHAM +0C85..0C8C;N # Lo [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L +0C8E..0C90;N # Lo [3] KANNADA LETTER E..KANNADA LETTER AI +0C92..0CA8;N # Lo [23] KANNADA LETTER O..KANNADA LETTER NA +0CAA..0CB3;N # Lo [10] KANNADA LETTER PA..KANNADA LETTER LLA +0CB5..0CB9;N # Lo [5] KANNADA LETTER VA..KANNADA LETTER HA +0CBC;N # Mn KANNADA SIGN NUKTA +0CBD;N # Lo KANNADA SIGN AVAGRAHA +0CBE;N # Mc KANNADA VOWEL SIGN AA +0CBF;N # Mn KANNADA VOWEL SIGN I +0CC0..0CC4;N # Mc [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR +0CC6;N # Mn KANNADA VOWEL SIGN E +0CC7..0CC8;N # Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI +0CCA..0CCB;N # Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO +0CCC..0CCD;N # Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA +0CD5..0CD6;N # Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK +0CDE;N # Lo KANNADA LETTER FA +0CE0..0CE1;N # Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL +0CE2..0CE3;N # Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL +0CE6..0CEF;N # Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE +0CF1..0CF2;N # Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA +0D00..0D01;N # Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU +0D02..0D03;N # Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA +0D05..0D0C;N # Lo [8] MALAYALAM LETTER A..MALAYALAM LETTER VOCALIC L +0D0E..0D10;N # Lo [3] MALAYALAM LETTER E..MALAYALAM LETTER AI +0D12..0D3A;N # Lo [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA +0D3B..0D3C;N # Mn [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA +0D3D;N # Lo MALAYALAM SIGN AVAGRAHA +0D3E..0D40;N # Mc [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II +0D41..0D44;N # Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR +0D46..0D48;N # Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI +0D4A..0D4C;N # Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU +0D4D;N # Mn MALAYALAM SIGN VIRAMA +0D4E;N # Lo MALAYALAM LETTER DOT REPH +0D4F;N # So MALAYALAM SIGN PARA +0D54..0D56;N # Lo [3] MALAYALAM LETTER CHILLU M..MALAYALAM LETTER CHILLU LLL +0D57;N # Mc MALAYALAM AU LENGTH MARK +0D58..0D5E;N # No [7] MALAYALAM FRACTION ONE ONE-HUNDRED-AND-SIXTIETH..MALAYALAM FRACTION ONE FIFTH +0D5F..0D61;N # Lo [3] MALAYALAM LETTER ARCHAIC II..MALAYALAM LETTER VOCALIC LL +0D62..0D63;N # Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL +0D66..0D6F;N # Nd [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE +0D70..0D78;N # No [9] MALAYALAM NUMBER TEN..MALAYALAM FRACTION THREE SIXTEENTHS +0D79;N # So MALAYALAM DATE MARK +0D7A..0D7F;N # Lo [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K +0D82..0D83;N # Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA +0D85..0D96;N # Lo [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA +0D9A..0DB1;N # Lo [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA +0DB3..0DBB;N # Lo [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA +0DBD;N # Lo SINHALA LETTER DANTAJA LAYANNA +0DC0..0DC6;N # Lo [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA +0DCA;N # Mn SINHALA SIGN AL-LAKUNA +0DCF..0DD1;N # Mc [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA +0DD2..0DD4;N # Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA +0DD6;N # Mn SINHALA VOWEL SIGN DIGA PAA-PILLA +0DD8..0DDF;N # Mc [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA +0DE6..0DEF;N # Nd [10] SINHALA LITH DIGIT ZERO..SINHALA LITH DIGIT NINE +0DF2..0DF3;N # Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA +0DF4;N # Po SINHALA PUNCTUATION KUNDDALIYA +0E01..0E30;N # Lo [48] THAI CHARACTER KO KAI..THAI CHARACTER SARA A +0E31;N # Mn THAI CHARACTER MAI HAN-AKAT +0E32..0E33;N # Lo [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM +0E34..0E3A;N # Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU +0E3F;N # Sc THAI CURRENCY SYMBOL BAHT +0E40..0E45;N # Lo [6] THAI CHARACTER SARA E..THAI CHARACTER LAKKHANGYAO +0E46;N # Lm THAI CHARACTER MAIYAMOK +0E47..0E4E;N # Mn [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN +0E4F;N # Po THAI CHARACTER FONGMAN +0E50..0E59;N # Nd [10] THAI DIGIT ZERO..THAI DIGIT NINE +0E5A..0E5B;N # Po [2] THAI CHARACTER ANGKHANKHU..THAI CHARACTER KHOMUT +0E81..0E82;N # Lo [2] LAO LETTER KO..LAO LETTER KHO SUNG +0E84;N # Lo LAO LETTER KHO TAM +0E86..0E8A;N # Lo [5] LAO LETTER PALI GHA..LAO LETTER SO TAM +0E8C..0EA3;N # Lo [24] LAO LETTER PALI JHA..LAO LETTER LO LING +0EA5;N # Lo LAO LETTER LO LOOT +0EA7..0EB0;N # Lo [10] LAO LETTER WO..LAO VOWEL SIGN A +0EB1;N # Mn LAO VOWEL SIGN MAI KAN +0EB2..0EB3;N # Lo [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM +0EB4..0EBC;N # Mn [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO +0EBD;N # Lo LAO SEMIVOWEL SIGN NYO +0EC0..0EC4;N # Lo [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI +0EC6;N # Lm LAO KO LA +0EC8..0ECD;N # Mn [6] LAO TONE MAI EK..LAO NIGGAHITA +0ED0..0ED9;N # Nd [10] LAO DIGIT ZERO..LAO DIGIT NINE +0EDC..0EDF;N # Lo [4] LAO HO NO..LAO LETTER KHMU NYO +0F00;N # Lo TIBETAN SYLLABLE OM +0F01..0F03;N # So [3] TIBETAN MARK GTER YIG MGO TRUNCATED A..TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA +0F04..0F12;N # Po [15] TIBETAN MARK INITIAL YIG MGO MDUN MA..TIBETAN MARK RGYA GRAM SHAD +0F13;N # So TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN +0F14;N # Po TIBETAN MARK GTER TSHEG +0F15..0F17;N # So [3] TIBETAN LOGOTYPE SIGN CHAD RTAGS..TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS +0F18..0F19;N # Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS +0F1A..0F1F;N # So [6] TIBETAN SIGN RDEL DKAR GCIG..TIBETAN SIGN RDEL DKAR RDEL NAG +0F20..0F29;N # Nd [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE +0F2A..0F33;N # No [10] TIBETAN DIGIT HALF ONE..TIBETAN DIGIT HALF ZERO +0F34;N # So TIBETAN MARK BSDUS RTAGS +0F35;N # Mn TIBETAN MARK NGAS BZUNG NYI ZLA +0F36;N # So TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN +0F37;N # Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS +0F38;N # So TIBETAN MARK CHE MGO +0F39;N # Mn TIBETAN MARK TSA -PHRU +0F3A;N # Ps TIBETAN MARK GUG RTAGS GYON +0F3B;N # Pe TIBETAN MARK GUG RTAGS GYAS +0F3C;N # Ps TIBETAN MARK ANG KHANG GYON +0F3D;N # Pe TIBETAN MARK ANG KHANG GYAS +0F3E..0F3F;N # Mc [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES +0F40..0F47;N # Lo [8] TIBETAN LETTER KA..TIBETAN LETTER JA +0F49..0F6C;N # Lo [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA +0F71..0F7E;N # Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO +0F7F;N # Mc TIBETAN SIGN RNAM BCAD +0F80..0F84;N # Mn [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA +0F85;N # Po TIBETAN MARK PALUTA +0F86..0F87;N # Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS +0F88..0F8C;N # Lo [5] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN INVERTED MCHU CAN +0F8D..0F97;N # Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA +0F99..0FBC;N # Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA +0FBE..0FC5;N # So [8] TIBETAN KU RU KHA..TIBETAN SYMBOL RDO RJE +0FC6;N # Mn TIBETAN SYMBOL PADMA GDAN +0FC7..0FCC;N # So [6] TIBETAN SYMBOL RDO RJE RGYA GRAM..TIBETAN SYMBOL NOR BU BZHI -KHYIL +0FCE..0FCF;N # So [2] TIBETAN SIGN RDEL NAG RDEL DKAR..TIBETAN SIGN RDEL NAG GSUM +0FD0..0FD4;N # Po [5] TIBETAN MARK BSKA- SHOG GI MGO RGYAN..TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA +0FD5..0FD8;N # So [4] RIGHT-FACING SVASTI SIGN..LEFT-FACING SVASTI SIGN WITH DOTS +0FD9..0FDA;N # Po [2] TIBETAN MARK LEADING MCHAN RTAGS..TIBETAN MARK TRAILING MCHAN RTAGS +1000..102A;N # Lo [43] MYANMAR LETTER KA..MYANMAR LETTER AU +102B..102C;N # Mc [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA +102D..1030;N # Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU +1031;N # Mc MYANMAR VOWEL SIGN E +1032..1037;N # Mn [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW +1038;N # Mc MYANMAR SIGN VISARGA +1039..103A;N # Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT +103B..103C;N # Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA +103D..103E;N # Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA +103F;N # Lo MYANMAR LETTER GREAT SA +1040..1049;N # Nd [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE +104A..104F;N # Po [6] MYANMAR SIGN LITTLE SECTION..MYANMAR SYMBOL GENITIVE +1050..1055;N # Lo [6] MYANMAR LETTER SHA..MYANMAR LETTER VOCALIC LL +1056..1057;N # Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR +1058..1059;N # Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL +105A..105D;N # Lo [4] MYANMAR LETTER MON NGA..MYANMAR LETTER MON BBE +105E..1060;N # Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA +1061;N # Lo MYANMAR LETTER SGAW KAREN SHA +1062..1064;N # Mc [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO +1065..1066;N # Lo [2] MYANMAR LETTER WESTERN PWO KAREN THA..MYANMAR LETTER WESTERN PWO KAREN PWA +1067..106D;N # Mc [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5 +106E..1070;N # Lo [3] MYANMAR LETTER EASTERN PWO KAREN NNA..MYANMAR LETTER EASTERN PWO KAREN GHWA +1071..1074;N # Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE +1075..1081;N # Lo [13] MYANMAR LETTER SHAN KA..MYANMAR LETTER SHAN HA +1082;N # Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA +1083..1084;N # Mc [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E +1085..1086;N # Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y +1087..108C;N # Mc [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3 +108D;N # Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE +108E;N # Lo MYANMAR LETTER RUMAI PALAUNG FA +108F;N # Mc MYANMAR SIGN RUMAI PALAUNG TONE-5 +1090..1099;N # Nd [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE +109A..109C;N # Mc [3] MYANMAR SIGN KHAMTI TONE-1..MYANMAR VOWEL SIGN AITON A +109D;N # Mn MYANMAR VOWEL SIGN AITON AI +109E..109F;N # So [2] MYANMAR SYMBOL SHAN ONE..MYANMAR SYMBOL SHAN EXCLAMATION +10A0..10C5;N # Lu [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE +10C7;N # Lu GEORGIAN CAPITAL LETTER YN +10CD;N # Lu GEORGIAN CAPITAL LETTER AEN +10D0..10FA;N # Ll [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN +10FB;N # Po GEORGIAN PARAGRAPH SEPARATOR +10FC;N # Lm MODIFIER LETTER GEORGIAN NAR +10FD..10FF;N # Ll [3] GEORGIAN LETTER AEN..GEORGIAN LETTER LABIAL SIGN +1100..115F;W # Lo [96] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG FILLER +1160..11FF;N # Lo [160] HANGUL JUNGSEONG FILLER..HANGUL JONGSEONG SSANGNIEUN +1200..1248;N # Lo [73] ETHIOPIC SYLLABLE HA..ETHIOPIC SYLLABLE QWA +124A..124D;N # Lo [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE +1250..1256;N # Lo [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO +1258;N # Lo ETHIOPIC SYLLABLE QHWA +125A..125D;N # Lo [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE +1260..1288;N # Lo [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA +128A..128D;N # Lo [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE +1290..12B0;N # Lo [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA +12B2..12B5;N # Lo [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE +12B8..12BE;N # Lo [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO +12C0;N # Lo ETHIOPIC SYLLABLE KXWA +12C2..12C5;N # Lo [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE +12C8..12D6;N # Lo [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O +12D8..1310;N # Lo [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA +1312..1315;N # Lo [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE +1318..135A;N # Lo [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA +135D..135F;N # Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK +1360..1368;N # Po [9] ETHIOPIC SECTION MARK..ETHIOPIC PARAGRAPH SEPARATOR +1369..137C;N # No [20] ETHIOPIC DIGIT ONE..ETHIOPIC NUMBER TEN THOUSAND +1380..138F;N # Lo [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE +1390..1399;N # So [10] ETHIOPIC TONAL MARK YIZET..ETHIOPIC TONAL MARK KURT +13A0..13F5;N # Lu [86] CHEROKEE LETTER A..CHEROKEE LETTER MV +13F8..13FD;N # Ll [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV +1400;N # Pd CANADIAN SYLLABICS HYPHEN +1401..166C;N # Lo [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA +166D;N # So CANADIAN SYLLABICS CHI SIGN +166E;N # Po CANADIAN SYLLABICS FULL STOP +166F..167F;N # Lo [17] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS BLACKFOOT W +1680;N # Zs OGHAM SPACE MARK +1681..169A;N # Lo [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH +169B;N # Ps OGHAM FEATHER MARK +169C;N # Pe OGHAM REVERSED FEATHER MARK +16A0..16EA;N # Lo [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X +16EB..16ED;N # Po [3] RUNIC SINGLE PUNCTUATION..RUNIC CROSS PUNCTUATION +16EE..16F0;N # Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL +16F1..16F8;N # Lo [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC +1700..170C;N # Lo [13] TAGALOG LETTER A..TAGALOG LETTER YA +170E..1711;N # Lo [4] TAGALOG LETTER LA..TAGALOG LETTER HA +1712..1714;N # Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA +1720..1731;N # Lo [18] HANUNOO LETTER A..HANUNOO LETTER HA +1732..1734;N # Mn [3] HANUNOO VOWEL SIGN I..HANUNOO SIGN PAMUDPOD +1735..1736;N # Po [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION +1740..1751;N # Lo [18] BUHID LETTER A..BUHID LETTER HA +1752..1753;N # Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U +1760..176C;N # Lo [13] TAGBANWA LETTER A..TAGBANWA LETTER YA +176E..1770;N # Lo [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA +1772..1773;N # Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U +1780..17B3;N # Lo [52] KHMER LETTER KA..KHMER INDEPENDENT VOWEL QAU +17B4..17B5;N # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA +17B6;N # Mc KHMER VOWEL SIGN AA +17B7..17BD;N # Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA +17BE..17C5;N # Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU +17C6;N # Mn KHMER SIGN NIKAHIT +17C7..17C8;N # Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU +17C9..17D3;N # Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT +17D4..17D6;N # Po [3] KHMER SIGN KHAN..KHMER SIGN CAMNUC PII KUUH +17D7;N # Lm KHMER SIGN LEK TOO +17D8..17DA;N # Po [3] KHMER SIGN BEYYAL..KHMER SIGN KOOMUUT +17DB;N # Sc KHMER CURRENCY SYMBOL RIEL +17DC;N # Lo KHMER SIGN AVAKRAHASANYA +17DD;N # Mn KHMER SIGN ATTHACAN +17E0..17E9;N # Nd [10] KHMER DIGIT ZERO..KHMER DIGIT NINE +17F0..17F9;N # No [10] KHMER SYMBOL LEK ATTAK SON..KHMER SYMBOL LEK ATTAK PRAM-BUON +1800..1805;N # Po [6] MONGOLIAN BIRGA..MONGOLIAN FOUR DOTS +1806;N # Pd MONGOLIAN TODO SOFT HYPHEN +1807..180A;N # Po [4] MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER..MONGOLIAN NIRUGU +180B..180D;N # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE +180E;N # Cf MONGOLIAN VOWEL SEPARATOR +1810..1819;N # Nd [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE +1820..1842;N # Lo [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI +1843;N # Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN +1844..1878;N # Lo [53] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER CHA WITH TWO DOTS +1880..1884;N # Lo [5] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI INVERTED UBADAMA +1885..1886;N # Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA +1887..18A8;N # Lo [34] MONGOLIAN LETTER ALI GALI A..MONGOLIAN LETTER MANCHU ALI GALI BHA +18A9;N # Mn MONGOLIAN LETTER ALI GALI DAGALGA +18AA;N # Lo MONGOLIAN LETTER MANCHU ALI GALI LHA +18B0..18F5;N # Lo [70] CANADIAN SYLLABICS OY..CANADIAN SYLLABICS CARRIER DENTAL S +1900..191E;N # Lo [31] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER TRA +1920..1922;N # Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U +1923..1926;N # Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU +1927..1928;N # Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O +1929..192B;N # Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA +1930..1931;N # Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA +1932;N # Mn LIMBU SMALL LETTER ANUSVARA +1933..1938;N # Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA +1939..193B;N # Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I +1940;N # So LIMBU SIGN LOO +1944..1945;N # Po [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK +1946..194F;N # Nd [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE +1950..196D;N # Lo [30] TAI LE LETTER KA..TAI LE LETTER AI +1970..1974;N # Lo [5] TAI LE LETTER TONE-2..TAI LE LETTER TONE-6 +1980..19AB;N # Lo [44] NEW TAI LUE LETTER HIGH QA..NEW TAI LUE LETTER LOW SUA +19B0..19C9;N # Lo [26] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE TONE MARK-2 +19D0..19D9;N # Nd [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE +19DA;N # No NEW TAI LUE THAM DIGIT ONE +19DE..19DF;N # So [2] NEW TAI LUE SIGN LAE..NEW TAI LUE SIGN LAEV +19E0..19FF;N # So [32] KHMER SYMBOL PATHAMASAT..KHMER SYMBOL DAP-PRAM ROC +1A00..1A16;N # Lo [23] BUGINESE LETTER KA..BUGINESE LETTER HA +1A17..1A18;N # Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U +1A19..1A1A;N # Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O +1A1B;N # Mn BUGINESE VOWEL SIGN AE +1A1E..1A1F;N # Po [2] BUGINESE PALLAWA..BUGINESE END OF SECTION +1A20..1A54;N # Lo [53] TAI THAM LETTER HIGH KA..TAI THAM LETTER GREAT SA +1A55;N # Mc TAI THAM CONSONANT SIGN MEDIAL RA +1A56;N # Mn TAI THAM CONSONANT SIGN MEDIAL LA +1A57;N # Mc TAI THAM CONSONANT SIGN LA TANG LAI +1A58..1A5E;N # Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA +1A60;N # Mn TAI THAM SIGN SAKOT +1A61;N # Mc TAI THAM VOWEL SIGN A +1A62;N # Mn TAI THAM VOWEL SIGN MAI SAT +1A63..1A64;N # Mc [2] TAI THAM VOWEL SIGN AA..TAI THAM VOWEL SIGN TALL AA +1A65..1A6C;N # Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW +1A6D..1A72;N # Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI +1A73..1A7C;N # Mn [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN +1A7F;N # Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT +1A80..1A89;N # Nd [10] TAI THAM HORA DIGIT ZERO..TAI THAM HORA DIGIT NINE +1A90..1A99;N # Nd [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE +1AA0..1AA6;N # Po [7] TAI THAM SIGN WIANG..TAI THAM SIGN REVERSED ROTATED RANA +1AA7;N # Lm TAI THAM SIGN MAI YAMOK +1AA8..1AAD;N # Po [6] TAI THAM SIGN KAAN..TAI THAM SIGN CAANG +1AB0..1ABD;N # Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW +1ABE;N # Me COMBINING PARENTHESES OVERLAY +1B00..1B03;N # Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG +1B04;N # Mc BALINESE SIGN BISAH +1B05..1B33;N # Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA +1B34;N # Mn BALINESE SIGN REREKAN +1B35;N # Mc BALINESE VOWEL SIGN TEDUNG +1B36..1B3A;N # Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA +1B3B;N # Mc BALINESE VOWEL SIGN RA REPA TEDUNG +1B3C;N # Mn BALINESE VOWEL SIGN LA LENGA +1B3D..1B41;N # Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG +1B42;N # Mn BALINESE VOWEL SIGN PEPET +1B43..1B44;N # Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG +1B45..1B4B;N # Lo [7] BALINESE LETTER KAF SASAK..BALINESE LETTER ASYURA SASAK +1B50..1B59;N # Nd [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE +1B5A..1B60;N # Po [7] BALINESE PANTI..BALINESE PAMENENG +1B61..1B6A;N # So [10] BALINESE MUSICAL SYMBOL DONG..BALINESE MUSICAL SYMBOL DANG GEDE +1B6B..1B73;N # Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG +1B74..1B7C;N # So [9] BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG..BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING +1B80..1B81;N # Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR +1B82;N # Mc SUNDANESE SIGN PANGWISAD +1B83..1BA0;N # Lo [30] SUNDANESE LETTER A..SUNDANESE LETTER HA +1BA1;N # Mc SUNDANESE CONSONANT SIGN PAMINGKAL +1BA2..1BA5;N # Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU +1BA6..1BA7;N # Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG +1BA8..1BA9;N # Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG +1BAA;N # Mc SUNDANESE SIGN PAMAAEH +1BAB..1BAD;N # Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA +1BAE..1BAF;N # Lo [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA +1BB0..1BB9;N # Nd [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE +1BBA..1BBF;N # Lo [6] SUNDANESE AVAGRAHA..SUNDANESE LETTER FINAL M +1BC0..1BE5;N # Lo [38] BATAK LETTER A..BATAK LETTER U +1BE6;N # Mn BATAK SIGN TOMPI +1BE7;N # Mc BATAK VOWEL SIGN E +1BE8..1BE9;N # Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE +1BEA..1BEC;N # Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O +1BED;N # Mn BATAK VOWEL SIGN KARO O +1BEE;N # Mc BATAK VOWEL SIGN U +1BEF..1BF1;N # Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H +1BF2..1BF3;N # Mc [2] BATAK PANGOLAT..BATAK PANONGONAN +1BFC..1BFF;N # Po [4] BATAK SYMBOL BINDU NA METEK..BATAK SYMBOL BINDU PANGOLAT +1C00..1C23;N # Lo [36] LEPCHA LETTER KA..LEPCHA LETTER A +1C24..1C2B;N # Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU +1C2C..1C33;N # Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T +1C34..1C35;N # Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG +1C36..1C37;N # Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA +1C3B..1C3F;N # Po [5] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION TSHOOK +1C40..1C49;N # Nd [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE +1C4D..1C4F;N # Lo [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA +1C50..1C59;N # Nd [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE +1C5A..1C77;N # Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH +1C78..1C7D;N # Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD +1C7E..1C7F;N # Po [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD +1C80..1C88;N # Ll [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK +1C90..1CBA;N # Lu [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN +1CBD..1CBF;N # Lu [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN +1CC0..1CC7;N # Po [8] SUNDANESE PUNCTUATION BINDU SURYA..SUNDANESE PUNCTUATION BINDU BA SATANGA +1CD0..1CD2;N # Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA +1CD3;N # Po VEDIC SIGN NIHSHVASA +1CD4..1CE0;N # Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA +1CE1;N # Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA +1CE2..1CE8;N # Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL +1CE9..1CEC;N # Lo [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL +1CED;N # Mn VEDIC SIGN TIRYAK +1CEE..1CF3;N # Lo [6] VEDIC SIGN HEXIFORM LONG ANUSVARA..VEDIC SIGN ROTATED ARDHAVISARGA +1CF4;N # Mn VEDIC TONE CANDRA ABOVE +1CF5..1CF6;N # Lo [2] VEDIC SIGN JIHVAMULIYA..VEDIC SIGN UPADHMANIYA +1CF7;N # Mc VEDIC SIGN ATIKRAMA +1CF8..1CF9;N # Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE +1CFA;N # Lo VEDIC SIGN DOUBLE ANUSVARA ANTARGOMUKHA +1D00..1D2B;N # Ll [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL +1D2C..1D6A;N # Lm [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI +1D6B..1D77;N # Ll [13] LATIN SMALL LETTER UE..LATIN SMALL LETTER TURNED G +1D78;N # Lm MODIFIER LETTER CYRILLIC EN +1D79..1D7F;N # Ll [7] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER UPSILON WITH STROKE +1D80..1D9A;N # Ll [27] LATIN SMALL LETTER B WITH PALATAL HOOK..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK +1D9B..1DBF;N # Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA +1DC0..1DF9;N # Mn [58] COMBINING DOTTED GRAVE ACCENT..COMBINING WIDE INVERTED BRIDGE BELOW +1DFB..1DFF;N # Mn [5] COMBINING DELETION MARK..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW +1E00..1EFF;N # L& [256] LATIN CAPITAL LETTER A WITH RING BELOW..LATIN SMALL LETTER Y WITH LOOP +1F00..1F15;N # L& [22] GREEK SMALL LETTER ALPHA WITH PSILI..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA +1F18..1F1D;N # Lu [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA +1F20..1F45;N # L& [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA +1F48..1F4D;N # Lu [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA +1F50..1F57;N # Ll [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI +1F59;N # Lu GREEK CAPITAL LETTER UPSILON WITH DASIA +1F5B;N # Lu GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA +1F5D;N # Lu GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA +1F5F..1F7D;N # L& [31] GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI..GREEK SMALL LETTER OMEGA WITH OXIA +1F80..1FB4;N # L& [53] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI +1FB6..1FBC;N # L& [7] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI +1FBD;N # Sk GREEK KORONIS +1FBE;N # Ll GREEK PROSGEGRAMMENI +1FBF..1FC1;N # Sk [3] GREEK PSILI..GREEK DIALYTIKA AND PERISPOMENI +1FC2..1FC4;N # Ll [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI +1FC6..1FCC;N # L& [7] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI +1FCD..1FCF;N # Sk [3] GREEK PSILI AND VARIA..GREEK PSILI AND PERISPOMENI +1FD0..1FD3;N # Ll [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA +1FD6..1FDB;N # L& [6] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK CAPITAL LETTER IOTA WITH OXIA +1FDD..1FDF;N # Sk [3] GREEK DASIA AND VARIA..GREEK DASIA AND PERISPOMENI +1FE0..1FEC;N # L& [13] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA +1FED..1FEF;N # Sk [3] GREEK DIALYTIKA AND VARIA..GREEK VARIA +1FF2..1FF4;N # Ll [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI +1FF6..1FFC;N # L& [7] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI +1FFD..1FFE;N # Sk [2] GREEK OXIA..GREEK DASIA +2000..200A;N # Zs [11] EN QUAD..HAIR SPACE +200B..200F;N # Cf [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK +2010;A # Pd HYPHEN +2011..2012;N # Pd [2] NON-BREAKING HYPHEN..FIGURE DASH +2013..2015;A # Pd [3] EN DASH..HORIZONTAL BAR +2016;A # Po DOUBLE VERTICAL LINE +2017;N # Po DOUBLE LOW LINE +2018;A # Pi LEFT SINGLE QUOTATION MARK +2019;A # Pf RIGHT SINGLE QUOTATION MARK +201A;N # Ps SINGLE LOW-9 QUOTATION MARK +201B;N # Pi SINGLE HIGH-REVERSED-9 QUOTATION MARK +201C;A # Pi LEFT DOUBLE QUOTATION MARK +201D;A # Pf RIGHT DOUBLE QUOTATION MARK +201E;N # Ps DOUBLE LOW-9 QUOTATION MARK +201F;N # Pi DOUBLE HIGH-REVERSED-9 QUOTATION MARK +2020..2022;A # Po [3] DAGGER..BULLET +2023;N # Po TRIANGULAR BULLET +2024..2027;A # Po [4] ONE DOT LEADER..HYPHENATION POINT +2028;N # Zl LINE SEPARATOR +2029;N # Zp PARAGRAPH SEPARATOR +202A..202E;N # Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE +202F;N # Zs NARROW NO-BREAK SPACE +2030;A # Po PER MILLE SIGN +2031;N # Po PER TEN THOUSAND SIGN +2032..2033;A # Po [2] PRIME..DOUBLE PRIME +2034;N # Po TRIPLE PRIME +2035;A # Po REVERSED PRIME +2036..2038;N # Po [3] REVERSED DOUBLE PRIME..CARET +2039;N # Pi SINGLE LEFT-POINTING ANGLE QUOTATION MARK +203A;N # Pf SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +203B;A # Po REFERENCE MARK +203C..203D;N # Po [2] DOUBLE EXCLAMATION MARK..INTERROBANG +203E;A # Po OVERLINE +203F..2040;N # Pc [2] UNDERTIE..CHARACTER TIE +2041..2043;N # Po [3] CARET INSERTION POINT..HYPHEN BULLET +2044;N # Sm FRACTION SLASH +2045;N # Ps LEFT SQUARE BRACKET WITH QUILL +2046;N # Pe RIGHT SQUARE BRACKET WITH QUILL +2047..2051;N # Po [11] DOUBLE QUESTION MARK..TWO ASTERISKS ALIGNED VERTICALLY +2052;N # Sm COMMERCIAL MINUS SIGN +2053;N # Po SWUNG DASH +2054;N # Pc INVERTED UNDERTIE +2055..205E;N # Po [10] FLOWER PUNCTUATION MARK..VERTICAL FOUR DOTS +205F;N # Zs MEDIUM MATHEMATICAL SPACE +2060..2064;N # Cf [5] WORD JOINER..INVISIBLE PLUS +2066..206F;N # Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES +2070;N # No SUPERSCRIPT ZERO +2071;N # Lm SUPERSCRIPT LATIN SMALL LETTER I +2074;A # No SUPERSCRIPT FOUR +2075..2079;N # No [5] SUPERSCRIPT FIVE..SUPERSCRIPT NINE +207A..207C;N # Sm [3] SUPERSCRIPT PLUS SIGN..SUPERSCRIPT EQUALS SIGN +207D;N # Ps SUPERSCRIPT LEFT PARENTHESIS +207E;N # Pe SUPERSCRIPT RIGHT PARENTHESIS +207F;A # Lm SUPERSCRIPT LATIN SMALL LETTER N +2080;N # No SUBSCRIPT ZERO +2081..2084;A # No [4] SUBSCRIPT ONE..SUBSCRIPT FOUR +2085..2089;N # No [5] SUBSCRIPT FIVE..SUBSCRIPT NINE +208A..208C;N # Sm [3] SUBSCRIPT PLUS SIGN..SUBSCRIPT EQUALS SIGN +208D;N # Ps SUBSCRIPT LEFT PARENTHESIS +208E;N # Pe SUBSCRIPT RIGHT PARENTHESIS +2090..209C;N # Lm [13] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER T +20A0..20A8;N # Sc [9] EURO-CURRENCY SIGN..RUPEE SIGN +20A9;H # Sc WON SIGN +20AA..20AB;N # Sc [2] NEW SHEQEL SIGN..DONG SIGN +20AC;A # Sc EURO SIGN +20AD..20BF;N # Sc [19] KIP SIGN..BITCOIN SIGN +20D0..20DC;N # Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE +20DD..20E0;N # Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH +20E1;N # Mn COMBINING LEFT RIGHT ARROW ABOVE +20E2..20E4;N # Me [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE +20E5..20F0;N # Mn [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE +2100..2101;N # So [2] ACCOUNT OF..ADDRESSED TO THE SUBJECT +2102;N # Lu DOUBLE-STRUCK CAPITAL C +2103;A # So DEGREE CELSIUS +2104;N # So CENTRE LINE SYMBOL +2105;A # So CARE OF +2106;N # So CADA UNA +2107;N # Lu EULER CONSTANT +2108;N # So SCRUPLE +2109;A # So DEGREE FAHRENHEIT +210A..2112;N # L& [9] SCRIPT SMALL G..SCRIPT CAPITAL L +2113;A # Ll SCRIPT SMALL L +2114;N # So L B BAR SYMBOL +2115;N # Lu DOUBLE-STRUCK CAPITAL N +2116;A # So NUMERO SIGN +2117;N # So SOUND RECORDING COPYRIGHT +2118;N # Sm SCRIPT CAPITAL P +2119..211D;N # Lu [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R +211E..2120;N # So [3] PRESCRIPTION TAKE..SERVICE MARK +2121..2122;A # So [2] TELEPHONE SIGN..TRADE MARK SIGN +2123;N # So VERSICLE +2124;N # Lu DOUBLE-STRUCK CAPITAL Z +2125;N # So OUNCE SIGN +2126;A # Lu OHM SIGN +2127;N # So INVERTED OHM SIGN +2128;N # Lu BLACK-LETTER CAPITAL Z +2129;N # So TURNED GREEK SMALL LETTER IOTA +212A;N # Lu KELVIN SIGN +212B;A # Lu ANGSTROM SIGN +212C..212D;N # Lu [2] SCRIPT CAPITAL B..BLACK-LETTER CAPITAL C +212E;N # So ESTIMATED SYMBOL +212F..2134;N # L& [6] SCRIPT SMALL E..SCRIPT SMALL O +2135..2138;N # Lo [4] ALEF SYMBOL..DALET SYMBOL +2139;N # Ll INFORMATION SOURCE +213A..213B;N # So [2] ROTATED CAPITAL Q..FACSIMILE SIGN +213C..213F;N # L& [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI +2140..2144;N # Sm [5] DOUBLE-STRUCK N-ARY SUMMATION..TURNED SANS-SERIF CAPITAL Y +2145..2149;N # L& [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J +214A;N # So PROPERTY LINE +214B;N # Sm TURNED AMPERSAND +214C..214D;N # So [2] PER SIGN..AKTIESELSKAB +214E;N # Ll TURNED SMALL F +214F;N # So SYMBOL FOR SAMARITAN SOURCE +2150..2152;N # No [3] VULGAR FRACTION ONE SEVENTH..VULGAR FRACTION ONE TENTH +2153..2154;A # No [2] VULGAR FRACTION ONE THIRD..VULGAR FRACTION TWO THIRDS +2155..215A;N # No [6] VULGAR FRACTION ONE FIFTH..VULGAR FRACTION FIVE SIXTHS +215B..215E;A # No [4] VULGAR FRACTION ONE EIGHTH..VULGAR FRACTION SEVEN EIGHTHS +215F;N # No FRACTION NUMERATOR ONE +2160..216B;A # Nl [12] ROMAN NUMERAL ONE..ROMAN NUMERAL TWELVE +216C..216F;N # Nl [4] ROMAN NUMERAL FIFTY..ROMAN NUMERAL ONE THOUSAND +2170..2179;A # Nl [10] SMALL ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL TEN +217A..2182;N # Nl [9] SMALL ROMAN NUMERAL ELEVEN..ROMAN NUMERAL TEN THOUSAND +2183..2184;N # L& [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C +2185..2188;N # Nl [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND +2189;A # No VULGAR FRACTION ZERO THIRDS +218A..218B;N # So [2] TURNED DIGIT TWO..TURNED DIGIT THREE +2190..2194;A # Sm [5] LEFTWARDS ARROW..LEFT RIGHT ARROW +2195..2199;A # So [5] UP DOWN ARROW..SOUTH WEST ARROW +219A..219B;N # Sm [2] LEFTWARDS ARROW WITH STROKE..RIGHTWARDS ARROW WITH STROKE +219C..219F;N # So [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW +21A0;N # Sm RIGHTWARDS TWO HEADED ARROW +21A1..21A2;N # So [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL +21A3;N # Sm RIGHTWARDS ARROW WITH TAIL +21A4..21A5;N # So [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR +21A6;N # Sm RIGHTWARDS ARROW FROM BAR +21A7..21AD;N # So [7] DOWNWARDS ARROW FROM BAR..LEFT RIGHT WAVE ARROW +21AE;N # Sm LEFT RIGHT ARROW WITH STROKE +21AF..21B7;N # So [9] DOWNWARDS ZIGZAG ARROW..CLOCKWISE TOP SEMICIRCLE ARROW +21B8..21B9;A # So [2] NORTH WEST ARROW TO LONG BAR..LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR +21BA..21CD;N # So [20] ANTICLOCKWISE OPEN CIRCLE ARROW..LEFTWARDS DOUBLE ARROW WITH STROKE +21CE..21CF;N # Sm [2] LEFT RIGHT DOUBLE ARROW WITH STROKE..RIGHTWARDS DOUBLE ARROW WITH STROKE +21D0..21D1;N # So [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW +21D2;A # Sm RIGHTWARDS DOUBLE ARROW +21D3;N # So DOWNWARDS DOUBLE ARROW +21D4;A # Sm LEFT RIGHT DOUBLE ARROW +21D5..21E6;N # So [18] UP DOWN DOUBLE ARROW..LEFTWARDS WHITE ARROW +21E7;A # So UPWARDS WHITE ARROW +21E8..21F3;N # So [12] RIGHTWARDS WHITE ARROW..UP DOWN WHITE ARROW +21F4..21FF;N # Sm [12] RIGHT ARROW WITH SMALL CIRCLE..LEFT RIGHT OPEN-HEADED ARROW +2200;A # Sm FOR ALL +2201;N # Sm COMPLEMENT +2202..2203;A # Sm [2] PARTIAL DIFFERENTIAL..THERE EXISTS +2204..2206;N # Sm [3] THERE DOES NOT EXIST..INCREMENT +2207..2208;A # Sm [2] NABLA..ELEMENT OF +2209..220A;N # Sm [2] NOT AN ELEMENT OF..SMALL ELEMENT OF +220B;A # Sm CONTAINS AS MEMBER +220C..220E;N # Sm [3] DOES NOT CONTAIN AS MEMBER..END OF PROOF +220F;A # Sm N-ARY PRODUCT +2210;N # Sm N-ARY COPRODUCT +2211;A # Sm N-ARY SUMMATION +2212..2214;N # Sm [3] MINUS SIGN..DOT PLUS +2215;A # Sm DIVISION SLASH +2216..2219;N # Sm [4] SET MINUS..BULLET OPERATOR +221A;A # Sm SQUARE ROOT +221B..221C;N # Sm [2] CUBE ROOT..FOURTH ROOT +221D..2220;A # Sm [4] PROPORTIONAL TO..ANGLE +2221..2222;N # Sm [2] MEASURED ANGLE..SPHERICAL ANGLE +2223;A # Sm DIVIDES +2224;N # Sm DOES NOT DIVIDE +2225;A # Sm PARALLEL TO +2226;N # Sm NOT PARALLEL TO +2227..222C;A # Sm [6] LOGICAL AND..DOUBLE INTEGRAL +222D;N # Sm TRIPLE INTEGRAL +222E;A # Sm CONTOUR INTEGRAL +222F..2233;N # Sm [5] SURFACE INTEGRAL..ANTICLOCKWISE CONTOUR INTEGRAL +2234..2237;A # Sm [4] THEREFORE..PROPORTION +2238..223B;N # Sm [4] DOT MINUS..HOMOTHETIC +223C..223D;A # Sm [2] TILDE OPERATOR..REVERSED TILDE +223E..2247;N # Sm [10] INVERTED LAZY S..NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO +2248;A # Sm ALMOST EQUAL TO +2249..224B;N # Sm [3] NOT ALMOST EQUAL TO..TRIPLE TILDE +224C;A # Sm ALL EQUAL TO +224D..2251;N # Sm [5] EQUIVALENT TO..GEOMETRICALLY EQUAL TO +2252;A # Sm APPROXIMATELY EQUAL TO OR THE IMAGE OF +2253..225F;N # Sm [13] IMAGE OF OR APPROXIMATELY EQUAL TO..QUESTIONED EQUAL TO +2260..2261;A # Sm [2] NOT EQUAL TO..IDENTICAL TO +2262..2263;N # Sm [2] NOT IDENTICAL TO..STRICTLY EQUIVALENT TO +2264..2267;A # Sm [4] LESS-THAN OR EQUAL TO..GREATER-THAN OVER EQUAL TO +2268..2269;N # Sm [2] LESS-THAN BUT NOT EQUAL TO..GREATER-THAN BUT NOT EQUAL TO +226A..226B;A # Sm [2] MUCH LESS-THAN..MUCH GREATER-THAN +226C..226D;N # Sm [2] BETWEEN..NOT EQUIVALENT TO +226E..226F;A # Sm [2] NOT LESS-THAN..NOT GREATER-THAN +2270..2281;N # Sm [18] NEITHER LESS-THAN NOR EQUAL TO..DOES NOT SUCCEED +2282..2283;A # Sm [2] SUBSET OF..SUPERSET OF +2284..2285;N # Sm [2] NOT A SUBSET OF..NOT A SUPERSET OF +2286..2287;A # Sm [2] SUBSET OF OR EQUAL TO..SUPERSET OF OR EQUAL TO +2288..2294;N # Sm [13] NEITHER A SUBSET OF NOR EQUAL TO..SQUARE CUP +2295;A # Sm CIRCLED PLUS +2296..2298;N # Sm [3] CIRCLED MINUS..CIRCLED DIVISION SLASH +2299;A # Sm CIRCLED DOT OPERATOR +229A..22A4;N # Sm [11] CIRCLED RING OPERATOR..DOWN TACK +22A5;A # Sm UP TACK +22A6..22BE;N # Sm [25] ASSERTION..RIGHT ANGLE WITH ARC +22BF;A # Sm RIGHT TRIANGLE +22C0..22FF;N # Sm [64] N-ARY LOGICAL AND..Z NOTATION BAG MEMBERSHIP +2300..2307;N # So [8] DIAMETER SIGN..WAVY LINE +2308;N # Ps LEFT CEILING +2309;N # Pe RIGHT CEILING +230A;N # Ps LEFT FLOOR +230B;N # Pe RIGHT FLOOR +230C..2311;N # So [6] BOTTOM RIGHT CROP..SQUARE LOZENGE +2312;A # So ARC +2313..2319;N # So [7] SEGMENT..TURNED NOT SIGN +231A..231B;W # So [2] WATCH..HOURGLASS +231C..231F;N # So [4] TOP LEFT CORNER..BOTTOM RIGHT CORNER +2320..2321;N # Sm [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL +2322..2328;N # So [7] FROWN..KEYBOARD +2329;W # Ps LEFT-POINTING ANGLE BRACKET +232A;W # Pe RIGHT-POINTING ANGLE BRACKET +232B..237B;N # So [81] ERASE TO THE LEFT..NOT CHECK MARK +237C;N # Sm RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW +237D..239A;N # So [30] SHOULDERED OPEN BOX..CLEAR SCREEN SYMBOL +239B..23B3;N # Sm [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM +23B4..23DB;N # So [40] TOP SQUARE BRACKET..FUSE +23DC..23E1;N # Sm [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET +23E2..23E8;N # So [7] WHITE TRAPEZIUM..DECIMAL EXPONENT SYMBOL +23E9..23EC;W # So [4] BLACK RIGHT-POINTING DOUBLE TRIANGLE..BLACK DOWN-POINTING DOUBLE TRIANGLE +23ED..23EF;N # So [3] BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR..BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR +23F0;W # So ALARM CLOCK +23F1..23F2;N # So [2] STOPWATCH..TIMER CLOCK +23F3;W # So HOURGLASS WITH FLOWING SAND +23F4..23FF;N # So [12] BLACK MEDIUM LEFT-POINTING TRIANGLE..OBSERVER EYE SYMBOL +2400..2426;N # So [39] SYMBOL FOR NULL..SYMBOL FOR SUBSTITUTE FORM TWO +2440..244A;N # So [11] OCR HOOK..OCR DOUBLE BACKSLASH +2460..249B;A # No [60] CIRCLED DIGIT ONE..NUMBER TWENTY FULL STOP +249C..24E9;A # So [78] PARENTHESIZED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z +24EA;N # No CIRCLED DIGIT ZERO +24EB..24FF;A # No [21] NEGATIVE CIRCLED NUMBER ELEVEN..NEGATIVE CIRCLED DIGIT ZERO +2500..254B;A # So [76] BOX DRAWINGS LIGHT HORIZONTAL..BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL +254C..254F;N # So [4] BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL..BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL +2550..2573;A # So [36] BOX DRAWINGS DOUBLE HORIZONTAL..BOX DRAWINGS LIGHT DIAGONAL CROSS +2574..257F;N # So [12] BOX DRAWINGS LIGHT LEFT..BOX DRAWINGS HEAVY UP AND LIGHT DOWN +2580..258F;A # So [16] UPPER HALF BLOCK..LEFT ONE EIGHTH BLOCK +2590..2591;N # So [2] RIGHT HALF BLOCK..LIGHT SHADE +2592..2595;A # So [4] MEDIUM SHADE..RIGHT ONE EIGHTH BLOCK +2596..259F;N # So [10] QUADRANT LOWER LEFT..QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT +25A0..25A1;A # So [2] BLACK SQUARE..WHITE SQUARE +25A2;N # So WHITE SQUARE WITH ROUNDED CORNERS +25A3..25A9;A # So [7] WHITE SQUARE CONTAINING BLACK SMALL SQUARE..SQUARE WITH DIAGONAL CROSSHATCH FILL +25AA..25B1;N # So [8] BLACK SMALL SQUARE..WHITE PARALLELOGRAM +25B2..25B3;A # So [2] BLACK UP-POINTING TRIANGLE..WHITE UP-POINTING TRIANGLE +25B4..25B5;N # So [2] BLACK UP-POINTING SMALL TRIANGLE..WHITE UP-POINTING SMALL TRIANGLE +25B6;A # So BLACK RIGHT-POINTING TRIANGLE +25B7;A # Sm WHITE RIGHT-POINTING TRIANGLE +25B8..25BB;N # So [4] BLACK RIGHT-POINTING SMALL TRIANGLE..WHITE RIGHT-POINTING POINTER +25BC..25BD;A # So [2] BLACK DOWN-POINTING TRIANGLE..WHITE DOWN-POINTING TRIANGLE +25BE..25BF;N # So [2] BLACK DOWN-POINTING SMALL TRIANGLE..WHITE DOWN-POINTING SMALL TRIANGLE +25C0;A # So BLACK LEFT-POINTING TRIANGLE +25C1;A # Sm WHITE LEFT-POINTING TRIANGLE +25C2..25C5;N # So [4] BLACK LEFT-POINTING SMALL TRIANGLE..WHITE LEFT-POINTING POINTER +25C6..25C8;A # So [3] BLACK DIAMOND..WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND +25C9..25CA;N # So [2] FISHEYE..LOZENGE +25CB;A # So WHITE CIRCLE +25CC..25CD;N # So [2] DOTTED CIRCLE..CIRCLE WITH VERTICAL FILL +25CE..25D1;A # So [4] BULLSEYE..CIRCLE WITH RIGHT HALF BLACK +25D2..25E1;N # So [16] CIRCLE WITH LOWER HALF BLACK..LOWER HALF CIRCLE +25E2..25E5;A # So [4] BLACK LOWER RIGHT TRIANGLE..BLACK UPPER RIGHT TRIANGLE +25E6..25EE;N # So [9] WHITE BULLET..UP-POINTING TRIANGLE WITH RIGHT HALF BLACK +25EF;A # So LARGE CIRCLE +25F0..25F7;N # So [8] WHITE SQUARE WITH UPPER LEFT QUADRANT..WHITE CIRCLE WITH UPPER RIGHT QUADRANT +25F8..25FC;N # Sm [5] UPPER LEFT TRIANGLE..BLACK MEDIUM SQUARE +25FD..25FE;W # Sm [2] WHITE MEDIUM SMALL SQUARE..BLACK MEDIUM SMALL SQUARE +25FF;N # Sm LOWER RIGHT TRIANGLE +2600..2604;N # So [5] BLACK SUN WITH RAYS..COMET +2605..2606;A # So [2] BLACK STAR..WHITE STAR +2607..2608;N # So [2] LIGHTNING..THUNDERSTORM +2609;A # So SUN +260A..260D;N # So [4] ASCENDING NODE..OPPOSITION +260E..260F;A # So [2] BLACK TELEPHONE..WHITE TELEPHONE +2610..2613;N # So [4] BALLOT BOX..SALTIRE +2614..2615;W # So [2] UMBRELLA WITH RAIN DROPS..HOT BEVERAGE +2616..261B;N # So [6] WHITE SHOGI PIECE..BLACK RIGHT POINTING INDEX +261C;A # So WHITE LEFT POINTING INDEX +261D;N # So WHITE UP POINTING INDEX +261E;A # So WHITE RIGHT POINTING INDEX +261F..263F;N # So [33] WHITE DOWN POINTING INDEX..MERCURY +2640;A # So FEMALE SIGN +2641;N # So EARTH +2642;A # So MALE SIGN +2643..2647;N # So [5] JUPITER..PLUTO +2648..2653;W # So [12] ARIES..PISCES +2654..265F;N # So [12] WHITE CHESS KING..BLACK CHESS PAWN +2660..2661;A # So [2] BLACK SPADE SUIT..WHITE HEART SUIT +2662;N # So WHITE DIAMOND SUIT +2663..2665;A # So [3] BLACK CLUB SUIT..BLACK HEART SUIT +2666;N # So BLACK DIAMOND SUIT +2667..266A;A # So [4] WHITE CLUB SUIT..EIGHTH NOTE +266B;N # So BEAMED EIGHTH NOTES +266C..266D;A # So [2] BEAMED SIXTEENTH NOTES..MUSIC FLAT SIGN +266E;N # So MUSIC NATURAL SIGN +266F;A # Sm MUSIC SHARP SIGN +2670..267E;N # So [15] WEST SYRIAC CROSS..PERMANENT PAPER SIGN +267F;W # So WHEELCHAIR SYMBOL +2680..2692;N # So [19] DIE FACE-1..HAMMER AND PICK +2693;W # So ANCHOR +2694..269D;N # So [10] CROSSED SWORDS..OUTLINED WHITE STAR +269E..269F;A # So [2] THREE LINES CONVERGING RIGHT..THREE LINES CONVERGING LEFT +26A0;N # So WARNING SIGN +26A1;W # So HIGH VOLTAGE SIGN +26A2..26A9;N # So [8] DOUBLED FEMALE SIGN..HORIZONTAL MALE WITH STROKE SIGN +26AA..26AB;W # So [2] MEDIUM WHITE CIRCLE..MEDIUM BLACK CIRCLE +26AC..26BC;N # So [17] MEDIUM SMALL WHITE CIRCLE..SESQUIQUADRATE +26BD..26BE;W # So [2] SOCCER BALL..BASEBALL +26BF;A # So SQUARED KEY +26C0..26C3;N # So [4] WHITE DRAUGHTS MAN..BLACK DRAUGHTS KING +26C4..26C5;W # So [2] SNOWMAN WITHOUT SNOW..SUN BEHIND CLOUD +26C6..26CD;A # So [8] RAIN..DISABLED CAR +26CE;W # So OPHIUCHUS +26CF..26D3;A # So [5] PICK..CHAINS +26D4;W # So NO ENTRY +26D5..26E1;A # So [13] ALTERNATE ONE-WAY LEFT WAY TRAFFIC..RESTRICTED LEFT ENTRY-2 +26E2;N # So ASTRONOMICAL SYMBOL FOR URANUS +26E3;A # So HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE +26E4..26E7;N # So [4] PENTAGRAM..INVERTED PENTAGRAM +26E8..26E9;A # So [2] BLACK CROSS ON SHIELD..SHINTO SHRINE +26EA;W # So CHURCH +26EB..26F1;A # So [7] CASTLE..UMBRELLA ON GROUND +26F2..26F3;W # So [2] FOUNTAIN..FLAG IN HOLE +26F4;A # So FERRY +26F5;W # So SAILBOAT +26F6..26F9;A # So [4] SQUARE FOUR CORNERS..PERSON WITH BALL +26FA;W # So TENT +26FB..26FC;A # So [2] JAPANESE BANK SYMBOL..HEADSTONE GRAVEYARD SYMBOL +26FD;W # So FUEL PUMP +26FE..26FF;A # So [2] CUP ON BLACK SQUARE..WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE +2700..2704;N # So [5] BLACK SAFETY SCISSORS..WHITE SCISSORS +2705;W # So WHITE HEAVY CHECK MARK +2706..2709;N # So [4] TELEPHONE LOCATION SIGN..ENVELOPE +270A..270B;W # So [2] RAISED FIST..RAISED HAND +270C..2727;N # So [28] VICTORY HAND..WHITE FOUR POINTED STAR +2728;W # So SPARKLES +2729..273C;N # So [20] STRESS OUTLINED WHITE STAR..OPEN CENTRE TEARDROP-SPOKED ASTERISK +273D;A # So HEAVY TEARDROP-SPOKED ASTERISK +273E..274B;N # So [14] SIX PETALLED BLACK AND WHITE FLORETTE..HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK +274C;W # So CROSS MARK +274D;N # So SHADOWED WHITE CIRCLE +274E;W # So NEGATIVE SQUARED CROSS MARK +274F..2752;N # So [4] LOWER RIGHT DROP-SHADOWED WHITE SQUARE..UPPER RIGHT SHADOWED WHITE SQUARE +2753..2755;W # So [3] BLACK QUESTION MARK ORNAMENT..WHITE EXCLAMATION MARK ORNAMENT +2756;N # So BLACK DIAMOND MINUS WHITE X +2757;W # So HEAVY EXCLAMATION MARK SYMBOL +2758..2767;N # So [16] LIGHT VERTICAL BAR..ROTATED FLORAL HEART BULLET +2768;N # Ps MEDIUM LEFT PARENTHESIS ORNAMENT +2769;N # Pe MEDIUM RIGHT PARENTHESIS ORNAMENT +276A;N # Ps MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT +276B;N # Pe MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT +276C;N # Ps MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT +276D;N # Pe MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT +276E;N # Ps HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT +276F;N # Pe HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT +2770;N # Ps HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT +2771;N # Pe HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT +2772;N # Ps LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT +2773;N # Pe LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT +2774;N # Ps MEDIUM LEFT CURLY BRACKET ORNAMENT +2775;N # Pe MEDIUM RIGHT CURLY BRACKET ORNAMENT +2776..277F;A # No [10] DINGBAT NEGATIVE CIRCLED DIGIT ONE..DINGBAT NEGATIVE CIRCLED NUMBER TEN +2780..2793;N # No [20] DINGBAT CIRCLED SANS-SERIF DIGIT ONE..DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN +2794;N # So HEAVY WIDE-HEADED RIGHTWARDS ARROW +2795..2797;W # So [3] HEAVY PLUS SIGN..HEAVY DIVISION SIGN +2798..27AF;N # So [24] HEAVY SOUTH EAST ARROW..NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW +27B0;W # So CURLY LOOP +27B1..27BE;N # So [14] NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW..OPEN-OUTLINED RIGHTWARDS ARROW +27BF;W # So DOUBLE CURLY LOOP +27C0..27C4;N # Sm [5] THREE DIMENSIONAL ANGLE..OPEN SUPERSET +27C5;N # Ps LEFT S-SHAPED BAG DELIMITER +27C6;N # Pe RIGHT S-SHAPED BAG DELIMITER +27C7..27E5;N # Sm [31] OR WITH DOT INSIDE..WHITE SQUARE WITH RIGHTWARDS TICK +27E6;Na # Ps MATHEMATICAL LEFT WHITE SQUARE BRACKET +27E7;Na # Pe MATHEMATICAL RIGHT WHITE SQUARE BRACKET +27E8;Na # Ps MATHEMATICAL LEFT ANGLE BRACKET +27E9;Na # Pe MATHEMATICAL RIGHT ANGLE BRACKET +27EA;Na # Ps MATHEMATICAL LEFT DOUBLE ANGLE BRACKET +27EB;Na # Pe MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET +27EC;Na # Ps MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET +27ED;Na # Pe MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET +27EE;N # Ps MATHEMATICAL LEFT FLATTENED PARENTHESIS +27EF;N # Pe MATHEMATICAL RIGHT FLATTENED PARENTHESIS +27F0..27FF;N # Sm [16] UPWARDS QUADRUPLE ARROW..LONG RIGHTWARDS SQUIGGLE ARROW +2800..28FF;N # So [256] BRAILLE PATTERN BLANK..BRAILLE PATTERN DOTS-12345678 +2900..297F;N # Sm [128] RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE..DOWN FISH TAIL +2980..2982;N # Sm [3] TRIPLE VERTICAL BAR DELIMITER..Z NOTATION TYPE COLON +2983;N # Ps LEFT WHITE CURLY BRACKET +2984;N # Pe RIGHT WHITE CURLY BRACKET +2985;Na # Ps LEFT WHITE PARENTHESIS +2986;Na # Pe RIGHT WHITE PARENTHESIS +2987;N # Ps Z NOTATION LEFT IMAGE BRACKET +2988;N # Pe Z NOTATION RIGHT IMAGE BRACKET +2989;N # Ps Z NOTATION LEFT BINDING BRACKET +298A;N # Pe Z NOTATION RIGHT BINDING BRACKET +298B;N # Ps LEFT SQUARE BRACKET WITH UNDERBAR +298C;N # Pe RIGHT SQUARE BRACKET WITH UNDERBAR +298D;N # Ps LEFT SQUARE BRACKET WITH TICK IN TOP CORNER +298E;N # Pe RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +298F;N # Ps LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +2990;N # Pe RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER +2991;N # Ps LEFT ANGLE BRACKET WITH DOT +2992;N # Pe RIGHT ANGLE BRACKET WITH DOT +2993;N # Ps LEFT ARC LESS-THAN BRACKET +2994;N # Pe RIGHT ARC GREATER-THAN BRACKET +2995;N # Ps DOUBLE LEFT ARC GREATER-THAN BRACKET +2996;N # Pe DOUBLE RIGHT ARC LESS-THAN BRACKET +2997;N # Ps LEFT BLACK TORTOISE SHELL BRACKET +2998;N # Pe RIGHT BLACK TORTOISE SHELL BRACKET +2999..29D7;N # Sm [63] DOTTED FENCE..BLACK HOURGLASS +29D8;N # Ps LEFT WIGGLY FENCE +29D9;N # Pe RIGHT WIGGLY FENCE +29DA;N # Ps LEFT DOUBLE WIGGLY FENCE +29DB;N # Pe RIGHT DOUBLE WIGGLY FENCE +29DC..29FB;N # Sm [32] INCOMPLETE INFINITY..TRIPLE PLUS +29FC;N # Ps LEFT-POINTING CURVED ANGLE BRACKET +29FD;N # Pe RIGHT-POINTING CURVED ANGLE BRACKET +29FE..29FF;N # Sm [2] TINY..MINY +2A00..2AFF;N # Sm [256] N-ARY CIRCLED DOT OPERATOR..N-ARY WHITE VERTICAL BAR +2B00..2B1A;N # So [27] NORTH EAST WHITE ARROW..DOTTED SQUARE +2B1B..2B1C;W # So [2] BLACK LARGE SQUARE..WHITE LARGE SQUARE +2B1D..2B2F;N # So [19] BLACK VERY SMALL SQUARE..WHITE VERTICAL ELLIPSE +2B30..2B44;N # Sm [21] LEFT ARROW WITH SMALL CIRCLE..RIGHTWARDS ARROW THROUGH SUPERSET +2B45..2B46;N # So [2] LEFTWARDS QUADRUPLE ARROW..RIGHTWARDS QUADRUPLE ARROW +2B47..2B4C;N # Sm [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR +2B4D..2B4F;N # So [3] DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW..SHORT BACKSLANTED SOUTH ARROW +2B50;W # So WHITE MEDIUM STAR +2B51..2B54;N # So [4] BLACK SMALL STAR..WHITE RIGHT-POINTING PENTAGON +2B55;W # So HEAVY LARGE CIRCLE +2B56..2B59;A # So [4] HEAVY OVAL WITH OVAL INSIDE..HEAVY CIRCLED SALTIRE +2B5A..2B73;N # So [26] SLANTED NORTH ARROW WITH HOOKED HEAD..DOWNWARDS TRIANGLE-HEADED ARROW TO BAR +2B76..2B95;N # So [32] NORTH WEST TRIANGLE-HEADED ARROW TO BAR..RIGHTWARDS BLACK ARROW +2B98..2BFF;N # So [104] THREE-D TOP-LIGHTED LEFTWARDS EQUILATERAL ARROWHEAD..HELLSCHREIBER PAUSE SYMBOL +2C00..2C2E;N # Lu [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE +2C30..2C5E;N # Ll [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE +2C60..2C7B;N # L& [28] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN LETTER SMALL CAPITAL TURNED E +2C7C..2C7D;N # Lm [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V +2C7E..2C7F;N # Lu [2] LATIN CAPITAL LETTER S WITH SWASH TAIL..LATIN CAPITAL LETTER Z WITH SWASH TAIL +2C80..2CE4;N # L& [101] COPTIC CAPITAL LETTER ALFA..COPTIC SYMBOL KAI +2CE5..2CEA;N # So [6] COPTIC SYMBOL MI RO..COPTIC SYMBOL SHIMA SIMA +2CEB..2CEE;N # L& [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA +2CEF..2CF1;N # Mn [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS +2CF2..2CF3;N # L& [2] COPTIC CAPITAL LETTER BOHAIRIC KHEI..COPTIC SMALL LETTER BOHAIRIC KHEI +2CF9..2CFC;N # Po [4] COPTIC OLD NUBIAN FULL STOP..COPTIC OLD NUBIAN VERSE DIVIDER +2CFD;N # No COPTIC FRACTION ONE HALF +2CFE..2CFF;N # Po [2] COPTIC FULL STOP..COPTIC MORPHOLOGICAL DIVIDER +2D00..2D25;N # Ll [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE +2D27;N # Ll GEORGIAN SMALL LETTER YN +2D2D;N # Ll GEORGIAN SMALL LETTER AEN +2D30..2D67;N # Lo [56] TIFINAGH LETTER YA..TIFINAGH LETTER YO +2D6F;N # Lm TIFINAGH MODIFIER LETTER LABIALIZATION MARK +2D70;N # Po TIFINAGH SEPARATOR MARK +2D7F;N # Mn TIFINAGH CONSONANT JOINER +2D80..2D96;N # Lo [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE +2DA0..2DA6;N # Lo [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO +2DA8..2DAE;N # Lo [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO +2DB0..2DB6;N # Lo [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO +2DB8..2DBE;N # Lo [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO +2DC0..2DC6;N # Lo [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO +2DC8..2DCE;N # Lo [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO +2DD0..2DD6;N # Lo [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO +2DD8..2DDE;N # Lo [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO +2DE0..2DFF;N # Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS +2E00..2E01;N # Po [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER +2E02;N # Pi LEFT SUBSTITUTION BRACKET +2E03;N # Pf RIGHT SUBSTITUTION BRACKET +2E04;N # Pi LEFT DOTTED SUBSTITUTION BRACKET +2E05;N # Pf RIGHT DOTTED SUBSTITUTION BRACKET +2E06..2E08;N # Po [3] RAISED INTERPOLATION MARKER..DOTTED TRANSPOSITION MARKER +2E09;N # Pi LEFT TRANSPOSITION BRACKET +2E0A;N # Pf RIGHT TRANSPOSITION BRACKET +2E0B;N # Po RAISED SQUARE +2E0C;N # Pi LEFT RAISED OMISSION BRACKET +2E0D;N # Pf RIGHT RAISED OMISSION BRACKET +2E0E..2E16;N # Po [9] EDITORIAL CORONIS..DOTTED RIGHT-POINTING ANGLE +2E17;N # Pd DOUBLE OBLIQUE HYPHEN +2E18..2E19;N # Po [2] INVERTED INTERROBANG..PALM BRANCH +2E1A;N # Pd HYPHEN WITH DIAERESIS +2E1B;N # Po TILDE WITH RING ABOVE +2E1C;N # Pi LEFT LOW PARAPHRASE BRACKET +2E1D;N # Pf RIGHT LOW PARAPHRASE BRACKET +2E1E..2E1F;N # Po [2] TILDE WITH DOT ABOVE..TILDE WITH DOT BELOW +2E20;N # Pi LEFT VERTICAL BAR WITH QUILL +2E21;N # Pf RIGHT VERTICAL BAR WITH QUILL +2E22;N # Ps TOP LEFT HALF BRACKET +2E23;N # Pe TOP RIGHT HALF BRACKET +2E24;N # Ps BOTTOM LEFT HALF BRACKET +2E25;N # Pe BOTTOM RIGHT HALF BRACKET +2E26;N # Ps LEFT SIDEWAYS U BRACKET +2E27;N # Pe RIGHT SIDEWAYS U BRACKET +2E28;N # Ps LEFT DOUBLE PARENTHESIS +2E29;N # Pe RIGHT DOUBLE PARENTHESIS +2E2A..2E2E;N # Po [5] TWO DOTS OVER ONE DOT PUNCTUATION..REVERSED QUESTION MARK +2E2F;N # Lm VERTICAL TILDE +2E30..2E39;N # Po [10] RING POINT..TOP HALF SECTION SIGN +2E3A..2E3B;N # Pd [2] TWO-EM DASH..THREE-EM DASH +2E3C..2E3F;N # Po [4] STENOGRAPHIC FULL STOP..CAPITULUM +2E40;N # Pd DOUBLE HYPHEN +2E41;N # Po REVERSED COMMA +2E42;N # Ps DOUBLE LOW-REVERSED-9 QUOTATION MARK +2E43..2E4F;N # Po [13] DASH WITH LEFT UPTURN..CORNISH VERSE DIVIDER +2E80..2E99;W # So [26] CJK RADICAL REPEAT..CJK RADICAL RAP +2E9B..2EF3;W # So [89] CJK RADICAL CHOKE..CJK RADICAL C-SIMPLIFIED TURTLE +2F00..2FD5;W # So [214] KANGXI RADICAL ONE..KANGXI RADICAL FLUTE +2FF0..2FFB;W # So [12] IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT..IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID +3000;F # Zs IDEOGRAPHIC SPACE +3001..3003;W # Po [3] IDEOGRAPHIC COMMA..DITTO MARK +3004;W # So JAPANESE INDUSTRIAL STANDARD SYMBOL +3005;W # Lm IDEOGRAPHIC ITERATION MARK +3006;W # Lo IDEOGRAPHIC CLOSING MARK +3007;W # Nl IDEOGRAPHIC NUMBER ZERO +3008;W # Ps LEFT ANGLE BRACKET +3009;W # Pe RIGHT ANGLE BRACKET +300A;W # Ps LEFT DOUBLE ANGLE BRACKET +300B;W # Pe RIGHT DOUBLE ANGLE BRACKET +300C;W # Ps LEFT CORNER BRACKET +300D;W # Pe RIGHT CORNER BRACKET +300E;W # Ps LEFT WHITE CORNER BRACKET +300F;W # Pe RIGHT WHITE CORNER BRACKET +3010;W # Ps LEFT BLACK LENTICULAR BRACKET +3011;W # Pe RIGHT BLACK LENTICULAR BRACKET +3012..3013;W # So [2] POSTAL MARK..GETA MARK +3014;W # Ps LEFT TORTOISE SHELL BRACKET +3015;W # Pe RIGHT TORTOISE SHELL BRACKET +3016;W # Ps LEFT WHITE LENTICULAR BRACKET +3017;W # Pe RIGHT WHITE LENTICULAR BRACKET +3018;W # Ps LEFT WHITE TORTOISE SHELL BRACKET +3019;W # Pe RIGHT WHITE TORTOISE SHELL BRACKET +301A;W # Ps LEFT WHITE SQUARE BRACKET +301B;W # Pe RIGHT WHITE SQUARE BRACKET +301C;W # Pd WAVE DASH +301D;W # Ps REVERSED DOUBLE PRIME QUOTATION MARK +301E..301F;W # Pe [2] DOUBLE PRIME QUOTATION MARK..LOW DOUBLE PRIME QUOTATION MARK +3020;W # So POSTAL MARK FACE +3021..3029;W # Nl [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE +302A..302D;W # Mn [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK +302E..302F;W # Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK +3030;W # Pd WAVY DASH +3031..3035;W # Lm [5] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT MARK LOWER HALF +3036..3037;W # So [2] CIRCLED POSTAL MARK..IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL +3038..303A;W # Nl [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY +303B;W # Lm VERTICAL IDEOGRAPHIC ITERATION MARK +303C;W # Lo MASU MARK +303D;W # Po PART ALTERNATION MARK +303E;W # So IDEOGRAPHIC VARIATION INDICATOR +303F;N # So IDEOGRAPHIC HALF FILL SPACE +3041..3096;W # Lo [86] HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE +3099..309A;W # Mn [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK +309B..309C;W # Sk [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK +309D..309E;W # Lm [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK +309F;W # Lo HIRAGANA DIGRAPH YORI +30A0;W # Pd KATAKANA-HIRAGANA DOUBLE HYPHEN +30A1..30FA;W # Lo [90] KATAKANA LETTER SMALL A..KATAKANA LETTER VO +30FB;W # Po KATAKANA MIDDLE DOT +30FC..30FE;W # Lm [3] KATAKANA-HIRAGANA PROLONGED SOUND MARK..KATAKANA VOICED ITERATION MARK +30FF;W # Lo KATAKANA DIGRAPH KOTO +3105..312F;W # Lo [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN +3131..318E;W # Lo [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE +3190..3191;W # So [2] IDEOGRAPHIC ANNOTATION LINKING MARK..IDEOGRAPHIC ANNOTATION REVERSE MARK +3192..3195;W # No [4] IDEOGRAPHIC ANNOTATION ONE MARK..IDEOGRAPHIC ANNOTATION FOUR MARK +3196..319F;W # So [10] IDEOGRAPHIC ANNOTATION TOP MARK..IDEOGRAPHIC ANNOTATION MAN MARK +31A0..31BA;W # Lo [27] BOPOMOFO LETTER BU..BOPOMOFO LETTER ZY +31C0..31E3;W # So [36] CJK STROKE T..CJK STROKE Q +31F0..31FF;W # Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO +3200..321E;W # So [31] PARENTHESIZED HANGUL KIYEOK..PARENTHESIZED KOREAN CHARACTER O HU +3220..3229;W # No [10] PARENTHESIZED IDEOGRAPH ONE..PARENTHESIZED IDEOGRAPH TEN +322A..3247;W # So [30] PARENTHESIZED IDEOGRAPH MOON..CIRCLED IDEOGRAPH KOTO +3248..324F;A # No [8] CIRCLED NUMBER TEN ON BLACK SQUARE..CIRCLED NUMBER EIGHTY ON BLACK SQUARE +3250;W # So PARTNERSHIP SIGN +3251..325F;W # No [15] CIRCLED NUMBER TWENTY ONE..CIRCLED NUMBER THIRTY FIVE +3260..327F;W # So [32] CIRCLED HANGUL KIYEOK..KOREAN STANDARD SYMBOL +3280..3289;W # No [10] CIRCLED IDEOGRAPH ONE..CIRCLED IDEOGRAPH TEN +328A..32B0;W # So [39] CIRCLED IDEOGRAPH MOON..CIRCLED IDEOGRAPH NIGHT +32B1..32BF;W # No [15] CIRCLED NUMBER THIRTY SIX..CIRCLED NUMBER FIFTY +32C0..32FF;W # So [64] IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY..SQUARE ERA NAME REIWA +3300..33FF;W # So [256] SQUARE APAATO..SQUARE GAL +3400..4DB5;W # Lo [6582] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DB5 +4DB6..4DBF;W # Cn [10] .. +4DC0..4DFF;N # So [64] HEXAGRAM FOR THE CREATIVE HEAVEN..HEXAGRAM FOR BEFORE COMPLETION +4E00..9FEF;W # Lo [20976] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FEF +9FF0..9FFF;W # Cn [16] .. +A000..A014;W # Lo [21] YI SYLLABLE IT..YI SYLLABLE E +A015;W # Lm YI SYLLABLE WU +A016..A48C;W # Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR +A490..A4C6;W # So [55] YI RADICAL QOT..YI RADICAL KE +A4D0..A4F7;N # Lo [40] LISU LETTER BA..LISU LETTER OE +A4F8..A4FD;N # Lm [6] LISU LETTER TONE MYA TI..LISU LETTER TONE MYA JEU +A4FE..A4FF;N # Po [2] LISU PUNCTUATION COMMA..LISU PUNCTUATION FULL STOP +A500..A60B;N # Lo [268] VAI SYLLABLE EE..VAI SYLLABLE NG +A60C;N # Lm VAI SYLLABLE LENGTHENER +A60D..A60F;N # Po [3] VAI COMMA..VAI QUESTION MARK +A610..A61F;N # Lo [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG +A620..A629;N # Nd [10] VAI DIGIT ZERO..VAI DIGIT NINE +A62A..A62B;N # Lo [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO +A640..A66D;N # L& [46] CYRILLIC CAPITAL LETTER ZEMLYA..CYRILLIC SMALL LETTER DOUBLE MONOCULAR O +A66E;N # Lo CYRILLIC LETTER MULTIOCULAR O +A66F;N # Mn COMBINING CYRILLIC VZMET +A670..A672;N # Me [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN +A673;N # Po SLAVONIC ASTERISK +A674..A67D;N # Mn [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK +A67E;N # Po CYRILLIC KAVYKA +A67F;N # Lm CYRILLIC PAYEROK +A680..A69B;N # L& [28] CYRILLIC CAPITAL LETTER DWE..CYRILLIC SMALL LETTER CROSSED O +A69C..A69D;N # Lm [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN +A69E..A69F;N # Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E +A6A0..A6E5;N # Lo [70] BAMUM LETTER A..BAMUM LETTER KI +A6E6..A6EF;N # Nl [10] BAMUM LETTER MO..BAMUM LETTER KOGHOM +A6F0..A6F1;N # Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS +A6F2..A6F7;N # Po [6] BAMUM NJAEMLI..BAMUM QUESTION MARK +A700..A716;N # Sk [23] MODIFIER LETTER CHINESE TONE YIN PING..MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR +A717..A71F;N # Lm [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK +A720..A721;N # Sk [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIFIER LETTER STRESS AND LOW TONE +A722..A76F;N # L& [78] LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF..LATIN SMALL LETTER CON +A770;N # Lm MODIFIER LETTER US +A771..A787;N # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T +A788;N # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT +A789..A78A;N # Sk [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN +A78B..A78E;N # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT +A78F;N # Lo LATIN LETTER SINOLOGICAL DOT +A790..A7BF;N # L& [48] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER GLOTTAL U +A7C2..A7C6;N # L& [5] LATIN CAPITAL LETTER ANGLICANA W..LATIN CAPITAL LETTER Z WITH PALATAL HOOK +A7F7;N # Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I +A7F8..A7F9;N # Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE +A7FA;N # Ll LATIN LETTER SMALL CAPITAL TURNED M +A7FB..A7FF;N # Lo [5] LATIN EPIGRAPHIC LETTER REVERSED F..LATIN EPIGRAPHIC LETTER ARCHAIC M +A800..A801;N # Lo [2] SYLOTI NAGRI LETTER A..SYLOTI NAGRI LETTER I +A802;N # Mn SYLOTI NAGRI SIGN DVISVARA +A803..A805;N # Lo [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O +A806;N # Mn SYLOTI NAGRI SIGN HASANTA +A807..A80A;N # Lo [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO +A80B;N # Mn SYLOTI NAGRI SIGN ANUSVARA +A80C..A822;N # Lo [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO +A823..A824;N # Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I +A825..A826;N # Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E +A827;N # Mc SYLOTI NAGRI VOWEL SIGN OO +A828..A82B;N # So [4] SYLOTI NAGRI POETRY MARK-1..SYLOTI NAGRI POETRY MARK-4 +A830..A835;N # No [6] NORTH INDIC FRACTION ONE QUARTER..NORTH INDIC FRACTION THREE SIXTEENTHS +A836..A837;N # So [2] NORTH INDIC QUARTER MARK..NORTH INDIC PLACEHOLDER MARK +A838;N # Sc NORTH INDIC RUPEE MARK +A839;N # So NORTH INDIC QUANTITY MARK +A840..A873;N # Lo [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU +A874..A877;N # Po [4] PHAGS-PA SINGLE HEAD MARK..PHAGS-PA MARK DOUBLE SHAD +A880..A881;N # Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA +A882..A8B3;N # Lo [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA +A8B4..A8C3;N # Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU +A8C4..A8C5;N # Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU +A8CE..A8CF;N # Po [2] SAURASHTRA DANDA..SAURASHTRA DOUBLE DANDA +A8D0..A8D9;N # Nd [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE +A8E0..A8F1;N # Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA +A8F2..A8F7;N # Lo [6] DEVANAGARI SIGN SPACING CANDRABINDU..DEVANAGARI SIGN CANDRABINDU AVAGRAHA +A8F8..A8FA;N # Po [3] DEVANAGARI SIGN PUSHPIKA..DEVANAGARI CARET +A8FB;N # Lo DEVANAGARI HEADSTROKE +A8FC;N # Po DEVANAGARI SIGN SIDDHAM +A8FD..A8FE;N # Lo [2] DEVANAGARI JAIN OM..DEVANAGARI LETTER AY +A8FF;N # Mn DEVANAGARI VOWEL SIGN AY +A900..A909;N # Nd [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE +A90A..A925;N # Lo [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO +A926..A92D;N # Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU +A92E..A92F;N # Po [2] KAYAH LI SIGN CWI..KAYAH LI SIGN SHYA +A930..A946;N # Lo [23] REJANG LETTER KA..REJANG LETTER A +A947..A951;N # Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R +A952..A953;N # Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA +A95F;N # Po REJANG SECTION MARK +A960..A97C;W # Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH +A980..A982;N # Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR +A983;N # Mc JAVANESE SIGN WIGNYAN +A984..A9B2;N # Lo [47] JAVANESE LETTER A..JAVANESE LETTER HA +A9B3;N # Mn JAVANESE SIGN CECAK TELU +A9B4..A9B5;N # Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG +A9B6..A9B9;N # Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT +A9BA..A9BB;N # Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE +A9BC..A9BD;N # Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET +A9BE..A9C0;N # Mc [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON +A9C1..A9CD;N # Po [13] JAVANESE LEFT RERENGGAN..JAVANESE TURNED PADA PISELEH +A9CF;N # Lm JAVANESE PANGRANGKEP +A9D0..A9D9;N # Nd [10] JAVANESE DIGIT ZERO..JAVANESE DIGIT NINE +A9DE..A9DF;N # Po [2] JAVANESE PADA TIRTA TUMETES..JAVANESE PADA ISEN-ISEN +A9E0..A9E4;N # Lo [5] MYANMAR LETTER SHAN GHA..MYANMAR LETTER SHAN BHA +A9E5;N # Mn MYANMAR SIGN SHAN SAW +A9E6;N # Lm MYANMAR MODIFIER LETTER SHAN REDUPLICATION +A9E7..A9EF;N # Lo [9] MYANMAR LETTER TAI LAING NYA..MYANMAR LETTER TAI LAING NNA +A9F0..A9F9;N # Nd [10] MYANMAR TAI LAING DIGIT ZERO..MYANMAR TAI LAING DIGIT NINE +A9FA..A9FE;N # Lo [5] MYANMAR LETTER TAI LAING LLA..MYANMAR LETTER TAI LAING BHA +AA00..AA28;N # Lo [41] CHAM LETTER A..CHAM LETTER HA +AA29..AA2E;N # Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE +AA2F..AA30;N # Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI +AA31..AA32;N # Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE +AA33..AA34;N # Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA +AA35..AA36;N # Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA +AA40..AA42;N # Lo [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG +AA43;N # Mn CHAM CONSONANT SIGN FINAL NG +AA44..AA4B;N # Lo [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS +AA4C;N # Mn CHAM CONSONANT SIGN FINAL M +AA4D;N # Mc CHAM CONSONANT SIGN FINAL H +AA50..AA59;N # Nd [10] CHAM DIGIT ZERO..CHAM DIGIT NINE +AA5C..AA5F;N # Po [4] CHAM PUNCTUATION SPIRAL..CHAM PUNCTUATION TRIPLE DANDA +AA60..AA6F;N # Lo [16] MYANMAR LETTER KHAMTI GA..MYANMAR LETTER KHAMTI FA +AA70;N # Lm MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION +AA71..AA76;N # Lo [6] MYANMAR LETTER KHAMTI XA..MYANMAR LOGOGRAM KHAMTI HM +AA77..AA79;N # So [3] MYANMAR SYMBOL AITON EXCLAMATION..MYANMAR SYMBOL AITON TWO +AA7A;N # Lo MYANMAR LETTER AITON RA +AA7B;N # Mc MYANMAR SIGN PAO KAREN TONE +AA7C;N # Mn MYANMAR SIGN TAI LAING TONE-2 +AA7D;N # Mc MYANMAR SIGN TAI LAING TONE-5 +AA7E..AA7F;N # Lo [2] MYANMAR LETTER SHWE PALAUNG CHA..MYANMAR LETTER SHWE PALAUNG SHA +AA80..AAAF;N # Lo [48] TAI VIET LETTER LOW KO..TAI VIET LETTER HIGH O +AAB0;N # Mn TAI VIET MAI KANG +AAB1;N # Lo TAI VIET VOWEL AA +AAB2..AAB4;N # Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U +AAB5..AAB6;N # Lo [2] TAI VIET VOWEL E..TAI VIET VOWEL O +AAB7..AAB8;N # Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA +AAB9..AABD;N # Lo [5] TAI VIET VOWEL UEA..TAI VIET VOWEL AN +AABE..AABF;N # Mn [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK +AAC0;N # Lo TAI VIET TONE MAI NUENG +AAC1;N # Mn TAI VIET TONE MAI THO +AAC2;N # Lo TAI VIET TONE MAI SONG +AADB..AADC;N # Lo [2] TAI VIET SYMBOL KON..TAI VIET SYMBOL NUENG +AADD;N # Lm TAI VIET SYMBOL SAM +AADE..AADF;N # Po [2] TAI VIET SYMBOL HO HOI..TAI VIET SYMBOL KOI KOI +AAE0..AAEA;N # Lo [11] MEETEI MAYEK LETTER E..MEETEI MAYEK LETTER SSA +AAEB;N # Mc MEETEI MAYEK VOWEL SIGN II +AAEC..AAED;N # Mn [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI +AAEE..AAEF;N # Mc [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU +AAF0..AAF1;N # Po [2] MEETEI MAYEK CHEIKHAN..MEETEI MAYEK AHANG KHUDAM +AAF2;N # Lo MEETEI MAYEK ANJI +AAF3..AAF4;N # Lm [2] MEETEI MAYEK SYLLABLE REPETITION MARK..MEETEI MAYEK WORD REPETITION MARK +AAF5;N # Mc MEETEI MAYEK VOWEL SIGN VISARGA +AAF6;N # Mn MEETEI MAYEK VIRAMA +AB01..AB06;N # Lo [6] ETHIOPIC SYLLABLE TTHU..ETHIOPIC SYLLABLE TTHO +AB09..AB0E;N # Lo [6] ETHIOPIC SYLLABLE DDHU..ETHIOPIC SYLLABLE DDHO +AB11..AB16;N # Lo [6] ETHIOPIC SYLLABLE DZU..ETHIOPIC SYLLABLE DZO +AB20..AB26;N # Lo [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE CCHHO +AB28..AB2E;N # Lo [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO +AB30..AB5A;N # Ll [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG +AB5B;N # Sk MODIFIER BREVE WITH INVERTED BREVE +AB5C..AB5F;N # Lm [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK +AB60..AB67;N # Ll [8] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TS DIGRAPH WITH RETROFLEX HOOK +AB70..ABBF;N # Ll [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA +ABC0..ABE2;N # Lo [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM +ABE3..ABE4;N # Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP +ABE5;N # Mn MEETEI MAYEK VOWEL SIGN ANAP +ABE6..ABE7;N # Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP +ABE8;N # Mn MEETEI MAYEK VOWEL SIGN UNAP +ABE9..ABEA;N # Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG +ABEB;N # Po MEETEI MAYEK CHEIKHEI +ABEC;N # Mc MEETEI MAYEK LUM IYEK +ABED;N # Mn MEETEI MAYEK APUN IYEK +ABF0..ABF9;N # Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DIGIT NINE +AC00..D7A3;W # Lo [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH +D7B0..D7C6;N # Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E +D7CB..D7FB;N # Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH +D800..DB7F;N # Cs [896] .. +DB80..DBFF;N # Cs [128] .. +DC00..DFFF;N # Cs [1024] .. +E000..F8FF;A # Co [6400] .. +F900..FA6D;W # Lo [366] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA6D +FA6E..FA6F;W # Cn [2] .. +FA70..FAD9;W # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9 +FADA..FAFF;W # Cn [38] .. +FB00..FB06;N # Ll [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST +FB13..FB17;N # Ll [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH +FB1D;N # Lo HEBREW LETTER YOD WITH HIRIQ +FB1E;N # Mn HEBREW POINT JUDEO-SPANISH VARIKA +FB1F..FB28;N # Lo [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV +FB29;N # Sm HEBREW LETTER ALTERNATIVE PLUS SIGN +FB2A..FB36;N # Lo [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH +FB38..FB3C;N # Lo [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH +FB3E;N # Lo HEBREW LETTER MEM WITH DAGESH +FB40..FB41;N # Lo [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH +FB43..FB44;N # Lo [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH +FB46..FB4F;N # Lo [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATURE ALEF LAMED +FB50..FBB1;N # Lo [98] ARABIC LETTER ALEF WASLA ISOLATED FORM..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM +FBB2..FBC1;N # Sk [16] ARABIC SYMBOL DOT ABOVE..ARABIC SYMBOL SMALL TAH BELOW +FBD3..FD3D;N # Lo [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM +FD3E;N # Pe ORNATE LEFT PARENTHESIS +FD3F;N # Ps ORNATE RIGHT PARENTHESIS +FD50..FD8F;N # Lo [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM +FD92..FDC7;N # Lo [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM +FDF0..FDFB;N # Lo [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU +FDFC;N # Sc RIAL SIGN +FDFD;N # So ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM +FE00..FE0F;A # Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 +FE10..FE16;W # Po [7] PRESENTATION FORM FOR VERTICAL COMMA..PRESENTATION FORM FOR VERTICAL QUESTION MARK +FE17;W # Ps PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET +FE18;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET +FE19;W # Po PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS +FE20..FE2F;N # Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF +FE30;W # Po PRESENTATION FORM FOR VERTICAL TWO DOT LEADER +FE31..FE32;W # Pd [2] PRESENTATION FORM FOR VERTICAL EM DASH..PRESENTATION FORM FOR VERTICAL EN DASH +FE33..FE34;W # Pc [2] PRESENTATION FORM FOR VERTICAL LOW LINE..PRESENTATION FORM FOR VERTICAL WAVY LOW LINE +FE35;W # Ps PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS +FE36;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS +FE37;W # Ps PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET +FE38;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET +FE39;W # Ps PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET +FE3A;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET +FE3B;W # Ps PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET +FE3C;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET +FE3D;W # Ps PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET +FE3E;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET +FE3F;W # Ps PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET +FE40;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET +FE41;W # Ps PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET +FE42;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET +FE43;W # Ps PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET +FE44;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET +FE45..FE46;W # Po [2] SESAME DOT..WHITE SESAME DOT +FE47;W # Ps PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET +FE48;W # Pe PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET +FE49..FE4C;W # Po [4] DASHED OVERLINE..DOUBLE WAVY OVERLINE +FE4D..FE4F;W # Pc [3] DASHED LOW LINE..WAVY LOW LINE +FE50..FE52;W # Po [3] SMALL COMMA..SMALL FULL STOP +FE54..FE57;W # Po [4] SMALL SEMICOLON..SMALL EXCLAMATION MARK +FE58;W # Pd SMALL EM DASH +FE59;W # Ps SMALL LEFT PARENTHESIS +FE5A;W # Pe SMALL RIGHT PARENTHESIS +FE5B;W # Ps SMALL LEFT CURLY BRACKET +FE5C;W # Pe SMALL RIGHT CURLY BRACKET +FE5D;W # Ps SMALL LEFT TORTOISE SHELL BRACKET +FE5E;W # Pe SMALL RIGHT TORTOISE SHELL BRACKET +FE5F..FE61;W # Po [3] SMALL NUMBER SIGN..SMALL ASTERISK +FE62;W # Sm SMALL PLUS SIGN +FE63;W # Pd SMALL HYPHEN-MINUS +FE64..FE66;W # Sm [3] SMALL LESS-THAN SIGN..SMALL EQUALS SIGN +FE68;W # Po SMALL REVERSE SOLIDUS +FE69;W # Sc SMALL DOLLAR SIGN +FE6A..FE6B;W # Po [2] SMALL PERCENT SIGN..SMALL COMMERCIAL AT +FE70..FE74;N # Lo [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM +FE76..FEFC;N # Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM +FEFF;N # Cf ZERO WIDTH NO-BREAK SPACE +FF01..FF03;F # Po [3] FULLWIDTH EXCLAMATION MARK..FULLWIDTH NUMBER SIGN +FF04;F # Sc FULLWIDTH DOLLAR SIGN +FF05..FF07;F # Po [3] FULLWIDTH PERCENT SIGN..FULLWIDTH APOSTROPHE +FF08;F # Ps FULLWIDTH LEFT PARENTHESIS +FF09;F # Pe FULLWIDTH RIGHT PARENTHESIS +FF0A;F # Po FULLWIDTH ASTERISK +FF0B;F # Sm FULLWIDTH PLUS SIGN +FF0C;F # Po FULLWIDTH COMMA +FF0D;F # Pd FULLWIDTH HYPHEN-MINUS +FF0E..FF0F;F # Po [2] FULLWIDTH FULL STOP..FULLWIDTH SOLIDUS +FF10..FF19;F # Nd [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE +FF1A..FF1B;F # Po [2] FULLWIDTH COLON..FULLWIDTH SEMICOLON +FF1C..FF1E;F # Sm [3] FULLWIDTH LESS-THAN SIGN..FULLWIDTH GREATER-THAN SIGN +FF1F..FF20;F # Po [2] FULLWIDTH QUESTION MARK..FULLWIDTH COMMERCIAL AT +FF21..FF3A;F # Lu [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z +FF3B;F # Ps FULLWIDTH LEFT SQUARE BRACKET +FF3C;F # Po FULLWIDTH REVERSE SOLIDUS +FF3D;F # Pe FULLWIDTH RIGHT SQUARE BRACKET +FF3E;F # Sk FULLWIDTH CIRCUMFLEX ACCENT +FF3F;F # Pc FULLWIDTH LOW LINE +FF40;F # Sk FULLWIDTH GRAVE ACCENT +FF41..FF5A;F # Ll [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z +FF5B;F # Ps FULLWIDTH LEFT CURLY BRACKET +FF5C;F # Sm FULLWIDTH VERTICAL LINE +FF5D;F # Pe FULLWIDTH RIGHT CURLY BRACKET +FF5E;F # Sm FULLWIDTH TILDE +FF5F;F # Ps FULLWIDTH LEFT WHITE PARENTHESIS +FF60;F # Pe FULLWIDTH RIGHT WHITE PARENTHESIS +FF61;H # Po HALFWIDTH IDEOGRAPHIC FULL STOP +FF62;H # Ps HALFWIDTH LEFT CORNER BRACKET +FF63;H # Pe HALFWIDTH RIGHT CORNER BRACKET +FF64..FF65;H # Po [2] HALFWIDTH IDEOGRAPHIC COMMA..HALFWIDTH KATAKANA MIDDLE DOT +FF66..FF6F;H # Lo [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU +FF70;H # Lm HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK +FF71..FF9D;H # Lo [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N +FF9E..FF9F;H # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK +FFA0..FFBE;H # Lo [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH +FFC2..FFC7;H # Lo [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E +FFCA..FFCF;H # Lo [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE +FFD2..FFD7;H # Lo [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU +FFDA..FFDC;H # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I +FFE0..FFE1;F # Sc [2] FULLWIDTH CENT SIGN..FULLWIDTH POUND SIGN +FFE2;F # Sm FULLWIDTH NOT SIGN +FFE3;F # Sk FULLWIDTH MACRON +FFE4;F # So FULLWIDTH BROKEN BAR +FFE5..FFE6;F # Sc [2] FULLWIDTH YEN SIGN..FULLWIDTH WON SIGN +FFE8;H # So HALFWIDTH FORMS LIGHT VERTICAL +FFE9..FFEC;H # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS ARROW +FFED..FFEE;H # So [2] HALFWIDTH BLACK SQUARE..HALFWIDTH WHITE CIRCLE +FFF9..FFFB;N # Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR +FFFC;N # So OBJECT REPLACEMENT CHARACTER +FFFD;A # So REPLACEMENT CHARACTER +10000..1000B;N # Lo [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE +1000D..10026;N # Lo [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO +10028..1003A;N # Lo [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO +1003C..1003D;N # Lo [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE +1003F..1004D;N # Lo [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO +10050..1005D;N # Lo [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089 +10080..100FA;N # Lo [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305 +10100..10102;N # Po [3] AEGEAN WORD SEPARATOR LINE..AEGEAN CHECK MARK +10107..10133;N # No [45] AEGEAN NUMBER ONE..AEGEAN NUMBER NINETY THOUSAND +10137..1013F;N # So [9] AEGEAN WEIGHT BASE UNIT..AEGEAN MEASURE THIRD SUBUNIT +10140..10174;N # Nl [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS +10175..10178;N # No [4] GREEK ONE HALF SIGN..GREEK THREE QUARTERS SIGN +10179..10189;N # So [17] GREEK YEAR SIGN..GREEK TRYBLION BASE SIGN +1018A..1018B;N # No [2] GREEK ZERO SIGN..GREEK ONE QUARTER SIGN +1018C..1018E;N # So [3] GREEK SINUSOID SIGN..NOMISMA SIGN +10190..1019B;N # So [12] ROMAN SEXTANS SIGN..ROMAN CENTURIAL SIGN +101A0;N # So GREEK SYMBOL TAU RHO +101D0..101FC;N # So [45] PHAISTOS DISC SIGN PEDESTRIAN..PHAISTOS DISC SIGN WAVY BAND +101FD;N # Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE +10280..1029C;N # Lo [29] LYCIAN LETTER A..LYCIAN LETTER X +102A0..102D0;N # Lo [49] CARIAN LETTER A..CARIAN LETTER UUU3 +102E0;N # Mn COPTIC EPACT THOUSANDS MARK +102E1..102FB;N # No [27] COPTIC EPACT DIGIT ONE..COPTIC EPACT NUMBER NINE HUNDRED +10300..1031F;N # Lo [32] OLD ITALIC LETTER A..OLD ITALIC LETTER ESS +10320..10323;N # No [4] OLD ITALIC NUMERAL ONE..OLD ITALIC NUMERAL FIFTY +1032D..1032F;N # Lo [3] OLD ITALIC LETTER YE..OLD ITALIC LETTER SOUTHERN TSE +10330..10340;N # Lo [17] GOTHIC LETTER AHSA..GOTHIC LETTER PAIRTHRA +10341;N # Nl GOTHIC LETTER NINETY +10342..10349;N # Lo [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL +1034A;N # Nl GOTHIC LETTER NINE HUNDRED +10350..10375;N # Lo [38] OLD PERMIC LETTER AN..OLD PERMIC LETTER IA +10376..1037A;N # Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII +10380..1039D;N # Lo [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU +1039F;N # Po UGARITIC WORD DIVIDER +103A0..103C3;N # Lo [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA +103C8..103CF;N # Lo [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH +103D0;N # Po OLD PERSIAN WORD DIVIDER +103D1..103D5;N # Nl [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED +10400..1044F;N # L& [80] DESERET CAPITAL LETTER LONG I..DESERET SMALL LETTER EW +10450..1047F;N # Lo [48] SHAVIAN LETTER PEEP..SHAVIAN LETTER YEW +10480..1049D;N # Lo [30] OSMANYA LETTER ALEF..OSMANYA LETTER OO +104A0..104A9;N # Nd [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE +104B0..104D3;N # Lu [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA +104D8..104FB;N # Ll [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA +10500..10527;N # Lo [40] ELBASAN LETTER A..ELBASAN LETTER KHE +10530..10563;N # Lo [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW +1056F;N # Po CAUCASIAN ALBANIAN CITATION MARK +10600..10736;N # Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 +10740..10755;N # Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE +10760..10767;N # Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 +10800..10805;N # Lo [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA +10808;N # Lo CYPRIOT SYLLABLE JO +1080A..10835;N # Lo [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO +10837..10838;N # Lo [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE +1083C;N # Lo CYPRIOT SYLLABLE ZA +1083F;N # Lo CYPRIOT SYLLABLE ZO +10840..10855;N # Lo [22] IMPERIAL ARAMAIC LETTER ALEPH..IMPERIAL ARAMAIC LETTER TAW +10857;N # Po IMPERIAL ARAMAIC SECTION SIGN +10858..1085F;N # No [8] IMPERIAL ARAMAIC NUMBER ONE..IMPERIAL ARAMAIC NUMBER TEN THOUSAND +10860..10876;N # Lo [23] PALMYRENE LETTER ALEPH..PALMYRENE LETTER TAW +10877..10878;N # So [2] PALMYRENE LEFT-POINTING FLEURON..PALMYRENE RIGHT-POINTING FLEURON +10879..1087F;N # No [7] PALMYRENE NUMBER ONE..PALMYRENE NUMBER TWENTY +10880..1089E;N # Lo [31] NABATAEAN LETTER FINAL ALEPH..NABATAEAN LETTER TAW +108A7..108AF;N # No [9] NABATAEAN NUMBER ONE..NABATAEAN NUMBER ONE HUNDRED +108E0..108F2;N # Lo [19] HATRAN LETTER ALEPH..HATRAN LETTER QOPH +108F4..108F5;N # Lo [2] HATRAN LETTER SHIN..HATRAN LETTER TAW +108FB..108FF;N # No [5] HATRAN NUMBER ONE..HATRAN NUMBER ONE HUNDRED +10900..10915;N # Lo [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU +10916..1091B;N # No [6] PHOENICIAN NUMBER ONE..PHOENICIAN NUMBER THREE +1091F;N # Po PHOENICIAN WORD SEPARATOR +10920..10939;N # Lo [26] LYDIAN LETTER A..LYDIAN LETTER C +1093F;N # Po LYDIAN TRIANGULAR MARK +10980..1099F;N # Lo [32] MEROITIC HIEROGLYPHIC LETTER A..MEROITIC HIEROGLYPHIC SYMBOL VIDJ-2 +109A0..109B7;N # Lo [24] MEROITIC CURSIVE LETTER A..MEROITIC CURSIVE LETTER DA +109BC..109BD;N # No [2] MEROITIC CURSIVE FRACTION ELEVEN TWELFTHS..MEROITIC CURSIVE FRACTION ONE HALF +109BE..109BF;N # Lo [2] MEROITIC CURSIVE LOGOGRAM RMT..MEROITIC CURSIVE LOGOGRAM IMN +109C0..109CF;N # No [16] MEROITIC CURSIVE NUMBER ONE..MEROITIC CURSIVE NUMBER SEVENTY +109D2..109FF;N # No [46] MEROITIC CURSIVE NUMBER ONE HUNDRED..MEROITIC CURSIVE FRACTION TEN TWELFTHS +10A00;N # Lo KHAROSHTHI LETTER A +10A01..10A03;N # Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R +10A05..10A06;N # Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O +10A0C..10A0F;N # Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA +10A10..10A13;N # Lo [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA +10A15..10A17;N # Lo [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA +10A19..10A35;N # Lo [29] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER VHA +10A38..10A3A;N # Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW +10A3F;N # Mn KHAROSHTHI VIRAMA +10A40..10A48;N # No [9] KHAROSHTHI DIGIT ONE..KHAROSHTHI FRACTION ONE HALF +10A50..10A58;N # Po [9] KHAROSHTHI PUNCTUATION DOT..KHAROSHTHI PUNCTUATION LINES +10A60..10A7C;N # Lo [29] OLD SOUTH ARABIAN LETTER HE..OLD SOUTH ARABIAN LETTER THETH +10A7D..10A7E;N # No [2] OLD SOUTH ARABIAN NUMBER ONE..OLD SOUTH ARABIAN NUMBER FIFTY +10A7F;N # Po OLD SOUTH ARABIAN NUMERIC INDICATOR +10A80..10A9C;N # Lo [29] OLD NORTH ARABIAN LETTER HEH..OLD NORTH ARABIAN LETTER ZAH +10A9D..10A9F;N # No [3] OLD NORTH ARABIAN NUMBER ONE..OLD NORTH ARABIAN NUMBER TWENTY +10AC0..10AC7;N # Lo [8] MANICHAEAN LETTER ALEPH..MANICHAEAN LETTER WAW +10AC8;N # So MANICHAEAN SIGN UD +10AC9..10AE4;N # Lo [28] MANICHAEAN LETTER ZAYIN..MANICHAEAN LETTER TAW +10AE5..10AE6;N # Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW +10AEB..10AEF;N # No [5] MANICHAEAN NUMBER ONE..MANICHAEAN NUMBER ONE HUNDRED +10AF0..10AF6;N # Po [7] MANICHAEAN PUNCTUATION STAR..MANICHAEAN PUNCTUATION LINE FILLER +10B00..10B35;N # Lo [54] AVESTAN LETTER A..AVESTAN LETTER HE +10B39..10B3F;N # Po [7] AVESTAN ABBREVIATION MARK..LARGE ONE RING OVER TWO RINGS PUNCTUATION +10B40..10B55;N # Lo [22] INSCRIPTIONAL PARTHIAN LETTER ALEPH..INSCRIPTIONAL PARTHIAN LETTER TAW +10B58..10B5F;N # No [8] INSCRIPTIONAL PARTHIAN NUMBER ONE..INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND +10B60..10B72;N # Lo [19] INSCRIPTIONAL PAHLAVI LETTER ALEPH..INSCRIPTIONAL PAHLAVI LETTER TAW +10B78..10B7F;N # No [8] INSCRIPTIONAL PAHLAVI NUMBER ONE..INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND +10B80..10B91;N # Lo [18] PSALTER PAHLAVI LETTER ALEPH..PSALTER PAHLAVI LETTER TAW +10B99..10B9C;N # Po [4] PSALTER PAHLAVI SECTION MARK..PSALTER PAHLAVI FOUR DOTS WITH DOT +10BA9..10BAF;N # No [7] PSALTER PAHLAVI NUMBER ONE..PSALTER PAHLAVI NUMBER ONE HUNDRED +10C00..10C48;N # Lo [73] OLD TURKIC LETTER ORKHON A..OLD TURKIC LETTER ORKHON BASH +10C80..10CB2;N # Lu [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US +10CC0..10CF2;N # Ll [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US +10CFA..10CFF;N # No [6] OLD HUNGARIAN NUMBER ONE..OLD HUNGARIAN NUMBER ONE THOUSAND +10D00..10D23;N # Lo [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA +10D24..10D27;N # Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI +10D30..10D39;N # Nd [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE +10E60..10E7E;N # No [31] RUMI DIGIT ONE..RUMI FRACTION TWO THIRDS +10F00..10F1C;N # Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL +10F1D..10F26;N # No [10] OLD SOGDIAN NUMBER ONE..OLD SOGDIAN FRACTION ONE HALF +10F27;N # Lo OLD SOGDIAN LIGATURE AYIN-DALETH +10F30..10F45;N # Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN +10F46..10F50;N # Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW +10F51..10F54;N # No [4] SOGDIAN NUMBER ONE..SOGDIAN NUMBER ONE HUNDRED +10F55..10F59;N # Po [5] SOGDIAN PUNCTUATION TWO VERTICAL BARS..SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT +10FE0..10FF6;N # Lo [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH +11000;N # Mc BRAHMI SIGN CANDRABINDU +11001;N # Mn BRAHMI SIGN ANUSVARA +11002;N # Mc BRAHMI SIGN VISARGA +11003..11037;N # Lo [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA +11038..11046;N # Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA +11047..1104D;N # Po [7] BRAHMI DANDA..BRAHMI PUNCTUATION LOTUS +11052..11065;N # No [20] BRAHMI NUMBER ONE..BRAHMI NUMBER ONE THOUSAND +11066..1106F;N # Nd [10] BRAHMI DIGIT ZERO..BRAHMI DIGIT NINE +1107F;N # Mn BRAHMI NUMBER JOINER +11080..11081;N # Mn [2] KAITHI SIGN CANDRABINDU..KAITHI SIGN ANUSVARA +11082;N # Mc KAITHI SIGN VISARGA +11083..110AF;N # Lo [45] KAITHI LETTER A..KAITHI LETTER HA +110B0..110B2;N # Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II +110B3..110B6;N # Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI +110B7..110B8;N # Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU +110B9..110BA;N # Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA +110BB..110BC;N # Po [2] KAITHI ABBREVIATION SIGN..KAITHI ENUMERATION SIGN +110BD;N # Cf KAITHI NUMBER SIGN +110BE..110C1;N # Po [4] KAITHI SECTION MARK..KAITHI DOUBLE DANDA +110CD;N # Cf KAITHI NUMBER SIGN ABOVE +110D0..110E8;N # Lo [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE +110F0..110F9;N # Nd [10] SORA SOMPENG DIGIT ZERO..SORA SOMPENG DIGIT NINE +11100..11102;N # Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA +11103..11126;N # Lo [36] CHAKMA LETTER AA..CHAKMA LETTER HAA +11127..1112B;N # Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU +1112C;N # Mc CHAKMA VOWEL SIGN E +1112D..11134;N # Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA +11136..1113F;N # Nd [10] CHAKMA DIGIT ZERO..CHAKMA DIGIT NINE +11140..11143;N # Po [4] CHAKMA SECTION MARK..CHAKMA QUESTION MARK +11144;N # Lo CHAKMA LETTER LHAA +11145..11146;N # Mc [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI +11150..11172;N # Lo [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA +11173;N # Mn MAHAJANI SIGN NUKTA +11174..11175;N # Po [2] MAHAJANI ABBREVIATION SIGN..MAHAJANI SECTION MARK +11176;N # Lo MAHAJANI LIGATURE SHRI +11180..11181;N # Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA +11182;N # Mc SHARADA SIGN VISARGA +11183..111B2;N # Lo [48] SHARADA LETTER A..SHARADA LETTER HA +111B3..111B5;N # Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II +111B6..111BE;N # Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O +111BF..111C0;N # Mc [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA +111C1..111C4;N # Lo [4] SHARADA SIGN AVAGRAHA..SHARADA OM +111C5..111C8;N # Po [4] SHARADA DANDA..SHARADA SEPARATOR +111C9..111CC;N # Mn [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK +111CD;N # Po SHARADA SUTRA MARK +111D0..111D9;N # Nd [10] SHARADA DIGIT ZERO..SHARADA DIGIT NINE +111DA;N # Lo SHARADA EKAM +111DB;N # Po SHARADA SIGN SIDDHAM +111DC;N # Lo SHARADA HEADSTROKE +111DD..111DF;N # Po [3] SHARADA CONTINUATION SIGN..SHARADA SECTION MARK-2 +111E1..111F4;N # No [20] SINHALA ARCHAIC DIGIT ONE..SINHALA ARCHAIC NUMBER ONE THOUSAND +11200..11211;N # Lo [18] KHOJKI LETTER A..KHOJKI LETTER JJA +11213..1122B;N # Lo [25] KHOJKI LETTER NYA..KHOJKI LETTER LLA +1122C..1122E;N # Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II +1122F..11231;N # Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI +11232..11233;N # Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU +11234;N # Mn KHOJKI SIGN ANUSVARA +11235;N # Mc KHOJKI SIGN VIRAMA +11236..11237;N # Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA +11238..1123D;N # Po [6] KHOJKI DANDA..KHOJKI ABBREVIATION SIGN +1123E;N # Mn KHOJKI SIGN SUKUN +11280..11286;N # Lo [7] MULTANI LETTER A..MULTANI LETTER GA +11288;N # Lo MULTANI LETTER GHA +1128A..1128D;N # Lo [4] MULTANI LETTER CA..MULTANI LETTER JJA +1128F..1129D;N # Lo [15] MULTANI LETTER NYA..MULTANI LETTER BA +1129F..112A8;N # Lo [10] MULTANI LETTER BHA..MULTANI LETTER RHA +112A9;N # Po MULTANI SECTION MARK +112B0..112DE;N # Lo [47] KHUDAWADI LETTER A..KHUDAWADI LETTER HA +112DF;N # Mn KHUDAWADI SIGN ANUSVARA +112E0..112E2;N # Mc [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II +112E3..112EA;N # Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA +112F0..112F9;N # Nd [10] KHUDAWADI DIGIT ZERO..KHUDAWADI DIGIT NINE +11300..11301;N # Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU +11302..11303;N # Mc [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA +11305..1130C;N # Lo [8] GRANTHA LETTER A..GRANTHA LETTER VOCALIC L +1130F..11310;N # Lo [2] GRANTHA LETTER EE..GRANTHA LETTER AI +11313..11328;N # Lo [22] GRANTHA LETTER OO..GRANTHA LETTER NA +1132A..11330;N # Lo [7] GRANTHA LETTER PA..GRANTHA LETTER RA +11332..11333;N # Lo [2] GRANTHA LETTER LA..GRANTHA LETTER LLA +11335..11339;N # Lo [5] GRANTHA LETTER VA..GRANTHA LETTER HA +1133B..1133C;N # Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA +1133D;N # Lo GRANTHA SIGN AVAGRAHA +1133E..1133F;N # Mc [2] GRANTHA VOWEL SIGN AA..GRANTHA VOWEL SIGN I +11340;N # Mn GRANTHA VOWEL SIGN II +11341..11344;N # Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR +11347..11348;N # Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI +1134B..1134D;N # Mc [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA +11350;N # Lo GRANTHA OM +11357;N # Mc GRANTHA AU LENGTH MARK +1135D..11361;N # Lo [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL +11362..11363;N # Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL +11366..1136C;N # Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX +11370..11374;N # Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA +11400..11434;N # Lo [53] NEWA LETTER A..NEWA LETTER HA +11435..11437;N # Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II +11438..1143F;N # Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI +11440..11441;N # Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU +11442..11444;N # Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA +11445;N # Mc NEWA SIGN VISARGA +11446;N # Mn NEWA SIGN NUKTA +11447..1144A;N # Lo [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI +1144B..1144F;N # Po [5] NEWA DANDA..NEWA ABBREVIATION SIGN +11450..11459;N # Nd [10] NEWA DIGIT ZERO..NEWA DIGIT NINE +1145B;N # Po NEWA PLACEHOLDER MARK +1145D;N # Po NEWA INSERTION SIGN +1145E;N # Mn NEWA SANDHI MARK +1145F;N # Lo NEWA LETTER VEDIC ANUSVARA +11480..114AF;N # Lo [48] TIRHUTA ANJI..TIRHUTA LETTER HA +114B0..114B2;N # Mc [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II +114B3..114B8;N # Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL +114B9;N # Mc TIRHUTA VOWEL SIGN E +114BA;N # Mn TIRHUTA VOWEL SIGN SHORT E +114BB..114BE;N # Mc [4] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN AU +114BF..114C0;N # Mn [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA +114C1;N # Mc TIRHUTA SIGN VISARGA +114C2..114C3;N # Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA +114C4..114C5;N # Lo [2] TIRHUTA SIGN AVAGRAHA..TIRHUTA GVANG +114C6;N # Po TIRHUTA ABBREVIATION SIGN +114C7;N # Lo TIRHUTA OM +114D0..114D9;N # Nd [10] TIRHUTA DIGIT ZERO..TIRHUTA DIGIT NINE +11580..115AE;N # Lo [47] SIDDHAM LETTER A..SIDDHAM LETTER HA +115AF..115B1;N # Mc [3] SIDDHAM VOWEL SIGN AA..SIDDHAM VOWEL SIGN II +115B2..115B5;N # Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR +115B8..115BB;N # Mc [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU +115BC..115BD;N # Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA +115BE;N # Mc SIDDHAM SIGN VISARGA +115BF..115C0;N # Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA +115C1..115D7;N # Po [23] SIDDHAM SIGN SIDDHAM..SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES +115D8..115DB;N # Lo [4] SIDDHAM LETTER THREE-CIRCLE ALTERNATE I..SIDDHAM LETTER ALTERNATE U +115DC..115DD;N # Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU +11600..1162F;N # Lo [48] MODI LETTER A..MODI LETTER LLA +11630..11632;N # Mc [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II +11633..1163A;N # Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI +1163B..1163C;N # Mc [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU +1163D;N # Mn MODI SIGN ANUSVARA +1163E;N # Mc MODI SIGN VISARGA +1163F..11640;N # Mn [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA +11641..11643;N # Po [3] MODI DANDA..MODI ABBREVIATION SIGN +11644;N # Lo MODI SIGN HUVA +11650..11659;N # Nd [10] MODI DIGIT ZERO..MODI DIGIT NINE +11660..1166C;N # Po [13] MONGOLIAN BIRGA WITH ORNAMENT..MONGOLIAN TURNED SWIRL BIRGA WITH DOUBLE ORNAMENT +11680..116AA;N # Lo [43] TAKRI LETTER A..TAKRI LETTER RRA +116AB;N # Mn TAKRI SIGN ANUSVARA +116AC;N # Mc TAKRI SIGN VISARGA +116AD;N # Mn TAKRI VOWEL SIGN AA +116AE..116AF;N # Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II +116B0..116B5;N # Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU +116B6;N # Mc TAKRI SIGN VIRAMA +116B7;N # Mn TAKRI SIGN NUKTA +116B8;N # Lo TAKRI LETTER ARCHAIC KHA +116C0..116C9;N # Nd [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE +11700..1171A;N # Lo [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA +1171D..1171F;N # Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA +11720..11721;N # Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA +11722..11725;N # Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU +11726;N # Mc AHOM VOWEL SIGN E +11727..1172B;N # Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER +11730..11739;N # Nd [10] AHOM DIGIT ZERO..AHOM DIGIT NINE +1173A..1173B;N # No [2] AHOM NUMBER TEN..AHOM NUMBER TWENTY +1173C..1173E;N # Po [3] AHOM SIGN SMALL SECTION..AHOM SIGN RULAI +1173F;N # So AHOM SYMBOL VI +11800..1182B;N # Lo [44] DOGRA LETTER A..DOGRA LETTER RRA +1182C..1182E;N # Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II +1182F..11837;N # Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA +11838;N # Mc DOGRA SIGN VISARGA +11839..1183A;N # Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA +1183B;N # Po DOGRA ABBREVIATION SIGN +118A0..118DF;N # L& [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO +118E0..118E9;N # Nd [10] WARANG CITI DIGIT ZERO..WARANG CITI DIGIT NINE +118EA..118F2;N # No [9] WARANG CITI NUMBER TEN..WARANG CITI NUMBER NINETY +118FF;N # Lo WARANG CITI OM +119A0..119A7;N # Lo [8] NANDINAGARI LETTER A..NANDINAGARI LETTER VOCALIC RR +119AA..119D0;N # Lo [39] NANDINAGARI LETTER E..NANDINAGARI LETTER RRA +119D1..119D3;N # Mc [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II +119D4..119D7;N # Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR +119DA..119DB;N # Mn [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI +119DC..119DF;N # Mc [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA +119E0;N # Mn NANDINAGARI SIGN VIRAMA +119E1;N # Lo NANDINAGARI SIGN AVAGRAHA +119E2;N # Po NANDINAGARI SIGN SIDDHAM +119E3;N # Lo NANDINAGARI HEADSTROKE +119E4;N # Mc NANDINAGARI VOWEL SIGN PRISHTHAMATRA E +11A00;N # Lo ZANABAZAR SQUARE LETTER A +11A01..11A0A;N # Mn [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK +11A0B..11A32;N # Lo [40] ZANABAZAR SQUARE LETTER KA..ZANABAZAR SQUARE LETTER KSSA +11A33..11A38;N # Mn [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA +11A39;N # Mc ZANABAZAR SQUARE SIGN VISARGA +11A3A;N # Lo ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA +11A3B..11A3E;N # Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA +11A3F..11A46;N # Po [8] ZANABAZAR SQUARE INITIAL HEAD MARK..ZANABAZAR SQUARE CLOSING DOUBLE-LINED HEAD MARK +11A47;N # Mn ZANABAZAR SQUARE SUBJOINER +11A50;N # Lo SOYOMBO LETTER A +11A51..11A56;N # Mn [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE +11A57..11A58;N # Mc [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU +11A59..11A5B;N # Mn [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK +11A5C..11A89;N # Lo [46] SOYOMBO LETTER KA..SOYOMBO CLUSTER-INITIAL LETTER SA +11A8A..11A96;N # Mn [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA +11A97;N # Mc SOYOMBO SIGN VISARGA +11A98..11A99;N # Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER +11A9A..11A9C;N # Po [3] SOYOMBO MARK TSHEG..SOYOMBO MARK DOUBLE SHAD +11A9D;N # Lo SOYOMBO MARK PLUTA +11A9E..11AA2;N # Po [5] SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME..SOYOMBO TERMINAL MARK-2 +11AC0..11AF8;N # Lo [57] PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL +11C00..11C08;N # Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L +11C0A..11C2E;N # Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA +11C2F;N # Mc BHAIKSUKI VOWEL SIGN AA +11C30..11C36;N # Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L +11C38..11C3D;N # Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA +11C3E;N # Mc BHAIKSUKI SIGN VISARGA +11C3F;N # Mn BHAIKSUKI SIGN VIRAMA +11C40;N # Lo BHAIKSUKI SIGN AVAGRAHA +11C41..11C45;N # Po [5] BHAIKSUKI DANDA..BHAIKSUKI GAP FILLER-2 +11C50..11C59;N # Nd [10] BHAIKSUKI DIGIT ZERO..BHAIKSUKI DIGIT NINE +11C5A..11C6C;N # No [19] BHAIKSUKI NUMBER ONE..BHAIKSUKI HUNDREDS UNIT MARK +11C70..11C71;N # Po [2] MARCHEN HEAD MARK..MARCHEN MARK SHAD +11C72..11C8F;N # Lo [30] MARCHEN LETTER KA..MARCHEN LETTER A +11C92..11CA7;N # Mn [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA +11CA9;N # Mc MARCHEN SUBJOINED LETTER YA +11CAA..11CB0;N # Mn [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA +11CB1;N # Mc MARCHEN VOWEL SIGN I +11CB2..11CB3;N # Mn [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E +11CB4;N # Mc MARCHEN VOWEL SIGN O +11CB5..11CB6;N # Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU +11D00..11D06;N # Lo [7] MASARAM GONDI LETTER A..MASARAM GONDI LETTER E +11D08..11D09;N # Lo [2] MASARAM GONDI LETTER AI..MASARAM GONDI LETTER O +11D0B..11D30;N # Lo [38] MASARAM GONDI LETTER AU..MASARAM GONDI LETTER TRA +11D31..11D36;N # Mn [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R +11D3A;N # Mn MASARAM GONDI VOWEL SIGN E +11D3C..11D3D;N # Mn [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O +11D3F..11D45;N # Mn [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA +11D46;N # Lo MASARAM GONDI REPHA +11D47;N # Mn MASARAM GONDI RA-KARA +11D50..11D59;N # Nd [10] MASARAM GONDI DIGIT ZERO..MASARAM GONDI DIGIT NINE +11D60..11D65;N # Lo [6] GUNJALA GONDI LETTER A..GUNJALA GONDI LETTER UU +11D67..11D68;N # Lo [2] GUNJALA GONDI LETTER EE..GUNJALA GONDI LETTER AI +11D6A..11D89;N # Lo [32] GUNJALA GONDI LETTER OO..GUNJALA GONDI LETTER SA +11D8A..11D8E;N # Mc [5] GUNJALA GONDI VOWEL SIGN AA..GUNJALA GONDI VOWEL SIGN UU +11D90..11D91;N # Mn [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI +11D93..11D94;N # Mc [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU +11D95;N # Mn GUNJALA GONDI SIGN ANUSVARA +11D96;N # Mc GUNJALA GONDI SIGN VISARGA +11D97;N # Mn GUNJALA GONDI VIRAMA +11D98;N # Lo GUNJALA GONDI OM +11DA0..11DA9;N # Nd [10] GUNJALA GONDI DIGIT ZERO..GUNJALA GONDI DIGIT NINE +11EE0..11EF2;N # Lo [19] MAKASAR LETTER KA..MAKASAR ANGKA +11EF3..11EF4;N # Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U +11EF5..11EF6;N # Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O +11EF7..11EF8;N # Po [2] MAKASAR PASSIMBANG..MAKASAR END OF SECTION +11FC0..11FD4;N # No [21] TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH..TAMIL FRACTION DOWNSCALING FACTOR KIIZH +11FD5..11FDC;N # So [8] TAMIL SIGN NEL..TAMIL SIGN MUKKURUNI +11FDD..11FE0;N # Sc [4] TAMIL SIGN KAACU..TAMIL SIGN VARAAKAN +11FE1..11FF1;N # So [17] TAMIL SIGN PAARAM..TAMIL SIGN VAKAIYARAA +11FFF;N # Po TAMIL PUNCTUATION END OF TEXT +12000..12399;N # Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U +12400..1246E;N # Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM +12470..12474;N # Po [5] CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER..CUNEIFORM PUNCTUATION SIGN DIAGONAL QUADCOLON +12480..12543;N # Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU +13000..1342E;N # Lo [1071] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH AA032 +13430..13438;N # Cf [9] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END SEGMENT +14400..14646;N # Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 +16800..16A38;N # Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ +16A40..16A5E;N # Lo [31] MRO LETTER TA..MRO LETTER TEK +16A60..16A69;N # Nd [10] MRO DIGIT ZERO..MRO DIGIT NINE +16A6E..16A6F;N # Po [2] MRO DANDA..MRO DOUBLE DANDA +16AD0..16AED;N # Lo [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I +16AF0..16AF4;N # Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE +16AF5;N # Po BASSA VAH FULL STOP +16B00..16B2F;N # Lo [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU +16B30..16B36;N # Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM +16B37..16B3B;N # Po [5] PAHAWH HMONG SIGN VOS THOM..PAHAWH HMONG SIGN VOS FEEM +16B3C..16B3F;N # So [4] PAHAWH HMONG SIGN XYEEM NTXIV..PAHAWH HMONG SIGN XYEEM FAIB +16B40..16B43;N # Lm [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM +16B44;N # Po PAHAWH HMONG SIGN XAUS +16B45;N # So PAHAWH HMONG SIGN CIM TSOV ROG +16B50..16B59;N # Nd [10] PAHAWH HMONG DIGIT ZERO..PAHAWH HMONG DIGIT NINE +16B5B..16B61;N # No [7] PAHAWH HMONG NUMBER TENS..PAHAWH HMONG NUMBER TRILLIONS +16B63..16B77;N # Lo [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS +16B7D..16B8F;N # Lo [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ +16E40..16E7F;N # L& [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y +16E80..16E96;N # No [23] MEDEFAIDRIN DIGIT ZERO..MEDEFAIDRIN DIGIT THREE ALTERNATE FORM +16E97..16E9A;N # Po [4] MEDEFAIDRIN COMMA..MEDEFAIDRIN EXCLAMATION OH +16F00..16F4A;N # Lo [75] MIAO LETTER PA..MIAO LETTER RTE +16F4F;N # Mn MIAO SIGN CONSONANT MODIFIER BAR +16F50;N # Lo MIAO LETTER NASALIZATION +16F51..16F87;N # Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI +16F8F..16F92;N # Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW +16F93..16F9F;N # Lm [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8 +16FE0..16FE1;W # Lm [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK +16FE2;W # Po OLD CHINESE HOOK MARK +16FE3;W # Lm OLD CHINESE ITERATION MARK +17000..187F7;W # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 +18800..18AF2;W # Lo [755] TANGUT COMPONENT-001..TANGUT COMPONENT-755 +1B000..1B0FF;W # Lo [256] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER RE-2 +1B100..1B11E;W # Lo [31] HENTAIGANA LETTER RE-3..HENTAIGANA LETTER N-MU-MO-2 +1B150..1B152;W # Lo [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO +1B164..1B167;W # Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N +1B170..1B2FB;W # Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB +1BC00..1BC6A;N # Lo [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M +1BC70..1BC7C;N # Lo [13] DUPLOYAN AFFIX LEFT HORIZONTAL SECANT..DUPLOYAN AFFIX ATTACHED TANGENT HOOK +1BC80..1BC88;N # Lo [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL +1BC90..1BC99;N # Lo [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW +1BC9C;N # So DUPLOYAN SIGN O WITH CROSS +1BC9D..1BC9E;N # Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK +1BC9F;N # Po DUPLOYAN PUNCTUATION CHINOOK FULL STOP +1BCA0..1BCA3;N # Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP +1D000..1D0F5;N # So [246] BYZANTINE MUSICAL SYMBOL PSILI..BYZANTINE MUSICAL SYMBOL GORGON NEO KATO +1D100..1D126;N # So [39] MUSICAL SYMBOL SINGLE BARLINE..MUSICAL SYMBOL DRUM CLEF-2 +1D129..1D164;N # So [60] MUSICAL SYMBOL MULTIPLE MEASURE REST..MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE +1D165..1D166;N # Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM +1D167..1D169;N # Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 +1D16A..1D16C;N # So [3] MUSICAL SYMBOL FINGERED TREMOLO-1..MUSICAL SYMBOL FINGERED TREMOLO-3 +1D16D..1D172;N # Mc [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5 +1D173..1D17A;N # Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE +1D17B..1D182;N # Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE +1D183..1D184;N # So [2] MUSICAL SYMBOL ARPEGGIATO UP..MUSICAL SYMBOL ARPEGGIATO DOWN +1D185..1D18B;N # Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE +1D18C..1D1A9;N # So [30] MUSICAL SYMBOL RINFORZANDO..MUSICAL SYMBOL DEGREE SLASH +1D1AA..1D1AD;N # Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO +1D1AE..1D1E8;N # So [59] MUSICAL SYMBOL PEDAL MARK..MUSICAL SYMBOL KIEVAN FLAT SIGN +1D200..1D241;N # So [66] GREEK VOCAL NOTATION SYMBOL-1..GREEK INSTRUMENTAL NOTATION SYMBOL-54 +1D242..1D244;N # Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME +1D245;N # So GREEK MUSICAL LEIMMA +1D2E0..1D2F3;N # No [20] MAYAN NUMERAL ZERO..MAYAN NUMERAL NINETEEN +1D300..1D356;N # So [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING +1D360..1D378;N # No [25] COUNTING ROD UNIT DIGIT ONE..TALLY MARK FIVE +1D400..1D454;N # L& [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G +1D456..1D49C;N # L& [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A +1D49E..1D49F;N # Lu [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D +1D4A2;N # Lu MATHEMATICAL SCRIPT CAPITAL G +1D4A5..1D4A6;N # Lu [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K +1D4A9..1D4AC;N # Lu [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q +1D4AE..1D4B9;N # L& [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D +1D4BB;N # Ll MATHEMATICAL SCRIPT SMALL F +1D4BD..1D4C3;N # Ll [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N +1D4C5..1D505;N # L& [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B +1D507..1D50A;N # Lu [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G +1D50D..1D514;N # Lu [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q +1D516..1D51C;N # Lu [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y +1D51E..1D539;N # L& [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B +1D53B..1D53E;N # Lu [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G +1D540..1D544;N # Lu [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M +1D546;N # Lu MATHEMATICAL DOUBLE-STRUCK CAPITAL O +1D54A..1D550;N # Lu [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y +1D552..1D6A5;N # L& [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J +1D6A8..1D6C0;N # Lu [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA +1D6C1;N # Sm MATHEMATICAL BOLD NABLA +1D6C2..1D6DA;N # Ll [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA +1D6DB;N # Sm MATHEMATICAL BOLD PARTIAL DIFFERENTIAL +1D6DC..1D6FA;N # L& [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA +1D6FB;N # Sm MATHEMATICAL ITALIC NABLA +1D6FC..1D714;N # Ll [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA +1D715;N # Sm MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL +1D716..1D734;N # L& [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA +1D735;N # Sm MATHEMATICAL BOLD ITALIC NABLA +1D736..1D74E;N # Ll [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA +1D74F;N # Sm MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL +1D750..1D76E;N # L& [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA +1D76F;N # Sm MATHEMATICAL SANS-SERIF BOLD NABLA +1D770..1D788;N # Ll [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA +1D789;N # Sm MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL +1D78A..1D7A8;N # L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA +1D7A9;N # Sm MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA +1D7AA..1D7C2;N # Ll [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA +1D7C3;N # Sm MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL +1D7C4..1D7CB;N # L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA +1D7CE..1D7FF;N # Nd [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE +1D800..1D9FF;N # So [512] SIGNWRITING HAND-FIST INDEX..SIGNWRITING HEAD +1DA00..1DA36;N # Mn [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN +1DA37..1DA3A;N # So [4] SIGNWRITING AIR BLOW SMALL ROTATIONS..SIGNWRITING BREATH EXHALE +1DA3B..1DA6C;N # Mn [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT +1DA6D..1DA74;N # So [8] SIGNWRITING SHOULDER HIP SPINE..SIGNWRITING TORSO-FLOORPLANE TWISTING +1DA75;N # Mn SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS +1DA76..1DA83;N # So [14] SIGNWRITING LIMB COMBINATION..SIGNWRITING LOCATION DEPTH +1DA84;N # Mn SIGNWRITING LOCATION HEAD NECK +1DA85..1DA86;N # So [2] SIGNWRITING LOCATION TORSO..SIGNWRITING LOCATION LIMBS DIGITS +1DA87..1DA8B;N # Po [5] SIGNWRITING COMMA..SIGNWRITING PARENTHESIS +1DA9B..1DA9F;N # Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6 +1DAA1..1DAAF;N # Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16 +1E000..1E006;N # Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE +1E008..1E018;N # Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU +1E01B..1E021;N # Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI +1E023..1E024;N # Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS +1E026..1E02A;N # Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA +1E100..1E12C;N # Lo [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W +1E130..1E136;N # Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D +1E137..1E13D;N # Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER +1E140..1E149;N # Nd [10] NYIAKENG PUACHUE HMONG DIGIT ZERO..NYIAKENG PUACHUE HMONG DIGIT NINE +1E14E;N # Lo NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ +1E14F;N # So NYIAKENG PUACHUE HMONG CIRCLED CA +1E2C0..1E2EB;N # Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH +1E2EC..1E2EF;N # Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI +1E2F0..1E2F9;N # Nd [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE +1E2FF;N # Sc WANCHO NGUN SIGN +1E800..1E8C4;N # Lo [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON +1E8C7..1E8CF;N # No [9] MENDE KIKAKUI DIGIT ONE..MENDE KIKAKUI DIGIT NINE +1E8D0..1E8D6;N # Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS +1E900..1E943;N # L& [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA +1E944..1E94A;N # Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA +1E94B;N # Lm ADLAM NASALIZATION MARK +1E950..1E959;N # Nd [10] ADLAM DIGIT ZERO..ADLAM DIGIT NINE +1E95E..1E95F;N # Po [2] ADLAM INITIAL EXCLAMATION MARK..ADLAM INITIAL QUESTION MARK +1EC71..1ECAB;N # No [59] INDIC SIYAQ NUMBER ONE..INDIC SIYAQ NUMBER PREFIXED NINE +1ECAC;N # So INDIC SIYAQ PLACEHOLDER +1ECAD..1ECAF;N # No [3] INDIC SIYAQ FRACTION ONE QUARTER..INDIC SIYAQ FRACTION THREE QUARTERS +1ECB0;N # Sc INDIC SIYAQ RUPEE MARK +1ECB1..1ECB4;N # No [4] INDIC SIYAQ NUMBER ALTERNATE ONE..INDIC SIYAQ ALTERNATE LAKH MARK +1ED01..1ED2D;N # No [45] OTTOMAN SIYAQ NUMBER ONE..OTTOMAN SIYAQ NUMBER NINETY THOUSAND +1ED2E;N # So OTTOMAN SIYAQ MARRATAN +1ED2F..1ED3D;N # No [15] OTTOMAN SIYAQ ALTERNATE NUMBER TWO..OTTOMAN SIYAQ FRACTION ONE SIXTH +1EE00..1EE03;N # Lo [4] ARABIC MATHEMATICAL ALEF..ARABIC MATHEMATICAL DAL +1EE05..1EE1F;N # Lo [27] ARABIC MATHEMATICAL WAW..ARABIC MATHEMATICAL DOTLESS QAF +1EE21..1EE22;N # Lo [2] ARABIC MATHEMATICAL INITIAL BEH..ARABIC MATHEMATICAL INITIAL JEEM +1EE24;N # Lo ARABIC MATHEMATICAL INITIAL HEH +1EE27;N # Lo ARABIC MATHEMATICAL INITIAL HAH +1EE29..1EE32;N # Lo [10] ARABIC MATHEMATICAL INITIAL YEH..ARABIC MATHEMATICAL INITIAL QAF +1EE34..1EE37;N # Lo [4] ARABIC MATHEMATICAL INITIAL SHEEN..ARABIC MATHEMATICAL INITIAL KHAH +1EE39;N # Lo ARABIC MATHEMATICAL INITIAL DAD +1EE3B;N # Lo ARABIC MATHEMATICAL INITIAL GHAIN +1EE42;N # Lo ARABIC MATHEMATICAL TAILED JEEM +1EE47;N # Lo ARABIC MATHEMATICAL TAILED HAH +1EE49;N # Lo ARABIC MATHEMATICAL TAILED YEH +1EE4B;N # Lo ARABIC MATHEMATICAL TAILED LAM +1EE4D..1EE4F;N # Lo [3] ARABIC MATHEMATICAL TAILED NOON..ARABIC MATHEMATICAL TAILED AIN +1EE51..1EE52;N # Lo [2] ARABIC MATHEMATICAL TAILED SAD..ARABIC MATHEMATICAL TAILED QAF +1EE54;N # Lo ARABIC MATHEMATICAL TAILED SHEEN +1EE57;N # Lo ARABIC MATHEMATICAL TAILED KHAH +1EE59;N # Lo ARABIC MATHEMATICAL TAILED DAD +1EE5B;N # Lo ARABIC MATHEMATICAL TAILED GHAIN +1EE5D;N # Lo ARABIC MATHEMATICAL TAILED DOTLESS NOON +1EE5F;N # Lo ARABIC MATHEMATICAL TAILED DOTLESS QAF +1EE61..1EE62;N # Lo [2] ARABIC MATHEMATICAL STRETCHED BEH..ARABIC MATHEMATICAL STRETCHED JEEM +1EE64;N # Lo ARABIC MATHEMATICAL STRETCHED HEH +1EE67..1EE6A;N # Lo [4] ARABIC MATHEMATICAL STRETCHED HAH..ARABIC MATHEMATICAL STRETCHED KAF +1EE6C..1EE72;N # Lo [7] ARABIC MATHEMATICAL STRETCHED MEEM..ARABIC MATHEMATICAL STRETCHED QAF +1EE74..1EE77;N # Lo [4] ARABIC MATHEMATICAL STRETCHED SHEEN..ARABIC MATHEMATICAL STRETCHED KHAH +1EE79..1EE7C;N # Lo [4] ARABIC MATHEMATICAL STRETCHED DAD..ARABIC MATHEMATICAL STRETCHED DOTLESS BEH +1EE7E;N # Lo ARABIC MATHEMATICAL STRETCHED DOTLESS FEH +1EE80..1EE89;N # Lo [10] ARABIC MATHEMATICAL LOOPED ALEF..ARABIC MATHEMATICAL LOOPED YEH +1EE8B..1EE9B;N # Lo [17] ARABIC MATHEMATICAL LOOPED LAM..ARABIC MATHEMATICAL LOOPED GHAIN +1EEA1..1EEA3;N # Lo [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL +1EEA5..1EEA9;N # Lo [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH +1EEAB..1EEBB;N # Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN +1EEF0..1EEF1;N # Sm [2] ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL..ARABIC MATHEMATICAL OPERATOR HAH WITH DAL +1F000..1F003;N # So [4] MAHJONG TILE EAST WIND..MAHJONG TILE NORTH WIND +1F004;W # So MAHJONG TILE RED DRAGON +1F005..1F02B;N # So [39] MAHJONG TILE GREEN DRAGON..MAHJONG TILE BACK +1F030..1F093;N # So [100] DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06 +1F0A0..1F0AE;N # So [15] PLAYING CARD BACK..PLAYING CARD KING OF SPADES +1F0B1..1F0BF;N # So [15] PLAYING CARD ACE OF HEARTS..PLAYING CARD RED JOKER +1F0C1..1F0CE;N # So [14] PLAYING CARD ACE OF DIAMONDS..PLAYING CARD KING OF DIAMONDS +1F0CF;W # So PLAYING CARD BLACK JOKER +1F0D1..1F0F5;N # So [37] PLAYING CARD ACE OF CLUBS..PLAYING CARD TRUMP-21 +1F100..1F10A;A # No [11] DIGIT ZERO FULL STOP..DIGIT NINE COMMA +1F10B..1F10C;N # No [2] DINGBAT CIRCLED SANS-SERIF DIGIT ZERO..DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO +1F110..1F12D;A # So [30] PARENTHESIZED LATIN CAPITAL LETTER A..CIRCLED CD +1F12E..1F12F;N # So [2] CIRCLED WZ..COPYLEFT SYMBOL +1F130..1F169;A # So [58] SQUARED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z +1F16A..1F16C;N # So [3] RAISED MC SIGN..RAISED MR SIGN +1F170..1F18D;A # So [30] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED SA +1F18E;W # So NEGATIVE SQUARED AB +1F18F..1F190;A # So [2] NEGATIVE SQUARED WC..SQUARE DJ +1F191..1F19A;W # So [10] SQUARED CL..SQUARED VS +1F19B..1F1AC;A # So [18] SQUARED THREE D..SQUARED VOD +1F1E6..1F1FF;N # So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z +1F200..1F202;W # So [3] SQUARE HIRAGANA HOKA..SQUARED KATAKANA SA +1F210..1F23B;W # So [44] SQUARED CJK UNIFIED IDEOGRAPH-624B..SQUARED CJK UNIFIED IDEOGRAPH-914D +1F240..1F248;W # So [9] TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C..TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557 +1F250..1F251;W # So [2] CIRCLED IDEOGRAPH ADVANTAGE..CIRCLED IDEOGRAPH ACCEPT +1F260..1F265;W # So [6] ROUNDED SYMBOL FOR FU..ROUNDED SYMBOL FOR CAI +1F300..1F320;W # So [33] CYCLONE..SHOOTING STAR +1F321..1F32C;N # So [12] THERMOMETER..WIND BLOWING FACE +1F32D..1F335;W # So [9] HOT DOG..CACTUS +1F336;N # So HOT PEPPER +1F337..1F37C;W # So [70] TULIP..BABY BOTTLE +1F37D;N # So FORK AND KNIFE WITH PLATE +1F37E..1F393;W # So [22] BOTTLE WITH POPPING CORK..GRADUATION CAP +1F394..1F39F;N # So [12] HEART WITH TIP ON THE LEFT..ADMISSION TICKETS +1F3A0..1F3CA;W # So [43] CAROUSEL HORSE..SWIMMER +1F3CB..1F3CE;N # So [4] WEIGHT LIFTER..RACING CAR +1F3CF..1F3D3;W # So [5] CRICKET BAT AND BALL..TABLE TENNIS PADDLE AND BALL +1F3D4..1F3DF;N # So [12] SNOW CAPPED MOUNTAIN..STADIUM +1F3E0..1F3F0;W # So [17] HOUSE BUILDING..EUROPEAN CASTLE +1F3F1..1F3F3;N # So [3] WHITE PENNANT..WAVING WHITE FLAG +1F3F4;W # So WAVING BLACK FLAG +1F3F5..1F3F7;N # So [3] ROSETTE..LABEL +1F3F8..1F3FA;W # So [3] BADMINTON RACQUET AND SHUTTLECOCK..AMPHORA +1F3FB..1F3FF;W # Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6 +1F400..1F43E;W # So [63] RAT..PAW PRINTS +1F43F;N # So CHIPMUNK +1F440;W # So EYES +1F441;N # So EYE +1F442..1F4FC;W # So [187] EAR..VIDEOCASSETTE +1F4FD..1F4FE;N # So [2] FILM PROJECTOR..PORTABLE STEREO +1F4FF..1F53D;W # So [63] PRAYER BEADS..DOWN-POINTING SMALL RED TRIANGLE +1F53E..1F54A;N # So [13] LOWER RIGHT SHADOWED WHITE CIRCLE..DOVE OF PEACE +1F54B..1F54E;W # So [4] KAABA..MENORAH WITH NINE BRANCHES +1F54F;N # So BOWL OF HYGIEIA +1F550..1F567;W # So [24] CLOCK FACE ONE OCLOCK..CLOCK FACE TWELVE-THIRTY +1F568..1F579;N # So [18] RIGHT SPEAKER..JOYSTICK +1F57A;W # So MAN DANCING +1F57B..1F594;N # So [26] LEFT HAND TELEPHONE RECEIVER..REVERSED VICTORY HAND +1F595..1F596;W # So [2] REVERSED HAND WITH MIDDLE FINGER EXTENDED..RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS +1F597..1F5A3;N # So [13] WHITE DOWN POINTING LEFT HAND INDEX..BLACK DOWN POINTING BACKHAND INDEX +1F5A4;W # So BLACK HEART +1F5A5..1F5FA;N # So [86] DESKTOP COMPUTER..WORLD MAP +1F5FB..1F5FF;W # So [5] MOUNT FUJI..MOYAI +1F600..1F64F;W # So [80] GRINNING FACE..PERSON WITH FOLDED HANDS +1F650..1F67F;N # So [48] NORTH WEST POINTING LEAF..REVERSE CHECKER BOARD +1F680..1F6C5;W # So [70] ROCKET..LEFT LUGGAGE +1F6C6..1F6CB;N # So [6] TRIANGLE WITH ROUNDED CORNERS..COUCH AND LAMP +1F6CC;W # So SLEEPING ACCOMMODATION +1F6CD..1F6CF;N # So [3] SHOPPING BAGS..BED +1F6D0..1F6D2;W # So [3] PLACE OF WORSHIP..SHOPPING TROLLEY +1F6D3..1F6D4;N # So [2] STUPA..PAGODA +1F6D5;W # So HINDU TEMPLE +1F6E0..1F6EA;N # So [11] HAMMER AND WRENCH..NORTHEAST-POINTING AIRPLANE +1F6EB..1F6EC;W # So [2] AIRPLANE DEPARTURE..AIRPLANE ARRIVING +1F6F0..1F6F3;N # So [4] SATELLITE..PASSENGER SHIP +1F6F4..1F6FA;W # So [7] SCOOTER..AUTO RICKSHAW +1F700..1F773;N # So [116] ALCHEMICAL SYMBOL FOR QUINTESSENCE..ALCHEMICAL SYMBOL FOR HALF OUNCE +1F780..1F7D8;N # So [89] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..NEGATIVE CIRCLED SQUARE +1F7E0..1F7EB;W # So [12] LARGE ORANGE CIRCLE..LARGE BROWN SQUARE +1F800..1F80B;N # So [12] LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD..DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD +1F810..1F847;N # So [56] LEFTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD..DOWNWARDS HEAVY ARROW +1F850..1F859;N # So [10] LEFTWARDS SANS-SERIF ARROW..UP DOWN SANS-SERIF ARROW +1F860..1F887;N # So [40] WIDE-HEADED LEFTWARDS LIGHT BARB ARROW..WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW +1F890..1F8AD;N # So [30] LEFTWARDS TRIANGLE ARROWHEAD..WHITE ARROW SHAFT WIDTH TWO THIRDS +1F900..1F90B;N # So [12] CIRCLED CROSS FORMEE WITH FOUR DOTS..DOWNWARD FACING NOTCHED HOOK WITH DOT +1F90D..1F971;W # So [101] WHITE HEART..YAWNING FACE +1F973..1F976;W # So [4] FACE WITH PARTY HORN AND PARTY HAT..FREEZING FACE +1F97A..1F9A2;W # So [41] FACE WITH PLEADING EYES..SWAN +1F9A5..1F9AA;W # So [6] SLOTH..OYSTER +1F9AE..1F9CA;W # So [29] GUIDE DOG..ICE CUBE +1F9CD..1F9FF;W # So [51] STANDING PERSON..NAZAR AMULET +1FA00..1FA53;N # So [84] NEUTRAL CHESS KING..BLACK CHESS KNIGHT-BISHOP +1FA60..1FA6D;N # So [14] XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER +1FA70..1FA73;W # So [4] BALLET SHOES..SHORTS +1FA78..1FA7A;W # So [3] DROP OF BLOOD..STETHOSCOPE +1FA80..1FA82;W # So [3] YO-YO..PARACHUTE +1FA90..1FA95;W # So [6] RINGED PLANET..BANJO +20000..2A6D6;W # Lo [42711] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6D6 +2A6D7..2A6FF;W # Cn [41] .. +2A700..2B734;W # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734 +2B735..2B73F;W # Cn [11] .. +2B740..2B81D;W # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D +2B81E..2B81F;W # Cn [2] .. +2B820..2CEA1;W # Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1 +2CEA2..2CEAF;W # Cn [14] .. +2CEB0..2EBE0;W # Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0 +2EBE1..2F7FF;W # Cn [3103] .. +2F800..2FA1D;W # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D +2FA1E..2FA1F;W # Cn [2] .. +2FA20..2FFFD;W # Cn [1502] .. +30000..3FFFD;W # Cn [65534] .. +E0001;N # Cf LANGUAGE TAG +E0020..E007F;N # Cf [96] TAG SPACE..CANCEL TAG +E0100..E01EF;A # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 +F0000..FFFFD;A # Co [65534] .. +100000..10FFFD;A # Co [65534] .. + +# EOF diff --git a/libc/unicode/kcombiningchars.S b/libc/unicode/kcombiningchars.S new file mode 100644 index 00000000..a2311593 --- /dev/null +++ b/libc/unicode/kcombiningchars.S @@ -0,0 +1,236 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/macros.h" +#include "libc/sysv/consts/nr.h" +#include "libc/sysv/consts/madv.h" + + .rodata.cst4 +kCombiningCharsBits: + .long 114752 * 8 + .endobj kCombiningCharsBits,globl,hidden + .previous + + .initbss 400,_init_kCombiningChars +kCombiningChars: + .zero 114752 + .endobj kCombiningChars,globl,hidden + .previous + + .init.start 400,_init_kCombiningChars + push %rsi + mov $1257,%edx + call lz4cpy + mov %rax,%rdi + pop %rsi + add $1264,%rsi + .init.end 400,_init_kCombiningChars + +/ The data below is sparse, as evidenced by: +/ o/tool/viz/bing.com ♫ ←♫è & + .byte 0xff,0xff,0x37,0x00,0xa2,0x14,0xfe,0x21 #λλ7 ó¶■! + .byte 0xfe,0x00,0x0c,0x00,0x00,0x00,0x02,0x10 #■ ♀   ☻► + .byte 0x00,0x40,0x10,0x1e,0x20,0x00,0x10,0x00 # @►▲  ►  + .byte 0x23,0x40,0x06,0x10,0x00,0x20,0x86,0x39 #.@♠►  å9 + .byte 0x1a,0x00,0x24,0x23,0x00,0x10,0x00,0x21 #→ $. ► ! + .byte 0xbe,0x21,0x20,0x00,0x13,0xfc,0x30,0x00 #╛!  ‼ⁿ0  + .byte 0x41,0x90,0x1e,0x20,0x40,0x40,0x00,0x13 #AÉ▲ @@ ‼ + .byte 0x04,0x5e,0x00,0x22,0x01,0x20,0x08,0x00 #♦^ .☺ ◘  + .byte 0x13,0x11,0x93,0x00,0x38,0xc1,0x3d,0x60 #‼◄ô 8┴=` + .byte 0x60,0x00,0x31,0x90,0x40,0x30,0x40,0x00 #` 1É@0@  + .byte 0x13,0x00,0x0f,0x01,0x13,0x18,0x70,0x00 #‼ ☼☺‼↑p  + .byte 0x06,0x9f,0x00,0x27,0x04,0x5c,0x0d,0x00 #♠ƒ '♦\♪  + .byte 0x48,0xf2,0x07,0x80,0x7f,0x1d,0x00,0x45 #H≥•Ç⌂↔ E + .byte 0xf2,0x1f,0x00,0x3f,0x0d,0x00,0x43,0x03 #≥▼ ?♪ C♥ + .byte 0x00,0x00,0xa0,0x57,0x00,0x50,0xfe,0x7f #  áW P■⌂ + .byte 0xdf,0xe0,0xff,0x41,0x01,0x28,0x1f,0x40 #▀αλA☺(▼@ + .byte 0x2f,0x00,0xff,0x00,0xe0,0xfd,0x66,0x00 #/ λ α²f  + .byte 0x00,0x00,0xc3,0x01,0x00,0x1e,0x00,0x64 #  ├☺ ▲ d + .byte 0x20,0x00,0x20,0x7a,0x01,0x05,0x1f,0xff #   z☺♣▼λ + .byte 0x01,0x00,0x00,0x0f,0x13,0x02,0x18,0x2f #☺  ☼‼☻↑/ + .byte 0xe0,0x00,0x01,0x00,0x62,0x13,0x1c,0x04 #α ☺ b‼∟♦ + .byte 0x00,0x26,0x0c,0x00,0x42,0x01,0x52,0xb0 # &♀ B☺R░ + .byte 0x3f,0x40,0xfe,0x0f,0xe8,0x00,0x1a,0x78 #?@■☼Φ →x + .byte 0x2e,0x00,0x26,0x60,0x00,0x85,0x01,0x04 #. &` à☺♦ + .byte 0x14,0x00,0x4f,0x87,0x01,0x04,0x0e,0x60 #¶ Oç☺♦♫` + .byte 0x00,0x07,0x23,0x80,0x09,0x3f,0x03,0x53 # •.Ç○?♥S + .byte 0x7f,0xe5,0x1f,0xf8,0x9f,0x2a,0x01,0x05 #⌂σ▼°ƒ*☺♣ + .byte 0x8e,0x01,0x11,0x0f,0x06,0x00,0x32,0xd0 #Ä☺◄☼♠ 2╨ + .byte 0x17,0x04,0x70,0x02,0x01,0xd0,0x01,0x23 #↨♦p☻☺╨☺. + .byte 0x3c,0x3b,0x32,0x00,0x13,0xa3,0xde,0x01 #<;2 ‼ú▐☺ + .byte 0x2f,0xf0,0xcf,0x58,0x00,0x00,0x6f,0xf7 #/≡╧X  o≈ + .byte 0xff,0xfd,0x21,0x10,0x03,0x8c,0x01,0x0c #λ²!►♥î☺♀ + .byte 0x1f,0xfb,0x15,0x01,0x24,0x40,0xa0,0x03 #▼√§☺$@á♥ + .byte 0xe0,0x00,0x02,0x00,0x72,0x60,0x00,0xf8 #α ☻ r` ° + .byte 0x00,0x00,0x00,0x7c,0x15,0x00,0x2c,0xdf #   |§ ,▀ + .byte 0xff,0x62,0x00,0x2f,0x01,0x00,0x01,0x00 #λb /☺ ☺  + .byte 0xff,0x6b,0x1d,0x80,0xff,0x01,0x1c,0x80 #λk↔Çλ☺∟Ç + .byte 0xa2,0x01,0x0f,0x68,0x00,0x32,0x19,0x3c #ó☺☼h 2↓< + .byte 0x0e,0x00,0x2f,0x1e,0x00,0x01,0x00,0xff #♫ /▲ ☺ λ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xb3,0x20,0x80 #λλλλλ│ Ç + .byte 0xf7,0xf6,0x12,0x27,0xc0,0x00,0xfb,0x12 #≈÷↕'└ √↕ + .byte 0x58,0xff,0xff,0x7f,0x00,0x03,0x24,0x00 #Xλλ⌂ ♥$  + .byte 0x1a,0x06,0x33,0x00,0x23,0x44,0x08,0xf4 #→♠3 .D◘⌠ + .byte 0x11,0x0b,0x4b,0x00,0x11,0x30,0x60,0x0f #◄♂K ◄0`☼ + .byte 0x11,0x03,0x70,0x0f,0x62,0xc0,0x3f,0x00 #◄♥p☼b└?  + .byte 0x00,0x80,0xff,0x46,0x00,0x02,0x10,0x14 # ÇλF ☻►¶ + .byte 0x20,0xc8,0x33,0x06,0x00,0x05,0x29,0x13 # ╚3♠ ♣)‼ + .byte 0x52,0x7e,0x66,0x00,0x08,0x10,0xf8,0x13 #R~f ◘►°‼ + .byte 0x02,0x11,0x00,0x21,0x9d,0xc1,0x43,0x12 #☻◄ !¥┴C↕ + .byte 0x19,0x30,0x66,0x13,0x1c,0x08,0x64,0x00 #↓0f‼∟◘d  + .byte 0x2f,0x20,0x21,0x96,0x0a,0xff,0xff,0xff #/ !û◙λλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xdb,0x1e #λλλλλλ█▲ + .byte 0x40,0x13,0x00,0x3f,0xfc,0xff,0x03,0x5d #@‼ ?ⁿλ♥] + .byte 0x00,0x34,0x00,0x02,0x1a,0x0f,0x06,0x1a # 4 ☻→☼♠→ + .byte 0x08,0x1d,0x80,0xdc,0x1f,0x0a,0x91,0x0a #◘↔Ç▄▼◙æ◙ + .byte 0x1f,0x0e,0x7f,0x00,0x2c,0x1f,0x20,0x1d #▼♫⌂ ,▼ ↔ + .byte 0x00,0x09,0x0e,0x74,0x00,0x2f,0xc0,0x07 # ○♫t /└• + .byte 0xdd,0x01,0xbd,0x22,0x6e,0xf0,0x23,0x1e #▌☺╜.n≡.▲ + .byte 0x0f,0x1c,0x00,0x01,0x1f,0x60,0x64,0x00 #☼∟ ☺▼`d  + .byte 0x34,0x1f,0xf0,0x44,0x00,0x30,0x05,0xf4 #4▼≡D 0♣⌠ + .byte 0x20,0x0b,0x18,0x00,0x1a,0x02,0xb1,0x1e # ♂↑ →☻▒▲ + .byte 0x03,0x72,0x1c,0x24,0x78,0x26,0xda,0x01 #♥r∟$x&┌☺ + .byte 0x00,0xf0,0x0c,0x35,0x80,0xef,0x1f,0x32 # ≡♀5Ç∩▼2 + .byte 0x02,0x02,0x20,0x00,0x29,0xc0,0x7f,0x26 #☻☻  )└⌂& + .byte 0x1c,0x3f,0x80,0xd3,0x40,0x7c,0x02,0x01 #∟?Ç╙@|☻☺ + .byte 0x26,0xf8,0x07,0xc0,0x20,0x00,0x7e,0x00 #&°•└  ~  + .byte 0x3f,0xc0,0x1f,0x1f,0xc7,0x02,0x06,0x19 #?└▼▼╟☻♠↓ + .byte 0x5c,0x28,0x03,0x3f,0xf8,0x85,0x0d,0xb1 #\(♥?°à♪▒ + .byte 0x1c,0x0b,0x22,0xb0,0x01,0xa3,0x0d,0x04 #∟♂.░☺ú♪♦ + .byte 0x30,0x00,0x19,0xa7,0xde,0x00,0x29,0x28 #0 ↓º▐ )( + .byte 0xbf,0x78,0x20,0x2f,0xbc,0x0f,0x38,0x0e #┐x /╝☼8♫ + .byte 0x0d,0x2f,0xff,0x06,0x96,0x01,0x20,0x10 #♪/λ♠û☺ ► + .byte 0x0c,0x74,0x00,0x11,0xfe,0xd2,0x02,0x52 #♀t ◄■╥☻R + .byte 0xf8,0x79,0x80,0x00,0x7e,0x4c,0x03,0x2f #°yÇ ~L♥/ + .byte 0xfc,0x7f,0xdb,0x03,0x20,0x28,0x7f,0xbf #ⁿ⌂█♥ (⌂┐ + .byte 0x1c,0x04,0x3b,0xff,0xfc,0x6d,0x20,0x00 #∟♦;λⁿm   + .byte 0x26,0x7e,0xb4,0x21,0x00,0x1f,0xa3,0x58 #&~┤! ▼úX + .byte 0x00,0x18,0x1f,0x18,0x23,0x07,0xff,0xff # ↑▼↑.•λλ + .byte 0x96,0x2f,0xff,0x01,0xfb,0x0d,0xff,0xff #û/λ☺√♪λλ + .byte 0xff,0xff,0xff,0xff,0xc9,0x04,0xf0,0x0a #λλλλ╔♦≡◙ + .byte 0x1f,0x7f,0x1c,0x19,0x70,0x04,0x08,0x00 #▼⌂∟↓p♦◘  + .byte 0x1f,0x07,0x30,0x18,0xff,0xff,0xff,0xff #▼•0↑λλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0x96,0x2f,0x60 #λλλλλû/` + .byte 0x0f,0x5f,0x25,0xff,0xff,0x87,0x5d,0x03 #☼_%λλç]♥ + .byte 0xf8,0xff,0xe7,0x0f,0x30,0x34,0x05,0x66 #°λτ☼04♣f + .byte 0x37,0x0f,0xba,0x14,0xe2,0x01,0x01,0x00 #7☼║¶Γ☺☺  + .byte 0x12,0x7f,0x2d,0x3a,0x20,0x1f,0x20,0x01 #↕⌂-: ▼ ☺ + .byte 0x26,0x3f,0xf8,0xfe,0xff,0xc0,0x00,0x97 #&?°■λ└ ù + .byte 0x5f,0x7f,0xff,0xff,0xf9,0xdb,0x13,0x0e #_⌂λλ∙█‼♫ + .byte 0x0e,0x1f,0x7f,0xb9,0x1a,0x24,0x0f,0xda #♫▼⌂╣→$☼┌ + .byte 0x01,0xa9,0x0a,0xf4,0x00,0x1f,0xf0,0x37 #☺⌐◙⌠ ▼≡7 + .byte 0x0f,0xff,0x44,0x2f,0xf8,0x00,0x01,0x00 #☼λD/° ☺  + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xee,0x57,0x02,0x00,0x00,0x00 #λλεW☻    + .byte 0xff,0x01,0x00,0x0c,0x20,0x00,0x1f,0xff #λ☺ ♀  ▼λ + .byte 0x01,0x00,0x07,0x50,0xff,0xff,0xff,0x00 #☺ •Pλλλ  + .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + .endobj kCombiningCharsLz4,globl,hidden + .previous diff --git a/libc/unicode/keastasianwidth.s b/libc/unicode/keastasianwidth.s new file mode 100644 index 00000000..e5068de4 --- /dev/null +++ b/libc/unicode/keastasianwidth.s @@ -0,0 +1,92 @@ +/ o/$(MODE)/tool/build/lz4toasm.com -o o/$(MODE)/libc/str/EastAsianWidth.s -s kEastAsianWidth o/$(MODE)/libc/str/EastAsianWidth.bin.lz4 +.include "libc/macros.inc" + + .rodata + .align 4 +kEastAsianWidthBits: + .long 32768 * 8 + .endobj kEastAsianWidthBits,globl,hidden + .previous + + .initbss 500,_init_kEastAsianWidth +kEastAsianWidth: + .zero 32768 + .endobj kEastAsianWidth,globl,hidden + .previous + + .init.start 500,_init_kEastAsianWidth + push %rsi + mov $500,%edx + call lz4cpy + mov %rax,%rdi + pop %rsi + add $504,%rsi + .init.end 500,_init_kEastAsianWidth + + .initro 500,_init_kEastAsianWidth +kEastAsianWidthLz4: + .byte 0x1f,0x00,0x01,0x00,0xff,0xff,0x0e,0x17 #▼ ☺ λλ♫↨ + .byte 0xff,0x01,0x00,0x0f,0x30,0x01,0xff,0x12 #λ☺ ☼0☺λ↕ + .byte 0xaf,0x88,0x99,0xf0,0xad,0xae,0xfb,0x2b #»êÖ≡¡«√+ + .byte 0x00,0x81,0xfb,0x13,0x01,0xf6,0x3f,0x0c # ü√‼☺÷?♀ + .byte 0x00,0x06,0x1a,0x00,0x04,0x2f,0x1e,0x09 # ♠→ ♦/▲○ + .byte 0x5c,0x00,0x2d,0x43,0x60,0x00,0x00,0x30 #\ -C`  0 + .byte 0xa9,0x02,0x10,0x0f,0x06,0x00,0xf3,0x0d #⌐☻►☼♠ ≤♪ + .byte 0x80,0x00,0x00,0x08,0x00,0x02,0x0c,0x00 #Ç  ◘ ☻♀  + .byte 0x60,0x30,0x40,0x10,0x00,0x00,0x04,0x2c #`0@►  ♦, + .byte 0x24,0x20,0x0c,0x00,0x00,0x00,0x01,0x00 #$ ♀   ☺  + .byte 0x00,0x00,0x50,0xb8,0x33,0x00,0x10,0xe0 #  P╕3 ►α + .byte 0x11,0x00,0x1f,0x80,0x00,0x01,0x58,0x12 #◄ ▼Ç ☺X↕ + .byte 0x18,0x07,0x00,0x1f,0x21,0xb0,0x03,0x55 #↑• ▼!░♥U + .byte 0x16,0xfb,0xb2,0x03,0x3f,0x0f,0x00,0xff #▬√▓♥?☼ λ + .byte 0x01,0x00,0x06,0x11,0x3f,0x35,0x01,0x03 #☺ ♠◄?5☺♥ + .byte 0x0d,0x00,0x4e,0x7f,0xfe,0xff,0xff,0x0b #♪ N⌂■λλ♂ + .byte 0x00,0x41,0xff,0xff,0xff,0xe0,0x06,0x00 # Aλλλα♠  + .byte 0x07,0x13,0x00,0x11,0x7f,0x06,0x00,0x17 #•‼ ◄⌂♠ ↨ + .byte 0x07,0x5e,0x00,0x02,0x12,0x00,0x2f,0x00 #•^ ☻↕ /  + .byte 0xff,0x01,0x00,0xff,0xff,0xff,0x5d,0x0e #λ☺ λλλ]♫ + .byte 0xa0,0x07,0x0f,0x01,0x00,0xff,0xff,0xff #á•☼☺ λλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbe #λλλλλλλ╛ + .byte 0x13,0x1f,0x67,0x0e,0x0f,0x0c,0x13,0x83 #‼▼g♫☼♀‼â + .byte 0x1f,0x1f,0x60,0x13,0x3d,0x0f,0x63,0x06 #▼▼`‼=☼c♠ + .byte 0xff,0xff,0xff,0xff,0xff,0x66,0x2f,0x0f #λλλλλf/☼ + .byte 0x00,0x01,0x00,0xff,0xff,0xf9,0x04,0xb0 # ☺ λλ∙♦░ + .byte 0x1a,0x2f,0xd1,0xe0,0x00,0x1d,0xff,0x10 #→/╤α ↔λ► + .byte 0x0f,0xa8,0x15,0x21,0x0f,0xa2,0x00,0x50 #☼¿§!☼ó P + .byte 0x12,0x03,0xa6,0x00,0x3f,0xf7,0xff,0x7f #↕♥ª ?≈λ⌂ + .byte 0xd9,0x04,0x00,0x08,0xcd,0x19,0x1b,0x01 #┘♦ ◘═↓←☺ + .byte 0x1c,0x00,0x2f,0x7f,0x00,0x01,0x00,0xff #∟ /⌂ ☺ λ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xf8,0x1f,0x0f,0x80 #λλλλ°▼☼Ç + .byte 0x18,0xff,0xff,0xf1,0x0f,0x00,0x03,0x4c #↑λλ±☼ ♥L + .byte 0x1f,0x07,0x04,0x08,0xff,0xff,0xff,0xff #▼•♦◘λλλλ + .byte 0x92,0x0f,0xc5,0x04,0x10,0x03,0x27,0x16 #Æ☼┼♦►♥'▬ + .byte 0x4f,0x07,0x00,0xf0,0x00,0x6b,0x1b,0x1f #O• ≡ k←▼ + .byte 0x0f,0x04,0x10,0xff,0xff,0xff,0xff,0xff #☼♦►λλλλλ + .byte 0xff,0xff,0x94,0x1f,0x10,0x19,0x00,0x05 #λλö▼►↓ ♣ + .byte 0x0f,0x22,0x39,0x05,0x29,0x40,0xfe,0xd5 #☼.9♣)@■╒ + .byte 0x0c,0x12,0x07,0x14,0x08,0x6f,0x0f,0xff #♀↕•¶◘o☼λ + .byte 0x01,0x03,0x00,0x3f,0x60,0x08,0x04,0x34 #☺♥ ?`◘♦4 + .byte 0x01,0xe0,0xbf,0x10,0x08,0x15,0xdf,0x36 #☺α┐►◘§▀6 + .byte 0x38,0x10,0x87,0x08,0x00,0x15,0x11,0x64 #8►ç◘ §◄d + .byte 0x08,0x1f,0xfd,0x40,0x08,0x03,0x15,0x9f #◘▼²@◘♥§ƒ + .byte 0xad,0x38,0x11,0x78,0x4d,0x1f,0x10,0x04 #¡8◄xM▼►♦ + .byte 0xf3,0x39,0x07,0xb4,0x00,0x1c,0xf8,0x6a #≤9•┤ ∟°j + .byte 0x1f,0x05,0xde,0x38,0x6f,0x10,0x27,0x00 #▼♣▐8o►'  + .byte 0x00,0x18,0xf0,0x81,0x0d,0x0a,0x0f,0x9e # ↑≡ü♪◙☼€ + .byte 0x08,0x12,0x18,0xe0,0x8f,0x00,0x20,0x7b #◘↕↑αÅ  { + .byte 0xfc,0x06,0x00,0x20,0xe7,0xc7,0x05,0x00 #ⁿ♠  τ╟♣  + .byte 0x0f,0xe0,0x1f,0x01,0x5f,0x0f,0x07,0x07 #☼α▼☺_☼•• + .byte 0x00,0x3f,0xe0,0x20,0x9b,0x0f,0x01,0x00 # ?α ¢☼☺  + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0x0b,0x1f,0x3f,0xfc,0x1f,0xff,0xff,0xff #♂▼?ⁿ▼λλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff #λλλλλλλλ + .byte 0xff,0xff,0xff,0xff,0xff,0x08,0x50,0xff #λλλλλ◘Pλ + .byte 0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00 + .endobj kEastAsianWidthLz4,globl,hidden + .previous diff --git a/libc/unicode/strnwidth16.c b/libc/unicode/strnwidth16.c new file mode 100644 index 00000000..1b0c9f26 --- /dev/null +++ b/libc/unicode/strnwidth16.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/str/str.h" +#include "libc/unicode/unicode.h" + +/** + * Returns monospace display width of UTF-16 or UCS-2 string. + */ +int strnwidth16(const char16_t *p, size_t n) { + size_t l; + wint_t wc; + l = 0; + if (n) { + while (*p) { + p += getutf16(p, &wc); + l += max(0, wcwidth(wc)); + } + } + return l; +} diff --git a/libc/unicode/strwidth.c b/libc/unicode/strwidth.c new file mode 100644 index 00000000..dd54f572 --- /dev/null +++ b/libc/unicode/strwidth.c @@ -0,0 +1,71 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/conv/conv.h" +#include "libc/limits.h" +#include "libc/str/internal.h" +#include "libc/str/str.h" +#include "libc/unicode/unicode.h" + +#define kOneTrueTabWidth 8 + +/** + * Returns monospace display width in UTF-8 string. + */ +int(strwidth)(const char *s) { + return strnwidth(s, SIZE_MAX); +} + +int(strnwidth)(const char *s, size_t n) { + /* TODO(jart): Fix this function. */ + size_t l; + wint_t wc; + const unsigned char *p, *pe; + l = 0; + if (n) { + p = (const unsigned char *)s; + pe = (const unsigned char *)(n == SIZE_MAX ? INTPTR_MAX : (intptr_t)s + n); + for (;;) { + while (p < pe && iscont(*p)) p++; + if (p == pe || !*p) break; + if (*p == L'\t') { + if (l & (kOneTrueTabWidth - 1)) { + l += kOneTrueTabWidth - (l & (kOneTrueTabWidth - 1)); + } else { + l += kOneTrueTabWidth; + } + ++p; + } else if (*p == L'\e') { + while (++p < pe && *p) { + if (*p == '[' || *p == ';' || isdigit(*p)) { + continue; + } else { + ++p; + break; + } + } + } else { + p += abs(tpdecode((const char *)p, &wc)); + l += max(0, wcwidth(wc)); + } + } + } + return l; +} diff --git a/libc/unicode/strwidth16.c b/libc/unicode/strwidth16.c new file mode 100644 index 00000000..479321ac --- /dev/null +++ b/libc/unicode/strwidth16.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/limits.h" +#include "libc/unicode/unicode.h" + +/** + * Returns monospace display width of UTF-16 or UCS-2 string. + */ +int strwidth16(const char16_t *s) { + return strnwidth16(s, SIZE_MAX); +} diff --git a/libc/unicode/unicode.h b/libc/unicode/unicode.h new file mode 100644 index 00000000..01999110 --- /dev/null +++ b/libc/unicode/unicode.h @@ -0,0 +1,49 @@ +#ifndef COSMOPOLITAN_LIBC_UNICODE_UNICODE_H_ +#define COSMOPOLITAN_LIBC_UNICODE_UNICODE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § characters » unicode ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +extern const uint64_t kEastAsianWidth[]; +extern const uint32_t kEastAsianWidthBits; +extern const uint64_t kCombiningChars[]; +extern const uint32_t kCombiningCharsBits; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § strings » multibyte » unicode ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +int wcwidth(wchar_t) pureconst; +int wcswidth(const wchar_t *) strlenesque; +int wcsnwidth(const wchar_t *, size_t) strlenesque; +int strwidth(const char *) strlenesque; +int strnwidth(const char *, size_t) strlenesque; +int strwidth16(const char16_t *) strlenesque; +int strnwidth16(const char16_t *, size_t) strlenesque; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § unicode » generic typing ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#if __STDC_VERSION__ + 0 >= 201112 + +#define strwidth(s) \ + _Generic(*(s), wchar_t \ + : wcswidth, char16_t \ + : strwidth16, default \ + : strwidth)(s) + +#define strnwidth(s, n) \ + _Generic(*(s), wchar_t \ + : wcswidth, char16_t \ + : strnwidth16, default \ + : strnwidth)(s, n) + +#endif /* C11 */ + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_UNICODE_UNICODE_H_ */ diff --git a/libc/unicode/unicode.mk b/libc/unicode/unicode.mk new file mode 100644 index 00000000..40b1455e --- /dev/null +++ b/libc/unicode/unicode.mk @@ -0,0 +1,91 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += LIBC_UNICODE + +LIBC_UNICODE_ARTIFACTS += LIBC_UNICODE_A +LIBC_UNICODE = $(LIBC_UNICODE_A_DEPS) $(LIBC_UNICODE_A) +LIBC_UNICODE_A = o/$(MODE)/libc/unicode/unicode.a +LIBC_UNICODE_A_FILES := $(wildcard libc/unicode/*) +LIBC_UNICODE_A_HDRS = $(filter %.h,$(LIBC_UNICODE_A_FILES)) +LIBC_UNICODE_A_SRCS_A = $(filter %.s,$(LIBC_UNICODE_A_FILES)) +LIBC_UNICODE_A_SRCS_S = $(filter %.S,$(LIBC_UNICODE_A_FILES)) +LIBC_UNICODE_A_SRCS_C = $(filter %.c,$(LIBC_UNICODE_A_FILES)) + +LIBC_UNICODE_A_SRCS = \ + $(LIBC_UNICODE_A_SRCS_A) \ + $(LIBC_UNICODE_A_SRCS_S) \ + $(LIBC_UNICODE_A_SRCS_C) + +LIBC_UNICODE_A_OBJS = \ + $(LIBC_UNICODE_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_UNICODE_A_SRCS_A:%.s=o/$(MODE)/%.o) \ + $(LIBC_UNICODE_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_UNICODE_A_SRCS_C:%.c=o/$(MODE)/%.o) + +LIBC_UNICODE_A_CHECKS = \ + $(LIBC_UNICODE_A).pkg \ + $(LIBC_UNICODE_A_HDRS:%=o/$(MODE)/%.ok) + +LIBC_UNICODE_A_DIRECTDEPS = \ + LIBC_STUBS \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_STR \ + LIBC_SYSV + +LIBC_UNICODE_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_UNICODE_A_DIRECTDEPS),$($(x)))) + +$(LIBC_UNICODE_A): \ + libc/unicode/ \ + $(LIBC_UNICODE_A).pkg \ + $(LIBC_UNICODE_A_OBJS) + +$(LIBC_UNICODE_A).pkg: \ + $(LIBC_UNICODE_A_OBJS) \ + $(foreach x,$(LIBC_UNICODE_A_DIRECTDEPS),$($(x)_A).pkg) + +LIBC_UNICODE_LIBS = $(foreach x,$(LIBC_UNICODE_ARTIFACTS),$($(x))) +LIBC_UNICODE_SRCS = $(foreach x,$(LIBC_UNICODE_ARTIFACTS),$($(x)_SRCS)) +LIBC_UNICODE_HDRS = $(foreach x,$(LIBC_UNICODE_ARTIFACTS),$($(x)_HDRS)) +LIBC_UNICODE_BINS = $(foreach x,$(LIBC_UNICODE_ARTIFACTS),$($(x)_BINS)) +LIBC_UNICODE_CHECKS = $(foreach x,$(LIBC_UNICODE_ARTIFACTS),$($(x)_CHECKS)) +LIBC_UNICODE_OBJS = $(foreach x,$(LIBC_UNICODE_ARTIFACTS),$($(x)_OBJS)) +LIBC_UNICODE_TESTS = $(foreach x,$(LIBC_UNICODE_ARTIFACTS),$($(x)_TESTS)) +$(LIBC_UNICODE_OBJS): $(BUILD_FILES) libc/unicode/unicode.mk + +.PHONY: o/$(MODE)/libc/unicode +o/$(MODE)/libc/unicode: $(LIBC_UNICODE) $(LIBC_UNICODE_CHECKS) + +o/$(MODE)/libc/unicode/eastasianwidth.bin: \ + libc/unicode/eastasianwidth.txt \ + o/$(MODE)/tool/decode/mkwides.com + @TARGET=$@ ACTION=MKWIDES build/do \ + o/$(MODE)/tool/decode/mkwides.com -o $@ $< +o/$(MODE)/libc/unicode/eastasianwidth.bin.lz4: \ + o/$(MODE)/libc/unicode/eastasianwidth.bin \ + o/$(MODE)/third_party/lz4cli/lz4cli.com + @TARGET=$@ ACTION=LZ4 build/do \ + o/$(MODE)/third_party/lz4cli/lz4cli.com -q -f -9 --content-size $< $@ +o/$(MODE)/libc/unicode/eastasianwidth.s: \ + o/$(MODE)/libc/unicode/eastasianwidth.bin.lz4 \ + o/$(MODE)/tool/build/lz4toasm.com + @TARGET=$@ ACTION=BIN2ASM build/do \ + o/$(MODE)/tool/build/lz4toasm.com -s kEastAsianWidth -o $@ $< + +o/$(MODE)/libc/unicode/combiningchars.bin: \ + libc/unicode/unicodedata.txt \ + o/$(MODE)/tool/decode/mkcombos.com + @TARGET=$@ ACTION=MKCOMBOS build/do \ + o/$(MODE)/tool/decode/mkcombos.com -o $@ $< +o/$(MODE)/libc/unicode/combiningchars.bin.lz4: \ + o/$(MODE)/libc/unicode/combiningchars.bin \ + o/$(MODE)/third_party/lz4cli/lz4cli.com + @TARGET=$@ ACTION=LZ4 build/do \ + o/$(MODE)/third_party/lz4cli/lz4cli.com -q -f -9 --content-size $< $@ +o/$(MODE)/libc/unicode/combiningchars.s: \ + o/$(MODE)/libc/unicode/combiningchars.bin.lz4 \ + o/$(MODE)/tool/build/lz4toasm.com + @TARGET=$@ ACTION=BIN2ASM build/do \ + o/$(MODE)/tool/build/lz4toasm.com -s kCombiningChars -o $@ $< diff --git a/libc/unicode/unicodedata.txt b/libc/unicode/unicodedata.txt new file mode 100644 index 00000000..e65aec52 --- /dev/null +++ b/libc/unicode/unicodedata.txt @@ -0,0 +1,32841 @@ +0000;;Cc;0;BN;;;;;N;NULL;;;; +0001;;Cc;0;BN;;;;;N;START OF HEADING;;;; +0002;;Cc;0;BN;;;;;N;START OF TEXT;;;; +0003;;Cc;0;BN;;;;;N;END OF TEXT;;;; +0004;;Cc;0;BN;;;;;N;END OF TRANSMISSION;;;; +0005;;Cc;0;BN;;;;;N;ENQUIRY;;;; +0006;;Cc;0;BN;;;;;N;ACKNOWLEDGE;;;; +0007;;Cc;0;BN;;;;;N;BELL;;;; +0008;;Cc;0;BN;;;;;N;BACKSPACE;;;; +0009;;Cc;0;S;;;;;N;CHARACTER TABULATION;;;; +000A;;Cc;0;B;;;;;N;LINE FEED (LF);;;; +000B;;Cc;0;S;;;;;N;LINE TABULATION;;;; +000C;;Cc;0;WS;;;;;N;FORM FEED (FF);;;; +000D;;Cc;0;B;;;;;N;CARRIAGE RETURN (CR);;;; +000E;;Cc;0;BN;;;;;N;SHIFT OUT;;;; +000F;;Cc;0;BN;;;;;N;SHIFT IN;;;; +0010;;Cc;0;BN;;;;;N;DATA LINK ESCAPE;;;; +0011;;Cc;0;BN;;;;;N;DEVICE CONTROL ONE;;;; +0012;;Cc;0;BN;;;;;N;DEVICE CONTROL TWO;;;; +0013;;Cc;0;BN;;;;;N;DEVICE CONTROL THREE;;;; +0014;;Cc;0;BN;;;;;N;DEVICE CONTROL FOUR;;;; +0015;;Cc;0;BN;;;;;N;NEGATIVE ACKNOWLEDGE;;;; +0016;;Cc;0;BN;;;;;N;SYNCHRONOUS IDLE;;;; +0017;;Cc;0;BN;;;;;N;END OF TRANSMISSION BLOCK;;;; +0018;;Cc;0;BN;;;;;N;CANCEL;;;; +0019;;Cc;0;BN;;;;;N;END OF MEDIUM;;;; +001A;;Cc;0;BN;;;;;N;SUBSTITUTE;;;; +001B;;Cc;0;BN;;;;;N;ESCAPE;;;; +001C;;Cc;0;B;;;;;N;INFORMATION SEPARATOR FOUR;;;; +001D;;Cc;0;B;;;;;N;INFORMATION SEPARATOR THREE;;;; +001E;;Cc;0;B;;;;;N;INFORMATION SEPARATOR TWO;;;; +001F;;Cc;0;S;;;;;N;INFORMATION SEPARATOR ONE;;;; +0020;SPACE;Zs;0;WS;;;;;N;;;;; +0021;EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; +0022;QUOTATION MARK;Po;0;ON;;;;;N;;;;; +0023;NUMBER SIGN;Po;0;ET;;;;;N;;;;; +0024;DOLLAR SIGN;Sc;0;ET;;;;;N;;;;; +0025;PERCENT SIGN;Po;0;ET;;;;;N;;;;; +0026;AMPERSAND;Po;0;ON;;;;;N;;;;; +0027;APOSTROPHE;Po;0;ON;;;;;N;APOSTROPHE-QUOTE;;;; +0028;LEFT PARENTHESIS;Ps;0;ON;;;;;Y;OPENING PARENTHESIS;;;; +0029;RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;CLOSING PARENTHESIS;;;; +002A;ASTERISK;Po;0;ON;;;;;N;;;;; +002B;PLUS SIGN;Sm;0;ES;;;;;N;;;;; +002C;COMMA;Po;0;CS;;;;;N;;;;; +002D;HYPHEN-MINUS;Pd;0;ES;;;;;N;;;;; +002E;FULL STOP;Po;0;CS;;;;;N;PERIOD;;;; +002F;SOLIDUS;Po;0;CS;;;;;N;SLASH;;;; +0030;DIGIT ZERO;Nd;0;EN;;0;0;0;N;;;;; +0031;DIGIT ONE;Nd;0;EN;;1;1;1;N;;;;; +0032;DIGIT TWO;Nd;0;EN;;2;2;2;N;;;;; +0033;DIGIT THREE;Nd;0;EN;;3;3;3;N;;;;; +0034;DIGIT FOUR;Nd;0;EN;;4;4;4;N;;;;; +0035;DIGIT FIVE;Nd;0;EN;;5;5;5;N;;;;; +0036;DIGIT SIX;Nd;0;EN;;6;6;6;N;;;;; +0037;DIGIT SEVEN;Nd;0;EN;;7;7;7;N;;;;; +0038;DIGIT EIGHT;Nd;0;EN;;8;8;8;N;;;;; +0039;DIGIT NINE;Nd;0;EN;;9;9;9;N;;;;; +003A;COLON;Po;0;CS;;;;;N;;;;; +003B;SEMICOLON;Po;0;ON;;;;;N;;;;; +003C;LESS-THAN SIGN;Sm;0;ON;;;;;Y;;;;; +003D;EQUALS SIGN;Sm;0;ON;;;;;N;;;;; +003E;GREATER-THAN SIGN;Sm;0;ON;;;;;Y;;;;; +003F;QUESTION MARK;Po;0;ON;;;;;N;;;;; +0040;COMMERCIAL AT;Po;0;ON;;;;;N;;;;; +0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061; +0042;LATIN CAPITAL LETTER B;Lu;0;L;;;;;N;;;;0062; +0043;LATIN CAPITAL LETTER C;Lu;0;L;;;;;N;;;;0063; +0044;LATIN CAPITAL LETTER D;Lu;0;L;;;;;N;;;;0064; +0045;LATIN CAPITAL LETTER E;Lu;0;L;;;;;N;;;;0065; +0046;LATIN CAPITAL LETTER F;Lu;0;L;;;;;N;;;;0066; +0047;LATIN CAPITAL LETTER G;Lu;0;L;;;;;N;;;;0067; +0048;LATIN CAPITAL LETTER H;Lu;0;L;;;;;N;;;;0068; +0049;LATIN CAPITAL LETTER I;Lu;0;L;;;;;N;;;;0069; +004A;LATIN CAPITAL LETTER J;Lu;0;L;;;;;N;;;;006A; +004B;LATIN CAPITAL LETTER K;Lu;0;L;;;;;N;;;;006B; +004C;LATIN CAPITAL LETTER L;Lu;0;L;;;;;N;;;;006C; +004D;LATIN CAPITAL LETTER M;Lu;0;L;;;;;N;;;;006D; +004E;LATIN CAPITAL LETTER N;Lu;0;L;;;;;N;;;;006E; +004F;LATIN CAPITAL LETTER O;Lu;0;L;;;;;N;;;;006F; +0050;LATIN CAPITAL LETTER P;Lu;0;L;;;;;N;;;;0070; +0051;LATIN CAPITAL LETTER Q;Lu;0;L;;;;;N;;;;0071; +0052;LATIN CAPITAL LETTER R;Lu;0;L;;;;;N;;;;0072; +0053;LATIN CAPITAL LETTER S;Lu;0;L;;;;;N;;;;0073; +0054;LATIN CAPITAL LETTER T;Lu;0;L;;;;;N;;;;0074; +0055;LATIN CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0075; +0056;LATIN CAPITAL LETTER V;Lu;0;L;;;;;N;;;;0076; +0057;LATIN CAPITAL LETTER W;Lu;0;L;;;;;N;;;;0077; +0058;LATIN CAPITAL LETTER X;Lu;0;L;;;;;N;;;;0078; +0059;LATIN CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;0079; +005A;LATIN CAPITAL LETTER Z;Lu;0;L;;;;;N;;;;007A; +005B;LEFT SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING SQUARE BRACKET;;;; +005C;REVERSE SOLIDUS;Po;0;ON;;;;;N;BACKSLASH;;;; +005D;RIGHT SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING SQUARE BRACKET;;;; +005E;CIRCUMFLEX ACCENT;Sk;0;ON;;;;;N;SPACING CIRCUMFLEX;;;; +005F;LOW LINE;Pc;0;ON;;;;;N;SPACING UNDERSCORE;;;; +0060;GRAVE ACCENT;Sk;0;ON;;;;;N;SPACING GRAVE;;;; +0061;LATIN SMALL LETTER A;Ll;0;L;;;;;N;;;0041;;0041 +0062;LATIN SMALL LETTER B;Ll;0;L;;;;;N;;;0042;;0042 +0063;LATIN SMALL LETTER C;Ll;0;L;;;;;N;;;0043;;0043 +0064;LATIN SMALL LETTER D;Ll;0;L;;;;;N;;;0044;;0044 +0065;LATIN SMALL LETTER E;Ll;0;L;;;;;N;;;0045;;0045 +0066;LATIN SMALL LETTER F;Ll;0;L;;;;;N;;;0046;;0046 +0067;LATIN SMALL LETTER G;Ll;0;L;;;;;N;;;0047;;0047 +0068;LATIN SMALL LETTER H;Ll;0;L;;;;;N;;;0048;;0048 +0069;LATIN SMALL LETTER I;Ll;0;L;;;;;N;;;0049;;0049 +006A;LATIN SMALL LETTER J;Ll;0;L;;;;;N;;;004A;;004A +006B;LATIN SMALL LETTER K;Ll;0;L;;;;;N;;;004B;;004B +006C;LATIN SMALL LETTER L;Ll;0;L;;;;;N;;;004C;;004C +006D;LATIN SMALL LETTER M;Ll;0;L;;;;;N;;;004D;;004D +006E;LATIN SMALL LETTER N;Ll;0;L;;;;;N;;;004E;;004E +006F;LATIN SMALL LETTER O;Ll;0;L;;;;;N;;;004F;;004F +0070;LATIN SMALL LETTER P;Ll;0;L;;;;;N;;;0050;;0050 +0071;LATIN SMALL LETTER Q;Ll;0;L;;;;;N;;;0051;;0051 +0072;LATIN SMALL LETTER R;Ll;0;L;;;;;N;;;0052;;0052 +0073;LATIN SMALL LETTER S;Ll;0;L;;;;;N;;;0053;;0053 +0074;LATIN SMALL LETTER T;Ll;0;L;;;;;N;;;0054;;0054 +0075;LATIN SMALL LETTER U;Ll;0;L;;;;;N;;;0055;;0055 +0076;LATIN SMALL LETTER V;Ll;0;L;;;;;N;;;0056;;0056 +0077;LATIN SMALL LETTER W;Ll;0;L;;;;;N;;;0057;;0057 +0078;LATIN SMALL LETTER X;Ll;0;L;;;;;N;;;0058;;0058 +0079;LATIN SMALL LETTER Y;Ll;0;L;;;;;N;;;0059;;0059 +007A;LATIN SMALL LETTER Z;Ll;0;L;;;;;N;;;005A;;005A +007B;LEFT CURLY BRACKET;Ps;0;ON;;;;;Y;OPENING CURLY BRACKET;;;; +007C;VERTICAL LINE;Sm;0;ON;;;;;N;VERTICAL BAR;;;; +007D;RIGHT CURLY BRACKET;Pe;0;ON;;;;;Y;CLOSING CURLY BRACKET;;;; +007E;TILDE;Sm;0;ON;;;;;N;;;;; +007F;;Cc;0;BN;;;;;N;DELETE;;;; +0080;;Cc;0;BN;;;;;N;;;;; +0081;;Cc;0;BN;;;;;N;;;;; +0082;;Cc;0;BN;;;;;N;BREAK PERMITTED HERE;;;; +0083;;Cc;0;BN;;;;;N;NO BREAK HERE;;;; +0084;;Cc;0;BN;;;;;N;;;;; +0085;;Cc;0;B;;;;;N;NEXT LINE (NEL);;;; +0086;;Cc;0;BN;;;;;N;START OF SELECTED AREA;;;; +0087;;Cc;0;BN;;;;;N;END OF SELECTED AREA;;;; +0088;;Cc;0;BN;;;;;N;CHARACTER TABULATION SET;;;; +0089;;Cc;0;BN;;;;;N;CHARACTER TABULATION WITH JUSTIFICATION;;;; +008A;;Cc;0;BN;;;;;N;LINE TABULATION SET;;;; +008B;;Cc;0;BN;;;;;N;PARTIAL LINE FORWARD;;;; +008C;;Cc;0;BN;;;;;N;PARTIAL LINE BACKWARD;;;; +008D;;Cc;0;BN;;;;;N;REVERSE LINE FEED;;;; +008E;;Cc;0;BN;;;;;N;SINGLE SHIFT TWO;;;; +008F;;Cc;0;BN;;;;;N;SINGLE SHIFT THREE;;;; +0090;;Cc;0;BN;;;;;N;DEVICE CONTROL STRING;;;; +0091;;Cc;0;BN;;;;;N;PRIVATE USE ONE;;;; +0092;;Cc;0;BN;;;;;N;PRIVATE USE TWO;;;; +0093;;Cc;0;BN;;;;;N;SET TRANSMIT STATE;;;; +0094;;Cc;0;BN;;;;;N;CANCEL CHARACTER;;;; +0095;;Cc;0;BN;;;;;N;MESSAGE WAITING;;;; +0096;;Cc;0;BN;;;;;N;START OF GUARDED AREA;;;; +0097;;Cc;0;BN;;;;;N;END OF GUARDED AREA;;;; +0098;;Cc;0;BN;;;;;N;START OF STRING;;;; +0099;;Cc;0;BN;;;;;N;;;;; +009A;;Cc;0;BN;;;;;N;SINGLE CHARACTER INTRODUCER;;;; +009B;;Cc;0;BN;;;;;N;CONTROL SEQUENCE INTRODUCER;;;; +009C;;Cc;0;BN;;;;;N;STRING TERMINATOR;;;; +009D;;Cc;0;BN;;;;;N;OPERATING SYSTEM COMMAND;;;; +009E;;Cc;0;BN;;;;;N;PRIVACY MESSAGE;;;; +009F;;Cc;0;BN;;;;;N;APPLICATION PROGRAM COMMAND;;;; +00A0;NO-BREAK SPACE;Zs;0;CS; 0020;;;;N;NON-BREAKING SPACE;;;; +00A1;INVERTED EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; +00A2;CENT SIGN;Sc;0;ET;;;;;N;;;;; +00A3;POUND SIGN;Sc;0;ET;;;;;N;;;;; +00A4;CURRENCY SIGN;Sc;0;ET;;;;;N;;;;; +00A5;YEN SIGN;Sc;0;ET;;;;;N;;;;; +00A6;BROKEN BAR;So;0;ON;;;;;N;BROKEN VERTICAL BAR;;;; +00A7;SECTION SIGN;Po;0;ON;;;;;N;;;;; +00A8;DIAERESIS;Sk;0;ON; 0020 0308;;;;N;SPACING DIAERESIS;;;; +00A9;COPYRIGHT SIGN;So;0;ON;;;;;N;;;;; +00AA;FEMININE ORDINAL INDICATOR;Lo;0;L; 0061;;;;N;;;;; +00AB;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING GUILLEMET;;;; +00AC;NOT SIGN;Sm;0;ON;;;;;N;;;;; +00AD;SOFT HYPHEN;Cf;0;BN;;;;;N;;;;; +00AE;REGISTERED SIGN;So;0;ON;;;;;N;REGISTERED TRADE MARK SIGN;;;; +00AF;MACRON;Sk;0;ON; 0020 0304;;;;N;SPACING MACRON;;;; +00B0;DEGREE SIGN;So;0;ET;;;;;N;;;;; +00B1;PLUS-MINUS SIGN;Sm;0;ET;;;;;N;PLUS-OR-MINUS SIGN;;;; +00B2;SUPERSCRIPT TWO;No;0;EN; 0032;;2;2;N;SUPERSCRIPT DIGIT TWO;;;; +00B3;SUPERSCRIPT THREE;No;0;EN; 0033;;3;3;N;SUPERSCRIPT DIGIT THREE;;;; +00B4;ACUTE ACCENT;Sk;0;ON; 0020 0301;;;;N;SPACING ACUTE;;;; +00B5;MICRO SIGN;Ll;0;L; 03BC;;;;N;;;039C;;039C +00B6;PILCROW SIGN;Po;0;ON;;;;;N;PARAGRAPH SIGN;;;; +00B7;MIDDLE DOT;Po;0;ON;;;;;N;;;;; +00B8;CEDILLA;Sk;0;ON; 0020 0327;;;;N;SPACING CEDILLA;;;; +00B9;SUPERSCRIPT ONE;No;0;EN; 0031;;1;1;N;SUPERSCRIPT DIGIT ONE;;;; +00BA;MASCULINE ORDINAL INDICATOR;Lo;0;L; 006F;;;;N;;;;; +00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;;;; +00BC;VULGAR FRACTION ONE QUARTER;No;0;ON; 0031 2044 0034;;;1/4;N;FRACTION ONE QUARTER;;;; +00BD;VULGAR FRACTION ONE HALF;No;0;ON; 0031 2044 0032;;;1/2;N;FRACTION ONE HALF;;;; +00BE;VULGAR FRACTION THREE QUARTERS;No;0;ON; 0033 2044 0034;;;3/4;N;FRACTION THREE QUARTERS;;;; +00BF;INVERTED QUESTION MARK;Po;0;ON;;;;;N;;;;; +00C0;LATIN CAPITAL LETTER A WITH GRAVE;Lu;0;L;0041 0300;;;;N;LATIN CAPITAL LETTER A GRAVE;;;00E0; +00C1;LATIN CAPITAL LETTER A WITH ACUTE;Lu;0;L;0041 0301;;;;N;LATIN CAPITAL LETTER A ACUTE;;;00E1; +00C2;LATIN CAPITAL LETTER A WITH CIRCUMFLEX;Lu;0;L;0041 0302;;;;N;LATIN CAPITAL LETTER A CIRCUMFLEX;;;00E2; +00C3;LATIN CAPITAL LETTER A WITH TILDE;Lu;0;L;0041 0303;;;;N;LATIN CAPITAL LETTER A TILDE;;;00E3; +00C4;LATIN CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0041 0308;;;;N;LATIN CAPITAL LETTER A DIAERESIS;;;00E4; +00C5;LATIN CAPITAL LETTER A WITH RING ABOVE;Lu;0;L;0041 030A;;;;N;LATIN CAPITAL LETTER A RING;;;00E5; +00C6;LATIN CAPITAL LETTER AE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER A E;;;00E6; +00C7;LATIN CAPITAL LETTER C WITH CEDILLA;Lu;0;L;0043 0327;;;;N;LATIN CAPITAL LETTER C CEDILLA;;;00E7; +00C8;LATIN CAPITAL LETTER E WITH GRAVE;Lu;0;L;0045 0300;;;;N;LATIN CAPITAL LETTER E GRAVE;;;00E8; +00C9;LATIN CAPITAL LETTER E WITH ACUTE;Lu;0;L;0045 0301;;;;N;LATIN CAPITAL LETTER E ACUTE;;;00E9; +00CA;LATIN CAPITAL LETTER E WITH CIRCUMFLEX;Lu;0;L;0045 0302;;;;N;LATIN CAPITAL LETTER E CIRCUMFLEX;;;00EA; +00CB;LATIN CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;0045 0308;;;;N;LATIN CAPITAL LETTER E DIAERESIS;;;00EB; +00CC;LATIN CAPITAL LETTER I WITH GRAVE;Lu;0;L;0049 0300;;;;N;LATIN CAPITAL LETTER I GRAVE;;;00EC; +00CD;LATIN CAPITAL LETTER I WITH ACUTE;Lu;0;L;0049 0301;;;;N;LATIN CAPITAL LETTER I ACUTE;;;00ED; +00CE;LATIN CAPITAL LETTER I WITH CIRCUMFLEX;Lu;0;L;0049 0302;;;;N;LATIN CAPITAL LETTER I CIRCUMFLEX;;;00EE; +00CF;LATIN CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0049 0308;;;;N;LATIN CAPITAL LETTER I DIAERESIS;;;00EF; +00D0;LATIN CAPITAL LETTER ETH;Lu;0;L;;;;;N;;;;00F0; +00D1;LATIN CAPITAL LETTER N WITH TILDE;Lu;0;L;004E 0303;;;;N;LATIN CAPITAL LETTER N TILDE;;;00F1; +00D2;LATIN CAPITAL LETTER O WITH GRAVE;Lu;0;L;004F 0300;;;;N;LATIN CAPITAL LETTER O GRAVE;;;00F2; +00D3;LATIN CAPITAL LETTER O WITH ACUTE;Lu;0;L;004F 0301;;;;N;LATIN CAPITAL LETTER O ACUTE;;;00F3; +00D4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX;Lu;0;L;004F 0302;;;;N;LATIN CAPITAL LETTER O CIRCUMFLEX;;;00F4; +00D5;LATIN CAPITAL LETTER O WITH TILDE;Lu;0;L;004F 0303;;;;N;LATIN CAPITAL LETTER O TILDE;;;00F5; +00D6;LATIN CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;004F 0308;;;;N;LATIN CAPITAL LETTER O DIAERESIS;;;00F6; +00D7;MULTIPLICATION SIGN;Sm;0;ON;;;;;N;;;;; +00D8;LATIN CAPITAL LETTER O WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O SLASH;;;00F8; +00D9;LATIN CAPITAL LETTER U WITH GRAVE;Lu;0;L;0055 0300;;;;N;LATIN CAPITAL LETTER U GRAVE;;;00F9; +00DA;LATIN CAPITAL LETTER U WITH ACUTE;Lu;0;L;0055 0301;;;;N;LATIN CAPITAL LETTER U ACUTE;;;00FA; +00DB;LATIN CAPITAL LETTER U WITH CIRCUMFLEX;Lu;0;L;0055 0302;;;;N;LATIN CAPITAL LETTER U CIRCUMFLEX;;;00FB; +00DC;LATIN CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0055 0308;;;;N;LATIN CAPITAL LETTER U DIAERESIS;;;00FC; +00DD;LATIN CAPITAL LETTER Y WITH ACUTE;Lu;0;L;0059 0301;;;;N;LATIN CAPITAL LETTER Y ACUTE;;;00FD; +00DE;LATIN CAPITAL LETTER THORN;Lu;0;L;;;;;N;;;;00FE; +00DF;LATIN SMALL LETTER SHARP S;Ll;0;L;;;;;N;;;;; +00E0;LATIN SMALL LETTER A WITH GRAVE;Ll;0;L;0061 0300;;;;N;LATIN SMALL LETTER A GRAVE;;00C0;;00C0 +00E1;LATIN SMALL LETTER A WITH ACUTE;Ll;0;L;0061 0301;;;;N;LATIN SMALL LETTER A ACUTE;;00C1;;00C1 +00E2;LATIN SMALL LETTER A WITH CIRCUMFLEX;Ll;0;L;0061 0302;;;;N;LATIN SMALL LETTER A CIRCUMFLEX;;00C2;;00C2 +00E3;LATIN SMALL LETTER A WITH TILDE;Ll;0;L;0061 0303;;;;N;LATIN SMALL LETTER A TILDE;;00C3;;00C3 +00E4;LATIN SMALL LETTER A WITH DIAERESIS;Ll;0;L;0061 0308;;;;N;LATIN SMALL LETTER A DIAERESIS;;00C4;;00C4 +00E5;LATIN SMALL LETTER A WITH RING ABOVE;Ll;0;L;0061 030A;;;;N;LATIN SMALL LETTER A RING;;00C5;;00C5 +00E6;LATIN SMALL LETTER AE;Ll;0;L;;;;;N;LATIN SMALL LETTER A E;;00C6;;00C6 +00E7;LATIN SMALL LETTER C WITH CEDILLA;Ll;0;L;0063 0327;;;;N;LATIN SMALL LETTER C CEDILLA;;00C7;;00C7 +00E8;LATIN SMALL LETTER E WITH GRAVE;Ll;0;L;0065 0300;;;;N;LATIN SMALL LETTER E GRAVE;;00C8;;00C8 +00E9;LATIN SMALL LETTER E WITH ACUTE;Ll;0;L;0065 0301;;;;N;LATIN SMALL LETTER E ACUTE;;00C9;;00C9 +00EA;LATIN SMALL LETTER E WITH CIRCUMFLEX;Ll;0;L;0065 0302;;;;N;LATIN SMALL LETTER E CIRCUMFLEX;;00CA;;00CA +00EB;LATIN SMALL LETTER E WITH DIAERESIS;Ll;0;L;0065 0308;;;;N;LATIN SMALL LETTER E DIAERESIS;;00CB;;00CB +00EC;LATIN SMALL LETTER I WITH GRAVE;Ll;0;L;0069 0300;;;;N;LATIN SMALL LETTER I GRAVE;;00CC;;00CC +00ED;LATIN SMALL LETTER I WITH ACUTE;Ll;0;L;0069 0301;;;;N;LATIN SMALL LETTER I ACUTE;;00CD;;00CD +00EE;LATIN SMALL LETTER I WITH CIRCUMFLEX;Ll;0;L;0069 0302;;;;N;LATIN SMALL LETTER I CIRCUMFLEX;;00CE;;00CE +00EF;LATIN SMALL LETTER I WITH DIAERESIS;Ll;0;L;0069 0308;;;;N;LATIN SMALL LETTER I DIAERESIS;;00CF;;00CF +00F0;LATIN SMALL LETTER ETH;Ll;0;L;;;;;N;;;00D0;;00D0 +00F1;LATIN SMALL LETTER N WITH TILDE;Ll;0;L;006E 0303;;;;N;LATIN SMALL LETTER N TILDE;;00D1;;00D1 +00F2;LATIN SMALL LETTER O WITH GRAVE;Ll;0;L;006F 0300;;;;N;LATIN SMALL LETTER O GRAVE;;00D2;;00D2 +00F3;LATIN SMALL LETTER O WITH ACUTE;Ll;0;L;006F 0301;;;;N;LATIN SMALL LETTER O ACUTE;;00D3;;00D3 +00F4;LATIN SMALL LETTER O WITH CIRCUMFLEX;Ll;0;L;006F 0302;;;;N;LATIN SMALL LETTER O CIRCUMFLEX;;00D4;;00D4 +00F5;LATIN SMALL LETTER O WITH TILDE;Ll;0;L;006F 0303;;;;N;LATIN SMALL LETTER O TILDE;;00D5;;00D5 +00F6;LATIN SMALL LETTER O WITH DIAERESIS;Ll;0;L;006F 0308;;;;N;LATIN SMALL LETTER O DIAERESIS;;00D6;;00D6 +00F7;DIVISION SIGN;Sm;0;ON;;;;;N;;;;; +00F8;LATIN SMALL LETTER O WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER O SLASH;;00D8;;00D8 +00F9;LATIN SMALL LETTER U WITH GRAVE;Ll;0;L;0075 0300;;;;N;LATIN SMALL LETTER U GRAVE;;00D9;;00D9 +00FA;LATIN SMALL LETTER U WITH ACUTE;Ll;0;L;0075 0301;;;;N;LATIN SMALL LETTER U ACUTE;;00DA;;00DA +00FB;LATIN SMALL LETTER U WITH CIRCUMFLEX;Ll;0;L;0075 0302;;;;N;LATIN SMALL LETTER U CIRCUMFLEX;;00DB;;00DB +00FC;LATIN SMALL LETTER U WITH DIAERESIS;Ll;0;L;0075 0308;;;;N;LATIN SMALL LETTER U DIAERESIS;;00DC;;00DC +00FD;LATIN SMALL LETTER Y WITH ACUTE;Ll;0;L;0079 0301;;;;N;LATIN SMALL LETTER Y ACUTE;;00DD;;00DD +00FE;LATIN SMALL LETTER THORN;Ll;0;L;;;;;N;;;00DE;;00DE +00FF;LATIN SMALL LETTER Y WITH DIAERESIS;Ll;0;L;0079 0308;;;;N;LATIN SMALL LETTER Y DIAERESIS;;0178;;0178 +0100;LATIN CAPITAL LETTER A WITH MACRON;Lu;0;L;0041 0304;;;;N;LATIN CAPITAL LETTER A MACRON;;;0101; +0101;LATIN SMALL LETTER A WITH MACRON;Ll;0;L;0061 0304;;;;N;LATIN SMALL LETTER A MACRON;;0100;;0100 +0102;LATIN CAPITAL LETTER A WITH BREVE;Lu;0;L;0041 0306;;;;N;LATIN CAPITAL LETTER A BREVE;;;0103; +0103;LATIN SMALL LETTER A WITH BREVE;Ll;0;L;0061 0306;;;;N;LATIN SMALL LETTER A BREVE;;0102;;0102 +0104;LATIN CAPITAL LETTER A WITH OGONEK;Lu;0;L;0041 0328;;;;N;LATIN CAPITAL LETTER A OGONEK;;;0105; +0105;LATIN SMALL LETTER A WITH OGONEK;Ll;0;L;0061 0328;;;;N;LATIN SMALL LETTER A OGONEK;;0104;;0104 +0106;LATIN CAPITAL LETTER C WITH ACUTE;Lu;0;L;0043 0301;;;;N;LATIN CAPITAL LETTER C ACUTE;;;0107; +0107;LATIN SMALL LETTER C WITH ACUTE;Ll;0;L;0063 0301;;;;N;LATIN SMALL LETTER C ACUTE;;0106;;0106 +0108;LATIN CAPITAL LETTER C WITH CIRCUMFLEX;Lu;0;L;0043 0302;;;;N;LATIN CAPITAL LETTER C CIRCUMFLEX;;;0109; +0109;LATIN SMALL LETTER C WITH CIRCUMFLEX;Ll;0;L;0063 0302;;;;N;LATIN SMALL LETTER C CIRCUMFLEX;;0108;;0108 +010A;LATIN CAPITAL LETTER C WITH DOT ABOVE;Lu;0;L;0043 0307;;;;N;LATIN CAPITAL LETTER C DOT;;;010B; +010B;LATIN SMALL LETTER C WITH DOT ABOVE;Ll;0;L;0063 0307;;;;N;LATIN SMALL LETTER C DOT;;010A;;010A +010C;LATIN CAPITAL LETTER C WITH CARON;Lu;0;L;0043 030C;;;;N;LATIN CAPITAL LETTER C HACEK;;;010D; +010D;LATIN SMALL LETTER C WITH CARON;Ll;0;L;0063 030C;;;;N;LATIN SMALL LETTER C HACEK;;010C;;010C +010E;LATIN CAPITAL LETTER D WITH CARON;Lu;0;L;0044 030C;;;;N;LATIN CAPITAL LETTER D HACEK;;;010F; +010F;LATIN SMALL LETTER D WITH CARON;Ll;0;L;0064 030C;;;;N;LATIN SMALL LETTER D HACEK;;010E;;010E +0110;LATIN CAPITAL LETTER D WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D BAR;;;0111; +0111;LATIN SMALL LETTER D WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER D BAR;;0110;;0110 +0112;LATIN CAPITAL LETTER E WITH MACRON;Lu;0;L;0045 0304;;;;N;LATIN CAPITAL LETTER E MACRON;;;0113; +0113;LATIN SMALL LETTER E WITH MACRON;Ll;0;L;0065 0304;;;;N;LATIN SMALL LETTER E MACRON;;0112;;0112 +0114;LATIN CAPITAL LETTER E WITH BREVE;Lu;0;L;0045 0306;;;;N;LATIN CAPITAL LETTER E BREVE;;;0115; +0115;LATIN SMALL LETTER E WITH BREVE;Ll;0;L;0065 0306;;;;N;LATIN SMALL LETTER E BREVE;;0114;;0114 +0116;LATIN CAPITAL LETTER E WITH DOT ABOVE;Lu;0;L;0045 0307;;;;N;LATIN CAPITAL LETTER E DOT;;;0117; +0117;LATIN SMALL LETTER E WITH DOT ABOVE;Ll;0;L;0065 0307;;;;N;LATIN SMALL LETTER E DOT;;0116;;0116 +0118;LATIN CAPITAL LETTER E WITH OGONEK;Lu;0;L;0045 0328;;;;N;LATIN CAPITAL LETTER E OGONEK;;;0119; +0119;LATIN SMALL LETTER E WITH OGONEK;Ll;0;L;0065 0328;;;;N;LATIN SMALL LETTER E OGONEK;;0118;;0118 +011A;LATIN CAPITAL LETTER E WITH CARON;Lu;0;L;0045 030C;;;;N;LATIN CAPITAL LETTER E HACEK;;;011B; +011B;LATIN SMALL LETTER E WITH CARON;Ll;0;L;0065 030C;;;;N;LATIN SMALL LETTER E HACEK;;011A;;011A +011C;LATIN CAPITAL LETTER G WITH CIRCUMFLEX;Lu;0;L;0047 0302;;;;N;LATIN CAPITAL LETTER G CIRCUMFLEX;;;011D; +011D;LATIN SMALL LETTER G WITH CIRCUMFLEX;Ll;0;L;0067 0302;;;;N;LATIN SMALL LETTER G CIRCUMFLEX;;011C;;011C +011E;LATIN CAPITAL LETTER G WITH BREVE;Lu;0;L;0047 0306;;;;N;LATIN CAPITAL LETTER G BREVE;;;011F; +011F;LATIN SMALL LETTER G WITH BREVE;Ll;0;L;0067 0306;;;;N;LATIN SMALL LETTER G BREVE;;011E;;011E +0120;LATIN CAPITAL LETTER G WITH DOT ABOVE;Lu;0;L;0047 0307;;;;N;LATIN CAPITAL LETTER G DOT;;;0121; +0121;LATIN SMALL LETTER G WITH DOT ABOVE;Ll;0;L;0067 0307;;;;N;LATIN SMALL LETTER G DOT;;0120;;0120 +0122;LATIN CAPITAL LETTER G WITH CEDILLA;Lu;0;L;0047 0327;;;;N;LATIN CAPITAL LETTER G CEDILLA;;;0123; +0123;LATIN SMALL LETTER G WITH CEDILLA;Ll;0;L;0067 0327;;;;N;LATIN SMALL LETTER G CEDILLA;;0122;;0122 +0124;LATIN CAPITAL LETTER H WITH CIRCUMFLEX;Lu;0;L;0048 0302;;;;N;LATIN CAPITAL LETTER H CIRCUMFLEX;;;0125; +0125;LATIN SMALL LETTER H WITH CIRCUMFLEX;Ll;0;L;0068 0302;;;;N;LATIN SMALL LETTER H CIRCUMFLEX;;0124;;0124 +0126;LATIN CAPITAL LETTER H WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER H BAR;;;0127; +0127;LATIN SMALL LETTER H WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER H BAR;;0126;;0126 +0128;LATIN CAPITAL LETTER I WITH TILDE;Lu;0;L;0049 0303;;;;N;LATIN CAPITAL LETTER I TILDE;;;0129; +0129;LATIN SMALL LETTER I WITH TILDE;Ll;0;L;0069 0303;;;;N;LATIN SMALL LETTER I TILDE;;0128;;0128 +012A;LATIN CAPITAL LETTER I WITH MACRON;Lu;0;L;0049 0304;;;;N;LATIN CAPITAL LETTER I MACRON;;;012B; +012B;LATIN SMALL LETTER I WITH MACRON;Ll;0;L;0069 0304;;;;N;LATIN SMALL LETTER I MACRON;;012A;;012A +012C;LATIN CAPITAL LETTER I WITH BREVE;Lu;0;L;0049 0306;;;;N;LATIN CAPITAL LETTER I BREVE;;;012D; +012D;LATIN SMALL LETTER I WITH BREVE;Ll;0;L;0069 0306;;;;N;LATIN SMALL LETTER I BREVE;;012C;;012C +012E;LATIN CAPITAL LETTER I WITH OGONEK;Lu;0;L;0049 0328;;;;N;LATIN CAPITAL LETTER I OGONEK;;;012F; +012F;LATIN SMALL LETTER I WITH OGONEK;Ll;0;L;0069 0328;;;;N;LATIN SMALL LETTER I OGONEK;;012E;;012E +0130;LATIN CAPITAL LETTER I WITH DOT ABOVE;Lu;0;L;0049 0307;;;;N;LATIN CAPITAL LETTER I DOT;;;0069; +0131;LATIN SMALL LETTER DOTLESS I;Ll;0;L;;;;;N;;;0049;;0049 +0132;LATIN CAPITAL LIGATURE IJ;Lu;0;L; 0049 004A;;;;N;LATIN CAPITAL LETTER I J;;;0133; +0133;LATIN SMALL LIGATURE IJ;Ll;0;L; 0069 006A;;;;N;LATIN SMALL LETTER I J;;0132;;0132 +0134;LATIN CAPITAL LETTER J WITH CIRCUMFLEX;Lu;0;L;004A 0302;;;;N;LATIN CAPITAL LETTER J CIRCUMFLEX;;;0135; +0135;LATIN SMALL LETTER J WITH CIRCUMFLEX;Ll;0;L;006A 0302;;;;N;LATIN SMALL LETTER J CIRCUMFLEX;;0134;;0134 +0136;LATIN CAPITAL LETTER K WITH CEDILLA;Lu;0;L;004B 0327;;;;N;LATIN CAPITAL LETTER K CEDILLA;;;0137; +0137;LATIN SMALL LETTER K WITH CEDILLA;Ll;0;L;006B 0327;;;;N;LATIN SMALL LETTER K CEDILLA;;0136;;0136 +0138;LATIN SMALL LETTER KRA;Ll;0;L;;;;;N;;;;; +0139;LATIN CAPITAL LETTER L WITH ACUTE;Lu;0;L;004C 0301;;;;N;LATIN CAPITAL LETTER L ACUTE;;;013A; +013A;LATIN SMALL LETTER L WITH ACUTE;Ll;0;L;006C 0301;;;;N;LATIN SMALL LETTER L ACUTE;;0139;;0139 +013B;LATIN CAPITAL LETTER L WITH CEDILLA;Lu;0;L;004C 0327;;;;N;LATIN CAPITAL LETTER L CEDILLA;;;013C; +013C;LATIN SMALL LETTER L WITH CEDILLA;Ll;0;L;006C 0327;;;;N;LATIN SMALL LETTER L CEDILLA;;013B;;013B +013D;LATIN CAPITAL LETTER L WITH CARON;Lu;0;L;004C 030C;;;;N;LATIN CAPITAL LETTER L HACEK;;;013E; +013E;LATIN SMALL LETTER L WITH CARON;Ll;0;L;006C 030C;;;;N;LATIN SMALL LETTER L HACEK;;013D;;013D +013F;LATIN CAPITAL LETTER L WITH MIDDLE DOT;Lu;0;L; 004C 00B7;;;;N;;;;0140; +0140;LATIN SMALL LETTER L WITH MIDDLE DOT;Ll;0;L; 006C 00B7;;;;N;;;013F;;013F +0141;LATIN CAPITAL LETTER L WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER L SLASH;;;0142; +0142;LATIN SMALL LETTER L WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER L SLASH;;0141;;0141 +0143;LATIN CAPITAL LETTER N WITH ACUTE;Lu;0;L;004E 0301;;;;N;LATIN CAPITAL LETTER N ACUTE;;;0144; +0144;LATIN SMALL LETTER N WITH ACUTE;Ll;0;L;006E 0301;;;;N;LATIN SMALL LETTER N ACUTE;;0143;;0143 +0145;LATIN CAPITAL LETTER N WITH CEDILLA;Lu;0;L;004E 0327;;;;N;LATIN CAPITAL LETTER N CEDILLA;;;0146; +0146;LATIN SMALL LETTER N WITH CEDILLA;Ll;0;L;006E 0327;;;;N;LATIN SMALL LETTER N CEDILLA;;0145;;0145 +0147;LATIN CAPITAL LETTER N WITH CARON;Lu;0;L;004E 030C;;;;N;LATIN CAPITAL LETTER N HACEK;;;0148; +0148;LATIN SMALL LETTER N WITH CARON;Ll;0;L;006E 030C;;;;N;LATIN SMALL LETTER N HACEK;;0147;;0147 +0149;LATIN SMALL LETTER N PRECEDED BY APOSTROPHE;Ll;0;L; 02BC 006E;;;;N;LATIN SMALL LETTER APOSTROPHE N;;;; +014A;LATIN CAPITAL LETTER ENG;Lu;0;L;;;;;N;;;;014B; +014B;LATIN SMALL LETTER ENG;Ll;0;L;;;;;N;;;014A;;014A +014C;LATIN CAPITAL LETTER O WITH MACRON;Lu;0;L;004F 0304;;;;N;LATIN CAPITAL LETTER O MACRON;;;014D; +014D;LATIN SMALL LETTER O WITH MACRON;Ll;0;L;006F 0304;;;;N;LATIN SMALL LETTER O MACRON;;014C;;014C +014E;LATIN CAPITAL LETTER O WITH BREVE;Lu;0;L;004F 0306;;;;N;LATIN CAPITAL LETTER O BREVE;;;014F; +014F;LATIN SMALL LETTER O WITH BREVE;Ll;0;L;006F 0306;;;;N;LATIN SMALL LETTER O BREVE;;014E;;014E +0150;LATIN CAPITAL LETTER O WITH DOUBLE ACUTE;Lu;0;L;004F 030B;;;;N;LATIN CAPITAL LETTER O DOUBLE ACUTE;;;0151; +0151;LATIN SMALL LETTER O WITH DOUBLE ACUTE;Ll;0;L;006F 030B;;;;N;LATIN SMALL LETTER O DOUBLE ACUTE;;0150;;0150 +0152;LATIN CAPITAL LIGATURE OE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O E;;;0153; +0153;LATIN SMALL LIGATURE OE;Ll;0;L;;;;;N;LATIN SMALL LETTER O E;;0152;;0152 +0154;LATIN CAPITAL LETTER R WITH ACUTE;Lu;0;L;0052 0301;;;;N;LATIN CAPITAL LETTER R ACUTE;;;0155; +0155;LATIN SMALL LETTER R WITH ACUTE;Ll;0;L;0072 0301;;;;N;LATIN SMALL LETTER R ACUTE;;0154;;0154 +0156;LATIN CAPITAL LETTER R WITH CEDILLA;Lu;0;L;0052 0327;;;;N;LATIN CAPITAL LETTER R CEDILLA;;;0157; +0157;LATIN SMALL LETTER R WITH CEDILLA;Ll;0;L;0072 0327;;;;N;LATIN SMALL LETTER R CEDILLA;;0156;;0156 +0158;LATIN CAPITAL LETTER R WITH CARON;Lu;0;L;0052 030C;;;;N;LATIN CAPITAL LETTER R HACEK;;;0159; +0159;LATIN SMALL LETTER R WITH CARON;Ll;0;L;0072 030C;;;;N;LATIN SMALL LETTER R HACEK;;0158;;0158 +015A;LATIN CAPITAL LETTER S WITH ACUTE;Lu;0;L;0053 0301;;;;N;LATIN CAPITAL LETTER S ACUTE;;;015B; +015B;LATIN SMALL LETTER S WITH ACUTE;Ll;0;L;0073 0301;;;;N;LATIN SMALL LETTER S ACUTE;;015A;;015A +015C;LATIN CAPITAL LETTER S WITH CIRCUMFLEX;Lu;0;L;0053 0302;;;;N;LATIN CAPITAL LETTER S CIRCUMFLEX;;;015D; +015D;LATIN SMALL LETTER S WITH CIRCUMFLEX;Ll;0;L;0073 0302;;;;N;LATIN SMALL LETTER S CIRCUMFLEX;;015C;;015C +015E;LATIN CAPITAL LETTER S WITH CEDILLA;Lu;0;L;0053 0327;;;;N;LATIN CAPITAL LETTER S CEDILLA;;;015F; +015F;LATIN SMALL LETTER S WITH CEDILLA;Ll;0;L;0073 0327;;;;N;LATIN SMALL LETTER S CEDILLA;;015E;;015E +0160;LATIN CAPITAL LETTER S WITH CARON;Lu;0;L;0053 030C;;;;N;LATIN CAPITAL LETTER S HACEK;;;0161; +0161;LATIN SMALL LETTER S WITH CARON;Ll;0;L;0073 030C;;;;N;LATIN SMALL LETTER S HACEK;;0160;;0160 +0162;LATIN CAPITAL LETTER T WITH CEDILLA;Lu;0;L;0054 0327;;;;N;LATIN CAPITAL LETTER T CEDILLA;;;0163; +0163;LATIN SMALL LETTER T WITH CEDILLA;Ll;0;L;0074 0327;;;;N;LATIN SMALL LETTER T CEDILLA;;0162;;0162 +0164;LATIN CAPITAL LETTER T WITH CARON;Lu;0;L;0054 030C;;;;N;LATIN CAPITAL LETTER T HACEK;;;0165; +0165;LATIN SMALL LETTER T WITH CARON;Ll;0;L;0074 030C;;;;N;LATIN SMALL LETTER T HACEK;;0164;;0164 +0166;LATIN CAPITAL LETTER T WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T BAR;;;0167; +0167;LATIN SMALL LETTER T WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER T BAR;;0166;;0166 +0168;LATIN CAPITAL LETTER U WITH TILDE;Lu;0;L;0055 0303;;;;N;LATIN CAPITAL LETTER U TILDE;;;0169; +0169;LATIN SMALL LETTER U WITH TILDE;Ll;0;L;0075 0303;;;;N;LATIN SMALL LETTER U TILDE;;0168;;0168 +016A;LATIN CAPITAL LETTER U WITH MACRON;Lu;0;L;0055 0304;;;;N;LATIN CAPITAL LETTER U MACRON;;;016B; +016B;LATIN SMALL LETTER U WITH MACRON;Ll;0;L;0075 0304;;;;N;LATIN SMALL LETTER U MACRON;;016A;;016A +016C;LATIN CAPITAL LETTER U WITH BREVE;Lu;0;L;0055 0306;;;;N;LATIN CAPITAL LETTER U BREVE;;;016D; +016D;LATIN SMALL LETTER U WITH BREVE;Ll;0;L;0075 0306;;;;N;LATIN SMALL LETTER U BREVE;;016C;;016C +016E;LATIN CAPITAL LETTER U WITH RING ABOVE;Lu;0;L;0055 030A;;;;N;LATIN CAPITAL LETTER U RING;;;016F; +016F;LATIN SMALL LETTER U WITH RING ABOVE;Ll;0;L;0075 030A;;;;N;LATIN SMALL LETTER U RING;;016E;;016E +0170;LATIN CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0055 030B;;;;N;LATIN CAPITAL LETTER U DOUBLE ACUTE;;;0171; +0171;LATIN SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0075 030B;;;;N;LATIN SMALL LETTER U DOUBLE ACUTE;;0170;;0170 +0172;LATIN CAPITAL LETTER U WITH OGONEK;Lu;0;L;0055 0328;;;;N;LATIN CAPITAL LETTER U OGONEK;;;0173; +0173;LATIN SMALL LETTER U WITH OGONEK;Ll;0;L;0075 0328;;;;N;LATIN SMALL LETTER U OGONEK;;0172;;0172 +0174;LATIN CAPITAL LETTER W WITH CIRCUMFLEX;Lu;0;L;0057 0302;;;;N;LATIN CAPITAL LETTER W CIRCUMFLEX;;;0175; +0175;LATIN SMALL LETTER W WITH CIRCUMFLEX;Ll;0;L;0077 0302;;;;N;LATIN SMALL LETTER W CIRCUMFLEX;;0174;;0174 +0176;LATIN CAPITAL LETTER Y WITH CIRCUMFLEX;Lu;0;L;0059 0302;;;;N;LATIN CAPITAL LETTER Y CIRCUMFLEX;;;0177; +0177;LATIN SMALL LETTER Y WITH CIRCUMFLEX;Ll;0;L;0079 0302;;;;N;LATIN SMALL LETTER Y CIRCUMFLEX;;0176;;0176 +0178;LATIN CAPITAL LETTER Y WITH DIAERESIS;Lu;0;L;0059 0308;;;;N;LATIN CAPITAL LETTER Y DIAERESIS;;;00FF; +0179;LATIN CAPITAL LETTER Z WITH ACUTE;Lu;0;L;005A 0301;;;;N;LATIN CAPITAL LETTER Z ACUTE;;;017A; +017A;LATIN SMALL LETTER Z WITH ACUTE;Ll;0;L;007A 0301;;;;N;LATIN SMALL LETTER Z ACUTE;;0179;;0179 +017B;LATIN CAPITAL LETTER Z WITH DOT ABOVE;Lu;0;L;005A 0307;;;;N;LATIN CAPITAL LETTER Z DOT;;;017C; +017C;LATIN SMALL LETTER Z WITH DOT ABOVE;Ll;0;L;007A 0307;;;;N;LATIN SMALL LETTER Z DOT;;017B;;017B +017D;LATIN CAPITAL LETTER Z WITH CARON;Lu;0;L;005A 030C;;;;N;LATIN CAPITAL LETTER Z HACEK;;;017E; +017E;LATIN SMALL LETTER Z WITH CARON;Ll;0;L;007A 030C;;;;N;LATIN SMALL LETTER Z HACEK;;017D;;017D +017F;LATIN SMALL LETTER LONG S;Ll;0;L; 0073;;;;N;;;0053;;0053 +0180;LATIN SMALL LETTER B WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER B BAR;;0243;;0243 +0181;LATIN CAPITAL LETTER B WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B HOOK;;;0253; +0182;LATIN CAPITAL LETTER B WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B TOPBAR;;;0183; +0183;LATIN SMALL LETTER B WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER B TOPBAR;;0182;;0182 +0184;LATIN CAPITAL LETTER TONE SIX;Lu;0;L;;;;;N;;;;0185; +0185;LATIN SMALL LETTER TONE SIX;Ll;0;L;;;;;N;;;0184;;0184 +0186;LATIN CAPITAL LETTER OPEN O;Lu;0;L;;;;;N;;;;0254; +0187;LATIN CAPITAL LETTER C WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER C HOOK;;;0188; +0188;LATIN SMALL LETTER C WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER C HOOK;;0187;;0187 +0189;LATIN CAPITAL LETTER AFRICAN D;Lu;0;L;;;;;N;;;;0256; +018A;LATIN CAPITAL LETTER D WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D HOOK;;;0257; +018B;LATIN CAPITAL LETTER D WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D TOPBAR;;;018C; +018C;LATIN SMALL LETTER D WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER D TOPBAR;;018B;;018B +018D;LATIN SMALL LETTER TURNED DELTA;Ll;0;L;;;;;N;;;;; +018E;LATIN CAPITAL LETTER REVERSED E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER TURNED E;;;01DD; +018F;LATIN CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;0259; +0190;LATIN CAPITAL LETTER OPEN E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER EPSILON;;;025B; +0191;LATIN CAPITAL LETTER F WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER F HOOK;;;0192; +0192;LATIN SMALL LETTER F WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT F;;0191;;0191 +0193;LATIN CAPITAL LETTER G WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G HOOK;;;0260; +0194;LATIN CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;0263; +0195;LATIN SMALL LETTER HV;Ll;0;L;;;;;N;LATIN SMALL LETTER H V;;01F6;;01F6 +0196;LATIN CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;0269; +0197;LATIN CAPITAL LETTER I WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED I;;;0268; +0198;LATIN CAPITAL LETTER K WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER K HOOK;;;0199; +0199;LATIN SMALL LETTER K WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER K HOOK;;0198;;0198 +019A;LATIN SMALL LETTER L WITH BAR;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED L;;023D;;023D +019B;LATIN SMALL LETTER LAMBDA WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED LAMBDA;;;; +019C;LATIN CAPITAL LETTER TURNED M;Lu;0;L;;;;;N;;;;026F; +019D;LATIN CAPITAL LETTER N WITH LEFT HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER N HOOK;;;0272; +019E;LATIN SMALL LETTER N WITH LONG RIGHT LEG;Ll;0;L;;;;;N;;;0220;;0220 +019F;LATIN CAPITAL LETTER O WITH MIDDLE TILDE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED O;;;0275; +01A0;LATIN CAPITAL LETTER O WITH HORN;Lu;0;L;004F 031B;;;;N;LATIN CAPITAL LETTER O HORN;;;01A1; +01A1;LATIN SMALL LETTER O WITH HORN;Ll;0;L;006F 031B;;;;N;LATIN SMALL LETTER O HORN;;01A0;;01A0 +01A2;LATIN CAPITAL LETTER OI;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O I;;;01A3; +01A3;LATIN SMALL LETTER OI;Ll;0;L;;;;;N;LATIN SMALL LETTER O I;;01A2;;01A2 +01A4;LATIN CAPITAL LETTER P WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER P HOOK;;;01A5; +01A5;LATIN SMALL LETTER P WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER P HOOK;;01A4;;01A4 +01A6;LATIN LETTER YR;Lu;0;L;;;;;N;LATIN LETTER Y R;;;0280; +01A7;LATIN CAPITAL LETTER TONE TWO;Lu;0;L;;;;;N;;;;01A8; +01A8;LATIN SMALL LETTER TONE TWO;Ll;0;L;;;;;N;;;01A7;;01A7 +01A9;LATIN CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;0283; +01AA;LATIN LETTER REVERSED ESH LOOP;Ll;0;L;;;;;N;;;;; +01AB;LATIN SMALL LETTER T WITH PALATAL HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T PALATAL HOOK;;;; +01AC;LATIN CAPITAL LETTER T WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T HOOK;;;01AD; +01AD;LATIN SMALL LETTER T WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T HOOK;;01AC;;01AC +01AE;LATIN CAPITAL LETTER T WITH RETROFLEX HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T RETROFLEX HOOK;;;0288; +01AF;LATIN CAPITAL LETTER U WITH HORN;Lu;0;L;0055 031B;;;;N;LATIN CAPITAL LETTER U HORN;;;01B0; +01B0;LATIN SMALL LETTER U WITH HORN;Ll;0;L;0075 031B;;;;N;LATIN SMALL LETTER U HORN;;01AF;;01AF +01B1;LATIN CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;028A; +01B2;LATIN CAPITAL LETTER V WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER SCRIPT V;;;028B; +01B3;LATIN CAPITAL LETTER Y WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Y HOOK;;;01B4; +01B4;LATIN SMALL LETTER Y WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Y HOOK;;01B3;;01B3 +01B5;LATIN CAPITAL LETTER Z WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Z BAR;;;01B6; +01B6;LATIN SMALL LETTER Z WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER Z BAR;;01B5;;01B5 +01B7;LATIN CAPITAL LETTER EZH;Lu;0;L;;;;;N;LATIN CAPITAL LETTER YOGH;;;0292; +01B8;LATIN CAPITAL LETTER EZH REVERSED;Lu;0;L;;;;;N;LATIN CAPITAL LETTER REVERSED YOGH;;;01B9; +01B9;LATIN SMALL LETTER EZH REVERSED;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED YOGH;;01B8;;01B8 +01BA;LATIN SMALL LETTER EZH WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH WITH TAIL;;;; +01BB;LATIN LETTER TWO WITH STROKE;Lo;0;L;;;;;N;LATIN LETTER TWO BAR;;;; +01BC;LATIN CAPITAL LETTER TONE FIVE;Lu;0;L;;;;;N;;;;01BD; +01BD;LATIN SMALL LETTER TONE FIVE;Ll;0;L;;;;;N;;;01BC;;01BC +01BE;LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER INVERTED GLOTTAL STOP BAR;;;; +01BF;LATIN LETTER WYNN;Ll;0;L;;;;;N;;;01F7;;01F7 +01C0;LATIN LETTER DENTAL CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE;;;; +01C1;LATIN LETTER LATERAL CLICK;Lo;0;L;;;;;N;LATIN LETTER DOUBLE PIPE;;;; +01C2;LATIN LETTER ALVEOLAR CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE DOUBLE BAR;;;; +01C3;LATIN LETTER RETROFLEX CLICK;Lo;0;L;;;;;N;LATIN LETTER EXCLAMATION MARK;;;; +01C4;LATIN CAPITAL LETTER DZ WITH CARON;Lu;0;L; 0044 017D;;;;N;LATIN CAPITAL LETTER D Z HACEK;;;01C6;01C5 +01C5;LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON;Lt;0;L; 0044 017E;;;;N;LATIN LETTER CAPITAL D SMALL Z HACEK;;01C4;01C6;01C5 +01C6;LATIN SMALL LETTER DZ WITH CARON;Ll;0;L; 0064 017E;;;;N;LATIN SMALL LETTER D Z HACEK;;01C4;;01C5 +01C7;LATIN CAPITAL LETTER LJ;Lu;0;L; 004C 004A;;;;N;LATIN CAPITAL LETTER L J;;;01C9;01C8 +01C8;LATIN CAPITAL LETTER L WITH SMALL LETTER J;Lt;0;L; 004C 006A;;;;N;LATIN LETTER CAPITAL L SMALL J;;01C7;01C9;01C8 +01C9;LATIN SMALL LETTER LJ;Ll;0;L; 006C 006A;;;;N;LATIN SMALL LETTER L J;;01C7;;01C8 +01CA;LATIN CAPITAL LETTER NJ;Lu;0;L; 004E 004A;;;;N;LATIN CAPITAL LETTER N J;;;01CC;01CB +01CB;LATIN CAPITAL LETTER N WITH SMALL LETTER J;Lt;0;L; 004E 006A;;;;N;LATIN LETTER CAPITAL N SMALL J;;01CA;01CC;01CB +01CC;LATIN SMALL LETTER NJ;Ll;0;L; 006E 006A;;;;N;LATIN SMALL LETTER N J;;01CA;;01CB +01CD;LATIN CAPITAL LETTER A WITH CARON;Lu;0;L;0041 030C;;;;N;LATIN CAPITAL LETTER A HACEK;;;01CE; +01CE;LATIN SMALL LETTER A WITH CARON;Ll;0;L;0061 030C;;;;N;LATIN SMALL LETTER A HACEK;;01CD;;01CD +01CF;LATIN CAPITAL LETTER I WITH CARON;Lu;0;L;0049 030C;;;;N;LATIN CAPITAL LETTER I HACEK;;;01D0; +01D0;LATIN SMALL LETTER I WITH CARON;Ll;0;L;0069 030C;;;;N;LATIN SMALL LETTER I HACEK;;01CF;;01CF +01D1;LATIN CAPITAL LETTER O WITH CARON;Lu;0;L;004F 030C;;;;N;LATIN CAPITAL LETTER O HACEK;;;01D2; +01D2;LATIN SMALL LETTER O WITH CARON;Ll;0;L;006F 030C;;;;N;LATIN SMALL LETTER O HACEK;;01D1;;01D1 +01D3;LATIN CAPITAL LETTER U WITH CARON;Lu;0;L;0055 030C;;;;N;LATIN CAPITAL LETTER U HACEK;;;01D4; +01D4;LATIN SMALL LETTER U WITH CARON;Ll;0;L;0075 030C;;;;N;LATIN SMALL LETTER U HACEK;;01D3;;01D3 +01D5;LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON;Lu;0;L;00DC 0304;;;;N;LATIN CAPITAL LETTER U DIAERESIS MACRON;;;01D6; +01D6;LATIN SMALL LETTER U WITH DIAERESIS AND MACRON;Ll;0;L;00FC 0304;;;;N;LATIN SMALL LETTER U DIAERESIS MACRON;;01D5;;01D5 +01D7;LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE;Lu;0;L;00DC 0301;;;;N;LATIN CAPITAL LETTER U DIAERESIS ACUTE;;;01D8; +01D8;LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE;Ll;0;L;00FC 0301;;;;N;LATIN SMALL LETTER U DIAERESIS ACUTE;;01D7;;01D7 +01D9;LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON;Lu;0;L;00DC 030C;;;;N;LATIN CAPITAL LETTER U DIAERESIS HACEK;;;01DA; +01DA;LATIN SMALL LETTER U WITH DIAERESIS AND CARON;Ll;0;L;00FC 030C;;;;N;LATIN SMALL LETTER U DIAERESIS HACEK;;01D9;;01D9 +01DB;LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE;Lu;0;L;00DC 0300;;;;N;LATIN CAPITAL LETTER U DIAERESIS GRAVE;;;01DC; +01DC;LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE;Ll;0;L;00FC 0300;;;;N;LATIN SMALL LETTER U DIAERESIS GRAVE;;01DB;;01DB +01DD;LATIN SMALL LETTER TURNED E;Ll;0;L;;;;;N;;;018E;;018E +01DE;LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON;Lu;0;L;00C4 0304;;;;N;LATIN CAPITAL LETTER A DIAERESIS MACRON;;;01DF; +01DF;LATIN SMALL LETTER A WITH DIAERESIS AND MACRON;Ll;0;L;00E4 0304;;;;N;LATIN SMALL LETTER A DIAERESIS MACRON;;01DE;;01DE +01E0;LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON;Lu;0;L;0226 0304;;;;N;LATIN CAPITAL LETTER A DOT MACRON;;;01E1; +01E1;LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON;Ll;0;L;0227 0304;;;;N;LATIN SMALL LETTER A DOT MACRON;;01E0;;01E0 +01E2;LATIN CAPITAL LETTER AE WITH MACRON;Lu;0;L;00C6 0304;;;;N;LATIN CAPITAL LETTER A E MACRON;;;01E3; +01E3;LATIN SMALL LETTER AE WITH MACRON;Ll;0;L;00E6 0304;;;;N;LATIN SMALL LETTER A E MACRON;;01E2;;01E2 +01E4;LATIN CAPITAL LETTER G WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G BAR;;;01E5; +01E5;LATIN SMALL LETTER G WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER G BAR;;01E4;;01E4 +01E6;LATIN CAPITAL LETTER G WITH CARON;Lu;0;L;0047 030C;;;;N;LATIN CAPITAL LETTER G HACEK;;;01E7; +01E7;LATIN SMALL LETTER G WITH CARON;Ll;0;L;0067 030C;;;;N;LATIN SMALL LETTER G HACEK;;01E6;;01E6 +01E8;LATIN CAPITAL LETTER K WITH CARON;Lu;0;L;004B 030C;;;;N;LATIN CAPITAL LETTER K HACEK;;;01E9; +01E9;LATIN SMALL LETTER K WITH CARON;Ll;0;L;006B 030C;;;;N;LATIN SMALL LETTER K HACEK;;01E8;;01E8 +01EA;LATIN CAPITAL LETTER O WITH OGONEK;Lu;0;L;004F 0328;;;;N;LATIN CAPITAL LETTER O OGONEK;;;01EB; +01EB;LATIN SMALL LETTER O WITH OGONEK;Ll;0;L;006F 0328;;;;N;LATIN SMALL LETTER O OGONEK;;01EA;;01EA +01EC;LATIN CAPITAL LETTER O WITH OGONEK AND MACRON;Lu;0;L;01EA 0304;;;;N;LATIN CAPITAL LETTER O OGONEK MACRON;;;01ED; +01ED;LATIN SMALL LETTER O WITH OGONEK AND MACRON;Ll;0;L;01EB 0304;;;;N;LATIN SMALL LETTER O OGONEK MACRON;;01EC;;01EC +01EE;LATIN CAPITAL LETTER EZH WITH CARON;Lu;0;L;01B7 030C;;;;N;LATIN CAPITAL LETTER YOGH HACEK;;;01EF; +01EF;LATIN SMALL LETTER EZH WITH CARON;Ll;0;L;0292 030C;;;;N;LATIN SMALL LETTER YOGH HACEK;;01EE;;01EE +01F0;LATIN SMALL LETTER J WITH CARON;Ll;0;L;006A 030C;;;;N;LATIN SMALL LETTER J HACEK;;;; +01F1;LATIN CAPITAL LETTER DZ;Lu;0;L; 0044 005A;;;;N;;;;01F3;01F2 +01F2;LATIN CAPITAL LETTER D WITH SMALL LETTER Z;Lt;0;L; 0044 007A;;;;N;;;01F1;01F3;01F2 +01F3;LATIN SMALL LETTER DZ;Ll;0;L; 0064 007A;;;;N;;;01F1;;01F2 +01F4;LATIN CAPITAL LETTER G WITH ACUTE;Lu;0;L;0047 0301;;;;N;;;;01F5; +01F5;LATIN SMALL LETTER G WITH ACUTE;Ll;0;L;0067 0301;;;;N;;;01F4;;01F4 +01F6;LATIN CAPITAL LETTER HWAIR;Lu;0;L;;;;;N;;;;0195; +01F7;LATIN CAPITAL LETTER WYNN;Lu;0;L;;;;;N;;;;01BF; +01F8;LATIN CAPITAL LETTER N WITH GRAVE;Lu;0;L;004E 0300;;;;N;;;;01F9; +01F9;LATIN SMALL LETTER N WITH GRAVE;Ll;0;L;006E 0300;;;;N;;;01F8;;01F8 +01FA;LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE;Lu;0;L;00C5 0301;;;;N;;;;01FB; +01FB;LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE;Ll;0;L;00E5 0301;;;;N;;;01FA;;01FA +01FC;LATIN CAPITAL LETTER AE WITH ACUTE;Lu;0;L;00C6 0301;;;;N;;;;01FD; +01FD;LATIN SMALL LETTER AE WITH ACUTE;Ll;0;L;00E6 0301;;;;N;;;01FC;;01FC +01FE;LATIN CAPITAL LETTER O WITH STROKE AND ACUTE;Lu;0;L;00D8 0301;;;;N;;;;01FF; +01FF;LATIN SMALL LETTER O WITH STROKE AND ACUTE;Ll;0;L;00F8 0301;;;;N;;;01FE;;01FE +0200;LATIN CAPITAL LETTER A WITH DOUBLE GRAVE;Lu;0;L;0041 030F;;;;N;;;;0201; +0201;LATIN SMALL LETTER A WITH DOUBLE GRAVE;Ll;0;L;0061 030F;;;;N;;;0200;;0200 +0202;LATIN CAPITAL LETTER A WITH INVERTED BREVE;Lu;0;L;0041 0311;;;;N;;;;0203; +0203;LATIN SMALL LETTER A WITH INVERTED BREVE;Ll;0;L;0061 0311;;;;N;;;0202;;0202 +0204;LATIN CAPITAL LETTER E WITH DOUBLE GRAVE;Lu;0;L;0045 030F;;;;N;;;;0205; +0205;LATIN SMALL LETTER E WITH DOUBLE GRAVE;Ll;0;L;0065 030F;;;;N;;;0204;;0204 +0206;LATIN CAPITAL LETTER E WITH INVERTED BREVE;Lu;0;L;0045 0311;;;;N;;;;0207; +0207;LATIN SMALL LETTER E WITH INVERTED BREVE;Ll;0;L;0065 0311;;;;N;;;0206;;0206 +0208;LATIN CAPITAL LETTER I WITH DOUBLE GRAVE;Lu;0;L;0049 030F;;;;N;;;;0209; +0209;LATIN SMALL LETTER I WITH DOUBLE GRAVE;Ll;0;L;0069 030F;;;;N;;;0208;;0208 +020A;LATIN CAPITAL LETTER I WITH INVERTED BREVE;Lu;0;L;0049 0311;;;;N;;;;020B; +020B;LATIN SMALL LETTER I WITH INVERTED BREVE;Ll;0;L;0069 0311;;;;N;;;020A;;020A +020C;LATIN CAPITAL LETTER O WITH DOUBLE GRAVE;Lu;0;L;004F 030F;;;;N;;;;020D; +020D;LATIN SMALL LETTER O WITH DOUBLE GRAVE;Ll;0;L;006F 030F;;;;N;;;020C;;020C +020E;LATIN CAPITAL LETTER O WITH INVERTED BREVE;Lu;0;L;004F 0311;;;;N;;;;020F; +020F;LATIN SMALL LETTER O WITH INVERTED BREVE;Ll;0;L;006F 0311;;;;N;;;020E;;020E +0210;LATIN CAPITAL LETTER R WITH DOUBLE GRAVE;Lu;0;L;0052 030F;;;;N;;;;0211; +0211;LATIN SMALL LETTER R WITH DOUBLE GRAVE;Ll;0;L;0072 030F;;;;N;;;0210;;0210 +0212;LATIN CAPITAL LETTER R WITH INVERTED BREVE;Lu;0;L;0052 0311;;;;N;;;;0213; +0213;LATIN SMALL LETTER R WITH INVERTED BREVE;Ll;0;L;0072 0311;;;;N;;;0212;;0212 +0214;LATIN CAPITAL LETTER U WITH DOUBLE GRAVE;Lu;0;L;0055 030F;;;;N;;;;0215; +0215;LATIN SMALL LETTER U WITH DOUBLE GRAVE;Ll;0;L;0075 030F;;;;N;;;0214;;0214 +0216;LATIN CAPITAL LETTER U WITH INVERTED BREVE;Lu;0;L;0055 0311;;;;N;;;;0217; +0217;LATIN SMALL LETTER U WITH INVERTED BREVE;Ll;0;L;0075 0311;;;;N;;;0216;;0216 +0218;LATIN CAPITAL LETTER S WITH COMMA BELOW;Lu;0;L;0053 0326;;;;N;;;;0219; +0219;LATIN SMALL LETTER S WITH COMMA BELOW;Ll;0;L;0073 0326;;;;N;;;0218;;0218 +021A;LATIN CAPITAL LETTER T WITH COMMA BELOW;Lu;0;L;0054 0326;;;;N;;;;021B; +021B;LATIN SMALL LETTER T WITH COMMA BELOW;Ll;0;L;0074 0326;;;;N;;;021A;;021A +021C;LATIN CAPITAL LETTER YOGH;Lu;0;L;;;;;N;;;;021D; +021D;LATIN SMALL LETTER YOGH;Ll;0;L;;;;;N;;;021C;;021C +021E;LATIN CAPITAL LETTER H WITH CARON;Lu;0;L;0048 030C;;;;N;;;;021F; +021F;LATIN SMALL LETTER H WITH CARON;Ll;0;L;0068 030C;;;;N;;;021E;;021E +0220;LATIN CAPITAL LETTER N WITH LONG RIGHT LEG;Lu;0;L;;;;;N;;;;019E; +0221;LATIN SMALL LETTER D WITH CURL;Ll;0;L;;;;;N;;;;; +0222;LATIN CAPITAL LETTER OU;Lu;0;L;;;;;N;;;;0223; +0223;LATIN SMALL LETTER OU;Ll;0;L;;;;;N;;;0222;;0222 +0224;LATIN CAPITAL LETTER Z WITH HOOK;Lu;0;L;;;;;N;;;;0225; +0225;LATIN SMALL LETTER Z WITH HOOK;Ll;0;L;;;;;N;;;0224;;0224 +0226;LATIN CAPITAL LETTER A WITH DOT ABOVE;Lu;0;L;0041 0307;;;;N;;;;0227; +0227;LATIN SMALL LETTER A WITH DOT ABOVE;Ll;0;L;0061 0307;;;;N;;;0226;;0226 +0228;LATIN CAPITAL LETTER E WITH CEDILLA;Lu;0;L;0045 0327;;;;N;;;;0229; +0229;LATIN SMALL LETTER E WITH CEDILLA;Ll;0;L;0065 0327;;;;N;;;0228;;0228 +022A;LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON;Lu;0;L;00D6 0304;;;;N;;;;022B; +022B;LATIN SMALL LETTER O WITH DIAERESIS AND MACRON;Ll;0;L;00F6 0304;;;;N;;;022A;;022A +022C;LATIN CAPITAL LETTER O WITH TILDE AND MACRON;Lu;0;L;00D5 0304;;;;N;;;;022D; +022D;LATIN SMALL LETTER O WITH TILDE AND MACRON;Ll;0;L;00F5 0304;;;;N;;;022C;;022C +022E;LATIN CAPITAL LETTER O WITH DOT ABOVE;Lu;0;L;004F 0307;;;;N;;;;022F; +022F;LATIN SMALL LETTER O WITH DOT ABOVE;Ll;0;L;006F 0307;;;;N;;;022E;;022E +0230;LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON;Lu;0;L;022E 0304;;;;N;;;;0231; +0231;LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON;Ll;0;L;022F 0304;;;;N;;;0230;;0230 +0232;LATIN CAPITAL LETTER Y WITH MACRON;Lu;0;L;0059 0304;;;;N;;;;0233; +0233;LATIN SMALL LETTER Y WITH MACRON;Ll;0;L;0079 0304;;;;N;;;0232;;0232 +0234;LATIN SMALL LETTER L WITH CURL;Ll;0;L;;;;;N;;;;; +0235;LATIN SMALL LETTER N WITH CURL;Ll;0;L;;;;;N;;;;; +0236;LATIN SMALL LETTER T WITH CURL;Ll;0;L;;;;;N;;;;; +0237;LATIN SMALL LETTER DOTLESS J;Ll;0;L;;;;;N;;;;; +0238;LATIN SMALL LETTER DB DIGRAPH;Ll;0;L;;;;;N;;;;; +0239;LATIN SMALL LETTER QP DIGRAPH;Ll;0;L;;;;;N;;;;; +023A;LATIN CAPITAL LETTER A WITH STROKE;Lu;0;L;;;;;N;;;;2C65; +023B;LATIN CAPITAL LETTER C WITH STROKE;Lu;0;L;;;;;N;;;;023C; +023C;LATIN SMALL LETTER C WITH STROKE;Ll;0;L;;;;;N;;;023B;;023B +023D;LATIN CAPITAL LETTER L WITH BAR;Lu;0;L;;;;;N;;;;019A; +023E;LATIN CAPITAL LETTER T WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;2C66; +023F;LATIN SMALL LETTER S WITH SWASH TAIL;Ll;0;L;;;;;N;;;2C7E;;2C7E +0240;LATIN SMALL LETTER Z WITH SWASH TAIL;Ll;0;L;;;;;N;;;2C7F;;2C7F +0241;LATIN CAPITAL LETTER GLOTTAL STOP;Lu;0;L;;;;;N;;;;0242; +0242;LATIN SMALL LETTER GLOTTAL STOP;Ll;0;L;;;;;N;;;0241;;0241 +0243;LATIN CAPITAL LETTER B WITH STROKE;Lu;0;L;;;;;N;;;;0180; +0244;LATIN CAPITAL LETTER U BAR;Lu;0;L;;;;;N;;;;0289; +0245;LATIN CAPITAL LETTER TURNED V;Lu;0;L;;;;;N;;;;028C; +0246;LATIN CAPITAL LETTER E WITH STROKE;Lu;0;L;;;;;N;;;;0247; +0247;LATIN SMALL LETTER E WITH STROKE;Ll;0;L;;;;;N;;;0246;;0246 +0248;LATIN CAPITAL LETTER J WITH STROKE;Lu;0;L;;;;;N;;;;0249; +0249;LATIN SMALL LETTER J WITH STROKE;Ll;0;L;;;;;N;;;0248;;0248 +024A;LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL;Lu;0;L;;;;;N;;;;024B; +024B;LATIN SMALL LETTER Q WITH HOOK TAIL;Ll;0;L;;;;;N;;;024A;;024A +024C;LATIN CAPITAL LETTER R WITH STROKE;Lu;0;L;;;;;N;;;;024D; +024D;LATIN SMALL LETTER R WITH STROKE;Ll;0;L;;;;;N;;;024C;;024C +024E;LATIN CAPITAL LETTER Y WITH STROKE;Lu;0;L;;;;;N;;;;024F; +024F;LATIN SMALL LETTER Y WITH STROKE;Ll;0;L;;;;;N;;;024E;;024E +0250;LATIN SMALL LETTER TURNED A;Ll;0;L;;;;;N;;;2C6F;;2C6F +0251;LATIN SMALL LETTER ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT A;;2C6D;;2C6D +0252;LATIN SMALL LETTER TURNED ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED SCRIPT A;;2C70;;2C70 +0253;LATIN SMALL LETTER B WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER B HOOK;;0181;;0181 +0254;LATIN SMALL LETTER OPEN O;Ll;0;L;;;;;N;;;0186;;0186 +0255;LATIN SMALL LETTER C WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER C CURL;;;; +0256;LATIN SMALL LETTER D WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER D RETROFLEX HOOK;;0189;;0189 +0257;LATIN SMALL LETTER D WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER D HOOK;;018A;;018A +0258;LATIN SMALL LETTER REVERSED E;Ll;0;L;;;;;N;;;;; +0259;LATIN SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;018F;;018F +025A;LATIN SMALL LETTER SCHWA WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCHWA HOOK;;;; +025B;LATIN SMALL LETTER OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER EPSILON;;0190;;0190 +025C;LATIN SMALL LETTER REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON;;A7AB;;A7AB +025D;LATIN SMALL LETTER REVERSED OPEN E WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON HOOK;;;; +025E;LATIN SMALL LETTER CLOSED REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED REVERSED EPSILON;;;; +025F;LATIN SMALL LETTER DOTLESS J WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR;;;; +0260;LATIN SMALL LETTER G WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER G HOOK;;0193;;0193 +0261;LATIN SMALL LETTER SCRIPT G;Ll;0;L;;;;;N;;;A7AC;;A7AC +0262;LATIN LETTER SMALL CAPITAL G;Ll;0;L;;;;;N;;;;; +0263;LATIN SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0194;;0194 +0264;LATIN SMALL LETTER RAMS HORN;Ll;0;L;;;;;N;LATIN SMALL LETTER BABY GAMMA;;;; +0265;LATIN SMALL LETTER TURNED H;Ll;0;L;;;;;N;;;A78D;;A78D +0266;LATIN SMALL LETTER H WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER H HOOK;;A7AA;;A7AA +0267;LATIN SMALL LETTER HENG WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER HENG HOOK;;;; +0268;LATIN SMALL LETTER I WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED I;;0197;;0197 +0269;LATIN SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0196;;0196 +026A;LATIN LETTER SMALL CAPITAL I;Ll;0;L;;;;;N;;;A7AE;;A7AE +026B;LATIN SMALL LETTER L WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;2C62;;2C62 +026C;LATIN SMALL LETTER L WITH BELT;Ll;0;L;;;;;N;LATIN SMALL LETTER L BELT;;A7AD;;A7AD +026D;LATIN SMALL LETTER L WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER L RETROFLEX HOOK;;;; +026E;LATIN SMALL LETTER LEZH;Ll;0;L;;;;;N;LATIN SMALL LETTER L YOGH;;;; +026F;LATIN SMALL LETTER TURNED M;Ll;0;L;;;;;N;;;019C;;019C +0270;LATIN SMALL LETTER TURNED M WITH LONG LEG;Ll;0;L;;;;;N;;;;; +0271;LATIN SMALL LETTER M WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER M HOOK;;2C6E;;2C6E +0272;LATIN SMALL LETTER N WITH LEFT HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N HOOK;;019D;;019D +0273;LATIN SMALL LETTER N WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N RETROFLEX HOOK;;;; +0274;LATIN LETTER SMALL CAPITAL N;Ll;0;L;;;;;N;;;;; +0275;LATIN SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;019F;;019F +0276;LATIN LETTER SMALL CAPITAL OE;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL O E;;;; +0277;LATIN SMALL LETTER CLOSED OMEGA;Ll;0;L;;;;;N;;;;; +0278;LATIN SMALL LETTER PHI;Ll;0;L;;;;;N;;;;; +0279;LATIN SMALL LETTER TURNED R;Ll;0;L;;;;;N;;;;; +027A;LATIN SMALL LETTER TURNED R WITH LONG LEG;Ll;0;L;;;;;N;;;;; +027B;LATIN SMALL LETTER TURNED R WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED R HOOK;;;; +027C;LATIN SMALL LETTER R WITH LONG LEG;Ll;0;L;;;;;N;;;;; +027D;LATIN SMALL LETTER R WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER R HOOK;;2C64;;2C64 +027E;LATIN SMALL LETTER R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER FISHHOOK R;;;; +027F;LATIN SMALL LETTER REVERSED R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED FISHHOOK R;;;; +0280;LATIN LETTER SMALL CAPITAL R;Ll;0;L;;;;;N;;;01A6;;01A6 +0281;LATIN LETTER SMALL CAPITAL INVERTED R;Ll;0;L;;;;;N;;;;; +0282;LATIN SMALL LETTER S WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER S HOOK;;A7C5;;A7C5 +0283;LATIN SMALL LETTER ESH;Ll;0;L;;;;;N;;;01A9;;01A9 +0284;LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR HOOK;;;; +0285;LATIN SMALL LETTER SQUAT REVERSED ESH;Ll;0;L;;;;;N;;;;; +0286;LATIN SMALL LETTER ESH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER ESH CURL;;;; +0287;LATIN SMALL LETTER TURNED T;Ll;0;L;;;;;N;;;A7B1;;A7B1 +0288;LATIN SMALL LETTER T WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T RETROFLEX HOOK;;01AE;;01AE +0289;LATIN SMALL LETTER U BAR;Ll;0;L;;;;;N;;;0244;;0244 +028A;LATIN SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;01B1;;01B1 +028B;LATIN SMALL LETTER V WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT V;;01B2;;01B2 +028C;LATIN SMALL LETTER TURNED V;Ll;0;L;;;;;N;;;0245;;0245 +028D;LATIN SMALL LETTER TURNED W;Ll;0;L;;;;;N;;;;; +028E;LATIN SMALL LETTER TURNED Y;Ll;0;L;;;;;N;;;;; +028F;LATIN LETTER SMALL CAPITAL Y;Ll;0;L;;;;;N;;;;; +0290;LATIN SMALL LETTER Z WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Z RETROFLEX HOOK;;;; +0291;LATIN SMALL LETTER Z WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER Z CURL;;;; +0292;LATIN SMALL LETTER EZH;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH;;01B7;;01B7 +0293;LATIN SMALL LETTER EZH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH CURL;;;; +0294;LATIN LETTER GLOTTAL STOP;Lo;0;L;;;;;N;;;;; +0295;LATIN LETTER PHARYNGEAL VOICED FRICATIVE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP;;;; +0296;LATIN LETTER INVERTED GLOTTAL STOP;Ll;0;L;;;;;N;;;;; +0297;LATIN LETTER STRETCHED C;Ll;0;L;;;;;N;;;;; +0298;LATIN LETTER BILABIAL CLICK;Ll;0;L;;;;;N;LATIN LETTER BULLSEYE;;;; +0299;LATIN LETTER SMALL CAPITAL B;Ll;0;L;;;;;N;;;;; +029A;LATIN SMALL LETTER CLOSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED EPSILON;;;; +029B;LATIN LETTER SMALL CAPITAL G WITH HOOK;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL G HOOK;;;; +029C;LATIN LETTER SMALL CAPITAL H;Ll;0;L;;;;;N;;;;; +029D;LATIN SMALL LETTER J WITH CROSSED-TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER CROSSED-TAIL J;;A7B2;;A7B2 +029E;LATIN SMALL LETTER TURNED K;Ll;0;L;;;;;N;;;A7B0;;A7B0 +029F;LATIN LETTER SMALL CAPITAL L;Ll;0;L;;;;;N;;;;; +02A0;LATIN SMALL LETTER Q WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Q HOOK;;;; +02A1;LATIN LETTER GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER GLOTTAL STOP BAR;;;; +02A2;LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP BAR;;;; +02A3;LATIN SMALL LETTER DZ DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z;;;; +02A4;LATIN SMALL LETTER DEZH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D YOGH;;;; +02A5;LATIN SMALL LETTER DZ DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z CURL;;;; +02A6;LATIN SMALL LETTER TS DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T S;;;; +02A7;LATIN SMALL LETTER TESH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T ESH;;;; +02A8;LATIN SMALL LETTER TC DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER T C CURL;;;; +02A9;LATIN SMALL LETTER FENG DIGRAPH;Ll;0;L;;;;;N;;;;; +02AA;LATIN SMALL LETTER LS DIGRAPH;Ll;0;L;;;;;N;;;;; +02AB;LATIN SMALL LETTER LZ DIGRAPH;Ll;0;L;;;;;N;;;;; +02AC;LATIN LETTER BILABIAL PERCUSSIVE;Ll;0;L;;;;;N;;;;; +02AD;LATIN LETTER BIDENTAL PERCUSSIVE;Ll;0;L;;;;;N;;;;; +02AE;LATIN SMALL LETTER TURNED H WITH FISHHOOK;Ll;0;L;;;;;N;;;;; +02AF;LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL;Ll;0;L;;;;;N;;;;; +02B0;MODIFIER LETTER SMALL H;Lm;0;L; 0068;;;;N;;;;; +02B1;MODIFIER LETTER SMALL H WITH HOOK;Lm;0;L; 0266;;;;N;MODIFIER LETTER SMALL H HOOK;;;; +02B2;MODIFIER LETTER SMALL J;Lm;0;L; 006A;;;;N;;;;; +02B3;MODIFIER LETTER SMALL R;Lm;0;L; 0072;;;;N;;;;; +02B4;MODIFIER LETTER SMALL TURNED R;Lm;0;L; 0279;;;;N;;;;; +02B5;MODIFIER LETTER SMALL TURNED R WITH HOOK;Lm;0;L; 027B;;;;N;MODIFIER LETTER SMALL TURNED R HOOK;;;; +02B6;MODIFIER LETTER SMALL CAPITAL INVERTED R;Lm;0;L; 0281;;;;N;;;;; +02B7;MODIFIER LETTER SMALL W;Lm;0;L; 0077;;;;N;;;;; +02B8;MODIFIER LETTER SMALL Y;Lm;0;L; 0079;;;;N;;;;; +02B9;MODIFIER LETTER PRIME;Lm;0;ON;;;;;N;;;;; +02BA;MODIFIER LETTER DOUBLE PRIME;Lm;0;ON;;;;;N;;;;; +02BB;MODIFIER LETTER TURNED COMMA;Lm;0;L;;;;;N;;;;; +02BC;MODIFIER LETTER APOSTROPHE;Lm;0;L;;;;;N;;;;; +02BD;MODIFIER LETTER REVERSED COMMA;Lm;0;L;;;;;N;;;;; +02BE;MODIFIER LETTER RIGHT HALF RING;Lm;0;L;;;;;N;;;;; +02BF;MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;; +02C0;MODIFIER LETTER GLOTTAL STOP;Lm;0;L;;;;;N;;;;; +02C1;MODIFIER LETTER REVERSED GLOTTAL STOP;Lm;0;L;;;;;N;;;;; +02C2;MODIFIER LETTER LEFT ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02C3;MODIFIER LETTER RIGHT ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02C4;MODIFIER LETTER UP ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02C5;MODIFIER LETTER DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02C6;MODIFIER LETTER CIRCUMFLEX ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER CIRCUMFLEX;;;; +02C7;CARON;Lm;0;ON;;;;;N;MODIFIER LETTER HACEK;;;; +02C8;MODIFIER LETTER VERTICAL LINE;Lm;0;ON;;;;;N;;;;; +02C9;MODIFIER LETTER MACRON;Lm;0;ON;;;;;N;;;;; +02CA;MODIFIER LETTER ACUTE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER ACUTE;;;; +02CB;MODIFIER LETTER GRAVE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER GRAVE;;;; +02CC;MODIFIER LETTER LOW VERTICAL LINE;Lm;0;ON;;;;;N;;;;; +02CD;MODIFIER LETTER LOW MACRON;Lm;0;ON;;;;;N;;;;; +02CE;MODIFIER LETTER LOW GRAVE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER LOW GRAVE;;;; +02CF;MODIFIER LETTER LOW ACUTE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER LOW ACUTE;;;; +02D0;MODIFIER LETTER TRIANGULAR COLON;Lm;0;L;;;;;N;;;;; +02D1;MODIFIER LETTER HALF TRIANGULAR COLON;Lm;0;L;;;;;N;;;;; +02D2;MODIFIER LETTER CENTRED RIGHT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED RIGHT HALF RING;;;; +02D3;MODIFIER LETTER CENTRED LEFT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED LEFT HALF RING;;;; +02D4;MODIFIER LETTER UP TACK;Sk;0;ON;;;;;N;;;;; +02D5;MODIFIER LETTER DOWN TACK;Sk;0;ON;;;;;N;;;;; +02D6;MODIFIER LETTER PLUS SIGN;Sk;0;ON;;;;;N;;;;; +02D7;MODIFIER LETTER MINUS SIGN;Sk;0;ON;;;;;N;;;;; +02D8;BREVE;Sk;0;ON; 0020 0306;;;;N;SPACING BREVE;;;; +02D9;DOT ABOVE;Sk;0;ON; 0020 0307;;;;N;SPACING DOT ABOVE;;;; +02DA;RING ABOVE;Sk;0;ON; 0020 030A;;;;N;SPACING RING ABOVE;;;; +02DB;OGONEK;Sk;0;ON; 0020 0328;;;;N;SPACING OGONEK;;;; +02DC;SMALL TILDE;Sk;0;ON; 0020 0303;;;;N;SPACING TILDE;;;; +02DD;DOUBLE ACUTE ACCENT;Sk;0;ON; 0020 030B;;;;N;SPACING DOUBLE ACUTE;;;; +02DE;MODIFIER LETTER RHOTIC HOOK;Sk;0;ON;;;;;N;;;;; +02DF;MODIFIER LETTER CROSS ACCENT;Sk;0;ON;;;;;N;;;;; +02E0;MODIFIER LETTER SMALL GAMMA;Lm;0;L; 0263;;;;N;;;;; +02E1;MODIFIER LETTER SMALL L;Lm;0;L; 006C;;;;N;;;;; +02E2;MODIFIER LETTER SMALL S;Lm;0;L; 0073;;;;N;;;;; +02E3;MODIFIER LETTER SMALL X;Lm;0;L; 0078;;;;N;;;;; +02E4;MODIFIER LETTER SMALL REVERSED GLOTTAL STOP;Lm;0;L; 0295;;;;N;;;;; +02E5;MODIFIER LETTER EXTRA-HIGH TONE BAR;Sk;0;ON;;;;;N;;;;; +02E6;MODIFIER LETTER HIGH TONE BAR;Sk;0;ON;;;;;N;;;;; +02E7;MODIFIER LETTER MID TONE BAR;Sk;0;ON;;;;;N;;;;; +02E8;MODIFIER LETTER LOW TONE BAR;Sk;0;ON;;;;;N;;;;; +02E9;MODIFIER LETTER EXTRA-LOW TONE BAR;Sk;0;ON;;;;;N;;;;; +02EA;MODIFIER LETTER YIN DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;; +02EB;MODIFIER LETTER YANG DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;; +02EC;MODIFIER LETTER VOICING;Lm;0;ON;;;;;N;;;;; +02ED;MODIFIER LETTER UNASPIRATED;Sk;0;ON;;;;;N;;;;; +02EE;MODIFIER LETTER DOUBLE APOSTROPHE;Lm;0;L;;;;;N;;;;; +02EF;MODIFIER LETTER LOW DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02F0;MODIFIER LETTER LOW UP ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02F1;MODIFIER LETTER LOW LEFT ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02F2;MODIFIER LETTER LOW RIGHT ARROWHEAD;Sk;0;ON;;;;;N;;;;; +02F3;MODIFIER LETTER LOW RING;Sk;0;ON;;;;;N;;;;; +02F4;MODIFIER LETTER MIDDLE GRAVE ACCENT;Sk;0;ON;;;;;N;;;;; +02F5;MODIFIER LETTER MIDDLE DOUBLE GRAVE ACCENT;Sk;0;ON;;;;;N;;;;; +02F6;MODIFIER LETTER MIDDLE DOUBLE ACUTE ACCENT;Sk;0;ON;;;;;N;;;;; +02F7;MODIFIER LETTER LOW TILDE;Sk;0;ON;;;;;N;;;;; +02F8;MODIFIER LETTER RAISED COLON;Sk;0;ON;;;;;N;;;;; +02F9;MODIFIER LETTER BEGIN HIGH TONE;Sk;0;ON;;;;;N;;;;; +02FA;MODIFIER LETTER END HIGH TONE;Sk;0;ON;;;;;N;;;;; +02FB;MODIFIER LETTER BEGIN LOW TONE;Sk;0;ON;;;;;N;;;;; +02FC;MODIFIER LETTER END LOW TONE;Sk;0;ON;;;;;N;;;;; +02FD;MODIFIER LETTER SHELF;Sk;0;ON;;;;;N;;;;; +02FE;MODIFIER LETTER OPEN SHELF;Sk;0;ON;;;;;N;;;;; +02FF;MODIFIER LETTER LOW LEFT ARROW;Sk;0;ON;;;;;N;;;;; +0300;COMBINING GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING GRAVE;;;; +0301;COMBINING ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING ACUTE;;;; +0302;COMBINING CIRCUMFLEX ACCENT;Mn;230;NSM;;;;;N;NON-SPACING CIRCUMFLEX;;;; +0303;COMBINING TILDE;Mn;230;NSM;;;;;N;NON-SPACING TILDE;;;; +0304;COMBINING MACRON;Mn;230;NSM;;;;;N;NON-SPACING MACRON;;;; +0305;COMBINING OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING OVERSCORE;;;; +0306;COMBINING BREVE;Mn;230;NSM;;;;;N;NON-SPACING BREVE;;;; +0307;COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOT ABOVE;;;; +0308;COMBINING DIAERESIS;Mn;230;NSM;;;;;N;NON-SPACING DIAERESIS;;;; +0309;COMBINING HOOK ABOVE;Mn;230;NSM;;;;;N;NON-SPACING HOOK ABOVE;;;; +030A;COMBINING RING ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RING ABOVE;;;; +030B;COMBINING DOUBLE ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE ACUTE;;;; +030C;COMBINING CARON;Mn;230;NSM;;;;;N;NON-SPACING HACEK;;;; +030D;COMBINING VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL LINE ABOVE;;;; +030E;COMBINING DOUBLE VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE VERTICAL LINE ABOVE;;;; +030F;COMBINING DOUBLE GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE GRAVE;;;; +0310;COMBINING CANDRABINDU;Mn;230;NSM;;;;;N;NON-SPACING CANDRABINDU;;;; +0311;COMBINING INVERTED BREVE;Mn;230;NSM;;;;;N;NON-SPACING INVERTED BREVE;;;; +0312;COMBINING TURNED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING TURNED COMMA ABOVE;;;; +0313;COMBINING COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING COMMA ABOVE;;;; +0314;COMBINING REVERSED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING REVERSED COMMA ABOVE;;;; +0315;COMBINING COMMA ABOVE RIGHT;Mn;232;NSM;;;;;N;NON-SPACING COMMA ABOVE RIGHT;;;; +0316;COMBINING GRAVE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING GRAVE BELOW;;;; +0317;COMBINING ACUTE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING ACUTE BELOW;;;; +0318;COMBINING LEFT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT TACK BELOW;;;; +0319;COMBINING RIGHT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT TACK BELOW;;;; +031A;COMBINING LEFT ANGLE ABOVE;Mn;232;NSM;;;;;N;NON-SPACING LEFT ANGLE ABOVE;;;; +031B;COMBINING HORN;Mn;216;NSM;;;;;N;NON-SPACING HORN;;;; +031C;COMBINING LEFT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT HALF RING BELOW;;;; +031D;COMBINING UP TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING UP TACK BELOW;;;; +031E;COMBINING DOWN TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOWN TACK BELOW;;;; +031F;COMBINING PLUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING PLUS SIGN BELOW;;;; +0320;COMBINING MINUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING MINUS SIGN BELOW;;;; +0321;COMBINING PALATALIZED HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING PALATALIZED HOOK BELOW;;;; +0322;COMBINING RETROFLEX HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING RETROFLEX HOOK BELOW;;;; +0323;COMBINING DOT BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOT BELOW;;;; +0324;COMBINING DIAERESIS BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE DOT BELOW;;;; +0325;COMBINING RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RING BELOW;;;; +0326;COMBINING COMMA BELOW;Mn;220;NSM;;;;;N;NON-SPACING COMMA BELOW;;;; +0327;COMBINING CEDILLA;Mn;202;NSM;;;;;N;NON-SPACING CEDILLA;;;; +0328;COMBINING OGONEK;Mn;202;NSM;;;;;N;NON-SPACING OGONEK;;;; +0329;COMBINING VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;NON-SPACING VERTICAL LINE BELOW;;;; +032A;COMBINING BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BRIDGE BELOW;;;; +032B;COMBINING INVERTED DOUBLE ARCH BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED DOUBLE ARCH BELOW;;;; +032C;COMBINING CARON BELOW;Mn;220;NSM;;;;;N;NON-SPACING HACEK BELOW;;;; +032D;COMBINING CIRCUMFLEX ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING CIRCUMFLEX BELOW;;;; +032E;COMBINING BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BREVE BELOW;;;; +032F;COMBINING INVERTED BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BREVE BELOW;;;; +0330;COMBINING TILDE BELOW;Mn;220;NSM;;;;;N;NON-SPACING TILDE BELOW;;;; +0331;COMBINING MACRON BELOW;Mn;220;NSM;;;;;N;NON-SPACING MACRON BELOW;;;; +0332;COMBINING LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING UNDERSCORE;;;; +0333;COMBINING DOUBLE LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE UNDERSCORE;;;; +0334;COMBINING TILDE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING TILDE OVERLAY;;;; +0335;COMBINING SHORT STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT BAR OVERLAY;;;; +0336;COMBINING LONG STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG BAR OVERLAY;;;; +0337;COMBINING SHORT SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT SLASH OVERLAY;;;; +0338;COMBINING LONG SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG SLASH OVERLAY;;;; +0339;COMBINING RIGHT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT HALF RING BELOW;;;; +033A;COMBINING INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BRIDGE BELOW;;;; +033B;COMBINING SQUARE BELOW;Mn;220;NSM;;;;;N;NON-SPACING SQUARE BELOW;;;; +033C;COMBINING SEAGULL BELOW;Mn;220;NSM;;;;;N;NON-SPACING SEAGULL BELOW;;;; +033D;COMBINING X ABOVE;Mn;230;NSM;;;;;N;NON-SPACING X ABOVE;;;; +033E;COMBINING VERTICAL TILDE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL TILDE;;;; +033F;COMBINING DOUBLE OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE OVERSCORE;;;; +0340;COMBINING GRAVE TONE MARK;Mn;230;NSM;0300;;;;N;NON-SPACING GRAVE TONE MARK;;;; +0341;COMBINING ACUTE TONE MARK;Mn;230;NSM;0301;;;;N;NON-SPACING ACUTE TONE MARK;;;; +0342;COMBINING GREEK PERISPOMENI;Mn;230;NSM;;;;;N;;;;; +0343;COMBINING GREEK KORONIS;Mn;230;NSM;0313;;;;N;;;;; +0344;COMBINING GREEK DIALYTIKA TONOS;Mn;230;NSM;0308 0301;;;;N;GREEK NON-SPACING DIAERESIS TONOS;;;; +0345;COMBINING GREEK YPOGEGRAMMENI;Mn;240;NSM;;;;;N;GREEK NON-SPACING IOTA BELOW;;0399;;0399 +0346;COMBINING BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;; +0347;COMBINING EQUALS SIGN BELOW;Mn;220;NSM;;;;;N;;;;; +0348;COMBINING DOUBLE VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;;;;; +0349;COMBINING LEFT ANGLE BELOW;Mn;220;NSM;;;;;N;;;;; +034A;COMBINING NOT TILDE ABOVE;Mn;230;NSM;;;;;N;;;;; +034B;COMBINING HOMOTHETIC ABOVE;Mn;230;NSM;;;;;N;;;;; +034C;COMBINING ALMOST EQUAL TO ABOVE;Mn;230;NSM;;;;;N;;;;; +034D;COMBINING LEFT RIGHT ARROW BELOW;Mn;220;NSM;;;;;N;;;;; +034E;COMBINING UPWARDS ARROW BELOW;Mn;220;NSM;;;;;N;;;;; +034F;COMBINING GRAPHEME JOINER;Mn;0;NSM;;;;;N;;;;; +0350;COMBINING RIGHT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;; +0351;COMBINING LEFT HALF RING ABOVE;Mn;230;NSM;;;;;N;;;;; +0352;COMBINING FERMATA;Mn;230;NSM;;;;;N;;;;; +0353;COMBINING X BELOW;Mn;220;NSM;;;;;N;;;;; +0354;COMBINING LEFT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;; +0355;COMBINING RIGHT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;; +0356;COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;; +0357;COMBINING RIGHT HALF RING ABOVE;Mn;230;NSM;;;;;N;;;;; +0358;COMBINING DOT ABOVE RIGHT;Mn;232;NSM;;;;;N;;;;; +0359;COMBINING ASTERISK BELOW;Mn;220;NSM;;;;;N;;;;; +035A;COMBINING DOUBLE RING BELOW;Mn;220;NSM;;;;;N;;;;; +035B;COMBINING ZIGZAG ABOVE;Mn;230;NSM;;;;;N;;;;; +035C;COMBINING DOUBLE BREVE BELOW;Mn;233;NSM;;;;;N;;;;; +035D;COMBINING DOUBLE BREVE;Mn;234;NSM;;;;;N;;;;; +035E;COMBINING DOUBLE MACRON;Mn;234;NSM;;;;;N;;;;; +035F;COMBINING DOUBLE MACRON BELOW;Mn;233;NSM;;;;;N;;;;; +0360;COMBINING DOUBLE TILDE;Mn;234;NSM;;;;;N;;;;; +0361;COMBINING DOUBLE INVERTED BREVE;Mn;234;NSM;;;;;N;;;;; +0362;COMBINING DOUBLE RIGHTWARDS ARROW BELOW;Mn;233;NSM;;;;;N;;;;; +0363;COMBINING LATIN SMALL LETTER A;Mn;230;NSM;;;;;N;;;;; +0364;COMBINING LATIN SMALL LETTER E;Mn;230;NSM;;;;;N;;;;; +0365;COMBINING LATIN SMALL LETTER I;Mn;230;NSM;;;;;N;;;;; +0366;COMBINING LATIN SMALL LETTER O;Mn;230;NSM;;;;;N;;;;; +0367;COMBINING LATIN SMALL LETTER U;Mn;230;NSM;;;;;N;;;;; +0368;COMBINING LATIN SMALL LETTER C;Mn;230;NSM;;;;;N;;;;; +0369;COMBINING LATIN SMALL LETTER D;Mn;230;NSM;;;;;N;;;;; +036A;COMBINING LATIN SMALL LETTER H;Mn;230;NSM;;;;;N;;;;; +036B;COMBINING LATIN SMALL LETTER M;Mn;230;NSM;;;;;N;;;;; +036C;COMBINING LATIN SMALL LETTER R;Mn;230;NSM;;;;;N;;;;; +036D;COMBINING LATIN SMALL LETTER T;Mn;230;NSM;;;;;N;;;;; +036E;COMBINING LATIN SMALL LETTER V;Mn;230;NSM;;;;;N;;;;; +036F;COMBINING LATIN SMALL LETTER X;Mn;230;NSM;;;;;N;;;;; +0370;GREEK CAPITAL LETTER HETA;Lu;0;L;;;;;N;;;;0371; +0371;GREEK SMALL LETTER HETA;Ll;0;L;;;;;N;;;0370;;0370 +0372;GREEK CAPITAL LETTER ARCHAIC SAMPI;Lu;0;L;;;;;N;;;;0373; +0373;GREEK SMALL LETTER ARCHAIC SAMPI;Ll;0;L;;;;;N;;;0372;;0372 +0374;GREEK NUMERAL SIGN;Lm;0;ON;02B9;;;;N;GREEK UPPER NUMERAL SIGN;;;; +0375;GREEK LOWER NUMERAL SIGN;Sk;0;ON;;;;;N;;;;; +0376;GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA;Lu;0;L;;;;;N;;;;0377; +0377;GREEK SMALL LETTER PAMPHYLIAN DIGAMMA;Ll;0;L;;;;;N;;;0376;;0376 +037A;GREEK YPOGEGRAMMENI;Lm;0;L; 0020 0345;;;;N;GREEK SPACING IOTA BELOW;;;; +037B;GREEK SMALL REVERSED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FD;;03FD +037C;GREEK SMALL DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FE;;03FE +037D;GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FF;;03FF +037E;GREEK QUESTION MARK;Po;0;ON;003B;;;;N;;;;; +037F;GREEK CAPITAL LETTER YOT;Lu;0;L;;;;;N;;;;03F3; +0384;GREEK TONOS;Sk;0;ON; 0020 0301;;;;N;GREEK SPACING TONOS;;;; +0385;GREEK DIALYTIKA TONOS;Sk;0;ON;00A8 0301;;;;N;GREEK SPACING DIAERESIS TONOS;;;; +0386;GREEK CAPITAL LETTER ALPHA WITH TONOS;Lu;0;L;0391 0301;;;;N;GREEK CAPITAL LETTER ALPHA TONOS;;;03AC; +0387;GREEK ANO TELEIA;Po;0;ON;00B7;;;;N;;;;; +0388;GREEK CAPITAL LETTER EPSILON WITH TONOS;Lu;0;L;0395 0301;;;;N;GREEK CAPITAL LETTER EPSILON TONOS;;;03AD; +0389;GREEK CAPITAL LETTER ETA WITH TONOS;Lu;0;L;0397 0301;;;;N;GREEK CAPITAL LETTER ETA TONOS;;;03AE; +038A;GREEK CAPITAL LETTER IOTA WITH TONOS;Lu;0;L;0399 0301;;;;N;GREEK CAPITAL LETTER IOTA TONOS;;;03AF; +038C;GREEK CAPITAL LETTER OMICRON WITH TONOS;Lu;0;L;039F 0301;;;;N;GREEK CAPITAL LETTER OMICRON TONOS;;;03CC; +038E;GREEK CAPITAL LETTER UPSILON WITH TONOS;Lu;0;L;03A5 0301;;;;N;GREEK CAPITAL LETTER UPSILON TONOS;;;03CD; +038F;GREEK CAPITAL LETTER OMEGA WITH TONOS;Lu;0;L;03A9 0301;;;;N;GREEK CAPITAL LETTER OMEGA TONOS;;;03CE; +0390;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS;Ll;0;L;03CA 0301;;;;N;GREEK SMALL LETTER IOTA DIAERESIS TONOS;;;; +0391;GREEK CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;03B1; +0392;GREEK CAPITAL LETTER BETA;Lu;0;L;;;;;N;;;;03B2; +0393;GREEK CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;03B3; +0394;GREEK CAPITAL LETTER DELTA;Lu;0;L;;;;;N;;;;03B4; +0395;GREEK CAPITAL LETTER EPSILON;Lu;0;L;;;;;N;;;;03B5; +0396;GREEK CAPITAL LETTER ZETA;Lu;0;L;;;;;N;;;;03B6; +0397;GREEK CAPITAL LETTER ETA;Lu;0;L;;;;;N;;;;03B7; +0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8; +0399;GREEK CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;03B9; +039A;GREEK CAPITAL LETTER KAPPA;Lu;0;L;;;;;N;;;;03BA; +039B;GREEK CAPITAL LETTER LAMDA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER LAMBDA;;;03BB; +039C;GREEK CAPITAL LETTER MU;Lu;0;L;;;;;N;;;;03BC; +039D;GREEK CAPITAL LETTER NU;Lu;0;L;;;;;N;;;;03BD; +039E;GREEK CAPITAL LETTER XI;Lu;0;L;;;;;N;;;;03BE; +039F;GREEK CAPITAL LETTER OMICRON;Lu;0;L;;;;;N;;;;03BF; +03A0;GREEK CAPITAL LETTER PI;Lu;0;L;;;;;N;;;;03C0; +03A1;GREEK CAPITAL LETTER RHO;Lu;0;L;;;;;N;;;;03C1; +03A3;GREEK CAPITAL LETTER SIGMA;Lu;0;L;;;;;N;;;;03C3; +03A4;GREEK CAPITAL LETTER TAU;Lu;0;L;;;;;N;;;;03C4; +03A5;GREEK CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;03C5; +03A6;GREEK CAPITAL LETTER PHI;Lu;0;L;;;;;N;;;;03C6; +03A7;GREEK CAPITAL LETTER CHI;Lu;0;L;;;;;N;;;;03C7; +03A8;GREEK CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;03C8; +03A9;GREEK CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;03C9; +03AA;GREEK CAPITAL LETTER IOTA WITH DIALYTIKA;Lu;0;L;0399 0308;;;;N;GREEK CAPITAL LETTER IOTA DIAERESIS;;;03CA; +03AB;GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA;Lu;0;L;03A5 0308;;;;N;GREEK CAPITAL LETTER UPSILON DIAERESIS;;;03CB; +03AC;GREEK SMALL LETTER ALPHA WITH TONOS;Ll;0;L;03B1 0301;;;;N;GREEK SMALL LETTER ALPHA TONOS;;0386;;0386 +03AD;GREEK SMALL LETTER EPSILON WITH TONOS;Ll;0;L;03B5 0301;;;;N;GREEK SMALL LETTER EPSILON TONOS;;0388;;0388 +03AE;GREEK SMALL LETTER ETA WITH TONOS;Ll;0;L;03B7 0301;;;;N;GREEK SMALL LETTER ETA TONOS;;0389;;0389 +03AF;GREEK SMALL LETTER IOTA WITH TONOS;Ll;0;L;03B9 0301;;;;N;GREEK SMALL LETTER IOTA TONOS;;038A;;038A +03B0;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS;Ll;0;L;03CB 0301;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS TONOS;;;; +03B1;GREEK SMALL LETTER ALPHA;Ll;0;L;;;;;N;;;0391;;0391 +03B2;GREEK SMALL LETTER BETA;Ll;0;L;;;;;N;;;0392;;0392 +03B3;GREEK SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0393;;0393 +03B4;GREEK SMALL LETTER DELTA;Ll;0;L;;;;;N;;;0394;;0394 +03B5;GREEK SMALL LETTER EPSILON;Ll;0;L;;;;;N;;;0395;;0395 +03B6;GREEK SMALL LETTER ZETA;Ll;0;L;;;;;N;;;0396;;0396 +03B7;GREEK SMALL LETTER ETA;Ll;0;L;;;;;N;;;0397;;0397 +03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398 +03B9;GREEK SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0399;;0399 +03BA;GREEK SMALL LETTER KAPPA;Ll;0;L;;;;;N;;;039A;;039A +03BB;GREEK SMALL LETTER LAMDA;Ll;0;L;;;;;N;GREEK SMALL LETTER LAMBDA;;039B;;039B +03BC;GREEK SMALL LETTER MU;Ll;0;L;;;;;N;;;039C;;039C +03BD;GREEK SMALL LETTER NU;Ll;0;L;;;;;N;;;039D;;039D +03BE;GREEK SMALL LETTER XI;Ll;0;L;;;;;N;;;039E;;039E +03BF;GREEK SMALL LETTER OMICRON;Ll;0;L;;;;;N;;;039F;;039F +03C0;GREEK SMALL LETTER PI;Ll;0;L;;;;;N;;;03A0;;03A0 +03C1;GREEK SMALL LETTER RHO;Ll;0;L;;;;;N;;;03A1;;03A1 +03C2;GREEK SMALL LETTER FINAL SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3 +03C3;GREEK SMALL LETTER SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3 +03C4;GREEK SMALL LETTER TAU;Ll;0;L;;;;;N;;;03A4;;03A4 +03C5;GREEK SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;03A5;;03A5 +03C6;GREEK SMALL LETTER PHI;Ll;0;L;;;;;N;;;03A6;;03A6 +03C7;GREEK SMALL LETTER CHI;Ll;0;L;;;;;N;;;03A7;;03A7 +03C8;GREEK SMALL LETTER PSI;Ll;0;L;;;;;N;;;03A8;;03A8 +03C9;GREEK SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;03A9;;03A9 +03CA;GREEK SMALL LETTER IOTA WITH DIALYTIKA;Ll;0;L;03B9 0308;;;;N;GREEK SMALL LETTER IOTA DIAERESIS;;03AA;;03AA +03CB;GREEK SMALL LETTER UPSILON WITH DIALYTIKA;Ll;0;L;03C5 0308;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS;;03AB;;03AB +03CC;GREEK SMALL LETTER OMICRON WITH TONOS;Ll;0;L;03BF 0301;;;;N;GREEK SMALL LETTER OMICRON TONOS;;038C;;038C +03CD;GREEK SMALL LETTER UPSILON WITH TONOS;Ll;0;L;03C5 0301;;;;N;GREEK SMALL LETTER UPSILON TONOS;;038E;;038E +03CE;GREEK SMALL LETTER OMEGA WITH TONOS;Ll;0;L;03C9 0301;;;;N;GREEK SMALL LETTER OMEGA TONOS;;038F;;038F +03CF;GREEK CAPITAL KAI SYMBOL;Lu;0;L;;;;;N;;;;03D7; +03D0;GREEK BETA SYMBOL;Ll;0;L; 03B2;;;;N;GREEK SMALL LETTER CURLED BETA;;0392;;0392 +03D1;GREEK THETA SYMBOL;Ll;0;L; 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398 +03D2;GREEK UPSILON WITH HOOK SYMBOL;Lu;0;L; 03A5;;;;N;GREEK CAPITAL LETTER UPSILON HOOK;;;; +03D3;GREEK UPSILON WITH ACUTE AND HOOK SYMBOL;Lu;0;L;03D2 0301;;;;N;GREEK CAPITAL LETTER UPSILON HOOK TONOS;;;; +03D4;GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL;Lu;0;L;03D2 0308;;;;N;GREEK CAPITAL LETTER UPSILON HOOK DIAERESIS;;;; +03D5;GREEK PHI SYMBOL;Ll;0;L; 03C6;;;;N;GREEK SMALL LETTER SCRIPT PHI;;03A6;;03A6 +03D6;GREEK PI SYMBOL;Ll;0;L; 03C0;;;;N;GREEK SMALL LETTER OMEGA PI;;03A0;;03A0 +03D7;GREEK KAI SYMBOL;Ll;0;L;;;;;N;;;03CF;;03CF +03D8;GREEK LETTER ARCHAIC KOPPA;Lu;0;L;;;;;N;;;;03D9; +03D9;GREEK SMALL LETTER ARCHAIC KOPPA;Ll;0;L;;;;;N;;;03D8;;03D8 +03DA;GREEK LETTER STIGMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER STIGMA;;;03DB; +03DB;GREEK SMALL LETTER STIGMA;Ll;0;L;;;;;N;;;03DA;;03DA +03DC;GREEK LETTER DIGAMMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DIGAMMA;;;03DD; +03DD;GREEK SMALL LETTER DIGAMMA;Ll;0;L;;;;;N;;;03DC;;03DC +03DE;GREEK LETTER KOPPA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KOPPA;;;03DF; +03DF;GREEK SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;03DE;;03DE +03E0;GREEK LETTER SAMPI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SAMPI;;;03E1; +03E1;GREEK SMALL LETTER SAMPI;Ll;0;L;;;;;N;;;03E0;;03E0 +03E2;COPTIC CAPITAL LETTER SHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHEI;;;03E3; +03E3;COPTIC SMALL LETTER SHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER SHEI;;03E2;;03E2 +03E4;COPTIC CAPITAL LETTER FEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER FEI;;;03E5; +03E5;COPTIC SMALL LETTER FEI;Ll;0;L;;;;;N;GREEK SMALL LETTER FEI;;03E4;;03E4 +03E6;COPTIC CAPITAL LETTER KHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KHEI;;;03E7; +03E7;COPTIC SMALL LETTER KHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER KHEI;;03E6;;03E6 +03E8;COPTIC CAPITAL LETTER HORI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER HORI;;;03E9; +03E9;COPTIC SMALL LETTER HORI;Ll;0;L;;;;;N;GREEK SMALL LETTER HORI;;03E8;;03E8 +03EA;COPTIC CAPITAL LETTER GANGIA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER GANGIA;;;03EB; +03EB;COPTIC SMALL LETTER GANGIA;Ll;0;L;;;;;N;GREEK SMALL LETTER GANGIA;;03EA;;03EA +03EC;COPTIC CAPITAL LETTER SHIMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHIMA;;;03ED; +03ED;COPTIC SMALL LETTER SHIMA;Ll;0;L;;;;;N;GREEK SMALL LETTER SHIMA;;03EC;;03EC +03EE;COPTIC CAPITAL LETTER DEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DEI;;;03EF; +03EF;COPTIC SMALL LETTER DEI;Ll;0;L;;;;;N;GREEK SMALL LETTER DEI;;03EE;;03EE +03F0;GREEK KAPPA SYMBOL;Ll;0;L; 03BA;;;;N;GREEK SMALL LETTER SCRIPT KAPPA;;039A;;039A +03F1;GREEK RHO SYMBOL;Ll;0;L; 03C1;;;;N;GREEK SMALL LETTER TAILED RHO;;03A1;;03A1 +03F2;GREEK LUNATE SIGMA SYMBOL;Ll;0;L; 03C2;;;;N;GREEK SMALL LETTER LUNATE SIGMA;;03F9;;03F9 +03F3;GREEK LETTER YOT;Ll;0;L;;;;;N;;;037F;;037F +03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L; 0398;;;;N;;;;03B8; +03F5;GREEK LUNATE EPSILON SYMBOL;Ll;0;L; 03B5;;;;N;;;0395;;0395 +03F6;GREEK REVERSED LUNATE EPSILON SYMBOL;Sm;0;ON;;;;;N;;;;; +03F7;GREEK CAPITAL LETTER SHO;Lu;0;L;;;;;N;;;;03F8; +03F8;GREEK SMALL LETTER SHO;Ll;0;L;;;;;N;;;03F7;;03F7 +03F9;GREEK CAPITAL LUNATE SIGMA SYMBOL;Lu;0;L; 03A3;;;;N;;;;03F2; +03FA;GREEK CAPITAL LETTER SAN;Lu;0;L;;;;;N;;;;03FB; +03FB;GREEK SMALL LETTER SAN;Ll;0;L;;;;;N;;;03FA;;03FA +03FC;GREEK RHO WITH STROKE SYMBOL;Ll;0;L;;;;;N;;;;; +03FD;GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037B; +03FE;GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037C; +03FF;GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037D; +0400;CYRILLIC CAPITAL LETTER IE WITH GRAVE;Lu;0;L;0415 0300;;;;N;;;;0450; +0401;CYRILLIC CAPITAL LETTER IO;Lu;0;L;0415 0308;;;;N;;;;0451; +0402;CYRILLIC CAPITAL LETTER DJE;Lu;0;L;;;;;N;;;;0452; +0403;CYRILLIC CAPITAL LETTER GJE;Lu;0;L;0413 0301;;;;N;;;;0453; +0404;CYRILLIC CAPITAL LETTER UKRAINIAN IE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER E;;;0454; +0405;CYRILLIC CAPITAL LETTER DZE;Lu;0;L;;;;;N;;;;0455; +0406;CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER I;;;0456; +0407;CYRILLIC CAPITAL LETTER YI;Lu;0;L;0406 0308;;;;N;;;;0457; +0408;CYRILLIC CAPITAL LETTER JE;Lu;0;L;;;;;N;;;;0458; +0409;CYRILLIC CAPITAL LETTER LJE;Lu;0;L;;;;;N;;;;0459; +040A;CYRILLIC CAPITAL LETTER NJE;Lu;0;L;;;;;N;;;;045A; +040B;CYRILLIC CAPITAL LETTER TSHE;Lu;0;L;;;;;N;;;;045B; +040C;CYRILLIC CAPITAL LETTER KJE;Lu;0;L;041A 0301;;;;N;;;;045C; +040D;CYRILLIC CAPITAL LETTER I WITH GRAVE;Lu;0;L;0418 0300;;;;N;;;;045D; +040E;CYRILLIC CAPITAL LETTER SHORT U;Lu;0;L;0423 0306;;;;N;;;;045E; +040F;CYRILLIC CAPITAL LETTER DZHE;Lu;0;L;;;;;N;;;;045F; +0410;CYRILLIC CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0430; +0411;CYRILLIC CAPITAL LETTER BE;Lu;0;L;;;;;N;;;;0431; +0412;CYRILLIC CAPITAL LETTER VE;Lu;0;L;;;;;N;;;;0432; +0413;CYRILLIC CAPITAL LETTER GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE;;;0433; +0414;CYRILLIC CAPITAL LETTER DE;Lu;0;L;;;;;N;;;;0434; +0415;CYRILLIC CAPITAL LETTER IE;Lu;0;L;;;;;N;;;;0435; +0416;CYRILLIC CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;0436; +0417;CYRILLIC CAPITAL LETTER ZE;Lu;0;L;;;;;N;;;;0437; +0418;CYRILLIC CAPITAL LETTER I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER II;;;0438; +0419;CYRILLIC CAPITAL LETTER SHORT I;Lu;0;L;0418 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT II;;;0439; +041A;CYRILLIC CAPITAL LETTER KA;Lu;0;L;;;;;N;;;;043A; +041B;CYRILLIC CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;043B; +041C;CYRILLIC CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;043C; +041D;CYRILLIC CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;043D; +041E;CYRILLIC CAPITAL LETTER O;Lu;0;L;;;;;N;;;;043E; +041F;CYRILLIC CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;043F; +0420;CYRILLIC CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;0440; +0421;CYRILLIC CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;0441; +0422;CYRILLIC CAPITAL LETTER TE;Lu;0;L;;;;;N;;;;0442; +0423;CYRILLIC CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0443; +0424;CYRILLIC CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;0444; +0425;CYRILLIC CAPITAL LETTER HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA;;;0445; +0426;CYRILLIC CAPITAL LETTER TSE;Lu;0;L;;;;;N;;;;0446; +0427;CYRILLIC CAPITAL LETTER CHE;Lu;0;L;;;;;N;;;;0447; +0428;CYRILLIC CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0448; +0429;CYRILLIC CAPITAL LETTER SHCHA;Lu;0;L;;;;;N;;;;0449; +042A;CYRILLIC CAPITAL LETTER HARD SIGN;Lu;0;L;;;;;N;;;;044A; +042B;CYRILLIC CAPITAL LETTER YERU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER YERI;;;044B; +042C;CYRILLIC CAPITAL LETTER SOFT SIGN;Lu;0;L;;;;;N;;;;044C; +042D;CYRILLIC CAPITAL LETTER E;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED E;;;044D; +042E;CYRILLIC CAPITAL LETTER YU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IU;;;044E; +042F;CYRILLIC CAPITAL LETTER YA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IA;;;044F; +0430;CYRILLIC SMALL LETTER A;Ll;0;L;;;;;N;;;0410;;0410 +0431;CYRILLIC SMALL LETTER BE;Ll;0;L;;;;;N;;;0411;;0411 +0432;CYRILLIC SMALL LETTER VE;Ll;0;L;;;;;N;;;0412;;0412 +0433;CYRILLIC SMALL LETTER GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE;;0413;;0413 +0434;CYRILLIC SMALL LETTER DE;Ll;0;L;;;;;N;;;0414;;0414 +0435;CYRILLIC SMALL LETTER IE;Ll;0;L;;;;;N;;;0415;;0415 +0436;CYRILLIC SMALL LETTER ZHE;Ll;0;L;;;;;N;;;0416;;0416 +0437;CYRILLIC SMALL LETTER ZE;Ll;0;L;;;;;N;;;0417;;0417 +0438;CYRILLIC SMALL LETTER I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER II;;0418;;0418 +0439;CYRILLIC SMALL LETTER SHORT I;Ll;0;L;0438 0306;;;;N;CYRILLIC SMALL LETTER SHORT II;;0419;;0419 +043A;CYRILLIC SMALL LETTER KA;Ll;0;L;;;;;N;;;041A;;041A +043B;CYRILLIC SMALL LETTER EL;Ll;0;L;;;;;N;;;041B;;041B +043C;CYRILLIC SMALL LETTER EM;Ll;0;L;;;;;N;;;041C;;041C +043D;CYRILLIC SMALL LETTER EN;Ll;0;L;;;;;N;;;041D;;041D +043E;CYRILLIC SMALL LETTER O;Ll;0;L;;;;;N;;;041E;;041E +043F;CYRILLIC SMALL LETTER PE;Ll;0;L;;;;;N;;;041F;;041F +0440;CYRILLIC SMALL LETTER ER;Ll;0;L;;;;;N;;;0420;;0420 +0441;CYRILLIC SMALL LETTER ES;Ll;0;L;;;;;N;;;0421;;0421 +0442;CYRILLIC SMALL LETTER TE;Ll;0;L;;;;;N;;;0422;;0422 +0443;CYRILLIC SMALL LETTER U;Ll;0;L;;;;;N;;;0423;;0423 +0444;CYRILLIC SMALL LETTER EF;Ll;0;L;;;;;N;;;0424;;0424 +0445;CYRILLIC SMALL LETTER HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA;;0425;;0425 +0446;CYRILLIC SMALL LETTER TSE;Ll;0;L;;;;;N;;;0426;;0426 +0447;CYRILLIC SMALL LETTER CHE;Ll;0;L;;;;;N;;;0427;;0427 +0448;CYRILLIC SMALL LETTER SHA;Ll;0;L;;;;;N;;;0428;;0428 +0449;CYRILLIC SMALL LETTER SHCHA;Ll;0;L;;;;;N;;;0429;;0429 +044A;CYRILLIC SMALL LETTER HARD SIGN;Ll;0;L;;;;;N;;;042A;;042A +044B;CYRILLIC SMALL LETTER YERU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER YERI;;042B;;042B +044C;CYRILLIC SMALL LETTER SOFT SIGN;Ll;0;L;;;;;N;;;042C;;042C +044D;CYRILLIC SMALL LETTER E;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED E;;042D;;042D +044E;CYRILLIC SMALL LETTER YU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IU;;042E;;042E +044F;CYRILLIC SMALL LETTER YA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IA;;042F;;042F +0450;CYRILLIC SMALL LETTER IE WITH GRAVE;Ll;0;L;0435 0300;;;;N;;;0400;;0400 +0451;CYRILLIC SMALL LETTER IO;Ll;0;L;0435 0308;;;;N;;;0401;;0401 +0452;CYRILLIC SMALL LETTER DJE;Ll;0;L;;;;;N;;;0402;;0402 +0453;CYRILLIC SMALL LETTER GJE;Ll;0;L;0433 0301;;;;N;;;0403;;0403 +0454;CYRILLIC SMALL LETTER UKRAINIAN IE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER E;;0404;;0404 +0455;CYRILLIC SMALL LETTER DZE;Ll;0;L;;;;;N;;;0405;;0405 +0456;CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER I;;0406;;0406 +0457;CYRILLIC SMALL LETTER YI;Ll;0;L;0456 0308;;;;N;;;0407;;0407 +0458;CYRILLIC SMALL LETTER JE;Ll;0;L;;;;;N;;;0408;;0408 +0459;CYRILLIC SMALL LETTER LJE;Ll;0;L;;;;;N;;;0409;;0409 +045A;CYRILLIC SMALL LETTER NJE;Ll;0;L;;;;;N;;;040A;;040A +045B;CYRILLIC SMALL LETTER TSHE;Ll;0;L;;;;;N;;;040B;;040B +045C;CYRILLIC SMALL LETTER KJE;Ll;0;L;043A 0301;;;;N;;;040C;;040C +045D;CYRILLIC SMALL LETTER I WITH GRAVE;Ll;0;L;0438 0300;;;;N;;;040D;;040D +045E;CYRILLIC SMALL LETTER SHORT U;Ll;0;L;0443 0306;;;;N;;;040E;;040E +045F;CYRILLIC SMALL LETTER DZHE;Ll;0;L;;;;;N;;;040F;;040F +0460;CYRILLIC CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;0461; +0461;CYRILLIC SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;0460;;0460 +0462;CYRILLIC CAPITAL LETTER YAT;Lu;0;L;;;;;N;;;;0463; +0463;CYRILLIC SMALL LETTER YAT;Ll;0;L;;;;;N;;;0462;;0462 +0464;CYRILLIC CAPITAL LETTER IOTIFIED E;Lu;0;L;;;;;N;;;;0465; +0465;CYRILLIC SMALL LETTER IOTIFIED E;Ll;0;L;;;;;N;;;0464;;0464 +0466;CYRILLIC CAPITAL LETTER LITTLE YUS;Lu;0;L;;;;;N;;;;0467; +0467;CYRILLIC SMALL LETTER LITTLE YUS;Ll;0;L;;;;;N;;;0466;;0466 +0468;CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS;Lu;0;L;;;;;N;;;;0469; +0469;CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS;Ll;0;L;;;;;N;;;0468;;0468 +046A;CYRILLIC CAPITAL LETTER BIG YUS;Lu;0;L;;;;;N;;;;046B; +046B;CYRILLIC SMALL LETTER BIG YUS;Ll;0;L;;;;;N;;;046A;;046A +046C;CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS;Lu;0;L;;;;;N;;;;046D; +046D;CYRILLIC SMALL LETTER IOTIFIED BIG YUS;Ll;0;L;;;;;N;;;046C;;046C +046E;CYRILLIC CAPITAL LETTER KSI;Lu;0;L;;;;;N;;;;046F; +046F;CYRILLIC SMALL LETTER KSI;Ll;0;L;;;;;N;;;046E;;046E +0470;CYRILLIC CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;0471; +0471;CYRILLIC SMALL LETTER PSI;Ll;0;L;;;;;N;;;0470;;0470 +0472;CYRILLIC CAPITAL LETTER FITA;Lu;0;L;;;;;N;;;;0473; +0473;CYRILLIC SMALL LETTER FITA;Ll;0;L;;;;;N;;;0472;;0472 +0474;CYRILLIC CAPITAL LETTER IZHITSA;Lu;0;L;;;;;N;;;;0475; +0475;CYRILLIC SMALL LETTER IZHITSA;Ll;0;L;;;;;N;;;0474;;0474 +0476;CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Lu;0;L;0474 030F;;;;N;CYRILLIC CAPITAL LETTER IZHITSA DOUBLE GRAVE;;;0477; +0477;CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Ll;0;L;0475 030F;;;;N;CYRILLIC SMALL LETTER IZHITSA DOUBLE GRAVE;;0476;;0476 +0478;CYRILLIC CAPITAL LETTER UK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER UK DIGRAPH;;;0479; +0479;CYRILLIC SMALL LETTER UK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER UK DIGRAPH;;0478;;0478 +047A;CYRILLIC CAPITAL LETTER ROUND OMEGA;Lu;0;L;;;;;N;;;;047B; +047B;CYRILLIC SMALL LETTER ROUND OMEGA;Ll;0;L;;;;;N;;;047A;;047A +047C;CYRILLIC CAPITAL LETTER OMEGA WITH TITLO;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER OMEGA TITLO;;;047D; +047D;CYRILLIC SMALL LETTER OMEGA WITH TITLO;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER OMEGA TITLO;;047C;;047C +047E;CYRILLIC CAPITAL LETTER OT;Lu;0;L;;;;;N;;;;047F; +047F;CYRILLIC SMALL LETTER OT;Ll;0;L;;;;;N;;;047E;;047E +0480;CYRILLIC CAPITAL LETTER KOPPA;Lu;0;L;;;;;N;;;;0481; +0481;CYRILLIC SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;0480;;0480 +0482;CYRILLIC THOUSANDS SIGN;So;0;L;;;;;N;;;;; +0483;COMBINING CYRILLIC TITLO;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING TITLO;;;; +0484;COMBINING CYRILLIC PALATALIZATION;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PALATALIZATION;;;; +0485;COMBINING CYRILLIC DASIA PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING DASIA PNEUMATA;;;; +0486;COMBINING CYRILLIC PSILI PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PSILI PNEUMATA;;;; +0487;COMBINING CYRILLIC POKRYTIE;Mn;230;NSM;;;;;N;;;;; +0488;COMBINING CYRILLIC HUNDRED THOUSANDS SIGN;Me;0;NSM;;;;;N;;;;; +0489;COMBINING CYRILLIC MILLIONS SIGN;Me;0;NSM;;;;;N;;;;; +048A;CYRILLIC CAPITAL LETTER SHORT I WITH TAIL;Lu;0;L;;;;;N;;;;048B; +048B;CYRILLIC SMALL LETTER SHORT I WITH TAIL;Ll;0;L;;;;;N;;;048A;;048A +048C;CYRILLIC CAPITAL LETTER SEMISOFT SIGN;Lu;0;L;;;;;N;;;;048D; +048D;CYRILLIC SMALL LETTER SEMISOFT SIGN;Ll;0;L;;;;;N;;;048C;;048C +048E;CYRILLIC CAPITAL LETTER ER WITH TICK;Lu;0;L;;;;;N;;;;048F; +048F;CYRILLIC SMALL LETTER ER WITH TICK;Ll;0;L;;;;;N;;;048E;;048E +0490;CYRILLIC CAPITAL LETTER GHE WITH UPTURN;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE WITH UPTURN;;;0491; +0491;CYRILLIC SMALL LETTER GHE WITH UPTURN;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE WITH UPTURN;;0490;;0490 +0492;CYRILLIC CAPITAL LETTER GHE WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE BAR;;;0493; +0493;CYRILLIC SMALL LETTER GHE WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE BAR;;0492;;0492 +0494;CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE HOOK;;;0495; +0495;CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE HOOK;;0494;;0494 +0496;CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZHE WITH RIGHT DESCENDER;;;0497; +0497;CYRILLIC SMALL LETTER ZHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZHE WITH RIGHT DESCENDER;;0496;;0496 +0498;CYRILLIC CAPITAL LETTER ZE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZE CEDILLA;;;0499; +0499;CYRILLIC SMALL LETTER ZE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZE CEDILLA;;0498;;0498 +049A;CYRILLIC CAPITAL LETTER KA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA WITH RIGHT DESCENDER;;;049B; +049B;CYRILLIC SMALL LETTER KA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA WITH RIGHT DESCENDER;;049A;;049A +049C;CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA VERTICAL BAR;;;049D; +049D;CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA VERTICAL BAR;;049C;;049C +049E;CYRILLIC CAPITAL LETTER KA WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA BAR;;;049F; +049F;CYRILLIC SMALL LETTER KA WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA BAR;;049E;;049E +04A0;CYRILLIC CAPITAL LETTER BASHKIR KA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED GE KA;;;04A1; +04A1;CYRILLIC SMALL LETTER BASHKIR KA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED GE KA;;04A0;;04A0 +04A2;CYRILLIC CAPITAL LETTER EN WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN WITH RIGHT DESCENDER;;;04A3; +04A3;CYRILLIC SMALL LETTER EN WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN WITH RIGHT DESCENDER;;04A2;;04A2 +04A4;CYRILLIC CAPITAL LIGATURE EN GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN GE;;;04A5; +04A5;CYRILLIC SMALL LIGATURE EN GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN GE;;04A4;;04A4 +04A6;CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER PE HOOK;;;04A7; +04A7;CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER PE HOOK;;04A6;;04A6 +04A8;CYRILLIC CAPITAL LETTER ABKHASIAN HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER O HOOK;;;04A9; +04A9;CYRILLIC SMALL LETTER ABKHASIAN HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER O HOOK;;04A8;;04A8 +04AA;CYRILLIC CAPITAL LETTER ES WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ES CEDILLA;;;04AB; +04AB;CYRILLIC SMALL LETTER ES WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ES CEDILLA;;04AA;;04AA +04AC;CYRILLIC CAPITAL LETTER TE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE WITH RIGHT DESCENDER;;;04AD; +04AD;CYRILLIC SMALL LETTER TE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE WITH RIGHT DESCENDER;;04AC;;04AC +04AE;CYRILLIC CAPITAL LETTER STRAIGHT U;Lu;0;L;;;;;N;;;;04AF; +04AF;CYRILLIC SMALL LETTER STRAIGHT U;Ll;0;L;;;;;N;;;04AE;;04AE +04B0;CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER STRAIGHT U BAR;;;04B1; +04B1;CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER STRAIGHT U BAR;;04B0;;04B0 +04B2;CYRILLIC CAPITAL LETTER HA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA WITH RIGHT DESCENDER;;;04B3; +04B3;CYRILLIC SMALL LETTER HA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA WITH RIGHT DESCENDER;;04B2;;04B2 +04B4;CYRILLIC CAPITAL LIGATURE TE TSE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE TSE;;;04B5; +04B5;CYRILLIC SMALL LIGATURE TE TSE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE TSE;;04B4;;04B4 +04B6;CYRILLIC CAPITAL LETTER CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH RIGHT DESCENDER;;;04B7; +04B7;CYRILLIC SMALL LETTER CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH RIGHT DESCENDER;;04B6;;04B6 +04B8;CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE VERTICAL BAR;;;04B9; +04B9;CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE VERTICAL BAR;;04B8;;04B8 +04BA;CYRILLIC CAPITAL LETTER SHHA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER H;;;04BB; +04BB;CYRILLIC SMALL LETTER SHHA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER H;;04BA;;04BA +04BC;CYRILLIC CAPITAL LETTER ABKHASIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK;;;04BD; +04BD;CYRILLIC SMALL LETTER ABKHASIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK;;04BC;;04BC +04BE;CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK OGONEK;;;04BF; +04BF;CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK OGONEK;;04BE;;04BE +04C0;CYRILLIC LETTER PALOCHKA;Lu;0;L;;;;;N;CYRILLIC LETTER I;;;04CF; +04C1;CYRILLIC CAPITAL LETTER ZHE WITH BREVE;Lu;0;L;0416 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT ZHE;;;04C2; +04C2;CYRILLIC SMALL LETTER ZHE WITH BREVE;Ll;0;L;0436 0306;;;;N;CYRILLIC SMALL LETTER SHORT ZHE;;04C1;;04C1 +04C3;CYRILLIC CAPITAL LETTER KA WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA HOOK;;;04C4; +04C4;CYRILLIC SMALL LETTER KA WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA HOOK;;04C3;;04C3 +04C5;CYRILLIC CAPITAL LETTER EL WITH TAIL;Lu;0;L;;;;;N;;;;04C6; +04C6;CYRILLIC SMALL LETTER EL WITH TAIL;Ll;0;L;;;;;N;;;04C5;;04C5 +04C7;CYRILLIC CAPITAL LETTER EN WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN HOOK;;;04C8; +04C8;CYRILLIC SMALL LETTER EN WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN HOOK;;04C7;;04C7 +04C9;CYRILLIC CAPITAL LETTER EN WITH TAIL;Lu;0;L;;;;;N;;;;04CA; +04CA;CYRILLIC SMALL LETTER EN WITH TAIL;Ll;0;L;;;;;N;;;04C9;;04C9 +04CB;CYRILLIC CAPITAL LETTER KHAKASSIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH LEFT DESCENDER;;;04CC; +04CC;CYRILLIC SMALL LETTER KHAKASSIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH LEFT DESCENDER;;04CB;;04CB +04CD;CYRILLIC CAPITAL LETTER EM WITH TAIL;Lu;0;L;;;;;N;;;;04CE; +04CE;CYRILLIC SMALL LETTER EM WITH TAIL;Ll;0;L;;;;;N;;;04CD;;04CD +04CF;CYRILLIC SMALL LETTER PALOCHKA;Ll;0;L;;;;;N;;;04C0;;04C0 +04D0;CYRILLIC CAPITAL LETTER A WITH BREVE;Lu;0;L;0410 0306;;;;N;;;;04D1; +04D1;CYRILLIC SMALL LETTER A WITH BREVE;Ll;0;L;0430 0306;;;;N;;;04D0;;04D0 +04D2;CYRILLIC CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0410 0308;;;;N;;;;04D3; +04D3;CYRILLIC SMALL LETTER A WITH DIAERESIS;Ll;0;L;0430 0308;;;;N;;;04D2;;04D2 +04D4;CYRILLIC CAPITAL LIGATURE A IE;Lu;0;L;;;;;N;;;;04D5; +04D5;CYRILLIC SMALL LIGATURE A IE;Ll;0;L;;;;;N;;;04D4;;04D4 +04D6;CYRILLIC CAPITAL LETTER IE WITH BREVE;Lu;0;L;0415 0306;;;;N;;;;04D7; +04D7;CYRILLIC SMALL LETTER IE WITH BREVE;Ll;0;L;0435 0306;;;;N;;;04D6;;04D6 +04D8;CYRILLIC CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;04D9; +04D9;CYRILLIC SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;04D8;;04D8 +04DA;CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS;Lu;0;L;04D8 0308;;;;N;;;;04DB; +04DB;CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS;Ll;0;L;04D9 0308;;;;N;;;04DA;;04DA +04DC;CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS;Lu;0;L;0416 0308;;;;N;;;;04DD; +04DD;CYRILLIC SMALL LETTER ZHE WITH DIAERESIS;Ll;0;L;0436 0308;;;;N;;;04DC;;04DC +04DE;CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS;Lu;0;L;0417 0308;;;;N;;;;04DF; +04DF;CYRILLIC SMALL LETTER ZE WITH DIAERESIS;Ll;0;L;0437 0308;;;;N;;;04DE;;04DE +04E0;CYRILLIC CAPITAL LETTER ABKHASIAN DZE;Lu;0;L;;;;;N;;;;04E1; +04E1;CYRILLIC SMALL LETTER ABKHASIAN DZE;Ll;0;L;;;;;N;;;04E0;;04E0 +04E2;CYRILLIC CAPITAL LETTER I WITH MACRON;Lu;0;L;0418 0304;;;;N;;;;04E3; +04E3;CYRILLIC SMALL LETTER I WITH MACRON;Ll;0;L;0438 0304;;;;N;;;04E2;;04E2 +04E4;CYRILLIC CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0418 0308;;;;N;;;;04E5; +04E5;CYRILLIC SMALL LETTER I WITH DIAERESIS;Ll;0;L;0438 0308;;;;N;;;04E4;;04E4 +04E6;CYRILLIC CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;041E 0308;;;;N;;;;04E7; +04E7;CYRILLIC SMALL LETTER O WITH DIAERESIS;Ll;0;L;043E 0308;;;;N;;;04E6;;04E6 +04E8;CYRILLIC CAPITAL LETTER BARRED O;Lu;0;L;;;;;N;;;;04E9; +04E9;CYRILLIC SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;04E8;;04E8 +04EA;CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS;Lu;0;L;04E8 0308;;;;N;;;;04EB; +04EB;CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS;Ll;0;L;04E9 0308;;;;N;;;04EA;;04EA +04EC;CYRILLIC CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;042D 0308;;;;N;;;;04ED; +04ED;CYRILLIC SMALL LETTER E WITH DIAERESIS;Ll;0;L;044D 0308;;;;N;;;04EC;;04EC +04EE;CYRILLIC CAPITAL LETTER U WITH MACRON;Lu;0;L;0423 0304;;;;N;;;;04EF; +04EF;CYRILLIC SMALL LETTER U WITH MACRON;Ll;0;L;0443 0304;;;;N;;;04EE;;04EE +04F0;CYRILLIC CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0423 0308;;;;N;;;;04F1; +04F1;CYRILLIC SMALL LETTER U WITH DIAERESIS;Ll;0;L;0443 0308;;;;N;;;04F0;;04F0 +04F2;CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0423 030B;;;;N;;;;04F3; +04F3;CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0443 030B;;;;N;;;04F2;;04F2 +04F4;CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS;Lu;0;L;0427 0308;;;;N;;;;04F5; +04F5;CYRILLIC SMALL LETTER CHE WITH DIAERESIS;Ll;0;L;0447 0308;;;;N;;;04F4;;04F4 +04F6;CYRILLIC CAPITAL LETTER GHE WITH DESCENDER;Lu;0;L;;;;;N;;;;04F7; +04F7;CYRILLIC SMALL LETTER GHE WITH DESCENDER;Ll;0;L;;;;;N;;;04F6;;04F6 +04F8;CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS;Lu;0;L;042B 0308;;;;N;;;;04F9; +04F9;CYRILLIC SMALL LETTER YERU WITH DIAERESIS;Ll;0;L;044B 0308;;;;N;;;04F8;;04F8 +04FA;CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK;Lu;0;L;;;;;N;;;;04FB; +04FB;CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK;Ll;0;L;;;;;N;;;04FA;;04FA +04FC;CYRILLIC CAPITAL LETTER HA WITH HOOK;Lu;0;L;;;;;N;;;;04FD; +04FD;CYRILLIC SMALL LETTER HA WITH HOOK;Ll;0;L;;;;;N;;;04FC;;04FC +04FE;CYRILLIC CAPITAL LETTER HA WITH STROKE;Lu;0;L;;;;;N;;;;04FF; +04FF;CYRILLIC SMALL LETTER HA WITH STROKE;Ll;0;L;;;;;N;;;04FE;;04FE +0500;CYRILLIC CAPITAL LETTER KOMI DE;Lu;0;L;;;;;N;;;;0501; +0501;CYRILLIC SMALL LETTER KOMI DE;Ll;0;L;;;;;N;;;0500;;0500 +0502;CYRILLIC CAPITAL LETTER KOMI DJE;Lu;0;L;;;;;N;;;;0503; +0503;CYRILLIC SMALL LETTER KOMI DJE;Ll;0;L;;;;;N;;;0502;;0502 +0504;CYRILLIC CAPITAL LETTER KOMI ZJE;Lu;0;L;;;;;N;;;;0505; +0505;CYRILLIC SMALL LETTER KOMI ZJE;Ll;0;L;;;;;N;;;0504;;0504 +0506;CYRILLIC CAPITAL LETTER KOMI DZJE;Lu;0;L;;;;;N;;;;0507; +0507;CYRILLIC SMALL LETTER KOMI DZJE;Ll;0;L;;;;;N;;;0506;;0506 +0508;CYRILLIC CAPITAL LETTER KOMI LJE;Lu;0;L;;;;;N;;;;0509; +0509;CYRILLIC SMALL LETTER KOMI LJE;Ll;0;L;;;;;N;;;0508;;0508 +050A;CYRILLIC CAPITAL LETTER KOMI NJE;Lu;0;L;;;;;N;;;;050B; +050B;CYRILLIC SMALL LETTER KOMI NJE;Ll;0;L;;;;;N;;;050A;;050A +050C;CYRILLIC CAPITAL LETTER KOMI SJE;Lu;0;L;;;;;N;;;;050D; +050D;CYRILLIC SMALL LETTER KOMI SJE;Ll;0;L;;;;;N;;;050C;;050C +050E;CYRILLIC CAPITAL LETTER KOMI TJE;Lu;0;L;;;;;N;;;;050F; +050F;CYRILLIC SMALL LETTER KOMI TJE;Ll;0;L;;;;;N;;;050E;;050E +0510;CYRILLIC CAPITAL LETTER REVERSED ZE;Lu;0;L;;;;;N;;;;0511; +0511;CYRILLIC SMALL LETTER REVERSED ZE;Ll;0;L;;;;;N;;;0510;;0510 +0512;CYRILLIC CAPITAL LETTER EL WITH HOOK;Lu;0;L;;;;;N;;;;0513; +0513;CYRILLIC SMALL LETTER EL WITH HOOK;Ll;0;L;;;;;N;;;0512;;0512 +0514;CYRILLIC CAPITAL LETTER LHA;Lu;0;L;;;;;N;;;;0515; +0515;CYRILLIC SMALL LETTER LHA;Ll;0;L;;;;;N;;;0514;;0514 +0516;CYRILLIC CAPITAL LETTER RHA;Lu;0;L;;;;;N;;;;0517; +0517;CYRILLIC SMALL LETTER RHA;Ll;0;L;;;;;N;;;0516;;0516 +0518;CYRILLIC CAPITAL LETTER YAE;Lu;0;L;;;;;N;;;;0519; +0519;CYRILLIC SMALL LETTER YAE;Ll;0;L;;;;;N;;;0518;;0518 +051A;CYRILLIC CAPITAL LETTER QA;Lu;0;L;;;;;N;;;;051B; +051B;CYRILLIC SMALL LETTER QA;Ll;0;L;;;;;N;;;051A;;051A +051C;CYRILLIC CAPITAL LETTER WE;Lu;0;L;;;;;N;;;;051D; +051D;CYRILLIC SMALL LETTER WE;Ll;0;L;;;;;N;;;051C;;051C +051E;CYRILLIC CAPITAL LETTER ALEUT KA;Lu;0;L;;;;;N;;;;051F; +051F;CYRILLIC SMALL LETTER ALEUT KA;Ll;0;L;;;;;N;;;051E;;051E +0520;CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;0521; +0521;CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;0520;;0520 +0522;CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;0523; +0523;CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;0522;;0522 +0524;CYRILLIC CAPITAL LETTER PE WITH DESCENDER;Lu;0;L;;;;;N;;;;0525; +0525;CYRILLIC SMALL LETTER PE WITH DESCENDER;Ll;0;L;;;;;N;;;0524;;0524 +0526;CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER;Lu;0;L;;;;;N;;;;0527; +0527;CYRILLIC SMALL LETTER SHHA WITH DESCENDER;Ll;0;L;;;;;N;;;0526;;0526 +0528;CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK;Lu;0;L;;;;;N;;;;0529; +0529;CYRILLIC SMALL LETTER EN WITH LEFT HOOK;Ll;0;L;;;;;N;;;0528;;0528 +052A;CYRILLIC CAPITAL LETTER DZZHE;Lu;0;L;;;;;N;;;;052B; +052B;CYRILLIC SMALL LETTER DZZHE;Ll;0;L;;;;;N;;;052A;;052A +052C;CYRILLIC CAPITAL LETTER DCHE;Lu;0;L;;;;;N;;;;052D; +052D;CYRILLIC SMALL LETTER DCHE;Ll;0;L;;;;;N;;;052C;;052C +052E;CYRILLIC CAPITAL LETTER EL WITH DESCENDER;Lu;0;L;;;;;N;;;;052F; +052F;CYRILLIC SMALL LETTER EL WITH DESCENDER;Ll;0;L;;;;;N;;;052E;;052E +0531;ARMENIAN CAPITAL LETTER AYB;Lu;0;L;;;;;N;;;;0561; +0532;ARMENIAN CAPITAL LETTER BEN;Lu;0;L;;;;;N;;;;0562; +0533;ARMENIAN CAPITAL LETTER GIM;Lu;0;L;;;;;N;;;;0563; +0534;ARMENIAN CAPITAL LETTER DA;Lu;0;L;;;;;N;;;;0564; +0535;ARMENIAN CAPITAL LETTER ECH;Lu;0;L;;;;;N;;;;0565; +0536;ARMENIAN CAPITAL LETTER ZA;Lu;0;L;;;;;N;;;;0566; +0537;ARMENIAN CAPITAL LETTER EH;Lu;0;L;;;;;N;;;;0567; +0538;ARMENIAN CAPITAL LETTER ET;Lu;0;L;;;;;N;;;;0568; +0539;ARMENIAN CAPITAL LETTER TO;Lu;0;L;;;;;N;;;;0569; +053A;ARMENIAN CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;056A; +053B;ARMENIAN CAPITAL LETTER INI;Lu;0;L;;;;;N;;;;056B; +053C;ARMENIAN CAPITAL LETTER LIWN;Lu;0;L;;;;;N;;;;056C; +053D;ARMENIAN CAPITAL LETTER XEH;Lu;0;L;;;;;N;;;;056D; +053E;ARMENIAN CAPITAL LETTER CA;Lu;0;L;;;;;N;;;;056E; +053F;ARMENIAN CAPITAL LETTER KEN;Lu;0;L;;;;;N;;;;056F; +0540;ARMENIAN CAPITAL LETTER HO;Lu;0;L;;;;;N;;;;0570; +0541;ARMENIAN CAPITAL LETTER JA;Lu;0;L;;;;;N;;;;0571; +0542;ARMENIAN CAPITAL LETTER GHAD;Lu;0;L;;;;;N;ARMENIAN CAPITAL LETTER LAD;;;0572; +0543;ARMENIAN CAPITAL LETTER CHEH;Lu;0;L;;;;;N;;;;0573; +0544;ARMENIAN CAPITAL LETTER MEN;Lu;0;L;;;;;N;;;;0574; +0545;ARMENIAN CAPITAL LETTER YI;Lu;0;L;;;;;N;;;;0575; +0546;ARMENIAN CAPITAL LETTER NOW;Lu;0;L;;;;;N;;;;0576; +0547;ARMENIAN CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0577; +0548;ARMENIAN CAPITAL LETTER VO;Lu;0;L;;;;;N;;;;0578; +0549;ARMENIAN CAPITAL LETTER CHA;Lu;0;L;;;;;N;;;;0579; +054A;ARMENIAN CAPITAL LETTER PEH;Lu;0;L;;;;;N;;;;057A; +054B;ARMENIAN CAPITAL LETTER JHEH;Lu;0;L;;;;;N;;;;057B; +054C;ARMENIAN CAPITAL LETTER RA;Lu;0;L;;;;;N;;;;057C; +054D;ARMENIAN CAPITAL LETTER SEH;Lu;0;L;;;;;N;;;;057D; +054E;ARMENIAN CAPITAL LETTER VEW;Lu;0;L;;;;;N;;;;057E; +054F;ARMENIAN CAPITAL LETTER TIWN;Lu;0;L;;;;;N;;;;057F; +0550;ARMENIAN CAPITAL LETTER REH;Lu;0;L;;;;;N;;;;0580; +0551;ARMENIAN CAPITAL LETTER CO;Lu;0;L;;;;;N;;;;0581; +0552;ARMENIAN CAPITAL LETTER YIWN;Lu;0;L;;;;;N;;;;0582; +0553;ARMENIAN CAPITAL LETTER PIWR;Lu;0;L;;;;;N;;;;0583; +0554;ARMENIAN CAPITAL LETTER KEH;Lu;0;L;;;;;N;;;;0584; +0555;ARMENIAN CAPITAL LETTER OH;Lu;0;L;;;;;N;;;;0585; +0556;ARMENIAN CAPITAL LETTER FEH;Lu;0;L;;;;;N;;;;0586; +0559;ARMENIAN MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;; +055A;ARMENIAN APOSTROPHE;Po;0;L;;;;;N;ARMENIAN MODIFIER LETTER RIGHT HALF RING;;;; +055B;ARMENIAN EMPHASIS MARK;Po;0;L;;;;;N;;;;; +055C;ARMENIAN EXCLAMATION MARK;Po;0;L;;;;;N;;;;; +055D;ARMENIAN COMMA;Po;0;L;;;;;N;;;;; +055E;ARMENIAN QUESTION MARK;Po;0;L;;;;;N;;;;; +055F;ARMENIAN ABBREVIATION MARK;Po;0;L;;;;;N;;;;; +0560;ARMENIAN SMALL LETTER TURNED AYB;Ll;0;L;;;;;N;;;;; +0561;ARMENIAN SMALL LETTER AYB;Ll;0;L;;;;;N;;;0531;;0531 +0562;ARMENIAN SMALL LETTER BEN;Ll;0;L;;;;;N;;;0532;;0532 +0563;ARMENIAN SMALL LETTER GIM;Ll;0;L;;;;;N;;;0533;;0533 +0564;ARMENIAN SMALL LETTER DA;Ll;0;L;;;;;N;;;0534;;0534 +0565;ARMENIAN SMALL LETTER ECH;Ll;0;L;;;;;N;;;0535;;0535 +0566;ARMENIAN SMALL LETTER ZA;Ll;0;L;;;;;N;;;0536;;0536 +0567;ARMENIAN SMALL LETTER EH;Ll;0;L;;;;;N;;;0537;;0537 +0568;ARMENIAN SMALL LETTER ET;Ll;0;L;;;;;N;;;0538;;0538 +0569;ARMENIAN SMALL LETTER TO;Ll;0;L;;;;;N;;;0539;;0539 +056A;ARMENIAN SMALL LETTER ZHE;Ll;0;L;;;;;N;;;053A;;053A +056B;ARMENIAN SMALL LETTER INI;Ll;0;L;;;;;N;;;053B;;053B +056C;ARMENIAN SMALL LETTER LIWN;Ll;0;L;;;;;N;;;053C;;053C +056D;ARMENIAN SMALL LETTER XEH;Ll;0;L;;;;;N;;;053D;;053D +056E;ARMENIAN SMALL LETTER CA;Ll;0;L;;;;;N;;;053E;;053E +056F;ARMENIAN SMALL LETTER KEN;Ll;0;L;;;;;N;;;053F;;053F +0570;ARMENIAN SMALL LETTER HO;Ll;0;L;;;;;N;;;0540;;0540 +0571;ARMENIAN SMALL LETTER JA;Ll;0;L;;;;;N;;;0541;;0541 +0572;ARMENIAN SMALL LETTER GHAD;Ll;0;L;;;;;N;ARMENIAN SMALL LETTER LAD;;0542;;0542 +0573;ARMENIAN SMALL LETTER CHEH;Ll;0;L;;;;;N;;;0543;;0543 +0574;ARMENIAN SMALL LETTER MEN;Ll;0;L;;;;;N;;;0544;;0544 +0575;ARMENIAN SMALL LETTER YI;Ll;0;L;;;;;N;;;0545;;0545 +0576;ARMENIAN SMALL LETTER NOW;Ll;0;L;;;;;N;;;0546;;0546 +0577;ARMENIAN SMALL LETTER SHA;Ll;0;L;;;;;N;;;0547;;0547 +0578;ARMENIAN SMALL LETTER VO;Ll;0;L;;;;;N;;;0548;;0548 +0579;ARMENIAN SMALL LETTER CHA;Ll;0;L;;;;;N;;;0549;;0549 +057A;ARMENIAN SMALL LETTER PEH;Ll;0;L;;;;;N;;;054A;;054A +057B;ARMENIAN SMALL LETTER JHEH;Ll;0;L;;;;;N;;;054B;;054B +057C;ARMENIAN SMALL LETTER RA;Ll;0;L;;;;;N;;;054C;;054C +057D;ARMENIAN SMALL LETTER SEH;Ll;0;L;;;;;N;;;054D;;054D +057E;ARMENIAN SMALL LETTER VEW;Ll;0;L;;;;;N;;;054E;;054E +057F;ARMENIAN SMALL LETTER TIWN;Ll;0;L;;;;;N;;;054F;;054F +0580;ARMENIAN SMALL LETTER REH;Ll;0;L;;;;;N;;;0550;;0550 +0581;ARMENIAN SMALL LETTER CO;Ll;0;L;;;;;N;;;0551;;0551 +0582;ARMENIAN SMALL LETTER YIWN;Ll;0;L;;;;;N;;;0552;;0552 +0583;ARMENIAN SMALL LETTER PIWR;Ll;0;L;;;;;N;;;0553;;0553 +0584;ARMENIAN SMALL LETTER KEH;Ll;0;L;;;;;N;;;0554;;0554 +0585;ARMENIAN SMALL LETTER OH;Ll;0;L;;;;;N;;;0555;;0555 +0586;ARMENIAN SMALL LETTER FEH;Ll;0;L;;;;;N;;;0556;;0556 +0587;ARMENIAN SMALL LIGATURE ECH YIWN;Ll;0;L; 0565 0582;;;;N;;;;; +0588;ARMENIAN SMALL LETTER YI WITH STROKE;Ll;0;L;;;;;N;;;;; +0589;ARMENIAN FULL STOP;Po;0;L;;;;;N;ARMENIAN PERIOD;;;; +058A;ARMENIAN HYPHEN;Pd;0;ON;;;;;N;;;;; +058D;RIGHT-FACING ARMENIAN ETERNITY SIGN;So;0;ON;;;;;N;;;;; +058E;LEFT-FACING ARMENIAN ETERNITY SIGN;So;0;ON;;;;;N;;;;; +058F;ARMENIAN DRAM SIGN;Sc;0;ET;;;;;N;;;;; +0591;HEBREW ACCENT ETNAHTA;Mn;220;NSM;;;;;N;;;;; +0592;HEBREW ACCENT SEGOL;Mn;230;NSM;;;;;N;;;;; +0593;HEBREW ACCENT SHALSHELET;Mn;230;NSM;;;;;N;;;;; +0594;HEBREW ACCENT ZAQEF QATAN;Mn;230;NSM;;;;;N;;;;; +0595;HEBREW ACCENT ZAQEF GADOL;Mn;230;NSM;;;;;N;;;;; +0596;HEBREW ACCENT TIPEHA;Mn;220;NSM;;;;;N;;;;; +0597;HEBREW ACCENT REVIA;Mn;230;NSM;;;;;N;;;;; +0598;HEBREW ACCENT ZARQA;Mn;230;NSM;;;;;N;;;;; +0599;HEBREW ACCENT PASHTA;Mn;230;NSM;;;;;N;;;;; +059A;HEBREW ACCENT YETIV;Mn;222;NSM;;;;;N;;;;; +059B;HEBREW ACCENT TEVIR;Mn;220;NSM;;;;;N;;;;; +059C;HEBREW ACCENT GERESH;Mn;230;NSM;;;;;N;;;;; +059D;HEBREW ACCENT GERESH MUQDAM;Mn;230;NSM;;;;;N;;;;; +059E;HEBREW ACCENT GERSHAYIM;Mn;230;NSM;;;;;N;;;;; +059F;HEBREW ACCENT QARNEY PARA;Mn;230;NSM;;;;;N;;;;; +05A0;HEBREW ACCENT TELISHA GEDOLA;Mn;230;NSM;;;;;N;;;;; +05A1;HEBREW ACCENT PAZER;Mn;230;NSM;;;;;N;;;;; +05A2;HEBREW ACCENT ATNAH HAFUKH;Mn;220;NSM;;;;;N;;;;; +05A3;HEBREW ACCENT MUNAH;Mn;220;NSM;;;;;N;;;;; +05A4;HEBREW ACCENT MAHAPAKH;Mn;220;NSM;;;;;N;;;;; +05A5;HEBREW ACCENT MERKHA;Mn;220;NSM;;;;;N;;;;; +05A6;HEBREW ACCENT MERKHA KEFULA;Mn;220;NSM;;;;;N;;;;; +05A7;HEBREW ACCENT DARGA;Mn;220;NSM;;;;;N;;;;; +05A8;HEBREW ACCENT QADMA;Mn;230;NSM;;;;;N;;;;; +05A9;HEBREW ACCENT TELISHA QETANA;Mn;230;NSM;;;;;N;;;;; +05AA;HEBREW ACCENT YERAH BEN YOMO;Mn;220;NSM;;;;;N;;;;; +05AB;HEBREW ACCENT OLE;Mn;230;NSM;;;;;N;;;;; +05AC;HEBREW ACCENT ILUY;Mn;230;NSM;;;;;N;;;;; +05AD;HEBREW ACCENT DEHI;Mn;222;NSM;;;;;N;;;;; +05AE;HEBREW ACCENT ZINOR;Mn;228;NSM;;;;;N;;;;; +05AF;HEBREW MARK MASORA CIRCLE;Mn;230;NSM;;;;;N;;;;; +05B0;HEBREW POINT SHEVA;Mn;10;NSM;;;;;N;;;;; +05B1;HEBREW POINT HATAF SEGOL;Mn;11;NSM;;;;;N;;;;; +05B2;HEBREW POINT HATAF PATAH;Mn;12;NSM;;;;;N;;;;; +05B3;HEBREW POINT HATAF QAMATS;Mn;13;NSM;;;;;N;;;;; +05B4;HEBREW POINT HIRIQ;Mn;14;NSM;;;;;N;;;;; +05B5;HEBREW POINT TSERE;Mn;15;NSM;;;;;N;;;;; +05B6;HEBREW POINT SEGOL;Mn;16;NSM;;;;;N;;;;; +05B7;HEBREW POINT PATAH;Mn;17;NSM;;;;;N;;;;; +05B8;HEBREW POINT QAMATS;Mn;18;NSM;;;;;N;;;;; +05B9;HEBREW POINT HOLAM;Mn;19;NSM;;;;;N;;;;; +05BA;HEBREW POINT HOLAM HASER FOR VAV;Mn;19;NSM;;;;;N;;;;; +05BB;HEBREW POINT QUBUTS;Mn;20;NSM;;;;;N;;;;; +05BC;HEBREW POINT DAGESH OR MAPIQ;Mn;21;NSM;;;;;N;HEBREW POINT DAGESH;;;; +05BD;HEBREW POINT METEG;Mn;22;NSM;;;;;N;;;;; +05BE;HEBREW PUNCTUATION MAQAF;Pd;0;R;;;;;N;;;;; +05BF;HEBREW POINT RAFE;Mn;23;NSM;;;;;N;;;;; +05C0;HEBREW PUNCTUATION PASEQ;Po;0;R;;;;;N;HEBREW POINT PASEQ;;;; +05C1;HEBREW POINT SHIN DOT;Mn;24;NSM;;;;;N;;;;; +05C2;HEBREW POINT SIN DOT;Mn;25;NSM;;;;;N;;;;; +05C3;HEBREW PUNCTUATION SOF PASUQ;Po;0;R;;;;;N;;;;; +05C4;HEBREW MARK UPPER DOT;Mn;230;NSM;;;;;N;;;;; +05C5;HEBREW MARK LOWER DOT;Mn;220;NSM;;;;;N;;;;; +05C6;HEBREW PUNCTUATION NUN HAFUKHA;Po;0;R;;;;;N;;;;; +05C7;HEBREW POINT QAMATS QATAN;Mn;18;NSM;;;;;N;;;;; +05D0;HEBREW LETTER ALEF;Lo;0;R;;;;;N;;;;; +05D1;HEBREW LETTER BET;Lo;0;R;;;;;N;;;;; +05D2;HEBREW LETTER GIMEL;Lo;0;R;;;;;N;;;;; +05D3;HEBREW LETTER DALET;Lo;0;R;;;;;N;;;;; +05D4;HEBREW LETTER HE;Lo;0;R;;;;;N;;;;; +05D5;HEBREW LETTER VAV;Lo;0;R;;;;;N;;;;; +05D6;HEBREW LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +05D7;HEBREW LETTER HET;Lo;0;R;;;;;N;;;;; +05D8;HEBREW LETTER TET;Lo;0;R;;;;;N;;;;; +05D9;HEBREW LETTER YOD;Lo;0;R;;;;;N;;;;; +05DA;HEBREW LETTER FINAL KAF;Lo;0;R;;;;;N;;;;; +05DB;HEBREW LETTER KAF;Lo;0;R;;;;;N;;;;; +05DC;HEBREW LETTER LAMED;Lo;0;R;;;;;N;;;;; +05DD;HEBREW LETTER FINAL MEM;Lo;0;R;;;;;N;;;;; +05DE;HEBREW LETTER MEM;Lo;0;R;;;;;N;;;;; +05DF;HEBREW LETTER FINAL NUN;Lo;0;R;;;;;N;;;;; +05E0;HEBREW LETTER NUN;Lo;0;R;;;;;N;;;;; +05E1;HEBREW LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +05E2;HEBREW LETTER AYIN;Lo;0;R;;;;;N;;;;; +05E3;HEBREW LETTER FINAL PE;Lo;0;R;;;;;N;;;;; +05E4;HEBREW LETTER PE;Lo;0;R;;;;;N;;;;; +05E5;HEBREW LETTER FINAL TSADI;Lo;0;R;;;;;N;;;;; +05E6;HEBREW LETTER TSADI;Lo;0;R;;;;;N;;;;; +05E7;HEBREW LETTER QOF;Lo;0;R;;;;;N;;;;; +05E8;HEBREW LETTER RESH;Lo;0;R;;;;;N;;;;; +05E9;HEBREW LETTER SHIN;Lo;0;R;;;;;N;;;;; +05EA;HEBREW LETTER TAV;Lo;0;R;;;;;N;;;;; +05EF;HEBREW YOD TRIANGLE;Lo;0;R;;;;;N;;;;; +05F0;HEBREW LIGATURE YIDDISH DOUBLE VAV;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE VAV;;;; +05F1;HEBREW LIGATURE YIDDISH VAV YOD;Lo;0;R;;;;;N;HEBREW LETTER VAV YOD;;;; +05F2;HEBREW LIGATURE YIDDISH DOUBLE YOD;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE YOD;;;; +05F3;HEBREW PUNCTUATION GERESH;Po;0;R;;;;;N;;;;; +05F4;HEBREW PUNCTUATION GERSHAYIM;Po;0;R;;;;;N;;;;; +0600;ARABIC NUMBER SIGN;Cf;0;AN;;;;;N;;;;; +0601;ARABIC SIGN SANAH;Cf;0;AN;;;;;N;;;;; +0602;ARABIC FOOTNOTE MARKER;Cf;0;AN;;;;;N;;;;; +0603;ARABIC SIGN SAFHA;Cf;0;AN;;;;;N;;;;; +0604;ARABIC SIGN SAMVAT;Cf;0;AN;;;;;N;;;;; +0605;ARABIC NUMBER MARK ABOVE;Cf;0;AN;;;;;N;;;;; +0606;ARABIC-INDIC CUBE ROOT;Sm;0;ON;;;;;N;;;;; +0607;ARABIC-INDIC FOURTH ROOT;Sm;0;ON;;;;;N;;;;; +0608;ARABIC RAY;Sm;0;AL;;;;;N;;;;; +0609;ARABIC-INDIC PER MILLE SIGN;Po;0;ET;;;;;N;;;;; +060A;ARABIC-INDIC PER TEN THOUSAND SIGN;Po;0;ET;;;;;N;;;;; +060B;AFGHANI SIGN;Sc;0;AL;;;;;N;;;;; +060C;ARABIC COMMA;Po;0;CS;;;;;N;;;;; +060D;ARABIC DATE SEPARATOR;Po;0;AL;;;;;N;;;;; +060E;ARABIC POETIC VERSE SIGN;So;0;ON;;;;;N;;;;; +060F;ARABIC SIGN MISRA;So;0;ON;;;;;N;;;;; +0610;ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM;Mn;230;NSM;;;;;N;;;;; +0611;ARABIC SIGN ALAYHE ASSALLAM;Mn;230;NSM;;;;;N;;;;; +0612;ARABIC SIGN RAHMATULLAH ALAYHE;Mn;230;NSM;;;;;N;;;;; +0613;ARABIC SIGN RADI ALLAHOU ANHU;Mn;230;NSM;;;;;N;;;;; +0614;ARABIC SIGN TAKHALLUS;Mn;230;NSM;;;;;N;;;;; +0615;ARABIC SMALL HIGH TAH;Mn;230;NSM;;;;;N;;;;; +0616;ARABIC SMALL HIGH LIGATURE ALEF WITH LAM WITH YEH;Mn;230;NSM;;;;;N;;;;; +0617;ARABIC SMALL HIGH ZAIN;Mn;230;NSM;;;;;N;;;;; +0618;ARABIC SMALL FATHA;Mn;30;NSM;;;;;N;;;;; +0619;ARABIC SMALL DAMMA;Mn;31;NSM;;;;;N;;;;; +061A;ARABIC SMALL KASRA;Mn;32;NSM;;;;;N;;;;; +061B;ARABIC SEMICOLON;Po;0;AL;;;;;N;;;;; +061C;ARABIC LETTER MARK;Cf;0;AL;;;;;N;;;;; +061E;ARABIC TRIPLE DOT PUNCTUATION MARK;Po;0;AL;;;;;N;;;;; +061F;ARABIC QUESTION MARK;Po;0;AL;;;;;N;;;;; +0620;ARABIC LETTER KASHMIRI YEH;Lo;0;AL;;;;;N;;;;; +0621;ARABIC LETTER HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH;;;; +0622;ARABIC LETTER ALEF WITH MADDA ABOVE;Lo;0;AL;0627 0653;;;;N;ARABIC LETTER MADDAH ON ALEF;;;; +0623;ARABIC LETTER ALEF WITH HAMZA ABOVE;Lo;0;AL;0627 0654;;;;N;ARABIC LETTER HAMZAH ON ALEF;;;; +0624;ARABIC LETTER WAW WITH HAMZA ABOVE;Lo;0;AL;0648 0654;;;;N;ARABIC LETTER HAMZAH ON WAW;;;; +0625;ARABIC LETTER ALEF WITH HAMZA BELOW;Lo;0;AL;0627 0655;;;;N;ARABIC LETTER HAMZAH UNDER ALEF;;;; +0626;ARABIC LETTER YEH WITH HAMZA ABOVE;Lo;0;AL;064A 0654;;;;N;ARABIC LETTER HAMZAH ON YA;;;; +0627;ARABIC LETTER ALEF;Lo;0;AL;;;;;N;;;;; +0628;ARABIC LETTER BEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA;;;; +0629;ARABIC LETTER TEH MARBUTA;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH;;;; +062A;ARABIC LETTER TEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA;;;; +062B;ARABIC LETTER THEH;Lo;0;AL;;;;;N;ARABIC LETTER THAA;;;; +062C;ARABIC LETTER JEEM;Lo;0;AL;;;;;N;;;;; +062D;ARABIC LETTER HAH;Lo;0;AL;;;;;N;ARABIC LETTER HAA;;;; +062E;ARABIC LETTER KHAH;Lo;0;AL;;;;;N;ARABIC LETTER KHAA;;;; +062F;ARABIC LETTER DAL;Lo;0;AL;;;;;N;;;;; +0630;ARABIC LETTER THAL;Lo;0;AL;;;;;N;;;;; +0631;ARABIC LETTER REH;Lo;0;AL;;;;;N;ARABIC LETTER RA;;;; +0632;ARABIC LETTER ZAIN;Lo;0;AL;;;;;N;;;;; +0633;ARABIC LETTER SEEN;Lo;0;AL;;;;;N;;;;; +0634;ARABIC LETTER SHEEN;Lo;0;AL;;;;;N;;;;; +0635;ARABIC LETTER SAD;Lo;0;AL;;;;;N;;;;; +0636;ARABIC LETTER DAD;Lo;0;AL;;;;;N;;;;; +0637;ARABIC LETTER TAH;Lo;0;AL;;;;;N;;;;; +0638;ARABIC LETTER ZAH;Lo;0;AL;;;;;N;ARABIC LETTER DHAH;;;; +0639;ARABIC LETTER AIN;Lo;0;AL;;;;;N;;;;; +063A;ARABIC LETTER GHAIN;Lo;0;AL;;;;;N;;;;; +063B;ARABIC LETTER KEHEH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +063C;ARABIC LETTER KEHEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; +063D;ARABIC LETTER FARSI YEH WITH INVERTED V;Lo;0;AL;;;;;N;;;;; +063E;ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +063F;ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0640;ARABIC TATWEEL;Lm;0;AL;;;;;N;;;;; +0641;ARABIC LETTER FEH;Lo;0;AL;;;;;N;ARABIC LETTER FA;;;; +0642;ARABIC LETTER QAF;Lo;0;AL;;;;;N;;;;; +0643;ARABIC LETTER KAF;Lo;0;AL;;;;;N;ARABIC LETTER CAF;;;; +0644;ARABIC LETTER LAM;Lo;0;AL;;;;;N;;;;; +0645;ARABIC LETTER MEEM;Lo;0;AL;;;;;N;;;;; +0646;ARABIC LETTER NOON;Lo;0;AL;;;;;N;;;;; +0647;ARABIC LETTER HEH;Lo;0;AL;;;;;N;ARABIC LETTER HA;;;; +0648;ARABIC LETTER WAW;Lo;0;AL;;;;;N;;;;; +0649;ARABIC LETTER ALEF MAKSURA;Lo;0;AL;;;;;N;ARABIC LETTER ALEF MAQSURAH;;;; +064A;ARABIC LETTER YEH;Lo;0;AL;;;;;N;ARABIC LETTER YA;;;; +064B;ARABIC FATHATAN;Mn;27;NSM;;;;;N;;;;; +064C;ARABIC DAMMATAN;Mn;28;NSM;;;;;N;;;;; +064D;ARABIC KASRATAN;Mn;29;NSM;;;;;N;;;;; +064E;ARABIC FATHA;Mn;30;NSM;;;;;N;ARABIC FATHAH;;;; +064F;ARABIC DAMMA;Mn;31;NSM;;;;;N;ARABIC DAMMAH;;;; +0650;ARABIC KASRA;Mn;32;NSM;;;;;N;ARABIC KASRAH;;;; +0651;ARABIC SHADDA;Mn;33;NSM;;;;;N;ARABIC SHADDAH;;;; +0652;ARABIC SUKUN;Mn;34;NSM;;;;;N;;;;; +0653;ARABIC MADDAH ABOVE;Mn;230;NSM;;;;;N;;;;; +0654;ARABIC HAMZA ABOVE;Mn;230;NSM;;;;;N;;;;; +0655;ARABIC HAMZA BELOW;Mn;220;NSM;;;;;N;;;;; +0656;ARABIC SUBSCRIPT ALEF;Mn;220;NSM;;;;;N;;;;; +0657;ARABIC INVERTED DAMMA;Mn;230;NSM;;;;;N;;;;; +0658;ARABIC MARK NOON GHUNNA;Mn;230;NSM;;;;;N;;;;; +0659;ARABIC ZWARAKAY;Mn;230;NSM;;;;;N;;;;; +065A;ARABIC VOWEL SIGN SMALL V ABOVE;Mn;230;NSM;;;;;N;;;;; +065B;ARABIC VOWEL SIGN INVERTED SMALL V ABOVE;Mn;230;NSM;;;;;N;;;;; +065C;ARABIC VOWEL SIGN DOT BELOW;Mn;220;NSM;;;;;N;;;;; +065D;ARABIC REVERSED DAMMA;Mn;230;NSM;;;;;N;;;;; +065E;ARABIC FATHA WITH TWO DOTS;Mn;230;NSM;;;;;N;;;;; +065F;ARABIC WAVY HAMZA BELOW;Mn;220;NSM;;;;;N;;;;; +0660;ARABIC-INDIC DIGIT ZERO;Nd;0;AN;;0;0;0;N;;;;; +0661;ARABIC-INDIC DIGIT ONE;Nd;0;AN;;1;1;1;N;;;;; +0662;ARABIC-INDIC DIGIT TWO;Nd;0;AN;;2;2;2;N;;;;; +0663;ARABIC-INDIC DIGIT THREE;Nd;0;AN;;3;3;3;N;;;;; +0664;ARABIC-INDIC DIGIT FOUR;Nd;0;AN;;4;4;4;N;;;;; +0665;ARABIC-INDIC DIGIT FIVE;Nd;0;AN;;5;5;5;N;;;;; +0666;ARABIC-INDIC DIGIT SIX;Nd;0;AN;;6;6;6;N;;;;; +0667;ARABIC-INDIC DIGIT SEVEN;Nd;0;AN;;7;7;7;N;;;;; +0668;ARABIC-INDIC DIGIT EIGHT;Nd;0;AN;;8;8;8;N;;;;; +0669;ARABIC-INDIC DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;; +066A;ARABIC PERCENT SIGN;Po;0;ET;;;;;N;;;;; +066B;ARABIC DECIMAL SEPARATOR;Po;0;AN;;;;;N;;;;; +066C;ARABIC THOUSANDS SEPARATOR;Po;0;AN;;;;;N;;;;; +066D;ARABIC FIVE POINTED STAR;Po;0;AL;;;;;N;;;;; +066E;ARABIC LETTER DOTLESS BEH;Lo;0;AL;;;;;N;;;;; +066F;ARABIC LETTER DOTLESS QAF;Lo;0;AL;;;;;N;;;;; +0670;ARABIC LETTER SUPERSCRIPT ALEF;Mn;35;NSM;;;;;N;ARABIC ALEF ABOVE;;;; +0671;ARABIC LETTER ALEF WASLA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAT WASL ON ALEF;;;; +0672;ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH ON ALEF;;;; +0673;ARABIC LETTER ALEF WITH WAVY HAMZA BELOW;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH UNDER ALEF;;;; +0674;ARABIC LETTER HIGH HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HIGH HAMZAH;;;; +0675;ARABIC LETTER HIGH HAMZA ALEF;Lo;0;AL; 0627 0674;;;;N;ARABIC LETTER HIGH HAMZAH ALEF;;;; +0676;ARABIC LETTER HIGH HAMZA WAW;Lo;0;AL; 0648 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW;;;; +0677;ARABIC LETTER U WITH HAMZA ABOVE;Lo;0;AL; 06C7 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW WITH DAMMAH;;;; +0678;ARABIC LETTER HIGH HAMZA YEH;Lo;0;AL; 064A 0674;;;;N;ARABIC LETTER HIGH HAMZAH YA;;;; +0679;ARABIC LETTER TTEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH SMALL TAH;;;; +067A;ARABIC LETTER TTEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH TWO DOTS VERTICAL ABOVE;;;; +067B;ARABIC LETTER BEEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH TWO DOTS VERTICAL BELOW;;;; +067C;ARABIC LETTER TEH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH RING;;;; +067D;ARABIC LETTER TEH WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS ABOVE DOWNWARD;;;; +067E;ARABIC LETTER PEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS BELOW;;;; +067F;ARABIC LETTER TEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH FOUR DOTS ABOVE;;;; +0680;ARABIC LETTER BEHEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH FOUR DOTS BELOW;;;; +0681;ARABIC LETTER HAH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH ON HAA;;;; +0682;ARABIC LETTER HAH WITH TWO DOTS VERTICAL ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH TWO DOTS VERTICAL ABOVE;;;; +0683;ARABIC LETTER NYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS;;;; +0684;ARABIC LETTER DYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS VERTICAL;;;; +0685;ARABIC LETTER HAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH THREE DOTS ABOVE;;;; +0686;ARABIC LETTER TCHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE THREE DOTS DOWNWARD;;;; +0687;ARABIC LETTER TCHEHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE FOUR DOTS;;;; +0688;ARABIC LETTER DDAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH SMALL TAH;;;; +0689;ARABIC LETTER DAL WITH RING;Lo;0;AL;;;;;N;;;;; +068A;ARABIC LETTER DAL WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +068B;ARABIC LETTER DAL WITH DOT BELOW AND SMALL TAH;Lo;0;AL;;;;;N;;;;; +068C;ARABIC LETTER DAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS ABOVE;;;; +068D;ARABIC LETTER DDAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS BELOW;;;; +068E;ARABIC LETTER DUL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE;;;; +068F;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARD;;;; +0690;ARABIC LETTER DAL WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0691;ARABIC LETTER RREH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL TAH;;;; +0692;ARABIC LETTER REH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V;;;; +0693;ARABIC LETTER REH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH RING;;;; +0694;ARABIC LETTER REH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW;;;; +0695;ARABIC LETTER REH WITH SMALL V BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V BELOW;;;; +0696;ARABIC LETTER REH WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW AND DOT ABOVE;;;; +0697;ARABIC LETTER REH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH TWO DOTS ABOVE;;;; +0698;ARABIC LETTER JEH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH THREE DOTS ABOVE;;;; +0699;ARABIC LETTER REH WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH FOUR DOTS ABOVE;;;; +069A;ARABIC LETTER SEEN WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;; +069B;ARABIC LETTER SEEN WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; +069C;ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +069D;ARABIC LETTER SAD WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; +069E;ARABIC LETTER SAD WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +069F;ARABIC LETTER TAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06A0;ARABIC LETTER AIN WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06A1;ARABIC LETTER DOTLESS FEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS FA;;;; +06A2;ARABIC LETTER FEH WITH DOT MOVED BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT MOVED BELOW;;;; +06A3;ARABIC LETTER FEH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT BELOW;;;; +06A4;ARABIC LETTER VEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS ABOVE;;;; +06A5;ARABIC LETTER FEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS BELOW;;;; +06A6;ARABIC LETTER PEHEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH FOUR DOTS ABOVE;;;; +06A7;ARABIC LETTER QAF WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +06A8;ARABIC LETTER QAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06A9;ARABIC LETTER KEHEH;Lo;0;AL;;;;;N;ARABIC LETTER OPEN CAF;;;; +06AA;ARABIC LETTER SWASH KAF;Lo;0;AL;;;;;N;ARABIC LETTER SWASH CAF;;;; +06AB;ARABIC LETTER KAF WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH RING;;;; +06AC;ARABIC LETTER KAF WITH DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH DOT ABOVE;;;; +06AD;ARABIC LETTER NG;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS ABOVE;;;; +06AE;ARABIC LETTER KAF WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS BELOW;;;; +06AF;ARABIC LETTER GAF;Lo;0;AL;;;;;N;;;;; +06B0;ARABIC LETTER GAF WITH RING;Lo;0;AL;;;;;N;;;;; +06B1;ARABIC LETTER NGOEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS ABOVE;;;; +06B2;ARABIC LETTER GAF WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; +06B3;ARABIC LETTER GUEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS VERTICAL BELOW;;;; +06B4;ARABIC LETTER GAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06B5;ARABIC LETTER LAM WITH SMALL V;Lo;0;AL;;;;;N;;;;; +06B6;ARABIC LETTER LAM WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +06B7;ARABIC LETTER LAM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06B8;ARABIC LETTER LAM WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; +06B9;ARABIC LETTER NOON WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +06BA;ARABIC LETTER NOON GHUNNA;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON;;;; +06BB;ARABIC LETTER RNOON;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON WITH SMALL TAH;;;; +06BC;ARABIC LETTER NOON WITH RING;Lo;0;AL;;;;;N;;;;; +06BD;ARABIC LETTER NOON WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06BE;ARABIC LETTER HEH DOACHASHMEE;Lo;0;AL;;;;;N;ARABIC LETTER KNOTTED HA;;;; +06BF;ARABIC LETTER TCHEH WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +06C0;ARABIC LETTER HEH WITH YEH ABOVE;Lo;0;AL;06D5 0654;;;;N;ARABIC LETTER HAMZAH ON HA;;;; +06C1;ARABIC LETTER HEH GOAL;Lo;0;AL;;;;;N;ARABIC LETTER HA GOAL;;;; +06C2;ARABIC LETTER HEH GOAL WITH HAMZA ABOVE;Lo;0;AL;06C1 0654;;;;N;ARABIC LETTER HAMZAH ON HA GOAL;;;; +06C3;ARABIC LETTER TEH MARBUTA GOAL;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH GOAL;;;; +06C4;ARABIC LETTER WAW WITH RING;Lo;0;AL;;;;;N;;;;; +06C5;ARABIC LETTER KIRGHIZ OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH BAR;;;; +06C6;ARABIC LETTER OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH SMALL V;;;; +06C7;ARABIC LETTER U;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH DAMMAH;;;; +06C8;ARABIC LETTER YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH ALEF ABOVE;;;; +06C9;ARABIC LETTER KIRGHIZ YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH INVERTED SMALL V;;;; +06CA;ARABIC LETTER WAW WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +06CB;ARABIC LETTER VE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH THREE DOTS ABOVE;;;; +06CC;ARABIC LETTER FARSI YEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS YA;;;; +06CD;ARABIC LETTER YEH WITH TAIL;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TAIL;;;; +06CE;ARABIC LETTER YEH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH SMALL V;;;; +06CF;ARABIC LETTER WAW WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +06D0;ARABIC LETTER E;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TWO DOTS VERTICAL BELOW;;;; +06D1;ARABIC LETTER YEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH THREE DOTS BELOW;;;; +06D2;ARABIC LETTER YEH BARREE;Lo;0;AL;;;;;N;ARABIC LETTER YA BARREE;;;; +06D3;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE;Lo;0;AL;06D2 0654;;;;N;ARABIC LETTER HAMZAH ON YA BARREE;;;; +06D4;ARABIC FULL STOP;Po;0;AL;;;;;N;ARABIC PERIOD;;;; +06D5;ARABIC LETTER AE;Lo;0;AL;;;;;N;;;;; +06D6;ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;; +06D7;ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;; +06D8;ARABIC SMALL HIGH MEEM INITIAL FORM;Mn;230;NSM;;;;;N;;;;; +06D9;ARABIC SMALL HIGH LAM ALEF;Mn;230;NSM;;;;;N;;;;; +06DA;ARABIC SMALL HIGH JEEM;Mn;230;NSM;;;;;N;;;;; +06DB;ARABIC SMALL HIGH THREE DOTS;Mn;230;NSM;;;;;N;;;;; +06DC;ARABIC SMALL HIGH SEEN;Mn;230;NSM;;;;;N;;;;; +06DD;ARABIC END OF AYAH;Cf;0;AN;;;;;N;;;;; +06DE;ARABIC START OF RUB EL HIZB;So;0;ON;;;;;N;;;;; +06DF;ARABIC SMALL HIGH ROUNDED ZERO;Mn;230;NSM;;;;;N;;;;; +06E0;ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO;Mn;230;NSM;;;;;N;;;;; +06E1;ARABIC SMALL HIGH DOTLESS HEAD OF KHAH;Mn;230;NSM;;;;;N;;;;; +06E2;ARABIC SMALL HIGH MEEM ISOLATED FORM;Mn;230;NSM;;;;;N;;;;; +06E3;ARABIC SMALL LOW SEEN;Mn;220;NSM;;;;;N;;;;; +06E4;ARABIC SMALL HIGH MADDA;Mn;230;NSM;;;;;N;;;;; +06E5;ARABIC SMALL WAW;Lm;0;AL;;;;;N;;;;; +06E6;ARABIC SMALL YEH;Lm;0;AL;;;;;N;;;;; +06E7;ARABIC SMALL HIGH YEH;Mn;230;NSM;;;;;N;;;;; +06E8;ARABIC SMALL HIGH NOON;Mn;230;NSM;;;;;N;;;;; +06E9;ARABIC PLACE OF SAJDAH;So;0;ON;;;;;N;;;;; +06EA;ARABIC EMPTY CENTRE LOW STOP;Mn;220;NSM;;;;;N;;;;; +06EB;ARABIC EMPTY CENTRE HIGH STOP;Mn;230;NSM;;;;;N;;;;; +06EC;ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE;Mn;230;NSM;;;;;N;;;;; +06ED;ARABIC SMALL LOW MEEM;Mn;220;NSM;;;;;N;;;;; +06EE;ARABIC LETTER DAL WITH INVERTED V;Lo;0;AL;;;;;N;;;;; +06EF;ARABIC LETTER REH WITH INVERTED V;Lo;0;AL;;;;;N;;;;; +06F0;EXTENDED ARABIC-INDIC DIGIT ZERO;Nd;0;EN;;0;0;0;N;EASTERN ARABIC-INDIC DIGIT ZERO;;;; +06F1;EXTENDED ARABIC-INDIC DIGIT ONE;Nd;0;EN;;1;1;1;N;EASTERN ARABIC-INDIC DIGIT ONE;;;; +06F2;EXTENDED ARABIC-INDIC DIGIT TWO;Nd;0;EN;;2;2;2;N;EASTERN ARABIC-INDIC DIGIT TWO;;;; +06F3;EXTENDED ARABIC-INDIC DIGIT THREE;Nd;0;EN;;3;3;3;N;EASTERN ARABIC-INDIC DIGIT THREE;;;; +06F4;EXTENDED ARABIC-INDIC DIGIT FOUR;Nd;0;EN;;4;4;4;N;EASTERN ARABIC-INDIC DIGIT FOUR;;;; +06F5;EXTENDED ARABIC-INDIC DIGIT FIVE;Nd;0;EN;;5;5;5;N;EASTERN ARABIC-INDIC DIGIT FIVE;;;; +06F6;EXTENDED ARABIC-INDIC DIGIT SIX;Nd;0;EN;;6;6;6;N;EASTERN ARABIC-INDIC DIGIT SIX;;;; +06F7;EXTENDED ARABIC-INDIC DIGIT SEVEN;Nd;0;EN;;7;7;7;N;EASTERN ARABIC-INDIC DIGIT SEVEN;;;; +06F8;EXTENDED ARABIC-INDIC DIGIT EIGHT;Nd;0;EN;;8;8;8;N;EASTERN ARABIC-INDIC DIGIT EIGHT;;;; +06F9;EXTENDED ARABIC-INDIC DIGIT NINE;Nd;0;EN;;9;9;9;N;EASTERN ARABIC-INDIC DIGIT NINE;;;; +06FA;ARABIC LETTER SHEEN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +06FB;ARABIC LETTER DAD WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +06FC;ARABIC LETTER GHAIN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +06FD;ARABIC SIGN SINDHI AMPERSAND;So;0;AL;;;;;N;;;;; +06FE;ARABIC SIGN SINDHI POSTPOSITION MEN;So;0;AL;;;;;N;;;;; +06FF;ARABIC LETTER HEH WITH INVERTED V;Lo;0;AL;;;;;N;;;;; +0700;SYRIAC END OF PARAGRAPH;Po;0;AL;;;;;N;;;;; +0701;SYRIAC SUPRALINEAR FULL STOP;Po;0;AL;;;;;N;;;;; +0702;SYRIAC SUBLINEAR FULL STOP;Po;0;AL;;;;;N;;;;; +0703;SYRIAC SUPRALINEAR COLON;Po;0;AL;;;;;N;;;;; +0704;SYRIAC SUBLINEAR COLON;Po;0;AL;;;;;N;;;;; +0705;SYRIAC HORIZONTAL COLON;Po;0;AL;;;;;N;;;;; +0706;SYRIAC COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;; +0707;SYRIAC COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;; +0708;SYRIAC SUPRALINEAR COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;; +0709;SYRIAC SUBLINEAR COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;; +070A;SYRIAC CONTRACTION;Po;0;AL;;;;;N;;;;; +070B;SYRIAC HARKLEAN OBELUS;Po;0;AL;;;;;N;;;;; +070C;SYRIAC HARKLEAN METOBELUS;Po;0;AL;;;;;N;;;;; +070D;SYRIAC HARKLEAN ASTERISCUS;Po;0;AL;;;;;N;;;;; +070F;SYRIAC ABBREVIATION MARK;Cf;0;AL;;;;;N;;;;; +0710;SYRIAC LETTER ALAPH;Lo;0;AL;;;;;N;;;;; +0711;SYRIAC LETTER SUPERSCRIPT ALAPH;Mn;36;NSM;;;;;N;;;;; +0712;SYRIAC LETTER BETH;Lo;0;AL;;;;;N;;;;; +0713;SYRIAC LETTER GAMAL;Lo;0;AL;;;;;N;;;;; +0714;SYRIAC LETTER GAMAL GARSHUNI;Lo;0;AL;;;;;N;;;;; +0715;SYRIAC LETTER DALATH;Lo;0;AL;;;;;N;;;;; +0716;SYRIAC LETTER DOTLESS DALATH RISH;Lo;0;AL;;;;;N;;;;; +0717;SYRIAC LETTER HE;Lo;0;AL;;;;;N;;;;; +0718;SYRIAC LETTER WAW;Lo;0;AL;;;;;N;;;;; +0719;SYRIAC LETTER ZAIN;Lo;0;AL;;;;;N;;;;; +071A;SYRIAC LETTER HETH;Lo;0;AL;;;;;N;;;;; +071B;SYRIAC LETTER TETH;Lo;0;AL;;;;;N;;;;; +071C;SYRIAC LETTER TETH GARSHUNI;Lo;0;AL;;;;;N;;;;; +071D;SYRIAC LETTER YUDH;Lo;0;AL;;;;;N;;;;; +071E;SYRIAC LETTER YUDH HE;Lo;0;AL;;;;;N;;;;; +071F;SYRIAC LETTER KAPH;Lo;0;AL;;;;;N;;;;; +0720;SYRIAC LETTER LAMADH;Lo;0;AL;;;;;N;;;;; +0721;SYRIAC LETTER MIM;Lo;0;AL;;;;;N;;;;; +0722;SYRIAC LETTER NUN;Lo;0;AL;;;;;N;;;;; +0723;SYRIAC LETTER SEMKATH;Lo;0;AL;;;;;N;;;;; +0724;SYRIAC LETTER FINAL SEMKATH;Lo;0;AL;;;;;N;;;;; +0725;SYRIAC LETTER E;Lo;0;AL;;;;;N;;;;; +0726;SYRIAC LETTER PE;Lo;0;AL;;;;;N;;;;; +0727;SYRIAC LETTER REVERSED PE;Lo;0;AL;;;;;N;;;;; +0728;SYRIAC LETTER SADHE;Lo;0;AL;;;;;N;;;;; +0729;SYRIAC LETTER QAPH;Lo;0;AL;;;;;N;;;;; +072A;SYRIAC LETTER RISH;Lo;0;AL;;;;;N;;;;; +072B;SYRIAC LETTER SHIN;Lo;0;AL;;;;;N;;;;; +072C;SYRIAC LETTER TAW;Lo;0;AL;;;;;N;;;;; +072D;SYRIAC LETTER PERSIAN BHETH;Lo;0;AL;;;;;N;;;;; +072E;SYRIAC LETTER PERSIAN GHAMAL;Lo;0;AL;;;;;N;;;;; +072F;SYRIAC LETTER PERSIAN DHALATH;Lo;0;AL;;;;;N;;;;; +0730;SYRIAC PTHAHA ABOVE;Mn;230;NSM;;;;;N;;;;; +0731;SYRIAC PTHAHA BELOW;Mn;220;NSM;;;;;N;;;;; +0732;SYRIAC PTHAHA DOTTED;Mn;230;NSM;;;;;N;;;;; +0733;SYRIAC ZQAPHA ABOVE;Mn;230;NSM;;;;;N;;;;; +0734;SYRIAC ZQAPHA BELOW;Mn;220;NSM;;;;;N;;;;; +0735;SYRIAC ZQAPHA DOTTED;Mn;230;NSM;;;;;N;;;;; +0736;SYRIAC RBASA ABOVE;Mn;230;NSM;;;;;N;;;;; +0737;SYRIAC RBASA BELOW;Mn;220;NSM;;;;;N;;;;; +0738;SYRIAC DOTTED ZLAMA HORIZONTAL;Mn;220;NSM;;;;;N;;;;; +0739;SYRIAC DOTTED ZLAMA ANGULAR;Mn;220;NSM;;;;;N;;;;; +073A;SYRIAC HBASA ABOVE;Mn;230;NSM;;;;;N;;;;; +073B;SYRIAC HBASA BELOW;Mn;220;NSM;;;;;N;;;;; +073C;SYRIAC HBASA-ESASA DOTTED;Mn;220;NSM;;;;;N;;;;; +073D;SYRIAC ESASA ABOVE;Mn;230;NSM;;;;;N;;;;; +073E;SYRIAC ESASA BELOW;Mn;220;NSM;;;;;N;;;;; +073F;SYRIAC RWAHA;Mn;230;NSM;;;;;N;;;;; +0740;SYRIAC FEMININE DOT;Mn;230;NSM;;;;;N;;;;; +0741;SYRIAC QUSHSHAYA;Mn;230;NSM;;;;;N;;;;; +0742;SYRIAC RUKKAKHA;Mn;220;NSM;;;;;N;;;;; +0743;SYRIAC TWO VERTICAL DOTS ABOVE;Mn;230;NSM;;;;;N;;;;; +0744;SYRIAC TWO VERTICAL DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +0745;SYRIAC THREE DOTS ABOVE;Mn;230;NSM;;;;;N;;;;; +0746;SYRIAC THREE DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +0747;SYRIAC OBLIQUE LINE ABOVE;Mn;230;NSM;;;;;N;;;;; +0748;SYRIAC OBLIQUE LINE BELOW;Mn;220;NSM;;;;;N;;;;; +0749;SYRIAC MUSIC;Mn;230;NSM;;;;;N;;;;; +074A;SYRIAC BARREKH;Mn;230;NSM;;;;;N;;;;; +074D;SYRIAC LETTER SOGDIAN ZHAIN;Lo;0;AL;;;;;N;;;;; +074E;SYRIAC LETTER SOGDIAN KHAPH;Lo;0;AL;;;;;N;;;;; +074F;SYRIAC LETTER SOGDIAN FE;Lo;0;AL;;;;;N;;;;; +0750;ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW;Lo;0;AL;;;;;N;;;;; +0751;ARABIC LETTER BEH WITH DOT BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0752;ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;; +0753;ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW AND TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0754;ARABIC LETTER BEH WITH TWO DOTS BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;; +0755;ARABIC LETTER BEH WITH INVERTED SMALL V BELOW;Lo;0;AL;;;;;N;;;;; +0756;ARABIC LETTER BEH WITH SMALL V;Lo;0;AL;;;;;N;;;;; +0757;ARABIC LETTER HAH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0758;ARABIC LETTER HAH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;; +0759;ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW AND SMALL TAH;Lo;0;AL;;;;;N;;;;; +075A;ARABIC LETTER DAL WITH INVERTED SMALL V BELOW;Lo;0;AL;;;;;N;;;;; +075B;ARABIC LETTER REH WITH STROKE;Lo;0;AL;;;;;N;;;;; +075C;ARABIC LETTER SEEN WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +075D;ARABIC LETTER AIN WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +075E;ARABIC LETTER AIN WITH THREE DOTS POINTING DOWNWARDS ABOVE;Lo;0;AL;;;;;N;;;;; +075F;ARABIC LETTER AIN WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;; +0760;ARABIC LETTER FEH WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; +0761;ARABIC LETTER FEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;; +0762;ARABIC LETTER KEHEH WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +0763;ARABIC LETTER KEHEH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0764;ARABIC LETTER KEHEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;; +0765;ARABIC LETTER MEEM WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; +0766;ARABIC LETTER MEEM WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +0767;ARABIC LETTER NOON WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; +0768;ARABIC LETTER NOON WITH SMALL TAH;Lo;0;AL;;;;;N;;;;; +0769;ARABIC LETTER NOON WITH SMALL V;Lo;0;AL;;;;;N;;;;; +076A;ARABIC LETTER LAM WITH BAR;Lo;0;AL;;;;;N;;;;; +076B;ARABIC LETTER REH WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;; +076C;ARABIC LETTER REH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;;;;; +076D;ARABIC LETTER SEEN WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;; +076E;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH BELOW;Lo;0;AL;;;;;N;;;;; +076F;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;; +0770;ARABIC LETTER SEEN WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;; +0771;ARABIC LETTER REH WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;; +0772;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH ABOVE;Lo;0;AL;;;;;N;;;;; +0773;ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;; +0774;ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;; +0775;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;; +0776;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;; +0777;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW;Lo;0;AL;;;;;N;;;;; +0778;ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;; +0779;ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;; +077A;ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;; +077B;ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;; +077C;ARABIC LETTER HAH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW;Lo;0;AL;;;;;N;;;;; +077D;ARABIC LETTER SEEN WITH EXTENDED ARABIC-INDIC DIGIT FOUR ABOVE;Lo;0;AL;;;;;N;;;;; +077E;ARABIC LETTER SEEN WITH INVERTED V;Lo;0;AL;;;;;N;;;;; +077F;ARABIC LETTER KAF WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +0780;THAANA LETTER HAA;Lo;0;AL;;;;;N;;;;; +0781;THAANA LETTER SHAVIYANI;Lo;0;AL;;;;;N;;;;; +0782;THAANA LETTER NOONU;Lo;0;AL;;;;;N;;;;; +0783;THAANA LETTER RAA;Lo;0;AL;;;;;N;;;;; +0784;THAANA LETTER BAA;Lo;0;AL;;;;;N;;;;; +0785;THAANA LETTER LHAVIYANI;Lo;0;AL;;;;;N;;;;; +0786;THAANA LETTER KAAFU;Lo;0;AL;;;;;N;;;;; +0787;THAANA LETTER ALIFU;Lo;0;AL;;;;;N;;;;; +0788;THAANA LETTER VAAVU;Lo;0;AL;;;;;N;;;;; +0789;THAANA LETTER MEEMU;Lo;0;AL;;;;;N;;;;; +078A;THAANA LETTER FAAFU;Lo;0;AL;;;;;N;;;;; +078B;THAANA LETTER DHAALU;Lo;0;AL;;;;;N;;;;; +078C;THAANA LETTER THAA;Lo;0;AL;;;;;N;;;;; +078D;THAANA LETTER LAAMU;Lo;0;AL;;;;;N;;;;; +078E;THAANA LETTER GAAFU;Lo;0;AL;;;;;N;;;;; +078F;THAANA LETTER GNAVIYANI;Lo;0;AL;;;;;N;;;;; +0790;THAANA LETTER SEENU;Lo;0;AL;;;;;N;;;;; +0791;THAANA LETTER DAVIYANI;Lo;0;AL;;;;;N;;;;; +0792;THAANA LETTER ZAVIYANI;Lo;0;AL;;;;;N;;;;; +0793;THAANA LETTER TAVIYANI;Lo;0;AL;;;;;N;;;;; +0794;THAANA LETTER YAA;Lo;0;AL;;;;;N;;;;; +0795;THAANA LETTER PAVIYANI;Lo;0;AL;;;;;N;;;;; +0796;THAANA LETTER JAVIYANI;Lo;0;AL;;;;;N;;;;; +0797;THAANA LETTER CHAVIYANI;Lo;0;AL;;;;;N;;;;; +0798;THAANA LETTER TTAA;Lo;0;AL;;;;;N;;;;; +0799;THAANA LETTER HHAA;Lo;0;AL;;;;;N;;;;; +079A;THAANA LETTER KHAA;Lo;0;AL;;;;;N;;;;; +079B;THAANA LETTER THAALU;Lo;0;AL;;;;;N;;;;; +079C;THAANA LETTER ZAA;Lo;0;AL;;;;;N;;;;; +079D;THAANA LETTER SHEENU;Lo;0;AL;;;;;N;;;;; +079E;THAANA LETTER SAADHU;Lo;0;AL;;;;;N;;;;; +079F;THAANA LETTER DAADHU;Lo;0;AL;;;;;N;;;;; +07A0;THAANA LETTER TO;Lo;0;AL;;;;;N;;;;; +07A1;THAANA LETTER ZO;Lo;0;AL;;;;;N;;;;; +07A2;THAANA LETTER AINU;Lo;0;AL;;;;;N;;;;; +07A3;THAANA LETTER GHAINU;Lo;0;AL;;;;;N;;;;; +07A4;THAANA LETTER QAAFU;Lo;0;AL;;;;;N;;;;; +07A5;THAANA LETTER WAAVU;Lo;0;AL;;;;;N;;;;; +07A6;THAANA ABAFILI;Mn;0;NSM;;;;;N;;;;; +07A7;THAANA AABAAFILI;Mn;0;NSM;;;;;N;;;;; +07A8;THAANA IBIFILI;Mn;0;NSM;;;;;N;;;;; +07A9;THAANA EEBEEFILI;Mn;0;NSM;;;;;N;;;;; +07AA;THAANA UBUFILI;Mn;0;NSM;;;;;N;;;;; +07AB;THAANA OOBOOFILI;Mn;0;NSM;;;;;N;;;;; +07AC;THAANA EBEFILI;Mn;0;NSM;;;;;N;;;;; +07AD;THAANA EYBEYFILI;Mn;0;NSM;;;;;N;;;;; +07AE;THAANA OBOFILI;Mn;0;NSM;;;;;N;;;;; +07AF;THAANA OABOAFILI;Mn;0;NSM;;;;;N;;;;; +07B0;THAANA SUKUN;Mn;0;NSM;;;;;N;;;;; +07B1;THAANA LETTER NAA;Lo;0;AL;;;;;N;;;;; +07C0;NKO DIGIT ZERO;Nd;0;R;;0;0;0;N;;;;; +07C1;NKO DIGIT ONE;Nd;0;R;;1;1;1;N;;;;; +07C2;NKO DIGIT TWO;Nd;0;R;;2;2;2;N;;;;; +07C3;NKO DIGIT THREE;Nd;0;R;;3;3;3;N;;;;; +07C4;NKO DIGIT FOUR;Nd;0;R;;4;4;4;N;;;;; +07C5;NKO DIGIT FIVE;Nd;0;R;;5;5;5;N;;;;; +07C6;NKO DIGIT SIX;Nd;0;R;;6;6;6;N;;;;; +07C7;NKO DIGIT SEVEN;Nd;0;R;;7;7;7;N;;;;; +07C8;NKO DIGIT EIGHT;Nd;0;R;;8;8;8;N;;;;; +07C9;NKO DIGIT NINE;Nd;0;R;;9;9;9;N;;;;; +07CA;NKO LETTER A;Lo;0;R;;;;;N;;;;; +07CB;NKO LETTER EE;Lo;0;R;;;;;N;;;;; +07CC;NKO LETTER I;Lo;0;R;;;;;N;;;;; +07CD;NKO LETTER E;Lo;0;R;;;;;N;;;;; +07CE;NKO LETTER U;Lo;0;R;;;;;N;;;;; +07CF;NKO LETTER OO;Lo;0;R;;;;;N;;;;; +07D0;NKO LETTER O;Lo;0;R;;;;;N;;;;; +07D1;NKO LETTER DAGBASINNA;Lo;0;R;;;;;N;;;;; +07D2;NKO LETTER N;Lo;0;R;;;;;N;;;;; +07D3;NKO LETTER BA;Lo;0;R;;;;;N;;;;; +07D4;NKO LETTER PA;Lo;0;R;;;;;N;;;;; +07D5;NKO LETTER TA;Lo;0;R;;;;;N;;;;; +07D6;NKO LETTER JA;Lo;0;R;;;;;N;;;;; +07D7;NKO LETTER CHA;Lo;0;R;;;;;N;;;;; +07D8;NKO LETTER DA;Lo;0;R;;;;;N;;;;; +07D9;NKO LETTER RA;Lo;0;R;;;;;N;;;;; +07DA;NKO LETTER RRA;Lo;0;R;;;;;N;;;;; +07DB;NKO LETTER SA;Lo;0;R;;;;;N;;;;; +07DC;NKO LETTER GBA;Lo;0;R;;;;;N;;;;; +07DD;NKO LETTER FA;Lo;0;R;;;;;N;;;;; +07DE;NKO LETTER KA;Lo;0;R;;;;;N;;;;; +07DF;NKO LETTER LA;Lo;0;R;;;;;N;;;;; +07E0;NKO LETTER NA WOLOSO;Lo;0;R;;;;;N;;;;; +07E1;NKO LETTER MA;Lo;0;R;;;;;N;;;;; +07E2;NKO LETTER NYA;Lo;0;R;;;;;N;;;;; +07E3;NKO LETTER NA;Lo;0;R;;;;;N;;;;; +07E4;NKO LETTER HA;Lo;0;R;;;;;N;;;;; +07E5;NKO LETTER WA;Lo;0;R;;;;;N;;;;; +07E6;NKO LETTER YA;Lo;0;R;;;;;N;;;;; +07E7;NKO LETTER NYA WOLOSO;Lo;0;R;;;;;N;;;;; +07E8;NKO LETTER JONA JA;Lo;0;R;;;;;N;;;;; +07E9;NKO LETTER JONA CHA;Lo;0;R;;;;;N;;;;; +07EA;NKO LETTER JONA RA;Lo;0;R;;;;;N;;;;; +07EB;NKO COMBINING SHORT HIGH TONE;Mn;230;NSM;;;;;N;;;;; +07EC;NKO COMBINING SHORT LOW TONE;Mn;230;NSM;;;;;N;;;;; +07ED;NKO COMBINING SHORT RISING TONE;Mn;230;NSM;;;;;N;;;;; +07EE;NKO COMBINING LONG DESCENDING TONE;Mn;230;NSM;;;;;N;;;;; +07EF;NKO COMBINING LONG HIGH TONE;Mn;230;NSM;;;;;N;;;;; +07F0;NKO COMBINING LONG LOW TONE;Mn;230;NSM;;;;;N;;;;; +07F1;NKO COMBINING LONG RISING TONE;Mn;230;NSM;;;;;N;;;;; +07F2;NKO COMBINING NASALIZATION MARK;Mn;220;NSM;;;;;N;;;;; +07F3;NKO COMBINING DOUBLE DOT ABOVE;Mn;230;NSM;;;;;N;;;;; +07F4;NKO HIGH TONE APOSTROPHE;Lm;0;R;;;;;N;;;;; +07F5;NKO LOW TONE APOSTROPHE;Lm;0;R;;;;;N;;;;; +07F6;NKO SYMBOL OO DENNEN;So;0;ON;;;;;N;;;;; +07F7;NKO SYMBOL GBAKURUNEN;Po;0;ON;;;;;N;;;;; +07F8;NKO COMMA;Po;0;ON;;;;;N;;;;; +07F9;NKO EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; +07FA;NKO LAJANYALAN;Lm;0;R;;;;;N;;;;; +07FD;NKO DANTAYALAN;Mn;220;NSM;;;;;N;;;;; +07FE;NKO DOROME SIGN;Sc;0;R;;;;;N;;;;; +07FF;NKO TAMAN SIGN;Sc;0;R;;;;;N;;;;; +0800;SAMARITAN LETTER ALAF;Lo;0;R;;;;;N;;;;; +0801;SAMARITAN LETTER BIT;Lo;0;R;;;;;N;;;;; +0802;SAMARITAN LETTER GAMAN;Lo;0;R;;;;;N;;;;; +0803;SAMARITAN LETTER DALAT;Lo;0;R;;;;;N;;;;; +0804;SAMARITAN LETTER IY;Lo;0;R;;;;;N;;;;; +0805;SAMARITAN LETTER BAA;Lo;0;R;;;;;N;;;;; +0806;SAMARITAN LETTER ZEN;Lo;0;R;;;;;N;;;;; +0807;SAMARITAN LETTER IT;Lo;0;R;;;;;N;;;;; +0808;SAMARITAN LETTER TIT;Lo;0;R;;;;;N;;;;; +0809;SAMARITAN LETTER YUT;Lo;0;R;;;;;N;;;;; +080A;SAMARITAN LETTER KAAF;Lo;0;R;;;;;N;;;;; +080B;SAMARITAN LETTER LABAT;Lo;0;R;;;;;N;;;;; +080C;SAMARITAN LETTER MIM;Lo;0;R;;;;;N;;;;; +080D;SAMARITAN LETTER NUN;Lo;0;R;;;;;N;;;;; +080E;SAMARITAN LETTER SINGAAT;Lo;0;R;;;;;N;;;;; +080F;SAMARITAN LETTER IN;Lo;0;R;;;;;N;;;;; +0810;SAMARITAN LETTER FI;Lo;0;R;;;;;N;;;;; +0811;SAMARITAN LETTER TSAADIY;Lo;0;R;;;;;N;;;;; +0812;SAMARITAN LETTER QUF;Lo;0;R;;;;;N;;;;; +0813;SAMARITAN LETTER RISH;Lo;0;R;;;;;N;;;;; +0814;SAMARITAN LETTER SHAN;Lo;0;R;;;;;N;;;;; +0815;SAMARITAN LETTER TAAF;Lo;0;R;;;;;N;;;;; +0816;SAMARITAN MARK IN;Mn;230;NSM;;;;;N;;;;; +0817;SAMARITAN MARK IN-ALAF;Mn;230;NSM;;;;;N;;;;; +0818;SAMARITAN MARK OCCLUSION;Mn;230;NSM;;;;;N;;;;; +0819;SAMARITAN MARK DAGESH;Mn;230;NSM;;;;;N;;;;; +081A;SAMARITAN MODIFIER LETTER EPENTHETIC YUT;Lm;0;R;;;;;N;;;;; +081B;SAMARITAN MARK EPENTHETIC YUT;Mn;230;NSM;;;;;N;;;;; +081C;SAMARITAN VOWEL SIGN LONG E;Mn;230;NSM;;;;;N;;;;; +081D;SAMARITAN VOWEL SIGN E;Mn;230;NSM;;;;;N;;;;; +081E;SAMARITAN VOWEL SIGN OVERLONG AA;Mn;230;NSM;;;;;N;;;;; +081F;SAMARITAN VOWEL SIGN LONG AA;Mn;230;NSM;;;;;N;;;;; +0820;SAMARITAN VOWEL SIGN AA;Mn;230;NSM;;;;;N;;;;; +0821;SAMARITAN VOWEL SIGN OVERLONG A;Mn;230;NSM;;;;;N;;;;; +0822;SAMARITAN VOWEL SIGN LONG A;Mn;230;NSM;;;;;N;;;;; +0823;SAMARITAN VOWEL SIGN A;Mn;230;NSM;;;;;N;;;;; +0824;SAMARITAN MODIFIER LETTER SHORT A;Lm;0;R;;;;;N;;;;; +0825;SAMARITAN VOWEL SIGN SHORT A;Mn;230;NSM;;;;;N;;;;; +0826;SAMARITAN VOWEL SIGN LONG U;Mn;230;NSM;;;;;N;;;;; +0827;SAMARITAN VOWEL SIGN U;Mn;230;NSM;;;;;N;;;;; +0828;SAMARITAN MODIFIER LETTER I;Lm;0;R;;;;;N;;;;; +0829;SAMARITAN VOWEL SIGN LONG I;Mn;230;NSM;;;;;N;;;;; +082A;SAMARITAN VOWEL SIGN I;Mn;230;NSM;;;;;N;;;;; +082B;SAMARITAN VOWEL SIGN O;Mn;230;NSM;;;;;N;;;;; +082C;SAMARITAN VOWEL SIGN SUKUN;Mn;230;NSM;;;;;N;;;;; +082D;SAMARITAN MARK NEQUDAA;Mn;230;NSM;;;;;N;;;;; +0830;SAMARITAN PUNCTUATION NEQUDAA;Po;0;R;;;;;N;;;;; +0831;SAMARITAN PUNCTUATION AFSAAQ;Po;0;R;;;;;N;;;;; +0832;SAMARITAN PUNCTUATION ANGED;Po;0;R;;;;;N;;;;; +0833;SAMARITAN PUNCTUATION BAU;Po;0;R;;;;;N;;;;; +0834;SAMARITAN PUNCTUATION ATMAAU;Po;0;R;;;;;N;;;;; +0835;SAMARITAN PUNCTUATION SHIYYAALAA;Po;0;R;;;;;N;;;;; +0836;SAMARITAN ABBREVIATION MARK;Po;0;R;;;;;N;;;;; +0837;SAMARITAN PUNCTUATION MELODIC QITSA;Po;0;R;;;;;N;;;;; +0838;SAMARITAN PUNCTUATION ZIQAA;Po;0;R;;;;;N;;;;; +0839;SAMARITAN PUNCTUATION QITSA;Po;0;R;;;;;N;;;;; +083A;SAMARITAN PUNCTUATION ZAEF;Po;0;R;;;;;N;;;;; +083B;SAMARITAN PUNCTUATION TURU;Po;0;R;;;;;N;;;;; +083C;SAMARITAN PUNCTUATION ARKAANU;Po;0;R;;;;;N;;;;; +083D;SAMARITAN PUNCTUATION SOF MASHFAAT;Po;0;R;;;;;N;;;;; +083E;SAMARITAN PUNCTUATION ANNAAU;Po;0;R;;;;;N;;;;; +0840;MANDAIC LETTER HALQA;Lo;0;R;;;;;N;;;;; +0841;MANDAIC LETTER AB;Lo;0;R;;;;;N;;;;; +0842;MANDAIC LETTER AG;Lo;0;R;;;;;N;;;;; +0843;MANDAIC LETTER AD;Lo;0;R;;;;;N;;;;; +0844;MANDAIC LETTER AH;Lo;0;R;;;;;N;;;;; +0845;MANDAIC LETTER USHENNA;Lo;0;R;;;;;N;;;;; +0846;MANDAIC LETTER AZ;Lo;0;R;;;;;N;;;;; +0847;MANDAIC LETTER IT;Lo;0;R;;;;;N;;;;; +0848;MANDAIC LETTER ATT;Lo;0;R;;;;;N;;;;; +0849;MANDAIC LETTER AKSA;Lo;0;R;;;;;N;;;;; +084A;MANDAIC LETTER AK;Lo;0;R;;;;;N;;;;; +084B;MANDAIC LETTER AL;Lo;0;R;;;;;N;;;;; +084C;MANDAIC LETTER AM;Lo;0;R;;;;;N;;;;; +084D;MANDAIC LETTER AN;Lo;0;R;;;;;N;;;;; +084E;MANDAIC LETTER AS;Lo;0;R;;;;;N;;;;; +084F;MANDAIC LETTER IN;Lo;0;R;;;;;N;;;;; +0850;MANDAIC LETTER AP;Lo;0;R;;;;;N;;;;; +0851;MANDAIC LETTER ASZ;Lo;0;R;;;;;N;;;;; +0852;MANDAIC LETTER AQ;Lo;0;R;;;;;N;;;;; +0853;MANDAIC LETTER AR;Lo;0;R;;;;;N;;;;; +0854;MANDAIC LETTER ASH;Lo;0;R;;;;;N;;;;; +0855;MANDAIC LETTER AT;Lo;0;R;;;;;N;;;;; +0856;MANDAIC LETTER DUSHENNA;Lo;0;R;;;;;N;;;;; +0857;MANDAIC LETTER KAD;Lo;0;R;;;;;N;;;;; +0858;MANDAIC LETTER AIN;Lo;0;R;;;;;N;;;;; +0859;MANDAIC AFFRICATION MARK;Mn;220;NSM;;;;;N;;;;; +085A;MANDAIC VOCALIZATION MARK;Mn;220;NSM;;;;;N;;;;; +085B;MANDAIC GEMINATION MARK;Mn;220;NSM;;;;;N;;;;; +085E;MANDAIC PUNCTUATION;Po;0;R;;;;;N;;;;; +0860;SYRIAC LETTER MALAYALAM NGA;Lo;0;AL;;;;;N;;;;; +0861;SYRIAC LETTER MALAYALAM JA;Lo;0;AL;;;;;N;;;;; +0862;SYRIAC LETTER MALAYALAM NYA;Lo;0;AL;;;;;N;;;;; +0863;SYRIAC LETTER MALAYALAM TTA;Lo;0;AL;;;;;N;;;;; +0864;SYRIAC LETTER MALAYALAM NNA;Lo;0;AL;;;;;N;;;;; +0865;SYRIAC LETTER MALAYALAM NNNA;Lo;0;AL;;;;;N;;;;; +0866;SYRIAC LETTER MALAYALAM BHA;Lo;0;AL;;;;;N;;;;; +0867;SYRIAC LETTER MALAYALAM RA;Lo;0;AL;;;;;N;;;;; +0868;SYRIAC LETTER MALAYALAM LLA;Lo;0;AL;;;;;N;;;;; +0869;SYRIAC LETTER MALAYALAM LLLA;Lo;0;AL;;;;;N;;;;; +086A;SYRIAC LETTER MALAYALAM SSA;Lo;0;AL;;;;;N;;;;; +08A0;ARABIC LETTER BEH WITH SMALL V BELOW;Lo;0;AL;;;;;N;;;;; +08A1;ARABIC LETTER BEH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;;;;; +08A2;ARABIC LETTER JEEM WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +08A3;ARABIC LETTER TAH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +08A4;ARABIC LETTER FEH WITH DOT BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +08A5;ARABIC LETTER QAF WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +08A6;ARABIC LETTER LAM WITH DOUBLE BAR;Lo;0;AL;;;;;N;;;;; +08A7;ARABIC LETTER MEEM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +08A8;ARABIC LETTER YEH WITH TWO DOTS BELOW AND HAMZA ABOVE;Lo;0;AL;;;;;N;;;;; +08A9;ARABIC LETTER YEH WITH TWO DOTS BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;; +08AA;ARABIC LETTER REH WITH LOOP;Lo;0;AL;;;;;N;;;;; +08AB;ARABIC LETTER WAW WITH DOT WITHIN;Lo;0;AL;;;;;N;;;;; +08AC;ARABIC LETTER ROHINGYA YEH;Lo;0;AL;;;;;N;;;;; +08AD;ARABIC LETTER LOW ALEF;Lo;0;AL;;;;;N;;;;; +08AE;ARABIC LETTER DAL WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; +08AF;ARABIC LETTER SAD WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; +08B0;ARABIC LETTER GAF WITH INVERTED STROKE;Lo;0;AL;;;;;N;;;;; +08B1;ARABIC LETTER STRAIGHT WAW;Lo;0;AL;;;;;N;;;;; +08B2;ARABIC LETTER ZAIN WITH INVERTED V ABOVE;Lo;0;AL;;;;;N;;;;; +08B3;ARABIC LETTER AIN WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; +08B4;ARABIC LETTER KAF WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; +08B6;ARABIC LETTER BEH WITH SMALL MEEM ABOVE;Lo;0;AL;;;;;N;;;;; +08B7;ARABIC LETTER PEH WITH SMALL MEEM ABOVE;Lo;0;AL;;;;;N;;;;; +08B8;ARABIC LETTER TEH WITH SMALL TEH ABOVE;Lo;0;AL;;;;;N;;;;; +08B9;ARABIC LETTER REH WITH SMALL NOON ABOVE;Lo;0;AL;;;;;N;;;;; +08BA;ARABIC LETTER YEH WITH TWO DOTS BELOW AND SMALL NOON ABOVE;Lo;0;AL;;;;;N;;;;; +08BB;ARABIC LETTER AFRICAN FEH;Lo;0;AL;;;;;N;;;;; +08BC;ARABIC LETTER AFRICAN QAF;Lo;0;AL;;;;;N;;;;; +08BD;ARABIC LETTER AFRICAN NOON;Lo;0;AL;;;;;N;;;;; +08D3;ARABIC SMALL LOW WAW;Mn;220;NSM;;;;;N;;;;; +08D4;ARABIC SMALL HIGH WORD AR-RUB;Mn;230;NSM;;;;;N;;;;; +08D5;ARABIC SMALL HIGH SAD;Mn;230;NSM;;;;;N;;;;; +08D6;ARABIC SMALL HIGH AIN;Mn;230;NSM;;;;;N;;;;; +08D7;ARABIC SMALL HIGH QAF;Mn;230;NSM;;;;;N;;;;; +08D8;ARABIC SMALL HIGH NOON WITH KASRA;Mn;230;NSM;;;;;N;;;;; +08D9;ARABIC SMALL LOW NOON WITH KASRA;Mn;230;NSM;;;;;N;;;;; +08DA;ARABIC SMALL HIGH WORD ATH-THALATHA;Mn;230;NSM;;;;;N;;;;; +08DB;ARABIC SMALL HIGH WORD AS-SAJDA;Mn;230;NSM;;;;;N;;;;; +08DC;ARABIC SMALL HIGH WORD AN-NISF;Mn;230;NSM;;;;;N;;;;; +08DD;ARABIC SMALL HIGH WORD SAKTA;Mn;230;NSM;;;;;N;;;;; +08DE;ARABIC SMALL HIGH WORD QIF;Mn;230;NSM;;;;;N;;;;; +08DF;ARABIC SMALL HIGH WORD WAQFA;Mn;230;NSM;;;;;N;;;;; +08E0;ARABIC SMALL HIGH FOOTNOTE MARKER;Mn;230;NSM;;;;;N;;;;; +08E1;ARABIC SMALL HIGH SIGN SAFHA;Mn;230;NSM;;;;;N;;;;; +08E2;ARABIC DISPUTED END OF AYAH;Cf;0;AN;;;;;N;;;;; +08E3;ARABIC TURNED DAMMA BELOW;Mn;220;NSM;;;;;N;;;;; +08E4;ARABIC CURLY FATHA;Mn;230;NSM;;;;;N;;;;; +08E5;ARABIC CURLY DAMMA;Mn;230;NSM;;;;;N;;;;; +08E6;ARABIC CURLY KASRA;Mn;220;NSM;;;;;N;;;;; +08E7;ARABIC CURLY FATHATAN;Mn;230;NSM;;;;;N;;;;; +08E8;ARABIC CURLY DAMMATAN;Mn;230;NSM;;;;;N;;;;; +08E9;ARABIC CURLY KASRATAN;Mn;220;NSM;;;;;N;;;;; +08EA;ARABIC TONE ONE DOT ABOVE;Mn;230;NSM;;;;;N;;;;; +08EB;ARABIC TONE TWO DOTS ABOVE;Mn;230;NSM;;;;;N;;;;; +08EC;ARABIC TONE LOOP ABOVE;Mn;230;NSM;;;;;N;;;;; +08ED;ARABIC TONE ONE DOT BELOW;Mn;220;NSM;;;;;N;;;;; +08EE;ARABIC TONE TWO DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +08EF;ARABIC TONE LOOP BELOW;Mn;220;NSM;;;;;N;;;;; +08F0;ARABIC OPEN FATHATAN;Mn;27;NSM;;;;;N;;;;; +08F1;ARABIC OPEN DAMMATAN;Mn;28;NSM;;;;;N;;;;; +08F2;ARABIC OPEN KASRATAN;Mn;29;NSM;;;;;N;;;;; +08F3;ARABIC SMALL HIGH WAW;Mn;230;NSM;;;;;N;;;;; +08F4;ARABIC FATHA WITH RING;Mn;230;NSM;;;;;N;;;;; +08F5;ARABIC FATHA WITH DOT ABOVE;Mn;230;NSM;;;;;N;;;;; +08F6;ARABIC KASRA WITH DOT BELOW;Mn;220;NSM;;;;;N;;;;; +08F7;ARABIC LEFT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;; +08F8;ARABIC RIGHT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;; +08F9;ARABIC LEFT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;; +08FA;ARABIC RIGHT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;; +08FB;ARABIC DOUBLE RIGHT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;; +08FC;ARABIC DOUBLE RIGHT ARROWHEAD ABOVE WITH DOT;Mn;230;NSM;;;;;N;;;;; +08FD;ARABIC RIGHT ARROWHEAD ABOVE WITH DOT;Mn;230;NSM;;;;;N;;;;; +08FE;ARABIC DAMMA WITH DOT;Mn;230;NSM;;;;;N;;;;; +08FF;ARABIC MARK SIDEWAYS NOON GHUNNA;Mn;230;NSM;;;;;N;;;;; +0900;DEVANAGARI SIGN INVERTED CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0901;DEVANAGARI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0902;DEVANAGARI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +0903;DEVANAGARI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0904;DEVANAGARI LETTER SHORT A;Lo;0;L;;;;;N;;;;; +0905;DEVANAGARI LETTER A;Lo;0;L;;;;;N;;;;; +0906;DEVANAGARI LETTER AA;Lo;0;L;;;;;N;;;;; +0907;DEVANAGARI LETTER I;Lo;0;L;;;;;N;;;;; +0908;DEVANAGARI LETTER II;Lo;0;L;;;;;N;;;;; +0909;DEVANAGARI LETTER U;Lo;0;L;;;;;N;;;;; +090A;DEVANAGARI LETTER UU;Lo;0;L;;;;;N;;;;; +090B;DEVANAGARI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +090C;DEVANAGARI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +090D;DEVANAGARI LETTER CANDRA E;Lo;0;L;;;;;N;;;;; +090E;DEVANAGARI LETTER SHORT E;Lo;0;L;;;;;N;;;;; +090F;DEVANAGARI LETTER E;Lo;0;L;;;;;N;;;;; +0910;DEVANAGARI LETTER AI;Lo;0;L;;;;;N;;;;; +0911;DEVANAGARI LETTER CANDRA O;Lo;0;L;;;;;N;;;;; +0912;DEVANAGARI LETTER SHORT O;Lo;0;L;;;;;N;;;;; +0913;DEVANAGARI LETTER O;Lo;0;L;;;;;N;;;;; +0914;DEVANAGARI LETTER AU;Lo;0;L;;;;;N;;;;; +0915;DEVANAGARI LETTER KA;Lo;0;L;;;;;N;;;;; +0916;DEVANAGARI LETTER KHA;Lo;0;L;;;;;N;;;;; +0917;DEVANAGARI LETTER GA;Lo;0;L;;;;;N;;;;; +0918;DEVANAGARI LETTER GHA;Lo;0;L;;;;;N;;;;; +0919;DEVANAGARI LETTER NGA;Lo;0;L;;;;;N;;;;; +091A;DEVANAGARI LETTER CA;Lo;0;L;;;;;N;;;;; +091B;DEVANAGARI LETTER CHA;Lo;0;L;;;;;N;;;;; +091C;DEVANAGARI LETTER JA;Lo;0;L;;;;;N;;;;; +091D;DEVANAGARI LETTER JHA;Lo;0;L;;;;;N;;;;; +091E;DEVANAGARI LETTER NYA;Lo;0;L;;;;;N;;;;; +091F;DEVANAGARI LETTER TTA;Lo;0;L;;;;;N;;;;; +0920;DEVANAGARI LETTER TTHA;Lo;0;L;;;;;N;;;;; +0921;DEVANAGARI LETTER DDA;Lo;0;L;;;;;N;;;;; +0922;DEVANAGARI LETTER DDHA;Lo;0;L;;;;;N;;;;; +0923;DEVANAGARI LETTER NNA;Lo;0;L;;;;;N;;;;; +0924;DEVANAGARI LETTER TA;Lo;0;L;;;;;N;;;;; +0925;DEVANAGARI LETTER THA;Lo;0;L;;;;;N;;;;; +0926;DEVANAGARI LETTER DA;Lo;0;L;;;;;N;;;;; +0927;DEVANAGARI LETTER DHA;Lo;0;L;;;;;N;;;;; +0928;DEVANAGARI LETTER NA;Lo;0;L;;;;;N;;;;; +0929;DEVANAGARI LETTER NNNA;Lo;0;L;0928 093C;;;;N;;;;; +092A;DEVANAGARI LETTER PA;Lo;0;L;;;;;N;;;;; +092B;DEVANAGARI LETTER PHA;Lo;0;L;;;;;N;;;;; +092C;DEVANAGARI LETTER BA;Lo;0;L;;;;;N;;;;; +092D;DEVANAGARI LETTER BHA;Lo;0;L;;;;;N;;;;; +092E;DEVANAGARI LETTER MA;Lo;0;L;;;;;N;;;;; +092F;DEVANAGARI LETTER YA;Lo;0;L;;;;;N;;;;; +0930;DEVANAGARI LETTER RA;Lo;0;L;;;;;N;;;;; +0931;DEVANAGARI LETTER RRA;Lo;0;L;0930 093C;;;;N;;;;; +0932;DEVANAGARI LETTER LA;Lo;0;L;;;;;N;;;;; +0933;DEVANAGARI LETTER LLA;Lo;0;L;;;;;N;;;;; +0934;DEVANAGARI LETTER LLLA;Lo;0;L;0933 093C;;;;N;;;;; +0935;DEVANAGARI LETTER VA;Lo;0;L;;;;;N;;;;; +0936;DEVANAGARI LETTER SHA;Lo;0;L;;;;;N;;;;; +0937;DEVANAGARI LETTER SSA;Lo;0;L;;;;;N;;;;; +0938;DEVANAGARI LETTER SA;Lo;0;L;;;;;N;;;;; +0939;DEVANAGARI LETTER HA;Lo;0;L;;;;;N;;;;; +093A;DEVANAGARI VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;; +093B;DEVANAGARI VOWEL SIGN OOE;Mc;0;L;;;;;N;;;;; +093C;DEVANAGARI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +093D;DEVANAGARI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +093E;DEVANAGARI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +093F;DEVANAGARI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0940;DEVANAGARI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0941;DEVANAGARI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0942;DEVANAGARI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0943;DEVANAGARI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +0944;DEVANAGARI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +0945;DEVANAGARI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;; +0946;DEVANAGARI VOWEL SIGN SHORT E;Mn;0;NSM;;;;;N;;;;; +0947;DEVANAGARI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +0948;DEVANAGARI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +0949;DEVANAGARI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;; +094A;DEVANAGARI VOWEL SIGN SHORT O;Mc;0;L;;;;;N;;;;; +094B;DEVANAGARI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +094C;DEVANAGARI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +094D;DEVANAGARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +094E;DEVANAGARI VOWEL SIGN PRISHTHAMATRA E;Mc;0;L;;;;;N;;;;; +094F;DEVANAGARI VOWEL SIGN AW;Mc;0;L;;;;;N;;;;; +0950;DEVANAGARI OM;Lo;0;L;;;;;N;;;;; +0951;DEVANAGARI STRESS SIGN UDATTA;Mn;230;NSM;;;;;N;;;;; +0952;DEVANAGARI STRESS SIGN ANUDATTA;Mn;220;NSM;;;;;N;;;;; +0953;DEVANAGARI GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;; +0954;DEVANAGARI ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;; +0955;DEVANAGARI VOWEL SIGN CANDRA LONG E;Mn;0;NSM;;;;;N;;;;; +0956;DEVANAGARI VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;; +0957;DEVANAGARI VOWEL SIGN UUE;Mn;0;NSM;;;;;N;;;;; +0958;DEVANAGARI LETTER QA;Lo;0;L;0915 093C;;;;N;;;;; +0959;DEVANAGARI LETTER KHHA;Lo;0;L;0916 093C;;;;N;;;;; +095A;DEVANAGARI LETTER GHHA;Lo;0;L;0917 093C;;;;N;;;;; +095B;DEVANAGARI LETTER ZA;Lo;0;L;091C 093C;;;;N;;;;; +095C;DEVANAGARI LETTER DDDHA;Lo;0;L;0921 093C;;;;N;;;;; +095D;DEVANAGARI LETTER RHA;Lo;0;L;0922 093C;;;;N;;;;; +095E;DEVANAGARI LETTER FA;Lo;0;L;092B 093C;;;;N;;;;; +095F;DEVANAGARI LETTER YYA;Lo;0;L;092F 093C;;;;N;;;;; +0960;DEVANAGARI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0961;DEVANAGARI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0962;DEVANAGARI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0963;DEVANAGARI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0964;DEVANAGARI DANDA;Po;0;L;;;;;N;;;;; +0965;DEVANAGARI DOUBLE DANDA;Po;0;L;;;;;N;;;;; +0966;DEVANAGARI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0967;DEVANAGARI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0968;DEVANAGARI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0969;DEVANAGARI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +096A;DEVANAGARI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +096B;DEVANAGARI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +096C;DEVANAGARI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +096D;DEVANAGARI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +096E;DEVANAGARI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +096F;DEVANAGARI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0970;DEVANAGARI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +0971;DEVANAGARI SIGN HIGH SPACING DOT;Lm;0;L;;;;;N;;;;; +0972;DEVANAGARI LETTER CANDRA A;Lo;0;L;;;;;N;;;;; +0973;DEVANAGARI LETTER OE;Lo;0;L;;;;;N;;;;; +0974;DEVANAGARI LETTER OOE;Lo;0;L;;;;;N;;;;; +0975;DEVANAGARI LETTER AW;Lo;0;L;;;;;N;;;;; +0976;DEVANAGARI LETTER UE;Lo;0;L;;;;;N;;;;; +0977;DEVANAGARI LETTER UUE;Lo;0;L;;;;;N;;;;; +0978;DEVANAGARI LETTER MARWARI DDA;Lo;0;L;;;;;N;;;;; +0979;DEVANAGARI LETTER ZHA;Lo;0;L;;;;;N;;;;; +097A;DEVANAGARI LETTER HEAVY YA;Lo;0;L;;;;;N;;;;; +097B;DEVANAGARI LETTER GGA;Lo;0;L;;;;;N;;;;; +097C;DEVANAGARI LETTER JJA;Lo;0;L;;;;;N;;;;; +097D;DEVANAGARI LETTER GLOTTAL STOP;Lo;0;L;;;;;N;;;;; +097E;DEVANAGARI LETTER DDDA;Lo;0;L;;;;;N;;;;; +097F;DEVANAGARI LETTER BBA;Lo;0;L;;;;;N;;;;; +0980;BENGALI ANJI;Lo;0;L;;;;;N;;;;; +0981;BENGALI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0982;BENGALI SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0983;BENGALI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0985;BENGALI LETTER A;Lo;0;L;;;;;N;;;;; +0986;BENGALI LETTER AA;Lo;0;L;;;;;N;;;;; +0987;BENGALI LETTER I;Lo;0;L;;;;;N;;;;; +0988;BENGALI LETTER II;Lo;0;L;;;;;N;;;;; +0989;BENGALI LETTER U;Lo;0;L;;;;;N;;;;; +098A;BENGALI LETTER UU;Lo;0;L;;;;;N;;;;; +098B;BENGALI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +098C;BENGALI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +098F;BENGALI LETTER E;Lo;0;L;;;;;N;;;;; +0990;BENGALI LETTER AI;Lo;0;L;;;;;N;;;;; +0993;BENGALI LETTER O;Lo;0;L;;;;;N;;;;; +0994;BENGALI LETTER AU;Lo;0;L;;;;;N;;;;; +0995;BENGALI LETTER KA;Lo;0;L;;;;;N;;;;; +0996;BENGALI LETTER KHA;Lo;0;L;;;;;N;;;;; +0997;BENGALI LETTER GA;Lo;0;L;;;;;N;;;;; +0998;BENGALI LETTER GHA;Lo;0;L;;;;;N;;;;; +0999;BENGALI LETTER NGA;Lo;0;L;;;;;N;;;;; +099A;BENGALI LETTER CA;Lo;0;L;;;;;N;;;;; +099B;BENGALI LETTER CHA;Lo;0;L;;;;;N;;;;; +099C;BENGALI LETTER JA;Lo;0;L;;;;;N;;;;; +099D;BENGALI LETTER JHA;Lo;0;L;;;;;N;;;;; +099E;BENGALI LETTER NYA;Lo;0;L;;;;;N;;;;; +099F;BENGALI LETTER TTA;Lo;0;L;;;;;N;;;;; +09A0;BENGALI LETTER TTHA;Lo;0;L;;;;;N;;;;; +09A1;BENGALI LETTER DDA;Lo;0;L;;;;;N;;;;; +09A2;BENGALI LETTER DDHA;Lo;0;L;;;;;N;;;;; +09A3;BENGALI LETTER NNA;Lo;0;L;;;;;N;;;;; +09A4;BENGALI LETTER TA;Lo;0;L;;;;;N;;;;; +09A5;BENGALI LETTER THA;Lo;0;L;;;;;N;;;;; +09A6;BENGALI LETTER DA;Lo;0;L;;;;;N;;;;; +09A7;BENGALI LETTER DHA;Lo;0;L;;;;;N;;;;; +09A8;BENGALI LETTER NA;Lo;0;L;;;;;N;;;;; +09AA;BENGALI LETTER PA;Lo;0;L;;;;;N;;;;; +09AB;BENGALI LETTER PHA;Lo;0;L;;;;;N;;;;; +09AC;BENGALI LETTER BA;Lo;0;L;;;;;N;;;;; +09AD;BENGALI LETTER BHA;Lo;0;L;;;;;N;;;;; +09AE;BENGALI LETTER MA;Lo;0;L;;;;;N;;;;; +09AF;BENGALI LETTER YA;Lo;0;L;;;;;N;;;;; +09B0;BENGALI LETTER RA;Lo;0;L;;;;;N;;;;; +09B2;BENGALI LETTER LA;Lo;0;L;;;;;N;;;;; +09B6;BENGALI LETTER SHA;Lo;0;L;;;;;N;;;;; +09B7;BENGALI LETTER SSA;Lo;0;L;;;;;N;;;;; +09B8;BENGALI LETTER SA;Lo;0;L;;;;;N;;;;; +09B9;BENGALI LETTER HA;Lo;0;L;;;;;N;;;;; +09BC;BENGALI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +09BD;BENGALI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +09BE;BENGALI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +09BF;BENGALI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +09C0;BENGALI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +09C1;BENGALI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +09C2;BENGALI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +09C3;BENGALI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +09C4;BENGALI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +09C7;BENGALI VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +09C8;BENGALI VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +09CB;BENGALI VOWEL SIGN O;Mc;0;L;09C7 09BE;;;;N;;;;; +09CC;BENGALI VOWEL SIGN AU;Mc;0;L;09C7 09D7;;;;N;;;;; +09CD;BENGALI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +09CE;BENGALI LETTER KHANDA TA;Lo;0;L;;;;;N;;;;; +09D7;BENGALI AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +09DC;BENGALI LETTER RRA;Lo;0;L;09A1 09BC;;;;N;;;;; +09DD;BENGALI LETTER RHA;Lo;0;L;09A2 09BC;;;;N;;;;; +09DF;BENGALI LETTER YYA;Lo;0;L;09AF 09BC;;;;N;;;;; +09E0;BENGALI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +09E1;BENGALI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +09E2;BENGALI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +09E3;BENGALI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +09E6;BENGALI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +09E7;BENGALI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +09E8;BENGALI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +09E9;BENGALI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +09EA;BENGALI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +09EB;BENGALI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +09EC;BENGALI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +09ED;BENGALI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +09EE;BENGALI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +09EF;BENGALI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +09F0;BENGALI LETTER RA WITH MIDDLE DIAGONAL;Lo;0;L;;;;;N;;;;; +09F1;BENGALI LETTER RA WITH LOWER DIAGONAL;Lo;0;L;;;;;N;BENGALI LETTER VA WITH LOWER DIAGONAL;;;; +09F2;BENGALI RUPEE MARK;Sc;0;ET;;;;;N;;;;; +09F3;BENGALI RUPEE SIGN;Sc;0;ET;;;;;N;;;;; +09F4;BENGALI CURRENCY NUMERATOR ONE;No;0;L;;;;1/16;N;;;;; +09F5;BENGALI CURRENCY NUMERATOR TWO;No;0;L;;;;1/8;N;;;;; +09F6;BENGALI CURRENCY NUMERATOR THREE;No;0;L;;;;3/16;N;;;;; +09F7;BENGALI CURRENCY NUMERATOR FOUR;No;0;L;;;;1/4;N;;;;; +09F8;BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR;No;0;L;;;;3/4;N;;;;; +09F9;BENGALI CURRENCY DENOMINATOR SIXTEEN;No;0;L;;;;16;N;;;;; +09FA;BENGALI ISSHAR;So;0;L;;;;;N;;;;; +09FB;BENGALI GANDA MARK;Sc;0;ET;;;;;N;;;;; +09FC;BENGALI LETTER VEDIC ANUSVARA;Lo;0;L;;;;;N;;;;; +09FD;BENGALI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +09FE;BENGALI SANDHI MARK;Mn;230;NSM;;;;;N;;;;; +0A01;GURMUKHI SIGN ADAK BINDI;Mn;0;NSM;;;;;N;;;;; +0A02;GURMUKHI SIGN BINDI;Mn;0;NSM;;;;;N;;;;; +0A03;GURMUKHI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0A05;GURMUKHI LETTER A;Lo;0;L;;;;;N;;;;; +0A06;GURMUKHI LETTER AA;Lo;0;L;;;;;N;;;;; +0A07;GURMUKHI LETTER I;Lo;0;L;;;;;N;;;;; +0A08;GURMUKHI LETTER II;Lo;0;L;;;;;N;;;;; +0A09;GURMUKHI LETTER U;Lo;0;L;;;;;N;;;;; +0A0A;GURMUKHI LETTER UU;Lo;0;L;;;;;N;;;;; +0A0F;GURMUKHI LETTER EE;Lo;0;L;;;;;N;;;;; +0A10;GURMUKHI LETTER AI;Lo;0;L;;;;;N;;;;; +0A13;GURMUKHI LETTER OO;Lo;0;L;;;;;N;;;;; +0A14;GURMUKHI LETTER AU;Lo;0;L;;;;;N;;;;; +0A15;GURMUKHI LETTER KA;Lo;0;L;;;;;N;;;;; +0A16;GURMUKHI LETTER KHA;Lo;0;L;;;;;N;;;;; +0A17;GURMUKHI LETTER GA;Lo;0;L;;;;;N;;;;; +0A18;GURMUKHI LETTER GHA;Lo;0;L;;;;;N;;;;; +0A19;GURMUKHI LETTER NGA;Lo;0;L;;;;;N;;;;; +0A1A;GURMUKHI LETTER CA;Lo;0;L;;;;;N;;;;; +0A1B;GURMUKHI LETTER CHA;Lo;0;L;;;;;N;;;;; +0A1C;GURMUKHI LETTER JA;Lo;0;L;;;;;N;;;;; +0A1D;GURMUKHI LETTER JHA;Lo;0;L;;;;;N;;;;; +0A1E;GURMUKHI LETTER NYA;Lo;0;L;;;;;N;;;;; +0A1F;GURMUKHI LETTER TTA;Lo;0;L;;;;;N;;;;; +0A20;GURMUKHI LETTER TTHA;Lo;0;L;;;;;N;;;;; +0A21;GURMUKHI LETTER DDA;Lo;0;L;;;;;N;;;;; +0A22;GURMUKHI LETTER DDHA;Lo;0;L;;;;;N;;;;; +0A23;GURMUKHI LETTER NNA;Lo;0;L;;;;;N;;;;; +0A24;GURMUKHI LETTER TA;Lo;0;L;;;;;N;;;;; +0A25;GURMUKHI LETTER THA;Lo;0;L;;;;;N;;;;; +0A26;GURMUKHI LETTER DA;Lo;0;L;;;;;N;;;;; +0A27;GURMUKHI LETTER DHA;Lo;0;L;;;;;N;;;;; +0A28;GURMUKHI LETTER NA;Lo;0;L;;;;;N;;;;; +0A2A;GURMUKHI LETTER PA;Lo;0;L;;;;;N;;;;; +0A2B;GURMUKHI LETTER PHA;Lo;0;L;;;;;N;;;;; +0A2C;GURMUKHI LETTER BA;Lo;0;L;;;;;N;;;;; +0A2D;GURMUKHI LETTER BHA;Lo;0;L;;;;;N;;;;; +0A2E;GURMUKHI LETTER MA;Lo;0;L;;;;;N;;;;; +0A2F;GURMUKHI LETTER YA;Lo;0;L;;;;;N;;;;; +0A30;GURMUKHI LETTER RA;Lo;0;L;;;;;N;;;;; +0A32;GURMUKHI LETTER LA;Lo;0;L;;;;;N;;;;; +0A33;GURMUKHI LETTER LLA;Lo;0;L;0A32 0A3C;;;;N;;;;; +0A35;GURMUKHI LETTER VA;Lo;0;L;;;;;N;;;;; +0A36;GURMUKHI LETTER SHA;Lo;0;L;0A38 0A3C;;;;N;;;;; +0A38;GURMUKHI LETTER SA;Lo;0;L;;;;;N;;;;; +0A39;GURMUKHI LETTER HA;Lo;0;L;;;;;N;;;;; +0A3C;GURMUKHI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +0A3E;GURMUKHI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0A3F;GURMUKHI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0A40;GURMUKHI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0A41;GURMUKHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0A42;GURMUKHI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0A47;GURMUKHI VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;; +0A48;GURMUKHI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +0A4B;GURMUKHI VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;; +0A4C;GURMUKHI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +0A4D;GURMUKHI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0A51;GURMUKHI SIGN UDAAT;Mn;0;NSM;;;;;N;;;;; +0A59;GURMUKHI LETTER KHHA;Lo;0;L;0A16 0A3C;;;;N;;;;; +0A5A;GURMUKHI LETTER GHHA;Lo;0;L;0A17 0A3C;;;;N;;;;; +0A5B;GURMUKHI LETTER ZA;Lo;0;L;0A1C 0A3C;;;;N;;;;; +0A5C;GURMUKHI LETTER RRA;Lo;0;L;;;;;N;;;;; +0A5E;GURMUKHI LETTER FA;Lo;0;L;0A2B 0A3C;;;;N;;;;; +0A66;GURMUKHI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0A67;GURMUKHI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0A68;GURMUKHI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0A69;GURMUKHI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0A6A;GURMUKHI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0A6B;GURMUKHI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0A6C;GURMUKHI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0A6D;GURMUKHI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0A6E;GURMUKHI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0A6F;GURMUKHI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0A70;GURMUKHI TIPPI;Mn;0;NSM;;;;;N;;;;; +0A71;GURMUKHI ADDAK;Mn;0;NSM;;;;;N;;;;; +0A72;GURMUKHI IRI;Lo;0;L;;;;;N;;;;; +0A73;GURMUKHI URA;Lo;0;L;;;;;N;;;;; +0A74;GURMUKHI EK ONKAR;Lo;0;L;;;;;N;;;;; +0A75;GURMUKHI SIGN YAKASH;Mn;0;NSM;;;;;N;;;;; +0A76;GURMUKHI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +0A81;GUJARATI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0A82;GUJARATI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +0A83;GUJARATI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0A85;GUJARATI LETTER A;Lo;0;L;;;;;N;;;;; +0A86;GUJARATI LETTER AA;Lo;0;L;;;;;N;;;;; +0A87;GUJARATI LETTER I;Lo;0;L;;;;;N;;;;; +0A88;GUJARATI LETTER II;Lo;0;L;;;;;N;;;;; +0A89;GUJARATI LETTER U;Lo;0;L;;;;;N;;;;; +0A8A;GUJARATI LETTER UU;Lo;0;L;;;;;N;;;;; +0A8B;GUJARATI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0A8C;GUJARATI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0A8D;GUJARATI VOWEL CANDRA E;Lo;0;L;;;;;N;;;;; +0A8F;GUJARATI LETTER E;Lo;0;L;;;;;N;;;;; +0A90;GUJARATI LETTER AI;Lo;0;L;;;;;N;;;;; +0A91;GUJARATI VOWEL CANDRA O;Lo;0;L;;;;;N;;;;; +0A93;GUJARATI LETTER O;Lo;0;L;;;;;N;;;;; +0A94;GUJARATI LETTER AU;Lo;0;L;;;;;N;;;;; +0A95;GUJARATI LETTER KA;Lo;0;L;;;;;N;;;;; +0A96;GUJARATI LETTER KHA;Lo;0;L;;;;;N;;;;; +0A97;GUJARATI LETTER GA;Lo;0;L;;;;;N;;;;; +0A98;GUJARATI LETTER GHA;Lo;0;L;;;;;N;;;;; +0A99;GUJARATI LETTER NGA;Lo;0;L;;;;;N;;;;; +0A9A;GUJARATI LETTER CA;Lo;0;L;;;;;N;;;;; +0A9B;GUJARATI LETTER CHA;Lo;0;L;;;;;N;;;;; +0A9C;GUJARATI LETTER JA;Lo;0;L;;;;;N;;;;; +0A9D;GUJARATI LETTER JHA;Lo;0;L;;;;;N;;;;; +0A9E;GUJARATI LETTER NYA;Lo;0;L;;;;;N;;;;; +0A9F;GUJARATI LETTER TTA;Lo;0;L;;;;;N;;;;; +0AA0;GUJARATI LETTER TTHA;Lo;0;L;;;;;N;;;;; +0AA1;GUJARATI LETTER DDA;Lo;0;L;;;;;N;;;;; +0AA2;GUJARATI LETTER DDHA;Lo;0;L;;;;;N;;;;; +0AA3;GUJARATI LETTER NNA;Lo;0;L;;;;;N;;;;; +0AA4;GUJARATI LETTER TA;Lo;0;L;;;;;N;;;;; +0AA5;GUJARATI LETTER THA;Lo;0;L;;;;;N;;;;; +0AA6;GUJARATI LETTER DA;Lo;0;L;;;;;N;;;;; +0AA7;GUJARATI LETTER DHA;Lo;0;L;;;;;N;;;;; +0AA8;GUJARATI LETTER NA;Lo;0;L;;;;;N;;;;; +0AAA;GUJARATI LETTER PA;Lo;0;L;;;;;N;;;;; +0AAB;GUJARATI LETTER PHA;Lo;0;L;;;;;N;;;;; +0AAC;GUJARATI LETTER BA;Lo;0;L;;;;;N;;;;; +0AAD;GUJARATI LETTER BHA;Lo;0;L;;;;;N;;;;; +0AAE;GUJARATI LETTER MA;Lo;0;L;;;;;N;;;;; +0AAF;GUJARATI LETTER YA;Lo;0;L;;;;;N;;;;; +0AB0;GUJARATI LETTER RA;Lo;0;L;;;;;N;;;;; +0AB2;GUJARATI LETTER LA;Lo;0;L;;;;;N;;;;; +0AB3;GUJARATI LETTER LLA;Lo;0;L;;;;;N;;;;; +0AB5;GUJARATI LETTER VA;Lo;0;L;;;;;N;;;;; +0AB6;GUJARATI LETTER SHA;Lo;0;L;;;;;N;;;;; +0AB7;GUJARATI LETTER SSA;Lo;0;L;;;;;N;;;;; +0AB8;GUJARATI LETTER SA;Lo;0;L;;;;;N;;;;; +0AB9;GUJARATI LETTER HA;Lo;0;L;;;;;N;;;;; +0ABC;GUJARATI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +0ABD;GUJARATI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +0ABE;GUJARATI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0ABF;GUJARATI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0AC0;GUJARATI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0AC1;GUJARATI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0AC2;GUJARATI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0AC3;GUJARATI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +0AC4;GUJARATI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +0AC5;GUJARATI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;; +0AC7;GUJARATI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +0AC8;GUJARATI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +0AC9;GUJARATI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;; +0ACB;GUJARATI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +0ACC;GUJARATI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +0ACD;GUJARATI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0AD0;GUJARATI OM;Lo;0;L;;;;;N;;;;; +0AE0;GUJARATI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0AE1;GUJARATI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0AE2;GUJARATI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0AE3;GUJARATI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0AE6;GUJARATI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0AE7;GUJARATI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0AE8;GUJARATI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0AE9;GUJARATI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0AEA;GUJARATI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0AEB;GUJARATI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0AEC;GUJARATI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0AED;GUJARATI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0AEE;GUJARATI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0AEF;GUJARATI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0AF0;GUJARATI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +0AF1;GUJARATI RUPEE SIGN;Sc;0;ET;;;;;N;;;;; +0AF9;GUJARATI LETTER ZHA;Lo;0;L;;;;;N;;;;; +0AFA;GUJARATI SIGN SUKUN;Mn;0;NSM;;;;;N;;;;; +0AFB;GUJARATI SIGN SHADDA;Mn;0;NSM;;;;;N;;;;; +0AFC;GUJARATI SIGN MADDAH;Mn;0;NSM;;;;;N;;;;; +0AFD;GUJARATI SIGN THREE-DOT NUKTA ABOVE;Mn;0;NSM;;;;;N;;;;; +0AFE;GUJARATI SIGN CIRCLE NUKTA ABOVE;Mn;0;NSM;;;;;N;;;;; +0AFF;GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE;Mn;0;NSM;;;;;N;;;;; +0B01;ORIYA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0B02;ORIYA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0B03;ORIYA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0B05;ORIYA LETTER A;Lo;0;L;;;;;N;;;;; +0B06;ORIYA LETTER AA;Lo;0;L;;;;;N;;;;; +0B07;ORIYA LETTER I;Lo;0;L;;;;;N;;;;; +0B08;ORIYA LETTER II;Lo;0;L;;;;;N;;;;; +0B09;ORIYA LETTER U;Lo;0;L;;;;;N;;;;; +0B0A;ORIYA LETTER UU;Lo;0;L;;;;;N;;;;; +0B0B;ORIYA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0B0C;ORIYA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0B0F;ORIYA LETTER E;Lo;0;L;;;;;N;;;;; +0B10;ORIYA LETTER AI;Lo;0;L;;;;;N;;;;; +0B13;ORIYA LETTER O;Lo;0;L;;;;;N;;;;; +0B14;ORIYA LETTER AU;Lo;0;L;;;;;N;;;;; +0B15;ORIYA LETTER KA;Lo;0;L;;;;;N;;;;; +0B16;ORIYA LETTER KHA;Lo;0;L;;;;;N;;;;; +0B17;ORIYA LETTER GA;Lo;0;L;;;;;N;;;;; +0B18;ORIYA LETTER GHA;Lo;0;L;;;;;N;;;;; +0B19;ORIYA LETTER NGA;Lo;0;L;;;;;N;;;;; +0B1A;ORIYA LETTER CA;Lo;0;L;;;;;N;;;;; +0B1B;ORIYA LETTER CHA;Lo;0;L;;;;;N;;;;; +0B1C;ORIYA LETTER JA;Lo;0;L;;;;;N;;;;; +0B1D;ORIYA LETTER JHA;Lo;0;L;;;;;N;;;;; +0B1E;ORIYA LETTER NYA;Lo;0;L;;;;;N;;;;; +0B1F;ORIYA LETTER TTA;Lo;0;L;;;;;N;;;;; +0B20;ORIYA LETTER TTHA;Lo;0;L;;;;;N;;;;; +0B21;ORIYA LETTER DDA;Lo;0;L;;;;;N;;;;; +0B22;ORIYA LETTER DDHA;Lo;0;L;;;;;N;;;;; +0B23;ORIYA LETTER NNA;Lo;0;L;;;;;N;;;;; +0B24;ORIYA LETTER TA;Lo;0;L;;;;;N;;;;; +0B25;ORIYA LETTER THA;Lo;0;L;;;;;N;;;;; +0B26;ORIYA LETTER DA;Lo;0;L;;;;;N;;;;; +0B27;ORIYA LETTER DHA;Lo;0;L;;;;;N;;;;; +0B28;ORIYA LETTER NA;Lo;0;L;;;;;N;;;;; +0B2A;ORIYA LETTER PA;Lo;0;L;;;;;N;;;;; +0B2B;ORIYA LETTER PHA;Lo;0;L;;;;;N;;;;; +0B2C;ORIYA LETTER BA;Lo;0;L;;;;;N;;;;; +0B2D;ORIYA LETTER BHA;Lo;0;L;;;;;N;;;;; +0B2E;ORIYA LETTER MA;Lo;0;L;;;;;N;;;;; +0B2F;ORIYA LETTER YA;Lo;0;L;;;;;N;;;;; +0B30;ORIYA LETTER RA;Lo;0;L;;;;;N;;;;; +0B32;ORIYA LETTER LA;Lo;0;L;;;;;N;;;;; +0B33;ORIYA LETTER LLA;Lo;0;L;;;;;N;;;;; +0B35;ORIYA LETTER VA;Lo;0;L;;;;;N;;;;; +0B36;ORIYA LETTER SHA;Lo;0;L;;;;;N;;;;; +0B37;ORIYA LETTER SSA;Lo;0;L;;;;;N;;;;; +0B38;ORIYA LETTER SA;Lo;0;L;;;;;N;;;;; +0B39;ORIYA LETTER HA;Lo;0;L;;;;;N;;;;; +0B3C;ORIYA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +0B3D;ORIYA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +0B3E;ORIYA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0B3F;ORIYA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +0B40;ORIYA VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0B41;ORIYA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0B42;ORIYA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0B43;ORIYA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +0B44;ORIYA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +0B47;ORIYA VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +0B48;ORIYA VOWEL SIGN AI;Mc;0;L;0B47 0B56;;;;N;;;;; +0B4B;ORIYA VOWEL SIGN O;Mc;0;L;0B47 0B3E;;;;N;;;;; +0B4C;ORIYA VOWEL SIGN AU;Mc;0;L;0B47 0B57;;;;N;;;;; +0B4D;ORIYA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0B56;ORIYA AI LENGTH MARK;Mn;0;NSM;;;;;N;;;;; +0B57;ORIYA AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +0B5C;ORIYA LETTER RRA;Lo;0;L;0B21 0B3C;;;;N;;;;; +0B5D;ORIYA LETTER RHA;Lo;0;L;0B22 0B3C;;;;N;;;;; +0B5F;ORIYA LETTER YYA;Lo;0;L;;;;;N;;;;; +0B60;ORIYA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0B61;ORIYA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0B62;ORIYA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0B63;ORIYA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0B66;ORIYA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0B67;ORIYA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0B68;ORIYA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0B69;ORIYA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0B6A;ORIYA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0B6B;ORIYA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0B6C;ORIYA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0B6D;ORIYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0B6E;ORIYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0B6F;ORIYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0B70;ORIYA ISSHAR;So;0;L;;;;;N;;;;; +0B71;ORIYA LETTER WA;Lo;0;L;;;;;N;;;;; +0B72;ORIYA FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;; +0B73;ORIYA FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;; +0B74;ORIYA FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;; +0B75;ORIYA FRACTION ONE SIXTEENTH;No;0;L;;;;1/16;N;;;;; +0B76;ORIYA FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;; +0B77;ORIYA FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;; +0B82;TAMIL SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +0B83;TAMIL SIGN VISARGA;Lo;0;L;;;;;N;;;;; +0B85;TAMIL LETTER A;Lo;0;L;;;;;N;;;;; +0B86;TAMIL LETTER AA;Lo;0;L;;;;;N;;;;; +0B87;TAMIL LETTER I;Lo;0;L;;;;;N;;;;; +0B88;TAMIL LETTER II;Lo;0;L;;;;;N;;;;; +0B89;TAMIL LETTER U;Lo;0;L;;;;;N;;;;; +0B8A;TAMIL LETTER UU;Lo;0;L;;;;;N;;;;; +0B8E;TAMIL LETTER E;Lo;0;L;;;;;N;;;;; +0B8F;TAMIL LETTER EE;Lo;0;L;;;;;N;;;;; +0B90;TAMIL LETTER AI;Lo;0;L;;;;;N;;;;; +0B92;TAMIL LETTER O;Lo;0;L;;;;;N;;;;; +0B93;TAMIL LETTER OO;Lo;0;L;;;;;N;;;;; +0B94;TAMIL LETTER AU;Lo;0;L;0B92 0BD7;;;;N;;;;; +0B95;TAMIL LETTER KA;Lo;0;L;;;;;N;;;;; +0B99;TAMIL LETTER NGA;Lo;0;L;;;;;N;;;;; +0B9A;TAMIL LETTER CA;Lo;0;L;;;;;N;;;;; +0B9C;TAMIL LETTER JA;Lo;0;L;;;;;N;;;;; +0B9E;TAMIL LETTER NYA;Lo;0;L;;;;;N;;;;; +0B9F;TAMIL LETTER TTA;Lo;0;L;;;;;N;;;;; +0BA3;TAMIL LETTER NNA;Lo;0;L;;;;;N;;;;; +0BA4;TAMIL LETTER TA;Lo;0;L;;;;;N;;;;; +0BA8;TAMIL LETTER NA;Lo;0;L;;;;;N;;;;; +0BA9;TAMIL LETTER NNNA;Lo;0;L;;;;;N;;;;; +0BAA;TAMIL LETTER PA;Lo;0;L;;;;;N;;;;; +0BAE;TAMIL LETTER MA;Lo;0;L;;;;;N;;;;; +0BAF;TAMIL LETTER YA;Lo;0;L;;;;;N;;;;; +0BB0;TAMIL LETTER RA;Lo;0;L;;;;;N;;;;; +0BB1;TAMIL LETTER RRA;Lo;0;L;;;;;N;;;;; +0BB2;TAMIL LETTER LA;Lo;0;L;;;;;N;;;;; +0BB3;TAMIL LETTER LLA;Lo;0;L;;;;;N;;;;; +0BB4;TAMIL LETTER LLLA;Lo;0;L;;;;;N;;;;; +0BB5;TAMIL LETTER VA;Lo;0;L;;;;;N;;;;; +0BB6;TAMIL LETTER SHA;Lo;0;L;;;;;N;;;;; +0BB7;TAMIL LETTER SSA;Lo;0;L;;;;;N;;;;; +0BB8;TAMIL LETTER SA;Lo;0;L;;;;;N;;;;; +0BB9;TAMIL LETTER HA;Lo;0;L;;;;;N;;;;; +0BBE;TAMIL VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0BBF;TAMIL VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0BC0;TAMIL VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +0BC1;TAMIL VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +0BC2;TAMIL VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +0BC6;TAMIL VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +0BC7;TAMIL VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; +0BC8;TAMIL VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +0BCA;TAMIL VOWEL SIGN O;Mc;0;L;0BC6 0BBE;;;;N;;;;; +0BCB;TAMIL VOWEL SIGN OO;Mc;0;L;0BC7 0BBE;;;;N;;;;; +0BCC;TAMIL VOWEL SIGN AU;Mc;0;L;0BC6 0BD7;;;;N;;;;; +0BCD;TAMIL SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0BD0;TAMIL OM;Lo;0;L;;;;;N;;;;; +0BD7;TAMIL AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +0BE6;TAMIL DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0BE7;TAMIL DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0BE8;TAMIL DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0BE9;TAMIL DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0BEA;TAMIL DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0BEB;TAMIL DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0BEC;TAMIL DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0BED;TAMIL DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0BEE;TAMIL DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0BEF;TAMIL DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0BF0;TAMIL NUMBER TEN;No;0;L;;;;10;N;;;;; +0BF1;TAMIL NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;; +0BF2;TAMIL NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;; +0BF3;TAMIL DAY SIGN;So;0;ON;;;;;N;;;;; +0BF4;TAMIL MONTH SIGN;So;0;ON;;;;;N;;;;; +0BF5;TAMIL YEAR SIGN;So;0;ON;;;;;N;;;;; +0BF6;TAMIL DEBIT SIGN;So;0;ON;;;;;N;;;;; +0BF7;TAMIL CREDIT SIGN;So;0;ON;;;;;N;;;;; +0BF8;TAMIL AS ABOVE SIGN;So;0;ON;;;;;N;;;;; +0BF9;TAMIL RUPEE SIGN;Sc;0;ET;;;;;N;;;;; +0BFA;TAMIL NUMBER SIGN;So;0;ON;;;;;N;;;;; +0C00;TELUGU SIGN COMBINING CANDRABINDU ABOVE;Mn;0;NSM;;;;;N;;;;; +0C01;TELUGU SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;; +0C02;TELUGU SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0C03;TELUGU SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0C04;TELUGU SIGN COMBINING ANUSVARA ABOVE;Mn;0;NSM;;;;;N;;;;; +0C05;TELUGU LETTER A;Lo;0;L;;;;;N;;;;; +0C06;TELUGU LETTER AA;Lo;0;L;;;;;N;;;;; +0C07;TELUGU LETTER I;Lo;0;L;;;;;N;;;;; +0C08;TELUGU LETTER II;Lo;0;L;;;;;N;;;;; +0C09;TELUGU LETTER U;Lo;0;L;;;;;N;;;;; +0C0A;TELUGU LETTER UU;Lo;0;L;;;;;N;;;;; +0C0B;TELUGU LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0C0C;TELUGU LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0C0E;TELUGU LETTER E;Lo;0;L;;;;;N;;;;; +0C0F;TELUGU LETTER EE;Lo;0;L;;;;;N;;;;; +0C10;TELUGU LETTER AI;Lo;0;L;;;;;N;;;;; +0C12;TELUGU LETTER O;Lo;0;L;;;;;N;;;;; +0C13;TELUGU LETTER OO;Lo;0;L;;;;;N;;;;; +0C14;TELUGU LETTER AU;Lo;0;L;;;;;N;;;;; +0C15;TELUGU LETTER KA;Lo;0;L;;;;;N;;;;; +0C16;TELUGU LETTER KHA;Lo;0;L;;;;;N;;;;; +0C17;TELUGU LETTER GA;Lo;0;L;;;;;N;;;;; +0C18;TELUGU LETTER GHA;Lo;0;L;;;;;N;;;;; +0C19;TELUGU LETTER NGA;Lo;0;L;;;;;N;;;;; +0C1A;TELUGU LETTER CA;Lo;0;L;;;;;N;;;;; +0C1B;TELUGU LETTER CHA;Lo;0;L;;;;;N;;;;; +0C1C;TELUGU LETTER JA;Lo;0;L;;;;;N;;;;; +0C1D;TELUGU LETTER JHA;Lo;0;L;;;;;N;;;;; +0C1E;TELUGU LETTER NYA;Lo;0;L;;;;;N;;;;; +0C1F;TELUGU LETTER TTA;Lo;0;L;;;;;N;;;;; +0C20;TELUGU LETTER TTHA;Lo;0;L;;;;;N;;;;; +0C21;TELUGU LETTER DDA;Lo;0;L;;;;;N;;;;; +0C22;TELUGU LETTER DDHA;Lo;0;L;;;;;N;;;;; +0C23;TELUGU LETTER NNA;Lo;0;L;;;;;N;;;;; +0C24;TELUGU LETTER TA;Lo;0;L;;;;;N;;;;; +0C25;TELUGU LETTER THA;Lo;0;L;;;;;N;;;;; +0C26;TELUGU LETTER DA;Lo;0;L;;;;;N;;;;; +0C27;TELUGU LETTER DHA;Lo;0;L;;;;;N;;;;; +0C28;TELUGU LETTER NA;Lo;0;L;;;;;N;;;;; +0C2A;TELUGU LETTER PA;Lo;0;L;;;;;N;;;;; +0C2B;TELUGU LETTER PHA;Lo;0;L;;;;;N;;;;; +0C2C;TELUGU LETTER BA;Lo;0;L;;;;;N;;;;; +0C2D;TELUGU LETTER BHA;Lo;0;L;;;;;N;;;;; +0C2E;TELUGU LETTER MA;Lo;0;L;;;;;N;;;;; +0C2F;TELUGU LETTER YA;Lo;0;L;;;;;N;;;;; +0C30;TELUGU LETTER RA;Lo;0;L;;;;;N;;;;; +0C31;TELUGU LETTER RRA;Lo;0;L;;;;;N;;;;; +0C32;TELUGU LETTER LA;Lo;0;L;;;;;N;;;;; +0C33;TELUGU LETTER LLA;Lo;0;L;;;;;N;;;;; +0C34;TELUGU LETTER LLLA;Lo;0;L;;;;;N;;;;; +0C35;TELUGU LETTER VA;Lo;0;L;;;;;N;;;;; +0C36;TELUGU LETTER SHA;Lo;0;L;;;;;N;;;;; +0C37;TELUGU LETTER SSA;Lo;0;L;;;;;N;;;;; +0C38;TELUGU LETTER SA;Lo;0;L;;;;;N;;;;; +0C39;TELUGU LETTER HA;Lo;0;L;;;;;N;;;;; +0C3D;TELUGU SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +0C3E;TELUGU VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;; +0C3F;TELUGU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +0C40;TELUGU VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +0C41;TELUGU VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +0C42;TELUGU VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +0C43;TELUGU VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; +0C44;TELUGU VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; +0C46;TELUGU VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +0C47;TELUGU VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;; +0C48;TELUGU VOWEL SIGN AI;Mn;0;NSM;0C46 0C56;;;;N;;;;; +0C4A;TELUGU VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +0C4B;TELUGU VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;; +0C4C;TELUGU VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +0C4D;TELUGU SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0C55;TELUGU LENGTH MARK;Mn;84;NSM;;;;;N;;;;; +0C56;TELUGU AI LENGTH MARK;Mn;91;NSM;;;;;N;;;;; +0C58;TELUGU LETTER TSA;Lo;0;L;;;;;N;;;;; +0C59;TELUGU LETTER DZA;Lo;0;L;;;;;N;;;;; +0C5A;TELUGU LETTER RRRA;Lo;0;L;;;;;N;;;;; +0C60;TELUGU LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0C61;TELUGU LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0C62;TELUGU VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0C63;TELUGU VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0C66;TELUGU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0C67;TELUGU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0C68;TELUGU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0C69;TELUGU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0C6A;TELUGU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0C6B;TELUGU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0C6C;TELUGU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0C6D;TELUGU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0C6E;TELUGU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0C6F;TELUGU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0C77;TELUGU SIGN SIDDHAM;Po;0;L;;;;;N;;;;; +0C78;TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR;No;0;ON;;;;0;N;;;;; +0C79;TELUGU FRACTION DIGIT ONE FOR ODD POWERS OF FOUR;No;0;ON;;;;1;N;;;;; +0C7A;TELUGU FRACTION DIGIT TWO FOR ODD POWERS OF FOUR;No;0;ON;;;;2;N;;;;; +0C7B;TELUGU FRACTION DIGIT THREE FOR ODD POWERS OF FOUR;No;0;ON;;;;3;N;;;;; +0C7C;TELUGU FRACTION DIGIT ONE FOR EVEN POWERS OF FOUR;No;0;ON;;;;1;N;;;;; +0C7D;TELUGU FRACTION DIGIT TWO FOR EVEN POWERS OF FOUR;No;0;ON;;;;2;N;;;;; +0C7E;TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR;No;0;ON;;;;3;N;;;;; +0C7F;TELUGU SIGN TUUMU;So;0;L;;;;;N;;;;; +0C80;KANNADA SIGN SPACING CANDRABINDU;Lo;0;L;;;;;N;;;;; +0C81;KANNADA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0C82;KANNADA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0C83;KANNADA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0C84;KANNADA SIGN SIDDHAM;Po;0;L;;;;;N;;;;; +0C85;KANNADA LETTER A;Lo;0;L;;;;;N;;;;; +0C86;KANNADA LETTER AA;Lo;0;L;;;;;N;;;;; +0C87;KANNADA LETTER I;Lo;0;L;;;;;N;;;;; +0C88;KANNADA LETTER II;Lo;0;L;;;;;N;;;;; +0C89;KANNADA LETTER U;Lo;0;L;;;;;N;;;;; +0C8A;KANNADA LETTER UU;Lo;0;L;;;;;N;;;;; +0C8B;KANNADA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0C8C;KANNADA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0C8E;KANNADA LETTER E;Lo;0;L;;;;;N;;;;; +0C8F;KANNADA LETTER EE;Lo;0;L;;;;;N;;;;; +0C90;KANNADA LETTER AI;Lo;0;L;;;;;N;;;;; +0C92;KANNADA LETTER O;Lo;0;L;;;;;N;;;;; +0C93;KANNADA LETTER OO;Lo;0;L;;;;;N;;;;; +0C94;KANNADA LETTER AU;Lo;0;L;;;;;N;;;;; +0C95;KANNADA LETTER KA;Lo;0;L;;;;;N;;;;; +0C96;KANNADA LETTER KHA;Lo;0;L;;;;;N;;;;; +0C97;KANNADA LETTER GA;Lo;0;L;;;;;N;;;;; +0C98;KANNADA LETTER GHA;Lo;0;L;;;;;N;;;;; +0C99;KANNADA LETTER NGA;Lo;0;L;;;;;N;;;;; +0C9A;KANNADA LETTER CA;Lo;0;L;;;;;N;;;;; +0C9B;KANNADA LETTER CHA;Lo;0;L;;;;;N;;;;; +0C9C;KANNADA LETTER JA;Lo;0;L;;;;;N;;;;; +0C9D;KANNADA LETTER JHA;Lo;0;L;;;;;N;;;;; +0C9E;KANNADA LETTER NYA;Lo;0;L;;;;;N;;;;; +0C9F;KANNADA LETTER TTA;Lo;0;L;;;;;N;;;;; +0CA0;KANNADA LETTER TTHA;Lo;0;L;;;;;N;;;;; +0CA1;KANNADA LETTER DDA;Lo;0;L;;;;;N;;;;; +0CA2;KANNADA LETTER DDHA;Lo;0;L;;;;;N;;;;; +0CA3;KANNADA LETTER NNA;Lo;0;L;;;;;N;;;;; +0CA4;KANNADA LETTER TA;Lo;0;L;;;;;N;;;;; +0CA5;KANNADA LETTER THA;Lo;0;L;;;;;N;;;;; +0CA6;KANNADA LETTER DA;Lo;0;L;;;;;N;;;;; +0CA7;KANNADA LETTER DHA;Lo;0;L;;;;;N;;;;; +0CA8;KANNADA LETTER NA;Lo;0;L;;;;;N;;;;; +0CAA;KANNADA LETTER PA;Lo;0;L;;;;;N;;;;; +0CAB;KANNADA LETTER PHA;Lo;0;L;;;;;N;;;;; +0CAC;KANNADA LETTER BA;Lo;0;L;;;;;N;;;;; +0CAD;KANNADA LETTER BHA;Lo;0;L;;;;;N;;;;; +0CAE;KANNADA LETTER MA;Lo;0;L;;;;;N;;;;; +0CAF;KANNADA LETTER YA;Lo;0;L;;;;;N;;;;; +0CB0;KANNADA LETTER RA;Lo;0;L;;;;;N;;;;; +0CB1;KANNADA LETTER RRA;Lo;0;L;;;;;N;;;;; +0CB2;KANNADA LETTER LA;Lo;0;L;;;;;N;;;;; +0CB3;KANNADA LETTER LLA;Lo;0;L;;;;;N;;;;; +0CB5;KANNADA LETTER VA;Lo;0;L;;;;;N;;;;; +0CB6;KANNADA LETTER SHA;Lo;0;L;;;;;N;;;;; +0CB7;KANNADA LETTER SSA;Lo;0;L;;;;;N;;;;; +0CB8;KANNADA LETTER SA;Lo;0;L;;;;;N;;;;; +0CB9;KANNADA LETTER HA;Lo;0;L;;;;;N;;;;; +0CBC;KANNADA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +0CBD;KANNADA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +0CBE;KANNADA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0CBF;KANNADA VOWEL SIGN I;Mn;0;L;;;;;N;;;;; +0CC0;KANNADA VOWEL SIGN II;Mc;0;L;0CBF 0CD5;;;;N;;;;; +0CC1;KANNADA VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +0CC2;KANNADA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +0CC3;KANNADA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; +0CC4;KANNADA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; +0CC6;KANNADA VOWEL SIGN E;Mn;0;L;;;;;N;;;;; +0CC7;KANNADA VOWEL SIGN EE;Mc;0;L;0CC6 0CD5;;;;N;;;;; +0CC8;KANNADA VOWEL SIGN AI;Mc;0;L;0CC6 0CD6;;;;N;;;;; +0CCA;KANNADA VOWEL SIGN O;Mc;0;L;0CC6 0CC2;;;;N;;;;; +0CCB;KANNADA VOWEL SIGN OO;Mc;0;L;0CCA 0CD5;;;;N;;;;; +0CCC;KANNADA VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +0CCD;KANNADA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0CD5;KANNADA LENGTH MARK;Mc;0;L;;;;;N;;;;; +0CD6;KANNADA AI LENGTH MARK;Mc;0;L;;;;;N;;;;; +0CDE;KANNADA LETTER FA;Lo;0;L;;;;;N;;;;; +0CE0;KANNADA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0CE1;KANNADA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0CE2;KANNADA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0CE3;KANNADA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0CE6;KANNADA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0CE7;KANNADA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0CE8;KANNADA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0CE9;KANNADA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0CEA;KANNADA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0CEB;KANNADA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0CEC;KANNADA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0CED;KANNADA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0CEE;KANNADA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0CEF;KANNADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0CF1;KANNADA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;; +0CF2;KANNADA SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;; +0D00;MALAYALAM SIGN COMBINING ANUSVARA ABOVE;Mn;0;NSM;;;;;N;;;;; +0D01;MALAYALAM SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +0D03;MALAYALAM SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0D05;MALAYALAM LETTER A;Lo;0;L;;;;;N;;;;; +0D06;MALAYALAM LETTER AA;Lo;0;L;;;;;N;;;;; +0D07;MALAYALAM LETTER I;Lo;0;L;;;;;N;;;;; +0D08;MALAYALAM LETTER II;Lo;0;L;;;;;N;;;;; +0D09;MALAYALAM LETTER U;Lo;0;L;;;;;N;;;;; +0D0A;MALAYALAM LETTER UU;Lo;0;L;;;;;N;;;;; +0D0B;MALAYALAM LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +0D0C;MALAYALAM LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +0D0E;MALAYALAM LETTER E;Lo;0;L;;;;;N;;;;; +0D0F;MALAYALAM LETTER EE;Lo;0;L;;;;;N;;;;; +0D10;MALAYALAM LETTER AI;Lo;0;L;;;;;N;;;;; +0D12;MALAYALAM LETTER O;Lo;0;L;;;;;N;;;;; +0D13;MALAYALAM LETTER OO;Lo;0;L;;;;;N;;;;; +0D14;MALAYALAM LETTER AU;Lo;0;L;;;;;N;;;;; +0D15;MALAYALAM LETTER KA;Lo;0;L;;;;;N;;;;; +0D16;MALAYALAM LETTER KHA;Lo;0;L;;;;;N;;;;; +0D17;MALAYALAM LETTER GA;Lo;0;L;;;;;N;;;;; +0D18;MALAYALAM LETTER GHA;Lo;0;L;;;;;N;;;;; +0D19;MALAYALAM LETTER NGA;Lo;0;L;;;;;N;;;;; +0D1A;MALAYALAM LETTER CA;Lo;0;L;;;;;N;;;;; +0D1B;MALAYALAM LETTER CHA;Lo;0;L;;;;;N;;;;; +0D1C;MALAYALAM LETTER JA;Lo;0;L;;;;;N;;;;; +0D1D;MALAYALAM LETTER JHA;Lo;0;L;;;;;N;;;;; +0D1E;MALAYALAM LETTER NYA;Lo;0;L;;;;;N;;;;; +0D1F;MALAYALAM LETTER TTA;Lo;0;L;;;;;N;;;;; +0D20;MALAYALAM LETTER TTHA;Lo;0;L;;;;;N;;;;; +0D21;MALAYALAM LETTER DDA;Lo;0;L;;;;;N;;;;; +0D22;MALAYALAM LETTER DDHA;Lo;0;L;;;;;N;;;;; +0D23;MALAYALAM LETTER NNA;Lo;0;L;;;;;N;;;;; +0D24;MALAYALAM LETTER TA;Lo;0;L;;;;;N;;;;; +0D25;MALAYALAM LETTER THA;Lo;0;L;;;;;N;;;;; +0D26;MALAYALAM LETTER DA;Lo;0;L;;;;;N;;;;; +0D27;MALAYALAM LETTER DHA;Lo;0;L;;;;;N;;;;; +0D28;MALAYALAM LETTER NA;Lo;0;L;;;;;N;;;;; +0D29;MALAYALAM LETTER NNNA;Lo;0;L;;;;;N;;;;; +0D2A;MALAYALAM LETTER PA;Lo;0;L;;;;;N;;;;; +0D2B;MALAYALAM LETTER PHA;Lo;0;L;;;;;N;;;;; +0D2C;MALAYALAM LETTER BA;Lo;0;L;;;;;N;;;;; +0D2D;MALAYALAM LETTER BHA;Lo;0;L;;;;;N;;;;; +0D2E;MALAYALAM LETTER MA;Lo;0;L;;;;;N;;;;; +0D2F;MALAYALAM LETTER YA;Lo;0;L;;;;;N;;;;; +0D30;MALAYALAM LETTER RA;Lo;0;L;;;;;N;;;;; +0D31;MALAYALAM LETTER RRA;Lo;0;L;;;;;N;;;;; +0D32;MALAYALAM LETTER LA;Lo;0;L;;;;;N;;;;; +0D33;MALAYALAM LETTER LLA;Lo;0;L;;;;;N;;;;; +0D34;MALAYALAM LETTER LLLA;Lo;0;L;;;;;N;;;;; +0D35;MALAYALAM LETTER VA;Lo;0;L;;;;;N;;;;; +0D36;MALAYALAM LETTER SHA;Lo;0;L;;;;;N;;;;; +0D37;MALAYALAM LETTER SSA;Lo;0;L;;;;;N;;;;; +0D38;MALAYALAM LETTER SA;Lo;0;L;;;;;N;;;;; +0D39;MALAYALAM LETTER HA;Lo;0;L;;;;;N;;;;; +0D3A;MALAYALAM LETTER TTTA;Lo;0;L;;;;;N;;;;; +0D3B;MALAYALAM SIGN VERTICAL BAR VIRAMA;Mn;9;NSM;;;;;N;;;;; +0D3C;MALAYALAM SIGN CIRCULAR VIRAMA;Mn;9;NSM;;;;;N;;;;; +0D3D;MALAYALAM SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +0D3E;MALAYALAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +0D3F;MALAYALAM VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +0D40;MALAYALAM VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +0D41;MALAYALAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +0D42;MALAYALAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +0D43;MALAYALAM VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +0D44;MALAYALAM VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +0D46;MALAYALAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +0D47;MALAYALAM VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; +0D48;MALAYALAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +0D4A;MALAYALAM VOWEL SIGN O;Mc;0;L;0D46 0D3E;;;;N;;;;; +0D4B;MALAYALAM VOWEL SIGN OO;Mc;0;L;0D47 0D3E;;;;N;;;;; +0D4C;MALAYALAM VOWEL SIGN AU;Mc;0;L;0D46 0D57;;;;N;;;;; +0D4D;MALAYALAM SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0D4E;MALAYALAM LETTER DOT REPH;Lo;0;L;;;;;N;;;;; +0D4F;MALAYALAM SIGN PARA;So;0;L;;;;;N;;;;; +0D54;MALAYALAM LETTER CHILLU M;Lo;0;L;;;;;N;;;;; +0D55;MALAYALAM LETTER CHILLU Y;Lo;0;L;;;;;N;;;;; +0D56;MALAYALAM LETTER CHILLU LLL;Lo;0;L;;;;;N;;;;; +0D57;MALAYALAM AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +0D58;MALAYALAM FRACTION ONE ONE-HUNDRED-AND-SIXTIETH;No;0;L;;;;1/160;N;;;;; +0D59;MALAYALAM FRACTION ONE FORTIETH;No;0;L;;;;1/40;N;;;;; +0D5A;MALAYALAM FRACTION THREE EIGHTIETHS;No;0;L;;;;3/80;N;;;;; +0D5B;MALAYALAM FRACTION ONE TWENTIETH;No;0;L;;;;1/20;N;;;;; +0D5C;MALAYALAM FRACTION ONE TENTH;No;0;L;;;;1/10;N;;;;; +0D5D;MALAYALAM FRACTION THREE TWENTIETHS;No;0;L;;;;3/20;N;;;;; +0D5E;MALAYALAM FRACTION ONE FIFTH;No;0;L;;;;1/5;N;;;;; +0D5F;MALAYALAM LETTER ARCHAIC II;Lo;0;L;;;;;N;;;;; +0D60;MALAYALAM LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +0D61;MALAYALAM LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +0D62;MALAYALAM VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +0D63;MALAYALAM VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +0D66;MALAYALAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0D67;MALAYALAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0D68;MALAYALAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0D69;MALAYALAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0D6A;MALAYALAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0D6B;MALAYALAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0D6C;MALAYALAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0D6D;MALAYALAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0D6E;MALAYALAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0D6F;MALAYALAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0D70;MALAYALAM NUMBER TEN;No;0;L;;;;10;N;;;;; +0D71;MALAYALAM NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;; +0D72;MALAYALAM NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;; +0D73;MALAYALAM FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;; +0D74;MALAYALAM FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;; +0D75;MALAYALAM FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;; +0D76;MALAYALAM FRACTION ONE SIXTEENTH;No;0;L;;;;1/16;N;;;;; +0D77;MALAYALAM FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;; +0D78;MALAYALAM FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;; +0D79;MALAYALAM DATE MARK;So;0;L;;;;;N;;;;; +0D7A;MALAYALAM LETTER CHILLU NN;Lo;0;L;;;;;N;;;;; +0D7B;MALAYALAM LETTER CHILLU N;Lo;0;L;;;;;N;;;;; +0D7C;MALAYALAM LETTER CHILLU RR;Lo;0;L;;;;;N;;;;; +0D7D;MALAYALAM LETTER CHILLU L;Lo;0;L;;;;;N;;;;; +0D7E;MALAYALAM LETTER CHILLU LL;Lo;0;L;;;;;N;;;;; +0D7F;MALAYALAM LETTER CHILLU K;Lo;0;L;;;;;N;;;;; +0D82;SINHALA SIGN ANUSVARAYA;Mc;0;L;;;;;N;;;;; +0D83;SINHALA SIGN VISARGAYA;Mc;0;L;;;;;N;;;;; +0D85;SINHALA LETTER AYANNA;Lo;0;L;;;;;N;;;;; +0D86;SINHALA LETTER AAYANNA;Lo;0;L;;;;;N;;;;; +0D87;SINHALA LETTER AEYANNA;Lo;0;L;;;;;N;;;;; +0D88;SINHALA LETTER AEEYANNA;Lo;0;L;;;;;N;;;;; +0D89;SINHALA LETTER IYANNA;Lo;0;L;;;;;N;;;;; +0D8A;SINHALA LETTER IIYANNA;Lo;0;L;;;;;N;;;;; +0D8B;SINHALA LETTER UYANNA;Lo;0;L;;;;;N;;;;; +0D8C;SINHALA LETTER UUYANNA;Lo;0;L;;;;;N;;;;; +0D8D;SINHALA LETTER IRUYANNA;Lo;0;L;;;;;N;;;;; +0D8E;SINHALA LETTER IRUUYANNA;Lo;0;L;;;;;N;;;;; +0D8F;SINHALA LETTER ILUYANNA;Lo;0;L;;;;;N;;;;; +0D90;SINHALA LETTER ILUUYANNA;Lo;0;L;;;;;N;;;;; +0D91;SINHALA LETTER EYANNA;Lo;0;L;;;;;N;;;;; +0D92;SINHALA LETTER EEYANNA;Lo;0;L;;;;;N;;;;; +0D93;SINHALA LETTER AIYANNA;Lo;0;L;;;;;N;;;;; +0D94;SINHALA LETTER OYANNA;Lo;0;L;;;;;N;;;;; +0D95;SINHALA LETTER OOYANNA;Lo;0;L;;;;;N;;;;; +0D96;SINHALA LETTER AUYANNA;Lo;0;L;;;;;N;;;;; +0D9A;SINHALA LETTER ALPAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;; +0D9B;SINHALA LETTER MAHAAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;; +0D9C;SINHALA LETTER ALPAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;; +0D9D;SINHALA LETTER MAHAAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;; +0D9E;SINHALA LETTER KANTAJA NAASIKYAYA;Lo;0;L;;;;;N;;;;; +0D9F;SINHALA LETTER SANYAKA GAYANNA;Lo;0;L;;;;;N;;;;; +0DA0;SINHALA LETTER ALPAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;; +0DA1;SINHALA LETTER MAHAAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;; +0DA2;SINHALA LETTER ALPAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;; +0DA3;SINHALA LETTER MAHAAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;; +0DA4;SINHALA LETTER TAALUJA NAASIKYAYA;Lo;0;L;;;;;N;;;;; +0DA5;SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA;Lo;0;L;;;;;N;;;;; +0DA6;SINHALA LETTER SANYAKA JAYANNA;Lo;0;L;;;;;N;;;;; +0DA7;SINHALA LETTER ALPAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;; +0DA8;SINHALA LETTER MAHAAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;; +0DA9;SINHALA LETTER ALPAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;; +0DAA;SINHALA LETTER MAHAAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;; +0DAB;SINHALA LETTER MUURDHAJA NAYANNA;Lo;0;L;;;;;N;;;;; +0DAC;SINHALA LETTER SANYAKA DDAYANNA;Lo;0;L;;;;;N;;;;; +0DAD;SINHALA LETTER ALPAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;; +0DAE;SINHALA LETTER MAHAAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;; +0DAF;SINHALA LETTER ALPAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;; +0DB0;SINHALA LETTER MAHAAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;; +0DB1;SINHALA LETTER DANTAJA NAYANNA;Lo;0;L;;;;;N;;;;; +0DB3;SINHALA LETTER SANYAKA DAYANNA;Lo;0;L;;;;;N;;;;; +0DB4;SINHALA LETTER ALPAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;; +0DB5;SINHALA LETTER MAHAAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;; +0DB6;SINHALA LETTER ALPAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;; +0DB7;SINHALA LETTER MAHAAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;; +0DB8;SINHALA LETTER MAYANNA;Lo;0;L;;;;;N;;;;; +0DB9;SINHALA LETTER AMBA BAYANNA;Lo;0;L;;;;;N;;;;; +0DBA;SINHALA LETTER YAYANNA;Lo;0;L;;;;;N;;;;; +0DBB;SINHALA LETTER RAYANNA;Lo;0;L;;;;;N;;;;; +0DBD;SINHALA LETTER DANTAJA LAYANNA;Lo;0;L;;;;;N;;;;; +0DC0;SINHALA LETTER VAYANNA;Lo;0;L;;;;;N;;;;; +0DC1;SINHALA LETTER TAALUJA SAYANNA;Lo;0;L;;;;;N;;;;; +0DC2;SINHALA LETTER MUURDHAJA SAYANNA;Lo;0;L;;;;;N;;;;; +0DC3;SINHALA LETTER DANTAJA SAYANNA;Lo;0;L;;;;;N;;;;; +0DC4;SINHALA LETTER HAYANNA;Lo;0;L;;;;;N;;;;; +0DC5;SINHALA LETTER MUURDHAJA LAYANNA;Lo;0;L;;;;;N;;;;; +0DC6;SINHALA LETTER FAYANNA;Lo;0;L;;;;;N;;;;; +0DCA;SINHALA SIGN AL-LAKUNA;Mn;9;NSM;;;;;N;;;;; +0DCF;SINHALA VOWEL SIGN AELA-PILLA;Mc;0;L;;;;;N;;;;; +0DD0;SINHALA VOWEL SIGN KETTI AEDA-PILLA;Mc;0;L;;;;;N;;;;; +0DD1;SINHALA VOWEL SIGN DIGA AEDA-PILLA;Mc;0;L;;;;;N;;;;; +0DD2;SINHALA VOWEL SIGN KETTI IS-PILLA;Mn;0;NSM;;;;;N;;;;; +0DD3;SINHALA VOWEL SIGN DIGA IS-PILLA;Mn;0;NSM;;;;;N;;;;; +0DD4;SINHALA VOWEL SIGN KETTI PAA-PILLA;Mn;0;NSM;;;;;N;;;;; +0DD6;SINHALA VOWEL SIGN DIGA PAA-PILLA;Mn;0;NSM;;;;;N;;;;; +0DD8;SINHALA VOWEL SIGN GAETTA-PILLA;Mc;0;L;;;;;N;;;;; +0DD9;SINHALA VOWEL SIGN KOMBUVA;Mc;0;L;;;;;N;;;;; +0DDA;SINHALA VOWEL SIGN DIGA KOMBUVA;Mc;0;L;0DD9 0DCA;;;;N;;;;; +0DDB;SINHALA VOWEL SIGN KOMBU DEKA;Mc;0;L;;;;;N;;;;; +0DDC;SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA;Mc;0;L;0DD9 0DCF;;;;N;;;;; +0DDD;SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA;Mc;0;L;0DDC 0DCA;;;;N;;;;; +0DDE;SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA;Mc;0;L;0DD9 0DDF;;;;N;;;;; +0DDF;SINHALA VOWEL SIGN GAYANUKITTA;Mc;0;L;;;;;N;;;;; +0DE6;SINHALA LITH DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0DE7;SINHALA LITH DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0DE8;SINHALA LITH DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0DE9;SINHALA LITH DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0DEA;SINHALA LITH DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0DEB;SINHALA LITH DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0DEC;SINHALA LITH DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0DED;SINHALA LITH DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0DEE;SINHALA LITH DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0DEF;SINHALA LITH DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0DF2;SINHALA VOWEL SIGN DIGA GAETTA-PILLA;Mc;0;L;;;;;N;;;;; +0DF3;SINHALA VOWEL SIGN DIGA GAYANUKITTA;Mc;0;L;;;;;N;;;;; +0DF4;SINHALA PUNCTUATION KUNDDALIYA;Po;0;L;;;;;N;;;;; +0E01;THAI CHARACTER KO KAI;Lo;0;L;;;;;N;THAI LETTER KO KAI;;;; +0E02;THAI CHARACTER KHO KHAI;Lo;0;L;;;;;N;THAI LETTER KHO KHAI;;;; +0E03;THAI CHARACTER KHO KHUAT;Lo;0;L;;;;;N;THAI LETTER KHO KHUAT;;;; +0E04;THAI CHARACTER KHO KHWAI;Lo;0;L;;;;;N;THAI LETTER KHO KHWAI;;;; +0E05;THAI CHARACTER KHO KHON;Lo;0;L;;;;;N;THAI LETTER KHO KHON;;;; +0E06;THAI CHARACTER KHO RAKHANG;Lo;0;L;;;;;N;THAI LETTER KHO RAKHANG;;;; +0E07;THAI CHARACTER NGO NGU;Lo;0;L;;;;;N;THAI LETTER NGO NGU;;;; +0E08;THAI CHARACTER CHO CHAN;Lo;0;L;;;;;N;THAI LETTER CHO CHAN;;;; +0E09;THAI CHARACTER CHO CHING;Lo;0;L;;;;;N;THAI LETTER CHO CHING;;;; +0E0A;THAI CHARACTER CHO CHANG;Lo;0;L;;;;;N;THAI LETTER CHO CHANG;;;; +0E0B;THAI CHARACTER SO SO;Lo;0;L;;;;;N;THAI LETTER SO SO;;;; +0E0C;THAI CHARACTER CHO CHOE;Lo;0;L;;;;;N;THAI LETTER CHO CHOE;;;; +0E0D;THAI CHARACTER YO YING;Lo;0;L;;;;;N;THAI LETTER YO YING;;;; +0E0E;THAI CHARACTER DO CHADA;Lo;0;L;;;;;N;THAI LETTER DO CHADA;;;; +0E0F;THAI CHARACTER TO PATAK;Lo;0;L;;;;;N;THAI LETTER TO PATAK;;;; +0E10;THAI CHARACTER THO THAN;Lo;0;L;;;;;N;THAI LETTER THO THAN;;;; +0E11;THAI CHARACTER THO NANGMONTHO;Lo;0;L;;;;;N;THAI LETTER THO NANGMONTHO;;;; +0E12;THAI CHARACTER THO PHUTHAO;Lo;0;L;;;;;N;THAI LETTER THO PHUTHAO;;;; +0E13;THAI CHARACTER NO NEN;Lo;0;L;;;;;N;THAI LETTER NO NEN;;;; +0E14;THAI CHARACTER DO DEK;Lo;0;L;;;;;N;THAI LETTER DO DEK;;;; +0E15;THAI CHARACTER TO TAO;Lo;0;L;;;;;N;THAI LETTER TO TAO;;;; +0E16;THAI CHARACTER THO THUNG;Lo;0;L;;;;;N;THAI LETTER THO THUNG;;;; +0E17;THAI CHARACTER THO THAHAN;Lo;0;L;;;;;N;THAI LETTER THO THAHAN;;;; +0E18;THAI CHARACTER THO THONG;Lo;0;L;;;;;N;THAI LETTER THO THONG;;;; +0E19;THAI CHARACTER NO NU;Lo;0;L;;;;;N;THAI LETTER NO NU;;;; +0E1A;THAI CHARACTER BO BAIMAI;Lo;0;L;;;;;N;THAI LETTER BO BAIMAI;;;; +0E1B;THAI CHARACTER PO PLA;Lo;0;L;;;;;N;THAI LETTER PO PLA;;;; +0E1C;THAI CHARACTER PHO PHUNG;Lo;0;L;;;;;N;THAI LETTER PHO PHUNG;;;; +0E1D;THAI CHARACTER FO FA;Lo;0;L;;;;;N;THAI LETTER FO FA;;;; +0E1E;THAI CHARACTER PHO PHAN;Lo;0;L;;;;;N;THAI LETTER PHO PHAN;;;; +0E1F;THAI CHARACTER FO FAN;Lo;0;L;;;;;N;THAI LETTER FO FAN;;;; +0E20;THAI CHARACTER PHO SAMPHAO;Lo;0;L;;;;;N;THAI LETTER PHO SAMPHAO;;;; +0E21;THAI CHARACTER MO MA;Lo;0;L;;;;;N;THAI LETTER MO MA;;;; +0E22;THAI CHARACTER YO YAK;Lo;0;L;;;;;N;THAI LETTER YO YAK;;;; +0E23;THAI CHARACTER RO RUA;Lo;0;L;;;;;N;THAI LETTER RO RUA;;;; +0E24;THAI CHARACTER RU;Lo;0;L;;;;;N;THAI LETTER RU;;;; +0E25;THAI CHARACTER LO LING;Lo;0;L;;;;;N;THAI LETTER LO LING;;;; +0E26;THAI CHARACTER LU;Lo;0;L;;;;;N;THAI LETTER LU;;;; +0E27;THAI CHARACTER WO WAEN;Lo;0;L;;;;;N;THAI LETTER WO WAEN;;;; +0E28;THAI CHARACTER SO SALA;Lo;0;L;;;;;N;THAI LETTER SO SALA;;;; +0E29;THAI CHARACTER SO RUSI;Lo;0;L;;;;;N;THAI LETTER SO RUSI;;;; +0E2A;THAI CHARACTER SO SUA;Lo;0;L;;;;;N;THAI LETTER SO SUA;;;; +0E2B;THAI CHARACTER HO HIP;Lo;0;L;;;;;N;THAI LETTER HO HIP;;;; +0E2C;THAI CHARACTER LO CHULA;Lo;0;L;;;;;N;THAI LETTER LO CHULA;;;; +0E2D;THAI CHARACTER O ANG;Lo;0;L;;;;;N;THAI LETTER O ANG;;;; +0E2E;THAI CHARACTER HO NOKHUK;Lo;0;L;;;;;N;THAI LETTER HO NOK HUK;;;; +0E2F;THAI CHARACTER PAIYANNOI;Lo;0;L;;;;;N;THAI PAI YAN NOI;;;; +0E30;THAI CHARACTER SARA A;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA A;;;; +0E31;THAI CHARACTER MAI HAN-AKAT;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI HAN-AKAT;;;; +0E32;THAI CHARACTER SARA AA;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AA;;;; +0E33;THAI CHARACTER SARA AM;Lo;0;L; 0E4D 0E32;;;;N;THAI VOWEL SIGN SARA AM;;;; +0E34;THAI CHARACTER SARA I;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA I;;;; +0E35;THAI CHARACTER SARA II;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA II;;;; +0E36;THAI CHARACTER SARA UE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UE;;;; +0E37;THAI CHARACTER SARA UEE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UEE;;;; +0E38;THAI CHARACTER SARA U;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA U;;;; +0E39;THAI CHARACTER SARA UU;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA UU;;;; +0E3A;THAI CHARACTER PHINTHU;Mn;9;NSM;;;;;N;THAI VOWEL SIGN PHINTHU;;;; +0E3F;THAI CURRENCY SYMBOL BAHT;Sc;0;ET;;;;;N;THAI BAHT SIGN;;;; +0E40;THAI CHARACTER SARA E;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA E;;;; +0E41;THAI CHARACTER SARA AE;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AE;;;; +0E42;THAI CHARACTER SARA O;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA O;;;; +0E43;THAI CHARACTER SARA AI MAIMUAN;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MUAN;;;; +0E44;THAI CHARACTER SARA AI MAIMALAI;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MALAI;;;; +0E45;THAI CHARACTER LAKKHANGYAO;Lo;0;L;;;;;N;THAI LAK KHANG YAO;;;; +0E46;THAI CHARACTER MAIYAMOK;Lm;0;L;;;;;N;THAI MAI YAMOK;;;; +0E47;THAI CHARACTER MAITAIKHU;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI TAI KHU;;;; +0E48;THAI CHARACTER MAI EK;Mn;107;NSM;;;;;N;THAI TONE MAI EK;;;; +0E49;THAI CHARACTER MAI THO;Mn;107;NSM;;;;;N;THAI TONE MAI THO;;;; +0E4A;THAI CHARACTER MAI TRI;Mn;107;NSM;;;;;N;THAI TONE MAI TRI;;;; +0E4B;THAI CHARACTER MAI CHATTAWA;Mn;107;NSM;;;;;N;THAI TONE MAI CHATTAWA;;;; +0E4C;THAI CHARACTER THANTHAKHAT;Mn;0;NSM;;;;;N;THAI THANTHAKHAT;;;; +0E4D;THAI CHARACTER NIKHAHIT;Mn;0;NSM;;;;;N;THAI NIKKHAHIT;;;; +0E4E;THAI CHARACTER YAMAKKAN;Mn;0;NSM;;;;;N;THAI YAMAKKAN;;;; +0E4F;THAI CHARACTER FONGMAN;Po;0;L;;;;;N;THAI FONGMAN;;;; +0E50;THAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0E51;THAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0E52;THAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0E53;THAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0E54;THAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0E55;THAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0E56;THAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0E57;THAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0E58;THAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0E59;THAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0E5A;THAI CHARACTER ANGKHANKHU;Po;0;L;;;;;N;THAI ANGKHANKHU;;;; +0E5B;THAI CHARACTER KHOMUT;Po;0;L;;;;;N;THAI KHOMUT;;;; +0E81;LAO LETTER KO;Lo;0;L;;;;;N;;;;; +0E82;LAO LETTER KHO SUNG;Lo;0;L;;;;;N;;;;; +0E84;LAO LETTER KHO TAM;Lo;0;L;;;;;N;;;;; +0E86;LAO LETTER PALI GHA;Lo;0;L;;;;;N;;;;; +0E87;LAO LETTER NGO;Lo;0;L;;;;;N;;;;; +0E88;LAO LETTER CO;Lo;0;L;;;;;N;;;;; +0E89;LAO LETTER PALI CHA;Lo;0;L;;;;;N;;;;; +0E8A;LAO LETTER SO TAM;Lo;0;L;;;;;N;;;;; +0E8C;LAO LETTER PALI JHA;Lo;0;L;;;;;N;;;;; +0E8D;LAO LETTER NYO;Lo;0;L;;;;;N;;;;; +0E8E;LAO LETTER PALI NYA;Lo;0;L;;;;;N;;;;; +0E8F;LAO LETTER PALI TTA;Lo;0;L;;;;;N;;;;; +0E90;LAO LETTER PALI TTHA;Lo;0;L;;;;;N;;;;; +0E91;LAO LETTER PALI DDA;Lo;0;L;;;;;N;;;;; +0E92;LAO LETTER PALI DDHA;Lo;0;L;;;;;N;;;;; +0E93;LAO LETTER PALI NNA;Lo;0;L;;;;;N;;;;; +0E94;LAO LETTER DO;Lo;0;L;;;;;N;;;;; +0E95;LAO LETTER TO;Lo;0;L;;;;;N;;;;; +0E96;LAO LETTER THO SUNG;Lo;0;L;;;;;N;;;;; +0E97;LAO LETTER THO TAM;Lo;0;L;;;;;N;;;;; +0E98;LAO LETTER PALI DHA;Lo;0;L;;;;;N;;;;; +0E99;LAO LETTER NO;Lo;0;L;;;;;N;;;;; +0E9A;LAO LETTER BO;Lo;0;L;;;;;N;;;;; +0E9B;LAO LETTER PO;Lo;0;L;;;;;N;;;;; +0E9C;LAO LETTER PHO SUNG;Lo;0;L;;;;;N;;;;; +0E9D;LAO LETTER FO TAM;Lo;0;L;;;;;N;;;;; +0E9E;LAO LETTER PHO TAM;Lo;0;L;;;;;N;;;;; +0E9F;LAO LETTER FO SUNG;Lo;0;L;;;;;N;;;;; +0EA0;LAO LETTER PALI BHA;Lo;0;L;;;;;N;;;;; +0EA1;LAO LETTER MO;Lo;0;L;;;;;N;;;;; +0EA2;LAO LETTER YO;Lo;0;L;;;;;N;;;;; +0EA3;LAO LETTER LO LING;Lo;0;L;;;;;N;;;;; +0EA5;LAO LETTER LO LOOT;Lo;0;L;;;;;N;;;;; +0EA7;LAO LETTER WO;Lo;0;L;;;;;N;;;;; +0EA8;LAO LETTER SANSKRIT SHA;Lo;0;L;;;;;N;;;;; +0EA9;LAO LETTER SANSKRIT SSA;Lo;0;L;;;;;N;;;;; +0EAA;LAO LETTER SO SUNG;Lo;0;L;;;;;N;;;;; +0EAB;LAO LETTER HO SUNG;Lo;0;L;;;;;N;;;;; +0EAC;LAO LETTER PALI LLA;Lo;0;L;;;;;N;;;;; +0EAD;LAO LETTER O;Lo;0;L;;;;;N;;;;; +0EAE;LAO LETTER HO TAM;Lo;0;L;;;;;N;;;;; +0EAF;LAO ELLIPSIS;Lo;0;L;;;;;N;;;;; +0EB0;LAO VOWEL SIGN A;Lo;0;L;;;;;N;;;;; +0EB1;LAO VOWEL SIGN MAI KAN;Mn;0;NSM;;;;;N;;;;; +0EB2;LAO VOWEL SIGN AA;Lo;0;L;;;;;N;;;;; +0EB3;LAO VOWEL SIGN AM;Lo;0;L; 0ECD 0EB2;;;;N;;;;; +0EB4;LAO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +0EB5;LAO VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +0EB6;LAO VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;; +0EB7;LAO VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;; +0EB8;LAO VOWEL SIGN U;Mn;118;NSM;;;;;N;;;;; +0EB9;LAO VOWEL SIGN UU;Mn;118;NSM;;;;;N;;;;; +0EBA;LAO SIGN PALI VIRAMA;Mn;9;NSM;;;;;N;;;;; +0EBB;LAO VOWEL SIGN MAI KON;Mn;0;NSM;;;;;N;;;;; +0EBC;LAO SEMIVOWEL SIGN LO;Mn;0;NSM;;;;;N;;;;; +0EBD;LAO SEMIVOWEL SIGN NYO;Lo;0;L;;;;;N;;;;; +0EC0;LAO VOWEL SIGN E;Lo;0;L;;;;;N;;;;; +0EC1;LAO VOWEL SIGN EI;Lo;0;L;;;;;N;;;;; +0EC2;LAO VOWEL SIGN O;Lo;0;L;;;;;N;;;;; +0EC3;LAO VOWEL SIGN AY;Lo;0;L;;;;;N;;;;; +0EC4;LAO VOWEL SIGN AI;Lo;0;L;;;;;N;;;;; +0EC6;LAO KO LA;Lm;0;L;;;;;N;;;;; +0EC8;LAO TONE MAI EK;Mn;122;NSM;;;;;N;;;;; +0EC9;LAO TONE MAI THO;Mn;122;NSM;;;;;N;;;;; +0ECA;LAO TONE MAI TI;Mn;122;NSM;;;;;N;;;;; +0ECB;LAO TONE MAI CATAWA;Mn;122;NSM;;;;;N;;;;; +0ECC;LAO CANCELLATION MARK;Mn;0;NSM;;;;;N;;;;; +0ECD;LAO NIGGAHITA;Mn;0;NSM;;;;;N;;;;; +0ED0;LAO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0ED1;LAO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0ED2;LAO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0ED3;LAO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0ED4;LAO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0ED5;LAO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0ED6;LAO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0ED7;LAO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0ED8;LAO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0ED9;LAO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0EDC;LAO HO NO;Lo;0;L; 0EAB 0E99;;;;N;;;;; +0EDD;LAO HO MO;Lo;0;L; 0EAB 0EA1;;;;N;;;;; +0EDE;LAO LETTER KHMU GO;Lo;0;L;;;;;N;;;;; +0EDF;LAO LETTER KHMU NYO;Lo;0;L;;;;;N;;;;; +0F00;TIBETAN SYLLABLE OM;Lo;0;L;;;;;N;;;;; +0F01;TIBETAN MARK GTER YIG MGO TRUNCATED A;So;0;L;;;;;N;;;;; +0F02;TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA;So;0;L;;;;;N;;;;; +0F03;TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA;So;0;L;;;;;N;;;;; +0F04;TIBETAN MARK INITIAL YIG MGO MDUN MA;Po;0;L;;;;;N;TIBETAN SINGLE ORNAMENT;;;; +0F05;TIBETAN MARK CLOSING YIG MGO SGAB MA;Po;0;L;;;;;N;;;;; +0F06;TIBETAN MARK CARET YIG MGO PHUR SHAD MA;Po;0;L;;;;;N;;;;; +0F07;TIBETAN MARK YIG MGO TSHEG SHAD MA;Po;0;L;;;;;N;;;;; +0F08;TIBETAN MARK SBRUL SHAD;Po;0;L;;;;;N;TIBETAN RGYANSHAD;;;; +0F09;TIBETAN MARK BSKUR YIG MGO;Po;0;L;;;;;N;;;;; +0F0A;TIBETAN MARK BKA- SHOG YIG MGO;Po;0;L;;;;;N;;;;; +0F0B;TIBETAN MARK INTERSYLLABIC TSHEG;Po;0;L;;;;;N;TIBETAN TSEG;;;; +0F0C;TIBETAN MARK DELIMITER TSHEG BSTAR;Po;0;L; 0F0B;;;;N;;;;; +0F0D;TIBETAN MARK SHAD;Po;0;L;;;;;N;TIBETAN SHAD;;;; +0F0E;TIBETAN MARK NYIS SHAD;Po;0;L;;;;;N;TIBETAN DOUBLE SHAD;;;; +0F0F;TIBETAN MARK TSHEG SHAD;Po;0;L;;;;;N;;;;; +0F10;TIBETAN MARK NYIS TSHEG SHAD;Po;0;L;;;;;N;;;;; +0F11;TIBETAN MARK RIN CHEN SPUNGS SHAD;Po;0;L;;;;;N;TIBETAN RINCHANPHUNGSHAD;;;; +0F12;TIBETAN MARK RGYA GRAM SHAD;Po;0;L;;;;;N;;;;; +0F13;TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN;So;0;L;;;;;N;;;;; +0F14;TIBETAN MARK GTER TSHEG;Po;0;L;;;;;N;TIBETAN COMMA;;;; +0F15;TIBETAN LOGOTYPE SIGN CHAD RTAGS;So;0;L;;;;;N;;;;; +0F16;TIBETAN LOGOTYPE SIGN LHAG RTAGS;So;0;L;;;;;N;;;;; +0F17;TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS;So;0;L;;;;;N;;;;; +0F18;TIBETAN ASTROLOGICAL SIGN -KHYUD PA;Mn;220;NSM;;;;;N;;;;; +0F19;TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS;Mn;220;NSM;;;;;N;;;;; +0F1A;TIBETAN SIGN RDEL DKAR GCIG;So;0;L;;;;;N;;;;; +0F1B;TIBETAN SIGN RDEL DKAR GNYIS;So;0;L;;;;;N;;;;; +0F1C;TIBETAN SIGN RDEL DKAR GSUM;So;0;L;;;;;N;;;;; +0F1D;TIBETAN SIGN RDEL NAG GCIG;So;0;L;;;;;N;;;;; +0F1E;TIBETAN SIGN RDEL NAG GNYIS;So;0;L;;;;;N;;;;; +0F1F;TIBETAN SIGN RDEL DKAR RDEL NAG;So;0;L;;;;;N;;;;; +0F20;TIBETAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +0F21;TIBETAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +0F22;TIBETAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +0F23;TIBETAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +0F24;TIBETAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +0F25;TIBETAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +0F26;TIBETAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +0F27;TIBETAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +0F28;TIBETAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +0F29;TIBETAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0F2A;TIBETAN DIGIT HALF ONE;No;0;L;;;;1/2;N;;;;; +0F2B;TIBETAN DIGIT HALF TWO;No;0;L;;;;3/2;N;;;;; +0F2C;TIBETAN DIGIT HALF THREE;No;0;L;;;;5/2;N;;;;; +0F2D;TIBETAN DIGIT HALF FOUR;No;0;L;;;;7/2;N;;;;; +0F2E;TIBETAN DIGIT HALF FIVE;No;0;L;;;;9/2;N;;;;; +0F2F;TIBETAN DIGIT HALF SIX;No;0;L;;;;11/2;N;;;;; +0F30;TIBETAN DIGIT HALF SEVEN;No;0;L;;;;13/2;N;;;;; +0F31;TIBETAN DIGIT HALF EIGHT;No;0;L;;;;15/2;N;;;;; +0F32;TIBETAN DIGIT HALF NINE;No;0;L;;;;17/2;N;;;;; +0F33;TIBETAN DIGIT HALF ZERO;No;0;L;;;;-1/2;N;;;;; +0F34;TIBETAN MARK BSDUS RTAGS;So;0;L;;;;;N;;;;; +0F35;TIBETAN MARK NGAS BZUNG NYI ZLA;Mn;220;NSM;;;;;N;TIBETAN HONORIFIC UNDER RING;;;; +0F36;TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN;So;0;L;;;;;N;;;;; +0F37;TIBETAN MARK NGAS BZUNG SGOR RTAGS;Mn;220;NSM;;;;;N;TIBETAN UNDER RING;;;; +0F38;TIBETAN MARK CHE MGO;So;0;L;;;;;N;;;;; +0F39;TIBETAN MARK TSA -PHRU;Mn;216;NSM;;;;;N;TIBETAN LENITION MARK;;;; +0F3A;TIBETAN MARK GUG RTAGS GYON;Ps;0;ON;;;;;Y;;;;; +0F3B;TIBETAN MARK GUG RTAGS GYAS;Pe;0;ON;;;;;Y;;;;; +0F3C;TIBETAN MARK ANG KHANG GYON;Ps;0;ON;;;;;Y;TIBETAN LEFT BRACE;;;; +0F3D;TIBETAN MARK ANG KHANG GYAS;Pe;0;ON;;;;;Y;TIBETAN RIGHT BRACE;;;; +0F3E;TIBETAN SIGN YAR TSHES;Mc;0;L;;;;;N;;;;; +0F3F;TIBETAN SIGN MAR TSHES;Mc;0;L;;;;;N;;;;; +0F40;TIBETAN LETTER KA;Lo;0;L;;;;;N;;;;; +0F41;TIBETAN LETTER KHA;Lo;0;L;;;;;N;;;;; +0F42;TIBETAN LETTER GA;Lo;0;L;;;;;N;;;;; +0F43;TIBETAN LETTER GHA;Lo;0;L;0F42 0FB7;;;;N;;;;; +0F44;TIBETAN LETTER NGA;Lo;0;L;;;;;N;;;;; +0F45;TIBETAN LETTER CA;Lo;0;L;;;;;N;;;;; +0F46;TIBETAN LETTER CHA;Lo;0;L;;;;;N;;;;; +0F47;TIBETAN LETTER JA;Lo;0;L;;;;;N;;;;; +0F49;TIBETAN LETTER NYA;Lo;0;L;;;;;N;;;;; +0F4A;TIBETAN LETTER TTA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED TA;;;; +0F4B;TIBETAN LETTER TTHA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED THA;;;; +0F4C;TIBETAN LETTER DDA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED DA;;;; +0F4D;TIBETAN LETTER DDHA;Lo;0;L;0F4C 0FB7;;;;N;;;;; +0F4E;TIBETAN LETTER NNA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED NA;;;; +0F4F;TIBETAN LETTER TA;Lo;0;L;;;;;N;;;;; +0F50;TIBETAN LETTER THA;Lo;0;L;;;;;N;;;;; +0F51;TIBETAN LETTER DA;Lo;0;L;;;;;N;;;;; +0F52;TIBETAN LETTER DHA;Lo;0;L;0F51 0FB7;;;;N;;;;; +0F53;TIBETAN LETTER NA;Lo;0;L;;;;;N;;;;; +0F54;TIBETAN LETTER PA;Lo;0;L;;;;;N;;;;; +0F55;TIBETAN LETTER PHA;Lo;0;L;;;;;N;;;;; +0F56;TIBETAN LETTER BA;Lo;0;L;;;;;N;;;;; +0F57;TIBETAN LETTER BHA;Lo;0;L;0F56 0FB7;;;;N;;;;; +0F58;TIBETAN LETTER MA;Lo;0;L;;;;;N;;;;; +0F59;TIBETAN LETTER TSA;Lo;0;L;;;;;N;;;;; +0F5A;TIBETAN LETTER TSHA;Lo;0;L;;;;;N;;;;; +0F5B;TIBETAN LETTER DZA;Lo;0;L;;;;;N;;;;; +0F5C;TIBETAN LETTER DZHA;Lo;0;L;0F5B 0FB7;;;;N;;;;; +0F5D;TIBETAN LETTER WA;Lo;0;L;;;;;N;;;;; +0F5E;TIBETAN LETTER ZHA;Lo;0;L;;;;;N;;;;; +0F5F;TIBETAN LETTER ZA;Lo;0;L;;;;;N;;;;; +0F60;TIBETAN LETTER -A;Lo;0;L;;;;;N;TIBETAN LETTER AA;;;; +0F61;TIBETAN LETTER YA;Lo;0;L;;;;;N;;;;; +0F62;TIBETAN LETTER RA;Lo;0;L;;;;;N;;;;; +0F63;TIBETAN LETTER LA;Lo;0;L;;;;;N;;;;; +0F64;TIBETAN LETTER SHA;Lo;0;L;;;;;N;;;;; +0F65;TIBETAN LETTER SSA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED SHA;;;; +0F66;TIBETAN LETTER SA;Lo;0;L;;;;;N;;;;; +0F67;TIBETAN LETTER HA;Lo;0;L;;;;;N;;;;; +0F68;TIBETAN LETTER A;Lo;0;L;;;;;N;;;;; +0F69;TIBETAN LETTER KSSA;Lo;0;L;0F40 0FB5;;;;N;;;;; +0F6A;TIBETAN LETTER FIXED-FORM RA;Lo;0;L;;;;;N;;;;; +0F6B;TIBETAN LETTER KKA;Lo;0;L;;;;;N;;;;; +0F6C;TIBETAN LETTER RRA;Lo;0;L;;;;;N;;;;; +0F71;TIBETAN VOWEL SIGN AA;Mn;129;NSM;;;;;N;;;;; +0F72;TIBETAN VOWEL SIGN I;Mn;130;NSM;;;;;N;;;;; +0F73;TIBETAN VOWEL SIGN II;Mn;0;NSM;0F71 0F72;;;;N;;;;; +0F74;TIBETAN VOWEL SIGN U;Mn;132;NSM;;;;;N;;;;; +0F75;TIBETAN VOWEL SIGN UU;Mn;0;NSM;0F71 0F74;;;;N;;;;; +0F76;TIBETAN VOWEL SIGN VOCALIC R;Mn;0;NSM;0FB2 0F80;;;;N;;;;; +0F77;TIBETAN VOWEL SIGN VOCALIC RR;Mn;0;NSM; 0FB2 0F81;;;;N;;;;; +0F78;TIBETAN VOWEL SIGN VOCALIC L;Mn;0;NSM;0FB3 0F80;;;;N;;;;; +0F79;TIBETAN VOWEL SIGN VOCALIC LL;Mn;0;NSM; 0FB3 0F81;;;;N;;;;; +0F7A;TIBETAN VOWEL SIGN E;Mn;130;NSM;;;;;N;;;;; +0F7B;TIBETAN VOWEL SIGN EE;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AI;;;; +0F7C;TIBETAN VOWEL SIGN O;Mn;130;NSM;;;;;N;;;;; +0F7D;TIBETAN VOWEL SIGN OO;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AU;;;; +0F7E;TIBETAN SIGN RJES SU NGA RO;Mn;0;NSM;;;;;N;TIBETAN ANUSVARA;;;; +0F7F;TIBETAN SIGN RNAM BCAD;Mc;0;L;;;;;N;TIBETAN VISARGA;;;; +0F80;TIBETAN VOWEL SIGN REVERSED I;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN SHORT I;;;; +0F81;TIBETAN VOWEL SIGN REVERSED II;Mn;0;NSM;0F71 0F80;;;;N;;;;; +0F82;TIBETAN SIGN NYI ZLA NAA DA;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU WITH ORNAMENT;;;; +0F83;TIBETAN SIGN SNA LDAN;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU;;;; +0F84;TIBETAN MARK HALANTA;Mn;9;NSM;;;;;N;TIBETAN VIRAMA;;;; +0F85;TIBETAN MARK PALUTA;Po;0;L;;;;;N;TIBETAN CHUCHENYIGE;;;; +0F86;TIBETAN SIGN LCI RTAGS;Mn;230;NSM;;;;;N;;;;; +0F87;TIBETAN SIGN YANG RTAGS;Mn;230;NSM;;;;;N;;;;; +0F88;TIBETAN SIGN LCE TSA CAN;Lo;0;L;;;;;N;;;;; +0F89;TIBETAN SIGN MCHU CAN;Lo;0;L;;;;;N;;;;; +0F8A;TIBETAN SIGN GRU CAN RGYINGS;Lo;0;L;;;;;N;;;;; +0F8B;TIBETAN SIGN GRU MED RGYINGS;Lo;0;L;;;;;N;;;;; +0F8C;TIBETAN SIGN INVERTED MCHU CAN;Lo;0;L;;;;;N;;;;; +0F8D;TIBETAN SUBJOINED SIGN LCE TSA CAN;Mn;0;NSM;;;;;N;;;;; +0F8E;TIBETAN SUBJOINED SIGN MCHU CAN;Mn;0;NSM;;;;;N;;;;; +0F8F;TIBETAN SUBJOINED SIGN INVERTED MCHU CAN;Mn;0;NSM;;;;;N;;;;; +0F90;TIBETAN SUBJOINED LETTER KA;Mn;0;NSM;;;;;N;;;;; +0F91;TIBETAN SUBJOINED LETTER KHA;Mn;0;NSM;;;;;N;;;;; +0F92;TIBETAN SUBJOINED LETTER GA;Mn;0;NSM;;;;;N;;;;; +0F93;TIBETAN SUBJOINED LETTER GHA;Mn;0;NSM;0F92 0FB7;;;;N;;;;; +0F94;TIBETAN SUBJOINED LETTER NGA;Mn;0;NSM;;;;;N;;;;; +0F95;TIBETAN SUBJOINED LETTER CA;Mn;0;NSM;;;;;N;;;;; +0F96;TIBETAN SUBJOINED LETTER CHA;Mn;0;NSM;;;;;N;;;;; +0F97;TIBETAN SUBJOINED LETTER JA;Mn;0;NSM;;;;;N;;;;; +0F99;TIBETAN SUBJOINED LETTER NYA;Mn;0;NSM;;;;;N;;;;; +0F9A;TIBETAN SUBJOINED LETTER TTA;Mn;0;NSM;;;;;N;;;;; +0F9B;TIBETAN SUBJOINED LETTER TTHA;Mn;0;NSM;;;;;N;;;;; +0F9C;TIBETAN SUBJOINED LETTER DDA;Mn;0;NSM;;;;;N;;;;; +0F9D;TIBETAN SUBJOINED LETTER DDHA;Mn;0;NSM;0F9C 0FB7;;;;N;;;;; +0F9E;TIBETAN SUBJOINED LETTER NNA;Mn;0;NSM;;;;;N;;;;; +0F9F;TIBETAN SUBJOINED LETTER TA;Mn;0;NSM;;;;;N;;;;; +0FA0;TIBETAN SUBJOINED LETTER THA;Mn;0;NSM;;;;;N;;;;; +0FA1;TIBETAN SUBJOINED LETTER DA;Mn;0;NSM;;;;;N;;;;; +0FA2;TIBETAN SUBJOINED LETTER DHA;Mn;0;NSM;0FA1 0FB7;;;;N;;;;; +0FA3;TIBETAN SUBJOINED LETTER NA;Mn;0;NSM;;;;;N;;;;; +0FA4;TIBETAN SUBJOINED LETTER PA;Mn;0;NSM;;;;;N;;;;; +0FA5;TIBETAN SUBJOINED LETTER PHA;Mn;0;NSM;;;;;N;;;;; +0FA6;TIBETAN SUBJOINED LETTER BA;Mn;0;NSM;;;;;N;;;;; +0FA7;TIBETAN SUBJOINED LETTER BHA;Mn;0;NSM;0FA6 0FB7;;;;N;;;;; +0FA8;TIBETAN SUBJOINED LETTER MA;Mn;0;NSM;;;;;N;;;;; +0FA9;TIBETAN SUBJOINED LETTER TSA;Mn;0;NSM;;;;;N;;;;; +0FAA;TIBETAN SUBJOINED LETTER TSHA;Mn;0;NSM;;;;;N;;;;; +0FAB;TIBETAN SUBJOINED LETTER DZA;Mn;0;NSM;;;;;N;;;;; +0FAC;TIBETAN SUBJOINED LETTER DZHA;Mn;0;NSM;0FAB 0FB7;;;;N;;;;; +0FAD;TIBETAN SUBJOINED LETTER WA;Mn;0;NSM;;;;;N;;;;; +0FAE;TIBETAN SUBJOINED LETTER ZHA;Mn;0;NSM;;;;;N;;;;; +0FAF;TIBETAN SUBJOINED LETTER ZA;Mn;0;NSM;;;;;N;;;;; +0FB0;TIBETAN SUBJOINED LETTER -A;Mn;0;NSM;;;;;N;;;;; +0FB1;TIBETAN SUBJOINED LETTER YA;Mn;0;NSM;;;;;N;;;;; +0FB2;TIBETAN SUBJOINED LETTER RA;Mn;0;NSM;;;;;N;;;;; +0FB3;TIBETAN SUBJOINED LETTER LA;Mn;0;NSM;;;;;N;;;;; +0FB4;TIBETAN SUBJOINED LETTER SHA;Mn;0;NSM;;;;;N;;;;; +0FB5;TIBETAN SUBJOINED LETTER SSA;Mn;0;NSM;;;;;N;;;;; +0FB6;TIBETAN SUBJOINED LETTER SA;Mn;0;NSM;;;;;N;;;;; +0FB7;TIBETAN SUBJOINED LETTER HA;Mn;0;NSM;;;;;N;;;;; +0FB8;TIBETAN SUBJOINED LETTER A;Mn;0;NSM;;;;;N;;;;; +0FB9;TIBETAN SUBJOINED LETTER KSSA;Mn;0;NSM;0F90 0FB5;;;;N;;;;; +0FBA;TIBETAN SUBJOINED LETTER FIXED-FORM WA;Mn;0;NSM;;;;;N;;;;; +0FBB;TIBETAN SUBJOINED LETTER FIXED-FORM YA;Mn;0;NSM;;;;;N;;;;; +0FBC;TIBETAN SUBJOINED LETTER FIXED-FORM RA;Mn;0;NSM;;;;;N;;;;; +0FBE;TIBETAN KU RU KHA;So;0;L;;;;;N;;;;; +0FBF;TIBETAN KU RU KHA BZHI MIG CAN;So;0;L;;;;;N;;;;; +0FC0;TIBETAN CANTILLATION SIGN HEAVY BEAT;So;0;L;;;;;N;;;;; +0FC1;TIBETAN CANTILLATION SIGN LIGHT BEAT;So;0;L;;;;;N;;;;; +0FC2;TIBETAN CANTILLATION SIGN CANG TE-U;So;0;L;;;;;N;;;;; +0FC3;TIBETAN CANTILLATION SIGN SBUB -CHAL;So;0;L;;;;;N;;;;; +0FC4;TIBETAN SYMBOL DRIL BU;So;0;L;;;;;N;;;;; +0FC5;TIBETAN SYMBOL RDO RJE;So;0;L;;;;;N;;;;; +0FC6;TIBETAN SYMBOL PADMA GDAN;Mn;220;NSM;;;;;N;;;;; +0FC7;TIBETAN SYMBOL RDO RJE RGYA GRAM;So;0;L;;;;;N;;;;; +0FC8;TIBETAN SYMBOL PHUR PA;So;0;L;;;;;N;;;;; +0FC9;TIBETAN SYMBOL NOR BU;So;0;L;;;;;N;;;;; +0FCA;TIBETAN SYMBOL NOR BU NYIS -KHYIL;So;0;L;;;;;N;;;;; +0FCB;TIBETAN SYMBOL NOR BU GSUM -KHYIL;So;0;L;;;;;N;;;;; +0FCC;TIBETAN SYMBOL NOR BU BZHI -KHYIL;So;0;L;;;;;N;;;;; +0FCE;TIBETAN SIGN RDEL NAG RDEL DKAR;So;0;L;;;;;N;;;;; +0FCF;TIBETAN SIGN RDEL NAG GSUM;So;0;L;;;;;N;;;;; +0FD0;TIBETAN MARK BSKA- SHOG GI MGO RGYAN;Po;0;L;;;;;N;;;;; +0FD1;TIBETAN MARK MNYAM YIG GI MGO RGYAN;Po;0;L;;;;;N;;;;; +0FD2;TIBETAN MARK NYIS TSHEG;Po;0;L;;;;;N;;;;; +0FD3;TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA;Po;0;L;;;;;N;;;;; +0FD4;TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA;Po;0;L;;;;;N;;;;; +0FD5;RIGHT-FACING SVASTI SIGN;So;0;L;;;;;N;;;;; +0FD6;LEFT-FACING SVASTI SIGN;So;0;L;;;;;N;;;;; +0FD7;RIGHT-FACING SVASTI SIGN WITH DOTS;So;0;L;;;;;N;;;;; +0FD8;LEFT-FACING SVASTI SIGN WITH DOTS;So;0;L;;;;;N;;;;; +0FD9;TIBETAN MARK LEADING MCHAN RTAGS;Po;0;L;;;;;N;;;;; +0FDA;TIBETAN MARK TRAILING MCHAN RTAGS;Po;0;L;;;;;N;;;;; +1000;MYANMAR LETTER KA;Lo;0;L;;;;;N;;;;; +1001;MYANMAR LETTER KHA;Lo;0;L;;;;;N;;;;; +1002;MYANMAR LETTER GA;Lo;0;L;;;;;N;;;;; +1003;MYANMAR LETTER GHA;Lo;0;L;;;;;N;;;;; +1004;MYANMAR LETTER NGA;Lo;0;L;;;;;N;;;;; +1005;MYANMAR LETTER CA;Lo;0;L;;;;;N;;;;; +1006;MYANMAR LETTER CHA;Lo;0;L;;;;;N;;;;; +1007;MYANMAR LETTER JA;Lo;0;L;;;;;N;;;;; +1008;MYANMAR LETTER JHA;Lo;0;L;;;;;N;;;;; +1009;MYANMAR LETTER NYA;Lo;0;L;;;;;N;;;;; +100A;MYANMAR LETTER NNYA;Lo;0;L;;;;;N;;;;; +100B;MYANMAR LETTER TTA;Lo;0;L;;;;;N;;;;; +100C;MYANMAR LETTER TTHA;Lo;0;L;;;;;N;;;;; +100D;MYANMAR LETTER DDA;Lo;0;L;;;;;N;;;;; +100E;MYANMAR LETTER DDHA;Lo;0;L;;;;;N;;;;; +100F;MYANMAR LETTER NNA;Lo;0;L;;;;;N;;;;; +1010;MYANMAR LETTER TA;Lo;0;L;;;;;N;;;;; +1011;MYANMAR LETTER THA;Lo;0;L;;;;;N;;;;; +1012;MYANMAR LETTER DA;Lo;0;L;;;;;N;;;;; +1013;MYANMAR LETTER DHA;Lo;0;L;;;;;N;;;;; +1014;MYANMAR LETTER NA;Lo;0;L;;;;;N;;;;; +1015;MYANMAR LETTER PA;Lo;0;L;;;;;N;;;;; +1016;MYANMAR LETTER PHA;Lo;0;L;;;;;N;;;;; +1017;MYANMAR LETTER BA;Lo;0;L;;;;;N;;;;; +1018;MYANMAR LETTER BHA;Lo;0;L;;;;;N;;;;; +1019;MYANMAR LETTER MA;Lo;0;L;;;;;N;;;;; +101A;MYANMAR LETTER YA;Lo;0;L;;;;;N;;;;; +101B;MYANMAR LETTER RA;Lo;0;L;;;;;N;;;;; +101C;MYANMAR LETTER LA;Lo;0;L;;;;;N;;;;; +101D;MYANMAR LETTER WA;Lo;0;L;;;;;N;;;;; +101E;MYANMAR LETTER SA;Lo;0;L;;;;;N;;;;; +101F;MYANMAR LETTER HA;Lo;0;L;;;;;N;;;;; +1020;MYANMAR LETTER LLA;Lo;0;L;;;;;N;;;;; +1021;MYANMAR LETTER A;Lo;0;L;;;;;N;;;;; +1022;MYANMAR LETTER SHAN A;Lo;0;L;;;;;N;;;;; +1023;MYANMAR LETTER I;Lo;0;L;;;;;N;;;;; +1024;MYANMAR LETTER II;Lo;0;L;;;;;N;;;;; +1025;MYANMAR LETTER U;Lo;0;L;;;;;N;;;;; +1026;MYANMAR LETTER UU;Lo;0;L;1025 102E;;;;N;;;;; +1027;MYANMAR LETTER E;Lo;0;L;;;;;N;;;;; +1028;MYANMAR LETTER MON E;Lo;0;L;;;;;N;;;;; +1029;MYANMAR LETTER O;Lo;0;L;;;;;N;;;;; +102A;MYANMAR LETTER AU;Lo;0;L;;;;;N;;;;; +102B;MYANMAR VOWEL SIGN TALL AA;Mc;0;L;;;;;N;;;;; +102C;MYANMAR VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +102D;MYANMAR VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +102E;MYANMAR VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +102F;MYANMAR VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1030;MYANMAR VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +1031;MYANMAR VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +1032;MYANMAR VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +1033;MYANMAR VOWEL SIGN MON II;Mn;0;NSM;;;;;N;;;;; +1034;MYANMAR VOWEL SIGN MON O;Mn;0;NSM;;;;;N;;;;; +1035;MYANMAR VOWEL SIGN E ABOVE;Mn;0;NSM;;;;;N;;;;; +1036;MYANMAR SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +1037;MYANMAR SIGN DOT BELOW;Mn;7;NSM;;;;;N;;;;; +1038;MYANMAR SIGN VISARGA;Mc;0;L;;;;;N;;;;; +1039;MYANMAR SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +103A;MYANMAR SIGN ASAT;Mn;9;NSM;;;;;N;;;;; +103B;MYANMAR CONSONANT SIGN MEDIAL YA;Mc;0;L;;;;;N;;;;; +103C;MYANMAR CONSONANT SIGN MEDIAL RA;Mc;0;L;;;;;N;;;;; +103D;MYANMAR CONSONANT SIGN MEDIAL WA;Mn;0;NSM;;;;;N;;;;; +103E;MYANMAR CONSONANT SIGN MEDIAL HA;Mn;0;NSM;;;;;N;;;;; +103F;MYANMAR LETTER GREAT SA;Lo;0;L;;;;;N;;;;; +1040;MYANMAR DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1041;MYANMAR DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1042;MYANMAR DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1043;MYANMAR DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1044;MYANMAR DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1045;MYANMAR DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1046;MYANMAR DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1047;MYANMAR DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1048;MYANMAR DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1049;MYANMAR DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +104A;MYANMAR SIGN LITTLE SECTION;Po;0;L;;;;;N;;;;; +104B;MYANMAR SIGN SECTION;Po;0;L;;;;;N;;;;; +104C;MYANMAR SYMBOL LOCATIVE;Po;0;L;;;;;N;;;;; +104D;MYANMAR SYMBOL COMPLETED;Po;0;L;;;;;N;;;;; +104E;MYANMAR SYMBOL AFOREMENTIONED;Po;0;L;;;;;N;;;;; +104F;MYANMAR SYMBOL GENITIVE;Po;0;L;;;;;N;;;;; +1050;MYANMAR LETTER SHA;Lo;0;L;;;;;N;;;;; +1051;MYANMAR LETTER SSA;Lo;0;L;;;;;N;;;;; +1052;MYANMAR LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +1053;MYANMAR LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +1054;MYANMAR LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +1055;MYANMAR LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +1056;MYANMAR VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; +1057;MYANMAR VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; +1058;MYANMAR VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +1059;MYANMAR VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +105A;MYANMAR LETTER MON NGA;Lo;0;L;;;;;N;;;;; +105B;MYANMAR LETTER MON JHA;Lo;0;L;;;;;N;;;;; +105C;MYANMAR LETTER MON BBA;Lo;0;L;;;;;N;;;;; +105D;MYANMAR LETTER MON BBE;Lo;0;L;;;;;N;;;;; +105E;MYANMAR CONSONANT SIGN MON MEDIAL NA;Mn;0;NSM;;;;;N;;;;; +105F;MYANMAR CONSONANT SIGN MON MEDIAL MA;Mn;0;NSM;;;;;N;;;;; +1060;MYANMAR CONSONANT SIGN MON MEDIAL LA;Mn;0;NSM;;;;;N;;;;; +1061;MYANMAR LETTER SGAW KAREN SHA;Lo;0;L;;;;;N;;;;; +1062;MYANMAR VOWEL SIGN SGAW KAREN EU;Mc;0;L;;;;;N;;;;; +1063;MYANMAR TONE MARK SGAW KAREN HATHI;Mc;0;L;;;;;N;;;;; +1064;MYANMAR TONE MARK SGAW KAREN KE PHO;Mc;0;L;;;;;N;;;;; +1065;MYANMAR LETTER WESTERN PWO KAREN THA;Lo;0;L;;;;;N;;;;; +1066;MYANMAR LETTER WESTERN PWO KAREN PWA;Lo;0;L;;;;;N;;;;; +1067;MYANMAR VOWEL SIGN WESTERN PWO KAREN EU;Mc;0;L;;;;;N;;;;; +1068;MYANMAR VOWEL SIGN WESTERN PWO KAREN UE;Mc;0;L;;;;;N;;;;; +1069;MYANMAR SIGN WESTERN PWO KAREN TONE-1;Mc;0;L;;;;;N;;;;; +106A;MYANMAR SIGN WESTERN PWO KAREN TONE-2;Mc;0;L;;;;;N;;;;; +106B;MYANMAR SIGN WESTERN PWO KAREN TONE-3;Mc;0;L;;;;;N;;;;; +106C;MYANMAR SIGN WESTERN PWO KAREN TONE-4;Mc;0;L;;;;;N;;;;; +106D;MYANMAR SIGN WESTERN PWO KAREN TONE-5;Mc;0;L;;;;;N;;;;; +106E;MYANMAR LETTER EASTERN PWO KAREN NNA;Lo;0;L;;;;;N;;;;; +106F;MYANMAR LETTER EASTERN PWO KAREN YWA;Lo;0;L;;;;;N;;;;; +1070;MYANMAR LETTER EASTERN PWO KAREN GHWA;Lo;0;L;;;;;N;;;;; +1071;MYANMAR VOWEL SIGN GEBA KAREN I;Mn;0;NSM;;;;;N;;;;; +1072;MYANMAR VOWEL SIGN KAYAH OE;Mn;0;NSM;;;;;N;;;;; +1073;MYANMAR VOWEL SIGN KAYAH U;Mn;0;NSM;;;;;N;;;;; +1074;MYANMAR VOWEL SIGN KAYAH EE;Mn;0;NSM;;;;;N;;;;; +1075;MYANMAR LETTER SHAN KA;Lo;0;L;;;;;N;;;;; +1076;MYANMAR LETTER SHAN KHA;Lo;0;L;;;;;N;;;;; +1077;MYANMAR LETTER SHAN GA;Lo;0;L;;;;;N;;;;; +1078;MYANMAR LETTER SHAN CA;Lo;0;L;;;;;N;;;;; +1079;MYANMAR LETTER SHAN ZA;Lo;0;L;;;;;N;;;;; +107A;MYANMAR LETTER SHAN NYA;Lo;0;L;;;;;N;;;;; +107B;MYANMAR LETTER SHAN DA;Lo;0;L;;;;;N;;;;; +107C;MYANMAR LETTER SHAN NA;Lo;0;L;;;;;N;;;;; +107D;MYANMAR LETTER SHAN PHA;Lo;0;L;;;;;N;;;;; +107E;MYANMAR LETTER SHAN FA;Lo;0;L;;;;;N;;;;; +107F;MYANMAR LETTER SHAN BA;Lo;0;L;;;;;N;;;;; +1080;MYANMAR LETTER SHAN THA;Lo;0;L;;;;;N;;;;; +1081;MYANMAR LETTER SHAN HA;Lo;0;L;;;;;N;;;;; +1082;MYANMAR CONSONANT SIGN SHAN MEDIAL WA;Mn;0;NSM;;;;;N;;;;; +1083;MYANMAR VOWEL SIGN SHAN AA;Mc;0;L;;;;;N;;;;; +1084;MYANMAR VOWEL SIGN SHAN E;Mc;0;L;;;;;N;;;;; +1085;MYANMAR VOWEL SIGN SHAN E ABOVE;Mn;0;NSM;;;;;N;;;;; +1086;MYANMAR VOWEL SIGN SHAN FINAL Y;Mn;0;NSM;;;;;N;;;;; +1087;MYANMAR SIGN SHAN TONE-2;Mc;0;L;;;;;N;;;;; +1088;MYANMAR SIGN SHAN TONE-3;Mc;0;L;;;;;N;;;;; +1089;MYANMAR SIGN SHAN TONE-5;Mc;0;L;;;;;N;;;;; +108A;MYANMAR SIGN SHAN TONE-6;Mc;0;L;;;;;N;;;;; +108B;MYANMAR SIGN SHAN COUNCIL TONE-2;Mc;0;L;;;;;N;;;;; +108C;MYANMAR SIGN SHAN COUNCIL TONE-3;Mc;0;L;;;;;N;;;;; +108D;MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE;Mn;220;NSM;;;;;N;;;;; +108E;MYANMAR LETTER RUMAI PALAUNG FA;Lo;0;L;;;;;N;;;;; +108F;MYANMAR SIGN RUMAI PALAUNG TONE-5;Mc;0;L;;;;;N;;;;; +1090;MYANMAR SHAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1091;MYANMAR SHAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1092;MYANMAR SHAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1093;MYANMAR SHAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1094;MYANMAR SHAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1095;MYANMAR SHAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1096;MYANMAR SHAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1097;MYANMAR SHAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1098;MYANMAR SHAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1099;MYANMAR SHAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +109A;MYANMAR SIGN KHAMTI TONE-1;Mc;0;L;;;;;N;;;;; +109B;MYANMAR SIGN KHAMTI TONE-3;Mc;0;L;;;;;N;;;;; +109C;MYANMAR VOWEL SIGN AITON A;Mc;0;L;;;;;N;;;;; +109D;MYANMAR VOWEL SIGN AITON AI;Mn;0;NSM;;;;;N;;;;; +109E;MYANMAR SYMBOL SHAN ONE;So;0;L;;;;;N;;;;; +109F;MYANMAR SYMBOL SHAN EXCLAMATION;So;0;L;;;;;N;;;;; +10A0;GEORGIAN CAPITAL LETTER AN;Lu;0;L;;;;;N;;;;2D00; +10A1;GEORGIAN CAPITAL LETTER BAN;Lu;0;L;;;;;N;;;;2D01; +10A2;GEORGIAN CAPITAL LETTER GAN;Lu;0;L;;;;;N;;;;2D02; +10A3;GEORGIAN CAPITAL LETTER DON;Lu;0;L;;;;;N;;;;2D03; +10A4;GEORGIAN CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;2D04; +10A5;GEORGIAN CAPITAL LETTER VIN;Lu;0;L;;;;;N;;;;2D05; +10A6;GEORGIAN CAPITAL LETTER ZEN;Lu;0;L;;;;;N;;;;2D06; +10A7;GEORGIAN CAPITAL LETTER TAN;Lu;0;L;;;;;N;;;;2D07; +10A8;GEORGIAN CAPITAL LETTER IN;Lu;0;L;;;;;N;;;;2D08; +10A9;GEORGIAN CAPITAL LETTER KAN;Lu;0;L;;;;;N;;;;2D09; +10AA;GEORGIAN CAPITAL LETTER LAS;Lu;0;L;;;;;N;;;;2D0A; +10AB;GEORGIAN CAPITAL LETTER MAN;Lu;0;L;;;;;N;;;;2D0B; +10AC;GEORGIAN CAPITAL LETTER NAR;Lu;0;L;;;;;N;;;;2D0C; +10AD;GEORGIAN CAPITAL LETTER ON;Lu;0;L;;;;;N;;;;2D0D; +10AE;GEORGIAN CAPITAL LETTER PAR;Lu;0;L;;;;;N;;;;2D0E; +10AF;GEORGIAN CAPITAL LETTER ZHAR;Lu;0;L;;;;;N;;;;2D0F; +10B0;GEORGIAN CAPITAL LETTER RAE;Lu;0;L;;;;;N;;;;2D10; +10B1;GEORGIAN CAPITAL LETTER SAN;Lu;0;L;;;;;N;;;;2D11; +10B2;GEORGIAN CAPITAL LETTER TAR;Lu;0;L;;;;;N;;;;2D12; +10B3;GEORGIAN CAPITAL LETTER UN;Lu;0;L;;;;;N;;;;2D13; +10B4;GEORGIAN CAPITAL LETTER PHAR;Lu;0;L;;;;;N;;;;2D14; +10B5;GEORGIAN CAPITAL LETTER KHAR;Lu;0;L;;;;;N;;;;2D15; +10B6;GEORGIAN CAPITAL LETTER GHAN;Lu;0;L;;;;;N;;;;2D16; +10B7;GEORGIAN CAPITAL LETTER QAR;Lu;0;L;;;;;N;;;;2D17; +10B8;GEORGIAN CAPITAL LETTER SHIN;Lu;0;L;;;;;N;;;;2D18; +10B9;GEORGIAN CAPITAL LETTER CHIN;Lu;0;L;;;;;N;;;;2D19; +10BA;GEORGIAN CAPITAL LETTER CAN;Lu;0;L;;;;;N;;;;2D1A; +10BB;GEORGIAN CAPITAL LETTER JIL;Lu;0;L;;;;;N;;;;2D1B; +10BC;GEORGIAN CAPITAL LETTER CIL;Lu;0;L;;;;;N;;;;2D1C; +10BD;GEORGIAN CAPITAL LETTER CHAR;Lu;0;L;;;;;N;;;;2D1D; +10BE;GEORGIAN CAPITAL LETTER XAN;Lu;0;L;;;;;N;;;;2D1E; +10BF;GEORGIAN CAPITAL LETTER JHAN;Lu;0;L;;;;;N;;;;2D1F; +10C0;GEORGIAN CAPITAL LETTER HAE;Lu;0;L;;;;;N;;;;2D20; +10C1;GEORGIAN CAPITAL LETTER HE;Lu;0;L;;;;;N;;;;2D21; +10C2;GEORGIAN CAPITAL LETTER HIE;Lu;0;L;;;;;N;;;;2D22; +10C3;GEORGIAN CAPITAL LETTER WE;Lu;0;L;;;;;N;;;;2D23; +10C4;GEORGIAN CAPITAL LETTER HAR;Lu;0;L;;;;;N;;;;2D24; +10C5;GEORGIAN CAPITAL LETTER HOE;Lu;0;L;;;;;N;;;;2D25; +10C7;GEORGIAN CAPITAL LETTER YN;Lu;0;L;;;;;N;;;;2D27; +10CD;GEORGIAN CAPITAL LETTER AEN;Lu;0;L;;;;;N;;;;2D2D; +10D0;GEORGIAN LETTER AN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER AN;;1C90;;10D0 +10D1;GEORGIAN LETTER BAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER BAN;;1C91;;10D1 +10D2;GEORGIAN LETTER GAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER GAN;;1C92;;10D2 +10D3;GEORGIAN LETTER DON;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER DON;;1C93;;10D3 +10D4;GEORGIAN LETTER EN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER EN;;1C94;;10D4 +10D5;GEORGIAN LETTER VIN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER VIN;;1C95;;10D5 +10D6;GEORGIAN LETTER ZEN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER ZEN;;1C96;;10D6 +10D7;GEORGIAN LETTER TAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER TAN;;1C97;;10D7 +10D8;GEORGIAN LETTER IN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER IN;;1C98;;10D8 +10D9;GEORGIAN LETTER KAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER KAN;;1C99;;10D9 +10DA;GEORGIAN LETTER LAS;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER LAS;;1C9A;;10DA +10DB;GEORGIAN LETTER MAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER MAN;;1C9B;;10DB +10DC;GEORGIAN LETTER NAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER NAR;;1C9C;;10DC +10DD;GEORGIAN LETTER ON;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER ON;;1C9D;;10DD +10DE;GEORGIAN LETTER PAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER PAR;;1C9E;;10DE +10DF;GEORGIAN LETTER ZHAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER ZHAR;;1C9F;;10DF +10E0;GEORGIAN LETTER RAE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER RAE;;1CA0;;10E0 +10E1;GEORGIAN LETTER SAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER SAN;;1CA1;;10E1 +10E2;GEORGIAN LETTER TAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER TAR;;1CA2;;10E2 +10E3;GEORGIAN LETTER UN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER UN;;1CA3;;10E3 +10E4;GEORGIAN LETTER PHAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER PHAR;;1CA4;;10E4 +10E5;GEORGIAN LETTER KHAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER KHAR;;1CA5;;10E5 +10E6;GEORGIAN LETTER GHAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER GHAN;;1CA6;;10E6 +10E7;GEORGIAN LETTER QAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER QAR;;1CA7;;10E7 +10E8;GEORGIAN LETTER SHIN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER SHIN;;1CA8;;10E8 +10E9;GEORGIAN LETTER CHIN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER CHIN;;1CA9;;10E9 +10EA;GEORGIAN LETTER CAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER CAN;;1CAA;;10EA +10EB;GEORGIAN LETTER JIL;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER JIL;;1CAB;;10EB +10EC;GEORGIAN LETTER CIL;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER CIL;;1CAC;;10EC +10ED;GEORGIAN LETTER CHAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER CHAR;;1CAD;;10ED +10EE;GEORGIAN LETTER XAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER XAN;;1CAE;;10EE +10EF;GEORGIAN LETTER JHAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER JHAN;;1CAF;;10EF +10F0;GEORGIAN LETTER HAE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER HAE;;1CB0;;10F0 +10F1;GEORGIAN LETTER HE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER HE;;1CB1;;10F1 +10F2;GEORGIAN LETTER HIE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER HIE;;1CB2;;10F2 +10F3;GEORGIAN LETTER WE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER WE;;1CB3;;10F3 +10F4;GEORGIAN LETTER HAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER HAR;;1CB4;;10F4 +10F5;GEORGIAN LETTER HOE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER HOE;;1CB5;;10F5 +10F6;GEORGIAN LETTER FI;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER FI;;1CB6;;10F6 +10F7;GEORGIAN LETTER YN;Ll;0;L;;;;;N;;;1CB7;;10F7 +10F8;GEORGIAN LETTER ELIFI;Ll;0;L;;;;;N;;;1CB8;;10F8 +10F9;GEORGIAN LETTER TURNED GAN;Ll;0;L;;;;;N;;;1CB9;;10F9 +10FA;GEORGIAN LETTER AIN;Ll;0;L;;;;;N;;;1CBA;;10FA +10FB;GEORGIAN PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;; +10FC;MODIFIER LETTER GEORGIAN NAR;Lm;0;L; 10DC;;;;N;;;;; +10FD;GEORGIAN LETTER AEN;Ll;0;L;;;;;N;;;1CBD;;10FD +10FE;GEORGIAN LETTER HARD SIGN;Ll;0;L;;;;;N;;;1CBE;;10FE +10FF;GEORGIAN LETTER LABIAL SIGN;Ll;0;L;;;;;N;;;1CBF;;10FF +1100;HANGUL CHOSEONG KIYEOK;Lo;0;L;;;;;N;;;;; +1101;HANGUL CHOSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;;;; +1102;HANGUL CHOSEONG NIEUN;Lo;0;L;;;;;N;;;;; +1103;HANGUL CHOSEONG TIKEUT;Lo;0;L;;;;;N;;;;; +1104;HANGUL CHOSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;;;; +1105;HANGUL CHOSEONG RIEUL;Lo;0;L;;;;;N;;;;; +1106;HANGUL CHOSEONG MIEUM;Lo;0;L;;;;;N;;;;; +1107;HANGUL CHOSEONG PIEUP;Lo;0;L;;;;;N;;;;; +1108;HANGUL CHOSEONG SSANGPIEUP;Lo;0;L;;;;;N;;;;; +1109;HANGUL CHOSEONG SIOS;Lo;0;L;;;;;N;;;;; +110A;HANGUL CHOSEONG SSANGSIOS;Lo;0;L;;;;;N;;;;; +110B;HANGUL CHOSEONG IEUNG;Lo;0;L;;;;;N;;;;; +110C;HANGUL CHOSEONG CIEUC;Lo;0;L;;;;;N;;;;; +110D;HANGUL CHOSEONG SSANGCIEUC;Lo;0;L;;;;;N;;;;; +110E;HANGUL CHOSEONG CHIEUCH;Lo;0;L;;;;;N;;;;; +110F;HANGUL CHOSEONG KHIEUKH;Lo;0;L;;;;;N;;;;; +1110;HANGUL CHOSEONG THIEUTH;Lo;0;L;;;;;N;;;;; +1111;HANGUL CHOSEONG PHIEUPH;Lo;0;L;;;;;N;;;;; +1112;HANGUL CHOSEONG HIEUH;Lo;0;L;;;;;N;;;;; +1113;HANGUL CHOSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;; +1114;HANGUL CHOSEONG SSANGNIEUN;Lo;0;L;;;;;N;;;;; +1115;HANGUL CHOSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;; +1116;HANGUL CHOSEONG NIEUN-PIEUP;Lo;0;L;;;;;N;;;;; +1117;HANGUL CHOSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;; +1118;HANGUL CHOSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;; +1119;HANGUL CHOSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;; +111A;HANGUL CHOSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;;;; +111B;HANGUL CHOSEONG KAPYEOUNRIEUL;Lo;0;L;;;;;N;;;;; +111C;HANGUL CHOSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;; +111D;HANGUL CHOSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;; +111E;HANGUL CHOSEONG PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;; +111F;HANGUL CHOSEONG PIEUP-NIEUN;Lo;0;L;;;;;N;;;;; +1120;HANGUL CHOSEONG PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;; +1121;HANGUL CHOSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;;;; +1122;HANGUL CHOSEONG PIEUP-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +1123;HANGUL CHOSEONG PIEUP-SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +1124;HANGUL CHOSEONG PIEUP-SIOS-PIEUP;Lo;0;L;;;;;N;;;;; +1125;HANGUL CHOSEONG PIEUP-SSANGSIOS;Lo;0;L;;;;;N;;;;; +1126;HANGUL CHOSEONG PIEUP-SIOS-CIEUC;Lo;0;L;;;;;N;;;;; +1127;HANGUL CHOSEONG PIEUP-CIEUC;Lo;0;L;;;;;N;;;;; +1128;HANGUL CHOSEONG PIEUP-CHIEUCH;Lo;0;L;;;;;N;;;;; +1129;HANGUL CHOSEONG PIEUP-THIEUTH;Lo;0;L;;;;;N;;;;; +112A;HANGUL CHOSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;; +112B;HANGUL CHOSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +112C;HANGUL CHOSEONG KAPYEOUNSSANGPIEUP;Lo;0;L;;;;;N;;;;; +112D;HANGUL CHOSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +112E;HANGUL CHOSEONG SIOS-NIEUN;Lo;0;L;;;;;N;;;;; +112F;HANGUL CHOSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +1130;HANGUL CHOSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;; +1131;HANGUL CHOSEONG SIOS-MIEUM;Lo;0;L;;;;;N;;;;; +1132;HANGUL CHOSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;; +1133;HANGUL CHOSEONG SIOS-PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;; +1134;HANGUL CHOSEONG SIOS-SSANGSIOS;Lo;0;L;;;;;N;;;;; +1135;HANGUL CHOSEONG SIOS-IEUNG;Lo;0;L;;;;;N;;;;; +1136;HANGUL CHOSEONG SIOS-CIEUC;Lo;0;L;;;;;N;;;;; +1137;HANGUL CHOSEONG SIOS-CHIEUCH;Lo;0;L;;;;;N;;;;; +1138;HANGUL CHOSEONG SIOS-KHIEUKH;Lo;0;L;;;;;N;;;;; +1139;HANGUL CHOSEONG SIOS-THIEUTH;Lo;0;L;;;;;N;;;;; +113A;HANGUL CHOSEONG SIOS-PHIEUPH;Lo;0;L;;;;;N;;;;; +113B;HANGUL CHOSEONG SIOS-HIEUH;Lo;0;L;;;;;N;;;;; +113C;HANGUL CHOSEONG CHITUEUMSIOS;Lo;0;L;;;;;N;;;;; +113D;HANGUL CHOSEONG CHITUEUMSSANGSIOS;Lo;0;L;;;;;N;;;;; +113E;HANGUL CHOSEONG CEONGCHIEUMSIOS;Lo;0;L;;;;;N;;;;; +113F;HANGUL CHOSEONG CEONGCHIEUMSSANGSIOS;Lo;0;L;;;;;N;;;;; +1140;HANGUL CHOSEONG PANSIOS;Lo;0;L;;;;;N;;;;; +1141;HANGUL CHOSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;; +1142;HANGUL CHOSEONG IEUNG-TIKEUT;Lo;0;L;;;;;N;;;;; +1143;HANGUL CHOSEONG IEUNG-MIEUM;Lo;0;L;;;;;N;;;;; +1144;HANGUL CHOSEONG IEUNG-PIEUP;Lo;0;L;;;;;N;;;;; +1145;HANGUL CHOSEONG IEUNG-SIOS;Lo;0;L;;;;;N;;;;; +1146;HANGUL CHOSEONG IEUNG-PANSIOS;Lo;0;L;;;;;N;;;;; +1147;HANGUL CHOSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;; +1148;HANGUL CHOSEONG IEUNG-CIEUC;Lo;0;L;;;;;N;;;;; +1149;HANGUL CHOSEONG IEUNG-CHIEUCH;Lo;0;L;;;;;N;;;;; +114A;HANGUL CHOSEONG IEUNG-THIEUTH;Lo;0;L;;;;;N;;;;; +114B;HANGUL CHOSEONG IEUNG-PHIEUPH;Lo;0;L;;;;;N;;;;; +114C;HANGUL CHOSEONG YESIEUNG;Lo;0;L;;;;;N;;;;; +114D;HANGUL CHOSEONG CIEUC-IEUNG;Lo;0;L;;;;;N;;;;; +114E;HANGUL CHOSEONG CHITUEUMCIEUC;Lo;0;L;;;;;N;;;;; +114F;HANGUL CHOSEONG CHITUEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;; +1150;HANGUL CHOSEONG CEONGCHIEUMCIEUC;Lo;0;L;;;;;N;;;;; +1151;HANGUL CHOSEONG CEONGCHIEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;; +1152;HANGUL CHOSEONG CHIEUCH-KHIEUKH;Lo;0;L;;;;;N;;;;; +1153;HANGUL CHOSEONG CHIEUCH-HIEUH;Lo;0;L;;;;;N;;;;; +1154;HANGUL CHOSEONG CHITUEUMCHIEUCH;Lo;0;L;;;;;N;;;;; +1155;HANGUL CHOSEONG CEONGCHIEUMCHIEUCH;Lo;0;L;;;;;N;;;;; +1156;HANGUL CHOSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;; +1157;HANGUL CHOSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;; +1158;HANGUL CHOSEONG SSANGHIEUH;Lo;0;L;;;;;N;;;;; +1159;HANGUL CHOSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;; +115A;HANGUL CHOSEONG KIYEOK-TIKEUT;Lo;0;L;;;;;N;;;;; +115B;HANGUL CHOSEONG NIEUN-SIOS;Lo;0;L;;;;;N;;;;; +115C;HANGUL CHOSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;;;; +115D;HANGUL CHOSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;;;; +115E;HANGUL CHOSEONG TIKEUT-RIEUL;Lo;0;L;;;;;N;;;;; +115F;HANGUL CHOSEONG FILLER;Lo;0;L;;;;;N;;;;; +1160;HANGUL JUNGSEONG FILLER;Lo;0;L;;;;;N;;;;; +1161;HANGUL JUNGSEONG A;Lo;0;L;;;;;N;;;;; +1162;HANGUL JUNGSEONG AE;Lo;0;L;;;;;N;;;;; +1163;HANGUL JUNGSEONG YA;Lo;0;L;;;;;N;;;;; +1164;HANGUL JUNGSEONG YAE;Lo;0;L;;;;;N;;;;; +1165;HANGUL JUNGSEONG EO;Lo;0;L;;;;;N;;;;; +1166;HANGUL JUNGSEONG E;Lo;0;L;;;;;N;;;;; +1167;HANGUL JUNGSEONG YEO;Lo;0;L;;;;;N;;;;; +1168;HANGUL JUNGSEONG YE;Lo;0;L;;;;;N;;;;; +1169;HANGUL JUNGSEONG O;Lo;0;L;;;;;N;;;;; +116A;HANGUL JUNGSEONG WA;Lo;0;L;;;;;N;;;;; +116B;HANGUL JUNGSEONG WAE;Lo;0;L;;;;;N;;;;; +116C;HANGUL JUNGSEONG OE;Lo;0;L;;;;;N;;;;; +116D;HANGUL JUNGSEONG YO;Lo;0;L;;;;;N;;;;; +116E;HANGUL JUNGSEONG U;Lo;0;L;;;;;N;;;;; +116F;HANGUL JUNGSEONG WEO;Lo;0;L;;;;;N;;;;; +1170;HANGUL JUNGSEONG WE;Lo;0;L;;;;;N;;;;; +1171;HANGUL JUNGSEONG WI;Lo;0;L;;;;;N;;;;; +1172;HANGUL JUNGSEONG YU;Lo;0;L;;;;;N;;;;; +1173;HANGUL JUNGSEONG EU;Lo;0;L;;;;;N;;;;; +1174;HANGUL JUNGSEONG YI;Lo;0;L;;;;;N;;;;; +1175;HANGUL JUNGSEONG I;Lo;0;L;;;;;N;;;;; +1176;HANGUL JUNGSEONG A-O;Lo;0;L;;;;;N;;;;; +1177;HANGUL JUNGSEONG A-U;Lo;0;L;;;;;N;;;;; +1178;HANGUL JUNGSEONG YA-O;Lo;0;L;;;;;N;;;;; +1179;HANGUL JUNGSEONG YA-YO;Lo;0;L;;;;;N;;;;; +117A;HANGUL JUNGSEONG EO-O;Lo;0;L;;;;;N;;;;; +117B;HANGUL JUNGSEONG EO-U;Lo;0;L;;;;;N;;;;; +117C;HANGUL JUNGSEONG EO-EU;Lo;0;L;;;;;N;;;;; +117D;HANGUL JUNGSEONG YEO-O;Lo;0;L;;;;;N;;;;; +117E;HANGUL JUNGSEONG YEO-U;Lo;0;L;;;;;N;;;;; +117F;HANGUL JUNGSEONG O-EO;Lo;0;L;;;;;N;;;;; +1180;HANGUL JUNGSEONG O-E;Lo;0;L;;;;;N;;;;; +1181;HANGUL JUNGSEONG O-YE;Lo;0;L;;;;;N;;;;; +1182;HANGUL JUNGSEONG O-O;Lo;0;L;;;;;N;;;;; +1183;HANGUL JUNGSEONG O-U;Lo;0;L;;;;;N;;;;; +1184;HANGUL JUNGSEONG YO-YA;Lo;0;L;;;;;N;;;;; +1185;HANGUL JUNGSEONG YO-YAE;Lo;0;L;;;;;N;;;;; +1186;HANGUL JUNGSEONG YO-YEO;Lo;0;L;;;;;N;;;;; +1187;HANGUL JUNGSEONG YO-O;Lo;0;L;;;;;N;;;;; +1188;HANGUL JUNGSEONG YO-I;Lo;0;L;;;;;N;;;;; +1189;HANGUL JUNGSEONG U-A;Lo;0;L;;;;;N;;;;; +118A;HANGUL JUNGSEONG U-AE;Lo;0;L;;;;;N;;;;; +118B;HANGUL JUNGSEONG U-EO-EU;Lo;0;L;;;;;N;;;;; +118C;HANGUL JUNGSEONG U-YE;Lo;0;L;;;;;N;;;;; +118D;HANGUL JUNGSEONG U-U;Lo;0;L;;;;;N;;;;; +118E;HANGUL JUNGSEONG YU-A;Lo;0;L;;;;;N;;;;; +118F;HANGUL JUNGSEONG YU-EO;Lo;0;L;;;;;N;;;;; +1190;HANGUL JUNGSEONG YU-E;Lo;0;L;;;;;N;;;;; +1191;HANGUL JUNGSEONG YU-YEO;Lo;0;L;;;;;N;;;;; +1192;HANGUL JUNGSEONG YU-YE;Lo;0;L;;;;;N;;;;; +1193;HANGUL JUNGSEONG YU-U;Lo;0;L;;;;;N;;;;; +1194;HANGUL JUNGSEONG YU-I;Lo;0;L;;;;;N;;;;; +1195;HANGUL JUNGSEONG EU-U;Lo;0;L;;;;;N;;;;; +1196;HANGUL JUNGSEONG EU-EU;Lo;0;L;;;;;N;;;;; +1197;HANGUL JUNGSEONG YI-U;Lo;0;L;;;;;N;;;;; +1198;HANGUL JUNGSEONG I-A;Lo;0;L;;;;;N;;;;; +1199;HANGUL JUNGSEONG I-YA;Lo;0;L;;;;;N;;;;; +119A;HANGUL JUNGSEONG I-O;Lo;0;L;;;;;N;;;;; +119B;HANGUL JUNGSEONG I-U;Lo;0;L;;;;;N;;;;; +119C;HANGUL JUNGSEONG I-EU;Lo;0;L;;;;;N;;;;; +119D;HANGUL JUNGSEONG I-ARAEA;Lo;0;L;;;;;N;;;;; +119E;HANGUL JUNGSEONG ARAEA;Lo;0;L;;;;;N;;;;; +119F;HANGUL JUNGSEONG ARAEA-EO;Lo;0;L;;;;;N;;;;; +11A0;HANGUL JUNGSEONG ARAEA-U;Lo;0;L;;;;;N;;;;; +11A1;HANGUL JUNGSEONG ARAEA-I;Lo;0;L;;;;;N;;;;; +11A2;HANGUL JUNGSEONG SSANGARAEA;Lo;0;L;;;;;N;;;;; +11A3;HANGUL JUNGSEONG A-EU;Lo;0;L;;;;;N;;;;; +11A4;HANGUL JUNGSEONG YA-U;Lo;0;L;;;;;N;;;;; +11A5;HANGUL JUNGSEONG YEO-YA;Lo;0;L;;;;;N;;;;; +11A6;HANGUL JUNGSEONG O-YA;Lo;0;L;;;;;N;;;;; +11A7;HANGUL JUNGSEONG O-YAE;Lo;0;L;;;;;N;;;;; +11A8;HANGUL JONGSEONG KIYEOK;Lo;0;L;;;;;N;;;;; +11A9;HANGUL JONGSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;;;; +11AA;HANGUL JONGSEONG KIYEOK-SIOS;Lo;0;L;;;;;N;;;;; +11AB;HANGUL JONGSEONG NIEUN;Lo;0;L;;;;;N;;;;; +11AC;HANGUL JONGSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;;;; +11AD;HANGUL JONGSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;;;; +11AE;HANGUL JONGSEONG TIKEUT;Lo;0;L;;;;;N;;;;; +11AF;HANGUL JONGSEONG RIEUL;Lo;0;L;;;;;N;;;;; +11B0;HANGUL JONGSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;;;; +11B1;HANGUL JONGSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;;;; +11B2;HANGUL JONGSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;;;; +11B3;HANGUL JONGSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;;;; +11B4;HANGUL JONGSEONG RIEUL-THIEUTH;Lo;0;L;;;;;N;;;;; +11B5;HANGUL JONGSEONG RIEUL-PHIEUPH;Lo;0;L;;;;;N;;;;; +11B6;HANGUL JONGSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;;;; +11B7;HANGUL JONGSEONG MIEUM;Lo;0;L;;;;;N;;;;; +11B8;HANGUL JONGSEONG PIEUP;Lo;0;L;;;;;N;;;;; +11B9;HANGUL JONGSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;;;; +11BA;HANGUL JONGSEONG SIOS;Lo;0;L;;;;;N;;;;; +11BB;HANGUL JONGSEONG SSANGSIOS;Lo;0;L;;;;;N;;;;; +11BC;HANGUL JONGSEONG IEUNG;Lo;0;L;;;;;N;;;;; +11BD;HANGUL JONGSEONG CIEUC;Lo;0;L;;;;;N;;;;; +11BE;HANGUL JONGSEONG CHIEUCH;Lo;0;L;;;;;N;;;;; +11BF;HANGUL JONGSEONG KHIEUKH;Lo;0;L;;;;;N;;;;; +11C0;HANGUL JONGSEONG THIEUTH;Lo;0;L;;;;;N;;;;; +11C1;HANGUL JONGSEONG PHIEUPH;Lo;0;L;;;;;N;;;;; +11C2;HANGUL JONGSEONG HIEUH;Lo;0;L;;;;;N;;;;; +11C3;HANGUL JONGSEONG KIYEOK-RIEUL;Lo;0;L;;;;;N;;;;; +11C4;HANGUL JONGSEONG KIYEOK-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +11C5;HANGUL JONGSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;; +11C6;HANGUL JONGSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;; +11C7;HANGUL JONGSEONG NIEUN-SIOS;Lo;0;L;;;;;N;;;;; +11C8;HANGUL JONGSEONG NIEUN-PANSIOS;Lo;0;L;;;;;N;;;;; +11C9;HANGUL JONGSEONG NIEUN-THIEUTH;Lo;0;L;;;;;N;;;;; +11CA;HANGUL JONGSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;; +11CB;HANGUL JONGSEONG TIKEUT-RIEUL;Lo;0;L;;;;;N;;;;; +11CC;HANGUL JONGSEONG RIEUL-KIYEOK-SIOS;Lo;0;L;;;;;N;;;;; +11CD;HANGUL JONGSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;; +11CE;HANGUL JONGSEONG RIEUL-TIKEUT;Lo;0;L;;;;;N;;;;; +11CF;HANGUL JONGSEONG RIEUL-TIKEUT-HIEUH;Lo;0;L;;;;;N;;;;; +11D0;HANGUL JONGSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;; +11D1;HANGUL JONGSEONG RIEUL-MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;; +11D2;HANGUL JONGSEONG RIEUL-MIEUM-SIOS;Lo;0;L;;;;;N;;;;; +11D3;HANGUL JONGSEONG RIEUL-PIEUP-SIOS;Lo;0;L;;;;;N;;;;; +11D4;HANGUL JONGSEONG RIEUL-PIEUP-HIEUH;Lo;0;L;;;;;N;;;;; +11D5;HANGUL JONGSEONG RIEUL-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +11D6;HANGUL JONGSEONG RIEUL-SSANGSIOS;Lo;0;L;;;;;N;;;;; +11D7;HANGUL JONGSEONG RIEUL-PANSIOS;Lo;0;L;;;;;N;;;;; +11D8;HANGUL JONGSEONG RIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;; +11D9;HANGUL JONGSEONG RIEUL-YEORINHIEUH;Lo;0;L;;;;;N;;;;; +11DA;HANGUL JONGSEONG MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;; +11DB;HANGUL JONGSEONG MIEUM-RIEUL;Lo;0;L;;;;;N;;;;; +11DC;HANGUL JONGSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;; +11DD;HANGUL JONGSEONG MIEUM-SIOS;Lo;0;L;;;;;N;;;;; +11DE;HANGUL JONGSEONG MIEUM-SSANGSIOS;Lo;0;L;;;;;N;;;;; +11DF;HANGUL JONGSEONG MIEUM-PANSIOS;Lo;0;L;;;;;N;;;;; +11E0;HANGUL JONGSEONG MIEUM-CHIEUCH;Lo;0;L;;;;;N;;;;; +11E1;HANGUL JONGSEONG MIEUM-HIEUH;Lo;0;L;;;;;N;;;;; +11E2;HANGUL JONGSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;; +11E3;HANGUL JONGSEONG PIEUP-RIEUL;Lo;0;L;;;;;N;;;;; +11E4;HANGUL JONGSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;; +11E5;HANGUL JONGSEONG PIEUP-HIEUH;Lo;0;L;;;;;N;;;;; +11E6;HANGUL JONGSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +11E7;HANGUL JONGSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +11E8;HANGUL JONGSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +11E9;HANGUL JONGSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;; +11EA;HANGUL JONGSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;; +11EB;HANGUL JONGSEONG PANSIOS;Lo;0;L;;;;;N;;;;; +11EC;HANGUL JONGSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;; +11ED;HANGUL JONGSEONG IEUNG-SSANGKIYEOK;Lo;0;L;;;;;N;;;;; +11EE;HANGUL JONGSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;; +11EF;HANGUL JONGSEONG IEUNG-KHIEUKH;Lo;0;L;;;;;N;;;;; +11F0;HANGUL JONGSEONG YESIEUNG;Lo;0;L;;;;;N;;;;; +11F1;HANGUL JONGSEONG YESIEUNG-SIOS;Lo;0;L;;;;;N;;;;; +11F2;HANGUL JONGSEONG YESIEUNG-PANSIOS;Lo;0;L;;;;;N;;;;; +11F3;HANGUL JONGSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;; +11F4;HANGUL JONGSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;; +11F5;HANGUL JONGSEONG HIEUH-NIEUN;Lo;0;L;;;;;N;;;;; +11F6;HANGUL JONGSEONG HIEUH-RIEUL;Lo;0;L;;;;;N;;;;; +11F7;HANGUL JONGSEONG HIEUH-MIEUM;Lo;0;L;;;;;N;;;;; +11F8;HANGUL JONGSEONG HIEUH-PIEUP;Lo;0;L;;;;;N;;;;; +11F9;HANGUL JONGSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;; +11FA;HANGUL JONGSEONG KIYEOK-NIEUN;Lo;0;L;;;;;N;;;;; +11FB;HANGUL JONGSEONG KIYEOK-PIEUP;Lo;0;L;;;;;N;;;;; +11FC;HANGUL JONGSEONG KIYEOK-CHIEUCH;Lo;0;L;;;;;N;;;;; +11FD;HANGUL JONGSEONG KIYEOK-KHIEUKH;Lo;0;L;;;;;N;;;;; +11FE;HANGUL JONGSEONG KIYEOK-HIEUH;Lo;0;L;;;;;N;;;;; +11FF;HANGUL JONGSEONG SSANGNIEUN;Lo;0;L;;;;;N;;;;; +1200;ETHIOPIC SYLLABLE HA;Lo;0;L;;;;;N;;;;; +1201;ETHIOPIC SYLLABLE HU;Lo;0;L;;;;;N;;;;; +1202;ETHIOPIC SYLLABLE HI;Lo;0;L;;;;;N;;;;; +1203;ETHIOPIC SYLLABLE HAA;Lo;0;L;;;;;N;;;;; +1204;ETHIOPIC SYLLABLE HEE;Lo;0;L;;;;;N;;;;; +1205;ETHIOPIC SYLLABLE HE;Lo;0;L;;;;;N;;;;; +1206;ETHIOPIC SYLLABLE HO;Lo;0;L;;;;;N;;;;; +1207;ETHIOPIC SYLLABLE HOA;Lo;0;L;;;;;N;;;;; +1208;ETHIOPIC SYLLABLE LA;Lo;0;L;;;;;N;;;;; +1209;ETHIOPIC SYLLABLE LU;Lo;0;L;;;;;N;;;;; +120A;ETHIOPIC SYLLABLE LI;Lo;0;L;;;;;N;;;;; +120B;ETHIOPIC SYLLABLE LAA;Lo;0;L;;;;;N;;;;; +120C;ETHIOPIC SYLLABLE LEE;Lo;0;L;;;;;N;;;;; +120D;ETHIOPIC SYLLABLE LE;Lo;0;L;;;;;N;;;;; +120E;ETHIOPIC SYLLABLE LO;Lo;0;L;;;;;N;;;;; +120F;ETHIOPIC SYLLABLE LWA;Lo;0;L;;;;;N;;;;; +1210;ETHIOPIC SYLLABLE HHA;Lo;0;L;;;;;N;;;;; +1211;ETHIOPIC SYLLABLE HHU;Lo;0;L;;;;;N;;;;; +1212;ETHIOPIC SYLLABLE HHI;Lo;0;L;;;;;N;;;;; +1213;ETHIOPIC SYLLABLE HHAA;Lo;0;L;;;;;N;;;;; +1214;ETHIOPIC SYLLABLE HHEE;Lo;0;L;;;;;N;;;;; +1215;ETHIOPIC SYLLABLE HHE;Lo;0;L;;;;;N;;;;; +1216;ETHIOPIC SYLLABLE HHO;Lo;0;L;;;;;N;;;;; +1217;ETHIOPIC SYLLABLE HHWA;Lo;0;L;;;;;N;;;;; +1218;ETHIOPIC SYLLABLE MA;Lo;0;L;;;;;N;;;;; +1219;ETHIOPIC SYLLABLE MU;Lo;0;L;;;;;N;;;;; +121A;ETHIOPIC SYLLABLE MI;Lo;0;L;;;;;N;;;;; +121B;ETHIOPIC SYLLABLE MAA;Lo;0;L;;;;;N;;;;; +121C;ETHIOPIC SYLLABLE MEE;Lo;0;L;;;;;N;;;;; +121D;ETHIOPIC SYLLABLE ME;Lo;0;L;;;;;N;;;;; +121E;ETHIOPIC SYLLABLE MO;Lo;0;L;;;;;N;;;;; +121F;ETHIOPIC SYLLABLE MWA;Lo;0;L;;;;;N;;;;; +1220;ETHIOPIC SYLLABLE SZA;Lo;0;L;;;;;N;;;;; +1221;ETHIOPIC SYLLABLE SZU;Lo;0;L;;;;;N;;;;; +1222;ETHIOPIC SYLLABLE SZI;Lo;0;L;;;;;N;;;;; +1223;ETHIOPIC SYLLABLE SZAA;Lo;0;L;;;;;N;;;;; +1224;ETHIOPIC SYLLABLE SZEE;Lo;0;L;;;;;N;;;;; +1225;ETHIOPIC SYLLABLE SZE;Lo;0;L;;;;;N;;;;; +1226;ETHIOPIC SYLLABLE SZO;Lo;0;L;;;;;N;;;;; +1227;ETHIOPIC SYLLABLE SZWA;Lo;0;L;;;;;N;;;;; +1228;ETHIOPIC SYLLABLE RA;Lo;0;L;;;;;N;;;;; +1229;ETHIOPIC SYLLABLE RU;Lo;0;L;;;;;N;;;;; +122A;ETHIOPIC SYLLABLE RI;Lo;0;L;;;;;N;;;;; +122B;ETHIOPIC SYLLABLE RAA;Lo;0;L;;;;;N;;;;; +122C;ETHIOPIC SYLLABLE REE;Lo;0;L;;;;;N;;;;; +122D;ETHIOPIC SYLLABLE RE;Lo;0;L;;;;;N;;;;; +122E;ETHIOPIC SYLLABLE RO;Lo;0;L;;;;;N;;;;; +122F;ETHIOPIC SYLLABLE RWA;Lo;0;L;;;;;N;;;;; +1230;ETHIOPIC SYLLABLE SA;Lo;0;L;;;;;N;;;;; +1231;ETHIOPIC SYLLABLE SU;Lo;0;L;;;;;N;;;;; +1232;ETHIOPIC SYLLABLE SI;Lo;0;L;;;;;N;;;;; +1233;ETHIOPIC SYLLABLE SAA;Lo;0;L;;;;;N;;;;; +1234;ETHIOPIC SYLLABLE SEE;Lo;0;L;;;;;N;;;;; +1235;ETHIOPIC SYLLABLE SE;Lo;0;L;;;;;N;;;;; +1236;ETHIOPIC SYLLABLE SO;Lo;0;L;;;;;N;;;;; +1237;ETHIOPIC SYLLABLE SWA;Lo;0;L;;;;;N;;;;; +1238;ETHIOPIC SYLLABLE SHA;Lo;0;L;;;;;N;;;;; +1239;ETHIOPIC SYLLABLE SHU;Lo;0;L;;;;;N;;;;; +123A;ETHIOPIC SYLLABLE SHI;Lo;0;L;;;;;N;;;;; +123B;ETHIOPIC SYLLABLE SHAA;Lo;0;L;;;;;N;;;;; +123C;ETHIOPIC SYLLABLE SHEE;Lo;0;L;;;;;N;;;;; +123D;ETHIOPIC SYLLABLE SHE;Lo;0;L;;;;;N;;;;; +123E;ETHIOPIC SYLLABLE SHO;Lo;0;L;;;;;N;;;;; +123F;ETHIOPIC SYLLABLE SHWA;Lo;0;L;;;;;N;;;;; +1240;ETHIOPIC SYLLABLE QA;Lo;0;L;;;;;N;;;;; +1241;ETHIOPIC SYLLABLE QU;Lo;0;L;;;;;N;;;;; +1242;ETHIOPIC SYLLABLE QI;Lo;0;L;;;;;N;;;;; +1243;ETHIOPIC SYLLABLE QAA;Lo;0;L;;;;;N;;;;; +1244;ETHIOPIC SYLLABLE QEE;Lo;0;L;;;;;N;;;;; +1245;ETHIOPIC SYLLABLE QE;Lo;0;L;;;;;N;;;;; +1246;ETHIOPIC SYLLABLE QO;Lo;0;L;;;;;N;;;;; +1247;ETHIOPIC SYLLABLE QOA;Lo;0;L;;;;;N;;;;; +1248;ETHIOPIC SYLLABLE QWA;Lo;0;L;;;;;N;;;;; +124A;ETHIOPIC SYLLABLE QWI;Lo;0;L;;;;;N;;;;; +124B;ETHIOPIC SYLLABLE QWAA;Lo;0;L;;;;;N;;;;; +124C;ETHIOPIC SYLLABLE QWEE;Lo;0;L;;;;;N;;;;; +124D;ETHIOPIC SYLLABLE QWE;Lo;0;L;;;;;N;;;;; +1250;ETHIOPIC SYLLABLE QHA;Lo;0;L;;;;;N;;;;; +1251;ETHIOPIC SYLLABLE QHU;Lo;0;L;;;;;N;;;;; +1252;ETHIOPIC SYLLABLE QHI;Lo;0;L;;;;;N;;;;; +1253;ETHIOPIC SYLLABLE QHAA;Lo;0;L;;;;;N;;;;; +1254;ETHIOPIC SYLLABLE QHEE;Lo;0;L;;;;;N;;;;; +1255;ETHIOPIC SYLLABLE QHE;Lo;0;L;;;;;N;;;;; +1256;ETHIOPIC SYLLABLE QHO;Lo;0;L;;;;;N;;;;; +1258;ETHIOPIC SYLLABLE QHWA;Lo;0;L;;;;;N;;;;; +125A;ETHIOPIC SYLLABLE QHWI;Lo;0;L;;;;;N;;;;; +125B;ETHIOPIC SYLLABLE QHWAA;Lo;0;L;;;;;N;;;;; +125C;ETHIOPIC SYLLABLE QHWEE;Lo;0;L;;;;;N;;;;; +125D;ETHIOPIC SYLLABLE QHWE;Lo;0;L;;;;;N;;;;; +1260;ETHIOPIC SYLLABLE BA;Lo;0;L;;;;;N;;;;; +1261;ETHIOPIC SYLLABLE BU;Lo;0;L;;;;;N;;;;; +1262;ETHIOPIC SYLLABLE BI;Lo;0;L;;;;;N;;;;; +1263;ETHIOPIC SYLLABLE BAA;Lo;0;L;;;;;N;;;;; +1264;ETHIOPIC SYLLABLE BEE;Lo;0;L;;;;;N;;;;; +1265;ETHIOPIC SYLLABLE BE;Lo;0;L;;;;;N;;;;; +1266;ETHIOPIC SYLLABLE BO;Lo;0;L;;;;;N;;;;; +1267;ETHIOPIC SYLLABLE BWA;Lo;0;L;;;;;N;;;;; +1268;ETHIOPIC SYLLABLE VA;Lo;0;L;;;;;N;;;;; +1269;ETHIOPIC SYLLABLE VU;Lo;0;L;;;;;N;;;;; +126A;ETHIOPIC SYLLABLE VI;Lo;0;L;;;;;N;;;;; +126B;ETHIOPIC SYLLABLE VAA;Lo;0;L;;;;;N;;;;; +126C;ETHIOPIC SYLLABLE VEE;Lo;0;L;;;;;N;;;;; +126D;ETHIOPIC SYLLABLE VE;Lo;0;L;;;;;N;;;;; +126E;ETHIOPIC SYLLABLE VO;Lo;0;L;;;;;N;;;;; +126F;ETHIOPIC SYLLABLE VWA;Lo;0;L;;;;;N;;;;; +1270;ETHIOPIC SYLLABLE TA;Lo;0;L;;;;;N;;;;; +1271;ETHIOPIC SYLLABLE TU;Lo;0;L;;;;;N;;;;; +1272;ETHIOPIC SYLLABLE TI;Lo;0;L;;;;;N;;;;; +1273;ETHIOPIC SYLLABLE TAA;Lo;0;L;;;;;N;;;;; +1274;ETHIOPIC SYLLABLE TEE;Lo;0;L;;;;;N;;;;; +1275;ETHIOPIC SYLLABLE TE;Lo;0;L;;;;;N;;;;; +1276;ETHIOPIC SYLLABLE TO;Lo;0;L;;;;;N;;;;; +1277;ETHIOPIC SYLLABLE TWA;Lo;0;L;;;;;N;;;;; +1278;ETHIOPIC SYLLABLE CA;Lo;0;L;;;;;N;;;;; +1279;ETHIOPIC SYLLABLE CU;Lo;0;L;;;;;N;;;;; +127A;ETHIOPIC SYLLABLE CI;Lo;0;L;;;;;N;;;;; +127B;ETHIOPIC SYLLABLE CAA;Lo;0;L;;;;;N;;;;; +127C;ETHIOPIC SYLLABLE CEE;Lo;0;L;;;;;N;;;;; +127D;ETHIOPIC SYLLABLE CE;Lo;0;L;;;;;N;;;;; +127E;ETHIOPIC SYLLABLE CO;Lo;0;L;;;;;N;;;;; +127F;ETHIOPIC SYLLABLE CWA;Lo;0;L;;;;;N;;;;; +1280;ETHIOPIC SYLLABLE XA;Lo;0;L;;;;;N;;;;; +1281;ETHIOPIC SYLLABLE XU;Lo;0;L;;;;;N;;;;; +1282;ETHIOPIC SYLLABLE XI;Lo;0;L;;;;;N;;;;; +1283;ETHIOPIC SYLLABLE XAA;Lo;0;L;;;;;N;;;;; +1284;ETHIOPIC SYLLABLE XEE;Lo;0;L;;;;;N;;;;; +1285;ETHIOPIC SYLLABLE XE;Lo;0;L;;;;;N;;;;; +1286;ETHIOPIC SYLLABLE XO;Lo;0;L;;;;;N;;;;; +1287;ETHIOPIC SYLLABLE XOA;Lo;0;L;;;;;N;;;;; +1288;ETHIOPIC SYLLABLE XWA;Lo;0;L;;;;;N;;;;; +128A;ETHIOPIC SYLLABLE XWI;Lo;0;L;;;;;N;;;;; +128B;ETHIOPIC SYLLABLE XWAA;Lo;0;L;;;;;N;;;;; +128C;ETHIOPIC SYLLABLE XWEE;Lo;0;L;;;;;N;;;;; +128D;ETHIOPIC SYLLABLE XWE;Lo;0;L;;;;;N;;;;; +1290;ETHIOPIC SYLLABLE NA;Lo;0;L;;;;;N;;;;; +1291;ETHIOPIC SYLLABLE NU;Lo;0;L;;;;;N;;;;; +1292;ETHIOPIC SYLLABLE NI;Lo;0;L;;;;;N;;;;; +1293;ETHIOPIC SYLLABLE NAA;Lo;0;L;;;;;N;;;;; +1294;ETHIOPIC SYLLABLE NEE;Lo;0;L;;;;;N;;;;; +1295;ETHIOPIC SYLLABLE NE;Lo;0;L;;;;;N;;;;; +1296;ETHIOPIC SYLLABLE NO;Lo;0;L;;;;;N;;;;; +1297;ETHIOPIC SYLLABLE NWA;Lo;0;L;;;;;N;;;;; +1298;ETHIOPIC SYLLABLE NYA;Lo;0;L;;;;;N;;;;; +1299;ETHIOPIC SYLLABLE NYU;Lo;0;L;;;;;N;;;;; +129A;ETHIOPIC SYLLABLE NYI;Lo;0;L;;;;;N;;;;; +129B;ETHIOPIC SYLLABLE NYAA;Lo;0;L;;;;;N;;;;; +129C;ETHIOPIC SYLLABLE NYEE;Lo;0;L;;;;;N;;;;; +129D;ETHIOPIC SYLLABLE NYE;Lo;0;L;;;;;N;;;;; +129E;ETHIOPIC SYLLABLE NYO;Lo;0;L;;;;;N;;;;; +129F;ETHIOPIC SYLLABLE NYWA;Lo;0;L;;;;;N;;;;; +12A0;ETHIOPIC SYLLABLE GLOTTAL A;Lo;0;L;;;;;N;;;;; +12A1;ETHIOPIC SYLLABLE GLOTTAL U;Lo;0;L;;;;;N;;;;; +12A2;ETHIOPIC SYLLABLE GLOTTAL I;Lo;0;L;;;;;N;;;;; +12A3;ETHIOPIC SYLLABLE GLOTTAL AA;Lo;0;L;;;;;N;;;;; +12A4;ETHIOPIC SYLLABLE GLOTTAL EE;Lo;0;L;;;;;N;;;;; +12A5;ETHIOPIC SYLLABLE GLOTTAL E;Lo;0;L;;;;;N;;;;; +12A6;ETHIOPIC SYLLABLE GLOTTAL O;Lo;0;L;;;;;N;;;;; +12A7;ETHIOPIC SYLLABLE GLOTTAL WA;Lo;0;L;;;;;N;;;;; +12A8;ETHIOPIC SYLLABLE KA;Lo;0;L;;;;;N;;;;; +12A9;ETHIOPIC SYLLABLE KU;Lo;0;L;;;;;N;;;;; +12AA;ETHIOPIC SYLLABLE KI;Lo;0;L;;;;;N;;;;; +12AB;ETHIOPIC SYLLABLE KAA;Lo;0;L;;;;;N;;;;; +12AC;ETHIOPIC SYLLABLE KEE;Lo;0;L;;;;;N;;;;; +12AD;ETHIOPIC SYLLABLE KE;Lo;0;L;;;;;N;;;;; +12AE;ETHIOPIC SYLLABLE KO;Lo;0;L;;;;;N;;;;; +12AF;ETHIOPIC SYLLABLE KOA;Lo;0;L;;;;;N;;;;; +12B0;ETHIOPIC SYLLABLE KWA;Lo;0;L;;;;;N;;;;; +12B2;ETHIOPIC SYLLABLE KWI;Lo;0;L;;;;;N;;;;; +12B3;ETHIOPIC SYLLABLE KWAA;Lo;0;L;;;;;N;;;;; +12B4;ETHIOPIC SYLLABLE KWEE;Lo;0;L;;;;;N;;;;; +12B5;ETHIOPIC SYLLABLE KWE;Lo;0;L;;;;;N;;;;; +12B8;ETHIOPIC SYLLABLE KXA;Lo;0;L;;;;;N;;;;; +12B9;ETHIOPIC SYLLABLE KXU;Lo;0;L;;;;;N;;;;; +12BA;ETHIOPIC SYLLABLE KXI;Lo;0;L;;;;;N;;;;; +12BB;ETHIOPIC SYLLABLE KXAA;Lo;0;L;;;;;N;;;;; +12BC;ETHIOPIC SYLLABLE KXEE;Lo;0;L;;;;;N;;;;; +12BD;ETHIOPIC SYLLABLE KXE;Lo;0;L;;;;;N;;;;; +12BE;ETHIOPIC SYLLABLE KXO;Lo;0;L;;;;;N;;;;; +12C0;ETHIOPIC SYLLABLE KXWA;Lo;0;L;;;;;N;;;;; +12C2;ETHIOPIC SYLLABLE KXWI;Lo;0;L;;;;;N;;;;; +12C3;ETHIOPIC SYLLABLE KXWAA;Lo;0;L;;;;;N;;;;; +12C4;ETHIOPIC SYLLABLE KXWEE;Lo;0;L;;;;;N;;;;; +12C5;ETHIOPIC SYLLABLE KXWE;Lo;0;L;;;;;N;;;;; +12C8;ETHIOPIC SYLLABLE WA;Lo;0;L;;;;;N;;;;; +12C9;ETHIOPIC SYLLABLE WU;Lo;0;L;;;;;N;;;;; +12CA;ETHIOPIC SYLLABLE WI;Lo;0;L;;;;;N;;;;; +12CB;ETHIOPIC SYLLABLE WAA;Lo;0;L;;;;;N;;;;; +12CC;ETHIOPIC SYLLABLE WEE;Lo;0;L;;;;;N;;;;; +12CD;ETHIOPIC SYLLABLE WE;Lo;0;L;;;;;N;;;;; +12CE;ETHIOPIC SYLLABLE WO;Lo;0;L;;;;;N;;;;; +12CF;ETHIOPIC SYLLABLE WOA;Lo;0;L;;;;;N;;;;; +12D0;ETHIOPIC SYLLABLE PHARYNGEAL A;Lo;0;L;;;;;N;;;;; +12D1;ETHIOPIC SYLLABLE PHARYNGEAL U;Lo;0;L;;;;;N;;;;; +12D2;ETHIOPIC SYLLABLE PHARYNGEAL I;Lo;0;L;;;;;N;;;;; +12D3;ETHIOPIC SYLLABLE PHARYNGEAL AA;Lo;0;L;;;;;N;;;;; +12D4;ETHIOPIC SYLLABLE PHARYNGEAL EE;Lo;0;L;;;;;N;;;;; +12D5;ETHIOPIC SYLLABLE PHARYNGEAL E;Lo;0;L;;;;;N;;;;; +12D6;ETHIOPIC SYLLABLE PHARYNGEAL O;Lo;0;L;;;;;N;;;;; +12D8;ETHIOPIC SYLLABLE ZA;Lo;0;L;;;;;N;;;;; +12D9;ETHIOPIC SYLLABLE ZU;Lo;0;L;;;;;N;;;;; +12DA;ETHIOPIC SYLLABLE ZI;Lo;0;L;;;;;N;;;;; +12DB;ETHIOPIC SYLLABLE ZAA;Lo;0;L;;;;;N;;;;; +12DC;ETHIOPIC SYLLABLE ZEE;Lo;0;L;;;;;N;;;;; +12DD;ETHIOPIC SYLLABLE ZE;Lo;0;L;;;;;N;;;;; +12DE;ETHIOPIC SYLLABLE ZO;Lo;0;L;;;;;N;;;;; +12DF;ETHIOPIC SYLLABLE ZWA;Lo;0;L;;;;;N;;;;; +12E0;ETHIOPIC SYLLABLE ZHA;Lo;0;L;;;;;N;;;;; +12E1;ETHIOPIC SYLLABLE ZHU;Lo;0;L;;;;;N;;;;; +12E2;ETHIOPIC SYLLABLE ZHI;Lo;0;L;;;;;N;;;;; +12E3;ETHIOPIC SYLLABLE ZHAA;Lo;0;L;;;;;N;;;;; +12E4;ETHIOPIC SYLLABLE ZHEE;Lo;0;L;;;;;N;;;;; +12E5;ETHIOPIC SYLLABLE ZHE;Lo;0;L;;;;;N;;;;; +12E6;ETHIOPIC SYLLABLE ZHO;Lo;0;L;;;;;N;;;;; +12E7;ETHIOPIC SYLLABLE ZHWA;Lo;0;L;;;;;N;;;;; +12E8;ETHIOPIC SYLLABLE YA;Lo;0;L;;;;;N;;;;; +12E9;ETHIOPIC SYLLABLE YU;Lo;0;L;;;;;N;;;;; +12EA;ETHIOPIC SYLLABLE YI;Lo;0;L;;;;;N;;;;; +12EB;ETHIOPIC SYLLABLE YAA;Lo;0;L;;;;;N;;;;; +12EC;ETHIOPIC SYLLABLE YEE;Lo;0;L;;;;;N;;;;; +12ED;ETHIOPIC SYLLABLE YE;Lo;0;L;;;;;N;;;;; +12EE;ETHIOPIC SYLLABLE YO;Lo;0;L;;;;;N;;;;; +12EF;ETHIOPIC SYLLABLE YOA;Lo;0;L;;;;;N;;;;; +12F0;ETHIOPIC SYLLABLE DA;Lo;0;L;;;;;N;;;;; +12F1;ETHIOPIC SYLLABLE DU;Lo;0;L;;;;;N;;;;; +12F2;ETHIOPIC SYLLABLE DI;Lo;0;L;;;;;N;;;;; +12F3;ETHIOPIC SYLLABLE DAA;Lo;0;L;;;;;N;;;;; +12F4;ETHIOPIC SYLLABLE DEE;Lo;0;L;;;;;N;;;;; +12F5;ETHIOPIC SYLLABLE DE;Lo;0;L;;;;;N;;;;; +12F6;ETHIOPIC SYLLABLE DO;Lo;0;L;;;;;N;;;;; +12F7;ETHIOPIC SYLLABLE DWA;Lo;0;L;;;;;N;;;;; +12F8;ETHIOPIC SYLLABLE DDA;Lo;0;L;;;;;N;;;;; +12F9;ETHIOPIC SYLLABLE DDU;Lo;0;L;;;;;N;;;;; +12FA;ETHIOPIC SYLLABLE DDI;Lo;0;L;;;;;N;;;;; +12FB;ETHIOPIC SYLLABLE DDAA;Lo;0;L;;;;;N;;;;; +12FC;ETHIOPIC SYLLABLE DDEE;Lo;0;L;;;;;N;;;;; +12FD;ETHIOPIC SYLLABLE DDE;Lo;0;L;;;;;N;;;;; +12FE;ETHIOPIC SYLLABLE DDO;Lo;0;L;;;;;N;;;;; +12FF;ETHIOPIC SYLLABLE DDWA;Lo;0;L;;;;;N;;;;; +1300;ETHIOPIC SYLLABLE JA;Lo;0;L;;;;;N;;;;; +1301;ETHIOPIC SYLLABLE JU;Lo;0;L;;;;;N;;;;; +1302;ETHIOPIC SYLLABLE JI;Lo;0;L;;;;;N;;;;; +1303;ETHIOPIC SYLLABLE JAA;Lo;0;L;;;;;N;;;;; +1304;ETHIOPIC SYLLABLE JEE;Lo;0;L;;;;;N;;;;; +1305;ETHIOPIC SYLLABLE JE;Lo;0;L;;;;;N;;;;; +1306;ETHIOPIC SYLLABLE JO;Lo;0;L;;;;;N;;;;; +1307;ETHIOPIC SYLLABLE JWA;Lo;0;L;;;;;N;;;;; +1308;ETHIOPIC SYLLABLE GA;Lo;0;L;;;;;N;;;;; +1309;ETHIOPIC SYLLABLE GU;Lo;0;L;;;;;N;;;;; +130A;ETHIOPIC SYLLABLE GI;Lo;0;L;;;;;N;;;;; +130B;ETHIOPIC SYLLABLE GAA;Lo;0;L;;;;;N;;;;; +130C;ETHIOPIC SYLLABLE GEE;Lo;0;L;;;;;N;;;;; +130D;ETHIOPIC SYLLABLE GE;Lo;0;L;;;;;N;;;;; +130E;ETHIOPIC SYLLABLE GO;Lo;0;L;;;;;N;;;;; +130F;ETHIOPIC SYLLABLE GOA;Lo;0;L;;;;;N;;;;; +1310;ETHIOPIC SYLLABLE GWA;Lo;0;L;;;;;N;;;;; +1312;ETHIOPIC SYLLABLE GWI;Lo;0;L;;;;;N;;;;; +1313;ETHIOPIC SYLLABLE GWAA;Lo;0;L;;;;;N;;;;; +1314;ETHIOPIC SYLLABLE GWEE;Lo;0;L;;;;;N;;;;; +1315;ETHIOPIC SYLLABLE GWE;Lo;0;L;;;;;N;;;;; +1318;ETHIOPIC SYLLABLE GGA;Lo;0;L;;;;;N;;;;; +1319;ETHIOPIC SYLLABLE GGU;Lo;0;L;;;;;N;;;;; +131A;ETHIOPIC SYLLABLE GGI;Lo;0;L;;;;;N;;;;; +131B;ETHIOPIC SYLLABLE GGAA;Lo;0;L;;;;;N;;;;; +131C;ETHIOPIC SYLLABLE GGEE;Lo;0;L;;;;;N;;;;; +131D;ETHIOPIC SYLLABLE GGE;Lo;0;L;;;;;N;;;;; +131E;ETHIOPIC SYLLABLE GGO;Lo;0;L;;;;;N;;;;; +131F;ETHIOPIC SYLLABLE GGWAA;Lo;0;L;;;;;N;;;;; +1320;ETHIOPIC SYLLABLE THA;Lo;0;L;;;;;N;;;;; +1321;ETHIOPIC SYLLABLE THU;Lo;0;L;;;;;N;;;;; +1322;ETHIOPIC SYLLABLE THI;Lo;0;L;;;;;N;;;;; +1323;ETHIOPIC SYLLABLE THAA;Lo;0;L;;;;;N;;;;; +1324;ETHIOPIC SYLLABLE THEE;Lo;0;L;;;;;N;;;;; +1325;ETHIOPIC SYLLABLE THE;Lo;0;L;;;;;N;;;;; +1326;ETHIOPIC SYLLABLE THO;Lo;0;L;;;;;N;;;;; +1327;ETHIOPIC SYLLABLE THWA;Lo;0;L;;;;;N;;;;; +1328;ETHIOPIC SYLLABLE CHA;Lo;0;L;;;;;N;;;;; +1329;ETHIOPIC SYLLABLE CHU;Lo;0;L;;;;;N;;;;; +132A;ETHIOPIC SYLLABLE CHI;Lo;0;L;;;;;N;;;;; +132B;ETHIOPIC SYLLABLE CHAA;Lo;0;L;;;;;N;;;;; +132C;ETHIOPIC SYLLABLE CHEE;Lo;0;L;;;;;N;;;;; +132D;ETHIOPIC SYLLABLE CHE;Lo;0;L;;;;;N;;;;; +132E;ETHIOPIC SYLLABLE CHO;Lo;0;L;;;;;N;;;;; +132F;ETHIOPIC SYLLABLE CHWA;Lo;0;L;;;;;N;;;;; +1330;ETHIOPIC SYLLABLE PHA;Lo;0;L;;;;;N;;;;; +1331;ETHIOPIC SYLLABLE PHU;Lo;0;L;;;;;N;;;;; +1332;ETHIOPIC SYLLABLE PHI;Lo;0;L;;;;;N;;;;; +1333;ETHIOPIC SYLLABLE PHAA;Lo;0;L;;;;;N;;;;; +1334;ETHIOPIC SYLLABLE PHEE;Lo;0;L;;;;;N;;;;; +1335;ETHIOPIC SYLLABLE PHE;Lo;0;L;;;;;N;;;;; +1336;ETHIOPIC SYLLABLE PHO;Lo;0;L;;;;;N;;;;; +1337;ETHIOPIC SYLLABLE PHWA;Lo;0;L;;;;;N;;;;; +1338;ETHIOPIC SYLLABLE TSA;Lo;0;L;;;;;N;;;;; +1339;ETHIOPIC SYLLABLE TSU;Lo;0;L;;;;;N;;;;; +133A;ETHIOPIC SYLLABLE TSI;Lo;0;L;;;;;N;;;;; +133B;ETHIOPIC SYLLABLE TSAA;Lo;0;L;;;;;N;;;;; +133C;ETHIOPIC SYLLABLE TSEE;Lo;0;L;;;;;N;;;;; +133D;ETHIOPIC SYLLABLE TSE;Lo;0;L;;;;;N;;;;; +133E;ETHIOPIC SYLLABLE TSO;Lo;0;L;;;;;N;;;;; +133F;ETHIOPIC SYLLABLE TSWA;Lo;0;L;;;;;N;;;;; +1340;ETHIOPIC SYLLABLE TZA;Lo;0;L;;;;;N;;;;; +1341;ETHIOPIC SYLLABLE TZU;Lo;0;L;;;;;N;;;;; +1342;ETHIOPIC SYLLABLE TZI;Lo;0;L;;;;;N;;;;; +1343;ETHIOPIC SYLLABLE TZAA;Lo;0;L;;;;;N;;;;; +1344;ETHIOPIC SYLLABLE TZEE;Lo;0;L;;;;;N;;;;; +1345;ETHIOPIC SYLLABLE TZE;Lo;0;L;;;;;N;;;;; +1346;ETHIOPIC SYLLABLE TZO;Lo;0;L;;;;;N;;;;; +1347;ETHIOPIC SYLLABLE TZOA;Lo;0;L;;;;;N;;;;; +1348;ETHIOPIC SYLLABLE FA;Lo;0;L;;;;;N;;;;; +1349;ETHIOPIC SYLLABLE FU;Lo;0;L;;;;;N;;;;; +134A;ETHIOPIC SYLLABLE FI;Lo;0;L;;;;;N;;;;; +134B;ETHIOPIC SYLLABLE FAA;Lo;0;L;;;;;N;;;;; +134C;ETHIOPIC SYLLABLE FEE;Lo;0;L;;;;;N;;;;; +134D;ETHIOPIC SYLLABLE FE;Lo;0;L;;;;;N;;;;; +134E;ETHIOPIC SYLLABLE FO;Lo;0;L;;;;;N;;;;; +134F;ETHIOPIC SYLLABLE FWA;Lo;0;L;;;;;N;;;;; +1350;ETHIOPIC SYLLABLE PA;Lo;0;L;;;;;N;;;;; +1351;ETHIOPIC SYLLABLE PU;Lo;0;L;;;;;N;;;;; +1352;ETHIOPIC SYLLABLE PI;Lo;0;L;;;;;N;;;;; +1353;ETHIOPIC SYLLABLE PAA;Lo;0;L;;;;;N;;;;; +1354;ETHIOPIC SYLLABLE PEE;Lo;0;L;;;;;N;;;;; +1355;ETHIOPIC SYLLABLE PE;Lo;0;L;;;;;N;;;;; +1356;ETHIOPIC SYLLABLE PO;Lo;0;L;;;;;N;;;;; +1357;ETHIOPIC SYLLABLE PWA;Lo;0;L;;;;;N;;;;; +1358;ETHIOPIC SYLLABLE RYA;Lo;0;L;;;;;N;;;;; +1359;ETHIOPIC SYLLABLE MYA;Lo;0;L;;;;;N;;;;; +135A;ETHIOPIC SYLLABLE FYA;Lo;0;L;;;;;N;;;;; +135D;ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK;Mn;230;NSM;;;;;N;;;;; +135E;ETHIOPIC COMBINING VOWEL LENGTH MARK;Mn;230;NSM;;;;;N;;;;; +135F;ETHIOPIC COMBINING GEMINATION MARK;Mn;230;NSM;;;;;N;;;;; +1360;ETHIOPIC SECTION MARK;Po;0;L;;;;;N;;;;; +1361;ETHIOPIC WORDSPACE;Po;0;L;;;;;N;;;;; +1362;ETHIOPIC FULL STOP;Po;0;L;;;;;N;;;;; +1363;ETHIOPIC COMMA;Po;0;L;;;;;N;;;;; +1364;ETHIOPIC SEMICOLON;Po;0;L;;;;;N;;;;; +1365;ETHIOPIC COLON;Po;0;L;;;;;N;;;;; +1366;ETHIOPIC PREFACE COLON;Po;0;L;;;;;N;;;;; +1367;ETHIOPIC QUESTION MARK;Po;0;L;;;;;N;;;;; +1368;ETHIOPIC PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;; +1369;ETHIOPIC DIGIT ONE;No;0;L;;;1;1;N;;;;; +136A;ETHIOPIC DIGIT TWO;No;0;L;;;2;2;N;;;;; +136B;ETHIOPIC DIGIT THREE;No;0;L;;;3;3;N;;;;; +136C;ETHIOPIC DIGIT FOUR;No;0;L;;;4;4;N;;;;; +136D;ETHIOPIC DIGIT FIVE;No;0;L;;;5;5;N;;;;; +136E;ETHIOPIC DIGIT SIX;No;0;L;;;6;6;N;;;;; +136F;ETHIOPIC DIGIT SEVEN;No;0;L;;;7;7;N;;;;; +1370;ETHIOPIC DIGIT EIGHT;No;0;L;;;8;8;N;;;;; +1371;ETHIOPIC DIGIT NINE;No;0;L;;;9;9;N;;;;; +1372;ETHIOPIC NUMBER TEN;No;0;L;;;;10;N;;;;; +1373;ETHIOPIC NUMBER TWENTY;No;0;L;;;;20;N;;;;; +1374;ETHIOPIC NUMBER THIRTY;No;0;L;;;;30;N;;;;; +1375;ETHIOPIC NUMBER FORTY;No;0;L;;;;40;N;;;;; +1376;ETHIOPIC NUMBER FIFTY;No;0;L;;;;50;N;;;;; +1377;ETHIOPIC NUMBER SIXTY;No;0;L;;;;60;N;;;;; +1378;ETHIOPIC NUMBER SEVENTY;No;0;L;;;;70;N;;;;; +1379;ETHIOPIC NUMBER EIGHTY;No;0;L;;;;80;N;;;;; +137A;ETHIOPIC NUMBER NINETY;No;0;L;;;;90;N;;;;; +137B;ETHIOPIC NUMBER HUNDRED;No;0;L;;;;100;N;;;;; +137C;ETHIOPIC NUMBER TEN THOUSAND;No;0;L;;;;10000;N;;;;; +1380;ETHIOPIC SYLLABLE SEBATBEIT MWA;Lo;0;L;;;;;N;;;;; +1381;ETHIOPIC SYLLABLE MWI;Lo;0;L;;;;;N;;;;; +1382;ETHIOPIC SYLLABLE MWEE;Lo;0;L;;;;;N;;;;; +1383;ETHIOPIC SYLLABLE MWE;Lo;0;L;;;;;N;;;;; +1384;ETHIOPIC SYLLABLE SEBATBEIT BWA;Lo;0;L;;;;;N;;;;; +1385;ETHIOPIC SYLLABLE BWI;Lo;0;L;;;;;N;;;;; +1386;ETHIOPIC SYLLABLE BWEE;Lo;0;L;;;;;N;;;;; +1387;ETHIOPIC SYLLABLE BWE;Lo;0;L;;;;;N;;;;; +1388;ETHIOPIC SYLLABLE SEBATBEIT FWA;Lo;0;L;;;;;N;;;;; +1389;ETHIOPIC SYLLABLE FWI;Lo;0;L;;;;;N;;;;; +138A;ETHIOPIC SYLLABLE FWEE;Lo;0;L;;;;;N;;;;; +138B;ETHIOPIC SYLLABLE FWE;Lo;0;L;;;;;N;;;;; +138C;ETHIOPIC SYLLABLE SEBATBEIT PWA;Lo;0;L;;;;;N;;;;; +138D;ETHIOPIC SYLLABLE PWI;Lo;0;L;;;;;N;;;;; +138E;ETHIOPIC SYLLABLE PWEE;Lo;0;L;;;;;N;;;;; +138F;ETHIOPIC SYLLABLE PWE;Lo;0;L;;;;;N;;;;; +1390;ETHIOPIC TONAL MARK YIZET;So;0;ON;;;;;N;;;;; +1391;ETHIOPIC TONAL MARK DERET;So;0;ON;;;;;N;;;;; +1392;ETHIOPIC TONAL MARK RIKRIK;So;0;ON;;;;;N;;;;; +1393;ETHIOPIC TONAL MARK SHORT RIKRIK;So;0;ON;;;;;N;;;;; +1394;ETHIOPIC TONAL MARK DIFAT;So;0;ON;;;;;N;;;;; +1395;ETHIOPIC TONAL MARK KENAT;So;0;ON;;;;;N;;;;; +1396;ETHIOPIC TONAL MARK CHIRET;So;0;ON;;;;;N;;;;; +1397;ETHIOPIC TONAL MARK HIDET;So;0;ON;;;;;N;;;;; +1398;ETHIOPIC TONAL MARK DERET-HIDET;So;0;ON;;;;;N;;;;; +1399;ETHIOPIC TONAL MARK KURT;So;0;ON;;;;;N;;;;; +13A0;CHEROKEE LETTER A;Lu;0;L;;;;;N;;;;AB70; +13A1;CHEROKEE LETTER E;Lu;0;L;;;;;N;;;;AB71; +13A2;CHEROKEE LETTER I;Lu;0;L;;;;;N;;;;AB72; +13A3;CHEROKEE LETTER O;Lu;0;L;;;;;N;;;;AB73; +13A4;CHEROKEE LETTER U;Lu;0;L;;;;;N;;;;AB74; +13A5;CHEROKEE LETTER V;Lu;0;L;;;;;N;;;;AB75; +13A6;CHEROKEE LETTER GA;Lu;0;L;;;;;N;;;;AB76; +13A7;CHEROKEE LETTER KA;Lu;0;L;;;;;N;;;;AB77; +13A8;CHEROKEE LETTER GE;Lu;0;L;;;;;N;;;;AB78; +13A9;CHEROKEE LETTER GI;Lu;0;L;;;;;N;;;;AB79; +13AA;CHEROKEE LETTER GO;Lu;0;L;;;;;N;;;;AB7A; +13AB;CHEROKEE LETTER GU;Lu;0;L;;;;;N;;;;AB7B; +13AC;CHEROKEE LETTER GV;Lu;0;L;;;;;N;;;;AB7C; +13AD;CHEROKEE LETTER HA;Lu;0;L;;;;;N;;;;AB7D; +13AE;CHEROKEE LETTER HE;Lu;0;L;;;;;N;;;;AB7E; +13AF;CHEROKEE LETTER HI;Lu;0;L;;;;;N;;;;AB7F; +13B0;CHEROKEE LETTER HO;Lu;0;L;;;;;N;;;;AB80; +13B1;CHEROKEE LETTER HU;Lu;0;L;;;;;N;;;;AB81; +13B2;CHEROKEE LETTER HV;Lu;0;L;;;;;N;;;;AB82; +13B3;CHEROKEE LETTER LA;Lu;0;L;;;;;N;;;;AB83; +13B4;CHEROKEE LETTER LE;Lu;0;L;;;;;N;;;;AB84; +13B5;CHEROKEE LETTER LI;Lu;0;L;;;;;N;;;;AB85; +13B6;CHEROKEE LETTER LO;Lu;0;L;;;;;N;;;;AB86; +13B7;CHEROKEE LETTER LU;Lu;0;L;;;;;N;;;;AB87; +13B8;CHEROKEE LETTER LV;Lu;0;L;;;;;N;;;;AB88; +13B9;CHEROKEE LETTER MA;Lu;0;L;;;;;N;;;;AB89; +13BA;CHEROKEE LETTER ME;Lu;0;L;;;;;N;;;;AB8A; +13BB;CHEROKEE LETTER MI;Lu;0;L;;;;;N;;;;AB8B; +13BC;CHEROKEE LETTER MO;Lu;0;L;;;;;N;;;;AB8C; +13BD;CHEROKEE LETTER MU;Lu;0;L;;;;;N;;;;AB8D; +13BE;CHEROKEE LETTER NA;Lu;0;L;;;;;N;;;;AB8E; +13BF;CHEROKEE LETTER HNA;Lu;0;L;;;;;N;;;;AB8F; +13C0;CHEROKEE LETTER NAH;Lu;0;L;;;;;N;;;;AB90; +13C1;CHEROKEE LETTER NE;Lu;0;L;;;;;N;;;;AB91; +13C2;CHEROKEE LETTER NI;Lu;0;L;;;;;N;;;;AB92; +13C3;CHEROKEE LETTER NO;Lu;0;L;;;;;N;;;;AB93; +13C4;CHEROKEE LETTER NU;Lu;0;L;;;;;N;;;;AB94; +13C5;CHEROKEE LETTER NV;Lu;0;L;;;;;N;;;;AB95; +13C6;CHEROKEE LETTER QUA;Lu;0;L;;;;;N;;;;AB96; +13C7;CHEROKEE LETTER QUE;Lu;0;L;;;;;N;;;;AB97; +13C8;CHEROKEE LETTER QUI;Lu;0;L;;;;;N;;;;AB98; +13C9;CHEROKEE LETTER QUO;Lu;0;L;;;;;N;;;;AB99; +13CA;CHEROKEE LETTER QUU;Lu;0;L;;;;;N;;;;AB9A; +13CB;CHEROKEE LETTER QUV;Lu;0;L;;;;;N;;;;AB9B; +13CC;CHEROKEE LETTER SA;Lu;0;L;;;;;N;;;;AB9C; +13CD;CHEROKEE LETTER S;Lu;0;L;;;;;N;;;;AB9D; +13CE;CHEROKEE LETTER SE;Lu;0;L;;;;;N;;;;AB9E; +13CF;CHEROKEE LETTER SI;Lu;0;L;;;;;N;;;;AB9F; +13D0;CHEROKEE LETTER SO;Lu;0;L;;;;;N;;;;ABA0; +13D1;CHEROKEE LETTER SU;Lu;0;L;;;;;N;;;;ABA1; +13D2;CHEROKEE LETTER SV;Lu;0;L;;;;;N;;;;ABA2; +13D3;CHEROKEE LETTER DA;Lu;0;L;;;;;N;;;;ABA3; +13D4;CHEROKEE LETTER TA;Lu;0;L;;;;;N;;;;ABA4; +13D5;CHEROKEE LETTER DE;Lu;0;L;;;;;N;;;;ABA5; +13D6;CHEROKEE LETTER TE;Lu;0;L;;;;;N;;;;ABA6; +13D7;CHEROKEE LETTER DI;Lu;0;L;;;;;N;;;;ABA7; +13D8;CHEROKEE LETTER TI;Lu;0;L;;;;;N;;;;ABA8; +13D9;CHEROKEE LETTER DO;Lu;0;L;;;;;N;;;;ABA9; +13DA;CHEROKEE LETTER DU;Lu;0;L;;;;;N;;;;ABAA; +13DB;CHEROKEE LETTER DV;Lu;0;L;;;;;N;;;;ABAB; +13DC;CHEROKEE LETTER DLA;Lu;0;L;;;;;N;;;;ABAC; +13DD;CHEROKEE LETTER TLA;Lu;0;L;;;;;N;;;;ABAD; +13DE;CHEROKEE LETTER TLE;Lu;0;L;;;;;N;;;;ABAE; +13DF;CHEROKEE LETTER TLI;Lu;0;L;;;;;N;;;;ABAF; +13E0;CHEROKEE LETTER TLO;Lu;0;L;;;;;N;;;;ABB0; +13E1;CHEROKEE LETTER TLU;Lu;0;L;;;;;N;;;;ABB1; +13E2;CHEROKEE LETTER TLV;Lu;0;L;;;;;N;;;;ABB2; +13E3;CHEROKEE LETTER TSA;Lu;0;L;;;;;N;;;;ABB3; +13E4;CHEROKEE LETTER TSE;Lu;0;L;;;;;N;;;;ABB4; +13E5;CHEROKEE LETTER TSI;Lu;0;L;;;;;N;;;;ABB5; +13E6;CHEROKEE LETTER TSO;Lu;0;L;;;;;N;;;;ABB6; +13E7;CHEROKEE LETTER TSU;Lu;0;L;;;;;N;;;;ABB7; +13E8;CHEROKEE LETTER TSV;Lu;0;L;;;;;N;;;;ABB8; +13E9;CHEROKEE LETTER WA;Lu;0;L;;;;;N;;;;ABB9; +13EA;CHEROKEE LETTER WE;Lu;0;L;;;;;N;;;;ABBA; +13EB;CHEROKEE LETTER WI;Lu;0;L;;;;;N;;;;ABBB; +13EC;CHEROKEE LETTER WO;Lu;0;L;;;;;N;;;;ABBC; +13ED;CHEROKEE LETTER WU;Lu;0;L;;;;;N;;;;ABBD; +13EE;CHEROKEE LETTER WV;Lu;0;L;;;;;N;;;;ABBE; +13EF;CHEROKEE LETTER YA;Lu;0;L;;;;;N;;;;ABBF; +13F0;CHEROKEE LETTER YE;Lu;0;L;;;;;N;;;;13F8; +13F1;CHEROKEE LETTER YI;Lu;0;L;;;;;N;;;;13F9; +13F2;CHEROKEE LETTER YO;Lu;0;L;;;;;N;;;;13FA; +13F3;CHEROKEE LETTER YU;Lu;0;L;;;;;N;;;;13FB; +13F4;CHEROKEE LETTER YV;Lu;0;L;;;;;N;;;;13FC; +13F5;CHEROKEE LETTER MV;Lu;0;L;;;;;N;;;;13FD; +13F8;CHEROKEE SMALL LETTER YE;Ll;0;L;;;;;N;;;13F0;;13F0 +13F9;CHEROKEE SMALL LETTER YI;Ll;0;L;;;;;N;;;13F1;;13F1 +13FA;CHEROKEE SMALL LETTER YO;Ll;0;L;;;;;N;;;13F2;;13F2 +13FB;CHEROKEE SMALL LETTER YU;Ll;0;L;;;;;N;;;13F3;;13F3 +13FC;CHEROKEE SMALL LETTER YV;Ll;0;L;;;;;N;;;13F4;;13F4 +13FD;CHEROKEE SMALL LETTER MV;Ll;0;L;;;;;N;;;13F5;;13F5 +1400;CANADIAN SYLLABICS HYPHEN;Pd;0;ON;;;;;N;;;;; +1401;CANADIAN SYLLABICS E;Lo;0;L;;;;;N;;;;; +1402;CANADIAN SYLLABICS AAI;Lo;0;L;;;;;N;;;;; +1403;CANADIAN SYLLABICS I;Lo;0;L;;;;;N;;;;; +1404;CANADIAN SYLLABICS II;Lo;0;L;;;;;N;;;;; +1405;CANADIAN SYLLABICS O;Lo;0;L;;;;;N;;;;; +1406;CANADIAN SYLLABICS OO;Lo;0;L;;;;;N;;;;; +1407;CANADIAN SYLLABICS Y-CREE OO;Lo;0;L;;;;;N;;;;; +1408;CANADIAN SYLLABICS CARRIER EE;Lo;0;L;;;;;N;;;;; +1409;CANADIAN SYLLABICS CARRIER I;Lo;0;L;;;;;N;;;;; +140A;CANADIAN SYLLABICS A;Lo;0;L;;;;;N;;;;; +140B;CANADIAN SYLLABICS AA;Lo;0;L;;;;;N;;;;; +140C;CANADIAN SYLLABICS WE;Lo;0;L;;;;;N;;;;; +140D;CANADIAN SYLLABICS WEST-CREE WE;Lo;0;L;;;;;N;;;;; +140E;CANADIAN SYLLABICS WI;Lo;0;L;;;;;N;;;;; +140F;CANADIAN SYLLABICS WEST-CREE WI;Lo;0;L;;;;;N;;;;; +1410;CANADIAN SYLLABICS WII;Lo;0;L;;;;;N;;;;; +1411;CANADIAN SYLLABICS WEST-CREE WII;Lo;0;L;;;;;N;;;;; +1412;CANADIAN SYLLABICS WO;Lo;0;L;;;;;N;;;;; +1413;CANADIAN SYLLABICS WEST-CREE WO;Lo;0;L;;;;;N;;;;; +1414;CANADIAN SYLLABICS WOO;Lo;0;L;;;;;N;;;;; +1415;CANADIAN SYLLABICS WEST-CREE WOO;Lo;0;L;;;;;N;;;;; +1416;CANADIAN SYLLABICS NASKAPI WOO;Lo;0;L;;;;;N;;;;; +1417;CANADIAN SYLLABICS WA;Lo;0;L;;;;;N;;;;; +1418;CANADIAN SYLLABICS WEST-CREE WA;Lo;0;L;;;;;N;;;;; +1419;CANADIAN SYLLABICS WAA;Lo;0;L;;;;;N;;;;; +141A;CANADIAN SYLLABICS WEST-CREE WAA;Lo;0;L;;;;;N;;;;; +141B;CANADIAN SYLLABICS NASKAPI WAA;Lo;0;L;;;;;N;;;;; +141C;CANADIAN SYLLABICS AI;Lo;0;L;;;;;N;;;;; +141D;CANADIAN SYLLABICS Y-CREE W;Lo;0;L;;;;;N;;;;; +141E;CANADIAN SYLLABICS GLOTTAL STOP;Lo;0;L;;;;;N;;;;; +141F;CANADIAN SYLLABICS FINAL ACUTE;Lo;0;L;;;;;N;;;;; +1420;CANADIAN SYLLABICS FINAL GRAVE;Lo;0;L;;;;;N;;;;; +1421;CANADIAN SYLLABICS FINAL BOTTOM HALF RING;Lo;0;L;;;;;N;;;;; +1422;CANADIAN SYLLABICS FINAL TOP HALF RING;Lo;0;L;;;;;N;;;;; +1423;CANADIAN SYLLABICS FINAL RIGHT HALF RING;Lo;0;L;;;;;N;;;;; +1424;CANADIAN SYLLABICS FINAL RING;Lo;0;L;;;;;N;;;;; +1425;CANADIAN SYLLABICS FINAL DOUBLE ACUTE;Lo;0;L;;;;;N;;;;; +1426;CANADIAN SYLLABICS FINAL DOUBLE SHORT VERTICAL STROKES;Lo;0;L;;;;;N;;;;; +1427;CANADIAN SYLLABICS FINAL MIDDLE DOT;Lo;0;L;;;;;N;;;;; +1428;CANADIAN SYLLABICS FINAL SHORT HORIZONTAL STROKE;Lo;0;L;;;;;N;;;;; +1429;CANADIAN SYLLABICS FINAL PLUS;Lo;0;L;;;;;N;;;;; +142A;CANADIAN SYLLABICS FINAL DOWN TACK;Lo;0;L;;;;;N;;;;; +142B;CANADIAN SYLLABICS EN;Lo;0;L;;;;;N;;;;; +142C;CANADIAN SYLLABICS IN;Lo;0;L;;;;;N;;;;; +142D;CANADIAN SYLLABICS ON;Lo;0;L;;;;;N;;;;; +142E;CANADIAN SYLLABICS AN;Lo;0;L;;;;;N;;;;; +142F;CANADIAN SYLLABICS PE;Lo;0;L;;;;;N;;;;; +1430;CANADIAN SYLLABICS PAAI;Lo;0;L;;;;;N;;;;; +1431;CANADIAN SYLLABICS PI;Lo;0;L;;;;;N;;;;; +1432;CANADIAN SYLLABICS PII;Lo;0;L;;;;;N;;;;; +1433;CANADIAN SYLLABICS PO;Lo;0;L;;;;;N;;;;; +1434;CANADIAN SYLLABICS POO;Lo;0;L;;;;;N;;;;; +1435;CANADIAN SYLLABICS Y-CREE POO;Lo;0;L;;;;;N;;;;; +1436;CANADIAN SYLLABICS CARRIER HEE;Lo;0;L;;;;;N;;;;; +1437;CANADIAN SYLLABICS CARRIER HI;Lo;0;L;;;;;N;;;;; +1438;CANADIAN SYLLABICS PA;Lo;0;L;;;;;N;;;;; +1439;CANADIAN SYLLABICS PAA;Lo;0;L;;;;;N;;;;; +143A;CANADIAN SYLLABICS PWE;Lo;0;L;;;;;N;;;;; +143B;CANADIAN SYLLABICS WEST-CREE PWE;Lo;0;L;;;;;N;;;;; +143C;CANADIAN SYLLABICS PWI;Lo;0;L;;;;;N;;;;; +143D;CANADIAN SYLLABICS WEST-CREE PWI;Lo;0;L;;;;;N;;;;; +143E;CANADIAN SYLLABICS PWII;Lo;0;L;;;;;N;;;;; +143F;CANADIAN SYLLABICS WEST-CREE PWII;Lo;0;L;;;;;N;;;;; +1440;CANADIAN SYLLABICS PWO;Lo;0;L;;;;;N;;;;; +1441;CANADIAN SYLLABICS WEST-CREE PWO;Lo;0;L;;;;;N;;;;; +1442;CANADIAN SYLLABICS PWOO;Lo;0;L;;;;;N;;;;; +1443;CANADIAN SYLLABICS WEST-CREE PWOO;Lo;0;L;;;;;N;;;;; +1444;CANADIAN SYLLABICS PWA;Lo;0;L;;;;;N;;;;; +1445;CANADIAN SYLLABICS WEST-CREE PWA;Lo;0;L;;;;;N;;;;; +1446;CANADIAN SYLLABICS PWAA;Lo;0;L;;;;;N;;;;; +1447;CANADIAN SYLLABICS WEST-CREE PWAA;Lo;0;L;;;;;N;;;;; +1448;CANADIAN SYLLABICS Y-CREE PWAA;Lo;0;L;;;;;N;;;;; +1449;CANADIAN SYLLABICS P;Lo;0;L;;;;;N;;;;; +144A;CANADIAN SYLLABICS WEST-CREE P;Lo;0;L;;;;;N;;;;; +144B;CANADIAN SYLLABICS CARRIER H;Lo;0;L;;;;;N;;;;; +144C;CANADIAN SYLLABICS TE;Lo;0;L;;;;;N;;;;; +144D;CANADIAN SYLLABICS TAAI;Lo;0;L;;;;;N;;;;; +144E;CANADIAN SYLLABICS TI;Lo;0;L;;;;;N;;;;; +144F;CANADIAN SYLLABICS TII;Lo;0;L;;;;;N;;;;; +1450;CANADIAN SYLLABICS TO;Lo;0;L;;;;;N;;;;; +1451;CANADIAN SYLLABICS TOO;Lo;0;L;;;;;N;;;;; +1452;CANADIAN SYLLABICS Y-CREE TOO;Lo;0;L;;;;;N;;;;; +1453;CANADIAN SYLLABICS CARRIER DEE;Lo;0;L;;;;;N;;;;; +1454;CANADIAN SYLLABICS CARRIER DI;Lo;0;L;;;;;N;;;;; +1455;CANADIAN SYLLABICS TA;Lo;0;L;;;;;N;;;;; +1456;CANADIAN SYLLABICS TAA;Lo;0;L;;;;;N;;;;; +1457;CANADIAN SYLLABICS TWE;Lo;0;L;;;;;N;;;;; +1458;CANADIAN SYLLABICS WEST-CREE TWE;Lo;0;L;;;;;N;;;;; +1459;CANADIAN SYLLABICS TWI;Lo;0;L;;;;;N;;;;; +145A;CANADIAN SYLLABICS WEST-CREE TWI;Lo;0;L;;;;;N;;;;; +145B;CANADIAN SYLLABICS TWII;Lo;0;L;;;;;N;;;;; +145C;CANADIAN SYLLABICS WEST-CREE TWII;Lo;0;L;;;;;N;;;;; +145D;CANADIAN SYLLABICS TWO;Lo;0;L;;;;;N;;;;; +145E;CANADIAN SYLLABICS WEST-CREE TWO;Lo;0;L;;;;;N;;;;; +145F;CANADIAN SYLLABICS TWOO;Lo;0;L;;;;;N;;;;; +1460;CANADIAN SYLLABICS WEST-CREE TWOO;Lo;0;L;;;;;N;;;;; +1461;CANADIAN SYLLABICS TWA;Lo;0;L;;;;;N;;;;; +1462;CANADIAN SYLLABICS WEST-CREE TWA;Lo;0;L;;;;;N;;;;; +1463;CANADIAN SYLLABICS TWAA;Lo;0;L;;;;;N;;;;; +1464;CANADIAN SYLLABICS WEST-CREE TWAA;Lo;0;L;;;;;N;;;;; +1465;CANADIAN SYLLABICS NASKAPI TWAA;Lo;0;L;;;;;N;;;;; +1466;CANADIAN SYLLABICS T;Lo;0;L;;;;;N;;;;; +1467;CANADIAN SYLLABICS TTE;Lo;0;L;;;;;N;;;;; +1468;CANADIAN SYLLABICS TTI;Lo;0;L;;;;;N;;;;; +1469;CANADIAN SYLLABICS TTO;Lo;0;L;;;;;N;;;;; +146A;CANADIAN SYLLABICS TTA;Lo;0;L;;;;;N;;;;; +146B;CANADIAN SYLLABICS KE;Lo;0;L;;;;;N;;;;; +146C;CANADIAN SYLLABICS KAAI;Lo;0;L;;;;;N;;;;; +146D;CANADIAN SYLLABICS KI;Lo;0;L;;;;;N;;;;; +146E;CANADIAN SYLLABICS KII;Lo;0;L;;;;;N;;;;; +146F;CANADIAN SYLLABICS KO;Lo;0;L;;;;;N;;;;; +1470;CANADIAN SYLLABICS KOO;Lo;0;L;;;;;N;;;;; +1471;CANADIAN SYLLABICS Y-CREE KOO;Lo;0;L;;;;;N;;;;; +1472;CANADIAN SYLLABICS KA;Lo;0;L;;;;;N;;;;; +1473;CANADIAN SYLLABICS KAA;Lo;0;L;;;;;N;;;;; +1474;CANADIAN SYLLABICS KWE;Lo;0;L;;;;;N;;;;; +1475;CANADIAN SYLLABICS WEST-CREE KWE;Lo;0;L;;;;;N;;;;; +1476;CANADIAN SYLLABICS KWI;Lo;0;L;;;;;N;;;;; +1477;CANADIAN SYLLABICS WEST-CREE KWI;Lo;0;L;;;;;N;;;;; +1478;CANADIAN SYLLABICS KWII;Lo;0;L;;;;;N;;;;; +1479;CANADIAN SYLLABICS WEST-CREE KWII;Lo;0;L;;;;;N;;;;; +147A;CANADIAN SYLLABICS KWO;Lo;0;L;;;;;N;;;;; +147B;CANADIAN SYLLABICS WEST-CREE KWO;Lo;0;L;;;;;N;;;;; +147C;CANADIAN SYLLABICS KWOO;Lo;0;L;;;;;N;;;;; +147D;CANADIAN SYLLABICS WEST-CREE KWOO;Lo;0;L;;;;;N;;;;; +147E;CANADIAN SYLLABICS KWA;Lo;0;L;;;;;N;;;;; +147F;CANADIAN SYLLABICS WEST-CREE KWA;Lo;0;L;;;;;N;;;;; +1480;CANADIAN SYLLABICS KWAA;Lo;0;L;;;;;N;;;;; +1481;CANADIAN SYLLABICS WEST-CREE KWAA;Lo;0;L;;;;;N;;;;; +1482;CANADIAN SYLLABICS NASKAPI KWAA;Lo;0;L;;;;;N;;;;; +1483;CANADIAN SYLLABICS K;Lo;0;L;;;;;N;;;;; +1484;CANADIAN SYLLABICS KW;Lo;0;L;;;;;N;;;;; +1485;CANADIAN SYLLABICS SOUTH-SLAVEY KEH;Lo;0;L;;;;;N;;;;; +1486;CANADIAN SYLLABICS SOUTH-SLAVEY KIH;Lo;0;L;;;;;N;;;;; +1487;CANADIAN SYLLABICS SOUTH-SLAVEY KOH;Lo;0;L;;;;;N;;;;; +1488;CANADIAN SYLLABICS SOUTH-SLAVEY KAH;Lo;0;L;;;;;N;;;;; +1489;CANADIAN SYLLABICS CE;Lo;0;L;;;;;N;;;;; +148A;CANADIAN SYLLABICS CAAI;Lo;0;L;;;;;N;;;;; +148B;CANADIAN SYLLABICS CI;Lo;0;L;;;;;N;;;;; +148C;CANADIAN SYLLABICS CII;Lo;0;L;;;;;N;;;;; +148D;CANADIAN SYLLABICS CO;Lo;0;L;;;;;N;;;;; +148E;CANADIAN SYLLABICS COO;Lo;0;L;;;;;N;;;;; +148F;CANADIAN SYLLABICS Y-CREE COO;Lo;0;L;;;;;N;;;;; +1490;CANADIAN SYLLABICS CA;Lo;0;L;;;;;N;;;;; +1491;CANADIAN SYLLABICS CAA;Lo;0;L;;;;;N;;;;; +1492;CANADIAN SYLLABICS CWE;Lo;0;L;;;;;N;;;;; +1493;CANADIAN SYLLABICS WEST-CREE CWE;Lo;0;L;;;;;N;;;;; +1494;CANADIAN SYLLABICS CWI;Lo;0;L;;;;;N;;;;; +1495;CANADIAN SYLLABICS WEST-CREE CWI;Lo;0;L;;;;;N;;;;; +1496;CANADIAN SYLLABICS CWII;Lo;0;L;;;;;N;;;;; +1497;CANADIAN SYLLABICS WEST-CREE CWII;Lo;0;L;;;;;N;;;;; +1498;CANADIAN SYLLABICS CWO;Lo;0;L;;;;;N;;;;; +1499;CANADIAN SYLLABICS WEST-CREE CWO;Lo;0;L;;;;;N;;;;; +149A;CANADIAN SYLLABICS CWOO;Lo;0;L;;;;;N;;;;; +149B;CANADIAN SYLLABICS WEST-CREE CWOO;Lo;0;L;;;;;N;;;;; +149C;CANADIAN SYLLABICS CWA;Lo;0;L;;;;;N;;;;; +149D;CANADIAN SYLLABICS WEST-CREE CWA;Lo;0;L;;;;;N;;;;; +149E;CANADIAN SYLLABICS CWAA;Lo;0;L;;;;;N;;;;; +149F;CANADIAN SYLLABICS WEST-CREE CWAA;Lo;0;L;;;;;N;;;;; +14A0;CANADIAN SYLLABICS NASKAPI CWAA;Lo;0;L;;;;;N;;;;; +14A1;CANADIAN SYLLABICS C;Lo;0;L;;;;;N;;;;; +14A2;CANADIAN SYLLABICS SAYISI TH;Lo;0;L;;;;;N;;;;; +14A3;CANADIAN SYLLABICS ME;Lo;0;L;;;;;N;;;;; +14A4;CANADIAN SYLLABICS MAAI;Lo;0;L;;;;;N;;;;; +14A5;CANADIAN SYLLABICS MI;Lo;0;L;;;;;N;;;;; +14A6;CANADIAN SYLLABICS MII;Lo;0;L;;;;;N;;;;; +14A7;CANADIAN SYLLABICS MO;Lo;0;L;;;;;N;;;;; +14A8;CANADIAN SYLLABICS MOO;Lo;0;L;;;;;N;;;;; +14A9;CANADIAN SYLLABICS Y-CREE MOO;Lo;0;L;;;;;N;;;;; +14AA;CANADIAN SYLLABICS MA;Lo;0;L;;;;;N;;;;; +14AB;CANADIAN SYLLABICS MAA;Lo;0;L;;;;;N;;;;; +14AC;CANADIAN SYLLABICS MWE;Lo;0;L;;;;;N;;;;; +14AD;CANADIAN SYLLABICS WEST-CREE MWE;Lo;0;L;;;;;N;;;;; +14AE;CANADIAN SYLLABICS MWI;Lo;0;L;;;;;N;;;;; +14AF;CANADIAN SYLLABICS WEST-CREE MWI;Lo;0;L;;;;;N;;;;; +14B0;CANADIAN SYLLABICS MWII;Lo;0;L;;;;;N;;;;; +14B1;CANADIAN SYLLABICS WEST-CREE MWII;Lo;0;L;;;;;N;;;;; +14B2;CANADIAN SYLLABICS MWO;Lo;0;L;;;;;N;;;;; +14B3;CANADIAN SYLLABICS WEST-CREE MWO;Lo;0;L;;;;;N;;;;; +14B4;CANADIAN SYLLABICS MWOO;Lo;0;L;;;;;N;;;;; +14B5;CANADIAN SYLLABICS WEST-CREE MWOO;Lo;0;L;;;;;N;;;;; +14B6;CANADIAN SYLLABICS MWA;Lo;0;L;;;;;N;;;;; +14B7;CANADIAN SYLLABICS WEST-CREE MWA;Lo;0;L;;;;;N;;;;; +14B8;CANADIAN SYLLABICS MWAA;Lo;0;L;;;;;N;;;;; +14B9;CANADIAN SYLLABICS WEST-CREE MWAA;Lo;0;L;;;;;N;;;;; +14BA;CANADIAN SYLLABICS NASKAPI MWAA;Lo;0;L;;;;;N;;;;; +14BB;CANADIAN SYLLABICS M;Lo;0;L;;;;;N;;;;; +14BC;CANADIAN SYLLABICS WEST-CREE M;Lo;0;L;;;;;N;;;;; +14BD;CANADIAN SYLLABICS MH;Lo;0;L;;;;;N;;;;; +14BE;CANADIAN SYLLABICS ATHAPASCAN M;Lo;0;L;;;;;N;;;;; +14BF;CANADIAN SYLLABICS SAYISI M;Lo;0;L;;;;;N;;;;; +14C0;CANADIAN SYLLABICS NE;Lo;0;L;;;;;N;;;;; +14C1;CANADIAN SYLLABICS NAAI;Lo;0;L;;;;;N;;;;; +14C2;CANADIAN SYLLABICS NI;Lo;0;L;;;;;N;;;;; +14C3;CANADIAN SYLLABICS NII;Lo;0;L;;;;;N;;;;; +14C4;CANADIAN SYLLABICS NO;Lo;0;L;;;;;N;;;;; +14C5;CANADIAN SYLLABICS NOO;Lo;0;L;;;;;N;;;;; +14C6;CANADIAN SYLLABICS Y-CREE NOO;Lo;0;L;;;;;N;;;;; +14C7;CANADIAN SYLLABICS NA;Lo;0;L;;;;;N;;;;; +14C8;CANADIAN SYLLABICS NAA;Lo;0;L;;;;;N;;;;; +14C9;CANADIAN SYLLABICS NWE;Lo;0;L;;;;;N;;;;; +14CA;CANADIAN SYLLABICS WEST-CREE NWE;Lo;0;L;;;;;N;;;;; +14CB;CANADIAN SYLLABICS NWA;Lo;0;L;;;;;N;;;;; +14CC;CANADIAN SYLLABICS WEST-CREE NWA;Lo;0;L;;;;;N;;;;; +14CD;CANADIAN SYLLABICS NWAA;Lo;0;L;;;;;N;;;;; +14CE;CANADIAN SYLLABICS WEST-CREE NWAA;Lo;0;L;;;;;N;;;;; +14CF;CANADIAN SYLLABICS NASKAPI NWAA;Lo;0;L;;;;;N;;;;; +14D0;CANADIAN SYLLABICS N;Lo;0;L;;;;;N;;;;; +14D1;CANADIAN SYLLABICS CARRIER NG;Lo;0;L;;;;;N;;;;; +14D2;CANADIAN SYLLABICS NH;Lo;0;L;;;;;N;;;;; +14D3;CANADIAN SYLLABICS LE;Lo;0;L;;;;;N;;;;; +14D4;CANADIAN SYLLABICS LAAI;Lo;0;L;;;;;N;;;;; +14D5;CANADIAN SYLLABICS LI;Lo;0;L;;;;;N;;;;; +14D6;CANADIAN SYLLABICS LII;Lo;0;L;;;;;N;;;;; +14D7;CANADIAN SYLLABICS LO;Lo;0;L;;;;;N;;;;; +14D8;CANADIAN SYLLABICS LOO;Lo;0;L;;;;;N;;;;; +14D9;CANADIAN SYLLABICS Y-CREE LOO;Lo;0;L;;;;;N;;;;; +14DA;CANADIAN SYLLABICS LA;Lo;0;L;;;;;N;;;;; +14DB;CANADIAN SYLLABICS LAA;Lo;0;L;;;;;N;;;;; +14DC;CANADIAN SYLLABICS LWE;Lo;0;L;;;;;N;;;;; +14DD;CANADIAN SYLLABICS WEST-CREE LWE;Lo;0;L;;;;;N;;;;; +14DE;CANADIAN SYLLABICS LWI;Lo;0;L;;;;;N;;;;; +14DF;CANADIAN SYLLABICS WEST-CREE LWI;Lo;0;L;;;;;N;;;;; +14E0;CANADIAN SYLLABICS LWII;Lo;0;L;;;;;N;;;;; +14E1;CANADIAN SYLLABICS WEST-CREE LWII;Lo;0;L;;;;;N;;;;; +14E2;CANADIAN SYLLABICS LWO;Lo;0;L;;;;;N;;;;; +14E3;CANADIAN SYLLABICS WEST-CREE LWO;Lo;0;L;;;;;N;;;;; +14E4;CANADIAN SYLLABICS LWOO;Lo;0;L;;;;;N;;;;; +14E5;CANADIAN SYLLABICS WEST-CREE LWOO;Lo;0;L;;;;;N;;;;; +14E6;CANADIAN SYLLABICS LWA;Lo;0;L;;;;;N;;;;; +14E7;CANADIAN SYLLABICS WEST-CREE LWA;Lo;0;L;;;;;N;;;;; +14E8;CANADIAN SYLLABICS LWAA;Lo;0;L;;;;;N;;;;; +14E9;CANADIAN SYLLABICS WEST-CREE LWAA;Lo;0;L;;;;;N;;;;; +14EA;CANADIAN SYLLABICS L;Lo;0;L;;;;;N;;;;; +14EB;CANADIAN SYLLABICS WEST-CREE L;Lo;0;L;;;;;N;;;;; +14EC;CANADIAN SYLLABICS MEDIAL L;Lo;0;L;;;;;N;;;;; +14ED;CANADIAN SYLLABICS SE;Lo;0;L;;;;;N;;;;; +14EE;CANADIAN SYLLABICS SAAI;Lo;0;L;;;;;N;;;;; +14EF;CANADIAN SYLLABICS SI;Lo;0;L;;;;;N;;;;; +14F0;CANADIAN SYLLABICS SII;Lo;0;L;;;;;N;;;;; +14F1;CANADIAN SYLLABICS SO;Lo;0;L;;;;;N;;;;; +14F2;CANADIAN SYLLABICS SOO;Lo;0;L;;;;;N;;;;; +14F3;CANADIAN SYLLABICS Y-CREE SOO;Lo;0;L;;;;;N;;;;; +14F4;CANADIAN SYLLABICS SA;Lo;0;L;;;;;N;;;;; +14F5;CANADIAN SYLLABICS SAA;Lo;0;L;;;;;N;;;;; +14F6;CANADIAN SYLLABICS SWE;Lo;0;L;;;;;N;;;;; +14F7;CANADIAN SYLLABICS WEST-CREE SWE;Lo;0;L;;;;;N;;;;; +14F8;CANADIAN SYLLABICS SWI;Lo;0;L;;;;;N;;;;; +14F9;CANADIAN SYLLABICS WEST-CREE SWI;Lo;0;L;;;;;N;;;;; +14FA;CANADIAN SYLLABICS SWII;Lo;0;L;;;;;N;;;;; +14FB;CANADIAN SYLLABICS WEST-CREE SWII;Lo;0;L;;;;;N;;;;; +14FC;CANADIAN SYLLABICS SWO;Lo;0;L;;;;;N;;;;; +14FD;CANADIAN SYLLABICS WEST-CREE SWO;Lo;0;L;;;;;N;;;;; +14FE;CANADIAN SYLLABICS SWOO;Lo;0;L;;;;;N;;;;; +14FF;CANADIAN SYLLABICS WEST-CREE SWOO;Lo;0;L;;;;;N;;;;; +1500;CANADIAN SYLLABICS SWA;Lo;0;L;;;;;N;;;;; +1501;CANADIAN SYLLABICS WEST-CREE SWA;Lo;0;L;;;;;N;;;;; +1502;CANADIAN SYLLABICS SWAA;Lo;0;L;;;;;N;;;;; +1503;CANADIAN SYLLABICS WEST-CREE SWAA;Lo;0;L;;;;;N;;;;; +1504;CANADIAN SYLLABICS NASKAPI SWAA;Lo;0;L;;;;;N;;;;; +1505;CANADIAN SYLLABICS S;Lo;0;L;;;;;N;;;;; +1506;CANADIAN SYLLABICS ATHAPASCAN S;Lo;0;L;;;;;N;;;;; +1507;CANADIAN SYLLABICS SW;Lo;0;L;;;;;N;;;;; +1508;CANADIAN SYLLABICS BLACKFOOT S;Lo;0;L;;;;;N;;;;; +1509;CANADIAN SYLLABICS MOOSE-CREE SK;Lo;0;L;;;;;N;;;;; +150A;CANADIAN SYLLABICS NASKAPI SKW;Lo;0;L;;;;;N;;;;; +150B;CANADIAN SYLLABICS NASKAPI S-W;Lo;0;L;;;;;N;;;;; +150C;CANADIAN SYLLABICS NASKAPI SPWA;Lo;0;L;;;;;N;;;;; +150D;CANADIAN SYLLABICS NASKAPI STWA;Lo;0;L;;;;;N;;;;; +150E;CANADIAN SYLLABICS NASKAPI SKWA;Lo;0;L;;;;;N;;;;; +150F;CANADIAN SYLLABICS NASKAPI SCWA;Lo;0;L;;;;;N;;;;; +1510;CANADIAN SYLLABICS SHE;Lo;0;L;;;;;N;;;;; +1511;CANADIAN SYLLABICS SHI;Lo;0;L;;;;;N;;;;; +1512;CANADIAN SYLLABICS SHII;Lo;0;L;;;;;N;;;;; +1513;CANADIAN SYLLABICS SHO;Lo;0;L;;;;;N;;;;; +1514;CANADIAN SYLLABICS SHOO;Lo;0;L;;;;;N;;;;; +1515;CANADIAN SYLLABICS SHA;Lo;0;L;;;;;N;;;;; +1516;CANADIAN SYLLABICS SHAA;Lo;0;L;;;;;N;;;;; +1517;CANADIAN SYLLABICS SHWE;Lo;0;L;;;;;N;;;;; +1518;CANADIAN SYLLABICS WEST-CREE SHWE;Lo;0;L;;;;;N;;;;; +1519;CANADIAN SYLLABICS SHWI;Lo;0;L;;;;;N;;;;; +151A;CANADIAN SYLLABICS WEST-CREE SHWI;Lo;0;L;;;;;N;;;;; +151B;CANADIAN SYLLABICS SHWII;Lo;0;L;;;;;N;;;;; +151C;CANADIAN SYLLABICS WEST-CREE SHWII;Lo;0;L;;;;;N;;;;; +151D;CANADIAN SYLLABICS SHWO;Lo;0;L;;;;;N;;;;; +151E;CANADIAN SYLLABICS WEST-CREE SHWO;Lo;0;L;;;;;N;;;;; +151F;CANADIAN SYLLABICS SHWOO;Lo;0;L;;;;;N;;;;; +1520;CANADIAN SYLLABICS WEST-CREE SHWOO;Lo;0;L;;;;;N;;;;; +1521;CANADIAN SYLLABICS SHWA;Lo;0;L;;;;;N;;;;; +1522;CANADIAN SYLLABICS WEST-CREE SHWA;Lo;0;L;;;;;N;;;;; +1523;CANADIAN SYLLABICS SHWAA;Lo;0;L;;;;;N;;;;; +1524;CANADIAN SYLLABICS WEST-CREE SHWAA;Lo;0;L;;;;;N;;;;; +1525;CANADIAN SYLLABICS SH;Lo;0;L;;;;;N;;;;; +1526;CANADIAN SYLLABICS YE;Lo;0;L;;;;;N;;;;; +1527;CANADIAN SYLLABICS YAAI;Lo;0;L;;;;;N;;;;; +1528;CANADIAN SYLLABICS YI;Lo;0;L;;;;;N;;;;; +1529;CANADIAN SYLLABICS YII;Lo;0;L;;;;;N;;;;; +152A;CANADIAN SYLLABICS YO;Lo;0;L;;;;;N;;;;; +152B;CANADIAN SYLLABICS YOO;Lo;0;L;;;;;N;;;;; +152C;CANADIAN SYLLABICS Y-CREE YOO;Lo;0;L;;;;;N;;;;; +152D;CANADIAN SYLLABICS YA;Lo;0;L;;;;;N;;;;; +152E;CANADIAN SYLLABICS YAA;Lo;0;L;;;;;N;;;;; +152F;CANADIAN SYLLABICS YWE;Lo;0;L;;;;;N;;;;; +1530;CANADIAN SYLLABICS WEST-CREE YWE;Lo;0;L;;;;;N;;;;; +1531;CANADIAN SYLLABICS YWI;Lo;0;L;;;;;N;;;;; +1532;CANADIAN SYLLABICS WEST-CREE YWI;Lo;0;L;;;;;N;;;;; +1533;CANADIAN SYLLABICS YWII;Lo;0;L;;;;;N;;;;; +1534;CANADIAN SYLLABICS WEST-CREE YWII;Lo;0;L;;;;;N;;;;; +1535;CANADIAN SYLLABICS YWO;Lo;0;L;;;;;N;;;;; +1536;CANADIAN SYLLABICS WEST-CREE YWO;Lo;0;L;;;;;N;;;;; +1537;CANADIAN SYLLABICS YWOO;Lo;0;L;;;;;N;;;;; +1538;CANADIAN SYLLABICS WEST-CREE YWOO;Lo;0;L;;;;;N;;;;; +1539;CANADIAN SYLLABICS YWA;Lo;0;L;;;;;N;;;;; +153A;CANADIAN SYLLABICS WEST-CREE YWA;Lo;0;L;;;;;N;;;;; +153B;CANADIAN SYLLABICS YWAA;Lo;0;L;;;;;N;;;;; +153C;CANADIAN SYLLABICS WEST-CREE YWAA;Lo;0;L;;;;;N;;;;; +153D;CANADIAN SYLLABICS NASKAPI YWAA;Lo;0;L;;;;;N;;;;; +153E;CANADIAN SYLLABICS Y;Lo;0;L;;;;;N;;;;; +153F;CANADIAN SYLLABICS BIBLE-CREE Y;Lo;0;L;;;;;N;;;;; +1540;CANADIAN SYLLABICS WEST-CREE Y;Lo;0;L;;;;;N;;;;; +1541;CANADIAN SYLLABICS SAYISI YI;Lo;0;L;;;;;N;;;;; +1542;CANADIAN SYLLABICS RE;Lo;0;L;;;;;N;;;;; +1543;CANADIAN SYLLABICS R-CREE RE;Lo;0;L;;;;;N;;;;; +1544;CANADIAN SYLLABICS WEST-CREE LE;Lo;0;L;;;;;N;;;;; +1545;CANADIAN SYLLABICS RAAI;Lo;0;L;;;;;N;;;;; +1546;CANADIAN SYLLABICS RI;Lo;0;L;;;;;N;;;;; +1547;CANADIAN SYLLABICS RII;Lo;0;L;;;;;N;;;;; +1548;CANADIAN SYLLABICS RO;Lo;0;L;;;;;N;;;;; +1549;CANADIAN SYLLABICS ROO;Lo;0;L;;;;;N;;;;; +154A;CANADIAN SYLLABICS WEST-CREE LO;Lo;0;L;;;;;N;;;;; +154B;CANADIAN SYLLABICS RA;Lo;0;L;;;;;N;;;;; +154C;CANADIAN SYLLABICS RAA;Lo;0;L;;;;;N;;;;; +154D;CANADIAN SYLLABICS WEST-CREE LA;Lo;0;L;;;;;N;;;;; +154E;CANADIAN SYLLABICS RWAA;Lo;0;L;;;;;N;;;;; +154F;CANADIAN SYLLABICS WEST-CREE RWAA;Lo;0;L;;;;;N;;;;; +1550;CANADIAN SYLLABICS R;Lo;0;L;;;;;N;;;;; +1551;CANADIAN SYLLABICS WEST-CREE R;Lo;0;L;;;;;N;;;;; +1552;CANADIAN SYLLABICS MEDIAL R;Lo;0;L;;;;;N;;;;; +1553;CANADIAN SYLLABICS FE;Lo;0;L;;;;;N;;;;; +1554;CANADIAN SYLLABICS FAAI;Lo;0;L;;;;;N;;;;; +1555;CANADIAN SYLLABICS FI;Lo;0;L;;;;;N;;;;; +1556;CANADIAN SYLLABICS FII;Lo;0;L;;;;;N;;;;; +1557;CANADIAN SYLLABICS FO;Lo;0;L;;;;;N;;;;; +1558;CANADIAN SYLLABICS FOO;Lo;0;L;;;;;N;;;;; +1559;CANADIAN SYLLABICS FA;Lo;0;L;;;;;N;;;;; +155A;CANADIAN SYLLABICS FAA;Lo;0;L;;;;;N;;;;; +155B;CANADIAN SYLLABICS FWAA;Lo;0;L;;;;;N;;;;; +155C;CANADIAN SYLLABICS WEST-CREE FWAA;Lo;0;L;;;;;N;;;;; +155D;CANADIAN SYLLABICS F;Lo;0;L;;;;;N;;;;; +155E;CANADIAN SYLLABICS THE;Lo;0;L;;;;;N;;;;; +155F;CANADIAN SYLLABICS N-CREE THE;Lo;0;L;;;;;N;;;;; +1560;CANADIAN SYLLABICS THI;Lo;0;L;;;;;N;;;;; +1561;CANADIAN SYLLABICS N-CREE THI;Lo;0;L;;;;;N;;;;; +1562;CANADIAN SYLLABICS THII;Lo;0;L;;;;;N;;;;; +1563;CANADIAN SYLLABICS N-CREE THII;Lo;0;L;;;;;N;;;;; +1564;CANADIAN SYLLABICS THO;Lo;0;L;;;;;N;;;;; +1565;CANADIAN SYLLABICS THOO;Lo;0;L;;;;;N;;;;; +1566;CANADIAN SYLLABICS THA;Lo;0;L;;;;;N;;;;; +1567;CANADIAN SYLLABICS THAA;Lo;0;L;;;;;N;;;;; +1568;CANADIAN SYLLABICS THWAA;Lo;0;L;;;;;N;;;;; +1569;CANADIAN SYLLABICS WEST-CREE THWAA;Lo;0;L;;;;;N;;;;; +156A;CANADIAN SYLLABICS TH;Lo;0;L;;;;;N;;;;; +156B;CANADIAN SYLLABICS TTHE;Lo;0;L;;;;;N;;;;; +156C;CANADIAN SYLLABICS TTHI;Lo;0;L;;;;;N;;;;; +156D;CANADIAN SYLLABICS TTHO;Lo;0;L;;;;;N;;;;; +156E;CANADIAN SYLLABICS TTHA;Lo;0;L;;;;;N;;;;; +156F;CANADIAN SYLLABICS TTH;Lo;0;L;;;;;N;;;;; +1570;CANADIAN SYLLABICS TYE;Lo;0;L;;;;;N;;;;; +1571;CANADIAN SYLLABICS TYI;Lo;0;L;;;;;N;;;;; +1572;CANADIAN SYLLABICS TYO;Lo;0;L;;;;;N;;;;; +1573;CANADIAN SYLLABICS TYA;Lo;0;L;;;;;N;;;;; +1574;CANADIAN SYLLABICS NUNAVIK HE;Lo;0;L;;;;;N;;;;; +1575;CANADIAN SYLLABICS NUNAVIK HI;Lo;0;L;;;;;N;;;;; +1576;CANADIAN SYLLABICS NUNAVIK HII;Lo;0;L;;;;;N;;;;; +1577;CANADIAN SYLLABICS NUNAVIK HO;Lo;0;L;;;;;N;;;;; +1578;CANADIAN SYLLABICS NUNAVIK HOO;Lo;0;L;;;;;N;;;;; +1579;CANADIAN SYLLABICS NUNAVIK HA;Lo;0;L;;;;;N;;;;; +157A;CANADIAN SYLLABICS NUNAVIK HAA;Lo;0;L;;;;;N;;;;; +157B;CANADIAN SYLLABICS NUNAVIK H;Lo;0;L;;;;;N;;;;; +157C;CANADIAN SYLLABICS NUNAVUT H;Lo;0;L;;;;;N;;;;; +157D;CANADIAN SYLLABICS HK;Lo;0;L;;;;;N;;;;; +157E;CANADIAN SYLLABICS QAAI;Lo;0;L;;;;;N;;;;; +157F;CANADIAN SYLLABICS QI;Lo;0;L;;;;;N;;;;; +1580;CANADIAN SYLLABICS QII;Lo;0;L;;;;;N;;;;; +1581;CANADIAN SYLLABICS QO;Lo;0;L;;;;;N;;;;; +1582;CANADIAN SYLLABICS QOO;Lo;0;L;;;;;N;;;;; +1583;CANADIAN SYLLABICS QA;Lo;0;L;;;;;N;;;;; +1584;CANADIAN SYLLABICS QAA;Lo;0;L;;;;;N;;;;; +1585;CANADIAN SYLLABICS Q;Lo;0;L;;;;;N;;;;; +1586;CANADIAN SYLLABICS TLHE;Lo;0;L;;;;;N;;;;; +1587;CANADIAN SYLLABICS TLHI;Lo;0;L;;;;;N;;;;; +1588;CANADIAN SYLLABICS TLHO;Lo;0;L;;;;;N;;;;; +1589;CANADIAN SYLLABICS TLHA;Lo;0;L;;;;;N;;;;; +158A;CANADIAN SYLLABICS WEST-CREE RE;Lo;0;L;;;;;N;;;;; +158B;CANADIAN SYLLABICS WEST-CREE RI;Lo;0;L;;;;;N;;;;; +158C;CANADIAN SYLLABICS WEST-CREE RO;Lo;0;L;;;;;N;;;;; +158D;CANADIAN SYLLABICS WEST-CREE RA;Lo;0;L;;;;;N;;;;; +158E;CANADIAN SYLLABICS NGAAI;Lo;0;L;;;;;N;;;;; +158F;CANADIAN SYLLABICS NGI;Lo;0;L;;;;;N;;;;; +1590;CANADIAN SYLLABICS NGII;Lo;0;L;;;;;N;;;;; +1591;CANADIAN SYLLABICS NGO;Lo;0;L;;;;;N;;;;; +1592;CANADIAN SYLLABICS NGOO;Lo;0;L;;;;;N;;;;; +1593;CANADIAN SYLLABICS NGA;Lo;0;L;;;;;N;;;;; +1594;CANADIAN SYLLABICS NGAA;Lo;0;L;;;;;N;;;;; +1595;CANADIAN SYLLABICS NG;Lo;0;L;;;;;N;;;;; +1596;CANADIAN SYLLABICS NNG;Lo;0;L;;;;;N;;;;; +1597;CANADIAN SYLLABICS SAYISI SHE;Lo;0;L;;;;;N;;;;; +1598;CANADIAN SYLLABICS SAYISI SHI;Lo;0;L;;;;;N;;;;; +1599;CANADIAN SYLLABICS SAYISI SHO;Lo;0;L;;;;;N;;;;; +159A;CANADIAN SYLLABICS SAYISI SHA;Lo;0;L;;;;;N;;;;; +159B;CANADIAN SYLLABICS WOODS-CREE THE;Lo;0;L;;;;;N;;;;; +159C;CANADIAN SYLLABICS WOODS-CREE THI;Lo;0;L;;;;;N;;;;; +159D;CANADIAN SYLLABICS WOODS-CREE THO;Lo;0;L;;;;;N;;;;; +159E;CANADIAN SYLLABICS WOODS-CREE THA;Lo;0;L;;;;;N;;;;; +159F;CANADIAN SYLLABICS WOODS-CREE TH;Lo;0;L;;;;;N;;;;; +15A0;CANADIAN SYLLABICS LHI;Lo;0;L;;;;;N;;;;; +15A1;CANADIAN SYLLABICS LHII;Lo;0;L;;;;;N;;;;; +15A2;CANADIAN SYLLABICS LHO;Lo;0;L;;;;;N;;;;; +15A3;CANADIAN SYLLABICS LHOO;Lo;0;L;;;;;N;;;;; +15A4;CANADIAN SYLLABICS LHA;Lo;0;L;;;;;N;;;;; +15A5;CANADIAN SYLLABICS LHAA;Lo;0;L;;;;;N;;;;; +15A6;CANADIAN SYLLABICS LH;Lo;0;L;;;;;N;;;;; +15A7;CANADIAN SYLLABICS TH-CREE THE;Lo;0;L;;;;;N;;;;; +15A8;CANADIAN SYLLABICS TH-CREE THI;Lo;0;L;;;;;N;;;;; +15A9;CANADIAN SYLLABICS TH-CREE THII;Lo;0;L;;;;;N;;;;; +15AA;CANADIAN SYLLABICS TH-CREE THO;Lo;0;L;;;;;N;;;;; +15AB;CANADIAN SYLLABICS TH-CREE THOO;Lo;0;L;;;;;N;;;;; +15AC;CANADIAN SYLLABICS TH-CREE THA;Lo;0;L;;;;;N;;;;; +15AD;CANADIAN SYLLABICS TH-CREE THAA;Lo;0;L;;;;;N;;;;; +15AE;CANADIAN SYLLABICS TH-CREE TH;Lo;0;L;;;;;N;;;;; +15AF;CANADIAN SYLLABICS AIVILIK B;Lo;0;L;;;;;N;;;;; +15B0;CANADIAN SYLLABICS BLACKFOOT E;Lo;0;L;;;;;N;;;;; +15B1;CANADIAN SYLLABICS BLACKFOOT I;Lo;0;L;;;;;N;;;;; +15B2;CANADIAN SYLLABICS BLACKFOOT O;Lo;0;L;;;;;N;;;;; +15B3;CANADIAN SYLLABICS BLACKFOOT A;Lo;0;L;;;;;N;;;;; +15B4;CANADIAN SYLLABICS BLACKFOOT WE;Lo;0;L;;;;;N;;;;; +15B5;CANADIAN SYLLABICS BLACKFOOT WI;Lo;0;L;;;;;N;;;;; +15B6;CANADIAN SYLLABICS BLACKFOOT WO;Lo;0;L;;;;;N;;;;; +15B7;CANADIAN SYLLABICS BLACKFOOT WA;Lo;0;L;;;;;N;;;;; +15B8;CANADIAN SYLLABICS BLACKFOOT NE;Lo;0;L;;;;;N;;;;; +15B9;CANADIAN SYLLABICS BLACKFOOT NI;Lo;0;L;;;;;N;;;;; +15BA;CANADIAN SYLLABICS BLACKFOOT NO;Lo;0;L;;;;;N;;;;; +15BB;CANADIAN SYLLABICS BLACKFOOT NA;Lo;0;L;;;;;N;;;;; +15BC;CANADIAN SYLLABICS BLACKFOOT KE;Lo;0;L;;;;;N;;;;; +15BD;CANADIAN SYLLABICS BLACKFOOT KI;Lo;0;L;;;;;N;;;;; +15BE;CANADIAN SYLLABICS BLACKFOOT KO;Lo;0;L;;;;;N;;;;; +15BF;CANADIAN SYLLABICS BLACKFOOT KA;Lo;0;L;;;;;N;;;;; +15C0;CANADIAN SYLLABICS SAYISI HE;Lo;0;L;;;;;N;;;;; +15C1;CANADIAN SYLLABICS SAYISI HI;Lo;0;L;;;;;N;;;;; +15C2;CANADIAN SYLLABICS SAYISI HO;Lo;0;L;;;;;N;;;;; +15C3;CANADIAN SYLLABICS SAYISI HA;Lo;0;L;;;;;N;;;;; +15C4;CANADIAN SYLLABICS CARRIER GHU;Lo;0;L;;;;;N;;;;; +15C5;CANADIAN SYLLABICS CARRIER GHO;Lo;0;L;;;;;N;;;;; +15C6;CANADIAN SYLLABICS CARRIER GHE;Lo;0;L;;;;;N;;;;; +15C7;CANADIAN SYLLABICS CARRIER GHEE;Lo;0;L;;;;;N;;;;; +15C8;CANADIAN SYLLABICS CARRIER GHI;Lo;0;L;;;;;N;;;;; +15C9;CANADIAN SYLLABICS CARRIER GHA;Lo;0;L;;;;;N;;;;; +15CA;CANADIAN SYLLABICS CARRIER RU;Lo;0;L;;;;;N;;;;; +15CB;CANADIAN SYLLABICS CARRIER RO;Lo;0;L;;;;;N;;;;; +15CC;CANADIAN SYLLABICS CARRIER RE;Lo;0;L;;;;;N;;;;; +15CD;CANADIAN SYLLABICS CARRIER REE;Lo;0;L;;;;;N;;;;; +15CE;CANADIAN SYLLABICS CARRIER RI;Lo;0;L;;;;;N;;;;; +15CF;CANADIAN SYLLABICS CARRIER RA;Lo;0;L;;;;;N;;;;; +15D0;CANADIAN SYLLABICS CARRIER WU;Lo;0;L;;;;;N;;;;; +15D1;CANADIAN SYLLABICS CARRIER WO;Lo;0;L;;;;;N;;;;; +15D2;CANADIAN SYLLABICS CARRIER WE;Lo;0;L;;;;;N;;;;; +15D3;CANADIAN SYLLABICS CARRIER WEE;Lo;0;L;;;;;N;;;;; +15D4;CANADIAN SYLLABICS CARRIER WI;Lo;0;L;;;;;N;;;;; +15D5;CANADIAN SYLLABICS CARRIER WA;Lo;0;L;;;;;N;;;;; +15D6;CANADIAN SYLLABICS CARRIER HWU;Lo;0;L;;;;;N;;;;; +15D7;CANADIAN SYLLABICS CARRIER HWO;Lo;0;L;;;;;N;;;;; +15D8;CANADIAN SYLLABICS CARRIER HWE;Lo;0;L;;;;;N;;;;; +15D9;CANADIAN SYLLABICS CARRIER HWEE;Lo;0;L;;;;;N;;;;; +15DA;CANADIAN SYLLABICS CARRIER HWI;Lo;0;L;;;;;N;;;;; +15DB;CANADIAN SYLLABICS CARRIER HWA;Lo;0;L;;;;;N;;;;; +15DC;CANADIAN SYLLABICS CARRIER THU;Lo;0;L;;;;;N;;;;; +15DD;CANADIAN SYLLABICS CARRIER THO;Lo;0;L;;;;;N;;;;; +15DE;CANADIAN SYLLABICS CARRIER THE;Lo;0;L;;;;;N;;;;; +15DF;CANADIAN SYLLABICS CARRIER THEE;Lo;0;L;;;;;N;;;;; +15E0;CANADIAN SYLLABICS CARRIER THI;Lo;0;L;;;;;N;;;;; +15E1;CANADIAN SYLLABICS CARRIER THA;Lo;0;L;;;;;N;;;;; +15E2;CANADIAN SYLLABICS CARRIER TTU;Lo;0;L;;;;;N;;;;; +15E3;CANADIAN SYLLABICS CARRIER TTO;Lo;0;L;;;;;N;;;;; +15E4;CANADIAN SYLLABICS CARRIER TTE;Lo;0;L;;;;;N;;;;; +15E5;CANADIAN SYLLABICS CARRIER TTEE;Lo;0;L;;;;;N;;;;; +15E6;CANADIAN SYLLABICS CARRIER TTI;Lo;0;L;;;;;N;;;;; +15E7;CANADIAN SYLLABICS CARRIER TTA;Lo;0;L;;;;;N;;;;; +15E8;CANADIAN SYLLABICS CARRIER PU;Lo;0;L;;;;;N;;;;; +15E9;CANADIAN SYLLABICS CARRIER PO;Lo;0;L;;;;;N;;;;; +15EA;CANADIAN SYLLABICS CARRIER PE;Lo;0;L;;;;;N;;;;; +15EB;CANADIAN SYLLABICS CARRIER PEE;Lo;0;L;;;;;N;;;;; +15EC;CANADIAN SYLLABICS CARRIER PI;Lo;0;L;;;;;N;;;;; +15ED;CANADIAN SYLLABICS CARRIER PA;Lo;0;L;;;;;N;;;;; +15EE;CANADIAN SYLLABICS CARRIER P;Lo;0;L;;;;;N;;;;; +15EF;CANADIAN SYLLABICS CARRIER GU;Lo;0;L;;;;;N;;;;; +15F0;CANADIAN SYLLABICS CARRIER GO;Lo;0;L;;;;;N;;;;; +15F1;CANADIAN SYLLABICS CARRIER GE;Lo;0;L;;;;;N;;;;; +15F2;CANADIAN SYLLABICS CARRIER GEE;Lo;0;L;;;;;N;;;;; +15F3;CANADIAN SYLLABICS CARRIER GI;Lo;0;L;;;;;N;;;;; +15F4;CANADIAN SYLLABICS CARRIER GA;Lo;0;L;;;;;N;;;;; +15F5;CANADIAN SYLLABICS CARRIER KHU;Lo;0;L;;;;;N;;;;; +15F6;CANADIAN SYLLABICS CARRIER KHO;Lo;0;L;;;;;N;;;;; +15F7;CANADIAN SYLLABICS CARRIER KHE;Lo;0;L;;;;;N;;;;; +15F8;CANADIAN SYLLABICS CARRIER KHEE;Lo;0;L;;;;;N;;;;; +15F9;CANADIAN SYLLABICS CARRIER KHI;Lo;0;L;;;;;N;;;;; +15FA;CANADIAN SYLLABICS CARRIER KHA;Lo;0;L;;;;;N;;;;; +15FB;CANADIAN SYLLABICS CARRIER KKU;Lo;0;L;;;;;N;;;;; +15FC;CANADIAN SYLLABICS CARRIER KKO;Lo;0;L;;;;;N;;;;; +15FD;CANADIAN SYLLABICS CARRIER KKE;Lo;0;L;;;;;N;;;;; +15FE;CANADIAN SYLLABICS CARRIER KKEE;Lo;0;L;;;;;N;;;;; +15FF;CANADIAN SYLLABICS CARRIER KKI;Lo;0;L;;;;;N;;;;; +1600;CANADIAN SYLLABICS CARRIER KKA;Lo;0;L;;;;;N;;;;; +1601;CANADIAN SYLLABICS CARRIER KK;Lo;0;L;;;;;N;;;;; +1602;CANADIAN SYLLABICS CARRIER NU;Lo;0;L;;;;;N;;;;; +1603;CANADIAN SYLLABICS CARRIER NO;Lo;0;L;;;;;N;;;;; +1604;CANADIAN SYLLABICS CARRIER NE;Lo;0;L;;;;;N;;;;; +1605;CANADIAN SYLLABICS CARRIER NEE;Lo;0;L;;;;;N;;;;; +1606;CANADIAN SYLLABICS CARRIER NI;Lo;0;L;;;;;N;;;;; +1607;CANADIAN SYLLABICS CARRIER NA;Lo;0;L;;;;;N;;;;; +1608;CANADIAN SYLLABICS CARRIER MU;Lo;0;L;;;;;N;;;;; +1609;CANADIAN SYLLABICS CARRIER MO;Lo;0;L;;;;;N;;;;; +160A;CANADIAN SYLLABICS CARRIER ME;Lo;0;L;;;;;N;;;;; +160B;CANADIAN SYLLABICS CARRIER MEE;Lo;0;L;;;;;N;;;;; +160C;CANADIAN SYLLABICS CARRIER MI;Lo;0;L;;;;;N;;;;; +160D;CANADIAN SYLLABICS CARRIER MA;Lo;0;L;;;;;N;;;;; +160E;CANADIAN SYLLABICS CARRIER YU;Lo;0;L;;;;;N;;;;; +160F;CANADIAN SYLLABICS CARRIER YO;Lo;0;L;;;;;N;;;;; +1610;CANADIAN SYLLABICS CARRIER YE;Lo;0;L;;;;;N;;;;; +1611;CANADIAN SYLLABICS CARRIER YEE;Lo;0;L;;;;;N;;;;; +1612;CANADIAN SYLLABICS CARRIER YI;Lo;0;L;;;;;N;;;;; +1613;CANADIAN SYLLABICS CARRIER YA;Lo;0;L;;;;;N;;;;; +1614;CANADIAN SYLLABICS CARRIER JU;Lo;0;L;;;;;N;;;;; +1615;CANADIAN SYLLABICS SAYISI JU;Lo;0;L;;;;;N;;;;; +1616;CANADIAN SYLLABICS CARRIER JO;Lo;0;L;;;;;N;;;;; +1617;CANADIAN SYLLABICS CARRIER JE;Lo;0;L;;;;;N;;;;; +1618;CANADIAN SYLLABICS CARRIER JEE;Lo;0;L;;;;;N;;;;; +1619;CANADIAN SYLLABICS CARRIER JI;Lo;0;L;;;;;N;;;;; +161A;CANADIAN SYLLABICS SAYISI JI;Lo;0;L;;;;;N;;;;; +161B;CANADIAN SYLLABICS CARRIER JA;Lo;0;L;;;;;N;;;;; +161C;CANADIAN SYLLABICS CARRIER JJU;Lo;0;L;;;;;N;;;;; +161D;CANADIAN SYLLABICS CARRIER JJO;Lo;0;L;;;;;N;;;;; +161E;CANADIAN SYLLABICS CARRIER JJE;Lo;0;L;;;;;N;;;;; +161F;CANADIAN SYLLABICS CARRIER JJEE;Lo;0;L;;;;;N;;;;; +1620;CANADIAN SYLLABICS CARRIER JJI;Lo;0;L;;;;;N;;;;; +1621;CANADIAN SYLLABICS CARRIER JJA;Lo;0;L;;;;;N;;;;; +1622;CANADIAN SYLLABICS CARRIER LU;Lo;0;L;;;;;N;;;;; +1623;CANADIAN SYLLABICS CARRIER LO;Lo;0;L;;;;;N;;;;; +1624;CANADIAN SYLLABICS CARRIER LE;Lo;0;L;;;;;N;;;;; +1625;CANADIAN SYLLABICS CARRIER LEE;Lo;0;L;;;;;N;;;;; +1626;CANADIAN SYLLABICS CARRIER LI;Lo;0;L;;;;;N;;;;; +1627;CANADIAN SYLLABICS CARRIER LA;Lo;0;L;;;;;N;;;;; +1628;CANADIAN SYLLABICS CARRIER DLU;Lo;0;L;;;;;N;;;;; +1629;CANADIAN SYLLABICS CARRIER DLO;Lo;0;L;;;;;N;;;;; +162A;CANADIAN SYLLABICS CARRIER DLE;Lo;0;L;;;;;N;;;;; +162B;CANADIAN SYLLABICS CARRIER DLEE;Lo;0;L;;;;;N;;;;; +162C;CANADIAN SYLLABICS CARRIER DLI;Lo;0;L;;;;;N;;;;; +162D;CANADIAN SYLLABICS CARRIER DLA;Lo;0;L;;;;;N;;;;; +162E;CANADIAN SYLLABICS CARRIER LHU;Lo;0;L;;;;;N;;;;; +162F;CANADIAN SYLLABICS CARRIER LHO;Lo;0;L;;;;;N;;;;; +1630;CANADIAN SYLLABICS CARRIER LHE;Lo;0;L;;;;;N;;;;; +1631;CANADIAN SYLLABICS CARRIER LHEE;Lo;0;L;;;;;N;;;;; +1632;CANADIAN SYLLABICS CARRIER LHI;Lo;0;L;;;;;N;;;;; +1633;CANADIAN SYLLABICS CARRIER LHA;Lo;0;L;;;;;N;;;;; +1634;CANADIAN SYLLABICS CARRIER TLHU;Lo;0;L;;;;;N;;;;; +1635;CANADIAN SYLLABICS CARRIER TLHO;Lo;0;L;;;;;N;;;;; +1636;CANADIAN SYLLABICS CARRIER TLHE;Lo;0;L;;;;;N;;;;; +1637;CANADIAN SYLLABICS CARRIER TLHEE;Lo;0;L;;;;;N;;;;; +1638;CANADIAN SYLLABICS CARRIER TLHI;Lo;0;L;;;;;N;;;;; +1639;CANADIAN SYLLABICS CARRIER TLHA;Lo;0;L;;;;;N;;;;; +163A;CANADIAN SYLLABICS CARRIER TLU;Lo;0;L;;;;;N;;;;; +163B;CANADIAN SYLLABICS CARRIER TLO;Lo;0;L;;;;;N;;;;; +163C;CANADIAN SYLLABICS CARRIER TLE;Lo;0;L;;;;;N;;;;; +163D;CANADIAN SYLLABICS CARRIER TLEE;Lo;0;L;;;;;N;;;;; +163E;CANADIAN SYLLABICS CARRIER TLI;Lo;0;L;;;;;N;;;;; +163F;CANADIAN SYLLABICS CARRIER TLA;Lo;0;L;;;;;N;;;;; +1640;CANADIAN SYLLABICS CARRIER ZU;Lo;0;L;;;;;N;;;;; +1641;CANADIAN SYLLABICS CARRIER ZO;Lo;0;L;;;;;N;;;;; +1642;CANADIAN SYLLABICS CARRIER ZE;Lo;0;L;;;;;N;;;;; +1643;CANADIAN SYLLABICS CARRIER ZEE;Lo;0;L;;;;;N;;;;; +1644;CANADIAN SYLLABICS CARRIER ZI;Lo;0;L;;;;;N;;;;; +1645;CANADIAN SYLLABICS CARRIER ZA;Lo;0;L;;;;;N;;;;; +1646;CANADIAN SYLLABICS CARRIER Z;Lo;0;L;;;;;N;;;;; +1647;CANADIAN SYLLABICS CARRIER INITIAL Z;Lo;0;L;;;;;N;;;;; +1648;CANADIAN SYLLABICS CARRIER DZU;Lo;0;L;;;;;N;;;;; +1649;CANADIAN SYLLABICS CARRIER DZO;Lo;0;L;;;;;N;;;;; +164A;CANADIAN SYLLABICS CARRIER DZE;Lo;0;L;;;;;N;;;;; +164B;CANADIAN SYLLABICS CARRIER DZEE;Lo;0;L;;;;;N;;;;; +164C;CANADIAN SYLLABICS CARRIER DZI;Lo;0;L;;;;;N;;;;; +164D;CANADIAN SYLLABICS CARRIER DZA;Lo;0;L;;;;;N;;;;; +164E;CANADIAN SYLLABICS CARRIER SU;Lo;0;L;;;;;N;;;;; +164F;CANADIAN SYLLABICS CARRIER SO;Lo;0;L;;;;;N;;;;; +1650;CANADIAN SYLLABICS CARRIER SE;Lo;0;L;;;;;N;;;;; +1651;CANADIAN SYLLABICS CARRIER SEE;Lo;0;L;;;;;N;;;;; +1652;CANADIAN SYLLABICS CARRIER SI;Lo;0;L;;;;;N;;;;; +1653;CANADIAN SYLLABICS CARRIER SA;Lo;0;L;;;;;N;;;;; +1654;CANADIAN SYLLABICS CARRIER SHU;Lo;0;L;;;;;N;;;;; +1655;CANADIAN SYLLABICS CARRIER SHO;Lo;0;L;;;;;N;;;;; +1656;CANADIAN SYLLABICS CARRIER SHE;Lo;0;L;;;;;N;;;;; +1657;CANADIAN SYLLABICS CARRIER SHEE;Lo;0;L;;;;;N;;;;; +1658;CANADIAN SYLLABICS CARRIER SHI;Lo;0;L;;;;;N;;;;; +1659;CANADIAN SYLLABICS CARRIER SHA;Lo;0;L;;;;;N;;;;; +165A;CANADIAN SYLLABICS CARRIER SH;Lo;0;L;;;;;N;;;;; +165B;CANADIAN SYLLABICS CARRIER TSU;Lo;0;L;;;;;N;;;;; +165C;CANADIAN SYLLABICS CARRIER TSO;Lo;0;L;;;;;N;;;;; +165D;CANADIAN SYLLABICS CARRIER TSE;Lo;0;L;;;;;N;;;;; +165E;CANADIAN SYLLABICS CARRIER TSEE;Lo;0;L;;;;;N;;;;; +165F;CANADIAN SYLLABICS CARRIER TSI;Lo;0;L;;;;;N;;;;; +1660;CANADIAN SYLLABICS CARRIER TSA;Lo;0;L;;;;;N;;;;; +1661;CANADIAN SYLLABICS CARRIER CHU;Lo;0;L;;;;;N;;;;; +1662;CANADIAN SYLLABICS CARRIER CHO;Lo;0;L;;;;;N;;;;; +1663;CANADIAN SYLLABICS CARRIER CHE;Lo;0;L;;;;;N;;;;; +1664;CANADIAN SYLLABICS CARRIER CHEE;Lo;0;L;;;;;N;;;;; +1665;CANADIAN SYLLABICS CARRIER CHI;Lo;0;L;;;;;N;;;;; +1666;CANADIAN SYLLABICS CARRIER CHA;Lo;0;L;;;;;N;;;;; +1667;CANADIAN SYLLABICS CARRIER TTSU;Lo;0;L;;;;;N;;;;; +1668;CANADIAN SYLLABICS CARRIER TTSO;Lo;0;L;;;;;N;;;;; +1669;CANADIAN SYLLABICS CARRIER TTSE;Lo;0;L;;;;;N;;;;; +166A;CANADIAN SYLLABICS CARRIER TTSEE;Lo;0;L;;;;;N;;;;; +166B;CANADIAN SYLLABICS CARRIER TTSI;Lo;0;L;;;;;N;;;;; +166C;CANADIAN SYLLABICS CARRIER TTSA;Lo;0;L;;;;;N;;;;; +166D;CANADIAN SYLLABICS CHI SIGN;So;0;L;;;;;N;;;;; +166E;CANADIAN SYLLABICS FULL STOP;Po;0;L;;;;;N;;;;; +166F;CANADIAN SYLLABICS QAI;Lo;0;L;;;;;N;;;;; +1670;CANADIAN SYLLABICS NGAI;Lo;0;L;;;;;N;;;;; +1671;CANADIAN SYLLABICS NNGI;Lo;0;L;;;;;N;;;;; +1672;CANADIAN SYLLABICS NNGII;Lo;0;L;;;;;N;;;;; +1673;CANADIAN SYLLABICS NNGO;Lo;0;L;;;;;N;;;;; +1674;CANADIAN SYLLABICS NNGOO;Lo;0;L;;;;;N;;;;; +1675;CANADIAN SYLLABICS NNGA;Lo;0;L;;;;;N;;;;; +1676;CANADIAN SYLLABICS NNGAA;Lo;0;L;;;;;N;;;;; +1677;CANADIAN SYLLABICS WOODS-CREE THWEE;Lo;0;L;;;;;N;;;;; +1678;CANADIAN SYLLABICS WOODS-CREE THWI;Lo;0;L;;;;;N;;;;; +1679;CANADIAN SYLLABICS WOODS-CREE THWII;Lo;0;L;;;;;N;;;;; +167A;CANADIAN SYLLABICS WOODS-CREE THWO;Lo;0;L;;;;;N;;;;; +167B;CANADIAN SYLLABICS WOODS-CREE THWOO;Lo;0;L;;;;;N;;;;; +167C;CANADIAN SYLLABICS WOODS-CREE THWA;Lo;0;L;;;;;N;;;;; +167D;CANADIAN SYLLABICS WOODS-CREE THWAA;Lo;0;L;;;;;N;;;;; +167E;CANADIAN SYLLABICS WOODS-CREE FINAL TH;Lo;0;L;;;;;N;;;;; +167F;CANADIAN SYLLABICS BLACKFOOT W;Lo;0;L;;;;;N;;;;; +1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;; +1681;OGHAM LETTER BEITH;Lo;0;L;;;;;N;;;;; +1682;OGHAM LETTER LUIS;Lo;0;L;;;;;N;;;;; +1683;OGHAM LETTER FEARN;Lo;0;L;;;;;N;;;;; +1684;OGHAM LETTER SAIL;Lo;0;L;;;;;N;;;;; +1685;OGHAM LETTER NION;Lo;0;L;;;;;N;;;;; +1686;OGHAM LETTER UATH;Lo;0;L;;;;;N;;;;; +1687;OGHAM LETTER DAIR;Lo;0;L;;;;;N;;;;; +1688;OGHAM LETTER TINNE;Lo;0;L;;;;;N;;;;; +1689;OGHAM LETTER COLL;Lo;0;L;;;;;N;;;;; +168A;OGHAM LETTER CEIRT;Lo;0;L;;;;;N;;;;; +168B;OGHAM LETTER MUIN;Lo;0;L;;;;;N;;;;; +168C;OGHAM LETTER GORT;Lo;0;L;;;;;N;;;;; +168D;OGHAM LETTER NGEADAL;Lo;0;L;;;;;N;;;;; +168E;OGHAM LETTER STRAIF;Lo;0;L;;;;;N;;;;; +168F;OGHAM LETTER RUIS;Lo;0;L;;;;;N;;;;; +1690;OGHAM LETTER AILM;Lo;0;L;;;;;N;;;;; +1691;OGHAM LETTER ONN;Lo;0;L;;;;;N;;;;; +1692;OGHAM LETTER UR;Lo;0;L;;;;;N;;;;; +1693;OGHAM LETTER EADHADH;Lo;0;L;;;;;N;;;;; +1694;OGHAM LETTER IODHADH;Lo;0;L;;;;;N;;;;; +1695;OGHAM LETTER EABHADH;Lo;0;L;;;;;N;;;;; +1696;OGHAM LETTER OR;Lo;0;L;;;;;N;;;;; +1697;OGHAM LETTER UILLEANN;Lo;0;L;;;;;N;;;;; +1698;OGHAM LETTER IFIN;Lo;0;L;;;;;N;;;;; +1699;OGHAM LETTER EAMHANCHOLL;Lo;0;L;;;;;N;;;;; +169A;OGHAM LETTER PEITH;Lo;0;L;;;;;N;;;;; +169B;OGHAM FEATHER MARK;Ps;0;ON;;;;;Y;;;;; +169C;OGHAM REVERSED FEATHER MARK;Pe;0;ON;;;;;Y;;;;; +16A0;RUNIC LETTER FEHU FEOH FE F;Lo;0;L;;;;;N;;;;; +16A1;RUNIC LETTER V;Lo;0;L;;;;;N;;;;; +16A2;RUNIC LETTER URUZ UR U;Lo;0;L;;;;;N;;;;; +16A3;RUNIC LETTER YR;Lo;0;L;;;;;N;;;;; +16A4;RUNIC LETTER Y;Lo;0;L;;;;;N;;;;; +16A5;RUNIC LETTER W;Lo;0;L;;;;;N;;;;; +16A6;RUNIC LETTER THURISAZ THURS THORN;Lo;0;L;;;;;N;;;;; +16A7;RUNIC LETTER ETH;Lo;0;L;;;;;N;;;;; +16A8;RUNIC LETTER ANSUZ A;Lo;0;L;;;;;N;;;;; +16A9;RUNIC LETTER OS O;Lo;0;L;;;;;N;;;;; +16AA;RUNIC LETTER AC A;Lo;0;L;;;;;N;;;;; +16AB;RUNIC LETTER AESC;Lo;0;L;;;;;N;;;;; +16AC;RUNIC LETTER LONG-BRANCH-OSS O;Lo;0;L;;;;;N;;;;; +16AD;RUNIC LETTER SHORT-TWIG-OSS O;Lo;0;L;;;;;N;;;;; +16AE;RUNIC LETTER O;Lo;0;L;;;;;N;;;;; +16AF;RUNIC LETTER OE;Lo;0;L;;;;;N;;;;; +16B0;RUNIC LETTER ON;Lo;0;L;;;;;N;;;;; +16B1;RUNIC LETTER RAIDO RAD REID R;Lo;0;L;;;;;N;;;;; +16B2;RUNIC LETTER KAUNA;Lo;0;L;;;;;N;;;;; +16B3;RUNIC LETTER CEN;Lo;0;L;;;;;N;;;;; +16B4;RUNIC LETTER KAUN K;Lo;0;L;;;;;N;;;;; +16B5;RUNIC LETTER G;Lo;0;L;;;;;N;;;;; +16B6;RUNIC LETTER ENG;Lo;0;L;;;;;N;;;;; +16B7;RUNIC LETTER GEBO GYFU G;Lo;0;L;;;;;N;;;;; +16B8;RUNIC LETTER GAR;Lo;0;L;;;;;N;;;;; +16B9;RUNIC LETTER WUNJO WYNN W;Lo;0;L;;;;;N;;;;; +16BA;RUNIC LETTER HAGLAZ H;Lo;0;L;;;;;N;;;;; +16BB;RUNIC LETTER HAEGL H;Lo;0;L;;;;;N;;;;; +16BC;RUNIC LETTER LONG-BRANCH-HAGALL H;Lo;0;L;;;;;N;;;;; +16BD;RUNIC LETTER SHORT-TWIG-HAGALL H;Lo;0;L;;;;;N;;;;; +16BE;RUNIC LETTER NAUDIZ NYD NAUD N;Lo;0;L;;;;;N;;;;; +16BF;RUNIC LETTER SHORT-TWIG-NAUD N;Lo;0;L;;;;;N;;;;; +16C0;RUNIC LETTER DOTTED-N;Lo;0;L;;;;;N;;;;; +16C1;RUNIC LETTER ISAZ IS ISS I;Lo;0;L;;;;;N;;;;; +16C2;RUNIC LETTER E;Lo;0;L;;;;;N;;;;; +16C3;RUNIC LETTER JERAN J;Lo;0;L;;;;;N;;;;; +16C4;RUNIC LETTER GER;Lo;0;L;;;;;N;;;;; +16C5;RUNIC LETTER LONG-BRANCH-AR AE;Lo;0;L;;;;;N;;;;; +16C6;RUNIC LETTER SHORT-TWIG-AR A;Lo;0;L;;;;;N;;;;; +16C7;RUNIC LETTER IWAZ EOH;Lo;0;L;;;;;N;;;;; +16C8;RUNIC LETTER PERTHO PEORTH P;Lo;0;L;;;;;N;;;;; +16C9;RUNIC LETTER ALGIZ EOLHX;Lo;0;L;;;;;N;;;;; +16CA;RUNIC LETTER SOWILO S;Lo;0;L;;;;;N;;;;; +16CB;RUNIC LETTER SIGEL LONG-BRANCH-SOL S;Lo;0;L;;;;;N;;;;; +16CC;RUNIC LETTER SHORT-TWIG-SOL S;Lo;0;L;;;;;N;;;;; +16CD;RUNIC LETTER C;Lo;0;L;;;;;N;;;;; +16CE;RUNIC LETTER Z;Lo;0;L;;;;;N;;;;; +16CF;RUNIC LETTER TIWAZ TIR TYR T;Lo;0;L;;;;;N;;;;; +16D0;RUNIC LETTER SHORT-TWIG-TYR T;Lo;0;L;;;;;N;;;;; +16D1;RUNIC LETTER D;Lo;0;L;;;;;N;;;;; +16D2;RUNIC LETTER BERKANAN BEORC BJARKAN B;Lo;0;L;;;;;N;;;;; +16D3;RUNIC LETTER SHORT-TWIG-BJARKAN B;Lo;0;L;;;;;N;;;;; +16D4;RUNIC LETTER DOTTED-P;Lo;0;L;;;;;N;;;;; +16D5;RUNIC LETTER OPEN-P;Lo;0;L;;;;;N;;;;; +16D6;RUNIC LETTER EHWAZ EH E;Lo;0;L;;;;;N;;;;; +16D7;RUNIC LETTER MANNAZ MAN M;Lo;0;L;;;;;N;;;;; +16D8;RUNIC LETTER LONG-BRANCH-MADR M;Lo;0;L;;;;;N;;;;; +16D9;RUNIC LETTER SHORT-TWIG-MADR M;Lo;0;L;;;;;N;;;;; +16DA;RUNIC LETTER LAUKAZ LAGU LOGR L;Lo;0;L;;;;;N;;;;; +16DB;RUNIC LETTER DOTTED-L;Lo;0;L;;;;;N;;;;; +16DC;RUNIC LETTER INGWAZ;Lo;0;L;;;;;N;;;;; +16DD;RUNIC LETTER ING;Lo;0;L;;;;;N;;;;; +16DE;RUNIC LETTER DAGAZ DAEG D;Lo;0;L;;;;;N;;;;; +16DF;RUNIC LETTER OTHALAN ETHEL O;Lo;0;L;;;;;N;;;;; +16E0;RUNIC LETTER EAR;Lo;0;L;;;;;N;;;;; +16E1;RUNIC LETTER IOR;Lo;0;L;;;;;N;;;;; +16E2;RUNIC LETTER CWEORTH;Lo;0;L;;;;;N;;;;; +16E3;RUNIC LETTER CALC;Lo;0;L;;;;;N;;;;; +16E4;RUNIC LETTER CEALC;Lo;0;L;;;;;N;;;;; +16E5;RUNIC LETTER STAN;Lo;0;L;;;;;N;;;;; +16E6;RUNIC LETTER LONG-BRANCH-YR;Lo;0;L;;;;;N;;;;; +16E7;RUNIC LETTER SHORT-TWIG-YR;Lo;0;L;;;;;N;;;;; +16E8;RUNIC LETTER ICELANDIC-YR;Lo;0;L;;;;;N;;;;; +16E9;RUNIC LETTER Q;Lo;0;L;;;;;N;;;;; +16EA;RUNIC LETTER X;Lo;0;L;;;;;N;;;;; +16EB;RUNIC SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;; +16EC;RUNIC MULTIPLE PUNCTUATION;Po;0;L;;;;;N;;;;; +16ED;RUNIC CROSS PUNCTUATION;Po;0;L;;;;;N;;;;; +16EE;RUNIC ARLAUG SYMBOL;Nl;0;L;;;;17;N;;;;; +16EF;RUNIC TVIMADUR SYMBOL;Nl;0;L;;;;18;N;;;;; +16F0;RUNIC BELGTHOR SYMBOL;Nl;0;L;;;;19;N;;;;; +16F1;RUNIC LETTER K;Lo;0;L;;;;;N;;;;; +16F2;RUNIC LETTER SH;Lo;0;L;;;;;N;;;;; +16F3;RUNIC LETTER OO;Lo;0;L;;;;;N;;;;; +16F4;RUNIC LETTER FRANKS CASKET OS;Lo;0;L;;;;;N;;;;; +16F5;RUNIC LETTER FRANKS CASKET IS;Lo;0;L;;;;;N;;;;; +16F6;RUNIC LETTER FRANKS CASKET EH;Lo;0;L;;;;;N;;;;; +16F7;RUNIC LETTER FRANKS CASKET AC;Lo;0;L;;;;;N;;;;; +16F8;RUNIC LETTER FRANKS CASKET AESC;Lo;0;L;;;;;N;;;;; +1700;TAGALOG LETTER A;Lo;0;L;;;;;N;;;;; +1701;TAGALOG LETTER I;Lo;0;L;;;;;N;;;;; +1702;TAGALOG LETTER U;Lo;0;L;;;;;N;;;;; +1703;TAGALOG LETTER KA;Lo;0;L;;;;;N;;;;; +1704;TAGALOG LETTER GA;Lo;0;L;;;;;N;;;;; +1705;TAGALOG LETTER NGA;Lo;0;L;;;;;N;;;;; +1706;TAGALOG LETTER TA;Lo;0;L;;;;;N;;;;; +1707;TAGALOG LETTER DA;Lo;0;L;;;;;N;;;;; +1708;TAGALOG LETTER NA;Lo;0;L;;;;;N;;;;; +1709;TAGALOG LETTER PA;Lo;0;L;;;;;N;;;;; +170A;TAGALOG LETTER BA;Lo;0;L;;;;;N;;;;; +170B;TAGALOG LETTER MA;Lo;0;L;;;;;N;;;;; +170C;TAGALOG LETTER YA;Lo;0;L;;;;;N;;;;; +170E;TAGALOG LETTER LA;Lo;0;L;;;;;N;;;;; +170F;TAGALOG LETTER WA;Lo;0;L;;;;;N;;;;; +1710;TAGALOG LETTER SA;Lo;0;L;;;;;N;;;;; +1711;TAGALOG LETTER HA;Lo;0;L;;;;;N;;;;; +1712;TAGALOG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1713;TAGALOG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1714;TAGALOG SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +1720;HANUNOO LETTER A;Lo;0;L;;;;;N;;;;; +1721;HANUNOO LETTER I;Lo;0;L;;;;;N;;;;; +1722;HANUNOO LETTER U;Lo;0;L;;;;;N;;;;; +1723;HANUNOO LETTER KA;Lo;0;L;;;;;N;;;;; +1724;HANUNOO LETTER GA;Lo;0;L;;;;;N;;;;; +1725;HANUNOO LETTER NGA;Lo;0;L;;;;;N;;;;; +1726;HANUNOO LETTER TA;Lo;0;L;;;;;N;;;;; +1727;HANUNOO LETTER DA;Lo;0;L;;;;;N;;;;; +1728;HANUNOO LETTER NA;Lo;0;L;;;;;N;;;;; +1729;HANUNOO LETTER PA;Lo;0;L;;;;;N;;;;; +172A;HANUNOO LETTER BA;Lo;0;L;;;;;N;;;;; +172B;HANUNOO LETTER MA;Lo;0;L;;;;;N;;;;; +172C;HANUNOO LETTER YA;Lo;0;L;;;;;N;;;;; +172D;HANUNOO LETTER RA;Lo;0;L;;;;;N;;;;; +172E;HANUNOO LETTER LA;Lo;0;L;;;;;N;;;;; +172F;HANUNOO LETTER WA;Lo;0;L;;;;;N;;;;; +1730;HANUNOO LETTER SA;Lo;0;L;;;;;N;;;;; +1731;HANUNOO LETTER HA;Lo;0;L;;;;;N;;;;; +1732;HANUNOO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1733;HANUNOO VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1734;HANUNOO SIGN PAMUDPOD;Mn;9;NSM;;;;;N;;;;; +1735;PHILIPPINE SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;; +1736;PHILIPPINE DOUBLE PUNCTUATION;Po;0;L;;;;;N;;;;; +1740;BUHID LETTER A;Lo;0;L;;;;;N;;;;; +1741;BUHID LETTER I;Lo;0;L;;;;;N;;;;; +1742;BUHID LETTER U;Lo;0;L;;;;;N;;;;; +1743;BUHID LETTER KA;Lo;0;L;;;;;N;;;;; +1744;BUHID LETTER GA;Lo;0;L;;;;;N;;;;; +1745;BUHID LETTER NGA;Lo;0;L;;;;;N;;;;; +1746;BUHID LETTER TA;Lo;0;L;;;;;N;;;;; +1747;BUHID LETTER DA;Lo;0;L;;;;;N;;;;; +1748;BUHID LETTER NA;Lo;0;L;;;;;N;;;;; +1749;BUHID LETTER PA;Lo;0;L;;;;;N;;;;; +174A;BUHID LETTER BA;Lo;0;L;;;;;N;;;;; +174B;BUHID LETTER MA;Lo;0;L;;;;;N;;;;; +174C;BUHID LETTER YA;Lo;0;L;;;;;N;;;;; +174D;BUHID LETTER RA;Lo;0;L;;;;;N;;;;; +174E;BUHID LETTER LA;Lo;0;L;;;;;N;;;;; +174F;BUHID LETTER WA;Lo;0;L;;;;;N;;;;; +1750;BUHID LETTER SA;Lo;0;L;;;;;N;;;;; +1751;BUHID LETTER HA;Lo;0;L;;;;;N;;;;; +1752;BUHID VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1753;BUHID VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1760;TAGBANWA LETTER A;Lo;0;L;;;;;N;;;;; +1761;TAGBANWA LETTER I;Lo;0;L;;;;;N;;;;; +1762;TAGBANWA LETTER U;Lo;0;L;;;;;N;;;;; +1763;TAGBANWA LETTER KA;Lo;0;L;;;;;N;;;;; +1764;TAGBANWA LETTER GA;Lo;0;L;;;;;N;;;;; +1765;TAGBANWA LETTER NGA;Lo;0;L;;;;;N;;;;; +1766;TAGBANWA LETTER TA;Lo;0;L;;;;;N;;;;; +1767;TAGBANWA LETTER DA;Lo;0;L;;;;;N;;;;; +1768;TAGBANWA LETTER NA;Lo;0;L;;;;;N;;;;; +1769;TAGBANWA LETTER PA;Lo;0;L;;;;;N;;;;; +176A;TAGBANWA LETTER BA;Lo;0;L;;;;;N;;;;; +176B;TAGBANWA LETTER MA;Lo;0;L;;;;;N;;;;; +176C;TAGBANWA LETTER YA;Lo;0;L;;;;;N;;;;; +176E;TAGBANWA LETTER LA;Lo;0;L;;;;;N;;;;; +176F;TAGBANWA LETTER WA;Lo;0;L;;;;;N;;;;; +1770;TAGBANWA LETTER SA;Lo;0;L;;;;;N;;;;; +1772;TAGBANWA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1773;TAGBANWA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1780;KHMER LETTER KA;Lo;0;L;;;;;N;;;;; +1781;KHMER LETTER KHA;Lo;0;L;;;;;N;;;;; +1782;KHMER LETTER KO;Lo;0;L;;;;;N;;;;; +1783;KHMER LETTER KHO;Lo;0;L;;;;;N;;;;; +1784;KHMER LETTER NGO;Lo;0;L;;;;;N;;;;; +1785;KHMER LETTER CA;Lo;0;L;;;;;N;;;;; +1786;KHMER LETTER CHA;Lo;0;L;;;;;N;;;;; +1787;KHMER LETTER CO;Lo;0;L;;;;;N;;;;; +1788;KHMER LETTER CHO;Lo;0;L;;;;;N;;;;; +1789;KHMER LETTER NYO;Lo;0;L;;;;;N;;;;; +178A;KHMER LETTER DA;Lo;0;L;;;;;N;;;;; +178B;KHMER LETTER TTHA;Lo;0;L;;;;;N;;;;; +178C;KHMER LETTER DO;Lo;0;L;;;;;N;;;;; +178D;KHMER LETTER TTHO;Lo;0;L;;;;;N;;;;; +178E;KHMER LETTER NNO;Lo;0;L;;;;;N;;;;; +178F;KHMER LETTER TA;Lo;0;L;;;;;N;;;;; +1790;KHMER LETTER THA;Lo;0;L;;;;;N;;;;; +1791;KHMER LETTER TO;Lo;0;L;;;;;N;;;;; +1792;KHMER LETTER THO;Lo;0;L;;;;;N;;;;; +1793;KHMER LETTER NO;Lo;0;L;;;;;N;;;;; +1794;KHMER LETTER BA;Lo;0;L;;;;;N;;;;; +1795;KHMER LETTER PHA;Lo;0;L;;;;;N;;;;; +1796;KHMER LETTER PO;Lo;0;L;;;;;N;;;;; +1797;KHMER LETTER PHO;Lo;0;L;;;;;N;;;;; +1798;KHMER LETTER MO;Lo;0;L;;;;;N;;;;; +1799;KHMER LETTER YO;Lo;0;L;;;;;N;;;;; +179A;KHMER LETTER RO;Lo;0;L;;;;;N;;;;; +179B;KHMER LETTER LO;Lo;0;L;;;;;N;;;;; +179C;KHMER LETTER VO;Lo;0;L;;;;;N;;;;; +179D;KHMER LETTER SHA;Lo;0;L;;;;;N;;;;; +179E;KHMER LETTER SSO;Lo;0;L;;;;;N;;;;; +179F;KHMER LETTER SA;Lo;0;L;;;;;N;;;;; +17A0;KHMER LETTER HA;Lo;0;L;;;;;N;;;;; +17A1;KHMER LETTER LA;Lo;0;L;;;;;N;;;;; +17A2;KHMER LETTER QA;Lo;0;L;;;;;N;;;;; +17A3;KHMER INDEPENDENT VOWEL QAQ;Lo;0;L;;;;;N;;;;; +17A4;KHMER INDEPENDENT VOWEL QAA;Lo;0;L;;;;;N;;;;; +17A5;KHMER INDEPENDENT VOWEL QI;Lo;0;L;;;;;N;;;;; +17A6;KHMER INDEPENDENT VOWEL QII;Lo;0;L;;;;;N;;;;; +17A7;KHMER INDEPENDENT VOWEL QU;Lo;0;L;;;;;N;;;;; +17A8;KHMER INDEPENDENT VOWEL QUK;Lo;0;L;;;;;N;;;;; +17A9;KHMER INDEPENDENT VOWEL QUU;Lo;0;L;;;;;N;;;;; +17AA;KHMER INDEPENDENT VOWEL QUUV;Lo;0;L;;;;;N;;;;; +17AB;KHMER INDEPENDENT VOWEL RY;Lo;0;L;;;;;N;;;;; +17AC;KHMER INDEPENDENT VOWEL RYY;Lo;0;L;;;;;N;;;;; +17AD;KHMER INDEPENDENT VOWEL LY;Lo;0;L;;;;;N;;;;; +17AE;KHMER INDEPENDENT VOWEL LYY;Lo;0;L;;;;;N;;;;; +17AF;KHMER INDEPENDENT VOWEL QE;Lo;0;L;;;;;N;;;;; +17B0;KHMER INDEPENDENT VOWEL QAI;Lo;0;L;;;;;N;;;;; +17B1;KHMER INDEPENDENT VOWEL QOO TYPE ONE;Lo;0;L;;;;;N;;;;; +17B2;KHMER INDEPENDENT VOWEL QOO TYPE TWO;Lo;0;L;;;;;N;;;;; +17B3;KHMER INDEPENDENT VOWEL QAU;Lo;0;L;;;;;N;;;;; +17B4;KHMER VOWEL INHERENT AQ;Mn;0;NSM;;;;;N;;;;; +17B5;KHMER VOWEL INHERENT AA;Mn;0;NSM;;;;;N;;;;; +17B6;KHMER VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +17B7;KHMER VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +17B8;KHMER VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +17B9;KHMER VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;; +17BA;KHMER VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;; +17BB;KHMER VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +17BC;KHMER VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +17BD;KHMER VOWEL SIGN UA;Mn;0;NSM;;;;;N;;;;; +17BE;KHMER VOWEL SIGN OE;Mc;0;L;;;;;N;;;;; +17BF;KHMER VOWEL SIGN YA;Mc;0;L;;;;;N;;;;; +17C0;KHMER VOWEL SIGN IE;Mc;0;L;;;;;N;;;;; +17C1;KHMER VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +17C2;KHMER VOWEL SIGN AE;Mc;0;L;;;;;N;;;;; +17C3;KHMER VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +17C4;KHMER VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +17C5;KHMER VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +17C6;KHMER SIGN NIKAHIT;Mn;0;NSM;;;;;N;;;;; +17C7;KHMER SIGN REAHMUK;Mc;0;L;;;;;N;;;;; +17C8;KHMER SIGN YUUKALEAPINTU;Mc;0;L;;;;;N;;;;; +17C9;KHMER SIGN MUUSIKATOAN;Mn;0;NSM;;;;;N;;;;; +17CA;KHMER SIGN TRIISAP;Mn;0;NSM;;;;;N;;;;; +17CB;KHMER SIGN BANTOC;Mn;0;NSM;;;;;N;;;;; +17CC;KHMER SIGN ROBAT;Mn;0;NSM;;;;;N;;;;; +17CD;KHMER SIGN TOANDAKHIAT;Mn;0;NSM;;;;;N;;;;; +17CE;KHMER SIGN KAKABAT;Mn;0;NSM;;;;;N;;;;; +17CF;KHMER SIGN AHSDA;Mn;0;NSM;;;;;N;;;;; +17D0;KHMER SIGN SAMYOK SANNYA;Mn;0;NSM;;;;;N;;;;; +17D1;KHMER SIGN VIRIAM;Mn;0;NSM;;;;;N;;;;; +17D2;KHMER SIGN COENG;Mn;9;NSM;;;;;N;;;;; +17D3;KHMER SIGN BATHAMASAT;Mn;0;NSM;;;;;N;;;;; +17D4;KHMER SIGN KHAN;Po;0;L;;;;;N;;;;; +17D5;KHMER SIGN BARIYOOSAN;Po;0;L;;;;;N;;;;; +17D6;KHMER SIGN CAMNUC PII KUUH;Po;0;L;;;;;N;;;;; +17D7;KHMER SIGN LEK TOO;Lm;0;L;;;;;N;;;;; +17D8;KHMER SIGN BEYYAL;Po;0;L;;;;;N;;;;; +17D9;KHMER SIGN PHNAEK MUAN;Po;0;L;;;;;N;;;;; +17DA;KHMER SIGN KOOMUUT;Po;0;L;;;;;N;;;;; +17DB;KHMER CURRENCY SYMBOL RIEL;Sc;0;ET;;;;;N;;;;; +17DC;KHMER SIGN AVAKRAHASANYA;Lo;0;L;;;;;N;;;;; +17DD;KHMER SIGN ATTHACAN;Mn;230;NSM;;;;;N;;;;; +17E0;KHMER DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +17E1;KHMER DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +17E2;KHMER DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +17E3;KHMER DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +17E4;KHMER DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +17E5;KHMER DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +17E6;KHMER DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +17E7;KHMER DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +17E8;KHMER DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +17E9;KHMER DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +17F0;KHMER SYMBOL LEK ATTAK SON;No;0;ON;;;;0;N;;;;; +17F1;KHMER SYMBOL LEK ATTAK MUOY;No;0;ON;;;;1;N;;;;; +17F2;KHMER SYMBOL LEK ATTAK PII;No;0;ON;;;;2;N;;;;; +17F3;KHMER SYMBOL LEK ATTAK BEI;No;0;ON;;;;3;N;;;;; +17F4;KHMER SYMBOL LEK ATTAK BUON;No;0;ON;;;;4;N;;;;; +17F5;KHMER SYMBOL LEK ATTAK PRAM;No;0;ON;;;;5;N;;;;; +17F6;KHMER SYMBOL LEK ATTAK PRAM-MUOY;No;0;ON;;;;6;N;;;;; +17F7;KHMER SYMBOL LEK ATTAK PRAM-PII;No;0;ON;;;;7;N;;;;; +17F8;KHMER SYMBOL LEK ATTAK PRAM-BEI;No;0;ON;;;;8;N;;;;; +17F9;KHMER SYMBOL LEK ATTAK PRAM-BUON;No;0;ON;;;;9;N;;;;; +1800;MONGOLIAN BIRGA;Po;0;ON;;;;;N;;;;; +1801;MONGOLIAN ELLIPSIS;Po;0;ON;;;;;N;;;;; +1802;MONGOLIAN COMMA;Po;0;ON;;;;;N;;;;; +1803;MONGOLIAN FULL STOP;Po;0;ON;;;;;N;;;;; +1804;MONGOLIAN COLON;Po;0;ON;;;;;N;;;;; +1805;MONGOLIAN FOUR DOTS;Po;0;ON;;;;;N;;;;; +1806;MONGOLIAN TODO SOFT HYPHEN;Pd;0;ON;;;;;N;;;;; +1807;MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER;Po;0;ON;;;;;N;;;;; +1808;MONGOLIAN MANCHU COMMA;Po;0;ON;;;;;N;;;;; +1809;MONGOLIAN MANCHU FULL STOP;Po;0;ON;;;;;N;;;;; +180A;MONGOLIAN NIRUGU;Po;0;ON;;;;;N;;;;; +180B;MONGOLIAN FREE VARIATION SELECTOR ONE;Mn;0;NSM;;;;;N;;;;; +180C;MONGOLIAN FREE VARIATION SELECTOR TWO;Mn;0;NSM;;;;;N;;;;; +180D;MONGOLIAN FREE VARIATION SELECTOR THREE;Mn;0;NSM;;;;;N;;;;; +180E;MONGOLIAN VOWEL SEPARATOR;Cf;0;BN;;;;;N;;;;; +1810;MONGOLIAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1811;MONGOLIAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1812;MONGOLIAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1813;MONGOLIAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1814;MONGOLIAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1815;MONGOLIAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1816;MONGOLIAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1817;MONGOLIAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1818;MONGOLIAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1819;MONGOLIAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1820;MONGOLIAN LETTER A;Lo;0;L;;;;;N;;;;; +1821;MONGOLIAN LETTER E;Lo;0;L;;;;;N;;;;; +1822;MONGOLIAN LETTER I;Lo;0;L;;;;;N;;;;; +1823;MONGOLIAN LETTER O;Lo;0;L;;;;;N;;;;; +1824;MONGOLIAN LETTER U;Lo;0;L;;;;;N;;;;; +1825;MONGOLIAN LETTER OE;Lo;0;L;;;;;N;;;;; +1826;MONGOLIAN LETTER UE;Lo;0;L;;;;;N;;;;; +1827;MONGOLIAN LETTER EE;Lo;0;L;;;;;N;;;;; +1828;MONGOLIAN LETTER NA;Lo;0;L;;;;;N;;;;; +1829;MONGOLIAN LETTER ANG;Lo;0;L;;;;;N;;;;; +182A;MONGOLIAN LETTER BA;Lo;0;L;;;;;N;;;;; +182B;MONGOLIAN LETTER PA;Lo;0;L;;;;;N;;;;; +182C;MONGOLIAN LETTER QA;Lo;0;L;;;;;N;;;;; +182D;MONGOLIAN LETTER GA;Lo;0;L;;;;;N;;;;; +182E;MONGOLIAN LETTER MA;Lo;0;L;;;;;N;;;;; +182F;MONGOLIAN LETTER LA;Lo;0;L;;;;;N;;;;; +1830;MONGOLIAN LETTER SA;Lo;0;L;;;;;N;;;;; +1831;MONGOLIAN LETTER SHA;Lo;0;L;;;;;N;;;;; +1832;MONGOLIAN LETTER TA;Lo;0;L;;;;;N;;;;; +1833;MONGOLIAN LETTER DA;Lo;0;L;;;;;N;;;;; +1834;MONGOLIAN LETTER CHA;Lo;0;L;;;;;N;;;;; +1835;MONGOLIAN LETTER JA;Lo;0;L;;;;;N;;;;; +1836;MONGOLIAN LETTER YA;Lo;0;L;;;;;N;;;;; +1837;MONGOLIAN LETTER RA;Lo;0;L;;;;;N;;;;; +1838;MONGOLIAN LETTER WA;Lo;0;L;;;;;N;;;;; +1839;MONGOLIAN LETTER FA;Lo;0;L;;;;;N;;;;; +183A;MONGOLIAN LETTER KA;Lo;0;L;;;;;N;;;;; +183B;MONGOLIAN LETTER KHA;Lo;0;L;;;;;N;;;;; +183C;MONGOLIAN LETTER TSA;Lo;0;L;;;;;N;;;;; +183D;MONGOLIAN LETTER ZA;Lo;0;L;;;;;N;;;;; +183E;MONGOLIAN LETTER HAA;Lo;0;L;;;;;N;;;;; +183F;MONGOLIAN LETTER ZRA;Lo;0;L;;;;;N;;;;; +1840;MONGOLIAN LETTER LHA;Lo;0;L;;;;;N;;;;; +1841;MONGOLIAN LETTER ZHI;Lo;0;L;;;;;N;;;;; +1842;MONGOLIAN LETTER CHI;Lo;0;L;;;;;N;;;;; +1843;MONGOLIAN LETTER TODO LONG VOWEL SIGN;Lm;0;L;;;;;N;;;;; +1844;MONGOLIAN LETTER TODO E;Lo;0;L;;;;;N;;;;; +1845;MONGOLIAN LETTER TODO I;Lo;0;L;;;;;N;;;;; +1846;MONGOLIAN LETTER TODO O;Lo;0;L;;;;;N;;;;; +1847;MONGOLIAN LETTER TODO U;Lo;0;L;;;;;N;;;;; +1848;MONGOLIAN LETTER TODO OE;Lo;0;L;;;;;N;;;;; +1849;MONGOLIAN LETTER TODO UE;Lo;0;L;;;;;N;;;;; +184A;MONGOLIAN LETTER TODO ANG;Lo;0;L;;;;;N;;;;; +184B;MONGOLIAN LETTER TODO BA;Lo;0;L;;;;;N;;;;; +184C;MONGOLIAN LETTER TODO PA;Lo;0;L;;;;;N;;;;; +184D;MONGOLIAN LETTER TODO QA;Lo;0;L;;;;;N;;;;; +184E;MONGOLIAN LETTER TODO GA;Lo;0;L;;;;;N;;;;; +184F;MONGOLIAN LETTER TODO MA;Lo;0;L;;;;;N;;;;; +1850;MONGOLIAN LETTER TODO TA;Lo;0;L;;;;;N;;;;; +1851;MONGOLIAN LETTER TODO DA;Lo;0;L;;;;;N;;;;; +1852;MONGOLIAN LETTER TODO CHA;Lo;0;L;;;;;N;;;;; +1853;MONGOLIAN LETTER TODO JA;Lo;0;L;;;;;N;;;;; +1854;MONGOLIAN LETTER TODO TSA;Lo;0;L;;;;;N;;;;; +1855;MONGOLIAN LETTER TODO YA;Lo;0;L;;;;;N;;;;; +1856;MONGOLIAN LETTER TODO WA;Lo;0;L;;;;;N;;;;; +1857;MONGOLIAN LETTER TODO KA;Lo;0;L;;;;;N;;;;; +1858;MONGOLIAN LETTER TODO GAA;Lo;0;L;;;;;N;;;;; +1859;MONGOLIAN LETTER TODO HAA;Lo;0;L;;;;;N;;;;; +185A;MONGOLIAN LETTER TODO JIA;Lo;0;L;;;;;N;;;;; +185B;MONGOLIAN LETTER TODO NIA;Lo;0;L;;;;;N;;;;; +185C;MONGOLIAN LETTER TODO DZA;Lo;0;L;;;;;N;;;;; +185D;MONGOLIAN LETTER SIBE E;Lo;0;L;;;;;N;;;;; +185E;MONGOLIAN LETTER SIBE I;Lo;0;L;;;;;N;;;;; +185F;MONGOLIAN LETTER SIBE IY;Lo;0;L;;;;;N;;;;; +1860;MONGOLIAN LETTER SIBE UE;Lo;0;L;;;;;N;;;;; +1861;MONGOLIAN LETTER SIBE U;Lo;0;L;;;;;N;;;;; +1862;MONGOLIAN LETTER SIBE ANG;Lo;0;L;;;;;N;;;;; +1863;MONGOLIAN LETTER SIBE KA;Lo;0;L;;;;;N;;;;; +1864;MONGOLIAN LETTER SIBE GA;Lo;0;L;;;;;N;;;;; +1865;MONGOLIAN LETTER SIBE HA;Lo;0;L;;;;;N;;;;; +1866;MONGOLIAN LETTER SIBE PA;Lo;0;L;;;;;N;;;;; +1867;MONGOLIAN LETTER SIBE SHA;Lo;0;L;;;;;N;;;;; +1868;MONGOLIAN LETTER SIBE TA;Lo;0;L;;;;;N;;;;; +1869;MONGOLIAN LETTER SIBE DA;Lo;0;L;;;;;N;;;;; +186A;MONGOLIAN LETTER SIBE JA;Lo;0;L;;;;;N;;;;; +186B;MONGOLIAN LETTER SIBE FA;Lo;0;L;;;;;N;;;;; +186C;MONGOLIAN LETTER SIBE GAA;Lo;0;L;;;;;N;;;;; +186D;MONGOLIAN LETTER SIBE HAA;Lo;0;L;;;;;N;;;;; +186E;MONGOLIAN LETTER SIBE TSA;Lo;0;L;;;;;N;;;;; +186F;MONGOLIAN LETTER SIBE ZA;Lo;0;L;;;;;N;;;;; +1870;MONGOLIAN LETTER SIBE RAA;Lo;0;L;;;;;N;;;;; +1871;MONGOLIAN LETTER SIBE CHA;Lo;0;L;;;;;N;;;;; +1872;MONGOLIAN LETTER SIBE ZHA;Lo;0;L;;;;;N;;;;; +1873;MONGOLIAN LETTER MANCHU I;Lo;0;L;;;;;N;;;;; +1874;MONGOLIAN LETTER MANCHU KA;Lo;0;L;;;;;N;;;;; +1875;MONGOLIAN LETTER MANCHU RA;Lo;0;L;;;;;N;;;;; +1876;MONGOLIAN LETTER MANCHU FA;Lo;0;L;;;;;N;;;;; +1877;MONGOLIAN LETTER MANCHU ZHA;Lo;0;L;;;;;N;;;;; +1878;MONGOLIAN LETTER CHA WITH TWO DOTS;Lo;0;L;;;;;N;;;;; +1880;MONGOLIAN LETTER ALI GALI ANUSVARA ONE;Lo;0;L;;;;;N;;;;; +1881;MONGOLIAN LETTER ALI GALI VISARGA ONE;Lo;0;L;;;;;N;;;;; +1882;MONGOLIAN LETTER ALI GALI DAMARU;Lo;0;L;;;;;N;;;;; +1883;MONGOLIAN LETTER ALI GALI UBADAMA;Lo;0;L;;;;;N;;;;; +1884;MONGOLIAN LETTER ALI GALI INVERTED UBADAMA;Lo;0;L;;;;;N;;;;; +1885;MONGOLIAN LETTER ALI GALI BALUDA;Mn;0;NSM;;;;;N;;;;; +1886;MONGOLIAN LETTER ALI GALI THREE BALUDA;Mn;0;NSM;;;;;N;;;;; +1887;MONGOLIAN LETTER ALI GALI A;Lo;0;L;;;;;N;;;;; +1888;MONGOLIAN LETTER ALI GALI I;Lo;0;L;;;;;N;;;;; +1889;MONGOLIAN LETTER ALI GALI KA;Lo;0;L;;;;;N;;;;; +188A;MONGOLIAN LETTER ALI GALI NGA;Lo;0;L;;;;;N;;;;; +188B;MONGOLIAN LETTER ALI GALI CA;Lo;0;L;;;;;N;;;;; +188C;MONGOLIAN LETTER ALI GALI TTA;Lo;0;L;;;;;N;;;;; +188D;MONGOLIAN LETTER ALI GALI TTHA;Lo;0;L;;;;;N;;;;; +188E;MONGOLIAN LETTER ALI GALI DDA;Lo;0;L;;;;;N;;;;; +188F;MONGOLIAN LETTER ALI GALI NNA;Lo;0;L;;;;;N;;;;; +1890;MONGOLIAN LETTER ALI GALI TA;Lo;0;L;;;;;N;;;;; +1891;MONGOLIAN LETTER ALI GALI DA;Lo;0;L;;;;;N;;;;; +1892;MONGOLIAN LETTER ALI GALI PA;Lo;0;L;;;;;N;;;;; +1893;MONGOLIAN LETTER ALI GALI PHA;Lo;0;L;;;;;N;;;;; +1894;MONGOLIAN LETTER ALI GALI SSA;Lo;0;L;;;;;N;;;;; +1895;MONGOLIAN LETTER ALI GALI ZHA;Lo;0;L;;;;;N;;;;; +1896;MONGOLIAN LETTER ALI GALI ZA;Lo;0;L;;;;;N;;;;; +1897;MONGOLIAN LETTER ALI GALI AH;Lo;0;L;;;;;N;;;;; +1898;MONGOLIAN LETTER TODO ALI GALI TA;Lo;0;L;;;;;N;;;;; +1899;MONGOLIAN LETTER TODO ALI GALI ZHA;Lo;0;L;;;;;N;;;;; +189A;MONGOLIAN LETTER MANCHU ALI GALI GHA;Lo;0;L;;;;;N;;;;; +189B;MONGOLIAN LETTER MANCHU ALI GALI NGA;Lo;0;L;;;;;N;;;;; +189C;MONGOLIAN LETTER MANCHU ALI GALI CA;Lo;0;L;;;;;N;;;;; +189D;MONGOLIAN LETTER MANCHU ALI GALI JHA;Lo;0;L;;;;;N;;;;; +189E;MONGOLIAN LETTER MANCHU ALI GALI TTA;Lo;0;L;;;;;N;;;;; +189F;MONGOLIAN LETTER MANCHU ALI GALI DDHA;Lo;0;L;;;;;N;;;;; +18A0;MONGOLIAN LETTER MANCHU ALI GALI TA;Lo;0;L;;;;;N;;;;; +18A1;MONGOLIAN LETTER MANCHU ALI GALI DHA;Lo;0;L;;;;;N;;;;; +18A2;MONGOLIAN LETTER MANCHU ALI GALI SSA;Lo;0;L;;;;;N;;;;; +18A3;MONGOLIAN LETTER MANCHU ALI GALI CYA;Lo;0;L;;;;;N;;;;; +18A4;MONGOLIAN LETTER MANCHU ALI GALI ZHA;Lo;0;L;;;;;N;;;;; +18A5;MONGOLIAN LETTER MANCHU ALI GALI ZA;Lo;0;L;;;;;N;;;;; +18A6;MONGOLIAN LETTER ALI GALI HALF U;Lo;0;L;;;;;N;;;;; +18A7;MONGOLIAN LETTER ALI GALI HALF YA;Lo;0;L;;;;;N;;;;; +18A8;MONGOLIAN LETTER MANCHU ALI GALI BHA;Lo;0;L;;;;;N;;;;; +18A9;MONGOLIAN LETTER ALI GALI DAGALGA;Mn;228;NSM;;;;;N;;;;; +18AA;MONGOLIAN LETTER MANCHU ALI GALI LHA;Lo;0;L;;;;;N;;;;; +18B0;CANADIAN SYLLABICS OY;Lo;0;L;;;;;N;;;;; +18B1;CANADIAN SYLLABICS AY;Lo;0;L;;;;;N;;;;; +18B2;CANADIAN SYLLABICS AAY;Lo;0;L;;;;;N;;;;; +18B3;CANADIAN SYLLABICS WAY;Lo;0;L;;;;;N;;;;; +18B4;CANADIAN SYLLABICS POY;Lo;0;L;;;;;N;;;;; +18B5;CANADIAN SYLLABICS PAY;Lo;0;L;;;;;N;;;;; +18B6;CANADIAN SYLLABICS PWOY;Lo;0;L;;;;;N;;;;; +18B7;CANADIAN SYLLABICS TAY;Lo;0;L;;;;;N;;;;; +18B8;CANADIAN SYLLABICS KAY;Lo;0;L;;;;;N;;;;; +18B9;CANADIAN SYLLABICS KWAY;Lo;0;L;;;;;N;;;;; +18BA;CANADIAN SYLLABICS MAY;Lo;0;L;;;;;N;;;;; +18BB;CANADIAN SYLLABICS NOY;Lo;0;L;;;;;N;;;;; +18BC;CANADIAN SYLLABICS NAY;Lo;0;L;;;;;N;;;;; +18BD;CANADIAN SYLLABICS LAY;Lo;0;L;;;;;N;;;;; +18BE;CANADIAN SYLLABICS SOY;Lo;0;L;;;;;N;;;;; +18BF;CANADIAN SYLLABICS SAY;Lo;0;L;;;;;N;;;;; +18C0;CANADIAN SYLLABICS SHOY;Lo;0;L;;;;;N;;;;; +18C1;CANADIAN SYLLABICS SHAY;Lo;0;L;;;;;N;;;;; +18C2;CANADIAN SYLLABICS SHWOY;Lo;0;L;;;;;N;;;;; +18C3;CANADIAN SYLLABICS YOY;Lo;0;L;;;;;N;;;;; +18C4;CANADIAN SYLLABICS YAY;Lo;0;L;;;;;N;;;;; +18C5;CANADIAN SYLLABICS RAY;Lo;0;L;;;;;N;;;;; +18C6;CANADIAN SYLLABICS NWI;Lo;0;L;;;;;N;;;;; +18C7;CANADIAN SYLLABICS OJIBWAY NWI;Lo;0;L;;;;;N;;;;; +18C8;CANADIAN SYLLABICS NWII;Lo;0;L;;;;;N;;;;; +18C9;CANADIAN SYLLABICS OJIBWAY NWII;Lo;0;L;;;;;N;;;;; +18CA;CANADIAN SYLLABICS NWO;Lo;0;L;;;;;N;;;;; +18CB;CANADIAN SYLLABICS OJIBWAY NWO;Lo;0;L;;;;;N;;;;; +18CC;CANADIAN SYLLABICS NWOO;Lo;0;L;;;;;N;;;;; +18CD;CANADIAN SYLLABICS OJIBWAY NWOO;Lo;0;L;;;;;N;;;;; +18CE;CANADIAN SYLLABICS RWEE;Lo;0;L;;;;;N;;;;; +18CF;CANADIAN SYLLABICS RWI;Lo;0;L;;;;;N;;;;; +18D0;CANADIAN SYLLABICS RWII;Lo;0;L;;;;;N;;;;; +18D1;CANADIAN SYLLABICS RWO;Lo;0;L;;;;;N;;;;; +18D2;CANADIAN SYLLABICS RWOO;Lo;0;L;;;;;N;;;;; +18D3;CANADIAN SYLLABICS RWA;Lo;0;L;;;;;N;;;;; +18D4;CANADIAN SYLLABICS OJIBWAY P;Lo;0;L;;;;;N;;;;; +18D5;CANADIAN SYLLABICS OJIBWAY T;Lo;0;L;;;;;N;;;;; +18D6;CANADIAN SYLLABICS OJIBWAY K;Lo;0;L;;;;;N;;;;; +18D7;CANADIAN SYLLABICS OJIBWAY C;Lo;0;L;;;;;N;;;;; +18D8;CANADIAN SYLLABICS OJIBWAY M;Lo;0;L;;;;;N;;;;; +18D9;CANADIAN SYLLABICS OJIBWAY N;Lo;0;L;;;;;N;;;;; +18DA;CANADIAN SYLLABICS OJIBWAY S;Lo;0;L;;;;;N;;;;; +18DB;CANADIAN SYLLABICS OJIBWAY SH;Lo;0;L;;;;;N;;;;; +18DC;CANADIAN SYLLABICS EASTERN W;Lo;0;L;;;;;N;;;;; +18DD;CANADIAN SYLLABICS WESTERN W;Lo;0;L;;;;;N;;;;; +18DE;CANADIAN SYLLABICS FINAL SMALL RING;Lo;0;L;;;;;N;;;;; +18DF;CANADIAN SYLLABICS FINAL RAISED DOT;Lo;0;L;;;;;N;;;;; +18E0;CANADIAN SYLLABICS R-CREE RWE;Lo;0;L;;;;;N;;;;; +18E1;CANADIAN SYLLABICS WEST-CREE LOO;Lo;0;L;;;;;N;;;;; +18E2;CANADIAN SYLLABICS WEST-CREE LAA;Lo;0;L;;;;;N;;;;; +18E3;CANADIAN SYLLABICS THWE;Lo;0;L;;;;;N;;;;; +18E4;CANADIAN SYLLABICS THWA;Lo;0;L;;;;;N;;;;; +18E5;CANADIAN SYLLABICS TTHWE;Lo;0;L;;;;;N;;;;; +18E6;CANADIAN SYLLABICS TTHOO;Lo;0;L;;;;;N;;;;; +18E7;CANADIAN SYLLABICS TTHAA;Lo;0;L;;;;;N;;;;; +18E8;CANADIAN SYLLABICS TLHWE;Lo;0;L;;;;;N;;;;; +18E9;CANADIAN SYLLABICS TLHOO;Lo;0;L;;;;;N;;;;; +18EA;CANADIAN SYLLABICS SAYISI SHWE;Lo;0;L;;;;;N;;;;; +18EB;CANADIAN SYLLABICS SAYISI SHOO;Lo;0;L;;;;;N;;;;; +18EC;CANADIAN SYLLABICS SAYISI HOO;Lo;0;L;;;;;N;;;;; +18ED;CANADIAN SYLLABICS CARRIER GWU;Lo;0;L;;;;;N;;;;; +18EE;CANADIAN SYLLABICS CARRIER DENE GEE;Lo;0;L;;;;;N;;;;; +18EF;CANADIAN SYLLABICS CARRIER GAA;Lo;0;L;;;;;N;;;;; +18F0;CANADIAN SYLLABICS CARRIER GWA;Lo;0;L;;;;;N;;;;; +18F1;CANADIAN SYLLABICS SAYISI JUU;Lo;0;L;;;;;N;;;;; +18F2;CANADIAN SYLLABICS CARRIER JWA;Lo;0;L;;;;;N;;;;; +18F3;CANADIAN SYLLABICS BEAVER DENE L;Lo;0;L;;;;;N;;;;; +18F4;CANADIAN SYLLABICS BEAVER DENE R;Lo;0;L;;;;;N;;;;; +18F5;CANADIAN SYLLABICS CARRIER DENTAL S;Lo;0;L;;;;;N;;;;; +1900;LIMBU VOWEL-CARRIER LETTER;Lo;0;L;;;;;N;;;;; +1901;LIMBU LETTER KA;Lo;0;L;;;;;N;;;;; +1902;LIMBU LETTER KHA;Lo;0;L;;;;;N;;;;; +1903;LIMBU LETTER GA;Lo;0;L;;;;;N;;;;; +1904;LIMBU LETTER GHA;Lo;0;L;;;;;N;;;;; +1905;LIMBU LETTER NGA;Lo;0;L;;;;;N;;;;; +1906;LIMBU LETTER CA;Lo;0;L;;;;;N;;;;; +1907;LIMBU LETTER CHA;Lo;0;L;;;;;N;;;;; +1908;LIMBU LETTER JA;Lo;0;L;;;;;N;;;;; +1909;LIMBU LETTER JHA;Lo;0;L;;;;;N;;;;; +190A;LIMBU LETTER YAN;Lo;0;L;;;;;N;;;;; +190B;LIMBU LETTER TA;Lo;0;L;;;;;N;;;;; +190C;LIMBU LETTER THA;Lo;0;L;;;;;N;;;;; +190D;LIMBU LETTER DA;Lo;0;L;;;;;N;;;;; +190E;LIMBU LETTER DHA;Lo;0;L;;;;;N;;;;; +190F;LIMBU LETTER NA;Lo;0;L;;;;;N;;;;; +1910;LIMBU LETTER PA;Lo;0;L;;;;;N;;;;; +1911;LIMBU LETTER PHA;Lo;0;L;;;;;N;;;;; +1912;LIMBU LETTER BA;Lo;0;L;;;;;N;;;;; +1913;LIMBU LETTER BHA;Lo;0;L;;;;;N;;;;; +1914;LIMBU LETTER MA;Lo;0;L;;;;;N;;;;; +1915;LIMBU LETTER YA;Lo;0;L;;;;;N;;;;; +1916;LIMBU LETTER RA;Lo;0;L;;;;;N;;;;; +1917;LIMBU LETTER LA;Lo;0;L;;;;;N;;;;; +1918;LIMBU LETTER WA;Lo;0;L;;;;;N;;;;; +1919;LIMBU LETTER SHA;Lo;0;L;;;;;N;;;;; +191A;LIMBU LETTER SSA;Lo;0;L;;;;;N;;;;; +191B;LIMBU LETTER SA;Lo;0;L;;;;;N;;;;; +191C;LIMBU LETTER HA;Lo;0;L;;;;;N;;;;; +191D;LIMBU LETTER GYAN;Lo;0;L;;;;;N;;;;; +191E;LIMBU LETTER TRA;Lo;0;L;;;;;N;;;;; +1920;LIMBU VOWEL SIGN A;Mn;0;NSM;;;;;N;;;;; +1921;LIMBU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1922;LIMBU VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1923;LIMBU VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; +1924;LIMBU VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +1925;LIMBU VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +1926;LIMBU VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +1927;LIMBU VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +1928;LIMBU VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +1929;LIMBU SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;; +192A;LIMBU SUBJOINED LETTER RA;Mc;0;L;;;;;N;;;;; +192B;LIMBU SUBJOINED LETTER WA;Mc;0;L;;;;;N;;;;; +1930;LIMBU SMALL LETTER KA;Mc;0;L;;;;;N;;;;; +1931;LIMBU SMALL LETTER NGA;Mc;0;L;;;;;N;;;;; +1932;LIMBU SMALL LETTER ANUSVARA;Mn;0;NSM;;;;;N;;;;; +1933;LIMBU SMALL LETTER TA;Mc;0;L;;;;;N;;;;; +1934;LIMBU SMALL LETTER NA;Mc;0;L;;;;;N;;;;; +1935;LIMBU SMALL LETTER PA;Mc;0;L;;;;;N;;;;; +1936;LIMBU SMALL LETTER MA;Mc;0;L;;;;;N;;;;; +1937;LIMBU SMALL LETTER RA;Mc;0;L;;;;;N;;;;; +1938;LIMBU SMALL LETTER LA;Mc;0;L;;;;;N;;;;; +1939;LIMBU SIGN MUKPHRENG;Mn;222;NSM;;;;;N;;;;; +193A;LIMBU SIGN KEMPHRENG;Mn;230;NSM;;;;;N;;;;; +193B;LIMBU SIGN SA-I;Mn;220;NSM;;;;;N;;;;; +1940;LIMBU SIGN LOO;So;0;ON;;;;;N;;;;; +1944;LIMBU EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; +1945;LIMBU QUESTION MARK;Po;0;ON;;;;;N;;;;; +1946;LIMBU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1947;LIMBU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1948;LIMBU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1949;LIMBU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +194A;LIMBU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +194B;LIMBU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +194C;LIMBU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +194D;LIMBU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +194E;LIMBU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +194F;LIMBU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1950;TAI LE LETTER KA;Lo;0;L;;;;;N;;;;; +1951;TAI LE LETTER XA;Lo;0;L;;;;;N;;;;; +1952;TAI LE LETTER NGA;Lo;0;L;;;;;N;;;;; +1953;TAI LE LETTER TSA;Lo;0;L;;;;;N;;;;; +1954;TAI LE LETTER SA;Lo;0;L;;;;;N;;;;; +1955;TAI LE LETTER YA;Lo;0;L;;;;;N;;;;; +1956;TAI LE LETTER TA;Lo;0;L;;;;;N;;;;; +1957;TAI LE LETTER THA;Lo;0;L;;;;;N;;;;; +1958;TAI LE LETTER LA;Lo;0;L;;;;;N;;;;; +1959;TAI LE LETTER PA;Lo;0;L;;;;;N;;;;; +195A;TAI LE LETTER PHA;Lo;0;L;;;;;N;;;;; +195B;TAI LE LETTER MA;Lo;0;L;;;;;N;;;;; +195C;TAI LE LETTER FA;Lo;0;L;;;;;N;;;;; +195D;TAI LE LETTER VA;Lo;0;L;;;;;N;;;;; +195E;TAI LE LETTER HA;Lo;0;L;;;;;N;;;;; +195F;TAI LE LETTER QA;Lo;0;L;;;;;N;;;;; +1960;TAI LE LETTER KHA;Lo;0;L;;;;;N;;;;; +1961;TAI LE LETTER TSHA;Lo;0;L;;;;;N;;;;; +1962;TAI LE LETTER NA;Lo;0;L;;;;;N;;;;; +1963;TAI LE LETTER A;Lo;0;L;;;;;N;;;;; +1964;TAI LE LETTER I;Lo;0;L;;;;;N;;;;; +1965;TAI LE LETTER EE;Lo;0;L;;;;;N;;;;; +1966;TAI LE LETTER EH;Lo;0;L;;;;;N;;;;; +1967;TAI LE LETTER U;Lo;0;L;;;;;N;;;;; +1968;TAI LE LETTER OO;Lo;0;L;;;;;N;;;;; +1969;TAI LE LETTER O;Lo;0;L;;;;;N;;;;; +196A;TAI LE LETTER UE;Lo;0;L;;;;;N;;;;; +196B;TAI LE LETTER E;Lo;0;L;;;;;N;;;;; +196C;TAI LE LETTER AUE;Lo;0;L;;;;;N;;;;; +196D;TAI LE LETTER AI;Lo;0;L;;;;;N;;;;; +1970;TAI LE LETTER TONE-2;Lo;0;L;;;;;N;;;;; +1971;TAI LE LETTER TONE-3;Lo;0;L;;;;;N;;;;; +1972;TAI LE LETTER TONE-4;Lo;0;L;;;;;N;;;;; +1973;TAI LE LETTER TONE-5;Lo;0;L;;;;;N;;;;; +1974;TAI LE LETTER TONE-6;Lo;0;L;;;;;N;;;;; +1980;NEW TAI LUE LETTER HIGH QA;Lo;0;L;;;;;N;;;;; +1981;NEW TAI LUE LETTER LOW QA;Lo;0;L;;;;;N;;;;; +1982;NEW TAI LUE LETTER HIGH KA;Lo;0;L;;;;;N;;;;; +1983;NEW TAI LUE LETTER HIGH XA;Lo;0;L;;;;;N;;;;; +1984;NEW TAI LUE LETTER HIGH NGA;Lo;0;L;;;;;N;;;;; +1985;NEW TAI LUE LETTER LOW KA;Lo;0;L;;;;;N;;;;; +1986;NEW TAI LUE LETTER LOW XA;Lo;0;L;;;;;N;;;;; +1987;NEW TAI LUE LETTER LOW NGA;Lo;0;L;;;;;N;;;;; +1988;NEW TAI LUE LETTER HIGH TSA;Lo;0;L;;;;;N;;;;; +1989;NEW TAI LUE LETTER HIGH SA;Lo;0;L;;;;;N;;;;; +198A;NEW TAI LUE LETTER HIGH YA;Lo;0;L;;;;;N;;;;; +198B;NEW TAI LUE LETTER LOW TSA;Lo;0;L;;;;;N;;;;; +198C;NEW TAI LUE LETTER LOW SA;Lo;0;L;;;;;N;;;;; +198D;NEW TAI LUE LETTER LOW YA;Lo;0;L;;;;;N;;;;; +198E;NEW TAI LUE LETTER HIGH TA;Lo;0;L;;;;;N;;;;; +198F;NEW TAI LUE LETTER HIGH THA;Lo;0;L;;;;;N;;;;; +1990;NEW TAI LUE LETTER HIGH NA;Lo;0;L;;;;;N;;;;; +1991;NEW TAI LUE LETTER LOW TA;Lo;0;L;;;;;N;;;;; +1992;NEW TAI LUE LETTER LOW THA;Lo;0;L;;;;;N;;;;; +1993;NEW TAI LUE LETTER LOW NA;Lo;0;L;;;;;N;;;;; +1994;NEW TAI LUE LETTER HIGH PA;Lo;0;L;;;;;N;;;;; +1995;NEW TAI LUE LETTER HIGH PHA;Lo;0;L;;;;;N;;;;; +1996;NEW TAI LUE LETTER HIGH MA;Lo;0;L;;;;;N;;;;; +1997;NEW TAI LUE LETTER LOW PA;Lo;0;L;;;;;N;;;;; +1998;NEW TAI LUE LETTER LOW PHA;Lo;0;L;;;;;N;;;;; +1999;NEW TAI LUE LETTER LOW MA;Lo;0;L;;;;;N;;;;; +199A;NEW TAI LUE LETTER HIGH FA;Lo;0;L;;;;;N;;;;; +199B;NEW TAI LUE LETTER HIGH VA;Lo;0;L;;;;;N;;;;; +199C;NEW TAI LUE LETTER HIGH LA;Lo;0;L;;;;;N;;;;; +199D;NEW TAI LUE LETTER LOW FA;Lo;0;L;;;;;N;;;;; +199E;NEW TAI LUE LETTER LOW VA;Lo;0;L;;;;;N;;;;; +199F;NEW TAI LUE LETTER LOW LA;Lo;0;L;;;;;N;;;;; +19A0;NEW TAI LUE LETTER HIGH HA;Lo;0;L;;;;;N;;;;; +19A1;NEW TAI LUE LETTER HIGH DA;Lo;0;L;;;;;N;;;;; +19A2;NEW TAI LUE LETTER HIGH BA;Lo;0;L;;;;;N;;;;; +19A3;NEW TAI LUE LETTER LOW HA;Lo;0;L;;;;;N;;;;; +19A4;NEW TAI LUE LETTER LOW DA;Lo;0;L;;;;;N;;;;; +19A5;NEW TAI LUE LETTER LOW BA;Lo;0;L;;;;;N;;;;; +19A6;NEW TAI LUE LETTER HIGH KVA;Lo;0;L;;;;;N;;;;; +19A7;NEW TAI LUE LETTER HIGH XVA;Lo;0;L;;;;;N;;;;; +19A8;NEW TAI LUE LETTER LOW KVA;Lo;0;L;;;;;N;;;;; +19A9;NEW TAI LUE LETTER LOW XVA;Lo;0;L;;;;;N;;;;; +19AA;NEW TAI LUE LETTER HIGH SUA;Lo;0;L;;;;;N;;;;; +19AB;NEW TAI LUE LETTER LOW SUA;Lo;0;L;;;;;N;;;;; +19B0;NEW TAI LUE VOWEL SIGN VOWEL SHORTENER;Lo;0;L;;;;;N;;;;; +19B1;NEW TAI LUE VOWEL SIGN AA;Lo;0;L;;;;;N;;;;; +19B2;NEW TAI LUE VOWEL SIGN II;Lo;0;L;;;;;N;;;;; +19B3;NEW TAI LUE VOWEL SIGN U;Lo;0;L;;;;;N;;;;; +19B4;NEW TAI LUE VOWEL SIGN UU;Lo;0;L;;;;;N;;;;; +19B5;NEW TAI LUE VOWEL SIGN E;Lo;0;L;;;;;N;;;;; +19B6;NEW TAI LUE VOWEL SIGN AE;Lo;0;L;;;;;N;;;;; +19B7;NEW TAI LUE VOWEL SIGN O;Lo;0;L;;;;;N;;;;; +19B8;NEW TAI LUE VOWEL SIGN OA;Lo;0;L;;;;;N;;;;; +19B9;NEW TAI LUE VOWEL SIGN UE;Lo;0;L;;;;;N;;;;; +19BA;NEW TAI LUE VOWEL SIGN AY;Lo;0;L;;;;;N;;;;; +19BB;NEW TAI LUE VOWEL SIGN AAY;Lo;0;L;;;;;N;;;;; +19BC;NEW TAI LUE VOWEL SIGN UY;Lo;0;L;;;;;N;;;;; +19BD;NEW TAI LUE VOWEL SIGN OY;Lo;0;L;;;;;N;;;;; +19BE;NEW TAI LUE VOWEL SIGN OAY;Lo;0;L;;;;;N;;;;; +19BF;NEW TAI LUE VOWEL SIGN UEY;Lo;0;L;;;;;N;;;;; +19C0;NEW TAI LUE VOWEL SIGN IY;Lo;0;L;;;;;N;;;;; +19C1;NEW TAI LUE LETTER FINAL V;Lo;0;L;;;;;N;;;;; +19C2;NEW TAI LUE LETTER FINAL NG;Lo;0;L;;;;;N;;;;; +19C3;NEW TAI LUE LETTER FINAL N;Lo;0;L;;;;;N;;;;; +19C4;NEW TAI LUE LETTER FINAL M;Lo;0;L;;;;;N;;;;; +19C5;NEW TAI LUE LETTER FINAL K;Lo;0;L;;;;;N;;;;; +19C6;NEW TAI LUE LETTER FINAL D;Lo;0;L;;;;;N;;;;; +19C7;NEW TAI LUE LETTER FINAL B;Lo;0;L;;;;;N;;;;; +19C8;NEW TAI LUE TONE MARK-1;Lo;0;L;;;;;N;;;;; +19C9;NEW TAI LUE TONE MARK-2;Lo;0;L;;;;;N;;;;; +19D0;NEW TAI LUE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +19D1;NEW TAI LUE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +19D2;NEW TAI LUE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +19D3;NEW TAI LUE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +19D4;NEW TAI LUE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +19D5;NEW TAI LUE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +19D6;NEW TAI LUE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +19D7;NEW TAI LUE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +19D8;NEW TAI LUE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +19D9;NEW TAI LUE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +19DA;NEW TAI LUE THAM DIGIT ONE;No;0;L;;;1;1;N;;;;; +19DE;NEW TAI LUE SIGN LAE;So;0;ON;;;;;N;;;;; +19DF;NEW TAI LUE SIGN LAEV;So;0;ON;;;;;N;;;;; +19E0;KHMER SYMBOL PATHAMASAT;So;0;ON;;;;;N;;;;; +19E1;KHMER SYMBOL MUOY KOET;So;0;ON;;;;;N;;;;; +19E2;KHMER SYMBOL PII KOET;So;0;ON;;;;;N;;;;; +19E3;KHMER SYMBOL BEI KOET;So;0;ON;;;;;N;;;;; +19E4;KHMER SYMBOL BUON KOET;So;0;ON;;;;;N;;;;; +19E5;KHMER SYMBOL PRAM KOET;So;0;ON;;;;;N;;;;; +19E6;KHMER SYMBOL PRAM-MUOY KOET;So;0;ON;;;;;N;;;;; +19E7;KHMER SYMBOL PRAM-PII KOET;So;0;ON;;;;;N;;;;; +19E8;KHMER SYMBOL PRAM-BEI KOET;So;0;ON;;;;;N;;;;; +19E9;KHMER SYMBOL PRAM-BUON KOET;So;0;ON;;;;;N;;;;; +19EA;KHMER SYMBOL DAP KOET;So;0;ON;;;;;N;;;;; +19EB;KHMER SYMBOL DAP-MUOY KOET;So;0;ON;;;;;N;;;;; +19EC;KHMER SYMBOL DAP-PII KOET;So;0;ON;;;;;N;;;;; +19ED;KHMER SYMBOL DAP-BEI KOET;So;0;ON;;;;;N;;;;; +19EE;KHMER SYMBOL DAP-BUON KOET;So;0;ON;;;;;N;;;;; +19EF;KHMER SYMBOL DAP-PRAM KOET;So;0;ON;;;;;N;;;;; +19F0;KHMER SYMBOL TUTEYASAT;So;0;ON;;;;;N;;;;; +19F1;KHMER SYMBOL MUOY ROC;So;0;ON;;;;;N;;;;; +19F2;KHMER SYMBOL PII ROC;So;0;ON;;;;;N;;;;; +19F3;KHMER SYMBOL BEI ROC;So;0;ON;;;;;N;;;;; +19F4;KHMER SYMBOL BUON ROC;So;0;ON;;;;;N;;;;; +19F5;KHMER SYMBOL PRAM ROC;So;0;ON;;;;;N;;;;; +19F6;KHMER SYMBOL PRAM-MUOY ROC;So;0;ON;;;;;N;;;;; +19F7;KHMER SYMBOL PRAM-PII ROC;So;0;ON;;;;;N;;;;; +19F8;KHMER SYMBOL PRAM-BEI ROC;So;0;ON;;;;;N;;;;; +19F9;KHMER SYMBOL PRAM-BUON ROC;So;0;ON;;;;;N;;;;; +19FA;KHMER SYMBOL DAP ROC;So;0;ON;;;;;N;;;;; +19FB;KHMER SYMBOL DAP-MUOY ROC;So;0;ON;;;;;N;;;;; +19FC;KHMER SYMBOL DAP-PII ROC;So;0;ON;;;;;N;;;;; +19FD;KHMER SYMBOL DAP-BEI ROC;So;0;ON;;;;;N;;;;; +19FE;KHMER SYMBOL DAP-BUON ROC;So;0;ON;;;;;N;;;;; +19FF;KHMER SYMBOL DAP-PRAM ROC;So;0;ON;;;;;N;;;;; +1A00;BUGINESE LETTER KA;Lo;0;L;;;;;N;;;;; +1A01;BUGINESE LETTER GA;Lo;0;L;;;;;N;;;;; +1A02;BUGINESE LETTER NGA;Lo;0;L;;;;;N;;;;; +1A03;BUGINESE LETTER NGKA;Lo;0;L;;;;;N;;;;; +1A04;BUGINESE LETTER PA;Lo;0;L;;;;;N;;;;; +1A05;BUGINESE LETTER BA;Lo;0;L;;;;;N;;;;; +1A06;BUGINESE LETTER MA;Lo;0;L;;;;;N;;;;; +1A07;BUGINESE LETTER MPA;Lo;0;L;;;;;N;;;;; +1A08;BUGINESE LETTER TA;Lo;0;L;;;;;N;;;;; +1A09;BUGINESE LETTER DA;Lo;0;L;;;;;N;;;;; +1A0A;BUGINESE LETTER NA;Lo;0;L;;;;;N;;;;; +1A0B;BUGINESE LETTER NRA;Lo;0;L;;;;;N;;;;; +1A0C;BUGINESE LETTER CA;Lo;0;L;;;;;N;;;;; +1A0D;BUGINESE LETTER JA;Lo;0;L;;;;;N;;;;; +1A0E;BUGINESE LETTER NYA;Lo;0;L;;;;;N;;;;; +1A0F;BUGINESE LETTER NYCA;Lo;0;L;;;;;N;;;;; +1A10;BUGINESE LETTER YA;Lo;0;L;;;;;N;;;;; +1A11;BUGINESE LETTER RA;Lo;0;L;;;;;N;;;;; +1A12;BUGINESE LETTER LA;Lo;0;L;;;;;N;;;;; +1A13;BUGINESE LETTER VA;Lo;0;L;;;;;N;;;;; +1A14;BUGINESE LETTER SA;Lo;0;L;;;;;N;;;;; +1A15;BUGINESE LETTER A;Lo;0;L;;;;;N;;;;; +1A16;BUGINESE LETTER HA;Lo;0;L;;;;;N;;;;; +1A17;BUGINESE VOWEL SIGN I;Mn;230;NSM;;;;;N;;;;; +1A18;BUGINESE VOWEL SIGN U;Mn;220;NSM;;;;;N;;;;; +1A19;BUGINESE VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +1A1A;BUGINESE VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +1A1B;BUGINESE VOWEL SIGN AE;Mn;0;NSM;;;;;N;;;;; +1A1E;BUGINESE PALLAWA;Po;0;L;;;;;N;;;;; +1A1F;BUGINESE END OF SECTION;Po;0;L;;;;;N;;;;; +1A20;TAI THAM LETTER HIGH KA;Lo;0;L;;;;;N;;;;; +1A21;TAI THAM LETTER HIGH KHA;Lo;0;L;;;;;N;;;;; +1A22;TAI THAM LETTER HIGH KXA;Lo;0;L;;;;;N;;;;; +1A23;TAI THAM LETTER LOW KA;Lo;0;L;;;;;N;;;;; +1A24;TAI THAM LETTER LOW KXA;Lo;0;L;;;;;N;;;;; +1A25;TAI THAM LETTER LOW KHA;Lo;0;L;;;;;N;;;;; +1A26;TAI THAM LETTER NGA;Lo;0;L;;;;;N;;;;; +1A27;TAI THAM LETTER HIGH CA;Lo;0;L;;;;;N;;;;; +1A28;TAI THAM LETTER HIGH CHA;Lo;0;L;;;;;N;;;;; +1A29;TAI THAM LETTER LOW CA;Lo;0;L;;;;;N;;;;; +1A2A;TAI THAM LETTER LOW SA;Lo;0;L;;;;;N;;;;; +1A2B;TAI THAM LETTER LOW CHA;Lo;0;L;;;;;N;;;;; +1A2C;TAI THAM LETTER NYA;Lo;0;L;;;;;N;;;;; +1A2D;TAI THAM LETTER RATA;Lo;0;L;;;;;N;;;;; +1A2E;TAI THAM LETTER HIGH RATHA;Lo;0;L;;;;;N;;;;; +1A2F;TAI THAM LETTER DA;Lo;0;L;;;;;N;;;;; +1A30;TAI THAM LETTER LOW RATHA;Lo;0;L;;;;;N;;;;; +1A31;TAI THAM LETTER RANA;Lo;0;L;;;;;N;;;;; +1A32;TAI THAM LETTER HIGH TA;Lo;0;L;;;;;N;;;;; +1A33;TAI THAM LETTER HIGH THA;Lo;0;L;;;;;N;;;;; +1A34;TAI THAM LETTER LOW TA;Lo;0;L;;;;;N;;;;; +1A35;TAI THAM LETTER LOW THA;Lo;0;L;;;;;N;;;;; +1A36;TAI THAM LETTER NA;Lo;0;L;;;;;N;;;;; +1A37;TAI THAM LETTER BA;Lo;0;L;;;;;N;;;;; +1A38;TAI THAM LETTER HIGH PA;Lo;0;L;;;;;N;;;;; +1A39;TAI THAM LETTER HIGH PHA;Lo;0;L;;;;;N;;;;; +1A3A;TAI THAM LETTER HIGH FA;Lo;0;L;;;;;N;;;;; +1A3B;TAI THAM LETTER LOW PA;Lo;0;L;;;;;N;;;;; +1A3C;TAI THAM LETTER LOW FA;Lo;0;L;;;;;N;;;;; +1A3D;TAI THAM LETTER LOW PHA;Lo;0;L;;;;;N;;;;; +1A3E;TAI THAM LETTER MA;Lo;0;L;;;;;N;;;;; +1A3F;TAI THAM LETTER LOW YA;Lo;0;L;;;;;N;;;;; +1A40;TAI THAM LETTER HIGH YA;Lo;0;L;;;;;N;;;;; +1A41;TAI THAM LETTER RA;Lo;0;L;;;;;N;;;;; +1A42;TAI THAM LETTER RUE;Lo;0;L;;;;;N;;;;; +1A43;TAI THAM LETTER LA;Lo;0;L;;;;;N;;;;; +1A44;TAI THAM LETTER LUE;Lo;0;L;;;;;N;;;;; +1A45;TAI THAM LETTER WA;Lo;0;L;;;;;N;;;;; +1A46;TAI THAM LETTER HIGH SHA;Lo;0;L;;;;;N;;;;; +1A47;TAI THAM LETTER HIGH SSA;Lo;0;L;;;;;N;;;;; +1A48;TAI THAM LETTER HIGH SA;Lo;0;L;;;;;N;;;;; +1A49;TAI THAM LETTER HIGH HA;Lo;0;L;;;;;N;;;;; +1A4A;TAI THAM LETTER LLA;Lo;0;L;;;;;N;;;;; +1A4B;TAI THAM LETTER A;Lo;0;L;;;;;N;;;;; +1A4C;TAI THAM LETTER LOW HA;Lo;0;L;;;;;N;;;;; +1A4D;TAI THAM LETTER I;Lo;0;L;;;;;N;;;;; +1A4E;TAI THAM LETTER II;Lo;0;L;;;;;N;;;;; +1A4F;TAI THAM LETTER U;Lo;0;L;;;;;N;;;;; +1A50;TAI THAM LETTER UU;Lo;0;L;;;;;N;;;;; +1A51;TAI THAM LETTER EE;Lo;0;L;;;;;N;;;;; +1A52;TAI THAM LETTER OO;Lo;0;L;;;;;N;;;;; +1A53;TAI THAM LETTER LAE;Lo;0;L;;;;;N;;;;; +1A54;TAI THAM LETTER GREAT SA;Lo;0;L;;;;;N;;;;; +1A55;TAI THAM CONSONANT SIGN MEDIAL RA;Mc;0;L;;;;;N;;;;; +1A56;TAI THAM CONSONANT SIGN MEDIAL LA;Mn;0;NSM;;;;;N;;;;; +1A57;TAI THAM CONSONANT SIGN LA TANG LAI;Mc;0;L;;;;;N;;;;; +1A58;TAI THAM SIGN MAI KANG LAI;Mn;0;NSM;;;;;N;;;;; +1A59;TAI THAM CONSONANT SIGN FINAL NGA;Mn;0;NSM;;;;;N;;;;; +1A5A;TAI THAM CONSONANT SIGN LOW PA;Mn;0;NSM;;;;;N;;;;; +1A5B;TAI THAM CONSONANT SIGN HIGH RATHA OR LOW PA;Mn;0;NSM;;;;;N;;;;; +1A5C;TAI THAM CONSONANT SIGN MA;Mn;0;NSM;;;;;N;;;;; +1A5D;TAI THAM CONSONANT SIGN BA;Mn;0;NSM;;;;;N;;;;; +1A5E;TAI THAM CONSONANT SIGN SA;Mn;0;NSM;;;;;N;;;;; +1A60;TAI THAM SIGN SAKOT;Mn;9;NSM;;;;;N;;;;; +1A61;TAI THAM VOWEL SIGN A;Mc;0;L;;;;;N;;;;; +1A62;TAI THAM VOWEL SIGN MAI SAT;Mn;0;NSM;;;;;N;;;;; +1A63;TAI THAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +1A64;TAI THAM VOWEL SIGN TALL AA;Mc;0;L;;;;;N;;;;; +1A65;TAI THAM VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1A66;TAI THAM VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +1A67;TAI THAM VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;; +1A68;TAI THAM VOWEL SIGN UUE;Mn;0;NSM;;;;;N;;;;; +1A69;TAI THAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1A6A;TAI THAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +1A6B;TAI THAM VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +1A6C;TAI THAM VOWEL SIGN OA BELOW;Mn;0;NSM;;;;;N;;;;; +1A6D;TAI THAM VOWEL SIGN OY;Mc;0;L;;;;;N;;;;; +1A6E;TAI THAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +1A6F;TAI THAM VOWEL SIGN AE;Mc;0;L;;;;;N;;;;; +1A70;TAI THAM VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +1A71;TAI THAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +1A72;TAI THAM VOWEL SIGN THAM AI;Mc;0;L;;;;;N;;;;; +1A73;TAI THAM VOWEL SIGN OA ABOVE;Mn;0;NSM;;;;;N;;;;; +1A74;TAI THAM SIGN MAI KANG;Mn;0;NSM;;;;;N;;;;; +1A75;TAI THAM SIGN TONE-1;Mn;230;NSM;;;;;N;;;;; +1A76;TAI THAM SIGN TONE-2;Mn;230;NSM;;;;;N;;;;; +1A77;TAI THAM SIGN KHUEN TONE-3;Mn;230;NSM;;;;;N;;;;; +1A78;TAI THAM SIGN KHUEN TONE-4;Mn;230;NSM;;;;;N;;;;; +1A79;TAI THAM SIGN KHUEN TONE-5;Mn;230;NSM;;;;;N;;;;; +1A7A;TAI THAM SIGN RA HAAM;Mn;230;NSM;;;;;N;;;;; +1A7B;TAI THAM SIGN MAI SAM;Mn;230;NSM;;;;;N;;;;; +1A7C;TAI THAM SIGN KHUEN-LUE KARAN;Mn;230;NSM;;;;;N;;;;; +1A7F;TAI THAM COMBINING CRYPTOGRAMMIC DOT;Mn;220;NSM;;;;;N;;;;; +1A80;TAI THAM HORA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1A81;TAI THAM HORA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1A82;TAI THAM HORA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1A83;TAI THAM HORA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1A84;TAI THAM HORA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1A85;TAI THAM HORA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1A86;TAI THAM HORA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1A87;TAI THAM HORA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1A88;TAI THAM HORA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1A89;TAI THAM HORA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1A90;TAI THAM THAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1A91;TAI THAM THAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1A92;TAI THAM THAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1A93;TAI THAM THAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1A94;TAI THAM THAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1A95;TAI THAM THAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1A96;TAI THAM THAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1A97;TAI THAM THAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1A98;TAI THAM THAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1A99;TAI THAM THAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1AA0;TAI THAM SIGN WIANG;Po;0;L;;;;;N;;;;; +1AA1;TAI THAM SIGN WIANGWAAK;Po;0;L;;;;;N;;;;; +1AA2;TAI THAM SIGN SAWAN;Po;0;L;;;;;N;;;;; +1AA3;TAI THAM SIGN KEOW;Po;0;L;;;;;N;;;;; +1AA4;TAI THAM SIGN HOY;Po;0;L;;;;;N;;;;; +1AA5;TAI THAM SIGN DOKMAI;Po;0;L;;;;;N;;;;; +1AA6;TAI THAM SIGN REVERSED ROTATED RANA;Po;0;L;;;;;N;;;;; +1AA7;TAI THAM SIGN MAI YAMOK;Lm;0;L;;;;;N;;;;; +1AA8;TAI THAM SIGN KAAN;Po;0;L;;;;;N;;;;; +1AA9;TAI THAM SIGN KAANKUU;Po;0;L;;;;;N;;;;; +1AAA;TAI THAM SIGN SATKAAN;Po;0;L;;;;;N;;;;; +1AAB;TAI THAM SIGN SATKAANKUU;Po;0;L;;;;;N;;;;; +1AAC;TAI THAM SIGN HANG;Po;0;L;;;;;N;;;;; +1AAD;TAI THAM SIGN CAANG;Po;0;L;;;;;N;;;;; +1AB0;COMBINING DOUBLED CIRCUMFLEX ACCENT;Mn;230;NSM;;;;;N;;;;; +1AB1;COMBINING DIAERESIS-RING;Mn;230;NSM;;;;;N;;;;; +1AB2;COMBINING INFINITY;Mn;230;NSM;;;;;N;;;;; +1AB3;COMBINING DOWNWARDS ARROW;Mn;230;NSM;;;;;N;;;;; +1AB4;COMBINING TRIPLE DOT;Mn;230;NSM;;;;;N;;;;; +1AB5;COMBINING X-X BELOW;Mn;220;NSM;;;;;N;;;;; +1AB6;COMBINING WIGGLY LINE BELOW;Mn;220;NSM;;;;;N;;;;; +1AB7;COMBINING OPEN MARK BELOW;Mn;220;NSM;;;;;N;;;;; +1AB8;COMBINING DOUBLE OPEN MARK BELOW;Mn;220;NSM;;;;;N;;;;; +1AB9;COMBINING LIGHT CENTRALIZATION STROKE BELOW;Mn;220;NSM;;;;;N;;;;; +1ABA;COMBINING STRONG CENTRALIZATION STROKE BELOW;Mn;220;NSM;;;;;N;;;;; +1ABB;COMBINING PARENTHESES ABOVE;Mn;230;NSM;;;;;N;;;;; +1ABC;COMBINING DOUBLE PARENTHESES ABOVE;Mn;230;NSM;;;;;N;;;;; +1ABD;COMBINING PARENTHESES BELOW;Mn;220;NSM;;;;;N;;;;; +1ABE;COMBINING PARENTHESES OVERLAY;Me;0;NSM;;;;;N;;;;; +1B00;BALINESE SIGN ULU RICEM;Mn;0;NSM;;;;;N;;;;; +1B01;BALINESE SIGN ULU CANDRA;Mn;0;NSM;;;;;N;;;;; +1B02;BALINESE SIGN CECEK;Mn;0;NSM;;;;;N;;;;; +1B03;BALINESE SIGN SURANG;Mn;0;NSM;;;;;N;;;;; +1B04;BALINESE SIGN BISAH;Mc;0;L;;;;;N;;;;; +1B05;BALINESE LETTER AKARA;Lo;0;L;;;;;N;;;;; +1B06;BALINESE LETTER AKARA TEDUNG;Lo;0;L;1B05 1B35;;;;N;;;;; +1B07;BALINESE LETTER IKARA;Lo;0;L;;;;;N;;;;; +1B08;BALINESE LETTER IKARA TEDUNG;Lo;0;L;1B07 1B35;;;;N;;;;; +1B09;BALINESE LETTER UKARA;Lo;0;L;;;;;N;;;;; +1B0A;BALINESE LETTER UKARA TEDUNG;Lo;0;L;1B09 1B35;;;;N;;;;; +1B0B;BALINESE LETTER RA REPA;Lo;0;L;;;;;N;;;;; +1B0C;BALINESE LETTER RA REPA TEDUNG;Lo;0;L;1B0B 1B35;;;;N;;;;; +1B0D;BALINESE LETTER LA LENGA;Lo;0;L;;;;;N;;;;; +1B0E;BALINESE LETTER LA LENGA TEDUNG;Lo;0;L;1B0D 1B35;;;;N;;;;; +1B0F;BALINESE LETTER EKARA;Lo;0;L;;;;;N;;;;; +1B10;BALINESE LETTER AIKARA;Lo;0;L;;;;;N;;;;; +1B11;BALINESE LETTER OKARA;Lo;0;L;;;;;N;;;;; +1B12;BALINESE LETTER OKARA TEDUNG;Lo;0;L;1B11 1B35;;;;N;;;;; +1B13;BALINESE LETTER KA;Lo;0;L;;;;;N;;;;; +1B14;BALINESE LETTER KA MAHAPRANA;Lo;0;L;;;;;N;;;;; +1B15;BALINESE LETTER GA;Lo;0;L;;;;;N;;;;; +1B16;BALINESE LETTER GA GORA;Lo;0;L;;;;;N;;;;; +1B17;BALINESE LETTER NGA;Lo;0;L;;;;;N;;;;; +1B18;BALINESE LETTER CA;Lo;0;L;;;;;N;;;;; +1B19;BALINESE LETTER CA LACA;Lo;0;L;;;;;N;;;;; +1B1A;BALINESE LETTER JA;Lo;0;L;;;;;N;;;;; +1B1B;BALINESE LETTER JA JERA;Lo;0;L;;;;;N;;;;; +1B1C;BALINESE LETTER NYA;Lo;0;L;;;;;N;;;;; +1B1D;BALINESE LETTER TA LATIK;Lo;0;L;;;;;N;;;;; +1B1E;BALINESE LETTER TA MURDA MAHAPRANA;Lo;0;L;;;;;N;;;;; +1B1F;BALINESE LETTER DA MURDA ALPAPRANA;Lo;0;L;;;;;N;;;;; +1B20;BALINESE LETTER DA MURDA MAHAPRANA;Lo;0;L;;;;;N;;;;; +1B21;BALINESE LETTER NA RAMBAT;Lo;0;L;;;;;N;;;;; +1B22;BALINESE LETTER TA;Lo;0;L;;;;;N;;;;; +1B23;BALINESE LETTER TA TAWA;Lo;0;L;;;;;N;;;;; +1B24;BALINESE LETTER DA;Lo;0;L;;;;;N;;;;; +1B25;BALINESE LETTER DA MADU;Lo;0;L;;;;;N;;;;; +1B26;BALINESE LETTER NA;Lo;0;L;;;;;N;;;;; +1B27;BALINESE LETTER PA;Lo;0;L;;;;;N;;;;; +1B28;BALINESE LETTER PA KAPAL;Lo;0;L;;;;;N;;;;; +1B29;BALINESE LETTER BA;Lo;0;L;;;;;N;;;;; +1B2A;BALINESE LETTER BA KEMBANG;Lo;0;L;;;;;N;;;;; +1B2B;BALINESE LETTER MA;Lo;0;L;;;;;N;;;;; +1B2C;BALINESE LETTER YA;Lo;0;L;;;;;N;;;;; +1B2D;BALINESE LETTER RA;Lo;0;L;;;;;N;;;;; +1B2E;BALINESE LETTER LA;Lo;0;L;;;;;N;;;;; +1B2F;BALINESE LETTER WA;Lo;0;L;;;;;N;;;;; +1B30;BALINESE LETTER SA SAGA;Lo;0;L;;;;;N;;;;; +1B31;BALINESE LETTER SA SAPA;Lo;0;L;;;;;N;;;;; +1B32;BALINESE LETTER SA;Lo;0;L;;;;;N;;;;; +1B33;BALINESE LETTER HA;Lo;0;L;;;;;N;;;;; +1B34;BALINESE SIGN REREKAN;Mn;7;NSM;;;;;N;;;;; +1B35;BALINESE VOWEL SIGN TEDUNG;Mc;0;L;;;;;N;;;;; +1B36;BALINESE VOWEL SIGN ULU;Mn;0;NSM;;;;;N;;;;; +1B37;BALINESE VOWEL SIGN ULU SARI;Mn;0;NSM;;;;;N;;;;; +1B38;BALINESE VOWEL SIGN SUKU;Mn;0;NSM;;;;;N;;;;; +1B39;BALINESE VOWEL SIGN SUKU ILUT;Mn;0;NSM;;;;;N;;;;; +1B3A;BALINESE VOWEL SIGN RA REPA;Mn;0;NSM;;;;;N;;;;; +1B3B;BALINESE VOWEL SIGN RA REPA TEDUNG;Mc;0;L;1B3A 1B35;;;;N;;;;; +1B3C;BALINESE VOWEL SIGN LA LENGA;Mn;0;NSM;;;;;N;;;;; +1B3D;BALINESE VOWEL SIGN LA LENGA TEDUNG;Mc;0;L;1B3C 1B35;;;;N;;;;; +1B3E;BALINESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;;;; +1B3F;BALINESE VOWEL SIGN TALING REPA;Mc;0;L;;;;;N;;;;; +1B40;BALINESE VOWEL SIGN TALING TEDUNG;Mc;0;L;1B3E 1B35;;;;N;;;;; +1B41;BALINESE VOWEL SIGN TALING REPA TEDUNG;Mc;0;L;1B3F 1B35;;;;N;;;;; +1B42;BALINESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;;;; +1B43;BALINESE VOWEL SIGN PEPET TEDUNG;Mc;0;L;1B42 1B35;;;;N;;;;; +1B44;BALINESE ADEG ADEG;Mc;9;L;;;;;N;;;;; +1B45;BALINESE LETTER KAF SASAK;Lo;0;L;;;;;N;;;;; +1B46;BALINESE LETTER KHOT SASAK;Lo;0;L;;;;;N;;;;; +1B47;BALINESE LETTER TZIR SASAK;Lo;0;L;;;;;N;;;;; +1B48;BALINESE LETTER EF SASAK;Lo;0;L;;;;;N;;;;; +1B49;BALINESE LETTER VE SASAK;Lo;0;L;;;;;N;;;;; +1B4A;BALINESE LETTER ZAL SASAK;Lo;0;L;;;;;N;;;;; +1B4B;BALINESE LETTER ASYURA SASAK;Lo;0;L;;;;;N;;;;; +1B50;BALINESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1B51;BALINESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1B52;BALINESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1B53;BALINESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1B54;BALINESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1B55;BALINESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1B56;BALINESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1B57;BALINESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1B58;BALINESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1B59;BALINESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1B5A;BALINESE PANTI;Po;0;L;;;;;N;;;;; +1B5B;BALINESE PAMADA;Po;0;L;;;;;N;;;;; +1B5C;BALINESE WINDU;Po;0;L;;;;;N;;;;; +1B5D;BALINESE CARIK PAMUNGKAH;Po;0;L;;;;;N;;;;; +1B5E;BALINESE CARIK SIKI;Po;0;L;;;;;N;;;;; +1B5F;BALINESE CARIK PAREREN;Po;0;L;;;;;N;;;;; +1B60;BALINESE PAMENENG;Po;0;L;;;;;N;;;;; +1B61;BALINESE MUSICAL SYMBOL DONG;So;0;L;;;;;N;;;;; +1B62;BALINESE MUSICAL SYMBOL DENG;So;0;L;;;;;N;;;;; +1B63;BALINESE MUSICAL SYMBOL DUNG;So;0;L;;;;;N;;;;; +1B64;BALINESE MUSICAL SYMBOL DANG;So;0;L;;;;;N;;;;; +1B65;BALINESE MUSICAL SYMBOL DANG SURANG;So;0;L;;;;;N;;;;; +1B66;BALINESE MUSICAL SYMBOL DING;So;0;L;;;;;N;;;;; +1B67;BALINESE MUSICAL SYMBOL DAENG;So;0;L;;;;;N;;;;; +1B68;BALINESE MUSICAL SYMBOL DEUNG;So;0;L;;;;;N;;;;; +1B69;BALINESE MUSICAL SYMBOL DAING;So;0;L;;;;;N;;;;; +1B6A;BALINESE MUSICAL SYMBOL DANG GEDE;So;0;L;;;;;N;;;;; +1B6B;BALINESE MUSICAL SYMBOL COMBINING TEGEH;Mn;230;NSM;;;;;N;;;;; +1B6C;BALINESE MUSICAL SYMBOL COMBINING ENDEP;Mn;220;NSM;;;;;N;;;;; +1B6D;BALINESE MUSICAL SYMBOL COMBINING KEMPUL;Mn;230;NSM;;;;;N;;;;; +1B6E;BALINESE MUSICAL SYMBOL COMBINING KEMPLI;Mn;230;NSM;;;;;N;;;;; +1B6F;BALINESE MUSICAL SYMBOL COMBINING JEGOGAN;Mn;230;NSM;;;;;N;;;;; +1B70;BALINESE MUSICAL SYMBOL COMBINING KEMPUL WITH JEGOGAN;Mn;230;NSM;;;;;N;;;;; +1B71;BALINESE MUSICAL SYMBOL COMBINING KEMPLI WITH JEGOGAN;Mn;230;NSM;;;;;N;;;;; +1B72;BALINESE MUSICAL SYMBOL COMBINING BENDE;Mn;230;NSM;;;;;N;;;;; +1B73;BALINESE MUSICAL SYMBOL COMBINING GONG;Mn;230;NSM;;;;;N;;;;; +1B74;BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG;So;0;L;;;;;N;;;;; +1B75;BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DAG;So;0;L;;;;;N;;;;; +1B76;BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TUK;So;0;L;;;;;N;;;;; +1B77;BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TAK;So;0;L;;;;;N;;;;; +1B78;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PANG;So;0;L;;;;;N;;;;; +1B79;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PUNG;So;0;L;;;;;N;;;;; +1B7A;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLAK;So;0;L;;;;;N;;;;; +1B7B;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLUK;So;0;L;;;;;N;;;;; +1B7C;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING;So;0;L;;;;;N;;;;; +1B80;SUNDANESE SIGN PANYECEK;Mn;0;NSM;;;;;N;;;;; +1B81;SUNDANESE SIGN PANGLAYAR;Mn;0;NSM;;;;;N;;;;; +1B82;SUNDANESE SIGN PANGWISAD;Mc;0;L;;;;;N;;;;; +1B83;SUNDANESE LETTER A;Lo;0;L;;;;;N;;;;; +1B84;SUNDANESE LETTER I;Lo;0;L;;;;;N;;;;; +1B85;SUNDANESE LETTER U;Lo;0;L;;;;;N;;;;; +1B86;SUNDANESE LETTER AE;Lo;0;L;;;;;N;;;;; +1B87;SUNDANESE LETTER O;Lo;0;L;;;;;N;;;;; +1B88;SUNDANESE LETTER E;Lo;0;L;;;;;N;;;;; +1B89;SUNDANESE LETTER EU;Lo;0;L;;;;;N;;;;; +1B8A;SUNDANESE LETTER KA;Lo;0;L;;;;;N;;;;; +1B8B;SUNDANESE LETTER QA;Lo;0;L;;;;;N;;;;; +1B8C;SUNDANESE LETTER GA;Lo;0;L;;;;;N;;;;; +1B8D;SUNDANESE LETTER NGA;Lo;0;L;;;;;N;;;;; +1B8E;SUNDANESE LETTER CA;Lo;0;L;;;;;N;;;;; +1B8F;SUNDANESE LETTER JA;Lo;0;L;;;;;N;;;;; +1B90;SUNDANESE LETTER ZA;Lo;0;L;;;;;N;;;;; +1B91;SUNDANESE LETTER NYA;Lo;0;L;;;;;N;;;;; +1B92;SUNDANESE LETTER TA;Lo;0;L;;;;;N;;;;; +1B93;SUNDANESE LETTER DA;Lo;0;L;;;;;N;;;;; +1B94;SUNDANESE LETTER NA;Lo;0;L;;;;;N;;;;; +1B95;SUNDANESE LETTER PA;Lo;0;L;;;;;N;;;;; +1B96;SUNDANESE LETTER FA;Lo;0;L;;;;;N;;;;; +1B97;SUNDANESE LETTER VA;Lo;0;L;;;;;N;;;;; +1B98;SUNDANESE LETTER BA;Lo;0;L;;;;;N;;;;; +1B99;SUNDANESE LETTER MA;Lo;0;L;;;;;N;;;;; +1B9A;SUNDANESE LETTER YA;Lo;0;L;;;;;N;;;;; +1B9B;SUNDANESE LETTER RA;Lo;0;L;;;;;N;;;;; +1B9C;SUNDANESE LETTER LA;Lo;0;L;;;;;N;;;;; +1B9D;SUNDANESE LETTER WA;Lo;0;L;;;;;N;;;;; +1B9E;SUNDANESE LETTER SA;Lo;0;L;;;;;N;;;;; +1B9F;SUNDANESE LETTER XA;Lo;0;L;;;;;N;;;;; +1BA0;SUNDANESE LETTER HA;Lo;0;L;;;;;N;;;;; +1BA1;SUNDANESE CONSONANT SIGN PAMINGKAL;Mc;0;L;;;;;N;;;;; +1BA2;SUNDANESE CONSONANT SIGN PANYAKRA;Mn;0;NSM;;;;;N;;;;; +1BA3;SUNDANESE CONSONANT SIGN PANYIKU;Mn;0;NSM;;;;;N;;;;; +1BA4;SUNDANESE VOWEL SIGN PANGHULU;Mn;0;NSM;;;;;N;;;;; +1BA5;SUNDANESE VOWEL SIGN PANYUKU;Mn;0;NSM;;;;;N;;;;; +1BA6;SUNDANESE VOWEL SIGN PANAELAENG;Mc;0;L;;;;;N;;;;; +1BA7;SUNDANESE VOWEL SIGN PANOLONG;Mc;0;L;;;;;N;;;;; +1BA8;SUNDANESE VOWEL SIGN PAMEPET;Mn;0;NSM;;;;;N;;;;; +1BA9;SUNDANESE VOWEL SIGN PANEULEUNG;Mn;0;NSM;;;;;N;;;;; +1BAA;SUNDANESE SIGN PAMAAEH;Mc;9;L;;;;;N;;;;; +1BAB;SUNDANESE SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +1BAC;SUNDANESE CONSONANT SIGN PASANGAN MA;Mn;0;NSM;;;;;N;;;;; +1BAD;SUNDANESE CONSONANT SIGN PASANGAN WA;Mn;0;NSM;;;;;N;;;;; +1BAE;SUNDANESE LETTER KHA;Lo;0;L;;;;;N;;;;; +1BAF;SUNDANESE LETTER SYA;Lo;0;L;;;;;N;;;;; +1BB0;SUNDANESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1BB1;SUNDANESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1BB2;SUNDANESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1BB3;SUNDANESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1BB4;SUNDANESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1BB5;SUNDANESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1BB6;SUNDANESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1BB7;SUNDANESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1BB8;SUNDANESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1BB9;SUNDANESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1BBA;SUNDANESE AVAGRAHA;Lo;0;L;;;;;N;;;;; +1BBB;SUNDANESE LETTER REU;Lo;0;L;;;;;N;;;;; +1BBC;SUNDANESE LETTER LEU;Lo;0;L;;;;;N;;;;; +1BBD;SUNDANESE LETTER BHA;Lo;0;L;;;;;N;;;;; +1BBE;SUNDANESE LETTER FINAL K;Lo;0;L;;;;;N;;;;; +1BBF;SUNDANESE LETTER FINAL M;Lo;0;L;;;;;N;;;;; +1BC0;BATAK LETTER A;Lo;0;L;;;;;N;;;;; +1BC1;BATAK LETTER SIMALUNGUN A;Lo;0;L;;;;;N;;;;; +1BC2;BATAK LETTER HA;Lo;0;L;;;;;N;;;;; +1BC3;BATAK LETTER SIMALUNGUN HA;Lo;0;L;;;;;N;;;;; +1BC4;BATAK LETTER MANDAILING HA;Lo;0;L;;;;;N;;;;; +1BC5;BATAK LETTER BA;Lo;0;L;;;;;N;;;;; +1BC6;BATAK LETTER KARO BA;Lo;0;L;;;;;N;;;;; +1BC7;BATAK LETTER PA;Lo;0;L;;;;;N;;;;; +1BC8;BATAK LETTER SIMALUNGUN PA;Lo;0;L;;;;;N;;;;; +1BC9;BATAK LETTER NA;Lo;0;L;;;;;N;;;;; +1BCA;BATAK LETTER MANDAILING NA;Lo;0;L;;;;;N;;;;; +1BCB;BATAK LETTER WA;Lo;0;L;;;;;N;;;;; +1BCC;BATAK LETTER SIMALUNGUN WA;Lo;0;L;;;;;N;;;;; +1BCD;BATAK LETTER PAKPAK WA;Lo;0;L;;;;;N;;;;; +1BCE;BATAK LETTER GA;Lo;0;L;;;;;N;;;;; +1BCF;BATAK LETTER SIMALUNGUN GA;Lo;0;L;;;;;N;;;;; +1BD0;BATAK LETTER JA;Lo;0;L;;;;;N;;;;; +1BD1;BATAK LETTER DA;Lo;0;L;;;;;N;;;;; +1BD2;BATAK LETTER RA;Lo;0;L;;;;;N;;;;; +1BD3;BATAK LETTER SIMALUNGUN RA;Lo;0;L;;;;;N;;;;; +1BD4;BATAK LETTER MA;Lo;0;L;;;;;N;;;;; +1BD5;BATAK LETTER SIMALUNGUN MA;Lo;0;L;;;;;N;;;;; +1BD6;BATAK LETTER SOUTHERN TA;Lo;0;L;;;;;N;;;;; +1BD7;BATAK LETTER NORTHERN TA;Lo;0;L;;;;;N;;;;; +1BD8;BATAK LETTER SA;Lo;0;L;;;;;N;;;;; +1BD9;BATAK LETTER SIMALUNGUN SA;Lo;0;L;;;;;N;;;;; +1BDA;BATAK LETTER MANDAILING SA;Lo;0;L;;;;;N;;;;; +1BDB;BATAK LETTER YA;Lo;0;L;;;;;N;;;;; +1BDC;BATAK LETTER SIMALUNGUN YA;Lo;0;L;;;;;N;;;;; +1BDD;BATAK LETTER NGA;Lo;0;L;;;;;N;;;;; +1BDE;BATAK LETTER LA;Lo;0;L;;;;;N;;;;; +1BDF;BATAK LETTER SIMALUNGUN LA;Lo;0;L;;;;;N;;;;; +1BE0;BATAK LETTER NYA;Lo;0;L;;;;;N;;;;; +1BE1;BATAK LETTER CA;Lo;0;L;;;;;N;;;;; +1BE2;BATAK LETTER NDA;Lo;0;L;;;;;N;;;;; +1BE3;BATAK LETTER MBA;Lo;0;L;;;;;N;;;;; +1BE4;BATAK LETTER I;Lo;0;L;;;;;N;;;;; +1BE5;BATAK LETTER U;Lo;0;L;;;;;N;;;;; +1BE6;BATAK SIGN TOMPI;Mn;7;NSM;;;;;N;;;;; +1BE7;BATAK VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +1BE8;BATAK VOWEL SIGN PAKPAK E;Mn;0;NSM;;;;;N;;;;; +1BE9;BATAK VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;; +1BEA;BATAK VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +1BEB;BATAK VOWEL SIGN KARO I;Mc;0;L;;;;;N;;;;; +1BEC;BATAK VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +1BED;BATAK VOWEL SIGN KARO O;Mn;0;NSM;;;;;N;;;;; +1BEE;BATAK VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +1BEF;BATAK VOWEL SIGN U FOR SIMALUNGUN SA;Mn;0;NSM;;;;;N;;;;; +1BF0;BATAK CONSONANT SIGN NG;Mn;0;NSM;;;;;N;;;;; +1BF1;BATAK CONSONANT SIGN H;Mn;0;NSM;;;;;N;;;;; +1BF2;BATAK PANGOLAT;Mc;9;L;;;;;N;;;;; +1BF3;BATAK PANONGONAN;Mc;9;L;;;;;N;;;;; +1BFC;BATAK SYMBOL BINDU NA METEK;Po;0;L;;;;;N;;;;; +1BFD;BATAK SYMBOL BINDU PINARBORAS;Po;0;L;;;;;N;;;;; +1BFE;BATAK SYMBOL BINDU JUDUL;Po;0;L;;;;;N;;;;; +1BFF;BATAK SYMBOL BINDU PANGOLAT;Po;0;L;;;;;N;;;;; +1C00;LEPCHA LETTER KA;Lo;0;L;;;;;N;;;;; +1C01;LEPCHA LETTER KLA;Lo;0;L;;;;;N;;;;; +1C02;LEPCHA LETTER KHA;Lo;0;L;;;;;N;;;;; +1C03;LEPCHA LETTER GA;Lo;0;L;;;;;N;;;;; +1C04;LEPCHA LETTER GLA;Lo;0;L;;;;;N;;;;; +1C05;LEPCHA LETTER NGA;Lo;0;L;;;;;N;;;;; +1C06;LEPCHA LETTER CA;Lo;0;L;;;;;N;;;;; +1C07;LEPCHA LETTER CHA;Lo;0;L;;;;;N;;;;; +1C08;LEPCHA LETTER JA;Lo;0;L;;;;;N;;;;; +1C09;LEPCHA LETTER NYA;Lo;0;L;;;;;N;;;;; +1C0A;LEPCHA LETTER TA;Lo;0;L;;;;;N;;;;; +1C0B;LEPCHA LETTER THA;Lo;0;L;;;;;N;;;;; +1C0C;LEPCHA LETTER DA;Lo;0;L;;;;;N;;;;; +1C0D;LEPCHA LETTER NA;Lo;0;L;;;;;N;;;;; +1C0E;LEPCHA LETTER PA;Lo;0;L;;;;;N;;;;; +1C0F;LEPCHA LETTER PLA;Lo;0;L;;;;;N;;;;; +1C10;LEPCHA LETTER PHA;Lo;0;L;;;;;N;;;;; +1C11;LEPCHA LETTER FA;Lo;0;L;;;;;N;;;;; +1C12;LEPCHA LETTER FLA;Lo;0;L;;;;;N;;;;; +1C13;LEPCHA LETTER BA;Lo;0;L;;;;;N;;;;; +1C14;LEPCHA LETTER BLA;Lo;0;L;;;;;N;;;;; +1C15;LEPCHA LETTER MA;Lo;0;L;;;;;N;;;;; +1C16;LEPCHA LETTER MLA;Lo;0;L;;;;;N;;;;; +1C17;LEPCHA LETTER TSA;Lo;0;L;;;;;N;;;;; +1C18;LEPCHA LETTER TSHA;Lo;0;L;;;;;N;;;;; +1C19;LEPCHA LETTER DZA;Lo;0;L;;;;;N;;;;; +1C1A;LEPCHA LETTER YA;Lo;0;L;;;;;N;;;;; +1C1B;LEPCHA LETTER RA;Lo;0;L;;;;;N;;;;; +1C1C;LEPCHA LETTER LA;Lo;0;L;;;;;N;;;;; +1C1D;LEPCHA LETTER HA;Lo;0;L;;;;;N;;;;; +1C1E;LEPCHA LETTER HLA;Lo;0;L;;;;;N;;;;; +1C1F;LEPCHA LETTER VA;Lo;0;L;;;;;N;;;;; +1C20;LEPCHA LETTER SA;Lo;0;L;;;;;N;;;;; +1C21;LEPCHA LETTER SHA;Lo;0;L;;;;;N;;;;; +1C22;LEPCHA LETTER WA;Lo;0;L;;;;;N;;;;; +1C23;LEPCHA LETTER A;Lo;0;L;;;;;N;;;;; +1C24;LEPCHA SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;; +1C25;LEPCHA SUBJOINED LETTER RA;Mc;0;L;;;;;N;;;;; +1C26;LEPCHA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +1C27;LEPCHA VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +1C28;LEPCHA VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +1C29;LEPCHA VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +1C2A;LEPCHA VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +1C2B;LEPCHA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +1C2C;LEPCHA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +1C2D;LEPCHA CONSONANT SIGN K;Mn;0;NSM;;;;;N;;;;; +1C2E;LEPCHA CONSONANT SIGN M;Mn;0;NSM;;;;;N;;;;; +1C2F;LEPCHA CONSONANT SIGN L;Mn;0;NSM;;;;;N;;;;; +1C30;LEPCHA CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;; +1C31;LEPCHA CONSONANT SIGN P;Mn;0;NSM;;;;;N;;;;; +1C32;LEPCHA CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;; +1C33;LEPCHA CONSONANT SIGN T;Mn;0;NSM;;;;;N;;;;; +1C34;LEPCHA CONSONANT SIGN NYIN-DO;Mc;0;L;;;;;N;;;;; +1C35;LEPCHA CONSONANT SIGN KANG;Mc;0;L;;;;;N;;;;; +1C36;LEPCHA SIGN RAN;Mn;0;NSM;;;;;N;;;;; +1C37;LEPCHA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +1C3B;LEPCHA PUNCTUATION TA-ROL;Po;0;L;;;;;N;;;;; +1C3C;LEPCHA PUNCTUATION NYET THYOOM TA-ROL;Po;0;L;;;;;N;;;;; +1C3D;LEPCHA PUNCTUATION CER-WA;Po;0;L;;;;;N;;;;; +1C3E;LEPCHA PUNCTUATION TSHOOK CER-WA;Po;0;L;;;;;N;;;;; +1C3F;LEPCHA PUNCTUATION TSHOOK;Po;0;L;;;;;N;;;;; +1C40;LEPCHA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1C41;LEPCHA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1C42;LEPCHA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1C43;LEPCHA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1C44;LEPCHA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1C45;LEPCHA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1C46;LEPCHA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1C47;LEPCHA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1C48;LEPCHA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1C49;LEPCHA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1C4D;LEPCHA LETTER TTA;Lo;0;L;;;;;N;;;;; +1C4E;LEPCHA LETTER TTHA;Lo;0;L;;;;;N;;;;; +1C4F;LEPCHA LETTER DDA;Lo;0;L;;;;;N;;;;; +1C50;OL CHIKI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1C51;OL CHIKI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1C52;OL CHIKI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1C53;OL CHIKI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1C54;OL CHIKI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1C55;OL CHIKI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1C56;OL CHIKI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1C57;OL CHIKI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1C58;OL CHIKI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1C59;OL CHIKI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1C5A;OL CHIKI LETTER LA;Lo;0;L;;;;;N;;;;; +1C5B;OL CHIKI LETTER AT;Lo;0;L;;;;;N;;;;; +1C5C;OL CHIKI LETTER AG;Lo;0;L;;;;;N;;;;; +1C5D;OL CHIKI LETTER ANG;Lo;0;L;;;;;N;;;;; +1C5E;OL CHIKI LETTER AL;Lo;0;L;;;;;N;;;;; +1C5F;OL CHIKI LETTER LAA;Lo;0;L;;;;;N;;;;; +1C60;OL CHIKI LETTER AAK;Lo;0;L;;;;;N;;;;; +1C61;OL CHIKI LETTER AAJ;Lo;0;L;;;;;N;;;;; +1C62;OL CHIKI LETTER AAM;Lo;0;L;;;;;N;;;;; +1C63;OL CHIKI LETTER AAW;Lo;0;L;;;;;N;;;;; +1C64;OL CHIKI LETTER LI;Lo;0;L;;;;;N;;;;; +1C65;OL CHIKI LETTER IS;Lo;0;L;;;;;N;;;;; +1C66;OL CHIKI LETTER IH;Lo;0;L;;;;;N;;;;; +1C67;OL CHIKI LETTER INY;Lo;0;L;;;;;N;;;;; +1C68;OL CHIKI LETTER IR;Lo;0;L;;;;;N;;;;; +1C69;OL CHIKI LETTER LU;Lo;0;L;;;;;N;;;;; +1C6A;OL CHIKI LETTER UC;Lo;0;L;;;;;N;;;;; +1C6B;OL CHIKI LETTER UD;Lo;0;L;;;;;N;;;;; +1C6C;OL CHIKI LETTER UNN;Lo;0;L;;;;;N;;;;; +1C6D;OL CHIKI LETTER UY;Lo;0;L;;;;;N;;;;; +1C6E;OL CHIKI LETTER LE;Lo;0;L;;;;;N;;;;; +1C6F;OL CHIKI LETTER EP;Lo;0;L;;;;;N;;;;; +1C70;OL CHIKI LETTER EDD;Lo;0;L;;;;;N;;;;; +1C71;OL CHIKI LETTER EN;Lo;0;L;;;;;N;;;;; +1C72;OL CHIKI LETTER ERR;Lo;0;L;;;;;N;;;;; +1C73;OL CHIKI LETTER LO;Lo;0;L;;;;;N;;;;; +1C74;OL CHIKI LETTER OTT;Lo;0;L;;;;;N;;;;; +1C75;OL CHIKI LETTER OB;Lo;0;L;;;;;N;;;;; +1C76;OL CHIKI LETTER OV;Lo;0;L;;;;;N;;;;; +1C77;OL CHIKI LETTER OH;Lo;0;L;;;;;N;;;;; +1C78;OL CHIKI MU TTUDDAG;Lm;0;L;;;;;N;;;;; +1C79;OL CHIKI GAAHLAA TTUDDAAG;Lm;0;L;;;;;N;;;;; +1C7A;OL CHIKI MU-GAAHLAA TTUDDAAG;Lm;0;L;;;;;N;;;;; +1C7B;OL CHIKI RELAA;Lm;0;L;;;;;N;;;;; +1C7C;OL CHIKI PHAARKAA;Lm;0;L;;;;;N;;;;; +1C7D;OL CHIKI AHAD;Lm;0;L;;;;;N;;;;; +1C7E;OL CHIKI PUNCTUATION MUCAAD;Po;0;L;;;;;N;;;;; +1C7F;OL CHIKI PUNCTUATION DOUBLE MUCAAD;Po;0;L;;;;;N;;;;; +1C80;CYRILLIC SMALL LETTER ROUNDED VE;Ll;0;L;;;;;N;;;0412;;0412 +1C81;CYRILLIC SMALL LETTER LONG-LEGGED DE;Ll;0;L;;;;;N;;;0414;;0414 +1C82;CYRILLIC SMALL LETTER NARROW O;Ll;0;L;;;;;N;;;041E;;041E +1C83;CYRILLIC SMALL LETTER WIDE ES;Ll;0;L;;;;;N;;;0421;;0421 +1C84;CYRILLIC SMALL LETTER TALL TE;Ll;0;L;;;;;N;;;0422;;0422 +1C85;CYRILLIC SMALL LETTER THREE-LEGGED TE;Ll;0;L;;;;;N;;;0422;;0422 +1C86;CYRILLIC SMALL LETTER TALL HARD SIGN;Ll;0;L;;;;;N;;;042A;;042A +1C87;CYRILLIC SMALL LETTER TALL YAT;Ll;0;L;;;;;N;;;0462;;0462 +1C88;CYRILLIC SMALL LETTER UNBLENDED UK;Ll;0;L;;;;;N;;;A64A;;A64A +1C90;GEORGIAN MTAVRULI CAPITAL LETTER AN;Lu;0;L;;;;;N;;;;10D0; +1C91;GEORGIAN MTAVRULI CAPITAL LETTER BAN;Lu;0;L;;;;;N;;;;10D1; +1C92;GEORGIAN MTAVRULI CAPITAL LETTER GAN;Lu;0;L;;;;;N;;;;10D2; +1C93;GEORGIAN MTAVRULI CAPITAL LETTER DON;Lu;0;L;;;;;N;;;;10D3; +1C94;GEORGIAN MTAVRULI CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;10D4; +1C95;GEORGIAN MTAVRULI CAPITAL LETTER VIN;Lu;0;L;;;;;N;;;;10D5; +1C96;GEORGIAN MTAVRULI CAPITAL LETTER ZEN;Lu;0;L;;;;;N;;;;10D6; +1C97;GEORGIAN MTAVRULI CAPITAL LETTER TAN;Lu;0;L;;;;;N;;;;10D7; +1C98;GEORGIAN MTAVRULI CAPITAL LETTER IN;Lu;0;L;;;;;N;;;;10D8; +1C99;GEORGIAN MTAVRULI CAPITAL LETTER KAN;Lu;0;L;;;;;N;;;;10D9; +1C9A;GEORGIAN MTAVRULI CAPITAL LETTER LAS;Lu;0;L;;;;;N;;;;10DA; +1C9B;GEORGIAN MTAVRULI CAPITAL LETTER MAN;Lu;0;L;;;;;N;;;;10DB; +1C9C;GEORGIAN MTAVRULI CAPITAL LETTER NAR;Lu;0;L;;;;;N;;;;10DC; +1C9D;GEORGIAN MTAVRULI CAPITAL LETTER ON;Lu;0;L;;;;;N;;;;10DD; +1C9E;GEORGIAN MTAVRULI CAPITAL LETTER PAR;Lu;0;L;;;;;N;;;;10DE; +1C9F;GEORGIAN MTAVRULI CAPITAL LETTER ZHAR;Lu;0;L;;;;;N;;;;10DF; +1CA0;GEORGIAN MTAVRULI CAPITAL LETTER RAE;Lu;0;L;;;;;N;;;;10E0; +1CA1;GEORGIAN MTAVRULI CAPITAL LETTER SAN;Lu;0;L;;;;;N;;;;10E1; +1CA2;GEORGIAN MTAVRULI CAPITAL LETTER TAR;Lu;0;L;;;;;N;;;;10E2; +1CA3;GEORGIAN MTAVRULI CAPITAL LETTER UN;Lu;0;L;;;;;N;;;;10E3; +1CA4;GEORGIAN MTAVRULI CAPITAL LETTER PHAR;Lu;0;L;;;;;N;;;;10E4; +1CA5;GEORGIAN MTAVRULI CAPITAL LETTER KHAR;Lu;0;L;;;;;N;;;;10E5; +1CA6;GEORGIAN MTAVRULI CAPITAL LETTER GHAN;Lu;0;L;;;;;N;;;;10E6; +1CA7;GEORGIAN MTAVRULI CAPITAL LETTER QAR;Lu;0;L;;;;;N;;;;10E7; +1CA8;GEORGIAN MTAVRULI CAPITAL LETTER SHIN;Lu;0;L;;;;;N;;;;10E8; +1CA9;GEORGIAN MTAVRULI CAPITAL LETTER CHIN;Lu;0;L;;;;;N;;;;10E9; +1CAA;GEORGIAN MTAVRULI CAPITAL LETTER CAN;Lu;0;L;;;;;N;;;;10EA; +1CAB;GEORGIAN MTAVRULI CAPITAL LETTER JIL;Lu;0;L;;;;;N;;;;10EB; +1CAC;GEORGIAN MTAVRULI CAPITAL LETTER CIL;Lu;0;L;;;;;N;;;;10EC; +1CAD;GEORGIAN MTAVRULI CAPITAL LETTER CHAR;Lu;0;L;;;;;N;;;;10ED; +1CAE;GEORGIAN MTAVRULI CAPITAL LETTER XAN;Lu;0;L;;;;;N;;;;10EE; +1CAF;GEORGIAN MTAVRULI CAPITAL LETTER JHAN;Lu;0;L;;;;;N;;;;10EF; +1CB0;GEORGIAN MTAVRULI CAPITAL LETTER HAE;Lu;0;L;;;;;N;;;;10F0; +1CB1;GEORGIAN MTAVRULI CAPITAL LETTER HE;Lu;0;L;;;;;N;;;;10F1; +1CB2;GEORGIAN MTAVRULI CAPITAL LETTER HIE;Lu;0;L;;;;;N;;;;10F2; +1CB3;GEORGIAN MTAVRULI CAPITAL LETTER WE;Lu;0;L;;;;;N;;;;10F3; +1CB4;GEORGIAN MTAVRULI CAPITAL LETTER HAR;Lu;0;L;;;;;N;;;;10F4; +1CB5;GEORGIAN MTAVRULI CAPITAL LETTER HOE;Lu;0;L;;;;;N;;;;10F5; +1CB6;GEORGIAN MTAVRULI CAPITAL LETTER FI;Lu;0;L;;;;;N;;;;10F6; +1CB7;GEORGIAN MTAVRULI CAPITAL LETTER YN;Lu;0;L;;;;;N;;;;10F7; +1CB8;GEORGIAN MTAVRULI CAPITAL LETTER ELIFI;Lu;0;L;;;;;N;;;;10F8; +1CB9;GEORGIAN MTAVRULI CAPITAL LETTER TURNED GAN;Lu;0;L;;;;;N;;;;10F9; +1CBA;GEORGIAN MTAVRULI CAPITAL LETTER AIN;Lu;0;L;;;;;N;;;;10FA; +1CBD;GEORGIAN MTAVRULI CAPITAL LETTER AEN;Lu;0;L;;;;;N;;;;10FD; +1CBE;GEORGIAN MTAVRULI CAPITAL LETTER HARD SIGN;Lu;0;L;;;;;N;;;;10FE; +1CBF;GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN;Lu;0;L;;;;;N;;;;10FF; +1CC0;SUNDANESE PUNCTUATION BINDU SURYA;Po;0;L;;;;;N;;;;; +1CC1;SUNDANESE PUNCTUATION BINDU PANGLONG;Po;0;L;;;;;N;;;;; +1CC2;SUNDANESE PUNCTUATION BINDU PURNAMA;Po;0;L;;;;;N;;;;; +1CC3;SUNDANESE PUNCTUATION BINDU CAKRA;Po;0;L;;;;;N;;;;; +1CC4;SUNDANESE PUNCTUATION BINDU LEU SATANGA;Po;0;L;;;;;N;;;;; +1CC5;SUNDANESE PUNCTUATION BINDU KA SATANGA;Po;0;L;;;;;N;;;;; +1CC6;SUNDANESE PUNCTUATION BINDU DA SATANGA;Po;0;L;;;;;N;;;;; +1CC7;SUNDANESE PUNCTUATION BINDU BA SATANGA;Po;0;L;;;;;N;;;;; +1CD0;VEDIC TONE KARSHANA;Mn;230;NSM;;;;;N;;;;; +1CD1;VEDIC TONE SHARA;Mn;230;NSM;;;;;N;;;;; +1CD2;VEDIC TONE PRENKHA;Mn;230;NSM;;;;;N;;;;; +1CD3;VEDIC SIGN NIHSHVASA;Po;0;L;;;;;N;;;;; +1CD4;VEDIC SIGN YAJURVEDIC MIDLINE SVARITA;Mn;1;NSM;;;;;N;;;;; +1CD5;VEDIC TONE YAJURVEDIC AGGRAVATED INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;; +1CD6;VEDIC TONE YAJURVEDIC INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;; +1CD7;VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;; +1CD8;VEDIC TONE CANDRA BELOW;Mn;220;NSM;;;;;N;;;;; +1CD9;VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA SCHROEDER;Mn;220;NSM;;;;;N;;;;; +1CDA;VEDIC TONE DOUBLE SVARITA;Mn;230;NSM;;;;;N;;;;; +1CDB;VEDIC TONE TRIPLE SVARITA;Mn;230;NSM;;;;;N;;;;; +1CDC;VEDIC TONE KATHAKA ANUDATTA;Mn;220;NSM;;;;;N;;;;; +1CDD;VEDIC TONE DOT BELOW;Mn;220;NSM;;;;;N;;;;; +1CDE;VEDIC TONE TWO DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +1CDF;VEDIC TONE THREE DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +1CE0;VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA;Mn;230;NSM;;;;;N;;;;; +1CE1;VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA;Mc;0;L;;;;;N;;;;; +1CE2;VEDIC SIGN VISARGA SVARITA;Mn;1;NSM;;;;;N;;;;; +1CE3;VEDIC SIGN VISARGA UDATTA;Mn;1;NSM;;;;;N;;;;; +1CE4;VEDIC SIGN REVERSED VISARGA UDATTA;Mn;1;NSM;;;;;N;;;;; +1CE5;VEDIC SIGN VISARGA ANUDATTA;Mn;1;NSM;;;;;N;;;;; +1CE6;VEDIC SIGN REVERSED VISARGA ANUDATTA;Mn;1;NSM;;;;;N;;;;; +1CE7;VEDIC SIGN VISARGA UDATTA WITH TAIL;Mn;1;NSM;;;;;N;;;;; +1CE8;VEDIC SIGN VISARGA ANUDATTA WITH TAIL;Mn;1;NSM;;;;;N;;;;; +1CE9;VEDIC SIGN ANUSVARA ANTARGOMUKHA;Lo;0;L;;;;;N;;;;; +1CEA;VEDIC SIGN ANUSVARA BAHIRGOMUKHA;Lo;0;L;;;;;N;;;;; +1CEB;VEDIC SIGN ANUSVARA VAMAGOMUKHA;Lo;0;L;;;;;N;;;;; +1CEC;VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL;Lo;0;L;;;;;N;;;;; +1CED;VEDIC SIGN TIRYAK;Mn;220;NSM;;;;;N;;;;; +1CEE;VEDIC SIGN HEXIFORM LONG ANUSVARA;Lo;0;L;;;;;N;;;;; +1CEF;VEDIC SIGN LONG ANUSVARA;Lo;0;L;;;;;N;;;;; +1CF0;VEDIC SIGN RTHANG LONG ANUSVARA;Lo;0;L;;;;;N;;;;; +1CF1;VEDIC SIGN ANUSVARA UBHAYATO MUKHA;Lo;0;L;;;;;N;;;;; +1CF2;VEDIC SIGN ARDHAVISARGA;Lo;0;L;;;;;N;;;;; +1CF3;VEDIC SIGN ROTATED ARDHAVISARGA;Lo;0;L;;;;;N;;;;; +1CF4;VEDIC TONE CANDRA ABOVE;Mn;230;NSM;;;;;N;;;;; +1CF5;VEDIC SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;; +1CF6;VEDIC SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;; +1CF7;VEDIC SIGN ATIKRAMA;Mc;0;L;;;;;N;;;;; +1CF8;VEDIC TONE RING ABOVE;Mn;230;NSM;;;;;N;;;;; +1CF9;VEDIC TONE DOUBLE RING ABOVE;Mn;230;NSM;;;;;N;;;;; +1CFA;VEDIC SIGN DOUBLE ANUSVARA ANTARGOMUKHA;Lo;0;L;;;;;N;;;;; +1D00;LATIN LETTER SMALL CAPITAL A;Ll;0;L;;;;;N;;;;; +1D01;LATIN LETTER SMALL CAPITAL AE;Ll;0;L;;;;;N;;;;; +1D02;LATIN SMALL LETTER TURNED AE;Ll;0;L;;;;;N;;;;; +1D03;LATIN LETTER SMALL CAPITAL BARRED B;Ll;0;L;;;;;N;;;;; +1D04;LATIN LETTER SMALL CAPITAL C;Ll;0;L;;;;;N;;;;; +1D05;LATIN LETTER SMALL CAPITAL D;Ll;0;L;;;;;N;;;;; +1D06;LATIN LETTER SMALL CAPITAL ETH;Ll;0;L;;;;;N;;;;; +1D07;LATIN LETTER SMALL CAPITAL E;Ll;0;L;;;;;N;;;;; +1D08;LATIN SMALL LETTER TURNED OPEN E;Ll;0;L;;;;;N;;;;; +1D09;LATIN SMALL LETTER TURNED I;Ll;0;L;;;;;N;;;;; +1D0A;LATIN LETTER SMALL CAPITAL J;Ll;0;L;;;;;N;;;;; +1D0B;LATIN LETTER SMALL CAPITAL K;Ll;0;L;;;;;N;;;;; +1D0C;LATIN LETTER SMALL CAPITAL L WITH STROKE;Ll;0;L;;;;;N;;;;; +1D0D;LATIN LETTER SMALL CAPITAL M;Ll;0;L;;;;;N;;;;; +1D0E;LATIN LETTER SMALL CAPITAL REVERSED N;Ll;0;L;;;;;N;;;;; +1D0F;LATIN LETTER SMALL CAPITAL O;Ll;0;L;;;;;N;;;;; +1D10;LATIN LETTER SMALL CAPITAL OPEN O;Ll;0;L;;;;;N;;;;; +1D11;LATIN SMALL LETTER SIDEWAYS O;Ll;0;L;;;;;N;;;;; +1D12;LATIN SMALL LETTER SIDEWAYS OPEN O;Ll;0;L;;;;;N;;;;; +1D13;LATIN SMALL LETTER SIDEWAYS O WITH STROKE;Ll;0;L;;;;;N;;;;; +1D14;LATIN SMALL LETTER TURNED OE;Ll;0;L;;;;;N;;;;; +1D15;LATIN LETTER SMALL CAPITAL OU;Ll;0;L;;;;;N;;;;; +1D16;LATIN SMALL LETTER TOP HALF O;Ll;0;L;;;;;N;;;;; +1D17;LATIN SMALL LETTER BOTTOM HALF O;Ll;0;L;;;;;N;;;;; +1D18;LATIN LETTER SMALL CAPITAL P;Ll;0;L;;;;;N;;;;; +1D19;LATIN LETTER SMALL CAPITAL REVERSED R;Ll;0;L;;;;;N;;;;; +1D1A;LATIN LETTER SMALL CAPITAL TURNED R;Ll;0;L;;;;;N;;;;; +1D1B;LATIN LETTER SMALL CAPITAL T;Ll;0;L;;;;;N;;;;; +1D1C;LATIN LETTER SMALL CAPITAL U;Ll;0;L;;;;;N;;;;; +1D1D;LATIN SMALL LETTER SIDEWAYS U;Ll;0;L;;;;;N;;;;; +1D1E;LATIN SMALL LETTER SIDEWAYS DIAERESIZED U;Ll;0;L;;;;;N;;;;; +1D1F;LATIN SMALL LETTER SIDEWAYS TURNED M;Ll;0;L;;;;;N;;;;; +1D20;LATIN LETTER SMALL CAPITAL V;Ll;0;L;;;;;N;;;;; +1D21;LATIN LETTER SMALL CAPITAL W;Ll;0;L;;;;;N;;;;; +1D22;LATIN LETTER SMALL CAPITAL Z;Ll;0;L;;;;;N;;;;; +1D23;LATIN LETTER SMALL CAPITAL EZH;Ll;0;L;;;;;N;;;;; +1D24;LATIN LETTER VOICED LARYNGEAL SPIRANT;Ll;0;L;;;;;N;;;;; +1D25;LATIN LETTER AIN;Ll;0;L;;;;;N;;;;; +1D26;GREEK LETTER SMALL CAPITAL GAMMA;Ll;0;L;;;;;N;;;;; +1D27;GREEK LETTER SMALL CAPITAL LAMDA;Ll;0;L;;;;;N;;;;; +1D28;GREEK LETTER SMALL CAPITAL PI;Ll;0;L;;;;;N;;;;; +1D29;GREEK LETTER SMALL CAPITAL RHO;Ll;0;L;;;;;N;;;;; +1D2A;GREEK LETTER SMALL CAPITAL PSI;Ll;0;L;;;;;N;;;;; +1D2B;CYRILLIC LETTER SMALL CAPITAL EL;Ll;0;L;;;;;N;;;;; +1D2C;MODIFIER LETTER CAPITAL A;Lm;0;L; 0041;;;;N;;;;; +1D2D;MODIFIER LETTER CAPITAL AE;Lm;0;L; 00C6;;;;N;;;;; +1D2E;MODIFIER LETTER CAPITAL B;Lm;0;L; 0042;;;;N;;;;; +1D2F;MODIFIER LETTER CAPITAL BARRED B;Lm;0;L;;;;;N;;;;; +1D30;MODIFIER LETTER CAPITAL D;Lm;0;L; 0044;;;;N;;;;; +1D31;MODIFIER LETTER CAPITAL E;Lm;0;L; 0045;;;;N;;;;; +1D32;MODIFIER LETTER CAPITAL REVERSED E;Lm;0;L; 018E;;;;N;;;;; +1D33;MODIFIER LETTER CAPITAL G;Lm;0;L; 0047;;;;N;;;;; +1D34;MODIFIER LETTER CAPITAL H;Lm;0;L; 0048;;;;N;;;;; +1D35;MODIFIER LETTER CAPITAL I;Lm;0;L; 0049;;;;N;;;;; +1D36;MODIFIER LETTER CAPITAL J;Lm;0;L; 004A;;;;N;;;;; +1D37;MODIFIER LETTER CAPITAL K;Lm;0;L; 004B;;;;N;;;;; +1D38;MODIFIER LETTER CAPITAL L;Lm;0;L; 004C;;;;N;;;;; +1D39;MODIFIER LETTER CAPITAL M;Lm;0;L; 004D;;;;N;;;;; +1D3A;MODIFIER LETTER CAPITAL N;Lm;0;L; 004E;;;;N;;;;; +1D3B;MODIFIER LETTER CAPITAL REVERSED N;Lm;0;L;;;;;N;;;;; +1D3C;MODIFIER LETTER CAPITAL O;Lm;0;L; 004F;;;;N;;;;; +1D3D;MODIFIER LETTER CAPITAL OU;Lm;0;L; 0222;;;;N;;;;; +1D3E;MODIFIER LETTER CAPITAL P;Lm;0;L; 0050;;;;N;;;;; +1D3F;MODIFIER LETTER CAPITAL R;Lm;0;L; 0052;;;;N;;;;; +1D40;MODIFIER LETTER CAPITAL T;Lm;0;L; 0054;;;;N;;;;; +1D41;MODIFIER LETTER CAPITAL U;Lm;0;L; 0055;;;;N;;;;; +1D42;MODIFIER LETTER CAPITAL W;Lm;0;L; 0057;;;;N;;;;; +1D43;MODIFIER LETTER SMALL A;Lm;0;L; 0061;;;;N;;;;; +1D44;MODIFIER LETTER SMALL TURNED A;Lm;0;L; 0250;;;;N;;;;; +1D45;MODIFIER LETTER SMALL ALPHA;Lm;0;L; 0251;;;;N;;;;; +1D46;MODIFIER LETTER SMALL TURNED AE;Lm;0;L; 1D02;;;;N;;;;; +1D47;MODIFIER LETTER SMALL B;Lm;0;L; 0062;;;;N;;;;; +1D48;MODIFIER LETTER SMALL D;Lm;0;L; 0064;;;;N;;;;; +1D49;MODIFIER LETTER SMALL E;Lm;0;L; 0065;;;;N;;;;; +1D4A;MODIFIER LETTER SMALL SCHWA;Lm;0;L; 0259;;;;N;;;;; +1D4B;MODIFIER LETTER SMALL OPEN E;Lm;0;L; 025B;;;;N;;;;; +1D4C;MODIFIER LETTER SMALL TURNED OPEN E;Lm;0;L; 025C;;;;N;;;;; +1D4D;MODIFIER LETTER SMALL G;Lm;0;L; 0067;;;;N;;;;; +1D4E;MODIFIER LETTER SMALL TURNED I;Lm;0;L;;;;;N;;;;; +1D4F;MODIFIER LETTER SMALL K;Lm;0;L; 006B;;;;N;;;;; +1D50;MODIFIER LETTER SMALL M;Lm;0;L; 006D;;;;N;;;;; +1D51;MODIFIER LETTER SMALL ENG;Lm;0;L; 014B;;;;N;;;;; +1D52;MODIFIER LETTER SMALL O;Lm;0;L; 006F;;;;N;;;;; +1D53;MODIFIER LETTER SMALL OPEN O;Lm;0;L; 0254;;;;N;;;;; +1D54;MODIFIER LETTER SMALL TOP HALF O;Lm;0;L; 1D16;;;;N;;;;; +1D55;MODIFIER LETTER SMALL BOTTOM HALF O;Lm;0;L; 1D17;;;;N;;;;; +1D56;MODIFIER LETTER SMALL P;Lm;0;L; 0070;;;;N;;;;; +1D57;MODIFIER LETTER SMALL T;Lm;0;L; 0074;;;;N;;;;; +1D58;MODIFIER LETTER SMALL U;Lm;0;L; 0075;;;;N;;;;; +1D59;MODIFIER LETTER SMALL SIDEWAYS U;Lm;0;L; 1D1D;;;;N;;;;; +1D5A;MODIFIER LETTER SMALL TURNED M;Lm;0;L; 026F;;;;N;;;;; +1D5B;MODIFIER LETTER SMALL V;Lm;0;L; 0076;;;;N;;;;; +1D5C;MODIFIER LETTER SMALL AIN;Lm;0;L; 1D25;;;;N;;;;; +1D5D;MODIFIER LETTER SMALL BETA;Lm;0;L; 03B2;;;;N;;;;; +1D5E;MODIFIER LETTER SMALL GREEK GAMMA;Lm;0;L; 03B3;;;;N;;;;; +1D5F;MODIFIER LETTER SMALL DELTA;Lm;0;L; 03B4;;;;N;;;;; +1D60;MODIFIER LETTER SMALL GREEK PHI;Lm;0;L; 03C6;;;;N;;;;; +1D61;MODIFIER LETTER SMALL CHI;Lm;0;L; 03C7;;;;N;;;;; +1D62;LATIN SUBSCRIPT SMALL LETTER I;Lm;0;L; 0069;;;;N;;;;; +1D63;LATIN SUBSCRIPT SMALL LETTER R;Lm;0;L; 0072;;;;N;;;;; +1D64;LATIN SUBSCRIPT SMALL LETTER U;Lm;0;L; 0075;;;;N;;;;; +1D65;LATIN SUBSCRIPT SMALL LETTER V;Lm;0;L; 0076;;;;N;;;;; +1D66;GREEK SUBSCRIPT SMALL LETTER BETA;Lm;0;L; 03B2;;;;N;;;;; +1D67;GREEK SUBSCRIPT SMALL LETTER GAMMA;Lm;0;L; 03B3;;;;N;;;;; +1D68;GREEK SUBSCRIPT SMALL LETTER RHO;Lm;0;L; 03C1;;;;N;;;;; +1D69;GREEK SUBSCRIPT SMALL LETTER PHI;Lm;0;L; 03C6;;;;N;;;;; +1D6A;GREEK SUBSCRIPT SMALL LETTER CHI;Lm;0;L; 03C7;;;;N;;;;; +1D6B;LATIN SMALL LETTER UE;Ll;0;L;;;;;N;;;;; +1D6C;LATIN SMALL LETTER B WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D6D;LATIN SMALL LETTER D WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D6E;LATIN SMALL LETTER F WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D6F;LATIN SMALL LETTER M WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D70;LATIN SMALL LETTER N WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D71;LATIN SMALL LETTER P WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D72;LATIN SMALL LETTER R WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D73;LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D74;LATIN SMALL LETTER S WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D75;LATIN SMALL LETTER T WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D76;LATIN SMALL LETTER Z WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +1D77;LATIN SMALL LETTER TURNED G;Ll;0;L;;;;;N;;;;; +1D78;MODIFIER LETTER CYRILLIC EN;Lm;0;L; 043D;;;;N;;;;; +1D79;LATIN SMALL LETTER INSULAR G;Ll;0;L;;;;;N;;;A77D;;A77D +1D7A;LATIN SMALL LETTER TH WITH STRIKETHROUGH;Ll;0;L;;;;;N;;;;; +1D7B;LATIN SMALL CAPITAL LETTER I WITH STROKE;Ll;0;L;;;;;N;;;;; +1D7C;LATIN SMALL LETTER IOTA WITH STROKE;Ll;0;L;;;;;N;;;;; +1D7D;LATIN SMALL LETTER P WITH STROKE;Ll;0;L;;;;;N;;;2C63;;2C63 +1D7E;LATIN SMALL CAPITAL LETTER U WITH STROKE;Ll;0;L;;;;;N;;;;; +1D7F;LATIN SMALL LETTER UPSILON WITH STROKE;Ll;0;L;;;;;N;;;;; +1D80;LATIN SMALL LETTER B WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D81;LATIN SMALL LETTER D WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D82;LATIN SMALL LETTER F WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D83;LATIN SMALL LETTER G WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D84;LATIN SMALL LETTER K WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D85;LATIN SMALL LETTER L WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D86;LATIN SMALL LETTER M WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D87;LATIN SMALL LETTER N WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D88;LATIN SMALL LETTER P WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D89;LATIN SMALL LETTER R WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8A;LATIN SMALL LETTER S WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8B;LATIN SMALL LETTER ESH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8C;LATIN SMALL LETTER V WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8D;LATIN SMALL LETTER X WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8E;LATIN SMALL LETTER Z WITH PALATAL HOOK;Ll;0;L;;;;;N;;;A7C6;;A7C6 +1D8F;LATIN SMALL LETTER A WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D90;LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D91;LATIN SMALL LETTER D WITH HOOK AND TAIL;Ll;0;L;;;;;N;;;;; +1D92;LATIN SMALL LETTER E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D93;LATIN SMALL LETTER OPEN E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D94;LATIN SMALL LETTER REVERSED OPEN E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D95;LATIN SMALL LETTER SCHWA WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D96;LATIN SMALL LETTER I WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D97;LATIN SMALL LETTER OPEN O WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D98;LATIN SMALL LETTER ESH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D99;LATIN SMALL LETTER U WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D9A;LATIN SMALL LETTER EZH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +1D9B;MODIFIER LETTER SMALL TURNED ALPHA;Lm;0;L; 0252;;;;N;;;;; +1D9C;MODIFIER LETTER SMALL C;Lm;0;L; 0063;;;;N;;;;; +1D9D;MODIFIER LETTER SMALL C WITH CURL;Lm;0;L; 0255;;;;N;;;;; +1D9E;MODIFIER LETTER SMALL ETH;Lm;0;L; 00F0;;;;N;;;;; +1D9F;MODIFIER LETTER SMALL REVERSED OPEN E;Lm;0;L; 025C;;;;N;;;;; +1DA0;MODIFIER LETTER SMALL F;Lm;0;L; 0066;;;;N;;;;; +1DA1;MODIFIER LETTER SMALL DOTLESS J WITH STROKE;Lm;0;L; 025F;;;;N;;;;; +1DA2;MODIFIER LETTER SMALL SCRIPT G;Lm;0;L; 0261;;;;N;;;;; +1DA3;MODIFIER LETTER SMALL TURNED H;Lm;0;L; 0265;;;;N;;;;; +1DA4;MODIFIER LETTER SMALL I WITH STROKE;Lm;0;L; 0268;;;;N;;;;; +1DA5;MODIFIER LETTER SMALL IOTA;Lm;0;L; 0269;;;;N;;;;; +1DA6;MODIFIER LETTER SMALL CAPITAL I;Lm;0;L; 026A;;;;N;;;;; +1DA7;MODIFIER LETTER SMALL CAPITAL I WITH STROKE;Lm;0;L; 1D7B;;;;N;;;;; +1DA8;MODIFIER LETTER SMALL J WITH CROSSED-TAIL;Lm;0;L; 029D;;;;N;;;;; +1DA9;MODIFIER LETTER SMALL L WITH RETROFLEX HOOK;Lm;0;L; 026D;;;;N;;;;; +1DAA;MODIFIER LETTER SMALL L WITH PALATAL HOOK;Lm;0;L; 1D85;;;;N;;;;; +1DAB;MODIFIER LETTER SMALL CAPITAL L;Lm;0;L; 029F;;;;N;;;;; +1DAC;MODIFIER LETTER SMALL M WITH HOOK;Lm;0;L; 0271;;;;N;;;;; +1DAD;MODIFIER LETTER SMALL TURNED M WITH LONG LEG;Lm;0;L; 0270;;;;N;;;;; +1DAE;MODIFIER LETTER SMALL N WITH LEFT HOOK;Lm;0;L; 0272;;;;N;;;;; +1DAF;MODIFIER LETTER SMALL N WITH RETROFLEX HOOK;Lm;0;L; 0273;;;;N;;;;; +1DB0;MODIFIER LETTER SMALL CAPITAL N;Lm;0;L; 0274;;;;N;;;;; +1DB1;MODIFIER LETTER SMALL BARRED O;Lm;0;L; 0275;;;;N;;;;; +1DB2;MODIFIER LETTER SMALL PHI;Lm;0;L; 0278;;;;N;;;;; +1DB3;MODIFIER LETTER SMALL S WITH HOOK;Lm;0;L; 0282;;;;N;;;;; +1DB4;MODIFIER LETTER SMALL ESH;Lm;0;L; 0283;;;;N;;;;; +1DB5;MODIFIER LETTER SMALL T WITH PALATAL HOOK;Lm;0;L; 01AB;;;;N;;;;; +1DB6;MODIFIER LETTER SMALL U BAR;Lm;0;L; 0289;;;;N;;;;; +1DB7;MODIFIER LETTER SMALL UPSILON;Lm;0;L; 028A;;;;N;;;;; +1DB8;MODIFIER LETTER SMALL CAPITAL U;Lm;0;L; 1D1C;;;;N;;;;; +1DB9;MODIFIER LETTER SMALL V WITH HOOK;Lm;0;L; 028B;;;;N;;;;; +1DBA;MODIFIER LETTER SMALL TURNED V;Lm;0;L; 028C;;;;N;;;;; +1DBB;MODIFIER LETTER SMALL Z;Lm;0;L; 007A;;;;N;;;;; +1DBC;MODIFIER LETTER SMALL Z WITH RETROFLEX HOOK;Lm;0;L; 0290;;;;N;;;;; +1DBD;MODIFIER LETTER SMALL Z WITH CURL;Lm;0;L; 0291;;;;N;;;;; +1DBE;MODIFIER LETTER SMALL EZH;Lm;0;L; 0292;;;;N;;;;; +1DBF;MODIFIER LETTER SMALL THETA;Lm;0;L; 03B8;;;;N;;;;; +1DC0;COMBINING DOTTED GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;; +1DC1;COMBINING DOTTED ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;; +1DC2;COMBINING SNAKE BELOW;Mn;220;NSM;;;;;N;;;;; +1DC3;COMBINING SUSPENSION MARK;Mn;230;NSM;;;;;N;;;;; +1DC4;COMBINING MACRON-ACUTE;Mn;230;NSM;;;;;N;;;;; +1DC5;COMBINING GRAVE-MACRON;Mn;230;NSM;;;;;N;;;;; +1DC6;COMBINING MACRON-GRAVE;Mn;230;NSM;;;;;N;;;;; +1DC7;COMBINING ACUTE-MACRON;Mn;230;NSM;;;;;N;;;;; +1DC8;COMBINING GRAVE-ACUTE-GRAVE;Mn;230;NSM;;;;;N;;;;; +1DC9;COMBINING ACUTE-GRAVE-ACUTE;Mn;230;NSM;;;;;N;;;;; +1DCA;COMBINING LATIN SMALL LETTER R BELOW;Mn;220;NSM;;;;;N;;;;; +1DCB;COMBINING BREVE-MACRON;Mn;230;NSM;;;;;N;;;;; +1DCC;COMBINING MACRON-BREVE;Mn;230;NSM;;;;;N;;;;; +1DCD;COMBINING DOUBLE CIRCUMFLEX ABOVE;Mn;234;NSM;;;;;N;;;;; +1DCE;COMBINING OGONEK ABOVE;Mn;214;NSM;;;;;N;;;;; +1DCF;COMBINING ZIGZAG BELOW;Mn;220;NSM;;;;;N;;;;; +1DD0;COMBINING IS BELOW;Mn;202;NSM;;;;;N;;;;; +1DD1;COMBINING UR ABOVE;Mn;230;NSM;;;;;N;;;;; +1DD2;COMBINING US ABOVE;Mn;230;NSM;;;;;N;;;;; +1DD3;COMBINING LATIN SMALL LETTER FLATTENED OPEN A ABOVE;Mn;230;NSM;;;;;N;;;;; +1DD4;COMBINING LATIN SMALL LETTER AE;Mn;230;NSM;;;;;N;;;;; +1DD5;COMBINING LATIN SMALL LETTER AO;Mn;230;NSM;;;;;N;;;;; +1DD6;COMBINING LATIN SMALL LETTER AV;Mn;230;NSM;;;;;N;;;;; +1DD7;COMBINING LATIN SMALL LETTER C CEDILLA;Mn;230;NSM;;;;;N;;;;; +1DD8;COMBINING LATIN SMALL LETTER INSULAR D;Mn;230;NSM;;;;;N;;;;; +1DD9;COMBINING LATIN SMALL LETTER ETH;Mn;230;NSM;;;;;N;;;;; +1DDA;COMBINING LATIN SMALL LETTER G;Mn;230;NSM;;;;;N;;;;; +1DDB;COMBINING LATIN LETTER SMALL CAPITAL G;Mn;230;NSM;;;;;N;;;;; +1DDC;COMBINING LATIN SMALL LETTER K;Mn;230;NSM;;;;;N;;;;; +1DDD;COMBINING LATIN SMALL LETTER L;Mn;230;NSM;;;;;N;;;;; +1DDE;COMBINING LATIN LETTER SMALL CAPITAL L;Mn;230;NSM;;;;;N;;;;; +1DDF;COMBINING LATIN LETTER SMALL CAPITAL M;Mn;230;NSM;;;;;N;;;;; +1DE0;COMBINING LATIN SMALL LETTER N;Mn;230;NSM;;;;;N;;;;; +1DE1;COMBINING LATIN LETTER SMALL CAPITAL N;Mn;230;NSM;;;;;N;;;;; +1DE2;COMBINING LATIN LETTER SMALL CAPITAL R;Mn;230;NSM;;;;;N;;;;; +1DE3;COMBINING LATIN SMALL LETTER R ROTUNDA;Mn;230;NSM;;;;;N;;;;; +1DE4;COMBINING LATIN SMALL LETTER S;Mn;230;NSM;;;;;N;;;;; +1DE5;COMBINING LATIN SMALL LETTER LONG S;Mn;230;NSM;;;;;N;;;;; +1DE6;COMBINING LATIN SMALL LETTER Z;Mn;230;NSM;;;;;N;;;;; +1DE7;COMBINING LATIN SMALL LETTER ALPHA;Mn;230;NSM;;;;;N;;;;; +1DE8;COMBINING LATIN SMALL LETTER B;Mn;230;NSM;;;;;N;;;;; +1DE9;COMBINING LATIN SMALL LETTER BETA;Mn;230;NSM;;;;;N;;;;; +1DEA;COMBINING LATIN SMALL LETTER SCHWA;Mn;230;NSM;;;;;N;;;;; +1DEB;COMBINING LATIN SMALL LETTER F;Mn;230;NSM;;;;;N;;;;; +1DEC;COMBINING LATIN SMALL LETTER L WITH DOUBLE MIDDLE TILDE;Mn;230;NSM;;;;;N;;;;; +1DED;COMBINING LATIN SMALL LETTER O WITH LIGHT CENTRALIZATION STROKE;Mn;230;NSM;;;;;N;;;;; +1DEE;COMBINING LATIN SMALL LETTER P;Mn;230;NSM;;;;;N;;;;; +1DEF;COMBINING LATIN SMALL LETTER ESH;Mn;230;NSM;;;;;N;;;;; +1DF0;COMBINING LATIN SMALL LETTER U WITH LIGHT CENTRALIZATION STROKE;Mn;230;NSM;;;;;N;;;;; +1DF1;COMBINING LATIN SMALL LETTER W;Mn;230;NSM;;;;;N;;;;; +1DF2;COMBINING LATIN SMALL LETTER A WITH DIAERESIS;Mn;230;NSM;;;;;N;;;;; +1DF3;COMBINING LATIN SMALL LETTER O WITH DIAERESIS;Mn;230;NSM;;;;;N;;;;; +1DF4;COMBINING LATIN SMALL LETTER U WITH DIAERESIS;Mn;230;NSM;;;;;N;;;;; +1DF5;COMBINING UP TACK ABOVE;Mn;230;NSM;;;;;N;;;;; +1DF6;COMBINING KAVYKA ABOVE RIGHT;Mn;232;NSM;;;;;N;;;;; +1DF7;COMBINING KAVYKA ABOVE LEFT;Mn;228;NSM;;;;;N;;;;; +1DF8;COMBINING DOT ABOVE LEFT;Mn;228;NSM;;;;;N;;;;; +1DF9;COMBINING WIDE INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;;;;; +1DFB;COMBINING DELETION MARK;Mn;230;NSM;;;;;N;;;;; +1DFC;COMBINING DOUBLE INVERTED BREVE BELOW;Mn;233;NSM;;;;;N;;;;; +1DFD;COMBINING ALMOST EQUAL TO BELOW;Mn;220;NSM;;;;;N;;;;; +1DFE;COMBINING LEFT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;; +1DFF;COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;; +1E00;LATIN CAPITAL LETTER A WITH RING BELOW;Lu;0;L;0041 0325;;;;N;;;;1E01; +1E01;LATIN SMALL LETTER A WITH RING BELOW;Ll;0;L;0061 0325;;;;N;;;1E00;;1E00 +1E02;LATIN CAPITAL LETTER B WITH DOT ABOVE;Lu;0;L;0042 0307;;;;N;;;;1E03; +1E03;LATIN SMALL LETTER B WITH DOT ABOVE;Ll;0;L;0062 0307;;;;N;;;1E02;;1E02 +1E04;LATIN CAPITAL LETTER B WITH DOT BELOW;Lu;0;L;0042 0323;;;;N;;;;1E05; +1E05;LATIN SMALL LETTER B WITH DOT BELOW;Ll;0;L;0062 0323;;;;N;;;1E04;;1E04 +1E06;LATIN CAPITAL LETTER B WITH LINE BELOW;Lu;0;L;0042 0331;;;;N;;;;1E07; +1E07;LATIN SMALL LETTER B WITH LINE BELOW;Ll;0;L;0062 0331;;;;N;;;1E06;;1E06 +1E08;LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE;Lu;0;L;00C7 0301;;;;N;;;;1E09; +1E09;LATIN SMALL LETTER C WITH CEDILLA AND ACUTE;Ll;0;L;00E7 0301;;;;N;;;1E08;;1E08 +1E0A;LATIN CAPITAL LETTER D WITH DOT ABOVE;Lu;0;L;0044 0307;;;;N;;;;1E0B; +1E0B;LATIN SMALL LETTER D WITH DOT ABOVE;Ll;0;L;0064 0307;;;;N;;;1E0A;;1E0A +1E0C;LATIN CAPITAL LETTER D WITH DOT BELOW;Lu;0;L;0044 0323;;;;N;;;;1E0D; +1E0D;LATIN SMALL LETTER D WITH DOT BELOW;Ll;0;L;0064 0323;;;;N;;;1E0C;;1E0C +1E0E;LATIN CAPITAL LETTER D WITH LINE BELOW;Lu;0;L;0044 0331;;;;N;;;;1E0F; +1E0F;LATIN SMALL LETTER D WITH LINE BELOW;Ll;0;L;0064 0331;;;;N;;;1E0E;;1E0E +1E10;LATIN CAPITAL LETTER D WITH CEDILLA;Lu;0;L;0044 0327;;;;N;;;;1E11; +1E11;LATIN SMALL LETTER D WITH CEDILLA;Ll;0;L;0064 0327;;;;N;;;1E10;;1E10 +1E12;LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW;Lu;0;L;0044 032D;;;;N;;;;1E13; +1E13;LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW;Ll;0;L;0064 032D;;;;N;;;1E12;;1E12 +1E14;LATIN CAPITAL LETTER E WITH MACRON AND GRAVE;Lu;0;L;0112 0300;;;;N;;;;1E15; +1E15;LATIN SMALL LETTER E WITH MACRON AND GRAVE;Ll;0;L;0113 0300;;;;N;;;1E14;;1E14 +1E16;LATIN CAPITAL LETTER E WITH MACRON AND ACUTE;Lu;0;L;0112 0301;;;;N;;;;1E17; +1E17;LATIN SMALL LETTER E WITH MACRON AND ACUTE;Ll;0;L;0113 0301;;;;N;;;1E16;;1E16 +1E18;LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW;Lu;0;L;0045 032D;;;;N;;;;1E19; +1E19;LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW;Ll;0;L;0065 032D;;;;N;;;1E18;;1E18 +1E1A;LATIN CAPITAL LETTER E WITH TILDE BELOW;Lu;0;L;0045 0330;;;;N;;;;1E1B; +1E1B;LATIN SMALL LETTER E WITH TILDE BELOW;Ll;0;L;0065 0330;;;;N;;;1E1A;;1E1A +1E1C;LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE;Lu;0;L;0228 0306;;;;N;;;;1E1D; +1E1D;LATIN SMALL LETTER E WITH CEDILLA AND BREVE;Ll;0;L;0229 0306;;;;N;;;1E1C;;1E1C +1E1E;LATIN CAPITAL LETTER F WITH DOT ABOVE;Lu;0;L;0046 0307;;;;N;;;;1E1F; +1E1F;LATIN SMALL LETTER F WITH DOT ABOVE;Ll;0;L;0066 0307;;;;N;;;1E1E;;1E1E +1E20;LATIN CAPITAL LETTER G WITH MACRON;Lu;0;L;0047 0304;;;;N;;;;1E21; +1E21;LATIN SMALL LETTER G WITH MACRON;Ll;0;L;0067 0304;;;;N;;;1E20;;1E20 +1E22;LATIN CAPITAL LETTER H WITH DOT ABOVE;Lu;0;L;0048 0307;;;;N;;;;1E23; +1E23;LATIN SMALL LETTER H WITH DOT ABOVE;Ll;0;L;0068 0307;;;;N;;;1E22;;1E22 +1E24;LATIN CAPITAL LETTER H WITH DOT BELOW;Lu;0;L;0048 0323;;;;N;;;;1E25; +1E25;LATIN SMALL LETTER H WITH DOT BELOW;Ll;0;L;0068 0323;;;;N;;;1E24;;1E24 +1E26;LATIN CAPITAL LETTER H WITH DIAERESIS;Lu;0;L;0048 0308;;;;N;;;;1E27; +1E27;LATIN SMALL LETTER H WITH DIAERESIS;Ll;0;L;0068 0308;;;;N;;;1E26;;1E26 +1E28;LATIN CAPITAL LETTER H WITH CEDILLA;Lu;0;L;0048 0327;;;;N;;;;1E29; +1E29;LATIN SMALL LETTER H WITH CEDILLA;Ll;0;L;0068 0327;;;;N;;;1E28;;1E28 +1E2A;LATIN CAPITAL LETTER H WITH BREVE BELOW;Lu;0;L;0048 032E;;;;N;;;;1E2B; +1E2B;LATIN SMALL LETTER H WITH BREVE BELOW;Ll;0;L;0068 032E;;;;N;;;1E2A;;1E2A +1E2C;LATIN CAPITAL LETTER I WITH TILDE BELOW;Lu;0;L;0049 0330;;;;N;;;;1E2D; +1E2D;LATIN SMALL LETTER I WITH TILDE BELOW;Ll;0;L;0069 0330;;;;N;;;1E2C;;1E2C +1E2E;LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE;Lu;0;L;00CF 0301;;;;N;;;;1E2F; +1E2F;LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE;Ll;0;L;00EF 0301;;;;N;;;1E2E;;1E2E +1E30;LATIN CAPITAL LETTER K WITH ACUTE;Lu;0;L;004B 0301;;;;N;;;;1E31; +1E31;LATIN SMALL LETTER K WITH ACUTE;Ll;0;L;006B 0301;;;;N;;;1E30;;1E30 +1E32;LATIN CAPITAL LETTER K WITH DOT BELOW;Lu;0;L;004B 0323;;;;N;;;;1E33; +1E33;LATIN SMALL LETTER K WITH DOT BELOW;Ll;0;L;006B 0323;;;;N;;;1E32;;1E32 +1E34;LATIN CAPITAL LETTER K WITH LINE BELOW;Lu;0;L;004B 0331;;;;N;;;;1E35; +1E35;LATIN SMALL LETTER K WITH LINE BELOW;Ll;0;L;006B 0331;;;;N;;;1E34;;1E34 +1E36;LATIN CAPITAL LETTER L WITH DOT BELOW;Lu;0;L;004C 0323;;;;N;;;;1E37; +1E37;LATIN SMALL LETTER L WITH DOT BELOW;Ll;0;L;006C 0323;;;;N;;;1E36;;1E36 +1E38;LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON;Lu;0;L;1E36 0304;;;;N;;;;1E39; +1E39;LATIN SMALL LETTER L WITH DOT BELOW AND MACRON;Ll;0;L;1E37 0304;;;;N;;;1E38;;1E38 +1E3A;LATIN CAPITAL LETTER L WITH LINE BELOW;Lu;0;L;004C 0331;;;;N;;;;1E3B; +1E3B;LATIN SMALL LETTER L WITH LINE BELOW;Ll;0;L;006C 0331;;;;N;;;1E3A;;1E3A +1E3C;LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW;Lu;0;L;004C 032D;;;;N;;;;1E3D; +1E3D;LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW;Ll;0;L;006C 032D;;;;N;;;1E3C;;1E3C +1E3E;LATIN CAPITAL LETTER M WITH ACUTE;Lu;0;L;004D 0301;;;;N;;;;1E3F; +1E3F;LATIN SMALL LETTER M WITH ACUTE;Ll;0;L;006D 0301;;;;N;;;1E3E;;1E3E +1E40;LATIN CAPITAL LETTER M WITH DOT ABOVE;Lu;0;L;004D 0307;;;;N;;;;1E41; +1E41;LATIN SMALL LETTER M WITH DOT ABOVE;Ll;0;L;006D 0307;;;;N;;;1E40;;1E40 +1E42;LATIN CAPITAL LETTER M WITH DOT BELOW;Lu;0;L;004D 0323;;;;N;;;;1E43; +1E43;LATIN SMALL LETTER M WITH DOT BELOW;Ll;0;L;006D 0323;;;;N;;;1E42;;1E42 +1E44;LATIN CAPITAL LETTER N WITH DOT ABOVE;Lu;0;L;004E 0307;;;;N;;;;1E45; +1E45;LATIN SMALL LETTER N WITH DOT ABOVE;Ll;0;L;006E 0307;;;;N;;;1E44;;1E44 +1E46;LATIN CAPITAL LETTER N WITH DOT BELOW;Lu;0;L;004E 0323;;;;N;;;;1E47; +1E47;LATIN SMALL LETTER N WITH DOT BELOW;Ll;0;L;006E 0323;;;;N;;;1E46;;1E46 +1E48;LATIN CAPITAL LETTER N WITH LINE BELOW;Lu;0;L;004E 0331;;;;N;;;;1E49; +1E49;LATIN SMALL LETTER N WITH LINE BELOW;Ll;0;L;006E 0331;;;;N;;;1E48;;1E48 +1E4A;LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW;Lu;0;L;004E 032D;;;;N;;;;1E4B; +1E4B;LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW;Ll;0;L;006E 032D;;;;N;;;1E4A;;1E4A +1E4C;LATIN CAPITAL LETTER O WITH TILDE AND ACUTE;Lu;0;L;00D5 0301;;;;N;;;;1E4D; +1E4D;LATIN SMALL LETTER O WITH TILDE AND ACUTE;Ll;0;L;00F5 0301;;;;N;;;1E4C;;1E4C +1E4E;LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS;Lu;0;L;00D5 0308;;;;N;;;;1E4F; +1E4F;LATIN SMALL LETTER O WITH TILDE AND DIAERESIS;Ll;0;L;00F5 0308;;;;N;;;1E4E;;1E4E +1E50;LATIN CAPITAL LETTER O WITH MACRON AND GRAVE;Lu;0;L;014C 0300;;;;N;;;;1E51; +1E51;LATIN SMALL LETTER O WITH MACRON AND GRAVE;Ll;0;L;014D 0300;;;;N;;;1E50;;1E50 +1E52;LATIN CAPITAL LETTER O WITH MACRON AND ACUTE;Lu;0;L;014C 0301;;;;N;;;;1E53; +1E53;LATIN SMALL LETTER O WITH MACRON AND ACUTE;Ll;0;L;014D 0301;;;;N;;;1E52;;1E52 +1E54;LATIN CAPITAL LETTER P WITH ACUTE;Lu;0;L;0050 0301;;;;N;;;;1E55; +1E55;LATIN SMALL LETTER P WITH ACUTE;Ll;0;L;0070 0301;;;;N;;;1E54;;1E54 +1E56;LATIN CAPITAL LETTER P WITH DOT ABOVE;Lu;0;L;0050 0307;;;;N;;;;1E57; +1E57;LATIN SMALL LETTER P WITH DOT ABOVE;Ll;0;L;0070 0307;;;;N;;;1E56;;1E56 +1E58;LATIN CAPITAL LETTER R WITH DOT ABOVE;Lu;0;L;0052 0307;;;;N;;;;1E59; +1E59;LATIN SMALL LETTER R WITH DOT ABOVE;Ll;0;L;0072 0307;;;;N;;;1E58;;1E58 +1E5A;LATIN CAPITAL LETTER R WITH DOT BELOW;Lu;0;L;0052 0323;;;;N;;;;1E5B; +1E5B;LATIN SMALL LETTER R WITH DOT BELOW;Ll;0;L;0072 0323;;;;N;;;1E5A;;1E5A +1E5C;LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON;Lu;0;L;1E5A 0304;;;;N;;;;1E5D; +1E5D;LATIN SMALL LETTER R WITH DOT BELOW AND MACRON;Ll;0;L;1E5B 0304;;;;N;;;1E5C;;1E5C +1E5E;LATIN CAPITAL LETTER R WITH LINE BELOW;Lu;0;L;0052 0331;;;;N;;;;1E5F; +1E5F;LATIN SMALL LETTER R WITH LINE BELOW;Ll;0;L;0072 0331;;;;N;;;1E5E;;1E5E +1E60;LATIN CAPITAL LETTER S WITH DOT ABOVE;Lu;0;L;0053 0307;;;;N;;;;1E61; +1E61;LATIN SMALL LETTER S WITH DOT ABOVE;Ll;0;L;0073 0307;;;;N;;;1E60;;1E60 +1E62;LATIN CAPITAL LETTER S WITH DOT BELOW;Lu;0;L;0053 0323;;;;N;;;;1E63; +1E63;LATIN SMALL LETTER S WITH DOT BELOW;Ll;0;L;0073 0323;;;;N;;;1E62;;1E62 +1E64;LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE;Lu;0;L;015A 0307;;;;N;;;;1E65; +1E65;LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE;Ll;0;L;015B 0307;;;;N;;;1E64;;1E64 +1E66;LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE;Lu;0;L;0160 0307;;;;N;;;;1E67; +1E67;LATIN SMALL LETTER S WITH CARON AND DOT ABOVE;Ll;0;L;0161 0307;;;;N;;;1E66;;1E66 +1E68;LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE;Lu;0;L;1E62 0307;;;;N;;;;1E69; +1E69;LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE;Ll;0;L;1E63 0307;;;;N;;;1E68;;1E68 +1E6A;LATIN CAPITAL LETTER T WITH DOT ABOVE;Lu;0;L;0054 0307;;;;N;;;;1E6B; +1E6B;LATIN SMALL LETTER T WITH DOT ABOVE;Ll;0;L;0074 0307;;;;N;;;1E6A;;1E6A +1E6C;LATIN CAPITAL LETTER T WITH DOT BELOW;Lu;0;L;0054 0323;;;;N;;;;1E6D; +1E6D;LATIN SMALL LETTER T WITH DOT BELOW;Ll;0;L;0074 0323;;;;N;;;1E6C;;1E6C +1E6E;LATIN CAPITAL LETTER T WITH LINE BELOW;Lu;0;L;0054 0331;;;;N;;;;1E6F; +1E6F;LATIN SMALL LETTER T WITH LINE BELOW;Ll;0;L;0074 0331;;;;N;;;1E6E;;1E6E +1E70;LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW;Lu;0;L;0054 032D;;;;N;;;;1E71; +1E71;LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW;Ll;0;L;0074 032D;;;;N;;;1E70;;1E70 +1E72;LATIN CAPITAL LETTER U WITH DIAERESIS BELOW;Lu;0;L;0055 0324;;;;N;;;;1E73; +1E73;LATIN SMALL LETTER U WITH DIAERESIS BELOW;Ll;0;L;0075 0324;;;;N;;;1E72;;1E72 +1E74;LATIN CAPITAL LETTER U WITH TILDE BELOW;Lu;0;L;0055 0330;;;;N;;;;1E75; +1E75;LATIN SMALL LETTER U WITH TILDE BELOW;Ll;0;L;0075 0330;;;;N;;;1E74;;1E74 +1E76;LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW;Lu;0;L;0055 032D;;;;N;;;;1E77; +1E77;LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW;Ll;0;L;0075 032D;;;;N;;;1E76;;1E76 +1E78;LATIN CAPITAL LETTER U WITH TILDE AND ACUTE;Lu;0;L;0168 0301;;;;N;;;;1E79; +1E79;LATIN SMALL LETTER U WITH TILDE AND ACUTE;Ll;0;L;0169 0301;;;;N;;;1E78;;1E78 +1E7A;LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS;Lu;0;L;016A 0308;;;;N;;;;1E7B; +1E7B;LATIN SMALL LETTER U WITH MACRON AND DIAERESIS;Ll;0;L;016B 0308;;;;N;;;1E7A;;1E7A +1E7C;LATIN CAPITAL LETTER V WITH TILDE;Lu;0;L;0056 0303;;;;N;;;;1E7D; +1E7D;LATIN SMALL LETTER V WITH TILDE;Ll;0;L;0076 0303;;;;N;;;1E7C;;1E7C +1E7E;LATIN CAPITAL LETTER V WITH DOT BELOW;Lu;0;L;0056 0323;;;;N;;;;1E7F; +1E7F;LATIN SMALL LETTER V WITH DOT BELOW;Ll;0;L;0076 0323;;;;N;;;1E7E;;1E7E +1E80;LATIN CAPITAL LETTER W WITH GRAVE;Lu;0;L;0057 0300;;;;N;;;;1E81; +1E81;LATIN SMALL LETTER W WITH GRAVE;Ll;0;L;0077 0300;;;;N;;;1E80;;1E80 +1E82;LATIN CAPITAL LETTER W WITH ACUTE;Lu;0;L;0057 0301;;;;N;;;;1E83; +1E83;LATIN SMALL LETTER W WITH ACUTE;Ll;0;L;0077 0301;;;;N;;;1E82;;1E82 +1E84;LATIN CAPITAL LETTER W WITH DIAERESIS;Lu;0;L;0057 0308;;;;N;;;;1E85; +1E85;LATIN SMALL LETTER W WITH DIAERESIS;Ll;0;L;0077 0308;;;;N;;;1E84;;1E84 +1E86;LATIN CAPITAL LETTER W WITH DOT ABOVE;Lu;0;L;0057 0307;;;;N;;;;1E87; +1E87;LATIN SMALL LETTER W WITH DOT ABOVE;Ll;0;L;0077 0307;;;;N;;;1E86;;1E86 +1E88;LATIN CAPITAL LETTER W WITH DOT BELOW;Lu;0;L;0057 0323;;;;N;;;;1E89; +1E89;LATIN SMALL LETTER W WITH DOT BELOW;Ll;0;L;0077 0323;;;;N;;;1E88;;1E88 +1E8A;LATIN CAPITAL LETTER X WITH DOT ABOVE;Lu;0;L;0058 0307;;;;N;;;;1E8B; +1E8B;LATIN SMALL LETTER X WITH DOT ABOVE;Ll;0;L;0078 0307;;;;N;;;1E8A;;1E8A +1E8C;LATIN CAPITAL LETTER X WITH DIAERESIS;Lu;0;L;0058 0308;;;;N;;;;1E8D; +1E8D;LATIN SMALL LETTER X WITH DIAERESIS;Ll;0;L;0078 0308;;;;N;;;1E8C;;1E8C +1E8E;LATIN CAPITAL LETTER Y WITH DOT ABOVE;Lu;0;L;0059 0307;;;;N;;;;1E8F; +1E8F;LATIN SMALL LETTER Y WITH DOT ABOVE;Ll;0;L;0079 0307;;;;N;;;1E8E;;1E8E +1E90;LATIN CAPITAL LETTER Z WITH CIRCUMFLEX;Lu;0;L;005A 0302;;;;N;;;;1E91; +1E91;LATIN SMALL LETTER Z WITH CIRCUMFLEX;Ll;0;L;007A 0302;;;;N;;;1E90;;1E90 +1E92;LATIN CAPITAL LETTER Z WITH DOT BELOW;Lu;0;L;005A 0323;;;;N;;;;1E93; +1E93;LATIN SMALL LETTER Z WITH DOT BELOW;Ll;0;L;007A 0323;;;;N;;;1E92;;1E92 +1E94;LATIN CAPITAL LETTER Z WITH LINE BELOW;Lu;0;L;005A 0331;;;;N;;;;1E95; +1E95;LATIN SMALL LETTER Z WITH LINE BELOW;Ll;0;L;007A 0331;;;;N;;;1E94;;1E94 +1E96;LATIN SMALL LETTER H WITH LINE BELOW;Ll;0;L;0068 0331;;;;N;;;;; +1E97;LATIN SMALL LETTER T WITH DIAERESIS;Ll;0;L;0074 0308;;;;N;;;;; +1E98;LATIN SMALL LETTER W WITH RING ABOVE;Ll;0;L;0077 030A;;;;N;;;;; +1E99;LATIN SMALL LETTER Y WITH RING ABOVE;Ll;0;L;0079 030A;;;;N;;;;; +1E9A;LATIN SMALL LETTER A WITH RIGHT HALF RING;Ll;0;L; 0061 02BE;;;;N;;;;; +1E9B;LATIN SMALL LETTER LONG S WITH DOT ABOVE;Ll;0;L;017F 0307;;;;N;;;1E60;;1E60 +1E9C;LATIN SMALL LETTER LONG S WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;;; +1E9D;LATIN SMALL LETTER LONG S WITH HIGH STROKE;Ll;0;L;;;;;N;;;;; +1E9E;LATIN CAPITAL LETTER SHARP S;Lu;0;L;;;;;N;;;;00DF; +1E9F;LATIN SMALL LETTER DELTA;Ll;0;L;;;;;N;;;;; +1EA0;LATIN CAPITAL LETTER A WITH DOT BELOW;Lu;0;L;0041 0323;;;;N;;;;1EA1; +1EA1;LATIN SMALL LETTER A WITH DOT BELOW;Ll;0;L;0061 0323;;;;N;;;1EA0;;1EA0 +1EA2;LATIN CAPITAL LETTER A WITH HOOK ABOVE;Lu;0;L;0041 0309;;;;N;;;;1EA3; +1EA3;LATIN SMALL LETTER A WITH HOOK ABOVE;Ll;0;L;0061 0309;;;;N;;;1EA2;;1EA2 +1EA4;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00C2 0301;;;;N;;;;1EA5; +1EA5;LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00E2 0301;;;;N;;;1EA4;;1EA4 +1EA6;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00C2 0300;;;;N;;;;1EA7; +1EA7;LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00E2 0300;;;;N;;;1EA6;;1EA6 +1EA8;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00C2 0309;;;;N;;;;1EA9; +1EA9;LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00E2 0309;;;;N;;;1EA8;;1EA8 +1EAA;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE;Lu;0;L;00C2 0303;;;;N;;;;1EAB; +1EAB;LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE;Ll;0;L;00E2 0303;;;;N;;;1EAA;;1EAA +1EAC;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EA0 0302;;;;N;;;;1EAD; +1EAD;LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EA1 0302;;;;N;;;1EAC;;1EAC +1EAE;LATIN CAPITAL LETTER A WITH BREVE AND ACUTE;Lu;0;L;0102 0301;;;;N;;;;1EAF; +1EAF;LATIN SMALL LETTER A WITH BREVE AND ACUTE;Ll;0;L;0103 0301;;;;N;;;1EAE;;1EAE +1EB0;LATIN CAPITAL LETTER A WITH BREVE AND GRAVE;Lu;0;L;0102 0300;;;;N;;;;1EB1; +1EB1;LATIN SMALL LETTER A WITH BREVE AND GRAVE;Ll;0;L;0103 0300;;;;N;;;1EB0;;1EB0 +1EB2;LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE;Lu;0;L;0102 0309;;;;N;;;;1EB3; +1EB3;LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE;Ll;0;L;0103 0309;;;;N;;;1EB2;;1EB2 +1EB4;LATIN CAPITAL LETTER A WITH BREVE AND TILDE;Lu;0;L;0102 0303;;;;N;;;;1EB5; +1EB5;LATIN SMALL LETTER A WITH BREVE AND TILDE;Ll;0;L;0103 0303;;;;N;;;1EB4;;1EB4 +1EB6;LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW;Lu;0;L;1EA0 0306;;;;N;;;;1EB7; +1EB7;LATIN SMALL LETTER A WITH BREVE AND DOT BELOW;Ll;0;L;1EA1 0306;;;;N;;;1EB6;;1EB6 +1EB8;LATIN CAPITAL LETTER E WITH DOT BELOW;Lu;0;L;0045 0323;;;;N;;;;1EB9; +1EB9;LATIN SMALL LETTER E WITH DOT BELOW;Ll;0;L;0065 0323;;;;N;;;1EB8;;1EB8 +1EBA;LATIN CAPITAL LETTER E WITH HOOK ABOVE;Lu;0;L;0045 0309;;;;N;;;;1EBB; +1EBB;LATIN SMALL LETTER E WITH HOOK ABOVE;Ll;0;L;0065 0309;;;;N;;;1EBA;;1EBA +1EBC;LATIN CAPITAL LETTER E WITH TILDE;Lu;0;L;0045 0303;;;;N;;;;1EBD; +1EBD;LATIN SMALL LETTER E WITH TILDE;Ll;0;L;0065 0303;;;;N;;;1EBC;;1EBC +1EBE;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00CA 0301;;;;N;;;;1EBF; +1EBF;LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00EA 0301;;;;N;;;1EBE;;1EBE +1EC0;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00CA 0300;;;;N;;;;1EC1; +1EC1;LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00EA 0300;;;;N;;;1EC0;;1EC0 +1EC2;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00CA 0309;;;;N;;;;1EC3; +1EC3;LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00EA 0309;;;;N;;;1EC2;;1EC2 +1EC4;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE;Lu;0;L;00CA 0303;;;;N;;;;1EC5; +1EC5;LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE;Ll;0;L;00EA 0303;;;;N;;;1EC4;;1EC4 +1EC6;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EB8 0302;;;;N;;;;1EC7; +1EC7;LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EB9 0302;;;;N;;;1EC6;;1EC6 +1EC8;LATIN CAPITAL LETTER I WITH HOOK ABOVE;Lu;0;L;0049 0309;;;;N;;;;1EC9; +1EC9;LATIN SMALL LETTER I WITH HOOK ABOVE;Ll;0;L;0069 0309;;;;N;;;1EC8;;1EC8 +1ECA;LATIN CAPITAL LETTER I WITH DOT BELOW;Lu;0;L;0049 0323;;;;N;;;;1ECB; +1ECB;LATIN SMALL LETTER I WITH DOT BELOW;Ll;0;L;0069 0323;;;;N;;;1ECA;;1ECA +1ECC;LATIN CAPITAL LETTER O WITH DOT BELOW;Lu;0;L;004F 0323;;;;N;;;;1ECD; +1ECD;LATIN SMALL LETTER O WITH DOT BELOW;Ll;0;L;006F 0323;;;;N;;;1ECC;;1ECC +1ECE;LATIN CAPITAL LETTER O WITH HOOK ABOVE;Lu;0;L;004F 0309;;;;N;;;;1ECF; +1ECF;LATIN SMALL LETTER O WITH HOOK ABOVE;Ll;0;L;006F 0309;;;;N;;;1ECE;;1ECE +1ED0;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00D4 0301;;;;N;;;;1ED1; +1ED1;LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00F4 0301;;;;N;;;1ED0;;1ED0 +1ED2;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00D4 0300;;;;N;;;;1ED3; +1ED3;LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00F4 0300;;;;N;;;1ED2;;1ED2 +1ED4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00D4 0309;;;;N;;;;1ED5; +1ED5;LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00F4 0309;;;;N;;;1ED4;;1ED4 +1ED6;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE;Lu;0;L;00D4 0303;;;;N;;;;1ED7; +1ED7;LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE;Ll;0;L;00F4 0303;;;;N;;;1ED6;;1ED6 +1ED8;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1ECC 0302;;;;N;;;;1ED9; +1ED9;LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1ECD 0302;;;;N;;;1ED8;;1ED8 +1EDA;LATIN CAPITAL LETTER O WITH HORN AND ACUTE;Lu;0;L;01A0 0301;;;;N;;;;1EDB; +1EDB;LATIN SMALL LETTER O WITH HORN AND ACUTE;Ll;0;L;01A1 0301;;;;N;;;1EDA;;1EDA +1EDC;LATIN CAPITAL LETTER O WITH HORN AND GRAVE;Lu;0;L;01A0 0300;;;;N;;;;1EDD; +1EDD;LATIN SMALL LETTER O WITH HORN AND GRAVE;Ll;0;L;01A1 0300;;;;N;;;1EDC;;1EDC +1EDE;LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE;Lu;0;L;01A0 0309;;;;N;;;;1EDF; +1EDF;LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE;Ll;0;L;01A1 0309;;;;N;;;1EDE;;1EDE +1EE0;LATIN CAPITAL LETTER O WITH HORN AND TILDE;Lu;0;L;01A0 0303;;;;N;;;;1EE1; +1EE1;LATIN SMALL LETTER O WITH HORN AND TILDE;Ll;0;L;01A1 0303;;;;N;;;1EE0;;1EE0 +1EE2;LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW;Lu;0;L;01A0 0323;;;;N;;;;1EE3; +1EE3;LATIN SMALL LETTER O WITH HORN AND DOT BELOW;Ll;0;L;01A1 0323;;;;N;;;1EE2;;1EE2 +1EE4;LATIN CAPITAL LETTER U WITH DOT BELOW;Lu;0;L;0055 0323;;;;N;;;;1EE5; +1EE5;LATIN SMALL LETTER U WITH DOT BELOW;Ll;0;L;0075 0323;;;;N;;;1EE4;;1EE4 +1EE6;LATIN CAPITAL LETTER U WITH HOOK ABOVE;Lu;0;L;0055 0309;;;;N;;;;1EE7; +1EE7;LATIN SMALL LETTER U WITH HOOK ABOVE;Ll;0;L;0075 0309;;;;N;;;1EE6;;1EE6 +1EE8;LATIN CAPITAL LETTER U WITH HORN AND ACUTE;Lu;0;L;01AF 0301;;;;N;;;;1EE9; +1EE9;LATIN SMALL LETTER U WITH HORN AND ACUTE;Ll;0;L;01B0 0301;;;;N;;;1EE8;;1EE8 +1EEA;LATIN CAPITAL LETTER U WITH HORN AND GRAVE;Lu;0;L;01AF 0300;;;;N;;;;1EEB; +1EEB;LATIN SMALL LETTER U WITH HORN AND GRAVE;Ll;0;L;01B0 0300;;;;N;;;1EEA;;1EEA +1EEC;LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE;Lu;0;L;01AF 0309;;;;N;;;;1EED; +1EED;LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE;Ll;0;L;01B0 0309;;;;N;;;1EEC;;1EEC +1EEE;LATIN CAPITAL LETTER U WITH HORN AND TILDE;Lu;0;L;01AF 0303;;;;N;;;;1EEF; +1EEF;LATIN SMALL LETTER U WITH HORN AND TILDE;Ll;0;L;01B0 0303;;;;N;;;1EEE;;1EEE +1EF0;LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW;Lu;0;L;01AF 0323;;;;N;;;;1EF1; +1EF1;LATIN SMALL LETTER U WITH HORN AND DOT BELOW;Ll;0;L;01B0 0323;;;;N;;;1EF0;;1EF0 +1EF2;LATIN CAPITAL LETTER Y WITH GRAVE;Lu;0;L;0059 0300;;;;N;;;;1EF3; +1EF3;LATIN SMALL LETTER Y WITH GRAVE;Ll;0;L;0079 0300;;;;N;;;1EF2;;1EF2 +1EF4;LATIN CAPITAL LETTER Y WITH DOT BELOW;Lu;0;L;0059 0323;;;;N;;;;1EF5; +1EF5;LATIN SMALL LETTER Y WITH DOT BELOW;Ll;0;L;0079 0323;;;;N;;;1EF4;;1EF4 +1EF6;LATIN CAPITAL LETTER Y WITH HOOK ABOVE;Lu;0;L;0059 0309;;;;N;;;;1EF7; +1EF7;LATIN SMALL LETTER Y WITH HOOK ABOVE;Ll;0;L;0079 0309;;;;N;;;1EF6;;1EF6 +1EF8;LATIN CAPITAL LETTER Y WITH TILDE;Lu;0;L;0059 0303;;;;N;;;;1EF9; +1EF9;LATIN SMALL LETTER Y WITH TILDE;Ll;0;L;0079 0303;;;;N;;;1EF8;;1EF8 +1EFA;LATIN CAPITAL LETTER MIDDLE-WELSH LL;Lu;0;L;;;;;N;;;;1EFB; +1EFB;LATIN SMALL LETTER MIDDLE-WELSH LL;Ll;0;L;;;;;N;;;1EFA;;1EFA +1EFC;LATIN CAPITAL LETTER MIDDLE-WELSH V;Lu;0;L;;;;;N;;;;1EFD; +1EFD;LATIN SMALL LETTER MIDDLE-WELSH V;Ll;0;L;;;;;N;;;1EFC;;1EFC +1EFE;LATIN CAPITAL LETTER Y WITH LOOP;Lu;0;L;;;;;N;;;;1EFF; +1EFF;LATIN SMALL LETTER Y WITH LOOP;Ll;0;L;;;;;N;;;1EFE;;1EFE +1F00;GREEK SMALL LETTER ALPHA WITH PSILI;Ll;0;L;03B1 0313;;;;N;;;1F08;;1F08 +1F01;GREEK SMALL LETTER ALPHA WITH DASIA;Ll;0;L;03B1 0314;;;;N;;;1F09;;1F09 +1F02;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA;Ll;0;L;1F00 0300;;;;N;;;1F0A;;1F0A +1F03;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA;Ll;0;L;1F01 0300;;;;N;;;1F0B;;1F0B +1F04;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA;Ll;0;L;1F00 0301;;;;N;;;1F0C;;1F0C +1F05;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA;Ll;0;L;1F01 0301;;;;N;;;1F0D;;1F0D +1F06;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI;Ll;0;L;1F00 0342;;;;N;;;1F0E;;1F0E +1F07;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI;Ll;0;L;1F01 0342;;;;N;;;1F0F;;1F0F +1F08;GREEK CAPITAL LETTER ALPHA WITH PSILI;Lu;0;L;0391 0313;;;;N;;;;1F00; +1F09;GREEK CAPITAL LETTER ALPHA WITH DASIA;Lu;0;L;0391 0314;;;;N;;;;1F01; +1F0A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA;Lu;0;L;1F08 0300;;;;N;;;;1F02; +1F0B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA;Lu;0;L;1F09 0300;;;;N;;;;1F03; +1F0C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA;Lu;0;L;1F08 0301;;;;N;;;;1F04; +1F0D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA;Lu;0;L;1F09 0301;;;;N;;;;1F05; +1F0E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI;Lu;0;L;1F08 0342;;;;N;;;;1F06; +1F0F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI;Lu;0;L;1F09 0342;;;;N;;;;1F07; +1F10;GREEK SMALL LETTER EPSILON WITH PSILI;Ll;0;L;03B5 0313;;;;N;;;1F18;;1F18 +1F11;GREEK SMALL LETTER EPSILON WITH DASIA;Ll;0;L;03B5 0314;;;;N;;;1F19;;1F19 +1F12;GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA;Ll;0;L;1F10 0300;;;;N;;;1F1A;;1F1A +1F13;GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA;Ll;0;L;1F11 0300;;;;N;;;1F1B;;1F1B +1F14;GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA;Ll;0;L;1F10 0301;;;;N;;;1F1C;;1F1C +1F15;GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA;Ll;0;L;1F11 0301;;;;N;;;1F1D;;1F1D +1F18;GREEK CAPITAL LETTER EPSILON WITH PSILI;Lu;0;L;0395 0313;;;;N;;;;1F10; +1F19;GREEK CAPITAL LETTER EPSILON WITH DASIA;Lu;0;L;0395 0314;;;;N;;;;1F11; +1F1A;GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA;Lu;0;L;1F18 0300;;;;N;;;;1F12; +1F1B;GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA;Lu;0;L;1F19 0300;;;;N;;;;1F13; +1F1C;GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA;Lu;0;L;1F18 0301;;;;N;;;;1F14; +1F1D;GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA;Lu;0;L;1F19 0301;;;;N;;;;1F15; +1F20;GREEK SMALL LETTER ETA WITH PSILI;Ll;0;L;03B7 0313;;;;N;;;1F28;;1F28 +1F21;GREEK SMALL LETTER ETA WITH DASIA;Ll;0;L;03B7 0314;;;;N;;;1F29;;1F29 +1F22;GREEK SMALL LETTER ETA WITH PSILI AND VARIA;Ll;0;L;1F20 0300;;;;N;;;1F2A;;1F2A +1F23;GREEK SMALL LETTER ETA WITH DASIA AND VARIA;Ll;0;L;1F21 0300;;;;N;;;1F2B;;1F2B +1F24;GREEK SMALL LETTER ETA WITH PSILI AND OXIA;Ll;0;L;1F20 0301;;;;N;;;1F2C;;1F2C +1F25;GREEK SMALL LETTER ETA WITH DASIA AND OXIA;Ll;0;L;1F21 0301;;;;N;;;1F2D;;1F2D +1F26;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI;Ll;0;L;1F20 0342;;;;N;;;1F2E;;1F2E +1F27;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI;Ll;0;L;1F21 0342;;;;N;;;1F2F;;1F2F +1F28;GREEK CAPITAL LETTER ETA WITH PSILI;Lu;0;L;0397 0313;;;;N;;;;1F20; +1F29;GREEK CAPITAL LETTER ETA WITH DASIA;Lu;0;L;0397 0314;;;;N;;;;1F21; +1F2A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA;Lu;0;L;1F28 0300;;;;N;;;;1F22; +1F2B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA;Lu;0;L;1F29 0300;;;;N;;;;1F23; +1F2C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA;Lu;0;L;1F28 0301;;;;N;;;;1F24; +1F2D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA;Lu;0;L;1F29 0301;;;;N;;;;1F25; +1F2E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI;Lu;0;L;1F28 0342;;;;N;;;;1F26; +1F2F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI;Lu;0;L;1F29 0342;;;;N;;;;1F27; +1F30;GREEK SMALL LETTER IOTA WITH PSILI;Ll;0;L;03B9 0313;;;;N;;;1F38;;1F38 +1F31;GREEK SMALL LETTER IOTA WITH DASIA;Ll;0;L;03B9 0314;;;;N;;;1F39;;1F39 +1F32;GREEK SMALL LETTER IOTA WITH PSILI AND VARIA;Ll;0;L;1F30 0300;;;;N;;;1F3A;;1F3A +1F33;GREEK SMALL LETTER IOTA WITH DASIA AND VARIA;Ll;0;L;1F31 0300;;;;N;;;1F3B;;1F3B +1F34;GREEK SMALL LETTER IOTA WITH PSILI AND OXIA;Ll;0;L;1F30 0301;;;;N;;;1F3C;;1F3C +1F35;GREEK SMALL LETTER IOTA WITH DASIA AND OXIA;Ll;0;L;1F31 0301;;;;N;;;1F3D;;1F3D +1F36;GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI;Ll;0;L;1F30 0342;;;;N;;;1F3E;;1F3E +1F37;GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI;Ll;0;L;1F31 0342;;;;N;;;1F3F;;1F3F +1F38;GREEK CAPITAL LETTER IOTA WITH PSILI;Lu;0;L;0399 0313;;;;N;;;;1F30; +1F39;GREEK CAPITAL LETTER IOTA WITH DASIA;Lu;0;L;0399 0314;;;;N;;;;1F31; +1F3A;GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA;Lu;0;L;1F38 0300;;;;N;;;;1F32; +1F3B;GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA;Lu;0;L;1F39 0300;;;;N;;;;1F33; +1F3C;GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA;Lu;0;L;1F38 0301;;;;N;;;;1F34; +1F3D;GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA;Lu;0;L;1F39 0301;;;;N;;;;1F35; +1F3E;GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI;Lu;0;L;1F38 0342;;;;N;;;;1F36; +1F3F;GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI;Lu;0;L;1F39 0342;;;;N;;;;1F37; +1F40;GREEK SMALL LETTER OMICRON WITH PSILI;Ll;0;L;03BF 0313;;;;N;;;1F48;;1F48 +1F41;GREEK SMALL LETTER OMICRON WITH DASIA;Ll;0;L;03BF 0314;;;;N;;;1F49;;1F49 +1F42;GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA;Ll;0;L;1F40 0300;;;;N;;;1F4A;;1F4A +1F43;GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA;Ll;0;L;1F41 0300;;;;N;;;1F4B;;1F4B +1F44;GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA;Ll;0;L;1F40 0301;;;;N;;;1F4C;;1F4C +1F45;GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA;Ll;0;L;1F41 0301;;;;N;;;1F4D;;1F4D +1F48;GREEK CAPITAL LETTER OMICRON WITH PSILI;Lu;0;L;039F 0313;;;;N;;;;1F40; +1F49;GREEK CAPITAL LETTER OMICRON WITH DASIA;Lu;0;L;039F 0314;;;;N;;;;1F41; +1F4A;GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA;Lu;0;L;1F48 0300;;;;N;;;;1F42; +1F4B;GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA;Lu;0;L;1F49 0300;;;;N;;;;1F43; +1F4C;GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA;Lu;0;L;1F48 0301;;;;N;;;;1F44; +1F4D;GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA;Lu;0;L;1F49 0301;;;;N;;;;1F45; +1F50;GREEK SMALL LETTER UPSILON WITH PSILI;Ll;0;L;03C5 0313;;;;N;;;;; +1F51;GREEK SMALL LETTER UPSILON WITH DASIA;Ll;0;L;03C5 0314;;;;N;;;1F59;;1F59 +1F52;GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA;Ll;0;L;1F50 0300;;;;N;;;;; +1F53;GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA;Ll;0;L;1F51 0300;;;;N;;;1F5B;;1F5B +1F54;GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA;Ll;0;L;1F50 0301;;;;N;;;;; +1F55;GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA;Ll;0;L;1F51 0301;;;;N;;;1F5D;;1F5D +1F56;GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI;Ll;0;L;1F50 0342;;;;N;;;;; +1F57;GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI;Ll;0;L;1F51 0342;;;;N;;;1F5F;;1F5F +1F59;GREEK CAPITAL LETTER UPSILON WITH DASIA;Lu;0;L;03A5 0314;;;;N;;;;1F51; +1F5B;GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA;Lu;0;L;1F59 0300;;;;N;;;;1F53; +1F5D;GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA;Lu;0;L;1F59 0301;;;;N;;;;1F55; +1F5F;GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI;Lu;0;L;1F59 0342;;;;N;;;;1F57; +1F60;GREEK SMALL LETTER OMEGA WITH PSILI;Ll;0;L;03C9 0313;;;;N;;;1F68;;1F68 +1F61;GREEK SMALL LETTER OMEGA WITH DASIA;Ll;0;L;03C9 0314;;;;N;;;1F69;;1F69 +1F62;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA;Ll;0;L;1F60 0300;;;;N;;;1F6A;;1F6A +1F63;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA;Ll;0;L;1F61 0300;;;;N;;;1F6B;;1F6B +1F64;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA;Ll;0;L;1F60 0301;;;;N;;;1F6C;;1F6C +1F65;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA;Ll;0;L;1F61 0301;;;;N;;;1F6D;;1F6D +1F66;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI;Ll;0;L;1F60 0342;;;;N;;;1F6E;;1F6E +1F67;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI;Ll;0;L;1F61 0342;;;;N;;;1F6F;;1F6F +1F68;GREEK CAPITAL LETTER OMEGA WITH PSILI;Lu;0;L;03A9 0313;;;;N;;;;1F60; +1F69;GREEK CAPITAL LETTER OMEGA WITH DASIA;Lu;0;L;03A9 0314;;;;N;;;;1F61; +1F6A;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA;Lu;0;L;1F68 0300;;;;N;;;;1F62; +1F6B;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA;Lu;0;L;1F69 0300;;;;N;;;;1F63; +1F6C;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA;Lu;0;L;1F68 0301;;;;N;;;;1F64; +1F6D;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA;Lu;0;L;1F69 0301;;;;N;;;;1F65; +1F6E;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI;Lu;0;L;1F68 0342;;;;N;;;;1F66; +1F6F;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI;Lu;0;L;1F69 0342;;;;N;;;;1F67; +1F70;GREEK SMALL LETTER ALPHA WITH VARIA;Ll;0;L;03B1 0300;;;;N;;;1FBA;;1FBA +1F71;GREEK SMALL LETTER ALPHA WITH OXIA;Ll;0;L;03AC;;;;N;;;1FBB;;1FBB +1F72;GREEK SMALL LETTER EPSILON WITH VARIA;Ll;0;L;03B5 0300;;;;N;;;1FC8;;1FC8 +1F73;GREEK SMALL LETTER EPSILON WITH OXIA;Ll;0;L;03AD;;;;N;;;1FC9;;1FC9 +1F74;GREEK SMALL LETTER ETA WITH VARIA;Ll;0;L;03B7 0300;;;;N;;;1FCA;;1FCA +1F75;GREEK SMALL LETTER ETA WITH OXIA;Ll;0;L;03AE;;;;N;;;1FCB;;1FCB +1F76;GREEK SMALL LETTER IOTA WITH VARIA;Ll;0;L;03B9 0300;;;;N;;;1FDA;;1FDA +1F77;GREEK SMALL LETTER IOTA WITH OXIA;Ll;0;L;03AF;;;;N;;;1FDB;;1FDB +1F78;GREEK SMALL LETTER OMICRON WITH VARIA;Ll;0;L;03BF 0300;;;;N;;;1FF8;;1FF8 +1F79;GREEK SMALL LETTER OMICRON WITH OXIA;Ll;0;L;03CC;;;;N;;;1FF9;;1FF9 +1F7A;GREEK SMALL LETTER UPSILON WITH VARIA;Ll;0;L;03C5 0300;;;;N;;;1FEA;;1FEA +1F7B;GREEK SMALL LETTER UPSILON WITH OXIA;Ll;0;L;03CD;;;;N;;;1FEB;;1FEB +1F7C;GREEK SMALL LETTER OMEGA WITH VARIA;Ll;0;L;03C9 0300;;;;N;;;1FFA;;1FFA +1F7D;GREEK SMALL LETTER OMEGA WITH OXIA;Ll;0;L;03CE;;;;N;;;1FFB;;1FFB +1F80;GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F00 0345;;;;N;;;1F88;;1F88 +1F81;GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F01 0345;;;;N;;;1F89;;1F89 +1F82;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F02 0345;;;;N;;;1F8A;;1F8A +1F83;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F03 0345;;;;N;;;1F8B;;1F8B +1F84;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F04 0345;;;;N;;;1F8C;;1F8C +1F85;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F05 0345;;;;N;;;1F8D;;1F8D +1F86;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F06 0345;;;;N;;;1F8E;;1F8E +1F87;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F07 0345;;;;N;;;1F8F;;1F8F +1F88;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F08 0345;;;;N;;;;1F80; +1F89;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F09 0345;;;;N;;;;1F81; +1F8A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0A 0345;;;;N;;;;1F82; +1F8B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0B 0345;;;;N;;;;1F83; +1F8C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0C 0345;;;;N;;;;1F84; +1F8D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0D 0345;;;;N;;;;1F85; +1F8E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0E 0345;;;;N;;;;1F86; +1F8F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0F 0345;;;;N;;;;1F87; +1F90;GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F20 0345;;;;N;;;1F98;;1F98 +1F91;GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F21 0345;;;;N;;;1F99;;1F99 +1F92;GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F22 0345;;;;N;;;1F9A;;1F9A +1F93;GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F23 0345;;;;N;;;1F9B;;1F9B +1F94;GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F24 0345;;;;N;;;1F9C;;1F9C +1F95;GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F25 0345;;;;N;;;1F9D;;1F9D +1F96;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F26 0345;;;;N;;;1F9E;;1F9E +1F97;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F27 0345;;;;N;;;1F9F;;1F9F +1F98;GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F28 0345;;;;N;;;;1F90; +1F99;GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F29 0345;;;;N;;;;1F91; +1F9A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2A 0345;;;;N;;;;1F92; +1F9B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2B 0345;;;;N;;;;1F93; +1F9C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2C 0345;;;;N;;;;1F94; +1F9D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2D 0345;;;;N;;;;1F95; +1F9E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2E 0345;;;;N;;;;1F96; +1F9F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2F 0345;;;;N;;;;1F97; +1FA0;GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F60 0345;;;;N;;;1FA8;;1FA8 +1FA1;GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F61 0345;;;;N;;;1FA9;;1FA9 +1FA2;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F62 0345;;;;N;;;1FAA;;1FAA +1FA3;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F63 0345;;;;N;;;1FAB;;1FAB +1FA4;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F64 0345;;;;N;;;1FAC;;1FAC +1FA5;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F65 0345;;;;N;;;1FAD;;1FAD +1FA6;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F66 0345;;;;N;;;1FAE;;1FAE +1FA7;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F67 0345;;;;N;;;1FAF;;1FAF +1FA8;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F68 0345;;;;N;;;;1FA0; +1FA9;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F69 0345;;;;N;;;;1FA1; +1FAA;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6A 0345;;;;N;;;;1FA2; +1FAB;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6B 0345;;;;N;;;;1FA3; +1FAC;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6C 0345;;;;N;;;;1FA4; +1FAD;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6D 0345;;;;N;;;;1FA5; +1FAE;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6E 0345;;;;N;;;;1FA6; +1FAF;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6F 0345;;;;N;;;;1FA7; +1FB0;GREEK SMALL LETTER ALPHA WITH VRACHY;Ll;0;L;03B1 0306;;;;N;;;1FB8;;1FB8 +1FB1;GREEK SMALL LETTER ALPHA WITH MACRON;Ll;0;L;03B1 0304;;;;N;;;1FB9;;1FB9 +1FB2;GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F70 0345;;;;N;;;;; +1FB3;GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI;Ll;0;L;03B1 0345;;;;N;;;1FBC;;1FBC +1FB4;GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AC 0345;;;;N;;;;; +1FB6;GREEK SMALL LETTER ALPHA WITH PERISPOMENI;Ll;0;L;03B1 0342;;;;N;;;;; +1FB7;GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FB6 0345;;;;N;;;;; +1FB8;GREEK CAPITAL LETTER ALPHA WITH VRACHY;Lu;0;L;0391 0306;;;;N;;;;1FB0; +1FB9;GREEK CAPITAL LETTER ALPHA WITH MACRON;Lu;0;L;0391 0304;;;;N;;;;1FB1; +1FBA;GREEK CAPITAL LETTER ALPHA WITH VARIA;Lu;0;L;0391 0300;;;;N;;;;1F70; +1FBB;GREEK CAPITAL LETTER ALPHA WITH OXIA;Lu;0;L;0386;;;;N;;;;1F71; +1FBC;GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI;Lt;0;L;0391 0345;;;;N;;;;1FB3; +1FBD;GREEK KORONIS;Sk;0;ON; 0020 0313;;;;N;;;;; +1FBE;GREEK PROSGEGRAMMENI;Ll;0;L;03B9;;;;N;;;0399;;0399 +1FBF;GREEK PSILI;Sk;0;ON; 0020 0313;;;;N;;;;; +1FC0;GREEK PERISPOMENI;Sk;0;ON; 0020 0342;;;;N;;;;; +1FC1;GREEK DIALYTIKA AND PERISPOMENI;Sk;0;ON;00A8 0342;;;;N;;;;; +1FC2;GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F74 0345;;;;N;;;;; +1FC3;GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI;Ll;0;L;03B7 0345;;;;N;;;1FCC;;1FCC +1FC4;GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AE 0345;;;;N;;;;; +1FC6;GREEK SMALL LETTER ETA WITH PERISPOMENI;Ll;0;L;03B7 0342;;;;N;;;;; +1FC7;GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FC6 0345;;;;N;;;;; +1FC8;GREEK CAPITAL LETTER EPSILON WITH VARIA;Lu;0;L;0395 0300;;;;N;;;;1F72; +1FC9;GREEK CAPITAL LETTER EPSILON WITH OXIA;Lu;0;L;0388;;;;N;;;;1F73; +1FCA;GREEK CAPITAL LETTER ETA WITH VARIA;Lu;0;L;0397 0300;;;;N;;;;1F74; +1FCB;GREEK CAPITAL LETTER ETA WITH OXIA;Lu;0;L;0389;;;;N;;;;1F75; +1FCC;GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI;Lt;0;L;0397 0345;;;;N;;;;1FC3; +1FCD;GREEK PSILI AND VARIA;Sk;0;ON;1FBF 0300;;;;N;;;;; +1FCE;GREEK PSILI AND OXIA;Sk;0;ON;1FBF 0301;;;;N;;;;; +1FCF;GREEK PSILI AND PERISPOMENI;Sk;0;ON;1FBF 0342;;;;N;;;;; +1FD0;GREEK SMALL LETTER IOTA WITH VRACHY;Ll;0;L;03B9 0306;;;;N;;;1FD8;;1FD8 +1FD1;GREEK SMALL LETTER IOTA WITH MACRON;Ll;0;L;03B9 0304;;;;N;;;1FD9;;1FD9 +1FD2;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA;Ll;0;L;03CA 0300;;;;N;;;;; +1FD3;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA;Ll;0;L;0390;;;;N;;;;; +1FD6;GREEK SMALL LETTER IOTA WITH PERISPOMENI;Ll;0;L;03B9 0342;;;;N;;;;; +1FD7;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CA 0342;;;;N;;;;; +1FD8;GREEK CAPITAL LETTER IOTA WITH VRACHY;Lu;0;L;0399 0306;;;;N;;;;1FD0; +1FD9;GREEK CAPITAL LETTER IOTA WITH MACRON;Lu;0;L;0399 0304;;;;N;;;;1FD1; +1FDA;GREEK CAPITAL LETTER IOTA WITH VARIA;Lu;0;L;0399 0300;;;;N;;;;1F76; +1FDB;GREEK CAPITAL LETTER IOTA WITH OXIA;Lu;0;L;038A;;;;N;;;;1F77; +1FDD;GREEK DASIA AND VARIA;Sk;0;ON;1FFE 0300;;;;N;;;;; +1FDE;GREEK DASIA AND OXIA;Sk;0;ON;1FFE 0301;;;;N;;;;; +1FDF;GREEK DASIA AND PERISPOMENI;Sk;0;ON;1FFE 0342;;;;N;;;;; +1FE0;GREEK SMALL LETTER UPSILON WITH VRACHY;Ll;0;L;03C5 0306;;;;N;;;1FE8;;1FE8 +1FE1;GREEK SMALL LETTER UPSILON WITH MACRON;Ll;0;L;03C5 0304;;;;N;;;1FE9;;1FE9 +1FE2;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA;Ll;0;L;03CB 0300;;;;N;;;;; +1FE3;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA;Ll;0;L;03B0;;;;N;;;;; +1FE4;GREEK SMALL LETTER RHO WITH PSILI;Ll;0;L;03C1 0313;;;;N;;;;; +1FE5;GREEK SMALL LETTER RHO WITH DASIA;Ll;0;L;03C1 0314;;;;N;;;1FEC;;1FEC +1FE6;GREEK SMALL LETTER UPSILON WITH PERISPOMENI;Ll;0;L;03C5 0342;;;;N;;;;; +1FE7;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CB 0342;;;;N;;;;; +1FE8;GREEK CAPITAL LETTER UPSILON WITH VRACHY;Lu;0;L;03A5 0306;;;;N;;;;1FE0; +1FE9;GREEK CAPITAL LETTER UPSILON WITH MACRON;Lu;0;L;03A5 0304;;;;N;;;;1FE1; +1FEA;GREEK CAPITAL LETTER UPSILON WITH VARIA;Lu;0;L;03A5 0300;;;;N;;;;1F7A; +1FEB;GREEK CAPITAL LETTER UPSILON WITH OXIA;Lu;0;L;038E;;;;N;;;;1F7B; +1FEC;GREEK CAPITAL LETTER RHO WITH DASIA;Lu;0;L;03A1 0314;;;;N;;;;1FE5; +1FED;GREEK DIALYTIKA AND VARIA;Sk;0;ON;00A8 0300;;;;N;;;;; +1FEE;GREEK DIALYTIKA AND OXIA;Sk;0;ON;0385;;;;N;;;;; +1FEF;GREEK VARIA;Sk;0;ON;0060;;;;N;;;;; +1FF2;GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F7C 0345;;;;N;;;;; +1FF3;GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI;Ll;0;L;03C9 0345;;;;N;;;1FFC;;1FFC +1FF4;GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03CE 0345;;;;N;;;;; +1FF6;GREEK SMALL LETTER OMEGA WITH PERISPOMENI;Ll;0;L;03C9 0342;;;;N;;;;; +1FF7;GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FF6 0345;;;;N;;;;; +1FF8;GREEK CAPITAL LETTER OMICRON WITH VARIA;Lu;0;L;039F 0300;;;;N;;;;1F78; +1FF9;GREEK CAPITAL LETTER OMICRON WITH OXIA;Lu;0;L;038C;;;;N;;;;1F79; +1FFA;GREEK CAPITAL LETTER OMEGA WITH VARIA;Lu;0;L;03A9 0300;;;;N;;;;1F7C; +1FFB;GREEK CAPITAL LETTER OMEGA WITH OXIA;Lu;0;L;038F;;;;N;;;;1F7D; +1FFC;GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI;Lt;0;L;03A9 0345;;;;N;;;;1FF3; +1FFD;GREEK OXIA;Sk;0;ON;00B4;;;;N;;;;; +1FFE;GREEK DASIA;Sk;0;ON; 0020 0314;;;;N;;;;; +2000;EN QUAD;Zs;0;WS;2002;;;;N;;;;; +2001;EM QUAD;Zs;0;WS;2003;;;;N;;;;; +2002;EN SPACE;Zs;0;WS; 0020;;;;N;;;;; +2003;EM SPACE;Zs;0;WS; 0020;;;;N;;;;; +2004;THREE-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; +2005;FOUR-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; +2006;SIX-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; +2007;FIGURE SPACE;Zs;0;WS; 0020;;;;N;;;;; +2008;PUNCTUATION SPACE;Zs;0;WS; 0020;;;;N;;;;; +2009;THIN SPACE;Zs;0;WS; 0020;;;;N;;;;; +200A;HAIR SPACE;Zs;0;WS; 0020;;;;N;;;;; +200B;ZERO WIDTH SPACE;Cf;0;BN;;;;;N;;;;; +200C;ZERO WIDTH NON-JOINER;Cf;0;BN;;;;;N;;;;; +200D;ZERO WIDTH JOINER;Cf;0;BN;;;;;N;;;;; +200E;LEFT-TO-RIGHT MARK;Cf;0;L;;;;;N;;;;; +200F;RIGHT-TO-LEFT MARK;Cf;0;R;;;;;N;;;;; +2010;HYPHEN;Pd;0;ON;;;;;N;;;;; +2011;NON-BREAKING HYPHEN;Pd;0;ON; 2010;;;;N;;;;; +2012;FIGURE DASH;Pd;0;ON;;;;;N;;;;; +2013;EN DASH;Pd;0;ON;;;;;N;;;;; +2014;EM DASH;Pd;0;ON;;;;;N;;;;; +2015;HORIZONTAL BAR;Pd;0;ON;;;;;N;QUOTATION DASH;;;; +2016;DOUBLE VERTICAL LINE;Po;0;ON;;;;;N;DOUBLE VERTICAL BAR;;;; +2017;DOUBLE LOW LINE;Po;0;ON; 0020 0333;;;;N;SPACING DOUBLE UNDERSCORE;;;; +2018;LEFT SINGLE QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE TURNED COMMA QUOTATION MARK;;;; +2019;RIGHT SINGLE QUOTATION MARK;Pf;0;ON;;;;;N;SINGLE COMMA QUOTATION MARK;;;; +201A;SINGLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW SINGLE COMMA QUOTATION MARK;;;; +201B;SINGLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE REVERSED COMMA QUOTATION MARK;;;; +201C;LEFT DOUBLE QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE TURNED COMMA QUOTATION MARK;;;; +201D;RIGHT DOUBLE QUOTATION MARK;Pf;0;ON;;;;;N;DOUBLE COMMA QUOTATION MARK;;;; +201E;DOUBLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW DOUBLE COMMA QUOTATION MARK;;;; +201F;DOUBLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE REVERSED COMMA QUOTATION MARK;;;; +2020;DAGGER;Po;0;ON;;;;;N;;;;; +2021;DOUBLE DAGGER;Po;0;ON;;;;;N;;;;; +2022;BULLET;Po;0;ON;;;;;N;;;;; +2023;TRIANGULAR BULLET;Po;0;ON;;;;;N;;;;; +2024;ONE DOT LEADER;Po;0;ON; 002E;;;;N;;;;; +2025;TWO DOT LEADER;Po;0;ON; 002E 002E;;;;N;;;;; +2026;HORIZONTAL ELLIPSIS;Po;0;ON; 002E 002E 002E;;;;N;;;;; +2027;HYPHENATION POINT;Po;0;ON;;;;;N;;;;; +2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;; +2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;; +202A;LEFT-TO-RIGHT EMBEDDING;Cf;0;LRE;;;;;N;;;;; +202B;RIGHT-TO-LEFT EMBEDDING;Cf;0;RLE;;;;;N;;;;; +202C;POP DIRECTIONAL FORMATTING;Cf;0;PDF;;;;;N;;;;; +202D;LEFT-TO-RIGHT OVERRIDE;Cf;0;LRO;;;;;N;;;;; +202E;RIGHT-TO-LEFT OVERRIDE;Cf;0;RLO;;;;;N;;;;; +202F;NARROW NO-BREAK SPACE;Zs;0;CS; 0020;;;;N;;;;; +2030;PER MILLE SIGN;Po;0;ET;;;;;N;;;;; +2031;PER TEN THOUSAND SIGN;Po;0;ET;;;;;N;;;;; +2032;PRIME;Po;0;ET;;;;;N;;;;; +2033;DOUBLE PRIME;Po;0;ET; 2032 2032;;;;N;;;;; +2034;TRIPLE PRIME;Po;0;ET; 2032 2032 2032;;;;N;;;;; +2035;REVERSED PRIME;Po;0;ON;;;;;N;;;;; +2036;REVERSED DOUBLE PRIME;Po;0;ON; 2035 2035;;;;N;;;;; +2037;REVERSED TRIPLE PRIME;Po;0;ON; 2035 2035 2035;;;;N;;;;; +2038;CARET;Po;0;ON;;;;;N;;;;; +2039;SINGLE LEFT-POINTING ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING SINGLE GUILLEMET;;;; +203A;SINGLE RIGHT-POINTING ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING SINGLE GUILLEMET;;;; +203B;REFERENCE MARK;Po;0;ON;;;;;N;;;;; +203C;DOUBLE EXCLAMATION MARK;Po;0;ON; 0021 0021;;;;N;;;;; +203D;INTERROBANG;Po;0;ON;;;;;N;;;;; +203E;OVERLINE;Po;0;ON; 0020 0305;;;;N;SPACING OVERSCORE;;;; +203F;UNDERTIE;Pc;0;ON;;;;;N;;;;; +2040;CHARACTER TIE;Pc;0;ON;;;;;N;;;;; +2041;CARET INSERTION POINT;Po;0;ON;;;;;N;;;;; +2042;ASTERISM;Po;0;ON;;;;;N;;;;; +2043;HYPHEN BULLET;Po;0;ON;;;;;N;;;;; +2044;FRACTION SLASH;Sm;0;CS;;;;;N;;;;; +2045;LEFT SQUARE BRACKET WITH QUILL;Ps;0;ON;;;;;Y;;;;; +2046;RIGHT SQUARE BRACKET WITH QUILL;Pe;0;ON;;;;;Y;;;;; +2047;DOUBLE QUESTION MARK;Po;0;ON; 003F 003F;;;;N;;;;; +2048;QUESTION EXCLAMATION MARK;Po;0;ON; 003F 0021;;;;N;;;;; +2049;EXCLAMATION QUESTION MARK;Po;0;ON; 0021 003F;;;;N;;;;; +204A;TIRONIAN SIGN ET;Po;0;ON;;;;;N;;;;; +204B;REVERSED PILCROW SIGN;Po;0;ON;;;;;N;;;;; +204C;BLACK LEFTWARDS BULLET;Po;0;ON;;;;;N;;;;; +204D;BLACK RIGHTWARDS BULLET;Po;0;ON;;;;;N;;;;; +204E;LOW ASTERISK;Po;0;ON;;;;;N;;;;; +204F;REVERSED SEMICOLON;Po;0;ON;;;;;N;;;;; +2050;CLOSE UP;Po;0;ON;;;;;N;;;;; +2051;TWO ASTERISKS ALIGNED VERTICALLY;Po;0;ON;;;;;N;;;;; +2052;COMMERCIAL MINUS SIGN;Sm;0;ON;;;;;N;;;;; +2053;SWUNG DASH;Po;0;ON;;;;;N;;;;; +2054;INVERTED UNDERTIE;Pc;0;ON;;;;;N;;;;; +2055;FLOWER PUNCTUATION MARK;Po;0;ON;;;;;N;;;;; +2056;THREE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +2057;QUADRUPLE PRIME;Po;0;ON; 2032 2032 2032 2032;;;;N;;;;; +2058;FOUR DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +2059;FIVE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +205A;TWO DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +205B;FOUR DOT MARK;Po;0;ON;;;;;N;;;;; +205C;DOTTED CROSS;Po;0;ON;;;;;N;;;;; +205D;TRICOLON;Po;0;ON;;;;;N;;;;; +205E;VERTICAL FOUR DOTS;Po;0;ON;;;;;N;;;;; +205F;MEDIUM MATHEMATICAL SPACE;Zs;0;WS; 0020;;;;N;;;;; +2060;WORD JOINER;Cf;0;BN;;;;;N;;;;; +2061;FUNCTION APPLICATION;Cf;0;BN;;;;;N;;;;; +2062;INVISIBLE TIMES;Cf;0;BN;;;;;N;;;;; +2063;INVISIBLE SEPARATOR;Cf;0;BN;;;;;N;;;;; +2064;INVISIBLE PLUS;Cf;0;BN;;;;;N;;;;; +2066;LEFT-TO-RIGHT ISOLATE;Cf;0;LRI;;;;;N;;;;; +2067;RIGHT-TO-LEFT ISOLATE;Cf;0;RLI;;;;;N;;;;; +2068;FIRST STRONG ISOLATE;Cf;0;FSI;;;;;N;;;;; +2069;POP DIRECTIONAL ISOLATE;Cf;0;PDI;;;;;N;;;;; +206A;INHIBIT SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;; +206B;ACTIVATE SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;; +206C;INHIBIT ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;; +206D;ACTIVATE ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;; +206E;NATIONAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;; +206F;NOMINAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;; +2070;SUPERSCRIPT ZERO;No;0;EN; 0030;;0;0;N;SUPERSCRIPT DIGIT ZERO;;;; +2071;SUPERSCRIPT LATIN SMALL LETTER I;Lm;0;L; 0069;;;;N;;;;; +2074;SUPERSCRIPT FOUR;No;0;EN; 0034;;4;4;N;SUPERSCRIPT DIGIT FOUR;;;; +2075;SUPERSCRIPT FIVE;No;0;EN; 0035;;5;5;N;SUPERSCRIPT DIGIT FIVE;;;; +2076;SUPERSCRIPT SIX;No;0;EN; 0036;;6;6;N;SUPERSCRIPT DIGIT SIX;;;; +2077;SUPERSCRIPT SEVEN;No;0;EN; 0037;;7;7;N;SUPERSCRIPT DIGIT SEVEN;;;; +2078;SUPERSCRIPT EIGHT;No;0;EN; 0038;;8;8;N;SUPERSCRIPT DIGIT EIGHT;;;; +2079;SUPERSCRIPT NINE;No;0;EN; 0039;;9;9;N;SUPERSCRIPT DIGIT NINE;;;; +207A;SUPERSCRIPT PLUS SIGN;Sm;0;ES; 002B;;;;N;;;;; +207B;SUPERSCRIPT MINUS;Sm;0;ES; 2212;;;;N;SUPERSCRIPT HYPHEN-MINUS;;;; +207C;SUPERSCRIPT EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; +207D;SUPERSCRIPT LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;SUPERSCRIPT OPENING PARENTHESIS;;;; +207E;SUPERSCRIPT RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;SUPERSCRIPT CLOSING PARENTHESIS;;;; +207F;SUPERSCRIPT LATIN SMALL LETTER N;Lm;0;L; 006E;;;;N;;;;; +2080;SUBSCRIPT ZERO;No;0;EN; 0030;;0;0;N;SUBSCRIPT DIGIT ZERO;;;; +2081;SUBSCRIPT ONE;No;0;EN; 0031;;1;1;N;SUBSCRIPT DIGIT ONE;;;; +2082;SUBSCRIPT TWO;No;0;EN; 0032;;2;2;N;SUBSCRIPT DIGIT TWO;;;; +2083;SUBSCRIPT THREE;No;0;EN; 0033;;3;3;N;SUBSCRIPT DIGIT THREE;;;; +2084;SUBSCRIPT FOUR;No;0;EN; 0034;;4;4;N;SUBSCRIPT DIGIT FOUR;;;; +2085;SUBSCRIPT FIVE;No;0;EN; 0035;;5;5;N;SUBSCRIPT DIGIT FIVE;;;; +2086;SUBSCRIPT SIX;No;0;EN; 0036;;6;6;N;SUBSCRIPT DIGIT SIX;;;; +2087;SUBSCRIPT SEVEN;No;0;EN; 0037;;7;7;N;SUBSCRIPT DIGIT SEVEN;;;; +2088;SUBSCRIPT EIGHT;No;0;EN; 0038;;8;8;N;SUBSCRIPT DIGIT EIGHT;;;; +2089;SUBSCRIPT NINE;No;0;EN; 0039;;9;9;N;SUBSCRIPT DIGIT NINE;;;; +208A;SUBSCRIPT PLUS SIGN;Sm;0;ES; 002B;;;;N;;;;; +208B;SUBSCRIPT MINUS;Sm;0;ES; 2212;;;;N;SUBSCRIPT HYPHEN-MINUS;;;; +208C;SUBSCRIPT EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; +208D;SUBSCRIPT LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;SUBSCRIPT OPENING PARENTHESIS;;;; +208E;SUBSCRIPT RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;SUBSCRIPT CLOSING PARENTHESIS;;;; +2090;LATIN SUBSCRIPT SMALL LETTER A;Lm;0;L; 0061;;;;N;;;;; +2091;LATIN SUBSCRIPT SMALL LETTER E;Lm;0;L; 0065;;;;N;;;;; +2092;LATIN SUBSCRIPT SMALL LETTER O;Lm;0;L; 006F;;;;N;;;;; +2093;LATIN SUBSCRIPT SMALL LETTER X;Lm;0;L; 0078;;;;N;;;;; +2094;LATIN SUBSCRIPT SMALL LETTER SCHWA;Lm;0;L; 0259;;;;N;;;;; +2095;LATIN SUBSCRIPT SMALL LETTER H;Lm;0;L; 0068;;;;N;;;;; +2096;LATIN SUBSCRIPT SMALL LETTER K;Lm;0;L; 006B;;;;N;;;;; +2097;LATIN SUBSCRIPT SMALL LETTER L;Lm;0;L; 006C;;;;N;;;;; +2098;LATIN SUBSCRIPT SMALL LETTER M;Lm;0;L; 006D;;;;N;;;;; +2099;LATIN SUBSCRIPT SMALL LETTER N;Lm;0;L; 006E;;;;N;;;;; +209A;LATIN SUBSCRIPT SMALL LETTER P;Lm;0;L; 0070;;;;N;;;;; +209B;LATIN SUBSCRIPT SMALL LETTER S;Lm;0;L; 0073;;;;N;;;;; +209C;LATIN SUBSCRIPT SMALL LETTER T;Lm;0;L; 0074;;;;N;;;;; +20A0;EURO-CURRENCY SIGN;Sc;0;ET;;;;;N;;;;; +20A1;COLON SIGN;Sc;0;ET;;;;;N;;;;; +20A2;CRUZEIRO SIGN;Sc;0;ET;;;;;N;;;;; +20A3;FRENCH FRANC SIGN;Sc;0;ET;;;;;N;;;;; +20A4;LIRA SIGN;Sc;0;ET;;;;;N;;;;; +20A5;MILL SIGN;Sc;0;ET;;;;;N;;;;; +20A6;NAIRA SIGN;Sc;0;ET;;;;;N;;;;; +20A7;PESETA SIGN;Sc;0;ET;;;;;N;;;;; +20A8;RUPEE SIGN;Sc;0;ET; 0052 0073;;;;N;;;;; +20A9;WON SIGN;Sc;0;ET;;;;;N;;;;; +20AA;NEW SHEQEL SIGN;Sc;0;ET;;;;;N;;;;; +20AB;DONG SIGN;Sc;0;ET;;;;;N;;;;; +20AC;EURO SIGN;Sc;0;ET;;;;;N;;;;; +20AD;KIP SIGN;Sc;0;ET;;;;;N;;;;; +20AE;TUGRIK SIGN;Sc;0;ET;;;;;N;;;;; +20AF;DRACHMA SIGN;Sc;0;ET;;;;;N;;;;; +20B0;GERMAN PENNY SIGN;Sc;0;ET;;;;;N;;;;; +20B1;PESO SIGN;Sc;0;ET;;;;;N;;;;; +20B2;GUARANI SIGN;Sc;0;ET;;;;;N;;;;; +20B3;AUSTRAL SIGN;Sc;0;ET;;;;;N;;;;; +20B4;HRYVNIA SIGN;Sc;0;ET;;;;;N;;;;; +20B5;CEDI SIGN;Sc;0;ET;;;;;N;;;;; +20B6;LIVRE TOURNOIS SIGN;Sc;0;ET;;;;;N;;;;; +20B7;SPESMILO SIGN;Sc;0;ET;;;;;N;;;;; +20B8;TENGE SIGN;Sc;0;ET;;;;;N;;;;; +20B9;INDIAN RUPEE SIGN;Sc;0;ET;;;;;N;;;;; +20BA;TURKISH LIRA SIGN;Sc;0;ET;;;;;N;;;;; +20BB;NORDIC MARK SIGN;Sc;0;ET;;;;;N;;;;; +20BC;MANAT SIGN;Sc;0;ET;;;;;N;;;;; +20BD;RUBLE SIGN;Sc;0;ET;;;;;N;;;;; +20BE;LARI SIGN;Sc;0;ET;;;;;N;;;;; +20BF;BITCOIN SIGN;Sc;0;ET;;;;;N;;;;; +20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;; +20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;; +20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;; +20D3;COMBINING SHORT VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT VERTICAL BAR OVERLAY;;;; +20D4;COMBINING ANTICLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING ANTICLOCKWISE ARROW ABOVE;;;; +20D5;COMBINING CLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING CLOCKWISE ARROW ABOVE;;;; +20D6;COMBINING LEFT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT ARROW ABOVE;;;; +20D7;COMBINING RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT ARROW ABOVE;;;; +20D8;COMBINING RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING RING OVERLAY;;;; +20D9;COMBINING CLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING CLOCKWISE RING OVERLAY;;;; +20DA;COMBINING ANTICLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING ANTICLOCKWISE RING OVERLAY;;;; +20DB;COMBINING THREE DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING THREE DOTS ABOVE;;;; +20DC;COMBINING FOUR DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING FOUR DOTS ABOVE;;;; +20DD;COMBINING ENCLOSING CIRCLE;Me;0;NSM;;;;;N;ENCLOSING CIRCLE;;;; +20DE;COMBINING ENCLOSING SQUARE;Me;0;NSM;;;;;N;ENCLOSING SQUARE;;;; +20DF;COMBINING ENCLOSING DIAMOND;Me;0;NSM;;;;;N;ENCLOSING DIAMOND;;;; +20E0;COMBINING ENCLOSING CIRCLE BACKSLASH;Me;0;NSM;;;;;N;ENCLOSING CIRCLE SLASH;;;; +20E1;COMBINING LEFT RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT RIGHT ARROW ABOVE;;;; +20E2;COMBINING ENCLOSING SCREEN;Me;0;NSM;;;;;N;;;;; +20E3;COMBINING ENCLOSING KEYCAP;Me;0;NSM;;;;;N;;;;; +20E4;COMBINING ENCLOSING UPWARD POINTING TRIANGLE;Me;0;NSM;;;;;N;;;;; +20E5;COMBINING REVERSE SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;;;;; +20E6;COMBINING DOUBLE VERTICAL STROKE OVERLAY;Mn;1;NSM;;;;;N;;;;; +20E7;COMBINING ANNUITY SYMBOL;Mn;230;NSM;;;;;N;;;;; +20E8;COMBINING TRIPLE UNDERDOT;Mn;220;NSM;;;;;N;;;;; +20E9;COMBINING WIDE BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;; +20EA;COMBINING LEFTWARDS ARROW OVERLAY;Mn;1;NSM;;;;;N;;;;; +20EB;COMBINING LONG DOUBLE SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;;;;; +20EC;COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS;Mn;220;NSM;;;;;N;;;;; +20ED;COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS;Mn;220;NSM;;;;;N;;;;; +20EE;COMBINING LEFT ARROW BELOW;Mn;220;NSM;;;;;N;;;;; +20EF;COMBINING RIGHT ARROW BELOW;Mn;220;NSM;;;;;N;;;;; +20F0;COMBINING ASTERISK ABOVE;Mn;230;NSM;;;;;N;;;;; +2100;ACCOUNT OF;So;0;ON; 0061 002F 0063;;;;N;;;;; +2101;ADDRESSED TO THE SUBJECT;So;0;ON; 0061 002F 0073;;;;N;;;;; +2102;DOUBLE-STRUCK CAPITAL C;Lu;0;L; 0043;;;;N;DOUBLE-STRUCK C;;;; +2103;DEGREE CELSIUS;So;0;ON; 00B0 0043;;;;N;DEGREES CENTIGRADE;;;; +2104;CENTRE LINE SYMBOL;So;0;ON;;;;;N;C L SYMBOL;;;; +2105;CARE OF;So;0;ON; 0063 002F 006F;;;;N;;;;; +2106;CADA UNA;So;0;ON; 0063 002F 0075;;;;N;;;;; +2107;EULER CONSTANT;Lu;0;L; 0190;;;;N;EULERS;;;; +2108;SCRUPLE;So;0;ON;;;;;N;;;;; +2109;DEGREE FAHRENHEIT;So;0;ON; 00B0 0046;;;;N;DEGREES FAHRENHEIT;;;; +210A;SCRIPT SMALL G;Ll;0;L; 0067;;;;N;;;;; +210B;SCRIPT CAPITAL H;Lu;0;L; 0048;;;;N;SCRIPT H;;;; +210C;BLACK-LETTER CAPITAL H;Lu;0;L; 0048;;;;N;BLACK-LETTER H;;;; +210D;DOUBLE-STRUCK CAPITAL H;Lu;0;L; 0048;;;;N;DOUBLE-STRUCK H;;;; +210E;PLANCK CONSTANT;Ll;0;L; 0068;;;;N;;;;; +210F;PLANCK CONSTANT OVER TWO PI;Ll;0;L; 0127;;;;N;PLANCK CONSTANT OVER 2 PI;;;; +2110;SCRIPT CAPITAL I;Lu;0;L; 0049;;;;N;SCRIPT I;;;; +2111;BLACK-LETTER CAPITAL I;Lu;0;L; 0049;;;;N;BLACK-LETTER I;;;; +2112;SCRIPT CAPITAL L;Lu;0;L; 004C;;;;N;SCRIPT L;;;; +2113;SCRIPT SMALL L;Ll;0;L; 006C;;;;N;;;;; +2114;L B BAR SYMBOL;So;0;ON;;;;;N;;;;; +2115;DOUBLE-STRUCK CAPITAL N;Lu;0;L; 004E;;;;N;DOUBLE-STRUCK N;;;; +2116;NUMERO SIGN;So;0;ON; 004E 006F;;;;N;NUMERO;;;; +2117;SOUND RECORDING COPYRIGHT;So;0;ON;;;;;N;;;;; +2118;SCRIPT CAPITAL P;Sm;0;ON;;;;;N;SCRIPT P;;;; +2119;DOUBLE-STRUCK CAPITAL P;Lu;0;L; 0050;;;;N;DOUBLE-STRUCK P;;;; +211A;DOUBLE-STRUCK CAPITAL Q;Lu;0;L; 0051;;;;N;DOUBLE-STRUCK Q;;;; +211B;SCRIPT CAPITAL R;Lu;0;L; 0052;;;;N;SCRIPT R;;;; +211C;BLACK-LETTER CAPITAL R;Lu;0;L; 0052;;;;N;BLACK-LETTER R;;;; +211D;DOUBLE-STRUCK CAPITAL R;Lu;0;L; 0052;;;;N;DOUBLE-STRUCK R;;;; +211E;PRESCRIPTION TAKE;So;0;ON;;;;;N;;;;; +211F;RESPONSE;So;0;ON;;;;;N;;;;; +2120;SERVICE MARK;So;0;ON; 0053 004D;;;;N;;;;; +2121;TELEPHONE SIGN;So;0;ON; 0054 0045 004C;;;;N;T E L SYMBOL;;;; +2122;TRADE MARK SIGN;So;0;ON; 0054 004D;;;;N;TRADEMARK;;;; +2123;VERSICLE;So;0;ON;;;;;N;;;;; +2124;DOUBLE-STRUCK CAPITAL Z;Lu;0;L; 005A;;;;N;DOUBLE-STRUCK Z;;;; +2125;OUNCE SIGN;So;0;ON;;;;;N;OUNCE;;;; +2126;OHM SIGN;Lu;0;L;03A9;;;;N;OHM;;;03C9; +2127;INVERTED OHM SIGN;So;0;ON;;;;;N;MHO;;;; +2128;BLACK-LETTER CAPITAL Z;Lu;0;L; 005A;;;;N;BLACK-LETTER Z;;;; +2129;TURNED GREEK SMALL LETTER IOTA;So;0;ON;;;;;N;;;;; +212A;KELVIN SIGN;Lu;0;L;004B;;;;N;DEGREES KELVIN;;;006B; +212B;ANGSTROM SIGN;Lu;0;L;00C5;;;;N;ANGSTROM UNIT;;;00E5; +212C;SCRIPT CAPITAL B;Lu;0;L; 0042;;;;N;SCRIPT B;;;; +212D;BLACK-LETTER CAPITAL C;Lu;0;L; 0043;;;;N;BLACK-LETTER C;;;; +212E;ESTIMATED SYMBOL;So;0;ET;;;;;N;;;;; +212F;SCRIPT SMALL E;Ll;0;L; 0065;;;;N;;;;; +2130;SCRIPT CAPITAL E;Lu;0;L; 0045;;;;N;SCRIPT E;;;; +2131;SCRIPT CAPITAL F;Lu;0;L; 0046;;;;N;SCRIPT F;;;; +2132;TURNED CAPITAL F;Lu;0;L;;;;;N;TURNED F;;;214E; +2133;SCRIPT CAPITAL M;Lu;0;L; 004D;;;;N;SCRIPT M;;;; +2134;SCRIPT SMALL O;Ll;0;L; 006F;;;;N;;;;; +2135;ALEF SYMBOL;Lo;0;L; 05D0;;;;N;FIRST TRANSFINITE CARDINAL;;;; +2136;BET SYMBOL;Lo;0;L; 05D1;;;;N;SECOND TRANSFINITE CARDINAL;;;; +2137;GIMEL SYMBOL;Lo;0;L; 05D2;;;;N;THIRD TRANSFINITE CARDINAL;;;; +2138;DALET SYMBOL;Lo;0;L; 05D3;;;;N;FOURTH TRANSFINITE CARDINAL;;;; +2139;INFORMATION SOURCE;Ll;0;L; 0069;;;;N;;;;; +213A;ROTATED CAPITAL Q;So;0;ON;;;;;N;;;;; +213B;FACSIMILE SIGN;So;0;ON; 0046 0041 0058;;;;N;;;;; +213C;DOUBLE-STRUCK SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +213D;DOUBLE-STRUCK SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +213E;DOUBLE-STRUCK CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +213F;DOUBLE-STRUCK CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +2140;DOUBLE-STRUCK N-ARY SUMMATION;Sm;0;ON; 2211;;;;Y;;;;; +2141;TURNED SANS-SERIF CAPITAL G;Sm;0;ON;;;;;N;;;;; +2142;TURNED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;; +2143;REVERSED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;; +2144;TURNED SANS-SERIF CAPITAL Y;Sm;0;ON;;;;;N;;;;; +2145;DOUBLE-STRUCK ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +2146;DOUBLE-STRUCK ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +2147;DOUBLE-STRUCK ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +2148;DOUBLE-STRUCK ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +2149;DOUBLE-STRUCK ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +214A;PROPERTY LINE;So;0;ON;;;;;N;;;;; +214B;TURNED AMPERSAND;Sm;0;ON;;;;;N;;;;; +214C;PER SIGN;So;0;ON;;;;;N;;;;; +214D;AKTIESELSKAB;So;0;ON;;;;;N;;;;; +214E;TURNED SMALL F;Ll;0;L;;;;;N;;;2132;;2132 +214F;SYMBOL FOR SAMARITAN SOURCE;So;0;L;;;;;N;;;;; +2150;VULGAR FRACTION ONE SEVENTH;No;0;ON; 0031 2044 0037;;;1/7;N;;;;; +2151;VULGAR FRACTION ONE NINTH;No;0;ON; 0031 2044 0039;;;1/9;N;;;;; +2152;VULGAR FRACTION ONE TENTH;No;0;ON; 0031 2044 0031 0030;;;1/10;N;;;;; +2153;VULGAR FRACTION ONE THIRD;No;0;ON; 0031 2044 0033;;;1/3;N;FRACTION ONE THIRD;;;; +2154;VULGAR FRACTION TWO THIRDS;No;0;ON; 0032 2044 0033;;;2/3;N;FRACTION TWO THIRDS;;;; +2155;VULGAR FRACTION ONE FIFTH;No;0;ON; 0031 2044 0035;;;1/5;N;FRACTION ONE FIFTH;;;; +2156;VULGAR FRACTION TWO FIFTHS;No;0;ON; 0032 2044 0035;;;2/5;N;FRACTION TWO FIFTHS;;;; +2157;VULGAR FRACTION THREE FIFTHS;No;0;ON; 0033 2044 0035;;;3/5;N;FRACTION THREE FIFTHS;;;; +2158;VULGAR FRACTION FOUR FIFTHS;No;0;ON; 0034 2044 0035;;;4/5;N;FRACTION FOUR FIFTHS;;;; +2159;VULGAR FRACTION ONE SIXTH;No;0;ON; 0031 2044 0036;;;1/6;N;FRACTION ONE SIXTH;;;; +215A;VULGAR FRACTION FIVE SIXTHS;No;0;ON; 0035 2044 0036;;;5/6;N;FRACTION FIVE SIXTHS;;;; +215B;VULGAR FRACTION ONE EIGHTH;No;0;ON; 0031 2044 0038;;;1/8;N;FRACTION ONE EIGHTH;;;; +215C;VULGAR FRACTION THREE EIGHTHS;No;0;ON; 0033 2044 0038;;;3/8;N;FRACTION THREE EIGHTHS;;;; +215D;VULGAR FRACTION FIVE EIGHTHS;No;0;ON; 0035 2044 0038;;;5/8;N;FRACTION FIVE EIGHTHS;;;; +215E;VULGAR FRACTION SEVEN EIGHTHS;No;0;ON; 0037 2044 0038;;;7/8;N;FRACTION SEVEN EIGHTHS;;;; +215F;FRACTION NUMERATOR ONE;No;0;ON; 0031 2044;;;1;N;;;;; +2160;ROMAN NUMERAL ONE;Nl;0;L; 0049;;;1;N;;;;2170; +2161;ROMAN NUMERAL TWO;Nl;0;L; 0049 0049;;;2;N;;;;2171; +2162;ROMAN NUMERAL THREE;Nl;0;L; 0049 0049 0049;;;3;N;;;;2172; +2163;ROMAN NUMERAL FOUR;Nl;0;L; 0049 0056;;;4;N;;;;2173; +2164;ROMAN NUMERAL FIVE;Nl;0;L; 0056;;;5;N;;;;2174; +2165;ROMAN NUMERAL SIX;Nl;0;L; 0056 0049;;;6;N;;;;2175; +2166;ROMAN NUMERAL SEVEN;Nl;0;L; 0056 0049 0049;;;7;N;;;;2176; +2167;ROMAN NUMERAL EIGHT;Nl;0;L; 0056 0049 0049 0049;;;8;N;;;;2177; +2168;ROMAN NUMERAL NINE;Nl;0;L; 0049 0058;;;9;N;;;;2178; +2169;ROMAN NUMERAL TEN;Nl;0;L; 0058;;;10;N;;;;2179; +216A;ROMAN NUMERAL ELEVEN;Nl;0;L; 0058 0049;;;11;N;;;;217A; +216B;ROMAN NUMERAL TWELVE;Nl;0;L; 0058 0049 0049;;;12;N;;;;217B; +216C;ROMAN NUMERAL FIFTY;Nl;0;L; 004C;;;50;N;;;;217C; +216D;ROMAN NUMERAL ONE HUNDRED;Nl;0;L; 0043;;;100;N;;;;217D; +216E;ROMAN NUMERAL FIVE HUNDRED;Nl;0;L; 0044;;;500;N;;;;217E; +216F;ROMAN NUMERAL ONE THOUSAND;Nl;0;L; 004D;;;1000;N;;;;217F; +2170;SMALL ROMAN NUMERAL ONE;Nl;0;L; 0069;;;1;N;;;2160;;2160 +2171;SMALL ROMAN NUMERAL TWO;Nl;0;L; 0069 0069;;;2;N;;;2161;;2161 +2172;SMALL ROMAN NUMERAL THREE;Nl;0;L; 0069 0069 0069;;;3;N;;;2162;;2162 +2173;SMALL ROMAN NUMERAL FOUR;Nl;0;L; 0069 0076;;;4;N;;;2163;;2163 +2174;SMALL ROMAN NUMERAL FIVE;Nl;0;L; 0076;;;5;N;;;2164;;2164 +2175;SMALL ROMAN NUMERAL SIX;Nl;0;L; 0076 0069;;;6;N;;;2165;;2165 +2176;SMALL ROMAN NUMERAL SEVEN;Nl;0;L; 0076 0069 0069;;;7;N;;;2166;;2166 +2177;SMALL ROMAN NUMERAL EIGHT;Nl;0;L; 0076 0069 0069 0069;;;8;N;;;2167;;2167 +2178;SMALL ROMAN NUMERAL NINE;Nl;0;L; 0069 0078;;;9;N;;;2168;;2168 +2179;SMALL ROMAN NUMERAL TEN;Nl;0;L; 0078;;;10;N;;;2169;;2169 +217A;SMALL ROMAN NUMERAL ELEVEN;Nl;0;L; 0078 0069;;;11;N;;;216A;;216A +217B;SMALL ROMAN NUMERAL TWELVE;Nl;0;L; 0078 0069 0069;;;12;N;;;216B;;216B +217C;SMALL ROMAN NUMERAL FIFTY;Nl;0;L; 006C;;;50;N;;;216C;;216C +217D;SMALL ROMAN NUMERAL ONE HUNDRED;Nl;0;L; 0063;;;100;N;;;216D;;216D +217E;SMALL ROMAN NUMERAL FIVE HUNDRED;Nl;0;L; 0064;;;500;N;;;216E;;216E +217F;SMALL ROMAN NUMERAL ONE THOUSAND;Nl;0;L; 006D;;;1000;N;;;216F;;216F +2180;ROMAN NUMERAL ONE THOUSAND C D;Nl;0;L;;;;1000;N;;;;; +2181;ROMAN NUMERAL FIVE THOUSAND;Nl;0;L;;;;5000;N;;;;; +2182;ROMAN NUMERAL TEN THOUSAND;Nl;0;L;;;;10000;N;;;;; +2183;ROMAN NUMERAL REVERSED ONE HUNDRED;Lu;0;L;;;;;N;;;;2184; +2184;LATIN SMALL LETTER REVERSED C;Ll;0;L;;;;;N;;;2183;;2183 +2185;ROMAN NUMERAL SIX LATE FORM;Nl;0;L;;;;6;N;;;;; +2186;ROMAN NUMERAL FIFTY EARLY FORM;Nl;0;L;;;;50;N;;;;; +2187;ROMAN NUMERAL FIFTY THOUSAND;Nl;0;L;;;;50000;N;;;;; +2188;ROMAN NUMERAL ONE HUNDRED THOUSAND;Nl;0;L;;;;100000;N;;;;; +2189;VULGAR FRACTION ZERO THIRDS;No;0;ON; 0030 2044 0033;;;0;N;;;;; +218A;TURNED DIGIT TWO;So;0;ON;;;;;N;;;;; +218B;TURNED DIGIT THREE;So;0;ON;;;;;N;;;;; +2190;LEFTWARDS ARROW;Sm;0;ON;;;;;N;LEFT ARROW;;;; +2191;UPWARDS ARROW;Sm;0;ON;;;;;N;UP ARROW;;;; +2192;RIGHTWARDS ARROW;Sm;0;ON;;;;;N;RIGHT ARROW;;;; +2193;DOWNWARDS ARROW;Sm;0;ON;;;;;N;DOWN ARROW;;;; +2194;LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;; +2195;UP DOWN ARROW;So;0;ON;;;;;N;;;;; +2196;NORTH WEST ARROW;So;0;ON;;;;;N;UPPER LEFT ARROW;;;; +2197;NORTH EAST ARROW;So;0;ON;;;;;N;UPPER RIGHT ARROW;;;; +2198;SOUTH EAST ARROW;So;0;ON;;;;;N;LOWER RIGHT ARROW;;;; +2199;SOUTH WEST ARROW;So;0;ON;;;;;N;LOWER LEFT ARROW;;;; +219A;LEFTWARDS ARROW WITH STROKE;Sm;0;ON;2190 0338;;;;N;LEFT ARROW WITH STROKE;;;; +219B;RIGHTWARDS ARROW WITH STROKE;Sm;0;ON;2192 0338;;;;N;RIGHT ARROW WITH STROKE;;;; +219C;LEFTWARDS WAVE ARROW;So;0;ON;;;;;N;LEFT WAVE ARROW;;;; +219D;RIGHTWARDS WAVE ARROW;So;0;ON;;;;;N;RIGHT WAVE ARROW;;;; +219E;LEFTWARDS TWO HEADED ARROW;So;0;ON;;;;;N;LEFT TWO HEADED ARROW;;;; +219F;UPWARDS TWO HEADED ARROW;So;0;ON;;;;;N;UP TWO HEADED ARROW;;;; +21A0;RIGHTWARDS TWO HEADED ARROW;Sm;0;ON;;;;;N;RIGHT TWO HEADED ARROW;;;; +21A1;DOWNWARDS TWO HEADED ARROW;So;0;ON;;;;;N;DOWN TWO HEADED ARROW;;;; +21A2;LEFTWARDS ARROW WITH TAIL;So;0;ON;;;;;N;LEFT ARROW WITH TAIL;;;; +21A3;RIGHTWARDS ARROW WITH TAIL;Sm;0;ON;;;;;N;RIGHT ARROW WITH TAIL;;;; +21A4;LEFTWARDS ARROW FROM BAR;So;0;ON;;;;;N;LEFT ARROW FROM BAR;;;; +21A5;UPWARDS ARROW FROM BAR;So;0;ON;;;;;N;UP ARROW FROM BAR;;;; +21A6;RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;RIGHT ARROW FROM BAR;;;; +21A7;DOWNWARDS ARROW FROM BAR;So;0;ON;;;;;N;DOWN ARROW FROM BAR;;;; +21A8;UP DOWN ARROW WITH BASE;So;0;ON;;;;;N;;;;; +21A9;LEFTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;LEFT ARROW WITH HOOK;;;; +21AA;RIGHTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;RIGHT ARROW WITH HOOK;;;; +21AB;LEFTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;LEFT ARROW WITH LOOP;;;; +21AC;RIGHTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;RIGHT ARROW WITH LOOP;;;; +21AD;LEFT RIGHT WAVE ARROW;So;0;ON;;;;;N;;;;; +21AE;LEFT RIGHT ARROW WITH STROKE;Sm;0;ON;2194 0338;;;;N;;;;; +21AF;DOWNWARDS ZIGZAG ARROW;So;0;ON;;;;;N;DOWN ZIGZAG ARROW;;;; +21B0;UPWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP LEFT;;;; +21B1;UPWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP RIGHT;;;; +21B2;DOWNWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP LEFT;;;; +21B3;DOWNWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP RIGHT;;;; +21B4;RIGHTWARDS ARROW WITH CORNER DOWNWARDS;So;0;ON;;;;;N;RIGHT ARROW WITH CORNER DOWN;;;; +21B5;DOWNWARDS ARROW WITH CORNER LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH CORNER LEFT;;;; +21B6;ANTICLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;; +21B7;CLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;; +21B8;NORTH WEST ARROW TO LONG BAR;So;0;ON;;;;;N;UPPER LEFT ARROW TO LONG BAR;;;; +21B9;LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR OVER RIGHT ARROW TO BAR;;;; +21BA;ANTICLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;; +21BB;CLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;; +21BC;LEFTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB UP;;;; +21BD;LEFTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB DOWN;;;; +21BE;UPWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB RIGHT;;;; +21BF;UPWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB LEFT;;;; +21C0;RIGHTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB UP;;;; +21C1;RIGHTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB DOWN;;;; +21C2;DOWNWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB RIGHT;;;; +21C3;DOWNWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB LEFT;;;; +21C4;RIGHTWARDS ARROW OVER LEFTWARDS ARROW;So;0;ON;;;;;N;RIGHT ARROW OVER LEFT ARROW;;;; +21C5;UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW;So;0;ON;;;;;N;UP ARROW LEFT OF DOWN ARROW;;;; +21C6;LEFTWARDS ARROW OVER RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT ARROW OVER RIGHT ARROW;;;; +21C7;LEFTWARDS PAIRED ARROWS;So;0;ON;;;;;N;LEFT PAIRED ARROWS;;;; +21C8;UPWARDS PAIRED ARROWS;So;0;ON;;;;;N;UP PAIRED ARROWS;;;; +21C9;RIGHTWARDS PAIRED ARROWS;So;0;ON;;;;;N;RIGHT PAIRED ARROWS;;;; +21CA;DOWNWARDS PAIRED ARROWS;So;0;ON;;;;;N;DOWN PAIRED ARROWS;;;; +21CB;LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON;So;0;ON;;;;;N;LEFT HARPOON OVER RIGHT HARPOON;;;; +21CC;RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON;So;0;ON;;;;;N;RIGHT HARPOON OVER LEFT HARPOON;;;; +21CD;LEFTWARDS DOUBLE ARROW WITH STROKE;So;0;ON;21D0 0338;;;;N;LEFT DOUBLE ARROW WITH STROKE;;;; +21CE;LEFT RIGHT DOUBLE ARROW WITH STROKE;Sm;0;ON;21D4 0338;;;;N;;;;; +21CF;RIGHTWARDS DOUBLE ARROW WITH STROKE;Sm;0;ON;21D2 0338;;;;N;RIGHT DOUBLE ARROW WITH STROKE;;;; +21D0;LEFTWARDS DOUBLE ARROW;So;0;ON;;;;;N;LEFT DOUBLE ARROW;;;; +21D1;UPWARDS DOUBLE ARROW;So;0;ON;;;;;N;UP DOUBLE ARROW;;;; +21D2;RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;RIGHT DOUBLE ARROW;;;; +21D3;DOWNWARDS DOUBLE ARROW;So;0;ON;;;;;N;DOWN DOUBLE ARROW;;;; +21D4;LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; +21D5;UP DOWN DOUBLE ARROW;So;0;ON;;;;;N;;;;; +21D6;NORTH WEST DOUBLE ARROW;So;0;ON;;;;;N;UPPER LEFT DOUBLE ARROW;;;; +21D7;NORTH EAST DOUBLE ARROW;So;0;ON;;;;;N;UPPER RIGHT DOUBLE ARROW;;;; +21D8;SOUTH EAST DOUBLE ARROW;So;0;ON;;;;;N;LOWER RIGHT DOUBLE ARROW;;;; +21D9;SOUTH WEST DOUBLE ARROW;So;0;ON;;;;;N;LOWER LEFT DOUBLE ARROW;;;; +21DA;LEFTWARDS TRIPLE ARROW;So;0;ON;;;;;N;LEFT TRIPLE ARROW;;;; +21DB;RIGHTWARDS TRIPLE ARROW;So;0;ON;;;;;N;RIGHT TRIPLE ARROW;;;; +21DC;LEFTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;LEFT SQUIGGLE ARROW;;;; +21DD;RIGHTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;RIGHT SQUIGGLE ARROW;;;; +21DE;UPWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;UP ARROW WITH DOUBLE STROKE;;;; +21DF;DOWNWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;DOWN ARROW WITH DOUBLE STROKE;;;; +21E0;LEFTWARDS DASHED ARROW;So;0;ON;;;;;N;LEFT DASHED ARROW;;;; +21E1;UPWARDS DASHED ARROW;So;0;ON;;;;;N;UP DASHED ARROW;;;; +21E2;RIGHTWARDS DASHED ARROW;So;0;ON;;;;;N;RIGHT DASHED ARROW;;;; +21E3;DOWNWARDS DASHED ARROW;So;0;ON;;;;;N;DOWN DASHED ARROW;;;; +21E4;LEFTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR;;;; +21E5;RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;RIGHT ARROW TO BAR;;;; +21E6;LEFTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE LEFT ARROW;;;; +21E7;UPWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE UP ARROW;;;; +21E8;RIGHTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE RIGHT ARROW;;;; +21E9;DOWNWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE DOWN ARROW;;;; +21EA;UPWARDS WHITE ARROW FROM BAR;So;0;ON;;;;;N;WHITE UP ARROW FROM BAR;;;; +21EB;UPWARDS WHITE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;; +21EC;UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR;So;0;ON;;;;;N;;;;; +21ED;UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR;So;0;ON;;;;;N;;;;; +21EE;UPWARDS WHITE DOUBLE ARROW;So;0;ON;;;;;N;;;;; +21EF;UPWARDS WHITE DOUBLE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;; +21F0;RIGHTWARDS WHITE ARROW FROM WALL;So;0;ON;;;;;N;;;;; +21F1;NORTH WEST ARROW TO CORNER;So;0;ON;;;;;N;;;;; +21F2;SOUTH EAST ARROW TO CORNER;So;0;ON;;;;;N;;;;; +21F3;UP DOWN WHITE ARROW;So;0;ON;;;;;N;;;;; +21F4;RIGHT ARROW WITH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +21F5;DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW;Sm;0;ON;;;;;N;;;;; +21F6;THREE RIGHTWARDS ARROWS;Sm;0;ON;;;;;N;;;;; +21F7;LEFTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21F8;RIGHTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21F9;LEFT RIGHT ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21FA;LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21FB;RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21FC;LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +21FD;LEFTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;; +21FE;RIGHTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;; +21FF;LEFT RIGHT OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;; +2200;FOR ALL;Sm;0;ON;;;;;N;;;;; +2201;COMPLEMENT;Sm;0;ON;;;;;Y;;;;; +2202;PARTIAL DIFFERENTIAL;Sm;0;ON;;;;;Y;;;;; +2203;THERE EXISTS;Sm;0;ON;;;;;Y;;;;; +2204;THERE DOES NOT EXIST;Sm;0;ON;2203 0338;;;;Y;;;;; +2205;EMPTY SET;Sm;0;ON;;;;;N;;;;; +2206;INCREMENT;Sm;0;ON;;;;;N;;;;; +2207;NABLA;Sm;0;ON;;;;;N;;;;; +2208;ELEMENT OF;Sm;0;ON;;;;;Y;;;;; +2209;NOT AN ELEMENT OF;Sm;0;ON;2208 0338;;;;Y;;;;; +220A;SMALL ELEMENT OF;Sm;0;ON;;;;;Y;;;;; +220B;CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;; +220C;DOES NOT CONTAIN AS MEMBER;Sm;0;ON;220B 0338;;;;Y;;;;; +220D;SMALL CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;; +220E;END OF PROOF;Sm;0;ON;;;;;N;;;;; +220F;N-ARY PRODUCT;Sm;0;ON;;;;;N;;;;; +2210;N-ARY COPRODUCT;Sm;0;ON;;;;;N;;;;; +2211;N-ARY SUMMATION;Sm;0;ON;;;;;Y;;;;; +2212;MINUS SIGN;Sm;0;ES;;;;;N;;;;; +2213;MINUS-OR-PLUS SIGN;Sm;0;ET;;;;;N;;;;; +2214;DOT PLUS;Sm;0;ON;;;;;N;;;;; +2215;DIVISION SLASH;Sm;0;ON;;;;;Y;;;;; +2216;SET MINUS;Sm;0;ON;;;;;Y;;;;; +2217;ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;; +2218;RING OPERATOR;Sm;0;ON;;;;;N;;;;; +2219;BULLET OPERATOR;Sm;0;ON;;;;;N;;;;; +221A;SQUARE ROOT;Sm;0;ON;;;;;Y;;;;; +221B;CUBE ROOT;Sm;0;ON;;;;;Y;;;;; +221C;FOURTH ROOT;Sm;0;ON;;;;;Y;;;;; +221D;PROPORTIONAL TO;Sm;0;ON;;;;;Y;;;;; +221E;INFINITY;Sm;0;ON;;;;;N;;;;; +221F;RIGHT ANGLE;Sm;0;ON;;;;;Y;;;;; +2220;ANGLE;Sm;0;ON;;;;;Y;;;;; +2221;MEASURED ANGLE;Sm;0;ON;;;;;Y;;;;; +2222;SPHERICAL ANGLE;Sm;0;ON;;;;;Y;;;;; +2223;DIVIDES;Sm;0;ON;;;;;N;;;;; +2224;DOES NOT DIVIDE;Sm;0;ON;2223 0338;;;;Y;;;;; +2225;PARALLEL TO;Sm;0;ON;;;;;N;;;;; +2226;NOT PARALLEL TO;Sm;0;ON;2225 0338;;;;Y;;;;; +2227;LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2228;LOGICAL OR;Sm;0;ON;;;;;N;;;;; +2229;INTERSECTION;Sm;0;ON;;;;;N;;;;; +222A;UNION;Sm;0;ON;;;;;N;;;;; +222B;INTEGRAL;Sm;0;ON;;;;;Y;;;;; +222C;DOUBLE INTEGRAL;Sm;0;ON; 222B 222B;;;;Y;;;;; +222D;TRIPLE INTEGRAL;Sm;0;ON; 222B 222B 222B;;;;Y;;;;; +222E;CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;; +222F;SURFACE INTEGRAL;Sm;0;ON; 222E 222E;;;;Y;;;;; +2230;VOLUME INTEGRAL;Sm;0;ON; 222E 222E 222E;;;;Y;;;;; +2231;CLOCKWISE INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2232;CLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2233;ANTICLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2234;THEREFORE;Sm;0;ON;;;;;N;;;;; +2235;BECAUSE;Sm;0;ON;;;;;N;;;;; +2236;RATIO;Sm;0;ON;;;;;N;;;;; +2237;PROPORTION;Sm;0;ON;;;;;N;;;;; +2238;DOT MINUS;Sm;0;ON;;;;;N;;;;; +2239;EXCESS;Sm;0;ON;;;;;Y;;;;; +223A;GEOMETRIC PROPORTION;Sm;0;ON;;;;;N;;;;; +223B;HOMOTHETIC;Sm;0;ON;;;;;Y;;;;; +223C;TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +223D;REVERSED TILDE;Sm;0;ON;;;;;Y;;;;; +223E;INVERTED LAZY S;Sm;0;ON;;;;;Y;;;;; +223F;SINE WAVE;Sm;0;ON;;;;;Y;;;;; +2240;WREATH PRODUCT;Sm;0;ON;;;;;Y;;;;; +2241;NOT TILDE;Sm;0;ON;223C 0338;;;;Y;;;;; +2242;MINUS TILDE;Sm;0;ON;;;;;Y;;;;; +2243;ASYMPTOTICALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2244;NOT ASYMPTOTICALLY EQUAL TO;Sm;0;ON;2243 0338;;;;Y;;;;; +2245;APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2246;APPROXIMATELY BUT NOT ACTUALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2247;NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO;Sm;0;ON;2245 0338;;;;Y;;;;; +2248;ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2249;NOT ALMOST EQUAL TO;Sm;0;ON;2248 0338;;;;Y;;;;; +224A;ALMOST EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +224B;TRIPLE TILDE;Sm;0;ON;;;;;Y;;;;; +224C;ALL EQUAL TO;Sm;0;ON;;;;;Y;;;;; +224D;EQUIVALENT TO;Sm;0;ON;;;;;N;;;;; +224E;GEOMETRICALLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;; +224F;DIFFERENCE BETWEEN;Sm;0;ON;;;;;N;;;;; +2250;APPROACHES THE LIMIT;Sm;0;ON;;;;;N;;;;; +2251;GEOMETRICALLY EQUAL TO;Sm;0;ON;;;;;N;;;;; +2252;APPROXIMATELY EQUAL TO OR THE IMAGE OF;Sm;0;ON;;;;;Y;;;;; +2253;IMAGE OF OR APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2254;COLON EQUALS;Sm;0;ON;;;;;Y;COLON EQUAL;;;; +2255;EQUALS COLON;Sm;0;ON;;;;;Y;EQUAL COLON;;;; +2256;RING IN EQUAL TO;Sm;0;ON;;;;;N;;;;; +2257;RING EQUAL TO;Sm;0;ON;;;;;N;;;;; +2258;CORRESPONDS TO;Sm;0;ON;;;;;N;;;;; +2259;ESTIMATES;Sm;0;ON;;;;;N;;;;; +225A;EQUIANGULAR TO;Sm;0;ON;;;;;N;;;;; +225B;STAR EQUALS;Sm;0;ON;;;;;N;;;;; +225C;DELTA EQUAL TO;Sm;0;ON;;;;;N;;;;; +225D;EQUAL TO BY DEFINITION;Sm;0;ON;;;;;N;;;;; +225E;MEASURED BY;Sm;0;ON;;;;;N;;;;; +225F;QUESTIONED EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2260;NOT EQUAL TO;Sm;0;ON;003D 0338;;;;Y;;;;; +2261;IDENTICAL TO;Sm;0;ON;;;;;N;;;;; +2262;NOT IDENTICAL TO;Sm;0;ON;2261 0338;;;;Y;;;;; +2263;STRICTLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;; +2264;LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUAL TO;;;; +2265;GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUAL TO;;;; +2266;LESS-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OVER EQUAL TO;;;; +2267;GREATER-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OVER EQUAL TO;;;; +2268;LESS-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUAL TO;;;; +2269;GREATER-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUAL TO;;;; +226A;MUCH LESS-THAN;Sm;0;ON;;;;;Y;MUCH LESS THAN;;;; +226B;MUCH GREATER-THAN;Sm;0;ON;;;;;Y;MUCH GREATER THAN;;;; +226C;BETWEEN;Sm;0;ON;;;;;N;;;;; +226D;NOT EQUIVALENT TO;Sm;0;ON;224D 0338;;;;N;;;;; +226E;NOT LESS-THAN;Sm;0;ON;003C 0338;;;;Y;NOT LESS THAN;;;; +226F;NOT GREATER-THAN;Sm;0;ON;003E 0338;;;;Y;NOT GREATER THAN;;;; +2270;NEITHER LESS-THAN NOR EQUAL TO;Sm;0;ON;2264 0338;;;;Y;NEITHER LESS THAN NOR EQUAL TO;;;; +2271;NEITHER GREATER-THAN NOR EQUAL TO;Sm;0;ON;2265 0338;;;;Y;NEITHER GREATER THAN NOR EQUAL TO;;;; +2272;LESS-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUIVALENT TO;;;; +2273;GREATER-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUIVALENT TO;;;; +2274;NEITHER LESS-THAN NOR EQUIVALENT TO;Sm;0;ON;2272 0338;;;;Y;NEITHER LESS THAN NOR EQUIVALENT TO;;;; +2275;NEITHER GREATER-THAN NOR EQUIVALENT TO;Sm;0;ON;2273 0338;;;;Y;NEITHER GREATER THAN NOR EQUIVALENT TO;;;; +2276;LESS-THAN OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN OR GREATER THAN;;;; +2277;GREATER-THAN OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN OR LESS THAN;;;; +2278;NEITHER LESS-THAN NOR GREATER-THAN;Sm;0;ON;2276 0338;;;;Y;NEITHER LESS THAN NOR GREATER THAN;;;; +2279;NEITHER GREATER-THAN NOR LESS-THAN;Sm;0;ON;2277 0338;;;;Y;NEITHER GREATER THAN NOR LESS THAN;;;; +227A;PRECEDES;Sm;0;ON;;;;;Y;;;;; +227B;SUCCEEDS;Sm;0;ON;;;;;Y;;;;; +227C;PRECEDES OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +227D;SUCCEEDS OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +227E;PRECEDES OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; +227F;SUCCEEDS OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; +2280;DOES NOT PRECEDE;Sm;0;ON;227A 0338;;;;Y;;;;; +2281;DOES NOT SUCCEED;Sm;0;ON;227B 0338;;;;Y;;;;; +2282;SUBSET OF;Sm;0;ON;;;;;Y;;;;; +2283;SUPERSET OF;Sm;0;ON;;;;;Y;;;;; +2284;NOT A SUBSET OF;Sm;0;ON;2282 0338;;;;Y;;;;; +2285;NOT A SUPERSET OF;Sm;0;ON;2283 0338;;;;Y;;;;; +2286;SUBSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2287;SUPERSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2288;NEITHER A SUBSET OF NOR EQUAL TO;Sm;0;ON;2286 0338;;;;Y;;;;; +2289;NEITHER A SUPERSET OF NOR EQUAL TO;Sm;0;ON;2287 0338;;;;Y;;;;; +228A;SUBSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUBSET OF OR NOT EQUAL TO;;;; +228B;SUPERSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUPERSET OF OR NOT EQUAL TO;;;; +228C;MULTISET;Sm;0;ON;;;;;Y;;;;; +228D;MULTISET MULTIPLICATION;Sm;0;ON;;;;;N;;;;; +228E;MULTISET UNION;Sm;0;ON;;;;;N;;;;; +228F;SQUARE IMAGE OF;Sm;0;ON;;;;;Y;;;;; +2290;SQUARE ORIGINAL OF;Sm;0;ON;;;;;Y;;;;; +2291;SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2292;SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2293;SQUARE CAP;Sm;0;ON;;;;;N;;;;; +2294;SQUARE CUP;Sm;0;ON;;;;;N;;;;; +2295;CIRCLED PLUS;Sm;0;ON;;;;;N;;;;; +2296;CIRCLED MINUS;Sm;0;ON;;;;;N;;;;; +2297;CIRCLED TIMES;Sm;0;ON;;;;;N;;;;; +2298;CIRCLED DIVISION SLASH;Sm;0;ON;;;;;Y;;;;; +2299;CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;; +229A;CIRCLED RING OPERATOR;Sm;0;ON;;;;;N;;;;; +229B;CIRCLED ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;; +229C;CIRCLED EQUALS;Sm;0;ON;;;;;N;;;;; +229D;CIRCLED DASH;Sm;0;ON;;;;;N;;;;; +229E;SQUARED PLUS;Sm;0;ON;;;;;N;;;;; +229F;SQUARED MINUS;Sm;0;ON;;;;;N;;;;; +22A0;SQUARED TIMES;Sm;0;ON;;;;;N;;;;; +22A1;SQUARED DOT OPERATOR;Sm;0;ON;;;;;N;;;;; +22A2;RIGHT TACK;Sm;0;ON;;;;;Y;;;;; +22A3;LEFT TACK;Sm;0;ON;;;;;Y;;;;; +22A4;DOWN TACK;Sm;0;ON;;;;;N;;;;; +22A5;UP TACK;Sm;0;ON;;;;;N;;;;; +22A6;ASSERTION;Sm;0;ON;;;;;Y;;;;; +22A7;MODELS;Sm;0;ON;;;;;Y;;;;; +22A8;TRUE;Sm;0;ON;;;;;Y;;;;; +22A9;FORCES;Sm;0;ON;;;;;Y;;;;; +22AA;TRIPLE VERTICAL BAR RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +22AB;DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +22AC;DOES NOT PROVE;Sm;0;ON;22A2 0338;;;;Y;;;;; +22AD;NOT TRUE;Sm;0;ON;22A8 0338;;;;Y;;;;; +22AE;DOES NOT FORCE;Sm;0;ON;22A9 0338;;;;Y;;;;; +22AF;NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;22AB 0338;;;;Y;;;;; +22B0;PRECEDES UNDER RELATION;Sm;0;ON;;;;;Y;;;;; +22B1;SUCCEEDS UNDER RELATION;Sm;0;ON;;;;;Y;;;;; +22B2;NORMAL SUBGROUP OF;Sm;0;ON;;;;;Y;;;;; +22B3;CONTAINS AS NORMAL SUBGROUP;Sm;0;ON;;;;;Y;;;;; +22B4;NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +22B5;CONTAINS AS NORMAL SUBGROUP OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +22B6;ORIGINAL OF;Sm;0;ON;;;;;Y;;;;; +22B7;IMAGE OF;Sm;0;ON;;;;;Y;;;;; +22B8;MULTIMAP;Sm;0;ON;;;;;Y;;;;; +22B9;HERMITIAN CONJUGATE MATRIX;Sm;0;ON;;;;;N;;;;; +22BA;INTERCALATE;Sm;0;ON;;;;;N;;;;; +22BB;XOR;Sm;0;ON;;;;;N;;;;; +22BC;NAND;Sm;0;ON;;;;;N;;;;; +22BD;NOR;Sm;0;ON;;;;;N;;;;; +22BE;RIGHT ANGLE WITH ARC;Sm;0;ON;;;;;Y;;;;; +22BF;RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;; +22C0;N-ARY LOGICAL AND;Sm;0;ON;;;;;N;;;;; +22C1;N-ARY LOGICAL OR;Sm;0;ON;;;;;N;;;;; +22C2;N-ARY INTERSECTION;Sm;0;ON;;;;;N;;;;; +22C3;N-ARY UNION;Sm;0;ON;;;;;N;;;;; +22C4;DIAMOND OPERATOR;Sm;0;ON;;;;;N;;;;; +22C5;DOT OPERATOR;Sm;0;ON;;;;;N;;;;; +22C6;STAR OPERATOR;Sm;0;ON;;;;;N;;;;; +22C7;DIVISION TIMES;Sm;0;ON;;;;;N;;;;; +22C8;BOWTIE;Sm;0;ON;;;;;N;;;;; +22C9;LEFT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; +22CA;RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; +22CB;LEFT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; +22CC;RIGHT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; +22CD;REVERSED TILDE EQUALS;Sm;0;ON;;;;;Y;;;;; +22CE;CURLY LOGICAL OR;Sm;0;ON;;;;;N;;;;; +22CF;CURLY LOGICAL AND;Sm;0;ON;;;;;N;;;;; +22D0;DOUBLE SUBSET;Sm;0;ON;;;;;Y;;;;; +22D1;DOUBLE SUPERSET;Sm;0;ON;;;;;Y;;;;; +22D2;DOUBLE INTERSECTION;Sm;0;ON;;;;;N;;;;; +22D3;DOUBLE UNION;Sm;0;ON;;;;;N;;;;; +22D4;PITCHFORK;Sm;0;ON;;;;;N;;;;; +22D5;EQUAL AND PARALLEL TO;Sm;0;ON;;;;;N;;;;; +22D6;LESS-THAN WITH DOT;Sm;0;ON;;;;;Y;LESS THAN WITH DOT;;;; +22D7;GREATER-THAN WITH DOT;Sm;0;ON;;;;;Y;GREATER THAN WITH DOT;;;; +22D8;VERY MUCH LESS-THAN;Sm;0;ON;;;;;Y;VERY MUCH LESS THAN;;;; +22D9;VERY MUCH GREATER-THAN;Sm;0;ON;;;;;Y;VERY MUCH GREATER THAN;;;; +22DA;LESS-THAN EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN EQUAL TO OR GREATER THAN;;;; +22DB;GREATER-THAN EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN EQUAL TO OR LESS THAN;;;; +22DC;EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR LESS THAN;;;; +22DD;EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR GREATER THAN;;;; +22DE;EQUAL TO OR PRECEDES;Sm;0;ON;;;;;Y;;;;; +22DF;EQUAL TO OR SUCCEEDS;Sm;0;ON;;;;;Y;;;;; +22E0;DOES NOT PRECEDE OR EQUAL;Sm;0;ON;227C 0338;;;;Y;;;;; +22E1;DOES NOT SUCCEED OR EQUAL;Sm;0;ON;227D 0338;;;;Y;;;;; +22E2;NOT SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;2291 0338;;;;Y;;;;; +22E3;NOT SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;2292 0338;;;;Y;;;;; +22E4;SQUARE IMAGE OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +22E5;SQUARE ORIGINAL OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +22E6;LESS-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUIVALENT TO;;;; +22E7;GREATER-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUIVALENT TO;;;; +22E8;PRECEDES BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; +22E9;SUCCEEDS BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; +22EA;NOT NORMAL SUBGROUP OF;Sm;0;ON;22B2 0338;;;;Y;;;;; +22EB;DOES NOT CONTAIN AS NORMAL SUBGROUP;Sm;0;ON;22B3 0338;;;;Y;;;;; +22EC;NOT NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;22B4 0338;;;;Y;;;;; +22ED;DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL;Sm;0;ON;22B5 0338;;;;Y;;;;; +22EE;VERTICAL ELLIPSIS;Sm;0;ON;;;;;N;;;;; +22EF;MIDLINE HORIZONTAL ELLIPSIS;Sm;0;ON;;;;;N;;;;; +22F0;UP RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;; +22F1;DOWN RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;; +22F2;ELEMENT OF WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22F3;ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22F4;SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22F5;ELEMENT OF WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +22F6;ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +22F7;SMALL ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +22F8;ELEMENT OF WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +22F9;ELEMENT OF WITH TWO HORIZONTAL STROKES;Sm;0;ON;;;;;Y;;;;; +22FA;CONTAINS WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22FB;CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22FC;SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +22FD;CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +22FE;SMALL CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +22FF;Z NOTATION BAG MEMBERSHIP;Sm;0;ON;;;;;Y;;;;; +2300;DIAMETER SIGN;So;0;ON;;;;;N;;;;; +2301;ELECTRIC ARROW;So;0;ON;;;;;N;;;;; +2302;HOUSE;So;0;ON;;;;;N;;;;; +2303;UP ARROWHEAD;So;0;ON;;;;;N;;;;; +2304;DOWN ARROWHEAD;So;0;ON;;;;;N;;;;; +2305;PROJECTIVE;So;0;ON;;;;;N;;;;; +2306;PERSPECTIVE;So;0;ON;;;;;N;;;;; +2307;WAVY LINE;So;0;ON;;;;;N;;;;; +2308;LEFT CEILING;Ps;0;ON;;;;;Y;;;;; +2309;RIGHT CEILING;Pe;0;ON;;;;;Y;;;;; +230A;LEFT FLOOR;Ps;0;ON;;;;;Y;;;;; +230B;RIGHT FLOOR;Pe;0;ON;;;;;Y;;;;; +230C;BOTTOM RIGHT CROP;So;0;ON;;;;;N;;;;; +230D;BOTTOM LEFT CROP;So;0;ON;;;;;N;;;;; +230E;TOP RIGHT CROP;So;0;ON;;;;;N;;;;; +230F;TOP LEFT CROP;So;0;ON;;;;;N;;;;; +2310;REVERSED NOT SIGN;So;0;ON;;;;;N;;;;; +2311;SQUARE LOZENGE;So;0;ON;;;;;N;;;;; +2312;ARC;So;0;ON;;;;;N;;;;; +2313;SEGMENT;So;0;ON;;;;;N;;;;; +2314;SECTOR;So;0;ON;;;;;N;;;;; +2315;TELEPHONE RECORDER;So;0;ON;;;;;N;;;;; +2316;POSITION INDICATOR;So;0;ON;;;;;N;;;;; +2317;VIEWDATA SQUARE;So;0;ON;;;;;N;;;;; +2318;PLACE OF INTEREST SIGN;So;0;ON;;;;;N;COMMAND KEY;;;; +2319;TURNED NOT SIGN;So;0;ON;;;;;N;;;;; +231A;WATCH;So;0;ON;;;;;N;;;;; +231B;HOURGLASS;So;0;ON;;;;;N;;;;; +231C;TOP LEFT CORNER;So;0;ON;;;;;N;;;;; +231D;TOP RIGHT CORNER;So;0;ON;;;;;N;;;;; +231E;BOTTOM LEFT CORNER;So;0;ON;;;;;N;;;;; +231F;BOTTOM RIGHT CORNER;So;0;ON;;;;;N;;;;; +2320;TOP HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2321;BOTTOM HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2322;FROWN;So;0;ON;;;;;N;;;;; +2323;SMILE;So;0;ON;;;;;N;;;;; +2324;UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS;So;0;ON;;;;;N;ENTER KEY;;;; +2325;OPTION KEY;So;0;ON;;;;;N;;;;; +2326;ERASE TO THE RIGHT;So;0;ON;;;;;N;DELETE TO THE RIGHT KEY;;;; +2327;X IN A RECTANGLE BOX;So;0;ON;;;;;N;CLEAR KEY;;;; +2328;KEYBOARD;So;0;ON;;;;;N;;;;; +2329;LEFT-POINTING ANGLE BRACKET;Ps;0;ON;3008;;;;Y;BRA;;;; +232A;RIGHT-POINTING ANGLE BRACKET;Pe;0;ON;3009;;;;Y;KET;;;; +232B;ERASE TO THE LEFT;So;0;ON;;;;;N;DELETE TO THE LEFT KEY;;;; +232C;BENZENE RING;So;0;ON;;;;;N;;;;; +232D;CYLINDRICITY;So;0;ON;;;;;N;;;;; +232E;ALL AROUND-PROFILE;So;0;ON;;;;;N;;;;; +232F;SYMMETRY;So;0;ON;;;;;N;;;;; +2330;TOTAL RUNOUT;So;0;ON;;;;;N;;;;; +2331;DIMENSION ORIGIN;So;0;ON;;;;;N;;;;; +2332;CONICAL TAPER;So;0;ON;;;;;N;;;;; +2333;SLOPE;So;0;ON;;;;;N;;;;; +2334;COUNTERBORE;So;0;ON;;;;;N;;;;; +2335;COUNTERSINK;So;0;ON;;;;;N;;;;; +2336;APL FUNCTIONAL SYMBOL I-BEAM;So;0;L;;;;;N;;;;; +2337;APL FUNCTIONAL SYMBOL SQUISH QUAD;So;0;L;;;;;N;;;;; +2338;APL FUNCTIONAL SYMBOL QUAD EQUAL;So;0;L;;;;;N;;;;; +2339;APL FUNCTIONAL SYMBOL QUAD DIVIDE;So;0;L;;;;;N;;;;; +233A;APL FUNCTIONAL SYMBOL QUAD DIAMOND;So;0;L;;;;;N;;;;; +233B;APL FUNCTIONAL SYMBOL QUAD JOT;So;0;L;;;;;N;;;;; +233C;APL FUNCTIONAL SYMBOL QUAD CIRCLE;So;0;L;;;;;N;;;;; +233D;APL FUNCTIONAL SYMBOL CIRCLE STILE;So;0;L;;;;;N;;;;; +233E;APL FUNCTIONAL SYMBOL CIRCLE JOT;So;0;L;;;;;N;;;;; +233F;APL FUNCTIONAL SYMBOL SLASH BAR;So;0;L;;;;;N;;;;; +2340;APL FUNCTIONAL SYMBOL BACKSLASH BAR;So;0;L;;;;;N;;;;; +2341;APL FUNCTIONAL SYMBOL QUAD SLASH;So;0;L;;;;;N;;;;; +2342;APL FUNCTIONAL SYMBOL QUAD BACKSLASH;So;0;L;;;;;N;;;;; +2343;APL FUNCTIONAL SYMBOL QUAD LESS-THAN;So;0;L;;;;;N;;;;; +2344;APL FUNCTIONAL SYMBOL QUAD GREATER-THAN;So;0;L;;;;;N;;;;; +2345;APL FUNCTIONAL SYMBOL LEFTWARDS VANE;So;0;L;;;;;N;;;;; +2346;APL FUNCTIONAL SYMBOL RIGHTWARDS VANE;So;0;L;;;;;N;;;;; +2347;APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW;So;0;L;;;;;N;;;;; +2348;APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW;So;0;L;;;;;N;;;;; +2349;APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH;So;0;L;;;;;N;;;;; +234A;APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR;So;0;L;;;;;N;;;;; +234B;APL FUNCTIONAL SYMBOL DELTA STILE;So;0;L;;;;;N;;;;; +234C;APL FUNCTIONAL SYMBOL QUAD DOWN CARET;So;0;L;;;;;N;;;;; +234D;APL FUNCTIONAL SYMBOL QUAD DELTA;So;0;L;;;;;N;;;;; +234E;APL FUNCTIONAL SYMBOL DOWN TACK JOT;So;0;L;;;;;N;;;;; +234F;APL FUNCTIONAL SYMBOL UPWARDS VANE;So;0;L;;;;;N;;;;; +2350;APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW;So;0;L;;;;;N;;;;; +2351;APL FUNCTIONAL SYMBOL UP TACK OVERBAR;So;0;L;;;;;N;;;;; +2352;APL FUNCTIONAL SYMBOL DEL STILE;So;0;L;;;;;N;;;;; +2353;APL FUNCTIONAL SYMBOL QUAD UP CARET;So;0;L;;;;;N;;;;; +2354;APL FUNCTIONAL SYMBOL QUAD DEL;So;0;L;;;;;N;;;;; +2355;APL FUNCTIONAL SYMBOL UP TACK JOT;So;0;L;;;;;N;;;;; +2356;APL FUNCTIONAL SYMBOL DOWNWARDS VANE;So;0;L;;;;;N;;;;; +2357;APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW;So;0;L;;;;;N;;;;; +2358;APL FUNCTIONAL SYMBOL QUOTE UNDERBAR;So;0;L;;;;;N;;;;; +2359;APL FUNCTIONAL SYMBOL DELTA UNDERBAR;So;0;L;;;;;N;;;;; +235A;APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR;So;0;L;;;;;N;;;;; +235B;APL FUNCTIONAL SYMBOL JOT UNDERBAR;So;0;L;;;;;N;;;;; +235C;APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR;So;0;L;;;;;N;;;;; +235D;APL FUNCTIONAL SYMBOL UP SHOE JOT;So;0;L;;;;;N;;;;; +235E;APL FUNCTIONAL SYMBOL QUOTE QUAD;So;0;L;;;;;N;;;;; +235F;APL FUNCTIONAL SYMBOL CIRCLE STAR;So;0;L;;;;;N;;;;; +2360;APL FUNCTIONAL SYMBOL QUAD COLON;So;0;L;;;;;N;;;;; +2361;APL FUNCTIONAL SYMBOL UP TACK DIAERESIS;So;0;L;;;;;N;;;;; +2362;APL FUNCTIONAL SYMBOL DEL DIAERESIS;So;0;L;;;;;N;;;;; +2363;APL FUNCTIONAL SYMBOL STAR DIAERESIS;So;0;L;;;;;N;;;;; +2364;APL FUNCTIONAL SYMBOL JOT DIAERESIS;So;0;L;;;;;N;;;;; +2365;APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS;So;0;L;;;;;N;;;;; +2366;APL FUNCTIONAL SYMBOL DOWN SHOE STILE;So;0;L;;;;;N;;;;; +2367;APL FUNCTIONAL SYMBOL LEFT SHOE STILE;So;0;L;;;;;N;;;;; +2368;APL FUNCTIONAL SYMBOL TILDE DIAERESIS;So;0;L;;;;;N;;;;; +2369;APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS;So;0;L;;;;;N;;;;; +236A;APL FUNCTIONAL SYMBOL COMMA BAR;So;0;L;;;;;N;;;;; +236B;APL FUNCTIONAL SYMBOL DEL TILDE;So;0;L;;;;;N;;;;; +236C;APL FUNCTIONAL SYMBOL ZILDE;So;0;L;;;;;N;;;;; +236D;APL FUNCTIONAL SYMBOL STILE TILDE;So;0;L;;;;;N;;;;; +236E;APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR;So;0;L;;;;;N;;;;; +236F;APL FUNCTIONAL SYMBOL QUAD NOT EQUAL;So;0;L;;;;;N;;;;; +2370;APL FUNCTIONAL SYMBOL QUAD QUESTION;So;0;L;;;;;N;;;;; +2371;APL FUNCTIONAL SYMBOL DOWN CARET TILDE;So;0;L;;;;;N;;;;; +2372;APL FUNCTIONAL SYMBOL UP CARET TILDE;So;0;L;;;;;N;;;;; +2373;APL FUNCTIONAL SYMBOL IOTA;So;0;L;;;;;N;;;;; +2374;APL FUNCTIONAL SYMBOL RHO;So;0;L;;;;;N;;;;; +2375;APL FUNCTIONAL SYMBOL OMEGA;So;0;L;;;;;N;;;;; +2376;APL FUNCTIONAL SYMBOL ALPHA UNDERBAR;So;0;L;;;;;N;;;;; +2377;APL FUNCTIONAL SYMBOL EPSILON UNDERBAR;So;0;L;;;;;N;;;;; +2378;APL FUNCTIONAL SYMBOL IOTA UNDERBAR;So;0;L;;;;;N;;;;; +2379;APL FUNCTIONAL SYMBOL OMEGA UNDERBAR;So;0;L;;;;;N;;;;; +237A;APL FUNCTIONAL SYMBOL ALPHA;So;0;L;;;;;N;;;;; +237B;NOT CHECK MARK;So;0;ON;;;;;N;;;;; +237C;RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW;Sm;0;ON;;;;;N;;;;; +237D;SHOULDERED OPEN BOX;So;0;ON;;;;;N;;;;; +237E;BELL SYMBOL;So;0;ON;;;;;N;;;;; +237F;VERTICAL LINE WITH MIDDLE DOT;So;0;ON;;;;;N;;;;; +2380;INSERTION SYMBOL;So;0;ON;;;;;N;;;;; +2381;CONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;; +2382;DISCONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;; +2383;EMPHASIS SYMBOL;So;0;ON;;;;;N;;;;; +2384;COMPOSITION SYMBOL;So;0;ON;;;;;N;;;;; +2385;WHITE SQUARE WITH CENTRE VERTICAL LINE;So;0;ON;;;;;N;;;;; +2386;ENTER SYMBOL;So;0;ON;;;;;N;;;;; +2387;ALTERNATIVE KEY SYMBOL;So;0;ON;;;;;N;;;;; +2388;HELM SYMBOL;So;0;ON;;;;;N;;;;; +2389;CIRCLED HORIZONTAL BAR WITH NOTCH;So;0;ON;;;;;N;;;;; +238A;CIRCLED TRIANGLE DOWN;So;0;ON;;;;;N;;;;; +238B;BROKEN CIRCLE WITH NORTHWEST ARROW;So;0;ON;;;;;N;;;;; +238C;UNDO SYMBOL;So;0;ON;;;;;N;;;;; +238D;MONOSTABLE SYMBOL;So;0;ON;;;;;N;;;;; +238E;HYSTERESIS SYMBOL;So;0;ON;;;;;N;;;;; +238F;OPEN-CIRCUIT-OUTPUT H-TYPE SYMBOL;So;0;ON;;;;;N;;;;; +2390;OPEN-CIRCUIT-OUTPUT L-TYPE SYMBOL;So;0;ON;;;;;N;;;;; +2391;PASSIVE-PULL-DOWN-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;; +2392;PASSIVE-PULL-UP-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;; +2393;DIRECT CURRENT SYMBOL FORM TWO;So;0;ON;;;;;N;;;;; +2394;SOFTWARE-FUNCTION SYMBOL;So;0;ON;;;;;N;;;;; +2395;APL FUNCTIONAL SYMBOL QUAD;So;0;L;;;;;N;;;;; +2396;DECIMAL SEPARATOR KEY SYMBOL;So;0;ON;;;;;N;;;;; +2397;PREVIOUS PAGE;So;0;ON;;;;;N;;;;; +2398;NEXT PAGE;So;0;ON;;;;;N;;;;; +2399;PRINT SCREEN SYMBOL;So;0;ON;;;;;N;;;;; +239A;CLEAR SCREEN SYMBOL;So;0;ON;;;;;N;;;;; +239B;LEFT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;; +239C;LEFT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;; +239D;LEFT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;; +239E;RIGHT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;; +239F;RIGHT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;; +23A0;RIGHT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;; +23A1;LEFT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;; +23A2;LEFT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;; +23A3;LEFT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;; +23A4;RIGHT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;; +23A5;RIGHT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;; +23A6;RIGHT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;; +23A7;LEFT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;; +23A8;LEFT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;; +23A9;LEFT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;; +23AA;CURLY BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;; +23AB;RIGHT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;; +23AC;RIGHT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;; +23AD;RIGHT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;; +23AE;INTEGRAL EXTENSION;Sm;0;ON;;;;;N;;;;; +23AF;HORIZONTAL LINE EXTENSION;Sm;0;ON;;;;;N;;;;; +23B0;UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;; +23B1;UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;; +23B2;SUMMATION TOP;Sm;0;ON;;;;;N;;;;; +23B3;SUMMATION BOTTOM;Sm;0;ON;;;;;N;;;;; +23B4;TOP SQUARE BRACKET;So;0;ON;;;;;N;;;;; +23B5;BOTTOM SQUARE BRACKET;So;0;ON;;;;;N;;;;; +23B6;BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET;So;0;ON;;;;;N;;;;; +23B7;RADICAL SYMBOL BOTTOM;So;0;ON;;;;;N;;;;; +23B8;LEFT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;; +23B9;RIGHT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;; +23BA;HORIZONTAL SCAN LINE-1;So;0;ON;;;;;N;;;;; +23BB;HORIZONTAL SCAN LINE-3;So;0;ON;;;;;N;;;;; +23BC;HORIZONTAL SCAN LINE-7;So;0;ON;;;;;N;;;;; +23BD;HORIZONTAL SCAN LINE-9;So;0;ON;;;;;N;;;;; +23BE;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP RIGHT;So;0;ON;;;;;N;;;;; +23BF;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM RIGHT;So;0;ON;;;;;N;;;;; +23C0;DENTISTRY SYMBOL LIGHT VERTICAL WITH CIRCLE;So;0;ON;;;;;N;;;;; +23C1;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;; +23C2;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;; +23C3;DENTISTRY SYMBOL LIGHT VERTICAL WITH TRIANGLE;So;0;ON;;;;;N;;;;; +23C4;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;; +23C5;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;; +23C6;DENTISTRY SYMBOL LIGHT VERTICAL AND WAVE;So;0;ON;;;;;N;;;;; +23C7;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;; +23C8;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;; +23C9;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;;;;; +23CA;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;;;;; +23CB;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP LEFT;So;0;ON;;;;;N;;;;; +23CC;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM LEFT;So;0;ON;;;;;N;;;;; +23CD;SQUARE FOOT;So;0;ON;;;;;N;;;;; +23CE;RETURN SYMBOL;So;0;ON;;;;;N;;;;; +23CF;EJECT SYMBOL;So;0;ON;;;;;N;;;;; +23D0;VERTICAL LINE EXTENSION;So;0;ON;;;;;N;;;;; +23D1;METRICAL BREVE;So;0;ON;;;;;N;;;;; +23D2;METRICAL LONG OVER SHORT;So;0;ON;;;;;N;;;;; +23D3;METRICAL SHORT OVER LONG;So;0;ON;;;;;N;;;;; +23D4;METRICAL LONG OVER TWO SHORTS;So;0;ON;;;;;N;;;;; +23D5;METRICAL TWO SHORTS OVER LONG;So;0;ON;;;;;N;;;;; +23D6;METRICAL TWO SHORTS JOINED;So;0;ON;;;;;N;;;;; +23D7;METRICAL TRISEME;So;0;ON;;;;;N;;;;; +23D8;METRICAL TETRASEME;So;0;ON;;;;;N;;;;; +23D9;METRICAL PENTASEME;So;0;ON;;;;;N;;;;; +23DA;EARTH GROUND;So;0;ON;;;;;N;;;;; +23DB;FUSE;So;0;ON;;;;;N;;;;; +23DC;TOP PARENTHESIS;Sm;0;ON;;;;;N;;;;; +23DD;BOTTOM PARENTHESIS;Sm;0;ON;;;;;N;;;;; +23DE;TOP CURLY BRACKET;Sm;0;ON;;;;;N;;;;; +23DF;BOTTOM CURLY BRACKET;Sm;0;ON;;;;;N;;;;; +23E0;TOP TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;;;; +23E1;BOTTOM TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;;;; +23E2;WHITE TRAPEZIUM;So;0;ON;;;;;N;;;;; +23E3;BENZENE RING WITH CIRCLE;So;0;ON;;;;;N;;;;; +23E4;STRAIGHTNESS;So;0;ON;;;;;N;;;;; +23E5;FLATNESS;So;0;ON;;;;;N;;;;; +23E6;AC CURRENT;So;0;ON;;;;;N;;;;; +23E7;ELECTRICAL INTERSECTION;So;0;ON;;;;;N;;;;; +23E8;DECIMAL EXPONENT SYMBOL;So;0;ON;;;;;N;;;;; +23E9;BLACK RIGHT-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;; +23EA;BLACK LEFT-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;; +23EB;BLACK UP-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;; +23EC;BLACK DOWN-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;; +23ED;BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR;So;0;ON;;;;;N;;;;; +23EE;BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR;So;0;ON;;;;;N;;;;; +23EF;BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR;So;0;ON;;;;;N;;;;; +23F0;ALARM CLOCK;So;0;ON;;;;;N;;;;; +23F1;STOPWATCH;So;0;ON;;;;;N;;;;; +23F2;TIMER CLOCK;So;0;ON;;;;;N;;;;; +23F3;HOURGLASS WITH FLOWING SAND;So;0;ON;;;;;N;;;;; +23F4;BLACK MEDIUM LEFT-POINTING TRIANGLE;So;0;ON;;;;;N;;;;; +23F5;BLACK MEDIUM RIGHT-POINTING TRIANGLE;So;0;ON;;;;;N;;;;; +23F6;BLACK MEDIUM UP-POINTING TRIANGLE;So;0;ON;;;;;N;;;;; +23F7;BLACK MEDIUM DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;;;;; +23F8;DOUBLE VERTICAL BAR;So;0;ON;;;;;N;;;;; +23F9;BLACK SQUARE FOR STOP;So;0;ON;;;;;N;;;;; +23FA;BLACK CIRCLE FOR RECORD;So;0;ON;;;;;N;;;;; +23FB;POWER SYMBOL;So;0;ON;;;;;N;;;;; +23FC;POWER ON-OFF SYMBOL;So;0;ON;;;;;N;;;;; +23FD;POWER ON SYMBOL;So;0;ON;;;;;N;;;;; +23FE;POWER SLEEP SYMBOL;So;0;ON;;;;;N;;;;; +23FF;OBSERVER EYE SYMBOL;So;0;ON;;;;;N;;;;; +2400;SYMBOL FOR NULL;So;0;ON;;;;;N;GRAPHIC FOR NULL;;;; +2401;SYMBOL FOR START OF HEADING;So;0;ON;;;;;N;GRAPHIC FOR START OF HEADING;;;; +2402;SYMBOL FOR START OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR START OF TEXT;;;; +2403;SYMBOL FOR END OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR END OF TEXT;;;; +2404;SYMBOL FOR END OF TRANSMISSION;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION;;;; +2405;SYMBOL FOR ENQUIRY;So;0;ON;;;;;N;GRAPHIC FOR ENQUIRY;;;; +2406;SYMBOL FOR ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR ACKNOWLEDGE;;;; +2407;SYMBOL FOR BELL;So;0;ON;;;;;N;GRAPHIC FOR BELL;;;; +2408;SYMBOL FOR BACKSPACE;So;0;ON;;;;;N;GRAPHIC FOR BACKSPACE;;;; +2409;SYMBOL FOR HORIZONTAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR HORIZONTAL TABULATION;;;; +240A;SYMBOL FOR LINE FEED;So;0;ON;;;;;N;GRAPHIC FOR LINE FEED;;;; +240B;SYMBOL FOR VERTICAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR VERTICAL TABULATION;;;; +240C;SYMBOL FOR FORM FEED;So;0;ON;;;;;N;GRAPHIC FOR FORM FEED;;;; +240D;SYMBOL FOR CARRIAGE RETURN;So;0;ON;;;;;N;GRAPHIC FOR CARRIAGE RETURN;;;; +240E;SYMBOL FOR SHIFT OUT;So;0;ON;;;;;N;GRAPHIC FOR SHIFT OUT;;;; +240F;SYMBOL FOR SHIFT IN;So;0;ON;;;;;N;GRAPHIC FOR SHIFT IN;;;; +2410;SYMBOL FOR DATA LINK ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR DATA LINK ESCAPE;;;; +2411;SYMBOL FOR DEVICE CONTROL ONE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL ONE;;;; +2412;SYMBOL FOR DEVICE CONTROL TWO;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL TWO;;;; +2413;SYMBOL FOR DEVICE CONTROL THREE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL THREE;;;; +2414;SYMBOL FOR DEVICE CONTROL FOUR;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL FOUR;;;; +2415;SYMBOL FOR NEGATIVE ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR NEGATIVE ACKNOWLEDGE;;;; +2416;SYMBOL FOR SYNCHRONOUS IDLE;So;0;ON;;;;;N;GRAPHIC FOR SYNCHRONOUS IDLE;;;; +2417;SYMBOL FOR END OF TRANSMISSION BLOCK;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION BLOCK;;;; +2418;SYMBOL FOR CANCEL;So;0;ON;;;;;N;GRAPHIC FOR CANCEL;;;; +2419;SYMBOL FOR END OF MEDIUM;So;0;ON;;;;;N;GRAPHIC FOR END OF MEDIUM;;;; +241A;SYMBOL FOR SUBSTITUTE;So;0;ON;;;;;N;GRAPHIC FOR SUBSTITUTE;;;; +241B;SYMBOL FOR ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR ESCAPE;;;; +241C;SYMBOL FOR FILE SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR FILE SEPARATOR;;;; +241D;SYMBOL FOR GROUP SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR GROUP SEPARATOR;;;; +241E;SYMBOL FOR RECORD SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR RECORD SEPARATOR;;;; +241F;SYMBOL FOR UNIT SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR UNIT SEPARATOR;;;; +2420;SYMBOL FOR SPACE;So;0;ON;;;;;N;GRAPHIC FOR SPACE;;;; +2421;SYMBOL FOR DELETE;So;0;ON;;;;;N;GRAPHIC FOR DELETE;;;; +2422;BLANK SYMBOL;So;0;ON;;;;;N;BLANK;;;; +2423;OPEN BOX;So;0;ON;;;;;N;;;;; +2424;SYMBOL FOR NEWLINE;So;0;ON;;;;;N;GRAPHIC FOR NEWLINE;;;; +2425;SYMBOL FOR DELETE FORM TWO;So;0;ON;;;;;N;;;;; +2426;SYMBOL FOR SUBSTITUTE FORM TWO;So;0;ON;;;;;N;;;;; +2440;OCR HOOK;So;0;ON;;;;;N;;;;; +2441;OCR CHAIR;So;0;ON;;;;;N;;;;; +2442;OCR FORK;So;0;ON;;;;;N;;;;; +2443;OCR INVERTED FORK;So;0;ON;;;;;N;;;;; +2444;OCR BELT BUCKLE;So;0;ON;;;;;N;;;;; +2445;OCR BOW TIE;So;0;ON;;;;;N;;;;; +2446;OCR BRANCH BANK IDENTIFICATION;So;0;ON;;;;;N;;;;; +2447;OCR AMOUNT OF CHECK;So;0;ON;;;;;N;;;;; +2448;OCR DASH;So;0;ON;;;;;N;;;;; +2449;OCR CUSTOMER ACCOUNT NUMBER;So;0;ON;;;;;N;;;;; +244A;OCR DOUBLE BACKSLASH;So;0;ON;;;;;N;;;;; +2460;CIRCLED DIGIT ONE;No;0;ON; 0031;;1;1;N;;;;; +2461;CIRCLED DIGIT TWO;No;0;ON; 0032;;2;2;N;;;;; +2462;CIRCLED DIGIT THREE;No;0;ON; 0033;;3;3;N;;;;; +2463;CIRCLED DIGIT FOUR;No;0;ON; 0034;;4;4;N;;;;; +2464;CIRCLED DIGIT FIVE;No;0;ON; 0035;;5;5;N;;;;; +2465;CIRCLED DIGIT SIX;No;0;ON; 0036;;6;6;N;;;;; +2466;CIRCLED DIGIT SEVEN;No;0;ON; 0037;;7;7;N;;;;; +2467;CIRCLED DIGIT EIGHT;No;0;ON; 0038;;8;8;N;;;;; +2468;CIRCLED DIGIT NINE;No;0;ON; 0039;;9;9;N;;;;; +2469;CIRCLED NUMBER TEN;No;0;ON; 0031 0030;;;10;N;;;;; +246A;CIRCLED NUMBER ELEVEN;No;0;ON; 0031 0031;;;11;N;;;;; +246B;CIRCLED NUMBER TWELVE;No;0;ON; 0031 0032;;;12;N;;;;; +246C;CIRCLED NUMBER THIRTEEN;No;0;ON; 0031 0033;;;13;N;;;;; +246D;CIRCLED NUMBER FOURTEEN;No;0;ON; 0031 0034;;;14;N;;;;; +246E;CIRCLED NUMBER FIFTEEN;No;0;ON; 0031 0035;;;15;N;;;;; +246F;CIRCLED NUMBER SIXTEEN;No;0;ON; 0031 0036;;;16;N;;;;; +2470;CIRCLED NUMBER SEVENTEEN;No;0;ON; 0031 0037;;;17;N;;;;; +2471;CIRCLED NUMBER EIGHTEEN;No;0;ON; 0031 0038;;;18;N;;;;; +2472;CIRCLED NUMBER NINETEEN;No;0;ON; 0031 0039;;;19;N;;;;; +2473;CIRCLED NUMBER TWENTY;No;0;ON; 0032 0030;;;20;N;;;;; +2474;PARENTHESIZED DIGIT ONE;No;0;ON; 0028 0031 0029;;1;1;N;;;;; +2475;PARENTHESIZED DIGIT TWO;No;0;ON; 0028 0032 0029;;2;2;N;;;;; +2476;PARENTHESIZED DIGIT THREE;No;0;ON; 0028 0033 0029;;3;3;N;;;;; +2477;PARENTHESIZED DIGIT FOUR;No;0;ON; 0028 0034 0029;;4;4;N;;;;; +2478;PARENTHESIZED DIGIT FIVE;No;0;ON; 0028 0035 0029;;5;5;N;;;;; +2479;PARENTHESIZED DIGIT SIX;No;0;ON; 0028 0036 0029;;6;6;N;;;;; +247A;PARENTHESIZED DIGIT SEVEN;No;0;ON; 0028 0037 0029;;7;7;N;;;;; +247B;PARENTHESIZED DIGIT EIGHT;No;0;ON; 0028 0038 0029;;8;8;N;;;;; +247C;PARENTHESIZED DIGIT NINE;No;0;ON; 0028 0039 0029;;9;9;N;;;;; +247D;PARENTHESIZED NUMBER TEN;No;0;ON; 0028 0031 0030 0029;;;10;N;;;;; +247E;PARENTHESIZED NUMBER ELEVEN;No;0;ON; 0028 0031 0031 0029;;;11;N;;;;; +247F;PARENTHESIZED NUMBER TWELVE;No;0;ON; 0028 0031 0032 0029;;;12;N;;;;; +2480;PARENTHESIZED NUMBER THIRTEEN;No;0;ON; 0028 0031 0033 0029;;;13;N;;;;; +2481;PARENTHESIZED NUMBER FOURTEEN;No;0;ON; 0028 0031 0034 0029;;;14;N;;;;; +2482;PARENTHESIZED NUMBER FIFTEEN;No;0;ON; 0028 0031 0035 0029;;;15;N;;;;; +2483;PARENTHESIZED NUMBER SIXTEEN;No;0;ON; 0028 0031 0036 0029;;;16;N;;;;; +2484;PARENTHESIZED NUMBER SEVENTEEN;No;0;ON; 0028 0031 0037 0029;;;17;N;;;;; +2485;PARENTHESIZED NUMBER EIGHTEEN;No;0;ON; 0028 0031 0038 0029;;;18;N;;;;; +2486;PARENTHESIZED NUMBER NINETEEN;No;0;ON; 0028 0031 0039 0029;;;19;N;;;;; +2487;PARENTHESIZED NUMBER TWENTY;No;0;ON; 0028 0032 0030 0029;;;20;N;;;;; +2488;DIGIT ONE FULL STOP;No;0;EN; 0031 002E;;1;1;N;DIGIT ONE PERIOD;;;; +2489;DIGIT TWO FULL STOP;No;0;EN; 0032 002E;;2;2;N;DIGIT TWO PERIOD;;;; +248A;DIGIT THREE FULL STOP;No;0;EN; 0033 002E;;3;3;N;DIGIT THREE PERIOD;;;; +248B;DIGIT FOUR FULL STOP;No;0;EN; 0034 002E;;4;4;N;DIGIT FOUR PERIOD;;;; +248C;DIGIT FIVE FULL STOP;No;0;EN; 0035 002E;;5;5;N;DIGIT FIVE PERIOD;;;; +248D;DIGIT SIX FULL STOP;No;0;EN; 0036 002E;;6;6;N;DIGIT SIX PERIOD;;;; +248E;DIGIT SEVEN FULL STOP;No;0;EN; 0037 002E;;7;7;N;DIGIT SEVEN PERIOD;;;; +248F;DIGIT EIGHT FULL STOP;No;0;EN; 0038 002E;;8;8;N;DIGIT EIGHT PERIOD;;;; +2490;DIGIT NINE FULL STOP;No;0;EN; 0039 002E;;9;9;N;DIGIT NINE PERIOD;;;; +2491;NUMBER TEN FULL STOP;No;0;EN; 0031 0030 002E;;;10;N;NUMBER TEN PERIOD;;;; +2492;NUMBER ELEVEN FULL STOP;No;0;EN; 0031 0031 002E;;;11;N;NUMBER ELEVEN PERIOD;;;; +2493;NUMBER TWELVE FULL STOP;No;0;EN; 0031 0032 002E;;;12;N;NUMBER TWELVE PERIOD;;;; +2494;NUMBER THIRTEEN FULL STOP;No;0;EN; 0031 0033 002E;;;13;N;NUMBER THIRTEEN PERIOD;;;; +2495;NUMBER FOURTEEN FULL STOP;No;0;EN; 0031 0034 002E;;;14;N;NUMBER FOURTEEN PERIOD;;;; +2496;NUMBER FIFTEEN FULL STOP;No;0;EN; 0031 0035 002E;;;15;N;NUMBER FIFTEEN PERIOD;;;; +2497;NUMBER SIXTEEN FULL STOP;No;0;EN; 0031 0036 002E;;;16;N;NUMBER SIXTEEN PERIOD;;;; +2498;NUMBER SEVENTEEN FULL STOP;No;0;EN; 0031 0037 002E;;;17;N;NUMBER SEVENTEEN PERIOD;;;; +2499;NUMBER EIGHTEEN FULL STOP;No;0;EN; 0031 0038 002E;;;18;N;NUMBER EIGHTEEN PERIOD;;;; +249A;NUMBER NINETEEN FULL STOP;No;0;EN; 0031 0039 002E;;;19;N;NUMBER NINETEEN PERIOD;;;; +249B;NUMBER TWENTY FULL STOP;No;0;EN; 0032 0030 002E;;;20;N;NUMBER TWENTY PERIOD;;;; +249C;PARENTHESIZED LATIN SMALL LETTER A;So;0;L; 0028 0061 0029;;;;N;;;;; +249D;PARENTHESIZED LATIN SMALL LETTER B;So;0;L; 0028 0062 0029;;;;N;;;;; +249E;PARENTHESIZED LATIN SMALL LETTER C;So;0;L; 0028 0063 0029;;;;N;;;;; +249F;PARENTHESIZED LATIN SMALL LETTER D;So;0;L; 0028 0064 0029;;;;N;;;;; +24A0;PARENTHESIZED LATIN SMALL LETTER E;So;0;L; 0028 0065 0029;;;;N;;;;; +24A1;PARENTHESIZED LATIN SMALL LETTER F;So;0;L; 0028 0066 0029;;;;N;;;;; +24A2;PARENTHESIZED LATIN SMALL LETTER G;So;0;L; 0028 0067 0029;;;;N;;;;; +24A3;PARENTHESIZED LATIN SMALL LETTER H;So;0;L; 0028 0068 0029;;;;N;;;;; +24A4;PARENTHESIZED LATIN SMALL LETTER I;So;0;L; 0028 0069 0029;;;;N;;;;; +24A5;PARENTHESIZED LATIN SMALL LETTER J;So;0;L; 0028 006A 0029;;;;N;;;;; +24A6;PARENTHESIZED LATIN SMALL LETTER K;So;0;L; 0028 006B 0029;;;;N;;;;; +24A7;PARENTHESIZED LATIN SMALL LETTER L;So;0;L; 0028 006C 0029;;;;N;;;;; +24A8;PARENTHESIZED LATIN SMALL LETTER M;So;0;L; 0028 006D 0029;;;;N;;;;; +24A9;PARENTHESIZED LATIN SMALL LETTER N;So;0;L; 0028 006E 0029;;;;N;;;;; +24AA;PARENTHESIZED LATIN SMALL LETTER O;So;0;L; 0028 006F 0029;;;;N;;;;; +24AB;PARENTHESIZED LATIN SMALL LETTER P;So;0;L; 0028 0070 0029;;;;N;;;;; +24AC;PARENTHESIZED LATIN SMALL LETTER Q;So;0;L; 0028 0071 0029;;;;N;;;;; +24AD;PARENTHESIZED LATIN SMALL LETTER R;So;0;L; 0028 0072 0029;;;;N;;;;; +24AE;PARENTHESIZED LATIN SMALL LETTER S;So;0;L; 0028 0073 0029;;;;N;;;;; +24AF;PARENTHESIZED LATIN SMALL LETTER T;So;0;L; 0028 0074 0029;;;;N;;;;; +24B0;PARENTHESIZED LATIN SMALL LETTER U;So;0;L; 0028 0075 0029;;;;N;;;;; +24B1;PARENTHESIZED LATIN SMALL LETTER V;So;0;L; 0028 0076 0029;;;;N;;;;; +24B2;PARENTHESIZED LATIN SMALL LETTER W;So;0;L; 0028 0077 0029;;;;N;;;;; +24B3;PARENTHESIZED LATIN SMALL LETTER X;So;0;L; 0028 0078 0029;;;;N;;;;; +24B4;PARENTHESIZED LATIN SMALL LETTER Y;So;0;L; 0028 0079 0029;;;;N;;;;; +24B5;PARENTHESIZED LATIN SMALL LETTER Z;So;0;L; 0028 007A 0029;;;;N;;;;; +24B6;CIRCLED LATIN CAPITAL LETTER A;So;0;L; 0041;;;;N;;;;24D0; +24B7;CIRCLED LATIN CAPITAL LETTER B;So;0;L; 0042;;;;N;;;;24D1; +24B8;CIRCLED LATIN CAPITAL LETTER C;So;0;L; 0043;;;;N;;;;24D2; +24B9;CIRCLED LATIN CAPITAL LETTER D;So;0;L; 0044;;;;N;;;;24D3; +24BA;CIRCLED LATIN CAPITAL LETTER E;So;0;L; 0045;;;;N;;;;24D4; +24BB;CIRCLED LATIN CAPITAL LETTER F;So;0;L; 0046;;;;N;;;;24D5; +24BC;CIRCLED LATIN CAPITAL LETTER G;So;0;L; 0047;;;;N;;;;24D6; +24BD;CIRCLED LATIN CAPITAL LETTER H;So;0;L; 0048;;;;N;;;;24D7; +24BE;CIRCLED LATIN CAPITAL LETTER I;So;0;L; 0049;;;;N;;;;24D8; +24BF;CIRCLED LATIN CAPITAL LETTER J;So;0;L; 004A;;;;N;;;;24D9; +24C0;CIRCLED LATIN CAPITAL LETTER K;So;0;L; 004B;;;;N;;;;24DA; +24C1;CIRCLED LATIN CAPITAL LETTER L;So;0;L; 004C;;;;N;;;;24DB; +24C2;CIRCLED LATIN CAPITAL LETTER M;So;0;L; 004D;;;;N;;;;24DC; +24C3;CIRCLED LATIN CAPITAL LETTER N;So;0;L; 004E;;;;N;;;;24DD; +24C4;CIRCLED LATIN CAPITAL LETTER O;So;0;L; 004F;;;;N;;;;24DE; +24C5;CIRCLED LATIN CAPITAL LETTER P;So;0;L; 0050;;;;N;;;;24DF; +24C6;CIRCLED LATIN CAPITAL LETTER Q;So;0;L; 0051;;;;N;;;;24E0; +24C7;CIRCLED LATIN CAPITAL LETTER R;So;0;L; 0052;;;;N;;;;24E1; +24C8;CIRCLED LATIN CAPITAL LETTER S;So;0;L; 0053;;;;N;;;;24E2; +24C9;CIRCLED LATIN CAPITAL LETTER T;So;0;L; 0054;;;;N;;;;24E3; +24CA;CIRCLED LATIN CAPITAL LETTER U;So;0;L; 0055;;;;N;;;;24E4; +24CB;CIRCLED LATIN CAPITAL LETTER V;So;0;L; 0056;;;;N;;;;24E5; +24CC;CIRCLED LATIN CAPITAL LETTER W;So;0;L; 0057;;;;N;;;;24E6; +24CD;CIRCLED LATIN CAPITAL LETTER X;So;0;L; 0058;;;;N;;;;24E7; +24CE;CIRCLED LATIN CAPITAL LETTER Y;So;0;L; 0059;;;;N;;;;24E8; +24CF;CIRCLED LATIN CAPITAL LETTER Z;So;0;L; 005A;;;;N;;;;24E9; +24D0;CIRCLED LATIN SMALL LETTER A;So;0;L; 0061;;;;N;;;24B6;;24B6 +24D1;CIRCLED LATIN SMALL LETTER B;So;0;L; 0062;;;;N;;;24B7;;24B7 +24D2;CIRCLED LATIN SMALL LETTER C;So;0;L; 0063;;;;N;;;24B8;;24B8 +24D3;CIRCLED LATIN SMALL LETTER D;So;0;L; 0064;;;;N;;;24B9;;24B9 +24D4;CIRCLED LATIN SMALL LETTER E;So;0;L; 0065;;;;N;;;24BA;;24BA +24D5;CIRCLED LATIN SMALL LETTER F;So;0;L; 0066;;;;N;;;24BB;;24BB +24D6;CIRCLED LATIN SMALL LETTER G;So;0;L; 0067;;;;N;;;24BC;;24BC +24D7;CIRCLED LATIN SMALL LETTER H;So;0;L; 0068;;;;N;;;24BD;;24BD +24D8;CIRCLED LATIN SMALL LETTER I;So;0;L; 0069;;;;N;;;24BE;;24BE +24D9;CIRCLED LATIN SMALL LETTER J;So;0;L; 006A;;;;N;;;24BF;;24BF +24DA;CIRCLED LATIN SMALL LETTER K;So;0;L; 006B;;;;N;;;24C0;;24C0 +24DB;CIRCLED LATIN SMALL LETTER L;So;0;L; 006C;;;;N;;;24C1;;24C1 +24DC;CIRCLED LATIN SMALL LETTER M;So;0;L; 006D;;;;N;;;24C2;;24C2 +24DD;CIRCLED LATIN SMALL LETTER N;So;0;L; 006E;;;;N;;;24C3;;24C3 +24DE;CIRCLED LATIN SMALL LETTER O;So;0;L; 006F;;;;N;;;24C4;;24C4 +24DF;CIRCLED LATIN SMALL LETTER P;So;0;L; 0070;;;;N;;;24C5;;24C5 +24E0;CIRCLED LATIN SMALL LETTER Q;So;0;L; 0071;;;;N;;;24C6;;24C6 +24E1;CIRCLED LATIN SMALL LETTER R;So;0;L; 0072;;;;N;;;24C7;;24C7 +24E2;CIRCLED LATIN SMALL LETTER S;So;0;L; 0073;;;;N;;;24C8;;24C8 +24E3;CIRCLED LATIN SMALL LETTER T;So;0;L; 0074;;;;N;;;24C9;;24C9 +24E4;CIRCLED LATIN SMALL LETTER U;So;0;L; 0075;;;;N;;;24CA;;24CA +24E5;CIRCLED LATIN SMALL LETTER V;So;0;L; 0076;;;;N;;;24CB;;24CB +24E6;CIRCLED LATIN SMALL LETTER W;So;0;L; 0077;;;;N;;;24CC;;24CC +24E7;CIRCLED LATIN SMALL LETTER X;So;0;L; 0078;;;;N;;;24CD;;24CD +24E8;CIRCLED LATIN SMALL LETTER Y;So;0;L; 0079;;;;N;;;24CE;;24CE +24E9;CIRCLED LATIN SMALL LETTER Z;So;0;L; 007A;;;;N;;;24CF;;24CF +24EA;CIRCLED DIGIT ZERO;No;0;ON; 0030;;0;0;N;;;;; +24EB;NEGATIVE CIRCLED NUMBER ELEVEN;No;0;ON;;;;11;N;;;;; +24EC;NEGATIVE CIRCLED NUMBER TWELVE;No;0;ON;;;;12;N;;;;; +24ED;NEGATIVE CIRCLED NUMBER THIRTEEN;No;0;ON;;;;13;N;;;;; +24EE;NEGATIVE CIRCLED NUMBER FOURTEEN;No;0;ON;;;;14;N;;;;; +24EF;NEGATIVE CIRCLED NUMBER FIFTEEN;No;0;ON;;;;15;N;;;;; +24F0;NEGATIVE CIRCLED NUMBER SIXTEEN;No;0;ON;;;;16;N;;;;; +24F1;NEGATIVE CIRCLED NUMBER SEVENTEEN;No;0;ON;;;;17;N;;;;; +24F2;NEGATIVE CIRCLED NUMBER EIGHTEEN;No;0;ON;;;;18;N;;;;; +24F3;NEGATIVE CIRCLED NUMBER NINETEEN;No;0;ON;;;;19;N;;;;; +24F4;NEGATIVE CIRCLED NUMBER TWENTY;No;0;ON;;;;20;N;;;;; +24F5;DOUBLE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;;;;; +24F6;DOUBLE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;;;;; +24F7;DOUBLE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;;;;; +24F8;DOUBLE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;;;;; +24F9;DOUBLE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;;;;; +24FA;DOUBLE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;;;;; +24FB;DOUBLE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;;;;; +24FC;DOUBLE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;;;;; +24FD;DOUBLE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;;;;; +24FE;DOUBLE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;;;;; +24FF;NEGATIVE CIRCLED DIGIT ZERO;No;0;ON;;;0;0;N;;;;; +2500;BOX DRAWINGS LIGHT HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT HORIZONTAL;;;; +2501;BOX DRAWINGS HEAVY HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY HORIZONTAL;;;; +2502;BOX DRAWINGS LIGHT VERTICAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL;;;; +2503;BOX DRAWINGS HEAVY VERTICAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL;;;; +2504;BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH HORIZONTAL;;;; +2505;BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH HORIZONTAL;;;; +2506;BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH VERTICAL;;;; +2507;BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH VERTICAL;;;; +2508;BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH HORIZONTAL;;;; +2509;BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH HORIZONTAL;;;; +250A;BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH VERTICAL;;;; +250B;BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH VERTICAL;;;; +250C;BOX DRAWINGS LIGHT DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND RIGHT;;;; +250D;BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT HEAVY;;;; +250E;BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT LIGHT;;;; +250F;BOX DRAWINGS HEAVY DOWN AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND RIGHT;;;; +2510;BOX DRAWINGS LIGHT DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND LEFT;;;; +2511;BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT HEAVY;;;; +2512;BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT LIGHT;;;; +2513;BOX DRAWINGS HEAVY DOWN AND LEFT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND LEFT;;;; +2514;BOX DRAWINGS LIGHT UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT UP AND RIGHT;;;; +2515;BOX DRAWINGS UP LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT HEAVY;;;; +2516;BOX DRAWINGS UP HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT LIGHT;;;; +2517;BOX DRAWINGS HEAVY UP AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY UP AND RIGHT;;;; +2518;BOX DRAWINGS LIGHT UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT UP AND LEFT;;;; +2519;BOX DRAWINGS UP LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT HEAVY;;;; +251A;BOX DRAWINGS UP HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT LIGHT;;;; +251B;BOX DRAWINGS HEAVY UP AND LEFT;So;0;ON;;;;;N;FORMS HEAVY UP AND LEFT;;;; +251C;BOX DRAWINGS LIGHT VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND RIGHT;;;; +251D;BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND RIGHT HEAVY;;;; +251E;BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT DOWN LIGHT;;;; +251F;BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT UP LIGHT;;;; +2520;BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND RIGHT LIGHT;;;; +2521;BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT UP HEAVY;;;; +2522;BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT DOWN HEAVY;;;; +2523;BOX DRAWINGS HEAVY VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND RIGHT;;;; +2524;BOX DRAWINGS LIGHT VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND LEFT;;;; +2525;BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND LEFT HEAVY;;;; +2526;BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT DOWN LIGHT;;;; +2527;BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT UP LIGHT;;;; +2528;BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND LEFT LIGHT;;;; +2529;BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT UP HEAVY;;;; +252A;BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT DOWN HEAVY;;;; +252B;BOX DRAWINGS HEAVY VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND LEFT;;;; +252C;BOX DRAWINGS LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOWN AND HORIZONTAL;;;; +252D;BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT DOWN LIGHT;;;; +252E;BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT DOWN LIGHT;;;; +252F;BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND HORIZONTAL HEAVY;;;; +2530;BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND HORIZONTAL LIGHT;;;; +2531;BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT DOWN HEAVY;;;; +2532;BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT DOWN HEAVY;;;; +2533;BOX DRAWINGS HEAVY DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOWN AND HORIZONTAL;;;; +2534;BOX DRAWINGS LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT UP AND HORIZONTAL;;;; +2535;BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT UP LIGHT;;;; +2536;BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT UP LIGHT;;;; +2537;BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND HORIZONTAL HEAVY;;;; +2538;BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND HORIZONTAL LIGHT;;;; +2539;BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT UP HEAVY;;;; +253A;BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT UP HEAVY;;;; +253B;BOX DRAWINGS HEAVY UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY UP AND HORIZONTAL;;;; +253C;BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND HORIZONTAL;;;; +253D;BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT VERTICAL LIGHT;;;; +253E;BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT VERTICAL LIGHT;;;; +253F;BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND HORIZONTAL HEAVY;;;; +2540;BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND DOWN HORIZONTAL LIGHT;;;; +2541;BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND UP HORIZONTAL LIGHT;;;; +2542;BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND HORIZONTAL LIGHT;;;; +2543;BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT UP HEAVY AND RIGHT DOWN LIGHT;;;; +2544;BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT UP HEAVY AND LEFT DOWN LIGHT;;;; +2545;BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT DOWN HEAVY AND RIGHT UP LIGHT;;;; +2546;BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT DOWN HEAVY AND LEFT UP LIGHT;;;; +2547;BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND UP HORIZONTAL HEAVY;;;; +2548;BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND DOWN HORIZONTAL HEAVY;;;; +2549;BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT VERTICAL HEAVY;;;; +254A;BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT VERTICAL HEAVY;;;; +254B;BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND HORIZONTAL;;;; +254C;BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH HORIZONTAL;;;; +254D;BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH HORIZONTAL;;;; +254E;BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH VERTICAL;;;; +254F;BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH VERTICAL;;;; +2550;BOX DRAWINGS DOUBLE HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE HORIZONTAL;;;; +2551;BOX DRAWINGS DOUBLE VERTICAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL;;;; +2552;BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND RIGHT DOUBLE;;;; +2553;BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND RIGHT SINGLE;;;; +2554;BOX DRAWINGS DOUBLE DOWN AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND RIGHT;;;; +2555;BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND LEFT DOUBLE;;;; +2556;BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND LEFT SINGLE;;;; +2557;BOX DRAWINGS DOUBLE DOWN AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND LEFT;;;; +2558;BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND RIGHT DOUBLE;;;; +2559;BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND RIGHT SINGLE;;;; +255A;BOX DRAWINGS DOUBLE UP AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE UP AND RIGHT;;;; +255B;BOX DRAWINGS UP SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND LEFT DOUBLE;;;; +255C;BOX DRAWINGS UP DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND LEFT SINGLE;;;; +255D;BOX DRAWINGS DOUBLE UP AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE UP AND LEFT;;;; +255E;BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND RIGHT DOUBLE;;;; +255F;BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND RIGHT SINGLE;;;; +2560;BOX DRAWINGS DOUBLE VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND RIGHT;;;; +2561;BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND LEFT DOUBLE;;;; +2562;BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND LEFT SINGLE;;;; +2563;BOX DRAWINGS DOUBLE VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND LEFT;;;; +2564;BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND HORIZONTAL DOUBLE;;;; +2565;BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND HORIZONTAL SINGLE;;;; +2566;BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND HORIZONTAL;;;; +2567;BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND HORIZONTAL DOUBLE;;;; +2568;BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND HORIZONTAL SINGLE;;;; +2569;BOX DRAWINGS DOUBLE UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE UP AND HORIZONTAL;;;; +256A;BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND HORIZONTAL DOUBLE;;;; +256B;BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND HORIZONTAL SINGLE;;;; +256C;BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND HORIZONTAL;;;; +256D;BOX DRAWINGS LIGHT ARC DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND RIGHT;;;; +256E;BOX DRAWINGS LIGHT ARC DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND LEFT;;;; +256F;BOX DRAWINGS LIGHT ARC UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND LEFT;;;; +2570;BOX DRAWINGS LIGHT ARC UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND RIGHT;;;; +2571;BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;;;; +2572;BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;;;; +2573;BOX DRAWINGS LIGHT DIAGONAL CROSS;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL CROSS;;;; +2574;BOX DRAWINGS LIGHT LEFT;So;0;ON;;;;;N;FORMS LIGHT LEFT;;;; +2575;BOX DRAWINGS LIGHT UP;So;0;ON;;;;;N;FORMS LIGHT UP;;;; +2576;BOX DRAWINGS LIGHT RIGHT;So;0;ON;;;;;N;FORMS LIGHT RIGHT;;;; +2577;BOX DRAWINGS LIGHT DOWN;So;0;ON;;;;;N;FORMS LIGHT DOWN;;;; +2578;BOX DRAWINGS HEAVY LEFT;So;0;ON;;;;;N;FORMS HEAVY LEFT;;;; +2579;BOX DRAWINGS HEAVY UP;So;0;ON;;;;;N;FORMS HEAVY UP;;;; +257A;BOX DRAWINGS HEAVY RIGHT;So;0;ON;;;;;N;FORMS HEAVY RIGHT;;;; +257B;BOX DRAWINGS HEAVY DOWN;So;0;ON;;;;;N;FORMS HEAVY DOWN;;;; +257C;BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT;So;0;ON;;;;;N;FORMS LIGHT LEFT AND HEAVY RIGHT;;;; +257D;BOX DRAWINGS LIGHT UP AND HEAVY DOWN;So;0;ON;;;;;N;FORMS LIGHT UP AND HEAVY DOWN;;;; +257E;BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT;So;0;ON;;;;;N;FORMS HEAVY LEFT AND LIGHT RIGHT;;;; +257F;BOX DRAWINGS HEAVY UP AND LIGHT DOWN;So;0;ON;;;;;N;FORMS HEAVY UP AND LIGHT DOWN;;;; +2580;UPPER HALF BLOCK;So;0;ON;;;;;N;;;;; +2581;LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +2582;LOWER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +2583;LOWER THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +2584;LOWER HALF BLOCK;So;0;ON;;;;;N;;;;; +2585;LOWER FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +2586;LOWER THREE QUARTERS BLOCK;So;0;ON;;;;;N;LOWER THREE QUARTER BLOCK;;;; +2587;LOWER SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +2588;FULL BLOCK;So;0;ON;;;;;N;;;;; +2589;LEFT SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +258A;LEFT THREE QUARTERS BLOCK;So;0;ON;;;;;N;LEFT THREE QUARTER BLOCK;;;; +258B;LEFT FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +258C;LEFT HALF BLOCK;So;0;ON;;;;;N;;;;; +258D;LEFT THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +258E;LEFT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +258F;LEFT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +2590;RIGHT HALF BLOCK;So;0;ON;;;;;N;;;;; +2591;LIGHT SHADE;So;0;ON;;;;;N;;;;; +2592;MEDIUM SHADE;So;0;ON;;;;;N;;;;; +2593;DARK SHADE;So;0;ON;;;;;N;;;;; +2594;UPPER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +2595;RIGHT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +2596;QUADRANT LOWER LEFT;So;0;ON;;;;;N;;;;; +2597;QUADRANT LOWER RIGHT;So;0;ON;;;;;N;;;;; +2598;QUADRANT UPPER LEFT;So;0;ON;;;;;N;;;;; +2599;QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +259A;QUADRANT UPPER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +259B;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;; +259C;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +259D;QUADRANT UPPER RIGHT;So;0;ON;;;;;N;;;;; +259E;QUADRANT UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;; +259F;QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +25A0;BLACK SQUARE;So;0;ON;;;;;N;;;;; +25A1;WHITE SQUARE;So;0;ON;;;;;N;;;;; +25A2;WHITE SQUARE WITH ROUNDED CORNERS;So;0;ON;;;;;N;;;;; +25A3;WHITE SQUARE CONTAINING BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;; +25A4;SQUARE WITH HORIZONTAL FILL;So;0;ON;;;;;N;;;;; +25A5;SQUARE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;; +25A6;SQUARE WITH ORTHOGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;; +25A7;SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL;So;0;ON;;;;;N;;;;; +25A8;SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL;So;0;ON;;;;;N;;;;; +25A9;SQUARE WITH DIAGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;; +25AA;BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;; +25AB;WHITE SMALL SQUARE;So;0;ON;;;;;N;;;;; +25AC;BLACK RECTANGLE;So;0;ON;;;;;N;;;;; +25AD;WHITE RECTANGLE;So;0;ON;;;;;N;;;;; +25AE;BLACK VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;; +25AF;WHITE VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;; +25B0;BLACK PARALLELOGRAM;So;0;ON;;;;;N;;;;; +25B1;WHITE PARALLELOGRAM;So;0;ON;;;;;N;;;;; +25B2;BLACK UP-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING TRIANGLE;;;; +25B3;WHITE UP-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE;;;; +25B4;BLACK UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING SMALL TRIANGLE;;;; +25B5;WHITE UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING SMALL TRIANGLE;;;; +25B6;BLACK RIGHT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING TRIANGLE;;;; +25B7;WHITE RIGHT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE RIGHT POINTING TRIANGLE;;;; +25B8;BLACK RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING SMALL TRIANGLE;;;; +25B9;WHITE RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE RIGHT POINTING SMALL TRIANGLE;;;; +25BA;BLACK RIGHT-POINTING POINTER;So;0;ON;;;;;N;BLACK RIGHT POINTING POINTER;;;; +25BB;WHITE RIGHT-POINTING POINTER;So;0;ON;;;;;N;WHITE RIGHT POINTING POINTER;;;; +25BC;BLACK DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING TRIANGLE;;;; +25BD;WHITE DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING TRIANGLE;;;; +25BE;BLACK DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING SMALL TRIANGLE;;;; +25BF;WHITE DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING SMALL TRIANGLE;;;; +25C0;BLACK LEFT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING TRIANGLE;;;; +25C1;WHITE LEFT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE LEFT POINTING TRIANGLE;;;; +25C2;BLACK LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING SMALL TRIANGLE;;;; +25C3;WHITE LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE LEFT POINTING SMALL TRIANGLE;;;; +25C4;BLACK LEFT-POINTING POINTER;So;0;ON;;;;;N;BLACK LEFT POINTING POINTER;;;; +25C5;WHITE LEFT-POINTING POINTER;So;0;ON;;;;;N;WHITE LEFT POINTING POINTER;;;; +25C6;BLACK DIAMOND;So;0;ON;;;;;N;;;;; +25C7;WHITE DIAMOND;So;0;ON;;;;;N;;;;; +25C8;WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND;So;0;ON;;;;;N;;;;; +25C9;FISHEYE;So;0;ON;;;;;N;;;;; +25CA;LOZENGE;So;0;ON;;;;;N;;;;; +25CB;WHITE CIRCLE;So;0;ON;;;;;N;;;;; +25CC;DOTTED CIRCLE;So;0;ON;;;;;N;;;;; +25CD;CIRCLE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;; +25CE;BULLSEYE;So;0;ON;;;;;N;;;;; +25CF;BLACK CIRCLE;So;0;ON;;;;;N;;;;; +25D0;CIRCLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;; +25D1;CIRCLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;; +25D2;CIRCLE WITH LOWER HALF BLACK;So;0;ON;;;;;N;;;;; +25D3;CIRCLE WITH UPPER HALF BLACK;So;0;ON;;;;;N;;;;; +25D4;CIRCLE WITH UPPER RIGHT QUADRANT BLACK;So;0;ON;;;;;N;;;;; +25D5;CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK;So;0;ON;;;;;N;;;;; +25D6;LEFT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; +25D7;RIGHT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; +25D8;INVERSE BULLET;So;0;ON;;;;;N;;;;; +25D9;INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;; +25DA;UPPER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;; +25DB;LOWER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;; +25DC;UPPER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; +25DD;UPPER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; +25DE;LOWER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; +25DF;LOWER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; +25E0;UPPER HALF CIRCLE;So;0;ON;;;;;N;;;;; +25E1;LOWER HALF CIRCLE;So;0;ON;;;;;N;;;;; +25E2;BLACK LOWER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;; +25E3;BLACK LOWER LEFT TRIANGLE;So;0;ON;;;;;N;;;;; +25E4;BLACK UPPER LEFT TRIANGLE;So;0;ON;;;;;N;;;;; +25E5;BLACK UPPER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;; +25E6;WHITE BULLET;So;0;ON;;;;;N;;;;; +25E7;SQUARE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;; +25E8;SQUARE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;; +25E9;SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;; +25EA;SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;; +25EB;WHITE SQUARE WITH VERTICAL BISECTING LINE;So;0;ON;;;;;N;;;;; +25EC;WHITE UP-POINTING TRIANGLE WITH DOT;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE WITH DOT;;;; +25ED;UP-POINTING TRIANGLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH LEFT HALF BLACK;;;; +25EE;UP-POINTING TRIANGLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH RIGHT HALF BLACK;;;; +25EF;LARGE CIRCLE;So;0;ON;;;;;N;;;;; +25F0;WHITE SQUARE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;; +25F1;WHITE SQUARE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;; +25F2;WHITE SQUARE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; +25F3;WHITE SQUARE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; +25F4;WHITE CIRCLE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;; +25F5;WHITE CIRCLE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;; +25F6;WHITE CIRCLE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; +25F7;WHITE CIRCLE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; +25F8;UPPER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;; +25F9;UPPER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;; +25FA;LOWER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;; +25FB;WHITE MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;; +25FC;BLACK MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;; +25FD;WHITE MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;; +25FE;BLACK MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;; +25FF;LOWER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;; +2600;BLACK SUN WITH RAYS;So;0;ON;;;;;N;;;;; +2601;CLOUD;So;0;ON;;;;;N;;;;; +2602;UMBRELLA;So;0;ON;;;;;N;;;;; +2603;SNOWMAN;So;0;ON;;;;;N;;;;; +2604;COMET;So;0;ON;;;;;N;;;;; +2605;BLACK STAR;So;0;ON;;;;;N;;;;; +2606;WHITE STAR;So;0;ON;;;;;N;;;;; +2607;LIGHTNING;So;0;ON;;;;;N;;;;; +2608;THUNDERSTORM;So;0;ON;;;;;N;;;;; +2609;SUN;So;0;ON;;;;;N;;;;; +260A;ASCENDING NODE;So;0;ON;;;;;N;;;;; +260B;DESCENDING NODE;So;0;ON;;;;;N;;;;; +260C;CONJUNCTION;So;0;ON;;;;;N;;;;; +260D;OPPOSITION;So;0;ON;;;;;N;;;;; +260E;BLACK TELEPHONE;So;0;ON;;;;;N;;;;; +260F;WHITE TELEPHONE;So;0;ON;;;;;N;;;;; +2610;BALLOT BOX;So;0;ON;;;;;N;;;;; +2611;BALLOT BOX WITH CHECK;So;0;ON;;;;;N;;;;; +2612;BALLOT BOX WITH X;So;0;ON;;;;;N;;;;; +2613;SALTIRE;So;0;ON;;;;;N;;;;; +2614;UMBRELLA WITH RAIN DROPS;So;0;ON;;;;;N;;;;; +2615;HOT BEVERAGE;So;0;ON;;;;;N;;;;; +2616;WHITE SHOGI PIECE;So;0;ON;;;;;N;;;;; +2617;BLACK SHOGI PIECE;So;0;ON;;;;;N;;;;; +2618;SHAMROCK;So;0;ON;;;;;N;;;;; +2619;REVERSED ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;; +261A;BLACK LEFT POINTING INDEX;So;0;ON;;;;;N;;;;; +261B;BLACK RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;; +261C;WHITE LEFT POINTING INDEX;So;0;ON;;;;;N;;;;; +261D;WHITE UP POINTING INDEX;So;0;ON;;;;;N;;;;; +261E;WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;; +261F;WHITE DOWN POINTING INDEX;So;0;ON;;;;;N;;;;; +2620;SKULL AND CROSSBONES;So;0;ON;;;;;N;;;;; +2621;CAUTION SIGN;So;0;ON;;;;;N;;;;; +2622;RADIOACTIVE SIGN;So;0;ON;;;;;N;;;;; +2623;BIOHAZARD SIGN;So;0;ON;;;;;N;;;;; +2624;CADUCEUS;So;0;ON;;;;;N;;;;; +2625;ANKH;So;0;ON;;;;;N;;;;; +2626;ORTHODOX CROSS;So;0;ON;;;;;N;;;;; +2627;CHI RHO;So;0;ON;;;;;N;;;;; +2628;CROSS OF LORRAINE;So;0;ON;;;;;N;;;;; +2629;CROSS OF JERUSALEM;So;0;ON;;;;;N;;;;; +262A;STAR AND CRESCENT;So;0;ON;;;;;N;;;;; +262B;FARSI SYMBOL;So;0;ON;;;;;N;SYMBOL OF IRAN;;;; +262C;ADI SHAKTI;So;0;ON;;;;;N;;;;; +262D;HAMMER AND SICKLE;So;0;ON;;;;;N;;;;; +262E;PEACE SYMBOL;So;0;ON;;;;;N;;;;; +262F;YIN YANG;So;0;ON;;;;;N;;;;; +2630;TRIGRAM FOR HEAVEN;So;0;ON;;;;;N;;;;; +2631;TRIGRAM FOR LAKE;So;0;ON;;;;;N;;;;; +2632;TRIGRAM FOR FIRE;So;0;ON;;;;;N;;;;; +2633;TRIGRAM FOR THUNDER;So;0;ON;;;;;N;;;;; +2634;TRIGRAM FOR WIND;So;0;ON;;;;;N;;;;; +2635;TRIGRAM FOR WATER;So;0;ON;;;;;N;;;;; +2636;TRIGRAM FOR MOUNTAIN;So;0;ON;;;;;N;;;;; +2637;TRIGRAM FOR EARTH;So;0;ON;;;;;N;;;;; +2638;WHEEL OF DHARMA;So;0;ON;;;;;N;;;;; +2639;WHITE FROWNING FACE;So;0;ON;;;;;N;;;;; +263A;WHITE SMILING FACE;So;0;ON;;;;;N;;;;; +263B;BLACK SMILING FACE;So;0;ON;;;;;N;;;;; +263C;WHITE SUN WITH RAYS;So;0;ON;;;;;N;;;;; +263D;FIRST QUARTER MOON;So;0;ON;;;;;N;;;;; +263E;LAST QUARTER MOON;So;0;ON;;;;;N;;;;; +263F;MERCURY;So;0;ON;;;;;N;;;;; +2640;FEMALE SIGN;So;0;ON;;;;;N;;;;; +2641;EARTH;So;0;ON;;;;;N;;;;; +2642;MALE SIGN;So;0;ON;;;;;N;;;;; +2643;JUPITER;So;0;ON;;;;;N;;;;; +2644;SATURN;So;0;ON;;;;;N;;;;; +2645;URANUS;So;0;ON;;;;;N;;;;; +2646;NEPTUNE;So;0;ON;;;;;N;;;;; +2647;PLUTO;So;0;ON;;;;;N;;;;; +2648;ARIES;So;0;ON;;;;;N;;;;; +2649;TAURUS;So;0;ON;;;;;N;;;;; +264A;GEMINI;So;0;ON;;;;;N;;;;; +264B;CANCER;So;0;ON;;;;;N;;;;; +264C;LEO;So;0;ON;;;;;N;;;;; +264D;VIRGO;So;0;ON;;;;;N;;;;; +264E;LIBRA;So;0;ON;;;;;N;;;;; +264F;SCORPIUS;So;0;ON;;;;;N;;;;; +2650;SAGITTARIUS;So;0;ON;;;;;N;;;;; +2651;CAPRICORN;So;0;ON;;;;;N;;;;; +2652;AQUARIUS;So;0;ON;;;;;N;;;;; +2653;PISCES;So;0;ON;;;;;N;;;;; +2654;WHITE CHESS KING;So;0;ON;;;;;N;;;;; +2655;WHITE CHESS QUEEN;So;0;ON;;;;;N;;;;; +2656;WHITE CHESS ROOK;So;0;ON;;;;;N;;;;; +2657;WHITE CHESS BISHOP;So;0;ON;;;;;N;;;;; +2658;WHITE CHESS KNIGHT;So;0;ON;;;;;N;;;;; +2659;WHITE CHESS PAWN;So;0;ON;;;;;N;;;;; +265A;BLACK CHESS KING;So;0;ON;;;;;N;;;;; +265B;BLACK CHESS QUEEN;So;0;ON;;;;;N;;;;; +265C;BLACK CHESS ROOK;So;0;ON;;;;;N;;;;; +265D;BLACK CHESS BISHOP;So;0;ON;;;;;N;;;;; +265E;BLACK CHESS KNIGHT;So;0;ON;;;;;N;;;;; +265F;BLACK CHESS PAWN;So;0;ON;;;;;N;;;;; +2660;BLACK SPADE SUIT;So;0;ON;;;;;N;;;;; +2661;WHITE HEART SUIT;So;0;ON;;;;;N;;;;; +2662;WHITE DIAMOND SUIT;So;0;ON;;;;;N;;;;; +2663;BLACK CLUB SUIT;So;0;ON;;;;;N;;;;; +2664;WHITE SPADE SUIT;So;0;ON;;;;;N;;;;; +2665;BLACK HEART SUIT;So;0;ON;;;;;N;;;;; +2666;BLACK DIAMOND SUIT;So;0;ON;;;;;N;;;;; +2667;WHITE CLUB SUIT;So;0;ON;;;;;N;;;;; +2668;HOT SPRINGS;So;0;ON;;;;;N;;;;; +2669;QUARTER NOTE;So;0;ON;;;;;N;;;;; +266A;EIGHTH NOTE;So;0;ON;;;;;N;;;;; +266B;BEAMED EIGHTH NOTES;So;0;ON;;;;;N;BARRED EIGHTH NOTES;;;; +266C;BEAMED SIXTEENTH NOTES;So;0;ON;;;;;N;BARRED SIXTEENTH NOTES;;;; +266D;MUSIC FLAT SIGN;So;0;ON;;;;;N;FLAT;;;; +266E;MUSIC NATURAL SIGN;So;0;ON;;;;;N;NATURAL;;;; +266F;MUSIC SHARP SIGN;Sm;0;ON;;;;;N;SHARP;;;; +2670;WEST SYRIAC CROSS;So;0;ON;;;;;N;;;;; +2671;EAST SYRIAC CROSS;So;0;ON;;;;;N;;;;; +2672;UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;; +2673;RECYCLING SYMBOL FOR TYPE-1 PLASTICS;So;0;ON;;;;;N;;;;; +2674;RECYCLING SYMBOL FOR TYPE-2 PLASTICS;So;0;ON;;;;;N;;;;; +2675;RECYCLING SYMBOL FOR TYPE-3 PLASTICS;So;0;ON;;;;;N;;;;; +2676;RECYCLING SYMBOL FOR TYPE-4 PLASTICS;So;0;ON;;;;;N;;;;; +2677;RECYCLING SYMBOL FOR TYPE-5 PLASTICS;So;0;ON;;;;;N;;;;; +2678;RECYCLING SYMBOL FOR TYPE-6 PLASTICS;So;0;ON;;;;;N;;;;; +2679;RECYCLING SYMBOL FOR TYPE-7 PLASTICS;So;0;ON;;;;;N;;;;; +267A;RECYCLING SYMBOL FOR GENERIC MATERIALS;So;0;ON;;;;;N;;;;; +267B;BLACK UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;; +267C;RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;; +267D;PARTIALLY-RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;; +267E;PERMANENT PAPER SIGN;So;0;ON;;;;;N;;;;; +267F;WHEELCHAIR SYMBOL;So;0;ON;;;;;N;;;;; +2680;DIE FACE-1;So;0;ON;;;;;N;;;;; +2681;DIE FACE-2;So;0;ON;;;;;N;;;;; +2682;DIE FACE-3;So;0;ON;;;;;N;;;;; +2683;DIE FACE-4;So;0;ON;;;;;N;;;;; +2684;DIE FACE-5;So;0;ON;;;;;N;;;;; +2685;DIE FACE-6;So;0;ON;;;;;N;;;;; +2686;WHITE CIRCLE WITH DOT RIGHT;So;0;ON;;;;;N;;;;; +2687;WHITE CIRCLE WITH TWO DOTS;So;0;ON;;;;;N;;;;; +2688;BLACK CIRCLE WITH WHITE DOT RIGHT;So;0;ON;;;;;N;;;;; +2689;BLACK CIRCLE WITH TWO WHITE DOTS;So;0;ON;;;;;N;;;;; +268A;MONOGRAM FOR YANG;So;0;ON;;;;;N;;;;; +268B;MONOGRAM FOR YIN;So;0;ON;;;;;N;;;;; +268C;DIGRAM FOR GREATER YANG;So;0;ON;;;;;N;;;;; +268D;DIGRAM FOR LESSER YIN;So;0;ON;;;;;N;;;;; +268E;DIGRAM FOR LESSER YANG;So;0;ON;;;;;N;;;;; +268F;DIGRAM FOR GREATER YIN;So;0;ON;;;;;N;;;;; +2690;WHITE FLAG;So;0;ON;;;;;N;;;;; +2691;BLACK FLAG;So;0;ON;;;;;N;;;;; +2692;HAMMER AND PICK;So;0;ON;;;;;N;;;;; +2693;ANCHOR;So;0;ON;;;;;N;;;;; +2694;CROSSED SWORDS;So;0;ON;;;;;N;;;;; +2695;STAFF OF AESCULAPIUS;So;0;ON;;;;;N;;;;; +2696;SCALES;So;0;ON;;;;;N;;;;; +2697;ALEMBIC;So;0;ON;;;;;N;;;;; +2698;FLOWER;So;0;ON;;;;;N;;;;; +2699;GEAR;So;0;ON;;;;;N;;;;; +269A;STAFF OF HERMES;So;0;ON;;;;;N;;;;; +269B;ATOM SYMBOL;So;0;ON;;;;;N;;;;; +269C;FLEUR-DE-LIS;So;0;ON;;;;;N;;;;; +269D;OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;; +269E;THREE LINES CONVERGING RIGHT;So;0;ON;;;;;N;;;;; +269F;THREE LINES CONVERGING LEFT;So;0;ON;;;;;N;;;;; +26A0;WARNING SIGN;So;0;ON;;;;;N;;;;; +26A1;HIGH VOLTAGE SIGN;So;0;ON;;;;;N;;;;; +26A2;DOUBLED FEMALE SIGN;So;0;ON;;;;;N;;;;; +26A3;DOUBLED MALE SIGN;So;0;ON;;;;;N;;;;; +26A4;INTERLOCKED FEMALE AND MALE SIGN;So;0;ON;;;;;N;;;;; +26A5;MALE AND FEMALE SIGN;So;0;ON;;;;;N;;;;; +26A6;MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;; +26A7;MALE WITH STROKE AND MALE AND FEMALE SIGN;So;0;ON;;;;;N;;;;; +26A8;VERTICAL MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;; +26A9;HORIZONTAL MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;; +26AA;MEDIUM WHITE CIRCLE;So;0;ON;;;;;N;;;;; +26AB;MEDIUM BLACK CIRCLE;So;0;ON;;;;;N;;;;; +26AC;MEDIUM SMALL WHITE CIRCLE;So;0;L;;;;;N;;;;; +26AD;MARRIAGE SYMBOL;So;0;ON;;;;;N;;;;; +26AE;DIVORCE SYMBOL;So;0;ON;;;;;N;;;;; +26AF;UNMARRIED PARTNERSHIP SYMBOL;So;0;ON;;;;;N;;;;; +26B0;COFFIN;So;0;ON;;;;;N;;;;; +26B1;FUNERAL URN;So;0;ON;;;;;N;;;;; +26B2;NEUTER;So;0;ON;;;;;N;;;;; +26B3;CERES;So;0;ON;;;;;N;;;;; +26B4;PALLAS;So;0;ON;;;;;N;;;;; +26B5;JUNO;So;0;ON;;;;;N;;;;; +26B6;VESTA;So;0;ON;;;;;N;;;;; +26B7;CHIRON;So;0;ON;;;;;N;;;;; +26B8;BLACK MOON LILITH;So;0;ON;;;;;N;;;;; +26B9;SEXTILE;So;0;ON;;;;;N;;;;; +26BA;SEMISEXTILE;So;0;ON;;;;;N;;;;; +26BB;QUINCUNX;So;0;ON;;;;;N;;;;; +26BC;SESQUIQUADRATE;So;0;ON;;;;;N;;;;; +26BD;SOCCER BALL;So;0;ON;;;;;N;;;;; +26BE;BASEBALL;So;0;ON;;;;;N;;;;; +26BF;SQUARED KEY;So;0;ON;;;;;N;;;;; +26C0;WHITE DRAUGHTS MAN;So;0;ON;;;;;N;;;;; +26C1;WHITE DRAUGHTS KING;So;0;ON;;;;;N;;;;; +26C2;BLACK DRAUGHTS MAN;So;0;ON;;;;;N;;;;; +26C3;BLACK DRAUGHTS KING;So;0;ON;;;;;N;;;;; +26C4;SNOWMAN WITHOUT SNOW;So;0;ON;;;;;N;;;;; +26C5;SUN BEHIND CLOUD;So;0;ON;;;;;N;;;;; +26C6;RAIN;So;0;ON;;;;;N;;;;; +26C7;BLACK SNOWMAN;So;0;ON;;;;;N;;;;; +26C8;THUNDER CLOUD AND RAIN;So;0;ON;;;;;N;;;;; +26C9;TURNED WHITE SHOGI PIECE;So;0;ON;;;;;N;;;;; +26CA;TURNED BLACK SHOGI PIECE;So;0;ON;;;;;N;;;;; +26CB;WHITE DIAMOND IN SQUARE;So;0;ON;;;;;N;;;;; +26CC;CROSSING LANES;So;0;ON;;;;;N;;;;; +26CD;DISABLED CAR;So;0;ON;;;;;N;;;;; +26CE;OPHIUCHUS;So;0;ON;;;;;N;;;;; +26CF;PICK;So;0;ON;;;;;N;;;;; +26D0;CAR SLIDING;So;0;ON;;;;;N;;;;; +26D1;HELMET WITH WHITE CROSS;So;0;ON;;;;;N;;;;; +26D2;CIRCLED CROSSING LANES;So;0;ON;;;;;N;;;;; +26D3;CHAINS;So;0;ON;;;;;N;;;;; +26D4;NO ENTRY;So;0;ON;;;;;N;;;;; +26D5;ALTERNATE ONE-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;; +26D6;BLACK TWO-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;; +26D7;WHITE TWO-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;; +26D8;BLACK LEFT LANE MERGE;So;0;ON;;;;;N;;;;; +26D9;WHITE LEFT LANE MERGE;So;0;ON;;;;;N;;;;; +26DA;DRIVE SLOW SIGN;So;0;ON;;;;;N;;;;; +26DB;HEAVY WHITE DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;;;;; +26DC;LEFT CLOSED ENTRY;So;0;ON;;;;;N;;;;; +26DD;SQUARED SALTIRE;So;0;ON;;;;;N;;;;; +26DE;FALLING DIAGONAL IN WHITE CIRCLE IN BLACK SQUARE;So;0;ON;;;;;N;;;;; +26DF;BLACK TRUCK;So;0;ON;;;;;N;;;;; +26E0;RESTRICTED LEFT ENTRY-1;So;0;ON;;;;;N;;;;; +26E1;RESTRICTED LEFT ENTRY-2;So;0;ON;;;;;N;;;;; +26E2;ASTRONOMICAL SYMBOL FOR URANUS;So;0;ON;;;;;N;;;;; +26E3;HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE;So;0;ON;;;;;N;;;;; +26E4;PENTAGRAM;So;0;ON;;;;;N;;;;; +26E5;RIGHT-HANDED INTERLACED PENTAGRAM;So;0;ON;;;;;N;;;;; +26E6;LEFT-HANDED INTERLACED PENTAGRAM;So;0;ON;;;;;N;;;;; +26E7;INVERTED PENTAGRAM;So;0;ON;;;;;N;;;;; +26E8;BLACK CROSS ON SHIELD;So;0;ON;;;;;N;;;;; +26E9;SHINTO SHRINE;So;0;ON;;;;;N;;;;; +26EA;CHURCH;So;0;ON;;;;;N;;;;; +26EB;CASTLE;So;0;ON;;;;;N;;;;; +26EC;HISTORIC SITE;So;0;ON;;;;;N;;;;; +26ED;GEAR WITHOUT HUB;So;0;ON;;;;;N;;;;; +26EE;GEAR WITH HANDLES;So;0;ON;;;;;N;;;;; +26EF;MAP SYMBOL FOR LIGHTHOUSE;So;0;ON;;;;;N;;;;; +26F0;MOUNTAIN;So;0;ON;;;;;N;;;;; +26F1;UMBRELLA ON GROUND;So;0;ON;;;;;N;;;;; +26F2;FOUNTAIN;So;0;ON;;;;;N;;;;; +26F3;FLAG IN HOLE;So;0;ON;;;;;N;;;;; +26F4;FERRY;So;0;ON;;;;;N;;;;; +26F5;SAILBOAT;So;0;ON;;;;;N;;;;; +26F6;SQUARE FOUR CORNERS;So;0;ON;;;;;N;;;;; +26F7;SKIER;So;0;ON;;;;;N;;;;; +26F8;ICE SKATE;So;0;ON;;;;;N;;;;; +26F9;PERSON WITH BALL;So;0;ON;;;;;N;;;;; +26FA;TENT;So;0;ON;;;;;N;;;;; +26FB;JAPANESE BANK SYMBOL;So;0;ON;;;;;N;;;;; +26FC;HEADSTONE GRAVEYARD SYMBOL;So;0;ON;;;;;N;;;;; +26FD;FUEL PUMP;So;0;ON;;;;;N;;;;; +26FE;CUP ON BLACK SQUARE;So;0;ON;;;;;N;;;;; +26FF;WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE;So;0;ON;;;;;N;;;;; +2700;BLACK SAFETY SCISSORS;So;0;ON;;;;;N;;;;; +2701;UPPER BLADE SCISSORS;So;0;ON;;;;;N;;;;; +2702;BLACK SCISSORS;So;0;ON;;;;;N;;;;; +2703;LOWER BLADE SCISSORS;So;0;ON;;;;;N;;;;; +2704;WHITE SCISSORS;So;0;ON;;;;;N;;;;; +2705;WHITE HEAVY CHECK MARK;So;0;ON;;;;;N;;;;; +2706;TELEPHONE LOCATION SIGN;So;0;ON;;;;;N;;;;; +2707;TAPE DRIVE;So;0;ON;;;;;N;;;;; +2708;AIRPLANE;So;0;ON;;;;;N;;;;; +2709;ENVELOPE;So;0;ON;;;;;N;;;;; +270A;RAISED FIST;So;0;ON;;;;;N;;;;; +270B;RAISED HAND;So;0;ON;;;;;N;;;;; +270C;VICTORY HAND;So;0;ON;;;;;N;;;;; +270D;WRITING HAND;So;0;ON;;;;;N;;;;; +270E;LOWER RIGHT PENCIL;So;0;ON;;;;;N;;;;; +270F;PENCIL;So;0;ON;;;;;N;;;;; +2710;UPPER RIGHT PENCIL;So;0;ON;;;;;N;;;;; +2711;WHITE NIB;So;0;ON;;;;;N;;;;; +2712;BLACK NIB;So;0;ON;;;;;N;;;;; +2713;CHECK MARK;So;0;ON;;;;;N;;;;; +2714;HEAVY CHECK MARK;So;0;ON;;;;;N;;;;; +2715;MULTIPLICATION X;So;0;ON;;;;;N;;;;; +2716;HEAVY MULTIPLICATION X;So;0;ON;;;;;N;;;;; +2717;BALLOT X;So;0;ON;;;;;N;;;;; +2718;HEAVY BALLOT X;So;0;ON;;;;;N;;;;; +2719;OUTLINED GREEK CROSS;So;0;ON;;;;;N;;;;; +271A;HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;; +271B;OPEN CENTRE CROSS;So;0;ON;;;;;N;OPEN CENTER CROSS;;;; +271C;HEAVY OPEN CENTRE CROSS;So;0;ON;;;;;N;HEAVY OPEN CENTER CROSS;;;; +271D;LATIN CROSS;So;0;ON;;;;;N;;;;; +271E;SHADOWED WHITE LATIN CROSS;So;0;ON;;;;;N;;;;; +271F;OUTLINED LATIN CROSS;So;0;ON;;;;;N;;;;; +2720;MALTESE CROSS;So;0;ON;;;;;N;;;;; +2721;STAR OF DAVID;So;0;ON;;;;;N;;;;; +2722;FOUR TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2723;FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2724;HEAVY FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2725;FOUR CLUB-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2726;BLACK FOUR POINTED STAR;So;0;ON;;;;;N;;;;; +2727;WHITE FOUR POINTED STAR;So;0;ON;;;;;N;;;;; +2728;SPARKLES;So;0;ON;;;;;N;;;;; +2729;STRESS OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;; +272A;CIRCLED WHITE STAR;So;0;ON;;;;;N;;;;; +272B;OPEN CENTRE BLACK STAR;So;0;ON;;;;;N;OPEN CENTER BLACK STAR;;;; +272C;BLACK CENTRE WHITE STAR;So;0;ON;;;;;N;BLACK CENTER WHITE STAR;;;; +272D;OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;; +272E;HEAVY OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;; +272F;PINWHEEL STAR;So;0;ON;;;;;N;;;;; +2730;SHADOWED WHITE STAR;So;0;ON;;;;;N;;;;; +2731;HEAVY ASTERISK;So;0;ON;;;;;N;;;;; +2732;OPEN CENTRE ASTERISK;So;0;ON;;;;;N;OPEN CENTER ASTERISK;;;; +2733;EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +2734;EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +2735;EIGHT POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;; +2736;SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +2737;EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;; +2738;HEAVY EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;; +2739;TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +273A;SIXTEEN POINTED ASTERISK;So;0;ON;;;;;N;;;;; +273B;TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +273C;OPEN CENTRE TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;OPEN CENTER TEARDROP-SPOKED ASTERISK;;;; +273D;HEAVY TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +273E;SIX PETALLED BLACK AND WHITE FLORETTE;So;0;ON;;;;;N;;;;; +273F;BLACK FLORETTE;So;0;ON;;;;;N;;;;; +2740;WHITE FLORETTE;So;0;ON;;;;;N;;;;; +2741;EIGHT PETALLED OUTLINED BLACK FLORETTE;So;0;ON;;;;;N;;;;; +2742;CIRCLED OPEN CENTRE EIGHT POINTED STAR;So;0;ON;;;;;N;CIRCLED OPEN CENTER EIGHT POINTED STAR;;;; +2743;HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK;So;0;ON;;;;;N;;;;; +2744;SNOWFLAKE;So;0;ON;;;;;N;;;;; +2745;TIGHT TRIFOLIATE SNOWFLAKE;So;0;ON;;;;;N;;;;; +2746;HEAVY CHEVRON SNOWFLAKE;So;0;ON;;;;;N;;;;; +2747;SPARKLE;So;0;ON;;;;;N;;;;; +2748;HEAVY SPARKLE;So;0;ON;;;;;N;;;;; +2749;BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +274A;EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;; +274B;HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;; +274C;CROSS MARK;So;0;ON;;;;;N;;;;; +274D;SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;; +274E;NEGATIVE SQUARED CROSS MARK;So;0;ON;;;;;N;;;;; +274F;LOWER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; +2750;UPPER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; +2751;LOWER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; +2752;UPPER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; +2753;BLACK QUESTION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +2754;WHITE QUESTION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +2755;WHITE EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +2756;BLACK DIAMOND MINUS WHITE X;So;0;ON;;;;;N;;;;; +2757;HEAVY EXCLAMATION MARK SYMBOL;So;0;ON;;;;;N;;;;; +2758;LIGHT VERTICAL BAR;So;0;ON;;;;;N;;;;; +2759;MEDIUM VERTICAL BAR;So;0;ON;;;;;N;;;;; +275A;HEAVY VERTICAL BAR;So;0;ON;;;;;N;;;;; +275B;HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +275C;HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +275D;HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +275E;HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +275F;HEAVY LOW SINGLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +2760;HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +2761;CURVED STEM PARAGRAPH SIGN ORNAMENT;So;0;ON;;;;;N;;;;; +2762;HEAVY EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +2763;HEAVY HEART EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +2764;HEAVY BLACK HEART;So;0;ON;;;;;N;;;;; +2765;ROTATED HEAVY BLACK HEART BULLET;So;0;ON;;;;;N;;;;; +2766;FLORAL HEART;So;0;ON;;;;;N;;;;; +2767;ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;; +2768;MEDIUM LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;; +2769;MEDIUM RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;; +276A;MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;; +276B;MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;; +276C;MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; +276D;MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; +276E;HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT;Ps;0;ON;;;;;Y;;;;; +276F;HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT;Pe;0;ON;;;;;Y;;;;; +2770;HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; +2771;HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; +2772;LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; +2773;LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; +2774;MEDIUM LEFT CURLY BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; +2775;MEDIUM RIGHT CURLY BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; +2776;DINGBAT NEGATIVE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED DIGIT ONE;;;; +2777;DINGBAT NEGATIVE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED DIGIT TWO;;;; +2778;DINGBAT NEGATIVE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED DIGIT THREE;;;; +2779;DINGBAT NEGATIVE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED DIGIT FOUR;;;; +277A;DINGBAT NEGATIVE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED DIGIT FIVE;;;; +277B;DINGBAT NEGATIVE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED DIGIT SIX;;;; +277C;DINGBAT NEGATIVE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED DIGIT SEVEN;;;; +277D;DINGBAT NEGATIVE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED DIGIT EIGHT;;;; +277E;DINGBAT NEGATIVE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED DIGIT NINE;;;; +277F;DINGBAT NEGATIVE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED NUMBER TEN;;;; +2780;DINGBAT CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;CIRCLED SANS-SERIF DIGIT ONE;;;; +2781;DINGBAT CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;CIRCLED SANS-SERIF DIGIT TWO;;;; +2782;DINGBAT CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;CIRCLED SANS-SERIF DIGIT THREE;;;; +2783;DINGBAT CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;CIRCLED SANS-SERIF DIGIT FOUR;;;; +2784;DINGBAT CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;CIRCLED SANS-SERIF DIGIT FIVE;;;; +2785;DINGBAT CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;CIRCLED SANS-SERIF DIGIT SIX;;;; +2786;DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;CIRCLED SANS-SERIF DIGIT SEVEN;;;; +2787;DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;CIRCLED SANS-SERIF DIGIT EIGHT;;;; +2788;DINGBAT CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;CIRCLED SANS-SERIF DIGIT NINE;;;; +2789;DINGBAT CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;CIRCLED SANS-SERIF NUMBER TEN;;;; +278A;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED SANS-SERIF DIGIT ONE;;;; +278B;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED SANS-SERIF DIGIT TWO;;;; +278C;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED SANS-SERIF DIGIT THREE;;;; +278D;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED SANS-SERIF DIGIT FOUR;;;; +278E;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED SANS-SERIF DIGIT FIVE;;;; +278F;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED SANS-SERIF DIGIT SIX;;;; +2790;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED SANS-SERIF DIGIT SEVEN;;;; +2791;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED SANS-SERIF DIGIT EIGHT;;;; +2792;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED SANS-SERIF DIGIT NINE;;;; +2793;DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED SANS-SERIF NUMBER TEN;;;; +2794;HEAVY WIDE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WIDE-HEADED RIGHT ARROW;;;; +2795;HEAVY PLUS SIGN;So;0;ON;;;;;N;;;;; +2796;HEAVY MINUS SIGN;So;0;ON;;;;;N;;;;; +2797;HEAVY DIVISION SIGN;So;0;ON;;;;;N;;;;; +2798;HEAVY SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT ARROW;;;; +2799;HEAVY RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY RIGHT ARROW;;;; +279A;HEAVY NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT ARROW;;;; +279B;DRAFTING POINT RIGHTWARDS ARROW;So;0;ON;;;;;N;DRAFTING POINT RIGHT ARROW;;;; +279C;HEAVY ROUND-TIPPED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY ROUND-TIPPED RIGHT ARROW;;;; +279D;TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;TRIANGLE-HEADED RIGHT ARROW;;;; +279E;HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TRIANGLE-HEADED RIGHT ARROW;;;; +279F;DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;DASHED TRIANGLE-HEADED RIGHT ARROW;;;; +27A0;HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY DASHED TRIANGLE-HEADED RIGHT ARROW;;;; +27A1;BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK RIGHT ARROW;;;; +27A2;THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D TOP-LIGHTED RIGHT ARROWHEAD;;;; +27A3;THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D BOTTOM-LIGHTED RIGHT ARROWHEAD;;;; +27A4;BLACK RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;BLACK RIGHT ARROWHEAD;;;; +27A5;HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED DOWN AND RIGHT ARROW;;;; +27A6;HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED UP AND RIGHT ARROW;;;; +27A7;SQUAT BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;SQUAT BLACK RIGHT ARROW;;;; +27A8;HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY CONCAVE-POINTED BLACK RIGHT ARROW;;;; +27A9;RIGHT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;RIGHT-SHADED WHITE RIGHT ARROW;;;; +27AA;LEFT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT-SHADED WHITE RIGHT ARROW;;;; +27AB;BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;BACK-TILTED SHADOWED WHITE RIGHT ARROW;;;; +27AC;FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;FRONT-TILTED SHADOWED WHITE RIGHT ARROW;;;; +27AD;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; +27AE;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; +27AF;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; +27B0;CURLY LOOP;So;0;ON;;;;;N;;;;; +27B1;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; +27B2;CIRCLED HEAVY WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;CIRCLED HEAVY WHITE RIGHT ARROW;;;; +27B3;WHITE-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;WHITE-FEATHERED RIGHT ARROW;;;; +27B4;BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED LOWER RIGHT ARROW;;;; +27B5;BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK-FEATHERED RIGHT ARROW;;;; +27B6;BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED UPPER RIGHT ARROW;;;; +27B7;HEAVY BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED LOWER RIGHT ARROW;;;; +27B8;HEAVY BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED RIGHT ARROW;;;; +27B9;HEAVY BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED UPPER RIGHT ARROW;;;; +27BA;TEARDROP-BARBED RIGHTWARDS ARROW;So;0;ON;;;;;N;TEARDROP-BARBED RIGHT ARROW;;;; +27BB;HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TEARDROP-SHANKED RIGHT ARROW;;;; +27BC;WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;WEDGE-TAILED RIGHT ARROW;;;; +27BD;HEAVY WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WEDGE-TAILED RIGHT ARROW;;;; +27BE;OPEN-OUTLINED RIGHTWARDS ARROW;So;0;ON;;;;;N;OPEN-OUTLINED RIGHT ARROW;;;; +27BF;DOUBLE CURLY LOOP;So;0;ON;;;;;N;;;;; +27C0;THREE DIMENSIONAL ANGLE;Sm;0;ON;;;;;Y;;;;; +27C1;WHITE TRIANGLE CONTAINING SMALL WHITE TRIANGLE;Sm;0;ON;;;;;N;;;;; +27C2;PERPENDICULAR;Sm;0;ON;;;;;N;;;;; +27C3;OPEN SUBSET;Sm;0;ON;;;;;Y;;;;; +27C4;OPEN SUPERSET;Sm;0;ON;;;;;Y;;;;; +27C5;LEFT S-SHAPED BAG DELIMITER;Ps;0;ON;;;;;Y;;;;; +27C6;RIGHT S-SHAPED BAG DELIMITER;Pe;0;ON;;;;;Y;;;;; +27C7;OR WITH DOT INSIDE;Sm;0;ON;;;;;N;;;;; +27C8;REVERSE SOLIDUS PRECEDING SUBSET;Sm;0;ON;;;;;Y;;;;; +27C9;SUPERSET PRECEDING SOLIDUS;Sm;0;ON;;;;;Y;;;;; +27CA;VERTICAL BAR WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +27CB;MATHEMATICAL RISING DIAGONAL;Sm;0;ON;;;;;Y;;;;; +27CC;LONG DIVISION;Sm;0;ON;;;;;Y;;;;; +27CD;MATHEMATICAL FALLING DIAGONAL;Sm;0;ON;;;;;Y;;;;; +27CE;SQUARED LOGICAL AND;Sm;0;ON;;;;;N;;;;; +27CF;SQUARED LOGICAL OR;Sm;0;ON;;;;;N;;;;; +27D0;WHITE DIAMOND WITH CENTRED DOT;Sm;0;ON;;;;;N;;;;; +27D1;AND WITH DOT;Sm;0;ON;;;;;N;;;;; +27D2;ELEMENT OF OPENING UPWARDS;Sm;0;ON;;;;;N;;;;; +27D3;LOWER RIGHT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;; +27D4;UPPER LEFT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;; +27D5;LEFT OUTER JOIN;Sm;0;ON;;;;;Y;;;;; +27D6;RIGHT OUTER JOIN;Sm;0;ON;;;;;Y;;;;; +27D7;FULL OUTER JOIN;Sm;0;ON;;;;;N;;;;; +27D8;LARGE UP TACK;Sm;0;ON;;;;;N;;;;; +27D9;LARGE DOWN TACK;Sm;0;ON;;;;;N;;;;; +27DA;LEFT AND RIGHT DOUBLE TURNSTILE;Sm;0;ON;;;;;N;;;;; +27DB;LEFT AND RIGHT TACK;Sm;0;ON;;;;;N;;;;; +27DC;LEFT MULTIMAP;Sm;0;ON;;;;;Y;;;;; +27DD;LONG RIGHT TACK;Sm;0;ON;;;;;Y;;;;; +27DE;LONG LEFT TACK;Sm;0;ON;;;;;Y;;;;; +27DF;UP TACK WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; +27E0;LOZENGE DIVIDED BY HORIZONTAL RULE;Sm;0;ON;;;;;N;;;;; +27E1;WHITE CONCAVE-SIDED DIAMOND;Sm;0;ON;;;;;N;;;;; +27E2;WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;; +27E3;WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;; +27E4;WHITE SQUARE WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;; +27E5;WHITE SQUARE WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;; +27E6;MATHEMATICAL LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;;;;; +27E7;MATHEMATICAL RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;;;;; +27E8;MATHEMATICAL LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;; +27E9;MATHEMATICAL RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;; +27EA;MATHEMATICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;; +27EB;MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;; +27EC;MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;;;;; +27ED;MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;;;;; +27EE;MATHEMATICAL LEFT FLATTENED PARENTHESIS;Ps;0;ON;;;;;Y;;;;; +27EF;MATHEMATICAL RIGHT FLATTENED PARENTHESIS;Pe;0;ON;;;;;Y;;;;; +27F0;UPWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;; +27F1;DOWNWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;; +27F2;ANTICLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; +27F3;CLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; +27F4;RIGHT ARROW WITH CIRCLED PLUS;Sm;0;ON;;;;;N;;;;; +27F5;LONG LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +27F6;LONG RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +27F7;LONG LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;; +27F8;LONG LEFTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; +27F9;LONG RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; +27FA;LONG LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; +27FB;LONG LEFTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +27FC;LONG RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +27FD;LONG LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +27FE;LONG RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +27FF;LONG RIGHTWARDS SQUIGGLE ARROW;Sm;0;ON;;;;;N;;;;; +2800;BRAILLE PATTERN BLANK;So;0;L;;;;;N;;;;; +2801;BRAILLE PATTERN DOTS-1;So;0;L;;;;;N;;;;; +2802;BRAILLE PATTERN DOTS-2;So;0;L;;;;;N;;;;; +2803;BRAILLE PATTERN DOTS-12;So;0;L;;;;;N;;;;; +2804;BRAILLE PATTERN DOTS-3;So;0;L;;;;;N;;;;; +2805;BRAILLE PATTERN DOTS-13;So;0;L;;;;;N;;;;; +2806;BRAILLE PATTERN DOTS-23;So;0;L;;;;;N;;;;; +2807;BRAILLE PATTERN DOTS-123;So;0;L;;;;;N;;;;; +2808;BRAILLE PATTERN DOTS-4;So;0;L;;;;;N;;;;; +2809;BRAILLE PATTERN DOTS-14;So;0;L;;;;;N;;;;; +280A;BRAILLE PATTERN DOTS-24;So;0;L;;;;;N;;;;; +280B;BRAILLE PATTERN DOTS-124;So;0;L;;;;;N;;;;; +280C;BRAILLE PATTERN DOTS-34;So;0;L;;;;;N;;;;; +280D;BRAILLE PATTERN DOTS-134;So;0;L;;;;;N;;;;; +280E;BRAILLE PATTERN DOTS-234;So;0;L;;;;;N;;;;; +280F;BRAILLE PATTERN DOTS-1234;So;0;L;;;;;N;;;;; +2810;BRAILLE PATTERN DOTS-5;So;0;L;;;;;N;;;;; +2811;BRAILLE PATTERN DOTS-15;So;0;L;;;;;N;;;;; +2812;BRAILLE PATTERN DOTS-25;So;0;L;;;;;N;;;;; +2813;BRAILLE PATTERN DOTS-125;So;0;L;;;;;N;;;;; +2814;BRAILLE PATTERN DOTS-35;So;0;L;;;;;N;;;;; +2815;BRAILLE PATTERN DOTS-135;So;0;L;;;;;N;;;;; +2816;BRAILLE PATTERN DOTS-235;So;0;L;;;;;N;;;;; +2817;BRAILLE PATTERN DOTS-1235;So;0;L;;;;;N;;;;; +2818;BRAILLE PATTERN DOTS-45;So;0;L;;;;;N;;;;; +2819;BRAILLE PATTERN DOTS-145;So;0;L;;;;;N;;;;; +281A;BRAILLE PATTERN DOTS-245;So;0;L;;;;;N;;;;; +281B;BRAILLE PATTERN DOTS-1245;So;0;L;;;;;N;;;;; +281C;BRAILLE PATTERN DOTS-345;So;0;L;;;;;N;;;;; +281D;BRAILLE PATTERN DOTS-1345;So;0;L;;;;;N;;;;; +281E;BRAILLE PATTERN DOTS-2345;So;0;L;;;;;N;;;;; +281F;BRAILLE PATTERN DOTS-12345;So;0;L;;;;;N;;;;; +2820;BRAILLE PATTERN DOTS-6;So;0;L;;;;;N;;;;; +2821;BRAILLE PATTERN DOTS-16;So;0;L;;;;;N;;;;; +2822;BRAILLE PATTERN DOTS-26;So;0;L;;;;;N;;;;; +2823;BRAILLE PATTERN DOTS-126;So;0;L;;;;;N;;;;; +2824;BRAILLE PATTERN DOTS-36;So;0;L;;;;;N;;;;; +2825;BRAILLE PATTERN DOTS-136;So;0;L;;;;;N;;;;; +2826;BRAILLE PATTERN DOTS-236;So;0;L;;;;;N;;;;; +2827;BRAILLE PATTERN DOTS-1236;So;0;L;;;;;N;;;;; +2828;BRAILLE PATTERN DOTS-46;So;0;L;;;;;N;;;;; +2829;BRAILLE PATTERN DOTS-146;So;0;L;;;;;N;;;;; +282A;BRAILLE PATTERN DOTS-246;So;0;L;;;;;N;;;;; +282B;BRAILLE PATTERN DOTS-1246;So;0;L;;;;;N;;;;; +282C;BRAILLE PATTERN DOTS-346;So;0;L;;;;;N;;;;; +282D;BRAILLE PATTERN DOTS-1346;So;0;L;;;;;N;;;;; +282E;BRAILLE PATTERN DOTS-2346;So;0;L;;;;;N;;;;; +282F;BRAILLE PATTERN DOTS-12346;So;0;L;;;;;N;;;;; +2830;BRAILLE PATTERN DOTS-56;So;0;L;;;;;N;;;;; +2831;BRAILLE PATTERN DOTS-156;So;0;L;;;;;N;;;;; +2832;BRAILLE PATTERN DOTS-256;So;0;L;;;;;N;;;;; +2833;BRAILLE PATTERN DOTS-1256;So;0;L;;;;;N;;;;; +2834;BRAILLE PATTERN DOTS-356;So;0;L;;;;;N;;;;; +2835;BRAILLE PATTERN DOTS-1356;So;0;L;;;;;N;;;;; +2836;BRAILLE PATTERN DOTS-2356;So;0;L;;;;;N;;;;; +2837;BRAILLE PATTERN DOTS-12356;So;0;L;;;;;N;;;;; +2838;BRAILLE PATTERN DOTS-456;So;0;L;;;;;N;;;;; +2839;BRAILLE PATTERN DOTS-1456;So;0;L;;;;;N;;;;; +283A;BRAILLE PATTERN DOTS-2456;So;0;L;;;;;N;;;;; +283B;BRAILLE PATTERN DOTS-12456;So;0;L;;;;;N;;;;; +283C;BRAILLE PATTERN DOTS-3456;So;0;L;;;;;N;;;;; +283D;BRAILLE PATTERN DOTS-13456;So;0;L;;;;;N;;;;; +283E;BRAILLE PATTERN DOTS-23456;So;0;L;;;;;N;;;;; +283F;BRAILLE PATTERN DOTS-123456;So;0;L;;;;;N;;;;; +2840;BRAILLE PATTERN DOTS-7;So;0;L;;;;;N;;;;; +2841;BRAILLE PATTERN DOTS-17;So;0;L;;;;;N;;;;; +2842;BRAILLE PATTERN DOTS-27;So;0;L;;;;;N;;;;; +2843;BRAILLE PATTERN DOTS-127;So;0;L;;;;;N;;;;; +2844;BRAILLE PATTERN DOTS-37;So;0;L;;;;;N;;;;; +2845;BRAILLE PATTERN DOTS-137;So;0;L;;;;;N;;;;; +2846;BRAILLE PATTERN DOTS-237;So;0;L;;;;;N;;;;; +2847;BRAILLE PATTERN DOTS-1237;So;0;L;;;;;N;;;;; +2848;BRAILLE PATTERN DOTS-47;So;0;L;;;;;N;;;;; +2849;BRAILLE PATTERN DOTS-147;So;0;L;;;;;N;;;;; +284A;BRAILLE PATTERN DOTS-247;So;0;L;;;;;N;;;;; +284B;BRAILLE PATTERN DOTS-1247;So;0;L;;;;;N;;;;; +284C;BRAILLE PATTERN DOTS-347;So;0;L;;;;;N;;;;; +284D;BRAILLE PATTERN DOTS-1347;So;0;L;;;;;N;;;;; +284E;BRAILLE PATTERN DOTS-2347;So;0;L;;;;;N;;;;; +284F;BRAILLE PATTERN DOTS-12347;So;0;L;;;;;N;;;;; +2850;BRAILLE PATTERN DOTS-57;So;0;L;;;;;N;;;;; +2851;BRAILLE PATTERN DOTS-157;So;0;L;;;;;N;;;;; +2852;BRAILLE PATTERN DOTS-257;So;0;L;;;;;N;;;;; +2853;BRAILLE PATTERN DOTS-1257;So;0;L;;;;;N;;;;; +2854;BRAILLE PATTERN DOTS-357;So;0;L;;;;;N;;;;; +2855;BRAILLE PATTERN DOTS-1357;So;0;L;;;;;N;;;;; +2856;BRAILLE PATTERN DOTS-2357;So;0;L;;;;;N;;;;; +2857;BRAILLE PATTERN DOTS-12357;So;0;L;;;;;N;;;;; +2858;BRAILLE PATTERN DOTS-457;So;0;L;;;;;N;;;;; +2859;BRAILLE PATTERN DOTS-1457;So;0;L;;;;;N;;;;; +285A;BRAILLE PATTERN DOTS-2457;So;0;L;;;;;N;;;;; +285B;BRAILLE PATTERN DOTS-12457;So;0;L;;;;;N;;;;; +285C;BRAILLE PATTERN DOTS-3457;So;0;L;;;;;N;;;;; +285D;BRAILLE PATTERN DOTS-13457;So;0;L;;;;;N;;;;; +285E;BRAILLE PATTERN DOTS-23457;So;0;L;;;;;N;;;;; +285F;BRAILLE PATTERN DOTS-123457;So;0;L;;;;;N;;;;; +2860;BRAILLE PATTERN DOTS-67;So;0;L;;;;;N;;;;; +2861;BRAILLE PATTERN DOTS-167;So;0;L;;;;;N;;;;; +2862;BRAILLE PATTERN DOTS-267;So;0;L;;;;;N;;;;; +2863;BRAILLE PATTERN DOTS-1267;So;0;L;;;;;N;;;;; +2864;BRAILLE PATTERN DOTS-367;So;0;L;;;;;N;;;;; +2865;BRAILLE PATTERN DOTS-1367;So;0;L;;;;;N;;;;; +2866;BRAILLE PATTERN DOTS-2367;So;0;L;;;;;N;;;;; +2867;BRAILLE PATTERN DOTS-12367;So;0;L;;;;;N;;;;; +2868;BRAILLE PATTERN DOTS-467;So;0;L;;;;;N;;;;; +2869;BRAILLE PATTERN DOTS-1467;So;0;L;;;;;N;;;;; +286A;BRAILLE PATTERN DOTS-2467;So;0;L;;;;;N;;;;; +286B;BRAILLE PATTERN DOTS-12467;So;0;L;;;;;N;;;;; +286C;BRAILLE PATTERN DOTS-3467;So;0;L;;;;;N;;;;; +286D;BRAILLE PATTERN DOTS-13467;So;0;L;;;;;N;;;;; +286E;BRAILLE PATTERN DOTS-23467;So;0;L;;;;;N;;;;; +286F;BRAILLE PATTERN DOTS-123467;So;0;L;;;;;N;;;;; +2870;BRAILLE PATTERN DOTS-567;So;0;L;;;;;N;;;;; +2871;BRAILLE PATTERN DOTS-1567;So;0;L;;;;;N;;;;; +2872;BRAILLE PATTERN DOTS-2567;So;0;L;;;;;N;;;;; +2873;BRAILLE PATTERN DOTS-12567;So;0;L;;;;;N;;;;; +2874;BRAILLE PATTERN DOTS-3567;So;0;L;;;;;N;;;;; +2875;BRAILLE PATTERN DOTS-13567;So;0;L;;;;;N;;;;; +2876;BRAILLE PATTERN DOTS-23567;So;0;L;;;;;N;;;;; +2877;BRAILLE PATTERN DOTS-123567;So;0;L;;;;;N;;;;; +2878;BRAILLE PATTERN DOTS-4567;So;0;L;;;;;N;;;;; +2879;BRAILLE PATTERN DOTS-14567;So;0;L;;;;;N;;;;; +287A;BRAILLE PATTERN DOTS-24567;So;0;L;;;;;N;;;;; +287B;BRAILLE PATTERN DOTS-124567;So;0;L;;;;;N;;;;; +287C;BRAILLE PATTERN DOTS-34567;So;0;L;;;;;N;;;;; +287D;BRAILLE PATTERN DOTS-134567;So;0;L;;;;;N;;;;; +287E;BRAILLE PATTERN DOTS-234567;So;0;L;;;;;N;;;;; +287F;BRAILLE PATTERN DOTS-1234567;So;0;L;;;;;N;;;;; +2880;BRAILLE PATTERN DOTS-8;So;0;L;;;;;N;;;;; +2881;BRAILLE PATTERN DOTS-18;So;0;L;;;;;N;;;;; +2882;BRAILLE PATTERN DOTS-28;So;0;L;;;;;N;;;;; +2883;BRAILLE PATTERN DOTS-128;So;0;L;;;;;N;;;;; +2884;BRAILLE PATTERN DOTS-38;So;0;L;;;;;N;;;;; +2885;BRAILLE PATTERN DOTS-138;So;0;L;;;;;N;;;;; +2886;BRAILLE PATTERN DOTS-238;So;0;L;;;;;N;;;;; +2887;BRAILLE PATTERN DOTS-1238;So;0;L;;;;;N;;;;; +2888;BRAILLE PATTERN DOTS-48;So;0;L;;;;;N;;;;; +2889;BRAILLE PATTERN DOTS-148;So;0;L;;;;;N;;;;; +288A;BRAILLE PATTERN DOTS-248;So;0;L;;;;;N;;;;; +288B;BRAILLE PATTERN DOTS-1248;So;0;L;;;;;N;;;;; +288C;BRAILLE PATTERN DOTS-348;So;0;L;;;;;N;;;;; +288D;BRAILLE PATTERN DOTS-1348;So;0;L;;;;;N;;;;; +288E;BRAILLE PATTERN DOTS-2348;So;0;L;;;;;N;;;;; +288F;BRAILLE PATTERN DOTS-12348;So;0;L;;;;;N;;;;; +2890;BRAILLE PATTERN DOTS-58;So;0;L;;;;;N;;;;; +2891;BRAILLE PATTERN DOTS-158;So;0;L;;;;;N;;;;; +2892;BRAILLE PATTERN DOTS-258;So;0;L;;;;;N;;;;; +2893;BRAILLE PATTERN DOTS-1258;So;0;L;;;;;N;;;;; +2894;BRAILLE PATTERN DOTS-358;So;0;L;;;;;N;;;;; +2895;BRAILLE PATTERN DOTS-1358;So;0;L;;;;;N;;;;; +2896;BRAILLE PATTERN DOTS-2358;So;0;L;;;;;N;;;;; +2897;BRAILLE PATTERN DOTS-12358;So;0;L;;;;;N;;;;; +2898;BRAILLE PATTERN DOTS-458;So;0;L;;;;;N;;;;; +2899;BRAILLE PATTERN DOTS-1458;So;0;L;;;;;N;;;;; +289A;BRAILLE PATTERN DOTS-2458;So;0;L;;;;;N;;;;; +289B;BRAILLE PATTERN DOTS-12458;So;0;L;;;;;N;;;;; +289C;BRAILLE PATTERN DOTS-3458;So;0;L;;;;;N;;;;; +289D;BRAILLE PATTERN DOTS-13458;So;0;L;;;;;N;;;;; +289E;BRAILLE PATTERN DOTS-23458;So;0;L;;;;;N;;;;; +289F;BRAILLE PATTERN DOTS-123458;So;0;L;;;;;N;;;;; +28A0;BRAILLE PATTERN DOTS-68;So;0;L;;;;;N;;;;; +28A1;BRAILLE PATTERN DOTS-168;So;0;L;;;;;N;;;;; +28A2;BRAILLE PATTERN DOTS-268;So;0;L;;;;;N;;;;; +28A3;BRAILLE PATTERN DOTS-1268;So;0;L;;;;;N;;;;; +28A4;BRAILLE PATTERN DOTS-368;So;0;L;;;;;N;;;;; +28A5;BRAILLE PATTERN DOTS-1368;So;0;L;;;;;N;;;;; +28A6;BRAILLE PATTERN DOTS-2368;So;0;L;;;;;N;;;;; +28A7;BRAILLE PATTERN DOTS-12368;So;0;L;;;;;N;;;;; +28A8;BRAILLE PATTERN DOTS-468;So;0;L;;;;;N;;;;; +28A9;BRAILLE PATTERN DOTS-1468;So;0;L;;;;;N;;;;; +28AA;BRAILLE PATTERN DOTS-2468;So;0;L;;;;;N;;;;; +28AB;BRAILLE PATTERN DOTS-12468;So;0;L;;;;;N;;;;; +28AC;BRAILLE PATTERN DOTS-3468;So;0;L;;;;;N;;;;; +28AD;BRAILLE PATTERN DOTS-13468;So;0;L;;;;;N;;;;; +28AE;BRAILLE PATTERN DOTS-23468;So;0;L;;;;;N;;;;; +28AF;BRAILLE PATTERN DOTS-123468;So;0;L;;;;;N;;;;; +28B0;BRAILLE PATTERN DOTS-568;So;0;L;;;;;N;;;;; +28B1;BRAILLE PATTERN DOTS-1568;So;0;L;;;;;N;;;;; +28B2;BRAILLE PATTERN DOTS-2568;So;0;L;;;;;N;;;;; +28B3;BRAILLE PATTERN DOTS-12568;So;0;L;;;;;N;;;;; +28B4;BRAILLE PATTERN DOTS-3568;So;0;L;;;;;N;;;;; +28B5;BRAILLE PATTERN DOTS-13568;So;0;L;;;;;N;;;;; +28B6;BRAILLE PATTERN DOTS-23568;So;0;L;;;;;N;;;;; +28B7;BRAILLE PATTERN DOTS-123568;So;0;L;;;;;N;;;;; +28B8;BRAILLE PATTERN DOTS-4568;So;0;L;;;;;N;;;;; +28B9;BRAILLE PATTERN DOTS-14568;So;0;L;;;;;N;;;;; +28BA;BRAILLE PATTERN DOTS-24568;So;0;L;;;;;N;;;;; +28BB;BRAILLE PATTERN DOTS-124568;So;0;L;;;;;N;;;;; +28BC;BRAILLE PATTERN DOTS-34568;So;0;L;;;;;N;;;;; +28BD;BRAILLE PATTERN DOTS-134568;So;0;L;;;;;N;;;;; +28BE;BRAILLE PATTERN DOTS-234568;So;0;L;;;;;N;;;;; +28BF;BRAILLE PATTERN DOTS-1234568;So;0;L;;;;;N;;;;; +28C0;BRAILLE PATTERN DOTS-78;So;0;L;;;;;N;;;;; +28C1;BRAILLE PATTERN DOTS-178;So;0;L;;;;;N;;;;; +28C2;BRAILLE PATTERN DOTS-278;So;0;L;;;;;N;;;;; +28C3;BRAILLE PATTERN DOTS-1278;So;0;L;;;;;N;;;;; +28C4;BRAILLE PATTERN DOTS-378;So;0;L;;;;;N;;;;; +28C5;BRAILLE PATTERN DOTS-1378;So;0;L;;;;;N;;;;; +28C6;BRAILLE PATTERN DOTS-2378;So;0;L;;;;;N;;;;; +28C7;BRAILLE PATTERN DOTS-12378;So;0;L;;;;;N;;;;; +28C8;BRAILLE PATTERN DOTS-478;So;0;L;;;;;N;;;;; +28C9;BRAILLE PATTERN DOTS-1478;So;0;L;;;;;N;;;;; +28CA;BRAILLE PATTERN DOTS-2478;So;0;L;;;;;N;;;;; +28CB;BRAILLE PATTERN DOTS-12478;So;0;L;;;;;N;;;;; +28CC;BRAILLE PATTERN DOTS-3478;So;0;L;;;;;N;;;;; +28CD;BRAILLE PATTERN DOTS-13478;So;0;L;;;;;N;;;;; +28CE;BRAILLE PATTERN DOTS-23478;So;0;L;;;;;N;;;;; +28CF;BRAILLE PATTERN DOTS-123478;So;0;L;;;;;N;;;;; +28D0;BRAILLE PATTERN DOTS-578;So;0;L;;;;;N;;;;; +28D1;BRAILLE PATTERN DOTS-1578;So;0;L;;;;;N;;;;; +28D2;BRAILLE PATTERN DOTS-2578;So;0;L;;;;;N;;;;; +28D3;BRAILLE PATTERN DOTS-12578;So;0;L;;;;;N;;;;; +28D4;BRAILLE PATTERN DOTS-3578;So;0;L;;;;;N;;;;; +28D5;BRAILLE PATTERN DOTS-13578;So;0;L;;;;;N;;;;; +28D6;BRAILLE PATTERN DOTS-23578;So;0;L;;;;;N;;;;; +28D7;BRAILLE PATTERN DOTS-123578;So;0;L;;;;;N;;;;; +28D8;BRAILLE PATTERN DOTS-4578;So;0;L;;;;;N;;;;; +28D9;BRAILLE PATTERN DOTS-14578;So;0;L;;;;;N;;;;; +28DA;BRAILLE PATTERN DOTS-24578;So;0;L;;;;;N;;;;; +28DB;BRAILLE PATTERN DOTS-124578;So;0;L;;;;;N;;;;; +28DC;BRAILLE PATTERN DOTS-34578;So;0;L;;;;;N;;;;; +28DD;BRAILLE PATTERN DOTS-134578;So;0;L;;;;;N;;;;; +28DE;BRAILLE PATTERN DOTS-234578;So;0;L;;;;;N;;;;; +28DF;BRAILLE PATTERN DOTS-1234578;So;0;L;;;;;N;;;;; +28E0;BRAILLE PATTERN DOTS-678;So;0;L;;;;;N;;;;; +28E1;BRAILLE PATTERN DOTS-1678;So;0;L;;;;;N;;;;; +28E2;BRAILLE PATTERN DOTS-2678;So;0;L;;;;;N;;;;; +28E3;BRAILLE PATTERN DOTS-12678;So;0;L;;;;;N;;;;; +28E4;BRAILLE PATTERN DOTS-3678;So;0;L;;;;;N;;;;; +28E5;BRAILLE PATTERN DOTS-13678;So;0;L;;;;;N;;;;; +28E6;BRAILLE PATTERN DOTS-23678;So;0;L;;;;;N;;;;; +28E7;BRAILLE PATTERN DOTS-123678;So;0;L;;;;;N;;;;; +28E8;BRAILLE PATTERN DOTS-4678;So;0;L;;;;;N;;;;; +28E9;BRAILLE PATTERN DOTS-14678;So;0;L;;;;;N;;;;; +28EA;BRAILLE PATTERN DOTS-24678;So;0;L;;;;;N;;;;; +28EB;BRAILLE PATTERN DOTS-124678;So;0;L;;;;;N;;;;; +28EC;BRAILLE PATTERN DOTS-34678;So;0;L;;;;;N;;;;; +28ED;BRAILLE PATTERN DOTS-134678;So;0;L;;;;;N;;;;; +28EE;BRAILLE PATTERN DOTS-234678;So;0;L;;;;;N;;;;; +28EF;BRAILLE PATTERN DOTS-1234678;So;0;L;;;;;N;;;;; +28F0;BRAILLE PATTERN DOTS-5678;So;0;L;;;;;N;;;;; +28F1;BRAILLE PATTERN DOTS-15678;So;0;L;;;;;N;;;;; +28F2;BRAILLE PATTERN DOTS-25678;So;0;L;;;;;N;;;;; +28F3;BRAILLE PATTERN DOTS-125678;So;0;L;;;;;N;;;;; +28F4;BRAILLE PATTERN DOTS-35678;So;0;L;;;;;N;;;;; +28F5;BRAILLE PATTERN DOTS-135678;So;0;L;;;;;N;;;;; +28F6;BRAILLE PATTERN DOTS-235678;So;0;L;;;;;N;;;;; +28F7;BRAILLE PATTERN DOTS-1235678;So;0;L;;;;;N;;;;; +28F8;BRAILLE PATTERN DOTS-45678;So;0;L;;;;;N;;;;; +28F9;BRAILLE PATTERN DOTS-145678;So;0;L;;;;;N;;;;; +28FA;BRAILLE PATTERN DOTS-245678;So;0;L;;;;;N;;;;; +28FB;BRAILLE PATTERN DOTS-1245678;So;0;L;;;;;N;;;;; +28FC;BRAILLE PATTERN DOTS-345678;So;0;L;;;;;N;;;;; +28FD;BRAILLE PATTERN DOTS-1345678;So;0;L;;;;;N;;;;; +28FE;BRAILLE PATTERN DOTS-2345678;So;0;L;;;;;N;;;;; +28FF;BRAILLE PATTERN DOTS-12345678;So;0;L;;;;;N;;;;; +2900;RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2901;RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2902;LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2903;RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2904;LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2905;RIGHTWARDS TWO-HEADED ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +2906;LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +2907;RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +2908;DOWNWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +2909;UPWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +290A;UPWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;; +290B;DOWNWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;; +290C;LEFTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +290D;RIGHTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +290E;LEFTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +290F;RIGHTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +2910;RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +2911;RIGHTWARDS ARROW WITH DOTTED STEM;Sm;0;ON;;;;;N;;;;; +2912;UPWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;; +2913;DOWNWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;; +2914;RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2915;RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2916;RIGHTWARDS TWO-HEADED ARROW WITH TAIL;Sm;0;ON;;;;;N;;;;; +2917;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2918;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2919;LEFTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;; +291A;RIGHTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;; +291B;LEFTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;; +291C;RIGHTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;; +291D;LEFTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +291E;RIGHTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +291F;LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +2920;RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +2921;NORTH WEST AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2922;NORTH EAST AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;; +2923;NORTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; +2924;NORTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; +2925;SOUTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; +2926;SOUTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; +2927;NORTH WEST ARROW AND NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2928;NORTH EAST ARROW AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2929;SOUTH EAST ARROW AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;; +292A;SOUTH WEST ARROW AND NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;; +292B;RISING DIAGONAL CROSSING FALLING DIAGONAL;Sm;0;ON;;;;;N;;;;; +292C;FALLING DIAGONAL CROSSING RISING DIAGONAL;Sm;0;ON;;;;;N;;;;; +292D;SOUTH EAST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +292E;NORTH EAST ARROW CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +292F;FALLING DIAGONAL CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2930;RISING DIAGONAL CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2931;NORTH EAST ARROW CROSSING NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;; +2932;NORTH WEST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; +2933;WAVE ARROW POINTING DIRECTLY RIGHT;Sm;0;ON;;;;;N;;;;; +2934;ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS;Sm;0;ON;;;;;N;;;;; +2935;ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS;Sm;0;ON;;;;;N;;;;; +2936;ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS;Sm;0;ON;;;;;N;;;;; +2937;ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS;Sm;0;ON;;;;;N;;;;; +2938;RIGHT-SIDE ARC CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +2939;LEFT-SIDE ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +293A;TOP ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +293B;BOTTOM ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +293C;TOP ARC CLOCKWISE ARROW WITH MINUS;Sm;0;ON;;;;;N;;;;; +293D;TOP ARC ANTICLOCKWISE ARROW WITH PLUS;Sm;0;ON;;;;;N;;;;; +293E;LOWER RIGHT SEMICIRCULAR CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +293F;LOWER LEFT SEMICIRCULAR ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; +2940;ANTICLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; +2941;CLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; +2942;RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2943;LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2944;SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2945;RIGHTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;; +2946;LEFTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;; +2947;RIGHTWARDS ARROW THROUGH X;Sm;0;ON;;;;;N;;;;; +2948;LEFT RIGHT ARROW THROUGH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +2949;UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +294A;LEFT BARB UP RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;; +294B;LEFT BARB DOWN RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;; +294C;UP BARB RIGHT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;; +294D;UP BARB LEFT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;; +294E;LEFT BARB UP RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;; +294F;UP BARB RIGHT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;; +2950;LEFT BARB DOWN RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;; +2951;UP BARB LEFT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;; +2952;LEFTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;; +2953;RIGHTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;; +2954;UPWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;; +2955;DOWNWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;; +2956;LEFTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;; +2957;RIGHTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;; +2958;UPWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;; +2959;DOWNWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;; +295A;LEFTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;; +295B;RIGHTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;; +295C;UPWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;; +295D;DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;; +295E;LEFTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;; +295F;RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;; +2960;UPWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;; +2961;DOWNWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;; +2962;LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; +2963;UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; +2964;RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; +2965;DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; +2966;LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;; +2967;LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; +2968;RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;; +2969;RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; +296A;LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;; +296B;LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;; +296C;RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;; +296D;RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;; +296E;UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; +296F;DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; +2970;RIGHT DOUBLE ARROW WITH ROUNDED HEAD;Sm;0;ON;;;;;N;;;;; +2971;EQUALS SIGN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2972;TILDE OPERATOR ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2973;LEFTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;; +2974;RIGHTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;; +2975;RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;; +2976;LESS-THAN ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2977;LEFTWARDS ARROW THROUGH LESS-THAN;Sm;0;ON;;;;;N;;;;; +2978;GREATER-THAN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2979;SUBSET ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +297A;LEFTWARDS ARROW THROUGH SUBSET;Sm;0;ON;;;;;N;;;;; +297B;SUPERSET ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +297C;LEFT FISH TAIL;Sm;0;ON;;;;;N;;;;; +297D;RIGHT FISH TAIL;Sm;0;ON;;;;;N;;;;; +297E;UP FISH TAIL;Sm;0;ON;;;;;N;;;;; +297F;DOWN FISH TAIL;Sm;0;ON;;;;;N;;;;; +2980;TRIPLE VERTICAL BAR DELIMITER;Sm;0;ON;;;;;N;;;;; +2981;Z NOTATION SPOT;Sm;0;ON;;;;;N;;;;; +2982;Z NOTATION TYPE COLON;Sm;0;ON;;;;;N;;;;; +2983;LEFT WHITE CURLY BRACKET;Ps;0;ON;;;;;Y;;;;; +2984;RIGHT WHITE CURLY BRACKET;Pe;0;ON;;;;;Y;;;;; +2985;LEFT WHITE PARENTHESIS;Ps;0;ON;;;;;Y;;;;; +2986;RIGHT WHITE PARENTHESIS;Pe;0;ON;;;;;Y;;;;; +2987;Z NOTATION LEFT IMAGE BRACKET;Ps;0;ON;;;;;Y;;;;; +2988;Z NOTATION RIGHT IMAGE BRACKET;Pe;0;ON;;;;;Y;;;;; +2989;Z NOTATION LEFT BINDING BRACKET;Ps;0;ON;;;;;Y;;;;; +298A;Z NOTATION RIGHT BINDING BRACKET;Pe;0;ON;;;;;Y;;;;; +298B;LEFT SQUARE BRACKET WITH UNDERBAR;Ps;0;ON;;;;;Y;;;;; +298C;RIGHT SQUARE BRACKET WITH UNDERBAR;Pe;0;ON;;;;;Y;;;;; +298D;LEFT SQUARE BRACKET WITH TICK IN TOP CORNER;Ps;0;ON;;;;;Y;;;;; +298E;RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Pe;0;ON;;;;;Y;;;;; +298F;LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Ps;0;ON;;;;;Y;;;;; +2990;RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER;Pe;0;ON;;;;;Y;;;;; +2991;LEFT ANGLE BRACKET WITH DOT;Ps;0;ON;;;;;Y;;;;; +2992;RIGHT ANGLE BRACKET WITH DOT;Pe;0;ON;;;;;Y;;;;; +2993;LEFT ARC LESS-THAN BRACKET;Ps;0;ON;;;;;Y;;;;; +2994;RIGHT ARC GREATER-THAN BRACKET;Pe;0;ON;;;;;Y;;;;; +2995;DOUBLE LEFT ARC GREATER-THAN BRACKET;Ps;0;ON;;;;;Y;;;;; +2996;DOUBLE RIGHT ARC LESS-THAN BRACKET;Pe;0;ON;;;;;Y;;;;; +2997;LEFT BLACK TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;;;;; +2998;RIGHT BLACK TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;;;;; +2999;DOTTED FENCE;Sm;0;ON;;;;;N;;;;; +299A;VERTICAL ZIGZAG LINE;Sm;0;ON;;;;;N;;;;; +299B;MEASURED ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;; +299C;RIGHT ANGLE VARIANT WITH SQUARE;Sm;0;ON;;;;;Y;;;;; +299D;MEASURED RIGHT ANGLE WITH DOT;Sm;0;ON;;;;;Y;;;;; +299E;ANGLE WITH S INSIDE;Sm;0;ON;;;;;Y;;;;; +299F;ACUTE ANGLE;Sm;0;ON;;;;;Y;;;;; +29A0;SPHERICAL ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;; +29A1;SPHERICAL ANGLE OPENING UP;Sm;0;ON;;;;;N;;;;; +29A2;TURNED ANGLE;Sm;0;ON;;;;;Y;;;;; +29A3;REVERSED ANGLE;Sm;0;ON;;;;;Y;;;;; +29A4;ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +29A5;REVERSED ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +29A6;OBLIQUE ANGLE OPENING UP;Sm;0;ON;;;;;Y;;;;; +29A7;OBLIQUE ANGLE OPENING DOWN;Sm;0;ON;;;;;Y;;;;; +29A8;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT;Sm;0;ON;;;;;Y;;;;; +29A9;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT;Sm;0;ON;;;;;Y;;;;; +29AA;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT;Sm;0;ON;;;;;Y;;;;; +29AB;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT;Sm;0;ON;;;;;Y;;;;; +29AC;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP;Sm;0;ON;;;;;Y;;;;; +29AD;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP;Sm;0;ON;;;;;Y;;;;; +29AE;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN;Sm;0;ON;;;;;Y;;;;; +29AF;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN;Sm;0;ON;;;;;Y;;;;; +29B0;REVERSED EMPTY SET;Sm;0;ON;;;;;N;;;;; +29B1;EMPTY SET WITH OVERBAR;Sm;0;ON;;;;;N;;;;; +29B2;EMPTY SET WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; +29B3;EMPTY SET WITH RIGHT ARROW ABOVE;Sm;0;ON;;;;;N;;;;; +29B4;EMPTY SET WITH LEFT ARROW ABOVE;Sm;0;ON;;;;;N;;;;; +29B5;CIRCLE WITH HORIZONTAL BAR;Sm;0;ON;;;;;N;;;;; +29B6;CIRCLED VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +29B7;CIRCLED PARALLEL;Sm;0;ON;;;;;N;;;;; +29B8;CIRCLED REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;; +29B9;CIRCLED PERPENDICULAR;Sm;0;ON;;;;;N;;;;; +29BA;CIRCLE DIVIDED BY HORIZONTAL BAR AND TOP HALF DIVIDED BY VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +29BB;CIRCLE WITH SUPERIMPOSED X;Sm;0;ON;;;;;N;;;;; +29BC;CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN;Sm;0;ON;;;;;N;;;;; +29BD;UP ARROW THROUGH CIRCLE;Sm;0;ON;;;;;N;;;;; +29BE;CIRCLED WHITE BULLET;Sm;0;ON;;;;;N;;;;; +29BF;CIRCLED BULLET;Sm;0;ON;;;;;N;;;;; +29C0;CIRCLED LESS-THAN;Sm;0;ON;;;;;Y;;;;; +29C1;CIRCLED GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +29C2;CIRCLE WITH SMALL CIRCLE TO THE RIGHT;Sm;0;ON;;;;;Y;;;;; +29C3;CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT;Sm;0;ON;;;;;Y;;;;; +29C4;SQUARED RISING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;; +29C5;SQUARED FALLING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;; +29C6;SQUARED ASTERISK;Sm;0;ON;;;;;N;;;;; +29C7;SQUARED SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +29C8;SQUARED SQUARE;Sm;0;ON;;;;;N;;;;; +29C9;TWO JOINED SQUARES;Sm;0;ON;;;;;Y;;;;; +29CA;TRIANGLE WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +29CB;TRIANGLE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +29CC;S IN TRIANGLE;Sm;0;ON;;;;;N;;;;; +29CD;TRIANGLE WITH SERIFS AT BOTTOM;Sm;0;ON;;;;;N;;;;; +29CE;RIGHT TRIANGLE ABOVE LEFT TRIANGLE;Sm;0;ON;;;;;Y;;;;; +29CF;LEFT TRIANGLE BESIDE VERTICAL BAR;Sm;0;ON;;;;;Y;;;;; +29D0;VERTICAL BAR BESIDE RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;; +29D1;BOWTIE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29D2;BOWTIE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29D3;BLACK BOWTIE;Sm;0;ON;;;;;N;;;;; +29D4;TIMES WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29D5;TIMES WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29D6;WHITE HOURGLASS;Sm;0;ON;;;;;N;;;;; +29D7;BLACK HOURGLASS;Sm;0;ON;;;;;N;;;;; +29D8;LEFT WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;; +29D9;RIGHT WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;; +29DA;LEFT DOUBLE WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;; +29DB;RIGHT DOUBLE WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;; +29DC;INCOMPLETE INFINITY;Sm;0;ON;;;;;Y;;;;; +29DD;TIE OVER INFINITY;Sm;0;ON;;;;;N;;;;; +29DE;INFINITY NEGATED WITH VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +29DF;DOUBLE-ENDED MULTIMAP;Sm;0;ON;;;;;N;;;;; +29E0;SQUARE WITH CONTOURED OUTLINE;Sm;0;ON;;;;;N;;;;; +29E1;INCREASES AS;Sm;0;ON;;;;;Y;;;;; +29E2;SHUFFLE PRODUCT;Sm;0;ON;;;;;N;;;;; +29E3;EQUALS SIGN AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;; +29E4;EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;; +29E5;IDENTICAL TO AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;; +29E6;GLEICH STARK;Sm;0;ON;;;;;N;;;;; +29E7;THERMODYNAMIC;Sm;0;ON;;;;;N;;;;; +29E8;DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29E9;DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;; +29EA;BLACK DIAMOND WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;; +29EB;BLACK LOZENGE;Sm;0;ON;;;;;N;;;;; +29EC;WHITE CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;; +29ED;BLACK CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;; +29EE;ERROR-BARRED WHITE SQUARE;Sm;0;ON;;;;;N;;;;; +29EF;ERROR-BARRED BLACK SQUARE;Sm;0;ON;;;;;N;;;;; +29F0;ERROR-BARRED WHITE DIAMOND;Sm;0;ON;;;;;N;;;;; +29F1;ERROR-BARRED BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; +29F2;ERROR-BARRED WHITE CIRCLE;Sm;0;ON;;;;;N;;;;; +29F3;ERROR-BARRED BLACK CIRCLE;Sm;0;ON;;;;;N;;;;; +29F4;RULE-DELAYED;Sm;0;ON;;;;;Y;;;;; +29F5;REVERSE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;; +29F6;SOLIDUS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +29F7;REVERSE SOLIDUS WITH HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; +29F8;BIG SOLIDUS;Sm;0;ON;;;;;Y;;;;; +29F9;BIG REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;; +29FA;DOUBLE PLUS;Sm;0;ON;;;;;N;;;;; +29FB;TRIPLE PLUS;Sm;0;ON;;;;;N;;;;; +29FC;LEFT-POINTING CURVED ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;; +29FD;RIGHT-POINTING CURVED ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;; +29FE;TINY;Sm;0;ON;;;;;N;;;;; +29FF;MINY;Sm;0;ON;;;;;N;;;;; +2A00;N-ARY CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;; +2A01;N-ARY CIRCLED PLUS OPERATOR;Sm;0;ON;;;;;N;;;;; +2A02;N-ARY CIRCLED TIMES OPERATOR;Sm;0;ON;;;;;N;;;;; +2A03;N-ARY UNION OPERATOR WITH DOT;Sm;0;ON;;;;;N;;;;; +2A04;N-ARY UNION OPERATOR WITH PLUS;Sm;0;ON;;;;;N;;;;; +2A05;N-ARY SQUARE INTERSECTION OPERATOR;Sm;0;ON;;;;;N;;;;; +2A06;N-ARY SQUARE UNION OPERATOR;Sm;0;ON;;;;;N;;;;; +2A07;TWO LOGICAL AND OPERATOR;Sm;0;ON;;;;;N;;;;; +2A08;TWO LOGICAL OR OPERATOR;Sm;0;ON;;;;;N;;;;; +2A09;N-ARY TIMES OPERATOR;Sm;0;ON;;;;;N;;;;; +2A0A;MODULO TWO SUM;Sm;0;ON;;;;;Y;;;;; +2A0B;SUMMATION WITH INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2A0C;QUADRUPLE INTEGRAL OPERATOR;Sm;0;ON; 222B 222B 222B 222B;;;;Y;;;;; +2A0D;FINITE PART INTEGRAL;Sm;0;ON;;;;;Y;;;;; +2A0E;INTEGRAL WITH DOUBLE STROKE;Sm;0;ON;;;;;Y;;;;; +2A0F;INTEGRAL AVERAGE WITH SLASH;Sm;0;ON;;;;;Y;;;;; +2A10;CIRCULATION FUNCTION;Sm;0;ON;;;;;Y;;;;; +2A11;ANTICLOCKWISE INTEGRATION;Sm;0;ON;;;;;Y;;;;; +2A12;LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;; +2A13;LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;; +2A14;LINE INTEGRATION NOT INCLUDING THE POLE;Sm;0;ON;;;;;Y;;;;; +2A15;INTEGRAL AROUND A POINT OPERATOR;Sm;0;ON;;;;;Y;;;;; +2A16;QUATERNION INTEGRAL OPERATOR;Sm;0;ON;;;;;Y;;;;; +2A17;INTEGRAL WITH LEFTWARDS ARROW WITH HOOK;Sm;0;ON;;;;;Y;;;;; +2A18;INTEGRAL WITH TIMES SIGN;Sm;0;ON;;;;;Y;;;;; +2A19;INTEGRAL WITH INTERSECTION;Sm;0;ON;;;;;Y;;;;; +2A1A;INTEGRAL WITH UNION;Sm;0;ON;;;;;Y;;;;; +2A1B;INTEGRAL WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; +2A1C;INTEGRAL WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +2A1D;JOIN;Sm;0;ON;;;;;N;;;;; +2A1E;LARGE LEFT TRIANGLE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2A1F;Z NOTATION SCHEMA COMPOSITION;Sm;0;ON;;;;;Y;;;;; +2A20;Z NOTATION SCHEMA PIPING;Sm;0;ON;;;;;Y;;;;; +2A21;Z NOTATION SCHEMA PROJECTION;Sm;0;ON;;;;;Y;;;;; +2A22;PLUS SIGN WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; +2A23;PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE;Sm;0;ON;;;;;N;;;;; +2A24;PLUS SIGN WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;; +2A25;PLUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;; +2A26;PLUS SIGN WITH TILDE BELOW;Sm;0;ON;;;;;Y;;;;; +2A27;PLUS SIGN WITH SUBSCRIPT TWO;Sm;0;ON;;;;;N;;;;; +2A28;PLUS SIGN WITH BLACK TRIANGLE;Sm;0;ON;;;;;N;;;;; +2A29;MINUS SIGN WITH COMMA ABOVE;Sm;0;ON;;;;;Y;;;;; +2A2A;MINUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;; +2A2B;MINUS SIGN WITH FALLING DOTS;Sm;0;ON;;;;;Y;;;;; +2A2C;MINUS SIGN WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;; +2A2D;PLUS SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; +2A2E;PLUS SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; +2A2F;VECTOR OR CROSS PRODUCT;Sm;0;ON;;;;;N;;;;; +2A30;MULTIPLICATION SIGN WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +2A31;MULTIPLICATION SIGN WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A32;SEMIDIRECT PRODUCT WITH BOTTOM CLOSED;Sm;0;ON;;;;;N;;;;; +2A33;SMASH PRODUCT;Sm;0;ON;;;;;N;;;;; +2A34;MULTIPLICATION SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; +2A35;MULTIPLICATION SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; +2A36;CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;N;;;;; +2A37;MULTIPLICATION SIGN IN DOUBLE CIRCLE;Sm;0;ON;;;;;N;;;;; +2A38;CIRCLED DIVISION SIGN;Sm;0;ON;;;;;N;;;;; +2A39;PLUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;; +2A3A;MINUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;; +2A3B;MULTIPLICATION SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;; +2A3C;INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;; +2A3D;RIGHTHAND INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;; +2A3E;Z NOTATION RELATIONAL COMPOSITION;Sm;0;ON;;;;;Y;;;;; +2A3F;AMALGAMATION OR COPRODUCT;Sm;0;ON;;;;;N;;;;; +2A40;INTERSECTION WITH DOT;Sm;0;ON;;;;;N;;;;; +2A41;UNION WITH MINUS SIGN;Sm;0;ON;;;;;N;;;;; +2A42;UNION WITH OVERBAR;Sm;0;ON;;;;;N;;;;; +2A43;INTERSECTION WITH OVERBAR;Sm;0;ON;;;;;N;;;;; +2A44;INTERSECTION WITH LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2A45;UNION WITH LOGICAL OR;Sm;0;ON;;;;;N;;;;; +2A46;UNION ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;; +2A47;INTERSECTION ABOVE UNION;Sm;0;ON;;;;;N;;;;; +2A48;UNION ABOVE BAR ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;; +2A49;INTERSECTION ABOVE BAR ABOVE UNION;Sm;0;ON;;;;;N;;;;; +2A4A;UNION BESIDE AND JOINED WITH UNION;Sm;0;ON;;;;;N;;;;; +2A4B;INTERSECTION BESIDE AND JOINED WITH INTERSECTION;Sm;0;ON;;;;;N;;;;; +2A4C;CLOSED UNION WITH SERIFS;Sm;0;ON;;;;;N;;;;; +2A4D;CLOSED INTERSECTION WITH SERIFS;Sm;0;ON;;;;;N;;;;; +2A4E;DOUBLE SQUARE INTERSECTION;Sm;0;ON;;;;;N;;;;; +2A4F;DOUBLE SQUARE UNION;Sm;0;ON;;;;;N;;;;; +2A50;CLOSED UNION WITH SERIFS AND SMASH PRODUCT;Sm;0;ON;;;;;N;;;;; +2A51;LOGICAL AND WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +2A52;LOGICAL OR WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +2A53;DOUBLE LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2A54;DOUBLE LOGICAL OR;Sm;0;ON;;;;;N;;;;; +2A55;TWO INTERSECTING LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2A56;TWO INTERSECTING LOGICAL OR;Sm;0;ON;;;;;N;;;;; +2A57;SLOPING LARGE OR;Sm;0;ON;;;;;Y;;;;; +2A58;SLOPING LARGE AND;Sm;0;ON;;;;;Y;;;;; +2A59;LOGICAL OR OVERLAPPING LOGICAL AND;Sm;0;ON;;;;;N;;;;; +2A5A;LOGICAL AND WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;; +2A5B;LOGICAL OR WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;; +2A5C;LOGICAL AND WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;; +2A5D;LOGICAL OR WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;; +2A5E;LOGICAL AND WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;; +2A5F;LOGICAL AND WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A60;LOGICAL AND WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A61;SMALL VEE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A62;LOGICAL OR WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;; +2A63;LOGICAL OR WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;; +2A64;Z NOTATION DOMAIN ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;; +2A65;Z NOTATION RANGE ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;; +2A66;EQUALS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;; +2A67;IDENTICAL WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; +2A68;TRIPLE HORIZONTAL BAR WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2A69;TRIPLE HORIZONTAL BAR WITH TRIPLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2A6A;TILDE OPERATOR WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2A6B;TILDE OPERATOR WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;; +2A6C;SIMILAR MINUS SIMILAR;Sm;0;ON;;;;;Y;;;;; +2A6D;CONGRUENT WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2A6E;EQUALS WITH ASTERISK;Sm;0;ON;;;;;N;;;;; +2A6F;ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;Y;;;;; +2A70;APPROXIMATELY EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A71;EQUALS SIGN ABOVE PLUS SIGN;Sm;0;ON;;;;;N;;;;; +2A72;PLUS SIGN ABOVE EQUALS SIGN;Sm;0;ON;;;;;N;;;;; +2A73;EQUALS SIGN ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2A74;DOUBLE COLON EQUAL;Sm;0;ON; 003A 003A 003D;;;;Y;;;;; +2A75;TWO CONSECUTIVE EQUALS SIGNS;Sm;0;ON; 003D 003D;;;;N;;;;; +2A76;THREE CONSECUTIVE EQUALS SIGNS;Sm;0;ON; 003D 003D 003D;;;;N;;;;; +2A77;EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW;Sm;0;ON;;;;;N;;;;; +2A78;EQUIVALENT WITH FOUR DOTS ABOVE;Sm;0;ON;;;;;N;;;;; +2A79;LESS-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;; +2A7A;GREATER-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;; +2A7B;LESS-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;; +2A7C;GREATER-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;; +2A7D;LESS-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A7E;GREATER-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A7F;LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; +2A80;GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; +2A81;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2A82;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2A83;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT;Sm;0;ON;;;;;Y;;;;; +2A84;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT;Sm;0;ON;;;;;Y;;;;; +2A85;LESS-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;; +2A86;GREATER-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;; +2A87;LESS-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A88;GREATER-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2A89;LESS-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;; +2A8A;GREATER-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;; +2A8B;LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A8C;GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A8D;LESS-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;; +2A8E;GREATER-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;; +2A8F;LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A90;GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A91;LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;; +2A92;GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;; +2A93;LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; +2A94;GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; +2A95;SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A96;SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A97;SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; +2A98;SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; +2A99;DOUBLE-LINE EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A9A;DOUBLE-LINE EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A9B;DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A9C;DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A9D;SIMILAR OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2A9E;SIMILAR OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2A9F;SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AA0;SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AA1;DOUBLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2AA2;DOUBLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2AA3;DOUBLE NESTED LESS-THAN WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; +2AA4;GREATER-THAN OVERLAPPING LESS-THAN;Sm;0;ON;;;;;N;;;;; +2AA5;GREATER-THAN BESIDE LESS-THAN;Sm;0;ON;;;;;N;;;;; +2AA6;LESS-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;; +2AA7;GREATER-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;; +2AA8;LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; +2AA9;GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; +2AAA;SMALLER THAN;Sm;0;ON;;;;;Y;;;;; +2AAB;LARGER THAN;Sm;0;ON;;;;;Y;;;;; +2AAC;SMALLER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AAD;LARGER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AAE;EQUALS SIGN WITH BUMPY ABOVE;Sm;0;ON;;;;;N;;;;; +2AAF;PRECEDES ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AB0;SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AB1;PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB2;SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB3;PRECEDES ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AB4;SUCCEEDS ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AB5;PRECEDES ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB6;SUCCEEDS ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB7;PRECEDES ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB8;SUCCEEDS ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AB9;PRECEDES ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ABA;SUCCEEDS ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ABB;DOUBLE PRECEDES;Sm;0;ON;;;;;Y;;;;; +2ABC;DOUBLE SUCCEEDS;Sm;0;ON;;;;;Y;;;;; +2ABD;SUBSET WITH DOT;Sm;0;ON;;;;;Y;;;;; +2ABE;SUPERSET WITH DOT;Sm;0;ON;;;;;Y;;;;; +2ABF;SUBSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;; +2AC0;SUPERSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;; +2AC1;SUBSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;; +2AC2;SUPERSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;; +2AC3;SUBSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2AC4;SUPERSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; +2AC5;SUBSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AC6;SUPERSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; +2AC7;SUBSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2AC8;SUPERSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2AC9;SUBSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ACA;SUPERSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ACB;SUBSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ACC;SUPERSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2ACD;SQUARE LEFT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;; +2ACE;SQUARE RIGHT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;; +2ACF;CLOSED SUBSET;Sm;0;ON;;;;;Y;;;;; +2AD0;CLOSED SUPERSET;Sm;0;ON;;;;;Y;;;;; +2AD1;CLOSED SUBSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AD2;CLOSED SUPERSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AD3;SUBSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;; +2AD4;SUPERSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;; +2AD5;SUBSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;; +2AD6;SUPERSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;; +2AD7;SUPERSET BESIDE SUBSET;Sm;0;ON;;;;;N;;;;; +2AD8;SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET;Sm;0;ON;;;;;N;;;;; +2AD9;ELEMENT OF OPENING DOWNWARDS;Sm;0;ON;;;;;N;;;;; +2ADA;PITCHFORK WITH TEE TOP;Sm;0;ON;;;;;N;;;;; +2ADB;TRANSVERSAL INTERSECTION;Sm;0;ON;;;;;N;;;;; +2ADC;FORKING;Sm;0;ON;2ADD 0338;;;;Y;;;;; +2ADD;NONFORKING;Sm;0;ON;;;;;N;;;;; +2ADE;SHORT LEFT TACK;Sm;0;ON;;;;;Y;;;;; +2ADF;SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;; +2AE0;SHORT UP TACK;Sm;0;ON;;;;;N;;;;; +2AE1;PERPENDICULAR WITH S;Sm;0;ON;;;;;N;;;;; +2AE2;VERTICAL BAR TRIPLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +2AE3;DOUBLE VERTICAL BAR LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +2AE4;VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +2AE5;DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;; +2AE6;LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL;Sm;0;ON;;;;;Y;;;;; +2AE7;SHORT DOWN TACK WITH OVERBAR;Sm;0;ON;;;;;N;;;;; +2AE8;SHORT UP TACK WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; +2AE9;SHORT UP TACK ABOVE SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;; +2AEA;DOUBLE DOWN TACK;Sm;0;ON;;;;;N;;;;; +2AEB;DOUBLE UP TACK;Sm;0;ON;;;;;N;;;;; +2AEC;DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;; +2AED;REVERSED DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;; +2AEE;DOES NOT DIVIDE WITH REVERSED NEGATION SLASH;Sm;0;ON;;;;;Y;;;;; +2AEF;VERTICAL LINE WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; +2AF0;VERTICAL LINE WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;; +2AF1;DOWN TACK WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;; +2AF2;PARALLEL WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +2AF3;PARALLEL WITH TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; +2AF4;TRIPLE VERTICAL BAR BINARY RELATION;Sm;0;ON;;;;;N;;;;; +2AF5;TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; +2AF6;TRIPLE COLON OPERATOR;Sm;0;ON;;;;;N;;;;; +2AF7;TRIPLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;; +2AF8;TRIPLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;; +2AF9;DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AFA;DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; +2AFB;TRIPLE SOLIDUS BINARY RELATION;Sm;0;ON;;;;;Y;;;;; +2AFC;LARGE TRIPLE VERTICAL BAR OPERATOR;Sm;0;ON;;;;;N;;;;; +2AFD;DOUBLE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;; +2AFE;WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +2AFF;N-ARY WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;; +2B00;NORTH EAST WHITE ARROW;So;0;ON;;;;;N;;;;; +2B01;NORTH WEST WHITE ARROW;So;0;ON;;;;;N;;;;; +2B02;SOUTH EAST WHITE ARROW;So;0;ON;;;;;N;;;;; +2B03;SOUTH WEST WHITE ARROW;So;0;ON;;;;;N;;;;; +2B04;LEFT RIGHT WHITE ARROW;So;0;ON;;;;;N;;;;; +2B05;LEFTWARDS BLACK ARROW;So;0;ON;;;;;N;;;;; +2B06;UPWARDS BLACK ARROW;So;0;ON;;;;;N;;;;; +2B07;DOWNWARDS BLACK ARROW;So;0;ON;;;;;N;;;;; +2B08;NORTH EAST BLACK ARROW;So;0;ON;;;;;N;;;;; +2B09;NORTH WEST BLACK ARROW;So;0;ON;;;;;N;;;;; +2B0A;SOUTH EAST BLACK ARROW;So;0;ON;;;;;N;;;;; +2B0B;SOUTH WEST BLACK ARROW;So;0;ON;;;;;N;;;;; +2B0C;LEFT RIGHT BLACK ARROW;So;0;ON;;;;;N;;;;; +2B0D;UP DOWN BLACK ARROW;So;0;ON;;;;;N;;;;; +2B0E;RIGHTWARDS ARROW WITH TIP DOWNWARDS;So;0;ON;;;;;N;;;;; +2B0F;RIGHTWARDS ARROW WITH TIP UPWARDS;So;0;ON;;;;;N;;;;; +2B10;LEFTWARDS ARROW WITH TIP DOWNWARDS;So;0;ON;;;;;N;;;;; +2B11;LEFTWARDS ARROW WITH TIP UPWARDS;So;0;ON;;;;;N;;;;; +2B12;SQUARE WITH TOP HALF BLACK;So;0;ON;;;;;N;;;;; +2B13;SQUARE WITH BOTTOM HALF BLACK;So;0;ON;;;;;N;;;;; +2B14;SQUARE WITH UPPER RIGHT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;; +2B15;SQUARE WITH LOWER LEFT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;; +2B16;DIAMOND WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;; +2B17;DIAMOND WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;; +2B18;DIAMOND WITH TOP HALF BLACK;So;0;ON;;;;;N;;;;; +2B19;DIAMOND WITH BOTTOM HALF BLACK;So;0;ON;;;;;N;;;;; +2B1A;DOTTED SQUARE;So;0;ON;;;;;N;;;;; +2B1B;BLACK LARGE SQUARE;So;0;ON;;;;;N;;;;; +2B1C;WHITE LARGE SQUARE;So;0;ON;;;;;N;;;;; +2B1D;BLACK VERY SMALL SQUARE;So;0;ON;;;;;N;;;;; +2B1E;WHITE VERY SMALL SQUARE;So;0;ON;;;;;N;;;;; +2B1F;BLACK PENTAGON;So;0;ON;;;;;N;;;;; +2B20;WHITE PENTAGON;So;0;ON;;;;;N;;;;; +2B21;WHITE HEXAGON;So;0;ON;;;;;N;;;;; +2B22;BLACK HEXAGON;So;0;ON;;;;;N;;;;; +2B23;HORIZONTAL BLACK HEXAGON;So;0;ON;;;;;N;;;;; +2B24;BLACK LARGE CIRCLE;So;0;ON;;;;;N;;;;; +2B25;BLACK MEDIUM DIAMOND;So;0;ON;;;;;N;;;;; +2B26;WHITE MEDIUM DIAMOND;So;0;ON;;;;;N;;;;; +2B27;BLACK MEDIUM LOZENGE;So;0;ON;;;;;N;;;;; +2B28;WHITE MEDIUM LOZENGE;So;0;ON;;;;;N;;;;; +2B29;BLACK SMALL DIAMOND;So;0;ON;;;;;N;;;;; +2B2A;BLACK SMALL LOZENGE;So;0;ON;;;;;N;;;;; +2B2B;WHITE SMALL LOZENGE;So;0;ON;;;;;N;;;;; +2B2C;BLACK HORIZONTAL ELLIPSE;So;0;ON;;;;;N;;;;; +2B2D;WHITE HORIZONTAL ELLIPSE;So;0;ON;;;;;N;;;;; +2B2E;BLACK VERTICAL ELLIPSE;So;0;ON;;;;;N;;;;; +2B2F;WHITE VERTICAL ELLIPSE;So;0;ON;;;;;N;;;;; +2B30;LEFT ARROW WITH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; +2B31;THREE LEFTWARDS ARROWS;Sm;0;ON;;;;;N;;;;; +2B32;LEFT ARROW WITH CIRCLED PLUS;Sm;0;ON;;;;;N;;;;; +2B33;LONG LEFTWARDS SQUIGGLE ARROW;Sm;0;ON;;;;;N;;;;; +2B34;LEFTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B35;LEFTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B36;LEFTWARDS TWO-HEADED ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; +2B37;LEFTWARDS TWO-HEADED TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; +2B38;LEFTWARDS ARROW WITH DOTTED STEM;Sm;0;ON;;;;;N;;;;; +2B39;LEFTWARDS ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B3A;LEFTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B3B;LEFTWARDS TWO-HEADED ARROW WITH TAIL;Sm;0;ON;;;;;N;;;;; +2B3C;LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B3D;LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; +2B3E;LEFTWARDS ARROW THROUGH X;Sm;0;ON;;;;;N;;;;; +2B3F;WAVE ARROW POINTING DIRECTLY LEFT;Sm;0;ON;;;;;N;;;;; +2B40;EQUALS SIGN ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2B41;REVERSE TILDE OPERATOR ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2B42;LEFTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;; +2B43;RIGHTWARDS ARROW THROUGH GREATER-THAN;Sm;0;ON;;;;;N;;;;; +2B44;RIGHTWARDS ARROW THROUGH SUPERSET;Sm;0;ON;;;;;N;;;;; +2B45;LEFTWARDS QUADRUPLE ARROW;So;0;ON;;;;;N;;;;; +2B46;RIGHTWARDS QUADRUPLE ARROW;So;0;ON;;;;;N;;;;; +2B47;REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2B48;RIGHTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;; +2B49;TILDE OPERATOR ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; +2B4A;LEFTWARDS ARROW ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;; +2B4B;LEFTWARDS ARROW ABOVE REVERSE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;; +2B4C;RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;; +2B4D;DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW;So;0;ON;;;;;N;;;;; +2B4E;SHORT SLANTED NORTH ARROW;So;0;ON;;;;;N;;;;; +2B4F;SHORT BACKSLANTED SOUTH ARROW;So;0;ON;;;;;N;;;;; +2B50;WHITE MEDIUM STAR;So;0;ON;;;;;N;;;;; +2B51;BLACK SMALL STAR;So;0;ON;;;;;N;;;;; +2B52;WHITE SMALL STAR;So;0;ON;;;;;N;;;;; +2B53;BLACK RIGHT-POINTING PENTAGON;So;0;ON;;;;;N;;;;; +2B54;WHITE RIGHT-POINTING PENTAGON;So;0;ON;;;;;N;;;;; +2B55;HEAVY LARGE CIRCLE;So;0;ON;;;;;N;;;;; +2B56;HEAVY OVAL WITH OVAL INSIDE;So;0;ON;;;;;N;;;;; +2B57;HEAVY CIRCLE WITH CIRCLE INSIDE;So;0;ON;;;;;N;;;;; +2B58;HEAVY CIRCLE;So;0;ON;;;;;N;;;;; +2B59;HEAVY CIRCLED SALTIRE;So;0;ON;;;;;N;;;;; +2B5A;SLANTED NORTH ARROW WITH HOOKED HEAD;So;0;ON;;;;;N;;;;; +2B5B;BACKSLANTED SOUTH ARROW WITH HOOKED TAIL;So;0;ON;;;;;N;;;;; +2B5C;SLANTED NORTH ARROW WITH HORIZONTAL TAIL;So;0;ON;;;;;N;;;;; +2B5D;BACKSLANTED SOUTH ARROW WITH HORIZONTAL TAIL;So;0;ON;;;;;N;;;;; +2B5E;BENT ARROW POINTING DOWNWARDS THEN NORTH EAST;So;0;ON;;;;;N;;;;; +2B5F;SHORT BENT ARROW POINTING DOWNWARDS THEN NORTH EAST;So;0;ON;;;;;N;;;;; +2B60;LEFTWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;; +2B61;UPWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;; +2B62;RIGHTWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;; +2B63;DOWNWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;; +2B64;LEFT RIGHT TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;; +2B65;UP DOWN TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;; +2B66;NORTH WEST TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;; +2B67;NORTH EAST TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;; +2B68;SOUTH EAST TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;; +2B69;SOUTH WEST TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;; +2B6A;LEFTWARDS TRIANGLE-HEADED DASHED ARROW;So;0;ON;;;;;N;;;;; +2B6B;UPWARDS TRIANGLE-HEADED DASHED ARROW;So;0;ON;;;;;N;;;;; +2B6C;RIGHTWARDS TRIANGLE-HEADED DASHED ARROW;So;0;ON;;;;;N;;;;; +2B6D;DOWNWARDS TRIANGLE-HEADED DASHED ARROW;So;0;ON;;;;;N;;;;; +2B6E;CLOCKWISE TRIANGLE-HEADED OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;; +2B6F;ANTICLOCKWISE TRIANGLE-HEADED OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;; +2B70;LEFTWARDS TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;; +2B71;UPWARDS TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;; +2B72;RIGHTWARDS TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;; +2B73;DOWNWARDS TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;; +2B76;NORTH WEST TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;; +2B77;NORTH EAST TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;; +2B78;SOUTH EAST TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;; +2B79;SOUTH WEST TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;; +2B7A;LEFTWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE;So;0;ON;;;;;N;;;;; +2B7B;UPWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE;So;0;ON;;;;;N;;;;; +2B7C;RIGHTWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE;So;0;ON;;;;;N;;;;; +2B7D;DOWNWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE;So;0;ON;;;;;N;;;;; +2B7E;HORIZONTAL TAB KEY;So;0;ON;;;;;N;;;;; +2B7F;VERTICAL TAB KEY;So;0;ON;;;;;N;;;;; +2B80;LEFTWARDS TRIANGLE-HEADED ARROW OVER RIGHTWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;; +2B81;UPWARDS TRIANGLE-HEADED ARROW LEFTWARDS OF DOWNWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;; +2B82;RIGHTWARDS TRIANGLE-HEADED ARROW OVER LEFTWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;; +2B83;DOWNWARDS TRIANGLE-HEADED ARROW LEFTWARDS OF UPWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;; +2B84;LEFTWARDS TRIANGLE-HEADED PAIRED ARROWS;So;0;ON;;;;;N;;;;; +2B85;UPWARDS TRIANGLE-HEADED PAIRED ARROWS;So;0;ON;;;;;N;;;;; +2B86;RIGHTWARDS TRIANGLE-HEADED PAIRED ARROWS;So;0;ON;;;;;N;;;;; +2B87;DOWNWARDS TRIANGLE-HEADED PAIRED ARROWS;So;0;ON;;;;;N;;;;; +2B88;LEFTWARDS BLACK CIRCLED WHITE ARROW;So;0;ON;;;;;N;;;;; +2B89;UPWARDS BLACK CIRCLED WHITE ARROW;So;0;ON;;;;;N;;;;; +2B8A;RIGHTWARDS BLACK CIRCLED WHITE ARROW;So;0;ON;;;;;N;;;;; +2B8B;DOWNWARDS BLACK CIRCLED WHITE ARROW;So;0;ON;;;;;N;;;;; +2B8C;ANTICLOCKWISE TRIANGLE-HEADED RIGHT U-SHAPED ARROW;So;0;ON;;;;;N;;;;; +2B8D;ANTICLOCKWISE TRIANGLE-HEADED BOTTOM U-SHAPED ARROW;So;0;ON;;;;;N;;;;; +2B8E;ANTICLOCKWISE TRIANGLE-HEADED LEFT U-SHAPED ARROW;So;0;ON;;;;;N;;;;; +2B8F;ANTICLOCKWISE TRIANGLE-HEADED TOP U-SHAPED ARROW;So;0;ON;;;;;N;;;;; +2B90;RETURN LEFT;So;0;ON;;;;;N;;;;; +2B91;RETURN RIGHT;So;0;ON;;;;;N;;;;; +2B92;NEWLINE LEFT;So;0;ON;;;;;N;;;;; +2B93;NEWLINE RIGHT;So;0;ON;;;;;N;;;;; +2B94;FOUR CORNER ARROWS CIRCLING ANTICLOCKWISE;So;0;ON;;;;;N;;;;; +2B95;RIGHTWARDS BLACK ARROW;So;0;ON;;;;;N;;;;; +2B98;THREE-D TOP-LIGHTED LEFTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +2B99;THREE-D RIGHT-LIGHTED UPWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +2B9A;THREE-D TOP-LIGHTED RIGHTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +2B9B;THREE-D LEFT-LIGHTED DOWNWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +2B9C;BLACK LEFTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +2B9D;BLACK UPWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +2B9E;BLACK RIGHTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +2B9F;BLACK DOWNWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +2BA0;DOWNWARDS TRIANGLE-HEADED ARROW WITH LONG TIP LEFTWARDS;So;0;ON;;;;;N;;;;; +2BA1;DOWNWARDS TRIANGLE-HEADED ARROW WITH LONG TIP RIGHTWARDS;So;0;ON;;;;;N;;;;; +2BA2;UPWARDS TRIANGLE-HEADED ARROW WITH LONG TIP LEFTWARDS;So;0;ON;;;;;N;;;;; +2BA3;UPWARDS TRIANGLE-HEADED ARROW WITH LONG TIP RIGHTWARDS;So;0;ON;;;;;N;;;;; +2BA4;LEFTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP UPWARDS;So;0;ON;;;;;N;;;;; +2BA5;RIGHTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP UPWARDS;So;0;ON;;;;;N;;;;; +2BA6;LEFTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP DOWNWARDS;So;0;ON;;;;;N;;;;; +2BA7;RIGHTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP DOWNWARDS;So;0;ON;;;;;N;;;;; +2BA8;BLACK CURVED DOWNWARDS AND LEFTWARDS ARROW;So;0;ON;;;;;N;;;;; +2BA9;BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;;;;; +2BAA;BLACK CURVED UPWARDS AND LEFTWARDS ARROW;So;0;ON;;;;;N;;;;; +2BAB;BLACK CURVED UPWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;;;;; +2BAC;BLACK CURVED LEFTWARDS AND UPWARDS ARROW;So;0;ON;;;;;N;;;;; +2BAD;BLACK CURVED RIGHTWARDS AND UPWARDS ARROW;So;0;ON;;;;;N;;;;; +2BAE;BLACK CURVED LEFTWARDS AND DOWNWARDS ARROW;So;0;ON;;;;;N;;;;; +2BAF;BLACK CURVED RIGHTWARDS AND DOWNWARDS ARROW;So;0;ON;;;;;N;;;;; +2BB0;RIBBON ARROW DOWN LEFT;So;0;ON;;;;;N;;;;; +2BB1;RIBBON ARROW DOWN RIGHT;So;0;ON;;;;;N;;;;; +2BB2;RIBBON ARROW UP LEFT;So;0;ON;;;;;N;;;;; +2BB3;RIBBON ARROW UP RIGHT;So;0;ON;;;;;N;;;;; +2BB4;RIBBON ARROW LEFT UP;So;0;ON;;;;;N;;;;; +2BB5;RIBBON ARROW RIGHT UP;So;0;ON;;;;;N;;;;; +2BB6;RIBBON ARROW LEFT DOWN;So;0;ON;;;;;N;;;;; +2BB7;RIBBON ARROW RIGHT DOWN;So;0;ON;;;;;N;;;;; +2BB8;UPWARDS WHITE ARROW FROM BAR WITH HORIZONTAL BAR;So;0;ON;;;;;N;;;;; +2BB9;UP ARROWHEAD IN A RECTANGLE BOX;So;0;ON;;;;;N;;;;; +2BBA;OVERLAPPING WHITE SQUARES;So;0;ON;;;;;N;;;;; +2BBB;OVERLAPPING WHITE AND BLACK SQUARES;So;0;ON;;;;;N;;;;; +2BBC;OVERLAPPING BLACK SQUARES;So;0;ON;;;;;N;;;;; +2BBD;BALLOT BOX WITH LIGHT X;So;0;ON;;;;;N;;;;; +2BBE;CIRCLED X;So;0;ON;;;;;N;;;;; +2BBF;CIRCLED BOLD X;So;0;ON;;;;;N;;;;; +2BC0;BLACK SQUARE CENTRED;So;0;ON;;;;;N;;;;; +2BC1;BLACK DIAMOND CENTRED;So;0;ON;;;;;N;;;;; +2BC2;TURNED BLACK PENTAGON;So;0;ON;;;;;N;;;;; +2BC3;HORIZONTAL BLACK OCTAGON;So;0;ON;;;;;N;;;;; +2BC4;BLACK OCTAGON;So;0;ON;;;;;N;;;;; +2BC5;BLACK MEDIUM UP-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;; +2BC6;BLACK MEDIUM DOWN-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;; +2BC7;BLACK MEDIUM LEFT-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;; +2BC8;BLACK MEDIUM RIGHT-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;; +2BC9;NEPTUNE FORM TWO;So;0;ON;;;;;N;;;;; +2BCA;TOP HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; +2BCB;BOTTOM HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; +2BCC;LIGHT FOUR POINTED BLACK CUSP;So;0;ON;;;;;N;;;;; +2BCD;ROTATED LIGHT FOUR POINTED BLACK CUSP;So;0;ON;;;;;N;;;;; +2BCE;WHITE FOUR POINTED CUSP;So;0;ON;;;;;N;;;;; +2BCF;ROTATED WHITE FOUR POINTED CUSP;So;0;ON;;;;;N;;;;; +2BD0;SQUARE POSITION INDICATOR;So;0;ON;;;;;N;;;;; +2BD1;UNCERTAINTY SIGN;So;0;ON;;;;;N;;;;; +2BD2;GROUP MARK;So;0;ON;;;;;N;;;;; +2BD3;PLUTO FORM TWO;So;0;ON;;;;;N;;;;; +2BD4;PLUTO FORM THREE;So;0;ON;;;;;N;;;;; +2BD5;PLUTO FORM FOUR;So;0;ON;;;;;N;;;;; +2BD6;PLUTO FORM FIVE;So;0;ON;;;;;N;;;;; +2BD7;TRANSPLUTO;So;0;ON;;;;;N;;;;; +2BD8;PROSERPINA;So;0;ON;;;;;N;;;;; +2BD9;ASTRAEA;So;0;ON;;;;;N;;;;; +2BDA;HYGIEA;So;0;ON;;;;;N;;;;; +2BDB;PHOLUS;So;0;ON;;;;;N;;;;; +2BDC;NESSUS;So;0;ON;;;;;N;;;;; +2BDD;WHITE MOON SELENA;So;0;ON;;;;;N;;;;; +2BDE;BLACK DIAMOND ON CROSS;So;0;ON;;;;;N;;;;; +2BDF;TRUE LIGHT MOON ARTA;So;0;ON;;;;;N;;;;; +2BE0;CUPIDO;So;0;ON;;;;;N;;;;; +2BE1;HADES;So;0;ON;;;;;N;;;;; +2BE2;ZEUS;So;0;ON;;;;;N;;;;; +2BE3;KRONOS;So;0;ON;;;;;N;;;;; +2BE4;APOLLON;So;0;ON;;;;;N;;;;; +2BE5;ADMETOS;So;0;ON;;;;;N;;;;; +2BE6;VULCANUS;So;0;ON;;;;;N;;;;; +2BE7;POSEIDON;So;0;ON;;;;;N;;;;; +2BE8;LEFT HALF BLACK STAR;So;0;ON;;;;;N;;;;; +2BE9;RIGHT HALF BLACK STAR;So;0;ON;;;;;N;;;;; +2BEA;STAR WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;; +2BEB;STAR WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;; +2BEC;LEFTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;; +2BED;UPWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;; +2BEE;RIGHTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;; +2BEF;DOWNWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;; +2BF0;ERIS FORM ONE;So;0;ON;;;;;N;;;;; +2BF1;ERIS FORM TWO;So;0;ON;;;;;N;;;;; +2BF2;SEDNA;So;0;ON;;;;;N;;;;; +2BF3;RUSSIAN ASTROLOGICAL SYMBOL VIGINTILE;So;0;ON;;;;;N;;;;; +2BF4;RUSSIAN ASTROLOGICAL SYMBOL NOVILE;So;0;ON;;;;;N;;;;; +2BF5;RUSSIAN ASTROLOGICAL SYMBOL QUINTILE;So;0;ON;;;;;N;;;;; +2BF6;RUSSIAN ASTROLOGICAL SYMBOL BINOVILE;So;0;ON;;;;;N;;;;; +2BF7;RUSSIAN ASTROLOGICAL SYMBOL SENTAGON;So;0;ON;;;;;N;;;;; +2BF8;RUSSIAN ASTROLOGICAL SYMBOL TREDECILE;So;0;ON;;;;;N;;;;; +2BF9;EQUALS SIGN WITH INFINITY BELOW;So;0;ON;;;;;N;;;;; +2BFA;UNITED SYMBOL;So;0;ON;;;;;N;;;;; +2BFB;SEPARATED SYMBOL;So;0;ON;;;;;N;;;;; +2BFC;DOUBLED SYMBOL;So;0;ON;;;;;N;;;;; +2BFD;PASSED SYMBOL;So;0;ON;;;;;N;;;;; +2BFE;REVERSED RIGHT ANGLE;So;0;ON;;;;;Y;;;;; +2BFF;HELLSCHREIBER PAUSE SYMBOL;So;0;ON;;;;;N;;;;; +2C00;GLAGOLITIC CAPITAL LETTER AZU;Lu;0;L;;;;;N;;;;2C30; +2C01;GLAGOLITIC CAPITAL LETTER BUKY;Lu;0;L;;;;;N;;;;2C31; +2C02;GLAGOLITIC CAPITAL LETTER VEDE;Lu;0;L;;;;;N;;;;2C32; +2C03;GLAGOLITIC CAPITAL LETTER GLAGOLI;Lu;0;L;;;;;N;;;;2C33; +2C04;GLAGOLITIC CAPITAL LETTER DOBRO;Lu;0;L;;;;;N;;;;2C34; +2C05;GLAGOLITIC CAPITAL LETTER YESTU;Lu;0;L;;;;;N;;;;2C35; +2C06;GLAGOLITIC CAPITAL LETTER ZHIVETE;Lu;0;L;;;;;N;;;;2C36; +2C07;GLAGOLITIC CAPITAL LETTER DZELO;Lu;0;L;;;;;N;;;;2C37; +2C08;GLAGOLITIC CAPITAL LETTER ZEMLJA;Lu;0;L;;;;;N;;;;2C38; +2C09;GLAGOLITIC CAPITAL LETTER IZHE;Lu;0;L;;;;;N;;;;2C39; +2C0A;GLAGOLITIC CAPITAL LETTER INITIAL IZHE;Lu;0;L;;;;;N;;;;2C3A; +2C0B;GLAGOLITIC CAPITAL LETTER I;Lu;0;L;;;;;N;;;;2C3B; +2C0C;GLAGOLITIC CAPITAL LETTER DJERVI;Lu;0;L;;;;;N;;;;2C3C; +2C0D;GLAGOLITIC CAPITAL LETTER KAKO;Lu;0;L;;;;;N;;;;2C3D; +2C0E;GLAGOLITIC CAPITAL LETTER LJUDIJE;Lu;0;L;;;;;N;;;;2C3E; +2C0F;GLAGOLITIC CAPITAL LETTER MYSLITE;Lu;0;L;;;;;N;;;;2C3F; +2C10;GLAGOLITIC CAPITAL LETTER NASHI;Lu;0;L;;;;;N;;;;2C40; +2C11;GLAGOLITIC CAPITAL LETTER ONU;Lu;0;L;;;;;N;;;;2C41; +2C12;GLAGOLITIC CAPITAL LETTER POKOJI;Lu;0;L;;;;;N;;;;2C42; +2C13;GLAGOLITIC CAPITAL LETTER RITSI;Lu;0;L;;;;;N;;;;2C43; +2C14;GLAGOLITIC CAPITAL LETTER SLOVO;Lu;0;L;;;;;N;;;;2C44; +2C15;GLAGOLITIC CAPITAL LETTER TVRIDO;Lu;0;L;;;;;N;;;;2C45; +2C16;GLAGOLITIC CAPITAL LETTER UKU;Lu;0;L;;;;;N;;;;2C46; +2C17;GLAGOLITIC CAPITAL LETTER FRITU;Lu;0;L;;;;;N;;;;2C47; +2C18;GLAGOLITIC CAPITAL LETTER HERU;Lu;0;L;;;;;N;;;;2C48; +2C19;GLAGOLITIC CAPITAL LETTER OTU;Lu;0;L;;;;;N;;;;2C49; +2C1A;GLAGOLITIC CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;2C4A; +2C1B;GLAGOLITIC CAPITAL LETTER SHTA;Lu;0;L;;;;;N;;;;2C4B; +2C1C;GLAGOLITIC CAPITAL LETTER TSI;Lu;0;L;;;;;N;;;;2C4C; +2C1D;GLAGOLITIC CAPITAL LETTER CHRIVI;Lu;0;L;;;;;N;;;;2C4D; +2C1E;GLAGOLITIC CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;2C4E; +2C1F;GLAGOLITIC CAPITAL LETTER YERU;Lu;0;L;;;;;N;;;;2C4F; +2C20;GLAGOLITIC CAPITAL LETTER YERI;Lu;0;L;;;;;N;;;;2C50; +2C21;GLAGOLITIC CAPITAL LETTER YATI;Lu;0;L;;;;;N;;;;2C51; +2C22;GLAGOLITIC CAPITAL LETTER SPIDERY HA;Lu;0;L;;;;;N;;;;2C52; +2C23;GLAGOLITIC CAPITAL LETTER YU;Lu;0;L;;;;;N;;;;2C53; +2C24;GLAGOLITIC CAPITAL LETTER SMALL YUS;Lu;0;L;;;;;N;;;;2C54; +2C25;GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL;Lu;0;L;;;;;N;;;;2C55; +2C26;GLAGOLITIC CAPITAL LETTER YO;Lu;0;L;;;;;N;;;;2C56; +2C27;GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS;Lu;0;L;;;;;N;;;;2C57; +2C28;GLAGOLITIC CAPITAL LETTER BIG YUS;Lu;0;L;;;;;N;;;;2C58; +2C29;GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS;Lu;0;L;;;;;N;;;;2C59; +2C2A;GLAGOLITIC CAPITAL LETTER FITA;Lu;0;L;;;;;N;;;;2C5A; +2C2B;GLAGOLITIC CAPITAL LETTER IZHITSA;Lu;0;L;;;;;N;;;;2C5B; +2C2C;GLAGOLITIC CAPITAL LETTER SHTAPIC;Lu;0;L;;;;;N;;;;2C5C; +2C2D;GLAGOLITIC CAPITAL LETTER TROKUTASTI A;Lu;0;L;;;;;N;;;;2C5D; +2C2E;GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE;Lu;0;L;;;;;N;;;;2C5E; +2C30;GLAGOLITIC SMALL LETTER AZU;Ll;0;L;;;;;N;;;2C00;;2C00 +2C31;GLAGOLITIC SMALL LETTER BUKY;Ll;0;L;;;;;N;;;2C01;;2C01 +2C32;GLAGOLITIC SMALL LETTER VEDE;Ll;0;L;;;;;N;;;2C02;;2C02 +2C33;GLAGOLITIC SMALL LETTER GLAGOLI;Ll;0;L;;;;;N;;;2C03;;2C03 +2C34;GLAGOLITIC SMALL LETTER DOBRO;Ll;0;L;;;;;N;;;2C04;;2C04 +2C35;GLAGOLITIC SMALL LETTER YESTU;Ll;0;L;;;;;N;;;2C05;;2C05 +2C36;GLAGOLITIC SMALL LETTER ZHIVETE;Ll;0;L;;;;;N;;;2C06;;2C06 +2C37;GLAGOLITIC SMALL LETTER DZELO;Ll;0;L;;;;;N;;;2C07;;2C07 +2C38;GLAGOLITIC SMALL LETTER ZEMLJA;Ll;0;L;;;;;N;;;2C08;;2C08 +2C39;GLAGOLITIC SMALL LETTER IZHE;Ll;0;L;;;;;N;;;2C09;;2C09 +2C3A;GLAGOLITIC SMALL LETTER INITIAL IZHE;Ll;0;L;;;;;N;;;2C0A;;2C0A +2C3B;GLAGOLITIC SMALL LETTER I;Ll;0;L;;;;;N;;;2C0B;;2C0B +2C3C;GLAGOLITIC SMALL LETTER DJERVI;Ll;0;L;;;;;N;;;2C0C;;2C0C +2C3D;GLAGOLITIC SMALL LETTER KAKO;Ll;0;L;;;;;N;;;2C0D;;2C0D +2C3E;GLAGOLITIC SMALL LETTER LJUDIJE;Ll;0;L;;;;;N;;;2C0E;;2C0E +2C3F;GLAGOLITIC SMALL LETTER MYSLITE;Ll;0;L;;;;;N;;;2C0F;;2C0F +2C40;GLAGOLITIC SMALL LETTER NASHI;Ll;0;L;;;;;N;;;2C10;;2C10 +2C41;GLAGOLITIC SMALL LETTER ONU;Ll;0;L;;;;;N;;;2C11;;2C11 +2C42;GLAGOLITIC SMALL LETTER POKOJI;Ll;0;L;;;;;N;;;2C12;;2C12 +2C43;GLAGOLITIC SMALL LETTER RITSI;Ll;0;L;;;;;N;;;2C13;;2C13 +2C44;GLAGOLITIC SMALL LETTER SLOVO;Ll;0;L;;;;;N;;;2C14;;2C14 +2C45;GLAGOLITIC SMALL LETTER TVRIDO;Ll;0;L;;;;;N;;;2C15;;2C15 +2C46;GLAGOLITIC SMALL LETTER UKU;Ll;0;L;;;;;N;;;2C16;;2C16 +2C47;GLAGOLITIC SMALL LETTER FRITU;Ll;0;L;;;;;N;;;2C17;;2C17 +2C48;GLAGOLITIC SMALL LETTER HERU;Ll;0;L;;;;;N;;;2C18;;2C18 +2C49;GLAGOLITIC SMALL LETTER OTU;Ll;0;L;;;;;N;;;2C19;;2C19 +2C4A;GLAGOLITIC SMALL LETTER PE;Ll;0;L;;;;;N;;;2C1A;;2C1A +2C4B;GLAGOLITIC SMALL LETTER SHTA;Ll;0;L;;;;;N;;;2C1B;;2C1B +2C4C;GLAGOLITIC SMALL LETTER TSI;Ll;0;L;;;;;N;;;2C1C;;2C1C +2C4D;GLAGOLITIC SMALL LETTER CHRIVI;Ll;0;L;;;;;N;;;2C1D;;2C1D +2C4E;GLAGOLITIC SMALL LETTER SHA;Ll;0;L;;;;;N;;;2C1E;;2C1E +2C4F;GLAGOLITIC SMALL LETTER YERU;Ll;0;L;;;;;N;;;2C1F;;2C1F +2C50;GLAGOLITIC SMALL LETTER YERI;Ll;0;L;;;;;N;;;2C20;;2C20 +2C51;GLAGOLITIC SMALL LETTER YATI;Ll;0;L;;;;;N;;;2C21;;2C21 +2C52;GLAGOLITIC SMALL LETTER SPIDERY HA;Ll;0;L;;;;;N;;;2C22;;2C22 +2C53;GLAGOLITIC SMALL LETTER YU;Ll;0;L;;;;;N;;;2C23;;2C23 +2C54;GLAGOLITIC SMALL LETTER SMALL YUS;Ll;0;L;;;;;N;;;2C24;;2C24 +2C55;GLAGOLITIC SMALL LETTER SMALL YUS WITH TAIL;Ll;0;L;;;;;N;;;2C25;;2C25 +2C56;GLAGOLITIC SMALL LETTER YO;Ll;0;L;;;;;N;;;2C26;;2C26 +2C57;GLAGOLITIC SMALL LETTER IOTATED SMALL YUS;Ll;0;L;;;;;N;;;2C27;;2C27 +2C58;GLAGOLITIC SMALL LETTER BIG YUS;Ll;0;L;;;;;N;;;2C28;;2C28 +2C59;GLAGOLITIC SMALL LETTER IOTATED BIG YUS;Ll;0;L;;;;;N;;;2C29;;2C29 +2C5A;GLAGOLITIC SMALL LETTER FITA;Ll;0;L;;;;;N;;;2C2A;;2C2A +2C5B;GLAGOLITIC SMALL LETTER IZHITSA;Ll;0;L;;;;;N;;;2C2B;;2C2B +2C5C;GLAGOLITIC SMALL LETTER SHTAPIC;Ll;0;L;;;;;N;;;2C2C;;2C2C +2C5D;GLAGOLITIC SMALL LETTER TROKUTASTI A;Ll;0;L;;;;;N;;;2C2D;;2C2D +2C5E;GLAGOLITIC SMALL LETTER LATINATE MYSLITE;Ll;0;L;;;;;N;;;2C2E;;2C2E +2C60;LATIN CAPITAL LETTER L WITH DOUBLE BAR;Lu;0;L;;;;;N;;;;2C61; +2C61;LATIN SMALL LETTER L WITH DOUBLE BAR;Ll;0;L;;;;;N;;;2C60;;2C60 +2C62;LATIN CAPITAL LETTER L WITH MIDDLE TILDE;Lu;0;L;;;;;N;;;;026B; +2C63;LATIN CAPITAL LETTER P WITH STROKE;Lu;0;L;;;;;N;;;;1D7D; +2C64;LATIN CAPITAL LETTER R WITH TAIL;Lu;0;L;;;;;N;;;;027D; +2C65;LATIN SMALL LETTER A WITH STROKE;Ll;0;L;;;;;N;;;023A;;023A +2C66;LATIN SMALL LETTER T WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;023E;;023E +2C67;LATIN CAPITAL LETTER H WITH DESCENDER;Lu;0;L;;;;;N;;;;2C68; +2C68;LATIN SMALL LETTER H WITH DESCENDER;Ll;0;L;;;;;N;;;2C67;;2C67 +2C69;LATIN CAPITAL LETTER K WITH DESCENDER;Lu;0;L;;;;;N;;;;2C6A; +2C6A;LATIN SMALL LETTER K WITH DESCENDER;Ll;0;L;;;;;N;;;2C69;;2C69 +2C6B;LATIN CAPITAL LETTER Z WITH DESCENDER;Lu;0;L;;;;;N;;;;2C6C; +2C6C;LATIN SMALL LETTER Z WITH DESCENDER;Ll;0;L;;;;;N;;;2C6B;;2C6B +2C6D;LATIN CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;0251; +2C6E;LATIN CAPITAL LETTER M WITH HOOK;Lu;0;L;;;;;N;;;;0271; +2C6F;LATIN CAPITAL LETTER TURNED A;Lu;0;L;;;;;N;;;;0250; +2C70;LATIN CAPITAL LETTER TURNED ALPHA;Lu;0;L;;;;;N;;;;0252; +2C71;LATIN SMALL LETTER V WITH RIGHT HOOK;Ll;0;L;;;;;N;;;;; +2C72;LATIN CAPITAL LETTER W WITH HOOK;Lu;0;L;;;;;N;;;;2C73; +2C73;LATIN SMALL LETTER W WITH HOOK;Ll;0;L;;;;;N;;;2C72;;2C72 +2C74;LATIN SMALL LETTER V WITH CURL;Ll;0;L;;;;;N;;;;; +2C75;LATIN CAPITAL LETTER HALF H;Lu;0;L;;;;;N;;;;2C76; +2C76;LATIN SMALL LETTER HALF H;Ll;0;L;;;;;N;;;2C75;;2C75 +2C77;LATIN SMALL LETTER TAILLESS PHI;Ll;0;L;;;;;N;;;;; +2C78;LATIN SMALL LETTER E WITH NOTCH;Ll;0;L;;;;;N;;;;; +2C79;LATIN SMALL LETTER TURNED R WITH TAIL;Ll;0;L;;;;;N;;;;; +2C7A;LATIN SMALL LETTER O WITH LOW RING INSIDE;Ll;0;L;;;;;N;;;;; +2C7B;LATIN LETTER SMALL CAPITAL TURNED E;Ll;0;L;;;;;N;;;;; +2C7C;LATIN SUBSCRIPT SMALL LETTER J;Lm;0;L; 006A;;;;N;;;;; +2C7D;MODIFIER LETTER CAPITAL V;Lm;0;L; 0056;;;;N;;;;; +2C7E;LATIN CAPITAL LETTER S WITH SWASH TAIL;Lu;0;L;;;;;N;;;;023F; +2C7F;LATIN CAPITAL LETTER Z WITH SWASH TAIL;Lu;0;L;;;;;N;;;;0240; +2C80;COPTIC CAPITAL LETTER ALFA;Lu;0;L;;;;;N;;;;2C81; +2C81;COPTIC SMALL LETTER ALFA;Ll;0;L;;;;;N;;;2C80;;2C80 +2C82;COPTIC CAPITAL LETTER VIDA;Lu;0;L;;;;;N;;;;2C83; +2C83;COPTIC SMALL LETTER VIDA;Ll;0;L;;;;;N;;;2C82;;2C82 +2C84;COPTIC CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;2C85; +2C85;COPTIC SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;2C84;;2C84 +2C86;COPTIC CAPITAL LETTER DALDA;Lu;0;L;;;;;N;;;;2C87; +2C87;COPTIC SMALL LETTER DALDA;Ll;0;L;;;;;N;;;2C86;;2C86 +2C88;COPTIC CAPITAL LETTER EIE;Lu;0;L;;;;;N;;;;2C89; +2C89;COPTIC SMALL LETTER EIE;Ll;0;L;;;;;N;;;2C88;;2C88 +2C8A;COPTIC CAPITAL LETTER SOU;Lu;0;L;;;;;N;;;;2C8B; +2C8B;COPTIC SMALL LETTER SOU;Ll;0;L;;;;;N;;;2C8A;;2C8A +2C8C;COPTIC CAPITAL LETTER ZATA;Lu;0;L;;;;;N;;;;2C8D; +2C8D;COPTIC SMALL LETTER ZATA;Ll;0;L;;;;;N;;;2C8C;;2C8C +2C8E;COPTIC CAPITAL LETTER HATE;Lu;0;L;;;;;N;;;;2C8F; +2C8F;COPTIC SMALL LETTER HATE;Ll;0;L;;;;;N;;;2C8E;;2C8E +2C90;COPTIC CAPITAL LETTER THETHE;Lu;0;L;;;;;N;;;;2C91; +2C91;COPTIC SMALL LETTER THETHE;Ll;0;L;;;;;N;;;2C90;;2C90 +2C92;COPTIC CAPITAL LETTER IAUDA;Lu;0;L;;;;;N;;;;2C93; +2C93;COPTIC SMALL LETTER IAUDA;Ll;0;L;;;;;N;;;2C92;;2C92 +2C94;COPTIC CAPITAL LETTER KAPA;Lu;0;L;;;;;N;;;;2C95; +2C95;COPTIC SMALL LETTER KAPA;Ll;0;L;;;;;N;;;2C94;;2C94 +2C96;COPTIC CAPITAL LETTER LAULA;Lu;0;L;;;;;N;;;;2C97; +2C97;COPTIC SMALL LETTER LAULA;Ll;0;L;;;;;N;;;2C96;;2C96 +2C98;COPTIC CAPITAL LETTER MI;Lu;0;L;;;;;N;;;;2C99; +2C99;COPTIC SMALL LETTER MI;Ll;0;L;;;;;N;;;2C98;;2C98 +2C9A;COPTIC CAPITAL LETTER NI;Lu;0;L;;;;;N;;;;2C9B; +2C9B;COPTIC SMALL LETTER NI;Ll;0;L;;;;;N;;;2C9A;;2C9A +2C9C;COPTIC CAPITAL LETTER KSI;Lu;0;L;;;;;N;;;;2C9D; +2C9D;COPTIC SMALL LETTER KSI;Ll;0;L;;;;;N;;;2C9C;;2C9C +2C9E;COPTIC CAPITAL LETTER O;Lu;0;L;;;;;N;;;;2C9F; +2C9F;COPTIC SMALL LETTER O;Ll;0;L;;;;;N;;;2C9E;;2C9E +2CA0;COPTIC CAPITAL LETTER PI;Lu;0;L;;;;;N;;;;2CA1; +2CA1;COPTIC SMALL LETTER PI;Ll;0;L;;;;;N;;;2CA0;;2CA0 +2CA2;COPTIC CAPITAL LETTER RO;Lu;0;L;;;;;N;;;;2CA3; +2CA3;COPTIC SMALL LETTER RO;Ll;0;L;;;;;N;;;2CA2;;2CA2 +2CA4;COPTIC CAPITAL LETTER SIMA;Lu;0;L;;;;;N;;;;2CA5; +2CA5;COPTIC SMALL LETTER SIMA;Ll;0;L;;;;;N;;;2CA4;;2CA4 +2CA6;COPTIC CAPITAL LETTER TAU;Lu;0;L;;;;;N;;;;2CA7; +2CA7;COPTIC SMALL LETTER TAU;Ll;0;L;;;;;N;;;2CA6;;2CA6 +2CA8;COPTIC CAPITAL LETTER UA;Lu;0;L;;;;;N;;;;2CA9; +2CA9;COPTIC SMALL LETTER UA;Ll;0;L;;;;;N;;;2CA8;;2CA8 +2CAA;COPTIC CAPITAL LETTER FI;Lu;0;L;;;;;N;;;;2CAB; +2CAB;COPTIC SMALL LETTER FI;Ll;0;L;;;;;N;;;2CAA;;2CAA +2CAC;COPTIC CAPITAL LETTER KHI;Lu;0;L;;;;;N;;;;2CAD; +2CAD;COPTIC SMALL LETTER KHI;Ll;0;L;;;;;N;;;2CAC;;2CAC +2CAE;COPTIC CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;2CAF; +2CAF;COPTIC SMALL LETTER PSI;Ll;0;L;;;;;N;;;2CAE;;2CAE +2CB0;COPTIC CAPITAL LETTER OOU;Lu;0;L;;;;;N;;;;2CB1; +2CB1;COPTIC SMALL LETTER OOU;Ll;0;L;;;;;N;;;2CB0;;2CB0 +2CB2;COPTIC CAPITAL LETTER DIALECT-P ALEF;Lu;0;L;;;;;N;;;;2CB3; +2CB3;COPTIC SMALL LETTER DIALECT-P ALEF;Ll;0;L;;;;;N;;;2CB2;;2CB2 +2CB4;COPTIC CAPITAL LETTER OLD COPTIC AIN;Lu;0;L;;;;;N;;;;2CB5; +2CB5;COPTIC SMALL LETTER OLD COPTIC AIN;Ll;0;L;;;;;N;;;2CB4;;2CB4 +2CB6;COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE;Lu;0;L;;;;;N;;;;2CB7; +2CB7;COPTIC SMALL LETTER CRYPTOGRAMMIC EIE;Ll;0;L;;;;;N;;;2CB6;;2CB6 +2CB8;COPTIC CAPITAL LETTER DIALECT-P KAPA;Lu;0;L;;;;;N;;;;2CB9; +2CB9;COPTIC SMALL LETTER DIALECT-P KAPA;Ll;0;L;;;;;N;;;2CB8;;2CB8 +2CBA;COPTIC CAPITAL LETTER DIALECT-P NI;Lu;0;L;;;;;N;;;;2CBB; +2CBB;COPTIC SMALL LETTER DIALECT-P NI;Ll;0;L;;;;;N;;;2CBA;;2CBA +2CBC;COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI;Lu;0;L;;;;;N;;;;2CBD; +2CBD;COPTIC SMALL LETTER CRYPTOGRAMMIC NI;Ll;0;L;;;;;N;;;2CBC;;2CBC +2CBE;COPTIC CAPITAL LETTER OLD COPTIC OOU;Lu;0;L;;;;;N;;;;2CBF; +2CBF;COPTIC SMALL LETTER OLD COPTIC OOU;Ll;0;L;;;;;N;;;2CBE;;2CBE +2CC0;COPTIC CAPITAL LETTER SAMPI;Lu;0;L;;;;;N;;;;2CC1; +2CC1;COPTIC SMALL LETTER SAMPI;Ll;0;L;;;;;N;;;2CC0;;2CC0 +2CC2;COPTIC CAPITAL LETTER CROSSED SHEI;Lu;0;L;;;;;N;;;;2CC3; +2CC3;COPTIC SMALL LETTER CROSSED SHEI;Ll;0;L;;;;;N;;;2CC2;;2CC2 +2CC4;COPTIC CAPITAL LETTER OLD COPTIC SHEI;Lu;0;L;;;;;N;;;;2CC5; +2CC5;COPTIC SMALL LETTER OLD COPTIC SHEI;Ll;0;L;;;;;N;;;2CC4;;2CC4 +2CC6;COPTIC CAPITAL LETTER OLD COPTIC ESH;Lu;0;L;;;;;N;;;;2CC7; +2CC7;COPTIC SMALL LETTER OLD COPTIC ESH;Ll;0;L;;;;;N;;;2CC6;;2CC6 +2CC8;COPTIC CAPITAL LETTER AKHMIMIC KHEI;Lu;0;L;;;;;N;;;;2CC9; +2CC9;COPTIC SMALL LETTER AKHMIMIC KHEI;Ll;0;L;;;;;N;;;2CC8;;2CC8 +2CCA;COPTIC CAPITAL LETTER DIALECT-P HORI;Lu;0;L;;;;;N;;;;2CCB; +2CCB;COPTIC SMALL LETTER DIALECT-P HORI;Ll;0;L;;;;;N;;;2CCA;;2CCA +2CCC;COPTIC CAPITAL LETTER OLD COPTIC HORI;Lu;0;L;;;;;N;;;;2CCD; +2CCD;COPTIC SMALL LETTER OLD COPTIC HORI;Ll;0;L;;;;;N;;;2CCC;;2CCC +2CCE;COPTIC CAPITAL LETTER OLD COPTIC HA;Lu;0;L;;;;;N;;;;2CCF; +2CCF;COPTIC SMALL LETTER OLD COPTIC HA;Ll;0;L;;;;;N;;;2CCE;;2CCE +2CD0;COPTIC CAPITAL LETTER L-SHAPED HA;Lu;0;L;;;;;N;;;;2CD1; +2CD1;COPTIC SMALL LETTER L-SHAPED HA;Ll;0;L;;;;;N;;;2CD0;;2CD0 +2CD2;COPTIC CAPITAL LETTER OLD COPTIC HEI;Lu;0;L;;;;;N;;;;2CD3; +2CD3;COPTIC SMALL LETTER OLD COPTIC HEI;Ll;0;L;;;;;N;;;2CD2;;2CD2 +2CD4;COPTIC CAPITAL LETTER OLD COPTIC HAT;Lu;0;L;;;;;N;;;;2CD5; +2CD5;COPTIC SMALL LETTER OLD COPTIC HAT;Ll;0;L;;;;;N;;;2CD4;;2CD4 +2CD6;COPTIC CAPITAL LETTER OLD COPTIC GANGIA;Lu;0;L;;;;;N;;;;2CD7; +2CD7;COPTIC SMALL LETTER OLD COPTIC GANGIA;Ll;0;L;;;;;N;;;2CD6;;2CD6 +2CD8;COPTIC CAPITAL LETTER OLD COPTIC DJA;Lu;0;L;;;;;N;;;;2CD9; +2CD9;COPTIC SMALL LETTER OLD COPTIC DJA;Ll;0;L;;;;;N;;;2CD8;;2CD8 +2CDA;COPTIC CAPITAL LETTER OLD COPTIC SHIMA;Lu;0;L;;;;;N;;;;2CDB; +2CDB;COPTIC SMALL LETTER OLD COPTIC SHIMA;Ll;0;L;;;;;N;;;2CDA;;2CDA +2CDC;COPTIC CAPITAL LETTER OLD NUBIAN SHIMA;Lu;0;L;;;;;N;;;;2CDD; +2CDD;COPTIC SMALL LETTER OLD NUBIAN SHIMA;Ll;0;L;;;;;N;;;2CDC;;2CDC +2CDE;COPTIC CAPITAL LETTER OLD NUBIAN NGI;Lu;0;L;;;;;N;;;;2CDF; +2CDF;COPTIC SMALL LETTER OLD NUBIAN NGI;Ll;0;L;;;;;N;;;2CDE;;2CDE +2CE0;COPTIC CAPITAL LETTER OLD NUBIAN NYI;Lu;0;L;;;;;N;;;;2CE1; +2CE1;COPTIC SMALL LETTER OLD NUBIAN NYI;Ll;0;L;;;;;N;;;2CE0;;2CE0 +2CE2;COPTIC CAPITAL LETTER OLD NUBIAN WAU;Lu;0;L;;;;;N;;;;2CE3; +2CE3;COPTIC SMALL LETTER OLD NUBIAN WAU;Ll;0;L;;;;;N;;;2CE2;;2CE2 +2CE4;COPTIC SYMBOL KAI;Ll;0;L;;;;;N;;;;; +2CE5;COPTIC SYMBOL MI RO;So;0;ON;;;;;N;;;;; +2CE6;COPTIC SYMBOL PI RO;So;0;ON;;;;;N;;;;; +2CE7;COPTIC SYMBOL STAUROS;So;0;ON;;;;;N;;;;; +2CE8;COPTIC SYMBOL TAU RO;So;0;ON;;;;;N;;;;; +2CE9;COPTIC SYMBOL KHI RO;So;0;ON;;;;;N;;;;; +2CEA;COPTIC SYMBOL SHIMA SIMA;So;0;ON;;;;;N;;;;; +2CEB;COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI;Lu;0;L;;;;;N;;;;2CEC; +2CEC;COPTIC SMALL LETTER CRYPTOGRAMMIC SHEI;Ll;0;L;;;;;N;;;2CEB;;2CEB +2CED;COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA;Lu;0;L;;;;;N;;;;2CEE; +2CEE;COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA;Ll;0;L;;;;;N;;;2CED;;2CED +2CEF;COPTIC COMBINING NI ABOVE;Mn;230;NSM;;;;;N;;;;; +2CF0;COPTIC COMBINING SPIRITUS ASPER;Mn;230;NSM;;;;;N;;;;; +2CF1;COPTIC COMBINING SPIRITUS LENIS;Mn;230;NSM;;;;;N;;;;; +2CF2;COPTIC CAPITAL LETTER BOHAIRIC KHEI;Lu;0;L;;;;;N;;;;2CF3; +2CF3;COPTIC SMALL LETTER BOHAIRIC KHEI;Ll;0;L;;;;;N;;;2CF2;;2CF2 +2CF9;COPTIC OLD NUBIAN FULL STOP;Po;0;ON;;;;;N;;;;; +2CFA;COPTIC OLD NUBIAN DIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;; +2CFB;COPTIC OLD NUBIAN INDIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;; +2CFC;COPTIC OLD NUBIAN VERSE DIVIDER;Po;0;ON;;;;;N;;;;; +2CFD;COPTIC FRACTION ONE HALF;No;0;ON;;;;1/2;N;;;;; +2CFE;COPTIC FULL STOP;Po;0;ON;;;;;N;;;;; +2CFF;COPTIC MORPHOLOGICAL DIVIDER;Po;0;ON;;;;;N;;;;; +2D00;GEORGIAN SMALL LETTER AN;Ll;0;L;;;;;N;;;10A0;;10A0 +2D01;GEORGIAN SMALL LETTER BAN;Ll;0;L;;;;;N;;;10A1;;10A1 +2D02;GEORGIAN SMALL LETTER GAN;Ll;0;L;;;;;N;;;10A2;;10A2 +2D03;GEORGIAN SMALL LETTER DON;Ll;0;L;;;;;N;;;10A3;;10A3 +2D04;GEORGIAN SMALL LETTER EN;Ll;0;L;;;;;N;;;10A4;;10A4 +2D05;GEORGIAN SMALL LETTER VIN;Ll;0;L;;;;;N;;;10A5;;10A5 +2D06;GEORGIAN SMALL LETTER ZEN;Ll;0;L;;;;;N;;;10A6;;10A6 +2D07;GEORGIAN SMALL LETTER TAN;Ll;0;L;;;;;N;;;10A7;;10A7 +2D08;GEORGIAN SMALL LETTER IN;Ll;0;L;;;;;N;;;10A8;;10A8 +2D09;GEORGIAN SMALL LETTER KAN;Ll;0;L;;;;;N;;;10A9;;10A9 +2D0A;GEORGIAN SMALL LETTER LAS;Ll;0;L;;;;;N;;;10AA;;10AA +2D0B;GEORGIAN SMALL LETTER MAN;Ll;0;L;;;;;N;;;10AB;;10AB +2D0C;GEORGIAN SMALL LETTER NAR;Ll;0;L;;;;;N;;;10AC;;10AC +2D0D;GEORGIAN SMALL LETTER ON;Ll;0;L;;;;;N;;;10AD;;10AD +2D0E;GEORGIAN SMALL LETTER PAR;Ll;0;L;;;;;N;;;10AE;;10AE +2D0F;GEORGIAN SMALL LETTER ZHAR;Ll;0;L;;;;;N;;;10AF;;10AF +2D10;GEORGIAN SMALL LETTER RAE;Ll;0;L;;;;;N;;;10B0;;10B0 +2D11;GEORGIAN SMALL LETTER SAN;Ll;0;L;;;;;N;;;10B1;;10B1 +2D12;GEORGIAN SMALL LETTER TAR;Ll;0;L;;;;;N;;;10B2;;10B2 +2D13;GEORGIAN SMALL LETTER UN;Ll;0;L;;;;;N;;;10B3;;10B3 +2D14;GEORGIAN SMALL LETTER PHAR;Ll;0;L;;;;;N;;;10B4;;10B4 +2D15;GEORGIAN SMALL LETTER KHAR;Ll;0;L;;;;;N;;;10B5;;10B5 +2D16;GEORGIAN SMALL LETTER GHAN;Ll;0;L;;;;;N;;;10B6;;10B6 +2D17;GEORGIAN SMALL LETTER QAR;Ll;0;L;;;;;N;;;10B7;;10B7 +2D18;GEORGIAN SMALL LETTER SHIN;Ll;0;L;;;;;N;;;10B8;;10B8 +2D19;GEORGIAN SMALL LETTER CHIN;Ll;0;L;;;;;N;;;10B9;;10B9 +2D1A;GEORGIAN SMALL LETTER CAN;Ll;0;L;;;;;N;;;10BA;;10BA +2D1B;GEORGIAN SMALL LETTER JIL;Ll;0;L;;;;;N;;;10BB;;10BB +2D1C;GEORGIAN SMALL LETTER CIL;Ll;0;L;;;;;N;;;10BC;;10BC +2D1D;GEORGIAN SMALL LETTER CHAR;Ll;0;L;;;;;N;;;10BD;;10BD +2D1E;GEORGIAN SMALL LETTER XAN;Ll;0;L;;;;;N;;;10BE;;10BE +2D1F;GEORGIAN SMALL LETTER JHAN;Ll;0;L;;;;;N;;;10BF;;10BF +2D20;GEORGIAN SMALL LETTER HAE;Ll;0;L;;;;;N;;;10C0;;10C0 +2D21;GEORGIAN SMALL LETTER HE;Ll;0;L;;;;;N;;;10C1;;10C1 +2D22;GEORGIAN SMALL LETTER HIE;Ll;0;L;;;;;N;;;10C2;;10C2 +2D23;GEORGIAN SMALL LETTER WE;Ll;0;L;;;;;N;;;10C3;;10C3 +2D24;GEORGIAN SMALL LETTER HAR;Ll;0;L;;;;;N;;;10C4;;10C4 +2D25;GEORGIAN SMALL LETTER HOE;Ll;0;L;;;;;N;;;10C5;;10C5 +2D27;GEORGIAN SMALL LETTER YN;Ll;0;L;;;;;N;;;10C7;;10C7 +2D2D;GEORGIAN SMALL LETTER AEN;Ll;0;L;;;;;N;;;10CD;;10CD +2D30;TIFINAGH LETTER YA;Lo;0;L;;;;;N;;;;; +2D31;TIFINAGH LETTER YAB;Lo;0;L;;;;;N;;;;; +2D32;TIFINAGH LETTER YABH;Lo;0;L;;;;;N;;;;; +2D33;TIFINAGH LETTER YAG;Lo;0;L;;;;;N;;;;; +2D34;TIFINAGH LETTER YAGHH;Lo;0;L;;;;;N;;;;; +2D35;TIFINAGH LETTER BERBER ACADEMY YAJ;Lo;0;L;;;;;N;;;;; +2D36;TIFINAGH LETTER YAJ;Lo;0;L;;;;;N;;;;; +2D37;TIFINAGH LETTER YAD;Lo;0;L;;;;;N;;;;; +2D38;TIFINAGH LETTER YADH;Lo;0;L;;;;;N;;;;; +2D39;TIFINAGH LETTER YADD;Lo;0;L;;;;;N;;;;; +2D3A;TIFINAGH LETTER YADDH;Lo;0;L;;;;;N;;;;; +2D3B;TIFINAGH LETTER YEY;Lo;0;L;;;;;N;;;;; +2D3C;TIFINAGH LETTER YAF;Lo;0;L;;;;;N;;;;; +2D3D;TIFINAGH LETTER YAK;Lo;0;L;;;;;N;;;;; +2D3E;TIFINAGH LETTER TUAREG YAK;Lo;0;L;;;;;N;;;;; +2D3F;TIFINAGH LETTER YAKHH;Lo;0;L;;;;;N;;;;; +2D40;TIFINAGH LETTER YAH;Lo;0;L;;;;;N;;;;; +2D41;TIFINAGH LETTER BERBER ACADEMY YAH;Lo;0;L;;;;;N;;;;; +2D42;TIFINAGH LETTER TUAREG YAH;Lo;0;L;;;;;N;;;;; +2D43;TIFINAGH LETTER YAHH;Lo;0;L;;;;;N;;;;; +2D44;TIFINAGH LETTER YAA;Lo;0;L;;;;;N;;;;; +2D45;TIFINAGH LETTER YAKH;Lo;0;L;;;;;N;;;;; +2D46;TIFINAGH LETTER TUAREG YAKH;Lo;0;L;;;;;N;;;;; +2D47;TIFINAGH LETTER YAQ;Lo;0;L;;;;;N;;;;; +2D48;TIFINAGH LETTER TUAREG YAQ;Lo;0;L;;;;;N;;;;; +2D49;TIFINAGH LETTER YI;Lo;0;L;;;;;N;;;;; +2D4A;TIFINAGH LETTER YAZH;Lo;0;L;;;;;N;;;;; +2D4B;TIFINAGH LETTER AHAGGAR YAZH;Lo;0;L;;;;;N;;;;; +2D4C;TIFINAGH LETTER TUAREG YAZH;Lo;0;L;;;;;N;;;;; +2D4D;TIFINAGH LETTER YAL;Lo;0;L;;;;;N;;;;; +2D4E;TIFINAGH LETTER YAM;Lo;0;L;;;;;N;;;;; +2D4F;TIFINAGH LETTER YAN;Lo;0;L;;;;;N;;;;; +2D50;TIFINAGH LETTER TUAREG YAGN;Lo;0;L;;;;;N;;;;; +2D51;TIFINAGH LETTER TUAREG YANG;Lo;0;L;;;;;N;;;;; +2D52;TIFINAGH LETTER YAP;Lo;0;L;;;;;N;;;;; +2D53;TIFINAGH LETTER YU;Lo;0;L;;;;;N;;;;; +2D54;TIFINAGH LETTER YAR;Lo;0;L;;;;;N;;;;; +2D55;TIFINAGH LETTER YARR;Lo;0;L;;;;;N;;;;; +2D56;TIFINAGH LETTER YAGH;Lo;0;L;;;;;N;;;;; +2D57;TIFINAGH LETTER TUAREG YAGH;Lo;0;L;;;;;N;;;;; +2D58;TIFINAGH LETTER AYER YAGH;Lo;0;L;;;;;N;;;;; +2D59;TIFINAGH LETTER YAS;Lo;0;L;;;;;N;;;;; +2D5A;TIFINAGH LETTER YASS;Lo;0;L;;;;;N;;;;; +2D5B;TIFINAGH LETTER YASH;Lo;0;L;;;;;N;;;;; +2D5C;TIFINAGH LETTER YAT;Lo;0;L;;;;;N;;;;; +2D5D;TIFINAGH LETTER YATH;Lo;0;L;;;;;N;;;;; +2D5E;TIFINAGH LETTER YACH;Lo;0;L;;;;;N;;;;; +2D5F;TIFINAGH LETTER YATT;Lo;0;L;;;;;N;;;;; +2D60;TIFINAGH LETTER YAV;Lo;0;L;;;;;N;;;;; +2D61;TIFINAGH LETTER YAW;Lo;0;L;;;;;N;;;;; +2D62;TIFINAGH LETTER YAY;Lo;0;L;;;;;N;;;;; +2D63;TIFINAGH LETTER YAZ;Lo;0;L;;;;;N;;;;; +2D64;TIFINAGH LETTER TAWELLEMET YAZ;Lo;0;L;;;;;N;;;;; +2D65;TIFINAGH LETTER YAZZ;Lo;0;L;;;;;N;;;;; +2D66;TIFINAGH LETTER YE;Lo;0;L;;;;;N;;;;; +2D67;TIFINAGH LETTER YO;Lo;0;L;;;;;N;;;;; +2D6F;TIFINAGH MODIFIER LETTER LABIALIZATION MARK;Lm;0;L; 2D61;;;;N;;;;; +2D70;TIFINAGH SEPARATOR MARK;Po;0;L;;;;;N;;;;; +2D7F;TIFINAGH CONSONANT JOINER;Mn;9;NSM;;;;;N;;;;; +2D80;ETHIOPIC SYLLABLE LOA;Lo;0;L;;;;;N;;;;; +2D81;ETHIOPIC SYLLABLE MOA;Lo;0;L;;;;;N;;;;; +2D82;ETHIOPIC SYLLABLE ROA;Lo;0;L;;;;;N;;;;; +2D83;ETHIOPIC SYLLABLE SOA;Lo;0;L;;;;;N;;;;; +2D84;ETHIOPIC SYLLABLE SHOA;Lo;0;L;;;;;N;;;;; +2D85;ETHIOPIC SYLLABLE BOA;Lo;0;L;;;;;N;;;;; +2D86;ETHIOPIC SYLLABLE TOA;Lo;0;L;;;;;N;;;;; +2D87;ETHIOPIC SYLLABLE COA;Lo;0;L;;;;;N;;;;; +2D88;ETHIOPIC SYLLABLE NOA;Lo;0;L;;;;;N;;;;; +2D89;ETHIOPIC SYLLABLE NYOA;Lo;0;L;;;;;N;;;;; +2D8A;ETHIOPIC SYLLABLE GLOTTAL OA;Lo;0;L;;;;;N;;;;; +2D8B;ETHIOPIC SYLLABLE ZOA;Lo;0;L;;;;;N;;;;; +2D8C;ETHIOPIC SYLLABLE DOA;Lo;0;L;;;;;N;;;;; +2D8D;ETHIOPIC SYLLABLE DDOA;Lo;0;L;;;;;N;;;;; +2D8E;ETHIOPIC SYLLABLE JOA;Lo;0;L;;;;;N;;;;; +2D8F;ETHIOPIC SYLLABLE THOA;Lo;0;L;;;;;N;;;;; +2D90;ETHIOPIC SYLLABLE CHOA;Lo;0;L;;;;;N;;;;; +2D91;ETHIOPIC SYLLABLE PHOA;Lo;0;L;;;;;N;;;;; +2D92;ETHIOPIC SYLLABLE POA;Lo;0;L;;;;;N;;;;; +2D93;ETHIOPIC SYLLABLE GGWA;Lo;0;L;;;;;N;;;;; +2D94;ETHIOPIC SYLLABLE GGWI;Lo;0;L;;;;;N;;;;; +2D95;ETHIOPIC SYLLABLE GGWEE;Lo;0;L;;;;;N;;;;; +2D96;ETHIOPIC SYLLABLE GGWE;Lo;0;L;;;;;N;;;;; +2DA0;ETHIOPIC SYLLABLE SSA;Lo;0;L;;;;;N;;;;; +2DA1;ETHIOPIC SYLLABLE SSU;Lo;0;L;;;;;N;;;;; +2DA2;ETHIOPIC SYLLABLE SSI;Lo;0;L;;;;;N;;;;; +2DA3;ETHIOPIC SYLLABLE SSAA;Lo;0;L;;;;;N;;;;; +2DA4;ETHIOPIC SYLLABLE SSEE;Lo;0;L;;;;;N;;;;; +2DA5;ETHIOPIC SYLLABLE SSE;Lo;0;L;;;;;N;;;;; +2DA6;ETHIOPIC SYLLABLE SSO;Lo;0;L;;;;;N;;;;; +2DA8;ETHIOPIC SYLLABLE CCA;Lo;0;L;;;;;N;;;;; +2DA9;ETHIOPIC SYLLABLE CCU;Lo;0;L;;;;;N;;;;; +2DAA;ETHIOPIC SYLLABLE CCI;Lo;0;L;;;;;N;;;;; +2DAB;ETHIOPIC SYLLABLE CCAA;Lo;0;L;;;;;N;;;;; +2DAC;ETHIOPIC SYLLABLE CCEE;Lo;0;L;;;;;N;;;;; +2DAD;ETHIOPIC SYLLABLE CCE;Lo;0;L;;;;;N;;;;; +2DAE;ETHIOPIC SYLLABLE CCO;Lo;0;L;;;;;N;;;;; +2DB0;ETHIOPIC SYLLABLE ZZA;Lo;0;L;;;;;N;;;;; +2DB1;ETHIOPIC SYLLABLE ZZU;Lo;0;L;;;;;N;;;;; +2DB2;ETHIOPIC SYLLABLE ZZI;Lo;0;L;;;;;N;;;;; +2DB3;ETHIOPIC SYLLABLE ZZAA;Lo;0;L;;;;;N;;;;; +2DB4;ETHIOPIC SYLLABLE ZZEE;Lo;0;L;;;;;N;;;;; +2DB5;ETHIOPIC SYLLABLE ZZE;Lo;0;L;;;;;N;;;;; +2DB6;ETHIOPIC SYLLABLE ZZO;Lo;0;L;;;;;N;;;;; +2DB8;ETHIOPIC SYLLABLE CCHA;Lo;0;L;;;;;N;;;;; +2DB9;ETHIOPIC SYLLABLE CCHU;Lo;0;L;;;;;N;;;;; +2DBA;ETHIOPIC SYLLABLE CCHI;Lo;0;L;;;;;N;;;;; +2DBB;ETHIOPIC SYLLABLE CCHAA;Lo;0;L;;;;;N;;;;; +2DBC;ETHIOPIC SYLLABLE CCHEE;Lo;0;L;;;;;N;;;;; +2DBD;ETHIOPIC SYLLABLE CCHE;Lo;0;L;;;;;N;;;;; +2DBE;ETHIOPIC SYLLABLE CCHO;Lo;0;L;;;;;N;;;;; +2DC0;ETHIOPIC SYLLABLE QYA;Lo;0;L;;;;;N;;;;; +2DC1;ETHIOPIC SYLLABLE QYU;Lo;0;L;;;;;N;;;;; +2DC2;ETHIOPIC SYLLABLE QYI;Lo;0;L;;;;;N;;;;; +2DC3;ETHIOPIC SYLLABLE QYAA;Lo;0;L;;;;;N;;;;; +2DC4;ETHIOPIC SYLLABLE QYEE;Lo;0;L;;;;;N;;;;; +2DC5;ETHIOPIC SYLLABLE QYE;Lo;0;L;;;;;N;;;;; +2DC6;ETHIOPIC SYLLABLE QYO;Lo;0;L;;;;;N;;;;; +2DC8;ETHIOPIC SYLLABLE KYA;Lo;0;L;;;;;N;;;;; +2DC9;ETHIOPIC SYLLABLE KYU;Lo;0;L;;;;;N;;;;; +2DCA;ETHIOPIC SYLLABLE KYI;Lo;0;L;;;;;N;;;;; +2DCB;ETHIOPIC SYLLABLE KYAA;Lo;0;L;;;;;N;;;;; +2DCC;ETHIOPIC SYLLABLE KYEE;Lo;0;L;;;;;N;;;;; +2DCD;ETHIOPIC SYLLABLE KYE;Lo;0;L;;;;;N;;;;; +2DCE;ETHIOPIC SYLLABLE KYO;Lo;0;L;;;;;N;;;;; +2DD0;ETHIOPIC SYLLABLE XYA;Lo;0;L;;;;;N;;;;; +2DD1;ETHIOPIC SYLLABLE XYU;Lo;0;L;;;;;N;;;;; +2DD2;ETHIOPIC SYLLABLE XYI;Lo;0;L;;;;;N;;;;; +2DD3;ETHIOPIC SYLLABLE XYAA;Lo;0;L;;;;;N;;;;; +2DD4;ETHIOPIC SYLLABLE XYEE;Lo;0;L;;;;;N;;;;; +2DD5;ETHIOPIC SYLLABLE XYE;Lo;0;L;;;;;N;;;;; +2DD6;ETHIOPIC SYLLABLE XYO;Lo;0;L;;;;;N;;;;; +2DD8;ETHIOPIC SYLLABLE GYA;Lo;0;L;;;;;N;;;;; +2DD9;ETHIOPIC SYLLABLE GYU;Lo;0;L;;;;;N;;;;; +2DDA;ETHIOPIC SYLLABLE GYI;Lo;0;L;;;;;N;;;;; +2DDB;ETHIOPIC SYLLABLE GYAA;Lo;0;L;;;;;N;;;;; +2DDC;ETHIOPIC SYLLABLE GYEE;Lo;0;L;;;;;N;;;;; +2DDD;ETHIOPIC SYLLABLE GYE;Lo;0;L;;;;;N;;;;; +2DDE;ETHIOPIC SYLLABLE GYO;Lo;0;L;;;;;N;;;;; +2DE0;COMBINING CYRILLIC LETTER BE;Mn;230;NSM;;;;;N;;;;; +2DE1;COMBINING CYRILLIC LETTER VE;Mn;230;NSM;;;;;N;;;;; +2DE2;COMBINING CYRILLIC LETTER GHE;Mn;230;NSM;;;;;N;;;;; +2DE3;COMBINING CYRILLIC LETTER DE;Mn;230;NSM;;;;;N;;;;; +2DE4;COMBINING CYRILLIC LETTER ZHE;Mn;230;NSM;;;;;N;;;;; +2DE5;COMBINING CYRILLIC LETTER ZE;Mn;230;NSM;;;;;N;;;;; +2DE6;COMBINING CYRILLIC LETTER KA;Mn;230;NSM;;;;;N;;;;; +2DE7;COMBINING CYRILLIC LETTER EL;Mn;230;NSM;;;;;N;;;;; +2DE8;COMBINING CYRILLIC LETTER EM;Mn;230;NSM;;;;;N;;;;; +2DE9;COMBINING CYRILLIC LETTER EN;Mn;230;NSM;;;;;N;;;;; +2DEA;COMBINING CYRILLIC LETTER O;Mn;230;NSM;;;;;N;;;;; +2DEB;COMBINING CYRILLIC LETTER PE;Mn;230;NSM;;;;;N;;;;; +2DEC;COMBINING CYRILLIC LETTER ER;Mn;230;NSM;;;;;N;;;;; +2DED;COMBINING CYRILLIC LETTER ES;Mn;230;NSM;;;;;N;;;;; +2DEE;COMBINING CYRILLIC LETTER TE;Mn;230;NSM;;;;;N;;;;; +2DEF;COMBINING CYRILLIC LETTER HA;Mn;230;NSM;;;;;N;;;;; +2DF0;COMBINING CYRILLIC LETTER TSE;Mn;230;NSM;;;;;N;;;;; +2DF1;COMBINING CYRILLIC LETTER CHE;Mn;230;NSM;;;;;N;;;;; +2DF2;COMBINING CYRILLIC LETTER SHA;Mn;230;NSM;;;;;N;;;;; +2DF3;COMBINING CYRILLIC LETTER SHCHA;Mn;230;NSM;;;;;N;;;;; +2DF4;COMBINING CYRILLIC LETTER FITA;Mn;230;NSM;;;;;N;;;;; +2DF5;COMBINING CYRILLIC LETTER ES-TE;Mn;230;NSM;;;;;N;;;;; +2DF6;COMBINING CYRILLIC LETTER A;Mn;230;NSM;;;;;N;;;;; +2DF7;COMBINING CYRILLIC LETTER IE;Mn;230;NSM;;;;;N;;;;; +2DF8;COMBINING CYRILLIC LETTER DJERV;Mn;230;NSM;;;;;N;;;;; +2DF9;COMBINING CYRILLIC LETTER MONOGRAPH UK;Mn;230;NSM;;;;;N;;;;; +2DFA;COMBINING CYRILLIC LETTER YAT;Mn;230;NSM;;;;;N;;;;; +2DFB;COMBINING CYRILLIC LETTER YU;Mn;230;NSM;;;;;N;;;;; +2DFC;COMBINING CYRILLIC LETTER IOTIFIED A;Mn;230;NSM;;;;;N;;;;; +2DFD;COMBINING CYRILLIC LETTER LITTLE YUS;Mn;230;NSM;;;;;N;;;;; +2DFE;COMBINING CYRILLIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;; +2DFF;COMBINING CYRILLIC LETTER IOTIFIED BIG YUS;Mn;230;NSM;;;;;N;;;;; +2E00;RIGHT ANGLE SUBSTITUTION MARKER;Po;0;ON;;;;;N;;;;; +2E01;RIGHT ANGLE DOTTED SUBSTITUTION MARKER;Po;0;ON;;;;;N;;;;; +2E02;LEFT SUBSTITUTION BRACKET;Pi;0;ON;;;;;Y;;;;; +2E03;RIGHT SUBSTITUTION BRACKET;Pf;0;ON;;;;;Y;;;;; +2E04;LEFT DOTTED SUBSTITUTION BRACKET;Pi;0;ON;;;;;Y;;;;; +2E05;RIGHT DOTTED SUBSTITUTION BRACKET;Pf;0;ON;;;;;Y;;;;; +2E06;RAISED INTERPOLATION MARKER;Po;0;ON;;;;;N;;;;; +2E07;RAISED DOTTED INTERPOLATION MARKER;Po;0;ON;;;;;N;;;;; +2E08;DOTTED TRANSPOSITION MARKER;Po;0;ON;;;;;N;;;;; +2E09;LEFT TRANSPOSITION BRACKET;Pi;0;ON;;;;;Y;;;;; +2E0A;RIGHT TRANSPOSITION BRACKET;Pf;0;ON;;;;;Y;;;;; +2E0B;RAISED SQUARE;Po;0;ON;;;;;N;;;;; +2E0C;LEFT RAISED OMISSION BRACKET;Pi;0;ON;;;;;Y;;;;; +2E0D;RIGHT RAISED OMISSION BRACKET;Pf;0;ON;;;;;Y;;;;; +2E0E;EDITORIAL CORONIS;Po;0;ON;;;;;N;;;;; +2E0F;PARAGRAPHOS;Po;0;ON;;;;;N;;;;; +2E10;FORKED PARAGRAPHOS;Po;0;ON;;;;;N;;;;; +2E11;REVERSED FORKED PARAGRAPHOS;Po;0;ON;;;;;N;;;;; +2E12;HYPODIASTOLE;Po;0;ON;;;;;N;;;;; +2E13;DOTTED OBELOS;Po;0;ON;;;;;N;;;;; +2E14;DOWNWARDS ANCORA;Po;0;ON;;;;;N;;;;; +2E15;UPWARDS ANCORA;Po;0;ON;;;;;N;;;;; +2E16;DOTTED RIGHT-POINTING ANGLE;Po;0;ON;;;;;N;;;;; +2E17;DOUBLE OBLIQUE HYPHEN;Pd;0;ON;;;;;N;;;;; +2E18;INVERTED INTERROBANG;Po;0;ON;;;;;N;;;;; +2E19;PALM BRANCH;Po;0;ON;;;;;N;;;;; +2E1A;HYPHEN WITH DIAERESIS;Pd;0;ON;;;;;N;;;;; +2E1B;TILDE WITH RING ABOVE;Po;0;ON;;;;;N;;;;; +2E1C;LEFT LOW PARAPHRASE BRACKET;Pi;0;ON;;;;;Y;;;;; +2E1D;RIGHT LOW PARAPHRASE BRACKET;Pf;0;ON;;;;;Y;;;;; +2E1E;TILDE WITH DOT ABOVE;Po;0;ON;;;;;N;;;;; +2E1F;TILDE WITH DOT BELOW;Po;0;ON;;;;;N;;;;; +2E20;LEFT VERTICAL BAR WITH QUILL;Pi;0;ON;;;;;Y;;;;; +2E21;RIGHT VERTICAL BAR WITH QUILL;Pf;0;ON;;;;;Y;;;;; +2E22;TOP LEFT HALF BRACKET;Ps;0;ON;;;;;Y;;;;; +2E23;TOP RIGHT HALF BRACKET;Pe;0;ON;;;;;Y;;;;; +2E24;BOTTOM LEFT HALF BRACKET;Ps;0;ON;;;;;Y;;;;; +2E25;BOTTOM RIGHT HALF BRACKET;Pe;0;ON;;;;;Y;;;;; +2E26;LEFT SIDEWAYS U BRACKET;Ps;0;ON;;;;;Y;;;;; +2E27;RIGHT SIDEWAYS U BRACKET;Pe;0;ON;;;;;Y;;;;; +2E28;LEFT DOUBLE PARENTHESIS;Ps;0;ON;;;;;Y;;;;; +2E29;RIGHT DOUBLE PARENTHESIS;Pe;0;ON;;;;;Y;;;;; +2E2A;TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +2E2B;ONE DOT OVER TWO DOTS PUNCTUATION;Po;0;ON;;;;;N;;;;; +2E2C;SQUARED FOUR DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +2E2D;FIVE DOT MARK;Po;0;ON;;;;;N;;;;; +2E2E;REVERSED QUESTION MARK;Po;0;ON;;;;;N;;;;; +2E2F;VERTICAL TILDE;Lm;0;ON;;;;;N;;;;; +2E30;RING POINT;Po;0;ON;;;;;N;;;;; +2E31;WORD SEPARATOR MIDDLE DOT;Po;0;ON;;;;;N;;;;; +2E32;TURNED COMMA;Po;0;ON;;;;;N;;;;; +2E33;RAISED DOT;Po;0;ON;;;;;N;;;;; +2E34;RAISED COMMA;Po;0;ON;;;;;N;;;;; +2E35;TURNED SEMICOLON;Po;0;ON;;;;;N;;;;; +2E36;DAGGER WITH LEFT GUARD;Po;0;ON;;;;;N;;;;; +2E37;DAGGER WITH RIGHT GUARD;Po;0;ON;;;;;N;;;;; +2E38;TURNED DAGGER;Po;0;ON;;;;;N;;;;; +2E39;TOP HALF SECTION SIGN;Po;0;ON;;;;;N;;;;; +2E3A;TWO-EM DASH;Pd;0;ON;;;;;N;;;;; +2E3B;THREE-EM DASH;Pd;0;ON;;;;;N;;;;; +2E3C;STENOGRAPHIC FULL STOP;Po;0;ON;;;;;N;;;;; +2E3D;VERTICAL SIX DOTS;Po;0;ON;;;;;N;;;;; +2E3E;WIGGLY VERTICAL LINE;Po;0;ON;;;;;N;;;;; +2E3F;CAPITULUM;Po;0;ON;;;;;N;;;;; +2E40;DOUBLE HYPHEN;Pd;0;ON;;;;;N;;;;; +2E41;REVERSED COMMA;Po;0;ON;;;;;N;;;;; +2E42;DOUBLE LOW-REVERSED-9 QUOTATION MARK;Ps;0;ON;;;;;N;;;;; +2E43;DASH WITH LEFT UPTURN;Po;0;ON;;;;;N;;;;; +2E44;DOUBLE SUSPENSION MARK;Po;0;ON;;;;;N;;;;; +2E45;INVERTED LOW KAVYKA;Po;0;ON;;;;;N;;;;; +2E46;INVERTED LOW KAVYKA WITH KAVYKA ABOVE;Po;0;ON;;;;;N;;;;; +2E47;LOW KAVYKA;Po;0;ON;;;;;N;;;;; +2E48;LOW KAVYKA WITH DOT;Po;0;ON;;;;;N;;;;; +2E49;DOUBLE STACKED COMMA;Po;0;ON;;;;;N;;;;; +2E4A;DOTTED SOLIDUS;Po;0;ON;;;;;N;;;;; +2E4B;TRIPLE DAGGER;Po;0;ON;;;;;N;;;;; +2E4C;MEDIEVAL COMMA;Po;0;ON;;;;;N;;;;; +2E4D;PARAGRAPHUS MARK;Po;0;ON;;;;;N;;;;; +2E4E;PUNCTUS ELEVATUS MARK;Po;0;ON;;;;;N;;;;; +2E4F;CORNISH VERSE DIVIDER;Po;0;ON;;;;;N;;;;; +2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;; +2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;; +2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;; +2E83;CJK RADICAL SECOND TWO;So;0;ON;;;;;N;;;;; +2E84;CJK RADICAL SECOND THREE;So;0;ON;;;;;N;;;;; +2E85;CJK RADICAL PERSON;So;0;ON;;;;;N;;;;; +2E86;CJK RADICAL BOX;So;0;ON;;;;;N;;;;; +2E87;CJK RADICAL TABLE;So;0;ON;;;;;N;;;;; +2E88;CJK RADICAL KNIFE ONE;So;0;ON;;;;;N;;;;; +2E89;CJK RADICAL KNIFE TWO;So;0;ON;;;;;N;;;;; +2E8A;CJK RADICAL DIVINATION;So;0;ON;;;;;N;;;;; +2E8B;CJK RADICAL SEAL;So;0;ON;;;;;N;;;;; +2E8C;CJK RADICAL SMALL ONE;So;0;ON;;;;;N;;;;; +2E8D;CJK RADICAL SMALL TWO;So;0;ON;;;;;N;;;;; +2E8E;CJK RADICAL LAME ONE;So;0;ON;;;;;N;;;;; +2E8F;CJK RADICAL LAME TWO;So;0;ON;;;;;N;;;;; +2E90;CJK RADICAL LAME THREE;So;0;ON;;;;;N;;;;; +2E91;CJK RADICAL LAME FOUR;So;0;ON;;;;;N;;;;; +2E92;CJK RADICAL SNAKE;So;0;ON;;;;;N;;;;; +2E93;CJK RADICAL THREAD;So;0;ON;;;;;N;;;;; +2E94;CJK RADICAL SNOUT ONE;So;0;ON;;;;;N;;;;; +2E95;CJK RADICAL SNOUT TWO;So;0;ON;;;;;N;;;;; +2E96;CJK RADICAL HEART ONE;So;0;ON;;;;;N;;;;; +2E97;CJK RADICAL HEART TWO;So;0;ON;;;;;N;;;;; +2E98;CJK RADICAL HAND;So;0;ON;;;;;N;;;;; +2E99;CJK RADICAL RAP;So;0;ON;;;;;N;;;;; +2E9B;CJK RADICAL CHOKE;So;0;ON;;;;;N;;;;; +2E9C;CJK RADICAL SUN;So;0;ON;;;;;N;;;;; +2E9D;CJK RADICAL MOON;So;0;ON;;;;;N;;;;; +2E9E;CJK RADICAL DEATH;So;0;ON;;;;;N;;;;; +2E9F;CJK RADICAL MOTHER;So;0;ON; 6BCD;;;;N;;;;; +2EA0;CJK RADICAL CIVILIAN;So;0;ON;;;;;N;;;;; +2EA1;CJK RADICAL WATER ONE;So;0;ON;;;;;N;;;;; +2EA2;CJK RADICAL WATER TWO;So;0;ON;;;;;N;;;;; +2EA3;CJK RADICAL FIRE;So;0;ON;;;;;N;;;;; +2EA4;CJK RADICAL PAW ONE;So;0;ON;;;;;N;;;;; +2EA5;CJK RADICAL PAW TWO;So;0;ON;;;;;N;;;;; +2EA6;CJK RADICAL SIMPLIFIED HALF TREE TRUNK;So;0;ON;;;;;N;;;;; +2EA7;CJK RADICAL COW;So;0;ON;;;;;N;;;;; +2EA8;CJK RADICAL DOG;So;0;ON;;;;;N;;;;; +2EA9;CJK RADICAL JADE;So;0;ON;;;;;N;;;;; +2EAA;CJK RADICAL BOLT OF CLOTH;So;0;ON;;;;;N;;;;; +2EAB;CJK RADICAL EYE;So;0;ON;;;;;N;;;;; +2EAC;CJK RADICAL SPIRIT ONE;So;0;ON;;;;;N;;;;; +2EAD;CJK RADICAL SPIRIT TWO;So;0;ON;;;;;N;;;;; +2EAE;CJK RADICAL BAMBOO;So;0;ON;;;;;N;;;;; +2EAF;CJK RADICAL SILK;So;0;ON;;;;;N;;;;; +2EB0;CJK RADICAL C-SIMPLIFIED SILK;So;0;ON;;;;;N;;;;; +2EB1;CJK RADICAL NET ONE;So;0;ON;;;;;N;;;;; +2EB2;CJK RADICAL NET TWO;So;0;ON;;;;;N;;;;; +2EB3;CJK RADICAL NET THREE;So;0;ON;;;;;N;;;;; +2EB4;CJK RADICAL NET FOUR;So;0;ON;;;;;N;;;;; +2EB5;CJK RADICAL MESH;So;0;ON;;;;;N;;;;; +2EB6;CJK RADICAL SHEEP;So;0;ON;;;;;N;;;;; +2EB7;CJK RADICAL RAM;So;0;ON;;;;;N;;;;; +2EB8;CJK RADICAL EWE;So;0;ON;;;;;N;;;;; +2EB9;CJK RADICAL OLD;So;0;ON;;;;;N;;;;; +2EBA;CJK RADICAL BRUSH ONE;So;0;ON;;;;;N;;;;; +2EBB;CJK RADICAL BRUSH TWO;So;0;ON;;;;;N;;;;; +2EBC;CJK RADICAL MEAT;So;0;ON;;;;;N;;;;; +2EBD;CJK RADICAL MORTAR;So;0;ON;;;;;N;;;;; +2EBE;CJK RADICAL GRASS ONE;So;0;ON;;;;;N;;;;; +2EBF;CJK RADICAL GRASS TWO;So;0;ON;;;;;N;;;;; +2EC0;CJK RADICAL GRASS THREE;So;0;ON;;;;;N;;;;; +2EC1;CJK RADICAL TIGER;So;0;ON;;;;;N;;;;; +2EC2;CJK RADICAL CLOTHES;So;0;ON;;;;;N;;;;; +2EC3;CJK RADICAL WEST ONE;So;0;ON;;;;;N;;;;; +2EC4;CJK RADICAL WEST TWO;So;0;ON;;;;;N;;;;; +2EC5;CJK RADICAL C-SIMPLIFIED SEE;So;0;ON;;;;;N;;;;; +2EC6;CJK RADICAL SIMPLIFIED HORN;So;0;ON;;;;;N;;;;; +2EC7;CJK RADICAL HORN;So;0;ON;;;;;N;;;;; +2EC8;CJK RADICAL C-SIMPLIFIED SPEECH;So;0;ON;;;;;N;;;;; +2EC9;CJK RADICAL C-SIMPLIFIED SHELL;So;0;ON;;;;;N;;;;; +2ECA;CJK RADICAL FOOT;So;0;ON;;;;;N;;;;; +2ECB;CJK RADICAL C-SIMPLIFIED CART;So;0;ON;;;;;N;;;;; +2ECC;CJK RADICAL SIMPLIFIED WALK;So;0;ON;;;;;N;;;;; +2ECD;CJK RADICAL WALK ONE;So;0;ON;;;;;N;;;;; +2ECE;CJK RADICAL WALK TWO;So;0;ON;;;;;N;;;;; +2ECF;CJK RADICAL CITY;So;0;ON;;;;;N;;;;; +2ED0;CJK RADICAL C-SIMPLIFIED GOLD;So;0;ON;;;;;N;;;;; +2ED1;CJK RADICAL LONG ONE;So;0;ON;;;;;N;;;;; +2ED2;CJK RADICAL LONG TWO;So;0;ON;;;;;N;;;;; +2ED3;CJK RADICAL C-SIMPLIFIED LONG;So;0;ON;;;;;N;;;;; +2ED4;CJK RADICAL C-SIMPLIFIED GATE;So;0;ON;;;;;N;;;;; +2ED5;CJK RADICAL MOUND ONE;So;0;ON;;;;;N;;;;; +2ED6;CJK RADICAL MOUND TWO;So;0;ON;;;;;N;;;;; +2ED7;CJK RADICAL RAIN;So;0;ON;;;;;N;;;;; +2ED8;CJK RADICAL BLUE;So;0;ON;;;;;N;;;;; +2ED9;CJK RADICAL C-SIMPLIFIED TANNED LEATHER;So;0;ON;;;;;N;;;;; +2EDA;CJK RADICAL C-SIMPLIFIED LEAF;So;0;ON;;;;;N;;;;; +2EDB;CJK RADICAL C-SIMPLIFIED WIND;So;0;ON;;;;;N;;;;; +2EDC;CJK RADICAL C-SIMPLIFIED FLY;So;0;ON;;;;;N;;;;; +2EDD;CJK RADICAL EAT ONE;So;0;ON;;;;;N;;;;; +2EDE;CJK RADICAL EAT TWO;So;0;ON;;;;;N;;;;; +2EDF;CJK RADICAL EAT THREE;So;0;ON;;;;;N;;;;; +2EE0;CJK RADICAL C-SIMPLIFIED EAT;So;0;ON;;;;;N;;;;; +2EE1;CJK RADICAL HEAD;So;0;ON;;;;;N;;;;; +2EE2;CJK RADICAL C-SIMPLIFIED HORSE;So;0;ON;;;;;N;;;;; +2EE3;CJK RADICAL BONE;So;0;ON;;;;;N;;;;; +2EE4;CJK RADICAL GHOST;So;0;ON;;;;;N;;;;; +2EE5;CJK RADICAL C-SIMPLIFIED FISH;So;0;ON;;;;;N;;;;; +2EE6;CJK RADICAL C-SIMPLIFIED BIRD;So;0;ON;;;;;N;;;;; +2EE7;CJK RADICAL C-SIMPLIFIED SALT;So;0;ON;;;;;N;;;;; +2EE8;CJK RADICAL SIMPLIFIED WHEAT;So;0;ON;;;;;N;;;;; +2EE9;CJK RADICAL SIMPLIFIED YELLOW;So;0;ON;;;;;N;;;;; +2EEA;CJK RADICAL C-SIMPLIFIED FROG;So;0;ON;;;;;N;;;;; +2EEB;CJK RADICAL J-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;; +2EEC;CJK RADICAL C-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;; +2EED;CJK RADICAL J-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;; +2EEE;CJK RADICAL C-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;; +2EEF;CJK RADICAL J-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;; +2EF0;CJK RADICAL C-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;; +2EF1;CJK RADICAL TURTLE;So;0;ON;;;;;N;;;;; +2EF2;CJK RADICAL J-SIMPLIFIED TURTLE;So;0;ON;;;;;N;;;;; +2EF3;CJK RADICAL C-SIMPLIFIED TURTLE;So;0;ON; 9F9F;;;;N;;;;; +2F00;KANGXI RADICAL ONE;So;0;ON; 4E00;;;;N;;;;; +2F01;KANGXI RADICAL LINE;So;0;ON; 4E28;;;;N;;;;; +2F02;KANGXI RADICAL DOT;So;0;ON; 4E36;;;;N;;;;; +2F03;KANGXI RADICAL SLASH;So;0;ON; 4E3F;;;;N;;;;; +2F04;KANGXI RADICAL SECOND;So;0;ON; 4E59;;;;N;;;;; +2F05;KANGXI RADICAL HOOK;So;0;ON; 4E85;;;;N;;;;; +2F06;KANGXI RADICAL TWO;So;0;ON; 4E8C;;;;N;;;;; +2F07;KANGXI RADICAL LID;So;0;ON; 4EA0;;;;N;;;;; +2F08;KANGXI RADICAL MAN;So;0;ON; 4EBA;;;;N;;;;; +2F09;KANGXI RADICAL LEGS;So;0;ON; 513F;;;;N;;;;; +2F0A;KANGXI RADICAL ENTER;So;0;ON; 5165;;;;N;;;;; +2F0B;KANGXI RADICAL EIGHT;So;0;ON; 516B;;;;N;;;;; +2F0C;KANGXI RADICAL DOWN BOX;So;0;ON; 5182;;;;N;;;;; +2F0D;KANGXI RADICAL COVER;So;0;ON; 5196;;;;N;;;;; +2F0E;KANGXI RADICAL ICE;So;0;ON; 51AB;;;;N;;;;; +2F0F;KANGXI RADICAL TABLE;So;0;ON; 51E0;;;;N;;;;; +2F10;KANGXI RADICAL OPEN BOX;So;0;ON; 51F5;;;;N;;;;; +2F11;KANGXI RADICAL KNIFE;So;0;ON; 5200;;;;N;;;;; +2F12;KANGXI RADICAL POWER;So;0;ON; 529B;;;;N;;;;; +2F13;KANGXI RADICAL WRAP;So;0;ON; 52F9;;;;N;;;;; +2F14;KANGXI RADICAL SPOON;So;0;ON; 5315;;;;N;;;;; +2F15;KANGXI RADICAL RIGHT OPEN BOX;So;0;ON; 531A;;;;N;;;;; +2F16;KANGXI RADICAL HIDING ENCLOSURE;So;0;ON; 5338;;;;N;;;;; +2F17;KANGXI RADICAL TEN;So;0;ON; 5341;;;;N;;;;; +2F18;KANGXI RADICAL DIVINATION;So;0;ON; 535C;;;;N;;;;; +2F19;KANGXI RADICAL SEAL;So;0;ON; 5369;;;;N;;;;; +2F1A;KANGXI RADICAL CLIFF;So;0;ON; 5382;;;;N;;;;; +2F1B;KANGXI RADICAL PRIVATE;So;0;ON; 53B6;;;;N;;;;; +2F1C;KANGXI RADICAL AGAIN;So;0;ON; 53C8;;;;N;;;;; +2F1D;KANGXI RADICAL MOUTH;So;0;ON; 53E3;;;;N;;;;; +2F1E;KANGXI RADICAL ENCLOSURE;So;0;ON; 56D7;;;;N;;;;; +2F1F;KANGXI RADICAL EARTH;So;0;ON; 571F;;;;N;;;;; +2F20;KANGXI RADICAL SCHOLAR;So;0;ON; 58EB;;;;N;;;;; +2F21;KANGXI RADICAL GO;So;0;ON; 5902;;;;N;;;;; +2F22;KANGXI RADICAL GO SLOWLY;So;0;ON; 590A;;;;N;;;;; +2F23;KANGXI RADICAL EVENING;So;0;ON; 5915;;;;N;;;;; +2F24;KANGXI RADICAL BIG;So;0;ON; 5927;;;;N;;;;; +2F25;KANGXI RADICAL WOMAN;So;0;ON; 5973;;;;N;;;;; +2F26;KANGXI RADICAL CHILD;So;0;ON; 5B50;;;;N;;;;; +2F27;KANGXI RADICAL ROOF;So;0;ON; 5B80;;;;N;;;;; +2F28;KANGXI RADICAL INCH;So;0;ON; 5BF8;;;;N;;;;; +2F29;KANGXI RADICAL SMALL;So;0;ON; 5C0F;;;;N;;;;; +2F2A;KANGXI RADICAL LAME;So;0;ON; 5C22;;;;N;;;;; +2F2B;KANGXI RADICAL CORPSE;So;0;ON; 5C38;;;;N;;;;; +2F2C;KANGXI RADICAL SPROUT;So;0;ON; 5C6E;;;;N;;;;; +2F2D;KANGXI RADICAL MOUNTAIN;So;0;ON; 5C71;;;;N;;;;; +2F2E;KANGXI RADICAL RIVER;So;0;ON; 5DDB;;;;N;;;;; +2F2F;KANGXI RADICAL WORK;So;0;ON; 5DE5;;;;N;;;;; +2F30;KANGXI RADICAL ONESELF;So;0;ON; 5DF1;;;;N;;;;; +2F31;KANGXI RADICAL TURBAN;So;0;ON; 5DFE;;;;N;;;;; +2F32;KANGXI RADICAL DRY;So;0;ON; 5E72;;;;N;;;;; +2F33;KANGXI RADICAL SHORT THREAD;So;0;ON; 5E7A;;;;N;;;;; +2F34;KANGXI RADICAL DOTTED CLIFF;So;0;ON; 5E7F;;;;N;;;;; +2F35;KANGXI RADICAL LONG STRIDE;So;0;ON; 5EF4;;;;N;;;;; +2F36;KANGXI RADICAL TWO HANDS;So;0;ON; 5EFE;;;;N;;;;; +2F37;KANGXI RADICAL SHOOT;So;0;ON; 5F0B;;;;N;;;;; +2F38;KANGXI RADICAL BOW;So;0;ON; 5F13;;;;N;;;;; +2F39;KANGXI RADICAL SNOUT;So;0;ON; 5F50;;;;N;;;;; +2F3A;KANGXI RADICAL BRISTLE;So;0;ON; 5F61;;;;N;;;;; +2F3B;KANGXI RADICAL STEP;So;0;ON; 5F73;;;;N;;;;; +2F3C;KANGXI RADICAL HEART;So;0;ON; 5FC3;;;;N;;;;; +2F3D;KANGXI RADICAL HALBERD;So;0;ON; 6208;;;;N;;;;; +2F3E;KANGXI RADICAL DOOR;So;0;ON; 6236;;;;N;;;;; +2F3F;KANGXI RADICAL HAND;So;0;ON; 624B;;;;N;;;;; +2F40;KANGXI RADICAL BRANCH;So;0;ON; 652F;;;;N;;;;; +2F41;KANGXI RADICAL RAP;So;0;ON; 6534;;;;N;;;;; +2F42;KANGXI RADICAL SCRIPT;So;0;ON; 6587;;;;N;;;;; +2F43;KANGXI RADICAL DIPPER;So;0;ON; 6597;;;;N;;;;; +2F44;KANGXI RADICAL AXE;So;0;ON; 65A4;;;;N;;;;; +2F45;KANGXI RADICAL SQUARE;So;0;ON; 65B9;;;;N;;;;; +2F46;KANGXI RADICAL NOT;So;0;ON; 65E0;;;;N;;;;; +2F47;KANGXI RADICAL SUN;So;0;ON; 65E5;;;;N;;;;; +2F48;KANGXI RADICAL SAY;So;0;ON; 66F0;;;;N;;;;; +2F49;KANGXI RADICAL MOON;So;0;ON; 6708;;;;N;;;;; +2F4A;KANGXI RADICAL TREE;So;0;ON; 6728;;;;N;;;;; +2F4B;KANGXI RADICAL LACK;So;0;ON; 6B20;;;;N;;;;; +2F4C;KANGXI RADICAL STOP;So;0;ON; 6B62;;;;N;;;;; +2F4D;KANGXI RADICAL DEATH;So;0;ON; 6B79;;;;N;;;;; +2F4E;KANGXI RADICAL WEAPON;So;0;ON; 6BB3;;;;N;;;;; +2F4F;KANGXI RADICAL DO NOT;So;0;ON; 6BCB;;;;N;;;;; +2F50;KANGXI RADICAL COMPARE;So;0;ON; 6BD4;;;;N;;;;; +2F51;KANGXI RADICAL FUR;So;0;ON; 6BDB;;;;N;;;;; +2F52;KANGXI RADICAL CLAN;So;0;ON; 6C0F;;;;N;;;;; +2F53;KANGXI RADICAL STEAM;So;0;ON; 6C14;;;;N;;;;; +2F54;KANGXI RADICAL WATER;So;0;ON; 6C34;;;;N;;;;; +2F55;KANGXI RADICAL FIRE;So;0;ON; 706B;;;;N;;;;; +2F56;KANGXI RADICAL CLAW;So;0;ON; 722A;;;;N;;;;; +2F57;KANGXI RADICAL FATHER;So;0;ON; 7236;;;;N;;;;; +2F58;KANGXI RADICAL DOUBLE X;So;0;ON; 723B;;;;N;;;;; +2F59;KANGXI RADICAL HALF TREE TRUNK;So;0;ON; 723F;;;;N;;;;; +2F5A;KANGXI RADICAL SLICE;So;0;ON; 7247;;;;N;;;;; +2F5B;KANGXI RADICAL FANG;So;0;ON; 7259;;;;N;;;;; +2F5C;KANGXI RADICAL COW;So;0;ON; 725B;;;;N;;;;; +2F5D;KANGXI RADICAL DOG;So;0;ON; 72AC;;;;N;;;;; +2F5E;KANGXI RADICAL PROFOUND;So;0;ON; 7384;;;;N;;;;; +2F5F;KANGXI RADICAL JADE;So;0;ON; 7389;;;;N;;;;; +2F60;KANGXI RADICAL MELON;So;0;ON; 74DC;;;;N;;;;; +2F61;KANGXI RADICAL TILE;So;0;ON; 74E6;;;;N;;;;; +2F62;KANGXI RADICAL SWEET;So;0;ON; 7518;;;;N;;;;; +2F63;KANGXI RADICAL LIFE;So;0;ON; 751F;;;;N;;;;; +2F64;KANGXI RADICAL USE;So;0;ON; 7528;;;;N;;;;; +2F65;KANGXI RADICAL FIELD;So;0;ON; 7530;;;;N;;;;; +2F66;KANGXI RADICAL BOLT OF CLOTH;So;0;ON; 758B;;;;N;;;;; +2F67;KANGXI RADICAL SICKNESS;So;0;ON; 7592;;;;N;;;;; +2F68;KANGXI RADICAL DOTTED TENT;So;0;ON; 7676;;;;N;;;;; +2F69;KANGXI RADICAL WHITE;So;0;ON; 767D;;;;N;;;;; +2F6A;KANGXI RADICAL SKIN;So;0;ON; 76AE;;;;N;;;;; +2F6B;KANGXI RADICAL DISH;So;0;ON; 76BF;;;;N;;;;; +2F6C;KANGXI RADICAL EYE;So;0;ON; 76EE;;;;N;;;;; +2F6D;KANGXI RADICAL SPEAR;So;0;ON; 77DB;;;;N;;;;; +2F6E;KANGXI RADICAL ARROW;So;0;ON; 77E2;;;;N;;;;; +2F6F;KANGXI RADICAL STONE;So;0;ON; 77F3;;;;N;;;;; +2F70;KANGXI RADICAL SPIRIT;So;0;ON; 793A;;;;N;;;;; +2F71;KANGXI RADICAL TRACK;So;0;ON; 79B8;;;;N;;;;; +2F72;KANGXI RADICAL GRAIN;So;0;ON; 79BE;;;;N;;;;; +2F73;KANGXI RADICAL CAVE;So;0;ON; 7A74;;;;N;;;;; +2F74;KANGXI RADICAL STAND;So;0;ON; 7ACB;;;;N;;;;; +2F75;KANGXI RADICAL BAMBOO;So;0;ON; 7AF9;;;;N;;;;; +2F76;KANGXI RADICAL RICE;So;0;ON; 7C73;;;;N;;;;; +2F77;KANGXI RADICAL SILK;So;0;ON; 7CF8;;;;N;;;;; +2F78;KANGXI RADICAL JAR;So;0;ON; 7F36;;;;N;;;;; +2F79;KANGXI RADICAL NET;So;0;ON; 7F51;;;;N;;;;; +2F7A;KANGXI RADICAL SHEEP;So;0;ON; 7F8A;;;;N;;;;; +2F7B;KANGXI RADICAL FEATHER;So;0;ON; 7FBD;;;;N;;;;; +2F7C;KANGXI RADICAL OLD;So;0;ON; 8001;;;;N;;;;; +2F7D;KANGXI RADICAL AND;So;0;ON; 800C;;;;N;;;;; +2F7E;KANGXI RADICAL PLOW;So;0;ON; 8012;;;;N;;;;; +2F7F;KANGXI RADICAL EAR;So;0;ON; 8033;;;;N;;;;; +2F80;KANGXI RADICAL BRUSH;So;0;ON; 807F;;;;N;;;;; +2F81;KANGXI RADICAL MEAT;So;0;ON; 8089;;;;N;;;;; +2F82;KANGXI RADICAL MINISTER;So;0;ON; 81E3;;;;N;;;;; +2F83;KANGXI RADICAL SELF;So;0;ON; 81EA;;;;N;;;;; +2F84;KANGXI RADICAL ARRIVE;So;0;ON; 81F3;;;;N;;;;; +2F85;KANGXI RADICAL MORTAR;So;0;ON; 81FC;;;;N;;;;; +2F86;KANGXI RADICAL TONGUE;So;0;ON; 820C;;;;N;;;;; +2F87;KANGXI RADICAL OPPOSE;So;0;ON; 821B;;;;N;;;;; +2F88;KANGXI RADICAL BOAT;So;0;ON; 821F;;;;N;;;;; +2F89;KANGXI RADICAL STOPPING;So;0;ON; 826E;;;;N;;;;; +2F8A;KANGXI RADICAL COLOR;So;0;ON; 8272;;;;N;;;;; +2F8B;KANGXI RADICAL GRASS;So;0;ON; 8278;;;;N;;;;; +2F8C;KANGXI RADICAL TIGER;So;0;ON; 864D;;;;N;;;;; +2F8D;KANGXI RADICAL INSECT;So;0;ON; 866B;;;;N;;;;; +2F8E;KANGXI RADICAL BLOOD;So;0;ON; 8840;;;;N;;;;; +2F8F;KANGXI RADICAL WALK ENCLOSURE;So;0;ON; 884C;;;;N;;;;; +2F90;KANGXI RADICAL CLOTHES;So;0;ON; 8863;;;;N;;;;; +2F91;KANGXI RADICAL WEST;So;0;ON; 897E;;;;N;;;;; +2F92;KANGXI RADICAL SEE;So;0;ON; 898B;;;;N;;;;; +2F93;KANGXI RADICAL HORN;So;0;ON; 89D2;;;;N;;;;; +2F94;KANGXI RADICAL SPEECH;So;0;ON; 8A00;;;;N;;;;; +2F95;KANGXI RADICAL VALLEY;So;0;ON; 8C37;;;;N;;;;; +2F96;KANGXI RADICAL BEAN;So;0;ON; 8C46;;;;N;;;;; +2F97;KANGXI RADICAL PIG;So;0;ON; 8C55;;;;N;;;;; +2F98;KANGXI RADICAL BADGER;So;0;ON; 8C78;;;;N;;;;; +2F99;KANGXI RADICAL SHELL;So;0;ON; 8C9D;;;;N;;;;; +2F9A;KANGXI RADICAL RED;So;0;ON; 8D64;;;;N;;;;; +2F9B;KANGXI RADICAL RUN;So;0;ON; 8D70;;;;N;;;;; +2F9C;KANGXI RADICAL FOOT;So;0;ON; 8DB3;;;;N;;;;; +2F9D;KANGXI RADICAL BODY;So;0;ON; 8EAB;;;;N;;;;; +2F9E;KANGXI RADICAL CART;So;0;ON; 8ECA;;;;N;;;;; +2F9F;KANGXI RADICAL BITTER;So;0;ON; 8F9B;;;;N;;;;; +2FA0;KANGXI RADICAL MORNING;So;0;ON; 8FB0;;;;N;;;;; +2FA1;KANGXI RADICAL WALK;So;0;ON; 8FB5;;;;N;;;;; +2FA2;KANGXI RADICAL CITY;So;0;ON; 9091;;;;N;;;;; +2FA3;KANGXI RADICAL WINE;So;0;ON; 9149;;;;N;;;;; +2FA4;KANGXI RADICAL DISTINGUISH;So;0;ON; 91C6;;;;N;;;;; +2FA5;KANGXI RADICAL VILLAGE;So;0;ON; 91CC;;;;N;;;;; +2FA6;KANGXI RADICAL GOLD;So;0;ON; 91D1;;;;N;;;;; +2FA7;KANGXI RADICAL LONG;So;0;ON; 9577;;;;N;;;;; +2FA8;KANGXI RADICAL GATE;So;0;ON; 9580;;;;N;;;;; +2FA9;KANGXI RADICAL MOUND;So;0;ON; 961C;;;;N;;;;; +2FAA;KANGXI RADICAL SLAVE;So;0;ON; 96B6;;;;N;;;;; +2FAB;KANGXI RADICAL SHORT TAILED BIRD;So;0;ON; 96B9;;;;N;;;;; +2FAC;KANGXI RADICAL RAIN;So;0;ON; 96E8;;;;N;;;;; +2FAD;KANGXI RADICAL BLUE;So;0;ON; 9751;;;;N;;;;; +2FAE;KANGXI RADICAL WRONG;So;0;ON; 975E;;;;N;;;;; +2FAF;KANGXI RADICAL FACE;So;0;ON; 9762;;;;N;;;;; +2FB0;KANGXI RADICAL LEATHER;So;0;ON; 9769;;;;N;;;;; +2FB1;KANGXI RADICAL TANNED LEATHER;So;0;ON; 97CB;;;;N;;;;; +2FB2;KANGXI RADICAL LEEK;So;0;ON; 97ED;;;;N;;;;; +2FB3;KANGXI RADICAL SOUND;So;0;ON; 97F3;;;;N;;;;; +2FB4;KANGXI RADICAL LEAF;So;0;ON; 9801;;;;N;;;;; +2FB5;KANGXI RADICAL WIND;So;0;ON; 98A8;;;;N;;;;; +2FB6;KANGXI RADICAL FLY;So;0;ON; 98DB;;;;N;;;;; +2FB7;KANGXI RADICAL EAT;So;0;ON; 98DF;;;;N;;;;; +2FB8;KANGXI RADICAL HEAD;So;0;ON; 9996;;;;N;;;;; +2FB9;KANGXI RADICAL FRAGRANT;So;0;ON; 9999;;;;N;;;;; +2FBA;KANGXI RADICAL HORSE;So;0;ON; 99AC;;;;N;;;;; +2FBB;KANGXI RADICAL BONE;So;0;ON; 9AA8;;;;N;;;;; +2FBC;KANGXI RADICAL TALL;So;0;ON; 9AD8;;;;N;;;;; +2FBD;KANGXI RADICAL HAIR;So;0;ON; 9ADF;;;;N;;;;; +2FBE;KANGXI RADICAL FIGHT;So;0;ON; 9B25;;;;N;;;;; +2FBF;KANGXI RADICAL SACRIFICIAL WINE;So;0;ON; 9B2F;;;;N;;;;; +2FC0;KANGXI RADICAL CAULDRON;So;0;ON; 9B32;;;;N;;;;; +2FC1;KANGXI RADICAL GHOST;So;0;ON; 9B3C;;;;N;;;;; +2FC2;KANGXI RADICAL FISH;So;0;ON; 9B5A;;;;N;;;;; +2FC3;KANGXI RADICAL BIRD;So;0;ON; 9CE5;;;;N;;;;; +2FC4;KANGXI RADICAL SALT;So;0;ON; 9E75;;;;N;;;;; +2FC5;KANGXI RADICAL DEER;So;0;ON; 9E7F;;;;N;;;;; +2FC6;KANGXI RADICAL WHEAT;So;0;ON; 9EA5;;;;N;;;;; +2FC7;KANGXI RADICAL HEMP;So;0;ON; 9EBB;;;;N;;;;; +2FC8;KANGXI RADICAL YELLOW;So;0;ON; 9EC3;;;;N;;;;; +2FC9;KANGXI RADICAL MILLET;So;0;ON; 9ECD;;;;N;;;;; +2FCA;KANGXI RADICAL BLACK;So;0;ON; 9ED1;;;;N;;;;; +2FCB;KANGXI RADICAL EMBROIDERY;So;0;ON; 9EF9;;;;N;;;;; +2FCC;KANGXI RADICAL FROG;So;0;ON; 9EFD;;;;N;;;;; +2FCD;KANGXI RADICAL TRIPOD;So;0;ON; 9F0E;;;;N;;;;; +2FCE;KANGXI RADICAL DRUM;So;0;ON; 9F13;;;;N;;;;; +2FCF;KANGXI RADICAL RAT;So;0;ON; 9F20;;;;N;;;;; +2FD0;KANGXI RADICAL NOSE;So;0;ON; 9F3B;;;;N;;;;; +2FD1;KANGXI RADICAL EVEN;So;0;ON; 9F4A;;;;N;;;;; +2FD2;KANGXI RADICAL TOOTH;So;0;ON; 9F52;;;;N;;;;; +2FD3;KANGXI RADICAL DRAGON;So;0;ON; 9F8D;;;;N;;;;; +2FD4;KANGXI RADICAL TURTLE;So;0;ON; 9F9C;;;;N;;;;; +2FD5;KANGXI RADICAL FLUTE;So;0;ON; 9FA0;;;;N;;;;; +2FF0;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT;So;0;ON;;;;;N;;;;; +2FF1;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO BELOW;So;0;ON;;;;;N;;;;; +2FF2;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT;So;0;ON;;;;;N;;;;; +2FF3;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO MIDDLE AND BELOW;So;0;ON;;;;;N;;;;; +2FF4;IDEOGRAPHIC DESCRIPTION CHARACTER FULL SURROUND;So;0;ON;;;;;N;;;;; +2FF5;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM ABOVE;So;0;ON;;;;;N;;;;; +2FF6;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM BELOW;So;0;ON;;;;;N;;;;; +2FF7;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LEFT;So;0;ON;;;;;N;;;;; +2FF8;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER LEFT;So;0;ON;;;;;N;;;;; +2FF9;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER RIGHT;So;0;ON;;;;;N;;;;; +2FFA;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LOWER LEFT;So;0;ON;;;;;N;;;;; +2FFB;IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID;So;0;ON;;;;;N;;;;; +3000;IDEOGRAPHIC SPACE;Zs;0;WS; 0020;;;;N;;;;; +3001;IDEOGRAPHIC COMMA;Po;0;ON;;;;;N;;;;; +3002;IDEOGRAPHIC FULL STOP;Po;0;ON;;;;;N;IDEOGRAPHIC PERIOD;;;; +3003;DITTO MARK;Po;0;ON;;;;;N;;;;; +3004;JAPANESE INDUSTRIAL STANDARD SYMBOL;So;0;ON;;;;;N;;;;; +3005;IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;; +3006;IDEOGRAPHIC CLOSING MARK;Lo;0;L;;;;;N;;;;; +3007;IDEOGRAPHIC NUMBER ZERO;Nl;0;L;;;;0;N;;;;; +3008;LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING ANGLE BRACKET;;;; +3009;RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING ANGLE BRACKET;;;; +300A;LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING DOUBLE ANGLE BRACKET;;;; +300B;RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING DOUBLE ANGLE BRACKET;;;; +300C;LEFT CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING CORNER BRACKET;;;; +300D;RIGHT CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING CORNER BRACKET;;;; +300E;LEFT WHITE CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE CORNER BRACKET;;;; +300F;RIGHT WHITE CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE CORNER BRACKET;;;; +3010;LEFT BLACK LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING BLACK LENTICULAR BRACKET;;;; +3011;RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING BLACK LENTICULAR BRACKET;;;; +3012;POSTAL MARK;So;0;ON;;;;;N;;;;; +3013;GETA MARK;So;0;ON;;;;;N;;;;; +3014;LEFT TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING TORTOISE SHELL BRACKET;;;; +3015;RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING TORTOISE SHELL BRACKET;;;; +3016;LEFT WHITE LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE LENTICULAR BRACKET;;;; +3017;RIGHT WHITE LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE LENTICULAR BRACKET;;;; +3018;LEFT WHITE TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE TORTOISE SHELL BRACKET;;;; +3019;RIGHT WHITE TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE TORTOISE SHELL BRACKET;;;; +301A;LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE SQUARE BRACKET;;;; +301B;RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE SQUARE BRACKET;;;; +301C;WAVE DASH;Pd;0;ON;;;;;N;;;;; +301D;REVERSED DOUBLE PRIME QUOTATION MARK;Ps;0;ON;;;;;N;;;;; +301E;DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;; +301F;LOW DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;; +3020;POSTAL MARK FACE;So;0;ON;;;;;N;;;;; +3021;HANGZHOU NUMERAL ONE;Nl;0;L;;;;1;N;;;;; +3022;HANGZHOU NUMERAL TWO;Nl;0;L;;;;2;N;;;;; +3023;HANGZHOU NUMERAL THREE;Nl;0;L;;;;3;N;;;;; +3024;HANGZHOU NUMERAL FOUR;Nl;0;L;;;;4;N;;;;; +3025;HANGZHOU NUMERAL FIVE;Nl;0;L;;;;5;N;;;;; +3026;HANGZHOU NUMERAL SIX;Nl;0;L;;;;6;N;;;;; +3027;HANGZHOU NUMERAL SEVEN;Nl;0;L;;;;7;N;;;;; +3028;HANGZHOU NUMERAL EIGHT;Nl;0;L;;;;8;N;;;;; +3029;HANGZHOU NUMERAL NINE;Nl;0;L;;;;9;N;;;;; +302A;IDEOGRAPHIC LEVEL TONE MARK;Mn;218;NSM;;;;;N;;;;; +302B;IDEOGRAPHIC RISING TONE MARK;Mn;228;NSM;;;;;N;;;;; +302C;IDEOGRAPHIC DEPARTING TONE MARK;Mn;232;NSM;;;;;N;;;;; +302D;IDEOGRAPHIC ENTERING TONE MARK;Mn;222;NSM;;;;;N;;;;; +302E;HANGUL SINGLE DOT TONE MARK;Mc;224;L;;;;;N;;;;; +302F;HANGUL DOUBLE DOT TONE MARK;Mc;224;L;;;;;N;;;;; +3030;WAVY DASH;Pd;0;ON;;;;;N;;;;; +3031;VERTICAL KANA REPEAT MARK;Lm;0;L;;;;;N;;;;; +3032;VERTICAL KANA REPEAT WITH VOICED SOUND MARK;Lm;0;L;;;;;N;;;;; +3033;VERTICAL KANA REPEAT MARK UPPER HALF;Lm;0;L;;;;;N;;;;; +3034;VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF;Lm;0;L;;;;;N;;;;; +3035;VERTICAL KANA REPEAT MARK LOWER HALF;Lm;0;L;;;;;N;;;;; +3036;CIRCLED POSTAL MARK;So;0;ON; 3012;;;;N;;;;; +3037;IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL;So;0;ON;;;;;N;;;;; +3038;HANGZHOU NUMERAL TEN;Nl;0;L; 5341;;;10;N;;;;; +3039;HANGZHOU NUMERAL TWENTY;Nl;0;L; 5344;;;20;N;;;;; +303A;HANGZHOU NUMERAL THIRTY;Nl;0;L; 5345;;;30;N;;;;; +303B;VERTICAL IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;; +303C;MASU MARK;Lo;0;L;;;;;N;;;;; +303D;PART ALTERNATION MARK;Po;0;ON;;;;;N;;;;; +303E;IDEOGRAPHIC VARIATION INDICATOR;So;0;ON;;;;;N;;;;; +303F;IDEOGRAPHIC HALF FILL SPACE;So;0;ON;;;;;N;;;;; +3041;HIRAGANA LETTER SMALL A;Lo;0;L;;;;;N;;;;; +3042;HIRAGANA LETTER A;Lo;0;L;;;;;N;;;;; +3043;HIRAGANA LETTER SMALL I;Lo;0;L;;;;;N;;;;; +3044;HIRAGANA LETTER I;Lo;0;L;;;;;N;;;;; +3045;HIRAGANA LETTER SMALL U;Lo;0;L;;;;;N;;;;; +3046;HIRAGANA LETTER U;Lo;0;L;;;;;N;;;;; +3047;HIRAGANA LETTER SMALL E;Lo;0;L;;;;;N;;;;; +3048;HIRAGANA LETTER E;Lo;0;L;;;;;N;;;;; +3049;HIRAGANA LETTER SMALL O;Lo;0;L;;;;;N;;;;; +304A;HIRAGANA LETTER O;Lo;0;L;;;;;N;;;;; +304B;HIRAGANA LETTER KA;Lo;0;L;;;;;N;;;;; +304C;HIRAGANA LETTER GA;Lo;0;L;304B 3099;;;;N;;;;; +304D;HIRAGANA LETTER KI;Lo;0;L;;;;;N;;;;; +304E;HIRAGANA LETTER GI;Lo;0;L;304D 3099;;;;N;;;;; +304F;HIRAGANA LETTER KU;Lo;0;L;;;;;N;;;;; +3050;HIRAGANA LETTER GU;Lo;0;L;304F 3099;;;;N;;;;; +3051;HIRAGANA LETTER KE;Lo;0;L;;;;;N;;;;; +3052;HIRAGANA LETTER GE;Lo;0;L;3051 3099;;;;N;;;;; +3053;HIRAGANA LETTER KO;Lo;0;L;;;;;N;;;;; +3054;HIRAGANA LETTER GO;Lo;0;L;3053 3099;;;;N;;;;; +3055;HIRAGANA LETTER SA;Lo;0;L;;;;;N;;;;; +3056;HIRAGANA LETTER ZA;Lo;0;L;3055 3099;;;;N;;;;; +3057;HIRAGANA LETTER SI;Lo;0;L;;;;;N;;;;; +3058;HIRAGANA LETTER ZI;Lo;0;L;3057 3099;;;;N;;;;; +3059;HIRAGANA LETTER SU;Lo;0;L;;;;;N;;;;; +305A;HIRAGANA LETTER ZU;Lo;0;L;3059 3099;;;;N;;;;; +305B;HIRAGANA LETTER SE;Lo;0;L;;;;;N;;;;; +305C;HIRAGANA LETTER ZE;Lo;0;L;305B 3099;;;;N;;;;; +305D;HIRAGANA LETTER SO;Lo;0;L;;;;;N;;;;; +305E;HIRAGANA LETTER ZO;Lo;0;L;305D 3099;;;;N;;;;; +305F;HIRAGANA LETTER TA;Lo;0;L;;;;;N;;;;; +3060;HIRAGANA LETTER DA;Lo;0;L;305F 3099;;;;N;;;;; +3061;HIRAGANA LETTER TI;Lo;0;L;;;;;N;;;;; +3062;HIRAGANA LETTER DI;Lo;0;L;3061 3099;;;;N;;;;; +3063;HIRAGANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;; +3064;HIRAGANA LETTER TU;Lo;0;L;;;;;N;;;;; +3065;HIRAGANA LETTER DU;Lo;0;L;3064 3099;;;;N;;;;; +3066;HIRAGANA LETTER TE;Lo;0;L;;;;;N;;;;; +3067;HIRAGANA LETTER DE;Lo;0;L;3066 3099;;;;N;;;;; +3068;HIRAGANA LETTER TO;Lo;0;L;;;;;N;;;;; +3069;HIRAGANA LETTER DO;Lo;0;L;3068 3099;;;;N;;;;; +306A;HIRAGANA LETTER NA;Lo;0;L;;;;;N;;;;; +306B;HIRAGANA LETTER NI;Lo;0;L;;;;;N;;;;; +306C;HIRAGANA LETTER NU;Lo;0;L;;;;;N;;;;; +306D;HIRAGANA LETTER NE;Lo;0;L;;;;;N;;;;; +306E;HIRAGANA LETTER NO;Lo;0;L;;;;;N;;;;; +306F;HIRAGANA LETTER HA;Lo;0;L;;;;;N;;;;; +3070;HIRAGANA LETTER BA;Lo;0;L;306F 3099;;;;N;;;;; +3071;HIRAGANA LETTER PA;Lo;0;L;306F 309A;;;;N;;;;; +3072;HIRAGANA LETTER HI;Lo;0;L;;;;;N;;;;; +3073;HIRAGANA LETTER BI;Lo;0;L;3072 3099;;;;N;;;;; +3074;HIRAGANA LETTER PI;Lo;0;L;3072 309A;;;;N;;;;; +3075;HIRAGANA LETTER HU;Lo;0;L;;;;;N;;;;; +3076;HIRAGANA LETTER BU;Lo;0;L;3075 3099;;;;N;;;;; +3077;HIRAGANA LETTER PU;Lo;0;L;3075 309A;;;;N;;;;; +3078;HIRAGANA LETTER HE;Lo;0;L;;;;;N;;;;; +3079;HIRAGANA LETTER BE;Lo;0;L;3078 3099;;;;N;;;;; +307A;HIRAGANA LETTER PE;Lo;0;L;3078 309A;;;;N;;;;; +307B;HIRAGANA LETTER HO;Lo;0;L;;;;;N;;;;; +307C;HIRAGANA LETTER BO;Lo;0;L;307B 3099;;;;N;;;;; +307D;HIRAGANA LETTER PO;Lo;0;L;307B 309A;;;;N;;;;; +307E;HIRAGANA LETTER MA;Lo;0;L;;;;;N;;;;; +307F;HIRAGANA LETTER MI;Lo;0;L;;;;;N;;;;; +3080;HIRAGANA LETTER MU;Lo;0;L;;;;;N;;;;; +3081;HIRAGANA LETTER ME;Lo;0;L;;;;;N;;;;; +3082;HIRAGANA LETTER MO;Lo;0;L;;;;;N;;;;; +3083;HIRAGANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;; +3084;HIRAGANA LETTER YA;Lo;0;L;;;;;N;;;;; +3085;HIRAGANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;; +3086;HIRAGANA LETTER YU;Lo;0;L;;;;;N;;;;; +3087;HIRAGANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;; +3088;HIRAGANA LETTER YO;Lo;0;L;;;;;N;;;;; +3089;HIRAGANA LETTER RA;Lo;0;L;;;;;N;;;;; +308A;HIRAGANA LETTER RI;Lo;0;L;;;;;N;;;;; +308B;HIRAGANA LETTER RU;Lo;0;L;;;;;N;;;;; +308C;HIRAGANA LETTER RE;Lo;0;L;;;;;N;;;;; +308D;HIRAGANA LETTER RO;Lo;0;L;;;;;N;;;;; +308E;HIRAGANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;; +308F;HIRAGANA LETTER WA;Lo;0;L;;;;;N;;;;; +3090;HIRAGANA LETTER WI;Lo;0;L;;;;;N;;;;; +3091;HIRAGANA LETTER WE;Lo;0;L;;;;;N;;;;; +3092;HIRAGANA LETTER WO;Lo;0;L;;;;;N;;;;; +3093;HIRAGANA LETTER N;Lo;0;L;;;;;N;;;;; +3094;HIRAGANA LETTER VU;Lo;0;L;3046 3099;;;;N;;;;; +3095;HIRAGANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;; +3096;HIRAGANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;; +3099;COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA VOICED SOUND MARK;;;; +309A;COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;;;; +309B;KATAKANA-HIRAGANA VOICED SOUND MARK;Sk;0;ON; 0020 3099;;;;N;;;;; +309C;KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Sk;0;ON; 0020 309A;;;;N;;;;; +309D;HIRAGANA ITERATION MARK;Lm;0;L;;;;;N;;;;; +309E;HIRAGANA VOICED ITERATION MARK;Lm;0;L;309D 3099;;;;N;;;;; +309F;HIRAGANA DIGRAPH YORI;Lo;0;L; 3088 308A;;;;N;;;;; +30A0;KATAKANA-HIRAGANA DOUBLE HYPHEN;Pd;0;ON;;;;;N;;;;; +30A1;KATAKANA LETTER SMALL A;Lo;0;L;;;;;N;;;;; +30A2;KATAKANA LETTER A;Lo;0;L;;;;;N;;;;; +30A3;KATAKANA LETTER SMALL I;Lo;0;L;;;;;N;;;;; +30A4;KATAKANA LETTER I;Lo;0;L;;;;;N;;;;; +30A5;KATAKANA LETTER SMALL U;Lo;0;L;;;;;N;;;;; +30A6;KATAKANA LETTER U;Lo;0;L;;;;;N;;;;; +30A7;KATAKANA LETTER SMALL E;Lo;0;L;;;;;N;;;;; +30A8;KATAKANA LETTER E;Lo;0;L;;;;;N;;;;; +30A9;KATAKANA LETTER SMALL O;Lo;0;L;;;;;N;;;;; +30AA;KATAKANA LETTER O;Lo;0;L;;;;;N;;;;; +30AB;KATAKANA LETTER KA;Lo;0;L;;;;;N;;;;; +30AC;KATAKANA LETTER GA;Lo;0;L;30AB 3099;;;;N;;;;; +30AD;KATAKANA LETTER KI;Lo;0;L;;;;;N;;;;; +30AE;KATAKANA LETTER GI;Lo;0;L;30AD 3099;;;;N;;;;; +30AF;KATAKANA LETTER KU;Lo;0;L;;;;;N;;;;; +30B0;KATAKANA LETTER GU;Lo;0;L;30AF 3099;;;;N;;;;; +30B1;KATAKANA LETTER KE;Lo;0;L;;;;;N;;;;; +30B2;KATAKANA LETTER GE;Lo;0;L;30B1 3099;;;;N;;;;; +30B3;KATAKANA LETTER KO;Lo;0;L;;;;;N;;;;; +30B4;KATAKANA LETTER GO;Lo;0;L;30B3 3099;;;;N;;;;; +30B5;KATAKANA LETTER SA;Lo;0;L;;;;;N;;;;; +30B6;KATAKANA LETTER ZA;Lo;0;L;30B5 3099;;;;N;;;;; +30B7;KATAKANA LETTER SI;Lo;0;L;;;;;N;;;;; +30B8;KATAKANA LETTER ZI;Lo;0;L;30B7 3099;;;;N;;;;; +30B9;KATAKANA LETTER SU;Lo;0;L;;;;;N;;;;; +30BA;KATAKANA LETTER ZU;Lo;0;L;30B9 3099;;;;N;;;;; +30BB;KATAKANA LETTER SE;Lo;0;L;;;;;N;;;;; +30BC;KATAKANA LETTER ZE;Lo;0;L;30BB 3099;;;;N;;;;; +30BD;KATAKANA LETTER SO;Lo;0;L;;;;;N;;;;; +30BE;KATAKANA LETTER ZO;Lo;0;L;30BD 3099;;;;N;;;;; +30BF;KATAKANA LETTER TA;Lo;0;L;;;;;N;;;;; +30C0;KATAKANA LETTER DA;Lo;0;L;30BF 3099;;;;N;;;;; +30C1;KATAKANA LETTER TI;Lo;0;L;;;;;N;;;;; +30C2;KATAKANA LETTER DI;Lo;0;L;30C1 3099;;;;N;;;;; +30C3;KATAKANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;; +30C4;KATAKANA LETTER TU;Lo;0;L;;;;;N;;;;; +30C5;KATAKANA LETTER DU;Lo;0;L;30C4 3099;;;;N;;;;; +30C6;KATAKANA LETTER TE;Lo;0;L;;;;;N;;;;; +30C7;KATAKANA LETTER DE;Lo;0;L;30C6 3099;;;;N;;;;; +30C8;KATAKANA LETTER TO;Lo;0;L;;;;;N;;;;; +30C9;KATAKANA LETTER DO;Lo;0;L;30C8 3099;;;;N;;;;; +30CA;KATAKANA LETTER NA;Lo;0;L;;;;;N;;;;; +30CB;KATAKANA LETTER NI;Lo;0;L;;;;;N;;;;; +30CC;KATAKANA LETTER NU;Lo;0;L;;;;;N;;;;; +30CD;KATAKANA LETTER NE;Lo;0;L;;;;;N;;;;; +30CE;KATAKANA LETTER NO;Lo;0;L;;;;;N;;;;; +30CF;KATAKANA LETTER HA;Lo;0;L;;;;;N;;;;; +30D0;KATAKANA LETTER BA;Lo;0;L;30CF 3099;;;;N;;;;; +30D1;KATAKANA LETTER PA;Lo;0;L;30CF 309A;;;;N;;;;; +30D2;KATAKANA LETTER HI;Lo;0;L;;;;;N;;;;; +30D3;KATAKANA LETTER BI;Lo;0;L;30D2 3099;;;;N;;;;; +30D4;KATAKANA LETTER PI;Lo;0;L;30D2 309A;;;;N;;;;; +30D5;KATAKANA LETTER HU;Lo;0;L;;;;;N;;;;; +30D6;KATAKANA LETTER BU;Lo;0;L;30D5 3099;;;;N;;;;; +30D7;KATAKANA LETTER PU;Lo;0;L;30D5 309A;;;;N;;;;; +30D8;KATAKANA LETTER HE;Lo;0;L;;;;;N;;;;; +30D9;KATAKANA LETTER BE;Lo;0;L;30D8 3099;;;;N;;;;; +30DA;KATAKANA LETTER PE;Lo;0;L;30D8 309A;;;;N;;;;; +30DB;KATAKANA LETTER HO;Lo;0;L;;;;;N;;;;; +30DC;KATAKANA LETTER BO;Lo;0;L;30DB 3099;;;;N;;;;; +30DD;KATAKANA LETTER PO;Lo;0;L;30DB 309A;;;;N;;;;; +30DE;KATAKANA LETTER MA;Lo;0;L;;;;;N;;;;; +30DF;KATAKANA LETTER MI;Lo;0;L;;;;;N;;;;; +30E0;KATAKANA LETTER MU;Lo;0;L;;;;;N;;;;; +30E1;KATAKANA LETTER ME;Lo;0;L;;;;;N;;;;; +30E2;KATAKANA LETTER MO;Lo;0;L;;;;;N;;;;; +30E3;KATAKANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;; +30E4;KATAKANA LETTER YA;Lo;0;L;;;;;N;;;;; +30E5;KATAKANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;; +30E6;KATAKANA LETTER YU;Lo;0;L;;;;;N;;;;; +30E7;KATAKANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;; +30E8;KATAKANA LETTER YO;Lo;0;L;;;;;N;;;;; +30E9;KATAKANA LETTER RA;Lo;0;L;;;;;N;;;;; +30EA;KATAKANA LETTER RI;Lo;0;L;;;;;N;;;;; +30EB;KATAKANA LETTER RU;Lo;0;L;;;;;N;;;;; +30EC;KATAKANA LETTER RE;Lo;0;L;;;;;N;;;;; +30ED;KATAKANA LETTER RO;Lo;0;L;;;;;N;;;;; +30EE;KATAKANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;; +30EF;KATAKANA LETTER WA;Lo;0;L;;;;;N;;;;; +30F0;KATAKANA LETTER WI;Lo;0;L;;;;;N;;;;; +30F1;KATAKANA LETTER WE;Lo;0;L;;;;;N;;;;; +30F2;KATAKANA LETTER WO;Lo;0;L;;;;;N;;;;; +30F3;KATAKANA LETTER N;Lo;0;L;;;;;N;;;;; +30F4;KATAKANA LETTER VU;Lo;0;L;30A6 3099;;;;N;;;;; +30F5;KATAKANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;; +30F6;KATAKANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;; +30F7;KATAKANA LETTER VA;Lo;0;L;30EF 3099;;;;N;;;;; +30F8;KATAKANA LETTER VI;Lo;0;L;30F0 3099;;;;N;;;;; +30F9;KATAKANA LETTER VE;Lo;0;L;30F1 3099;;;;N;;;;; +30FA;KATAKANA LETTER VO;Lo;0;L;30F2 3099;;;;N;;;;; +30FB;KATAKANA MIDDLE DOT;Po;0;ON;;;;;N;;;;; +30FC;KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L;;;;;N;;;;; +30FD;KATAKANA ITERATION MARK;Lm;0;L;;;;;N;;;;; +30FE;KATAKANA VOICED ITERATION MARK;Lm;0;L;30FD 3099;;;;N;;;;; +30FF;KATAKANA DIGRAPH KOTO;Lo;0;L; 30B3 30C8;;;;N;;;;; +3105;BOPOMOFO LETTER B;Lo;0;L;;;;;N;;;;; +3106;BOPOMOFO LETTER P;Lo;0;L;;;;;N;;;;; +3107;BOPOMOFO LETTER M;Lo;0;L;;;;;N;;;;; +3108;BOPOMOFO LETTER F;Lo;0;L;;;;;N;;;;; +3109;BOPOMOFO LETTER D;Lo;0;L;;;;;N;;;;; +310A;BOPOMOFO LETTER T;Lo;0;L;;;;;N;;;;; +310B;BOPOMOFO LETTER N;Lo;0;L;;;;;N;;;;; +310C;BOPOMOFO LETTER L;Lo;0;L;;;;;N;;;;; +310D;BOPOMOFO LETTER G;Lo;0;L;;;;;N;;;;; +310E;BOPOMOFO LETTER K;Lo;0;L;;;;;N;;;;; +310F;BOPOMOFO LETTER H;Lo;0;L;;;;;N;;;;; +3110;BOPOMOFO LETTER J;Lo;0;L;;;;;N;;;;; +3111;BOPOMOFO LETTER Q;Lo;0;L;;;;;N;;;;; +3112;BOPOMOFO LETTER X;Lo;0;L;;;;;N;;;;; +3113;BOPOMOFO LETTER ZH;Lo;0;L;;;;;N;;;;; +3114;BOPOMOFO LETTER CH;Lo;0;L;;;;;N;;;;; +3115;BOPOMOFO LETTER SH;Lo;0;L;;;;;N;;;;; +3116;BOPOMOFO LETTER R;Lo;0;L;;;;;N;;;;; +3117;BOPOMOFO LETTER Z;Lo;0;L;;;;;N;;;;; +3118;BOPOMOFO LETTER C;Lo;0;L;;;;;N;;;;; +3119;BOPOMOFO LETTER S;Lo;0;L;;;;;N;;;;; +311A;BOPOMOFO LETTER A;Lo;0;L;;;;;N;;;;; +311B;BOPOMOFO LETTER O;Lo;0;L;;;;;N;;;;; +311C;BOPOMOFO LETTER E;Lo;0;L;;;;;N;;;;; +311D;BOPOMOFO LETTER EH;Lo;0;L;;;;;N;;;;; +311E;BOPOMOFO LETTER AI;Lo;0;L;;;;;N;;;;; +311F;BOPOMOFO LETTER EI;Lo;0;L;;;;;N;;;;; +3120;BOPOMOFO LETTER AU;Lo;0;L;;;;;N;;;;; +3121;BOPOMOFO LETTER OU;Lo;0;L;;;;;N;;;;; +3122;BOPOMOFO LETTER AN;Lo;0;L;;;;;N;;;;; +3123;BOPOMOFO LETTER EN;Lo;0;L;;;;;N;;;;; +3124;BOPOMOFO LETTER ANG;Lo;0;L;;;;;N;;;;; +3125;BOPOMOFO LETTER ENG;Lo;0;L;;;;;N;;;;; +3126;BOPOMOFO LETTER ER;Lo;0;L;;;;;N;;;;; +3127;BOPOMOFO LETTER I;Lo;0;L;;;;;N;;;;; +3128;BOPOMOFO LETTER U;Lo;0;L;;;;;N;;;;; +3129;BOPOMOFO LETTER IU;Lo;0;L;;;;;N;;;;; +312A;BOPOMOFO LETTER V;Lo;0;L;;;;;N;;;;; +312B;BOPOMOFO LETTER NG;Lo;0;L;;;;;N;;;;; +312C;BOPOMOFO LETTER GN;Lo;0;L;;;;;N;;;;; +312D;BOPOMOFO LETTER IH;Lo;0;L;;;;;N;;;;; +312E;BOPOMOFO LETTER O WITH DOT ABOVE;Lo;0;L;;;;;N;;;;; +312F;BOPOMOFO LETTER NN;Lo;0;L;;;;;N;;;;; +3131;HANGUL LETTER KIYEOK;Lo;0;L; 1100;;;;N;HANGUL LETTER GIYEOG;;;; +3132;HANGUL LETTER SSANGKIYEOK;Lo;0;L; 1101;;;;N;HANGUL LETTER SSANG GIYEOG;;;; +3133;HANGUL LETTER KIYEOK-SIOS;Lo;0;L; 11AA;;;;N;HANGUL LETTER GIYEOG SIOS;;;; +3134;HANGUL LETTER NIEUN;Lo;0;L; 1102;;;;N;;;;; +3135;HANGUL LETTER NIEUN-CIEUC;Lo;0;L; 11AC;;;;N;HANGUL LETTER NIEUN JIEUJ;;;; +3136;HANGUL LETTER NIEUN-HIEUH;Lo;0;L; 11AD;;;;N;HANGUL LETTER NIEUN HIEUH;;;; +3137;HANGUL LETTER TIKEUT;Lo;0;L; 1103;;;;N;HANGUL LETTER DIGEUD;;;; +3138;HANGUL LETTER SSANGTIKEUT;Lo;0;L; 1104;;;;N;HANGUL LETTER SSANG DIGEUD;;;; +3139;HANGUL LETTER RIEUL;Lo;0;L; 1105;;;;N;HANGUL LETTER LIEUL;;;; +313A;HANGUL LETTER RIEUL-KIYEOK;Lo;0;L; 11B0;;;;N;HANGUL LETTER LIEUL GIYEOG;;;; +313B;HANGUL LETTER RIEUL-MIEUM;Lo;0;L; 11B1;;;;N;HANGUL LETTER LIEUL MIEUM;;;; +313C;HANGUL LETTER RIEUL-PIEUP;Lo;0;L; 11B2;;;;N;HANGUL LETTER LIEUL BIEUB;;;; +313D;HANGUL LETTER RIEUL-SIOS;Lo;0;L; 11B3;;;;N;HANGUL LETTER LIEUL SIOS;;;; +313E;HANGUL LETTER RIEUL-THIEUTH;Lo;0;L; 11B4;;;;N;HANGUL LETTER LIEUL TIEUT;;;; +313F;HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L; 11B5;;;;N;HANGUL LETTER LIEUL PIEUP;;;; +3140;HANGUL LETTER RIEUL-HIEUH;Lo;0;L; 111A;;;;N;HANGUL LETTER LIEUL HIEUH;;;; +3141;HANGUL LETTER MIEUM;Lo;0;L; 1106;;;;N;;;;; +3142;HANGUL LETTER PIEUP;Lo;0;L; 1107;;;;N;HANGUL LETTER BIEUB;;;; +3143;HANGUL LETTER SSANGPIEUP;Lo;0;L; 1108;;;;N;HANGUL LETTER SSANG BIEUB;;;; +3144;HANGUL LETTER PIEUP-SIOS;Lo;0;L; 1121;;;;N;HANGUL LETTER BIEUB SIOS;;;; +3145;HANGUL LETTER SIOS;Lo;0;L; 1109;;;;N;;;;; +3146;HANGUL LETTER SSANGSIOS;Lo;0;L; 110A;;;;N;HANGUL LETTER SSANG SIOS;;;; +3147;HANGUL LETTER IEUNG;Lo;0;L; 110B;;;;N;;;;; +3148;HANGUL LETTER CIEUC;Lo;0;L; 110C;;;;N;HANGUL LETTER JIEUJ;;;; +3149;HANGUL LETTER SSANGCIEUC;Lo;0;L; 110D;;;;N;HANGUL LETTER SSANG JIEUJ;;;; +314A;HANGUL LETTER CHIEUCH;Lo;0;L; 110E;;;;N;HANGUL LETTER CIEUC;;;; +314B;HANGUL LETTER KHIEUKH;Lo;0;L; 110F;;;;N;HANGUL LETTER KIYEOK;;;; +314C;HANGUL LETTER THIEUTH;Lo;0;L; 1110;;;;N;HANGUL LETTER TIEUT;;;; +314D;HANGUL LETTER PHIEUPH;Lo;0;L; 1111;;;;N;HANGUL LETTER PIEUP;;;; +314E;HANGUL LETTER HIEUH;Lo;0;L; 1112;;;;N;;;;; +314F;HANGUL LETTER A;Lo;0;L; 1161;;;;N;;;;; +3150;HANGUL LETTER AE;Lo;0;L; 1162;;;;N;;;;; +3151;HANGUL LETTER YA;Lo;0;L; 1163;;;;N;;;;; +3152;HANGUL LETTER YAE;Lo;0;L; 1164;;;;N;;;;; +3153;HANGUL LETTER EO;Lo;0;L; 1165;;;;N;;;;; +3154;HANGUL LETTER E;Lo;0;L; 1166;;;;N;;;;; +3155;HANGUL LETTER YEO;Lo;0;L; 1167;;;;N;;;;; +3156;HANGUL LETTER YE;Lo;0;L; 1168;;;;N;;;;; +3157;HANGUL LETTER O;Lo;0;L; 1169;;;;N;;;;; +3158;HANGUL LETTER WA;Lo;0;L; 116A;;;;N;;;;; +3159;HANGUL LETTER WAE;Lo;0;L; 116B;;;;N;;;;; +315A;HANGUL LETTER OE;Lo;0;L; 116C;;;;N;;;;; +315B;HANGUL LETTER YO;Lo;0;L; 116D;;;;N;;;;; +315C;HANGUL LETTER U;Lo;0;L; 116E;;;;N;;;;; +315D;HANGUL LETTER WEO;Lo;0;L; 116F;;;;N;;;;; +315E;HANGUL LETTER WE;Lo;0;L; 1170;;;;N;;;;; +315F;HANGUL LETTER WI;Lo;0;L; 1171;;;;N;;;;; +3160;HANGUL LETTER YU;Lo;0;L; 1172;;;;N;;;;; +3161;HANGUL LETTER EU;Lo;0;L; 1173;;;;N;;;;; +3162;HANGUL LETTER YI;Lo;0;L; 1174;;;;N;;;;; +3163;HANGUL LETTER I;Lo;0;L; 1175;;;;N;;;;; +3164;HANGUL FILLER;Lo;0;L; 1160;;;;N;HANGUL CAE OM;;;; +3165;HANGUL LETTER SSANGNIEUN;Lo;0;L; 1114;;;;N;HANGUL LETTER SSANG NIEUN;;;; +3166;HANGUL LETTER NIEUN-TIKEUT;Lo;0;L; 1115;;;;N;HANGUL LETTER NIEUN DIGEUD;;;; +3167;HANGUL LETTER NIEUN-SIOS;Lo;0;L; 11C7;;;;N;HANGUL LETTER NIEUN SIOS;;;; +3168;HANGUL LETTER NIEUN-PANSIOS;Lo;0;L; 11C8;;;;N;HANGUL LETTER NIEUN BAN CHI EUM;;;; +3169;HANGUL LETTER RIEUL-KIYEOK-SIOS;Lo;0;L; 11CC;;;;N;HANGUL LETTER LIEUL GIYEOG SIOS;;;; +316A;HANGUL LETTER RIEUL-TIKEUT;Lo;0;L; 11CE;;;;N;HANGUL LETTER LIEUL DIGEUD;;;; +316B;HANGUL LETTER RIEUL-PIEUP-SIOS;Lo;0;L; 11D3;;;;N;HANGUL LETTER LIEUL BIEUB SIOS;;;; +316C;HANGUL LETTER RIEUL-PANSIOS;Lo;0;L; 11D7;;;;N;HANGUL LETTER LIEUL BAN CHI EUM;;;; +316D;HANGUL LETTER RIEUL-YEORINHIEUH;Lo;0;L; 11D9;;;;N;HANGUL LETTER LIEUL YEOLIN HIEUH;;;; +316E;HANGUL LETTER MIEUM-PIEUP;Lo;0;L; 111C;;;;N;HANGUL LETTER MIEUM BIEUB;;;; +316F;HANGUL LETTER MIEUM-SIOS;Lo;0;L; 11DD;;;;N;HANGUL LETTER MIEUM SIOS;;;; +3170;HANGUL LETTER MIEUM-PANSIOS;Lo;0;L; 11DF;;;;N;HANGUL LETTER BIEUB BAN CHI EUM;;;; +3171;HANGUL LETTER KAPYEOUNMIEUM;Lo;0;L; 111D;;;;N;HANGUL LETTER MIEUM SUN GYEONG EUM;;;; +3172;HANGUL LETTER PIEUP-KIYEOK;Lo;0;L; 111E;;;;N;HANGUL LETTER BIEUB GIYEOG;;;; +3173;HANGUL LETTER PIEUP-TIKEUT;Lo;0;L; 1120;;;;N;HANGUL LETTER BIEUB DIGEUD;;;; +3174;HANGUL LETTER PIEUP-SIOS-KIYEOK;Lo;0;L; 1122;;;;N;HANGUL LETTER BIEUB SIOS GIYEOG;;;; +3175;HANGUL LETTER PIEUP-SIOS-TIKEUT;Lo;0;L; 1123;;;;N;HANGUL LETTER BIEUB SIOS DIGEUD;;;; +3176;HANGUL LETTER PIEUP-CIEUC;Lo;0;L; 1127;;;;N;HANGUL LETTER BIEUB JIEUJ;;;; +3177;HANGUL LETTER PIEUP-THIEUTH;Lo;0;L; 1129;;;;N;HANGUL LETTER BIEUB TIEUT;;;; +3178;HANGUL LETTER KAPYEOUNPIEUP;Lo;0;L; 112B;;;;N;HANGUL LETTER BIEUB SUN GYEONG EUM;;;; +3179;HANGUL LETTER KAPYEOUNSSANGPIEUP;Lo;0;L; 112C;;;;N;HANGUL LETTER SSANG BIEUB SUN GYEONG EUM;;;; +317A;HANGUL LETTER SIOS-KIYEOK;Lo;0;L; 112D;;;;N;HANGUL LETTER SIOS GIYEOG;;;; +317B;HANGUL LETTER SIOS-NIEUN;Lo;0;L; 112E;;;;N;HANGUL LETTER SIOS NIEUN;;;; +317C;HANGUL LETTER SIOS-TIKEUT;Lo;0;L; 112F;;;;N;HANGUL LETTER SIOS DIGEUD;;;; +317D;HANGUL LETTER SIOS-PIEUP;Lo;0;L; 1132;;;;N;HANGUL LETTER SIOS BIEUB;;;; +317E;HANGUL LETTER SIOS-CIEUC;Lo;0;L; 1136;;;;N;HANGUL LETTER SIOS JIEUJ;;;; +317F;HANGUL LETTER PANSIOS;Lo;0;L; 1140;;;;N;HANGUL LETTER BAN CHI EUM;;;; +3180;HANGUL LETTER SSANGIEUNG;Lo;0;L; 1147;;;;N;HANGUL LETTER SSANG IEUNG;;;; +3181;HANGUL LETTER YESIEUNG;Lo;0;L; 114C;;;;N;HANGUL LETTER NGIEUNG;;;; +3182;HANGUL LETTER YESIEUNG-SIOS;Lo;0;L; 11F1;;;;N;HANGUL LETTER NGIEUNG SIOS;;;; +3183;HANGUL LETTER YESIEUNG-PANSIOS;Lo;0;L; 11F2;;;;N;HANGUL LETTER NGIEUNG BAN CHI EUM;;;; +3184;HANGUL LETTER KAPYEOUNPHIEUPH;Lo;0;L; 1157;;;;N;HANGUL LETTER PIEUP SUN GYEONG EUM;;;; +3185;HANGUL LETTER SSANGHIEUH;Lo;0;L; 1158;;;;N;HANGUL LETTER SSANG HIEUH;;;; +3186;HANGUL LETTER YEORINHIEUH;Lo;0;L; 1159;;;;N;HANGUL LETTER YEOLIN HIEUH;;;; +3187;HANGUL LETTER YO-YA;Lo;0;L; 1184;;;;N;HANGUL LETTER YOYA;;;; +3188;HANGUL LETTER YO-YAE;Lo;0;L; 1185;;;;N;HANGUL LETTER YOYAE;;;; +3189;HANGUL LETTER YO-I;Lo;0;L; 1188;;;;N;HANGUL LETTER YOI;;;; +318A;HANGUL LETTER YU-YEO;Lo;0;L; 1191;;;;N;HANGUL LETTER YUYEO;;;; +318B;HANGUL LETTER YU-YE;Lo;0;L; 1192;;;;N;HANGUL LETTER YUYE;;;; +318C;HANGUL LETTER YU-I;Lo;0;L; 1194;;;;N;HANGUL LETTER YUI;;;; +318D;HANGUL LETTER ARAEA;Lo;0;L; 119E;;;;N;HANGUL LETTER ALAE A;;;; +318E;HANGUL LETTER ARAEAE;Lo;0;L; 11A1;;;;N;HANGUL LETTER ALAE AE;;;; +3190;IDEOGRAPHIC ANNOTATION LINKING MARK;So;0;L;;;;;N;KANBUN TATETEN;;;; +3191;IDEOGRAPHIC ANNOTATION REVERSE MARK;So;0;L;;;;;N;KAERITEN RE;;;; +3192;IDEOGRAPHIC ANNOTATION ONE MARK;No;0;L; 4E00;;;1;N;KAERITEN ITI;;;; +3193;IDEOGRAPHIC ANNOTATION TWO MARK;No;0;L; 4E8C;;;2;N;KAERITEN NI;;;; +3194;IDEOGRAPHIC ANNOTATION THREE MARK;No;0;L; 4E09;;;3;N;KAERITEN SAN;;;; +3195;IDEOGRAPHIC ANNOTATION FOUR MARK;No;0;L; 56DB;;;4;N;KAERITEN SI;;;; +3196;IDEOGRAPHIC ANNOTATION TOP MARK;So;0;L; 4E0A;;;;N;KAERITEN ZYOU;;;; +3197;IDEOGRAPHIC ANNOTATION MIDDLE MARK;So;0;L; 4E2D;;;;N;KAERITEN TYUU;;;; +3198;IDEOGRAPHIC ANNOTATION BOTTOM MARK;So;0;L; 4E0B;;;;N;KAERITEN GE;;;; +3199;IDEOGRAPHIC ANNOTATION FIRST MARK;So;0;L; 7532;;;;N;KAERITEN KOU;;;; +319A;IDEOGRAPHIC ANNOTATION SECOND MARK;So;0;L; 4E59;;;;N;KAERITEN OTU;;;; +319B;IDEOGRAPHIC ANNOTATION THIRD MARK;So;0;L; 4E19;;;;N;KAERITEN HEI;;;; +319C;IDEOGRAPHIC ANNOTATION FOURTH MARK;So;0;L; 4E01;;;;N;KAERITEN TEI;;;; +319D;IDEOGRAPHIC ANNOTATION HEAVEN MARK;So;0;L; 5929;;;;N;KAERITEN TEN;;;; +319E;IDEOGRAPHIC ANNOTATION EARTH MARK;So;0;L; 5730;;;;N;KAERITEN TI;;;; +319F;IDEOGRAPHIC ANNOTATION MAN MARK;So;0;L; 4EBA;;;;N;KAERITEN ZIN;;;; +31A0;BOPOMOFO LETTER BU;Lo;0;L;;;;;N;;;;; +31A1;BOPOMOFO LETTER ZI;Lo;0;L;;;;;N;;;;; +31A2;BOPOMOFO LETTER JI;Lo;0;L;;;;;N;;;;; +31A3;BOPOMOFO LETTER GU;Lo;0;L;;;;;N;;;;; +31A4;BOPOMOFO LETTER EE;Lo;0;L;;;;;N;;;;; +31A5;BOPOMOFO LETTER ENN;Lo;0;L;;;;;N;;;;; +31A6;BOPOMOFO LETTER OO;Lo;0;L;;;;;N;;;;; +31A7;BOPOMOFO LETTER ONN;Lo;0;L;;;;;N;;;;; +31A8;BOPOMOFO LETTER IR;Lo;0;L;;;;;N;;;;; +31A9;BOPOMOFO LETTER ANN;Lo;0;L;;;;;N;;;;; +31AA;BOPOMOFO LETTER INN;Lo;0;L;;;;;N;;;;; +31AB;BOPOMOFO LETTER UNN;Lo;0;L;;;;;N;;;;; +31AC;BOPOMOFO LETTER IM;Lo;0;L;;;;;N;;;;; +31AD;BOPOMOFO LETTER NGG;Lo;0;L;;;;;N;;;;; +31AE;BOPOMOFO LETTER AINN;Lo;0;L;;;;;N;;;;; +31AF;BOPOMOFO LETTER AUNN;Lo;0;L;;;;;N;;;;; +31B0;BOPOMOFO LETTER AM;Lo;0;L;;;;;N;;;;; +31B1;BOPOMOFO LETTER OM;Lo;0;L;;;;;N;;;;; +31B2;BOPOMOFO LETTER ONG;Lo;0;L;;;;;N;;;;; +31B3;BOPOMOFO LETTER INNN;Lo;0;L;;;;;N;;;;; +31B4;BOPOMOFO FINAL LETTER P;Lo;0;L;;;;;N;;;;; +31B5;BOPOMOFO FINAL LETTER T;Lo;0;L;;;;;N;;;;; +31B6;BOPOMOFO FINAL LETTER K;Lo;0;L;;;;;N;;;;; +31B7;BOPOMOFO FINAL LETTER H;Lo;0;L;;;;;N;;;;; +31B8;BOPOMOFO LETTER GH;Lo;0;L;;;;;N;;;;; +31B9;BOPOMOFO LETTER LH;Lo;0;L;;;;;N;;;;; +31BA;BOPOMOFO LETTER ZY;Lo;0;L;;;;;N;;;;; +31C0;CJK STROKE T;So;0;ON;;;;;N;;;;; +31C1;CJK STROKE WG;So;0;ON;;;;;N;;;;; +31C2;CJK STROKE XG;So;0;ON;;;;;N;;;;; +31C3;CJK STROKE BXG;So;0;ON;;;;;N;;;;; +31C4;CJK STROKE SW;So;0;ON;;;;;N;;;;; +31C5;CJK STROKE HZZ;So;0;ON;;;;;N;;;;; +31C6;CJK STROKE HZG;So;0;ON;;;;;N;;;;; +31C7;CJK STROKE HP;So;0;ON;;;;;N;;;;; +31C8;CJK STROKE HZWG;So;0;ON;;;;;N;;;;; +31C9;CJK STROKE SZWG;So;0;ON;;;;;N;;;;; +31CA;CJK STROKE HZT;So;0;ON;;;;;N;;;;; +31CB;CJK STROKE HZZP;So;0;ON;;;;;N;;;;; +31CC;CJK STROKE HPWG;So;0;ON;;;;;N;;;;; +31CD;CJK STROKE HZW;So;0;ON;;;;;N;;;;; +31CE;CJK STROKE HZZZ;So;0;ON;;;;;N;;;;; +31CF;CJK STROKE N;So;0;ON;;;;;N;;;;; +31D0;CJK STROKE H;So;0;ON;;;;;N;;;;; +31D1;CJK STROKE S;So;0;ON;;;;;N;;;;; +31D2;CJK STROKE P;So;0;ON;;;;;N;;;;; +31D3;CJK STROKE SP;So;0;ON;;;;;N;;;;; +31D4;CJK STROKE D;So;0;ON;;;;;N;;;;; +31D5;CJK STROKE HZ;So;0;ON;;;;;N;;;;; +31D6;CJK STROKE HG;So;0;ON;;;;;N;;;;; +31D7;CJK STROKE SZ;So;0;ON;;;;;N;;;;; +31D8;CJK STROKE SWZ;So;0;ON;;;;;N;;;;; +31D9;CJK STROKE ST;So;0;ON;;;;;N;;;;; +31DA;CJK STROKE SG;So;0;ON;;;;;N;;;;; +31DB;CJK STROKE PD;So;0;ON;;;;;N;;;;; +31DC;CJK STROKE PZ;So;0;ON;;;;;N;;;;; +31DD;CJK STROKE TN;So;0;ON;;;;;N;;;;; +31DE;CJK STROKE SZZ;So;0;ON;;;;;N;;;;; +31DF;CJK STROKE SWG;So;0;ON;;;;;N;;;;; +31E0;CJK STROKE HXWG;So;0;ON;;;;;N;;;;; +31E1;CJK STROKE HZZZG;So;0;ON;;;;;N;;;;; +31E2;CJK STROKE PG;So;0;ON;;;;;N;;;;; +31E3;CJK STROKE Q;So;0;ON;;;;;N;;;;; +31F0;KATAKANA LETTER SMALL KU;Lo;0;L;;;;;N;;;;; +31F1;KATAKANA LETTER SMALL SI;Lo;0;L;;;;;N;;;;; +31F2;KATAKANA LETTER SMALL SU;Lo;0;L;;;;;N;;;;; +31F3;KATAKANA LETTER SMALL TO;Lo;0;L;;;;;N;;;;; +31F4;KATAKANA LETTER SMALL NU;Lo;0;L;;;;;N;;;;; +31F5;KATAKANA LETTER SMALL HA;Lo;0;L;;;;;N;;;;; +31F6;KATAKANA LETTER SMALL HI;Lo;0;L;;;;;N;;;;; +31F7;KATAKANA LETTER SMALL HU;Lo;0;L;;;;;N;;;;; +31F8;KATAKANA LETTER SMALL HE;Lo;0;L;;;;;N;;;;; +31F9;KATAKANA LETTER SMALL HO;Lo;0;L;;;;;N;;;;; +31FA;KATAKANA LETTER SMALL MU;Lo;0;L;;;;;N;;;;; +31FB;KATAKANA LETTER SMALL RA;Lo;0;L;;;;;N;;;;; +31FC;KATAKANA LETTER SMALL RI;Lo;0;L;;;;;N;;;;; +31FD;KATAKANA LETTER SMALL RU;Lo;0;L;;;;;N;;;;; +31FE;KATAKANA LETTER SMALL RE;Lo;0;L;;;;;N;;;;; +31FF;KATAKANA LETTER SMALL RO;Lo;0;L;;;;;N;;;;; +3200;PARENTHESIZED HANGUL KIYEOK;So;0;L; 0028 1100 0029;;;;N;PARENTHESIZED HANGUL GIYEOG;;;; +3201;PARENTHESIZED HANGUL NIEUN;So;0;L; 0028 1102 0029;;;;N;;;;; +3202;PARENTHESIZED HANGUL TIKEUT;So;0;L; 0028 1103 0029;;;;N;PARENTHESIZED HANGUL DIGEUD;;;; +3203;PARENTHESIZED HANGUL RIEUL;So;0;L; 0028 1105 0029;;;;N;PARENTHESIZED HANGUL LIEUL;;;; +3204;PARENTHESIZED HANGUL MIEUM;So;0;L; 0028 1106 0029;;;;N;;;;; +3205;PARENTHESIZED HANGUL PIEUP;So;0;L; 0028 1107 0029;;;;N;PARENTHESIZED HANGUL BIEUB;;;; +3206;PARENTHESIZED HANGUL SIOS;So;0;L; 0028 1109 0029;;;;N;;;;; +3207;PARENTHESIZED HANGUL IEUNG;So;0;L; 0028 110B 0029;;;;N;;;;; +3208;PARENTHESIZED HANGUL CIEUC;So;0;L; 0028 110C 0029;;;;N;PARENTHESIZED HANGUL JIEUJ;;;; +3209;PARENTHESIZED HANGUL CHIEUCH;So;0;L; 0028 110E 0029;;;;N;PARENTHESIZED HANGUL CIEUC;;;; +320A;PARENTHESIZED HANGUL KHIEUKH;So;0;L; 0028 110F 0029;;;;N;PARENTHESIZED HANGUL KIYEOK;;;; +320B;PARENTHESIZED HANGUL THIEUTH;So;0;L; 0028 1110 0029;;;;N;PARENTHESIZED HANGUL TIEUT;;;; +320C;PARENTHESIZED HANGUL PHIEUPH;So;0;L; 0028 1111 0029;;;;N;PARENTHESIZED HANGUL PIEUP;;;; +320D;PARENTHESIZED HANGUL HIEUH;So;0;L; 0028 1112 0029;;;;N;;;;; +320E;PARENTHESIZED HANGUL KIYEOK A;So;0;L; 0028 1100 1161 0029;;;;N;PARENTHESIZED HANGUL GA;;;; +320F;PARENTHESIZED HANGUL NIEUN A;So;0;L; 0028 1102 1161 0029;;;;N;PARENTHESIZED HANGUL NA;;;; +3210;PARENTHESIZED HANGUL TIKEUT A;So;0;L; 0028 1103 1161 0029;;;;N;PARENTHESIZED HANGUL DA;;;; +3211;PARENTHESIZED HANGUL RIEUL A;So;0;L; 0028 1105 1161 0029;;;;N;PARENTHESIZED HANGUL LA;;;; +3212;PARENTHESIZED HANGUL MIEUM A;So;0;L; 0028 1106 1161 0029;;;;N;PARENTHESIZED HANGUL MA;;;; +3213;PARENTHESIZED HANGUL PIEUP A;So;0;L; 0028 1107 1161 0029;;;;N;PARENTHESIZED HANGUL BA;;;; +3214;PARENTHESIZED HANGUL SIOS A;So;0;L; 0028 1109 1161 0029;;;;N;PARENTHESIZED HANGUL SA;;;; +3215;PARENTHESIZED HANGUL IEUNG A;So;0;L; 0028 110B 1161 0029;;;;N;PARENTHESIZED HANGUL A;;;; +3216;PARENTHESIZED HANGUL CIEUC A;So;0;L; 0028 110C 1161 0029;;;;N;PARENTHESIZED HANGUL JA;;;; +3217;PARENTHESIZED HANGUL CHIEUCH A;So;0;L; 0028 110E 1161 0029;;;;N;PARENTHESIZED HANGUL CA;;;; +3218;PARENTHESIZED HANGUL KHIEUKH A;So;0;L; 0028 110F 1161 0029;;;;N;PARENTHESIZED HANGUL KA;;;; +3219;PARENTHESIZED HANGUL THIEUTH A;So;0;L; 0028 1110 1161 0029;;;;N;PARENTHESIZED HANGUL TA;;;; +321A;PARENTHESIZED HANGUL PHIEUPH A;So;0;L; 0028 1111 1161 0029;;;;N;PARENTHESIZED HANGUL PA;;;; +321B;PARENTHESIZED HANGUL HIEUH A;So;0;L; 0028 1112 1161 0029;;;;N;PARENTHESIZED HANGUL HA;;;; +321C;PARENTHESIZED HANGUL CIEUC U;So;0;L; 0028 110C 116E 0029;;;;N;PARENTHESIZED HANGUL JU;;;; +321D;PARENTHESIZED KOREAN CHARACTER OJEON;So;0;ON; 0028 110B 1169 110C 1165 11AB 0029;;;;N;;;;; +321E;PARENTHESIZED KOREAN CHARACTER O HU;So;0;ON; 0028 110B 1169 1112 116E 0029;;;;N;;;;; +3220;PARENTHESIZED IDEOGRAPH ONE;No;0;L; 0028 4E00 0029;;;1;N;;;;; +3221;PARENTHESIZED IDEOGRAPH TWO;No;0;L; 0028 4E8C 0029;;;2;N;;;;; +3222;PARENTHESIZED IDEOGRAPH THREE;No;0;L; 0028 4E09 0029;;;3;N;;;;; +3223;PARENTHESIZED IDEOGRAPH FOUR;No;0;L; 0028 56DB 0029;;;4;N;;;;; +3224;PARENTHESIZED IDEOGRAPH FIVE;No;0;L; 0028 4E94 0029;;;5;N;;;;; +3225;PARENTHESIZED IDEOGRAPH SIX;No;0;L; 0028 516D 0029;;;6;N;;;;; +3226;PARENTHESIZED IDEOGRAPH SEVEN;No;0;L; 0028 4E03 0029;;;7;N;;;;; +3227;PARENTHESIZED IDEOGRAPH EIGHT;No;0;L; 0028 516B 0029;;;8;N;;;;; +3228;PARENTHESIZED IDEOGRAPH NINE;No;0;L; 0028 4E5D 0029;;;9;N;;;;; +3229;PARENTHESIZED IDEOGRAPH TEN;No;0;L; 0028 5341 0029;;;10;N;;;;; +322A;PARENTHESIZED IDEOGRAPH MOON;So;0;L; 0028 6708 0029;;;;N;;;;; +322B;PARENTHESIZED IDEOGRAPH FIRE;So;0;L; 0028 706B 0029;;;;N;;;;; +322C;PARENTHESIZED IDEOGRAPH WATER;So;0;L; 0028 6C34 0029;;;;N;;;;; +322D;PARENTHESIZED IDEOGRAPH WOOD;So;0;L; 0028 6728 0029;;;;N;;;;; +322E;PARENTHESIZED IDEOGRAPH METAL;So;0;L; 0028 91D1 0029;;;;N;;;;; +322F;PARENTHESIZED IDEOGRAPH EARTH;So;0;L; 0028 571F 0029;;;;N;;;;; +3230;PARENTHESIZED IDEOGRAPH SUN;So;0;L; 0028 65E5 0029;;;;N;;;;; +3231;PARENTHESIZED IDEOGRAPH STOCK;So;0;L; 0028 682A 0029;;;;N;;;;; +3232;PARENTHESIZED IDEOGRAPH HAVE;So;0;L; 0028 6709 0029;;;;N;;;;; +3233;PARENTHESIZED IDEOGRAPH SOCIETY;So;0;L; 0028 793E 0029;;;;N;;;;; +3234;PARENTHESIZED IDEOGRAPH NAME;So;0;L; 0028 540D 0029;;;;N;;;;; +3235;PARENTHESIZED IDEOGRAPH SPECIAL;So;0;L; 0028 7279 0029;;;;N;;;;; +3236;PARENTHESIZED IDEOGRAPH FINANCIAL;So;0;L; 0028 8CA1 0029;;;;N;;;;; +3237;PARENTHESIZED IDEOGRAPH CONGRATULATION;So;0;L; 0028 795D 0029;;;;N;;;;; +3238;PARENTHESIZED IDEOGRAPH LABOR;So;0;L; 0028 52B4 0029;;;;N;;;;; +3239;PARENTHESIZED IDEOGRAPH REPRESENT;So;0;L; 0028 4EE3 0029;;;;N;;;;; +323A;PARENTHESIZED IDEOGRAPH CALL;So;0;L; 0028 547C 0029;;;;N;;;;; +323B;PARENTHESIZED IDEOGRAPH STUDY;So;0;L; 0028 5B66 0029;;;;N;;;;; +323C;PARENTHESIZED IDEOGRAPH SUPERVISE;So;0;L; 0028 76E3 0029;;;;N;;;;; +323D;PARENTHESIZED IDEOGRAPH ENTERPRISE;So;0;L; 0028 4F01 0029;;;;N;;;;; +323E;PARENTHESIZED IDEOGRAPH RESOURCE;So;0;L; 0028 8CC7 0029;;;;N;;;;; +323F;PARENTHESIZED IDEOGRAPH ALLIANCE;So;0;L; 0028 5354 0029;;;;N;;;;; +3240;PARENTHESIZED IDEOGRAPH FESTIVAL;So;0;L; 0028 796D 0029;;;;N;;;;; +3241;PARENTHESIZED IDEOGRAPH REST;So;0;L; 0028 4F11 0029;;;;N;;;;; +3242;PARENTHESIZED IDEOGRAPH SELF;So;0;L; 0028 81EA 0029;;;;N;;;;; +3243;PARENTHESIZED IDEOGRAPH REACH;So;0;L; 0028 81F3 0029;;;;N;;;;; +3244;CIRCLED IDEOGRAPH QUESTION;So;0;L; 554F;;;;N;;;;; +3245;CIRCLED IDEOGRAPH KINDERGARTEN;So;0;L; 5E7C;;;;N;;;;; +3246;CIRCLED IDEOGRAPH SCHOOL;So;0;L; 6587;;;;N;;;;; +3247;CIRCLED IDEOGRAPH KOTO;So;0;L; 7B8F;;;;N;;;;; +3248;CIRCLED NUMBER TEN ON BLACK SQUARE;No;0;L;;;;10;N;;;;; +3249;CIRCLED NUMBER TWENTY ON BLACK SQUARE;No;0;L;;;;20;N;;;;; +324A;CIRCLED NUMBER THIRTY ON BLACK SQUARE;No;0;L;;;;30;N;;;;; +324B;CIRCLED NUMBER FORTY ON BLACK SQUARE;No;0;L;;;;40;N;;;;; +324C;CIRCLED NUMBER FIFTY ON BLACK SQUARE;No;0;L;;;;50;N;;;;; +324D;CIRCLED NUMBER SIXTY ON BLACK SQUARE;No;0;L;;;;60;N;;;;; +324E;CIRCLED NUMBER SEVENTY ON BLACK SQUARE;No;0;L;;;;70;N;;;;; +324F;CIRCLED NUMBER EIGHTY ON BLACK SQUARE;No;0;L;;;;80;N;;;;; +3250;PARTNERSHIP SIGN;So;0;ON; 0050 0054 0045;;;;N;;;;; +3251;CIRCLED NUMBER TWENTY ONE;No;0;ON; 0032 0031;;;21;N;;;;; +3252;CIRCLED NUMBER TWENTY TWO;No;0;ON; 0032 0032;;;22;N;;;;; +3253;CIRCLED NUMBER TWENTY THREE;No;0;ON; 0032 0033;;;23;N;;;;; +3254;CIRCLED NUMBER TWENTY FOUR;No;0;ON; 0032 0034;;;24;N;;;;; +3255;CIRCLED NUMBER TWENTY FIVE;No;0;ON; 0032 0035;;;25;N;;;;; +3256;CIRCLED NUMBER TWENTY SIX;No;0;ON; 0032 0036;;;26;N;;;;; +3257;CIRCLED NUMBER TWENTY SEVEN;No;0;ON; 0032 0037;;;27;N;;;;; +3258;CIRCLED NUMBER TWENTY EIGHT;No;0;ON; 0032 0038;;;28;N;;;;; +3259;CIRCLED NUMBER TWENTY NINE;No;0;ON; 0032 0039;;;29;N;;;;; +325A;CIRCLED NUMBER THIRTY;No;0;ON; 0033 0030;;;30;N;;;;; +325B;CIRCLED NUMBER THIRTY ONE;No;0;ON; 0033 0031;;;31;N;;;;; +325C;CIRCLED NUMBER THIRTY TWO;No;0;ON; 0033 0032;;;32;N;;;;; +325D;CIRCLED NUMBER THIRTY THREE;No;0;ON; 0033 0033;;;33;N;;;;; +325E;CIRCLED NUMBER THIRTY FOUR;No;0;ON; 0033 0034;;;34;N;;;;; +325F;CIRCLED NUMBER THIRTY FIVE;No;0;ON; 0033 0035;;;35;N;;;;; +3260;CIRCLED HANGUL KIYEOK;So;0;L; 1100;;;;N;CIRCLED HANGUL GIYEOG;;;; +3261;CIRCLED HANGUL NIEUN;So;0;L; 1102;;;;N;;;;; +3262;CIRCLED HANGUL TIKEUT;So;0;L; 1103;;;;N;CIRCLED HANGUL DIGEUD;;;; +3263;CIRCLED HANGUL RIEUL;So;0;L; 1105;;;;N;CIRCLED HANGUL LIEUL;;;; +3264;CIRCLED HANGUL MIEUM;So;0;L; 1106;;;;N;;;;; +3265;CIRCLED HANGUL PIEUP;So;0;L; 1107;;;;N;CIRCLED HANGUL BIEUB;;;; +3266;CIRCLED HANGUL SIOS;So;0;L; 1109;;;;N;;;;; +3267;CIRCLED HANGUL IEUNG;So;0;L; 110B;;;;N;;;;; +3268;CIRCLED HANGUL CIEUC;So;0;L; 110C;;;;N;CIRCLED HANGUL JIEUJ;;;; +3269;CIRCLED HANGUL CHIEUCH;So;0;L; 110E;;;;N;CIRCLED HANGUL CIEUC;;;; +326A;CIRCLED HANGUL KHIEUKH;So;0;L; 110F;;;;N;CIRCLED HANGUL KIYEOK;;;; +326B;CIRCLED HANGUL THIEUTH;So;0;L; 1110;;;;N;CIRCLED HANGUL TIEUT;;;; +326C;CIRCLED HANGUL PHIEUPH;So;0;L; 1111;;;;N;CIRCLED HANGUL PIEUP;;;; +326D;CIRCLED HANGUL HIEUH;So;0;L; 1112;;;;N;;;;; +326E;CIRCLED HANGUL KIYEOK A;So;0;L; 1100 1161;;;;N;CIRCLED HANGUL GA;;;; +326F;CIRCLED HANGUL NIEUN A;So;0;L; 1102 1161;;;;N;CIRCLED HANGUL NA;;;; +3270;CIRCLED HANGUL TIKEUT A;So;0;L; 1103 1161;;;;N;CIRCLED HANGUL DA;;;; +3271;CIRCLED HANGUL RIEUL A;So;0;L; 1105 1161;;;;N;CIRCLED HANGUL LA;;;; +3272;CIRCLED HANGUL MIEUM A;So;0;L; 1106 1161;;;;N;CIRCLED HANGUL MA;;;; +3273;CIRCLED HANGUL PIEUP A;So;0;L; 1107 1161;;;;N;CIRCLED HANGUL BA;;;; +3274;CIRCLED HANGUL SIOS A;So;0;L; 1109 1161;;;;N;CIRCLED HANGUL SA;;;; +3275;CIRCLED HANGUL IEUNG A;So;0;L; 110B 1161;;;;N;CIRCLED HANGUL A;;;; +3276;CIRCLED HANGUL CIEUC A;So;0;L; 110C 1161;;;;N;CIRCLED HANGUL JA;;;; +3277;CIRCLED HANGUL CHIEUCH A;So;0;L; 110E 1161;;;;N;CIRCLED HANGUL CA;;;; +3278;CIRCLED HANGUL KHIEUKH A;So;0;L; 110F 1161;;;;N;CIRCLED HANGUL KA;;;; +3279;CIRCLED HANGUL THIEUTH A;So;0;L; 1110 1161;;;;N;CIRCLED HANGUL TA;;;; +327A;CIRCLED HANGUL PHIEUPH A;So;0;L; 1111 1161;;;;N;CIRCLED HANGUL PA;;;; +327B;CIRCLED HANGUL HIEUH A;So;0;L; 1112 1161;;;;N;CIRCLED HANGUL HA;;;; +327C;CIRCLED KOREAN CHARACTER CHAMKO;So;0;ON; 110E 1161 11B7 1100 1169;;;;N;;;;; +327D;CIRCLED KOREAN CHARACTER JUEUI;So;0;ON; 110C 116E 110B 1174;;;;N;;;;; +327E;CIRCLED HANGUL IEUNG U;So;0;ON; 110B 116E;;;;N;;;;; +327F;KOREAN STANDARD SYMBOL;So;0;L;;;;;N;;;;; +3280;CIRCLED IDEOGRAPH ONE;No;0;L; 4E00;;;1;N;;;;; +3281;CIRCLED IDEOGRAPH TWO;No;0;L; 4E8C;;;2;N;;;;; +3282;CIRCLED IDEOGRAPH THREE;No;0;L; 4E09;;;3;N;;;;; +3283;CIRCLED IDEOGRAPH FOUR;No;0;L; 56DB;;;4;N;;;;; +3284;CIRCLED IDEOGRAPH FIVE;No;0;L; 4E94;;;5;N;;;;; +3285;CIRCLED IDEOGRAPH SIX;No;0;L; 516D;;;6;N;;;;; +3286;CIRCLED IDEOGRAPH SEVEN;No;0;L; 4E03;;;7;N;;;;; +3287;CIRCLED IDEOGRAPH EIGHT;No;0;L; 516B;;;8;N;;;;; +3288;CIRCLED IDEOGRAPH NINE;No;0;L; 4E5D;;;9;N;;;;; +3289;CIRCLED IDEOGRAPH TEN;No;0;L; 5341;;;10;N;;;;; +328A;CIRCLED IDEOGRAPH MOON;So;0;L; 6708;;;;N;;;;; +328B;CIRCLED IDEOGRAPH FIRE;So;0;L; 706B;;;;N;;;;; +328C;CIRCLED IDEOGRAPH WATER;So;0;L; 6C34;;;;N;;;;; +328D;CIRCLED IDEOGRAPH WOOD;So;0;L; 6728;;;;N;;;;; +328E;CIRCLED IDEOGRAPH METAL;So;0;L; 91D1;;;;N;;;;; +328F;CIRCLED IDEOGRAPH EARTH;So;0;L; 571F;;;;N;;;;; +3290;CIRCLED IDEOGRAPH SUN;So;0;L; 65E5;;;;N;;;;; +3291;CIRCLED IDEOGRAPH STOCK;So;0;L; 682A;;;;N;;;;; +3292;CIRCLED IDEOGRAPH HAVE;So;0;L; 6709;;;;N;;;;; +3293;CIRCLED IDEOGRAPH SOCIETY;So;0;L; 793E;;;;N;;;;; +3294;CIRCLED IDEOGRAPH NAME;So;0;L; 540D;;;;N;;;;; +3295;CIRCLED IDEOGRAPH SPECIAL;So;0;L; 7279;;;;N;;;;; +3296;CIRCLED IDEOGRAPH FINANCIAL;So;0;L; 8CA1;;;;N;;;;; +3297;CIRCLED IDEOGRAPH CONGRATULATION;So;0;L; 795D;;;;N;;;;; +3298;CIRCLED IDEOGRAPH LABOR;So;0;L; 52B4;;;;N;;;;; +3299;CIRCLED IDEOGRAPH SECRET;So;0;L; 79D8;;;;N;;;;; +329A;CIRCLED IDEOGRAPH MALE;So;0;L; 7537;;;;N;;;;; +329B;CIRCLED IDEOGRAPH FEMALE;So;0;L; 5973;;;;N;;;;; +329C;CIRCLED IDEOGRAPH SUITABLE;So;0;L; 9069;;;;N;;;;; +329D;CIRCLED IDEOGRAPH EXCELLENT;So;0;L; 512A;;;;N;;;;; +329E;CIRCLED IDEOGRAPH PRINT;So;0;L; 5370;;;;N;;;;; +329F;CIRCLED IDEOGRAPH ATTENTION;So;0;L; 6CE8;;;;N;;;;; +32A0;CIRCLED IDEOGRAPH ITEM;So;0;L; 9805;;;;N;;;;; +32A1;CIRCLED IDEOGRAPH REST;So;0;L; 4F11;;;;N;;;;; +32A2;CIRCLED IDEOGRAPH COPY;So;0;L; 5199;;;;N;;;;; +32A3;CIRCLED IDEOGRAPH CORRECT;So;0;L; 6B63;;;;N;;;;; +32A4;CIRCLED IDEOGRAPH HIGH;So;0;L; 4E0A;;;;N;;;;; +32A5;CIRCLED IDEOGRAPH CENTRE;So;0;L; 4E2D;;;;N;CIRCLED IDEOGRAPH CENTER;;;; +32A6;CIRCLED IDEOGRAPH LOW;So;0;L; 4E0B;;;;N;;;;; +32A7;CIRCLED IDEOGRAPH LEFT;So;0;L; 5DE6;;;;N;;;;; +32A8;CIRCLED IDEOGRAPH RIGHT;So;0;L; 53F3;;;;N;;;;; +32A9;CIRCLED IDEOGRAPH MEDICINE;So;0;L; 533B;;;;N;;;;; +32AA;CIRCLED IDEOGRAPH RELIGION;So;0;L; 5B97;;;;N;;;;; +32AB;CIRCLED IDEOGRAPH STUDY;So;0;L; 5B66;;;;N;;;;; +32AC;CIRCLED IDEOGRAPH SUPERVISE;So;0;L; 76E3;;;;N;;;;; +32AD;CIRCLED IDEOGRAPH ENTERPRISE;So;0;L; 4F01;;;;N;;;;; +32AE;CIRCLED IDEOGRAPH RESOURCE;So;0;L; 8CC7;;;;N;;;;; +32AF;CIRCLED IDEOGRAPH ALLIANCE;So;0;L; 5354;;;;N;;;;; +32B0;CIRCLED IDEOGRAPH NIGHT;So;0;L; 591C;;;;N;;;;; +32B1;CIRCLED NUMBER THIRTY SIX;No;0;ON; 0033 0036;;;36;N;;;;; +32B2;CIRCLED NUMBER THIRTY SEVEN;No;0;ON; 0033 0037;;;37;N;;;;; +32B3;CIRCLED NUMBER THIRTY EIGHT;No;0;ON; 0033 0038;;;38;N;;;;; +32B4;CIRCLED NUMBER THIRTY NINE;No;0;ON; 0033 0039;;;39;N;;;;; +32B5;CIRCLED NUMBER FORTY;No;0;ON; 0034 0030;;;40;N;;;;; +32B6;CIRCLED NUMBER FORTY ONE;No;0;ON; 0034 0031;;;41;N;;;;; +32B7;CIRCLED NUMBER FORTY TWO;No;0;ON; 0034 0032;;;42;N;;;;; +32B8;CIRCLED NUMBER FORTY THREE;No;0;ON; 0034 0033;;;43;N;;;;; +32B9;CIRCLED NUMBER FORTY FOUR;No;0;ON; 0034 0034;;;44;N;;;;; +32BA;CIRCLED NUMBER FORTY FIVE;No;0;ON; 0034 0035;;;45;N;;;;; +32BB;CIRCLED NUMBER FORTY SIX;No;0;ON; 0034 0036;;;46;N;;;;; +32BC;CIRCLED NUMBER FORTY SEVEN;No;0;ON; 0034 0037;;;47;N;;;;; +32BD;CIRCLED NUMBER FORTY EIGHT;No;0;ON; 0034 0038;;;48;N;;;;; +32BE;CIRCLED NUMBER FORTY NINE;No;0;ON; 0034 0039;;;49;N;;;;; +32BF;CIRCLED NUMBER FIFTY;No;0;ON; 0035 0030;;;50;N;;;;; +32C0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY;So;0;L; 0031 6708;;;;N;;;;; +32C1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY;So;0;L; 0032 6708;;;;N;;;;; +32C2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH;So;0;L; 0033 6708;;;;N;;;;; +32C3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL;So;0;L; 0034 6708;;;;N;;;;; +32C4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY;So;0;L; 0035 6708;;;;N;;;;; +32C5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE;So;0;L; 0036 6708;;;;N;;;;; +32C6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY;So;0;L; 0037 6708;;;;N;;;;; +32C7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST;So;0;L; 0038 6708;;;;N;;;;; +32C8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER;So;0;L; 0039 6708;;;;N;;;;; +32C9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER;So;0;L; 0031 0030 6708;;;;N;;;;; +32CA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER;So;0;L; 0031 0031 6708;;;;N;;;;; +32CB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER;So;0;L; 0031 0032 6708;;;;N;;;;; +32CC;SQUARE HG;So;0;ON; 0048 0067;;;;N;;;;; +32CD;SQUARE ERG;So;0;ON; 0065 0072 0067;;;;N;;;;; +32CE;SQUARE EV;So;0;ON; 0065 0056;;;;N;;;;; +32CF;LIMITED LIABILITY SIGN;So;0;ON; 004C 0054 0044;;;;N;;;;; +32D0;CIRCLED KATAKANA A;So;0;L; 30A2;;;;N;;;;; +32D1;CIRCLED KATAKANA I;So;0;L; 30A4;;;;N;;;;; +32D2;CIRCLED KATAKANA U;So;0;L; 30A6;;;;N;;;;; +32D3;CIRCLED KATAKANA E;So;0;L; 30A8;;;;N;;;;; +32D4;CIRCLED KATAKANA O;So;0;L; 30AA;;;;N;;;;; +32D5;CIRCLED KATAKANA KA;So;0;L; 30AB;;;;N;;;;; +32D6;CIRCLED KATAKANA KI;So;0;L; 30AD;;;;N;;;;; +32D7;CIRCLED KATAKANA KU;So;0;L; 30AF;;;;N;;;;; +32D8;CIRCLED KATAKANA KE;So;0;L; 30B1;;;;N;;;;; +32D9;CIRCLED KATAKANA KO;So;0;L; 30B3;;;;N;;;;; +32DA;CIRCLED KATAKANA SA;So;0;L; 30B5;;;;N;;;;; +32DB;CIRCLED KATAKANA SI;So;0;L; 30B7;;;;N;;;;; +32DC;CIRCLED KATAKANA SU;So;0;L; 30B9;;;;N;;;;; +32DD;CIRCLED KATAKANA SE;So;0;L; 30BB;;;;N;;;;; +32DE;CIRCLED KATAKANA SO;So;0;L; 30BD;;;;N;;;;; +32DF;CIRCLED KATAKANA TA;So;0;L; 30BF;;;;N;;;;; +32E0;CIRCLED KATAKANA TI;So;0;L; 30C1;;;;N;;;;; +32E1;CIRCLED KATAKANA TU;So;0;L; 30C4;;;;N;;;;; +32E2;CIRCLED KATAKANA TE;So;0;L; 30C6;;;;N;;;;; +32E3;CIRCLED KATAKANA TO;So;0;L; 30C8;;;;N;;;;; +32E4;CIRCLED KATAKANA NA;So;0;L; 30CA;;;;N;;;;; +32E5;CIRCLED KATAKANA NI;So;0;L; 30CB;;;;N;;;;; +32E6;CIRCLED KATAKANA NU;So;0;L; 30CC;;;;N;;;;; +32E7;CIRCLED KATAKANA NE;So;0;L; 30CD;;;;N;;;;; +32E8;CIRCLED KATAKANA NO;So;0;L; 30CE;;;;N;;;;; +32E9;CIRCLED KATAKANA HA;So;0;L; 30CF;;;;N;;;;; +32EA;CIRCLED KATAKANA HI;So;0;L; 30D2;;;;N;;;;; +32EB;CIRCLED KATAKANA HU;So;0;L; 30D5;;;;N;;;;; +32EC;CIRCLED KATAKANA HE;So;0;L; 30D8;;;;N;;;;; +32ED;CIRCLED KATAKANA HO;So;0;L; 30DB;;;;N;;;;; +32EE;CIRCLED KATAKANA MA;So;0;L; 30DE;;;;N;;;;; +32EF;CIRCLED KATAKANA MI;So;0;L; 30DF;;;;N;;;;; +32F0;CIRCLED KATAKANA MU;So;0;L; 30E0;;;;N;;;;; +32F1;CIRCLED KATAKANA ME;So;0;L; 30E1;;;;N;;;;; +32F2;CIRCLED KATAKANA MO;So;0;L; 30E2;;;;N;;;;; +32F3;CIRCLED KATAKANA YA;So;0;L; 30E4;;;;N;;;;; +32F4;CIRCLED KATAKANA YU;So;0;L; 30E6;;;;N;;;;; +32F5;CIRCLED KATAKANA YO;So;0;L; 30E8;;;;N;;;;; +32F6;CIRCLED KATAKANA RA;So;0;L; 30E9;;;;N;;;;; +32F7;CIRCLED KATAKANA RI;So;0;L; 30EA;;;;N;;;;; +32F8;CIRCLED KATAKANA RU;So;0;L; 30EB;;;;N;;;;; +32F9;CIRCLED KATAKANA RE;So;0;L; 30EC;;;;N;;;;; +32FA;CIRCLED KATAKANA RO;So;0;L; 30ED;;;;N;;;;; +32FB;CIRCLED KATAKANA WA;So;0;L; 30EF;;;;N;;;;; +32FC;CIRCLED KATAKANA WI;So;0;L; 30F0;;;;N;;;;; +32FD;CIRCLED KATAKANA WE;So;0;L; 30F1;;;;N;;;;; +32FE;CIRCLED KATAKANA WO;So;0;L; 30F2;;;;N;;;;; +32FF;SQUARE ERA NAME REIWA;So;0;L; 4EE4 548C;;;;N;;;;; +3300;SQUARE APAATO;So;0;L; 30A2 30D1 30FC 30C8;;;;N;SQUARED APAATO;;;; +3301;SQUARE ARUHUA;So;0;L; 30A2 30EB 30D5 30A1;;;;N;SQUARED ARUHUA;;;; +3302;SQUARE ANPEA;So;0;L; 30A2 30F3 30DA 30A2;;;;N;SQUARED ANPEA;;;; +3303;SQUARE AARU;So;0;L; 30A2 30FC 30EB;;;;N;SQUARED AARU;;;; +3304;SQUARE ININGU;So;0;L; 30A4 30CB 30F3 30B0;;;;N;SQUARED ININGU;;;; +3305;SQUARE INTI;So;0;L; 30A4 30F3 30C1;;;;N;SQUARED INTI;;;; +3306;SQUARE UON;So;0;L; 30A6 30A9 30F3;;;;N;SQUARED UON;;;; +3307;SQUARE ESUKUUDO;So;0;L; 30A8 30B9 30AF 30FC 30C9;;;;N;SQUARED ESUKUUDO;;;; +3308;SQUARE EEKAA;So;0;L; 30A8 30FC 30AB 30FC;;;;N;SQUARED EEKAA;;;; +3309;SQUARE ONSU;So;0;L; 30AA 30F3 30B9;;;;N;SQUARED ONSU;;;; +330A;SQUARE OOMU;So;0;L; 30AA 30FC 30E0;;;;N;SQUARED OOMU;;;; +330B;SQUARE KAIRI;So;0;L; 30AB 30A4 30EA;;;;N;SQUARED KAIRI;;;; +330C;SQUARE KARATTO;So;0;L; 30AB 30E9 30C3 30C8;;;;N;SQUARED KARATTO;;;; +330D;SQUARE KARORII;So;0;L; 30AB 30ED 30EA 30FC;;;;N;SQUARED KARORII;;;; +330E;SQUARE GARON;So;0;L; 30AC 30ED 30F3;;;;N;SQUARED GARON;;;; +330F;SQUARE GANMA;So;0;L; 30AC 30F3 30DE;;;;N;SQUARED GANMA;;;; +3310;SQUARE GIGA;So;0;L; 30AE 30AC;;;;N;SQUARED GIGA;;;; +3311;SQUARE GINII;So;0;L; 30AE 30CB 30FC;;;;N;SQUARED GINII;;;; +3312;SQUARE KYURII;So;0;L; 30AD 30E5 30EA 30FC;;;;N;SQUARED KYURII;;;; +3313;SQUARE GIRUDAA;So;0;L; 30AE 30EB 30C0 30FC;;;;N;SQUARED GIRUDAA;;;; +3314;SQUARE KIRO;So;0;L; 30AD 30ED;;;;N;SQUARED KIRO;;;; +3315;SQUARE KIROGURAMU;So;0;L; 30AD 30ED 30B0 30E9 30E0;;;;N;SQUARED KIROGURAMU;;;; +3316;SQUARE KIROMEETORU;So;0;L; 30AD 30ED 30E1 30FC 30C8 30EB;;;;N;SQUARED KIROMEETORU;;;; +3317;SQUARE KIROWATTO;So;0;L; 30AD 30ED 30EF 30C3 30C8;;;;N;SQUARED KIROWATTO;;;; +3318;SQUARE GURAMU;So;0;L; 30B0 30E9 30E0;;;;N;SQUARED GURAMU;;;; +3319;SQUARE GURAMUTON;So;0;L; 30B0 30E9 30E0 30C8 30F3;;;;N;SQUARED GURAMUTON;;;; +331A;SQUARE KURUZEIRO;So;0;L; 30AF 30EB 30BC 30A4 30ED;;;;N;SQUARED KURUZEIRO;;;; +331B;SQUARE KUROONE;So;0;L; 30AF 30ED 30FC 30CD;;;;N;SQUARED KUROONE;;;; +331C;SQUARE KEESU;So;0;L; 30B1 30FC 30B9;;;;N;SQUARED KEESU;;;; +331D;SQUARE KORUNA;So;0;L; 30B3 30EB 30CA;;;;N;SQUARED KORUNA;;;; +331E;SQUARE KOOPO;So;0;L; 30B3 30FC 30DD;;;;N;SQUARED KOOPO;;;; +331F;SQUARE SAIKURU;So;0;L; 30B5 30A4 30AF 30EB;;;;N;SQUARED SAIKURU;;;; +3320;SQUARE SANTIIMU;So;0;L; 30B5 30F3 30C1 30FC 30E0;;;;N;SQUARED SANTIIMU;;;; +3321;SQUARE SIRINGU;So;0;L; 30B7 30EA 30F3 30B0;;;;N;SQUARED SIRINGU;;;; +3322;SQUARE SENTI;So;0;L; 30BB 30F3 30C1;;;;N;SQUARED SENTI;;;; +3323;SQUARE SENTO;So;0;L; 30BB 30F3 30C8;;;;N;SQUARED SENTO;;;; +3324;SQUARE DAASU;So;0;L; 30C0 30FC 30B9;;;;N;SQUARED DAASU;;;; +3325;SQUARE DESI;So;0;L; 30C7 30B7;;;;N;SQUARED DESI;;;; +3326;SQUARE DORU;So;0;L; 30C9 30EB;;;;N;SQUARED DORU;;;; +3327;SQUARE TON;So;0;L; 30C8 30F3;;;;N;SQUARED TON;;;; +3328;SQUARE NANO;So;0;L; 30CA 30CE;;;;N;SQUARED NANO;;;; +3329;SQUARE NOTTO;So;0;L; 30CE 30C3 30C8;;;;N;SQUARED NOTTO;;;; +332A;SQUARE HAITU;So;0;L; 30CF 30A4 30C4;;;;N;SQUARED HAITU;;;; +332B;SQUARE PAASENTO;So;0;L; 30D1 30FC 30BB 30F3 30C8;;;;N;SQUARED PAASENTO;;;; +332C;SQUARE PAATU;So;0;L; 30D1 30FC 30C4;;;;N;SQUARED PAATU;;;; +332D;SQUARE BAARERU;So;0;L; 30D0 30FC 30EC 30EB;;;;N;SQUARED BAARERU;;;; +332E;SQUARE PIASUTORU;So;0;L; 30D4 30A2 30B9 30C8 30EB;;;;N;SQUARED PIASUTORU;;;; +332F;SQUARE PIKURU;So;0;L; 30D4 30AF 30EB;;;;N;SQUARED PIKURU;;;; +3330;SQUARE PIKO;So;0;L; 30D4 30B3;;;;N;SQUARED PIKO;;;; +3331;SQUARE BIRU;So;0;L; 30D3 30EB;;;;N;SQUARED BIRU;;;; +3332;SQUARE HUARADDO;So;0;L; 30D5 30A1 30E9 30C3 30C9;;;;N;SQUARED HUARADDO;;;; +3333;SQUARE HUIITO;So;0;L; 30D5 30A3 30FC 30C8;;;;N;SQUARED HUIITO;;;; +3334;SQUARE BUSSYERU;So;0;L; 30D6 30C3 30B7 30A7 30EB;;;;N;SQUARED BUSSYERU;;;; +3335;SQUARE HURAN;So;0;L; 30D5 30E9 30F3;;;;N;SQUARED HURAN;;;; +3336;SQUARE HEKUTAARU;So;0;L; 30D8 30AF 30BF 30FC 30EB;;;;N;SQUARED HEKUTAARU;;;; +3337;SQUARE PESO;So;0;L; 30DA 30BD;;;;N;SQUARED PESO;;;; +3338;SQUARE PENIHI;So;0;L; 30DA 30CB 30D2;;;;N;SQUARED PENIHI;;;; +3339;SQUARE HERUTU;So;0;L; 30D8 30EB 30C4;;;;N;SQUARED HERUTU;;;; +333A;SQUARE PENSU;So;0;L; 30DA 30F3 30B9;;;;N;SQUARED PENSU;;;; +333B;SQUARE PEEZI;So;0;L; 30DA 30FC 30B8;;;;N;SQUARED PEEZI;;;; +333C;SQUARE BEETA;So;0;L; 30D9 30FC 30BF;;;;N;SQUARED BEETA;;;; +333D;SQUARE POINTO;So;0;L; 30DD 30A4 30F3 30C8;;;;N;SQUARED POINTO;;;; +333E;SQUARE BORUTO;So;0;L; 30DC 30EB 30C8;;;;N;SQUARED BORUTO;;;; +333F;SQUARE HON;So;0;L; 30DB 30F3;;;;N;SQUARED HON;;;; +3340;SQUARE PONDO;So;0;L; 30DD 30F3 30C9;;;;N;SQUARED PONDO;;;; +3341;SQUARE HOORU;So;0;L; 30DB 30FC 30EB;;;;N;SQUARED HOORU;;;; +3342;SQUARE HOON;So;0;L; 30DB 30FC 30F3;;;;N;SQUARED HOON;;;; +3343;SQUARE MAIKURO;So;0;L; 30DE 30A4 30AF 30ED;;;;N;SQUARED MAIKURO;;;; +3344;SQUARE MAIRU;So;0;L; 30DE 30A4 30EB;;;;N;SQUARED MAIRU;;;; +3345;SQUARE MAHHA;So;0;L; 30DE 30C3 30CF;;;;N;SQUARED MAHHA;;;; +3346;SQUARE MARUKU;So;0;L; 30DE 30EB 30AF;;;;N;SQUARED MARUKU;;;; +3347;SQUARE MANSYON;So;0;L; 30DE 30F3 30B7 30E7 30F3;;;;N;SQUARED MANSYON;;;; +3348;SQUARE MIKURON;So;0;L; 30DF 30AF 30ED 30F3;;;;N;SQUARED MIKURON;;;; +3349;SQUARE MIRI;So;0;L; 30DF 30EA;;;;N;SQUARED MIRI;;;; +334A;SQUARE MIRIBAARU;So;0;L; 30DF 30EA 30D0 30FC 30EB;;;;N;SQUARED MIRIBAARU;;;; +334B;SQUARE MEGA;So;0;L; 30E1 30AC;;;;N;SQUARED MEGA;;;; +334C;SQUARE MEGATON;So;0;L; 30E1 30AC 30C8 30F3;;;;N;SQUARED MEGATON;;;; +334D;SQUARE MEETORU;So;0;L; 30E1 30FC 30C8 30EB;;;;N;SQUARED MEETORU;;;; +334E;SQUARE YAADO;So;0;L; 30E4 30FC 30C9;;;;N;SQUARED YAADO;;;; +334F;SQUARE YAARU;So;0;L; 30E4 30FC 30EB;;;;N;SQUARED YAARU;;;; +3350;SQUARE YUAN;So;0;L; 30E6 30A2 30F3;;;;N;SQUARED YUAN;;;; +3351;SQUARE RITTORU;So;0;L; 30EA 30C3 30C8 30EB;;;;N;SQUARED RITTORU;;;; +3352;SQUARE RIRA;So;0;L; 30EA 30E9;;;;N;SQUARED RIRA;;;; +3353;SQUARE RUPII;So;0;L; 30EB 30D4 30FC;;;;N;SQUARED RUPII;;;; +3354;SQUARE RUUBURU;So;0;L; 30EB 30FC 30D6 30EB;;;;N;SQUARED RUUBURU;;;; +3355;SQUARE REMU;So;0;L; 30EC 30E0;;;;N;SQUARED REMU;;;; +3356;SQUARE RENTOGEN;So;0;L; 30EC 30F3 30C8 30B2 30F3;;;;N;SQUARED RENTOGEN;;;; +3357;SQUARE WATTO;So;0;L; 30EF 30C3 30C8;;;;N;SQUARED WATTO;;;; +3358;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO;So;0;L; 0030 70B9;;;;N;;;;; +3359;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE;So;0;L; 0031 70B9;;;;N;;;;; +335A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO;So;0;L; 0032 70B9;;;;N;;;;; +335B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE;So;0;L; 0033 70B9;;;;N;;;;; +335C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR;So;0;L; 0034 70B9;;;;N;;;;; +335D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE;So;0;L; 0035 70B9;;;;N;;;;; +335E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX;So;0;L; 0036 70B9;;;;N;;;;; +335F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN;So;0;L; 0037 70B9;;;;N;;;;; +3360;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT;So;0;L; 0038 70B9;;;;N;;;;; +3361;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE;So;0;L; 0039 70B9;;;;N;;;;; +3362;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN;So;0;L; 0031 0030 70B9;;;;N;;;;; +3363;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN;So;0;L; 0031 0031 70B9;;;;N;;;;; +3364;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE;So;0;L; 0031 0032 70B9;;;;N;;;;; +3365;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN;So;0;L; 0031 0033 70B9;;;;N;;;;; +3366;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN;So;0;L; 0031 0034 70B9;;;;N;;;;; +3367;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN;So;0;L; 0031 0035 70B9;;;;N;;;;; +3368;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN;So;0;L; 0031 0036 70B9;;;;N;;;;; +3369;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN;So;0;L; 0031 0037 70B9;;;;N;;;;; +336A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN;So;0;L; 0031 0038 70B9;;;;N;;;;; +336B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN;So;0;L; 0031 0039 70B9;;;;N;;;;; +336C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY;So;0;L; 0032 0030 70B9;;;;N;;;;; +336D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE;So;0;L; 0032 0031 70B9;;;;N;;;;; +336E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO;So;0;L; 0032 0032 70B9;;;;N;;;;; +336F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE;So;0;L; 0032 0033 70B9;;;;N;;;;; +3370;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR;So;0;L; 0032 0034 70B9;;;;N;;;;; +3371;SQUARE HPA;So;0;L; 0068 0050 0061;;;;N;;;;; +3372;SQUARE DA;So;0;L; 0064 0061;;;;N;;;;; +3373;SQUARE AU;So;0;L; 0041 0055;;;;N;;;;; +3374;SQUARE BAR;So;0;L; 0062 0061 0072;;;;N;;;;; +3375;SQUARE OV;So;0;L; 006F 0056;;;;N;;;;; +3376;SQUARE PC;So;0;L; 0070 0063;;;;N;;;;; +3377;SQUARE DM;So;0;ON; 0064 006D;;;;N;;;;; +3378;SQUARE DM SQUARED;So;0;ON; 0064 006D 00B2;;;;N;;;;; +3379;SQUARE DM CUBED;So;0;ON; 0064 006D 00B3;;;;N;;;;; +337A;SQUARE IU;So;0;ON; 0049 0055;;;;N;;;;; +337B;SQUARE ERA NAME HEISEI;So;0;L; 5E73 6210;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME HEISEI;;;; +337C;SQUARE ERA NAME SYOUWA;So;0;L; 662D 548C;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME SYOUWA;;;; +337D;SQUARE ERA NAME TAISYOU;So;0;L; 5927 6B63;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME TAISYOU;;;; +337E;SQUARE ERA NAME MEIZI;So;0;L; 660E 6CBB;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME MEIZI;;;; +337F;SQUARE CORPORATION;So;0;L; 682A 5F0F 4F1A 793E;;;;N;SQUARED FOUR IDEOGRAPHS CORPORATION;;;; +3380;SQUARE PA AMPS;So;0;L; 0070 0041;;;;N;SQUARED PA AMPS;;;; +3381;SQUARE NA;So;0;L; 006E 0041;;;;N;SQUARED NA;;;; +3382;SQUARE MU A;So;0;L; 03BC 0041;;;;N;SQUARED MU A;;;; +3383;SQUARE MA;So;0;L; 006D 0041;;;;N;SQUARED MA;;;; +3384;SQUARE KA;So;0;L; 006B 0041;;;;N;SQUARED KA;;;; +3385;SQUARE KB;So;0;L; 004B 0042;;;;N;SQUARED KB;;;; +3386;SQUARE MB;So;0;L; 004D 0042;;;;N;SQUARED MB;;;; +3387;SQUARE GB;So;0;L; 0047 0042;;;;N;SQUARED GB;;;; +3388;SQUARE CAL;So;0;L; 0063 0061 006C;;;;N;SQUARED CAL;;;; +3389;SQUARE KCAL;So;0;L; 006B 0063 0061 006C;;;;N;SQUARED KCAL;;;; +338A;SQUARE PF;So;0;L; 0070 0046;;;;N;SQUARED PF;;;; +338B;SQUARE NF;So;0;L; 006E 0046;;;;N;SQUARED NF;;;; +338C;SQUARE MU F;So;0;L; 03BC 0046;;;;N;SQUARED MU F;;;; +338D;SQUARE MU G;So;0;L; 03BC 0067;;;;N;SQUARED MU G;;;; +338E;SQUARE MG;So;0;L; 006D 0067;;;;N;SQUARED MG;;;; +338F;SQUARE KG;So;0;L; 006B 0067;;;;N;SQUARED KG;;;; +3390;SQUARE HZ;So;0;L; 0048 007A;;;;N;SQUARED HZ;;;; +3391;SQUARE KHZ;So;0;L; 006B 0048 007A;;;;N;SQUARED KHZ;;;; +3392;SQUARE MHZ;So;0;L; 004D 0048 007A;;;;N;SQUARED MHZ;;;; +3393;SQUARE GHZ;So;0;L; 0047 0048 007A;;;;N;SQUARED GHZ;;;; +3394;SQUARE THZ;So;0;L; 0054 0048 007A;;;;N;SQUARED THZ;;;; +3395;SQUARE MU L;So;0;L; 03BC 2113;;;;N;SQUARED MU L;;;; +3396;SQUARE ML;So;0;L; 006D 2113;;;;N;SQUARED ML;;;; +3397;SQUARE DL;So;0;L; 0064 2113;;;;N;SQUARED DL;;;; +3398;SQUARE KL;So;0;L; 006B 2113;;;;N;SQUARED KL;;;; +3399;SQUARE FM;So;0;L; 0066 006D;;;;N;SQUARED FM;;;; +339A;SQUARE NM;So;0;L; 006E 006D;;;;N;SQUARED NM;;;; +339B;SQUARE MU M;So;0;L; 03BC 006D;;;;N;SQUARED MU M;;;; +339C;SQUARE MM;So;0;L; 006D 006D;;;;N;SQUARED MM;;;; +339D;SQUARE CM;So;0;L; 0063 006D;;;;N;SQUARED CM;;;; +339E;SQUARE KM;So;0;L; 006B 006D;;;;N;SQUARED KM;;;; +339F;SQUARE MM SQUARED;So;0;L; 006D 006D 00B2;;;;N;SQUARED MM SQUARED;;;; +33A0;SQUARE CM SQUARED;So;0;L; 0063 006D 00B2;;;;N;SQUARED CM SQUARED;;;; +33A1;SQUARE M SQUARED;So;0;L; 006D 00B2;;;;N;SQUARED M SQUARED;;;; +33A2;SQUARE KM SQUARED;So;0;L; 006B 006D 00B2;;;;N;SQUARED KM SQUARED;;;; +33A3;SQUARE MM CUBED;So;0;L; 006D 006D 00B3;;;;N;SQUARED MM CUBED;;;; +33A4;SQUARE CM CUBED;So;0;L; 0063 006D 00B3;;;;N;SQUARED CM CUBED;;;; +33A5;SQUARE M CUBED;So;0;L; 006D 00B3;;;;N;SQUARED M CUBED;;;; +33A6;SQUARE KM CUBED;So;0;L; 006B 006D 00B3;;;;N;SQUARED KM CUBED;;;; +33A7;SQUARE M OVER S;So;0;L; 006D 2215 0073;;;;N;SQUARED M OVER S;;;; +33A8;SQUARE M OVER S SQUARED;So;0;L; 006D 2215 0073 00B2;;;;N;SQUARED M OVER S SQUARED;;;; +33A9;SQUARE PA;So;0;L; 0050 0061;;;;N;SQUARED PA;;;; +33AA;SQUARE KPA;So;0;L; 006B 0050 0061;;;;N;SQUARED KPA;;;; +33AB;SQUARE MPA;So;0;L; 004D 0050 0061;;;;N;SQUARED MPA;;;; +33AC;SQUARE GPA;So;0;L; 0047 0050 0061;;;;N;SQUARED GPA;;;; +33AD;SQUARE RAD;So;0;L; 0072 0061 0064;;;;N;SQUARED RAD;;;; +33AE;SQUARE RAD OVER S;So;0;L; 0072 0061 0064 2215 0073;;;;N;SQUARED RAD OVER S;;;; +33AF;SQUARE RAD OVER S SQUARED;So;0;L; 0072 0061 0064 2215 0073 00B2;;;;N;SQUARED RAD OVER S SQUARED;;;; +33B0;SQUARE PS;So;0;L; 0070 0073;;;;N;SQUARED PS;;;; +33B1;SQUARE NS;So;0;L; 006E 0073;;;;N;SQUARED NS;;;; +33B2;SQUARE MU S;So;0;L; 03BC 0073;;;;N;SQUARED MU S;;;; +33B3;SQUARE MS;So;0;L; 006D 0073;;;;N;SQUARED MS;;;; +33B4;SQUARE PV;So;0;L; 0070 0056;;;;N;SQUARED PV;;;; +33B5;SQUARE NV;So;0;L; 006E 0056;;;;N;SQUARED NV;;;; +33B6;SQUARE MU V;So;0;L; 03BC 0056;;;;N;SQUARED MU V;;;; +33B7;SQUARE MV;So;0;L; 006D 0056;;;;N;SQUARED MV;;;; +33B8;SQUARE KV;So;0;L; 006B 0056;;;;N;SQUARED KV;;;; +33B9;SQUARE MV MEGA;So;0;L; 004D 0056;;;;N;SQUARED MV MEGA;;;; +33BA;SQUARE PW;So;0;L; 0070 0057;;;;N;SQUARED PW;;;; +33BB;SQUARE NW;So;0;L; 006E 0057;;;;N;SQUARED NW;;;; +33BC;SQUARE MU W;So;0;L; 03BC 0057;;;;N;SQUARED MU W;;;; +33BD;SQUARE MW;So;0;L; 006D 0057;;;;N;SQUARED MW;;;; +33BE;SQUARE KW;So;0;L; 006B 0057;;;;N;SQUARED KW;;;; +33BF;SQUARE MW MEGA;So;0;L; 004D 0057;;;;N;SQUARED MW MEGA;;;; +33C0;SQUARE K OHM;So;0;L; 006B 03A9;;;;N;SQUARED K OHM;;;; +33C1;SQUARE M OHM;So;0;L; 004D 03A9;;;;N;SQUARED M OHM;;;; +33C2;SQUARE AM;So;0;L; 0061 002E 006D 002E;;;;N;SQUARED AM;;;; +33C3;SQUARE BQ;So;0;L; 0042 0071;;;;N;SQUARED BQ;;;; +33C4;SQUARE CC;So;0;L; 0063 0063;;;;N;SQUARED CC;;;; +33C5;SQUARE CD;So;0;L; 0063 0064;;;;N;SQUARED CD;;;; +33C6;SQUARE C OVER KG;So;0;L; 0043 2215 006B 0067;;;;N;SQUARED C OVER KG;;;; +33C7;SQUARE CO;So;0;L; 0043 006F 002E;;;;N;SQUARED CO;;;; +33C8;SQUARE DB;So;0;L; 0064 0042;;;;N;SQUARED DB;;;; +33C9;SQUARE GY;So;0;L; 0047 0079;;;;N;SQUARED GY;;;; +33CA;SQUARE HA;So;0;L; 0068 0061;;;;N;SQUARED HA;;;; +33CB;SQUARE HP;So;0;L; 0048 0050;;;;N;SQUARED HP;;;; +33CC;SQUARE IN;So;0;L; 0069 006E;;;;N;SQUARED IN;;;; +33CD;SQUARE KK;So;0;L; 004B 004B;;;;N;SQUARED KK;;;; +33CE;SQUARE KM CAPITAL;So;0;L; 004B 004D;;;;N;SQUARED KM CAPITAL;;;; +33CF;SQUARE KT;So;0;L; 006B 0074;;;;N;SQUARED KT;;;; +33D0;SQUARE LM;So;0;L; 006C 006D;;;;N;SQUARED LM;;;; +33D1;SQUARE LN;So;0;L; 006C 006E;;;;N;SQUARED LN;;;; +33D2;SQUARE LOG;So;0;L; 006C 006F 0067;;;;N;SQUARED LOG;;;; +33D3;SQUARE LX;So;0;L; 006C 0078;;;;N;SQUARED LX;;;; +33D4;SQUARE MB SMALL;So;0;L; 006D 0062;;;;N;SQUARED MB SMALL;;;; +33D5;SQUARE MIL;So;0;L; 006D 0069 006C;;;;N;SQUARED MIL;;;; +33D6;SQUARE MOL;So;0;L; 006D 006F 006C;;;;N;SQUARED MOL;;;; +33D7;SQUARE PH;So;0;L; 0050 0048;;;;N;SQUARED PH;;;; +33D8;SQUARE PM;So;0;L; 0070 002E 006D 002E;;;;N;SQUARED PM;;;; +33D9;SQUARE PPM;So;0;L; 0050 0050 004D;;;;N;SQUARED PPM;;;; +33DA;SQUARE PR;So;0;L; 0050 0052;;;;N;SQUARED PR;;;; +33DB;SQUARE SR;So;0;L; 0073 0072;;;;N;SQUARED SR;;;; +33DC;SQUARE SV;So;0;L; 0053 0076;;;;N;SQUARED SV;;;; +33DD;SQUARE WB;So;0;L; 0057 0062;;;;N;SQUARED WB;;;; +33DE;SQUARE V OVER M;So;0;ON; 0056 2215 006D;;;;N;;;;; +33DF;SQUARE A OVER M;So;0;ON; 0041 2215 006D;;;;N;;;;; +33E0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE;So;0;L; 0031 65E5;;;;N;;;;; +33E1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO;So;0;L; 0032 65E5;;;;N;;;;; +33E2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE;So;0;L; 0033 65E5;;;;N;;;;; +33E3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR;So;0;L; 0034 65E5;;;;N;;;;; +33E4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE;So;0;L; 0035 65E5;;;;N;;;;; +33E5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX;So;0;L; 0036 65E5;;;;N;;;;; +33E6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN;So;0;L; 0037 65E5;;;;N;;;;; +33E7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT;So;0;L; 0038 65E5;;;;N;;;;; +33E8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE;So;0;L; 0039 65E5;;;;N;;;;; +33E9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN;So;0;L; 0031 0030 65E5;;;;N;;;;; +33EA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN;So;0;L; 0031 0031 65E5;;;;N;;;;; +33EB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE;So;0;L; 0031 0032 65E5;;;;N;;;;; +33EC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN;So;0;L; 0031 0033 65E5;;;;N;;;;; +33ED;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN;So;0;L; 0031 0034 65E5;;;;N;;;;; +33EE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN;So;0;L; 0031 0035 65E5;;;;N;;;;; +33EF;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN;So;0;L; 0031 0036 65E5;;;;N;;;;; +33F0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN;So;0;L; 0031 0037 65E5;;;;N;;;;; +33F1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN;So;0;L; 0031 0038 65E5;;;;N;;;;; +33F2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN;So;0;L; 0031 0039 65E5;;;;N;;;;; +33F3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY;So;0;L; 0032 0030 65E5;;;;N;;;;; +33F4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE;So;0;L; 0032 0031 65E5;;;;N;;;;; +33F5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO;So;0;L; 0032 0032 65E5;;;;N;;;;; +33F6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE;So;0;L; 0032 0033 65E5;;;;N;;;;; +33F7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR;So;0;L; 0032 0034 65E5;;;;N;;;;; +33F8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE;So;0;L; 0032 0035 65E5;;;;N;;;;; +33F9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX;So;0;L; 0032 0036 65E5;;;;N;;;;; +33FA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN;So;0;L; 0032 0037 65E5;;;;N;;;;; +33FB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT;So;0;L; 0032 0038 65E5;;;;N;;;;; +33FC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE;So;0;L; 0032 0039 65E5;;;;N;;;;; +33FD;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY;So;0;L; 0033 0030 65E5;;;;N;;;;; +33FE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE;So;0;L; 0033 0031 65E5;;;;N;;;;; +33FF;SQUARE GAL;So;0;ON; 0067 0061 006C;;;;N;;;;; +3400;;Lo;0;L;;;;;N;;;;; +4DB5;;Lo;0;L;;;;;N;;;;; +4DC0;HEXAGRAM FOR THE CREATIVE HEAVEN;So;0;ON;;;;;N;;;;; +4DC1;HEXAGRAM FOR THE RECEPTIVE EARTH;So;0;ON;;;;;N;;;;; +4DC2;HEXAGRAM FOR DIFFICULTY AT THE BEGINNING;So;0;ON;;;;;N;;;;; +4DC3;HEXAGRAM FOR YOUTHFUL FOLLY;So;0;ON;;;;;N;;;;; +4DC4;HEXAGRAM FOR WAITING;So;0;ON;;;;;N;;;;; +4DC5;HEXAGRAM FOR CONFLICT;So;0;ON;;;;;N;;;;; +4DC6;HEXAGRAM FOR THE ARMY;So;0;ON;;;;;N;;;;; +4DC7;HEXAGRAM FOR HOLDING TOGETHER;So;0;ON;;;;;N;;;;; +4DC8;HEXAGRAM FOR SMALL TAMING;So;0;ON;;;;;N;;;;; +4DC9;HEXAGRAM FOR TREADING;So;0;ON;;;;;N;;;;; +4DCA;HEXAGRAM FOR PEACE;So;0;ON;;;;;N;;;;; +4DCB;HEXAGRAM FOR STANDSTILL;So;0;ON;;;;;N;;;;; +4DCC;HEXAGRAM FOR FELLOWSHIP;So;0;ON;;;;;N;;;;; +4DCD;HEXAGRAM FOR GREAT POSSESSION;So;0;ON;;;;;N;;;;; +4DCE;HEXAGRAM FOR MODESTY;So;0;ON;;;;;N;;;;; +4DCF;HEXAGRAM FOR ENTHUSIASM;So;0;ON;;;;;N;;;;; +4DD0;HEXAGRAM FOR FOLLOWING;So;0;ON;;;;;N;;;;; +4DD1;HEXAGRAM FOR WORK ON THE DECAYED;So;0;ON;;;;;N;;;;; +4DD2;HEXAGRAM FOR APPROACH;So;0;ON;;;;;N;;;;; +4DD3;HEXAGRAM FOR CONTEMPLATION;So;0;ON;;;;;N;;;;; +4DD4;HEXAGRAM FOR BITING THROUGH;So;0;ON;;;;;N;;;;; +4DD5;HEXAGRAM FOR GRACE;So;0;ON;;;;;N;;;;; +4DD6;HEXAGRAM FOR SPLITTING APART;So;0;ON;;;;;N;;;;; +4DD7;HEXAGRAM FOR RETURN;So;0;ON;;;;;N;;;;; +4DD8;HEXAGRAM FOR INNOCENCE;So;0;ON;;;;;N;;;;; +4DD9;HEXAGRAM FOR GREAT TAMING;So;0;ON;;;;;N;;;;; +4DDA;HEXAGRAM FOR MOUTH CORNERS;So;0;ON;;;;;N;;;;; +4DDB;HEXAGRAM FOR GREAT PREPONDERANCE;So;0;ON;;;;;N;;;;; +4DDC;HEXAGRAM FOR THE ABYSMAL WATER;So;0;ON;;;;;N;;;;; +4DDD;HEXAGRAM FOR THE CLINGING FIRE;So;0;ON;;;;;N;;;;; +4DDE;HEXAGRAM FOR INFLUENCE;So;0;ON;;;;;N;;;;; +4DDF;HEXAGRAM FOR DURATION;So;0;ON;;;;;N;;;;; +4DE0;HEXAGRAM FOR RETREAT;So;0;ON;;;;;N;;;;; +4DE1;HEXAGRAM FOR GREAT POWER;So;0;ON;;;;;N;;;;; +4DE2;HEXAGRAM FOR PROGRESS;So;0;ON;;;;;N;;;;; +4DE3;HEXAGRAM FOR DARKENING OF THE LIGHT;So;0;ON;;;;;N;;;;; +4DE4;HEXAGRAM FOR THE FAMILY;So;0;ON;;;;;N;;;;; +4DE5;HEXAGRAM FOR OPPOSITION;So;0;ON;;;;;N;;;;; +4DE6;HEXAGRAM FOR OBSTRUCTION;So;0;ON;;;;;N;;;;; +4DE7;HEXAGRAM FOR DELIVERANCE;So;0;ON;;;;;N;;;;; +4DE8;HEXAGRAM FOR DECREASE;So;0;ON;;;;;N;;;;; +4DE9;HEXAGRAM FOR INCREASE;So;0;ON;;;;;N;;;;; +4DEA;HEXAGRAM FOR BREAKTHROUGH;So;0;ON;;;;;N;;;;; +4DEB;HEXAGRAM FOR COMING TO MEET;So;0;ON;;;;;N;;;;; +4DEC;HEXAGRAM FOR GATHERING TOGETHER;So;0;ON;;;;;N;;;;; +4DED;HEXAGRAM FOR PUSHING UPWARD;So;0;ON;;;;;N;;;;; +4DEE;HEXAGRAM FOR OPPRESSION;So;0;ON;;;;;N;;;;; +4DEF;HEXAGRAM FOR THE WELL;So;0;ON;;;;;N;;;;; +4DF0;HEXAGRAM FOR REVOLUTION;So;0;ON;;;;;N;;;;; +4DF1;HEXAGRAM FOR THE CAULDRON;So;0;ON;;;;;N;;;;; +4DF2;HEXAGRAM FOR THE AROUSING THUNDER;So;0;ON;;;;;N;;;;; +4DF3;HEXAGRAM FOR THE KEEPING STILL MOUNTAIN;So;0;ON;;;;;N;;;;; +4DF4;HEXAGRAM FOR DEVELOPMENT;So;0;ON;;;;;N;;;;; +4DF5;HEXAGRAM FOR THE MARRYING MAIDEN;So;0;ON;;;;;N;;;;; +4DF6;HEXAGRAM FOR ABUNDANCE;So;0;ON;;;;;N;;;;; +4DF7;HEXAGRAM FOR THE WANDERER;So;0;ON;;;;;N;;;;; +4DF8;HEXAGRAM FOR THE GENTLE WIND;So;0;ON;;;;;N;;;;; +4DF9;HEXAGRAM FOR THE JOYOUS LAKE;So;0;ON;;;;;N;;;;; +4DFA;HEXAGRAM FOR DISPERSION;So;0;ON;;;;;N;;;;; +4DFB;HEXAGRAM FOR LIMITATION;So;0;ON;;;;;N;;;;; +4DFC;HEXAGRAM FOR INNER TRUTH;So;0;ON;;;;;N;;;;; +4DFD;HEXAGRAM FOR SMALL PREPONDERANCE;So;0;ON;;;;;N;;;;; +4DFE;HEXAGRAM FOR AFTER COMPLETION;So;0;ON;;;;;N;;;;; +4DFF;HEXAGRAM FOR BEFORE COMPLETION;So;0;ON;;;;;N;;;;; +4E00;;Lo;0;L;;;;;N;;;;; +9FEF;;Lo;0;L;;;;;N;;;;; +A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;; +A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;; +A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;; +A003;YI SYLLABLE IP;Lo;0;L;;;;;N;;;;; +A004;YI SYLLABLE IET;Lo;0;L;;;;;N;;;;; +A005;YI SYLLABLE IEX;Lo;0;L;;;;;N;;;;; +A006;YI SYLLABLE IE;Lo;0;L;;;;;N;;;;; +A007;YI SYLLABLE IEP;Lo;0;L;;;;;N;;;;; +A008;YI SYLLABLE AT;Lo;0;L;;;;;N;;;;; +A009;YI SYLLABLE AX;Lo;0;L;;;;;N;;;;; +A00A;YI SYLLABLE A;Lo;0;L;;;;;N;;;;; +A00B;YI SYLLABLE AP;Lo;0;L;;;;;N;;;;; +A00C;YI SYLLABLE UOX;Lo;0;L;;;;;N;;;;; +A00D;YI SYLLABLE UO;Lo;0;L;;;;;N;;;;; +A00E;YI SYLLABLE UOP;Lo;0;L;;;;;N;;;;; +A00F;YI SYLLABLE OT;Lo;0;L;;;;;N;;;;; +A010;YI SYLLABLE OX;Lo;0;L;;;;;N;;;;; +A011;YI SYLLABLE O;Lo;0;L;;;;;N;;;;; +A012;YI SYLLABLE OP;Lo;0;L;;;;;N;;;;; +A013;YI SYLLABLE EX;Lo;0;L;;;;;N;;;;; +A014;YI SYLLABLE E;Lo;0;L;;;;;N;;;;; +A015;YI SYLLABLE WU;Lm;0;L;;;;;N;;;;; +A016;YI SYLLABLE BIT;Lo;0;L;;;;;N;;;;; +A017;YI SYLLABLE BIX;Lo;0;L;;;;;N;;;;; +A018;YI SYLLABLE BI;Lo;0;L;;;;;N;;;;; +A019;YI SYLLABLE BIP;Lo;0;L;;;;;N;;;;; +A01A;YI SYLLABLE BIET;Lo;0;L;;;;;N;;;;; +A01B;YI SYLLABLE BIEX;Lo;0;L;;;;;N;;;;; +A01C;YI SYLLABLE BIE;Lo;0;L;;;;;N;;;;; +A01D;YI SYLLABLE BIEP;Lo;0;L;;;;;N;;;;; +A01E;YI SYLLABLE BAT;Lo;0;L;;;;;N;;;;; +A01F;YI SYLLABLE BAX;Lo;0;L;;;;;N;;;;; +A020;YI SYLLABLE BA;Lo;0;L;;;;;N;;;;; +A021;YI SYLLABLE BAP;Lo;0;L;;;;;N;;;;; +A022;YI SYLLABLE BUOX;Lo;0;L;;;;;N;;;;; +A023;YI SYLLABLE BUO;Lo;0;L;;;;;N;;;;; +A024;YI SYLLABLE BUOP;Lo;0;L;;;;;N;;;;; +A025;YI SYLLABLE BOT;Lo;0;L;;;;;N;;;;; +A026;YI SYLLABLE BOX;Lo;0;L;;;;;N;;;;; +A027;YI SYLLABLE BO;Lo;0;L;;;;;N;;;;; +A028;YI SYLLABLE BOP;Lo;0;L;;;;;N;;;;; +A029;YI SYLLABLE BEX;Lo;0;L;;;;;N;;;;; +A02A;YI SYLLABLE BE;Lo;0;L;;;;;N;;;;; +A02B;YI SYLLABLE BEP;Lo;0;L;;;;;N;;;;; +A02C;YI SYLLABLE BUT;Lo;0;L;;;;;N;;;;; +A02D;YI SYLLABLE BUX;Lo;0;L;;;;;N;;;;; +A02E;YI SYLLABLE BU;Lo;0;L;;;;;N;;;;; +A02F;YI SYLLABLE BUP;Lo;0;L;;;;;N;;;;; +A030;YI SYLLABLE BURX;Lo;0;L;;;;;N;;;;; +A031;YI SYLLABLE BUR;Lo;0;L;;;;;N;;;;; +A032;YI SYLLABLE BYT;Lo;0;L;;;;;N;;;;; +A033;YI SYLLABLE BYX;Lo;0;L;;;;;N;;;;; +A034;YI SYLLABLE BY;Lo;0;L;;;;;N;;;;; +A035;YI SYLLABLE BYP;Lo;0;L;;;;;N;;;;; +A036;YI SYLLABLE BYRX;Lo;0;L;;;;;N;;;;; +A037;YI SYLLABLE BYR;Lo;0;L;;;;;N;;;;; +A038;YI SYLLABLE PIT;Lo;0;L;;;;;N;;;;; +A039;YI SYLLABLE PIX;Lo;0;L;;;;;N;;;;; +A03A;YI SYLLABLE PI;Lo;0;L;;;;;N;;;;; +A03B;YI SYLLABLE PIP;Lo;0;L;;;;;N;;;;; +A03C;YI SYLLABLE PIEX;Lo;0;L;;;;;N;;;;; +A03D;YI SYLLABLE PIE;Lo;0;L;;;;;N;;;;; +A03E;YI SYLLABLE PIEP;Lo;0;L;;;;;N;;;;; +A03F;YI SYLLABLE PAT;Lo;0;L;;;;;N;;;;; +A040;YI SYLLABLE PAX;Lo;0;L;;;;;N;;;;; +A041;YI SYLLABLE PA;Lo;0;L;;;;;N;;;;; +A042;YI SYLLABLE PAP;Lo;0;L;;;;;N;;;;; +A043;YI SYLLABLE PUOX;Lo;0;L;;;;;N;;;;; +A044;YI SYLLABLE PUO;Lo;0;L;;;;;N;;;;; +A045;YI SYLLABLE PUOP;Lo;0;L;;;;;N;;;;; +A046;YI SYLLABLE POT;Lo;0;L;;;;;N;;;;; +A047;YI SYLLABLE POX;Lo;0;L;;;;;N;;;;; +A048;YI SYLLABLE PO;Lo;0;L;;;;;N;;;;; +A049;YI SYLLABLE POP;Lo;0;L;;;;;N;;;;; +A04A;YI SYLLABLE PUT;Lo;0;L;;;;;N;;;;; +A04B;YI SYLLABLE PUX;Lo;0;L;;;;;N;;;;; +A04C;YI SYLLABLE PU;Lo;0;L;;;;;N;;;;; +A04D;YI SYLLABLE PUP;Lo;0;L;;;;;N;;;;; +A04E;YI SYLLABLE PURX;Lo;0;L;;;;;N;;;;; +A04F;YI SYLLABLE PUR;Lo;0;L;;;;;N;;;;; +A050;YI SYLLABLE PYT;Lo;0;L;;;;;N;;;;; +A051;YI SYLLABLE PYX;Lo;0;L;;;;;N;;;;; +A052;YI SYLLABLE PY;Lo;0;L;;;;;N;;;;; +A053;YI SYLLABLE PYP;Lo;0;L;;;;;N;;;;; +A054;YI SYLLABLE PYRX;Lo;0;L;;;;;N;;;;; +A055;YI SYLLABLE PYR;Lo;0;L;;;;;N;;;;; +A056;YI SYLLABLE BBIT;Lo;0;L;;;;;N;;;;; +A057;YI SYLLABLE BBIX;Lo;0;L;;;;;N;;;;; +A058;YI SYLLABLE BBI;Lo;0;L;;;;;N;;;;; +A059;YI SYLLABLE BBIP;Lo;0;L;;;;;N;;;;; +A05A;YI SYLLABLE BBIET;Lo;0;L;;;;;N;;;;; +A05B;YI SYLLABLE BBIEX;Lo;0;L;;;;;N;;;;; +A05C;YI SYLLABLE BBIE;Lo;0;L;;;;;N;;;;; +A05D;YI SYLLABLE BBIEP;Lo;0;L;;;;;N;;;;; +A05E;YI SYLLABLE BBAT;Lo;0;L;;;;;N;;;;; +A05F;YI SYLLABLE BBAX;Lo;0;L;;;;;N;;;;; +A060;YI SYLLABLE BBA;Lo;0;L;;;;;N;;;;; +A061;YI SYLLABLE BBAP;Lo;0;L;;;;;N;;;;; +A062;YI SYLLABLE BBUOX;Lo;0;L;;;;;N;;;;; +A063;YI SYLLABLE BBUO;Lo;0;L;;;;;N;;;;; +A064;YI SYLLABLE BBUOP;Lo;0;L;;;;;N;;;;; +A065;YI SYLLABLE BBOT;Lo;0;L;;;;;N;;;;; +A066;YI SYLLABLE BBOX;Lo;0;L;;;;;N;;;;; +A067;YI SYLLABLE BBO;Lo;0;L;;;;;N;;;;; +A068;YI SYLLABLE BBOP;Lo;0;L;;;;;N;;;;; +A069;YI SYLLABLE BBEX;Lo;0;L;;;;;N;;;;; +A06A;YI SYLLABLE BBE;Lo;0;L;;;;;N;;;;; +A06B;YI SYLLABLE BBEP;Lo;0;L;;;;;N;;;;; +A06C;YI SYLLABLE BBUT;Lo;0;L;;;;;N;;;;; +A06D;YI SYLLABLE BBUX;Lo;0;L;;;;;N;;;;; +A06E;YI SYLLABLE BBU;Lo;0;L;;;;;N;;;;; +A06F;YI SYLLABLE BBUP;Lo;0;L;;;;;N;;;;; +A070;YI SYLLABLE BBURX;Lo;0;L;;;;;N;;;;; +A071;YI SYLLABLE BBUR;Lo;0;L;;;;;N;;;;; +A072;YI SYLLABLE BBYT;Lo;0;L;;;;;N;;;;; +A073;YI SYLLABLE BBYX;Lo;0;L;;;;;N;;;;; +A074;YI SYLLABLE BBY;Lo;0;L;;;;;N;;;;; +A075;YI SYLLABLE BBYP;Lo;0;L;;;;;N;;;;; +A076;YI SYLLABLE NBIT;Lo;0;L;;;;;N;;;;; +A077;YI SYLLABLE NBIX;Lo;0;L;;;;;N;;;;; +A078;YI SYLLABLE NBI;Lo;0;L;;;;;N;;;;; +A079;YI SYLLABLE NBIP;Lo;0;L;;;;;N;;;;; +A07A;YI SYLLABLE NBIEX;Lo;0;L;;;;;N;;;;; +A07B;YI SYLLABLE NBIE;Lo;0;L;;;;;N;;;;; +A07C;YI SYLLABLE NBIEP;Lo;0;L;;;;;N;;;;; +A07D;YI SYLLABLE NBAT;Lo;0;L;;;;;N;;;;; +A07E;YI SYLLABLE NBAX;Lo;0;L;;;;;N;;;;; +A07F;YI SYLLABLE NBA;Lo;0;L;;;;;N;;;;; +A080;YI SYLLABLE NBAP;Lo;0;L;;;;;N;;;;; +A081;YI SYLLABLE NBOT;Lo;0;L;;;;;N;;;;; +A082;YI SYLLABLE NBOX;Lo;0;L;;;;;N;;;;; +A083;YI SYLLABLE NBO;Lo;0;L;;;;;N;;;;; +A084;YI SYLLABLE NBOP;Lo;0;L;;;;;N;;;;; +A085;YI SYLLABLE NBUT;Lo;0;L;;;;;N;;;;; +A086;YI SYLLABLE NBUX;Lo;0;L;;;;;N;;;;; +A087;YI SYLLABLE NBU;Lo;0;L;;;;;N;;;;; +A088;YI SYLLABLE NBUP;Lo;0;L;;;;;N;;;;; +A089;YI SYLLABLE NBURX;Lo;0;L;;;;;N;;;;; +A08A;YI SYLLABLE NBUR;Lo;0;L;;;;;N;;;;; +A08B;YI SYLLABLE NBYT;Lo;0;L;;;;;N;;;;; +A08C;YI SYLLABLE NBYX;Lo;0;L;;;;;N;;;;; +A08D;YI SYLLABLE NBY;Lo;0;L;;;;;N;;;;; +A08E;YI SYLLABLE NBYP;Lo;0;L;;;;;N;;;;; +A08F;YI SYLLABLE NBYRX;Lo;0;L;;;;;N;;;;; +A090;YI SYLLABLE NBYR;Lo;0;L;;;;;N;;;;; +A091;YI SYLLABLE HMIT;Lo;0;L;;;;;N;;;;; +A092;YI SYLLABLE HMIX;Lo;0;L;;;;;N;;;;; +A093;YI SYLLABLE HMI;Lo;0;L;;;;;N;;;;; +A094;YI SYLLABLE HMIP;Lo;0;L;;;;;N;;;;; +A095;YI SYLLABLE HMIEX;Lo;0;L;;;;;N;;;;; +A096;YI SYLLABLE HMIE;Lo;0;L;;;;;N;;;;; +A097;YI SYLLABLE HMIEP;Lo;0;L;;;;;N;;;;; +A098;YI SYLLABLE HMAT;Lo;0;L;;;;;N;;;;; +A099;YI SYLLABLE HMAX;Lo;0;L;;;;;N;;;;; +A09A;YI SYLLABLE HMA;Lo;0;L;;;;;N;;;;; +A09B;YI SYLLABLE HMAP;Lo;0;L;;;;;N;;;;; +A09C;YI SYLLABLE HMUOX;Lo;0;L;;;;;N;;;;; +A09D;YI SYLLABLE HMUO;Lo;0;L;;;;;N;;;;; +A09E;YI SYLLABLE HMUOP;Lo;0;L;;;;;N;;;;; +A09F;YI SYLLABLE HMOT;Lo;0;L;;;;;N;;;;; +A0A0;YI SYLLABLE HMOX;Lo;0;L;;;;;N;;;;; +A0A1;YI SYLLABLE HMO;Lo;0;L;;;;;N;;;;; +A0A2;YI SYLLABLE HMOP;Lo;0;L;;;;;N;;;;; +A0A3;YI SYLLABLE HMUT;Lo;0;L;;;;;N;;;;; +A0A4;YI SYLLABLE HMUX;Lo;0;L;;;;;N;;;;; +A0A5;YI SYLLABLE HMU;Lo;0;L;;;;;N;;;;; +A0A6;YI SYLLABLE HMUP;Lo;0;L;;;;;N;;;;; +A0A7;YI SYLLABLE HMURX;Lo;0;L;;;;;N;;;;; +A0A8;YI SYLLABLE HMUR;Lo;0;L;;;;;N;;;;; +A0A9;YI SYLLABLE HMYX;Lo;0;L;;;;;N;;;;; +A0AA;YI SYLLABLE HMY;Lo;0;L;;;;;N;;;;; +A0AB;YI SYLLABLE HMYP;Lo;0;L;;;;;N;;;;; +A0AC;YI SYLLABLE HMYRX;Lo;0;L;;;;;N;;;;; +A0AD;YI SYLLABLE HMYR;Lo;0;L;;;;;N;;;;; +A0AE;YI SYLLABLE MIT;Lo;0;L;;;;;N;;;;; +A0AF;YI SYLLABLE MIX;Lo;0;L;;;;;N;;;;; +A0B0;YI SYLLABLE MI;Lo;0;L;;;;;N;;;;; +A0B1;YI SYLLABLE MIP;Lo;0;L;;;;;N;;;;; +A0B2;YI SYLLABLE MIEX;Lo;0;L;;;;;N;;;;; +A0B3;YI SYLLABLE MIE;Lo;0;L;;;;;N;;;;; +A0B4;YI SYLLABLE MIEP;Lo;0;L;;;;;N;;;;; +A0B5;YI SYLLABLE MAT;Lo;0;L;;;;;N;;;;; +A0B6;YI SYLLABLE MAX;Lo;0;L;;;;;N;;;;; +A0B7;YI SYLLABLE MA;Lo;0;L;;;;;N;;;;; +A0B8;YI SYLLABLE MAP;Lo;0;L;;;;;N;;;;; +A0B9;YI SYLLABLE MUOT;Lo;0;L;;;;;N;;;;; +A0BA;YI SYLLABLE MUOX;Lo;0;L;;;;;N;;;;; +A0BB;YI SYLLABLE MUO;Lo;0;L;;;;;N;;;;; +A0BC;YI SYLLABLE MUOP;Lo;0;L;;;;;N;;;;; +A0BD;YI SYLLABLE MOT;Lo;0;L;;;;;N;;;;; +A0BE;YI SYLLABLE MOX;Lo;0;L;;;;;N;;;;; +A0BF;YI SYLLABLE MO;Lo;0;L;;;;;N;;;;; +A0C0;YI SYLLABLE MOP;Lo;0;L;;;;;N;;;;; +A0C1;YI SYLLABLE MEX;Lo;0;L;;;;;N;;;;; +A0C2;YI SYLLABLE ME;Lo;0;L;;;;;N;;;;; +A0C3;YI SYLLABLE MUT;Lo;0;L;;;;;N;;;;; +A0C4;YI SYLLABLE MUX;Lo;0;L;;;;;N;;;;; +A0C5;YI SYLLABLE MU;Lo;0;L;;;;;N;;;;; +A0C6;YI SYLLABLE MUP;Lo;0;L;;;;;N;;;;; +A0C7;YI SYLLABLE MURX;Lo;0;L;;;;;N;;;;; +A0C8;YI SYLLABLE MUR;Lo;0;L;;;;;N;;;;; +A0C9;YI SYLLABLE MYT;Lo;0;L;;;;;N;;;;; +A0CA;YI SYLLABLE MYX;Lo;0;L;;;;;N;;;;; +A0CB;YI SYLLABLE MY;Lo;0;L;;;;;N;;;;; +A0CC;YI SYLLABLE MYP;Lo;0;L;;;;;N;;;;; +A0CD;YI SYLLABLE FIT;Lo;0;L;;;;;N;;;;; +A0CE;YI SYLLABLE FIX;Lo;0;L;;;;;N;;;;; +A0CF;YI SYLLABLE FI;Lo;0;L;;;;;N;;;;; +A0D0;YI SYLLABLE FIP;Lo;0;L;;;;;N;;;;; +A0D1;YI SYLLABLE FAT;Lo;0;L;;;;;N;;;;; +A0D2;YI SYLLABLE FAX;Lo;0;L;;;;;N;;;;; +A0D3;YI SYLLABLE FA;Lo;0;L;;;;;N;;;;; +A0D4;YI SYLLABLE FAP;Lo;0;L;;;;;N;;;;; +A0D5;YI SYLLABLE FOX;Lo;0;L;;;;;N;;;;; +A0D6;YI SYLLABLE FO;Lo;0;L;;;;;N;;;;; +A0D7;YI SYLLABLE FOP;Lo;0;L;;;;;N;;;;; +A0D8;YI SYLLABLE FUT;Lo;0;L;;;;;N;;;;; +A0D9;YI SYLLABLE FUX;Lo;0;L;;;;;N;;;;; +A0DA;YI SYLLABLE FU;Lo;0;L;;;;;N;;;;; +A0DB;YI SYLLABLE FUP;Lo;0;L;;;;;N;;;;; +A0DC;YI SYLLABLE FURX;Lo;0;L;;;;;N;;;;; +A0DD;YI SYLLABLE FUR;Lo;0;L;;;;;N;;;;; +A0DE;YI SYLLABLE FYT;Lo;0;L;;;;;N;;;;; +A0DF;YI SYLLABLE FYX;Lo;0;L;;;;;N;;;;; +A0E0;YI SYLLABLE FY;Lo;0;L;;;;;N;;;;; +A0E1;YI SYLLABLE FYP;Lo;0;L;;;;;N;;;;; +A0E2;YI SYLLABLE VIT;Lo;0;L;;;;;N;;;;; +A0E3;YI SYLLABLE VIX;Lo;0;L;;;;;N;;;;; +A0E4;YI SYLLABLE VI;Lo;0;L;;;;;N;;;;; +A0E5;YI SYLLABLE VIP;Lo;0;L;;;;;N;;;;; +A0E6;YI SYLLABLE VIET;Lo;0;L;;;;;N;;;;; +A0E7;YI SYLLABLE VIEX;Lo;0;L;;;;;N;;;;; +A0E8;YI SYLLABLE VIE;Lo;0;L;;;;;N;;;;; +A0E9;YI SYLLABLE VIEP;Lo;0;L;;;;;N;;;;; +A0EA;YI SYLLABLE VAT;Lo;0;L;;;;;N;;;;; +A0EB;YI SYLLABLE VAX;Lo;0;L;;;;;N;;;;; +A0EC;YI SYLLABLE VA;Lo;0;L;;;;;N;;;;; +A0ED;YI SYLLABLE VAP;Lo;0;L;;;;;N;;;;; +A0EE;YI SYLLABLE VOT;Lo;0;L;;;;;N;;;;; +A0EF;YI SYLLABLE VOX;Lo;0;L;;;;;N;;;;; +A0F0;YI SYLLABLE VO;Lo;0;L;;;;;N;;;;; +A0F1;YI SYLLABLE VOP;Lo;0;L;;;;;N;;;;; +A0F2;YI SYLLABLE VEX;Lo;0;L;;;;;N;;;;; +A0F3;YI SYLLABLE VEP;Lo;0;L;;;;;N;;;;; +A0F4;YI SYLLABLE VUT;Lo;0;L;;;;;N;;;;; +A0F5;YI SYLLABLE VUX;Lo;0;L;;;;;N;;;;; +A0F6;YI SYLLABLE VU;Lo;0;L;;;;;N;;;;; +A0F7;YI SYLLABLE VUP;Lo;0;L;;;;;N;;;;; +A0F8;YI SYLLABLE VURX;Lo;0;L;;;;;N;;;;; +A0F9;YI SYLLABLE VUR;Lo;0;L;;;;;N;;;;; +A0FA;YI SYLLABLE VYT;Lo;0;L;;;;;N;;;;; +A0FB;YI SYLLABLE VYX;Lo;0;L;;;;;N;;;;; +A0FC;YI SYLLABLE VY;Lo;0;L;;;;;N;;;;; +A0FD;YI SYLLABLE VYP;Lo;0;L;;;;;N;;;;; +A0FE;YI SYLLABLE VYRX;Lo;0;L;;;;;N;;;;; +A0FF;YI SYLLABLE VYR;Lo;0;L;;;;;N;;;;; +A100;YI SYLLABLE DIT;Lo;0;L;;;;;N;;;;; +A101;YI SYLLABLE DIX;Lo;0;L;;;;;N;;;;; +A102;YI SYLLABLE DI;Lo;0;L;;;;;N;;;;; +A103;YI SYLLABLE DIP;Lo;0;L;;;;;N;;;;; +A104;YI SYLLABLE DIEX;Lo;0;L;;;;;N;;;;; +A105;YI SYLLABLE DIE;Lo;0;L;;;;;N;;;;; +A106;YI SYLLABLE DIEP;Lo;0;L;;;;;N;;;;; +A107;YI SYLLABLE DAT;Lo;0;L;;;;;N;;;;; +A108;YI SYLLABLE DAX;Lo;0;L;;;;;N;;;;; +A109;YI SYLLABLE DA;Lo;0;L;;;;;N;;;;; +A10A;YI SYLLABLE DAP;Lo;0;L;;;;;N;;;;; +A10B;YI SYLLABLE DUOX;Lo;0;L;;;;;N;;;;; +A10C;YI SYLLABLE DUO;Lo;0;L;;;;;N;;;;; +A10D;YI SYLLABLE DOT;Lo;0;L;;;;;N;;;;; +A10E;YI SYLLABLE DOX;Lo;0;L;;;;;N;;;;; +A10F;YI SYLLABLE DO;Lo;0;L;;;;;N;;;;; +A110;YI SYLLABLE DOP;Lo;0;L;;;;;N;;;;; +A111;YI SYLLABLE DEX;Lo;0;L;;;;;N;;;;; +A112;YI SYLLABLE DE;Lo;0;L;;;;;N;;;;; +A113;YI SYLLABLE DEP;Lo;0;L;;;;;N;;;;; +A114;YI SYLLABLE DUT;Lo;0;L;;;;;N;;;;; +A115;YI SYLLABLE DUX;Lo;0;L;;;;;N;;;;; +A116;YI SYLLABLE DU;Lo;0;L;;;;;N;;;;; +A117;YI SYLLABLE DUP;Lo;0;L;;;;;N;;;;; +A118;YI SYLLABLE DURX;Lo;0;L;;;;;N;;;;; +A119;YI SYLLABLE DUR;Lo;0;L;;;;;N;;;;; +A11A;YI SYLLABLE TIT;Lo;0;L;;;;;N;;;;; +A11B;YI SYLLABLE TIX;Lo;0;L;;;;;N;;;;; +A11C;YI SYLLABLE TI;Lo;0;L;;;;;N;;;;; +A11D;YI SYLLABLE TIP;Lo;0;L;;;;;N;;;;; +A11E;YI SYLLABLE TIEX;Lo;0;L;;;;;N;;;;; +A11F;YI SYLLABLE TIE;Lo;0;L;;;;;N;;;;; +A120;YI SYLLABLE TIEP;Lo;0;L;;;;;N;;;;; +A121;YI SYLLABLE TAT;Lo;0;L;;;;;N;;;;; +A122;YI SYLLABLE TAX;Lo;0;L;;;;;N;;;;; +A123;YI SYLLABLE TA;Lo;0;L;;;;;N;;;;; +A124;YI SYLLABLE TAP;Lo;0;L;;;;;N;;;;; +A125;YI SYLLABLE TUOT;Lo;0;L;;;;;N;;;;; +A126;YI SYLLABLE TUOX;Lo;0;L;;;;;N;;;;; +A127;YI SYLLABLE TUO;Lo;0;L;;;;;N;;;;; +A128;YI SYLLABLE TUOP;Lo;0;L;;;;;N;;;;; +A129;YI SYLLABLE TOT;Lo;0;L;;;;;N;;;;; +A12A;YI SYLLABLE TOX;Lo;0;L;;;;;N;;;;; +A12B;YI SYLLABLE TO;Lo;0;L;;;;;N;;;;; +A12C;YI SYLLABLE TOP;Lo;0;L;;;;;N;;;;; +A12D;YI SYLLABLE TEX;Lo;0;L;;;;;N;;;;; +A12E;YI SYLLABLE TE;Lo;0;L;;;;;N;;;;; +A12F;YI SYLLABLE TEP;Lo;0;L;;;;;N;;;;; +A130;YI SYLLABLE TUT;Lo;0;L;;;;;N;;;;; +A131;YI SYLLABLE TUX;Lo;0;L;;;;;N;;;;; +A132;YI SYLLABLE TU;Lo;0;L;;;;;N;;;;; +A133;YI SYLLABLE TUP;Lo;0;L;;;;;N;;;;; +A134;YI SYLLABLE TURX;Lo;0;L;;;;;N;;;;; +A135;YI SYLLABLE TUR;Lo;0;L;;;;;N;;;;; +A136;YI SYLLABLE DDIT;Lo;0;L;;;;;N;;;;; +A137;YI SYLLABLE DDIX;Lo;0;L;;;;;N;;;;; +A138;YI SYLLABLE DDI;Lo;0;L;;;;;N;;;;; +A139;YI SYLLABLE DDIP;Lo;0;L;;;;;N;;;;; +A13A;YI SYLLABLE DDIEX;Lo;0;L;;;;;N;;;;; +A13B;YI SYLLABLE DDIE;Lo;0;L;;;;;N;;;;; +A13C;YI SYLLABLE DDIEP;Lo;0;L;;;;;N;;;;; +A13D;YI SYLLABLE DDAT;Lo;0;L;;;;;N;;;;; +A13E;YI SYLLABLE DDAX;Lo;0;L;;;;;N;;;;; +A13F;YI SYLLABLE DDA;Lo;0;L;;;;;N;;;;; +A140;YI SYLLABLE DDAP;Lo;0;L;;;;;N;;;;; +A141;YI SYLLABLE DDUOX;Lo;0;L;;;;;N;;;;; +A142;YI SYLLABLE DDUO;Lo;0;L;;;;;N;;;;; +A143;YI SYLLABLE DDUOP;Lo;0;L;;;;;N;;;;; +A144;YI SYLLABLE DDOT;Lo;0;L;;;;;N;;;;; +A145;YI SYLLABLE DDOX;Lo;0;L;;;;;N;;;;; +A146;YI SYLLABLE DDO;Lo;0;L;;;;;N;;;;; +A147;YI SYLLABLE DDOP;Lo;0;L;;;;;N;;;;; +A148;YI SYLLABLE DDEX;Lo;0;L;;;;;N;;;;; +A149;YI SYLLABLE DDE;Lo;0;L;;;;;N;;;;; +A14A;YI SYLLABLE DDEP;Lo;0;L;;;;;N;;;;; +A14B;YI SYLLABLE DDUT;Lo;0;L;;;;;N;;;;; +A14C;YI SYLLABLE DDUX;Lo;0;L;;;;;N;;;;; +A14D;YI SYLLABLE DDU;Lo;0;L;;;;;N;;;;; +A14E;YI SYLLABLE DDUP;Lo;0;L;;;;;N;;;;; +A14F;YI SYLLABLE DDURX;Lo;0;L;;;;;N;;;;; +A150;YI SYLLABLE DDUR;Lo;0;L;;;;;N;;;;; +A151;YI SYLLABLE NDIT;Lo;0;L;;;;;N;;;;; +A152;YI SYLLABLE NDIX;Lo;0;L;;;;;N;;;;; +A153;YI SYLLABLE NDI;Lo;0;L;;;;;N;;;;; +A154;YI SYLLABLE NDIP;Lo;0;L;;;;;N;;;;; +A155;YI SYLLABLE NDIEX;Lo;0;L;;;;;N;;;;; +A156;YI SYLLABLE NDIE;Lo;0;L;;;;;N;;;;; +A157;YI SYLLABLE NDAT;Lo;0;L;;;;;N;;;;; +A158;YI SYLLABLE NDAX;Lo;0;L;;;;;N;;;;; +A159;YI SYLLABLE NDA;Lo;0;L;;;;;N;;;;; +A15A;YI SYLLABLE NDAP;Lo;0;L;;;;;N;;;;; +A15B;YI SYLLABLE NDOT;Lo;0;L;;;;;N;;;;; +A15C;YI SYLLABLE NDOX;Lo;0;L;;;;;N;;;;; +A15D;YI SYLLABLE NDO;Lo;0;L;;;;;N;;;;; +A15E;YI SYLLABLE NDOP;Lo;0;L;;;;;N;;;;; +A15F;YI SYLLABLE NDEX;Lo;0;L;;;;;N;;;;; +A160;YI SYLLABLE NDE;Lo;0;L;;;;;N;;;;; +A161;YI SYLLABLE NDEP;Lo;0;L;;;;;N;;;;; +A162;YI SYLLABLE NDUT;Lo;0;L;;;;;N;;;;; +A163;YI SYLLABLE NDUX;Lo;0;L;;;;;N;;;;; +A164;YI SYLLABLE NDU;Lo;0;L;;;;;N;;;;; +A165;YI SYLLABLE NDUP;Lo;0;L;;;;;N;;;;; +A166;YI SYLLABLE NDURX;Lo;0;L;;;;;N;;;;; +A167;YI SYLLABLE NDUR;Lo;0;L;;;;;N;;;;; +A168;YI SYLLABLE HNIT;Lo;0;L;;;;;N;;;;; +A169;YI SYLLABLE HNIX;Lo;0;L;;;;;N;;;;; +A16A;YI SYLLABLE HNI;Lo;0;L;;;;;N;;;;; +A16B;YI SYLLABLE HNIP;Lo;0;L;;;;;N;;;;; +A16C;YI SYLLABLE HNIET;Lo;0;L;;;;;N;;;;; +A16D;YI SYLLABLE HNIEX;Lo;0;L;;;;;N;;;;; +A16E;YI SYLLABLE HNIE;Lo;0;L;;;;;N;;;;; +A16F;YI SYLLABLE HNIEP;Lo;0;L;;;;;N;;;;; +A170;YI SYLLABLE HNAT;Lo;0;L;;;;;N;;;;; +A171;YI SYLLABLE HNAX;Lo;0;L;;;;;N;;;;; +A172;YI SYLLABLE HNA;Lo;0;L;;;;;N;;;;; +A173;YI SYLLABLE HNAP;Lo;0;L;;;;;N;;;;; +A174;YI SYLLABLE HNUOX;Lo;0;L;;;;;N;;;;; +A175;YI SYLLABLE HNUO;Lo;0;L;;;;;N;;;;; +A176;YI SYLLABLE HNOT;Lo;0;L;;;;;N;;;;; +A177;YI SYLLABLE HNOX;Lo;0;L;;;;;N;;;;; +A178;YI SYLLABLE HNOP;Lo;0;L;;;;;N;;;;; +A179;YI SYLLABLE HNEX;Lo;0;L;;;;;N;;;;; +A17A;YI SYLLABLE HNE;Lo;0;L;;;;;N;;;;; +A17B;YI SYLLABLE HNEP;Lo;0;L;;;;;N;;;;; +A17C;YI SYLLABLE HNUT;Lo;0;L;;;;;N;;;;; +A17D;YI SYLLABLE NIT;Lo;0;L;;;;;N;;;;; +A17E;YI SYLLABLE NIX;Lo;0;L;;;;;N;;;;; +A17F;YI SYLLABLE NI;Lo;0;L;;;;;N;;;;; +A180;YI SYLLABLE NIP;Lo;0;L;;;;;N;;;;; +A181;YI SYLLABLE NIEX;Lo;0;L;;;;;N;;;;; +A182;YI SYLLABLE NIE;Lo;0;L;;;;;N;;;;; +A183;YI SYLLABLE NIEP;Lo;0;L;;;;;N;;;;; +A184;YI SYLLABLE NAX;Lo;0;L;;;;;N;;;;; +A185;YI SYLLABLE NA;Lo;0;L;;;;;N;;;;; +A186;YI SYLLABLE NAP;Lo;0;L;;;;;N;;;;; +A187;YI SYLLABLE NUOX;Lo;0;L;;;;;N;;;;; +A188;YI SYLLABLE NUO;Lo;0;L;;;;;N;;;;; +A189;YI SYLLABLE NUOP;Lo;0;L;;;;;N;;;;; +A18A;YI SYLLABLE NOT;Lo;0;L;;;;;N;;;;; +A18B;YI SYLLABLE NOX;Lo;0;L;;;;;N;;;;; +A18C;YI SYLLABLE NO;Lo;0;L;;;;;N;;;;; +A18D;YI SYLLABLE NOP;Lo;0;L;;;;;N;;;;; +A18E;YI SYLLABLE NEX;Lo;0;L;;;;;N;;;;; +A18F;YI SYLLABLE NE;Lo;0;L;;;;;N;;;;; +A190;YI SYLLABLE NEP;Lo;0;L;;;;;N;;;;; +A191;YI SYLLABLE NUT;Lo;0;L;;;;;N;;;;; +A192;YI SYLLABLE NUX;Lo;0;L;;;;;N;;;;; +A193;YI SYLLABLE NU;Lo;0;L;;;;;N;;;;; +A194;YI SYLLABLE NUP;Lo;0;L;;;;;N;;;;; +A195;YI SYLLABLE NURX;Lo;0;L;;;;;N;;;;; +A196;YI SYLLABLE NUR;Lo;0;L;;;;;N;;;;; +A197;YI SYLLABLE HLIT;Lo;0;L;;;;;N;;;;; +A198;YI SYLLABLE HLIX;Lo;0;L;;;;;N;;;;; +A199;YI SYLLABLE HLI;Lo;0;L;;;;;N;;;;; +A19A;YI SYLLABLE HLIP;Lo;0;L;;;;;N;;;;; +A19B;YI SYLLABLE HLIEX;Lo;0;L;;;;;N;;;;; +A19C;YI SYLLABLE HLIE;Lo;0;L;;;;;N;;;;; +A19D;YI SYLLABLE HLIEP;Lo;0;L;;;;;N;;;;; +A19E;YI SYLLABLE HLAT;Lo;0;L;;;;;N;;;;; +A19F;YI SYLLABLE HLAX;Lo;0;L;;;;;N;;;;; +A1A0;YI SYLLABLE HLA;Lo;0;L;;;;;N;;;;; +A1A1;YI SYLLABLE HLAP;Lo;0;L;;;;;N;;;;; +A1A2;YI SYLLABLE HLUOX;Lo;0;L;;;;;N;;;;; +A1A3;YI SYLLABLE HLUO;Lo;0;L;;;;;N;;;;; +A1A4;YI SYLLABLE HLUOP;Lo;0;L;;;;;N;;;;; +A1A5;YI SYLLABLE HLOX;Lo;0;L;;;;;N;;;;; +A1A6;YI SYLLABLE HLO;Lo;0;L;;;;;N;;;;; +A1A7;YI SYLLABLE HLOP;Lo;0;L;;;;;N;;;;; +A1A8;YI SYLLABLE HLEX;Lo;0;L;;;;;N;;;;; +A1A9;YI SYLLABLE HLE;Lo;0;L;;;;;N;;;;; +A1AA;YI SYLLABLE HLEP;Lo;0;L;;;;;N;;;;; +A1AB;YI SYLLABLE HLUT;Lo;0;L;;;;;N;;;;; +A1AC;YI SYLLABLE HLUX;Lo;0;L;;;;;N;;;;; +A1AD;YI SYLLABLE HLU;Lo;0;L;;;;;N;;;;; +A1AE;YI SYLLABLE HLUP;Lo;0;L;;;;;N;;;;; +A1AF;YI SYLLABLE HLURX;Lo;0;L;;;;;N;;;;; +A1B0;YI SYLLABLE HLUR;Lo;0;L;;;;;N;;;;; +A1B1;YI SYLLABLE HLYT;Lo;0;L;;;;;N;;;;; +A1B2;YI SYLLABLE HLYX;Lo;0;L;;;;;N;;;;; +A1B3;YI SYLLABLE HLY;Lo;0;L;;;;;N;;;;; +A1B4;YI SYLLABLE HLYP;Lo;0;L;;;;;N;;;;; +A1B5;YI SYLLABLE HLYRX;Lo;0;L;;;;;N;;;;; +A1B6;YI SYLLABLE HLYR;Lo;0;L;;;;;N;;;;; +A1B7;YI SYLLABLE LIT;Lo;0;L;;;;;N;;;;; +A1B8;YI SYLLABLE LIX;Lo;0;L;;;;;N;;;;; +A1B9;YI SYLLABLE LI;Lo;0;L;;;;;N;;;;; +A1BA;YI SYLLABLE LIP;Lo;0;L;;;;;N;;;;; +A1BB;YI SYLLABLE LIET;Lo;0;L;;;;;N;;;;; +A1BC;YI SYLLABLE LIEX;Lo;0;L;;;;;N;;;;; +A1BD;YI SYLLABLE LIE;Lo;0;L;;;;;N;;;;; +A1BE;YI SYLLABLE LIEP;Lo;0;L;;;;;N;;;;; +A1BF;YI SYLLABLE LAT;Lo;0;L;;;;;N;;;;; +A1C0;YI SYLLABLE LAX;Lo;0;L;;;;;N;;;;; +A1C1;YI SYLLABLE LA;Lo;0;L;;;;;N;;;;; +A1C2;YI SYLLABLE LAP;Lo;0;L;;;;;N;;;;; +A1C3;YI SYLLABLE LUOT;Lo;0;L;;;;;N;;;;; +A1C4;YI SYLLABLE LUOX;Lo;0;L;;;;;N;;;;; +A1C5;YI SYLLABLE LUO;Lo;0;L;;;;;N;;;;; +A1C6;YI SYLLABLE LUOP;Lo;0;L;;;;;N;;;;; +A1C7;YI SYLLABLE LOT;Lo;0;L;;;;;N;;;;; +A1C8;YI SYLLABLE LOX;Lo;0;L;;;;;N;;;;; +A1C9;YI SYLLABLE LO;Lo;0;L;;;;;N;;;;; +A1CA;YI SYLLABLE LOP;Lo;0;L;;;;;N;;;;; +A1CB;YI SYLLABLE LEX;Lo;0;L;;;;;N;;;;; +A1CC;YI SYLLABLE LE;Lo;0;L;;;;;N;;;;; +A1CD;YI SYLLABLE LEP;Lo;0;L;;;;;N;;;;; +A1CE;YI SYLLABLE LUT;Lo;0;L;;;;;N;;;;; +A1CF;YI SYLLABLE LUX;Lo;0;L;;;;;N;;;;; +A1D0;YI SYLLABLE LU;Lo;0;L;;;;;N;;;;; +A1D1;YI SYLLABLE LUP;Lo;0;L;;;;;N;;;;; +A1D2;YI SYLLABLE LURX;Lo;0;L;;;;;N;;;;; +A1D3;YI SYLLABLE LUR;Lo;0;L;;;;;N;;;;; +A1D4;YI SYLLABLE LYT;Lo;0;L;;;;;N;;;;; +A1D5;YI SYLLABLE LYX;Lo;0;L;;;;;N;;;;; +A1D6;YI SYLLABLE LY;Lo;0;L;;;;;N;;;;; +A1D7;YI SYLLABLE LYP;Lo;0;L;;;;;N;;;;; +A1D8;YI SYLLABLE LYRX;Lo;0;L;;;;;N;;;;; +A1D9;YI SYLLABLE LYR;Lo;0;L;;;;;N;;;;; +A1DA;YI SYLLABLE GIT;Lo;0;L;;;;;N;;;;; +A1DB;YI SYLLABLE GIX;Lo;0;L;;;;;N;;;;; +A1DC;YI SYLLABLE GI;Lo;0;L;;;;;N;;;;; +A1DD;YI SYLLABLE GIP;Lo;0;L;;;;;N;;;;; +A1DE;YI SYLLABLE GIET;Lo;0;L;;;;;N;;;;; +A1DF;YI SYLLABLE GIEX;Lo;0;L;;;;;N;;;;; +A1E0;YI SYLLABLE GIE;Lo;0;L;;;;;N;;;;; +A1E1;YI SYLLABLE GIEP;Lo;0;L;;;;;N;;;;; +A1E2;YI SYLLABLE GAT;Lo;0;L;;;;;N;;;;; +A1E3;YI SYLLABLE GAX;Lo;0;L;;;;;N;;;;; +A1E4;YI SYLLABLE GA;Lo;0;L;;;;;N;;;;; +A1E5;YI SYLLABLE GAP;Lo;0;L;;;;;N;;;;; +A1E6;YI SYLLABLE GUOT;Lo;0;L;;;;;N;;;;; +A1E7;YI SYLLABLE GUOX;Lo;0;L;;;;;N;;;;; +A1E8;YI SYLLABLE GUO;Lo;0;L;;;;;N;;;;; +A1E9;YI SYLLABLE GUOP;Lo;0;L;;;;;N;;;;; +A1EA;YI SYLLABLE GOT;Lo;0;L;;;;;N;;;;; +A1EB;YI SYLLABLE GOX;Lo;0;L;;;;;N;;;;; +A1EC;YI SYLLABLE GO;Lo;0;L;;;;;N;;;;; +A1ED;YI SYLLABLE GOP;Lo;0;L;;;;;N;;;;; +A1EE;YI SYLLABLE GET;Lo;0;L;;;;;N;;;;; +A1EF;YI SYLLABLE GEX;Lo;0;L;;;;;N;;;;; +A1F0;YI SYLLABLE GE;Lo;0;L;;;;;N;;;;; +A1F1;YI SYLLABLE GEP;Lo;0;L;;;;;N;;;;; +A1F2;YI SYLLABLE GUT;Lo;0;L;;;;;N;;;;; +A1F3;YI SYLLABLE GUX;Lo;0;L;;;;;N;;;;; +A1F4;YI SYLLABLE GU;Lo;0;L;;;;;N;;;;; +A1F5;YI SYLLABLE GUP;Lo;0;L;;;;;N;;;;; +A1F6;YI SYLLABLE GURX;Lo;0;L;;;;;N;;;;; +A1F7;YI SYLLABLE GUR;Lo;0;L;;;;;N;;;;; +A1F8;YI SYLLABLE KIT;Lo;0;L;;;;;N;;;;; +A1F9;YI SYLLABLE KIX;Lo;0;L;;;;;N;;;;; +A1FA;YI SYLLABLE KI;Lo;0;L;;;;;N;;;;; +A1FB;YI SYLLABLE KIP;Lo;0;L;;;;;N;;;;; +A1FC;YI SYLLABLE KIEX;Lo;0;L;;;;;N;;;;; +A1FD;YI SYLLABLE KIE;Lo;0;L;;;;;N;;;;; +A1FE;YI SYLLABLE KIEP;Lo;0;L;;;;;N;;;;; +A1FF;YI SYLLABLE KAT;Lo;0;L;;;;;N;;;;; +A200;YI SYLLABLE KAX;Lo;0;L;;;;;N;;;;; +A201;YI SYLLABLE KA;Lo;0;L;;;;;N;;;;; +A202;YI SYLLABLE KAP;Lo;0;L;;;;;N;;;;; +A203;YI SYLLABLE KUOX;Lo;0;L;;;;;N;;;;; +A204;YI SYLLABLE KUO;Lo;0;L;;;;;N;;;;; +A205;YI SYLLABLE KUOP;Lo;0;L;;;;;N;;;;; +A206;YI SYLLABLE KOT;Lo;0;L;;;;;N;;;;; +A207;YI SYLLABLE KOX;Lo;0;L;;;;;N;;;;; +A208;YI SYLLABLE KO;Lo;0;L;;;;;N;;;;; +A209;YI SYLLABLE KOP;Lo;0;L;;;;;N;;;;; +A20A;YI SYLLABLE KET;Lo;0;L;;;;;N;;;;; +A20B;YI SYLLABLE KEX;Lo;0;L;;;;;N;;;;; +A20C;YI SYLLABLE KE;Lo;0;L;;;;;N;;;;; +A20D;YI SYLLABLE KEP;Lo;0;L;;;;;N;;;;; +A20E;YI SYLLABLE KUT;Lo;0;L;;;;;N;;;;; +A20F;YI SYLLABLE KUX;Lo;0;L;;;;;N;;;;; +A210;YI SYLLABLE KU;Lo;0;L;;;;;N;;;;; +A211;YI SYLLABLE KUP;Lo;0;L;;;;;N;;;;; +A212;YI SYLLABLE KURX;Lo;0;L;;;;;N;;;;; +A213;YI SYLLABLE KUR;Lo;0;L;;;;;N;;;;; +A214;YI SYLLABLE GGIT;Lo;0;L;;;;;N;;;;; +A215;YI SYLLABLE GGIX;Lo;0;L;;;;;N;;;;; +A216;YI SYLLABLE GGI;Lo;0;L;;;;;N;;;;; +A217;YI SYLLABLE GGIEX;Lo;0;L;;;;;N;;;;; +A218;YI SYLLABLE GGIE;Lo;0;L;;;;;N;;;;; +A219;YI SYLLABLE GGIEP;Lo;0;L;;;;;N;;;;; +A21A;YI SYLLABLE GGAT;Lo;0;L;;;;;N;;;;; +A21B;YI SYLLABLE GGAX;Lo;0;L;;;;;N;;;;; +A21C;YI SYLLABLE GGA;Lo;0;L;;;;;N;;;;; +A21D;YI SYLLABLE GGAP;Lo;0;L;;;;;N;;;;; +A21E;YI SYLLABLE GGUOT;Lo;0;L;;;;;N;;;;; +A21F;YI SYLLABLE GGUOX;Lo;0;L;;;;;N;;;;; +A220;YI SYLLABLE GGUO;Lo;0;L;;;;;N;;;;; +A221;YI SYLLABLE GGUOP;Lo;0;L;;;;;N;;;;; +A222;YI SYLLABLE GGOT;Lo;0;L;;;;;N;;;;; +A223;YI SYLLABLE GGOX;Lo;0;L;;;;;N;;;;; +A224;YI SYLLABLE GGO;Lo;0;L;;;;;N;;;;; +A225;YI SYLLABLE GGOP;Lo;0;L;;;;;N;;;;; +A226;YI SYLLABLE GGET;Lo;0;L;;;;;N;;;;; +A227;YI SYLLABLE GGEX;Lo;0;L;;;;;N;;;;; +A228;YI SYLLABLE GGE;Lo;0;L;;;;;N;;;;; +A229;YI SYLLABLE GGEP;Lo;0;L;;;;;N;;;;; +A22A;YI SYLLABLE GGUT;Lo;0;L;;;;;N;;;;; +A22B;YI SYLLABLE GGUX;Lo;0;L;;;;;N;;;;; +A22C;YI SYLLABLE GGU;Lo;0;L;;;;;N;;;;; +A22D;YI SYLLABLE GGUP;Lo;0;L;;;;;N;;;;; +A22E;YI SYLLABLE GGURX;Lo;0;L;;;;;N;;;;; +A22F;YI SYLLABLE GGUR;Lo;0;L;;;;;N;;;;; +A230;YI SYLLABLE MGIEX;Lo;0;L;;;;;N;;;;; +A231;YI SYLLABLE MGIE;Lo;0;L;;;;;N;;;;; +A232;YI SYLLABLE MGAT;Lo;0;L;;;;;N;;;;; +A233;YI SYLLABLE MGAX;Lo;0;L;;;;;N;;;;; +A234;YI SYLLABLE MGA;Lo;0;L;;;;;N;;;;; +A235;YI SYLLABLE MGAP;Lo;0;L;;;;;N;;;;; +A236;YI SYLLABLE MGUOX;Lo;0;L;;;;;N;;;;; +A237;YI SYLLABLE MGUO;Lo;0;L;;;;;N;;;;; +A238;YI SYLLABLE MGUOP;Lo;0;L;;;;;N;;;;; +A239;YI SYLLABLE MGOT;Lo;0;L;;;;;N;;;;; +A23A;YI SYLLABLE MGOX;Lo;0;L;;;;;N;;;;; +A23B;YI SYLLABLE MGO;Lo;0;L;;;;;N;;;;; +A23C;YI SYLLABLE MGOP;Lo;0;L;;;;;N;;;;; +A23D;YI SYLLABLE MGEX;Lo;0;L;;;;;N;;;;; +A23E;YI SYLLABLE MGE;Lo;0;L;;;;;N;;;;; +A23F;YI SYLLABLE MGEP;Lo;0;L;;;;;N;;;;; +A240;YI SYLLABLE MGUT;Lo;0;L;;;;;N;;;;; +A241;YI SYLLABLE MGUX;Lo;0;L;;;;;N;;;;; +A242;YI SYLLABLE MGU;Lo;0;L;;;;;N;;;;; +A243;YI SYLLABLE MGUP;Lo;0;L;;;;;N;;;;; +A244;YI SYLLABLE MGURX;Lo;0;L;;;;;N;;;;; +A245;YI SYLLABLE MGUR;Lo;0;L;;;;;N;;;;; +A246;YI SYLLABLE HXIT;Lo;0;L;;;;;N;;;;; +A247;YI SYLLABLE HXIX;Lo;0;L;;;;;N;;;;; +A248;YI SYLLABLE HXI;Lo;0;L;;;;;N;;;;; +A249;YI SYLLABLE HXIP;Lo;0;L;;;;;N;;;;; +A24A;YI SYLLABLE HXIET;Lo;0;L;;;;;N;;;;; +A24B;YI SYLLABLE HXIEX;Lo;0;L;;;;;N;;;;; +A24C;YI SYLLABLE HXIE;Lo;0;L;;;;;N;;;;; +A24D;YI SYLLABLE HXIEP;Lo;0;L;;;;;N;;;;; +A24E;YI SYLLABLE HXAT;Lo;0;L;;;;;N;;;;; +A24F;YI SYLLABLE HXAX;Lo;0;L;;;;;N;;;;; +A250;YI SYLLABLE HXA;Lo;0;L;;;;;N;;;;; +A251;YI SYLLABLE HXAP;Lo;0;L;;;;;N;;;;; +A252;YI SYLLABLE HXUOT;Lo;0;L;;;;;N;;;;; +A253;YI SYLLABLE HXUOX;Lo;0;L;;;;;N;;;;; +A254;YI SYLLABLE HXUO;Lo;0;L;;;;;N;;;;; +A255;YI SYLLABLE HXUOP;Lo;0;L;;;;;N;;;;; +A256;YI SYLLABLE HXOT;Lo;0;L;;;;;N;;;;; +A257;YI SYLLABLE HXOX;Lo;0;L;;;;;N;;;;; +A258;YI SYLLABLE HXO;Lo;0;L;;;;;N;;;;; +A259;YI SYLLABLE HXOP;Lo;0;L;;;;;N;;;;; +A25A;YI SYLLABLE HXEX;Lo;0;L;;;;;N;;;;; +A25B;YI SYLLABLE HXE;Lo;0;L;;;;;N;;;;; +A25C;YI SYLLABLE HXEP;Lo;0;L;;;;;N;;;;; +A25D;YI SYLLABLE NGIEX;Lo;0;L;;;;;N;;;;; +A25E;YI SYLLABLE NGIE;Lo;0;L;;;;;N;;;;; +A25F;YI SYLLABLE NGIEP;Lo;0;L;;;;;N;;;;; +A260;YI SYLLABLE NGAT;Lo;0;L;;;;;N;;;;; +A261;YI SYLLABLE NGAX;Lo;0;L;;;;;N;;;;; +A262;YI SYLLABLE NGA;Lo;0;L;;;;;N;;;;; +A263;YI SYLLABLE NGAP;Lo;0;L;;;;;N;;;;; +A264;YI SYLLABLE NGUOT;Lo;0;L;;;;;N;;;;; +A265;YI SYLLABLE NGUOX;Lo;0;L;;;;;N;;;;; +A266;YI SYLLABLE NGUO;Lo;0;L;;;;;N;;;;; +A267;YI SYLLABLE NGOT;Lo;0;L;;;;;N;;;;; +A268;YI SYLLABLE NGOX;Lo;0;L;;;;;N;;;;; +A269;YI SYLLABLE NGO;Lo;0;L;;;;;N;;;;; +A26A;YI SYLLABLE NGOP;Lo;0;L;;;;;N;;;;; +A26B;YI SYLLABLE NGEX;Lo;0;L;;;;;N;;;;; +A26C;YI SYLLABLE NGE;Lo;0;L;;;;;N;;;;; +A26D;YI SYLLABLE NGEP;Lo;0;L;;;;;N;;;;; +A26E;YI SYLLABLE HIT;Lo;0;L;;;;;N;;;;; +A26F;YI SYLLABLE HIEX;Lo;0;L;;;;;N;;;;; +A270;YI SYLLABLE HIE;Lo;0;L;;;;;N;;;;; +A271;YI SYLLABLE HAT;Lo;0;L;;;;;N;;;;; +A272;YI SYLLABLE HAX;Lo;0;L;;;;;N;;;;; +A273;YI SYLLABLE HA;Lo;0;L;;;;;N;;;;; +A274;YI SYLLABLE HAP;Lo;0;L;;;;;N;;;;; +A275;YI SYLLABLE HUOT;Lo;0;L;;;;;N;;;;; +A276;YI SYLLABLE HUOX;Lo;0;L;;;;;N;;;;; +A277;YI SYLLABLE HUO;Lo;0;L;;;;;N;;;;; +A278;YI SYLLABLE HUOP;Lo;0;L;;;;;N;;;;; +A279;YI SYLLABLE HOT;Lo;0;L;;;;;N;;;;; +A27A;YI SYLLABLE HOX;Lo;0;L;;;;;N;;;;; +A27B;YI SYLLABLE HO;Lo;0;L;;;;;N;;;;; +A27C;YI SYLLABLE HOP;Lo;0;L;;;;;N;;;;; +A27D;YI SYLLABLE HEX;Lo;0;L;;;;;N;;;;; +A27E;YI SYLLABLE HE;Lo;0;L;;;;;N;;;;; +A27F;YI SYLLABLE HEP;Lo;0;L;;;;;N;;;;; +A280;YI SYLLABLE WAT;Lo;0;L;;;;;N;;;;; +A281;YI SYLLABLE WAX;Lo;0;L;;;;;N;;;;; +A282;YI SYLLABLE WA;Lo;0;L;;;;;N;;;;; +A283;YI SYLLABLE WAP;Lo;0;L;;;;;N;;;;; +A284;YI SYLLABLE WUOX;Lo;0;L;;;;;N;;;;; +A285;YI SYLLABLE WUO;Lo;0;L;;;;;N;;;;; +A286;YI SYLLABLE WUOP;Lo;0;L;;;;;N;;;;; +A287;YI SYLLABLE WOX;Lo;0;L;;;;;N;;;;; +A288;YI SYLLABLE WO;Lo;0;L;;;;;N;;;;; +A289;YI SYLLABLE WOP;Lo;0;L;;;;;N;;;;; +A28A;YI SYLLABLE WEX;Lo;0;L;;;;;N;;;;; +A28B;YI SYLLABLE WE;Lo;0;L;;;;;N;;;;; +A28C;YI SYLLABLE WEP;Lo;0;L;;;;;N;;;;; +A28D;YI SYLLABLE ZIT;Lo;0;L;;;;;N;;;;; +A28E;YI SYLLABLE ZIX;Lo;0;L;;;;;N;;;;; +A28F;YI SYLLABLE ZI;Lo;0;L;;;;;N;;;;; +A290;YI SYLLABLE ZIP;Lo;0;L;;;;;N;;;;; +A291;YI SYLLABLE ZIEX;Lo;0;L;;;;;N;;;;; +A292;YI SYLLABLE ZIE;Lo;0;L;;;;;N;;;;; +A293;YI SYLLABLE ZIEP;Lo;0;L;;;;;N;;;;; +A294;YI SYLLABLE ZAT;Lo;0;L;;;;;N;;;;; +A295;YI SYLLABLE ZAX;Lo;0;L;;;;;N;;;;; +A296;YI SYLLABLE ZA;Lo;0;L;;;;;N;;;;; +A297;YI SYLLABLE ZAP;Lo;0;L;;;;;N;;;;; +A298;YI SYLLABLE ZUOX;Lo;0;L;;;;;N;;;;; +A299;YI SYLLABLE ZUO;Lo;0;L;;;;;N;;;;; +A29A;YI SYLLABLE ZUOP;Lo;0;L;;;;;N;;;;; +A29B;YI SYLLABLE ZOT;Lo;0;L;;;;;N;;;;; +A29C;YI SYLLABLE ZOX;Lo;0;L;;;;;N;;;;; +A29D;YI SYLLABLE ZO;Lo;0;L;;;;;N;;;;; +A29E;YI SYLLABLE ZOP;Lo;0;L;;;;;N;;;;; +A29F;YI SYLLABLE ZEX;Lo;0;L;;;;;N;;;;; +A2A0;YI SYLLABLE ZE;Lo;0;L;;;;;N;;;;; +A2A1;YI SYLLABLE ZEP;Lo;0;L;;;;;N;;;;; +A2A2;YI SYLLABLE ZUT;Lo;0;L;;;;;N;;;;; +A2A3;YI SYLLABLE ZUX;Lo;0;L;;;;;N;;;;; +A2A4;YI SYLLABLE ZU;Lo;0;L;;;;;N;;;;; +A2A5;YI SYLLABLE ZUP;Lo;0;L;;;;;N;;;;; +A2A6;YI SYLLABLE ZURX;Lo;0;L;;;;;N;;;;; +A2A7;YI SYLLABLE ZUR;Lo;0;L;;;;;N;;;;; +A2A8;YI SYLLABLE ZYT;Lo;0;L;;;;;N;;;;; +A2A9;YI SYLLABLE ZYX;Lo;0;L;;;;;N;;;;; +A2AA;YI SYLLABLE ZY;Lo;0;L;;;;;N;;;;; +A2AB;YI SYLLABLE ZYP;Lo;0;L;;;;;N;;;;; +A2AC;YI SYLLABLE ZYRX;Lo;0;L;;;;;N;;;;; +A2AD;YI SYLLABLE ZYR;Lo;0;L;;;;;N;;;;; +A2AE;YI SYLLABLE CIT;Lo;0;L;;;;;N;;;;; +A2AF;YI SYLLABLE CIX;Lo;0;L;;;;;N;;;;; +A2B0;YI SYLLABLE CI;Lo;0;L;;;;;N;;;;; +A2B1;YI SYLLABLE CIP;Lo;0;L;;;;;N;;;;; +A2B2;YI SYLLABLE CIET;Lo;0;L;;;;;N;;;;; +A2B3;YI SYLLABLE CIEX;Lo;0;L;;;;;N;;;;; +A2B4;YI SYLLABLE CIE;Lo;0;L;;;;;N;;;;; +A2B5;YI SYLLABLE CIEP;Lo;0;L;;;;;N;;;;; +A2B6;YI SYLLABLE CAT;Lo;0;L;;;;;N;;;;; +A2B7;YI SYLLABLE CAX;Lo;0;L;;;;;N;;;;; +A2B8;YI SYLLABLE CA;Lo;0;L;;;;;N;;;;; +A2B9;YI SYLLABLE CAP;Lo;0;L;;;;;N;;;;; +A2BA;YI SYLLABLE CUOX;Lo;0;L;;;;;N;;;;; +A2BB;YI SYLLABLE CUO;Lo;0;L;;;;;N;;;;; +A2BC;YI SYLLABLE CUOP;Lo;0;L;;;;;N;;;;; +A2BD;YI SYLLABLE COT;Lo;0;L;;;;;N;;;;; +A2BE;YI SYLLABLE COX;Lo;0;L;;;;;N;;;;; +A2BF;YI SYLLABLE CO;Lo;0;L;;;;;N;;;;; +A2C0;YI SYLLABLE COP;Lo;0;L;;;;;N;;;;; +A2C1;YI SYLLABLE CEX;Lo;0;L;;;;;N;;;;; +A2C2;YI SYLLABLE CE;Lo;0;L;;;;;N;;;;; +A2C3;YI SYLLABLE CEP;Lo;0;L;;;;;N;;;;; +A2C4;YI SYLLABLE CUT;Lo;0;L;;;;;N;;;;; +A2C5;YI SYLLABLE CUX;Lo;0;L;;;;;N;;;;; +A2C6;YI SYLLABLE CU;Lo;0;L;;;;;N;;;;; +A2C7;YI SYLLABLE CUP;Lo;0;L;;;;;N;;;;; +A2C8;YI SYLLABLE CURX;Lo;0;L;;;;;N;;;;; +A2C9;YI SYLLABLE CUR;Lo;0;L;;;;;N;;;;; +A2CA;YI SYLLABLE CYT;Lo;0;L;;;;;N;;;;; +A2CB;YI SYLLABLE CYX;Lo;0;L;;;;;N;;;;; +A2CC;YI SYLLABLE CY;Lo;0;L;;;;;N;;;;; +A2CD;YI SYLLABLE CYP;Lo;0;L;;;;;N;;;;; +A2CE;YI SYLLABLE CYRX;Lo;0;L;;;;;N;;;;; +A2CF;YI SYLLABLE CYR;Lo;0;L;;;;;N;;;;; +A2D0;YI SYLLABLE ZZIT;Lo;0;L;;;;;N;;;;; +A2D1;YI SYLLABLE ZZIX;Lo;0;L;;;;;N;;;;; +A2D2;YI SYLLABLE ZZI;Lo;0;L;;;;;N;;;;; +A2D3;YI SYLLABLE ZZIP;Lo;0;L;;;;;N;;;;; +A2D4;YI SYLLABLE ZZIET;Lo;0;L;;;;;N;;;;; +A2D5;YI SYLLABLE ZZIEX;Lo;0;L;;;;;N;;;;; +A2D6;YI SYLLABLE ZZIE;Lo;0;L;;;;;N;;;;; +A2D7;YI SYLLABLE ZZIEP;Lo;0;L;;;;;N;;;;; +A2D8;YI SYLLABLE ZZAT;Lo;0;L;;;;;N;;;;; +A2D9;YI SYLLABLE ZZAX;Lo;0;L;;;;;N;;;;; +A2DA;YI SYLLABLE ZZA;Lo;0;L;;;;;N;;;;; +A2DB;YI SYLLABLE ZZAP;Lo;0;L;;;;;N;;;;; +A2DC;YI SYLLABLE ZZOX;Lo;0;L;;;;;N;;;;; +A2DD;YI SYLLABLE ZZO;Lo;0;L;;;;;N;;;;; +A2DE;YI SYLLABLE ZZOP;Lo;0;L;;;;;N;;;;; +A2DF;YI SYLLABLE ZZEX;Lo;0;L;;;;;N;;;;; +A2E0;YI SYLLABLE ZZE;Lo;0;L;;;;;N;;;;; +A2E1;YI SYLLABLE ZZEP;Lo;0;L;;;;;N;;;;; +A2E2;YI SYLLABLE ZZUX;Lo;0;L;;;;;N;;;;; +A2E3;YI SYLLABLE ZZU;Lo;0;L;;;;;N;;;;; +A2E4;YI SYLLABLE ZZUP;Lo;0;L;;;;;N;;;;; +A2E5;YI SYLLABLE ZZURX;Lo;0;L;;;;;N;;;;; +A2E6;YI SYLLABLE ZZUR;Lo;0;L;;;;;N;;;;; +A2E7;YI SYLLABLE ZZYT;Lo;0;L;;;;;N;;;;; +A2E8;YI SYLLABLE ZZYX;Lo;0;L;;;;;N;;;;; +A2E9;YI SYLLABLE ZZY;Lo;0;L;;;;;N;;;;; +A2EA;YI SYLLABLE ZZYP;Lo;0;L;;;;;N;;;;; +A2EB;YI SYLLABLE ZZYRX;Lo;0;L;;;;;N;;;;; +A2EC;YI SYLLABLE ZZYR;Lo;0;L;;;;;N;;;;; +A2ED;YI SYLLABLE NZIT;Lo;0;L;;;;;N;;;;; +A2EE;YI SYLLABLE NZIX;Lo;0;L;;;;;N;;;;; +A2EF;YI SYLLABLE NZI;Lo;0;L;;;;;N;;;;; +A2F0;YI SYLLABLE NZIP;Lo;0;L;;;;;N;;;;; +A2F1;YI SYLLABLE NZIEX;Lo;0;L;;;;;N;;;;; +A2F2;YI SYLLABLE NZIE;Lo;0;L;;;;;N;;;;; +A2F3;YI SYLLABLE NZIEP;Lo;0;L;;;;;N;;;;; +A2F4;YI SYLLABLE NZAT;Lo;0;L;;;;;N;;;;; +A2F5;YI SYLLABLE NZAX;Lo;0;L;;;;;N;;;;; +A2F6;YI SYLLABLE NZA;Lo;0;L;;;;;N;;;;; +A2F7;YI SYLLABLE NZAP;Lo;0;L;;;;;N;;;;; +A2F8;YI SYLLABLE NZUOX;Lo;0;L;;;;;N;;;;; +A2F9;YI SYLLABLE NZUO;Lo;0;L;;;;;N;;;;; +A2FA;YI SYLLABLE NZOX;Lo;0;L;;;;;N;;;;; +A2FB;YI SYLLABLE NZOP;Lo;0;L;;;;;N;;;;; +A2FC;YI SYLLABLE NZEX;Lo;0;L;;;;;N;;;;; +A2FD;YI SYLLABLE NZE;Lo;0;L;;;;;N;;;;; +A2FE;YI SYLLABLE NZUX;Lo;0;L;;;;;N;;;;; +A2FF;YI SYLLABLE NZU;Lo;0;L;;;;;N;;;;; +A300;YI SYLLABLE NZUP;Lo;0;L;;;;;N;;;;; +A301;YI SYLLABLE NZURX;Lo;0;L;;;;;N;;;;; +A302;YI SYLLABLE NZUR;Lo;0;L;;;;;N;;;;; +A303;YI SYLLABLE NZYT;Lo;0;L;;;;;N;;;;; +A304;YI SYLLABLE NZYX;Lo;0;L;;;;;N;;;;; +A305;YI SYLLABLE NZY;Lo;0;L;;;;;N;;;;; +A306;YI SYLLABLE NZYP;Lo;0;L;;;;;N;;;;; +A307;YI SYLLABLE NZYRX;Lo;0;L;;;;;N;;;;; +A308;YI SYLLABLE NZYR;Lo;0;L;;;;;N;;;;; +A309;YI SYLLABLE SIT;Lo;0;L;;;;;N;;;;; +A30A;YI SYLLABLE SIX;Lo;0;L;;;;;N;;;;; +A30B;YI SYLLABLE SI;Lo;0;L;;;;;N;;;;; +A30C;YI SYLLABLE SIP;Lo;0;L;;;;;N;;;;; +A30D;YI SYLLABLE SIEX;Lo;0;L;;;;;N;;;;; +A30E;YI SYLLABLE SIE;Lo;0;L;;;;;N;;;;; +A30F;YI SYLLABLE SIEP;Lo;0;L;;;;;N;;;;; +A310;YI SYLLABLE SAT;Lo;0;L;;;;;N;;;;; +A311;YI SYLLABLE SAX;Lo;0;L;;;;;N;;;;; +A312;YI SYLLABLE SA;Lo;0;L;;;;;N;;;;; +A313;YI SYLLABLE SAP;Lo;0;L;;;;;N;;;;; +A314;YI SYLLABLE SUOX;Lo;0;L;;;;;N;;;;; +A315;YI SYLLABLE SUO;Lo;0;L;;;;;N;;;;; +A316;YI SYLLABLE SUOP;Lo;0;L;;;;;N;;;;; +A317;YI SYLLABLE SOT;Lo;0;L;;;;;N;;;;; +A318;YI SYLLABLE SOX;Lo;0;L;;;;;N;;;;; +A319;YI SYLLABLE SO;Lo;0;L;;;;;N;;;;; +A31A;YI SYLLABLE SOP;Lo;0;L;;;;;N;;;;; +A31B;YI SYLLABLE SEX;Lo;0;L;;;;;N;;;;; +A31C;YI SYLLABLE SE;Lo;0;L;;;;;N;;;;; +A31D;YI SYLLABLE SEP;Lo;0;L;;;;;N;;;;; +A31E;YI SYLLABLE SUT;Lo;0;L;;;;;N;;;;; +A31F;YI SYLLABLE SUX;Lo;0;L;;;;;N;;;;; +A320;YI SYLLABLE SU;Lo;0;L;;;;;N;;;;; +A321;YI SYLLABLE SUP;Lo;0;L;;;;;N;;;;; +A322;YI SYLLABLE SURX;Lo;0;L;;;;;N;;;;; +A323;YI SYLLABLE SUR;Lo;0;L;;;;;N;;;;; +A324;YI SYLLABLE SYT;Lo;0;L;;;;;N;;;;; +A325;YI SYLLABLE SYX;Lo;0;L;;;;;N;;;;; +A326;YI SYLLABLE SY;Lo;0;L;;;;;N;;;;; +A327;YI SYLLABLE SYP;Lo;0;L;;;;;N;;;;; +A328;YI SYLLABLE SYRX;Lo;0;L;;;;;N;;;;; +A329;YI SYLLABLE SYR;Lo;0;L;;;;;N;;;;; +A32A;YI SYLLABLE SSIT;Lo;0;L;;;;;N;;;;; +A32B;YI SYLLABLE SSIX;Lo;0;L;;;;;N;;;;; +A32C;YI SYLLABLE SSI;Lo;0;L;;;;;N;;;;; +A32D;YI SYLLABLE SSIP;Lo;0;L;;;;;N;;;;; +A32E;YI SYLLABLE SSIEX;Lo;0;L;;;;;N;;;;; +A32F;YI SYLLABLE SSIE;Lo;0;L;;;;;N;;;;; +A330;YI SYLLABLE SSIEP;Lo;0;L;;;;;N;;;;; +A331;YI SYLLABLE SSAT;Lo;0;L;;;;;N;;;;; +A332;YI SYLLABLE SSAX;Lo;0;L;;;;;N;;;;; +A333;YI SYLLABLE SSA;Lo;0;L;;;;;N;;;;; +A334;YI SYLLABLE SSAP;Lo;0;L;;;;;N;;;;; +A335;YI SYLLABLE SSOT;Lo;0;L;;;;;N;;;;; +A336;YI SYLLABLE SSOX;Lo;0;L;;;;;N;;;;; +A337;YI SYLLABLE SSO;Lo;0;L;;;;;N;;;;; +A338;YI SYLLABLE SSOP;Lo;0;L;;;;;N;;;;; +A339;YI SYLLABLE SSEX;Lo;0;L;;;;;N;;;;; +A33A;YI SYLLABLE SSE;Lo;0;L;;;;;N;;;;; +A33B;YI SYLLABLE SSEP;Lo;0;L;;;;;N;;;;; +A33C;YI SYLLABLE SSUT;Lo;0;L;;;;;N;;;;; +A33D;YI SYLLABLE SSUX;Lo;0;L;;;;;N;;;;; +A33E;YI SYLLABLE SSU;Lo;0;L;;;;;N;;;;; +A33F;YI SYLLABLE SSUP;Lo;0;L;;;;;N;;;;; +A340;YI SYLLABLE SSYT;Lo;0;L;;;;;N;;;;; +A341;YI SYLLABLE SSYX;Lo;0;L;;;;;N;;;;; +A342;YI SYLLABLE SSY;Lo;0;L;;;;;N;;;;; +A343;YI SYLLABLE SSYP;Lo;0;L;;;;;N;;;;; +A344;YI SYLLABLE SSYRX;Lo;0;L;;;;;N;;;;; +A345;YI SYLLABLE SSYR;Lo;0;L;;;;;N;;;;; +A346;YI SYLLABLE ZHAT;Lo;0;L;;;;;N;;;;; +A347;YI SYLLABLE ZHAX;Lo;0;L;;;;;N;;;;; +A348;YI SYLLABLE ZHA;Lo;0;L;;;;;N;;;;; +A349;YI SYLLABLE ZHAP;Lo;0;L;;;;;N;;;;; +A34A;YI SYLLABLE ZHUOX;Lo;0;L;;;;;N;;;;; +A34B;YI SYLLABLE ZHUO;Lo;0;L;;;;;N;;;;; +A34C;YI SYLLABLE ZHUOP;Lo;0;L;;;;;N;;;;; +A34D;YI SYLLABLE ZHOT;Lo;0;L;;;;;N;;;;; +A34E;YI SYLLABLE ZHOX;Lo;0;L;;;;;N;;;;; +A34F;YI SYLLABLE ZHO;Lo;0;L;;;;;N;;;;; +A350;YI SYLLABLE ZHOP;Lo;0;L;;;;;N;;;;; +A351;YI SYLLABLE ZHET;Lo;0;L;;;;;N;;;;; +A352;YI SYLLABLE ZHEX;Lo;0;L;;;;;N;;;;; +A353;YI SYLLABLE ZHE;Lo;0;L;;;;;N;;;;; +A354;YI SYLLABLE ZHEP;Lo;0;L;;;;;N;;;;; +A355;YI SYLLABLE ZHUT;Lo;0;L;;;;;N;;;;; +A356;YI SYLLABLE ZHUX;Lo;0;L;;;;;N;;;;; +A357;YI SYLLABLE ZHU;Lo;0;L;;;;;N;;;;; +A358;YI SYLLABLE ZHUP;Lo;0;L;;;;;N;;;;; +A359;YI SYLLABLE ZHURX;Lo;0;L;;;;;N;;;;; +A35A;YI SYLLABLE ZHUR;Lo;0;L;;;;;N;;;;; +A35B;YI SYLLABLE ZHYT;Lo;0;L;;;;;N;;;;; +A35C;YI SYLLABLE ZHYX;Lo;0;L;;;;;N;;;;; +A35D;YI SYLLABLE ZHY;Lo;0;L;;;;;N;;;;; +A35E;YI SYLLABLE ZHYP;Lo;0;L;;;;;N;;;;; +A35F;YI SYLLABLE ZHYRX;Lo;0;L;;;;;N;;;;; +A360;YI SYLLABLE ZHYR;Lo;0;L;;;;;N;;;;; +A361;YI SYLLABLE CHAT;Lo;0;L;;;;;N;;;;; +A362;YI SYLLABLE CHAX;Lo;0;L;;;;;N;;;;; +A363;YI SYLLABLE CHA;Lo;0;L;;;;;N;;;;; +A364;YI SYLLABLE CHAP;Lo;0;L;;;;;N;;;;; +A365;YI SYLLABLE CHUOT;Lo;0;L;;;;;N;;;;; +A366;YI SYLLABLE CHUOX;Lo;0;L;;;;;N;;;;; +A367;YI SYLLABLE CHUO;Lo;0;L;;;;;N;;;;; +A368;YI SYLLABLE CHUOP;Lo;0;L;;;;;N;;;;; +A369;YI SYLLABLE CHOT;Lo;0;L;;;;;N;;;;; +A36A;YI SYLLABLE CHOX;Lo;0;L;;;;;N;;;;; +A36B;YI SYLLABLE CHO;Lo;0;L;;;;;N;;;;; +A36C;YI SYLLABLE CHOP;Lo;0;L;;;;;N;;;;; +A36D;YI SYLLABLE CHET;Lo;0;L;;;;;N;;;;; +A36E;YI SYLLABLE CHEX;Lo;0;L;;;;;N;;;;; +A36F;YI SYLLABLE CHE;Lo;0;L;;;;;N;;;;; +A370;YI SYLLABLE CHEP;Lo;0;L;;;;;N;;;;; +A371;YI SYLLABLE CHUX;Lo;0;L;;;;;N;;;;; +A372;YI SYLLABLE CHU;Lo;0;L;;;;;N;;;;; +A373;YI SYLLABLE CHUP;Lo;0;L;;;;;N;;;;; +A374;YI SYLLABLE CHURX;Lo;0;L;;;;;N;;;;; +A375;YI SYLLABLE CHUR;Lo;0;L;;;;;N;;;;; +A376;YI SYLLABLE CHYT;Lo;0;L;;;;;N;;;;; +A377;YI SYLLABLE CHYX;Lo;0;L;;;;;N;;;;; +A378;YI SYLLABLE CHY;Lo;0;L;;;;;N;;;;; +A379;YI SYLLABLE CHYP;Lo;0;L;;;;;N;;;;; +A37A;YI SYLLABLE CHYRX;Lo;0;L;;;;;N;;;;; +A37B;YI SYLLABLE CHYR;Lo;0;L;;;;;N;;;;; +A37C;YI SYLLABLE RRAX;Lo;0;L;;;;;N;;;;; +A37D;YI SYLLABLE RRA;Lo;0;L;;;;;N;;;;; +A37E;YI SYLLABLE RRUOX;Lo;0;L;;;;;N;;;;; +A37F;YI SYLLABLE RRUO;Lo;0;L;;;;;N;;;;; +A380;YI SYLLABLE RROT;Lo;0;L;;;;;N;;;;; +A381;YI SYLLABLE RROX;Lo;0;L;;;;;N;;;;; +A382;YI SYLLABLE RRO;Lo;0;L;;;;;N;;;;; +A383;YI SYLLABLE RROP;Lo;0;L;;;;;N;;;;; +A384;YI SYLLABLE RRET;Lo;0;L;;;;;N;;;;; +A385;YI SYLLABLE RREX;Lo;0;L;;;;;N;;;;; +A386;YI SYLLABLE RRE;Lo;0;L;;;;;N;;;;; +A387;YI SYLLABLE RREP;Lo;0;L;;;;;N;;;;; +A388;YI SYLLABLE RRUT;Lo;0;L;;;;;N;;;;; +A389;YI SYLLABLE RRUX;Lo;0;L;;;;;N;;;;; +A38A;YI SYLLABLE RRU;Lo;0;L;;;;;N;;;;; +A38B;YI SYLLABLE RRUP;Lo;0;L;;;;;N;;;;; +A38C;YI SYLLABLE RRURX;Lo;0;L;;;;;N;;;;; +A38D;YI SYLLABLE RRUR;Lo;0;L;;;;;N;;;;; +A38E;YI SYLLABLE RRYT;Lo;0;L;;;;;N;;;;; +A38F;YI SYLLABLE RRYX;Lo;0;L;;;;;N;;;;; +A390;YI SYLLABLE RRY;Lo;0;L;;;;;N;;;;; +A391;YI SYLLABLE RRYP;Lo;0;L;;;;;N;;;;; +A392;YI SYLLABLE RRYRX;Lo;0;L;;;;;N;;;;; +A393;YI SYLLABLE RRYR;Lo;0;L;;;;;N;;;;; +A394;YI SYLLABLE NRAT;Lo;0;L;;;;;N;;;;; +A395;YI SYLLABLE NRAX;Lo;0;L;;;;;N;;;;; +A396;YI SYLLABLE NRA;Lo;0;L;;;;;N;;;;; +A397;YI SYLLABLE NRAP;Lo;0;L;;;;;N;;;;; +A398;YI SYLLABLE NROX;Lo;0;L;;;;;N;;;;; +A399;YI SYLLABLE NRO;Lo;0;L;;;;;N;;;;; +A39A;YI SYLLABLE NROP;Lo;0;L;;;;;N;;;;; +A39B;YI SYLLABLE NRET;Lo;0;L;;;;;N;;;;; +A39C;YI SYLLABLE NREX;Lo;0;L;;;;;N;;;;; +A39D;YI SYLLABLE NRE;Lo;0;L;;;;;N;;;;; +A39E;YI SYLLABLE NREP;Lo;0;L;;;;;N;;;;; +A39F;YI SYLLABLE NRUT;Lo;0;L;;;;;N;;;;; +A3A0;YI SYLLABLE NRUX;Lo;0;L;;;;;N;;;;; +A3A1;YI SYLLABLE NRU;Lo;0;L;;;;;N;;;;; +A3A2;YI SYLLABLE NRUP;Lo;0;L;;;;;N;;;;; +A3A3;YI SYLLABLE NRURX;Lo;0;L;;;;;N;;;;; +A3A4;YI SYLLABLE NRUR;Lo;0;L;;;;;N;;;;; +A3A5;YI SYLLABLE NRYT;Lo;0;L;;;;;N;;;;; +A3A6;YI SYLLABLE NRYX;Lo;0;L;;;;;N;;;;; +A3A7;YI SYLLABLE NRY;Lo;0;L;;;;;N;;;;; +A3A8;YI SYLLABLE NRYP;Lo;0;L;;;;;N;;;;; +A3A9;YI SYLLABLE NRYRX;Lo;0;L;;;;;N;;;;; +A3AA;YI SYLLABLE NRYR;Lo;0;L;;;;;N;;;;; +A3AB;YI SYLLABLE SHAT;Lo;0;L;;;;;N;;;;; +A3AC;YI SYLLABLE SHAX;Lo;0;L;;;;;N;;;;; +A3AD;YI SYLLABLE SHA;Lo;0;L;;;;;N;;;;; +A3AE;YI SYLLABLE SHAP;Lo;0;L;;;;;N;;;;; +A3AF;YI SYLLABLE SHUOX;Lo;0;L;;;;;N;;;;; +A3B0;YI SYLLABLE SHUO;Lo;0;L;;;;;N;;;;; +A3B1;YI SYLLABLE SHUOP;Lo;0;L;;;;;N;;;;; +A3B2;YI SYLLABLE SHOT;Lo;0;L;;;;;N;;;;; +A3B3;YI SYLLABLE SHOX;Lo;0;L;;;;;N;;;;; +A3B4;YI SYLLABLE SHO;Lo;0;L;;;;;N;;;;; +A3B5;YI SYLLABLE SHOP;Lo;0;L;;;;;N;;;;; +A3B6;YI SYLLABLE SHET;Lo;0;L;;;;;N;;;;; +A3B7;YI SYLLABLE SHEX;Lo;0;L;;;;;N;;;;; +A3B8;YI SYLLABLE SHE;Lo;0;L;;;;;N;;;;; +A3B9;YI SYLLABLE SHEP;Lo;0;L;;;;;N;;;;; +A3BA;YI SYLLABLE SHUT;Lo;0;L;;;;;N;;;;; +A3BB;YI SYLLABLE SHUX;Lo;0;L;;;;;N;;;;; +A3BC;YI SYLLABLE SHU;Lo;0;L;;;;;N;;;;; +A3BD;YI SYLLABLE SHUP;Lo;0;L;;;;;N;;;;; +A3BE;YI SYLLABLE SHURX;Lo;0;L;;;;;N;;;;; +A3BF;YI SYLLABLE SHUR;Lo;0;L;;;;;N;;;;; +A3C0;YI SYLLABLE SHYT;Lo;0;L;;;;;N;;;;; +A3C1;YI SYLLABLE SHYX;Lo;0;L;;;;;N;;;;; +A3C2;YI SYLLABLE SHY;Lo;0;L;;;;;N;;;;; +A3C3;YI SYLLABLE SHYP;Lo;0;L;;;;;N;;;;; +A3C4;YI SYLLABLE SHYRX;Lo;0;L;;;;;N;;;;; +A3C5;YI SYLLABLE SHYR;Lo;0;L;;;;;N;;;;; +A3C6;YI SYLLABLE RAT;Lo;0;L;;;;;N;;;;; +A3C7;YI SYLLABLE RAX;Lo;0;L;;;;;N;;;;; +A3C8;YI SYLLABLE RA;Lo;0;L;;;;;N;;;;; +A3C9;YI SYLLABLE RAP;Lo;0;L;;;;;N;;;;; +A3CA;YI SYLLABLE RUOX;Lo;0;L;;;;;N;;;;; +A3CB;YI SYLLABLE RUO;Lo;0;L;;;;;N;;;;; +A3CC;YI SYLLABLE RUOP;Lo;0;L;;;;;N;;;;; +A3CD;YI SYLLABLE ROT;Lo;0;L;;;;;N;;;;; +A3CE;YI SYLLABLE ROX;Lo;0;L;;;;;N;;;;; +A3CF;YI SYLLABLE RO;Lo;0;L;;;;;N;;;;; +A3D0;YI SYLLABLE ROP;Lo;0;L;;;;;N;;;;; +A3D1;YI SYLLABLE REX;Lo;0;L;;;;;N;;;;; +A3D2;YI SYLLABLE RE;Lo;0;L;;;;;N;;;;; +A3D3;YI SYLLABLE REP;Lo;0;L;;;;;N;;;;; +A3D4;YI SYLLABLE RUT;Lo;0;L;;;;;N;;;;; +A3D5;YI SYLLABLE RUX;Lo;0;L;;;;;N;;;;; +A3D6;YI SYLLABLE RU;Lo;0;L;;;;;N;;;;; +A3D7;YI SYLLABLE RUP;Lo;0;L;;;;;N;;;;; +A3D8;YI SYLLABLE RURX;Lo;0;L;;;;;N;;;;; +A3D9;YI SYLLABLE RUR;Lo;0;L;;;;;N;;;;; +A3DA;YI SYLLABLE RYT;Lo;0;L;;;;;N;;;;; +A3DB;YI SYLLABLE RYX;Lo;0;L;;;;;N;;;;; +A3DC;YI SYLLABLE RY;Lo;0;L;;;;;N;;;;; +A3DD;YI SYLLABLE RYP;Lo;0;L;;;;;N;;;;; +A3DE;YI SYLLABLE RYRX;Lo;0;L;;;;;N;;;;; +A3DF;YI SYLLABLE RYR;Lo;0;L;;;;;N;;;;; +A3E0;YI SYLLABLE JIT;Lo;0;L;;;;;N;;;;; +A3E1;YI SYLLABLE JIX;Lo;0;L;;;;;N;;;;; +A3E2;YI SYLLABLE JI;Lo;0;L;;;;;N;;;;; +A3E3;YI SYLLABLE JIP;Lo;0;L;;;;;N;;;;; +A3E4;YI SYLLABLE JIET;Lo;0;L;;;;;N;;;;; +A3E5;YI SYLLABLE JIEX;Lo;0;L;;;;;N;;;;; +A3E6;YI SYLLABLE JIE;Lo;0;L;;;;;N;;;;; +A3E7;YI SYLLABLE JIEP;Lo;0;L;;;;;N;;;;; +A3E8;YI SYLLABLE JUOT;Lo;0;L;;;;;N;;;;; +A3E9;YI SYLLABLE JUOX;Lo;0;L;;;;;N;;;;; +A3EA;YI SYLLABLE JUO;Lo;0;L;;;;;N;;;;; +A3EB;YI SYLLABLE JUOP;Lo;0;L;;;;;N;;;;; +A3EC;YI SYLLABLE JOT;Lo;0;L;;;;;N;;;;; +A3ED;YI SYLLABLE JOX;Lo;0;L;;;;;N;;;;; +A3EE;YI SYLLABLE JO;Lo;0;L;;;;;N;;;;; +A3EF;YI SYLLABLE JOP;Lo;0;L;;;;;N;;;;; +A3F0;YI SYLLABLE JUT;Lo;0;L;;;;;N;;;;; +A3F1;YI SYLLABLE JUX;Lo;0;L;;;;;N;;;;; +A3F2;YI SYLLABLE JU;Lo;0;L;;;;;N;;;;; +A3F3;YI SYLLABLE JUP;Lo;0;L;;;;;N;;;;; +A3F4;YI SYLLABLE JURX;Lo;0;L;;;;;N;;;;; +A3F5;YI SYLLABLE JUR;Lo;0;L;;;;;N;;;;; +A3F6;YI SYLLABLE JYT;Lo;0;L;;;;;N;;;;; +A3F7;YI SYLLABLE JYX;Lo;0;L;;;;;N;;;;; +A3F8;YI SYLLABLE JY;Lo;0;L;;;;;N;;;;; +A3F9;YI SYLLABLE JYP;Lo;0;L;;;;;N;;;;; +A3FA;YI SYLLABLE JYRX;Lo;0;L;;;;;N;;;;; +A3FB;YI SYLLABLE JYR;Lo;0;L;;;;;N;;;;; +A3FC;YI SYLLABLE QIT;Lo;0;L;;;;;N;;;;; +A3FD;YI SYLLABLE QIX;Lo;0;L;;;;;N;;;;; +A3FE;YI SYLLABLE QI;Lo;0;L;;;;;N;;;;; +A3FF;YI SYLLABLE QIP;Lo;0;L;;;;;N;;;;; +A400;YI SYLLABLE QIET;Lo;0;L;;;;;N;;;;; +A401;YI SYLLABLE QIEX;Lo;0;L;;;;;N;;;;; +A402;YI SYLLABLE QIE;Lo;0;L;;;;;N;;;;; +A403;YI SYLLABLE QIEP;Lo;0;L;;;;;N;;;;; +A404;YI SYLLABLE QUOT;Lo;0;L;;;;;N;;;;; +A405;YI SYLLABLE QUOX;Lo;0;L;;;;;N;;;;; +A406;YI SYLLABLE QUO;Lo;0;L;;;;;N;;;;; +A407;YI SYLLABLE QUOP;Lo;0;L;;;;;N;;;;; +A408;YI SYLLABLE QOT;Lo;0;L;;;;;N;;;;; +A409;YI SYLLABLE QOX;Lo;0;L;;;;;N;;;;; +A40A;YI SYLLABLE QO;Lo;0;L;;;;;N;;;;; +A40B;YI SYLLABLE QOP;Lo;0;L;;;;;N;;;;; +A40C;YI SYLLABLE QUT;Lo;0;L;;;;;N;;;;; +A40D;YI SYLLABLE QUX;Lo;0;L;;;;;N;;;;; +A40E;YI SYLLABLE QU;Lo;0;L;;;;;N;;;;; +A40F;YI SYLLABLE QUP;Lo;0;L;;;;;N;;;;; +A410;YI SYLLABLE QURX;Lo;0;L;;;;;N;;;;; +A411;YI SYLLABLE QUR;Lo;0;L;;;;;N;;;;; +A412;YI SYLLABLE QYT;Lo;0;L;;;;;N;;;;; +A413;YI SYLLABLE QYX;Lo;0;L;;;;;N;;;;; +A414;YI SYLLABLE QY;Lo;0;L;;;;;N;;;;; +A415;YI SYLLABLE QYP;Lo;0;L;;;;;N;;;;; +A416;YI SYLLABLE QYRX;Lo;0;L;;;;;N;;;;; +A417;YI SYLLABLE QYR;Lo;0;L;;;;;N;;;;; +A418;YI SYLLABLE JJIT;Lo;0;L;;;;;N;;;;; +A419;YI SYLLABLE JJIX;Lo;0;L;;;;;N;;;;; +A41A;YI SYLLABLE JJI;Lo;0;L;;;;;N;;;;; +A41B;YI SYLLABLE JJIP;Lo;0;L;;;;;N;;;;; +A41C;YI SYLLABLE JJIET;Lo;0;L;;;;;N;;;;; +A41D;YI SYLLABLE JJIEX;Lo;0;L;;;;;N;;;;; +A41E;YI SYLLABLE JJIE;Lo;0;L;;;;;N;;;;; +A41F;YI SYLLABLE JJIEP;Lo;0;L;;;;;N;;;;; +A420;YI SYLLABLE JJUOX;Lo;0;L;;;;;N;;;;; +A421;YI SYLLABLE JJUO;Lo;0;L;;;;;N;;;;; +A422;YI SYLLABLE JJUOP;Lo;0;L;;;;;N;;;;; +A423;YI SYLLABLE JJOT;Lo;0;L;;;;;N;;;;; +A424;YI SYLLABLE JJOX;Lo;0;L;;;;;N;;;;; +A425;YI SYLLABLE JJO;Lo;0;L;;;;;N;;;;; +A426;YI SYLLABLE JJOP;Lo;0;L;;;;;N;;;;; +A427;YI SYLLABLE JJUT;Lo;0;L;;;;;N;;;;; +A428;YI SYLLABLE JJUX;Lo;0;L;;;;;N;;;;; +A429;YI SYLLABLE JJU;Lo;0;L;;;;;N;;;;; +A42A;YI SYLLABLE JJUP;Lo;0;L;;;;;N;;;;; +A42B;YI SYLLABLE JJURX;Lo;0;L;;;;;N;;;;; +A42C;YI SYLLABLE JJUR;Lo;0;L;;;;;N;;;;; +A42D;YI SYLLABLE JJYT;Lo;0;L;;;;;N;;;;; +A42E;YI SYLLABLE JJYX;Lo;0;L;;;;;N;;;;; +A42F;YI SYLLABLE JJY;Lo;0;L;;;;;N;;;;; +A430;YI SYLLABLE JJYP;Lo;0;L;;;;;N;;;;; +A431;YI SYLLABLE NJIT;Lo;0;L;;;;;N;;;;; +A432;YI SYLLABLE NJIX;Lo;0;L;;;;;N;;;;; +A433;YI SYLLABLE NJI;Lo;0;L;;;;;N;;;;; +A434;YI SYLLABLE NJIP;Lo;0;L;;;;;N;;;;; +A435;YI SYLLABLE NJIET;Lo;0;L;;;;;N;;;;; +A436;YI SYLLABLE NJIEX;Lo;0;L;;;;;N;;;;; +A437;YI SYLLABLE NJIE;Lo;0;L;;;;;N;;;;; +A438;YI SYLLABLE NJIEP;Lo;0;L;;;;;N;;;;; +A439;YI SYLLABLE NJUOX;Lo;0;L;;;;;N;;;;; +A43A;YI SYLLABLE NJUO;Lo;0;L;;;;;N;;;;; +A43B;YI SYLLABLE NJOT;Lo;0;L;;;;;N;;;;; +A43C;YI SYLLABLE NJOX;Lo;0;L;;;;;N;;;;; +A43D;YI SYLLABLE NJO;Lo;0;L;;;;;N;;;;; +A43E;YI SYLLABLE NJOP;Lo;0;L;;;;;N;;;;; +A43F;YI SYLLABLE NJUX;Lo;0;L;;;;;N;;;;; +A440;YI SYLLABLE NJU;Lo;0;L;;;;;N;;;;; +A441;YI SYLLABLE NJUP;Lo;0;L;;;;;N;;;;; +A442;YI SYLLABLE NJURX;Lo;0;L;;;;;N;;;;; +A443;YI SYLLABLE NJUR;Lo;0;L;;;;;N;;;;; +A444;YI SYLLABLE NJYT;Lo;0;L;;;;;N;;;;; +A445;YI SYLLABLE NJYX;Lo;0;L;;;;;N;;;;; +A446;YI SYLLABLE NJY;Lo;0;L;;;;;N;;;;; +A447;YI SYLLABLE NJYP;Lo;0;L;;;;;N;;;;; +A448;YI SYLLABLE NJYRX;Lo;0;L;;;;;N;;;;; +A449;YI SYLLABLE NJYR;Lo;0;L;;;;;N;;;;; +A44A;YI SYLLABLE NYIT;Lo;0;L;;;;;N;;;;; +A44B;YI SYLLABLE NYIX;Lo;0;L;;;;;N;;;;; +A44C;YI SYLLABLE NYI;Lo;0;L;;;;;N;;;;; +A44D;YI SYLLABLE NYIP;Lo;0;L;;;;;N;;;;; +A44E;YI SYLLABLE NYIET;Lo;0;L;;;;;N;;;;; +A44F;YI SYLLABLE NYIEX;Lo;0;L;;;;;N;;;;; +A450;YI SYLLABLE NYIE;Lo;0;L;;;;;N;;;;; +A451;YI SYLLABLE NYIEP;Lo;0;L;;;;;N;;;;; +A452;YI SYLLABLE NYUOX;Lo;0;L;;;;;N;;;;; +A453;YI SYLLABLE NYUO;Lo;0;L;;;;;N;;;;; +A454;YI SYLLABLE NYUOP;Lo;0;L;;;;;N;;;;; +A455;YI SYLLABLE NYOT;Lo;0;L;;;;;N;;;;; +A456;YI SYLLABLE NYOX;Lo;0;L;;;;;N;;;;; +A457;YI SYLLABLE NYO;Lo;0;L;;;;;N;;;;; +A458;YI SYLLABLE NYOP;Lo;0;L;;;;;N;;;;; +A459;YI SYLLABLE NYUT;Lo;0;L;;;;;N;;;;; +A45A;YI SYLLABLE NYUX;Lo;0;L;;;;;N;;;;; +A45B;YI SYLLABLE NYU;Lo;0;L;;;;;N;;;;; +A45C;YI SYLLABLE NYUP;Lo;0;L;;;;;N;;;;; +A45D;YI SYLLABLE XIT;Lo;0;L;;;;;N;;;;; +A45E;YI SYLLABLE XIX;Lo;0;L;;;;;N;;;;; +A45F;YI SYLLABLE XI;Lo;0;L;;;;;N;;;;; +A460;YI SYLLABLE XIP;Lo;0;L;;;;;N;;;;; +A461;YI SYLLABLE XIET;Lo;0;L;;;;;N;;;;; +A462;YI SYLLABLE XIEX;Lo;0;L;;;;;N;;;;; +A463;YI SYLLABLE XIE;Lo;0;L;;;;;N;;;;; +A464;YI SYLLABLE XIEP;Lo;0;L;;;;;N;;;;; +A465;YI SYLLABLE XUOX;Lo;0;L;;;;;N;;;;; +A466;YI SYLLABLE XUO;Lo;0;L;;;;;N;;;;; +A467;YI SYLLABLE XOT;Lo;0;L;;;;;N;;;;; +A468;YI SYLLABLE XOX;Lo;0;L;;;;;N;;;;; +A469;YI SYLLABLE XO;Lo;0;L;;;;;N;;;;; +A46A;YI SYLLABLE XOP;Lo;0;L;;;;;N;;;;; +A46B;YI SYLLABLE XYT;Lo;0;L;;;;;N;;;;; +A46C;YI SYLLABLE XYX;Lo;0;L;;;;;N;;;;; +A46D;YI SYLLABLE XY;Lo;0;L;;;;;N;;;;; +A46E;YI SYLLABLE XYP;Lo;0;L;;;;;N;;;;; +A46F;YI SYLLABLE XYRX;Lo;0;L;;;;;N;;;;; +A470;YI SYLLABLE XYR;Lo;0;L;;;;;N;;;;; +A471;YI SYLLABLE YIT;Lo;0;L;;;;;N;;;;; +A472;YI SYLLABLE YIX;Lo;0;L;;;;;N;;;;; +A473;YI SYLLABLE YI;Lo;0;L;;;;;N;;;;; +A474;YI SYLLABLE YIP;Lo;0;L;;;;;N;;;;; +A475;YI SYLLABLE YIET;Lo;0;L;;;;;N;;;;; +A476;YI SYLLABLE YIEX;Lo;0;L;;;;;N;;;;; +A477;YI SYLLABLE YIE;Lo;0;L;;;;;N;;;;; +A478;YI SYLLABLE YIEP;Lo;0;L;;;;;N;;;;; +A479;YI SYLLABLE YUOT;Lo;0;L;;;;;N;;;;; +A47A;YI SYLLABLE YUOX;Lo;0;L;;;;;N;;;;; +A47B;YI SYLLABLE YUO;Lo;0;L;;;;;N;;;;; +A47C;YI SYLLABLE YUOP;Lo;0;L;;;;;N;;;;; +A47D;YI SYLLABLE YOT;Lo;0;L;;;;;N;;;;; +A47E;YI SYLLABLE YOX;Lo;0;L;;;;;N;;;;; +A47F;YI SYLLABLE YO;Lo;0;L;;;;;N;;;;; +A480;YI SYLLABLE YOP;Lo;0;L;;;;;N;;;;; +A481;YI SYLLABLE YUT;Lo;0;L;;;;;N;;;;; +A482;YI SYLLABLE YUX;Lo;0;L;;;;;N;;;;; +A483;YI SYLLABLE YU;Lo;0;L;;;;;N;;;;; +A484;YI SYLLABLE YUP;Lo;0;L;;;;;N;;;;; +A485;YI SYLLABLE YURX;Lo;0;L;;;;;N;;;;; +A486;YI SYLLABLE YUR;Lo;0;L;;;;;N;;;;; +A487;YI SYLLABLE YYT;Lo;0;L;;;;;N;;;;; +A488;YI SYLLABLE YYX;Lo;0;L;;;;;N;;;;; +A489;YI SYLLABLE YY;Lo;0;L;;;;;N;;;;; +A48A;YI SYLLABLE YYP;Lo;0;L;;;;;N;;;;; +A48B;YI SYLLABLE YYRX;Lo;0;L;;;;;N;;;;; +A48C;YI SYLLABLE YYR;Lo;0;L;;;;;N;;;;; +A490;YI RADICAL QOT;So;0;ON;;;;;N;;;;; +A491;YI RADICAL LI;So;0;ON;;;;;N;;;;; +A492;YI RADICAL KIT;So;0;ON;;;;;N;;;;; +A493;YI RADICAL NYIP;So;0;ON;;;;;N;;;;; +A494;YI RADICAL CYP;So;0;ON;;;;;N;;;;; +A495;YI RADICAL SSI;So;0;ON;;;;;N;;;;; +A496;YI RADICAL GGOP;So;0;ON;;;;;N;;;;; +A497;YI RADICAL GEP;So;0;ON;;;;;N;;;;; +A498;YI RADICAL MI;So;0;ON;;;;;N;;;;; +A499;YI RADICAL HXIT;So;0;ON;;;;;N;;;;; +A49A;YI RADICAL LYR;So;0;ON;;;;;N;;;;; +A49B;YI RADICAL BBUT;So;0;ON;;;;;N;;;;; +A49C;YI RADICAL MOP;So;0;ON;;;;;N;;;;; +A49D;YI RADICAL YO;So;0;ON;;;;;N;;;;; +A49E;YI RADICAL PUT;So;0;ON;;;;;N;;;;; +A49F;YI RADICAL HXUO;So;0;ON;;;;;N;;;;; +A4A0;YI RADICAL TAT;So;0;ON;;;;;N;;;;; +A4A1;YI RADICAL GA;So;0;ON;;;;;N;;;;; +A4A2;YI RADICAL ZUP;So;0;ON;;;;;N;;;;; +A4A3;YI RADICAL CYT;So;0;ON;;;;;N;;;;; +A4A4;YI RADICAL DDUR;So;0;ON;;;;;N;;;;; +A4A5;YI RADICAL BUR;So;0;ON;;;;;N;;;;; +A4A6;YI RADICAL GGUO;So;0;ON;;;;;N;;;;; +A4A7;YI RADICAL NYOP;So;0;ON;;;;;N;;;;; +A4A8;YI RADICAL TU;So;0;ON;;;;;N;;;;; +A4A9;YI RADICAL OP;So;0;ON;;;;;N;;;;; +A4AA;YI RADICAL JJUT;So;0;ON;;;;;N;;;;; +A4AB;YI RADICAL ZOT;So;0;ON;;;;;N;;;;; +A4AC;YI RADICAL PYT;So;0;ON;;;;;N;;;;; +A4AD;YI RADICAL HMO;So;0;ON;;;;;N;;;;; +A4AE;YI RADICAL YIT;So;0;ON;;;;;N;;;;; +A4AF;YI RADICAL VUR;So;0;ON;;;;;N;;;;; +A4B0;YI RADICAL SHY;So;0;ON;;;;;N;;;;; +A4B1;YI RADICAL VEP;So;0;ON;;;;;N;;;;; +A4B2;YI RADICAL ZA;So;0;ON;;;;;N;;;;; +A4B3;YI RADICAL JO;So;0;ON;;;;;N;;;;; +A4B4;YI RADICAL NZUP;So;0;ON;;;;;N;;;;; +A4B5;YI RADICAL JJY;So;0;ON;;;;;N;;;;; +A4B6;YI RADICAL GOT;So;0;ON;;;;;N;;;;; +A4B7;YI RADICAL JJIE;So;0;ON;;;;;N;;;;; +A4B8;YI RADICAL WO;So;0;ON;;;;;N;;;;; +A4B9;YI RADICAL DU;So;0;ON;;;;;N;;;;; +A4BA;YI RADICAL SHUR;So;0;ON;;;;;N;;;;; +A4BB;YI RADICAL LIE;So;0;ON;;;;;N;;;;; +A4BC;YI RADICAL CY;So;0;ON;;;;;N;;;;; +A4BD;YI RADICAL CUOP;So;0;ON;;;;;N;;;;; +A4BE;YI RADICAL CIP;So;0;ON;;;;;N;;;;; +A4BF;YI RADICAL HXOP;So;0;ON;;;;;N;;;;; +A4C0;YI RADICAL SHAT;So;0;ON;;;;;N;;;;; +A4C1;YI RADICAL ZUR;So;0;ON;;;;;N;;;;; +A4C2;YI RADICAL SHOP;So;0;ON;;;;;N;;;;; +A4C3;YI RADICAL CHE;So;0;ON;;;;;N;;;;; +A4C4;YI RADICAL ZZIET;So;0;ON;;;;;N;;;;; +A4C5;YI RADICAL NBIE;So;0;ON;;;;;N;;;;; +A4C6;YI RADICAL KE;So;0;ON;;;;;N;;;;; +A4D0;LISU LETTER BA;Lo;0;L;;;;;N;;;;; +A4D1;LISU LETTER PA;Lo;0;L;;;;;N;;;;; +A4D2;LISU LETTER PHA;Lo;0;L;;;;;N;;;;; +A4D3;LISU LETTER DA;Lo;0;L;;;;;N;;;;; +A4D4;LISU LETTER TA;Lo;0;L;;;;;N;;;;; +A4D5;LISU LETTER THA;Lo;0;L;;;;;N;;;;; +A4D6;LISU LETTER GA;Lo;0;L;;;;;N;;;;; +A4D7;LISU LETTER KA;Lo;0;L;;;;;N;;;;; +A4D8;LISU LETTER KHA;Lo;0;L;;;;;N;;;;; +A4D9;LISU LETTER JA;Lo;0;L;;;;;N;;;;; +A4DA;LISU LETTER CA;Lo;0;L;;;;;N;;;;; +A4DB;LISU LETTER CHA;Lo;0;L;;;;;N;;;;; +A4DC;LISU LETTER DZA;Lo;0;L;;;;;N;;;;; +A4DD;LISU LETTER TSA;Lo;0;L;;;;;N;;;;; +A4DE;LISU LETTER TSHA;Lo;0;L;;;;;N;;;;; +A4DF;LISU LETTER MA;Lo;0;L;;;;;N;;;;; +A4E0;LISU LETTER NA;Lo;0;L;;;;;N;;;;; +A4E1;LISU LETTER LA;Lo;0;L;;;;;N;;;;; +A4E2;LISU LETTER SA;Lo;0;L;;;;;N;;;;; +A4E3;LISU LETTER ZHA;Lo;0;L;;;;;N;;;;; +A4E4;LISU LETTER ZA;Lo;0;L;;;;;N;;;;; +A4E5;LISU LETTER NGA;Lo;0;L;;;;;N;;;;; +A4E6;LISU LETTER HA;Lo;0;L;;;;;N;;;;; +A4E7;LISU LETTER XA;Lo;0;L;;;;;N;;;;; +A4E8;LISU LETTER HHA;Lo;0;L;;;;;N;;;;; +A4E9;LISU LETTER FA;Lo;0;L;;;;;N;;;;; +A4EA;LISU LETTER WA;Lo;0;L;;;;;N;;;;; +A4EB;LISU LETTER SHA;Lo;0;L;;;;;N;;;;; +A4EC;LISU LETTER YA;Lo;0;L;;;;;N;;;;; +A4ED;LISU LETTER GHA;Lo;0;L;;;;;N;;;;; +A4EE;LISU LETTER A;Lo;0;L;;;;;N;;;;; +A4EF;LISU LETTER AE;Lo;0;L;;;;;N;;;;; +A4F0;LISU LETTER E;Lo;0;L;;;;;N;;;;; +A4F1;LISU LETTER EU;Lo;0;L;;;;;N;;;;; +A4F2;LISU LETTER I;Lo;0;L;;;;;N;;;;; +A4F3;LISU LETTER O;Lo;0;L;;;;;N;;;;; +A4F4;LISU LETTER U;Lo;0;L;;;;;N;;;;; +A4F5;LISU LETTER UE;Lo;0;L;;;;;N;;;;; +A4F6;LISU LETTER UH;Lo;0;L;;;;;N;;;;; +A4F7;LISU LETTER OE;Lo;0;L;;;;;N;;;;; +A4F8;LISU LETTER TONE MYA TI;Lm;0;L;;;;;N;;;;; +A4F9;LISU LETTER TONE NA PO;Lm;0;L;;;;;N;;;;; +A4FA;LISU LETTER TONE MYA CYA;Lm;0;L;;;;;N;;;;; +A4FB;LISU LETTER TONE MYA BO;Lm;0;L;;;;;N;;;;; +A4FC;LISU LETTER TONE MYA NA;Lm;0;L;;;;;N;;;;; +A4FD;LISU LETTER TONE MYA JEU;Lm;0;L;;;;;N;;;;; +A4FE;LISU PUNCTUATION COMMA;Po;0;L;;;;;N;;;;; +A4FF;LISU PUNCTUATION FULL STOP;Po;0;L;;;;;N;;;;; +A500;VAI SYLLABLE EE;Lo;0;L;;;;;N;;;;; +A501;VAI SYLLABLE EEN;Lo;0;L;;;;;N;;;;; +A502;VAI SYLLABLE HEE;Lo;0;L;;;;;N;;;;; +A503;VAI SYLLABLE WEE;Lo;0;L;;;;;N;;;;; +A504;VAI SYLLABLE WEEN;Lo;0;L;;;;;N;;;;; +A505;VAI SYLLABLE PEE;Lo;0;L;;;;;N;;;;; +A506;VAI SYLLABLE BHEE;Lo;0;L;;;;;N;;;;; +A507;VAI SYLLABLE BEE;Lo;0;L;;;;;N;;;;; +A508;VAI SYLLABLE MBEE;Lo;0;L;;;;;N;;;;; +A509;VAI SYLLABLE KPEE;Lo;0;L;;;;;N;;;;; +A50A;VAI SYLLABLE MGBEE;Lo;0;L;;;;;N;;;;; +A50B;VAI SYLLABLE GBEE;Lo;0;L;;;;;N;;;;; +A50C;VAI SYLLABLE FEE;Lo;0;L;;;;;N;;;;; +A50D;VAI SYLLABLE VEE;Lo;0;L;;;;;N;;;;; +A50E;VAI SYLLABLE TEE;Lo;0;L;;;;;N;;;;; +A50F;VAI SYLLABLE THEE;Lo;0;L;;;;;N;;;;; +A510;VAI SYLLABLE DHEE;Lo;0;L;;;;;N;;;;; +A511;VAI SYLLABLE DHHEE;Lo;0;L;;;;;N;;;;; +A512;VAI SYLLABLE LEE;Lo;0;L;;;;;N;;;;; +A513;VAI SYLLABLE REE;Lo;0;L;;;;;N;;;;; +A514;VAI SYLLABLE DEE;Lo;0;L;;;;;N;;;;; +A515;VAI SYLLABLE NDEE;Lo;0;L;;;;;N;;;;; +A516;VAI SYLLABLE SEE;Lo;0;L;;;;;N;;;;; +A517;VAI SYLLABLE SHEE;Lo;0;L;;;;;N;;;;; +A518;VAI SYLLABLE ZEE;Lo;0;L;;;;;N;;;;; +A519;VAI SYLLABLE ZHEE;Lo;0;L;;;;;N;;;;; +A51A;VAI SYLLABLE CEE;Lo;0;L;;;;;N;;;;; +A51B;VAI SYLLABLE JEE;Lo;0;L;;;;;N;;;;; +A51C;VAI SYLLABLE NJEE;Lo;0;L;;;;;N;;;;; +A51D;VAI SYLLABLE YEE;Lo;0;L;;;;;N;;;;; +A51E;VAI SYLLABLE KEE;Lo;0;L;;;;;N;;;;; +A51F;VAI SYLLABLE NGGEE;Lo;0;L;;;;;N;;;;; +A520;VAI SYLLABLE GEE;Lo;0;L;;;;;N;;;;; +A521;VAI SYLLABLE MEE;Lo;0;L;;;;;N;;;;; +A522;VAI SYLLABLE NEE;Lo;0;L;;;;;N;;;;; +A523;VAI SYLLABLE NYEE;Lo;0;L;;;;;N;;;;; +A524;VAI SYLLABLE I;Lo;0;L;;;;;N;;;;; +A525;VAI SYLLABLE IN;Lo;0;L;;;;;N;;;;; +A526;VAI SYLLABLE HI;Lo;0;L;;;;;N;;;;; +A527;VAI SYLLABLE HIN;Lo;0;L;;;;;N;;;;; +A528;VAI SYLLABLE WI;Lo;0;L;;;;;N;;;;; +A529;VAI SYLLABLE WIN;Lo;0;L;;;;;N;;;;; +A52A;VAI SYLLABLE PI;Lo;0;L;;;;;N;;;;; +A52B;VAI SYLLABLE BHI;Lo;0;L;;;;;N;;;;; +A52C;VAI SYLLABLE BI;Lo;0;L;;;;;N;;;;; +A52D;VAI SYLLABLE MBI;Lo;0;L;;;;;N;;;;; +A52E;VAI SYLLABLE KPI;Lo;0;L;;;;;N;;;;; +A52F;VAI SYLLABLE MGBI;Lo;0;L;;;;;N;;;;; +A530;VAI SYLLABLE GBI;Lo;0;L;;;;;N;;;;; +A531;VAI SYLLABLE FI;Lo;0;L;;;;;N;;;;; +A532;VAI SYLLABLE VI;Lo;0;L;;;;;N;;;;; +A533;VAI SYLLABLE TI;Lo;0;L;;;;;N;;;;; +A534;VAI SYLLABLE THI;Lo;0;L;;;;;N;;;;; +A535;VAI SYLLABLE DHI;Lo;0;L;;;;;N;;;;; +A536;VAI SYLLABLE DHHI;Lo;0;L;;;;;N;;;;; +A537;VAI SYLLABLE LI;Lo;0;L;;;;;N;;;;; +A538;VAI SYLLABLE RI;Lo;0;L;;;;;N;;;;; +A539;VAI SYLLABLE DI;Lo;0;L;;;;;N;;;;; +A53A;VAI SYLLABLE NDI;Lo;0;L;;;;;N;;;;; +A53B;VAI SYLLABLE SI;Lo;0;L;;;;;N;;;;; +A53C;VAI SYLLABLE SHI;Lo;0;L;;;;;N;;;;; +A53D;VAI SYLLABLE ZI;Lo;0;L;;;;;N;;;;; +A53E;VAI SYLLABLE ZHI;Lo;0;L;;;;;N;;;;; +A53F;VAI SYLLABLE CI;Lo;0;L;;;;;N;;;;; +A540;VAI SYLLABLE JI;Lo;0;L;;;;;N;;;;; +A541;VAI SYLLABLE NJI;Lo;0;L;;;;;N;;;;; +A542;VAI SYLLABLE YI;Lo;0;L;;;;;N;;;;; +A543;VAI SYLLABLE KI;Lo;0;L;;;;;N;;;;; +A544;VAI SYLLABLE NGGI;Lo;0;L;;;;;N;;;;; +A545;VAI SYLLABLE GI;Lo;0;L;;;;;N;;;;; +A546;VAI SYLLABLE MI;Lo;0;L;;;;;N;;;;; +A547;VAI SYLLABLE NI;Lo;0;L;;;;;N;;;;; +A548;VAI SYLLABLE NYI;Lo;0;L;;;;;N;;;;; +A549;VAI SYLLABLE A;Lo;0;L;;;;;N;;;;; +A54A;VAI SYLLABLE AN;Lo;0;L;;;;;N;;;;; +A54B;VAI SYLLABLE NGAN;Lo;0;L;;;;;N;;;;; +A54C;VAI SYLLABLE HA;Lo;0;L;;;;;N;;;;; +A54D;VAI SYLLABLE HAN;Lo;0;L;;;;;N;;;;; +A54E;VAI SYLLABLE WA;Lo;0;L;;;;;N;;;;; +A54F;VAI SYLLABLE WAN;Lo;0;L;;;;;N;;;;; +A550;VAI SYLLABLE PA;Lo;0;L;;;;;N;;;;; +A551;VAI SYLLABLE BHA;Lo;0;L;;;;;N;;;;; +A552;VAI SYLLABLE BA;Lo;0;L;;;;;N;;;;; +A553;VAI SYLLABLE MBA;Lo;0;L;;;;;N;;;;; +A554;VAI SYLLABLE KPA;Lo;0;L;;;;;N;;;;; +A555;VAI SYLLABLE KPAN;Lo;0;L;;;;;N;;;;; +A556;VAI SYLLABLE MGBA;Lo;0;L;;;;;N;;;;; +A557;VAI SYLLABLE GBA;Lo;0;L;;;;;N;;;;; +A558;VAI SYLLABLE FA;Lo;0;L;;;;;N;;;;; +A559;VAI SYLLABLE VA;Lo;0;L;;;;;N;;;;; +A55A;VAI SYLLABLE TA;Lo;0;L;;;;;N;;;;; +A55B;VAI SYLLABLE THA;Lo;0;L;;;;;N;;;;; +A55C;VAI SYLLABLE DHA;Lo;0;L;;;;;N;;;;; +A55D;VAI SYLLABLE DHHA;Lo;0;L;;;;;N;;;;; +A55E;VAI SYLLABLE LA;Lo;0;L;;;;;N;;;;; +A55F;VAI SYLLABLE RA;Lo;0;L;;;;;N;;;;; +A560;VAI SYLLABLE DA;Lo;0;L;;;;;N;;;;; +A561;VAI SYLLABLE NDA;Lo;0;L;;;;;N;;;;; +A562;VAI SYLLABLE SA;Lo;0;L;;;;;N;;;;; +A563;VAI SYLLABLE SHA;Lo;0;L;;;;;N;;;;; +A564;VAI SYLLABLE ZA;Lo;0;L;;;;;N;;;;; +A565;VAI SYLLABLE ZHA;Lo;0;L;;;;;N;;;;; +A566;VAI SYLLABLE CA;Lo;0;L;;;;;N;;;;; +A567;VAI SYLLABLE JA;Lo;0;L;;;;;N;;;;; +A568;VAI SYLLABLE NJA;Lo;0;L;;;;;N;;;;; +A569;VAI SYLLABLE YA;Lo;0;L;;;;;N;;;;; +A56A;VAI SYLLABLE KA;Lo;0;L;;;;;N;;;;; +A56B;VAI SYLLABLE KAN;Lo;0;L;;;;;N;;;;; +A56C;VAI SYLLABLE NGGA;Lo;0;L;;;;;N;;;;; +A56D;VAI SYLLABLE GA;Lo;0;L;;;;;N;;;;; +A56E;VAI SYLLABLE MA;Lo;0;L;;;;;N;;;;; +A56F;VAI SYLLABLE NA;Lo;0;L;;;;;N;;;;; +A570;VAI SYLLABLE NYA;Lo;0;L;;;;;N;;;;; +A571;VAI SYLLABLE OO;Lo;0;L;;;;;N;;;;; +A572;VAI SYLLABLE OON;Lo;0;L;;;;;N;;;;; +A573;VAI SYLLABLE HOO;Lo;0;L;;;;;N;;;;; +A574;VAI SYLLABLE WOO;Lo;0;L;;;;;N;;;;; +A575;VAI SYLLABLE WOON;Lo;0;L;;;;;N;;;;; +A576;VAI SYLLABLE POO;Lo;0;L;;;;;N;;;;; +A577;VAI SYLLABLE BHOO;Lo;0;L;;;;;N;;;;; +A578;VAI SYLLABLE BOO;Lo;0;L;;;;;N;;;;; +A579;VAI SYLLABLE MBOO;Lo;0;L;;;;;N;;;;; +A57A;VAI SYLLABLE KPOO;Lo;0;L;;;;;N;;;;; +A57B;VAI SYLLABLE MGBOO;Lo;0;L;;;;;N;;;;; +A57C;VAI SYLLABLE GBOO;Lo;0;L;;;;;N;;;;; +A57D;VAI SYLLABLE FOO;Lo;0;L;;;;;N;;;;; +A57E;VAI SYLLABLE VOO;Lo;0;L;;;;;N;;;;; +A57F;VAI SYLLABLE TOO;Lo;0;L;;;;;N;;;;; +A580;VAI SYLLABLE THOO;Lo;0;L;;;;;N;;;;; +A581;VAI SYLLABLE DHOO;Lo;0;L;;;;;N;;;;; +A582;VAI SYLLABLE DHHOO;Lo;0;L;;;;;N;;;;; +A583;VAI SYLLABLE LOO;Lo;0;L;;;;;N;;;;; +A584;VAI SYLLABLE ROO;Lo;0;L;;;;;N;;;;; +A585;VAI SYLLABLE DOO;Lo;0;L;;;;;N;;;;; +A586;VAI SYLLABLE NDOO;Lo;0;L;;;;;N;;;;; +A587;VAI SYLLABLE SOO;Lo;0;L;;;;;N;;;;; +A588;VAI SYLLABLE SHOO;Lo;0;L;;;;;N;;;;; +A589;VAI SYLLABLE ZOO;Lo;0;L;;;;;N;;;;; +A58A;VAI SYLLABLE ZHOO;Lo;0;L;;;;;N;;;;; +A58B;VAI SYLLABLE COO;Lo;0;L;;;;;N;;;;; +A58C;VAI SYLLABLE JOO;Lo;0;L;;;;;N;;;;; +A58D;VAI SYLLABLE NJOO;Lo;0;L;;;;;N;;;;; +A58E;VAI SYLLABLE YOO;Lo;0;L;;;;;N;;;;; +A58F;VAI SYLLABLE KOO;Lo;0;L;;;;;N;;;;; +A590;VAI SYLLABLE NGGOO;Lo;0;L;;;;;N;;;;; +A591;VAI SYLLABLE GOO;Lo;0;L;;;;;N;;;;; +A592;VAI SYLLABLE MOO;Lo;0;L;;;;;N;;;;; +A593;VAI SYLLABLE NOO;Lo;0;L;;;;;N;;;;; +A594;VAI SYLLABLE NYOO;Lo;0;L;;;;;N;;;;; +A595;VAI SYLLABLE U;Lo;0;L;;;;;N;;;;; +A596;VAI SYLLABLE UN;Lo;0;L;;;;;N;;;;; +A597;VAI SYLLABLE HU;Lo;0;L;;;;;N;;;;; +A598;VAI SYLLABLE HUN;Lo;0;L;;;;;N;;;;; +A599;VAI SYLLABLE WU;Lo;0;L;;;;;N;;;;; +A59A;VAI SYLLABLE WUN;Lo;0;L;;;;;N;;;;; +A59B;VAI SYLLABLE PU;Lo;0;L;;;;;N;;;;; +A59C;VAI SYLLABLE BHU;Lo;0;L;;;;;N;;;;; +A59D;VAI SYLLABLE BU;Lo;0;L;;;;;N;;;;; +A59E;VAI SYLLABLE MBU;Lo;0;L;;;;;N;;;;; +A59F;VAI SYLLABLE KPU;Lo;0;L;;;;;N;;;;; +A5A0;VAI SYLLABLE MGBU;Lo;0;L;;;;;N;;;;; +A5A1;VAI SYLLABLE GBU;Lo;0;L;;;;;N;;;;; +A5A2;VAI SYLLABLE FU;Lo;0;L;;;;;N;;;;; +A5A3;VAI SYLLABLE VU;Lo;0;L;;;;;N;;;;; +A5A4;VAI SYLLABLE TU;Lo;0;L;;;;;N;;;;; +A5A5;VAI SYLLABLE THU;Lo;0;L;;;;;N;;;;; +A5A6;VAI SYLLABLE DHU;Lo;0;L;;;;;N;;;;; +A5A7;VAI SYLLABLE DHHU;Lo;0;L;;;;;N;;;;; +A5A8;VAI SYLLABLE LU;Lo;0;L;;;;;N;;;;; +A5A9;VAI SYLLABLE RU;Lo;0;L;;;;;N;;;;; +A5AA;VAI SYLLABLE DU;Lo;0;L;;;;;N;;;;; +A5AB;VAI SYLLABLE NDU;Lo;0;L;;;;;N;;;;; +A5AC;VAI SYLLABLE SU;Lo;0;L;;;;;N;;;;; +A5AD;VAI SYLLABLE SHU;Lo;0;L;;;;;N;;;;; +A5AE;VAI SYLLABLE ZU;Lo;0;L;;;;;N;;;;; +A5AF;VAI SYLLABLE ZHU;Lo;0;L;;;;;N;;;;; +A5B0;VAI SYLLABLE CU;Lo;0;L;;;;;N;;;;; +A5B1;VAI SYLLABLE JU;Lo;0;L;;;;;N;;;;; +A5B2;VAI SYLLABLE NJU;Lo;0;L;;;;;N;;;;; +A5B3;VAI SYLLABLE YU;Lo;0;L;;;;;N;;;;; +A5B4;VAI SYLLABLE KU;Lo;0;L;;;;;N;;;;; +A5B5;VAI SYLLABLE NGGU;Lo;0;L;;;;;N;;;;; +A5B6;VAI SYLLABLE GU;Lo;0;L;;;;;N;;;;; +A5B7;VAI SYLLABLE MU;Lo;0;L;;;;;N;;;;; +A5B8;VAI SYLLABLE NU;Lo;0;L;;;;;N;;;;; +A5B9;VAI SYLLABLE NYU;Lo;0;L;;;;;N;;;;; +A5BA;VAI SYLLABLE O;Lo;0;L;;;;;N;;;;; +A5BB;VAI SYLLABLE ON;Lo;0;L;;;;;N;;;;; +A5BC;VAI SYLLABLE NGON;Lo;0;L;;;;;N;;;;; +A5BD;VAI SYLLABLE HO;Lo;0;L;;;;;N;;;;; +A5BE;VAI SYLLABLE HON;Lo;0;L;;;;;N;;;;; +A5BF;VAI SYLLABLE WO;Lo;0;L;;;;;N;;;;; +A5C0;VAI SYLLABLE WON;Lo;0;L;;;;;N;;;;; +A5C1;VAI SYLLABLE PO;Lo;0;L;;;;;N;;;;; +A5C2;VAI SYLLABLE BHO;Lo;0;L;;;;;N;;;;; +A5C3;VAI SYLLABLE BO;Lo;0;L;;;;;N;;;;; +A5C4;VAI SYLLABLE MBO;Lo;0;L;;;;;N;;;;; +A5C5;VAI SYLLABLE KPO;Lo;0;L;;;;;N;;;;; +A5C6;VAI SYLLABLE MGBO;Lo;0;L;;;;;N;;;;; +A5C7;VAI SYLLABLE GBO;Lo;0;L;;;;;N;;;;; +A5C8;VAI SYLLABLE GBON;Lo;0;L;;;;;N;;;;; +A5C9;VAI SYLLABLE FO;Lo;0;L;;;;;N;;;;; +A5CA;VAI SYLLABLE VO;Lo;0;L;;;;;N;;;;; +A5CB;VAI SYLLABLE TO;Lo;0;L;;;;;N;;;;; +A5CC;VAI SYLLABLE THO;Lo;0;L;;;;;N;;;;; +A5CD;VAI SYLLABLE DHO;Lo;0;L;;;;;N;;;;; +A5CE;VAI SYLLABLE DHHO;Lo;0;L;;;;;N;;;;; +A5CF;VAI SYLLABLE LO;Lo;0;L;;;;;N;;;;; +A5D0;VAI SYLLABLE RO;Lo;0;L;;;;;N;;;;; +A5D1;VAI SYLLABLE DO;Lo;0;L;;;;;N;;;;; +A5D2;VAI SYLLABLE NDO;Lo;0;L;;;;;N;;;;; +A5D3;VAI SYLLABLE SO;Lo;0;L;;;;;N;;;;; +A5D4;VAI SYLLABLE SHO;Lo;0;L;;;;;N;;;;; +A5D5;VAI SYLLABLE ZO;Lo;0;L;;;;;N;;;;; +A5D6;VAI SYLLABLE ZHO;Lo;0;L;;;;;N;;;;; +A5D7;VAI SYLLABLE CO;Lo;0;L;;;;;N;;;;; +A5D8;VAI SYLLABLE JO;Lo;0;L;;;;;N;;;;; +A5D9;VAI SYLLABLE NJO;Lo;0;L;;;;;N;;;;; +A5DA;VAI SYLLABLE YO;Lo;0;L;;;;;N;;;;; +A5DB;VAI SYLLABLE KO;Lo;0;L;;;;;N;;;;; +A5DC;VAI SYLLABLE NGGO;Lo;0;L;;;;;N;;;;; +A5DD;VAI SYLLABLE GO;Lo;0;L;;;;;N;;;;; +A5DE;VAI SYLLABLE MO;Lo;0;L;;;;;N;;;;; +A5DF;VAI SYLLABLE NO;Lo;0;L;;;;;N;;;;; +A5E0;VAI SYLLABLE NYO;Lo;0;L;;;;;N;;;;; +A5E1;VAI SYLLABLE E;Lo;0;L;;;;;N;;;;; +A5E2;VAI SYLLABLE EN;Lo;0;L;;;;;N;;;;; +A5E3;VAI SYLLABLE NGEN;Lo;0;L;;;;;N;;;;; +A5E4;VAI SYLLABLE HE;Lo;0;L;;;;;N;;;;; +A5E5;VAI SYLLABLE HEN;Lo;0;L;;;;;N;;;;; +A5E6;VAI SYLLABLE WE;Lo;0;L;;;;;N;;;;; +A5E7;VAI SYLLABLE WEN;Lo;0;L;;;;;N;;;;; +A5E8;VAI SYLLABLE PE;Lo;0;L;;;;;N;;;;; +A5E9;VAI SYLLABLE BHE;Lo;0;L;;;;;N;;;;; +A5EA;VAI SYLLABLE BE;Lo;0;L;;;;;N;;;;; +A5EB;VAI SYLLABLE MBE;Lo;0;L;;;;;N;;;;; +A5EC;VAI SYLLABLE KPE;Lo;0;L;;;;;N;;;;; +A5ED;VAI SYLLABLE KPEN;Lo;0;L;;;;;N;;;;; +A5EE;VAI SYLLABLE MGBE;Lo;0;L;;;;;N;;;;; +A5EF;VAI SYLLABLE GBE;Lo;0;L;;;;;N;;;;; +A5F0;VAI SYLLABLE GBEN;Lo;0;L;;;;;N;;;;; +A5F1;VAI SYLLABLE FE;Lo;0;L;;;;;N;;;;; +A5F2;VAI SYLLABLE VE;Lo;0;L;;;;;N;;;;; +A5F3;VAI SYLLABLE TE;Lo;0;L;;;;;N;;;;; +A5F4;VAI SYLLABLE THE;Lo;0;L;;;;;N;;;;; +A5F5;VAI SYLLABLE DHE;Lo;0;L;;;;;N;;;;; +A5F6;VAI SYLLABLE DHHE;Lo;0;L;;;;;N;;;;; +A5F7;VAI SYLLABLE LE;Lo;0;L;;;;;N;;;;; +A5F8;VAI SYLLABLE RE;Lo;0;L;;;;;N;;;;; +A5F9;VAI SYLLABLE DE;Lo;0;L;;;;;N;;;;; +A5FA;VAI SYLLABLE NDE;Lo;0;L;;;;;N;;;;; +A5FB;VAI SYLLABLE SE;Lo;0;L;;;;;N;;;;; +A5FC;VAI SYLLABLE SHE;Lo;0;L;;;;;N;;;;; +A5FD;VAI SYLLABLE ZE;Lo;0;L;;;;;N;;;;; +A5FE;VAI SYLLABLE ZHE;Lo;0;L;;;;;N;;;;; +A5FF;VAI SYLLABLE CE;Lo;0;L;;;;;N;;;;; +A600;VAI SYLLABLE JE;Lo;0;L;;;;;N;;;;; +A601;VAI SYLLABLE NJE;Lo;0;L;;;;;N;;;;; +A602;VAI SYLLABLE YE;Lo;0;L;;;;;N;;;;; +A603;VAI SYLLABLE KE;Lo;0;L;;;;;N;;;;; +A604;VAI SYLLABLE NGGE;Lo;0;L;;;;;N;;;;; +A605;VAI SYLLABLE NGGEN;Lo;0;L;;;;;N;;;;; +A606;VAI SYLLABLE GE;Lo;0;L;;;;;N;;;;; +A607;VAI SYLLABLE GEN;Lo;0;L;;;;;N;;;;; +A608;VAI SYLLABLE ME;Lo;0;L;;;;;N;;;;; +A609;VAI SYLLABLE NE;Lo;0;L;;;;;N;;;;; +A60A;VAI SYLLABLE NYE;Lo;0;L;;;;;N;;;;; +A60B;VAI SYLLABLE NG;Lo;0;L;;;;;N;;;;; +A60C;VAI SYLLABLE LENGTHENER;Lm;0;L;;;;;N;;;;; +A60D;VAI COMMA;Po;0;ON;;;;;N;;;;; +A60E;VAI FULL STOP;Po;0;ON;;;;;N;;;;; +A60F;VAI QUESTION MARK;Po;0;ON;;;;;N;;;;; +A610;VAI SYLLABLE NDOLE FA;Lo;0;L;;;;;N;;;;; +A611;VAI SYLLABLE NDOLE KA;Lo;0;L;;;;;N;;;;; +A612;VAI SYLLABLE NDOLE SOO;Lo;0;L;;;;;N;;;;; +A613;VAI SYMBOL FEENG;Lo;0;L;;;;;N;;;;; +A614;VAI SYMBOL KEENG;Lo;0;L;;;;;N;;;;; +A615;VAI SYMBOL TING;Lo;0;L;;;;;N;;;;; +A616;VAI SYMBOL NII;Lo;0;L;;;;;N;;;;; +A617;VAI SYMBOL BANG;Lo;0;L;;;;;N;;;;; +A618;VAI SYMBOL FAA;Lo;0;L;;;;;N;;;;; +A619;VAI SYMBOL TAA;Lo;0;L;;;;;N;;;;; +A61A;VAI SYMBOL DANG;Lo;0;L;;;;;N;;;;; +A61B;VAI SYMBOL DOONG;Lo;0;L;;;;;N;;;;; +A61C;VAI SYMBOL KUNG;Lo;0;L;;;;;N;;;;; +A61D;VAI SYMBOL TONG;Lo;0;L;;;;;N;;;;; +A61E;VAI SYMBOL DO-O;Lo;0;L;;;;;N;;;;; +A61F;VAI SYMBOL JONG;Lo;0;L;;;;;N;;;;; +A620;VAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +A621;VAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +A622;VAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +A623;VAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +A624;VAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +A625;VAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +A626;VAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +A627;VAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +A628;VAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +A629;VAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +A62A;VAI SYLLABLE NDOLE MA;Lo;0;L;;;;;N;;;;; +A62B;VAI SYLLABLE NDOLE DO;Lo;0;L;;;;;N;;;;; +A640;CYRILLIC CAPITAL LETTER ZEMLYA;Lu;0;L;;;;;N;;;;A641; +A641;CYRILLIC SMALL LETTER ZEMLYA;Ll;0;L;;;;;N;;;A640;;A640 +A642;CYRILLIC CAPITAL LETTER DZELO;Lu;0;L;;;;;N;;;;A643; +A643;CYRILLIC SMALL LETTER DZELO;Ll;0;L;;;;;N;;;A642;;A642 +A644;CYRILLIC CAPITAL LETTER REVERSED DZE;Lu;0;L;;;;;N;;;;A645; +A645;CYRILLIC SMALL LETTER REVERSED DZE;Ll;0;L;;;;;N;;;A644;;A644 +A646;CYRILLIC CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;A647; +A647;CYRILLIC SMALL LETTER IOTA;Ll;0;L;;;;;N;;;A646;;A646 +A648;CYRILLIC CAPITAL LETTER DJERV;Lu;0;L;;;;;N;;;;A649; +A649;CYRILLIC SMALL LETTER DJERV;Ll;0;L;;;;;N;;;A648;;A648 +A64A;CYRILLIC CAPITAL LETTER MONOGRAPH UK;Lu;0;L;;;;;N;;;;A64B; +A64B;CYRILLIC SMALL LETTER MONOGRAPH UK;Ll;0;L;;;;;N;;;A64A;;A64A +A64C;CYRILLIC CAPITAL LETTER BROAD OMEGA;Lu;0;L;;;;;N;;;;A64D; +A64D;CYRILLIC SMALL LETTER BROAD OMEGA;Ll;0;L;;;;;N;;;A64C;;A64C +A64E;CYRILLIC CAPITAL LETTER NEUTRAL YER;Lu;0;L;;;;;N;;;;A64F; +A64F;CYRILLIC SMALL LETTER NEUTRAL YER;Ll;0;L;;;;;N;;;A64E;;A64E +A650;CYRILLIC CAPITAL LETTER YERU WITH BACK YER;Lu;0;L;;;;;N;;;;A651; +A651;CYRILLIC SMALL LETTER YERU WITH BACK YER;Ll;0;L;;;;;N;;;A650;;A650 +A652;CYRILLIC CAPITAL LETTER IOTIFIED YAT;Lu;0;L;;;;;N;;;;A653; +A653;CYRILLIC SMALL LETTER IOTIFIED YAT;Ll;0;L;;;;;N;;;A652;;A652 +A654;CYRILLIC CAPITAL LETTER REVERSED YU;Lu;0;L;;;;;N;;;;A655; +A655;CYRILLIC SMALL LETTER REVERSED YU;Ll;0;L;;;;;N;;;A654;;A654 +A656;CYRILLIC CAPITAL LETTER IOTIFIED A;Lu;0;L;;;;;N;;;;A657; +A657;CYRILLIC SMALL LETTER IOTIFIED A;Ll;0;L;;;;;N;;;A656;;A656 +A658;CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS;Lu;0;L;;;;;N;;;;A659; +A659;CYRILLIC SMALL LETTER CLOSED LITTLE YUS;Ll;0;L;;;;;N;;;A658;;A658 +A65A;CYRILLIC CAPITAL LETTER BLENDED YUS;Lu;0;L;;;;;N;;;;A65B; +A65B;CYRILLIC SMALL LETTER BLENDED YUS;Ll;0;L;;;;;N;;;A65A;;A65A +A65C;CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS;Lu;0;L;;;;;N;;;;A65D; +A65D;CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS;Ll;0;L;;;;;N;;;A65C;;A65C +A65E;CYRILLIC CAPITAL LETTER YN;Lu;0;L;;;;;N;;;;A65F; +A65F;CYRILLIC SMALL LETTER YN;Ll;0;L;;;;;N;;;A65E;;A65E +A660;CYRILLIC CAPITAL LETTER REVERSED TSE;Lu;0;L;;;;;N;;;;A661; +A661;CYRILLIC SMALL LETTER REVERSED TSE;Ll;0;L;;;;;N;;;A660;;A660 +A662;CYRILLIC CAPITAL LETTER SOFT DE;Lu;0;L;;;;;N;;;;A663; +A663;CYRILLIC SMALL LETTER SOFT DE;Ll;0;L;;;;;N;;;A662;;A662 +A664;CYRILLIC CAPITAL LETTER SOFT EL;Lu;0;L;;;;;N;;;;A665; +A665;CYRILLIC SMALL LETTER SOFT EL;Ll;0;L;;;;;N;;;A664;;A664 +A666;CYRILLIC CAPITAL LETTER SOFT EM;Lu;0;L;;;;;N;;;;A667; +A667;CYRILLIC SMALL LETTER SOFT EM;Ll;0;L;;;;;N;;;A666;;A666 +A668;CYRILLIC CAPITAL LETTER MONOCULAR O;Lu;0;L;;;;;N;;;;A669; +A669;CYRILLIC SMALL LETTER MONOCULAR O;Ll;0;L;;;;;N;;;A668;;A668 +A66A;CYRILLIC CAPITAL LETTER BINOCULAR O;Lu;0;L;;;;;N;;;;A66B; +A66B;CYRILLIC SMALL LETTER BINOCULAR O;Ll;0;L;;;;;N;;;A66A;;A66A +A66C;CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O;Lu;0;L;;;;;N;;;;A66D; +A66D;CYRILLIC SMALL LETTER DOUBLE MONOCULAR O;Ll;0;L;;;;;N;;;A66C;;A66C +A66E;CYRILLIC LETTER MULTIOCULAR O;Lo;0;L;;;;;N;;;;; +A66F;COMBINING CYRILLIC VZMET;Mn;230;NSM;;;;;N;;;;; +A670;COMBINING CYRILLIC TEN MILLIONS SIGN;Me;0;NSM;;;;;N;;;;; +A671;COMBINING CYRILLIC HUNDRED MILLIONS SIGN;Me;0;NSM;;;;;N;;;;; +A672;COMBINING CYRILLIC THOUSAND MILLIONS SIGN;Me;0;NSM;;;;;N;;;;; +A673;SLAVONIC ASTERISK;Po;0;ON;;;;;N;;;;; +A674;COMBINING CYRILLIC LETTER UKRAINIAN IE;Mn;230;NSM;;;;;N;;;;; +A675;COMBINING CYRILLIC LETTER I;Mn;230;NSM;;;;;N;;;;; +A676;COMBINING CYRILLIC LETTER YI;Mn;230;NSM;;;;;N;;;;; +A677;COMBINING CYRILLIC LETTER U;Mn;230;NSM;;;;;N;;;;; +A678;COMBINING CYRILLIC LETTER HARD SIGN;Mn;230;NSM;;;;;N;;;;; +A679;COMBINING CYRILLIC LETTER YERU;Mn;230;NSM;;;;;N;;;;; +A67A;COMBINING CYRILLIC LETTER SOFT SIGN;Mn;230;NSM;;;;;N;;;;; +A67B;COMBINING CYRILLIC LETTER OMEGA;Mn;230;NSM;;;;;N;;;;; +A67C;COMBINING CYRILLIC KAVYKA;Mn;230;NSM;;;;;N;;;;; +A67D;COMBINING CYRILLIC PAYEROK;Mn;230;NSM;;;;;N;;;;; +A67E;CYRILLIC KAVYKA;Po;0;ON;;;;;N;;;;; +A67F;CYRILLIC PAYEROK;Lm;0;ON;;;;;N;;;;; +A680;CYRILLIC CAPITAL LETTER DWE;Lu;0;L;;;;;N;;;;A681; +A681;CYRILLIC SMALL LETTER DWE;Ll;0;L;;;;;N;;;A680;;A680 +A682;CYRILLIC CAPITAL LETTER DZWE;Lu;0;L;;;;;N;;;;A683; +A683;CYRILLIC SMALL LETTER DZWE;Ll;0;L;;;;;N;;;A682;;A682 +A684;CYRILLIC CAPITAL LETTER ZHWE;Lu;0;L;;;;;N;;;;A685; +A685;CYRILLIC SMALL LETTER ZHWE;Ll;0;L;;;;;N;;;A684;;A684 +A686;CYRILLIC CAPITAL LETTER CCHE;Lu;0;L;;;;;N;;;;A687; +A687;CYRILLIC SMALL LETTER CCHE;Ll;0;L;;;;;N;;;A686;;A686 +A688;CYRILLIC CAPITAL LETTER DZZE;Lu;0;L;;;;;N;;;;A689; +A689;CYRILLIC SMALL LETTER DZZE;Ll;0;L;;;;;N;;;A688;;A688 +A68A;CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;A68B; +A68B;CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;A68A;;A68A +A68C;CYRILLIC CAPITAL LETTER TWE;Lu;0;L;;;;;N;;;;A68D; +A68D;CYRILLIC SMALL LETTER TWE;Ll;0;L;;;;;N;;;A68C;;A68C +A68E;CYRILLIC CAPITAL LETTER TSWE;Lu;0;L;;;;;N;;;;A68F; +A68F;CYRILLIC SMALL LETTER TSWE;Ll;0;L;;;;;N;;;A68E;;A68E +A690;CYRILLIC CAPITAL LETTER TSSE;Lu;0;L;;;;;N;;;;A691; +A691;CYRILLIC SMALL LETTER TSSE;Ll;0;L;;;;;N;;;A690;;A690 +A692;CYRILLIC CAPITAL LETTER TCHE;Lu;0;L;;;;;N;;;;A693; +A693;CYRILLIC SMALL LETTER TCHE;Ll;0;L;;;;;N;;;A692;;A692 +A694;CYRILLIC CAPITAL LETTER HWE;Lu;0;L;;;;;N;;;;A695; +A695;CYRILLIC SMALL LETTER HWE;Ll;0;L;;;;;N;;;A694;;A694 +A696;CYRILLIC CAPITAL LETTER SHWE;Lu;0;L;;;;;N;;;;A697; +A697;CYRILLIC SMALL LETTER SHWE;Ll;0;L;;;;;N;;;A696;;A696 +A698;CYRILLIC CAPITAL LETTER DOUBLE O;Lu;0;L;;;;;N;;;;A699; +A699;CYRILLIC SMALL LETTER DOUBLE O;Ll;0;L;;;;;N;;;A698;;A698 +A69A;CYRILLIC CAPITAL LETTER CROSSED O;Lu;0;L;;;;;N;;;;A69B; +A69B;CYRILLIC SMALL LETTER CROSSED O;Ll;0;L;;;;;N;;;A69A;;A69A +A69C;MODIFIER LETTER CYRILLIC HARD SIGN;Lm;0;L; 044A;;;;N;;;;; +A69D;MODIFIER LETTER CYRILLIC SOFT SIGN;Lm;0;L; 044C;;;;N;;;;; +A69E;COMBINING CYRILLIC LETTER EF;Mn;230;NSM;;;;;N;;;;; +A69F;COMBINING CYRILLIC LETTER IOTIFIED E;Mn;230;NSM;;;;;N;;;;; +A6A0;BAMUM LETTER A;Lo;0;L;;;;;N;;;;; +A6A1;BAMUM LETTER KA;Lo;0;L;;;;;N;;;;; +A6A2;BAMUM LETTER U;Lo;0;L;;;;;N;;;;; +A6A3;BAMUM LETTER KU;Lo;0;L;;;;;N;;;;; +A6A4;BAMUM LETTER EE;Lo;0;L;;;;;N;;;;; +A6A5;BAMUM LETTER REE;Lo;0;L;;;;;N;;;;; +A6A6;BAMUM LETTER TAE;Lo;0;L;;;;;N;;;;; +A6A7;BAMUM LETTER O;Lo;0;L;;;;;N;;;;; +A6A8;BAMUM LETTER NYI;Lo;0;L;;;;;N;;;;; +A6A9;BAMUM LETTER I;Lo;0;L;;;;;N;;;;; +A6AA;BAMUM LETTER LA;Lo;0;L;;;;;N;;;;; +A6AB;BAMUM LETTER PA;Lo;0;L;;;;;N;;;;; +A6AC;BAMUM LETTER RII;Lo;0;L;;;;;N;;;;; +A6AD;BAMUM LETTER RIEE;Lo;0;L;;;;;N;;;;; +A6AE;BAMUM LETTER LEEEE;Lo;0;L;;;;;N;;;;; +A6AF;BAMUM LETTER MEEEE;Lo;0;L;;;;;N;;;;; +A6B0;BAMUM LETTER TAA;Lo;0;L;;;;;N;;;;; +A6B1;BAMUM LETTER NDAA;Lo;0;L;;;;;N;;;;; +A6B2;BAMUM LETTER NJAEM;Lo;0;L;;;;;N;;;;; +A6B3;BAMUM LETTER M;Lo;0;L;;;;;N;;;;; +A6B4;BAMUM LETTER SUU;Lo;0;L;;;;;N;;;;; +A6B5;BAMUM LETTER MU;Lo;0;L;;;;;N;;;;; +A6B6;BAMUM LETTER SHII;Lo;0;L;;;;;N;;;;; +A6B7;BAMUM LETTER SI;Lo;0;L;;;;;N;;;;; +A6B8;BAMUM LETTER SHEUX;Lo;0;L;;;;;N;;;;; +A6B9;BAMUM LETTER SEUX;Lo;0;L;;;;;N;;;;; +A6BA;BAMUM LETTER KYEE;Lo;0;L;;;;;N;;;;; +A6BB;BAMUM LETTER KET;Lo;0;L;;;;;N;;;;; +A6BC;BAMUM LETTER NUAE;Lo;0;L;;;;;N;;;;; +A6BD;BAMUM LETTER NU;Lo;0;L;;;;;N;;;;; +A6BE;BAMUM LETTER NJUAE;Lo;0;L;;;;;N;;;;; +A6BF;BAMUM LETTER YOQ;Lo;0;L;;;;;N;;;;; +A6C0;BAMUM LETTER SHU;Lo;0;L;;;;;N;;;;; +A6C1;BAMUM LETTER YUQ;Lo;0;L;;;;;N;;;;; +A6C2;BAMUM LETTER YA;Lo;0;L;;;;;N;;;;; +A6C3;BAMUM LETTER NSHA;Lo;0;L;;;;;N;;;;; +A6C4;BAMUM LETTER KEUX;Lo;0;L;;;;;N;;;;; +A6C5;BAMUM LETTER PEUX;Lo;0;L;;;;;N;;;;; +A6C6;BAMUM LETTER NJEE;Lo;0;L;;;;;N;;;;; +A6C7;BAMUM LETTER NTEE;Lo;0;L;;;;;N;;;;; +A6C8;BAMUM LETTER PUE;Lo;0;L;;;;;N;;;;; +A6C9;BAMUM LETTER WUE;Lo;0;L;;;;;N;;;;; +A6CA;BAMUM LETTER PEE;Lo;0;L;;;;;N;;;;; +A6CB;BAMUM LETTER FEE;Lo;0;L;;;;;N;;;;; +A6CC;BAMUM LETTER RU;Lo;0;L;;;;;N;;;;; +A6CD;BAMUM LETTER LU;Lo;0;L;;;;;N;;;;; +A6CE;BAMUM LETTER MI;Lo;0;L;;;;;N;;;;; +A6CF;BAMUM LETTER NI;Lo;0;L;;;;;N;;;;; +A6D0;BAMUM LETTER REUX;Lo;0;L;;;;;N;;;;; +A6D1;BAMUM LETTER RAE;Lo;0;L;;;;;N;;;;; +A6D2;BAMUM LETTER KEN;Lo;0;L;;;;;N;;;;; +A6D3;BAMUM LETTER NGKWAEN;Lo;0;L;;;;;N;;;;; +A6D4;BAMUM LETTER NGGA;Lo;0;L;;;;;N;;;;; +A6D5;BAMUM LETTER NGA;Lo;0;L;;;;;N;;;;; +A6D6;BAMUM LETTER SHO;Lo;0;L;;;;;N;;;;; +A6D7;BAMUM LETTER PUAE;Lo;0;L;;;;;N;;;;; +A6D8;BAMUM LETTER FU;Lo;0;L;;;;;N;;;;; +A6D9;BAMUM LETTER FOM;Lo;0;L;;;;;N;;;;; +A6DA;BAMUM LETTER WA;Lo;0;L;;;;;N;;;;; +A6DB;BAMUM LETTER NA;Lo;0;L;;;;;N;;;;; +A6DC;BAMUM LETTER LI;Lo;0;L;;;;;N;;;;; +A6DD;BAMUM LETTER PI;Lo;0;L;;;;;N;;;;; +A6DE;BAMUM LETTER LOQ;Lo;0;L;;;;;N;;;;; +A6DF;BAMUM LETTER KO;Lo;0;L;;;;;N;;;;; +A6E0;BAMUM LETTER MBEN;Lo;0;L;;;;;N;;;;; +A6E1;BAMUM LETTER REN;Lo;0;L;;;;;N;;;;; +A6E2;BAMUM LETTER MEN;Lo;0;L;;;;;N;;;;; +A6E3;BAMUM LETTER MA;Lo;0;L;;;;;N;;;;; +A6E4;BAMUM LETTER TI;Lo;0;L;;;;;N;;;;; +A6E5;BAMUM LETTER KI;Lo;0;L;;;;;N;;;;; +A6E6;BAMUM LETTER MO;Nl;0;L;;;;1;N;;;;; +A6E7;BAMUM LETTER MBAA;Nl;0;L;;;;2;N;;;;; +A6E8;BAMUM LETTER TET;Nl;0;L;;;;3;N;;;;; +A6E9;BAMUM LETTER KPA;Nl;0;L;;;;4;N;;;;; +A6EA;BAMUM LETTER TEN;Nl;0;L;;;;5;N;;;;; +A6EB;BAMUM LETTER NTUU;Nl;0;L;;;;6;N;;;;; +A6EC;BAMUM LETTER SAMBA;Nl;0;L;;;;7;N;;;;; +A6ED;BAMUM LETTER FAAMAE;Nl;0;L;;;;8;N;;;;; +A6EE;BAMUM LETTER KOVUU;Nl;0;L;;;;9;N;;;;; +A6EF;BAMUM LETTER KOGHOM;Nl;0;L;;;;0;N;;;;; +A6F0;BAMUM COMBINING MARK KOQNDON;Mn;230;NSM;;;;;N;;;;; +A6F1;BAMUM COMBINING MARK TUKWENTIS;Mn;230;NSM;;;;;N;;;;; +A6F2;BAMUM NJAEMLI;Po;0;L;;;;;N;;;;; +A6F3;BAMUM FULL STOP;Po;0;L;;;;;N;;;;; +A6F4;BAMUM COLON;Po;0;L;;;;;N;;;;; +A6F5;BAMUM COMMA;Po;0;L;;;;;N;;;;; +A6F6;BAMUM SEMICOLON;Po;0;L;;;;;N;;;;; +A6F7;BAMUM QUESTION MARK;Po;0;L;;;;;N;;;;; +A700;MODIFIER LETTER CHINESE TONE YIN PING;Sk;0;ON;;;;;N;;;;; +A701;MODIFIER LETTER CHINESE TONE YANG PING;Sk;0;ON;;;;;N;;;;; +A702;MODIFIER LETTER CHINESE TONE YIN SHANG;Sk;0;ON;;;;;N;;;;; +A703;MODIFIER LETTER CHINESE TONE YANG SHANG;Sk;0;ON;;;;;N;;;;; +A704;MODIFIER LETTER CHINESE TONE YIN QU;Sk;0;ON;;;;;N;;;;; +A705;MODIFIER LETTER CHINESE TONE YANG QU;Sk;0;ON;;;;;N;;;;; +A706;MODIFIER LETTER CHINESE TONE YIN RU;Sk;0;ON;;;;;N;;;;; +A707;MODIFIER LETTER CHINESE TONE YANG RU;Sk;0;ON;;;;;N;;;;; +A708;MODIFIER LETTER EXTRA-HIGH DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;; +A709;MODIFIER LETTER HIGH DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;; +A70A;MODIFIER LETTER MID DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;; +A70B;MODIFIER LETTER LOW DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;; +A70C;MODIFIER LETTER EXTRA-LOW DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;; +A70D;MODIFIER LETTER EXTRA-HIGH DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A70E;MODIFIER LETTER HIGH DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A70F;MODIFIER LETTER MID DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A710;MODIFIER LETTER LOW DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A711;MODIFIER LETTER EXTRA-LOW DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A712;MODIFIER LETTER EXTRA-HIGH LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A713;MODIFIER LETTER HIGH LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A714;MODIFIER LETTER MID LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A715;MODIFIER LETTER LOW LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A716;MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;; +A717;MODIFIER LETTER DOT VERTICAL BAR;Lm;0;ON;;;;;N;;;;; +A718;MODIFIER LETTER DOT SLASH;Lm;0;ON;;;;;N;;;;; +A719;MODIFIER LETTER DOT HORIZONTAL BAR;Lm;0;ON;;;;;N;;;;; +A71A;MODIFIER LETTER LOWER RIGHT CORNER ANGLE;Lm;0;ON;;;;;N;;;;; +A71B;MODIFIER LETTER RAISED UP ARROW;Lm;0;ON;;;;;N;;;;; +A71C;MODIFIER LETTER RAISED DOWN ARROW;Lm;0;ON;;;;;N;;;;; +A71D;MODIFIER LETTER RAISED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;; +A71E;MODIFIER LETTER RAISED INVERTED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;; +A71F;MODIFIER LETTER LOW INVERTED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;; +A720;MODIFIER LETTER STRESS AND HIGH TONE;Sk;0;ON;;;;;N;;;;; +A721;MODIFIER LETTER STRESS AND LOW TONE;Sk;0;ON;;;;;N;;;;; +A722;LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF;Lu;0;L;;;;;N;;;;A723; +A723;LATIN SMALL LETTER EGYPTOLOGICAL ALEF;Ll;0;L;;;;;N;;;A722;;A722 +A724;LATIN CAPITAL LETTER EGYPTOLOGICAL AIN;Lu;0;L;;;;;N;;;;A725; +A725;LATIN SMALL LETTER EGYPTOLOGICAL AIN;Ll;0;L;;;;;N;;;A724;;A724 +A726;LATIN CAPITAL LETTER HENG;Lu;0;L;;;;;N;;;;A727; +A727;LATIN SMALL LETTER HENG;Ll;0;L;;;;;N;;;A726;;A726 +A728;LATIN CAPITAL LETTER TZ;Lu;0;L;;;;;N;;;;A729; +A729;LATIN SMALL LETTER TZ;Ll;0;L;;;;;N;;;A728;;A728 +A72A;LATIN CAPITAL LETTER TRESILLO;Lu;0;L;;;;;N;;;;A72B; +A72B;LATIN SMALL LETTER TRESILLO;Ll;0;L;;;;;N;;;A72A;;A72A +A72C;LATIN CAPITAL LETTER CUATRILLO;Lu;0;L;;;;;N;;;;A72D; +A72D;LATIN SMALL LETTER CUATRILLO;Ll;0;L;;;;;N;;;A72C;;A72C +A72E;LATIN CAPITAL LETTER CUATRILLO WITH COMMA;Lu;0;L;;;;;N;;;;A72F; +A72F;LATIN SMALL LETTER CUATRILLO WITH COMMA;Ll;0;L;;;;;N;;;A72E;;A72E +A730;LATIN LETTER SMALL CAPITAL F;Ll;0;L;;;;;N;;;;; +A731;LATIN LETTER SMALL CAPITAL S;Ll;0;L;;;;;N;;;;; +A732;LATIN CAPITAL LETTER AA;Lu;0;L;;;;;N;;;;A733; +A733;LATIN SMALL LETTER AA;Ll;0;L;;;;;N;;;A732;;A732 +A734;LATIN CAPITAL LETTER AO;Lu;0;L;;;;;N;;;;A735; +A735;LATIN SMALL LETTER AO;Ll;0;L;;;;;N;;;A734;;A734 +A736;LATIN CAPITAL LETTER AU;Lu;0;L;;;;;N;;;;A737; +A737;LATIN SMALL LETTER AU;Ll;0;L;;;;;N;;;A736;;A736 +A738;LATIN CAPITAL LETTER AV;Lu;0;L;;;;;N;;;;A739; +A739;LATIN SMALL LETTER AV;Ll;0;L;;;;;N;;;A738;;A738 +A73A;LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR;Lu;0;L;;;;;N;;;;A73B; +A73B;LATIN SMALL LETTER AV WITH HORIZONTAL BAR;Ll;0;L;;;;;N;;;A73A;;A73A +A73C;LATIN CAPITAL LETTER AY;Lu;0;L;;;;;N;;;;A73D; +A73D;LATIN SMALL LETTER AY;Ll;0;L;;;;;N;;;A73C;;A73C +A73E;LATIN CAPITAL LETTER REVERSED C WITH DOT;Lu;0;L;;;;;N;;;;A73F; +A73F;LATIN SMALL LETTER REVERSED C WITH DOT;Ll;0;L;;;;;N;;;A73E;;A73E +A740;LATIN CAPITAL LETTER K WITH STROKE;Lu;0;L;;;;;N;;;;A741; +A741;LATIN SMALL LETTER K WITH STROKE;Ll;0;L;;;;;N;;;A740;;A740 +A742;LATIN CAPITAL LETTER K WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A743; +A743;LATIN SMALL LETTER K WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A742;;A742 +A744;LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A745; +A745;LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE;Ll;0;L;;;;;N;;;A744;;A744 +A746;LATIN CAPITAL LETTER BROKEN L;Lu;0;L;;;;;N;;;;A747; +A747;LATIN SMALL LETTER BROKEN L;Ll;0;L;;;;;N;;;A746;;A746 +A748;LATIN CAPITAL LETTER L WITH HIGH STROKE;Lu;0;L;;;;;N;;;;A749; +A749;LATIN SMALL LETTER L WITH HIGH STROKE;Ll;0;L;;;;;N;;;A748;;A748 +A74A;LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY;Lu;0;L;;;;;N;;;;A74B; +A74B;LATIN SMALL LETTER O WITH LONG STROKE OVERLAY;Ll;0;L;;;;;N;;;A74A;;A74A +A74C;LATIN CAPITAL LETTER O WITH LOOP;Lu;0;L;;;;;N;;;;A74D; +A74D;LATIN SMALL LETTER O WITH LOOP;Ll;0;L;;;;;N;;;A74C;;A74C +A74E;LATIN CAPITAL LETTER OO;Lu;0;L;;;;;N;;;;A74F; +A74F;LATIN SMALL LETTER OO;Ll;0;L;;;;;N;;;A74E;;A74E +A750;LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A751; +A751;LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A750;;A750 +A752;LATIN CAPITAL LETTER P WITH FLOURISH;Lu;0;L;;;;;N;;;;A753; +A753;LATIN SMALL LETTER P WITH FLOURISH;Ll;0;L;;;;;N;;;A752;;A752 +A754;LATIN CAPITAL LETTER P WITH SQUIRREL TAIL;Lu;0;L;;;;;N;;;;A755; +A755;LATIN SMALL LETTER P WITH SQUIRREL TAIL;Ll;0;L;;;;;N;;;A754;;A754 +A756;LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A757; +A757;LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A756;;A756 +A758;LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A759; +A759;LATIN SMALL LETTER Q WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A758;;A758 +A75A;LATIN CAPITAL LETTER R ROTUNDA;Lu;0;L;;;;;N;;;;A75B; +A75B;LATIN SMALL LETTER R ROTUNDA;Ll;0;L;;;;;N;;;A75A;;A75A +A75C;LATIN CAPITAL LETTER RUM ROTUNDA;Lu;0;L;;;;;N;;;;A75D; +A75D;LATIN SMALL LETTER RUM ROTUNDA;Ll;0;L;;;;;N;;;A75C;;A75C +A75E;LATIN CAPITAL LETTER V WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A75F; +A75F;LATIN SMALL LETTER V WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A75E;;A75E +A760;LATIN CAPITAL LETTER VY;Lu;0;L;;;;;N;;;;A761; +A761;LATIN SMALL LETTER VY;Ll;0;L;;;;;N;;;A760;;A760 +A762;LATIN CAPITAL LETTER VISIGOTHIC Z;Lu;0;L;;;;;N;;;;A763; +A763;LATIN SMALL LETTER VISIGOTHIC Z;Ll;0;L;;;;;N;;;A762;;A762 +A764;LATIN CAPITAL LETTER THORN WITH STROKE;Lu;0;L;;;;;N;;;;A765; +A765;LATIN SMALL LETTER THORN WITH STROKE;Ll;0;L;;;;;N;;;A764;;A764 +A766;LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A767; +A767;LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A766;;A766 +A768;LATIN CAPITAL LETTER VEND;Lu;0;L;;;;;N;;;;A769; +A769;LATIN SMALL LETTER VEND;Ll;0;L;;;;;N;;;A768;;A768 +A76A;LATIN CAPITAL LETTER ET;Lu;0;L;;;;;N;;;;A76B; +A76B;LATIN SMALL LETTER ET;Ll;0;L;;;;;N;;;A76A;;A76A +A76C;LATIN CAPITAL LETTER IS;Lu;0;L;;;;;N;;;;A76D; +A76D;LATIN SMALL LETTER IS;Ll;0;L;;;;;N;;;A76C;;A76C +A76E;LATIN CAPITAL LETTER CON;Lu;0;L;;;;;N;;;;A76F; +A76F;LATIN SMALL LETTER CON;Ll;0;L;;;;;N;;;A76E;;A76E +A770;MODIFIER LETTER US;Lm;0;L; A76F;;;;N;;;;; +A771;LATIN SMALL LETTER DUM;Ll;0;L;;;;;N;;;;; +A772;LATIN SMALL LETTER LUM;Ll;0;L;;;;;N;;;;; +A773;LATIN SMALL LETTER MUM;Ll;0;L;;;;;N;;;;; +A774;LATIN SMALL LETTER NUM;Ll;0;L;;;;;N;;;;; +A775;LATIN SMALL LETTER RUM;Ll;0;L;;;;;N;;;;; +A776;LATIN LETTER SMALL CAPITAL RUM;Ll;0;L;;;;;N;;;;; +A777;LATIN SMALL LETTER TUM;Ll;0;L;;;;;N;;;;; +A778;LATIN SMALL LETTER UM;Ll;0;L;;;;;N;;;;; +A779;LATIN CAPITAL LETTER INSULAR D;Lu;0;L;;;;;N;;;;A77A; +A77A;LATIN SMALL LETTER INSULAR D;Ll;0;L;;;;;N;;;A779;;A779 +A77B;LATIN CAPITAL LETTER INSULAR F;Lu;0;L;;;;;N;;;;A77C; +A77C;LATIN SMALL LETTER INSULAR F;Ll;0;L;;;;;N;;;A77B;;A77B +A77D;LATIN CAPITAL LETTER INSULAR G;Lu;0;L;;;;;N;;;;1D79; +A77E;LATIN CAPITAL LETTER TURNED INSULAR G;Lu;0;L;;;;;N;;;;A77F; +A77F;LATIN SMALL LETTER TURNED INSULAR G;Ll;0;L;;;;;N;;;A77E;;A77E +A780;LATIN CAPITAL LETTER TURNED L;Lu;0;L;;;;;N;;;;A781; +A781;LATIN SMALL LETTER TURNED L;Ll;0;L;;;;;N;;;A780;;A780 +A782;LATIN CAPITAL LETTER INSULAR R;Lu;0;L;;;;;N;;;;A783; +A783;LATIN SMALL LETTER INSULAR R;Ll;0;L;;;;;N;;;A782;;A782 +A784;LATIN CAPITAL LETTER INSULAR S;Lu;0;L;;;;;N;;;;A785; +A785;LATIN SMALL LETTER INSULAR S;Ll;0;L;;;;;N;;;A784;;A784 +A786;LATIN CAPITAL LETTER INSULAR T;Lu;0;L;;;;;N;;;;A787; +A787;LATIN SMALL LETTER INSULAR T;Ll;0;L;;;;;N;;;A786;;A786 +A788;MODIFIER LETTER LOW CIRCUMFLEX ACCENT;Lm;0;ON;;;;;N;;;;; +A789;MODIFIER LETTER COLON;Sk;0;L;;;;;N;;;;; +A78A;MODIFIER LETTER SHORT EQUALS SIGN;Sk;0;L;;;;;N;;;;; +A78B;LATIN CAPITAL LETTER SALTILLO;Lu;0;L;;;;;N;;;;A78C; +A78C;LATIN SMALL LETTER SALTILLO;Ll;0;L;;;;;N;;;A78B;;A78B +A78D;LATIN CAPITAL LETTER TURNED H;Lu;0;L;;;;;N;;;;0265; +A78E;LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT;Ll;0;L;;;;;N;;;;; +A78F;LATIN LETTER SINOLOGICAL DOT;Lo;0;L;;;;;N;;;;; +A790;LATIN CAPITAL LETTER N WITH DESCENDER;Lu;0;L;;;;;N;;;;A791; +A791;LATIN SMALL LETTER N WITH DESCENDER;Ll;0;L;;;;;N;;;A790;;A790 +A792;LATIN CAPITAL LETTER C WITH BAR;Lu;0;L;;;;;N;;;;A793; +A793;LATIN SMALL LETTER C WITH BAR;Ll;0;L;;;;;N;;;A792;;A792 +A794;LATIN SMALL LETTER C WITH PALATAL HOOK;Ll;0;L;;;;;N;;;A7C4;;A7C4 +A795;LATIN SMALL LETTER H WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +A796;LATIN CAPITAL LETTER B WITH FLOURISH;Lu;0;L;;;;;N;;;;A797; +A797;LATIN SMALL LETTER B WITH FLOURISH;Ll;0;L;;;;;N;;;A796;;A796 +A798;LATIN CAPITAL LETTER F WITH STROKE;Lu;0;L;;;;;N;;;;A799; +A799;LATIN SMALL LETTER F WITH STROKE;Ll;0;L;;;;;N;;;A798;;A798 +A79A;LATIN CAPITAL LETTER VOLAPUK AE;Lu;0;L;;;;;N;;;;A79B; +A79B;LATIN SMALL LETTER VOLAPUK AE;Ll;0;L;;;;;N;;;A79A;;A79A +A79C;LATIN CAPITAL LETTER VOLAPUK OE;Lu;0;L;;;;;N;;;;A79D; +A79D;LATIN SMALL LETTER VOLAPUK OE;Ll;0;L;;;;;N;;;A79C;;A79C +A79E;LATIN CAPITAL LETTER VOLAPUK UE;Lu;0;L;;;;;N;;;;A79F; +A79F;LATIN SMALL LETTER VOLAPUK UE;Ll;0;L;;;;;N;;;A79E;;A79E +A7A0;LATIN CAPITAL LETTER G WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A1; +A7A1;LATIN SMALL LETTER G WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A0;;A7A0 +A7A2;LATIN CAPITAL LETTER K WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A3; +A7A3;LATIN SMALL LETTER K WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A2;;A7A2 +A7A4;LATIN CAPITAL LETTER N WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A5; +A7A5;LATIN SMALL LETTER N WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A4;;A7A4 +A7A6;LATIN CAPITAL LETTER R WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A7; +A7A7;LATIN SMALL LETTER R WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A6;;A7A6 +A7A8;LATIN CAPITAL LETTER S WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A9; +A7A9;LATIN SMALL LETTER S WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A8;;A7A8 +A7AA;LATIN CAPITAL LETTER H WITH HOOK;Lu;0;L;;;;;N;;;;0266; +A7AB;LATIN CAPITAL LETTER REVERSED OPEN E;Lu;0;L;;;;;N;;;;025C; +A7AC;LATIN CAPITAL LETTER SCRIPT G;Lu;0;L;;;;;N;;;;0261; +A7AD;LATIN CAPITAL LETTER L WITH BELT;Lu;0;L;;;;;N;;;;026C; +A7AE;LATIN CAPITAL LETTER SMALL CAPITAL I;Lu;0;L;;;;;N;;;;026A; +A7AF;LATIN LETTER SMALL CAPITAL Q;Ll;0;L;;;;;N;;;;; +A7B0;LATIN CAPITAL LETTER TURNED K;Lu;0;L;;;;;N;;;;029E; +A7B1;LATIN CAPITAL LETTER TURNED T;Lu;0;L;;;;;N;;;;0287; +A7B2;LATIN CAPITAL LETTER J WITH CROSSED-TAIL;Lu;0;L;;;;;N;;;;029D; +A7B3;LATIN CAPITAL LETTER CHI;Lu;0;L;;;;;N;;;;AB53; +A7B4;LATIN CAPITAL LETTER BETA;Lu;0;L;;;;;N;;;;A7B5; +A7B5;LATIN SMALL LETTER BETA;Ll;0;L;;;;;N;;;A7B4;;A7B4 +A7B6;LATIN CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;A7B7; +A7B7;LATIN SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;A7B6;;A7B6 +A7B8;LATIN CAPITAL LETTER U WITH STROKE;Lu;0;L;;;;;N;;;;A7B9; +A7B9;LATIN SMALL LETTER U WITH STROKE;Ll;0;L;;;;;N;;;A7B8;;A7B8 +A7BA;LATIN CAPITAL LETTER GLOTTAL A;Lu;0;L;;;;;N;;;;A7BB; +A7BB;LATIN SMALL LETTER GLOTTAL A;Ll;0;L;;;;;N;;;A7BA;;A7BA +A7BC;LATIN CAPITAL LETTER GLOTTAL I;Lu;0;L;;;;;N;;;;A7BD; +A7BD;LATIN SMALL LETTER GLOTTAL I;Ll;0;L;;;;;N;;;A7BC;;A7BC +A7BE;LATIN CAPITAL LETTER GLOTTAL U;Lu;0;L;;;;;N;;;;A7BF; +A7BF;LATIN SMALL LETTER GLOTTAL U;Ll;0;L;;;;;N;;;A7BE;;A7BE +A7C2;LATIN CAPITAL LETTER ANGLICANA W;Lu;0;L;;;;;N;;;;A7C3; +A7C3;LATIN SMALL LETTER ANGLICANA W;Ll;0;L;;;;;N;;;A7C2;;A7C2 +A7C4;LATIN CAPITAL LETTER C WITH PALATAL HOOK;Lu;0;L;;;;;N;;;;A794; +A7C5;LATIN CAPITAL LETTER S WITH HOOK;Lu;0;L;;;;;N;;;;0282; +A7C6;LATIN CAPITAL LETTER Z WITH PALATAL HOOK;Lu;0;L;;;;;N;;;;1D8E; +A7F7;LATIN EPIGRAPHIC LETTER SIDEWAYS I;Lo;0;L;;;;;N;;;;; +A7F8;MODIFIER LETTER CAPITAL H WITH STROKE;Lm;0;L; 0126;;;;N;;;;; +A7F9;MODIFIER LETTER SMALL LIGATURE OE;Lm;0;L; 0153;;;;N;;;;; +A7FA;LATIN LETTER SMALL CAPITAL TURNED M;Ll;0;L;;;;;N;;;;; +A7FB;LATIN EPIGRAPHIC LETTER REVERSED F;Lo;0;L;;;;;N;;;;; +A7FC;LATIN EPIGRAPHIC LETTER REVERSED P;Lo;0;L;;;;;N;;;;; +A7FD;LATIN EPIGRAPHIC LETTER INVERTED M;Lo;0;L;;;;;N;;;;; +A7FE;LATIN EPIGRAPHIC LETTER I LONGA;Lo;0;L;;;;;N;;;;; +A7FF;LATIN EPIGRAPHIC LETTER ARCHAIC M;Lo;0;L;;;;;N;;;;; +A800;SYLOTI NAGRI LETTER A;Lo;0;L;;;;;N;;;;; +A801;SYLOTI NAGRI LETTER I;Lo;0;L;;;;;N;;;;; +A802;SYLOTI NAGRI SIGN DVISVARA;Mn;0;NSM;;;;;N;;;;; +A803;SYLOTI NAGRI LETTER U;Lo;0;L;;;;;N;;;;; +A804;SYLOTI NAGRI LETTER E;Lo;0;L;;;;;N;;;;; +A805;SYLOTI NAGRI LETTER O;Lo;0;L;;;;;N;;;;; +A806;SYLOTI NAGRI SIGN HASANTA;Mn;9;NSM;;;;;N;;;;; +A807;SYLOTI NAGRI LETTER KO;Lo;0;L;;;;;N;;;;; +A808;SYLOTI NAGRI LETTER KHO;Lo;0;L;;;;;N;;;;; +A809;SYLOTI NAGRI LETTER GO;Lo;0;L;;;;;N;;;;; +A80A;SYLOTI NAGRI LETTER GHO;Lo;0;L;;;;;N;;;;; +A80B;SYLOTI NAGRI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +A80C;SYLOTI NAGRI LETTER CO;Lo;0;L;;;;;N;;;;; +A80D;SYLOTI NAGRI LETTER CHO;Lo;0;L;;;;;N;;;;; +A80E;SYLOTI NAGRI LETTER JO;Lo;0;L;;;;;N;;;;; +A80F;SYLOTI NAGRI LETTER JHO;Lo;0;L;;;;;N;;;;; +A810;SYLOTI NAGRI LETTER TTO;Lo;0;L;;;;;N;;;;; +A811;SYLOTI NAGRI LETTER TTHO;Lo;0;L;;;;;N;;;;; +A812;SYLOTI NAGRI LETTER DDO;Lo;0;L;;;;;N;;;;; +A813;SYLOTI NAGRI LETTER DDHO;Lo;0;L;;;;;N;;;;; +A814;SYLOTI NAGRI LETTER TO;Lo;0;L;;;;;N;;;;; +A815;SYLOTI NAGRI LETTER THO;Lo;0;L;;;;;N;;;;; +A816;SYLOTI NAGRI LETTER DO;Lo;0;L;;;;;N;;;;; +A817;SYLOTI NAGRI LETTER DHO;Lo;0;L;;;;;N;;;;; +A818;SYLOTI NAGRI LETTER NO;Lo;0;L;;;;;N;;;;; +A819;SYLOTI NAGRI LETTER PO;Lo;0;L;;;;;N;;;;; +A81A;SYLOTI NAGRI LETTER PHO;Lo;0;L;;;;;N;;;;; +A81B;SYLOTI NAGRI LETTER BO;Lo;0;L;;;;;N;;;;; +A81C;SYLOTI NAGRI LETTER BHO;Lo;0;L;;;;;N;;;;; +A81D;SYLOTI NAGRI LETTER MO;Lo;0;L;;;;;N;;;;; +A81E;SYLOTI NAGRI LETTER RO;Lo;0;L;;;;;N;;;;; +A81F;SYLOTI NAGRI LETTER LO;Lo;0;L;;;;;N;;;;; +A820;SYLOTI NAGRI LETTER RRO;Lo;0;L;;;;;N;;;;; +A821;SYLOTI NAGRI LETTER SO;Lo;0;L;;;;;N;;;;; +A822;SYLOTI NAGRI LETTER HO;Lo;0;L;;;;;N;;;;; +A823;SYLOTI NAGRI VOWEL SIGN A;Mc;0;L;;;;;N;;;;; +A824;SYLOTI NAGRI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +A825;SYLOTI NAGRI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +A826;SYLOTI NAGRI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +A827;SYLOTI NAGRI VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +A828;SYLOTI NAGRI POETRY MARK-1;So;0;ON;;;;;N;;;;; +A829;SYLOTI NAGRI POETRY MARK-2;So;0;ON;;;;;N;;;;; +A82A;SYLOTI NAGRI POETRY MARK-3;So;0;ON;;;;;N;;;;; +A82B;SYLOTI NAGRI POETRY MARK-4;So;0;ON;;;;;N;;;;; +A830;NORTH INDIC FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;; +A831;NORTH INDIC FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;; +A832;NORTH INDIC FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;; +A833;NORTH INDIC FRACTION ONE SIXTEENTH;No;0;L;;;;1/16;N;;;;; +A834;NORTH INDIC FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;; +A835;NORTH INDIC FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;; +A836;NORTH INDIC QUARTER MARK;So;0;L;;;;;N;;;;; +A837;NORTH INDIC PLACEHOLDER MARK;So;0;L;;;;;N;;;;; +A838;NORTH INDIC RUPEE MARK;Sc;0;ET;;;;;N;;;;; +A839;NORTH INDIC QUANTITY MARK;So;0;ET;;;;;N;;;;; +A840;PHAGS-PA LETTER KA;Lo;0;L;;;;;N;;;;; +A841;PHAGS-PA LETTER KHA;Lo;0;L;;;;;N;;;;; +A842;PHAGS-PA LETTER GA;Lo;0;L;;;;;N;;;;; +A843;PHAGS-PA LETTER NGA;Lo;0;L;;;;;N;;;;; +A844;PHAGS-PA LETTER CA;Lo;0;L;;;;;N;;;;; +A845;PHAGS-PA LETTER CHA;Lo;0;L;;;;;N;;;;; +A846;PHAGS-PA LETTER JA;Lo;0;L;;;;;N;;;;; +A847;PHAGS-PA LETTER NYA;Lo;0;L;;;;;N;;;;; +A848;PHAGS-PA LETTER TA;Lo;0;L;;;;;N;;;;; +A849;PHAGS-PA LETTER THA;Lo;0;L;;;;;N;;;;; +A84A;PHAGS-PA LETTER DA;Lo;0;L;;;;;N;;;;; +A84B;PHAGS-PA LETTER NA;Lo;0;L;;;;;N;;;;; +A84C;PHAGS-PA LETTER PA;Lo;0;L;;;;;N;;;;; +A84D;PHAGS-PA LETTER PHA;Lo;0;L;;;;;N;;;;; +A84E;PHAGS-PA LETTER BA;Lo;0;L;;;;;N;;;;; +A84F;PHAGS-PA LETTER MA;Lo;0;L;;;;;N;;;;; +A850;PHAGS-PA LETTER TSA;Lo;0;L;;;;;N;;;;; +A851;PHAGS-PA LETTER TSHA;Lo;0;L;;;;;N;;;;; +A852;PHAGS-PA LETTER DZA;Lo;0;L;;;;;N;;;;; +A853;PHAGS-PA LETTER WA;Lo;0;L;;;;;N;;;;; +A854;PHAGS-PA LETTER ZHA;Lo;0;L;;;;;N;;;;; +A855;PHAGS-PA LETTER ZA;Lo;0;L;;;;;N;;;;; +A856;PHAGS-PA LETTER SMALL A;Lo;0;L;;;;;N;;;;; +A857;PHAGS-PA LETTER YA;Lo;0;L;;;;;N;;;;; +A858;PHAGS-PA LETTER RA;Lo;0;L;;;;;N;;;;; +A859;PHAGS-PA LETTER LA;Lo;0;L;;;;;N;;;;; +A85A;PHAGS-PA LETTER SHA;Lo;0;L;;;;;N;;;;; +A85B;PHAGS-PA LETTER SA;Lo;0;L;;;;;N;;;;; +A85C;PHAGS-PA LETTER HA;Lo;0;L;;;;;N;;;;; +A85D;PHAGS-PA LETTER A;Lo;0;L;;;;;N;;;;; +A85E;PHAGS-PA LETTER I;Lo;0;L;;;;;N;;;;; +A85F;PHAGS-PA LETTER U;Lo;0;L;;;;;N;;;;; +A860;PHAGS-PA LETTER E;Lo;0;L;;;;;N;;;;; +A861;PHAGS-PA LETTER O;Lo;0;L;;;;;N;;;;; +A862;PHAGS-PA LETTER QA;Lo;0;L;;;;;N;;;;; +A863;PHAGS-PA LETTER XA;Lo;0;L;;;;;N;;;;; +A864;PHAGS-PA LETTER FA;Lo;0;L;;;;;N;;;;; +A865;PHAGS-PA LETTER GGA;Lo;0;L;;;;;N;;;;; +A866;PHAGS-PA LETTER EE;Lo;0;L;;;;;N;;;;; +A867;PHAGS-PA SUBJOINED LETTER WA;Lo;0;L;;;;;N;;;;; +A868;PHAGS-PA SUBJOINED LETTER YA;Lo;0;L;;;;;N;;;;; +A869;PHAGS-PA LETTER TTA;Lo;0;L;;;;;N;;;;; +A86A;PHAGS-PA LETTER TTHA;Lo;0;L;;;;;N;;;;; +A86B;PHAGS-PA LETTER DDA;Lo;0;L;;;;;N;;;;; +A86C;PHAGS-PA LETTER NNA;Lo;0;L;;;;;N;;;;; +A86D;PHAGS-PA LETTER ALTERNATE YA;Lo;0;L;;;;;N;;;;; +A86E;PHAGS-PA LETTER VOICELESS SHA;Lo;0;L;;;;;N;;;;; +A86F;PHAGS-PA LETTER VOICED HA;Lo;0;L;;;;;N;;;;; +A870;PHAGS-PA LETTER ASPIRATED FA;Lo;0;L;;;;;N;;;;; +A871;PHAGS-PA SUBJOINED LETTER RA;Lo;0;L;;;;;N;;;;; +A872;PHAGS-PA SUPERFIXED LETTER RA;Lo;0;L;;;;;N;;;;; +A873;PHAGS-PA LETTER CANDRABINDU;Lo;0;L;;;;;N;;;;; +A874;PHAGS-PA SINGLE HEAD MARK;Po;0;ON;;;;;N;;;;; +A875;PHAGS-PA DOUBLE HEAD MARK;Po;0;ON;;;;;N;;;;; +A876;PHAGS-PA MARK SHAD;Po;0;ON;;;;;N;;;;; +A877;PHAGS-PA MARK DOUBLE SHAD;Po;0;ON;;;;;N;;;;; +A880;SAURASHTRA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +A881;SAURASHTRA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +A882;SAURASHTRA LETTER A;Lo;0;L;;;;;N;;;;; +A883;SAURASHTRA LETTER AA;Lo;0;L;;;;;N;;;;; +A884;SAURASHTRA LETTER I;Lo;0;L;;;;;N;;;;; +A885;SAURASHTRA LETTER II;Lo;0;L;;;;;N;;;;; +A886;SAURASHTRA LETTER U;Lo;0;L;;;;;N;;;;; +A887;SAURASHTRA LETTER UU;Lo;0;L;;;;;N;;;;; +A888;SAURASHTRA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +A889;SAURASHTRA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +A88A;SAURASHTRA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +A88B;SAURASHTRA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +A88C;SAURASHTRA LETTER E;Lo;0;L;;;;;N;;;;; +A88D;SAURASHTRA LETTER EE;Lo;0;L;;;;;N;;;;; +A88E;SAURASHTRA LETTER AI;Lo;0;L;;;;;N;;;;; +A88F;SAURASHTRA LETTER O;Lo;0;L;;;;;N;;;;; +A890;SAURASHTRA LETTER OO;Lo;0;L;;;;;N;;;;; +A891;SAURASHTRA LETTER AU;Lo;0;L;;;;;N;;;;; +A892;SAURASHTRA LETTER KA;Lo;0;L;;;;;N;;;;; +A893;SAURASHTRA LETTER KHA;Lo;0;L;;;;;N;;;;; +A894;SAURASHTRA LETTER GA;Lo;0;L;;;;;N;;;;; +A895;SAURASHTRA LETTER GHA;Lo;0;L;;;;;N;;;;; +A896;SAURASHTRA LETTER NGA;Lo;0;L;;;;;N;;;;; +A897;SAURASHTRA LETTER CA;Lo;0;L;;;;;N;;;;; +A898;SAURASHTRA LETTER CHA;Lo;0;L;;;;;N;;;;; +A899;SAURASHTRA LETTER JA;Lo;0;L;;;;;N;;;;; +A89A;SAURASHTRA LETTER JHA;Lo;0;L;;;;;N;;;;; +A89B;SAURASHTRA LETTER NYA;Lo;0;L;;;;;N;;;;; +A89C;SAURASHTRA LETTER TTA;Lo;0;L;;;;;N;;;;; +A89D;SAURASHTRA LETTER TTHA;Lo;0;L;;;;;N;;;;; +A89E;SAURASHTRA LETTER DDA;Lo;0;L;;;;;N;;;;; +A89F;SAURASHTRA LETTER DDHA;Lo;0;L;;;;;N;;;;; +A8A0;SAURASHTRA LETTER NNA;Lo;0;L;;;;;N;;;;; +A8A1;SAURASHTRA LETTER TA;Lo;0;L;;;;;N;;;;; +A8A2;SAURASHTRA LETTER THA;Lo;0;L;;;;;N;;;;; +A8A3;SAURASHTRA LETTER DA;Lo;0;L;;;;;N;;;;; +A8A4;SAURASHTRA LETTER DHA;Lo;0;L;;;;;N;;;;; +A8A5;SAURASHTRA LETTER NA;Lo;0;L;;;;;N;;;;; +A8A6;SAURASHTRA LETTER PA;Lo;0;L;;;;;N;;;;; +A8A7;SAURASHTRA LETTER PHA;Lo;0;L;;;;;N;;;;; +A8A8;SAURASHTRA LETTER BA;Lo;0;L;;;;;N;;;;; +A8A9;SAURASHTRA LETTER BHA;Lo;0;L;;;;;N;;;;; +A8AA;SAURASHTRA LETTER MA;Lo;0;L;;;;;N;;;;; +A8AB;SAURASHTRA LETTER YA;Lo;0;L;;;;;N;;;;; +A8AC;SAURASHTRA LETTER RA;Lo;0;L;;;;;N;;;;; +A8AD;SAURASHTRA LETTER LA;Lo;0;L;;;;;N;;;;; +A8AE;SAURASHTRA LETTER VA;Lo;0;L;;;;;N;;;;; +A8AF;SAURASHTRA LETTER SHA;Lo;0;L;;;;;N;;;;; +A8B0;SAURASHTRA LETTER SSA;Lo;0;L;;;;;N;;;;; +A8B1;SAURASHTRA LETTER SA;Lo;0;L;;;;;N;;;;; +A8B2;SAURASHTRA LETTER HA;Lo;0;L;;;;;N;;;;; +A8B3;SAURASHTRA LETTER LLA;Lo;0;L;;;;;N;;;;; +A8B4;SAURASHTRA CONSONANT SIGN HAARU;Mc;0;L;;;;;N;;;;; +A8B5;SAURASHTRA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +A8B6;SAURASHTRA VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +A8B7;SAURASHTRA VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +A8B8;SAURASHTRA VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +A8B9;SAURASHTRA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +A8BA;SAURASHTRA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; +A8BB;SAURASHTRA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; +A8BC;SAURASHTRA VOWEL SIGN VOCALIC L;Mc;0;L;;;;;N;;;;; +A8BD;SAURASHTRA VOWEL SIGN VOCALIC LL;Mc;0;L;;;;;N;;;;; +A8BE;SAURASHTRA VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +A8BF;SAURASHTRA VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; +A8C0;SAURASHTRA VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +A8C1;SAURASHTRA VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +A8C2;SAURASHTRA VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +A8C3;SAURASHTRA VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +A8C4;SAURASHTRA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +A8C5;SAURASHTRA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +A8CE;SAURASHTRA DANDA;Po;0;L;;;;;N;;;;; +A8CF;SAURASHTRA DOUBLE DANDA;Po;0;L;;;;;N;;;;; +A8D0;SAURASHTRA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +A8D1;SAURASHTRA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +A8D2;SAURASHTRA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +A8D3;SAURASHTRA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +A8D4;SAURASHTRA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +A8D5;SAURASHTRA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +A8D6;SAURASHTRA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +A8D7;SAURASHTRA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +A8D8;SAURASHTRA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +A8D9;SAURASHTRA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +A8E0;COMBINING DEVANAGARI DIGIT ZERO;Mn;230;NSM;;;;;N;;;;; +A8E1;COMBINING DEVANAGARI DIGIT ONE;Mn;230;NSM;;;;;N;;;;; +A8E2;COMBINING DEVANAGARI DIGIT TWO;Mn;230;NSM;;;;;N;;;;; +A8E3;COMBINING DEVANAGARI DIGIT THREE;Mn;230;NSM;;;;;N;;;;; +A8E4;COMBINING DEVANAGARI DIGIT FOUR;Mn;230;NSM;;;;;N;;;;; +A8E5;COMBINING DEVANAGARI DIGIT FIVE;Mn;230;NSM;;;;;N;;;;; +A8E6;COMBINING DEVANAGARI DIGIT SIX;Mn;230;NSM;;;;;N;;;;; +A8E7;COMBINING DEVANAGARI DIGIT SEVEN;Mn;230;NSM;;;;;N;;;;; +A8E8;COMBINING DEVANAGARI DIGIT EIGHT;Mn;230;NSM;;;;;N;;;;; +A8E9;COMBINING DEVANAGARI DIGIT NINE;Mn;230;NSM;;;;;N;;;;; +A8EA;COMBINING DEVANAGARI LETTER A;Mn;230;NSM;;;;;N;;;;; +A8EB;COMBINING DEVANAGARI LETTER U;Mn;230;NSM;;;;;N;;;;; +A8EC;COMBINING DEVANAGARI LETTER KA;Mn;230;NSM;;;;;N;;;;; +A8ED;COMBINING DEVANAGARI LETTER NA;Mn;230;NSM;;;;;N;;;;; +A8EE;COMBINING DEVANAGARI LETTER PA;Mn;230;NSM;;;;;N;;;;; +A8EF;COMBINING DEVANAGARI LETTER RA;Mn;230;NSM;;;;;N;;;;; +A8F0;COMBINING DEVANAGARI LETTER VI;Mn;230;NSM;;;;;N;;;;; +A8F1;COMBINING DEVANAGARI SIGN AVAGRAHA;Mn;230;NSM;;;;;N;;;;; +A8F2;DEVANAGARI SIGN SPACING CANDRABINDU;Lo;0;L;;;;;N;;;;; +A8F3;DEVANAGARI SIGN CANDRABINDU VIRAMA;Lo;0;L;;;;;N;;;;; +A8F4;DEVANAGARI SIGN DOUBLE CANDRABINDU VIRAMA;Lo;0;L;;;;;N;;;;; +A8F5;DEVANAGARI SIGN CANDRABINDU TWO;Lo;0;L;;;;;N;;;;; +A8F6;DEVANAGARI SIGN CANDRABINDU THREE;Lo;0;L;;;;;N;;;;; +A8F7;DEVANAGARI SIGN CANDRABINDU AVAGRAHA;Lo;0;L;;;;;N;;;;; +A8F8;DEVANAGARI SIGN PUSHPIKA;Po;0;L;;;;;N;;;;; +A8F9;DEVANAGARI GAP FILLER;Po;0;L;;;;;N;;;;; +A8FA;DEVANAGARI CARET;Po;0;L;;;;;N;;;;; +A8FB;DEVANAGARI HEADSTROKE;Lo;0;L;;;;;N;;;;; +A8FC;DEVANAGARI SIGN SIDDHAM;Po;0;L;;;;;N;;;;; +A8FD;DEVANAGARI JAIN OM;Lo;0;L;;;;;N;;;;; +A8FE;DEVANAGARI LETTER AY;Lo;0;L;;;;;N;;;;; +A8FF;DEVANAGARI VOWEL SIGN AY;Mn;0;NSM;;;;;N;;;;; +A900;KAYAH LI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +A901;KAYAH LI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +A902;KAYAH LI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +A903;KAYAH LI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +A904;KAYAH LI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +A905;KAYAH LI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +A906;KAYAH LI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +A907;KAYAH LI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +A908;KAYAH LI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +A909;KAYAH LI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +A90A;KAYAH LI LETTER KA;Lo;0;L;;;;;N;;;;; +A90B;KAYAH LI LETTER KHA;Lo;0;L;;;;;N;;;;; +A90C;KAYAH LI LETTER GA;Lo;0;L;;;;;N;;;;; +A90D;KAYAH LI LETTER NGA;Lo;0;L;;;;;N;;;;; +A90E;KAYAH LI LETTER SA;Lo;0;L;;;;;N;;;;; +A90F;KAYAH LI LETTER SHA;Lo;0;L;;;;;N;;;;; +A910;KAYAH LI LETTER ZA;Lo;0;L;;;;;N;;;;; +A911;KAYAH LI LETTER NYA;Lo;0;L;;;;;N;;;;; +A912;KAYAH LI LETTER TA;Lo;0;L;;;;;N;;;;; +A913;KAYAH LI LETTER HTA;Lo;0;L;;;;;N;;;;; +A914;KAYAH LI LETTER NA;Lo;0;L;;;;;N;;;;; +A915;KAYAH LI LETTER PA;Lo;0;L;;;;;N;;;;; +A916;KAYAH LI LETTER PHA;Lo;0;L;;;;;N;;;;; +A917;KAYAH LI LETTER MA;Lo;0;L;;;;;N;;;;; +A918;KAYAH LI LETTER DA;Lo;0;L;;;;;N;;;;; +A919;KAYAH LI LETTER BA;Lo;0;L;;;;;N;;;;; +A91A;KAYAH LI LETTER RA;Lo;0;L;;;;;N;;;;; +A91B;KAYAH LI LETTER YA;Lo;0;L;;;;;N;;;;; +A91C;KAYAH LI LETTER LA;Lo;0;L;;;;;N;;;;; +A91D;KAYAH LI LETTER WA;Lo;0;L;;;;;N;;;;; +A91E;KAYAH LI LETTER THA;Lo;0;L;;;;;N;;;;; +A91F;KAYAH LI LETTER HA;Lo;0;L;;;;;N;;;;; +A920;KAYAH LI LETTER VA;Lo;0;L;;;;;N;;;;; +A921;KAYAH LI LETTER CA;Lo;0;L;;;;;N;;;;; +A922;KAYAH LI LETTER A;Lo;0;L;;;;;N;;;;; +A923;KAYAH LI LETTER OE;Lo;0;L;;;;;N;;;;; +A924;KAYAH LI LETTER I;Lo;0;L;;;;;N;;;;; +A925;KAYAH LI LETTER OO;Lo;0;L;;;;;N;;;;; +A926;KAYAH LI VOWEL UE;Mn;0;NSM;;;;;N;;;;; +A927;KAYAH LI VOWEL E;Mn;0;NSM;;;;;N;;;;; +A928;KAYAH LI VOWEL U;Mn;0;NSM;;;;;N;;;;; +A929;KAYAH LI VOWEL EE;Mn;0;NSM;;;;;N;;;;; +A92A;KAYAH LI VOWEL O;Mn;0;NSM;;;;;N;;;;; +A92B;KAYAH LI TONE PLOPHU;Mn;220;NSM;;;;;N;;;;; +A92C;KAYAH LI TONE CALYA;Mn;220;NSM;;;;;N;;;;; +A92D;KAYAH LI TONE CALYA PLOPHU;Mn;220;NSM;;;;;N;;;;; +A92E;KAYAH LI SIGN CWI;Po;0;L;;;;;N;;;;; +A92F;KAYAH LI SIGN SHYA;Po;0;L;;;;;N;;;;; +A930;REJANG LETTER KA;Lo;0;L;;;;;N;;;;; +A931;REJANG LETTER GA;Lo;0;L;;;;;N;;;;; +A932;REJANG LETTER NGA;Lo;0;L;;;;;N;;;;; +A933;REJANG LETTER TA;Lo;0;L;;;;;N;;;;; +A934;REJANG LETTER DA;Lo;0;L;;;;;N;;;;; +A935;REJANG LETTER NA;Lo;0;L;;;;;N;;;;; +A936;REJANG LETTER PA;Lo;0;L;;;;;N;;;;; +A937;REJANG LETTER BA;Lo;0;L;;;;;N;;;;; +A938;REJANG LETTER MA;Lo;0;L;;;;;N;;;;; +A939;REJANG LETTER CA;Lo;0;L;;;;;N;;;;; +A93A;REJANG LETTER JA;Lo;0;L;;;;;N;;;;; +A93B;REJANG LETTER NYA;Lo;0;L;;;;;N;;;;; +A93C;REJANG LETTER SA;Lo;0;L;;;;;N;;;;; +A93D;REJANG LETTER RA;Lo;0;L;;;;;N;;;;; +A93E;REJANG LETTER LA;Lo;0;L;;;;;N;;;;; +A93F;REJANG LETTER YA;Lo;0;L;;;;;N;;;;; +A940;REJANG LETTER WA;Lo;0;L;;;;;N;;;;; +A941;REJANG LETTER HA;Lo;0;L;;;;;N;;;;; +A942;REJANG LETTER MBA;Lo;0;L;;;;;N;;;;; +A943;REJANG LETTER NGGA;Lo;0;L;;;;;N;;;;; +A944;REJANG LETTER NDA;Lo;0;L;;;;;N;;;;; +A945;REJANG LETTER NYJA;Lo;0;L;;;;;N;;;;; +A946;REJANG LETTER A;Lo;0;L;;;;;N;;;;; +A947;REJANG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +A948;REJANG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +A949;REJANG VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +A94A;REJANG VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +A94B;REJANG VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +A94C;REJANG VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +A94D;REJANG VOWEL SIGN EU;Mn;0;NSM;;;;;N;;;;; +A94E;REJANG VOWEL SIGN EA;Mn;0;NSM;;;;;N;;;;; +A94F;REJANG CONSONANT SIGN NG;Mn;0;NSM;;;;;N;;;;; +A950;REJANG CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;; +A951;REJANG CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;; +A952;REJANG CONSONANT SIGN H;Mc;0;L;;;;;N;;;;; +A953;REJANG VIRAMA;Mc;9;L;;;;;N;;;;; +A95F;REJANG SECTION MARK;Po;0;L;;;;;N;;;;; +A960;HANGUL CHOSEONG TIKEUT-MIEUM;Lo;0;L;;;;;N;;;;; +A961;HANGUL CHOSEONG TIKEUT-PIEUP;Lo;0;L;;;;;N;;;;; +A962;HANGUL CHOSEONG TIKEUT-SIOS;Lo;0;L;;;;;N;;;;; +A963;HANGUL CHOSEONG TIKEUT-CIEUC;Lo;0;L;;;;;N;;;;; +A964;HANGUL CHOSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;;;; +A965;HANGUL CHOSEONG RIEUL-SSANGKIYEOK;Lo;0;L;;;;;N;;;;; +A966;HANGUL CHOSEONG RIEUL-TIKEUT;Lo;0;L;;;;;N;;;;; +A967;HANGUL CHOSEONG RIEUL-SSANGTIKEUT;Lo;0;L;;;;;N;;;;; +A968;HANGUL CHOSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;;;; +A969;HANGUL CHOSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;;;; +A96A;HANGUL CHOSEONG RIEUL-SSANGPIEUP;Lo;0;L;;;;;N;;;;; +A96B;HANGUL CHOSEONG RIEUL-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +A96C;HANGUL CHOSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;;;; +A96D;HANGUL CHOSEONG RIEUL-CIEUC;Lo;0;L;;;;;N;;;;; +A96E;HANGUL CHOSEONG RIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;; +A96F;HANGUL CHOSEONG MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;; +A970;HANGUL CHOSEONG MIEUM-TIKEUT;Lo;0;L;;;;;N;;;;; +A971;HANGUL CHOSEONG MIEUM-SIOS;Lo;0;L;;;;;N;;;;; +A972;HANGUL CHOSEONG PIEUP-SIOS-THIEUTH;Lo;0;L;;;;;N;;;;; +A973;HANGUL CHOSEONG PIEUP-KHIEUKH;Lo;0;L;;;;;N;;;;; +A974;HANGUL CHOSEONG PIEUP-HIEUH;Lo;0;L;;;;;N;;;;; +A975;HANGUL CHOSEONG SSANGSIOS-PIEUP;Lo;0;L;;;;;N;;;;; +A976;HANGUL CHOSEONG IEUNG-RIEUL;Lo;0;L;;;;;N;;;;; +A977;HANGUL CHOSEONG IEUNG-HIEUH;Lo;0;L;;;;;N;;;;; +A978;HANGUL CHOSEONG SSANGCIEUC-HIEUH;Lo;0;L;;;;;N;;;;; +A979;HANGUL CHOSEONG SSANGTHIEUTH;Lo;0;L;;;;;N;;;;; +A97A;HANGUL CHOSEONG PHIEUPH-HIEUH;Lo;0;L;;;;;N;;;;; +A97B;HANGUL CHOSEONG HIEUH-SIOS;Lo;0;L;;;;;N;;;;; +A97C;HANGUL CHOSEONG SSANGYEORINHIEUH;Lo;0;L;;;;;N;;;;; +A980;JAVANESE SIGN PANYANGGA;Mn;0;NSM;;;;;N;;;;; +A981;JAVANESE SIGN CECAK;Mn;0;NSM;;;;;N;;;;; +A982;JAVANESE SIGN LAYAR;Mn;0;NSM;;;;;N;;;;; +A983;JAVANESE SIGN WIGNYAN;Mc;0;L;;;;;N;;;;; +A984;JAVANESE LETTER A;Lo;0;L;;;;;N;;;;; +A985;JAVANESE LETTER I KAWI;Lo;0;L;;;;;N;;;;; +A986;JAVANESE LETTER I;Lo;0;L;;;;;N;;;;; +A987;JAVANESE LETTER II;Lo;0;L;;;;;N;;;;; +A988;JAVANESE LETTER U;Lo;0;L;;;;;N;;;;; +A989;JAVANESE LETTER PA CEREK;Lo;0;L;;;;;N;;;;; +A98A;JAVANESE LETTER NGA LELET;Lo;0;L;;;;;N;;;;; +A98B;JAVANESE LETTER NGA LELET RASWADI;Lo;0;L;;;;;N;;;;; +A98C;JAVANESE LETTER E;Lo;0;L;;;;;N;;;;; +A98D;JAVANESE LETTER AI;Lo;0;L;;;;;N;;;;; +A98E;JAVANESE LETTER O;Lo;0;L;;;;;N;;;;; +A98F;JAVANESE LETTER KA;Lo;0;L;;;;;N;;;;; +A990;JAVANESE LETTER KA SASAK;Lo;0;L;;;;;N;;;;; +A991;JAVANESE LETTER KA MURDA;Lo;0;L;;;;;N;;;;; +A992;JAVANESE LETTER GA;Lo;0;L;;;;;N;;;;; +A993;JAVANESE LETTER GA MURDA;Lo;0;L;;;;;N;;;;; +A994;JAVANESE LETTER NGA;Lo;0;L;;;;;N;;;;; +A995;JAVANESE LETTER CA;Lo;0;L;;;;;N;;;;; +A996;JAVANESE LETTER CA MURDA;Lo;0;L;;;;;N;;;;; +A997;JAVANESE LETTER JA;Lo;0;L;;;;;N;;;;; +A998;JAVANESE LETTER NYA MURDA;Lo;0;L;;;;;N;;;;; +A999;JAVANESE LETTER JA MAHAPRANA;Lo;0;L;;;;;N;;;;; +A99A;JAVANESE LETTER NYA;Lo;0;L;;;;;N;;;;; +A99B;JAVANESE LETTER TTA;Lo;0;L;;;;;N;;;;; +A99C;JAVANESE LETTER TTA MAHAPRANA;Lo;0;L;;;;;N;;;;; +A99D;JAVANESE LETTER DDA;Lo;0;L;;;;;N;;;;; +A99E;JAVANESE LETTER DDA MAHAPRANA;Lo;0;L;;;;;N;;;;; +A99F;JAVANESE LETTER NA MURDA;Lo;0;L;;;;;N;;;;; +A9A0;JAVANESE LETTER TA;Lo;0;L;;;;;N;;;;; +A9A1;JAVANESE LETTER TA MURDA;Lo;0;L;;;;;N;;;;; +A9A2;JAVANESE LETTER DA;Lo;0;L;;;;;N;;;;; +A9A3;JAVANESE LETTER DA MAHAPRANA;Lo;0;L;;;;;N;;;;; +A9A4;JAVANESE LETTER NA;Lo;0;L;;;;;N;;;;; +A9A5;JAVANESE LETTER PA;Lo;0;L;;;;;N;;;;; +A9A6;JAVANESE LETTER PA MURDA;Lo;0;L;;;;;N;;;;; +A9A7;JAVANESE LETTER BA;Lo;0;L;;;;;N;;;;; +A9A8;JAVANESE LETTER BA MURDA;Lo;0;L;;;;;N;;;;; +A9A9;JAVANESE LETTER MA;Lo;0;L;;;;;N;;;;; +A9AA;JAVANESE LETTER YA;Lo;0;L;;;;;N;;;;; +A9AB;JAVANESE LETTER RA;Lo;0;L;;;;;N;;;;; +A9AC;JAVANESE LETTER RA AGUNG;Lo;0;L;;;;;N;;;;; +A9AD;JAVANESE LETTER LA;Lo;0;L;;;;;N;;;;; +A9AE;JAVANESE LETTER WA;Lo;0;L;;;;;N;;;;; +A9AF;JAVANESE LETTER SA MURDA;Lo;0;L;;;;;N;;;;; +A9B0;JAVANESE LETTER SA MAHAPRANA;Lo;0;L;;;;;N;;;;; +A9B1;JAVANESE LETTER SA;Lo;0;L;;;;;N;;;;; +A9B2;JAVANESE LETTER HA;Lo;0;L;;;;;N;;;;; +A9B3;JAVANESE SIGN CECAK TELU;Mn;7;NSM;;;;;N;;;;; +A9B4;JAVANESE VOWEL SIGN TARUNG;Mc;0;L;;;;;N;;;;; +A9B5;JAVANESE VOWEL SIGN TOLONG;Mc;0;L;;;;;N;;;;; +A9B6;JAVANESE VOWEL SIGN WULU;Mn;0;NSM;;;;;N;;;;; +A9B7;JAVANESE VOWEL SIGN WULU MELIK;Mn;0;NSM;;;;;N;;;;; +A9B8;JAVANESE VOWEL SIGN SUKU;Mn;0;NSM;;;;;N;;;;; +A9B9;JAVANESE VOWEL SIGN SUKU MENDUT;Mn;0;NSM;;;;;N;;;;; +A9BA;JAVANESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;;;; +A9BB;JAVANESE VOWEL SIGN DIRGA MURE;Mc;0;L;;;;;N;;;;; +A9BC;JAVANESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;;;; +A9BD;JAVANESE CONSONANT SIGN KERET;Mn;0;NSM;;;;;N;;;;; +A9BE;JAVANESE CONSONANT SIGN PENGKAL;Mc;0;L;;;;;N;;;;; +A9BF;JAVANESE CONSONANT SIGN CAKRA;Mc;0;L;;;;;N;;;;; +A9C0;JAVANESE PANGKON;Mc;9;L;;;;;N;;;;; +A9C1;JAVANESE LEFT RERENGGAN;Po;0;L;;;;;N;;;;; +A9C2;JAVANESE RIGHT RERENGGAN;Po;0;L;;;;;N;;;;; +A9C3;JAVANESE PADA ANDAP;Po;0;L;;;;;N;;;;; +A9C4;JAVANESE PADA MADYA;Po;0;L;;;;;N;;;;; +A9C5;JAVANESE PADA LUHUR;Po;0;L;;;;;N;;;;; +A9C6;JAVANESE PADA WINDU;Po;0;L;;;;;N;;;;; +A9C7;JAVANESE PADA PANGKAT;Po;0;L;;;;;N;;;;; +A9C8;JAVANESE PADA LINGSA;Po;0;L;;;;;N;;;;; +A9C9;JAVANESE PADA LUNGSI;Po;0;L;;;;;N;;;;; +A9CA;JAVANESE PADA ADEG;Po;0;L;;;;;N;;;;; +A9CB;JAVANESE PADA ADEG ADEG;Po;0;L;;;;;N;;;;; +A9CC;JAVANESE PADA PISELEH;Po;0;L;;;;;N;;;;; +A9CD;JAVANESE TURNED PADA PISELEH;Po;0;L;;;;;N;;;;; +A9CF;JAVANESE PANGRANGKEP;Lm;0;L;;;;;N;;;;; +A9D0;JAVANESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +A9D1;JAVANESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +A9D2;JAVANESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +A9D3;JAVANESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +A9D4;JAVANESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +A9D5;JAVANESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +A9D6;JAVANESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +A9D7;JAVANESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +A9D8;JAVANESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +A9D9;JAVANESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +A9DE;JAVANESE PADA TIRTA TUMETES;Po;0;L;;;;;N;;;;; +A9DF;JAVANESE PADA ISEN-ISEN;Po;0;L;;;;;N;;;;; +A9E0;MYANMAR LETTER SHAN GHA;Lo;0;L;;;;;N;;;;; +A9E1;MYANMAR LETTER SHAN CHA;Lo;0;L;;;;;N;;;;; +A9E2;MYANMAR LETTER SHAN JHA;Lo;0;L;;;;;N;;;;; +A9E3;MYANMAR LETTER SHAN NNA;Lo;0;L;;;;;N;;;;; +A9E4;MYANMAR LETTER SHAN BHA;Lo;0;L;;;;;N;;;;; +A9E5;MYANMAR SIGN SHAN SAW;Mn;0;NSM;;;;;N;;;;; +A9E6;MYANMAR MODIFIER LETTER SHAN REDUPLICATION;Lm;0;L;;;;;N;;;;; +A9E7;MYANMAR LETTER TAI LAING NYA;Lo;0;L;;;;;N;;;;; +A9E8;MYANMAR LETTER TAI LAING FA;Lo;0;L;;;;;N;;;;; +A9E9;MYANMAR LETTER TAI LAING GA;Lo;0;L;;;;;N;;;;; +A9EA;MYANMAR LETTER TAI LAING GHA;Lo;0;L;;;;;N;;;;; +A9EB;MYANMAR LETTER TAI LAING JA;Lo;0;L;;;;;N;;;;; +A9EC;MYANMAR LETTER TAI LAING JHA;Lo;0;L;;;;;N;;;;; +A9ED;MYANMAR LETTER TAI LAING DDA;Lo;0;L;;;;;N;;;;; +A9EE;MYANMAR LETTER TAI LAING DDHA;Lo;0;L;;;;;N;;;;; +A9EF;MYANMAR LETTER TAI LAING NNA;Lo;0;L;;;;;N;;;;; +A9F0;MYANMAR TAI LAING DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +A9F1;MYANMAR TAI LAING DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +A9F2;MYANMAR TAI LAING DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +A9F3;MYANMAR TAI LAING DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +A9F4;MYANMAR TAI LAING DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +A9F5;MYANMAR TAI LAING DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +A9F6;MYANMAR TAI LAING DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +A9F7;MYANMAR TAI LAING DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +A9F8;MYANMAR TAI LAING DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +A9F9;MYANMAR TAI LAING DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +A9FA;MYANMAR LETTER TAI LAING LLA;Lo;0;L;;;;;N;;;;; +A9FB;MYANMAR LETTER TAI LAING DA;Lo;0;L;;;;;N;;;;; +A9FC;MYANMAR LETTER TAI LAING DHA;Lo;0;L;;;;;N;;;;; +A9FD;MYANMAR LETTER TAI LAING BA;Lo;0;L;;;;;N;;;;; +A9FE;MYANMAR LETTER TAI LAING BHA;Lo;0;L;;;;;N;;;;; +AA00;CHAM LETTER A;Lo;0;L;;;;;N;;;;; +AA01;CHAM LETTER I;Lo;0;L;;;;;N;;;;; +AA02;CHAM LETTER U;Lo;0;L;;;;;N;;;;; +AA03;CHAM LETTER E;Lo;0;L;;;;;N;;;;; +AA04;CHAM LETTER AI;Lo;0;L;;;;;N;;;;; +AA05;CHAM LETTER O;Lo;0;L;;;;;N;;;;; +AA06;CHAM LETTER KA;Lo;0;L;;;;;N;;;;; +AA07;CHAM LETTER KHA;Lo;0;L;;;;;N;;;;; +AA08;CHAM LETTER GA;Lo;0;L;;;;;N;;;;; +AA09;CHAM LETTER GHA;Lo;0;L;;;;;N;;;;; +AA0A;CHAM LETTER NGUE;Lo;0;L;;;;;N;;;;; +AA0B;CHAM LETTER NGA;Lo;0;L;;;;;N;;;;; +AA0C;CHAM LETTER CHA;Lo;0;L;;;;;N;;;;; +AA0D;CHAM LETTER CHHA;Lo;0;L;;;;;N;;;;; +AA0E;CHAM LETTER JA;Lo;0;L;;;;;N;;;;; +AA0F;CHAM LETTER JHA;Lo;0;L;;;;;N;;;;; +AA10;CHAM LETTER NHUE;Lo;0;L;;;;;N;;;;; +AA11;CHAM LETTER NHA;Lo;0;L;;;;;N;;;;; +AA12;CHAM LETTER NHJA;Lo;0;L;;;;;N;;;;; +AA13;CHAM LETTER TA;Lo;0;L;;;;;N;;;;; +AA14;CHAM LETTER THA;Lo;0;L;;;;;N;;;;; +AA15;CHAM LETTER DA;Lo;0;L;;;;;N;;;;; +AA16;CHAM LETTER DHA;Lo;0;L;;;;;N;;;;; +AA17;CHAM LETTER NUE;Lo;0;L;;;;;N;;;;; +AA18;CHAM LETTER NA;Lo;0;L;;;;;N;;;;; +AA19;CHAM LETTER DDA;Lo;0;L;;;;;N;;;;; +AA1A;CHAM LETTER PA;Lo;0;L;;;;;N;;;;; +AA1B;CHAM LETTER PPA;Lo;0;L;;;;;N;;;;; +AA1C;CHAM LETTER PHA;Lo;0;L;;;;;N;;;;; +AA1D;CHAM LETTER BA;Lo;0;L;;;;;N;;;;; +AA1E;CHAM LETTER BHA;Lo;0;L;;;;;N;;;;; +AA1F;CHAM LETTER MUE;Lo;0;L;;;;;N;;;;; +AA20;CHAM LETTER MA;Lo;0;L;;;;;N;;;;; +AA21;CHAM LETTER BBA;Lo;0;L;;;;;N;;;;; +AA22;CHAM LETTER YA;Lo;0;L;;;;;N;;;;; +AA23;CHAM LETTER RA;Lo;0;L;;;;;N;;;;; +AA24;CHAM LETTER LA;Lo;0;L;;;;;N;;;;; +AA25;CHAM LETTER VA;Lo;0;L;;;;;N;;;;; +AA26;CHAM LETTER SSA;Lo;0;L;;;;;N;;;;; +AA27;CHAM LETTER SA;Lo;0;L;;;;;N;;;;; +AA28;CHAM LETTER HA;Lo;0;L;;;;;N;;;;; +AA29;CHAM VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;; +AA2A;CHAM VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +AA2B;CHAM VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +AA2C;CHAM VOWEL SIGN EI;Mn;0;NSM;;;;;N;;;;; +AA2D;CHAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +AA2E;CHAM VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;; +AA2F;CHAM VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +AA30;CHAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +AA31;CHAM VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +AA32;CHAM VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;; +AA33;CHAM CONSONANT SIGN YA;Mc;0;L;;;;;N;;;;; +AA34;CHAM CONSONANT SIGN RA;Mc;0;L;;;;;N;;;;; +AA35;CHAM CONSONANT SIGN LA;Mn;0;NSM;;;;;N;;;;; +AA36;CHAM CONSONANT SIGN WA;Mn;0;NSM;;;;;N;;;;; +AA40;CHAM LETTER FINAL K;Lo;0;L;;;;;N;;;;; +AA41;CHAM LETTER FINAL G;Lo;0;L;;;;;N;;;;; +AA42;CHAM LETTER FINAL NG;Lo;0;L;;;;;N;;;;; +AA43;CHAM CONSONANT SIGN FINAL NG;Mn;0;NSM;;;;;N;;;;; +AA44;CHAM LETTER FINAL CH;Lo;0;L;;;;;N;;;;; +AA45;CHAM LETTER FINAL T;Lo;0;L;;;;;N;;;;; +AA46;CHAM LETTER FINAL N;Lo;0;L;;;;;N;;;;; +AA47;CHAM LETTER FINAL P;Lo;0;L;;;;;N;;;;; +AA48;CHAM LETTER FINAL Y;Lo;0;L;;;;;N;;;;; +AA49;CHAM LETTER FINAL R;Lo;0;L;;;;;N;;;;; +AA4A;CHAM LETTER FINAL L;Lo;0;L;;;;;N;;;;; +AA4B;CHAM LETTER FINAL SS;Lo;0;L;;;;;N;;;;; +AA4C;CHAM CONSONANT SIGN FINAL M;Mn;0;NSM;;;;;N;;;;; +AA4D;CHAM CONSONANT SIGN FINAL H;Mc;0;L;;;;;N;;;;; +AA50;CHAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +AA51;CHAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +AA52;CHAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +AA53;CHAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +AA54;CHAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +AA55;CHAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +AA56;CHAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +AA57;CHAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +AA58;CHAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +AA59;CHAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +AA5C;CHAM PUNCTUATION SPIRAL;Po;0;L;;;;;N;;;;; +AA5D;CHAM PUNCTUATION DANDA;Po;0;L;;;;;N;;;;; +AA5E;CHAM PUNCTUATION DOUBLE DANDA;Po;0;L;;;;;N;;;;; +AA5F;CHAM PUNCTUATION TRIPLE DANDA;Po;0;L;;;;;N;;;;; +AA60;MYANMAR LETTER KHAMTI GA;Lo;0;L;;;;;N;;;;; +AA61;MYANMAR LETTER KHAMTI CA;Lo;0;L;;;;;N;;;;; +AA62;MYANMAR LETTER KHAMTI CHA;Lo;0;L;;;;;N;;;;; +AA63;MYANMAR LETTER KHAMTI JA;Lo;0;L;;;;;N;;;;; +AA64;MYANMAR LETTER KHAMTI JHA;Lo;0;L;;;;;N;;;;; +AA65;MYANMAR LETTER KHAMTI NYA;Lo;0;L;;;;;N;;;;; +AA66;MYANMAR LETTER KHAMTI TTA;Lo;0;L;;;;;N;;;;; +AA67;MYANMAR LETTER KHAMTI TTHA;Lo;0;L;;;;;N;;;;; +AA68;MYANMAR LETTER KHAMTI DDA;Lo;0;L;;;;;N;;;;; +AA69;MYANMAR LETTER KHAMTI DDHA;Lo;0;L;;;;;N;;;;; +AA6A;MYANMAR LETTER KHAMTI DHA;Lo;0;L;;;;;N;;;;; +AA6B;MYANMAR LETTER KHAMTI NA;Lo;0;L;;;;;N;;;;; +AA6C;MYANMAR LETTER KHAMTI SA;Lo;0;L;;;;;N;;;;; +AA6D;MYANMAR LETTER KHAMTI HA;Lo;0;L;;;;;N;;;;; +AA6E;MYANMAR LETTER KHAMTI HHA;Lo;0;L;;;;;N;;;;; +AA6F;MYANMAR LETTER KHAMTI FA;Lo;0;L;;;;;N;;;;; +AA70;MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION;Lm;0;L;;;;;N;;;;; +AA71;MYANMAR LETTER KHAMTI XA;Lo;0;L;;;;;N;;;;; +AA72;MYANMAR LETTER KHAMTI ZA;Lo;0;L;;;;;N;;;;; +AA73;MYANMAR LETTER KHAMTI RA;Lo;0;L;;;;;N;;;;; +AA74;MYANMAR LOGOGRAM KHAMTI OAY;Lo;0;L;;;;;N;;;;; +AA75;MYANMAR LOGOGRAM KHAMTI QN;Lo;0;L;;;;;N;;;;; +AA76;MYANMAR LOGOGRAM KHAMTI HM;Lo;0;L;;;;;N;;;;; +AA77;MYANMAR SYMBOL AITON EXCLAMATION;So;0;L;;;;;N;;;;; +AA78;MYANMAR SYMBOL AITON ONE;So;0;L;;;;;N;;;;; +AA79;MYANMAR SYMBOL AITON TWO;So;0;L;;;;;N;;;;; +AA7A;MYANMAR LETTER AITON RA;Lo;0;L;;;;;N;;;;; +AA7B;MYANMAR SIGN PAO KAREN TONE;Mc;0;L;;;;;N;;;;; +AA7C;MYANMAR SIGN TAI LAING TONE-2;Mn;0;NSM;;;;;N;;;;; +AA7D;MYANMAR SIGN TAI LAING TONE-5;Mc;0;L;;;;;N;;;;; +AA7E;MYANMAR LETTER SHWE PALAUNG CHA;Lo;0;L;;;;;N;;;;; +AA7F;MYANMAR LETTER SHWE PALAUNG SHA;Lo;0;L;;;;;N;;;;; +AA80;TAI VIET LETTER LOW KO;Lo;0;L;;;;;N;;;;; +AA81;TAI VIET LETTER HIGH KO;Lo;0;L;;;;;N;;;;; +AA82;TAI VIET LETTER LOW KHO;Lo;0;L;;;;;N;;;;; +AA83;TAI VIET LETTER HIGH KHO;Lo;0;L;;;;;N;;;;; +AA84;TAI VIET LETTER LOW KHHO;Lo;0;L;;;;;N;;;;; +AA85;TAI VIET LETTER HIGH KHHO;Lo;0;L;;;;;N;;;;; +AA86;TAI VIET LETTER LOW GO;Lo;0;L;;;;;N;;;;; +AA87;TAI VIET LETTER HIGH GO;Lo;0;L;;;;;N;;;;; +AA88;TAI VIET LETTER LOW NGO;Lo;0;L;;;;;N;;;;; +AA89;TAI VIET LETTER HIGH NGO;Lo;0;L;;;;;N;;;;; +AA8A;TAI VIET LETTER LOW CO;Lo;0;L;;;;;N;;;;; +AA8B;TAI VIET LETTER HIGH CO;Lo;0;L;;;;;N;;;;; +AA8C;TAI VIET LETTER LOW CHO;Lo;0;L;;;;;N;;;;; +AA8D;TAI VIET LETTER HIGH CHO;Lo;0;L;;;;;N;;;;; +AA8E;TAI VIET LETTER LOW SO;Lo;0;L;;;;;N;;;;; +AA8F;TAI VIET LETTER HIGH SO;Lo;0;L;;;;;N;;;;; +AA90;TAI VIET LETTER LOW NYO;Lo;0;L;;;;;N;;;;; +AA91;TAI VIET LETTER HIGH NYO;Lo;0;L;;;;;N;;;;; +AA92;TAI VIET LETTER LOW DO;Lo;0;L;;;;;N;;;;; +AA93;TAI VIET LETTER HIGH DO;Lo;0;L;;;;;N;;;;; +AA94;TAI VIET LETTER LOW TO;Lo;0;L;;;;;N;;;;; +AA95;TAI VIET LETTER HIGH TO;Lo;0;L;;;;;N;;;;; +AA96;TAI VIET LETTER LOW THO;Lo;0;L;;;;;N;;;;; +AA97;TAI VIET LETTER HIGH THO;Lo;0;L;;;;;N;;;;; +AA98;TAI VIET LETTER LOW NO;Lo;0;L;;;;;N;;;;; +AA99;TAI VIET LETTER HIGH NO;Lo;0;L;;;;;N;;;;; +AA9A;TAI VIET LETTER LOW BO;Lo;0;L;;;;;N;;;;; +AA9B;TAI VIET LETTER HIGH BO;Lo;0;L;;;;;N;;;;; +AA9C;TAI VIET LETTER LOW PO;Lo;0;L;;;;;N;;;;; +AA9D;TAI VIET LETTER HIGH PO;Lo;0;L;;;;;N;;;;; +AA9E;TAI VIET LETTER LOW PHO;Lo;0;L;;;;;N;;;;; +AA9F;TAI VIET LETTER HIGH PHO;Lo;0;L;;;;;N;;;;; +AAA0;TAI VIET LETTER LOW FO;Lo;0;L;;;;;N;;;;; +AAA1;TAI VIET LETTER HIGH FO;Lo;0;L;;;;;N;;;;; +AAA2;TAI VIET LETTER LOW MO;Lo;0;L;;;;;N;;;;; +AAA3;TAI VIET LETTER HIGH MO;Lo;0;L;;;;;N;;;;; +AAA4;TAI VIET LETTER LOW YO;Lo;0;L;;;;;N;;;;; +AAA5;TAI VIET LETTER HIGH YO;Lo;0;L;;;;;N;;;;; +AAA6;TAI VIET LETTER LOW RO;Lo;0;L;;;;;N;;;;; +AAA7;TAI VIET LETTER HIGH RO;Lo;0;L;;;;;N;;;;; +AAA8;TAI VIET LETTER LOW LO;Lo;0;L;;;;;N;;;;; +AAA9;TAI VIET LETTER HIGH LO;Lo;0;L;;;;;N;;;;; +AAAA;TAI VIET LETTER LOW VO;Lo;0;L;;;;;N;;;;; +AAAB;TAI VIET LETTER HIGH VO;Lo;0;L;;;;;N;;;;; +AAAC;TAI VIET LETTER LOW HO;Lo;0;L;;;;;N;;;;; +AAAD;TAI VIET LETTER HIGH HO;Lo;0;L;;;;;N;;;;; +AAAE;TAI VIET LETTER LOW O;Lo;0;L;;;;;N;;;;; +AAAF;TAI VIET LETTER HIGH O;Lo;0;L;;;;;N;;;;; +AAB0;TAI VIET MAI KANG;Mn;230;NSM;;;;;N;;;;; +AAB1;TAI VIET VOWEL AA;Lo;0;L;;;;;N;;;;; +AAB2;TAI VIET VOWEL I;Mn;230;NSM;;;;;N;;;;; +AAB3;TAI VIET VOWEL UE;Mn;230;NSM;;;;;N;;;;; +AAB4;TAI VIET VOWEL U;Mn;220;NSM;;;;;N;;;;; +AAB5;TAI VIET VOWEL E;Lo;0;L;;;;;N;;;;; +AAB6;TAI VIET VOWEL O;Lo;0;L;;;;;N;;;;; +AAB7;TAI VIET MAI KHIT;Mn;230;NSM;;;;;N;;;;; +AAB8;TAI VIET VOWEL IA;Mn;230;NSM;;;;;N;;;;; +AAB9;TAI VIET VOWEL UEA;Lo;0;L;;;;;N;;;;; +AABA;TAI VIET VOWEL UA;Lo;0;L;;;;;N;;;;; +AABB;TAI VIET VOWEL AUE;Lo;0;L;;;;;N;;;;; +AABC;TAI VIET VOWEL AY;Lo;0;L;;;;;N;;;;; +AABD;TAI VIET VOWEL AN;Lo;0;L;;;;;N;;;;; +AABE;TAI VIET VOWEL AM;Mn;230;NSM;;;;;N;;;;; +AABF;TAI VIET TONE MAI EK;Mn;230;NSM;;;;;N;;;;; +AAC0;TAI VIET TONE MAI NUENG;Lo;0;L;;;;;N;;;;; +AAC1;TAI VIET TONE MAI THO;Mn;230;NSM;;;;;N;;;;; +AAC2;TAI VIET TONE MAI SONG;Lo;0;L;;;;;N;;;;; +AADB;TAI VIET SYMBOL KON;Lo;0;L;;;;;N;;;;; +AADC;TAI VIET SYMBOL NUENG;Lo;0;L;;;;;N;;;;; +AADD;TAI VIET SYMBOL SAM;Lm;0;L;;;;;N;;;;; +AADE;TAI VIET SYMBOL HO HOI;Po;0;L;;;;;N;;;;; +AADF;TAI VIET SYMBOL KOI KOI;Po;0;L;;;;;N;;;;; +AAE0;MEETEI MAYEK LETTER E;Lo;0;L;;;;;N;;;;; +AAE1;MEETEI MAYEK LETTER O;Lo;0;L;;;;;N;;;;; +AAE2;MEETEI MAYEK LETTER CHA;Lo;0;L;;;;;N;;;;; +AAE3;MEETEI MAYEK LETTER NYA;Lo;0;L;;;;;N;;;;; +AAE4;MEETEI MAYEK LETTER TTA;Lo;0;L;;;;;N;;;;; +AAE5;MEETEI MAYEK LETTER TTHA;Lo;0;L;;;;;N;;;;; +AAE6;MEETEI MAYEK LETTER DDA;Lo;0;L;;;;;N;;;;; +AAE7;MEETEI MAYEK LETTER DDHA;Lo;0;L;;;;;N;;;;; +AAE8;MEETEI MAYEK LETTER NNA;Lo;0;L;;;;;N;;;;; +AAE9;MEETEI MAYEK LETTER SHA;Lo;0;L;;;;;N;;;;; +AAEA;MEETEI MAYEK LETTER SSA;Lo;0;L;;;;;N;;;;; +AAEB;MEETEI MAYEK VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +AAEC;MEETEI MAYEK VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +AAED;MEETEI MAYEK VOWEL SIGN AAI;Mn;0;NSM;;;;;N;;;;; +AAEE;MEETEI MAYEK VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +AAEF;MEETEI MAYEK VOWEL SIGN AAU;Mc;0;L;;;;;N;;;;; +AAF0;MEETEI MAYEK CHEIKHAN;Po;0;L;;;;;N;;;;; +AAF1;MEETEI MAYEK AHANG KHUDAM;Po;0;L;;;;;N;;;;; +AAF2;MEETEI MAYEK ANJI;Lo;0;L;;;;;N;;;;; +AAF3;MEETEI MAYEK SYLLABLE REPETITION MARK;Lm;0;L;;;;;N;;;;; +AAF4;MEETEI MAYEK WORD REPETITION MARK;Lm;0;L;;;;;N;;;;; +AAF5;MEETEI MAYEK VOWEL SIGN VISARGA;Mc;0;L;;;;;N;;;;; +AAF6;MEETEI MAYEK VIRAMA;Mn;9;NSM;;;;;N;;;;; +AB01;ETHIOPIC SYLLABLE TTHU;Lo;0;L;;;;;N;;;;; +AB02;ETHIOPIC SYLLABLE TTHI;Lo;0;L;;;;;N;;;;; +AB03;ETHIOPIC SYLLABLE TTHAA;Lo;0;L;;;;;N;;;;; +AB04;ETHIOPIC SYLLABLE TTHEE;Lo;0;L;;;;;N;;;;; +AB05;ETHIOPIC SYLLABLE TTHE;Lo;0;L;;;;;N;;;;; +AB06;ETHIOPIC SYLLABLE TTHO;Lo;0;L;;;;;N;;;;; +AB09;ETHIOPIC SYLLABLE DDHU;Lo;0;L;;;;;N;;;;; +AB0A;ETHIOPIC SYLLABLE DDHI;Lo;0;L;;;;;N;;;;; +AB0B;ETHIOPIC SYLLABLE DDHAA;Lo;0;L;;;;;N;;;;; +AB0C;ETHIOPIC SYLLABLE DDHEE;Lo;0;L;;;;;N;;;;; +AB0D;ETHIOPIC SYLLABLE DDHE;Lo;0;L;;;;;N;;;;; +AB0E;ETHIOPIC SYLLABLE DDHO;Lo;0;L;;;;;N;;;;; +AB11;ETHIOPIC SYLLABLE DZU;Lo;0;L;;;;;N;;;;; +AB12;ETHIOPIC SYLLABLE DZI;Lo;0;L;;;;;N;;;;; +AB13;ETHIOPIC SYLLABLE DZAA;Lo;0;L;;;;;N;;;;; +AB14;ETHIOPIC SYLLABLE DZEE;Lo;0;L;;;;;N;;;;; +AB15;ETHIOPIC SYLLABLE DZE;Lo;0;L;;;;;N;;;;; +AB16;ETHIOPIC SYLLABLE DZO;Lo;0;L;;;;;N;;;;; +AB20;ETHIOPIC SYLLABLE CCHHA;Lo;0;L;;;;;N;;;;; +AB21;ETHIOPIC SYLLABLE CCHHU;Lo;0;L;;;;;N;;;;; +AB22;ETHIOPIC SYLLABLE CCHHI;Lo;0;L;;;;;N;;;;; +AB23;ETHIOPIC SYLLABLE CCHHAA;Lo;0;L;;;;;N;;;;; +AB24;ETHIOPIC SYLLABLE CCHHEE;Lo;0;L;;;;;N;;;;; +AB25;ETHIOPIC SYLLABLE CCHHE;Lo;0;L;;;;;N;;;;; +AB26;ETHIOPIC SYLLABLE CCHHO;Lo;0;L;;;;;N;;;;; +AB28;ETHIOPIC SYLLABLE BBA;Lo;0;L;;;;;N;;;;; +AB29;ETHIOPIC SYLLABLE BBU;Lo;0;L;;;;;N;;;;; +AB2A;ETHIOPIC SYLLABLE BBI;Lo;0;L;;;;;N;;;;; +AB2B;ETHIOPIC SYLLABLE BBAA;Lo;0;L;;;;;N;;;;; +AB2C;ETHIOPIC SYLLABLE BBEE;Lo;0;L;;;;;N;;;;; +AB2D;ETHIOPIC SYLLABLE BBE;Lo;0;L;;;;;N;;;;; +AB2E;ETHIOPIC SYLLABLE BBO;Lo;0;L;;;;;N;;;;; +AB30;LATIN SMALL LETTER BARRED ALPHA;Ll;0;L;;;;;N;;;;; +AB31;LATIN SMALL LETTER A REVERSED-SCHWA;Ll;0;L;;;;;N;;;;; +AB32;LATIN SMALL LETTER BLACKLETTER E;Ll;0;L;;;;;N;;;;; +AB33;LATIN SMALL LETTER BARRED E;Ll;0;L;;;;;N;;;;; +AB34;LATIN SMALL LETTER E WITH FLOURISH;Ll;0;L;;;;;N;;;;; +AB35;LATIN SMALL LETTER LENIS F;Ll;0;L;;;;;N;;;;; +AB36;LATIN SMALL LETTER SCRIPT G WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;; +AB37;LATIN SMALL LETTER L WITH INVERTED LAZY S;Ll;0;L;;;;;N;;;;; +AB38;LATIN SMALL LETTER L WITH DOUBLE MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +AB39;LATIN SMALL LETTER L WITH MIDDLE RING;Ll;0;L;;;;;N;;;;; +AB3A;LATIN SMALL LETTER M WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;; +AB3B;LATIN SMALL LETTER N WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;; +AB3C;LATIN SMALL LETTER ENG WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;; +AB3D;LATIN SMALL LETTER BLACKLETTER O;Ll;0;L;;;;;N;;;;; +AB3E;LATIN SMALL LETTER BLACKLETTER O WITH STROKE;Ll;0;L;;;;;N;;;;; +AB3F;LATIN SMALL LETTER OPEN O WITH STROKE;Ll;0;L;;;;;N;;;;; +AB40;LATIN SMALL LETTER INVERTED OE;Ll;0;L;;;;;N;;;;; +AB41;LATIN SMALL LETTER TURNED OE WITH STROKE;Ll;0;L;;;;;N;;;;; +AB42;LATIN SMALL LETTER TURNED OE WITH HORIZONTAL STROKE;Ll;0;L;;;;;N;;;;; +AB43;LATIN SMALL LETTER TURNED O OPEN-O;Ll;0;L;;;;;N;;;;; +AB44;LATIN SMALL LETTER TURNED O OPEN-O WITH STROKE;Ll;0;L;;;;;N;;;;; +AB45;LATIN SMALL LETTER STIRRUP R;Ll;0;L;;;;;N;;;;; +AB46;LATIN LETTER SMALL CAPITAL R WITH RIGHT LEG;Ll;0;L;;;;;N;;;;; +AB47;LATIN SMALL LETTER R WITHOUT HANDLE;Ll;0;L;;;;;N;;;;; +AB48;LATIN SMALL LETTER DOUBLE R;Ll;0;L;;;;;N;;;;; +AB49;LATIN SMALL LETTER R WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;; +AB4A;LATIN SMALL LETTER DOUBLE R WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;; +AB4B;LATIN SMALL LETTER SCRIPT R;Ll;0;L;;;;;N;;;;; +AB4C;LATIN SMALL LETTER SCRIPT R WITH RING;Ll;0;L;;;;;N;;;;; +AB4D;LATIN SMALL LETTER BASELINE ESH;Ll;0;L;;;;;N;;;;; +AB4E;LATIN SMALL LETTER U WITH SHORT RIGHT LEG;Ll;0;L;;;;;N;;;;; +AB4F;LATIN SMALL LETTER U BAR WITH SHORT RIGHT LEG;Ll;0;L;;;;;N;;;;; +AB50;LATIN SMALL LETTER UI;Ll;0;L;;;;;N;;;;; +AB51;LATIN SMALL LETTER TURNED UI;Ll;0;L;;;;;N;;;;; +AB52;LATIN SMALL LETTER U WITH LEFT HOOK;Ll;0;L;;;;;N;;;;; +AB53;LATIN SMALL LETTER CHI;Ll;0;L;;;;;N;;;A7B3;;A7B3 +AB54;LATIN SMALL LETTER CHI WITH LOW RIGHT RING;Ll;0;L;;;;;N;;;;; +AB55;LATIN SMALL LETTER CHI WITH LOW LEFT SERIF;Ll;0;L;;;;;N;;;;; +AB56;LATIN SMALL LETTER X WITH LOW RIGHT RING;Ll;0;L;;;;;N;;;;; +AB57;LATIN SMALL LETTER X WITH LONG LEFT LEG;Ll;0;L;;;;;N;;;;; +AB58;LATIN SMALL LETTER X WITH LONG LEFT LEG AND LOW RIGHT RING;Ll;0;L;;;;;N;;;;; +AB59;LATIN SMALL LETTER X WITH LONG LEFT LEG WITH SERIF;Ll;0;L;;;;;N;;;;; +AB5A;LATIN SMALL LETTER Y WITH SHORT RIGHT LEG;Ll;0;L;;;;;N;;;;; +AB5B;MODIFIER BREVE WITH INVERTED BREVE;Sk;0;L;;;;;N;;;;; +AB5C;MODIFIER LETTER SMALL HENG;Lm;0;L; A727;;;;N;;;;; +AB5D;MODIFIER LETTER SMALL L WITH INVERTED LAZY S;Lm;0;L; AB37;;;;N;;;;; +AB5E;MODIFIER LETTER SMALL L WITH MIDDLE TILDE;Lm;0;L; 026B;;;;N;;;;; +AB5F;MODIFIER LETTER SMALL U WITH LEFT HOOK;Lm;0;L; AB52;;;;N;;;;; +AB60;LATIN SMALL LETTER SAKHA YAT;Ll;0;L;;;;;N;;;;; +AB61;LATIN SMALL LETTER IOTIFIED E;Ll;0;L;;;;;N;;;;; +AB62;LATIN SMALL LETTER OPEN OE;Ll;0;L;;;;;N;;;;; +AB63;LATIN SMALL LETTER UO;Ll;0;L;;;;;N;;;;; +AB64;LATIN SMALL LETTER INVERTED ALPHA;Ll;0;L;;;;;N;;;;; +AB65;GREEK LETTER SMALL CAPITAL OMEGA;Ll;0;L;;;;;N;;;;; +AB66;LATIN SMALL LETTER DZ DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +AB67;LATIN SMALL LETTER TS DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +AB70;CHEROKEE SMALL LETTER A;Ll;0;L;;;;;N;;;13A0;;13A0 +AB71;CHEROKEE SMALL LETTER E;Ll;0;L;;;;;N;;;13A1;;13A1 +AB72;CHEROKEE SMALL LETTER I;Ll;0;L;;;;;N;;;13A2;;13A2 +AB73;CHEROKEE SMALL LETTER O;Ll;0;L;;;;;N;;;13A3;;13A3 +AB74;CHEROKEE SMALL LETTER U;Ll;0;L;;;;;N;;;13A4;;13A4 +AB75;CHEROKEE SMALL LETTER V;Ll;0;L;;;;;N;;;13A5;;13A5 +AB76;CHEROKEE SMALL LETTER GA;Ll;0;L;;;;;N;;;13A6;;13A6 +AB77;CHEROKEE SMALL LETTER KA;Ll;0;L;;;;;N;;;13A7;;13A7 +AB78;CHEROKEE SMALL LETTER GE;Ll;0;L;;;;;N;;;13A8;;13A8 +AB79;CHEROKEE SMALL LETTER GI;Ll;0;L;;;;;N;;;13A9;;13A9 +AB7A;CHEROKEE SMALL LETTER GO;Ll;0;L;;;;;N;;;13AA;;13AA +AB7B;CHEROKEE SMALL LETTER GU;Ll;0;L;;;;;N;;;13AB;;13AB +AB7C;CHEROKEE SMALL LETTER GV;Ll;0;L;;;;;N;;;13AC;;13AC +AB7D;CHEROKEE SMALL LETTER HA;Ll;0;L;;;;;N;;;13AD;;13AD +AB7E;CHEROKEE SMALL LETTER HE;Ll;0;L;;;;;N;;;13AE;;13AE +AB7F;CHEROKEE SMALL LETTER HI;Ll;0;L;;;;;N;;;13AF;;13AF +AB80;CHEROKEE SMALL LETTER HO;Ll;0;L;;;;;N;;;13B0;;13B0 +AB81;CHEROKEE SMALL LETTER HU;Ll;0;L;;;;;N;;;13B1;;13B1 +AB82;CHEROKEE SMALL LETTER HV;Ll;0;L;;;;;N;;;13B2;;13B2 +AB83;CHEROKEE SMALL LETTER LA;Ll;0;L;;;;;N;;;13B3;;13B3 +AB84;CHEROKEE SMALL LETTER LE;Ll;0;L;;;;;N;;;13B4;;13B4 +AB85;CHEROKEE SMALL LETTER LI;Ll;0;L;;;;;N;;;13B5;;13B5 +AB86;CHEROKEE SMALL LETTER LO;Ll;0;L;;;;;N;;;13B6;;13B6 +AB87;CHEROKEE SMALL LETTER LU;Ll;0;L;;;;;N;;;13B7;;13B7 +AB88;CHEROKEE SMALL LETTER LV;Ll;0;L;;;;;N;;;13B8;;13B8 +AB89;CHEROKEE SMALL LETTER MA;Ll;0;L;;;;;N;;;13B9;;13B9 +AB8A;CHEROKEE SMALL LETTER ME;Ll;0;L;;;;;N;;;13BA;;13BA +AB8B;CHEROKEE SMALL LETTER MI;Ll;0;L;;;;;N;;;13BB;;13BB +AB8C;CHEROKEE SMALL LETTER MO;Ll;0;L;;;;;N;;;13BC;;13BC +AB8D;CHEROKEE SMALL LETTER MU;Ll;0;L;;;;;N;;;13BD;;13BD +AB8E;CHEROKEE SMALL LETTER NA;Ll;0;L;;;;;N;;;13BE;;13BE +AB8F;CHEROKEE SMALL LETTER HNA;Ll;0;L;;;;;N;;;13BF;;13BF +AB90;CHEROKEE SMALL LETTER NAH;Ll;0;L;;;;;N;;;13C0;;13C0 +AB91;CHEROKEE SMALL LETTER NE;Ll;0;L;;;;;N;;;13C1;;13C1 +AB92;CHEROKEE SMALL LETTER NI;Ll;0;L;;;;;N;;;13C2;;13C2 +AB93;CHEROKEE SMALL LETTER NO;Ll;0;L;;;;;N;;;13C3;;13C3 +AB94;CHEROKEE SMALL LETTER NU;Ll;0;L;;;;;N;;;13C4;;13C4 +AB95;CHEROKEE SMALL LETTER NV;Ll;0;L;;;;;N;;;13C5;;13C5 +AB96;CHEROKEE SMALL LETTER QUA;Ll;0;L;;;;;N;;;13C6;;13C6 +AB97;CHEROKEE SMALL LETTER QUE;Ll;0;L;;;;;N;;;13C7;;13C7 +AB98;CHEROKEE SMALL LETTER QUI;Ll;0;L;;;;;N;;;13C8;;13C8 +AB99;CHEROKEE SMALL LETTER QUO;Ll;0;L;;;;;N;;;13C9;;13C9 +AB9A;CHEROKEE SMALL LETTER QUU;Ll;0;L;;;;;N;;;13CA;;13CA +AB9B;CHEROKEE SMALL LETTER QUV;Ll;0;L;;;;;N;;;13CB;;13CB +AB9C;CHEROKEE SMALL LETTER SA;Ll;0;L;;;;;N;;;13CC;;13CC +AB9D;CHEROKEE SMALL LETTER S;Ll;0;L;;;;;N;;;13CD;;13CD +AB9E;CHEROKEE SMALL LETTER SE;Ll;0;L;;;;;N;;;13CE;;13CE +AB9F;CHEROKEE SMALL LETTER SI;Ll;0;L;;;;;N;;;13CF;;13CF +ABA0;CHEROKEE SMALL LETTER SO;Ll;0;L;;;;;N;;;13D0;;13D0 +ABA1;CHEROKEE SMALL LETTER SU;Ll;0;L;;;;;N;;;13D1;;13D1 +ABA2;CHEROKEE SMALL LETTER SV;Ll;0;L;;;;;N;;;13D2;;13D2 +ABA3;CHEROKEE SMALL LETTER DA;Ll;0;L;;;;;N;;;13D3;;13D3 +ABA4;CHEROKEE SMALL LETTER TA;Ll;0;L;;;;;N;;;13D4;;13D4 +ABA5;CHEROKEE SMALL LETTER DE;Ll;0;L;;;;;N;;;13D5;;13D5 +ABA6;CHEROKEE SMALL LETTER TE;Ll;0;L;;;;;N;;;13D6;;13D6 +ABA7;CHEROKEE SMALL LETTER DI;Ll;0;L;;;;;N;;;13D7;;13D7 +ABA8;CHEROKEE SMALL LETTER TI;Ll;0;L;;;;;N;;;13D8;;13D8 +ABA9;CHEROKEE SMALL LETTER DO;Ll;0;L;;;;;N;;;13D9;;13D9 +ABAA;CHEROKEE SMALL LETTER DU;Ll;0;L;;;;;N;;;13DA;;13DA +ABAB;CHEROKEE SMALL LETTER DV;Ll;0;L;;;;;N;;;13DB;;13DB +ABAC;CHEROKEE SMALL LETTER DLA;Ll;0;L;;;;;N;;;13DC;;13DC +ABAD;CHEROKEE SMALL LETTER TLA;Ll;0;L;;;;;N;;;13DD;;13DD +ABAE;CHEROKEE SMALL LETTER TLE;Ll;0;L;;;;;N;;;13DE;;13DE +ABAF;CHEROKEE SMALL LETTER TLI;Ll;0;L;;;;;N;;;13DF;;13DF +ABB0;CHEROKEE SMALL LETTER TLO;Ll;0;L;;;;;N;;;13E0;;13E0 +ABB1;CHEROKEE SMALL LETTER TLU;Ll;0;L;;;;;N;;;13E1;;13E1 +ABB2;CHEROKEE SMALL LETTER TLV;Ll;0;L;;;;;N;;;13E2;;13E2 +ABB3;CHEROKEE SMALL LETTER TSA;Ll;0;L;;;;;N;;;13E3;;13E3 +ABB4;CHEROKEE SMALL LETTER TSE;Ll;0;L;;;;;N;;;13E4;;13E4 +ABB5;CHEROKEE SMALL LETTER TSI;Ll;0;L;;;;;N;;;13E5;;13E5 +ABB6;CHEROKEE SMALL LETTER TSO;Ll;0;L;;;;;N;;;13E6;;13E6 +ABB7;CHEROKEE SMALL LETTER TSU;Ll;0;L;;;;;N;;;13E7;;13E7 +ABB8;CHEROKEE SMALL LETTER TSV;Ll;0;L;;;;;N;;;13E8;;13E8 +ABB9;CHEROKEE SMALL LETTER WA;Ll;0;L;;;;;N;;;13E9;;13E9 +ABBA;CHEROKEE SMALL LETTER WE;Ll;0;L;;;;;N;;;13EA;;13EA +ABBB;CHEROKEE SMALL LETTER WI;Ll;0;L;;;;;N;;;13EB;;13EB +ABBC;CHEROKEE SMALL LETTER WO;Ll;0;L;;;;;N;;;13EC;;13EC +ABBD;CHEROKEE SMALL LETTER WU;Ll;0;L;;;;;N;;;13ED;;13ED +ABBE;CHEROKEE SMALL LETTER WV;Ll;0;L;;;;;N;;;13EE;;13EE +ABBF;CHEROKEE SMALL LETTER YA;Ll;0;L;;;;;N;;;13EF;;13EF +ABC0;MEETEI MAYEK LETTER KOK;Lo;0;L;;;;;N;;;;; +ABC1;MEETEI MAYEK LETTER SAM;Lo;0;L;;;;;N;;;;; +ABC2;MEETEI MAYEK LETTER LAI;Lo;0;L;;;;;N;;;;; +ABC3;MEETEI MAYEK LETTER MIT;Lo;0;L;;;;;N;;;;; +ABC4;MEETEI MAYEK LETTER PA;Lo;0;L;;;;;N;;;;; +ABC5;MEETEI MAYEK LETTER NA;Lo;0;L;;;;;N;;;;; +ABC6;MEETEI MAYEK LETTER CHIL;Lo;0;L;;;;;N;;;;; +ABC7;MEETEI MAYEK LETTER TIL;Lo;0;L;;;;;N;;;;; +ABC8;MEETEI MAYEK LETTER KHOU;Lo;0;L;;;;;N;;;;; +ABC9;MEETEI MAYEK LETTER NGOU;Lo;0;L;;;;;N;;;;; +ABCA;MEETEI MAYEK LETTER THOU;Lo;0;L;;;;;N;;;;; +ABCB;MEETEI MAYEK LETTER WAI;Lo;0;L;;;;;N;;;;; +ABCC;MEETEI MAYEK LETTER YANG;Lo;0;L;;;;;N;;;;; +ABCD;MEETEI MAYEK LETTER HUK;Lo;0;L;;;;;N;;;;; +ABCE;MEETEI MAYEK LETTER UN;Lo;0;L;;;;;N;;;;; +ABCF;MEETEI MAYEK LETTER I;Lo;0;L;;;;;N;;;;; +ABD0;MEETEI MAYEK LETTER PHAM;Lo;0;L;;;;;N;;;;; +ABD1;MEETEI MAYEK LETTER ATIYA;Lo;0;L;;;;;N;;;;; +ABD2;MEETEI MAYEK LETTER GOK;Lo;0;L;;;;;N;;;;; +ABD3;MEETEI MAYEK LETTER JHAM;Lo;0;L;;;;;N;;;;; +ABD4;MEETEI MAYEK LETTER RAI;Lo;0;L;;;;;N;;;;; +ABD5;MEETEI MAYEK LETTER BA;Lo;0;L;;;;;N;;;;; +ABD6;MEETEI MAYEK LETTER JIL;Lo;0;L;;;;;N;;;;; +ABD7;MEETEI MAYEK LETTER DIL;Lo;0;L;;;;;N;;;;; +ABD8;MEETEI MAYEK LETTER GHOU;Lo;0;L;;;;;N;;;;; +ABD9;MEETEI MAYEK LETTER DHOU;Lo;0;L;;;;;N;;;;; +ABDA;MEETEI MAYEK LETTER BHAM;Lo;0;L;;;;;N;;;;; +ABDB;MEETEI MAYEK LETTER KOK LONSUM;Lo;0;L;;;;;N;;;;; +ABDC;MEETEI MAYEK LETTER LAI LONSUM;Lo;0;L;;;;;N;;;;; +ABDD;MEETEI MAYEK LETTER MIT LONSUM;Lo;0;L;;;;;N;;;;; +ABDE;MEETEI MAYEK LETTER PA LONSUM;Lo;0;L;;;;;N;;;;; +ABDF;MEETEI MAYEK LETTER NA LONSUM;Lo;0;L;;;;;N;;;;; +ABE0;MEETEI MAYEK LETTER TIL LONSUM;Lo;0;L;;;;;N;;;;; +ABE1;MEETEI MAYEK LETTER NGOU LONSUM;Lo;0;L;;;;;N;;;;; +ABE2;MEETEI MAYEK LETTER I LONSUM;Lo;0;L;;;;;N;;;;; +ABE3;MEETEI MAYEK VOWEL SIGN ONAP;Mc;0;L;;;;;N;;;;; +ABE4;MEETEI MAYEK VOWEL SIGN INAP;Mc;0;L;;;;;N;;;;; +ABE5;MEETEI MAYEK VOWEL SIGN ANAP;Mn;0;NSM;;;;;N;;;;; +ABE6;MEETEI MAYEK VOWEL SIGN YENAP;Mc;0;L;;;;;N;;;;; +ABE7;MEETEI MAYEK VOWEL SIGN SOUNAP;Mc;0;L;;;;;N;;;;; +ABE8;MEETEI MAYEK VOWEL SIGN UNAP;Mn;0;NSM;;;;;N;;;;; +ABE9;MEETEI MAYEK VOWEL SIGN CHEINAP;Mc;0;L;;;;;N;;;;; +ABEA;MEETEI MAYEK VOWEL SIGN NUNG;Mc;0;L;;;;;N;;;;; +ABEB;MEETEI MAYEK CHEIKHEI;Po;0;L;;;;;N;;;;; +ABEC;MEETEI MAYEK LUM IYEK;Mc;0;L;;;;;N;;;;; +ABED;MEETEI MAYEK APUN IYEK;Mn;9;NSM;;;;;N;;;;; +ABF0;MEETEI MAYEK DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +ABF1;MEETEI MAYEK DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +ABF2;MEETEI MAYEK DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +ABF3;MEETEI MAYEK DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +ABF4;MEETEI MAYEK DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +ABF5;MEETEI MAYEK DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +ABF6;MEETEI MAYEK DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +ABF7;MEETEI MAYEK DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +ABF8;MEETEI MAYEK DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +ABF9;MEETEI MAYEK DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +AC00;;Lo;0;L;;;;;N;;;;; +D7A3;;Lo;0;L;;;;;N;;;;; +D7B0;HANGUL JUNGSEONG O-YEO;Lo;0;L;;;;;N;;;;; +D7B1;HANGUL JUNGSEONG O-O-I;Lo;0;L;;;;;N;;;;; +D7B2;HANGUL JUNGSEONG YO-A;Lo;0;L;;;;;N;;;;; +D7B3;HANGUL JUNGSEONG YO-AE;Lo;0;L;;;;;N;;;;; +D7B4;HANGUL JUNGSEONG YO-EO;Lo;0;L;;;;;N;;;;; +D7B5;HANGUL JUNGSEONG U-YEO;Lo;0;L;;;;;N;;;;; +D7B6;HANGUL JUNGSEONG U-I-I;Lo;0;L;;;;;N;;;;; +D7B7;HANGUL JUNGSEONG YU-AE;Lo;0;L;;;;;N;;;;; +D7B8;HANGUL JUNGSEONG YU-O;Lo;0;L;;;;;N;;;;; +D7B9;HANGUL JUNGSEONG EU-A;Lo;0;L;;;;;N;;;;; +D7BA;HANGUL JUNGSEONG EU-EO;Lo;0;L;;;;;N;;;;; +D7BB;HANGUL JUNGSEONG EU-E;Lo;0;L;;;;;N;;;;; +D7BC;HANGUL JUNGSEONG EU-O;Lo;0;L;;;;;N;;;;; +D7BD;HANGUL JUNGSEONG I-YA-O;Lo;0;L;;;;;N;;;;; +D7BE;HANGUL JUNGSEONG I-YAE;Lo;0;L;;;;;N;;;;; +D7BF;HANGUL JUNGSEONG I-YEO;Lo;0;L;;;;;N;;;;; +D7C0;HANGUL JUNGSEONG I-YE;Lo;0;L;;;;;N;;;;; +D7C1;HANGUL JUNGSEONG I-O-I;Lo;0;L;;;;;N;;;;; +D7C2;HANGUL JUNGSEONG I-YO;Lo;0;L;;;;;N;;;;; +D7C3;HANGUL JUNGSEONG I-YU;Lo;0;L;;;;;N;;;;; +D7C4;HANGUL JUNGSEONG I-I;Lo;0;L;;;;;N;;;;; +D7C5;HANGUL JUNGSEONG ARAEA-A;Lo;0;L;;;;;N;;;;; +D7C6;HANGUL JUNGSEONG ARAEA-E;Lo;0;L;;;;;N;;;;; +D7CB;HANGUL JONGSEONG NIEUN-RIEUL;Lo;0;L;;;;;N;;;;; +D7CC;HANGUL JONGSEONG NIEUN-CHIEUCH;Lo;0;L;;;;;N;;;;; +D7CD;HANGUL JONGSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;;;; +D7CE;HANGUL JONGSEONG SSANGTIKEUT-PIEUP;Lo;0;L;;;;;N;;;;; +D7CF;HANGUL JONGSEONG TIKEUT-PIEUP;Lo;0;L;;;;;N;;;;; +D7D0;HANGUL JONGSEONG TIKEUT-SIOS;Lo;0;L;;;;;N;;;;; +D7D1;HANGUL JONGSEONG TIKEUT-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +D7D2;HANGUL JONGSEONG TIKEUT-CIEUC;Lo;0;L;;;;;N;;;;; +D7D3;HANGUL JONGSEONG TIKEUT-CHIEUCH;Lo;0;L;;;;;N;;;;; +D7D4;HANGUL JONGSEONG TIKEUT-THIEUTH;Lo;0;L;;;;;N;;;;; +D7D5;HANGUL JONGSEONG RIEUL-SSANGKIYEOK;Lo;0;L;;;;;N;;;;; +D7D6;HANGUL JONGSEONG RIEUL-KIYEOK-HIEUH;Lo;0;L;;;;;N;;;;; +D7D7;HANGUL JONGSEONG SSANGRIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;; +D7D8;HANGUL JONGSEONG RIEUL-MIEUM-HIEUH;Lo;0;L;;;;;N;;;;; +D7D9;HANGUL JONGSEONG RIEUL-PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;; +D7DA;HANGUL JONGSEONG RIEUL-PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;; +D7DB;HANGUL JONGSEONG RIEUL-YESIEUNG;Lo;0;L;;;;;N;;;;; +D7DC;HANGUL JONGSEONG RIEUL-YEORINHIEUH-HIEUH;Lo;0;L;;;;;N;;;;; +D7DD;HANGUL JONGSEONG KAPYEOUNRIEUL;Lo;0;L;;;;;N;;;;; +D7DE;HANGUL JONGSEONG MIEUM-NIEUN;Lo;0;L;;;;;N;;;;; +D7DF;HANGUL JONGSEONG MIEUM-SSANGNIEUN;Lo;0;L;;;;;N;;;;; +D7E0;HANGUL JONGSEONG SSANGMIEUM;Lo;0;L;;;;;N;;;;; +D7E1;HANGUL JONGSEONG MIEUM-PIEUP-SIOS;Lo;0;L;;;;;N;;;;; +D7E2;HANGUL JONGSEONG MIEUM-CIEUC;Lo;0;L;;;;;N;;;;; +D7E3;HANGUL JONGSEONG PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;; +D7E4;HANGUL JONGSEONG PIEUP-RIEUL-PHIEUPH;Lo;0;L;;;;;N;;;;; +D7E5;HANGUL JONGSEONG PIEUP-MIEUM;Lo;0;L;;;;;N;;;;; +D7E6;HANGUL JONGSEONG SSANGPIEUP;Lo;0;L;;;;;N;;;;; +D7E7;HANGUL JONGSEONG PIEUP-SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +D7E8;HANGUL JONGSEONG PIEUP-CIEUC;Lo;0;L;;;;;N;;;;; +D7E9;HANGUL JONGSEONG PIEUP-CHIEUCH;Lo;0;L;;;;;N;;;;; +D7EA;HANGUL JONGSEONG SIOS-MIEUM;Lo;0;L;;;;;N;;;;; +D7EB;HANGUL JONGSEONG SIOS-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +D7EC;HANGUL JONGSEONG SSANGSIOS-KIYEOK;Lo;0;L;;;;;N;;;;; +D7ED;HANGUL JONGSEONG SSANGSIOS-TIKEUT;Lo;0;L;;;;;N;;;;; +D7EE;HANGUL JONGSEONG SIOS-PANSIOS;Lo;0;L;;;;;N;;;;; +D7EF;HANGUL JONGSEONG SIOS-CIEUC;Lo;0;L;;;;;N;;;;; +D7F0;HANGUL JONGSEONG SIOS-CHIEUCH;Lo;0;L;;;;;N;;;;; +D7F1;HANGUL JONGSEONG SIOS-THIEUTH;Lo;0;L;;;;;N;;;;; +D7F2;HANGUL JONGSEONG SIOS-HIEUH;Lo;0;L;;;;;N;;;;; +D7F3;HANGUL JONGSEONG PANSIOS-PIEUP;Lo;0;L;;;;;N;;;;; +D7F4;HANGUL JONGSEONG PANSIOS-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; +D7F5;HANGUL JONGSEONG YESIEUNG-MIEUM;Lo;0;L;;;;;N;;;;; +D7F6;HANGUL JONGSEONG YESIEUNG-HIEUH;Lo;0;L;;;;;N;;;;; +D7F7;HANGUL JONGSEONG CIEUC-PIEUP;Lo;0;L;;;;;N;;;;; +D7F8;HANGUL JONGSEONG CIEUC-SSANGPIEUP;Lo;0;L;;;;;N;;;;; +D7F9;HANGUL JONGSEONG SSANGCIEUC;Lo;0;L;;;;;N;;;;; +D7FA;HANGUL JONGSEONG PHIEUPH-SIOS;Lo;0;L;;;;;N;;;;; +D7FB;HANGUL JONGSEONG PHIEUPH-THIEUTH;Lo;0;L;;;;;N;;;;; +D800;;Cs;0;L;;;;;N;;;;; +DB7F;;Cs;0;L;;;;;N;;;;; +DB80;;Cs;0;L;;;;;N;;;;; +DBFF;;Cs;0;L;;;;;N;;;;; +DC00;;Cs;0;L;;;;;N;;;;; +DFFF;;Cs;0;L;;;;;N;;;;; +E000;;Co;0;L;;;;;N;;;;; +F8FF;;Co;0;L;;;;;N;;;;; +F900;CJK COMPATIBILITY IDEOGRAPH-F900;Lo;0;L;8C48;;;;N;;;;; +F901;CJK COMPATIBILITY IDEOGRAPH-F901;Lo;0;L;66F4;;;;N;;;;; +F902;CJK COMPATIBILITY IDEOGRAPH-F902;Lo;0;L;8ECA;;;;N;;;;; +F903;CJK COMPATIBILITY IDEOGRAPH-F903;Lo;0;L;8CC8;;;;N;;;;; +F904;CJK COMPATIBILITY IDEOGRAPH-F904;Lo;0;L;6ED1;;;;N;;;;; +F905;CJK COMPATIBILITY IDEOGRAPH-F905;Lo;0;L;4E32;;;;N;;;;; +F906;CJK COMPATIBILITY IDEOGRAPH-F906;Lo;0;L;53E5;;;;N;;;;; +F907;CJK COMPATIBILITY IDEOGRAPH-F907;Lo;0;L;9F9C;;;;N;;;;; +F908;CJK COMPATIBILITY IDEOGRAPH-F908;Lo;0;L;9F9C;;;;N;;;;; +F909;CJK COMPATIBILITY IDEOGRAPH-F909;Lo;0;L;5951;;;;N;;;;; +F90A;CJK COMPATIBILITY IDEOGRAPH-F90A;Lo;0;L;91D1;;;;N;;;;; +F90B;CJK COMPATIBILITY IDEOGRAPH-F90B;Lo;0;L;5587;;;;N;;;;; +F90C;CJK COMPATIBILITY IDEOGRAPH-F90C;Lo;0;L;5948;;;;N;;;;; +F90D;CJK COMPATIBILITY IDEOGRAPH-F90D;Lo;0;L;61F6;;;;N;;;;; +F90E;CJK COMPATIBILITY IDEOGRAPH-F90E;Lo;0;L;7669;;;;N;;;;; +F90F;CJK COMPATIBILITY IDEOGRAPH-F90F;Lo;0;L;7F85;;;;N;;;;; +F910;CJK COMPATIBILITY IDEOGRAPH-F910;Lo;0;L;863F;;;;N;;;;; +F911;CJK COMPATIBILITY IDEOGRAPH-F911;Lo;0;L;87BA;;;;N;;;;; +F912;CJK COMPATIBILITY IDEOGRAPH-F912;Lo;0;L;88F8;;;;N;;;;; +F913;CJK COMPATIBILITY IDEOGRAPH-F913;Lo;0;L;908F;;;;N;;;;; +F914;CJK COMPATIBILITY IDEOGRAPH-F914;Lo;0;L;6A02;;;;N;;;;; +F915;CJK COMPATIBILITY IDEOGRAPH-F915;Lo;0;L;6D1B;;;;N;;;;; +F916;CJK COMPATIBILITY IDEOGRAPH-F916;Lo;0;L;70D9;;;;N;;;;; +F917;CJK COMPATIBILITY IDEOGRAPH-F917;Lo;0;L;73DE;;;;N;;;;; +F918;CJK COMPATIBILITY IDEOGRAPH-F918;Lo;0;L;843D;;;;N;;;;; +F919;CJK COMPATIBILITY IDEOGRAPH-F919;Lo;0;L;916A;;;;N;;;;; +F91A;CJK COMPATIBILITY IDEOGRAPH-F91A;Lo;0;L;99F1;;;;N;;;;; +F91B;CJK COMPATIBILITY IDEOGRAPH-F91B;Lo;0;L;4E82;;;;N;;;;; +F91C;CJK COMPATIBILITY IDEOGRAPH-F91C;Lo;0;L;5375;;;;N;;;;; +F91D;CJK COMPATIBILITY IDEOGRAPH-F91D;Lo;0;L;6B04;;;;N;;;;; +F91E;CJK COMPATIBILITY IDEOGRAPH-F91E;Lo;0;L;721B;;;;N;;;;; +F91F;CJK COMPATIBILITY IDEOGRAPH-F91F;Lo;0;L;862D;;;;N;;;;; +F920;CJK COMPATIBILITY IDEOGRAPH-F920;Lo;0;L;9E1E;;;;N;;;;; +F921;CJK COMPATIBILITY IDEOGRAPH-F921;Lo;0;L;5D50;;;;N;;;;; +F922;CJK COMPATIBILITY IDEOGRAPH-F922;Lo;0;L;6FEB;;;;N;;;;; +F923;CJK COMPATIBILITY IDEOGRAPH-F923;Lo;0;L;85CD;;;;N;;;;; +F924;CJK COMPATIBILITY IDEOGRAPH-F924;Lo;0;L;8964;;;;N;;;;; +F925;CJK COMPATIBILITY IDEOGRAPH-F925;Lo;0;L;62C9;;;;N;;;;; +F926;CJK COMPATIBILITY IDEOGRAPH-F926;Lo;0;L;81D8;;;;N;;;;; +F927;CJK COMPATIBILITY IDEOGRAPH-F927;Lo;0;L;881F;;;;N;;;;; +F928;CJK COMPATIBILITY IDEOGRAPH-F928;Lo;0;L;5ECA;;;;N;;;;; +F929;CJK COMPATIBILITY IDEOGRAPH-F929;Lo;0;L;6717;;;;N;;;;; +F92A;CJK COMPATIBILITY IDEOGRAPH-F92A;Lo;0;L;6D6A;;;;N;;;;; +F92B;CJK COMPATIBILITY IDEOGRAPH-F92B;Lo;0;L;72FC;;;;N;;;;; +F92C;CJK COMPATIBILITY IDEOGRAPH-F92C;Lo;0;L;90CE;;;;N;;;;; +F92D;CJK COMPATIBILITY IDEOGRAPH-F92D;Lo;0;L;4F86;;;;N;;;;; +F92E;CJK COMPATIBILITY IDEOGRAPH-F92E;Lo;0;L;51B7;;;;N;;;;; +F92F;CJK COMPATIBILITY IDEOGRAPH-F92F;Lo;0;L;52DE;;;;N;;;;; +F930;CJK COMPATIBILITY IDEOGRAPH-F930;Lo;0;L;64C4;;;;N;;;;; +F931;CJK COMPATIBILITY IDEOGRAPH-F931;Lo;0;L;6AD3;;;;N;;;;; +F932;CJK COMPATIBILITY IDEOGRAPH-F932;Lo;0;L;7210;;;;N;;;;; +F933;CJK COMPATIBILITY IDEOGRAPH-F933;Lo;0;L;76E7;;;;N;;;;; +F934;CJK COMPATIBILITY IDEOGRAPH-F934;Lo;0;L;8001;;;;N;;;;; +F935;CJK COMPATIBILITY IDEOGRAPH-F935;Lo;0;L;8606;;;;N;;;;; +F936;CJK COMPATIBILITY IDEOGRAPH-F936;Lo;0;L;865C;;;;N;;;;; +F937;CJK COMPATIBILITY IDEOGRAPH-F937;Lo;0;L;8DEF;;;;N;;;;; +F938;CJK COMPATIBILITY IDEOGRAPH-F938;Lo;0;L;9732;;;;N;;;;; +F939;CJK COMPATIBILITY IDEOGRAPH-F939;Lo;0;L;9B6F;;;;N;;;;; +F93A;CJK COMPATIBILITY IDEOGRAPH-F93A;Lo;0;L;9DFA;;;;N;;;;; +F93B;CJK COMPATIBILITY IDEOGRAPH-F93B;Lo;0;L;788C;;;;N;;;;; +F93C;CJK COMPATIBILITY IDEOGRAPH-F93C;Lo;0;L;797F;;;;N;;;;; +F93D;CJK COMPATIBILITY IDEOGRAPH-F93D;Lo;0;L;7DA0;;;;N;;;;; +F93E;CJK COMPATIBILITY IDEOGRAPH-F93E;Lo;0;L;83C9;;;;N;;;;; +F93F;CJK COMPATIBILITY IDEOGRAPH-F93F;Lo;0;L;9304;;;;N;;;;; +F940;CJK COMPATIBILITY IDEOGRAPH-F940;Lo;0;L;9E7F;;;;N;;;;; +F941;CJK COMPATIBILITY IDEOGRAPH-F941;Lo;0;L;8AD6;;;;N;;;;; +F942;CJK COMPATIBILITY IDEOGRAPH-F942;Lo;0;L;58DF;;;;N;;;;; +F943;CJK COMPATIBILITY IDEOGRAPH-F943;Lo;0;L;5F04;;;;N;;;;; +F944;CJK COMPATIBILITY IDEOGRAPH-F944;Lo;0;L;7C60;;;;N;;;;; +F945;CJK COMPATIBILITY IDEOGRAPH-F945;Lo;0;L;807E;;;;N;;;;; +F946;CJK COMPATIBILITY IDEOGRAPH-F946;Lo;0;L;7262;;;;N;;;;; +F947;CJK COMPATIBILITY IDEOGRAPH-F947;Lo;0;L;78CA;;;;N;;;;; +F948;CJK COMPATIBILITY IDEOGRAPH-F948;Lo;0;L;8CC2;;;;N;;;;; +F949;CJK COMPATIBILITY IDEOGRAPH-F949;Lo;0;L;96F7;;;;N;;;;; +F94A;CJK COMPATIBILITY IDEOGRAPH-F94A;Lo;0;L;58D8;;;;N;;;;; +F94B;CJK COMPATIBILITY IDEOGRAPH-F94B;Lo;0;L;5C62;;;;N;;;;; +F94C;CJK COMPATIBILITY IDEOGRAPH-F94C;Lo;0;L;6A13;;;;N;;;;; +F94D;CJK COMPATIBILITY IDEOGRAPH-F94D;Lo;0;L;6DDA;;;;N;;;;; +F94E;CJK COMPATIBILITY IDEOGRAPH-F94E;Lo;0;L;6F0F;;;;N;;;;; +F94F;CJK COMPATIBILITY IDEOGRAPH-F94F;Lo;0;L;7D2F;;;;N;;;;; +F950;CJK COMPATIBILITY IDEOGRAPH-F950;Lo;0;L;7E37;;;;N;;;;; +F951;CJK COMPATIBILITY IDEOGRAPH-F951;Lo;0;L;964B;;;;N;;;;; +F952;CJK COMPATIBILITY IDEOGRAPH-F952;Lo;0;L;52D2;;;;N;;;;; +F953;CJK COMPATIBILITY IDEOGRAPH-F953;Lo;0;L;808B;;;;N;;;;; +F954;CJK COMPATIBILITY IDEOGRAPH-F954;Lo;0;L;51DC;;;;N;;;;; +F955;CJK COMPATIBILITY IDEOGRAPH-F955;Lo;0;L;51CC;;;;N;;;;; +F956;CJK COMPATIBILITY IDEOGRAPH-F956;Lo;0;L;7A1C;;;;N;;;;; +F957;CJK COMPATIBILITY IDEOGRAPH-F957;Lo;0;L;7DBE;;;;N;;;;; +F958;CJK COMPATIBILITY IDEOGRAPH-F958;Lo;0;L;83F1;;;;N;;;;; +F959;CJK COMPATIBILITY IDEOGRAPH-F959;Lo;0;L;9675;;;;N;;;;; +F95A;CJK COMPATIBILITY IDEOGRAPH-F95A;Lo;0;L;8B80;;;;N;;;;; +F95B;CJK COMPATIBILITY IDEOGRAPH-F95B;Lo;0;L;62CF;;;;N;;;;; +F95C;CJK COMPATIBILITY IDEOGRAPH-F95C;Lo;0;L;6A02;;;;N;;;;; +F95D;CJK COMPATIBILITY IDEOGRAPH-F95D;Lo;0;L;8AFE;;;;N;;;;; +F95E;CJK COMPATIBILITY IDEOGRAPH-F95E;Lo;0;L;4E39;;;;N;;;;; +F95F;CJK COMPATIBILITY IDEOGRAPH-F95F;Lo;0;L;5BE7;;;;N;;;;; +F960;CJK COMPATIBILITY IDEOGRAPH-F960;Lo;0;L;6012;;;;N;;;;; +F961;CJK COMPATIBILITY IDEOGRAPH-F961;Lo;0;L;7387;;;;N;;;;; +F962;CJK COMPATIBILITY IDEOGRAPH-F962;Lo;0;L;7570;;;;N;;;;; +F963;CJK COMPATIBILITY IDEOGRAPH-F963;Lo;0;L;5317;;;;N;;;;; +F964;CJK COMPATIBILITY IDEOGRAPH-F964;Lo;0;L;78FB;;;;N;;;;; +F965;CJK COMPATIBILITY IDEOGRAPH-F965;Lo;0;L;4FBF;;;;N;;;;; +F966;CJK COMPATIBILITY IDEOGRAPH-F966;Lo;0;L;5FA9;;;;N;;;;; +F967;CJK COMPATIBILITY IDEOGRAPH-F967;Lo;0;L;4E0D;;;;N;;;;; +F968;CJK COMPATIBILITY IDEOGRAPH-F968;Lo;0;L;6CCC;;;;N;;;;; +F969;CJK COMPATIBILITY IDEOGRAPH-F969;Lo;0;L;6578;;;;N;;;;; +F96A;CJK COMPATIBILITY IDEOGRAPH-F96A;Lo;0;L;7D22;;;;N;;;;; +F96B;CJK COMPATIBILITY IDEOGRAPH-F96B;Lo;0;L;53C3;;;3;N;;;;; +F96C;CJK COMPATIBILITY IDEOGRAPH-F96C;Lo;0;L;585E;;;;N;;;;; +F96D;CJK COMPATIBILITY IDEOGRAPH-F96D;Lo;0;L;7701;;;;N;;;;; +F96E;CJK COMPATIBILITY IDEOGRAPH-F96E;Lo;0;L;8449;;;;N;;;;; +F96F;CJK COMPATIBILITY IDEOGRAPH-F96F;Lo;0;L;8AAA;;;;N;;;;; +F970;CJK COMPATIBILITY IDEOGRAPH-F970;Lo;0;L;6BBA;;;;N;;;;; +F971;CJK COMPATIBILITY IDEOGRAPH-F971;Lo;0;L;8FB0;;;;N;;;;; +F972;CJK COMPATIBILITY IDEOGRAPH-F972;Lo;0;L;6C88;;;;N;;;;; +F973;CJK COMPATIBILITY IDEOGRAPH-F973;Lo;0;L;62FE;;;10;N;;;;; +F974;CJK COMPATIBILITY IDEOGRAPH-F974;Lo;0;L;82E5;;;;N;;;;; +F975;CJK COMPATIBILITY IDEOGRAPH-F975;Lo;0;L;63A0;;;;N;;;;; +F976;CJK COMPATIBILITY IDEOGRAPH-F976;Lo;0;L;7565;;;;N;;;;; +F977;CJK COMPATIBILITY IDEOGRAPH-F977;Lo;0;L;4EAE;;;;N;;;;; +F978;CJK COMPATIBILITY IDEOGRAPH-F978;Lo;0;L;5169;;;2;N;;;;; +F979;CJK COMPATIBILITY IDEOGRAPH-F979;Lo;0;L;51C9;;;;N;;;;; +F97A;CJK COMPATIBILITY IDEOGRAPH-F97A;Lo;0;L;6881;;;;N;;;;; +F97B;CJK COMPATIBILITY IDEOGRAPH-F97B;Lo;0;L;7CE7;;;;N;;;;; +F97C;CJK COMPATIBILITY IDEOGRAPH-F97C;Lo;0;L;826F;;;;N;;;;; +F97D;CJK COMPATIBILITY IDEOGRAPH-F97D;Lo;0;L;8AD2;;;;N;;;;; +F97E;CJK COMPATIBILITY IDEOGRAPH-F97E;Lo;0;L;91CF;;;;N;;;;; +F97F;CJK COMPATIBILITY IDEOGRAPH-F97F;Lo;0;L;52F5;;;;N;;;;; +F980;CJK COMPATIBILITY IDEOGRAPH-F980;Lo;0;L;5442;;;;N;;;;; +F981;CJK COMPATIBILITY IDEOGRAPH-F981;Lo;0;L;5973;;;;N;;;;; +F982;CJK COMPATIBILITY IDEOGRAPH-F982;Lo;0;L;5EEC;;;;N;;;;; +F983;CJK COMPATIBILITY IDEOGRAPH-F983;Lo;0;L;65C5;;;;N;;;;; +F984;CJK COMPATIBILITY IDEOGRAPH-F984;Lo;0;L;6FFE;;;;N;;;;; +F985;CJK COMPATIBILITY IDEOGRAPH-F985;Lo;0;L;792A;;;;N;;;;; +F986;CJK COMPATIBILITY IDEOGRAPH-F986;Lo;0;L;95AD;;;;N;;;;; +F987;CJK COMPATIBILITY IDEOGRAPH-F987;Lo;0;L;9A6A;;;;N;;;;; +F988;CJK COMPATIBILITY IDEOGRAPH-F988;Lo;0;L;9E97;;;;N;;;;; +F989;CJK COMPATIBILITY IDEOGRAPH-F989;Lo;0;L;9ECE;;;;N;;;;; +F98A;CJK COMPATIBILITY IDEOGRAPH-F98A;Lo;0;L;529B;;;;N;;;;; +F98B;CJK COMPATIBILITY IDEOGRAPH-F98B;Lo;0;L;66C6;;;;N;;;;; +F98C;CJK COMPATIBILITY IDEOGRAPH-F98C;Lo;0;L;6B77;;;;N;;;;; +F98D;CJK COMPATIBILITY IDEOGRAPH-F98D;Lo;0;L;8F62;;;;N;;;;; +F98E;CJK COMPATIBILITY IDEOGRAPH-F98E;Lo;0;L;5E74;;;;N;;;;; +F98F;CJK COMPATIBILITY IDEOGRAPH-F98F;Lo;0;L;6190;;;;N;;;;; +F990;CJK COMPATIBILITY IDEOGRAPH-F990;Lo;0;L;6200;;;;N;;;;; +F991;CJK COMPATIBILITY IDEOGRAPH-F991;Lo;0;L;649A;;;;N;;;;; +F992;CJK COMPATIBILITY IDEOGRAPH-F992;Lo;0;L;6F23;;;;N;;;;; +F993;CJK COMPATIBILITY IDEOGRAPH-F993;Lo;0;L;7149;;;;N;;;;; +F994;CJK COMPATIBILITY IDEOGRAPH-F994;Lo;0;L;7489;;;;N;;;;; +F995;CJK COMPATIBILITY IDEOGRAPH-F995;Lo;0;L;79CA;;;;N;;;;; +F996;CJK COMPATIBILITY IDEOGRAPH-F996;Lo;0;L;7DF4;;;;N;;;;; +F997;CJK COMPATIBILITY IDEOGRAPH-F997;Lo;0;L;806F;;;;N;;;;; +F998;CJK COMPATIBILITY IDEOGRAPH-F998;Lo;0;L;8F26;;;;N;;;;; +F999;CJK COMPATIBILITY IDEOGRAPH-F999;Lo;0;L;84EE;;;;N;;;;; +F99A;CJK COMPATIBILITY IDEOGRAPH-F99A;Lo;0;L;9023;;;;N;;;;; +F99B;CJK COMPATIBILITY IDEOGRAPH-F99B;Lo;0;L;934A;;;;N;;;;; +F99C;CJK COMPATIBILITY IDEOGRAPH-F99C;Lo;0;L;5217;;;;N;;;;; +F99D;CJK COMPATIBILITY IDEOGRAPH-F99D;Lo;0;L;52A3;;;;N;;;;; +F99E;CJK COMPATIBILITY IDEOGRAPH-F99E;Lo;0;L;54BD;;;;N;;;;; +F99F;CJK COMPATIBILITY IDEOGRAPH-F99F;Lo;0;L;70C8;;;;N;;;;; +F9A0;CJK COMPATIBILITY IDEOGRAPH-F9A0;Lo;0;L;88C2;;;;N;;;;; +F9A1;CJK COMPATIBILITY IDEOGRAPH-F9A1;Lo;0;L;8AAA;;;;N;;;;; +F9A2;CJK COMPATIBILITY IDEOGRAPH-F9A2;Lo;0;L;5EC9;;;;N;;;;; +F9A3;CJK COMPATIBILITY IDEOGRAPH-F9A3;Lo;0;L;5FF5;;;;N;;;;; +F9A4;CJK COMPATIBILITY IDEOGRAPH-F9A4;Lo;0;L;637B;;;;N;;;;; +F9A5;CJK COMPATIBILITY IDEOGRAPH-F9A5;Lo;0;L;6BAE;;;;N;;;;; +F9A6;CJK COMPATIBILITY IDEOGRAPH-F9A6;Lo;0;L;7C3E;;;;N;;;;; +F9A7;CJK COMPATIBILITY IDEOGRAPH-F9A7;Lo;0;L;7375;;;;N;;;;; +F9A8;CJK COMPATIBILITY IDEOGRAPH-F9A8;Lo;0;L;4EE4;;;;N;;;;; +F9A9;CJK COMPATIBILITY IDEOGRAPH-F9A9;Lo;0;L;56F9;;;;N;;;;; +F9AA;CJK COMPATIBILITY IDEOGRAPH-F9AA;Lo;0;L;5BE7;;;;N;;;;; +F9AB;CJK COMPATIBILITY IDEOGRAPH-F9AB;Lo;0;L;5DBA;;;;N;;;;; +F9AC;CJK COMPATIBILITY IDEOGRAPH-F9AC;Lo;0;L;601C;;;;N;;;;; +F9AD;CJK COMPATIBILITY IDEOGRAPH-F9AD;Lo;0;L;73B2;;;;N;;;;; +F9AE;CJK COMPATIBILITY IDEOGRAPH-F9AE;Lo;0;L;7469;;;;N;;;;; +F9AF;CJK COMPATIBILITY IDEOGRAPH-F9AF;Lo;0;L;7F9A;;;;N;;;;; +F9B0;CJK COMPATIBILITY IDEOGRAPH-F9B0;Lo;0;L;8046;;;;N;;;;; +F9B1;CJK COMPATIBILITY IDEOGRAPH-F9B1;Lo;0;L;9234;;;;N;;;;; +F9B2;CJK COMPATIBILITY IDEOGRAPH-F9B2;Lo;0;L;96F6;;;0;N;;;;; +F9B3;CJK COMPATIBILITY IDEOGRAPH-F9B3;Lo;0;L;9748;;;;N;;;;; +F9B4;CJK COMPATIBILITY IDEOGRAPH-F9B4;Lo;0;L;9818;;;;N;;;;; +F9B5;CJK COMPATIBILITY IDEOGRAPH-F9B5;Lo;0;L;4F8B;;;;N;;;;; +F9B6;CJK COMPATIBILITY IDEOGRAPH-F9B6;Lo;0;L;79AE;;;;N;;;;; +F9B7;CJK COMPATIBILITY IDEOGRAPH-F9B7;Lo;0;L;91B4;;;;N;;;;; +F9B8;CJK COMPATIBILITY IDEOGRAPH-F9B8;Lo;0;L;96B8;;;;N;;;;; +F9B9;CJK COMPATIBILITY IDEOGRAPH-F9B9;Lo;0;L;60E1;;;;N;;;;; +F9BA;CJK COMPATIBILITY IDEOGRAPH-F9BA;Lo;0;L;4E86;;;;N;;;;; +F9BB;CJK COMPATIBILITY IDEOGRAPH-F9BB;Lo;0;L;50DA;;;;N;;;;; +F9BC;CJK COMPATIBILITY IDEOGRAPH-F9BC;Lo;0;L;5BEE;;;;N;;;;; +F9BD;CJK COMPATIBILITY IDEOGRAPH-F9BD;Lo;0;L;5C3F;;;;N;;;;; +F9BE;CJK COMPATIBILITY IDEOGRAPH-F9BE;Lo;0;L;6599;;;;N;;;;; +F9BF;CJK COMPATIBILITY IDEOGRAPH-F9BF;Lo;0;L;6A02;;;;N;;;;; +F9C0;CJK COMPATIBILITY IDEOGRAPH-F9C0;Lo;0;L;71CE;;;;N;;;;; +F9C1;CJK COMPATIBILITY IDEOGRAPH-F9C1;Lo;0;L;7642;;;;N;;;;; +F9C2;CJK COMPATIBILITY IDEOGRAPH-F9C2;Lo;0;L;84FC;;;;N;;;;; +F9C3;CJK COMPATIBILITY IDEOGRAPH-F9C3;Lo;0;L;907C;;;;N;;;;; +F9C4;CJK COMPATIBILITY IDEOGRAPH-F9C4;Lo;0;L;9F8D;;;;N;;;;; +F9C5;CJK COMPATIBILITY IDEOGRAPH-F9C5;Lo;0;L;6688;;;;N;;;;; +F9C6;CJK COMPATIBILITY IDEOGRAPH-F9C6;Lo;0;L;962E;;;;N;;;;; +F9C7;CJK COMPATIBILITY IDEOGRAPH-F9C7;Lo;0;L;5289;;;;N;;;;; +F9C8;CJK COMPATIBILITY IDEOGRAPH-F9C8;Lo;0;L;677B;;;;N;;;;; +F9C9;CJK COMPATIBILITY IDEOGRAPH-F9C9;Lo;0;L;67F3;;;;N;;;;; +F9CA;CJK COMPATIBILITY IDEOGRAPH-F9CA;Lo;0;L;6D41;;;;N;;;;; +F9CB;CJK COMPATIBILITY IDEOGRAPH-F9CB;Lo;0;L;6E9C;;;;N;;;;; +F9CC;CJK COMPATIBILITY IDEOGRAPH-F9CC;Lo;0;L;7409;;;;N;;;;; +F9CD;CJK COMPATIBILITY IDEOGRAPH-F9CD;Lo;0;L;7559;;;;N;;;;; +F9CE;CJK COMPATIBILITY IDEOGRAPH-F9CE;Lo;0;L;786B;;;;N;;;;; +F9CF;CJK COMPATIBILITY IDEOGRAPH-F9CF;Lo;0;L;7D10;;;;N;;;;; +F9D0;CJK COMPATIBILITY IDEOGRAPH-F9D0;Lo;0;L;985E;;;;N;;;;; +F9D1;CJK COMPATIBILITY IDEOGRAPH-F9D1;Lo;0;L;516D;;;6;N;;;;; +F9D2;CJK COMPATIBILITY IDEOGRAPH-F9D2;Lo;0;L;622E;;;;N;;;;; +F9D3;CJK COMPATIBILITY IDEOGRAPH-F9D3;Lo;0;L;9678;;;6;N;;;;; +F9D4;CJK COMPATIBILITY IDEOGRAPH-F9D4;Lo;0;L;502B;;;;N;;;;; +F9D5;CJK COMPATIBILITY IDEOGRAPH-F9D5;Lo;0;L;5D19;;;;N;;;;; +F9D6;CJK COMPATIBILITY IDEOGRAPH-F9D6;Lo;0;L;6DEA;;;;N;;;;; +F9D7;CJK COMPATIBILITY IDEOGRAPH-F9D7;Lo;0;L;8F2A;;;;N;;;;; +F9D8;CJK COMPATIBILITY IDEOGRAPH-F9D8;Lo;0;L;5F8B;;;;N;;;;; +F9D9;CJK COMPATIBILITY IDEOGRAPH-F9D9;Lo;0;L;6144;;;;N;;;;; +F9DA;CJK COMPATIBILITY IDEOGRAPH-F9DA;Lo;0;L;6817;;;;N;;;;; +F9DB;CJK COMPATIBILITY IDEOGRAPH-F9DB;Lo;0;L;7387;;;;N;;;;; +F9DC;CJK COMPATIBILITY IDEOGRAPH-F9DC;Lo;0;L;9686;;;;N;;;;; +F9DD;CJK COMPATIBILITY IDEOGRAPH-F9DD;Lo;0;L;5229;;;;N;;;;; +F9DE;CJK COMPATIBILITY IDEOGRAPH-F9DE;Lo;0;L;540F;;;;N;;;;; +F9DF;CJK COMPATIBILITY IDEOGRAPH-F9DF;Lo;0;L;5C65;;;;N;;;;; +F9E0;CJK COMPATIBILITY IDEOGRAPH-F9E0;Lo;0;L;6613;;;;N;;;;; +F9E1;CJK COMPATIBILITY IDEOGRAPH-F9E1;Lo;0;L;674E;;;;N;;;;; +F9E2;CJK COMPATIBILITY IDEOGRAPH-F9E2;Lo;0;L;68A8;;;;N;;;;; +F9E3;CJK COMPATIBILITY IDEOGRAPH-F9E3;Lo;0;L;6CE5;;;;N;;;;; +F9E4;CJK COMPATIBILITY IDEOGRAPH-F9E4;Lo;0;L;7406;;;;N;;;;; +F9E5;CJK COMPATIBILITY IDEOGRAPH-F9E5;Lo;0;L;75E2;;;;N;;;;; +F9E6;CJK COMPATIBILITY IDEOGRAPH-F9E6;Lo;0;L;7F79;;;;N;;;;; +F9E7;CJK COMPATIBILITY IDEOGRAPH-F9E7;Lo;0;L;88CF;;;;N;;;;; +F9E8;CJK COMPATIBILITY IDEOGRAPH-F9E8;Lo;0;L;88E1;;;;N;;;;; +F9E9;CJK COMPATIBILITY IDEOGRAPH-F9E9;Lo;0;L;91CC;;;;N;;;;; +F9EA;CJK COMPATIBILITY IDEOGRAPH-F9EA;Lo;0;L;96E2;;;;N;;;;; +F9EB;CJK COMPATIBILITY IDEOGRAPH-F9EB;Lo;0;L;533F;;;;N;;;;; +F9EC;CJK COMPATIBILITY IDEOGRAPH-F9EC;Lo;0;L;6EBA;;;;N;;;;; +F9ED;CJK COMPATIBILITY IDEOGRAPH-F9ED;Lo;0;L;541D;;;;N;;;;; +F9EE;CJK COMPATIBILITY IDEOGRAPH-F9EE;Lo;0;L;71D0;;;;N;;;;; +F9EF;CJK COMPATIBILITY IDEOGRAPH-F9EF;Lo;0;L;7498;;;;N;;;;; +F9F0;CJK COMPATIBILITY IDEOGRAPH-F9F0;Lo;0;L;85FA;;;;N;;;;; +F9F1;CJK COMPATIBILITY IDEOGRAPH-F9F1;Lo;0;L;96A3;;;;N;;;;; +F9F2;CJK COMPATIBILITY IDEOGRAPH-F9F2;Lo;0;L;9C57;;;;N;;;;; +F9F3;CJK COMPATIBILITY IDEOGRAPH-F9F3;Lo;0;L;9E9F;;;;N;;;;; +F9F4;CJK COMPATIBILITY IDEOGRAPH-F9F4;Lo;0;L;6797;;;;N;;;;; +F9F5;CJK COMPATIBILITY IDEOGRAPH-F9F5;Lo;0;L;6DCB;;;;N;;;;; +F9F6;CJK COMPATIBILITY IDEOGRAPH-F9F6;Lo;0;L;81E8;;;;N;;;;; +F9F7;CJK COMPATIBILITY IDEOGRAPH-F9F7;Lo;0;L;7ACB;;;;N;;;;; +F9F8;CJK COMPATIBILITY IDEOGRAPH-F9F8;Lo;0;L;7B20;;;;N;;;;; +F9F9;CJK COMPATIBILITY IDEOGRAPH-F9F9;Lo;0;L;7C92;;;;N;;;;; +F9FA;CJK COMPATIBILITY IDEOGRAPH-F9FA;Lo;0;L;72C0;;;;N;;;;; +F9FB;CJK COMPATIBILITY IDEOGRAPH-F9FB;Lo;0;L;7099;;;;N;;;;; +F9FC;CJK COMPATIBILITY IDEOGRAPH-F9FC;Lo;0;L;8B58;;;;N;;;;; +F9FD;CJK COMPATIBILITY IDEOGRAPH-F9FD;Lo;0;L;4EC0;;;10;N;;;;; +F9FE;CJK COMPATIBILITY IDEOGRAPH-F9FE;Lo;0;L;8336;;;;N;;;;; +F9FF;CJK COMPATIBILITY IDEOGRAPH-F9FF;Lo;0;L;523A;;;;N;;;;; +FA00;CJK COMPATIBILITY IDEOGRAPH-FA00;Lo;0;L;5207;;;;N;;;;; +FA01;CJK COMPATIBILITY IDEOGRAPH-FA01;Lo;0;L;5EA6;;;;N;;;;; +FA02;CJK COMPATIBILITY IDEOGRAPH-FA02;Lo;0;L;62D3;;;;N;;;;; +FA03;CJK COMPATIBILITY IDEOGRAPH-FA03;Lo;0;L;7CD6;;;;N;;;;; +FA04;CJK COMPATIBILITY IDEOGRAPH-FA04;Lo;0;L;5B85;;;;N;;;;; +FA05;CJK COMPATIBILITY IDEOGRAPH-FA05;Lo;0;L;6D1E;;;;N;;;;; +FA06;CJK COMPATIBILITY IDEOGRAPH-FA06;Lo;0;L;66B4;;;;N;;;;; +FA07;CJK COMPATIBILITY IDEOGRAPH-FA07;Lo;0;L;8F3B;;;;N;;;;; +FA08;CJK COMPATIBILITY IDEOGRAPH-FA08;Lo;0;L;884C;;;;N;;;;; +FA09;CJK COMPATIBILITY IDEOGRAPH-FA09;Lo;0;L;964D;;;;N;;;;; +FA0A;CJK COMPATIBILITY IDEOGRAPH-FA0A;Lo;0;L;898B;;;;N;;;;; +FA0B;CJK COMPATIBILITY IDEOGRAPH-FA0B;Lo;0;L;5ED3;;;;N;;;;; +FA0C;CJK COMPATIBILITY IDEOGRAPH-FA0C;Lo;0;L;5140;;;;N;;;;; +FA0D;CJK COMPATIBILITY IDEOGRAPH-FA0D;Lo;0;L;55C0;;;;N;;;;; +FA0E;CJK COMPATIBILITY IDEOGRAPH-FA0E;Lo;0;L;;;;;N;;;;; +FA0F;CJK COMPATIBILITY IDEOGRAPH-FA0F;Lo;0;L;;;;;N;;;;; +FA10;CJK COMPATIBILITY IDEOGRAPH-FA10;Lo;0;L;585A;;;;N;;;;; +FA11;CJK COMPATIBILITY IDEOGRAPH-FA11;Lo;0;L;;;;;N;;;;; +FA12;CJK COMPATIBILITY IDEOGRAPH-FA12;Lo;0;L;6674;;;;N;;;;; +FA13;CJK COMPATIBILITY IDEOGRAPH-FA13;Lo;0;L;;;;;N;;;;; +FA14;CJK COMPATIBILITY IDEOGRAPH-FA14;Lo;0;L;;;;;N;;;;; +FA15;CJK COMPATIBILITY IDEOGRAPH-FA15;Lo;0;L;51DE;;;;N;;;;; +FA16;CJK COMPATIBILITY IDEOGRAPH-FA16;Lo;0;L;732A;;;;N;;;;; +FA17;CJK COMPATIBILITY IDEOGRAPH-FA17;Lo;0;L;76CA;;;;N;;;;; +FA18;CJK COMPATIBILITY IDEOGRAPH-FA18;Lo;0;L;793C;;;;N;;;;; +FA19;CJK COMPATIBILITY IDEOGRAPH-FA19;Lo;0;L;795E;;;;N;;;;; +FA1A;CJK COMPATIBILITY IDEOGRAPH-FA1A;Lo;0;L;7965;;;;N;;;;; +FA1B;CJK COMPATIBILITY IDEOGRAPH-FA1B;Lo;0;L;798F;;;;N;;;;; +FA1C;CJK COMPATIBILITY IDEOGRAPH-FA1C;Lo;0;L;9756;;;;N;;;;; +FA1D;CJK COMPATIBILITY IDEOGRAPH-FA1D;Lo;0;L;7CBE;;;;N;;;;; +FA1E;CJK COMPATIBILITY IDEOGRAPH-FA1E;Lo;0;L;7FBD;;;;N;;;;; +FA1F;CJK COMPATIBILITY IDEOGRAPH-FA1F;Lo;0;L;;;;;N;;;;; +FA20;CJK COMPATIBILITY IDEOGRAPH-FA20;Lo;0;L;8612;;;;N;;;;; +FA21;CJK COMPATIBILITY IDEOGRAPH-FA21;Lo;0;L;;;;;N;;;;; +FA22;CJK COMPATIBILITY IDEOGRAPH-FA22;Lo;0;L;8AF8;;;;N;;;;; +FA23;CJK COMPATIBILITY IDEOGRAPH-FA23;Lo;0;L;;;;;N;;;;; +FA24;CJK COMPATIBILITY IDEOGRAPH-FA24;Lo;0;L;;;;;N;;;;; +FA25;CJK COMPATIBILITY IDEOGRAPH-FA25;Lo;0;L;9038;;;;N;;;;; +FA26;CJK COMPATIBILITY IDEOGRAPH-FA26;Lo;0;L;90FD;;;;N;;;;; +FA27;CJK COMPATIBILITY IDEOGRAPH-FA27;Lo;0;L;;;;;N;;;;; +FA28;CJK COMPATIBILITY IDEOGRAPH-FA28;Lo;0;L;;;;;N;;;;; +FA29;CJK COMPATIBILITY IDEOGRAPH-FA29;Lo;0;L;;;;;N;;;;; +FA2A;CJK COMPATIBILITY IDEOGRAPH-FA2A;Lo;0;L;98EF;;;;N;;;;; +FA2B;CJK COMPATIBILITY IDEOGRAPH-FA2B;Lo;0;L;98FC;;;;N;;;;; +FA2C;CJK COMPATIBILITY IDEOGRAPH-FA2C;Lo;0;L;9928;;;;N;;;;; +FA2D;CJK COMPATIBILITY IDEOGRAPH-FA2D;Lo;0;L;9DB4;;;;N;;;;; +FA2E;CJK COMPATIBILITY IDEOGRAPH-FA2E;Lo;0;L;90DE;;;;N;;;;; +FA2F;CJK COMPATIBILITY IDEOGRAPH-FA2F;Lo;0;L;96B7;;;;N;;;;; +FA30;CJK COMPATIBILITY IDEOGRAPH-FA30;Lo;0;L;4FAE;;;;N;;;;; +FA31;CJK COMPATIBILITY IDEOGRAPH-FA31;Lo;0;L;50E7;;;;N;;;;; +FA32;CJK COMPATIBILITY IDEOGRAPH-FA32;Lo;0;L;514D;;;;N;;;;; +FA33;CJK COMPATIBILITY IDEOGRAPH-FA33;Lo;0;L;52C9;;;;N;;;;; +FA34;CJK COMPATIBILITY IDEOGRAPH-FA34;Lo;0;L;52E4;;;;N;;;;; +FA35;CJK COMPATIBILITY IDEOGRAPH-FA35;Lo;0;L;5351;;;;N;;;;; +FA36;CJK COMPATIBILITY IDEOGRAPH-FA36;Lo;0;L;559D;;;;N;;;;; +FA37;CJK COMPATIBILITY IDEOGRAPH-FA37;Lo;0;L;5606;;;;N;;;;; +FA38;CJK COMPATIBILITY IDEOGRAPH-FA38;Lo;0;L;5668;;;;N;;;;; +FA39;CJK COMPATIBILITY IDEOGRAPH-FA39;Lo;0;L;5840;;;;N;;;;; +FA3A;CJK COMPATIBILITY IDEOGRAPH-FA3A;Lo;0;L;58A8;;;;N;;;;; +FA3B;CJK COMPATIBILITY IDEOGRAPH-FA3B;Lo;0;L;5C64;;;;N;;;;; +FA3C;CJK COMPATIBILITY IDEOGRAPH-FA3C;Lo;0;L;5C6E;;;;N;;;;; +FA3D;CJK COMPATIBILITY IDEOGRAPH-FA3D;Lo;0;L;6094;;;;N;;;;; +FA3E;CJK COMPATIBILITY IDEOGRAPH-FA3E;Lo;0;L;6168;;;;N;;;;; +FA3F;CJK COMPATIBILITY IDEOGRAPH-FA3F;Lo;0;L;618E;;;;N;;;;; +FA40;CJK COMPATIBILITY IDEOGRAPH-FA40;Lo;0;L;61F2;;;;N;;;;; +FA41;CJK COMPATIBILITY IDEOGRAPH-FA41;Lo;0;L;654F;;;;N;;;;; +FA42;CJK COMPATIBILITY IDEOGRAPH-FA42;Lo;0;L;65E2;;;;N;;;;; +FA43;CJK COMPATIBILITY IDEOGRAPH-FA43;Lo;0;L;6691;;;;N;;;;; +FA44;CJK COMPATIBILITY IDEOGRAPH-FA44;Lo;0;L;6885;;;;N;;;;; +FA45;CJK COMPATIBILITY IDEOGRAPH-FA45;Lo;0;L;6D77;;;;N;;;;; +FA46;CJK COMPATIBILITY IDEOGRAPH-FA46;Lo;0;L;6E1A;;;;N;;;;; +FA47;CJK COMPATIBILITY IDEOGRAPH-FA47;Lo;0;L;6F22;;;;N;;;;; +FA48;CJK COMPATIBILITY IDEOGRAPH-FA48;Lo;0;L;716E;;;;N;;;;; +FA49;CJK COMPATIBILITY IDEOGRAPH-FA49;Lo;0;L;722B;;;;N;;;;; +FA4A;CJK COMPATIBILITY IDEOGRAPH-FA4A;Lo;0;L;7422;;;;N;;;;; +FA4B;CJK COMPATIBILITY IDEOGRAPH-FA4B;Lo;0;L;7891;;;;N;;;;; +FA4C;CJK COMPATIBILITY IDEOGRAPH-FA4C;Lo;0;L;793E;;;;N;;;;; +FA4D;CJK COMPATIBILITY IDEOGRAPH-FA4D;Lo;0;L;7949;;;;N;;;;; +FA4E;CJK COMPATIBILITY IDEOGRAPH-FA4E;Lo;0;L;7948;;;;N;;;;; +FA4F;CJK COMPATIBILITY IDEOGRAPH-FA4F;Lo;0;L;7950;;;;N;;;;; +FA50;CJK COMPATIBILITY IDEOGRAPH-FA50;Lo;0;L;7956;;;;N;;;;; +FA51;CJK COMPATIBILITY IDEOGRAPH-FA51;Lo;0;L;795D;;;;N;;;;; +FA52;CJK COMPATIBILITY IDEOGRAPH-FA52;Lo;0;L;798D;;;;N;;;;; +FA53;CJK COMPATIBILITY IDEOGRAPH-FA53;Lo;0;L;798E;;;;N;;;;; +FA54;CJK COMPATIBILITY IDEOGRAPH-FA54;Lo;0;L;7A40;;;;N;;;;; +FA55;CJK COMPATIBILITY IDEOGRAPH-FA55;Lo;0;L;7A81;;;;N;;;;; +FA56;CJK COMPATIBILITY IDEOGRAPH-FA56;Lo;0;L;7BC0;;;;N;;;;; +FA57;CJK COMPATIBILITY IDEOGRAPH-FA57;Lo;0;L;7DF4;;;;N;;;;; +FA58;CJK COMPATIBILITY IDEOGRAPH-FA58;Lo;0;L;7E09;;;;N;;;;; +FA59;CJK COMPATIBILITY IDEOGRAPH-FA59;Lo;0;L;7E41;;;;N;;;;; +FA5A;CJK COMPATIBILITY IDEOGRAPH-FA5A;Lo;0;L;7F72;;;;N;;;;; +FA5B;CJK COMPATIBILITY IDEOGRAPH-FA5B;Lo;0;L;8005;;;;N;;;;; +FA5C;CJK COMPATIBILITY IDEOGRAPH-FA5C;Lo;0;L;81ED;;;;N;;;;; +FA5D;CJK COMPATIBILITY IDEOGRAPH-FA5D;Lo;0;L;8279;;;;N;;;;; +FA5E;CJK COMPATIBILITY IDEOGRAPH-FA5E;Lo;0;L;8279;;;;N;;;;; +FA5F;CJK COMPATIBILITY IDEOGRAPH-FA5F;Lo;0;L;8457;;;;N;;;;; +FA60;CJK COMPATIBILITY IDEOGRAPH-FA60;Lo;0;L;8910;;;;N;;;;; +FA61;CJK COMPATIBILITY IDEOGRAPH-FA61;Lo;0;L;8996;;;;N;;;;; +FA62;CJK COMPATIBILITY IDEOGRAPH-FA62;Lo;0;L;8B01;;;;N;;;;; +FA63;CJK COMPATIBILITY IDEOGRAPH-FA63;Lo;0;L;8B39;;;;N;;;;; +FA64;CJK COMPATIBILITY IDEOGRAPH-FA64;Lo;0;L;8CD3;;;;N;;;;; +FA65;CJK COMPATIBILITY IDEOGRAPH-FA65;Lo;0;L;8D08;;;;N;;;;; +FA66;CJK COMPATIBILITY IDEOGRAPH-FA66;Lo;0;L;8FB6;;;;N;;;;; +FA67;CJK COMPATIBILITY IDEOGRAPH-FA67;Lo;0;L;9038;;;;N;;;;; +FA68;CJK COMPATIBILITY IDEOGRAPH-FA68;Lo;0;L;96E3;;;;N;;;;; +FA69;CJK COMPATIBILITY IDEOGRAPH-FA69;Lo;0;L;97FF;;;;N;;;;; +FA6A;CJK COMPATIBILITY IDEOGRAPH-FA6A;Lo;0;L;983B;;;;N;;;;; +FA6B;CJK COMPATIBILITY IDEOGRAPH-FA6B;Lo;0;L;6075;;;;N;;;;; +FA6C;CJK COMPATIBILITY IDEOGRAPH-FA6C;Lo;0;L;242EE;;;;N;;;;; +FA6D;CJK COMPATIBILITY IDEOGRAPH-FA6D;Lo;0;L;8218;;;;N;;;;; +FA70;CJK COMPATIBILITY IDEOGRAPH-FA70;Lo;0;L;4E26;;;;N;;;;; +FA71;CJK COMPATIBILITY IDEOGRAPH-FA71;Lo;0;L;51B5;;;;N;;;;; +FA72;CJK COMPATIBILITY IDEOGRAPH-FA72;Lo;0;L;5168;;;;N;;;;; +FA73;CJK COMPATIBILITY IDEOGRAPH-FA73;Lo;0;L;4F80;;;;N;;;;; +FA74;CJK COMPATIBILITY IDEOGRAPH-FA74;Lo;0;L;5145;;;;N;;;;; +FA75;CJK COMPATIBILITY IDEOGRAPH-FA75;Lo;0;L;5180;;;;N;;;;; +FA76;CJK COMPATIBILITY IDEOGRAPH-FA76;Lo;0;L;52C7;;;;N;;;;; +FA77;CJK COMPATIBILITY IDEOGRAPH-FA77;Lo;0;L;52FA;;;;N;;;;; +FA78;CJK COMPATIBILITY IDEOGRAPH-FA78;Lo;0;L;559D;;;;N;;;;; +FA79;CJK COMPATIBILITY IDEOGRAPH-FA79;Lo;0;L;5555;;;;N;;;;; +FA7A;CJK COMPATIBILITY IDEOGRAPH-FA7A;Lo;0;L;5599;;;;N;;;;; +FA7B;CJK COMPATIBILITY IDEOGRAPH-FA7B;Lo;0;L;55E2;;;;N;;;;; +FA7C;CJK COMPATIBILITY IDEOGRAPH-FA7C;Lo;0;L;585A;;;;N;;;;; +FA7D;CJK COMPATIBILITY IDEOGRAPH-FA7D;Lo;0;L;58B3;;;;N;;;;; +FA7E;CJK COMPATIBILITY IDEOGRAPH-FA7E;Lo;0;L;5944;;;;N;;;;; +FA7F;CJK COMPATIBILITY IDEOGRAPH-FA7F;Lo;0;L;5954;;;;N;;;;; +FA80;CJK COMPATIBILITY IDEOGRAPH-FA80;Lo;0;L;5A62;;;;N;;;;; +FA81;CJK COMPATIBILITY IDEOGRAPH-FA81;Lo;0;L;5B28;;;;N;;;;; +FA82;CJK COMPATIBILITY IDEOGRAPH-FA82;Lo;0;L;5ED2;;;;N;;;;; +FA83;CJK COMPATIBILITY IDEOGRAPH-FA83;Lo;0;L;5ED9;;;;N;;;;; +FA84;CJK COMPATIBILITY IDEOGRAPH-FA84;Lo;0;L;5F69;;;;N;;;;; +FA85;CJK COMPATIBILITY IDEOGRAPH-FA85;Lo;0;L;5FAD;;;;N;;;;; +FA86;CJK COMPATIBILITY IDEOGRAPH-FA86;Lo;0;L;60D8;;;;N;;;;; +FA87;CJK COMPATIBILITY IDEOGRAPH-FA87;Lo;0;L;614E;;;;N;;;;; +FA88;CJK COMPATIBILITY IDEOGRAPH-FA88;Lo;0;L;6108;;;;N;;;;; +FA89;CJK COMPATIBILITY IDEOGRAPH-FA89;Lo;0;L;618E;;;;N;;;;; +FA8A;CJK COMPATIBILITY IDEOGRAPH-FA8A;Lo;0;L;6160;;;;N;;;;; +FA8B;CJK COMPATIBILITY IDEOGRAPH-FA8B;Lo;0;L;61F2;;;;N;;;;; +FA8C;CJK COMPATIBILITY IDEOGRAPH-FA8C;Lo;0;L;6234;;;;N;;;;; +FA8D;CJK COMPATIBILITY IDEOGRAPH-FA8D;Lo;0;L;63C4;;;;N;;;;; +FA8E;CJK COMPATIBILITY IDEOGRAPH-FA8E;Lo;0;L;641C;;;;N;;;;; +FA8F;CJK COMPATIBILITY IDEOGRAPH-FA8F;Lo;0;L;6452;;;;N;;;;; +FA90;CJK COMPATIBILITY IDEOGRAPH-FA90;Lo;0;L;6556;;;;N;;;;; +FA91;CJK COMPATIBILITY IDEOGRAPH-FA91;Lo;0;L;6674;;;;N;;;;; +FA92;CJK COMPATIBILITY IDEOGRAPH-FA92;Lo;0;L;6717;;;;N;;;;; +FA93;CJK COMPATIBILITY IDEOGRAPH-FA93;Lo;0;L;671B;;;;N;;;;; +FA94;CJK COMPATIBILITY IDEOGRAPH-FA94;Lo;0;L;6756;;;;N;;;;; +FA95;CJK COMPATIBILITY IDEOGRAPH-FA95;Lo;0;L;6B79;;;;N;;;;; +FA96;CJK COMPATIBILITY IDEOGRAPH-FA96;Lo;0;L;6BBA;;;;N;;;;; +FA97;CJK COMPATIBILITY IDEOGRAPH-FA97;Lo;0;L;6D41;;;;N;;;;; +FA98;CJK COMPATIBILITY IDEOGRAPH-FA98;Lo;0;L;6EDB;;;;N;;;;; +FA99;CJK COMPATIBILITY IDEOGRAPH-FA99;Lo;0;L;6ECB;;;;N;;;;; +FA9A;CJK COMPATIBILITY IDEOGRAPH-FA9A;Lo;0;L;6F22;;;;N;;;;; +FA9B;CJK COMPATIBILITY IDEOGRAPH-FA9B;Lo;0;L;701E;;;;N;;;;; +FA9C;CJK COMPATIBILITY IDEOGRAPH-FA9C;Lo;0;L;716E;;;;N;;;;; +FA9D;CJK COMPATIBILITY IDEOGRAPH-FA9D;Lo;0;L;77A7;;;;N;;;;; +FA9E;CJK COMPATIBILITY IDEOGRAPH-FA9E;Lo;0;L;7235;;;;N;;;;; +FA9F;CJK COMPATIBILITY IDEOGRAPH-FA9F;Lo;0;L;72AF;;;;N;;;;; +FAA0;CJK COMPATIBILITY IDEOGRAPH-FAA0;Lo;0;L;732A;;;;N;;;;; +FAA1;CJK COMPATIBILITY IDEOGRAPH-FAA1;Lo;0;L;7471;;;;N;;;;; +FAA2;CJK COMPATIBILITY IDEOGRAPH-FAA2;Lo;0;L;7506;;;;N;;;;; +FAA3;CJK COMPATIBILITY IDEOGRAPH-FAA3;Lo;0;L;753B;;;;N;;;;; +FAA4;CJK COMPATIBILITY IDEOGRAPH-FAA4;Lo;0;L;761D;;;;N;;;;; +FAA5;CJK COMPATIBILITY IDEOGRAPH-FAA5;Lo;0;L;761F;;;;N;;;;; +FAA6;CJK COMPATIBILITY IDEOGRAPH-FAA6;Lo;0;L;76CA;;;;N;;;;; +FAA7;CJK COMPATIBILITY IDEOGRAPH-FAA7;Lo;0;L;76DB;;;;N;;;;; +FAA8;CJK COMPATIBILITY IDEOGRAPH-FAA8;Lo;0;L;76F4;;;;N;;;;; +FAA9;CJK COMPATIBILITY IDEOGRAPH-FAA9;Lo;0;L;774A;;;;N;;;;; +FAAA;CJK COMPATIBILITY IDEOGRAPH-FAAA;Lo;0;L;7740;;;;N;;;;; +FAAB;CJK COMPATIBILITY IDEOGRAPH-FAAB;Lo;0;L;78CC;;;;N;;;;; +FAAC;CJK COMPATIBILITY IDEOGRAPH-FAAC;Lo;0;L;7AB1;;;;N;;;;; +FAAD;CJK COMPATIBILITY IDEOGRAPH-FAAD;Lo;0;L;7BC0;;;;N;;;;; +FAAE;CJK COMPATIBILITY IDEOGRAPH-FAAE;Lo;0;L;7C7B;;;;N;;;;; +FAAF;CJK COMPATIBILITY IDEOGRAPH-FAAF;Lo;0;L;7D5B;;;;N;;;;; +FAB0;CJK COMPATIBILITY IDEOGRAPH-FAB0;Lo;0;L;7DF4;;;;N;;;;; +FAB1;CJK COMPATIBILITY IDEOGRAPH-FAB1;Lo;0;L;7F3E;;;;N;;;;; +FAB2;CJK COMPATIBILITY IDEOGRAPH-FAB2;Lo;0;L;8005;;;;N;;;;; +FAB3;CJK COMPATIBILITY IDEOGRAPH-FAB3;Lo;0;L;8352;;;;N;;;;; +FAB4;CJK COMPATIBILITY IDEOGRAPH-FAB4;Lo;0;L;83EF;;;;N;;;;; +FAB5;CJK COMPATIBILITY IDEOGRAPH-FAB5;Lo;0;L;8779;;;;N;;;;; +FAB6;CJK COMPATIBILITY IDEOGRAPH-FAB6;Lo;0;L;8941;;;;N;;;;; +FAB7;CJK COMPATIBILITY IDEOGRAPH-FAB7;Lo;0;L;8986;;;;N;;;;; +FAB8;CJK COMPATIBILITY IDEOGRAPH-FAB8;Lo;0;L;8996;;;;N;;;;; +FAB9;CJK COMPATIBILITY IDEOGRAPH-FAB9;Lo;0;L;8ABF;;;;N;;;;; +FABA;CJK COMPATIBILITY IDEOGRAPH-FABA;Lo;0;L;8AF8;;;;N;;;;; +FABB;CJK COMPATIBILITY IDEOGRAPH-FABB;Lo;0;L;8ACB;;;;N;;;;; +FABC;CJK COMPATIBILITY IDEOGRAPH-FABC;Lo;0;L;8B01;;;;N;;;;; +FABD;CJK COMPATIBILITY IDEOGRAPH-FABD;Lo;0;L;8AFE;;;;N;;;;; +FABE;CJK COMPATIBILITY IDEOGRAPH-FABE;Lo;0;L;8AED;;;;N;;;;; +FABF;CJK COMPATIBILITY IDEOGRAPH-FABF;Lo;0;L;8B39;;;;N;;;;; +FAC0;CJK COMPATIBILITY IDEOGRAPH-FAC0;Lo;0;L;8B8A;;;;N;;;;; +FAC1;CJK COMPATIBILITY IDEOGRAPH-FAC1;Lo;0;L;8D08;;;;N;;;;; +FAC2;CJK COMPATIBILITY IDEOGRAPH-FAC2;Lo;0;L;8F38;;;;N;;;;; +FAC3;CJK COMPATIBILITY IDEOGRAPH-FAC3;Lo;0;L;9072;;;;N;;;;; +FAC4;CJK COMPATIBILITY IDEOGRAPH-FAC4;Lo;0;L;9199;;;;N;;;;; +FAC5;CJK COMPATIBILITY IDEOGRAPH-FAC5;Lo;0;L;9276;;;;N;;;;; +FAC6;CJK COMPATIBILITY IDEOGRAPH-FAC6;Lo;0;L;967C;;;;N;;;;; +FAC7;CJK COMPATIBILITY IDEOGRAPH-FAC7;Lo;0;L;96E3;;;;N;;;;; +FAC8;CJK COMPATIBILITY IDEOGRAPH-FAC8;Lo;0;L;9756;;;;N;;;;; +FAC9;CJK COMPATIBILITY IDEOGRAPH-FAC9;Lo;0;L;97DB;;;;N;;;;; +FACA;CJK COMPATIBILITY IDEOGRAPH-FACA;Lo;0;L;97FF;;;;N;;;;; +FACB;CJK COMPATIBILITY IDEOGRAPH-FACB;Lo;0;L;980B;;;;N;;;;; +FACC;CJK COMPATIBILITY IDEOGRAPH-FACC;Lo;0;L;983B;;;;N;;;;; +FACD;CJK COMPATIBILITY IDEOGRAPH-FACD;Lo;0;L;9B12;;;;N;;;;; +FACE;CJK COMPATIBILITY IDEOGRAPH-FACE;Lo;0;L;9F9C;;;;N;;;;; +FACF;CJK COMPATIBILITY IDEOGRAPH-FACF;Lo;0;L;2284A;;;;N;;;;; +FAD0;CJK COMPATIBILITY IDEOGRAPH-FAD0;Lo;0;L;22844;;;;N;;;;; +FAD1;CJK COMPATIBILITY IDEOGRAPH-FAD1;Lo;0;L;233D5;;;;N;;;;; +FAD2;CJK COMPATIBILITY IDEOGRAPH-FAD2;Lo;0;L;3B9D;;;;N;;;;; +FAD3;CJK COMPATIBILITY IDEOGRAPH-FAD3;Lo;0;L;4018;;;;N;;;;; +FAD4;CJK COMPATIBILITY IDEOGRAPH-FAD4;Lo;0;L;4039;;;;N;;;;; +FAD5;CJK COMPATIBILITY IDEOGRAPH-FAD5;Lo;0;L;25249;;;;N;;;;; +FAD6;CJK COMPATIBILITY IDEOGRAPH-FAD6;Lo;0;L;25CD0;;;;N;;;;; +FAD7;CJK COMPATIBILITY IDEOGRAPH-FAD7;Lo;0;L;27ED3;;;;N;;;;; +FAD8;CJK COMPATIBILITY IDEOGRAPH-FAD8;Lo;0;L;9F43;;;;N;;;;; +FAD9;CJK COMPATIBILITY IDEOGRAPH-FAD9;Lo;0;L;9F8E;;;;N;;;;; +FB00;LATIN SMALL LIGATURE FF;Ll;0;L; 0066 0066;;;;N;;;;; +FB01;LATIN SMALL LIGATURE FI;Ll;0;L; 0066 0069;;;;N;;;;; +FB02;LATIN SMALL LIGATURE FL;Ll;0;L; 0066 006C;;;;N;;;;; +FB03;LATIN SMALL LIGATURE FFI;Ll;0;L; 0066 0066 0069;;;;N;;;;; +FB04;LATIN SMALL LIGATURE FFL;Ll;0;L; 0066 0066 006C;;;;N;;;;; +FB05;LATIN SMALL LIGATURE LONG S T;Ll;0;L; 017F 0074;;;;N;;;;; +FB06;LATIN SMALL LIGATURE ST;Ll;0;L; 0073 0074;;;;N;;;;; +FB13;ARMENIAN SMALL LIGATURE MEN NOW;Ll;0;L; 0574 0576;;;;N;;;;; +FB14;ARMENIAN SMALL LIGATURE MEN ECH;Ll;0;L; 0574 0565;;;;N;;;;; +FB15;ARMENIAN SMALL LIGATURE MEN INI;Ll;0;L; 0574 056B;;;;N;;;;; +FB16;ARMENIAN SMALL LIGATURE VEW NOW;Ll;0;L; 057E 0576;;;;N;;;;; +FB17;ARMENIAN SMALL LIGATURE MEN XEH;Ll;0;L; 0574 056D;;;;N;;;;; +FB1D;HEBREW LETTER YOD WITH HIRIQ;Lo;0;R;05D9 05B4;;;;N;;;;; +FB1E;HEBREW POINT JUDEO-SPANISH VARIKA;Mn;26;NSM;;;;;N;HEBREW POINT VARIKA;;;; +FB1F;HEBREW LIGATURE YIDDISH YOD YOD PATAH;Lo;0;R;05F2 05B7;;;;N;;;;; +FB20;HEBREW LETTER ALTERNATIVE AYIN;Lo;0;R; 05E2;;;;N;;;;; +FB21;HEBREW LETTER WIDE ALEF;Lo;0;R; 05D0;;;;N;;;;; +FB22;HEBREW LETTER WIDE DALET;Lo;0;R; 05D3;;;;N;;;;; +FB23;HEBREW LETTER WIDE HE;Lo;0;R; 05D4;;;;N;;;;; +FB24;HEBREW LETTER WIDE KAF;Lo;0;R; 05DB;;;;N;;;;; +FB25;HEBREW LETTER WIDE LAMED;Lo;0;R; 05DC;;;;N;;;;; +FB26;HEBREW LETTER WIDE FINAL MEM;Lo;0;R; 05DD;;;;N;;;;; +FB27;HEBREW LETTER WIDE RESH;Lo;0;R; 05E8;;;;N;;;;; +FB28;HEBREW LETTER WIDE TAV;Lo;0;R; 05EA;;;;N;;;;; +FB29;HEBREW LETTER ALTERNATIVE PLUS SIGN;Sm;0;ES; 002B;;;;N;;;;; +FB2A;HEBREW LETTER SHIN WITH SHIN DOT;Lo;0;R;05E9 05C1;;;;N;;;;; +FB2B;HEBREW LETTER SHIN WITH SIN DOT;Lo;0;R;05E9 05C2;;;;N;;;;; +FB2C;HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT;Lo;0;R;FB49 05C1;;;;N;;;;; +FB2D;HEBREW LETTER SHIN WITH DAGESH AND SIN DOT;Lo;0;R;FB49 05C2;;;;N;;;;; +FB2E;HEBREW LETTER ALEF WITH PATAH;Lo;0;R;05D0 05B7;;;;N;;;;; +FB2F;HEBREW LETTER ALEF WITH QAMATS;Lo;0;R;05D0 05B8;;;;N;;;;; +FB30;HEBREW LETTER ALEF WITH MAPIQ;Lo;0;R;05D0 05BC;;;;N;;;;; +FB31;HEBREW LETTER BET WITH DAGESH;Lo;0;R;05D1 05BC;;;;N;;;;; +FB32;HEBREW LETTER GIMEL WITH DAGESH;Lo;0;R;05D2 05BC;;;;N;;;;; +FB33;HEBREW LETTER DALET WITH DAGESH;Lo;0;R;05D3 05BC;;;;N;;;;; +FB34;HEBREW LETTER HE WITH MAPIQ;Lo;0;R;05D4 05BC;;;;N;;;;; +FB35;HEBREW LETTER VAV WITH DAGESH;Lo;0;R;05D5 05BC;;;;N;;;;; +FB36;HEBREW LETTER ZAYIN WITH DAGESH;Lo;0;R;05D6 05BC;;;;N;;;;; +FB38;HEBREW LETTER TET WITH DAGESH;Lo;0;R;05D8 05BC;;;;N;;;;; +FB39;HEBREW LETTER YOD WITH DAGESH;Lo;0;R;05D9 05BC;;;;N;;;;; +FB3A;HEBREW LETTER FINAL KAF WITH DAGESH;Lo;0;R;05DA 05BC;;;;N;;;;; +FB3B;HEBREW LETTER KAF WITH DAGESH;Lo;0;R;05DB 05BC;;;;N;;;;; +FB3C;HEBREW LETTER LAMED WITH DAGESH;Lo;0;R;05DC 05BC;;;;N;;;;; +FB3E;HEBREW LETTER MEM WITH DAGESH;Lo;0;R;05DE 05BC;;;;N;;;;; +FB40;HEBREW LETTER NUN WITH DAGESH;Lo;0;R;05E0 05BC;;;;N;;;;; +FB41;HEBREW LETTER SAMEKH WITH DAGESH;Lo;0;R;05E1 05BC;;;;N;;;;; +FB43;HEBREW LETTER FINAL PE WITH DAGESH;Lo;0;R;05E3 05BC;;;;N;;;;; +FB44;HEBREW LETTER PE WITH DAGESH;Lo;0;R;05E4 05BC;;;;N;;;;; +FB46;HEBREW LETTER TSADI WITH DAGESH;Lo;0;R;05E6 05BC;;;;N;;;;; +FB47;HEBREW LETTER QOF WITH DAGESH;Lo;0;R;05E7 05BC;;;;N;;;;; +FB48;HEBREW LETTER RESH WITH DAGESH;Lo;0;R;05E8 05BC;;;;N;;;;; +FB49;HEBREW LETTER SHIN WITH DAGESH;Lo;0;R;05E9 05BC;;;;N;;;;; +FB4A;HEBREW LETTER TAV WITH DAGESH;Lo;0;R;05EA 05BC;;;;N;;;;; +FB4B;HEBREW LETTER VAV WITH HOLAM;Lo;0;R;05D5 05B9;;;;N;;;;; +FB4C;HEBREW LETTER BET WITH RAFE;Lo;0;R;05D1 05BF;;;;N;;;;; +FB4D;HEBREW LETTER KAF WITH RAFE;Lo;0;R;05DB 05BF;;;;N;;;;; +FB4E;HEBREW LETTER PE WITH RAFE;Lo;0;R;05E4 05BF;;;;N;;;;; +FB4F;HEBREW LIGATURE ALEF LAMED;Lo;0;R; 05D0 05DC;;;;N;;;;; +FB50;ARABIC LETTER ALEF WASLA ISOLATED FORM;Lo;0;AL; 0671;;;;N;;;;; +FB51;ARABIC LETTER ALEF WASLA FINAL FORM;Lo;0;AL; 0671;;;;N;;;;; +FB52;ARABIC LETTER BEEH ISOLATED FORM;Lo;0;AL; 067B;;;;N;;;;; +FB53;ARABIC LETTER BEEH FINAL FORM;Lo;0;AL; 067B;;;;N;;;;; +FB54;ARABIC LETTER BEEH INITIAL FORM;Lo;0;AL; 067B;;;;N;;;;; +FB55;ARABIC LETTER BEEH MEDIAL FORM;Lo;0;AL; 067B;;;;N;;;;; +FB56;ARABIC LETTER PEH ISOLATED FORM;Lo;0;AL; 067E;;;;N;;;;; +FB57;ARABIC LETTER PEH FINAL FORM;Lo;0;AL; 067E;;;;N;;;;; +FB58;ARABIC LETTER PEH INITIAL FORM;Lo;0;AL; 067E;;;;N;;;;; +FB59;ARABIC LETTER PEH MEDIAL FORM;Lo;0;AL; 067E;;;;N;;;;; +FB5A;ARABIC LETTER BEHEH ISOLATED FORM;Lo;0;AL; 0680;;;;N;;;;; +FB5B;ARABIC LETTER BEHEH FINAL FORM;Lo;0;AL; 0680;;;;N;;;;; +FB5C;ARABIC LETTER BEHEH INITIAL FORM;Lo;0;AL; 0680;;;;N;;;;; +FB5D;ARABIC LETTER BEHEH MEDIAL FORM;Lo;0;AL; 0680;;;;N;;;;; +FB5E;ARABIC LETTER TTEHEH ISOLATED FORM;Lo;0;AL; 067A;;;;N;;;;; +FB5F;ARABIC LETTER TTEHEH FINAL FORM;Lo;0;AL; 067A;;;;N;;;;; +FB60;ARABIC LETTER TTEHEH INITIAL FORM;Lo;0;AL; 067A;;;;N;;;;; +FB61;ARABIC LETTER TTEHEH MEDIAL FORM;Lo;0;AL; 067A;;;;N;;;;; +FB62;ARABIC LETTER TEHEH ISOLATED FORM;Lo;0;AL; 067F;;;;N;;;;; +FB63;ARABIC LETTER TEHEH FINAL FORM;Lo;0;AL; 067F;;;;N;;;;; +FB64;ARABIC LETTER TEHEH INITIAL FORM;Lo;0;AL; 067F;;;;N;;;;; +FB65;ARABIC LETTER TEHEH MEDIAL FORM;Lo;0;AL; 067F;;;;N;;;;; +FB66;ARABIC LETTER TTEH ISOLATED FORM;Lo;0;AL; 0679;;;;N;;;;; +FB67;ARABIC LETTER TTEH FINAL FORM;Lo;0;AL; 0679;;;;N;;;;; +FB68;ARABIC LETTER TTEH INITIAL FORM;Lo;0;AL; 0679;;;;N;;;;; +FB69;ARABIC LETTER TTEH MEDIAL FORM;Lo;0;AL; 0679;;;;N;;;;; +FB6A;ARABIC LETTER VEH ISOLATED FORM;Lo;0;AL; 06A4;;;;N;;;;; +FB6B;ARABIC LETTER VEH FINAL FORM;Lo;0;AL; 06A4;;;;N;;;;; +FB6C;ARABIC LETTER VEH INITIAL FORM;Lo;0;AL; 06A4;;;;N;;;;; +FB6D;ARABIC LETTER VEH MEDIAL FORM;Lo;0;AL; 06A4;;;;N;;;;; +FB6E;ARABIC LETTER PEHEH ISOLATED FORM;Lo;0;AL; 06A6;;;;N;;;;; +FB6F;ARABIC LETTER PEHEH FINAL FORM;Lo;0;AL; 06A6;;;;N;;;;; +FB70;ARABIC LETTER PEHEH INITIAL FORM;Lo;0;AL; 06A6;;;;N;;;;; +FB71;ARABIC LETTER PEHEH MEDIAL FORM;Lo;0;AL; 06A6;;;;N;;;;; +FB72;ARABIC LETTER DYEH ISOLATED FORM;Lo;0;AL; 0684;;;;N;;;;; +FB73;ARABIC LETTER DYEH FINAL FORM;Lo;0;AL; 0684;;;;N;;;;; +FB74;ARABIC LETTER DYEH INITIAL FORM;Lo;0;AL; 0684;;;;N;;;;; +FB75;ARABIC LETTER DYEH MEDIAL FORM;Lo;0;AL; 0684;;;;N;;;;; +FB76;ARABIC LETTER NYEH ISOLATED FORM;Lo;0;AL; 0683;;;;N;;;;; +FB77;ARABIC LETTER NYEH FINAL FORM;Lo;0;AL; 0683;;;;N;;;;; +FB78;ARABIC LETTER NYEH INITIAL FORM;Lo;0;AL; 0683;;;;N;;;;; +FB79;ARABIC LETTER NYEH MEDIAL FORM;Lo;0;AL; 0683;;;;N;;;;; +FB7A;ARABIC LETTER TCHEH ISOLATED FORM;Lo;0;AL; 0686;;;;N;;;;; +FB7B;ARABIC LETTER TCHEH FINAL FORM;Lo;0;AL; 0686;;;;N;;;;; +FB7C;ARABIC LETTER TCHEH INITIAL FORM;Lo;0;AL; 0686;;;;N;;;;; +FB7D;ARABIC LETTER TCHEH MEDIAL FORM;Lo;0;AL; 0686;;;;N;;;;; +FB7E;ARABIC LETTER TCHEHEH ISOLATED FORM;Lo;0;AL; 0687;;;;N;;;;; +FB7F;ARABIC LETTER TCHEHEH FINAL FORM;Lo;0;AL; 0687;;;;N;;;;; +FB80;ARABIC LETTER TCHEHEH INITIAL FORM;Lo;0;AL; 0687;;;;N;;;;; +FB81;ARABIC LETTER TCHEHEH MEDIAL FORM;Lo;0;AL; 0687;;;;N;;;;; +FB82;ARABIC LETTER DDAHAL ISOLATED FORM;Lo;0;AL; 068D;;;;N;;;;; +FB83;ARABIC LETTER DDAHAL FINAL FORM;Lo;0;AL; 068D;;;;N;;;;; +FB84;ARABIC LETTER DAHAL ISOLATED FORM;Lo;0;AL; 068C;;;;N;;;;; +FB85;ARABIC LETTER DAHAL FINAL FORM;Lo;0;AL; 068C;;;;N;;;;; +FB86;ARABIC LETTER DUL ISOLATED FORM;Lo;0;AL; 068E;;;;N;;;;; +FB87;ARABIC LETTER DUL FINAL FORM;Lo;0;AL; 068E;;;;N;;;;; +FB88;ARABIC LETTER DDAL ISOLATED FORM;Lo;0;AL; 0688;;;;N;;;;; +FB89;ARABIC LETTER DDAL FINAL FORM;Lo;0;AL; 0688;;;;N;;;;; +FB8A;ARABIC LETTER JEH ISOLATED FORM;Lo;0;AL; 0698;;;;N;;;;; +FB8B;ARABIC LETTER JEH FINAL FORM;Lo;0;AL; 0698;;;;N;;;;; +FB8C;ARABIC LETTER RREH ISOLATED FORM;Lo;0;AL; 0691;;;;N;;;;; +FB8D;ARABIC LETTER RREH FINAL FORM;Lo;0;AL; 0691;;;;N;;;;; +FB8E;ARABIC LETTER KEHEH ISOLATED FORM;Lo;0;AL; 06A9;;;;N;;;;; +FB8F;ARABIC LETTER KEHEH FINAL FORM;Lo;0;AL; 06A9;;;;N;;;;; +FB90;ARABIC LETTER KEHEH INITIAL FORM;Lo;0;AL; 06A9;;;;N;;;;; +FB91;ARABIC LETTER KEHEH MEDIAL FORM;Lo;0;AL; 06A9;;;;N;;;;; +FB92;ARABIC LETTER GAF ISOLATED FORM;Lo;0;AL; 06AF;;;;N;;;;; +FB93;ARABIC LETTER GAF FINAL FORM;Lo;0;AL; 06AF;;;;N;;;;; +FB94;ARABIC LETTER GAF INITIAL FORM;Lo;0;AL; 06AF;;;;N;;;;; +FB95;ARABIC LETTER GAF MEDIAL FORM;Lo;0;AL; 06AF;;;;N;;;;; +FB96;ARABIC LETTER GUEH ISOLATED FORM;Lo;0;AL; 06B3;;;;N;;;;; +FB97;ARABIC LETTER GUEH FINAL FORM;Lo;0;AL; 06B3;;;;N;;;;; +FB98;ARABIC LETTER GUEH INITIAL FORM;Lo;0;AL; 06B3;;;;N;;;;; +FB99;ARABIC LETTER GUEH MEDIAL FORM;Lo;0;AL; 06B3;;;;N;;;;; +FB9A;ARABIC LETTER NGOEH ISOLATED FORM;Lo;0;AL; 06B1;;;;N;;;;; +FB9B;ARABIC LETTER NGOEH FINAL FORM;Lo;0;AL; 06B1;;;;N;;;;; +FB9C;ARABIC LETTER NGOEH INITIAL FORM;Lo;0;AL; 06B1;;;;N;;;;; +FB9D;ARABIC LETTER NGOEH MEDIAL FORM;Lo;0;AL; 06B1;;;;N;;;;; +FB9E;ARABIC LETTER NOON GHUNNA ISOLATED FORM;Lo;0;AL; 06BA;;;;N;;;;; +FB9F;ARABIC LETTER NOON GHUNNA FINAL FORM;Lo;0;AL; 06BA;;;;N;;;;; +FBA0;ARABIC LETTER RNOON ISOLATED FORM;Lo;0;AL; 06BB;;;;N;;;;; +FBA1;ARABIC LETTER RNOON FINAL FORM;Lo;0;AL; 06BB;;;;N;;;;; +FBA2;ARABIC LETTER RNOON INITIAL FORM;Lo;0;AL; 06BB;;;;N;;;;; +FBA3;ARABIC LETTER RNOON MEDIAL FORM;Lo;0;AL; 06BB;;;;N;;;;; +FBA4;ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM;Lo;0;AL; 06C0;;;;N;;;;; +FBA5;ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM;Lo;0;AL; 06C0;;;;N;;;;; +FBA6;ARABIC LETTER HEH GOAL ISOLATED FORM;Lo;0;AL; 06C1;;;;N;;;;; +FBA7;ARABIC LETTER HEH GOAL FINAL FORM;Lo;0;AL; 06C1;;;;N;;;;; +FBA8;ARABIC LETTER HEH GOAL INITIAL FORM;Lo;0;AL; 06C1;;;;N;;;;; +FBA9;ARABIC LETTER HEH GOAL MEDIAL FORM;Lo;0;AL; 06C1;;;;N;;;;; +FBAA;ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM;Lo;0;AL; 06BE;;;;N;;;;; +FBAB;ARABIC LETTER HEH DOACHASHMEE FINAL FORM;Lo;0;AL; 06BE;;;;N;;;;; +FBAC;ARABIC LETTER HEH DOACHASHMEE INITIAL FORM;Lo;0;AL; 06BE;;;;N;;;;; +FBAD;ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM;Lo;0;AL; 06BE;;;;N;;;;; +FBAE;ARABIC LETTER YEH BARREE ISOLATED FORM;Lo;0;AL; 06D2;;;;N;;;;; +FBAF;ARABIC LETTER YEH BARREE FINAL FORM;Lo;0;AL; 06D2;;;;N;;;;; +FBB0;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 06D3;;;;N;;;;; +FBB1;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 06D3;;;;N;;;;; +FBB2;ARABIC SYMBOL DOT ABOVE;Sk;0;AL;;;;;N;;;;; +FBB3;ARABIC SYMBOL DOT BELOW;Sk;0;AL;;;;;N;;;;; +FBB4;ARABIC SYMBOL TWO DOTS ABOVE;Sk;0;AL;;;;;N;;;;; +FBB5;ARABIC SYMBOL TWO DOTS BELOW;Sk;0;AL;;;;;N;;;;; +FBB6;ARABIC SYMBOL THREE DOTS ABOVE;Sk;0;AL;;;;;N;;;;; +FBB7;ARABIC SYMBOL THREE DOTS BELOW;Sk;0;AL;;;;;N;;;;; +FBB8;ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS ABOVE;Sk;0;AL;;;;;N;;;;; +FBB9;ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS BELOW;Sk;0;AL;;;;;N;;;;; +FBBA;ARABIC SYMBOL FOUR DOTS ABOVE;Sk;0;AL;;;;;N;;;;; +FBBB;ARABIC SYMBOL FOUR DOTS BELOW;Sk;0;AL;;;;;N;;;;; +FBBC;ARABIC SYMBOL DOUBLE VERTICAL BAR BELOW;Sk;0;AL;;;;;N;;;;; +FBBD;ARABIC SYMBOL TWO DOTS VERTICALLY ABOVE;Sk;0;AL;;;;;N;;;;; +FBBE;ARABIC SYMBOL TWO DOTS VERTICALLY BELOW;Sk;0;AL;;;;;N;;;;; +FBBF;ARABIC SYMBOL RING;Sk;0;AL;;;;;N;;;;; +FBC0;ARABIC SYMBOL SMALL TAH ABOVE;Sk;0;AL;;;;;N;;;;; +FBC1;ARABIC SYMBOL SMALL TAH BELOW;Sk;0;AL;;;;;N;;;;; +FBD3;ARABIC LETTER NG ISOLATED FORM;Lo;0;AL; 06AD;;;;N;;;;; +FBD4;ARABIC LETTER NG FINAL FORM;Lo;0;AL; 06AD;;;;N;;;;; +FBD5;ARABIC LETTER NG INITIAL FORM;Lo;0;AL; 06AD;;;;N;;;;; +FBD6;ARABIC LETTER NG MEDIAL FORM;Lo;0;AL; 06AD;;;;N;;;;; +FBD7;ARABIC LETTER U ISOLATED FORM;Lo;0;AL; 06C7;;;;N;;;;; +FBD8;ARABIC LETTER U FINAL FORM;Lo;0;AL; 06C7;;;;N;;;;; +FBD9;ARABIC LETTER OE ISOLATED FORM;Lo;0;AL; 06C6;;;;N;;;;; +FBDA;ARABIC LETTER OE FINAL FORM;Lo;0;AL; 06C6;;;;N;;;;; +FBDB;ARABIC LETTER YU ISOLATED FORM;Lo;0;AL; 06C8;;;;N;;;;; +FBDC;ARABIC LETTER YU FINAL FORM;Lo;0;AL; 06C8;;;;N;;;;; +FBDD;ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0677;;;;N;;;;; +FBDE;ARABIC LETTER VE ISOLATED FORM;Lo;0;AL; 06CB;;;;N;;;;; +FBDF;ARABIC LETTER VE FINAL FORM;Lo;0;AL; 06CB;;;;N;;;;; +FBE0;ARABIC LETTER KIRGHIZ OE ISOLATED FORM;Lo;0;AL; 06C5;;;;N;;;;; +FBE1;ARABIC LETTER KIRGHIZ OE FINAL FORM;Lo;0;AL; 06C5;;;;N;;;;; +FBE2;ARABIC LETTER KIRGHIZ YU ISOLATED FORM;Lo;0;AL; 06C9;;;;N;;;;; +FBE3;ARABIC LETTER KIRGHIZ YU FINAL FORM;Lo;0;AL; 06C9;;;;N;;;;; +FBE4;ARABIC LETTER E ISOLATED FORM;Lo;0;AL; 06D0;;;;N;;;;; +FBE5;ARABIC LETTER E FINAL FORM;Lo;0;AL; 06D0;;;;N;;;;; +FBE6;ARABIC LETTER E INITIAL FORM;Lo;0;AL; 06D0;;;;N;;;;; +FBE7;ARABIC LETTER E MEDIAL FORM;Lo;0;AL; 06D0;;;;N;;;;; +FBE8;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM;Lo;0;AL; 0649;;;;N;;;;; +FBE9;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM;Lo;0;AL; 0649;;;;N;;;;; +FBEA;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM;Lo;0;AL; 0626 0627;;;;N;;;;; +FBEB;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM;Lo;0;AL; 0626 0627;;;;N;;;;; +FBEC;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM;Lo;0;AL; 0626 06D5;;;;N;;;;; +FBED;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM;Lo;0;AL; 0626 06D5;;;;N;;;;; +FBEE;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM;Lo;0;AL; 0626 0648;;;;N;;;;; +FBEF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM;Lo;0;AL; 0626 0648;;;;N;;;;; +FBF0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM;Lo;0;AL; 0626 06C7;;;;N;;;;; +FBF1;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM;Lo;0;AL; 0626 06C7;;;;N;;;;; +FBF2;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM;Lo;0;AL; 0626 06C6;;;;N;;;;; +FBF3;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM;Lo;0;AL; 0626 06C6;;;;N;;;;; +FBF4;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM;Lo;0;AL; 0626 06C8;;;;N;;;;; +FBF5;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM;Lo;0;AL; 0626 06C8;;;;N;;;;; +FBF6;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM;Lo;0;AL; 0626 06D0;;;;N;;;;; +FBF7;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM;Lo;0;AL; 0626 06D0;;;;N;;;;; +FBF8;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM;Lo;0;AL; 0626 06D0;;;;N;;;;; +FBF9;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FBFA;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FBFB;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FBFC;ARABIC LETTER FARSI YEH ISOLATED FORM;Lo;0;AL; 06CC;;;;N;;;;; +FBFD;ARABIC LETTER FARSI YEH FINAL FORM;Lo;0;AL; 06CC;;;;N;;;;; +FBFE;ARABIC LETTER FARSI YEH INITIAL FORM;Lo;0;AL; 06CC;;;;N;;;;; +FBFF;ARABIC LETTER FARSI YEH MEDIAL FORM;Lo;0;AL; 06CC;;;;N;;;;; +FC00;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM;Lo;0;AL; 0626 062C;;;;N;;;;; +FC01;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM;Lo;0;AL; 0626 062D;;;;N;;;;; +FC02;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM;Lo;0;AL; 0626 0645;;;;N;;;;; +FC03;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FC04;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM;Lo;0;AL; 0626 064A;;;;N;;;;; +FC05;ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM;Lo;0;AL; 0628 062C;;;;N;;;;; +FC06;ARABIC LIGATURE BEH WITH HAH ISOLATED FORM;Lo;0;AL; 0628 062D;;;;N;;;;; +FC07;ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM;Lo;0;AL; 0628 062E;;;;N;;;;; +FC08;ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM;Lo;0;AL; 0628 0645;;;;N;;;;; +FC09;ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0628 0649;;;;N;;;;; +FC0A;ARABIC LIGATURE BEH WITH YEH ISOLATED FORM;Lo;0;AL; 0628 064A;;;;N;;;;; +FC0B;ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM;Lo;0;AL; 062A 062C;;;;N;;;;; +FC0C;ARABIC LIGATURE TEH WITH HAH ISOLATED FORM;Lo;0;AL; 062A 062D;;;;N;;;;; +FC0D;ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM;Lo;0;AL; 062A 062E;;;;N;;;;; +FC0E;ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM;Lo;0;AL; 062A 0645;;;;N;;;;; +FC0F;ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062A 0649;;;;N;;;;; +FC10;ARABIC LIGATURE TEH WITH YEH ISOLATED FORM;Lo;0;AL; 062A 064A;;;;N;;;;; +FC11;ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM;Lo;0;AL; 062B 062C;;;;N;;;;; +FC12;ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM;Lo;0;AL; 062B 0645;;;;N;;;;; +FC13;ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062B 0649;;;;N;;;;; +FC14;ARABIC LIGATURE THEH WITH YEH ISOLATED FORM;Lo;0;AL; 062B 064A;;;;N;;;;; +FC15;ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM;Lo;0;AL; 062C 062D;;;;N;;;;; +FC16;ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM;Lo;0;AL; 062C 0645;;;;N;;;;; +FC17;ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM;Lo;0;AL; 062D 062C;;;;N;;;;; +FC18;ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM;Lo;0;AL; 062D 0645;;;;N;;;;; +FC19;ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM;Lo;0;AL; 062E 062C;;;;N;;;;; +FC1A;ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM;Lo;0;AL; 062E 062D;;;;N;;;;; +FC1B;ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM;Lo;0;AL; 062E 0645;;;;N;;;;; +FC1C;ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM;Lo;0;AL; 0633 062C;;;;N;;;;; +FC1D;ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM;Lo;0;AL; 0633 062D;;;;N;;;;; +FC1E;ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM;Lo;0;AL; 0633 062E;;;;N;;;;; +FC1F;ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM;Lo;0;AL; 0633 0645;;;;N;;;;; +FC20;ARABIC LIGATURE SAD WITH HAH ISOLATED FORM;Lo;0;AL; 0635 062D;;;;N;;;;; +FC21;ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM;Lo;0;AL; 0635 0645;;;;N;;;;; +FC22;ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM;Lo;0;AL; 0636 062C;;;;N;;;;; +FC23;ARABIC LIGATURE DAD WITH HAH ISOLATED FORM;Lo;0;AL; 0636 062D;;;;N;;;;; +FC24;ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM;Lo;0;AL; 0636 062E;;;;N;;;;; +FC25;ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM;Lo;0;AL; 0636 0645;;;;N;;;;; +FC26;ARABIC LIGATURE TAH WITH HAH ISOLATED FORM;Lo;0;AL; 0637 062D;;;;N;;;;; +FC27;ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM;Lo;0;AL; 0637 0645;;;;N;;;;; +FC28;ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM;Lo;0;AL; 0638 0645;;;;N;;;;; +FC29;ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM;Lo;0;AL; 0639 062C;;;;N;;;;; +FC2A;ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM;Lo;0;AL; 0639 0645;;;;N;;;;; +FC2B;ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM;Lo;0;AL; 063A 062C;;;;N;;;;; +FC2C;ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM;Lo;0;AL; 063A 0645;;;;N;;;;; +FC2D;ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM;Lo;0;AL; 0641 062C;;;;N;;;;; +FC2E;ARABIC LIGATURE FEH WITH HAH ISOLATED FORM;Lo;0;AL; 0641 062D;;;;N;;;;; +FC2F;ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM;Lo;0;AL; 0641 062E;;;;N;;;;; +FC30;ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM;Lo;0;AL; 0641 0645;;;;N;;;;; +FC31;ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0641 0649;;;;N;;;;; +FC32;ARABIC LIGATURE FEH WITH YEH ISOLATED FORM;Lo;0;AL; 0641 064A;;;;N;;;;; +FC33;ARABIC LIGATURE QAF WITH HAH ISOLATED FORM;Lo;0;AL; 0642 062D;;;;N;;;;; +FC34;ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM;Lo;0;AL; 0642 0645;;;;N;;;;; +FC35;ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0642 0649;;;;N;;;;; +FC36;ARABIC LIGATURE QAF WITH YEH ISOLATED FORM;Lo;0;AL; 0642 064A;;;;N;;;;; +FC37;ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM;Lo;0;AL; 0643 0627;;;;N;;;;; +FC38;ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM;Lo;0;AL; 0643 062C;;;;N;;;;; +FC39;ARABIC LIGATURE KAF WITH HAH ISOLATED FORM;Lo;0;AL; 0643 062D;;;;N;;;;; +FC3A;ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM;Lo;0;AL; 0643 062E;;;;N;;;;; +FC3B;ARABIC LIGATURE KAF WITH LAM ISOLATED FORM;Lo;0;AL; 0643 0644;;;;N;;;;; +FC3C;ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM;Lo;0;AL; 0643 0645;;;;N;;;;; +FC3D;ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0643 0649;;;;N;;;;; +FC3E;ARABIC LIGATURE KAF WITH YEH ISOLATED FORM;Lo;0;AL; 0643 064A;;;;N;;;;; +FC3F;ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM;Lo;0;AL; 0644 062C;;;;N;;;;; +FC40;ARABIC LIGATURE LAM WITH HAH ISOLATED FORM;Lo;0;AL; 0644 062D;;;;N;;;;; +FC41;ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM;Lo;0;AL; 0644 062E;;;;N;;;;; +FC42;ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM;Lo;0;AL; 0644 0645;;;;N;;;;; +FC43;ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0644 0649;;;;N;;;;; +FC44;ARABIC LIGATURE LAM WITH YEH ISOLATED FORM;Lo;0;AL; 0644 064A;;;;N;;;;; +FC45;ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM;Lo;0;AL; 0645 062C;;;;N;;;;; +FC46;ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM;Lo;0;AL; 0645 062D;;;;N;;;;; +FC47;ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM;Lo;0;AL; 0645 062E;;;;N;;;;; +FC48;ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM;Lo;0;AL; 0645 0645;;;;N;;;;; +FC49;ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0645 0649;;;;N;;;;; +FC4A;ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM;Lo;0;AL; 0645 064A;;;;N;;;;; +FC4B;ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM;Lo;0;AL; 0646 062C;;;;N;;;;; +FC4C;ARABIC LIGATURE NOON WITH HAH ISOLATED FORM;Lo;0;AL; 0646 062D;;;;N;;;;; +FC4D;ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM;Lo;0;AL; 0646 062E;;;;N;;;;; +FC4E;ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM;Lo;0;AL; 0646 0645;;;;N;;;;; +FC4F;ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0646 0649;;;;N;;;;; +FC50;ARABIC LIGATURE NOON WITH YEH ISOLATED FORM;Lo;0;AL; 0646 064A;;;;N;;;;; +FC51;ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM;Lo;0;AL; 0647 062C;;;;N;;;;; +FC52;ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM;Lo;0;AL; 0647 0645;;;;N;;;;; +FC53;ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0647 0649;;;;N;;;;; +FC54;ARABIC LIGATURE HEH WITH YEH ISOLATED FORM;Lo;0;AL; 0647 064A;;;;N;;;;; +FC55;ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM;Lo;0;AL; 064A 062C;;;;N;;;;; +FC56;ARABIC LIGATURE YEH WITH HAH ISOLATED FORM;Lo;0;AL; 064A 062D;;;;N;;;;; +FC57;ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM;Lo;0;AL; 064A 062E;;;;N;;;;; +FC58;ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM;Lo;0;AL; 064A 0645;;;;N;;;;; +FC59;ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 064A 0649;;;;N;;;;; +FC5A;ARABIC LIGATURE YEH WITH YEH ISOLATED FORM;Lo;0;AL; 064A 064A;;;;N;;;;; +FC5B;ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0630 0670;;;;N;;;;; +FC5C;ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0631 0670;;;;N;;;;; +FC5D;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0649 0670;;;;N;;;;; +FC5E;ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM;Lo;0;AL; 0020 064C 0651;;;;N;;;;; +FC5F;ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM;Lo;0;AL; 0020 064D 0651;;;;N;;;;; +FC60;ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM;Lo;0;AL; 0020 064E 0651;;;;N;;;;; +FC61;ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM;Lo;0;AL; 0020 064F 0651;;;;N;;;;; +FC62;ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM;Lo;0;AL; 0020 0650 0651;;;;N;;;;; +FC63;ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0020 0651 0670;;;;N;;;;; +FC64;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM;Lo;0;AL; 0626 0631;;;;N;;;;; +FC65;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM;Lo;0;AL; 0626 0632;;;;N;;;;; +FC66;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM;Lo;0;AL; 0626 0645;;;;N;;;;; +FC67;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM;Lo;0;AL; 0626 0646;;;;N;;;;; +FC68;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0626 0649;;;;N;;;;; +FC69;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM;Lo;0;AL; 0626 064A;;;;N;;;;; +FC6A;ARABIC LIGATURE BEH WITH REH FINAL FORM;Lo;0;AL; 0628 0631;;;;N;;;;; +FC6B;ARABIC LIGATURE BEH WITH ZAIN FINAL FORM;Lo;0;AL; 0628 0632;;;;N;;;;; +FC6C;ARABIC LIGATURE BEH WITH MEEM FINAL FORM;Lo;0;AL; 0628 0645;;;;N;;;;; +FC6D;ARABIC LIGATURE BEH WITH NOON FINAL FORM;Lo;0;AL; 0628 0646;;;;N;;;;; +FC6E;ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0628 0649;;;;N;;;;; +FC6F;ARABIC LIGATURE BEH WITH YEH FINAL FORM;Lo;0;AL; 0628 064A;;;;N;;;;; +FC70;ARABIC LIGATURE TEH WITH REH FINAL FORM;Lo;0;AL; 062A 0631;;;;N;;;;; +FC71;ARABIC LIGATURE TEH WITH ZAIN FINAL FORM;Lo;0;AL; 062A 0632;;;;N;;;;; +FC72;ARABIC LIGATURE TEH WITH MEEM FINAL FORM;Lo;0;AL; 062A 0645;;;;N;;;;; +FC73;ARABIC LIGATURE TEH WITH NOON FINAL FORM;Lo;0;AL; 062A 0646;;;;N;;;;; +FC74;ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 0649;;;;N;;;;; +FC75;ARABIC LIGATURE TEH WITH YEH FINAL FORM;Lo;0;AL; 062A 064A;;;;N;;;;; +FC76;ARABIC LIGATURE THEH WITH REH FINAL FORM;Lo;0;AL; 062B 0631;;;;N;;;;; +FC77;ARABIC LIGATURE THEH WITH ZAIN FINAL FORM;Lo;0;AL; 062B 0632;;;;N;;;;; +FC78;ARABIC LIGATURE THEH WITH MEEM FINAL FORM;Lo;0;AL; 062B 0645;;;;N;;;;; +FC79;ARABIC LIGATURE THEH WITH NOON FINAL FORM;Lo;0;AL; 062B 0646;;;;N;;;;; +FC7A;ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062B 0649;;;;N;;;;; +FC7B;ARABIC LIGATURE THEH WITH YEH FINAL FORM;Lo;0;AL; 062B 064A;;;;N;;;;; +FC7C;ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0641 0649;;;;N;;;;; +FC7D;ARABIC LIGATURE FEH WITH YEH FINAL FORM;Lo;0;AL; 0641 064A;;;;N;;;;; +FC7E;ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0642 0649;;;;N;;;;; +FC7F;ARABIC LIGATURE QAF WITH YEH FINAL FORM;Lo;0;AL; 0642 064A;;;;N;;;;; +FC80;ARABIC LIGATURE KAF WITH ALEF FINAL FORM;Lo;0;AL; 0643 0627;;;;N;;;;; +FC81;ARABIC LIGATURE KAF WITH LAM FINAL FORM;Lo;0;AL; 0643 0644;;;;N;;;;; +FC82;ARABIC LIGATURE KAF WITH MEEM FINAL FORM;Lo;0;AL; 0643 0645;;;;N;;;;; +FC83;ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0643 0649;;;;N;;;;; +FC84;ARABIC LIGATURE KAF WITH YEH FINAL FORM;Lo;0;AL; 0643 064A;;;;N;;;;; +FC85;ARABIC LIGATURE LAM WITH MEEM FINAL FORM;Lo;0;AL; 0644 0645;;;;N;;;;; +FC86;ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0644 0649;;;;N;;;;; +FC87;ARABIC LIGATURE LAM WITH YEH FINAL FORM;Lo;0;AL; 0644 064A;;;;N;;;;; +FC88;ARABIC LIGATURE MEEM WITH ALEF FINAL FORM;Lo;0;AL; 0645 0627;;;;N;;;;; +FC89;ARABIC LIGATURE MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0645 0645;;;;N;;;;; +FC8A;ARABIC LIGATURE NOON WITH REH FINAL FORM;Lo;0;AL; 0646 0631;;;;N;;;;; +FC8B;ARABIC LIGATURE NOON WITH ZAIN FINAL FORM;Lo;0;AL; 0646 0632;;;;N;;;;; +FC8C;ARABIC LIGATURE NOON WITH MEEM FINAL FORM;Lo;0;AL; 0646 0645;;;;N;;;;; +FC8D;ARABIC LIGATURE NOON WITH NOON FINAL FORM;Lo;0;AL; 0646 0646;;;;N;;;;; +FC8E;ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 0649;;;;N;;;;; +FC8F;ARABIC LIGATURE NOON WITH YEH FINAL FORM;Lo;0;AL; 0646 064A;;;;N;;;;; +FC90;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM;Lo;0;AL; 0649 0670;;;;N;;;;; +FC91;ARABIC LIGATURE YEH WITH REH FINAL FORM;Lo;0;AL; 064A 0631;;;;N;;;;; +FC92;ARABIC LIGATURE YEH WITH ZAIN FINAL FORM;Lo;0;AL; 064A 0632;;;;N;;;;; +FC93;ARABIC LIGATURE YEH WITH MEEM FINAL FORM;Lo;0;AL; 064A 0645;;;;N;;;;; +FC94;ARABIC LIGATURE YEH WITH NOON FINAL FORM;Lo;0;AL; 064A 0646;;;;N;;;;; +FC95;ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 064A 0649;;;;N;;;;; +FC96;ARABIC LIGATURE YEH WITH YEH FINAL FORM;Lo;0;AL; 064A 064A;;;;N;;;;; +FC97;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM;Lo;0;AL; 0626 062C;;;;N;;;;; +FC98;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM;Lo;0;AL; 0626 062D;;;;N;;;;; +FC99;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM;Lo;0;AL; 0626 062E;;;;N;;;;; +FC9A;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM;Lo;0;AL; 0626 0645;;;;N;;;;; +FC9B;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM;Lo;0;AL; 0626 0647;;;;N;;;;; +FC9C;ARABIC LIGATURE BEH WITH JEEM INITIAL FORM;Lo;0;AL; 0628 062C;;;;N;;;;; +FC9D;ARABIC LIGATURE BEH WITH HAH INITIAL FORM;Lo;0;AL; 0628 062D;;;;N;;;;; +FC9E;ARABIC LIGATURE BEH WITH KHAH INITIAL FORM;Lo;0;AL; 0628 062E;;;;N;;;;; +FC9F;ARABIC LIGATURE BEH WITH MEEM INITIAL FORM;Lo;0;AL; 0628 0645;;;;N;;;;; +FCA0;ARABIC LIGATURE BEH WITH HEH INITIAL FORM;Lo;0;AL; 0628 0647;;;;N;;;;; +FCA1;ARABIC LIGATURE TEH WITH JEEM INITIAL FORM;Lo;0;AL; 062A 062C;;;;N;;;;; +FCA2;ARABIC LIGATURE TEH WITH HAH INITIAL FORM;Lo;0;AL; 062A 062D;;;;N;;;;; +FCA3;ARABIC LIGATURE TEH WITH KHAH INITIAL FORM;Lo;0;AL; 062A 062E;;;;N;;;;; +FCA4;ARABIC LIGATURE TEH WITH MEEM INITIAL FORM;Lo;0;AL; 062A 0645;;;;N;;;;; +FCA5;ARABIC LIGATURE TEH WITH HEH INITIAL FORM;Lo;0;AL; 062A 0647;;;;N;;;;; +FCA6;ARABIC LIGATURE THEH WITH MEEM INITIAL FORM;Lo;0;AL; 062B 0645;;;;N;;;;; +FCA7;ARABIC LIGATURE JEEM WITH HAH INITIAL FORM;Lo;0;AL; 062C 062D;;;;N;;;;; +FCA8;ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 062C 0645;;;;N;;;;; +FCA9;ARABIC LIGATURE HAH WITH JEEM INITIAL FORM;Lo;0;AL; 062D 062C;;;;N;;;;; +FCAA;ARABIC LIGATURE HAH WITH MEEM INITIAL FORM;Lo;0;AL; 062D 0645;;;;N;;;;; +FCAB;ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM;Lo;0;AL; 062E 062C;;;;N;;;;; +FCAC;ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 062E 0645;;;;N;;;;; +FCAD;ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM;Lo;0;AL; 0633 062C;;;;N;;;;; +FCAE;ARABIC LIGATURE SEEN WITH HAH INITIAL FORM;Lo;0;AL; 0633 062D;;;;N;;;;; +FCAF;ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM;Lo;0;AL; 0633 062E;;;;N;;;;; +FCB0;ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM;Lo;0;AL; 0633 0645;;;;N;;;;; +FCB1;ARABIC LIGATURE SAD WITH HAH INITIAL FORM;Lo;0;AL; 0635 062D;;;;N;;;;; +FCB2;ARABIC LIGATURE SAD WITH KHAH INITIAL FORM;Lo;0;AL; 0635 062E;;;;N;;;;; +FCB3;ARABIC LIGATURE SAD WITH MEEM INITIAL FORM;Lo;0;AL; 0635 0645;;;;N;;;;; +FCB4;ARABIC LIGATURE DAD WITH JEEM INITIAL FORM;Lo;0;AL; 0636 062C;;;;N;;;;; +FCB5;ARABIC LIGATURE DAD WITH HAH INITIAL FORM;Lo;0;AL; 0636 062D;;;;N;;;;; +FCB6;ARABIC LIGATURE DAD WITH KHAH INITIAL FORM;Lo;0;AL; 0636 062E;;;;N;;;;; +FCB7;ARABIC LIGATURE DAD WITH MEEM INITIAL FORM;Lo;0;AL; 0636 0645;;;;N;;;;; +FCB8;ARABIC LIGATURE TAH WITH HAH INITIAL FORM;Lo;0;AL; 0637 062D;;;;N;;;;; +FCB9;ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM;Lo;0;AL; 0638 0645;;;;N;;;;; +FCBA;ARABIC LIGATURE AIN WITH JEEM INITIAL FORM;Lo;0;AL; 0639 062C;;;;N;;;;; +FCBB;ARABIC LIGATURE AIN WITH MEEM INITIAL FORM;Lo;0;AL; 0639 0645;;;;N;;;;; +FCBC;ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM;Lo;0;AL; 063A 062C;;;;N;;;;; +FCBD;ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM;Lo;0;AL; 063A 0645;;;;N;;;;; +FCBE;ARABIC LIGATURE FEH WITH JEEM INITIAL FORM;Lo;0;AL; 0641 062C;;;;N;;;;; +FCBF;ARABIC LIGATURE FEH WITH HAH INITIAL FORM;Lo;0;AL; 0641 062D;;;;N;;;;; +FCC0;ARABIC LIGATURE FEH WITH KHAH INITIAL FORM;Lo;0;AL; 0641 062E;;;;N;;;;; +FCC1;ARABIC LIGATURE FEH WITH MEEM INITIAL FORM;Lo;0;AL; 0641 0645;;;;N;;;;; +FCC2;ARABIC LIGATURE QAF WITH HAH INITIAL FORM;Lo;0;AL; 0642 062D;;;;N;;;;; +FCC3;ARABIC LIGATURE QAF WITH MEEM INITIAL FORM;Lo;0;AL; 0642 0645;;;;N;;;;; +FCC4;ARABIC LIGATURE KAF WITH JEEM INITIAL FORM;Lo;0;AL; 0643 062C;;;;N;;;;; +FCC5;ARABIC LIGATURE KAF WITH HAH INITIAL FORM;Lo;0;AL; 0643 062D;;;;N;;;;; +FCC6;ARABIC LIGATURE KAF WITH KHAH INITIAL FORM;Lo;0;AL; 0643 062E;;;;N;;;;; +FCC7;ARABIC LIGATURE KAF WITH LAM INITIAL FORM;Lo;0;AL; 0643 0644;;;;N;;;;; +FCC8;ARABIC LIGATURE KAF WITH MEEM INITIAL FORM;Lo;0;AL; 0643 0645;;;;N;;;;; +FCC9;ARABIC LIGATURE LAM WITH JEEM INITIAL FORM;Lo;0;AL; 0644 062C;;;;N;;;;; +FCCA;ARABIC LIGATURE LAM WITH HAH INITIAL FORM;Lo;0;AL; 0644 062D;;;;N;;;;; +FCCB;ARABIC LIGATURE LAM WITH KHAH INITIAL FORM;Lo;0;AL; 0644 062E;;;;N;;;;; +FCCC;ARABIC LIGATURE LAM WITH MEEM INITIAL FORM;Lo;0;AL; 0644 0645;;;;N;;;;; +FCCD;ARABIC LIGATURE LAM WITH HEH INITIAL FORM;Lo;0;AL; 0644 0647;;;;N;;;;; +FCCE;ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0645 062C;;;;N;;;;; +FCCF;ARABIC LIGATURE MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0645 062D;;;;N;;;;; +FCD0;ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM;Lo;0;AL; 0645 062E;;;;N;;;;; +FCD1;ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0645 0645;;;;N;;;;; +FCD2;ARABIC LIGATURE NOON WITH JEEM INITIAL FORM;Lo;0;AL; 0646 062C;;;;N;;;;; +FCD3;ARABIC LIGATURE NOON WITH HAH INITIAL FORM;Lo;0;AL; 0646 062D;;;;N;;;;; +FCD4;ARABIC LIGATURE NOON WITH KHAH INITIAL FORM;Lo;0;AL; 0646 062E;;;;N;;;;; +FCD5;ARABIC LIGATURE NOON WITH MEEM INITIAL FORM;Lo;0;AL; 0646 0645;;;;N;;;;; +FCD6;ARABIC LIGATURE NOON WITH HEH INITIAL FORM;Lo;0;AL; 0646 0647;;;;N;;;;; +FCD7;ARABIC LIGATURE HEH WITH JEEM INITIAL FORM;Lo;0;AL; 0647 062C;;;;N;;;;; +FCD8;ARABIC LIGATURE HEH WITH MEEM INITIAL FORM;Lo;0;AL; 0647 0645;;;;N;;;;; +FCD9;ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM;Lo;0;AL; 0647 0670;;;;N;;;;; +FCDA;ARABIC LIGATURE YEH WITH JEEM INITIAL FORM;Lo;0;AL; 064A 062C;;;;N;;;;; +FCDB;ARABIC LIGATURE YEH WITH HAH INITIAL FORM;Lo;0;AL; 064A 062D;;;;N;;;;; +FCDC;ARABIC LIGATURE YEH WITH KHAH INITIAL FORM;Lo;0;AL; 064A 062E;;;;N;;;;; +FCDD;ARABIC LIGATURE YEH WITH MEEM INITIAL FORM;Lo;0;AL; 064A 0645;;;;N;;;;; +FCDE;ARABIC LIGATURE YEH WITH HEH INITIAL FORM;Lo;0;AL; 064A 0647;;;;N;;;;; +FCDF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM;Lo;0;AL; 0626 0645;;;;N;;;;; +FCE0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM;Lo;0;AL; 0626 0647;;;;N;;;;; +FCE1;ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM;Lo;0;AL; 0628 0645;;;;N;;;;; +FCE2;ARABIC LIGATURE BEH WITH HEH MEDIAL FORM;Lo;0;AL; 0628 0647;;;;N;;;;; +FCE3;ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM;Lo;0;AL; 062A 0645;;;;N;;;;; +FCE4;ARABIC LIGATURE TEH WITH HEH MEDIAL FORM;Lo;0;AL; 062A 0647;;;;N;;;;; +FCE5;ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM;Lo;0;AL; 062B 0645;;;;N;;;;; +FCE6;ARABIC LIGATURE THEH WITH HEH MEDIAL FORM;Lo;0;AL; 062B 0647;;;;N;;;;; +FCE7;ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM;Lo;0;AL; 0633 0645;;;;N;;;;; +FCE8;ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM;Lo;0;AL; 0633 0647;;;;N;;;;; +FCE9;ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM;Lo;0;AL; 0634 0645;;;;N;;;;; +FCEA;ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM;Lo;0;AL; 0634 0647;;;;N;;;;; +FCEB;ARABIC LIGATURE KAF WITH LAM MEDIAL FORM;Lo;0;AL; 0643 0644;;;;N;;;;; +FCEC;ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM;Lo;0;AL; 0643 0645;;;;N;;;;; +FCED;ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM;Lo;0;AL; 0644 0645;;;;N;;;;; +FCEE;ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM;Lo;0;AL; 0646 0645;;;;N;;;;; +FCEF;ARABIC LIGATURE NOON WITH HEH MEDIAL FORM;Lo;0;AL; 0646 0647;;;;N;;;;; +FCF0;ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM;Lo;0;AL; 064A 0645;;;;N;;;;; +FCF1;ARABIC LIGATURE YEH WITH HEH MEDIAL FORM;Lo;0;AL; 064A 0647;;;;N;;;;; +FCF2;ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM;Lo;0;AL; 0640 064E 0651;;;;N;;;;; +FCF3;ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM;Lo;0;AL; 0640 064F 0651;;;;N;;;;; +FCF4;ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM;Lo;0;AL; 0640 0650 0651;;;;N;;;;; +FCF5;ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0637 0649;;;;N;;;;; +FCF6;ARABIC LIGATURE TAH WITH YEH ISOLATED FORM;Lo;0;AL; 0637 064A;;;;N;;;;; +FCF7;ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0639 0649;;;;N;;;;; +FCF8;ARABIC LIGATURE AIN WITH YEH ISOLATED FORM;Lo;0;AL; 0639 064A;;;;N;;;;; +FCF9;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 063A 0649;;;;N;;;;; +FCFA;ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM;Lo;0;AL; 063A 064A;;;;N;;;;; +FCFB;ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0633 0649;;;;N;;;;; +FCFC;ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM;Lo;0;AL; 0633 064A;;;;N;;;;; +FCFD;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0634 0649;;;;N;;;;; +FCFE;ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM;Lo;0;AL; 0634 064A;;;;N;;;;; +FCFF;ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062D 0649;;;;N;;;;; +FD00;ARABIC LIGATURE HAH WITH YEH ISOLATED FORM;Lo;0;AL; 062D 064A;;;;N;;;;; +FD01;ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062C 0649;;;;N;;;;; +FD02;ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM;Lo;0;AL; 062C 064A;;;;N;;;;; +FD03;ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062E 0649;;;;N;;;;; +FD04;ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM;Lo;0;AL; 062E 064A;;;;N;;;;; +FD05;ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0635 0649;;;;N;;;;; +FD06;ARABIC LIGATURE SAD WITH YEH ISOLATED FORM;Lo;0;AL; 0635 064A;;;;N;;;;; +FD07;ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0636 0649;;;;N;;;;; +FD08;ARABIC LIGATURE DAD WITH YEH ISOLATED FORM;Lo;0;AL; 0636 064A;;;;N;;;;; +FD09;ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM;Lo;0;AL; 0634 062C;;;;N;;;;; +FD0A;ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM;Lo;0;AL; 0634 062D;;;;N;;;;; +FD0B;ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM;Lo;0;AL; 0634 062E;;;;N;;;;; +FD0C;ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM;Lo;0;AL; 0634 0645;;;;N;;;;; +FD0D;ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM;Lo;0;AL; 0634 0631;;;;N;;;;; +FD0E;ARABIC LIGATURE SEEN WITH REH ISOLATED FORM;Lo;0;AL; 0633 0631;;;;N;;;;; +FD0F;ARABIC LIGATURE SAD WITH REH ISOLATED FORM;Lo;0;AL; 0635 0631;;;;N;;;;; +FD10;ARABIC LIGATURE DAD WITH REH ISOLATED FORM;Lo;0;AL; 0636 0631;;;;N;;;;; +FD11;ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0637 0649;;;;N;;;;; +FD12;ARABIC LIGATURE TAH WITH YEH FINAL FORM;Lo;0;AL; 0637 064A;;;;N;;;;; +FD13;ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0639 0649;;;;N;;;;; +FD14;ARABIC LIGATURE AIN WITH YEH FINAL FORM;Lo;0;AL; 0639 064A;;;;N;;;;; +FD15;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 063A 0649;;;;N;;;;; +FD16;ARABIC LIGATURE GHAIN WITH YEH FINAL FORM;Lo;0;AL; 063A 064A;;;;N;;;;; +FD17;ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0633 0649;;;;N;;;;; +FD18;ARABIC LIGATURE SEEN WITH YEH FINAL FORM;Lo;0;AL; 0633 064A;;;;N;;;;; +FD19;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0634 0649;;;;N;;;;; +FD1A;ARABIC LIGATURE SHEEN WITH YEH FINAL FORM;Lo;0;AL; 0634 064A;;;;N;;;;; +FD1B;ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062D 0649;;;;N;;;;; +FD1C;ARABIC LIGATURE HAH WITH YEH FINAL FORM;Lo;0;AL; 062D 064A;;;;N;;;;; +FD1D;ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062C 0649;;;;N;;;;; +FD1E;ARABIC LIGATURE JEEM WITH YEH FINAL FORM;Lo;0;AL; 062C 064A;;;;N;;;;; +FD1F;ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062E 0649;;;;N;;;;; +FD20;ARABIC LIGATURE KHAH WITH YEH FINAL FORM;Lo;0;AL; 062E 064A;;;;N;;;;; +FD21;ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0635 0649;;;;N;;;;; +FD22;ARABIC LIGATURE SAD WITH YEH FINAL FORM;Lo;0;AL; 0635 064A;;;;N;;;;; +FD23;ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0636 0649;;;;N;;;;; +FD24;ARABIC LIGATURE DAD WITH YEH FINAL FORM;Lo;0;AL; 0636 064A;;;;N;;;;; +FD25;ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM;Lo;0;AL; 0634 062C;;;;N;;;;; +FD26;ARABIC LIGATURE SHEEN WITH HAH FINAL FORM;Lo;0;AL; 0634 062D;;;;N;;;;; +FD27;ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM;Lo;0;AL; 0634 062E;;;;N;;;;; +FD28;ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM;Lo;0;AL; 0634 0645;;;;N;;;;; +FD29;ARABIC LIGATURE SHEEN WITH REH FINAL FORM;Lo;0;AL; 0634 0631;;;;N;;;;; +FD2A;ARABIC LIGATURE SEEN WITH REH FINAL FORM;Lo;0;AL; 0633 0631;;;;N;;;;; +FD2B;ARABIC LIGATURE SAD WITH REH FINAL FORM;Lo;0;AL; 0635 0631;;;;N;;;;; +FD2C;ARABIC LIGATURE DAD WITH REH FINAL FORM;Lo;0;AL; 0636 0631;;;;N;;;;; +FD2D;ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM;Lo;0;AL; 0634 062C;;;;N;;;;; +FD2E;ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM;Lo;0;AL; 0634 062D;;;;N;;;;; +FD2F;ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM;Lo;0;AL; 0634 062E;;;;N;;;;; +FD30;ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM;Lo;0;AL; 0634 0645;;;;N;;;;; +FD31;ARABIC LIGATURE SEEN WITH HEH INITIAL FORM;Lo;0;AL; 0633 0647;;;;N;;;;; +FD32;ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM;Lo;0;AL; 0634 0647;;;;N;;;;; +FD33;ARABIC LIGATURE TAH WITH MEEM INITIAL FORM;Lo;0;AL; 0637 0645;;;;N;;;;; +FD34;ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM;Lo;0;AL; 0633 062C;;;;N;;;;; +FD35;ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM;Lo;0;AL; 0633 062D;;;;N;;;;; +FD36;ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM;Lo;0;AL; 0633 062E;;;;N;;;;; +FD37;ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM;Lo;0;AL; 0634 062C;;;;N;;;;; +FD38;ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM;Lo;0;AL; 0634 062D;;;;N;;;;; +FD39;ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM;Lo;0;AL; 0634 062E;;;;N;;;;; +FD3A;ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM;Lo;0;AL; 0637 0645;;;;N;;;;; +FD3B;ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM;Lo;0;AL; 0638 0645;;;;N;;;;; +FD3C;ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM;Lo;0;AL; 0627 064B;;;;N;;;;; +FD3D;ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM;Lo;0;AL; 0627 064B;;;;N;;;;; +FD3E;ORNATE LEFT PARENTHESIS;Pe;0;ON;;;;;N;;;;; +FD3F;ORNATE RIGHT PARENTHESIS;Ps;0;ON;;;;;N;;;;; +FD50;ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 062A 062C 0645;;;;N;;;;; +FD51;ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM;Lo;0;AL; 062A 062D 062C;;;;N;;;;; +FD52;ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL; 062A 062D 062C;;;;N;;;;; +FD53;ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 062A 062D 0645;;;;N;;;;; +FD54;ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 062A 062E 0645;;;;N;;;;; +FD55;ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 062A 0645 062C;;;;N;;;;; +FD56;ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 062A 0645 062D;;;;N;;;;; +FD57;ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL; 062A 0645 062E;;;;N;;;;; +FD58;ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 062C 0645 062D;;;;N;;;;; +FD59;ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 062C 0645 062D;;;;N;;;;; +FD5A;ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 062D 0645 064A;;;;N;;;;; +FD5B;ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062D 0645 0649;;;;N;;;;; +FD5C;ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL; 0633 062D 062C;;;;N;;;;; +FD5D;ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL; 0633 062C 062D;;;;N;;;;; +FD5E;ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0633 062C 0649;;;;N;;;;; +FD5F;ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0633 0645 062D;;;;N;;;;; +FD60;ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0633 0645 062D;;;;N;;;;; +FD61;ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0633 0645 062C;;;;N;;;;; +FD62;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0633 0645 0645;;;;N;;;;; +FD63;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0633 0645 0645;;;;N;;;;; +FD64;ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM;Lo;0;AL; 0635 062D 062D;;;;N;;;;; +FD65;ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM;Lo;0;AL; 0635 062D 062D;;;;N;;;;; +FD66;ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0635 0645 0645;;;;N;;;;; +FD67;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM;Lo;0;AL; 0634 062D 0645;;;;N;;;;; +FD68;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0634 062D 0645;;;;N;;;;; +FD69;ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0634 062C 064A;;;;N;;;;; +FD6A;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM;Lo;0;AL; 0634 0645 062E;;;;N;;;;; +FD6B;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL; 0634 0645 062E;;;;N;;;;; +FD6C;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0634 0645 0645;;;;N;;;;; +FD6D;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0634 0645 0645;;;;N;;;;; +FD6E;ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0636 062D 0649;;;;N;;;;; +FD6F;ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL; 0636 062E 0645;;;;N;;;;; +FD70;ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0636 062E 0645;;;;N;;;;; +FD71;ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0637 0645 062D;;;;N;;;;; +FD72;ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0637 0645 062D;;;;N;;;;; +FD73;ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0637 0645 0645;;;;N;;;;; +FD74;ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0637 0645 064A;;;;N;;;;; +FD75;ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL; 0639 062C 0645;;;;N;;;;; +FD76;ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0639 0645 0645;;;;N;;;;; +FD77;ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0639 0645 0645;;;;N;;;;; +FD78;ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0639 0645 0649;;;;N;;;;; +FD79;ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 063A 0645 0645;;;;N;;;;; +FD7A;ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 063A 0645 064A;;;;N;;;;; +FD7B;ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 063A 0645 0649;;;;N;;;;; +FD7C;ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL; 0641 062E 0645;;;;N;;;;; +FD7D;ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0641 062E 0645;;;;N;;;;; +FD7E;ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0642 0645 062D;;;;N;;;;; +FD7F;ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0642 0645 0645;;;;N;;;;; +FD80;ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM;Lo;0;AL; 0644 062D 0645;;;;N;;;;; +FD81;ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0644 062D 064A;;;;N;;;;; +FD82;ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0644 062D 0649;;;;N;;;;; +FD83;ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0644 062C 062C;;;;N;;;;; +FD84;ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM;Lo;0;AL; 0644 062C 062C;;;;N;;;;; +FD85;ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL; 0644 062E 0645;;;;N;;;;; +FD86;ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0644 062E 0645;;;;N;;;;; +FD87;ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0644 0645 062D;;;;N;;;;; +FD88;ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0644 0645 062D;;;;N;;;;; +FD89;ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL; 0645 062D 062C;;;;N;;;;; +FD8A;ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0645 062D 0645;;;;N;;;;; +FD8B;ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0645 062D 064A;;;;N;;;;; +FD8C;ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL; 0645 062C 062D;;;;N;;;;; +FD8D;ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0645 062C 0645;;;;N;;;;; +FD8E;ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM;Lo;0;AL; 0645 062E 062C;;;;N;;;;; +FD8F;ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0645 062E 0645;;;;N;;;;; +FD92;ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM;Lo;0;AL; 0645 062C 062E;;;;N;;;;; +FD93;ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0647 0645 062C;;;;N;;;;; +FD94;ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0647 0645 0645;;;;N;;;;; +FD95;ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0646 062D 0645;;;;N;;;;; +FD96;ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 062D 0649;;;;N;;;;; +FD97;ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL; 0646 062C 0645;;;;N;;;;; +FD98;ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0646 062C 0645;;;;N;;;;; +FD99;ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 062C 0649;;;;N;;;;; +FD9A;ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0646 0645 064A;;;;N;;;;; +FD9B;ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 0645 0649;;;;N;;;;; +FD9C;ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 064A 0645 0645;;;;N;;;;; +FD9D;ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 064A 0645 0645;;;;N;;;;; +FD9E;ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 0628 062E 064A;;;;N;;;;; +FD9F;ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 062A 062C 064A;;;;N;;;;; +FDA0;ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 062C 0649;;;;N;;;;; +FDA1;ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 062A 062E 064A;;;;N;;;;; +FDA2;ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 062E 0649;;;;N;;;;; +FDA3;ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 062A 0645 064A;;;;N;;;;; +FDA4;ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 0645 0649;;;;N;;;;; +FDA5;ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 062C 0645 064A;;;;N;;;;; +FDA6;ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062C 062D 0649;;;;N;;;;; +FDA7;ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062C 0645 0649;;;;N;;;;; +FDA8;ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0633 062E 0649;;;;N;;;;; +FDA9;ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0635 062D 064A;;;;N;;;;; +FDAA;ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0634 062D 064A;;;;N;;;;; +FDAB;ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0636 062D 064A;;;;N;;;;; +FDAC;ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0644 062C 064A;;;;N;;;;; +FDAD;ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0644 0645 064A;;;;N;;;;; +FDAE;ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 064A 062D 064A;;;;N;;;;; +FDAF;ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 064A 062C 064A;;;;N;;;;; +FDB0;ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 064A 0645 064A;;;;N;;;;; +FDB1;ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0645 0645 064A;;;;N;;;;; +FDB2;ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0642 0645 064A;;;;N;;;;; +FDB3;ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0646 062D 064A;;;;N;;;;; +FDB4;ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0642 0645 062D;;;;N;;;;; +FDB5;ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0644 062D 0645;;;;N;;;;; +FDB6;ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0639 0645 064A;;;;N;;;;; +FDB7;ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0643 0645 064A;;;;N;;;;; +FDB8;ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL; 0646 062C 062D;;;;N;;;;; +FDB9;ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 0645 062E 064A;;;;N;;;;; +FDBA;ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0644 062C 0645;;;;N;;;;; +FDBB;ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0643 0645 0645;;;;N;;;;; +FDBC;ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL; 0644 062C 0645;;;;N;;;;; +FDBD;ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM;Lo;0;AL; 0646 062C 062D;;;;N;;;;; +FDBE;ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 062C 062D 064A;;;;N;;;;; +FDBF;ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 062D 062C 064A;;;;N;;;;; +FDC0;ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0645 062C 064A;;;;N;;;;; +FDC1;ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0641 0645 064A;;;;N;;;;; +FDC2;ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0628 062D 064A;;;;N;;;;; +FDC3;ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0643 0645 0645;;;;N;;;;; +FDC4;ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0639 062C 0645;;;;N;;;;; +FDC5;ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0635 0645 0645;;;;N;;;;; +FDC6;ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 0633 062E 064A;;;;N;;;;; +FDC7;ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0646 062C 064A;;;;N;;;;; +FDF0;ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL; 0635 0644 06D2;;;;N;;;;; +FDF1;ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL; 0642 0644 06D2;;;;N;;;;; +FDF2;ARABIC LIGATURE ALLAH ISOLATED FORM;Lo;0;AL; 0627 0644 0644 0647;;;;N;;;;; +FDF3;ARABIC LIGATURE AKBAR ISOLATED FORM;Lo;0;AL; 0627 0643 0628 0631;;;;N;;;;; +FDF4;ARABIC LIGATURE MOHAMMAD ISOLATED FORM;Lo;0;AL; 0645 062D 0645 062F;;;;N;;;;; +FDF5;ARABIC LIGATURE SALAM ISOLATED FORM;Lo;0;AL; 0635 0644 0639 0645;;;;N;;;;; +FDF6;ARABIC LIGATURE RASOUL ISOLATED FORM;Lo;0;AL; 0631 0633 0648 0644;;;;N;;;;; +FDF7;ARABIC LIGATURE ALAYHE ISOLATED FORM;Lo;0;AL; 0639 0644 064A 0647;;;;N;;;;; +FDF8;ARABIC LIGATURE WASALLAM ISOLATED FORM;Lo;0;AL; 0648 0633 0644 0645;;;;N;;;;; +FDF9;ARABIC LIGATURE SALLA ISOLATED FORM;Lo;0;AL; 0635 0644 0649;;;;N;;;;; +FDFA;ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM;Lo;0;AL; 0635 0644 0649 0020 0627 0644 0644 0647 0020 0639 0644 064A 0647 0020 0648 0633 0644 0645;;;;N;ARABIC LETTER SALLALLAHOU ALAYHE WASALLAM;;;; +FDFB;ARABIC LIGATURE JALLAJALALOUHOU;Lo;0;AL; 062C 0644 0020 062C 0644 0627 0644 0647;;;;N;ARABIC LETTER JALLAJALALOUHOU;;;; +FDFC;RIAL SIGN;Sc;0;AL; 0631 06CC 0627 0644;;;;N;;;;; +FDFD;ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM;So;0;ON;;;;;N;;;;; +FE00;VARIATION SELECTOR-1;Mn;0;NSM;;;;;N;;;;; +FE01;VARIATION SELECTOR-2;Mn;0;NSM;;;;;N;;;;; +FE02;VARIATION SELECTOR-3;Mn;0;NSM;;;;;N;;;;; +FE03;VARIATION SELECTOR-4;Mn;0;NSM;;;;;N;;;;; +FE04;VARIATION SELECTOR-5;Mn;0;NSM;;;;;N;;;;; +FE05;VARIATION SELECTOR-6;Mn;0;NSM;;;;;N;;;;; +FE06;VARIATION SELECTOR-7;Mn;0;NSM;;;;;N;;;;; +FE07;VARIATION SELECTOR-8;Mn;0;NSM;;;;;N;;;;; +FE08;VARIATION SELECTOR-9;Mn;0;NSM;;;;;N;;;;; +FE09;VARIATION SELECTOR-10;Mn;0;NSM;;;;;N;;;;; +FE0A;VARIATION SELECTOR-11;Mn;0;NSM;;;;;N;;;;; +FE0B;VARIATION SELECTOR-12;Mn;0;NSM;;;;;N;;;;; +FE0C;VARIATION SELECTOR-13;Mn;0;NSM;;;;;N;;;;; +FE0D;VARIATION SELECTOR-14;Mn;0;NSM;;;;;N;;;;; +FE0E;VARIATION SELECTOR-15;Mn;0;NSM;;;;;N;;;;; +FE0F;VARIATION SELECTOR-16;Mn;0;NSM;;;;;N;;;;; +FE10;PRESENTATION FORM FOR VERTICAL COMMA;Po;0;ON; 002C;;;;N;;;;; +FE11;PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA;Po;0;ON; 3001;;;;N;;;;; +FE12;PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP;Po;0;ON; 3002;;;;N;;;;; +FE13;PRESENTATION FORM FOR VERTICAL COLON;Po;0;ON; 003A;;;;N;;;;; +FE14;PRESENTATION FORM FOR VERTICAL SEMICOLON;Po;0;ON; 003B;;;;N;;;;; +FE15;PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK;Po;0;ON; 0021;;;;N;;;;; +FE16;PRESENTATION FORM FOR VERTICAL QUESTION MARK;Po;0;ON; 003F;;;;N;;;;; +FE17;PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET;Ps;0;ON; 3016;;;;N;;;;; +FE18;PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET;Pe;0;ON; 3017;;;;N;;;;; +FE19;PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS;Po;0;ON; 2026;;;;N;;;;; +FE20;COMBINING LIGATURE LEFT HALF;Mn;230;NSM;;;;;N;;;;; +FE21;COMBINING LIGATURE RIGHT HALF;Mn;230;NSM;;;;;N;;;;; +FE22;COMBINING DOUBLE TILDE LEFT HALF;Mn;230;NSM;;;;;N;;;;; +FE23;COMBINING DOUBLE TILDE RIGHT HALF;Mn;230;NSM;;;;;N;;;;; +FE24;COMBINING MACRON LEFT HALF;Mn;230;NSM;;;;;N;;;;; +FE25;COMBINING MACRON RIGHT HALF;Mn;230;NSM;;;;;N;;;;; +FE26;COMBINING CONJOINING MACRON;Mn;230;NSM;;;;;N;;;;; +FE27;COMBINING LIGATURE LEFT HALF BELOW;Mn;220;NSM;;;;;N;;;;; +FE28;COMBINING LIGATURE RIGHT HALF BELOW;Mn;220;NSM;;;;;N;;;;; +FE29;COMBINING TILDE LEFT HALF BELOW;Mn;220;NSM;;;;;N;;;;; +FE2A;COMBINING TILDE RIGHT HALF BELOW;Mn;220;NSM;;;;;N;;;;; +FE2B;COMBINING MACRON LEFT HALF BELOW;Mn;220;NSM;;;;;N;;;;; +FE2C;COMBINING MACRON RIGHT HALF BELOW;Mn;220;NSM;;;;;N;;;;; +FE2D;COMBINING CONJOINING MACRON BELOW;Mn;220;NSM;;;;;N;;;;; +FE2E;COMBINING CYRILLIC TITLO LEFT HALF;Mn;230;NSM;;;;;N;;;;; +FE2F;COMBINING CYRILLIC TITLO RIGHT HALF;Mn;230;NSM;;;;;N;;;;; +FE30;PRESENTATION FORM FOR VERTICAL TWO DOT LEADER;Po;0;ON; 2025;;;;N;GLYPH FOR VERTICAL TWO DOT LEADER;;;; +FE31;PRESENTATION FORM FOR VERTICAL EM DASH;Pd;0;ON; 2014;;;;N;GLYPH FOR VERTICAL EM DASH;;;; +FE32;PRESENTATION FORM FOR VERTICAL EN DASH;Pd;0;ON; 2013;;;;N;GLYPH FOR VERTICAL EN DASH;;;; +FE33;PRESENTATION FORM FOR VERTICAL LOW LINE;Pc;0;ON; 005F;;;;N;GLYPH FOR VERTICAL SPACING UNDERSCORE;;;; +FE34;PRESENTATION FORM FOR VERTICAL WAVY LOW LINE;Pc;0;ON; 005F;;;;N;GLYPH FOR VERTICAL SPACING WAVY UNDERSCORE;;;; +FE35;PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS;Ps;0;ON; 0028;;;;N;GLYPH FOR VERTICAL OPENING PARENTHESIS;;;; +FE36;PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;N;GLYPH FOR VERTICAL CLOSING PARENTHESIS;;;; +FE37;PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET;Ps;0;ON; 007B;;;;N;GLYPH FOR VERTICAL OPENING CURLY BRACKET;;;; +FE38;PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET;Pe;0;ON; 007D;;;;N;GLYPH FOR VERTICAL CLOSING CURLY BRACKET;;;; +FE39;PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET;Ps;0;ON; 3014;;;;N;GLYPH FOR VERTICAL OPENING TORTOISE SHELL BRACKET;;;; +FE3A;PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON; 3015;;;;N;GLYPH FOR VERTICAL CLOSING TORTOISE SHELL BRACKET;;;; +FE3B;PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET;Ps;0;ON; 3010;;;;N;GLYPH FOR VERTICAL OPENING BLACK LENTICULAR BRACKET;;;; +FE3C;PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON; 3011;;;;N;GLYPH FOR VERTICAL CLOSING BLACK LENTICULAR BRACKET;;;; +FE3D;PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON; 300A;;;;N;GLYPH FOR VERTICAL OPENING DOUBLE ANGLE BRACKET;;;; +FE3E;PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON; 300B;;;;N;GLYPH FOR VERTICAL CLOSING DOUBLE ANGLE BRACKET;;;; +FE3F;PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET;Ps;0;ON; 3008;;;;N;GLYPH FOR VERTICAL OPENING ANGLE BRACKET;;;; +FE40;PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET;Pe;0;ON; 3009;;;;N;GLYPH FOR VERTICAL CLOSING ANGLE BRACKET;;;; +FE41;PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET;Ps;0;ON; 300C;;;;N;GLYPH FOR VERTICAL OPENING CORNER BRACKET;;;; +FE42;PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET;Pe;0;ON; 300D;;;;N;GLYPH FOR VERTICAL CLOSING CORNER BRACKET;;;; +FE43;PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET;Ps;0;ON; 300E;;;;N;GLYPH FOR VERTICAL OPENING WHITE CORNER BRACKET;;;; +FE44;PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET;Pe;0;ON; 300F;;;;N;GLYPH FOR VERTICAL CLOSING WHITE CORNER BRACKET;;;; +FE45;SESAME DOT;Po;0;ON;;;;;N;;;;; +FE46;WHITE SESAME DOT;Po;0;ON;;;;;N;;;;; +FE47;PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET;Ps;0;ON; 005B;;;;N;;;;; +FE48;PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET;Pe;0;ON; 005D;;;;N;;;;; +FE49;DASHED OVERLINE;Po;0;ON; 203E;;;;N;SPACING DASHED OVERSCORE;;;; +FE4A;CENTRELINE OVERLINE;Po;0;ON; 203E;;;;N;SPACING CENTERLINE OVERSCORE;;;; +FE4B;WAVY OVERLINE;Po;0;ON; 203E;;;;N;SPACING WAVY OVERSCORE;;;; +FE4C;DOUBLE WAVY OVERLINE;Po;0;ON; 203E;;;;N;SPACING DOUBLE WAVY OVERSCORE;;;; +FE4D;DASHED LOW LINE;Pc;0;ON; 005F;;;;N;SPACING DASHED UNDERSCORE;;;; +FE4E;CENTRELINE LOW LINE;Pc;0;ON; 005F;;;;N;SPACING CENTERLINE UNDERSCORE;;;; +FE4F;WAVY LOW LINE;Pc;0;ON; 005F;;;;N;SPACING WAVY UNDERSCORE;;;; +FE50;SMALL COMMA;Po;0;CS; 002C;;;;N;;;;; +FE51;SMALL IDEOGRAPHIC COMMA;Po;0;ON; 3001;;;;N;;;;; +FE52;SMALL FULL STOP;Po;0;CS; 002E;;;;N;SMALL PERIOD;;;; +FE54;SMALL SEMICOLON;Po;0;ON; 003B;;;;N;;;;; +FE55;SMALL COLON;Po;0;CS; 003A;;;;N;;;;; +FE56;SMALL QUESTION MARK;Po;0;ON; 003F;;;;N;;;;; +FE57;SMALL EXCLAMATION MARK;Po;0;ON; 0021;;;;N;;;;; +FE58;SMALL EM DASH;Pd;0;ON; 2014;;;;N;;;;; +FE59;SMALL LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;SMALL OPENING PARENTHESIS;;;; +FE5A;SMALL RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;SMALL CLOSING PARENTHESIS;;;; +FE5B;SMALL LEFT CURLY BRACKET;Ps;0;ON; 007B;;;;Y;SMALL OPENING CURLY BRACKET;;;; +FE5C;SMALL RIGHT CURLY BRACKET;Pe;0;ON; 007D;;;;Y;SMALL CLOSING CURLY BRACKET;;;; +FE5D;SMALL LEFT TORTOISE SHELL BRACKET;Ps;0;ON; 3014;;;;Y;SMALL OPENING TORTOISE SHELL BRACKET;;;; +FE5E;SMALL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON; 3015;;;;Y;SMALL CLOSING TORTOISE SHELL BRACKET;;;; +FE5F;SMALL NUMBER SIGN;Po;0;ET; 0023;;;;N;;;;; +FE60;SMALL AMPERSAND;Po;0;ON; 0026;;;;N;;;;; +FE61;SMALL ASTERISK;Po;0;ON; 002A;;;;N;;;;; +FE62;SMALL PLUS SIGN;Sm;0;ES; 002B;;;;N;;;;; +FE63;SMALL HYPHEN-MINUS;Pd;0;ES; 002D;;;;N;;;;; +FE64;SMALL LESS-THAN SIGN;Sm;0;ON; 003C;;;;Y;;;;; +FE65;SMALL GREATER-THAN SIGN;Sm;0;ON; 003E;;;;Y;;;;; +FE66;SMALL EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; +FE68;SMALL REVERSE SOLIDUS;Po;0;ON; 005C;;;;N;SMALL BACKSLASH;;;; +FE69;SMALL DOLLAR SIGN;Sc;0;ET; 0024;;;;N;;;;; +FE6A;SMALL PERCENT SIGN;Po;0;ET; 0025;;;;N;;;;; +FE6B;SMALL COMMERCIAL AT;Po;0;ON; 0040;;;;N;;;;; +FE70;ARABIC FATHATAN ISOLATED FORM;Lo;0;AL; 0020 064B;;;;N;ARABIC SPACING FATHATAN;;;; +FE71;ARABIC TATWEEL WITH FATHATAN ABOVE;Lo;0;AL; 0640 064B;;;;N;ARABIC FATHATAN ON TATWEEL;;;; +FE72;ARABIC DAMMATAN ISOLATED FORM;Lo;0;AL; 0020 064C;;;;N;ARABIC SPACING DAMMATAN;;;; +FE73;ARABIC TAIL FRAGMENT;Lo;0;AL;;;;;N;;;;; +FE74;ARABIC KASRATAN ISOLATED FORM;Lo;0;AL; 0020 064D;;;;N;ARABIC SPACING KASRATAN;;;; +FE76;ARABIC FATHA ISOLATED FORM;Lo;0;AL; 0020 064E;;;;N;ARABIC SPACING FATHAH;;;; +FE77;ARABIC FATHA MEDIAL FORM;Lo;0;AL; 0640 064E;;;;N;ARABIC FATHAH ON TATWEEL;;;; +FE78;ARABIC DAMMA ISOLATED FORM;Lo;0;AL; 0020 064F;;;;N;ARABIC SPACING DAMMAH;;;; +FE79;ARABIC DAMMA MEDIAL FORM;Lo;0;AL; 0640 064F;;;;N;ARABIC DAMMAH ON TATWEEL;;;; +FE7A;ARABIC KASRA ISOLATED FORM;Lo;0;AL; 0020 0650;;;;N;ARABIC SPACING KASRAH;;;; +FE7B;ARABIC KASRA MEDIAL FORM;Lo;0;AL; 0640 0650;;;;N;ARABIC KASRAH ON TATWEEL;;;; +FE7C;ARABIC SHADDA ISOLATED FORM;Lo;0;AL; 0020 0651;;;;N;ARABIC SPACING SHADDAH;;;; +FE7D;ARABIC SHADDA MEDIAL FORM;Lo;0;AL; 0640 0651;;;;N;ARABIC SHADDAH ON TATWEEL;;;; +FE7E;ARABIC SUKUN ISOLATED FORM;Lo;0;AL; 0020 0652;;;;N;ARABIC SPACING SUKUN;;;; +FE7F;ARABIC SUKUN MEDIAL FORM;Lo;0;AL; 0640 0652;;;;N;ARABIC SUKUN ON TATWEEL;;;; +FE80;ARABIC LETTER HAMZA ISOLATED FORM;Lo;0;AL; 0621;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH;;;; +FE81;ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL; 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON ALEF;;;; +FE82;ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL; 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON ALEF;;;; +FE83;ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON ALEF;;;; +FE84;ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON ALEF;;;; +FE85;ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0624;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON WAW;;;; +FE86;ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0624;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON WAW;;;; +FE87;ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL; 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER ALEF;;;; +FE88;ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL; 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER ALEF;;;; +FE89;ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON YA;;;; +FE8A;ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON YA;;;; +FE8B;ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR INITIAL ARABIC HAMZAH ON YA;;;; +FE8C;ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR MEDIAL ARABIC HAMZAH ON YA;;;; +FE8D;ARABIC LETTER ALEF ISOLATED FORM;Lo;0;AL; 0627;;;;N;GLYPH FOR ISOLATE ARABIC ALEF;;;; +FE8E;ARABIC LETTER ALEF FINAL FORM;Lo;0;AL; 0627;;;;N;GLYPH FOR FINAL ARABIC ALEF;;;; +FE8F;ARABIC LETTER BEH ISOLATED FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR ISOLATE ARABIC BAA;;;; +FE90;ARABIC LETTER BEH FINAL FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR FINAL ARABIC BAA;;;; +FE91;ARABIC LETTER BEH INITIAL FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR INITIAL ARABIC BAA;;;; +FE92;ARABIC LETTER BEH MEDIAL FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR MEDIAL ARABIC BAA;;;; +FE93;ARABIC LETTER TEH MARBUTA ISOLATED FORM;Lo;0;AL; 0629;;;;N;GLYPH FOR ISOLATE ARABIC TAA MARBUTAH;;;; +FE94;ARABIC LETTER TEH MARBUTA FINAL FORM;Lo;0;AL; 0629;;;;N;GLYPH FOR FINAL ARABIC TAA MARBUTAH;;;; +FE95;ARABIC LETTER TEH ISOLATED FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR ISOLATE ARABIC TAA;;;; +FE96;ARABIC LETTER TEH FINAL FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR FINAL ARABIC TAA;;;; +FE97;ARABIC LETTER TEH INITIAL FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR INITIAL ARABIC TAA;;;; +FE98;ARABIC LETTER TEH MEDIAL FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR MEDIAL ARABIC TAA;;;; +FE99;ARABIC LETTER THEH ISOLATED FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR ISOLATE ARABIC THAA;;;; +FE9A;ARABIC LETTER THEH FINAL FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR FINAL ARABIC THAA;;;; +FE9B;ARABIC LETTER THEH INITIAL FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR INITIAL ARABIC THAA;;;; +FE9C;ARABIC LETTER THEH MEDIAL FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR MEDIAL ARABIC THAA;;;; +FE9D;ARABIC LETTER JEEM ISOLATED FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR ISOLATE ARABIC JEEM;;;; +FE9E;ARABIC LETTER JEEM FINAL FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR FINAL ARABIC JEEM;;;; +FE9F;ARABIC LETTER JEEM INITIAL FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR INITIAL ARABIC JEEM;;;; +FEA0;ARABIC LETTER JEEM MEDIAL FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR MEDIAL ARABIC JEEM;;;; +FEA1;ARABIC LETTER HAH ISOLATED FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR ISOLATE ARABIC HAA;;;; +FEA2;ARABIC LETTER HAH FINAL FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR FINAL ARABIC HAA;;;; +FEA3;ARABIC LETTER HAH INITIAL FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR INITIAL ARABIC HAA;;;; +FEA4;ARABIC LETTER HAH MEDIAL FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR MEDIAL ARABIC HAA;;;; +FEA5;ARABIC LETTER KHAH ISOLATED FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR ISOLATE ARABIC KHAA;;;; +FEA6;ARABIC LETTER KHAH FINAL FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR FINAL ARABIC KHAA;;;; +FEA7;ARABIC LETTER KHAH INITIAL FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR INITIAL ARABIC KHAA;;;; +FEA8;ARABIC LETTER KHAH MEDIAL FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR MEDIAL ARABIC KHAA;;;; +FEA9;ARABIC LETTER DAL ISOLATED FORM;Lo;0;AL; 062F;;;;N;GLYPH FOR ISOLATE ARABIC DAL;;;; +FEAA;ARABIC LETTER DAL FINAL FORM;Lo;0;AL; 062F;;;;N;GLYPH FOR FINAL ARABIC DAL;;;; +FEAB;ARABIC LETTER THAL ISOLATED FORM;Lo;0;AL; 0630;;;;N;GLYPH FOR ISOLATE ARABIC THAL;;;; +FEAC;ARABIC LETTER THAL FINAL FORM;Lo;0;AL; 0630;;;;N;GLYPH FOR FINAL ARABIC THAL;;;; +FEAD;ARABIC LETTER REH ISOLATED FORM;Lo;0;AL; 0631;;;;N;GLYPH FOR ISOLATE ARABIC RA;;;; +FEAE;ARABIC LETTER REH FINAL FORM;Lo;0;AL; 0631;;;;N;GLYPH FOR FINAL ARABIC RA;;;; +FEAF;ARABIC LETTER ZAIN ISOLATED FORM;Lo;0;AL; 0632;;;;N;GLYPH FOR ISOLATE ARABIC ZAIN;;;; +FEB0;ARABIC LETTER ZAIN FINAL FORM;Lo;0;AL; 0632;;;;N;GLYPH FOR FINAL ARABIC ZAIN;;;; +FEB1;ARABIC LETTER SEEN ISOLATED FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR ISOLATE ARABIC SEEN;;;; +FEB2;ARABIC LETTER SEEN FINAL FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR FINAL ARABIC SEEN;;;; +FEB3;ARABIC LETTER SEEN INITIAL FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR INITIAL ARABIC SEEN;;;; +FEB4;ARABIC LETTER SEEN MEDIAL FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR MEDIAL ARABIC SEEN;;;; +FEB5;ARABIC LETTER SHEEN ISOLATED FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR ISOLATE ARABIC SHEEN;;;; +FEB6;ARABIC LETTER SHEEN FINAL FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR FINAL ARABIC SHEEN;;;; +FEB7;ARABIC LETTER SHEEN INITIAL FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR INITIAL ARABIC SHEEN;;;; +FEB8;ARABIC LETTER SHEEN MEDIAL FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR MEDIAL ARABIC SHEEN;;;; +FEB9;ARABIC LETTER SAD ISOLATED FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR ISOLATE ARABIC SAD;;;; +FEBA;ARABIC LETTER SAD FINAL FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR FINAL ARABIC SAD;;;; +FEBB;ARABIC LETTER SAD INITIAL FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR INITIAL ARABIC SAD;;;; +FEBC;ARABIC LETTER SAD MEDIAL FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR MEDIAL ARABIC SAD;;;; +FEBD;ARABIC LETTER DAD ISOLATED FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR ISOLATE ARABIC DAD;;;; +FEBE;ARABIC LETTER DAD FINAL FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR FINAL ARABIC DAD;;;; +FEBF;ARABIC LETTER DAD INITIAL FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR INITIAL ARABIC DAD;;;; +FEC0;ARABIC LETTER DAD MEDIAL FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR MEDIAL ARABIC DAD;;;; +FEC1;ARABIC LETTER TAH ISOLATED FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR ISOLATE ARABIC TAH;;;; +FEC2;ARABIC LETTER TAH FINAL FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR FINAL ARABIC TAH;;;; +FEC3;ARABIC LETTER TAH INITIAL FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR INITIAL ARABIC TAH;;;; +FEC4;ARABIC LETTER TAH MEDIAL FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR MEDIAL ARABIC TAH;;;; +FEC5;ARABIC LETTER ZAH ISOLATED FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR ISOLATE ARABIC DHAH;;;; +FEC6;ARABIC LETTER ZAH FINAL FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR FINAL ARABIC DHAH;;;; +FEC7;ARABIC LETTER ZAH INITIAL FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR INITIAL ARABIC DHAH;;;; +FEC8;ARABIC LETTER ZAH MEDIAL FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR MEDIAL ARABIC DHAH;;;; +FEC9;ARABIC LETTER AIN ISOLATED FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR ISOLATE ARABIC AIN;;;; +FECA;ARABIC LETTER AIN FINAL FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR FINAL ARABIC AIN;;;; +FECB;ARABIC LETTER AIN INITIAL FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR INITIAL ARABIC AIN;;;; +FECC;ARABIC LETTER AIN MEDIAL FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR MEDIAL ARABIC AIN;;;; +FECD;ARABIC LETTER GHAIN ISOLATED FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR ISOLATE ARABIC GHAIN;;;; +FECE;ARABIC LETTER GHAIN FINAL FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR FINAL ARABIC GHAIN;;;; +FECF;ARABIC LETTER GHAIN INITIAL FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR INITIAL ARABIC GHAIN;;;; +FED0;ARABIC LETTER GHAIN MEDIAL FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR MEDIAL ARABIC GHAIN;;;; +FED1;ARABIC LETTER FEH ISOLATED FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR ISOLATE ARABIC FA;;;; +FED2;ARABIC LETTER FEH FINAL FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR FINAL ARABIC FA;;;; +FED3;ARABIC LETTER FEH INITIAL FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR INITIAL ARABIC FA;;;; +FED4;ARABIC LETTER FEH MEDIAL FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR MEDIAL ARABIC FA;;;; +FED5;ARABIC LETTER QAF ISOLATED FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR ISOLATE ARABIC QAF;;;; +FED6;ARABIC LETTER QAF FINAL FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR FINAL ARABIC QAF;;;; +FED7;ARABIC LETTER QAF INITIAL FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR INITIAL ARABIC QAF;;;; +FED8;ARABIC LETTER QAF MEDIAL FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR MEDIAL ARABIC QAF;;;; +FED9;ARABIC LETTER KAF ISOLATED FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR ISOLATE ARABIC CAF;;;; +FEDA;ARABIC LETTER KAF FINAL FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR FINAL ARABIC CAF;;;; +FEDB;ARABIC LETTER KAF INITIAL FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR INITIAL ARABIC CAF;;;; +FEDC;ARABIC LETTER KAF MEDIAL FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR MEDIAL ARABIC CAF;;;; +FEDD;ARABIC LETTER LAM ISOLATED FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR ISOLATE ARABIC LAM;;;; +FEDE;ARABIC LETTER LAM FINAL FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR FINAL ARABIC LAM;;;; +FEDF;ARABIC LETTER LAM INITIAL FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR INITIAL ARABIC LAM;;;; +FEE0;ARABIC LETTER LAM MEDIAL FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR MEDIAL ARABIC LAM;;;; +FEE1;ARABIC LETTER MEEM ISOLATED FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR ISOLATE ARABIC MEEM;;;; +FEE2;ARABIC LETTER MEEM FINAL FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR FINAL ARABIC MEEM;;;; +FEE3;ARABIC LETTER MEEM INITIAL FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR INITIAL ARABIC MEEM;;;; +FEE4;ARABIC LETTER MEEM MEDIAL FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR MEDIAL ARABIC MEEM;;;; +FEE5;ARABIC LETTER NOON ISOLATED FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR ISOLATE ARABIC NOON;;;; +FEE6;ARABIC LETTER NOON FINAL FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR FINAL ARABIC NOON;;;; +FEE7;ARABIC LETTER NOON INITIAL FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR INITIAL ARABIC NOON;;;; +FEE8;ARABIC LETTER NOON MEDIAL FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR MEDIAL ARABIC NOON;;;; +FEE9;ARABIC LETTER HEH ISOLATED FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR ISOLATE ARABIC HA;;;; +FEEA;ARABIC LETTER HEH FINAL FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR FINAL ARABIC HA;;;; +FEEB;ARABIC LETTER HEH INITIAL FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR INITIAL ARABIC HA;;;; +FEEC;ARABIC LETTER HEH MEDIAL FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR MEDIAL ARABIC HA;;;; +FEED;ARABIC LETTER WAW ISOLATED FORM;Lo;0;AL; 0648;;;;N;GLYPH FOR ISOLATE ARABIC WAW;;;; +FEEE;ARABIC LETTER WAW FINAL FORM;Lo;0;AL; 0648;;;;N;GLYPH FOR FINAL ARABIC WAW;;;; +FEEF;ARABIC LETTER ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0649;;;;N;GLYPH FOR ISOLATE ARABIC ALEF MAQSURAH;;;; +FEF0;ARABIC LETTER ALEF MAKSURA FINAL FORM;Lo;0;AL; 0649;;;;N;GLYPH FOR FINAL ARABIC ALEF MAQSURAH;;;; +FEF1;ARABIC LETTER YEH ISOLATED FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR ISOLATE ARABIC YA;;;; +FEF2;ARABIC LETTER YEH FINAL FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR FINAL ARABIC YA;;;; +FEF3;ARABIC LETTER YEH INITIAL FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR INITIAL ARABIC YA;;;; +FEF4;ARABIC LETTER YEH MEDIAL FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR MEDIAL ARABIC YA;;;; +FEF5;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL; 0644 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON LIGATURE LAM ALEF;;;; +FEF6;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL; 0644 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON LIGATURE LAM ALEF;;;; +FEF7;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0644 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON LIGATURE LAM ALEF;;;; +FEF8;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0644 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON LIGATURE LAM ALEF;;;; +FEF9;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL; 0644 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;; +FEFA;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL; 0644 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;; +FEFB;ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM;Lo;0;AL; 0644 0627;;;;N;GLYPH FOR ISOLATE ARABIC LIGATURE LAM ALEF;;;; +FEFC;ARABIC LIGATURE LAM WITH ALEF FINAL FORM;Lo;0;AL; 0644 0627;;;;N;GLYPH FOR FINAL ARABIC LIGATURE LAM ALEF;;;; +FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;; +FF01;FULLWIDTH EXCLAMATION MARK;Po;0;ON; 0021;;;;N;;;;; +FF02;FULLWIDTH QUOTATION MARK;Po;0;ON; 0022;;;;N;;;;; +FF03;FULLWIDTH NUMBER SIGN;Po;0;ET; 0023;;;;N;;;;; +FF04;FULLWIDTH DOLLAR SIGN;Sc;0;ET; 0024;;;;N;;;;; +FF05;FULLWIDTH PERCENT SIGN;Po;0;ET; 0025;;;;N;;;;; +FF06;FULLWIDTH AMPERSAND;Po;0;ON; 0026;;;;N;;;;; +FF07;FULLWIDTH APOSTROPHE;Po;0;ON; 0027;;;;N;;;;; +FF08;FULLWIDTH LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;FULLWIDTH OPENING PARENTHESIS;;;; +FF09;FULLWIDTH RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;FULLWIDTH CLOSING PARENTHESIS;;;; +FF0A;FULLWIDTH ASTERISK;Po;0;ON; 002A;;;;N;;;;; +FF0B;FULLWIDTH PLUS SIGN;Sm;0;ES; 002B;;;;N;;;;; +FF0C;FULLWIDTH COMMA;Po;0;CS; 002C;;;;N;;;;; +FF0D;FULLWIDTH HYPHEN-MINUS;Pd;0;ES; 002D;;;;N;;;;; +FF0E;FULLWIDTH FULL STOP;Po;0;CS; 002E;;;;N;FULLWIDTH PERIOD;;;; +FF0F;FULLWIDTH SOLIDUS;Po;0;CS; 002F;;;;N;FULLWIDTH SLASH;;;; +FF10;FULLWIDTH DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +FF11;FULLWIDTH DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +FF12;FULLWIDTH DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +FF13;FULLWIDTH DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +FF14;FULLWIDTH DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +FF15;FULLWIDTH DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +FF16;FULLWIDTH DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +FF17;FULLWIDTH DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +FF18;FULLWIDTH DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +FF19;FULLWIDTH DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +FF1A;FULLWIDTH COLON;Po;0;CS; 003A;;;;N;;;;; +FF1B;FULLWIDTH SEMICOLON;Po;0;ON; 003B;;;;N;;;;; +FF1C;FULLWIDTH LESS-THAN SIGN;Sm;0;ON; 003C;;;;Y;;;;; +FF1D;FULLWIDTH EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; +FF1E;FULLWIDTH GREATER-THAN SIGN;Sm;0;ON; 003E;;;;Y;;;;; +FF1F;FULLWIDTH QUESTION MARK;Po;0;ON; 003F;;;;N;;;;; +FF20;FULLWIDTH COMMERCIAL AT;Po;0;ON; 0040;;;;N;;;;; +FF21;FULLWIDTH LATIN CAPITAL LETTER A;Lu;0;L; 0041;;;;N;;;;FF41; +FF22;FULLWIDTH LATIN CAPITAL LETTER B;Lu;0;L; 0042;;;;N;;;;FF42; +FF23;FULLWIDTH LATIN CAPITAL LETTER C;Lu;0;L; 0043;;;;N;;;;FF43; +FF24;FULLWIDTH LATIN CAPITAL LETTER D;Lu;0;L; 0044;;;;N;;;;FF44; +FF25;FULLWIDTH LATIN CAPITAL LETTER E;Lu;0;L; 0045;;;;N;;;;FF45; +FF26;FULLWIDTH LATIN CAPITAL LETTER F;Lu;0;L; 0046;;;;N;;;;FF46; +FF27;FULLWIDTH LATIN CAPITAL LETTER G;Lu;0;L; 0047;;;;N;;;;FF47; +FF28;FULLWIDTH LATIN CAPITAL LETTER H;Lu;0;L; 0048;;;;N;;;;FF48; +FF29;FULLWIDTH LATIN CAPITAL LETTER I;Lu;0;L; 0049;;;;N;;;;FF49; +FF2A;FULLWIDTH LATIN CAPITAL LETTER J;Lu;0;L; 004A;;;;N;;;;FF4A; +FF2B;FULLWIDTH LATIN CAPITAL LETTER K;Lu;0;L; 004B;;;;N;;;;FF4B; +FF2C;FULLWIDTH LATIN CAPITAL LETTER L;Lu;0;L; 004C;;;;N;;;;FF4C; +FF2D;FULLWIDTH LATIN CAPITAL LETTER M;Lu;0;L; 004D;;;;N;;;;FF4D; +FF2E;FULLWIDTH LATIN CAPITAL LETTER N;Lu;0;L; 004E;;;;N;;;;FF4E; +FF2F;FULLWIDTH LATIN CAPITAL LETTER O;Lu;0;L; 004F;;;;N;;;;FF4F; +FF30;FULLWIDTH LATIN CAPITAL LETTER P;Lu;0;L; 0050;;;;N;;;;FF50; +FF31;FULLWIDTH LATIN CAPITAL LETTER Q;Lu;0;L; 0051;;;;N;;;;FF51; +FF32;FULLWIDTH LATIN CAPITAL LETTER R;Lu;0;L; 0052;;;;N;;;;FF52; +FF33;FULLWIDTH LATIN CAPITAL LETTER S;Lu;0;L; 0053;;;;N;;;;FF53; +FF34;FULLWIDTH LATIN CAPITAL LETTER T;Lu;0;L; 0054;;;;N;;;;FF54; +FF35;FULLWIDTH LATIN CAPITAL LETTER U;Lu;0;L; 0055;;;;N;;;;FF55; +FF36;FULLWIDTH LATIN CAPITAL LETTER V;Lu;0;L; 0056;;;;N;;;;FF56; +FF37;FULLWIDTH LATIN CAPITAL LETTER W;Lu;0;L; 0057;;;;N;;;;FF57; +FF38;FULLWIDTH LATIN CAPITAL LETTER X;Lu;0;L; 0058;;;;N;;;;FF58; +FF39;FULLWIDTH LATIN CAPITAL LETTER Y;Lu;0;L; 0059;;;;N;;;;FF59; +FF3A;FULLWIDTH LATIN CAPITAL LETTER Z;Lu;0;L; 005A;;;;N;;;;FF5A; +FF3B;FULLWIDTH LEFT SQUARE BRACKET;Ps;0;ON; 005B;;;;Y;FULLWIDTH OPENING SQUARE BRACKET;;;; +FF3C;FULLWIDTH REVERSE SOLIDUS;Po;0;ON; 005C;;;;N;FULLWIDTH BACKSLASH;;;; +FF3D;FULLWIDTH RIGHT SQUARE BRACKET;Pe;0;ON; 005D;;;;Y;FULLWIDTH CLOSING SQUARE BRACKET;;;; +FF3E;FULLWIDTH CIRCUMFLEX ACCENT;Sk;0;ON; 005E;;;;N;FULLWIDTH SPACING CIRCUMFLEX;;;; +FF3F;FULLWIDTH LOW LINE;Pc;0;ON; 005F;;;;N;FULLWIDTH SPACING UNDERSCORE;;;; +FF40;FULLWIDTH GRAVE ACCENT;Sk;0;ON; 0060;;;;N;FULLWIDTH SPACING GRAVE;;;; +FF41;FULLWIDTH LATIN SMALL LETTER A;Ll;0;L; 0061;;;;N;;;FF21;;FF21 +FF42;FULLWIDTH LATIN SMALL LETTER B;Ll;0;L; 0062;;;;N;;;FF22;;FF22 +FF43;FULLWIDTH LATIN SMALL LETTER C;Ll;0;L; 0063;;;;N;;;FF23;;FF23 +FF44;FULLWIDTH LATIN SMALL LETTER D;Ll;0;L; 0064;;;;N;;;FF24;;FF24 +FF45;FULLWIDTH LATIN SMALL LETTER E;Ll;0;L; 0065;;;;N;;;FF25;;FF25 +FF46;FULLWIDTH LATIN SMALL LETTER F;Ll;0;L; 0066;;;;N;;;FF26;;FF26 +FF47;FULLWIDTH LATIN SMALL LETTER G;Ll;0;L; 0067;;;;N;;;FF27;;FF27 +FF48;FULLWIDTH LATIN SMALL LETTER H;Ll;0;L; 0068;;;;N;;;FF28;;FF28 +FF49;FULLWIDTH LATIN SMALL LETTER I;Ll;0;L; 0069;;;;N;;;FF29;;FF29 +FF4A;FULLWIDTH LATIN SMALL LETTER J;Ll;0;L; 006A;;;;N;;;FF2A;;FF2A +FF4B;FULLWIDTH LATIN SMALL LETTER K;Ll;0;L; 006B;;;;N;;;FF2B;;FF2B +FF4C;FULLWIDTH LATIN SMALL LETTER L;Ll;0;L; 006C;;;;N;;;FF2C;;FF2C +FF4D;FULLWIDTH LATIN SMALL LETTER M;Ll;0;L; 006D;;;;N;;;FF2D;;FF2D +FF4E;FULLWIDTH LATIN SMALL LETTER N;Ll;0;L; 006E;;;;N;;;FF2E;;FF2E +FF4F;FULLWIDTH LATIN SMALL LETTER O;Ll;0;L; 006F;;;;N;;;FF2F;;FF2F +FF50;FULLWIDTH LATIN SMALL LETTER P;Ll;0;L; 0070;;;;N;;;FF30;;FF30 +FF51;FULLWIDTH LATIN SMALL LETTER Q;Ll;0;L; 0071;;;;N;;;FF31;;FF31 +FF52;FULLWIDTH LATIN SMALL LETTER R;Ll;0;L; 0072;;;;N;;;FF32;;FF32 +FF53;FULLWIDTH LATIN SMALL LETTER S;Ll;0;L; 0073;;;;N;;;FF33;;FF33 +FF54;FULLWIDTH LATIN SMALL LETTER T;Ll;0;L; 0074;;;;N;;;FF34;;FF34 +FF55;FULLWIDTH LATIN SMALL LETTER U;Ll;0;L; 0075;;;;N;;;FF35;;FF35 +FF56;FULLWIDTH LATIN SMALL LETTER V;Ll;0;L; 0076;;;;N;;;FF36;;FF36 +FF57;FULLWIDTH LATIN SMALL LETTER W;Ll;0;L; 0077;;;;N;;;FF37;;FF37 +FF58;FULLWIDTH LATIN SMALL LETTER X;Ll;0;L; 0078;;;;N;;;FF38;;FF38 +FF59;FULLWIDTH LATIN SMALL LETTER Y;Ll;0;L; 0079;;;;N;;;FF39;;FF39 +FF5A;FULLWIDTH LATIN SMALL LETTER Z;Ll;0;L; 007A;;;;N;;;FF3A;;FF3A +FF5B;FULLWIDTH LEFT CURLY BRACKET;Ps;0;ON; 007B;;;;Y;FULLWIDTH OPENING CURLY BRACKET;;;; +FF5C;FULLWIDTH VERTICAL LINE;Sm;0;ON; 007C;;;;N;FULLWIDTH VERTICAL BAR;;;; +FF5D;FULLWIDTH RIGHT CURLY BRACKET;Pe;0;ON; 007D;;;;Y;FULLWIDTH CLOSING CURLY BRACKET;;;; +FF5E;FULLWIDTH TILDE;Sm;0;ON; 007E;;;;N;FULLWIDTH SPACING TILDE;;;; +FF5F;FULLWIDTH LEFT WHITE PARENTHESIS;Ps;0;ON; 2985;;;;Y;;;;; +FF60;FULLWIDTH RIGHT WHITE PARENTHESIS;Pe;0;ON; 2986;;;;Y;;;;; +FF61;HALFWIDTH IDEOGRAPHIC FULL STOP;Po;0;ON; 3002;;;;N;HALFWIDTH IDEOGRAPHIC PERIOD;;;; +FF62;HALFWIDTH LEFT CORNER BRACKET;Ps;0;ON; 300C;;;;Y;HALFWIDTH OPENING CORNER BRACKET;;;; +FF63;HALFWIDTH RIGHT CORNER BRACKET;Pe;0;ON; 300D;;;;Y;HALFWIDTH CLOSING CORNER BRACKET;;;; +FF64;HALFWIDTH IDEOGRAPHIC COMMA;Po;0;ON; 3001;;;;N;;;;; +FF65;HALFWIDTH KATAKANA MIDDLE DOT;Po;0;ON; 30FB;;;;N;;;;; +FF66;HALFWIDTH KATAKANA LETTER WO;Lo;0;L; 30F2;;;;N;;;;; +FF67;HALFWIDTH KATAKANA LETTER SMALL A;Lo;0;L; 30A1;;;;N;;;;; +FF68;HALFWIDTH KATAKANA LETTER SMALL I;Lo;0;L; 30A3;;;;N;;;;; +FF69;HALFWIDTH KATAKANA LETTER SMALL U;Lo;0;L; 30A5;;;;N;;;;; +FF6A;HALFWIDTH KATAKANA LETTER SMALL E;Lo;0;L; 30A7;;;;N;;;;; +FF6B;HALFWIDTH KATAKANA LETTER SMALL O;Lo;0;L; 30A9;;;;N;;;;; +FF6C;HALFWIDTH KATAKANA LETTER SMALL YA;Lo;0;L; 30E3;;;;N;;;;; +FF6D;HALFWIDTH KATAKANA LETTER SMALL YU;Lo;0;L; 30E5;;;;N;;;;; +FF6E;HALFWIDTH KATAKANA LETTER SMALL YO;Lo;0;L; 30E7;;;;N;;;;; +FF6F;HALFWIDTH KATAKANA LETTER SMALL TU;Lo;0;L; 30C3;;;;N;;;;; +FF70;HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L; 30FC;;;;N;;;;; +FF71;HALFWIDTH KATAKANA LETTER A;Lo;0;L; 30A2;;;;N;;;;; +FF72;HALFWIDTH KATAKANA LETTER I;Lo;0;L; 30A4;;;;N;;;;; +FF73;HALFWIDTH KATAKANA LETTER U;Lo;0;L; 30A6;;;;N;;;;; +FF74;HALFWIDTH KATAKANA LETTER E;Lo;0;L; 30A8;;;;N;;;;; +FF75;HALFWIDTH KATAKANA LETTER O;Lo;0;L; 30AA;;;;N;;;;; +FF76;HALFWIDTH KATAKANA LETTER KA;Lo;0;L; 30AB;;;;N;;;;; +FF77;HALFWIDTH KATAKANA LETTER KI;Lo;0;L; 30AD;;;;N;;;;; +FF78;HALFWIDTH KATAKANA LETTER KU;Lo;0;L; 30AF;;;;N;;;;; +FF79;HALFWIDTH KATAKANA LETTER KE;Lo;0;L; 30B1;;;;N;;;;; +FF7A;HALFWIDTH KATAKANA LETTER KO;Lo;0;L; 30B3;;;;N;;;;; +FF7B;HALFWIDTH KATAKANA LETTER SA;Lo;0;L; 30B5;;;;N;;;;; +FF7C;HALFWIDTH KATAKANA LETTER SI;Lo;0;L; 30B7;;;;N;;;;; +FF7D;HALFWIDTH KATAKANA LETTER SU;Lo;0;L; 30B9;;;;N;;;;; +FF7E;HALFWIDTH KATAKANA LETTER SE;Lo;0;L; 30BB;;;;N;;;;; +FF7F;HALFWIDTH KATAKANA LETTER SO;Lo;0;L; 30BD;;;;N;;;;; +FF80;HALFWIDTH KATAKANA LETTER TA;Lo;0;L; 30BF;;;;N;;;;; +FF81;HALFWIDTH KATAKANA LETTER TI;Lo;0;L; 30C1;;;;N;;;;; +FF82;HALFWIDTH KATAKANA LETTER TU;Lo;0;L; 30C4;;;;N;;;;; +FF83;HALFWIDTH KATAKANA LETTER TE;Lo;0;L; 30C6;;;;N;;;;; +FF84;HALFWIDTH KATAKANA LETTER TO;Lo;0;L; 30C8;;;;N;;;;; +FF85;HALFWIDTH KATAKANA LETTER NA;Lo;0;L; 30CA;;;;N;;;;; +FF86;HALFWIDTH KATAKANA LETTER NI;Lo;0;L; 30CB;;;;N;;;;; +FF87;HALFWIDTH KATAKANA LETTER NU;Lo;0;L; 30CC;;;;N;;;;; +FF88;HALFWIDTH KATAKANA LETTER NE;Lo;0;L; 30CD;;;;N;;;;; +FF89;HALFWIDTH KATAKANA LETTER NO;Lo;0;L; 30CE;;;;N;;;;; +FF8A;HALFWIDTH KATAKANA LETTER HA;Lo;0;L; 30CF;;;;N;;;;; +FF8B;HALFWIDTH KATAKANA LETTER HI;Lo;0;L; 30D2;;;;N;;;;; +FF8C;HALFWIDTH KATAKANA LETTER HU;Lo;0;L; 30D5;;;;N;;;;; +FF8D;HALFWIDTH KATAKANA LETTER HE;Lo;0;L; 30D8;;;;N;;;;; +FF8E;HALFWIDTH KATAKANA LETTER HO;Lo;0;L; 30DB;;;;N;;;;; +FF8F;HALFWIDTH KATAKANA LETTER MA;Lo;0;L; 30DE;;;;N;;;;; +FF90;HALFWIDTH KATAKANA LETTER MI;Lo;0;L; 30DF;;;;N;;;;; +FF91;HALFWIDTH KATAKANA LETTER MU;Lo;0;L; 30E0;;;;N;;;;; +FF92;HALFWIDTH KATAKANA LETTER ME;Lo;0;L; 30E1;;;;N;;;;; +FF93;HALFWIDTH KATAKANA LETTER MO;Lo;0;L; 30E2;;;;N;;;;; +FF94;HALFWIDTH KATAKANA LETTER YA;Lo;0;L; 30E4;;;;N;;;;; +FF95;HALFWIDTH KATAKANA LETTER YU;Lo;0;L; 30E6;;;;N;;;;; +FF96;HALFWIDTH KATAKANA LETTER YO;Lo;0;L; 30E8;;;;N;;;;; +FF97;HALFWIDTH KATAKANA LETTER RA;Lo;0;L; 30E9;;;;N;;;;; +FF98;HALFWIDTH KATAKANA LETTER RI;Lo;0;L; 30EA;;;;N;;;;; +FF99;HALFWIDTH KATAKANA LETTER RU;Lo;0;L; 30EB;;;;N;;;;; +FF9A;HALFWIDTH KATAKANA LETTER RE;Lo;0;L; 30EC;;;;N;;;;; +FF9B;HALFWIDTH KATAKANA LETTER RO;Lo;0;L; 30ED;;;;N;;;;; +FF9C;HALFWIDTH KATAKANA LETTER WA;Lo;0;L; 30EF;;;;N;;;;; +FF9D;HALFWIDTH KATAKANA LETTER N;Lo;0;L; 30F3;;;;N;;;;; +FF9E;HALFWIDTH KATAKANA VOICED SOUND MARK;Lm;0;L; 3099;;;;N;;;;; +FF9F;HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK;Lm;0;L; 309A;;;;N;;;;; +FFA0;HALFWIDTH HANGUL FILLER;Lo;0;L; 3164;;;;N;HALFWIDTH HANGUL CAE OM;;;; +FFA1;HALFWIDTH HANGUL LETTER KIYEOK;Lo;0;L; 3131;;;;N;HALFWIDTH HANGUL LETTER GIYEOG;;;; +FFA2;HALFWIDTH HANGUL LETTER SSANGKIYEOK;Lo;0;L; 3132;;;;N;HALFWIDTH HANGUL LETTER SSANG GIYEOG;;;; +FFA3;HALFWIDTH HANGUL LETTER KIYEOK-SIOS;Lo;0;L; 3133;;;;N;HALFWIDTH HANGUL LETTER GIYEOG SIOS;;;; +FFA4;HALFWIDTH HANGUL LETTER NIEUN;Lo;0;L; 3134;;;;N;;;;; +FFA5;HALFWIDTH HANGUL LETTER NIEUN-CIEUC;Lo;0;L; 3135;;;;N;HALFWIDTH HANGUL LETTER NIEUN JIEUJ;;;; +FFA6;HALFWIDTH HANGUL LETTER NIEUN-HIEUH;Lo;0;L; 3136;;;;N;HALFWIDTH HANGUL LETTER NIEUN HIEUH;;;; +FFA7;HALFWIDTH HANGUL LETTER TIKEUT;Lo;0;L; 3137;;;;N;HALFWIDTH HANGUL LETTER DIGEUD;;;; +FFA8;HALFWIDTH HANGUL LETTER SSANGTIKEUT;Lo;0;L; 3138;;;;N;HALFWIDTH HANGUL LETTER SSANG DIGEUD;;;; +FFA9;HALFWIDTH HANGUL LETTER RIEUL;Lo;0;L; 3139;;;;N;HALFWIDTH HANGUL LETTER LIEUL;;;; +FFAA;HALFWIDTH HANGUL LETTER RIEUL-KIYEOK;Lo;0;L; 313A;;;;N;HALFWIDTH HANGUL LETTER LIEUL GIYEOG;;;; +FFAB;HALFWIDTH HANGUL LETTER RIEUL-MIEUM;Lo;0;L; 313B;;;;N;HALFWIDTH HANGUL LETTER LIEUL MIEUM;;;; +FFAC;HALFWIDTH HANGUL LETTER RIEUL-PIEUP;Lo;0;L; 313C;;;;N;HALFWIDTH HANGUL LETTER LIEUL BIEUB;;;; +FFAD;HALFWIDTH HANGUL LETTER RIEUL-SIOS;Lo;0;L; 313D;;;;N;HALFWIDTH HANGUL LETTER LIEUL SIOS;;;; +FFAE;HALFWIDTH HANGUL LETTER RIEUL-THIEUTH;Lo;0;L; 313E;;;;N;HALFWIDTH HANGUL LETTER LIEUL TIEUT;;;; +FFAF;HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L; 313F;;;;N;HALFWIDTH HANGUL LETTER LIEUL PIEUP;;;; +FFB0;HALFWIDTH HANGUL LETTER RIEUL-HIEUH;Lo;0;L; 3140;;;;N;HALFWIDTH HANGUL LETTER LIEUL HIEUH;;;; +FFB1;HALFWIDTH HANGUL LETTER MIEUM;Lo;0;L; 3141;;;;N;;;;; +FFB2;HALFWIDTH HANGUL LETTER PIEUP;Lo;0;L; 3142;;;;N;HALFWIDTH HANGUL LETTER BIEUB;;;; +FFB3;HALFWIDTH HANGUL LETTER SSANGPIEUP;Lo;0;L; 3143;;;;N;HALFWIDTH HANGUL LETTER SSANG BIEUB;;;; +FFB4;HALFWIDTH HANGUL LETTER PIEUP-SIOS;Lo;0;L; 3144;;;;N;HALFWIDTH HANGUL LETTER BIEUB SIOS;;;; +FFB5;HALFWIDTH HANGUL LETTER SIOS;Lo;0;L; 3145;;;;N;;;;; +FFB6;HALFWIDTH HANGUL LETTER SSANGSIOS;Lo;0;L; 3146;;;;N;HALFWIDTH HANGUL LETTER SSANG SIOS;;;; +FFB7;HALFWIDTH HANGUL LETTER IEUNG;Lo;0;L; 3147;;;;N;;;;; +FFB8;HALFWIDTH HANGUL LETTER CIEUC;Lo;0;L; 3148;;;;N;HALFWIDTH HANGUL LETTER JIEUJ;;;; +FFB9;HALFWIDTH HANGUL LETTER SSANGCIEUC;Lo;0;L; 3149;;;;N;HALFWIDTH HANGUL LETTER SSANG JIEUJ;;;; +FFBA;HALFWIDTH HANGUL LETTER CHIEUCH;Lo;0;L; 314A;;;;N;HALFWIDTH HANGUL LETTER CIEUC;;;; +FFBB;HALFWIDTH HANGUL LETTER KHIEUKH;Lo;0;L; 314B;;;;N;HALFWIDTH HANGUL LETTER KIYEOK;;;; +FFBC;HALFWIDTH HANGUL LETTER THIEUTH;Lo;0;L; 314C;;;;N;HALFWIDTH HANGUL LETTER TIEUT;;;; +FFBD;HALFWIDTH HANGUL LETTER PHIEUPH;Lo;0;L; 314D;;;;N;HALFWIDTH HANGUL LETTER PIEUP;;;; +FFBE;HALFWIDTH HANGUL LETTER HIEUH;Lo;0;L; 314E;;;;N;;;;; +FFC2;HALFWIDTH HANGUL LETTER A;Lo;0;L; 314F;;;;N;;;;; +FFC3;HALFWIDTH HANGUL LETTER AE;Lo;0;L; 3150;;;;N;;;;; +FFC4;HALFWIDTH HANGUL LETTER YA;Lo;0;L; 3151;;;;N;;;;; +FFC5;HALFWIDTH HANGUL LETTER YAE;Lo;0;L; 3152;;;;N;;;;; +FFC6;HALFWIDTH HANGUL LETTER EO;Lo;0;L; 3153;;;;N;;;;; +FFC7;HALFWIDTH HANGUL LETTER E;Lo;0;L; 3154;;;;N;;;;; +FFCA;HALFWIDTH HANGUL LETTER YEO;Lo;0;L; 3155;;;;N;;;;; +FFCB;HALFWIDTH HANGUL LETTER YE;Lo;0;L; 3156;;;;N;;;;; +FFCC;HALFWIDTH HANGUL LETTER O;Lo;0;L; 3157;;;;N;;;;; +FFCD;HALFWIDTH HANGUL LETTER WA;Lo;0;L; 3158;;;;N;;;;; +FFCE;HALFWIDTH HANGUL LETTER WAE;Lo;0;L; 3159;;;;N;;;;; +FFCF;HALFWIDTH HANGUL LETTER OE;Lo;0;L; 315A;;;;N;;;;; +FFD2;HALFWIDTH HANGUL LETTER YO;Lo;0;L; 315B;;;;N;;;;; +FFD3;HALFWIDTH HANGUL LETTER U;Lo;0;L; 315C;;;;N;;;;; +FFD4;HALFWIDTH HANGUL LETTER WEO;Lo;0;L; 315D;;;;N;;;;; +FFD5;HALFWIDTH HANGUL LETTER WE;Lo;0;L; 315E;;;;N;;;;; +FFD6;HALFWIDTH HANGUL LETTER WI;Lo;0;L; 315F;;;;N;;;;; +FFD7;HALFWIDTH HANGUL LETTER YU;Lo;0;L; 3160;;;;N;;;;; +FFDA;HALFWIDTH HANGUL LETTER EU;Lo;0;L; 3161;;;;N;;;;; +FFDB;HALFWIDTH HANGUL LETTER YI;Lo;0;L; 3162;;;;N;;;;; +FFDC;HALFWIDTH HANGUL LETTER I;Lo;0;L; 3163;;;;N;;;;; +FFE0;FULLWIDTH CENT SIGN;Sc;0;ET; 00A2;;;;N;;;;; +FFE1;FULLWIDTH POUND SIGN;Sc;0;ET; 00A3;;;;N;;;;; +FFE2;FULLWIDTH NOT SIGN;Sm;0;ON; 00AC;;;;N;;;;; +FFE3;FULLWIDTH MACRON;Sk;0;ON; 00AF;;;;N;FULLWIDTH SPACING MACRON;;;; +FFE4;FULLWIDTH BROKEN BAR;So;0;ON; 00A6;;;;N;FULLWIDTH BROKEN VERTICAL BAR;;;; +FFE5;FULLWIDTH YEN SIGN;Sc;0;ET; 00A5;;;;N;;;;; +FFE6;FULLWIDTH WON SIGN;Sc;0;ET; 20A9;;;;N;;;;; +FFE8;HALFWIDTH FORMS LIGHT VERTICAL;So;0;ON; 2502;;;;N;;;;; +FFE9;HALFWIDTH LEFTWARDS ARROW;Sm;0;ON; 2190;;;;N;;;;; +FFEA;HALFWIDTH UPWARDS ARROW;Sm;0;ON; 2191;;;;N;;;;; +FFEB;HALFWIDTH RIGHTWARDS ARROW;Sm;0;ON; 2192;;;;N;;;;; +FFEC;HALFWIDTH DOWNWARDS ARROW;Sm;0;ON; 2193;;;;N;;;;; +FFED;HALFWIDTH BLACK SQUARE;So;0;ON; 25A0;;;;N;;;;; +FFEE;HALFWIDTH WHITE CIRCLE;So;0;ON; 25CB;;;;N;;;;; +FFF9;INTERLINEAR ANNOTATION ANCHOR;Cf;0;ON;;;;;N;;;;; +FFFA;INTERLINEAR ANNOTATION SEPARATOR;Cf;0;ON;;;;;N;;;;; +FFFB;INTERLINEAR ANNOTATION TERMINATOR;Cf;0;ON;;;;;N;;;;; +FFFC;OBJECT REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; +FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; +10000;LINEAR B SYLLABLE B008 A;Lo;0;L;;;;;N;;;;; +10001;LINEAR B SYLLABLE B038 E;Lo;0;L;;;;;N;;;;; +10002;LINEAR B SYLLABLE B028 I;Lo;0;L;;;;;N;;;;; +10003;LINEAR B SYLLABLE B061 O;Lo;0;L;;;;;N;;;;; +10004;LINEAR B SYLLABLE B010 U;Lo;0;L;;;;;N;;;;; +10005;LINEAR B SYLLABLE B001 DA;Lo;0;L;;;;;N;;;;; +10006;LINEAR B SYLLABLE B045 DE;Lo;0;L;;;;;N;;;;; +10007;LINEAR B SYLLABLE B007 DI;Lo;0;L;;;;;N;;;;; +10008;LINEAR B SYLLABLE B014 DO;Lo;0;L;;;;;N;;;;; +10009;LINEAR B SYLLABLE B051 DU;Lo;0;L;;;;;N;;;;; +1000A;LINEAR B SYLLABLE B057 JA;Lo;0;L;;;;;N;;;;; +1000B;LINEAR B SYLLABLE B046 JE;Lo;0;L;;;;;N;;;;; +1000D;LINEAR B SYLLABLE B036 JO;Lo;0;L;;;;;N;;;;; +1000E;LINEAR B SYLLABLE B065 JU;Lo;0;L;;;;;N;;;;; +1000F;LINEAR B SYLLABLE B077 KA;Lo;0;L;;;;;N;;;;; +10010;LINEAR B SYLLABLE B044 KE;Lo;0;L;;;;;N;;;;; +10011;LINEAR B SYLLABLE B067 KI;Lo;0;L;;;;;N;;;;; +10012;LINEAR B SYLLABLE B070 KO;Lo;0;L;;;;;N;;;;; +10013;LINEAR B SYLLABLE B081 KU;Lo;0;L;;;;;N;;;;; +10014;LINEAR B SYLLABLE B080 MA;Lo;0;L;;;;;N;;;;; +10015;LINEAR B SYLLABLE B013 ME;Lo;0;L;;;;;N;;;;; +10016;LINEAR B SYLLABLE B073 MI;Lo;0;L;;;;;N;;;;; +10017;LINEAR B SYLLABLE B015 MO;Lo;0;L;;;;;N;;;;; +10018;LINEAR B SYLLABLE B023 MU;Lo;0;L;;;;;N;;;;; +10019;LINEAR B SYLLABLE B006 NA;Lo;0;L;;;;;N;;;;; +1001A;LINEAR B SYLLABLE B024 NE;Lo;0;L;;;;;N;;;;; +1001B;LINEAR B SYLLABLE B030 NI;Lo;0;L;;;;;N;;;;; +1001C;LINEAR B SYLLABLE B052 NO;Lo;0;L;;;;;N;;;;; +1001D;LINEAR B SYLLABLE B055 NU;Lo;0;L;;;;;N;;;;; +1001E;LINEAR B SYLLABLE B003 PA;Lo;0;L;;;;;N;;;;; +1001F;LINEAR B SYLLABLE B072 PE;Lo;0;L;;;;;N;;;;; +10020;LINEAR B SYLLABLE B039 PI;Lo;0;L;;;;;N;;;;; +10021;LINEAR B SYLLABLE B011 PO;Lo;0;L;;;;;N;;;;; +10022;LINEAR B SYLLABLE B050 PU;Lo;0;L;;;;;N;;;;; +10023;LINEAR B SYLLABLE B016 QA;Lo;0;L;;;;;N;;;;; +10024;LINEAR B SYLLABLE B078 QE;Lo;0;L;;;;;N;;;;; +10025;LINEAR B SYLLABLE B021 QI;Lo;0;L;;;;;N;;;;; +10026;LINEAR B SYLLABLE B032 QO;Lo;0;L;;;;;N;;;;; +10028;LINEAR B SYLLABLE B060 RA;Lo;0;L;;;;;N;;;;; +10029;LINEAR B SYLLABLE B027 RE;Lo;0;L;;;;;N;;;;; +1002A;LINEAR B SYLLABLE B053 RI;Lo;0;L;;;;;N;;;;; +1002B;LINEAR B SYLLABLE B002 RO;Lo;0;L;;;;;N;;;;; +1002C;LINEAR B SYLLABLE B026 RU;Lo;0;L;;;;;N;;;;; +1002D;LINEAR B SYLLABLE B031 SA;Lo;0;L;;;;;N;;;;; +1002E;LINEAR B SYLLABLE B009 SE;Lo;0;L;;;;;N;;;;; +1002F;LINEAR B SYLLABLE B041 SI;Lo;0;L;;;;;N;;;;; +10030;LINEAR B SYLLABLE B012 SO;Lo;0;L;;;;;N;;;;; +10031;LINEAR B SYLLABLE B058 SU;Lo;0;L;;;;;N;;;;; +10032;LINEAR B SYLLABLE B059 TA;Lo;0;L;;;;;N;;;;; +10033;LINEAR B SYLLABLE B004 TE;Lo;0;L;;;;;N;;;;; +10034;LINEAR B SYLLABLE B037 TI;Lo;0;L;;;;;N;;;;; +10035;LINEAR B SYLLABLE B005 TO;Lo;0;L;;;;;N;;;;; +10036;LINEAR B SYLLABLE B069 TU;Lo;0;L;;;;;N;;;;; +10037;LINEAR B SYLLABLE B054 WA;Lo;0;L;;;;;N;;;;; +10038;LINEAR B SYLLABLE B075 WE;Lo;0;L;;;;;N;;;;; +10039;LINEAR B SYLLABLE B040 WI;Lo;0;L;;;;;N;;;;; +1003A;LINEAR B SYLLABLE B042 WO;Lo;0;L;;;;;N;;;;; +1003C;LINEAR B SYLLABLE B017 ZA;Lo;0;L;;;;;N;;;;; +1003D;LINEAR B SYLLABLE B074 ZE;Lo;0;L;;;;;N;;;;; +1003F;LINEAR B SYLLABLE B020 ZO;Lo;0;L;;;;;N;;;;; +10040;LINEAR B SYLLABLE B025 A2;Lo;0;L;;;;;N;;;;; +10041;LINEAR B SYLLABLE B043 A3;Lo;0;L;;;;;N;;;;; +10042;LINEAR B SYLLABLE B085 AU;Lo;0;L;;;;;N;;;;; +10043;LINEAR B SYLLABLE B071 DWE;Lo;0;L;;;;;N;;;;; +10044;LINEAR B SYLLABLE B090 DWO;Lo;0;L;;;;;N;;;;; +10045;LINEAR B SYLLABLE B048 NWA;Lo;0;L;;;;;N;;;;; +10046;LINEAR B SYLLABLE B029 PU2;Lo;0;L;;;;;N;;;;; +10047;LINEAR B SYLLABLE B062 PTE;Lo;0;L;;;;;N;;;;; +10048;LINEAR B SYLLABLE B076 RA2;Lo;0;L;;;;;N;;;;; +10049;LINEAR B SYLLABLE B033 RA3;Lo;0;L;;;;;N;;;;; +1004A;LINEAR B SYLLABLE B068 RO2;Lo;0;L;;;;;N;;;;; +1004B;LINEAR B SYLLABLE B066 TA2;Lo;0;L;;;;;N;;;;; +1004C;LINEAR B SYLLABLE B087 TWE;Lo;0;L;;;;;N;;;;; +1004D;LINEAR B SYLLABLE B091 TWO;Lo;0;L;;;;;N;;;;; +10050;LINEAR B SYMBOL B018;Lo;0;L;;;;;N;;;;; +10051;LINEAR B SYMBOL B019;Lo;0;L;;;;;N;;;;; +10052;LINEAR B SYMBOL B022;Lo;0;L;;;;;N;;;;; +10053;LINEAR B SYMBOL B034;Lo;0;L;;;;;N;;;;; +10054;LINEAR B SYMBOL B047;Lo;0;L;;;;;N;;;;; +10055;LINEAR B SYMBOL B049;Lo;0;L;;;;;N;;;;; +10056;LINEAR B SYMBOL B056;Lo;0;L;;;;;N;;;;; +10057;LINEAR B SYMBOL B063;Lo;0;L;;;;;N;;;;; +10058;LINEAR B SYMBOL B064;Lo;0;L;;;;;N;;;;; +10059;LINEAR B SYMBOL B079;Lo;0;L;;;;;N;;;;; +1005A;LINEAR B SYMBOL B082;Lo;0;L;;;;;N;;;;; +1005B;LINEAR B SYMBOL B083;Lo;0;L;;;;;N;;;;; +1005C;LINEAR B SYMBOL B086;Lo;0;L;;;;;N;;;;; +1005D;LINEAR B SYMBOL B089;Lo;0;L;;;;;N;;;;; +10080;LINEAR B IDEOGRAM B100 MAN;Lo;0;L;;;;;N;;;;; +10081;LINEAR B IDEOGRAM B102 WOMAN;Lo;0;L;;;;;N;;;;; +10082;LINEAR B IDEOGRAM B104 DEER;Lo;0;L;;;;;N;;;;; +10083;LINEAR B IDEOGRAM B105 EQUID;Lo;0;L;;;;;N;;;;; +10084;LINEAR B IDEOGRAM B105F MARE;Lo;0;L;;;;;N;;;;; +10085;LINEAR B IDEOGRAM B105M STALLION;Lo;0;L;;;;;N;;;;; +10086;LINEAR B IDEOGRAM B106F EWE;Lo;0;L;;;;;N;;;;; +10087;LINEAR B IDEOGRAM B106M RAM;Lo;0;L;;;;;N;;;;; +10088;LINEAR B IDEOGRAM B107F SHE-GOAT;Lo;0;L;;;;;N;;;;; +10089;LINEAR B IDEOGRAM B107M HE-GOAT;Lo;0;L;;;;;N;;;;; +1008A;LINEAR B IDEOGRAM B108F SOW;Lo;0;L;;;;;N;;;;; +1008B;LINEAR B IDEOGRAM B108M BOAR;Lo;0;L;;;;;N;;;;; +1008C;LINEAR B IDEOGRAM B109F COW;Lo;0;L;;;;;N;;;;; +1008D;LINEAR B IDEOGRAM B109M BULL;Lo;0;L;;;;;N;;;;; +1008E;LINEAR B IDEOGRAM B120 WHEAT;Lo;0;L;;;;;N;;;;; +1008F;LINEAR B IDEOGRAM B121 BARLEY;Lo;0;L;;;;;N;;;;; +10090;LINEAR B IDEOGRAM B122 OLIVE;Lo;0;L;;;;;N;;;;; +10091;LINEAR B IDEOGRAM B123 SPICE;Lo;0;L;;;;;N;;;;; +10092;LINEAR B IDEOGRAM B125 CYPERUS;Lo;0;L;;;;;N;;;;; +10093;LINEAR B MONOGRAM B127 KAPO;Lo;0;L;;;;;N;;;;; +10094;LINEAR B MONOGRAM B128 KANAKO;Lo;0;L;;;;;N;;;;; +10095;LINEAR B IDEOGRAM B130 OIL;Lo;0;L;;;;;N;;;;; +10096;LINEAR B IDEOGRAM B131 WINE;Lo;0;L;;;;;N;;;;; +10097;LINEAR B IDEOGRAM B132;Lo;0;L;;;;;N;;;;; +10098;LINEAR B MONOGRAM B133 AREPA;Lo;0;L;;;;;N;;;;; +10099;LINEAR B MONOGRAM B135 MERI;Lo;0;L;;;;;N;;;;; +1009A;LINEAR B IDEOGRAM B140 BRONZE;Lo;0;L;;;;;N;;;;; +1009B;LINEAR B IDEOGRAM B141 GOLD;Lo;0;L;;;;;N;;;;; +1009C;LINEAR B IDEOGRAM B142;Lo;0;L;;;;;N;;;;; +1009D;LINEAR B IDEOGRAM B145 WOOL;Lo;0;L;;;;;N;;;;; +1009E;LINEAR B IDEOGRAM B146;Lo;0;L;;;;;N;;;;; +1009F;LINEAR B IDEOGRAM B150;Lo;0;L;;;;;N;;;;; +100A0;LINEAR B IDEOGRAM B151 HORN;Lo;0;L;;;;;N;;;;; +100A1;LINEAR B IDEOGRAM B152;Lo;0;L;;;;;N;;;;; +100A2;LINEAR B IDEOGRAM B153;Lo;0;L;;;;;N;;;;; +100A3;LINEAR B IDEOGRAM B154;Lo;0;L;;;;;N;;;;; +100A4;LINEAR B MONOGRAM B156 TURO2;Lo;0;L;;;;;N;;;;; +100A5;LINEAR B IDEOGRAM B157;Lo;0;L;;;;;N;;;;; +100A6;LINEAR B IDEOGRAM B158;Lo;0;L;;;;;N;;;;; +100A7;LINEAR B IDEOGRAM B159 CLOTH;Lo;0;L;;;;;N;;;;; +100A8;LINEAR B IDEOGRAM B160;Lo;0;L;;;;;N;;;;; +100A9;LINEAR B IDEOGRAM B161;Lo;0;L;;;;;N;;;;; +100AA;LINEAR B IDEOGRAM B162 GARMENT;Lo;0;L;;;;;N;;;;; +100AB;LINEAR B IDEOGRAM B163 ARMOUR;Lo;0;L;;;;;N;;;;; +100AC;LINEAR B IDEOGRAM B164;Lo;0;L;;;;;N;;;;; +100AD;LINEAR B IDEOGRAM B165;Lo;0;L;;;;;N;;;;; +100AE;LINEAR B IDEOGRAM B166;Lo;0;L;;;;;N;;;;; +100AF;LINEAR B IDEOGRAM B167;Lo;0;L;;;;;N;;;;; +100B0;LINEAR B IDEOGRAM B168;Lo;0;L;;;;;N;;;;; +100B1;LINEAR B IDEOGRAM B169;Lo;0;L;;;;;N;;;;; +100B2;LINEAR B IDEOGRAM B170;Lo;0;L;;;;;N;;;;; +100B3;LINEAR B IDEOGRAM B171;Lo;0;L;;;;;N;;;;; +100B4;LINEAR B IDEOGRAM B172;Lo;0;L;;;;;N;;;;; +100B5;LINEAR B IDEOGRAM B173 MONTH;Lo;0;L;;;;;N;;;;; +100B6;LINEAR B IDEOGRAM B174;Lo;0;L;;;;;N;;;;; +100B7;LINEAR B IDEOGRAM B176 TREE;Lo;0;L;;;;;N;;;;; +100B8;LINEAR B IDEOGRAM B177;Lo;0;L;;;;;N;;;;; +100B9;LINEAR B IDEOGRAM B178;Lo;0;L;;;;;N;;;;; +100BA;LINEAR B IDEOGRAM B179;Lo;0;L;;;;;N;;;;; +100BB;LINEAR B IDEOGRAM B180;Lo;0;L;;;;;N;;;;; +100BC;LINEAR B IDEOGRAM B181;Lo;0;L;;;;;N;;;;; +100BD;LINEAR B IDEOGRAM B182;Lo;0;L;;;;;N;;;;; +100BE;LINEAR B IDEOGRAM B183;Lo;0;L;;;;;N;;;;; +100BF;LINEAR B IDEOGRAM B184;Lo;0;L;;;;;N;;;;; +100C0;LINEAR B IDEOGRAM B185;Lo;0;L;;;;;N;;;;; +100C1;LINEAR B IDEOGRAM B189;Lo;0;L;;;;;N;;;;; +100C2;LINEAR B IDEOGRAM B190;Lo;0;L;;;;;N;;;;; +100C3;LINEAR B IDEOGRAM B191 HELMET;Lo;0;L;;;;;N;;;;; +100C4;LINEAR B IDEOGRAM B220 FOOTSTOOL;Lo;0;L;;;;;N;;;;; +100C5;LINEAR B IDEOGRAM B225 BATHTUB;Lo;0;L;;;;;N;;;;; +100C6;LINEAR B IDEOGRAM B230 SPEAR;Lo;0;L;;;;;N;;;;; +100C7;LINEAR B IDEOGRAM B231 ARROW;Lo;0;L;;;;;N;;;;; +100C8;LINEAR B IDEOGRAM B232;Lo;0;L;;;;;N;;;;; +100C9;LINEAR B IDEOGRAM B233 SWORD;Lo;0;L;;;;;N;;;;; +100CA;LINEAR B IDEOGRAM B234;Lo;0;L;;;;;N;;;;; +100CB;LINEAR B IDEOGRAM B236;Lo;0;L;;;;;N;;;;; +100CC;LINEAR B IDEOGRAM B240 WHEELED CHARIOT;Lo;0;L;;;;;N;;;;; +100CD;LINEAR B IDEOGRAM B241 CHARIOT;Lo;0;L;;;;;N;;;;; +100CE;LINEAR B IDEOGRAM B242 CHARIOT FRAME;Lo;0;L;;;;;N;;;;; +100CF;LINEAR B IDEOGRAM B243 WHEEL;Lo;0;L;;;;;N;;;;; +100D0;LINEAR B IDEOGRAM B245;Lo;0;L;;;;;N;;;;; +100D1;LINEAR B IDEOGRAM B246;Lo;0;L;;;;;N;;;;; +100D2;LINEAR B MONOGRAM B247 DIPTE;Lo;0;L;;;;;N;;;;; +100D3;LINEAR B IDEOGRAM B248;Lo;0;L;;;;;N;;;;; +100D4;LINEAR B IDEOGRAM B249;Lo;0;L;;;;;N;;;;; +100D5;LINEAR B IDEOGRAM B251;Lo;0;L;;;;;N;;;;; +100D6;LINEAR B IDEOGRAM B252;Lo;0;L;;;;;N;;;;; +100D7;LINEAR B IDEOGRAM B253;Lo;0;L;;;;;N;;;;; +100D8;LINEAR B IDEOGRAM B254 DART;Lo;0;L;;;;;N;;;;; +100D9;LINEAR B IDEOGRAM B255;Lo;0;L;;;;;N;;;;; +100DA;LINEAR B IDEOGRAM B256;Lo;0;L;;;;;N;;;;; +100DB;LINEAR B IDEOGRAM B257;Lo;0;L;;;;;N;;;;; +100DC;LINEAR B IDEOGRAM B258;Lo;0;L;;;;;N;;;;; +100DD;LINEAR B IDEOGRAM B259;Lo;0;L;;;;;N;;;;; +100DE;LINEAR B IDEOGRAM VESSEL B155;Lo;0;L;;;;;N;;;;; +100DF;LINEAR B IDEOGRAM VESSEL B200;Lo;0;L;;;;;N;;;;; +100E0;LINEAR B IDEOGRAM VESSEL B201;Lo;0;L;;;;;N;;;;; +100E1;LINEAR B IDEOGRAM VESSEL B202;Lo;0;L;;;;;N;;;;; +100E2;LINEAR B IDEOGRAM VESSEL B203;Lo;0;L;;;;;N;;;;; +100E3;LINEAR B IDEOGRAM VESSEL B204;Lo;0;L;;;;;N;;;;; +100E4;LINEAR B IDEOGRAM VESSEL B205;Lo;0;L;;;;;N;;;;; +100E5;LINEAR B IDEOGRAM VESSEL B206;Lo;0;L;;;;;N;;;;; +100E6;LINEAR B IDEOGRAM VESSEL B207;Lo;0;L;;;;;N;;;;; +100E7;LINEAR B IDEOGRAM VESSEL B208;Lo;0;L;;;;;N;;;;; +100E8;LINEAR B IDEOGRAM VESSEL B209;Lo;0;L;;;;;N;;;;; +100E9;LINEAR B IDEOGRAM VESSEL B210;Lo;0;L;;;;;N;;;;; +100EA;LINEAR B IDEOGRAM VESSEL B211;Lo;0;L;;;;;N;;;;; +100EB;LINEAR B IDEOGRAM VESSEL B212;Lo;0;L;;;;;N;;;;; +100EC;LINEAR B IDEOGRAM VESSEL B213;Lo;0;L;;;;;N;;;;; +100ED;LINEAR B IDEOGRAM VESSEL B214;Lo;0;L;;;;;N;;;;; +100EE;LINEAR B IDEOGRAM VESSEL B215;Lo;0;L;;;;;N;;;;; +100EF;LINEAR B IDEOGRAM VESSEL B216;Lo;0;L;;;;;N;;;;; +100F0;LINEAR B IDEOGRAM VESSEL B217;Lo;0;L;;;;;N;;;;; +100F1;LINEAR B IDEOGRAM VESSEL B218;Lo;0;L;;;;;N;;;;; +100F2;LINEAR B IDEOGRAM VESSEL B219;Lo;0;L;;;;;N;;;;; +100F3;LINEAR B IDEOGRAM VESSEL B221;Lo;0;L;;;;;N;;;;; +100F4;LINEAR B IDEOGRAM VESSEL B222;Lo;0;L;;;;;N;;;;; +100F5;LINEAR B IDEOGRAM VESSEL B226;Lo;0;L;;;;;N;;;;; +100F6;LINEAR B IDEOGRAM VESSEL B227;Lo;0;L;;;;;N;;;;; +100F7;LINEAR B IDEOGRAM VESSEL B228;Lo;0;L;;;;;N;;;;; +100F8;LINEAR B IDEOGRAM VESSEL B229;Lo;0;L;;;;;N;;;;; +100F9;LINEAR B IDEOGRAM VESSEL B250;Lo;0;L;;;;;N;;;;; +100FA;LINEAR B IDEOGRAM VESSEL B305;Lo;0;L;;;;;N;;;;; +10100;AEGEAN WORD SEPARATOR LINE;Po;0;L;;;;;N;;;;; +10101;AEGEAN WORD SEPARATOR DOT;Po;0;ON;;;;;N;;;;; +10102;AEGEAN CHECK MARK;Po;0;L;;;;;N;;;;; +10107;AEGEAN NUMBER ONE;No;0;L;;;;1;N;;;;; +10108;AEGEAN NUMBER TWO;No;0;L;;;;2;N;;;;; +10109;AEGEAN NUMBER THREE;No;0;L;;;;3;N;;;;; +1010A;AEGEAN NUMBER FOUR;No;0;L;;;;4;N;;;;; +1010B;AEGEAN NUMBER FIVE;No;0;L;;;;5;N;;;;; +1010C;AEGEAN NUMBER SIX;No;0;L;;;;6;N;;;;; +1010D;AEGEAN NUMBER SEVEN;No;0;L;;;;7;N;;;;; +1010E;AEGEAN NUMBER EIGHT;No;0;L;;;;8;N;;;;; +1010F;AEGEAN NUMBER NINE;No;0;L;;;;9;N;;;;; +10110;AEGEAN NUMBER TEN;No;0;L;;;;10;N;;;;; +10111;AEGEAN NUMBER TWENTY;No;0;L;;;;20;N;;;;; +10112;AEGEAN NUMBER THIRTY;No;0;L;;;;30;N;;;;; +10113;AEGEAN NUMBER FORTY;No;0;L;;;;40;N;;;;; +10114;AEGEAN NUMBER FIFTY;No;0;L;;;;50;N;;;;; +10115;AEGEAN NUMBER SIXTY;No;0;L;;;;60;N;;;;; +10116;AEGEAN NUMBER SEVENTY;No;0;L;;;;70;N;;;;; +10117;AEGEAN NUMBER EIGHTY;No;0;L;;;;80;N;;;;; +10118;AEGEAN NUMBER NINETY;No;0;L;;;;90;N;;;;; +10119;AEGEAN NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;; +1011A;AEGEAN NUMBER TWO HUNDRED;No;0;L;;;;200;N;;;;; +1011B;AEGEAN NUMBER THREE HUNDRED;No;0;L;;;;300;N;;;;; +1011C;AEGEAN NUMBER FOUR HUNDRED;No;0;L;;;;400;N;;;;; +1011D;AEGEAN NUMBER FIVE HUNDRED;No;0;L;;;;500;N;;;;; +1011E;AEGEAN NUMBER SIX HUNDRED;No;0;L;;;;600;N;;;;; +1011F;AEGEAN NUMBER SEVEN HUNDRED;No;0;L;;;;700;N;;;;; +10120;AEGEAN NUMBER EIGHT HUNDRED;No;0;L;;;;800;N;;;;; +10121;AEGEAN NUMBER NINE HUNDRED;No;0;L;;;;900;N;;;;; +10122;AEGEAN NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;; +10123;AEGEAN NUMBER TWO THOUSAND;No;0;L;;;;2000;N;;;;; +10124;AEGEAN NUMBER THREE THOUSAND;No;0;L;;;;3000;N;;;;; +10125;AEGEAN NUMBER FOUR THOUSAND;No;0;L;;;;4000;N;;;;; +10126;AEGEAN NUMBER FIVE THOUSAND;No;0;L;;;;5000;N;;;;; +10127;AEGEAN NUMBER SIX THOUSAND;No;0;L;;;;6000;N;;;;; +10128;AEGEAN NUMBER SEVEN THOUSAND;No;0;L;;;;7000;N;;;;; +10129;AEGEAN NUMBER EIGHT THOUSAND;No;0;L;;;;8000;N;;;;; +1012A;AEGEAN NUMBER NINE THOUSAND;No;0;L;;;;9000;N;;;;; +1012B;AEGEAN NUMBER TEN THOUSAND;No;0;L;;;;10000;N;;;;; +1012C;AEGEAN NUMBER TWENTY THOUSAND;No;0;L;;;;20000;N;;;;; +1012D;AEGEAN NUMBER THIRTY THOUSAND;No;0;L;;;;30000;N;;;;; +1012E;AEGEAN NUMBER FORTY THOUSAND;No;0;L;;;;40000;N;;;;; +1012F;AEGEAN NUMBER FIFTY THOUSAND;No;0;L;;;;50000;N;;;;; +10130;AEGEAN NUMBER SIXTY THOUSAND;No;0;L;;;;60000;N;;;;; +10131;AEGEAN NUMBER SEVENTY THOUSAND;No;0;L;;;;70000;N;;;;; +10132;AEGEAN NUMBER EIGHTY THOUSAND;No;0;L;;;;80000;N;;;;; +10133;AEGEAN NUMBER NINETY THOUSAND;No;0;L;;;;90000;N;;;;; +10137;AEGEAN WEIGHT BASE UNIT;So;0;L;;;;;N;;;;; +10138;AEGEAN WEIGHT FIRST SUBUNIT;So;0;L;;;;;N;;;;; +10139;AEGEAN WEIGHT SECOND SUBUNIT;So;0;L;;;;;N;;;;; +1013A;AEGEAN WEIGHT THIRD SUBUNIT;So;0;L;;;;;N;;;;; +1013B;AEGEAN WEIGHT FOURTH SUBUNIT;So;0;L;;;;;N;;;;; +1013C;AEGEAN DRY MEASURE FIRST SUBUNIT;So;0;L;;;;;N;;;;; +1013D;AEGEAN LIQUID MEASURE FIRST SUBUNIT;So;0;L;;;;;N;;;;; +1013E;AEGEAN MEASURE SECOND SUBUNIT;So;0;L;;;;;N;;;;; +1013F;AEGEAN MEASURE THIRD SUBUNIT;So;0;L;;;;;N;;;;; +10140;GREEK ACROPHONIC ATTIC ONE QUARTER;Nl;0;ON;;;;1/4;N;;;;; +10141;GREEK ACROPHONIC ATTIC ONE HALF;Nl;0;ON;;;;1/2;N;;;;; +10142;GREEK ACROPHONIC ATTIC ONE DRACHMA;Nl;0;ON;;;;1;N;;;;; +10143;GREEK ACROPHONIC ATTIC FIVE;Nl;0;ON;;;;5;N;;;;; +10144;GREEK ACROPHONIC ATTIC FIFTY;Nl;0;ON;;;;50;N;;;;; +10145;GREEK ACROPHONIC ATTIC FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +10146;GREEK ACROPHONIC ATTIC FIVE THOUSAND;Nl;0;ON;;;;5000;N;;;;; +10147;GREEK ACROPHONIC ATTIC FIFTY THOUSAND;Nl;0;ON;;;;50000;N;;;;; +10148;GREEK ACROPHONIC ATTIC FIVE TALENTS;Nl;0;ON;;;;5;N;;;;; +10149;GREEK ACROPHONIC ATTIC TEN TALENTS;Nl;0;ON;;;;10;N;;;;; +1014A;GREEK ACROPHONIC ATTIC FIFTY TALENTS;Nl;0;ON;;;;50;N;;;;; +1014B;GREEK ACROPHONIC ATTIC ONE HUNDRED TALENTS;Nl;0;ON;;;;100;N;;;;; +1014C;GREEK ACROPHONIC ATTIC FIVE HUNDRED TALENTS;Nl;0;ON;;;;500;N;;;;; +1014D;GREEK ACROPHONIC ATTIC ONE THOUSAND TALENTS;Nl;0;ON;;;;1000;N;;;;; +1014E;GREEK ACROPHONIC ATTIC FIVE THOUSAND TALENTS;Nl;0;ON;;;;5000;N;;;;; +1014F;GREEK ACROPHONIC ATTIC FIVE STATERS;Nl;0;ON;;;;5;N;;;;; +10150;GREEK ACROPHONIC ATTIC TEN STATERS;Nl;0;ON;;;;10;N;;;;; +10151;GREEK ACROPHONIC ATTIC FIFTY STATERS;Nl;0;ON;;;;50;N;;;;; +10152;GREEK ACROPHONIC ATTIC ONE HUNDRED STATERS;Nl;0;ON;;;;100;N;;;;; +10153;GREEK ACROPHONIC ATTIC FIVE HUNDRED STATERS;Nl;0;ON;;;;500;N;;;;; +10154;GREEK ACROPHONIC ATTIC ONE THOUSAND STATERS;Nl;0;ON;;;;1000;N;;;;; +10155;GREEK ACROPHONIC ATTIC TEN THOUSAND STATERS;Nl;0;ON;;;;10000;N;;;;; +10156;GREEK ACROPHONIC ATTIC FIFTY THOUSAND STATERS;Nl;0;ON;;;;50000;N;;;;; +10157;GREEK ACROPHONIC ATTIC TEN MNAS;Nl;0;ON;;;;10;N;;;;; +10158;GREEK ACROPHONIC HERAEUM ONE PLETHRON;Nl;0;ON;;;;1;N;;;;; +10159;GREEK ACROPHONIC THESPIAN ONE;Nl;0;ON;;;;1;N;;;;; +1015A;GREEK ACROPHONIC HERMIONIAN ONE;Nl;0;ON;;;;1;N;;;;; +1015B;GREEK ACROPHONIC EPIDAUREAN TWO;Nl;0;ON;;;;2;N;;;;; +1015C;GREEK ACROPHONIC THESPIAN TWO;Nl;0;ON;;;;2;N;;;;; +1015D;GREEK ACROPHONIC CYRENAIC TWO DRACHMAS;Nl;0;ON;;;;2;N;;;;; +1015E;GREEK ACROPHONIC EPIDAUREAN TWO DRACHMAS;Nl;0;ON;;;;2;N;;;;; +1015F;GREEK ACROPHONIC TROEZENIAN FIVE;Nl;0;ON;;;;5;N;;;;; +10160;GREEK ACROPHONIC TROEZENIAN TEN;Nl;0;ON;;;;10;N;;;;; +10161;GREEK ACROPHONIC TROEZENIAN TEN ALTERNATE FORM;Nl;0;ON;;;;10;N;;;;; +10162;GREEK ACROPHONIC HERMIONIAN TEN;Nl;0;ON;;;;10;N;;;;; +10163;GREEK ACROPHONIC MESSENIAN TEN;Nl;0;ON;;;;10;N;;;;; +10164;GREEK ACROPHONIC THESPIAN TEN;Nl;0;ON;;;;10;N;;;;; +10165;GREEK ACROPHONIC THESPIAN THIRTY;Nl;0;ON;;;;30;N;;;;; +10166;GREEK ACROPHONIC TROEZENIAN FIFTY;Nl;0;ON;;;;50;N;;;;; +10167;GREEK ACROPHONIC TROEZENIAN FIFTY ALTERNATE FORM;Nl;0;ON;;;;50;N;;;;; +10168;GREEK ACROPHONIC HERMIONIAN FIFTY;Nl;0;ON;;;;50;N;;;;; +10169;GREEK ACROPHONIC THESPIAN FIFTY;Nl;0;ON;;;;50;N;;;;; +1016A;GREEK ACROPHONIC THESPIAN ONE HUNDRED;Nl;0;ON;;;;100;N;;;;; +1016B;GREEK ACROPHONIC THESPIAN THREE HUNDRED;Nl;0;ON;;;;300;N;;;;; +1016C;GREEK ACROPHONIC EPIDAUREAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +1016D;GREEK ACROPHONIC TROEZENIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +1016E;GREEK ACROPHONIC THESPIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +1016F;GREEK ACROPHONIC CARYSTIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +10170;GREEK ACROPHONIC NAXIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;; +10171;GREEK ACROPHONIC THESPIAN ONE THOUSAND;Nl;0;ON;;;;1000;N;;;;; +10172;GREEK ACROPHONIC THESPIAN FIVE THOUSAND;Nl;0;ON;;;;5000;N;;;;; +10173;GREEK ACROPHONIC DELPHIC FIVE MNAS;Nl;0;ON;;;;5;N;;;;; +10174;GREEK ACROPHONIC STRATIAN FIFTY MNAS;Nl;0;ON;;;;50;N;;;;; +10175;GREEK ONE HALF SIGN;No;0;ON;;;;1/2;N;;;;; +10176;GREEK ONE HALF SIGN ALTERNATE FORM;No;0;ON;;;;1/2;N;;;;; +10177;GREEK TWO THIRDS SIGN;No;0;ON;;;;2/3;N;;;;; +10178;GREEK THREE QUARTERS SIGN;No;0;ON;;;;3/4;N;;;;; +10179;GREEK YEAR SIGN;So;0;ON;;;;;N;;;;; +1017A;GREEK TALENT SIGN;So;0;ON;;;;;N;;;;; +1017B;GREEK DRACHMA SIGN;So;0;ON;;;;;N;;;;; +1017C;GREEK OBOL SIGN;So;0;ON;;;;;N;;;;; +1017D;GREEK TWO OBOLS SIGN;So;0;ON;;;;;N;;;;; +1017E;GREEK THREE OBOLS SIGN;So;0;ON;;;;;N;;;;; +1017F;GREEK FOUR OBOLS SIGN;So;0;ON;;;;;N;;;;; +10180;GREEK FIVE OBOLS SIGN;So;0;ON;;;;;N;;;;; +10181;GREEK METRETES SIGN;So;0;ON;;;;;N;;;;; +10182;GREEK KYATHOS BASE SIGN;So;0;ON;;;;;N;;;;; +10183;GREEK LITRA SIGN;So;0;ON;;;;;N;;;;; +10184;GREEK OUNKIA SIGN;So;0;ON;;;;;N;;;;; +10185;GREEK XESTES SIGN;So;0;ON;;;;;N;;;;; +10186;GREEK ARTABE SIGN;So;0;ON;;;;;N;;;;; +10187;GREEK AROURA SIGN;So;0;ON;;;;;N;;;;; +10188;GREEK GRAMMA SIGN;So;0;ON;;;;;N;;;;; +10189;GREEK TRYBLION BASE SIGN;So;0;ON;;;;;N;;;;; +1018A;GREEK ZERO SIGN;No;0;ON;;;;0;N;;;;; +1018B;GREEK ONE QUARTER SIGN;No;0;ON;;;;1/4;N;;;;; +1018C;GREEK SINUSOID SIGN;So;0;ON;;;;;N;;;;; +1018D;GREEK INDICTION SIGN;So;0;L;;;;;N;;;;; +1018E;NOMISMA SIGN;So;0;L;;;;;N;;;;; +10190;ROMAN SEXTANS SIGN;So;0;ON;;;;;N;;;;; +10191;ROMAN UNCIA SIGN;So;0;ON;;;;;N;;;;; +10192;ROMAN SEMUNCIA SIGN;So;0;ON;;;;;N;;;;; +10193;ROMAN SEXTULA SIGN;So;0;ON;;;;;N;;;;; +10194;ROMAN DIMIDIA SEXTULA SIGN;So;0;ON;;;;;N;;;;; +10195;ROMAN SILIQUA SIGN;So;0;ON;;;;;N;;;;; +10196;ROMAN DENARIUS SIGN;So;0;ON;;;;;N;;;;; +10197;ROMAN QUINARIUS SIGN;So;0;ON;;;;;N;;;;; +10198;ROMAN SESTERTIUS SIGN;So;0;ON;;;;;N;;;;; +10199;ROMAN DUPONDIUS SIGN;So;0;ON;;;;;N;;;;; +1019A;ROMAN AS SIGN;So;0;ON;;;;;N;;;;; +1019B;ROMAN CENTURIAL SIGN;So;0;ON;;;;;N;;;;; +101A0;GREEK SYMBOL TAU RHO;So;0;ON;;;;;N;;;;; +101D0;PHAISTOS DISC SIGN PEDESTRIAN;So;0;L;;;;;N;;;;; +101D1;PHAISTOS DISC SIGN PLUMED HEAD;So;0;L;;;;;N;;;;; +101D2;PHAISTOS DISC SIGN TATTOOED HEAD;So;0;L;;;;;N;;;;; +101D3;PHAISTOS DISC SIGN CAPTIVE;So;0;L;;;;;N;;;;; +101D4;PHAISTOS DISC SIGN CHILD;So;0;L;;;;;N;;;;; +101D5;PHAISTOS DISC SIGN WOMAN;So;0;L;;;;;N;;;;; +101D6;PHAISTOS DISC SIGN HELMET;So;0;L;;;;;N;;;;; +101D7;PHAISTOS DISC SIGN GAUNTLET;So;0;L;;;;;N;;;;; +101D8;PHAISTOS DISC SIGN TIARA;So;0;L;;;;;N;;;;; +101D9;PHAISTOS DISC SIGN ARROW;So;0;L;;;;;N;;;;; +101DA;PHAISTOS DISC SIGN BOW;So;0;L;;;;;N;;;;; +101DB;PHAISTOS DISC SIGN SHIELD;So;0;L;;;;;N;;;;; +101DC;PHAISTOS DISC SIGN CLUB;So;0;L;;;;;N;;;;; +101DD;PHAISTOS DISC SIGN MANACLES;So;0;L;;;;;N;;;;; +101DE;PHAISTOS DISC SIGN MATTOCK;So;0;L;;;;;N;;;;; +101DF;PHAISTOS DISC SIGN SAW;So;0;L;;;;;N;;;;; +101E0;PHAISTOS DISC SIGN LID;So;0;L;;;;;N;;;;; +101E1;PHAISTOS DISC SIGN BOOMERANG;So;0;L;;;;;N;;;;; +101E2;PHAISTOS DISC SIGN CARPENTRY PLANE;So;0;L;;;;;N;;;;; +101E3;PHAISTOS DISC SIGN DOLIUM;So;0;L;;;;;N;;;;; +101E4;PHAISTOS DISC SIGN COMB;So;0;L;;;;;N;;;;; +101E5;PHAISTOS DISC SIGN SLING;So;0;L;;;;;N;;;;; +101E6;PHAISTOS DISC SIGN COLUMN;So;0;L;;;;;N;;;;; +101E7;PHAISTOS DISC SIGN BEEHIVE;So;0;L;;;;;N;;;;; +101E8;PHAISTOS DISC SIGN SHIP;So;0;L;;;;;N;;;;; +101E9;PHAISTOS DISC SIGN HORN;So;0;L;;;;;N;;;;; +101EA;PHAISTOS DISC SIGN HIDE;So;0;L;;;;;N;;;;; +101EB;PHAISTOS DISC SIGN BULLS LEG;So;0;L;;;;;N;;;;; +101EC;PHAISTOS DISC SIGN CAT;So;0;L;;;;;N;;;;; +101ED;PHAISTOS DISC SIGN RAM;So;0;L;;;;;N;;;;; +101EE;PHAISTOS DISC SIGN EAGLE;So;0;L;;;;;N;;;;; +101EF;PHAISTOS DISC SIGN DOVE;So;0;L;;;;;N;;;;; +101F0;PHAISTOS DISC SIGN TUNNY;So;0;L;;;;;N;;;;; +101F1;PHAISTOS DISC SIGN BEE;So;0;L;;;;;N;;;;; +101F2;PHAISTOS DISC SIGN PLANE TREE;So;0;L;;;;;N;;;;; +101F3;PHAISTOS DISC SIGN VINE;So;0;L;;;;;N;;;;; +101F4;PHAISTOS DISC SIGN PAPYRUS;So;0;L;;;;;N;;;;; +101F5;PHAISTOS DISC SIGN ROSETTE;So;0;L;;;;;N;;;;; +101F6;PHAISTOS DISC SIGN LILY;So;0;L;;;;;N;;;;; +101F7;PHAISTOS DISC SIGN OX BACK;So;0;L;;;;;N;;;;; +101F8;PHAISTOS DISC SIGN FLUTE;So;0;L;;;;;N;;;;; +101F9;PHAISTOS DISC SIGN GRATER;So;0;L;;;;;N;;;;; +101FA;PHAISTOS DISC SIGN STRAINER;So;0;L;;;;;N;;;;; +101FB;PHAISTOS DISC SIGN SMALL AXE;So;0;L;;;;;N;;;;; +101FC;PHAISTOS DISC SIGN WAVY BAND;So;0;L;;;;;N;;;;; +101FD;PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE;Mn;220;NSM;;;;;N;;;;; +10280;LYCIAN LETTER A;Lo;0;L;;;;;N;;;;; +10281;LYCIAN LETTER E;Lo;0;L;;;;;N;;;;; +10282;LYCIAN LETTER B;Lo;0;L;;;;;N;;;;; +10283;LYCIAN LETTER BH;Lo;0;L;;;;;N;;;;; +10284;LYCIAN LETTER G;Lo;0;L;;;;;N;;;;; +10285;LYCIAN LETTER D;Lo;0;L;;;;;N;;;;; +10286;LYCIAN LETTER I;Lo;0;L;;;;;N;;;;; +10287;LYCIAN LETTER W;Lo;0;L;;;;;N;;;;; +10288;LYCIAN LETTER Z;Lo;0;L;;;;;N;;;;; +10289;LYCIAN LETTER TH;Lo;0;L;;;;;N;;;;; +1028A;LYCIAN LETTER J;Lo;0;L;;;;;N;;;;; +1028B;LYCIAN LETTER K;Lo;0;L;;;;;N;;;;; +1028C;LYCIAN LETTER Q;Lo;0;L;;;;;N;;;;; +1028D;LYCIAN LETTER L;Lo;0;L;;;;;N;;;;; +1028E;LYCIAN LETTER M;Lo;0;L;;;;;N;;;;; +1028F;LYCIAN LETTER N;Lo;0;L;;;;;N;;;;; +10290;LYCIAN LETTER MM;Lo;0;L;;;;;N;;;;; +10291;LYCIAN LETTER NN;Lo;0;L;;;;;N;;;;; +10292;LYCIAN LETTER U;Lo;0;L;;;;;N;;;;; +10293;LYCIAN LETTER P;Lo;0;L;;;;;N;;;;; +10294;LYCIAN LETTER KK;Lo;0;L;;;;;N;;;;; +10295;LYCIAN LETTER R;Lo;0;L;;;;;N;;;;; +10296;LYCIAN LETTER S;Lo;0;L;;;;;N;;;;; +10297;LYCIAN LETTER T;Lo;0;L;;;;;N;;;;; +10298;LYCIAN LETTER TT;Lo;0;L;;;;;N;;;;; +10299;LYCIAN LETTER AN;Lo;0;L;;;;;N;;;;; +1029A;LYCIAN LETTER EN;Lo;0;L;;;;;N;;;;; +1029B;LYCIAN LETTER H;Lo;0;L;;;;;N;;;;; +1029C;LYCIAN LETTER X;Lo;0;L;;;;;N;;;;; +102A0;CARIAN LETTER A;Lo;0;L;;;;;N;;;;; +102A1;CARIAN LETTER P2;Lo;0;L;;;;;N;;;;; +102A2;CARIAN LETTER D;Lo;0;L;;;;;N;;;;; +102A3;CARIAN LETTER L;Lo;0;L;;;;;N;;;;; +102A4;CARIAN LETTER UUU;Lo;0;L;;;;;N;;;;; +102A5;CARIAN LETTER R;Lo;0;L;;;;;N;;;;; +102A6;CARIAN LETTER LD;Lo;0;L;;;;;N;;;;; +102A7;CARIAN LETTER A2;Lo;0;L;;;;;N;;;;; +102A8;CARIAN LETTER Q;Lo;0;L;;;;;N;;;;; +102A9;CARIAN LETTER B;Lo;0;L;;;;;N;;;;; +102AA;CARIAN LETTER M;Lo;0;L;;;;;N;;;;; +102AB;CARIAN LETTER O;Lo;0;L;;;;;N;;;;; +102AC;CARIAN LETTER D2;Lo;0;L;;;;;N;;;;; +102AD;CARIAN LETTER T;Lo;0;L;;;;;N;;;;; +102AE;CARIAN LETTER SH;Lo;0;L;;;;;N;;;;; +102AF;CARIAN LETTER SH2;Lo;0;L;;;;;N;;;;; +102B0;CARIAN LETTER S;Lo;0;L;;;;;N;;;;; +102B1;CARIAN LETTER C-18;Lo;0;L;;;;;N;;;;; +102B2;CARIAN LETTER U;Lo;0;L;;;;;N;;;;; +102B3;CARIAN LETTER NN;Lo;0;L;;;;;N;;;;; +102B4;CARIAN LETTER X;Lo;0;L;;;;;N;;;;; +102B5;CARIAN LETTER N;Lo;0;L;;;;;N;;;;; +102B6;CARIAN LETTER TT2;Lo;0;L;;;;;N;;;;; +102B7;CARIAN LETTER P;Lo;0;L;;;;;N;;;;; +102B8;CARIAN LETTER SS;Lo;0;L;;;;;N;;;;; +102B9;CARIAN LETTER I;Lo;0;L;;;;;N;;;;; +102BA;CARIAN LETTER E;Lo;0;L;;;;;N;;;;; +102BB;CARIAN LETTER UUUU;Lo;0;L;;;;;N;;;;; +102BC;CARIAN LETTER K;Lo;0;L;;;;;N;;;;; +102BD;CARIAN LETTER K2;Lo;0;L;;;;;N;;;;; +102BE;CARIAN LETTER ND;Lo;0;L;;;;;N;;;;; +102BF;CARIAN LETTER UU;Lo;0;L;;;;;N;;;;; +102C0;CARIAN LETTER G;Lo;0;L;;;;;N;;;;; +102C1;CARIAN LETTER G2;Lo;0;L;;;;;N;;;;; +102C2;CARIAN LETTER ST;Lo;0;L;;;;;N;;;;; +102C3;CARIAN LETTER ST2;Lo;0;L;;;;;N;;;;; +102C4;CARIAN LETTER NG;Lo;0;L;;;;;N;;;;; +102C5;CARIAN LETTER II;Lo;0;L;;;;;N;;;;; +102C6;CARIAN LETTER C-39;Lo;0;L;;;;;N;;;;; +102C7;CARIAN LETTER TT;Lo;0;L;;;;;N;;;;; +102C8;CARIAN LETTER UUU2;Lo;0;L;;;;;N;;;;; +102C9;CARIAN LETTER RR;Lo;0;L;;;;;N;;;;; +102CA;CARIAN LETTER MB;Lo;0;L;;;;;N;;;;; +102CB;CARIAN LETTER MB2;Lo;0;L;;;;;N;;;;; +102CC;CARIAN LETTER MB3;Lo;0;L;;;;;N;;;;; +102CD;CARIAN LETTER MB4;Lo;0;L;;;;;N;;;;; +102CE;CARIAN LETTER LD2;Lo;0;L;;;;;N;;;;; +102CF;CARIAN LETTER E2;Lo;0;L;;;;;N;;;;; +102D0;CARIAN LETTER UUU3;Lo;0;L;;;;;N;;;;; +102E0;COPTIC EPACT THOUSANDS MARK;Mn;220;NSM;;;;;N;;;;; +102E1;COPTIC EPACT DIGIT ONE;No;0;EN;;;;1;N;;;;; +102E2;COPTIC EPACT DIGIT TWO;No;0;EN;;;;2;N;;;;; +102E3;COPTIC EPACT DIGIT THREE;No;0;EN;;;;3;N;;;;; +102E4;COPTIC EPACT DIGIT FOUR;No;0;EN;;;;4;N;;;;; +102E5;COPTIC EPACT DIGIT FIVE;No;0;EN;;;;5;N;;;;; +102E6;COPTIC EPACT DIGIT SIX;No;0;EN;;;;6;N;;;;; +102E7;COPTIC EPACT DIGIT SEVEN;No;0;EN;;;;7;N;;;;; +102E8;COPTIC EPACT DIGIT EIGHT;No;0;EN;;;;8;N;;;;; +102E9;COPTIC EPACT DIGIT NINE;No;0;EN;;;;9;N;;;;; +102EA;COPTIC EPACT NUMBER TEN;No;0;EN;;;;10;N;;;;; +102EB;COPTIC EPACT NUMBER TWENTY;No;0;EN;;;;20;N;;;;; +102EC;COPTIC EPACT NUMBER THIRTY;No;0;EN;;;;30;N;;;;; +102ED;COPTIC EPACT NUMBER FORTY;No;0;EN;;;;40;N;;;;; +102EE;COPTIC EPACT NUMBER FIFTY;No;0;EN;;;;50;N;;;;; +102EF;COPTIC EPACT NUMBER SIXTY;No;0;EN;;;;60;N;;;;; +102F0;COPTIC EPACT NUMBER SEVENTY;No;0;EN;;;;70;N;;;;; +102F1;COPTIC EPACT NUMBER EIGHTY;No;0;EN;;;;80;N;;;;; +102F2;COPTIC EPACT NUMBER NINETY;No;0;EN;;;;90;N;;;;; +102F3;COPTIC EPACT NUMBER ONE HUNDRED;No;0;EN;;;;100;N;;;;; +102F4;COPTIC EPACT NUMBER TWO HUNDRED;No;0;EN;;;;200;N;;;;; +102F5;COPTIC EPACT NUMBER THREE HUNDRED;No;0;EN;;;;300;N;;;;; +102F6;COPTIC EPACT NUMBER FOUR HUNDRED;No;0;EN;;;;400;N;;;;; +102F7;COPTIC EPACT NUMBER FIVE HUNDRED;No;0;EN;;;;500;N;;;;; +102F8;COPTIC EPACT NUMBER SIX HUNDRED;No;0;EN;;;;600;N;;;;; +102F9;COPTIC EPACT NUMBER SEVEN HUNDRED;No;0;EN;;;;700;N;;;;; +102FA;COPTIC EPACT NUMBER EIGHT HUNDRED;No;0;EN;;;;800;N;;;;; +102FB;COPTIC EPACT NUMBER NINE HUNDRED;No;0;EN;;;;900;N;;;;; +10300;OLD ITALIC LETTER A;Lo;0;L;;;;;N;;;;; +10301;OLD ITALIC LETTER BE;Lo;0;L;;;;;N;;;;; +10302;OLD ITALIC LETTER KE;Lo;0;L;;;;;N;;;;; +10303;OLD ITALIC LETTER DE;Lo;0;L;;;;;N;;;;; +10304;OLD ITALIC LETTER E;Lo;0;L;;;;;N;;;;; +10305;OLD ITALIC LETTER VE;Lo;0;L;;;;;N;;;;; +10306;OLD ITALIC LETTER ZE;Lo;0;L;;;;;N;;;;; +10307;OLD ITALIC LETTER HE;Lo;0;L;;;;;N;;;;; +10308;OLD ITALIC LETTER THE;Lo;0;L;;;;;N;;;;; +10309;OLD ITALIC LETTER I;Lo;0;L;;;;;N;;;;; +1030A;OLD ITALIC LETTER KA;Lo;0;L;;;;;N;;;;; +1030B;OLD ITALIC LETTER EL;Lo;0;L;;;;;N;;;;; +1030C;OLD ITALIC LETTER EM;Lo;0;L;;;;;N;;;;; +1030D;OLD ITALIC LETTER EN;Lo;0;L;;;;;N;;;;; +1030E;OLD ITALIC LETTER ESH;Lo;0;L;;;;;N;;;;; +1030F;OLD ITALIC LETTER O;Lo;0;L;;;;;N;;;;; +10310;OLD ITALIC LETTER PE;Lo;0;L;;;;;N;;;;; +10311;OLD ITALIC LETTER SHE;Lo;0;L;;;;;N;;;;; +10312;OLD ITALIC LETTER KU;Lo;0;L;;;;;N;;;;; +10313;OLD ITALIC LETTER ER;Lo;0;L;;;;;N;;;;; +10314;OLD ITALIC LETTER ES;Lo;0;L;;;;;N;;;;; +10315;OLD ITALIC LETTER TE;Lo;0;L;;;;;N;;;;; +10316;OLD ITALIC LETTER U;Lo;0;L;;;;;N;;;;; +10317;OLD ITALIC LETTER EKS;Lo;0;L;;;;;N;;;;; +10318;OLD ITALIC LETTER PHE;Lo;0;L;;;;;N;;;;; +10319;OLD ITALIC LETTER KHE;Lo;0;L;;;;;N;;;;; +1031A;OLD ITALIC LETTER EF;Lo;0;L;;;;;N;;;;; +1031B;OLD ITALIC LETTER ERS;Lo;0;L;;;;;N;;;;; +1031C;OLD ITALIC LETTER CHE;Lo;0;L;;;;;N;;;;; +1031D;OLD ITALIC LETTER II;Lo;0;L;;;;;N;;;;; +1031E;OLD ITALIC LETTER UU;Lo;0;L;;;;;N;;;;; +1031F;OLD ITALIC LETTER ESS;Lo;0;L;;;;;N;;;;; +10320;OLD ITALIC NUMERAL ONE;No;0;L;;;;1;N;;;;; +10321;OLD ITALIC NUMERAL FIVE;No;0;L;;;;5;N;;;;; +10322;OLD ITALIC NUMERAL TEN;No;0;L;;;;10;N;;;;; +10323;OLD ITALIC NUMERAL FIFTY;No;0;L;;;;50;N;;;;; +1032D;OLD ITALIC LETTER YE;Lo;0;L;;;;;N;;;;; +1032E;OLD ITALIC LETTER NORTHERN TSE;Lo;0;L;;;;;N;;;;; +1032F;OLD ITALIC LETTER SOUTHERN TSE;Lo;0;L;;;;;N;;;;; +10330;GOTHIC LETTER AHSA;Lo;0;L;;;;;N;;;;; +10331;GOTHIC LETTER BAIRKAN;Lo;0;L;;;;;N;;;;; +10332;GOTHIC LETTER GIBA;Lo;0;L;;;;;N;;;;; +10333;GOTHIC LETTER DAGS;Lo;0;L;;;;;N;;;;; +10334;GOTHIC LETTER AIHVUS;Lo;0;L;;;;;N;;;;; +10335;GOTHIC LETTER QAIRTHRA;Lo;0;L;;;;;N;;;;; +10336;GOTHIC LETTER IUJA;Lo;0;L;;;;;N;;;;; +10337;GOTHIC LETTER HAGL;Lo;0;L;;;;;N;;;;; +10338;GOTHIC LETTER THIUTH;Lo;0;L;;;;;N;;;;; +10339;GOTHIC LETTER EIS;Lo;0;L;;;;;N;;;;; +1033A;GOTHIC LETTER KUSMA;Lo;0;L;;;;;N;;;;; +1033B;GOTHIC LETTER LAGUS;Lo;0;L;;;;;N;;;;; +1033C;GOTHIC LETTER MANNA;Lo;0;L;;;;;N;;;;; +1033D;GOTHIC LETTER NAUTHS;Lo;0;L;;;;;N;;;;; +1033E;GOTHIC LETTER JER;Lo;0;L;;;;;N;;;;; +1033F;GOTHIC LETTER URUS;Lo;0;L;;;;;N;;;;; +10340;GOTHIC LETTER PAIRTHRA;Lo;0;L;;;;;N;;;;; +10341;GOTHIC LETTER NINETY;Nl;0;L;;;;90;N;;;;; +10342;GOTHIC LETTER RAIDA;Lo;0;L;;;;;N;;;;; +10343;GOTHIC LETTER SAUIL;Lo;0;L;;;;;N;;;;; +10344;GOTHIC LETTER TEIWS;Lo;0;L;;;;;N;;;;; +10345;GOTHIC LETTER WINJA;Lo;0;L;;;;;N;;;;; +10346;GOTHIC LETTER FAIHU;Lo;0;L;;;;;N;;;;; +10347;GOTHIC LETTER IGGWS;Lo;0;L;;;;;N;;;;; +10348;GOTHIC LETTER HWAIR;Lo;0;L;;;;;N;;;;; +10349;GOTHIC LETTER OTHAL;Lo;0;L;;;;;N;;;;; +1034A;GOTHIC LETTER NINE HUNDRED;Nl;0;L;;;;900;N;;;;; +10350;OLD PERMIC LETTER AN;Lo;0;L;;;;;N;;;;; +10351;OLD PERMIC LETTER BUR;Lo;0;L;;;;;N;;;;; +10352;OLD PERMIC LETTER GAI;Lo;0;L;;;;;N;;;;; +10353;OLD PERMIC LETTER DOI;Lo;0;L;;;;;N;;;;; +10354;OLD PERMIC LETTER E;Lo;0;L;;;;;N;;;;; +10355;OLD PERMIC LETTER ZHOI;Lo;0;L;;;;;N;;;;; +10356;OLD PERMIC LETTER DZHOI;Lo;0;L;;;;;N;;;;; +10357;OLD PERMIC LETTER ZATA;Lo;0;L;;;;;N;;;;; +10358;OLD PERMIC LETTER DZITA;Lo;0;L;;;;;N;;;;; +10359;OLD PERMIC LETTER I;Lo;0;L;;;;;N;;;;; +1035A;OLD PERMIC LETTER KOKE;Lo;0;L;;;;;N;;;;; +1035B;OLD PERMIC LETTER LEI;Lo;0;L;;;;;N;;;;; +1035C;OLD PERMIC LETTER MENOE;Lo;0;L;;;;;N;;;;; +1035D;OLD PERMIC LETTER NENOE;Lo;0;L;;;;;N;;;;; +1035E;OLD PERMIC LETTER VOOI;Lo;0;L;;;;;N;;;;; +1035F;OLD PERMIC LETTER PEEI;Lo;0;L;;;;;N;;;;; +10360;OLD PERMIC LETTER REI;Lo;0;L;;;;;N;;;;; +10361;OLD PERMIC LETTER SII;Lo;0;L;;;;;N;;;;; +10362;OLD PERMIC LETTER TAI;Lo;0;L;;;;;N;;;;; +10363;OLD PERMIC LETTER U;Lo;0;L;;;;;N;;;;; +10364;OLD PERMIC LETTER CHERY;Lo;0;L;;;;;N;;;;; +10365;OLD PERMIC LETTER SHOOI;Lo;0;L;;;;;N;;;;; +10366;OLD PERMIC LETTER SHCHOOI;Lo;0;L;;;;;N;;;;; +10367;OLD PERMIC LETTER YRY;Lo;0;L;;;;;N;;;;; +10368;OLD PERMIC LETTER YERU;Lo;0;L;;;;;N;;;;; +10369;OLD PERMIC LETTER O;Lo;0;L;;;;;N;;;;; +1036A;OLD PERMIC LETTER OO;Lo;0;L;;;;;N;;;;; +1036B;OLD PERMIC LETTER EF;Lo;0;L;;;;;N;;;;; +1036C;OLD PERMIC LETTER HA;Lo;0;L;;;;;N;;;;; +1036D;OLD PERMIC LETTER TSIU;Lo;0;L;;;;;N;;;;; +1036E;OLD PERMIC LETTER VER;Lo;0;L;;;;;N;;;;; +1036F;OLD PERMIC LETTER YER;Lo;0;L;;;;;N;;;;; +10370;OLD PERMIC LETTER YERI;Lo;0;L;;;;;N;;;;; +10371;OLD PERMIC LETTER YAT;Lo;0;L;;;;;N;;;;; +10372;OLD PERMIC LETTER IE;Lo;0;L;;;;;N;;;;; +10373;OLD PERMIC LETTER YU;Lo;0;L;;;;;N;;;;; +10374;OLD PERMIC LETTER YA;Lo;0;L;;;;;N;;;;; +10375;OLD PERMIC LETTER IA;Lo;0;L;;;;;N;;;;; +10376;COMBINING OLD PERMIC LETTER AN;Mn;230;NSM;;;;;N;;;;; +10377;COMBINING OLD PERMIC LETTER DOI;Mn;230;NSM;;;;;N;;;;; +10378;COMBINING OLD PERMIC LETTER ZATA;Mn;230;NSM;;;;;N;;;;; +10379;COMBINING OLD PERMIC LETTER NENOE;Mn;230;NSM;;;;;N;;;;; +1037A;COMBINING OLD PERMIC LETTER SII;Mn;230;NSM;;;;;N;;;;; +10380;UGARITIC LETTER ALPA;Lo;0;L;;;;;N;;;;; +10381;UGARITIC LETTER BETA;Lo;0;L;;;;;N;;;;; +10382;UGARITIC LETTER GAMLA;Lo;0;L;;;;;N;;;;; +10383;UGARITIC LETTER KHA;Lo;0;L;;;;;N;;;;; +10384;UGARITIC LETTER DELTA;Lo;0;L;;;;;N;;;;; +10385;UGARITIC LETTER HO;Lo;0;L;;;;;N;;;;; +10386;UGARITIC LETTER WO;Lo;0;L;;;;;N;;;;; +10387;UGARITIC LETTER ZETA;Lo;0;L;;;;;N;;;;; +10388;UGARITIC LETTER HOTA;Lo;0;L;;;;;N;;;;; +10389;UGARITIC LETTER TET;Lo;0;L;;;;;N;;;;; +1038A;UGARITIC LETTER YOD;Lo;0;L;;;;;N;;;;; +1038B;UGARITIC LETTER KAF;Lo;0;L;;;;;N;;;;; +1038C;UGARITIC LETTER SHIN;Lo;0;L;;;;;N;;;;; +1038D;UGARITIC LETTER LAMDA;Lo;0;L;;;;;N;;;;; +1038E;UGARITIC LETTER MEM;Lo;0;L;;;;;N;;;;; +1038F;UGARITIC LETTER DHAL;Lo;0;L;;;;;N;;;;; +10390;UGARITIC LETTER NUN;Lo;0;L;;;;;N;;;;; +10391;UGARITIC LETTER ZU;Lo;0;L;;;;;N;;;;; +10392;UGARITIC LETTER SAMKA;Lo;0;L;;;;;N;;;;; +10393;UGARITIC LETTER AIN;Lo;0;L;;;;;N;;;;; +10394;UGARITIC LETTER PU;Lo;0;L;;;;;N;;;;; +10395;UGARITIC LETTER SADE;Lo;0;L;;;;;N;;;;; +10396;UGARITIC LETTER QOPA;Lo;0;L;;;;;N;;;;; +10397;UGARITIC LETTER RASHA;Lo;0;L;;;;;N;;;;; +10398;UGARITIC LETTER THANNA;Lo;0;L;;;;;N;;;;; +10399;UGARITIC LETTER GHAIN;Lo;0;L;;;;;N;;;;; +1039A;UGARITIC LETTER TO;Lo;0;L;;;;;N;;;;; +1039B;UGARITIC LETTER I;Lo;0;L;;;;;N;;;;; +1039C;UGARITIC LETTER U;Lo;0;L;;;;;N;;;;; +1039D;UGARITIC LETTER SSU;Lo;0;L;;;;;N;;;;; +1039F;UGARITIC WORD DIVIDER;Po;0;L;;;;;N;;;;; +103A0;OLD PERSIAN SIGN A;Lo;0;L;;;;;N;;;;; +103A1;OLD PERSIAN SIGN I;Lo;0;L;;;;;N;;;;; +103A2;OLD PERSIAN SIGN U;Lo;0;L;;;;;N;;;;; +103A3;OLD PERSIAN SIGN KA;Lo;0;L;;;;;N;;;;; +103A4;OLD PERSIAN SIGN KU;Lo;0;L;;;;;N;;;;; +103A5;OLD PERSIAN SIGN GA;Lo;0;L;;;;;N;;;;; +103A6;OLD PERSIAN SIGN GU;Lo;0;L;;;;;N;;;;; +103A7;OLD PERSIAN SIGN XA;Lo;0;L;;;;;N;;;;; +103A8;OLD PERSIAN SIGN CA;Lo;0;L;;;;;N;;;;; +103A9;OLD PERSIAN SIGN JA;Lo;0;L;;;;;N;;;;; +103AA;OLD PERSIAN SIGN JI;Lo;0;L;;;;;N;;;;; +103AB;OLD PERSIAN SIGN TA;Lo;0;L;;;;;N;;;;; +103AC;OLD PERSIAN SIGN TU;Lo;0;L;;;;;N;;;;; +103AD;OLD PERSIAN SIGN DA;Lo;0;L;;;;;N;;;;; +103AE;OLD PERSIAN SIGN DI;Lo;0;L;;;;;N;;;;; +103AF;OLD PERSIAN SIGN DU;Lo;0;L;;;;;N;;;;; +103B0;OLD PERSIAN SIGN THA;Lo;0;L;;;;;N;;;;; +103B1;OLD PERSIAN SIGN PA;Lo;0;L;;;;;N;;;;; +103B2;OLD PERSIAN SIGN BA;Lo;0;L;;;;;N;;;;; +103B3;OLD PERSIAN SIGN FA;Lo;0;L;;;;;N;;;;; +103B4;OLD PERSIAN SIGN NA;Lo;0;L;;;;;N;;;;; +103B5;OLD PERSIAN SIGN NU;Lo;0;L;;;;;N;;;;; +103B6;OLD PERSIAN SIGN MA;Lo;0;L;;;;;N;;;;; +103B7;OLD PERSIAN SIGN MI;Lo;0;L;;;;;N;;;;; +103B8;OLD PERSIAN SIGN MU;Lo;0;L;;;;;N;;;;; +103B9;OLD PERSIAN SIGN YA;Lo;0;L;;;;;N;;;;; +103BA;OLD PERSIAN SIGN VA;Lo;0;L;;;;;N;;;;; +103BB;OLD PERSIAN SIGN VI;Lo;0;L;;;;;N;;;;; +103BC;OLD PERSIAN SIGN RA;Lo;0;L;;;;;N;;;;; +103BD;OLD PERSIAN SIGN RU;Lo;0;L;;;;;N;;;;; +103BE;OLD PERSIAN SIGN LA;Lo;0;L;;;;;N;;;;; +103BF;OLD PERSIAN SIGN SA;Lo;0;L;;;;;N;;;;; +103C0;OLD PERSIAN SIGN ZA;Lo;0;L;;;;;N;;;;; +103C1;OLD PERSIAN SIGN SHA;Lo;0;L;;;;;N;;;;; +103C2;OLD PERSIAN SIGN SSA;Lo;0;L;;;;;N;;;;; +103C3;OLD PERSIAN SIGN HA;Lo;0;L;;;;;N;;;;; +103C8;OLD PERSIAN SIGN AURAMAZDAA;Lo;0;L;;;;;N;;;;; +103C9;OLD PERSIAN SIGN AURAMAZDAA-2;Lo;0;L;;;;;N;;;;; +103CA;OLD PERSIAN SIGN AURAMAZDAAHA;Lo;0;L;;;;;N;;;;; +103CB;OLD PERSIAN SIGN XSHAAYATHIYA;Lo;0;L;;;;;N;;;;; +103CC;OLD PERSIAN SIGN DAHYAAUSH;Lo;0;L;;;;;N;;;;; +103CD;OLD PERSIAN SIGN DAHYAAUSH-2;Lo;0;L;;;;;N;;;;; +103CE;OLD PERSIAN SIGN BAGA;Lo;0;L;;;;;N;;;;; +103CF;OLD PERSIAN SIGN BUUMISH;Lo;0;L;;;;;N;;;;; +103D0;OLD PERSIAN WORD DIVIDER;Po;0;L;;;;;N;;;;; +103D1;OLD PERSIAN NUMBER ONE;Nl;0;L;;;;1;N;;;;; +103D2;OLD PERSIAN NUMBER TWO;Nl;0;L;;;;2;N;;;;; +103D3;OLD PERSIAN NUMBER TEN;Nl;0;L;;;;10;N;;;;; +103D4;OLD PERSIAN NUMBER TWENTY;Nl;0;L;;;;20;N;;;;; +103D5;OLD PERSIAN NUMBER HUNDRED;Nl;0;L;;;;100;N;;;;; +10400;DESERET CAPITAL LETTER LONG I;Lu;0;L;;;;;N;;;;10428; +10401;DESERET CAPITAL LETTER LONG E;Lu;0;L;;;;;N;;;;10429; +10402;DESERET CAPITAL LETTER LONG A;Lu;0;L;;;;;N;;;;1042A; +10403;DESERET CAPITAL LETTER LONG AH;Lu;0;L;;;;;N;;;;1042B; +10404;DESERET CAPITAL LETTER LONG O;Lu;0;L;;;;;N;;;;1042C; +10405;DESERET CAPITAL LETTER LONG OO;Lu;0;L;;;;;N;;;;1042D; +10406;DESERET CAPITAL LETTER SHORT I;Lu;0;L;;;;;N;;;;1042E; +10407;DESERET CAPITAL LETTER SHORT E;Lu;0;L;;;;;N;;;;1042F; +10408;DESERET CAPITAL LETTER SHORT A;Lu;0;L;;;;;N;;;;10430; +10409;DESERET CAPITAL LETTER SHORT AH;Lu;0;L;;;;;N;;;;10431; +1040A;DESERET CAPITAL LETTER SHORT O;Lu;0;L;;;;;N;;;;10432; +1040B;DESERET CAPITAL LETTER SHORT OO;Lu;0;L;;;;;N;;;;10433; +1040C;DESERET CAPITAL LETTER AY;Lu;0;L;;;;;N;;;;10434; +1040D;DESERET CAPITAL LETTER OW;Lu;0;L;;;;;N;;;;10435; +1040E;DESERET CAPITAL LETTER WU;Lu;0;L;;;;;N;;;;10436; +1040F;DESERET CAPITAL LETTER YEE;Lu;0;L;;;;;N;;;;10437; +10410;DESERET CAPITAL LETTER H;Lu;0;L;;;;;N;;;;10438; +10411;DESERET CAPITAL LETTER PEE;Lu;0;L;;;;;N;;;;10439; +10412;DESERET CAPITAL LETTER BEE;Lu;0;L;;;;;N;;;;1043A; +10413;DESERET CAPITAL LETTER TEE;Lu;0;L;;;;;N;;;;1043B; +10414;DESERET CAPITAL LETTER DEE;Lu;0;L;;;;;N;;;;1043C; +10415;DESERET CAPITAL LETTER CHEE;Lu;0;L;;;;;N;;;;1043D; +10416;DESERET CAPITAL LETTER JEE;Lu;0;L;;;;;N;;;;1043E; +10417;DESERET CAPITAL LETTER KAY;Lu;0;L;;;;;N;;;;1043F; +10418;DESERET CAPITAL LETTER GAY;Lu;0;L;;;;;N;;;;10440; +10419;DESERET CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;10441; +1041A;DESERET CAPITAL LETTER VEE;Lu;0;L;;;;;N;;;;10442; +1041B;DESERET CAPITAL LETTER ETH;Lu;0;L;;;;;N;;;;10443; +1041C;DESERET CAPITAL LETTER THEE;Lu;0;L;;;;;N;;;;10444; +1041D;DESERET CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;10445; +1041E;DESERET CAPITAL LETTER ZEE;Lu;0;L;;;;;N;;;;10446; +1041F;DESERET CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;10447; +10420;DESERET CAPITAL LETTER ZHEE;Lu;0;L;;;;;N;;;;10448; +10421;DESERET CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;10449; +10422;DESERET CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;1044A; +10423;DESERET CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;1044B; +10424;DESERET CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;1044C; +10425;DESERET CAPITAL LETTER ENG;Lu;0;L;;;;;N;;;;1044D; +10426;DESERET CAPITAL LETTER OI;Lu;0;L;;;;;N;;;;1044E; +10427;DESERET CAPITAL LETTER EW;Lu;0;L;;;;;N;;;;1044F; +10428;DESERET SMALL LETTER LONG I;Ll;0;L;;;;;N;;;10400;;10400 +10429;DESERET SMALL LETTER LONG E;Ll;0;L;;;;;N;;;10401;;10401 +1042A;DESERET SMALL LETTER LONG A;Ll;0;L;;;;;N;;;10402;;10402 +1042B;DESERET SMALL LETTER LONG AH;Ll;0;L;;;;;N;;;10403;;10403 +1042C;DESERET SMALL LETTER LONG O;Ll;0;L;;;;;N;;;10404;;10404 +1042D;DESERET SMALL LETTER LONG OO;Ll;0;L;;;;;N;;;10405;;10405 +1042E;DESERET SMALL LETTER SHORT I;Ll;0;L;;;;;N;;;10406;;10406 +1042F;DESERET SMALL LETTER SHORT E;Ll;0;L;;;;;N;;;10407;;10407 +10430;DESERET SMALL LETTER SHORT A;Ll;0;L;;;;;N;;;10408;;10408 +10431;DESERET SMALL LETTER SHORT AH;Ll;0;L;;;;;N;;;10409;;10409 +10432;DESERET SMALL LETTER SHORT O;Ll;0;L;;;;;N;;;1040A;;1040A +10433;DESERET SMALL LETTER SHORT OO;Ll;0;L;;;;;N;;;1040B;;1040B +10434;DESERET SMALL LETTER AY;Ll;0;L;;;;;N;;;1040C;;1040C +10435;DESERET SMALL LETTER OW;Ll;0;L;;;;;N;;;1040D;;1040D +10436;DESERET SMALL LETTER WU;Ll;0;L;;;;;N;;;1040E;;1040E +10437;DESERET SMALL LETTER YEE;Ll;0;L;;;;;N;;;1040F;;1040F +10438;DESERET SMALL LETTER H;Ll;0;L;;;;;N;;;10410;;10410 +10439;DESERET SMALL LETTER PEE;Ll;0;L;;;;;N;;;10411;;10411 +1043A;DESERET SMALL LETTER BEE;Ll;0;L;;;;;N;;;10412;;10412 +1043B;DESERET SMALL LETTER TEE;Ll;0;L;;;;;N;;;10413;;10413 +1043C;DESERET SMALL LETTER DEE;Ll;0;L;;;;;N;;;10414;;10414 +1043D;DESERET SMALL LETTER CHEE;Ll;0;L;;;;;N;;;10415;;10415 +1043E;DESERET SMALL LETTER JEE;Ll;0;L;;;;;N;;;10416;;10416 +1043F;DESERET SMALL LETTER KAY;Ll;0;L;;;;;N;;;10417;;10417 +10440;DESERET SMALL LETTER GAY;Ll;0;L;;;;;N;;;10418;;10418 +10441;DESERET SMALL LETTER EF;Ll;0;L;;;;;N;;;10419;;10419 +10442;DESERET SMALL LETTER VEE;Ll;0;L;;;;;N;;;1041A;;1041A +10443;DESERET SMALL LETTER ETH;Ll;0;L;;;;;N;;;1041B;;1041B +10444;DESERET SMALL LETTER THEE;Ll;0;L;;;;;N;;;1041C;;1041C +10445;DESERET SMALL LETTER ES;Ll;0;L;;;;;N;;;1041D;;1041D +10446;DESERET SMALL LETTER ZEE;Ll;0;L;;;;;N;;;1041E;;1041E +10447;DESERET SMALL LETTER ESH;Ll;0;L;;;;;N;;;1041F;;1041F +10448;DESERET SMALL LETTER ZHEE;Ll;0;L;;;;;N;;;10420;;10420 +10449;DESERET SMALL LETTER ER;Ll;0;L;;;;;N;;;10421;;10421 +1044A;DESERET SMALL LETTER EL;Ll;0;L;;;;;N;;;10422;;10422 +1044B;DESERET SMALL LETTER EM;Ll;0;L;;;;;N;;;10423;;10423 +1044C;DESERET SMALL LETTER EN;Ll;0;L;;;;;N;;;10424;;10424 +1044D;DESERET SMALL LETTER ENG;Ll;0;L;;;;;N;;;10425;;10425 +1044E;DESERET SMALL LETTER OI;Ll;0;L;;;;;N;;;10426;;10426 +1044F;DESERET SMALL LETTER EW;Ll;0;L;;;;;N;;;10427;;10427 +10450;SHAVIAN LETTER PEEP;Lo;0;L;;;;;N;;;;; +10451;SHAVIAN LETTER TOT;Lo;0;L;;;;;N;;;;; +10452;SHAVIAN LETTER KICK;Lo;0;L;;;;;N;;;;; +10453;SHAVIAN LETTER FEE;Lo;0;L;;;;;N;;;;; +10454;SHAVIAN LETTER THIGH;Lo;0;L;;;;;N;;;;; +10455;SHAVIAN LETTER SO;Lo;0;L;;;;;N;;;;; +10456;SHAVIAN LETTER SURE;Lo;0;L;;;;;N;;;;; +10457;SHAVIAN LETTER CHURCH;Lo;0;L;;;;;N;;;;; +10458;SHAVIAN LETTER YEA;Lo;0;L;;;;;N;;;;; +10459;SHAVIAN LETTER HUNG;Lo;0;L;;;;;N;;;;; +1045A;SHAVIAN LETTER BIB;Lo;0;L;;;;;N;;;;; +1045B;SHAVIAN LETTER DEAD;Lo;0;L;;;;;N;;;;; +1045C;SHAVIAN LETTER GAG;Lo;0;L;;;;;N;;;;; +1045D;SHAVIAN LETTER VOW;Lo;0;L;;;;;N;;;;; +1045E;SHAVIAN LETTER THEY;Lo;0;L;;;;;N;;;;; +1045F;SHAVIAN LETTER ZOO;Lo;0;L;;;;;N;;;;; +10460;SHAVIAN LETTER MEASURE;Lo;0;L;;;;;N;;;;; +10461;SHAVIAN LETTER JUDGE;Lo;0;L;;;;;N;;;;; +10462;SHAVIAN LETTER WOE;Lo;0;L;;;;;N;;;;; +10463;SHAVIAN LETTER HA-HA;Lo;0;L;;;;;N;;;;; +10464;SHAVIAN LETTER LOLL;Lo;0;L;;;;;N;;;;; +10465;SHAVIAN LETTER MIME;Lo;0;L;;;;;N;;;;; +10466;SHAVIAN LETTER IF;Lo;0;L;;;;;N;;;;; +10467;SHAVIAN LETTER EGG;Lo;0;L;;;;;N;;;;; +10468;SHAVIAN LETTER ASH;Lo;0;L;;;;;N;;;;; +10469;SHAVIAN LETTER ADO;Lo;0;L;;;;;N;;;;; +1046A;SHAVIAN LETTER ON;Lo;0;L;;;;;N;;;;; +1046B;SHAVIAN LETTER WOOL;Lo;0;L;;;;;N;;;;; +1046C;SHAVIAN LETTER OUT;Lo;0;L;;;;;N;;;;; +1046D;SHAVIAN LETTER AH;Lo;0;L;;;;;N;;;;; +1046E;SHAVIAN LETTER ROAR;Lo;0;L;;;;;N;;;;; +1046F;SHAVIAN LETTER NUN;Lo;0;L;;;;;N;;;;; +10470;SHAVIAN LETTER EAT;Lo;0;L;;;;;N;;;;; +10471;SHAVIAN LETTER AGE;Lo;0;L;;;;;N;;;;; +10472;SHAVIAN LETTER ICE;Lo;0;L;;;;;N;;;;; +10473;SHAVIAN LETTER UP;Lo;0;L;;;;;N;;;;; +10474;SHAVIAN LETTER OAK;Lo;0;L;;;;;N;;;;; +10475;SHAVIAN LETTER OOZE;Lo;0;L;;;;;N;;;;; +10476;SHAVIAN LETTER OIL;Lo;0;L;;;;;N;;;;; +10477;SHAVIAN LETTER AWE;Lo;0;L;;;;;N;;;;; +10478;SHAVIAN LETTER ARE;Lo;0;L;;;;;N;;;;; +10479;SHAVIAN LETTER OR;Lo;0;L;;;;;N;;;;; +1047A;SHAVIAN LETTER AIR;Lo;0;L;;;;;N;;;;; +1047B;SHAVIAN LETTER ERR;Lo;0;L;;;;;N;;;;; +1047C;SHAVIAN LETTER ARRAY;Lo;0;L;;;;;N;;;;; +1047D;SHAVIAN LETTER EAR;Lo;0;L;;;;;N;;;;; +1047E;SHAVIAN LETTER IAN;Lo;0;L;;;;;N;;;;; +1047F;SHAVIAN LETTER YEW;Lo;0;L;;;;;N;;;;; +10480;OSMANYA LETTER ALEF;Lo;0;L;;;;;N;;;;; +10481;OSMANYA LETTER BA;Lo;0;L;;;;;N;;;;; +10482;OSMANYA LETTER TA;Lo;0;L;;;;;N;;;;; +10483;OSMANYA LETTER JA;Lo;0;L;;;;;N;;;;; +10484;OSMANYA LETTER XA;Lo;0;L;;;;;N;;;;; +10485;OSMANYA LETTER KHA;Lo;0;L;;;;;N;;;;; +10486;OSMANYA LETTER DEEL;Lo;0;L;;;;;N;;;;; +10487;OSMANYA LETTER RA;Lo;0;L;;;;;N;;;;; +10488;OSMANYA LETTER SA;Lo;0;L;;;;;N;;;;; +10489;OSMANYA LETTER SHIIN;Lo;0;L;;;;;N;;;;; +1048A;OSMANYA LETTER DHA;Lo;0;L;;;;;N;;;;; +1048B;OSMANYA LETTER CAYN;Lo;0;L;;;;;N;;;;; +1048C;OSMANYA LETTER GA;Lo;0;L;;;;;N;;;;; +1048D;OSMANYA LETTER FA;Lo;0;L;;;;;N;;;;; +1048E;OSMANYA LETTER QAAF;Lo;0;L;;;;;N;;;;; +1048F;OSMANYA LETTER KAAF;Lo;0;L;;;;;N;;;;; +10490;OSMANYA LETTER LAAN;Lo;0;L;;;;;N;;;;; +10491;OSMANYA LETTER MIIN;Lo;0;L;;;;;N;;;;; +10492;OSMANYA LETTER NUUN;Lo;0;L;;;;;N;;;;; +10493;OSMANYA LETTER WAW;Lo;0;L;;;;;N;;;;; +10494;OSMANYA LETTER HA;Lo;0;L;;;;;N;;;;; +10495;OSMANYA LETTER YA;Lo;0;L;;;;;N;;;;; +10496;OSMANYA LETTER A;Lo;0;L;;;;;N;;;;; +10497;OSMANYA LETTER E;Lo;0;L;;;;;N;;;;; +10498;OSMANYA LETTER I;Lo;0;L;;;;;N;;;;; +10499;OSMANYA LETTER O;Lo;0;L;;;;;N;;;;; +1049A;OSMANYA LETTER U;Lo;0;L;;;;;N;;;;; +1049B;OSMANYA LETTER AA;Lo;0;L;;;;;N;;;;; +1049C;OSMANYA LETTER EE;Lo;0;L;;;;;N;;;;; +1049D;OSMANYA LETTER OO;Lo;0;L;;;;;N;;;;; +104A0;OSMANYA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +104A1;OSMANYA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +104A2;OSMANYA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +104A3;OSMANYA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +104A4;OSMANYA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +104A5;OSMANYA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +104A6;OSMANYA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +104A7;OSMANYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +104A8;OSMANYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +104A9;OSMANYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +104B0;OSAGE CAPITAL LETTER A;Lu;0;L;;;;;N;;;;104D8; +104B1;OSAGE CAPITAL LETTER AI;Lu;0;L;;;;;N;;;;104D9; +104B2;OSAGE CAPITAL LETTER AIN;Lu;0;L;;;;;N;;;;104DA; +104B3;OSAGE CAPITAL LETTER AH;Lu;0;L;;;;;N;;;;104DB; +104B4;OSAGE CAPITAL LETTER BRA;Lu;0;L;;;;;N;;;;104DC; +104B5;OSAGE CAPITAL LETTER CHA;Lu;0;L;;;;;N;;;;104DD; +104B6;OSAGE CAPITAL LETTER EHCHA;Lu;0;L;;;;;N;;;;104DE; +104B7;OSAGE CAPITAL LETTER E;Lu;0;L;;;;;N;;;;104DF; +104B8;OSAGE CAPITAL LETTER EIN;Lu;0;L;;;;;N;;;;104E0; +104B9;OSAGE CAPITAL LETTER HA;Lu;0;L;;;;;N;;;;104E1; +104BA;OSAGE CAPITAL LETTER HYA;Lu;0;L;;;;;N;;;;104E2; +104BB;OSAGE CAPITAL LETTER I;Lu;0;L;;;;;N;;;;104E3; +104BC;OSAGE CAPITAL LETTER KA;Lu;0;L;;;;;N;;;;104E4; +104BD;OSAGE CAPITAL LETTER EHKA;Lu;0;L;;;;;N;;;;104E5; +104BE;OSAGE CAPITAL LETTER KYA;Lu;0;L;;;;;N;;;;104E6; +104BF;OSAGE CAPITAL LETTER LA;Lu;0;L;;;;;N;;;;104E7; +104C0;OSAGE CAPITAL LETTER MA;Lu;0;L;;;;;N;;;;104E8; +104C1;OSAGE CAPITAL LETTER NA;Lu;0;L;;;;;N;;;;104E9; +104C2;OSAGE CAPITAL LETTER O;Lu;0;L;;;;;N;;;;104EA; +104C3;OSAGE CAPITAL LETTER OIN;Lu;0;L;;;;;N;;;;104EB; +104C4;OSAGE CAPITAL LETTER PA;Lu;0;L;;;;;N;;;;104EC; +104C5;OSAGE CAPITAL LETTER EHPA;Lu;0;L;;;;;N;;;;104ED; +104C6;OSAGE CAPITAL LETTER SA;Lu;0;L;;;;;N;;;;104EE; +104C7;OSAGE CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;104EF; +104C8;OSAGE CAPITAL LETTER TA;Lu;0;L;;;;;N;;;;104F0; +104C9;OSAGE CAPITAL LETTER EHTA;Lu;0;L;;;;;N;;;;104F1; +104CA;OSAGE CAPITAL LETTER TSA;Lu;0;L;;;;;N;;;;104F2; +104CB;OSAGE CAPITAL LETTER EHTSA;Lu;0;L;;;;;N;;;;104F3; +104CC;OSAGE CAPITAL LETTER TSHA;Lu;0;L;;;;;N;;;;104F4; +104CD;OSAGE CAPITAL LETTER DHA;Lu;0;L;;;;;N;;;;104F5; +104CE;OSAGE CAPITAL LETTER U;Lu;0;L;;;;;N;;;;104F6; +104CF;OSAGE CAPITAL LETTER WA;Lu;0;L;;;;;N;;;;104F7; +104D0;OSAGE CAPITAL LETTER KHA;Lu;0;L;;;;;N;;;;104F8; +104D1;OSAGE CAPITAL LETTER GHA;Lu;0;L;;;;;N;;;;104F9; +104D2;OSAGE CAPITAL LETTER ZA;Lu;0;L;;;;;N;;;;104FA; +104D3;OSAGE CAPITAL LETTER ZHA;Lu;0;L;;;;;N;;;;104FB; +104D8;OSAGE SMALL LETTER A;Ll;0;L;;;;;N;;;104B0;;104B0 +104D9;OSAGE SMALL LETTER AI;Ll;0;L;;;;;N;;;104B1;;104B1 +104DA;OSAGE SMALL LETTER AIN;Ll;0;L;;;;;N;;;104B2;;104B2 +104DB;OSAGE SMALL LETTER AH;Ll;0;L;;;;;N;;;104B3;;104B3 +104DC;OSAGE SMALL LETTER BRA;Ll;0;L;;;;;N;;;104B4;;104B4 +104DD;OSAGE SMALL LETTER CHA;Ll;0;L;;;;;N;;;104B5;;104B5 +104DE;OSAGE SMALL LETTER EHCHA;Ll;0;L;;;;;N;;;104B6;;104B6 +104DF;OSAGE SMALL LETTER E;Ll;0;L;;;;;N;;;104B7;;104B7 +104E0;OSAGE SMALL LETTER EIN;Ll;0;L;;;;;N;;;104B8;;104B8 +104E1;OSAGE SMALL LETTER HA;Ll;0;L;;;;;N;;;104B9;;104B9 +104E2;OSAGE SMALL LETTER HYA;Ll;0;L;;;;;N;;;104BA;;104BA +104E3;OSAGE SMALL LETTER I;Ll;0;L;;;;;N;;;104BB;;104BB +104E4;OSAGE SMALL LETTER KA;Ll;0;L;;;;;N;;;104BC;;104BC +104E5;OSAGE SMALL LETTER EHKA;Ll;0;L;;;;;N;;;104BD;;104BD +104E6;OSAGE SMALL LETTER KYA;Ll;0;L;;;;;N;;;104BE;;104BE +104E7;OSAGE SMALL LETTER LA;Ll;0;L;;;;;N;;;104BF;;104BF +104E8;OSAGE SMALL LETTER MA;Ll;0;L;;;;;N;;;104C0;;104C0 +104E9;OSAGE SMALL LETTER NA;Ll;0;L;;;;;N;;;104C1;;104C1 +104EA;OSAGE SMALL LETTER O;Ll;0;L;;;;;N;;;104C2;;104C2 +104EB;OSAGE SMALL LETTER OIN;Ll;0;L;;;;;N;;;104C3;;104C3 +104EC;OSAGE SMALL LETTER PA;Ll;0;L;;;;;N;;;104C4;;104C4 +104ED;OSAGE SMALL LETTER EHPA;Ll;0;L;;;;;N;;;104C5;;104C5 +104EE;OSAGE SMALL LETTER SA;Ll;0;L;;;;;N;;;104C6;;104C6 +104EF;OSAGE SMALL LETTER SHA;Ll;0;L;;;;;N;;;104C7;;104C7 +104F0;OSAGE SMALL LETTER TA;Ll;0;L;;;;;N;;;104C8;;104C8 +104F1;OSAGE SMALL LETTER EHTA;Ll;0;L;;;;;N;;;104C9;;104C9 +104F2;OSAGE SMALL LETTER TSA;Ll;0;L;;;;;N;;;104CA;;104CA +104F3;OSAGE SMALL LETTER EHTSA;Ll;0;L;;;;;N;;;104CB;;104CB +104F4;OSAGE SMALL LETTER TSHA;Ll;0;L;;;;;N;;;104CC;;104CC +104F5;OSAGE SMALL LETTER DHA;Ll;0;L;;;;;N;;;104CD;;104CD +104F6;OSAGE SMALL LETTER U;Ll;0;L;;;;;N;;;104CE;;104CE +104F7;OSAGE SMALL LETTER WA;Ll;0;L;;;;;N;;;104CF;;104CF +104F8;OSAGE SMALL LETTER KHA;Ll;0;L;;;;;N;;;104D0;;104D0 +104F9;OSAGE SMALL LETTER GHA;Ll;0;L;;;;;N;;;104D1;;104D1 +104FA;OSAGE SMALL LETTER ZA;Ll;0;L;;;;;N;;;104D2;;104D2 +104FB;OSAGE SMALL LETTER ZHA;Ll;0;L;;;;;N;;;104D3;;104D3 +10500;ELBASAN LETTER A;Lo;0;L;;;;;N;;;;; +10501;ELBASAN LETTER BE;Lo;0;L;;;;;N;;;;; +10502;ELBASAN LETTER CE;Lo;0;L;;;;;N;;;;; +10503;ELBASAN LETTER CHE;Lo;0;L;;;;;N;;;;; +10504;ELBASAN LETTER DE;Lo;0;L;;;;;N;;;;; +10505;ELBASAN LETTER NDE;Lo;0;L;;;;;N;;;;; +10506;ELBASAN LETTER DHE;Lo;0;L;;;;;N;;;;; +10507;ELBASAN LETTER EI;Lo;0;L;;;;;N;;;;; +10508;ELBASAN LETTER E;Lo;0;L;;;;;N;;;;; +10509;ELBASAN LETTER FE;Lo;0;L;;;;;N;;;;; +1050A;ELBASAN LETTER GE;Lo;0;L;;;;;N;;;;; +1050B;ELBASAN LETTER GJE;Lo;0;L;;;;;N;;;;; +1050C;ELBASAN LETTER HE;Lo;0;L;;;;;N;;;;; +1050D;ELBASAN LETTER I;Lo;0;L;;;;;N;;;;; +1050E;ELBASAN LETTER JE;Lo;0;L;;;;;N;;;;; +1050F;ELBASAN LETTER KE;Lo;0;L;;;;;N;;;;; +10510;ELBASAN LETTER LE;Lo;0;L;;;;;N;;;;; +10511;ELBASAN LETTER LLE;Lo;0;L;;;;;N;;;;; +10512;ELBASAN LETTER ME;Lo;0;L;;;;;N;;;;; +10513;ELBASAN LETTER NE;Lo;0;L;;;;;N;;;;; +10514;ELBASAN LETTER NA;Lo;0;L;;;;;N;;;;; +10515;ELBASAN LETTER NJE;Lo;0;L;;;;;N;;;;; +10516;ELBASAN LETTER O;Lo;0;L;;;;;N;;;;; +10517;ELBASAN LETTER PE;Lo;0;L;;;;;N;;;;; +10518;ELBASAN LETTER QE;Lo;0;L;;;;;N;;;;; +10519;ELBASAN LETTER RE;Lo;0;L;;;;;N;;;;; +1051A;ELBASAN LETTER RRE;Lo;0;L;;;;;N;;;;; +1051B;ELBASAN LETTER SE;Lo;0;L;;;;;N;;;;; +1051C;ELBASAN LETTER SHE;Lo;0;L;;;;;N;;;;; +1051D;ELBASAN LETTER TE;Lo;0;L;;;;;N;;;;; +1051E;ELBASAN LETTER THE;Lo;0;L;;;;;N;;;;; +1051F;ELBASAN LETTER U;Lo;0;L;;;;;N;;;;; +10520;ELBASAN LETTER VE;Lo;0;L;;;;;N;;;;; +10521;ELBASAN LETTER XE;Lo;0;L;;;;;N;;;;; +10522;ELBASAN LETTER Y;Lo;0;L;;;;;N;;;;; +10523;ELBASAN LETTER ZE;Lo;0;L;;;;;N;;;;; +10524;ELBASAN LETTER ZHE;Lo;0;L;;;;;N;;;;; +10525;ELBASAN LETTER GHE;Lo;0;L;;;;;N;;;;; +10526;ELBASAN LETTER GHAMMA;Lo;0;L;;;;;N;;;;; +10527;ELBASAN LETTER KHE;Lo;0;L;;;;;N;;;;; +10530;CAUCASIAN ALBANIAN LETTER ALT;Lo;0;L;;;;;N;;;;; +10531;CAUCASIAN ALBANIAN LETTER BET;Lo;0;L;;;;;N;;;;; +10532;CAUCASIAN ALBANIAN LETTER GIM;Lo;0;L;;;;;N;;;;; +10533;CAUCASIAN ALBANIAN LETTER DAT;Lo;0;L;;;;;N;;;;; +10534;CAUCASIAN ALBANIAN LETTER EB;Lo;0;L;;;;;N;;;;; +10535;CAUCASIAN ALBANIAN LETTER ZARL;Lo;0;L;;;;;N;;;;; +10536;CAUCASIAN ALBANIAN LETTER EYN;Lo;0;L;;;;;N;;;;; +10537;CAUCASIAN ALBANIAN LETTER ZHIL;Lo;0;L;;;;;N;;;;; +10538;CAUCASIAN ALBANIAN LETTER TAS;Lo;0;L;;;;;N;;;;; +10539;CAUCASIAN ALBANIAN LETTER CHA;Lo;0;L;;;;;N;;;;; +1053A;CAUCASIAN ALBANIAN LETTER YOWD;Lo;0;L;;;;;N;;;;; +1053B;CAUCASIAN ALBANIAN LETTER ZHA;Lo;0;L;;;;;N;;;;; +1053C;CAUCASIAN ALBANIAN LETTER IRB;Lo;0;L;;;;;N;;;;; +1053D;CAUCASIAN ALBANIAN LETTER SHA;Lo;0;L;;;;;N;;;;; +1053E;CAUCASIAN ALBANIAN LETTER LAN;Lo;0;L;;;;;N;;;;; +1053F;CAUCASIAN ALBANIAN LETTER INYA;Lo;0;L;;;;;N;;;;; +10540;CAUCASIAN ALBANIAN LETTER XEYN;Lo;0;L;;;;;N;;;;; +10541;CAUCASIAN ALBANIAN LETTER DYAN;Lo;0;L;;;;;N;;;;; +10542;CAUCASIAN ALBANIAN LETTER CAR;Lo;0;L;;;;;N;;;;; +10543;CAUCASIAN ALBANIAN LETTER JHOX;Lo;0;L;;;;;N;;;;; +10544;CAUCASIAN ALBANIAN LETTER KAR;Lo;0;L;;;;;N;;;;; +10545;CAUCASIAN ALBANIAN LETTER LYIT;Lo;0;L;;;;;N;;;;; +10546;CAUCASIAN ALBANIAN LETTER HEYT;Lo;0;L;;;;;N;;;;; +10547;CAUCASIAN ALBANIAN LETTER QAY;Lo;0;L;;;;;N;;;;; +10548;CAUCASIAN ALBANIAN LETTER AOR;Lo;0;L;;;;;N;;;;; +10549;CAUCASIAN ALBANIAN LETTER CHOY;Lo;0;L;;;;;N;;;;; +1054A;CAUCASIAN ALBANIAN LETTER CHI;Lo;0;L;;;;;N;;;;; +1054B;CAUCASIAN ALBANIAN LETTER CYAY;Lo;0;L;;;;;N;;;;; +1054C;CAUCASIAN ALBANIAN LETTER MAQ;Lo;0;L;;;;;N;;;;; +1054D;CAUCASIAN ALBANIAN LETTER QAR;Lo;0;L;;;;;N;;;;; +1054E;CAUCASIAN ALBANIAN LETTER NOWC;Lo;0;L;;;;;N;;;;; +1054F;CAUCASIAN ALBANIAN LETTER DZYAY;Lo;0;L;;;;;N;;;;; +10550;CAUCASIAN ALBANIAN LETTER SHAK;Lo;0;L;;;;;N;;;;; +10551;CAUCASIAN ALBANIAN LETTER JAYN;Lo;0;L;;;;;N;;;;; +10552;CAUCASIAN ALBANIAN LETTER ON;Lo;0;L;;;;;N;;;;; +10553;CAUCASIAN ALBANIAN LETTER TYAY;Lo;0;L;;;;;N;;;;; +10554;CAUCASIAN ALBANIAN LETTER FAM;Lo;0;L;;;;;N;;;;; +10555;CAUCASIAN ALBANIAN LETTER DZAY;Lo;0;L;;;;;N;;;;; +10556;CAUCASIAN ALBANIAN LETTER CHAT;Lo;0;L;;;;;N;;;;; +10557;CAUCASIAN ALBANIAN LETTER PEN;Lo;0;L;;;;;N;;;;; +10558;CAUCASIAN ALBANIAN LETTER GHEYS;Lo;0;L;;;;;N;;;;; +10559;CAUCASIAN ALBANIAN LETTER RAT;Lo;0;L;;;;;N;;;;; +1055A;CAUCASIAN ALBANIAN LETTER SEYK;Lo;0;L;;;;;N;;;;; +1055B;CAUCASIAN ALBANIAN LETTER VEYZ;Lo;0;L;;;;;N;;;;; +1055C;CAUCASIAN ALBANIAN LETTER TIWR;Lo;0;L;;;;;N;;;;; +1055D;CAUCASIAN ALBANIAN LETTER SHOY;Lo;0;L;;;;;N;;;;; +1055E;CAUCASIAN ALBANIAN LETTER IWN;Lo;0;L;;;;;N;;;;; +1055F;CAUCASIAN ALBANIAN LETTER CYAW;Lo;0;L;;;;;N;;;;; +10560;CAUCASIAN ALBANIAN LETTER CAYN;Lo;0;L;;;;;N;;;;; +10561;CAUCASIAN ALBANIAN LETTER YAYD;Lo;0;L;;;;;N;;;;; +10562;CAUCASIAN ALBANIAN LETTER PIWR;Lo;0;L;;;;;N;;;;; +10563;CAUCASIAN ALBANIAN LETTER KIW;Lo;0;L;;;;;N;;;;; +1056F;CAUCASIAN ALBANIAN CITATION MARK;Po;0;L;;;;;N;;;;; +10600;LINEAR A SIGN AB001;Lo;0;L;;;;;N;;;;; +10601;LINEAR A SIGN AB002;Lo;0;L;;;;;N;;;;; +10602;LINEAR A SIGN AB003;Lo;0;L;;;;;N;;;;; +10603;LINEAR A SIGN AB004;Lo;0;L;;;;;N;;;;; +10604;LINEAR A SIGN AB005;Lo;0;L;;;;;N;;;;; +10605;LINEAR A SIGN AB006;Lo;0;L;;;;;N;;;;; +10606;LINEAR A SIGN AB007;Lo;0;L;;;;;N;;;;; +10607;LINEAR A SIGN AB008;Lo;0;L;;;;;N;;;;; +10608;LINEAR A SIGN AB009;Lo;0;L;;;;;N;;;;; +10609;LINEAR A SIGN AB010;Lo;0;L;;;;;N;;;;; +1060A;LINEAR A SIGN AB011;Lo;0;L;;;;;N;;;;; +1060B;LINEAR A SIGN AB013;Lo;0;L;;;;;N;;;;; +1060C;LINEAR A SIGN AB016;Lo;0;L;;;;;N;;;;; +1060D;LINEAR A SIGN AB017;Lo;0;L;;;;;N;;;;; +1060E;LINEAR A SIGN AB020;Lo;0;L;;;;;N;;;;; +1060F;LINEAR A SIGN AB021;Lo;0;L;;;;;N;;;;; +10610;LINEAR A SIGN AB021F;Lo;0;L;;;;;N;;;;; +10611;LINEAR A SIGN AB021M;Lo;0;L;;;;;N;;;;; +10612;LINEAR A SIGN AB022;Lo;0;L;;;;;N;;;;; +10613;LINEAR A SIGN AB022F;Lo;0;L;;;;;N;;;;; +10614;LINEAR A SIGN AB022M;Lo;0;L;;;;;N;;;;; +10615;LINEAR A SIGN AB023;Lo;0;L;;;;;N;;;;; +10616;LINEAR A SIGN AB023M;Lo;0;L;;;;;N;;;;; +10617;LINEAR A SIGN AB024;Lo;0;L;;;;;N;;;;; +10618;LINEAR A SIGN AB026;Lo;0;L;;;;;N;;;;; +10619;LINEAR A SIGN AB027;Lo;0;L;;;;;N;;;;; +1061A;LINEAR A SIGN AB028;Lo;0;L;;;;;N;;;;; +1061B;LINEAR A SIGN A028B;Lo;0;L;;;;;N;;;;; +1061C;LINEAR A SIGN AB029;Lo;0;L;;;;;N;;;;; +1061D;LINEAR A SIGN AB030;Lo;0;L;;;;;N;;;;; +1061E;LINEAR A SIGN AB031;Lo;0;L;;;;;N;;;;; +1061F;LINEAR A SIGN AB034;Lo;0;L;;;;;N;;;;; +10620;LINEAR A SIGN AB037;Lo;0;L;;;;;N;;;;; +10621;LINEAR A SIGN AB038;Lo;0;L;;;;;N;;;;; +10622;LINEAR A SIGN AB039;Lo;0;L;;;;;N;;;;; +10623;LINEAR A SIGN AB040;Lo;0;L;;;;;N;;;;; +10624;LINEAR A SIGN AB041;Lo;0;L;;;;;N;;;;; +10625;LINEAR A SIGN AB044;Lo;0;L;;;;;N;;;;; +10626;LINEAR A SIGN AB045;Lo;0;L;;;;;N;;;;; +10627;LINEAR A SIGN AB046;Lo;0;L;;;;;N;;;;; +10628;LINEAR A SIGN AB047;Lo;0;L;;;;;N;;;;; +10629;LINEAR A SIGN AB048;Lo;0;L;;;;;N;;;;; +1062A;LINEAR A SIGN AB049;Lo;0;L;;;;;N;;;;; +1062B;LINEAR A SIGN AB050;Lo;0;L;;;;;N;;;;; +1062C;LINEAR A SIGN AB051;Lo;0;L;;;;;N;;;;; +1062D;LINEAR A SIGN AB053;Lo;0;L;;;;;N;;;;; +1062E;LINEAR A SIGN AB054;Lo;0;L;;;;;N;;;;; +1062F;LINEAR A SIGN AB055;Lo;0;L;;;;;N;;;;; +10630;LINEAR A SIGN AB056;Lo;0;L;;;;;N;;;;; +10631;LINEAR A SIGN AB057;Lo;0;L;;;;;N;;;;; +10632;LINEAR A SIGN AB058;Lo;0;L;;;;;N;;;;; +10633;LINEAR A SIGN AB059;Lo;0;L;;;;;N;;;;; +10634;LINEAR A SIGN AB060;Lo;0;L;;;;;N;;;;; +10635;LINEAR A SIGN AB061;Lo;0;L;;;;;N;;;;; +10636;LINEAR A SIGN AB065;Lo;0;L;;;;;N;;;;; +10637;LINEAR A SIGN AB066;Lo;0;L;;;;;N;;;;; +10638;LINEAR A SIGN AB067;Lo;0;L;;;;;N;;;;; +10639;LINEAR A SIGN AB069;Lo;0;L;;;;;N;;;;; +1063A;LINEAR A SIGN AB070;Lo;0;L;;;;;N;;;;; +1063B;LINEAR A SIGN AB073;Lo;0;L;;;;;N;;;;; +1063C;LINEAR A SIGN AB074;Lo;0;L;;;;;N;;;;; +1063D;LINEAR A SIGN AB076;Lo;0;L;;;;;N;;;;; +1063E;LINEAR A SIGN AB077;Lo;0;L;;;;;N;;;;; +1063F;LINEAR A SIGN AB078;Lo;0;L;;;;;N;;;;; +10640;LINEAR A SIGN AB079;Lo;0;L;;;;;N;;;;; +10641;LINEAR A SIGN AB080;Lo;0;L;;;;;N;;;;; +10642;LINEAR A SIGN AB081;Lo;0;L;;;;;N;;;;; +10643;LINEAR A SIGN AB082;Lo;0;L;;;;;N;;;;; +10644;LINEAR A SIGN AB085;Lo;0;L;;;;;N;;;;; +10645;LINEAR A SIGN AB086;Lo;0;L;;;;;N;;;;; +10646;LINEAR A SIGN AB087;Lo;0;L;;;;;N;;;;; +10647;LINEAR A SIGN A100-102;Lo;0;L;;;;;N;;;;; +10648;LINEAR A SIGN AB118;Lo;0;L;;;;;N;;;;; +10649;LINEAR A SIGN AB120;Lo;0;L;;;;;N;;;;; +1064A;LINEAR A SIGN A120B;Lo;0;L;;;;;N;;;;; +1064B;LINEAR A SIGN AB122;Lo;0;L;;;;;N;;;;; +1064C;LINEAR A SIGN AB123;Lo;0;L;;;;;N;;;;; +1064D;LINEAR A SIGN AB131A;Lo;0;L;;;;;N;;;;; +1064E;LINEAR A SIGN AB131B;Lo;0;L;;;;;N;;;;; +1064F;LINEAR A SIGN A131C;Lo;0;L;;;;;N;;;;; +10650;LINEAR A SIGN AB164;Lo;0;L;;;;;N;;;;; +10651;LINEAR A SIGN AB171;Lo;0;L;;;;;N;;;;; +10652;LINEAR A SIGN AB180;Lo;0;L;;;;;N;;;;; +10653;LINEAR A SIGN AB188;Lo;0;L;;;;;N;;;;; +10654;LINEAR A SIGN AB191;Lo;0;L;;;;;N;;;;; +10655;LINEAR A SIGN A301;Lo;0;L;;;;;N;;;;; +10656;LINEAR A SIGN A302;Lo;0;L;;;;;N;;;;; +10657;LINEAR A SIGN A303;Lo;0;L;;;;;N;;;;; +10658;LINEAR A SIGN A304;Lo;0;L;;;;;N;;;;; +10659;LINEAR A SIGN A305;Lo;0;L;;;;;N;;;;; +1065A;LINEAR A SIGN A306;Lo;0;L;;;;;N;;;;; +1065B;LINEAR A SIGN A307;Lo;0;L;;;;;N;;;;; +1065C;LINEAR A SIGN A308;Lo;0;L;;;;;N;;;;; +1065D;LINEAR A SIGN A309A;Lo;0;L;;;;;N;;;;; +1065E;LINEAR A SIGN A309B;Lo;0;L;;;;;N;;;;; +1065F;LINEAR A SIGN A309C;Lo;0;L;;;;;N;;;;; +10660;LINEAR A SIGN A310;Lo;0;L;;;;;N;;;;; +10661;LINEAR A SIGN A311;Lo;0;L;;;;;N;;;;; +10662;LINEAR A SIGN A312;Lo;0;L;;;;;N;;;;; +10663;LINEAR A SIGN A313A;Lo;0;L;;;;;N;;;;; +10664;LINEAR A SIGN A313B;Lo;0;L;;;;;N;;;;; +10665;LINEAR A SIGN A313C;Lo;0;L;;;;;N;;;;; +10666;LINEAR A SIGN A314;Lo;0;L;;;;;N;;;;; +10667;LINEAR A SIGN A315;Lo;0;L;;;;;N;;;;; +10668;LINEAR A SIGN A316;Lo;0;L;;;;;N;;;;; +10669;LINEAR A SIGN A317;Lo;0;L;;;;;N;;;;; +1066A;LINEAR A SIGN A318;Lo;0;L;;;;;N;;;;; +1066B;LINEAR A SIGN A319;Lo;0;L;;;;;N;;;;; +1066C;LINEAR A SIGN A320;Lo;0;L;;;;;N;;;;; +1066D;LINEAR A SIGN A321;Lo;0;L;;;;;N;;;;; +1066E;LINEAR A SIGN A322;Lo;0;L;;;;;N;;;;; +1066F;LINEAR A SIGN A323;Lo;0;L;;;;;N;;;;; +10670;LINEAR A SIGN A324;Lo;0;L;;;;;N;;;;; +10671;LINEAR A SIGN A325;Lo;0;L;;;;;N;;;;; +10672;LINEAR A SIGN A326;Lo;0;L;;;;;N;;;;; +10673;LINEAR A SIGN A327;Lo;0;L;;;;;N;;;;; +10674;LINEAR A SIGN A328;Lo;0;L;;;;;N;;;;; +10675;LINEAR A SIGN A329;Lo;0;L;;;;;N;;;;; +10676;LINEAR A SIGN A330;Lo;0;L;;;;;N;;;;; +10677;LINEAR A SIGN A331;Lo;0;L;;;;;N;;;;; +10678;LINEAR A SIGN A332;Lo;0;L;;;;;N;;;;; +10679;LINEAR A SIGN A333;Lo;0;L;;;;;N;;;;; +1067A;LINEAR A SIGN A334;Lo;0;L;;;;;N;;;;; +1067B;LINEAR A SIGN A335;Lo;0;L;;;;;N;;;;; +1067C;LINEAR A SIGN A336;Lo;0;L;;;;;N;;;;; +1067D;LINEAR A SIGN A337;Lo;0;L;;;;;N;;;;; +1067E;LINEAR A SIGN A338;Lo;0;L;;;;;N;;;;; +1067F;LINEAR A SIGN A339;Lo;0;L;;;;;N;;;;; +10680;LINEAR A SIGN A340;Lo;0;L;;;;;N;;;;; +10681;LINEAR A SIGN A341;Lo;0;L;;;;;N;;;;; +10682;LINEAR A SIGN A342;Lo;0;L;;;;;N;;;;; +10683;LINEAR A SIGN A343;Lo;0;L;;;;;N;;;;; +10684;LINEAR A SIGN A344;Lo;0;L;;;;;N;;;;; +10685;LINEAR A SIGN A345;Lo;0;L;;;;;N;;;;; +10686;LINEAR A SIGN A346;Lo;0;L;;;;;N;;;;; +10687;LINEAR A SIGN A347;Lo;0;L;;;;;N;;;;; +10688;LINEAR A SIGN A348;Lo;0;L;;;;;N;;;;; +10689;LINEAR A SIGN A349;Lo;0;L;;;;;N;;;;; +1068A;LINEAR A SIGN A350;Lo;0;L;;;;;N;;;;; +1068B;LINEAR A SIGN A351;Lo;0;L;;;;;N;;;;; +1068C;LINEAR A SIGN A352;Lo;0;L;;;;;N;;;;; +1068D;LINEAR A SIGN A353;Lo;0;L;;;;;N;;;;; +1068E;LINEAR A SIGN A354;Lo;0;L;;;;;N;;;;; +1068F;LINEAR A SIGN A355;Lo;0;L;;;;;N;;;;; +10690;LINEAR A SIGN A356;Lo;0;L;;;;;N;;;;; +10691;LINEAR A SIGN A357;Lo;0;L;;;;;N;;;;; +10692;LINEAR A SIGN A358;Lo;0;L;;;;;N;;;;; +10693;LINEAR A SIGN A359;Lo;0;L;;;;;N;;;;; +10694;LINEAR A SIGN A360;Lo;0;L;;;;;N;;;;; +10695;LINEAR A SIGN A361;Lo;0;L;;;;;N;;;;; +10696;LINEAR A SIGN A362;Lo;0;L;;;;;N;;;;; +10697;LINEAR A SIGN A363;Lo;0;L;;;;;N;;;;; +10698;LINEAR A SIGN A364;Lo;0;L;;;;;N;;;;; +10699;LINEAR A SIGN A365;Lo;0;L;;;;;N;;;;; +1069A;LINEAR A SIGN A366;Lo;0;L;;;;;N;;;;; +1069B;LINEAR A SIGN A367;Lo;0;L;;;;;N;;;;; +1069C;LINEAR A SIGN A368;Lo;0;L;;;;;N;;;;; +1069D;LINEAR A SIGN A369;Lo;0;L;;;;;N;;;;; +1069E;LINEAR A SIGN A370;Lo;0;L;;;;;N;;;;; +1069F;LINEAR A SIGN A371;Lo;0;L;;;;;N;;;;; +106A0;LINEAR A SIGN A400-VAS;Lo;0;L;;;;;N;;;;; +106A1;LINEAR A SIGN A401-VAS;Lo;0;L;;;;;N;;;;; +106A2;LINEAR A SIGN A402-VAS;Lo;0;L;;;;;N;;;;; +106A3;LINEAR A SIGN A403-VAS;Lo;0;L;;;;;N;;;;; +106A4;LINEAR A SIGN A404-VAS;Lo;0;L;;;;;N;;;;; +106A5;LINEAR A SIGN A405-VAS;Lo;0;L;;;;;N;;;;; +106A6;LINEAR A SIGN A406-VAS;Lo;0;L;;;;;N;;;;; +106A7;LINEAR A SIGN A407-VAS;Lo;0;L;;;;;N;;;;; +106A8;LINEAR A SIGN A408-VAS;Lo;0;L;;;;;N;;;;; +106A9;LINEAR A SIGN A409-VAS;Lo;0;L;;;;;N;;;;; +106AA;LINEAR A SIGN A410-VAS;Lo;0;L;;;;;N;;;;; +106AB;LINEAR A SIGN A411-VAS;Lo;0;L;;;;;N;;;;; +106AC;LINEAR A SIGN A412-VAS;Lo;0;L;;;;;N;;;;; +106AD;LINEAR A SIGN A413-VAS;Lo;0;L;;;;;N;;;;; +106AE;LINEAR A SIGN A414-VAS;Lo;0;L;;;;;N;;;;; +106AF;LINEAR A SIGN A415-VAS;Lo;0;L;;;;;N;;;;; +106B0;LINEAR A SIGN A416-VAS;Lo;0;L;;;;;N;;;;; +106B1;LINEAR A SIGN A417-VAS;Lo;0;L;;;;;N;;;;; +106B2;LINEAR A SIGN A418-VAS;Lo;0;L;;;;;N;;;;; +106B3;LINEAR A SIGN A501;Lo;0;L;;;;;N;;;;; +106B4;LINEAR A SIGN A502;Lo;0;L;;;;;N;;;;; +106B5;LINEAR A SIGN A503;Lo;0;L;;;;;N;;;;; +106B6;LINEAR A SIGN A504;Lo;0;L;;;;;N;;;;; +106B7;LINEAR A SIGN A505;Lo;0;L;;;;;N;;;;; +106B8;LINEAR A SIGN A506;Lo;0;L;;;;;N;;;;; +106B9;LINEAR A SIGN A508;Lo;0;L;;;;;N;;;;; +106BA;LINEAR A SIGN A509;Lo;0;L;;;;;N;;;;; +106BB;LINEAR A SIGN A510;Lo;0;L;;;;;N;;;;; +106BC;LINEAR A SIGN A511;Lo;0;L;;;;;N;;;;; +106BD;LINEAR A SIGN A512;Lo;0;L;;;;;N;;;;; +106BE;LINEAR A SIGN A513;Lo;0;L;;;;;N;;;;; +106BF;LINEAR A SIGN A515;Lo;0;L;;;;;N;;;;; +106C0;LINEAR A SIGN A516;Lo;0;L;;;;;N;;;;; +106C1;LINEAR A SIGN A520;Lo;0;L;;;;;N;;;;; +106C2;LINEAR A SIGN A521;Lo;0;L;;;;;N;;;;; +106C3;LINEAR A SIGN A523;Lo;0;L;;;;;N;;;;; +106C4;LINEAR A SIGN A524;Lo;0;L;;;;;N;;;;; +106C5;LINEAR A SIGN A525;Lo;0;L;;;;;N;;;;; +106C6;LINEAR A SIGN A526;Lo;0;L;;;;;N;;;;; +106C7;LINEAR A SIGN A527;Lo;0;L;;;;;N;;;;; +106C8;LINEAR A SIGN A528;Lo;0;L;;;;;N;;;;; +106C9;LINEAR A SIGN A529;Lo;0;L;;;;;N;;;;; +106CA;LINEAR A SIGN A530;Lo;0;L;;;;;N;;;;; +106CB;LINEAR A SIGN A531;Lo;0;L;;;;;N;;;;; +106CC;LINEAR A SIGN A532;Lo;0;L;;;;;N;;;;; +106CD;LINEAR A SIGN A534;Lo;0;L;;;;;N;;;;; +106CE;LINEAR A SIGN A535;Lo;0;L;;;;;N;;;;; +106CF;LINEAR A SIGN A536;Lo;0;L;;;;;N;;;;; +106D0;LINEAR A SIGN A537;Lo;0;L;;;;;N;;;;; +106D1;LINEAR A SIGN A538;Lo;0;L;;;;;N;;;;; +106D2;LINEAR A SIGN A539;Lo;0;L;;;;;N;;;;; +106D3;LINEAR A SIGN A540;Lo;0;L;;;;;N;;;;; +106D4;LINEAR A SIGN A541;Lo;0;L;;;;;N;;;;; +106D5;LINEAR A SIGN A542;Lo;0;L;;;;;N;;;;; +106D6;LINEAR A SIGN A545;Lo;0;L;;;;;N;;;;; +106D7;LINEAR A SIGN A547;Lo;0;L;;;;;N;;;;; +106D8;LINEAR A SIGN A548;Lo;0;L;;;;;N;;;;; +106D9;LINEAR A SIGN A549;Lo;0;L;;;;;N;;;;; +106DA;LINEAR A SIGN A550;Lo;0;L;;;;;N;;;;; +106DB;LINEAR A SIGN A551;Lo;0;L;;;;;N;;;;; +106DC;LINEAR A SIGN A552;Lo;0;L;;;;;N;;;;; +106DD;LINEAR A SIGN A553;Lo;0;L;;;;;N;;;;; +106DE;LINEAR A SIGN A554;Lo;0;L;;;;;N;;;;; +106DF;LINEAR A SIGN A555;Lo;0;L;;;;;N;;;;; +106E0;LINEAR A SIGN A556;Lo;0;L;;;;;N;;;;; +106E1;LINEAR A SIGN A557;Lo;0;L;;;;;N;;;;; +106E2;LINEAR A SIGN A559;Lo;0;L;;;;;N;;;;; +106E3;LINEAR A SIGN A563;Lo;0;L;;;;;N;;;;; +106E4;LINEAR A SIGN A564;Lo;0;L;;;;;N;;;;; +106E5;LINEAR A SIGN A565;Lo;0;L;;;;;N;;;;; +106E6;LINEAR A SIGN A566;Lo;0;L;;;;;N;;;;; +106E7;LINEAR A SIGN A568;Lo;0;L;;;;;N;;;;; +106E8;LINEAR A SIGN A569;Lo;0;L;;;;;N;;;;; +106E9;LINEAR A SIGN A570;Lo;0;L;;;;;N;;;;; +106EA;LINEAR A SIGN A571;Lo;0;L;;;;;N;;;;; +106EB;LINEAR A SIGN A572;Lo;0;L;;;;;N;;;;; +106EC;LINEAR A SIGN A573;Lo;0;L;;;;;N;;;;; +106ED;LINEAR A SIGN A574;Lo;0;L;;;;;N;;;;; +106EE;LINEAR A SIGN A575;Lo;0;L;;;;;N;;;;; +106EF;LINEAR A SIGN A576;Lo;0;L;;;;;N;;;;; +106F0;LINEAR A SIGN A577;Lo;0;L;;;;;N;;;;; +106F1;LINEAR A SIGN A578;Lo;0;L;;;;;N;;;;; +106F2;LINEAR A SIGN A579;Lo;0;L;;;;;N;;;;; +106F3;LINEAR A SIGN A580;Lo;0;L;;;;;N;;;;; +106F4;LINEAR A SIGN A581;Lo;0;L;;;;;N;;;;; +106F5;LINEAR A SIGN A582;Lo;0;L;;;;;N;;;;; +106F6;LINEAR A SIGN A583;Lo;0;L;;;;;N;;;;; +106F7;LINEAR A SIGN A584;Lo;0;L;;;;;N;;;;; +106F8;LINEAR A SIGN A585;Lo;0;L;;;;;N;;;;; +106F9;LINEAR A SIGN A586;Lo;0;L;;;;;N;;;;; +106FA;LINEAR A SIGN A587;Lo;0;L;;;;;N;;;;; +106FB;LINEAR A SIGN A588;Lo;0;L;;;;;N;;;;; +106FC;LINEAR A SIGN A589;Lo;0;L;;;;;N;;;;; +106FD;LINEAR A SIGN A591;Lo;0;L;;;;;N;;;;; +106FE;LINEAR A SIGN A592;Lo;0;L;;;;;N;;;;; +106FF;LINEAR A SIGN A594;Lo;0;L;;;;;N;;;;; +10700;LINEAR A SIGN A595;Lo;0;L;;;;;N;;;;; +10701;LINEAR A SIGN A596;Lo;0;L;;;;;N;;;;; +10702;LINEAR A SIGN A598;Lo;0;L;;;;;N;;;;; +10703;LINEAR A SIGN A600;Lo;0;L;;;;;N;;;;; +10704;LINEAR A SIGN A601;Lo;0;L;;;;;N;;;;; +10705;LINEAR A SIGN A602;Lo;0;L;;;;;N;;;;; +10706;LINEAR A SIGN A603;Lo;0;L;;;;;N;;;;; +10707;LINEAR A SIGN A604;Lo;0;L;;;;;N;;;;; +10708;LINEAR A SIGN A606;Lo;0;L;;;;;N;;;;; +10709;LINEAR A SIGN A608;Lo;0;L;;;;;N;;;;; +1070A;LINEAR A SIGN A609;Lo;0;L;;;;;N;;;;; +1070B;LINEAR A SIGN A610;Lo;0;L;;;;;N;;;;; +1070C;LINEAR A SIGN A611;Lo;0;L;;;;;N;;;;; +1070D;LINEAR A SIGN A612;Lo;0;L;;;;;N;;;;; +1070E;LINEAR A SIGN A613;Lo;0;L;;;;;N;;;;; +1070F;LINEAR A SIGN A614;Lo;0;L;;;;;N;;;;; +10710;LINEAR A SIGN A615;Lo;0;L;;;;;N;;;;; +10711;LINEAR A SIGN A616;Lo;0;L;;;;;N;;;;; +10712;LINEAR A SIGN A617;Lo;0;L;;;;;N;;;;; +10713;LINEAR A SIGN A618;Lo;0;L;;;;;N;;;;; +10714;LINEAR A SIGN A619;Lo;0;L;;;;;N;;;;; +10715;LINEAR A SIGN A620;Lo;0;L;;;;;N;;;;; +10716;LINEAR A SIGN A621;Lo;0;L;;;;;N;;;;; +10717;LINEAR A SIGN A622;Lo;0;L;;;;;N;;;;; +10718;LINEAR A SIGN A623;Lo;0;L;;;;;N;;;;; +10719;LINEAR A SIGN A624;Lo;0;L;;;;;N;;;;; +1071A;LINEAR A SIGN A626;Lo;0;L;;;;;N;;;;; +1071B;LINEAR A SIGN A627;Lo;0;L;;;;;N;;;;; +1071C;LINEAR A SIGN A628;Lo;0;L;;;;;N;;;;; +1071D;LINEAR A SIGN A629;Lo;0;L;;;;;N;;;;; +1071E;LINEAR A SIGN A634;Lo;0;L;;;;;N;;;;; +1071F;LINEAR A SIGN A637;Lo;0;L;;;;;N;;;;; +10720;LINEAR A SIGN A638;Lo;0;L;;;;;N;;;;; +10721;LINEAR A SIGN A640;Lo;0;L;;;;;N;;;;; +10722;LINEAR A SIGN A642;Lo;0;L;;;;;N;;;;; +10723;LINEAR A SIGN A643;Lo;0;L;;;;;N;;;;; +10724;LINEAR A SIGN A644;Lo;0;L;;;;;N;;;;; +10725;LINEAR A SIGN A645;Lo;0;L;;;;;N;;;;; +10726;LINEAR A SIGN A646;Lo;0;L;;;;;N;;;;; +10727;LINEAR A SIGN A648;Lo;0;L;;;;;N;;;;; +10728;LINEAR A SIGN A649;Lo;0;L;;;;;N;;;;; +10729;LINEAR A SIGN A651;Lo;0;L;;;;;N;;;;; +1072A;LINEAR A SIGN A652;Lo;0;L;;;;;N;;;;; +1072B;LINEAR A SIGN A653;Lo;0;L;;;;;N;;;;; +1072C;LINEAR A SIGN A654;Lo;0;L;;;;;N;;;;; +1072D;LINEAR A SIGN A655;Lo;0;L;;;;;N;;;;; +1072E;LINEAR A SIGN A656;Lo;0;L;;;;;N;;;;; +1072F;LINEAR A SIGN A657;Lo;0;L;;;;;N;;;;; +10730;LINEAR A SIGN A658;Lo;0;L;;;;;N;;;;; +10731;LINEAR A SIGN A659;Lo;0;L;;;;;N;;;;; +10732;LINEAR A SIGN A660;Lo;0;L;;;;;N;;;;; +10733;LINEAR A SIGN A661;Lo;0;L;;;;;N;;;;; +10734;LINEAR A SIGN A662;Lo;0;L;;;;;N;;;;; +10735;LINEAR A SIGN A663;Lo;0;L;;;;;N;;;;; +10736;LINEAR A SIGN A664;Lo;0;L;;;;;N;;;;; +10740;LINEAR A SIGN A701 A;Lo;0;L;;;;;N;;;;; +10741;LINEAR A SIGN A702 B;Lo;0;L;;;;;N;;;;; +10742;LINEAR A SIGN A703 D;Lo;0;L;;;;;N;;;;; +10743;LINEAR A SIGN A704 E;Lo;0;L;;;;;N;;;;; +10744;LINEAR A SIGN A705 F;Lo;0;L;;;;;N;;;;; +10745;LINEAR A SIGN A706 H;Lo;0;L;;;;;N;;;;; +10746;LINEAR A SIGN A707 J;Lo;0;L;;;;;N;;;;; +10747;LINEAR A SIGN A708 K;Lo;0;L;;;;;N;;;;; +10748;LINEAR A SIGN A709 L;Lo;0;L;;;;;N;;;;; +10749;LINEAR A SIGN A709-2 L2;Lo;0;L;;;;;N;;;;; +1074A;LINEAR A SIGN A709-3 L3;Lo;0;L;;;;;N;;;;; +1074B;LINEAR A SIGN A709-4 L4;Lo;0;L;;;;;N;;;;; +1074C;LINEAR A SIGN A709-6 L6;Lo;0;L;;;;;N;;;;; +1074D;LINEAR A SIGN A710 W;Lo;0;L;;;;;N;;;;; +1074E;LINEAR A SIGN A711 X;Lo;0;L;;;;;N;;;;; +1074F;LINEAR A SIGN A712 Y;Lo;0;L;;;;;N;;;;; +10750;LINEAR A SIGN A713 OMEGA;Lo;0;L;;;;;N;;;;; +10751;LINEAR A SIGN A714 ABB;Lo;0;L;;;;;N;;;;; +10752;LINEAR A SIGN A715 BB;Lo;0;L;;;;;N;;;;; +10753;LINEAR A SIGN A717 DD;Lo;0;L;;;;;N;;;;; +10754;LINEAR A SIGN A726 EYYY;Lo;0;L;;;;;N;;;;; +10755;LINEAR A SIGN A732 JE;Lo;0;L;;;;;N;;;;; +10760;LINEAR A SIGN A800;Lo;0;L;;;;;N;;;;; +10761;LINEAR A SIGN A801;Lo;0;L;;;;;N;;;;; +10762;LINEAR A SIGN A802;Lo;0;L;;;;;N;;;;; +10763;LINEAR A SIGN A803;Lo;0;L;;;;;N;;;;; +10764;LINEAR A SIGN A804;Lo;0;L;;;;;N;;;;; +10765;LINEAR A SIGN A805;Lo;0;L;;;;;N;;;;; +10766;LINEAR A SIGN A806;Lo;0;L;;;;;N;;;;; +10767;LINEAR A SIGN A807;Lo;0;L;;;;;N;;;;; +10800;CYPRIOT SYLLABLE A;Lo;0;R;;;;;N;;;;; +10801;CYPRIOT SYLLABLE E;Lo;0;R;;;;;N;;;;; +10802;CYPRIOT SYLLABLE I;Lo;0;R;;;;;N;;;;; +10803;CYPRIOT SYLLABLE O;Lo;0;R;;;;;N;;;;; +10804;CYPRIOT SYLLABLE U;Lo;0;R;;;;;N;;;;; +10805;CYPRIOT SYLLABLE JA;Lo;0;R;;;;;N;;;;; +10808;CYPRIOT SYLLABLE JO;Lo;0;R;;;;;N;;;;; +1080A;CYPRIOT SYLLABLE KA;Lo;0;R;;;;;N;;;;; +1080B;CYPRIOT SYLLABLE KE;Lo;0;R;;;;;N;;;;; +1080C;CYPRIOT SYLLABLE KI;Lo;0;R;;;;;N;;;;; +1080D;CYPRIOT SYLLABLE KO;Lo;0;R;;;;;N;;;;; +1080E;CYPRIOT SYLLABLE KU;Lo;0;R;;;;;N;;;;; +1080F;CYPRIOT SYLLABLE LA;Lo;0;R;;;;;N;;;;; +10810;CYPRIOT SYLLABLE LE;Lo;0;R;;;;;N;;;;; +10811;CYPRIOT SYLLABLE LI;Lo;0;R;;;;;N;;;;; +10812;CYPRIOT SYLLABLE LO;Lo;0;R;;;;;N;;;;; +10813;CYPRIOT SYLLABLE LU;Lo;0;R;;;;;N;;;;; +10814;CYPRIOT SYLLABLE MA;Lo;0;R;;;;;N;;;;; +10815;CYPRIOT SYLLABLE ME;Lo;0;R;;;;;N;;;;; +10816;CYPRIOT SYLLABLE MI;Lo;0;R;;;;;N;;;;; +10817;CYPRIOT SYLLABLE MO;Lo;0;R;;;;;N;;;;; +10818;CYPRIOT SYLLABLE MU;Lo;0;R;;;;;N;;;;; +10819;CYPRIOT SYLLABLE NA;Lo;0;R;;;;;N;;;;; +1081A;CYPRIOT SYLLABLE NE;Lo;0;R;;;;;N;;;;; +1081B;CYPRIOT SYLLABLE NI;Lo;0;R;;;;;N;;;;; +1081C;CYPRIOT SYLLABLE NO;Lo;0;R;;;;;N;;;;; +1081D;CYPRIOT SYLLABLE NU;Lo;0;R;;;;;N;;;;; +1081E;CYPRIOT SYLLABLE PA;Lo;0;R;;;;;N;;;;; +1081F;CYPRIOT SYLLABLE PE;Lo;0;R;;;;;N;;;;; +10820;CYPRIOT SYLLABLE PI;Lo;0;R;;;;;N;;;;; +10821;CYPRIOT SYLLABLE PO;Lo;0;R;;;;;N;;;;; +10822;CYPRIOT SYLLABLE PU;Lo;0;R;;;;;N;;;;; +10823;CYPRIOT SYLLABLE RA;Lo;0;R;;;;;N;;;;; +10824;CYPRIOT SYLLABLE RE;Lo;0;R;;;;;N;;;;; +10825;CYPRIOT SYLLABLE RI;Lo;0;R;;;;;N;;;;; +10826;CYPRIOT SYLLABLE RO;Lo;0;R;;;;;N;;;;; +10827;CYPRIOT SYLLABLE RU;Lo;0;R;;;;;N;;;;; +10828;CYPRIOT SYLLABLE SA;Lo;0;R;;;;;N;;;;; +10829;CYPRIOT SYLLABLE SE;Lo;0;R;;;;;N;;;;; +1082A;CYPRIOT SYLLABLE SI;Lo;0;R;;;;;N;;;;; +1082B;CYPRIOT SYLLABLE SO;Lo;0;R;;;;;N;;;;; +1082C;CYPRIOT SYLLABLE SU;Lo;0;R;;;;;N;;;;; +1082D;CYPRIOT SYLLABLE TA;Lo;0;R;;;;;N;;;;; +1082E;CYPRIOT SYLLABLE TE;Lo;0;R;;;;;N;;;;; +1082F;CYPRIOT SYLLABLE TI;Lo;0;R;;;;;N;;;;; +10830;CYPRIOT SYLLABLE TO;Lo;0;R;;;;;N;;;;; +10831;CYPRIOT SYLLABLE TU;Lo;0;R;;;;;N;;;;; +10832;CYPRIOT SYLLABLE WA;Lo;0;R;;;;;N;;;;; +10833;CYPRIOT SYLLABLE WE;Lo;0;R;;;;;N;;;;; +10834;CYPRIOT SYLLABLE WI;Lo;0;R;;;;;N;;;;; +10835;CYPRIOT SYLLABLE WO;Lo;0;R;;;;;N;;;;; +10837;CYPRIOT SYLLABLE XA;Lo;0;R;;;;;N;;;;; +10838;CYPRIOT SYLLABLE XE;Lo;0;R;;;;;N;;;;; +1083C;CYPRIOT SYLLABLE ZA;Lo;0;R;;;;;N;;;;; +1083F;CYPRIOT SYLLABLE ZO;Lo;0;R;;;;;N;;;;; +10840;IMPERIAL ARAMAIC LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10841;IMPERIAL ARAMAIC LETTER BETH;Lo;0;R;;;;;N;;;;; +10842;IMPERIAL ARAMAIC LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10843;IMPERIAL ARAMAIC LETTER DALETH;Lo;0;R;;;;;N;;;;; +10844;IMPERIAL ARAMAIC LETTER HE;Lo;0;R;;;;;N;;;;; +10845;IMPERIAL ARAMAIC LETTER WAW;Lo;0;R;;;;;N;;;;; +10846;IMPERIAL ARAMAIC LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10847;IMPERIAL ARAMAIC LETTER HETH;Lo;0;R;;;;;N;;;;; +10848;IMPERIAL ARAMAIC LETTER TETH;Lo;0;R;;;;;N;;;;; +10849;IMPERIAL ARAMAIC LETTER YODH;Lo;0;R;;;;;N;;;;; +1084A;IMPERIAL ARAMAIC LETTER KAPH;Lo;0;R;;;;;N;;;;; +1084B;IMPERIAL ARAMAIC LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +1084C;IMPERIAL ARAMAIC LETTER MEM;Lo;0;R;;;;;N;;;;; +1084D;IMPERIAL ARAMAIC LETTER NUN;Lo;0;R;;;;;N;;;;; +1084E;IMPERIAL ARAMAIC LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +1084F;IMPERIAL ARAMAIC LETTER AYIN;Lo;0;R;;;;;N;;;;; +10850;IMPERIAL ARAMAIC LETTER PE;Lo;0;R;;;;;N;;;;; +10851;IMPERIAL ARAMAIC LETTER SADHE;Lo;0;R;;;;;N;;;;; +10852;IMPERIAL ARAMAIC LETTER QOPH;Lo;0;R;;;;;N;;;;; +10853;IMPERIAL ARAMAIC LETTER RESH;Lo;0;R;;;;;N;;;;; +10854;IMPERIAL ARAMAIC LETTER SHIN;Lo;0;R;;;;;N;;;;; +10855;IMPERIAL ARAMAIC LETTER TAW;Lo;0;R;;;;;N;;;;; +10857;IMPERIAL ARAMAIC SECTION SIGN;Po;0;R;;;;;N;;;;; +10858;IMPERIAL ARAMAIC NUMBER ONE;No;0;R;;;;1;N;;;;; +10859;IMPERIAL ARAMAIC NUMBER TWO;No;0;R;;;;2;N;;;;; +1085A;IMPERIAL ARAMAIC NUMBER THREE;No;0;R;;;;3;N;;;;; +1085B;IMPERIAL ARAMAIC NUMBER TEN;No;0;R;;;;10;N;;;;; +1085C;IMPERIAL ARAMAIC NUMBER TWENTY;No;0;R;;;;20;N;;;;; +1085D;IMPERIAL ARAMAIC NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +1085E;IMPERIAL ARAMAIC NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;; +1085F;IMPERIAL ARAMAIC NUMBER TEN THOUSAND;No;0;R;;;;10000;N;;;;; +10860;PALMYRENE LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10861;PALMYRENE LETTER BETH;Lo;0;R;;;;;N;;;;; +10862;PALMYRENE LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10863;PALMYRENE LETTER DALETH;Lo;0;R;;;;;N;;;;; +10864;PALMYRENE LETTER HE;Lo;0;R;;;;;N;;;;; +10865;PALMYRENE LETTER WAW;Lo;0;R;;;;;N;;;;; +10866;PALMYRENE LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10867;PALMYRENE LETTER HETH;Lo;0;R;;;;;N;;;;; +10868;PALMYRENE LETTER TETH;Lo;0;R;;;;;N;;;;; +10869;PALMYRENE LETTER YODH;Lo;0;R;;;;;N;;;;; +1086A;PALMYRENE LETTER KAPH;Lo;0;R;;;;;N;;;;; +1086B;PALMYRENE LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +1086C;PALMYRENE LETTER MEM;Lo;0;R;;;;;N;;;;; +1086D;PALMYRENE LETTER FINAL NUN;Lo;0;R;;;;;N;;;;; +1086E;PALMYRENE LETTER NUN;Lo;0;R;;;;;N;;;;; +1086F;PALMYRENE LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10870;PALMYRENE LETTER AYIN;Lo;0;R;;;;;N;;;;; +10871;PALMYRENE LETTER PE;Lo;0;R;;;;;N;;;;; +10872;PALMYRENE LETTER SADHE;Lo;0;R;;;;;N;;;;; +10873;PALMYRENE LETTER QOPH;Lo;0;R;;;;;N;;;;; +10874;PALMYRENE LETTER RESH;Lo;0;R;;;;;N;;;;; +10875;PALMYRENE LETTER SHIN;Lo;0;R;;;;;N;;;;; +10876;PALMYRENE LETTER TAW;Lo;0;R;;;;;N;;;;; +10877;PALMYRENE LEFT-POINTING FLEURON;So;0;R;;;;;N;;;;; +10878;PALMYRENE RIGHT-POINTING FLEURON;So;0;R;;;;;N;;;;; +10879;PALMYRENE NUMBER ONE;No;0;R;;;;1;N;;;;; +1087A;PALMYRENE NUMBER TWO;No;0;R;;;;2;N;;;;; +1087B;PALMYRENE NUMBER THREE;No;0;R;;;;3;N;;;;; +1087C;PALMYRENE NUMBER FOUR;No;0;R;;;;4;N;;;;; +1087D;PALMYRENE NUMBER FIVE;No;0;R;;;;5;N;;;;; +1087E;PALMYRENE NUMBER TEN;No;0;R;;;;10;N;;;;; +1087F;PALMYRENE NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10880;NABATAEAN LETTER FINAL ALEPH;Lo;0;R;;;;;N;;;;; +10881;NABATAEAN LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10882;NABATAEAN LETTER FINAL BETH;Lo;0;R;;;;;N;;;;; +10883;NABATAEAN LETTER BETH;Lo;0;R;;;;;N;;;;; +10884;NABATAEAN LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10885;NABATAEAN LETTER DALETH;Lo;0;R;;;;;N;;;;; +10886;NABATAEAN LETTER FINAL HE;Lo;0;R;;;;;N;;;;; +10887;NABATAEAN LETTER HE;Lo;0;R;;;;;N;;;;; +10888;NABATAEAN LETTER WAW;Lo;0;R;;;;;N;;;;; +10889;NABATAEAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +1088A;NABATAEAN LETTER HETH;Lo;0;R;;;;;N;;;;; +1088B;NABATAEAN LETTER TETH;Lo;0;R;;;;;N;;;;; +1088C;NABATAEAN LETTER FINAL YODH;Lo;0;R;;;;;N;;;;; +1088D;NABATAEAN LETTER YODH;Lo;0;R;;;;;N;;;;; +1088E;NABATAEAN LETTER FINAL KAPH;Lo;0;R;;;;;N;;;;; +1088F;NABATAEAN LETTER KAPH;Lo;0;R;;;;;N;;;;; +10890;NABATAEAN LETTER FINAL LAMEDH;Lo;0;R;;;;;N;;;;; +10891;NABATAEAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10892;NABATAEAN LETTER FINAL MEM;Lo;0;R;;;;;N;;;;; +10893;NABATAEAN LETTER MEM;Lo;0;R;;;;;N;;;;; +10894;NABATAEAN LETTER FINAL NUN;Lo;0;R;;;;;N;;;;; +10895;NABATAEAN LETTER NUN;Lo;0;R;;;;;N;;;;; +10896;NABATAEAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10897;NABATAEAN LETTER AYIN;Lo;0;R;;;;;N;;;;; +10898;NABATAEAN LETTER PE;Lo;0;R;;;;;N;;;;; +10899;NABATAEAN LETTER SADHE;Lo;0;R;;;;;N;;;;; +1089A;NABATAEAN LETTER QOPH;Lo;0;R;;;;;N;;;;; +1089B;NABATAEAN LETTER RESH;Lo;0;R;;;;;N;;;;; +1089C;NABATAEAN LETTER FINAL SHIN;Lo;0;R;;;;;N;;;;; +1089D;NABATAEAN LETTER SHIN;Lo;0;R;;;;;N;;;;; +1089E;NABATAEAN LETTER TAW;Lo;0;R;;;;;N;;;;; +108A7;NABATAEAN NUMBER ONE;No;0;R;;;;1;N;;;;; +108A8;NABATAEAN NUMBER TWO;No;0;R;;;;2;N;;;;; +108A9;NABATAEAN NUMBER THREE;No;0;R;;;;3;N;;;;; +108AA;NABATAEAN NUMBER FOUR;No;0;R;;;;4;N;;;;; +108AB;NABATAEAN CRUCIFORM NUMBER FOUR;No;0;R;;;;4;N;;;;; +108AC;NABATAEAN NUMBER FIVE;No;0;R;;;;5;N;;;;; +108AD;NABATAEAN NUMBER TEN;No;0;R;;;;10;N;;;;; +108AE;NABATAEAN NUMBER TWENTY;No;0;R;;;;20;N;;;;; +108AF;NABATAEAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +108E0;HATRAN LETTER ALEPH;Lo;0;R;;;;;N;;;;; +108E1;HATRAN LETTER BETH;Lo;0;R;;;;;N;;;;; +108E2;HATRAN LETTER GIMEL;Lo;0;R;;;;;N;;;;; +108E3;HATRAN LETTER DALETH-RESH;Lo;0;R;;;;;N;;;;; +108E4;HATRAN LETTER HE;Lo;0;R;;;;;N;;;;; +108E5;HATRAN LETTER WAW;Lo;0;R;;;;;N;;;;; +108E6;HATRAN LETTER ZAYN;Lo;0;R;;;;;N;;;;; +108E7;HATRAN LETTER HETH;Lo;0;R;;;;;N;;;;; +108E8;HATRAN LETTER TETH;Lo;0;R;;;;;N;;;;; +108E9;HATRAN LETTER YODH;Lo;0;R;;;;;N;;;;; +108EA;HATRAN LETTER KAPH;Lo;0;R;;;;;N;;;;; +108EB;HATRAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +108EC;HATRAN LETTER MEM;Lo;0;R;;;;;N;;;;; +108ED;HATRAN LETTER NUN;Lo;0;R;;;;;N;;;;; +108EE;HATRAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +108EF;HATRAN LETTER AYN;Lo;0;R;;;;;N;;;;; +108F0;HATRAN LETTER PE;Lo;0;R;;;;;N;;;;; +108F1;HATRAN LETTER SADHE;Lo;0;R;;;;;N;;;;; +108F2;HATRAN LETTER QOPH;Lo;0;R;;;;;N;;;;; +108F4;HATRAN LETTER SHIN;Lo;0;R;;;;;N;;;;; +108F5;HATRAN LETTER TAW;Lo;0;R;;;;;N;;;;; +108FB;HATRAN NUMBER ONE;No;0;R;;;;1;N;;;;; +108FC;HATRAN NUMBER FIVE;No;0;R;;;;5;N;;;;; +108FD;HATRAN NUMBER TEN;No;0;R;;;;10;N;;;;; +108FE;HATRAN NUMBER TWENTY;No;0;R;;;;20;N;;;;; +108FF;HATRAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +10900;PHOENICIAN LETTER ALF;Lo;0;R;;;;;N;;;;; +10901;PHOENICIAN LETTER BET;Lo;0;R;;;;;N;;;;; +10902;PHOENICIAN LETTER GAML;Lo;0;R;;;;;N;;;;; +10903;PHOENICIAN LETTER DELT;Lo;0;R;;;;;N;;;;; +10904;PHOENICIAN LETTER HE;Lo;0;R;;;;;N;;;;; +10905;PHOENICIAN LETTER WAU;Lo;0;R;;;;;N;;;;; +10906;PHOENICIAN LETTER ZAI;Lo;0;R;;;;;N;;;;; +10907;PHOENICIAN LETTER HET;Lo;0;R;;;;;N;;;;; +10908;PHOENICIAN LETTER TET;Lo;0;R;;;;;N;;;;; +10909;PHOENICIAN LETTER YOD;Lo;0;R;;;;;N;;;;; +1090A;PHOENICIAN LETTER KAF;Lo;0;R;;;;;N;;;;; +1090B;PHOENICIAN LETTER LAMD;Lo;0;R;;;;;N;;;;; +1090C;PHOENICIAN LETTER MEM;Lo;0;R;;;;;N;;;;; +1090D;PHOENICIAN LETTER NUN;Lo;0;R;;;;;N;;;;; +1090E;PHOENICIAN LETTER SEMK;Lo;0;R;;;;;N;;;;; +1090F;PHOENICIAN LETTER AIN;Lo;0;R;;;;;N;;;;; +10910;PHOENICIAN LETTER PE;Lo;0;R;;;;;N;;;;; +10911;PHOENICIAN LETTER SADE;Lo;0;R;;;;;N;;;;; +10912;PHOENICIAN LETTER QOF;Lo;0;R;;;;;N;;;;; +10913;PHOENICIAN LETTER ROSH;Lo;0;R;;;;;N;;;;; +10914;PHOENICIAN LETTER SHIN;Lo;0;R;;;;;N;;;;; +10915;PHOENICIAN LETTER TAU;Lo;0;R;;;;;N;;;;; +10916;PHOENICIAN NUMBER ONE;No;0;R;;;;1;N;;;;; +10917;PHOENICIAN NUMBER TEN;No;0;R;;;;10;N;;;;; +10918;PHOENICIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10919;PHOENICIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +1091A;PHOENICIAN NUMBER TWO;No;0;R;;;;2;N;;;;; +1091B;PHOENICIAN NUMBER THREE;No;0;R;;;;3;N;;;;; +1091F;PHOENICIAN WORD SEPARATOR;Po;0;ON;;;;;N;;;;; +10920;LYDIAN LETTER A;Lo;0;R;;;;;N;;;;; +10921;LYDIAN LETTER B;Lo;0;R;;;;;N;;;;; +10922;LYDIAN LETTER G;Lo;0;R;;;;;N;;;;; +10923;LYDIAN LETTER D;Lo;0;R;;;;;N;;;;; +10924;LYDIAN LETTER E;Lo;0;R;;;;;N;;;;; +10925;LYDIAN LETTER V;Lo;0;R;;;;;N;;;;; +10926;LYDIAN LETTER I;Lo;0;R;;;;;N;;;;; +10927;LYDIAN LETTER Y;Lo;0;R;;;;;N;;;;; +10928;LYDIAN LETTER K;Lo;0;R;;;;;N;;;;; +10929;LYDIAN LETTER L;Lo;0;R;;;;;N;;;;; +1092A;LYDIAN LETTER M;Lo;0;R;;;;;N;;;;; +1092B;LYDIAN LETTER N;Lo;0;R;;;;;N;;;;; +1092C;LYDIAN LETTER O;Lo;0;R;;;;;N;;;;; +1092D;LYDIAN LETTER R;Lo;0;R;;;;;N;;;;; +1092E;LYDIAN LETTER SS;Lo;0;R;;;;;N;;;;; +1092F;LYDIAN LETTER T;Lo;0;R;;;;;N;;;;; +10930;LYDIAN LETTER U;Lo;0;R;;;;;N;;;;; +10931;LYDIAN LETTER F;Lo;0;R;;;;;N;;;;; +10932;LYDIAN LETTER Q;Lo;0;R;;;;;N;;;;; +10933;LYDIAN LETTER S;Lo;0;R;;;;;N;;;;; +10934;LYDIAN LETTER TT;Lo;0;R;;;;;N;;;;; +10935;LYDIAN LETTER AN;Lo;0;R;;;;;N;;;;; +10936;LYDIAN LETTER EN;Lo;0;R;;;;;N;;;;; +10937;LYDIAN LETTER LY;Lo;0;R;;;;;N;;;;; +10938;LYDIAN LETTER NN;Lo;0;R;;;;;N;;;;; +10939;LYDIAN LETTER C;Lo;0;R;;;;;N;;;;; +1093F;LYDIAN TRIANGULAR MARK;Po;0;R;;;;;N;;;;; +10980;MEROITIC HIEROGLYPHIC LETTER A;Lo;0;R;;;;;N;;;;; +10981;MEROITIC HIEROGLYPHIC LETTER E;Lo;0;R;;;;;N;;;;; +10982;MEROITIC HIEROGLYPHIC LETTER I;Lo;0;R;;;;;N;;;;; +10983;MEROITIC HIEROGLYPHIC LETTER O;Lo;0;R;;;;;N;;;;; +10984;MEROITIC HIEROGLYPHIC LETTER YA;Lo;0;R;;;;;N;;;;; +10985;MEROITIC HIEROGLYPHIC LETTER WA;Lo;0;R;;;;;N;;;;; +10986;MEROITIC HIEROGLYPHIC LETTER BA;Lo;0;R;;;;;N;;;;; +10987;MEROITIC HIEROGLYPHIC LETTER BA-2;Lo;0;R;;;;;N;;;;; +10988;MEROITIC HIEROGLYPHIC LETTER PA;Lo;0;R;;;;;N;;;;; +10989;MEROITIC HIEROGLYPHIC LETTER MA;Lo;0;R;;;;;N;;;;; +1098A;MEROITIC HIEROGLYPHIC LETTER NA;Lo;0;R;;;;;N;;;;; +1098B;MEROITIC HIEROGLYPHIC LETTER NA-2;Lo;0;R;;;;;N;;;;; +1098C;MEROITIC HIEROGLYPHIC LETTER NE;Lo;0;R;;;;;N;;;;; +1098D;MEROITIC HIEROGLYPHIC LETTER NE-2;Lo;0;R;;;;;N;;;;; +1098E;MEROITIC HIEROGLYPHIC LETTER RA;Lo;0;R;;;;;N;;;;; +1098F;MEROITIC HIEROGLYPHIC LETTER RA-2;Lo;0;R;;;;;N;;;;; +10990;MEROITIC HIEROGLYPHIC LETTER LA;Lo;0;R;;;;;N;;;;; +10991;MEROITIC HIEROGLYPHIC LETTER KHA;Lo;0;R;;;;;N;;;;; +10992;MEROITIC HIEROGLYPHIC LETTER HHA;Lo;0;R;;;;;N;;;;; +10993;MEROITIC HIEROGLYPHIC LETTER SA;Lo;0;R;;;;;N;;;;; +10994;MEROITIC HIEROGLYPHIC LETTER SA-2;Lo;0;R;;;;;N;;;;; +10995;MEROITIC HIEROGLYPHIC LETTER SE;Lo;0;R;;;;;N;;;;; +10996;MEROITIC HIEROGLYPHIC LETTER KA;Lo;0;R;;;;;N;;;;; +10997;MEROITIC HIEROGLYPHIC LETTER QA;Lo;0;R;;;;;N;;;;; +10998;MEROITIC HIEROGLYPHIC LETTER TA;Lo;0;R;;;;;N;;;;; +10999;MEROITIC HIEROGLYPHIC LETTER TA-2;Lo;0;R;;;;;N;;;;; +1099A;MEROITIC HIEROGLYPHIC LETTER TE;Lo;0;R;;;;;N;;;;; +1099B;MEROITIC HIEROGLYPHIC LETTER TE-2;Lo;0;R;;;;;N;;;;; +1099C;MEROITIC HIEROGLYPHIC LETTER TO;Lo;0;R;;;;;N;;;;; +1099D;MEROITIC HIEROGLYPHIC LETTER DA;Lo;0;R;;;;;N;;;;; +1099E;MEROITIC HIEROGLYPHIC SYMBOL VIDJ;Lo;0;R;;;;;N;;;;; +1099F;MEROITIC HIEROGLYPHIC SYMBOL VIDJ-2;Lo;0;R;;;;;N;;;;; +109A0;MEROITIC CURSIVE LETTER A;Lo;0;R;;;;;N;;;;; +109A1;MEROITIC CURSIVE LETTER E;Lo;0;R;;;;;N;;;;; +109A2;MEROITIC CURSIVE LETTER I;Lo;0;R;;;;;N;;;;; +109A3;MEROITIC CURSIVE LETTER O;Lo;0;R;;;;;N;;;;; +109A4;MEROITIC CURSIVE LETTER YA;Lo;0;R;;;;;N;;;;; +109A5;MEROITIC CURSIVE LETTER WA;Lo;0;R;;;;;N;;;;; +109A6;MEROITIC CURSIVE LETTER BA;Lo;0;R;;;;;N;;;;; +109A7;MEROITIC CURSIVE LETTER PA;Lo;0;R;;;;;N;;;;; +109A8;MEROITIC CURSIVE LETTER MA;Lo;0;R;;;;;N;;;;; +109A9;MEROITIC CURSIVE LETTER NA;Lo;0;R;;;;;N;;;;; +109AA;MEROITIC CURSIVE LETTER NE;Lo;0;R;;;;;N;;;;; +109AB;MEROITIC CURSIVE LETTER RA;Lo;0;R;;;;;N;;;;; +109AC;MEROITIC CURSIVE LETTER LA;Lo;0;R;;;;;N;;;;; +109AD;MEROITIC CURSIVE LETTER KHA;Lo;0;R;;;;;N;;;;; +109AE;MEROITIC CURSIVE LETTER HHA;Lo;0;R;;;;;N;;;;; +109AF;MEROITIC CURSIVE LETTER SA;Lo;0;R;;;;;N;;;;; +109B0;MEROITIC CURSIVE LETTER ARCHAIC SA;Lo;0;R;;;;;N;;;;; +109B1;MEROITIC CURSIVE LETTER SE;Lo;0;R;;;;;N;;;;; +109B2;MEROITIC CURSIVE LETTER KA;Lo;0;R;;;;;N;;;;; +109B3;MEROITIC CURSIVE LETTER QA;Lo;0;R;;;;;N;;;;; +109B4;MEROITIC CURSIVE LETTER TA;Lo;0;R;;;;;N;;;;; +109B5;MEROITIC CURSIVE LETTER TE;Lo;0;R;;;;;N;;;;; +109B6;MEROITIC CURSIVE LETTER TO;Lo;0;R;;;;;N;;;;; +109B7;MEROITIC CURSIVE LETTER DA;Lo;0;R;;;;;N;;;;; +109BC;MEROITIC CURSIVE FRACTION ELEVEN TWELFTHS;No;0;R;;;;11/12;N;;;;; +109BD;MEROITIC CURSIVE FRACTION ONE HALF;No;0;R;;;;1/2;N;;;;; +109BE;MEROITIC CURSIVE LOGOGRAM RMT;Lo;0;R;;;;;N;;;;; +109BF;MEROITIC CURSIVE LOGOGRAM IMN;Lo;0;R;;;;;N;;;;; +109C0;MEROITIC CURSIVE NUMBER ONE;No;0;R;;;;1;N;;;;; +109C1;MEROITIC CURSIVE NUMBER TWO;No;0;R;;;;2;N;;;;; +109C2;MEROITIC CURSIVE NUMBER THREE;No;0;R;;;;3;N;;;;; +109C3;MEROITIC CURSIVE NUMBER FOUR;No;0;R;;;;4;N;;;;; +109C4;MEROITIC CURSIVE NUMBER FIVE;No;0;R;;;;5;N;;;;; +109C5;MEROITIC CURSIVE NUMBER SIX;No;0;R;;;;6;N;;;;; +109C6;MEROITIC CURSIVE NUMBER SEVEN;No;0;R;;;;7;N;;;;; +109C7;MEROITIC CURSIVE NUMBER EIGHT;No;0;R;;;;8;N;;;;; +109C8;MEROITIC CURSIVE NUMBER NINE;No;0;R;;;;9;N;;;;; +109C9;MEROITIC CURSIVE NUMBER TEN;No;0;R;;;;10;N;;;;; +109CA;MEROITIC CURSIVE NUMBER TWENTY;No;0;R;;;;20;N;;;;; +109CB;MEROITIC CURSIVE NUMBER THIRTY;No;0;R;;;;30;N;;;;; +109CC;MEROITIC CURSIVE NUMBER FORTY;No;0;R;;;;40;N;;;;; +109CD;MEROITIC CURSIVE NUMBER FIFTY;No;0;R;;;;50;N;;;;; +109CE;MEROITIC CURSIVE NUMBER SIXTY;No;0;R;;;;60;N;;;;; +109CF;MEROITIC CURSIVE NUMBER SEVENTY;No;0;R;;;;70;N;;;;; +109D2;MEROITIC CURSIVE NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +109D3;MEROITIC CURSIVE NUMBER TWO HUNDRED;No;0;R;;;;200;N;;;;; +109D4;MEROITIC CURSIVE NUMBER THREE HUNDRED;No;0;R;;;;300;N;;;;; +109D5;MEROITIC CURSIVE NUMBER FOUR HUNDRED;No;0;R;;;;400;N;;;;; +109D6;MEROITIC CURSIVE NUMBER FIVE HUNDRED;No;0;R;;;;500;N;;;;; +109D7;MEROITIC CURSIVE NUMBER SIX HUNDRED;No;0;R;;;;600;N;;;;; +109D8;MEROITIC CURSIVE NUMBER SEVEN HUNDRED;No;0;R;;;;700;N;;;;; +109D9;MEROITIC CURSIVE NUMBER EIGHT HUNDRED;No;0;R;;;;800;N;;;;; +109DA;MEROITIC CURSIVE NUMBER NINE HUNDRED;No;0;R;;;;900;N;;;;; +109DB;MEROITIC CURSIVE NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;; +109DC;MEROITIC CURSIVE NUMBER TWO THOUSAND;No;0;R;;;;2000;N;;;;; +109DD;MEROITIC CURSIVE NUMBER THREE THOUSAND;No;0;R;;;;3000;N;;;;; +109DE;MEROITIC CURSIVE NUMBER FOUR THOUSAND;No;0;R;;;;4000;N;;;;; +109DF;MEROITIC CURSIVE NUMBER FIVE THOUSAND;No;0;R;;;;5000;N;;;;; +109E0;MEROITIC CURSIVE NUMBER SIX THOUSAND;No;0;R;;;;6000;N;;;;; +109E1;MEROITIC CURSIVE NUMBER SEVEN THOUSAND;No;0;R;;;;7000;N;;;;; +109E2;MEROITIC CURSIVE NUMBER EIGHT THOUSAND;No;0;R;;;;8000;N;;;;; +109E3;MEROITIC CURSIVE NUMBER NINE THOUSAND;No;0;R;;;;9000;N;;;;; +109E4;MEROITIC CURSIVE NUMBER TEN THOUSAND;No;0;R;;;;10000;N;;;;; +109E5;MEROITIC CURSIVE NUMBER TWENTY THOUSAND;No;0;R;;;;20000;N;;;;; +109E6;MEROITIC CURSIVE NUMBER THIRTY THOUSAND;No;0;R;;;;30000;N;;;;; +109E7;MEROITIC CURSIVE NUMBER FORTY THOUSAND;No;0;R;;;;40000;N;;;;; +109E8;MEROITIC CURSIVE NUMBER FIFTY THOUSAND;No;0;R;;;;50000;N;;;;; +109E9;MEROITIC CURSIVE NUMBER SIXTY THOUSAND;No;0;R;;;;60000;N;;;;; +109EA;MEROITIC CURSIVE NUMBER SEVENTY THOUSAND;No;0;R;;;;70000;N;;;;; +109EB;MEROITIC CURSIVE NUMBER EIGHTY THOUSAND;No;0;R;;;;80000;N;;;;; +109EC;MEROITIC CURSIVE NUMBER NINETY THOUSAND;No;0;R;;;;90000;N;;;;; +109ED;MEROITIC CURSIVE NUMBER ONE HUNDRED THOUSAND;No;0;R;;;;100000;N;;;;; +109EE;MEROITIC CURSIVE NUMBER TWO HUNDRED THOUSAND;No;0;R;;;;200000;N;;;;; +109EF;MEROITIC CURSIVE NUMBER THREE HUNDRED THOUSAND;No;0;R;;;;300000;N;;;;; +109F0;MEROITIC CURSIVE NUMBER FOUR HUNDRED THOUSAND;No;0;R;;;;400000;N;;;;; +109F1;MEROITIC CURSIVE NUMBER FIVE HUNDRED THOUSAND;No;0;R;;;;500000;N;;;;; +109F2;MEROITIC CURSIVE NUMBER SIX HUNDRED THOUSAND;No;0;R;;;;600000;N;;;;; +109F3;MEROITIC CURSIVE NUMBER SEVEN HUNDRED THOUSAND;No;0;R;;;;700000;N;;;;; +109F4;MEROITIC CURSIVE NUMBER EIGHT HUNDRED THOUSAND;No;0;R;;;;800000;N;;;;; +109F5;MEROITIC CURSIVE NUMBER NINE HUNDRED THOUSAND;No;0;R;;;;900000;N;;;;; +109F6;MEROITIC CURSIVE FRACTION ONE TWELFTH;No;0;R;;;;1/12;N;;;;; +109F7;MEROITIC CURSIVE FRACTION TWO TWELFTHS;No;0;R;;;;2/12;N;;;;; +109F8;MEROITIC CURSIVE FRACTION THREE TWELFTHS;No;0;R;;;;3/12;N;;;;; +109F9;MEROITIC CURSIVE FRACTION FOUR TWELFTHS;No;0;R;;;;4/12;N;;;;; +109FA;MEROITIC CURSIVE FRACTION FIVE TWELFTHS;No;0;R;;;;5/12;N;;;;; +109FB;MEROITIC CURSIVE FRACTION SIX TWELFTHS;No;0;R;;;;6/12;N;;;;; +109FC;MEROITIC CURSIVE FRACTION SEVEN TWELFTHS;No;0;R;;;;7/12;N;;;;; +109FD;MEROITIC CURSIVE FRACTION EIGHT TWELFTHS;No;0;R;;;;8/12;N;;;;; +109FE;MEROITIC CURSIVE FRACTION NINE TWELFTHS;No;0;R;;;;9/12;N;;;;; +109FF;MEROITIC CURSIVE FRACTION TEN TWELFTHS;No;0;R;;;;10/12;N;;;;; +10A00;KHAROSHTHI LETTER A;Lo;0;R;;;;;N;;;;; +10A01;KHAROSHTHI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +10A02;KHAROSHTHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +10A03;KHAROSHTHI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +10A05;KHAROSHTHI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +10A06;KHAROSHTHI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +10A0C;KHAROSHTHI VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;; +10A0D;KHAROSHTHI SIGN DOUBLE RING BELOW;Mn;220;NSM;;;;;N;;;;; +10A0E;KHAROSHTHI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +10A0F;KHAROSHTHI SIGN VISARGA;Mn;230;NSM;;;;;N;;;;; +10A10;KHAROSHTHI LETTER KA;Lo;0;R;;;;;N;;;;; +10A11;KHAROSHTHI LETTER KHA;Lo;0;R;;;;;N;;;;; +10A12;KHAROSHTHI LETTER GA;Lo;0;R;;;;;N;;;;; +10A13;KHAROSHTHI LETTER GHA;Lo;0;R;;;;;N;;;;; +10A15;KHAROSHTHI LETTER CA;Lo;0;R;;;;;N;;;;; +10A16;KHAROSHTHI LETTER CHA;Lo;0;R;;;;;N;;;;; +10A17;KHAROSHTHI LETTER JA;Lo;0;R;;;;;N;;;;; +10A19;KHAROSHTHI LETTER NYA;Lo;0;R;;;;;N;;;;; +10A1A;KHAROSHTHI LETTER TTA;Lo;0;R;;;;;N;;;;; +10A1B;KHAROSHTHI LETTER TTHA;Lo;0;R;;;;;N;;;;; +10A1C;KHAROSHTHI LETTER DDA;Lo;0;R;;;;;N;;;;; +10A1D;KHAROSHTHI LETTER DDHA;Lo;0;R;;;;;N;;;;; +10A1E;KHAROSHTHI LETTER NNA;Lo;0;R;;;;;N;;;;; +10A1F;KHAROSHTHI LETTER TA;Lo;0;R;;;;;N;;;;; +10A20;KHAROSHTHI LETTER THA;Lo;0;R;;;;;N;;;;; +10A21;KHAROSHTHI LETTER DA;Lo;0;R;;;;;N;;;;; +10A22;KHAROSHTHI LETTER DHA;Lo;0;R;;;;;N;;;;; +10A23;KHAROSHTHI LETTER NA;Lo;0;R;;;;;N;;;;; +10A24;KHAROSHTHI LETTER PA;Lo;0;R;;;;;N;;;;; +10A25;KHAROSHTHI LETTER PHA;Lo;0;R;;;;;N;;;;; +10A26;KHAROSHTHI LETTER BA;Lo;0;R;;;;;N;;;;; +10A27;KHAROSHTHI LETTER BHA;Lo;0;R;;;;;N;;;;; +10A28;KHAROSHTHI LETTER MA;Lo;0;R;;;;;N;;;;; +10A29;KHAROSHTHI LETTER YA;Lo;0;R;;;;;N;;;;; +10A2A;KHAROSHTHI LETTER RA;Lo;0;R;;;;;N;;;;; +10A2B;KHAROSHTHI LETTER LA;Lo;0;R;;;;;N;;;;; +10A2C;KHAROSHTHI LETTER VA;Lo;0;R;;;;;N;;;;; +10A2D;KHAROSHTHI LETTER SHA;Lo;0;R;;;;;N;;;;; +10A2E;KHAROSHTHI LETTER SSA;Lo;0;R;;;;;N;;;;; +10A2F;KHAROSHTHI LETTER SA;Lo;0;R;;;;;N;;;;; +10A30;KHAROSHTHI LETTER ZA;Lo;0;R;;;;;N;;;;; +10A31;KHAROSHTHI LETTER HA;Lo;0;R;;;;;N;;;;; +10A32;KHAROSHTHI LETTER KKA;Lo;0;R;;;;;N;;;;; +10A33;KHAROSHTHI LETTER TTTHA;Lo;0;R;;;;;N;;;;; +10A34;KHAROSHTHI LETTER TTTA;Lo;0;R;;;;;N;;;;; +10A35;KHAROSHTHI LETTER VHA;Lo;0;R;;;;;N;;;;; +10A38;KHAROSHTHI SIGN BAR ABOVE;Mn;230;NSM;;;;;N;;;;; +10A39;KHAROSHTHI SIGN CAUDA;Mn;1;NSM;;;;;N;;;;; +10A3A;KHAROSHTHI SIGN DOT BELOW;Mn;220;NSM;;;;;N;;;;; +10A3F;KHAROSHTHI VIRAMA;Mn;9;NSM;;;;;N;;;;; +10A40;KHAROSHTHI DIGIT ONE;No;0;R;;;1;1;N;;;;; +10A41;KHAROSHTHI DIGIT TWO;No;0;R;;;2;2;N;;;;; +10A42;KHAROSHTHI DIGIT THREE;No;0;R;;;3;3;N;;;;; +10A43;KHAROSHTHI DIGIT FOUR;No;0;R;;;4;4;N;;;;; +10A44;KHAROSHTHI NUMBER TEN;No;0;R;;;;10;N;;;;; +10A45;KHAROSHTHI NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10A46;KHAROSHTHI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +10A47;KHAROSHTHI NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;; +10A48;KHAROSHTHI FRACTION ONE HALF;No;0;R;;;;1/2;N;;;;; +10A50;KHAROSHTHI PUNCTUATION DOT;Po;0;R;;;;;N;;;;; +10A51;KHAROSHTHI PUNCTUATION SMALL CIRCLE;Po;0;R;;;;;N;;;;; +10A52;KHAROSHTHI PUNCTUATION CIRCLE;Po;0;R;;;;;N;;;;; +10A53;KHAROSHTHI PUNCTUATION CRESCENT BAR;Po;0;R;;;;;N;;;;; +10A54;KHAROSHTHI PUNCTUATION MANGALAM;Po;0;R;;;;;N;;;;; +10A55;KHAROSHTHI PUNCTUATION LOTUS;Po;0;R;;;;;N;;;;; +10A56;KHAROSHTHI PUNCTUATION DANDA;Po;0;R;;;;;N;;;;; +10A57;KHAROSHTHI PUNCTUATION DOUBLE DANDA;Po;0;R;;;;;N;;;;; +10A58;KHAROSHTHI PUNCTUATION LINES;Po;0;R;;;;;N;;;;; +10A60;OLD SOUTH ARABIAN LETTER HE;Lo;0;R;;;;;N;;;;; +10A61;OLD SOUTH ARABIAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10A62;OLD SOUTH ARABIAN LETTER HETH;Lo;0;R;;;;;N;;;;; +10A63;OLD SOUTH ARABIAN LETTER MEM;Lo;0;R;;;;;N;;;;; +10A64;OLD SOUTH ARABIAN LETTER QOPH;Lo;0;R;;;;;N;;;;; +10A65;OLD SOUTH ARABIAN LETTER WAW;Lo;0;R;;;;;N;;;;; +10A66;OLD SOUTH ARABIAN LETTER SHIN;Lo;0;R;;;;;N;;;;; +10A67;OLD SOUTH ARABIAN LETTER RESH;Lo;0;R;;;;;N;;;;; +10A68;OLD SOUTH ARABIAN LETTER BETH;Lo;0;R;;;;;N;;;;; +10A69;OLD SOUTH ARABIAN LETTER TAW;Lo;0;R;;;;;N;;;;; +10A6A;OLD SOUTH ARABIAN LETTER SAT;Lo;0;R;;;;;N;;;;; +10A6B;OLD SOUTH ARABIAN LETTER KAPH;Lo;0;R;;;;;N;;;;; +10A6C;OLD SOUTH ARABIAN LETTER NUN;Lo;0;R;;;;;N;;;;; +10A6D;OLD SOUTH ARABIAN LETTER KHETH;Lo;0;R;;;;;N;;;;; +10A6E;OLD SOUTH ARABIAN LETTER SADHE;Lo;0;R;;;;;N;;;;; +10A6F;OLD SOUTH ARABIAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10A70;OLD SOUTH ARABIAN LETTER FE;Lo;0;R;;;;;N;;;;; +10A71;OLD SOUTH ARABIAN LETTER ALEF;Lo;0;R;;;;;N;;;;; +10A72;OLD SOUTH ARABIAN LETTER AYN;Lo;0;R;;;;;N;;;;; +10A73;OLD SOUTH ARABIAN LETTER DHADHE;Lo;0;R;;;;;N;;;;; +10A74;OLD SOUTH ARABIAN LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10A75;OLD SOUTH ARABIAN LETTER DALETH;Lo;0;R;;;;;N;;;;; +10A76;OLD SOUTH ARABIAN LETTER GHAYN;Lo;0;R;;;;;N;;;;; +10A77;OLD SOUTH ARABIAN LETTER TETH;Lo;0;R;;;;;N;;;;; +10A78;OLD SOUTH ARABIAN LETTER ZAYN;Lo;0;R;;;;;N;;;;; +10A79;OLD SOUTH ARABIAN LETTER DHALETH;Lo;0;R;;;;;N;;;;; +10A7A;OLD SOUTH ARABIAN LETTER YODH;Lo;0;R;;;;;N;;;;; +10A7B;OLD SOUTH ARABIAN LETTER THAW;Lo;0;R;;;;;N;;;;; +10A7C;OLD SOUTH ARABIAN LETTER THETH;Lo;0;R;;;;;N;;;;; +10A7D;OLD SOUTH ARABIAN NUMBER ONE;No;0;R;;;;1;N;;;;; +10A7E;OLD SOUTH ARABIAN NUMBER FIFTY;No;0;R;;;;50;N;;;;; +10A7F;OLD SOUTH ARABIAN NUMERIC INDICATOR;Po;0;R;;;;;N;;;;; +10A80;OLD NORTH ARABIAN LETTER HEH;Lo;0;R;;;;;N;;;;; +10A81;OLD NORTH ARABIAN LETTER LAM;Lo;0;R;;;;;N;;;;; +10A82;OLD NORTH ARABIAN LETTER HAH;Lo;0;R;;;;;N;;;;; +10A83;OLD NORTH ARABIAN LETTER MEEM;Lo;0;R;;;;;N;;;;; +10A84;OLD NORTH ARABIAN LETTER QAF;Lo;0;R;;;;;N;;;;; +10A85;OLD NORTH ARABIAN LETTER WAW;Lo;0;R;;;;;N;;;;; +10A86;OLD NORTH ARABIAN LETTER ES-2;Lo;0;R;;;;;N;;;;; +10A87;OLD NORTH ARABIAN LETTER REH;Lo;0;R;;;;;N;;;;; +10A88;OLD NORTH ARABIAN LETTER BEH;Lo;0;R;;;;;N;;;;; +10A89;OLD NORTH ARABIAN LETTER TEH;Lo;0;R;;;;;N;;;;; +10A8A;OLD NORTH ARABIAN LETTER ES-1;Lo;0;R;;;;;N;;;;; +10A8B;OLD NORTH ARABIAN LETTER KAF;Lo;0;R;;;;;N;;;;; +10A8C;OLD NORTH ARABIAN LETTER NOON;Lo;0;R;;;;;N;;;;; +10A8D;OLD NORTH ARABIAN LETTER KHAH;Lo;0;R;;;;;N;;;;; +10A8E;OLD NORTH ARABIAN LETTER SAD;Lo;0;R;;;;;N;;;;; +10A8F;OLD NORTH ARABIAN LETTER ES-3;Lo;0;R;;;;;N;;;;; +10A90;OLD NORTH ARABIAN LETTER FEH;Lo;0;R;;;;;N;;;;; +10A91;OLD NORTH ARABIAN LETTER ALEF;Lo;0;R;;;;;N;;;;; +10A92;OLD NORTH ARABIAN LETTER AIN;Lo;0;R;;;;;N;;;;; +10A93;OLD NORTH ARABIAN LETTER DAD;Lo;0;R;;;;;N;;;;; +10A94;OLD NORTH ARABIAN LETTER GEEM;Lo;0;R;;;;;N;;;;; +10A95;OLD NORTH ARABIAN LETTER DAL;Lo;0;R;;;;;N;;;;; +10A96;OLD NORTH ARABIAN LETTER GHAIN;Lo;0;R;;;;;N;;;;; +10A97;OLD NORTH ARABIAN LETTER TAH;Lo;0;R;;;;;N;;;;; +10A98;OLD NORTH ARABIAN LETTER ZAIN;Lo;0;R;;;;;N;;;;; +10A99;OLD NORTH ARABIAN LETTER THAL;Lo;0;R;;;;;N;;;;; +10A9A;OLD NORTH ARABIAN LETTER YEH;Lo;0;R;;;;;N;;;;; +10A9B;OLD NORTH ARABIAN LETTER THEH;Lo;0;R;;;;;N;;;;; +10A9C;OLD NORTH ARABIAN LETTER ZAH;Lo;0;R;;;;;N;;;;; +10A9D;OLD NORTH ARABIAN NUMBER ONE;No;0;R;;;;1;N;;;;; +10A9E;OLD NORTH ARABIAN NUMBER TEN;No;0;R;;;;10;N;;;;; +10A9F;OLD NORTH ARABIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10AC0;MANICHAEAN LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10AC1;MANICHAEAN LETTER BETH;Lo;0;R;;;;;N;;;;; +10AC2;MANICHAEAN LETTER BHETH;Lo;0;R;;;;;N;;;;; +10AC3;MANICHAEAN LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10AC4;MANICHAEAN LETTER GHIMEL;Lo;0;R;;;;;N;;;;; +10AC5;MANICHAEAN LETTER DALETH;Lo;0;R;;;;;N;;;;; +10AC6;MANICHAEAN LETTER HE;Lo;0;R;;;;;N;;;;; +10AC7;MANICHAEAN LETTER WAW;Lo;0;R;;;;;N;;;;; +10AC8;MANICHAEAN SIGN UD;So;0;R;;;;;N;;;;; +10AC9;MANICHAEAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10ACA;MANICHAEAN LETTER ZHAYIN;Lo;0;R;;;;;N;;;;; +10ACB;MANICHAEAN LETTER JAYIN;Lo;0;R;;;;;N;;;;; +10ACC;MANICHAEAN LETTER JHAYIN;Lo;0;R;;;;;N;;;;; +10ACD;MANICHAEAN LETTER HETH;Lo;0;R;;;;;N;;;;; +10ACE;MANICHAEAN LETTER TETH;Lo;0;R;;;;;N;;;;; +10ACF;MANICHAEAN LETTER YODH;Lo;0;R;;;;;N;;;;; +10AD0;MANICHAEAN LETTER KAPH;Lo;0;R;;;;;N;;;;; +10AD1;MANICHAEAN LETTER XAPH;Lo;0;R;;;;;N;;;;; +10AD2;MANICHAEAN LETTER KHAPH;Lo;0;R;;;;;N;;;;; +10AD3;MANICHAEAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10AD4;MANICHAEAN LETTER DHAMEDH;Lo;0;R;;;;;N;;;;; +10AD5;MANICHAEAN LETTER THAMEDH;Lo;0;R;;;;;N;;;;; +10AD6;MANICHAEAN LETTER MEM;Lo;0;R;;;;;N;;;;; +10AD7;MANICHAEAN LETTER NUN;Lo;0;R;;;;;N;;;;; +10AD8;MANICHAEAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10AD9;MANICHAEAN LETTER AYIN;Lo;0;R;;;;;N;;;;; +10ADA;MANICHAEAN LETTER AAYIN;Lo;0;R;;;;;N;;;;; +10ADB;MANICHAEAN LETTER PE;Lo;0;R;;;;;N;;;;; +10ADC;MANICHAEAN LETTER FE;Lo;0;R;;;;;N;;;;; +10ADD;MANICHAEAN LETTER SADHE;Lo;0;R;;;;;N;;;;; +10ADE;MANICHAEAN LETTER QOPH;Lo;0;R;;;;;N;;;;; +10ADF;MANICHAEAN LETTER XOPH;Lo;0;R;;;;;N;;;;; +10AE0;MANICHAEAN LETTER QHOPH;Lo;0;R;;;;;N;;;;; +10AE1;MANICHAEAN LETTER RESH;Lo;0;R;;;;;N;;;;; +10AE2;MANICHAEAN LETTER SHIN;Lo;0;R;;;;;N;;;;; +10AE3;MANICHAEAN LETTER SSHIN;Lo;0;R;;;;;N;;;;; +10AE4;MANICHAEAN LETTER TAW;Lo;0;R;;;;;N;;;;; +10AE5;MANICHAEAN ABBREVIATION MARK ABOVE;Mn;230;NSM;;;;;N;;;;; +10AE6;MANICHAEAN ABBREVIATION MARK BELOW;Mn;220;NSM;;;;;N;;;;; +10AEB;MANICHAEAN NUMBER ONE;No;0;R;;;;1;N;;;;; +10AEC;MANICHAEAN NUMBER FIVE;No;0;R;;;;5;N;;;;; +10AED;MANICHAEAN NUMBER TEN;No;0;R;;;;10;N;;;;; +10AEE;MANICHAEAN NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10AEF;MANICHAEAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +10AF0;MANICHAEAN PUNCTUATION STAR;Po;0;R;;;;;N;;;;; +10AF1;MANICHAEAN PUNCTUATION FLEURON;Po;0;R;;;;;N;;;;; +10AF2;MANICHAEAN PUNCTUATION DOUBLE DOT WITHIN DOT;Po;0;R;;;;;N;;;;; +10AF3;MANICHAEAN PUNCTUATION DOT WITHIN DOT;Po;0;R;;;;;N;;;;; +10AF4;MANICHAEAN PUNCTUATION DOT;Po;0;R;;;;;N;;;;; +10AF5;MANICHAEAN PUNCTUATION TWO DOTS;Po;0;R;;;;;N;;;;; +10AF6;MANICHAEAN PUNCTUATION LINE FILLER;Po;0;R;;;;;N;;;;; +10B00;AVESTAN LETTER A;Lo;0;R;;;;;N;;;;; +10B01;AVESTAN LETTER AA;Lo;0;R;;;;;N;;;;; +10B02;AVESTAN LETTER AO;Lo;0;R;;;;;N;;;;; +10B03;AVESTAN LETTER AAO;Lo;0;R;;;;;N;;;;; +10B04;AVESTAN LETTER AN;Lo;0;R;;;;;N;;;;; +10B05;AVESTAN LETTER AAN;Lo;0;R;;;;;N;;;;; +10B06;AVESTAN LETTER AE;Lo;0;R;;;;;N;;;;; +10B07;AVESTAN LETTER AEE;Lo;0;R;;;;;N;;;;; +10B08;AVESTAN LETTER E;Lo;0;R;;;;;N;;;;; +10B09;AVESTAN LETTER EE;Lo;0;R;;;;;N;;;;; +10B0A;AVESTAN LETTER O;Lo;0;R;;;;;N;;;;; +10B0B;AVESTAN LETTER OO;Lo;0;R;;;;;N;;;;; +10B0C;AVESTAN LETTER I;Lo;0;R;;;;;N;;;;; +10B0D;AVESTAN LETTER II;Lo;0;R;;;;;N;;;;; +10B0E;AVESTAN LETTER U;Lo;0;R;;;;;N;;;;; +10B0F;AVESTAN LETTER UU;Lo;0;R;;;;;N;;;;; +10B10;AVESTAN LETTER KE;Lo;0;R;;;;;N;;;;; +10B11;AVESTAN LETTER XE;Lo;0;R;;;;;N;;;;; +10B12;AVESTAN LETTER XYE;Lo;0;R;;;;;N;;;;; +10B13;AVESTAN LETTER XVE;Lo;0;R;;;;;N;;;;; +10B14;AVESTAN LETTER GE;Lo;0;R;;;;;N;;;;; +10B15;AVESTAN LETTER GGE;Lo;0;R;;;;;N;;;;; +10B16;AVESTAN LETTER GHE;Lo;0;R;;;;;N;;;;; +10B17;AVESTAN LETTER CE;Lo;0;R;;;;;N;;;;; +10B18;AVESTAN LETTER JE;Lo;0;R;;;;;N;;;;; +10B19;AVESTAN LETTER TE;Lo;0;R;;;;;N;;;;; +10B1A;AVESTAN LETTER THE;Lo;0;R;;;;;N;;;;; +10B1B;AVESTAN LETTER DE;Lo;0;R;;;;;N;;;;; +10B1C;AVESTAN LETTER DHE;Lo;0;R;;;;;N;;;;; +10B1D;AVESTAN LETTER TTE;Lo;0;R;;;;;N;;;;; +10B1E;AVESTAN LETTER PE;Lo;0;R;;;;;N;;;;; +10B1F;AVESTAN LETTER FE;Lo;0;R;;;;;N;;;;; +10B20;AVESTAN LETTER BE;Lo;0;R;;;;;N;;;;; +10B21;AVESTAN LETTER BHE;Lo;0;R;;;;;N;;;;; +10B22;AVESTAN LETTER NGE;Lo;0;R;;;;;N;;;;; +10B23;AVESTAN LETTER NGYE;Lo;0;R;;;;;N;;;;; +10B24;AVESTAN LETTER NGVE;Lo;0;R;;;;;N;;;;; +10B25;AVESTAN LETTER NE;Lo;0;R;;;;;N;;;;; +10B26;AVESTAN LETTER NYE;Lo;0;R;;;;;N;;;;; +10B27;AVESTAN LETTER NNE;Lo;0;R;;;;;N;;;;; +10B28;AVESTAN LETTER ME;Lo;0;R;;;;;N;;;;; +10B29;AVESTAN LETTER HME;Lo;0;R;;;;;N;;;;; +10B2A;AVESTAN LETTER YYE;Lo;0;R;;;;;N;;;;; +10B2B;AVESTAN LETTER YE;Lo;0;R;;;;;N;;;;; +10B2C;AVESTAN LETTER VE;Lo;0;R;;;;;N;;;;; +10B2D;AVESTAN LETTER RE;Lo;0;R;;;;;N;;;;; +10B2E;AVESTAN LETTER LE;Lo;0;R;;;;;N;;;;; +10B2F;AVESTAN LETTER SE;Lo;0;R;;;;;N;;;;; +10B30;AVESTAN LETTER ZE;Lo;0;R;;;;;N;;;;; +10B31;AVESTAN LETTER SHE;Lo;0;R;;;;;N;;;;; +10B32;AVESTAN LETTER ZHE;Lo;0;R;;;;;N;;;;; +10B33;AVESTAN LETTER SHYE;Lo;0;R;;;;;N;;;;; +10B34;AVESTAN LETTER SSHE;Lo;0;R;;;;;N;;;;; +10B35;AVESTAN LETTER HE;Lo;0;R;;;;;N;;;;; +10B39;AVESTAN ABBREVIATION MARK;Po;0;ON;;;;;N;;;;; +10B3A;TINY TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B3B;SMALL TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B3C;LARGE TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B3D;LARGE ONE DOT OVER TWO DOTS PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B3E;LARGE TWO RINGS OVER ONE RING PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B3F;LARGE ONE RING OVER TWO RINGS PUNCTUATION;Po;0;ON;;;;;N;;;;; +10B40;INSCRIPTIONAL PARTHIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10B41;INSCRIPTIONAL PARTHIAN LETTER BETH;Lo;0;R;;;;;N;;;;; +10B42;INSCRIPTIONAL PARTHIAN LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10B43;INSCRIPTIONAL PARTHIAN LETTER DALETH;Lo;0;R;;;;;N;;;;; +10B44;INSCRIPTIONAL PARTHIAN LETTER HE;Lo;0;R;;;;;N;;;;; +10B45;INSCRIPTIONAL PARTHIAN LETTER WAW;Lo;0;R;;;;;N;;;;; +10B46;INSCRIPTIONAL PARTHIAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10B47;INSCRIPTIONAL PARTHIAN LETTER HETH;Lo;0;R;;;;;N;;;;; +10B48;INSCRIPTIONAL PARTHIAN LETTER TETH;Lo;0;R;;;;;N;;;;; +10B49;INSCRIPTIONAL PARTHIAN LETTER YODH;Lo;0;R;;;;;N;;;;; +10B4A;INSCRIPTIONAL PARTHIAN LETTER KAPH;Lo;0;R;;;;;N;;;;; +10B4B;INSCRIPTIONAL PARTHIAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10B4C;INSCRIPTIONAL PARTHIAN LETTER MEM;Lo;0;R;;;;;N;;;;; +10B4D;INSCRIPTIONAL PARTHIAN LETTER NUN;Lo;0;R;;;;;N;;;;; +10B4E;INSCRIPTIONAL PARTHIAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10B4F;INSCRIPTIONAL PARTHIAN LETTER AYIN;Lo;0;R;;;;;N;;;;; +10B50;INSCRIPTIONAL PARTHIAN LETTER PE;Lo;0;R;;;;;N;;;;; +10B51;INSCRIPTIONAL PARTHIAN LETTER SADHE;Lo;0;R;;;;;N;;;;; +10B52;INSCRIPTIONAL PARTHIAN LETTER QOPH;Lo;0;R;;;;;N;;;;; +10B53;INSCRIPTIONAL PARTHIAN LETTER RESH;Lo;0;R;;;;;N;;;;; +10B54;INSCRIPTIONAL PARTHIAN LETTER SHIN;Lo;0;R;;;;;N;;;;; +10B55;INSCRIPTIONAL PARTHIAN LETTER TAW;Lo;0;R;;;;;N;;;;; +10B58;INSCRIPTIONAL PARTHIAN NUMBER ONE;No;0;R;;;;1;N;;;;; +10B59;INSCRIPTIONAL PARTHIAN NUMBER TWO;No;0;R;;;;2;N;;;;; +10B5A;INSCRIPTIONAL PARTHIAN NUMBER THREE;No;0;R;;;;3;N;;;;; +10B5B;INSCRIPTIONAL PARTHIAN NUMBER FOUR;No;0;R;;;;4;N;;;;; +10B5C;INSCRIPTIONAL PARTHIAN NUMBER TEN;No;0;R;;;;10;N;;;;; +10B5D;INSCRIPTIONAL PARTHIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10B5E;INSCRIPTIONAL PARTHIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +10B5F;INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;; +10B60;INSCRIPTIONAL PAHLAVI LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10B61;INSCRIPTIONAL PAHLAVI LETTER BETH;Lo;0;R;;;;;N;;;;; +10B62;INSCRIPTIONAL PAHLAVI LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10B63;INSCRIPTIONAL PAHLAVI LETTER DALETH;Lo;0;R;;;;;N;;;;; +10B64;INSCRIPTIONAL PAHLAVI LETTER HE;Lo;0;R;;;;;N;;;;; +10B65;INSCRIPTIONAL PAHLAVI LETTER WAW-AYIN-RESH;Lo;0;R;;;;;N;;;;; +10B66;INSCRIPTIONAL PAHLAVI LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10B67;INSCRIPTIONAL PAHLAVI LETTER HETH;Lo;0;R;;;;;N;;;;; +10B68;INSCRIPTIONAL PAHLAVI LETTER TETH;Lo;0;R;;;;;N;;;;; +10B69;INSCRIPTIONAL PAHLAVI LETTER YODH;Lo;0;R;;;;;N;;;;; +10B6A;INSCRIPTIONAL PAHLAVI LETTER KAPH;Lo;0;R;;;;;N;;;;; +10B6B;INSCRIPTIONAL PAHLAVI LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10B6C;INSCRIPTIONAL PAHLAVI LETTER MEM-QOPH;Lo;0;R;;;;;N;;;;; +10B6D;INSCRIPTIONAL PAHLAVI LETTER NUN;Lo;0;R;;;;;N;;;;; +10B6E;INSCRIPTIONAL PAHLAVI LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10B6F;INSCRIPTIONAL PAHLAVI LETTER PE;Lo;0;R;;;;;N;;;;; +10B70;INSCRIPTIONAL PAHLAVI LETTER SADHE;Lo;0;R;;;;;N;;;;; +10B71;INSCRIPTIONAL PAHLAVI LETTER SHIN;Lo;0;R;;;;;N;;;;; +10B72;INSCRIPTIONAL PAHLAVI LETTER TAW;Lo;0;R;;;;;N;;;;; +10B78;INSCRIPTIONAL PAHLAVI NUMBER ONE;No;0;R;;;;1;N;;;;; +10B79;INSCRIPTIONAL PAHLAVI NUMBER TWO;No;0;R;;;;2;N;;;;; +10B7A;INSCRIPTIONAL PAHLAVI NUMBER THREE;No;0;R;;;;3;N;;;;; +10B7B;INSCRIPTIONAL PAHLAVI NUMBER FOUR;No;0;R;;;;4;N;;;;; +10B7C;INSCRIPTIONAL PAHLAVI NUMBER TEN;No;0;R;;;;10;N;;;;; +10B7D;INSCRIPTIONAL PAHLAVI NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10B7E;INSCRIPTIONAL PAHLAVI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +10B7F;INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;; +10B80;PSALTER PAHLAVI LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10B81;PSALTER PAHLAVI LETTER BETH;Lo;0;R;;;;;N;;;;; +10B82;PSALTER PAHLAVI LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10B83;PSALTER PAHLAVI LETTER DALETH;Lo;0;R;;;;;N;;;;; +10B84;PSALTER PAHLAVI LETTER HE;Lo;0;R;;;;;N;;;;; +10B85;PSALTER PAHLAVI LETTER WAW-AYIN-RESH;Lo;0;R;;;;;N;;;;; +10B86;PSALTER PAHLAVI LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10B87;PSALTER PAHLAVI LETTER HETH;Lo;0;R;;;;;N;;;;; +10B88;PSALTER PAHLAVI LETTER YODH;Lo;0;R;;;;;N;;;;; +10B89;PSALTER PAHLAVI LETTER KAPH;Lo;0;R;;;;;N;;;;; +10B8A;PSALTER PAHLAVI LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10B8B;PSALTER PAHLAVI LETTER MEM-QOPH;Lo;0;R;;;;;N;;;;; +10B8C;PSALTER PAHLAVI LETTER NUN;Lo;0;R;;;;;N;;;;; +10B8D;PSALTER PAHLAVI LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10B8E;PSALTER PAHLAVI LETTER PE;Lo;0;R;;;;;N;;;;; +10B8F;PSALTER PAHLAVI LETTER SADHE;Lo;0;R;;;;;N;;;;; +10B90;PSALTER PAHLAVI LETTER SHIN;Lo;0;R;;;;;N;;;;; +10B91;PSALTER PAHLAVI LETTER TAW;Lo;0;R;;;;;N;;;;; +10B99;PSALTER PAHLAVI SECTION MARK;Po;0;R;;;;;N;;;;; +10B9A;PSALTER PAHLAVI TURNED SECTION MARK;Po;0;R;;;;;N;;;;; +10B9B;PSALTER PAHLAVI FOUR DOTS WITH CROSS;Po;0;R;;;;;N;;;;; +10B9C;PSALTER PAHLAVI FOUR DOTS WITH DOT;Po;0;R;;;;;N;;;;; +10BA9;PSALTER PAHLAVI NUMBER ONE;No;0;R;;;;1;N;;;;; +10BAA;PSALTER PAHLAVI NUMBER TWO;No;0;R;;;;2;N;;;;; +10BAB;PSALTER PAHLAVI NUMBER THREE;No;0;R;;;;3;N;;;;; +10BAC;PSALTER PAHLAVI NUMBER FOUR;No;0;R;;;;4;N;;;;; +10BAD;PSALTER PAHLAVI NUMBER TEN;No;0;R;;;;10;N;;;;; +10BAE;PSALTER PAHLAVI NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10BAF;PSALTER PAHLAVI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +10C00;OLD TURKIC LETTER ORKHON A;Lo;0;R;;;;;N;;;;; +10C01;OLD TURKIC LETTER YENISEI A;Lo;0;R;;;;;N;;;;; +10C02;OLD TURKIC LETTER YENISEI AE;Lo;0;R;;;;;N;;;;; +10C03;OLD TURKIC LETTER ORKHON I;Lo;0;R;;;;;N;;;;; +10C04;OLD TURKIC LETTER YENISEI I;Lo;0;R;;;;;N;;;;; +10C05;OLD TURKIC LETTER YENISEI E;Lo;0;R;;;;;N;;;;; +10C06;OLD TURKIC LETTER ORKHON O;Lo;0;R;;;;;N;;;;; +10C07;OLD TURKIC LETTER ORKHON OE;Lo;0;R;;;;;N;;;;; +10C08;OLD TURKIC LETTER YENISEI OE;Lo;0;R;;;;;N;;;;; +10C09;OLD TURKIC LETTER ORKHON AB;Lo;0;R;;;;;N;;;;; +10C0A;OLD TURKIC LETTER YENISEI AB;Lo;0;R;;;;;N;;;;; +10C0B;OLD TURKIC LETTER ORKHON AEB;Lo;0;R;;;;;N;;;;; +10C0C;OLD TURKIC LETTER YENISEI AEB;Lo;0;R;;;;;N;;;;; +10C0D;OLD TURKIC LETTER ORKHON AG;Lo;0;R;;;;;N;;;;; +10C0E;OLD TURKIC LETTER YENISEI AG;Lo;0;R;;;;;N;;;;; +10C0F;OLD TURKIC LETTER ORKHON AEG;Lo;0;R;;;;;N;;;;; +10C10;OLD TURKIC LETTER YENISEI AEG;Lo;0;R;;;;;N;;;;; +10C11;OLD TURKIC LETTER ORKHON AD;Lo;0;R;;;;;N;;;;; +10C12;OLD TURKIC LETTER YENISEI AD;Lo;0;R;;;;;N;;;;; +10C13;OLD TURKIC LETTER ORKHON AED;Lo;0;R;;;;;N;;;;; +10C14;OLD TURKIC LETTER ORKHON EZ;Lo;0;R;;;;;N;;;;; +10C15;OLD TURKIC LETTER YENISEI EZ;Lo;0;R;;;;;N;;;;; +10C16;OLD TURKIC LETTER ORKHON AY;Lo;0;R;;;;;N;;;;; +10C17;OLD TURKIC LETTER YENISEI AY;Lo;0;R;;;;;N;;;;; +10C18;OLD TURKIC LETTER ORKHON AEY;Lo;0;R;;;;;N;;;;; +10C19;OLD TURKIC LETTER YENISEI AEY;Lo;0;R;;;;;N;;;;; +10C1A;OLD TURKIC LETTER ORKHON AEK;Lo;0;R;;;;;N;;;;; +10C1B;OLD TURKIC LETTER YENISEI AEK;Lo;0;R;;;;;N;;;;; +10C1C;OLD TURKIC LETTER ORKHON OEK;Lo;0;R;;;;;N;;;;; +10C1D;OLD TURKIC LETTER YENISEI OEK;Lo;0;R;;;;;N;;;;; +10C1E;OLD TURKIC LETTER ORKHON AL;Lo;0;R;;;;;N;;;;; +10C1F;OLD TURKIC LETTER YENISEI AL;Lo;0;R;;;;;N;;;;; +10C20;OLD TURKIC LETTER ORKHON AEL;Lo;0;R;;;;;N;;;;; +10C21;OLD TURKIC LETTER ORKHON ELT;Lo;0;R;;;;;N;;;;; +10C22;OLD TURKIC LETTER ORKHON EM;Lo;0;R;;;;;N;;;;; +10C23;OLD TURKIC LETTER ORKHON AN;Lo;0;R;;;;;N;;;;; +10C24;OLD TURKIC LETTER ORKHON AEN;Lo;0;R;;;;;N;;;;; +10C25;OLD TURKIC LETTER YENISEI AEN;Lo;0;R;;;;;N;;;;; +10C26;OLD TURKIC LETTER ORKHON ENT;Lo;0;R;;;;;N;;;;; +10C27;OLD TURKIC LETTER YENISEI ENT;Lo;0;R;;;;;N;;;;; +10C28;OLD TURKIC LETTER ORKHON ENC;Lo;0;R;;;;;N;;;;; +10C29;OLD TURKIC LETTER YENISEI ENC;Lo;0;R;;;;;N;;;;; +10C2A;OLD TURKIC LETTER ORKHON ENY;Lo;0;R;;;;;N;;;;; +10C2B;OLD TURKIC LETTER YENISEI ENY;Lo;0;R;;;;;N;;;;; +10C2C;OLD TURKIC LETTER YENISEI ANG;Lo;0;R;;;;;N;;;;; +10C2D;OLD TURKIC LETTER ORKHON ENG;Lo;0;R;;;;;N;;;;; +10C2E;OLD TURKIC LETTER YENISEI AENG;Lo;0;R;;;;;N;;;;; +10C2F;OLD TURKIC LETTER ORKHON EP;Lo;0;R;;;;;N;;;;; +10C30;OLD TURKIC LETTER ORKHON OP;Lo;0;R;;;;;N;;;;; +10C31;OLD TURKIC LETTER ORKHON IC;Lo;0;R;;;;;N;;;;; +10C32;OLD TURKIC LETTER ORKHON EC;Lo;0;R;;;;;N;;;;; +10C33;OLD TURKIC LETTER YENISEI EC;Lo;0;R;;;;;N;;;;; +10C34;OLD TURKIC LETTER ORKHON AQ;Lo;0;R;;;;;N;;;;; +10C35;OLD TURKIC LETTER YENISEI AQ;Lo;0;R;;;;;N;;;;; +10C36;OLD TURKIC LETTER ORKHON IQ;Lo;0;R;;;;;N;;;;; +10C37;OLD TURKIC LETTER YENISEI IQ;Lo;0;R;;;;;N;;;;; +10C38;OLD TURKIC LETTER ORKHON OQ;Lo;0;R;;;;;N;;;;; +10C39;OLD TURKIC LETTER YENISEI OQ;Lo;0;R;;;;;N;;;;; +10C3A;OLD TURKIC LETTER ORKHON AR;Lo;0;R;;;;;N;;;;; +10C3B;OLD TURKIC LETTER YENISEI AR;Lo;0;R;;;;;N;;;;; +10C3C;OLD TURKIC LETTER ORKHON AER;Lo;0;R;;;;;N;;;;; +10C3D;OLD TURKIC LETTER ORKHON AS;Lo;0;R;;;;;N;;;;; +10C3E;OLD TURKIC LETTER ORKHON AES;Lo;0;R;;;;;N;;;;; +10C3F;OLD TURKIC LETTER ORKHON ASH;Lo;0;R;;;;;N;;;;; +10C40;OLD TURKIC LETTER YENISEI ASH;Lo;0;R;;;;;N;;;;; +10C41;OLD TURKIC LETTER ORKHON ESH;Lo;0;R;;;;;N;;;;; +10C42;OLD TURKIC LETTER YENISEI ESH;Lo;0;R;;;;;N;;;;; +10C43;OLD TURKIC LETTER ORKHON AT;Lo;0;R;;;;;N;;;;; +10C44;OLD TURKIC LETTER YENISEI AT;Lo;0;R;;;;;N;;;;; +10C45;OLD TURKIC LETTER ORKHON AET;Lo;0;R;;;;;N;;;;; +10C46;OLD TURKIC LETTER YENISEI AET;Lo;0;R;;;;;N;;;;; +10C47;OLD TURKIC LETTER ORKHON OT;Lo;0;R;;;;;N;;;;; +10C48;OLD TURKIC LETTER ORKHON BASH;Lo;0;R;;;;;N;;;;; +10C80;OLD HUNGARIAN CAPITAL LETTER A;Lu;0;R;;;;;N;;;;10CC0; +10C81;OLD HUNGARIAN CAPITAL LETTER AA;Lu;0;R;;;;;N;;;;10CC1; +10C82;OLD HUNGARIAN CAPITAL LETTER EB;Lu;0;R;;;;;N;;;;10CC2; +10C83;OLD HUNGARIAN CAPITAL LETTER AMB;Lu;0;R;;;;;N;;;;10CC3; +10C84;OLD HUNGARIAN CAPITAL LETTER EC;Lu;0;R;;;;;N;;;;10CC4; +10C85;OLD HUNGARIAN CAPITAL LETTER ENC;Lu;0;R;;;;;N;;;;10CC5; +10C86;OLD HUNGARIAN CAPITAL LETTER ECS;Lu;0;R;;;;;N;;;;10CC6; +10C87;OLD HUNGARIAN CAPITAL LETTER ED;Lu;0;R;;;;;N;;;;10CC7; +10C88;OLD HUNGARIAN CAPITAL LETTER AND;Lu;0;R;;;;;N;;;;10CC8; +10C89;OLD HUNGARIAN CAPITAL LETTER E;Lu;0;R;;;;;N;;;;10CC9; +10C8A;OLD HUNGARIAN CAPITAL LETTER CLOSE E;Lu;0;R;;;;;N;;;;10CCA; +10C8B;OLD HUNGARIAN CAPITAL LETTER EE;Lu;0;R;;;;;N;;;;10CCB; +10C8C;OLD HUNGARIAN CAPITAL LETTER EF;Lu;0;R;;;;;N;;;;10CCC; +10C8D;OLD HUNGARIAN CAPITAL LETTER EG;Lu;0;R;;;;;N;;;;10CCD; +10C8E;OLD HUNGARIAN CAPITAL LETTER EGY;Lu;0;R;;;;;N;;;;10CCE; +10C8F;OLD HUNGARIAN CAPITAL LETTER EH;Lu;0;R;;;;;N;;;;10CCF; +10C90;OLD HUNGARIAN CAPITAL LETTER I;Lu;0;R;;;;;N;;;;10CD0; +10C91;OLD HUNGARIAN CAPITAL LETTER II;Lu;0;R;;;;;N;;;;10CD1; +10C92;OLD HUNGARIAN CAPITAL LETTER EJ;Lu;0;R;;;;;N;;;;10CD2; +10C93;OLD HUNGARIAN CAPITAL LETTER EK;Lu;0;R;;;;;N;;;;10CD3; +10C94;OLD HUNGARIAN CAPITAL LETTER AK;Lu;0;R;;;;;N;;;;10CD4; +10C95;OLD HUNGARIAN CAPITAL LETTER UNK;Lu;0;R;;;;;N;;;;10CD5; +10C96;OLD HUNGARIAN CAPITAL LETTER EL;Lu;0;R;;;;;N;;;;10CD6; +10C97;OLD HUNGARIAN CAPITAL LETTER ELY;Lu;0;R;;;;;N;;;;10CD7; +10C98;OLD HUNGARIAN CAPITAL LETTER EM;Lu;0;R;;;;;N;;;;10CD8; +10C99;OLD HUNGARIAN CAPITAL LETTER EN;Lu;0;R;;;;;N;;;;10CD9; +10C9A;OLD HUNGARIAN CAPITAL LETTER ENY;Lu;0;R;;;;;N;;;;10CDA; +10C9B;OLD HUNGARIAN CAPITAL LETTER O;Lu;0;R;;;;;N;;;;10CDB; +10C9C;OLD HUNGARIAN CAPITAL LETTER OO;Lu;0;R;;;;;N;;;;10CDC; +10C9D;OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE;Lu;0;R;;;;;N;;;;10CDD; +10C9E;OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE;Lu;0;R;;;;;N;;;;10CDE; +10C9F;OLD HUNGARIAN CAPITAL LETTER OEE;Lu;0;R;;;;;N;;;;10CDF; +10CA0;OLD HUNGARIAN CAPITAL LETTER EP;Lu;0;R;;;;;N;;;;10CE0; +10CA1;OLD HUNGARIAN CAPITAL LETTER EMP;Lu;0;R;;;;;N;;;;10CE1; +10CA2;OLD HUNGARIAN CAPITAL LETTER ER;Lu;0;R;;;;;N;;;;10CE2; +10CA3;OLD HUNGARIAN CAPITAL LETTER SHORT ER;Lu;0;R;;;;;N;;;;10CE3; +10CA4;OLD HUNGARIAN CAPITAL LETTER ES;Lu;0;R;;;;;N;;;;10CE4; +10CA5;OLD HUNGARIAN CAPITAL LETTER ESZ;Lu;0;R;;;;;N;;;;10CE5; +10CA6;OLD HUNGARIAN CAPITAL LETTER ET;Lu;0;R;;;;;N;;;;10CE6; +10CA7;OLD HUNGARIAN CAPITAL LETTER ENT;Lu;0;R;;;;;N;;;;10CE7; +10CA8;OLD HUNGARIAN CAPITAL LETTER ETY;Lu;0;R;;;;;N;;;;10CE8; +10CA9;OLD HUNGARIAN CAPITAL LETTER ECH;Lu;0;R;;;;;N;;;;10CE9; +10CAA;OLD HUNGARIAN CAPITAL LETTER U;Lu;0;R;;;;;N;;;;10CEA; +10CAB;OLD HUNGARIAN CAPITAL LETTER UU;Lu;0;R;;;;;N;;;;10CEB; +10CAC;OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE;Lu;0;R;;;;;N;;;;10CEC; +10CAD;OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE;Lu;0;R;;;;;N;;;;10CED; +10CAE;OLD HUNGARIAN CAPITAL LETTER EV;Lu;0;R;;;;;N;;;;10CEE; +10CAF;OLD HUNGARIAN CAPITAL LETTER EZ;Lu;0;R;;;;;N;;;;10CEF; +10CB0;OLD HUNGARIAN CAPITAL LETTER EZS;Lu;0;R;;;;;N;;;;10CF0; +10CB1;OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN;Lu;0;R;;;;;N;;;;10CF1; +10CB2;OLD HUNGARIAN CAPITAL LETTER US;Lu;0;R;;;;;N;;;;10CF2; +10CC0;OLD HUNGARIAN SMALL LETTER A;Ll;0;R;;;;;N;;;10C80;;10C80 +10CC1;OLD HUNGARIAN SMALL LETTER AA;Ll;0;R;;;;;N;;;10C81;;10C81 +10CC2;OLD HUNGARIAN SMALL LETTER EB;Ll;0;R;;;;;N;;;10C82;;10C82 +10CC3;OLD HUNGARIAN SMALL LETTER AMB;Ll;0;R;;;;;N;;;10C83;;10C83 +10CC4;OLD HUNGARIAN SMALL LETTER EC;Ll;0;R;;;;;N;;;10C84;;10C84 +10CC5;OLD HUNGARIAN SMALL LETTER ENC;Ll;0;R;;;;;N;;;10C85;;10C85 +10CC6;OLD HUNGARIAN SMALL LETTER ECS;Ll;0;R;;;;;N;;;10C86;;10C86 +10CC7;OLD HUNGARIAN SMALL LETTER ED;Ll;0;R;;;;;N;;;10C87;;10C87 +10CC8;OLD HUNGARIAN SMALL LETTER AND;Ll;0;R;;;;;N;;;10C88;;10C88 +10CC9;OLD HUNGARIAN SMALL LETTER E;Ll;0;R;;;;;N;;;10C89;;10C89 +10CCA;OLD HUNGARIAN SMALL LETTER CLOSE E;Ll;0;R;;;;;N;;;10C8A;;10C8A +10CCB;OLD HUNGARIAN SMALL LETTER EE;Ll;0;R;;;;;N;;;10C8B;;10C8B +10CCC;OLD HUNGARIAN SMALL LETTER EF;Ll;0;R;;;;;N;;;10C8C;;10C8C +10CCD;OLD HUNGARIAN SMALL LETTER EG;Ll;0;R;;;;;N;;;10C8D;;10C8D +10CCE;OLD HUNGARIAN SMALL LETTER EGY;Ll;0;R;;;;;N;;;10C8E;;10C8E +10CCF;OLD HUNGARIAN SMALL LETTER EH;Ll;0;R;;;;;N;;;10C8F;;10C8F +10CD0;OLD HUNGARIAN SMALL LETTER I;Ll;0;R;;;;;N;;;10C90;;10C90 +10CD1;OLD HUNGARIAN SMALL LETTER II;Ll;0;R;;;;;N;;;10C91;;10C91 +10CD2;OLD HUNGARIAN SMALL LETTER EJ;Ll;0;R;;;;;N;;;10C92;;10C92 +10CD3;OLD HUNGARIAN SMALL LETTER EK;Ll;0;R;;;;;N;;;10C93;;10C93 +10CD4;OLD HUNGARIAN SMALL LETTER AK;Ll;0;R;;;;;N;;;10C94;;10C94 +10CD5;OLD HUNGARIAN SMALL LETTER UNK;Ll;0;R;;;;;N;;;10C95;;10C95 +10CD6;OLD HUNGARIAN SMALL LETTER EL;Ll;0;R;;;;;N;;;10C96;;10C96 +10CD7;OLD HUNGARIAN SMALL LETTER ELY;Ll;0;R;;;;;N;;;10C97;;10C97 +10CD8;OLD HUNGARIAN SMALL LETTER EM;Ll;0;R;;;;;N;;;10C98;;10C98 +10CD9;OLD HUNGARIAN SMALL LETTER EN;Ll;0;R;;;;;N;;;10C99;;10C99 +10CDA;OLD HUNGARIAN SMALL LETTER ENY;Ll;0;R;;;;;N;;;10C9A;;10C9A +10CDB;OLD HUNGARIAN SMALL LETTER O;Ll;0;R;;;;;N;;;10C9B;;10C9B +10CDC;OLD HUNGARIAN SMALL LETTER OO;Ll;0;R;;;;;N;;;10C9C;;10C9C +10CDD;OLD HUNGARIAN SMALL LETTER NIKOLSBURG OE;Ll;0;R;;;;;N;;;10C9D;;10C9D +10CDE;OLD HUNGARIAN SMALL LETTER RUDIMENTA OE;Ll;0;R;;;;;N;;;10C9E;;10C9E +10CDF;OLD HUNGARIAN SMALL LETTER OEE;Ll;0;R;;;;;N;;;10C9F;;10C9F +10CE0;OLD HUNGARIAN SMALL LETTER EP;Ll;0;R;;;;;N;;;10CA0;;10CA0 +10CE1;OLD HUNGARIAN SMALL LETTER EMP;Ll;0;R;;;;;N;;;10CA1;;10CA1 +10CE2;OLD HUNGARIAN SMALL LETTER ER;Ll;0;R;;;;;N;;;10CA2;;10CA2 +10CE3;OLD HUNGARIAN SMALL LETTER SHORT ER;Ll;0;R;;;;;N;;;10CA3;;10CA3 +10CE4;OLD HUNGARIAN SMALL LETTER ES;Ll;0;R;;;;;N;;;10CA4;;10CA4 +10CE5;OLD HUNGARIAN SMALL LETTER ESZ;Ll;0;R;;;;;N;;;10CA5;;10CA5 +10CE6;OLD HUNGARIAN SMALL LETTER ET;Ll;0;R;;;;;N;;;10CA6;;10CA6 +10CE7;OLD HUNGARIAN SMALL LETTER ENT;Ll;0;R;;;;;N;;;10CA7;;10CA7 +10CE8;OLD HUNGARIAN SMALL LETTER ETY;Ll;0;R;;;;;N;;;10CA8;;10CA8 +10CE9;OLD HUNGARIAN SMALL LETTER ECH;Ll;0;R;;;;;N;;;10CA9;;10CA9 +10CEA;OLD HUNGARIAN SMALL LETTER U;Ll;0;R;;;;;N;;;10CAA;;10CAA +10CEB;OLD HUNGARIAN SMALL LETTER UU;Ll;0;R;;;;;N;;;10CAB;;10CAB +10CEC;OLD HUNGARIAN SMALL LETTER NIKOLSBURG UE;Ll;0;R;;;;;N;;;10CAC;;10CAC +10CED;OLD HUNGARIAN SMALL LETTER RUDIMENTA UE;Ll;0;R;;;;;N;;;10CAD;;10CAD +10CEE;OLD HUNGARIAN SMALL LETTER EV;Ll;0;R;;;;;N;;;10CAE;;10CAE +10CEF;OLD HUNGARIAN SMALL LETTER EZ;Ll;0;R;;;;;N;;;10CAF;;10CAF +10CF0;OLD HUNGARIAN SMALL LETTER EZS;Ll;0;R;;;;;N;;;10CB0;;10CB0 +10CF1;OLD HUNGARIAN SMALL LETTER ENT-SHAPED SIGN;Ll;0;R;;;;;N;;;10CB1;;10CB1 +10CF2;OLD HUNGARIAN SMALL LETTER US;Ll;0;R;;;;;N;;;10CB2;;10CB2 +10CFA;OLD HUNGARIAN NUMBER ONE;No;0;R;;;;1;N;;;;; +10CFB;OLD HUNGARIAN NUMBER FIVE;No;0;R;;;;5;N;;;;; +10CFC;OLD HUNGARIAN NUMBER TEN;No;0;R;;;;10;N;;;;; +10CFD;OLD HUNGARIAN NUMBER FIFTY;No;0;R;;;;50;N;;;;; +10CFE;OLD HUNGARIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +10CFF;OLD HUNGARIAN NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;; +10D00;HANIFI ROHINGYA LETTER A;Lo;0;AL;;;;;N;;;;; +10D01;HANIFI ROHINGYA LETTER BA;Lo;0;AL;;;;;N;;;;; +10D02;HANIFI ROHINGYA LETTER PA;Lo;0;AL;;;;;N;;;;; +10D03;HANIFI ROHINGYA LETTER TA;Lo;0;AL;;;;;N;;;;; +10D04;HANIFI ROHINGYA LETTER TTA;Lo;0;AL;;;;;N;;;;; +10D05;HANIFI ROHINGYA LETTER JA;Lo;0;AL;;;;;N;;;;; +10D06;HANIFI ROHINGYA LETTER CA;Lo;0;AL;;;;;N;;;;; +10D07;HANIFI ROHINGYA LETTER HA;Lo;0;AL;;;;;N;;;;; +10D08;HANIFI ROHINGYA LETTER KHA;Lo;0;AL;;;;;N;;;;; +10D09;HANIFI ROHINGYA LETTER FA;Lo;0;AL;;;;;N;;;;; +10D0A;HANIFI ROHINGYA LETTER DA;Lo;0;AL;;;;;N;;;;; +10D0B;HANIFI ROHINGYA LETTER DDA;Lo;0;AL;;;;;N;;;;; +10D0C;HANIFI ROHINGYA LETTER RA;Lo;0;AL;;;;;N;;;;; +10D0D;HANIFI ROHINGYA LETTER RRA;Lo;0;AL;;;;;N;;;;; +10D0E;HANIFI ROHINGYA LETTER ZA;Lo;0;AL;;;;;N;;;;; +10D0F;HANIFI ROHINGYA LETTER SA;Lo;0;AL;;;;;N;;;;; +10D10;HANIFI ROHINGYA LETTER SHA;Lo;0;AL;;;;;N;;;;; +10D11;HANIFI ROHINGYA LETTER KA;Lo;0;AL;;;;;N;;;;; +10D12;HANIFI ROHINGYA LETTER GA;Lo;0;AL;;;;;N;;;;; +10D13;HANIFI ROHINGYA LETTER LA;Lo;0;AL;;;;;N;;;;; +10D14;HANIFI ROHINGYA LETTER MA;Lo;0;AL;;;;;N;;;;; +10D15;HANIFI ROHINGYA LETTER NA;Lo;0;AL;;;;;N;;;;; +10D16;HANIFI ROHINGYA LETTER WA;Lo;0;AL;;;;;N;;;;; +10D17;HANIFI ROHINGYA LETTER KINNA WA;Lo;0;AL;;;;;N;;;;; +10D18;HANIFI ROHINGYA LETTER YA;Lo;0;AL;;;;;N;;;;; +10D19;HANIFI ROHINGYA LETTER KINNA YA;Lo;0;AL;;;;;N;;;;; +10D1A;HANIFI ROHINGYA LETTER NGA;Lo;0;AL;;;;;N;;;;; +10D1B;HANIFI ROHINGYA LETTER NYA;Lo;0;AL;;;;;N;;;;; +10D1C;HANIFI ROHINGYA LETTER VA;Lo;0;AL;;;;;N;;;;; +10D1D;HANIFI ROHINGYA VOWEL A;Lo;0;AL;;;;;N;;;;; +10D1E;HANIFI ROHINGYA VOWEL I;Lo;0;AL;;;;;N;;;;; +10D1F;HANIFI ROHINGYA VOWEL U;Lo;0;AL;;;;;N;;;;; +10D20;HANIFI ROHINGYA VOWEL E;Lo;0;AL;;;;;N;;;;; +10D21;HANIFI ROHINGYA VOWEL O;Lo;0;AL;;;;;N;;;;; +10D22;HANIFI ROHINGYA MARK SAKIN;Lo;0;AL;;;;;N;;;;; +10D23;HANIFI ROHINGYA MARK NA KHONNA;Lo;0;AL;;;;;N;;;;; +10D24;HANIFI ROHINGYA SIGN HARBAHAY;Mn;230;NSM;;;;;N;;;;; +10D25;HANIFI ROHINGYA SIGN TAHALA;Mn;230;NSM;;;;;N;;;;; +10D26;HANIFI ROHINGYA SIGN TANA;Mn;230;NSM;;;;;N;;;;; +10D27;HANIFI ROHINGYA SIGN TASSI;Mn;230;NSM;;;;;N;;;;; +10D30;HANIFI ROHINGYA DIGIT ZERO;Nd;0;AN;;0;0;0;N;;;;; +10D31;HANIFI ROHINGYA DIGIT ONE;Nd;0;AN;;1;1;1;N;;;;; +10D32;HANIFI ROHINGYA DIGIT TWO;Nd;0;AN;;2;2;2;N;;;;; +10D33;HANIFI ROHINGYA DIGIT THREE;Nd;0;AN;;3;3;3;N;;;;; +10D34;HANIFI ROHINGYA DIGIT FOUR;Nd;0;AN;;4;4;4;N;;;;; +10D35;HANIFI ROHINGYA DIGIT FIVE;Nd;0;AN;;5;5;5;N;;;;; +10D36;HANIFI ROHINGYA DIGIT SIX;Nd;0;AN;;6;6;6;N;;;;; +10D37;HANIFI ROHINGYA DIGIT SEVEN;Nd;0;AN;;7;7;7;N;;;;; +10D38;HANIFI ROHINGYA DIGIT EIGHT;Nd;0;AN;;8;8;8;N;;;;; +10D39;HANIFI ROHINGYA DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;; +10E60;RUMI DIGIT ONE;No;0;AN;;;1;1;N;;;;; +10E61;RUMI DIGIT TWO;No;0;AN;;;2;2;N;;;;; +10E62;RUMI DIGIT THREE;No;0;AN;;;3;3;N;;;;; +10E63;RUMI DIGIT FOUR;No;0;AN;;;4;4;N;;;;; +10E64;RUMI DIGIT FIVE;No;0;AN;;;5;5;N;;;;; +10E65;RUMI DIGIT SIX;No;0;AN;;;6;6;N;;;;; +10E66;RUMI DIGIT SEVEN;No;0;AN;;;7;7;N;;;;; +10E67;RUMI DIGIT EIGHT;No;0;AN;;;8;8;N;;;;; +10E68;RUMI DIGIT NINE;No;0;AN;;;9;9;N;;;;; +10E69;RUMI NUMBER TEN;No;0;AN;;;;10;N;;;;; +10E6A;RUMI NUMBER TWENTY;No;0;AN;;;;20;N;;;;; +10E6B;RUMI NUMBER THIRTY;No;0;AN;;;;30;N;;;;; +10E6C;RUMI NUMBER FORTY;No;0;AN;;;;40;N;;;;; +10E6D;RUMI NUMBER FIFTY;No;0;AN;;;;50;N;;;;; +10E6E;RUMI NUMBER SIXTY;No;0;AN;;;;60;N;;;;; +10E6F;RUMI NUMBER SEVENTY;No;0;AN;;;;70;N;;;;; +10E70;RUMI NUMBER EIGHTY;No;0;AN;;;;80;N;;;;; +10E71;RUMI NUMBER NINETY;No;0;AN;;;;90;N;;;;; +10E72;RUMI NUMBER ONE HUNDRED;No;0;AN;;;;100;N;;;;; +10E73;RUMI NUMBER TWO HUNDRED;No;0;AN;;;;200;N;;;;; +10E74;RUMI NUMBER THREE HUNDRED;No;0;AN;;;;300;N;;;;; +10E75;RUMI NUMBER FOUR HUNDRED;No;0;AN;;;;400;N;;;;; +10E76;RUMI NUMBER FIVE HUNDRED;No;0;AN;;;;500;N;;;;; +10E77;RUMI NUMBER SIX HUNDRED;No;0;AN;;;;600;N;;;;; +10E78;RUMI NUMBER SEVEN HUNDRED;No;0;AN;;;;700;N;;;;; +10E79;RUMI NUMBER EIGHT HUNDRED;No;0;AN;;;;800;N;;;;; +10E7A;RUMI NUMBER NINE HUNDRED;No;0;AN;;;;900;N;;;;; +10E7B;RUMI FRACTION ONE HALF;No;0;AN;;;;1/2;N;;;;; +10E7C;RUMI FRACTION ONE QUARTER;No;0;AN;;;;1/4;N;;;;; +10E7D;RUMI FRACTION ONE THIRD;No;0;AN;;;;1/3;N;;;;; +10E7E;RUMI FRACTION TWO THIRDS;No;0;AN;;;;2/3;N;;;;; +10F00;OLD SOGDIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10F01;OLD SOGDIAN LETTER FINAL ALEPH;Lo;0;R;;;;;N;;;;; +10F02;OLD SOGDIAN LETTER BETH;Lo;0;R;;;;;N;;;;; +10F03;OLD SOGDIAN LETTER FINAL BETH;Lo;0;R;;;;;N;;;;; +10F04;OLD SOGDIAN LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10F05;OLD SOGDIAN LETTER HE;Lo;0;R;;;;;N;;;;; +10F06;OLD SOGDIAN LETTER FINAL HE;Lo;0;R;;;;;N;;;;; +10F07;OLD SOGDIAN LETTER WAW;Lo;0;R;;;;;N;;;;; +10F08;OLD SOGDIAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10F09;OLD SOGDIAN LETTER HETH;Lo;0;R;;;;;N;;;;; +10F0A;OLD SOGDIAN LETTER YODH;Lo;0;R;;;;;N;;;;; +10F0B;OLD SOGDIAN LETTER KAPH;Lo;0;R;;;;;N;;;;; +10F0C;OLD SOGDIAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10F0D;OLD SOGDIAN LETTER MEM;Lo;0;R;;;;;N;;;;; +10F0E;OLD SOGDIAN LETTER NUN;Lo;0;R;;;;;N;;;;; +10F0F;OLD SOGDIAN LETTER FINAL NUN;Lo;0;R;;;;;N;;;;; +10F10;OLD SOGDIAN LETTER FINAL NUN WITH VERTICAL TAIL;Lo;0;R;;;;;N;;;;; +10F11;OLD SOGDIAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10F12;OLD SOGDIAN LETTER AYIN;Lo;0;R;;;;;N;;;;; +10F13;OLD SOGDIAN LETTER ALTERNATE AYIN;Lo;0;R;;;;;N;;;;; +10F14;OLD SOGDIAN LETTER PE;Lo;0;R;;;;;N;;;;; +10F15;OLD SOGDIAN LETTER SADHE;Lo;0;R;;;;;N;;;;; +10F16;OLD SOGDIAN LETTER FINAL SADHE;Lo;0;R;;;;;N;;;;; +10F17;OLD SOGDIAN LETTER FINAL SADHE WITH VERTICAL TAIL;Lo;0;R;;;;;N;;;;; +10F18;OLD SOGDIAN LETTER RESH-AYIN-DALETH;Lo;0;R;;;;;N;;;;; +10F19;OLD SOGDIAN LETTER SHIN;Lo;0;R;;;;;N;;;;; +10F1A;OLD SOGDIAN LETTER TAW;Lo;0;R;;;;;N;;;;; +10F1B;OLD SOGDIAN LETTER FINAL TAW;Lo;0;R;;;;;N;;;;; +10F1C;OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL;Lo;0;R;;;;;N;;;;; +10F1D;OLD SOGDIAN NUMBER ONE;No;0;R;;;;1;N;;;;; +10F1E;OLD SOGDIAN NUMBER TWO;No;0;R;;;;2;N;;;;; +10F1F;OLD SOGDIAN NUMBER THREE;No;0;R;;;;3;N;;;;; +10F20;OLD SOGDIAN NUMBER FOUR;No;0;R;;;;4;N;;;;; +10F21;OLD SOGDIAN NUMBER FIVE;No;0;R;;;;5;N;;;;; +10F22;OLD SOGDIAN NUMBER TEN;No;0;R;;;;10;N;;;;; +10F23;OLD SOGDIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10F24;OLD SOGDIAN NUMBER THIRTY;No;0;R;;;;30;N;;;;; +10F25;OLD SOGDIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +10F26;OLD SOGDIAN FRACTION ONE HALF;No;0;R;;;;1/2;N;;;;; +10F27;OLD SOGDIAN LIGATURE AYIN-DALETH;Lo;0;R;;;;;N;;;;; +10F30;SOGDIAN LETTER ALEPH;Lo;0;AL;;;;;N;;;;; +10F31;SOGDIAN LETTER BETH;Lo;0;AL;;;;;N;;;;; +10F32;SOGDIAN LETTER GIMEL;Lo;0;AL;;;;;N;;;;; +10F33;SOGDIAN LETTER HE;Lo;0;AL;;;;;N;;;;; +10F34;SOGDIAN LETTER WAW;Lo;0;AL;;;;;N;;;;; +10F35;SOGDIAN LETTER ZAYIN;Lo;0;AL;;;;;N;;;;; +10F36;SOGDIAN LETTER HETH;Lo;0;AL;;;;;N;;;;; +10F37;SOGDIAN LETTER YODH;Lo;0;AL;;;;;N;;;;; +10F38;SOGDIAN LETTER KAPH;Lo;0;AL;;;;;N;;;;; +10F39;SOGDIAN LETTER LAMEDH;Lo;0;AL;;;;;N;;;;; +10F3A;SOGDIAN LETTER MEM;Lo;0;AL;;;;;N;;;;; +10F3B;SOGDIAN LETTER NUN;Lo;0;AL;;;;;N;;;;; +10F3C;SOGDIAN LETTER SAMEKH;Lo;0;AL;;;;;N;;;;; +10F3D;SOGDIAN LETTER AYIN;Lo;0;AL;;;;;N;;;;; +10F3E;SOGDIAN LETTER PE;Lo;0;AL;;;;;N;;;;; +10F3F;SOGDIAN LETTER SADHE;Lo;0;AL;;;;;N;;;;; +10F40;SOGDIAN LETTER RESH-AYIN;Lo;0;AL;;;;;N;;;;; +10F41;SOGDIAN LETTER SHIN;Lo;0;AL;;;;;N;;;;; +10F42;SOGDIAN LETTER TAW;Lo;0;AL;;;;;N;;;;; +10F43;SOGDIAN LETTER FETH;Lo;0;AL;;;;;N;;;;; +10F44;SOGDIAN LETTER LESH;Lo;0;AL;;;;;N;;;;; +10F45;SOGDIAN INDEPENDENT SHIN;Lo;0;AL;;;;;N;;;;; +10F46;SOGDIAN COMBINING DOT BELOW;Mn;220;NSM;;;;;N;;;;; +10F47;SOGDIAN COMBINING TWO DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +10F48;SOGDIAN COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;;;;; +10F49;SOGDIAN COMBINING TWO DOTS ABOVE;Mn;230;NSM;;;;;N;;;;; +10F4A;SOGDIAN COMBINING CURVE ABOVE;Mn;230;NSM;;;;;N;;;;; +10F4B;SOGDIAN COMBINING CURVE BELOW;Mn;220;NSM;;;;;N;;;;; +10F4C;SOGDIAN COMBINING HOOK ABOVE;Mn;230;NSM;;;;;N;;;;; +10F4D;SOGDIAN COMBINING HOOK BELOW;Mn;220;NSM;;;;;N;;;;; +10F4E;SOGDIAN COMBINING LONG HOOK BELOW;Mn;220;NSM;;;;;N;;;;; +10F4F;SOGDIAN COMBINING RESH BELOW;Mn;220;NSM;;;;;N;;;;; +10F50;SOGDIAN COMBINING STROKE BELOW;Mn;220;NSM;;;;;N;;;;; +10F51;SOGDIAN NUMBER ONE;No;0;AL;;;;1;N;;;;; +10F52;SOGDIAN NUMBER TEN;No;0;AL;;;;10;N;;;;; +10F53;SOGDIAN NUMBER TWENTY;No;0;AL;;;;20;N;;;;; +10F54;SOGDIAN NUMBER ONE HUNDRED;No;0;AL;;;;100;N;;;;; +10F55;SOGDIAN PUNCTUATION TWO VERTICAL BARS;Po;0;AL;;;;;N;;;;; +10F56;SOGDIAN PUNCTUATION TWO VERTICAL BARS WITH DOTS;Po;0;AL;;;;;N;;;;; +10F57;SOGDIAN PUNCTUATION CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;; +10F58;SOGDIAN PUNCTUATION TWO CIRCLES WITH DOTS;Po;0;AL;;;;;N;;;;; +10F59;SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;; +10FE0;ELYMAIC LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10FE1;ELYMAIC LETTER BETH;Lo;0;R;;;;;N;;;;; +10FE2;ELYMAIC LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10FE3;ELYMAIC LETTER DALETH;Lo;0;R;;;;;N;;;;; +10FE4;ELYMAIC LETTER HE;Lo;0;R;;;;;N;;;;; +10FE5;ELYMAIC LETTER WAW;Lo;0;R;;;;;N;;;;; +10FE6;ELYMAIC LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10FE7;ELYMAIC LETTER HETH;Lo;0;R;;;;;N;;;;; +10FE8;ELYMAIC LETTER TETH;Lo;0;R;;;;;N;;;;; +10FE9;ELYMAIC LETTER YODH;Lo;0;R;;;;;N;;;;; +10FEA;ELYMAIC LETTER KAPH;Lo;0;R;;;;;N;;;;; +10FEB;ELYMAIC LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10FEC;ELYMAIC LETTER MEM;Lo;0;R;;;;;N;;;;; +10FED;ELYMAIC LETTER NUN;Lo;0;R;;;;;N;;;;; +10FEE;ELYMAIC LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10FEF;ELYMAIC LETTER AYIN;Lo;0;R;;;;;N;;;;; +10FF0;ELYMAIC LETTER PE;Lo;0;R;;;;;N;;;;; +10FF1;ELYMAIC LETTER SADHE;Lo;0;R;;;;;N;;;;; +10FF2;ELYMAIC LETTER QOPH;Lo;0;R;;;;;N;;;;; +10FF3;ELYMAIC LETTER RESH;Lo;0;R;;;;;N;;;;; +10FF4;ELYMAIC LETTER SHIN;Lo;0;R;;;;;N;;;;; +10FF5;ELYMAIC LETTER TAW;Lo;0;R;;;;;N;;;;; +10FF6;ELYMAIC LIGATURE ZAYIN-YODH;Lo;0;R;;;;;N;;;;; +11000;BRAHMI SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;; +11001;BRAHMI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11002;BRAHMI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +11003;BRAHMI SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;; +11004;BRAHMI SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;; +11005;BRAHMI LETTER A;Lo;0;L;;;;;N;;;;; +11006;BRAHMI LETTER AA;Lo;0;L;;;;;N;;;;; +11007;BRAHMI LETTER I;Lo;0;L;;;;;N;;;;; +11008;BRAHMI LETTER II;Lo;0;L;;;;;N;;;;; +11009;BRAHMI LETTER U;Lo;0;L;;;;;N;;;;; +1100A;BRAHMI LETTER UU;Lo;0;L;;;;;N;;;;; +1100B;BRAHMI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +1100C;BRAHMI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +1100D;BRAHMI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +1100E;BRAHMI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +1100F;BRAHMI LETTER E;Lo;0;L;;;;;N;;;;; +11010;BRAHMI LETTER AI;Lo;0;L;;;;;N;;;;; +11011;BRAHMI LETTER O;Lo;0;L;;;;;N;;;;; +11012;BRAHMI LETTER AU;Lo;0;L;;;;;N;;;;; +11013;BRAHMI LETTER KA;Lo;0;L;;;;;N;;;;; +11014;BRAHMI LETTER KHA;Lo;0;L;;;;;N;;;;; +11015;BRAHMI LETTER GA;Lo;0;L;;;;;N;;;;; +11016;BRAHMI LETTER GHA;Lo;0;L;;;;;N;;;;; +11017;BRAHMI LETTER NGA;Lo;0;L;;;;;N;;;;; +11018;BRAHMI LETTER CA;Lo;0;L;;;;;N;;;;; +11019;BRAHMI LETTER CHA;Lo;0;L;;;;;N;;;;; +1101A;BRAHMI LETTER JA;Lo;0;L;;;;;N;;;;; +1101B;BRAHMI LETTER JHA;Lo;0;L;;;;;N;;;;; +1101C;BRAHMI LETTER NYA;Lo;0;L;;;;;N;;;;; +1101D;BRAHMI LETTER TTA;Lo;0;L;;;;;N;;;;; +1101E;BRAHMI LETTER TTHA;Lo;0;L;;;;;N;;;;; +1101F;BRAHMI LETTER DDA;Lo;0;L;;;;;N;;;;; +11020;BRAHMI LETTER DDHA;Lo;0;L;;;;;N;;;;; +11021;BRAHMI LETTER NNA;Lo;0;L;;;;;N;;;;; +11022;BRAHMI LETTER TA;Lo;0;L;;;;;N;;;;; +11023;BRAHMI LETTER THA;Lo;0;L;;;;;N;;;;; +11024;BRAHMI LETTER DA;Lo;0;L;;;;;N;;;;; +11025;BRAHMI LETTER DHA;Lo;0;L;;;;;N;;;;; +11026;BRAHMI LETTER NA;Lo;0;L;;;;;N;;;;; +11027;BRAHMI LETTER PA;Lo;0;L;;;;;N;;;;; +11028;BRAHMI LETTER PHA;Lo;0;L;;;;;N;;;;; +11029;BRAHMI LETTER BA;Lo;0;L;;;;;N;;;;; +1102A;BRAHMI LETTER BHA;Lo;0;L;;;;;N;;;;; +1102B;BRAHMI LETTER MA;Lo;0;L;;;;;N;;;;; +1102C;BRAHMI LETTER YA;Lo;0;L;;;;;N;;;;; +1102D;BRAHMI LETTER RA;Lo;0;L;;;;;N;;;;; +1102E;BRAHMI LETTER LA;Lo;0;L;;;;;N;;;;; +1102F;BRAHMI LETTER VA;Lo;0;L;;;;;N;;;;; +11030;BRAHMI LETTER SHA;Lo;0;L;;;;;N;;;;; +11031;BRAHMI LETTER SSA;Lo;0;L;;;;;N;;;;; +11032;BRAHMI LETTER SA;Lo;0;L;;;;;N;;;;; +11033;BRAHMI LETTER HA;Lo;0;L;;;;;N;;;;; +11034;BRAHMI LETTER LLA;Lo;0;L;;;;;N;;;;; +11035;BRAHMI LETTER OLD TAMIL LLLA;Lo;0;L;;;;;N;;;;; +11036;BRAHMI LETTER OLD TAMIL RRA;Lo;0;L;;;;;N;;;;; +11037;BRAHMI LETTER OLD TAMIL NNNA;Lo;0;L;;;;;N;;;;; +11038;BRAHMI VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;; +11039;BRAHMI VOWEL SIGN BHATTIPROLU AA;Mn;0;NSM;;;;;N;;;;; +1103A;BRAHMI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +1103B;BRAHMI VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +1103C;BRAHMI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1103D;BRAHMI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +1103E;BRAHMI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +1103F;BRAHMI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +11040;BRAHMI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +11041;BRAHMI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +11042;BRAHMI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +11043;BRAHMI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +11044;BRAHMI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +11045;BRAHMI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +11046;BRAHMI VIRAMA;Mn;9;NSM;;;;;N;;;;; +11047;BRAHMI DANDA;Po;0;L;;;;;N;;;;; +11048;BRAHMI DOUBLE DANDA;Po;0;L;;;;;N;;;;; +11049;BRAHMI PUNCTUATION DOT;Po;0;L;;;;;N;;;;; +1104A;BRAHMI PUNCTUATION DOUBLE DOT;Po;0;L;;;;;N;;;;; +1104B;BRAHMI PUNCTUATION LINE;Po;0;L;;;;;N;;;;; +1104C;BRAHMI PUNCTUATION CRESCENT BAR;Po;0;L;;;;;N;;;;; +1104D;BRAHMI PUNCTUATION LOTUS;Po;0;L;;;;;N;;;;; +11052;BRAHMI NUMBER ONE;No;0;ON;;;1;1;N;;;;; +11053;BRAHMI NUMBER TWO;No;0;ON;;;2;2;N;;;;; +11054;BRAHMI NUMBER THREE;No;0;ON;;;3;3;N;;;;; +11055;BRAHMI NUMBER FOUR;No;0;ON;;;4;4;N;;;;; +11056;BRAHMI NUMBER FIVE;No;0;ON;;;5;5;N;;;;; +11057;BRAHMI NUMBER SIX;No;0;ON;;;6;6;N;;;;; +11058;BRAHMI NUMBER SEVEN;No;0;ON;;;7;7;N;;;;; +11059;BRAHMI NUMBER EIGHT;No;0;ON;;;8;8;N;;;;; +1105A;BRAHMI NUMBER NINE;No;0;ON;;;9;9;N;;;;; +1105B;BRAHMI NUMBER TEN;No;0;ON;;;;10;N;;;;; +1105C;BRAHMI NUMBER TWENTY;No;0;ON;;;;20;N;;;;; +1105D;BRAHMI NUMBER THIRTY;No;0;ON;;;;30;N;;;;; +1105E;BRAHMI NUMBER FORTY;No;0;ON;;;;40;N;;;;; +1105F;BRAHMI NUMBER FIFTY;No;0;ON;;;;50;N;;;;; +11060;BRAHMI NUMBER SIXTY;No;0;ON;;;;60;N;;;;; +11061;BRAHMI NUMBER SEVENTY;No;0;ON;;;;70;N;;;;; +11062;BRAHMI NUMBER EIGHTY;No;0;ON;;;;80;N;;;;; +11063;BRAHMI NUMBER NINETY;No;0;ON;;;;90;N;;;;; +11064;BRAHMI NUMBER ONE HUNDRED;No;0;ON;;;;100;N;;;;; +11065;BRAHMI NUMBER ONE THOUSAND;No;0;ON;;;;1000;N;;;;; +11066;BRAHMI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +11067;BRAHMI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +11068;BRAHMI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +11069;BRAHMI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1106A;BRAHMI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1106B;BRAHMI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1106C;BRAHMI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1106D;BRAHMI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1106E;BRAHMI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1106F;BRAHMI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1107F;BRAHMI NUMBER JOINER;Mn;9;NSM;;;;;N;;;;; +11080;KAITHI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +11081;KAITHI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11082;KAITHI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +11083;KAITHI LETTER A;Lo;0;L;;;;;N;;;;; +11084;KAITHI LETTER AA;Lo;0;L;;;;;N;;;;; +11085;KAITHI LETTER I;Lo;0;L;;;;;N;;;;; +11086;KAITHI LETTER II;Lo;0;L;;;;;N;;;;; +11087;KAITHI LETTER U;Lo;0;L;;;;;N;;;;; +11088;KAITHI LETTER UU;Lo;0;L;;;;;N;;;;; +11089;KAITHI LETTER E;Lo;0;L;;;;;N;;;;; +1108A;KAITHI LETTER AI;Lo;0;L;;;;;N;;;;; +1108B;KAITHI LETTER O;Lo;0;L;;;;;N;;;;; +1108C;KAITHI LETTER AU;Lo;0;L;;;;;N;;;;; +1108D;KAITHI LETTER KA;Lo;0;L;;;;;N;;;;; +1108E;KAITHI LETTER KHA;Lo;0;L;;;;;N;;;;; +1108F;KAITHI LETTER GA;Lo;0;L;;;;;N;;;;; +11090;KAITHI LETTER GHA;Lo;0;L;;;;;N;;;;; +11091;KAITHI LETTER NGA;Lo;0;L;;;;;N;;;;; +11092;KAITHI LETTER CA;Lo;0;L;;;;;N;;;;; +11093;KAITHI LETTER CHA;Lo;0;L;;;;;N;;;;; +11094;KAITHI LETTER JA;Lo;0;L;;;;;N;;;;; +11095;KAITHI LETTER JHA;Lo;0;L;;;;;N;;;;; +11096;KAITHI LETTER NYA;Lo;0;L;;;;;N;;;;; +11097;KAITHI LETTER TTA;Lo;0;L;;;;;N;;;;; +11098;KAITHI LETTER TTHA;Lo;0;L;;;;;N;;;;; +11099;KAITHI LETTER DDA;Lo;0;L;;;;;N;;;;; +1109A;KAITHI LETTER DDDHA;Lo;0;L;11099 110BA;;;;N;;;;; +1109B;KAITHI LETTER DDHA;Lo;0;L;;;;;N;;;;; +1109C;KAITHI LETTER RHA;Lo;0;L;1109B 110BA;;;;N;;;;; +1109D;KAITHI LETTER NNA;Lo;0;L;;;;;N;;;;; +1109E;KAITHI LETTER TA;Lo;0;L;;;;;N;;;;; +1109F;KAITHI LETTER THA;Lo;0;L;;;;;N;;;;; +110A0;KAITHI LETTER DA;Lo;0;L;;;;;N;;;;; +110A1;KAITHI LETTER DHA;Lo;0;L;;;;;N;;;;; +110A2;KAITHI LETTER NA;Lo;0;L;;;;;N;;;;; +110A3;KAITHI LETTER PA;Lo;0;L;;;;;N;;;;; +110A4;KAITHI LETTER PHA;Lo;0;L;;;;;N;;;;; +110A5;KAITHI LETTER BA;Lo;0;L;;;;;N;;;;; +110A6;KAITHI LETTER BHA;Lo;0;L;;;;;N;;;;; +110A7;KAITHI LETTER MA;Lo;0;L;;;;;N;;;;; +110A8;KAITHI LETTER YA;Lo;0;L;;;;;N;;;;; +110A9;KAITHI LETTER RA;Lo;0;L;;;;;N;;;;; +110AA;KAITHI LETTER LA;Lo;0;L;;;;;N;;;;; +110AB;KAITHI LETTER VA;Lo;0;L;110A5 110BA;;;;N;;;;; +110AC;KAITHI LETTER SHA;Lo;0;L;;;;;N;;;;; +110AD;KAITHI LETTER SSA;Lo;0;L;;;;;N;;;;; +110AE;KAITHI LETTER SA;Lo;0;L;;;;;N;;;;; +110AF;KAITHI LETTER HA;Lo;0;L;;;;;N;;;;; +110B0;KAITHI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +110B1;KAITHI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +110B2;KAITHI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +110B3;KAITHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +110B4;KAITHI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +110B5;KAITHI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +110B6;KAITHI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +110B7;KAITHI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +110B8;KAITHI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +110B9;KAITHI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +110BA;KAITHI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +110BB;KAITHI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +110BC;KAITHI ENUMERATION SIGN;Po;0;L;;;;;N;;;;; +110BD;KAITHI NUMBER SIGN;Cf;0;L;;;;;N;;;;; +110BE;KAITHI SECTION MARK;Po;0;L;;;;;N;;;;; +110BF;KAITHI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;; +110C0;KAITHI DANDA;Po;0;L;;;;;N;;;;; +110C1;KAITHI DOUBLE DANDA;Po;0;L;;;;;N;;;;; +110CD;KAITHI NUMBER SIGN ABOVE;Cf;0;L;;;;;N;;;;; +110D0;SORA SOMPENG LETTER SAH;Lo;0;L;;;;;N;;;;; +110D1;SORA SOMPENG LETTER TAH;Lo;0;L;;;;;N;;;;; +110D2;SORA SOMPENG LETTER BAH;Lo;0;L;;;;;N;;;;; +110D3;SORA SOMPENG LETTER CAH;Lo;0;L;;;;;N;;;;; +110D4;SORA SOMPENG LETTER DAH;Lo;0;L;;;;;N;;;;; +110D5;SORA SOMPENG LETTER GAH;Lo;0;L;;;;;N;;;;; +110D6;SORA SOMPENG LETTER MAH;Lo;0;L;;;;;N;;;;; +110D7;SORA SOMPENG LETTER NGAH;Lo;0;L;;;;;N;;;;; +110D8;SORA SOMPENG LETTER LAH;Lo;0;L;;;;;N;;;;; +110D9;SORA SOMPENG LETTER NAH;Lo;0;L;;;;;N;;;;; +110DA;SORA SOMPENG LETTER VAH;Lo;0;L;;;;;N;;;;; +110DB;SORA SOMPENG LETTER PAH;Lo;0;L;;;;;N;;;;; +110DC;SORA SOMPENG LETTER YAH;Lo;0;L;;;;;N;;;;; +110DD;SORA SOMPENG LETTER RAH;Lo;0;L;;;;;N;;;;; +110DE;SORA SOMPENG LETTER HAH;Lo;0;L;;;;;N;;;;; +110DF;SORA SOMPENG LETTER KAH;Lo;0;L;;;;;N;;;;; +110E0;SORA SOMPENG LETTER JAH;Lo;0;L;;;;;N;;;;; +110E1;SORA SOMPENG LETTER NYAH;Lo;0;L;;;;;N;;;;; +110E2;SORA SOMPENG LETTER AH;Lo;0;L;;;;;N;;;;; +110E3;SORA SOMPENG LETTER EEH;Lo;0;L;;;;;N;;;;; +110E4;SORA SOMPENG LETTER IH;Lo;0;L;;;;;N;;;;; +110E5;SORA SOMPENG LETTER UH;Lo;0;L;;;;;N;;;;; +110E6;SORA SOMPENG LETTER OH;Lo;0;L;;;;;N;;;;; +110E7;SORA SOMPENG LETTER EH;Lo;0;L;;;;;N;;;;; +110E8;SORA SOMPENG LETTER MAE;Lo;0;L;;;;;N;;;;; +110F0;SORA SOMPENG DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +110F1;SORA SOMPENG DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +110F2;SORA SOMPENG DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +110F3;SORA SOMPENG DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +110F4;SORA SOMPENG DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +110F5;SORA SOMPENG DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +110F6;SORA SOMPENG DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +110F7;SORA SOMPENG DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +110F8;SORA SOMPENG DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +110F9;SORA SOMPENG DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +11100;CHAKMA SIGN CANDRABINDU;Mn;230;NSM;;;;;N;;;;; +11101;CHAKMA SIGN ANUSVARA;Mn;230;NSM;;;;;N;;;;; +11102;CHAKMA SIGN VISARGA;Mn;230;NSM;;;;;N;;;;; +11103;CHAKMA LETTER AA;Lo;0;L;;;;;N;;;;; +11104;CHAKMA LETTER I;Lo;0;L;;;;;N;;;;; +11105;CHAKMA LETTER U;Lo;0;L;;;;;N;;;;; +11106;CHAKMA LETTER E;Lo;0;L;;;;;N;;;;; +11107;CHAKMA LETTER KAA;Lo;0;L;;;;;N;;;;; +11108;CHAKMA LETTER KHAA;Lo;0;L;;;;;N;;;;; +11109;CHAKMA LETTER GAA;Lo;0;L;;;;;N;;;;; +1110A;CHAKMA LETTER GHAA;Lo;0;L;;;;;N;;;;; +1110B;CHAKMA LETTER NGAA;Lo;0;L;;;;;N;;;;; +1110C;CHAKMA LETTER CAA;Lo;0;L;;;;;N;;;;; +1110D;CHAKMA LETTER CHAA;Lo;0;L;;;;;N;;;;; +1110E;CHAKMA LETTER JAA;Lo;0;L;;;;;N;;;;; +1110F;CHAKMA LETTER JHAA;Lo;0;L;;;;;N;;;;; +11110;CHAKMA LETTER NYAA;Lo;0;L;;;;;N;;;;; +11111;CHAKMA LETTER TTAA;Lo;0;L;;;;;N;;;;; +11112;CHAKMA LETTER TTHAA;Lo;0;L;;;;;N;;;;; +11113;CHAKMA LETTER DDAA;Lo;0;L;;;;;N;;;;; +11114;CHAKMA LETTER DDHAA;Lo;0;L;;;;;N;;;;; +11115;CHAKMA LETTER NNAA;Lo;0;L;;;;;N;;;;; +11116;CHAKMA LETTER TAA;Lo;0;L;;;;;N;;;;; +11117;CHAKMA LETTER THAA;Lo;0;L;;;;;N;;;;; +11118;CHAKMA LETTER DAA;Lo;0;L;;;;;N;;;;; +11119;CHAKMA LETTER DHAA;Lo;0;L;;;;;N;;;;; +1111A;CHAKMA LETTER NAA;Lo;0;L;;;;;N;;;;; +1111B;CHAKMA LETTER PAA;Lo;0;L;;;;;N;;;;; +1111C;CHAKMA LETTER PHAA;Lo;0;L;;;;;N;;;;; +1111D;CHAKMA LETTER BAA;Lo;0;L;;;;;N;;;;; +1111E;CHAKMA LETTER BHAA;Lo;0;L;;;;;N;;;;; +1111F;CHAKMA LETTER MAA;Lo;0;L;;;;;N;;;;; +11120;CHAKMA LETTER YYAA;Lo;0;L;;;;;N;;;;; +11121;CHAKMA LETTER YAA;Lo;0;L;;;;;N;;;;; +11122;CHAKMA LETTER RAA;Lo;0;L;;;;;N;;;;; +11123;CHAKMA LETTER LAA;Lo;0;L;;;;;N;;;;; +11124;CHAKMA LETTER WAA;Lo;0;L;;;;;N;;;;; +11125;CHAKMA LETTER SAA;Lo;0;L;;;;;N;;;;; +11126;CHAKMA LETTER HAA;Lo;0;L;;;;;N;;;;; +11127;CHAKMA VOWEL SIGN A;Mn;0;NSM;;;;;N;;;;; +11128;CHAKMA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +11129;CHAKMA VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +1112A;CHAKMA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +1112B;CHAKMA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +1112C;CHAKMA VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +1112D;CHAKMA VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +1112E;CHAKMA VOWEL SIGN O;Mn;0;NSM;11131 11127;;;;N;;;;; +1112F;CHAKMA VOWEL SIGN AU;Mn;0;NSM;11132 11127;;;;N;;;;; +11130;CHAKMA VOWEL SIGN OI;Mn;0;NSM;;;;;N;;;;; +11131;CHAKMA O MARK;Mn;0;NSM;;;;;N;;;;; +11132;CHAKMA AU MARK;Mn;0;NSM;;;;;N;;;;; +11133;CHAKMA VIRAMA;Mn;9;NSM;;;;;N;;;;; +11134;CHAKMA MAAYYAA;Mn;9;NSM;;;;;N;;;;; +11136;CHAKMA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +11137;CHAKMA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +11138;CHAKMA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +11139;CHAKMA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1113A;CHAKMA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1113B;CHAKMA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1113C;CHAKMA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1113D;CHAKMA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1113E;CHAKMA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1113F;CHAKMA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +11140;CHAKMA SECTION MARK;Po;0;L;;;;;N;;;;; +11141;CHAKMA DANDA;Po;0;L;;;;;N;;;;; +11142;CHAKMA DOUBLE DANDA;Po;0;L;;;;;N;;;;; +11143;CHAKMA QUESTION MARK;Po;0;L;;;;;N;;;;; +11144;CHAKMA LETTER LHAA;Lo;0;L;;;;;N;;;;; +11145;CHAKMA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +11146;CHAKMA VOWEL SIGN EI;Mc;0;L;;;;;N;;;;; +11150;MAHAJANI LETTER A;Lo;0;L;;;;;N;;;;; +11151;MAHAJANI LETTER I;Lo;0;L;;;;;N;;;;; +11152;MAHAJANI LETTER U;Lo;0;L;;;;;N;;;;; +11153;MAHAJANI LETTER E;Lo;0;L;;;;;N;;;;; +11154;MAHAJANI LETTER O;Lo;0;L;;;;;N;;;;; +11155;MAHAJANI LETTER KA;Lo;0;L;;;;;N;;;;; +11156;MAHAJANI LETTER KHA;Lo;0;L;;;;;N;;;;; +11157;MAHAJANI LETTER GA;Lo;0;L;;;;;N;;;;; +11158;MAHAJANI LETTER GHA;Lo;0;L;;;;;N;;;;; +11159;MAHAJANI LETTER CA;Lo;0;L;;;;;N;;;;; +1115A;MAHAJANI LETTER CHA;Lo;0;L;;;;;N;;;;; +1115B;MAHAJANI LETTER JA;Lo;0;L;;;;;N;;;;; +1115C;MAHAJANI LETTER JHA;Lo;0;L;;;;;N;;;;; +1115D;MAHAJANI LETTER NYA;Lo;0;L;;;;;N;;;;; +1115E;MAHAJANI LETTER TTA;Lo;0;L;;;;;N;;;;; +1115F;MAHAJANI LETTER TTHA;Lo;0;L;;;;;N;;;;; +11160;MAHAJANI LETTER DDA;Lo;0;L;;;;;N;;;;; +11161;MAHAJANI LETTER DDHA;Lo;0;L;;;;;N;;;;; +11162;MAHAJANI LETTER NNA;Lo;0;L;;;;;N;;;;; +11163;MAHAJANI LETTER TA;Lo;0;L;;;;;N;;;;; +11164;MAHAJANI LETTER THA;Lo;0;L;;;;;N;;;;; +11165;MAHAJANI LETTER DA;Lo;0;L;;;;;N;;;;; +11166;MAHAJANI LETTER DHA;Lo;0;L;;;;;N;;;;; +11167;MAHAJANI LETTER NA;Lo;0;L;;;;;N;;;;; +11168;MAHAJANI LETTER PA;Lo;0;L;;;;;N;;;;; +11169;MAHAJANI LETTER PHA;Lo;0;L;;;;;N;;;;; +1116A;MAHAJANI LETTER BA;Lo;0;L;;;;;N;;;;; +1116B;MAHAJANI LETTER BHA;Lo;0;L;;;;;N;;;;; +1116C;MAHAJANI LETTER MA;Lo;0;L;;;;;N;;;;; +1116D;MAHAJANI LETTER RA;Lo;0;L;;;;;N;;;;; +1116E;MAHAJANI LETTER LA;Lo;0;L;;;;;N;;;;; +1116F;MAHAJANI LETTER VA;Lo;0;L;;;;;N;;;;; +11170;MAHAJANI LETTER SA;Lo;0;L;;;;;N;;;;; +11171;MAHAJANI LETTER HA;Lo;0;L;;;;;N;;;;; +11172;MAHAJANI LETTER RRA;Lo;0;L;;;;;N;;;;; +11173;MAHAJANI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +11174;MAHAJANI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +11175;MAHAJANI SECTION MARK;Po;0;L;;;;;N;;;;; +11176;MAHAJANI LIGATURE SHRI;Lo;0;L;;;;;N;;;;; +11180;SHARADA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +11181;SHARADA SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11182;SHARADA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +11183;SHARADA LETTER A;Lo;0;L;;;;;N;;;;; +11184;SHARADA LETTER AA;Lo;0;L;;;;;N;;;;; +11185;SHARADA LETTER I;Lo;0;L;;;;;N;;;;; +11186;SHARADA LETTER II;Lo;0;L;;;;;N;;;;; +11187;SHARADA LETTER U;Lo;0;L;;;;;N;;;;; +11188;SHARADA LETTER UU;Lo;0;L;;;;;N;;;;; +11189;SHARADA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +1118A;SHARADA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +1118B;SHARADA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +1118C;SHARADA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +1118D;SHARADA LETTER E;Lo;0;L;;;;;N;;;;; +1118E;SHARADA LETTER AI;Lo;0;L;;;;;N;;;;; +1118F;SHARADA LETTER O;Lo;0;L;;;;;N;;;;; +11190;SHARADA LETTER AU;Lo;0;L;;;;;N;;;;; +11191;SHARADA LETTER KA;Lo;0;L;;;;;N;;;;; +11192;SHARADA LETTER KHA;Lo;0;L;;;;;N;;;;; +11193;SHARADA LETTER GA;Lo;0;L;;;;;N;;;;; +11194;SHARADA LETTER GHA;Lo;0;L;;;;;N;;;;; +11195;SHARADA LETTER NGA;Lo;0;L;;;;;N;;;;; +11196;SHARADA LETTER CA;Lo;0;L;;;;;N;;;;; +11197;SHARADA LETTER CHA;Lo;0;L;;;;;N;;;;; +11198;SHARADA LETTER JA;Lo;0;L;;;;;N;;;;; +11199;SHARADA LETTER JHA;Lo;0;L;;;;;N;;;;; +1119A;SHARADA LETTER NYA;Lo;0;L;;;;;N;;;;; +1119B;SHARADA LETTER TTA;Lo;0;L;;;;;N;;;;; +1119C;SHARADA LETTER TTHA;Lo;0;L;;;;;N;;;;; +1119D;SHARADA LETTER DDA;Lo;0;L;;;;;N;;;;; +1119E;SHARADA LETTER DDHA;Lo;0;L;;;;;N;;;;; +1119F;SHARADA LETTER NNA;Lo;0;L;;;;;N;;;;; +111A0;SHARADA LETTER TA;Lo;0;L;;;;;N;;;;; +111A1;SHARADA LETTER THA;Lo;0;L;;;;;N;;;;; +111A2;SHARADA LETTER DA;Lo;0;L;;;;;N;;;;; +111A3;SHARADA LETTER DHA;Lo;0;L;;;;;N;;;;; +111A4;SHARADA LETTER NA;Lo;0;L;;;;;N;;;;; +111A5;SHARADA LETTER PA;Lo;0;L;;;;;N;;;;; +111A6;SHARADA LETTER PHA;Lo;0;L;;;;;N;;;;; +111A7;SHARADA LETTER BA;Lo;0;L;;;;;N;;;;; +111A8;SHARADA LETTER BHA;Lo;0;L;;;;;N;;;;; +111A9;SHARADA LETTER MA;Lo;0;L;;;;;N;;;;; +111AA;SHARADA LETTER YA;Lo;0;L;;;;;N;;;;; +111AB;SHARADA LETTER RA;Lo;0;L;;;;;N;;;;; +111AC;SHARADA LETTER LA;Lo;0;L;;;;;N;;;;; +111AD;SHARADA LETTER LLA;Lo;0;L;;;;;N;;;;; +111AE;SHARADA LETTER VA;Lo;0;L;;;;;N;;;;; +111AF;SHARADA LETTER SHA;Lo;0;L;;;;;N;;;;; +111B0;SHARADA LETTER SSA;Lo;0;L;;;;;N;;;;; +111B1;SHARADA LETTER SA;Lo;0;L;;;;;N;;;;; +111B2;SHARADA LETTER HA;Lo;0;L;;;;;N;;;;; +111B3;SHARADA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +111B4;SHARADA VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +111B5;SHARADA VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +111B6;SHARADA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +111B7;SHARADA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +111B8;SHARADA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +111B9;SHARADA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +111BA;SHARADA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +111BB;SHARADA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +111BC;SHARADA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +111BD;SHARADA VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +111BE;SHARADA VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +111BF;SHARADA VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +111C0;SHARADA SIGN VIRAMA;Mc;9;L;;;;;N;;;;; +111C1;SHARADA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +111C2;SHARADA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;; +111C3;SHARADA SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;; +111C4;SHARADA OM;Lo;0;L;;;;;N;;;;; +111C5;SHARADA DANDA;Po;0;L;;;;;N;;;;; +111C6;SHARADA DOUBLE DANDA;Po;0;L;;;;;N;;;;; +111C7;SHARADA ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +111C8;SHARADA SEPARATOR;Po;0;L;;;;;N;;;;; +111C9;SHARADA SANDHI MARK;Mn;0;NSM;;;;;N;;;;; +111CA;SHARADA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +111CB;SHARADA VOWEL MODIFIER MARK;Mn;0;NSM;;;;;N;;;;; +111CC;SHARADA EXTRA SHORT VOWEL MARK;Mn;0;NSM;;;;;N;;;;; +111CD;SHARADA SUTRA MARK;Po;0;L;;;;;N;;;;; +111D0;SHARADA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +111D1;SHARADA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +111D2;SHARADA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +111D3;SHARADA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +111D4;SHARADA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +111D5;SHARADA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +111D6;SHARADA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +111D7;SHARADA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +111D8;SHARADA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +111D9;SHARADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +111DA;SHARADA EKAM;Lo;0;L;;;;;N;;;;; +111DB;SHARADA SIGN SIDDHAM;Po;0;L;;;;;N;;;;; +111DC;SHARADA HEADSTROKE;Lo;0;L;;;;;N;;;;; +111DD;SHARADA CONTINUATION SIGN;Po;0;L;;;;;N;;;;; +111DE;SHARADA SECTION MARK-1;Po;0;L;;;;;N;;;;; +111DF;SHARADA SECTION MARK-2;Po;0;L;;;;;N;;;;; +111E1;SINHALA ARCHAIC DIGIT ONE;No;0;L;;;;1;N;;;;; +111E2;SINHALA ARCHAIC DIGIT TWO;No;0;L;;;;2;N;;;;; +111E3;SINHALA ARCHAIC DIGIT THREE;No;0;L;;;;3;N;;;;; +111E4;SINHALA ARCHAIC DIGIT FOUR;No;0;L;;;;4;N;;;;; +111E5;SINHALA ARCHAIC DIGIT FIVE;No;0;L;;;;5;N;;;;; +111E6;SINHALA ARCHAIC DIGIT SIX;No;0;L;;;;6;N;;;;; +111E7;SINHALA ARCHAIC DIGIT SEVEN;No;0;L;;;;7;N;;;;; +111E8;SINHALA ARCHAIC DIGIT EIGHT;No;0;L;;;;8;N;;;;; +111E9;SINHALA ARCHAIC DIGIT NINE;No;0;L;;;;9;N;;;;; +111EA;SINHALA ARCHAIC NUMBER TEN;No;0;L;;;;10;N;;;;; +111EB;SINHALA ARCHAIC NUMBER TWENTY;No;0;L;;;;20;N;;;;; +111EC;SINHALA ARCHAIC NUMBER THIRTY;No;0;L;;;;30;N;;;;; +111ED;SINHALA ARCHAIC NUMBER FORTY;No;0;L;;;;40;N;;;;; +111EE;SINHALA ARCHAIC NUMBER FIFTY;No;0;L;;;;50;N;;;;; +111EF;SINHALA ARCHAIC NUMBER SIXTY;No;0;L;;;;60;N;;;;; +111F0;SINHALA ARCHAIC NUMBER SEVENTY;No;0;L;;;;70;N;;;;; +111F1;SINHALA ARCHAIC NUMBER EIGHTY;No;0;L;;;;80;N;;;;; +111F2;SINHALA ARCHAIC NUMBER NINETY;No;0;L;;;;90;N;;;;; +111F3;SINHALA ARCHAIC NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;; +111F4;SINHALA ARCHAIC NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;; +11200;KHOJKI LETTER A;Lo;0;L;;;;;N;;;;; +11201;KHOJKI LETTER AA;Lo;0;L;;;;;N;;;;; +11202;KHOJKI LETTER I;Lo;0;L;;;;;N;;;;; +11203;KHOJKI LETTER U;Lo;0;L;;;;;N;;;;; +11204;KHOJKI LETTER E;Lo;0;L;;;;;N;;;;; +11205;KHOJKI LETTER AI;Lo;0;L;;;;;N;;;;; +11206;KHOJKI LETTER O;Lo;0;L;;;;;N;;;;; +11207;KHOJKI LETTER AU;Lo;0;L;;;;;N;;;;; +11208;KHOJKI LETTER KA;Lo;0;L;;;;;N;;;;; +11209;KHOJKI LETTER KHA;Lo;0;L;;;;;N;;;;; +1120A;KHOJKI LETTER GA;Lo;0;L;;;;;N;;;;; +1120B;KHOJKI LETTER GGA;Lo;0;L;;;;;N;;;;; +1120C;KHOJKI LETTER GHA;Lo;0;L;;;;;N;;;;; +1120D;KHOJKI LETTER NGA;Lo;0;L;;;;;N;;;;; +1120E;KHOJKI LETTER CA;Lo;0;L;;;;;N;;;;; +1120F;KHOJKI LETTER CHA;Lo;0;L;;;;;N;;;;; +11210;KHOJKI LETTER JA;Lo;0;L;;;;;N;;;;; +11211;KHOJKI LETTER JJA;Lo;0;L;;;;;N;;;;; +11213;KHOJKI LETTER NYA;Lo;0;L;;;;;N;;;;; +11214;KHOJKI LETTER TTA;Lo;0;L;;;;;N;;;;; +11215;KHOJKI LETTER TTHA;Lo;0;L;;;;;N;;;;; +11216;KHOJKI LETTER DDA;Lo;0;L;;;;;N;;;;; +11217;KHOJKI LETTER DDHA;Lo;0;L;;;;;N;;;;; +11218;KHOJKI LETTER NNA;Lo;0;L;;;;;N;;;;; +11219;KHOJKI LETTER TA;Lo;0;L;;;;;N;;;;; +1121A;KHOJKI LETTER THA;Lo;0;L;;;;;N;;;;; +1121B;KHOJKI LETTER DA;Lo;0;L;;;;;N;;;;; +1121C;KHOJKI LETTER DDDA;Lo;0;L;;;;;N;;;;; +1121D;KHOJKI LETTER DHA;Lo;0;L;;;;;N;;;;; +1121E;KHOJKI LETTER NA;Lo;0;L;;;;;N;;;;; +1121F;KHOJKI LETTER PA;Lo;0;L;;;;;N;;;;; +11220;KHOJKI LETTER PHA;Lo;0;L;;;;;N;;;;; +11221;KHOJKI LETTER BA;Lo;0;L;;;;;N;;;;; +11222;KHOJKI LETTER BBA;Lo;0;L;;;;;N;;;;; +11223;KHOJKI LETTER BHA;Lo;0;L;;;;;N;;;;; +11224;KHOJKI LETTER MA;Lo;0;L;;;;;N;;;;; +11225;KHOJKI LETTER YA;Lo;0;L;;;;;N;;;;; +11226;KHOJKI LETTER RA;Lo;0;L;;;;;N;;;;; +11227;KHOJKI LETTER LA;Lo;0;L;;;;;N;;;;; +11228;KHOJKI LETTER VA;Lo;0;L;;;;;N;;;;; +11229;KHOJKI LETTER SA;Lo;0;L;;;;;N;;;;; +1122A;KHOJKI LETTER HA;Lo;0;L;;;;;N;;;;; +1122B;KHOJKI LETTER LLA;Lo;0;L;;;;;N;;;;; +1122C;KHOJKI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +1122D;KHOJKI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +1122E;KHOJKI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +1122F;KHOJKI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +11230;KHOJKI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +11231;KHOJKI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +11232;KHOJKI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +11233;KHOJKI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +11234;KHOJKI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11235;KHOJKI SIGN VIRAMA;Mc;9;L;;;;;N;;;;; +11236;KHOJKI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +11237;KHOJKI SIGN SHADDA;Mn;0;NSM;;;;;N;;;;; +11238;KHOJKI DANDA;Po;0;L;;;;;N;;;;; +11239;KHOJKI DOUBLE DANDA;Po;0;L;;;;;N;;;;; +1123A;KHOJKI WORD SEPARATOR;Po;0;L;;;;;N;;;;; +1123B;KHOJKI SECTION MARK;Po;0;L;;;;;N;;;;; +1123C;KHOJKI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;; +1123D;KHOJKI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +1123E;KHOJKI SIGN SUKUN;Mn;0;NSM;;;;;N;;;;; +11280;MULTANI LETTER A;Lo;0;L;;;;;N;;;;; +11281;MULTANI LETTER I;Lo;0;L;;;;;N;;;;; +11282;MULTANI LETTER U;Lo;0;L;;;;;N;;;;; +11283;MULTANI LETTER E;Lo;0;L;;;;;N;;;;; +11284;MULTANI LETTER KA;Lo;0;L;;;;;N;;;;; +11285;MULTANI LETTER KHA;Lo;0;L;;;;;N;;;;; +11286;MULTANI LETTER GA;Lo;0;L;;;;;N;;;;; +11288;MULTANI LETTER GHA;Lo;0;L;;;;;N;;;;; +1128A;MULTANI LETTER CA;Lo;0;L;;;;;N;;;;; +1128B;MULTANI LETTER CHA;Lo;0;L;;;;;N;;;;; +1128C;MULTANI LETTER JA;Lo;0;L;;;;;N;;;;; +1128D;MULTANI LETTER JJA;Lo;0;L;;;;;N;;;;; +1128F;MULTANI LETTER NYA;Lo;0;L;;;;;N;;;;; +11290;MULTANI LETTER TTA;Lo;0;L;;;;;N;;;;; +11291;MULTANI LETTER TTHA;Lo;0;L;;;;;N;;;;; +11292;MULTANI LETTER DDA;Lo;0;L;;;;;N;;;;; +11293;MULTANI LETTER DDDA;Lo;0;L;;;;;N;;;;; +11294;MULTANI LETTER DDHA;Lo;0;L;;;;;N;;;;; +11295;MULTANI LETTER NNA;Lo;0;L;;;;;N;;;;; +11296;MULTANI LETTER TA;Lo;0;L;;;;;N;;;;; +11297;MULTANI LETTER THA;Lo;0;L;;;;;N;;;;; +11298;MULTANI LETTER DA;Lo;0;L;;;;;N;;;;; +11299;MULTANI LETTER DHA;Lo;0;L;;;;;N;;;;; +1129A;MULTANI LETTER NA;Lo;0;L;;;;;N;;;;; +1129B;MULTANI LETTER PA;Lo;0;L;;;;;N;;;;; +1129C;MULTANI LETTER PHA;Lo;0;L;;;;;N;;;;; +1129D;MULTANI LETTER BA;Lo;0;L;;;;;N;;;;; +1129F;MULTANI LETTER BHA;Lo;0;L;;;;;N;;;;; +112A0;MULTANI LETTER MA;Lo;0;L;;;;;N;;;;; +112A1;MULTANI LETTER YA;Lo;0;L;;;;;N;;;;; +112A2;MULTANI LETTER RA;Lo;0;L;;;;;N;;;;; +112A3;MULTANI LETTER LA;Lo;0;L;;;;;N;;;;; +112A4;MULTANI LETTER VA;Lo;0;L;;;;;N;;;;; +112A5;MULTANI LETTER SA;Lo;0;L;;;;;N;;;;; +112A6;MULTANI LETTER HA;Lo;0;L;;;;;N;;;;; +112A7;MULTANI LETTER RRA;Lo;0;L;;;;;N;;;;; +112A8;MULTANI LETTER RHA;Lo;0;L;;;;;N;;;;; +112A9;MULTANI SECTION MARK;Po;0;L;;;;;N;;;;; +112B0;KHUDAWADI LETTER A;Lo;0;L;;;;;N;;;;; +112B1;KHUDAWADI LETTER AA;Lo;0;L;;;;;N;;;;; +112B2;KHUDAWADI LETTER I;Lo;0;L;;;;;N;;;;; +112B3;KHUDAWADI LETTER II;Lo;0;L;;;;;N;;;;; +112B4;KHUDAWADI LETTER U;Lo;0;L;;;;;N;;;;; +112B5;KHUDAWADI LETTER UU;Lo;0;L;;;;;N;;;;; +112B6;KHUDAWADI LETTER E;Lo;0;L;;;;;N;;;;; +112B7;KHUDAWADI LETTER AI;Lo;0;L;;;;;N;;;;; +112B8;KHUDAWADI LETTER O;Lo;0;L;;;;;N;;;;; +112B9;KHUDAWADI LETTER AU;Lo;0;L;;;;;N;;;;; +112BA;KHUDAWADI LETTER KA;Lo;0;L;;;;;N;;;;; +112BB;KHUDAWADI LETTER KHA;Lo;0;L;;;;;N;;;;; +112BC;KHUDAWADI LETTER GA;Lo;0;L;;;;;N;;;;; +112BD;KHUDAWADI LETTER GGA;Lo;0;L;;;;;N;;;;; +112BE;KHUDAWADI LETTER GHA;Lo;0;L;;;;;N;;;;; +112BF;KHUDAWADI LETTER NGA;Lo;0;L;;;;;N;;;;; +112C0;KHUDAWADI LETTER CA;Lo;0;L;;;;;N;;;;; +112C1;KHUDAWADI LETTER CHA;Lo;0;L;;;;;N;;;;; +112C2;KHUDAWADI LETTER JA;Lo;0;L;;;;;N;;;;; +112C3;KHUDAWADI LETTER JJA;Lo;0;L;;;;;N;;;;; +112C4;KHUDAWADI LETTER JHA;Lo;0;L;;;;;N;;;;; +112C5;KHUDAWADI LETTER NYA;Lo;0;L;;;;;N;;;;; +112C6;KHUDAWADI LETTER TTA;Lo;0;L;;;;;N;;;;; +112C7;KHUDAWADI LETTER TTHA;Lo;0;L;;;;;N;;;;; +112C8;KHUDAWADI LETTER DDA;Lo;0;L;;;;;N;;;;; +112C9;KHUDAWADI LETTER DDDA;Lo;0;L;;;;;N;;;;; +112CA;KHUDAWADI LETTER RRA;Lo;0;L;;;;;N;;;;; +112CB;KHUDAWADI LETTER DDHA;Lo;0;L;;;;;N;;;;; +112CC;KHUDAWADI LETTER NNA;Lo;0;L;;;;;N;;;;; +112CD;KHUDAWADI LETTER TA;Lo;0;L;;;;;N;;;;; +112CE;KHUDAWADI LETTER THA;Lo;0;L;;;;;N;;;;; +112CF;KHUDAWADI LETTER DA;Lo;0;L;;;;;N;;;;; +112D0;KHUDAWADI LETTER DHA;Lo;0;L;;;;;N;;;;; +112D1;KHUDAWADI LETTER NA;Lo;0;L;;;;;N;;;;; +112D2;KHUDAWADI LETTER PA;Lo;0;L;;;;;N;;;;; +112D3;KHUDAWADI LETTER PHA;Lo;0;L;;;;;N;;;;; +112D4;KHUDAWADI LETTER BA;Lo;0;L;;;;;N;;;;; +112D5;KHUDAWADI LETTER BBA;Lo;0;L;;;;;N;;;;; +112D6;KHUDAWADI LETTER BHA;Lo;0;L;;;;;N;;;;; +112D7;KHUDAWADI LETTER MA;Lo;0;L;;;;;N;;;;; +112D8;KHUDAWADI LETTER YA;Lo;0;L;;;;;N;;;;; +112D9;KHUDAWADI LETTER RA;Lo;0;L;;;;;N;;;;; +112DA;KHUDAWADI LETTER LA;Lo;0;L;;;;;N;;;;; +112DB;KHUDAWADI LETTER VA;Lo;0;L;;;;;N;;;;; +112DC;KHUDAWADI LETTER SHA;Lo;0;L;;;;;N;;;;; +112DD;KHUDAWADI LETTER SA;Lo;0;L;;;;;N;;;;; +112DE;KHUDAWADI LETTER HA;Lo;0;L;;;;;N;;;;; +112DF;KHUDAWADI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +112E0;KHUDAWADI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +112E1;KHUDAWADI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +112E2;KHUDAWADI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +112E3;KHUDAWADI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +112E4;KHUDAWADI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +112E5;KHUDAWADI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +112E6;KHUDAWADI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +112E7;KHUDAWADI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +112E8;KHUDAWADI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +112E9;KHUDAWADI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +112EA;KHUDAWADI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +112F0;KHUDAWADI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +112F1;KHUDAWADI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +112F2;KHUDAWADI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +112F3;KHUDAWADI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +112F4;KHUDAWADI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +112F5;KHUDAWADI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +112F6;KHUDAWADI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +112F7;KHUDAWADI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +112F8;KHUDAWADI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +112F9;KHUDAWADI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +11300;GRANTHA SIGN COMBINING ANUSVARA ABOVE;Mn;0;NSM;;;;;N;;;;; +11301;GRANTHA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +11302;GRANTHA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +11303;GRANTHA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +11305;GRANTHA LETTER A;Lo;0;L;;;;;N;;;;; +11306;GRANTHA LETTER AA;Lo;0;L;;;;;N;;;;; +11307;GRANTHA LETTER I;Lo;0;L;;;;;N;;;;; +11308;GRANTHA LETTER II;Lo;0;L;;;;;N;;;;; +11309;GRANTHA LETTER U;Lo;0;L;;;;;N;;;;; +1130A;GRANTHA LETTER UU;Lo;0;L;;;;;N;;;;; +1130B;GRANTHA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +1130C;GRANTHA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +1130F;GRANTHA LETTER EE;Lo;0;L;;;;;N;;;;; +11310;GRANTHA LETTER AI;Lo;0;L;;;;;N;;;;; +11313;GRANTHA LETTER OO;Lo;0;L;;;;;N;;;;; +11314;GRANTHA LETTER AU;Lo;0;L;;;;;N;;;;; +11315;GRANTHA LETTER KA;Lo;0;L;;;;;N;;;;; +11316;GRANTHA LETTER KHA;Lo;0;L;;;;;N;;;;; +11317;GRANTHA LETTER GA;Lo;0;L;;;;;N;;;;; +11318;GRANTHA LETTER GHA;Lo;0;L;;;;;N;;;;; +11319;GRANTHA LETTER NGA;Lo;0;L;;;;;N;;;;; +1131A;GRANTHA LETTER CA;Lo;0;L;;;;;N;;;;; +1131B;GRANTHA LETTER CHA;Lo;0;L;;;;;N;;;;; +1131C;GRANTHA LETTER JA;Lo;0;L;;;;;N;;;;; +1131D;GRANTHA LETTER JHA;Lo;0;L;;;;;N;;;;; +1131E;GRANTHA LETTER NYA;Lo;0;L;;;;;N;;;;; +1131F;GRANTHA LETTER TTA;Lo;0;L;;;;;N;;;;; +11320;GRANTHA LETTER TTHA;Lo;0;L;;;;;N;;;;; +11321;GRANTHA LETTER DDA;Lo;0;L;;;;;N;;;;; +11322;GRANTHA LETTER DDHA;Lo;0;L;;;;;N;;;;; +11323;GRANTHA LETTER NNA;Lo;0;L;;;;;N;;;;; +11324;GRANTHA LETTER TA;Lo;0;L;;;;;N;;;;; +11325;GRANTHA LETTER THA;Lo;0;L;;;;;N;;;;; +11326;GRANTHA LETTER DA;Lo;0;L;;;;;N;;;;; +11327;GRANTHA LETTER DHA;Lo;0;L;;;;;N;;;;; +11328;GRANTHA LETTER NA;Lo;0;L;;;;;N;;;;; +1132A;GRANTHA LETTER PA;Lo;0;L;;;;;N;;;;; +1132B;GRANTHA LETTER PHA;Lo;0;L;;;;;N;;;;; +1132C;GRANTHA LETTER BA;Lo;0;L;;;;;N;;;;; +1132D;GRANTHA LETTER BHA;Lo;0;L;;;;;N;;;;; +1132E;GRANTHA LETTER MA;Lo;0;L;;;;;N;;;;; +1132F;GRANTHA LETTER YA;Lo;0;L;;;;;N;;;;; +11330;GRANTHA LETTER RA;Lo;0;L;;;;;N;;;;; +11332;GRANTHA LETTER LA;Lo;0;L;;;;;N;;;;; +11333;GRANTHA LETTER LLA;Lo;0;L;;;;;N;;;;; +11335;GRANTHA LETTER VA;Lo;0;L;;;;;N;;;;; +11336;GRANTHA LETTER SHA;Lo;0;L;;;;;N;;;;; +11337;GRANTHA LETTER SSA;Lo;0;L;;;;;N;;;;; +11338;GRANTHA LETTER SA;Lo;0;L;;;;;N;;;;; +11339;GRANTHA LETTER HA;Lo;0;L;;;;;N;;;;; +1133B;COMBINING BINDU BELOW;Mn;7;NSM;;;;;N;;;;; +1133C;GRANTHA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +1133D;GRANTHA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +1133E;GRANTHA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +1133F;GRANTHA VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +11340;GRANTHA VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +11341;GRANTHA VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +11342;GRANTHA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +11343;GRANTHA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; +11344;GRANTHA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; +11347;GRANTHA VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; +11348;GRANTHA VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +1134B;GRANTHA VOWEL SIGN OO;Mc;0;L;11347 1133E;;;;N;;;;; +1134C;GRANTHA VOWEL SIGN AU;Mc;0;L;11347 11357;;;;N;;;;; +1134D;GRANTHA SIGN VIRAMA;Mc;9;L;;;;;N;;;;; +11350;GRANTHA OM;Lo;0;L;;;;;N;;;;; +11357;GRANTHA AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +1135D;GRANTHA SIGN PLUTA;Lo;0;L;;;;;N;;;;; +1135E;GRANTHA LETTER VEDIC ANUSVARA;Lo;0;L;;;;;N;;;;; +1135F;GRANTHA LETTER VEDIC DOUBLE ANUSVARA;Lo;0;L;;;;;N;;;;; +11360;GRANTHA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +11361;GRANTHA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +11362;GRANTHA VOWEL SIGN VOCALIC L;Mc;0;L;;;;;N;;;;; +11363;GRANTHA VOWEL SIGN VOCALIC LL;Mc;0;L;;;;;N;;;;; +11366;COMBINING GRANTHA DIGIT ZERO;Mn;230;NSM;;;;;N;;;;; +11367;COMBINING GRANTHA DIGIT ONE;Mn;230;NSM;;;;;N;;;;; +11368;COMBINING GRANTHA DIGIT TWO;Mn;230;NSM;;;;;N;;;;; +11369;COMBINING GRANTHA DIGIT THREE;Mn;230;NSM;;;;;N;;;;; +1136A;COMBINING GRANTHA DIGIT FOUR;Mn;230;NSM;;;;;N;;;;; +1136B;COMBINING GRANTHA DIGIT FIVE;Mn;230;NSM;;;;;N;;;;; +1136C;COMBINING GRANTHA DIGIT SIX;Mn;230;NSM;;;;;N;;;;; +11370;COMBINING GRANTHA LETTER A;Mn;230;NSM;;;;;N;;;;; +11371;COMBINING GRANTHA LETTER KA;Mn;230;NSM;;;;;N;;;;; +11372;COMBINING GRANTHA LETTER NA;Mn;230;NSM;;;;;N;;;;; +11373;COMBINING GRANTHA LETTER VI;Mn;230;NSM;;;;;N;;;;; +11374;COMBINING GRANTHA LETTER PA;Mn;230;NSM;;;;;N;;;;; +11400;NEWA LETTER A;Lo;0;L;;;;;N;;;;; +11401;NEWA LETTER AA;Lo;0;L;;;;;N;;;;; +11402;NEWA LETTER I;Lo;0;L;;;;;N;;;;; +11403;NEWA LETTER II;Lo;0;L;;;;;N;;;;; +11404;NEWA LETTER U;Lo;0;L;;;;;N;;;;; +11405;NEWA LETTER UU;Lo;0;L;;;;;N;;;;; +11406;NEWA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +11407;NEWA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +11408;NEWA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +11409;NEWA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +1140A;NEWA LETTER E;Lo;0;L;;;;;N;;;;; +1140B;NEWA LETTER AI;Lo;0;L;;;;;N;;;;; +1140C;NEWA LETTER O;Lo;0;L;;;;;N;;;;; +1140D;NEWA LETTER AU;Lo;0;L;;;;;N;;;;; +1140E;NEWA LETTER KA;Lo;0;L;;;;;N;;;;; +1140F;NEWA LETTER KHA;Lo;0;L;;;;;N;;;;; +11410;NEWA LETTER GA;Lo;0;L;;;;;N;;;;; +11411;NEWA LETTER GHA;Lo;0;L;;;;;N;;;;; +11412;NEWA LETTER NGA;Lo;0;L;;;;;N;;;;; +11413;NEWA LETTER NGHA;Lo;0;L;;;;;N;;;;; +11414;NEWA LETTER CA;Lo;0;L;;;;;N;;;;; +11415;NEWA LETTER CHA;Lo;0;L;;;;;N;;;;; +11416;NEWA LETTER JA;Lo;0;L;;;;;N;;;;; +11417;NEWA LETTER JHA;Lo;0;L;;;;;N;;;;; +11418;NEWA LETTER NYA;Lo;0;L;;;;;N;;;;; +11419;NEWA LETTER NYHA;Lo;0;L;;;;;N;;;;; +1141A;NEWA LETTER TTA;Lo;0;L;;;;;N;;;;; +1141B;NEWA LETTER TTHA;Lo;0;L;;;;;N;;;;; +1141C;NEWA LETTER DDA;Lo;0;L;;;;;N;;;;; +1141D;NEWA LETTER DDHA;Lo;0;L;;;;;N;;;;; +1141E;NEWA LETTER NNA;Lo;0;L;;;;;N;;;;; +1141F;NEWA LETTER TA;Lo;0;L;;;;;N;;;;; +11420;NEWA LETTER THA;Lo;0;L;;;;;N;;;;; +11421;NEWA LETTER DA;Lo;0;L;;;;;N;;;;; +11422;NEWA LETTER DHA;Lo;0;L;;;;;N;;;;; +11423;NEWA LETTER NA;Lo;0;L;;;;;N;;;;; +11424;NEWA LETTER NHA;Lo;0;L;;;;;N;;;;; +11425;NEWA LETTER PA;Lo;0;L;;;;;N;;;;; +11426;NEWA LETTER PHA;Lo;0;L;;;;;N;;;;; +11427;NEWA LETTER BA;Lo;0;L;;;;;N;;;;; +11428;NEWA LETTER BHA;Lo;0;L;;;;;N;;;;; +11429;NEWA LETTER MA;Lo;0;L;;;;;N;;;;; +1142A;NEWA LETTER MHA;Lo;0;L;;;;;N;;;;; +1142B;NEWA LETTER YA;Lo;0;L;;;;;N;;;;; +1142C;NEWA LETTER RA;Lo;0;L;;;;;N;;;;; +1142D;NEWA LETTER RHA;Lo;0;L;;;;;N;;;;; +1142E;NEWA LETTER LA;Lo;0;L;;;;;N;;;;; +1142F;NEWA LETTER LHA;Lo;0;L;;;;;N;;;;; +11430;NEWA LETTER WA;Lo;0;L;;;;;N;;;;; +11431;NEWA LETTER SHA;Lo;0;L;;;;;N;;;;; +11432;NEWA LETTER SSA;Lo;0;L;;;;;N;;;;; +11433;NEWA LETTER SA;Lo;0;L;;;;;N;;;;; +11434;NEWA LETTER HA;Lo;0;L;;;;;N;;;;; +11435;NEWA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +11436;NEWA VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +11437;NEWA VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +11438;NEWA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +11439;NEWA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +1143A;NEWA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +1143B;NEWA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +1143C;NEWA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +1143D;NEWA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +1143E;NEWA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +1143F;NEWA VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +11440;NEWA VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +11441;NEWA VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +11442;NEWA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +11443;NEWA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +11444;NEWA SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11445;NEWA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +11446;NEWA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +11447;NEWA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +11448;NEWA SIGN FINAL ANUSVARA;Lo;0;L;;;;;N;;;;; +11449;NEWA OM;Lo;0;L;;;;;N;;;;; +1144A;NEWA SIDDHI;Lo;0;L;;;;;N;;;;; +1144B;NEWA DANDA;Po;0;L;;;;;N;;;;; +1144C;NEWA DOUBLE DANDA;Po;0;L;;;;;N;;;;; +1144D;NEWA COMMA;Po;0;L;;;;;N;;;;; +1144E;NEWA GAP FILLER;Po;0;L;;;;;N;;;;; +1144F;NEWA ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +11450;NEWA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +11451;NEWA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +11452;NEWA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +11453;NEWA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +11454;NEWA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +11455;NEWA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +11456;NEWA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +11457;NEWA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +11458;NEWA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +11459;NEWA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1145B;NEWA PLACEHOLDER MARK;Po;0;L;;;;;N;;;;; +1145D;NEWA INSERTION SIGN;Po;0;L;;;;;N;;;;; +1145E;NEWA SANDHI MARK;Mn;230;NSM;;;;;N;;;;; +1145F;NEWA LETTER VEDIC ANUSVARA;Lo;0;L;;;;;N;;;;; +11480;TIRHUTA ANJI;Lo;0;L;;;;;N;;;;; +11481;TIRHUTA LETTER A;Lo;0;L;;;;;N;;;;; +11482;TIRHUTA LETTER AA;Lo;0;L;;;;;N;;;;; +11483;TIRHUTA LETTER I;Lo;0;L;;;;;N;;;;; +11484;TIRHUTA LETTER II;Lo;0;L;;;;;N;;;;; +11485;TIRHUTA LETTER U;Lo;0;L;;;;;N;;;;; +11486;TIRHUTA LETTER UU;Lo;0;L;;;;;N;;;;; +11487;TIRHUTA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +11488;TIRHUTA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +11489;TIRHUTA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +1148A;TIRHUTA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +1148B;TIRHUTA LETTER E;Lo;0;L;;;;;N;;;;; +1148C;TIRHUTA LETTER AI;Lo;0;L;;;;;N;;;;; +1148D;TIRHUTA LETTER O;Lo;0;L;;;;;N;;;;; +1148E;TIRHUTA LETTER AU;Lo;0;L;;;;;N;;;;; +1148F;TIRHUTA LETTER KA;Lo;0;L;;;;;N;;;;; +11490;TIRHUTA LETTER KHA;Lo;0;L;;;;;N;;;;; +11491;TIRHUTA LETTER GA;Lo;0;L;;;;;N;;;;; +11492;TIRHUTA LETTER GHA;Lo;0;L;;;;;N;;;;; +11493;TIRHUTA LETTER NGA;Lo;0;L;;;;;N;;;;; +11494;TIRHUTA LETTER CA;Lo;0;L;;;;;N;;;;; +11495;TIRHUTA LETTER CHA;Lo;0;L;;;;;N;;;;; +11496;TIRHUTA LETTER JA;Lo;0;L;;;;;N;;;;; +11497;TIRHUTA LETTER JHA;Lo;0;L;;;;;N;;;;; +11498;TIRHUTA LETTER NYA;Lo;0;L;;;;;N;;;;; +11499;TIRHUTA LETTER TTA;Lo;0;L;;;;;N;;;;; +1149A;TIRHUTA LETTER TTHA;Lo;0;L;;;;;N;;;;; +1149B;TIRHUTA LETTER DDA;Lo;0;L;;;;;N;;;;; +1149C;TIRHUTA LETTER DDHA;Lo;0;L;;;;;N;;;;; +1149D;TIRHUTA LETTER NNA;Lo;0;L;;;;;N;;;;; +1149E;TIRHUTA LETTER TA;Lo;0;L;;;;;N;;;;; +1149F;TIRHUTA LETTER THA;Lo;0;L;;;;;N;;;;; +114A0;TIRHUTA LETTER DA;Lo;0;L;;;;;N;;;;; +114A1;TIRHUTA LETTER DHA;Lo;0;L;;;;;N;;;;; +114A2;TIRHUTA LETTER NA;Lo;0;L;;;;;N;;;;; +114A3;TIRHUTA LETTER PA;Lo;0;L;;;;;N;;;;; +114A4;TIRHUTA LETTER PHA;Lo;0;L;;;;;N;;;;; +114A5;TIRHUTA LETTER BA;Lo;0;L;;;;;N;;;;; +114A6;TIRHUTA LETTER BHA;Lo;0;L;;;;;N;;;;; +114A7;TIRHUTA LETTER MA;Lo;0;L;;;;;N;;;;; +114A8;TIRHUTA LETTER YA;Lo;0;L;;;;;N;;;;; +114A9;TIRHUTA LETTER RA;Lo;0;L;;;;;N;;;;; +114AA;TIRHUTA LETTER LA;Lo;0;L;;;;;N;;;;; +114AB;TIRHUTA LETTER VA;Lo;0;L;;;;;N;;;;; +114AC;TIRHUTA LETTER SHA;Lo;0;L;;;;;N;;;;; +114AD;TIRHUTA LETTER SSA;Lo;0;L;;;;;N;;;;; +114AE;TIRHUTA LETTER SA;Lo;0;L;;;;;N;;;;; +114AF;TIRHUTA LETTER HA;Lo;0;L;;;;;N;;;;; +114B0;TIRHUTA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +114B1;TIRHUTA VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +114B2;TIRHUTA VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +114B3;TIRHUTA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +114B4;TIRHUTA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +114B5;TIRHUTA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +114B6;TIRHUTA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +114B7;TIRHUTA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +114B8;TIRHUTA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +114B9;TIRHUTA VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +114BA;TIRHUTA VOWEL SIGN SHORT E;Mn;0;NSM;;;;;N;;;;; +114BB;TIRHUTA VOWEL SIGN AI;Mc;0;L;114B9 114BA;;;;N;;;;; +114BC;TIRHUTA VOWEL SIGN O;Mc;0;L;114B9 114B0;;;;N;;;;; +114BD;TIRHUTA VOWEL SIGN SHORT O;Mc;0;L;;;;;N;;;;; +114BE;TIRHUTA VOWEL SIGN AU;Mc;0;L;114B9 114BD;;;;N;;;;; +114BF;TIRHUTA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +114C0;TIRHUTA SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +114C1;TIRHUTA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +114C2;TIRHUTA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +114C3;TIRHUTA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +114C4;TIRHUTA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +114C5;TIRHUTA GVANG;Lo;0;L;;;;;N;;;;; +114C6;TIRHUTA ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +114C7;TIRHUTA OM;Lo;0;L;;;;;N;;;;; +114D0;TIRHUTA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +114D1;TIRHUTA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +114D2;TIRHUTA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +114D3;TIRHUTA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +114D4;TIRHUTA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +114D5;TIRHUTA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +114D6;TIRHUTA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +114D7;TIRHUTA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +114D8;TIRHUTA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +114D9;TIRHUTA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +11580;SIDDHAM LETTER A;Lo;0;L;;;;;N;;;;; +11581;SIDDHAM LETTER AA;Lo;0;L;;;;;N;;;;; +11582;SIDDHAM LETTER I;Lo;0;L;;;;;N;;;;; +11583;SIDDHAM LETTER II;Lo;0;L;;;;;N;;;;; +11584;SIDDHAM LETTER U;Lo;0;L;;;;;N;;;;; +11585;SIDDHAM LETTER UU;Lo;0;L;;;;;N;;;;; +11586;SIDDHAM LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +11587;SIDDHAM LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +11588;SIDDHAM LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +11589;SIDDHAM LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +1158A;SIDDHAM LETTER E;Lo;0;L;;;;;N;;;;; +1158B;SIDDHAM LETTER AI;Lo;0;L;;;;;N;;;;; +1158C;SIDDHAM LETTER O;Lo;0;L;;;;;N;;;;; +1158D;SIDDHAM LETTER AU;Lo;0;L;;;;;N;;;;; +1158E;SIDDHAM LETTER KA;Lo;0;L;;;;;N;;;;; +1158F;SIDDHAM LETTER KHA;Lo;0;L;;;;;N;;;;; +11590;SIDDHAM LETTER GA;Lo;0;L;;;;;N;;;;; +11591;SIDDHAM LETTER GHA;Lo;0;L;;;;;N;;;;; +11592;SIDDHAM LETTER NGA;Lo;0;L;;;;;N;;;;; +11593;SIDDHAM LETTER CA;Lo;0;L;;;;;N;;;;; +11594;SIDDHAM LETTER CHA;Lo;0;L;;;;;N;;;;; +11595;SIDDHAM LETTER JA;Lo;0;L;;;;;N;;;;; +11596;SIDDHAM LETTER JHA;Lo;0;L;;;;;N;;;;; +11597;SIDDHAM LETTER NYA;Lo;0;L;;;;;N;;;;; +11598;SIDDHAM LETTER TTA;Lo;0;L;;;;;N;;;;; +11599;SIDDHAM LETTER TTHA;Lo;0;L;;;;;N;;;;; +1159A;SIDDHAM LETTER DDA;Lo;0;L;;;;;N;;;;; +1159B;SIDDHAM LETTER DDHA;Lo;0;L;;;;;N;;;;; +1159C;SIDDHAM LETTER NNA;Lo;0;L;;;;;N;;;;; +1159D;SIDDHAM LETTER TA;Lo;0;L;;;;;N;;;;; +1159E;SIDDHAM LETTER THA;Lo;0;L;;;;;N;;;;; +1159F;SIDDHAM LETTER DA;Lo;0;L;;;;;N;;;;; +115A0;SIDDHAM LETTER DHA;Lo;0;L;;;;;N;;;;; +115A1;SIDDHAM LETTER NA;Lo;0;L;;;;;N;;;;; +115A2;SIDDHAM LETTER PA;Lo;0;L;;;;;N;;;;; +115A3;SIDDHAM LETTER PHA;Lo;0;L;;;;;N;;;;; +115A4;SIDDHAM LETTER BA;Lo;0;L;;;;;N;;;;; +115A5;SIDDHAM LETTER BHA;Lo;0;L;;;;;N;;;;; +115A6;SIDDHAM LETTER MA;Lo;0;L;;;;;N;;;;; +115A7;SIDDHAM LETTER YA;Lo;0;L;;;;;N;;;;; +115A8;SIDDHAM LETTER RA;Lo;0;L;;;;;N;;;;; +115A9;SIDDHAM LETTER LA;Lo;0;L;;;;;N;;;;; +115AA;SIDDHAM LETTER VA;Lo;0;L;;;;;N;;;;; +115AB;SIDDHAM LETTER SHA;Lo;0;L;;;;;N;;;;; +115AC;SIDDHAM LETTER SSA;Lo;0;L;;;;;N;;;;; +115AD;SIDDHAM LETTER SA;Lo;0;L;;;;;N;;;;; +115AE;SIDDHAM LETTER HA;Lo;0;L;;;;;N;;;;; +115AF;SIDDHAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +115B0;SIDDHAM VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +115B1;SIDDHAM VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +115B2;SIDDHAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +115B3;SIDDHAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +115B4;SIDDHAM VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +115B5;SIDDHAM VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +115B8;SIDDHAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +115B9;SIDDHAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +115BA;SIDDHAM VOWEL SIGN O;Mc;0;L;115B8 115AF;;;;N;;;;; +115BB;SIDDHAM VOWEL SIGN AU;Mc;0;L;115B9 115AF;;;;N;;;;; +115BC;SIDDHAM SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +115BD;SIDDHAM SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +115BE;SIDDHAM SIGN VISARGA;Mc;0;L;;;;;N;;;;; +115BF;SIDDHAM SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +115C0;SIDDHAM SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +115C1;SIDDHAM SIGN SIDDHAM;Po;0;L;;;;;N;;;;; +115C2;SIDDHAM DANDA;Po;0;L;;;;;N;;;;; +115C3;SIDDHAM DOUBLE DANDA;Po;0;L;;;;;N;;;;; +115C4;SIDDHAM SEPARATOR DOT;Po;0;L;;;;;N;;;;; +115C5;SIDDHAM SEPARATOR BAR;Po;0;L;;;;;N;;;;; +115C6;SIDDHAM REPETITION MARK-1;Po;0;L;;;;;N;;;;; +115C7;SIDDHAM REPETITION MARK-2;Po;0;L;;;;;N;;;;; +115C8;SIDDHAM REPETITION MARK-3;Po;0;L;;;;;N;;;;; +115C9;SIDDHAM END OF TEXT MARK;Po;0;L;;;;;N;;;;; +115CA;SIDDHAM SECTION MARK WITH TRIDENT AND U-SHAPED ORNAMENTS;Po;0;L;;;;;N;;;;; +115CB;SIDDHAM SECTION MARK WITH TRIDENT AND DOTTED CRESCENTS;Po;0;L;;;;;N;;;;; +115CC;SIDDHAM SECTION MARK WITH RAYS AND DOTTED CRESCENTS;Po;0;L;;;;;N;;;;; +115CD;SIDDHAM SECTION MARK WITH RAYS AND DOTTED DOUBLE CRESCENTS;Po;0;L;;;;;N;;;;; +115CE;SIDDHAM SECTION MARK WITH RAYS AND DOTTED TRIPLE CRESCENTS;Po;0;L;;;;;N;;;;; +115CF;SIDDHAM SECTION MARK DOUBLE RING;Po;0;L;;;;;N;;;;; +115D0;SIDDHAM SECTION MARK DOUBLE RING WITH RAYS;Po;0;L;;;;;N;;;;; +115D1;SIDDHAM SECTION MARK WITH DOUBLE CRESCENTS;Po;0;L;;;;;N;;;;; +115D2;SIDDHAM SECTION MARK WITH TRIPLE CRESCENTS;Po;0;L;;;;;N;;;;; +115D3;SIDDHAM SECTION MARK WITH QUADRUPLE CRESCENTS;Po;0;L;;;;;N;;;;; +115D4;SIDDHAM SECTION MARK WITH SEPTUPLE CRESCENTS;Po;0;L;;;;;N;;;;; +115D5;SIDDHAM SECTION MARK WITH CIRCLES AND RAYS;Po;0;L;;;;;N;;;;; +115D6;SIDDHAM SECTION MARK WITH CIRCLES AND TWO ENCLOSURES;Po;0;L;;;;;N;;;;; +115D7;SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES;Po;0;L;;;;;N;;;;; +115D8;SIDDHAM LETTER THREE-CIRCLE ALTERNATE I;Lo;0;L;;;;;N;;;;; +115D9;SIDDHAM LETTER TWO-CIRCLE ALTERNATE I;Lo;0;L;;;;;N;;;;; +115DA;SIDDHAM LETTER TWO-CIRCLE ALTERNATE II;Lo;0;L;;;;;N;;;;; +115DB;SIDDHAM LETTER ALTERNATE U;Lo;0;L;;;;;N;;;;; +115DC;SIDDHAM VOWEL SIGN ALTERNATE U;Mn;0;NSM;;;;;N;;;;; +115DD;SIDDHAM VOWEL SIGN ALTERNATE UU;Mn;0;NSM;;;;;N;;;;; +11600;MODI LETTER A;Lo;0;L;;;;;N;;;;; +11601;MODI LETTER AA;Lo;0;L;;;;;N;;;;; +11602;MODI LETTER I;Lo;0;L;;;;;N;;;;; +11603;MODI LETTER II;Lo;0;L;;;;;N;;;;; +11604;MODI LETTER U;Lo;0;L;;;;;N;;;;; +11605;MODI LETTER UU;Lo;0;L;;;;;N;;;;; +11606;MODI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +11607;MODI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +11608;MODI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +11609;MODI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +1160A;MODI LETTER E;Lo;0;L;;;;;N;;;;; +1160B;MODI LETTER AI;Lo;0;L;;;;;N;;;;; +1160C;MODI LETTER O;Lo;0;L;;;;;N;;;;; +1160D;MODI LETTER AU;Lo;0;L;;;;;N;;;;; +1160E;MODI LETTER KA;Lo;0;L;;;;;N;;;;; +1160F;MODI LETTER KHA;Lo;0;L;;;;;N;;;;; +11610;MODI LETTER GA;Lo;0;L;;;;;N;;;;; +11611;MODI LETTER GHA;Lo;0;L;;;;;N;;;;; +11612;MODI LETTER NGA;Lo;0;L;;;;;N;;;;; +11613;MODI LETTER CA;Lo;0;L;;;;;N;;;;; +11614;MODI LETTER CHA;Lo;0;L;;;;;N;;;;; +11615;MODI LETTER JA;Lo;0;L;;;;;N;;;;; +11616;MODI LETTER JHA;Lo;0;L;;;;;N;;;;; +11617;MODI LETTER NYA;Lo;0;L;;;;;N;;;;; +11618;MODI LETTER TTA;Lo;0;L;;;;;N;;;;; +11619;MODI LETTER TTHA;Lo;0;L;;;;;N;;;;; +1161A;MODI LETTER DDA;Lo;0;L;;;;;N;;;;; +1161B;MODI LETTER DDHA;Lo;0;L;;;;;N;;;;; +1161C;MODI LETTER NNA;Lo;0;L;;;;;N;;;;; +1161D;MODI LETTER TA;Lo;0;L;;;;;N;;;;; +1161E;MODI LETTER THA;Lo;0;L;;;;;N;;;;; +1161F;MODI LETTER DA;Lo;0;L;;;;;N;;;;; +11620;MODI LETTER DHA;Lo;0;L;;;;;N;;;;; +11621;MODI LETTER NA;Lo;0;L;;;;;N;;;;; +11622;MODI LETTER PA;Lo;0;L;;;;;N;;;;; +11623;MODI LETTER PHA;Lo;0;L;;;;;N;;;;; +11624;MODI LETTER BA;Lo;0;L;;;;;N;;;;; +11625;MODI LETTER BHA;Lo;0;L;;;;;N;;;;; +11626;MODI LETTER MA;Lo;0;L;;;;;N;;;;; +11627;MODI LETTER YA;Lo;0;L;;;;;N;;;;; +11628;MODI LETTER RA;Lo;0;L;;;;;N;;;;; +11629;MODI LETTER LA;Lo;0;L;;;;;N;;;;; +1162A;MODI LETTER VA;Lo;0;L;;;;;N;;;;; +1162B;MODI LETTER SHA;Lo;0;L;;;;;N;;;;; +1162C;MODI LETTER SSA;Lo;0;L;;;;;N;;;;; +1162D;MODI LETTER SA;Lo;0;L;;;;;N;;;;; +1162E;MODI LETTER HA;Lo;0;L;;;;;N;;;;; +1162F;MODI LETTER LLA;Lo;0;L;;;;;N;;;;; +11630;MODI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +11631;MODI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +11632;MODI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +11633;MODI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +11634;MODI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +11635;MODI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +11636;MODI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +11637;MODI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +11638;MODI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +11639;MODI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +1163A;MODI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +1163B;MODI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +1163C;MODI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +1163D;MODI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +1163E;MODI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +1163F;MODI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +11640;MODI SIGN ARDHACANDRA;Mn;0;NSM;;;;;N;;;;; +11641;MODI DANDA;Po;0;L;;;;;N;;;;; +11642;MODI DOUBLE DANDA;Po;0;L;;;;;N;;;;; +11643;MODI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +11644;MODI SIGN HUVA;Lo;0;L;;;;;N;;;;; +11650;MODI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +11651;MODI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +11652;MODI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +11653;MODI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +11654;MODI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +11655;MODI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +11656;MODI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +11657;MODI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +11658;MODI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +11659;MODI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +11660;MONGOLIAN BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;; +11661;MONGOLIAN ROTATED BIRGA;Po;0;ON;;;;;N;;;;; +11662;MONGOLIAN DOUBLE BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;; +11663;MONGOLIAN TRIPLE BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;; +11664;MONGOLIAN BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;; +11665;MONGOLIAN ROTATED BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;; +11666;MONGOLIAN ROTATED BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;; +11667;MONGOLIAN INVERTED BIRGA;Po;0;ON;;;;;N;;;;; +11668;MONGOLIAN INVERTED BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;; +11669;MONGOLIAN SWIRL BIRGA;Po;0;ON;;;;;N;;;;; +1166A;MONGOLIAN SWIRL BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;; +1166B;MONGOLIAN SWIRL BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;; +1166C;MONGOLIAN TURNED SWIRL BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;; +11680;TAKRI LETTER A;Lo;0;L;;;;;N;;;;; +11681;TAKRI LETTER AA;Lo;0;L;;;;;N;;;;; +11682;TAKRI LETTER I;Lo;0;L;;;;;N;;;;; +11683;TAKRI LETTER II;Lo;0;L;;;;;N;;;;; +11684;TAKRI LETTER U;Lo;0;L;;;;;N;;;;; +11685;TAKRI LETTER UU;Lo;0;L;;;;;N;;;;; +11686;TAKRI LETTER E;Lo;0;L;;;;;N;;;;; +11687;TAKRI LETTER AI;Lo;0;L;;;;;N;;;;; +11688;TAKRI LETTER O;Lo;0;L;;;;;N;;;;; +11689;TAKRI LETTER AU;Lo;0;L;;;;;N;;;;; +1168A;TAKRI LETTER KA;Lo;0;L;;;;;N;;;;; +1168B;TAKRI LETTER KHA;Lo;0;L;;;;;N;;;;; +1168C;TAKRI LETTER GA;Lo;0;L;;;;;N;;;;; +1168D;TAKRI LETTER GHA;Lo;0;L;;;;;N;;;;; +1168E;TAKRI LETTER NGA;Lo;0;L;;;;;N;;;;; +1168F;TAKRI LETTER CA;Lo;0;L;;;;;N;;;;; +11690;TAKRI LETTER CHA;Lo;0;L;;;;;N;;;;; +11691;TAKRI LETTER JA;Lo;0;L;;;;;N;;;;; +11692;TAKRI LETTER JHA;Lo;0;L;;;;;N;;;;; +11693;TAKRI LETTER NYA;Lo;0;L;;;;;N;;;;; +11694;TAKRI LETTER TTA;Lo;0;L;;;;;N;;;;; +11695;TAKRI LETTER TTHA;Lo;0;L;;;;;N;;;;; +11696;TAKRI LETTER DDA;Lo;0;L;;;;;N;;;;; +11697;TAKRI LETTER DDHA;Lo;0;L;;;;;N;;;;; +11698;TAKRI LETTER NNA;Lo;0;L;;;;;N;;;;; +11699;TAKRI LETTER TA;Lo;0;L;;;;;N;;;;; +1169A;TAKRI LETTER THA;Lo;0;L;;;;;N;;;;; +1169B;TAKRI LETTER DA;Lo;0;L;;;;;N;;;;; +1169C;TAKRI LETTER DHA;Lo;0;L;;;;;N;;;;; +1169D;TAKRI LETTER NA;Lo;0;L;;;;;N;;;;; +1169E;TAKRI LETTER PA;Lo;0;L;;;;;N;;;;; +1169F;TAKRI LETTER PHA;Lo;0;L;;;;;N;;;;; +116A0;TAKRI LETTER BA;Lo;0;L;;;;;N;;;;; +116A1;TAKRI LETTER BHA;Lo;0;L;;;;;N;;;;; +116A2;TAKRI LETTER MA;Lo;0;L;;;;;N;;;;; +116A3;TAKRI LETTER YA;Lo;0;L;;;;;N;;;;; +116A4;TAKRI LETTER RA;Lo;0;L;;;;;N;;;;; +116A5;TAKRI LETTER LA;Lo;0;L;;;;;N;;;;; +116A6;TAKRI LETTER VA;Lo;0;L;;;;;N;;;;; +116A7;TAKRI LETTER SHA;Lo;0;L;;;;;N;;;;; +116A8;TAKRI LETTER SA;Lo;0;L;;;;;N;;;;; +116A9;TAKRI LETTER HA;Lo;0;L;;;;;N;;;;; +116AA;TAKRI LETTER RRA;Lo;0;L;;;;;N;;;;; +116AB;TAKRI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +116AC;TAKRI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +116AD;TAKRI VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;; +116AE;TAKRI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +116AF;TAKRI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +116B0;TAKRI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +116B1;TAKRI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +116B2;TAKRI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +116B3;TAKRI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +116B4;TAKRI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +116B5;TAKRI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +116B6;TAKRI SIGN VIRAMA;Mc;9;L;;;;;N;;;;; +116B7;TAKRI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +116B8;TAKRI LETTER ARCHAIC KHA;Lo;0;L;;;;;N;;;;; +116C0;TAKRI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +116C1;TAKRI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +116C2;TAKRI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +116C3;TAKRI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +116C4;TAKRI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +116C5;TAKRI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +116C6;TAKRI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +116C7;TAKRI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +116C8;TAKRI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +116C9;TAKRI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +11700;AHOM LETTER KA;Lo;0;L;;;;;N;;;;; +11701;AHOM LETTER KHA;Lo;0;L;;;;;N;;;;; +11702;AHOM LETTER NGA;Lo;0;L;;;;;N;;;;; +11703;AHOM LETTER NA;Lo;0;L;;;;;N;;;;; +11704;AHOM LETTER TA;Lo;0;L;;;;;N;;;;; +11705;AHOM LETTER ALTERNATE TA;Lo;0;L;;;;;N;;;;; +11706;AHOM LETTER PA;Lo;0;L;;;;;N;;;;; +11707;AHOM LETTER PHA;Lo;0;L;;;;;N;;;;; +11708;AHOM LETTER BA;Lo;0;L;;;;;N;;;;; +11709;AHOM LETTER MA;Lo;0;L;;;;;N;;;;; +1170A;AHOM LETTER JA;Lo;0;L;;;;;N;;;;; +1170B;AHOM LETTER CHA;Lo;0;L;;;;;N;;;;; +1170C;AHOM LETTER THA;Lo;0;L;;;;;N;;;;; +1170D;AHOM LETTER RA;Lo;0;L;;;;;N;;;;; +1170E;AHOM LETTER LA;Lo;0;L;;;;;N;;;;; +1170F;AHOM LETTER SA;Lo;0;L;;;;;N;;;;; +11710;AHOM LETTER NYA;Lo;0;L;;;;;N;;;;; +11711;AHOM LETTER HA;Lo;0;L;;;;;N;;;;; +11712;AHOM LETTER A;Lo;0;L;;;;;N;;;;; +11713;AHOM LETTER DA;Lo;0;L;;;;;N;;;;; +11714;AHOM LETTER DHA;Lo;0;L;;;;;N;;;;; +11715;AHOM LETTER GA;Lo;0;L;;;;;N;;;;; +11716;AHOM LETTER ALTERNATE GA;Lo;0;L;;;;;N;;;;; +11717;AHOM LETTER GHA;Lo;0;L;;;;;N;;;;; +11718;AHOM LETTER BHA;Lo;0;L;;;;;N;;;;; +11719;AHOM LETTER JHA;Lo;0;L;;;;;N;;;;; +1171A;AHOM LETTER ALTERNATE BA;Lo;0;L;;;;;N;;;;; +1171D;AHOM CONSONANT SIGN MEDIAL LA;Mn;0;NSM;;;;;N;;;;; +1171E;AHOM CONSONANT SIGN MEDIAL RA;Mn;0;NSM;;;;;N;;;;; +1171F;AHOM CONSONANT SIGN MEDIAL LIGATING RA;Mn;0;NSM;;;;;N;;;;; +11720;AHOM VOWEL SIGN A;Mc;0;L;;;;;N;;;;; +11721;AHOM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +11722;AHOM VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +11723;AHOM VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +11724;AHOM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +11725;AHOM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +11726;AHOM VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +11727;AHOM VOWEL SIGN AW;Mn;0;NSM;;;;;N;;;;; +11728;AHOM VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +11729;AHOM VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +1172A;AHOM VOWEL SIGN AM;Mn;0;NSM;;;;;N;;;;; +1172B;AHOM SIGN KILLER;Mn;9;NSM;;;;;N;;;;; +11730;AHOM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +11731;AHOM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +11732;AHOM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +11733;AHOM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +11734;AHOM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +11735;AHOM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +11736;AHOM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +11737;AHOM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +11738;AHOM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +11739;AHOM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1173A;AHOM NUMBER TEN;No;0;L;;;;10;N;;;;; +1173B;AHOM NUMBER TWENTY;No;0;L;;;;20;N;;;;; +1173C;AHOM SIGN SMALL SECTION;Po;0;L;;;;;N;;;;; +1173D;AHOM SIGN SECTION;Po;0;L;;;;;N;;;;; +1173E;AHOM SIGN RULAI;Po;0;L;;;;;N;;;;; +1173F;AHOM SYMBOL VI;So;0;L;;;;;N;;;;; +11800;DOGRA LETTER A;Lo;0;L;;;;;N;;;;; +11801;DOGRA LETTER AA;Lo;0;L;;;;;N;;;;; +11802;DOGRA LETTER I;Lo;0;L;;;;;N;;;;; +11803;DOGRA LETTER II;Lo;0;L;;;;;N;;;;; +11804;DOGRA LETTER U;Lo;0;L;;;;;N;;;;; +11805;DOGRA LETTER UU;Lo;0;L;;;;;N;;;;; +11806;DOGRA LETTER E;Lo;0;L;;;;;N;;;;; +11807;DOGRA LETTER AI;Lo;0;L;;;;;N;;;;; +11808;DOGRA LETTER O;Lo;0;L;;;;;N;;;;; +11809;DOGRA LETTER AU;Lo;0;L;;;;;N;;;;; +1180A;DOGRA LETTER KA;Lo;0;L;;;;;N;;;;; +1180B;DOGRA LETTER KHA;Lo;0;L;;;;;N;;;;; +1180C;DOGRA LETTER GA;Lo;0;L;;;;;N;;;;; +1180D;DOGRA LETTER GHA;Lo;0;L;;;;;N;;;;; +1180E;DOGRA LETTER NGA;Lo;0;L;;;;;N;;;;; +1180F;DOGRA LETTER CA;Lo;0;L;;;;;N;;;;; +11810;DOGRA LETTER CHA;Lo;0;L;;;;;N;;;;; +11811;DOGRA LETTER JA;Lo;0;L;;;;;N;;;;; +11812;DOGRA LETTER JHA;Lo;0;L;;;;;N;;;;; +11813;DOGRA LETTER NYA;Lo;0;L;;;;;N;;;;; +11814;DOGRA LETTER TTA;Lo;0;L;;;;;N;;;;; +11815;DOGRA LETTER TTHA;Lo;0;L;;;;;N;;;;; +11816;DOGRA LETTER DDA;Lo;0;L;;;;;N;;;;; +11817;DOGRA LETTER DDHA;Lo;0;L;;;;;N;;;;; +11818;DOGRA LETTER NNA;Lo;0;L;;;;;N;;;;; +11819;DOGRA LETTER TA;Lo;0;L;;;;;N;;;;; +1181A;DOGRA LETTER THA;Lo;0;L;;;;;N;;;;; +1181B;DOGRA LETTER DA;Lo;0;L;;;;;N;;;;; +1181C;DOGRA LETTER DHA;Lo;0;L;;;;;N;;;;; +1181D;DOGRA LETTER NA;Lo;0;L;;;;;N;;;;; +1181E;DOGRA LETTER PA;Lo;0;L;;;;;N;;;;; +1181F;DOGRA LETTER PHA;Lo;0;L;;;;;N;;;;; +11820;DOGRA LETTER BA;Lo;0;L;;;;;N;;;;; +11821;DOGRA LETTER BHA;Lo;0;L;;;;;N;;;;; +11822;DOGRA LETTER MA;Lo;0;L;;;;;N;;;;; +11823;DOGRA LETTER YA;Lo;0;L;;;;;N;;;;; +11824;DOGRA LETTER RA;Lo;0;L;;;;;N;;;;; +11825;DOGRA LETTER LA;Lo;0;L;;;;;N;;;;; +11826;DOGRA LETTER VA;Lo;0;L;;;;;N;;;;; +11827;DOGRA LETTER SHA;Lo;0;L;;;;;N;;;;; +11828;DOGRA LETTER SSA;Lo;0;L;;;;;N;;;;; +11829;DOGRA LETTER SA;Lo;0;L;;;;;N;;;;; +1182A;DOGRA LETTER HA;Lo;0;L;;;;;N;;;;; +1182B;DOGRA LETTER RRA;Lo;0;L;;;;;N;;;;; +1182C;DOGRA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +1182D;DOGRA VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +1182E;DOGRA VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +1182F;DOGRA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +11830;DOGRA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +11831;DOGRA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +11832;DOGRA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +11833;DOGRA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +11834;DOGRA VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +11835;DOGRA VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +11836;DOGRA VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +11837;DOGRA SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11838;DOGRA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +11839;DOGRA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +1183A;DOGRA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +1183B;DOGRA ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +118A0;WARANG CITI CAPITAL LETTER NGAA;Lu;0;L;;;;;N;;;;118C0; +118A1;WARANG CITI CAPITAL LETTER A;Lu;0;L;;;;;N;;;;118C1; +118A2;WARANG CITI CAPITAL LETTER WI;Lu;0;L;;;;;N;;;;118C2; +118A3;WARANG CITI CAPITAL LETTER YU;Lu;0;L;;;;;N;;;;118C3; +118A4;WARANG CITI CAPITAL LETTER YA;Lu;0;L;;;;;N;;;;118C4; +118A5;WARANG CITI CAPITAL LETTER YO;Lu;0;L;;;;;N;;;;118C5; +118A6;WARANG CITI CAPITAL LETTER II;Lu;0;L;;;;;N;;;;118C6; +118A7;WARANG CITI CAPITAL LETTER UU;Lu;0;L;;;;;N;;;;118C7; +118A8;WARANG CITI CAPITAL LETTER E;Lu;0;L;;;;;N;;;;118C8; +118A9;WARANG CITI CAPITAL LETTER O;Lu;0;L;;;;;N;;;;118C9; +118AA;WARANG CITI CAPITAL LETTER ANG;Lu;0;L;;;;;N;;;;118CA; +118AB;WARANG CITI CAPITAL LETTER GA;Lu;0;L;;;;;N;;;;118CB; +118AC;WARANG CITI CAPITAL LETTER KO;Lu;0;L;;;;;N;;;;118CC; +118AD;WARANG CITI CAPITAL LETTER ENY;Lu;0;L;;;;;N;;;;118CD; +118AE;WARANG CITI CAPITAL LETTER YUJ;Lu;0;L;;;;;N;;;;118CE; +118AF;WARANG CITI CAPITAL LETTER UC;Lu;0;L;;;;;N;;;;118CF; +118B0;WARANG CITI CAPITAL LETTER ENN;Lu;0;L;;;;;N;;;;118D0; +118B1;WARANG CITI CAPITAL LETTER ODD;Lu;0;L;;;;;N;;;;118D1; +118B2;WARANG CITI CAPITAL LETTER TTE;Lu;0;L;;;;;N;;;;118D2; +118B3;WARANG CITI CAPITAL LETTER NUNG;Lu;0;L;;;;;N;;;;118D3; +118B4;WARANG CITI CAPITAL LETTER DA;Lu;0;L;;;;;N;;;;118D4; +118B5;WARANG CITI CAPITAL LETTER AT;Lu;0;L;;;;;N;;;;118D5; +118B6;WARANG CITI CAPITAL LETTER AM;Lu;0;L;;;;;N;;;;118D6; +118B7;WARANG CITI CAPITAL LETTER BU;Lu;0;L;;;;;N;;;;118D7; +118B8;WARANG CITI CAPITAL LETTER PU;Lu;0;L;;;;;N;;;;118D8; +118B9;WARANG CITI CAPITAL LETTER HIYO;Lu;0;L;;;;;N;;;;118D9; +118BA;WARANG CITI CAPITAL LETTER HOLO;Lu;0;L;;;;;N;;;;118DA; +118BB;WARANG CITI CAPITAL LETTER HORR;Lu;0;L;;;;;N;;;;118DB; +118BC;WARANG CITI CAPITAL LETTER HAR;Lu;0;L;;;;;N;;;;118DC; +118BD;WARANG CITI CAPITAL LETTER SSUU;Lu;0;L;;;;;N;;;;118DD; +118BE;WARANG CITI CAPITAL LETTER SII;Lu;0;L;;;;;N;;;;118DE; +118BF;WARANG CITI CAPITAL LETTER VIYO;Lu;0;L;;;;;N;;;;118DF; +118C0;WARANG CITI SMALL LETTER NGAA;Ll;0;L;;;;;N;;;118A0;;118A0 +118C1;WARANG CITI SMALL LETTER A;Ll;0;L;;;;;N;;;118A1;;118A1 +118C2;WARANG CITI SMALL LETTER WI;Ll;0;L;;;;;N;;;118A2;;118A2 +118C3;WARANG CITI SMALL LETTER YU;Ll;0;L;;;;;N;;;118A3;;118A3 +118C4;WARANG CITI SMALL LETTER YA;Ll;0;L;;;;;N;;;118A4;;118A4 +118C5;WARANG CITI SMALL LETTER YO;Ll;0;L;;;;;N;;;118A5;;118A5 +118C6;WARANG CITI SMALL LETTER II;Ll;0;L;;;;;N;;;118A6;;118A6 +118C7;WARANG CITI SMALL LETTER UU;Ll;0;L;;;;;N;;;118A7;;118A7 +118C8;WARANG CITI SMALL LETTER E;Ll;0;L;;;;;N;;;118A8;;118A8 +118C9;WARANG CITI SMALL LETTER O;Ll;0;L;;;;;N;;;118A9;;118A9 +118CA;WARANG CITI SMALL LETTER ANG;Ll;0;L;;;;;N;;;118AA;;118AA +118CB;WARANG CITI SMALL LETTER GA;Ll;0;L;;;;;N;;;118AB;;118AB +118CC;WARANG CITI SMALL LETTER KO;Ll;0;L;;;;;N;;;118AC;;118AC +118CD;WARANG CITI SMALL LETTER ENY;Ll;0;L;;;;;N;;;118AD;;118AD +118CE;WARANG CITI SMALL LETTER YUJ;Ll;0;L;;;;;N;;;118AE;;118AE +118CF;WARANG CITI SMALL LETTER UC;Ll;0;L;;;;;N;;;118AF;;118AF +118D0;WARANG CITI SMALL LETTER ENN;Ll;0;L;;;;;N;;;118B0;;118B0 +118D1;WARANG CITI SMALL LETTER ODD;Ll;0;L;;;;;N;;;118B1;;118B1 +118D2;WARANG CITI SMALL LETTER TTE;Ll;0;L;;;;;N;;;118B2;;118B2 +118D3;WARANG CITI SMALL LETTER NUNG;Ll;0;L;;;;;N;;;118B3;;118B3 +118D4;WARANG CITI SMALL LETTER DA;Ll;0;L;;;;;N;;;118B4;;118B4 +118D5;WARANG CITI SMALL LETTER AT;Ll;0;L;;;;;N;;;118B5;;118B5 +118D6;WARANG CITI SMALL LETTER AM;Ll;0;L;;;;;N;;;118B6;;118B6 +118D7;WARANG CITI SMALL LETTER BU;Ll;0;L;;;;;N;;;118B7;;118B7 +118D8;WARANG CITI SMALL LETTER PU;Ll;0;L;;;;;N;;;118B8;;118B8 +118D9;WARANG CITI SMALL LETTER HIYO;Ll;0;L;;;;;N;;;118B9;;118B9 +118DA;WARANG CITI SMALL LETTER HOLO;Ll;0;L;;;;;N;;;118BA;;118BA +118DB;WARANG CITI SMALL LETTER HORR;Ll;0;L;;;;;N;;;118BB;;118BB +118DC;WARANG CITI SMALL LETTER HAR;Ll;0;L;;;;;N;;;118BC;;118BC +118DD;WARANG CITI SMALL LETTER SSUU;Ll;0;L;;;;;N;;;118BD;;118BD +118DE;WARANG CITI SMALL LETTER SII;Ll;0;L;;;;;N;;;118BE;;118BE +118DF;WARANG CITI SMALL LETTER VIYO;Ll;0;L;;;;;N;;;118BF;;118BF +118E0;WARANG CITI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +118E1;WARANG CITI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +118E2;WARANG CITI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +118E3;WARANG CITI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +118E4;WARANG CITI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +118E5;WARANG CITI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +118E6;WARANG CITI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +118E7;WARANG CITI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +118E8;WARANG CITI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +118E9;WARANG CITI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +118EA;WARANG CITI NUMBER TEN;No;0;L;;;;10;N;;;;; +118EB;WARANG CITI NUMBER TWENTY;No;0;L;;;;20;N;;;;; +118EC;WARANG CITI NUMBER THIRTY;No;0;L;;;;30;N;;;;; +118ED;WARANG CITI NUMBER FORTY;No;0;L;;;;40;N;;;;; +118EE;WARANG CITI NUMBER FIFTY;No;0;L;;;;50;N;;;;; +118EF;WARANG CITI NUMBER SIXTY;No;0;L;;;;60;N;;;;; +118F0;WARANG CITI NUMBER SEVENTY;No;0;L;;;;70;N;;;;; +118F1;WARANG CITI NUMBER EIGHTY;No;0;L;;;;80;N;;;;; +118F2;WARANG CITI NUMBER NINETY;No;0;L;;;;90;N;;;;; +118FF;WARANG CITI OM;Lo;0;L;;;;;N;;;;; +119A0;NANDINAGARI LETTER A;Lo;0;L;;;;;N;;;;; +119A1;NANDINAGARI LETTER AA;Lo;0;L;;;;;N;;;;; +119A2;NANDINAGARI LETTER I;Lo;0;L;;;;;N;;;;; +119A3;NANDINAGARI LETTER II;Lo;0;L;;;;;N;;;;; +119A4;NANDINAGARI LETTER U;Lo;0;L;;;;;N;;;;; +119A5;NANDINAGARI LETTER UU;Lo;0;L;;;;;N;;;;; +119A6;NANDINAGARI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +119A7;NANDINAGARI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +119AA;NANDINAGARI LETTER E;Lo;0;L;;;;;N;;;;; +119AB;NANDINAGARI LETTER AI;Lo;0;L;;;;;N;;;;; +119AC;NANDINAGARI LETTER O;Lo;0;L;;;;;N;;;;; +119AD;NANDINAGARI LETTER AU;Lo;0;L;;;;;N;;;;; +119AE;NANDINAGARI LETTER KA;Lo;0;L;;;;;N;;;;; +119AF;NANDINAGARI LETTER KHA;Lo;0;L;;;;;N;;;;; +119B0;NANDINAGARI LETTER GA;Lo;0;L;;;;;N;;;;; +119B1;NANDINAGARI LETTER GHA;Lo;0;L;;;;;N;;;;; +119B2;NANDINAGARI LETTER NGA;Lo;0;L;;;;;N;;;;; +119B3;NANDINAGARI LETTER CA;Lo;0;L;;;;;N;;;;; +119B4;NANDINAGARI LETTER CHA;Lo;0;L;;;;;N;;;;; +119B5;NANDINAGARI LETTER JA;Lo;0;L;;;;;N;;;;; +119B6;NANDINAGARI LETTER JHA;Lo;0;L;;;;;N;;;;; +119B7;NANDINAGARI LETTER NYA;Lo;0;L;;;;;N;;;;; +119B8;NANDINAGARI LETTER TTA;Lo;0;L;;;;;N;;;;; +119B9;NANDINAGARI LETTER TTHA;Lo;0;L;;;;;N;;;;; +119BA;NANDINAGARI LETTER DDA;Lo;0;L;;;;;N;;;;; +119BB;NANDINAGARI LETTER DDHA;Lo;0;L;;;;;N;;;;; +119BC;NANDINAGARI LETTER NNA;Lo;0;L;;;;;N;;;;; +119BD;NANDINAGARI LETTER TA;Lo;0;L;;;;;N;;;;; +119BE;NANDINAGARI LETTER THA;Lo;0;L;;;;;N;;;;; +119BF;NANDINAGARI LETTER DA;Lo;0;L;;;;;N;;;;; +119C0;NANDINAGARI LETTER DHA;Lo;0;L;;;;;N;;;;; +119C1;NANDINAGARI LETTER NA;Lo;0;L;;;;;N;;;;; +119C2;NANDINAGARI LETTER PA;Lo;0;L;;;;;N;;;;; +119C3;NANDINAGARI LETTER PHA;Lo;0;L;;;;;N;;;;; +119C4;NANDINAGARI LETTER BA;Lo;0;L;;;;;N;;;;; +119C5;NANDINAGARI LETTER BHA;Lo;0;L;;;;;N;;;;; +119C6;NANDINAGARI LETTER MA;Lo;0;L;;;;;N;;;;; +119C7;NANDINAGARI LETTER YA;Lo;0;L;;;;;N;;;;; +119C8;NANDINAGARI LETTER RA;Lo;0;L;;;;;N;;;;; +119C9;NANDINAGARI LETTER LA;Lo;0;L;;;;;N;;;;; +119CA;NANDINAGARI LETTER VA;Lo;0;L;;;;;N;;;;; +119CB;NANDINAGARI LETTER SHA;Lo;0;L;;;;;N;;;;; +119CC;NANDINAGARI LETTER SSA;Lo;0;L;;;;;N;;;;; +119CD;NANDINAGARI LETTER SA;Lo;0;L;;;;;N;;;;; +119CE;NANDINAGARI LETTER HA;Lo;0;L;;;;;N;;;;; +119CF;NANDINAGARI LETTER LLA;Lo;0;L;;;;;N;;;;; +119D0;NANDINAGARI LETTER RRA;Lo;0;L;;;;;N;;;;; +119D1;NANDINAGARI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +119D2;NANDINAGARI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +119D3;NANDINAGARI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +119D4;NANDINAGARI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +119D5;NANDINAGARI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +119D6;NANDINAGARI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +119D7;NANDINAGARI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +119DA;NANDINAGARI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +119DB;NANDINAGARI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +119DC;NANDINAGARI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +119DD;NANDINAGARI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +119DE;NANDINAGARI SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +119DF;NANDINAGARI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +119E0;NANDINAGARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +119E1;NANDINAGARI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +119E2;NANDINAGARI SIGN SIDDHAM;Po;0;L;;;;;N;;;;; +119E3;NANDINAGARI HEADSTROKE;Lo;0;L;;;;;N;;;;; +119E4;NANDINAGARI VOWEL SIGN PRISHTHAMATRA E;Mc;0;L;;;;;N;;;;; +11A00;ZANABAZAR SQUARE LETTER A;Lo;0;L;;;;;N;;;;; +11A01;ZANABAZAR SQUARE VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +11A02;ZANABAZAR SQUARE VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;; +11A03;ZANABAZAR SQUARE VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +11A04;ZANABAZAR SQUARE VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +11A05;ZANABAZAR SQUARE VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;; +11A06;ZANABAZAR SQUARE VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +11A07;ZANABAZAR SQUARE VOWEL SIGN AI;Mn;0;L;;;;;N;;;;; +11A08;ZANABAZAR SQUARE VOWEL SIGN AU;Mn;0;L;;;;;N;;;;; +11A09;ZANABAZAR SQUARE VOWEL SIGN REVERSED I;Mn;0;NSM;;;;;N;;;;; +11A0A;ZANABAZAR SQUARE VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;; +11A0B;ZANABAZAR SQUARE LETTER KA;Lo;0;L;;;;;N;;;;; +11A0C;ZANABAZAR SQUARE LETTER KHA;Lo;0;L;;;;;N;;;;; +11A0D;ZANABAZAR SQUARE LETTER GA;Lo;0;L;;;;;N;;;;; +11A0E;ZANABAZAR SQUARE LETTER GHA;Lo;0;L;;;;;N;;;;; +11A0F;ZANABAZAR SQUARE LETTER NGA;Lo;0;L;;;;;N;;;;; +11A10;ZANABAZAR SQUARE LETTER CA;Lo;0;L;;;;;N;;;;; +11A11;ZANABAZAR SQUARE LETTER CHA;Lo;0;L;;;;;N;;;;; +11A12;ZANABAZAR SQUARE LETTER JA;Lo;0;L;;;;;N;;;;; +11A13;ZANABAZAR SQUARE LETTER NYA;Lo;0;L;;;;;N;;;;; +11A14;ZANABAZAR SQUARE LETTER TTA;Lo;0;L;;;;;N;;;;; +11A15;ZANABAZAR SQUARE LETTER TTHA;Lo;0;L;;;;;N;;;;; +11A16;ZANABAZAR SQUARE LETTER DDA;Lo;0;L;;;;;N;;;;; +11A17;ZANABAZAR SQUARE LETTER DDHA;Lo;0;L;;;;;N;;;;; +11A18;ZANABAZAR SQUARE LETTER NNA;Lo;0;L;;;;;N;;;;; +11A19;ZANABAZAR SQUARE LETTER TA;Lo;0;L;;;;;N;;;;; +11A1A;ZANABAZAR SQUARE LETTER THA;Lo;0;L;;;;;N;;;;; +11A1B;ZANABAZAR SQUARE LETTER DA;Lo;0;L;;;;;N;;;;; +11A1C;ZANABAZAR SQUARE LETTER DHA;Lo;0;L;;;;;N;;;;; +11A1D;ZANABAZAR SQUARE LETTER NA;Lo;0;L;;;;;N;;;;; +11A1E;ZANABAZAR SQUARE LETTER PA;Lo;0;L;;;;;N;;;;; +11A1F;ZANABAZAR SQUARE LETTER PHA;Lo;0;L;;;;;N;;;;; +11A20;ZANABAZAR SQUARE LETTER BA;Lo;0;L;;;;;N;;;;; +11A21;ZANABAZAR SQUARE LETTER BHA;Lo;0;L;;;;;N;;;;; +11A22;ZANABAZAR SQUARE LETTER MA;Lo;0;L;;;;;N;;;;; +11A23;ZANABAZAR SQUARE LETTER TSA;Lo;0;L;;;;;N;;;;; +11A24;ZANABAZAR SQUARE LETTER TSHA;Lo;0;L;;;;;N;;;;; +11A25;ZANABAZAR SQUARE LETTER DZA;Lo;0;L;;;;;N;;;;; +11A26;ZANABAZAR SQUARE LETTER DZHA;Lo;0;L;;;;;N;;;;; +11A27;ZANABAZAR SQUARE LETTER ZHA;Lo;0;L;;;;;N;;;;; +11A28;ZANABAZAR SQUARE LETTER ZA;Lo;0;L;;;;;N;;;;; +11A29;ZANABAZAR SQUARE LETTER -A;Lo;0;L;;;;;N;;;;; +11A2A;ZANABAZAR SQUARE LETTER YA;Lo;0;L;;;;;N;;;;; +11A2B;ZANABAZAR SQUARE LETTER RA;Lo;0;L;;;;;N;;;;; +11A2C;ZANABAZAR SQUARE LETTER LA;Lo;0;L;;;;;N;;;;; +11A2D;ZANABAZAR SQUARE LETTER VA;Lo;0;L;;;;;N;;;;; +11A2E;ZANABAZAR SQUARE LETTER SHA;Lo;0;L;;;;;N;;;;; +11A2F;ZANABAZAR SQUARE LETTER SSA;Lo;0;L;;;;;N;;;;; +11A30;ZANABAZAR SQUARE LETTER SA;Lo;0;L;;;;;N;;;;; +11A31;ZANABAZAR SQUARE LETTER HA;Lo;0;L;;;;;N;;;;; +11A32;ZANABAZAR SQUARE LETTER KSSA;Lo;0;L;;;;;N;;;;; +11A33;ZANABAZAR SQUARE FINAL CONSONANT MARK;Mn;0;NSM;;;;;N;;;;; +11A34;ZANABAZAR SQUARE SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +11A35;ZANABAZAR SQUARE SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +11A36;ZANABAZAR SQUARE SIGN CANDRABINDU WITH ORNAMENT;Mn;0;NSM;;;;;N;;;;; +11A37;ZANABAZAR SQUARE SIGN CANDRA WITH ORNAMENT;Mn;0;NSM;;;;;N;;;;; +11A38;ZANABAZAR SQUARE SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11A39;ZANABAZAR SQUARE SIGN VISARGA;Mc;0;L;;;;;N;;;;; +11A3A;ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA;Lo;0;L;;;;;N;;;;; +11A3B;ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA;Mn;0;NSM;;;;;N;;;;; +11A3C;ZANABAZAR SQUARE CLUSTER-FINAL LETTER RA;Mn;0;NSM;;;;;N;;;;; +11A3D;ZANABAZAR SQUARE CLUSTER-FINAL LETTER LA;Mn;0;NSM;;;;;N;;;;; +11A3E;ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA;Mn;0;NSM;;;;;N;;;;; +11A3F;ZANABAZAR SQUARE INITIAL HEAD MARK;Po;0;L;;;;;N;;;;; +11A40;ZANABAZAR SQUARE CLOSING HEAD MARK;Po;0;L;;;;;N;;;;; +11A41;ZANABAZAR SQUARE MARK TSHEG;Po;0;L;;;;;N;;;;; +11A42;ZANABAZAR SQUARE MARK SHAD;Po;0;L;;;;;N;;;;; +11A43;ZANABAZAR SQUARE MARK DOUBLE SHAD;Po;0;L;;;;;N;;;;; +11A44;ZANABAZAR SQUARE MARK LONG TSHEG;Po;0;L;;;;;N;;;;; +11A45;ZANABAZAR SQUARE INITIAL DOUBLE-LINED HEAD MARK;Po;0;L;;;;;N;;;;; +11A46;ZANABAZAR SQUARE CLOSING DOUBLE-LINED HEAD MARK;Po;0;L;;;;;N;;;;; +11A47;ZANABAZAR SQUARE SUBJOINER;Mn;9;NSM;;;;;N;;;;; +11A50;SOYOMBO LETTER A;Lo;0;L;;;;;N;;;;; +11A51;SOYOMBO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +11A52;SOYOMBO VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;; +11A53;SOYOMBO VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +11A54;SOYOMBO VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +11A55;SOYOMBO VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +11A56;SOYOMBO VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;; +11A57;SOYOMBO VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +11A58;SOYOMBO VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +11A59;SOYOMBO VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +11A5A;SOYOMBO VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +11A5B;SOYOMBO VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;; +11A5C;SOYOMBO LETTER KA;Lo;0;L;;;;;N;;;;; +11A5D;SOYOMBO LETTER KHA;Lo;0;L;;;;;N;;;;; +11A5E;SOYOMBO LETTER GA;Lo;0;L;;;;;N;;;;; +11A5F;SOYOMBO LETTER GHA;Lo;0;L;;;;;N;;;;; +11A60;SOYOMBO LETTER NGA;Lo;0;L;;;;;N;;;;; +11A61;SOYOMBO LETTER CA;Lo;0;L;;;;;N;;;;; +11A62;SOYOMBO LETTER CHA;Lo;0;L;;;;;N;;;;; +11A63;SOYOMBO LETTER JA;Lo;0;L;;;;;N;;;;; +11A64;SOYOMBO LETTER JHA;Lo;0;L;;;;;N;;;;; +11A65;SOYOMBO LETTER NYA;Lo;0;L;;;;;N;;;;; +11A66;SOYOMBO LETTER TTA;Lo;0;L;;;;;N;;;;; +11A67;SOYOMBO LETTER TTHA;Lo;0;L;;;;;N;;;;; +11A68;SOYOMBO LETTER DDA;Lo;0;L;;;;;N;;;;; +11A69;SOYOMBO LETTER DDHA;Lo;0;L;;;;;N;;;;; +11A6A;SOYOMBO LETTER NNA;Lo;0;L;;;;;N;;;;; +11A6B;SOYOMBO LETTER TA;Lo;0;L;;;;;N;;;;; +11A6C;SOYOMBO LETTER THA;Lo;0;L;;;;;N;;;;; +11A6D;SOYOMBO LETTER DA;Lo;0;L;;;;;N;;;;; +11A6E;SOYOMBO LETTER DHA;Lo;0;L;;;;;N;;;;; +11A6F;SOYOMBO LETTER NA;Lo;0;L;;;;;N;;;;; +11A70;SOYOMBO LETTER PA;Lo;0;L;;;;;N;;;;; +11A71;SOYOMBO LETTER PHA;Lo;0;L;;;;;N;;;;; +11A72;SOYOMBO LETTER BA;Lo;0;L;;;;;N;;;;; +11A73;SOYOMBO LETTER BHA;Lo;0;L;;;;;N;;;;; +11A74;SOYOMBO LETTER MA;Lo;0;L;;;;;N;;;;; +11A75;SOYOMBO LETTER TSA;Lo;0;L;;;;;N;;;;; +11A76;SOYOMBO LETTER TSHA;Lo;0;L;;;;;N;;;;; +11A77;SOYOMBO LETTER DZA;Lo;0;L;;;;;N;;;;; +11A78;SOYOMBO LETTER ZHA;Lo;0;L;;;;;N;;;;; +11A79;SOYOMBO LETTER ZA;Lo;0;L;;;;;N;;;;; +11A7A;SOYOMBO LETTER -A;Lo;0;L;;;;;N;;;;; +11A7B;SOYOMBO LETTER YA;Lo;0;L;;;;;N;;;;; +11A7C;SOYOMBO LETTER RA;Lo;0;L;;;;;N;;;;; +11A7D;SOYOMBO LETTER LA;Lo;0;L;;;;;N;;;;; +11A7E;SOYOMBO LETTER VA;Lo;0;L;;;;;N;;;;; +11A7F;SOYOMBO LETTER SHA;Lo;0;L;;;;;N;;;;; +11A80;SOYOMBO LETTER SSA;Lo;0;L;;;;;N;;;;; +11A81;SOYOMBO LETTER SA;Lo;0;L;;;;;N;;;;; +11A82;SOYOMBO LETTER HA;Lo;0;L;;;;;N;;;;; +11A83;SOYOMBO LETTER KSSA;Lo;0;L;;;;;N;;;;; +11A84;SOYOMBO SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;; +11A85;SOYOMBO SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;; +11A86;SOYOMBO CLUSTER-INITIAL LETTER RA;Lo;0;L;;;;;N;;;;; +11A87;SOYOMBO CLUSTER-INITIAL LETTER LA;Lo;0;L;;;;;N;;;;; +11A88;SOYOMBO CLUSTER-INITIAL LETTER SHA;Lo;0;L;;;;;N;;;;; +11A89;SOYOMBO CLUSTER-INITIAL LETTER SA;Lo;0;L;;;;;N;;;;; +11A8A;SOYOMBO FINAL CONSONANT SIGN G;Mn;0;NSM;;;;;N;;;;; +11A8B;SOYOMBO FINAL CONSONANT SIGN K;Mn;0;NSM;;;;;N;;;;; +11A8C;SOYOMBO FINAL CONSONANT SIGN NG;Mn;0;NSM;;;;;N;;;;; +11A8D;SOYOMBO FINAL CONSONANT SIGN D;Mn;0;NSM;;;;;N;;;;; +11A8E;SOYOMBO FINAL CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;; +11A8F;SOYOMBO FINAL CONSONANT SIGN B;Mn;0;NSM;;;;;N;;;;; +11A90;SOYOMBO FINAL CONSONANT SIGN M;Mn;0;NSM;;;;;N;;;;; +11A91;SOYOMBO FINAL CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;; +11A92;SOYOMBO FINAL CONSONANT SIGN L;Mn;0;NSM;;;;;N;;;;; +11A93;SOYOMBO FINAL CONSONANT SIGN SH;Mn;0;NSM;;;;;N;;;;; +11A94;SOYOMBO FINAL CONSONANT SIGN S;Mn;0;NSM;;;;;N;;;;; +11A95;SOYOMBO FINAL CONSONANT SIGN -A;Mn;0;NSM;;;;;N;;;;; +11A96;SOYOMBO SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11A97;SOYOMBO SIGN VISARGA;Mc;0;L;;;;;N;;;;; +11A98;SOYOMBO GEMINATION MARK;Mn;0;NSM;;;;;N;;;;; +11A99;SOYOMBO SUBJOINER;Mn;9;NSM;;;;;N;;;;; +11A9A;SOYOMBO MARK TSHEG;Po;0;L;;;;;N;;;;; +11A9B;SOYOMBO MARK SHAD;Po;0;L;;;;;N;;;;; +11A9C;SOYOMBO MARK DOUBLE SHAD;Po;0;L;;;;;N;;;;; +11A9D;SOYOMBO MARK PLUTA;Lo;0;L;;;;;N;;;;; +11A9E;SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME;Po;0;L;;;;;N;;;;; +11A9F;SOYOMBO HEAD MARK WITH MOON AND SUN AND FLAME;Po;0;L;;;;;N;;;;; +11AA0;SOYOMBO HEAD MARK WITH MOON AND SUN;Po;0;L;;;;;N;;;;; +11AA1;SOYOMBO TERMINAL MARK-1;Po;0;L;;;;;N;;;;; +11AA2;SOYOMBO TERMINAL MARK-2;Po;0;L;;;;;N;;;;; +11AC0;PAU CIN HAU LETTER PA;Lo;0;L;;;;;N;;;;; +11AC1;PAU CIN HAU LETTER KA;Lo;0;L;;;;;N;;;;; +11AC2;PAU CIN HAU LETTER LA;Lo;0;L;;;;;N;;;;; +11AC3;PAU CIN HAU LETTER MA;Lo;0;L;;;;;N;;;;; +11AC4;PAU CIN HAU LETTER DA;Lo;0;L;;;;;N;;;;; +11AC5;PAU CIN HAU LETTER ZA;Lo;0;L;;;;;N;;;;; +11AC6;PAU CIN HAU LETTER VA;Lo;0;L;;;;;N;;;;; +11AC7;PAU CIN HAU LETTER NGA;Lo;0;L;;;;;N;;;;; +11AC8;PAU CIN HAU LETTER HA;Lo;0;L;;;;;N;;;;; +11AC9;PAU CIN HAU LETTER GA;Lo;0;L;;;;;N;;;;; +11ACA;PAU CIN HAU LETTER KHA;Lo;0;L;;;;;N;;;;; +11ACB;PAU CIN HAU LETTER SA;Lo;0;L;;;;;N;;;;; +11ACC;PAU CIN HAU LETTER BA;Lo;0;L;;;;;N;;;;; +11ACD;PAU CIN HAU LETTER CA;Lo;0;L;;;;;N;;;;; +11ACE;PAU CIN HAU LETTER TA;Lo;0;L;;;;;N;;;;; +11ACF;PAU CIN HAU LETTER THA;Lo;0;L;;;;;N;;;;; +11AD0;PAU CIN HAU LETTER NA;Lo;0;L;;;;;N;;;;; +11AD1;PAU CIN HAU LETTER PHA;Lo;0;L;;;;;N;;;;; +11AD2;PAU CIN HAU LETTER RA;Lo;0;L;;;;;N;;;;; +11AD3;PAU CIN HAU LETTER FA;Lo;0;L;;;;;N;;;;; +11AD4;PAU CIN HAU LETTER CHA;Lo;0;L;;;;;N;;;;; +11AD5;PAU CIN HAU LETTER A;Lo;0;L;;;;;N;;;;; +11AD6;PAU CIN HAU LETTER E;Lo;0;L;;;;;N;;;;; +11AD7;PAU CIN HAU LETTER I;Lo;0;L;;;;;N;;;;; +11AD8;PAU CIN HAU LETTER O;Lo;0;L;;;;;N;;;;; +11AD9;PAU CIN HAU LETTER U;Lo;0;L;;;;;N;;;;; +11ADA;PAU CIN HAU LETTER UA;Lo;0;L;;;;;N;;;;; +11ADB;PAU CIN HAU LETTER IA;Lo;0;L;;;;;N;;;;; +11ADC;PAU CIN HAU LETTER FINAL P;Lo;0;L;;;;;N;;;;; +11ADD;PAU CIN HAU LETTER FINAL K;Lo;0;L;;;;;N;;;;; +11ADE;PAU CIN HAU LETTER FINAL T;Lo;0;L;;;;;N;;;;; +11ADF;PAU CIN HAU LETTER FINAL M;Lo;0;L;;;;;N;;;;; +11AE0;PAU CIN HAU LETTER FINAL N;Lo;0;L;;;;;N;;;;; +11AE1;PAU CIN HAU LETTER FINAL L;Lo;0;L;;;;;N;;;;; +11AE2;PAU CIN HAU LETTER FINAL W;Lo;0;L;;;;;N;;;;; +11AE3;PAU CIN HAU LETTER FINAL NG;Lo;0;L;;;;;N;;;;; +11AE4;PAU CIN HAU LETTER FINAL Y;Lo;0;L;;;;;N;;;;; +11AE5;PAU CIN HAU RISING TONE LONG;Lo;0;L;;;;;N;;;;; +11AE6;PAU CIN HAU RISING TONE;Lo;0;L;;;;;N;;;;; +11AE7;PAU CIN HAU SANDHI GLOTTAL STOP;Lo;0;L;;;;;N;;;;; +11AE8;PAU CIN HAU RISING TONE LONG FINAL;Lo;0;L;;;;;N;;;;; +11AE9;PAU CIN HAU RISING TONE FINAL;Lo;0;L;;;;;N;;;;; +11AEA;PAU CIN HAU SANDHI GLOTTAL STOP FINAL;Lo;0;L;;;;;N;;;;; +11AEB;PAU CIN HAU SANDHI TONE LONG;Lo;0;L;;;;;N;;;;; +11AEC;PAU CIN HAU SANDHI TONE;Lo;0;L;;;;;N;;;;; +11AED;PAU CIN HAU SANDHI TONE LONG FINAL;Lo;0;L;;;;;N;;;;; +11AEE;PAU CIN HAU SANDHI TONE FINAL;Lo;0;L;;;;;N;;;;; +11AEF;PAU CIN HAU MID-LEVEL TONE;Lo;0;L;;;;;N;;;;; +11AF0;PAU CIN HAU GLOTTAL STOP VARIANT;Lo;0;L;;;;;N;;;;; +11AF1;PAU CIN HAU MID-LEVEL TONE LONG FINAL;Lo;0;L;;;;;N;;;;; +11AF2;PAU CIN HAU MID-LEVEL TONE FINAL;Lo;0;L;;;;;N;;;;; +11AF3;PAU CIN HAU LOW-FALLING TONE LONG;Lo;0;L;;;;;N;;;;; +11AF4;PAU CIN HAU LOW-FALLING TONE;Lo;0;L;;;;;N;;;;; +11AF5;PAU CIN HAU GLOTTAL STOP;Lo;0;L;;;;;N;;;;; +11AF6;PAU CIN HAU LOW-FALLING TONE LONG FINAL;Lo;0;L;;;;;N;;;;; +11AF7;PAU CIN HAU LOW-FALLING TONE FINAL;Lo;0;L;;;;;N;;;;; +11AF8;PAU CIN HAU GLOTTAL STOP FINAL;Lo;0;L;;;;;N;;;;; +11C00;BHAIKSUKI LETTER A;Lo;0;L;;;;;N;;;;; +11C01;BHAIKSUKI LETTER AA;Lo;0;L;;;;;N;;;;; +11C02;BHAIKSUKI LETTER I;Lo;0;L;;;;;N;;;;; +11C03;BHAIKSUKI LETTER II;Lo;0;L;;;;;N;;;;; +11C04;BHAIKSUKI LETTER U;Lo;0;L;;;;;N;;;;; +11C05;BHAIKSUKI LETTER UU;Lo;0;L;;;;;N;;;;; +11C06;BHAIKSUKI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +11C07;BHAIKSUKI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +11C08;BHAIKSUKI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +11C0A;BHAIKSUKI LETTER E;Lo;0;L;;;;;N;;;;; +11C0B;BHAIKSUKI LETTER AI;Lo;0;L;;;;;N;;;;; +11C0C;BHAIKSUKI LETTER O;Lo;0;L;;;;;N;;;;; +11C0D;BHAIKSUKI LETTER AU;Lo;0;L;;;;;N;;;;; +11C0E;BHAIKSUKI LETTER KA;Lo;0;L;;;;;N;;;;; +11C0F;BHAIKSUKI LETTER KHA;Lo;0;L;;;;;N;;;;; +11C10;BHAIKSUKI LETTER GA;Lo;0;L;;;;;N;;;;; +11C11;BHAIKSUKI LETTER GHA;Lo;0;L;;;;;N;;;;; +11C12;BHAIKSUKI LETTER NGA;Lo;0;L;;;;;N;;;;; +11C13;BHAIKSUKI LETTER CA;Lo;0;L;;;;;N;;;;; +11C14;BHAIKSUKI LETTER CHA;Lo;0;L;;;;;N;;;;; +11C15;BHAIKSUKI LETTER JA;Lo;0;L;;;;;N;;;;; +11C16;BHAIKSUKI LETTER JHA;Lo;0;L;;;;;N;;;;; +11C17;BHAIKSUKI LETTER NYA;Lo;0;L;;;;;N;;;;; +11C18;BHAIKSUKI LETTER TTA;Lo;0;L;;;;;N;;;;; +11C19;BHAIKSUKI LETTER TTHA;Lo;0;L;;;;;N;;;;; +11C1A;BHAIKSUKI LETTER DDA;Lo;0;L;;;;;N;;;;; +11C1B;BHAIKSUKI LETTER DDHA;Lo;0;L;;;;;N;;;;; +11C1C;BHAIKSUKI LETTER NNA;Lo;0;L;;;;;N;;;;; +11C1D;BHAIKSUKI LETTER TA;Lo;0;L;;;;;N;;;;; +11C1E;BHAIKSUKI LETTER THA;Lo;0;L;;;;;N;;;;; +11C1F;BHAIKSUKI LETTER DA;Lo;0;L;;;;;N;;;;; +11C20;BHAIKSUKI LETTER DHA;Lo;0;L;;;;;N;;;;; +11C21;BHAIKSUKI LETTER NA;Lo;0;L;;;;;N;;;;; +11C22;BHAIKSUKI LETTER PA;Lo;0;L;;;;;N;;;;; +11C23;BHAIKSUKI LETTER PHA;Lo;0;L;;;;;N;;;;; +11C24;BHAIKSUKI LETTER BA;Lo;0;L;;;;;N;;;;; +11C25;BHAIKSUKI LETTER BHA;Lo;0;L;;;;;N;;;;; +11C26;BHAIKSUKI LETTER MA;Lo;0;L;;;;;N;;;;; +11C27;BHAIKSUKI LETTER YA;Lo;0;L;;;;;N;;;;; +11C28;BHAIKSUKI LETTER RA;Lo;0;L;;;;;N;;;;; +11C29;BHAIKSUKI LETTER LA;Lo;0;L;;;;;N;;;;; +11C2A;BHAIKSUKI LETTER VA;Lo;0;L;;;;;N;;;;; +11C2B;BHAIKSUKI LETTER SHA;Lo;0;L;;;;;N;;;;; +11C2C;BHAIKSUKI LETTER SSA;Lo;0;L;;;;;N;;;;; +11C2D;BHAIKSUKI LETTER SA;Lo;0;L;;;;;N;;;;; +11C2E;BHAIKSUKI LETTER HA;Lo;0;L;;;;;N;;;;; +11C2F;BHAIKSUKI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +11C30;BHAIKSUKI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +11C31;BHAIKSUKI VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +11C32;BHAIKSUKI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +11C33;BHAIKSUKI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +11C34;BHAIKSUKI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +11C35;BHAIKSUKI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +11C36;BHAIKSUKI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +11C38;BHAIKSUKI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +11C39;BHAIKSUKI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +11C3A;BHAIKSUKI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +11C3B;BHAIKSUKI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +11C3C;BHAIKSUKI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +11C3D;BHAIKSUKI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11C3E;BHAIKSUKI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +11C3F;BHAIKSUKI SIGN VIRAMA;Mn;9;L;;;;;N;;;;; +11C40;BHAIKSUKI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +11C41;BHAIKSUKI DANDA;Po;0;L;;;;;N;;;;; +11C42;BHAIKSUKI DOUBLE DANDA;Po;0;L;;;;;N;;;;; +11C43;BHAIKSUKI WORD SEPARATOR;Po;0;L;;;;;N;;;;; +11C44;BHAIKSUKI GAP FILLER-1;Po;0;L;;;;;N;;;;; +11C45;BHAIKSUKI GAP FILLER-2;Po;0;L;;;;;N;;;;; +11C50;BHAIKSUKI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +11C51;BHAIKSUKI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +11C52;BHAIKSUKI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +11C53;BHAIKSUKI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +11C54;BHAIKSUKI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +11C55;BHAIKSUKI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +11C56;BHAIKSUKI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +11C57;BHAIKSUKI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +11C58;BHAIKSUKI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +11C59;BHAIKSUKI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +11C5A;BHAIKSUKI NUMBER ONE;No;0;L;;;;1;N;;;;; +11C5B;BHAIKSUKI NUMBER TWO;No;0;L;;;;2;N;;;;; +11C5C;BHAIKSUKI NUMBER THREE;No;0;L;;;;3;N;;;;; +11C5D;BHAIKSUKI NUMBER FOUR;No;0;L;;;;4;N;;;;; +11C5E;BHAIKSUKI NUMBER FIVE;No;0;L;;;;5;N;;;;; +11C5F;BHAIKSUKI NUMBER SIX;No;0;L;;;;6;N;;;;; +11C60;BHAIKSUKI NUMBER SEVEN;No;0;L;;;;7;N;;;;; +11C61;BHAIKSUKI NUMBER EIGHT;No;0;L;;;;8;N;;;;; +11C62;BHAIKSUKI NUMBER NINE;No;0;L;;;;9;N;;;;; +11C63;BHAIKSUKI NUMBER TEN;No;0;L;;;;10;N;;;;; +11C64;BHAIKSUKI NUMBER TWENTY;No;0;L;;;;20;N;;;;; +11C65;BHAIKSUKI NUMBER THIRTY;No;0;L;;;;30;N;;;;; +11C66;BHAIKSUKI NUMBER FORTY;No;0;L;;;;40;N;;;;; +11C67;BHAIKSUKI NUMBER FIFTY;No;0;L;;;;50;N;;;;; +11C68;BHAIKSUKI NUMBER SIXTY;No;0;L;;;;60;N;;;;; +11C69;BHAIKSUKI NUMBER SEVENTY;No;0;L;;;;70;N;;;;; +11C6A;BHAIKSUKI NUMBER EIGHTY;No;0;L;;;;80;N;;;;; +11C6B;BHAIKSUKI NUMBER NINETY;No;0;L;;;;90;N;;;;; +11C6C;BHAIKSUKI HUNDREDS UNIT MARK;No;0;L;;;;100;N;;;;; +11C70;MARCHEN HEAD MARK;Po;0;L;;;;;N;;;;; +11C71;MARCHEN MARK SHAD;Po;0;L;;;;;N;;;;; +11C72;MARCHEN LETTER KA;Lo;0;L;;;;;N;;;;; +11C73;MARCHEN LETTER KHA;Lo;0;L;;;;;N;;;;; +11C74;MARCHEN LETTER GA;Lo;0;L;;;;;N;;;;; +11C75;MARCHEN LETTER NGA;Lo;0;L;;;;;N;;;;; +11C76;MARCHEN LETTER CA;Lo;0;L;;;;;N;;;;; +11C77;MARCHEN LETTER CHA;Lo;0;L;;;;;N;;;;; +11C78;MARCHEN LETTER JA;Lo;0;L;;;;;N;;;;; +11C79;MARCHEN LETTER NYA;Lo;0;L;;;;;N;;;;; +11C7A;MARCHEN LETTER TA;Lo;0;L;;;;;N;;;;; +11C7B;MARCHEN LETTER THA;Lo;0;L;;;;;N;;;;; +11C7C;MARCHEN LETTER DA;Lo;0;L;;;;;N;;;;; +11C7D;MARCHEN LETTER NA;Lo;0;L;;;;;N;;;;; +11C7E;MARCHEN LETTER PA;Lo;0;L;;;;;N;;;;; +11C7F;MARCHEN LETTER PHA;Lo;0;L;;;;;N;;;;; +11C80;MARCHEN LETTER BA;Lo;0;L;;;;;N;;;;; +11C81;MARCHEN LETTER MA;Lo;0;L;;;;;N;;;;; +11C82;MARCHEN LETTER TSA;Lo;0;L;;;;;N;;;;; +11C83;MARCHEN LETTER TSHA;Lo;0;L;;;;;N;;;;; +11C84;MARCHEN LETTER DZA;Lo;0;L;;;;;N;;;;; +11C85;MARCHEN LETTER WA;Lo;0;L;;;;;N;;;;; +11C86;MARCHEN LETTER ZHA;Lo;0;L;;;;;N;;;;; +11C87;MARCHEN LETTER ZA;Lo;0;L;;;;;N;;;;; +11C88;MARCHEN LETTER -A;Lo;0;L;;;;;N;;;;; +11C89;MARCHEN LETTER YA;Lo;0;L;;;;;N;;;;; +11C8A;MARCHEN LETTER RA;Lo;0;L;;;;;N;;;;; +11C8B;MARCHEN LETTER LA;Lo;0;L;;;;;N;;;;; +11C8C;MARCHEN LETTER SHA;Lo;0;L;;;;;N;;;;; +11C8D;MARCHEN LETTER SA;Lo;0;L;;;;;N;;;;; +11C8E;MARCHEN LETTER HA;Lo;0;L;;;;;N;;;;; +11C8F;MARCHEN LETTER A;Lo;0;L;;;;;N;;;;; +11C92;MARCHEN SUBJOINED LETTER KA;Mn;0;NSM;;;;;N;;;;; +11C93;MARCHEN SUBJOINED LETTER KHA;Mn;0;NSM;;;;;N;;;;; +11C94;MARCHEN SUBJOINED LETTER GA;Mn;0;NSM;;;;;N;;;;; +11C95;MARCHEN SUBJOINED LETTER NGA;Mn;0;NSM;;;;;N;;;;; +11C96;MARCHEN SUBJOINED LETTER CA;Mn;0;NSM;;;;;N;;;;; +11C97;MARCHEN SUBJOINED LETTER CHA;Mn;0;NSM;;;;;N;;;;; +11C98;MARCHEN SUBJOINED LETTER JA;Mn;0;NSM;;;;;N;;;;; +11C99;MARCHEN SUBJOINED LETTER NYA;Mn;0;NSM;;;;;N;;;;; +11C9A;MARCHEN SUBJOINED LETTER TA;Mn;0;NSM;;;;;N;;;;; +11C9B;MARCHEN SUBJOINED LETTER THA;Mn;0;NSM;;;;;N;;;;; +11C9C;MARCHEN SUBJOINED LETTER DA;Mn;0;NSM;;;;;N;;;;; +11C9D;MARCHEN SUBJOINED LETTER NA;Mn;0;NSM;;;;;N;;;;; +11C9E;MARCHEN SUBJOINED LETTER PA;Mn;0;NSM;;;;;N;;;;; +11C9F;MARCHEN SUBJOINED LETTER PHA;Mn;0;NSM;;;;;N;;;;; +11CA0;MARCHEN SUBJOINED LETTER BA;Mn;0;NSM;;;;;N;;;;; +11CA1;MARCHEN SUBJOINED LETTER MA;Mn;0;NSM;;;;;N;;;;; +11CA2;MARCHEN SUBJOINED LETTER TSA;Mn;0;NSM;;;;;N;;;;; +11CA3;MARCHEN SUBJOINED LETTER TSHA;Mn;0;NSM;;;;;N;;;;; +11CA4;MARCHEN SUBJOINED LETTER DZA;Mn;0;NSM;;;;;N;;;;; +11CA5;MARCHEN SUBJOINED LETTER WA;Mn;0;NSM;;;;;N;;;;; +11CA6;MARCHEN SUBJOINED LETTER ZHA;Mn;0;NSM;;;;;N;;;;; +11CA7;MARCHEN SUBJOINED LETTER ZA;Mn;0;NSM;;;;;N;;;;; +11CA9;MARCHEN SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;; +11CAA;MARCHEN SUBJOINED LETTER RA;Mn;0;NSM;;;;;N;;;;; +11CAB;MARCHEN SUBJOINED LETTER LA;Mn;0;NSM;;;;;N;;;;; +11CAC;MARCHEN SUBJOINED LETTER SHA;Mn;0;NSM;;;;;N;;;;; +11CAD;MARCHEN SUBJOINED LETTER SA;Mn;0;NSM;;;;;N;;;;; +11CAE;MARCHEN SUBJOINED LETTER HA;Mn;0;NSM;;;;;N;;;;; +11CAF;MARCHEN SUBJOINED LETTER A;Mn;0;NSM;;;;;N;;;;; +11CB0;MARCHEN VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;; +11CB1;MARCHEN VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +11CB2;MARCHEN VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +11CB3;MARCHEN VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +11CB4;MARCHEN VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +11CB5;MARCHEN SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11CB6;MARCHEN SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +11D00;MASARAM GONDI LETTER A;Lo;0;L;;;;;N;;;;; +11D01;MASARAM GONDI LETTER AA;Lo;0;L;;;;;N;;;;; +11D02;MASARAM GONDI LETTER I;Lo;0;L;;;;;N;;;;; +11D03;MASARAM GONDI LETTER II;Lo;0;L;;;;;N;;;;; +11D04;MASARAM GONDI LETTER U;Lo;0;L;;;;;N;;;;; +11D05;MASARAM GONDI LETTER UU;Lo;0;L;;;;;N;;;;; +11D06;MASARAM GONDI LETTER E;Lo;0;L;;;;;N;;;;; +11D08;MASARAM GONDI LETTER AI;Lo;0;L;;;;;N;;;;; +11D09;MASARAM GONDI LETTER O;Lo;0;L;;;;;N;;;;; +11D0B;MASARAM GONDI LETTER AU;Lo;0;L;;;;;N;;;;; +11D0C;MASARAM GONDI LETTER KA;Lo;0;L;;;;;N;;;;; +11D0D;MASARAM GONDI LETTER KHA;Lo;0;L;;;;;N;;;;; +11D0E;MASARAM GONDI LETTER GA;Lo;0;L;;;;;N;;;;; +11D0F;MASARAM GONDI LETTER GHA;Lo;0;L;;;;;N;;;;; +11D10;MASARAM GONDI LETTER NGA;Lo;0;L;;;;;N;;;;; +11D11;MASARAM GONDI LETTER CA;Lo;0;L;;;;;N;;;;; +11D12;MASARAM GONDI LETTER CHA;Lo;0;L;;;;;N;;;;; +11D13;MASARAM GONDI LETTER JA;Lo;0;L;;;;;N;;;;; +11D14;MASARAM GONDI LETTER JHA;Lo;0;L;;;;;N;;;;; +11D15;MASARAM GONDI LETTER NYA;Lo;0;L;;;;;N;;;;; +11D16;MASARAM GONDI LETTER TTA;Lo;0;L;;;;;N;;;;; +11D17;MASARAM GONDI LETTER TTHA;Lo;0;L;;;;;N;;;;; +11D18;MASARAM GONDI LETTER DDA;Lo;0;L;;;;;N;;;;; +11D19;MASARAM GONDI LETTER DDHA;Lo;0;L;;;;;N;;;;; +11D1A;MASARAM GONDI LETTER NNA;Lo;0;L;;;;;N;;;;; +11D1B;MASARAM GONDI LETTER TA;Lo;0;L;;;;;N;;;;; +11D1C;MASARAM GONDI LETTER THA;Lo;0;L;;;;;N;;;;; +11D1D;MASARAM GONDI LETTER DA;Lo;0;L;;;;;N;;;;; +11D1E;MASARAM GONDI LETTER DHA;Lo;0;L;;;;;N;;;;; +11D1F;MASARAM GONDI LETTER NA;Lo;0;L;;;;;N;;;;; +11D20;MASARAM GONDI LETTER PA;Lo;0;L;;;;;N;;;;; +11D21;MASARAM GONDI LETTER PHA;Lo;0;L;;;;;N;;;;; +11D22;MASARAM GONDI LETTER BA;Lo;0;L;;;;;N;;;;; +11D23;MASARAM GONDI LETTER BHA;Lo;0;L;;;;;N;;;;; +11D24;MASARAM GONDI LETTER MA;Lo;0;L;;;;;N;;;;; +11D25;MASARAM GONDI LETTER YA;Lo;0;L;;;;;N;;;;; +11D26;MASARAM GONDI LETTER RA;Lo;0;L;;;;;N;;;;; +11D27;MASARAM GONDI LETTER LA;Lo;0;L;;;;;N;;;;; +11D28;MASARAM GONDI LETTER VA;Lo;0;L;;;;;N;;;;; +11D29;MASARAM GONDI LETTER SHA;Lo;0;L;;;;;N;;;;; +11D2A;MASARAM GONDI LETTER SSA;Lo;0;L;;;;;N;;;;; +11D2B;MASARAM GONDI LETTER SA;Lo;0;L;;;;;N;;;;; +11D2C;MASARAM GONDI LETTER HA;Lo;0;L;;;;;N;;;;; +11D2D;MASARAM GONDI LETTER LLA;Lo;0;L;;;;;N;;;;; +11D2E;MASARAM GONDI LETTER KSSA;Lo;0;L;;;;;N;;;;; +11D2F;MASARAM GONDI LETTER JNYA;Lo;0;L;;;;;N;;;;; +11D30;MASARAM GONDI LETTER TRA;Lo;0;L;;;;;N;;;;; +11D31;MASARAM GONDI VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;; +11D32;MASARAM GONDI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +11D33;MASARAM GONDI VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +11D34;MASARAM GONDI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +11D35;MASARAM GONDI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +11D36;MASARAM GONDI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +11D3A;MASARAM GONDI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +11D3C;MASARAM GONDI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +11D3D;MASARAM GONDI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +11D3F;MASARAM GONDI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +11D40;MASARAM GONDI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11D41;MASARAM GONDI SIGN VISARGA;Mn;0;NSM;;;;;N;;;;; +11D42;MASARAM GONDI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +11D43;MASARAM GONDI SIGN CANDRA;Mn;0;NSM;;;;;N;;;;; +11D44;MASARAM GONDI SIGN HALANTA;Mn;9;NSM;;;;;N;;;;; +11D45;MASARAM GONDI VIRAMA;Mn;9;NSM;;;;;N;;;;; +11D46;MASARAM GONDI REPHA;Lo;0;L;;;;;N;;;;; +11D47;MASARAM GONDI RA-KARA;Mn;0;NSM;;;;;N;;;;; +11D50;MASARAM GONDI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +11D51;MASARAM GONDI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +11D52;MASARAM GONDI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +11D53;MASARAM GONDI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +11D54;MASARAM GONDI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +11D55;MASARAM GONDI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +11D56;MASARAM GONDI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +11D57;MASARAM GONDI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +11D58;MASARAM GONDI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +11D59;MASARAM GONDI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +11D60;GUNJALA GONDI LETTER A;Lo;0;L;;;;;N;;;;; +11D61;GUNJALA GONDI LETTER AA;Lo;0;L;;;;;N;;;;; +11D62;GUNJALA GONDI LETTER I;Lo;0;L;;;;;N;;;;; +11D63;GUNJALA GONDI LETTER II;Lo;0;L;;;;;N;;;;; +11D64;GUNJALA GONDI LETTER U;Lo;0;L;;;;;N;;;;; +11D65;GUNJALA GONDI LETTER UU;Lo;0;L;;;;;N;;;;; +11D67;GUNJALA GONDI LETTER EE;Lo;0;L;;;;;N;;;;; +11D68;GUNJALA GONDI LETTER AI;Lo;0;L;;;;;N;;;;; +11D6A;GUNJALA GONDI LETTER OO;Lo;0;L;;;;;N;;;;; +11D6B;GUNJALA GONDI LETTER AU;Lo;0;L;;;;;N;;;;; +11D6C;GUNJALA GONDI LETTER YA;Lo;0;L;;;;;N;;;;; +11D6D;GUNJALA GONDI LETTER VA;Lo;0;L;;;;;N;;;;; +11D6E;GUNJALA GONDI LETTER BA;Lo;0;L;;;;;N;;;;; +11D6F;GUNJALA GONDI LETTER BHA;Lo;0;L;;;;;N;;;;; +11D70;GUNJALA GONDI LETTER MA;Lo;0;L;;;;;N;;;;; +11D71;GUNJALA GONDI LETTER KA;Lo;0;L;;;;;N;;;;; +11D72;GUNJALA GONDI LETTER KHA;Lo;0;L;;;;;N;;;;; +11D73;GUNJALA GONDI LETTER TA;Lo;0;L;;;;;N;;;;; +11D74;GUNJALA GONDI LETTER THA;Lo;0;L;;;;;N;;;;; +11D75;GUNJALA GONDI LETTER LA;Lo;0;L;;;;;N;;;;; +11D76;GUNJALA GONDI LETTER GA;Lo;0;L;;;;;N;;;;; +11D77;GUNJALA GONDI LETTER GHA;Lo;0;L;;;;;N;;;;; +11D78;GUNJALA GONDI LETTER DA;Lo;0;L;;;;;N;;;;; +11D79;GUNJALA GONDI LETTER DHA;Lo;0;L;;;;;N;;;;; +11D7A;GUNJALA GONDI LETTER NA;Lo;0;L;;;;;N;;;;; +11D7B;GUNJALA GONDI LETTER CA;Lo;0;L;;;;;N;;;;; +11D7C;GUNJALA GONDI LETTER CHA;Lo;0;L;;;;;N;;;;; +11D7D;GUNJALA GONDI LETTER TTA;Lo;0;L;;;;;N;;;;; +11D7E;GUNJALA GONDI LETTER TTHA;Lo;0;L;;;;;N;;;;; +11D7F;GUNJALA GONDI LETTER LLA;Lo;0;L;;;;;N;;;;; +11D80;GUNJALA GONDI LETTER JA;Lo;0;L;;;;;N;;;;; +11D81;GUNJALA GONDI LETTER JHA;Lo;0;L;;;;;N;;;;; +11D82;GUNJALA GONDI LETTER DDA;Lo;0;L;;;;;N;;;;; +11D83;GUNJALA GONDI LETTER DDHA;Lo;0;L;;;;;N;;;;; +11D84;GUNJALA GONDI LETTER NGA;Lo;0;L;;;;;N;;;;; +11D85;GUNJALA GONDI LETTER PA;Lo;0;L;;;;;N;;;;; +11D86;GUNJALA GONDI LETTER PHA;Lo;0;L;;;;;N;;;;; +11D87;GUNJALA GONDI LETTER HA;Lo;0;L;;;;;N;;;;; +11D88;GUNJALA GONDI LETTER RA;Lo;0;L;;;;;N;;;;; +11D89;GUNJALA GONDI LETTER SA;Lo;0;L;;;;;N;;;;; +11D8A;GUNJALA GONDI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +11D8B;GUNJALA GONDI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +11D8C;GUNJALA GONDI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +11D8D;GUNJALA GONDI VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +11D8E;GUNJALA GONDI VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +11D90;GUNJALA GONDI VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;; +11D91;GUNJALA GONDI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +11D93;GUNJALA GONDI VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +11D94;GUNJALA GONDI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +11D95;GUNJALA GONDI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11D96;GUNJALA GONDI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +11D97;GUNJALA GONDI VIRAMA;Mn;9;NSM;;;;;N;;;;; +11D98;GUNJALA GONDI OM;Lo;0;L;;;;;N;;;;; +11DA0;GUNJALA GONDI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +11DA1;GUNJALA GONDI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +11DA2;GUNJALA GONDI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +11DA3;GUNJALA GONDI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +11DA4;GUNJALA GONDI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +11DA5;GUNJALA GONDI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +11DA6;GUNJALA GONDI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +11DA7;GUNJALA GONDI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +11DA8;GUNJALA GONDI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +11DA9;GUNJALA GONDI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +11EE0;MAKASAR LETTER KA;Lo;0;L;;;;;N;;;;; +11EE1;MAKASAR LETTER GA;Lo;0;L;;;;;N;;;;; +11EE2;MAKASAR LETTER NGA;Lo;0;L;;;;;N;;;;; +11EE3;MAKASAR LETTER PA;Lo;0;L;;;;;N;;;;; +11EE4;MAKASAR LETTER BA;Lo;0;L;;;;;N;;;;; +11EE5;MAKASAR LETTER MA;Lo;0;L;;;;;N;;;;; +11EE6;MAKASAR LETTER TA;Lo;0;L;;;;;N;;;;; +11EE7;MAKASAR LETTER DA;Lo;0;L;;;;;N;;;;; +11EE8;MAKASAR LETTER NA;Lo;0;L;;;;;N;;;;; +11EE9;MAKASAR LETTER CA;Lo;0;L;;;;;N;;;;; +11EEA;MAKASAR LETTER JA;Lo;0;L;;;;;N;;;;; +11EEB;MAKASAR LETTER NYA;Lo;0;L;;;;;N;;;;; +11EEC;MAKASAR LETTER YA;Lo;0;L;;;;;N;;;;; +11EED;MAKASAR LETTER RA;Lo;0;L;;;;;N;;;;; +11EEE;MAKASAR LETTER LA;Lo;0;L;;;;;N;;;;; +11EEF;MAKASAR LETTER VA;Lo;0;L;;;;;N;;;;; +11EF0;MAKASAR LETTER SA;Lo;0;L;;;;;N;;;;; +11EF1;MAKASAR LETTER A;Lo;0;L;;;;;N;;;;; +11EF2;MAKASAR ANGKA;Lo;0;L;;;;;N;;;;; +11EF3;MAKASAR VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +11EF4;MAKASAR VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +11EF5;MAKASAR VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +11EF6;MAKASAR VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +11EF7;MAKASAR PASSIMBANG;Po;0;L;;;;;N;;;;; +11EF8;MAKASAR END OF SECTION;Po;0;L;;;;;N;;;;; +11FC0;TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH;No;0;L;;;;1/320;N;;;;; +11FC1;TAMIL FRACTION ONE ONE-HUNDRED-AND-SIXTIETH;No;0;L;;;;1/160;N;;;;; +11FC2;TAMIL FRACTION ONE EIGHTIETH;No;0;L;;;;1/80;N;;;;; +11FC3;TAMIL FRACTION ONE SIXTY-FOURTH;No;0;L;;;;1/64;N;;;;; +11FC4;TAMIL FRACTION ONE FORTIETH;No;0;L;;;;1/40;N;;;;; +11FC5;TAMIL FRACTION ONE THIRTY-SECOND;No;0;L;;;;1/32;N;;;;; +11FC6;TAMIL FRACTION THREE EIGHTIETHS;No;0;L;;;;3/80;N;;;;; +11FC7;TAMIL FRACTION THREE SIXTY-FOURTHS;No;0;L;;;;3/64;N;;;;; +11FC8;TAMIL FRACTION ONE TWENTIETH;No;0;L;;;;1/20;N;;;;; +11FC9;TAMIL FRACTION ONE SIXTEENTH-1;No;0;L;;;;1/16;N;;;;; +11FCA;TAMIL FRACTION ONE SIXTEENTH-2;No;0;L;;;;1/16;N;;;;; +11FCB;TAMIL FRACTION ONE TENTH;No;0;L;;;;1/10;N;;;;; +11FCC;TAMIL FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;; +11FCD;TAMIL FRACTION THREE TWENTIETHS;No;0;L;;;;3/20;N;;;;; +11FCE;TAMIL FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;; +11FCF;TAMIL FRACTION ONE FIFTH;No;0;L;;;;1/5;N;;;;; +11FD0;TAMIL FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;; +11FD1;TAMIL FRACTION ONE HALF-1;No;0;L;;;;1/2;N;;;;; +11FD2;TAMIL FRACTION ONE HALF-2;No;0;L;;;;1/2;N;;;;; +11FD3;TAMIL FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;; +11FD4;TAMIL FRACTION DOWNSCALING FACTOR KIIZH;No;0;L;;;;1/320;N;;;;; +11FD5;TAMIL SIGN NEL;So;0;ON;;;;;N;;;;; +11FD6;TAMIL SIGN CEVITU;So;0;ON;;;;;N;;;;; +11FD7;TAMIL SIGN AAZHAAKKU;So;0;ON;;;;;N;;;;; +11FD8;TAMIL SIGN UZHAKKU;So;0;ON;;;;;N;;;;; +11FD9;TAMIL SIGN MUUVUZHAKKU;So;0;ON;;;;;N;;;;; +11FDA;TAMIL SIGN KURUNI;So;0;ON;;;;;N;;;;; +11FDB;TAMIL SIGN PATHAKKU;So;0;ON;;;;;N;;;;; +11FDC;TAMIL SIGN MUKKURUNI;So;0;ON;;;;;N;;;;; +11FDD;TAMIL SIGN KAACU;Sc;0;ET;;;;;N;;;;; +11FDE;TAMIL SIGN PANAM;Sc;0;ET;;;;;N;;;;; +11FDF;TAMIL SIGN PON;Sc;0;ET;;;;;N;;;;; +11FE0;TAMIL SIGN VARAAKAN;Sc;0;ET;;;;;N;;;;; +11FE1;TAMIL SIGN PAARAM;So;0;ON;;;;;N;;;;; +11FE2;TAMIL SIGN KUZHI;So;0;ON;;;;;N;;;;; +11FE3;TAMIL SIGN VELI;So;0;ON;;;;;N;;;;; +11FE4;TAMIL WET CULTIVATION SIGN;So;0;ON;;;;;N;;;;; +11FE5;TAMIL DRY CULTIVATION SIGN;So;0;ON;;;;;N;;;;; +11FE6;TAMIL LAND SIGN;So;0;ON;;;;;N;;;;; +11FE7;TAMIL SALT PAN SIGN;So;0;ON;;;;;N;;;;; +11FE8;TAMIL TRADITIONAL CREDIT SIGN;So;0;ON;;;;;N;;;;; +11FE9;TAMIL TRADITIONAL NUMBER SIGN;So;0;ON;;;;;N;;;;; +11FEA;TAMIL CURRENT SIGN;So;0;ON;;;;;N;;;;; +11FEB;TAMIL AND ODD SIGN;So;0;ON;;;;;N;;;;; +11FEC;TAMIL SPENT SIGN;So;0;ON;;;;;N;;;;; +11FED;TAMIL TOTAL SIGN;So;0;ON;;;;;N;;;;; +11FEE;TAMIL IN POSSESSION SIGN;So;0;ON;;;;;N;;;;; +11FEF;TAMIL STARTING FROM SIGN;So;0;ON;;;;;N;;;;; +11FF0;TAMIL SIGN MUTHALIYA;So;0;ON;;;;;N;;;;; +11FF1;TAMIL SIGN VAKAIYARAA;So;0;ON;;;;;N;;;;; +11FFF;TAMIL PUNCTUATION END OF TEXT;Po;0;L;;;;;N;;;;; +12000;CUNEIFORM SIGN A;Lo;0;L;;;;;N;;;;; +12001;CUNEIFORM SIGN A TIMES A;Lo;0;L;;;;;N;;;;; +12002;CUNEIFORM SIGN A TIMES BAD;Lo;0;L;;;;;N;;;;; +12003;CUNEIFORM SIGN A TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +12004;CUNEIFORM SIGN A TIMES HA;Lo;0;L;;;;;N;;;;; +12005;CUNEIFORM SIGN A TIMES IGI;Lo;0;L;;;;;N;;;;; +12006;CUNEIFORM SIGN A TIMES LAGAR GUNU;Lo;0;L;;;;;N;;;;; +12007;CUNEIFORM SIGN A TIMES MUSH;Lo;0;L;;;;;N;;;;; +12008;CUNEIFORM SIGN A TIMES SAG;Lo;0;L;;;;;N;;;;; +12009;CUNEIFORM SIGN A2;Lo;0;L;;;;;N;;;;; +1200A;CUNEIFORM SIGN AB;Lo;0;L;;;;;N;;;;; +1200B;CUNEIFORM SIGN AB TIMES ASH2;Lo;0;L;;;;;N;;;;; +1200C;CUNEIFORM SIGN AB TIMES DUN3 GUNU;Lo;0;L;;;;;N;;;;; +1200D;CUNEIFORM SIGN AB TIMES GAL;Lo;0;L;;;;;N;;;;; +1200E;CUNEIFORM SIGN AB TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +1200F;CUNEIFORM SIGN AB TIMES HA;Lo;0;L;;;;;N;;;;; +12010;CUNEIFORM SIGN AB TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +12011;CUNEIFORM SIGN AB TIMES IMIN;Lo;0;L;;;;;N;;;;; +12012;CUNEIFORM SIGN AB TIMES LAGAB;Lo;0;L;;;;;N;;;;; +12013;CUNEIFORM SIGN AB TIMES SHESH;Lo;0;L;;;;;N;;;;; +12014;CUNEIFORM SIGN AB TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;; +12015;CUNEIFORM SIGN AB GUNU;Lo;0;L;;;;;N;;;;; +12016;CUNEIFORM SIGN AB2;Lo;0;L;;;;;N;;;;; +12017;CUNEIFORM SIGN AB2 TIMES BALAG;Lo;0;L;;;;;N;;;;; +12018;CUNEIFORM SIGN AB2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +12019;CUNEIFORM SIGN AB2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;; +1201A;CUNEIFORM SIGN AB2 TIMES SHA3;Lo;0;L;;;;;N;;;;; +1201B;CUNEIFORM SIGN AB2 TIMES TAK4;Lo;0;L;;;;;N;;;;; +1201C;CUNEIFORM SIGN AD;Lo;0;L;;;;;N;;;;; +1201D;CUNEIFORM SIGN AK;Lo;0;L;;;;;N;;;;; +1201E;CUNEIFORM SIGN AK TIMES ERIN2;Lo;0;L;;;;;N;;;;; +1201F;CUNEIFORM SIGN AK TIMES SHITA PLUS GISH;Lo;0;L;;;;;N;;;;; +12020;CUNEIFORM SIGN AL;Lo;0;L;;;;;N;;;;; +12021;CUNEIFORM SIGN AL TIMES AL;Lo;0;L;;;;;N;;;;; +12022;CUNEIFORM SIGN AL TIMES DIM2;Lo;0;L;;;;;N;;;;; +12023;CUNEIFORM SIGN AL TIMES GISH;Lo;0;L;;;;;N;;;;; +12024;CUNEIFORM SIGN AL TIMES HA;Lo;0;L;;;;;N;;;;; +12025;CUNEIFORM SIGN AL TIMES KAD3;Lo;0;L;;;;;N;;;;; +12026;CUNEIFORM SIGN AL TIMES KI;Lo;0;L;;;;;N;;;;; +12027;CUNEIFORM SIGN AL TIMES SHE;Lo;0;L;;;;;N;;;;; +12028;CUNEIFORM SIGN AL TIMES USH;Lo;0;L;;;;;N;;;;; +12029;CUNEIFORM SIGN ALAN;Lo;0;L;;;;;N;;;;; +1202A;CUNEIFORM SIGN ALEPH;Lo;0;L;;;;;N;;;;; +1202B;CUNEIFORM SIGN AMAR;Lo;0;L;;;;;N;;;;; +1202C;CUNEIFORM SIGN AMAR TIMES SHE;Lo;0;L;;;;;N;;;;; +1202D;CUNEIFORM SIGN AN;Lo;0;L;;;;;N;;;;; +1202E;CUNEIFORM SIGN AN OVER AN;Lo;0;L;;;;;N;;;;; +1202F;CUNEIFORM SIGN AN THREE TIMES;Lo;0;L;;;;;N;;;;; +12030;CUNEIFORM SIGN AN PLUS NAGA OPPOSING AN PLUS NAGA;Lo;0;L;;;;;N;;;;; +12031;CUNEIFORM SIGN AN PLUS NAGA SQUARED;Lo;0;L;;;;;N;;;;; +12032;CUNEIFORM SIGN ANSHE;Lo;0;L;;;;;N;;;;; +12033;CUNEIFORM SIGN APIN;Lo;0;L;;;;;N;;;;; +12034;CUNEIFORM SIGN ARAD;Lo;0;L;;;;;N;;;;; +12035;CUNEIFORM SIGN ARAD TIMES KUR;Lo;0;L;;;;;N;;;;; +12036;CUNEIFORM SIGN ARKAB;Lo;0;L;;;;;N;;;;; +12037;CUNEIFORM SIGN ASAL2;Lo;0;L;;;;;N;;;;; +12038;CUNEIFORM SIGN ASH;Lo;0;L;;;;;N;;;;; +12039;CUNEIFORM SIGN ASH ZIDA TENU;Lo;0;L;;;;;N;;;;; +1203A;CUNEIFORM SIGN ASH KABA TENU;Lo;0;L;;;;;N;;;;; +1203B;CUNEIFORM SIGN ASH OVER ASH TUG2 OVER TUG2 TUG2 OVER TUG2 PAP;Lo;0;L;;;;;N;;;;; +1203C;CUNEIFORM SIGN ASH OVER ASH OVER ASH;Lo;0;L;;;;;N;;;;; +1203D;CUNEIFORM SIGN ASH OVER ASH OVER ASH CROSSING ASH OVER ASH OVER ASH;Lo;0;L;;;;;N;;;;; +1203E;CUNEIFORM SIGN ASH2;Lo;0;L;;;;;N;;;;; +1203F;CUNEIFORM SIGN ASHGAB;Lo;0;L;;;;;N;;;;; +12040;CUNEIFORM SIGN BA;Lo;0;L;;;;;N;;;;; +12041;CUNEIFORM SIGN BAD;Lo;0;L;;;;;N;;;;; +12042;CUNEIFORM SIGN BAG3;Lo;0;L;;;;;N;;;;; +12043;CUNEIFORM SIGN BAHAR2;Lo;0;L;;;;;N;;;;; +12044;CUNEIFORM SIGN BAL;Lo;0;L;;;;;N;;;;; +12045;CUNEIFORM SIGN BAL OVER BAL;Lo;0;L;;;;;N;;;;; +12046;CUNEIFORM SIGN BALAG;Lo;0;L;;;;;N;;;;; +12047;CUNEIFORM SIGN BAR;Lo;0;L;;;;;N;;;;; +12048;CUNEIFORM SIGN BARA2;Lo;0;L;;;;;N;;;;; +12049;CUNEIFORM SIGN BI;Lo;0;L;;;;;N;;;;; +1204A;CUNEIFORM SIGN BI TIMES A;Lo;0;L;;;;;N;;;;; +1204B;CUNEIFORM SIGN BI TIMES GAR;Lo;0;L;;;;;N;;;;; +1204C;CUNEIFORM SIGN BI TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +1204D;CUNEIFORM SIGN BU;Lo;0;L;;;;;N;;;;; +1204E;CUNEIFORM SIGN BU OVER BU AB;Lo;0;L;;;;;N;;;;; +1204F;CUNEIFORM SIGN BU OVER BU UN;Lo;0;L;;;;;N;;;;; +12050;CUNEIFORM SIGN BU CROSSING BU;Lo;0;L;;;;;N;;;;; +12051;CUNEIFORM SIGN BULUG;Lo;0;L;;;;;N;;;;; +12052;CUNEIFORM SIGN BULUG OVER BULUG;Lo;0;L;;;;;N;;;;; +12053;CUNEIFORM SIGN BUR;Lo;0;L;;;;;N;;;;; +12054;CUNEIFORM SIGN BUR2;Lo;0;L;;;;;N;;;;; +12055;CUNEIFORM SIGN DA;Lo;0;L;;;;;N;;;;; +12056;CUNEIFORM SIGN DAG;Lo;0;L;;;;;N;;;;; +12057;CUNEIFORM SIGN DAG KISIM5 TIMES A PLUS MASH;Lo;0;L;;;;;N;;;;; +12058;CUNEIFORM SIGN DAG KISIM5 TIMES AMAR;Lo;0;L;;;;;N;;;;; +12059;CUNEIFORM SIGN DAG KISIM5 TIMES BALAG;Lo;0;L;;;;;N;;;;; +1205A;CUNEIFORM SIGN DAG KISIM5 TIMES BI;Lo;0;L;;;;;N;;;;; +1205B;CUNEIFORM SIGN DAG KISIM5 TIMES GA;Lo;0;L;;;;;N;;;;; +1205C;CUNEIFORM SIGN DAG KISIM5 TIMES GA PLUS MASH;Lo;0;L;;;;;N;;;;; +1205D;CUNEIFORM SIGN DAG KISIM5 TIMES GI;Lo;0;L;;;;;N;;;;; +1205E;CUNEIFORM SIGN DAG KISIM5 TIMES GIR2;Lo;0;L;;;;;N;;;;; +1205F;CUNEIFORM SIGN DAG KISIM5 TIMES GUD;Lo;0;L;;;;;N;;;;; +12060;CUNEIFORM SIGN DAG KISIM5 TIMES HA;Lo;0;L;;;;;N;;;;; +12061;CUNEIFORM SIGN DAG KISIM5 TIMES IR;Lo;0;L;;;;;N;;;;; +12062;CUNEIFORM SIGN DAG KISIM5 TIMES IR PLUS LU;Lo;0;L;;;;;N;;;;; +12063;CUNEIFORM SIGN DAG KISIM5 TIMES KAK;Lo;0;L;;;;;N;;;;; +12064;CUNEIFORM SIGN DAG KISIM5 TIMES LA;Lo;0;L;;;;;N;;;;; +12065;CUNEIFORM SIGN DAG KISIM5 TIMES LU;Lo;0;L;;;;;N;;;;; +12066;CUNEIFORM SIGN DAG KISIM5 TIMES LU PLUS MASH2;Lo;0;L;;;;;N;;;;; +12067;CUNEIFORM SIGN DAG KISIM5 TIMES LUM;Lo;0;L;;;;;N;;;;; +12068;CUNEIFORM SIGN DAG KISIM5 TIMES NE;Lo;0;L;;;;;N;;;;; +12069;CUNEIFORM SIGN DAG KISIM5 TIMES PAP PLUS PAP;Lo;0;L;;;;;N;;;;; +1206A;CUNEIFORM SIGN DAG KISIM5 TIMES SI;Lo;0;L;;;;;N;;;;; +1206B;CUNEIFORM SIGN DAG KISIM5 TIMES TAK4;Lo;0;L;;;;;N;;;;; +1206C;CUNEIFORM SIGN DAG KISIM5 TIMES U2 PLUS GIR2;Lo;0;L;;;;;N;;;;; +1206D;CUNEIFORM SIGN DAG KISIM5 TIMES USH;Lo;0;L;;;;;N;;;;; +1206E;CUNEIFORM SIGN DAM;Lo;0;L;;;;;N;;;;; +1206F;CUNEIFORM SIGN DAR;Lo;0;L;;;;;N;;;;; +12070;CUNEIFORM SIGN DARA3;Lo;0;L;;;;;N;;;;; +12071;CUNEIFORM SIGN DARA4;Lo;0;L;;;;;N;;;;; +12072;CUNEIFORM SIGN DI;Lo;0;L;;;;;N;;;;; +12073;CUNEIFORM SIGN DIB;Lo;0;L;;;;;N;;;;; +12074;CUNEIFORM SIGN DIM;Lo;0;L;;;;;N;;;;; +12075;CUNEIFORM SIGN DIM TIMES SHE;Lo;0;L;;;;;N;;;;; +12076;CUNEIFORM SIGN DIM2;Lo;0;L;;;;;N;;;;; +12077;CUNEIFORM SIGN DIN;Lo;0;L;;;;;N;;;;; +12078;CUNEIFORM SIGN DIN KASKAL U GUNU DISH;Lo;0;L;;;;;N;;;;; +12079;CUNEIFORM SIGN DISH;Lo;0;L;;;;;N;;;;; +1207A;CUNEIFORM SIGN DU;Lo;0;L;;;;;N;;;;; +1207B;CUNEIFORM SIGN DU OVER DU;Lo;0;L;;;;;N;;;;; +1207C;CUNEIFORM SIGN DU GUNU;Lo;0;L;;;;;N;;;;; +1207D;CUNEIFORM SIGN DU SHESHIG;Lo;0;L;;;;;N;;;;; +1207E;CUNEIFORM SIGN DUB;Lo;0;L;;;;;N;;;;; +1207F;CUNEIFORM SIGN DUB TIMES ESH2;Lo;0;L;;;;;N;;;;; +12080;CUNEIFORM SIGN DUB2;Lo;0;L;;;;;N;;;;; +12081;CUNEIFORM SIGN DUG;Lo;0;L;;;;;N;;;;; +12082;CUNEIFORM SIGN DUGUD;Lo;0;L;;;;;N;;;;; +12083;CUNEIFORM SIGN DUH;Lo;0;L;;;;;N;;;;; +12084;CUNEIFORM SIGN DUN;Lo;0;L;;;;;N;;;;; +12085;CUNEIFORM SIGN DUN3;Lo;0;L;;;;;N;;;;; +12086;CUNEIFORM SIGN DUN3 GUNU;Lo;0;L;;;;;N;;;;; +12087;CUNEIFORM SIGN DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;; +12088;CUNEIFORM SIGN DUN4;Lo;0;L;;;;;N;;;;; +12089;CUNEIFORM SIGN DUR2;Lo;0;L;;;;;N;;;;; +1208A;CUNEIFORM SIGN E;Lo;0;L;;;;;N;;;;; +1208B;CUNEIFORM SIGN E TIMES PAP;Lo;0;L;;;;;N;;;;; +1208C;CUNEIFORM SIGN E OVER E NUN OVER NUN;Lo;0;L;;;;;N;;;;; +1208D;CUNEIFORM SIGN E2;Lo;0;L;;;;;N;;;;; +1208E;CUNEIFORM SIGN E2 TIMES A PLUS HA PLUS DA;Lo;0;L;;;;;N;;;;; +1208F;CUNEIFORM SIGN E2 TIMES GAR;Lo;0;L;;;;;N;;;;; +12090;CUNEIFORM SIGN E2 TIMES MI;Lo;0;L;;;;;N;;;;; +12091;CUNEIFORM SIGN E2 TIMES SAL;Lo;0;L;;;;;N;;;;; +12092;CUNEIFORM SIGN E2 TIMES SHE;Lo;0;L;;;;;N;;;;; +12093;CUNEIFORM SIGN E2 TIMES U;Lo;0;L;;;;;N;;;;; +12094;CUNEIFORM SIGN EDIN;Lo;0;L;;;;;N;;;;; +12095;CUNEIFORM SIGN EGIR;Lo;0;L;;;;;N;;;;; +12096;CUNEIFORM SIGN EL;Lo;0;L;;;;;N;;;;; +12097;CUNEIFORM SIGN EN;Lo;0;L;;;;;N;;;;; +12098;CUNEIFORM SIGN EN TIMES GAN2;Lo;0;L;;;;;N;;;;; +12099;CUNEIFORM SIGN EN TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +1209A;CUNEIFORM SIGN EN TIMES ME;Lo;0;L;;;;;N;;;;; +1209B;CUNEIFORM SIGN EN CROSSING EN;Lo;0;L;;;;;N;;;;; +1209C;CUNEIFORM SIGN EN OPPOSING EN;Lo;0;L;;;;;N;;;;; +1209D;CUNEIFORM SIGN EN SQUARED;Lo;0;L;;;;;N;;;;; +1209E;CUNEIFORM SIGN EREN;Lo;0;L;;;;;N;;;;; +1209F;CUNEIFORM SIGN ERIN2;Lo;0;L;;;;;N;;;;; +120A0;CUNEIFORM SIGN ESH2;Lo;0;L;;;;;N;;;;; +120A1;CUNEIFORM SIGN EZEN;Lo;0;L;;;;;N;;;;; +120A2;CUNEIFORM SIGN EZEN TIMES A;Lo;0;L;;;;;N;;;;; +120A3;CUNEIFORM SIGN EZEN TIMES A PLUS LAL;Lo;0;L;;;;;N;;;;; +120A4;CUNEIFORM SIGN EZEN TIMES A PLUS LAL TIMES LAL;Lo;0;L;;;;;N;;;;; +120A5;CUNEIFORM SIGN EZEN TIMES AN;Lo;0;L;;;;;N;;;;; +120A6;CUNEIFORM SIGN EZEN TIMES BAD;Lo;0;L;;;;;N;;;;; +120A7;CUNEIFORM SIGN EZEN TIMES DUN3 GUNU;Lo;0;L;;;;;N;;;;; +120A8;CUNEIFORM SIGN EZEN TIMES DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;; +120A9;CUNEIFORM SIGN EZEN TIMES HA;Lo;0;L;;;;;N;;;;; +120AA;CUNEIFORM SIGN EZEN TIMES HA GUNU;Lo;0;L;;;;;N;;;;; +120AB;CUNEIFORM SIGN EZEN TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +120AC;CUNEIFORM SIGN EZEN TIMES KASKAL;Lo;0;L;;;;;N;;;;; +120AD;CUNEIFORM SIGN EZEN TIMES KASKAL SQUARED;Lo;0;L;;;;;N;;;;; +120AE;CUNEIFORM SIGN EZEN TIMES KU3;Lo;0;L;;;;;N;;;;; +120AF;CUNEIFORM SIGN EZEN TIMES LA;Lo;0;L;;;;;N;;;;; +120B0;CUNEIFORM SIGN EZEN TIMES LAL TIMES LAL;Lo;0;L;;;;;N;;;;; +120B1;CUNEIFORM SIGN EZEN TIMES LI;Lo;0;L;;;;;N;;;;; +120B2;CUNEIFORM SIGN EZEN TIMES LU;Lo;0;L;;;;;N;;;;; +120B3;CUNEIFORM SIGN EZEN TIMES U2;Lo;0;L;;;;;N;;;;; +120B4;CUNEIFORM SIGN EZEN TIMES UD;Lo;0;L;;;;;N;;;;; +120B5;CUNEIFORM SIGN GA;Lo;0;L;;;;;N;;;;; +120B6;CUNEIFORM SIGN GA GUNU;Lo;0;L;;;;;N;;;;; +120B7;CUNEIFORM SIGN GA2;Lo;0;L;;;;;N;;;;; +120B8;CUNEIFORM SIGN GA2 TIMES A PLUS DA PLUS HA;Lo;0;L;;;;;N;;;;; +120B9;CUNEIFORM SIGN GA2 TIMES A PLUS HA;Lo;0;L;;;;;N;;;;; +120BA;CUNEIFORM SIGN GA2 TIMES A PLUS IGI;Lo;0;L;;;;;N;;;;; +120BB;CUNEIFORM SIGN GA2 TIMES AB2 TENU PLUS TAB;Lo;0;L;;;;;N;;;;; +120BC;CUNEIFORM SIGN GA2 TIMES AN;Lo;0;L;;;;;N;;;;; +120BD;CUNEIFORM SIGN GA2 TIMES ASH;Lo;0;L;;;;;N;;;;; +120BE;CUNEIFORM SIGN GA2 TIMES ASH2 PLUS GAL;Lo;0;L;;;;;N;;;;; +120BF;CUNEIFORM SIGN GA2 TIMES BAD;Lo;0;L;;;;;N;;;;; +120C0;CUNEIFORM SIGN GA2 TIMES BAR PLUS RA;Lo;0;L;;;;;N;;;;; +120C1;CUNEIFORM SIGN GA2 TIMES BUR;Lo;0;L;;;;;N;;;;; +120C2;CUNEIFORM SIGN GA2 TIMES BUR PLUS RA;Lo;0;L;;;;;N;;;;; +120C3;CUNEIFORM SIGN GA2 TIMES DA;Lo;0;L;;;;;N;;;;; +120C4;CUNEIFORM SIGN GA2 TIMES DI;Lo;0;L;;;;;N;;;;; +120C5;CUNEIFORM SIGN GA2 TIMES DIM TIMES SHE;Lo;0;L;;;;;N;;;;; +120C6;CUNEIFORM SIGN GA2 TIMES DUB;Lo;0;L;;;;;N;;;;; +120C7;CUNEIFORM SIGN GA2 TIMES EL;Lo;0;L;;;;;N;;;;; +120C8;CUNEIFORM SIGN GA2 TIMES EL PLUS LA;Lo;0;L;;;;;N;;;;; +120C9;CUNEIFORM SIGN GA2 TIMES EN;Lo;0;L;;;;;N;;;;; +120CA;CUNEIFORM SIGN GA2 TIMES EN TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +120CB;CUNEIFORM SIGN GA2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +120CC;CUNEIFORM SIGN GA2 TIMES GAR;Lo;0;L;;;;;N;;;;; +120CD;CUNEIFORM SIGN GA2 TIMES GI;Lo;0;L;;;;;N;;;;; +120CE;CUNEIFORM SIGN GA2 TIMES GI4;Lo;0;L;;;;;N;;;;; +120CF;CUNEIFORM SIGN GA2 TIMES GI4 PLUS A;Lo;0;L;;;;;N;;;;; +120D0;CUNEIFORM SIGN GA2 TIMES GIR2 PLUS SU;Lo;0;L;;;;;N;;;;; +120D1;CUNEIFORM SIGN GA2 TIMES HA PLUS LU PLUS ESH2;Lo;0;L;;;;;N;;;;; +120D2;CUNEIFORM SIGN GA2 TIMES HAL;Lo;0;L;;;;;N;;;;; +120D3;CUNEIFORM SIGN GA2 TIMES HAL PLUS LA;Lo;0;L;;;;;N;;;;; +120D4;CUNEIFORM SIGN GA2 TIMES HI PLUS LI;Lo;0;L;;;;;N;;;;; +120D5;CUNEIFORM SIGN GA2 TIMES HUB2;Lo;0;L;;;;;N;;;;; +120D6;CUNEIFORM SIGN GA2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +120D7;CUNEIFORM SIGN GA2 TIMES ISH PLUS HU PLUS ASH;Lo;0;L;;;;;N;;;;; +120D8;CUNEIFORM SIGN GA2 TIMES KAK;Lo;0;L;;;;;N;;;;; +120D9;CUNEIFORM SIGN GA2 TIMES KASKAL;Lo;0;L;;;;;N;;;;; +120DA;CUNEIFORM SIGN GA2 TIMES KID;Lo;0;L;;;;;N;;;;; +120DB;CUNEIFORM SIGN GA2 TIMES KID PLUS LAL;Lo;0;L;;;;;N;;;;; +120DC;CUNEIFORM SIGN GA2 TIMES KU3 PLUS AN;Lo;0;L;;;;;N;;;;; +120DD;CUNEIFORM SIGN GA2 TIMES LA;Lo;0;L;;;;;N;;;;; +120DE;CUNEIFORM SIGN GA2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;; +120DF;CUNEIFORM SIGN GA2 TIMES MI;Lo;0;L;;;;;N;;;;; +120E0;CUNEIFORM SIGN GA2 TIMES NUN;Lo;0;L;;;;;N;;;;; +120E1;CUNEIFORM SIGN GA2 TIMES NUN OVER NUN;Lo;0;L;;;;;N;;;;; +120E2;CUNEIFORM SIGN GA2 TIMES PA;Lo;0;L;;;;;N;;;;; +120E3;CUNEIFORM SIGN GA2 TIMES SAL;Lo;0;L;;;;;N;;;;; +120E4;CUNEIFORM SIGN GA2 TIMES SAR;Lo;0;L;;;;;N;;;;; +120E5;CUNEIFORM SIGN GA2 TIMES SHE;Lo;0;L;;;;;N;;;;; +120E6;CUNEIFORM SIGN GA2 TIMES SHE PLUS TUR;Lo;0;L;;;;;N;;;;; +120E7;CUNEIFORM SIGN GA2 TIMES SHID;Lo;0;L;;;;;N;;;;; +120E8;CUNEIFORM SIGN GA2 TIMES SUM;Lo;0;L;;;;;N;;;;; +120E9;CUNEIFORM SIGN GA2 TIMES TAK4;Lo;0;L;;;;;N;;;;; +120EA;CUNEIFORM SIGN GA2 TIMES U;Lo;0;L;;;;;N;;;;; +120EB;CUNEIFORM SIGN GA2 TIMES UD;Lo;0;L;;;;;N;;;;; +120EC;CUNEIFORM SIGN GA2 TIMES UD PLUS DU;Lo;0;L;;;;;N;;;;; +120ED;CUNEIFORM SIGN GA2 OVER GA2;Lo;0;L;;;;;N;;;;; +120EE;CUNEIFORM SIGN GABA;Lo;0;L;;;;;N;;;;; +120EF;CUNEIFORM SIGN GABA CROSSING GABA;Lo;0;L;;;;;N;;;;; +120F0;CUNEIFORM SIGN GAD;Lo;0;L;;;;;N;;;;; +120F1;CUNEIFORM SIGN GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;; +120F2;CUNEIFORM SIGN GAL;Lo;0;L;;;;;N;;;;; +120F3;CUNEIFORM SIGN GAL GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;; +120F4;CUNEIFORM SIGN GALAM;Lo;0;L;;;;;N;;;;; +120F5;CUNEIFORM SIGN GAM;Lo;0;L;;;;;N;;;;; +120F6;CUNEIFORM SIGN GAN;Lo;0;L;;;;;N;;;;; +120F7;CUNEIFORM SIGN GAN2;Lo;0;L;;;;;N;;;;; +120F8;CUNEIFORM SIGN GAN2 TENU;Lo;0;L;;;;;N;;;;; +120F9;CUNEIFORM SIGN GAN2 OVER GAN2;Lo;0;L;;;;;N;;;;; +120FA;CUNEIFORM SIGN GAN2 CROSSING GAN2;Lo;0;L;;;;;N;;;;; +120FB;CUNEIFORM SIGN GAR;Lo;0;L;;;;;N;;;;; +120FC;CUNEIFORM SIGN GAR3;Lo;0;L;;;;;N;;;;; +120FD;CUNEIFORM SIGN GASHAN;Lo;0;L;;;;;N;;;;; +120FE;CUNEIFORM SIGN GESHTIN;Lo;0;L;;;;;N;;;;; +120FF;CUNEIFORM SIGN GESHTIN TIMES KUR;Lo;0;L;;;;;N;;;;; +12100;CUNEIFORM SIGN GI;Lo;0;L;;;;;N;;;;; +12101;CUNEIFORM SIGN GI TIMES E;Lo;0;L;;;;;N;;;;; +12102;CUNEIFORM SIGN GI TIMES U;Lo;0;L;;;;;N;;;;; +12103;CUNEIFORM SIGN GI CROSSING GI;Lo;0;L;;;;;N;;;;; +12104;CUNEIFORM SIGN GI4;Lo;0;L;;;;;N;;;;; +12105;CUNEIFORM SIGN GI4 OVER GI4;Lo;0;L;;;;;N;;;;; +12106;CUNEIFORM SIGN GI4 CROSSING GI4;Lo;0;L;;;;;N;;;;; +12107;CUNEIFORM SIGN GIDIM;Lo;0;L;;;;;N;;;;; +12108;CUNEIFORM SIGN GIR2;Lo;0;L;;;;;N;;;;; +12109;CUNEIFORM SIGN GIR2 GUNU;Lo;0;L;;;;;N;;;;; +1210A;CUNEIFORM SIGN GIR3;Lo;0;L;;;;;N;;;;; +1210B;CUNEIFORM SIGN GIR3 TIMES A PLUS IGI;Lo;0;L;;;;;N;;;;; +1210C;CUNEIFORM SIGN GIR3 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +1210D;CUNEIFORM SIGN GIR3 TIMES IGI;Lo;0;L;;;;;N;;;;; +1210E;CUNEIFORM SIGN GIR3 TIMES LU PLUS IGI;Lo;0;L;;;;;N;;;;; +1210F;CUNEIFORM SIGN GIR3 TIMES PA;Lo;0;L;;;;;N;;;;; +12110;CUNEIFORM SIGN GISAL;Lo;0;L;;;;;N;;;;; +12111;CUNEIFORM SIGN GISH;Lo;0;L;;;;;N;;;;; +12112;CUNEIFORM SIGN GISH CROSSING GISH;Lo;0;L;;;;;N;;;;; +12113;CUNEIFORM SIGN GISH TIMES BAD;Lo;0;L;;;;;N;;;;; +12114;CUNEIFORM SIGN GISH TIMES TAK4;Lo;0;L;;;;;N;;;;; +12115;CUNEIFORM SIGN GISH TENU;Lo;0;L;;;;;N;;;;; +12116;CUNEIFORM SIGN GU;Lo;0;L;;;;;N;;;;; +12117;CUNEIFORM SIGN GU CROSSING GU;Lo;0;L;;;;;N;;;;; +12118;CUNEIFORM SIGN GU2;Lo;0;L;;;;;N;;;;; +12119;CUNEIFORM SIGN GU2 TIMES KAK;Lo;0;L;;;;;N;;;;; +1211A;CUNEIFORM SIGN GU2 TIMES KAK TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +1211B;CUNEIFORM SIGN GU2 TIMES NUN;Lo;0;L;;;;;N;;;;; +1211C;CUNEIFORM SIGN GU2 TIMES SAL PLUS TUG2;Lo;0;L;;;;;N;;;;; +1211D;CUNEIFORM SIGN GU2 GUNU;Lo;0;L;;;;;N;;;;; +1211E;CUNEIFORM SIGN GUD;Lo;0;L;;;;;N;;;;; +1211F;CUNEIFORM SIGN GUD TIMES A PLUS KUR;Lo;0;L;;;;;N;;;;; +12120;CUNEIFORM SIGN GUD TIMES KUR;Lo;0;L;;;;;N;;;;; +12121;CUNEIFORM SIGN GUD OVER GUD LUGAL;Lo;0;L;;;;;N;;;;; +12122;CUNEIFORM SIGN GUL;Lo;0;L;;;;;N;;;;; +12123;CUNEIFORM SIGN GUM;Lo;0;L;;;;;N;;;;; +12124;CUNEIFORM SIGN GUM TIMES SHE;Lo;0;L;;;;;N;;;;; +12125;CUNEIFORM SIGN GUR;Lo;0;L;;;;;N;;;;; +12126;CUNEIFORM SIGN GUR7;Lo;0;L;;;;;N;;;;; +12127;CUNEIFORM SIGN GURUN;Lo;0;L;;;;;N;;;;; +12128;CUNEIFORM SIGN GURUSH;Lo;0;L;;;;;N;;;;; +12129;CUNEIFORM SIGN HA;Lo;0;L;;;;;N;;;;; +1212A;CUNEIFORM SIGN HA TENU;Lo;0;L;;;;;N;;;;; +1212B;CUNEIFORM SIGN HA GUNU;Lo;0;L;;;;;N;;;;; +1212C;CUNEIFORM SIGN HAL;Lo;0;L;;;;;N;;;;; +1212D;CUNEIFORM SIGN HI;Lo;0;L;;;;;N;;;;; +1212E;CUNEIFORM SIGN HI TIMES ASH;Lo;0;L;;;;;N;;;;; +1212F;CUNEIFORM SIGN HI TIMES ASH2;Lo;0;L;;;;;N;;;;; +12130;CUNEIFORM SIGN HI TIMES BAD;Lo;0;L;;;;;N;;;;; +12131;CUNEIFORM SIGN HI TIMES DISH;Lo;0;L;;;;;N;;;;; +12132;CUNEIFORM SIGN HI TIMES GAD;Lo;0;L;;;;;N;;;;; +12133;CUNEIFORM SIGN HI TIMES KIN;Lo;0;L;;;;;N;;;;; +12134;CUNEIFORM SIGN HI TIMES NUN;Lo;0;L;;;;;N;;;;; +12135;CUNEIFORM SIGN HI TIMES SHE;Lo;0;L;;;;;N;;;;; +12136;CUNEIFORM SIGN HI TIMES U;Lo;0;L;;;;;N;;;;; +12137;CUNEIFORM SIGN HU;Lo;0;L;;;;;N;;;;; +12138;CUNEIFORM SIGN HUB2;Lo;0;L;;;;;N;;;;; +12139;CUNEIFORM SIGN HUB2 TIMES AN;Lo;0;L;;;;;N;;;;; +1213A;CUNEIFORM SIGN HUB2 TIMES HAL;Lo;0;L;;;;;N;;;;; +1213B;CUNEIFORM SIGN HUB2 TIMES KASKAL;Lo;0;L;;;;;N;;;;; +1213C;CUNEIFORM SIGN HUB2 TIMES LISH;Lo;0;L;;;;;N;;;;; +1213D;CUNEIFORM SIGN HUB2 TIMES UD;Lo;0;L;;;;;N;;;;; +1213E;CUNEIFORM SIGN HUL2;Lo;0;L;;;;;N;;;;; +1213F;CUNEIFORM SIGN I;Lo;0;L;;;;;N;;;;; +12140;CUNEIFORM SIGN I A;Lo;0;L;;;;;N;;;;; +12141;CUNEIFORM SIGN IB;Lo;0;L;;;;;N;;;;; +12142;CUNEIFORM SIGN IDIM;Lo;0;L;;;;;N;;;;; +12143;CUNEIFORM SIGN IDIM OVER IDIM BUR;Lo;0;L;;;;;N;;;;; +12144;CUNEIFORM SIGN IDIM OVER IDIM SQUARED;Lo;0;L;;;;;N;;;;; +12145;CUNEIFORM SIGN IG;Lo;0;L;;;;;N;;;;; +12146;CUNEIFORM SIGN IGI;Lo;0;L;;;;;N;;;;; +12147;CUNEIFORM SIGN IGI DIB;Lo;0;L;;;;;N;;;;; +12148;CUNEIFORM SIGN IGI RI;Lo;0;L;;;;;N;;;;; +12149;CUNEIFORM SIGN IGI OVER IGI SHIR OVER SHIR UD OVER UD;Lo;0;L;;;;;N;;;;; +1214A;CUNEIFORM SIGN IGI GUNU;Lo;0;L;;;;;N;;;;; +1214B;CUNEIFORM SIGN IL;Lo;0;L;;;;;N;;;;; +1214C;CUNEIFORM SIGN IL TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +1214D;CUNEIFORM SIGN IL2;Lo;0;L;;;;;N;;;;; +1214E;CUNEIFORM SIGN IM;Lo;0;L;;;;;N;;;;; +1214F;CUNEIFORM SIGN IM TIMES TAK4;Lo;0;L;;;;;N;;;;; +12150;CUNEIFORM SIGN IM CROSSING IM;Lo;0;L;;;;;N;;;;; +12151;CUNEIFORM SIGN IM OPPOSING IM;Lo;0;L;;;;;N;;;;; +12152;CUNEIFORM SIGN IM SQUARED;Lo;0;L;;;;;N;;;;; +12153;CUNEIFORM SIGN IMIN;Lo;0;L;;;;;N;;;;; +12154;CUNEIFORM SIGN IN;Lo;0;L;;;;;N;;;;; +12155;CUNEIFORM SIGN IR;Lo;0;L;;;;;N;;;;; +12156;CUNEIFORM SIGN ISH;Lo;0;L;;;;;N;;;;; +12157;CUNEIFORM SIGN KA;Lo;0;L;;;;;N;;;;; +12158;CUNEIFORM SIGN KA TIMES A;Lo;0;L;;;;;N;;;;; +12159;CUNEIFORM SIGN KA TIMES AD;Lo;0;L;;;;;N;;;;; +1215A;CUNEIFORM SIGN KA TIMES AD PLUS KU3;Lo;0;L;;;;;N;;;;; +1215B;CUNEIFORM SIGN KA TIMES ASH2;Lo;0;L;;;;;N;;;;; +1215C;CUNEIFORM SIGN KA TIMES BAD;Lo;0;L;;;;;N;;;;; +1215D;CUNEIFORM SIGN KA TIMES BALAG;Lo;0;L;;;;;N;;;;; +1215E;CUNEIFORM SIGN KA TIMES BAR;Lo;0;L;;;;;N;;;;; +1215F;CUNEIFORM SIGN KA TIMES BI;Lo;0;L;;;;;N;;;;; +12160;CUNEIFORM SIGN KA TIMES ERIN2;Lo;0;L;;;;;N;;;;; +12161;CUNEIFORM SIGN KA TIMES ESH2;Lo;0;L;;;;;N;;;;; +12162;CUNEIFORM SIGN KA TIMES GA;Lo;0;L;;;;;N;;;;; +12163;CUNEIFORM SIGN KA TIMES GAL;Lo;0;L;;;;;N;;;;; +12164;CUNEIFORM SIGN KA TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +12165;CUNEIFORM SIGN KA TIMES GAR;Lo;0;L;;;;;N;;;;; +12166;CUNEIFORM SIGN KA TIMES GAR PLUS SHA3 PLUS A;Lo;0;L;;;;;N;;;;; +12167;CUNEIFORM SIGN KA TIMES GI;Lo;0;L;;;;;N;;;;; +12168;CUNEIFORM SIGN KA TIMES GIR2;Lo;0;L;;;;;N;;;;; +12169;CUNEIFORM SIGN KA TIMES GISH PLUS SAR;Lo;0;L;;;;;N;;;;; +1216A;CUNEIFORM SIGN KA TIMES GISH CROSSING GISH;Lo;0;L;;;;;N;;;;; +1216B;CUNEIFORM SIGN KA TIMES GU;Lo;0;L;;;;;N;;;;; +1216C;CUNEIFORM SIGN KA TIMES GUR7;Lo;0;L;;;;;N;;;;; +1216D;CUNEIFORM SIGN KA TIMES IGI;Lo;0;L;;;;;N;;;;; +1216E;CUNEIFORM SIGN KA TIMES IM;Lo;0;L;;;;;N;;;;; +1216F;CUNEIFORM SIGN KA TIMES KAK;Lo;0;L;;;;;N;;;;; +12170;CUNEIFORM SIGN KA TIMES KI;Lo;0;L;;;;;N;;;;; +12171;CUNEIFORM SIGN KA TIMES KID;Lo;0;L;;;;;N;;;;; +12172;CUNEIFORM SIGN KA TIMES LI;Lo;0;L;;;;;N;;;;; +12173;CUNEIFORM SIGN KA TIMES LU;Lo;0;L;;;;;N;;;;; +12174;CUNEIFORM SIGN KA TIMES ME;Lo;0;L;;;;;N;;;;; +12175;CUNEIFORM SIGN KA TIMES ME PLUS DU;Lo;0;L;;;;;N;;;;; +12176;CUNEIFORM SIGN KA TIMES ME PLUS GI;Lo;0;L;;;;;N;;;;; +12177;CUNEIFORM SIGN KA TIMES ME PLUS TE;Lo;0;L;;;;;N;;;;; +12178;CUNEIFORM SIGN KA TIMES MI;Lo;0;L;;;;;N;;;;; +12179;CUNEIFORM SIGN KA TIMES MI PLUS NUNUZ;Lo;0;L;;;;;N;;;;; +1217A;CUNEIFORM SIGN KA TIMES NE;Lo;0;L;;;;;N;;;;; +1217B;CUNEIFORM SIGN KA TIMES NUN;Lo;0;L;;;;;N;;;;; +1217C;CUNEIFORM SIGN KA TIMES PI;Lo;0;L;;;;;N;;;;; +1217D;CUNEIFORM SIGN KA TIMES RU;Lo;0;L;;;;;N;;;;; +1217E;CUNEIFORM SIGN KA TIMES SA;Lo;0;L;;;;;N;;;;; +1217F;CUNEIFORM SIGN KA TIMES SAR;Lo;0;L;;;;;N;;;;; +12180;CUNEIFORM SIGN KA TIMES SHA;Lo;0;L;;;;;N;;;;; +12181;CUNEIFORM SIGN KA TIMES SHE;Lo;0;L;;;;;N;;;;; +12182;CUNEIFORM SIGN KA TIMES SHID;Lo;0;L;;;;;N;;;;; +12183;CUNEIFORM SIGN KA TIMES SHU;Lo;0;L;;;;;N;;;;; +12184;CUNEIFORM SIGN KA TIMES SIG;Lo;0;L;;;;;N;;;;; +12185;CUNEIFORM SIGN KA TIMES SUHUR;Lo;0;L;;;;;N;;;;; +12186;CUNEIFORM SIGN KA TIMES TAR;Lo;0;L;;;;;N;;;;; +12187;CUNEIFORM SIGN KA TIMES U;Lo;0;L;;;;;N;;;;; +12188;CUNEIFORM SIGN KA TIMES U2;Lo;0;L;;;;;N;;;;; +12189;CUNEIFORM SIGN KA TIMES UD;Lo;0;L;;;;;N;;;;; +1218A;CUNEIFORM SIGN KA TIMES UMUM TIMES PA;Lo;0;L;;;;;N;;;;; +1218B;CUNEIFORM SIGN KA TIMES USH;Lo;0;L;;;;;N;;;;; +1218C;CUNEIFORM SIGN KA TIMES ZI;Lo;0;L;;;;;N;;;;; +1218D;CUNEIFORM SIGN KA2;Lo;0;L;;;;;N;;;;; +1218E;CUNEIFORM SIGN KA2 CROSSING KA2;Lo;0;L;;;;;N;;;;; +1218F;CUNEIFORM SIGN KAB;Lo;0;L;;;;;N;;;;; +12190;CUNEIFORM SIGN KAD2;Lo;0;L;;;;;N;;;;; +12191;CUNEIFORM SIGN KAD3;Lo;0;L;;;;;N;;;;; +12192;CUNEIFORM SIGN KAD4;Lo;0;L;;;;;N;;;;; +12193;CUNEIFORM SIGN KAD5;Lo;0;L;;;;;N;;;;; +12194;CUNEIFORM SIGN KAD5 OVER KAD5;Lo;0;L;;;;;N;;;;; +12195;CUNEIFORM SIGN KAK;Lo;0;L;;;;;N;;;;; +12196;CUNEIFORM SIGN KAK TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +12197;CUNEIFORM SIGN KAL;Lo;0;L;;;;;N;;;;; +12198;CUNEIFORM SIGN KAL TIMES BAD;Lo;0;L;;;;;N;;;;; +12199;CUNEIFORM SIGN KAL CROSSING KAL;Lo;0;L;;;;;N;;;;; +1219A;CUNEIFORM SIGN KAM2;Lo;0;L;;;;;N;;;;; +1219B;CUNEIFORM SIGN KAM4;Lo;0;L;;;;;N;;;;; +1219C;CUNEIFORM SIGN KASKAL;Lo;0;L;;;;;N;;;;; +1219D;CUNEIFORM SIGN KASKAL LAGAB TIMES U OVER LAGAB TIMES U;Lo;0;L;;;;;N;;;;; +1219E;CUNEIFORM SIGN KASKAL OVER KASKAL LAGAB TIMES U OVER LAGAB TIMES U;Lo;0;L;;;;;N;;;;; +1219F;CUNEIFORM SIGN KESH2;Lo;0;L;;;;;N;;;;; +121A0;CUNEIFORM SIGN KI;Lo;0;L;;;;;N;;;;; +121A1;CUNEIFORM SIGN KI TIMES BAD;Lo;0;L;;;;;N;;;;; +121A2;CUNEIFORM SIGN KI TIMES U;Lo;0;L;;;;;N;;;;; +121A3;CUNEIFORM SIGN KI TIMES UD;Lo;0;L;;;;;N;;;;; +121A4;CUNEIFORM SIGN KID;Lo;0;L;;;;;N;;;;; +121A5;CUNEIFORM SIGN KIN;Lo;0;L;;;;;N;;;;; +121A6;CUNEIFORM SIGN KISAL;Lo;0;L;;;;;N;;;;; +121A7;CUNEIFORM SIGN KISH;Lo;0;L;;;;;N;;;;; +121A8;CUNEIFORM SIGN KISIM5;Lo;0;L;;;;;N;;;;; +121A9;CUNEIFORM SIGN KISIM5 OVER KISIM5;Lo;0;L;;;;;N;;;;; +121AA;CUNEIFORM SIGN KU;Lo;0;L;;;;;N;;;;; +121AB;CUNEIFORM SIGN KU OVER HI TIMES ASH2 KU OVER HI TIMES ASH2;Lo;0;L;;;;;N;;;;; +121AC;CUNEIFORM SIGN KU3;Lo;0;L;;;;;N;;;;; +121AD;CUNEIFORM SIGN KU4;Lo;0;L;;;;;N;;;;; +121AE;CUNEIFORM SIGN KU4 VARIANT FORM;Lo;0;L;;;;;N;;;;; +121AF;CUNEIFORM SIGN KU7;Lo;0;L;;;;;N;;;;; +121B0;CUNEIFORM SIGN KUL;Lo;0;L;;;;;N;;;;; +121B1;CUNEIFORM SIGN KUL GUNU;Lo;0;L;;;;;N;;;;; +121B2;CUNEIFORM SIGN KUN;Lo;0;L;;;;;N;;;;; +121B3;CUNEIFORM SIGN KUR;Lo;0;L;;;;;N;;;;; +121B4;CUNEIFORM SIGN KUR OPPOSING KUR;Lo;0;L;;;;;N;;;;; +121B5;CUNEIFORM SIGN KUSHU2;Lo;0;L;;;;;N;;;;; +121B6;CUNEIFORM SIGN KWU318;Lo;0;L;;;;;N;;;;; +121B7;CUNEIFORM SIGN LA;Lo;0;L;;;;;N;;;;; +121B8;CUNEIFORM SIGN LAGAB;Lo;0;L;;;;;N;;;;; +121B9;CUNEIFORM SIGN LAGAB TIMES A;Lo;0;L;;;;;N;;;;; +121BA;CUNEIFORM SIGN LAGAB TIMES A PLUS DA PLUS HA;Lo;0;L;;;;;N;;;;; +121BB;CUNEIFORM SIGN LAGAB TIMES A PLUS GAR;Lo;0;L;;;;;N;;;;; +121BC;CUNEIFORM SIGN LAGAB TIMES A PLUS LAL;Lo;0;L;;;;;N;;;;; +121BD;CUNEIFORM SIGN LAGAB TIMES AL;Lo;0;L;;;;;N;;;;; +121BE;CUNEIFORM SIGN LAGAB TIMES AN;Lo;0;L;;;;;N;;;;; +121BF;CUNEIFORM SIGN LAGAB TIMES ASH ZIDA TENU;Lo;0;L;;;;;N;;;;; +121C0;CUNEIFORM SIGN LAGAB TIMES BAD;Lo;0;L;;;;;N;;;;; +121C1;CUNEIFORM SIGN LAGAB TIMES BI;Lo;0;L;;;;;N;;;;; +121C2;CUNEIFORM SIGN LAGAB TIMES DAR;Lo;0;L;;;;;N;;;;; +121C3;CUNEIFORM SIGN LAGAB TIMES EN;Lo;0;L;;;;;N;;;;; +121C4;CUNEIFORM SIGN LAGAB TIMES GA;Lo;0;L;;;;;N;;;;; +121C5;CUNEIFORM SIGN LAGAB TIMES GAR;Lo;0;L;;;;;N;;;;; +121C6;CUNEIFORM SIGN LAGAB TIMES GUD;Lo;0;L;;;;;N;;;;; +121C7;CUNEIFORM SIGN LAGAB TIMES GUD PLUS GUD;Lo;0;L;;;;;N;;;;; +121C8;CUNEIFORM SIGN LAGAB TIMES HA;Lo;0;L;;;;;N;;;;; +121C9;CUNEIFORM SIGN LAGAB TIMES HAL;Lo;0;L;;;;;N;;;;; +121CA;CUNEIFORM SIGN LAGAB TIMES HI TIMES NUN;Lo;0;L;;;;;N;;;;; +121CB;CUNEIFORM SIGN LAGAB TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +121CC;CUNEIFORM SIGN LAGAB TIMES IM;Lo;0;L;;;;;N;;;;; +121CD;CUNEIFORM SIGN LAGAB TIMES IM PLUS HA;Lo;0;L;;;;;N;;;;; +121CE;CUNEIFORM SIGN LAGAB TIMES IM PLUS LU;Lo;0;L;;;;;N;;;;; +121CF;CUNEIFORM SIGN LAGAB TIMES KI;Lo;0;L;;;;;N;;;;; +121D0;CUNEIFORM SIGN LAGAB TIMES KIN;Lo;0;L;;;;;N;;;;; +121D1;CUNEIFORM SIGN LAGAB TIMES KU3;Lo;0;L;;;;;N;;;;; +121D2;CUNEIFORM SIGN LAGAB TIMES KUL;Lo;0;L;;;;;N;;;;; +121D3;CUNEIFORM SIGN LAGAB TIMES KUL PLUS HI PLUS A;Lo;0;L;;;;;N;;;;; +121D4;CUNEIFORM SIGN LAGAB TIMES LAGAB;Lo;0;L;;;;;N;;;;; +121D5;CUNEIFORM SIGN LAGAB TIMES LISH;Lo;0;L;;;;;N;;;;; +121D6;CUNEIFORM SIGN LAGAB TIMES LU;Lo;0;L;;;;;N;;;;; +121D7;CUNEIFORM SIGN LAGAB TIMES LUL;Lo;0;L;;;;;N;;;;; +121D8;CUNEIFORM SIGN LAGAB TIMES ME;Lo;0;L;;;;;N;;;;; +121D9;CUNEIFORM SIGN LAGAB TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;; +121DA;CUNEIFORM SIGN LAGAB TIMES MUSH;Lo;0;L;;;;;N;;;;; +121DB;CUNEIFORM SIGN LAGAB TIMES NE;Lo;0;L;;;;;N;;;;; +121DC;CUNEIFORM SIGN LAGAB TIMES SHE PLUS SUM;Lo;0;L;;;;;N;;;;; +121DD;CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH PLUS ERIN2;Lo;0;L;;;;;N;;;;; +121DE;CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH TENU;Lo;0;L;;;;;N;;;;; +121DF;CUNEIFORM SIGN LAGAB TIMES SHU2;Lo;0;L;;;;;N;;;;; +121E0;CUNEIFORM SIGN LAGAB TIMES SHU2 PLUS SHU2;Lo;0;L;;;;;N;;;;; +121E1;CUNEIFORM SIGN LAGAB TIMES SUM;Lo;0;L;;;;;N;;;;; +121E2;CUNEIFORM SIGN LAGAB TIMES TAG;Lo;0;L;;;;;N;;;;; +121E3;CUNEIFORM SIGN LAGAB TIMES TAK4;Lo;0;L;;;;;N;;;;; +121E4;CUNEIFORM SIGN LAGAB TIMES TE PLUS A PLUS SU PLUS NA;Lo;0;L;;;;;N;;;;; +121E5;CUNEIFORM SIGN LAGAB TIMES U;Lo;0;L;;;;;N;;;;; +121E6;CUNEIFORM SIGN LAGAB TIMES U PLUS A;Lo;0;L;;;;;N;;;;; +121E7;CUNEIFORM SIGN LAGAB TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;; +121E8;CUNEIFORM SIGN LAGAB TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;; +121E9;CUNEIFORM SIGN LAGAB TIMES UD;Lo;0;L;;;;;N;;;;; +121EA;CUNEIFORM SIGN LAGAB TIMES USH;Lo;0;L;;;;;N;;;;; +121EB;CUNEIFORM SIGN LAGAB SQUARED;Lo;0;L;;;;;N;;;;; +121EC;CUNEIFORM SIGN LAGAR;Lo;0;L;;;;;N;;;;; +121ED;CUNEIFORM SIGN LAGAR TIMES SHE;Lo;0;L;;;;;N;;;;; +121EE;CUNEIFORM SIGN LAGAR TIMES SHE PLUS SUM;Lo;0;L;;;;;N;;;;; +121EF;CUNEIFORM SIGN LAGAR GUNU;Lo;0;L;;;;;N;;;;; +121F0;CUNEIFORM SIGN LAGAR GUNU OVER LAGAR GUNU SHE;Lo;0;L;;;;;N;;;;; +121F1;CUNEIFORM SIGN LAHSHU;Lo;0;L;;;;;N;;;;; +121F2;CUNEIFORM SIGN LAL;Lo;0;L;;;;;N;;;;; +121F3;CUNEIFORM SIGN LAL TIMES LAL;Lo;0;L;;;;;N;;;;; +121F4;CUNEIFORM SIGN LAM;Lo;0;L;;;;;N;;;;; +121F5;CUNEIFORM SIGN LAM TIMES KUR;Lo;0;L;;;;;N;;;;; +121F6;CUNEIFORM SIGN LAM TIMES KUR PLUS RU;Lo;0;L;;;;;N;;;;; +121F7;CUNEIFORM SIGN LI;Lo;0;L;;;;;N;;;;; +121F8;CUNEIFORM SIGN LIL;Lo;0;L;;;;;N;;;;; +121F9;CUNEIFORM SIGN LIMMU2;Lo;0;L;;;;;N;;;;; +121FA;CUNEIFORM SIGN LISH;Lo;0;L;;;;;N;;;;; +121FB;CUNEIFORM SIGN LU;Lo;0;L;;;;;N;;;;; +121FC;CUNEIFORM SIGN LU TIMES BAD;Lo;0;L;;;;;N;;;;; +121FD;CUNEIFORM SIGN LU2;Lo;0;L;;;;;N;;;;; +121FE;CUNEIFORM SIGN LU2 TIMES AL;Lo;0;L;;;;;N;;;;; +121FF;CUNEIFORM SIGN LU2 TIMES BAD;Lo;0;L;;;;;N;;;;; +12200;CUNEIFORM SIGN LU2 TIMES ESH2;Lo;0;L;;;;;N;;;;; +12201;CUNEIFORM SIGN LU2 TIMES ESH2 TENU;Lo;0;L;;;;;N;;;;; +12202;CUNEIFORM SIGN LU2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +12203;CUNEIFORM SIGN LU2 TIMES HI TIMES BAD;Lo;0;L;;;;;N;;;;; +12204;CUNEIFORM SIGN LU2 TIMES IM;Lo;0;L;;;;;N;;;;; +12205;CUNEIFORM SIGN LU2 TIMES KAD2;Lo;0;L;;;;;N;;;;; +12206;CUNEIFORM SIGN LU2 TIMES KAD3;Lo;0;L;;;;;N;;;;; +12207;CUNEIFORM SIGN LU2 TIMES KAD3 PLUS ASH;Lo;0;L;;;;;N;;;;; +12208;CUNEIFORM SIGN LU2 TIMES KI;Lo;0;L;;;;;N;;;;; +12209;CUNEIFORM SIGN LU2 TIMES LA PLUS ASH;Lo;0;L;;;;;N;;;;; +1220A;CUNEIFORM SIGN LU2 TIMES LAGAB;Lo;0;L;;;;;N;;;;; +1220B;CUNEIFORM SIGN LU2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;; +1220C;CUNEIFORM SIGN LU2 TIMES NE;Lo;0;L;;;;;N;;;;; +1220D;CUNEIFORM SIGN LU2 TIMES NU;Lo;0;L;;;;;N;;;;; +1220E;CUNEIFORM SIGN LU2 TIMES SI PLUS ASH;Lo;0;L;;;;;N;;;;; +1220F;CUNEIFORM SIGN LU2 TIMES SIK2 PLUS BU;Lo;0;L;;;;;N;;;;; +12210;CUNEIFORM SIGN LU2 TIMES TUG2;Lo;0;L;;;;;N;;;;; +12211;CUNEIFORM SIGN LU2 TENU;Lo;0;L;;;;;N;;;;; +12212;CUNEIFORM SIGN LU2 CROSSING LU2;Lo;0;L;;;;;N;;;;; +12213;CUNEIFORM SIGN LU2 OPPOSING LU2;Lo;0;L;;;;;N;;;;; +12214;CUNEIFORM SIGN LU2 SQUARED;Lo;0;L;;;;;N;;;;; +12215;CUNEIFORM SIGN LU2 SHESHIG;Lo;0;L;;;;;N;;;;; +12216;CUNEIFORM SIGN LU3;Lo;0;L;;;;;N;;;;; +12217;CUNEIFORM SIGN LUGAL;Lo;0;L;;;;;N;;;;; +12218;CUNEIFORM SIGN LUGAL OVER LUGAL;Lo;0;L;;;;;N;;;;; +12219;CUNEIFORM SIGN LUGAL OPPOSING LUGAL;Lo;0;L;;;;;N;;;;; +1221A;CUNEIFORM SIGN LUGAL SHESHIG;Lo;0;L;;;;;N;;;;; +1221B;CUNEIFORM SIGN LUH;Lo;0;L;;;;;N;;;;; +1221C;CUNEIFORM SIGN LUL;Lo;0;L;;;;;N;;;;; +1221D;CUNEIFORM SIGN LUM;Lo;0;L;;;;;N;;;;; +1221E;CUNEIFORM SIGN LUM OVER LUM;Lo;0;L;;;;;N;;;;; +1221F;CUNEIFORM SIGN LUM OVER LUM GAR OVER GAR;Lo;0;L;;;;;N;;;;; +12220;CUNEIFORM SIGN MA;Lo;0;L;;;;;N;;;;; +12221;CUNEIFORM SIGN MA TIMES TAK4;Lo;0;L;;;;;N;;;;; +12222;CUNEIFORM SIGN MA GUNU;Lo;0;L;;;;;N;;;;; +12223;CUNEIFORM SIGN MA2;Lo;0;L;;;;;N;;;;; +12224;CUNEIFORM SIGN MAH;Lo;0;L;;;;;N;;;;; +12225;CUNEIFORM SIGN MAR;Lo;0;L;;;;;N;;;;; +12226;CUNEIFORM SIGN MASH;Lo;0;L;;;;;N;;;;; +12227;CUNEIFORM SIGN MASH2;Lo;0;L;;;;;N;;;;; +12228;CUNEIFORM SIGN ME;Lo;0;L;;;;;N;;;;; +12229;CUNEIFORM SIGN MES;Lo;0;L;;;;;N;;;;; +1222A;CUNEIFORM SIGN MI;Lo;0;L;;;;;N;;;;; +1222B;CUNEIFORM SIGN MIN;Lo;0;L;;;;;N;;;;; +1222C;CUNEIFORM SIGN MU;Lo;0;L;;;;;N;;;;; +1222D;CUNEIFORM SIGN MU OVER MU;Lo;0;L;;;;;N;;;;; +1222E;CUNEIFORM SIGN MUG;Lo;0;L;;;;;N;;;;; +1222F;CUNEIFORM SIGN MUG GUNU;Lo;0;L;;;;;N;;;;; +12230;CUNEIFORM SIGN MUNSUB;Lo;0;L;;;;;N;;;;; +12231;CUNEIFORM SIGN MURGU2;Lo;0;L;;;;;N;;;;; +12232;CUNEIFORM SIGN MUSH;Lo;0;L;;;;;N;;;;; +12233;CUNEIFORM SIGN MUSH TIMES A;Lo;0;L;;;;;N;;;;; +12234;CUNEIFORM SIGN MUSH TIMES KUR;Lo;0;L;;;;;N;;;;; +12235;CUNEIFORM SIGN MUSH TIMES ZA;Lo;0;L;;;;;N;;;;; +12236;CUNEIFORM SIGN MUSH OVER MUSH;Lo;0;L;;;;;N;;;;; +12237;CUNEIFORM SIGN MUSH OVER MUSH TIMES A PLUS NA;Lo;0;L;;;;;N;;;;; +12238;CUNEIFORM SIGN MUSH CROSSING MUSH;Lo;0;L;;;;;N;;;;; +12239;CUNEIFORM SIGN MUSH3;Lo;0;L;;;;;N;;;;; +1223A;CUNEIFORM SIGN MUSH3 TIMES A;Lo;0;L;;;;;N;;;;; +1223B;CUNEIFORM SIGN MUSH3 TIMES A PLUS DI;Lo;0;L;;;;;N;;;;; +1223C;CUNEIFORM SIGN MUSH3 TIMES DI;Lo;0;L;;;;;N;;;;; +1223D;CUNEIFORM SIGN MUSH3 GUNU;Lo;0;L;;;;;N;;;;; +1223E;CUNEIFORM SIGN NA;Lo;0;L;;;;;N;;;;; +1223F;CUNEIFORM SIGN NA2;Lo;0;L;;;;;N;;;;; +12240;CUNEIFORM SIGN NAGA;Lo;0;L;;;;;N;;;;; +12241;CUNEIFORM SIGN NAGA INVERTED;Lo;0;L;;;;;N;;;;; +12242;CUNEIFORM SIGN NAGA TIMES SHU TENU;Lo;0;L;;;;;N;;;;; +12243;CUNEIFORM SIGN NAGA OPPOSING NAGA;Lo;0;L;;;;;N;;;;; +12244;CUNEIFORM SIGN NAGAR;Lo;0;L;;;;;N;;;;; +12245;CUNEIFORM SIGN NAM NUTILLU;Lo;0;L;;;;;N;;;;; +12246;CUNEIFORM SIGN NAM;Lo;0;L;;;;;N;;;;; +12247;CUNEIFORM SIGN NAM2;Lo;0;L;;;;;N;;;;; +12248;CUNEIFORM SIGN NE;Lo;0;L;;;;;N;;;;; +12249;CUNEIFORM SIGN NE TIMES A;Lo;0;L;;;;;N;;;;; +1224A;CUNEIFORM SIGN NE TIMES UD;Lo;0;L;;;;;N;;;;; +1224B;CUNEIFORM SIGN NE SHESHIG;Lo;0;L;;;;;N;;;;; +1224C;CUNEIFORM SIGN NI;Lo;0;L;;;;;N;;;;; +1224D;CUNEIFORM SIGN NI TIMES E;Lo;0;L;;;;;N;;;;; +1224E;CUNEIFORM SIGN NI2;Lo;0;L;;;;;N;;;;; +1224F;CUNEIFORM SIGN NIM;Lo;0;L;;;;;N;;;;; +12250;CUNEIFORM SIGN NIM TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +12251;CUNEIFORM SIGN NIM TIMES GAR PLUS GAN2 TENU;Lo;0;L;;;;;N;;;;; +12252;CUNEIFORM SIGN NINDA2;Lo;0;L;;;;;N;;;;; +12253;CUNEIFORM SIGN NINDA2 TIMES AN;Lo;0;L;;;;;N;;;;; +12254;CUNEIFORM SIGN NINDA2 TIMES ASH;Lo;0;L;;;;;N;;;;; +12255;CUNEIFORM SIGN NINDA2 TIMES ASH PLUS ASH;Lo;0;L;;;;;N;;;;; +12256;CUNEIFORM SIGN NINDA2 TIMES GUD;Lo;0;L;;;;;N;;;;; +12257;CUNEIFORM SIGN NINDA2 TIMES ME PLUS GAN2 TENU;Lo;0;L;;;;;N;;;;; +12258;CUNEIFORM SIGN NINDA2 TIMES NE;Lo;0;L;;;;;N;;;;; +12259;CUNEIFORM SIGN NINDA2 TIMES NUN;Lo;0;L;;;;;N;;;;; +1225A;CUNEIFORM SIGN NINDA2 TIMES SHE;Lo;0;L;;;;;N;;;;; +1225B;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS A AN;Lo;0;L;;;;;N;;;;; +1225C;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH;Lo;0;L;;;;;N;;;;; +1225D;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH PLUS ASH;Lo;0;L;;;;;N;;;;; +1225E;CUNEIFORM SIGN NINDA2 TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;; +1225F;CUNEIFORM SIGN NINDA2 TIMES USH;Lo;0;L;;;;;N;;;;; +12260;CUNEIFORM SIGN NISAG;Lo;0;L;;;;;N;;;;; +12261;CUNEIFORM SIGN NU;Lo;0;L;;;;;N;;;;; +12262;CUNEIFORM SIGN NU11;Lo;0;L;;;;;N;;;;; +12263;CUNEIFORM SIGN NUN;Lo;0;L;;;;;N;;;;; +12264;CUNEIFORM SIGN NUN LAGAR TIMES GAR;Lo;0;L;;;;;N;;;;; +12265;CUNEIFORM SIGN NUN LAGAR TIMES MASH;Lo;0;L;;;;;N;;;;; +12266;CUNEIFORM SIGN NUN LAGAR TIMES SAL;Lo;0;L;;;;;N;;;;; +12267;CUNEIFORM SIGN NUN LAGAR TIMES SAL OVER NUN LAGAR TIMES SAL;Lo;0;L;;;;;N;;;;; +12268;CUNEIFORM SIGN NUN LAGAR TIMES USH;Lo;0;L;;;;;N;;;;; +12269;CUNEIFORM SIGN NUN TENU;Lo;0;L;;;;;N;;;;; +1226A;CUNEIFORM SIGN NUN OVER NUN;Lo;0;L;;;;;N;;;;; +1226B;CUNEIFORM SIGN NUN CROSSING NUN;Lo;0;L;;;;;N;;;;; +1226C;CUNEIFORM SIGN NUN CROSSING NUN LAGAR OVER LAGAR;Lo;0;L;;;;;N;;;;; +1226D;CUNEIFORM SIGN NUNUZ;Lo;0;L;;;;;N;;;;; +1226E;CUNEIFORM SIGN NUNUZ AB2 TIMES ASHGAB;Lo;0;L;;;;;N;;;;; +1226F;CUNEIFORM SIGN NUNUZ AB2 TIMES BI;Lo;0;L;;;;;N;;;;; +12270;CUNEIFORM SIGN NUNUZ AB2 TIMES DUG;Lo;0;L;;;;;N;;;;; +12271;CUNEIFORM SIGN NUNUZ AB2 TIMES GUD;Lo;0;L;;;;;N;;;;; +12272;CUNEIFORM SIGN NUNUZ AB2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +12273;CUNEIFORM SIGN NUNUZ AB2 TIMES KAD3;Lo;0;L;;;;;N;;;;; +12274;CUNEIFORM SIGN NUNUZ AB2 TIMES LA;Lo;0;L;;;;;N;;;;; +12275;CUNEIFORM SIGN NUNUZ AB2 TIMES NE;Lo;0;L;;;;;N;;;;; +12276;CUNEIFORM SIGN NUNUZ AB2 TIMES SILA3;Lo;0;L;;;;;N;;;;; +12277;CUNEIFORM SIGN NUNUZ AB2 TIMES U2;Lo;0;L;;;;;N;;;;; +12278;CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI;Lo;0;L;;;;;N;;;;; +12279;CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI U;Lo;0;L;;;;;N;;;;; +1227A;CUNEIFORM SIGN PA;Lo;0;L;;;;;N;;;;; +1227B;CUNEIFORM SIGN PAD;Lo;0;L;;;;;N;;;;; +1227C;CUNEIFORM SIGN PAN;Lo;0;L;;;;;N;;;;; +1227D;CUNEIFORM SIGN PAP;Lo;0;L;;;;;N;;;;; +1227E;CUNEIFORM SIGN PESH2;Lo;0;L;;;;;N;;;;; +1227F;CUNEIFORM SIGN PI;Lo;0;L;;;;;N;;;;; +12280;CUNEIFORM SIGN PI TIMES A;Lo;0;L;;;;;N;;;;; +12281;CUNEIFORM SIGN PI TIMES AB;Lo;0;L;;;;;N;;;;; +12282;CUNEIFORM SIGN PI TIMES BI;Lo;0;L;;;;;N;;;;; +12283;CUNEIFORM SIGN PI TIMES BU;Lo;0;L;;;;;N;;;;; +12284;CUNEIFORM SIGN PI TIMES E;Lo;0;L;;;;;N;;;;; +12285;CUNEIFORM SIGN PI TIMES I;Lo;0;L;;;;;N;;;;; +12286;CUNEIFORM SIGN PI TIMES IB;Lo;0;L;;;;;N;;;;; +12287;CUNEIFORM SIGN PI TIMES U;Lo;0;L;;;;;N;;;;; +12288;CUNEIFORM SIGN PI TIMES U2;Lo;0;L;;;;;N;;;;; +12289;CUNEIFORM SIGN PI CROSSING PI;Lo;0;L;;;;;N;;;;; +1228A;CUNEIFORM SIGN PIRIG;Lo;0;L;;;;;N;;;;; +1228B;CUNEIFORM SIGN PIRIG TIMES KAL;Lo;0;L;;;;;N;;;;; +1228C;CUNEIFORM SIGN PIRIG TIMES UD;Lo;0;L;;;;;N;;;;; +1228D;CUNEIFORM SIGN PIRIG TIMES ZA;Lo;0;L;;;;;N;;;;; +1228E;CUNEIFORM SIGN PIRIG OPPOSING PIRIG;Lo;0;L;;;;;N;;;;; +1228F;CUNEIFORM SIGN RA;Lo;0;L;;;;;N;;;;; +12290;CUNEIFORM SIGN RAB;Lo;0;L;;;;;N;;;;; +12291;CUNEIFORM SIGN RI;Lo;0;L;;;;;N;;;;; +12292;CUNEIFORM SIGN RU;Lo;0;L;;;;;N;;;;; +12293;CUNEIFORM SIGN SA;Lo;0;L;;;;;N;;;;; +12294;CUNEIFORM SIGN SAG NUTILLU;Lo;0;L;;;;;N;;;;; +12295;CUNEIFORM SIGN SAG;Lo;0;L;;;;;N;;;;; +12296;CUNEIFORM SIGN SAG TIMES A;Lo;0;L;;;;;N;;;;; +12297;CUNEIFORM SIGN SAG TIMES DU;Lo;0;L;;;;;N;;;;; +12298;CUNEIFORM SIGN SAG TIMES DUB;Lo;0;L;;;;;N;;;;; +12299;CUNEIFORM SIGN SAG TIMES HA;Lo;0;L;;;;;N;;;;; +1229A;CUNEIFORM SIGN SAG TIMES KAK;Lo;0;L;;;;;N;;;;; +1229B;CUNEIFORM SIGN SAG TIMES KUR;Lo;0;L;;;;;N;;;;; +1229C;CUNEIFORM SIGN SAG TIMES LUM;Lo;0;L;;;;;N;;;;; +1229D;CUNEIFORM SIGN SAG TIMES MI;Lo;0;L;;;;;N;;;;; +1229E;CUNEIFORM SIGN SAG TIMES NUN;Lo;0;L;;;;;N;;;;; +1229F;CUNEIFORM SIGN SAG TIMES SAL;Lo;0;L;;;;;N;;;;; +122A0;CUNEIFORM SIGN SAG TIMES SHID;Lo;0;L;;;;;N;;;;; +122A1;CUNEIFORM SIGN SAG TIMES TAB;Lo;0;L;;;;;N;;;;; +122A2;CUNEIFORM SIGN SAG TIMES U2;Lo;0;L;;;;;N;;;;; +122A3;CUNEIFORM SIGN SAG TIMES UB;Lo;0;L;;;;;N;;;;; +122A4;CUNEIFORM SIGN SAG TIMES UM;Lo;0;L;;;;;N;;;;; +122A5;CUNEIFORM SIGN SAG TIMES UR;Lo;0;L;;;;;N;;;;; +122A6;CUNEIFORM SIGN SAG TIMES USH;Lo;0;L;;;;;N;;;;; +122A7;CUNEIFORM SIGN SAG OVER SAG;Lo;0;L;;;;;N;;;;; +122A8;CUNEIFORM SIGN SAG GUNU;Lo;0;L;;;;;N;;;;; +122A9;CUNEIFORM SIGN SAL;Lo;0;L;;;;;N;;;;; +122AA;CUNEIFORM SIGN SAL LAGAB TIMES ASH2;Lo;0;L;;;;;N;;;;; +122AB;CUNEIFORM SIGN SANGA2;Lo;0;L;;;;;N;;;;; +122AC;CUNEIFORM SIGN SAR;Lo;0;L;;;;;N;;;;; +122AD;CUNEIFORM SIGN SHA;Lo;0;L;;;;;N;;;;; +122AE;CUNEIFORM SIGN SHA3;Lo;0;L;;;;;N;;;;; +122AF;CUNEIFORM SIGN SHA3 TIMES A;Lo;0;L;;;;;N;;;;; +122B0;CUNEIFORM SIGN SHA3 TIMES BAD;Lo;0;L;;;;;N;;;;; +122B1;CUNEIFORM SIGN SHA3 TIMES GISH;Lo;0;L;;;;;N;;;;; +122B2;CUNEIFORM SIGN SHA3 TIMES NE;Lo;0;L;;;;;N;;;;; +122B3;CUNEIFORM SIGN SHA3 TIMES SHU2;Lo;0;L;;;;;N;;;;; +122B4;CUNEIFORM SIGN SHA3 TIMES TUR;Lo;0;L;;;;;N;;;;; +122B5;CUNEIFORM SIGN SHA3 TIMES U;Lo;0;L;;;;;N;;;;; +122B6;CUNEIFORM SIGN SHA3 TIMES U PLUS A;Lo;0;L;;;;;N;;;;; +122B7;CUNEIFORM SIGN SHA6;Lo;0;L;;;;;N;;;;; +122B8;CUNEIFORM SIGN SHAB6;Lo;0;L;;;;;N;;;;; +122B9;CUNEIFORM SIGN SHAR2;Lo;0;L;;;;;N;;;;; +122BA;CUNEIFORM SIGN SHE;Lo;0;L;;;;;N;;;;; +122BB;CUNEIFORM SIGN SHE HU;Lo;0;L;;;;;N;;;;; +122BC;CUNEIFORM SIGN SHE OVER SHE GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;; +122BD;CUNEIFORM SIGN SHE OVER SHE TAB OVER TAB GAR OVER GAR;Lo;0;L;;;;;N;;;;; +122BE;CUNEIFORM SIGN SHEG9;Lo;0;L;;;;;N;;;;; +122BF;CUNEIFORM SIGN SHEN;Lo;0;L;;;;;N;;;;; +122C0;CUNEIFORM SIGN SHESH;Lo;0;L;;;;;N;;;;; +122C1;CUNEIFORM SIGN SHESH2;Lo;0;L;;;;;N;;;;; +122C2;CUNEIFORM SIGN SHESHLAM;Lo;0;L;;;;;N;;;;; +122C3;CUNEIFORM SIGN SHID;Lo;0;L;;;;;N;;;;; +122C4;CUNEIFORM SIGN SHID TIMES A;Lo;0;L;;;;;N;;;;; +122C5;CUNEIFORM SIGN SHID TIMES IM;Lo;0;L;;;;;N;;;;; +122C6;CUNEIFORM SIGN SHIM;Lo;0;L;;;;;N;;;;; +122C7;CUNEIFORM SIGN SHIM TIMES A;Lo;0;L;;;;;N;;;;; +122C8;CUNEIFORM SIGN SHIM TIMES BAL;Lo;0;L;;;;;N;;;;; +122C9;CUNEIFORM SIGN SHIM TIMES BULUG;Lo;0;L;;;;;N;;;;; +122CA;CUNEIFORM SIGN SHIM TIMES DIN;Lo;0;L;;;;;N;;;;; +122CB;CUNEIFORM SIGN SHIM TIMES GAR;Lo;0;L;;;;;N;;;;; +122CC;CUNEIFORM SIGN SHIM TIMES IGI;Lo;0;L;;;;;N;;;;; +122CD;CUNEIFORM SIGN SHIM TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +122CE;CUNEIFORM SIGN SHIM TIMES KUSHU2;Lo;0;L;;;;;N;;;;; +122CF;CUNEIFORM SIGN SHIM TIMES LUL;Lo;0;L;;;;;N;;;;; +122D0;CUNEIFORM SIGN SHIM TIMES MUG;Lo;0;L;;;;;N;;;;; +122D1;CUNEIFORM SIGN SHIM TIMES SAL;Lo;0;L;;;;;N;;;;; +122D2;CUNEIFORM SIGN SHINIG;Lo;0;L;;;;;N;;;;; +122D3;CUNEIFORM SIGN SHIR;Lo;0;L;;;;;N;;;;; +122D4;CUNEIFORM SIGN SHIR TENU;Lo;0;L;;;;;N;;;;; +122D5;CUNEIFORM SIGN SHIR OVER SHIR BUR OVER BUR;Lo;0;L;;;;;N;;;;; +122D6;CUNEIFORM SIGN SHITA;Lo;0;L;;;;;N;;;;; +122D7;CUNEIFORM SIGN SHU;Lo;0;L;;;;;N;;;;; +122D8;CUNEIFORM SIGN SHU OVER INVERTED SHU;Lo;0;L;;;;;N;;;;; +122D9;CUNEIFORM SIGN SHU2;Lo;0;L;;;;;N;;;;; +122DA;CUNEIFORM SIGN SHUBUR;Lo;0;L;;;;;N;;;;; +122DB;CUNEIFORM SIGN SI;Lo;0;L;;;;;N;;;;; +122DC;CUNEIFORM SIGN SI GUNU;Lo;0;L;;;;;N;;;;; +122DD;CUNEIFORM SIGN SIG;Lo;0;L;;;;;N;;;;; +122DE;CUNEIFORM SIGN SIG4;Lo;0;L;;;;;N;;;;; +122DF;CUNEIFORM SIGN SIG4 OVER SIG4 SHU2;Lo;0;L;;;;;N;;;;; +122E0;CUNEIFORM SIGN SIK2;Lo;0;L;;;;;N;;;;; +122E1;CUNEIFORM SIGN SILA3;Lo;0;L;;;;;N;;;;; +122E2;CUNEIFORM SIGN SU;Lo;0;L;;;;;N;;;;; +122E3;CUNEIFORM SIGN SU OVER SU;Lo;0;L;;;;;N;;;;; +122E4;CUNEIFORM SIGN SUD;Lo;0;L;;;;;N;;;;; +122E5;CUNEIFORM SIGN SUD2;Lo;0;L;;;;;N;;;;; +122E6;CUNEIFORM SIGN SUHUR;Lo;0;L;;;;;N;;;;; +122E7;CUNEIFORM SIGN SUM;Lo;0;L;;;;;N;;;;; +122E8;CUNEIFORM SIGN SUMASH;Lo;0;L;;;;;N;;;;; +122E9;CUNEIFORM SIGN SUR;Lo;0;L;;;;;N;;;;; +122EA;CUNEIFORM SIGN SUR9;Lo;0;L;;;;;N;;;;; +122EB;CUNEIFORM SIGN TA;Lo;0;L;;;;;N;;;;; +122EC;CUNEIFORM SIGN TA ASTERISK;Lo;0;L;;;;;N;;;;; +122ED;CUNEIFORM SIGN TA TIMES HI;Lo;0;L;;;;;N;;;;; +122EE;CUNEIFORM SIGN TA TIMES MI;Lo;0;L;;;;;N;;;;; +122EF;CUNEIFORM SIGN TA GUNU;Lo;0;L;;;;;N;;;;; +122F0;CUNEIFORM SIGN TAB;Lo;0;L;;;;;N;;;;; +122F1;CUNEIFORM SIGN TAB OVER TAB NI OVER NI DISH OVER DISH;Lo;0;L;;;;;N;;;;; +122F2;CUNEIFORM SIGN TAB SQUARED;Lo;0;L;;;;;N;;;;; +122F3;CUNEIFORM SIGN TAG;Lo;0;L;;;;;N;;;;; +122F4;CUNEIFORM SIGN TAG TIMES BI;Lo;0;L;;;;;N;;;;; +122F5;CUNEIFORM SIGN TAG TIMES GUD;Lo;0;L;;;;;N;;;;; +122F6;CUNEIFORM SIGN TAG TIMES SHE;Lo;0;L;;;;;N;;;;; +122F7;CUNEIFORM SIGN TAG TIMES SHU;Lo;0;L;;;;;N;;;;; +122F8;CUNEIFORM SIGN TAG TIMES TUG2;Lo;0;L;;;;;N;;;;; +122F9;CUNEIFORM SIGN TAG TIMES UD;Lo;0;L;;;;;N;;;;; +122FA;CUNEIFORM SIGN TAK4;Lo;0;L;;;;;N;;;;; +122FB;CUNEIFORM SIGN TAR;Lo;0;L;;;;;N;;;;; +122FC;CUNEIFORM SIGN TE;Lo;0;L;;;;;N;;;;; +122FD;CUNEIFORM SIGN TE GUNU;Lo;0;L;;;;;N;;;;; +122FE;CUNEIFORM SIGN TI;Lo;0;L;;;;;N;;;;; +122FF;CUNEIFORM SIGN TI TENU;Lo;0;L;;;;;N;;;;; +12300;CUNEIFORM SIGN TIL;Lo;0;L;;;;;N;;;;; +12301;CUNEIFORM SIGN TIR;Lo;0;L;;;;;N;;;;; +12302;CUNEIFORM SIGN TIR TIMES TAK4;Lo;0;L;;;;;N;;;;; +12303;CUNEIFORM SIGN TIR OVER TIR;Lo;0;L;;;;;N;;;;; +12304;CUNEIFORM SIGN TIR OVER TIR GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;; +12305;CUNEIFORM SIGN TU;Lo;0;L;;;;;N;;;;; +12306;CUNEIFORM SIGN TUG2;Lo;0;L;;;;;N;;;;; +12307;CUNEIFORM SIGN TUK;Lo;0;L;;;;;N;;;;; +12308;CUNEIFORM SIGN TUM;Lo;0;L;;;;;N;;;;; +12309;CUNEIFORM SIGN TUR;Lo;0;L;;;;;N;;;;; +1230A;CUNEIFORM SIGN TUR OVER TUR ZA OVER ZA;Lo;0;L;;;;;N;;;;; +1230B;CUNEIFORM SIGN U;Lo;0;L;;;;;N;;;;; +1230C;CUNEIFORM SIGN U GUD;Lo;0;L;;;;;N;;;;; +1230D;CUNEIFORM SIGN U U U;Lo;0;L;;;;;N;;;;; +1230E;CUNEIFORM SIGN U OVER U PA OVER PA GAR OVER GAR;Lo;0;L;;;;;N;;;;; +1230F;CUNEIFORM SIGN U OVER U SUR OVER SUR;Lo;0;L;;;;;N;;;;; +12310;CUNEIFORM SIGN U OVER U U REVERSED OVER U REVERSED;Lo;0;L;;;;;N;;;;; +12311;CUNEIFORM SIGN U2;Lo;0;L;;;;;N;;;;; +12312;CUNEIFORM SIGN UB;Lo;0;L;;;;;N;;;;; +12313;CUNEIFORM SIGN UD;Lo;0;L;;;;;N;;;;; +12314;CUNEIFORM SIGN UD KUSHU2;Lo;0;L;;;;;N;;;;; +12315;CUNEIFORM SIGN UD TIMES BAD;Lo;0;L;;;;;N;;;;; +12316;CUNEIFORM SIGN UD TIMES MI;Lo;0;L;;;;;N;;;;; +12317;CUNEIFORM SIGN UD TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;; +12318;CUNEIFORM SIGN UD TIMES U PLUS U PLUS U GUNU;Lo;0;L;;;;;N;;;;; +12319;CUNEIFORM SIGN UD GUNU;Lo;0;L;;;;;N;;;;; +1231A;CUNEIFORM SIGN UD SHESHIG;Lo;0;L;;;;;N;;;;; +1231B;CUNEIFORM SIGN UD SHESHIG TIMES BAD;Lo;0;L;;;;;N;;;;; +1231C;CUNEIFORM SIGN UDUG;Lo;0;L;;;;;N;;;;; +1231D;CUNEIFORM SIGN UM;Lo;0;L;;;;;N;;;;; +1231E;CUNEIFORM SIGN UM TIMES LAGAB;Lo;0;L;;;;;N;;;;; +1231F;CUNEIFORM SIGN UM TIMES ME PLUS DA;Lo;0;L;;;;;N;;;;; +12320;CUNEIFORM SIGN UM TIMES SHA3;Lo;0;L;;;;;N;;;;; +12321;CUNEIFORM SIGN UM TIMES U;Lo;0;L;;;;;N;;;;; +12322;CUNEIFORM SIGN UMBIN;Lo;0;L;;;;;N;;;;; +12323;CUNEIFORM SIGN UMUM;Lo;0;L;;;;;N;;;;; +12324;CUNEIFORM SIGN UMUM TIMES KASKAL;Lo;0;L;;;;;N;;;;; +12325;CUNEIFORM SIGN UMUM TIMES PA;Lo;0;L;;;;;N;;;;; +12326;CUNEIFORM SIGN UN;Lo;0;L;;;;;N;;;;; +12327;CUNEIFORM SIGN UN GUNU;Lo;0;L;;;;;N;;;;; +12328;CUNEIFORM SIGN UR;Lo;0;L;;;;;N;;;;; +12329;CUNEIFORM SIGN UR CROSSING UR;Lo;0;L;;;;;N;;;;; +1232A;CUNEIFORM SIGN UR SHESHIG;Lo;0;L;;;;;N;;;;; +1232B;CUNEIFORM SIGN UR2;Lo;0;L;;;;;N;;;;; +1232C;CUNEIFORM SIGN UR2 TIMES A PLUS HA;Lo;0;L;;;;;N;;;;; +1232D;CUNEIFORM SIGN UR2 TIMES A PLUS NA;Lo;0;L;;;;;N;;;;; +1232E;CUNEIFORM SIGN UR2 TIMES AL;Lo;0;L;;;;;N;;;;; +1232F;CUNEIFORM SIGN UR2 TIMES HA;Lo;0;L;;;;;N;;;;; +12330;CUNEIFORM SIGN UR2 TIMES NUN;Lo;0;L;;;;;N;;;;; +12331;CUNEIFORM SIGN UR2 TIMES U2;Lo;0;L;;;;;N;;;;; +12332;CUNEIFORM SIGN UR2 TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;; +12333;CUNEIFORM SIGN UR2 TIMES U2 PLUS BI;Lo;0;L;;;;;N;;;;; +12334;CUNEIFORM SIGN UR4;Lo;0;L;;;;;N;;;;; +12335;CUNEIFORM SIGN URI;Lo;0;L;;;;;N;;;;; +12336;CUNEIFORM SIGN URI3;Lo;0;L;;;;;N;;;;; +12337;CUNEIFORM SIGN URU;Lo;0;L;;;;;N;;;;; +12338;CUNEIFORM SIGN URU TIMES A;Lo;0;L;;;;;N;;;;; +12339;CUNEIFORM SIGN URU TIMES ASHGAB;Lo;0;L;;;;;N;;;;; +1233A;CUNEIFORM SIGN URU TIMES BAR;Lo;0;L;;;;;N;;;;; +1233B;CUNEIFORM SIGN URU TIMES DUN;Lo;0;L;;;;;N;;;;; +1233C;CUNEIFORM SIGN URU TIMES GA;Lo;0;L;;;;;N;;;;; +1233D;CUNEIFORM SIGN URU TIMES GAL;Lo;0;L;;;;;N;;;;; +1233E;CUNEIFORM SIGN URU TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +1233F;CUNEIFORM SIGN URU TIMES GAR;Lo;0;L;;;;;N;;;;; +12340;CUNEIFORM SIGN URU TIMES GU;Lo;0;L;;;;;N;;;;; +12341;CUNEIFORM SIGN URU TIMES HA;Lo;0;L;;;;;N;;;;; +12342;CUNEIFORM SIGN URU TIMES IGI;Lo;0;L;;;;;N;;;;; +12343;CUNEIFORM SIGN URU TIMES IM;Lo;0;L;;;;;N;;;;; +12344;CUNEIFORM SIGN URU TIMES ISH;Lo;0;L;;;;;N;;;;; +12345;CUNEIFORM SIGN URU TIMES KI;Lo;0;L;;;;;N;;;;; +12346;CUNEIFORM SIGN URU TIMES LUM;Lo;0;L;;;;;N;;;;; +12347;CUNEIFORM SIGN URU TIMES MIN;Lo;0;L;;;;;N;;;;; +12348;CUNEIFORM SIGN URU TIMES PA;Lo;0;L;;;;;N;;;;; +12349;CUNEIFORM SIGN URU TIMES SHE;Lo;0;L;;;;;N;;;;; +1234A;CUNEIFORM SIGN URU TIMES SIG4;Lo;0;L;;;;;N;;;;; +1234B;CUNEIFORM SIGN URU TIMES TU;Lo;0;L;;;;;N;;;;; +1234C;CUNEIFORM SIGN URU TIMES U PLUS GUD;Lo;0;L;;;;;N;;;;; +1234D;CUNEIFORM SIGN URU TIMES UD;Lo;0;L;;;;;N;;;;; +1234E;CUNEIFORM SIGN URU TIMES URUDA;Lo;0;L;;;;;N;;;;; +1234F;CUNEIFORM SIGN URUDA;Lo;0;L;;;;;N;;;;; +12350;CUNEIFORM SIGN URUDA TIMES U;Lo;0;L;;;;;N;;;;; +12351;CUNEIFORM SIGN USH;Lo;0;L;;;;;N;;;;; +12352;CUNEIFORM SIGN USH TIMES A;Lo;0;L;;;;;N;;;;; +12353;CUNEIFORM SIGN USH TIMES KU;Lo;0;L;;;;;N;;;;; +12354;CUNEIFORM SIGN USH TIMES KUR;Lo;0;L;;;;;N;;;;; +12355;CUNEIFORM SIGN USH TIMES TAK4;Lo;0;L;;;;;N;;;;; +12356;CUNEIFORM SIGN USHX;Lo;0;L;;;;;N;;;;; +12357;CUNEIFORM SIGN USH2;Lo;0;L;;;;;N;;;;; +12358;CUNEIFORM SIGN USHUMX;Lo;0;L;;;;;N;;;;; +12359;CUNEIFORM SIGN UTUKI;Lo;0;L;;;;;N;;;;; +1235A;CUNEIFORM SIGN UZ3;Lo;0;L;;;;;N;;;;; +1235B;CUNEIFORM SIGN UZ3 TIMES KASKAL;Lo;0;L;;;;;N;;;;; +1235C;CUNEIFORM SIGN UZU;Lo;0;L;;;;;N;;;;; +1235D;CUNEIFORM SIGN ZA;Lo;0;L;;;;;N;;;;; +1235E;CUNEIFORM SIGN ZA TENU;Lo;0;L;;;;;N;;;;; +1235F;CUNEIFORM SIGN ZA SQUARED TIMES KUR;Lo;0;L;;;;;N;;;;; +12360;CUNEIFORM SIGN ZAG;Lo;0;L;;;;;N;;;;; +12361;CUNEIFORM SIGN ZAMX;Lo;0;L;;;;;N;;;;; +12362;CUNEIFORM SIGN ZE2;Lo;0;L;;;;;N;;;;; +12363;CUNEIFORM SIGN ZI;Lo;0;L;;;;;N;;;;; +12364;CUNEIFORM SIGN ZI OVER ZI;Lo;0;L;;;;;N;;;;; +12365;CUNEIFORM SIGN ZI3;Lo;0;L;;;;;N;;;;; +12366;CUNEIFORM SIGN ZIB;Lo;0;L;;;;;N;;;;; +12367;CUNEIFORM SIGN ZIB KABA TENU;Lo;0;L;;;;;N;;;;; +12368;CUNEIFORM SIGN ZIG;Lo;0;L;;;;;N;;;;; +12369;CUNEIFORM SIGN ZIZ2;Lo;0;L;;;;;N;;;;; +1236A;CUNEIFORM SIGN ZU;Lo;0;L;;;;;N;;;;; +1236B;CUNEIFORM SIGN ZU5;Lo;0;L;;;;;N;;;;; +1236C;CUNEIFORM SIGN ZU5 TIMES A;Lo;0;L;;;;;N;;;;; +1236D;CUNEIFORM SIGN ZUBUR;Lo;0;L;;;;;N;;;;; +1236E;CUNEIFORM SIGN ZUM;Lo;0;L;;;;;N;;;;; +1236F;CUNEIFORM SIGN KAP ELAMITE;Lo;0;L;;;;;N;;;;; +12370;CUNEIFORM SIGN AB TIMES NUN;Lo;0;L;;;;;N;;;;; +12371;CUNEIFORM SIGN AB2 TIMES A;Lo;0;L;;;;;N;;;;; +12372;CUNEIFORM SIGN AMAR TIMES KUG;Lo;0;L;;;;;N;;;;; +12373;CUNEIFORM SIGN DAG KISIM5 TIMES U2 PLUS MASH;Lo;0;L;;;;;N;;;;; +12374;CUNEIFORM SIGN DAG3;Lo;0;L;;;;;N;;;;; +12375;CUNEIFORM SIGN DISH PLUS SHU;Lo;0;L;;;;;N;;;;; +12376;CUNEIFORM SIGN DUB TIMES SHE;Lo;0;L;;;;;N;;;;; +12377;CUNEIFORM SIGN EZEN TIMES GUD;Lo;0;L;;;;;N;;;;; +12378;CUNEIFORM SIGN EZEN TIMES SHE;Lo;0;L;;;;;N;;;;; +12379;CUNEIFORM SIGN GA2 TIMES AN PLUS KAK PLUS A;Lo;0;L;;;;;N;;;;; +1237A;CUNEIFORM SIGN GA2 TIMES ASH2;Lo;0;L;;;;;N;;;;; +1237B;CUNEIFORM SIGN GE22;Lo;0;L;;;;;N;;;;; +1237C;CUNEIFORM SIGN GIG;Lo;0;L;;;;;N;;;;; +1237D;CUNEIFORM SIGN HUSH;Lo;0;L;;;;;N;;;;; +1237E;CUNEIFORM SIGN KA TIMES ANSHE;Lo;0;L;;;;;N;;;;; +1237F;CUNEIFORM SIGN KA TIMES ASH3;Lo;0;L;;;;;N;;;;; +12380;CUNEIFORM SIGN KA TIMES GISH;Lo;0;L;;;;;N;;;;; +12381;CUNEIFORM SIGN KA TIMES GUD;Lo;0;L;;;;;N;;;;; +12382;CUNEIFORM SIGN KA TIMES HI TIMES ASH2;Lo;0;L;;;;;N;;;;; +12383;CUNEIFORM SIGN KA TIMES LUM;Lo;0;L;;;;;N;;;;; +12384;CUNEIFORM SIGN KA TIMES PA;Lo;0;L;;;;;N;;;;; +12385;CUNEIFORM SIGN KA TIMES SHUL;Lo;0;L;;;;;N;;;;; +12386;CUNEIFORM SIGN KA TIMES TU;Lo;0;L;;;;;N;;;;; +12387;CUNEIFORM SIGN KA TIMES UR2;Lo;0;L;;;;;N;;;;; +12388;CUNEIFORM SIGN LAGAB TIMES GI;Lo;0;L;;;;;N;;;;; +12389;CUNEIFORM SIGN LU2 SHESHIG TIMES BAD;Lo;0;L;;;;;N;;;;; +1238A;CUNEIFORM SIGN LU2 TIMES ESH2 PLUS LAL;Lo;0;L;;;;;N;;;;; +1238B;CUNEIFORM SIGN LU2 TIMES SHU;Lo;0;L;;;;;N;;;;; +1238C;CUNEIFORM SIGN MESH;Lo;0;L;;;;;N;;;;; +1238D;CUNEIFORM SIGN MUSH3 TIMES ZA;Lo;0;L;;;;;N;;;;; +1238E;CUNEIFORM SIGN NA4;Lo;0;L;;;;;N;;;;; +1238F;CUNEIFORM SIGN NIN;Lo;0;L;;;;;N;;;;; +12390;CUNEIFORM SIGN NIN9;Lo;0;L;;;;;N;;;;; +12391;CUNEIFORM SIGN NINDA2 TIMES BAL;Lo;0;L;;;;;N;;;;; +12392;CUNEIFORM SIGN NINDA2 TIMES GI;Lo;0;L;;;;;N;;;;; +12393;CUNEIFORM SIGN NU11 ROTATED NINETY DEGREES;Lo;0;L;;;;;N;;;;; +12394;CUNEIFORM SIGN PESH2 ASTERISK;Lo;0;L;;;;;N;;;;; +12395;CUNEIFORM SIGN PIR2;Lo;0;L;;;;;N;;;;; +12396;CUNEIFORM SIGN SAG TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +12397;CUNEIFORM SIGN TI2;Lo;0;L;;;;;N;;;;; +12398;CUNEIFORM SIGN UM TIMES ME;Lo;0;L;;;;;N;;;;; +12399;CUNEIFORM SIGN U U;Lo;0;L;;;;;N;;;;; +12400;CUNEIFORM NUMERIC SIGN TWO ASH;Nl;0;L;;;;2;N;;;;; +12401;CUNEIFORM NUMERIC SIGN THREE ASH;Nl;0;L;;;;3;N;;;;; +12402;CUNEIFORM NUMERIC SIGN FOUR ASH;Nl;0;L;;;;4;N;;;;; +12403;CUNEIFORM NUMERIC SIGN FIVE ASH;Nl;0;L;;;;5;N;;;;; +12404;CUNEIFORM NUMERIC SIGN SIX ASH;Nl;0;L;;;;6;N;;;;; +12405;CUNEIFORM NUMERIC SIGN SEVEN ASH;Nl;0;L;;;;7;N;;;;; +12406;CUNEIFORM NUMERIC SIGN EIGHT ASH;Nl;0;L;;;;8;N;;;;; +12407;CUNEIFORM NUMERIC SIGN NINE ASH;Nl;0;L;;;;9;N;;;;; +12408;CUNEIFORM NUMERIC SIGN THREE DISH;Nl;0;L;;;;3;N;;;;; +12409;CUNEIFORM NUMERIC SIGN FOUR DISH;Nl;0;L;;;;4;N;;;;; +1240A;CUNEIFORM NUMERIC SIGN FIVE DISH;Nl;0;L;;;;5;N;;;;; +1240B;CUNEIFORM NUMERIC SIGN SIX DISH;Nl;0;L;;;;6;N;;;;; +1240C;CUNEIFORM NUMERIC SIGN SEVEN DISH;Nl;0;L;;;;7;N;;;;; +1240D;CUNEIFORM NUMERIC SIGN EIGHT DISH;Nl;0;L;;;;8;N;;;;; +1240E;CUNEIFORM NUMERIC SIGN NINE DISH;Nl;0;L;;;;9;N;;;;; +1240F;CUNEIFORM NUMERIC SIGN FOUR U;Nl;0;L;;;;4;N;;;;; +12410;CUNEIFORM NUMERIC SIGN FIVE U;Nl;0;L;;;;5;N;;;;; +12411;CUNEIFORM NUMERIC SIGN SIX U;Nl;0;L;;;;6;N;;;;; +12412;CUNEIFORM NUMERIC SIGN SEVEN U;Nl;0;L;;;;7;N;;;;; +12413;CUNEIFORM NUMERIC SIGN EIGHT U;Nl;0;L;;;;8;N;;;;; +12414;CUNEIFORM NUMERIC SIGN NINE U;Nl;0;L;;;;9;N;;;;; +12415;CUNEIFORM NUMERIC SIGN ONE GESH2;Nl;0;L;;;;1;N;;;;; +12416;CUNEIFORM NUMERIC SIGN TWO GESH2;Nl;0;L;;;;2;N;;;;; +12417;CUNEIFORM NUMERIC SIGN THREE GESH2;Nl;0;L;;;;3;N;;;;; +12418;CUNEIFORM NUMERIC SIGN FOUR GESH2;Nl;0;L;;;;4;N;;;;; +12419;CUNEIFORM NUMERIC SIGN FIVE GESH2;Nl;0;L;;;;5;N;;;;; +1241A;CUNEIFORM NUMERIC SIGN SIX GESH2;Nl;0;L;;;;6;N;;;;; +1241B;CUNEIFORM NUMERIC SIGN SEVEN GESH2;Nl;0;L;;;;7;N;;;;; +1241C;CUNEIFORM NUMERIC SIGN EIGHT GESH2;Nl;0;L;;;;8;N;;;;; +1241D;CUNEIFORM NUMERIC SIGN NINE GESH2;Nl;0;L;;;;9;N;;;;; +1241E;CUNEIFORM NUMERIC SIGN ONE GESHU;Nl;0;L;;;;1;N;;;;; +1241F;CUNEIFORM NUMERIC SIGN TWO GESHU;Nl;0;L;;;;2;N;;;;; +12420;CUNEIFORM NUMERIC SIGN THREE GESHU;Nl;0;L;;;;3;N;;;;; +12421;CUNEIFORM NUMERIC SIGN FOUR GESHU;Nl;0;L;;;;4;N;;;;; +12422;CUNEIFORM NUMERIC SIGN FIVE GESHU;Nl;0;L;;;;5;N;;;;; +12423;CUNEIFORM NUMERIC SIGN TWO SHAR2;Nl;0;L;;;;2;N;;;;; +12424;CUNEIFORM NUMERIC SIGN THREE SHAR2;Nl;0;L;;;;3;N;;;;; +12425;CUNEIFORM NUMERIC SIGN THREE SHAR2 VARIANT FORM;Nl;0;L;;;;3;N;;;;; +12426;CUNEIFORM NUMERIC SIGN FOUR SHAR2;Nl;0;L;;;;4;N;;;;; +12427;CUNEIFORM NUMERIC SIGN FIVE SHAR2;Nl;0;L;;;;5;N;;;;; +12428;CUNEIFORM NUMERIC SIGN SIX SHAR2;Nl;0;L;;;;6;N;;;;; +12429;CUNEIFORM NUMERIC SIGN SEVEN SHAR2;Nl;0;L;;;;7;N;;;;; +1242A;CUNEIFORM NUMERIC SIGN EIGHT SHAR2;Nl;0;L;;;;8;N;;;;; +1242B;CUNEIFORM NUMERIC SIGN NINE SHAR2;Nl;0;L;;;;9;N;;;;; +1242C;CUNEIFORM NUMERIC SIGN ONE SHARU;Nl;0;L;;;;1;N;;;;; +1242D;CUNEIFORM NUMERIC SIGN TWO SHARU;Nl;0;L;;;;2;N;;;;; +1242E;CUNEIFORM NUMERIC SIGN THREE SHARU;Nl;0;L;;;;3;N;;;;; +1242F;CUNEIFORM NUMERIC SIGN THREE SHARU VARIANT FORM;Nl;0;L;;;;3;N;;;;; +12430;CUNEIFORM NUMERIC SIGN FOUR SHARU;Nl;0;L;;;;4;N;;;;; +12431;CUNEIFORM NUMERIC SIGN FIVE SHARU;Nl;0;L;;;;5;N;;;;; +12432;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS DISH;Nl;0;L;;;;216000;N;;;;; +12433;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS MIN;Nl;0;L;;;;432000;N;;;;; +12434;CUNEIFORM NUMERIC SIGN ONE BURU;Nl;0;L;;;;1;N;;;;; +12435;CUNEIFORM NUMERIC SIGN TWO BURU;Nl;0;L;;;;2;N;;;;; +12436;CUNEIFORM NUMERIC SIGN THREE BURU;Nl;0;L;;;;3;N;;;;; +12437;CUNEIFORM NUMERIC SIGN THREE BURU VARIANT FORM;Nl;0;L;;;;3;N;;;;; +12438;CUNEIFORM NUMERIC SIGN FOUR BURU;Nl;0;L;;;;4;N;;;;; +12439;CUNEIFORM NUMERIC SIGN FIVE BURU;Nl;0;L;;;;5;N;;;;; +1243A;CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH16;Nl;0;L;;;;3;N;;;;; +1243B;CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH21;Nl;0;L;;;;3;N;;;;; +1243C;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU;Nl;0;L;;;;4;N;;;;; +1243D;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU4;Nl;0;L;;;;4;N;;;;; +1243E;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU A;Nl;0;L;;;;4;N;;;;; +1243F;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU B;Nl;0;L;;;;4;N;;;;; +12440;CUNEIFORM NUMERIC SIGN SIX VARIANT FORM ASH9;Nl;0;L;;;;6;N;;;;; +12441;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN3;Nl;0;L;;;;7;N;;;;; +12442;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN A;Nl;0;L;;;;7;N;;;;; +12443;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN B;Nl;0;L;;;;7;N;;;;; +12444;CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU;Nl;0;L;;;;8;N;;;;; +12445;CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU3;Nl;0;L;;;;8;N;;;;; +12446;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU;Nl;0;L;;;;9;N;;;;; +12447;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU3;Nl;0;L;;;;9;N;;;;; +12448;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU4;Nl;0;L;;;;9;N;;;;; +12449;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU A;Nl;0;L;;;;9;N;;;;; +1244A;CUNEIFORM NUMERIC SIGN TWO ASH TENU;Nl;0;L;;;;2;N;;;;; +1244B;CUNEIFORM NUMERIC SIGN THREE ASH TENU;Nl;0;L;;;;3;N;;;;; +1244C;CUNEIFORM NUMERIC SIGN FOUR ASH TENU;Nl;0;L;;;;4;N;;;;; +1244D;CUNEIFORM NUMERIC SIGN FIVE ASH TENU;Nl;0;L;;;;5;N;;;;; +1244E;CUNEIFORM NUMERIC SIGN SIX ASH TENU;Nl;0;L;;;;6;N;;;;; +1244F;CUNEIFORM NUMERIC SIGN ONE BAN2;Nl;0;L;;;;1;N;;;;; +12450;CUNEIFORM NUMERIC SIGN TWO BAN2;Nl;0;L;;;;2;N;;;;; +12451;CUNEIFORM NUMERIC SIGN THREE BAN2;Nl;0;L;;;;3;N;;;;; +12452;CUNEIFORM NUMERIC SIGN FOUR BAN2;Nl;0;L;;;;4;N;;;;; +12453;CUNEIFORM NUMERIC SIGN FOUR BAN2 VARIANT FORM;Nl;0;L;;;;4;N;;;;; +12454;CUNEIFORM NUMERIC SIGN FIVE BAN2;Nl;0;L;;;;5;N;;;;; +12455;CUNEIFORM NUMERIC SIGN FIVE BAN2 VARIANT FORM;Nl;0;L;;;;5;N;;;;; +12456;CUNEIFORM NUMERIC SIGN NIGIDAMIN;Nl;0;L;;;;2;N;;;;; +12457;CUNEIFORM NUMERIC SIGN NIGIDAESH;Nl;0;L;;;;3;N;;;;; +12458;CUNEIFORM NUMERIC SIGN ONE ESHE3;Nl;0;L;;;;1;N;;;;; +12459;CUNEIFORM NUMERIC SIGN TWO ESHE3;Nl;0;L;;;;2;N;;;;; +1245A;CUNEIFORM NUMERIC SIGN ONE THIRD DISH;Nl;0;L;;;;1/3;N;;;;; +1245B;CUNEIFORM NUMERIC SIGN TWO THIRDS DISH;Nl;0;L;;;;2/3;N;;;;; +1245C;CUNEIFORM NUMERIC SIGN FIVE SIXTHS DISH;Nl;0;L;;;;5/6;N;;;;; +1245D;CUNEIFORM NUMERIC SIGN ONE THIRD VARIANT FORM A;Nl;0;L;;;;1/3;N;;;;; +1245E;CUNEIFORM NUMERIC SIGN TWO THIRDS VARIANT FORM A;Nl;0;L;;;;2/3;N;;;;; +1245F;CUNEIFORM NUMERIC SIGN ONE EIGHTH ASH;Nl;0;L;;;;1/8;N;;;;; +12460;CUNEIFORM NUMERIC SIGN ONE QUARTER ASH;Nl;0;L;;;;1/4;N;;;;; +12461;CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE SIXTH;Nl;0;L;;;;1/6;N;;;;; +12462;CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE QUARTER;Nl;0;L;;;;1/4;N;;;;; +12463;CUNEIFORM NUMERIC SIGN ONE QUARTER GUR;Nl;0;L;;;;1/4;N;;;;; +12464;CUNEIFORM NUMERIC SIGN ONE HALF GUR;Nl;0;L;;;;1/2;N;;;;; +12465;CUNEIFORM NUMERIC SIGN ELAMITE ONE THIRD;Nl;0;L;;;;1/3;N;;;;; +12466;CUNEIFORM NUMERIC SIGN ELAMITE TWO THIRDS;Nl;0;L;;;;2/3;N;;;;; +12467;CUNEIFORM NUMERIC SIGN ELAMITE FORTY;Nl;0;L;;;;40;N;;;;; +12468;CUNEIFORM NUMERIC SIGN ELAMITE FIFTY;Nl;0;L;;;;50;N;;;;; +12469;CUNEIFORM NUMERIC SIGN FOUR U VARIANT FORM;Nl;0;L;;;;4;N;;;;; +1246A;CUNEIFORM NUMERIC SIGN FIVE U VARIANT FORM;Nl;0;L;;;;5;N;;;;; +1246B;CUNEIFORM NUMERIC SIGN SIX U VARIANT FORM;Nl;0;L;;;;6;N;;;;; +1246C;CUNEIFORM NUMERIC SIGN SEVEN U VARIANT FORM;Nl;0;L;;;;7;N;;;;; +1246D;CUNEIFORM NUMERIC SIGN EIGHT U VARIANT FORM;Nl;0;L;;;;8;N;;;;; +1246E;CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM;Nl;0;L;;;;9;N;;;;; +12470;CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER;Po;0;L;;;;;N;;;;; +12471;CUNEIFORM PUNCTUATION SIGN VERTICAL COLON;Po;0;L;;;;;N;;;;; +12472;CUNEIFORM PUNCTUATION SIGN DIAGONAL COLON;Po;0;L;;;;;N;;;;; +12473;CUNEIFORM PUNCTUATION SIGN DIAGONAL TRICOLON;Po;0;L;;;;;N;;;;; +12474;CUNEIFORM PUNCTUATION SIGN DIAGONAL QUADCOLON;Po;0;L;;;;;N;;;;; +12480;CUNEIFORM SIGN AB TIMES NUN TENU;Lo;0;L;;;;;N;;;;; +12481;CUNEIFORM SIGN AB TIMES SHU2;Lo;0;L;;;;;N;;;;; +12482;CUNEIFORM SIGN AD TIMES ESH2;Lo;0;L;;;;;N;;;;; +12483;CUNEIFORM SIGN BAD TIMES DISH TENU;Lo;0;L;;;;;N;;;;; +12484;CUNEIFORM SIGN BAHAR2 TIMES AB2;Lo;0;L;;;;;N;;;;; +12485;CUNEIFORM SIGN BAHAR2 TIMES NI;Lo;0;L;;;;;N;;;;; +12486;CUNEIFORM SIGN BAHAR2 TIMES ZA;Lo;0;L;;;;;N;;;;; +12487;CUNEIFORM SIGN BU OVER BU TIMES NA2;Lo;0;L;;;;;N;;;;; +12488;CUNEIFORM SIGN DA TIMES TAK4;Lo;0;L;;;;;N;;;;; +12489;CUNEIFORM SIGN DAG TIMES KUR;Lo;0;L;;;;;N;;;;; +1248A;CUNEIFORM SIGN DIM TIMES IGI;Lo;0;L;;;;;N;;;;; +1248B;CUNEIFORM SIGN DIM TIMES U U U;Lo;0;L;;;;;N;;;;; +1248C;CUNEIFORM SIGN DIM2 TIMES UD;Lo;0;L;;;;;N;;;;; +1248D;CUNEIFORM SIGN DUG TIMES ANSHE;Lo;0;L;;;;;N;;;;; +1248E;CUNEIFORM SIGN DUG TIMES ASH;Lo;0;L;;;;;N;;;;; +1248F;CUNEIFORM SIGN DUG TIMES ASH AT LEFT;Lo;0;L;;;;;N;;;;; +12490;CUNEIFORM SIGN DUG TIMES DIN;Lo;0;L;;;;;N;;;;; +12491;CUNEIFORM SIGN DUG TIMES DUN;Lo;0;L;;;;;N;;;;; +12492;CUNEIFORM SIGN DUG TIMES ERIN2;Lo;0;L;;;;;N;;;;; +12493;CUNEIFORM SIGN DUG TIMES GA;Lo;0;L;;;;;N;;;;; +12494;CUNEIFORM SIGN DUG TIMES GI;Lo;0;L;;;;;N;;;;; +12495;CUNEIFORM SIGN DUG TIMES GIR2 GUNU;Lo;0;L;;;;;N;;;;; +12496;CUNEIFORM SIGN DUG TIMES GISH;Lo;0;L;;;;;N;;;;; +12497;CUNEIFORM SIGN DUG TIMES HA;Lo;0;L;;;;;N;;;;; +12498;CUNEIFORM SIGN DUG TIMES HI;Lo;0;L;;;;;N;;;;; +12499;CUNEIFORM SIGN DUG TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +1249A;CUNEIFORM SIGN DUG TIMES KASKAL;Lo;0;L;;;;;N;;;;; +1249B;CUNEIFORM SIGN DUG TIMES KUR;Lo;0;L;;;;;N;;;;; +1249C;CUNEIFORM SIGN DUG TIMES KUSHU2;Lo;0;L;;;;;N;;;;; +1249D;CUNEIFORM SIGN DUG TIMES KUSHU2 PLUS KASKAL;Lo;0;L;;;;;N;;;;; +1249E;CUNEIFORM SIGN DUG TIMES LAK-020;Lo;0;L;;;;;N;;;;; +1249F;CUNEIFORM SIGN DUG TIMES LAM;Lo;0;L;;;;;N;;;;; +124A0;CUNEIFORM SIGN DUG TIMES LAM TIMES KUR;Lo;0;L;;;;;N;;;;; +124A1;CUNEIFORM SIGN DUG TIMES LUH PLUS GISH;Lo;0;L;;;;;N;;;;; +124A2;CUNEIFORM SIGN DUG TIMES MASH;Lo;0;L;;;;;N;;;;; +124A3;CUNEIFORM SIGN DUG TIMES MES;Lo;0;L;;;;;N;;;;; +124A4;CUNEIFORM SIGN DUG TIMES MI;Lo;0;L;;;;;N;;;;; +124A5;CUNEIFORM SIGN DUG TIMES NI;Lo;0;L;;;;;N;;;;; +124A6;CUNEIFORM SIGN DUG TIMES PI;Lo;0;L;;;;;N;;;;; +124A7;CUNEIFORM SIGN DUG TIMES SHE;Lo;0;L;;;;;N;;;;; +124A8;CUNEIFORM SIGN DUG TIMES SI GUNU;Lo;0;L;;;;;N;;;;; +124A9;CUNEIFORM SIGN E2 TIMES KUR;Lo;0;L;;;;;N;;;;; +124AA;CUNEIFORM SIGN E2 TIMES PAP;Lo;0;L;;;;;N;;;;; +124AB;CUNEIFORM SIGN ERIN2 X;Lo;0;L;;;;;N;;;;; +124AC;CUNEIFORM SIGN ESH2 CROSSING ESH2;Lo;0;L;;;;;N;;;;; +124AD;CUNEIFORM SIGN EZEN SHESHIG TIMES ASH;Lo;0;L;;;;;N;;;;; +124AE;CUNEIFORM SIGN EZEN SHESHIG TIMES HI;Lo;0;L;;;;;N;;;;; +124AF;CUNEIFORM SIGN EZEN SHESHIG TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +124B0;CUNEIFORM SIGN EZEN SHESHIG TIMES LA;Lo;0;L;;;;;N;;;;; +124B1;CUNEIFORM SIGN EZEN SHESHIG TIMES LAL;Lo;0;L;;;;;N;;;;; +124B2;CUNEIFORM SIGN EZEN SHESHIG TIMES ME;Lo;0;L;;;;;N;;;;; +124B3;CUNEIFORM SIGN EZEN SHESHIG TIMES MES;Lo;0;L;;;;;N;;;;; +124B4;CUNEIFORM SIGN EZEN SHESHIG TIMES SU;Lo;0;L;;;;;N;;;;; +124B5;CUNEIFORM SIGN EZEN TIMES SU;Lo;0;L;;;;;N;;;;; +124B6;CUNEIFORM SIGN GA2 TIMES BAHAR2;Lo;0;L;;;;;N;;;;; +124B7;CUNEIFORM SIGN GA2 TIMES DIM GUNU;Lo;0;L;;;;;N;;;;; +124B8;CUNEIFORM SIGN GA2 TIMES DUG TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +124B9;CUNEIFORM SIGN GA2 TIMES DUG TIMES KASKAL;Lo;0;L;;;;;N;;;;; +124BA;CUNEIFORM SIGN GA2 TIMES EREN;Lo;0;L;;;;;N;;;;; +124BB;CUNEIFORM SIGN GA2 TIMES GA;Lo;0;L;;;;;N;;;;; +124BC;CUNEIFORM SIGN GA2 TIMES GAR PLUS DI;Lo;0;L;;;;;N;;;;; +124BD;CUNEIFORM SIGN GA2 TIMES GAR PLUS NE;Lo;0;L;;;;;N;;;;; +124BE;CUNEIFORM SIGN GA2 TIMES HA PLUS A;Lo;0;L;;;;;N;;;;; +124BF;CUNEIFORM SIGN GA2 TIMES KUSHU2 PLUS KASKAL;Lo;0;L;;;;;N;;;;; +124C0;CUNEIFORM SIGN GA2 TIMES LAM;Lo;0;L;;;;;N;;;;; +124C1;CUNEIFORM SIGN GA2 TIMES LAM TIMES KUR;Lo;0;L;;;;;N;;;;; +124C2;CUNEIFORM SIGN GA2 TIMES LUH;Lo;0;L;;;;;N;;;;; +124C3;CUNEIFORM SIGN GA2 TIMES MUSH;Lo;0;L;;;;;N;;;;; +124C4;CUNEIFORM SIGN GA2 TIMES NE;Lo;0;L;;;;;N;;;;; +124C5;CUNEIFORM SIGN GA2 TIMES NE PLUS E2;Lo;0;L;;;;;N;;;;; +124C6;CUNEIFORM SIGN GA2 TIMES NE PLUS GI;Lo;0;L;;;;;N;;;;; +124C7;CUNEIFORM SIGN GA2 TIMES SHIM;Lo;0;L;;;;;N;;;;; +124C8;CUNEIFORM SIGN GA2 TIMES ZIZ2;Lo;0;L;;;;;N;;;;; +124C9;CUNEIFORM SIGN GABA ROTATED NINETY DEGREES;Lo;0;L;;;;;N;;;;; +124CA;CUNEIFORM SIGN GESHTIN TIMES U;Lo;0;L;;;;;N;;;;; +124CB;CUNEIFORM SIGN GISH TIMES GISH CROSSING GISH;Lo;0;L;;;;;N;;;;; +124CC;CUNEIFORM SIGN GU2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +124CD;CUNEIFORM SIGN GUD PLUS GISH TIMES TAK4;Lo;0;L;;;;;N;;;;; +124CE;CUNEIFORM SIGN HA TENU GUNU;Lo;0;L;;;;;N;;;;; +124CF;CUNEIFORM SIGN HI TIMES ASH OVER HI TIMES ASH;Lo;0;L;;;;;N;;;;; +124D0;CUNEIFORM SIGN KA TIMES BU;Lo;0;L;;;;;N;;;;; +124D1;CUNEIFORM SIGN KA TIMES KA;Lo;0;L;;;;;N;;;;; +124D2;CUNEIFORM SIGN KA TIMES U U U;Lo;0;L;;;;;N;;;;; +124D3;CUNEIFORM SIGN KA TIMES UR;Lo;0;L;;;;;N;;;;; +124D4;CUNEIFORM SIGN LAGAB TIMES ZU OVER ZU;Lo;0;L;;;;;N;;;;; +124D5;CUNEIFORM SIGN LAK-003;Lo;0;L;;;;;N;;;;; +124D6;CUNEIFORM SIGN LAK-021;Lo;0;L;;;;;N;;;;; +124D7;CUNEIFORM SIGN LAK-025;Lo;0;L;;;;;N;;;;; +124D8;CUNEIFORM SIGN LAK-030;Lo;0;L;;;;;N;;;;; +124D9;CUNEIFORM SIGN LAK-050;Lo;0;L;;;;;N;;;;; +124DA;CUNEIFORM SIGN LAK-051;Lo;0;L;;;;;N;;;;; +124DB;CUNEIFORM SIGN LAK-062;Lo;0;L;;;;;N;;;;; +124DC;CUNEIFORM SIGN LAK-079 OVER LAK-079 GUNU;Lo;0;L;;;;;N;;;;; +124DD;CUNEIFORM SIGN LAK-080;Lo;0;L;;;;;N;;;;; +124DE;CUNEIFORM SIGN LAK-081 OVER LAK-081;Lo;0;L;;;;;N;;;;; +124DF;CUNEIFORM SIGN LAK-092;Lo;0;L;;;;;N;;;;; +124E0;CUNEIFORM SIGN LAK-130;Lo;0;L;;;;;N;;;;; +124E1;CUNEIFORM SIGN LAK-142;Lo;0;L;;;;;N;;;;; +124E2;CUNEIFORM SIGN LAK-210;Lo;0;L;;;;;N;;;;; +124E3;CUNEIFORM SIGN LAK-219;Lo;0;L;;;;;N;;;;; +124E4;CUNEIFORM SIGN LAK-220;Lo;0;L;;;;;N;;;;; +124E5;CUNEIFORM SIGN LAK-225;Lo;0;L;;;;;N;;;;; +124E6;CUNEIFORM SIGN LAK-228;Lo;0;L;;;;;N;;;;; +124E7;CUNEIFORM SIGN LAK-238;Lo;0;L;;;;;N;;;;; +124E8;CUNEIFORM SIGN LAK-265;Lo;0;L;;;;;N;;;;; +124E9;CUNEIFORM SIGN LAK-266;Lo;0;L;;;;;N;;;;; +124EA;CUNEIFORM SIGN LAK-343;Lo;0;L;;;;;N;;;;; +124EB;CUNEIFORM SIGN LAK-347;Lo;0;L;;;;;N;;;;; +124EC;CUNEIFORM SIGN LAK-348;Lo;0;L;;;;;N;;;;; +124ED;CUNEIFORM SIGN LAK-383;Lo;0;L;;;;;N;;;;; +124EE;CUNEIFORM SIGN LAK-384;Lo;0;L;;;;;N;;;;; +124EF;CUNEIFORM SIGN LAK-390;Lo;0;L;;;;;N;;;;; +124F0;CUNEIFORM SIGN LAK-441;Lo;0;L;;;;;N;;;;; +124F1;CUNEIFORM SIGN LAK-449;Lo;0;L;;;;;N;;;;; +124F2;CUNEIFORM SIGN LAK-449 TIMES GU;Lo;0;L;;;;;N;;;;; +124F3;CUNEIFORM SIGN LAK-449 TIMES IGI;Lo;0;L;;;;;N;;;;; +124F4;CUNEIFORM SIGN LAK-449 TIMES PAP PLUS LU3;Lo;0;L;;;;;N;;;;; +124F5;CUNEIFORM SIGN LAK-449 TIMES PAP PLUS PAP PLUS LU3;Lo;0;L;;;;;N;;;;; +124F6;CUNEIFORM SIGN LAK-449 TIMES U2 PLUS BA;Lo;0;L;;;;;N;;;;; +124F7;CUNEIFORM SIGN LAK-450;Lo;0;L;;;;;N;;;;; +124F8;CUNEIFORM SIGN LAK-457;Lo;0;L;;;;;N;;;;; +124F9;CUNEIFORM SIGN LAK-470;Lo;0;L;;;;;N;;;;; +124FA;CUNEIFORM SIGN LAK-483;Lo;0;L;;;;;N;;;;; +124FB;CUNEIFORM SIGN LAK-490;Lo;0;L;;;;;N;;;;; +124FC;CUNEIFORM SIGN LAK-492;Lo;0;L;;;;;N;;;;; +124FD;CUNEIFORM SIGN LAK-493;Lo;0;L;;;;;N;;;;; +124FE;CUNEIFORM SIGN LAK-495;Lo;0;L;;;;;N;;;;; +124FF;CUNEIFORM SIGN LAK-550;Lo;0;L;;;;;N;;;;; +12500;CUNEIFORM SIGN LAK-608;Lo;0;L;;;;;N;;;;; +12501;CUNEIFORM SIGN LAK-617;Lo;0;L;;;;;N;;;;; +12502;CUNEIFORM SIGN LAK-617 TIMES ASH;Lo;0;L;;;;;N;;;;; +12503;CUNEIFORM SIGN LAK-617 TIMES BAD;Lo;0;L;;;;;N;;;;; +12504;CUNEIFORM SIGN LAK-617 TIMES DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;; +12505;CUNEIFORM SIGN LAK-617 TIMES KU3;Lo;0;L;;;;;N;;;;; +12506;CUNEIFORM SIGN LAK-617 TIMES LA;Lo;0;L;;;;;N;;;;; +12507;CUNEIFORM SIGN LAK-617 TIMES TAR;Lo;0;L;;;;;N;;;;; +12508;CUNEIFORM SIGN LAK-617 TIMES TE;Lo;0;L;;;;;N;;;;; +12509;CUNEIFORM SIGN LAK-617 TIMES U2;Lo;0;L;;;;;N;;;;; +1250A;CUNEIFORM SIGN LAK-617 TIMES UD;Lo;0;L;;;;;N;;;;; +1250B;CUNEIFORM SIGN LAK-617 TIMES URUDA;Lo;0;L;;;;;N;;;;; +1250C;CUNEIFORM SIGN LAK-636;Lo;0;L;;;;;N;;;;; +1250D;CUNEIFORM SIGN LAK-648;Lo;0;L;;;;;N;;;;; +1250E;CUNEIFORM SIGN LAK-648 TIMES DUB;Lo;0;L;;;;;N;;;;; +1250F;CUNEIFORM SIGN LAK-648 TIMES GA;Lo;0;L;;;;;N;;;;; +12510;CUNEIFORM SIGN LAK-648 TIMES IGI;Lo;0;L;;;;;N;;;;; +12511;CUNEIFORM SIGN LAK-648 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;; +12512;CUNEIFORM SIGN LAK-648 TIMES NI;Lo;0;L;;;;;N;;;;; +12513;CUNEIFORM SIGN LAK-648 TIMES PAP PLUS PAP PLUS LU3;Lo;0;L;;;;;N;;;;; +12514;CUNEIFORM SIGN LAK-648 TIMES SHESH PLUS KI;Lo;0;L;;;;;N;;;;; +12515;CUNEIFORM SIGN LAK-648 TIMES UD;Lo;0;L;;;;;N;;;;; +12516;CUNEIFORM SIGN LAK-648 TIMES URUDA;Lo;0;L;;;;;N;;;;; +12517;CUNEIFORM SIGN LAK-724;Lo;0;L;;;;;N;;;;; +12518;CUNEIFORM SIGN LAK-749;Lo;0;L;;;;;N;;;;; +12519;CUNEIFORM SIGN LU2 GUNU TIMES ASH;Lo;0;L;;;;;N;;;;; +1251A;CUNEIFORM SIGN LU2 TIMES DISH;Lo;0;L;;;;;N;;;;; +1251B;CUNEIFORM SIGN LU2 TIMES HAL;Lo;0;L;;;;;N;;;;; +1251C;CUNEIFORM SIGN LU2 TIMES PAP;Lo;0;L;;;;;N;;;;; +1251D;CUNEIFORM SIGN LU2 TIMES PAP PLUS PAP PLUS LU3;Lo;0;L;;;;;N;;;;; +1251E;CUNEIFORM SIGN LU2 TIMES TAK4;Lo;0;L;;;;;N;;;;; +1251F;CUNEIFORM SIGN MI PLUS ZA7;Lo;0;L;;;;;N;;;;; +12520;CUNEIFORM SIGN MUSH OVER MUSH TIMES GA;Lo;0;L;;;;;N;;;;; +12521;CUNEIFORM SIGN MUSH OVER MUSH TIMES KAK;Lo;0;L;;;;;N;;;;; +12522;CUNEIFORM SIGN NINDA2 TIMES DIM GUNU;Lo;0;L;;;;;N;;;;; +12523;CUNEIFORM SIGN NINDA2 TIMES GISH;Lo;0;L;;;;;N;;;;; +12524;CUNEIFORM SIGN NINDA2 TIMES GUL;Lo;0;L;;;;;N;;;;; +12525;CUNEIFORM SIGN NINDA2 TIMES HI;Lo;0;L;;;;;N;;;;; +12526;CUNEIFORM SIGN NINDA2 TIMES KESH2;Lo;0;L;;;;;N;;;;; +12527;CUNEIFORM SIGN NINDA2 TIMES LAK-050;Lo;0;L;;;;;N;;;;; +12528;CUNEIFORM SIGN NINDA2 TIMES MASH;Lo;0;L;;;;;N;;;;; +12529;CUNEIFORM SIGN NINDA2 TIMES PAP PLUS PAP;Lo;0;L;;;;;N;;;;; +1252A;CUNEIFORM SIGN NINDA2 TIMES U;Lo;0;L;;;;;N;;;;; +1252B;CUNEIFORM SIGN NINDA2 TIMES U PLUS U;Lo;0;L;;;;;N;;;;; +1252C;CUNEIFORM SIGN NINDA2 TIMES URUDA;Lo;0;L;;;;;N;;;;; +1252D;CUNEIFORM SIGN SAG GUNU TIMES HA;Lo;0;L;;;;;N;;;;; +1252E;CUNEIFORM SIGN SAG TIMES EN;Lo;0;L;;;;;N;;;;; +1252F;CUNEIFORM SIGN SAG TIMES SHE AT LEFT;Lo;0;L;;;;;N;;;;; +12530;CUNEIFORM SIGN SAG TIMES TAK4;Lo;0;L;;;;;N;;;;; +12531;CUNEIFORM SIGN SHA6 TENU;Lo;0;L;;;;;N;;;;; +12532;CUNEIFORM SIGN SHE OVER SHE;Lo;0;L;;;;;N;;;;; +12533;CUNEIFORM SIGN SHE PLUS HUB2;Lo;0;L;;;;;N;;;;; +12534;CUNEIFORM SIGN SHE PLUS NAM2;Lo;0;L;;;;;N;;;;; +12535;CUNEIFORM SIGN SHE PLUS SAR;Lo;0;L;;;;;N;;;;; +12536;CUNEIFORM SIGN SHU2 PLUS DUG TIMES NI;Lo;0;L;;;;;N;;;;; +12537;CUNEIFORM SIGN SHU2 PLUS E2 TIMES AN;Lo;0;L;;;;;N;;;;; +12538;CUNEIFORM SIGN SI TIMES TAK4;Lo;0;L;;;;;N;;;;; +12539;CUNEIFORM SIGN TAK4 PLUS SAG;Lo;0;L;;;;;N;;;;; +1253A;CUNEIFORM SIGN TUM TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;; +1253B;CUNEIFORM SIGN TUM TIMES THREE DISH;Lo;0;L;;;;;N;;;;; +1253C;CUNEIFORM SIGN UR2 INVERTED;Lo;0;L;;;;;N;;;;; +1253D;CUNEIFORM SIGN UR2 TIMES UD;Lo;0;L;;;;;N;;;;; +1253E;CUNEIFORM SIGN URU TIMES DARA3;Lo;0;L;;;;;N;;;;; +1253F;CUNEIFORM SIGN URU TIMES LAK-668;Lo;0;L;;;;;N;;;;; +12540;CUNEIFORM SIGN URU TIMES LU3;Lo;0;L;;;;;N;;;;; +12541;CUNEIFORM SIGN ZA7;Lo;0;L;;;;;N;;;;; +12542;CUNEIFORM SIGN ZU OVER ZU PLUS SAR;Lo;0;L;;;;;N;;;;; +12543;CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU;Lo;0;L;;;;;N;;;;; +13000;EGYPTIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;; +13001;EGYPTIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;; +13002;EGYPTIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;; +13003;EGYPTIAN HIEROGLYPH A004;Lo;0;L;;;;;N;;;;; +13004;EGYPTIAN HIEROGLYPH A005;Lo;0;L;;;;;N;;;;; +13005;EGYPTIAN HIEROGLYPH A005A;Lo;0;L;;;;;N;;;;; +13006;EGYPTIAN HIEROGLYPH A006;Lo;0;L;;;;;N;;;;; +13007;EGYPTIAN HIEROGLYPH A006A;Lo;0;L;;;;;N;;;;; +13008;EGYPTIAN HIEROGLYPH A006B;Lo;0;L;;;;;N;;;;; +13009;EGYPTIAN HIEROGLYPH A007;Lo;0;L;;;;;N;;;;; +1300A;EGYPTIAN HIEROGLYPH A008;Lo;0;L;;;;;N;;;;; +1300B;EGYPTIAN HIEROGLYPH A009;Lo;0;L;;;;;N;;;;; +1300C;EGYPTIAN HIEROGLYPH A010;Lo;0;L;;;;;N;;;;; +1300D;EGYPTIAN HIEROGLYPH A011;Lo;0;L;;;;;N;;;;; +1300E;EGYPTIAN HIEROGLYPH A012;Lo;0;L;;;;;N;;;;; +1300F;EGYPTIAN HIEROGLYPH A013;Lo;0;L;;;;;N;;;;; +13010;EGYPTIAN HIEROGLYPH A014;Lo;0;L;;;;;N;;;;; +13011;EGYPTIAN HIEROGLYPH A014A;Lo;0;L;;;;;N;;;;; +13012;EGYPTIAN HIEROGLYPH A015;Lo;0;L;;;;;N;;;;; +13013;EGYPTIAN HIEROGLYPH A016;Lo;0;L;;;;;N;;;;; +13014;EGYPTIAN HIEROGLYPH A017;Lo;0;L;;;;;N;;;;; +13015;EGYPTIAN HIEROGLYPH A017A;Lo;0;L;;;;;N;;;;; +13016;EGYPTIAN HIEROGLYPH A018;Lo;0;L;;;;;N;;;;; +13017;EGYPTIAN HIEROGLYPH A019;Lo;0;L;;;;;N;;;;; +13018;EGYPTIAN HIEROGLYPH A020;Lo;0;L;;;;;N;;;;; +13019;EGYPTIAN HIEROGLYPH A021;Lo;0;L;;;;;N;;;;; +1301A;EGYPTIAN HIEROGLYPH A022;Lo;0;L;;;;;N;;;;; +1301B;EGYPTIAN HIEROGLYPH A023;Lo;0;L;;;;;N;;;;; +1301C;EGYPTIAN HIEROGLYPH A024;Lo;0;L;;;;;N;;;;; +1301D;EGYPTIAN HIEROGLYPH A025;Lo;0;L;;;;;N;;;;; +1301E;EGYPTIAN HIEROGLYPH A026;Lo;0;L;;;;;N;;;;; +1301F;EGYPTIAN HIEROGLYPH A027;Lo;0;L;;;;;N;;;;; +13020;EGYPTIAN HIEROGLYPH A028;Lo;0;L;;;;;N;;;;; +13021;EGYPTIAN HIEROGLYPH A029;Lo;0;L;;;;;N;;;;; +13022;EGYPTIAN HIEROGLYPH A030;Lo;0;L;;;;;N;;;;; +13023;EGYPTIAN HIEROGLYPH A031;Lo;0;L;;;;;N;;;;; +13024;EGYPTIAN HIEROGLYPH A032;Lo;0;L;;;;;N;;;;; +13025;EGYPTIAN HIEROGLYPH A032A;Lo;0;L;;;;;N;;;;; +13026;EGYPTIAN HIEROGLYPH A033;Lo;0;L;;;;;N;;;;; +13027;EGYPTIAN HIEROGLYPH A034;Lo;0;L;;;;;N;;;;; +13028;EGYPTIAN HIEROGLYPH A035;Lo;0;L;;;;;N;;;;; +13029;EGYPTIAN HIEROGLYPH A036;Lo;0;L;;;;;N;;;;; +1302A;EGYPTIAN HIEROGLYPH A037;Lo;0;L;;;;;N;;;;; +1302B;EGYPTIAN HIEROGLYPH A038;Lo;0;L;;;;;N;;;;; +1302C;EGYPTIAN HIEROGLYPH A039;Lo;0;L;;;;;N;;;;; +1302D;EGYPTIAN HIEROGLYPH A040;Lo;0;L;;;;;N;;;;; +1302E;EGYPTIAN HIEROGLYPH A040A;Lo;0;L;;;;;N;;;;; +1302F;EGYPTIAN HIEROGLYPH A041;Lo;0;L;;;;;N;;;;; +13030;EGYPTIAN HIEROGLYPH A042;Lo;0;L;;;;;N;;;;; +13031;EGYPTIAN HIEROGLYPH A042A;Lo;0;L;;;;;N;;;;; +13032;EGYPTIAN HIEROGLYPH A043;Lo;0;L;;;;;N;;;;; +13033;EGYPTIAN HIEROGLYPH A043A;Lo;0;L;;;;;N;;;;; +13034;EGYPTIAN HIEROGLYPH A044;Lo;0;L;;;;;N;;;;; +13035;EGYPTIAN HIEROGLYPH A045;Lo;0;L;;;;;N;;;;; +13036;EGYPTIAN HIEROGLYPH A045A;Lo;0;L;;;;;N;;;;; +13037;EGYPTIAN HIEROGLYPH A046;Lo;0;L;;;;;N;;;;; +13038;EGYPTIAN HIEROGLYPH A047;Lo;0;L;;;;;N;;;;; +13039;EGYPTIAN HIEROGLYPH A048;Lo;0;L;;;;;N;;;;; +1303A;EGYPTIAN HIEROGLYPH A049;Lo;0;L;;;;;N;;;;; +1303B;EGYPTIAN HIEROGLYPH A050;Lo;0;L;;;;;N;;;;; +1303C;EGYPTIAN HIEROGLYPH A051;Lo;0;L;;;;;N;;;;; +1303D;EGYPTIAN HIEROGLYPH A052;Lo;0;L;;;;;N;;;;; +1303E;EGYPTIAN HIEROGLYPH A053;Lo;0;L;;;;;N;;;;; +1303F;EGYPTIAN HIEROGLYPH A054;Lo;0;L;;;;;N;;;;; +13040;EGYPTIAN HIEROGLYPH A055;Lo;0;L;;;;;N;;;;; +13041;EGYPTIAN HIEROGLYPH A056;Lo;0;L;;;;;N;;;;; +13042;EGYPTIAN HIEROGLYPH A057;Lo;0;L;;;;;N;;;;; +13043;EGYPTIAN HIEROGLYPH A058;Lo;0;L;;;;;N;;;;; +13044;EGYPTIAN HIEROGLYPH A059;Lo;0;L;;;;;N;;;;; +13045;EGYPTIAN HIEROGLYPH A060;Lo;0;L;;;;;N;;;;; +13046;EGYPTIAN HIEROGLYPH A061;Lo;0;L;;;;;N;;;;; +13047;EGYPTIAN HIEROGLYPH A062;Lo;0;L;;;;;N;;;;; +13048;EGYPTIAN HIEROGLYPH A063;Lo;0;L;;;;;N;;;;; +13049;EGYPTIAN HIEROGLYPH A064;Lo;0;L;;;;;N;;;;; +1304A;EGYPTIAN HIEROGLYPH A065;Lo;0;L;;;;;N;;;;; +1304B;EGYPTIAN HIEROGLYPH A066;Lo;0;L;;;;;N;;;;; +1304C;EGYPTIAN HIEROGLYPH A067;Lo;0;L;;;;;N;;;;; +1304D;EGYPTIAN HIEROGLYPH A068;Lo;0;L;;;;;N;;;;; +1304E;EGYPTIAN HIEROGLYPH A069;Lo;0;L;;;;;N;;;;; +1304F;EGYPTIAN HIEROGLYPH A070;Lo;0;L;;;;;N;;;;; +13050;EGYPTIAN HIEROGLYPH B001;Lo;0;L;;;;;N;;;;; +13051;EGYPTIAN HIEROGLYPH B002;Lo;0;L;;;;;N;;;;; +13052;EGYPTIAN HIEROGLYPH B003;Lo;0;L;;;;;N;;;;; +13053;EGYPTIAN HIEROGLYPH B004;Lo;0;L;;;;;N;;;;; +13054;EGYPTIAN HIEROGLYPH B005;Lo;0;L;;;;;N;;;;; +13055;EGYPTIAN HIEROGLYPH B005A;Lo;0;L;;;;;N;;;;; +13056;EGYPTIAN HIEROGLYPH B006;Lo;0;L;;;;;N;;;;; +13057;EGYPTIAN HIEROGLYPH B007;Lo;0;L;;;;;N;;;;; +13058;EGYPTIAN HIEROGLYPH B008;Lo;0;L;;;;;N;;;;; +13059;EGYPTIAN HIEROGLYPH B009;Lo;0;L;;;;;N;;;;; +1305A;EGYPTIAN HIEROGLYPH C001;Lo;0;L;;;;;N;;;;; +1305B;EGYPTIAN HIEROGLYPH C002;Lo;0;L;;;;;N;;;;; +1305C;EGYPTIAN HIEROGLYPH C002A;Lo;0;L;;;;;N;;;;; +1305D;EGYPTIAN HIEROGLYPH C002B;Lo;0;L;;;;;N;;;;; +1305E;EGYPTIAN HIEROGLYPH C002C;Lo;0;L;;;;;N;;;;; +1305F;EGYPTIAN HIEROGLYPH C003;Lo;0;L;;;;;N;;;;; +13060;EGYPTIAN HIEROGLYPH C004;Lo;0;L;;;;;N;;;;; +13061;EGYPTIAN HIEROGLYPH C005;Lo;0;L;;;;;N;;;;; +13062;EGYPTIAN HIEROGLYPH C006;Lo;0;L;;;;;N;;;;; +13063;EGYPTIAN HIEROGLYPH C007;Lo;0;L;;;;;N;;;;; +13064;EGYPTIAN HIEROGLYPH C008;Lo;0;L;;;;;N;;;;; +13065;EGYPTIAN HIEROGLYPH C009;Lo;0;L;;;;;N;;;;; +13066;EGYPTIAN HIEROGLYPH C010;Lo;0;L;;;;;N;;;;; +13067;EGYPTIAN HIEROGLYPH C010A;Lo;0;L;;;;;N;;;;; +13068;EGYPTIAN HIEROGLYPH C011;Lo;0;L;;;;;N;;;;; +13069;EGYPTIAN HIEROGLYPH C012;Lo;0;L;;;;;N;;;;; +1306A;EGYPTIAN HIEROGLYPH C013;Lo;0;L;;;;;N;;;;; +1306B;EGYPTIAN HIEROGLYPH C014;Lo;0;L;;;;;N;;;;; +1306C;EGYPTIAN HIEROGLYPH C015;Lo;0;L;;;;;N;;;;; +1306D;EGYPTIAN HIEROGLYPH C016;Lo;0;L;;;;;N;;;;; +1306E;EGYPTIAN HIEROGLYPH C017;Lo;0;L;;;;;N;;;;; +1306F;EGYPTIAN HIEROGLYPH C018;Lo;0;L;;;;;N;;;;; +13070;EGYPTIAN HIEROGLYPH C019;Lo;0;L;;;;;N;;;;; +13071;EGYPTIAN HIEROGLYPH C020;Lo;0;L;;;;;N;;;;; +13072;EGYPTIAN HIEROGLYPH C021;Lo;0;L;;;;;N;;;;; +13073;EGYPTIAN HIEROGLYPH C022;Lo;0;L;;;;;N;;;;; +13074;EGYPTIAN HIEROGLYPH C023;Lo;0;L;;;;;N;;;;; +13075;EGYPTIAN HIEROGLYPH C024;Lo;0;L;;;;;N;;;;; +13076;EGYPTIAN HIEROGLYPH D001;Lo;0;L;;;;;N;;;;; +13077;EGYPTIAN HIEROGLYPH D002;Lo;0;L;;;;;N;;;;; +13078;EGYPTIAN HIEROGLYPH D003;Lo;0;L;;;;;N;;;;; +13079;EGYPTIAN HIEROGLYPH D004;Lo;0;L;;;;;N;;;;; +1307A;EGYPTIAN HIEROGLYPH D005;Lo;0;L;;;;;N;;;;; +1307B;EGYPTIAN HIEROGLYPH D006;Lo;0;L;;;;;N;;;;; +1307C;EGYPTIAN HIEROGLYPH D007;Lo;0;L;;;;;N;;;;; +1307D;EGYPTIAN HIEROGLYPH D008;Lo;0;L;;;;;N;;;;; +1307E;EGYPTIAN HIEROGLYPH D008A;Lo;0;L;;;;;N;;;;; +1307F;EGYPTIAN HIEROGLYPH D009;Lo;0;L;;;;;N;;;;; +13080;EGYPTIAN HIEROGLYPH D010;Lo;0;L;;;;;N;;;;; +13081;EGYPTIAN HIEROGLYPH D011;Lo;0;L;;;;;N;;;;; +13082;EGYPTIAN HIEROGLYPH D012;Lo;0;L;;;;;N;;;;; +13083;EGYPTIAN HIEROGLYPH D013;Lo;0;L;;;;;N;;;;; +13084;EGYPTIAN HIEROGLYPH D014;Lo;0;L;;;;;N;;;;; +13085;EGYPTIAN HIEROGLYPH D015;Lo;0;L;;;;;N;;;;; +13086;EGYPTIAN HIEROGLYPH D016;Lo;0;L;;;;;N;;;;; +13087;EGYPTIAN HIEROGLYPH D017;Lo;0;L;;;;;N;;;;; +13088;EGYPTIAN HIEROGLYPH D018;Lo;0;L;;;;;N;;;;; +13089;EGYPTIAN HIEROGLYPH D019;Lo;0;L;;;;;N;;;;; +1308A;EGYPTIAN HIEROGLYPH D020;Lo;0;L;;;;;N;;;;; +1308B;EGYPTIAN HIEROGLYPH D021;Lo;0;L;;;;;N;;;;; +1308C;EGYPTIAN HIEROGLYPH D022;Lo;0;L;;;;;N;;;;; +1308D;EGYPTIAN HIEROGLYPH D023;Lo;0;L;;;;;N;;;;; +1308E;EGYPTIAN HIEROGLYPH D024;Lo;0;L;;;;;N;;;;; +1308F;EGYPTIAN HIEROGLYPH D025;Lo;0;L;;;;;N;;;;; +13090;EGYPTIAN HIEROGLYPH D026;Lo;0;L;;;;;N;;;;; +13091;EGYPTIAN HIEROGLYPH D027;Lo;0;L;;;;;N;;;;; +13092;EGYPTIAN HIEROGLYPH D027A;Lo;0;L;;;;;N;;;;; +13093;EGYPTIAN HIEROGLYPH D028;Lo;0;L;;;;;N;;;;; +13094;EGYPTIAN HIEROGLYPH D029;Lo;0;L;;;;;N;;;;; +13095;EGYPTIAN HIEROGLYPH D030;Lo;0;L;;;;;N;;;;; +13096;EGYPTIAN HIEROGLYPH D031;Lo;0;L;;;;;N;;;;; +13097;EGYPTIAN HIEROGLYPH D031A;Lo;0;L;;;;;N;;;;; +13098;EGYPTIAN HIEROGLYPH D032;Lo;0;L;;;;;N;;;;; +13099;EGYPTIAN HIEROGLYPH D033;Lo;0;L;;;;;N;;;;; +1309A;EGYPTIAN HIEROGLYPH D034;Lo;0;L;;;;;N;;;;; +1309B;EGYPTIAN HIEROGLYPH D034A;Lo;0;L;;;;;N;;;;; +1309C;EGYPTIAN HIEROGLYPH D035;Lo;0;L;;;;;N;;;;; +1309D;EGYPTIAN HIEROGLYPH D036;Lo;0;L;;;;;N;;;;; +1309E;EGYPTIAN HIEROGLYPH D037;Lo;0;L;;;;;N;;;;; +1309F;EGYPTIAN HIEROGLYPH D038;Lo;0;L;;;;;N;;;;; +130A0;EGYPTIAN HIEROGLYPH D039;Lo;0;L;;;;;N;;;;; +130A1;EGYPTIAN HIEROGLYPH D040;Lo;0;L;;;;;N;;;;; +130A2;EGYPTIAN HIEROGLYPH D041;Lo;0;L;;;;;N;;;;; +130A3;EGYPTIAN HIEROGLYPH D042;Lo;0;L;;;;;N;;;;; +130A4;EGYPTIAN HIEROGLYPH D043;Lo;0;L;;;;;N;;;;; +130A5;EGYPTIAN HIEROGLYPH D044;Lo;0;L;;;;;N;;;;; +130A6;EGYPTIAN HIEROGLYPH D045;Lo;0;L;;;;;N;;;;; +130A7;EGYPTIAN HIEROGLYPH D046;Lo;0;L;;;;;N;;;;; +130A8;EGYPTIAN HIEROGLYPH D046A;Lo;0;L;;;;;N;;;;; +130A9;EGYPTIAN HIEROGLYPH D047;Lo;0;L;;;;;N;;;;; +130AA;EGYPTIAN HIEROGLYPH D048;Lo;0;L;;;;;N;;;;; +130AB;EGYPTIAN HIEROGLYPH D048A;Lo;0;L;;;;;N;;;;; +130AC;EGYPTIAN HIEROGLYPH D049;Lo;0;L;;;;;N;;;;; +130AD;EGYPTIAN HIEROGLYPH D050;Lo;0;L;;;;;N;;;;; +130AE;EGYPTIAN HIEROGLYPH D050A;Lo;0;L;;;;;N;;;;; +130AF;EGYPTIAN HIEROGLYPH D050B;Lo;0;L;;;;;N;;;;; +130B0;EGYPTIAN HIEROGLYPH D050C;Lo;0;L;;;;;N;;;;; +130B1;EGYPTIAN HIEROGLYPH D050D;Lo;0;L;;;;;N;;;;; +130B2;EGYPTIAN HIEROGLYPH D050E;Lo;0;L;;;;;N;;;;; +130B3;EGYPTIAN HIEROGLYPH D050F;Lo;0;L;;;;;N;;;;; +130B4;EGYPTIAN HIEROGLYPH D050G;Lo;0;L;;;;;N;;;;; +130B5;EGYPTIAN HIEROGLYPH D050H;Lo;0;L;;;;;N;;;;; +130B6;EGYPTIAN HIEROGLYPH D050I;Lo;0;L;;;;;N;;;;; +130B7;EGYPTIAN HIEROGLYPH D051;Lo;0;L;;;;;N;;;;; +130B8;EGYPTIAN HIEROGLYPH D052;Lo;0;L;;;;;N;;;;; +130B9;EGYPTIAN HIEROGLYPH D052A;Lo;0;L;;;;;N;;;;; +130BA;EGYPTIAN HIEROGLYPH D053;Lo;0;L;;;;;N;;;;; +130BB;EGYPTIAN HIEROGLYPH D054;Lo;0;L;;;;;N;;;;; +130BC;EGYPTIAN HIEROGLYPH D054A;Lo;0;L;;;;;N;;;;; +130BD;EGYPTIAN HIEROGLYPH D055;Lo;0;L;;;;;N;;;;; +130BE;EGYPTIAN HIEROGLYPH D056;Lo;0;L;;;;;N;;;;; +130BF;EGYPTIAN HIEROGLYPH D057;Lo;0;L;;;;;N;;;;; +130C0;EGYPTIAN HIEROGLYPH D058;Lo;0;L;;;;;N;;;;; +130C1;EGYPTIAN HIEROGLYPH D059;Lo;0;L;;;;;N;;;;; +130C2;EGYPTIAN HIEROGLYPH D060;Lo;0;L;;;;;N;;;;; +130C3;EGYPTIAN HIEROGLYPH D061;Lo;0;L;;;;;N;;;;; +130C4;EGYPTIAN HIEROGLYPH D062;Lo;0;L;;;;;N;;;;; +130C5;EGYPTIAN HIEROGLYPH D063;Lo;0;L;;;;;N;;;;; +130C6;EGYPTIAN HIEROGLYPH D064;Lo;0;L;;;;;N;;;;; +130C7;EGYPTIAN HIEROGLYPH D065;Lo;0;L;;;;;N;;;;; +130C8;EGYPTIAN HIEROGLYPH D066;Lo;0;L;;;;;N;;;;; +130C9;EGYPTIAN HIEROGLYPH D067;Lo;0;L;;;;;N;;;;; +130CA;EGYPTIAN HIEROGLYPH D067A;Lo;0;L;;;;;N;;;;; +130CB;EGYPTIAN HIEROGLYPH D067B;Lo;0;L;;;;;N;;;;; +130CC;EGYPTIAN HIEROGLYPH D067C;Lo;0;L;;;;;N;;;;; +130CD;EGYPTIAN HIEROGLYPH D067D;Lo;0;L;;;;;N;;;;; +130CE;EGYPTIAN HIEROGLYPH D067E;Lo;0;L;;;;;N;;;;; +130CF;EGYPTIAN HIEROGLYPH D067F;Lo;0;L;;;;;N;;;;; +130D0;EGYPTIAN HIEROGLYPH D067G;Lo;0;L;;;;;N;;;;; +130D1;EGYPTIAN HIEROGLYPH D067H;Lo;0;L;;;;;N;;;;; +130D2;EGYPTIAN HIEROGLYPH E001;Lo;0;L;;;;;N;;;;; +130D3;EGYPTIAN HIEROGLYPH E002;Lo;0;L;;;;;N;;;;; +130D4;EGYPTIAN HIEROGLYPH E003;Lo;0;L;;;;;N;;;;; +130D5;EGYPTIAN HIEROGLYPH E004;Lo;0;L;;;;;N;;;;; +130D6;EGYPTIAN HIEROGLYPH E005;Lo;0;L;;;;;N;;;;; +130D7;EGYPTIAN HIEROGLYPH E006;Lo;0;L;;;;;N;;;;; +130D8;EGYPTIAN HIEROGLYPH E007;Lo;0;L;;;;;N;;;;; +130D9;EGYPTIAN HIEROGLYPH E008;Lo;0;L;;;;;N;;;;; +130DA;EGYPTIAN HIEROGLYPH E008A;Lo;0;L;;;;;N;;;;; +130DB;EGYPTIAN HIEROGLYPH E009;Lo;0;L;;;;;N;;;;; +130DC;EGYPTIAN HIEROGLYPH E009A;Lo;0;L;;;;;N;;;;; +130DD;EGYPTIAN HIEROGLYPH E010;Lo;0;L;;;;;N;;;;; +130DE;EGYPTIAN HIEROGLYPH E011;Lo;0;L;;;;;N;;;;; +130DF;EGYPTIAN HIEROGLYPH E012;Lo;0;L;;;;;N;;;;; +130E0;EGYPTIAN HIEROGLYPH E013;Lo;0;L;;;;;N;;;;; +130E1;EGYPTIAN HIEROGLYPH E014;Lo;0;L;;;;;N;;;;; +130E2;EGYPTIAN HIEROGLYPH E015;Lo;0;L;;;;;N;;;;; +130E3;EGYPTIAN HIEROGLYPH E016;Lo;0;L;;;;;N;;;;; +130E4;EGYPTIAN HIEROGLYPH E016A;Lo;0;L;;;;;N;;;;; +130E5;EGYPTIAN HIEROGLYPH E017;Lo;0;L;;;;;N;;;;; +130E6;EGYPTIAN HIEROGLYPH E017A;Lo;0;L;;;;;N;;;;; +130E7;EGYPTIAN HIEROGLYPH E018;Lo;0;L;;;;;N;;;;; +130E8;EGYPTIAN HIEROGLYPH E019;Lo;0;L;;;;;N;;;;; +130E9;EGYPTIAN HIEROGLYPH E020;Lo;0;L;;;;;N;;;;; +130EA;EGYPTIAN HIEROGLYPH E020A;Lo;0;L;;;;;N;;;;; +130EB;EGYPTIAN HIEROGLYPH E021;Lo;0;L;;;;;N;;;;; +130EC;EGYPTIAN HIEROGLYPH E022;Lo;0;L;;;;;N;;;;; +130ED;EGYPTIAN HIEROGLYPH E023;Lo;0;L;;;;;N;;;;; +130EE;EGYPTIAN HIEROGLYPH E024;Lo;0;L;;;;;N;;;;; +130EF;EGYPTIAN HIEROGLYPH E025;Lo;0;L;;;;;N;;;;; +130F0;EGYPTIAN HIEROGLYPH E026;Lo;0;L;;;;;N;;;;; +130F1;EGYPTIAN HIEROGLYPH E027;Lo;0;L;;;;;N;;;;; +130F2;EGYPTIAN HIEROGLYPH E028;Lo;0;L;;;;;N;;;;; +130F3;EGYPTIAN HIEROGLYPH E028A;Lo;0;L;;;;;N;;;;; +130F4;EGYPTIAN HIEROGLYPH E029;Lo;0;L;;;;;N;;;;; +130F5;EGYPTIAN HIEROGLYPH E030;Lo;0;L;;;;;N;;;;; +130F6;EGYPTIAN HIEROGLYPH E031;Lo;0;L;;;;;N;;;;; +130F7;EGYPTIAN HIEROGLYPH E032;Lo;0;L;;;;;N;;;;; +130F8;EGYPTIAN HIEROGLYPH E033;Lo;0;L;;;;;N;;;;; +130F9;EGYPTIAN HIEROGLYPH E034;Lo;0;L;;;;;N;;;;; +130FA;EGYPTIAN HIEROGLYPH E034A;Lo;0;L;;;;;N;;;;; +130FB;EGYPTIAN HIEROGLYPH E036;Lo;0;L;;;;;N;;;;; +130FC;EGYPTIAN HIEROGLYPH E037;Lo;0;L;;;;;N;;;;; +130FD;EGYPTIAN HIEROGLYPH E038;Lo;0;L;;;;;N;;;;; +130FE;EGYPTIAN HIEROGLYPH F001;Lo;0;L;;;;;N;;;;; +130FF;EGYPTIAN HIEROGLYPH F001A;Lo;0;L;;;;;N;;;;; +13100;EGYPTIAN HIEROGLYPH F002;Lo;0;L;;;;;N;;;;; +13101;EGYPTIAN HIEROGLYPH F003;Lo;0;L;;;;;N;;;;; +13102;EGYPTIAN HIEROGLYPH F004;Lo;0;L;;;;;N;;;;; +13103;EGYPTIAN HIEROGLYPH F005;Lo;0;L;;;;;N;;;;; +13104;EGYPTIAN HIEROGLYPH F006;Lo;0;L;;;;;N;;;;; +13105;EGYPTIAN HIEROGLYPH F007;Lo;0;L;;;;;N;;;;; +13106;EGYPTIAN HIEROGLYPH F008;Lo;0;L;;;;;N;;;;; +13107;EGYPTIAN HIEROGLYPH F009;Lo;0;L;;;;;N;;;;; +13108;EGYPTIAN HIEROGLYPH F010;Lo;0;L;;;;;N;;;;; +13109;EGYPTIAN HIEROGLYPH F011;Lo;0;L;;;;;N;;;;; +1310A;EGYPTIAN HIEROGLYPH F012;Lo;0;L;;;;;N;;;;; +1310B;EGYPTIAN HIEROGLYPH F013;Lo;0;L;;;;;N;;;;; +1310C;EGYPTIAN HIEROGLYPH F013A;Lo;0;L;;;;;N;;;;; +1310D;EGYPTIAN HIEROGLYPH F014;Lo;0;L;;;;;N;;;;; +1310E;EGYPTIAN HIEROGLYPH F015;Lo;0;L;;;;;N;;;;; +1310F;EGYPTIAN HIEROGLYPH F016;Lo;0;L;;;;;N;;;;; +13110;EGYPTIAN HIEROGLYPH F017;Lo;0;L;;;;;N;;;;; +13111;EGYPTIAN HIEROGLYPH F018;Lo;0;L;;;;;N;;;;; +13112;EGYPTIAN HIEROGLYPH F019;Lo;0;L;;;;;N;;;;; +13113;EGYPTIAN HIEROGLYPH F020;Lo;0;L;;;;;N;;;;; +13114;EGYPTIAN HIEROGLYPH F021;Lo;0;L;;;;;N;;;;; +13115;EGYPTIAN HIEROGLYPH F021A;Lo;0;L;;;;;N;;;;; +13116;EGYPTIAN HIEROGLYPH F022;Lo;0;L;;;;;N;;;;; +13117;EGYPTIAN HIEROGLYPH F023;Lo;0;L;;;;;N;;;;; +13118;EGYPTIAN HIEROGLYPH F024;Lo;0;L;;;;;N;;;;; +13119;EGYPTIAN HIEROGLYPH F025;Lo;0;L;;;;;N;;;;; +1311A;EGYPTIAN HIEROGLYPH F026;Lo;0;L;;;;;N;;;;; +1311B;EGYPTIAN HIEROGLYPH F027;Lo;0;L;;;;;N;;;;; +1311C;EGYPTIAN HIEROGLYPH F028;Lo;0;L;;;;;N;;;;; +1311D;EGYPTIAN HIEROGLYPH F029;Lo;0;L;;;;;N;;;;; +1311E;EGYPTIAN HIEROGLYPH F030;Lo;0;L;;;;;N;;;;; +1311F;EGYPTIAN HIEROGLYPH F031;Lo;0;L;;;;;N;;;;; +13120;EGYPTIAN HIEROGLYPH F031A;Lo;0;L;;;;;N;;;;; +13121;EGYPTIAN HIEROGLYPH F032;Lo;0;L;;;;;N;;;;; +13122;EGYPTIAN HIEROGLYPH F033;Lo;0;L;;;;;N;;;;; +13123;EGYPTIAN HIEROGLYPH F034;Lo;0;L;;;;;N;;;;; +13124;EGYPTIAN HIEROGLYPH F035;Lo;0;L;;;;;N;;;;; +13125;EGYPTIAN HIEROGLYPH F036;Lo;0;L;;;;;N;;;;; +13126;EGYPTIAN HIEROGLYPH F037;Lo;0;L;;;;;N;;;;; +13127;EGYPTIAN HIEROGLYPH F037A;Lo;0;L;;;;;N;;;;; +13128;EGYPTIAN HIEROGLYPH F038;Lo;0;L;;;;;N;;;;; +13129;EGYPTIAN HIEROGLYPH F038A;Lo;0;L;;;;;N;;;;; +1312A;EGYPTIAN HIEROGLYPH F039;Lo;0;L;;;;;N;;;;; +1312B;EGYPTIAN HIEROGLYPH F040;Lo;0;L;;;;;N;;;;; +1312C;EGYPTIAN HIEROGLYPH F041;Lo;0;L;;;;;N;;;;; +1312D;EGYPTIAN HIEROGLYPH F042;Lo;0;L;;;;;N;;;;; +1312E;EGYPTIAN HIEROGLYPH F043;Lo;0;L;;;;;N;;;;; +1312F;EGYPTIAN HIEROGLYPH F044;Lo;0;L;;;;;N;;;;; +13130;EGYPTIAN HIEROGLYPH F045;Lo;0;L;;;;;N;;;;; +13131;EGYPTIAN HIEROGLYPH F045A;Lo;0;L;;;;;N;;;;; +13132;EGYPTIAN HIEROGLYPH F046;Lo;0;L;;;;;N;;;;; +13133;EGYPTIAN HIEROGLYPH F046A;Lo;0;L;;;;;N;;;;; +13134;EGYPTIAN HIEROGLYPH F047;Lo;0;L;;;;;N;;;;; +13135;EGYPTIAN HIEROGLYPH F047A;Lo;0;L;;;;;N;;;;; +13136;EGYPTIAN HIEROGLYPH F048;Lo;0;L;;;;;N;;;;; +13137;EGYPTIAN HIEROGLYPH F049;Lo;0;L;;;;;N;;;;; +13138;EGYPTIAN HIEROGLYPH F050;Lo;0;L;;;;;N;;;;; +13139;EGYPTIAN HIEROGLYPH F051;Lo;0;L;;;;;N;;;;; +1313A;EGYPTIAN HIEROGLYPH F051A;Lo;0;L;;;;;N;;;;; +1313B;EGYPTIAN HIEROGLYPH F051B;Lo;0;L;;;;;N;;;;; +1313C;EGYPTIAN HIEROGLYPH F051C;Lo;0;L;;;;;N;;;;; +1313D;EGYPTIAN HIEROGLYPH F052;Lo;0;L;;;;;N;;;;; +1313E;EGYPTIAN HIEROGLYPH F053;Lo;0;L;;;;;N;;;;; +1313F;EGYPTIAN HIEROGLYPH G001;Lo;0;L;;;;;N;;;;; +13140;EGYPTIAN HIEROGLYPH G002;Lo;0;L;;;;;N;;;;; +13141;EGYPTIAN HIEROGLYPH G003;Lo;0;L;;;;;N;;;;; +13142;EGYPTIAN HIEROGLYPH G004;Lo;0;L;;;;;N;;;;; +13143;EGYPTIAN HIEROGLYPH G005;Lo;0;L;;;;;N;;;;; +13144;EGYPTIAN HIEROGLYPH G006;Lo;0;L;;;;;N;;;;; +13145;EGYPTIAN HIEROGLYPH G006A;Lo;0;L;;;;;N;;;;; +13146;EGYPTIAN HIEROGLYPH G007;Lo;0;L;;;;;N;;;;; +13147;EGYPTIAN HIEROGLYPH G007A;Lo;0;L;;;;;N;;;;; +13148;EGYPTIAN HIEROGLYPH G007B;Lo;0;L;;;;;N;;;;; +13149;EGYPTIAN HIEROGLYPH G008;Lo;0;L;;;;;N;;;;; +1314A;EGYPTIAN HIEROGLYPH G009;Lo;0;L;;;;;N;;;;; +1314B;EGYPTIAN HIEROGLYPH G010;Lo;0;L;;;;;N;;;;; +1314C;EGYPTIAN HIEROGLYPH G011;Lo;0;L;;;;;N;;;;; +1314D;EGYPTIAN HIEROGLYPH G011A;Lo;0;L;;;;;N;;;;; +1314E;EGYPTIAN HIEROGLYPH G012;Lo;0;L;;;;;N;;;;; +1314F;EGYPTIAN HIEROGLYPH G013;Lo;0;L;;;;;N;;;;; +13150;EGYPTIAN HIEROGLYPH G014;Lo;0;L;;;;;N;;;;; +13151;EGYPTIAN HIEROGLYPH G015;Lo;0;L;;;;;N;;;;; +13152;EGYPTIAN HIEROGLYPH G016;Lo;0;L;;;;;N;;;;; +13153;EGYPTIAN HIEROGLYPH G017;Lo;0;L;;;;;N;;;;; +13154;EGYPTIAN HIEROGLYPH G018;Lo;0;L;;;;;N;;;;; +13155;EGYPTIAN HIEROGLYPH G019;Lo;0;L;;;;;N;;;;; +13156;EGYPTIAN HIEROGLYPH G020;Lo;0;L;;;;;N;;;;; +13157;EGYPTIAN HIEROGLYPH G020A;Lo;0;L;;;;;N;;;;; +13158;EGYPTIAN HIEROGLYPH G021;Lo;0;L;;;;;N;;;;; +13159;EGYPTIAN HIEROGLYPH G022;Lo;0;L;;;;;N;;;;; +1315A;EGYPTIAN HIEROGLYPH G023;Lo;0;L;;;;;N;;;;; +1315B;EGYPTIAN HIEROGLYPH G024;Lo;0;L;;;;;N;;;;; +1315C;EGYPTIAN HIEROGLYPH G025;Lo;0;L;;;;;N;;;;; +1315D;EGYPTIAN HIEROGLYPH G026;Lo;0;L;;;;;N;;;;; +1315E;EGYPTIAN HIEROGLYPH G026A;Lo;0;L;;;;;N;;;;; +1315F;EGYPTIAN HIEROGLYPH G027;Lo;0;L;;;;;N;;;;; +13160;EGYPTIAN HIEROGLYPH G028;Lo;0;L;;;;;N;;;;; +13161;EGYPTIAN HIEROGLYPH G029;Lo;0;L;;;;;N;;;;; +13162;EGYPTIAN HIEROGLYPH G030;Lo;0;L;;;;;N;;;;; +13163;EGYPTIAN HIEROGLYPH G031;Lo;0;L;;;;;N;;;;; +13164;EGYPTIAN HIEROGLYPH G032;Lo;0;L;;;;;N;;;;; +13165;EGYPTIAN HIEROGLYPH G033;Lo;0;L;;;;;N;;;;; +13166;EGYPTIAN HIEROGLYPH G034;Lo;0;L;;;;;N;;;;; +13167;EGYPTIAN HIEROGLYPH G035;Lo;0;L;;;;;N;;;;; +13168;EGYPTIAN HIEROGLYPH G036;Lo;0;L;;;;;N;;;;; +13169;EGYPTIAN HIEROGLYPH G036A;Lo;0;L;;;;;N;;;;; +1316A;EGYPTIAN HIEROGLYPH G037;Lo;0;L;;;;;N;;;;; +1316B;EGYPTIAN HIEROGLYPH G037A;Lo;0;L;;;;;N;;;;; +1316C;EGYPTIAN HIEROGLYPH G038;Lo;0;L;;;;;N;;;;; +1316D;EGYPTIAN HIEROGLYPH G039;Lo;0;L;;;;;N;;;;; +1316E;EGYPTIAN HIEROGLYPH G040;Lo;0;L;;;;;N;;;;; +1316F;EGYPTIAN HIEROGLYPH G041;Lo;0;L;;;;;N;;;;; +13170;EGYPTIAN HIEROGLYPH G042;Lo;0;L;;;;;N;;;;; +13171;EGYPTIAN HIEROGLYPH G043;Lo;0;L;;;;;N;;;;; +13172;EGYPTIAN HIEROGLYPH G043A;Lo;0;L;;;;;N;;;;; +13173;EGYPTIAN HIEROGLYPH G044;Lo;0;L;;;;;N;;;;; +13174;EGYPTIAN HIEROGLYPH G045;Lo;0;L;;;;;N;;;;; +13175;EGYPTIAN HIEROGLYPH G045A;Lo;0;L;;;;;N;;;;; +13176;EGYPTIAN HIEROGLYPH G046;Lo;0;L;;;;;N;;;;; +13177;EGYPTIAN HIEROGLYPH G047;Lo;0;L;;;;;N;;;;; +13178;EGYPTIAN HIEROGLYPH G048;Lo;0;L;;;;;N;;;;; +13179;EGYPTIAN HIEROGLYPH G049;Lo;0;L;;;;;N;;;;; +1317A;EGYPTIAN HIEROGLYPH G050;Lo;0;L;;;;;N;;;;; +1317B;EGYPTIAN HIEROGLYPH G051;Lo;0;L;;;;;N;;;;; +1317C;EGYPTIAN HIEROGLYPH G052;Lo;0;L;;;;;N;;;;; +1317D;EGYPTIAN HIEROGLYPH G053;Lo;0;L;;;;;N;;;;; +1317E;EGYPTIAN HIEROGLYPH G054;Lo;0;L;;;;;N;;;;; +1317F;EGYPTIAN HIEROGLYPH H001;Lo;0;L;;;;;N;;;;; +13180;EGYPTIAN HIEROGLYPH H002;Lo;0;L;;;;;N;;;;; +13181;EGYPTIAN HIEROGLYPH H003;Lo;0;L;;;;;N;;;;; +13182;EGYPTIAN HIEROGLYPH H004;Lo;0;L;;;;;N;;;;; +13183;EGYPTIAN HIEROGLYPH H005;Lo;0;L;;;;;N;;;;; +13184;EGYPTIAN HIEROGLYPH H006;Lo;0;L;;;;;N;;;;; +13185;EGYPTIAN HIEROGLYPH H006A;Lo;0;L;;;;;N;;;;; +13186;EGYPTIAN HIEROGLYPH H007;Lo;0;L;;;;;N;;;;; +13187;EGYPTIAN HIEROGLYPH H008;Lo;0;L;;;;;N;;;;; +13188;EGYPTIAN HIEROGLYPH I001;Lo;0;L;;;;;N;;;;; +13189;EGYPTIAN HIEROGLYPH I002;Lo;0;L;;;;;N;;;;; +1318A;EGYPTIAN HIEROGLYPH I003;Lo;0;L;;;;;N;;;;; +1318B;EGYPTIAN HIEROGLYPH I004;Lo;0;L;;;;;N;;;;; +1318C;EGYPTIAN HIEROGLYPH I005;Lo;0;L;;;;;N;;;;; +1318D;EGYPTIAN HIEROGLYPH I005A;Lo;0;L;;;;;N;;;;; +1318E;EGYPTIAN HIEROGLYPH I006;Lo;0;L;;;;;N;;;;; +1318F;EGYPTIAN HIEROGLYPH I007;Lo;0;L;;;;;N;;;;; +13190;EGYPTIAN HIEROGLYPH I008;Lo;0;L;;;;;N;;;;; +13191;EGYPTIAN HIEROGLYPH I009;Lo;0;L;;;;;N;;;;; +13192;EGYPTIAN HIEROGLYPH I009A;Lo;0;L;;;;;N;;;;; +13193;EGYPTIAN HIEROGLYPH I010;Lo;0;L;;;;;N;;;;; +13194;EGYPTIAN HIEROGLYPH I010A;Lo;0;L;;;;;N;;;;; +13195;EGYPTIAN HIEROGLYPH I011;Lo;0;L;;;;;N;;;;; +13196;EGYPTIAN HIEROGLYPH I011A;Lo;0;L;;;;;N;;;;; +13197;EGYPTIAN HIEROGLYPH I012;Lo;0;L;;;;;N;;;;; +13198;EGYPTIAN HIEROGLYPH I013;Lo;0;L;;;;;N;;;;; +13199;EGYPTIAN HIEROGLYPH I014;Lo;0;L;;;;;N;;;;; +1319A;EGYPTIAN HIEROGLYPH I015;Lo;0;L;;;;;N;;;;; +1319B;EGYPTIAN HIEROGLYPH K001;Lo;0;L;;;;;N;;;;; +1319C;EGYPTIAN HIEROGLYPH K002;Lo;0;L;;;;;N;;;;; +1319D;EGYPTIAN HIEROGLYPH K003;Lo;0;L;;;;;N;;;;; +1319E;EGYPTIAN HIEROGLYPH K004;Lo;0;L;;;;;N;;;;; +1319F;EGYPTIAN HIEROGLYPH K005;Lo;0;L;;;;;N;;;;; +131A0;EGYPTIAN HIEROGLYPH K006;Lo;0;L;;;;;N;;;;; +131A1;EGYPTIAN HIEROGLYPH K007;Lo;0;L;;;;;N;;;;; +131A2;EGYPTIAN HIEROGLYPH K008;Lo;0;L;;;;;N;;;;; +131A3;EGYPTIAN HIEROGLYPH L001;Lo;0;L;;;;;N;;;;; +131A4;EGYPTIAN HIEROGLYPH L002;Lo;0;L;;;;;N;;;;; +131A5;EGYPTIAN HIEROGLYPH L002A;Lo;0;L;;;;;N;;;;; +131A6;EGYPTIAN HIEROGLYPH L003;Lo;0;L;;;;;N;;;;; +131A7;EGYPTIAN HIEROGLYPH L004;Lo;0;L;;;;;N;;;;; +131A8;EGYPTIAN HIEROGLYPH L005;Lo;0;L;;;;;N;;;;; +131A9;EGYPTIAN HIEROGLYPH L006;Lo;0;L;;;;;N;;;;; +131AA;EGYPTIAN HIEROGLYPH L006A;Lo;0;L;;;;;N;;;;; +131AB;EGYPTIAN HIEROGLYPH L007;Lo;0;L;;;;;N;;;;; +131AC;EGYPTIAN HIEROGLYPH L008;Lo;0;L;;;;;N;;;;; +131AD;EGYPTIAN HIEROGLYPH M001;Lo;0;L;;;;;N;;;;; +131AE;EGYPTIAN HIEROGLYPH M001A;Lo;0;L;;;;;N;;;;; +131AF;EGYPTIAN HIEROGLYPH M001B;Lo;0;L;;;;;N;;;;; +131B0;EGYPTIAN HIEROGLYPH M002;Lo;0;L;;;;;N;;;;; +131B1;EGYPTIAN HIEROGLYPH M003;Lo;0;L;;;;;N;;;;; +131B2;EGYPTIAN HIEROGLYPH M003A;Lo;0;L;;;;;N;;;;; +131B3;EGYPTIAN HIEROGLYPH M004;Lo;0;L;;;;;N;;;;; +131B4;EGYPTIAN HIEROGLYPH M005;Lo;0;L;;;;;N;;;;; +131B5;EGYPTIAN HIEROGLYPH M006;Lo;0;L;;;;;N;;;;; +131B6;EGYPTIAN HIEROGLYPH M007;Lo;0;L;;;;;N;;;;; +131B7;EGYPTIAN HIEROGLYPH M008;Lo;0;L;;;;;N;;;;; +131B8;EGYPTIAN HIEROGLYPH M009;Lo;0;L;;;;;N;;;;; +131B9;EGYPTIAN HIEROGLYPH M010;Lo;0;L;;;;;N;;;;; +131BA;EGYPTIAN HIEROGLYPH M010A;Lo;0;L;;;;;N;;;;; +131BB;EGYPTIAN HIEROGLYPH M011;Lo;0;L;;;;;N;;;;; +131BC;EGYPTIAN HIEROGLYPH M012;Lo;0;L;;;;;N;;;;; +131BD;EGYPTIAN HIEROGLYPH M012A;Lo;0;L;;;;;N;;;;; +131BE;EGYPTIAN HIEROGLYPH M012B;Lo;0;L;;;;;N;;;;; +131BF;EGYPTIAN HIEROGLYPH M012C;Lo;0;L;;;;;N;;;;; +131C0;EGYPTIAN HIEROGLYPH M012D;Lo;0;L;;;;;N;;;;; +131C1;EGYPTIAN HIEROGLYPH M012E;Lo;0;L;;;;;N;;;;; +131C2;EGYPTIAN HIEROGLYPH M012F;Lo;0;L;;;;;N;;;;; +131C3;EGYPTIAN HIEROGLYPH M012G;Lo;0;L;;;;;N;;;;; +131C4;EGYPTIAN HIEROGLYPH M012H;Lo;0;L;;;;;N;;;;; +131C5;EGYPTIAN HIEROGLYPH M013;Lo;0;L;;;;;N;;;;; +131C6;EGYPTIAN HIEROGLYPH M014;Lo;0;L;;;;;N;;;;; +131C7;EGYPTIAN HIEROGLYPH M015;Lo;0;L;;;;;N;;;;; +131C8;EGYPTIAN HIEROGLYPH M015A;Lo;0;L;;;;;N;;;;; +131C9;EGYPTIAN HIEROGLYPH M016;Lo;0;L;;;;;N;;;;; +131CA;EGYPTIAN HIEROGLYPH M016A;Lo;0;L;;;;;N;;;;; +131CB;EGYPTIAN HIEROGLYPH M017;Lo;0;L;;;;;N;;;;; +131CC;EGYPTIAN HIEROGLYPH M017A;Lo;0;L;;;;;N;;;;; +131CD;EGYPTIAN HIEROGLYPH M018;Lo;0;L;;;;;N;;;;; +131CE;EGYPTIAN HIEROGLYPH M019;Lo;0;L;;;;;N;;;;; +131CF;EGYPTIAN HIEROGLYPH M020;Lo;0;L;;;;;N;;;;; +131D0;EGYPTIAN HIEROGLYPH M021;Lo;0;L;;;;;N;;;;; +131D1;EGYPTIAN HIEROGLYPH M022;Lo;0;L;;;;;N;;;;; +131D2;EGYPTIAN HIEROGLYPH M022A;Lo;0;L;;;;;N;;;;; +131D3;EGYPTIAN HIEROGLYPH M023;Lo;0;L;;;;;N;;;;; +131D4;EGYPTIAN HIEROGLYPH M024;Lo;0;L;;;;;N;;;;; +131D5;EGYPTIAN HIEROGLYPH M024A;Lo;0;L;;;;;N;;;;; +131D6;EGYPTIAN HIEROGLYPH M025;Lo;0;L;;;;;N;;;;; +131D7;EGYPTIAN HIEROGLYPH M026;Lo;0;L;;;;;N;;;;; +131D8;EGYPTIAN HIEROGLYPH M027;Lo;0;L;;;;;N;;;;; +131D9;EGYPTIAN HIEROGLYPH M028;Lo;0;L;;;;;N;;;;; +131DA;EGYPTIAN HIEROGLYPH M028A;Lo;0;L;;;;;N;;;;; +131DB;EGYPTIAN HIEROGLYPH M029;Lo;0;L;;;;;N;;;;; +131DC;EGYPTIAN HIEROGLYPH M030;Lo;0;L;;;;;N;;;;; +131DD;EGYPTIAN HIEROGLYPH M031;Lo;0;L;;;;;N;;;;; +131DE;EGYPTIAN HIEROGLYPH M031A;Lo;0;L;;;;;N;;;;; +131DF;EGYPTIAN HIEROGLYPH M032;Lo;0;L;;;;;N;;;;; +131E0;EGYPTIAN HIEROGLYPH M033;Lo;0;L;;;;;N;;;;; +131E1;EGYPTIAN HIEROGLYPH M033A;Lo;0;L;;;;;N;;;;; +131E2;EGYPTIAN HIEROGLYPH M033B;Lo;0;L;;;;;N;;;;; +131E3;EGYPTIAN HIEROGLYPH M034;Lo;0;L;;;;;N;;;;; +131E4;EGYPTIAN HIEROGLYPH M035;Lo;0;L;;;;;N;;;;; +131E5;EGYPTIAN HIEROGLYPH M036;Lo;0;L;;;;;N;;;;; +131E6;EGYPTIAN HIEROGLYPH M037;Lo;0;L;;;;;N;;;;; +131E7;EGYPTIAN HIEROGLYPH M038;Lo;0;L;;;;;N;;;;; +131E8;EGYPTIAN HIEROGLYPH M039;Lo;0;L;;;;;N;;;;; +131E9;EGYPTIAN HIEROGLYPH M040;Lo;0;L;;;;;N;;;;; +131EA;EGYPTIAN HIEROGLYPH M040A;Lo;0;L;;;;;N;;;;; +131EB;EGYPTIAN HIEROGLYPH M041;Lo;0;L;;;;;N;;;;; +131EC;EGYPTIAN HIEROGLYPH M042;Lo;0;L;;;;;N;;;;; +131ED;EGYPTIAN HIEROGLYPH M043;Lo;0;L;;;;;N;;;;; +131EE;EGYPTIAN HIEROGLYPH M044;Lo;0;L;;;;;N;;;;; +131EF;EGYPTIAN HIEROGLYPH N001;Lo;0;L;;;;;N;;;;; +131F0;EGYPTIAN HIEROGLYPH N002;Lo;0;L;;;;;N;;;;; +131F1;EGYPTIAN HIEROGLYPH N003;Lo;0;L;;;;;N;;;;; +131F2;EGYPTIAN HIEROGLYPH N004;Lo;0;L;;;;;N;;;;; +131F3;EGYPTIAN HIEROGLYPH N005;Lo;0;L;;;;;N;;;;; +131F4;EGYPTIAN HIEROGLYPH N006;Lo;0;L;;;;;N;;;;; +131F5;EGYPTIAN HIEROGLYPH N007;Lo;0;L;;;;;N;;;;; +131F6;EGYPTIAN HIEROGLYPH N008;Lo;0;L;;;;;N;;;;; +131F7;EGYPTIAN HIEROGLYPH N009;Lo;0;L;;;;;N;;;;; +131F8;EGYPTIAN HIEROGLYPH N010;Lo;0;L;;;;;N;;;;; +131F9;EGYPTIAN HIEROGLYPH N011;Lo;0;L;;;;;N;;;;; +131FA;EGYPTIAN HIEROGLYPH N012;Lo;0;L;;;;;N;;;;; +131FB;EGYPTIAN HIEROGLYPH N013;Lo;0;L;;;;;N;;;;; +131FC;EGYPTIAN HIEROGLYPH N014;Lo;0;L;;;;;N;;;;; +131FD;EGYPTIAN HIEROGLYPH N015;Lo;0;L;;;;;N;;;;; +131FE;EGYPTIAN HIEROGLYPH N016;Lo;0;L;;;;;N;;;;; +131FF;EGYPTIAN HIEROGLYPH N017;Lo;0;L;;;;;N;;;;; +13200;EGYPTIAN HIEROGLYPH N018;Lo;0;L;;;;;N;;;;; +13201;EGYPTIAN HIEROGLYPH N018A;Lo;0;L;;;;;N;;;;; +13202;EGYPTIAN HIEROGLYPH N018B;Lo;0;L;;;;;N;;;;; +13203;EGYPTIAN HIEROGLYPH N019;Lo;0;L;;;;;N;;;;; +13204;EGYPTIAN HIEROGLYPH N020;Lo;0;L;;;;;N;;;;; +13205;EGYPTIAN HIEROGLYPH N021;Lo;0;L;;;;;N;;;;; +13206;EGYPTIAN HIEROGLYPH N022;Lo;0;L;;;;;N;;;;; +13207;EGYPTIAN HIEROGLYPH N023;Lo;0;L;;;;;N;;;;; +13208;EGYPTIAN HIEROGLYPH N024;Lo;0;L;;;;;N;;;;; +13209;EGYPTIAN HIEROGLYPH N025;Lo;0;L;;;;;N;;;;; +1320A;EGYPTIAN HIEROGLYPH N025A;Lo;0;L;;;;;N;;;;; +1320B;EGYPTIAN HIEROGLYPH N026;Lo;0;L;;;;;N;;;;; +1320C;EGYPTIAN HIEROGLYPH N027;Lo;0;L;;;;;N;;;;; +1320D;EGYPTIAN HIEROGLYPH N028;Lo;0;L;;;;;N;;;;; +1320E;EGYPTIAN HIEROGLYPH N029;Lo;0;L;;;;;N;;;;; +1320F;EGYPTIAN HIEROGLYPH N030;Lo;0;L;;;;;N;;;;; +13210;EGYPTIAN HIEROGLYPH N031;Lo;0;L;;;;;N;;;;; +13211;EGYPTIAN HIEROGLYPH N032;Lo;0;L;;;;;N;;;;; +13212;EGYPTIAN HIEROGLYPH N033;Lo;0;L;;;;;N;;;;; +13213;EGYPTIAN HIEROGLYPH N033A;Lo;0;L;;;;;N;;;;; +13214;EGYPTIAN HIEROGLYPH N034;Lo;0;L;;;;;N;;;;; +13215;EGYPTIAN HIEROGLYPH N034A;Lo;0;L;;;;;N;;;;; +13216;EGYPTIAN HIEROGLYPH N035;Lo;0;L;;;;;N;;;;; +13217;EGYPTIAN HIEROGLYPH N035A;Lo;0;L;;;;;N;;;;; +13218;EGYPTIAN HIEROGLYPH N036;Lo;0;L;;;;;N;;;;; +13219;EGYPTIAN HIEROGLYPH N037;Lo;0;L;;;;;N;;;;; +1321A;EGYPTIAN HIEROGLYPH N037A;Lo;0;L;;;;;N;;;;; +1321B;EGYPTIAN HIEROGLYPH N038;Lo;0;L;;;;;N;;;;; +1321C;EGYPTIAN HIEROGLYPH N039;Lo;0;L;;;;;N;;;;; +1321D;EGYPTIAN HIEROGLYPH N040;Lo;0;L;;;;;N;;;;; +1321E;EGYPTIAN HIEROGLYPH N041;Lo;0;L;;;;;N;;;;; +1321F;EGYPTIAN HIEROGLYPH N042;Lo;0;L;;;;;N;;;;; +13220;EGYPTIAN HIEROGLYPH NL001;Lo;0;L;;;;;N;;;;; +13221;EGYPTIAN HIEROGLYPH NL002;Lo;0;L;;;;;N;;;;; +13222;EGYPTIAN HIEROGLYPH NL003;Lo;0;L;;;;;N;;;;; +13223;EGYPTIAN HIEROGLYPH NL004;Lo;0;L;;;;;N;;;;; +13224;EGYPTIAN HIEROGLYPH NL005;Lo;0;L;;;;;N;;;;; +13225;EGYPTIAN HIEROGLYPH NL005A;Lo;0;L;;;;;N;;;;; +13226;EGYPTIAN HIEROGLYPH NL006;Lo;0;L;;;;;N;;;;; +13227;EGYPTIAN HIEROGLYPH NL007;Lo;0;L;;;;;N;;;;; +13228;EGYPTIAN HIEROGLYPH NL008;Lo;0;L;;;;;N;;;;; +13229;EGYPTIAN HIEROGLYPH NL009;Lo;0;L;;;;;N;;;;; +1322A;EGYPTIAN HIEROGLYPH NL010;Lo;0;L;;;;;N;;;;; +1322B;EGYPTIAN HIEROGLYPH NL011;Lo;0;L;;;;;N;;;;; +1322C;EGYPTIAN HIEROGLYPH NL012;Lo;0;L;;;;;N;;;;; +1322D;EGYPTIAN HIEROGLYPH NL013;Lo;0;L;;;;;N;;;;; +1322E;EGYPTIAN HIEROGLYPH NL014;Lo;0;L;;;;;N;;;;; +1322F;EGYPTIAN HIEROGLYPH NL015;Lo;0;L;;;;;N;;;;; +13230;EGYPTIAN HIEROGLYPH NL016;Lo;0;L;;;;;N;;;;; +13231;EGYPTIAN HIEROGLYPH NL017;Lo;0;L;;;;;N;;;;; +13232;EGYPTIAN HIEROGLYPH NL017A;Lo;0;L;;;;;N;;;;; +13233;EGYPTIAN HIEROGLYPH NL018;Lo;0;L;;;;;N;;;;; +13234;EGYPTIAN HIEROGLYPH NL019;Lo;0;L;;;;;N;;;;; +13235;EGYPTIAN HIEROGLYPH NL020;Lo;0;L;;;;;N;;;;; +13236;EGYPTIAN HIEROGLYPH NU001;Lo;0;L;;;;;N;;;;; +13237;EGYPTIAN HIEROGLYPH NU002;Lo;0;L;;;;;N;;;;; +13238;EGYPTIAN HIEROGLYPH NU003;Lo;0;L;;;;;N;;;;; +13239;EGYPTIAN HIEROGLYPH NU004;Lo;0;L;;;;;N;;;;; +1323A;EGYPTIAN HIEROGLYPH NU005;Lo;0;L;;;;;N;;;;; +1323B;EGYPTIAN HIEROGLYPH NU006;Lo;0;L;;;;;N;;;;; +1323C;EGYPTIAN HIEROGLYPH NU007;Lo;0;L;;;;;N;;;;; +1323D;EGYPTIAN HIEROGLYPH NU008;Lo;0;L;;;;;N;;;;; +1323E;EGYPTIAN HIEROGLYPH NU009;Lo;0;L;;;;;N;;;;; +1323F;EGYPTIAN HIEROGLYPH NU010;Lo;0;L;;;;;N;;;;; +13240;EGYPTIAN HIEROGLYPH NU010A;Lo;0;L;;;;;N;;;;; +13241;EGYPTIAN HIEROGLYPH NU011;Lo;0;L;;;;;N;;;;; +13242;EGYPTIAN HIEROGLYPH NU011A;Lo;0;L;;;;;N;;;;; +13243;EGYPTIAN HIEROGLYPH NU012;Lo;0;L;;;;;N;;;;; +13244;EGYPTIAN HIEROGLYPH NU013;Lo;0;L;;;;;N;;;;; +13245;EGYPTIAN HIEROGLYPH NU014;Lo;0;L;;;;;N;;;;; +13246;EGYPTIAN HIEROGLYPH NU015;Lo;0;L;;;;;N;;;;; +13247;EGYPTIAN HIEROGLYPH NU016;Lo;0;L;;;;;N;;;;; +13248;EGYPTIAN HIEROGLYPH NU017;Lo;0;L;;;;;N;;;;; +13249;EGYPTIAN HIEROGLYPH NU018;Lo;0;L;;;;;N;;;;; +1324A;EGYPTIAN HIEROGLYPH NU018A;Lo;0;L;;;;;N;;;;; +1324B;EGYPTIAN HIEROGLYPH NU019;Lo;0;L;;;;;N;;;;; +1324C;EGYPTIAN HIEROGLYPH NU020;Lo;0;L;;;;;N;;;;; +1324D;EGYPTIAN HIEROGLYPH NU021;Lo;0;L;;;;;N;;;;; +1324E;EGYPTIAN HIEROGLYPH NU022;Lo;0;L;;;;;N;;;;; +1324F;EGYPTIAN HIEROGLYPH NU022A;Lo;0;L;;;;;N;;;;; +13250;EGYPTIAN HIEROGLYPH O001;Lo;0;L;;;;;N;;;;; +13251;EGYPTIAN HIEROGLYPH O001A;Lo;0;L;;;;;N;;;;; +13252;EGYPTIAN HIEROGLYPH O002;Lo;0;L;;;;;N;;;;; +13253;EGYPTIAN HIEROGLYPH O003;Lo;0;L;;;;;N;;;;; +13254;EGYPTIAN HIEROGLYPH O004;Lo;0;L;;;;;N;;;;; +13255;EGYPTIAN HIEROGLYPH O005;Lo;0;L;;;;;N;;;;; +13256;EGYPTIAN HIEROGLYPH O005A;Lo;0;L;;;;;N;;;;; +13257;EGYPTIAN HIEROGLYPH O006;Lo;0;L;;;;;N;;;;; +13258;EGYPTIAN HIEROGLYPH O006A;Lo;0;L;;;;;N;;;;; +13259;EGYPTIAN HIEROGLYPH O006B;Lo;0;L;;;;;N;;;;; +1325A;EGYPTIAN HIEROGLYPH O006C;Lo;0;L;;;;;N;;;;; +1325B;EGYPTIAN HIEROGLYPH O006D;Lo;0;L;;;;;N;;;;; +1325C;EGYPTIAN HIEROGLYPH O006E;Lo;0;L;;;;;N;;;;; +1325D;EGYPTIAN HIEROGLYPH O006F;Lo;0;L;;;;;N;;;;; +1325E;EGYPTIAN HIEROGLYPH O007;Lo;0;L;;;;;N;;;;; +1325F;EGYPTIAN HIEROGLYPH O008;Lo;0;L;;;;;N;;;;; +13260;EGYPTIAN HIEROGLYPH O009;Lo;0;L;;;;;N;;;;; +13261;EGYPTIAN HIEROGLYPH O010;Lo;0;L;;;;;N;;;;; +13262;EGYPTIAN HIEROGLYPH O010A;Lo;0;L;;;;;N;;;;; +13263;EGYPTIAN HIEROGLYPH O010B;Lo;0;L;;;;;N;;;;; +13264;EGYPTIAN HIEROGLYPH O010C;Lo;0;L;;;;;N;;;;; +13265;EGYPTIAN HIEROGLYPH O011;Lo;0;L;;;;;N;;;;; +13266;EGYPTIAN HIEROGLYPH O012;Lo;0;L;;;;;N;;;;; +13267;EGYPTIAN HIEROGLYPH O013;Lo;0;L;;;;;N;;;;; +13268;EGYPTIAN HIEROGLYPH O014;Lo;0;L;;;;;N;;;;; +13269;EGYPTIAN HIEROGLYPH O015;Lo;0;L;;;;;N;;;;; +1326A;EGYPTIAN HIEROGLYPH O016;Lo;0;L;;;;;N;;;;; +1326B;EGYPTIAN HIEROGLYPH O017;Lo;0;L;;;;;N;;;;; +1326C;EGYPTIAN HIEROGLYPH O018;Lo;0;L;;;;;N;;;;; +1326D;EGYPTIAN HIEROGLYPH O019;Lo;0;L;;;;;N;;;;; +1326E;EGYPTIAN HIEROGLYPH O019A;Lo;0;L;;;;;N;;;;; +1326F;EGYPTIAN HIEROGLYPH O020;Lo;0;L;;;;;N;;;;; +13270;EGYPTIAN HIEROGLYPH O020A;Lo;0;L;;;;;N;;;;; +13271;EGYPTIAN HIEROGLYPH O021;Lo;0;L;;;;;N;;;;; +13272;EGYPTIAN HIEROGLYPH O022;Lo;0;L;;;;;N;;;;; +13273;EGYPTIAN HIEROGLYPH O023;Lo;0;L;;;;;N;;;;; +13274;EGYPTIAN HIEROGLYPH O024;Lo;0;L;;;;;N;;;;; +13275;EGYPTIAN HIEROGLYPH O024A;Lo;0;L;;;;;N;;;;; +13276;EGYPTIAN HIEROGLYPH O025;Lo;0;L;;;;;N;;;;; +13277;EGYPTIAN HIEROGLYPH O025A;Lo;0;L;;;;;N;;;;; +13278;EGYPTIAN HIEROGLYPH O026;Lo;0;L;;;;;N;;;;; +13279;EGYPTIAN HIEROGLYPH O027;Lo;0;L;;;;;N;;;;; +1327A;EGYPTIAN HIEROGLYPH O028;Lo;0;L;;;;;N;;;;; +1327B;EGYPTIAN HIEROGLYPH O029;Lo;0;L;;;;;N;;;;; +1327C;EGYPTIAN HIEROGLYPH O029A;Lo;0;L;;;;;N;;;;; +1327D;EGYPTIAN HIEROGLYPH O030;Lo;0;L;;;;;N;;;;; +1327E;EGYPTIAN HIEROGLYPH O030A;Lo;0;L;;;;;N;;;;; +1327F;EGYPTIAN HIEROGLYPH O031;Lo;0;L;;;;;N;;;;; +13280;EGYPTIAN HIEROGLYPH O032;Lo;0;L;;;;;N;;;;; +13281;EGYPTIAN HIEROGLYPH O033;Lo;0;L;;;;;N;;;;; +13282;EGYPTIAN HIEROGLYPH O033A;Lo;0;L;;;;;N;;;;; +13283;EGYPTIAN HIEROGLYPH O034;Lo;0;L;;;;;N;;;;; +13284;EGYPTIAN HIEROGLYPH O035;Lo;0;L;;;;;N;;;;; +13285;EGYPTIAN HIEROGLYPH O036;Lo;0;L;;;;;N;;;;; +13286;EGYPTIAN HIEROGLYPH O036A;Lo;0;L;;;;;N;;;;; +13287;EGYPTIAN HIEROGLYPH O036B;Lo;0;L;;;;;N;;;;; +13288;EGYPTIAN HIEROGLYPH O036C;Lo;0;L;;;;;N;;;;; +13289;EGYPTIAN HIEROGLYPH O036D;Lo;0;L;;;;;N;;;;; +1328A;EGYPTIAN HIEROGLYPH O037;Lo;0;L;;;;;N;;;;; +1328B;EGYPTIAN HIEROGLYPH O038;Lo;0;L;;;;;N;;;;; +1328C;EGYPTIAN HIEROGLYPH O039;Lo;0;L;;;;;N;;;;; +1328D;EGYPTIAN HIEROGLYPH O040;Lo;0;L;;;;;N;;;;; +1328E;EGYPTIAN HIEROGLYPH O041;Lo;0;L;;;;;N;;;;; +1328F;EGYPTIAN HIEROGLYPH O042;Lo;0;L;;;;;N;;;;; +13290;EGYPTIAN HIEROGLYPH O043;Lo;0;L;;;;;N;;;;; +13291;EGYPTIAN HIEROGLYPH O044;Lo;0;L;;;;;N;;;;; +13292;EGYPTIAN HIEROGLYPH O045;Lo;0;L;;;;;N;;;;; +13293;EGYPTIAN HIEROGLYPH O046;Lo;0;L;;;;;N;;;;; +13294;EGYPTIAN HIEROGLYPH O047;Lo;0;L;;;;;N;;;;; +13295;EGYPTIAN HIEROGLYPH O048;Lo;0;L;;;;;N;;;;; +13296;EGYPTIAN HIEROGLYPH O049;Lo;0;L;;;;;N;;;;; +13297;EGYPTIAN HIEROGLYPH O050;Lo;0;L;;;;;N;;;;; +13298;EGYPTIAN HIEROGLYPH O050A;Lo;0;L;;;;;N;;;;; +13299;EGYPTIAN HIEROGLYPH O050B;Lo;0;L;;;;;N;;;;; +1329A;EGYPTIAN HIEROGLYPH O051;Lo;0;L;;;;;N;;;;; +1329B;EGYPTIAN HIEROGLYPH P001;Lo;0;L;;;;;N;;;;; +1329C;EGYPTIAN HIEROGLYPH P001A;Lo;0;L;;;;;N;;;;; +1329D;EGYPTIAN HIEROGLYPH P002;Lo;0;L;;;;;N;;;;; +1329E;EGYPTIAN HIEROGLYPH P003;Lo;0;L;;;;;N;;;;; +1329F;EGYPTIAN HIEROGLYPH P003A;Lo;0;L;;;;;N;;;;; +132A0;EGYPTIAN HIEROGLYPH P004;Lo;0;L;;;;;N;;;;; +132A1;EGYPTIAN HIEROGLYPH P005;Lo;0;L;;;;;N;;;;; +132A2;EGYPTIAN HIEROGLYPH P006;Lo;0;L;;;;;N;;;;; +132A3;EGYPTIAN HIEROGLYPH P007;Lo;0;L;;;;;N;;;;; +132A4;EGYPTIAN HIEROGLYPH P008;Lo;0;L;;;;;N;;;;; +132A5;EGYPTIAN HIEROGLYPH P009;Lo;0;L;;;;;N;;;;; +132A6;EGYPTIAN HIEROGLYPH P010;Lo;0;L;;;;;N;;;;; +132A7;EGYPTIAN HIEROGLYPH P011;Lo;0;L;;;;;N;;;;; +132A8;EGYPTIAN HIEROGLYPH Q001;Lo;0;L;;;;;N;;;;; +132A9;EGYPTIAN HIEROGLYPH Q002;Lo;0;L;;;;;N;;;;; +132AA;EGYPTIAN HIEROGLYPH Q003;Lo;0;L;;;;;N;;;;; +132AB;EGYPTIAN HIEROGLYPH Q004;Lo;0;L;;;;;N;;;;; +132AC;EGYPTIAN HIEROGLYPH Q005;Lo;0;L;;;;;N;;;;; +132AD;EGYPTIAN HIEROGLYPH Q006;Lo;0;L;;;;;N;;;;; +132AE;EGYPTIAN HIEROGLYPH Q007;Lo;0;L;;;;;N;;;;; +132AF;EGYPTIAN HIEROGLYPH R001;Lo;0;L;;;;;N;;;;; +132B0;EGYPTIAN HIEROGLYPH R002;Lo;0;L;;;;;N;;;;; +132B1;EGYPTIAN HIEROGLYPH R002A;Lo;0;L;;;;;N;;;;; +132B2;EGYPTIAN HIEROGLYPH R003;Lo;0;L;;;;;N;;;;; +132B3;EGYPTIAN HIEROGLYPH R003A;Lo;0;L;;;;;N;;;;; +132B4;EGYPTIAN HIEROGLYPH R003B;Lo;0;L;;;;;N;;;;; +132B5;EGYPTIAN HIEROGLYPH R004;Lo;0;L;;;;;N;;;;; +132B6;EGYPTIAN HIEROGLYPH R005;Lo;0;L;;;;;N;;;;; +132B7;EGYPTIAN HIEROGLYPH R006;Lo;0;L;;;;;N;;;;; +132B8;EGYPTIAN HIEROGLYPH R007;Lo;0;L;;;;;N;;;;; +132B9;EGYPTIAN HIEROGLYPH R008;Lo;0;L;;;;;N;;;;; +132BA;EGYPTIAN HIEROGLYPH R009;Lo;0;L;;;;;N;;;;; +132BB;EGYPTIAN HIEROGLYPH R010;Lo;0;L;;;;;N;;;;; +132BC;EGYPTIAN HIEROGLYPH R010A;Lo;0;L;;;;;N;;;;; +132BD;EGYPTIAN HIEROGLYPH R011;Lo;0;L;;;;;N;;;;; +132BE;EGYPTIAN HIEROGLYPH R012;Lo;0;L;;;;;N;;;;; +132BF;EGYPTIAN HIEROGLYPH R013;Lo;0;L;;;;;N;;;;; +132C0;EGYPTIAN HIEROGLYPH R014;Lo;0;L;;;;;N;;;;; +132C1;EGYPTIAN HIEROGLYPH R015;Lo;0;L;;;;;N;;;;; +132C2;EGYPTIAN HIEROGLYPH R016;Lo;0;L;;;;;N;;;;; +132C3;EGYPTIAN HIEROGLYPH R016A;Lo;0;L;;;;;N;;;;; +132C4;EGYPTIAN HIEROGLYPH R017;Lo;0;L;;;;;N;;;;; +132C5;EGYPTIAN HIEROGLYPH R018;Lo;0;L;;;;;N;;;;; +132C6;EGYPTIAN HIEROGLYPH R019;Lo;0;L;;;;;N;;;;; +132C7;EGYPTIAN HIEROGLYPH R020;Lo;0;L;;;;;N;;;;; +132C8;EGYPTIAN HIEROGLYPH R021;Lo;0;L;;;;;N;;;;; +132C9;EGYPTIAN HIEROGLYPH R022;Lo;0;L;;;;;N;;;;; +132CA;EGYPTIAN HIEROGLYPH R023;Lo;0;L;;;;;N;;;;; +132CB;EGYPTIAN HIEROGLYPH R024;Lo;0;L;;;;;N;;;;; +132CC;EGYPTIAN HIEROGLYPH R025;Lo;0;L;;;;;N;;;;; +132CD;EGYPTIAN HIEROGLYPH R026;Lo;0;L;;;;;N;;;;; +132CE;EGYPTIAN HIEROGLYPH R027;Lo;0;L;;;;;N;;;;; +132CF;EGYPTIAN HIEROGLYPH R028;Lo;0;L;;;;;N;;;;; +132D0;EGYPTIAN HIEROGLYPH R029;Lo;0;L;;;;;N;;;;; +132D1;EGYPTIAN HIEROGLYPH S001;Lo;0;L;;;;;N;;;;; +132D2;EGYPTIAN HIEROGLYPH S002;Lo;0;L;;;;;N;;;;; +132D3;EGYPTIAN HIEROGLYPH S002A;Lo;0;L;;;;;N;;;;; +132D4;EGYPTIAN HIEROGLYPH S003;Lo;0;L;;;;;N;;;;; +132D5;EGYPTIAN HIEROGLYPH S004;Lo;0;L;;;;;N;;;;; +132D6;EGYPTIAN HIEROGLYPH S005;Lo;0;L;;;;;N;;;;; +132D7;EGYPTIAN HIEROGLYPH S006;Lo;0;L;;;;;N;;;;; +132D8;EGYPTIAN HIEROGLYPH S006A;Lo;0;L;;;;;N;;;;; +132D9;EGYPTIAN HIEROGLYPH S007;Lo;0;L;;;;;N;;;;; +132DA;EGYPTIAN HIEROGLYPH S008;Lo;0;L;;;;;N;;;;; +132DB;EGYPTIAN HIEROGLYPH S009;Lo;0;L;;;;;N;;;;; +132DC;EGYPTIAN HIEROGLYPH S010;Lo;0;L;;;;;N;;;;; +132DD;EGYPTIAN HIEROGLYPH S011;Lo;0;L;;;;;N;;;;; +132DE;EGYPTIAN HIEROGLYPH S012;Lo;0;L;;;;;N;;;;; +132DF;EGYPTIAN HIEROGLYPH S013;Lo;0;L;;;;;N;;;;; +132E0;EGYPTIAN HIEROGLYPH S014;Lo;0;L;;;;;N;;;;; +132E1;EGYPTIAN HIEROGLYPH S014A;Lo;0;L;;;;;N;;;;; +132E2;EGYPTIAN HIEROGLYPH S014B;Lo;0;L;;;;;N;;;;; +132E3;EGYPTIAN HIEROGLYPH S015;Lo;0;L;;;;;N;;;;; +132E4;EGYPTIAN HIEROGLYPH S016;Lo;0;L;;;;;N;;;;; +132E5;EGYPTIAN HIEROGLYPH S017;Lo;0;L;;;;;N;;;;; +132E6;EGYPTIAN HIEROGLYPH S017A;Lo;0;L;;;;;N;;;;; +132E7;EGYPTIAN HIEROGLYPH S018;Lo;0;L;;;;;N;;;;; +132E8;EGYPTIAN HIEROGLYPH S019;Lo;0;L;;;;;N;;;;; +132E9;EGYPTIAN HIEROGLYPH S020;Lo;0;L;;;;;N;;;;; +132EA;EGYPTIAN HIEROGLYPH S021;Lo;0;L;;;;;N;;;;; +132EB;EGYPTIAN HIEROGLYPH S022;Lo;0;L;;;;;N;;;;; +132EC;EGYPTIAN HIEROGLYPH S023;Lo;0;L;;;;;N;;;;; +132ED;EGYPTIAN HIEROGLYPH S024;Lo;0;L;;;;;N;;;;; +132EE;EGYPTIAN HIEROGLYPH S025;Lo;0;L;;;;;N;;;;; +132EF;EGYPTIAN HIEROGLYPH S026;Lo;0;L;;;;;N;;;;; +132F0;EGYPTIAN HIEROGLYPH S026A;Lo;0;L;;;;;N;;;;; +132F1;EGYPTIAN HIEROGLYPH S026B;Lo;0;L;;;;;N;;;;; +132F2;EGYPTIAN HIEROGLYPH S027;Lo;0;L;;;;;N;;;;; +132F3;EGYPTIAN HIEROGLYPH S028;Lo;0;L;;;;;N;;;;; +132F4;EGYPTIAN HIEROGLYPH S029;Lo;0;L;;;;;N;;;;; +132F5;EGYPTIAN HIEROGLYPH S030;Lo;0;L;;;;;N;;;;; +132F6;EGYPTIAN HIEROGLYPH S031;Lo;0;L;;;;;N;;;;; +132F7;EGYPTIAN HIEROGLYPH S032;Lo;0;L;;;;;N;;;;; +132F8;EGYPTIAN HIEROGLYPH S033;Lo;0;L;;;;;N;;;;; +132F9;EGYPTIAN HIEROGLYPH S034;Lo;0;L;;;;;N;;;;; +132FA;EGYPTIAN HIEROGLYPH S035;Lo;0;L;;;;;N;;;;; +132FB;EGYPTIAN HIEROGLYPH S035A;Lo;0;L;;;;;N;;;;; +132FC;EGYPTIAN HIEROGLYPH S036;Lo;0;L;;;;;N;;;;; +132FD;EGYPTIAN HIEROGLYPH S037;Lo;0;L;;;;;N;;;;; +132FE;EGYPTIAN HIEROGLYPH S038;Lo;0;L;;;;;N;;;;; +132FF;EGYPTIAN HIEROGLYPH S039;Lo;0;L;;;;;N;;;;; +13300;EGYPTIAN HIEROGLYPH S040;Lo;0;L;;;;;N;;;;; +13301;EGYPTIAN HIEROGLYPH S041;Lo;0;L;;;;;N;;;;; +13302;EGYPTIAN HIEROGLYPH S042;Lo;0;L;;;;;N;;;;; +13303;EGYPTIAN HIEROGLYPH S043;Lo;0;L;;;;;N;;;;; +13304;EGYPTIAN HIEROGLYPH S044;Lo;0;L;;;;;N;;;;; +13305;EGYPTIAN HIEROGLYPH S045;Lo;0;L;;;;;N;;;;; +13306;EGYPTIAN HIEROGLYPH S046;Lo;0;L;;;;;N;;;;; +13307;EGYPTIAN HIEROGLYPH T001;Lo;0;L;;;;;N;;;;; +13308;EGYPTIAN HIEROGLYPH T002;Lo;0;L;;;;;N;;;;; +13309;EGYPTIAN HIEROGLYPH T003;Lo;0;L;;;;;N;;;;; +1330A;EGYPTIAN HIEROGLYPH T003A;Lo;0;L;;;;;N;;;;; +1330B;EGYPTIAN HIEROGLYPH T004;Lo;0;L;;;;;N;;;;; +1330C;EGYPTIAN HIEROGLYPH T005;Lo;0;L;;;;;N;;;;; +1330D;EGYPTIAN HIEROGLYPH T006;Lo;0;L;;;;;N;;;;; +1330E;EGYPTIAN HIEROGLYPH T007;Lo;0;L;;;;;N;;;;; +1330F;EGYPTIAN HIEROGLYPH T007A;Lo;0;L;;;;;N;;;;; +13310;EGYPTIAN HIEROGLYPH T008;Lo;0;L;;;;;N;;;;; +13311;EGYPTIAN HIEROGLYPH T008A;Lo;0;L;;;;;N;;;;; +13312;EGYPTIAN HIEROGLYPH T009;Lo;0;L;;;;;N;;;;; +13313;EGYPTIAN HIEROGLYPH T009A;Lo;0;L;;;;;N;;;;; +13314;EGYPTIAN HIEROGLYPH T010;Lo;0;L;;;;;N;;;;; +13315;EGYPTIAN HIEROGLYPH T011;Lo;0;L;;;;;N;;;;; +13316;EGYPTIAN HIEROGLYPH T011A;Lo;0;L;;;;;N;;;;; +13317;EGYPTIAN HIEROGLYPH T012;Lo;0;L;;;;;N;;;;; +13318;EGYPTIAN HIEROGLYPH T013;Lo;0;L;;;;;N;;;;; +13319;EGYPTIAN HIEROGLYPH T014;Lo;0;L;;;;;N;;;;; +1331A;EGYPTIAN HIEROGLYPH T015;Lo;0;L;;;;;N;;;;; +1331B;EGYPTIAN HIEROGLYPH T016;Lo;0;L;;;;;N;;;;; +1331C;EGYPTIAN HIEROGLYPH T016A;Lo;0;L;;;;;N;;;;; +1331D;EGYPTIAN HIEROGLYPH T017;Lo;0;L;;;;;N;;;;; +1331E;EGYPTIAN HIEROGLYPH T018;Lo;0;L;;;;;N;;;;; +1331F;EGYPTIAN HIEROGLYPH T019;Lo;0;L;;;;;N;;;;; +13320;EGYPTIAN HIEROGLYPH T020;Lo;0;L;;;;;N;;;;; +13321;EGYPTIAN HIEROGLYPH T021;Lo;0;L;;;;;N;;;;; +13322;EGYPTIAN HIEROGLYPH T022;Lo;0;L;;;;;N;;;;; +13323;EGYPTIAN HIEROGLYPH T023;Lo;0;L;;;;;N;;;;; +13324;EGYPTIAN HIEROGLYPH T024;Lo;0;L;;;;;N;;;;; +13325;EGYPTIAN HIEROGLYPH T025;Lo;0;L;;;;;N;;;;; +13326;EGYPTIAN HIEROGLYPH T026;Lo;0;L;;;;;N;;;;; +13327;EGYPTIAN HIEROGLYPH T027;Lo;0;L;;;;;N;;;;; +13328;EGYPTIAN HIEROGLYPH T028;Lo;0;L;;;;;N;;;;; +13329;EGYPTIAN HIEROGLYPH T029;Lo;0;L;;;;;N;;;;; +1332A;EGYPTIAN HIEROGLYPH T030;Lo;0;L;;;;;N;;;;; +1332B;EGYPTIAN HIEROGLYPH T031;Lo;0;L;;;;;N;;;;; +1332C;EGYPTIAN HIEROGLYPH T032;Lo;0;L;;;;;N;;;;; +1332D;EGYPTIAN HIEROGLYPH T032A;Lo;0;L;;;;;N;;;;; +1332E;EGYPTIAN HIEROGLYPH T033;Lo;0;L;;;;;N;;;;; +1332F;EGYPTIAN HIEROGLYPH T033A;Lo;0;L;;;;;N;;;;; +13330;EGYPTIAN HIEROGLYPH T034;Lo;0;L;;;;;N;;;;; +13331;EGYPTIAN HIEROGLYPH T035;Lo;0;L;;;;;N;;;;; +13332;EGYPTIAN HIEROGLYPH T036;Lo;0;L;;;;;N;;;;; +13333;EGYPTIAN HIEROGLYPH U001;Lo;0;L;;;;;N;;;;; +13334;EGYPTIAN HIEROGLYPH U002;Lo;0;L;;;;;N;;;;; +13335;EGYPTIAN HIEROGLYPH U003;Lo;0;L;;;;;N;;;;; +13336;EGYPTIAN HIEROGLYPH U004;Lo;0;L;;;;;N;;;;; +13337;EGYPTIAN HIEROGLYPH U005;Lo;0;L;;;;;N;;;;; +13338;EGYPTIAN HIEROGLYPH U006;Lo;0;L;;;;;N;;;;; +13339;EGYPTIAN HIEROGLYPH U006A;Lo;0;L;;;;;N;;;;; +1333A;EGYPTIAN HIEROGLYPH U006B;Lo;0;L;;;;;N;;;;; +1333B;EGYPTIAN HIEROGLYPH U007;Lo;0;L;;;;;N;;;;; +1333C;EGYPTIAN HIEROGLYPH U008;Lo;0;L;;;;;N;;;;; +1333D;EGYPTIAN HIEROGLYPH U009;Lo;0;L;;;;;N;;;;; +1333E;EGYPTIAN HIEROGLYPH U010;Lo;0;L;;;;;N;;;;; +1333F;EGYPTIAN HIEROGLYPH U011;Lo;0;L;;;;;N;;;;; +13340;EGYPTIAN HIEROGLYPH U012;Lo;0;L;;;;;N;;;;; +13341;EGYPTIAN HIEROGLYPH U013;Lo;0;L;;;;;N;;;;; +13342;EGYPTIAN HIEROGLYPH U014;Lo;0;L;;;;;N;;;;; +13343;EGYPTIAN HIEROGLYPH U015;Lo;0;L;;;;;N;;;;; +13344;EGYPTIAN HIEROGLYPH U016;Lo;0;L;;;;;N;;;;; +13345;EGYPTIAN HIEROGLYPH U017;Lo;0;L;;;;;N;;;;; +13346;EGYPTIAN HIEROGLYPH U018;Lo;0;L;;;;;N;;;;; +13347;EGYPTIAN HIEROGLYPH U019;Lo;0;L;;;;;N;;;;; +13348;EGYPTIAN HIEROGLYPH U020;Lo;0;L;;;;;N;;;;; +13349;EGYPTIAN HIEROGLYPH U021;Lo;0;L;;;;;N;;;;; +1334A;EGYPTIAN HIEROGLYPH U022;Lo;0;L;;;;;N;;;;; +1334B;EGYPTIAN HIEROGLYPH U023;Lo;0;L;;;;;N;;;;; +1334C;EGYPTIAN HIEROGLYPH U023A;Lo;0;L;;;;;N;;;;; +1334D;EGYPTIAN HIEROGLYPH U024;Lo;0;L;;;;;N;;;;; +1334E;EGYPTIAN HIEROGLYPH U025;Lo;0;L;;;;;N;;;;; +1334F;EGYPTIAN HIEROGLYPH U026;Lo;0;L;;;;;N;;;;; +13350;EGYPTIAN HIEROGLYPH U027;Lo;0;L;;;;;N;;;;; +13351;EGYPTIAN HIEROGLYPH U028;Lo;0;L;;;;;N;;;;; +13352;EGYPTIAN HIEROGLYPH U029;Lo;0;L;;;;;N;;;;; +13353;EGYPTIAN HIEROGLYPH U029A;Lo;0;L;;;;;N;;;;; +13354;EGYPTIAN HIEROGLYPH U030;Lo;0;L;;;;;N;;;;; +13355;EGYPTIAN HIEROGLYPH U031;Lo;0;L;;;;;N;;;;; +13356;EGYPTIAN HIEROGLYPH U032;Lo;0;L;;;;;N;;;;; +13357;EGYPTIAN HIEROGLYPH U032A;Lo;0;L;;;;;N;;;;; +13358;EGYPTIAN HIEROGLYPH U033;Lo;0;L;;;;;N;;;;; +13359;EGYPTIAN HIEROGLYPH U034;Lo;0;L;;;;;N;;;;; +1335A;EGYPTIAN HIEROGLYPH U035;Lo;0;L;;;;;N;;;;; +1335B;EGYPTIAN HIEROGLYPH U036;Lo;0;L;;;;;N;;;;; +1335C;EGYPTIAN HIEROGLYPH U037;Lo;0;L;;;;;N;;;;; +1335D;EGYPTIAN HIEROGLYPH U038;Lo;0;L;;;;;N;;;;; +1335E;EGYPTIAN HIEROGLYPH U039;Lo;0;L;;;;;N;;;;; +1335F;EGYPTIAN HIEROGLYPH U040;Lo;0;L;;;;;N;;;;; +13360;EGYPTIAN HIEROGLYPH U041;Lo;0;L;;;;;N;;;;; +13361;EGYPTIAN HIEROGLYPH U042;Lo;0;L;;;;;N;;;;; +13362;EGYPTIAN HIEROGLYPH V001;Lo;0;L;;;;;N;;;;; +13363;EGYPTIAN HIEROGLYPH V001A;Lo;0;L;;;;;N;;;;; +13364;EGYPTIAN HIEROGLYPH V001B;Lo;0;L;;;;;N;;;;; +13365;EGYPTIAN HIEROGLYPH V001C;Lo;0;L;;;;;N;;;;; +13366;EGYPTIAN HIEROGLYPH V001D;Lo;0;L;;;;;N;;;;; +13367;EGYPTIAN HIEROGLYPH V001E;Lo;0;L;;;;;N;;;;; +13368;EGYPTIAN HIEROGLYPH V001F;Lo;0;L;;;;;N;;;;; +13369;EGYPTIAN HIEROGLYPH V001G;Lo;0;L;;;;;N;;;;; +1336A;EGYPTIAN HIEROGLYPH V001H;Lo;0;L;;;;;N;;;;; +1336B;EGYPTIAN HIEROGLYPH V001I;Lo;0;L;;;;;N;;;;; +1336C;EGYPTIAN HIEROGLYPH V002;Lo;0;L;;;;;N;;;;; +1336D;EGYPTIAN HIEROGLYPH V002A;Lo;0;L;;;;;N;;;;; +1336E;EGYPTIAN HIEROGLYPH V003;Lo;0;L;;;;;N;;;;; +1336F;EGYPTIAN HIEROGLYPH V004;Lo;0;L;;;;;N;;;;; +13370;EGYPTIAN HIEROGLYPH V005;Lo;0;L;;;;;N;;;;; +13371;EGYPTIAN HIEROGLYPH V006;Lo;0;L;;;;;N;;;;; +13372;EGYPTIAN HIEROGLYPH V007;Lo;0;L;;;;;N;;;;; +13373;EGYPTIAN HIEROGLYPH V007A;Lo;0;L;;;;;N;;;;; +13374;EGYPTIAN HIEROGLYPH V007B;Lo;0;L;;;;;N;;;;; +13375;EGYPTIAN HIEROGLYPH V008;Lo;0;L;;;;;N;;;;; +13376;EGYPTIAN HIEROGLYPH V009;Lo;0;L;;;;;N;;;;; +13377;EGYPTIAN HIEROGLYPH V010;Lo;0;L;;;;;N;;;;; +13378;EGYPTIAN HIEROGLYPH V011;Lo;0;L;;;;;N;;;;; +13379;EGYPTIAN HIEROGLYPH V011A;Lo;0;L;;;;;N;;;;; +1337A;EGYPTIAN HIEROGLYPH V011B;Lo;0;L;;;;;N;;;;; +1337B;EGYPTIAN HIEROGLYPH V011C;Lo;0;L;;;;;N;;;;; +1337C;EGYPTIAN HIEROGLYPH V012;Lo;0;L;;;;;N;;;;; +1337D;EGYPTIAN HIEROGLYPH V012A;Lo;0;L;;;;;N;;;;; +1337E;EGYPTIAN HIEROGLYPH V012B;Lo;0;L;;;;;N;;;;; +1337F;EGYPTIAN HIEROGLYPH V013;Lo;0;L;;;;;N;;;;; +13380;EGYPTIAN HIEROGLYPH V014;Lo;0;L;;;;;N;;;;; +13381;EGYPTIAN HIEROGLYPH V015;Lo;0;L;;;;;N;;;;; +13382;EGYPTIAN HIEROGLYPH V016;Lo;0;L;;;;;N;;;;; +13383;EGYPTIAN HIEROGLYPH V017;Lo;0;L;;;;;N;;;;; +13384;EGYPTIAN HIEROGLYPH V018;Lo;0;L;;;;;N;;;;; +13385;EGYPTIAN HIEROGLYPH V019;Lo;0;L;;;;;N;;;;; +13386;EGYPTIAN HIEROGLYPH V020;Lo;0;L;;;;;N;;;;; +13387;EGYPTIAN HIEROGLYPH V020A;Lo;0;L;;;;;N;;;;; +13388;EGYPTIAN HIEROGLYPH V020B;Lo;0;L;;;;;N;;;;; +13389;EGYPTIAN HIEROGLYPH V020C;Lo;0;L;;;;;N;;;;; +1338A;EGYPTIAN HIEROGLYPH V020D;Lo;0;L;;;;;N;;;;; +1338B;EGYPTIAN HIEROGLYPH V020E;Lo;0;L;;;;;N;;;;; +1338C;EGYPTIAN HIEROGLYPH V020F;Lo;0;L;;;;;N;;;;; +1338D;EGYPTIAN HIEROGLYPH V020G;Lo;0;L;;;;;N;;;;; +1338E;EGYPTIAN HIEROGLYPH V020H;Lo;0;L;;;;;N;;;;; +1338F;EGYPTIAN HIEROGLYPH V020I;Lo;0;L;;;;;N;;;;; +13390;EGYPTIAN HIEROGLYPH V020J;Lo;0;L;;;;;N;;;;; +13391;EGYPTIAN HIEROGLYPH V020K;Lo;0;L;;;;;N;;;;; +13392;EGYPTIAN HIEROGLYPH V020L;Lo;0;L;;;;;N;;;;; +13393;EGYPTIAN HIEROGLYPH V021;Lo;0;L;;;;;N;;;;; +13394;EGYPTIAN HIEROGLYPH V022;Lo;0;L;;;;;N;;;;; +13395;EGYPTIAN HIEROGLYPH V023;Lo;0;L;;;;;N;;;;; +13396;EGYPTIAN HIEROGLYPH V023A;Lo;0;L;;;;;N;;;;; +13397;EGYPTIAN HIEROGLYPH V024;Lo;0;L;;;;;N;;;;; +13398;EGYPTIAN HIEROGLYPH V025;Lo;0;L;;;;;N;;;;; +13399;EGYPTIAN HIEROGLYPH V026;Lo;0;L;;;;;N;;;;; +1339A;EGYPTIAN HIEROGLYPH V027;Lo;0;L;;;;;N;;;;; +1339B;EGYPTIAN HIEROGLYPH V028;Lo;0;L;;;;;N;;;;; +1339C;EGYPTIAN HIEROGLYPH V028A;Lo;0;L;;;;;N;;;;; +1339D;EGYPTIAN HIEROGLYPH V029;Lo;0;L;;;;;N;;;;; +1339E;EGYPTIAN HIEROGLYPH V029A;Lo;0;L;;;;;N;;;;; +1339F;EGYPTIAN HIEROGLYPH V030;Lo;0;L;;;;;N;;;;; +133A0;EGYPTIAN HIEROGLYPH V030A;Lo;0;L;;;;;N;;;;; +133A1;EGYPTIAN HIEROGLYPH V031;Lo;0;L;;;;;N;;;;; +133A2;EGYPTIAN HIEROGLYPH V031A;Lo;0;L;;;;;N;;;;; +133A3;EGYPTIAN HIEROGLYPH V032;Lo;0;L;;;;;N;;;;; +133A4;EGYPTIAN HIEROGLYPH V033;Lo;0;L;;;;;N;;;;; +133A5;EGYPTIAN HIEROGLYPH V033A;Lo;0;L;;;;;N;;;;; +133A6;EGYPTIAN HIEROGLYPH V034;Lo;0;L;;;;;N;;;;; +133A7;EGYPTIAN HIEROGLYPH V035;Lo;0;L;;;;;N;;;;; +133A8;EGYPTIAN HIEROGLYPH V036;Lo;0;L;;;;;N;;;;; +133A9;EGYPTIAN HIEROGLYPH V037;Lo;0;L;;;;;N;;;;; +133AA;EGYPTIAN HIEROGLYPH V037A;Lo;0;L;;;;;N;;;;; +133AB;EGYPTIAN HIEROGLYPH V038;Lo;0;L;;;;;N;;;;; +133AC;EGYPTIAN HIEROGLYPH V039;Lo;0;L;;;;;N;;;;; +133AD;EGYPTIAN HIEROGLYPH V040;Lo;0;L;;;;;N;;;;; +133AE;EGYPTIAN HIEROGLYPH V040A;Lo;0;L;;;;;N;;;;; +133AF;EGYPTIAN HIEROGLYPH W001;Lo;0;L;;;;;N;;;;; +133B0;EGYPTIAN HIEROGLYPH W002;Lo;0;L;;;;;N;;;;; +133B1;EGYPTIAN HIEROGLYPH W003;Lo;0;L;;;;;N;;;;; +133B2;EGYPTIAN HIEROGLYPH W003A;Lo;0;L;;;;;N;;;;; +133B3;EGYPTIAN HIEROGLYPH W004;Lo;0;L;;;;;N;;;;; +133B4;EGYPTIAN HIEROGLYPH W005;Lo;0;L;;;;;N;;;;; +133B5;EGYPTIAN HIEROGLYPH W006;Lo;0;L;;;;;N;;;;; +133B6;EGYPTIAN HIEROGLYPH W007;Lo;0;L;;;;;N;;;;; +133B7;EGYPTIAN HIEROGLYPH W008;Lo;0;L;;;;;N;;;;; +133B8;EGYPTIAN HIEROGLYPH W009;Lo;0;L;;;;;N;;;;; +133B9;EGYPTIAN HIEROGLYPH W009A;Lo;0;L;;;;;N;;;;; +133BA;EGYPTIAN HIEROGLYPH W010;Lo;0;L;;;;;N;;;;; +133BB;EGYPTIAN HIEROGLYPH W010A;Lo;0;L;;;;;N;;;;; +133BC;EGYPTIAN HIEROGLYPH W011;Lo;0;L;;;;;N;;;;; +133BD;EGYPTIAN HIEROGLYPH W012;Lo;0;L;;;;;N;;;;; +133BE;EGYPTIAN HIEROGLYPH W013;Lo;0;L;;;;;N;;;;; +133BF;EGYPTIAN HIEROGLYPH W014;Lo;0;L;;;;;N;;;;; +133C0;EGYPTIAN HIEROGLYPH W014A;Lo;0;L;;;;;N;;;;; +133C1;EGYPTIAN HIEROGLYPH W015;Lo;0;L;;;;;N;;;;; +133C2;EGYPTIAN HIEROGLYPH W016;Lo;0;L;;;;;N;;;;; +133C3;EGYPTIAN HIEROGLYPH W017;Lo;0;L;;;;;N;;;;; +133C4;EGYPTIAN HIEROGLYPH W017A;Lo;0;L;;;;;N;;;;; +133C5;EGYPTIAN HIEROGLYPH W018;Lo;0;L;;;;;N;;;;; +133C6;EGYPTIAN HIEROGLYPH W018A;Lo;0;L;;;;;N;;;;; +133C7;EGYPTIAN HIEROGLYPH W019;Lo;0;L;;;;;N;;;;; +133C8;EGYPTIAN HIEROGLYPH W020;Lo;0;L;;;;;N;;;;; +133C9;EGYPTIAN HIEROGLYPH W021;Lo;0;L;;;;;N;;;;; +133CA;EGYPTIAN HIEROGLYPH W022;Lo;0;L;;;;;N;;;;; +133CB;EGYPTIAN HIEROGLYPH W023;Lo;0;L;;;;;N;;;;; +133CC;EGYPTIAN HIEROGLYPH W024;Lo;0;L;;;;;N;;;;; +133CD;EGYPTIAN HIEROGLYPH W024A;Lo;0;L;;;;;N;;;;; +133CE;EGYPTIAN HIEROGLYPH W025;Lo;0;L;;;;;N;;;;; +133CF;EGYPTIAN HIEROGLYPH X001;Lo;0;L;;;;;N;;;;; +133D0;EGYPTIAN HIEROGLYPH X002;Lo;0;L;;;;;N;;;;; +133D1;EGYPTIAN HIEROGLYPH X003;Lo;0;L;;;;;N;;;;; +133D2;EGYPTIAN HIEROGLYPH X004;Lo;0;L;;;;;N;;;;; +133D3;EGYPTIAN HIEROGLYPH X004A;Lo;0;L;;;;;N;;;;; +133D4;EGYPTIAN HIEROGLYPH X004B;Lo;0;L;;;;;N;;;;; +133D5;EGYPTIAN HIEROGLYPH X005;Lo;0;L;;;;;N;;;;; +133D6;EGYPTIAN HIEROGLYPH X006;Lo;0;L;;;;;N;;;;; +133D7;EGYPTIAN HIEROGLYPH X006A;Lo;0;L;;;;;N;;;;; +133D8;EGYPTIAN HIEROGLYPH X007;Lo;0;L;;;;;N;;;;; +133D9;EGYPTIAN HIEROGLYPH X008;Lo;0;L;;;;;N;;;;; +133DA;EGYPTIAN HIEROGLYPH X008A;Lo;0;L;;;;;N;;;;; +133DB;EGYPTIAN HIEROGLYPH Y001;Lo;0;L;;;;;N;;;;; +133DC;EGYPTIAN HIEROGLYPH Y001A;Lo;0;L;;;;;N;;;;; +133DD;EGYPTIAN HIEROGLYPH Y002;Lo;0;L;;;;;N;;;;; +133DE;EGYPTIAN HIEROGLYPH Y003;Lo;0;L;;;;;N;;;;; +133DF;EGYPTIAN HIEROGLYPH Y004;Lo;0;L;;;;;N;;;;; +133E0;EGYPTIAN HIEROGLYPH Y005;Lo;0;L;;;;;N;;;;; +133E1;EGYPTIAN HIEROGLYPH Y006;Lo;0;L;;;;;N;;;;; +133E2;EGYPTIAN HIEROGLYPH Y007;Lo;0;L;;;;;N;;;;; +133E3;EGYPTIAN HIEROGLYPH Y008;Lo;0;L;;;;;N;;;;; +133E4;EGYPTIAN HIEROGLYPH Z001;Lo;0;L;;;;;N;;;;; +133E5;EGYPTIAN HIEROGLYPH Z002;Lo;0;L;;;;;N;;;;; +133E6;EGYPTIAN HIEROGLYPH Z002A;Lo;0;L;;;;;N;;;;; +133E7;EGYPTIAN HIEROGLYPH Z002B;Lo;0;L;;;;;N;;;;; +133E8;EGYPTIAN HIEROGLYPH Z002C;Lo;0;L;;;;;N;;;;; +133E9;EGYPTIAN HIEROGLYPH Z002D;Lo;0;L;;;;;N;;;;; +133EA;EGYPTIAN HIEROGLYPH Z003;Lo;0;L;;;;;N;;;;; +133EB;EGYPTIAN HIEROGLYPH Z003A;Lo;0;L;;;;;N;;;;; +133EC;EGYPTIAN HIEROGLYPH Z003B;Lo;0;L;;;;;N;;;;; +133ED;EGYPTIAN HIEROGLYPH Z004;Lo;0;L;;;;;N;;;;; +133EE;EGYPTIAN HIEROGLYPH Z004A;Lo;0;L;;;;;N;;;;; +133EF;EGYPTIAN HIEROGLYPH Z005;Lo;0;L;;;;;N;;;;; +133F0;EGYPTIAN HIEROGLYPH Z005A;Lo;0;L;;;;;N;;;;; +133F1;EGYPTIAN HIEROGLYPH Z006;Lo;0;L;;;;;N;;;;; +133F2;EGYPTIAN HIEROGLYPH Z007;Lo;0;L;;;;;N;;;;; +133F3;EGYPTIAN HIEROGLYPH Z008;Lo;0;L;;;;;N;;;;; +133F4;EGYPTIAN HIEROGLYPH Z009;Lo;0;L;;;;;N;;;;; +133F5;EGYPTIAN HIEROGLYPH Z010;Lo;0;L;;;;;N;;;;; +133F6;EGYPTIAN HIEROGLYPH Z011;Lo;0;L;;;;;N;;;;; +133F7;EGYPTIAN HIEROGLYPH Z012;Lo;0;L;;;;;N;;;;; +133F8;EGYPTIAN HIEROGLYPH Z013;Lo;0;L;;;;;N;;;;; +133F9;EGYPTIAN HIEROGLYPH Z014;Lo;0;L;;;;;N;;;;; +133FA;EGYPTIAN HIEROGLYPH Z015;Lo;0;L;;;;;N;;;;; +133FB;EGYPTIAN HIEROGLYPH Z015A;Lo;0;L;;;;;N;;;;; +133FC;EGYPTIAN HIEROGLYPH Z015B;Lo;0;L;;;;;N;;;;; +133FD;EGYPTIAN HIEROGLYPH Z015C;Lo;0;L;;;;;N;;;;; +133FE;EGYPTIAN HIEROGLYPH Z015D;Lo;0;L;;;;;N;;;;; +133FF;EGYPTIAN HIEROGLYPH Z015E;Lo;0;L;;;;;N;;;;; +13400;EGYPTIAN HIEROGLYPH Z015F;Lo;0;L;;;;;N;;;;; +13401;EGYPTIAN HIEROGLYPH Z015G;Lo;0;L;;;;;N;;;;; +13402;EGYPTIAN HIEROGLYPH Z015H;Lo;0;L;;;;;N;;;;; +13403;EGYPTIAN HIEROGLYPH Z015I;Lo;0;L;;;;;N;;;;; +13404;EGYPTIAN HIEROGLYPH Z016;Lo;0;L;;;;;N;;;;; +13405;EGYPTIAN HIEROGLYPH Z016A;Lo;0;L;;;;;N;;;;; +13406;EGYPTIAN HIEROGLYPH Z016B;Lo;0;L;;;;;N;;;;; +13407;EGYPTIAN HIEROGLYPH Z016C;Lo;0;L;;;;;N;;;;; +13408;EGYPTIAN HIEROGLYPH Z016D;Lo;0;L;;;;;N;;;;; +13409;EGYPTIAN HIEROGLYPH Z016E;Lo;0;L;;;;;N;;;;; +1340A;EGYPTIAN HIEROGLYPH Z016F;Lo;0;L;;;;;N;;;;; +1340B;EGYPTIAN HIEROGLYPH Z016G;Lo;0;L;;;;;N;;;;; +1340C;EGYPTIAN HIEROGLYPH Z016H;Lo;0;L;;;;;N;;;;; +1340D;EGYPTIAN HIEROGLYPH AA001;Lo;0;L;;;;;N;;;;; +1340E;EGYPTIAN HIEROGLYPH AA002;Lo;0;L;;;;;N;;;;; +1340F;EGYPTIAN HIEROGLYPH AA003;Lo;0;L;;;;;N;;;;; +13410;EGYPTIAN HIEROGLYPH AA004;Lo;0;L;;;;;N;;;;; +13411;EGYPTIAN HIEROGLYPH AA005;Lo;0;L;;;;;N;;;;; +13412;EGYPTIAN HIEROGLYPH AA006;Lo;0;L;;;;;N;;;;; +13413;EGYPTIAN HIEROGLYPH AA007;Lo;0;L;;;;;N;;;;; +13414;EGYPTIAN HIEROGLYPH AA007A;Lo;0;L;;;;;N;;;;; +13415;EGYPTIAN HIEROGLYPH AA007B;Lo;0;L;;;;;N;;;;; +13416;EGYPTIAN HIEROGLYPH AA008;Lo;0;L;;;;;N;;;;; +13417;EGYPTIAN HIEROGLYPH AA009;Lo;0;L;;;;;N;;;;; +13418;EGYPTIAN HIEROGLYPH AA010;Lo;0;L;;;;;N;;;;; +13419;EGYPTIAN HIEROGLYPH AA011;Lo;0;L;;;;;N;;;;; +1341A;EGYPTIAN HIEROGLYPH AA012;Lo;0;L;;;;;N;;;;; +1341B;EGYPTIAN HIEROGLYPH AA013;Lo;0;L;;;;;N;;;;; +1341C;EGYPTIAN HIEROGLYPH AA014;Lo;0;L;;;;;N;;;;; +1341D;EGYPTIAN HIEROGLYPH AA015;Lo;0;L;;;;;N;;;;; +1341E;EGYPTIAN HIEROGLYPH AA016;Lo;0;L;;;;;N;;;;; +1341F;EGYPTIAN HIEROGLYPH AA017;Lo;0;L;;;;;N;;;;; +13420;EGYPTIAN HIEROGLYPH AA018;Lo;0;L;;;;;N;;;;; +13421;EGYPTIAN HIEROGLYPH AA019;Lo;0;L;;;;;N;;;;; +13422;EGYPTIAN HIEROGLYPH AA020;Lo;0;L;;;;;N;;;;; +13423;EGYPTIAN HIEROGLYPH AA021;Lo;0;L;;;;;N;;;;; +13424;EGYPTIAN HIEROGLYPH AA022;Lo;0;L;;;;;N;;;;; +13425;EGYPTIAN HIEROGLYPH AA023;Lo;0;L;;;;;N;;;;; +13426;EGYPTIAN HIEROGLYPH AA024;Lo;0;L;;;;;N;;;;; +13427;EGYPTIAN HIEROGLYPH AA025;Lo;0;L;;;;;N;;;;; +13428;EGYPTIAN HIEROGLYPH AA026;Lo;0;L;;;;;N;;;;; +13429;EGYPTIAN HIEROGLYPH AA027;Lo;0;L;;;;;N;;;;; +1342A;EGYPTIAN HIEROGLYPH AA028;Lo;0;L;;;;;N;;;;; +1342B;EGYPTIAN HIEROGLYPH AA029;Lo;0;L;;;;;N;;;;; +1342C;EGYPTIAN HIEROGLYPH AA030;Lo;0;L;;;;;N;;;;; +1342D;EGYPTIAN HIEROGLYPH AA031;Lo;0;L;;;;;N;;;;; +1342E;EGYPTIAN HIEROGLYPH AA032;Lo;0;L;;;;;N;;;;; +13430;EGYPTIAN HIEROGLYPH VERTICAL JOINER;Cf;0;L;;;;;N;;;;; +13431;EGYPTIAN HIEROGLYPH HORIZONTAL JOINER;Cf;0;L;;;;;N;;;;; +13432;EGYPTIAN HIEROGLYPH INSERT AT TOP START;Cf;0;L;;;;;N;;;;; +13433;EGYPTIAN HIEROGLYPH INSERT AT BOTTOM START;Cf;0;L;;;;;N;;;;; +13434;EGYPTIAN HIEROGLYPH INSERT AT TOP END;Cf;0;L;;;;;N;;;;; +13435;EGYPTIAN HIEROGLYPH INSERT AT BOTTOM END;Cf;0;L;;;;;N;;;;; +13436;EGYPTIAN HIEROGLYPH OVERLAY MIDDLE;Cf;0;L;;;;;N;;;;; +13437;EGYPTIAN HIEROGLYPH BEGIN SEGMENT;Cf;0;L;;;;;N;;;;; +13438;EGYPTIAN HIEROGLYPH END SEGMENT;Cf;0;L;;;;;N;;;;; +14400;ANATOLIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;; +14401;ANATOLIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;; +14402;ANATOLIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;; +14403;ANATOLIAN HIEROGLYPH A004;Lo;0;L;;;;;N;;;;; +14404;ANATOLIAN HIEROGLYPH A005;Lo;0;L;;;;;N;;;;; +14405;ANATOLIAN HIEROGLYPH A006;Lo;0;L;;;;;N;;;;; +14406;ANATOLIAN HIEROGLYPH A007;Lo;0;L;;;;;N;;;;; +14407;ANATOLIAN HIEROGLYPH A008;Lo;0;L;;;;;N;;;;; +14408;ANATOLIAN HIEROGLYPH A009;Lo;0;L;;;;;N;;;;; +14409;ANATOLIAN HIEROGLYPH A010;Lo;0;L;;;;;N;;;;; +1440A;ANATOLIAN HIEROGLYPH A010A;Lo;0;L;;;;;N;;;;; +1440B;ANATOLIAN HIEROGLYPH A011;Lo;0;L;;;;;N;;;;; +1440C;ANATOLIAN HIEROGLYPH A012;Lo;0;L;;;;;N;;;;; +1440D;ANATOLIAN HIEROGLYPH A013;Lo;0;L;;;;;N;;;;; +1440E;ANATOLIAN HIEROGLYPH A014;Lo;0;L;;;;;N;;;;; +1440F;ANATOLIAN HIEROGLYPH A015;Lo;0;L;;;;;N;;;;; +14410;ANATOLIAN HIEROGLYPH A016;Lo;0;L;;;;;N;;;;; +14411;ANATOLIAN HIEROGLYPH A017;Lo;0;L;;;;;N;;;;; +14412;ANATOLIAN HIEROGLYPH A018;Lo;0;L;;;;;N;;;;; +14413;ANATOLIAN HIEROGLYPH A019;Lo;0;L;;;;;N;;;;; +14414;ANATOLIAN HIEROGLYPH A020;Lo;0;L;;;;;N;;;;; +14415;ANATOLIAN HIEROGLYPH A021;Lo;0;L;;;;;N;;;;; +14416;ANATOLIAN HIEROGLYPH A022;Lo;0;L;;;;;N;;;;; +14417;ANATOLIAN HIEROGLYPH A023;Lo;0;L;;;;;N;;;;; +14418;ANATOLIAN HIEROGLYPH A024;Lo;0;L;;;;;N;;;;; +14419;ANATOLIAN HIEROGLYPH A025;Lo;0;L;;;;;N;;;;; +1441A;ANATOLIAN HIEROGLYPH A026;Lo;0;L;;;;;N;;;;; +1441B;ANATOLIAN HIEROGLYPH A026A;Lo;0;L;;;;;N;;;;; +1441C;ANATOLIAN HIEROGLYPH A027;Lo;0;L;;;;;N;;;;; +1441D;ANATOLIAN HIEROGLYPH A028;Lo;0;L;;;;;N;;;;; +1441E;ANATOLIAN HIEROGLYPH A029;Lo;0;L;;;;;N;;;;; +1441F;ANATOLIAN HIEROGLYPH A030;Lo;0;L;;;;;N;;;;; +14420;ANATOLIAN HIEROGLYPH A031;Lo;0;L;;;;;N;;;;; +14421;ANATOLIAN HIEROGLYPH A032;Lo;0;L;;;;;N;;;;; +14422;ANATOLIAN HIEROGLYPH A033;Lo;0;L;;;;;N;;;;; +14423;ANATOLIAN HIEROGLYPH A034;Lo;0;L;;;;;N;;;;; +14424;ANATOLIAN HIEROGLYPH A035;Lo;0;L;;;;;N;;;;; +14425;ANATOLIAN HIEROGLYPH A036;Lo;0;L;;;;;N;;;;; +14426;ANATOLIAN HIEROGLYPH A037;Lo;0;L;;;;;N;;;;; +14427;ANATOLIAN HIEROGLYPH A038;Lo;0;L;;;;;N;;;;; +14428;ANATOLIAN HIEROGLYPH A039;Lo;0;L;;;;;N;;;;; +14429;ANATOLIAN HIEROGLYPH A039A;Lo;0;L;;;;;N;;;;; +1442A;ANATOLIAN HIEROGLYPH A040;Lo;0;L;;;;;N;;;;; +1442B;ANATOLIAN HIEROGLYPH A041;Lo;0;L;;;;;N;;;;; +1442C;ANATOLIAN HIEROGLYPH A041A;Lo;0;L;;;;;N;;;;; +1442D;ANATOLIAN HIEROGLYPH A042;Lo;0;L;;;;;N;;;;; +1442E;ANATOLIAN HIEROGLYPH A043;Lo;0;L;;;;;N;;;;; +1442F;ANATOLIAN HIEROGLYPH A044;Lo;0;L;;;;;N;;;;; +14430;ANATOLIAN HIEROGLYPH A045;Lo;0;L;;;;;N;;;;; +14431;ANATOLIAN HIEROGLYPH A045A;Lo;0;L;;;;;N;;;;; +14432;ANATOLIAN HIEROGLYPH A046;Lo;0;L;;;;;N;;;;; +14433;ANATOLIAN HIEROGLYPH A046A;Lo;0;L;;;;;N;;;;; +14434;ANATOLIAN HIEROGLYPH A046B;Lo;0;L;;;;;N;;;;; +14435;ANATOLIAN HIEROGLYPH A047;Lo;0;L;;;;;N;;;;; +14436;ANATOLIAN HIEROGLYPH A048;Lo;0;L;;;;;N;;;;; +14437;ANATOLIAN HIEROGLYPH A049;Lo;0;L;;;;;N;;;;; +14438;ANATOLIAN HIEROGLYPH A050;Lo;0;L;;;;;N;;;;; +14439;ANATOLIAN HIEROGLYPH A051;Lo;0;L;;;;;N;;;;; +1443A;ANATOLIAN HIEROGLYPH A052;Lo;0;L;;;;;N;;;;; +1443B;ANATOLIAN HIEROGLYPH A053;Lo;0;L;;;;;N;;;;; +1443C;ANATOLIAN HIEROGLYPH A054;Lo;0;L;;;;;N;;;;; +1443D;ANATOLIAN HIEROGLYPH A055;Lo;0;L;;;;;N;;;;; +1443E;ANATOLIAN HIEROGLYPH A056;Lo;0;L;;;;;N;;;;; +1443F;ANATOLIAN HIEROGLYPH A057;Lo;0;L;;;;;N;;;;; +14440;ANATOLIAN HIEROGLYPH A058;Lo;0;L;;;;;N;;;;; +14441;ANATOLIAN HIEROGLYPH A059;Lo;0;L;;;;;N;;;;; +14442;ANATOLIAN HIEROGLYPH A060;Lo;0;L;;;;;N;;;;; +14443;ANATOLIAN HIEROGLYPH A061;Lo;0;L;;;;;N;;;;; +14444;ANATOLIAN HIEROGLYPH A062;Lo;0;L;;;;;N;;;;; +14445;ANATOLIAN HIEROGLYPH A063;Lo;0;L;;;;;N;;;;; +14446;ANATOLIAN HIEROGLYPH A064;Lo;0;L;;;;;N;;;;; +14447;ANATOLIAN HIEROGLYPH A065;Lo;0;L;;;;;N;;;;; +14448;ANATOLIAN HIEROGLYPH A066;Lo;0;L;;;;;N;;;;; +14449;ANATOLIAN HIEROGLYPH A066A;Lo;0;L;;;;;N;;;;; +1444A;ANATOLIAN HIEROGLYPH A066B;Lo;0;L;;;;;N;;;;; +1444B;ANATOLIAN HIEROGLYPH A066C;Lo;0;L;;;;;N;;;;; +1444C;ANATOLIAN HIEROGLYPH A067;Lo;0;L;;;;;N;;;;; +1444D;ANATOLIAN HIEROGLYPH A068;Lo;0;L;;;;;N;;;;; +1444E;ANATOLIAN HIEROGLYPH A069;Lo;0;L;;;;;N;;;;; +1444F;ANATOLIAN HIEROGLYPH A070;Lo;0;L;;;;;N;;;;; +14450;ANATOLIAN HIEROGLYPH A071;Lo;0;L;;;;;N;;;;; +14451;ANATOLIAN HIEROGLYPH A072;Lo;0;L;;;;;N;;;;; +14452;ANATOLIAN HIEROGLYPH A073;Lo;0;L;;;;;N;;;;; +14453;ANATOLIAN HIEROGLYPH A074;Lo;0;L;;;;;N;;;;; +14454;ANATOLIAN HIEROGLYPH A075;Lo;0;L;;;;;N;;;;; +14455;ANATOLIAN HIEROGLYPH A076;Lo;0;L;;;;;N;;;;; +14456;ANATOLIAN HIEROGLYPH A077;Lo;0;L;;;;;N;;;;; +14457;ANATOLIAN HIEROGLYPH A078;Lo;0;L;;;;;N;;;;; +14458;ANATOLIAN HIEROGLYPH A079;Lo;0;L;;;;;N;;;;; +14459;ANATOLIAN HIEROGLYPH A080;Lo;0;L;;;;;N;;;;; +1445A;ANATOLIAN HIEROGLYPH A081;Lo;0;L;;;;;N;;;;; +1445B;ANATOLIAN HIEROGLYPH A082;Lo;0;L;;;;;N;;;;; +1445C;ANATOLIAN HIEROGLYPH A083;Lo;0;L;;;;;N;;;;; +1445D;ANATOLIAN HIEROGLYPH A084;Lo;0;L;;;;;N;;;;; +1445E;ANATOLIAN HIEROGLYPH A085;Lo;0;L;;;;;N;;;;; +1445F;ANATOLIAN HIEROGLYPH A086;Lo;0;L;;;;;N;;;;; +14460;ANATOLIAN HIEROGLYPH A087;Lo;0;L;;;;;N;;;;; +14461;ANATOLIAN HIEROGLYPH A088;Lo;0;L;;;;;N;;;;; +14462;ANATOLIAN HIEROGLYPH A089;Lo;0;L;;;;;N;;;;; +14463;ANATOLIAN HIEROGLYPH A090;Lo;0;L;;;;;N;;;;; +14464;ANATOLIAN HIEROGLYPH A091;Lo;0;L;;;;;N;;;;; +14465;ANATOLIAN HIEROGLYPH A092;Lo;0;L;;;;;N;;;;; +14466;ANATOLIAN HIEROGLYPH A093;Lo;0;L;;;;;N;;;;; +14467;ANATOLIAN HIEROGLYPH A094;Lo;0;L;;;;;N;;;;; +14468;ANATOLIAN HIEROGLYPH A095;Lo;0;L;;;;;N;;;;; +14469;ANATOLIAN HIEROGLYPH A096;Lo;0;L;;;;;N;;;;; +1446A;ANATOLIAN HIEROGLYPH A097;Lo;0;L;;;;;N;;;;; +1446B;ANATOLIAN HIEROGLYPH A097A;Lo;0;L;;;;;N;;;;; +1446C;ANATOLIAN HIEROGLYPH A098;Lo;0;L;;;;;N;;;;; +1446D;ANATOLIAN HIEROGLYPH A098A;Lo;0;L;;;;;N;;;;; +1446E;ANATOLIAN HIEROGLYPH A099;Lo;0;L;;;;;N;;;;; +1446F;ANATOLIAN HIEROGLYPH A100;Lo;0;L;;;;;N;;;;; +14470;ANATOLIAN HIEROGLYPH A100A;Lo;0;L;;;;;N;;;;; +14471;ANATOLIAN HIEROGLYPH A101;Lo;0;L;;;;;N;;;;; +14472;ANATOLIAN HIEROGLYPH A101A;Lo;0;L;;;;;N;;;;; +14473;ANATOLIAN HIEROGLYPH A102;Lo;0;L;;;;;N;;;;; +14474;ANATOLIAN HIEROGLYPH A102A;Lo;0;L;;;;;N;;;;; +14475;ANATOLIAN HIEROGLYPH A103;Lo;0;L;;;;;N;;;;; +14476;ANATOLIAN HIEROGLYPH A104;Lo;0;L;;;;;N;;;;; +14477;ANATOLIAN HIEROGLYPH A104A;Lo;0;L;;;;;N;;;;; +14478;ANATOLIAN HIEROGLYPH A104B;Lo;0;L;;;;;N;;;;; +14479;ANATOLIAN HIEROGLYPH A104C;Lo;0;L;;;;;N;;;;; +1447A;ANATOLIAN HIEROGLYPH A105;Lo;0;L;;;;;N;;;;; +1447B;ANATOLIAN HIEROGLYPH A105A;Lo;0;L;;;;;N;;;;; +1447C;ANATOLIAN HIEROGLYPH A105B;Lo;0;L;;;;;N;;;;; +1447D;ANATOLIAN HIEROGLYPH A106;Lo;0;L;;;;;N;;;;; +1447E;ANATOLIAN HIEROGLYPH A107;Lo;0;L;;;;;N;;;;; +1447F;ANATOLIAN HIEROGLYPH A107A;Lo;0;L;;;;;N;;;;; +14480;ANATOLIAN HIEROGLYPH A107B;Lo;0;L;;;;;N;;;;; +14481;ANATOLIAN HIEROGLYPH A107C;Lo;0;L;;;;;N;;;;; +14482;ANATOLIAN HIEROGLYPH A108;Lo;0;L;;;;;N;;;;; +14483;ANATOLIAN HIEROGLYPH A109;Lo;0;L;;;;;N;;;;; +14484;ANATOLIAN HIEROGLYPH A110;Lo;0;L;;;;;N;;;;; +14485;ANATOLIAN HIEROGLYPH A110A;Lo;0;L;;;;;N;;;;; +14486;ANATOLIAN HIEROGLYPH A110B;Lo;0;L;;;;;N;;;;; +14487;ANATOLIAN HIEROGLYPH A111;Lo;0;L;;;;;N;;;;; +14488;ANATOLIAN HIEROGLYPH A112;Lo;0;L;;;;;N;;;;; +14489;ANATOLIAN HIEROGLYPH A113;Lo;0;L;;;;;N;;;;; +1448A;ANATOLIAN HIEROGLYPH A114;Lo;0;L;;;;;N;;;;; +1448B;ANATOLIAN HIEROGLYPH A115;Lo;0;L;;;;;N;;;;; +1448C;ANATOLIAN HIEROGLYPH A115A;Lo;0;L;;;;;N;;;;; +1448D;ANATOLIAN HIEROGLYPH A116;Lo;0;L;;;;;N;;;;; +1448E;ANATOLIAN HIEROGLYPH A117;Lo;0;L;;;;;N;;;;; +1448F;ANATOLIAN HIEROGLYPH A118;Lo;0;L;;;;;N;;;;; +14490;ANATOLIAN HIEROGLYPH A119;Lo;0;L;;;;;N;;;;; +14491;ANATOLIAN HIEROGLYPH A120;Lo;0;L;;;;;N;;;;; +14492;ANATOLIAN HIEROGLYPH A121;Lo;0;L;;;;;N;;;;; +14493;ANATOLIAN HIEROGLYPH A122;Lo;0;L;;;;;N;;;;; +14494;ANATOLIAN HIEROGLYPH A123;Lo;0;L;;;;;N;;;;; +14495;ANATOLIAN HIEROGLYPH A124;Lo;0;L;;;;;N;;;;; +14496;ANATOLIAN HIEROGLYPH A125;Lo;0;L;;;;;N;;;;; +14497;ANATOLIAN HIEROGLYPH A125A;Lo;0;L;;;;;N;;;;; +14498;ANATOLIAN HIEROGLYPH A126;Lo;0;L;;;;;N;;;;; +14499;ANATOLIAN HIEROGLYPH A127;Lo;0;L;;;;;N;;;;; +1449A;ANATOLIAN HIEROGLYPH A128;Lo;0;L;;;;;N;;;;; +1449B;ANATOLIAN HIEROGLYPH A129;Lo;0;L;;;;;N;;;;; +1449C;ANATOLIAN HIEROGLYPH A130;Lo;0;L;;;;;N;;;;; +1449D;ANATOLIAN HIEROGLYPH A131;Lo;0;L;;;;;N;;;;; +1449E;ANATOLIAN HIEROGLYPH A132;Lo;0;L;;;;;N;;;;; +1449F;ANATOLIAN HIEROGLYPH A133;Lo;0;L;;;;;N;;;;; +144A0;ANATOLIAN HIEROGLYPH A134;Lo;0;L;;;;;N;;;;; +144A1;ANATOLIAN HIEROGLYPH A135;Lo;0;L;;;;;N;;;;; +144A2;ANATOLIAN HIEROGLYPH A135A;Lo;0;L;;;;;N;;;;; +144A3;ANATOLIAN HIEROGLYPH A136;Lo;0;L;;;;;N;;;;; +144A4;ANATOLIAN HIEROGLYPH A137;Lo;0;L;;;;;N;;;;; +144A5;ANATOLIAN HIEROGLYPH A138;Lo;0;L;;;;;N;;;;; +144A6;ANATOLIAN HIEROGLYPH A139;Lo;0;L;;;;;N;;;;; +144A7;ANATOLIAN HIEROGLYPH A140;Lo;0;L;;;;;N;;;;; +144A8;ANATOLIAN HIEROGLYPH A141;Lo;0;L;;;;;N;;;;; +144A9;ANATOLIAN HIEROGLYPH A142;Lo;0;L;;;;;N;;;;; +144AA;ANATOLIAN HIEROGLYPH A143;Lo;0;L;;;;;N;;;;; +144AB;ANATOLIAN HIEROGLYPH A144;Lo;0;L;;;;;N;;;;; +144AC;ANATOLIAN HIEROGLYPH A145;Lo;0;L;;;;;N;;;;; +144AD;ANATOLIAN HIEROGLYPH A146;Lo;0;L;;;;;N;;;;; +144AE;ANATOLIAN HIEROGLYPH A147;Lo;0;L;;;;;N;;;;; +144AF;ANATOLIAN HIEROGLYPH A148;Lo;0;L;;;;;N;;;;; +144B0;ANATOLIAN HIEROGLYPH A149;Lo;0;L;;;;;N;;;;; +144B1;ANATOLIAN HIEROGLYPH A150;Lo;0;L;;;;;N;;;;; +144B2;ANATOLIAN HIEROGLYPH A151;Lo;0;L;;;;;N;;;;; +144B3;ANATOLIAN HIEROGLYPH A152;Lo;0;L;;;;;N;;;;; +144B4;ANATOLIAN HIEROGLYPH A153;Lo;0;L;;;;;N;;;;; +144B5;ANATOLIAN HIEROGLYPH A154;Lo;0;L;;;;;N;;;;; +144B6;ANATOLIAN HIEROGLYPH A155;Lo;0;L;;;;;N;;;;; +144B7;ANATOLIAN HIEROGLYPH A156;Lo;0;L;;;;;N;;;;; +144B8;ANATOLIAN HIEROGLYPH A157;Lo;0;L;;;;;N;;;;; +144B9;ANATOLIAN HIEROGLYPH A158;Lo;0;L;;;;;N;;;;; +144BA;ANATOLIAN HIEROGLYPH A159;Lo;0;L;;;;;N;;;;; +144BB;ANATOLIAN HIEROGLYPH A160;Lo;0;L;;;;;N;;;;; +144BC;ANATOLIAN HIEROGLYPH A161;Lo;0;L;;;;;N;;;;; +144BD;ANATOLIAN HIEROGLYPH A162;Lo;0;L;;;;;N;;;;; +144BE;ANATOLIAN HIEROGLYPH A163;Lo;0;L;;;;;N;;;;; +144BF;ANATOLIAN HIEROGLYPH A164;Lo;0;L;;;;;N;;;;; +144C0;ANATOLIAN HIEROGLYPH A165;Lo;0;L;;;;;N;;;;; +144C1;ANATOLIAN HIEROGLYPH A166;Lo;0;L;;;;;N;;;;; +144C2;ANATOLIAN HIEROGLYPH A167;Lo;0;L;;;;;N;;;;; +144C3;ANATOLIAN HIEROGLYPH A168;Lo;0;L;;;;;N;;;;; +144C4;ANATOLIAN HIEROGLYPH A169;Lo;0;L;;;;;N;;;;; +144C5;ANATOLIAN HIEROGLYPH A170;Lo;0;L;;;;;N;;;;; +144C6;ANATOLIAN HIEROGLYPH A171;Lo;0;L;;;;;N;;;;; +144C7;ANATOLIAN HIEROGLYPH A172;Lo;0;L;;;;;N;;;;; +144C8;ANATOLIAN HIEROGLYPH A173;Lo;0;L;;;;;N;;;;; +144C9;ANATOLIAN HIEROGLYPH A174;Lo;0;L;;;;;N;;;;; +144CA;ANATOLIAN HIEROGLYPH A175;Lo;0;L;;;;;N;;;;; +144CB;ANATOLIAN HIEROGLYPH A176;Lo;0;L;;;;;N;;;;; +144CC;ANATOLIAN HIEROGLYPH A177;Lo;0;L;;;;;N;;;;; +144CD;ANATOLIAN HIEROGLYPH A178;Lo;0;L;;;;;N;;;;; +144CE;ANATOLIAN HIEROGLYPH A179;Lo;0;L;;;;;N;;;;; +144CF;ANATOLIAN HIEROGLYPH A180;Lo;0;L;;;;;N;;;;; +144D0;ANATOLIAN HIEROGLYPH A181;Lo;0;L;;;;;N;;;;; +144D1;ANATOLIAN HIEROGLYPH A182;Lo;0;L;;;;;N;;;;; +144D2;ANATOLIAN HIEROGLYPH A183;Lo;0;L;;;;;N;;;;; +144D3;ANATOLIAN HIEROGLYPH A184;Lo;0;L;;;;;N;;;;; +144D4;ANATOLIAN HIEROGLYPH A185;Lo;0;L;;;;;N;;;;; +144D5;ANATOLIAN HIEROGLYPH A186;Lo;0;L;;;;;N;;;;; +144D6;ANATOLIAN HIEROGLYPH A187;Lo;0;L;;;;;N;;;;; +144D7;ANATOLIAN HIEROGLYPH A188;Lo;0;L;;;;;N;;;;; +144D8;ANATOLIAN HIEROGLYPH A189;Lo;0;L;;;;;N;;;;; +144D9;ANATOLIAN HIEROGLYPH A190;Lo;0;L;;;;;N;;;;; +144DA;ANATOLIAN HIEROGLYPH A191;Lo;0;L;;;;;N;;;;; +144DB;ANATOLIAN HIEROGLYPH A192;Lo;0;L;;;;;N;;;;; +144DC;ANATOLIAN HIEROGLYPH A193;Lo;0;L;;;;;N;;;;; +144DD;ANATOLIAN HIEROGLYPH A194;Lo;0;L;;;;;N;;;;; +144DE;ANATOLIAN HIEROGLYPH A195;Lo;0;L;;;;;N;;;;; +144DF;ANATOLIAN HIEROGLYPH A196;Lo;0;L;;;;;N;;;;; +144E0;ANATOLIAN HIEROGLYPH A197;Lo;0;L;;;;;N;;;;; +144E1;ANATOLIAN HIEROGLYPH A198;Lo;0;L;;;;;N;;;;; +144E2;ANATOLIAN HIEROGLYPH A199;Lo;0;L;;;;;N;;;;; +144E3;ANATOLIAN HIEROGLYPH A200;Lo;0;L;;;;;N;;;;; +144E4;ANATOLIAN HIEROGLYPH A201;Lo;0;L;;;;;N;;;;; +144E5;ANATOLIAN HIEROGLYPH A202;Lo;0;L;;;;;N;;;;; +144E6;ANATOLIAN HIEROGLYPH A202A;Lo;0;L;;;;;N;;;;; +144E7;ANATOLIAN HIEROGLYPH A202B;Lo;0;L;;;;;N;;;;; +144E8;ANATOLIAN HIEROGLYPH A203;Lo;0;L;;;;;N;;;;; +144E9;ANATOLIAN HIEROGLYPH A204;Lo;0;L;;;;;N;;;;; +144EA;ANATOLIAN HIEROGLYPH A205;Lo;0;L;;;;;N;;;;; +144EB;ANATOLIAN HIEROGLYPH A206;Lo;0;L;;;;;N;;;;; +144EC;ANATOLIAN HIEROGLYPH A207;Lo;0;L;;;;;N;;;;; +144ED;ANATOLIAN HIEROGLYPH A207A;Lo;0;L;;;;;N;;;;; +144EE;ANATOLIAN HIEROGLYPH A208;Lo;0;L;;;;;N;;;;; +144EF;ANATOLIAN HIEROGLYPH A209;Lo;0;L;;;;;N;;;;; +144F0;ANATOLIAN HIEROGLYPH A209A;Lo;0;L;;;;;N;;;;; +144F1;ANATOLIAN HIEROGLYPH A210;Lo;0;L;;;;;N;;;;; +144F2;ANATOLIAN HIEROGLYPH A211;Lo;0;L;;;;;N;;;;; +144F3;ANATOLIAN HIEROGLYPH A212;Lo;0;L;;;;;N;;;;; +144F4;ANATOLIAN HIEROGLYPH A213;Lo;0;L;;;;;N;;;;; +144F5;ANATOLIAN HIEROGLYPH A214;Lo;0;L;;;;;N;;;;; +144F6;ANATOLIAN HIEROGLYPH A215;Lo;0;L;;;;;N;;;;; +144F7;ANATOLIAN HIEROGLYPH A215A;Lo;0;L;;;;;N;;;;; +144F8;ANATOLIAN HIEROGLYPH A216;Lo;0;L;;;;;N;;;;; +144F9;ANATOLIAN HIEROGLYPH A216A;Lo;0;L;;;;;N;;;;; +144FA;ANATOLIAN HIEROGLYPH A217;Lo;0;L;;;;;N;;;;; +144FB;ANATOLIAN HIEROGLYPH A218;Lo;0;L;;;;;N;;;;; +144FC;ANATOLIAN HIEROGLYPH A219;Lo;0;L;;;;;N;;;;; +144FD;ANATOLIAN HIEROGLYPH A220;Lo;0;L;;;;;N;;;;; +144FE;ANATOLIAN HIEROGLYPH A221;Lo;0;L;;;;;N;;;;; +144FF;ANATOLIAN HIEROGLYPH A222;Lo;0;L;;;;;N;;;;; +14500;ANATOLIAN HIEROGLYPH A223;Lo;0;L;;;;;N;;;;; +14501;ANATOLIAN HIEROGLYPH A224;Lo;0;L;;;;;N;;;;; +14502;ANATOLIAN HIEROGLYPH A225;Lo;0;L;;;;;N;;;;; +14503;ANATOLIAN HIEROGLYPH A226;Lo;0;L;;;;;N;;;;; +14504;ANATOLIAN HIEROGLYPH A227;Lo;0;L;;;;;N;;;;; +14505;ANATOLIAN HIEROGLYPH A227A;Lo;0;L;;;;;N;;;;; +14506;ANATOLIAN HIEROGLYPH A228;Lo;0;L;;;;;N;;;;; +14507;ANATOLIAN HIEROGLYPH A229;Lo;0;L;;;;;N;;;;; +14508;ANATOLIAN HIEROGLYPH A230;Lo;0;L;;;;;N;;;;; +14509;ANATOLIAN HIEROGLYPH A231;Lo;0;L;;;;;N;;;;; +1450A;ANATOLIAN HIEROGLYPH A232;Lo;0;L;;;;;N;;;;; +1450B;ANATOLIAN HIEROGLYPH A233;Lo;0;L;;;;;N;;;;; +1450C;ANATOLIAN HIEROGLYPH A234;Lo;0;L;;;;;N;;;;; +1450D;ANATOLIAN HIEROGLYPH A235;Lo;0;L;;;;;N;;;;; +1450E;ANATOLIAN HIEROGLYPH A236;Lo;0;L;;;;;N;;;;; +1450F;ANATOLIAN HIEROGLYPH A237;Lo;0;L;;;;;N;;;;; +14510;ANATOLIAN HIEROGLYPH A238;Lo;0;L;;;;;N;;;;; +14511;ANATOLIAN HIEROGLYPH A239;Lo;0;L;;;;;N;;;;; +14512;ANATOLIAN HIEROGLYPH A240;Lo;0;L;;;;;N;;;;; +14513;ANATOLIAN HIEROGLYPH A241;Lo;0;L;;;;;N;;;;; +14514;ANATOLIAN HIEROGLYPH A242;Lo;0;L;;;;;N;;;;; +14515;ANATOLIAN HIEROGLYPH A243;Lo;0;L;;;;;N;;;;; +14516;ANATOLIAN HIEROGLYPH A244;Lo;0;L;;;;;N;;;;; +14517;ANATOLIAN HIEROGLYPH A245;Lo;0;L;;;;;N;;;;; +14518;ANATOLIAN HIEROGLYPH A246;Lo;0;L;;;;;N;;;;; +14519;ANATOLIAN HIEROGLYPH A247;Lo;0;L;;;;;N;;;;; +1451A;ANATOLIAN HIEROGLYPH A248;Lo;0;L;;;;;N;;;;; +1451B;ANATOLIAN HIEROGLYPH A249;Lo;0;L;;;;;N;;;;; +1451C;ANATOLIAN HIEROGLYPH A250;Lo;0;L;;;;;N;;;;; +1451D;ANATOLIAN HIEROGLYPH A251;Lo;0;L;;;;;N;;;;; +1451E;ANATOLIAN HIEROGLYPH A252;Lo;0;L;;;;;N;;;;; +1451F;ANATOLIAN HIEROGLYPH A253;Lo;0;L;;;;;N;;;;; +14520;ANATOLIAN HIEROGLYPH A254;Lo;0;L;;;;;N;;;;; +14521;ANATOLIAN HIEROGLYPH A255;Lo;0;L;;;;;N;;;;; +14522;ANATOLIAN HIEROGLYPH A256;Lo;0;L;;;;;N;;;;; +14523;ANATOLIAN HIEROGLYPH A257;Lo;0;L;;;;;N;;;;; +14524;ANATOLIAN HIEROGLYPH A258;Lo;0;L;;;;;N;;;;; +14525;ANATOLIAN HIEROGLYPH A259;Lo;0;L;;;;;N;;;;; +14526;ANATOLIAN HIEROGLYPH A260;Lo;0;L;;;;;N;;;;; +14527;ANATOLIAN HIEROGLYPH A261;Lo;0;L;;;;;N;;;;; +14528;ANATOLIAN HIEROGLYPH A262;Lo;0;L;;;;;N;;;;; +14529;ANATOLIAN HIEROGLYPH A263;Lo;0;L;;;;;N;;;;; +1452A;ANATOLIAN HIEROGLYPH A264;Lo;0;L;;;;;N;;;;; +1452B;ANATOLIAN HIEROGLYPH A265;Lo;0;L;;;;;N;;;;; +1452C;ANATOLIAN HIEROGLYPH A266;Lo;0;L;;;;;N;;;;; +1452D;ANATOLIAN HIEROGLYPH A267;Lo;0;L;;;;;N;;;;; +1452E;ANATOLIAN HIEROGLYPH A267A;Lo;0;L;;;;;N;;;;; +1452F;ANATOLIAN HIEROGLYPH A268;Lo;0;L;;;;;N;;;;; +14530;ANATOLIAN HIEROGLYPH A269;Lo;0;L;;;;;N;;;;; +14531;ANATOLIAN HIEROGLYPH A270;Lo;0;L;;;;;N;;;;; +14532;ANATOLIAN HIEROGLYPH A271;Lo;0;L;;;;;N;;;;; +14533;ANATOLIAN HIEROGLYPH A272;Lo;0;L;;;;;N;;;;; +14534;ANATOLIAN HIEROGLYPH A273;Lo;0;L;;;;;N;;;;; +14535;ANATOLIAN HIEROGLYPH A274;Lo;0;L;;;;;N;;;;; +14536;ANATOLIAN HIEROGLYPH A275;Lo;0;L;;;;;N;;;;; +14537;ANATOLIAN HIEROGLYPH A276;Lo;0;L;;;;;N;;;;; +14538;ANATOLIAN HIEROGLYPH A277;Lo;0;L;;;;;N;;;;; +14539;ANATOLIAN HIEROGLYPH A278;Lo;0;L;;;;;N;;;;; +1453A;ANATOLIAN HIEROGLYPH A279;Lo;0;L;;;;;N;;;;; +1453B;ANATOLIAN HIEROGLYPH A280;Lo;0;L;;;;;N;;;;; +1453C;ANATOLIAN HIEROGLYPH A281;Lo;0;L;;;;;N;;;;; +1453D;ANATOLIAN HIEROGLYPH A282;Lo;0;L;;;;;N;;;;; +1453E;ANATOLIAN HIEROGLYPH A283;Lo;0;L;;;;;N;;;;; +1453F;ANATOLIAN HIEROGLYPH A284;Lo;0;L;;;;;N;;;;; +14540;ANATOLIAN HIEROGLYPH A285;Lo;0;L;;;;;N;;;;; +14541;ANATOLIAN HIEROGLYPH A286;Lo;0;L;;;;;N;;;;; +14542;ANATOLIAN HIEROGLYPH A287;Lo;0;L;;;;;N;;;;; +14543;ANATOLIAN HIEROGLYPH A288;Lo;0;L;;;;;N;;;;; +14544;ANATOLIAN HIEROGLYPH A289;Lo;0;L;;;;;N;;;;; +14545;ANATOLIAN HIEROGLYPH A289A;Lo;0;L;;;;;N;;;;; +14546;ANATOLIAN HIEROGLYPH A290;Lo;0;L;;;;;N;;;;; +14547;ANATOLIAN HIEROGLYPH A291;Lo;0;L;;;;;N;;;;; +14548;ANATOLIAN HIEROGLYPH A292;Lo;0;L;;;;;N;;;;; +14549;ANATOLIAN HIEROGLYPH A293;Lo;0;L;;;;;N;;;;; +1454A;ANATOLIAN HIEROGLYPH A294;Lo;0;L;;;;;N;;;;; +1454B;ANATOLIAN HIEROGLYPH A294A;Lo;0;L;;;;;N;;;;; +1454C;ANATOLIAN HIEROGLYPH A295;Lo;0;L;;;;;N;;;;; +1454D;ANATOLIAN HIEROGLYPH A296;Lo;0;L;;;;;N;;;;; +1454E;ANATOLIAN HIEROGLYPH A297;Lo;0;L;;;;;N;;;;; +1454F;ANATOLIAN HIEROGLYPH A298;Lo;0;L;;;;;N;;;;; +14550;ANATOLIAN HIEROGLYPH A299;Lo;0;L;;;;;N;;;;; +14551;ANATOLIAN HIEROGLYPH A299A;Lo;0;L;;;;;N;;;;; +14552;ANATOLIAN HIEROGLYPH A300;Lo;0;L;;;;;N;;;;; +14553;ANATOLIAN HIEROGLYPH A301;Lo;0;L;;;;;N;;;;; +14554;ANATOLIAN HIEROGLYPH A302;Lo;0;L;;;;;N;;;;; +14555;ANATOLIAN HIEROGLYPH A303;Lo;0;L;;;;;N;;;;; +14556;ANATOLIAN HIEROGLYPH A304;Lo;0;L;;;;;N;;;;; +14557;ANATOLIAN HIEROGLYPH A305;Lo;0;L;;;;;N;;;;; +14558;ANATOLIAN HIEROGLYPH A306;Lo;0;L;;;;;N;;;;; +14559;ANATOLIAN HIEROGLYPH A307;Lo;0;L;;;;;N;;;;; +1455A;ANATOLIAN HIEROGLYPH A308;Lo;0;L;;;;;N;;;;; +1455B;ANATOLIAN HIEROGLYPH A309;Lo;0;L;;;;;N;;;;; +1455C;ANATOLIAN HIEROGLYPH A309A;Lo;0;L;;;;;N;;;;; +1455D;ANATOLIAN HIEROGLYPH A310;Lo;0;L;;;;;N;;;;; +1455E;ANATOLIAN HIEROGLYPH A311;Lo;0;L;;;;;N;;;;; +1455F;ANATOLIAN HIEROGLYPH A312;Lo;0;L;;;;;N;;;;; +14560;ANATOLIAN HIEROGLYPH A313;Lo;0;L;;;;;N;;;;; +14561;ANATOLIAN HIEROGLYPH A314;Lo;0;L;;;;;N;;;;; +14562;ANATOLIAN HIEROGLYPH A315;Lo;0;L;;;;;N;;;;; +14563;ANATOLIAN HIEROGLYPH A316;Lo;0;L;;;;;N;;;;; +14564;ANATOLIAN HIEROGLYPH A317;Lo;0;L;;;;;N;;;;; +14565;ANATOLIAN HIEROGLYPH A318;Lo;0;L;;;;;N;;;;; +14566;ANATOLIAN HIEROGLYPH A319;Lo;0;L;;;;;N;;;;; +14567;ANATOLIAN HIEROGLYPH A320;Lo;0;L;;;;;N;;;;; +14568;ANATOLIAN HIEROGLYPH A321;Lo;0;L;;;;;N;;;;; +14569;ANATOLIAN HIEROGLYPH A322;Lo;0;L;;;;;N;;;;; +1456A;ANATOLIAN HIEROGLYPH A323;Lo;0;L;;;;;N;;;;; +1456B;ANATOLIAN HIEROGLYPH A324;Lo;0;L;;;;;N;;;;; +1456C;ANATOLIAN HIEROGLYPH A325;Lo;0;L;;;;;N;;;;; +1456D;ANATOLIAN HIEROGLYPH A326;Lo;0;L;;;;;N;;;;; +1456E;ANATOLIAN HIEROGLYPH A327;Lo;0;L;;;;;N;;;;; +1456F;ANATOLIAN HIEROGLYPH A328;Lo;0;L;;;;;N;;;;; +14570;ANATOLIAN HIEROGLYPH A329;Lo;0;L;;;;;N;;;;; +14571;ANATOLIAN HIEROGLYPH A329A;Lo;0;L;;;;;N;;;;; +14572;ANATOLIAN HIEROGLYPH A330;Lo;0;L;;;;;N;;;;; +14573;ANATOLIAN HIEROGLYPH A331;Lo;0;L;;;;;N;;;;; +14574;ANATOLIAN HIEROGLYPH A332A;Lo;0;L;;;;;N;;;;; +14575;ANATOLIAN HIEROGLYPH A332B;Lo;0;L;;;;;N;;;;; +14576;ANATOLIAN HIEROGLYPH A332C;Lo;0;L;;;;;N;;;;; +14577;ANATOLIAN HIEROGLYPH A333;Lo;0;L;;;;;N;;;;; +14578;ANATOLIAN HIEROGLYPH A334;Lo;0;L;;;;;N;;;;; +14579;ANATOLIAN HIEROGLYPH A335;Lo;0;L;;;;;N;;;;; +1457A;ANATOLIAN HIEROGLYPH A336;Lo;0;L;;;;;N;;;;; +1457B;ANATOLIAN HIEROGLYPH A336A;Lo;0;L;;;;;N;;;;; +1457C;ANATOLIAN HIEROGLYPH A336B;Lo;0;L;;;;;N;;;;; +1457D;ANATOLIAN HIEROGLYPH A336C;Lo;0;L;;;;;N;;;;; +1457E;ANATOLIAN HIEROGLYPH A337;Lo;0;L;;;;;N;;;;; +1457F;ANATOLIAN HIEROGLYPH A338;Lo;0;L;;;;;N;;;;; +14580;ANATOLIAN HIEROGLYPH A339;Lo;0;L;;;;;N;;;;; +14581;ANATOLIAN HIEROGLYPH A340;Lo;0;L;;;;;N;;;;; +14582;ANATOLIAN HIEROGLYPH A341;Lo;0;L;;;;;N;;;;; +14583;ANATOLIAN HIEROGLYPH A342;Lo;0;L;;;;;N;;;;; +14584;ANATOLIAN HIEROGLYPH A343;Lo;0;L;;;;;N;;;;; +14585;ANATOLIAN HIEROGLYPH A344;Lo;0;L;;;;;N;;;;; +14586;ANATOLIAN HIEROGLYPH A345;Lo;0;L;;;;;N;;;;; +14587;ANATOLIAN HIEROGLYPH A346;Lo;0;L;;;;;N;;;;; +14588;ANATOLIAN HIEROGLYPH A347;Lo;0;L;;;;;N;;;;; +14589;ANATOLIAN HIEROGLYPH A348;Lo;0;L;;;;;N;;;;; +1458A;ANATOLIAN HIEROGLYPH A349;Lo;0;L;;;;;N;;;;; +1458B;ANATOLIAN HIEROGLYPH A350;Lo;0;L;;;;;N;;;;; +1458C;ANATOLIAN HIEROGLYPH A351;Lo;0;L;;;;;N;;;;; +1458D;ANATOLIAN HIEROGLYPH A352;Lo;0;L;;;;;N;;;;; +1458E;ANATOLIAN HIEROGLYPH A353;Lo;0;L;;;;;N;;;;; +1458F;ANATOLIAN HIEROGLYPH A354;Lo;0;L;;;;;N;;;;; +14590;ANATOLIAN HIEROGLYPH A355;Lo;0;L;;;;;N;;;;; +14591;ANATOLIAN HIEROGLYPH A356;Lo;0;L;;;;;N;;;;; +14592;ANATOLIAN HIEROGLYPH A357;Lo;0;L;;;;;N;;;;; +14593;ANATOLIAN HIEROGLYPH A358;Lo;0;L;;;;;N;;;;; +14594;ANATOLIAN HIEROGLYPH A359;Lo;0;L;;;;;N;;;;; +14595;ANATOLIAN HIEROGLYPH A359A;Lo;0;L;;;;;N;;;;; +14596;ANATOLIAN HIEROGLYPH A360;Lo;0;L;;;;;N;;;;; +14597;ANATOLIAN HIEROGLYPH A361;Lo;0;L;;;;;N;;;;; +14598;ANATOLIAN HIEROGLYPH A362;Lo;0;L;;;;;N;;;;; +14599;ANATOLIAN HIEROGLYPH A363;Lo;0;L;;;;;N;;;;; +1459A;ANATOLIAN HIEROGLYPH A364;Lo;0;L;;;;;N;;;;; +1459B;ANATOLIAN HIEROGLYPH A364A;Lo;0;L;;;;;N;;;;; +1459C;ANATOLIAN HIEROGLYPH A365;Lo;0;L;;;;;N;;;;; +1459D;ANATOLIAN HIEROGLYPH A366;Lo;0;L;;;;;N;;;;; +1459E;ANATOLIAN HIEROGLYPH A367;Lo;0;L;;;;;N;;;;; +1459F;ANATOLIAN HIEROGLYPH A368;Lo;0;L;;;;;N;;;;; +145A0;ANATOLIAN HIEROGLYPH A368A;Lo;0;L;;;;;N;;;;; +145A1;ANATOLIAN HIEROGLYPH A369;Lo;0;L;;;;;N;;;;; +145A2;ANATOLIAN HIEROGLYPH A370;Lo;0;L;;;;;N;;;;; +145A3;ANATOLIAN HIEROGLYPH A371;Lo;0;L;;;;;N;;;;; +145A4;ANATOLIAN HIEROGLYPH A371A;Lo;0;L;;;;;N;;;;; +145A5;ANATOLIAN HIEROGLYPH A372;Lo;0;L;;;;;N;;;;; +145A6;ANATOLIAN HIEROGLYPH A373;Lo;0;L;;;;;N;;;;; +145A7;ANATOLIAN HIEROGLYPH A374;Lo;0;L;;;;;N;;;;; +145A8;ANATOLIAN HIEROGLYPH A375;Lo;0;L;;;;;N;;;;; +145A9;ANATOLIAN HIEROGLYPH A376;Lo;0;L;;;;;N;;;;; +145AA;ANATOLIAN HIEROGLYPH A377;Lo;0;L;;;;;N;;;;; +145AB;ANATOLIAN HIEROGLYPH A378;Lo;0;L;;;;;N;;;;; +145AC;ANATOLIAN HIEROGLYPH A379;Lo;0;L;;;;;N;;;;; +145AD;ANATOLIAN HIEROGLYPH A380;Lo;0;L;;;;;N;;;;; +145AE;ANATOLIAN HIEROGLYPH A381;Lo;0;L;;;;;N;;;;; +145AF;ANATOLIAN HIEROGLYPH A381A;Lo;0;L;;;;;N;;;;; +145B0;ANATOLIAN HIEROGLYPH A382;Lo;0;L;;;;;N;;;;; +145B1;ANATOLIAN HIEROGLYPH A383 RA OR RI;Lo;0;L;;;;;N;;;;; +145B2;ANATOLIAN HIEROGLYPH A383A;Lo;0;L;;;;;N;;;;; +145B3;ANATOLIAN HIEROGLYPH A384;Lo;0;L;;;;;N;;;;; +145B4;ANATOLIAN HIEROGLYPH A385;Lo;0;L;;;;;N;;;;; +145B5;ANATOLIAN HIEROGLYPH A386;Lo;0;L;;;;;N;;;;; +145B6;ANATOLIAN HIEROGLYPH A386A;Lo;0;L;;;;;N;;;;; +145B7;ANATOLIAN HIEROGLYPH A387;Lo;0;L;;;;;N;;;;; +145B8;ANATOLIAN HIEROGLYPH A388;Lo;0;L;;;;;N;;;;; +145B9;ANATOLIAN HIEROGLYPH A389;Lo;0;L;;;;;N;;;;; +145BA;ANATOLIAN HIEROGLYPH A390;Lo;0;L;;;;;N;;;;; +145BB;ANATOLIAN HIEROGLYPH A391;Lo;0;L;;;;;N;;;;; +145BC;ANATOLIAN HIEROGLYPH A392;Lo;0;L;;;;;N;;;;; +145BD;ANATOLIAN HIEROGLYPH A393 EIGHT;Lo;0;L;;;;;N;;;;; +145BE;ANATOLIAN HIEROGLYPH A394;Lo;0;L;;;;;N;;;;; +145BF;ANATOLIAN HIEROGLYPH A395;Lo;0;L;;;;;N;;;;; +145C0;ANATOLIAN HIEROGLYPH A396;Lo;0;L;;;;;N;;;;; +145C1;ANATOLIAN HIEROGLYPH A397;Lo;0;L;;;;;N;;;;; +145C2;ANATOLIAN HIEROGLYPH A398;Lo;0;L;;;;;N;;;;; +145C3;ANATOLIAN HIEROGLYPH A399;Lo;0;L;;;;;N;;;;; +145C4;ANATOLIAN HIEROGLYPH A400;Lo;0;L;;;;;N;;;;; +145C5;ANATOLIAN HIEROGLYPH A401;Lo;0;L;;;;;N;;;;; +145C6;ANATOLIAN HIEROGLYPH A402;Lo;0;L;;;;;N;;;;; +145C7;ANATOLIAN HIEROGLYPH A403;Lo;0;L;;;;;N;;;;; +145C8;ANATOLIAN HIEROGLYPH A404;Lo;0;L;;;;;N;;;;; +145C9;ANATOLIAN HIEROGLYPH A405;Lo;0;L;;;;;N;;;;; +145CA;ANATOLIAN HIEROGLYPH A406;Lo;0;L;;;;;N;;;;; +145CB;ANATOLIAN HIEROGLYPH A407;Lo;0;L;;;;;N;;;;; +145CC;ANATOLIAN HIEROGLYPH A408;Lo;0;L;;;;;N;;;;; +145CD;ANATOLIAN HIEROGLYPH A409;Lo;0;L;;;;;N;;;;; +145CE;ANATOLIAN HIEROGLYPH A410 BEGIN LOGOGRAM MARK;Lo;0;L;;;;;N;;;;; +145CF;ANATOLIAN HIEROGLYPH A410A END LOGOGRAM MARK;Lo;0;L;;;;;N;;;;; +145D0;ANATOLIAN HIEROGLYPH A411;Lo;0;L;;;;;N;;;;; +145D1;ANATOLIAN HIEROGLYPH A412;Lo;0;L;;;;;N;;;;; +145D2;ANATOLIAN HIEROGLYPH A413;Lo;0;L;;;;;N;;;;; +145D3;ANATOLIAN HIEROGLYPH A414;Lo;0;L;;;;;N;;;;; +145D4;ANATOLIAN HIEROGLYPH A415;Lo;0;L;;;;;N;;;;; +145D5;ANATOLIAN HIEROGLYPH A416;Lo;0;L;;;;;N;;;;; +145D6;ANATOLIAN HIEROGLYPH A417;Lo;0;L;;;;;N;;;;; +145D7;ANATOLIAN HIEROGLYPH A418;Lo;0;L;;;;;N;;;;; +145D8;ANATOLIAN HIEROGLYPH A419;Lo;0;L;;;;;N;;;;; +145D9;ANATOLIAN HIEROGLYPH A420;Lo;0;L;;;;;N;;;;; +145DA;ANATOLIAN HIEROGLYPH A421;Lo;0;L;;;;;N;;;;; +145DB;ANATOLIAN HIEROGLYPH A422;Lo;0;L;;;;;N;;;;; +145DC;ANATOLIAN HIEROGLYPH A423;Lo;0;L;;;;;N;;;;; +145DD;ANATOLIAN HIEROGLYPH A424;Lo;0;L;;;;;N;;;;; +145DE;ANATOLIAN HIEROGLYPH A425;Lo;0;L;;;;;N;;;;; +145DF;ANATOLIAN HIEROGLYPH A426;Lo;0;L;;;;;N;;;;; +145E0;ANATOLIAN HIEROGLYPH A427;Lo;0;L;;;;;N;;;;; +145E1;ANATOLIAN HIEROGLYPH A428;Lo;0;L;;;;;N;;;;; +145E2;ANATOLIAN HIEROGLYPH A429;Lo;0;L;;;;;N;;;;; +145E3;ANATOLIAN HIEROGLYPH A430;Lo;0;L;;;;;N;;;;; +145E4;ANATOLIAN HIEROGLYPH A431;Lo;0;L;;;;;N;;;;; +145E5;ANATOLIAN HIEROGLYPH A432;Lo;0;L;;;;;N;;;;; +145E6;ANATOLIAN HIEROGLYPH A433;Lo;0;L;;;;;N;;;;; +145E7;ANATOLIAN HIEROGLYPH A434;Lo;0;L;;;;;N;;;;; +145E8;ANATOLIAN HIEROGLYPH A435;Lo;0;L;;;;;N;;;;; +145E9;ANATOLIAN HIEROGLYPH A436;Lo;0;L;;;;;N;;;;; +145EA;ANATOLIAN HIEROGLYPH A437;Lo;0;L;;;;;N;;;;; +145EB;ANATOLIAN HIEROGLYPH A438;Lo;0;L;;;;;N;;;;; +145EC;ANATOLIAN HIEROGLYPH A439;Lo;0;L;;;;;N;;;;; +145ED;ANATOLIAN HIEROGLYPH A440;Lo;0;L;;;;;N;;;;; +145EE;ANATOLIAN HIEROGLYPH A441;Lo;0;L;;;;;N;;;;; +145EF;ANATOLIAN HIEROGLYPH A442;Lo;0;L;;;;;N;;;;; +145F0;ANATOLIAN HIEROGLYPH A443;Lo;0;L;;;;;N;;;;; +145F1;ANATOLIAN HIEROGLYPH A444;Lo;0;L;;;;;N;;;;; +145F2;ANATOLIAN HIEROGLYPH A445;Lo;0;L;;;;;N;;;;; +145F3;ANATOLIAN HIEROGLYPH A446;Lo;0;L;;;;;N;;;;; +145F4;ANATOLIAN HIEROGLYPH A447;Lo;0;L;;;;;N;;;;; +145F5;ANATOLIAN HIEROGLYPH A448;Lo;0;L;;;;;N;;;;; +145F6;ANATOLIAN HIEROGLYPH A449;Lo;0;L;;;;;N;;;;; +145F7;ANATOLIAN HIEROGLYPH A450;Lo;0;L;;;;;N;;;;; +145F8;ANATOLIAN HIEROGLYPH A450A;Lo;0;L;;;;;N;;;;; +145F9;ANATOLIAN HIEROGLYPH A451;Lo;0;L;;;;;N;;;;; +145FA;ANATOLIAN HIEROGLYPH A452;Lo;0;L;;;;;N;;;;; +145FB;ANATOLIAN HIEROGLYPH A453;Lo;0;L;;;;;N;;;;; +145FC;ANATOLIAN HIEROGLYPH A454;Lo;0;L;;;;;N;;;;; +145FD;ANATOLIAN HIEROGLYPH A455;Lo;0;L;;;;;N;;;;; +145FE;ANATOLIAN HIEROGLYPH A456;Lo;0;L;;;;;N;;;;; +145FF;ANATOLIAN HIEROGLYPH A457;Lo;0;L;;;;;N;;;;; +14600;ANATOLIAN HIEROGLYPH A457A;Lo;0;L;;;;;N;;;;; +14601;ANATOLIAN HIEROGLYPH A458;Lo;0;L;;;;;N;;;;; +14602;ANATOLIAN HIEROGLYPH A459;Lo;0;L;;;;;N;;;;; +14603;ANATOLIAN HIEROGLYPH A460;Lo;0;L;;;;;N;;;;; +14604;ANATOLIAN HIEROGLYPH A461;Lo;0;L;;;;;N;;;;; +14605;ANATOLIAN HIEROGLYPH A462;Lo;0;L;;;;;N;;;;; +14606;ANATOLIAN HIEROGLYPH A463;Lo;0;L;;;;;N;;;;; +14607;ANATOLIAN HIEROGLYPH A464;Lo;0;L;;;;;N;;;;; +14608;ANATOLIAN HIEROGLYPH A465;Lo;0;L;;;;;N;;;;; +14609;ANATOLIAN HIEROGLYPH A466;Lo;0;L;;;;;N;;;;; +1460A;ANATOLIAN HIEROGLYPH A467;Lo;0;L;;;;;N;;;;; +1460B;ANATOLIAN HIEROGLYPH A468;Lo;0;L;;;;;N;;;;; +1460C;ANATOLIAN HIEROGLYPH A469;Lo;0;L;;;;;N;;;;; +1460D;ANATOLIAN HIEROGLYPH A470;Lo;0;L;;;;;N;;;;; +1460E;ANATOLIAN HIEROGLYPH A471;Lo;0;L;;;;;N;;;;; +1460F;ANATOLIAN HIEROGLYPH A472;Lo;0;L;;;;;N;;;;; +14610;ANATOLIAN HIEROGLYPH A473;Lo;0;L;;;;;N;;;;; +14611;ANATOLIAN HIEROGLYPH A474;Lo;0;L;;;;;N;;;;; +14612;ANATOLIAN HIEROGLYPH A475;Lo;0;L;;;;;N;;;;; +14613;ANATOLIAN HIEROGLYPH A476;Lo;0;L;;;;;N;;;;; +14614;ANATOLIAN HIEROGLYPH A477;Lo;0;L;;;;;N;;;;; +14615;ANATOLIAN HIEROGLYPH A478;Lo;0;L;;;;;N;;;;; +14616;ANATOLIAN HIEROGLYPH A479;Lo;0;L;;;;;N;;;;; +14617;ANATOLIAN HIEROGLYPH A480;Lo;0;L;;;;;N;;;;; +14618;ANATOLIAN HIEROGLYPH A481;Lo;0;L;;;;;N;;;;; +14619;ANATOLIAN HIEROGLYPH A482;Lo;0;L;;;;;N;;;;; +1461A;ANATOLIAN HIEROGLYPH A483;Lo;0;L;;;;;N;;;;; +1461B;ANATOLIAN HIEROGLYPH A484;Lo;0;L;;;;;N;;;;; +1461C;ANATOLIAN HIEROGLYPH A485;Lo;0;L;;;;;N;;;;; +1461D;ANATOLIAN HIEROGLYPH A486;Lo;0;L;;;;;N;;;;; +1461E;ANATOLIAN HIEROGLYPH A487;Lo;0;L;;;;;N;;;;; +1461F;ANATOLIAN HIEROGLYPH A488;Lo;0;L;;;;;N;;;;; +14620;ANATOLIAN HIEROGLYPH A489;Lo;0;L;;;;;N;;;;; +14621;ANATOLIAN HIEROGLYPH A490;Lo;0;L;;;;;N;;;;; +14622;ANATOLIAN HIEROGLYPH A491;Lo;0;L;;;;;N;;;;; +14623;ANATOLIAN HIEROGLYPH A492;Lo;0;L;;;;;N;;;;; +14624;ANATOLIAN HIEROGLYPH A493;Lo;0;L;;;;;N;;;;; +14625;ANATOLIAN HIEROGLYPH A494;Lo;0;L;;;;;N;;;;; +14626;ANATOLIAN HIEROGLYPH A495;Lo;0;L;;;;;N;;;;; +14627;ANATOLIAN HIEROGLYPH A496;Lo;0;L;;;;;N;;;;; +14628;ANATOLIAN HIEROGLYPH A497;Lo;0;L;;;;;N;;;;; +14629;ANATOLIAN HIEROGLYPH A501;Lo;0;L;;;;;N;;;;; +1462A;ANATOLIAN HIEROGLYPH A502;Lo;0;L;;;;;N;;;;; +1462B;ANATOLIAN HIEROGLYPH A503;Lo;0;L;;;;;N;;;;; +1462C;ANATOLIAN HIEROGLYPH A504;Lo;0;L;;;;;N;;;;; +1462D;ANATOLIAN HIEROGLYPH A505;Lo;0;L;;;;;N;;;;; +1462E;ANATOLIAN HIEROGLYPH A506;Lo;0;L;;;;;N;;;;; +1462F;ANATOLIAN HIEROGLYPH A507;Lo;0;L;;;;;N;;;;; +14630;ANATOLIAN HIEROGLYPH A508;Lo;0;L;;;;;N;;;;; +14631;ANATOLIAN HIEROGLYPH A509;Lo;0;L;;;;;N;;;;; +14632;ANATOLIAN HIEROGLYPH A510;Lo;0;L;;;;;N;;;;; +14633;ANATOLIAN HIEROGLYPH A511;Lo;0;L;;;;;N;;;;; +14634;ANATOLIAN HIEROGLYPH A512;Lo;0;L;;;;;N;;;;; +14635;ANATOLIAN HIEROGLYPH A513;Lo;0;L;;;;;N;;;;; +14636;ANATOLIAN HIEROGLYPH A514;Lo;0;L;;;;;N;;;;; +14637;ANATOLIAN HIEROGLYPH A515;Lo;0;L;;;;;N;;;;; +14638;ANATOLIAN HIEROGLYPH A516;Lo;0;L;;;;;N;;;;; +14639;ANATOLIAN HIEROGLYPH A517;Lo;0;L;;;;;N;;;;; +1463A;ANATOLIAN HIEROGLYPH A518;Lo;0;L;;;;;N;;;;; +1463B;ANATOLIAN HIEROGLYPH A519;Lo;0;L;;;;;N;;;;; +1463C;ANATOLIAN HIEROGLYPH A520;Lo;0;L;;;;;N;;;;; +1463D;ANATOLIAN HIEROGLYPH A521;Lo;0;L;;;;;N;;;;; +1463E;ANATOLIAN HIEROGLYPH A522;Lo;0;L;;;;;N;;;;; +1463F;ANATOLIAN HIEROGLYPH A523;Lo;0;L;;;;;N;;;;; +14640;ANATOLIAN HIEROGLYPH A524;Lo;0;L;;;;;N;;;;; +14641;ANATOLIAN HIEROGLYPH A525;Lo;0;L;;;;;N;;;;; +14642;ANATOLIAN HIEROGLYPH A526;Lo;0;L;;;;;N;;;;; +14643;ANATOLIAN HIEROGLYPH A527;Lo;0;L;;;;;N;;;;; +14644;ANATOLIAN HIEROGLYPH A528;Lo;0;L;;;;;N;;;;; +14645;ANATOLIAN HIEROGLYPH A529;Lo;0;L;;;;;N;;;;; +14646;ANATOLIAN HIEROGLYPH A530;Lo;0;L;;;;;N;;;;; +16800;BAMUM LETTER PHASE-A NGKUE MFON;Lo;0;L;;;;;N;;;;; +16801;BAMUM LETTER PHASE-A GBIEE FON;Lo;0;L;;;;;N;;;;; +16802;BAMUM LETTER PHASE-A PON MFON PIPAEMGBIEE;Lo;0;L;;;;;N;;;;; +16803;BAMUM LETTER PHASE-A PON MFON PIPAEMBA;Lo;0;L;;;;;N;;;;; +16804;BAMUM LETTER PHASE-A NAA MFON;Lo;0;L;;;;;N;;;;; +16805;BAMUM LETTER PHASE-A SHUENSHUET;Lo;0;L;;;;;N;;;;; +16806;BAMUM LETTER PHASE-A TITA MFON;Lo;0;L;;;;;N;;;;; +16807;BAMUM LETTER PHASE-A NZA MFON;Lo;0;L;;;;;N;;;;; +16808;BAMUM LETTER PHASE-A SHINDA PA NJI;Lo;0;L;;;;;N;;;;; +16809;BAMUM LETTER PHASE-A PON PA NJI PIPAEMGBIEE;Lo;0;L;;;;;N;;;;; +1680A;BAMUM LETTER PHASE-A PON PA NJI PIPAEMBA;Lo;0;L;;;;;N;;;;; +1680B;BAMUM LETTER PHASE-A MAEMBGBIEE;Lo;0;L;;;;;N;;;;; +1680C;BAMUM LETTER PHASE-A TU MAEMBA;Lo;0;L;;;;;N;;;;; +1680D;BAMUM LETTER PHASE-A NGANGU;Lo;0;L;;;;;N;;;;; +1680E;BAMUM LETTER PHASE-A MAEMVEUX;Lo;0;L;;;;;N;;;;; +1680F;BAMUM LETTER PHASE-A MANSUAE;Lo;0;L;;;;;N;;;;; +16810;BAMUM LETTER PHASE-A MVEUAENGAM;Lo;0;L;;;;;N;;;;; +16811;BAMUM LETTER PHASE-A SEUNYAM;Lo;0;L;;;;;N;;;;; +16812;BAMUM LETTER PHASE-A NTOQPEN;Lo;0;L;;;;;N;;;;; +16813;BAMUM LETTER PHASE-A KEUKEUTNDA;Lo;0;L;;;;;N;;;;; +16814;BAMUM LETTER PHASE-A NKINDI;Lo;0;L;;;;;N;;;;; +16815;BAMUM LETTER PHASE-A SUU;Lo;0;L;;;;;N;;;;; +16816;BAMUM LETTER PHASE-A NGKUENZEUM;Lo;0;L;;;;;N;;;;; +16817;BAMUM LETTER PHASE-A LAPAQ;Lo;0;L;;;;;N;;;;; +16818;BAMUM LETTER PHASE-A LET KUT;Lo;0;L;;;;;N;;;;; +16819;BAMUM LETTER PHASE-A NTAP MFAA;Lo;0;L;;;;;N;;;;; +1681A;BAMUM LETTER PHASE-A MAEKEUP;Lo;0;L;;;;;N;;;;; +1681B;BAMUM LETTER PHASE-A PASHAE;Lo;0;L;;;;;N;;;;; +1681C;BAMUM LETTER PHASE-A GHEUAERAE;Lo;0;L;;;;;N;;;;; +1681D;BAMUM LETTER PHASE-A PAMSHAE;Lo;0;L;;;;;N;;;;; +1681E;BAMUM LETTER PHASE-A MON NGGEUAET;Lo;0;L;;;;;N;;;;; +1681F;BAMUM LETTER PHASE-A NZUN MEUT;Lo;0;L;;;;;N;;;;; +16820;BAMUM LETTER PHASE-A U YUQ NAE;Lo;0;L;;;;;N;;;;; +16821;BAMUM LETTER PHASE-A GHEUAEGHEUAE;Lo;0;L;;;;;N;;;;; +16822;BAMUM LETTER PHASE-A NTAP NTAA;Lo;0;L;;;;;N;;;;; +16823;BAMUM LETTER PHASE-A SISA;Lo;0;L;;;;;N;;;;; +16824;BAMUM LETTER PHASE-A MGBASA;Lo;0;L;;;;;N;;;;; +16825;BAMUM LETTER PHASE-A MEUNJOMNDEUQ;Lo;0;L;;;;;N;;;;; +16826;BAMUM LETTER PHASE-A MOOMPUQ;Lo;0;L;;;;;N;;;;; +16827;BAMUM LETTER PHASE-A KAFA;Lo;0;L;;;;;N;;;;; +16828;BAMUM LETTER PHASE-A PA LEERAEWA;Lo;0;L;;;;;N;;;;; +16829;BAMUM LETTER PHASE-A NDA LEERAEWA;Lo;0;L;;;;;N;;;;; +1682A;BAMUM LETTER PHASE-A PET;Lo;0;L;;;;;N;;;;; +1682B;BAMUM LETTER PHASE-A MAEMKPEN;Lo;0;L;;;;;N;;;;; +1682C;BAMUM LETTER PHASE-A NIKA;Lo;0;L;;;;;N;;;;; +1682D;BAMUM LETTER PHASE-A PUP;Lo;0;L;;;;;N;;;;; +1682E;BAMUM LETTER PHASE-A TUAEP;Lo;0;L;;;;;N;;;;; +1682F;BAMUM LETTER PHASE-A LUAEP;Lo;0;L;;;;;N;;;;; +16830;BAMUM LETTER PHASE-A SONJAM;Lo;0;L;;;;;N;;;;; +16831;BAMUM LETTER PHASE-A TEUTEUWEN;Lo;0;L;;;;;N;;;;; +16832;BAMUM LETTER PHASE-A MAENYI;Lo;0;L;;;;;N;;;;; +16833;BAMUM LETTER PHASE-A KET;Lo;0;L;;;;;N;;;;; +16834;BAMUM LETTER PHASE-A NDAANGGEUAET;Lo;0;L;;;;;N;;;;; +16835;BAMUM LETTER PHASE-A KUOQ;Lo;0;L;;;;;N;;;;; +16836;BAMUM LETTER PHASE-A MOOMEUT;Lo;0;L;;;;;N;;;;; +16837;BAMUM LETTER PHASE-A SHUM;Lo;0;L;;;;;N;;;;; +16838;BAMUM LETTER PHASE-A LOMMAE;Lo;0;L;;;;;N;;;;; +16839;BAMUM LETTER PHASE-A FIRI;Lo;0;L;;;;;N;;;;; +1683A;BAMUM LETTER PHASE-A ROM;Lo;0;L;;;;;N;;;;; +1683B;BAMUM LETTER PHASE-A KPOQ;Lo;0;L;;;;;N;;;;; +1683C;BAMUM LETTER PHASE-A SOQ;Lo;0;L;;;;;N;;;;; +1683D;BAMUM LETTER PHASE-A MAP PIEET;Lo;0;L;;;;;N;;;;; +1683E;BAMUM LETTER PHASE-A SHIRAE;Lo;0;L;;;;;N;;;;; +1683F;BAMUM LETTER PHASE-A NTAP;Lo;0;L;;;;;N;;;;; +16840;BAMUM LETTER PHASE-A SHOQ NSHUT YUM;Lo;0;L;;;;;N;;;;; +16841;BAMUM LETTER PHASE-A NYIT MONGKEUAEQ;Lo;0;L;;;;;N;;;;; +16842;BAMUM LETTER PHASE-A PAARAE;Lo;0;L;;;;;N;;;;; +16843;BAMUM LETTER PHASE-A NKAARAE;Lo;0;L;;;;;N;;;;; +16844;BAMUM LETTER PHASE-A UNKNOWN;Lo;0;L;;;;;N;;;;; +16845;BAMUM LETTER PHASE-A NGGEN;Lo;0;L;;;;;N;;;;; +16846;BAMUM LETTER PHASE-A MAESI;Lo;0;L;;;;;N;;;;; +16847;BAMUM LETTER PHASE-A NJAM;Lo;0;L;;;;;N;;;;; +16848;BAMUM LETTER PHASE-A MBANYI;Lo;0;L;;;;;N;;;;; +16849;BAMUM LETTER PHASE-A NYET;Lo;0;L;;;;;N;;;;; +1684A;BAMUM LETTER PHASE-A TEUAEN;Lo;0;L;;;;;N;;;;; +1684B;BAMUM LETTER PHASE-A SOT;Lo;0;L;;;;;N;;;;; +1684C;BAMUM LETTER PHASE-A PAAM;Lo;0;L;;;;;N;;;;; +1684D;BAMUM LETTER PHASE-A NSHIEE;Lo;0;L;;;;;N;;;;; +1684E;BAMUM LETTER PHASE-A MAEM;Lo;0;L;;;;;N;;;;; +1684F;BAMUM LETTER PHASE-A NYI;Lo;0;L;;;;;N;;;;; +16850;BAMUM LETTER PHASE-A KAQ;Lo;0;L;;;;;N;;;;; +16851;BAMUM LETTER PHASE-A NSHA;Lo;0;L;;;;;N;;;;; +16852;BAMUM LETTER PHASE-A VEE;Lo;0;L;;;;;N;;;;; +16853;BAMUM LETTER PHASE-A LU;Lo;0;L;;;;;N;;;;; +16854;BAMUM LETTER PHASE-A NEN;Lo;0;L;;;;;N;;;;; +16855;BAMUM LETTER PHASE-A NAQ;Lo;0;L;;;;;N;;;;; +16856;BAMUM LETTER PHASE-A MBAQ;Lo;0;L;;;;;N;;;;; +16857;BAMUM LETTER PHASE-B NSHUET;Lo;0;L;;;;;N;;;;; +16858;BAMUM LETTER PHASE-B TU MAEMGBIEE;Lo;0;L;;;;;N;;;;; +16859;BAMUM LETTER PHASE-B SIEE;Lo;0;L;;;;;N;;;;; +1685A;BAMUM LETTER PHASE-B SET TU;Lo;0;L;;;;;N;;;;; +1685B;BAMUM LETTER PHASE-B LOM NTEUM;Lo;0;L;;;;;N;;;;; +1685C;BAMUM LETTER PHASE-B MBA MAELEE;Lo;0;L;;;;;N;;;;; +1685D;BAMUM LETTER PHASE-B KIEEM;Lo;0;L;;;;;N;;;;; +1685E;BAMUM LETTER PHASE-B YEURAE;Lo;0;L;;;;;N;;;;; +1685F;BAMUM LETTER PHASE-B MBAARAE;Lo;0;L;;;;;N;;;;; +16860;BAMUM LETTER PHASE-B KAM;Lo;0;L;;;;;N;;;;; +16861;BAMUM LETTER PHASE-B PEESHI;Lo;0;L;;;;;N;;;;; +16862;BAMUM LETTER PHASE-B YAFU LEERAEWA;Lo;0;L;;;;;N;;;;; +16863;BAMUM LETTER PHASE-B LAM NSHUT NYAM;Lo;0;L;;;;;N;;;;; +16864;BAMUM LETTER PHASE-B NTIEE SHEUOQ;Lo;0;L;;;;;N;;;;; +16865;BAMUM LETTER PHASE-B NDU NJAA;Lo;0;L;;;;;N;;;;; +16866;BAMUM LETTER PHASE-B GHEUGHEUAEM;Lo;0;L;;;;;N;;;;; +16867;BAMUM LETTER PHASE-B PIT;Lo;0;L;;;;;N;;;;; +16868;BAMUM LETTER PHASE-B TU NSIEE;Lo;0;L;;;;;N;;;;; +16869;BAMUM LETTER PHASE-B SHET NJAQ;Lo;0;L;;;;;N;;;;; +1686A;BAMUM LETTER PHASE-B SHEUAEQTU;Lo;0;L;;;;;N;;;;; +1686B;BAMUM LETTER PHASE-B MFON TEUAEQ;Lo;0;L;;;;;N;;;;; +1686C;BAMUM LETTER PHASE-B MBIT MBAAKET;Lo;0;L;;;;;N;;;;; +1686D;BAMUM LETTER PHASE-B NYI NTEUM;Lo;0;L;;;;;N;;;;; +1686E;BAMUM LETTER PHASE-B KEUPUQ;Lo;0;L;;;;;N;;;;; +1686F;BAMUM LETTER PHASE-B GHEUGHEN;Lo;0;L;;;;;N;;;;; +16870;BAMUM LETTER PHASE-B KEUYEUX;Lo;0;L;;;;;N;;;;; +16871;BAMUM LETTER PHASE-B LAANAE;Lo;0;L;;;;;N;;;;; +16872;BAMUM LETTER PHASE-B PARUM;Lo;0;L;;;;;N;;;;; +16873;BAMUM LETTER PHASE-B VEUM;Lo;0;L;;;;;N;;;;; +16874;BAMUM LETTER PHASE-B NGKINDI MVOP;Lo;0;L;;;;;N;;;;; +16875;BAMUM LETTER PHASE-B NGGEU MBU;Lo;0;L;;;;;N;;;;; +16876;BAMUM LETTER PHASE-B WUAET;Lo;0;L;;;;;N;;;;; +16877;BAMUM LETTER PHASE-B SAKEUAE;Lo;0;L;;;;;N;;;;; +16878;BAMUM LETTER PHASE-B TAAM;Lo;0;L;;;;;N;;;;; +16879;BAMUM LETTER PHASE-B MEUQ;Lo;0;L;;;;;N;;;;; +1687A;BAMUM LETTER PHASE-B NGGUOQ;Lo;0;L;;;;;N;;;;; +1687B;BAMUM LETTER PHASE-B NGGUOQ LARGE;Lo;0;L;;;;;N;;;;; +1687C;BAMUM LETTER PHASE-B MFIYAQ;Lo;0;L;;;;;N;;;;; +1687D;BAMUM LETTER PHASE-B SUE;Lo;0;L;;;;;N;;;;; +1687E;BAMUM LETTER PHASE-B MBEURI;Lo;0;L;;;;;N;;;;; +1687F;BAMUM LETTER PHASE-B MONTIEEN;Lo;0;L;;;;;N;;;;; +16880;BAMUM LETTER PHASE-B NYAEMAE;Lo;0;L;;;;;N;;;;; +16881;BAMUM LETTER PHASE-B PUNGAAM;Lo;0;L;;;;;N;;;;; +16882;BAMUM LETTER PHASE-B MEUT NGGEET;Lo;0;L;;;;;N;;;;; +16883;BAMUM LETTER PHASE-B FEUX;Lo;0;L;;;;;N;;;;; +16884;BAMUM LETTER PHASE-B MBUOQ;Lo;0;L;;;;;N;;;;; +16885;BAMUM LETTER PHASE-B FEE;Lo;0;L;;;;;N;;;;; +16886;BAMUM LETTER PHASE-B KEUAEM;Lo;0;L;;;;;N;;;;; +16887;BAMUM LETTER PHASE-B MA NJEUAENA;Lo;0;L;;;;;N;;;;; +16888;BAMUM LETTER PHASE-B MA NJUQA;Lo;0;L;;;;;N;;;;; +16889;BAMUM LETTER PHASE-B LET;Lo;0;L;;;;;N;;;;; +1688A;BAMUM LETTER PHASE-B NGGAAM;Lo;0;L;;;;;N;;;;; +1688B;BAMUM LETTER PHASE-B NSEN;Lo;0;L;;;;;N;;;;; +1688C;BAMUM LETTER PHASE-B MA;Lo;0;L;;;;;N;;;;; +1688D;BAMUM LETTER PHASE-B KIQ;Lo;0;L;;;;;N;;;;; +1688E;BAMUM LETTER PHASE-B NGOM;Lo;0;L;;;;;N;;;;; +1688F;BAMUM LETTER PHASE-C NGKUE MAEMBA;Lo;0;L;;;;;N;;;;; +16890;BAMUM LETTER PHASE-C NZA;Lo;0;L;;;;;N;;;;; +16891;BAMUM LETTER PHASE-C YUM;Lo;0;L;;;;;N;;;;; +16892;BAMUM LETTER PHASE-C WANGKUOQ;Lo;0;L;;;;;N;;;;; +16893;BAMUM LETTER PHASE-C NGGEN;Lo;0;L;;;;;N;;;;; +16894;BAMUM LETTER PHASE-C NDEUAEREE;Lo;0;L;;;;;N;;;;; +16895;BAMUM LETTER PHASE-C NGKAQ;Lo;0;L;;;;;N;;;;; +16896;BAMUM LETTER PHASE-C GHARAE;Lo;0;L;;;;;N;;;;; +16897;BAMUM LETTER PHASE-C MBEEKEET;Lo;0;L;;;;;N;;;;; +16898;BAMUM LETTER PHASE-C GBAYI;Lo;0;L;;;;;N;;;;; +16899;BAMUM LETTER PHASE-C NYIR MKPARAQ MEUN;Lo;0;L;;;;;N;;;;; +1689A;BAMUM LETTER PHASE-C NTU MBIT;Lo;0;L;;;;;N;;;;; +1689B;BAMUM LETTER PHASE-C MBEUM;Lo;0;L;;;;;N;;;;; +1689C;BAMUM LETTER PHASE-C PIRIEEN;Lo;0;L;;;;;N;;;;; +1689D;BAMUM LETTER PHASE-C NDOMBU;Lo;0;L;;;;;N;;;;; +1689E;BAMUM LETTER PHASE-C MBAA CABBAGE-TREE;Lo;0;L;;;;;N;;;;; +1689F;BAMUM LETTER PHASE-C KEUSHEUAEP;Lo;0;L;;;;;N;;;;; +168A0;BAMUM LETTER PHASE-C GHAP;Lo;0;L;;;;;N;;;;; +168A1;BAMUM LETTER PHASE-C KEUKAQ;Lo;0;L;;;;;N;;;;; +168A2;BAMUM LETTER PHASE-C YU MUOMAE;Lo;0;L;;;;;N;;;;; +168A3;BAMUM LETTER PHASE-C NZEUM;Lo;0;L;;;;;N;;;;; +168A4;BAMUM LETTER PHASE-C MBUE;Lo;0;L;;;;;N;;;;; +168A5;BAMUM LETTER PHASE-C NSEUAEN;Lo;0;L;;;;;N;;;;; +168A6;BAMUM LETTER PHASE-C MBIT;Lo;0;L;;;;;N;;;;; +168A7;BAMUM LETTER PHASE-C YEUQ;Lo;0;L;;;;;N;;;;; +168A8;BAMUM LETTER PHASE-C KPARAQ;Lo;0;L;;;;;N;;;;; +168A9;BAMUM LETTER PHASE-C KAA;Lo;0;L;;;;;N;;;;; +168AA;BAMUM LETTER PHASE-C SEUX;Lo;0;L;;;;;N;;;;; +168AB;BAMUM LETTER PHASE-C NDIDA;Lo;0;L;;;;;N;;;;; +168AC;BAMUM LETTER PHASE-C TAASHAE;Lo;0;L;;;;;N;;;;; +168AD;BAMUM LETTER PHASE-C NJUEQ;Lo;0;L;;;;;N;;;;; +168AE;BAMUM LETTER PHASE-C TITA YUE;Lo;0;L;;;;;N;;;;; +168AF;BAMUM LETTER PHASE-C SUAET;Lo;0;L;;;;;N;;;;; +168B0;BAMUM LETTER PHASE-C NGGUAEN NYAM;Lo;0;L;;;;;N;;;;; +168B1;BAMUM LETTER PHASE-C VEUX;Lo;0;L;;;;;N;;;;; +168B2;BAMUM LETTER PHASE-C NANSANAQ;Lo;0;L;;;;;N;;;;; +168B3;BAMUM LETTER PHASE-C MA KEUAERI;Lo;0;L;;;;;N;;;;; +168B4;BAMUM LETTER PHASE-C NTAA;Lo;0;L;;;;;N;;;;; +168B5;BAMUM LETTER PHASE-C NGGUON;Lo;0;L;;;;;N;;;;; +168B6;BAMUM LETTER PHASE-C LAP;Lo;0;L;;;;;N;;;;; +168B7;BAMUM LETTER PHASE-C MBIRIEEN;Lo;0;L;;;;;N;;;;; +168B8;BAMUM LETTER PHASE-C MGBASAQ;Lo;0;L;;;;;N;;;;; +168B9;BAMUM LETTER PHASE-C NTEUNGBA;Lo;0;L;;;;;N;;;;; +168BA;BAMUM LETTER PHASE-C TEUTEUX;Lo;0;L;;;;;N;;;;; +168BB;BAMUM LETTER PHASE-C NGGUM;Lo;0;L;;;;;N;;;;; +168BC;BAMUM LETTER PHASE-C FUE;Lo;0;L;;;;;N;;;;; +168BD;BAMUM LETTER PHASE-C NDEUT;Lo;0;L;;;;;N;;;;; +168BE;BAMUM LETTER PHASE-C NSA;Lo;0;L;;;;;N;;;;; +168BF;BAMUM LETTER PHASE-C NSHAQ;Lo;0;L;;;;;N;;;;; +168C0;BAMUM LETTER PHASE-C BUNG;Lo;0;L;;;;;N;;;;; +168C1;BAMUM LETTER PHASE-C VEUAEPEN;Lo;0;L;;;;;N;;;;; +168C2;BAMUM LETTER PHASE-C MBERAE;Lo;0;L;;;;;N;;;;; +168C3;BAMUM LETTER PHASE-C RU;Lo;0;L;;;;;N;;;;; +168C4;BAMUM LETTER PHASE-C NJAEM;Lo;0;L;;;;;N;;;;; +168C5;BAMUM LETTER PHASE-C LAM;Lo;0;L;;;;;N;;;;; +168C6;BAMUM LETTER PHASE-C TITUAEP;Lo;0;L;;;;;N;;;;; +168C7;BAMUM LETTER PHASE-C NSUOT NGOM;Lo;0;L;;;;;N;;;;; +168C8;BAMUM LETTER PHASE-C NJEEEE;Lo;0;L;;;;;N;;;;; +168C9;BAMUM LETTER PHASE-C KET;Lo;0;L;;;;;N;;;;; +168CA;BAMUM LETTER PHASE-C NGGU;Lo;0;L;;;;;N;;;;; +168CB;BAMUM LETTER PHASE-C MAESI;Lo;0;L;;;;;N;;;;; +168CC;BAMUM LETTER PHASE-C MBUAEM;Lo;0;L;;;;;N;;;;; +168CD;BAMUM LETTER PHASE-C LU;Lo;0;L;;;;;N;;;;; +168CE;BAMUM LETTER PHASE-C KUT;Lo;0;L;;;;;N;;;;; +168CF;BAMUM LETTER PHASE-C NJAM;Lo;0;L;;;;;N;;;;; +168D0;BAMUM LETTER PHASE-C NGOM;Lo;0;L;;;;;N;;;;; +168D1;BAMUM LETTER PHASE-C WUP;Lo;0;L;;;;;N;;;;; +168D2;BAMUM LETTER PHASE-C NGGUEET;Lo;0;L;;;;;N;;;;; +168D3;BAMUM LETTER PHASE-C NSOM;Lo;0;L;;;;;N;;;;; +168D4;BAMUM LETTER PHASE-C NTEN;Lo;0;L;;;;;N;;;;; +168D5;BAMUM LETTER PHASE-C KUOP NKAARAE;Lo;0;L;;;;;N;;;;; +168D6;BAMUM LETTER PHASE-C NSUN;Lo;0;L;;;;;N;;;;; +168D7;BAMUM LETTER PHASE-C NDAM;Lo;0;L;;;;;N;;;;; +168D8;BAMUM LETTER PHASE-C MA NSIEE;Lo;0;L;;;;;N;;;;; +168D9;BAMUM LETTER PHASE-C YAA;Lo;0;L;;;;;N;;;;; +168DA;BAMUM LETTER PHASE-C NDAP;Lo;0;L;;;;;N;;;;; +168DB;BAMUM LETTER PHASE-C SHUEQ;Lo;0;L;;;;;N;;;;; +168DC;BAMUM LETTER PHASE-C SETFON;Lo;0;L;;;;;N;;;;; +168DD;BAMUM LETTER PHASE-C MBI;Lo;0;L;;;;;N;;;;; +168DE;BAMUM LETTER PHASE-C MAEMBA;Lo;0;L;;;;;N;;;;; +168DF;BAMUM LETTER PHASE-C MBANYI;Lo;0;L;;;;;N;;;;; +168E0;BAMUM LETTER PHASE-C KEUSEUX;Lo;0;L;;;;;N;;;;; +168E1;BAMUM LETTER PHASE-C MBEUX;Lo;0;L;;;;;N;;;;; +168E2;BAMUM LETTER PHASE-C KEUM;Lo;0;L;;;;;N;;;;; +168E3;BAMUM LETTER PHASE-C MBAA PICKET;Lo;0;L;;;;;N;;;;; +168E4;BAMUM LETTER PHASE-C YUWOQ;Lo;0;L;;;;;N;;;;; +168E5;BAMUM LETTER PHASE-C NJEUX;Lo;0;L;;;;;N;;;;; +168E6;BAMUM LETTER PHASE-C MIEE;Lo;0;L;;;;;N;;;;; +168E7;BAMUM LETTER PHASE-C MUAE;Lo;0;L;;;;;N;;;;; +168E8;BAMUM LETTER PHASE-C SHIQ;Lo;0;L;;;;;N;;;;; +168E9;BAMUM LETTER PHASE-C KEN LAW;Lo;0;L;;;;;N;;;;; +168EA;BAMUM LETTER PHASE-C KEN FATIGUE;Lo;0;L;;;;;N;;;;; +168EB;BAMUM LETTER PHASE-C NGAQ;Lo;0;L;;;;;N;;;;; +168EC;BAMUM LETTER PHASE-C NAQ;Lo;0;L;;;;;N;;;;; +168ED;BAMUM LETTER PHASE-C LIQ;Lo;0;L;;;;;N;;;;; +168EE;BAMUM LETTER PHASE-C PIN;Lo;0;L;;;;;N;;;;; +168EF;BAMUM LETTER PHASE-C PEN;Lo;0;L;;;;;N;;;;; +168F0;BAMUM LETTER PHASE-C TET;Lo;0;L;;;;;N;;;;; +168F1;BAMUM LETTER PHASE-D MBUO;Lo;0;L;;;;;N;;;;; +168F2;BAMUM LETTER PHASE-D WAP;Lo;0;L;;;;;N;;;;; +168F3;BAMUM LETTER PHASE-D NJI;Lo;0;L;;;;;N;;;;; +168F4;BAMUM LETTER PHASE-D MFON;Lo;0;L;;;;;N;;;;; +168F5;BAMUM LETTER PHASE-D NJIEE;Lo;0;L;;;;;N;;;;; +168F6;BAMUM LETTER PHASE-D LIEE;Lo;0;L;;;;;N;;;;; +168F7;BAMUM LETTER PHASE-D NJEUT;Lo;0;L;;;;;N;;;;; +168F8;BAMUM LETTER PHASE-D NSHEE;Lo;0;L;;;;;N;;;;; +168F9;BAMUM LETTER PHASE-D NGGAAMAE;Lo;0;L;;;;;N;;;;; +168FA;BAMUM LETTER PHASE-D NYAM;Lo;0;L;;;;;N;;;;; +168FB;BAMUM LETTER PHASE-D WUAEN;Lo;0;L;;;;;N;;;;; +168FC;BAMUM LETTER PHASE-D NGKUN;Lo;0;L;;;;;N;;;;; +168FD;BAMUM LETTER PHASE-D SHEE;Lo;0;L;;;;;N;;;;; +168FE;BAMUM LETTER PHASE-D NGKAP;Lo;0;L;;;;;N;;;;; +168FF;BAMUM LETTER PHASE-D KEUAETMEUN;Lo;0;L;;;;;N;;;;; +16900;BAMUM LETTER PHASE-D TEUT;Lo;0;L;;;;;N;;;;; +16901;BAMUM LETTER PHASE-D SHEUAE;Lo;0;L;;;;;N;;;;; +16902;BAMUM LETTER PHASE-D NJAP;Lo;0;L;;;;;N;;;;; +16903;BAMUM LETTER PHASE-D SUE;Lo;0;L;;;;;N;;;;; +16904;BAMUM LETTER PHASE-D KET;Lo;0;L;;;;;N;;;;; +16905;BAMUM LETTER PHASE-D YAEMMAE;Lo;0;L;;;;;N;;;;; +16906;BAMUM LETTER PHASE-D KUOM;Lo;0;L;;;;;N;;;;; +16907;BAMUM LETTER PHASE-D SAP;Lo;0;L;;;;;N;;;;; +16908;BAMUM LETTER PHASE-D MFEUT;Lo;0;L;;;;;N;;;;; +16909;BAMUM LETTER PHASE-D NDEUX;Lo;0;L;;;;;N;;;;; +1690A;BAMUM LETTER PHASE-D MALEERI;Lo;0;L;;;;;N;;;;; +1690B;BAMUM LETTER PHASE-D MEUT;Lo;0;L;;;;;N;;;;; +1690C;BAMUM LETTER PHASE-D SEUAEQ;Lo;0;L;;;;;N;;;;; +1690D;BAMUM LETTER PHASE-D YEN;Lo;0;L;;;;;N;;;;; +1690E;BAMUM LETTER PHASE-D NJEUAEM;Lo;0;L;;;;;N;;;;; +1690F;BAMUM LETTER PHASE-D KEUOT MBUAE;Lo;0;L;;;;;N;;;;; +16910;BAMUM LETTER PHASE-D NGKEURI;Lo;0;L;;;;;N;;;;; +16911;BAMUM LETTER PHASE-D TU;Lo;0;L;;;;;N;;;;; +16912;BAMUM LETTER PHASE-D GHAA;Lo;0;L;;;;;N;;;;; +16913;BAMUM LETTER PHASE-D NGKYEE;Lo;0;L;;;;;N;;;;; +16914;BAMUM LETTER PHASE-D FEUFEUAET;Lo;0;L;;;;;N;;;;; +16915;BAMUM LETTER PHASE-D NDEE;Lo;0;L;;;;;N;;;;; +16916;BAMUM LETTER PHASE-D MGBOFUM;Lo;0;L;;;;;N;;;;; +16917;BAMUM LETTER PHASE-D LEUAEP;Lo;0;L;;;;;N;;;;; +16918;BAMUM LETTER PHASE-D NDON;Lo;0;L;;;;;N;;;;; +16919;BAMUM LETTER PHASE-D MONI;Lo;0;L;;;;;N;;;;; +1691A;BAMUM LETTER PHASE-D MGBEUN;Lo;0;L;;;;;N;;;;; +1691B;BAMUM LETTER PHASE-D PUUT;Lo;0;L;;;;;N;;;;; +1691C;BAMUM LETTER PHASE-D MGBIEE;Lo;0;L;;;;;N;;;;; +1691D;BAMUM LETTER PHASE-D MFO;Lo;0;L;;;;;N;;;;; +1691E;BAMUM LETTER PHASE-D LUM;Lo;0;L;;;;;N;;;;; +1691F;BAMUM LETTER PHASE-D NSIEEP;Lo;0;L;;;;;N;;;;; +16920;BAMUM LETTER PHASE-D MBAA;Lo;0;L;;;;;N;;;;; +16921;BAMUM LETTER PHASE-D KWAET;Lo;0;L;;;;;N;;;;; +16922;BAMUM LETTER PHASE-D NYET;Lo;0;L;;;;;N;;;;; +16923;BAMUM LETTER PHASE-D TEUAEN;Lo;0;L;;;;;N;;;;; +16924;BAMUM LETTER PHASE-D SOT;Lo;0;L;;;;;N;;;;; +16925;BAMUM LETTER PHASE-D YUWOQ;Lo;0;L;;;;;N;;;;; +16926;BAMUM LETTER PHASE-D KEUM;Lo;0;L;;;;;N;;;;; +16927;BAMUM LETTER PHASE-D RAEM;Lo;0;L;;;;;N;;;;; +16928;BAMUM LETTER PHASE-D TEEEE;Lo;0;L;;;;;N;;;;; +16929;BAMUM LETTER PHASE-D NGKEUAEQ;Lo;0;L;;;;;N;;;;; +1692A;BAMUM LETTER PHASE-D MFEUAE;Lo;0;L;;;;;N;;;;; +1692B;BAMUM LETTER PHASE-D NSIEET;Lo;0;L;;;;;N;;;;; +1692C;BAMUM LETTER PHASE-D KEUP;Lo;0;L;;;;;N;;;;; +1692D;BAMUM LETTER PHASE-D PIP;Lo;0;L;;;;;N;;;;; +1692E;BAMUM LETTER PHASE-D PEUTAE;Lo;0;L;;;;;N;;;;; +1692F;BAMUM LETTER PHASE-D NYUE;Lo;0;L;;;;;N;;;;; +16930;BAMUM LETTER PHASE-D LET;Lo;0;L;;;;;N;;;;; +16931;BAMUM LETTER PHASE-D NGGAAM;Lo;0;L;;;;;N;;;;; +16932;BAMUM LETTER PHASE-D MFIEE;Lo;0;L;;;;;N;;;;; +16933;BAMUM LETTER PHASE-D NGGWAEN;Lo;0;L;;;;;N;;;;; +16934;BAMUM LETTER PHASE-D YUOM;Lo;0;L;;;;;N;;;;; +16935;BAMUM LETTER PHASE-D PAP;Lo;0;L;;;;;N;;;;; +16936;BAMUM LETTER PHASE-D YUOP;Lo;0;L;;;;;N;;;;; +16937;BAMUM LETTER PHASE-D NDAM;Lo;0;L;;;;;N;;;;; +16938;BAMUM LETTER PHASE-D NTEUM;Lo;0;L;;;;;N;;;;; +16939;BAMUM LETTER PHASE-D SUAE;Lo;0;L;;;;;N;;;;; +1693A;BAMUM LETTER PHASE-D KUN;Lo;0;L;;;;;N;;;;; +1693B;BAMUM LETTER PHASE-D NGGEUX;Lo;0;L;;;;;N;;;;; +1693C;BAMUM LETTER PHASE-D NGKIEE;Lo;0;L;;;;;N;;;;; +1693D;BAMUM LETTER PHASE-D TUOT;Lo;0;L;;;;;N;;;;; +1693E;BAMUM LETTER PHASE-D MEUN;Lo;0;L;;;;;N;;;;; +1693F;BAMUM LETTER PHASE-D KUQ;Lo;0;L;;;;;N;;;;; +16940;BAMUM LETTER PHASE-D NSUM;Lo;0;L;;;;;N;;;;; +16941;BAMUM LETTER PHASE-D TEUN;Lo;0;L;;;;;N;;;;; +16942;BAMUM LETTER PHASE-D MAENJET;Lo;0;L;;;;;N;;;;; +16943;BAMUM LETTER PHASE-D NGGAP;Lo;0;L;;;;;N;;;;; +16944;BAMUM LETTER PHASE-D LEUM;Lo;0;L;;;;;N;;;;; +16945;BAMUM LETTER PHASE-D NGGUOM;Lo;0;L;;;;;N;;;;; +16946;BAMUM LETTER PHASE-D NSHUT;Lo;0;L;;;;;N;;;;; +16947;BAMUM LETTER PHASE-D NJUEQ;Lo;0;L;;;;;N;;;;; +16948;BAMUM LETTER PHASE-D GHEUAE;Lo;0;L;;;;;N;;;;; +16949;BAMUM LETTER PHASE-D KU;Lo;0;L;;;;;N;;;;; +1694A;BAMUM LETTER PHASE-D REN OLD;Lo;0;L;;;;;N;;;;; +1694B;BAMUM LETTER PHASE-D TAE;Lo;0;L;;;;;N;;;;; +1694C;BAMUM LETTER PHASE-D TOQ;Lo;0;L;;;;;N;;;;; +1694D;BAMUM LETTER PHASE-D NYI;Lo;0;L;;;;;N;;;;; +1694E;BAMUM LETTER PHASE-D RII;Lo;0;L;;;;;N;;;;; +1694F;BAMUM LETTER PHASE-D LEEEE;Lo;0;L;;;;;N;;;;; +16950;BAMUM LETTER PHASE-D MEEEE;Lo;0;L;;;;;N;;;;; +16951;BAMUM LETTER PHASE-D M;Lo;0;L;;;;;N;;;;; +16952;BAMUM LETTER PHASE-D SUU;Lo;0;L;;;;;N;;;;; +16953;BAMUM LETTER PHASE-D MU;Lo;0;L;;;;;N;;;;; +16954;BAMUM LETTER PHASE-D SHII;Lo;0;L;;;;;N;;;;; +16955;BAMUM LETTER PHASE-D SHEUX;Lo;0;L;;;;;N;;;;; +16956;BAMUM LETTER PHASE-D KYEE;Lo;0;L;;;;;N;;;;; +16957;BAMUM LETTER PHASE-D NU;Lo;0;L;;;;;N;;;;; +16958;BAMUM LETTER PHASE-D SHU;Lo;0;L;;;;;N;;;;; +16959;BAMUM LETTER PHASE-D NTEE;Lo;0;L;;;;;N;;;;; +1695A;BAMUM LETTER PHASE-D PEE;Lo;0;L;;;;;N;;;;; +1695B;BAMUM LETTER PHASE-D NI;Lo;0;L;;;;;N;;;;; +1695C;BAMUM LETTER PHASE-D SHOQ;Lo;0;L;;;;;N;;;;; +1695D;BAMUM LETTER PHASE-D PUQ;Lo;0;L;;;;;N;;;;; +1695E;BAMUM LETTER PHASE-D MVOP;Lo;0;L;;;;;N;;;;; +1695F;BAMUM LETTER PHASE-D LOQ;Lo;0;L;;;;;N;;;;; +16960;BAMUM LETTER PHASE-D REN MUCH;Lo;0;L;;;;;N;;;;; +16961;BAMUM LETTER PHASE-D TI;Lo;0;L;;;;;N;;;;; +16962;BAMUM LETTER PHASE-D NTUU;Lo;0;L;;;;;N;;;;; +16963;BAMUM LETTER PHASE-D MBAA SEVEN;Lo;0;L;;;;;N;;;;; +16964;BAMUM LETTER PHASE-D SAQ;Lo;0;L;;;;;N;;;;; +16965;BAMUM LETTER PHASE-D FAA;Lo;0;L;;;;;N;;;;; +16966;BAMUM LETTER PHASE-E NDAP;Lo;0;L;;;;;N;;;;; +16967;BAMUM LETTER PHASE-E TOON;Lo;0;L;;;;;N;;;;; +16968;BAMUM LETTER PHASE-E MBEUM;Lo;0;L;;;;;N;;;;; +16969;BAMUM LETTER PHASE-E LAP;Lo;0;L;;;;;N;;;;; +1696A;BAMUM LETTER PHASE-E VOM;Lo;0;L;;;;;N;;;;; +1696B;BAMUM LETTER PHASE-E LOON;Lo;0;L;;;;;N;;;;; +1696C;BAMUM LETTER PHASE-E PAA;Lo;0;L;;;;;N;;;;; +1696D;BAMUM LETTER PHASE-E SOM;Lo;0;L;;;;;N;;;;; +1696E;BAMUM LETTER PHASE-E RAQ;Lo;0;L;;;;;N;;;;; +1696F;BAMUM LETTER PHASE-E NSHUOP;Lo;0;L;;;;;N;;;;; +16970;BAMUM LETTER PHASE-E NDUN;Lo;0;L;;;;;N;;;;; +16971;BAMUM LETTER PHASE-E PUAE;Lo;0;L;;;;;N;;;;; +16972;BAMUM LETTER PHASE-E TAM;Lo;0;L;;;;;N;;;;; +16973;BAMUM LETTER PHASE-E NGKA;Lo;0;L;;;;;N;;;;; +16974;BAMUM LETTER PHASE-E KPEUX;Lo;0;L;;;;;N;;;;; +16975;BAMUM LETTER PHASE-E WUO;Lo;0;L;;;;;N;;;;; +16976;BAMUM LETTER PHASE-E SEE;Lo;0;L;;;;;N;;;;; +16977;BAMUM LETTER PHASE-E NGGEUAET;Lo;0;L;;;;;N;;;;; +16978;BAMUM LETTER PHASE-E PAAM;Lo;0;L;;;;;N;;;;; +16979;BAMUM LETTER PHASE-E TOO;Lo;0;L;;;;;N;;;;; +1697A;BAMUM LETTER PHASE-E KUOP;Lo;0;L;;;;;N;;;;; +1697B;BAMUM LETTER PHASE-E LOM;Lo;0;L;;;;;N;;;;; +1697C;BAMUM LETTER PHASE-E NSHIEE;Lo;0;L;;;;;N;;;;; +1697D;BAMUM LETTER PHASE-E NGOP;Lo;0;L;;;;;N;;;;; +1697E;BAMUM LETTER PHASE-E MAEM;Lo;0;L;;;;;N;;;;; +1697F;BAMUM LETTER PHASE-E NGKEUX;Lo;0;L;;;;;N;;;;; +16980;BAMUM LETTER PHASE-E NGOQ;Lo;0;L;;;;;N;;;;; +16981;BAMUM LETTER PHASE-E NSHUE;Lo;0;L;;;;;N;;;;; +16982;BAMUM LETTER PHASE-E RIMGBA;Lo;0;L;;;;;N;;;;; +16983;BAMUM LETTER PHASE-E NJEUX;Lo;0;L;;;;;N;;;;; +16984;BAMUM LETTER PHASE-E PEEM;Lo;0;L;;;;;N;;;;; +16985;BAMUM LETTER PHASE-E SAA;Lo;0;L;;;;;N;;;;; +16986;BAMUM LETTER PHASE-E NGGURAE;Lo;0;L;;;;;N;;;;; +16987;BAMUM LETTER PHASE-E MGBA;Lo;0;L;;;;;N;;;;; +16988;BAMUM LETTER PHASE-E GHEUX;Lo;0;L;;;;;N;;;;; +16989;BAMUM LETTER PHASE-E NGKEUAEM;Lo;0;L;;;;;N;;;;; +1698A;BAMUM LETTER PHASE-E NJAEMLI;Lo;0;L;;;;;N;;;;; +1698B;BAMUM LETTER PHASE-E MAP;Lo;0;L;;;;;N;;;;; +1698C;BAMUM LETTER PHASE-E LOOT;Lo;0;L;;;;;N;;;;; +1698D;BAMUM LETTER PHASE-E NGGEEEE;Lo;0;L;;;;;N;;;;; +1698E;BAMUM LETTER PHASE-E NDIQ;Lo;0;L;;;;;N;;;;; +1698F;BAMUM LETTER PHASE-E TAEN NTEUM;Lo;0;L;;;;;N;;;;; +16990;BAMUM LETTER PHASE-E SET;Lo;0;L;;;;;N;;;;; +16991;BAMUM LETTER PHASE-E PUM;Lo;0;L;;;;;N;;;;; +16992;BAMUM LETTER PHASE-E NDAA SOFTNESS;Lo;0;L;;;;;N;;;;; +16993;BAMUM LETTER PHASE-E NGGUAESHAE NYAM;Lo;0;L;;;;;N;;;;; +16994;BAMUM LETTER PHASE-E YIEE;Lo;0;L;;;;;N;;;;; +16995;BAMUM LETTER PHASE-E GHEUN;Lo;0;L;;;;;N;;;;; +16996;BAMUM LETTER PHASE-E TUAE;Lo;0;L;;;;;N;;;;; +16997;BAMUM LETTER PHASE-E YEUAE;Lo;0;L;;;;;N;;;;; +16998;BAMUM LETTER PHASE-E PO;Lo;0;L;;;;;N;;;;; +16999;BAMUM LETTER PHASE-E TUMAE;Lo;0;L;;;;;N;;;;; +1699A;BAMUM LETTER PHASE-E KEUAE;Lo;0;L;;;;;N;;;;; +1699B;BAMUM LETTER PHASE-E SUAEN;Lo;0;L;;;;;N;;;;; +1699C;BAMUM LETTER PHASE-E TEUAEQ;Lo;0;L;;;;;N;;;;; +1699D;BAMUM LETTER PHASE-E VEUAE;Lo;0;L;;;;;N;;;;; +1699E;BAMUM LETTER PHASE-E WEUX;Lo;0;L;;;;;N;;;;; +1699F;BAMUM LETTER PHASE-E LAAM;Lo;0;L;;;;;N;;;;; +169A0;BAMUM LETTER PHASE-E PU;Lo;0;L;;;;;N;;;;; +169A1;BAMUM LETTER PHASE-E TAAQ;Lo;0;L;;;;;N;;;;; +169A2;BAMUM LETTER PHASE-E GHAAMAE;Lo;0;L;;;;;N;;;;; +169A3;BAMUM LETTER PHASE-E NGEUREUT;Lo;0;L;;;;;N;;;;; +169A4;BAMUM LETTER PHASE-E SHEUAEQ;Lo;0;L;;;;;N;;;;; +169A5;BAMUM LETTER PHASE-E MGBEN;Lo;0;L;;;;;N;;;;; +169A6;BAMUM LETTER PHASE-E MBEE;Lo;0;L;;;;;N;;;;; +169A7;BAMUM LETTER PHASE-E NZAQ;Lo;0;L;;;;;N;;;;; +169A8;BAMUM LETTER PHASE-E NKOM;Lo;0;L;;;;;N;;;;; +169A9;BAMUM LETTER PHASE-E GBET;Lo;0;L;;;;;N;;;;; +169AA;BAMUM LETTER PHASE-E TUM;Lo;0;L;;;;;N;;;;; +169AB;BAMUM LETTER PHASE-E KUET;Lo;0;L;;;;;N;;;;; +169AC;BAMUM LETTER PHASE-E YAP;Lo;0;L;;;;;N;;;;; +169AD;BAMUM LETTER PHASE-E NYI CLEAVER;Lo;0;L;;;;;N;;;;; +169AE;BAMUM LETTER PHASE-E YIT;Lo;0;L;;;;;N;;;;; +169AF;BAMUM LETTER PHASE-E MFEUQ;Lo;0;L;;;;;N;;;;; +169B0;BAMUM LETTER PHASE-E NDIAQ;Lo;0;L;;;;;N;;;;; +169B1;BAMUM LETTER PHASE-E PIEEQ;Lo;0;L;;;;;N;;;;; +169B2;BAMUM LETTER PHASE-E YUEQ;Lo;0;L;;;;;N;;;;; +169B3;BAMUM LETTER PHASE-E LEUAEM;Lo;0;L;;;;;N;;;;; +169B4;BAMUM LETTER PHASE-E FUE;Lo;0;L;;;;;N;;;;; +169B5;BAMUM LETTER PHASE-E GBEUX;Lo;0;L;;;;;N;;;;; +169B6;BAMUM LETTER PHASE-E NGKUP;Lo;0;L;;;;;N;;;;; +169B7;BAMUM LETTER PHASE-E KET;Lo;0;L;;;;;N;;;;; +169B8;BAMUM LETTER PHASE-E MAE;Lo;0;L;;;;;N;;;;; +169B9;BAMUM LETTER PHASE-E NGKAAMI;Lo;0;L;;;;;N;;;;; +169BA;BAMUM LETTER PHASE-E GHET;Lo;0;L;;;;;N;;;;; +169BB;BAMUM LETTER PHASE-E FA;Lo;0;L;;;;;N;;;;; +169BC;BAMUM LETTER PHASE-E NTUM;Lo;0;L;;;;;N;;;;; +169BD;BAMUM LETTER PHASE-E PEUT;Lo;0;L;;;;;N;;;;; +169BE;BAMUM LETTER PHASE-E YEUM;Lo;0;L;;;;;N;;;;; +169BF;BAMUM LETTER PHASE-E NGGEUAE;Lo;0;L;;;;;N;;;;; +169C0;BAMUM LETTER PHASE-E NYI BETWEEN;Lo;0;L;;;;;N;;;;; +169C1;BAMUM LETTER PHASE-E NZUQ;Lo;0;L;;;;;N;;;;; +169C2;BAMUM LETTER PHASE-E POON;Lo;0;L;;;;;N;;;;; +169C3;BAMUM LETTER PHASE-E MIEE;Lo;0;L;;;;;N;;;;; +169C4;BAMUM LETTER PHASE-E FUET;Lo;0;L;;;;;N;;;;; +169C5;BAMUM LETTER PHASE-E NAE;Lo;0;L;;;;;N;;;;; +169C6;BAMUM LETTER PHASE-E MUAE;Lo;0;L;;;;;N;;;;; +169C7;BAMUM LETTER PHASE-E GHEUAE;Lo;0;L;;;;;N;;;;; +169C8;BAMUM LETTER PHASE-E FU I;Lo;0;L;;;;;N;;;;; +169C9;BAMUM LETTER PHASE-E MVI;Lo;0;L;;;;;N;;;;; +169CA;BAMUM LETTER PHASE-E PUAQ;Lo;0;L;;;;;N;;;;; +169CB;BAMUM LETTER PHASE-E NGKUM;Lo;0;L;;;;;N;;;;; +169CC;BAMUM LETTER PHASE-E KUT;Lo;0;L;;;;;N;;;;; +169CD;BAMUM LETTER PHASE-E PIET;Lo;0;L;;;;;N;;;;; +169CE;BAMUM LETTER PHASE-E NTAP;Lo;0;L;;;;;N;;;;; +169CF;BAMUM LETTER PHASE-E YEUAET;Lo;0;L;;;;;N;;;;; +169D0;BAMUM LETTER PHASE-E NGGUP;Lo;0;L;;;;;N;;;;; +169D1;BAMUM LETTER PHASE-E PA PEOPLE;Lo;0;L;;;;;N;;;;; +169D2;BAMUM LETTER PHASE-E FU CALL;Lo;0;L;;;;;N;;;;; +169D3;BAMUM LETTER PHASE-E FOM;Lo;0;L;;;;;N;;;;; +169D4;BAMUM LETTER PHASE-E NJEE;Lo;0;L;;;;;N;;;;; +169D5;BAMUM LETTER PHASE-E A;Lo;0;L;;;;;N;;;;; +169D6;BAMUM LETTER PHASE-E TOQ;Lo;0;L;;;;;N;;;;; +169D7;BAMUM LETTER PHASE-E O;Lo;0;L;;;;;N;;;;; +169D8;BAMUM LETTER PHASE-E I;Lo;0;L;;;;;N;;;;; +169D9;BAMUM LETTER PHASE-E LAQ;Lo;0;L;;;;;N;;;;; +169DA;BAMUM LETTER PHASE-E PA PLURAL;Lo;0;L;;;;;N;;;;; +169DB;BAMUM LETTER PHASE-E TAA;Lo;0;L;;;;;N;;;;; +169DC;BAMUM LETTER PHASE-E TAQ;Lo;0;L;;;;;N;;;;; +169DD;BAMUM LETTER PHASE-E NDAA MY HOUSE;Lo;0;L;;;;;N;;;;; +169DE;BAMUM LETTER PHASE-E SHIQ;Lo;0;L;;;;;N;;;;; +169DF;BAMUM LETTER PHASE-E YEUX;Lo;0;L;;;;;N;;;;; +169E0;BAMUM LETTER PHASE-E NGUAE;Lo;0;L;;;;;N;;;;; +169E1;BAMUM LETTER PHASE-E YUAEN;Lo;0;L;;;;;N;;;;; +169E2;BAMUM LETTER PHASE-E YOQ SWIMMING;Lo;0;L;;;;;N;;;;; +169E3;BAMUM LETTER PHASE-E YOQ COVER;Lo;0;L;;;;;N;;;;; +169E4;BAMUM LETTER PHASE-E YUQ;Lo;0;L;;;;;N;;;;; +169E5;BAMUM LETTER PHASE-E YUN;Lo;0;L;;;;;N;;;;; +169E6;BAMUM LETTER PHASE-E KEUX;Lo;0;L;;;;;N;;;;; +169E7;BAMUM LETTER PHASE-E PEUX;Lo;0;L;;;;;N;;;;; +169E8;BAMUM LETTER PHASE-E NJEE EPOCH;Lo;0;L;;;;;N;;;;; +169E9;BAMUM LETTER PHASE-E PUE;Lo;0;L;;;;;N;;;;; +169EA;BAMUM LETTER PHASE-E WUE;Lo;0;L;;;;;N;;;;; +169EB;BAMUM LETTER PHASE-E FEE;Lo;0;L;;;;;N;;;;; +169EC;BAMUM LETTER PHASE-E VEE;Lo;0;L;;;;;N;;;;; +169ED;BAMUM LETTER PHASE-E LU;Lo;0;L;;;;;N;;;;; +169EE;BAMUM LETTER PHASE-E MI;Lo;0;L;;;;;N;;;;; +169EF;BAMUM LETTER PHASE-E REUX;Lo;0;L;;;;;N;;;;; +169F0;BAMUM LETTER PHASE-E RAE;Lo;0;L;;;;;N;;;;; +169F1;BAMUM LETTER PHASE-E NGUAET;Lo;0;L;;;;;N;;;;; +169F2;BAMUM LETTER PHASE-E NGA;Lo;0;L;;;;;N;;;;; +169F3;BAMUM LETTER PHASE-E SHO;Lo;0;L;;;;;N;;;;; +169F4;BAMUM LETTER PHASE-E SHOQ;Lo;0;L;;;;;N;;;;; +169F5;BAMUM LETTER PHASE-E FU REMEDY;Lo;0;L;;;;;N;;;;; +169F6;BAMUM LETTER PHASE-E NA;Lo;0;L;;;;;N;;;;; +169F7;BAMUM LETTER PHASE-E PI;Lo;0;L;;;;;N;;;;; +169F8;BAMUM LETTER PHASE-E LOQ;Lo;0;L;;;;;N;;;;; +169F9;BAMUM LETTER PHASE-E KO;Lo;0;L;;;;;N;;;;; +169FA;BAMUM LETTER PHASE-E MEN;Lo;0;L;;;;;N;;;;; +169FB;BAMUM LETTER PHASE-E MA;Lo;0;L;;;;;N;;;;; +169FC;BAMUM LETTER PHASE-E MAQ;Lo;0;L;;;;;N;;;;; +169FD;BAMUM LETTER PHASE-E TEU;Lo;0;L;;;;;N;;;;; +169FE;BAMUM LETTER PHASE-E KI;Lo;0;L;;;;;N;;;;; +169FF;BAMUM LETTER PHASE-E MON;Lo;0;L;;;;;N;;;;; +16A00;BAMUM LETTER PHASE-E TEN;Lo;0;L;;;;;N;;;;; +16A01;BAMUM LETTER PHASE-E FAQ;Lo;0;L;;;;;N;;;;; +16A02;BAMUM LETTER PHASE-E GHOM;Lo;0;L;;;;;N;;;;; +16A03;BAMUM LETTER PHASE-F KA;Lo;0;L;;;;;N;;;;; +16A04;BAMUM LETTER PHASE-F U;Lo;0;L;;;;;N;;;;; +16A05;BAMUM LETTER PHASE-F KU;Lo;0;L;;;;;N;;;;; +16A06;BAMUM LETTER PHASE-F EE;Lo;0;L;;;;;N;;;;; +16A07;BAMUM LETTER PHASE-F REE;Lo;0;L;;;;;N;;;;; +16A08;BAMUM LETTER PHASE-F TAE;Lo;0;L;;;;;N;;;;; +16A09;BAMUM LETTER PHASE-F NYI;Lo;0;L;;;;;N;;;;; +16A0A;BAMUM LETTER PHASE-F LA;Lo;0;L;;;;;N;;;;; +16A0B;BAMUM LETTER PHASE-F RII;Lo;0;L;;;;;N;;;;; +16A0C;BAMUM LETTER PHASE-F RIEE;Lo;0;L;;;;;N;;;;; +16A0D;BAMUM LETTER PHASE-F MEEEE;Lo;0;L;;;;;N;;;;; +16A0E;BAMUM LETTER PHASE-F TAA;Lo;0;L;;;;;N;;;;; +16A0F;BAMUM LETTER PHASE-F NDAA;Lo;0;L;;;;;N;;;;; +16A10;BAMUM LETTER PHASE-F NJAEM;Lo;0;L;;;;;N;;;;; +16A11;BAMUM LETTER PHASE-F M;Lo;0;L;;;;;N;;;;; +16A12;BAMUM LETTER PHASE-F SUU;Lo;0;L;;;;;N;;;;; +16A13;BAMUM LETTER PHASE-F SHII;Lo;0;L;;;;;N;;;;; +16A14;BAMUM LETTER PHASE-F SI;Lo;0;L;;;;;N;;;;; +16A15;BAMUM LETTER PHASE-F SEUX;Lo;0;L;;;;;N;;;;; +16A16;BAMUM LETTER PHASE-F KYEE;Lo;0;L;;;;;N;;;;; +16A17;BAMUM LETTER PHASE-F KET;Lo;0;L;;;;;N;;;;; +16A18;BAMUM LETTER PHASE-F NUAE;Lo;0;L;;;;;N;;;;; +16A19;BAMUM LETTER PHASE-F NU;Lo;0;L;;;;;N;;;;; +16A1A;BAMUM LETTER PHASE-F NJUAE;Lo;0;L;;;;;N;;;;; +16A1B;BAMUM LETTER PHASE-F YOQ;Lo;0;L;;;;;N;;;;; +16A1C;BAMUM LETTER PHASE-F SHU;Lo;0;L;;;;;N;;;;; +16A1D;BAMUM LETTER PHASE-F YA;Lo;0;L;;;;;N;;;;; +16A1E;BAMUM LETTER PHASE-F NSHA;Lo;0;L;;;;;N;;;;; +16A1F;BAMUM LETTER PHASE-F PEUX;Lo;0;L;;;;;N;;;;; +16A20;BAMUM LETTER PHASE-F NTEE;Lo;0;L;;;;;N;;;;; +16A21;BAMUM LETTER PHASE-F WUE;Lo;0;L;;;;;N;;;;; +16A22;BAMUM LETTER PHASE-F PEE;Lo;0;L;;;;;N;;;;; +16A23;BAMUM LETTER PHASE-F RU;Lo;0;L;;;;;N;;;;; +16A24;BAMUM LETTER PHASE-F NI;Lo;0;L;;;;;N;;;;; +16A25;BAMUM LETTER PHASE-F REUX;Lo;0;L;;;;;N;;;;; +16A26;BAMUM LETTER PHASE-F KEN;Lo;0;L;;;;;N;;;;; +16A27;BAMUM LETTER PHASE-F NGKWAEN;Lo;0;L;;;;;N;;;;; +16A28;BAMUM LETTER PHASE-F NGGA;Lo;0;L;;;;;N;;;;; +16A29;BAMUM LETTER PHASE-F SHO;Lo;0;L;;;;;N;;;;; +16A2A;BAMUM LETTER PHASE-F PUAE;Lo;0;L;;;;;N;;;;; +16A2B;BAMUM LETTER PHASE-F FOM;Lo;0;L;;;;;N;;;;; +16A2C;BAMUM LETTER PHASE-F WA;Lo;0;L;;;;;N;;;;; +16A2D;BAMUM LETTER PHASE-F LI;Lo;0;L;;;;;N;;;;; +16A2E;BAMUM LETTER PHASE-F LOQ;Lo;0;L;;;;;N;;;;; +16A2F;BAMUM LETTER PHASE-F KO;Lo;0;L;;;;;N;;;;; +16A30;BAMUM LETTER PHASE-F MBEN;Lo;0;L;;;;;N;;;;; +16A31;BAMUM LETTER PHASE-F REN;Lo;0;L;;;;;N;;;;; +16A32;BAMUM LETTER PHASE-F MA;Lo;0;L;;;;;N;;;;; +16A33;BAMUM LETTER PHASE-F MO;Lo;0;L;;;;;N;;;;; +16A34;BAMUM LETTER PHASE-F MBAA;Lo;0;L;;;;;N;;;;; +16A35;BAMUM LETTER PHASE-F TET;Lo;0;L;;;;;N;;;;; +16A36;BAMUM LETTER PHASE-F KPA;Lo;0;L;;;;;N;;;;; +16A37;BAMUM LETTER PHASE-F SAMBA;Lo;0;L;;;;;N;;;;; +16A38;BAMUM LETTER PHASE-F VUEQ;Lo;0;L;;;;;N;;;;; +16A40;MRO LETTER TA;Lo;0;L;;;;;N;;;;; +16A41;MRO LETTER NGI;Lo;0;L;;;;;N;;;;; +16A42;MRO LETTER YO;Lo;0;L;;;;;N;;;;; +16A43;MRO LETTER MIM;Lo;0;L;;;;;N;;;;; +16A44;MRO LETTER BA;Lo;0;L;;;;;N;;;;; +16A45;MRO LETTER DA;Lo;0;L;;;;;N;;;;; +16A46;MRO LETTER A;Lo;0;L;;;;;N;;;;; +16A47;MRO LETTER PHI;Lo;0;L;;;;;N;;;;; +16A48;MRO LETTER KHAI;Lo;0;L;;;;;N;;;;; +16A49;MRO LETTER HAO;Lo;0;L;;;;;N;;;;; +16A4A;MRO LETTER DAI;Lo;0;L;;;;;N;;;;; +16A4B;MRO LETTER CHU;Lo;0;L;;;;;N;;;;; +16A4C;MRO LETTER KEAAE;Lo;0;L;;;;;N;;;;; +16A4D;MRO LETTER OL;Lo;0;L;;;;;N;;;;; +16A4E;MRO LETTER MAEM;Lo;0;L;;;;;N;;;;; +16A4F;MRO LETTER NIN;Lo;0;L;;;;;N;;;;; +16A50;MRO LETTER PA;Lo;0;L;;;;;N;;;;; +16A51;MRO LETTER OO;Lo;0;L;;;;;N;;;;; +16A52;MRO LETTER O;Lo;0;L;;;;;N;;;;; +16A53;MRO LETTER RO;Lo;0;L;;;;;N;;;;; +16A54;MRO LETTER SHI;Lo;0;L;;;;;N;;;;; +16A55;MRO LETTER THEA;Lo;0;L;;;;;N;;;;; +16A56;MRO LETTER EA;Lo;0;L;;;;;N;;;;; +16A57;MRO LETTER WA;Lo;0;L;;;;;N;;;;; +16A58;MRO LETTER E;Lo;0;L;;;;;N;;;;; +16A59;MRO LETTER KO;Lo;0;L;;;;;N;;;;; +16A5A;MRO LETTER LAN;Lo;0;L;;;;;N;;;;; +16A5B;MRO LETTER LA;Lo;0;L;;;;;N;;;;; +16A5C;MRO LETTER HAI;Lo;0;L;;;;;N;;;;; +16A5D;MRO LETTER RI;Lo;0;L;;;;;N;;;;; +16A5E;MRO LETTER TEK;Lo;0;L;;;;;N;;;;; +16A60;MRO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +16A61;MRO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +16A62;MRO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +16A63;MRO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +16A64;MRO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +16A65;MRO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +16A66;MRO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +16A67;MRO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +16A68;MRO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +16A69;MRO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +16A6E;MRO DANDA;Po;0;L;;;;;N;;;;; +16A6F;MRO DOUBLE DANDA;Po;0;L;;;;;N;;;;; +16AD0;BASSA VAH LETTER ENNI;Lo;0;L;;;;;N;;;;; +16AD1;BASSA VAH LETTER KA;Lo;0;L;;;;;N;;;;; +16AD2;BASSA VAH LETTER SE;Lo;0;L;;;;;N;;;;; +16AD3;BASSA VAH LETTER FA;Lo;0;L;;;;;N;;;;; +16AD4;BASSA VAH LETTER MBE;Lo;0;L;;;;;N;;;;; +16AD5;BASSA VAH LETTER YIE;Lo;0;L;;;;;N;;;;; +16AD6;BASSA VAH LETTER GAH;Lo;0;L;;;;;N;;;;; +16AD7;BASSA VAH LETTER DHII;Lo;0;L;;;;;N;;;;; +16AD8;BASSA VAH LETTER KPAH;Lo;0;L;;;;;N;;;;; +16AD9;BASSA VAH LETTER JO;Lo;0;L;;;;;N;;;;; +16ADA;BASSA VAH LETTER HWAH;Lo;0;L;;;;;N;;;;; +16ADB;BASSA VAH LETTER WA;Lo;0;L;;;;;N;;;;; +16ADC;BASSA VAH LETTER ZO;Lo;0;L;;;;;N;;;;; +16ADD;BASSA VAH LETTER GBU;Lo;0;L;;;;;N;;;;; +16ADE;BASSA VAH LETTER DO;Lo;0;L;;;;;N;;;;; +16ADF;BASSA VAH LETTER CE;Lo;0;L;;;;;N;;;;; +16AE0;BASSA VAH LETTER UWU;Lo;0;L;;;;;N;;;;; +16AE1;BASSA VAH LETTER TO;Lo;0;L;;;;;N;;;;; +16AE2;BASSA VAH LETTER BA;Lo;0;L;;;;;N;;;;; +16AE3;BASSA VAH LETTER VU;Lo;0;L;;;;;N;;;;; +16AE4;BASSA VAH LETTER YEIN;Lo;0;L;;;;;N;;;;; +16AE5;BASSA VAH LETTER PA;Lo;0;L;;;;;N;;;;; +16AE6;BASSA VAH LETTER WADDA;Lo;0;L;;;;;N;;;;; +16AE7;BASSA VAH LETTER A;Lo;0;L;;;;;N;;;;; +16AE8;BASSA VAH LETTER O;Lo;0;L;;;;;N;;;;; +16AE9;BASSA VAH LETTER OO;Lo;0;L;;;;;N;;;;; +16AEA;BASSA VAH LETTER U;Lo;0;L;;;;;N;;;;; +16AEB;BASSA VAH LETTER EE;Lo;0;L;;;;;N;;;;; +16AEC;BASSA VAH LETTER E;Lo;0;L;;;;;N;;;;; +16AED;BASSA VAH LETTER I;Lo;0;L;;;;;N;;;;; +16AF0;BASSA VAH COMBINING HIGH TONE;Mn;1;NSM;;;;;N;;;;; +16AF1;BASSA VAH COMBINING LOW TONE;Mn;1;NSM;;;;;N;;;;; +16AF2;BASSA VAH COMBINING MID TONE;Mn;1;NSM;;;;;N;;;;; +16AF3;BASSA VAH COMBINING LOW-MID TONE;Mn;1;NSM;;;;;N;;;;; +16AF4;BASSA VAH COMBINING HIGH-LOW TONE;Mn;1;NSM;;;;;N;;;;; +16AF5;BASSA VAH FULL STOP;Po;0;L;;;;;N;;;;; +16B00;PAHAWH HMONG VOWEL KEEB;Lo;0;L;;;;;N;;;;; +16B01;PAHAWH HMONG VOWEL KEEV;Lo;0;L;;;;;N;;;;; +16B02;PAHAWH HMONG VOWEL KIB;Lo;0;L;;;;;N;;;;; +16B03;PAHAWH HMONG VOWEL KIV;Lo;0;L;;;;;N;;;;; +16B04;PAHAWH HMONG VOWEL KAUB;Lo;0;L;;;;;N;;;;; +16B05;PAHAWH HMONG VOWEL KAUV;Lo;0;L;;;;;N;;;;; +16B06;PAHAWH HMONG VOWEL KUB;Lo;0;L;;;;;N;;;;; +16B07;PAHAWH HMONG VOWEL KUV;Lo;0;L;;;;;N;;;;; +16B08;PAHAWH HMONG VOWEL KEB;Lo;0;L;;;;;N;;;;; +16B09;PAHAWH HMONG VOWEL KEV;Lo;0;L;;;;;N;;;;; +16B0A;PAHAWH HMONG VOWEL KAIB;Lo;0;L;;;;;N;;;;; +16B0B;PAHAWH HMONG VOWEL KAIV;Lo;0;L;;;;;N;;;;; +16B0C;PAHAWH HMONG VOWEL KOOB;Lo;0;L;;;;;N;;;;; +16B0D;PAHAWH HMONG VOWEL KOOV;Lo;0;L;;;;;N;;;;; +16B0E;PAHAWH HMONG VOWEL KAWB;Lo;0;L;;;;;N;;;;; +16B0F;PAHAWH HMONG VOWEL KAWV;Lo;0;L;;;;;N;;;;; +16B10;PAHAWH HMONG VOWEL KUAB;Lo;0;L;;;;;N;;;;; +16B11;PAHAWH HMONG VOWEL KUAV;Lo;0;L;;;;;N;;;;; +16B12;PAHAWH HMONG VOWEL KOB;Lo;0;L;;;;;N;;;;; +16B13;PAHAWH HMONG VOWEL KOV;Lo;0;L;;;;;N;;;;; +16B14;PAHAWH HMONG VOWEL KIAB;Lo;0;L;;;;;N;;;;; +16B15;PAHAWH HMONG VOWEL KIAV;Lo;0;L;;;;;N;;;;; +16B16;PAHAWH HMONG VOWEL KAB;Lo;0;L;;;;;N;;;;; +16B17;PAHAWH HMONG VOWEL KAV;Lo;0;L;;;;;N;;;;; +16B18;PAHAWH HMONG VOWEL KWB;Lo;0;L;;;;;N;;;;; +16B19;PAHAWH HMONG VOWEL KWV;Lo;0;L;;;;;N;;;;; +16B1A;PAHAWH HMONG VOWEL KAAB;Lo;0;L;;;;;N;;;;; +16B1B;PAHAWH HMONG VOWEL KAAV;Lo;0;L;;;;;N;;;;; +16B1C;PAHAWH HMONG CONSONANT VAU;Lo;0;L;;;;;N;;;;; +16B1D;PAHAWH HMONG CONSONANT NTSAU;Lo;0;L;;;;;N;;;;; +16B1E;PAHAWH HMONG CONSONANT LAU;Lo;0;L;;;;;N;;;;; +16B1F;PAHAWH HMONG CONSONANT HAU;Lo;0;L;;;;;N;;;;; +16B20;PAHAWH HMONG CONSONANT NLAU;Lo;0;L;;;;;N;;;;; +16B21;PAHAWH HMONG CONSONANT RAU;Lo;0;L;;;;;N;;;;; +16B22;PAHAWH HMONG CONSONANT NKAU;Lo;0;L;;;;;N;;;;; +16B23;PAHAWH HMONG CONSONANT QHAU;Lo;0;L;;;;;N;;;;; +16B24;PAHAWH HMONG CONSONANT YAU;Lo;0;L;;;;;N;;;;; +16B25;PAHAWH HMONG CONSONANT HLAU;Lo;0;L;;;;;N;;;;; +16B26;PAHAWH HMONG CONSONANT MAU;Lo;0;L;;;;;N;;;;; +16B27;PAHAWH HMONG CONSONANT CHAU;Lo;0;L;;;;;N;;;;; +16B28;PAHAWH HMONG CONSONANT NCHAU;Lo;0;L;;;;;N;;;;; +16B29;PAHAWH HMONG CONSONANT HNAU;Lo;0;L;;;;;N;;;;; +16B2A;PAHAWH HMONG CONSONANT PLHAU;Lo;0;L;;;;;N;;;;; +16B2B;PAHAWH HMONG CONSONANT NTHAU;Lo;0;L;;;;;N;;;;; +16B2C;PAHAWH HMONG CONSONANT NAU;Lo;0;L;;;;;N;;;;; +16B2D;PAHAWH HMONG CONSONANT AU;Lo;0;L;;;;;N;;;;; +16B2E;PAHAWH HMONG CONSONANT XAU;Lo;0;L;;;;;N;;;;; +16B2F;PAHAWH HMONG CONSONANT CAU;Lo;0;L;;;;;N;;;;; +16B30;PAHAWH HMONG MARK CIM TUB;Mn;230;NSM;;;;;N;;;;; +16B31;PAHAWH HMONG MARK CIM SO;Mn;230;NSM;;;;;N;;;;; +16B32;PAHAWH HMONG MARK CIM KES;Mn;230;NSM;;;;;N;;;;; +16B33;PAHAWH HMONG MARK CIM KHAV;Mn;230;NSM;;;;;N;;;;; +16B34;PAHAWH HMONG MARK CIM SUAM;Mn;230;NSM;;;;;N;;;;; +16B35;PAHAWH HMONG MARK CIM HOM;Mn;230;NSM;;;;;N;;;;; +16B36;PAHAWH HMONG MARK CIM TAUM;Mn;230;NSM;;;;;N;;;;; +16B37;PAHAWH HMONG SIGN VOS THOM;Po;0;L;;;;;N;;;;; +16B38;PAHAWH HMONG SIGN VOS TSHAB CEEB;Po;0;L;;;;;N;;;;; +16B39;PAHAWH HMONG SIGN CIM CHEEM;Po;0;L;;;;;N;;;;; +16B3A;PAHAWH HMONG SIGN VOS THIAB;Po;0;L;;;;;N;;;;; +16B3B;PAHAWH HMONG SIGN VOS FEEM;Po;0;L;;;;;N;;;;; +16B3C;PAHAWH HMONG SIGN XYEEM NTXIV;So;0;L;;;;;N;;;;; +16B3D;PAHAWH HMONG SIGN XYEEM RHO;So;0;L;;;;;N;;;;; +16B3E;PAHAWH HMONG SIGN XYEEM TOV;So;0;L;;;;;N;;;;; +16B3F;PAHAWH HMONG SIGN XYEEM FAIB;So;0;L;;;;;N;;;;; +16B40;PAHAWH HMONG SIGN VOS SEEV;Lm;0;L;;;;;N;;;;; +16B41;PAHAWH HMONG SIGN MEEJ SUAB;Lm;0;L;;;;;N;;;;; +16B42;PAHAWH HMONG SIGN VOS NRUA;Lm;0;L;;;;;N;;;;; +16B43;PAHAWH HMONG SIGN IB YAM;Lm;0;L;;;;;N;;;;; +16B44;PAHAWH HMONG SIGN XAUS;Po;0;L;;;;;N;;;;; +16B45;PAHAWH HMONG SIGN CIM TSOV ROG;So;0;L;;;;;N;;;;; +16B50;PAHAWH HMONG DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +16B51;PAHAWH HMONG DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +16B52;PAHAWH HMONG DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +16B53;PAHAWH HMONG DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +16B54;PAHAWH HMONG DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +16B55;PAHAWH HMONG DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +16B56;PAHAWH HMONG DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +16B57;PAHAWH HMONG DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +16B58;PAHAWH HMONG DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +16B59;PAHAWH HMONG DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +16B5B;PAHAWH HMONG NUMBER TENS;No;0;L;;;;10;N;;;;; +16B5C;PAHAWH HMONG NUMBER HUNDREDS;No;0;L;;;;100;N;;;;; +16B5D;PAHAWH HMONG NUMBER TEN THOUSANDS;No;0;L;;;;10000;N;;;;; +16B5E;PAHAWH HMONG NUMBER MILLIONS;No;0;L;;;;1000000;N;;;;; +16B5F;PAHAWH HMONG NUMBER HUNDRED MILLIONS;No;0;L;;;;100000000;N;;;;; +16B60;PAHAWH HMONG NUMBER TEN BILLIONS;No;0;L;;;;10000000000;N;;;;; +16B61;PAHAWH HMONG NUMBER TRILLIONS;No;0;L;;;;1000000000000;N;;;;; +16B63;PAHAWH HMONG SIGN VOS LUB;Lo;0;L;;;;;N;;;;; +16B64;PAHAWH HMONG SIGN XYOO;Lo;0;L;;;;;N;;;;; +16B65;PAHAWH HMONG SIGN HLI;Lo;0;L;;;;;N;;;;; +16B66;PAHAWH HMONG SIGN THIRD-STAGE HLI;Lo;0;L;;;;;N;;;;; +16B67;PAHAWH HMONG SIGN ZWJ THAJ;Lo;0;L;;;;;N;;;;; +16B68;PAHAWH HMONG SIGN HNUB;Lo;0;L;;;;;N;;;;; +16B69;PAHAWH HMONG SIGN NQIG;Lo;0;L;;;;;N;;;;; +16B6A;PAHAWH HMONG SIGN XIAB;Lo;0;L;;;;;N;;;;; +16B6B;PAHAWH HMONG SIGN NTUJ;Lo;0;L;;;;;N;;;;; +16B6C;PAHAWH HMONG SIGN AV;Lo;0;L;;;;;N;;;;; +16B6D;PAHAWH HMONG SIGN TXHEEJ CEEV;Lo;0;L;;;;;N;;;;; +16B6E;PAHAWH HMONG SIGN MEEJ TSEEB;Lo;0;L;;;;;N;;;;; +16B6F;PAHAWH HMONG SIGN TAU;Lo;0;L;;;;;N;;;;; +16B70;PAHAWH HMONG SIGN LOS;Lo;0;L;;;;;N;;;;; +16B71;PAHAWH HMONG SIGN MUS;Lo;0;L;;;;;N;;;;; +16B72;PAHAWH HMONG SIGN CIM HAIS LUS NTOG NTOG;Lo;0;L;;;;;N;;;;; +16B73;PAHAWH HMONG SIGN CIM CUAM TSHOOJ;Lo;0;L;;;;;N;;;;; +16B74;PAHAWH HMONG SIGN CIM TXWV;Lo;0;L;;;;;N;;;;; +16B75;PAHAWH HMONG SIGN CIM TXWV CHWV;Lo;0;L;;;;;N;;;;; +16B76;PAHAWH HMONG SIGN CIM PUB DAWB;Lo;0;L;;;;;N;;;;; +16B77;PAHAWH HMONG SIGN CIM NRES TOS;Lo;0;L;;;;;N;;;;; +16B7D;PAHAWH HMONG CLAN SIGN TSHEEJ;Lo;0;L;;;;;N;;;;; +16B7E;PAHAWH HMONG CLAN SIGN YEEG;Lo;0;L;;;;;N;;;;; +16B7F;PAHAWH HMONG CLAN SIGN LIS;Lo;0;L;;;;;N;;;;; +16B80;PAHAWH HMONG CLAN SIGN LAUJ;Lo;0;L;;;;;N;;;;; +16B81;PAHAWH HMONG CLAN SIGN XYOOJ;Lo;0;L;;;;;N;;;;; +16B82;PAHAWH HMONG CLAN SIGN KOO;Lo;0;L;;;;;N;;;;; +16B83;PAHAWH HMONG CLAN SIGN HAWJ;Lo;0;L;;;;;N;;;;; +16B84;PAHAWH HMONG CLAN SIGN MUAS;Lo;0;L;;;;;N;;;;; +16B85;PAHAWH HMONG CLAN SIGN THOJ;Lo;0;L;;;;;N;;;;; +16B86;PAHAWH HMONG CLAN SIGN TSAB;Lo;0;L;;;;;N;;;;; +16B87;PAHAWH HMONG CLAN SIGN PHAB;Lo;0;L;;;;;N;;;;; +16B88;PAHAWH HMONG CLAN SIGN KHAB;Lo;0;L;;;;;N;;;;; +16B89;PAHAWH HMONG CLAN SIGN HAM;Lo;0;L;;;;;N;;;;; +16B8A;PAHAWH HMONG CLAN SIGN VAJ;Lo;0;L;;;;;N;;;;; +16B8B;PAHAWH HMONG CLAN SIGN FAJ;Lo;0;L;;;;;N;;;;; +16B8C;PAHAWH HMONG CLAN SIGN YAJ;Lo;0;L;;;;;N;;;;; +16B8D;PAHAWH HMONG CLAN SIGN TSWB;Lo;0;L;;;;;N;;;;; +16B8E;PAHAWH HMONG CLAN SIGN KWM;Lo;0;L;;;;;N;;;;; +16B8F;PAHAWH HMONG CLAN SIGN VWJ;Lo;0;L;;;;;N;;;;; +16E40;MEDEFAIDRIN CAPITAL LETTER M;Lu;0;L;;;;;N;;;;16E60; +16E41;MEDEFAIDRIN CAPITAL LETTER S;Lu;0;L;;;;;N;;;;16E61; +16E42;MEDEFAIDRIN CAPITAL LETTER V;Lu;0;L;;;;;N;;;;16E62; +16E43;MEDEFAIDRIN CAPITAL LETTER W;Lu;0;L;;;;;N;;;;16E63; +16E44;MEDEFAIDRIN CAPITAL LETTER ATIU;Lu;0;L;;;;;N;;;;16E64; +16E45;MEDEFAIDRIN CAPITAL LETTER Z;Lu;0;L;;;;;N;;;;16E65; +16E46;MEDEFAIDRIN CAPITAL LETTER KP;Lu;0;L;;;;;N;;;;16E66; +16E47;MEDEFAIDRIN CAPITAL LETTER P;Lu;0;L;;;;;N;;;;16E67; +16E48;MEDEFAIDRIN CAPITAL LETTER T;Lu;0;L;;;;;N;;;;16E68; +16E49;MEDEFAIDRIN CAPITAL LETTER G;Lu;0;L;;;;;N;;;;16E69; +16E4A;MEDEFAIDRIN CAPITAL LETTER F;Lu;0;L;;;;;N;;;;16E6A; +16E4B;MEDEFAIDRIN CAPITAL LETTER I;Lu;0;L;;;;;N;;;;16E6B; +16E4C;MEDEFAIDRIN CAPITAL LETTER K;Lu;0;L;;;;;N;;;;16E6C; +16E4D;MEDEFAIDRIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;16E6D; +16E4E;MEDEFAIDRIN CAPITAL LETTER J;Lu;0;L;;;;;N;;;;16E6E; +16E4F;MEDEFAIDRIN CAPITAL LETTER E;Lu;0;L;;;;;N;;;;16E6F; +16E50;MEDEFAIDRIN CAPITAL LETTER B;Lu;0;L;;;;;N;;;;16E70; +16E51;MEDEFAIDRIN CAPITAL LETTER C;Lu;0;L;;;;;N;;;;16E71; +16E52;MEDEFAIDRIN CAPITAL LETTER U;Lu;0;L;;;;;N;;;;16E72; +16E53;MEDEFAIDRIN CAPITAL LETTER YU;Lu;0;L;;;;;N;;;;16E73; +16E54;MEDEFAIDRIN CAPITAL LETTER L;Lu;0;L;;;;;N;;;;16E74; +16E55;MEDEFAIDRIN CAPITAL LETTER Q;Lu;0;L;;;;;N;;;;16E75; +16E56;MEDEFAIDRIN CAPITAL LETTER HP;Lu;0;L;;;;;N;;;;16E76; +16E57;MEDEFAIDRIN CAPITAL LETTER NY;Lu;0;L;;;;;N;;;;16E77; +16E58;MEDEFAIDRIN CAPITAL LETTER X;Lu;0;L;;;;;N;;;;16E78; +16E59;MEDEFAIDRIN CAPITAL LETTER D;Lu;0;L;;;;;N;;;;16E79; +16E5A;MEDEFAIDRIN CAPITAL LETTER OE;Lu;0;L;;;;;N;;;;16E7A; +16E5B;MEDEFAIDRIN CAPITAL LETTER N;Lu;0;L;;;;;N;;;;16E7B; +16E5C;MEDEFAIDRIN CAPITAL LETTER R;Lu;0;L;;;;;N;;;;16E7C; +16E5D;MEDEFAIDRIN CAPITAL LETTER O;Lu;0;L;;;;;N;;;;16E7D; +16E5E;MEDEFAIDRIN CAPITAL LETTER AI;Lu;0;L;;;;;N;;;;16E7E; +16E5F;MEDEFAIDRIN CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;16E7F; +16E60;MEDEFAIDRIN SMALL LETTER M;Ll;0;L;;;;;N;;;16E40;;16E40 +16E61;MEDEFAIDRIN SMALL LETTER S;Ll;0;L;;;;;N;;;16E41;;16E41 +16E62;MEDEFAIDRIN SMALL LETTER V;Ll;0;L;;;;;N;;;16E42;;16E42 +16E63;MEDEFAIDRIN SMALL LETTER W;Ll;0;L;;;;;N;;;16E43;;16E43 +16E64;MEDEFAIDRIN SMALL LETTER ATIU;Ll;0;L;;;;;N;;;16E44;;16E44 +16E65;MEDEFAIDRIN SMALL LETTER Z;Ll;0;L;;;;;N;;;16E45;;16E45 +16E66;MEDEFAIDRIN SMALL LETTER KP;Ll;0;L;;;;;N;;;16E46;;16E46 +16E67;MEDEFAIDRIN SMALL LETTER P;Ll;0;L;;;;;N;;;16E47;;16E47 +16E68;MEDEFAIDRIN SMALL LETTER T;Ll;0;L;;;;;N;;;16E48;;16E48 +16E69;MEDEFAIDRIN SMALL LETTER G;Ll;0;L;;;;;N;;;16E49;;16E49 +16E6A;MEDEFAIDRIN SMALL LETTER F;Ll;0;L;;;;;N;;;16E4A;;16E4A +16E6B;MEDEFAIDRIN SMALL LETTER I;Ll;0;L;;;;;N;;;16E4B;;16E4B +16E6C;MEDEFAIDRIN SMALL LETTER K;Ll;0;L;;;;;N;;;16E4C;;16E4C +16E6D;MEDEFAIDRIN SMALL LETTER A;Ll;0;L;;;;;N;;;16E4D;;16E4D +16E6E;MEDEFAIDRIN SMALL LETTER J;Ll;0;L;;;;;N;;;16E4E;;16E4E +16E6F;MEDEFAIDRIN SMALL LETTER E;Ll;0;L;;;;;N;;;16E4F;;16E4F +16E70;MEDEFAIDRIN SMALL LETTER B;Ll;0;L;;;;;N;;;16E50;;16E50 +16E71;MEDEFAIDRIN SMALL LETTER C;Ll;0;L;;;;;N;;;16E51;;16E51 +16E72;MEDEFAIDRIN SMALL LETTER U;Ll;0;L;;;;;N;;;16E52;;16E52 +16E73;MEDEFAIDRIN SMALL LETTER YU;Ll;0;L;;;;;N;;;16E53;;16E53 +16E74;MEDEFAIDRIN SMALL LETTER L;Ll;0;L;;;;;N;;;16E54;;16E54 +16E75;MEDEFAIDRIN SMALL LETTER Q;Ll;0;L;;;;;N;;;16E55;;16E55 +16E76;MEDEFAIDRIN SMALL LETTER HP;Ll;0;L;;;;;N;;;16E56;;16E56 +16E77;MEDEFAIDRIN SMALL LETTER NY;Ll;0;L;;;;;N;;;16E57;;16E57 +16E78;MEDEFAIDRIN SMALL LETTER X;Ll;0;L;;;;;N;;;16E58;;16E58 +16E79;MEDEFAIDRIN SMALL LETTER D;Ll;0;L;;;;;N;;;16E59;;16E59 +16E7A;MEDEFAIDRIN SMALL LETTER OE;Ll;0;L;;;;;N;;;16E5A;;16E5A +16E7B;MEDEFAIDRIN SMALL LETTER N;Ll;0;L;;;;;N;;;16E5B;;16E5B +16E7C;MEDEFAIDRIN SMALL LETTER R;Ll;0;L;;;;;N;;;16E5C;;16E5C +16E7D;MEDEFAIDRIN SMALL LETTER O;Ll;0;L;;;;;N;;;16E5D;;16E5D +16E7E;MEDEFAIDRIN SMALL LETTER AI;Ll;0;L;;;;;N;;;16E5E;;16E5E +16E7F;MEDEFAIDRIN SMALL LETTER Y;Ll;0;L;;;;;N;;;16E5F;;16E5F +16E80;MEDEFAIDRIN DIGIT ZERO;No;0;L;;;;0;N;;;;; +16E81;MEDEFAIDRIN DIGIT ONE;No;0;L;;;;1;N;;;;; +16E82;MEDEFAIDRIN DIGIT TWO;No;0;L;;;;2;N;;;;; +16E83;MEDEFAIDRIN DIGIT THREE;No;0;L;;;;3;N;;;;; +16E84;MEDEFAIDRIN DIGIT FOUR;No;0;L;;;;4;N;;;;; +16E85;MEDEFAIDRIN DIGIT FIVE;No;0;L;;;;5;N;;;;; +16E86;MEDEFAIDRIN DIGIT SIX;No;0;L;;;;6;N;;;;; +16E87;MEDEFAIDRIN DIGIT SEVEN;No;0;L;;;;7;N;;;;; +16E88;MEDEFAIDRIN DIGIT EIGHT;No;0;L;;;;8;N;;;;; +16E89;MEDEFAIDRIN DIGIT NINE;No;0;L;;;;9;N;;;;; +16E8A;MEDEFAIDRIN NUMBER TEN;No;0;L;;;;10;N;;;;; +16E8B;MEDEFAIDRIN NUMBER ELEVEN;No;0;L;;;;11;N;;;;; +16E8C;MEDEFAIDRIN NUMBER TWELVE;No;0;L;;;;12;N;;;;; +16E8D;MEDEFAIDRIN NUMBER THIRTEEN;No;0;L;;;;13;N;;;;; +16E8E;MEDEFAIDRIN NUMBER FOURTEEN;No;0;L;;;;14;N;;;;; +16E8F;MEDEFAIDRIN NUMBER FIFTEEN;No;0;L;;;;15;N;;;;; +16E90;MEDEFAIDRIN NUMBER SIXTEEN;No;0;L;;;;16;N;;;;; +16E91;MEDEFAIDRIN NUMBER SEVENTEEN;No;0;L;;;;17;N;;;;; +16E92;MEDEFAIDRIN NUMBER EIGHTEEN;No;0;L;;;;18;N;;;;; +16E93;MEDEFAIDRIN NUMBER NINETEEN;No;0;L;;;;19;N;;;;; +16E94;MEDEFAIDRIN DIGIT ONE ALTERNATE FORM;No;0;L;;;;1;N;;;;; +16E95;MEDEFAIDRIN DIGIT TWO ALTERNATE FORM;No;0;L;;;;2;N;;;;; +16E96;MEDEFAIDRIN DIGIT THREE ALTERNATE FORM;No;0;L;;;;3;N;;;;; +16E97;MEDEFAIDRIN COMMA;Po;0;L;;;;;N;;;;; +16E98;MEDEFAIDRIN FULL STOP;Po;0;L;;;;;N;;;;; +16E99;MEDEFAIDRIN SYMBOL AIVA;Po;0;L;;;;;N;;;;; +16E9A;MEDEFAIDRIN EXCLAMATION OH;Po;0;L;;;;;N;;;;; +16F00;MIAO LETTER PA;Lo;0;L;;;;;N;;;;; +16F01;MIAO LETTER BA;Lo;0;L;;;;;N;;;;; +16F02;MIAO LETTER YI PA;Lo;0;L;;;;;N;;;;; +16F03;MIAO LETTER PLA;Lo;0;L;;;;;N;;;;; +16F04;MIAO LETTER MA;Lo;0;L;;;;;N;;;;; +16F05;MIAO LETTER MHA;Lo;0;L;;;;;N;;;;; +16F06;MIAO LETTER ARCHAIC MA;Lo;0;L;;;;;N;;;;; +16F07;MIAO LETTER FA;Lo;0;L;;;;;N;;;;; +16F08;MIAO LETTER VA;Lo;0;L;;;;;N;;;;; +16F09;MIAO LETTER VFA;Lo;0;L;;;;;N;;;;; +16F0A;MIAO LETTER TA;Lo;0;L;;;;;N;;;;; +16F0B;MIAO LETTER DA;Lo;0;L;;;;;N;;;;; +16F0C;MIAO LETTER YI TTA;Lo;0;L;;;;;N;;;;; +16F0D;MIAO LETTER YI TA;Lo;0;L;;;;;N;;;;; +16F0E;MIAO LETTER TTA;Lo;0;L;;;;;N;;;;; +16F0F;MIAO LETTER DDA;Lo;0;L;;;;;N;;;;; +16F10;MIAO LETTER NA;Lo;0;L;;;;;N;;;;; +16F11;MIAO LETTER NHA;Lo;0;L;;;;;N;;;;; +16F12;MIAO LETTER YI NNA;Lo;0;L;;;;;N;;;;; +16F13;MIAO LETTER ARCHAIC NA;Lo;0;L;;;;;N;;;;; +16F14;MIAO LETTER NNA;Lo;0;L;;;;;N;;;;; +16F15;MIAO LETTER NNHA;Lo;0;L;;;;;N;;;;; +16F16;MIAO LETTER LA;Lo;0;L;;;;;N;;;;; +16F17;MIAO LETTER LYA;Lo;0;L;;;;;N;;;;; +16F18;MIAO LETTER LHA;Lo;0;L;;;;;N;;;;; +16F19;MIAO LETTER LHYA;Lo;0;L;;;;;N;;;;; +16F1A;MIAO LETTER TLHA;Lo;0;L;;;;;N;;;;; +16F1B;MIAO LETTER DLHA;Lo;0;L;;;;;N;;;;; +16F1C;MIAO LETTER TLHYA;Lo;0;L;;;;;N;;;;; +16F1D;MIAO LETTER DLHYA;Lo;0;L;;;;;N;;;;; +16F1E;MIAO LETTER KA;Lo;0;L;;;;;N;;;;; +16F1F;MIAO LETTER GA;Lo;0;L;;;;;N;;;;; +16F20;MIAO LETTER YI KA;Lo;0;L;;;;;N;;;;; +16F21;MIAO LETTER QA;Lo;0;L;;;;;N;;;;; +16F22;MIAO LETTER QGA;Lo;0;L;;;;;N;;;;; +16F23;MIAO LETTER NGA;Lo;0;L;;;;;N;;;;; +16F24;MIAO LETTER NGHA;Lo;0;L;;;;;N;;;;; +16F25;MIAO LETTER ARCHAIC NGA;Lo;0;L;;;;;N;;;;; +16F26;MIAO LETTER HA;Lo;0;L;;;;;N;;;;; +16F27;MIAO LETTER XA;Lo;0;L;;;;;N;;;;; +16F28;MIAO LETTER GHA;Lo;0;L;;;;;N;;;;; +16F29;MIAO LETTER GHHA;Lo;0;L;;;;;N;;;;; +16F2A;MIAO LETTER TSSA;Lo;0;L;;;;;N;;;;; +16F2B;MIAO LETTER DZZA;Lo;0;L;;;;;N;;;;; +16F2C;MIAO LETTER NYA;Lo;0;L;;;;;N;;;;; +16F2D;MIAO LETTER NYHA;Lo;0;L;;;;;N;;;;; +16F2E;MIAO LETTER TSHA;Lo;0;L;;;;;N;;;;; +16F2F;MIAO LETTER DZHA;Lo;0;L;;;;;N;;;;; +16F30;MIAO LETTER YI TSHA;Lo;0;L;;;;;N;;;;; +16F31;MIAO LETTER YI DZHA;Lo;0;L;;;;;N;;;;; +16F32;MIAO LETTER REFORMED TSHA;Lo;0;L;;;;;N;;;;; +16F33;MIAO LETTER SHA;Lo;0;L;;;;;N;;;;; +16F34;MIAO LETTER SSA;Lo;0;L;;;;;N;;;;; +16F35;MIAO LETTER ZHA;Lo;0;L;;;;;N;;;;; +16F36;MIAO LETTER ZSHA;Lo;0;L;;;;;N;;;;; +16F37;MIAO LETTER TSA;Lo;0;L;;;;;N;;;;; +16F38;MIAO LETTER DZA;Lo;0;L;;;;;N;;;;; +16F39;MIAO LETTER YI TSA;Lo;0;L;;;;;N;;;;; +16F3A;MIAO LETTER SA;Lo;0;L;;;;;N;;;;; +16F3B;MIAO LETTER ZA;Lo;0;L;;;;;N;;;;; +16F3C;MIAO LETTER ZSA;Lo;0;L;;;;;N;;;;; +16F3D;MIAO LETTER ZZA;Lo;0;L;;;;;N;;;;; +16F3E;MIAO LETTER ZZSA;Lo;0;L;;;;;N;;;;; +16F3F;MIAO LETTER ARCHAIC ZZA;Lo;0;L;;;;;N;;;;; +16F40;MIAO LETTER ZZYA;Lo;0;L;;;;;N;;;;; +16F41;MIAO LETTER ZZSYA;Lo;0;L;;;;;N;;;;; +16F42;MIAO LETTER WA;Lo;0;L;;;;;N;;;;; +16F43;MIAO LETTER AH;Lo;0;L;;;;;N;;;;; +16F44;MIAO LETTER HHA;Lo;0;L;;;;;N;;;;; +16F45;MIAO LETTER BRI;Lo;0;L;;;;;N;;;;; +16F46;MIAO LETTER SYI;Lo;0;L;;;;;N;;;;; +16F47;MIAO LETTER DZYI;Lo;0;L;;;;;N;;;;; +16F48;MIAO LETTER TE;Lo;0;L;;;;;N;;;;; +16F49;MIAO LETTER TSE;Lo;0;L;;;;;N;;;;; +16F4A;MIAO LETTER RTE;Lo;0;L;;;;;N;;;;; +16F4F;MIAO SIGN CONSONANT MODIFIER BAR;Mn;0;NSM;;;;;N;;;;; +16F50;MIAO LETTER NASALIZATION;Lo;0;L;;;;;N;;;;; +16F51;MIAO SIGN ASPIRATION;Mc;0;L;;;;;N;;;;; +16F52;MIAO SIGN REFORMED VOICING;Mc;0;L;;;;;N;;;;; +16F53;MIAO SIGN REFORMED ASPIRATION;Mc;0;L;;;;;N;;;;; +16F54;MIAO VOWEL SIGN A;Mc;0;L;;;;;N;;;;; +16F55;MIAO VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +16F56;MIAO VOWEL SIGN AHH;Mc;0;L;;;;;N;;;;; +16F57;MIAO VOWEL SIGN AN;Mc;0;L;;;;;N;;;;; +16F58;MIAO VOWEL SIGN ANG;Mc;0;L;;;;;N;;;;; +16F59;MIAO VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +16F5A;MIAO VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +16F5B;MIAO VOWEL SIGN WO;Mc;0;L;;;;;N;;;;; +16F5C;MIAO VOWEL SIGN W;Mc;0;L;;;;;N;;;;; +16F5D;MIAO VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +16F5E;MIAO VOWEL SIGN EN;Mc;0;L;;;;;N;;;;; +16F5F;MIAO VOWEL SIGN ENG;Mc;0;L;;;;;N;;;;; +16F60;MIAO VOWEL SIGN OEY;Mc;0;L;;;;;N;;;;; +16F61;MIAO VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +16F62;MIAO VOWEL SIGN IA;Mc;0;L;;;;;N;;;;; +16F63;MIAO VOWEL SIGN IAN;Mc;0;L;;;;;N;;;;; +16F64;MIAO VOWEL SIGN IANG;Mc;0;L;;;;;N;;;;; +16F65;MIAO VOWEL SIGN IO;Mc;0;L;;;;;N;;;;; +16F66;MIAO VOWEL SIGN IE;Mc;0;L;;;;;N;;;;; +16F67;MIAO VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +16F68;MIAO VOWEL SIGN IU;Mc;0;L;;;;;N;;;;; +16F69;MIAO VOWEL SIGN ING;Mc;0;L;;;;;N;;;;; +16F6A;MIAO VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +16F6B;MIAO VOWEL SIGN UA;Mc;0;L;;;;;N;;;;; +16F6C;MIAO VOWEL SIGN UAN;Mc;0;L;;;;;N;;;;; +16F6D;MIAO VOWEL SIGN UANG;Mc;0;L;;;;;N;;;;; +16F6E;MIAO VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +16F6F;MIAO VOWEL SIGN UEI;Mc;0;L;;;;;N;;;;; +16F70;MIAO VOWEL SIGN UNG;Mc;0;L;;;;;N;;;;; +16F71;MIAO VOWEL SIGN Y;Mc;0;L;;;;;N;;;;; +16F72;MIAO VOWEL SIGN YI;Mc;0;L;;;;;N;;;;; +16F73;MIAO VOWEL SIGN AE;Mc;0;L;;;;;N;;;;; +16F74;MIAO VOWEL SIGN AEE;Mc;0;L;;;;;N;;;;; +16F75;MIAO VOWEL SIGN ERR;Mc;0;L;;;;;N;;;;; +16F76;MIAO VOWEL SIGN ROUNDED ERR;Mc;0;L;;;;;N;;;;; +16F77;MIAO VOWEL SIGN ER;Mc;0;L;;;;;N;;;;; +16F78;MIAO VOWEL SIGN ROUNDED ER;Mc;0;L;;;;;N;;;;; +16F79;MIAO VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +16F7A;MIAO VOWEL SIGN EI;Mc;0;L;;;;;N;;;;; +16F7B;MIAO VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +16F7C;MIAO VOWEL SIGN OU;Mc;0;L;;;;;N;;;;; +16F7D;MIAO VOWEL SIGN N;Mc;0;L;;;;;N;;;;; +16F7E;MIAO VOWEL SIGN NG;Mc;0;L;;;;;N;;;;; +16F7F;MIAO VOWEL SIGN UOG;Mc;0;L;;;;;N;;;;; +16F80;MIAO VOWEL SIGN YUI;Mc;0;L;;;;;N;;;;; +16F81;MIAO VOWEL SIGN OG;Mc;0;L;;;;;N;;;;; +16F82;MIAO VOWEL SIGN OER;Mc;0;L;;;;;N;;;;; +16F83;MIAO VOWEL SIGN VW;Mc;0;L;;;;;N;;;;; +16F84;MIAO VOWEL SIGN IG;Mc;0;L;;;;;N;;;;; +16F85;MIAO VOWEL SIGN EA;Mc;0;L;;;;;N;;;;; +16F86;MIAO VOWEL SIGN IONG;Mc;0;L;;;;;N;;;;; +16F87;MIAO VOWEL SIGN UI;Mc;0;L;;;;;N;;;;; +16F8F;MIAO TONE RIGHT;Mn;0;NSM;;;;;N;;;;; +16F90;MIAO TONE TOP RIGHT;Mn;0;NSM;;;;;N;;;;; +16F91;MIAO TONE ABOVE;Mn;0;NSM;;;;;N;;;;; +16F92;MIAO TONE BELOW;Mn;0;NSM;;;;;N;;;;; +16F93;MIAO LETTER TONE-2;Lm;0;L;;;;;N;;;;; +16F94;MIAO LETTER TONE-3;Lm;0;L;;;;;N;;;;; +16F95;MIAO LETTER TONE-4;Lm;0;L;;;;;N;;;;; +16F96;MIAO LETTER TONE-5;Lm;0;L;;;;;N;;;;; +16F97;MIAO LETTER TONE-6;Lm;0;L;;;;;N;;;;; +16F98;MIAO LETTER TONE-7;Lm;0;L;;;;;N;;;;; +16F99;MIAO LETTER TONE-8;Lm;0;L;;;;;N;;;;; +16F9A;MIAO LETTER REFORMED TONE-1;Lm;0;L;;;;;N;;;;; +16F9B;MIAO LETTER REFORMED TONE-2;Lm;0;L;;;;;N;;;;; +16F9C;MIAO LETTER REFORMED TONE-4;Lm;0;L;;;;;N;;;;; +16F9D;MIAO LETTER REFORMED TONE-5;Lm;0;L;;;;;N;;;;; +16F9E;MIAO LETTER REFORMED TONE-6;Lm;0;L;;;;;N;;;;; +16F9F;MIAO LETTER REFORMED TONE-8;Lm;0;L;;;;;N;;;;; +16FE0;TANGUT ITERATION MARK;Lm;0;L;;;;;N;;;;; +16FE1;NUSHU ITERATION MARK;Lm;0;L;;;;;N;;;;; +16FE2;OLD CHINESE HOOK MARK;Po;0;ON;;;;;N;;;;; +16FE3;OLD CHINESE ITERATION MARK;Lm;0;L;;;;;N;;;;; +17000;;Lo;0;L;;;;;N;;;;; +187F7;;Lo;0;L;;;;;N;;;;; +18800;TANGUT COMPONENT-001;Lo;0;L;;;;;N;;;;; +18801;TANGUT COMPONENT-002;Lo;0;L;;;;;N;;;;; +18802;TANGUT COMPONENT-003;Lo;0;L;;;;;N;;;;; +18803;TANGUT COMPONENT-004;Lo;0;L;;;;;N;;;;; +18804;TANGUT COMPONENT-005;Lo;0;L;;;;;N;;;;; +18805;TANGUT COMPONENT-006;Lo;0;L;;;;;N;;;;; +18806;TANGUT COMPONENT-007;Lo;0;L;;;;;N;;;;; +18807;TANGUT COMPONENT-008;Lo;0;L;;;;;N;;;;; +18808;TANGUT COMPONENT-009;Lo;0;L;;;;;N;;;;; +18809;TANGUT COMPONENT-010;Lo;0;L;;;;;N;;;;; +1880A;TANGUT COMPONENT-011;Lo;0;L;;;;;N;;;;; +1880B;TANGUT COMPONENT-012;Lo;0;L;;;;;N;;;;; +1880C;TANGUT COMPONENT-013;Lo;0;L;;;;;N;;;;; +1880D;TANGUT COMPONENT-014;Lo;0;L;;;;;N;;;;; +1880E;TANGUT COMPONENT-015;Lo;0;L;;;;;N;;;;; +1880F;TANGUT COMPONENT-016;Lo;0;L;;;;;N;;;;; +18810;TANGUT COMPONENT-017;Lo;0;L;;;;;N;;;;; +18811;TANGUT COMPONENT-018;Lo;0;L;;;;;N;;;;; +18812;TANGUT COMPONENT-019;Lo;0;L;;;;;N;;;;; +18813;TANGUT COMPONENT-020;Lo;0;L;;;;;N;;;;; +18814;TANGUT COMPONENT-021;Lo;0;L;;;;;N;;;;; +18815;TANGUT COMPONENT-022;Lo;0;L;;;;;N;;;;; +18816;TANGUT COMPONENT-023;Lo;0;L;;;;;N;;;;; +18817;TANGUT COMPONENT-024;Lo;0;L;;;;;N;;;;; +18818;TANGUT COMPONENT-025;Lo;0;L;;;;;N;;;;; +18819;TANGUT COMPONENT-026;Lo;0;L;;;;;N;;;;; +1881A;TANGUT COMPONENT-027;Lo;0;L;;;;;N;;;;; +1881B;TANGUT COMPONENT-028;Lo;0;L;;;;;N;;;;; +1881C;TANGUT COMPONENT-029;Lo;0;L;;;;;N;;;;; +1881D;TANGUT COMPONENT-030;Lo;0;L;;;;;N;;;;; +1881E;TANGUT COMPONENT-031;Lo;0;L;;;;;N;;;;; +1881F;TANGUT COMPONENT-032;Lo;0;L;;;;;N;;;;; +18820;TANGUT COMPONENT-033;Lo;0;L;;;;;N;;;;; +18821;TANGUT COMPONENT-034;Lo;0;L;;;;;N;;;;; +18822;TANGUT COMPONENT-035;Lo;0;L;;;;;N;;;;; +18823;TANGUT COMPONENT-036;Lo;0;L;;;;;N;;;;; +18824;TANGUT COMPONENT-037;Lo;0;L;;;;;N;;;;; +18825;TANGUT COMPONENT-038;Lo;0;L;;;;;N;;;;; +18826;TANGUT COMPONENT-039;Lo;0;L;;;;;N;;;;; +18827;TANGUT COMPONENT-040;Lo;0;L;;;;;N;;;;; +18828;TANGUT COMPONENT-041;Lo;0;L;;;;;N;;;;; +18829;TANGUT COMPONENT-042;Lo;0;L;;;;;N;;;;; +1882A;TANGUT COMPONENT-043;Lo;0;L;;;;;N;;;;; +1882B;TANGUT COMPONENT-044;Lo;0;L;;;;;N;;;;; +1882C;TANGUT COMPONENT-045;Lo;0;L;;;;;N;;;;; +1882D;TANGUT COMPONENT-046;Lo;0;L;;;;;N;;;;; +1882E;TANGUT COMPONENT-047;Lo;0;L;;;;;N;;;;; +1882F;TANGUT COMPONENT-048;Lo;0;L;;;;;N;;;;; +18830;TANGUT COMPONENT-049;Lo;0;L;;;;;N;;;;; +18831;TANGUT COMPONENT-050;Lo;0;L;;;;;N;;;;; +18832;TANGUT COMPONENT-051;Lo;0;L;;;;;N;;;;; +18833;TANGUT COMPONENT-052;Lo;0;L;;;;;N;;;;; +18834;TANGUT COMPONENT-053;Lo;0;L;;;;;N;;;;; +18835;TANGUT COMPONENT-054;Lo;0;L;;;;;N;;;;; +18836;TANGUT COMPONENT-055;Lo;0;L;;;;;N;;;;; +18837;TANGUT COMPONENT-056;Lo;0;L;;;;;N;;;;; +18838;TANGUT COMPONENT-057;Lo;0;L;;;;;N;;;;; +18839;TANGUT COMPONENT-058;Lo;0;L;;;;;N;;;;; +1883A;TANGUT COMPONENT-059;Lo;0;L;;;;;N;;;;; +1883B;TANGUT COMPONENT-060;Lo;0;L;;;;;N;;;;; +1883C;TANGUT COMPONENT-061;Lo;0;L;;;;;N;;;;; +1883D;TANGUT COMPONENT-062;Lo;0;L;;;;;N;;;;; +1883E;TANGUT COMPONENT-063;Lo;0;L;;;;;N;;;;; +1883F;TANGUT COMPONENT-064;Lo;0;L;;;;;N;;;;; +18840;TANGUT COMPONENT-065;Lo;0;L;;;;;N;;;;; +18841;TANGUT COMPONENT-066;Lo;0;L;;;;;N;;;;; +18842;TANGUT COMPONENT-067;Lo;0;L;;;;;N;;;;; +18843;TANGUT COMPONENT-068;Lo;0;L;;;;;N;;;;; +18844;TANGUT COMPONENT-069;Lo;0;L;;;;;N;;;;; +18845;TANGUT COMPONENT-070;Lo;0;L;;;;;N;;;;; +18846;TANGUT COMPONENT-071;Lo;0;L;;;;;N;;;;; +18847;TANGUT COMPONENT-072;Lo;0;L;;;;;N;;;;; +18848;TANGUT COMPONENT-073;Lo;0;L;;;;;N;;;;; +18849;TANGUT COMPONENT-074;Lo;0;L;;;;;N;;;;; +1884A;TANGUT COMPONENT-075;Lo;0;L;;;;;N;;;;; +1884B;TANGUT COMPONENT-076;Lo;0;L;;;;;N;;;;; +1884C;TANGUT COMPONENT-077;Lo;0;L;;;;;N;;;;; +1884D;TANGUT COMPONENT-078;Lo;0;L;;;;;N;;;;; +1884E;TANGUT COMPONENT-079;Lo;0;L;;;;;N;;;;; +1884F;TANGUT COMPONENT-080;Lo;0;L;;;;;N;;;;; +18850;TANGUT COMPONENT-081;Lo;0;L;;;;;N;;;;; +18851;TANGUT COMPONENT-082;Lo;0;L;;;;;N;;;;; +18852;TANGUT COMPONENT-083;Lo;0;L;;;;;N;;;;; +18853;TANGUT COMPONENT-084;Lo;0;L;;;;;N;;;;; +18854;TANGUT COMPONENT-085;Lo;0;L;;;;;N;;;;; +18855;TANGUT COMPONENT-086;Lo;0;L;;;;;N;;;;; +18856;TANGUT COMPONENT-087;Lo;0;L;;;;;N;;;;; +18857;TANGUT COMPONENT-088;Lo;0;L;;;;;N;;;;; +18858;TANGUT COMPONENT-089;Lo;0;L;;;;;N;;;;; +18859;TANGUT COMPONENT-090;Lo;0;L;;;;;N;;;;; +1885A;TANGUT COMPONENT-091;Lo;0;L;;;;;N;;;;; +1885B;TANGUT COMPONENT-092;Lo;0;L;;;;;N;;;;; +1885C;TANGUT COMPONENT-093;Lo;0;L;;;;;N;;;;; +1885D;TANGUT COMPONENT-094;Lo;0;L;;;;;N;;;;; +1885E;TANGUT COMPONENT-095;Lo;0;L;;;;;N;;;;; +1885F;TANGUT COMPONENT-096;Lo;0;L;;;;;N;;;;; +18860;TANGUT COMPONENT-097;Lo;0;L;;;;;N;;;;; +18861;TANGUT COMPONENT-098;Lo;0;L;;;;;N;;;;; +18862;TANGUT COMPONENT-099;Lo;0;L;;;;;N;;;;; +18863;TANGUT COMPONENT-100;Lo;0;L;;;;;N;;;;; +18864;TANGUT COMPONENT-101;Lo;0;L;;;;;N;;;;; +18865;TANGUT COMPONENT-102;Lo;0;L;;;;;N;;;;; +18866;TANGUT COMPONENT-103;Lo;0;L;;;;;N;;;;; +18867;TANGUT COMPONENT-104;Lo;0;L;;;;;N;;;;; +18868;TANGUT COMPONENT-105;Lo;0;L;;;;;N;;;;; +18869;TANGUT COMPONENT-106;Lo;0;L;;;;;N;;;;; +1886A;TANGUT COMPONENT-107;Lo;0;L;;;;;N;;;;; +1886B;TANGUT COMPONENT-108;Lo;0;L;;;;;N;;;;; +1886C;TANGUT COMPONENT-109;Lo;0;L;;;;;N;;;;; +1886D;TANGUT COMPONENT-110;Lo;0;L;;;;;N;;;;; +1886E;TANGUT COMPONENT-111;Lo;0;L;;;;;N;;;;; +1886F;TANGUT COMPONENT-112;Lo;0;L;;;;;N;;;;; +18870;TANGUT COMPONENT-113;Lo;0;L;;;;;N;;;;; +18871;TANGUT COMPONENT-114;Lo;0;L;;;;;N;;;;; +18872;TANGUT COMPONENT-115;Lo;0;L;;;;;N;;;;; +18873;TANGUT COMPONENT-116;Lo;0;L;;;;;N;;;;; +18874;TANGUT COMPONENT-117;Lo;0;L;;;;;N;;;;; +18875;TANGUT COMPONENT-118;Lo;0;L;;;;;N;;;;; +18876;TANGUT COMPONENT-119;Lo;0;L;;;;;N;;;;; +18877;TANGUT COMPONENT-120;Lo;0;L;;;;;N;;;;; +18878;TANGUT COMPONENT-121;Lo;0;L;;;;;N;;;;; +18879;TANGUT COMPONENT-122;Lo;0;L;;;;;N;;;;; +1887A;TANGUT COMPONENT-123;Lo;0;L;;;;;N;;;;; +1887B;TANGUT COMPONENT-124;Lo;0;L;;;;;N;;;;; +1887C;TANGUT COMPONENT-125;Lo;0;L;;;;;N;;;;; +1887D;TANGUT COMPONENT-126;Lo;0;L;;;;;N;;;;; +1887E;TANGUT COMPONENT-127;Lo;0;L;;;;;N;;;;; +1887F;TANGUT COMPONENT-128;Lo;0;L;;;;;N;;;;; +18880;TANGUT COMPONENT-129;Lo;0;L;;;;;N;;;;; +18881;TANGUT COMPONENT-130;Lo;0;L;;;;;N;;;;; +18882;TANGUT COMPONENT-131;Lo;0;L;;;;;N;;;;; +18883;TANGUT COMPONENT-132;Lo;0;L;;;;;N;;;;; +18884;TANGUT COMPONENT-133;Lo;0;L;;;;;N;;;;; +18885;TANGUT COMPONENT-134;Lo;0;L;;;;;N;;;;; +18886;TANGUT COMPONENT-135;Lo;0;L;;;;;N;;;;; +18887;TANGUT COMPONENT-136;Lo;0;L;;;;;N;;;;; +18888;TANGUT COMPONENT-137;Lo;0;L;;;;;N;;;;; +18889;TANGUT COMPONENT-138;Lo;0;L;;;;;N;;;;; +1888A;TANGUT COMPONENT-139;Lo;0;L;;;;;N;;;;; +1888B;TANGUT COMPONENT-140;Lo;0;L;;;;;N;;;;; +1888C;TANGUT COMPONENT-141;Lo;0;L;;;;;N;;;;; +1888D;TANGUT COMPONENT-142;Lo;0;L;;;;;N;;;;; +1888E;TANGUT COMPONENT-143;Lo;0;L;;;;;N;;;;; +1888F;TANGUT COMPONENT-144;Lo;0;L;;;;;N;;;;; +18890;TANGUT COMPONENT-145;Lo;0;L;;;;;N;;;;; +18891;TANGUT COMPONENT-146;Lo;0;L;;;;;N;;;;; +18892;TANGUT COMPONENT-147;Lo;0;L;;;;;N;;;;; +18893;TANGUT COMPONENT-148;Lo;0;L;;;;;N;;;;; +18894;TANGUT COMPONENT-149;Lo;0;L;;;;;N;;;;; +18895;TANGUT COMPONENT-150;Lo;0;L;;;;;N;;;;; +18896;TANGUT COMPONENT-151;Lo;0;L;;;;;N;;;;; +18897;TANGUT COMPONENT-152;Lo;0;L;;;;;N;;;;; +18898;TANGUT COMPONENT-153;Lo;0;L;;;;;N;;;;; +18899;TANGUT COMPONENT-154;Lo;0;L;;;;;N;;;;; +1889A;TANGUT COMPONENT-155;Lo;0;L;;;;;N;;;;; +1889B;TANGUT COMPONENT-156;Lo;0;L;;;;;N;;;;; +1889C;TANGUT COMPONENT-157;Lo;0;L;;;;;N;;;;; +1889D;TANGUT COMPONENT-158;Lo;0;L;;;;;N;;;;; +1889E;TANGUT COMPONENT-159;Lo;0;L;;;;;N;;;;; +1889F;TANGUT COMPONENT-160;Lo;0;L;;;;;N;;;;; +188A0;TANGUT COMPONENT-161;Lo;0;L;;;;;N;;;;; +188A1;TANGUT COMPONENT-162;Lo;0;L;;;;;N;;;;; +188A2;TANGUT COMPONENT-163;Lo;0;L;;;;;N;;;;; +188A3;TANGUT COMPONENT-164;Lo;0;L;;;;;N;;;;; +188A4;TANGUT COMPONENT-165;Lo;0;L;;;;;N;;;;; +188A5;TANGUT COMPONENT-166;Lo;0;L;;;;;N;;;;; +188A6;TANGUT COMPONENT-167;Lo;0;L;;;;;N;;;;; +188A7;TANGUT COMPONENT-168;Lo;0;L;;;;;N;;;;; +188A8;TANGUT COMPONENT-169;Lo;0;L;;;;;N;;;;; +188A9;TANGUT COMPONENT-170;Lo;0;L;;;;;N;;;;; +188AA;TANGUT COMPONENT-171;Lo;0;L;;;;;N;;;;; +188AB;TANGUT COMPONENT-172;Lo;0;L;;;;;N;;;;; +188AC;TANGUT COMPONENT-173;Lo;0;L;;;;;N;;;;; +188AD;TANGUT COMPONENT-174;Lo;0;L;;;;;N;;;;; +188AE;TANGUT COMPONENT-175;Lo;0;L;;;;;N;;;;; +188AF;TANGUT COMPONENT-176;Lo;0;L;;;;;N;;;;; +188B0;TANGUT COMPONENT-177;Lo;0;L;;;;;N;;;;; +188B1;TANGUT COMPONENT-178;Lo;0;L;;;;;N;;;;; +188B2;TANGUT COMPONENT-179;Lo;0;L;;;;;N;;;;; +188B3;TANGUT COMPONENT-180;Lo;0;L;;;;;N;;;;; +188B4;TANGUT COMPONENT-181;Lo;0;L;;;;;N;;;;; +188B5;TANGUT COMPONENT-182;Lo;0;L;;;;;N;;;;; +188B6;TANGUT COMPONENT-183;Lo;0;L;;;;;N;;;;; +188B7;TANGUT COMPONENT-184;Lo;0;L;;;;;N;;;;; +188B8;TANGUT COMPONENT-185;Lo;0;L;;;;;N;;;;; +188B9;TANGUT COMPONENT-186;Lo;0;L;;;;;N;;;;; +188BA;TANGUT COMPONENT-187;Lo;0;L;;;;;N;;;;; +188BB;TANGUT COMPONENT-188;Lo;0;L;;;;;N;;;;; +188BC;TANGUT COMPONENT-189;Lo;0;L;;;;;N;;;;; +188BD;TANGUT COMPONENT-190;Lo;0;L;;;;;N;;;;; +188BE;TANGUT COMPONENT-191;Lo;0;L;;;;;N;;;;; +188BF;TANGUT COMPONENT-192;Lo;0;L;;;;;N;;;;; +188C0;TANGUT COMPONENT-193;Lo;0;L;;;;;N;;;;; +188C1;TANGUT COMPONENT-194;Lo;0;L;;;;;N;;;;; +188C2;TANGUT COMPONENT-195;Lo;0;L;;;;;N;;;;; +188C3;TANGUT COMPONENT-196;Lo;0;L;;;;;N;;;;; +188C4;TANGUT COMPONENT-197;Lo;0;L;;;;;N;;;;; +188C5;TANGUT COMPONENT-198;Lo;0;L;;;;;N;;;;; +188C6;TANGUT COMPONENT-199;Lo;0;L;;;;;N;;;;; +188C7;TANGUT COMPONENT-200;Lo;0;L;;;;;N;;;;; +188C8;TANGUT COMPONENT-201;Lo;0;L;;;;;N;;;;; +188C9;TANGUT COMPONENT-202;Lo;0;L;;;;;N;;;;; +188CA;TANGUT COMPONENT-203;Lo;0;L;;;;;N;;;;; +188CB;TANGUT COMPONENT-204;Lo;0;L;;;;;N;;;;; +188CC;TANGUT COMPONENT-205;Lo;0;L;;;;;N;;;;; +188CD;TANGUT COMPONENT-206;Lo;0;L;;;;;N;;;;; +188CE;TANGUT COMPONENT-207;Lo;0;L;;;;;N;;;;; +188CF;TANGUT COMPONENT-208;Lo;0;L;;;;;N;;;;; +188D0;TANGUT COMPONENT-209;Lo;0;L;;;;;N;;;;; +188D1;TANGUT COMPONENT-210;Lo;0;L;;;;;N;;;;; +188D2;TANGUT COMPONENT-211;Lo;0;L;;;;;N;;;;; +188D3;TANGUT COMPONENT-212;Lo;0;L;;;;;N;;;;; +188D4;TANGUT COMPONENT-213;Lo;0;L;;;;;N;;;;; +188D5;TANGUT COMPONENT-214;Lo;0;L;;;;;N;;;;; +188D6;TANGUT COMPONENT-215;Lo;0;L;;;;;N;;;;; +188D7;TANGUT COMPONENT-216;Lo;0;L;;;;;N;;;;; +188D8;TANGUT COMPONENT-217;Lo;0;L;;;;;N;;;;; +188D9;TANGUT COMPONENT-218;Lo;0;L;;;;;N;;;;; +188DA;TANGUT COMPONENT-219;Lo;0;L;;;;;N;;;;; +188DB;TANGUT COMPONENT-220;Lo;0;L;;;;;N;;;;; +188DC;TANGUT COMPONENT-221;Lo;0;L;;;;;N;;;;; +188DD;TANGUT COMPONENT-222;Lo;0;L;;;;;N;;;;; +188DE;TANGUT COMPONENT-223;Lo;0;L;;;;;N;;;;; +188DF;TANGUT COMPONENT-224;Lo;0;L;;;;;N;;;;; +188E0;TANGUT COMPONENT-225;Lo;0;L;;;;;N;;;;; +188E1;TANGUT COMPONENT-226;Lo;0;L;;;;;N;;;;; +188E2;TANGUT COMPONENT-227;Lo;0;L;;;;;N;;;;; +188E3;TANGUT COMPONENT-228;Lo;0;L;;;;;N;;;;; +188E4;TANGUT COMPONENT-229;Lo;0;L;;;;;N;;;;; +188E5;TANGUT COMPONENT-230;Lo;0;L;;;;;N;;;;; +188E6;TANGUT COMPONENT-231;Lo;0;L;;;;;N;;;;; +188E7;TANGUT COMPONENT-232;Lo;0;L;;;;;N;;;;; +188E8;TANGUT COMPONENT-233;Lo;0;L;;;;;N;;;;; +188E9;TANGUT COMPONENT-234;Lo;0;L;;;;;N;;;;; +188EA;TANGUT COMPONENT-235;Lo;0;L;;;;;N;;;;; +188EB;TANGUT COMPONENT-236;Lo;0;L;;;;;N;;;;; +188EC;TANGUT COMPONENT-237;Lo;0;L;;;;;N;;;;; +188ED;TANGUT COMPONENT-238;Lo;0;L;;;;;N;;;;; +188EE;TANGUT COMPONENT-239;Lo;0;L;;;;;N;;;;; +188EF;TANGUT COMPONENT-240;Lo;0;L;;;;;N;;;;; +188F0;TANGUT COMPONENT-241;Lo;0;L;;;;;N;;;;; +188F1;TANGUT COMPONENT-242;Lo;0;L;;;;;N;;;;; +188F2;TANGUT COMPONENT-243;Lo;0;L;;;;;N;;;;; +188F3;TANGUT COMPONENT-244;Lo;0;L;;;;;N;;;;; +188F4;TANGUT COMPONENT-245;Lo;0;L;;;;;N;;;;; +188F5;TANGUT COMPONENT-246;Lo;0;L;;;;;N;;;;; +188F6;TANGUT COMPONENT-247;Lo;0;L;;;;;N;;;;; +188F7;TANGUT COMPONENT-248;Lo;0;L;;;;;N;;;;; +188F8;TANGUT COMPONENT-249;Lo;0;L;;;;;N;;;;; +188F9;TANGUT COMPONENT-250;Lo;0;L;;;;;N;;;;; +188FA;TANGUT COMPONENT-251;Lo;0;L;;;;;N;;;;; +188FB;TANGUT COMPONENT-252;Lo;0;L;;;;;N;;;;; +188FC;TANGUT COMPONENT-253;Lo;0;L;;;;;N;;;;; +188FD;TANGUT COMPONENT-254;Lo;0;L;;;;;N;;;;; +188FE;TANGUT COMPONENT-255;Lo;0;L;;;;;N;;;;; +188FF;TANGUT COMPONENT-256;Lo;0;L;;;;;N;;;;; +18900;TANGUT COMPONENT-257;Lo;0;L;;;;;N;;;;; +18901;TANGUT COMPONENT-258;Lo;0;L;;;;;N;;;;; +18902;TANGUT COMPONENT-259;Lo;0;L;;;;;N;;;;; +18903;TANGUT COMPONENT-260;Lo;0;L;;;;;N;;;;; +18904;TANGUT COMPONENT-261;Lo;0;L;;;;;N;;;;; +18905;TANGUT COMPONENT-262;Lo;0;L;;;;;N;;;;; +18906;TANGUT COMPONENT-263;Lo;0;L;;;;;N;;;;; +18907;TANGUT COMPONENT-264;Lo;0;L;;;;;N;;;;; +18908;TANGUT COMPONENT-265;Lo;0;L;;;;;N;;;;; +18909;TANGUT COMPONENT-266;Lo;0;L;;;;;N;;;;; +1890A;TANGUT COMPONENT-267;Lo;0;L;;;;;N;;;;; +1890B;TANGUT COMPONENT-268;Lo;0;L;;;;;N;;;;; +1890C;TANGUT COMPONENT-269;Lo;0;L;;;;;N;;;;; +1890D;TANGUT COMPONENT-270;Lo;0;L;;;;;N;;;;; +1890E;TANGUT COMPONENT-271;Lo;0;L;;;;;N;;;;; +1890F;TANGUT COMPONENT-272;Lo;0;L;;;;;N;;;;; +18910;TANGUT COMPONENT-273;Lo;0;L;;;;;N;;;;; +18911;TANGUT COMPONENT-274;Lo;0;L;;;;;N;;;;; +18912;TANGUT COMPONENT-275;Lo;0;L;;;;;N;;;;; +18913;TANGUT COMPONENT-276;Lo;0;L;;;;;N;;;;; +18914;TANGUT COMPONENT-277;Lo;0;L;;;;;N;;;;; +18915;TANGUT COMPONENT-278;Lo;0;L;;;;;N;;;;; +18916;TANGUT COMPONENT-279;Lo;0;L;;;;;N;;;;; +18917;TANGUT COMPONENT-280;Lo;0;L;;;;;N;;;;; +18918;TANGUT COMPONENT-281;Lo;0;L;;;;;N;;;;; +18919;TANGUT COMPONENT-282;Lo;0;L;;;;;N;;;;; +1891A;TANGUT COMPONENT-283;Lo;0;L;;;;;N;;;;; +1891B;TANGUT COMPONENT-284;Lo;0;L;;;;;N;;;;; +1891C;TANGUT COMPONENT-285;Lo;0;L;;;;;N;;;;; +1891D;TANGUT COMPONENT-286;Lo;0;L;;;;;N;;;;; +1891E;TANGUT COMPONENT-287;Lo;0;L;;;;;N;;;;; +1891F;TANGUT COMPONENT-288;Lo;0;L;;;;;N;;;;; +18920;TANGUT COMPONENT-289;Lo;0;L;;;;;N;;;;; +18921;TANGUT COMPONENT-290;Lo;0;L;;;;;N;;;;; +18922;TANGUT COMPONENT-291;Lo;0;L;;;;;N;;;;; +18923;TANGUT COMPONENT-292;Lo;0;L;;;;;N;;;;; +18924;TANGUT COMPONENT-293;Lo;0;L;;;;;N;;;;; +18925;TANGUT COMPONENT-294;Lo;0;L;;;;;N;;;;; +18926;TANGUT COMPONENT-295;Lo;0;L;;;;;N;;;;; +18927;TANGUT COMPONENT-296;Lo;0;L;;;;;N;;;;; +18928;TANGUT COMPONENT-297;Lo;0;L;;;;;N;;;;; +18929;TANGUT COMPONENT-298;Lo;0;L;;;;;N;;;;; +1892A;TANGUT COMPONENT-299;Lo;0;L;;;;;N;;;;; +1892B;TANGUT COMPONENT-300;Lo;0;L;;;;;N;;;;; +1892C;TANGUT COMPONENT-301;Lo;0;L;;;;;N;;;;; +1892D;TANGUT COMPONENT-302;Lo;0;L;;;;;N;;;;; +1892E;TANGUT COMPONENT-303;Lo;0;L;;;;;N;;;;; +1892F;TANGUT COMPONENT-304;Lo;0;L;;;;;N;;;;; +18930;TANGUT COMPONENT-305;Lo;0;L;;;;;N;;;;; +18931;TANGUT COMPONENT-306;Lo;0;L;;;;;N;;;;; +18932;TANGUT COMPONENT-307;Lo;0;L;;;;;N;;;;; +18933;TANGUT COMPONENT-308;Lo;0;L;;;;;N;;;;; +18934;TANGUT COMPONENT-309;Lo;0;L;;;;;N;;;;; +18935;TANGUT COMPONENT-310;Lo;0;L;;;;;N;;;;; +18936;TANGUT COMPONENT-311;Lo;0;L;;;;;N;;;;; +18937;TANGUT COMPONENT-312;Lo;0;L;;;;;N;;;;; +18938;TANGUT COMPONENT-313;Lo;0;L;;;;;N;;;;; +18939;TANGUT COMPONENT-314;Lo;0;L;;;;;N;;;;; +1893A;TANGUT COMPONENT-315;Lo;0;L;;;;;N;;;;; +1893B;TANGUT COMPONENT-316;Lo;0;L;;;;;N;;;;; +1893C;TANGUT COMPONENT-317;Lo;0;L;;;;;N;;;;; +1893D;TANGUT COMPONENT-318;Lo;0;L;;;;;N;;;;; +1893E;TANGUT COMPONENT-319;Lo;0;L;;;;;N;;;;; +1893F;TANGUT COMPONENT-320;Lo;0;L;;;;;N;;;;; +18940;TANGUT COMPONENT-321;Lo;0;L;;;;;N;;;;; +18941;TANGUT COMPONENT-322;Lo;0;L;;;;;N;;;;; +18942;TANGUT COMPONENT-323;Lo;0;L;;;;;N;;;;; +18943;TANGUT COMPONENT-324;Lo;0;L;;;;;N;;;;; +18944;TANGUT COMPONENT-325;Lo;0;L;;;;;N;;;;; +18945;TANGUT COMPONENT-326;Lo;0;L;;;;;N;;;;; +18946;TANGUT COMPONENT-327;Lo;0;L;;;;;N;;;;; +18947;TANGUT COMPONENT-328;Lo;0;L;;;;;N;;;;; +18948;TANGUT COMPONENT-329;Lo;0;L;;;;;N;;;;; +18949;TANGUT COMPONENT-330;Lo;0;L;;;;;N;;;;; +1894A;TANGUT COMPONENT-331;Lo;0;L;;;;;N;;;;; +1894B;TANGUT COMPONENT-332;Lo;0;L;;;;;N;;;;; +1894C;TANGUT COMPONENT-333;Lo;0;L;;;;;N;;;;; +1894D;TANGUT COMPONENT-334;Lo;0;L;;;;;N;;;;; +1894E;TANGUT COMPONENT-335;Lo;0;L;;;;;N;;;;; +1894F;TANGUT COMPONENT-336;Lo;0;L;;;;;N;;;;; +18950;TANGUT COMPONENT-337;Lo;0;L;;;;;N;;;;; +18951;TANGUT COMPONENT-338;Lo;0;L;;;;;N;;;;; +18952;TANGUT COMPONENT-339;Lo;0;L;;;;;N;;;;; +18953;TANGUT COMPONENT-340;Lo;0;L;;;;;N;;;;; +18954;TANGUT COMPONENT-341;Lo;0;L;;;;;N;;;;; +18955;TANGUT COMPONENT-342;Lo;0;L;;;;;N;;;;; +18956;TANGUT COMPONENT-343;Lo;0;L;;;;;N;;;;; +18957;TANGUT COMPONENT-344;Lo;0;L;;;;;N;;;;; +18958;TANGUT COMPONENT-345;Lo;0;L;;;;;N;;;;; +18959;TANGUT COMPONENT-346;Lo;0;L;;;;;N;;;;; +1895A;TANGUT COMPONENT-347;Lo;0;L;;;;;N;;;;; +1895B;TANGUT COMPONENT-348;Lo;0;L;;;;;N;;;;; +1895C;TANGUT COMPONENT-349;Lo;0;L;;;;;N;;;;; +1895D;TANGUT COMPONENT-350;Lo;0;L;;;;;N;;;;; +1895E;TANGUT COMPONENT-351;Lo;0;L;;;;;N;;;;; +1895F;TANGUT COMPONENT-352;Lo;0;L;;;;;N;;;;; +18960;TANGUT COMPONENT-353;Lo;0;L;;;;;N;;;;; +18961;TANGUT COMPONENT-354;Lo;0;L;;;;;N;;;;; +18962;TANGUT COMPONENT-355;Lo;0;L;;;;;N;;;;; +18963;TANGUT COMPONENT-356;Lo;0;L;;;;;N;;;;; +18964;TANGUT COMPONENT-357;Lo;0;L;;;;;N;;;;; +18965;TANGUT COMPONENT-358;Lo;0;L;;;;;N;;;;; +18966;TANGUT COMPONENT-359;Lo;0;L;;;;;N;;;;; +18967;TANGUT COMPONENT-360;Lo;0;L;;;;;N;;;;; +18968;TANGUT COMPONENT-361;Lo;0;L;;;;;N;;;;; +18969;TANGUT COMPONENT-362;Lo;0;L;;;;;N;;;;; +1896A;TANGUT COMPONENT-363;Lo;0;L;;;;;N;;;;; +1896B;TANGUT COMPONENT-364;Lo;0;L;;;;;N;;;;; +1896C;TANGUT COMPONENT-365;Lo;0;L;;;;;N;;;;; +1896D;TANGUT COMPONENT-366;Lo;0;L;;;;;N;;;;; +1896E;TANGUT COMPONENT-367;Lo;0;L;;;;;N;;;;; +1896F;TANGUT COMPONENT-368;Lo;0;L;;;;;N;;;;; +18970;TANGUT COMPONENT-369;Lo;0;L;;;;;N;;;;; +18971;TANGUT COMPONENT-370;Lo;0;L;;;;;N;;;;; +18972;TANGUT COMPONENT-371;Lo;0;L;;;;;N;;;;; +18973;TANGUT COMPONENT-372;Lo;0;L;;;;;N;;;;; +18974;TANGUT COMPONENT-373;Lo;0;L;;;;;N;;;;; +18975;TANGUT COMPONENT-374;Lo;0;L;;;;;N;;;;; +18976;TANGUT COMPONENT-375;Lo;0;L;;;;;N;;;;; +18977;TANGUT COMPONENT-376;Lo;0;L;;;;;N;;;;; +18978;TANGUT COMPONENT-377;Lo;0;L;;;;;N;;;;; +18979;TANGUT COMPONENT-378;Lo;0;L;;;;;N;;;;; +1897A;TANGUT COMPONENT-379;Lo;0;L;;;;;N;;;;; +1897B;TANGUT COMPONENT-380;Lo;0;L;;;;;N;;;;; +1897C;TANGUT COMPONENT-381;Lo;0;L;;;;;N;;;;; +1897D;TANGUT COMPONENT-382;Lo;0;L;;;;;N;;;;; +1897E;TANGUT COMPONENT-383;Lo;0;L;;;;;N;;;;; +1897F;TANGUT COMPONENT-384;Lo;0;L;;;;;N;;;;; +18980;TANGUT COMPONENT-385;Lo;0;L;;;;;N;;;;; +18981;TANGUT COMPONENT-386;Lo;0;L;;;;;N;;;;; +18982;TANGUT COMPONENT-387;Lo;0;L;;;;;N;;;;; +18983;TANGUT COMPONENT-388;Lo;0;L;;;;;N;;;;; +18984;TANGUT COMPONENT-389;Lo;0;L;;;;;N;;;;; +18985;TANGUT COMPONENT-390;Lo;0;L;;;;;N;;;;; +18986;TANGUT COMPONENT-391;Lo;0;L;;;;;N;;;;; +18987;TANGUT COMPONENT-392;Lo;0;L;;;;;N;;;;; +18988;TANGUT COMPONENT-393;Lo;0;L;;;;;N;;;;; +18989;TANGUT COMPONENT-394;Lo;0;L;;;;;N;;;;; +1898A;TANGUT COMPONENT-395;Lo;0;L;;;;;N;;;;; +1898B;TANGUT COMPONENT-396;Lo;0;L;;;;;N;;;;; +1898C;TANGUT COMPONENT-397;Lo;0;L;;;;;N;;;;; +1898D;TANGUT COMPONENT-398;Lo;0;L;;;;;N;;;;; +1898E;TANGUT COMPONENT-399;Lo;0;L;;;;;N;;;;; +1898F;TANGUT COMPONENT-400;Lo;0;L;;;;;N;;;;; +18990;TANGUT COMPONENT-401;Lo;0;L;;;;;N;;;;; +18991;TANGUT COMPONENT-402;Lo;0;L;;;;;N;;;;; +18992;TANGUT COMPONENT-403;Lo;0;L;;;;;N;;;;; +18993;TANGUT COMPONENT-404;Lo;0;L;;;;;N;;;;; +18994;TANGUT COMPONENT-405;Lo;0;L;;;;;N;;;;; +18995;TANGUT COMPONENT-406;Lo;0;L;;;;;N;;;;; +18996;TANGUT COMPONENT-407;Lo;0;L;;;;;N;;;;; +18997;TANGUT COMPONENT-408;Lo;0;L;;;;;N;;;;; +18998;TANGUT COMPONENT-409;Lo;0;L;;;;;N;;;;; +18999;TANGUT COMPONENT-410;Lo;0;L;;;;;N;;;;; +1899A;TANGUT COMPONENT-411;Lo;0;L;;;;;N;;;;; +1899B;TANGUT COMPONENT-412;Lo;0;L;;;;;N;;;;; +1899C;TANGUT COMPONENT-413;Lo;0;L;;;;;N;;;;; +1899D;TANGUT COMPONENT-414;Lo;0;L;;;;;N;;;;; +1899E;TANGUT COMPONENT-415;Lo;0;L;;;;;N;;;;; +1899F;TANGUT COMPONENT-416;Lo;0;L;;;;;N;;;;; +189A0;TANGUT COMPONENT-417;Lo;0;L;;;;;N;;;;; +189A1;TANGUT COMPONENT-418;Lo;0;L;;;;;N;;;;; +189A2;TANGUT COMPONENT-419;Lo;0;L;;;;;N;;;;; +189A3;TANGUT COMPONENT-420;Lo;0;L;;;;;N;;;;; +189A4;TANGUT COMPONENT-421;Lo;0;L;;;;;N;;;;; +189A5;TANGUT COMPONENT-422;Lo;0;L;;;;;N;;;;; +189A6;TANGUT COMPONENT-423;Lo;0;L;;;;;N;;;;; +189A7;TANGUT COMPONENT-424;Lo;0;L;;;;;N;;;;; +189A8;TANGUT COMPONENT-425;Lo;0;L;;;;;N;;;;; +189A9;TANGUT COMPONENT-426;Lo;0;L;;;;;N;;;;; +189AA;TANGUT COMPONENT-427;Lo;0;L;;;;;N;;;;; +189AB;TANGUT COMPONENT-428;Lo;0;L;;;;;N;;;;; +189AC;TANGUT COMPONENT-429;Lo;0;L;;;;;N;;;;; +189AD;TANGUT COMPONENT-430;Lo;0;L;;;;;N;;;;; +189AE;TANGUT COMPONENT-431;Lo;0;L;;;;;N;;;;; +189AF;TANGUT COMPONENT-432;Lo;0;L;;;;;N;;;;; +189B0;TANGUT COMPONENT-433;Lo;0;L;;;;;N;;;;; +189B1;TANGUT COMPONENT-434;Lo;0;L;;;;;N;;;;; +189B2;TANGUT COMPONENT-435;Lo;0;L;;;;;N;;;;; +189B3;TANGUT COMPONENT-436;Lo;0;L;;;;;N;;;;; +189B4;TANGUT COMPONENT-437;Lo;0;L;;;;;N;;;;; +189B5;TANGUT COMPONENT-438;Lo;0;L;;;;;N;;;;; +189B6;TANGUT COMPONENT-439;Lo;0;L;;;;;N;;;;; +189B7;TANGUT COMPONENT-440;Lo;0;L;;;;;N;;;;; +189B8;TANGUT COMPONENT-441;Lo;0;L;;;;;N;;;;; +189B9;TANGUT COMPONENT-442;Lo;0;L;;;;;N;;;;; +189BA;TANGUT COMPONENT-443;Lo;0;L;;;;;N;;;;; +189BB;TANGUT COMPONENT-444;Lo;0;L;;;;;N;;;;; +189BC;TANGUT COMPONENT-445;Lo;0;L;;;;;N;;;;; +189BD;TANGUT COMPONENT-446;Lo;0;L;;;;;N;;;;; +189BE;TANGUT COMPONENT-447;Lo;0;L;;;;;N;;;;; +189BF;TANGUT COMPONENT-448;Lo;0;L;;;;;N;;;;; +189C0;TANGUT COMPONENT-449;Lo;0;L;;;;;N;;;;; +189C1;TANGUT COMPONENT-450;Lo;0;L;;;;;N;;;;; +189C2;TANGUT COMPONENT-451;Lo;0;L;;;;;N;;;;; +189C3;TANGUT COMPONENT-452;Lo;0;L;;;;;N;;;;; +189C4;TANGUT COMPONENT-453;Lo;0;L;;;;;N;;;;; +189C5;TANGUT COMPONENT-454;Lo;0;L;;;;;N;;;;; +189C6;TANGUT COMPONENT-455;Lo;0;L;;;;;N;;;;; +189C7;TANGUT COMPONENT-456;Lo;0;L;;;;;N;;;;; +189C8;TANGUT COMPONENT-457;Lo;0;L;;;;;N;;;;; +189C9;TANGUT COMPONENT-458;Lo;0;L;;;;;N;;;;; +189CA;TANGUT COMPONENT-459;Lo;0;L;;;;;N;;;;; +189CB;TANGUT COMPONENT-460;Lo;0;L;;;;;N;;;;; +189CC;TANGUT COMPONENT-461;Lo;0;L;;;;;N;;;;; +189CD;TANGUT COMPONENT-462;Lo;0;L;;;;;N;;;;; +189CE;TANGUT COMPONENT-463;Lo;0;L;;;;;N;;;;; +189CF;TANGUT COMPONENT-464;Lo;0;L;;;;;N;;;;; +189D0;TANGUT COMPONENT-465;Lo;0;L;;;;;N;;;;; +189D1;TANGUT COMPONENT-466;Lo;0;L;;;;;N;;;;; +189D2;TANGUT COMPONENT-467;Lo;0;L;;;;;N;;;;; +189D3;TANGUT COMPONENT-468;Lo;0;L;;;;;N;;;;; +189D4;TANGUT COMPONENT-469;Lo;0;L;;;;;N;;;;; +189D5;TANGUT COMPONENT-470;Lo;0;L;;;;;N;;;;; +189D6;TANGUT COMPONENT-471;Lo;0;L;;;;;N;;;;; +189D7;TANGUT COMPONENT-472;Lo;0;L;;;;;N;;;;; +189D8;TANGUT COMPONENT-473;Lo;0;L;;;;;N;;;;; +189D9;TANGUT COMPONENT-474;Lo;0;L;;;;;N;;;;; +189DA;TANGUT COMPONENT-475;Lo;0;L;;;;;N;;;;; +189DB;TANGUT COMPONENT-476;Lo;0;L;;;;;N;;;;; +189DC;TANGUT COMPONENT-477;Lo;0;L;;;;;N;;;;; +189DD;TANGUT COMPONENT-478;Lo;0;L;;;;;N;;;;; +189DE;TANGUT COMPONENT-479;Lo;0;L;;;;;N;;;;; +189DF;TANGUT COMPONENT-480;Lo;0;L;;;;;N;;;;; +189E0;TANGUT COMPONENT-481;Lo;0;L;;;;;N;;;;; +189E1;TANGUT COMPONENT-482;Lo;0;L;;;;;N;;;;; +189E2;TANGUT COMPONENT-483;Lo;0;L;;;;;N;;;;; +189E3;TANGUT COMPONENT-484;Lo;0;L;;;;;N;;;;; +189E4;TANGUT COMPONENT-485;Lo;0;L;;;;;N;;;;; +189E5;TANGUT COMPONENT-486;Lo;0;L;;;;;N;;;;; +189E6;TANGUT COMPONENT-487;Lo;0;L;;;;;N;;;;; +189E7;TANGUT COMPONENT-488;Lo;0;L;;;;;N;;;;; +189E8;TANGUT COMPONENT-489;Lo;0;L;;;;;N;;;;; +189E9;TANGUT COMPONENT-490;Lo;0;L;;;;;N;;;;; +189EA;TANGUT COMPONENT-491;Lo;0;L;;;;;N;;;;; +189EB;TANGUT COMPONENT-492;Lo;0;L;;;;;N;;;;; +189EC;TANGUT COMPONENT-493;Lo;0;L;;;;;N;;;;; +189ED;TANGUT COMPONENT-494;Lo;0;L;;;;;N;;;;; +189EE;TANGUT COMPONENT-495;Lo;0;L;;;;;N;;;;; +189EF;TANGUT COMPONENT-496;Lo;0;L;;;;;N;;;;; +189F0;TANGUT COMPONENT-497;Lo;0;L;;;;;N;;;;; +189F1;TANGUT COMPONENT-498;Lo;0;L;;;;;N;;;;; +189F2;TANGUT COMPONENT-499;Lo;0;L;;;;;N;;;;; +189F3;TANGUT COMPONENT-500;Lo;0;L;;;;;N;;;;; +189F4;TANGUT COMPONENT-501;Lo;0;L;;;;;N;;;;; +189F5;TANGUT COMPONENT-502;Lo;0;L;;;;;N;;;;; +189F6;TANGUT COMPONENT-503;Lo;0;L;;;;;N;;;;; +189F7;TANGUT COMPONENT-504;Lo;0;L;;;;;N;;;;; +189F8;TANGUT COMPONENT-505;Lo;0;L;;;;;N;;;;; +189F9;TANGUT COMPONENT-506;Lo;0;L;;;;;N;;;;; +189FA;TANGUT COMPONENT-507;Lo;0;L;;;;;N;;;;; +189FB;TANGUT COMPONENT-508;Lo;0;L;;;;;N;;;;; +189FC;TANGUT COMPONENT-509;Lo;0;L;;;;;N;;;;; +189FD;TANGUT COMPONENT-510;Lo;0;L;;;;;N;;;;; +189FE;TANGUT COMPONENT-511;Lo;0;L;;;;;N;;;;; +189FF;TANGUT COMPONENT-512;Lo;0;L;;;;;N;;;;; +18A00;TANGUT COMPONENT-513;Lo;0;L;;;;;N;;;;; +18A01;TANGUT COMPONENT-514;Lo;0;L;;;;;N;;;;; +18A02;TANGUT COMPONENT-515;Lo;0;L;;;;;N;;;;; +18A03;TANGUT COMPONENT-516;Lo;0;L;;;;;N;;;;; +18A04;TANGUT COMPONENT-517;Lo;0;L;;;;;N;;;;; +18A05;TANGUT COMPONENT-518;Lo;0;L;;;;;N;;;;; +18A06;TANGUT COMPONENT-519;Lo;0;L;;;;;N;;;;; +18A07;TANGUT COMPONENT-520;Lo;0;L;;;;;N;;;;; +18A08;TANGUT COMPONENT-521;Lo;0;L;;;;;N;;;;; +18A09;TANGUT COMPONENT-522;Lo;0;L;;;;;N;;;;; +18A0A;TANGUT COMPONENT-523;Lo;0;L;;;;;N;;;;; +18A0B;TANGUT COMPONENT-524;Lo;0;L;;;;;N;;;;; +18A0C;TANGUT COMPONENT-525;Lo;0;L;;;;;N;;;;; +18A0D;TANGUT COMPONENT-526;Lo;0;L;;;;;N;;;;; +18A0E;TANGUT COMPONENT-527;Lo;0;L;;;;;N;;;;; +18A0F;TANGUT COMPONENT-528;Lo;0;L;;;;;N;;;;; +18A10;TANGUT COMPONENT-529;Lo;0;L;;;;;N;;;;; +18A11;TANGUT COMPONENT-530;Lo;0;L;;;;;N;;;;; +18A12;TANGUT COMPONENT-531;Lo;0;L;;;;;N;;;;; +18A13;TANGUT COMPONENT-532;Lo;0;L;;;;;N;;;;; +18A14;TANGUT COMPONENT-533;Lo;0;L;;;;;N;;;;; +18A15;TANGUT COMPONENT-534;Lo;0;L;;;;;N;;;;; +18A16;TANGUT COMPONENT-535;Lo;0;L;;;;;N;;;;; +18A17;TANGUT COMPONENT-536;Lo;0;L;;;;;N;;;;; +18A18;TANGUT COMPONENT-537;Lo;0;L;;;;;N;;;;; +18A19;TANGUT COMPONENT-538;Lo;0;L;;;;;N;;;;; +18A1A;TANGUT COMPONENT-539;Lo;0;L;;;;;N;;;;; +18A1B;TANGUT COMPONENT-540;Lo;0;L;;;;;N;;;;; +18A1C;TANGUT COMPONENT-541;Lo;0;L;;;;;N;;;;; +18A1D;TANGUT COMPONENT-542;Lo;0;L;;;;;N;;;;; +18A1E;TANGUT COMPONENT-543;Lo;0;L;;;;;N;;;;; +18A1F;TANGUT COMPONENT-544;Lo;0;L;;;;;N;;;;; +18A20;TANGUT COMPONENT-545;Lo;0;L;;;;;N;;;;; +18A21;TANGUT COMPONENT-546;Lo;0;L;;;;;N;;;;; +18A22;TANGUT COMPONENT-547;Lo;0;L;;;;;N;;;;; +18A23;TANGUT COMPONENT-548;Lo;0;L;;;;;N;;;;; +18A24;TANGUT COMPONENT-549;Lo;0;L;;;;;N;;;;; +18A25;TANGUT COMPONENT-550;Lo;0;L;;;;;N;;;;; +18A26;TANGUT COMPONENT-551;Lo;0;L;;;;;N;;;;; +18A27;TANGUT COMPONENT-552;Lo;0;L;;;;;N;;;;; +18A28;TANGUT COMPONENT-553;Lo;0;L;;;;;N;;;;; +18A29;TANGUT COMPONENT-554;Lo;0;L;;;;;N;;;;; +18A2A;TANGUT COMPONENT-555;Lo;0;L;;;;;N;;;;; +18A2B;TANGUT COMPONENT-556;Lo;0;L;;;;;N;;;;; +18A2C;TANGUT COMPONENT-557;Lo;0;L;;;;;N;;;;; +18A2D;TANGUT COMPONENT-558;Lo;0;L;;;;;N;;;;; +18A2E;TANGUT COMPONENT-559;Lo;0;L;;;;;N;;;;; +18A2F;TANGUT COMPONENT-560;Lo;0;L;;;;;N;;;;; +18A30;TANGUT COMPONENT-561;Lo;0;L;;;;;N;;;;; +18A31;TANGUT COMPONENT-562;Lo;0;L;;;;;N;;;;; +18A32;TANGUT COMPONENT-563;Lo;0;L;;;;;N;;;;; +18A33;TANGUT COMPONENT-564;Lo;0;L;;;;;N;;;;; +18A34;TANGUT COMPONENT-565;Lo;0;L;;;;;N;;;;; +18A35;TANGUT COMPONENT-566;Lo;0;L;;;;;N;;;;; +18A36;TANGUT COMPONENT-567;Lo;0;L;;;;;N;;;;; +18A37;TANGUT COMPONENT-568;Lo;0;L;;;;;N;;;;; +18A38;TANGUT COMPONENT-569;Lo;0;L;;;;;N;;;;; +18A39;TANGUT COMPONENT-570;Lo;0;L;;;;;N;;;;; +18A3A;TANGUT COMPONENT-571;Lo;0;L;;;;;N;;;;; +18A3B;TANGUT COMPONENT-572;Lo;0;L;;;;;N;;;;; +18A3C;TANGUT COMPONENT-573;Lo;0;L;;;;;N;;;;; +18A3D;TANGUT COMPONENT-574;Lo;0;L;;;;;N;;;;; +18A3E;TANGUT COMPONENT-575;Lo;0;L;;;;;N;;;;; +18A3F;TANGUT COMPONENT-576;Lo;0;L;;;;;N;;;;; +18A40;TANGUT COMPONENT-577;Lo;0;L;;;;;N;;;;; +18A41;TANGUT COMPONENT-578;Lo;0;L;;;;;N;;;;; +18A42;TANGUT COMPONENT-579;Lo;0;L;;;;;N;;;;; +18A43;TANGUT COMPONENT-580;Lo;0;L;;;;;N;;;;; +18A44;TANGUT COMPONENT-581;Lo;0;L;;;;;N;;;;; +18A45;TANGUT COMPONENT-582;Lo;0;L;;;;;N;;;;; +18A46;TANGUT COMPONENT-583;Lo;0;L;;;;;N;;;;; +18A47;TANGUT COMPONENT-584;Lo;0;L;;;;;N;;;;; +18A48;TANGUT COMPONENT-585;Lo;0;L;;;;;N;;;;; +18A49;TANGUT COMPONENT-586;Lo;0;L;;;;;N;;;;; +18A4A;TANGUT COMPONENT-587;Lo;0;L;;;;;N;;;;; +18A4B;TANGUT COMPONENT-588;Lo;0;L;;;;;N;;;;; +18A4C;TANGUT COMPONENT-589;Lo;0;L;;;;;N;;;;; +18A4D;TANGUT COMPONENT-590;Lo;0;L;;;;;N;;;;; +18A4E;TANGUT COMPONENT-591;Lo;0;L;;;;;N;;;;; +18A4F;TANGUT COMPONENT-592;Lo;0;L;;;;;N;;;;; +18A50;TANGUT COMPONENT-593;Lo;0;L;;;;;N;;;;; +18A51;TANGUT COMPONENT-594;Lo;0;L;;;;;N;;;;; +18A52;TANGUT COMPONENT-595;Lo;0;L;;;;;N;;;;; +18A53;TANGUT COMPONENT-596;Lo;0;L;;;;;N;;;;; +18A54;TANGUT COMPONENT-597;Lo;0;L;;;;;N;;;;; +18A55;TANGUT COMPONENT-598;Lo;0;L;;;;;N;;;;; +18A56;TANGUT COMPONENT-599;Lo;0;L;;;;;N;;;;; +18A57;TANGUT COMPONENT-600;Lo;0;L;;;;;N;;;;; +18A58;TANGUT COMPONENT-601;Lo;0;L;;;;;N;;;;; +18A59;TANGUT COMPONENT-602;Lo;0;L;;;;;N;;;;; +18A5A;TANGUT COMPONENT-603;Lo;0;L;;;;;N;;;;; +18A5B;TANGUT COMPONENT-604;Lo;0;L;;;;;N;;;;; +18A5C;TANGUT COMPONENT-605;Lo;0;L;;;;;N;;;;; +18A5D;TANGUT COMPONENT-606;Lo;0;L;;;;;N;;;;; +18A5E;TANGUT COMPONENT-607;Lo;0;L;;;;;N;;;;; +18A5F;TANGUT COMPONENT-608;Lo;0;L;;;;;N;;;;; +18A60;TANGUT COMPONENT-609;Lo;0;L;;;;;N;;;;; +18A61;TANGUT COMPONENT-610;Lo;0;L;;;;;N;;;;; +18A62;TANGUT COMPONENT-611;Lo;0;L;;;;;N;;;;; +18A63;TANGUT COMPONENT-612;Lo;0;L;;;;;N;;;;; +18A64;TANGUT COMPONENT-613;Lo;0;L;;;;;N;;;;; +18A65;TANGUT COMPONENT-614;Lo;0;L;;;;;N;;;;; +18A66;TANGUT COMPONENT-615;Lo;0;L;;;;;N;;;;; +18A67;TANGUT COMPONENT-616;Lo;0;L;;;;;N;;;;; +18A68;TANGUT COMPONENT-617;Lo;0;L;;;;;N;;;;; +18A69;TANGUT COMPONENT-618;Lo;0;L;;;;;N;;;;; +18A6A;TANGUT COMPONENT-619;Lo;0;L;;;;;N;;;;; +18A6B;TANGUT COMPONENT-620;Lo;0;L;;;;;N;;;;; +18A6C;TANGUT COMPONENT-621;Lo;0;L;;;;;N;;;;; +18A6D;TANGUT COMPONENT-622;Lo;0;L;;;;;N;;;;; +18A6E;TANGUT COMPONENT-623;Lo;0;L;;;;;N;;;;; +18A6F;TANGUT COMPONENT-624;Lo;0;L;;;;;N;;;;; +18A70;TANGUT COMPONENT-625;Lo;0;L;;;;;N;;;;; +18A71;TANGUT COMPONENT-626;Lo;0;L;;;;;N;;;;; +18A72;TANGUT COMPONENT-627;Lo;0;L;;;;;N;;;;; +18A73;TANGUT COMPONENT-628;Lo;0;L;;;;;N;;;;; +18A74;TANGUT COMPONENT-629;Lo;0;L;;;;;N;;;;; +18A75;TANGUT COMPONENT-630;Lo;0;L;;;;;N;;;;; +18A76;TANGUT COMPONENT-631;Lo;0;L;;;;;N;;;;; +18A77;TANGUT COMPONENT-632;Lo;0;L;;;;;N;;;;; +18A78;TANGUT COMPONENT-633;Lo;0;L;;;;;N;;;;; +18A79;TANGUT COMPONENT-634;Lo;0;L;;;;;N;;;;; +18A7A;TANGUT COMPONENT-635;Lo;0;L;;;;;N;;;;; +18A7B;TANGUT COMPONENT-636;Lo;0;L;;;;;N;;;;; +18A7C;TANGUT COMPONENT-637;Lo;0;L;;;;;N;;;;; +18A7D;TANGUT COMPONENT-638;Lo;0;L;;;;;N;;;;; +18A7E;TANGUT COMPONENT-639;Lo;0;L;;;;;N;;;;; +18A7F;TANGUT COMPONENT-640;Lo;0;L;;;;;N;;;;; +18A80;TANGUT COMPONENT-641;Lo;0;L;;;;;N;;;;; +18A81;TANGUT COMPONENT-642;Lo;0;L;;;;;N;;;;; +18A82;TANGUT COMPONENT-643;Lo;0;L;;;;;N;;;;; +18A83;TANGUT COMPONENT-644;Lo;0;L;;;;;N;;;;; +18A84;TANGUT COMPONENT-645;Lo;0;L;;;;;N;;;;; +18A85;TANGUT COMPONENT-646;Lo;0;L;;;;;N;;;;; +18A86;TANGUT COMPONENT-647;Lo;0;L;;;;;N;;;;; +18A87;TANGUT COMPONENT-648;Lo;0;L;;;;;N;;;;; +18A88;TANGUT COMPONENT-649;Lo;0;L;;;;;N;;;;; +18A89;TANGUT COMPONENT-650;Lo;0;L;;;;;N;;;;; +18A8A;TANGUT COMPONENT-651;Lo;0;L;;;;;N;;;;; +18A8B;TANGUT COMPONENT-652;Lo;0;L;;;;;N;;;;; +18A8C;TANGUT COMPONENT-653;Lo;0;L;;;;;N;;;;; +18A8D;TANGUT COMPONENT-654;Lo;0;L;;;;;N;;;;; +18A8E;TANGUT COMPONENT-655;Lo;0;L;;;;;N;;;;; +18A8F;TANGUT COMPONENT-656;Lo;0;L;;;;;N;;;;; +18A90;TANGUT COMPONENT-657;Lo;0;L;;;;;N;;;;; +18A91;TANGUT COMPONENT-658;Lo;0;L;;;;;N;;;;; +18A92;TANGUT COMPONENT-659;Lo;0;L;;;;;N;;;;; +18A93;TANGUT COMPONENT-660;Lo;0;L;;;;;N;;;;; +18A94;TANGUT COMPONENT-661;Lo;0;L;;;;;N;;;;; +18A95;TANGUT COMPONENT-662;Lo;0;L;;;;;N;;;;; +18A96;TANGUT COMPONENT-663;Lo;0;L;;;;;N;;;;; +18A97;TANGUT COMPONENT-664;Lo;0;L;;;;;N;;;;; +18A98;TANGUT COMPONENT-665;Lo;0;L;;;;;N;;;;; +18A99;TANGUT COMPONENT-666;Lo;0;L;;;;;N;;;;; +18A9A;TANGUT COMPONENT-667;Lo;0;L;;;;;N;;;;; +18A9B;TANGUT COMPONENT-668;Lo;0;L;;;;;N;;;;; +18A9C;TANGUT COMPONENT-669;Lo;0;L;;;;;N;;;;; +18A9D;TANGUT COMPONENT-670;Lo;0;L;;;;;N;;;;; +18A9E;TANGUT COMPONENT-671;Lo;0;L;;;;;N;;;;; +18A9F;TANGUT COMPONENT-672;Lo;0;L;;;;;N;;;;; +18AA0;TANGUT COMPONENT-673;Lo;0;L;;;;;N;;;;; +18AA1;TANGUT COMPONENT-674;Lo;0;L;;;;;N;;;;; +18AA2;TANGUT COMPONENT-675;Lo;0;L;;;;;N;;;;; +18AA3;TANGUT COMPONENT-676;Lo;0;L;;;;;N;;;;; +18AA4;TANGUT COMPONENT-677;Lo;0;L;;;;;N;;;;; +18AA5;TANGUT COMPONENT-678;Lo;0;L;;;;;N;;;;; +18AA6;TANGUT COMPONENT-679;Lo;0;L;;;;;N;;;;; +18AA7;TANGUT COMPONENT-680;Lo;0;L;;;;;N;;;;; +18AA8;TANGUT COMPONENT-681;Lo;0;L;;;;;N;;;;; +18AA9;TANGUT COMPONENT-682;Lo;0;L;;;;;N;;;;; +18AAA;TANGUT COMPONENT-683;Lo;0;L;;;;;N;;;;; +18AAB;TANGUT COMPONENT-684;Lo;0;L;;;;;N;;;;; +18AAC;TANGUT COMPONENT-685;Lo;0;L;;;;;N;;;;; +18AAD;TANGUT COMPONENT-686;Lo;0;L;;;;;N;;;;; +18AAE;TANGUT COMPONENT-687;Lo;0;L;;;;;N;;;;; +18AAF;TANGUT COMPONENT-688;Lo;0;L;;;;;N;;;;; +18AB0;TANGUT COMPONENT-689;Lo;0;L;;;;;N;;;;; +18AB1;TANGUT COMPONENT-690;Lo;0;L;;;;;N;;;;; +18AB2;TANGUT COMPONENT-691;Lo;0;L;;;;;N;;;;; +18AB3;TANGUT COMPONENT-692;Lo;0;L;;;;;N;;;;; +18AB4;TANGUT COMPONENT-693;Lo;0;L;;;;;N;;;;; +18AB5;TANGUT COMPONENT-694;Lo;0;L;;;;;N;;;;; +18AB6;TANGUT COMPONENT-695;Lo;0;L;;;;;N;;;;; +18AB7;TANGUT COMPONENT-696;Lo;0;L;;;;;N;;;;; +18AB8;TANGUT COMPONENT-697;Lo;0;L;;;;;N;;;;; +18AB9;TANGUT COMPONENT-698;Lo;0;L;;;;;N;;;;; +18ABA;TANGUT COMPONENT-699;Lo;0;L;;;;;N;;;;; +18ABB;TANGUT COMPONENT-700;Lo;0;L;;;;;N;;;;; +18ABC;TANGUT COMPONENT-701;Lo;0;L;;;;;N;;;;; +18ABD;TANGUT COMPONENT-702;Lo;0;L;;;;;N;;;;; +18ABE;TANGUT COMPONENT-703;Lo;0;L;;;;;N;;;;; +18ABF;TANGUT COMPONENT-704;Lo;0;L;;;;;N;;;;; +18AC0;TANGUT COMPONENT-705;Lo;0;L;;;;;N;;;;; +18AC1;TANGUT COMPONENT-706;Lo;0;L;;;;;N;;;;; +18AC2;TANGUT COMPONENT-707;Lo;0;L;;;;;N;;;;; +18AC3;TANGUT COMPONENT-708;Lo;0;L;;;;;N;;;;; +18AC4;TANGUT COMPONENT-709;Lo;0;L;;;;;N;;;;; +18AC5;TANGUT COMPONENT-710;Lo;0;L;;;;;N;;;;; +18AC6;TANGUT COMPONENT-711;Lo;0;L;;;;;N;;;;; +18AC7;TANGUT COMPONENT-712;Lo;0;L;;;;;N;;;;; +18AC8;TANGUT COMPONENT-713;Lo;0;L;;;;;N;;;;; +18AC9;TANGUT COMPONENT-714;Lo;0;L;;;;;N;;;;; +18ACA;TANGUT COMPONENT-715;Lo;0;L;;;;;N;;;;; +18ACB;TANGUT COMPONENT-716;Lo;0;L;;;;;N;;;;; +18ACC;TANGUT COMPONENT-717;Lo;0;L;;;;;N;;;;; +18ACD;TANGUT COMPONENT-718;Lo;0;L;;;;;N;;;;; +18ACE;TANGUT COMPONENT-719;Lo;0;L;;;;;N;;;;; +18ACF;TANGUT COMPONENT-720;Lo;0;L;;;;;N;;;;; +18AD0;TANGUT COMPONENT-721;Lo;0;L;;;;;N;;;;; +18AD1;TANGUT COMPONENT-722;Lo;0;L;;;;;N;;;;; +18AD2;TANGUT COMPONENT-723;Lo;0;L;;;;;N;;;;; +18AD3;TANGUT COMPONENT-724;Lo;0;L;;;;;N;;;;; +18AD4;TANGUT COMPONENT-725;Lo;0;L;;;;;N;;;;; +18AD5;TANGUT COMPONENT-726;Lo;0;L;;;;;N;;;;; +18AD6;TANGUT COMPONENT-727;Lo;0;L;;;;;N;;;;; +18AD7;TANGUT COMPONENT-728;Lo;0;L;;;;;N;;;;; +18AD8;TANGUT COMPONENT-729;Lo;0;L;;;;;N;;;;; +18AD9;TANGUT COMPONENT-730;Lo;0;L;;;;;N;;;;; +18ADA;TANGUT COMPONENT-731;Lo;0;L;;;;;N;;;;; +18ADB;TANGUT COMPONENT-732;Lo;0;L;;;;;N;;;;; +18ADC;TANGUT COMPONENT-733;Lo;0;L;;;;;N;;;;; +18ADD;TANGUT COMPONENT-734;Lo;0;L;;;;;N;;;;; +18ADE;TANGUT COMPONENT-735;Lo;0;L;;;;;N;;;;; +18ADF;TANGUT COMPONENT-736;Lo;0;L;;;;;N;;;;; +18AE0;TANGUT COMPONENT-737;Lo;0;L;;;;;N;;;;; +18AE1;TANGUT COMPONENT-738;Lo;0;L;;;;;N;;;;; +18AE2;TANGUT COMPONENT-739;Lo;0;L;;;;;N;;;;; +18AE3;TANGUT COMPONENT-740;Lo;0;L;;;;;N;;;;; +18AE4;TANGUT COMPONENT-741;Lo;0;L;;;;;N;;;;; +18AE5;TANGUT COMPONENT-742;Lo;0;L;;;;;N;;;;; +18AE6;TANGUT COMPONENT-743;Lo;0;L;;;;;N;;;;; +18AE7;TANGUT COMPONENT-744;Lo;0;L;;;;;N;;;;; +18AE8;TANGUT COMPONENT-745;Lo;0;L;;;;;N;;;;; +18AE9;TANGUT COMPONENT-746;Lo;0;L;;;;;N;;;;; +18AEA;TANGUT COMPONENT-747;Lo;0;L;;;;;N;;;;; +18AEB;TANGUT COMPONENT-748;Lo;0;L;;;;;N;;;;; +18AEC;TANGUT COMPONENT-749;Lo;0;L;;;;;N;;;;; +18AED;TANGUT COMPONENT-750;Lo;0;L;;;;;N;;;;; +18AEE;TANGUT COMPONENT-751;Lo;0;L;;;;;N;;;;; +18AEF;TANGUT COMPONENT-752;Lo;0;L;;;;;N;;;;; +18AF0;TANGUT COMPONENT-753;Lo;0;L;;;;;N;;;;; +18AF1;TANGUT COMPONENT-754;Lo;0;L;;;;;N;;;;; +18AF2;TANGUT COMPONENT-755;Lo;0;L;;;;;N;;;;; +1B000;KATAKANA LETTER ARCHAIC E;Lo;0;L;;;;;N;;;;; +1B001;HIRAGANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;; +1B002;HENTAIGANA LETTER A-1;Lo;0;L;;;;;N;;;;; +1B003;HENTAIGANA LETTER A-2;Lo;0;L;;;;;N;;;;; +1B004;HENTAIGANA LETTER A-3;Lo;0;L;;;;;N;;;;; +1B005;HENTAIGANA LETTER A-WO;Lo;0;L;;;;;N;;;;; +1B006;HENTAIGANA LETTER I-1;Lo;0;L;;;;;N;;;;; +1B007;HENTAIGANA LETTER I-2;Lo;0;L;;;;;N;;;;; +1B008;HENTAIGANA LETTER I-3;Lo;0;L;;;;;N;;;;; +1B009;HENTAIGANA LETTER I-4;Lo;0;L;;;;;N;;;;; +1B00A;HENTAIGANA LETTER U-1;Lo;0;L;;;;;N;;;;; +1B00B;HENTAIGANA LETTER U-2;Lo;0;L;;;;;N;;;;; +1B00C;HENTAIGANA LETTER U-3;Lo;0;L;;;;;N;;;;; +1B00D;HENTAIGANA LETTER U-4;Lo;0;L;;;;;N;;;;; +1B00E;HENTAIGANA LETTER U-5;Lo;0;L;;;;;N;;;;; +1B00F;HENTAIGANA LETTER E-2;Lo;0;L;;;;;N;;;;; +1B010;HENTAIGANA LETTER E-3;Lo;0;L;;;;;N;;;;; +1B011;HENTAIGANA LETTER E-4;Lo;0;L;;;;;N;;;;; +1B012;HENTAIGANA LETTER E-5;Lo;0;L;;;;;N;;;;; +1B013;HENTAIGANA LETTER E-6;Lo;0;L;;;;;N;;;;; +1B014;HENTAIGANA LETTER O-1;Lo;0;L;;;;;N;;;;; +1B015;HENTAIGANA LETTER O-2;Lo;0;L;;;;;N;;;;; +1B016;HENTAIGANA LETTER O-3;Lo;0;L;;;;;N;;;;; +1B017;HENTAIGANA LETTER KA-1;Lo;0;L;;;;;N;;;;; +1B018;HENTAIGANA LETTER KA-2;Lo;0;L;;;;;N;;;;; +1B019;HENTAIGANA LETTER KA-3;Lo;0;L;;;;;N;;;;; +1B01A;HENTAIGANA LETTER KA-4;Lo;0;L;;;;;N;;;;; +1B01B;HENTAIGANA LETTER KA-5;Lo;0;L;;;;;N;;;;; +1B01C;HENTAIGANA LETTER KA-6;Lo;0;L;;;;;N;;;;; +1B01D;HENTAIGANA LETTER KA-7;Lo;0;L;;;;;N;;;;; +1B01E;HENTAIGANA LETTER KA-8;Lo;0;L;;;;;N;;;;; +1B01F;HENTAIGANA LETTER KA-9;Lo;0;L;;;;;N;;;;; +1B020;HENTAIGANA LETTER KA-10;Lo;0;L;;;;;N;;;;; +1B021;HENTAIGANA LETTER KA-11;Lo;0;L;;;;;N;;;;; +1B022;HENTAIGANA LETTER KA-KE;Lo;0;L;;;;;N;;;;; +1B023;HENTAIGANA LETTER KI-1;Lo;0;L;;;;;N;;;;; +1B024;HENTAIGANA LETTER KI-2;Lo;0;L;;;;;N;;;;; +1B025;HENTAIGANA LETTER KI-3;Lo;0;L;;;;;N;;;;; +1B026;HENTAIGANA LETTER KI-4;Lo;0;L;;;;;N;;;;; +1B027;HENTAIGANA LETTER KI-5;Lo;0;L;;;;;N;;;;; +1B028;HENTAIGANA LETTER KI-6;Lo;0;L;;;;;N;;;;; +1B029;HENTAIGANA LETTER KI-7;Lo;0;L;;;;;N;;;;; +1B02A;HENTAIGANA LETTER KI-8;Lo;0;L;;;;;N;;;;; +1B02B;HENTAIGANA LETTER KU-1;Lo;0;L;;;;;N;;;;; +1B02C;HENTAIGANA LETTER KU-2;Lo;0;L;;;;;N;;;;; +1B02D;HENTAIGANA LETTER KU-3;Lo;0;L;;;;;N;;;;; +1B02E;HENTAIGANA LETTER KU-4;Lo;0;L;;;;;N;;;;; +1B02F;HENTAIGANA LETTER KU-5;Lo;0;L;;;;;N;;;;; +1B030;HENTAIGANA LETTER KU-6;Lo;0;L;;;;;N;;;;; +1B031;HENTAIGANA LETTER KU-7;Lo;0;L;;;;;N;;;;; +1B032;HENTAIGANA LETTER KE-1;Lo;0;L;;;;;N;;;;; +1B033;HENTAIGANA LETTER KE-2;Lo;0;L;;;;;N;;;;; +1B034;HENTAIGANA LETTER KE-3;Lo;0;L;;;;;N;;;;; +1B035;HENTAIGANA LETTER KE-4;Lo;0;L;;;;;N;;;;; +1B036;HENTAIGANA LETTER KE-5;Lo;0;L;;;;;N;;;;; +1B037;HENTAIGANA LETTER KE-6;Lo;0;L;;;;;N;;;;; +1B038;HENTAIGANA LETTER KO-1;Lo;0;L;;;;;N;;;;; +1B039;HENTAIGANA LETTER KO-2;Lo;0;L;;;;;N;;;;; +1B03A;HENTAIGANA LETTER KO-3;Lo;0;L;;;;;N;;;;; +1B03B;HENTAIGANA LETTER KO-KI;Lo;0;L;;;;;N;;;;; +1B03C;HENTAIGANA LETTER SA-1;Lo;0;L;;;;;N;;;;; +1B03D;HENTAIGANA LETTER SA-2;Lo;0;L;;;;;N;;;;; +1B03E;HENTAIGANA LETTER SA-3;Lo;0;L;;;;;N;;;;; +1B03F;HENTAIGANA LETTER SA-4;Lo;0;L;;;;;N;;;;; +1B040;HENTAIGANA LETTER SA-5;Lo;0;L;;;;;N;;;;; +1B041;HENTAIGANA LETTER SA-6;Lo;0;L;;;;;N;;;;; +1B042;HENTAIGANA LETTER SA-7;Lo;0;L;;;;;N;;;;; +1B043;HENTAIGANA LETTER SA-8;Lo;0;L;;;;;N;;;;; +1B044;HENTAIGANA LETTER SI-1;Lo;0;L;;;;;N;;;;; +1B045;HENTAIGANA LETTER SI-2;Lo;0;L;;;;;N;;;;; +1B046;HENTAIGANA LETTER SI-3;Lo;0;L;;;;;N;;;;; +1B047;HENTAIGANA LETTER SI-4;Lo;0;L;;;;;N;;;;; +1B048;HENTAIGANA LETTER SI-5;Lo;0;L;;;;;N;;;;; +1B049;HENTAIGANA LETTER SI-6;Lo;0;L;;;;;N;;;;; +1B04A;HENTAIGANA LETTER SU-1;Lo;0;L;;;;;N;;;;; +1B04B;HENTAIGANA LETTER SU-2;Lo;0;L;;;;;N;;;;; +1B04C;HENTAIGANA LETTER SU-3;Lo;0;L;;;;;N;;;;; +1B04D;HENTAIGANA LETTER SU-4;Lo;0;L;;;;;N;;;;; +1B04E;HENTAIGANA LETTER SU-5;Lo;0;L;;;;;N;;;;; +1B04F;HENTAIGANA LETTER SU-6;Lo;0;L;;;;;N;;;;; +1B050;HENTAIGANA LETTER SU-7;Lo;0;L;;;;;N;;;;; +1B051;HENTAIGANA LETTER SU-8;Lo;0;L;;;;;N;;;;; +1B052;HENTAIGANA LETTER SE-1;Lo;0;L;;;;;N;;;;; +1B053;HENTAIGANA LETTER SE-2;Lo;0;L;;;;;N;;;;; +1B054;HENTAIGANA LETTER SE-3;Lo;0;L;;;;;N;;;;; +1B055;HENTAIGANA LETTER SE-4;Lo;0;L;;;;;N;;;;; +1B056;HENTAIGANA LETTER SE-5;Lo;0;L;;;;;N;;;;; +1B057;HENTAIGANA LETTER SO-1;Lo;0;L;;;;;N;;;;; +1B058;HENTAIGANA LETTER SO-2;Lo;0;L;;;;;N;;;;; +1B059;HENTAIGANA LETTER SO-3;Lo;0;L;;;;;N;;;;; +1B05A;HENTAIGANA LETTER SO-4;Lo;0;L;;;;;N;;;;; +1B05B;HENTAIGANA LETTER SO-5;Lo;0;L;;;;;N;;;;; +1B05C;HENTAIGANA LETTER SO-6;Lo;0;L;;;;;N;;;;; +1B05D;HENTAIGANA LETTER SO-7;Lo;0;L;;;;;N;;;;; +1B05E;HENTAIGANA LETTER TA-1;Lo;0;L;;;;;N;;;;; +1B05F;HENTAIGANA LETTER TA-2;Lo;0;L;;;;;N;;;;; +1B060;HENTAIGANA LETTER TA-3;Lo;0;L;;;;;N;;;;; +1B061;HENTAIGANA LETTER TA-4;Lo;0;L;;;;;N;;;;; +1B062;HENTAIGANA LETTER TI-1;Lo;0;L;;;;;N;;;;; +1B063;HENTAIGANA LETTER TI-2;Lo;0;L;;;;;N;;;;; +1B064;HENTAIGANA LETTER TI-3;Lo;0;L;;;;;N;;;;; +1B065;HENTAIGANA LETTER TI-4;Lo;0;L;;;;;N;;;;; +1B066;HENTAIGANA LETTER TI-5;Lo;0;L;;;;;N;;;;; +1B067;HENTAIGANA LETTER TI-6;Lo;0;L;;;;;N;;;;; +1B068;HENTAIGANA LETTER TI-7;Lo;0;L;;;;;N;;;;; +1B069;HENTAIGANA LETTER TU-1;Lo;0;L;;;;;N;;;;; +1B06A;HENTAIGANA LETTER TU-2;Lo;0;L;;;;;N;;;;; +1B06B;HENTAIGANA LETTER TU-3;Lo;0;L;;;;;N;;;;; +1B06C;HENTAIGANA LETTER TU-4;Lo;0;L;;;;;N;;;;; +1B06D;HENTAIGANA LETTER TU-TO;Lo;0;L;;;;;N;;;;; +1B06E;HENTAIGANA LETTER TE-1;Lo;0;L;;;;;N;;;;; +1B06F;HENTAIGANA LETTER TE-2;Lo;0;L;;;;;N;;;;; +1B070;HENTAIGANA LETTER TE-3;Lo;0;L;;;;;N;;;;; +1B071;HENTAIGANA LETTER TE-4;Lo;0;L;;;;;N;;;;; +1B072;HENTAIGANA LETTER TE-5;Lo;0;L;;;;;N;;;;; +1B073;HENTAIGANA LETTER TE-6;Lo;0;L;;;;;N;;;;; +1B074;HENTAIGANA LETTER TE-7;Lo;0;L;;;;;N;;;;; +1B075;HENTAIGANA LETTER TE-8;Lo;0;L;;;;;N;;;;; +1B076;HENTAIGANA LETTER TE-9;Lo;0;L;;;;;N;;;;; +1B077;HENTAIGANA LETTER TO-1;Lo;0;L;;;;;N;;;;; +1B078;HENTAIGANA LETTER TO-2;Lo;0;L;;;;;N;;;;; +1B079;HENTAIGANA LETTER TO-3;Lo;0;L;;;;;N;;;;; +1B07A;HENTAIGANA LETTER TO-4;Lo;0;L;;;;;N;;;;; +1B07B;HENTAIGANA LETTER TO-5;Lo;0;L;;;;;N;;;;; +1B07C;HENTAIGANA LETTER TO-6;Lo;0;L;;;;;N;;;;; +1B07D;HENTAIGANA LETTER TO-RA;Lo;0;L;;;;;N;;;;; +1B07E;HENTAIGANA LETTER NA-1;Lo;0;L;;;;;N;;;;; +1B07F;HENTAIGANA LETTER NA-2;Lo;0;L;;;;;N;;;;; +1B080;HENTAIGANA LETTER NA-3;Lo;0;L;;;;;N;;;;; +1B081;HENTAIGANA LETTER NA-4;Lo;0;L;;;;;N;;;;; +1B082;HENTAIGANA LETTER NA-5;Lo;0;L;;;;;N;;;;; +1B083;HENTAIGANA LETTER NA-6;Lo;0;L;;;;;N;;;;; +1B084;HENTAIGANA LETTER NA-7;Lo;0;L;;;;;N;;;;; +1B085;HENTAIGANA LETTER NA-8;Lo;0;L;;;;;N;;;;; +1B086;HENTAIGANA LETTER NA-9;Lo;0;L;;;;;N;;;;; +1B087;HENTAIGANA LETTER NI-1;Lo;0;L;;;;;N;;;;; +1B088;HENTAIGANA LETTER NI-2;Lo;0;L;;;;;N;;;;; +1B089;HENTAIGANA LETTER NI-3;Lo;0;L;;;;;N;;;;; +1B08A;HENTAIGANA LETTER NI-4;Lo;0;L;;;;;N;;;;; +1B08B;HENTAIGANA LETTER NI-5;Lo;0;L;;;;;N;;;;; +1B08C;HENTAIGANA LETTER NI-6;Lo;0;L;;;;;N;;;;; +1B08D;HENTAIGANA LETTER NI-7;Lo;0;L;;;;;N;;;;; +1B08E;HENTAIGANA LETTER NI-TE;Lo;0;L;;;;;N;;;;; +1B08F;HENTAIGANA LETTER NU-1;Lo;0;L;;;;;N;;;;; +1B090;HENTAIGANA LETTER NU-2;Lo;0;L;;;;;N;;;;; +1B091;HENTAIGANA LETTER NU-3;Lo;0;L;;;;;N;;;;; +1B092;HENTAIGANA LETTER NE-1;Lo;0;L;;;;;N;;;;; +1B093;HENTAIGANA LETTER NE-2;Lo;0;L;;;;;N;;;;; +1B094;HENTAIGANA LETTER NE-3;Lo;0;L;;;;;N;;;;; +1B095;HENTAIGANA LETTER NE-4;Lo;0;L;;;;;N;;;;; +1B096;HENTAIGANA LETTER NE-5;Lo;0;L;;;;;N;;;;; +1B097;HENTAIGANA LETTER NE-6;Lo;0;L;;;;;N;;;;; +1B098;HENTAIGANA LETTER NE-KO;Lo;0;L;;;;;N;;;;; +1B099;HENTAIGANA LETTER NO-1;Lo;0;L;;;;;N;;;;; +1B09A;HENTAIGANA LETTER NO-2;Lo;0;L;;;;;N;;;;; +1B09B;HENTAIGANA LETTER NO-3;Lo;0;L;;;;;N;;;;; +1B09C;HENTAIGANA LETTER NO-4;Lo;0;L;;;;;N;;;;; +1B09D;HENTAIGANA LETTER NO-5;Lo;0;L;;;;;N;;;;; +1B09E;HENTAIGANA LETTER HA-1;Lo;0;L;;;;;N;;;;; +1B09F;HENTAIGANA LETTER HA-2;Lo;0;L;;;;;N;;;;; +1B0A0;HENTAIGANA LETTER HA-3;Lo;0;L;;;;;N;;;;; +1B0A1;HENTAIGANA LETTER HA-4;Lo;0;L;;;;;N;;;;; +1B0A2;HENTAIGANA LETTER HA-5;Lo;0;L;;;;;N;;;;; +1B0A3;HENTAIGANA LETTER HA-6;Lo;0;L;;;;;N;;;;; +1B0A4;HENTAIGANA LETTER HA-7;Lo;0;L;;;;;N;;;;; +1B0A5;HENTAIGANA LETTER HA-8;Lo;0;L;;;;;N;;;;; +1B0A6;HENTAIGANA LETTER HA-9;Lo;0;L;;;;;N;;;;; +1B0A7;HENTAIGANA LETTER HA-10;Lo;0;L;;;;;N;;;;; +1B0A8;HENTAIGANA LETTER HA-11;Lo;0;L;;;;;N;;;;; +1B0A9;HENTAIGANA LETTER HI-1;Lo;0;L;;;;;N;;;;; +1B0AA;HENTAIGANA LETTER HI-2;Lo;0;L;;;;;N;;;;; +1B0AB;HENTAIGANA LETTER HI-3;Lo;0;L;;;;;N;;;;; +1B0AC;HENTAIGANA LETTER HI-4;Lo;0;L;;;;;N;;;;; +1B0AD;HENTAIGANA LETTER HI-5;Lo;0;L;;;;;N;;;;; +1B0AE;HENTAIGANA LETTER HI-6;Lo;0;L;;;;;N;;;;; +1B0AF;HENTAIGANA LETTER HI-7;Lo;0;L;;;;;N;;;;; +1B0B0;HENTAIGANA LETTER HU-1;Lo;0;L;;;;;N;;;;; +1B0B1;HENTAIGANA LETTER HU-2;Lo;0;L;;;;;N;;;;; +1B0B2;HENTAIGANA LETTER HU-3;Lo;0;L;;;;;N;;;;; +1B0B3;HENTAIGANA LETTER HE-1;Lo;0;L;;;;;N;;;;; +1B0B4;HENTAIGANA LETTER HE-2;Lo;0;L;;;;;N;;;;; +1B0B5;HENTAIGANA LETTER HE-3;Lo;0;L;;;;;N;;;;; +1B0B6;HENTAIGANA LETTER HE-4;Lo;0;L;;;;;N;;;;; +1B0B7;HENTAIGANA LETTER HE-5;Lo;0;L;;;;;N;;;;; +1B0B8;HENTAIGANA LETTER HE-6;Lo;0;L;;;;;N;;;;; +1B0B9;HENTAIGANA LETTER HE-7;Lo;0;L;;;;;N;;;;; +1B0BA;HENTAIGANA LETTER HO-1;Lo;0;L;;;;;N;;;;; +1B0BB;HENTAIGANA LETTER HO-2;Lo;0;L;;;;;N;;;;; +1B0BC;HENTAIGANA LETTER HO-3;Lo;0;L;;;;;N;;;;; +1B0BD;HENTAIGANA LETTER HO-4;Lo;0;L;;;;;N;;;;; +1B0BE;HENTAIGANA LETTER HO-5;Lo;0;L;;;;;N;;;;; +1B0BF;HENTAIGANA LETTER HO-6;Lo;0;L;;;;;N;;;;; +1B0C0;HENTAIGANA LETTER HO-7;Lo;0;L;;;;;N;;;;; +1B0C1;HENTAIGANA LETTER HO-8;Lo;0;L;;;;;N;;;;; +1B0C2;HENTAIGANA LETTER MA-1;Lo;0;L;;;;;N;;;;; +1B0C3;HENTAIGANA LETTER MA-2;Lo;0;L;;;;;N;;;;; +1B0C4;HENTAIGANA LETTER MA-3;Lo;0;L;;;;;N;;;;; +1B0C5;HENTAIGANA LETTER MA-4;Lo;0;L;;;;;N;;;;; +1B0C6;HENTAIGANA LETTER MA-5;Lo;0;L;;;;;N;;;;; +1B0C7;HENTAIGANA LETTER MA-6;Lo;0;L;;;;;N;;;;; +1B0C8;HENTAIGANA LETTER MA-7;Lo;0;L;;;;;N;;;;; +1B0C9;HENTAIGANA LETTER MI-1;Lo;0;L;;;;;N;;;;; +1B0CA;HENTAIGANA LETTER MI-2;Lo;0;L;;;;;N;;;;; +1B0CB;HENTAIGANA LETTER MI-3;Lo;0;L;;;;;N;;;;; +1B0CC;HENTAIGANA LETTER MI-4;Lo;0;L;;;;;N;;;;; +1B0CD;HENTAIGANA LETTER MI-5;Lo;0;L;;;;;N;;;;; +1B0CE;HENTAIGANA LETTER MI-6;Lo;0;L;;;;;N;;;;; +1B0CF;HENTAIGANA LETTER MI-7;Lo;0;L;;;;;N;;;;; +1B0D0;HENTAIGANA LETTER MU-1;Lo;0;L;;;;;N;;;;; +1B0D1;HENTAIGANA LETTER MU-2;Lo;0;L;;;;;N;;;;; +1B0D2;HENTAIGANA LETTER MU-3;Lo;0;L;;;;;N;;;;; +1B0D3;HENTAIGANA LETTER MU-4;Lo;0;L;;;;;N;;;;; +1B0D4;HENTAIGANA LETTER ME-1;Lo;0;L;;;;;N;;;;; +1B0D5;HENTAIGANA LETTER ME-2;Lo;0;L;;;;;N;;;;; +1B0D6;HENTAIGANA LETTER ME-MA;Lo;0;L;;;;;N;;;;; +1B0D7;HENTAIGANA LETTER MO-1;Lo;0;L;;;;;N;;;;; +1B0D8;HENTAIGANA LETTER MO-2;Lo;0;L;;;;;N;;;;; +1B0D9;HENTAIGANA LETTER MO-3;Lo;0;L;;;;;N;;;;; +1B0DA;HENTAIGANA LETTER MO-4;Lo;0;L;;;;;N;;;;; +1B0DB;HENTAIGANA LETTER MO-5;Lo;0;L;;;;;N;;;;; +1B0DC;HENTAIGANA LETTER MO-6;Lo;0;L;;;;;N;;;;; +1B0DD;HENTAIGANA LETTER YA-1;Lo;0;L;;;;;N;;;;; +1B0DE;HENTAIGANA LETTER YA-2;Lo;0;L;;;;;N;;;;; +1B0DF;HENTAIGANA LETTER YA-3;Lo;0;L;;;;;N;;;;; +1B0E0;HENTAIGANA LETTER YA-4;Lo;0;L;;;;;N;;;;; +1B0E1;HENTAIGANA LETTER YA-5;Lo;0;L;;;;;N;;;;; +1B0E2;HENTAIGANA LETTER YA-YO;Lo;0;L;;;;;N;;;;; +1B0E3;HENTAIGANA LETTER YU-1;Lo;0;L;;;;;N;;;;; +1B0E4;HENTAIGANA LETTER YU-2;Lo;0;L;;;;;N;;;;; +1B0E5;HENTAIGANA LETTER YU-3;Lo;0;L;;;;;N;;;;; +1B0E6;HENTAIGANA LETTER YU-4;Lo;0;L;;;;;N;;;;; +1B0E7;HENTAIGANA LETTER YO-1;Lo;0;L;;;;;N;;;;; +1B0E8;HENTAIGANA LETTER YO-2;Lo;0;L;;;;;N;;;;; +1B0E9;HENTAIGANA LETTER YO-3;Lo;0;L;;;;;N;;;;; +1B0EA;HENTAIGANA LETTER YO-4;Lo;0;L;;;;;N;;;;; +1B0EB;HENTAIGANA LETTER YO-5;Lo;0;L;;;;;N;;;;; +1B0EC;HENTAIGANA LETTER YO-6;Lo;0;L;;;;;N;;;;; +1B0ED;HENTAIGANA LETTER RA-1;Lo;0;L;;;;;N;;;;; +1B0EE;HENTAIGANA LETTER RA-2;Lo;0;L;;;;;N;;;;; +1B0EF;HENTAIGANA LETTER RA-3;Lo;0;L;;;;;N;;;;; +1B0F0;HENTAIGANA LETTER RA-4;Lo;0;L;;;;;N;;;;; +1B0F1;HENTAIGANA LETTER RI-1;Lo;0;L;;;;;N;;;;; +1B0F2;HENTAIGANA LETTER RI-2;Lo;0;L;;;;;N;;;;; +1B0F3;HENTAIGANA LETTER RI-3;Lo;0;L;;;;;N;;;;; +1B0F4;HENTAIGANA LETTER RI-4;Lo;0;L;;;;;N;;;;; +1B0F5;HENTAIGANA LETTER RI-5;Lo;0;L;;;;;N;;;;; +1B0F6;HENTAIGANA LETTER RI-6;Lo;0;L;;;;;N;;;;; +1B0F7;HENTAIGANA LETTER RI-7;Lo;0;L;;;;;N;;;;; +1B0F8;HENTAIGANA LETTER RU-1;Lo;0;L;;;;;N;;;;; +1B0F9;HENTAIGANA LETTER RU-2;Lo;0;L;;;;;N;;;;; +1B0FA;HENTAIGANA LETTER RU-3;Lo;0;L;;;;;N;;;;; +1B0FB;HENTAIGANA LETTER RU-4;Lo;0;L;;;;;N;;;;; +1B0FC;HENTAIGANA LETTER RU-5;Lo;0;L;;;;;N;;;;; +1B0FD;HENTAIGANA LETTER RU-6;Lo;0;L;;;;;N;;;;; +1B0FE;HENTAIGANA LETTER RE-1;Lo;0;L;;;;;N;;;;; +1B0FF;HENTAIGANA LETTER RE-2;Lo;0;L;;;;;N;;;;; +1B100;HENTAIGANA LETTER RE-3;Lo;0;L;;;;;N;;;;; +1B101;HENTAIGANA LETTER RE-4;Lo;0;L;;;;;N;;;;; +1B102;HENTAIGANA LETTER RO-1;Lo;0;L;;;;;N;;;;; +1B103;HENTAIGANA LETTER RO-2;Lo;0;L;;;;;N;;;;; +1B104;HENTAIGANA LETTER RO-3;Lo;0;L;;;;;N;;;;; +1B105;HENTAIGANA LETTER RO-4;Lo;0;L;;;;;N;;;;; +1B106;HENTAIGANA LETTER RO-5;Lo;0;L;;;;;N;;;;; +1B107;HENTAIGANA LETTER RO-6;Lo;0;L;;;;;N;;;;; +1B108;HENTAIGANA LETTER WA-1;Lo;0;L;;;;;N;;;;; +1B109;HENTAIGANA LETTER WA-2;Lo;0;L;;;;;N;;;;; +1B10A;HENTAIGANA LETTER WA-3;Lo;0;L;;;;;N;;;;; +1B10B;HENTAIGANA LETTER WA-4;Lo;0;L;;;;;N;;;;; +1B10C;HENTAIGANA LETTER WA-5;Lo;0;L;;;;;N;;;;; +1B10D;HENTAIGANA LETTER WI-1;Lo;0;L;;;;;N;;;;; +1B10E;HENTAIGANA LETTER WI-2;Lo;0;L;;;;;N;;;;; +1B10F;HENTAIGANA LETTER WI-3;Lo;0;L;;;;;N;;;;; +1B110;HENTAIGANA LETTER WI-4;Lo;0;L;;;;;N;;;;; +1B111;HENTAIGANA LETTER WI-5;Lo;0;L;;;;;N;;;;; +1B112;HENTAIGANA LETTER WE-1;Lo;0;L;;;;;N;;;;; +1B113;HENTAIGANA LETTER WE-2;Lo;0;L;;;;;N;;;;; +1B114;HENTAIGANA LETTER WE-3;Lo;0;L;;;;;N;;;;; +1B115;HENTAIGANA LETTER WE-4;Lo;0;L;;;;;N;;;;; +1B116;HENTAIGANA LETTER WO-1;Lo;0;L;;;;;N;;;;; +1B117;HENTAIGANA LETTER WO-2;Lo;0;L;;;;;N;;;;; +1B118;HENTAIGANA LETTER WO-3;Lo;0;L;;;;;N;;;;; +1B119;HENTAIGANA LETTER WO-4;Lo;0;L;;;;;N;;;;; +1B11A;HENTAIGANA LETTER WO-5;Lo;0;L;;;;;N;;;;; +1B11B;HENTAIGANA LETTER WO-6;Lo;0;L;;;;;N;;;;; +1B11C;HENTAIGANA LETTER WO-7;Lo;0;L;;;;;N;;;;; +1B11D;HENTAIGANA LETTER N-MU-MO-1;Lo;0;L;;;;;N;;;;; +1B11E;HENTAIGANA LETTER N-MU-MO-2;Lo;0;L;;;;;N;;;;; +1B150;HIRAGANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;; +1B151;HIRAGANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;; +1B152;HIRAGANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;; +1B164;KATAKANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;; +1B165;KATAKANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;; +1B166;KATAKANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;; +1B167;KATAKANA LETTER SMALL N;Lo;0;L;;;;;N;;;;; +1B170;NUSHU CHARACTER-1B170;Lo;0;L;;;;;N;;;;; +1B171;NUSHU CHARACTER-1B171;Lo;0;L;;;;;N;;;;; +1B172;NUSHU CHARACTER-1B172;Lo;0;L;;;;;N;;;;; +1B173;NUSHU CHARACTER-1B173;Lo;0;L;;;;;N;;;;; +1B174;NUSHU CHARACTER-1B174;Lo;0;L;;;;;N;;;;; +1B175;NUSHU CHARACTER-1B175;Lo;0;L;;;;;N;;;;; +1B176;NUSHU CHARACTER-1B176;Lo;0;L;;;;;N;;;;; +1B177;NUSHU CHARACTER-1B177;Lo;0;L;;;;;N;;;;; +1B178;NUSHU CHARACTER-1B178;Lo;0;L;;;;;N;;;;; +1B179;NUSHU CHARACTER-1B179;Lo;0;L;;;;;N;;;;; +1B17A;NUSHU CHARACTER-1B17A;Lo;0;L;;;;;N;;;;; +1B17B;NUSHU CHARACTER-1B17B;Lo;0;L;;;;;N;;;;; +1B17C;NUSHU CHARACTER-1B17C;Lo;0;L;;;;;N;;;;; +1B17D;NUSHU CHARACTER-1B17D;Lo;0;L;;;;;N;;;;; +1B17E;NUSHU CHARACTER-1B17E;Lo;0;L;;;;;N;;;;; +1B17F;NUSHU CHARACTER-1B17F;Lo;0;L;;;;;N;;;;; +1B180;NUSHU CHARACTER-1B180;Lo;0;L;;;;;N;;;;; +1B181;NUSHU CHARACTER-1B181;Lo;0;L;;;;;N;;;;; +1B182;NUSHU CHARACTER-1B182;Lo;0;L;;;;;N;;;;; +1B183;NUSHU CHARACTER-1B183;Lo;0;L;;;;;N;;;;; +1B184;NUSHU CHARACTER-1B184;Lo;0;L;;;;;N;;;;; +1B185;NUSHU CHARACTER-1B185;Lo;0;L;;;;;N;;;;; +1B186;NUSHU CHARACTER-1B186;Lo;0;L;;;;;N;;;;; +1B187;NUSHU CHARACTER-1B187;Lo;0;L;;;;;N;;;;; +1B188;NUSHU CHARACTER-1B188;Lo;0;L;;;;;N;;;;; +1B189;NUSHU CHARACTER-1B189;Lo;0;L;;;;;N;;;;; +1B18A;NUSHU CHARACTER-1B18A;Lo;0;L;;;;;N;;;;; +1B18B;NUSHU CHARACTER-1B18B;Lo;0;L;;;;;N;;;;; +1B18C;NUSHU CHARACTER-1B18C;Lo;0;L;;;;;N;;;;; +1B18D;NUSHU CHARACTER-1B18D;Lo;0;L;;;;;N;;;;; +1B18E;NUSHU CHARACTER-1B18E;Lo;0;L;;;;;N;;;;; +1B18F;NUSHU CHARACTER-1B18F;Lo;0;L;;;;;N;;;;; +1B190;NUSHU CHARACTER-1B190;Lo;0;L;;;;;N;;;;; +1B191;NUSHU CHARACTER-1B191;Lo;0;L;;;;;N;;;;; +1B192;NUSHU CHARACTER-1B192;Lo;0;L;;;;;N;;;;; +1B193;NUSHU CHARACTER-1B193;Lo;0;L;;;;;N;;;;; +1B194;NUSHU CHARACTER-1B194;Lo;0;L;;;;;N;;;;; +1B195;NUSHU CHARACTER-1B195;Lo;0;L;;;;;N;;;;; +1B196;NUSHU CHARACTER-1B196;Lo;0;L;;;;;N;;;;; +1B197;NUSHU CHARACTER-1B197;Lo;0;L;;;;;N;;;;; +1B198;NUSHU CHARACTER-1B198;Lo;0;L;;;;;N;;;;; +1B199;NUSHU CHARACTER-1B199;Lo;0;L;;;;;N;;;;; +1B19A;NUSHU CHARACTER-1B19A;Lo;0;L;;;;;N;;;;; +1B19B;NUSHU CHARACTER-1B19B;Lo;0;L;;;;;N;;;;; +1B19C;NUSHU CHARACTER-1B19C;Lo;0;L;;;;;N;;;;; +1B19D;NUSHU CHARACTER-1B19D;Lo;0;L;;;;;N;;;;; +1B19E;NUSHU CHARACTER-1B19E;Lo;0;L;;;;;N;;;;; +1B19F;NUSHU CHARACTER-1B19F;Lo;0;L;;;;;N;;;;; +1B1A0;NUSHU CHARACTER-1B1A0;Lo;0;L;;;;;N;;;;; +1B1A1;NUSHU CHARACTER-1B1A1;Lo;0;L;;;;;N;;;;; +1B1A2;NUSHU CHARACTER-1B1A2;Lo;0;L;;;;;N;;;;; +1B1A3;NUSHU CHARACTER-1B1A3;Lo;0;L;;;;;N;;;;; +1B1A4;NUSHU CHARACTER-1B1A4;Lo;0;L;;;;;N;;;;; +1B1A5;NUSHU CHARACTER-1B1A5;Lo;0;L;;;;;N;;;;; +1B1A6;NUSHU CHARACTER-1B1A6;Lo;0;L;;;;;N;;;;; +1B1A7;NUSHU CHARACTER-1B1A7;Lo;0;L;;;;;N;;;;; +1B1A8;NUSHU CHARACTER-1B1A8;Lo;0;L;;;;;N;;;;; +1B1A9;NUSHU CHARACTER-1B1A9;Lo;0;L;;;;;N;;;;; +1B1AA;NUSHU CHARACTER-1B1AA;Lo;0;L;;;;;N;;;;; +1B1AB;NUSHU CHARACTER-1B1AB;Lo;0;L;;;;;N;;;;; +1B1AC;NUSHU CHARACTER-1B1AC;Lo;0;L;;;;;N;;;;; +1B1AD;NUSHU CHARACTER-1B1AD;Lo;0;L;;;;;N;;;;; +1B1AE;NUSHU CHARACTER-1B1AE;Lo;0;L;;;;;N;;;;; +1B1AF;NUSHU CHARACTER-1B1AF;Lo;0;L;;;;;N;;;;; +1B1B0;NUSHU CHARACTER-1B1B0;Lo;0;L;;;;;N;;;;; +1B1B1;NUSHU CHARACTER-1B1B1;Lo;0;L;;;;;N;;;;; +1B1B2;NUSHU CHARACTER-1B1B2;Lo;0;L;;;;;N;;;;; +1B1B3;NUSHU CHARACTER-1B1B3;Lo;0;L;;;;;N;;;;; +1B1B4;NUSHU CHARACTER-1B1B4;Lo;0;L;;;;;N;;;;; +1B1B5;NUSHU CHARACTER-1B1B5;Lo;0;L;;;;;N;;;;; +1B1B6;NUSHU CHARACTER-1B1B6;Lo;0;L;;;;;N;;;;; +1B1B7;NUSHU CHARACTER-1B1B7;Lo;0;L;;;;;N;;;;; +1B1B8;NUSHU CHARACTER-1B1B8;Lo;0;L;;;;;N;;;;; +1B1B9;NUSHU CHARACTER-1B1B9;Lo;0;L;;;;;N;;;;; +1B1BA;NUSHU CHARACTER-1B1BA;Lo;0;L;;;;;N;;;;; +1B1BB;NUSHU CHARACTER-1B1BB;Lo;0;L;;;;;N;;;;; +1B1BC;NUSHU CHARACTER-1B1BC;Lo;0;L;;;;;N;;;;; +1B1BD;NUSHU CHARACTER-1B1BD;Lo;0;L;;;;;N;;;;; +1B1BE;NUSHU CHARACTER-1B1BE;Lo;0;L;;;;;N;;;;; +1B1BF;NUSHU CHARACTER-1B1BF;Lo;0;L;;;;;N;;;;; +1B1C0;NUSHU CHARACTER-1B1C0;Lo;0;L;;;;;N;;;;; +1B1C1;NUSHU CHARACTER-1B1C1;Lo;0;L;;;;;N;;;;; +1B1C2;NUSHU CHARACTER-1B1C2;Lo;0;L;;;;;N;;;;; +1B1C3;NUSHU CHARACTER-1B1C3;Lo;0;L;;;;;N;;;;; +1B1C4;NUSHU CHARACTER-1B1C4;Lo;0;L;;;;;N;;;;; +1B1C5;NUSHU CHARACTER-1B1C5;Lo;0;L;;;;;N;;;;; +1B1C6;NUSHU CHARACTER-1B1C6;Lo;0;L;;;;;N;;;;; +1B1C7;NUSHU CHARACTER-1B1C7;Lo;0;L;;;;;N;;;;; +1B1C8;NUSHU CHARACTER-1B1C8;Lo;0;L;;;;;N;;;;; +1B1C9;NUSHU CHARACTER-1B1C9;Lo;0;L;;;;;N;;;;; +1B1CA;NUSHU CHARACTER-1B1CA;Lo;0;L;;;;;N;;;;; +1B1CB;NUSHU CHARACTER-1B1CB;Lo;0;L;;;;;N;;;;; +1B1CC;NUSHU CHARACTER-1B1CC;Lo;0;L;;;;;N;;;;; +1B1CD;NUSHU CHARACTER-1B1CD;Lo;0;L;;;;;N;;;;; +1B1CE;NUSHU CHARACTER-1B1CE;Lo;0;L;;;;;N;;;;; +1B1CF;NUSHU CHARACTER-1B1CF;Lo;0;L;;;;;N;;;;; +1B1D0;NUSHU CHARACTER-1B1D0;Lo;0;L;;;;;N;;;;; +1B1D1;NUSHU CHARACTER-1B1D1;Lo;0;L;;;;;N;;;;; +1B1D2;NUSHU CHARACTER-1B1D2;Lo;0;L;;;;;N;;;;; +1B1D3;NUSHU CHARACTER-1B1D3;Lo;0;L;;;;;N;;;;; +1B1D4;NUSHU CHARACTER-1B1D4;Lo;0;L;;;;;N;;;;; +1B1D5;NUSHU CHARACTER-1B1D5;Lo;0;L;;;;;N;;;;; +1B1D6;NUSHU CHARACTER-1B1D6;Lo;0;L;;;;;N;;;;; +1B1D7;NUSHU CHARACTER-1B1D7;Lo;0;L;;;;;N;;;;; +1B1D8;NUSHU CHARACTER-1B1D8;Lo;0;L;;;;;N;;;;; +1B1D9;NUSHU CHARACTER-1B1D9;Lo;0;L;;;;;N;;;;; +1B1DA;NUSHU CHARACTER-1B1DA;Lo;0;L;;;;;N;;;;; +1B1DB;NUSHU CHARACTER-1B1DB;Lo;0;L;;;;;N;;;;; +1B1DC;NUSHU CHARACTER-1B1DC;Lo;0;L;;;;;N;;;;; +1B1DD;NUSHU CHARACTER-1B1DD;Lo;0;L;;;;;N;;;;; +1B1DE;NUSHU CHARACTER-1B1DE;Lo;0;L;;;;;N;;;;; +1B1DF;NUSHU CHARACTER-1B1DF;Lo;0;L;;;;;N;;;;; +1B1E0;NUSHU CHARACTER-1B1E0;Lo;0;L;;;;;N;;;;; +1B1E1;NUSHU CHARACTER-1B1E1;Lo;0;L;;;;;N;;;;; +1B1E2;NUSHU CHARACTER-1B1E2;Lo;0;L;;;;;N;;;;; +1B1E3;NUSHU CHARACTER-1B1E3;Lo;0;L;;;;;N;;;;; +1B1E4;NUSHU CHARACTER-1B1E4;Lo;0;L;;;;;N;;;;; +1B1E5;NUSHU CHARACTER-1B1E5;Lo;0;L;;;;;N;;;;; +1B1E6;NUSHU CHARACTER-1B1E6;Lo;0;L;;;;;N;;;;; +1B1E7;NUSHU CHARACTER-1B1E7;Lo;0;L;;;;;N;;;;; +1B1E8;NUSHU CHARACTER-1B1E8;Lo;0;L;;;;;N;;;;; +1B1E9;NUSHU CHARACTER-1B1E9;Lo;0;L;;;;;N;;;;; +1B1EA;NUSHU CHARACTER-1B1EA;Lo;0;L;;;;;N;;;;; +1B1EB;NUSHU CHARACTER-1B1EB;Lo;0;L;;;;;N;;;;; +1B1EC;NUSHU CHARACTER-1B1EC;Lo;0;L;;;;;N;;;;; +1B1ED;NUSHU CHARACTER-1B1ED;Lo;0;L;;;;;N;;;;; +1B1EE;NUSHU CHARACTER-1B1EE;Lo;0;L;;;;;N;;;;; +1B1EF;NUSHU CHARACTER-1B1EF;Lo;0;L;;;;;N;;;;; +1B1F0;NUSHU CHARACTER-1B1F0;Lo;0;L;;;;;N;;;;; +1B1F1;NUSHU CHARACTER-1B1F1;Lo;0;L;;;;;N;;;;; +1B1F2;NUSHU CHARACTER-1B1F2;Lo;0;L;;;;;N;;;;; +1B1F3;NUSHU CHARACTER-1B1F3;Lo;0;L;;;;;N;;;;; +1B1F4;NUSHU CHARACTER-1B1F4;Lo;0;L;;;;;N;;;;; +1B1F5;NUSHU CHARACTER-1B1F5;Lo;0;L;;;;;N;;;;; +1B1F6;NUSHU CHARACTER-1B1F6;Lo;0;L;;;;;N;;;;; +1B1F7;NUSHU CHARACTER-1B1F7;Lo;0;L;;;;;N;;;;; +1B1F8;NUSHU CHARACTER-1B1F8;Lo;0;L;;;;;N;;;;; +1B1F9;NUSHU CHARACTER-1B1F9;Lo;0;L;;;;;N;;;;; +1B1FA;NUSHU CHARACTER-1B1FA;Lo;0;L;;;;;N;;;;; +1B1FB;NUSHU CHARACTER-1B1FB;Lo;0;L;;;;;N;;;;; +1B1FC;NUSHU CHARACTER-1B1FC;Lo;0;L;;;;;N;;;;; +1B1FD;NUSHU CHARACTER-1B1FD;Lo;0;L;;;;;N;;;;; +1B1FE;NUSHU CHARACTER-1B1FE;Lo;0;L;;;;;N;;;;; +1B1FF;NUSHU CHARACTER-1B1FF;Lo;0;L;;;;;N;;;;; +1B200;NUSHU CHARACTER-1B200;Lo;0;L;;;;;N;;;;; +1B201;NUSHU CHARACTER-1B201;Lo;0;L;;;;;N;;;;; +1B202;NUSHU CHARACTER-1B202;Lo;0;L;;;;;N;;;;; +1B203;NUSHU CHARACTER-1B203;Lo;0;L;;;;;N;;;;; +1B204;NUSHU CHARACTER-1B204;Lo;0;L;;;;;N;;;;; +1B205;NUSHU CHARACTER-1B205;Lo;0;L;;;;;N;;;;; +1B206;NUSHU CHARACTER-1B206;Lo;0;L;;;;;N;;;;; +1B207;NUSHU CHARACTER-1B207;Lo;0;L;;;;;N;;;;; +1B208;NUSHU CHARACTER-1B208;Lo;0;L;;;;;N;;;;; +1B209;NUSHU CHARACTER-1B209;Lo;0;L;;;;;N;;;;; +1B20A;NUSHU CHARACTER-1B20A;Lo;0;L;;;;;N;;;;; +1B20B;NUSHU CHARACTER-1B20B;Lo;0;L;;;;;N;;;;; +1B20C;NUSHU CHARACTER-1B20C;Lo;0;L;;;;;N;;;;; +1B20D;NUSHU CHARACTER-1B20D;Lo;0;L;;;;;N;;;;; +1B20E;NUSHU CHARACTER-1B20E;Lo;0;L;;;;;N;;;;; +1B20F;NUSHU CHARACTER-1B20F;Lo;0;L;;;;;N;;;;; +1B210;NUSHU CHARACTER-1B210;Lo;0;L;;;;;N;;;;; +1B211;NUSHU CHARACTER-1B211;Lo;0;L;;;;;N;;;;; +1B212;NUSHU CHARACTER-1B212;Lo;0;L;;;;;N;;;;; +1B213;NUSHU CHARACTER-1B213;Lo;0;L;;;;;N;;;;; +1B214;NUSHU CHARACTER-1B214;Lo;0;L;;;;;N;;;;; +1B215;NUSHU CHARACTER-1B215;Lo;0;L;;;;;N;;;;; +1B216;NUSHU CHARACTER-1B216;Lo;0;L;;;;;N;;;;; +1B217;NUSHU CHARACTER-1B217;Lo;0;L;;;;;N;;;;; +1B218;NUSHU CHARACTER-1B218;Lo;0;L;;;;;N;;;;; +1B219;NUSHU CHARACTER-1B219;Lo;0;L;;;;;N;;;;; +1B21A;NUSHU CHARACTER-1B21A;Lo;0;L;;;;;N;;;;; +1B21B;NUSHU CHARACTER-1B21B;Lo;0;L;;;;;N;;;;; +1B21C;NUSHU CHARACTER-1B21C;Lo;0;L;;;;;N;;;;; +1B21D;NUSHU CHARACTER-1B21D;Lo;0;L;;;;;N;;;;; +1B21E;NUSHU CHARACTER-1B21E;Lo;0;L;;;;;N;;;;; +1B21F;NUSHU CHARACTER-1B21F;Lo;0;L;;;;;N;;;;; +1B220;NUSHU CHARACTER-1B220;Lo;0;L;;;;;N;;;;; +1B221;NUSHU CHARACTER-1B221;Lo;0;L;;;;;N;;;;; +1B222;NUSHU CHARACTER-1B222;Lo;0;L;;;;;N;;;;; +1B223;NUSHU CHARACTER-1B223;Lo;0;L;;;;;N;;;;; +1B224;NUSHU CHARACTER-1B224;Lo;0;L;;;;;N;;;;; +1B225;NUSHU CHARACTER-1B225;Lo;0;L;;;;;N;;;;; +1B226;NUSHU CHARACTER-1B226;Lo;0;L;;;;;N;;;;; +1B227;NUSHU CHARACTER-1B227;Lo;0;L;;;;;N;;;;; +1B228;NUSHU CHARACTER-1B228;Lo;0;L;;;;;N;;;;; +1B229;NUSHU CHARACTER-1B229;Lo;0;L;;;;;N;;;;; +1B22A;NUSHU CHARACTER-1B22A;Lo;0;L;;;;;N;;;;; +1B22B;NUSHU CHARACTER-1B22B;Lo;0;L;;;;;N;;;;; +1B22C;NUSHU CHARACTER-1B22C;Lo;0;L;;;;;N;;;;; +1B22D;NUSHU CHARACTER-1B22D;Lo;0;L;;;;;N;;;;; +1B22E;NUSHU CHARACTER-1B22E;Lo;0;L;;;;;N;;;;; +1B22F;NUSHU CHARACTER-1B22F;Lo;0;L;;;;;N;;;;; +1B230;NUSHU CHARACTER-1B230;Lo;0;L;;;;;N;;;;; +1B231;NUSHU CHARACTER-1B231;Lo;0;L;;;;;N;;;;; +1B232;NUSHU CHARACTER-1B232;Lo;0;L;;;;;N;;;;; +1B233;NUSHU CHARACTER-1B233;Lo;0;L;;;;;N;;;;; +1B234;NUSHU CHARACTER-1B234;Lo;0;L;;;;;N;;;;; +1B235;NUSHU CHARACTER-1B235;Lo;0;L;;;;;N;;;;; +1B236;NUSHU CHARACTER-1B236;Lo;0;L;;;;;N;;;;; +1B237;NUSHU CHARACTER-1B237;Lo;0;L;;;;;N;;;;; +1B238;NUSHU CHARACTER-1B238;Lo;0;L;;;;;N;;;;; +1B239;NUSHU CHARACTER-1B239;Lo;0;L;;;;;N;;;;; +1B23A;NUSHU CHARACTER-1B23A;Lo;0;L;;;;;N;;;;; +1B23B;NUSHU CHARACTER-1B23B;Lo;0;L;;;;;N;;;;; +1B23C;NUSHU CHARACTER-1B23C;Lo;0;L;;;;;N;;;;; +1B23D;NUSHU CHARACTER-1B23D;Lo;0;L;;;;;N;;;;; +1B23E;NUSHU CHARACTER-1B23E;Lo;0;L;;;;;N;;;;; +1B23F;NUSHU CHARACTER-1B23F;Lo;0;L;;;;;N;;;;; +1B240;NUSHU CHARACTER-1B240;Lo;0;L;;;;;N;;;;; +1B241;NUSHU CHARACTER-1B241;Lo;0;L;;;;;N;;;;; +1B242;NUSHU CHARACTER-1B242;Lo;0;L;;;;;N;;;;; +1B243;NUSHU CHARACTER-1B243;Lo;0;L;;;;;N;;;;; +1B244;NUSHU CHARACTER-1B244;Lo;0;L;;;;;N;;;;; +1B245;NUSHU CHARACTER-1B245;Lo;0;L;;;;;N;;;;; +1B246;NUSHU CHARACTER-1B246;Lo;0;L;;;;;N;;;;; +1B247;NUSHU CHARACTER-1B247;Lo;0;L;;;;;N;;;;; +1B248;NUSHU CHARACTER-1B248;Lo;0;L;;;;;N;;;;; +1B249;NUSHU CHARACTER-1B249;Lo;0;L;;;;;N;;;;; +1B24A;NUSHU CHARACTER-1B24A;Lo;0;L;;;;;N;;;;; +1B24B;NUSHU CHARACTER-1B24B;Lo;0;L;;;;;N;;;;; +1B24C;NUSHU CHARACTER-1B24C;Lo;0;L;;;;;N;;;;; +1B24D;NUSHU CHARACTER-1B24D;Lo;0;L;;;;;N;;;;; +1B24E;NUSHU CHARACTER-1B24E;Lo;0;L;;;;;N;;;;; +1B24F;NUSHU CHARACTER-1B24F;Lo;0;L;;;;;N;;;;; +1B250;NUSHU CHARACTER-1B250;Lo;0;L;;;;;N;;;;; +1B251;NUSHU CHARACTER-1B251;Lo;0;L;;;;;N;;;;; +1B252;NUSHU CHARACTER-1B252;Lo;0;L;;;;;N;;;;; +1B253;NUSHU CHARACTER-1B253;Lo;0;L;;;;;N;;;;; +1B254;NUSHU CHARACTER-1B254;Lo;0;L;;;;;N;;;;; +1B255;NUSHU CHARACTER-1B255;Lo;0;L;;;;;N;;;;; +1B256;NUSHU CHARACTER-1B256;Lo;0;L;;;;;N;;;;; +1B257;NUSHU CHARACTER-1B257;Lo;0;L;;;;;N;;;;; +1B258;NUSHU CHARACTER-1B258;Lo;0;L;;;;;N;;;;; +1B259;NUSHU CHARACTER-1B259;Lo;0;L;;;;;N;;;;; +1B25A;NUSHU CHARACTER-1B25A;Lo;0;L;;;;;N;;;;; +1B25B;NUSHU CHARACTER-1B25B;Lo;0;L;;;;;N;;;;; +1B25C;NUSHU CHARACTER-1B25C;Lo;0;L;;;;;N;;;;; +1B25D;NUSHU CHARACTER-1B25D;Lo;0;L;;;;;N;;;;; +1B25E;NUSHU CHARACTER-1B25E;Lo;0;L;;;;;N;;;;; +1B25F;NUSHU CHARACTER-1B25F;Lo;0;L;;;;;N;;;;; +1B260;NUSHU CHARACTER-1B260;Lo;0;L;;;;;N;;;;; +1B261;NUSHU CHARACTER-1B261;Lo;0;L;;;;;N;;;;; +1B262;NUSHU CHARACTER-1B262;Lo;0;L;;;;;N;;;;; +1B263;NUSHU CHARACTER-1B263;Lo;0;L;;;;;N;;;;; +1B264;NUSHU CHARACTER-1B264;Lo;0;L;;;;;N;;;;; +1B265;NUSHU CHARACTER-1B265;Lo;0;L;;;;;N;;;;; +1B266;NUSHU CHARACTER-1B266;Lo;0;L;;;;;N;;;;; +1B267;NUSHU CHARACTER-1B267;Lo;0;L;;;;;N;;;;; +1B268;NUSHU CHARACTER-1B268;Lo;0;L;;;;;N;;;;; +1B269;NUSHU CHARACTER-1B269;Lo;0;L;;;;;N;;;;; +1B26A;NUSHU CHARACTER-1B26A;Lo;0;L;;;;;N;;;;; +1B26B;NUSHU CHARACTER-1B26B;Lo;0;L;;;;;N;;;;; +1B26C;NUSHU CHARACTER-1B26C;Lo;0;L;;;;;N;;;;; +1B26D;NUSHU CHARACTER-1B26D;Lo;0;L;;;;;N;;;;; +1B26E;NUSHU CHARACTER-1B26E;Lo;0;L;;;;;N;;;;; +1B26F;NUSHU CHARACTER-1B26F;Lo;0;L;;;;;N;;;;; +1B270;NUSHU CHARACTER-1B270;Lo;0;L;;;;;N;;;;; +1B271;NUSHU CHARACTER-1B271;Lo;0;L;;;;;N;;;;; +1B272;NUSHU CHARACTER-1B272;Lo;0;L;;;;;N;;;;; +1B273;NUSHU CHARACTER-1B273;Lo;0;L;;;;;N;;;;; +1B274;NUSHU CHARACTER-1B274;Lo;0;L;;;;;N;;;;; +1B275;NUSHU CHARACTER-1B275;Lo;0;L;;;;;N;;;;; +1B276;NUSHU CHARACTER-1B276;Lo;0;L;;;;;N;;;;; +1B277;NUSHU CHARACTER-1B277;Lo;0;L;;;;;N;;;;; +1B278;NUSHU CHARACTER-1B278;Lo;0;L;;;;;N;;;;; +1B279;NUSHU CHARACTER-1B279;Lo;0;L;;;;;N;;;;; +1B27A;NUSHU CHARACTER-1B27A;Lo;0;L;;;;;N;;;;; +1B27B;NUSHU CHARACTER-1B27B;Lo;0;L;;;;;N;;;;; +1B27C;NUSHU CHARACTER-1B27C;Lo;0;L;;;;;N;;;;; +1B27D;NUSHU CHARACTER-1B27D;Lo;0;L;;;;;N;;;;; +1B27E;NUSHU CHARACTER-1B27E;Lo;0;L;;;;;N;;;;; +1B27F;NUSHU CHARACTER-1B27F;Lo;0;L;;;;;N;;;;; +1B280;NUSHU CHARACTER-1B280;Lo;0;L;;;;;N;;;;; +1B281;NUSHU CHARACTER-1B281;Lo;0;L;;;;;N;;;;; +1B282;NUSHU CHARACTER-1B282;Lo;0;L;;;;;N;;;;; +1B283;NUSHU CHARACTER-1B283;Lo;0;L;;;;;N;;;;; +1B284;NUSHU CHARACTER-1B284;Lo;0;L;;;;;N;;;;; +1B285;NUSHU CHARACTER-1B285;Lo;0;L;;;;;N;;;;; +1B286;NUSHU CHARACTER-1B286;Lo;0;L;;;;;N;;;;; +1B287;NUSHU CHARACTER-1B287;Lo;0;L;;;;;N;;;;; +1B288;NUSHU CHARACTER-1B288;Lo;0;L;;;;;N;;;;; +1B289;NUSHU CHARACTER-1B289;Lo;0;L;;;;;N;;;;; +1B28A;NUSHU CHARACTER-1B28A;Lo;0;L;;;;;N;;;;; +1B28B;NUSHU CHARACTER-1B28B;Lo;0;L;;;;;N;;;;; +1B28C;NUSHU CHARACTER-1B28C;Lo;0;L;;;;;N;;;;; +1B28D;NUSHU CHARACTER-1B28D;Lo;0;L;;;;;N;;;;; +1B28E;NUSHU CHARACTER-1B28E;Lo;0;L;;;;;N;;;;; +1B28F;NUSHU CHARACTER-1B28F;Lo;0;L;;;;;N;;;;; +1B290;NUSHU CHARACTER-1B290;Lo;0;L;;;;;N;;;;; +1B291;NUSHU CHARACTER-1B291;Lo;0;L;;;;;N;;;;; +1B292;NUSHU CHARACTER-1B292;Lo;0;L;;;;;N;;;;; +1B293;NUSHU CHARACTER-1B293;Lo;0;L;;;;;N;;;;; +1B294;NUSHU CHARACTER-1B294;Lo;0;L;;;;;N;;;;; +1B295;NUSHU CHARACTER-1B295;Lo;0;L;;;;;N;;;;; +1B296;NUSHU CHARACTER-1B296;Lo;0;L;;;;;N;;;;; +1B297;NUSHU CHARACTER-1B297;Lo;0;L;;;;;N;;;;; +1B298;NUSHU CHARACTER-1B298;Lo;0;L;;;;;N;;;;; +1B299;NUSHU CHARACTER-1B299;Lo;0;L;;;;;N;;;;; +1B29A;NUSHU CHARACTER-1B29A;Lo;0;L;;;;;N;;;;; +1B29B;NUSHU CHARACTER-1B29B;Lo;0;L;;;;;N;;;;; +1B29C;NUSHU CHARACTER-1B29C;Lo;0;L;;;;;N;;;;; +1B29D;NUSHU CHARACTER-1B29D;Lo;0;L;;;;;N;;;;; +1B29E;NUSHU CHARACTER-1B29E;Lo;0;L;;;;;N;;;;; +1B29F;NUSHU CHARACTER-1B29F;Lo;0;L;;;;;N;;;;; +1B2A0;NUSHU CHARACTER-1B2A0;Lo;0;L;;;;;N;;;;; +1B2A1;NUSHU CHARACTER-1B2A1;Lo;0;L;;;;;N;;;;; +1B2A2;NUSHU CHARACTER-1B2A2;Lo;0;L;;;;;N;;;;; +1B2A3;NUSHU CHARACTER-1B2A3;Lo;0;L;;;;;N;;;;; +1B2A4;NUSHU CHARACTER-1B2A4;Lo;0;L;;;;;N;;;;; +1B2A5;NUSHU CHARACTER-1B2A5;Lo;0;L;;;;;N;;;;; +1B2A6;NUSHU CHARACTER-1B2A6;Lo;0;L;;;;;N;;;;; +1B2A7;NUSHU CHARACTER-1B2A7;Lo;0;L;;;;;N;;;;; +1B2A8;NUSHU CHARACTER-1B2A8;Lo;0;L;;;;;N;;;;; +1B2A9;NUSHU CHARACTER-1B2A9;Lo;0;L;;;;;N;;;;; +1B2AA;NUSHU CHARACTER-1B2AA;Lo;0;L;;;;;N;;;;; +1B2AB;NUSHU CHARACTER-1B2AB;Lo;0;L;;;;;N;;;;; +1B2AC;NUSHU CHARACTER-1B2AC;Lo;0;L;;;;;N;;;;; +1B2AD;NUSHU CHARACTER-1B2AD;Lo;0;L;;;;;N;;;;; +1B2AE;NUSHU CHARACTER-1B2AE;Lo;0;L;;;;;N;;;;; +1B2AF;NUSHU CHARACTER-1B2AF;Lo;0;L;;;;;N;;;;; +1B2B0;NUSHU CHARACTER-1B2B0;Lo;0;L;;;;;N;;;;; +1B2B1;NUSHU CHARACTER-1B2B1;Lo;0;L;;;;;N;;;;; +1B2B2;NUSHU CHARACTER-1B2B2;Lo;0;L;;;;;N;;;;; +1B2B3;NUSHU CHARACTER-1B2B3;Lo;0;L;;;;;N;;;;; +1B2B4;NUSHU CHARACTER-1B2B4;Lo;0;L;;;;;N;;;;; +1B2B5;NUSHU CHARACTER-1B2B5;Lo;0;L;;;;;N;;;;; +1B2B6;NUSHU CHARACTER-1B2B6;Lo;0;L;;;;;N;;;;; +1B2B7;NUSHU CHARACTER-1B2B7;Lo;0;L;;;;;N;;;;; +1B2B8;NUSHU CHARACTER-1B2B8;Lo;0;L;;;;;N;;;;; +1B2B9;NUSHU CHARACTER-1B2B9;Lo;0;L;;;;;N;;;;; +1B2BA;NUSHU CHARACTER-1B2BA;Lo;0;L;;;;;N;;;;; +1B2BB;NUSHU CHARACTER-1B2BB;Lo;0;L;;;;;N;;;;; +1B2BC;NUSHU CHARACTER-1B2BC;Lo;0;L;;;;;N;;;;; +1B2BD;NUSHU CHARACTER-1B2BD;Lo;0;L;;;;;N;;;;; +1B2BE;NUSHU CHARACTER-1B2BE;Lo;0;L;;;;;N;;;;; +1B2BF;NUSHU CHARACTER-1B2BF;Lo;0;L;;;;;N;;;;; +1B2C0;NUSHU CHARACTER-1B2C0;Lo;0;L;;;;;N;;;;; +1B2C1;NUSHU CHARACTER-1B2C1;Lo;0;L;;;;;N;;;;; +1B2C2;NUSHU CHARACTER-1B2C2;Lo;0;L;;;;;N;;;;; +1B2C3;NUSHU CHARACTER-1B2C3;Lo;0;L;;;;;N;;;;; +1B2C4;NUSHU CHARACTER-1B2C4;Lo;0;L;;;;;N;;;;; +1B2C5;NUSHU CHARACTER-1B2C5;Lo;0;L;;;;;N;;;;; +1B2C6;NUSHU CHARACTER-1B2C6;Lo;0;L;;;;;N;;;;; +1B2C7;NUSHU CHARACTER-1B2C7;Lo;0;L;;;;;N;;;;; +1B2C8;NUSHU CHARACTER-1B2C8;Lo;0;L;;;;;N;;;;; +1B2C9;NUSHU CHARACTER-1B2C9;Lo;0;L;;;;;N;;;;; +1B2CA;NUSHU CHARACTER-1B2CA;Lo;0;L;;;;;N;;;;; +1B2CB;NUSHU CHARACTER-1B2CB;Lo;0;L;;;;;N;;;;; +1B2CC;NUSHU CHARACTER-1B2CC;Lo;0;L;;;;;N;;;;; +1B2CD;NUSHU CHARACTER-1B2CD;Lo;0;L;;;;;N;;;;; +1B2CE;NUSHU CHARACTER-1B2CE;Lo;0;L;;;;;N;;;;; +1B2CF;NUSHU CHARACTER-1B2CF;Lo;0;L;;;;;N;;;;; +1B2D0;NUSHU CHARACTER-1B2D0;Lo;0;L;;;;;N;;;;; +1B2D1;NUSHU CHARACTER-1B2D1;Lo;0;L;;;;;N;;;;; +1B2D2;NUSHU CHARACTER-1B2D2;Lo;0;L;;;;;N;;;;; +1B2D3;NUSHU CHARACTER-1B2D3;Lo;0;L;;;;;N;;;;; +1B2D4;NUSHU CHARACTER-1B2D4;Lo;0;L;;;;;N;;;;; +1B2D5;NUSHU CHARACTER-1B2D5;Lo;0;L;;;;;N;;;;; +1B2D6;NUSHU CHARACTER-1B2D6;Lo;0;L;;;;;N;;;;; +1B2D7;NUSHU CHARACTER-1B2D7;Lo;0;L;;;;;N;;;;; +1B2D8;NUSHU CHARACTER-1B2D8;Lo;0;L;;;;;N;;;;; +1B2D9;NUSHU CHARACTER-1B2D9;Lo;0;L;;;;;N;;;;; +1B2DA;NUSHU CHARACTER-1B2DA;Lo;0;L;;;;;N;;;;; +1B2DB;NUSHU CHARACTER-1B2DB;Lo;0;L;;;;;N;;;;; +1B2DC;NUSHU CHARACTER-1B2DC;Lo;0;L;;;;;N;;;;; +1B2DD;NUSHU CHARACTER-1B2DD;Lo;0;L;;;;;N;;;;; +1B2DE;NUSHU CHARACTER-1B2DE;Lo;0;L;;;;;N;;;;; +1B2DF;NUSHU CHARACTER-1B2DF;Lo;0;L;;;;;N;;;;; +1B2E0;NUSHU CHARACTER-1B2E0;Lo;0;L;;;;;N;;;;; +1B2E1;NUSHU CHARACTER-1B2E1;Lo;0;L;;;;;N;;;;; +1B2E2;NUSHU CHARACTER-1B2E2;Lo;0;L;;;;;N;;;;; +1B2E3;NUSHU CHARACTER-1B2E3;Lo;0;L;;;;;N;;;;; +1B2E4;NUSHU CHARACTER-1B2E4;Lo;0;L;;;;;N;;;;; +1B2E5;NUSHU CHARACTER-1B2E5;Lo;0;L;;;;;N;;;;; +1B2E6;NUSHU CHARACTER-1B2E6;Lo;0;L;;;;;N;;;;; +1B2E7;NUSHU CHARACTER-1B2E7;Lo;0;L;;;;;N;;;;; +1B2E8;NUSHU CHARACTER-1B2E8;Lo;0;L;;;;;N;;;;; +1B2E9;NUSHU CHARACTER-1B2E9;Lo;0;L;;;;;N;;;;; +1B2EA;NUSHU CHARACTER-1B2EA;Lo;0;L;;;;;N;;;;; +1B2EB;NUSHU CHARACTER-1B2EB;Lo;0;L;;;;;N;;;;; +1B2EC;NUSHU CHARACTER-1B2EC;Lo;0;L;;;;;N;;;;; +1B2ED;NUSHU CHARACTER-1B2ED;Lo;0;L;;;;;N;;;;; +1B2EE;NUSHU CHARACTER-1B2EE;Lo;0;L;;;;;N;;;;; +1B2EF;NUSHU CHARACTER-1B2EF;Lo;0;L;;;;;N;;;;; +1B2F0;NUSHU CHARACTER-1B2F0;Lo;0;L;;;;;N;;;;; +1B2F1;NUSHU CHARACTER-1B2F1;Lo;0;L;;;;;N;;;;; +1B2F2;NUSHU CHARACTER-1B2F2;Lo;0;L;;;;;N;;;;; +1B2F3;NUSHU CHARACTER-1B2F3;Lo;0;L;;;;;N;;;;; +1B2F4;NUSHU CHARACTER-1B2F4;Lo;0;L;;;;;N;;;;; +1B2F5;NUSHU CHARACTER-1B2F5;Lo;0;L;;;;;N;;;;; +1B2F6;NUSHU CHARACTER-1B2F6;Lo;0;L;;;;;N;;;;; +1B2F7;NUSHU CHARACTER-1B2F7;Lo;0;L;;;;;N;;;;; +1B2F8;NUSHU CHARACTER-1B2F8;Lo;0;L;;;;;N;;;;; +1B2F9;NUSHU CHARACTER-1B2F9;Lo;0;L;;;;;N;;;;; +1B2FA;NUSHU CHARACTER-1B2FA;Lo;0;L;;;;;N;;;;; +1B2FB;NUSHU CHARACTER-1B2FB;Lo;0;L;;;;;N;;;;; +1BC00;DUPLOYAN LETTER H;Lo;0;L;;;;;N;;;;; +1BC01;DUPLOYAN LETTER X;Lo;0;L;;;;;N;;;;; +1BC02;DUPLOYAN LETTER P;Lo;0;L;;;;;N;;;;; +1BC03;DUPLOYAN LETTER T;Lo;0;L;;;;;N;;;;; +1BC04;DUPLOYAN LETTER F;Lo;0;L;;;;;N;;;;; +1BC05;DUPLOYAN LETTER K;Lo;0;L;;;;;N;;;;; +1BC06;DUPLOYAN LETTER L;Lo;0;L;;;;;N;;;;; +1BC07;DUPLOYAN LETTER B;Lo;0;L;;;;;N;;;;; +1BC08;DUPLOYAN LETTER D;Lo;0;L;;;;;N;;;;; +1BC09;DUPLOYAN LETTER V;Lo;0;L;;;;;N;;;;; +1BC0A;DUPLOYAN LETTER G;Lo;0;L;;;;;N;;;;; +1BC0B;DUPLOYAN LETTER R;Lo;0;L;;;;;N;;;;; +1BC0C;DUPLOYAN LETTER P N;Lo;0;L;;;;;N;;;;; +1BC0D;DUPLOYAN LETTER D S;Lo;0;L;;;;;N;;;;; +1BC0E;DUPLOYAN LETTER F N;Lo;0;L;;;;;N;;;;; +1BC0F;DUPLOYAN LETTER K M;Lo;0;L;;;;;N;;;;; +1BC10;DUPLOYAN LETTER R S;Lo;0;L;;;;;N;;;;; +1BC11;DUPLOYAN LETTER TH;Lo;0;L;;;;;N;;;;; +1BC12;DUPLOYAN LETTER SLOAN DH;Lo;0;L;;;;;N;;;;; +1BC13;DUPLOYAN LETTER DH;Lo;0;L;;;;;N;;;;; +1BC14;DUPLOYAN LETTER KK;Lo;0;L;;;;;N;;;;; +1BC15;DUPLOYAN LETTER SLOAN J;Lo;0;L;;;;;N;;;;; +1BC16;DUPLOYAN LETTER HL;Lo;0;L;;;;;N;;;;; +1BC17;DUPLOYAN LETTER LH;Lo;0;L;;;;;N;;;;; +1BC18;DUPLOYAN LETTER RH;Lo;0;L;;;;;N;;;;; +1BC19;DUPLOYAN LETTER M;Lo;0;L;;;;;N;;;;; +1BC1A;DUPLOYAN LETTER N;Lo;0;L;;;;;N;;;;; +1BC1B;DUPLOYAN LETTER J;Lo;0;L;;;;;N;;;;; +1BC1C;DUPLOYAN LETTER S;Lo;0;L;;;;;N;;;;; +1BC1D;DUPLOYAN LETTER M N;Lo;0;L;;;;;N;;;;; +1BC1E;DUPLOYAN LETTER N M;Lo;0;L;;;;;N;;;;; +1BC1F;DUPLOYAN LETTER J M;Lo;0;L;;;;;N;;;;; +1BC20;DUPLOYAN LETTER S J;Lo;0;L;;;;;N;;;;; +1BC21;DUPLOYAN LETTER M WITH DOT;Lo;0;L;;;;;N;;;;; +1BC22;DUPLOYAN LETTER N WITH DOT;Lo;0;L;;;;;N;;;;; +1BC23;DUPLOYAN LETTER J WITH DOT;Lo;0;L;;;;;N;;;;; +1BC24;DUPLOYAN LETTER J WITH DOTS INSIDE AND ABOVE;Lo;0;L;;;;;N;;;;; +1BC25;DUPLOYAN LETTER S WITH DOT;Lo;0;L;;;;;N;;;;; +1BC26;DUPLOYAN LETTER S WITH DOT BELOW;Lo;0;L;;;;;N;;;;; +1BC27;DUPLOYAN LETTER M S;Lo;0;L;;;;;N;;;;; +1BC28;DUPLOYAN LETTER N S;Lo;0;L;;;;;N;;;;; +1BC29;DUPLOYAN LETTER J S;Lo;0;L;;;;;N;;;;; +1BC2A;DUPLOYAN LETTER S S;Lo;0;L;;;;;N;;;;; +1BC2B;DUPLOYAN LETTER M N S;Lo;0;L;;;;;N;;;;; +1BC2C;DUPLOYAN LETTER N M S;Lo;0;L;;;;;N;;;;; +1BC2D;DUPLOYAN LETTER J M S;Lo;0;L;;;;;N;;;;; +1BC2E;DUPLOYAN LETTER S J S;Lo;0;L;;;;;N;;;;; +1BC2F;DUPLOYAN LETTER J S WITH DOT;Lo;0;L;;;;;N;;;;; +1BC30;DUPLOYAN LETTER J N;Lo;0;L;;;;;N;;;;; +1BC31;DUPLOYAN LETTER J N S;Lo;0;L;;;;;N;;;;; +1BC32;DUPLOYAN LETTER S T;Lo;0;L;;;;;N;;;;; +1BC33;DUPLOYAN LETTER S T R;Lo;0;L;;;;;N;;;;; +1BC34;DUPLOYAN LETTER S P;Lo;0;L;;;;;N;;;;; +1BC35;DUPLOYAN LETTER S P R;Lo;0;L;;;;;N;;;;; +1BC36;DUPLOYAN LETTER T S;Lo;0;L;;;;;N;;;;; +1BC37;DUPLOYAN LETTER T R S;Lo;0;L;;;;;N;;;;; +1BC38;DUPLOYAN LETTER W;Lo;0;L;;;;;N;;;;; +1BC39;DUPLOYAN LETTER WH;Lo;0;L;;;;;N;;;;; +1BC3A;DUPLOYAN LETTER W R;Lo;0;L;;;;;N;;;;; +1BC3B;DUPLOYAN LETTER S N;Lo;0;L;;;;;N;;;;; +1BC3C;DUPLOYAN LETTER S M;Lo;0;L;;;;;N;;;;; +1BC3D;DUPLOYAN LETTER K R S;Lo;0;L;;;;;N;;;;; +1BC3E;DUPLOYAN LETTER G R S;Lo;0;L;;;;;N;;;;; +1BC3F;DUPLOYAN LETTER S K;Lo;0;L;;;;;N;;;;; +1BC40;DUPLOYAN LETTER S K R;Lo;0;L;;;;;N;;;;; +1BC41;DUPLOYAN LETTER A;Lo;0;L;;;;;N;;;;; +1BC42;DUPLOYAN LETTER SLOAN OW;Lo;0;L;;;;;N;;;;; +1BC43;DUPLOYAN LETTER OA;Lo;0;L;;;;;N;;;;; +1BC44;DUPLOYAN LETTER O;Lo;0;L;;;;;N;;;;; +1BC45;DUPLOYAN LETTER AOU;Lo;0;L;;;;;N;;;;; +1BC46;DUPLOYAN LETTER I;Lo;0;L;;;;;N;;;;; +1BC47;DUPLOYAN LETTER E;Lo;0;L;;;;;N;;;;; +1BC48;DUPLOYAN LETTER IE;Lo;0;L;;;;;N;;;;; +1BC49;DUPLOYAN LETTER SHORT I;Lo;0;L;;;;;N;;;;; +1BC4A;DUPLOYAN LETTER UI;Lo;0;L;;;;;N;;;;; +1BC4B;DUPLOYAN LETTER EE;Lo;0;L;;;;;N;;;;; +1BC4C;DUPLOYAN LETTER SLOAN EH;Lo;0;L;;;;;N;;;;; +1BC4D;DUPLOYAN LETTER ROMANIAN I;Lo;0;L;;;;;N;;;;; +1BC4E;DUPLOYAN LETTER SLOAN EE;Lo;0;L;;;;;N;;;;; +1BC4F;DUPLOYAN LETTER LONG I;Lo;0;L;;;;;N;;;;; +1BC50;DUPLOYAN LETTER YE;Lo;0;L;;;;;N;;;;; +1BC51;DUPLOYAN LETTER U;Lo;0;L;;;;;N;;;;; +1BC52;DUPLOYAN LETTER EU;Lo;0;L;;;;;N;;;;; +1BC53;DUPLOYAN LETTER XW;Lo;0;L;;;;;N;;;;; +1BC54;DUPLOYAN LETTER U N;Lo;0;L;;;;;N;;;;; +1BC55;DUPLOYAN LETTER LONG U;Lo;0;L;;;;;N;;;;; +1BC56;DUPLOYAN LETTER ROMANIAN U;Lo;0;L;;;;;N;;;;; +1BC57;DUPLOYAN LETTER UH;Lo;0;L;;;;;N;;;;; +1BC58;DUPLOYAN LETTER SLOAN U;Lo;0;L;;;;;N;;;;; +1BC59;DUPLOYAN LETTER OOH;Lo;0;L;;;;;N;;;;; +1BC5A;DUPLOYAN LETTER OW;Lo;0;L;;;;;N;;;;; +1BC5B;DUPLOYAN LETTER OU;Lo;0;L;;;;;N;;;;; +1BC5C;DUPLOYAN LETTER WA;Lo;0;L;;;;;N;;;;; +1BC5D;DUPLOYAN LETTER WO;Lo;0;L;;;;;N;;;;; +1BC5E;DUPLOYAN LETTER WI;Lo;0;L;;;;;N;;;;; +1BC5F;DUPLOYAN LETTER WEI;Lo;0;L;;;;;N;;;;; +1BC60;DUPLOYAN LETTER WOW;Lo;0;L;;;;;N;;;;; +1BC61;DUPLOYAN LETTER NASAL U;Lo;0;L;;;;;N;;;;; +1BC62;DUPLOYAN LETTER NASAL O;Lo;0;L;;;;;N;;;;; +1BC63;DUPLOYAN LETTER NASAL I;Lo;0;L;;;;;N;;;;; +1BC64;DUPLOYAN LETTER NASAL A;Lo;0;L;;;;;N;;;;; +1BC65;DUPLOYAN LETTER PERNIN AN;Lo;0;L;;;;;N;;;;; +1BC66;DUPLOYAN LETTER PERNIN AM;Lo;0;L;;;;;N;;;;; +1BC67;DUPLOYAN LETTER SLOAN EN;Lo;0;L;;;;;N;;;;; +1BC68;DUPLOYAN LETTER SLOAN AN;Lo;0;L;;;;;N;;;;; +1BC69;DUPLOYAN LETTER SLOAN ON;Lo;0;L;;;;;N;;;;; +1BC6A;DUPLOYAN LETTER VOCALIC M;Lo;0;L;;;;;N;;;;; +1BC70;DUPLOYAN AFFIX LEFT HORIZONTAL SECANT;Lo;0;L;;;;;N;;;;; +1BC71;DUPLOYAN AFFIX MID HORIZONTAL SECANT;Lo;0;L;;;;;N;;;;; +1BC72;DUPLOYAN AFFIX RIGHT HORIZONTAL SECANT;Lo;0;L;;;;;N;;;;; +1BC73;DUPLOYAN AFFIX LOW VERTICAL SECANT;Lo;0;L;;;;;N;;;;; +1BC74;DUPLOYAN AFFIX MID VERTICAL SECANT;Lo;0;L;;;;;N;;;;; +1BC75;DUPLOYAN AFFIX HIGH VERTICAL SECANT;Lo;0;L;;;;;N;;;;; +1BC76;DUPLOYAN AFFIX ATTACHED SECANT;Lo;0;L;;;;;N;;;;; +1BC77;DUPLOYAN AFFIX ATTACHED LEFT-TO-RIGHT SECANT;Lo;0;L;;;;;N;;;;; +1BC78;DUPLOYAN AFFIX ATTACHED TANGENT;Lo;0;L;;;;;N;;;;; +1BC79;DUPLOYAN AFFIX ATTACHED TAIL;Lo;0;L;;;;;N;;;;; +1BC7A;DUPLOYAN AFFIX ATTACHED E HOOK;Lo;0;L;;;;;N;;;;; +1BC7B;DUPLOYAN AFFIX ATTACHED I HOOK;Lo;0;L;;;;;N;;;;; +1BC7C;DUPLOYAN AFFIX ATTACHED TANGENT HOOK;Lo;0;L;;;;;N;;;;; +1BC80;DUPLOYAN AFFIX HIGH ACUTE;Lo;0;L;;;;;N;;;;; +1BC81;DUPLOYAN AFFIX HIGH TIGHT ACUTE;Lo;0;L;;;;;N;;;;; +1BC82;DUPLOYAN AFFIX HIGH GRAVE;Lo;0;L;;;;;N;;;;; +1BC83;DUPLOYAN AFFIX HIGH LONG GRAVE;Lo;0;L;;;;;N;;;;; +1BC84;DUPLOYAN AFFIX HIGH DOT;Lo;0;L;;;;;N;;;;; +1BC85;DUPLOYAN AFFIX HIGH CIRCLE;Lo;0;L;;;;;N;;;;; +1BC86;DUPLOYAN AFFIX HIGH LINE;Lo;0;L;;;;;N;;;;; +1BC87;DUPLOYAN AFFIX HIGH WAVE;Lo;0;L;;;;;N;;;;; +1BC88;DUPLOYAN AFFIX HIGH VERTICAL;Lo;0;L;;;;;N;;;;; +1BC90;DUPLOYAN AFFIX LOW ACUTE;Lo;0;L;;;;;N;;;;; +1BC91;DUPLOYAN AFFIX LOW TIGHT ACUTE;Lo;0;L;;;;;N;;;;; +1BC92;DUPLOYAN AFFIX LOW GRAVE;Lo;0;L;;;;;N;;;;; +1BC93;DUPLOYAN AFFIX LOW LONG GRAVE;Lo;0;L;;;;;N;;;;; +1BC94;DUPLOYAN AFFIX LOW DOT;Lo;0;L;;;;;N;;;;; +1BC95;DUPLOYAN AFFIX LOW CIRCLE;Lo;0;L;;;;;N;;;;; +1BC96;DUPLOYAN AFFIX LOW LINE;Lo;0;L;;;;;N;;;;; +1BC97;DUPLOYAN AFFIX LOW WAVE;Lo;0;L;;;;;N;;;;; +1BC98;DUPLOYAN AFFIX LOW VERTICAL;Lo;0;L;;;;;N;;;;; +1BC99;DUPLOYAN AFFIX LOW ARROW;Lo;0;L;;;;;N;;;;; +1BC9C;DUPLOYAN SIGN O WITH CROSS;So;0;L;;;;;N;;;;; +1BC9D;DUPLOYAN THICK LETTER SELECTOR;Mn;0;NSM;;;;;N;;;;; +1BC9E;DUPLOYAN DOUBLE MARK;Mn;1;NSM;;;;;N;;;;; +1BC9F;DUPLOYAN PUNCTUATION CHINOOK FULL STOP;Po;0;L;;;;;N;;;;; +1BCA0;SHORTHAND FORMAT LETTER OVERLAP;Cf;0;BN;;;;;N;;;;; +1BCA1;SHORTHAND FORMAT CONTINUING OVERLAP;Cf;0;BN;;;;;N;;;;; +1BCA2;SHORTHAND FORMAT DOWN STEP;Cf;0;BN;;;;;N;;;;; +1BCA3;SHORTHAND FORMAT UP STEP;Cf;0;BN;;;;;N;;;;; +1D000;BYZANTINE MUSICAL SYMBOL PSILI;So;0;L;;;;;N;;;;; +1D001;BYZANTINE MUSICAL SYMBOL DASEIA;So;0;L;;;;;N;;;;; +1D002;BYZANTINE MUSICAL SYMBOL PERISPOMENI;So;0;L;;;;;N;;;;; +1D003;BYZANTINE MUSICAL SYMBOL OXEIA EKFONITIKON;So;0;L;;;;;N;;;;; +1D004;BYZANTINE MUSICAL SYMBOL OXEIA DIPLI;So;0;L;;;;;N;;;;; +1D005;BYZANTINE MUSICAL SYMBOL VAREIA EKFONITIKON;So;0;L;;;;;N;;;;; +1D006;BYZANTINE MUSICAL SYMBOL VAREIA DIPLI;So;0;L;;;;;N;;;;; +1D007;BYZANTINE MUSICAL SYMBOL KATHISTI;So;0;L;;;;;N;;;;; +1D008;BYZANTINE MUSICAL SYMBOL SYRMATIKI;So;0;L;;;;;N;;;;; +1D009;BYZANTINE MUSICAL SYMBOL PARAKLITIKI;So;0;L;;;;;N;;;;; +1D00A;BYZANTINE MUSICAL SYMBOL YPOKRISIS;So;0;L;;;;;N;;;;; +1D00B;BYZANTINE MUSICAL SYMBOL YPOKRISIS DIPLI;So;0;L;;;;;N;;;;; +1D00C;BYZANTINE MUSICAL SYMBOL KREMASTI;So;0;L;;;;;N;;;;; +1D00D;BYZANTINE MUSICAL SYMBOL APESO EKFONITIKON;So;0;L;;;;;N;;;;; +1D00E;BYZANTINE MUSICAL SYMBOL EXO EKFONITIKON;So;0;L;;;;;N;;;;; +1D00F;BYZANTINE MUSICAL SYMBOL TELEIA;So;0;L;;;;;N;;;;; +1D010;BYZANTINE MUSICAL SYMBOL KENTIMATA;So;0;L;;;;;N;;;;; +1D011;BYZANTINE MUSICAL SYMBOL APOSTROFOS;So;0;L;;;;;N;;;;; +1D012;BYZANTINE MUSICAL SYMBOL APOSTROFOS DIPLI;So;0;L;;;;;N;;;;; +1D013;BYZANTINE MUSICAL SYMBOL SYNEVMA;So;0;L;;;;;N;;;;; +1D014;BYZANTINE MUSICAL SYMBOL THITA;So;0;L;;;;;N;;;;; +1D015;BYZANTINE MUSICAL SYMBOL OLIGON ARCHAION;So;0;L;;;;;N;;;;; +1D016;BYZANTINE MUSICAL SYMBOL GORGON ARCHAION;So;0;L;;;;;N;;;;; +1D017;BYZANTINE MUSICAL SYMBOL PSILON;So;0;L;;;;;N;;;;; +1D018;BYZANTINE MUSICAL SYMBOL CHAMILON;So;0;L;;;;;N;;;;; +1D019;BYZANTINE MUSICAL SYMBOL VATHY;So;0;L;;;;;N;;;;; +1D01A;BYZANTINE MUSICAL SYMBOL ISON ARCHAION;So;0;L;;;;;N;;;;; +1D01B;BYZANTINE MUSICAL SYMBOL KENTIMA ARCHAION;So;0;L;;;;;N;;;;; +1D01C;BYZANTINE MUSICAL SYMBOL KENTIMATA ARCHAION;So;0;L;;;;;N;;;;; +1D01D;BYZANTINE MUSICAL SYMBOL SAXIMATA;So;0;L;;;;;N;;;;; +1D01E;BYZANTINE MUSICAL SYMBOL PARICHON;So;0;L;;;;;N;;;;; +1D01F;BYZANTINE MUSICAL SYMBOL STAVROS APODEXIA;So;0;L;;;;;N;;;;; +1D020;BYZANTINE MUSICAL SYMBOL OXEIAI ARCHAION;So;0;L;;;;;N;;;;; +1D021;BYZANTINE MUSICAL SYMBOL VAREIAI ARCHAION;So;0;L;;;;;N;;;;; +1D022;BYZANTINE MUSICAL SYMBOL APODERMA ARCHAION;So;0;L;;;;;N;;;;; +1D023;BYZANTINE MUSICAL SYMBOL APOTHEMA;So;0;L;;;;;N;;;;; +1D024;BYZANTINE MUSICAL SYMBOL KLASMA;So;0;L;;;;;N;;;;; +1D025;BYZANTINE MUSICAL SYMBOL REVMA;So;0;L;;;;;N;;;;; +1D026;BYZANTINE MUSICAL SYMBOL PIASMA ARCHAION;So;0;L;;;;;N;;;;; +1D027;BYZANTINE MUSICAL SYMBOL TINAGMA;So;0;L;;;;;N;;;;; +1D028;BYZANTINE MUSICAL SYMBOL ANATRICHISMA;So;0;L;;;;;N;;;;; +1D029;BYZANTINE MUSICAL SYMBOL SEISMA;So;0;L;;;;;N;;;;; +1D02A;BYZANTINE MUSICAL SYMBOL SYNAGMA ARCHAION;So;0;L;;;;;N;;;;; +1D02B;BYZANTINE MUSICAL SYMBOL SYNAGMA META STAVROU;So;0;L;;;;;N;;;;; +1D02C;BYZANTINE MUSICAL SYMBOL OYRANISMA ARCHAION;So;0;L;;;;;N;;;;; +1D02D;BYZANTINE MUSICAL SYMBOL THEMA;So;0;L;;;;;N;;;;; +1D02E;BYZANTINE MUSICAL SYMBOL LEMOI;So;0;L;;;;;N;;;;; +1D02F;BYZANTINE MUSICAL SYMBOL DYO;So;0;L;;;;;N;;;;; +1D030;BYZANTINE MUSICAL SYMBOL TRIA;So;0;L;;;;;N;;;;; +1D031;BYZANTINE MUSICAL SYMBOL TESSERA;So;0;L;;;;;N;;;;; +1D032;BYZANTINE MUSICAL SYMBOL KRATIMATA;So;0;L;;;;;N;;;;; +1D033;BYZANTINE MUSICAL SYMBOL APESO EXO NEO;So;0;L;;;;;N;;;;; +1D034;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION;So;0;L;;;;;N;;;;; +1D035;BYZANTINE MUSICAL SYMBOL IMIFTHORA;So;0;L;;;;;N;;;;; +1D036;BYZANTINE MUSICAL SYMBOL TROMIKON ARCHAION;So;0;L;;;;;N;;;;; +1D037;BYZANTINE MUSICAL SYMBOL KATAVA TROMIKON;So;0;L;;;;;N;;;;; +1D038;BYZANTINE MUSICAL SYMBOL PELASTON;So;0;L;;;;;N;;;;; +1D039;BYZANTINE MUSICAL SYMBOL PSIFISTON;So;0;L;;;;;N;;;;; +1D03A;BYZANTINE MUSICAL SYMBOL KONTEVMA;So;0;L;;;;;N;;;;; +1D03B;BYZANTINE MUSICAL SYMBOL CHOREVMA ARCHAION;So;0;L;;;;;N;;;;; +1D03C;BYZANTINE MUSICAL SYMBOL RAPISMA;So;0;L;;;;;N;;;;; +1D03D;BYZANTINE MUSICAL SYMBOL PARAKALESMA ARCHAION;So;0;L;;;;;N;;;;; +1D03E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI ARCHAION;So;0;L;;;;;N;;;;; +1D03F;BYZANTINE MUSICAL SYMBOL ICHADIN;So;0;L;;;;;N;;;;; +1D040;BYZANTINE MUSICAL SYMBOL NANA;So;0;L;;;;;N;;;;; +1D041;BYZANTINE MUSICAL SYMBOL PETASMA;So;0;L;;;;;N;;;;; +1D042;BYZANTINE MUSICAL SYMBOL KONTEVMA ALLO;So;0;L;;;;;N;;;;; +1D043;BYZANTINE MUSICAL SYMBOL TROMIKON ALLO;So;0;L;;;;;N;;;;; +1D044;BYZANTINE MUSICAL SYMBOL STRAGGISMATA;So;0;L;;;;;N;;;;; +1D045;BYZANTINE MUSICAL SYMBOL GRONTHISMATA;So;0;L;;;;;N;;;;; +1D046;BYZANTINE MUSICAL SYMBOL ISON NEO;So;0;L;;;;;N;;;;; +1D047;BYZANTINE MUSICAL SYMBOL OLIGON NEO;So;0;L;;;;;N;;;;; +1D048;BYZANTINE MUSICAL SYMBOL OXEIA NEO;So;0;L;;;;;N;;;;; +1D049;BYZANTINE MUSICAL SYMBOL PETASTI;So;0;L;;;;;N;;;;; +1D04A;BYZANTINE MUSICAL SYMBOL KOUFISMA;So;0;L;;;;;N;;;;; +1D04B;BYZANTINE MUSICAL SYMBOL PETASTOKOUFISMA;So;0;L;;;;;N;;;;; +1D04C;BYZANTINE MUSICAL SYMBOL KRATIMOKOUFISMA;So;0;L;;;;;N;;;;; +1D04D;BYZANTINE MUSICAL SYMBOL PELASTON NEO;So;0;L;;;;;N;;;;; +1D04E;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO ANO;So;0;L;;;;;N;;;;; +1D04F;BYZANTINE MUSICAL SYMBOL KENTIMA NEO ANO;So;0;L;;;;;N;;;;; +1D050;BYZANTINE MUSICAL SYMBOL YPSILI;So;0;L;;;;;N;;;;; +1D051;BYZANTINE MUSICAL SYMBOL APOSTROFOS NEO;So;0;L;;;;;N;;;;; +1D052;BYZANTINE MUSICAL SYMBOL APOSTROFOI SYNDESMOS NEO;So;0;L;;;;;N;;;;; +1D053;BYZANTINE MUSICAL SYMBOL YPORROI;So;0;L;;;;;N;;;;; +1D054;BYZANTINE MUSICAL SYMBOL KRATIMOYPORROON;So;0;L;;;;;N;;;;; +1D055;BYZANTINE MUSICAL SYMBOL ELAFRON;So;0;L;;;;;N;;;;; +1D056;BYZANTINE MUSICAL SYMBOL CHAMILI;So;0;L;;;;;N;;;;; +1D057;BYZANTINE MUSICAL SYMBOL MIKRON ISON;So;0;L;;;;;N;;;;; +1D058;BYZANTINE MUSICAL SYMBOL VAREIA NEO;So;0;L;;;;;N;;;;; +1D059;BYZANTINE MUSICAL SYMBOL PIASMA NEO;So;0;L;;;;;N;;;;; +1D05A;BYZANTINE MUSICAL SYMBOL PSIFISTON NEO;So;0;L;;;;;N;;;;; +1D05B;BYZANTINE MUSICAL SYMBOL OMALON;So;0;L;;;;;N;;;;; +1D05C;BYZANTINE MUSICAL SYMBOL ANTIKENOMA;So;0;L;;;;;N;;;;; +1D05D;BYZANTINE MUSICAL SYMBOL LYGISMA;So;0;L;;;;;N;;;;; +1D05E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI NEO;So;0;L;;;;;N;;;;; +1D05F;BYZANTINE MUSICAL SYMBOL PARAKALESMA NEO;So;0;L;;;;;N;;;;; +1D060;BYZANTINE MUSICAL SYMBOL ETERON PARAKALESMA;So;0;L;;;;;N;;;;; +1D061;BYZANTINE MUSICAL SYMBOL KYLISMA;So;0;L;;;;;N;;;;; +1D062;BYZANTINE MUSICAL SYMBOL ANTIKENOKYLISMA;So;0;L;;;;;N;;;;; +1D063;BYZANTINE MUSICAL SYMBOL TROMIKON NEO;So;0;L;;;;;N;;;;; +1D064;BYZANTINE MUSICAL SYMBOL EKSTREPTON;So;0;L;;;;;N;;;;; +1D065;BYZANTINE MUSICAL SYMBOL SYNAGMA NEO;So;0;L;;;;;N;;;;; +1D066;BYZANTINE MUSICAL SYMBOL SYRMA;So;0;L;;;;;N;;;;; +1D067;BYZANTINE MUSICAL SYMBOL CHOREVMA NEO;So;0;L;;;;;N;;;;; +1D068;BYZANTINE MUSICAL SYMBOL EPEGERMA;So;0;L;;;;;N;;;;; +1D069;BYZANTINE MUSICAL SYMBOL SEISMA NEO;So;0;L;;;;;N;;;;; +1D06A;BYZANTINE MUSICAL SYMBOL XIRON KLASMA;So;0;L;;;;;N;;;;; +1D06B;BYZANTINE MUSICAL SYMBOL TROMIKOPSIFISTON;So;0;L;;;;;N;;;;; +1D06C;BYZANTINE MUSICAL SYMBOL PSIFISTOLYGISMA;So;0;L;;;;;N;;;;; +1D06D;BYZANTINE MUSICAL SYMBOL TROMIKOLYGISMA;So;0;L;;;;;N;;;;; +1D06E;BYZANTINE MUSICAL SYMBOL TROMIKOPARAKALESMA;So;0;L;;;;;N;;;;; +1D06F;BYZANTINE MUSICAL SYMBOL PSIFISTOPARAKALESMA;So;0;L;;;;;N;;;;; +1D070;BYZANTINE MUSICAL SYMBOL TROMIKOSYNAGMA;So;0;L;;;;;N;;;;; +1D071;BYZANTINE MUSICAL SYMBOL PSIFISTOSYNAGMA;So;0;L;;;;;N;;;;; +1D072;BYZANTINE MUSICAL SYMBOL GORGOSYNTHETON;So;0;L;;;;;N;;;;; +1D073;BYZANTINE MUSICAL SYMBOL ARGOSYNTHETON;So;0;L;;;;;N;;;;; +1D074;BYZANTINE MUSICAL SYMBOL ETERON ARGOSYNTHETON;So;0;L;;;;;N;;;;; +1D075;BYZANTINE MUSICAL SYMBOL OYRANISMA NEO;So;0;L;;;;;N;;;;; +1D076;BYZANTINE MUSICAL SYMBOL THEMATISMOS ESO;So;0;L;;;;;N;;;;; +1D077;BYZANTINE MUSICAL SYMBOL THEMATISMOS EXO;So;0;L;;;;;N;;;;; +1D078;BYZANTINE MUSICAL SYMBOL THEMA APLOUN;So;0;L;;;;;N;;;;; +1D079;BYZANTINE MUSICAL SYMBOL THES KAI APOTHES;So;0;L;;;;;N;;;;; +1D07A;BYZANTINE MUSICAL SYMBOL KATAVASMA;So;0;L;;;;;N;;;;; +1D07B;BYZANTINE MUSICAL SYMBOL ENDOFONON;So;0;L;;;;;N;;;;; +1D07C;BYZANTINE MUSICAL SYMBOL YFEN KATO;So;0;L;;;;;N;;;;; +1D07D;BYZANTINE MUSICAL SYMBOL YFEN ANO;So;0;L;;;;;N;;;;; +1D07E;BYZANTINE MUSICAL SYMBOL STAVROS;So;0;L;;;;;N;;;;; +1D07F;BYZANTINE MUSICAL SYMBOL KLASMA ANO;So;0;L;;;;;N;;;;; +1D080;BYZANTINE MUSICAL SYMBOL DIPLI ARCHAION;So;0;L;;;;;N;;;;; +1D081;BYZANTINE MUSICAL SYMBOL KRATIMA ARCHAION;So;0;L;;;;;N;;;;; +1D082;BYZANTINE MUSICAL SYMBOL KRATIMA ALLO;So;0;L;;;;;N;;;;; +1D083;BYZANTINE MUSICAL SYMBOL KRATIMA NEO;So;0;L;;;;;N;;;;; +1D084;BYZANTINE MUSICAL SYMBOL APODERMA NEO;So;0;L;;;;;N;;;;; +1D085;BYZANTINE MUSICAL SYMBOL APLI;So;0;L;;;;;N;;;;; +1D086;BYZANTINE MUSICAL SYMBOL DIPLI;So;0;L;;;;;N;;;;; +1D087;BYZANTINE MUSICAL SYMBOL TRIPLI;So;0;L;;;;;N;;;;; +1D088;BYZANTINE MUSICAL SYMBOL TETRAPLI;So;0;L;;;;;N;;;;; +1D089;BYZANTINE MUSICAL SYMBOL KORONIS;So;0;L;;;;;N;;;;; +1D08A;BYZANTINE MUSICAL SYMBOL LEIMMA ENOS CHRONOU;So;0;L;;;;;N;;;;; +1D08B;BYZANTINE MUSICAL SYMBOL LEIMMA DYO CHRONON;So;0;L;;;;;N;;;;; +1D08C;BYZANTINE MUSICAL SYMBOL LEIMMA TRION CHRONON;So;0;L;;;;;N;;;;; +1D08D;BYZANTINE MUSICAL SYMBOL LEIMMA TESSARON CHRONON;So;0;L;;;;;N;;;;; +1D08E;BYZANTINE MUSICAL SYMBOL LEIMMA IMISEOS CHRONOU;So;0;L;;;;;N;;;;; +1D08F;BYZANTINE MUSICAL SYMBOL GORGON NEO ANO;So;0;L;;;;;N;;;;; +1D090;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON ARISTERA;So;0;L;;;;;N;;;;; +1D091;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;; +1D092;BYZANTINE MUSICAL SYMBOL DIGORGON;So;0;L;;;;;N;;;;; +1D093;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA KATO;So;0;L;;;;;N;;;;; +1D094;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA ANO;So;0;L;;;;;N;;;;; +1D095;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;; +1D096;BYZANTINE MUSICAL SYMBOL TRIGORGON;So;0;L;;;;;N;;;;; +1D097;BYZANTINE MUSICAL SYMBOL ARGON;So;0;L;;;;;N;;;;; +1D098;BYZANTINE MUSICAL SYMBOL IMIDIARGON;So;0;L;;;;;N;;;;; +1D099;BYZANTINE MUSICAL SYMBOL DIARGON;So;0;L;;;;;N;;;;; +1D09A;BYZANTINE MUSICAL SYMBOL AGOGI POLI ARGI;So;0;L;;;;;N;;;;; +1D09B;BYZANTINE MUSICAL SYMBOL AGOGI ARGOTERI;So;0;L;;;;;N;;;;; +1D09C;BYZANTINE MUSICAL SYMBOL AGOGI ARGI;So;0;L;;;;;N;;;;; +1D09D;BYZANTINE MUSICAL SYMBOL AGOGI METRIA;So;0;L;;;;;N;;;;; +1D09E;BYZANTINE MUSICAL SYMBOL AGOGI MESI;So;0;L;;;;;N;;;;; +1D09F;BYZANTINE MUSICAL SYMBOL AGOGI GORGI;So;0;L;;;;;N;;;;; +1D0A0;BYZANTINE MUSICAL SYMBOL AGOGI GORGOTERI;So;0;L;;;;;N;;;;; +1D0A1;BYZANTINE MUSICAL SYMBOL AGOGI POLI GORGI;So;0;L;;;;;N;;;;; +1D0A2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOS ICHOS;So;0;L;;;;;N;;;;; +1D0A3;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI PROTOS ICHOS;So;0;L;;;;;N;;;;; +1D0A4;BYZANTINE MUSICAL SYMBOL MARTYRIA DEYTEROS ICHOS;So;0;L;;;;;N;;;;; +1D0A5;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI DEYTEROS ICHOS;So;0;L;;;;;N;;;;; +1D0A6;BYZANTINE MUSICAL SYMBOL MARTYRIA TRITOS ICHOS;So;0;L;;;;;N;;;;; +1D0A7;BYZANTINE MUSICAL SYMBOL MARTYRIA TRIFONIAS;So;0;L;;;;;N;;;;; +1D0A8;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS ICHOS;So;0;L;;;;;N;;;;; +1D0A9;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS LEGETOS ICHOS;So;0;L;;;;;N;;;;; +1D0AA;BYZANTINE MUSICAL SYMBOL MARTYRIA LEGETOS ICHOS;So;0;L;;;;;N;;;;; +1D0AB;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS ICHOS;So;0;L;;;;;N;;;;; +1D0AC;BYZANTINE MUSICAL SYMBOL ISAKIA TELOUS ICHIMATOS;So;0;L;;;;;N;;;;; +1D0AD;BYZANTINE MUSICAL SYMBOL APOSTROFOI TELOUS ICHIMATOS;So;0;L;;;;;N;;;;; +1D0AE;BYZANTINE MUSICAL SYMBOL FANEROSIS TETRAFONIAS;So;0;L;;;;;N;;;;; +1D0AF;BYZANTINE MUSICAL SYMBOL FANEROSIS MONOFONIAS;So;0;L;;;;;N;;;;; +1D0B0;BYZANTINE MUSICAL SYMBOL FANEROSIS DIFONIAS;So;0;L;;;;;N;;;;; +1D0B1;BYZANTINE MUSICAL SYMBOL MARTYRIA VARYS ICHOS;So;0;L;;;;;N;;;;; +1D0B2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOVARYS ICHOS;So;0;L;;;;;N;;;;; +1D0B3;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS TETARTOS ICHOS;So;0;L;;;;;N;;;;; +1D0B4;BYZANTINE MUSICAL SYMBOL GORTHMIKON N APLOUN;So;0;L;;;;;N;;;;; +1D0B5;BYZANTINE MUSICAL SYMBOL GORTHMIKON N DIPLOUN;So;0;L;;;;;N;;;;; +1D0B6;BYZANTINE MUSICAL SYMBOL ENARXIS KAI FTHORA VOU;So;0;L;;;;;N;;;;; +1D0B7;BYZANTINE MUSICAL SYMBOL IMIFONON;So;0;L;;;;;N;;;;; +1D0B8;BYZANTINE MUSICAL SYMBOL IMIFTHORON;So;0;L;;;;;N;;;;; +1D0B9;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION DEYTEROU ICHOU;So;0;L;;;;;N;;;;; +1D0BA;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI PA;So;0;L;;;;;N;;;;; +1D0BB;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NANA;So;0;L;;;;;N;;;;; +1D0BC;BYZANTINE MUSICAL SYMBOL FTHORA NAOS ICHOS;So;0;L;;;;;N;;;;; +1D0BD;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI DI;So;0;L;;;;;N;;;;; +1D0BE;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON DIATONON DI;So;0;L;;;;;N;;;;; +1D0BF;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI KE;So;0;L;;;;;N;;;;; +1D0C0;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI ZO;So;0;L;;;;;N;;;;; +1D0C1;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI KATO;So;0;L;;;;;N;;;;; +1D0C2;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI ANO;So;0;L;;;;;N;;;;; +1D0C3;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA DIFONIAS;So;0;L;;;;;N;;;;; +1D0C4;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA MONOFONIAS;So;0;L;;;;;N;;;;; +1D0C5;BYZANTINE MUSICAL SYMBOL FHTORA SKLIRON CHROMA VASIS;So;0;L;;;;;N;;;;; +1D0C6;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON CHROMA SYNAFI;So;0;L;;;;;N;;;;; +1D0C7;BYZANTINE MUSICAL SYMBOL FTHORA NENANO;So;0;L;;;;;N;;;;; +1D0C8;BYZANTINE MUSICAL SYMBOL CHROA ZYGOS;So;0;L;;;;;N;;;;; +1D0C9;BYZANTINE MUSICAL SYMBOL CHROA KLITON;So;0;L;;;;;N;;;;; +1D0CA;BYZANTINE MUSICAL SYMBOL CHROA SPATHI;So;0;L;;;;;N;;;;; +1D0CB;BYZANTINE MUSICAL SYMBOL FTHORA I YFESIS TETARTIMORION;So;0;L;;;;;N;;;;; +1D0CC;BYZANTINE MUSICAL SYMBOL FTHORA ENARMONIOS ANTIFONIA;So;0;L;;;;;N;;;;; +1D0CD;BYZANTINE MUSICAL SYMBOL YFESIS TRITIMORION;So;0;L;;;;;N;;;;; +1D0CE;BYZANTINE MUSICAL SYMBOL DIESIS TRITIMORION;So;0;L;;;;;N;;;;; +1D0CF;BYZANTINE MUSICAL SYMBOL DIESIS TETARTIMORION;So;0;L;;;;;N;;;;; +1D0D0;BYZANTINE MUSICAL SYMBOL DIESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;; +1D0D1;BYZANTINE MUSICAL SYMBOL DIESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;; +1D0D2;BYZANTINE MUSICAL SYMBOL DIESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;; +1D0D3;BYZANTINE MUSICAL SYMBOL DIESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;; +1D0D4;BYZANTINE MUSICAL SYMBOL YFESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;; +1D0D5;BYZANTINE MUSICAL SYMBOL YFESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;; +1D0D6;BYZANTINE MUSICAL SYMBOL YFESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;; +1D0D7;BYZANTINE MUSICAL SYMBOL YFESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;; +1D0D8;BYZANTINE MUSICAL SYMBOL GENIKI DIESIS;So;0;L;;;;;N;;;;; +1D0D9;BYZANTINE MUSICAL SYMBOL GENIKI YFESIS;So;0;L;;;;;N;;;;; +1D0DA;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MIKRI;So;0;L;;;;;N;;;;; +1D0DB;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MEGALI;So;0;L;;;;;N;;;;; +1D0DC;BYZANTINE MUSICAL SYMBOL DIASTOLI DIPLI;So;0;L;;;;;N;;;;; +1D0DD;BYZANTINE MUSICAL SYMBOL DIASTOLI THESEOS;So;0;L;;;;;N;;;;; +1D0DE;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS;So;0;L;;;;;N;;;;; +1D0DF;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS DISIMOU;So;0;L;;;;;N;;;;; +1D0E0;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TRISIMOU;So;0;L;;;;;N;;;;; +1D0E1;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TETRASIMOU;So;0;L;;;;;N;;;;; +1D0E2;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS;So;0;L;;;;;N;;;;; +1D0E3;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS DISIMOU;So;0;L;;;;;N;;;;; +1D0E4;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TRISIMOU;So;0;L;;;;;N;;;;; +1D0E5;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TETRASIMOU;So;0;L;;;;;N;;;;; +1D0E6;BYZANTINE MUSICAL SYMBOL DIGRAMMA GG;So;0;L;;;;;N;;;;; +1D0E7;BYZANTINE MUSICAL SYMBOL DIFTOGGOS OU;So;0;L;;;;;N;;;;; +1D0E8;BYZANTINE MUSICAL SYMBOL STIGMA;So;0;L;;;;;N;;;;; +1D0E9;BYZANTINE MUSICAL SYMBOL ARKTIKO PA;So;0;L;;;;;N;;;;; +1D0EA;BYZANTINE MUSICAL SYMBOL ARKTIKO VOU;So;0;L;;;;;N;;;;; +1D0EB;BYZANTINE MUSICAL SYMBOL ARKTIKO GA;So;0;L;;;;;N;;;;; +1D0EC;BYZANTINE MUSICAL SYMBOL ARKTIKO DI;So;0;L;;;;;N;;;;; +1D0ED;BYZANTINE MUSICAL SYMBOL ARKTIKO KE;So;0;L;;;;;N;;;;; +1D0EE;BYZANTINE MUSICAL SYMBOL ARKTIKO ZO;So;0;L;;;;;N;;;;; +1D0EF;BYZANTINE MUSICAL SYMBOL ARKTIKO NI;So;0;L;;;;;N;;;;; +1D0F0;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO MESO;So;0;L;;;;;N;;;;; +1D0F1;BYZANTINE MUSICAL SYMBOL KENTIMA NEO MESO;So;0;L;;;;;N;;;;; +1D0F2;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO KATO;So;0;L;;;;;N;;;;; +1D0F3;BYZANTINE MUSICAL SYMBOL KENTIMA NEO KATO;So;0;L;;;;;N;;;;; +1D0F4;BYZANTINE MUSICAL SYMBOL KLASMA KATO;So;0;L;;;;;N;;;;; +1D0F5;BYZANTINE MUSICAL SYMBOL GORGON NEO KATO;So;0;L;;;;;N;;;;; +1D100;MUSICAL SYMBOL SINGLE BARLINE;So;0;L;;;;;N;;;;; +1D101;MUSICAL SYMBOL DOUBLE BARLINE;So;0;L;;;;;N;;;;; +1D102;MUSICAL SYMBOL FINAL BARLINE;So;0;L;;;;;N;;;;; +1D103;MUSICAL SYMBOL REVERSE FINAL BARLINE;So;0;L;;;;;N;;;;; +1D104;MUSICAL SYMBOL DASHED BARLINE;So;0;L;;;;;N;;;;; +1D105;MUSICAL SYMBOL SHORT BARLINE;So;0;L;;;;;N;;;;; +1D106;MUSICAL SYMBOL LEFT REPEAT SIGN;So;0;L;;;;;N;;;;; +1D107;MUSICAL SYMBOL RIGHT REPEAT SIGN;So;0;L;;;;;N;;;;; +1D108;MUSICAL SYMBOL REPEAT DOTS;So;0;L;;;;;N;;;;; +1D109;MUSICAL SYMBOL DAL SEGNO;So;0;L;;;;;N;;;;; +1D10A;MUSICAL SYMBOL DA CAPO;So;0;L;;;;;N;;;;; +1D10B;MUSICAL SYMBOL SEGNO;So;0;L;;;;;N;;;;; +1D10C;MUSICAL SYMBOL CODA;So;0;L;;;;;N;;;;; +1D10D;MUSICAL SYMBOL REPEATED FIGURE-1;So;0;L;;;;;N;;;;; +1D10E;MUSICAL SYMBOL REPEATED FIGURE-2;So;0;L;;;;;N;;;;; +1D10F;MUSICAL SYMBOL REPEATED FIGURE-3;So;0;L;;;;;N;;;;; +1D110;MUSICAL SYMBOL FERMATA;So;0;L;;;;;N;;;;; +1D111;MUSICAL SYMBOL FERMATA BELOW;So;0;L;;;;;N;;;;; +1D112;MUSICAL SYMBOL BREATH MARK;So;0;L;;;;;N;;;;; +1D113;MUSICAL SYMBOL CAESURA;So;0;L;;;;;N;;;;; +1D114;MUSICAL SYMBOL BRACE;So;0;L;;;;;N;;;;; +1D115;MUSICAL SYMBOL BRACKET;So;0;L;;;;;N;;;;; +1D116;MUSICAL SYMBOL ONE-LINE STAFF;So;0;L;;;;;N;;;;; +1D117;MUSICAL SYMBOL TWO-LINE STAFF;So;0;L;;;;;N;;;;; +1D118;MUSICAL SYMBOL THREE-LINE STAFF;So;0;L;;;;;N;;;;; +1D119;MUSICAL SYMBOL FOUR-LINE STAFF;So;0;L;;;;;N;;;;; +1D11A;MUSICAL SYMBOL FIVE-LINE STAFF;So;0;L;;;;;N;;;;; +1D11B;MUSICAL SYMBOL SIX-LINE STAFF;So;0;L;;;;;N;;;;; +1D11C;MUSICAL SYMBOL SIX-STRING FRETBOARD;So;0;L;;;;;N;;;;; +1D11D;MUSICAL SYMBOL FOUR-STRING FRETBOARD;So;0;L;;;;;N;;;;; +1D11E;MUSICAL SYMBOL G CLEF;So;0;L;;;;;N;;;;; +1D11F;MUSICAL SYMBOL G CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;; +1D120;MUSICAL SYMBOL G CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;; +1D121;MUSICAL SYMBOL C CLEF;So;0;L;;;;;N;;;;; +1D122;MUSICAL SYMBOL F CLEF;So;0;L;;;;;N;;;;; +1D123;MUSICAL SYMBOL F CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;; +1D124;MUSICAL SYMBOL F CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;; +1D125;MUSICAL SYMBOL DRUM CLEF-1;So;0;L;;;;;N;;;;; +1D126;MUSICAL SYMBOL DRUM CLEF-2;So;0;L;;;;;N;;;;; +1D129;MUSICAL SYMBOL MULTIPLE MEASURE REST;So;0;L;;;;;N;;;;; +1D12A;MUSICAL SYMBOL DOUBLE SHARP;So;0;L;;;;;N;;;;; +1D12B;MUSICAL SYMBOL DOUBLE FLAT;So;0;L;;;;;N;;;;; +1D12C;MUSICAL SYMBOL FLAT UP;So;0;L;;;;;N;;;;; +1D12D;MUSICAL SYMBOL FLAT DOWN;So;0;L;;;;;N;;;;; +1D12E;MUSICAL SYMBOL NATURAL UP;So;0;L;;;;;N;;;;; +1D12F;MUSICAL SYMBOL NATURAL DOWN;So;0;L;;;;;N;;;;; +1D130;MUSICAL SYMBOL SHARP UP;So;0;L;;;;;N;;;;; +1D131;MUSICAL SYMBOL SHARP DOWN;So;0;L;;;;;N;;;;; +1D132;MUSICAL SYMBOL QUARTER TONE SHARP;So;0;L;;;;;N;;;;; +1D133;MUSICAL SYMBOL QUARTER TONE FLAT;So;0;L;;;;;N;;;;; +1D134;MUSICAL SYMBOL COMMON TIME;So;0;L;;;;;N;;;;; +1D135;MUSICAL SYMBOL CUT TIME;So;0;L;;;;;N;;;;; +1D136;MUSICAL SYMBOL OTTAVA ALTA;So;0;L;;;;;N;;;;; +1D137;MUSICAL SYMBOL OTTAVA BASSA;So;0;L;;;;;N;;;;; +1D138;MUSICAL SYMBOL QUINDICESIMA ALTA;So;0;L;;;;;N;;;;; +1D139;MUSICAL SYMBOL QUINDICESIMA BASSA;So;0;L;;;;;N;;;;; +1D13A;MUSICAL SYMBOL MULTI REST;So;0;L;;;;;N;;;;; +1D13B;MUSICAL SYMBOL WHOLE REST;So;0;L;;;;;N;;;;; +1D13C;MUSICAL SYMBOL HALF REST;So;0;L;;;;;N;;;;; +1D13D;MUSICAL SYMBOL QUARTER REST;So;0;L;;;;;N;;;;; +1D13E;MUSICAL SYMBOL EIGHTH REST;So;0;L;;;;;N;;;;; +1D13F;MUSICAL SYMBOL SIXTEENTH REST;So;0;L;;;;;N;;;;; +1D140;MUSICAL SYMBOL THIRTY-SECOND REST;So;0;L;;;;;N;;;;; +1D141;MUSICAL SYMBOL SIXTY-FOURTH REST;So;0;L;;;;;N;;;;; +1D142;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH REST;So;0;L;;;;;N;;;;; +1D143;MUSICAL SYMBOL X NOTEHEAD;So;0;L;;;;;N;;;;; +1D144;MUSICAL SYMBOL PLUS NOTEHEAD;So;0;L;;;;;N;;;;; +1D145;MUSICAL SYMBOL CIRCLE X NOTEHEAD;So;0;L;;;;;N;;;;; +1D146;MUSICAL SYMBOL SQUARE NOTEHEAD WHITE;So;0;L;;;;;N;;;;; +1D147;MUSICAL SYMBOL SQUARE NOTEHEAD BLACK;So;0;L;;;;;N;;;;; +1D148;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP WHITE;So;0;L;;;;;N;;;;; +1D149;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP BLACK;So;0;L;;;;;N;;;;; +1D14A;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT WHITE;So;0;L;;;;;N;;;;; +1D14B;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT BLACK;So;0;L;;;;;N;;;;; +1D14C;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT WHITE;So;0;L;;;;;N;;;;; +1D14D;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT BLACK;So;0;L;;;;;N;;;;; +1D14E;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;; +1D14F;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;; +1D150;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT WHITE;So;0;L;;;;;N;;;;; +1D151;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT BLACK;So;0;L;;;;;N;;;;; +1D152;MUSICAL SYMBOL MOON NOTEHEAD WHITE;So;0;L;;;;;N;;;;; +1D153;MUSICAL SYMBOL MOON NOTEHEAD BLACK;So;0;L;;;;;N;;;;; +1D154;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;; +1D155;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;; +1D156;MUSICAL SYMBOL PARENTHESIS NOTEHEAD;So;0;L;;;;;N;;;;; +1D157;MUSICAL SYMBOL VOID NOTEHEAD;So;0;L;;;;;N;;;;; +1D158;MUSICAL SYMBOL NOTEHEAD BLACK;So;0;L;;;;;N;;;;; +1D159;MUSICAL SYMBOL NULL NOTEHEAD;So;0;L;;;;;N;;;;; +1D15A;MUSICAL SYMBOL CLUSTER NOTEHEAD WHITE;So;0;L;;;;;N;;;;; +1D15B;MUSICAL SYMBOL CLUSTER NOTEHEAD BLACK;So;0;L;;;;;N;;;;; +1D15C;MUSICAL SYMBOL BREVE;So;0;L;;;;;N;;;;; +1D15D;MUSICAL SYMBOL WHOLE NOTE;So;0;L;;;;;N;;;;; +1D15E;MUSICAL SYMBOL HALF NOTE;So;0;L;1D157 1D165;;;;N;;;;; +1D15F;MUSICAL SYMBOL QUARTER NOTE;So;0;L;1D158 1D165;;;;N;;;;; +1D160;MUSICAL SYMBOL EIGHTH NOTE;So;0;L;1D15F 1D16E;;;;N;;;;; +1D161;MUSICAL SYMBOL SIXTEENTH NOTE;So;0;L;1D15F 1D16F;;;;N;;;;; +1D162;MUSICAL SYMBOL THIRTY-SECOND NOTE;So;0;L;1D15F 1D170;;;;N;;;;; +1D163;MUSICAL SYMBOL SIXTY-FOURTH NOTE;So;0;L;1D15F 1D171;;;;N;;;;; +1D164;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE;So;0;L;1D15F 1D172;;;;N;;;;; +1D165;MUSICAL SYMBOL COMBINING STEM;Mc;216;L;;;;;N;;;;; +1D166;MUSICAL SYMBOL COMBINING SPRECHGESANG STEM;Mc;216;L;;;;;N;;;;; +1D167;MUSICAL SYMBOL COMBINING TREMOLO-1;Mn;1;NSM;;;;;N;;;;; +1D168;MUSICAL SYMBOL COMBINING TREMOLO-2;Mn;1;NSM;;;;;N;;;;; +1D169;MUSICAL SYMBOL COMBINING TREMOLO-3;Mn;1;NSM;;;;;N;;;;; +1D16A;MUSICAL SYMBOL FINGERED TREMOLO-1;So;0;L;;;;;N;;;;; +1D16B;MUSICAL SYMBOL FINGERED TREMOLO-2;So;0;L;;;;;N;;;;; +1D16C;MUSICAL SYMBOL FINGERED TREMOLO-3;So;0;L;;;;;N;;;;; +1D16D;MUSICAL SYMBOL COMBINING AUGMENTATION DOT;Mc;226;L;;;;;N;;;;; +1D16E;MUSICAL SYMBOL COMBINING FLAG-1;Mc;216;L;;;;;N;;;;; +1D16F;MUSICAL SYMBOL COMBINING FLAG-2;Mc;216;L;;;;;N;;;;; +1D170;MUSICAL SYMBOL COMBINING FLAG-3;Mc;216;L;;;;;N;;;;; +1D171;MUSICAL SYMBOL COMBINING FLAG-4;Mc;216;L;;;;;N;;;;; +1D172;MUSICAL SYMBOL COMBINING FLAG-5;Mc;216;L;;;;;N;;;;; +1D173;MUSICAL SYMBOL BEGIN BEAM;Cf;0;BN;;;;;N;;;;; +1D174;MUSICAL SYMBOL END BEAM;Cf;0;BN;;;;;N;;;;; +1D175;MUSICAL SYMBOL BEGIN TIE;Cf;0;BN;;;;;N;;;;; +1D176;MUSICAL SYMBOL END TIE;Cf;0;BN;;;;;N;;;;; +1D177;MUSICAL SYMBOL BEGIN SLUR;Cf;0;BN;;;;;N;;;;; +1D178;MUSICAL SYMBOL END SLUR;Cf;0;BN;;;;;N;;;;; +1D179;MUSICAL SYMBOL BEGIN PHRASE;Cf;0;BN;;;;;N;;;;; +1D17A;MUSICAL SYMBOL END PHRASE;Cf;0;BN;;;;;N;;;;; +1D17B;MUSICAL SYMBOL COMBINING ACCENT;Mn;220;NSM;;;;;N;;;;; +1D17C;MUSICAL SYMBOL COMBINING STACCATO;Mn;220;NSM;;;;;N;;;;; +1D17D;MUSICAL SYMBOL COMBINING TENUTO;Mn;220;NSM;;;;;N;;;;; +1D17E;MUSICAL SYMBOL COMBINING STACCATISSIMO;Mn;220;NSM;;;;;N;;;;; +1D17F;MUSICAL SYMBOL COMBINING MARCATO;Mn;220;NSM;;;;;N;;;;; +1D180;MUSICAL SYMBOL COMBINING MARCATO-STACCATO;Mn;220;NSM;;;;;N;;;;; +1D181;MUSICAL SYMBOL COMBINING ACCENT-STACCATO;Mn;220;NSM;;;;;N;;;;; +1D182;MUSICAL SYMBOL COMBINING LOURE;Mn;220;NSM;;;;;N;;;;; +1D183;MUSICAL SYMBOL ARPEGGIATO UP;So;0;L;;;;;N;;;;; +1D184;MUSICAL SYMBOL ARPEGGIATO DOWN;So;0;L;;;;;N;;;;; +1D185;MUSICAL SYMBOL COMBINING DOIT;Mn;230;NSM;;;;;N;;;;; +1D186;MUSICAL SYMBOL COMBINING RIP;Mn;230;NSM;;;;;N;;;;; +1D187;MUSICAL SYMBOL COMBINING FLIP;Mn;230;NSM;;;;;N;;;;; +1D188;MUSICAL SYMBOL COMBINING SMEAR;Mn;230;NSM;;;;;N;;;;; +1D189;MUSICAL SYMBOL COMBINING BEND;Mn;230;NSM;;;;;N;;;;; +1D18A;MUSICAL SYMBOL COMBINING DOUBLE TONGUE;Mn;220;NSM;;;;;N;;;;; +1D18B;MUSICAL SYMBOL COMBINING TRIPLE TONGUE;Mn;220;NSM;;;;;N;;;;; +1D18C;MUSICAL SYMBOL RINFORZANDO;So;0;L;;;;;N;;;;; +1D18D;MUSICAL SYMBOL SUBITO;So;0;L;;;;;N;;;;; +1D18E;MUSICAL SYMBOL Z;So;0;L;;;;;N;;;;; +1D18F;MUSICAL SYMBOL PIANO;So;0;L;;;;;N;;;;; +1D190;MUSICAL SYMBOL MEZZO;So;0;L;;;;;N;;;;; +1D191;MUSICAL SYMBOL FORTE;So;0;L;;;;;N;;;;; +1D192;MUSICAL SYMBOL CRESCENDO;So;0;L;;;;;N;;;;; +1D193;MUSICAL SYMBOL DECRESCENDO;So;0;L;;;;;N;;;;; +1D194;MUSICAL SYMBOL GRACE NOTE SLASH;So;0;L;;;;;N;;;;; +1D195;MUSICAL SYMBOL GRACE NOTE NO SLASH;So;0;L;;;;;N;;;;; +1D196;MUSICAL SYMBOL TR;So;0;L;;;;;N;;;;; +1D197;MUSICAL SYMBOL TURN;So;0;L;;;;;N;;;;; +1D198;MUSICAL SYMBOL INVERTED TURN;So;0;L;;;;;N;;;;; +1D199;MUSICAL SYMBOL TURN SLASH;So;0;L;;;;;N;;;;; +1D19A;MUSICAL SYMBOL TURN UP;So;0;L;;;;;N;;;;; +1D19B;MUSICAL SYMBOL ORNAMENT STROKE-1;So;0;L;;;;;N;;;;; +1D19C;MUSICAL SYMBOL ORNAMENT STROKE-2;So;0;L;;;;;N;;;;; +1D19D;MUSICAL SYMBOL ORNAMENT STROKE-3;So;0;L;;;;;N;;;;; +1D19E;MUSICAL SYMBOL ORNAMENT STROKE-4;So;0;L;;;;;N;;;;; +1D19F;MUSICAL SYMBOL ORNAMENT STROKE-5;So;0;L;;;;;N;;;;; +1D1A0;MUSICAL SYMBOL ORNAMENT STROKE-6;So;0;L;;;;;N;;;;; +1D1A1;MUSICAL SYMBOL ORNAMENT STROKE-7;So;0;L;;;;;N;;;;; +1D1A2;MUSICAL SYMBOL ORNAMENT STROKE-8;So;0;L;;;;;N;;;;; +1D1A3;MUSICAL SYMBOL ORNAMENT STROKE-9;So;0;L;;;;;N;;;;; +1D1A4;MUSICAL SYMBOL ORNAMENT STROKE-10;So;0;L;;;;;N;;;;; +1D1A5;MUSICAL SYMBOL ORNAMENT STROKE-11;So;0;L;;;;;N;;;;; +1D1A6;MUSICAL SYMBOL HAUPTSTIMME;So;0;L;;;;;N;;;;; +1D1A7;MUSICAL SYMBOL NEBENSTIMME;So;0;L;;;;;N;;;;; +1D1A8;MUSICAL SYMBOL END OF STIMME;So;0;L;;;;;N;;;;; +1D1A9;MUSICAL SYMBOL DEGREE SLASH;So;0;L;;;;;N;;;;; +1D1AA;MUSICAL SYMBOL COMBINING DOWN BOW;Mn;230;NSM;;;;;N;;;;; +1D1AB;MUSICAL SYMBOL COMBINING UP BOW;Mn;230;NSM;;;;;N;;;;; +1D1AC;MUSICAL SYMBOL COMBINING HARMONIC;Mn;230;NSM;;;;;N;;;;; +1D1AD;MUSICAL SYMBOL COMBINING SNAP PIZZICATO;Mn;230;NSM;;;;;N;;;;; +1D1AE;MUSICAL SYMBOL PEDAL MARK;So;0;L;;;;;N;;;;; +1D1AF;MUSICAL SYMBOL PEDAL UP MARK;So;0;L;;;;;N;;;;; +1D1B0;MUSICAL SYMBOL HALF PEDAL MARK;So;0;L;;;;;N;;;;; +1D1B1;MUSICAL SYMBOL GLISSANDO UP;So;0;L;;;;;N;;;;; +1D1B2;MUSICAL SYMBOL GLISSANDO DOWN;So;0;L;;;;;N;;;;; +1D1B3;MUSICAL SYMBOL WITH FINGERNAILS;So;0;L;;;;;N;;;;; +1D1B4;MUSICAL SYMBOL DAMP;So;0;L;;;;;N;;;;; +1D1B5;MUSICAL SYMBOL DAMP ALL;So;0;L;;;;;N;;;;; +1D1B6;MUSICAL SYMBOL MAXIMA;So;0;L;;;;;N;;;;; +1D1B7;MUSICAL SYMBOL LONGA;So;0;L;;;;;N;;;;; +1D1B8;MUSICAL SYMBOL BREVIS;So;0;L;;;;;N;;;;; +1D1B9;MUSICAL SYMBOL SEMIBREVIS WHITE;So;0;L;;;;;N;;;;; +1D1BA;MUSICAL SYMBOL SEMIBREVIS BLACK;So;0;L;;;;;N;;;;; +1D1BB;MUSICAL SYMBOL MINIMA;So;0;L;1D1B9 1D165;;;;N;;;;; +1D1BC;MUSICAL SYMBOL MINIMA BLACK;So;0;L;1D1BA 1D165;;;;N;;;;; +1D1BD;MUSICAL SYMBOL SEMIMINIMA WHITE;So;0;L;1D1BB 1D16E;;;;N;;;;; +1D1BE;MUSICAL SYMBOL SEMIMINIMA BLACK;So;0;L;1D1BC 1D16E;;;;N;;;;; +1D1BF;MUSICAL SYMBOL FUSA WHITE;So;0;L;1D1BB 1D16F;;;;N;;;;; +1D1C0;MUSICAL SYMBOL FUSA BLACK;So;0;L;1D1BC 1D16F;;;;N;;;;; +1D1C1;MUSICAL SYMBOL LONGA PERFECTA REST;So;0;L;;;;;N;;;;; +1D1C2;MUSICAL SYMBOL LONGA IMPERFECTA REST;So;0;L;;;;;N;;;;; +1D1C3;MUSICAL SYMBOL BREVIS REST;So;0;L;;;;;N;;;;; +1D1C4;MUSICAL SYMBOL SEMIBREVIS REST;So;0;L;;;;;N;;;;; +1D1C5;MUSICAL SYMBOL MINIMA REST;So;0;L;;;;;N;;;;; +1D1C6;MUSICAL SYMBOL SEMIMINIMA REST;So;0;L;;;;;N;;;;; +1D1C7;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;; +1D1C8;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;; +1D1C9;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;; +1D1CA;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;; +1D1CB;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;; +1D1CC;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;; +1D1CD;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-2;So;0;L;;;;;N;;;;; +1D1CE;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-3;So;0;L;;;;;N;;;;; +1D1CF;MUSICAL SYMBOL CROIX;So;0;L;;;;;N;;;;; +1D1D0;MUSICAL SYMBOL GREGORIAN C CLEF;So;0;L;;;;;N;;;;; +1D1D1;MUSICAL SYMBOL GREGORIAN F CLEF;So;0;L;;;;;N;;;;; +1D1D2;MUSICAL SYMBOL SQUARE B;So;0;L;;;;;N;;;;; +1D1D3;MUSICAL SYMBOL VIRGA;So;0;L;;;;;N;;;;; +1D1D4;MUSICAL SYMBOL PODATUS;So;0;L;;;;;N;;;;; +1D1D5;MUSICAL SYMBOL CLIVIS;So;0;L;;;;;N;;;;; +1D1D6;MUSICAL SYMBOL SCANDICUS;So;0;L;;;;;N;;;;; +1D1D7;MUSICAL SYMBOL CLIMACUS;So;0;L;;;;;N;;;;; +1D1D8;MUSICAL SYMBOL TORCULUS;So;0;L;;;;;N;;;;; +1D1D9;MUSICAL SYMBOL PORRECTUS;So;0;L;;;;;N;;;;; +1D1DA;MUSICAL SYMBOL PORRECTUS FLEXUS;So;0;L;;;;;N;;;;; +1D1DB;MUSICAL SYMBOL SCANDICUS FLEXUS;So;0;L;;;;;N;;;;; +1D1DC;MUSICAL SYMBOL TORCULUS RESUPINUS;So;0;L;;;;;N;;;;; +1D1DD;MUSICAL SYMBOL PES SUBPUNCTIS;So;0;L;;;;;N;;;;; +1D1DE;MUSICAL SYMBOL KIEVAN C CLEF;So;0;L;;;;;N;;;;; +1D1DF;MUSICAL SYMBOL KIEVAN END OF PIECE;So;0;L;;;;;N;;;;; +1D1E0;MUSICAL SYMBOL KIEVAN FINAL NOTE;So;0;L;;;;;N;;;;; +1D1E1;MUSICAL SYMBOL KIEVAN RECITATIVE MARK;So;0;L;;;;;N;;;;; +1D1E2;MUSICAL SYMBOL KIEVAN WHOLE NOTE;So;0;L;;;;;N;;;;; +1D1E3;MUSICAL SYMBOL KIEVAN HALF NOTE;So;0;L;;;;;N;;;;; +1D1E4;MUSICAL SYMBOL KIEVAN QUARTER NOTE STEM DOWN;So;0;L;;;;;N;;;;; +1D1E5;MUSICAL SYMBOL KIEVAN QUARTER NOTE STEM UP;So;0;L;;;;;N;;;;; +1D1E6;MUSICAL SYMBOL KIEVAN EIGHTH NOTE STEM DOWN;So;0;L;;;;;N;;;;; +1D1E7;MUSICAL SYMBOL KIEVAN EIGHTH NOTE STEM UP;So;0;L;;;;;N;;;;; +1D1E8;MUSICAL SYMBOL KIEVAN FLAT SIGN;So;0;L;;;;;N;;;;; +1D200;GREEK VOCAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;; +1D201;GREEK VOCAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;; +1D202;GREEK VOCAL NOTATION SYMBOL-3;So;0;ON;;;;;N;;;;; +1D203;GREEK VOCAL NOTATION SYMBOL-4;So;0;ON;;;;;N;;;;; +1D204;GREEK VOCAL NOTATION SYMBOL-5;So;0;ON;;;;;N;;;;; +1D205;GREEK VOCAL NOTATION SYMBOL-6;So;0;ON;;;;;N;;;;; +1D206;GREEK VOCAL NOTATION SYMBOL-7;So;0;ON;;;;;N;;;;; +1D207;GREEK VOCAL NOTATION SYMBOL-8;So;0;ON;;;;;N;;;;; +1D208;GREEK VOCAL NOTATION SYMBOL-9;So;0;ON;;;;;N;;;;; +1D209;GREEK VOCAL NOTATION SYMBOL-10;So;0;ON;;;;;N;;;;; +1D20A;GREEK VOCAL NOTATION SYMBOL-11;So;0;ON;;;;;N;;;;; +1D20B;GREEK VOCAL NOTATION SYMBOL-12;So;0;ON;;;;;N;;;;; +1D20C;GREEK VOCAL NOTATION SYMBOL-13;So;0;ON;;;;;N;;;;; +1D20D;GREEK VOCAL NOTATION SYMBOL-14;So;0;ON;;;;;N;;;;; +1D20E;GREEK VOCAL NOTATION SYMBOL-15;So;0;ON;;;;;N;;;;; +1D20F;GREEK VOCAL NOTATION SYMBOL-16;So;0;ON;;;;;N;;;;; +1D210;GREEK VOCAL NOTATION SYMBOL-17;So;0;ON;;;;;N;;;;; +1D211;GREEK VOCAL NOTATION SYMBOL-18;So;0;ON;;;;;N;;;;; +1D212;GREEK VOCAL NOTATION SYMBOL-19;So;0;ON;;;;;N;;;;; +1D213;GREEK VOCAL NOTATION SYMBOL-20;So;0;ON;;;;;N;;;;; +1D214;GREEK VOCAL NOTATION SYMBOL-21;So;0;ON;;;;;N;;;;; +1D215;GREEK VOCAL NOTATION SYMBOL-22;So;0;ON;;;;;N;;;;; +1D216;GREEK VOCAL NOTATION SYMBOL-23;So;0;ON;;;;;N;;;;; +1D217;GREEK VOCAL NOTATION SYMBOL-24;So;0;ON;;;;;N;;;;; +1D218;GREEK VOCAL NOTATION SYMBOL-50;So;0;ON;;;;;N;;;;; +1D219;GREEK VOCAL NOTATION SYMBOL-51;So;0;ON;;;;;N;;;;; +1D21A;GREEK VOCAL NOTATION SYMBOL-52;So;0;ON;;;;;N;;;;; +1D21B;GREEK VOCAL NOTATION SYMBOL-53;So;0;ON;;;;;N;;;;; +1D21C;GREEK VOCAL NOTATION SYMBOL-54;So;0;ON;;;;;N;;;;; +1D21D;GREEK INSTRUMENTAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;; +1D21E;GREEK INSTRUMENTAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;; +1D21F;GREEK INSTRUMENTAL NOTATION SYMBOL-4;So;0;ON;;;;;N;;;;; +1D220;GREEK INSTRUMENTAL NOTATION SYMBOL-5;So;0;ON;;;;;N;;;;; +1D221;GREEK INSTRUMENTAL NOTATION SYMBOL-7;So;0;ON;;;;;N;;;;; +1D222;GREEK INSTRUMENTAL NOTATION SYMBOL-8;So;0;ON;;;;;N;;;;; +1D223;GREEK INSTRUMENTAL NOTATION SYMBOL-11;So;0;ON;;;;;N;;;;; +1D224;GREEK INSTRUMENTAL NOTATION SYMBOL-12;So;0;ON;;;;;N;;;;; +1D225;GREEK INSTRUMENTAL NOTATION SYMBOL-13;So;0;ON;;;;;N;;;;; +1D226;GREEK INSTRUMENTAL NOTATION SYMBOL-14;So;0;ON;;;;;N;;;;; +1D227;GREEK INSTRUMENTAL NOTATION SYMBOL-17;So;0;ON;;;;;N;;;;; +1D228;GREEK INSTRUMENTAL NOTATION SYMBOL-18;So;0;ON;;;;;N;;;;; +1D229;GREEK INSTRUMENTAL NOTATION SYMBOL-19;So;0;ON;;;;;N;;;;; +1D22A;GREEK INSTRUMENTAL NOTATION SYMBOL-23;So;0;ON;;;;;N;;;;; +1D22B;GREEK INSTRUMENTAL NOTATION SYMBOL-24;So;0;ON;;;;;N;;;;; +1D22C;GREEK INSTRUMENTAL NOTATION SYMBOL-25;So;0;ON;;;;;N;;;;; +1D22D;GREEK INSTRUMENTAL NOTATION SYMBOL-26;So;0;ON;;;;;N;;;;; +1D22E;GREEK INSTRUMENTAL NOTATION SYMBOL-27;So;0;ON;;;;;N;;;;; +1D22F;GREEK INSTRUMENTAL NOTATION SYMBOL-29;So;0;ON;;;;;N;;;;; +1D230;GREEK INSTRUMENTAL NOTATION SYMBOL-30;So;0;ON;;;;;N;;;;; +1D231;GREEK INSTRUMENTAL NOTATION SYMBOL-32;So;0;ON;;;;;N;;;;; +1D232;GREEK INSTRUMENTAL NOTATION SYMBOL-36;So;0;ON;;;;;N;;;;; +1D233;GREEK INSTRUMENTAL NOTATION SYMBOL-37;So;0;ON;;;;;N;;;;; +1D234;GREEK INSTRUMENTAL NOTATION SYMBOL-38;So;0;ON;;;;;N;;;;; +1D235;GREEK INSTRUMENTAL NOTATION SYMBOL-39;So;0;ON;;;;;N;;;;; +1D236;GREEK INSTRUMENTAL NOTATION SYMBOL-40;So;0;ON;;;;;N;;;;; +1D237;GREEK INSTRUMENTAL NOTATION SYMBOL-42;So;0;ON;;;;;N;;;;; +1D238;GREEK INSTRUMENTAL NOTATION SYMBOL-43;So;0;ON;;;;;N;;;;; +1D239;GREEK INSTRUMENTAL NOTATION SYMBOL-45;So;0;ON;;;;;N;;;;; +1D23A;GREEK INSTRUMENTAL NOTATION SYMBOL-47;So;0;ON;;;;;N;;;;; +1D23B;GREEK INSTRUMENTAL NOTATION SYMBOL-48;So;0;ON;;;;;N;;;;; +1D23C;GREEK INSTRUMENTAL NOTATION SYMBOL-49;So;0;ON;;;;;N;;;;; +1D23D;GREEK INSTRUMENTAL NOTATION SYMBOL-50;So;0;ON;;;;;N;;;;; +1D23E;GREEK INSTRUMENTAL NOTATION SYMBOL-51;So;0;ON;;;;;N;;;;; +1D23F;GREEK INSTRUMENTAL NOTATION SYMBOL-52;So;0;ON;;;;;N;;;;; +1D240;GREEK INSTRUMENTAL NOTATION SYMBOL-53;So;0;ON;;;;;N;;;;; +1D241;GREEK INSTRUMENTAL NOTATION SYMBOL-54;So;0;ON;;;;;N;;;;; +1D242;COMBINING GREEK MUSICAL TRISEME;Mn;230;NSM;;;;;N;;;;; +1D243;COMBINING GREEK MUSICAL TETRASEME;Mn;230;NSM;;;;;N;;;;; +1D244;COMBINING GREEK MUSICAL PENTASEME;Mn;230;NSM;;;;;N;;;;; +1D245;GREEK MUSICAL LEIMMA;So;0;ON;;;;;N;;;;; +1D2E0;MAYAN NUMERAL ZERO;No;0;L;;;;0;N;;;;; +1D2E1;MAYAN NUMERAL ONE;No;0;L;;;;1;N;;;;; +1D2E2;MAYAN NUMERAL TWO;No;0;L;;;;2;N;;;;; +1D2E3;MAYAN NUMERAL THREE;No;0;L;;;;3;N;;;;; +1D2E4;MAYAN NUMERAL FOUR;No;0;L;;;;4;N;;;;; +1D2E5;MAYAN NUMERAL FIVE;No;0;L;;;;5;N;;;;; +1D2E6;MAYAN NUMERAL SIX;No;0;L;;;;6;N;;;;; +1D2E7;MAYAN NUMERAL SEVEN;No;0;L;;;;7;N;;;;; +1D2E8;MAYAN NUMERAL EIGHT;No;0;L;;;;8;N;;;;; +1D2E9;MAYAN NUMERAL NINE;No;0;L;;;;9;N;;;;; +1D2EA;MAYAN NUMERAL TEN;No;0;L;;;;10;N;;;;; +1D2EB;MAYAN NUMERAL ELEVEN;No;0;L;;;;11;N;;;;; +1D2EC;MAYAN NUMERAL TWELVE;No;0;L;;;;12;N;;;;; +1D2ED;MAYAN NUMERAL THIRTEEN;No;0;L;;;;13;N;;;;; +1D2EE;MAYAN NUMERAL FOURTEEN;No;0;L;;;;14;N;;;;; +1D2EF;MAYAN NUMERAL FIFTEEN;No;0;L;;;;15;N;;;;; +1D2F0;MAYAN NUMERAL SIXTEEN;No;0;L;;;;16;N;;;;; +1D2F1;MAYAN NUMERAL SEVENTEEN;No;0;L;;;;17;N;;;;; +1D2F2;MAYAN NUMERAL EIGHTEEN;No;0;L;;;;18;N;;;;; +1D2F3;MAYAN NUMERAL NINETEEN;No;0;L;;;;19;N;;;;; +1D300;MONOGRAM FOR EARTH;So;0;ON;;;;;N;;;;; +1D301;DIGRAM FOR HEAVENLY EARTH;So;0;ON;;;;;N;;;;; +1D302;DIGRAM FOR HUMAN EARTH;So;0;ON;;;;;N;;;;; +1D303;DIGRAM FOR EARTHLY HEAVEN;So;0;ON;;;;;N;;;;; +1D304;DIGRAM FOR EARTHLY HUMAN;So;0;ON;;;;;N;;;;; +1D305;DIGRAM FOR EARTH;So;0;ON;;;;;N;;;;; +1D306;TETRAGRAM FOR CENTRE;So;0;ON;;;;;N;;;;; +1D307;TETRAGRAM FOR FULL CIRCLE;So;0;ON;;;;;N;;;;; +1D308;TETRAGRAM FOR MIRED;So;0;ON;;;;;N;;;;; +1D309;TETRAGRAM FOR BARRIER;So;0;ON;;;;;N;;;;; +1D30A;TETRAGRAM FOR KEEPING SMALL;So;0;ON;;;;;N;;;;; +1D30B;TETRAGRAM FOR CONTRARIETY;So;0;ON;;;;;N;;;;; +1D30C;TETRAGRAM FOR ASCENT;So;0;ON;;;;;N;;;;; +1D30D;TETRAGRAM FOR OPPOSITION;So;0;ON;;;;;N;;;;; +1D30E;TETRAGRAM FOR BRANCHING OUT;So;0;ON;;;;;N;;;;; +1D30F;TETRAGRAM FOR DEFECTIVENESS OR DISTORTION;So;0;ON;;;;;N;;;;; +1D310;TETRAGRAM FOR DIVERGENCE;So;0;ON;;;;;N;;;;; +1D311;TETRAGRAM FOR YOUTHFULNESS;So;0;ON;;;;;N;;;;; +1D312;TETRAGRAM FOR INCREASE;So;0;ON;;;;;N;;;;; +1D313;TETRAGRAM FOR PENETRATION;So;0;ON;;;;;N;;;;; +1D314;TETRAGRAM FOR REACH;So;0;ON;;;;;N;;;;; +1D315;TETRAGRAM FOR CONTACT;So;0;ON;;;;;N;;;;; +1D316;TETRAGRAM FOR HOLDING BACK;So;0;ON;;;;;N;;;;; +1D317;TETRAGRAM FOR WAITING;So;0;ON;;;;;N;;;;; +1D318;TETRAGRAM FOR FOLLOWING;So;0;ON;;;;;N;;;;; +1D319;TETRAGRAM FOR ADVANCE;So;0;ON;;;;;N;;;;; +1D31A;TETRAGRAM FOR RELEASE;So;0;ON;;;;;N;;;;; +1D31B;TETRAGRAM FOR RESISTANCE;So;0;ON;;;;;N;;;;; +1D31C;TETRAGRAM FOR EASE;So;0;ON;;;;;N;;;;; +1D31D;TETRAGRAM FOR JOY;So;0;ON;;;;;N;;;;; +1D31E;TETRAGRAM FOR CONTENTION;So;0;ON;;;;;N;;;;; +1D31F;TETRAGRAM FOR ENDEAVOUR;So;0;ON;;;;;N;;;;; +1D320;TETRAGRAM FOR DUTIES;So;0;ON;;;;;N;;;;; +1D321;TETRAGRAM FOR CHANGE;So;0;ON;;;;;N;;;;; +1D322;TETRAGRAM FOR DECISIVENESS;So;0;ON;;;;;N;;;;; +1D323;TETRAGRAM FOR BOLD RESOLUTION;So;0;ON;;;;;N;;;;; +1D324;TETRAGRAM FOR PACKING;So;0;ON;;;;;N;;;;; +1D325;TETRAGRAM FOR LEGION;So;0;ON;;;;;N;;;;; +1D326;TETRAGRAM FOR CLOSENESS;So;0;ON;;;;;N;;;;; +1D327;TETRAGRAM FOR KINSHIP;So;0;ON;;;;;N;;;;; +1D328;TETRAGRAM FOR GATHERING;So;0;ON;;;;;N;;;;; +1D329;TETRAGRAM FOR STRENGTH;So;0;ON;;;;;N;;;;; +1D32A;TETRAGRAM FOR PURITY;So;0;ON;;;;;N;;;;; +1D32B;TETRAGRAM FOR FULLNESS;So;0;ON;;;;;N;;;;; +1D32C;TETRAGRAM FOR RESIDENCE;So;0;ON;;;;;N;;;;; +1D32D;TETRAGRAM FOR LAW OR MODEL;So;0;ON;;;;;N;;;;; +1D32E;TETRAGRAM FOR RESPONSE;So;0;ON;;;;;N;;;;; +1D32F;TETRAGRAM FOR GOING TO MEET;So;0;ON;;;;;N;;;;; +1D330;TETRAGRAM FOR ENCOUNTERS;So;0;ON;;;;;N;;;;; +1D331;TETRAGRAM FOR STOVE;So;0;ON;;;;;N;;;;; +1D332;TETRAGRAM FOR GREATNESS;So;0;ON;;;;;N;;;;; +1D333;TETRAGRAM FOR ENLARGEMENT;So;0;ON;;;;;N;;;;; +1D334;TETRAGRAM FOR PATTERN;So;0;ON;;;;;N;;;;; +1D335;TETRAGRAM FOR RITUAL;So;0;ON;;;;;N;;;;; +1D336;TETRAGRAM FOR FLIGHT;So;0;ON;;;;;N;;;;; +1D337;TETRAGRAM FOR VASTNESS OR WASTING;So;0;ON;;;;;N;;;;; +1D338;TETRAGRAM FOR CONSTANCY;So;0;ON;;;;;N;;;;; +1D339;TETRAGRAM FOR MEASURE;So;0;ON;;;;;N;;;;; +1D33A;TETRAGRAM FOR ETERNITY;So;0;ON;;;;;N;;;;; +1D33B;TETRAGRAM FOR UNITY;So;0;ON;;;;;N;;;;; +1D33C;TETRAGRAM FOR DIMINISHMENT;So;0;ON;;;;;N;;;;; +1D33D;TETRAGRAM FOR CLOSED MOUTH;So;0;ON;;;;;N;;;;; +1D33E;TETRAGRAM FOR GUARDEDNESS;So;0;ON;;;;;N;;;;; +1D33F;TETRAGRAM FOR GATHERING IN;So;0;ON;;;;;N;;;;; +1D340;TETRAGRAM FOR MASSING;So;0;ON;;;;;N;;;;; +1D341;TETRAGRAM FOR ACCUMULATION;So;0;ON;;;;;N;;;;; +1D342;TETRAGRAM FOR EMBELLISHMENT;So;0;ON;;;;;N;;;;; +1D343;TETRAGRAM FOR DOUBT;So;0;ON;;;;;N;;;;; +1D344;TETRAGRAM FOR WATCH;So;0;ON;;;;;N;;;;; +1D345;TETRAGRAM FOR SINKING;So;0;ON;;;;;N;;;;; +1D346;TETRAGRAM FOR INNER;So;0;ON;;;;;N;;;;; +1D347;TETRAGRAM FOR DEPARTURE;So;0;ON;;;;;N;;;;; +1D348;TETRAGRAM FOR DARKENING;So;0;ON;;;;;N;;;;; +1D349;TETRAGRAM FOR DIMMING;So;0;ON;;;;;N;;;;; +1D34A;TETRAGRAM FOR EXHAUSTION;So;0;ON;;;;;N;;;;; +1D34B;TETRAGRAM FOR SEVERANCE;So;0;ON;;;;;N;;;;; +1D34C;TETRAGRAM FOR STOPPAGE;So;0;ON;;;;;N;;;;; +1D34D;TETRAGRAM FOR HARDNESS;So;0;ON;;;;;N;;;;; +1D34E;TETRAGRAM FOR COMPLETION;So;0;ON;;;;;N;;;;; +1D34F;TETRAGRAM FOR CLOSURE;So;0;ON;;;;;N;;;;; +1D350;TETRAGRAM FOR FAILURE;So;0;ON;;;;;N;;;;; +1D351;TETRAGRAM FOR AGGRAVATION;So;0;ON;;;;;N;;;;; +1D352;TETRAGRAM FOR COMPLIANCE;So;0;ON;;;;;N;;;;; +1D353;TETRAGRAM FOR ON THE VERGE;So;0;ON;;;;;N;;;;; +1D354;TETRAGRAM FOR DIFFICULTIES;So;0;ON;;;;;N;;;;; +1D355;TETRAGRAM FOR LABOURING;So;0;ON;;;;;N;;;;; +1D356;TETRAGRAM FOR FOSTERING;So;0;ON;;;;;N;;;;; +1D360;COUNTING ROD UNIT DIGIT ONE;No;0;L;;;;1;N;;;;; +1D361;COUNTING ROD UNIT DIGIT TWO;No;0;L;;;;2;N;;;;; +1D362;COUNTING ROD UNIT DIGIT THREE;No;0;L;;;;3;N;;;;; +1D363;COUNTING ROD UNIT DIGIT FOUR;No;0;L;;;;4;N;;;;; +1D364;COUNTING ROD UNIT DIGIT FIVE;No;0;L;;;;5;N;;;;; +1D365;COUNTING ROD UNIT DIGIT SIX;No;0;L;;;;6;N;;;;; +1D366;COUNTING ROD UNIT DIGIT SEVEN;No;0;L;;;;7;N;;;;; +1D367;COUNTING ROD UNIT DIGIT EIGHT;No;0;L;;;;8;N;;;;; +1D368;COUNTING ROD UNIT DIGIT NINE;No;0;L;;;;9;N;;;;; +1D369;COUNTING ROD TENS DIGIT ONE;No;0;L;;;;10;N;;;;; +1D36A;COUNTING ROD TENS DIGIT TWO;No;0;L;;;;20;N;;;;; +1D36B;COUNTING ROD TENS DIGIT THREE;No;0;L;;;;30;N;;;;; +1D36C;COUNTING ROD TENS DIGIT FOUR;No;0;L;;;;40;N;;;;; +1D36D;COUNTING ROD TENS DIGIT FIVE;No;0;L;;;;50;N;;;;; +1D36E;COUNTING ROD TENS DIGIT SIX;No;0;L;;;;60;N;;;;; +1D36F;COUNTING ROD TENS DIGIT SEVEN;No;0;L;;;;70;N;;;;; +1D370;COUNTING ROD TENS DIGIT EIGHT;No;0;L;;;;80;N;;;;; +1D371;COUNTING ROD TENS DIGIT NINE;No;0;L;;;;90;N;;;;; +1D372;IDEOGRAPHIC TALLY MARK ONE;No;0;L;;;;1;N;;;;; +1D373;IDEOGRAPHIC TALLY MARK TWO;No;0;L;;;;2;N;;;;; +1D374;IDEOGRAPHIC TALLY MARK THREE;No;0;L;;;;3;N;;;;; +1D375;IDEOGRAPHIC TALLY MARK FOUR;No;0;L;;;;4;N;;;;; +1D376;IDEOGRAPHIC TALLY MARK FIVE;No;0;L;;;;5;N;;;;; +1D377;TALLY MARK ONE;No;0;L;;;;1;N;;;;; +1D378;TALLY MARK FIVE;No;0;L;;;;5;N;;;;; +1D400;MATHEMATICAL BOLD CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D401;MATHEMATICAL BOLD CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D402;MATHEMATICAL BOLD CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D403;MATHEMATICAL BOLD CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D404;MATHEMATICAL BOLD CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D405;MATHEMATICAL BOLD CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D406;MATHEMATICAL BOLD CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D407;MATHEMATICAL BOLD CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D408;MATHEMATICAL BOLD CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D409;MATHEMATICAL BOLD CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D40A;MATHEMATICAL BOLD CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D40B;MATHEMATICAL BOLD CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D40C;MATHEMATICAL BOLD CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D40D;MATHEMATICAL BOLD CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D40E;MATHEMATICAL BOLD CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D40F;MATHEMATICAL BOLD CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D410;MATHEMATICAL BOLD CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D411;MATHEMATICAL BOLD CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D412;MATHEMATICAL BOLD CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D413;MATHEMATICAL BOLD CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D414;MATHEMATICAL BOLD CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D415;MATHEMATICAL BOLD CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D416;MATHEMATICAL BOLD CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D417;MATHEMATICAL BOLD CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D418;MATHEMATICAL BOLD CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D419;MATHEMATICAL BOLD CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D41A;MATHEMATICAL BOLD SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D41B;MATHEMATICAL BOLD SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D41C;MATHEMATICAL BOLD SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D41D;MATHEMATICAL BOLD SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D41E;MATHEMATICAL BOLD SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D41F;MATHEMATICAL BOLD SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D420;MATHEMATICAL BOLD SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D421;MATHEMATICAL BOLD SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D422;MATHEMATICAL BOLD SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D423;MATHEMATICAL BOLD SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D424;MATHEMATICAL BOLD SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D425;MATHEMATICAL BOLD SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D426;MATHEMATICAL BOLD SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D427;MATHEMATICAL BOLD SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D428;MATHEMATICAL BOLD SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D429;MATHEMATICAL BOLD SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D42A;MATHEMATICAL BOLD SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D42B;MATHEMATICAL BOLD SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D42C;MATHEMATICAL BOLD SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D42D;MATHEMATICAL BOLD SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D42E;MATHEMATICAL BOLD SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D42F;MATHEMATICAL BOLD SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D430;MATHEMATICAL BOLD SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D431;MATHEMATICAL BOLD SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D432;MATHEMATICAL BOLD SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D433;MATHEMATICAL BOLD SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D434;MATHEMATICAL ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D435;MATHEMATICAL ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D436;MATHEMATICAL ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D437;MATHEMATICAL ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D438;MATHEMATICAL ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D439;MATHEMATICAL ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D43A;MATHEMATICAL ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D43B;MATHEMATICAL ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D43C;MATHEMATICAL ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D43D;MATHEMATICAL ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D43E;MATHEMATICAL ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D43F;MATHEMATICAL ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D440;MATHEMATICAL ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D441;MATHEMATICAL ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D442;MATHEMATICAL ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D443;MATHEMATICAL ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D444;MATHEMATICAL ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D445;MATHEMATICAL ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D446;MATHEMATICAL ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D447;MATHEMATICAL ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D448;MATHEMATICAL ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D449;MATHEMATICAL ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D44A;MATHEMATICAL ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D44B;MATHEMATICAL ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D44C;MATHEMATICAL ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D44D;MATHEMATICAL ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D44E;MATHEMATICAL ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D44F;MATHEMATICAL ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D450;MATHEMATICAL ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D451;MATHEMATICAL ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D452;MATHEMATICAL ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D453;MATHEMATICAL ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D454;MATHEMATICAL ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D456;MATHEMATICAL ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D457;MATHEMATICAL ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D458;MATHEMATICAL ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D459;MATHEMATICAL ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D45A;MATHEMATICAL ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D45B;MATHEMATICAL ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D45C;MATHEMATICAL ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D45D;MATHEMATICAL ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D45E;MATHEMATICAL ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D45F;MATHEMATICAL ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D460;MATHEMATICAL ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D461;MATHEMATICAL ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D462;MATHEMATICAL ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D463;MATHEMATICAL ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D464;MATHEMATICAL ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D465;MATHEMATICAL ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D466;MATHEMATICAL ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D467;MATHEMATICAL ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D468;MATHEMATICAL BOLD ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D469;MATHEMATICAL BOLD ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D46A;MATHEMATICAL BOLD ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D46B;MATHEMATICAL BOLD ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D46C;MATHEMATICAL BOLD ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D46D;MATHEMATICAL BOLD ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D46E;MATHEMATICAL BOLD ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D46F;MATHEMATICAL BOLD ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D470;MATHEMATICAL BOLD ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D471;MATHEMATICAL BOLD ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D472;MATHEMATICAL BOLD ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D473;MATHEMATICAL BOLD ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D474;MATHEMATICAL BOLD ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D475;MATHEMATICAL BOLD ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D476;MATHEMATICAL BOLD ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D477;MATHEMATICAL BOLD ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D478;MATHEMATICAL BOLD ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D479;MATHEMATICAL BOLD ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D47A;MATHEMATICAL BOLD ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D47B;MATHEMATICAL BOLD ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D47C;MATHEMATICAL BOLD ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D47D;MATHEMATICAL BOLD ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D47E;MATHEMATICAL BOLD ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D47F;MATHEMATICAL BOLD ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D480;MATHEMATICAL BOLD ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D481;MATHEMATICAL BOLD ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D482;MATHEMATICAL BOLD ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D483;MATHEMATICAL BOLD ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D484;MATHEMATICAL BOLD ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D485;MATHEMATICAL BOLD ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D486;MATHEMATICAL BOLD ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D487;MATHEMATICAL BOLD ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D488;MATHEMATICAL BOLD ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D489;MATHEMATICAL BOLD ITALIC SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D48A;MATHEMATICAL BOLD ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D48B;MATHEMATICAL BOLD ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D48C;MATHEMATICAL BOLD ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D48D;MATHEMATICAL BOLD ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D48E;MATHEMATICAL BOLD ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D48F;MATHEMATICAL BOLD ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D490;MATHEMATICAL BOLD ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D491;MATHEMATICAL BOLD ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D492;MATHEMATICAL BOLD ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D493;MATHEMATICAL BOLD ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D494;MATHEMATICAL BOLD ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D495;MATHEMATICAL BOLD ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D496;MATHEMATICAL BOLD ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D497;MATHEMATICAL BOLD ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D498;MATHEMATICAL BOLD ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D499;MATHEMATICAL BOLD ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D49A;MATHEMATICAL BOLD ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D49B;MATHEMATICAL BOLD ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D49C;MATHEMATICAL SCRIPT CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D49E;MATHEMATICAL SCRIPT CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D49F;MATHEMATICAL SCRIPT CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D4A2;MATHEMATICAL SCRIPT CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D4A5;MATHEMATICAL SCRIPT CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D4A6;MATHEMATICAL SCRIPT CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D4A9;MATHEMATICAL SCRIPT CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D4AA;MATHEMATICAL SCRIPT CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D4AB;MATHEMATICAL SCRIPT CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D4AC;MATHEMATICAL SCRIPT CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D4AE;MATHEMATICAL SCRIPT CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D4AF;MATHEMATICAL SCRIPT CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D4B0;MATHEMATICAL SCRIPT CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D4B1;MATHEMATICAL SCRIPT CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D4B2;MATHEMATICAL SCRIPT CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D4B3;MATHEMATICAL SCRIPT CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D4B4;MATHEMATICAL SCRIPT CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D4B5;MATHEMATICAL SCRIPT CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D4B6;MATHEMATICAL SCRIPT SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D4B7;MATHEMATICAL SCRIPT SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D4B8;MATHEMATICAL SCRIPT SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D4B9;MATHEMATICAL SCRIPT SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D4BB;MATHEMATICAL SCRIPT SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D4BD;MATHEMATICAL SCRIPT SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D4BE;MATHEMATICAL SCRIPT SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D4BF;MATHEMATICAL SCRIPT SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D4C0;MATHEMATICAL SCRIPT SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D4C1;MATHEMATICAL SCRIPT SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D4C2;MATHEMATICAL SCRIPT SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D4C3;MATHEMATICAL SCRIPT SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D4C5;MATHEMATICAL SCRIPT SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D4C6;MATHEMATICAL SCRIPT SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D4C7;MATHEMATICAL SCRIPT SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D4C8;MATHEMATICAL SCRIPT SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D4C9;MATHEMATICAL SCRIPT SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D4CA;MATHEMATICAL SCRIPT SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D4CB;MATHEMATICAL SCRIPT SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D4CC;MATHEMATICAL SCRIPT SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D4CD;MATHEMATICAL SCRIPT SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D4CE;MATHEMATICAL SCRIPT SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D4CF;MATHEMATICAL SCRIPT SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D4D0;MATHEMATICAL BOLD SCRIPT CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D4D1;MATHEMATICAL BOLD SCRIPT CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D4D2;MATHEMATICAL BOLD SCRIPT CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D4D3;MATHEMATICAL BOLD SCRIPT CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D4D4;MATHEMATICAL BOLD SCRIPT CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D4D5;MATHEMATICAL BOLD SCRIPT CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D4D6;MATHEMATICAL BOLD SCRIPT CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D4D7;MATHEMATICAL BOLD SCRIPT CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D4D8;MATHEMATICAL BOLD SCRIPT CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D4D9;MATHEMATICAL BOLD SCRIPT CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D4DA;MATHEMATICAL BOLD SCRIPT CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D4DB;MATHEMATICAL BOLD SCRIPT CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D4DC;MATHEMATICAL BOLD SCRIPT CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D4DD;MATHEMATICAL BOLD SCRIPT CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D4DE;MATHEMATICAL BOLD SCRIPT CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D4DF;MATHEMATICAL BOLD SCRIPT CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D4E0;MATHEMATICAL BOLD SCRIPT CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D4E1;MATHEMATICAL BOLD SCRIPT CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D4E2;MATHEMATICAL BOLD SCRIPT CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D4E3;MATHEMATICAL BOLD SCRIPT CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D4E4;MATHEMATICAL BOLD SCRIPT CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D4E5;MATHEMATICAL BOLD SCRIPT CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D4E6;MATHEMATICAL BOLD SCRIPT CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D4E7;MATHEMATICAL BOLD SCRIPT CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D4E8;MATHEMATICAL BOLD SCRIPT CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D4E9;MATHEMATICAL BOLD SCRIPT CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D4EA;MATHEMATICAL BOLD SCRIPT SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D4EB;MATHEMATICAL BOLD SCRIPT SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D4EC;MATHEMATICAL BOLD SCRIPT SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D4ED;MATHEMATICAL BOLD SCRIPT SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D4EE;MATHEMATICAL BOLD SCRIPT SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D4EF;MATHEMATICAL BOLD SCRIPT SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D4F0;MATHEMATICAL BOLD SCRIPT SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D4F1;MATHEMATICAL BOLD SCRIPT SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D4F2;MATHEMATICAL BOLD SCRIPT SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D4F3;MATHEMATICAL BOLD SCRIPT SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D4F4;MATHEMATICAL BOLD SCRIPT SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D4F5;MATHEMATICAL BOLD SCRIPT SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D4F6;MATHEMATICAL BOLD SCRIPT SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D4F7;MATHEMATICAL BOLD SCRIPT SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D4F8;MATHEMATICAL BOLD SCRIPT SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D4F9;MATHEMATICAL BOLD SCRIPT SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D4FA;MATHEMATICAL BOLD SCRIPT SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D4FB;MATHEMATICAL BOLD SCRIPT SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D4FC;MATHEMATICAL BOLD SCRIPT SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D4FD;MATHEMATICAL BOLD SCRIPT SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D4FE;MATHEMATICAL BOLD SCRIPT SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D4FF;MATHEMATICAL BOLD SCRIPT SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D500;MATHEMATICAL BOLD SCRIPT SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D501;MATHEMATICAL BOLD SCRIPT SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D502;MATHEMATICAL BOLD SCRIPT SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D503;MATHEMATICAL BOLD SCRIPT SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D504;MATHEMATICAL FRAKTUR CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D505;MATHEMATICAL FRAKTUR CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D507;MATHEMATICAL FRAKTUR CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D508;MATHEMATICAL FRAKTUR CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D509;MATHEMATICAL FRAKTUR CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D50A;MATHEMATICAL FRAKTUR CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D50D;MATHEMATICAL FRAKTUR CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D50E;MATHEMATICAL FRAKTUR CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D50F;MATHEMATICAL FRAKTUR CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D510;MATHEMATICAL FRAKTUR CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D511;MATHEMATICAL FRAKTUR CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D512;MATHEMATICAL FRAKTUR CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D513;MATHEMATICAL FRAKTUR CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D514;MATHEMATICAL FRAKTUR CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D516;MATHEMATICAL FRAKTUR CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D517;MATHEMATICAL FRAKTUR CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D518;MATHEMATICAL FRAKTUR CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D519;MATHEMATICAL FRAKTUR CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D51A;MATHEMATICAL FRAKTUR CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D51B;MATHEMATICAL FRAKTUR CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D51C;MATHEMATICAL FRAKTUR CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D51E;MATHEMATICAL FRAKTUR SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D51F;MATHEMATICAL FRAKTUR SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D520;MATHEMATICAL FRAKTUR SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D521;MATHEMATICAL FRAKTUR SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D522;MATHEMATICAL FRAKTUR SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D523;MATHEMATICAL FRAKTUR SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D524;MATHEMATICAL FRAKTUR SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D525;MATHEMATICAL FRAKTUR SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D526;MATHEMATICAL FRAKTUR SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D527;MATHEMATICAL FRAKTUR SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D528;MATHEMATICAL FRAKTUR SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D529;MATHEMATICAL FRAKTUR SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D52A;MATHEMATICAL FRAKTUR SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D52B;MATHEMATICAL FRAKTUR SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D52C;MATHEMATICAL FRAKTUR SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D52D;MATHEMATICAL FRAKTUR SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D52E;MATHEMATICAL FRAKTUR SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D52F;MATHEMATICAL FRAKTUR SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D530;MATHEMATICAL FRAKTUR SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D531;MATHEMATICAL FRAKTUR SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D532;MATHEMATICAL FRAKTUR SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D533;MATHEMATICAL FRAKTUR SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D534;MATHEMATICAL FRAKTUR SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D535;MATHEMATICAL FRAKTUR SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D536;MATHEMATICAL FRAKTUR SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D537;MATHEMATICAL FRAKTUR SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D538;MATHEMATICAL DOUBLE-STRUCK CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D539;MATHEMATICAL DOUBLE-STRUCK CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D53B;MATHEMATICAL DOUBLE-STRUCK CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D53C;MATHEMATICAL DOUBLE-STRUCK CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D53D;MATHEMATICAL DOUBLE-STRUCK CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D53E;MATHEMATICAL DOUBLE-STRUCK CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D540;MATHEMATICAL DOUBLE-STRUCK CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D541;MATHEMATICAL DOUBLE-STRUCK CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D542;MATHEMATICAL DOUBLE-STRUCK CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D543;MATHEMATICAL DOUBLE-STRUCK CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D544;MATHEMATICAL DOUBLE-STRUCK CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D546;MATHEMATICAL DOUBLE-STRUCK CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D54A;MATHEMATICAL DOUBLE-STRUCK CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D54B;MATHEMATICAL DOUBLE-STRUCK CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D54C;MATHEMATICAL DOUBLE-STRUCK CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D54D;MATHEMATICAL DOUBLE-STRUCK CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D54E;MATHEMATICAL DOUBLE-STRUCK CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D54F;MATHEMATICAL DOUBLE-STRUCK CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D550;MATHEMATICAL DOUBLE-STRUCK CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D552;MATHEMATICAL DOUBLE-STRUCK SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D553;MATHEMATICAL DOUBLE-STRUCK SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D554;MATHEMATICAL DOUBLE-STRUCK SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D555;MATHEMATICAL DOUBLE-STRUCK SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D556;MATHEMATICAL DOUBLE-STRUCK SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D557;MATHEMATICAL DOUBLE-STRUCK SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D558;MATHEMATICAL DOUBLE-STRUCK SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D559;MATHEMATICAL DOUBLE-STRUCK SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D55A;MATHEMATICAL DOUBLE-STRUCK SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D55B;MATHEMATICAL DOUBLE-STRUCK SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D55C;MATHEMATICAL DOUBLE-STRUCK SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D55D;MATHEMATICAL DOUBLE-STRUCK SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D55E;MATHEMATICAL DOUBLE-STRUCK SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D55F;MATHEMATICAL DOUBLE-STRUCK SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D560;MATHEMATICAL DOUBLE-STRUCK SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D561;MATHEMATICAL DOUBLE-STRUCK SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D562;MATHEMATICAL DOUBLE-STRUCK SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D563;MATHEMATICAL DOUBLE-STRUCK SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D564;MATHEMATICAL DOUBLE-STRUCK SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D565;MATHEMATICAL DOUBLE-STRUCK SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D566;MATHEMATICAL DOUBLE-STRUCK SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D567;MATHEMATICAL DOUBLE-STRUCK SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D568;MATHEMATICAL DOUBLE-STRUCK SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D569;MATHEMATICAL DOUBLE-STRUCK SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D56A;MATHEMATICAL DOUBLE-STRUCK SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D56B;MATHEMATICAL DOUBLE-STRUCK SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D56C;MATHEMATICAL BOLD FRAKTUR CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D56D;MATHEMATICAL BOLD FRAKTUR CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D56E;MATHEMATICAL BOLD FRAKTUR CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D56F;MATHEMATICAL BOLD FRAKTUR CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D570;MATHEMATICAL BOLD FRAKTUR CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D571;MATHEMATICAL BOLD FRAKTUR CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D572;MATHEMATICAL BOLD FRAKTUR CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D573;MATHEMATICAL BOLD FRAKTUR CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D574;MATHEMATICAL BOLD FRAKTUR CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D575;MATHEMATICAL BOLD FRAKTUR CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D576;MATHEMATICAL BOLD FRAKTUR CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D577;MATHEMATICAL BOLD FRAKTUR CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D578;MATHEMATICAL BOLD FRAKTUR CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D579;MATHEMATICAL BOLD FRAKTUR CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D57A;MATHEMATICAL BOLD FRAKTUR CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D57B;MATHEMATICAL BOLD FRAKTUR CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D57C;MATHEMATICAL BOLD FRAKTUR CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D57D;MATHEMATICAL BOLD FRAKTUR CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D57E;MATHEMATICAL BOLD FRAKTUR CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D57F;MATHEMATICAL BOLD FRAKTUR CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D580;MATHEMATICAL BOLD FRAKTUR CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D581;MATHEMATICAL BOLD FRAKTUR CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D582;MATHEMATICAL BOLD FRAKTUR CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D583;MATHEMATICAL BOLD FRAKTUR CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D584;MATHEMATICAL BOLD FRAKTUR CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D585;MATHEMATICAL BOLD FRAKTUR CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D586;MATHEMATICAL BOLD FRAKTUR SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D587;MATHEMATICAL BOLD FRAKTUR SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D588;MATHEMATICAL BOLD FRAKTUR SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D589;MATHEMATICAL BOLD FRAKTUR SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D58A;MATHEMATICAL BOLD FRAKTUR SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D58B;MATHEMATICAL BOLD FRAKTUR SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D58C;MATHEMATICAL BOLD FRAKTUR SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D58D;MATHEMATICAL BOLD FRAKTUR SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D58E;MATHEMATICAL BOLD FRAKTUR SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D58F;MATHEMATICAL BOLD FRAKTUR SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D590;MATHEMATICAL BOLD FRAKTUR SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D591;MATHEMATICAL BOLD FRAKTUR SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D592;MATHEMATICAL BOLD FRAKTUR SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D593;MATHEMATICAL BOLD FRAKTUR SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D594;MATHEMATICAL BOLD FRAKTUR SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D595;MATHEMATICAL BOLD FRAKTUR SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D596;MATHEMATICAL BOLD FRAKTUR SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D597;MATHEMATICAL BOLD FRAKTUR SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D598;MATHEMATICAL BOLD FRAKTUR SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D599;MATHEMATICAL BOLD FRAKTUR SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D59A;MATHEMATICAL BOLD FRAKTUR SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D59B;MATHEMATICAL BOLD FRAKTUR SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D59C;MATHEMATICAL BOLD FRAKTUR SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D59D;MATHEMATICAL BOLD FRAKTUR SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D59E;MATHEMATICAL BOLD FRAKTUR SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D59F;MATHEMATICAL BOLD FRAKTUR SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D5A0;MATHEMATICAL SANS-SERIF CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D5A1;MATHEMATICAL SANS-SERIF CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D5A2;MATHEMATICAL SANS-SERIF CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D5A3;MATHEMATICAL SANS-SERIF CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D5A4;MATHEMATICAL SANS-SERIF CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D5A5;MATHEMATICAL SANS-SERIF CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D5A6;MATHEMATICAL SANS-SERIF CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D5A7;MATHEMATICAL SANS-SERIF CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D5A8;MATHEMATICAL SANS-SERIF CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D5A9;MATHEMATICAL SANS-SERIF CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D5AA;MATHEMATICAL SANS-SERIF CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D5AB;MATHEMATICAL SANS-SERIF CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D5AC;MATHEMATICAL SANS-SERIF CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D5AD;MATHEMATICAL SANS-SERIF CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D5AE;MATHEMATICAL SANS-SERIF CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D5AF;MATHEMATICAL SANS-SERIF CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D5B0;MATHEMATICAL SANS-SERIF CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D5B1;MATHEMATICAL SANS-SERIF CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D5B2;MATHEMATICAL SANS-SERIF CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D5B3;MATHEMATICAL SANS-SERIF CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D5B4;MATHEMATICAL SANS-SERIF CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D5B5;MATHEMATICAL SANS-SERIF CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D5B6;MATHEMATICAL SANS-SERIF CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D5B7;MATHEMATICAL SANS-SERIF CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D5B8;MATHEMATICAL SANS-SERIF CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D5B9;MATHEMATICAL SANS-SERIF CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D5BA;MATHEMATICAL SANS-SERIF SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D5BB;MATHEMATICAL SANS-SERIF SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D5BC;MATHEMATICAL SANS-SERIF SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D5BD;MATHEMATICAL SANS-SERIF SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D5BE;MATHEMATICAL SANS-SERIF SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D5BF;MATHEMATICAL SANS-SERIF SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D5C0;MATHEMATICAL SANS-SERIF SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D5C1;MATHEMATICAL SANS-SERIF SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D5C2;MATHEMATICAL SANS-SERIF SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D5C3;MATHEMATICAL SANS-SERIF SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D5C4;MATHEMATICAL SANS-SERIF SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D5C5;MATHEMATICAL SANS-SERIF SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D5C6;MATHEMATICAL SANS-SERIF SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D5C7;MATHEMATICAL SANS-SERIF SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D5C8;MATHEMATICAL SANS-SERIF SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D5C9;MATHEMATICAL SANS-SERIF SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D5CA;MATHEMATICAL SANS-SERIF SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D5CB;MATHEMATICAL SANS-SERIF SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D5CC;MATHEMATICAL SANS-SERIF SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D5CD;MATHEMATICAL SANS-SERIF SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D5CE;MATHEMATICAL SANS-SERIF SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D5CF;MATHEMATICAL SANS-SERIF SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D5D0;MATHEMATICAL SANS-SERIF SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D5D1;MATHEMATICAL SANS-SERIF SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D5D2;MATHEMATICAL SANS-SERIF SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D5D3;MATHEMATICAL SANS-SERIF SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D5D4;MATHEMATICAL SANS-SERIF BOLD CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D5D5;MATHEMATICAL SANS-SERIF BOLD CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D5D6;MATHEMATICAL SANS-SERIF BOLD CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D5D7;MATHEMATICAL SANS-SERIF BOLD CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D5D8;MATHEMATICAL SANS-SERIF BOLD CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D5D9;MATHEMATICAL SANS-SERIF BOLD CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D5DA;MATHEMATICAL SANS-SERIF BOLD CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D5DB;MATHEMATICAL SANS-SERIF BOLD CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D5DC;MATHEMATICAL SANS-SERIF BOLD CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D5DD;MATHEMATICAL SANS-SERIF BOLD CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D5DE;MATHEMATICAL SANS-SERIF BOLD CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D5DF;MATHEMATICAL SANS-SERIF BOLD CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D5E0;MATHEMATICAL SANS-SERIF BOLD CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D5E1;MATHEMATICAL SANS-SERIF BOLD CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D5E2;MATHEMATICAL SANS-SERIF BOLD CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D5E3;MATHEMATICAL SANS-SERIF BOLD CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D5E4;MATHEMATICAL SANS-SERIF BOLD CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D5E5;MATHEMATICAL SANS-SERIF BOLD CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D5E6;MATHEMATICAL SANS-SERIF BOLD CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D5E7;MATHEMATICAL SANS-SERIF BOLD CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D5E8;MATHEMATICAL SANS-SERIF BOLD CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D5E9;MATHEMATICAL SANS-SERIF BOLD CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D5EA;MATHEMATICAL SANS-SERIF BOLD CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D5EB;MATHEMATICAL SANS-SERIF BOLD CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D5EC;MATHEMATICAL SANS-SERIF BOLD CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D5ED;MATHEMATICAL SANS-SERIF BOLD CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D5EE;MATHEMATICAL SANS-SERIF BOLD SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D5EF;MATHEMATICAL SANS-SERIF BOLD SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D5F0;MATHEMATICAL SANS-SERIF BOLD SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D5F1;MATHEMATICAL SANS-SERIF BOLD SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D5F2;MATHEMATICAL SANS-SERIF BOLD SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D5F3;MATHEMATICAL SANS-SERIF BOLD SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D5F4;MATHEMATICAL SANS-SERIF BOLD SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D5F5;MATHEMATICAL SANS-SERIF BOLD SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D5F6;MATHEMATICAL SANS-SERIF BOLD SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D5F7;MATHEMATICAL SANS-SERIF BOLD SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D5F8;MATHEMATICAL SANS-SERIF BOLD SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D5F9;MATHEMATICAL SANS-SERIF BOLD SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D5FA;MATHEMATICAL SANS-SERIF BOLD SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D5FB;MATHEMATICAL SANS-SERIF BOLD SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D5FC;MATHEMATICAL SANS-SERIF BOLD SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D5FD;MATHEMATICAL SANS-SERIF BOLD SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D5FE;MATHEMATICAL SANS-SERIF BOLD SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D5FF;MATHEMATICAL SANS-SERIF BOLD SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D600;MATHEMATICAL SANS-SERIF BOLD SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D601;MATHEMATICAL SANS-SERIF BOLD SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D602;MATHEMATICAL SANS-SERIF BOLD SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D603;MATHEMATICAL SANS-SERIF BOLD SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D604;MATHEMATICAL SANS-SERIF BOLD SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D605;MATHEMATICAL SANS-SERIF BOLD SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D606;MATHEMATICAL SANS-SERIF BOLD SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D607;MATHEMATICAL SANS-SERIF BOLD SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D608;MATHEMATICAL SANS-SERIF ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D609;MATHEMATICAL SANS-SERIF ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D60A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D60B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D60C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D60D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D60E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D60F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D610;MATHEMATICAL SANS-SERIF ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D611;MATHEMATICAL SANS-SERIF ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D612;MATHEMATICAL SANS-SERIF ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D613;MATHEMATICAL SANS-SERIF ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D614;MATHEMATICAL SANS-SERIF ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D615;MATHEMATICAL SANS-SERIF ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D616;MATHEMATICAL SANS-SERIF ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D617;MATHEMATICAL SANS-SERIF ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D618;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D619;MATHEMATICAL SANS-SERIF ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D61A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D61B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D61C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D61D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D61E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D61F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D620;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D621;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D622;MATHEMATICAL SANS-SERIF ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D623;MATHEMATICAL SANS-SERIF ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D624;MATHEMATICAL SANS-SERIF ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D625;MATHEMATICAL SANS-SERIF ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D626;MATHEMATICAL SANS-SERIF ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D627;MATHEMATICAL SANS-SERIF ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D628;MATHEMATICAL SANS-SERIF ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D629;MATHEMATICAL SANS-SERIF ITALIC SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D62A;MATHEMATICAL SANS-SERIF ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D62B;MATHEMATICAL SANS-SERIF ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D62C;MATHEMATICAL SANS-SERIF ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D62D;MATHEMATICAL SANS-SERIF ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D62E;MATHEMATICAL SANS-SERIF ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D62F;MATHEMATICAL SANS-SERIF ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D630;MATHEMATICAL SANS-SERIF ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D631;MATHEMATICAL SANS-SERIF ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D632;MATHEMATICAL SANS-SERIF ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D633;MATHEMATICAL SANS-SERIF ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D634;MATHEMATICAL SANS-SERIF ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D635;MATHEMATICAL SANS-SERIF ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D636;MATHEMATICAL SANS-SERIF ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D637;MATHEMATICAL SANS-SERIF ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D638;MATHEMATICAL SANS-SERIF ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D639;MATHEMATICAL SANS-SERIF ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D63A;MATHEMATICAL SANS-SERIF ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D63B;MATHEMATICAL SANS-SERIF ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D63C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D63D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D63E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D63F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D640;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D641;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D642;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D643;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D644;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D645;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D646;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D647;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D648;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D649;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D64A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D64B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D64C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D64D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D64E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D64F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D650;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D651;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D652;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D653;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D654;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D655;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D656;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D657;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D658;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D659;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D65A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D65B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D65C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D65D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D65E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D65F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D660;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D661;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D662;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D663;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D664;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D665;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D666;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D667;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D668;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D669;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D66A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D66B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D66C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D66D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D66E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D66F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D670;MATHEMATICAL MONOSPACE CAPITAL A;Lu;0;L; 0041;;;;N;;;;; +1D671;MATHEMATICAL MONOSPACE CAPITAL B;Lu;0;L; 0042;;;;N;;;;; +1D672;MATHEMATICAL MONOSPACE CAPITAL C;Lu;0;L; 0043;;;;N;;;;; +1D673;MATHEMATICAL MONOSPACE CAPITAL D;Lu;0;L; 0044;;;;N;;;;; +1D674;MATHEMATICAL MONOSPACE CAPITAL E;Lu;0;L; 0045;;;;N;;;;; +1D675;MATHEMATICAL MONOSPACE CAPITAL F;Lu;0;L; 0046;;;;N;;;;; +1D676;MATHEMATICAL MONOSPACE CAPITAL G;Lu;0;L; 0047;;;;N;;;;; +1D677;MATHEMATICAL MONOSPACE CAPITAL H;Lu;0;L; 0048;;;;N;;;;; +1D678;MATHEMATICAL MONOSPACE CAPITAL I;Lu;0;L; 0049;;;;N;;;;; +1D679;MATHEMATICAL MONOSPACE CAPITAL J;Lu;0;L; 004A;;;;N;;;;; +1D67A;MATHEMATICAL MONOSPACE CAPITAL K;Lu;0;L; 004B;;;;N;;;;; +1D67B;MATHEMATICAL MONOSPACE CAPITAL L;Lu;0;L; 004C;;;;N;;;;; +1D67C;MATHEMATICAL MONOSPACE CAPITAL M;Lu;0;L; 004D;;;;N;;;;; +1D67D;MATHEMATICAL MONOSPACE CAPITAL N;Lu;0;L; 004E;;;;N;;;;; +1D67E;MATHEMATICAL MONOSPACE CAPITAL O;Lu;0;L; 004F;;;;N;;;;; +1D67F;MATHEMATICAL MONOSPACE CAPITAL P;Lu;0;L; 0050;;;;N;;;;; +1D680;MATHEMATICAL MONOSPACE CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; +1D681;MATHEMATICAL MONOSPACE CAPITAL R;Lu;0;L; 0052;;;;N;;;;; +1D682;MATHEMATICAL MONOSPACE CAPITAL S;Lu;0;L; 0053;;;;N;;;;; +1D683;MATHEMATICAL MONOSPACE CAPITAL T;Lu;0;L; 0054;;;;N;;;;; +1D684;MATHEMATICAL MONOSPACE CAPITAL U;Lu;0;L; 0055;;;;N;;;;; +1D685;MATHEMATICAL MONOSPACE CAPITAL V;Lu;0;L; 0056;;;;N;;;;; +1D686;MATHEMATICAL MONOSPACE CAPITAL W;Lu;0;L; 0057;;;;N;;;;; +1D687;MATHEMATICAL MONOSPACE CAPITAL X;Lu;0;L; 0058;;;;N;;;;; +1D688;MATHEMATICAL MONOSPACE CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; +1D689;MATHEMATICAL MONOSPACE CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; +1D68A;MATHEMATICAL MONOSPACE SMALL A;Ll;0;L; 0061;;;;N;;;;; +1D68B;MATHEMATICAL MONOSPACE SMALL B;Ll;0;L; 0062;;;;N;;;;; +1D68C;MATHEMATICAL MONOSPACE SMALL C;Ll;0;L; 0063;;;;N;;;;; +1D68D;MATHEMATICAL MONOSPACE SMALL D;Ll;0;L; 0064;;;;N;;;;; +1D68E;MATHEMATICAL MONOSPACE SMALL E;Ll;0;L; 0065;;;;N;;;;; +1D68F;MATHEMATICAL MONOSPACE SMALL F;Ll;0;L; 0066;;;;N;;;;; +1D690;MATHEMATICAL MONOSPACE SMALL G;Ll;0;L; 0067;;;;N;;;;; +1D691;MATHEMATICAL MONOSPACE SMALL H;Ll;0;L; 0068;;;;N;;;;; +1D692;MATHEMATICAL MONOSPACE SMALL I;Ll;0;L; 0069;;;;N;;;;; +1D693;MATHEMATICAL MONOSPACE SMALL J;Ll;0;L; 006A;;;;N;;;;; +1D694;MATHEMATICAL MONOSPACE SMALL K;Ll;0;L; 006B;;;;N;;;;; +1D695;MATHEMATICAL MONOSPACE SMALL L;Ll;0;L; 006C;;;;N;;;;; +1D696;MATHEMATICAL MONOSPACE SMALL M;Ll;0;L; 006D;;;;N;;;;; +1D697;MATHEMATICAL MONOSPACE SMALL N;Ll;0;L; 006E;;;;N;;;;; +1D698;MATHEMATICAL MONOSPACE SMALL O;Ll;0;L; 006F;;;;N;;;;; +1D699;MATHEMATICAL MONOSPACE SMALL P;Ll;0;L; 0070;;;;N;;;;; +1D69A;MATHEMATICAL MONOSPACE SMALL Q;Ll;0;L; 0071;;;;N;;;;; +1D69B;MATHEMATICAL MONOSPACE SMALL R;Ll;0;L; 0072;;;;N;;;;; +1D69C;MATHEMATICAL MONOSPACE SMALL S;Ll;0;L; 0073;;;;N;;;;; +1D69D;MATHEMATICAL MONOSPACE SMALL T;Ll;0;L; 0074;;;;N;;;;; +1D69E;MATHEMATICAL MONOSPACE SMALL U;Ll;0;L; 0075;;;;N;;;;; +1D69F;MATHEMATICAL MONOSPACE SMALL V;Ll;0;L; 0076;;;;N;;;;; +1D6A0;MATHEMATICAL MONOSPACE SMALL W;Ll;0;L; 0077;;;;N;;;;; +1D6A1;MATHEMATICAL MONOSPACE SMALL X;Ll;0;L; 0078;;;;N;;;;; +1D6A2;MATHEMATICAL MONOSPACE SMALL Y;Ll;0;L; 0079;;;;N;;;;; +1D6A3;MATHEMATICAL MONOSPACE SMALL Z;Ll;0;L; 007A;;;;N;;;;; +1D6A4;MATHEMATICAL ITALIC SMALL DOTLESS I;Ll;0;L; 0131;;;;N;;;;; +1D6A5;MATHEMATICAL ITALIC SMALL DOTLESS J;Ll;0;L; 0237;;;;N;;;;; +1D6A8;MATHEMATICAL BOLD CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D6A9;MATHEMATICAL BOLD CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D6AA;MATHEMATICAL BOLD CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D6AB;MATHEMATICAL BOLD CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D6AC;MATHEMATICAL BOLD CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D6AD;MATHEMATICAL BOLD CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D6AE;MATHEMATICAL BOLD CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D6AF;MATHEMATICAL BOLD CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D6B0;MATHEMATICAL BOLD CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D6B1;MATHEMATICAL BOLD CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D6B2;MATHEMATICAL BOLD CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D6B3;MATHEMATICAL BOLD CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D6B4;MATHEMATICAL BOLD CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D6B5;MATHEMATICAL BOLD CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D6B6;MATHEMATICAL BOLD CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D6B7;MATHEMATICAL BOLD CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D6B8;MATHEMATICAL BOLD CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D6B9;MATHEMATICAL BOLD CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D6BA;MATHEMATICAL BOLD CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D6BB;MATHEMATICAL BOLD CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D6BC;MATHEMATICAL BOLD CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D6BD;MATHEMATICAL BOLD CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D6BE;MATHEMATICAL BOLD CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D6BF;MATHEMATICAL BOLD CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D6C0;MATHEMATICAL BOLD CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D6C1;MATHEMATICAL BOLD NABLA;Sm;0;L; 2207;;;;N;;;;; +1D6C2;MATHEMATICAL BOLD SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D6C3;MATHEMATICAL BOLD SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D6C4;MATHEMATICAL BOLD SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D6C5;MATHEMATICAL BOLD SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D6C6;MATHEMATICAL BOLD SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D6C7;MATHEMATICAL BOLD SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D6C8;MATHEMATICAL BOLD SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D6C9;MATHEMATICAL BOLD SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D6CA;MATHEMATICAL BOLD SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D6CB;MATHEMATICAL BOLD SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D6CC;MATHEMATICAL BOLD SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D6CD;MATHEMATICAL BOLD SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D6CE;MATHEMATICAL BOLD SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D6CF;MATHEMATICAL BOLD SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D6D0;MATHEMATICAL BOLD SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D6D1;MATHEMATICAL BOLD SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D6D2;MATHEMATICAL BOLD SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D6D3;MATHEMATICAL BOLD SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D6D4;MATHEMATICAL BOLD SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D6D5;MATHEMATICAL BOLD SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D6D6;MATHEMATICAL BOLD SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D6D7;MATHEMATICAL BOLD SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D6D8;MATHEMATICAL BOLD SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D6D9;MATHEMATICAL BOLD SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D6DA;MATHEMATICAL BOLD SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D6DB;MATHEMATICAL BOLD PARTIAL DIFFERENTIAL;Sm;0;ON; 2202;;;;Y;;;;; +1D6DC;MATHEMATICAL BOLD EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D6DD;MATHEMATICAL BOLD THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D6DE;MATHEMATICAL BOLD KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D6DF;MATHEMATICAL BOLD PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D6E0;MATHEMATICAL BOLD RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D6E1;MATHEMATICAL BOLD PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D6E2;MATHEMATICAL ITALIC CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D6E3;MATHEMATICAL ITALIC CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D6E4;MATHEMATICAL ITALIC CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D6E5;MATHEMATICAL ITALIC CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D6E6;MATHEMATICAL ITALIC CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D6E7;MATHEMATICAL ITALIC CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D6E8;MATHEMATICAL ITALIC CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D6E9;MATHEMATICAL ITALIC CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D6EA;MATHEMATICAL ITALIC CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D6EB;MATHEMATICAL ITALIC CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D6EC;MATHEMATICAL ITALIC CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D6ED;MATHEMATICAL ITALIC CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D6EE;MATHEMATICAL ITALIC CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D6EF;MATHEMATICAL ITALIC CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D6F0;MATHEMATICAL ITALIC CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D6F1;MATHEMATICAL ITALIC CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D6F2;MATHEMATICAL ITALIC CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D6F3;MATHEMATICAL ITALIC CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D6F4;MATHEMATICAL ITALIC CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D6F5;MATHEMATICAL ITALIC CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D6F6;MATHEMATICAL ITALIC CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D6F7;MATHEMATICAL ITALIC CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D6F8;MATHEMATICAL ITALIC CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D6F9;MATHEMATICAL ITALIC CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D6FA;MATHEMATICAL ITALIC CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D6FB;MATHEMATICAL ITALIC NABLA;Sm;0;L; 2207;;;;N;;;;; +1D6FC;MATHEMATICAL ITALIC SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D6FD;MATHEMATICAL ITALIC SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D6FE;MATHEMATICAL ITALIC SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D6FF;MATHEMATICAL ITALIC SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D700;MATHEMATICAL ITALIC SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D701;MATHEMATICAL ITALIC SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D702;MATHEMATICAL ITALIC SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D703;MATHEMATICAL ITALIC SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D704;MATHEMATICAL ITALIC SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D705;MATHEMATICAL ITALIC SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D706;MATHEMATICAL ITALIC SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D707;MATHEMATICAL ITALIC SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D708;MATHEMATICAL ITALIC SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D709;MATHEMATICAL ITALIC SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D70A;MATHEMATICAL ITALIC SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D70B;MATHEMATICAL ITALIC SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D70C;MATHEMATICAL ITALIC SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D70D;MATHEMATICAL ITALIC SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D70E;MATHEMATICAL ITALIC SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D70F;MATHEMATICAL ITALIC SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D710;MATHEMATICAL ITALIC SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D711;MATHEMATICAL ITALIC SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D712;MATHEMATICAL ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D713;MATHEMATICAL ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D714;MATHEMATICAL ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D715;MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON; 2202;;;;Y;;;;; +1D716;MATHEMATICAL ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D717;MATHEMATICAL ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D718;MATHEMATICAL ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D719;MATHEMATICAL ITALIC PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D71A;MATHEMATICAL ITALIC RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D71B;MATHEMATICAL ITALIC PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D71C;MATHEMATICAL BOLD ITALIC CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D71D;MATHEMATICAL BOLD ITALIC CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D71E;MATHEMATICAL BOLD ITALIC CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D71F;MATHEMATICAL BOLD ITALIC CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D720;MATHEMATICAL BOLD ITALIC CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D721;MATHEMATICAL BOLD ITALIC CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D722;MATHEMATICAL BOLD ITALIC CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D723;MATHEMATICAL BOLD ITALIC CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D724;MATHEMATICAL BOLD ITALIC CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D725;MATHEMATICAL BOLD ITALIC CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D726;MATHEMATICAL BOLD ITALIC CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D727;MATHEMATICAL BOLD ITALIC CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D728;MATHEMATICAL BOLD ITALIC CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D729;MATHEMATICAL BOLD ITALIC CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D72A;MATHEMATICAL BOLD ITALIC CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D72B;MATHEMATICAL BOLD ITALIC CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D72C;MATHEMATICAL BOLD ITALIC CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D72D;MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D72E;MATHEMATICAL BOLD ITALIC CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D72F;MATHEMATICAL BOLD ITALIC CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D730;MATHEMATICAL BOLD ITALIC CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D731;MATHEMATICAL BOLD ITALIC CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D732;MATHEMATICAL BOLD ITALIC CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D733;MATHEMATICAL BOLD ITALIC CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D734;MATHEMATICAL BOLD ITALIC CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D735;MATHEMATICAL BOLD ITALIC NABLA;Sm;0;L; 2207;;;;N;;;;; +1D736;MATHEMATICAL BOLD ITALIC SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D737;MATHEMATICAL BOLD ITALIC SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D738;MATHEMATICAL BOLD ITALIC SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D739;MATHEMATICAL BOLD ITALIC SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D73A;MATHEMATICAL BOLD ITALIC SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D73B;MATHEMATICAL BOLD ITALIC SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D73C;MATHEMATICAL BOLD ITALIC SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D73D;MATHEMATICAL BOLD ITALIC SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D73E;MATHEMATICAL BOLD ITALIC SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D73F;MATHEMATICAL BOLD ITALIC SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D740;MATHEMATICAL BOLD ITALIC SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D741;MATHEMATICAL BOLD ITALIC SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D742;MATHEMATICAL BOLD ITALIC SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D743;MATHEMATICAL BOLD ITALIC SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D744;MATHEMATICAL BOLD ITALIC SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D745;MATHEMATICAL BOLD ITALIC SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D746;MATHEMATICAL BOLD ITALIC SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D747;MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D748;MATHEMATICAL BOLD ITALIC SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D749;MATHEMATICAL BOLD ITALIC SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D74A;MATHEMATICAL BOLD ITALIC SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D74B;MATHEMATICAL BOLD ITALIC SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D74C;MATHEMATICAL BOLD ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D74D;MATHEMATICAL BOLD ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D74E;MATHEMATICAL BOLD ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D74F;MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON; 2202;;;;Y;;;;; +1D750;MATHEMATICAL BOLD ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D751;MATHEMATICAL BOLD ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D752;MATHEMATICAL BOLD ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D753;MATHEMATICAL BOLD ITALIC PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D754;MATHEMATICAL BOLD ITALIC RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D755;MATHEMATICAL BOLD ITALIC PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D756;MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D757;MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D758;MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D759;MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D75A;MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D75B;MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D75C;MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D75D;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D75E;MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D75F;MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D760;MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D761;MATHEMATICAL SANS-SERIF BOLD CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D762;MATHEMATICAL SANS-SERIF BOLD CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D763;MATHEMATICAL SANS-SERIF BOLD CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D764;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D765;MATHEMATICAL SANS-SERIF BOLD CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D766;MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D767;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D768;MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D769;MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D76A;MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D76B;MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D76C;MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D76D;MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D76E;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D76F;MATHEMATICAL SANS-SERIF BOLD NABLA;Sm;0;L; 2207;;;;N;;;;; +1D770;MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D771;MATHEMATICAL SANS-SERIF BOLD SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D772;MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D773;MATHEMATICAL SANS-SERIF BOLD SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D774;MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D775;MATHEMATICAL SANS-SERIF BOLD SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D776;MATHEMATICAL SANS-SERIF BOLD SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D777;MATHEMATICAL SANS-SERIF BOLD SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D778;MATHEMATICAL SANS-SERIF BOLD SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D779;MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D77A;MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D77B;MATHEMATICAL SANS-SERIF BOLD SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D77C;MATHEMATICAL SANS-SERIF BOLD SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D77D;MATHEMATICAL SANS-SERIF BOLD SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D77E;MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D77F;MATHEMATICAL SANS-SERIF BOLD SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D780;MATHEMATICAL SANS-SERIF BOLD SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D781;MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D782;MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D783;MATHEMATICAL SANS-SERIF BOLD SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D784;MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D785;MATHEMATICAL SANS-SERIF BOLD SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D786;MATHEMATICAL SANS-SERIF BOLD SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D787;MATHEMATICAL SANS-SERIF BOLD SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D788;MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D789;MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL;Sm;0;ON; 2202;;;;Y;;;;; +1D78A;MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D78B;MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D78C;MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D78D;MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D78E;MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D78F;MATHEMATICAL SANS-SERIF BOLD PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D790;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; +1D791;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; +1D792;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; +1D793;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; +1D794;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; +1D795;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; +1D796;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; +1D797;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; +1D798;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; +1D799;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; +1D79A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; +1D79B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; +1D79C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; +1D79D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; +1D79E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; +1D79F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; +1D7A0;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; +1D7A1;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; +1D7A2;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; +1D7A3;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; +1D7A4;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; +1D7A5;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; +1D7A6;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; +1D7A7;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; +1D7A8;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; +1D7A9;MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA;Sm;0;L; 2207;;;;N;;;;; +1D7AA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; +1D7AB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; +1D7AC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; +1D7AD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; +1D7AE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; +1D7AF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; +1D7B0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; +1D7B1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; +1D7B2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; +1D7B3;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; +1D7B4;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; +1D7B5;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU;Ll;0;L; 03BC;;;;N;;;;; +1D7B6;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU;Ll;0;L; 03BD;;;;N;;;;; +1D7B7;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI;Ll;0;L; 03BE;;;;N;;;;; +1D7B8;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; +1D7B9;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI;Ll;0;L; 03C0;;;;N;;;;; +1D7BA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; +1D7BB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; +1D7BC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; +1D7BD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; +1D7BE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; +1D7BF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; +1D7C0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; +1D7C1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; +1D7C2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; +1D7C3;MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON; 2202;;;;Y;;;;; +1D7C4;MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; +1D7C5;MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; +1D7C6;MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; +1D7C7;MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; +1D7C8;MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; +1D7C9;MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; +1D7CA;MATHEMATICAL BOLD CAPITAL DIGAMMA;Lu;0;L; 03DC;;;;N;;;;; +1D7CB;MATHEMATICAL BOLD SMALL DIGAMMA;Ll;0;L; 03DD;;;;N;;;;; +1D7CE;MATHEMATICAL BOLD DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7CF;MATHEMATICAL BOLD DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7D0;MATHEMATICAL BOLD DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7D1;MATHEMATICAL BOLD DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7D2;MATHEMATICAL BOLD DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7D3;MATHEMATICAL BOLD DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7D4;MATHEMATICAL BOLD DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7D5;MATHEMATICAL BOLD DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7D6;MATHEMATICAL BOLD DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7D7;MATHEMATICAL BOLD DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1D7D8;MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7D9;MATHEMATICAL DOUBLE-STRUCK DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7DA;MATHEMATICAL DOUBLE-STRUCK DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7DB;MATHEMATICAL DOUBLE-STRUCK DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7DC;MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7DD;MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7DE;MATHEMATICAL DOUBLE-STRUCK DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7DF;MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7E0;MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7E1;MATHEMATICAL DOUBLE-STRUCK DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1D7E2;MATHEMATICAL SANS-SERIF DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7E3;MATHEMATICAL SANS-SERIF DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7E4;MATHEMATICAL SANS-SERIF DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7E5;MATHEMATICAL SANS-SERIF DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7E6;MATHEMATICAL SANS-SERIF DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7E7;MATHEMATICAL SANS-SERIF DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7E8;MATHEMATICAL SANS-SERIF DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7E9;MATHEMATICAL SANS-SERIF DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7EA;MATHEMATICAL SANS-SERIF DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7EB;MATHEMATICAL SANS-SERIF DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1D7EC;MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7ED;MATHEMATICAL SANS-SERIF BOLD DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7EE;MATHEMATICAL SANS-SERIF BOLD DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7EF;MATHEMATICAL SANS-SERIF BOLD DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7F0;MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7F1;MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7F2;MATHEMATICAL SANS-SERIF BOLD DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7F3;MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7F4;MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7F5;MATHEMATICAL SANS-SERIF BOLD DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1D7F6;MATHEMATICAL MONOSPACE DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1D7F7;MATHEMATICAL MONOSPACE DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1D7F8;MATHEMATICAL MONOSPACE DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1D7F9;MATHEMATICAL MONOSPACE DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1D7FA;MATHEMATICAL MONOSPACE DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1D7FB;MATHEMATICAL MONOSPACE DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1D7FC;MATHEMATICAL MONOSPACE DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1D7FD;MATHEMATICAL MONOSPACE DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1D7FE;MATHEMATICAL MONOSPACE DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1D7FF;MATHEMATICAL MONOSPACE DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; +1D800;SIGNWRITING HAND-FIST INDEX;So;0;L;;;;;N;;;;; +1D801;SIGNWRITING HAND-CIRCLE INDEX;So;0;L;;;;;N;;;;; +1D802;SIGNWRITING HAND-CUP INDEX;So;0;L;;;;;N;;;;; +1D803;SIGNWRITING HAND-OVAL INDEX;So;0;L;;;;;N;;;;; +1D804;SIGNWRITING HAND-HINGE INDEX;So;0;L;;;;;N;;;;; +1D805;SIGNWRITING HAND-ANGLE INDEX;So;0;L;;;;;N;;;;; +1D806;SIGNWRITING HAND-FIST INDEX BENT;So;0;L;;;;;N;;;;; +1D807;SIGNWRITING HAND-CIRCLE INDEX BENT;So;0;L;;;;;N;;;;; +1D808;SIGNWRITING HAND-FIST THUMB UNDER INDEX BENT;So;0;L;;;;;N;;;;; +1D809;SIGNWRITING HAND-FIST INDEX RAISED KNUCKLE;So;0;L;;;;;N;;;;; +1D80A;SIGNWRITING HAND-FIST INDEX CUPPED;So;0;L;;;;;N;;;;; +1D80B;SIGNWRITING HAND-FIST INDEX HINGED;So;0;L;;;;;N;;;;; +1D80C;SIGNWRITING HAND-FIST INDEX HINGED LOW;So;0;L;;;;;N;;;;; +1D80D;SIGNWRITING HAND-CIRCLE INDEX HINGE;So;0;L;;;;;N;;;;; +1D80E;SIGNWRITING HAND-FIST INDEX MIDDLE;So;0;L;;;;;N;;;;; +1D80F;SIGNWRITING HAND-CIRCLE INDEX MIDDLE;So;0;L;;;;;N;;;;; +1D810;SIGNWRITING HAND-FIST INDEX MIDDLE BENT;So;0;L;;;;;N;;;;; +1D811;SIGNWRITING HAND-FIST INDEX MIDDLE RAISED KNUCKLES;So;0;L;;;;;N;;;;; +1D812;SIGNWRITING HAND-FIST INDEX MIDDLE HINGED;So;0;L;;;;;N;;;;; +1D813;SIGNWRITING HAND-FIST INDEX UP MIDDLE HINGED;So;0;L;;;;;N;;;;; +1D814;SIGNWRITING HAND-FIST INDEX HINGED MIDDLE UP;So;0;L;;;;;N;;;;; +1D815;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED;So;0;L;;;;;N;;;;; +1D816;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED INDEX BENT;So;0;L;;;;;N;;;;; +1D817;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED MIDDLE BENT;So;0;L;;;;;N;;;;; +1D818;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED CUPPED;So;0;L;;;;;N;;;;; +1D819;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED HINGED;So;0;L;;;;;N;;;;; +1D81A;SIGNWRITING HAND-FIST INDEX MIDDLE CROSSED;So;0;L;;;;;N;;;;; +1D81B;SIGNWRITING HAND-CIRCLE INDEX MIDDLE CROSSED;So;0;L;;;;;N;;;;; +1D81C;SIGNWRITING HAND-FIST MIDDLE BENT OVER INDEX;So;0;L;;;;;N;;;;; +1D81D;SIGNWRITING HAND-FIST INDEX BENT OVER MIDDLE;So;0;L;;;;;N;;;;; +1D81E;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB;So;0;L;;;;;N;;;;; +1D81F;SIGNWRITING HAND-CIRCLE INDEX MIDDLE THUMB;So;0;L;;;;;N;;;;; +1D820;SIGNWRITING HAND-FIST INDEX MIDDLE STRAIGHT THUMB BENT;So;0;L;;;;;N;;;;; +1D821;SIGNWRITING HAND-FIST INDEX MIDDLE BENT THUMB STRAIGHT;So;0;L;;;;;N;;;;; +1D822;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB BENT;So;0;L;;;;;N;;;;; +1D823;SIGNWRITING HAND-FIST INDEX MIDDLE HINGED SPREAD THUMB SIDE;So;0;L;;;;;N;;;;; +1D824;SIGNWRITING HAND-FIST INDEX UP MIDDLE HINGED THUMB SIDE;So;0;L;;;;;N;;;;; +1D825;SIGNWRITING HAND-FIST INDEX UP MIDDLE HINGED THUMB CONJOINED;So;0;L;;;;;N;;;;; +1D826;SIGNWRITING HAND-FIST INDEX HINGED MIDDLE UP THUMB SIDE;So;0;L;;;;;N;;;;; +1D827;SIGNWRITING HAND-FIST INDEX MIDDLE UP SPREAD THUMB FORWARD;So;0;L;;;;;N;;;;; +1D828;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB CUPPED;So;0;L;;;;;N;;;;; +1D829;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB CIRCLED;So;0;L;;;;;N;;;;; +1D82A;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB HOOKED;So;0;L;;;;;N;;;;; +1D82B;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB HINGED;So;0;L;;;;;N;;;;; +1D82C;SIGNWRITING HAND-FIST THUMB BETWEEN INDEX MIDDLE STRAIGHT;So;0;L;;;;;N;;;;; +1D82D;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED THUMB SIDE;So;0;L;;;;;N;;;;; +1D82E;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED THUMB SIDE CONJOINED;So;0;L;;;;;N;;;;; +1D82F;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED THUMB SIDE BENT;So;0;L;;;;;N;;;;; +1D830;SIGNWRITING HAND-FIST MIDDLE THUMB HOOKED INDEX UP;So;0;L;;;;;N;;;;; +1D831;SIGNWRITING HAND-FIST INDEX THUMB HOOKED MIDDLE UP;So;0;L;;;;;N;;;;; +1D832;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED HINGED THUMB SIDE;So;0;L;;;;;N;;;;; +1D833;SIGNWRITING HAND-FIST INDEX MIDDLE CROSSED THUMB SIDE;So;0;L;;;;;N;;;;; +1D834;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED THUMB FORWARD;So;0;L;;;;;N;;;;; +1D835;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED CUPPED THUMB FORWARD;So;0;L;;;;;N;;;;; +1D836;SIGNWRITING HAND-FIST MIDDLE THUMB CUPPED INDEX UP;So;0;L;;;;;N;;;;; +1D837;SIGNWRITING HAND-FIST INDEX THUMB CUPPED MIDDLE UP;So;0;L;;;;;N;;;;; +1D838;SIGNWRITING HAND-FIST MIDDLE THUMB CIRCLED INDEX UP;So;0;L;;;;;N;;;;; +1D839;SIGNWRITING HAND-FIST MIDDLE THUMB CIRCLED INDEX HINGED;So;0;L;;;;;N;;;;; +1D83A;SIGNWRITING HAND-FIST INDEX THUMB ANGLED OUT MIDDLE UP;So;0;L;;;;;N;;;;; +1D83B;SIGNWRITING HAND-FIST INDEX THUMB ANGLED IN MIDDLE UP;So;0;L;;;;;N;;;;; +1D83C;SIGNWRITING HAND-FIST INDEX THUMB CIRCLED MIDDLE UP;So;0;L;;;;;N;;;;; +1D83D;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB CONJOINED HINGED;So;0;L;;;;;N;;;;; +1D83E;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB ANGLED OUT;So;0;L;;;;;N;;;;; +1D83F;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB ANGLED;So;0;L;;;;;N;;;;; +1D840;SIGNWRITING HAND-FIST MIDDLE THUMB ANGLED OUT INDEX UP;So;0;L;;;;;N;;;;; +1D841;SIGNWRITING HAND-FIST MIDDLE THUMB ANGLED OUT INDEX CROSSED;So;0;L;;;;;N;;;;; +1D842;SIGNWRITING HAND-FIST MIDDLE THUMB ANGLED INDEX UP;So;0;L;;;;;N;;;;; +1D843;SIGNWRITING HAND-FIST INDEX THUMB HOOKED MIDDLE HINGED;So;0;L;;;;;N;;;;; +1D844;SIGNWRITING HAND-FLAT FOUR FINGERS;So;0;L;;;;;N;;;;; +1D845;SIGNWRITING HAND-FLAT FOUR FINGERS BENT;So;0;L;;;;;N;;;;; +1D846;SIGNWRITING HAND-FLAT FOUR FINGERS HINGED;So;0;L;;;;;N;;;;; +1D847;SIGNWRITING HAND-FLAT FOUR FINGERS CONJOINED;So;0;L;;;;;N;;;;; +1D848;SIGNWRITING HAND-FLAT FOUR FINGERS CONJOINED SPLIT;So;0;L;;;;;N;;;;; +1D849;SIGNWRITING HAND-CLAW FOUR FINGERS CONJOINED;So;0;L;;;;;N;;;;; +1D84A;SIGNWRITING HAND-FIST FOUR FINGERS CONJOINED BENT;So;0;L;;;;;N;;;;; +1D84B;SIGNWRITING HAND-HINGE FOUR FINGERS CONJOINED;So;0;L;;;;;N;;;;; +1D84C;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD;So;0;L;;;;;N;;;;; +1D84D;SIGNWRITING HAND-FLAT HEEL FIVE FINGERS SPREAD;So;0;L;;;;;N;;;;; +1D84E;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD FOUR BENT;So;0;L;;;;;N;;;;; +1D84F;SIGNWRITING HAND-FLAT HEEL FIVE FINGERS SPREAD FOUR BENT;So;0;L;;;;;N;;;;; +1D850;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD BENT;So;0;L;;;;;N;;;;; +1D851;SIGNWRITING HAND-FLAT HEEL FIVE FINGERS SPREAD BENT;So;0;L;;;;;N;;;;; +1D852;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD THUMB FORWARD;So;0;L;;;;;N;;;;; +1D853;SIGNWRITING HAND-CUP FIVE FINGERS SPREAD;So;0;L;;;;;N;;;;; +1D854;SIGNWRITING HAND-CUP FIVE FINGERS SPREAD OPEN;So;0;L;;;;;N;;;;; +1D855;SIGNWRITING HAND-HINGE FIVE FINGERS SPREAD OPEN;So;0;L;;;;;N;;;;; +1D856;SIGNWRITING HAND-OVAL FIVE FINGERS SPREAD;So;0;L;;;;;N;;;;; +1D857;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD HINGED;So;0;L;;;;;N;;;;; +1D858;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD HINGED THUMB SIDE;So;0;L;;;;;N;;;;; +1D859;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD HINGED NO THUMB;So;0;L;;;;;N;;;;; +1D85A;SIGNWRITING HAND-FLAT;So;0;L;;;;;N;;;;; +1D85B;SIGNWRITING HAND-FLAT BETWEEN PALM FACINGS;So;0;L;;;;;N;;;;; +1D85C;SIGNWRITING HAND-FLAT HEEL;So;0;L;;;;;N;;;;; +1D85D;SIGNWRITING HAND-FLAT THUMB SIDE;So;0;L;;;;;N;;;;; +1D85E;SIGNWRITING HAND-FLAT HEEL THUMB SIDE;So;0;L;;;;;N;;;;; +1D85F;SIGNWRITING HAND-FLAT THUMB BENT;So;0;L;;;;;N;;;;; +1D860;SIGNWRITING HAND-FLAT THUMB FORWARD;So;0;L;;;;;N;;;;; +1D861;SIGNWRITING HAND-FLAT SPLIT INDEX THUMB SIDE;So;0;L;;;;;N;;;;; +1D862;SIGNWRITING HAND-FLAT SPLIT CENTRE;So;0;L;;;;;N;;;;; +1D863;SIGNWRITING HAND-FLAT SPLIT CENTRE THUMB SIDE;So;0;L;;;;;N;;;;; +1D864;SIGNWRITING HAND-FLAT SPLIT CENTRE THUMB SIDE BENT;So;0;L;;;;;N;;;;; +1D865;SIGNWRITING HAND-FLAT SPLIT LITTLE;So;0;L;;;;;N;;;;; +1D866;SIGNWRITING HAND-CLAW;So;0;L;;;;;N;;;;; +1D867;SIGNWRITING HAND-CLAW THUMB SIDE;So;0;L;;;;;N;;;;; +1D868;SIGNWRITING HAND-CLAW NO THUMB;So;0;L;;;;;N;;;;; +1D869;SIGNWRITING HAND-CLAW THUMB FORWARD;So;0;L;;;;;N;;;;; +1D86A;SIGNWRITING HAND-HOOK CURLICUE;So;0;L;;;;;N;;;;; +1D86B;SIGNWRITING HAND-HOOK;So;0;L;;;;;N;;;;; +1D86C;SIGNWRITING HAND-CUP OPEN;So;0;L;;;;;N;;;;; +1D86D;SIGNWRITING HAND-CUP;So;0;L;;;;;N;;;;; +1D86E;SIGNWRITING HAND-CUP OPEN THUMB SIDE;So;0;L;;;;;N;;;;; +1D86F;SIGNWRITING HAND-CUP THUMB SIDE;So;0;L;;;;;N;;;;; +1D870;SIGNWRITING HAND-CUP OPEN NO THUMB;So;0;L;;;;;N;;;;; +1D871;SIGNWRITING HAND-CUP NO THUMB;So;0;L;;;;;N;;;;; +1D872;SIGNWRITING HAND-CUP OPEN THUMB FORWARD;So;0;L;;;;;N;;;;; +1D873;SIGNWRITING HAND-CUP THUMB FORWARD;So;0;L;;;;;N;;;;; +1D874;SIGNWRITING HAND-CURLICUE OPEN;So;0;L;;;;;N;;;;; +1D875;SIGNWRITING HAND-CURLICUE;So;0;L;;;;;N;;;;; +1D876;SIGNWRITING HAND-CIRCLE;So;0;L;;;;;N;;;;; +1D877;SIGNWRITING HAND-OVAL;So;0;L;;;;;N;;;;; +1D878;SIGNWRITING HAND-OVAL THUMB SIDE;So;0;L;;;;;N;;;;; +1D879;SIGNWRITING HAND-OVAL NO THUMB;So;0;L;;;;;N;;;;; +1D87A;SIGNWRITING HAND-OVAL THUMB FORWARD;So;0;L;;;;;N;;;;; +1D87B;SIGNWRITING HAND-HINGE OPEN;So;0;L;;;;;N;;;;; +1D87C;SIGNWRITING HAND-HINGE OPEN THUMB FORWARD;So;0;L;;;;;N;;;;; +1D87D;SIGNWRITING HAND-HINGE;So;0;L;;;;;N;;;;; +1D87E;SIGNWRITING HAND-HINGE SMALL;So;0;L;;;;;N;;;;; +1D87F;SIGNWRITING HAND-HINGE OPEN THUMB SIDE;So;0;L;;;;;N;;;;; +1D880;SIGNWRITING HAND-HINGE THUMB SIDE;So;0;L;;;;;N;;;;; +1D881;SIGNWRITING HAND-HINGE OPEN NO THUMB;So;0;L;;;;;N;;;;; +1D882;SIGNWRITING HAND-HINGE NO THUMB;So;0;L;;;;;N;;;;; +1D883;SIGNWRITING HAND-HINGE THUMB SIDE TOUCHING INDEX;So;0;L;;;;;N;;;;; +1D884;SIGNWRITING HAND-HINGE THUMB BETWEEN MIDDLE RING;So;0;L;;;;;N;;;;; +1D885;SIGNWRITING HAND-ANGLE;So;0;L;;;;;N;;;;; +1D886;SIGNWRITING HAND-FIST INDEX MIDDLE RING;So;0;L;;;;;N;;;;; +1D887;SIGNWRITING HAND-CIRCLE INDEX MIDDLE RING;So;0;L;;;;;N;;;;; +1D888;SIGNWRITING HAND-HINGE INDEX MIDDLE RING;So;0;L;;;;;N;;;;; +1D889;SIGNWRITING HAND-ANGLE INDEX MIDDLE RING;So;0;L;;;;;N;;;;; +1D88A;SIGNWRITING HAND-HINGE LITTLE;So;0;L;;;;;N;;;;; +1D88B;SIGNWRITING HAND-FIST INDEX MIDDLE RING BENT;So;0;L;;;;;N;;;;; +1D88C;SIGNWRITING HAND-FIST INDEX MIDDLE RING CONJOINED;So;0;L;;;;;N;;;;; +1D88D;SIGNWRITING HAND-HINGE INDEX MIDDLE RING CONJOINED;So;0;L;;;;;N;;;;; +1D88E;SIGNWRITING HAND-FIST LITTLE DOWN;So;0;L;;;;;N;;;;; +1D88F;SIGNWRITING HAND-FIST LITTLE DOWN RIPPLE STRAIGHT;So;0;L;;;;;N;;;;; +1D890;SIGNWRITING HAND-FIST LITTLE DOWN RIPPLE CURVED;So;0;L;;;;;N;;;;; +1D891;SIGNWRITING HAND-FIST LITTLE DOWN OTHERS CIRCLED;So;0;L;;;;;N;;;;; +1D892;SIGNWRITING HAND-FIST LITTLE UP;So;0;L;;;;;N;;;;; +1D893;SIGNWRITING HAND-FIST THUMB UNDER LITTLE UP;So;0;L;;;;;N;;;;; +1D894;SIGNWRITING HAND-CIRCLE LITTLE UP;So;0;L;;;;;N;;;;; +1D895;SIGNWRITING HAND-OVAL LITTLE UP;So;0;L;;;;;N;;;;; +1D896;SIGNWRITING HAND-ANGLE LITTLE UP;So;0;L;;;;;N;;;;; +1D897;SIGNWRITING HAND-FIST LITTLE RAISED KNUCKLE;So;0;L;;;;;N;;;;; +1D898;SIGNWRITING HAND-FIST LITTLE BENT;So;0;L;;;;;N;;;;; +1D899;SIGNWRITING HAND-FIST LITTLE TOUCHES THUMB;So;0;L;;;;;N;;;;; +1D89A;SIGNWRITING HAND-FIST LITTLE THUMB;So;0;L;;;;;N;;;;; +1D89B;SIGNWRITING HAND-HINGE LITTLE THUMB;So;0;L;;;;;N;;;;; +1D89C;SIGNWRITING HAND-FIST LITTLE INDEX THUMB;So;0;L;;;;;N;;;;; +1D89D;SIGNWRITING HAND-HINGE LITTLE INDEX THUMB;So;0;L;;;;;N;;;;; +1D89E;SIGNWRITING HAND-ANGLE LITTLE INDEX THUMB INDEX THUMB OUT;So;0;L;;;;;N;;;;; +1D89F;SIGNWRITING HAND-ANGLE LITTLE INDEX THUMB INDEX THUMB;So;0;L;;;;;N;;;;; +1D8A0;SIGNWRITING HAND-FIST LITTLE INDEX;So;0;L;;;;;N;;;;; +1D8A1;SIGNWRITING HAND-CIRCLE LITTLE INDEX;So;0;L;;;;;N;;;;; +1D8A2;SIGNWRITING HAND-HINGE LITTLE INDEX;So;0;L;;;;;N;;;;; +1D8A3;SIGNWRITING HAND-ANGLE LITTLE INDEX;So;0;L;;;;;N;;;;; +1D8A4;SIGNWRITING HAND-FIST INDEX MIDDLE LITTLE;So;0;L;;;;;N;;;;; +1D8A5;SIGNWRITING HAND-CIRCLE INDEX MIDDLE LITTLE;So;0;L;;;;;N;;;;; +1D8A6;SIGNWRITING HAND-HINGE INDEX MIDDLE LITTLE;So;0;L;;;;;N;;;;; +1D8A7;SIGNWRITING HAND-HINGE RING;So;0;L;;;;;N;;;;; +1D8A8;SIGNWRITING HAND-ANGLE INDEX MIDDLE LITTLE;So;0;L;;;;;N;;;;; +1D8A9;SIGNWRITING HAND-FIST INDEX MIDDLE CROSS LITTLE;So;0;L;;;;;N;;;;; +1D8AA;SIGNWRITING HAND-CIRCLE INDEX MIDDLE CROSS LITTLE;So;0;L;;;;;N;;;;; +1D8AB;SIGNWRITING HAND-FIST RING DOWN;So;0;L;;;;;N;;;;; +1D8AC;SIGNWRITING HAND-HINGE RING DOWN INDEX THUMB HOOK MIDDLE;So;0;L;;;;;N;;;;; +1D8AD;SIGNWRITING HAND-ANGLE RING DOWN MIDDLE THUMB INDEX CROSS;So;0;L;;;;;N;;;;; +1D8AE;SIGNWRITING HAND-FIST RING UP;So;0;L;;;;;N;;;;; +1D8AF;SIGNWRITING HAND-FIST RING RAISED KNUCKLE;So;0;L;;;;;N;;;;; +1D8B0;SIGNWRITING HAND-FIST RING LITTLE;So;0;L;;;;;N;;;;; +1D8B1;SIGNWRITING HAND-CIRCLE RING LITTLE;So;0;L;;;;;N;;;;; +1D8B2;SIGNWRITING HAND-OVAL RING LITTLE;So;0;L;;;;;N;;;;; +1D8B3;SIGNWRITING HAND-ANGLE RING LITTLE;So;0;L;;;;;N;;;;; +1D8B4;SIGNWRITING HAND-FIST RING MIDDLE;So;0;L;;;;;N;;;;; +1D8B5;SIGNWRITING HAND-FIST RING MIDDLE CONJOINED;So;0;L;;;;;N;;;;; +1D8B6;SIGNWRITING HAND-FIST RING MIDDLE RAISED KNUCKLES;So;0;L;;;;;N;;;;; +1D8B7;SIGNWRITING HAND-FIST RING INDEX;So;0;L;;;;;N;;;;; +1D8B8;SIGNWRITING HAND-FIST RING THUMB;So;0;L;;;;;N;;;;; +1D8B9;SIGNWRITING HAND-HOOK RING THUMB;So;0;L;;;;;N;;;;; +1D8BA;SIGNWRITING HAND-FIST INDEX RING LITTLE;So;0;L;;;;;N;;;;; +1D8BB;SIGNWRITING HAND-CIRCLE INDEX RING LITTLE;So;0;L;;;;;N;;;;; +1D8BC;SIGNWRITING HAND-CURLICUE INDEX RING LITTLE ON;So;0;L;;;;;N;;;;; +1D8BD;SIGNWRITING HAND-HOOK INDEX RING LITTLE OUT;So;0;L;;;;;N;;;;; +1D8BE;SIGNWRITING HAND-HOOK INDEX RING LITTLE IN;So;0;L;;;;;N;;;;; +1D8BF;SIGNWRITING HAND-HOOK INDEX RING LITTLE UNDER;So;0;L;;;;;N;;;;; +1D8C0;SIGNWRITING HAND-CUP INDEX RING LITTLE;So;0;L;;;;;N;;;;; +1D8C1;SIGNWRITING HAND-HINGE INDEX RING LITTLE;So;0;L;;;;;N;;;;; +1D8C2;SIGNWRITING HAND-ANGLE INDEX RING LITTLE OUT;So;0;L;;;;;N;;;;; +1D8C3;SIGNWRITING HAND-ANGLE INDEX RING LITTLE;So;0;L;;;;;N;;;;; +1D8C4;SIGNWRITING HAND-FIST MIDDLE DOWN;So;0;L;;;;;N;;;;; +1D8C5;SIGNWRITING HAND-HINGE MIDDLE;So;0;L;;;;;N;;;;; +1D8C6;SIGNWRITING HAND-FIST MIDDLE UP;So;0;L;;;;;N;;;;; +1D8C7;SIGNWRITING HAND-CIRCLE MIDDLE UP;So;0;L;;;;;N;;;;; +1D8C8;SIGNWRITING HAND-FIST MIDDLE RAISED KNUCKLE;So;0;L;;;;;N;;;;; +1D8C9;SIGNWRITING HAND-FIST MIDDLE UP THUMB SIDE;So;0;L;;;;;N;;;;; +1D8CA;SIGNWRITING HAND-HOOK MIDDLE THUMB;So;0;L;;;;;N;;;;; +1D8CB;SIGNWRITING HAND-FIST MIDDLE THUMB LITTLE;So;0;L;;;;;N;;;;; +1D8CC;SIGNWRITING HAND-FIST MIDDLE LITTLE;So;0;L;;;;;N;;;;; +1D8CD;SIGNWRITING HAND-FIST MIDDLE RING LITTLE;So;0;L;;;;;N;;;;; +1D8CE;SIGNWRITING HAND-CIRCLE MIDDLE RING LITTLE;So;0;L;;;;;N;;;;; +1D8CF;SIGNWRITING HAND-CURLICUE MIDDLE RING LITTLE ON;So;0;L;;;;;N;;;;; +1D8D0;SIGNWRITING HAND-CUP MIDDLE RING LITTLE;So;0;L;;;;;N;;;;; +1D8D1;SIGNWRITING HAND-HINGE MIDDLE RING LITTLE;So;0;L;;;;;N;;;;; +1D8D2;SIGNWRITING HAND-ANGLE MIDDLE RING LITTLE OUT;So;0;L;;;;;N;;;;; +1D8D3;SIGNWRITING HAND-ANGLE MIDDLE RING LITTLE IN;So;0;L;;;;;N;;;;; +1D8D4;SIGNWRITING HAND-ANGLE MIDDLE RING LITTLE;So;0;L;;;;;N;;;;; +1D8D5;SIGNWRITING HAND-CIRCLE MIDDLE RING LITTLE BENT;So;0;L;;;;;N;;;;; +1D8D6;SIGNWRITING HAND-CLAW MIDDLE RING LITTLE CONJOINED;So;0;L;;;;;N;;;;; +1D8D7;SIGNWRITING HAND-CLAW MIDDLE RING LITTLE CONJOINED SIDE;So;0;L;;;;;N;;;;; +1D8D8;SIGNWRITING HAND-HOOK MIDDLE RING LITTLE CONJOINED OUT;So;0;L;;;;;N;;;;; +1D8D9;SIGNWRITING HAND-HOOK MIDDLE RING LITTLE CONJOINED IN;So;0;L;;;;;N;;;;; +1D8DA;SIGNWRITING HAND-HOOK MIDDLE RING LITTLE CONJOINED;So;0;L;;;;;N;;;;; +1D8DB;SIGNWRITING HAND-HINGE INDEX HINGED;So;0;L;;;;;N;;;;; +1D8DC;SIGNWRITING HAND-FIST INDEX THUMB SIDE;So;0;L;;;;;N;;;;; +1D8DD;SIGNWRITING HAND-HINGE INDEX THUMB SIDE;So;0;L;;;;;N;;;;; +1D8DE;SIGNWRITING HAND-FIST INDEX THUMB SIDE THUMB DIAGONAL;So;0;L;;;;;N;;;;; +1D8DF;SIGNWRITING HAND-FIST INDEX THUMB SIDE THUMB CONJOINED;So;0;L;;;;;N;;;;; +1D8E0;SIGNWRITING HAND-FIST INDEX THUMB SIDE THUMB BENT;So;0;L;;;;;N;;;;; +1D8E1;SIGNWRITING HAND-FIST INDEX THUMB SIDE INDEX BENT;So;0;L;;;;;N;;;;; +1D8E2;SIGNWRITING HAND-FIST INDEX THUMB SIDE BOTH BENT;So;0;L;;;;;N;;;;; +1D8E3;SIGNWRITING HAND-FIST INDEX THUMB SIDE INDEX HINGE;So;0;L;;;;;N;;;;; +1D8E4;SIGNWRITING HAND-FIST INDEX THUMB FORWARD INDEX STRAIGHT;So;0;L;;;;;N;;;;; +1D8E5;SIGNWRITING HAND-FIST INDEX THUMB FORWARD INDEX BENT;So;0;L;;;;;N;;;;; +1D8E6;SIGNWRITING HAND-FIST INDEX THUMB HOOK;So;0;L;;;;;N;;;;; +1D8E7;SIGNWRITING HAND-FIST INDEX THUMB CURLICUE;So;0;L;;;;;N;;;;; +1D8E8;SIGNWRITING HAND-FIST INDEX THUMB CURVE THUMB INSIDE;So;0;L;;;;;N;;;;; +1D8E9;SIGNWRITING HAND-CLAW INDEX THUMB CURVE THUMB INSIDE;So;0;L;;;;;N;;;;; +1D8EA;SIGNWRITING HAND-FIST INDEX THUMB CURVE THUMB UNDER;So;0;L;;;;;N;;;;; +1D8EB;SIGNWRITING HAND-FIST INDEX THUMB CIRCLE;So;0;L;;;;;N;;;;; +1D8EC;SIGNWRITING HAND-CUP INDEX THUMB;So;0;L;;;;;N;;;;; +1D8ED;SIGNWRITING HAND-CUP INDEX THUMB OPEN;So;0;L;;;;;N;;;;; +1D8EE;SIGNWRITING HAND-HINGE INDEX THUMB OPEN;So;0;L;;;;;N;;;;; +1D8EF;SIGNWRITING HAND-HINGE INDEX THUMB LARGE;So;0;L;;;;;N;;;;; +1D8F0;SIGNWRITING HAND-HINGE INDEX THUMB;So;0;L;;;;;N;;;;; +1D8F1;SIGNWRITING HAND-HINGE INDEX THUMB SMALL;So;0;L;;;;;N;;;;; +1D8F2;SIGNWRITING HAND-ANGLE INDEX THUMB OUT;So;0;L;;;;;N;;;;; +1D8F3;SIGNWRITING HAND-ANGLE INDEX THUMB IN;So;0;L;;;;;N;;;;; +1D8F4;SIGNWRITING HAND-ANGLE INDEX THUMB;So;0;L;;;;;N;;;;; +1D8F5;SIGNWRITING HAND-FIST THUMB;So;0;L;;;;;N;;;;; +1D8F6;SIGNWRITING HAND-FIST THUMB HEEL;So;0;L;;;;;N;;;;; +1D8F7;SIGNWRITING HAND-FIST THUMB SIDE DIAGONAL;So;0;L;;;;;N;;;;; +1D8F8;SIGNWRITING HAND-FIST THUMB SIDE CONJOINED;So;0;L;;;;;N;;;;; +1D8F9;SIGNWRITING HAND-FIST THUMB SIDE BENT;So;0;L;;;;;N;;;;; +1D8FA;SIGNWRITING HAND-FIST THUMB FORWARD;So;0;L;;;;;N;;;;; +1D8FB;SIGNWRITING HAND-FIST THUMB BETWEEN INDEX MIDDLE;So;0;L;;;;;N;;;;; +1D8FC;SIGNWRITING HAND-FIST THUMB BETWEEN MIDDLE RING;So;0;L;;;;;N;;;;; +1D8FD;SIGNWRITING HAND-FIST THUMB BETWEEN RING LITTLE;So;0;L;;;;;N;;;;; +1D8FE;SIGNWRITING HAND-FIST THUMB UNDER TWO FINGERS;So;0;L;;;;;N;;;;; +1D8FF;SIGNWRITING HAND-FIST THUMB OVER TWO FINGERS;So;0;L;;;;;N;;;;; +1D900;SIGNWRITING HAND-FIST THUMB UNDER THREE FINGERS;So;0;L;;;;;N;;;;; +1D901;SIGNWRITING HAND-FIST THUMB UNDER FOUR FINGERS;So;0;L;;;;;N;;;;; +1D902;SIGNWRITING HAND-FIST THUMB OVER FOUR RAISED KNUCKLES;So;0;L;;;;;N;;;;; +1D903;SIGNWRITING HAND-FIST;So;0;L;;;;;N;;;;; +1D904;SIGNWRITING HAND-FIST HEEL;So;0;L;;;;;N;;;;; +1D905;SIGNWRITING TOUCH SINGLE;So;0;L;;;;;N;;;;; +1D906;SIGNWRITING TOUCH MULTIPLE;So;0;L;;;;;N;;;;; +1D907;SIGNWRITING TOUCH BETWEEN;So;0;L;;;;;N;;;;; +1D908;SIGNWRITING GRASP SINGLE;So;0;L;;;;;N;;;;; +1D909;SIGNWRITING GRASP MULTIPLE;So;0;L;;;;;N;;;;; +1D90A;SIGNWRITING GRASP BETWEEN;So;0;L;;;;;N;;;;; +1D90B;SIGNWRITING STRIKE SINGLE;So;0;L;;;;;N;;;;; +1D90C;SIGNWRITING STRIKE MULTIPLE;So;0;L;;;;;N;;;;; +1D90D;SIGNWRITING STRIKE BETWEEN;So;0;L;;;;;N;;;;; +1D90E;SIGNWRITING BRUSH SINGLE;So;0;L;;;;;N;;;;; +1D90F;SIGNWRITING BRUSH MULTIPLE;So;0;L;;;;;N;;;;; +1D910;SIGNWRITING BRUSH BETWEEN;So;0;L;;;;;N;;;;; +1D911;SIGNWRITING RUB SINGLE;So;0;L;;;;;N;;;;; +1D912;SIGNWRITING RUB MULTIPLE;So;0;L;;;;;N;;;;; +1D913;SIGNWRITING RUB BETWEEN;So;0;L;;;;;N;;;;; +1D914;SIGNWRITING SURFACE SYMBOLS;So;0;L;;;;;N;;;;; +1D915;SIGNWRITING SURFACE BETWEEN;So;0;L;;;;;N;;;;; +1D916;SIGNWRITING SQUEEZE LARGE SINGLE;So;0;L;;;;;N;;;;; +1D917;SIGNWRITING SQUEEZE SMALL SINGLE;So;0;L;;;;;N;;;;; +1D918;SIGNWRITING SQUEEZE LARGE MULTIPLE;So;0;L;;;;;N;;;;; +1D919;SIGNWRITING SQUEEZE SMALL MULTIPLE;So;0;L;;;;;N;;;;; +1D91A;SIGNWRITING SQUEEZE SEQUENTIAL;So;0;L;;;;;N;;;;; +1D91B;SIGNWRITING FLICK LARGE SINGLE;So;0;L;;;;;N;;;;; +1D91C;SIGNWRITING FLICK SMALL SINGLE;So;0;L;;;;;N;;;;; +1D91D;SIGNWRITING FLICK LARGE MULTIPLE;So;0;L;;;;;N;;;;; +1D91E;SIGNWRITING FLICK SMALL MULTIPLE;So;0;L;;;;;N;;;;; +1D91F;SIGNWRITING FLICK SEQUENTIAL;So;0;L;;;;;N;;;;; +1D920;SIGNWRITING SQUEEZE FLICK ALTERNATING;So;0;L;;;;;N;;;;; +1D921;SIGNWRITING MOVEMENT-HINGE UP DOWN LARGE;So;0;L;;;;;N;;;;; +1D922;SIGNWRITING MOVEMENT-HINGE UP DOWN SMALL;So;0;L;;;;;N;;;;; +1D923;SIGNWRITING MOVEMENT-HINGE UP SEQUENTIAL;So;0;L;;;;;N;;;;; +1D924;SIGNWRITING MOVEMENT-HINGE DOWN SEQUENTIAL;So;0;L;;;;;N;;;;; +1D925;SIGNWRITING MOVEMENT-HINGE UP DOWN ALTERNATING LARGE;So;0;L;;;;;N;;;;; +1D926;SIGNWRITING MOVEMENT-HINGE UP DOWN ALTERNATING SMALL;So;0;L;;;;;N;;;;; +1D927;SIGNWRITING MOVEMENT-HINGE SIDE TO SIDE SCISSORS;So;0;L;;;;;N;;;;; +1D928;SIGNWRITING MOVEMENT-WALLPLANE FINGER CONTACT;So;0;L;;;;;N;;;;; +1D929;SIGNWRITING MOVEMENT-FLOORPLANE FINGER CONTACT;So;0;L;;;;;N;;;;; +1D92A;SIGNWRITING MOVEMENT-WALLPLANE SINGLE STRAIGHT SMALL;So;0;L;;;;;N;;;;; +1D92B;SIGNWRITING MOVEMENT-WALLPLANE SINGLE STRAIGHT MEDIUM;So;0;L;;;;;N;;;;; +1D92C;SIGNWRITING MOVEMENT-WALLPLANE SINGLE STRAIGHT LARGE;So;0;L;;;;;N;;;;; +1D92D;SIGNWRITING MOVEMENT-WALLPLANE SINGLE STRAIGHT LARGEST;So;0;L;;;;;N;;;;; +1D92E;SIGNWRITING MOVEMENT-WALLPLANE SINGLE WRIST FLEX;So;0;L;;;;;N;;;;; +1D92F;SIGNWRITING MOVEMENT-WALLPLANE DOUBLE STRAIGHT;So;0;L;;;;;N;;;;; +1D930;SIGNWRITING MOVEMENT-WALLPLANE DOUBLE WRIST FLEX;So;0;L;;;;;N;;;;; +1D931;SIGNWRITING MOVEMENT-WALLPLANE DOUBLE ALTERNATING;So;0;L;;;;;N;;;;; +1D932;SIGNWRITING MOVEMENT-WALLPLANE DOUBLE ALTERNATING WRIST FLEX;So;0;L;;;;;N;;;;; +1D933;SIGNWRITING MOVEMENT-WALLPLANE CROSS;So;0;L;;;;;N;;;;; +1D934;SIGNWRITING MOVEMENT-WALLPLANE TRIPLE STRAIGHT MOVEMENT;So;0;L;;;;;N;;;;; +1D935;SIGNWRITING MOVEMENT-WALLPLANE TRIPLE WRIST FLEX;So;0;L;;;;;N;;;;; +1D936;SIGNWRITING MOVEMENT-WALLPLANE TRIPLE ALTERNATING;So;0;L;;;;;N;;;;; +1D937;SIGNWRITING MOVEMENT-WALLPLANE TRIPLE ALTERNATING WRIST FLEX;So;0;L;;;;;N;;;;; +1D938;SIGNWRITING MOVEMENT-WALLPLANE BEND SMALL;So;0;L;;;;;N;;;;; +1D939;SIGNWRITING MOVEMENT-WALLPLANE BEND MEDIUM;So;0;L;;;;;N;;;;; +1D93A;SIGNWRITING MOVEMENT-WALLPLANE BEND LARGE;So;0;L;;;;;N;;;;; +1D93B;SIGNWRITING MOVEMENT-WALLPLANE CORNER SMALL;So;0;L;;;;;N;;;;; +1D93C;SIGNWRITING MOVEMENT-WALLPLANE CORNER MEDIUM;So;0;L;;;;;N;;;;; +1D93D;SIGNWRITING MOVEMENT-WALLPLANE CORNER LARGE;So;0;L;;;;;N;;;;; +1D93E;SIGNWRITING MOVEMENT-WALLPLANE CORNER ROTATION;So;0;L;;;;;N;;;;; +1D93F;SIGNWRITING MOVEMENT-WALLPLANE CHECK SMALL;So;0;L;;;;;N;;;;; +1D940;SIGNWRITING MOVEMENT-WALLPLANE CHECK MEDIUM;So;0;L;;;;;N;;;;; +1D941;SIGNWRITING MOVEMENT-WALLPLANE CHECK LARGE;So;0;L;;;;;N;;;;; +1D942;SIGNWRITING MOVEMENT-WALLPLANE BOX SMALL;So;0;L;;;;;N;;;;; +1D943;SIGNWRITING MOVEMENT-WALLPLANE BOX MEDIUM;So;0;L;;;;;N;;;;; +1D944;SIGNWRITING MOVEMENT-WALLPLANE BOX LARGE;So;0;L;;;;;N;;;;; +1D945;SIGNWRITING MOVEMENT-WALLPLANE ZIGZAG SMALL;So;0;L;;;;;N;;;;; +1D946;SIGNWRITING MOVEMENT-WALLPLANE ZIGZAG MEDIUM;So;0;L;;;;;N;;;;; +1D947;SIGNWRITING MOVEMENT-WALLPLANE ZIGZAG LARGE;So;0;L;;;;;N;;;;; +1D948;SIGNWRITING MOVEMENT-WALLPLANE PEAKS SMALL;So;0;L;;;;;N;;;;; +1D949;SIGNWRITING MOVEMENT-WALLPLANE PEAKS MEDIUM;So;0;L;;;;;N;;;;; +1D94A;SIGNWRITING MOVEMENT-WALLPLANE PEAKS LARGE;So;0;L;;;;;N;;;;; +1D94B;SIGNWRITING TRAVEL-WALLPLANE ROTATION-WALLPLANE SINGLE;So;0;L;;;;;N;;;;; +1D94C;SIGNWRITING TRAVEL-WALLPLANE ROTATION-WALLPLANE DOUBLE;So;0;L;;;;;N;;;;; +1D94D;SIGNWRITING TRAVEL-WALLPLANE ROTATION-WALLPLANE ALTERNATING;So;0;L;;;;;N;;;;; +1D94E;SIGNWRITING TRAVEL-WALLPLANE ROTATION-FLOORPLANE SINGLE;So;0;L;;;;;N;;;;; +1D94F;SIGNWRITING TRAVEL-WALLPLANE ROTATION-FLOORPLANE DOUBLE;So;0;L;;;;;N;;;;; +1D950;SIGNWRITING TRAVEL-WALLPLANE ROTATION-FLOORPLANE ALTERNATING;So;0;L;;;;;N;;;;; +1D951;SIGNWRITING TRAVEL-WALLPLANE SHAKING;So;0;L;;;;;N;;;;; +1D952;SIGNWRITING TRAVEL-WALLPLANE ARM SPIRAL SINGLE;So;0;L;;;;;N;;;;; +1D953;SIGNWRITING TRAVEL-WALLPLANE ARM SPIRAL DOUBLE;So;0;L;;;;;N;;;;; +1D954;SIGNWRITING TRAVEL-WALLPLANE ARM SPIRAL TRIPLE;So;0;L;;;;;N;;;;; +1D955;SIGNWRITING MOVEMENT-DIAGONAL AWAY SMALL;So;0;L;;;;;N;;;;; +1D956;SIGNWRITING MOVEMENT-DIAGONAL AWAY MEDIUM;So;0;L;;;;;N;;;;; +1D957;SIGNWRITING MOVEMENT-DIAGONAL AWAY LARGE;So;0;L;;;;;N;;;;; +1D958;SIGNWRITING MOVEMENT-DIAGONAL AWAY LARGEST;So;0;L;;;;;N;;;;; +1D959;SIGNWRITING MOVEMENT-DIAGONAL TOWARDS SMALL;So;0;L;;;;;N;;;;; +1D95A;SIGNWRITING MOVEMENT-DIAGONAL TOWARDS MEDIUM;So;0;L;;;;;N;;;;; +1D95B;SIGNWRITING MOVEMENT-DIAGONAL TOWARDS LARGE;So;0;L;;;;;N;;;;; +1D95C;SIGNWRITING MOVEMENT-DIAGONAL TOWARDS LARGEST;So;0;L;;;;;N;;;;; +1D95D;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN AWAY SMALL;So;0;L;;;;;N;;;;; +1D95E;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN AWAY MEDIUM;So;0;L;;;;;N;;;;; +1D95F;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN AWAY LARGE;So;0;L;;;;;N;;;;; +1D960;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN AWAY LARGEST;So;0;L;;;;;N;;;;; +1D961;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN TOWARDS SMALL;So;0;L;;;;;N;;;;; +1D962;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN TOWARDS MEDIUM;So;0;L;;;;;N;;;;; +1D963;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN TOWARDS LARGE;So;0;L;;;;;N;;;;; +1D964;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN TOWARDS LARGEST;So;0;L;;;;;N;;;;; +1D965;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE STRAIGHT SMALL;So;0;L;;;;;N;;;;; +1D966;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE STRAIGHT MEDIUM;So;0;L;;;;;N;;;;; +1D967;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE STRAIGHT LARGE;So;0;L;;;;;N;;;;; +1D968;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE STRAIGHT LARGEST;So;0;L;;;;;N;;;;; +1D969;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE WRIST FLEX;So;0;L;;;;;N;;;;; +1D96A;SIGNWRITING MOVEMENT-FLOORPLANE DOUBLE STRAIGHT;So;0;L;;;;;N;;;;; +1D96B;SIGNWRITING MOVEMENT-FLOORPLANE DOUBLE WRIST FLEX;So;0;L;;;;;N;;;;; +1D96C;SIGNWRITING MOVEMENT-FLOORPLANE DOUBLE ALTERNATING;So;0;L;;;;;N;;;;; +1D96D;SIGNWRITING MOVEMENT-FLOORPLANE DOUBLE ALTERNATING WRIST FLEX;So;0;L;;;;;N;;;;; +1D96E;SIGNWRITING MOVEMENT-FLOORPLANE CROSS;So;0;L;;;;;N;;;;; +1D96F;SIGNWRITING MOVEMENT-FLOORPLANE TRIPLE STRAIGHT MOVEMENT;So;0;L;;;;;N;;;;; +1D970;SIGNWRITING MOVEMENT-FLOORPLANE TRIPLE WRIST FLEX;So;0;L;;;;;N;;;;; +1D971;SIGNWRITING MOVEMENT-FLOORPLANE TRIPLE ALTERNATING MOVEMENT;So;0;L;;;;;N;;;;; +1D972;SIGNWRITING MOVEMENT-FLOORPLANE TRIPLE ALTERNATING WRIST FLEX;So;0;L;;;;;N;;;;; +1D973;SIGNWRITING MOVEMENT-FLOORPLANE BEND;So;0;L;;;;;N;;;;; +1D974;SIGNWRITING MOVEMENT-FLOORPLANE CORNER SMALL;So;0;L;;;;;N;;;;; +1D975;SIGNWRITING MOVEMENT-FLOORPLANE CORNER MEDIUM;So;0;L;;;;;N;;;;; +1D976;SIGNWRITING MOVEMENT-FLOORPLANE CORNER LARGE;So;0;L;;;;;N;;;;; +1D977;SIGNWRITING MOVEMENT-FLOORPLANE CHECK;So;0;L;;;;;N;;;;; +1D978;SIGNWRITING MOVEMENT-FLOORPLANE BOX SMALL;So;0;L;;;;;N;;;;; +1D979;SIGNWRITING MOVEMENT-FLOORPLANE BOX MEDIUM;So;0;L;;;;;N;;;;; +1D97A;SIGNWRITING MOVEMENT-FLOORPLANE BOX LARGE;So;0;L;;;;;N;;;;; +1D97B;SIGNWRITING MOVEMENT-FLOORPLANE ZIGZAG SMALL;So;0;L;;;;;N;;;;; +1D97C;SIGNWRITING MOVEMENT-FLOORPLANE ZIGZAG MEDIUM;So;0;L;;;;;N;;;;; +1D97D;SIGNWRITING MOVEMENT-FLOORPLANE ZIGZAG LARGE;So;0;L;;;;;N;;;;; +1D97E;SIGNWRITING MOVEMENT-FLOORPLANE PEAKS SMALL;So;0;L;;;;;N;;;;; +1D97F;SIGNWRITING MOVEMENT-FLOORPLANE PEAKS MEDIUM;So;0;L;;;;;N;;;;; +1D980;SIGNWRITING MOVEMENT-FLOORPLANE PEAKS LARGE;So;0;L;;;;;N;;;;; +1D981;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-FLOORPLANE SINGLE;So;0;L;;;;;N;;;;; +1D982;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-FLOORPLANE DOUBLE;So;0;L;;;;;N;;;;; +1D983;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-FLOORPLANE ALTERNATING;So;0;L;;;;;N;;;;; +1D984;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-WALLPLANE SINGLE;So;0;L;;;;;N;;;;; +1D985;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-WALLPLANE DOUBLE;So;0;L;;;;;N;;;;; +1D986;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-WALLPLANE ALTERNATING;So;0;L;;;;;N;;;;; +1D987;SIGNWRITING TRAVEL-FLOORPLANE SHAKING;So;0;L;;;;;N;;;;; +1D988;SIGNWRITING MOVEMENT-WALLPLANE CURVE QUARTER SMALL;So;0;L;;;;;N;;;;; +1D989;SIGNWRITING MOVEMENT-WALLPLANE CURVE QUARTER MEDIUM;So;0;L;;;;;N;;;;; +1D98A;SIGNWRITING MOVEMENT-WALLPLANE CURVE QUARTER LARGE;So;0;L;;;;;N;;;;; +1D98B;SIGNWRITING MOVEMENT-WALLPLANE CURVE QUARTER LARGEST;So;0;L;;;;;N;;;;; +1D98C;SIGNWRITING MOVEMENT-WALLPLANE CURVE HALF-CIRCLE SMALL;So;0;L;;;;;N;;;;; +1D98D;SIGNWRITING MOVEMENT-WALLPLANE CURVE HALF-CIRCLE MEDIUM;So;0;L;;;;;N;;;;; +1D98E;SIGNWRITING MOVEMENT-WALLPLANE CURVE HALF-CIRCLE LARGE;So;0;L;;;;;N;;;;; +1D98F;SIGNWRITING MOVEMENT-WALLPLANE CURVE HALF-CIRCLE LARGEST;So;0;L;;;;;N;;;;; +1D990;SIGNWRITING MOVEMENT-WALLPLANE CURVE THREE-QUARTER CIRCLE SMALL;So;0;L;;;;;N;;;;; +1D991;SIGNWRITING MOVEMENT-WALLPLANE CURVE THREE-QUARTER CIRCLE MEDIUM;So;0;L;;;;;N;;;;; +1D992;SIGNWRITING MOVEMENT-WALLPLANE HUMP SMALL;So;0;L;;;;;N;;;;; +1D993;SIGNWRITING MOVEMENT-WALLPLANE HUMP MEDIUM;So;0;L;;;;;N;;;;; +1D994;SIGNWRITING MOVEMENT-WALLPLANE HUMP LARGE;So;0;L;;;;;N;;;;; +1D995;SIGNWRITING MOVEMENT-WALLPLANE LOOP SMALL;So;0;L;;;;;N;;;;; +1D996;SIGNWRITING MOVEMENT-WALLPLANE LOOP MEDIUM;So;0;L;;;;;N;;;;; +1D997;SIGNWRITING MOVEMENT-WALLPLANE LOOP LARGE;So;0;L;;;;;N;;;;; +1D998;SIGNWRITING MOVEMENT-WALLPLANE LOOP SMALL DOUBLE;So;0;L;;;;;N;;;;; +1D999;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE DOUBLE SMALL;So;0;L;;;;;N;;;;; +1D99A;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE DOUBLE MEDIUM;So;0;L;;;;;N;;;;; +1D99B;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE DOUBLE LARGE;So;0;L;;;;;N;;;;; +1D99C;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE TRIPLE SMALL;So;0;L;;;;;N;;;;; +1D99D;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE TRIPLE MEDIUM;So;0;L;;;;;N;;;;; +1D99E;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE TRIPLE LARGE;So;0;L;;;;;N;;;;; +1D99F;SIGNWRITING MOVEMENT-WALLPLANE CURVE THEN STRAIGHT;So;0;L;;;;;N;;;;; +1D9A0;SIGNWRITING MOVEMENT-WALLPLANE CURVED CROSS SMALL;So;0;L;;;;;N;;;;; +1D9A1;SIGNWRITING MOVEMENT-WALLPLANE CURVED CROSS MEDIUM;So;0;L;;;;;N;;;;; +1D9A2;SIGNWRITING ROTATION-WALLPLANE SINGLE;So;0;L;;;;;N;;;;; +1D9A3;SIGNWRITING ROTATION-WALLPLANE DOUBLE;So;0;L;;;;;N;;;;; +1D9A4;SIGNWRITING ROTATION-WALLPLANE ALTERNATE;So;0;L;;;;;N;;;;; +1D9A5;SIGNWRITING MOVEMENT-WALLPLANE SHAKING;So;0;L;;;;;N;;;;; +1D9A6;SIGNWRITING MOVEMENT-WALLPLANE CURVE HITTING FRONT WALL;So;0;L;;;;;N;;;;; +1D9A7;SIGNWRITING MOVEMENT-WALLPLANE HUMP HITTING FRONT WALL;So;0;L;;;;;N;;;;; +1D9A8;SIGNWRITING MOVEMENT-WALLPLANE LOOP HITTING FRONT WALL;So;0;L;;;;;N;;;;; +1D9A9;SIGNWRITING MOVEMENT-WALLPLANE WAVE HITTING FRONT WALL;So;0;L;;;;;N;;;;; +1D9AA;SIGNWRITING ROTATION-WALLPLANE SINGLE HITTING FRONT WALL;So;0;L;;;;;N;;;;; +1D9AB;SIGNWRITING ROTATION-WALLPLANE DOUBLE HITTING FRONT WALL;So;0;L;;;;;N;;;;; +1D9AC;SIGNWRITING ROTATION-WALLPLANE ALTERNATING HITTING FRONT WALL;So;0;L;;;;;N;;;;; +1D9AD;SIGNWRITING MOVEMENT-WALLPLANE CURVE HITTING CHEST;So;0;L;;;;;N;;;;; +1D9AE;SIGNWRITING MOVEMENT-WALLPLANE HUMP HITTING CHEST;So;0;L;;;;;N;;;;; +1D9AF;SIGNWRITING MOVEMENT-WALLPLANE LOOP HITTING CHEST;So;0;L;;;;;N;;;;; +1D9B0;SIGNWRITING MOVEMENT-WALLPLANE WAVE HITTING CHEST;So;0;L;;;;;N;;;;; +1D9B1;SIGNWRITING ROTATION-WALLPLANE SINGLE HITTING CHEST;So;0;L;;;;;N;;;;; +1D9B2;SIGNWRITING ROTATION-WALLPLANE DOUBLE HITTING CHEST;So;0;L;;;;;N;;;;; +1D9B3;SIGNWRITING ROTATION-WALLPLANE ALTERNATING HITTING CHEST;So;0;L;;;;;N;;;;; +1D9B4;SIGNWRITING MOVEMENT-WALLPLANE WAVE DIAGONAL PATH SMALL;So;0;L;;;;;N;;;;; +1D9B5;SIGNWRITING MOVEMENT-WALLPLANE WAVE DIAGONAL PATH MEDIUM;So;0;L;;;;;N;;;;; +1D9B6;SIGNWRITING MOVEMENT-WALLPLANE WAVE DIAGONAL PATH LARGE;So;0;L;;;;;N;;;;; +1D9B7;SIGNWRITING MOVEMENT-FLOORPLANE CURVE HITTING CEILING SMALL;So;0;L;;;;;N;;;;; +1D9B8;SIGNWRITING MOVEMENT-FLOORPLANE CURVE HITTING CEILING LARGE;So;0;L;;;;;N;;;;; +1D9B9;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING CEILING SMALL DOUBLE;So;0;L;;;;;N;;;;; +1D9BA;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING CEILING LARGE DOUBLE;So;0;L;;;;;N;;;;; +1D9BB;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING CEILING SMALL TRIPLE;So;0;L;;;;;N;;;;; +1D9BC;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING CEILING LARGE TRIPLE;So;0;L;;;;;N;;;;; +1D9BD;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING CEILING SMALL SINGLE;So;0;L;;;;;N;;;;; +1D9BE;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING CEILING LARGE SINGLE;So;0;L;;;;;N;;;;; +1D9BF;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING CEILING SMALL DOUBLE;So;0;L;;;;;N;;;;; +1D9C0;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING CEILING LARGE DOUBLE;So;0;L;;;;;N;;;;; +1D9C1;SIGNWRITING MOVEMENT-FLOORPLANE WAVE HITTING CEILING SMALL;So;0;L;;;;;N;;;;; +1D9C2;SIGNWRITING MOVEMENT-FLOORPLANE WAVE HITTING CEILING LARGE;So;0;L;;;;;N;;;;; +1D9C3;SIGNWRITING ROTATION-FLOORPLANE SINGLE HITTING CEILING;So;0;L;;;;;N;;;;; +1D9C4;SIGNWRITING ROTATION-FLOORPLANE DOUBLE HITTING CEILING;So;0;L;;;;;N;;;;; +1D9C5;SIGNWRITING ROTATION-FLOORPLANE ALTERNATING HITTING CEILING;So;0;L;;;;;N;;;;; +1D9C6;SIGNWRITING MOVEMENT-FLOORPLANE CURVE HITTING FLOOR SMALL;So;0;L;;;;;N;;;;; +1D9C7;SIGNWRITING MOVEMENT-FLOORPLANE CURVE HITTING FLOOR LARGE;So;0;L;;;;;N;;;;; +1D9C8;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING FLOOR SMALL DOUBLE;So;0;L;;;;;N;;;;; +1D9C9;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING FLOOR LARGE DOUBLE;So;0;L;;;;;N;;;;; +1D9CA;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING FLOOR TRIPLE SMALL TRIPLE;So;0;L;;;;;N;;;;; +1D9CB;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING FLOOR TRIPLE LARGE TRIPLE;So;0;L;;;;;N;;;;; +1D9CC;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING FLOOR SMALL SINGLE;So;0;L;;;;;N;;;;; +1D9CD;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING FLOOR LARGE SINGLE;So;0;L;;;;;N;;;;; +1D9CE;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING FLOOR SMALL DOUBLE;So;0;L;;;;;N;;;;; +1D9CF;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING FLOOR LARGE DOUBLE;So;0;L;;;;;N;;;;; +1D9D0;SIGNWRITING MOVEMENT-FLOORPLANE WAVE HITTING FLOOR SMALL;So;0;L;;;;;N;;;;; +1D9D1;SIGNWRITING MOVEMENT-FLOORPLANE WAVE HITTING FLOOR LARGE;So;0;L;;;;;N;;;;; +1D9D2;SIGNWRITING ROTATION-FLOORPLANE SINGLE HITTING FLOOR;So;0;L;;;;;N;;;;; +1D9D3;SIGNWRITING ROTATION-FLOORPLANE DOUBLE HITTING FLOOR;So;0;L;;;;;N;;;;; +1D9D4;SIGNWRITING ROTATION-FLOORPLANE ALTERNATING HITTING FLOOR;So;0;L;;;;;N;;;;; +1D9D5;SIGNWRITING MOVEMENT-FLOORPLANE CURVE SMALL;So;0;L;;;;;N;;;;; +1D9D6;SIGNWRITING MOVEMENT-FLOORPLANE CURVE MEDIUM;So;0;L;;;;;N;;;;; +1D9D7;SIGNWRITING MOVEMENT-FLOORPLANE CURVE LARGE;So;0;L;;;;;N;;;;; +1D9D8;SIGNWRITING MOVEMENT-FLOORPLANE CURVE LARGEST;So;0;L;;;;;N;;;;; +1D9D9;SIGNWRITING MOVEMENT-FLOORPLANE CURVE COMBINED;So;0;L;;;;;N;;;;; +1D9DA;SIGNWRITING MOVEMENT-FLOORPLANE HUMP SMALL;So;0;L;;;;;N;;;;; +1D9DB;SIGNWRITING MOVEMENT-FLOORPLANE LOOP SMALL;So;0;L;;;;;N;;;;; +1D9DC;SIGNWRITING MOVEMENT-FLOORPLANE WAVE SNAKE;So;0;L;;;;;N;;;;; +1D9DD;SIGNWRITING MOVEMENT-FLOORPLANE WAVE SMALL;So;0;L;;;;;N;;;;; +1D9DE;SIGNWRITING MOVEMENT-FLOORPLANE WAVE LARGE;So;0;L;;;;;N;;;;; +1D9DF;SIGNWRITING ROTATION-FLOORPLANE SINGLE;So;0;L;;;;;N;;;;; +1D9E0;SIGNWRITING ROTATION-FLOORPLANE DOUBLE;So;0;L;;;;;N;;;;; +1D9E1;SIGNWRITING ROTATION-FLOORPLANE ALTERNATING;So;0;L;;;;;N;;;;; +1D9E2;SIGNWRITING MOVEMENT-FLOORPLANE SHAKING PARALLEL;So;0;L;;;;;N;;;;; +1D9E3;SIGNWRITING MOVEMENT-WALLPLANE ARM CIRCLE SMALL SINGLE;So;0;L;;;;;N;;;;; +1D9E4;SIGNWRITING MOVEMENT-WALLPLANE ARM CIRCLE MEDIUM SINGLE;So;0;L;;;;;N;;;;; +1D9E5;SIGNWRITING MOVEMENT-WALLPLANE ARM CIRCLE SMALL DOUBLE;So;0;L;;;;;N;;;;; +1D9E6;SIGNWRITING MOVEMENT-WALLPLANE ARM CIRCLE MEDIUM DOUBLE;So;0;L;;;;;N;;;;; +1D9E7;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL SMALL SINGLE;So;0;L;;;;;N;;;;; +1D9E8;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL MEDIUM SINGLE;So;0;L;;;;;N;;;;; +1D9E9;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL LARGE SINGLE;So;0;L;;;;;N;;;;; +1D9EA;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL SMALL DOUBLE;So;0;L;;;;;N;;;;; +1D9EB;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL MEDIUM DOUBLE;So;0;L;;;;;N;;;;; +1D9EC;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL LARGE DOUBLE;So;0;L;;;;;N;;;;; +1D9ED;SIGNWRITING MOVEMENT-WALLPLANE WRIST CIRCLE FRONT SINGLE;So;0;L;;;;;N;;;;; +1D9EE;SIGNWRITING MOVEMENT-WALLPLANE WRIST CIRCLE FRONT DOUBLE;So;0;L;;;;;N;;;;; +1D9EF;SIGNWRITING MOVEMENT-FLOORPLANE WRIST CIRCLE HITTING WALL SINGLE;So;0;L;;;;;N;;;;; +1D9F0;SIGNWRITING MOVEMENT-FLOORPLANE WRIST CIRCLE HITTING WALL DOUBLE;So;0;L;;;;;N;;;;; +1D9F1;SIGNWRITING MOVEMENT-WALLPLANE FINGER CIRCLES SINGLE;So;0;L;;;;;N;;;;; +1D9F2;SIGNWRITING MOVEMENT-WALLPLANE FINGER CIRCLES DOUBLE;So;0;L;;;;;N;;;;; +1D9F3;SIGNWRITING MOVEMENT-FLOORPLANE FINGER CIRCLES HITTING WALL SINGLE;So;0;L;;;;;N;;;;; +1D9F4;SIGNWRITING MOVEMENT-FLOORPLANE FINGER CIRCLES HITTING WALL DOUBLE;So;0;L;;;;;N;;;;; +1D9F5;SIGNWRITING DYNAMIC ARROWHEAD SMALL;So;0;L;;;;;N;;;;; +1D9F6;SIGNWRITING DYNAMIC ARROWHEAD LARGE;So;0;L;;;;;N;;;;; +1D9F7;SIGNWRITING DYNAMIC FAST;So;0;L;;;;;N;;;;; +1D9F8;SIGNWRITING DYNAMIC SLOW;So;0;L;;;;;N;;;;; +1D9F9;SIGNWRITING DYNAMIC TENSE;So;0;L;;;;;N;;;;; +1D9FA;SIGNWRITING DYNAMIC RELAXED;So;0;L;;;;;N;;;;; +1D9FB;SIGNWRITING DYNAMIC SIMULTANEOUS;So;0;L;;;;;N;;;;; +1D9FC;SIGNWRITING DYNAMIC SIMULTANEOUS ALTERNATING;So;0;L;;;;;N;;;;; +1D9FD;SIGNWRITING DYNAMIC EVERY OTHER TIME;So;0;L;;;;;N;;;;; +1D9FE;SIGNWRITING DYNAMIC GRADUAL;So;0;L;;;;;N;;;;; +1D9FF;SIGNWRITING HEAD;So;0;L;;;;;N;;;;; +1DA00;SIGNWRITING HEAD RIM;Mn;0;NSM;;;;;N;;;;; +1DA01;SIGNWRITING HEAD MOVEMENT-WALLPLANE STRAIGHT;Mn;0;NSM;;;;;N;;;;; +1DA02;SIGNWRITING HEAD MOVEMENT-WALLPLANE TILT;Mn;0;NSM;;;;;N;;;;; +1DA03;SIGNWRITING HEAD MOVEMENT-FLOORPLANE STRAIGHT;Mn;0;NSM;;;;;N;;;;; +1DA04;SIGNWRITING HEAD MOVEMENT-WALLPLANE CURVE;Mn;0;NSM;;;;;N;;;;; +1DA05;SIGNWRITING HEAD MOVEMENT-FLOORPLANE CURVE;Mn;0;NSM;;;;;N;;;;; +1DA06;SIGNWRITING HEAD MOVEMENT CIRCLE;Mn;0;NSM;;;;;N;;;;; +1DA07;SIGNWRITING FACE DIRECTION POSITION NOSE FORWARD TILTING;Mn;0;NSM;;;;;N;;;;; +1DA08;SIGNWRITING FACE DIRECTION POSITION NOSE UP OR DOWN;Mn;0;NSM;;;;;N;;;;; +1DA09;SIGNWRITING FACE DIRECTION POSITION NOSE UP OR DOWN TILTING;Mn;0;NSM;;;;;N;;;;; +1DA0A;SIGNWRITING EYEBROWS STRAIGHT UP;Mn;0;NSM;;;;;N;;;;; +1DA0B;SIGNWRITING EYEBROWS STRAIGHT NEUTRAL;Mn;0;NSM;;;;;N;;;;; +1DA0C;SIGNWRITING EYEBROWS STRAIGHT DOWN;Mn;0;NSM;;;;;N;;;;; +1DA0D;SIGNWRITING DREAMY EYEBROWS NEUTRAL DOWN;Mn;0;NSM;;;;;N;;;;; +1DA0E;SIGNWRITING DREAMY EYEBROWS DOWN NEUTRAL;Mn;0;NSM;;;;;N;;;;; +1DA0F;SIGNWRITING DREAMY EYEBROWS UP NEUTRAL;Mn;0;NSM;;;;;N;;;;; +1DA10;SIGNWRITING DREAMY EYEBROWS NEUTRAL UP;Mn;0;NSM;;;;;N;;;;; +1DA11;SIGNWRITING FOREHEAD NEUTRAL;Mn;0;NSM;;;;;N;;;;; +1DA12;SIGNWRITING FOREHEAD CONTACT;Mn;0;NSM;;;;;N;;;;; +1DA13;SIGNWRITING FOREHEAD WRINKLED;Mn;0;NSM;;;;;N;;;;; +1DA14;SIGNWRITING EYES OPEN;Mn;0;NSM;;;;;N;;;;; +1DA15;SIGNWRITING EYES SQUEEZED;Mn;0;NSM;;;;;N;;;;; +1DA16;SIGNWRITING EYES CLOSED;Mn;0;NSM;;;;;N;;;;; +1DA17;SIGNWRITING EYE BLINK SINGLE;Mn;0;NSM;;;;;N;;;;; +1DA18;SIGNWRITING EYE BLINK MULTIPLE;Mn;0;NSM;;;;;N;;;;; +1DA19;SIGNWRITING EYES HALF OPEN;Mn;0;NSM;;;;;N;;;;; +1DA1A;SIGNWRITING EYES WIDE OPEN;Mn;0;NSM;;;;;N;;;;; +1DA1B;SIGNWRITING EYES HALF CLOSED;Mn;0;NSM;;;;;N;;;;; +1DA1C;SIGNWRITING EYES WIDENING MOVEMENT;Mn;0;NSM;;;;;N;;;;; +1DA1D;SIGNWRITING EYE WINK;Mn;0;NSM;;;;;N;;;;; +1DA1E;SIGNWRITING EYELASHES UP;Mn;0;NSM;;;;;N;;;;; +1DA1F;SIGNWRITING EYELASHES DOWN;Mn;0;NSM;;;;;N;;;;; +1DA20;SIGNWRITING EYELASHES FLUTTERING;Mn;0;NSM;;;;;N;;;;; +1DA21;SIGNWRITING EYEGAZE-WALLPLANE STRAIGHT;Mn;0;NSM;;;;;N;;;;; +1DA22;SIGNWRITING EYEGAZE-WALLPLANE STRAIGHT DOUBLE;Mn;0;NSM;;;;;N;;;;; +1DA23;SIGNWRITING EYEGAZE-WALLPLANE STRAIGHT ALTERNATING;Mn;0;NSM;;;;;N;;;;; +1DA24;SIGNWRITING EYEGAZE-FLOORPLANE STRAIGHT;Mn;0;NSM;;;;;N;;;;; +1DA25;SIGNWRITING EYEGAZE-FLOORPLANE STRAIGHT DOUBLE;Mn;0;NSM;;;;;N;;;;; +1DA26;SIGNWRITING EYEGAZE-FLOORPLANE STRAIGHT ALTERNATING;Mn;0;NSM;;;;;N;;;;; +1DA27;SIGNWRITING EYEGAZE-WALLPLANE CURVED;Mn;0;NSM;;;;;N;;;;; +1DA28;SIGNWRITING EYEGAZE-FLOORPLANE CURVED;Mn;0;NSM;;;;;N;;;;; +1DA29;SIGNWRITING EYEGAZE-WALLPLANE CIRCLING;Mn;0;NSM;;;;;N;;;;; +1DA2A;SIGNWRITING CHEEKS PUFFED;Mn;0;NSM;;;;;N;;;;; +1DA2B;SIGNWRITING CHEEKS NEUTRAL;Mn;0;NSM;;;;;N;;;;; +1DA2C;SIGNWRITING CHEEKS SUCKED;Mn;0;NSM;;;;;N;;;;; +1DA2D;SIGNWRITING TENSE CHEEKS HIGH;Mn;0;NSM;;;;;N;;;;; +1DA2E;SIGNWRITING TENSE CHEEKS MIDDLE;Mn;0;NSM;;;;;N;;;;; +1DA2F;SIGNWRITING TENSE CHEEKS LOW;Mn;0;NSM;;;;;N;;;;; +1DA30;SIGNWRITING EARS;Mn;0;NSM;;;;;N;;;;; +1DA31;SIGNWRITING NOSE NEUTRAL;Mn;0;NSM;;;;;N;;;;; +1DA32;SIGNWRITING NOSE CONTACT;Mn;0;NSM;;;;;N;;;;; +1DA33;SIGNWRITING NOSE WRINKLES;Mn;0;NSM;;;;;N;;;;; +1DA34;SIGNWRITING NOSE WIGGLES;Mn;0;NSM;;;;;N;;;;; +1DA35;SIGNWRITING AIR BLOWING OUT;Mn;0;NSM;;;;;N;;;;; +1DA36;SIGNWRITING AIR SUCKING IN;Mn;0;NSM;;;;;N;;;;; +1DA37;SIGNWRITING AIR BLOW SMALL ROTATIONS;So;0;L;;;;;N;;;;; +1DA38;SIGNWRITING AIR SUCK SMALL ROTATIONS;So;0;L;;;;;N;;;;; +1DA39;SIGNWRITING BREATH INHALE;So;0;L;;;;;N;;;;; +1DA3A;SIGNWRITING BREATH EXHALE;So;0;L;;;;;N;;;;; +1DA3B;SIGNWRITING MOUTH CLOSED NEUTRAL;Mn;0;NSM;;;;;N;;;;; +1DA3C;SIGNWRITING MOUTH CLOSED FORWARD;Mn;0;NSM;;;;;N;;;;; +1DA3D;SIGNWRITING MOUTH CLOSED CONTACT;Mn;0;NSM;;;;;N;;;;; +1DA3E;SIGNWRITING MOUTH SMILE;Mn;0;NSM;;;;;N;;;;; +1DA3F;SIGNWRITING MOUTH SMILE WRINKLED;Mn;0;NSM;;;;;N;;;;; +1DA40;SIGNWRITING MOUTH SMILE OPEN;Mn;0;NSM;;;;;N;;;;; +1DA41;SIGNWRITING MOUTH FROWN;Mn;0;NSM;;;;;N;;;;; +1DA42;SIGNWRITING MOUTH FROWN WRINKLED;Mn;0;NSM;;;;;N;;;;; +1DA43;SIGNWRITING MOUTH FROWN OPEN;Mn;0;NSM;;;;;N;;;;; +1DA44;SIGNWRITING MOUTH OPEN CIRCLE;Mn;0;NSM;;;;;N;;;;; +1DA45;SIGNWRITING MOUTH OPEN FORWARD;Mn;0;NSM;;;;;N;;;;; +1DA46;SIGNWRITING MOUTH OPEN WRINKLED;Mn;0;NSM;;;;;N;;;;; +1DA47;SIGNWRITING MOUTH OPEN OVAL;Mn;0;NSM;;;;;N;;;;; +1DA48;SIGNWRITING MOUTH OPEN OVAL WRINKLED;Mn;0;NSM;;;;;N;;;;; +1DA49;SIGNWRITING MOUTH OPEN OVAL YAWN;Mn;0;NSM;;;;;N;;;;; +1DA4A;SIGNWRITING MOUTH OPEN RECTANGLE;Mn;0;NSM;;;;;N;;;;; +1DA4B;SIGNWRITING MOUTH OPEN RECTANGLE WRINKLED;Mn;0;NSM;;;;;N;;;;; +1DA4C;SIGNWRITING MOUTH OPEN RECTANGLE YAWN;Mn;0;NSM;;;;;N;;;;; +1DA4D;SIGNWRITING MOUTH KISS;Mn;0;NSM;;;;;N;;;;; +1DA4E;SIGNWRITING MOUTH KISS FORWARD;Mn;0;NSM;;;;;N;;;;; +1DA4F;SIGNWRITING MOUTH KISS WRINKLED;Mn;0;NSM;;;;;N;;;;; +1DA50;SIGNWRITING MOUTH TENSE;Mn;0;NSM;;;;;N;;;;; +1DA51;SIGNWRITING MOUTH TENSE FORWARD;Mn;0;NSM;;;;;N;;;;; +1DA52;SIGNWRITING MOUTH TENSE SUCKED;Mn;0;NSM;;;;;N;;;;; +1DA53;SIGNWRITING LIPS PRESSED TOGETHER;Mn;0;NSM;;;;;N;;;;; +1DA54;SIGNWRITING LIP LOWER OVER UPPER;Mn;0;NSM;;;;;N;;;;; +1DA55;SIGNWRITING LIP UPPER OVER LOWER;Mn;0;NSM;;;;;N;;;;; +1DA56;SIGNWRITING MOUTH CORNERS;Mn;0;NSM;;;;;N;;;;; +1DA57;SIGNWRITING MOUTH WRINKLES SINGLE;Mn;0;NSM;;;;;N;;;;; +1DA58;SIGNWRITING MOUTH WRINKLES DOUBLE;Mn;0;NSM;;;;;N;;;;; +1DA59;SIGNWRITING TONGUE STICKING OUT FAR;Mn;0;NSM;;;;;N;;;;; +1DA5A;SIGNWRITING TONGUE LICKING LIPS;Mn;0;NSM;;;;;N;;;;; +1DA5B;SIGNWRITING TONGUE TIP BETWEEN LIPS;Mn;0;NSM;;;;;N;;;;; +1DA5C;SIGNWRITING TONGUE TIP TOUCHING INSIDE MOUTH;Mn;0;NSM;;;;;N;;;;; +1DA5D;SIGNWRITING TONGUE INSIDE MOUTH RELAXED;Mn;0;NSM;;;;;N;;;;; +1DA5E;SIGNWRITING TONGUE MOVES AGAINST CHEEK;Mn;0;NSM;;;;;N;;;;; +1DA5F;SIGNWRITING TONGUE CENTRE STICKING OUT;Mn;0;NSM;;;;;N;;;;; +1DA60;SIGNWRITING TONGUE CENTRE INSIDE MOUTH;Mn;0;NSM;;;;;N;;;;; +1DA61;SIGNWRITING TEETH;Mn;0;NSM;;;;;N;;;;; +1DA62;SIGNWRITING TEETH MOVEMENT;Mn;0;NSM;;;;;N;;;;; +1DA63;SIGNWRITING TEETH ON TONGUE;Mn;0;NSM;;;;;N;;;;; +1DA64;SIGNWRITING TEETH ON TONGUE MOVEMENT;Mn;0;NSM;;;;;N;;;;; +1DA65;SIGNWRITING TEETH ON LIPS;Mn;0;NSM;;;;;N;;;;; +1DA66;SIGNWRITING TEETH ON LIPS MOVEMENT;Mn;0;NSM;;;;;N;;;;; +1DA67;SIGNWRITING TEETH BITE LIPS;Mn;0;NSM;;;;;N;;;;; +1DA68;SIGNWRITING MOVEMENT-WALLPLANE JAW;Mn;0;NSM;;;;;N;;;;; +1DA69;SIGNWRITING MOVEMENT-FLOORPLANE JAW;Mn;0;NSM;;;;;N;;;;; +1DA6A;SIGNWRITING NECK;Mn;0;NSM;;;;;N;;;;; +1DA6B;SIGNWRITING HAIR;Mn;0;NSM;;;;;N;;;;; +1DA6C;SIGNWRITING EXCITEMENT;Mn;0;NSM;;;;;N;;;;; +1DA6D;SIGNWRITING SHOULDER HIP SPINE;So;0;L;;;;;N;;;;; +1DA6E;SIGNWRITING SHOULDER HIP POSITIONS;So;0;L;;;;;N;;;;; +1DA6F;SIGNWRITING WALLPLANE SHOULDER HIP MOVE;So;0;L;;;;;N;;;;; +1DA70;SIGNWRITING FLOORPLANE SHOULDER HIP MOVE;So;0;L;;;;;N;;;;; +1DA71;SIGNWRITING SHOULDER TILTING FROM WAIST;So;0;L;;;;;N;;;;; +1DA72;SIGNWRITING TORSO-WALLPLANE STRAIGHT STRETCH;So;0;L;;;;;N;;;;; +1DA73;SIGNWRITING TORSO-WALLPLANE CURVED BEND;So;0;L;;;;;N;;;;; +1DA74;SIGNWRITING TORSO-FLOORPLANE TWISTING;So;0;L;;;;;N;;;;; +1DA75;SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS;Mn;0;NSM;;;;;N;;;;; +1DA76;SIGNWRITING LIMB COMBINATION;So;0;L;;;;;N;;;;; +1DA77;SIGNWRITING LIMB LENGTH-1;So;0;L;;;;;N;;;;; +1DA78;SIGNWRITING LIMB LENGTH-2;So;0;L;;;;;N;;;;; +1DA79;SIGNWRITING LIMB LENGTH-3;So;0;L;;;;;N;;;;; +1DA7A;SIGNWRITING LIMB LENGTH-4;So;0;L;;;;;N;;;;; +1DA7B;SIGNWRITING LIMB LENGTH-5;So;0;L;;;;;N;;;;; +1DA7C;SIGNWRITING LIMB LENGTH-6;So;0;L;;;;;N;;;;; +1DA7D;SIGNWRITING LIMB LENGTH-7;So;0;L;;;;;N;;;;; +1DA7E;SIGNWRITING FINGER;So;0;L;;;;;N;;;;; +1DA7F;SIGNWRITING LOCATION-WALLPLANE SPACE;So;0;L;;;;;N;;;;; +1DA80;SIGNWRITING LOCATION-FLOORPLANE SPACE;So;0;L;;;;;N;;;;; +1DA81;SIGNWRITING LOCATION HEIGHT;So;0;L;;;;;N;;;;; +1DA82;SIGNWRITING LOCATION WIDTH;So;0;L;;;;;N;;;;; +1DA83;SIGNWRITING LOCATION DEPTH;So;0;L;;;;;N;;;;; +1DA84;SIGNWRITING LOCATION HEAD NECK;Mn;0;NSM;;;;;N;;;;; +1DA85;SIGNWRITING LOCATION TORSO;So;0;L;;;;;N;;;;; +1DA86;SIGNWRITING LOCATION LIMBS DIGITS;So;0;L;;;;;N;;;;; +1DA87;SIGNWRITING COMMA;Po;0;L;;;;;N;;;;; +1DA88;SIGNWRITING FULL STOP;Po;0;L;;;;;N;;;;; +1DA89;SIGNWRITING SEMICOLON;Po;0;L;;;;;N;;;;; +1DA8A;SIGNWRITING COLON;Po;0;L;;;;;N;;;;; +1DA8B;SIGNWRITING PARENTHESIS;Po;0;L;;;;;N;;;;; +1DA9B;SIGNWRITING FILL MODIFIER-2;Mn;0;NSM;;;;;N;;;;; +1DA9C;SIGNWRITING FILL MODIFIER-3;Mn;0;NSM;;;;;N;;;;; +1DA9D;SIGNWRITING FILL MODIFIER-4;Mn;0;NSM;;;;;N;;;;; +1DA9E;SIGNWRITING FILL MODIFIER-5;Mn;0;NSM;;;;;N;;;;; +1DA9F;SIGNWRITING FILL MODIFIER-6;Mn;0;NSM;;;;;N;;;;; +1DAA1;SIGNWRITING ROTATION MODIFIER-2;Mn;0;NSM;;;;;N;;;;; +1DAA2;SIGNWRITING ROTATION MODIFIER-3;Mn;0;NSM;;;;;N;;;;; +1DAA3;SIGNWRITING ROTATION MODIFIER-4;Mn;0;NSM;;;;;N;;;;; +1DAA4;SIGNWRITING ROTATION MODIFIER-5;Mn;0;NSM;;;;;N;;;;; +1DAA5;SIGNWRITING ROTATION MODIFIER-6;Mn;0;NSM;;;;;N;;;;; +1DAA6;SIGNWRITING ROTATION MODIFIER-7;Mn;0;NSM;;;;;N;;;;; +1DAA7;SIGNWRITING ROTATION MODIFIER-8;Mn;0;NSM;;;;;N;;;;; +1DAA8;SIGNWRITING ROTATION MODIFIER-9;Mn;0;NSM;;;;;N;;;;; +1DAA9;SIGNWRITING ROTATION MODIFIER-10;Mn;0;NSM;;;;;N;;;;; +1DAAA;SIGNWRITING ROTATION MODIFIER-11;Mn;0;NSM;;;;;N;;;;; +1DAAB;SIGNWRITING ROTATION MODIFIER-12;Mn;0;NSM;;;;;N;;;;; +1DAAC;SIGNWRITING ROTATION MODIFIER-13;Mn;0;NSM;;;;;N;;;;; +1DAAD;SIGNWRITING ROTATION MODIFIER-14;Mn;0;NSM;;;;;N;;;;; +1DAAE;SIGNWRITING ROTATION MODIFIER-15;Mn;0;NSM;;;;;N;;;;; +1DAAF;SIGNWRITING ROTATION MODIFIER-16;Mn;0;NSM;;;;;N;;;;; +1E000;COMBINING GLAGOLITIC LETTER AZU;Mn;230;NSM;;;;;N;;;;; +1E001;COMBINING GLAGOLITIC LETTER BUKY;Mn;230;NSM;;;;;N;;;;; +1E002;COMBINING GLAGOLITIC LETTER VEDE;Mn;230;NSM;;;;;N;;;;; +1E003;COMBINING GLAGOLITIC LETTER GLAGOLI;Mn;230;NSM;;;;;N;;;;; +1E004;COMBINING GLAGOLITIC LETTER DOBRO;Mn;230;NSM;;;;;N;;;;; +1E005;COMBINING GLAGOLITIC LETTER YESTU;Mn;230;NSM;;;;;N;;;;; +1E006;COMBINING GLAGOLITIC LETTER ZHIVETE;Mn;230;NSM;;;;;N;;;;; +1E008;COMBINING GLAGOLITIC LETTER ZEMLJA;Mn;230;NSM;;;;;N;;;;; +1E009;COMBINING GLAGOLITIC LETTER IZHE;Mn;230;NSM;;;;;N;;;;; +1E00A;COMBINING GLAGOLITIC LETTER INITIAL IZHE;Mn;230;NSM;;;;;N;;;;; +1E00B;COMBINING GLAGOLITIC LETTER I;Mn;230;NSM;;;;;N;;;;; +1E00C;COMBINING GLAGOLITIC LETTER DJERVI;Mn;230;NSM;;;;;N;;;;; +1E00D;COMBINING GLAGOLITIC LETTER KAKO;Mn;230;NSM;;;;;N;;;;; +1E00E;COMBINING GLAGOLITIC LETTER LJUDIJE;Mn;230;NSM;;;;;N;;;;; +1E00F;COMBINING GLAGOLITIC LETTER MYSLITE;Mn;230;NSM;;;;;N;;;;; +1E010;COMBINING GLAGOLITIC LETTER NASHI;Mn;230;NSM;;;;;N;;;;; +1E011;COMBINING GLAGOLITIC LETTER ONU;Mn;230;NSM;;;;;N;;;;; +1E012;COMBINING GLAGOLITIC LETTER POKOJI;Mn;230;NSM;;;;;N;;;;; +1E013;COMBINING GLAGOLITIC LETTER RITSI;Mn;230;NSM;;;;;N;;;;; +1E014;COMBINING GLAGOLITIC LETTER SLOVO;Mn;230;NSM;;;;;N;;;;; +1E015;COMBINING GLAGOLITIC LETTER TVRIDO;Mn;230;NSM;;;;;N;;;;; +1E016;COMBINING GLAGOLITIC LETTER UKU;Mn;230;NSM;;;;;N;;;;; +1E017;COMBINING GLAGOLITIC LETTER FRITU;Mn;230;NSM;;;;;N;;;;; +1E018;COMBINING GLAGOLITIC LETTER HERU;Mn;230;NSM;;;;;N;;;;; +1E01B;COMBINING GLAGOLITIC LETTER SHTA;Mn;230;NSM;;;;;N;;;;; +1E01C;COMBINING GLAGOLITIC LETTER TSI;Mn;230;NSM;;;;;N;;;;; +1E01D;COMBINING GLAGOLITIC LETTER CHRIVI;Mn;230;NSM;;;;;N;;;;; +1E01E;COMBINING GLAGOLITIC LETTER SHA;Mn;230;NSM;;;;;N;;;;; +1E01F;COMBINING GLAGOLITIC LETTER YERU;Mn;230;NSM;;;;;N;;;;; +1E020;COMBINING GLAGOLITIC LETTER YERI;Mn;230;NSM;;;;;N;;;;; +1E021;COMBINING GLAGOLITIC LETTER YATI;Mn;230;NSM;;;;;N;;;;; +1E023;COMBINING GLAGOLITIC LETTER YU;Mn;230;NSM;;;;;N;;;;; +1E024;COMBINING GLAGOLITIC LETTER SMALL YUS;Mn;230;NSM;;;;;N;;;;; +1E026;COMBINING GLAGOLITIC LETTER YO;Mn;230;NSM;;;;;N;;;;; +1E027;COMBINING GLAGOLITIC LETTER IOTATED SMALL YUS;Mn;230;NSM;;;;;N;;;;; +1E028;COMBINING GLAGOLITIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;; +1E029;COMBINING GLAGOLITIC LETTER IOTATED BIG YUS;Mn;230;NSM;;;;;N;;;;; +1E02A;COMBINING GLAGOLITIC LETTER FITA;Mn;230;NSM;;;;;N;;;;; +1E100;NYIAKENG PUACHUE HMONG LETTER MA;Lo;0;L;;;;;N;;;;; +1E101;NYIAKENG PUACHUE HMONG LETTER TSA;Lo;0;L;;;;;N;;;;; +1E102;NYIAKENG PUACHUE HMONG LETTER NTA;Lo;0;L;;;;;N;;;;; +1E103;NYIAKENG PUACHUE HMONG LETTER TA;Lo;0;L;;;;;N;;;;; +1E104;NYIAKENG PUACHUE HMONG LETTER HA;Lo;0;L;;;;;N;;;;; +1E105;NYIAKENG PUACHUE HMONG LETTER NA;Lo;0;L;;;;;N;;;;; +1E106;NYIAKENG PUACHUE HMONG LETTER XA;Lo;0;L;;;;;N;;;;; +1E107;NYIAKENG PUACHUE HMONG LETTER NKA;Lo;0;L;;;;;N;;;;; +1E108;NYIAKENG PUACHUE HMONG LETTER CA;Lo;0;L;;;;;N;;;;; +1E109;NYIAKENG PUACHUE HMONG LETTER LA;Lo;0;L;;;;;N;;;;; +1E10A;NYIAKENG PUACHUE HMONG LETTER SA;Lo;0;L;;;;;N;;;;; +1E10B;NYIAKENG PUACHUE HMONG LETTER ZA;Lo;0;L;;;;;N;;;;; +1E10C;NYIAKENG PUACHUE HMONG LETTER NCA;Lo;0;L;;;;;N;;;;; +1E10D;NYIAKENG PUACHUE HMONG LETTER NTSA;Lo;0;L;;;;;N;;;;; +1E10E;NYIAKENG PUACHUE HMONG LETTER KA;Lo;0;L;;;;;N;;;;; +1E10F;NYIAKENG PUACHUE HMONG LETTER DA;Lo;0;L;;;;;N;;;;; +1E110;NYIAKENG PUACHUE HMONG LETTER NYA;Lo;0;L;;;;;N;;;;; +1E111;NYIAKENG PUACHUE HMONG LETTER NRA;Lo;0;L;;;;;N;;;;; +1E112;NYIAKENG PUACHUE HMONG LETTER VA;Lo;0;L;;;;;N;;;;; +1E113;NYIAKENG PUACHUE HMONG LETTER NTXA;Lo;0;L;;;;;N;;;;; +1E114;NYIAKENG PUACHUE HMONG LETTER TXA;Lo;0;L;;;;;N;;;;; +1E115;NYIAKENG PUACHUE HMONG LETTER FA;Lo;0;L;;;;;N;;;;; +1E116;NYIAKENG PUACHUE HMONG LETTER RA;Lo;0;L;;;;;N;;;;; +1E117;NYIAKENG PUACHUE HMONG LETTER QA;Lo;0;L;;;;;N;;;;; +1E118;NYIAKENG PUACHUE HMONG LETTER YA;Lo;0;L;;;;;N;;;;; +1E119;NYIAKENG PUACHUE HMONG LETTER NQA;Lo;0;L;;;;;N;;;;; +1E11A;NYIAKENG PUACHUE HMONG LETTER PA;Lo;0;L;;;;;N;;;;; +1E11B;NYIAKENG PUACHUE HMONG LETTER XYA;Lo;0;L;;;;;N;;;;; +1E11C;NYIAKENG PUACHUE HMONG LETTER NPA;Lo;0;L;;;;;N;;;;; +1E11D;NYIAKENG PUACHUE HMONG LETTER DLA;Lo;0;L;;;;;N;;;;; +1E11E;NYIAKENG PUACHUE HMONG LETTER NPLA;Lo;0;L;;;;;N;;;;; +1E11F;NYIAKENG PUACHUE HMONG LETTER HAH;Lo;0;L;;;;;N;;;;; +1E120;NYIAKENG PUACHUE HMONG LETTER MLA;Lo;0;L;;;;;N;;;;; +1E121;NYIAKENG PUACHUE HMONG LETTER PLA;Lo;0;L;;;;;N;;;;; +1E122;NYIAKENG PUACHUE HMONG LETTER GA;Lo;0;L;;;;;N;;;;; +1E123;NYIAKENG PUACHUE HMONG LETTER RRA;Lo;0;L;;;;;N;;;;; +1E124;NYIAKENG PUACHUE HMONG LETTER A;Lo;0;L;;;;;N;;;;; +1E125;NYIAKENG PUACHUE HMONG LETTER AA;Lo;0;L;;;;;N;;;;; +1E126;NYIAKENG PUACHUE HMONG LETTER I;Lo;0;L;;;;;N;;;;; +1E127;NYIAKENG PUACHUE HMONG LETTER U;Lo;0;L;;;;;N;;;;; +1E128;NYIAKENG PUACHUE HMONG LETTER O;Lo;0;L;;;;;N;;;;; +1E129;NYIAKENG PUACHUE HMONG LETTER OO;Lo;0;L;;;;;N;;;;; +1E12A;NYIAKENG PUACHUE HMONG LETTER E;Lo;0;L;;;;;N;;;;; +1E12B;NYIAKENG PUACHUE HMONG LETTER EE;Lo;0;L;;;;;N;;;;; +1E12C;NYIAKENG PUACHUE HMONG LETTER W;Lo;0;L;;;;;N;;;;; +1E130;NYIAKENG PUACHUE HMONG TONE-B;Mn;230;NSM;;;;;N;;;;; +1E131;NYIAKENG PUACHUE HMONG TONE-M;Mn;230;NSM;;;;;N;;;;; +1E132;NYIAKENG PUACHUE HMONG TONE-J;Mn;230;NSM;;;;;N;;;;; +1E133;NYIAKENG PUACHUE HMONG TONE-V;Mn;230;NSM;;;;;N;;;;; +1E134;NYIAKENG PUACHUE HMONG TONE-S;Mn;230;NSM;;;;;N;;;;; +1E135;NYIAKENG PUACHUE HMONG TONE-G;Mn;230;NSM;;;;;N;;;;; +1E136;NYIAKENG PUACHUE HMONG TONE-D;Mn;230;NSM;;;;;N;;;;; +1E137;NYIAKENG PUACHUE HMONG SIGN FOR PERSON;Lm;0;L;;;;;N;;;;; +1E138;NYIAKENG PUACHUE HMONG SIGN FOR THING;Lm;0;L;;;;;N;;;;; +1E139;NYIAKENG PUACHUE HMONG SIGN FOR LOCATION;Lm;0;L;;;;;N;;;;; +1E13A;NYIAKENG PUACHUE HMONG SIGN FOR ANIMAL;Lm;0;L;;;;;N;;;;; +1E13B;NYIAKENG PUACHUE HMONG SIGN FOR INVERTEBRATE;Lm;0;L;;;;;N;;;;; +1E13C;NYIAKENG PUACHUE HMONG SIGN XW XW;Lm;0;L;;;;;N;;;;; +1E13D;NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER;Lm;0;L;;;;;N;;;;; +1E140;NYIAKENG PUACHUE HMONG DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1E141;NYIAKENG PUACHUE HMONG DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1E142;NYIAKENG PUACHUE HMONG DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1E143;NYIAKENG PUACHUE HMONG DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1E144;NYIAKENG PUACHUE HMONG DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1E145;NYIAKENG PUACHUE HMONG DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1E146;NYIAKENG PUACHUE HMONG DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1E147;NYIAKENG PUACHUE HMONG DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1E148;NYIAKENG PUACHUE HMONG DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1E149;NYIAKENG PUACHUE HMONG DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1E14E;NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ;Lo;0;L;;;;;N;;;;; +1E14F;NYIAKENG PUACHUE HMONG CIRCLED CA;So;0;L;;;;;N;;;;; +1E2C0;WANCHO LETTER AA;Lo;0;L;;;;;N;;;;; +1E2C1;WANCHO LETTER A;Lo;0;L;;;;;N;;;;; +1E2C2;WANCHO LETTER BA;Lo;0;L;;;;;N;;;;; +1E2C3;WANCHO LETTER CA;Lo;0;L;;;;;N;;;;; +1E2C4;WANCHO LETTER DA;Lo;0;L;;;;;N;;;;; +1E2C5;WANCHO LETTER GA;Lo;0;L;;;;;N;;;;; +1E2C6;WANCHO LETTER YA;Lo;0;L;;;;;N;;;;; +1E2C7;WANCHO LETTER PHA;Lo;0;L;;;;;N;;;;; +1E2C8;WANCHO LETTER LA;Lo;0;L;;;;;N;;;;; +1E2C9;WANCHO LETTER NA;Lo;0;L;;;;;N;;;;; +1E2CA;WANCHO LETTER PA;Lo;0;L;;;;;N;;;;; +1E2CB;WANCHO LETTER TA;Lo;0;L;;;;;N;;;;; +1E2CC;WANCHO LETTER THA;Lo;0;L;;;;;N;;;;; +1E2CD;WANCHO LETTER FA;Lo;0;L;;;;;N;;;;; +1E2CE;WANCHO LETTER SA;Lo;0;L;;;;;N;;;;; +1E2CF;WANCHO LETTER SHA;Lo;0;L;;;;;N;;;;; +1E2D0;WANCHO LETTER JA;Lo;0;L;;;;;N;;;;; +1E2D1;WANCHO LETTER ZA;Lo;0;L;;;;;N;;;;; +1E2D2;WANCHO LETTER WA;Lo;0;L;;;;;N;;;;; +1E2D3;WANCHO LETTER VA;Lo;0;L;;;;;N;;;;; +1E2D4;WANCHO LETTER KA;Lo;0;L;;;;;N;;;;; +1E2D5;WANCHO LETTER O;Lo;0;L;;;;;N;;;;; +1E2D6;WANCHO LETTER AU;Lo;0;L;;;;;N;;;;; +1E2D7;WANCHO LETTER RA;Lo;0;L;;;;;N;;;;; +1E2D8;WANCHO LETTER MA;Lo;0;L;;;;;N;;;;; +1E2D9;WANCHO LETTER KHA;Lo;0;L;;;;;N;;;;; +1E2DA;WANCHO LETTER HA;Lo;0;L;;;;;N;;;;; +1E2DB;WANCHO LETTER E;Lo;0;L;;;;;N;;;;; +1E2DC;WANCHO LETTER I;Lo;0;L;;;;;N;;;;; +1E2DD;WANCHO LETTER NGA;Lo;0;L;;;;;N;;;;; +1E2DE;WANCHO LETTER U;Lo;0;L;;;;;N;;;;; +1E2DF;WANCHO LETTER LLHA;Lo;0;L;;;;;N;;;;; +1E2E0;WANCHO LETTER TSA;Lo;0;L;;;;;N;;;;; +1E2E1;WANCHO LETTER TRA;Lo;0;L;;;;;N;;;;; +1E2E2;WANCHO LETTER ONG;Lo;0;L;;;;;N;;;;; +1E2E3;WANCHO LETTER AANG;Lo;0;L;;;;;N;;;;; +1E2E4;WANCHO LETTER ANG;Lo;0;L;;;;;N;;;;; +1E2E5;WANCHO LETTER ING;Lo;0;L;;;;;N;;;;; +1E2E6;WANCHO LETTER ON;Lo;0;L;;;;;N;;;;; +1E2E7;WANCHO LETTER EN;Lo;0;L;;;;;N;;;;; +1E2E8;WANCHO LETTER AAN;Lo;0;L;;;;;N;;;;; +1E2E9;WANCHO LETTER NYA;Lo;0;L;;;;;N;;;;; +1E2EA;WANCHO LETTER UEN;Lo;0;L;;;;;N;;;;; +1E2EB;WANCHO LETTER YIH;Lo;0;L;;;;;N;;;;; +1E2EC;WANCHO TONE TUP;Mn;230;NSM;;;;;N;;;;; +1E2ED;WANCHO TONE TUPNI;Mn;230;NSM;;;;;N;;;;; +1E2EE;WANCHO TONE KOI;Mn;230;NSM;;;;;N;;;;; +1E2EF;WANCHO TONE KOINI;Mn;230;NSM;;;;;N;;;;; +1E2F0;WANCHO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1E2F1;WANCHO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1E2F2;WANCHO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1E2F3;WANCHO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1E2F4;WANCHO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1E2F5;WANCHO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1E2F6;WANCHO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1E2F7;WANCHO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1E2F8;WANCHO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1E2F9;WANCHO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1E2FF;WANCHO NGUN SIGN;Sc;0;ET;;;;;N;;;;; +1E800;MENDE KIKAKUI SYLLABLE M001 KI;Lo;0;R;;;;;N;;;;; +1E801;MENDE KIKAKUI SYLLABLE M002 KA;Lo;0;R;;;;;N;;;;; +1E802;MENDE KIKAKUI SYLLABLE M003 KU;Lo;0;R;;;;;N;;;;; +1E803;MENDE KIKAKUI SYLLABLE M065 KEE;Lo;0;R;;;;;N;;;;; +1E804;MENDE KIKAKUI SYLLABLE M095 KE;Lo;0;R;;;;;N;;;;; +1E805;MENDE KIKAKUI SYLLABLE M076 KOO;Lo;0;R;;;;;N;;;;; +1E806;MENDE KIKAKUI SYLLABLE M048 KO;Lo;0;R;;;;;N;;;;; +1E807;MENDE KIKAKUI SYLLABLE M179 KUA;Lo;0;R;;;;;N;;;;; +1E808;MENDE KIKAKUI SYLLABLE M004 WI;Lo;0;R;;;;;N;;;;; +1E809;MENDE KIKAKUI SYLLABLE M005 WA;Lo;0;R;;;;;N;;;;; +1E80A;MENDE KIKAKUI SYLLABLE M006 WU;Lo;0;R;;;;;N;;;;; +1E80B;MENDE KIKAKUI SYLLABLE M126 WEE;Lo;0;R;;;;;N;;;;; +1E80C;MENDE KIKAKUI SYLLABLE M118 WE;Lo;0;R;;;;;N;;;;; +1E80D;MENDE KIKAKUI SYLLABLE M114 WOO;Lo;0;R;;;;;N;;;;; +1E80E;MENDE KIKAKUI SYLLABLE M045 WO;Lo;0;R;;;;;N;;;;; +1E80F;MENDE KIKAKUI SYLLABLE M194 WUI;Lo;0;R;;;;;N;;;;; +1E810;MENDE KIKAKUI SYLLABLE M143 WEI;Lo;0;R;;;;;N;;;;; +1E811;MENDE KIKAKUI SYLLABLE M061 WVI;Lo;0;R;;;;;N;;;;; +1E812;MENDE KIKAKUI SYLLABLE M049 WVA;Lo;0;R;;;;;N;;;;; +1E813;MENDE KIKAKUI SYLLABLE M139 WVE;Lo;0;R;;;;;N;;;;; +1E814;MENDE KIKAKUI SYLLABLE M007 MIN;Lo;0;R;;;;;N;;;;; +1E815;MENDE KIKAKUI SYLLABLE M008 MAN;Lo;0;R;;;;;N;;;;; +1E816;MENDE KIKAKUI SYLLABLE M009 MUN;Lo;0;R;;;;;N;;;;; +1E817;MENDE KIKAKUI SYLLABLE M059 MEN;Lo;0;R;;;;;N;;;;; +1E818;MENDE KIKAKUI SYLLABLE M094 MON;Lo;0;R;;;;;N;;;;; +1E819;MENDE KIKAKUI SYLLABLE M154 MUAN;Lo;0;R;;;;;N;;;;; +1E81A;MENDE KIKAKUI SYLLABLE M189 MUEN;Lo;0;R;;;;;N;;;;; +1E81B;MENDE KIKAKUI SYLLABLE M010 BI;Lo;0;R;;;;;N;;;;; +1E81C;MENDE KIKAKUI SYLLABLE M011 BA;Lo;0;R;;;;;N;;;;; +1E81D;MENDE KIKAKUI SYLLABLE M012 BU;Lo;0;R;;;;;N;;;;; +1E81E;MENDE KIKAKUI SYLLABLE M150 BEE;Lo;0;R;;;;;N;;;;; +1E81F;MENDE KIKAKUI SYLLABLE M097 BE;Lo;0;R;;;;;N;;;;; +1E820;MENDE KIKAKUI SYLLABLE M103 BOO;Lo;0;R;;;;;N;;;;; +1E821;MENDE KIKAKUI SYLLABLE M138 BO;Lo;0;R;;;;;N;;;;; +1E822;MENDE KIKAKUI SYLLABLE M013 I;Lo;0;R;;;;;N;;;;; +1E823;MENDE KIKAKUI SYLLABLE M014 A;Lo;0;R;;;;;N;;;;; +1E824;MENDE KIKAKUI SYLLABLE M015 U;Lo;0;R;;;;;N;;;;; +1E825;MENDE KIKAKUI SYLLABLE M163 EE;Lo;0;R;;;;;N;;;;; +1E826;MENDE KIKAKUI SYLLABLE M100 E;Lo;0;R;;;;;N;;;;; +1E827;MENDE KIKAKUI SYLLABLE M165 OO;Lo;0;R;;;;;N;;;;; +1E828;MENDE KIKAKUI SYLLABLE M147 O;Lo;0;R;;;;;N;;;;; +1E829;MENDE KIKAKUI SYLLABLE M137 EI;Lo;0;R;;;;;N;;;;; +1E82A;MENDE KIKAKUI SYLLABLE M131 IN;Lo;0;R;;;;;N;;;;; +1E82B;MENDE KIKAKUI SYLLABLE M135 IN;Lo;0;R;;;;;N;;;;; +1E82C;MENDE KIKAKUI SYLLABLE M195 AN;Lo;0;R;;;;;N;;;;; +1E82D;MENDE KIKAKUI SYLLABLE M178 EN;Lo;0;R;;;;;N;;;;; +1E82E;MENDE KIKAKUI SYLLABLE M019 SI;Lo;0;R;;;;;N;;;;; +1E82F;MENDE KIKAKUI SYLLABLE M020 SA;Lo;0;R;;;;;N;;;;; +1E830;MENDE KIKAKUI SYLLABLE M021 SU;Lo;0;R;;;;;N;;;;; +1E831;MENDE KIKAKUI SYLLABLE M162 SEE;Lo;0;R;;;;;N;;;;; +1E832;MENDE KIKAKUI SYLLABLE M116 SE;Lo;0;R;;;;;N;;;;; +1E833;MENDE KIKAKUI SYLLABLE M136 SOO;Lo;0;R;;;;;N;;;;; +1E834;MENDE KIKAKUI SYLLABLE M079 SO;Lo;0;R;;;;;N;;;;; +1E835;MENDE KIKAKUI SYLLABLE M196 SIA;Lo;0;R;;;;;N;;;;; +1E836;MENDE KIKAKUI SYLLABLE M025 LI;Lo;0;R;;;;;N;;;;; +1E837;MENDE KIKAKUI SYLLABLE M026 LA;Lo;0;R;;;;;N;;;;; +1E838;MENDE KIKAKUI SYLLABLE M027 LU;Lo;0;R;;;;;N;;;;; +1E839;MENDE KIKAKUI SYLLABLE M084 LEE;Lo;0;R;;;;;N;;;;; +1E83A;MENDE KIKAKUI SYLLABLE M073 LE;Lo;0;R;;;;;N;;;;; +1E83B;MENDE KIKAKUI SYLLABLE M054 LOO;Lo;0;R;;;;;N;;;;; +1E83C;MENDE KIKAKUI SYLLABLE M153 LO;Lo;0;R;;;;;N;;;;; +1E83D;MENDE KIKAKUI SYLLABLE M110 LONG LE;Lo;0;R;;;;;N;;;;; +1E83E;MENDE KIKAKUI SYLLABLE M016 DI;Lo;0;R;;;;;N;;;;; +1E83F;MENDE KIKAKUI SYLLABLE M017 DA;Lo;0;R;;;;;N;;;;; +1E840;MENDE KIKAKUI SYLLABLE M018 DU;Lo;0;R;;;;;N;;;;; +1E841;MENDE KIKAKUI SYLLABLE M089 DEE;Lo;0;R;;;;;N;;;;; +1E842;MENDE KIKAKUI SYLLABLE M180 DOO;Lo;0;R;;;;;N;;;;; +1E843;MENDE KIKAKUI SYLLABLE M181 DO;Lo;0;R;;;;;N;;;;; +1E844;MENDE KIKAKUI SYLLABLE M022 TI;Lo;0;R;;;;;N;;;;; +1E845;MENDE KIKAKUI SYLLABLE M023 TA;Lo;0;R;;;;;N;;;;; +1E846;MENDE KIKAKUI SYLLABLE M024 TU;Lo;0;R;;;;;N;;;;; +1E847;MENDE KIKAKUI SYLLABLE M091 TEE;Lo;0;R;;;;;N;;;;; +1E848;MENDE KIKAKUI SYLLABLE M055 TE;Lo;0;R;;;;;N;;;;; +1E849;MENDE KIKAKUI SYLLABLE M104 TOO;Lo;0;R;;;;;N;;;;; +1E84A;MENDE KIKAKUI SYLLABLE M069 TO;Lo;0;R;;;;;N;;;;; +1E84B;MENDE KIKAKUI SYLLABLE M028 JI;Lo;0;R;;;;;N;;;;; +1E84C;MENDE KIKAKUI SYLLABLE M029 JA;Lo;0;R;;;;;N;;;;; +1E84D;MENDE KIKAKUI SYLLABLE M030 JU;Lo;0;R;;;;;N;;;;; +1E84E;MENDE KIKAKUI SYLLABLE M157 JEE;Lo;0;R;;;;;N;;;;; +1E84F;MENDE KIKAKUI SYLLABLE M113 JE;Lo;0;R;;;;;N;;;;; +1E850;MENDE KIKAKUI SYLLABLE M160 JOO;Lo;0;R;;;;;N;;;;; +1E851;MENDE KIKAKUI SYLLABLE M063 JO;Lo;0;R;;;;;N;;;;; +1E852;MENDE KIKAKUI SYLLABLE M175 LONG JO;Lo;0;R;;;;;N;;;;; +1E853;MENDE KIKAKUI SYLLABLE M031 YI;Lo;0;R;;;;;N;;;;; +1E854;MENDE KIKAKUI SYLLABLE M032 YA;Lo;0;R;;;;;N;;;;; +1E855;MENDE KIKAKUI SYLLABLE M033 YU;Lo;0;R;;;;;N;;;;; +1E856;MENDE KIKAKUI SYLLABLE M109 YEE;Lo;0;R;;;;;N;;;;; +1E857;MENDE KIKAKUI SYLLABLE M080 YE;Lo;0;R;;;;;N;;;;; +1E858;MENDE KIKAKUI SYLLABLE M141 YOO;Lo;0;R;;;;;N;;;;; +1E859;MENDE KIKAKUI SYLLABLE M121 YO;Lo;0;R;;;;;N;;;;; +1E85A;MENDE KIKAKUI SYLLABLE M034 FI;Lo;0;R;;;;;N;;;;; +1E85B;MENDE KIKAKUI SYLLABLE M035 FA;Lo;0;R;;;;;N;;;;; +1E85C;MENDE KIKAKUI SYLLABLE M036 FU;Lo;0;R;;;;;N;;;;; +1E85D;MENDE KIKAKUI SYLLABLE M078 FEE;Lo;0;R;;;;;N;;;;; +1E85E;MENDE KIKAKUI SYLLABLE M075 FE;Lo;0;R;;;;;N;;;;; +1E85F;MENDE KIKAKUI SYLLABLE M133 FOO;Lo;0;R;;;;;N;;;;; +1E860;MENDE KIKAKUI SYLLABLE M088 FO;Lo;0;R;;;;;N;;;;; +1E861;MENDE KIKAKUI SYLLABLE M197 FUA;Lo;0;R;;;;;N;;;;; +1E862;MENDE KIKAKUI SYLLABLE M101 FAN;Lo;0;R;;;;;N;;;;; +1E863;MENDE KIKAKUI SYLLABLE M037 NIN;Lo;0;R;;;;;N;;;;; +1E864;MENDE KIKAKUI SYLLABLE M038 NAN;Lo;0;R;;;;;N;;;;; +1E865;MENDE KIKAKUI SYLLABLE M039 NUN;Lo;0;R;;;;;N;;;;; +1E866;MENDE KIKAKUI SYLLABLE M117 NEN;Lo;0;R;;;;;N;;;;; +1E867;MENDE KIKAKUI SYLLABLE M169 NON;Lo;0;R;;;;;N;;;;; +1E868;MENDE KIKAKUI SYLLABLE M176 HI;Lo;0;R;;;;;N;;;;; +1E869;MENDE KIKAKUI SYLLABLE M041 HA;Lo;0;R;;;;;N;;;;; +1E86A;MENDE KIKAKUI SYLLABLE M186 HU;Lo;0;R;;;;;N;;;;; +1E86B;MENDE KIKAKUI SYLLABLE M040 HEE;Lo;0;R;;;;;N;;;;; +1E86C;MENDE KIKAKUI SYLLABLE M096 HE;Lo;0;R;;;;;N;;;;; +1E86D;MENDE KIKAKUI SYLLABLE M042 HOO;Lo;0;R;;;;;N;;;;; +1E86E;MENDE KIKAKUI SYLLABLE M140 HO;Lo;0;R;;;;;N;;;;; +1E86F;MENDE KIKAKUI SYLLABLE M083 HEEI;Lo;0;R;;;;;N;;;;; +1E870;MENDE KIKAKUI SYLLABLE M128 HOOU;Lo;0;R;;;;;N;;;;; +1E871;MENDE KIKAKUI SYLLABLE M053 HIN;Lo;0;R;;;;;N;;;;; +1E872;MENDE KIKAKUI SYLLABLE M130 HAN;Lo;0;R;;;;;N;;;;; +1E873;MENDE KIKAKUI SYLLABLE M087 HUN;Lo;0;R;;;;;N;;;;; +1E874;MENDE KIKAKUI SYLLABLE M052 HEN;Lo;0;R;;;;;N;;;;; +1E875;MENDE KIKAKUI SYLLABLE M193 HON;Lo;0;R;;;;;N;;;;; +1E876;MENDE KIKAKUI SYLLABLE M046 HUAN;Lo;0;R;;;;;N;;;;; +1E877;MENDE KIKAKUI SYLLABLE M090 NGGI;Lo;0;R;;;;;N;;;;; +1E878;MENDE KIKAKUI SYLLABLE M043 NGGA;Lo;0;R;;;;;N;;;;; +1E879;MENDE KIKAKUI SYLLABLE M082 NGGU;Lo;0;R;;;;;N;;;;; +1E87A;MENDE KIKAKUI SYLLABLE M115 NGGEE;Lo;0;R;;;;;N;;;;; +1E87B;MENDE KIKAKUI SYLLABLE M146 NGGE;Lo;0;R;;;;;N;;;;; +1E87C;MENDE KIKAKUI SYLLABLE M156 NGGOO;Lo;0;R;;;;;N;;;;; +1E87D;MENDE KIKAKUI SYLLABLE M120 NGGO;Lo;0;R;;;;;N;;;;; +1E87E;MENDE KIKAKUI SYLLABLE M159 NGGAA;Lo;0;R;;;;;N;;;;; +1E87F;MENDE KIKAKUI SYLLABLE M127 NGGUA;Lo;0;R;;;;;N;;;;; +1E880;MENDE KIKAKUI SYLLABLE M086 LONG NGGE;Lo;0;R;;;;;N;;;;; +1E881;MENDE KIKAKUI SYLLABLE M106 LONG NGGOO;Lo;0;R;;;;;N;;;;; +1E882;MENDE KIKAKUI SYLLABLE M183 LONG NGGO;Lo;0;R;;;;;N;;;;; +1E883;MENDE KIKAKUI SYLLABLE M155 GI;Lo;0;R;;;;;N;;;;; +1E884;MENDE KIKAKUI SYLLABLE M111 GA;Lo;0;R;;;;;N;;;;; +1E885;MENDE KIKAKUI SYLLABLE M168 GU;Lo;0;R;;;;;N;;;;; +1E886;MENDE KIKAKUI SYLLABLE M190 GEE;Lo;0;R;;;;;N;;;;; +1E887;MENDE KIKAKUI SYLLABLE M166 GUEI;Lo;0;R;;;;;N;;;;; +1E888;MENDE KIKAKUI SYLLABLE M167 GUAN;Lo;0;R;;;;;N;;;;; +1E889;MENDE KIKAKUI SYLLABLE M184 NGEN;Lo;0;R;;;;;N;;;;; +1E88A;MENDE KIKAKUI SYLLABLE M057 NGON;Lo;0;R;;;;;N;;;;; +1E88B;MENDE KIKAKUI SYLLABLE M177 NGUAN;Lo;0;R;;;;;N;;;;; +1E88C;MENDE KIKAKUI SYLLABLE M068 PI;Lo;0;R;;;;;N;;;;; +1E88D;MENDE KIKAKUI SYLLABLE M099 PA;Lo;0;R;;;;;N;;;;; +1E88E;MENDE KIKAKUI SYLLABLE M050 PU;Lo;0;R;;;;;N;;;;; +1E88F;MENDE KIKAKUI SYLLABLE M081 PEE;Lo;0;R;;;;;N;;;;; +1E890;MENDE KIKAKUI SYLLABLE M051 PE;Lo;0;R;;;;;N;;;;; +1E891;MENDE KIKAKUI SYLLABLE M102 POO;Lo;0;R;;;;;N;;;;; +1E892;MENDE KIKAKUI SYLLABLE M066 PO;Lo;0;R;;;;;N;;;;; +1E893;MENDE KIKAKUI SYLLABLE M145 MBI;Lo;0;R;;;;;N;;;;; +1E894;MENDE KIKAKUI SYLLABLE M062 MBA;Lo;0;R;;;;;N;;;;; +1E895;MENDE KIKAKUI SYLLABLE M122 MBU;Lo;0;R;;;;;N;;;;; +1E896;MENDE KIKAKUI SYLLABLE M047 MBEE;Lo;0;R;;;;;N;;;;; +1E897;MENDE KIKAKUI SYLLABLE M188 MBEE;Lo;0;R;;;;;N;;;;; +1E898;MENDE KIKAKUI SYLLABLE M072 MBE;Lo;0;R;;;;;N;;;;; +1E899;MENDE KIKAKUI SYLLABLE M172 MBOO;Lo;0;R;;;;;N;;;;; +1E89A;MENDE KIKAKUI SYLLABLE M174 MBO;Lo;0;R;;;;;N;;;;; +1E89B;MENDE KIKAKUI SYLLABLE M187 MBUU;Lo;0;R;;;;;N;;;;; +1E89C;MENDE KIKAKUI SYLLABLE M161 LONG MBE;Lo;0;R;;;;;N;;;;; +1E89D;MENDE KIKAKUI SYLLABLE M105 LONG MBOO;Lo;0;R;;;;;N;;;;; +1E89E;MENDE KIKAKUI SYLLABLE M142 LONG MBO;Lo;0;R;;;;;N;;;;; +1E89F;MENDE KIKAKUI SYLLABLE M132 KPI;Lo;0;R;;;;;N;;;;; +1E8A0;MENDE KIKAKUI SYLLABLE M092 KPA;Lo;0;R;;;;;N;;;;; +1E8A1;MENDE KIKAKUI SYLLABLE M074 KPU;Lo;0;R;;;;;N;;;;; +1E8A2;MENDE KIKAKUI SYLLABLE M044 KPEE;Lo;0;R;;;;;N;;;;; +1E8A3;MENDE KIKAKUI SYLLABLE M108 KPE;Lo;0;R;;;;;N;;;;; +1E8A4;MENDE KIKAKUI SYLLABLE M112 KPOO;Lo;0;R;;;;;N;;;;; +1E8A5;MENDE KIKAKUI SYLLABLE M158 KPO;Lo;0;R;;;;;N;;;;; +1E8A6;MENDE KIKAKUI SYLLABLE M124 GBI;Lo;0;R;;;;;N;;;;; +1E8A7;MENDE KIKAKUI SYLLABLE M056 GBA;Lo;0;R;;;;;N;;;;; +1E8A8;MENDE KIKAKUI SYLLABLE M148 GBU;Lo;0;R;;;;;N;;;;; +1E8A9;MENDE KIKAKUI SYLLABLE M093 GBEE;Lo;0;R;;;;;N;;;;; +1E8AA;MENDE KIKAKUI SYLLABLE M107 GBE;Lo;0;R;;;;;N;;;;; +1E8AB;MENDE KIKAKUI SYLLABLE M071 GBOO;Lo;0;R;;;;;N;;;;; +1E8AC;MENDE KIKAKUI SYLLABLE M070 GBO;Lo;0;R;;;;;N;;;;; +1E8AD;MENDE KIKAKUI SYLLABLE M171 RA;Lo;0;R;;;;;N;;;;; +1E8AE;MENDE KIKAKUI SYLLABLE M123 NDI;Lo;0;R;;;;;N;;;;; +1E8AF;MENDE KIKAKUI SYLLABLE M129 NDA;Lo;0;R;;;;;N;;;;; +1E8B0;MENDE KIKAKUI SYLLABLE M125 NDU;Lo;0;R;;;;;N;;;;; +1E8B1;MENDE KIKAKUI SYLLABLE M191 NDEE;Lo;0;R;;;;;N;;;;; +1E8B2;MENDE KIKAKUI SYLLABLE M119 NDE;Lo;0;R;;;;;N;;;;; +1E8B3;MENDE KIKAKUI SYLLABLE M067 NDOO;Lo;0;R;;;;;N;;;;; +1E8B4;MENDE KIKAKUI SYLLABLE M064 NDO;Lo;0;R;;;;;N;;;;; +1E8B5;MENDE KIKAKUI SYLLABLE M152 NJA;Lo;0;R;;;;;N;;;;; +1E8B6;MENDE KIKAKUI SYLLABLE M192 NJU;Lo;0;R;;;;;N;;;;; +1E8B7;MENDE KIKAKUI SYLLABLE M149 NJEE;Lo;0;R;;;;;N;;;;; +1E8B8;MENDE KIKAKUI SYLLABLE M134 NJOO;Lo;0;R;;;;;N;;;;; +1E8B9;MENDE KIKAKUI SYLLABLE M182 VI;Lo;0;R;;;;;N;;;;; +1E8BA;MENDE KIKAKUI SYLLABLE M185 VA;Lo;0;R;;;;;N;;;;; +1E8BB;MENDE KIKAKUI SYLLABLE M151 VU;Lo;0;R;;;;;N;;;;; +1E8BC;MENDE KIKAKUI SYLLABLE M173 VEE;Lo;0;R;;;;;N;;;;; +1E8BD;MENDE KIKAKUI SYLLABLE M085 VE;Lo;0;R;;;;;N;;;;; +1E8BE;MENDE KIKAKUI SYLLABLE M144 VOO;Lo;0;R;;;;;N;;;;; +1E8BF;MENDE KIKAKUI SYLLABLE M077 VO;Lo;0;R;;;;;N;;;;; +1E8C0;MENDE KIKAKUI SYLLABLE M164 NYIN;Lo;0;R;;;;;N;;;;; +1E8C1;MENDE KIKAKUI SYLLABLE M058 NYAN;Lo;0;R;;;;;N;;;;; +1E8C2;MENDE KIKAKUI SYLLABLE M170 NYUN;Lo;0;R;;;;;N;;;;; +1E8C3;MENDE KIKAKUI SYLLABLE M098 NYEN;Lo;0;R;;;;;N;;;;; +1E8C4;MENDE KIKAKUI SYLLABLE M060 NYON;Lo;0;R;;;;;N;;;;; +1E8C7;MENDE KIKAKUI DIGIT ONE;No;0;R;;;;1;N;;;;; +1E8C8;MENDE KIKAKUI DIGIT TWO;No;0;R;;;;2;N;;;;; +1E8C9;MENDE KIKAKUI DIGIT THREE;No;0;R;;;;3;N;;;;; +1E8CA;MENDE KIKAKUI DIGIT FOUR;No;0;R;;;;4;N;;;;; +1E8CB;MENDE KIKAKUI DIGIT FIVE;No;0;R;;;;5;N;;;;; +1E8CC;MENDE KIKAKUI DIGIT SIX;No;0;R;;;;6;N;;;;; +1E8CD;MENDE KIKAKUI DIGIT SEVEN;No;0;R;;;;7;N;;;;; +1E8CE;MENDE KIKAKUI DIGIT EIGHT;No;0;R;;;;8;N;;;;; +1E8CF;MENDE KIKAKUI DIGIT NINE;No;0;R;;;;9;N;;;;; +1E8D0;MENDE KIKAKUI COMBINING NUMBER TEENS;Mn;220;NSM;;;;;N;;;;; +1E8D1;MENDE KIKAKUI COMBINING NUMBER TENS;Mn;220;NSM;;;;;N;;;;; +1E8D2;MENDE KIKAKUI COMBINING NUMBER HUNDREDS;Mn;220;NSM;;;;;N;;;;; +1E8D3;MENDE KIKAKUI COMBINING NUMBER THOUSANDS;Mn;220;NSM;;;;;N;;;;; +1E8D4;MENDE KIKAKUI COMBINING NUMBER TEN THOUSANDS;Mn;220;NSM;;;;;N;;;;; +1E8D5;MENDE KIKAKUI COMBINING NUMBER HUNDRED THOUSANDS;Mn;220;NSM;;;;;N;;;;; +1E8D6;MENDE KIKAKUI COMBINING NUMBER MILLIONS;Mn;220;NSM;;;;;N;;;;; +1E900;ADLAM CAPITAL LETTER ALIF;Lu;0;R;;;;;N;;;;1E922; +1E901;ADLAM CAPITAL LETTER DAALI;Lu;0;R;;;;;N;;;;1E923; +1E902;ADLAM CAPITAL LETTER LAAM;Lu;0;R;;;;;N;;;;1E924; +1E903;ADLAM CAPITAL LETTER MIIM;Lu;0;R;;;;;N;;;;1E925; +1E904;ADLAM CAPITAL LETTER BA;Lu;0;R;;;;;N;;;;1E926; +1E905;ADLAM CAPITAL LETTER SINNYIIYHE;Lu;0;R;;;;;N;;;;1E927; +1E906;ADLAM CAPITAL LETTER PE;Lu;0;R;;;;;N;;;;1E928; +1E907;ADLAM CAPITAL LETTER BHE;Lu;0;R;;;;;N;;;;1E929; +1E908;ADLAM CAPITAL LETTER RA;Lu;0;R;;;;;N;;;;1E92A; +1E909;ADLAM CAPITAL LETTER E;Lu;0;R;;;;;N;;;;1E92B; +1E90A;ADLAM CAPITAL LETTER FA;Lu;0;R;;;;;N;;;;1E92C; +1E90B;ADLAM CAPITAL LETTER I;Lu;0;R;;;;;N;;;;1E92D; +1E90C;ADLAM CAPITAL LETTER O;Lu;0;R;;;;;N;;;;1E92E; +1E90D;ADLAM CAPITAL LETTER DHA;Lu;0;R;;;;;N;;;;1E92F; +1E90E;ADLAM CAPITAL LETTER YHE;Lu;0;R;;;;;N;;;;1E930; +1E90F;ADLAM CAPITAL LETTER WAW;Lu;0;R;;;;;N;;;;1E931; +1E910;ADLAM CAPITAL LETTER NUN;Lu;0;R;;;;;N;;;;1E932; +1E911;ADLAM CAPITAL LETTER KAF;Lu;0;R;;;;;N;;;;1E933; +1E912;ADLAM CAPITAL LETTER YA;Lu;0;R;;;;;N;;;;1E934; +1E913;ADLAM CAPITAL LETTER U;Lu;0;R;;;;;N;;;;1E935; +1E914;ADLAM CAPITAL LETTER JIIM;Lu;0;R;;;;;N;;;;1E936; +1E915;ADLAM CAPITAL LETTER CHI;Lu;0;R;;;;;N;;;;1E937; +1E916;ADLAM CAPITAL LETTER HA;Lu;0;R;;;;;N;;;;1E938; +1E917;ADLAM CAPITAL LETTER QAAF;Lu;0;R;;;;;N;;;;1E939; +1E918;ADLAM CAPITAL LETTER GA;Lu;0;R;;;;;N;;;;1E93A; +1E919;ADLAM CAPITAL LETTER NYA;Lu;0;R;;;;;N;;;;1E93B; +1E91A;ADLAM CAPITAL LETTER TU;Lu;0;R;;;;;N;;;;1E93C; +1E91B;ADLAM CAPITAL LETTER NHA;Lu;0;R;;;;;N;;;;1E93D; +1E91C;ADLAM CAPITAL LETTER VA;Lu;0;R;;;;;N;;;;1E93E; +1E91D;ADLAM CAPITAL LETTER KHA;Lu;0;R;;;;;N;;;;1E93F; +1E91E;ADLAM CAPITAL LETTER GBE;Lu;0;R;;;;;N;;;;1E940; +1E91F;ADLAM CAPITAL LETTER ZAL;Lu;0;R;;;;;N;;;;1E941; +1E920;ADLAM CAPITAL LETTER KPO;Lu;0;R;;;;;N;;;;1E942; +1E921;ADLAM CAPITAL LETTER SHA;Lu;0;R;;;;;N;;;;1E943; +1E922;ADLAM SMALL LETTER ALIF;Ll;0;R;;;;;N;;;1E900;;1E900 +1E923;ADLAM SMALL LETTER DAALI;Ll;0;R;;;;;N;;;1E901;;1E901 +1E924;ADLAM SMALL LETTER LAAM;Ll;0;R;;;;;N;;;1E902;;1E902 +1E925;ADLAM SMALL LETTER MIIM;Ll;0;R;;;;;N;;;1E903;;1E903 +1E926;ADLAM SMALL LETTER BA;Ll;0;R;;;;;N;;;1E904;;1E904 +1E927;ADLAM SMALL LETTER SINNYIIYHE;Ll;0;R;;;;;N;;;1E905;;1E905 +1E928;ADLAM SMALL LETTER PE;Ll;0;R;;;;;N;;;1E906;;1E906 +1E929;ADLAM SMALL LETTER BHE;Ll;0;R;;;;;N;;;1E907;;1E907 +1E92A;ADLAM SMALL LETTER RA;Ll;0;R;;;;;N;;;1E908;;1E908 +1E92B;ADLAM SMALL LETTER E;Ll;0;R;;;;;N;;;1E909;;1E909 +1E92C;ADLAM SMALL LETTER FA;Ll;0;R;;;;;N;;;1E90A;;1E90A +1E92D;ADLAM SMALL LETTER I;Ll;0;R;;;;;N;;;1E90B;;1E90B +1E92E;ADLAM SMALL LETTER O;Ll;0;R;;;;;N;;;1E90C;;1E90C +1E92F;ADLAM SMALL LETTER DHA;Ll;0;R;;;;;N;;;1E90D;;1E90D +1E930;ADLAM SMALL LETTER YHE;Ll;0;R;;;;;N;;;1E90E;;1E90E +1E931;ADLAM SMALL LETTER WAW;Ll;0;R;;;;;N;;;1E90F;;1E90F +1E932;ADLAM SMALL LETTER NUN;Ll;0;R;;;;;N;;;1E910;;1E910 +1E933;ADLAM SMALL LETTER KAF;Ll;0;R;;;;;N;;;1E911;;1E911 +1E934;ADLAM SMALL LETTER YA;Ll;0;R;;;;;N;;;1E912;;1E912 +1E935;ADLAM SMALL LETTER U;Ll;0;R;;;;;N;;;1E913;;1E913 +1E936;ADLAM SMALL LETTER JIIM;Ll;0;R;;;;;N;;;1E914;;1E914 +1E937;ADLAM SMALL LETTER CHI;Ll;0;R;;;;;N;;;1E915;;1E915 +1E938;ADLAM SMALL LETTER HA;Ll;0;R;;;;;N;;;1E916;;1E916 +1E939;ADLAM SMALL LETTER QAAF;Ll;0;R;;;;;N;;;1E917;;1E917 +1E93A;ADLAM SMALL LETTER GA;Ll;0;R;;;;;N;;;1E918;;1E918 +1E93B;ADLAM SMALL LETTER NYA;Ll;0;R;;;;;N;;;1E919;;1E919 +1E93C;ADLAM SMALL LETTER TU;Ll;0;R;;;;;N;;;1E91A;;1E91A +1E93D;ADLAM SMALL LETTER NHA;Ll;0;R;;;;;N;;;1E91B;;1E91B +1E93E;ADLAM SMALL LETTER VA;Ll;0;R;;;;;N;;;1E91C;;1E91C +1E93F;ADLAM SMALL LETTER KHA;Ll;0;R;;;;;N;;;1E91D;;1E91D +1E940;ADLAM SMALL LETTER GBE;Ll;0;R;;;;;N;;;1E91E;;1E91E +1E941;ADLAM SMALL LETTER ZAL;Ll;0;R;;;;;N;;;1E91F;;1E91F +1E942;ADLAM SMALL LETTER KPO;Ll;0;R;;;;;N;;;1E920;;1E920 +1E943;ADLAM SMALL LETTER SHA;Ll;0;R;;;;;N;;;1E921;;1E921 +1E944;ADLAM ALIF LENGTHENER;Mn;230;NSM;;;;;N;;;;; +1E945;ADLAM VOWEL LENGTHENER;Mn;230;NSM;;;;;N;;;;; +1E946;ADLAM GEMINATION MARK;Mn;230;NSM;;;;;N;;;;; +1E947;ADLAM HAMZA;Mn;230;NSM;;;;;N;;;;; +1E948;ADLAM CONSONANT MODIFIER;Mn;230;NSM;;;;;N;;;;; +1E949;ADLAM GEMINATE CONSONANT MODIFIER;Mn;230;NSM;;;;;N;;;;; +1E94A;ADLAM NUKTA;Mn;7;NSM;;;;;N;;;;; +1E94B;ADLAM NASALIZATION MARK;Lm;0;R;;;;;N;;;;; +1E950;ADLAM DIGIT ZERO;Nd;0;R;;0;0;0;N;;;;; +1E951;ADLAM DIGIT ONE;Nd;0;R;;1;1;1;N;;;;; +1E952;ADLAM DIGIT TWO;Nd;0;R;;2;2;2;N;;;;; +1E953;ADLAM DIGIT THREE;Nd;0;R;;3;3;3;N;;;;; +1E954;ADLAM DIGIT FOUR;Nd;0;R;;4;4;4;N;;;;; +1E955;ADLAM DIGIT FIVE;Nd;0;R;;5;5;5;N;;;;; +1E956;ADLAM DIGIT SIX;Nd;0;R;;6;6;6;N;;;;; +1E957;ADLAM DIGIT SEVEN;Nd;0;R;;7;7;7;N;;;;; +1E958;ADLAM DIGIT EIGHT;Nd;0;R;;8;8;8;N;;;;; +1E959;ADLAM DIGIT NINE;Nd;0;R;;9;9;9;N;;;;; +1E95E;ADLAM INITIAL EXCLAMATION MARK;Po;0;R;;;;;N;;;;; +1E95F;ADLAM INITIAL QUESTION MARK;Po;0;R;;;;;N;;;;; +1EC71;INDIC SIYAQ NUMBER ONE;No;0;AL;;;;1;N;;;;; +1EC72;INDIC SIYAQ NUMBER TWO;No;0;AL;;;;2;N;;;;; +1EC73;INDIC SIYAQ NUMBER THREE;No;0;AL;;;;3;N;;;;; +1EC74;INDIC SIYAQ NUMBER FOUR;No;0;AL;;;;4;N;;;;; +1EC75;INDIC SIYAQ NUMBER FIVE;No;0;AL;;;;5;N;;;;; +1EC76;INDIC SIYAQ NUMBER SIX;No;0;AL;;;;6;N;;;;; +1EC77;INDIC SIYAQ NUMBER SEVEN;No;0;AL;;;;7;N;;;;; +1EC78;INDIC SIYAQ NUMBER EIGHT;No;0;AL;;;;8;N;;;;; +1EC79;INDIC SIYAQ NUMBER NINE;No;0;AL;;;;9;N;;;;; +1EC7A;INDIC SIYAQ NUMBER TEN;No;0;AL;;;;10;N;;;;; +1EC7B;INDIC SIYAQ NUMBER TWENTY;No;0;AL;;;;20;N;;;;; +1EC7C;INDIC SIYAQ NUMBER THIRTY;No;0;AL;;;;30;N;;;;; +1EC7D;INDIC SIYAQ NUMBER FORTY;No;0;AL;;;;40;N;;;;; +1EC7E;INDIC SIYAQ NUMBER FIFTY;No;0;AL;;;;50;N;;;;; +1EC7F;INDIC SIYAQ NUMBER SIXTY;No;0;AL;;;;60;N;;;;; +1EC80;INDIC SIYAQ NUMBER SEVENTY;No;0;AL;;;;70;N;;;;; +1EC81;INDIC SIYAQ NUMBER EIGHTY;No;0;AL;;;;80;N;;;;; +1EC82;INDIC SIYAQ NUMBER NINETY;No;0;AL;;;;90;N;;;;; +1EC83;INDIC SIYAQ NUMBER ONE HUNDRED;No;0;AL;;;;100;N;;;;; +1EC84;INDIC SIYAQ NUMBER TWO HUNDRED;No;0;AL;;;;200;N;;;;; +1EC85;INDIC SIYAQ NUMBER THREE HUNDRED;No;0;AL;;;;300;N;;;;; +1EC86;INDIC SIYAQ NUMBER FOUR HUNDRED;No;0;AL;;;;400;N;;;;; +1EC87;INDIC SIYAQ NUMBER FIVE HUNDRED;No;0;AL;;;;500;N;;;;; +1EC88;INDIC SIYAQ NUMBER SIX HUNDRED;No;0;AL;;;;600;N;;;;; +1EC89;INDIC SIYAQ NUMBER SEVEN HUNDRED;No;0;AL;;;;700;N;;;;; +1EC8A;INDIC SIYAQ NUMBER EIGHT HUNDRED;No;0;AL;;;;800;N;;;;; +1EC8B;INDIC SIYAQ NUMBER NINE HUNDRED;No;0;AL;;;;900;N;;;;; +1EC8C;INDIC SIYAQ NUMBER ONE THOUSAND;No;0;AL;;;;1000;N;;;;; +1EC8D;INDIC SIYAQ NUMBER TWO THOUSAND;No;0;AL;;;;2000;N;;;;; +1EC8E;INDIC SIYAQ NUMBER THREE THOUSAND;No;0;AL;;;;3000;N;;;;; +1EC8F;INDIC SIYAQ NUMBER FOUR THOUSAND;No;0;AL;;;;4000;N;;;;; +1EC90;INDIC SIYAQ NUMBER FIVE THOUSAND;No;0;AL;;;;5000;N;;;;; +1EC91;INDIC SIYAQ NUMBER SIX THOUSAND;No;0;AL;;;;6000;N;;;;; +1EC92;INDIC SIYAQ NUMBER SEVEN THOUSAND;No;0;AL;;;;7000;N;;;;; +1EC93;INDIC SIYAQ NUMBER EIGHT THOUSAND;No;0;AL;;;;8000;N;;;;; +1EC94;INDIC SIYAQ NUMBER NINE THOUSAND;No;0;AL;;;;9000;N;;;;; +1EC95;INDIC SIYAQ NUMBER TEN THOUSAND;No;0;AL;;;;10000;N;;;;; +1EC96;INDIC SIYAQ NUMBER TWENTY THOUSAND;No;0;AL;;;;20000;N;;;;; +1EC97;INDIC SIYAQ NUMBER THIRTY THOUSAND;No;0;AL;;;;30000;N;;;;; +1EC98;INDIC SIYAQ NUMBER FORTY THOUSAND;No;0;AL;;;;40000;N;;;;; +1EC99;INDIC SIYAQ NUMBER FIFTY THOUSAND;No;0;AL;;;;50000;N;;;;; +1EC9A;INDIC SIYAQ NUMBER SIXTY THOUSAND;No;0;AL;;;;60000;N;;;;; +1EC9B;INDIC SIYAQ NUMBER SEVENTY THOUSAND;No;0;AL;;;;70000;N;;;;; +1EC9C;INDIC SIYAQ NUMBER EIGHTY THOUSAND;No;0;AL;;;;80000;N;;;;; +1EC9D;INDIC SIYAQ NUMBER NINETY THOUSAND;No;0;AL;;;;90000;N;;;;; +1EC9E;INDIC SIYAQ NUMBER LAKH;No;0;AL;;;;100000;N;;;;; +1EC9F;INDIC SIYAQ NUMBER LAKHAN;No;0;AL;;;;200000;N;;;;; +1ECA0;INDIC SIYAQ LAKH MARK;No;0;AL;;;;100000;N;;;;; +1ECA1;INDIC SIYAQ NUMBER KAROR;No;0;AL;;;;10000000;N;;;;; +1ECA2;INDIC SIYAQ NUMBER KARORAN;No;0;AL;;;;20000000;N;;;;; +1ECA3;INDIC SIYAQ NUMBER PREFIXED ONE;No;0;AL;;;;1;N;;;;; +1ECA4;INDIC SIYAQ NUMBER PREFIXED TWO;No;0;AL;;;;2;N;;;;; +1ECA5;INDIC SIYAQ NUMBER PREFIXED THREE;No;0;AL;;;;3;N;;;;; +1ECA6;INDIC SIYAQ NUMBER PREFIXED FOUR;No;0;AL;;;;4;N;;;;; +1ECA7;INDIC SIYAQ NUMBER PREFIXED FIVE;No;0;AL;;;;5;N;;;;; +1ECA8;INDIC SIYAQ NUMBER PREFIXED SIX;No;0;AL;;;;6;N;;;;; +1ECA9;INDIC SIYAQ NUMBER PREFIXED SEVEN;No;0;AL;;;;7;N;;;;; +1ECAA;INDIC SIYAQ NUMBER PREFIXED EIGHT;No;0;AL;;;;8;N;;;;; +1ECAB;INDIC SIYAQ NUMBER PREFIXED NINE;No;0;AL;;;;9;N;;;;; +1ECAC;INDIC SIYAQ PLACEHOLDER;So;0;AL;;;;;N;;;;; +1ECAD;INDIC SIYAQ FRACTION ONE QUARTER;No;0;AL;;;;1/4;N;;;;; +1ECAE;INDIC SIYAQ FRACTION ONE HALF;No;0;AL;;;;1/2;N;;;;; +1ECAF;INDIC SIYAQ FRACTION THREE QUARTERS;No;0;AL;;;;3/4;N;;;;; +1ECB0;INDIC SIYAQ RUPEE MARK;Sc;0;AL;;;;;N;;;;; +1ECB1;INDIC SIYAQ NUMBER ALTERNATE ONE;No;0;AL;;;;1;N;;;;; +1ECB2;INDIC SIYAQ NUMBER ALTERNATE TWO;No;0;AL;;;;2;N;;;;; +1ECB3;INDIC SIYAQ NUMBER ALTERNATE TEN THOUSAND;No;0;AL;;;;10000;N;;;;; +1ECB4;INDIC SIYAQ ALTERNATE LAKH MARK;No;0;AL;;;;100000;N;;;;; +1ED01;OTTOMAN SIYAQ NUMBER ONE;No;0;AL;;;;1;N;;;;; +1ED02;OTTOMAN SIYAQ NUMBER TWO;No;0;AL;;;;2;N;;;;; +1ED03;OTTOMAN SIYAQ NUMBER THREE;No;0;AL;;;;3;N;;;;; +1ED04;OTTOMAN SIYAQ NUMBER FOUR;No;0;AL;;;;4;N;;;;; +1ED05;OTTOMAN SIYAQ NUMBER FIVE;No;0;AL;;;;5;N;;;;; +1ED06;OTTOMAN SIYAQ NUMBER SIX;No;0;AL;;;;6;N;;;;; +1ED07;OTTOMAN SIYAQ NUMBER SEVEN;No;0;AL;;;;7;N;;;;; +1ED08;OTTOMAN SIYAQ NUMBER EIGHT;No;0;AL;;;;8;N;;;;; +1ED09;OTTOMAN SIYAQ NUMBER NINE;No;0;AL;;;;9;N;;;;; +1ED0A;OTTOMAN SIYAQ NUMBER TEN;No;0;AL;;;;10;N;;;;; +1ED0B;OTTOMAN SIYAQ NUMBER TWENTY;No;0;AL;;;;20;N;;;;; +1ED0C;OTTOMAN SIYAQ NUMBER THIRTY;No;0;AL;;;;30;N;;;;; +1ED0D;OTTOMAN SIYAQ NUMBER FORTY;No;0;AL;;;;40;N;;;;; +1ED0E;OTTOMAN SIYAQ NUMBER FIFTY;No;0;AL;;;;50;N;;;;; +1ED0F;OTTOMAN SIYAQ NUMBER SIXTY;No;0;AL;;;;60;N;;;;; +1ED10;OTTOMAN SIYAQ NUMBER SEVENTY;No;0;AL;;;;70;N;;;;; +1ED11;OTTOMAN SIYAQ NUMBER EIGHTY;No;0;AL;;;;80;N;;;;; +1ED12;OTTOMAN SIYAQ NUMBER NINETY;No;0;AL;;;;90;N;;;;; +1ED13;OTTOMAN SIYAQ NUMBER ONE HUNDRED;No;0;AL;;;;100;N;;;;; +1ED14;OTTOMAN SIYAQ NUMBER TWO HUNDRED;No;0;AL;;;;200;N;;;;; +1ED15;OTTOMAN SIYAQ NUMBER THREE HUNDRED;No;0;AL;;;;300;N;;;;; +1ED16;OTTOMAN SIYAQ NUMBER FOUR HUNDRED;No;0;AL;;;;400;N;;;;; +1ED17;OTTOMAN SIYAQ NUMBER FIVE HUNDRED;No;0;AL;;;;500;N;;;;; +1ED18;OTTOMAN SIYAQ NUMBER SIX HUNDRED;No;0;AL;;;;600;N;;;;; +1ED19;OTTOMAN SIYAQ NUMBER SEVEN HUNDRED;No;0;AL;;;;700;N;;;;; +1ED1A;OTTOMAN SIYAQ NUMBER EIGHT HUNDRED;No;0;AL;;;;800;N;;;;; +1ED1B;OTTOMAN SIYAQ NUMBER NINE HUNDRED;No;0;AL;;;;900;N;;;;; +1ED1C;OTTOMAN SIYAQ NUMBER ONE THOUSAND;No;0;AL;;;;1000;N;;;;; +1ED1D;OTTOMAN SIYAQ NUMBER TWO THOUSAND;No;0;AL;;;;2000;N;;;;; +1ED1E;OTTOMAN SIYAQ NUMBER THREE THOUSAND;No;0;AL;;;;3000;N;;;;; +1ED1F;OTTOMAN SIYAQ NUMBER FOUR THOUSAND;No;0;AL;;;;4000;N;;;;; +1ED20;OTTOMAN SIYAQ NUMBER FIVE THOUSAND;No;0;AL;;;;5000;N;;;;; +1ED21;OTTOMAN SIYAQ NUMBER SIX THOUSAND;No;0;AL;;;;6000;N;;;;; +1ED22;OTTOMAN SIYAQ NUMBER SEVEN THOUSAND;No;0;AL;;;;7000;N;;;;; +1ED23;OTTOMAN SIYAQ NUMBER EIGHT THOUSAND;No;0;AL;;;;8000;N;;;;; +1ED24;OTTOMAN SIYAQ NUMBER NINE THOUSAND;No;0;AL;;;;9000;N;;;;; +1ED25;OTTOMAN SIYAQ NUMBER TEN THOUSAND;No;0;AL;;;;10000;N;;;;; +1ED26;OTTOMAN SIYAQ NUMBER TWENTY THOUSAND;No;0;AL;;;;20000;N;;;;; +1ED27;OTTOMAN SIYAQ NUMBER THIRTY THOUSAND;No;0;AL;;;;30000;N;;;;; +1ED28;OTTOMAN SIYAQ NUMBER FORTY THOUSAND;No;0;AL;;;;40000;N;;;;; +1ED29;OTTOMAN SIYAQ NUMBER FIFTY THOUSAND;No;0;AL;;;;50000;N;;;;; +1ED2A;OTTOMAN SIYAQ NUMBER SIXTY THOUSAND;No;0;AL;;;;60000;N;;;;; +1ED2B;OTTOMAN SIYAQ NUMBER SEVENTY THOUSAND;No;0;AL;;;;70000;N;;;;; +1ED2C;OTTOMAN SIYAQ NUMBER EIGHTY THOUSAND;No;0;AL;;;;80000;N;;;;; +1ED2D;OTTOMAN SIYAQ NUMBER NINETY THOUSAND;No;0;AL;;;;90000;N;;;;; +1ED2E;OTTOMAN SIYAQ MARRATAN;So;0;AL;;;;;N;;;;; +1ED2F;OTTOMAN SIYAQ ALTERNATE NUMBER TWO;No;0;AL;;;;2;N;;;;; +1ED30;OTTOMAN SIYAQ ALTERNATE NUMBER THREE;No;0;AL;;;;3;N;;;;; +1ED31;OTTOMAN SIYAQ ALTERNATE NUMBER FOUR;No;0;AL;;;;4;N;;;;; +1ED32;OTTOMAN SIYAQ ALTERNATE NUMBER FIVE;No;0;AL;;;;5;N;;;;; +1ED33;OTTOMAN SIYAQ ALTERNATE NUMBER SIX;No;0;AL;;;;6;N;;;;; +1ED34;OTTOMAN SIYAQ ALTERNATE NUMBER SEVEN;No;0;AL;;;;7;N;;;;; +1ED35;OTTOMAN SIYAQ ALTERNATE NUMBER EIGHT;No;0;AL;;;;8;N;;;;; +1ED36;OTTOMAN SIYAQ ALTERNATE NUMBER NINE;No;0;AL;;;;9;N;;;;; +1ED37;OTTOMAN SIYAQ ALTERNATE NUMBER TEN;No;0;AL;;;;10;N;;;;; +1ED38;OTTOMAN SIYAQ ALTERNATE NUMBER FOUR HUNDRED;No;0;AL;;;;400;N;;;;; +1ED39;OTTOMAN SIYAQ ALTERNATE NUMBER SIX HUNDRED;No;0;AL;;;;600;N;;;;; +1ED3A;OTTOMAN SIYAQ ALTERNATE NUMBER TWO THOUSAND;No;0;AL;;;;2000;N;;;;; +1ED3B;OTTOMAN SIYAQ ALTERNATE NUMBER TEN THOUSAND;No;0;AL;;;;10000;N;;;;; +1ED3C;OTTOMAN SIYAQ FRACTION ONE HALF;No;0;AL;;;;1/2;N;;;;; +1ED3D;OTTOMAN SIYAQ FRACTION ONE SIXTH;No;0;AL;;;;1/6;N;;;;; +1EE00;ARABIC MATHEMATICAL ALEF;Lo;0;AL; 0627;;;;N;;;;; +1EE01;ARABIC MATHEMATICAL BEH;Lo;0;AL; 0628;;;;N;;;;; +1EE02;ARABIC MATHEMATICAL JEEM;Lo;0;AL; 062C;;;;N;;;;; +1EE03;ARABIC MATHEMATICAL DAL;Lo;0;AL; 062F;;;;N;;;;; +1EE05;ARABIC MATHEMATICAL WAW;Lo;0;AL; 0648;;;;N;;;;; +1EE06;ARABIC MATHEMATICAL ZAIN;Lo;0;AL; 0632;;;;N;;;;; +1EE07;ARABIC MATHEMATICAL HAH;Lo;0;AL; 062D;;;;N;;;;; +1EE08;ARABIC MATHEMATICAL TAH;Lo;0;AL; 0637;;;;N;;;;; +1EE09;ARABIC MATHEMATICAL YEH;Lo;0;AL; 064A;;;;N;;;;; +1EE0A;ARABIC MATHEMATICAL KAF;Lo;0;AL; 0643;;;;N;;;;; +1EE0B;ARABIC MATHEMATICAL LAM;Lo;0;AL; 0644;;;;N;;;;; +1EE0C;ARABIC MATHEMATICAL MEEM;Lo;0;AL; 0645;;;;N;;;;; +1EE0D;ARABIC MATHEMATICAL NOON;Lo;0;AL; 0646;;;;N;;;;; +1EE0E;ARABIC MATHEMATICAL SEEN;Lo;0;AL; 0633;;;;N;;;;; +1EE0F;ARABIC MATHEMATICAL AIN;Lo;0;AL; 0639;;;;N;;;;; +1EE10;ARABIC MATHEMATICAL FEH;Lo;0;AL; 0641;;;;N;;;;; +1EE11;ARABIC MATHEMATICAL SAD;Lo;0;AL; 0635;;;;N;;;;; +1EE12;ARABIC MATHEMATICAL QAF;Lo;0;AL; 0642;;;;N;;;;; +1EE13;ARABIC MATHEMATICAL REH;Lo;0;AL; 0631;;;;N;;;;; +1EE14;ARABIC MATHEMATICAL SHEEN;Lo;0;AL; 0634;;;;N;;;;; +1EE15;ARABIC MATHEMATICAL TEH;Lo;0;AL; 062A;;;;N;;;;; +1EE16;ARABIC MATHEMATICAL THEH;Lo;0;AL; 062B;;;;N;;;;; +1EE17;ARABIC MATHEMATICAL KHAH;Lo;0;AL; 062E;;;;N;;;;; +1EE18;ARABIC MATHEMATICAL THAL;Lo;0;AL; 0630;;;;N;;;;; +1EE19;ARABIC MATHEMATICAL DAD;Lo;0;AL; 0636;;;;N;;;;; +1EE1A;ARABIC MATHEMATICAL ZAH;Lo;0;AL; 0638;;;;N;;;;; +1EE1B;ARABIC MATHEMATICAL GHAIN;Lo;0;AL; 063A;;;;N;;;;; +1EE1C;ARABIC MATHEMATICAL DOTLESS BEH;Lo;0;AL; 066E;;;;N;;;;; +1EE1D;ARABIC MATHEMATICAL DOTLESS NOON;Lo;0;AL; 06BA;;;;N;;;;; +1EE1E;ARABIC MATHEMATICAL DOTLESS FEH;Lo;0;AL; 06A1;;;;N;;;;; +1EE1F;ARABIC MATHEMATICAL DOTLESS QAF;Lo;0;AL; 066F;;;;N;;;;; +1EE21;ARABIC MATHEMATICAL INITIAL BEH;Lo;0;AL; 0628;;;;N;;;;; +1EE22;ARABIC MATHEMATICAL INITIAL JEEM;Lo;0;AL; 062C;;;;N;;;;; +1EE24;ARABIC MATHEMATICAL INITIAL HEH;Lo;0;AL; 0647;;;;N;;;;; +1EE27;ARABIC MATHEMATICAL INITIAL HAH;Lo;0;AL; 062D;;;;N;;;;; +1EE29;ARABIC MATHEMATICAL INITIAL YEH;Lo;0;AL; 064A;;;;N;;;;; +1EE2A;ARABIC MATHEMATICAL INITIAL KAF;Lo;0;AL; 0643;;;;N;;;;; +1EE2B;ARABIC MATHEMATICAL INITIAL LAM;Lo;0;AL; 0644;;;;N;;;;; +1EE2C;ARABIC MATHEMATICAL INITIAL MEEM;Lo;0;AL; 0645;;;;N;;;;; +1EE2D;ARABIC MATHEMATICAL INITIAL NOON;Lo;0;AL; 0646;;;;N;;;;; +1EE2E;ARABIC MATHEMATICAL INITIAL SEEN;Lo;0;AL; 0633;;;;N;;;;; +1EE2F;ARABIC MATHEMATICAL INITIAL AIN;Lo;0;AL; 0639;;;;N;;;;; +1EE30;ARABIC MATHEMATICAL INITIAL FEH;Lo;0;AL; 0641;;;;N;;;;; +1EE31;ARABIC MATHEMATICAL INITIAL SAD;Lo;0;AL; 0635;;;;N;;;;; +1EE32;ARABIC MATHEMATICAL INITIAL QAF;Lo;0;AL; 0642;;;;N;;;;; +1EE34;ARABIC MATHEMATICAL INITIAL SHEEN;Lo;0;AL; 0634;;;;N;;;;; +1EE35;ARABIC MATHEMATICAL INITIAL TEH;Lo;0;AL; 062A;;;;N;;;;; +1EE36;ARABIC MATHEMATICAL INITIAL THEH;Lo;0;AL; 062B;;;;N;;;;; +1EE37;ARABIC MATHEMATICAL INITIAL KHAH;Lo;0;AL; 062E;;;;N;;;;; +1EE39;ARABIC MATHEMATICAL INITIAL DAD;Lo;0;AL; 0636;;;;N;;;;; +1EE3B;ARABIC MATHEMATICAL INITIAL GHAIN;Lo;0;AL; 063A;;;;N;;;;; +1EE42;ARABIC MATHEMATICAL TAILED JEEM;Lo;0;AL; 062C;;;;N;;;;; +1EE47;ARABIC MATHEMATICAL TAILED HAH;Lo;0;AL; 062D;;;;N;;;;; +1EE49;ARABIC MATHEMATICAL TAILED YEH;Lo;0;AL; 064A;;;;N;;;;; +1EE4B;ARABIC MATHEMATICAL TAILED LAM;Lo;0;AL; 0644;;;;N;;;;; +1EE4D;ARABIC MATHEMATICAL TAILED NOON;Lo;0;AL; 0646;;;;N;;;;; +1EE4E;ARABIC MATHEMATICAL TAILED SEEN;Lo;0;AL; 0633;;;;N;;;;; +1EE4F;ARABIC MATHEMATICAL TAILED AIN;Lo;0;AL; 0639;;;;N;;;;; +1EE51;ARABIC MATHEMATICAL TAILED SAD;Lo;0;AL; 0635;;;;N;;;;; +1EE52;ARABIC MATHEMATICAL TAILED QAF;Lo;0;AL; 0642;;;;N;;;;; +1EE54;ARABIC MATHEMATICAL TAILED SHEEN;Lo;0;AL; 0634;;;;N;;;;; +1EE57;ARABIC MATHEMATICAL TAILED KHAH;Lo;0;AL; 062E;;;;N;;;;; +1EE59;ARABIC MATHEMATICAL TAILED DAD;Lo;0;AL; 0636;;;;N;;;;; +1EE5B;ARABIC MATHEMATICAL TAILED GHAIN;Lo;0;AL; 063A;;;;N;;;;; +1EE5D;ARABIC MATHEMATICAL TAILED DOTLESS NOON;Lo;0;AL; 06BA;;;;N;;;;; +1EE5F;ARABIC MATHEMATICAL TAILED DOTLESS QAF;Lo;0;AL; 066F;;;;N;;;;; +1EE61;ARABIC MATHEMATICAL STRETCHED BEH;Lo;0;AL; 0628;;;;N;;;;; +1EE62;ARABIC MATHEMATICAL STRETCHED JEEM;Lo;0;AL; 062C;;;;N;;;;; +1EE64;ARABIC MATHEMATICAL STRETCHED HEH;Lo;0;AL; 0647;;;;N;;;;; +1EE67;ARABIC MATHEMATICAL STRETCHED HAH;Lo;0;AL; 062D;;;;N;;;;; +1EE68;ARABIC MATHEMATICAL STRETCHED TAH;Lo;0;AL; 0637;;;;N;;;;; +1EE69;ARABIC MATHEMATICAL STRETCHED YEH;Lo;0;AL; 064A;;;;N;;;;; +1EE6A;ARABIC MATHEMATICAL STRETCHED KAF;Lo;0;AL; 0643;;;;N;;;;; +1EE6C;ARABIC MATHEMATICAL STRETCHED MEEM;Lo;0;AL; 0645;;;;N;;;;; +1EE6D;ARABIC MATHEMATICAL STRETCHED NOON;Lo;0;AL; 0646;;;;N;;;;; +1EE6E;ARABIC MATHEMATICAL STRETCHED SEEN;Lo;0;AL; 0633;;;;N;;;;; +1EE6F;ARABIC MATHEMATICAL STRETCHED AIN;Lo;0;AL; 0639;;;;N;;;;; +1EE70;ARABIC MATHEMATICAL STRETCHED FEH;Lo;0;AL; 0641;;;;N;;;;; +1EE71;ARABIC MATHEMATICAL STRETCHED SAD;Lo;0;AL; 0635;;;;N;;;;; +1EE72;ARABIC MATHEMATICAL STRETCHED QAF;Lo;0;AL; 0642;;;;N;;;;; +1EE74;ARABIC MATHEMATICAL STRETCHED SHEEN;Lo;0;AL; 0634;;;;N;;;;; +1EE75;ARABIC MATHEMATICAL STRETCHED TEH;Lo;0;AL; 062A;;;;N;;;;; +1EE76;ARABIC MATHEMATICAL STRETCHED THEH;Lo;0;AL; 062B;;;;N;;;;; +1EE77;ARABIC MATHEMATICAL STRETCHED KHAH;Lo;0;AL; 062E;;;;N;;;;; +1EE79;ARABIC MATHEMATICAL STRETCHED DAD;Lo;0;AL; 0636;;;;N;;;;; +1EE7A;ARABIC MATHEMATICAL STRETCHED ZAH;Lo;0;AL; 0638;;;;N;;;;; +1EE7B;ARABIC MATHEMATICAL STRETCHED GHAIN;Lo;0;AL; 063A;;;;N;;;;; +1EE7C;ARABIC MATHEMATICAL STRETCHED DOTLESS BEH;Lo;0;AL; 066E;;;;N;;;;; +1EE7E;ARABIC MATHEMATICAL STRETCHED DOTLESS FEH;Lo;0;AL; 06A1;;;;N;;;;; +1EE80;ARABIC MATHEMATICAL LOOPED ALEF;Lo;0;AL; 0627;;;;N;;;;; +1EE81;ARABIC MATHEMATICAL LOOPED BEH;Lo;0;AL; 0628;;;;N;;;;; +1EE82;ARABIC MATHEMATICAL LOOPED JEEM;Lo;0;AL; 062C;;;;N;;;;; +1EE83;ARABIC MATHEMATICAL LOOPED DAL;Lo;0;AL; 062F;;;;N;;;;; +1EE84;ARABIC MATHEMATICAL LOOPED HEH;Lo;0;AL; 0647;;;;N;;;;; +1EE85;ARABIC MATHEMATICAL LOOPED WAW;Lo;0;AL; 0648;;;;N;;;;; +1EE86;ARABIC MATHEMATICAL LOOPED ZAIN;Lo;0;AL; 0632;;;;N;;;;; +1EE87;ARABIC MATHEMATICAL LOOPED HAH;Lo;0;AL; 062D;;;;N;;;;; +1EE88;ARABIC MATHEMATICAL LOOPED TAH;Lo;0;AL; 0637;;;;N;;;;; +1EE89;ARABIC MATHEMATICAL LOOPED YEH;Lo;0;AL; 064A;;;;N;;;;; +1EE8B;ARABIC MATHEMATICAL LOOPED LAM;Lo;0;AL; 0644;;;;N;;;;; +1EE8C;ARABIC MATHEMATICAL LOOPED MEEM;Lo;0;AL; 0645;;;;N;;;;; +1EE8D;ARABIC MATHEMATICAL LOOPED NOON;Lo;0;AL; 0646;;;;N;;;;; +1EE8E;ARABIC MATHEMATICAL LOOPED SEEN;Lo;0;AL; 0633;;;;N;;;;; +1EE8F;ARABIC MATHEMATICAL LOOPED AIN;Lo;0;AL; 0639;;;;N;;;;; +1EE90;ARABIC MATHEMATICAL LOOPED FEH;Lo;0;AL; 0641;;;;N;;;;; +1EE91;ARABIC MATHEMATICAL LOOPED SAD;Lo;0;AL; 0635;;;;N;;;;; +1EE92;ARABIC MATHEMATICAL LOOPED QAF;Lo;0;AL; 0642;;;;N;;;;; +1EE93;ARABIC MATHEMATICAL LOOPED REH;Lo;0;AL; 0631;;;;N;;;;; +1EE94;ARABIC MATHEMATICAL LOOPED SHEEN;Lo;0;AL; 0634;;;;N;;;;; +1EE95;ARABIC MATHEMATICAL LOOPED TEH;Lo;0;AL; 062A;;;;N;;;;; +1EE96;ARABIC MATHEMATICAL LOOPED THEH;Lo;0;AL; 062B;;;;N;;;;; +1EE97;ARABIC MATHEMATICAL LOOPED KHAH;Lo;0;AL; 062E;;;;N;;;;; +1EE98;ARABIC MATHEMATICAL LOOPED THAL;Lo;0;AL; 0630;;;;N;;;;; +1EE99;ARABIC MATHEMATICAL LOOPED DAD;Lo;0;AL; 0636;;;;N;;;;; +1EE9A;ARABIC MATHEMATICAL LOOPED ZAH;Lo;0;AL; 0638;;;;N;;;;; +1EE9B;ARABIC MATHEMATICAL LOOPED GHAIN;Lo;0;AL; 063A;;;;N;;;;; +1EEA1;ARABIC MATHEMATICAL DOUBLE-STRUCK BEH;Lo;0;AL; 0628;;;;N;;;;; +1EEA2;ARABIC MATHEMATICAL DOUBLE-STRUCK JEEM;Lo;0;AL; 062C;;;;N;;;;; +1EEA3;ARABIC MATHEMATICAL DOUBLE-STRUCK DAL;Lo;0;AL; 062F;;;;N;;;;; +1EEA5;ARABIC MATHEMATICAL DOUBLE-STRUCK WAW;Lo;0;AL; 0648;;;;N;;;;; +1EEA6;ARABIC MATHEMATICAL DOUBLE-STRUCK ZAIN;Lo;0;AL; 0632;;;;N;;;;; +1EEA7;ARABIC MATHEMATICAL DOUBLE-STRUCK HAH;Lo;0;AL; 062D;;;;N;;;;; +1EEA8;ARABIC MATHEMATICAL DOUBLE-STRUCK TAH;Lo;0;AL; 0637;;;;N;;;;; +1EEA9;ARABIC MATHEMATICAL DOUBLE-STRUCK YEH;Lo;0;AL; 064A;;;;N;;;;; +1EEAB;ARABIC MATHEMATICAL DOUBLE-STRUCK LAM;Lo;0;AL; 0644;;;;N;;;;; +1EEAC;ARABIC MATHEMATICAL DOUBLE-STRUCK MEEM;Lo;0;AL; 0645;;;;N;;;;; +1EEAD;ARABIC MATHEMATICAL DOUBLE-STRUCK NOON;Lo;0;AL; 0646;;;;N;;;;; +1EEAE;ARABIC MATHEMATICAL DOUBLE-STRUCK SEEN;Lo;0;AL; 0633;;;;N;;;;; +1EEAF;ARABIC MATHEMATICAL DOUBLE-STRUCK AIN;Lo;0;AL; 0639;;;;N;;;;; +1EEB0;ARABIC MATHEMATICAL DOUBLE-STRUCK FEH;Lo;0;AL; 0641;;;;N;;;;; +1EEB1;ARABIC MATHEMATICAL DOUBLE-STRUCK SAD;Lo;0;AL; 0635;;;;N;;;;; +1EEB2;ARABIC MATHEMATICAL DOUBLE-STRUCK QAF;Lo;0;AL; 0642;;;;N;;;;; +1EEB3;ARABIC MATHEMATICAL DOUBLE-STRUCK REH;Lo;0;AL; 0631;;;;N;;;;; +1EEB4;ARABIC MATHEMATICAL DOUBLE-STRUCK SHEEN;Lo;0;AL; 0634;;;;N;;;;; +1EEB5;ARABIC MATHEMATICAL DOUBLE-STRUCK TEH;Lo;0;AL; 062A;;;;N;;;;; +1EEB6;ARABIC MATHEMATICAL DOUBLE-STRUCK THEH;Lo;0;AL; 062B;;;;N;;;;; +1EEB7;ARABIC MATHEMATICAL DOUBLE-STRUCK KHAH;Lo;0;AL; 062E;;;;N;;;;; +1EEB8;ARABIC MATHEMATICAL DOUBLE-STRUCK THAL;Lo;0;AL; 0630;;;;N;;;;; +1EEB9;ARABIC MATHEMATICAL DOUBLE-STRUCK DAD;Lo;0;AL; 0636;;;;N;;;;; +1EEBA;ARABIC MATHEMATICAL DOUBLE-STRUCK ZAH;Lo;0;AL; 0638;;;;N;;;;; +1EEBB;ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN;Lo;0;AL; 063A;;;;N;;;;; +1EEF0;ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL;Sm;0;ON;;;;;N;;;;; +1EEF1;ARABIC MATHEMATICAL OPERATOR HAH WITH DAL;Sm;0;ON;;;;;N;;;;; +1F000;MAHJONG TILE EAST WIND;So;0;ON;;;;;N;;;;; +1F001;MAHJONG TILE SOUTH WIND;So;0;ON;;;;;N;;;;; +1F002;MAHJONG TILE WEST WIND;So;0;ON;;;;;N;;;;; +1F003;MAHJONG TILE NORTH WIND;So;0;ON;;;;;N;;;;; +1F004;MAHJONG TILE RED DRAGON;So;0;ON;;;;;N;;;;; +1F005;MAHJONG TILE GREEN DRAGON;So;0;ON;;;;;N;;;;; +1F006;MAHJONG TILE WHITE DRAGON;So;0;ON;;;;;N;;;;; +1F007;MAHJONG TILE ONE OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F008;MAHJONG TILE TWO OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F009;MAHJONG TILE THREE OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00A;MAHJONG TILE FOUR OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00B;MAHJONG TILE FIVE OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00C;MAHJONG TILE SIX OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00D;MAHJONG TILE SEVEN OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00E;MAHJONG TILE EIGHT OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F00F;MAHJONG TILE NINE OF CHARACTERS;So;0;ON;;;;;N;;;;; +1F010;MAHJONG TILE ONE OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F011;MAHJONG TILE TWO OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F012;MAHJONG TILE THREE OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F013;MAHJONG TILE FOUR OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F014;MAHJONG TILE FIVE OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F015;MAHJONG TILE SIX OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F016;MAHJONG TILE SEVEN OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F017;MAHJONG TILE EIGHT OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F018;MAHJONG TILE NINE OF BAMBOOS;So;0;ON;;;;;N;;;;; +1F019;MAHJONG TILE ONE OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01A;MAHJONG TILE TWO OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01B;MAHJONG TILE THREE OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01C;MAHJONG TILE FOUR OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01D;MAHJONG TILE FIVE OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01E;MAHJONG TILE SIX OF CIRCLES;So;0;ON;;;;;N;;;;; +1F01F;MAHJONG TILE SEVEN OF CIRCLES;So;0;ON;;;;;N;;;;; +1F020;MAHJONG TILE EIGHT OF CIRCLES;So;0;ON;;;;;N;;;;; +1F021;MAHJONG TILE NINE OF CIRCLES;So;0;ON;;;;;N;;;;; +1F022;MAHJONG TILE PLUM;So;0;ON;;;;;N;;;;; +1F023;MAHJONG TILE ORCHID;So;0;ON;;;;;N;;;;; +1F024;MAHJONG TILE BAMBOO;So;0;ON;;;;;N;;;;; +1F025;MAHJONG TILE CHRYSANTHEMUM;So;0;ON;;;;;N;;;;; +1F026;MAHJONG TILE SPRING;So;0;ON;;;;;N;;;;; +1F027;MAHJONG TILE SUMMER;So;0;ON;;;;;N;;;;; +1F028;MAHJONG TILE AUTUMN;So;0;ON;;;;;N;;;;; +1F029;MAHJONG TILE WINTER;So;0;ON;;;;;N;;;;; +1F02A;MAHJONG TILE JOKER;So;0;ON;;;;;N;;;;; +1F02B;MAHJONG TILE BACK;So;0;ON;;;;;N;;;;; +1F030;DOMINO TILE HORIZONTAL BACK;So;0;ON;;;;;N;;;;; +1F031;DOMINO TILE HORIZONTAL-00-00;So;0;ON;;;;;N;;;;; +1F032;DOMINO TILE HORIZONTAL-00-01;So;0;ON;;;;;N;;;;; +1F033;DOMINO TILE HORIZONTAL-00-02;So;0;ON;;;;;N;;;;; +1F034;DOMINO TILE HORIZONTAL-00-03;So;0;ON;;;;;N;;;;; +1F035;DOMINO TILE HORIZONTAL-00-04;So;0;ON;;;;;N;;;;; +1F036;DOMINO TILE HORIZONTAL-00-05;So;0;ON;;;;;N;;;;; +1F037;DOMINO TILE HORIZONTAL-00-06;So;0;ON;;;;;N;;;;; +1F038;DOMINO TILE HORIZONTAL-01-00;So;0;ON;;;;;N;;;;; +1F039;DOMINO TILE HORIZONTAL-01-01;So;0;ON;;;;;N;;;;; +1F03A;DOMINO TILE HORIZONTAL-01-02;So;0;ON;;;;;N;;;;; +1F03B;DOMINO TILE HORIZONTAL-01-03;So;0;ON;;;;;N;;;;; +1F03C;DOMINO TILE HORIZONTAL-01-04;So;0;ON;;;;;N;;;;; +1F03D;DOMINO TILE HORIZONTAL-01-05;So;0;ON;;;;;N;;;;; +1F03E;DOMINO TILE HORIZONTAL-01-06;So;0;ON;;;;;N;;;;; +1F03F;DOMINO TILE HORIZONTAL-02-00;So;0;ON;;;;;N;;;;; +1F040;DOMINO TILE HORIZONTAL-02-01;So;0;ON;;;;;N;;;;; +1F041;DOMINO TILE HORIZONTAL-02-02;So;0;ON;;;;;N;;;;; +1F042;DOMINO TILE HORIZONTAL-02-03;So;0;ON;;;;;N;;;;; +1F043;DOMINO TILE HORIZONTAL-02-04;So;0;ON;;;;;N;;;;; +1F044;DOMINO TILE HORIZONTAL-02-05;So;0;ON;;;;;N;;;;; +1F045;DOMINO TILE HORIZONTAL-02-06;So;0;ON;;;;;N;;;;; +1F046;DOMINO TILE HORIZONTAL-03-00;So;0;ON;;;;;N;;;;; +1F047;DOMINO TILE HORIZONTAL-03-01;So;0;ON;;;;;N;;;;; +1F048;DOMINO TILE HORIZONTAL-03-02;So;0;ON;;;;;N;;;;; +1F049;DOMINO TILE HORIZONTAL-03-03;So;0;ON;;;;;N;;;;; +1F04A;DOMINO TILE HORIZONTAL-03-04;So;0;ON;;;;;N;;;;; +1F04B;DOMINO TILE HORIZONTAL-03-05;So;0;ON;;;;;N;;;;; +1F04C;DOMINO TILE HORIZONTAL-03-06;So;0;ON;;;;;N;;;;; +1F04D;DOMINO TILE HORIZONTAL-04-00;So;0;ON;;;;;N;;;;; +1F04E;DOMINO TILE HORIZONTAL-04-01;So;0;ON;;;;;N;;;;; +1F04F;DOMINO TILE HORIZONTAL-04-02;So;0;ON;;;;;N;;;;; +1F050;DOMINO TILE HORIZONTAL-04-03;So;0;ON;;;;;N;;;;; +1F051;DOMINO TILE HORIZONTAL-04-04;So;0;ON;;;;;N;;;;; +1F052;DOMINO TILE HORIZONTAL-04-05;So;0;ON;;;;;N;;;;; +1F053;DOMINO TILE HORIZONTAL-04-06;So;0;ON;;;;;N;;;;; +1F054;DOMINO TILE HORIZONTAL-05-00;So;0;ON;;;;;N;;;;; +1F055;DOMINO TILE HORIZONTAL-05-01;So;0;ON;;;;;N;;;;; +1F056;DOMINO TILE HORIZONTAL-05-02;So;0;ON;;;;;N;;;;; +1F057;DOMINO TILE HORIZONTAL-05-03;So;0;ON;;;;;N;;;;; +1F058;DOMINO TILE HORIZONTAL-05-04;So;0;ON;;;;;N;;;;; +1F059;DOMINO TILE HORIZONTAL-05-05;So;0;ON;;;;;N;;;;; +1F05A;DOMINO TILE HORIZONTAL-05-06;So;0;ON;;;;;N;;;;; +1F05B;DOMINO TILE HORIZONTAL-06-00;So;0;ON;;;;;N;;;;; +1F05C;DOMINO TILE HORIZONTAL-06-01;So;0;ON;;;;;N;;;;; +1F05D;DOMINO TILE HORIZONTAL-06-02;So;0;ON;;;;;N;;;;; +1F05E;DOMINO TILE HORIZONTAL-06-03;So;0;ON;;;;;N;;;;; +1F05F;DOMINO TILE HORIZONTAL-06-04;So;0;ON;;;;;N;;;;; +1F060;DOMINO TILE HORIZONTAL-06-05;So;0;ON;;;;;N;;;;; +1F061;DOMINO TILE HORIZONTAL-06-06;So;0;ON;;;;;N;;;;; +1F062;DOMINO TILE VERTICAL BACK;So;0;ON;;;;;N;;;;; +1F063;DOMINO TILE VERTICAL-00-00;So;0;ON;;;;;N;;;;; +1F064;DOMINO TILE VERTICAL-00-01;So;0;ON;;;;;N;;;;; +1F065;DOMINO TILE VERTICAL-00-02;So;0;ON;;;;;N;;;;; +1F066;DOMINO TILE VERTICAL-00-03;So;0;ON;;;;;N;;;;; +1F067;DOMINO TILE VERTICAL-00-04;So;0;ON;;;;;N;;;;; +1F068;DOMINO TILE VERTICAL-00-05;So;0;ON;;;;;N;;;;; +1F069;DOMINO TILE VERTICAL-00-06;So;0;ON;;;;;N;;;;; +1F06A;DOMINO TILE VERTICAL-01-00;So;0;ON;;;;;N;;;;; +1F06B;DOMINO TILE VERTICAL-01-01;So;0;ON;;;;;N;;;;; +1F06C;DOMINO TILE VERTICAL-01-02;So;0;ON;;;;;N;;;;; +1F06D;DOMINO TILE VERTICAL-01-03;So;0;ON;;;;;N;;;;; +1F06E;DOMINO TILE VERTICAL-01-04;So;0;ON;;;;;N;;;;; +1F06F;DOMINO TILE VERTICAL-01-05;So;0;ON;;;;;N;;;;; +1F070;DOMINO TILE VERTICAL-01-06;So;0;ON;;;;;N;;;;; +1F071;DOMINO TILE VERTICAL-02-00;So;0;ON;;;;;N;;;;; +1F072;DOMINO TILE VERTICAL-02-01;So;0;ON;;;;;N;;;;; +1F073;DOMINO TILE VERTICAL-02-02;So;0;ON;;;;;N;;;;; +1F074;DOMINO TILE VERTICAL-02-03;So;0;ON;;;;;N;;;;; +1F075;DOMINO TILE VERTICAL-02-04;So;0;ON;;;;;N;;;;; +1F076;DOMINO TILE VERTICAL-02-05;So;0;ON;;;;;N;;;;; +1F077;DOMINO TILE VERTICAL-02-06;So;0;ON;;;;;N;;;;; +1F078;DOMINO TILE VERTICAL-03-00;So;0;ON;;;;;N;;;;; +1F079;DOMINO TILE VERTICAL-03-01;So;0;ON;;;;;N;;;;; +1F07A;DOMINO TILE VERTICAL-03-02;So;0;ON;;;;;N;;;;; +1F07B;DOMINO TILE VERTICAL-03-03;So;0;ON;;;;;N;;;;; +1F07C;DOMINO TILE VERTICAL-03-04;So;0;ON;;;;;N;;;;; +1F07D;DOMINO TILE VERTICAL-03-05;So;0;ON;;;;;N;;;;; +1F07E;DOMINO TILE VERTICAL-03-06;So;0;ON;;;;;N;;;;; +1F07F;DOMINO TILE VERTICAL-04-00;So;0;ON;;;;;N;;;;; +1F080;DOMINO TILE VERTICAL-04-01;So;0;ON;;;;;N;;;;; +1F081;DOMINO TILE VERTICAL-04-02;So;0;ON;;;;;N;;;;; +1F082;DOMINO TILE VERTICAL-04-03;So;0;ON;;;;;N;;;;; +1F083;DOMINO TILE VERTICAL-04-04;So;0;ON;;;;;N;;;;; +1F084;DOMINO TILE VERTICAL-04-05;So;0;ON;;;;;N;;;;; +1F085;DOMINO TILE VERTICAL-04-06;So;0;ON;;;;;N;;;;; +1F086;DOMINO TILE VERTICAL-05-00;So;0;ON;;;;;N;;;;; +1F087;DOMINO TILE VERTICAL-05-01;So;0;ON;;;;;N;;;;; +1F088;DOMINO TILE VERTICAL-05-02;So;0;ON;;;;;N;;;;; +1F089;DOMINO TILE VERTICAL-05-03;So;0;ON;;;;;N;;;;; +1F08A;DOMINO TILE VERTICAL-05-04;So;0;ON;;;;;N;;;;; +1F08B;DOMINO TILE VERTICAL-05-05;So;0;ON;;;;;N;;;;; +1F08C;DOMINO TILE VERTICAL-05-06;So;0;ON;;;;;N;;;;; +1F08D;DOMINO TILE VERTICAL-06-00;So;0;ON;;;;;N;;;;; +1F08E;DOMINO TILE VERTICAL-06-01;So;0;ON;;;;;N;;;;; +1F08F;DOMINO TILE VERTICAL-06-02;So;0;ON;;;;;N;;;;; +1F090;DOMINO TILE VERTICAL-06-03;So;0;ON;;;;;N;;;;; +1F091;DOMINO TILE VERTICAL-06-04;So;0;ON;;;;;N;;;;; +1F092;DOMINO TILE VERTICAL-06-05;So;0;ON;;;;;N;;;;; +1F093;DOMINO TILE VERTICAL-06-06;So;0;ON;;;;;N;;;;; +1F0A0;PLAYING CARD BACK;So;0;ON;;;;;N;;;;; +1F0A1;PLAYING CARD ACE OF SPADES;So;0;ON;;;;;N;;;;; +1F0A2;PLAYING CARD TWO OF SPADES;So;0;ON;;;;;N;;;;; +1F0A3;PLAYING CARD THREE OF SPADES;So;0;ON;;;;;N;;;;; +1F0A4;PLAYING CARD FOUR OF SPADES;So;0;ON;;;;;N;;;;; +1F0A5;PLAYING CARD FIVE OF SPADES;So;0;ON;;;;;N;;;;; +1F0A6;PLAYING CARD SIX OF SPADES;So;0;ON;;;;;N;;;;; +1F0A7;PLAYING CARD SEVEN OF SPADES;So;0;ON;;;;;N;;;;; +1F0A8;PLAYING CARD EIGHT OF SPADES;So;0;ON;;;;;N;;;;; +1F0A9;PLAYING CARD NINE OF SPADES;So;0;ON;;;;;N;;;;; +1F0AA;PLAYING CARD TEN OF SPADES;So;0;ON;;;;;N;;;;; +1F0AB;PLAYING CARD JACK OF SPADES;So;0;ON;;;;;N;;;;; +1F0AC;PLAYING CARD KNIGHT OF SPADES;So;0;ON;;;;;N;;;;; +1F0AD;PLAYING CARD QUEEN OF SPADES;So;0;ON;;;;;N;;;;; +1F0AE;PLAYING CARD KING OF SPADES;So;0;ON;;;;;N;;;;; +1F0B1;PLAYING CARD ACE OF HEARTS;So;0;ON;;;;;N;;;;; +1F0B2;PLAYING CARD TWO OF HEARTS;So;0;ON;;;;;N;;;;; +1F0B3;PLAYING CARD THREE OF HEARTS;So;0;ON;;;;;N;;;;; +1F0B4;PLAYING CARD FOUR OF HEARTS;So;0;ON;;;;;N;;;;; +1F0B5;PLAYING CARD FIVE OF HEARTS;So;0;ON;;;;;N;;;;; +1F0B6;PLAYING CARD SIX OF HEARTS;So;0;ON;;;;;N;;;;; +1F0B7;PLAYING CARD SEVEN OF HEARTS;So;0;ON;;;;;N;;;;; +1F0B8;PLAYING CARD EIGHT OF HEARTS;So;0;ON;;;;;N;;;;; +1F0B9;PLAYING CARD NINE OF HEARTS;So;0;ON;;;;;N;;;;; +1F0BA;PLAYING CARD TEN OF HEARTS;So;0;ON;;;;;N;;;;; +1F0BB;PLAYING CARD JACK OF HEARTS;So;0;ON;;;;;N;;;;; +1F0BC;PLAYING CARD KNIGHT OF HEARTS;So;0;ON;;;;;N;;;;; +1F0BD;PLAYING CARD QUEEN OF HEARTS;So;0;ON;;;;;N;;;;; +1F0BE;PLAYING CARD KING OF HEARTS;So;0;ON;;;;;N;;;;; +1F0BF;PLAYING CARD RED JOKER;So;0;ON;;;;;N;;;;; +1F0C1;PLAYING CARD ACE OF DIAMONDS;So;0;ON;;;;;N;;;;; +1F0C2;PLAYING CARD TWO OF DIAMONDS;So;0;ON;;;;;N;;;;; +1F0C3;PLAYING CARD THREE OF DIAMONDS;So;0;ON;;;;;N;;;;; +1F0C4;PLAYING CARD FOUR OF DIAMONDS;So;0;ON;;;;;N;;;;; +1F0C5;PLAYING CARD FIVE OF DIAMONDS;So;0;ON;;;;;N;;;;; +1F0C6;PLAYING CARD SIX OF DIAMONDS;So;0;ON;;;;;N;;;;; +1F0C7;PLAYING CARD SEVEN OF DIAMONDS;So;0;ON;;;;;N;;;;; +1F0C8;PLAYING CARD EIGHT OF DIAMONDS;So;0;ON;;;;;N;;;;; +1F0C9;PLAYING CARD NINE OF DIAMONDS;So;0;ON;;;;;N;;;;; +1F0CA;PLAYING CARD TEN OF DIAMONDS;So;0;ON;;;;;N;;;;; +1F0CB;PLAYING CARD JACK OF DIAMONDS;So;0;ON;;;;;N;;;;; +1F0CC;PLAYING CARD KNIGHT OF DIAMONDS;So;0;ON;;;;;N;;;;; +1F0CD;PLAYING CARD QUEEN OF DIAMONDS;So;0;ON;;;;;N;;;;; +1F0CE;PLAYING CARD KING OF DIAMONDS;So;0;ON;;;;;N;;;;; +1F0CF;PLAYING CARD BLACK JOKER;So;0;ON;;;;;N;;;;; +1F0D1;PLAYING CARD ACE OF CLUBS;So;0;ON;;;;;N;;;;; +1F0D2;PLAYING CARD TWO OF CLUBS;So;0;ON;;;;;N;;;;; +1F0D3;PLAYING CARD THREE OF CLUBS;So;0;ON;;;;;N;;;;; +1F0D4;PLAYING CARD FOUR OF CLUBS;So;0;ON;;;;;N;;;;; +1F0D5;PLAYING CARD FIVE OF CLUBS;So;0;ON;;;;;N;;;;; +1F0D6;PLAYING CARD SIX OF CLUBS;So;0;ON;;;;;N;;;;; +1F0D7;PLAYING CARD SEVEN OF CLUBS;So;0;ON;;;;;N;;;;; +1F0D8;PLAYING CARD EIGHT OF CLUBS;So;0;ON;;;;;N;;;;; +1F0D9;PLAYING CARD NINE OF CLUBS;So;0;ON;;;;;N;;;;; +1F0DA;PLAYING CARD TEN OF CLUBS;So;0;ON;;;;;N;;;;; +1F0DB;PLAYING CARD JACK OF CLUBS;So;0;ON;;;;;N;;;;; +1F0DC;PLAYING CARD KNIGHT OF CLUBS;So;0;ON;;;;;N;;;;; +1F0DD;PLAYING CARD QUEEN OF CLUBS;So;0;ON;;;;;N;;;;; +1F0DE;PLAYING CARD KING OF CLUBS;So;0;ON;;;;;N;;;;; +1F0DF;PLAYING CARD WHITE JOKER;So;0;ON;;;;;N;;;;; +1F0E0;PLAYING CARD FOOL;So;0;ON;;;;;N;;;;; +1F0E1;PLAYING CARD TRUMP-1;So;0;ON;;;;;N;;;;; +1F0E2;PLAYING CARD TRUMP-2;So;0;ON;;;;;N;;;;; +1F0E3;PLAYING CARD TRUMP-3;So;0;ON;;;;;N;;;;; +1F0E4;PLAYING CARD TRUMP-4;So;0;ON;;;;;N;;;;; +1F0E5;PLAYING CARD TRUMP-5;So;0;ON;;;;;N;;;;; +1F0E6;PLAYING CARD TRUMP-6;So;0;ON;;;;;N;;;;; +1F0E7;PLAYING CARD TRUMP-7;So;0;ON;;;;;N;;;;; +1F0E8;PLAYING CARD TRUMP-8;So;0;ON;;;;;N;;;;; +1F0E9;PLAYING CARD TRUMP-9;So;0;ON;;;;;N;;;;; +1F0EA;PLAYING CARD TRUMP-10;So;0;ON;;;;;N;;;;; +1F0EB;PLAYING CARD TRUMP-11;So;0;ON;;;;;N;;;;; +1F0EC;PLAYING CARD TRUMP-12;So;0;ON;;;;;N;;;;; +1F0ED;PLAYING CARD TRUMP-13;So;0;ON;;;;;N;;;;; +1F0EE;PLAYING CARD TRUMP-14;So;0;ON;;;;;N;;;;; +1F0EF;PLAYING CARD TRUMP-15;So;0;ON;;;;;N;;;;; +1F0F0;PLAYING CARD TRUMP-16;So;0;ON;;;;;N;;;;; +1F0F1;PLAYING CARD TRUMP-17;So;0;ON;;;;;N;;;;; +1F0F2;PLAYING CARD TRUMP-18;So;0;ON;;;;;N;;;;; +1F0F3;PLAYING CARD TRUMP-19;So;0;ON;;;;;N;;;;; +1F0F4;PLAYING CARD TRUMP-20;So;0;ON;;;;;N;;;;; +1F0F5;PLAYING CARD TRUMP-21;So;0;ON;;;;;N;;;;; +1F100;DIGIT ZERO FULL STOP;No;0;EN; 0030 002E;;0;0;N;;;;; +1F101;DIGIT ZERO COMMA;No;0;EN; 0030 002C;;0;0;N;;;;; +1F102;DIGIT ONE COMMA;No;0;EN; 0031 002C;;1;1;N;;;;; +1F103;DIGIT TWO COMMA;No;0;EN; 0032 002C;;2;2;N;;;;; +1F104;DIGIT THREE COMMA;No;0;EN; 0033 002C;;3;3;N;;;;; +1F105;DIGIT FOUR COMMA;No;0;EN; 0034 002C;;4;4;N;;;;; +1F106;DIGIT FIVE COMMA;No;0;EN; 0035 002C;;5;5;N;;;;; +1F107;DIGIT SIX COMMA;No;0;EN; 0036 002C;;6;6;N;;;;; +1F108;DIGIT SEVEN COMMA;No;0;EN; 0037 002C;;7;7;N;;;;; +1F109;DIGIT EIGHT COMMA;No;0;EN; 0038 002C;;8;8;N;;;;; +1F10A;DIGIT NINE COMMA;No;0;EN; 0039 002C;;9;9;N;;;;; +1F10B;DINGBAT CIRCLED SANS-SERIF DIGIT ZERO;No;0;ON;;;;0;N;;;;; +1F10C;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO;No;0;ON;;;;0;N;;;;; +1F110;PARENTHESIZED LATIN CAPITAL LETTER A;So;0;L; 0028 0041 0029;;;;N;;;;; +1F111;PARENTHESIZED LATIN CAPITAL LETTER B;So;0;L; 0028 0042 0029;;;;N;;;;; +1F112;PARENTHESIZED LATIN CAPITAL LETTER C;So;0;L; 0028 0043 0029;;;;N;;;;; +1F113;PARENTHESIZED LATIN CAPITAL LETTER D;So;0;L; 0028 0044 0029;;;;N;;;;; +1F114;PARENTHESIZED LATIN CAPITAL LETTER E;So;0;L; 0028 0045 0029;;;;N;;;;; +1F115;PARENTHESIZED LATIN CAPITAL LETTER F;So;0;L; 0028 0046 0029;;;;N;;;;; +1F116;PARENTHESIZED LATIN CAPITAL LETTER G;So;0;L; 0028 0047 0029;;;;N;;;;; +1F117;PARENTHESIZED LATIN CAPITAL LETTER H;So;0;L; 0028 0048 0029;;;;N;;;;; +1F118;PARENTHESIZED LATIN CAPITAL LETTER I;So;0;L; 0028 0049 0029;;;;N;;;;; +1F119;PARENTHESIZED LATIN CAPITAL LETTER J;So;0;L; 0028 004A 0029;;;;N;;;;; +1F11A;PARENTHESIZED LATIN CAPITAL LETTER K;So;0;L; 0028 004B 0029;;;;N;;;;; +1F11B;PARENTHESIZED LATIN CAPITAL LETTER L;So;0;L; 0028 004C 0029;;;;N;;;;; +1F11C;PARENTHESIZED LATIN CAPITAL LETTER M;So;0;L; 0028 004D 0029;;;;N;;;;; +1F11D;PARENTHESIZED LATIN CAPITAL LETTER N;So;0;L; 0028 004E 0029;;;;N;;;;; +1F11E;PARENTHESIZED LATIN CAPITAL LETTER O;So;0;L; 0028 004F 0029;;;;N;;;;; +1F11F;PARENTHESIZED LATIN CAPITAL LETTER P;So;0;L; 0028 0050 0029;;;;N;;;;; +1F120;PARENTHESIZED LATIN CAPITAL LETTER Q;So;0;L; 0028 0051 0029;;;;N;;;;; +1F121;PARENTHESIZED LATIN CAPITAL LETTER R;So;0;L; 0028 0052 0029;;;;N;;;;; +1F122;PARENTHESIZED LATIN CAPITAL LETTER S;So;0;L; 0028 0053 0029;;;;N;;;;; +1F123;PARENTHESIZED LATIN CAPITAL LETTER T;So;0;L; 0028 0054 0029;;;;N;;;;; +1F124;PARENTHESIZED LATIN CAPITAL LETTER U;So;0;L; 0028 0055 0029;;;;N;;;;; +1F125;PARENTHESIZED LATIN CAPITAL LETTER V;So;0;L; 0028 0056 0029;;;;N;;;;; +1F126;PARENTHESIZED LATIN CAPITAL LETTER W;So;0;L; 0028 0057 0029;;;;N;;;;; +1F127;PARENTHESIZED LATIN CAPITAL LETTER X;So;0;L; 0028 0058 0029;;;;N;;;;; +1F128;PARENTHESIZED LATIN CAPITAL LETTER Y;So;0;L; 0028 0059 0029;;;;N;;;;; +1F129;PARENTHESIZED LATIN CAPITAL LETTER Z;So;0;L; 0028 005A 0029;;;;N;;;;; +1F12A;TORTOISE SHELL BRACKETED LATIN CAPITAL LETTER S;So;0;L; 3014 0053 3015;;;;N;;;;; +1F12B;CIRCLED ITALIC LATIN CAPITAL LETTER C;So;0;L; 0043;;;;N;;;;; +1F12C;CIRCLED ITALIC LATIN CAPITAL LETTER R;So;0;L; 0052;;;;N;;;;; +1F12D;CIRCLED CD;So;0;L; 0043 0044;;;;N;;;;; +1F12E;CIRCLED WZ;So;0;L; 0057 005A;;;;N;;;;; +1F12F;COPYLEFT SYMBOL;So;0;ON;;;;;N;;;;; +1F130;SQUARED LATIN CAPITAL LETTER A;So;0;L; 0041;;;;N;;;;; +1F131;SQUARED LATIN CAPITAL LETTER B;So;0;L; 0042;;;;N;;;;; +1F132;SQUARED LATIN CAPITAL LETTER C;So;0;L; 0043;;;;N;;;;; +1F133;SQUARED LATIN CAPITAL LETTER D;So;0;L; 0044;;;;N;;;;; +1F134;SQUARED LATIN CAPITAL LETTER E;So;0;L; 0045;;;;N;;;;; +1F135;SQUARED LATIN CAPITAL LETTER F;So;0;L; 0046;;;;N;;;;; +1F136;SQUARED LATIN CAPITAL LETTER G;So;0;L; 0047;;;;N;;;;; +1F137;SQUARED LATIN CAPITAL LETTER H;So;0;L; 0048;;;;N;;;;; +1F138;SQUARED LATIN CAPITAL LETTER I;So;0;L; 0049;;;;N;;;;; +1F139;SQUARED LATIN CAPITAL LETTER J;So;0;L; 004A;;;;N;;;;; +1F13A;SQUARED LATIN CAPITAL LETTER K;So;0;L; 004B;;;;N;;;;; +1F13B;SQUARED LATIN CAPITAL LETTER L;So;0;L; 004C;;;;N;;;;; +1F13C;SQUARED LATIN CAPITAL LETTER M;So;0;L; 004D;;;;N;;;;; +1F13D;SQUARED LATIN CAPITAL LETTER N;So;0;L; 004E;;;;N;;;;; +1F13E;SQUARED LATIN CAPITAL LETTER O;So;0;L; 004F;;;;N;;;;; +1F13F;SQUARED LATIN CAPITAL LETTER P;So;0;L; 0050;;;;N;;;;; +1F140;SQUARED LATIN CAPITAL LETTER Q;So;0;L; 0051;;;;N;;;;; +1F141;SQUARED LATIN CAPITAL LETTER R;So;0;L; 0052;;;;N;;;;; +1F142;SQUARED LATIN CAPITAL LETTER S;So;0;L; 0053;;;;N;;;;; +1F143;SQUARED LATIN CAPITAL LETTER T;So;0;L; 0054;;;;N;;;;; +1F144;SQUARED LATIN CAPITAL LETTER U;So;0;L; 0055;;;;N;;;;; +1F145;SQUARED LATIN CAPITAL LETTER V;So;0;L; 0056;;;;N;;;;; +1F146;SQUARED LATIN CAPITAL LETTER W;So;0;L; 0057;;;;N;;;;; +1F147;SQUARED LATIN CAPITAL LETTER X;So;0;L; 0058;;;;N;;;;; +1F148;SQUARED LATIN CAPITAL LETTER Y;So;0;L; 0059;;;;N;;;;; +1F149;SQUARED LATIN CAPITAL LETTER Z;So;0;L; 005A;;;;N;;;;; +1F14A;SQUARED HV;So;0;L; 0048 0056;;;;N;;;;; +1F14B;SQUARED MV;So;0;L; 004D 0056;;;;N;;;;; +1F14C;SQUARED SD;So;0;L; 0053 0044;;;;N;;;;; +1F14D;SQUARED SS;So;0;L; 0053 0053;;;;N;;;;; +1F14E;SQUARED PPV;So;0;L; 0050 0050 0056;;;;N;;;;; +1F14F;SQUARED WC;So;0;L; 0057 0043;;;;N;;;;; +1F150;NEGATIVE CIRCLED LATIN CAPITAL LETTER A;So;0;L;;;;;N;;;;; +1F151;NEGATIVE CIRCLED LATIN CAPITAL LETTER B;So;0;L;;;;;N;;;;; +1F152;NEGATIVE CIRCLED LATIN CAPITAL LETTER C;So;0;L;;;;;N;;;;; +1F153;NEGATIVE CIRCLED LATIN CAPITAL LETTER D;So;0;L;;;;;N;;;;; +1F154;NEGATIVE CIRCLED LATIN CAPITAL LETTER E;So;0;L;;;;;N;;;;; +1F155;NEGATIVE CIRCLED LATIN CAPITAL LETTER F;So;0;L;;;;;N;;;;; +1F156;NEGATIVE CIRCLED LATIN CAPITAL LETTER G;So;0;L;;;;;N;;;;; +1F157;NEGATIVE CIRCLED LATIN CAPITAL LETTER H;So;0;L;;;;;N;;;;; +1F158;NEGATIVE CIRCLED LATIN CAPITAL LETTER I;So;0;L;;;;;N;;;;; +1F159;NEGATIVE CIRCLED LATIN CAPITAL LETTER J;So;0;L;;;;;N;;;;; +1F15A;NEGATIVE CIRCLED LATIN CAPITAL LETTER K;So;0;L;;;;;N;;;;; +1F15B;NEGATIVE CIRCLED LATIN CAPITAL LETTER L;So;0;L;;;;;N;;;;; +1F15C;NEGATIVE CIRCLED LATIN CAPITAL LETTER M;So;0;L;;;;;N;;;;; +1F15D;NEGATIVE CIRCLED LATIN CAPITAL LETTER N;So;0;L;;;;;N;;;;; +1F15E;NEGATIVE CIRCLED LATIN CAPITAL LETTER O;So;0;L;;;;;N;;;;; +1F15F;NEGATIVE CIRCLED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;; +1F160;NEGATIVE CIRCLED LATIN CAPITAL LETTER Q;So;0;L;;;;;N;;;;; +1F161;NEGATIVE CIRCLED LATIN CAPITAL LETTER R;So;0;L;;;;;N;;;;; +1F162;NEGATIVE CIRCLED LATIN CAPITAL LETTER S;So;0;L;;;;;N;;;;; +1F163;NEGATIVE CIRCLED LATIN CAPITAL LETTER T;So;0;L;;;;;N;;;;; +1F164;NEGATIVE CIRCLED LATIN CAPITAL LETTER U;So;0;L;;;;;N;;;;; +1F165;NEGATIVE CIRCLED LATIN CAPITAL LETTER V;So;0;L;;;;;N;;;;; +1F166;NEGATIVE CIRCLED LATIN CAPITAL LETTER W;So;0;L;;;;;N;;;;; +1F167;NEGATIVE CIRCLED LATIN CAPITAL LETTER X;So;0;L;;;;;N;;;;; +1F168;NEGATIVE CIRCLED LATIN CAPITAL LETTER Y;So;0;L;;;;;N;;;;; +1F169;NEGATIVE CIRCLED LATIN CAPITAL LETTER Z;So;0;L;;;;;N;;;;; +1F16A;RAISED MC SIGN;So;0;ON; 004D 0043;;;;N;;;;; +1F16B;RAISED MD SIGN;So;0;ON; 004D 0044;;;;N;;;;; +1F16C;RAISED MR SIGN;So;0;ON; 004D 0052;;;;N;;;;; +1F170;NEGATIVE SQUARED LATIN CAPITAL LETTER A;So;0;L;;;;;N;;;;; +1F171;NEGATIVE SQUARED LATIN CAPITAL LETTER B;So;0;L;;;;;N;;;;; +1F172;NEGATIVE SQUARED LATIN CAPITAL LETTER C;So;0;L;;;;;N;;;;; +1F173;NEGATIVE SQUARED LATIN CAPITAL LETTER D;So;0;L;;;;;N;;;;; +1F174;NEGATIVE SQUARED LATIN CAPITAL LETTER E;So;0;L;;;;;N;;;;; +1F175;NEGATIVE SQUARED LATIN CAPITAL LETTER F;So;0;L;;;;;N;;;;; +1F176;NEGATIVE SQUARED LATIN CAPITAL LETTER G;So;0;L;;;;;N;;;;; +1F177;NEGATIVE SQUARED LATIN CAPITAL LETTER H;So;0;L;;;;;N;;;;; +1F178;NEGATIVE SQUARED LATIN CAPITAL LETTER I;So;0;L;;;;;N;;;;; +1F179;NEGATIVE SQUARED LATIN CAPITAL LETTER J;So;0;L;;;;;N;;;;; +1F17A;NEGATIVE SQUARED LATIN CAPITAL LETTER K;So;0;L;;;;;N;;;;; +1F17B;NEGATIVE SQUARED LATIN CAPITAL LETTER L;So;0;L;;;;;N;;;;; +1F17C;NEGATIVE SQUARED LATIN CAPITAL LETTER M;So;0;L;;;;;N;;;;; +1F17D;NEGATIVE SQUARED LATIN CAPITAL LETTER N;So;0;L;;;;;N;;;;; +1F17E;NEGATIVE SQUARED LATIN CAPITAL LETTER O;So;0;L;;;;;N;;;;; +1F17F;NEGATIVE SQUARED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;; +1F180;NEGATIVE SQUARED LATIN CAPITAL LETTER Q;So;0;L;;;;;N;;;;; +1F181;NEGATIVE SQUARED LATIN CAPITAL LETTER R;So;0;L;;;;;N;;;;; +1F182;NEGATIVE SQUARED LATIN CAPITAL LETTER S;So;0;L;;;;;N;;;;; +1F183;NEGATIVE SQUARED LATIN CAPITAL LETTER T;So;0;L;;;;;N;;;;; +1F184;NEGATIVE SQUARED LATIN CAPITAL LETTER U;So;0;L;;;;;N;;;;; +1F185;NEGATIVE SQUARED LATIN CAPITAL LETTER V;So;0;L;;;;;N;;;;; +1F186;NEGATIVE SQUARED LATIN CAPITAL LETTER W;So;0;L;;;;;N;;;;; +1F187;NEGATIVE SQUARED LATIN CAPITAL LETTER X;So;0;L;;;;;N;;;;; +1F188;NEGATIVE SQUARED LATIN CAPITAL LETTER Y;So;0;L;;;;;N;;;;; +1F189;NEGATIVE SQUARED LATIN CAPITAL LETTER Z;So;0;L;;;;;N;;;;; +1F18A;CROSSED NEGATIVE SQUARED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;; +1F18B;NEGATIVE SQUARED IC;So;0;L;;;;;N;;;;; +1F18C;NEGATIVE SQUARED PA;So;0;L;;;;;N;;;;; +1F18D;NEGATIVE SQUARED SA;So;0;L;;;;;N;;;;; +1F18E;NEGATIVE SQUARED AB;So;0;L;;;;;N;;;;; +1F18F;NEGATIVE SQUARED WC;So;0;L;;;;;N;;;;; +1F190;SQUARE DJ;So;0;L; 0044 004A;;;;N;;;;; +1F191;SQUARED CL;So;0;L;;;;;N;;;;; +1F192;SQUARED COOL;So;0;L;;;;;N;;;;; +1F193;SQUARED FREE;So;0;L;;;;;N;;;;; +1F194;SQUARED ID;So;0;L;;;;;N;;;;; +1F195;SQUARED NEW;So;0;L;;;;;N;;;;; +1F196;SQUARED NG;So;0;L;;;;;N;;;;; +1F197;SQUARED OK;So;0;L;;;;;N;;;;; +1F198;SQUARED SOS;So;0;L;;;;;N;;;;; +1F199;SQUARED UP WITH EXCLAMATION MARK;So;0;L;;;;;N;;;;; +1F19A;SQUARED VS;So;0;L;;;;;N;;;;; +1F19B;SQUARED THREE D;So;0;L;;;;;N;;;;; +1F19C;SQUARED SECOND SCREEN;So;0;L;;;;;N;;;;; +1F19D;SQUARED TWO K;So;0;L;;;;;N;;;;; +1F19E;SQUARED FOUR K;So;0;L;;;;;N;;;;; +1F19F;SQUARED EIGHT K;So;0;L;;;;;N;;;;; +1F1A0;SQUARED FIVE POINT ONE;So;0;L;;;;;N;;;;; +1F1A1;SQUARED SEVEN POINT ONE;So;0;L;;;;;N;;;;; +1F1A2;SQUARED TWENTY-TWO POINT TWO;So;0;L;;;;;N;;;;; +1F1A3;SQUARED SIXTY P;So;0;L;;;;;N;;;;; +1F1A4;SQUARED ONE HUNDRED TWENTY P;So;0;L;;;;;N;;;;; +1F1A5;SQUARED LATIN SMALL LETTER D;So;0;L;;;;;N;;;;; +1F1A6;SQUARED HC;So;0;L;;;;;N;;;;; +1F1A7;SQUARED HDR;So;0;L;;;;;N;;;;; +1F1A8;SQUARED HI-RES;So;0;L;;;;;N;;;;; +1F1A9;SQUARED LOSSLESS;So;0;L;;;;;N;;;;; +1F1AA;SQUARED SHV;So;0;L;;;;;N;;;;; +1F1AB;SQUARED UHD;So;0;L;;;;;N;;;;; +1F1AC;SQUARED VOD;So;0;L;;;;;N;;;;; +1F1E6;REGIONAL INDICATOR SYMBOL LETTER A;So;0;L;;;;;N;;;;; +1F1E7;REGIONAL INDICATOR SYMBOL LETTER B;So;0;L;;;;;N;;;;; +1F1E8;REGIONAL INDICATOR SYMBOL LETTER C;So;0;L;;;;;N;;;;; +1F1E9;REGIONAL INDICATOR SYMBOL LETTER D;So;0;L;;;;;N;;;;; +1F1EA;REGIONAL INDICATOR SYMBOL LETTER E;So;0;L;;;;;N;;;;; +1F1EB;REGIONAL INDICATOR SYMBOL LETTER F;So;0;L;;;;;N;;;;; +1F1EC;REGIONAL INDICATOR SYMBOL LETTER G;So;0;L;;;;;N;;;;; +1F1ED;REGIONAL INDICATOR SYMBOL LETTER H;So;0;L;;;;;N;;;;; +1F1EE;REGIONAL INDICATOR SYMBOL LETTER I;So;0;L;;;;;N;;;;; +1F1EF;REGIONAL INDICATOR SYMBOL LETTER J;So;0;L;;;;;N;;;;; +1F1F0;REGIONAL INDICATOR SYMBOL LETTER K;So;0;L;;;;;N;;;;; +1F1F1;REGIONAL INDICATOR SYMBOL LETTER L;So;0;L;;;;;N;;;;; +1F1F2;REGIONAL INDICATOR SYMBOL LETTER M;So;0;L;;;;;N;;;;; +1F1F3;REGIONAL INDICATOR SYMBOL LETTER N;So;0;L;;;;;N;;;;; +1F1F4;REGIONAL INDICATOR SYMBOL LETTER O;So;0;L;;;;;N;;;;; +1F1F5;REGIONAL INDICATOR SYMBOL LETTER P;So;0;L;;;;;N;;;;; +1F1F6;REGIONAL INDICATOR SYMBOL LETTER Q;So;0;L;;;;;N;;;;; +1F1F7;REGIONAL INDICATOR SYMBOL LETTER R;So;0;L;;;;;N;;;;; +1F1F8;REGIONAL INDICATOR SYMBOL LETTER S;So;0;L;;;;;N;;;;; +1F1F9;REGIONAL INDICATOR SYMBOL LETTER T;So;0;L;;;;;N;;;;; +1F1FA;REGIONAL INDICATOR SYMBOL LETTER U;So;0;L;;;;;N;;;;; +1F1FB;REGIONAL INDICATOR SYMBOL LETTER V;So;0;L;;;;;N;;;;; +1F1FC;REGIONAL INDICATOR SYMBOL LETTER W;So;0;L;;;;;N;;;;; +1F1FD;REGIONAL INDICATOR SYMBOL LETTER X;So;0;L;;;;;N;;;;; +1F1FE;REGIONAL INDICATOR SYMBOL LETTER Y;So;0;L;;;;;N;;;;; +1F1FF;REGIONAL INDICATOR SYMBOL LETTER Z;So;0;L;;;;;N;;;;; +1F200;SQUARE HIRAGANA HOKA;So;0;L; 307B 304B;;;;N;;;;; +1F201;SQUARED KATAKANA KOKO;So;0;L; 30B3 30B3;;;;N;;;;; +1F202;SQUARED KATAKANA SA;So;0;L; 30B5;;;;N;;;;; +1F210;SQUARED CJK UNIFIED IDEOGRAPH-624B;So;0;L; 624B;;;;N;;;;; +1F211;SQUARED CJK UNIFIED IDEOGRAPH-5B57;So;0;L; 5B57;;;;N;;;;; +1F212;SQUARED CJK UNIFIED IDEOGRAPH-53CC;So;0;L; 53CC;;;;N;;;;; +1F213;SQUARED KATAKANA DE;So;0;L; 30C7;;;;N;;;;; +1F214;SQUARED CJK UNIFIED IDEOGRAPH-4E8C;So;0;L; 4E8C;;;;N;;;;; +1F215;SQUARED CJK UNIFIED IDEOGRAPH-591A;So;0;L; 591A;;;;N;;;;; +1F216;SQUARED CJK UNIFIED IDEOGRAPH-89E3;So;0;L; 89E3;;;;N;;;;; +1F217;SQUARED CJK UNIFIED IDEOGRAPH-5929;So;0;L; 5929;;;;N;;;;; +1F218;SQUARED CJK UNIFIED IDEOGRAPH-4EA4;So;0;L; 4EA4;;;;N;;;;; +1F219;SQUARED CJK UNIFIED IDEOGRAPH-6620;So;0;L; 6620;;;;N;;;;; +1F21A;SQUARED CJK UNIFIED IDEOGRAPH-7121;So;0;L; 7121;;;;N;;;;; +1F21B;SQUARED CJK UNIFIED IDEOGRAPH-6599;So;0;L; 6599;;;;N;;;;; +1F21C;SQUARED CJK UNIFIED IDEOGRAPH-524D;So;0;L; 524D;;;;N;;;;; +1F21D;SQUARED CJK UNIFIED IDEOGRAPH-5F8C;So;0;L; 5F8C;;;;N;;;;; +1F21E;SQUARED CJK UNIFIED IDEOGRAPH-518D;So;0;L; 518D;;;;N;;;;; +1F21F;SQUARED CJK UNIFIED IDEOGRAPH-65B0;So;0;L; 65B0;;;;N;;;;; +1F220;SQUARED CJK UNIFIED IDEOGRAPH-521D;So;0;L; 521D;;;;N;;;;; +1F221;SQUARED CJK UNIFIED IDEOGRAPH-7D42;So;0;L; 7D42;;;;N;;;;; +1F222;SQUARED CJK UNIFIED IDEOGRAPH-751F;So;0;L; 751F;;;;N;;;;; +1F223;SQUARED CJK UNIFIED IDEOGRAPH-8CA9;So;0;L; 8CA9;;;;N;;;;; +1F224;SQUARED CJK UNIFIED IDEOGRAPH-58F0;So;0;L; 58F0;;;;N;;;;; +1F225;SQUARED CJK UNIFIED IDEOGRAPH-5439;So;0;L; 5439;;;;N;;;;; +1F226;SQUARED CJK UNIFIED IDEOGRAPH-6F14;So;0;L; 6F14;;;;N;;;;; +1F227;SQUARED CJK UNIFIED IDEOGRAPH-6295;So;0;L; 6295;;;;N;;;;; +1F228;SQUARED CJK UNIFIED IDEOGRAPH-6355;So;0;L; 6355;;;;N;;;;; +1F229;SQUARED CJK UNIFIED IDEOGRAPH-4E00;So;0;L; 4E00;;;;N;;;;; +1F22A;SQUARED CJK UNIFIED IDEOGRAPH-4E09;So;0;L; 4E09;;;;N;;;;; +1F22B;SQUARED CJK UNIFIED IDEOGRAPH-904A;So;0;L; 904A;;;;N;;;;; +1F22C;SQUARED CJK UNIFIED IDEOGRAPH-5DE6;So;0;L; 5DE6;;;;N;;;;; +1F22D;SQUARED CJK UNIFIED IDEOGRAPH-4E2D;So;0;L; 4E2D;;;;N;;;;; +1F22E;SQUARED CJK UNIFIED IDEOGRAPH-53F3;So;0;L; 53F3;;;;N;;;;; +1F22F;SQUARED CJK UNIFIED IDEOGRAPH-6307;So;0;L; 6307;;;;N;;;;; +1F230;SQUARED CJK UNIFIED IDEOGRAPH-8D70;So;0;L; 8D70;;;;N;;;;; +1F231;SQUARED CJK UNIFIED IDEOGRAPH-6253;So;0;L; 6253;;;;N;;;;; +1F232;SQUARED CJK UNIFIED IDEOGRAPH-7981;So;0;L; 7981;;;;N;;;;; +1F233;SQUARED CJK UNIFIED IDEOGRAPH-7A7A;So;0;L; 7A7A;;;;N;;;;; +1F234;SQUARED CJK UNIFIED IDEOGRAPH-5408;So;0;L; 5408;;;;N;;;;; +1F235;SQUARED CJK UNIFIED IDEOGRAPH-6E80;So;0;L; 6E80;;;;N;;;;; +1F236;SQUARED CJK UNIFIED IDEOGRAPH-6709;So;0;L; 6709;;;;N;;;;; +1F237;SQUARED CJK UNIFIED IDEOGRAPH-6708;So;0;L; 6708;;;;N;;;;; +1F238;SQUARED CJK UNIFIED IDEOGRAPH-7533;So;0;L; 7533;;;;N;;;;; +1F239;SQUARED CJK UNIFIED IDEOGRAPH-5272;So;0;L; 5272;;;;N;;;;; +1F23A;SQUARED CJK UNIFIED IDEOGRAPH-55B6;So;0;L; 55B6;;;;N;;;;; +1F23B;SQUARED CJK UNIFIED IDEOGRAPH-914D;So;0;L; 914D;;;;N;;;;; +1F240;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C;So;0;L; 3014 672C 3015;;;;N;;;;; +1F241;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E09;So;0;L; 3014 4E09 3015;;;;N;;;;; +1F242;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E8C;So;0;L; 3014 4E8C 3015;;;;N;;;;; +1F243;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-5B89;So;0;L; 3014 5B89 3015;;;;N;;;;; +1F244;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-70B9;So;0;L; 3014 70B9 3015;;;;N;;;;; +1F245;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6253;So;0;L; 3014 6253 3015;;;;N;;;;; +1F246;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-76D7;So;0;L; 3014 76D7 3015;;;;N;;;;; +1F247;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-52DD;So;0;L; 3014 52DD 3015;;;;N;;;;; +1F248;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557;So;0;L; 3014 6557 3015;;;;N;;;;; +1F250;CIRCLED IDEOGRAPH ADVANTAGE;So;0;L; 5F97;;;;N;;;;; +1F251;CIRCLED IDEOGRAPH ACCEPT;So;0;L; 53EF;;;;N;;;;; +1F260;ROUNDED SYMBOL FOR FU;So;0;ON;;;;;N;;;;; +1F261;ROUNDED SYMBOL FOR LU;So;0;ON;;;;;N;;;;; +1F262;ROUNDED SYMBOL FOR SHOU;So;0;ON;;;;;N;;;;; +1F263;ROUNDED SYMBOL FOR XI;So;0;ON;;;;;N;;;;; +1F264;ROUNDED SYMBOL FOR SHUANGXI;So;0;ON;;;;;N;;;;; +1F265;ROUNDED SYMBOL FOR CAI;So;0;ON;;;;;N;;;;; +1F300;CYCLONE;So;0;ON;;;;;N;;;;; +1F301;FOGGY;So;0;ON;;;;;N;;;;; +1F302;CLOSED UMBRELLA;So;0;ON;;;;;N;;;;; +1F303;NIGHT WITH STARS;So;0;ON;;;;;N;;;;; +1F304;SUNRISE OVER MOUNTAINS;So;0;ON;;;;;N;;;;; +1F305;SUNRISE;So;0;ON;;;;;N;;;;; +1F306;CITYSCAPE AT DUSK;So;0;ON;;;;;N;;;;; +1F307;SUNSET OVER BUILDINGS;So;0;ON;;;;;N;;;;; +1F308;RAINBOW;So;0;ON;;;;;N;;;;; +1F309;BRIDGE AT NIGHT;So;0;ON;;;;;N;;;;; +1F30A;WATER WAVE;So;0;ON;;;;;N;;;;; +1F30B;VOLCANO;So;0;ON;;;;;N;;;;; +1F30C;MILKY WAY;So;0;ON;;;;;N;;;;; +1F30D;EARTH GLOBE EUROPE-AFRICA;So;0;ON;;;;;N;;;;; +1F30E;EARTH GLOBE AMERICAS;So;0;ON;;;;;N;;;;; +1F30F;EARTH GLOBE ASIA-AUSTRALIA;So;0;ON;;;;;N;;;;; +1F310;GLOBE WITH MERIDIANS;So;0;ON;;;;;N;;;;; +1F311;NEW MOON SYMBOL;So;0;ON;;;;;N;;;;; +1F312;WAXING CRESCENT MOON SYMBOL;So;0;ON;;;;;N;;;;; +1F313;FIRST QUARTER MOON SYMBOL;So;0;ON;;;;;N;;;;; +1F314;WAXING GIBBOUS MOON SYMBOL;So;0;ON;;;;;N;;;;; +1F315;FULL MOON SYMBOL;So;0;ON;;;;;N;;;;; +1F316;WANING GIBBOUS MOON SYMBOL;So;0;ON;;;;;N;;;;; +1F317;LAST QUARTER MOON SYMBOL;So;0;ON;;;;;N;;;;; +1F318;WANING CRESCENT MOON SYMBOL;So;0;ON;;;;;N;;;;; +1F319;CRESCENT MOON;So;0;ON;;;;;N;;;;; +1F31A;NEW MOON WITH FACE;So;0;ON;;;;;N;;;;; +1F31B;FIRST QUARTER MOON WITH FACE;So;0;ON;;;;;N;;;;; +1F31C;LAST QUARTER MOON WITH FACE;So;0;ON;;;;;N;;;;; +1F31D;FULL MOON WITH FACE;So;0;ON;;;;;N;;;;; +1F31E;SUN WITH FACE;So;0;ON;;;;;N;;;;; +1F31F;GLOWING STAR;So;0;ON;;;;;N;;;;; +1F320;SHOOTING STAR;So;0;ON;;;;;N;;;;; +1F321;THERMOMETER;So;0;ON;;;;;N;;;;; +1F322;BLACK DROPLET;So;0;ON;;;;;N;;;;; +1F323;WHITE SUN;So;0;ON;;;;;N;;;;; +1F324;WHITE SUN WITH SMALL CLOUD;So;0;ON;;;;;N;;;;; +1F325;WHITE SUN BEHIND CLOUD;So;0;ON;;;;;N;;;;; +1F326;WHITE SUN BEHIND CLOUD WITH RAIN;So;0;ON;;;;;N;;;;; +1F327;CLOUD WITH RAIN;So;0;ON;;;;;N;;;;; +1F328;CLOUD WITH SNOW;So;0;ON;;;;;N;;;;; +1F329;CLOUD WITH LIGHTNING;So;0;ON;;;;;N;;;;; +1F32A;CLOUD WITH TORNADO;So;0;ON;;;;;N;;;;; +1F32B;FOG;So;0;ON;;;;;N;;;;; +1F32C;WIND BLOWING FACE;So;0;ON;;;;;N;;;;; +1F32D;HOT DOG;So;0;ON;;;;;N;;;;; +1F32E;TACO;So;0;ON;;;;;N;;;;; +1F32F;BURRITO;So;0;ON;;;;;N;;;;; +1F330;CHESTNUT;So;0;ON;;;;;N;;;;; +1F331;SEEDLING;So;0;ON;;;;;N;;;;; +1F332;EVERGREEN TREE;So;0;ON;;;;;N;;;;; +1F333;DECIDUOUS TREE;So;0;ON;;;;;N;;;;; +1F334;PALM TREE;So;0;ON;;;;;N;;;;; +1F335;CACTUS;So;0;ON;;;;;N;;;;; +1F336;HOT PEPPER;So;0;ON;;;;;N;;;;; +1F337;TULIP;So;0;ON;;;;;N;;;;; +1F338;CHERRY BLOSSOM;So;0;ON;;;;;N;;;;; +1F339;ROSE;So;0;ON;;;;;N;;;;; +1F33A;HIBISCUS;So;0;ON;;;;;N;;;;; +1F33B;SUNFLOWER;So;0;ON;;;;;N;;;;; +1F33C;BLOSSOM;So;0;ON;;;;;N;;;;; +1F33D;EAR OF MAIZE;So;0;ON;;;;;N;;;;; +1F33E;EAR OF RICE;So;0;ON;;;;;N;;;;; +1F33F;HERB;So;0;ON;;;;;N;;;;; +1F340;FOUR LEAF CLOVER;So;0;ON;;;;;N;;;;; +1F341;MAPLE LEAF;So;0;ON;;;;;N;;;;; +1F342;FALLEN LEAF;So;0;ON;;;;;N;;;;; +1F343;LEAF FLUTTERING IN WIND;So;0;ON;;;;;N;;;;; +1F344;MUSHROOM;So;0;ON;;;;;N;;;;; +1F345;TOMATO;So;0;ON;;;;;N;;;;; +1F346;AUBERGINE;So;0;ON;;;;;N;;;;; +1F347;GRAPES;So;0;ON;;;;;N;;;;; +1F348;MELON;So;0;ON;;;;;N;;;;; +1F349;WATERMELON;So;0;ON;;;;;N;;;;; +1F34A;TANGERINE;So;0;ON;;;;;N;;;;; +1F34B;LEMON;So;0;ON;;;;;N;;;;; +1F34C;BANANA;So;0;ON;;;;;N;;;;; +1F34D;PINEAPPLE;So;0;ON;;;;;N;;;;; +1F34E;RED APPLE;So;0;ON;;;;;N;;;;; +1F34F;GREEN APPLE;So;0;ON;;;;;N;;;;; +1F350;PEAR;So;0;ON;;;;;N;;;;; +1F351;PEACH;So;0;ON;;;;;N;;;;; +1F352;CHERRIES;So;0;ON;;;;;N;;;;; +1F353;STRAWBERRY;So;0;ON;;;;;N;;;;; +1F354;HAMBURGER;So;0;ON;;;;;N;;;;; +1F355;SLICE OF PIZZA;So;0;ON;;;;;N;;;;; +1F356;MEAT ON BONE;So;0;ON;;;;;N;;;;; +1F357;POULTRY LEG;So;0;ON;;;;;N;;;;; +1F358;RICE CRACKER;So;0;ON;;;;;N;;;;; +1F359;RICE BALL;So;0;ON;;;;;N;;;;; +1F35A;COOKED RICE;So;0;ON;;;;;N;;;;; +1F35B;CURRY AND RICE;So;0;ON;;;;;N;;;;; +1F35C;STEAMING BOWL;So;0;ON;;;;;N;;;;; +1F35D;SPAGHETTI;So;0;ON;;;;;N;;;;; +1F35E;BREAD;So;0;ON;;;;;N;;;;; +1F35F;FRENCH FRIES;So;0;ON;;;;;N;;;;; +1F360;ROASTED SWEET POTATO;So;0;ON;;;;;N;;;;; +1F361;DANGO;So;0;ON;;;;;N;;;;; +1F362;ODEN;So;0;ON;;;;;N;;;;; +1F363;SUSHI;So;0;ON;;;;;N;;;;; +1F364;FRIED SHRIMP;So;0;ON;;;;;N;;;;; +1F365;FISH CAKE WITH SWIRL DESIGN;So;0;ON;;;;;N;;;;; +1F366;SOFT ICE CREAM;So;0;ON;;;;;N;;;;; +1F367;SHAVED ICE;So;0;ON;;;;;N;;;;; +1F368;ICE CREAM;So;0;ON;;;;;N;;;;; +1F369;DOUGHNUT;So;0;ON;;;;;N;;;;; +1F36A;COOKIE;So;0;ON;;;;;N;;;;; +1F36B;CHOCOLATE BAR;So;0;ON;;;;;N;;;;; +1F36C;CANDY;So;0;ON;;;;;N;;;;; +1F36D;LOLLIPOP;So;0;ON;;;;;N;;;;; +1F36E;CUSTARD;So;0;ON;;;;;N;;;;; +1F36F;HONEY POT;So;0;ON;;;;;N;;;;; +1F370;SHORTCAKE;So;0;ON;;;;;N;;;;; +1F371;BENTO BOX;So;0;ON;;;;;N;;;;; +1F372;POT OF FOOD;So;0;ON;;;;;N;;;;; +1F373;COOKING;So;0;ON;;;;;N;;;;; +1F374;FORK AND KNIFE;So;0;ON;;;;;N;;;;; +1F375;TEACUP WITHOUT HANDLE;So;0;ON;;;;;N;;;;; +1F376;SAKE BOTTLE AND CUP;So;0;ON;;;;;N;;;;; +1F377;WINE GLASS;So;0;ON;;;;;N;;;;; +1F378;COCKTAIL GLASS;So;0;ON;;;;;N;;;;; +1F379;TROPICAL DRINK;So;0;ON;;;;;N;;;;; +1F37A;BEER MUG;So;0;ON;;;;;N;;;;; +1F37B;CLINKING BEER MUGS;So;0;ON;;;;;N;;;;; +1F37C;BABY BOTTLE;So;0;ON;;;;;N;;;;; +1F37D;FORK AND KNIFE WITH PLATE;So;0;ON;;;;;N;;;;; +1F37E;BOTTLE WITH POPPING CORK;So;0;ON;;;;;N;;;;; +1F37F;POPCORN;So;0;ON;;;;;N;;;;; +1F380;RIBBON;So;0;ON;;;;;N;;;;; +1F381;WRAPPED PRESENT;So;0;ON;;;;;N;;;;; +1F382;BIRTHDAY CAKE;So;0;ON;;;;;N;;;;; +1F383;JACK-O-LANTERN;So;0;ON;;;;;N;;;;; +1F384;CHRISTMAS TREE;So;0;ON;;;;;N;;;;; +1F385;FATHER CHRISTMAS;So;0;ON;;;;;N;;;;; +1F386;FIREWORKS;So;0;ON;;;;;N;;;;; +1F387;FIREWORK SPARKLER;So;0;ON;;;;;N;;;;; +1F388;BALLOON;So;0;ON;;;;;N;;;;; +1F389;PARTY POPPER;So;0;ON;;;;;N;;;;; +1F38A;CONFETTI BALL;So;0;ON;;;;;N;;;;; +1F38B;TANABATA TREE;So;0;ON;;;;;N;;;;; +1F38C;CROSSED FLAGS;So;0;ON;;;;;N;;;;; +1F38D;PINE DECORATION;So;0;ON;;;;;N;;;;; +1F38E;JAPANESE DOLLS;So;0;ON;;;;;N;;;;; +1F38F;CARP STREAMER;So;0;ON;;;;;N;;;;; +1F390;WIND CHIME;So;0;ON;;;;;N;;;;; +1F391;MOON VIEWING CEREMONY;So;0;ON;;;;;N;;;;; +1F392;SCHOOL SATCHEL;So;0;ON;;;;;N;;;;; +1F393;GRADUATION CAP;So;0;ON;;;;;N;;;;; +1F394;HEART WITH TIP ON THE LEFT;So;0;ON;;;;;N;;;;; +1F395;BOUQUET OF FLOWERS;So;0;ON;;;;;N;;;;; +1F396;MILITARY MEDAL;So;0;ON;;;;;N;;;;; +1F397;REMINDER RIBBON;So;0;ON;;;;;N;;;;; +1F398;MUSICAL KEYBOARD WITH JACKS;So;0;ON;;;;;N;;;;; +1F399;STUDIO MICROPHONE;So;0;ON;;;;;N;;;;; +1F39A;LEVEL SLIDER;So;0;ON;;;;;N;;;;; +1F39B;CONTROL KNOBS;So;0;ON;;;;;N;;;;; +1F39C;BEAMED ASCENDING MUSICAL NOTES;So;0;ON;;;;;N;;;;; +1F39D;BEAMED DESCENDING MUSICAL NOTES;So;0;ON;;;;;N;;;;; +1F39E;FILM FRAMES;So;0;ON;;;;;N;;;;; +1F39F;ADMISSION TICKETS;So;0;ON;;;;;N;;;;; +1F3A0;CAROUSEL HORSE;So;0;ON;;;;;N;;;;; +1F3A1;FERRIS WHEEL;So;0;ON;;;;;N;;;;; +1F3A2;ROLLER COASTER;So;0;ON;;;;;N;;;;; +1F3A3;FISHING POLE AND FISH;So;0;ON;;;;;N;;;;; +1F3A4;MICROPHONE;So;0;ON;;;;;N;;;;; +1F3A5;MOVIE CAMERA;So;0;ON;;;;;N;;;;; +1F3A6;CINEMA;So;0;ON;;;;;N;;;;; +1F3A7;HEADPHONE;So;0;ON;;;;;N;;;;; +1F3A8;ARTIST PALETTE;So;0;ON;;;;;N;;;;; +1F3A9;TOP HAT;So;0;ON;;;;;N;;;;; +1F3AA;CIRCUS TENT;So;0;ON;;;;;N;;;;; +1F3AB;TICKET;So;0;ON;;;;;N;;;;; +1F3AC;CLAPPER BOARD;So;0;ON;;;;;N;;;;; +1F3AD;PERFORMING ARTS;So;0;ON;;;;;N;;;;; +1F3AE;VIDEO GAME;So;0;ON;;;;;N;;;;; +1F3AF;DIRECT HIT;So;0;ON;;;;;N;;;;; +1F3B0;SLOT MACHINE;So;0;ON;;;;;N;;;;; +1F3B1;BILLIARDS;So;0;ON;;;;;N;;;;; +1F3B2;GAME DIE;So;0;ON;;;;;N;;;;; +1F3B3;BOWLING;So;0;ON;;;;;N;;;;; +1F3B4;FLOWER PLAYING CARDS;So;0;ON;;;;;N;;;;; +1F3B5;MUSICAL NOTE;So;0;ON;;;;;N;;;;; +1F3B6;MULTIPLE MUSICAL NOTES;So;0;ON;;;;;N;;;;; +1F3B7;SAXOPHONE;So;0;ON;;;;;N;;;;; +1F3B8;GUITAR;So;0;ON;;;;;N;;;;; +1F3B9;MUSICAL KEYBOARD;So;0;ON;;;;;N;;;;; +1F3BA;TRUMPET;So;0;ON;;;;;N;;;;; +1F3BB;VIOLIN;So;0;ON;;;;;N;;;;; +1F3BC;MUSICAL SCORE;So;0;ON;;;;;N;;;;; +1F3BD;RUNNING SHIRT WITH SASH;So;0;ON;;;;;N;;;;; +1F3BE;TENNIS RACQUET AND BALL;So;0;ON;;;;;N;;;;; +1F3BF;SKI AND SKI BOOT;So;0;ON;;;;;N;;;;; +1F3C0;BASKETBALL AND HOOP;So;0;ON;;;;;N;;;;; +1F3C1;CHEQUERED FLAG;So;0;ON;;;;;N;;;;; +1F3C2;SNOWBOARDER;So;0;ON;;;;;N;;;;; +1F3C3;RUNNER;So;0;ON;;;;;N;;;;; +1F3C4;SURFER;So;0;ON;;;;;N;;;;; +1F3C5;SPORTS MEDAL;So;0;ON;;;;;N;;;;; +1F3C6;TROPHY;So;0;ON;;;;;N;;;;; +1F3C7;HORSE RACING;So;0;ON;;;;;N;;;;; +1F3C8;AMERICAN FOOTBALL;So;0;ON;;;;;N;;;;; +1F3C9;RUGBY FOOTBALL;So;0;ON;;;;;N;;;;; +1F3CA;SWIMMER;So;0;ON;;;;;N;;;;; +1F3CB;WEIGHT LIFTER;So;0;ON;;;;;N;;;;; +1F3CC;GOLFER;So;0;ON;;;;;N;;;;; +1F3CD;RACING MOTORCYCLE;So;0;ON;;;;;N;;;;; +1F3CE;RACING CAR;So;0;ON;;;;;N;;;;; +1F3CF;CRICKET BAT AND BALL;So;0;ON;;;;;N;;;;; +1F3D0;VOLLEYBALL;So;0;ON;;;;;N;;;;; +1F3D1;FIELD HOCKEY STICK AND BALL;So;0;ON;;;;;N;;;;; +1F3D2;ICE HOCKEY STICK AND PUCK;So;0;ON;;;;;N;;;;; +1F3D3;TABLE TENNIS PADDLE AND BALL;So;0;ON;;;;;N;;;;; +1F3D4;SNOW CAPPED MOUNTAIN;So;0;ON;;;;;N;;;;; +1F3D5;CAMPING;So;0;ON;;;;;N;;;;; +1F3D6;BEACH WITH UMBRELLA;So;0;ON;;;;;N;;;;; +1F3D7;BUILDING CONSTRUCTION;So;0;ON;;;;;N;;;;; +1F3D8;HOUSE BUILDINGS;So;0;ON;;;;;N;;;;; +1F3D9;CITYSCAPE;So;0;ON;;;;;N;;;;; +1F3DA;DERELICT HOUSE BUILDING;So;0;ON;;;;;N;;;;; +1F3DB;CLASSICAL BUILDING;So;0;ON;;;;;N;;;;; +1F3DC;DESERT;So;0;ON;;;;;N;;;;; +1F3DD;DESERT ISLAND;So;0;ON;;;;;N;;;;; +1F3DE;NATIONAL PARK;So;0;ON;;;;;N;;;;; +1F3DF;STADIUM;So;0;ON;;;;;N;;;;; +1F3E0;HOUSE BUILDING;So;0;ON;;;;;N;;;;; +1F3E1;HOUSE WITH GARDEN;So;0;ON;;;;;N;;;;; +1F3E2;OFFICE BUILDING;So;0;ON;;;;;N;;;;; +1F3E3;JAPANESE POST OFFICE;So;0;ON;;;;;N;;;;; +1F3E4;EUROPEAN POST OFFICE;So;0;ON;;;;;N;;;;; +1F3E5;HOSPITAL;So;0;ON;;;;;N;;;;; +1F3E6;BANK;So;0;ON;;;;;N;;;;; +1F3E7;AUTOMATED TELLER MACHINE;So;0;ON;;;;;N;;;;; +1F3E8;HOTEL;So;0;ON;;;;;N;;;;; +1F3E9;LOVE HOTEL;So;0;ON;;;;;N;;;;; +1F3EA;CONVENIENCE STORE;So;0;ON;;;;;N;;;;; +1F3EB;SCHOOL;So;0;ON;;;;;N;;;;; +1F3EC;DEPARTMENT STORE;So;0;ON;;;;;N;;;;; +1F3ED;FACTORY;So;0;ON;;;;;N;;;;; +1F3EE;IZAKAYA LANTERN;So;0;ON;;;;;N;;;;; +1F3EF;JAPANESE CASTLE;So;0;ON;;;;;N;;;;; +1F3F0;EUROPEAN CASTLE;So;0;ON;;;;;N;;;;; +1F3F1;WHITE PENNANT;So;0;ON;;;;;N;;;;; +1F3F2;BLACK PENNANT;So;0;ON;;;;;N;;;;; +1F3F3;WAVING WHITE FLAG;So;0;ON;;;;;N;;;;; +1F3F4;WAVING BLACK FLAG;So;0;ON;;;;;N;;;;; +1F3F5;ROSETTE;So;0;ON;;;;;N;;;;; +1F3F6;BLACK ROSETTE;So;0;ON;;;;;N;;;;; +1F3F7;LABEL;So;0;ON;;;;;N;;;;; +1F3F8;BADMINTON RACQUET AND SHUTTLECOCK;So;0;ON;;;;;N;;;;; +1F3F9;BOW AND ARROW;So;0;ON;;;;;N;;;;; +1F3FA;AMPHORA;So;0;ON;;;;;N;;;;; +1F3FB;EMOJI MODIFIER FITZPATRICK TYPE-1-2;Sk;0;ON;;;;;N;;;;; +1F3FC;EMOJI MODIFIER FITZPATRICK TYPE-3;Sk;0;ON;;;;;N;;;;; +1F3FD;EMOJI MODIFIER FITZPATRICK TYPE-4;Sk;0;ON;;;;;N;;;;; +1F3FE;EMOJI MODIFIER FITZPATRICK TYPE-5;Sk;0;ON;;;;;N;;;;; +1F3FF;EMOJI MODIFIER FITZPATRICK TYPE-6;Sk;0;ON;;;;;N;;;;; +1F400;RAT;So;0;ON;;;;;N;;;;; +1F401;MOUSE;So;0;ON;;;;;N;;;;; +1F402;OX;So;0;ON;;;;;N;;;;; +1F403;WATER BUFFALO;So;0;ON;;;;;N;;;;; +1F404;COW;So;0;ON;;;;;N;;;;; +1F405;TIGER;So;0;ON;;;;;N;;;;; +1F406;LEOPARD;So;0;ON;;;;;N;;;;; +1F407;RABBIT;So;0;ON;;;;;N;;;;; +1F408;CAT;So;0;ON;;;;;N;;;;; +1F409;DRAGON;So;0;ON;;;;;N;;;;; +1F40A;CROCODILE;So;0;ON;;;;;N;;;;; +1F40B;WHALE;So;0;ON;;;;;N;;;;; +1F40C;SNAIL;So;0;ON;;;;;N;;;;; +1F40D;SNAKE;So;0;ON;;;;;N;;;;; +1F40E;HORSE;So;0;ON;;;;;N;;;;; +1F40F;RAM;So;0;ON;;;;;N;;;;; +1F410;GOAT;So;0;ON;;;;;N;;;;; +1F411;SHEEP;So;0;ON;;;;;N;;;;; +1F412;MONKEY;So;0;ON;;;;;N;;;;; +1F413;ROOSTER;So;0;ON;;;;;N;;;;; +1F414;CHICKEN;So;0;ON;;;;;N;;;;; +1F415;DOG;So;0;ON;;;;;N;;;;; +1F416;PIG;So;0;ON;;;;;N;;;;; +1F417;BOAR;So;0;ON;;;;;N;;;;; +1F418;ELEPHANT;So;0;ON;;;;;N;;;;; +1F419;OCTOPUS;So;0;ON;;;;;N;;;;; +1F41A;SPIRAL SHELL;So;0;ON;;;;;N;;;;; +1F41B;BUG;So;0;ON;;;;;N;;;;; +1F41C;ANT;So;0;ON;;;;;N;;;;; +1F41D;HONEYBEE;So;0;ON;;;;;N;;;;; +1F41E;LADY BEETLE;So;0;ON;;;;;N;;;;; +1F41F;FISH;So;0;ON;;;;;N;;;;; +1F420;TROPICAL FISH;So;0;ON;;;;;N;;;;; +1F421;BLOWFISH;So;0;ON;;;;;N;;;;; +1F422;TURTLE;So;0;ON;;;;;N;;;;; +1F423;HATCHING CHICK;So;0;ON;;;;;N;;;;; +1F424;BABY CHICK;So;0;ON;;;;;N;;;;; +1F425;FRONT-FACING BABY CHICK;So;0;ON;;;;;N;;;;; +1F426;BIRD;So;0;ON;;;;;N;;;;; +1F427;PENGUIN;So;0;ON;;;;;N;;;;; +1F428;KOALA;So;0;ON;;;;;N;;;;; +1F429;POODLE;So;0;ON;;;;;N;;;;; +1F42A;DROMEDARY CAMEL;So;0;ON;;;;;N;;;;; +1F42B;BACTRIAN CAMEL;So;0;ON;;;;;N;;;;; +1F42C;DOLPHIN;So;0;ON;;;;;N;;;;; +1F42D;MOUSE FACE;So;0;ON;;;;;N;;;;; +1F42E;COW FACE;So;0;ON;;;;;N;;;;; +1F42F;TIGER FACE;So;0;ON;;;;;N;;;;; +1F430;RABBIT FACE;So;0;ON;;;;;N;;;;; +1F431;CAT FACE;So;0;ON;;;;;N;;;;; +1F432;DRAGON FACE;So;0;ON;;;;;N;;;;; +1F433;SPOUTING WHALE;So;0;ON;;;;;N;;;;; +1F434;HORSE FACE;So;0;ON;;;;;N;;;;; +1F435;MONKEY FACE;So;0;ON;;;;;N;;;;; +1F436;DOG FACE;So;0;ON;;;;;N;;;;; +1F437;PIG FACE;So;0;ON;;;;;N;;;;; +1F438;FROG FACE;So;0;ON;;;;;N;;;;; +1F439;HAMSTER FACE;So;0;ON;;;;;N;;;;; +1F43A;WOLF FACE;So;0;ON;;;;;N;;;;; +1F43B;BEAR FACE;So;0;ON;;;;;N;;;;; +1F43C;PANDA FACE;So;0;ON;;;;;N;;;;; +1F43D;PIG NOSE;So;0;ON;;;;;N;;;;; +1F43E;PAW PRINTS;So;0;ON;;;;;N;;;;; +1F43F;CHIPMUNK;So;0;ON;;;;;N;;;;; +1F440;EYES;So;0;ON;;;;;N;;;;; +1F441;EYE;So;0;ON;;;;;N;;;;; +1F442;EAR;So;0;ON;;;;;N;;;;; +1F443;NOSE;So;0;ON;;;;;N;;;;; +1F444;MOUTH;So;0;ON;;;;;N;;;;; +1F445;TONGUE;So;0;ON;;;;;N;;;;; +1F446;WHITE UP POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;; +1F447;WHITE DOWN POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;; +1F448;WHITE LEFT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;; +1F449;WHITE RIGHT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;; +1F44A;FISTED HAND SIGN;So;0;ON;;;;;N;;;;; +1F44B;WAVING HAND SIGN;So;0;ON;;;;;N;;;;; +1F44C;OK HAND SIGN;So;0;ON;;;;;N;;;;; +1F44D;THUMBS UP SIGN;So;0;ON;;;;;N;;;;; +1F44E;THUMBS DOWN SIGN;So;0;ON;;;;;N;;;;; +1F44F;CLAPPING HANDS SIGN;So;0;ON;;;;;N;;;;; +1F450;OPEN HANDS SIGN;So;0;ON;;;;;N;;;;; +1F451;CROWN;So;0;ON;;;;;N;;;;; +1F452;WOMANS HAT;So;0;ON;;;;;N;;;;; +1F453;EYEGLASSES;So;0;ON;;;;;N;;;;; +1F454;NECKTIE;So;0;ON;;;;;N;;;;; +1F455;T-SHIRT;So;0;ON;;;;;N;;;;; +1F456;JEANS;So;0;ON;;;;;N;;;;; +1F457;DRESS;So;0;ON;;;;;N;;;;; +1F458;KIMONO;So;0;ON;;;;;N;;;;; +1F459;BIKINI;So;0;ON;;;;;N;;;;; +1F45A;WOMANS CLOTHES;So;0;ON;;;;;N;;;;; +1F45B;PURSE;So;0;ON;;;;;N;;;;; +1F45C;HANDBAG;So;0;ON;;;;;N;;;;; +1F45D;POUCH;So;0;ON;;;;;N;;;;; +1F45E;MANS SHOE;So;0;ON;;;;;N;;;;; +1F45F;ATHLETIC SHOE;So;0;ON;;;;;N;;;;; +1F460;HIGH-HEELED SHOE;So;0;ON;;;;;N;;;;; +1F461;WOMANS SANDAL;So;0;ON;;;;;N;;;;; +1F462;WOMANS BOOTS;So;0;ON;;;;;N;;;;; +1F463;FOOTPRINTS;So;0;ON;;;;;N;;;;; +1F464;BUST IN SILHOUETTE;So;0;ON;;;;;N;;;;; +1F465;BUSTS IN SILHOUETTE;So;0;ON;;;;;N;;;;; +1F466;BOY;So;0;ON;;;;;N;;;;; +1F467;GIRL;So;0;ON;;;;;N;;;;; +1F468;MAN;So;0;ON;;;;;N;;;;; +1F469;WOMAN;So;0;ON;;;;;N;;;;; +1F46A;FAMILY;So;0;ON;;;;;N;;;;; +1F46B;MAN AND WOMAN HOLDING HANDS;So;0;ON;;;;;N;;;;; +1F46C;TWO MEN HOLDING HANDS;So;0;ON;;;;;N;;;;; +1F46D;TWO WOMEN HOLDING HANDS;So;0;ON;;;;;N;;;;; +1F46E;POLICE OFFICER;So;0;ON;;;;;N;;;;; +1F46F;WOMAN WITH BUNNY EARS;So;0;ON;;;;;N;;;;; +1F470;BRIDE WITH VEIL;So;0;ON;;;;;N;;;;; +1F471;PERSON WITH BLOND HAIR;So;0;ON;;;;;N;;;;; +1F472;MAN WITH GUA PI MAO;So;0;ON;;;;;N;;;;; +1F473;MAN WITH TURBAN;So;0;ON;;;;;N;;;;; +1F474;OLDER MAN;So;0;ON;;;;;N;;;;; +1F475;OLDER WOMAN;So;0;ON;;;;;N;;;;; +1F476;BABY;So;0;ON;;;;;N;;;;; +1F477;CONSTRUCTION WORKER;So;0;ON;;;;;N;;;;; +1F478;PRINCESS;So;0;ON;;;;;N;;;;; +1F479;JAPANESE OGRE;So;0;ON;;;;;N;;;;; +1F47A;JAPANESE GOBLIN;So;0;ON;;;;;N;;;;; +1F47B;GHOST;So;0;ON;;;;;N;;;;; +1F47C;BABY ANGEL;So;0;ON;;;;;N;;;;; +1F47D;EXTRATERRESTRIAL ALIEN;So;0;ON;;;;;N;;;;; +1F47E;ALIEN MONSTER;So;0;ON;;;;;N;;;;; +1F47F;IMP;So;0;ON;;;;;N;;;;; +1F480;SKULL;So;0;ON;;;;;N;;;;; +1F481;INFORMATION DESK PERSON;So;0;ON;;;;;N;;;;; +1F482;GUARDSMAN;So;0;ON;;;;;N;;;;; +1F483;DANCER;So;0;ON;;;;;N;;;;; +1F484;LIPSTICK;So;0;ON;;;;;N;;;;; +1F485;NAIL POLISH;So;0;ON;;;;;N;;;;; +1F486;FACE MASSAGE;So;0;ON;;;;;N;;;;; +1F487;HAIRCUT;So;0;ON;;;;;N;;;;; +1F488;BARBER POLE;So;0;ON;;;;;N;;;;; +1F489;SYRINGE;So;0;ON;;;;;N;;;;; +1F48A;PILL;So;0;ON;;;;;N;;;;; +1F48B;KISS MARK;So;0;ON;;;;;N;;;;; +1F48C;LOVE LETTER;So;0;ON;;;;;N;;;;; +1F48D;RING;So;0;ON;;;;;N;;;;; +1F48E;GEM STONE;So;0;ON;;;;;N;;;;; +1F48F;KISS;So;0;ON;;;;;N;;;;; +1F490;BOUQUET;So;0;ON;;;;;N;;;;; +1F491;COUPLE WITH HEART;So;0;ON;;;;;N;;;;; +1F492;WEDDING;So;0;ON;;;;;N;;;;; +1F493;BEATING HEART;So;0;ON;;;;;N;;;;; +1F494;BROKEN HEART;So;0;ON;;;;;N;;;;; +1F495;TWO HEARTS;So;0;ON;;;;;N;;;;; +1F496;SPARKLING HEART;So;0;ON;;;;;N;;;;; +1F497;GROWING HEART;So;0;ON;;;;;N;;;;; +1F498;HEART WITH ARROW;So;0;ON;;;;;N;;;;; +1F499;BLUE HEART;So;0;ON;;;;;N;;;;; +1F49A;GREEN HEART;So;0;ON;;;;;N;;;;; +1F49B;YELLOW HEART;So;0;ON;;;;;N;;;;; +1F49C;PURPLE HEART;So;0;ON;;;;;N;;;;; +1F49D;HEART WITH RIBBON;So;0;ON;;;;;N;;;;; +1F49E;REVOLVING HEARTS;So;0;ON;;;;;N;;;;; +1F49F;HEART DECORATION;So;0;ON;;;;;N;;;;; +1F4A0;DIAMOND SHAPE WITH A DOT INSIDE;So;0;ON;;;;;N;;;;; +1F4A1;ELECTRIC LIGHT BULB;So;0;ON;;;;;N;;;;; +1F4A2;ANGER SYMBOL;So;0;ON;;;;;N;;;;; +1F4A3;BOMB;So;0;ON;;;;;N;;;;; +1F4A4;SLEEPING SYMBOL;So;0;ON;;;;;N;;;;; +1F4A5;COLLISION SYMBOL;So;0;ON;;;;;N;;;;; +1F4A6;SPLASHING SWEAT SYMBOL;So;0;ON;;;;;N;;;;; +1F4A7;DROPLET;So;0;ON;;;;;N;;;;; +1F4A8;DASH SYMBOL;So;0;ON;;;;;N;;;;; +1F4A9;PILE OF POO;So;0;ON;;;;;N;;;;; +1F4AA;FLEXED BICEPS;So;0;ON;;;;;N;;;;; +1F4AB;DIZZY SYMBOL;So;0;ON;;;;;N;;;;; +1F4AC;SPEECH BALLOON;So;0;ON;;;;;N;;;;; +1F4AD;THOUGHT BALLOON;So;0;ON;;;;;N;;;;; +1F4AE;WHITE FLOWER;So;0;ON;;;;;N;;;;; +1F4AF;HUNDRED POINTS SYMBOL;So;0;ON;;;;;N;;;;; +1F4B0;MONEY BAG;So;0;ON;;;;;N;;;;; +1F4B1;CURRENCY EXCHANGE;So;0;ON;;;;;N;;;;; +1F4B2;HEAVY DOLLAR SIGN;So;0;ON;;;;;N;;;;; +1F4B3;CREDIT CARD;So;0;ON;;;;;N;;;;; +1F4B4;BANKNOTE WITH YEN SIGN;So;0;ON;;;;;N;;;;; +1F4B5;BANKNOTE WITH DOLLAR SIGN;So;0;ON;;;;;N;;;;; +1F4B6;BANKNOTE WITH EURO SIGN;So;0;ON;;;;;N;;;;; +1F4B7;BANKNOTE WITH POUND SIGN;So;0;ON;;;;;N;;;;; +1F4B8;MONEY WITH WINGS;So;0;ON;;;;;N;;;;; +1F4B9;CHART WITH UPWARDS TREND AND YEN SIGN;So;0;ON;;;;;N;;;;; +1F4BA;SEAT;So;0;ON;;;;;N;;;;; +1F4BB;PERSONAL COMPUTER;So;0;ON;;;;;N;;;;; +1F4BC;BRIEFCASE;So;0;ON;;;;;N;;;;; +1F4BD;MINIDISC;So;0;ON;;;;;N;;;;; +1F4BE;FLOPPY DISK;So;0;ON;;;;;N;;;;; +1F4BF;OPTICAL DISC;So;0;ON;;;;;N;;;;; +1F4C0;DVD;So;0;ON;;;;;N;;;;; +1F4C1;FILE FOLDER;So;0;ON;;;;;N;;;;; +1F4C2;OPEN FILE FOLDER;So;0;ON;;;;;N;;;;; +1F4C3;PAGE WITH CURL;So;0;ON;;;;;N;;;;; +1F4C4;PAGE FACING UP;So;0;ON;;;;;N;;;;; +1F4C5;CALENDAR;So;0;ON;;;;;N;;;;; +1F4C6;TEAR-OFF CALENDAR;So;0;ON;;;;;N;;;;; +1F4C7;CARD INDEX;So;0;ON;;;;;N;;;;; +1F4C8;CHART WITH UPWARDS TREND;So;0;ON;;;;;N;;;;; +1F4C9;CHART WITH DOWNWARDS TREND;So;0;ON;;;;;N;;;;; +1F4CA;BAR CHART;So;0;ON;;;;;N;;;;; +1F4CB;CLIPBOARD;So;0;ON;;;;;N;;;;; +1F4CC;PUSHPIN;So;0;ON;;;;;N;;;;; +1F4CD;ROUND PUSHPIN;So;0;ON;;;;;N;;;;; +1F4CE;PAPERCLIP;So;0;ON;;;;;N;;;;; +1F4CF;STRAIGHT RULER;So;0;ON;;;;;N;;;;; +1F4D0;TRIANGULAR RULER;So;0;ON;;;;;N;;;;; +1F4D1;BOOKMARK TABS;So;0;ON;;;;;N;;;;; +1F4D2;LEDGER;So;0;ON;;;;;N;;;;; +1F4D3;NOTEBOOK;So;0;ON;;;;;N;;;;; +1F4D4;NOTEBOOK WITH DECORATIVE COVER;So;0;ON;;;;;N;;;;; +1F4D5;CLOSED BOOK;So;0;ON;;;;;N;;;;; +1F4D6;OPEN BOOK;So;0;ON;;;;;N;;;;; +1F4D7;GREEN BOOK;So;0;ON;;;;;N;;;;; +1F4D8;BLUE BOOK;So;0;ON;;;;;N;;;;; +1F4D9;ORANGE BOOK;So;0;ON;;;;;N;;;;; +1F4DA;BOOKS;So;0;ON;;;;;N;;;;; +1F4DB;NAME BADGE;So;0;ON;;;;;N;;;;; +1F4DC;SCROLL;So;0;ON;;;;;N;;;;; +1F4DD;MEMO;So;0;ON;;;;;N;;;;; +1F4DE;TELEPHONE RECEIVER;So;0;ON;;;;;N;;;;; +1F4DF;PAGER;So;0;ON;;;;;N;;;;; +1F4E0;FAX MACHINE;So;0;ON;;;;;N;;;;; +1F4E1;SATELLITE ANTENNA;So;0;ON;;;;;N;;;;; +1F4E2;PUBLIC ADDRESS LOUDSPEAKER;So;0;ON;;;;;N;;;;; +1F4E3;CHEERING MEGAPHONE;So;0;ON;;;;;N;;;;; +1F4E4;OUTBOX TRAY;So;0;ON;;;;;N;;;;; +1F4E5;INBOX TRAY;So;0;ON;;;;;N;;;;; +1F4E6;PACKAGE;So;0;ON;;;;;N;;;;; +1F4E7;E-MAIL SYMBOL;So;0;ON;;;;;N;;;;; +1F4E8;INCOMING ENVELOPE;So;0;ON;;;;;N;;;;; +1F4E9;ENVELOPE WITH DOWNWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;; +1F4EA;CLOSED MAILBOX WITH LOWERED FLAG;So;0;ON;;;;;N;;;;; +1F4EB;CLOSED MAILBOX WITH RAISED FLAG;So;0;ON;;;;;N;;;;; +1F4EC;OPEN MAILBOX WITH RAISED FLAG;So;0;ON;;;;;N;;;;; +1F4ED;OPEN MAILBOX WITH LOWERED FLAG;So;0;ON;;;;;N;;;;; +1F4EE;POSTBOX;So;0;ON;;;;;N;;;;; +1F4EF;POSTAL HORN;So;0;ON;;;;;N;;;;; +1F4F0;NEWSPAPER;So;0;ON;;;;;N;;;;; +1F4F1;MOBILE PHONE;So;0;ON;;;;;N;;;;; +1F4F2;MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT;So;0;ON;;;;;N;;;;; +1F4F3;VIBRATION MODE;So;0;ON;;;;;N;;;;; +1F4F4;MOBILE PHONE OFF;So;0;ON;;;;;N;;;;; +1F4F5;NO MOBILE PHONES;So;0;ON;;;;;N;;;;; +1F4F6;ANTENNA WITH BARS;So;0;ON;;;;;N;;;;; +1F4F7;CAMERA;So;0;ON;;;;;N;;;;; +1F4F8;CAMERA WITH FLASH;So;0;ON;;;;;N;;;;; +1F4F9;VIDEO CAMERA;So;0;ON;;;;;N;;;;; +1F4FA;TELEVISION;So;0;ON;;;;;N;;;;; +1F4FB;RADIO;So;0;ON;;;;;N;;;;; +1F4FC;VIDEOCASSETTE;So;0;ON;;;;;N;;;;; +1F4FD;FILM PROJECTOR;So;0;ON;;;;;N;;;;; +1F4FE;PORTABLE STEREO;So;0;ON;;;;;N;;;;; +1F4FF;PRAYER BEADS;So;0;ON;;;;;N;;;;; +1F500;TWISTED RIGHTWARDS ARROWS;So;0;ON;;;;;N;;;;; +1F501;CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS;So;0;ON;;;;;N;;;;; +1F502;CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS WITH CIRCLED ONE OVERLAY;So;0;ON;;;;;N;;;;; +1F503;CLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS;So;0;ON;;;;;N;;;;; +1F504;ANTICLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS;So;0;ON;;;;;N;;;;; +1F505;LOW BRIGHTNESS SYMBOL;So;0;ON;;;;;N;;;;; +1F506;HIGH BRIGHTNESS SYMBOL;So;0;ON;;;;;N;;;;; +1F507;SPEAKER WITH CANCELLATION STROKE;So;0;ON;;;;;N;;;;; +1F508;SPEAKER;So;0;ON;;;;;N;;;;; +1F509;SPEAKER WITH ONE SOUND WAVE;So;0;ON;;;;;N;;;;; +1F50A;SPEAKER WITH THREE SOUND WAVES;So;0;ON;;;;;N;;;;; +1F50B;BATTERY;So;0;ON;;;;;N;;;;; +1F50C;ELECTRIC PLUG;So;0;ON;;;;;N;;;;; +1F50D;LEFT-POINTING MAGNIFYING GLASS;So;0;ON;;;;;N;;;;; +1F50E;RIGHT-POINTING MAGNIFYING GLASS;So;0;ON;;;;;N;;;;; +1F50F;LOCK WITH INK PEN;So;0;ON;;;;;N;;;;; +1F510;CLOSED LOCK WITH KEY;So;0;ON;;;;;N;;;;; +1F511;KEY;So;0;ON;;;;;N;;;;; +1F512;LOCK;So;0;ON;;;;;N;;;;; +1F513;OPEN LOCK;So;0;ON;;;;;N;;;;; +1F514;BELL;So;0;ON;;;;;N;;;;; +1F515;BELL WITH CANCELLATION STROKE;So;0;ON;;;;;N;;;;; +1F516;BOOKMARK;So;0;ON;;;;;N;;;;; +1F517;LINK SYMBOL;So;0;ON;;;;;N;;;;; +1F518;RADIO BUTTON;So;0;ON;;;;;N;;;;; +1F519;BACK WITH LEFTWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;; +1F51A;END WITH LEFTWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;; +1F51B;ON WITH EXCLAMATION MARK WITH LEFT RIGHT ARROW ABOVE;So;0;ON;;;;;N;;;;; +1F51C;SOON WITH RIGHTWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;; +1F51D;TOP WITH UPWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;; +1F51E;NO ONE UNDER EIGHTEEN SYMBOL;So;0;ON;;;;;N;;;;; +1F51F;KEYCAP TEN;So;0;ON;;;;;N;;;;; +1F520;INPUT SYMBOL FOR LATIN CAPITAL LETTERS;So;0;ON;;;;;N;;;;; +1F521;INPUT SYMBOL FOR LATIN SMALL LETTERS;So;0;ON;;;;;N;;;;; +1F522;INPUT SYMBOL FOR NUMBERS;So;0;ON;;;;;N;;;;; +1F523;INPUT SYMBOL FOR SYMBOLS;So;0;ON;;;;;N;;;;; +1F524;INPUT SYMBOL FOR LATIN LETTERS;So;0;ON;;;;;N;;;;; +1F525;FIRE;So;0;ON;;;;;N;;;;; +1F526;ELECTRIC TORCH;So;0;ON;;;;;N;;;;; +1F527;WRENCH;So;0;ON;;;;;N;;;;; +1F528;HAMMER;So;0;ON;;;;;N;;;;; +1F529;NUT AND BOLT;So;0;ON;;;;;N;;;;; +1F52A;HOCHO;So;0;ON;;;;;N;;;;; +1F52B;PISTOL;So;0;ON;;;;;N;;;;; +1F52C;MICROSCOPE;So;0;ON;;;;;N;;;;; +1F52D;TELESCOPE;So;0;ON;;;;;N;;;;; +1F52E;CRYSTAL BALL;So;0;ON;;;;;N;;;;; +1F52F;SIX POINTED STAR WITH MIDDLE DOT;So;0;ON;;;;;N;;;;; +1F530;JAPANESE SYMBOL FOR BEGINNER;So;0;ON;;;;;N;;;;; +1F531;TRIDENT EMBLEM;So;0;ON;;;;;N;;;;; +1F532;BLACK SQUARE BUTTON;So;0;ON;;;;;N;;;;; +1F533;WHITE SQUARE BUTTON;So;0;ON;;;;;N;;;;; +1F534;LARGE RED CIRCLE;So;0;ON;;;;;N;;;;; +1F535;LARGE BLUE CIRCLE;So;0;ON;;;;;N;;;;; +1F536;LARGE ORANGE DIAMOND;So;0;ON;;;;;N;;;;; +1F537;LARGE BLUE DIAMOND;So;0;ON;;;;;N;;;;; +1F538;SMALL ORANGE DIAMOND;So;0;ON;;;;;N;;;;; +1F539;SMALL BLUE DIAMOND;So;0;ON;;;;;N;;;;; +1F53A;UP-POINTING RED TRIANGLE;So;0;ON;;;;;N;;;;; +1F53B;DOWN-POINTING RED TRIANGLE;So;0;ON;;;;;N;;;;; +1F53C;UP-POINTING SMALL RED TRIANGLE;So;0;ON;;;;;N;;;;; +1F53D;DOWN-POINTING SMALL RED TRIANGLE;So;0;ON;;;;;N;;;;; +1F53E;LOWER RIGHT SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;; +1F53F;UPPER RIGHT SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;; +1F540;CIRCLED CROSS POMMEE;So;0;ON;;;;;N;;;;; +1F541;CROSS POMMEE WITH HALF-CIRCLE BELOW;So;0;ON;;;;;N;;;;; +1F542;CROSS POMMEE;So;0;ON;;;;;N;;;;; +1F543;NOTCHED LEFT SEMICIRCLE WITH THREE DOTS;So;0;ON;;;;;N;;;;; +1F544;NOTCHED RIGHT SEMICIRCLE WITH THREE DOTS;So;0;ON;;;;;N;;;;; +1F545;SYMBOL FOR MARKS CHAPTER;So;0;ON;;;;;N;;;;; +1F546;WHITE LATIN CROSS;So;0;ON;;;;;N;;;;; +1F547;HEAVY LATIN CROSS;So;0;ON;;;;;N;;;;; +1F548;CELTIC CROSS;So;0;ON;;;;;N;;;;; +1F549;OM SYMBOL;So;0;ON;;;;;N;;;;; +1F54A;DOVE OF PEACE;So;0;ON;;;;;N;;;;; +1F54B;KAABA;So;0;ON;;;;;N;;;;; +1F54C;MOSQUE;So;0;ON;;;;;N;;;;; +1F54D;SYNAGOGUE;So;0;ON;;;;;N;;;;; +1F54E;MENORAH WITH NINE BRANCHES;So;0;ON;;;;;N;;;;; +1F54F;BOWL OF HYGIEIA;So;0;ON;;;;;N;;;;; +1F550;CLOCK FACE ONE OCLOCK;So;0;ON;;;;;N;;;;; +1F551;CLOCK FACE TWO OCLOCK;So;0;ON;;;;;N;;;;; +1F552;CLOCK FACE THREE OCLOCK;So;0;ON;;;;;N;;;;; +1F553;CLOCK FACE FOUR OCLOCK;So;0;ON;;;;;N;;;;; +1F554;CLOCK FACE FIVE OCLOCK;So;0;ON;;;;;N;;;;; +1F555;CLOCK FACE SIX OCLOCK;So;0;ON;;;;;N;;;;; +1F556;CLOCK FACE SEVEN OCLOCK;So;0;ON;;;;;N;;;;; +1F557;CLOCK FACE EIGHT OCLOCK;So;0;ON;;;;;N;;;;; +1F558;CLOCK FACE NINE OCLOCK;So;0;ON;;;;;N;;;;; +1F559;CLOCK FACE TEN OCLOCK;So;0;ON;;;;;N;;;;; +1F55A;CLOCK FACE ELEVEN OCLOCK;So;0;ON;;;;;N;;;;; +1F55B;CLOCK FACE TWELVE OCLOCK;So;0;ON;;;;;N;;;;; +1F55C;CLOCK FACE ONE-THIRTY;So;0;ON;;;;;N;;;;; +1F55D;CLOCK FACE TWO-THIRTY;So;0;ON;;;;;N;;;;; +1F55E;CLOCK FACE THREE-THIRTY;So;0;ON;;;;;N;;;;; +1F55F;CLOCK FACE FOUR-THIRTY;So;0;ON;;;;;N;;;;; +1F560;CLOCK FACE FIVE-THIRTY;So;0;ON;;;;;N;;;;; +1F561;CLOCK FACE SIX-THIRTY;So;0;ON;;;;;N;;;;; +1F562;CLOCK FACE SEVEN-THIRTY;So;0;ON;;;;;N;;;;; +1F563;CLOCK FACE EIGHT-THIRTY;So;0;ON;;;;;N;;;;; +1F564;CLOCK FACE NINE-THIRTY;So;0;ON;;;;;N;;;;; +1F565;CLOCK FACE TEN-THIRTY;So;0;ON;;;;;N;;;;; +1F566;CLOCK FACE ELEVEN-THIRTY;So;0;ON;;;;;N;;;;; +1F567;CLOCK FACE TWELVE-THIRTY;So;0;ON;;;;;N;;;;; +1F568;RIGHT SPEAKER;So;0;ON;;;;;N;;;;; +1F569;RIGHT SPEAKER WITH ONE SOUND WAVE;So;0;ON;;;;;N;;;;; +1F56A;RIGHT SPEAKER WITH THREE SOUND WAVES;So;0;ON;;;;;N;;;;; +1F56B;BULLHORN;So;0;ON;;;;;N;;;;; +1F56C;BULLHORN WITH SOUND WAVES;So;0;ON;;;;;N;;;;; +1F56D;RINGING BELL;So;0;ON;;;;;N;;;;; +1F56E;BOOK;So;0;ON;;;;;N;;;;; +1F56F;CANDLE;So;0;ON;;;;;N;;;;; +1F570;MANTELPIECE CLOCK;So;0;ON;;;;;N;;;;; +1F571;BLACK SKULL AND CROSSBONES;So;0;ON;;;;;N;;;;; +1F572;NO PIRACY;So;0;ON;;;;;N;;;;; +1F573;HOLE;So;0;ON;;;;;N;;;;; +1F574;MAN IN BUSINESS SUIT LEVITATING;So;0;ON;;;;;N;;;;; +1F575;SLEUTH OR SPY;So;0;ON;;;;;N;;;;; +1F576;DARK SUNGLASSES;So;0;ON;;;;;N;;;;; +1F577;SPIDER;So;0;ON;;;;;N;;;;; +1F578;SPIDER WEB;So;0;ON;;;;;N;;;;; +1F579;JOYSTICK;So;0;ON;;;;;N;;;;; +1F57A;MAN DANCING;So;0;ON;;;;;N;;;;; +1F57B;LEFT HAND TELEPHONE RECEIVER;So;0;ON;;;;;N;;;;; +1F57C;TELEPHONE RECEIVER WITH PAGE;So;0;ON;;;;;N;;;;; +1F57D;RIGHT HAND TELEPHONE RECEIVER;So;0;ON;;;;;N;;;;; +1F57E;WHITE TOUCHTONE TELEPHONE;So;0;ON;;;;;N;;;;; +1F57F;BLACK TOUCHTONE TELEPHONE;So;0;ON;;;;;N;;;;; +1F580;TELEPHONE ON TOP OF MODEM;So;0;ON;;;;;N;;;;; +1F581;CLAMSHELL MOBILE PHONE;So;0;ON;;;;;N;;;;; +1F582;BACK OF ENVELOPE;So;0;ON;;;;;N;;;;; +1F583;STAMPED ENVELOPE;So;0;ON;;;;;N;;;;; +1F584;ENVELOPE WITH LIGHTNING;So;0;ON;;;;;N;;;;; +1F585;FLYING ENVELOPE;So;0;ON;;;;;N;;;;; +1F586;PEN OVER STAMPED ENVELOPE;So;0;ON;;;;;N;;;;; +1F587;LINKED PAPERCLIPS;So;0;ON;;;;;N;;;;; +1F588;BLACK PUSHPIN;So;0;ON;;;;;N;;;;; +1F589;LOWER LEFT PENCIL;So;0;ON;;;;;N;;;;; +1F58A;LOWER LEFT BALLPOINT PEN;So;0;ON;;;;;N;;;;; +1F58B;LOWER LEFT FOUNTAIN PEN;So;0;ON;;;;;N;;;;; +1F58C;LOWER LEFT PAINTBRUSH;So;0;ON;;;;;N;;;;; +1F58D;LOWER LEFT CRAYON;So;0;ON;;;;;N;;;;; +1F58E;LEFT WRITING HAND;So;0;ON;;;;;N;;;;; +1F58F;TURNED OK HAND SIGN;So;0;ON;;;;;N;;;;; +1F590;RAISED HAND WITH FINGERS SPLAYED;So;0;ON;;;;;N;;;;; +1F591;REVERSED RAISED HAND WITH FINGERS SPLAYED;So;0;ON;;;;;N;;;;; +1F592;REVERSED THUMBS UP SIGN;So;0;ON;;;;;N;;;;; +1F593;REVERSED THUMBS DOWN SIGN;So;0;ON;;;;;N;;;;; +1F594;REVERSED VICTORY HAND;So;0;ON;;;;;N;;;;; +1F595;REVERSED HAND WITH MIDDLE FINGER EXTENDED;So;0;ON;;;;;N;;;;; +1F596;RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS;So;0;ON;;;;;N;;;;; +1F597;WHITE DOWN POINTING LEFT HAND INDEX;So;0;ON;;;;;N;;;;; +1F598;SIDEWAYS WHITE LEFT POINTING INDEX;So;0;ON;;;;;N;;;;; +1F599;SIDEWAYS WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;; +1F59A;SIDEWAYS BLACK LEFT POINTING INDEX;So;0;ON;;;;;N;;;;; +1F59B;SIDEWAYS BLACK RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;; +1F59C;BLACK LEFT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;; +1F59D;BLACK RIGHT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;; +1F59E;SIDEWAYS WHITE UP POINTING INDEX;So;0;ON;;;;;N;;;;; +1F59F;SIDEWAYS WHITE DOWN POINTING INDEX;So;0;ON;;;;;N;;;;; +1F5A0;SIDEWAYS BLACK UP POINTING INDEX;So;0;ON;;;;;N;;;;; +1F5A1;SIDEWAYS BLACK DOWN POINTING INDEX;So;0;ON;;;;;N;;;;; +1F5A2;BLACK UP POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;; +1F5A3;BLACK DOWN POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;; +1F5A4;BLACK HEART;So;0;ON;;;;;N;;;;; +1F5A5;DESKTOP COMPUTER;So;0;ON;;;;;N;;;;; +1F5A6;KEYBOARD AND MOUSE;So;0;ON;;;;;N;;;;; +1F5A7;THREE NETWORKED COMPUTERS;So;0;ON;;;;;N;;;;; +1F5A8;PRINTER;So;0;ON;;;;;N;;;;; +1F5A9;POCKET CALCULATOR;So;0;ON;;;;;N;;;;; +1F5AA;BLACK HARD SHELL FLOPPY DISK;So;0;ON;;;;;N;;;;; +1F5AB;WHITE HARD SHELL FLOPPY DISK;So;0;ON;;;;;N;;;;; +1F5AC;SOFT SHELL FLOPPY DISK;So;0;ON;;;;;N;;;;; +1F5AD;TAPE CARTRIDGE;So;0;ON;;;;;N;;;;; +1F5AE;WIRED KEYBOARD;So;0;ON;;;;;N;;;;; +1F5AF;ONE BUTTON MOUSE;So;0;ON;;;;;N;;;;; +1F5B0;TWO BUTTON MOUSE;So;0;ON;;;;;N;;;;; +1F5B1;THREE BUTTON MOUSE;So;0;ON;;;;;N;;;;; +1F5B2;TRACKBALL;So;0;ON;;;;;N;;;;; +1F5B3;OLD PERSONAL COMPUTER;So;0;ON;;;;;N;;;;; +1F5B4;HARD DISK;So;0;ON;;;;;N;;;;; +1F5B5;SCREEN;So;0;ON;;;;;N;;;;; +1F5B6;PRINTER ICON;So;0;ON;;;;;N;;;;; +1F5B7;FAX ICON;So;0;ON;;;;;N;;;;; +1F5B8;OPTICAL DISC ICON;So;0;ON;;;;;N;;;;; +1F5B9;DOCUMENT WITH TEXT;So;0;ON;;;;;N;;;;; +1F5BA;DOCUMENT WITH TEXT AND PICTURE;So;0;ON;;;;;N;;;;; +1F5BB;DOCUMENT WITH PICTURE;So;0;ON;;;;;N;;;;; +1F5BC;FRAME WITH PICTURE;So;0;ON;;;;;N;;;;; +1F5BD;FRAME WITH TILES;So;0;ON;;;;;N;;;;; +1F5BE;FRAME WITH AN X;So;0;ON;;;;;N;;;;; +1F5BF;BLACK FOLDER;So;0;ON;;;;;N;;;;; +1F5C0;FOLDER;So;0;ON;;;;;N;;;;; +1F5C1;OPEN FOLDER;So;0;ON;;;;;N;;;;; +1F5C2;CARD INDEX DIVIDERS;So;0;ON;;;;;N;;;;; +1F5C3;CARD FILE BOX;So;0;ON;;;;;N;;;;; +1F5C4;FILE CABINET;So;0;ON;;;;;N;;;;; +1F5C5;EMPTY NOTE;So;0;ON;;;;;N;;;;; +1F5C6;EMPTY NOTE PAGE;So;0;ON;;;;;N;;;;; +1F5C7;EMPTY NOTE PAD;So;0;ON;;;;;N;;;;; +1F5C8;NOTE;So;0;ON;;;;;N;;;;; +1F5C9;NOTE PAGE;So;0;ON;;;;;N;;;;; +1F5CA;NOTE PAD;So;0;ON;;;;;N;;;;; +1F5CB;EMPTY DOCUMENT;So;0;ON;;;;;N;;;;; +1F5CC;EMPTY PAGE;So;0;ON;;;;;N;;;;; +1F5CD;EMPTY PAGES;So;0;ON;;;;;N;;;;; +1F5CE;DOCUMENT;So;0;ON;;;;;N;;;;; +1F5CF;PAGE;So;0;ON;;;;;N;;;;; +1F5D0;PAGES;So;0;ON;;;;;N;;;;; +1F5D1;WASTEBASKET;So;0;ON;;;;;N;;;;; +1F5D2;SPIRAL NOTE PAD;So;0;ON;;;;;N;;;;; +1F5D3;SPIRAL CALENDAR PAD;So;0;ON;;;;;N;;;;; +1F5D4;DESKTOP WINDOW;So;0;ON;;;;;N;;;;; +1F5D5;MINIMIZE;So;0;ON;;;;;N;;;;; +1F5D6;MAXIMIZE;So;0;ON;;;;;N;;;;; +1F5D7;OVERLAP;So;0;ON;;;;;N;;;;; +1F5D8;CLOCKWISE RIGHT AND LEFT SEMICIRCLE ARROWS;So;0;ON;;;;;N;;;;; +1F5D9;CANCELLATION X;So;0;ON;;;;;N;;;;; +1F5DA;INCREASE FONT SIZE SYMBOL;So;0;ON;;;;;N;;;;; +1F5DB;DECREASE FONT SIZE SYMBOL;So;0;ON;;;;;N;;;;; +1F5DC;COMPRESSION;So;0;ON;;;;;N;;;;; +1F5DD;OLD KEY;So;0;ON;;;;;N;;;;; +1F5DE;ROLLED-UP NEWSPAPER;So;0;ON;;;;;N;;;;; +1F5DF;PAGE WITH CIRCLED TEXT;So;0;ON;;;;;N;;;;; +1F5E0;STOCK CHART;So;0;ON;;;;;N;;;;; +1F5E1;DAGGER KNIFE;So;0;ON;;;;;N;;;;; +1F5E2;LIPS;So;0;ON;;;;;N;;;;; +1F5E3;SPEAKING HEAD IN SILHOUETTE;So;0;ON;;;;;N;;;;; +1F5E4;THREE RAYS ABOVE;So;0;ON;;;;;N;;;;; +1F5E5;THREE RAYS BELOW;So;0;ON;;;;;N;;;;; +1F5E6;THREE RAYS LEFT;So;0;ON;;;;;N;;;;; +1F5E7;THREE RAYS RIGHT;So;0;ON;;;;;N;;;;; +1F5E8;LEFT SPEECH BUBBLE;So;0;ON;;;;;N;;;;; +1F5E9;RIGHT SPEECH BUBBLE;So;0;ON;;;;;N;;;;; +1F5EA;TWO SPEECH BUBBLES;So;0;ON;;;;;N;;;;; +1F5EB;THREE SPEECH BUBBLES;So;0;ON;;;;;N;;;;; +1F5EC;LEFT THOUGHT BUBBLE;So;0;ON;;;;;N;;;;; +1F5ED;RIGHT THOUGHT BUBBLE;So;0;ON;;;;;N;;;;; +1F5EE;LEFT ANGER BUBBLE;So;0;ON;;;;;N;;;;; +1F5EF;RIGHT ANGER BUBBLE;So;0;ON;;;;;N;;;;; +1F5F0;MOOD BUBBLE;So;0;ON;;;;;N;;;;; +1F5F1;LIGHTNING MOOD BUBBLE;So;0;ON;;;;;N;;;;; +1F5F2;LIGHTNING MOOD;So;0;ON;;;;;N;;;;; +1F5F3;BALLOT BOX WITH BALLOT;So;0;ON;;;;;N;;;;; +1F5F4;BALLOT SCRIPT X;So;0;ON;;;;;N;;;;; +1F5F5;BALLOT BOX WITH SCRIPT X;So;0;ON;;;;;N;;;;; +1F5F6;BALLOT BOLD SCRIPT X;So;0;ON;;;;;N;;;;; +1F5F7;BALLOT BOX WITH BOLD SCRIPT X;So;0;ON;;;;;N;;;;; +1F5F8;LIGHT CHECK MARK;So;0;ON;;;;;N;;;;; +1F5F9;BALLOT BOX WITH BOLD CHECK;So;0;ON;;;;;N;;;;; +1F5FA;WORLD MAP;So;0;ON;;;;;N;;;;; +1F5FB;MOUNT FUJI;So;0;ON;;;;;N;;;;; +1F5FC;TOKYO TOWER;So;0;ON;;;;;N;;;;; +1F5FD;STATUE OF LIBERTY;So;0;ON;;;;;N;;;;; +1F5FE;SILHOUETTE OF JAPAN;So;0;ON;;;;;N;;;;; +1F5FF;MOYAI;So;0;ON;;;;;N;;;;; +1F600;GRINNING FACE;So;0;ON;;;;;N;;;;; +1F601;GRINNING FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;; +1F602;FACE WITH TEARS OF JOY;So;0;ON;;;;;N;;;;; +1F603;SMILING FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;; +1F604;SMILING FACE WITH OPEN MOUTH AND SMILING EYES;So;0;ON;;;;;N;;;;; +1F605;SMILING FACE WITH OPEN MOUTH AND COLD SWEAT;So;0;ON;;;;;N;;;;; +1F606;SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES;So;0;ON;;;;;N;;;;; +1F607;SMILING FACE WITH HALO;So;0;ON;;;;;N;;;;; +1F608;SMILING FACE WITH HORNS;So;0;ON;;;;;N;;;;; +1F609;WINKING FACE;So;0;ON;;;;;N;;;;; +1F60A;SMILING FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;; +1F60B;FACE SAVOURING DELICIOUS FOOD;So;0;ON;;;;;N;;;;; +1F60C;RELIEVED FACE;So;0;ON;;;;;N;;;;; +1F60D;SMILING FACE WITH HEART-SHAPED EYES;So;0;ON;;;;;N;;;;; +1F60E;SMILING FACE WITH SUNGLASSES;So;0;ON;;;;;N;;;;; +1F60F;SMIRKING FACE;So;0;ON;;;;;N;;;;; +1F610;NEUTRAL FACE;So;0;ON;;;;;N;;;;; +1F611;EXPRESSIONLESS FACE;So;0;ON;;;;;N;;;;; +1F612;UNAMUSED FACE;So;0;ON;;;;;N;;;;; +1F613;FACE WITH COLD SWEAT;So;0;ON;;;;;N;;;;; +1F614;PENSIVE FACE;So;0;ON;;;;;N;;;;; +1F615;CONFUSED FACE;So;0;ON;;;;;N;;;;; +1F616;CONFOUNDED FACE;So;0;ON;;;;;N;;;;; +1F617;KISSING FACE;So;0;ON;;;;;N;;;;; +1F618;FACE THROWING A KISS;So;0;ON;;;;;N;;;;; +1F619;KISSING FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;; +1F61A;KISSING FACE WITH CLOSED EYES;So;0;ON;;;;;N;;;;; +1F61B;FACE WITH STUCK-OUT TONGUE;So;0;ON;;;;;N;;;;; +1F61C;FACE WITH STUCK-OUT TONGUE AND WINKING EYE;So;0;ON;;;;;N;;;;; +1F61D;FACE WITH STUCK-OUT TONGUE AND TIGHTLY-CLOSED EYES;So;0;ON;;;;;N;;;;; +1F61E;DISAPPOINTED FACE;So;0;ON;;;;;N;;;;; +1F61F;WORRIED FACE;So;0;ON;;;;;N;;;;; +1F620;ANGRY FACE;So;0;ON;;;;;N;;;;; +1F621;POUTING FACE;So;0;ON;;;;;N;;;;; +1F622;CRYING FACE;So;0;ON;;;;;N;;;;; +1F623;PERSEVERING FACE;So;0;ON;;;;;N;;;;; +1F624;FACE WITH LOOK OF TRIUMPH;So;0;ON;;;;;N;;;;; +1F625;DISAPPOINTED BUT RELIEVED FACE;So;0;ON;;;;;N;;;;; +1F626;FROWNING FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;; +1F627;ANGUISHED FACE;So;0;ON;;;;;N;;;;; +1F628;FEARFUL FACE;So;0;ON;;;;;N;;;;; +1F629;WEARY FACE;So;0;ON;;;;;N;;;;; +1F62A;SLEEPY FACE;So;0;ON;;;;;N;;;;; +1F62B;TIRED FACE;So;0;ON;;;;;N;;;;; +1F62C;GRIMACING FACE;So;0;ON;;;;;N;;;;; +1F62D;LOUDLY CRYING FACE;So;0;ON;;;;;N;;;;; +1F62E;FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;; +1F62F;HUSHED FACE;So;0;ON;;;;;N;;;;; +1F630;FACE WITH OPEN MOUTH AND COLD SWEAT;So;0;ON;;;;;N;;;;; +1F631;FACE SCREAMING IN FEAR;So;0;ON;;;;;N;;;;; +1F632;ASTONISHED FACE;So;0;ON;;;;;N;;;;; +1F633;FLUSHED FACE;So;0;ON;;;;;N;;;;; +1F634;SLEEPING FACE;So;0;ON;;;;;N;;;;; +1F635;DIZZY FACE;So;0;ON;;;;;N;;;;; +1F636;FACE WITHOUT MOUTH;So;0;ON;;;;;N;;;;; +1F637;FACE WITH MEDICAL MASK;So;0;ON;;;;;N;;;;; +1F638;GRINNING CAT FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;; +1F639;CAT FACE WITH TEARS OF JOY;So;0;ON;;;;;N;;;;; +1F63A;SMILING CAT FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;; +1F63B;SMILING CAT FACE WITH HEART-SHAPED EYES;So;0;ON;;;;;N;;;;; +1F63C;CAT FACE WITH WRY SMILE;So;0;ON;;;;;N;;;;; +1F63D;KISSING CAT FACE WITH CLOSED EYES;So;0;ON;;;;;N;;;;; +1F63E;POUTING CAT FACE;So;0;ON;;;;;N;;;;; +1F63F;CRYING CAT FACE;So;0;ON;;;;;N;;;;; +1F640;WEARY CAT FACE;So;0;ON;;;;;N;;;;; +1F641;SLIGHTLY FROWNING FACE;So;0;ON;;;;;N;;;;; +1F642;SLIGHTLY SMILING FACE;So;0;ON;;;;;N;;;;; +1F643;UPSIDE-DOWN FACE;So;0;ON;;;;;N;;;;; +1F644;FACE WITH ROLLING EYES;So;0;ON;;;;;N;;;;; +1F645;FACE WITH NO GOOD GESTURE;So;0;ON;;;;;N;;;;; +1F646;FACE WITH OK GESTURE;So;0;ON;;;;;N;;;;; +1F647;PERSON BOWING DEEPLY;So;0;ON;;;;;N;;;;; +1F648;SEE-NO-EVIL MONKEY;So;0;ON;;;;;N;;;;; +1F649;HEAR-NO-EVIL MONKEY;So;0;ON;;;;;N;;;;; +1F64A;SPEAK-NO-EVIL MONKEY;So;0;ON;;;;;N;;;;; +1F64B;HAPPY PERSON RAISING ONE HAND;So;0;ON;;;;;N;;;;; +1F64C;PERSON RAISING BOTH HANDS IN CELEBRATION;So;0;ON;;;;;N;;;;; +1F64D;PERSON FROWNING;So;0;ON;;;;;N;;;;; +1F64E;PERSON WITH POUTING FACE;So;0;ON;;;;;N;;;;; +1F64F;PERSON WITH FOLDED HANDS;So;0;ON;;;;;N;;;;; +1F650;NORTH WEST POINTING LEAF;So;0;ON;;;;;N;;;;; +1F651;SOUTH WEST POINTING LEAF;So;0;ON;;;;;N;;;;; +1F652;NORTH EAST POINTING LEAF;So;0;ON;;;;;N;;;;; +1F653;SOUTH EAST POINTING LEAF;So;0;ON;;;;;N;;;;; +1F654;TURNED NORTH WEST POINTING LEAF;So;0;ON;;;;;N;;;;; +1F655;TURNED SOUTH WEST POINTING LEAF;So;0;ON;;;;;N;;;;; +1F656;TURNED NORTH EAST POINTING LEAF;So;0;ON;;;;;N;;;;; +1F657;TURNED SOUTH EAST POINTING LEAF;So;0;ON;;;;;N;;;;; +1F658;NORTH WEST POINTING VINE LEAF;So;0;ON;;;;;N;;;;; +1F659;SOUTH WEST POINTING VINE LEAF;So;0;ON;;;;;N;;;;; +1F65A;NORTH EAST POINTING VINE LEAF;So;0;ON;;;;;N;;;;; +1F65B;SOUTH EAST POINTING VINE LEAF;So;0;ON;;;;;N;;;;; +1F65C;HEAVY NORTH WEST POINTING VINE LEAF;So;0;ON;;;;;N;;;;; +1F65D;HEAVY SOUTH WEST POINTING VINE LEAF;So;0;ON;;;;;N;;;;; +1F65E;HEAVY NORTH EAST POINTING VINE LEAF;So;0;ON;;;;;N;;;;; +1F65F;HEAVY SOUTH EAST POINTING VINE LEAF;So;0;ON;;;;;N;;;;; +1F660;NORTH WEST POINTING BUD;So;0;ON;;;;;N;;;;; +1F661;SOUTH WEST POINTING BUD;So;0;ON;;;;;N;;;;; +1F662;NORTH EAST POINTING BUD;So;0;ON;;;;;N;;;;; +1F663;SOUTH EAST POINTING BUD;So;0;ON;;;;;N;;;;; +1F664;HEAVY NORTH WEST POINTING BUD;So;0;ON;;;;;N;;;;; +1F665;HEAVY SOUTH WEST POINTING BUD;So;0;ON;;;;;N;;;;; +1F666;HEAVY NORTH EAST POINTING BUD;So;0;ON;;;;;N;;;;; +1F667;HEAVY SOUTH EAST POINTING BUD;So;0;ON;;;;;N;;;;; +1F668;HOLLOW QUILT SQUARE ORNAMENT;So;0;ON;;;;;N;;;;; +1F669;HOLLOW QUILT SQUARE ORNAMENT IN BLACK SQUARE;So;0;ON;;;;;N;;;;; +1F66A;SOLID QUILT SQUARE ORNAMENT;So;0;ON;;;;;N;;;;; +1F66B;SOLID QUILT SQUARE ORNAMENT IN BLACK SQUARE;So;0;ON;;;;;N;;;;; +1F66C;LEFTWARDS ROCKET;So;0;ON;;;;;N;;;;; +1F66D;UPWARDS ROCKET;So;0;ON;;;;;N;;;;; +1F66E;RIGHTWARDS ROCKET;So;0;ON;;;;;N;;;;; +1F66F;DOWNWARDS ROCKET;So;0;ON;;;;;N;;;;; +1F670;SCRIPT LIGATURE ET ORNAMENT;So;0;ON;;;;;N;;;;; +1F671;HEAVY SCRIPT LIGATURE ET ORNAMENT;So;0;ON;;;;;N;;;;; +1F672;LIGATURE OPEN ET ORNAMENT;So;0;ON;;;;;N;;;;; +1F673;HEAVY LIGATURE OPEN ET ORNAMENT;So;0;ON;;;;;N;;;;; +1F674;HEAVY AMPERSAND ORNAMENT;So;0;ON;;;;;N;;;;; +1F675;SWASH AMPERSAND ORNAMENT;So;0;ON;;;;;N;;;;; +1F676;SANS-SERIF HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +1F677;SANS-SERIF HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +1F678;SANS-SERIF HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; +1F679;HEAVY INTERROBANG ORNAMENT;So;0;ON;;;;;N;;;;; +1F67A;SANS-SERIF INTERROBANG ORNAMENT;So;0;ON;;;;;N;;;;; +1F67B;HEAVY SANS-SERIF INTERROBANG ORNAMENT;So;0;ON;;;;;N;;;;; +1F67C;VERY HEAVY SOLIDUS;So;0;ON;;;;;N;;;;; +1F67D;VERY HEAVY REVERSE SOLIDUS;So;0;ON;;;;;N;;;;; +1F67E;CHECKER BOARD;So;0;ON;;;;;N;;;;; +1F67F;REVERSE CHECKER BOARD;So;0;ON;;;;;N;;;;; +1F680;ROCKET;So;0;ON;;;;;N;;;;; +1F681;HELICOPTER;So;0;ON;;;;;N;;;;; +1F682;STEAM LOCOMOTIVE;So;0;ON;;;;;N;;;;; +1F683;RAILWAY CAR;So;0;ON;;;;;N;;;;; +1F684;HIGH-SPEED TRAIN;So;0;ON;;;;;N;;;;; +1F685;HIGH-SPEED TRAIN WITH BULLET NOSE;So;0;ON;;;;;N;;;;; +1F686;TRAIN;So;0;ON;;;;;N;;;;; +1F687;METRO;So;0;ON;;;;;N;;;;; +1F688;LIGHT RAIL;So;0;ON;;;;;N;;;;; +1F689;STATION;So;0;ON;;;;;N;;;;; +1F68A;TRAM;So;0;ON;;;;;N;;;;; +1F68B;TRAM CAR;So;0;ON;;;;;N;;;;; +1F68C;BUS;So;0;ON;;;;;N;;;;; +1F68D;ONCOMING BUS;So;0;ON;;;;;N;;;;; +1F68E;TROLLEYBUS;So;0;ON;;;;;N;;;;; +1F68F;BUS STOP;So;0;ON;;;;;N;;;;; +1F690;MINIBUS;So;0;ON;;;;;N;;;;; +1F691;AMBULANCE;So;0;ON;;;;;N;;;;; +1F692;FIRE ENGINE;So;0;ON;;;;;N;;;;; +1F693;POLICE CAR;So;0;ON;;;;;N;;;;; +1F694;ONCOMING POLICE CAR;So;0;ON;;;;;N;;;;; +1F695;TAXI;So;0;ON;;;;;N;;;;; +1F696;ONCOMING TAXI;So;0;ON;;;;;N;;;;; +1F697;AUTOMOBILE;So;0;ON;;;;;N;;;;; +1F698;ONCOMING AUTOMOBILE;So;0;ON;;;;;N;;;;; +1F699;RECREATIONAL VEHICLE;So;0;ON;;;;;N;;;;; +1F69A;DELIVERY TRUCK;So;0;ON;;;;;N;;;;; +1F69B;ARTICULATED LORRY;So;0;ON;;;;;N;;;;; +1F69C;TRACTOR;So;0;ON;;;;;N;;;;; +1F69D;MONORAIL;So;0;ON;;;;;N;;;;; +1F69E;MOUNTAIN RAILWAY;So;0;ON;;;;;N;;;;; +1F69F;SUSPENSION RAILWAY;So;0;ON;;;;;N;;;;; +1F6A0;MOUNTAIN CABLEWAY;So;0;ON;;;;;N;;;;; +1F6A1;AERIAL TRAMWAY;So;0;ON;;;;;N;;;;; +1F6A2;SHIP;So;0;ON;;;;;N;;;;; +1F6A3;ROWBOAT;So;0;ON;;;;;N;;;;; +1F6A4;SPEEDBOAT;So;0;ON;;;;;N;;;;; +1F6A5;HORIZONTAL TRAFFIC LIGHT;So;0;ON;;;;;N;;;;; +1F6A6;VERTICAL TRAFFIC LIGHT;So;0;ON;;;;;N;;;;; +1F6A7;CONSTRUCTION SIGN;So;0;ON;;;;;N;;;;; +1F6A8;POLICE CARS REVOLVING LIGHT;So;0;ON;;;;;N;;;;; +1F6A9;TRIANGULAR FLAG ON POST;So;0;ON;;;;;N;;;;; +1F6AA;DOOR;So;0;ON;;;;;N;;;;; +1F6AB;NO ENTRY SIGN;So;0;ON;;;;;N;;;;; +1F6AC;SMOKING SYMBOL;So;0;ON;;;;;N;;;;; +1F6AD;NO SMOKING SYMBOL;So;0;ON;;;;;N;;;;; +1F6AE;PUT LITTER IN ITS PLACE SYMBOL;So;0;ON;;;;;N;;;;; +1F6AF;DO NOT LITTER SYMBOL;So;0;ON;;;;;N;;;;; +1F6B0;POTABLE WATER SYMBOL;So;0;ON;;;;;N;;;;; +1F6B1;NON-POTABLE WATER SYMBOL;So;0;ON;;;;;N;;;;; +1F6B2;BICYCLE;So;0;ON;;;;;N;;;;; +1F6B3;NO BICYCLES;So;0;ON;;;;;N;;;;; +1F6B4;BICYCLIST;So;0;ON;;;;;N;;;;; +1F6B5;MOUNTAIN BICYCLIST;So;0;ON;;;;;N;;;;; +1F6B6;PEDESTRIAN;So;0;ON;;;;;N;;;;; +1F6B7;NO PEDESTRIANS;So;0;ON;;;;;N;;;;; +1F6B8;CHILDREN CROSSING;So;0;ON;;;;;N;;;;; +1F6B9;MENS SYMBOL;So;0;ON;;;;;N;;;;; +1F6BA;WOMENS SYMBOL;So;0;ON;;;;;N;;;;; +1F6BB;RESTROOM;So;0;ON;;;;;N;;;;; +1F6BC;BABY SYMBOL;So;0;ON;;;;;N;;;;; +1F6BD;TOILET;So;0;ON;;;;;N;;;;; +1F6BE;WATER CLOSET;So;0;ON;;;;;N;;;;; +1F6BF;SHOWER;So;0;ON;;;;;N;;;;; +1F6C0;BATH;So;0;ON;;;;;N;;;;; +1F6C1;BATHTUB;So;0;ON;;;;;N;;;;; +1F6C2;PASSPORT CONTROL;So;0;ON;;;;;N;;;;; +1F6C3;CUSTOMS;So;0;ON;;;;;N;;;;; +1F6C4;BAGGAGE CLAIM;So;0;ON;;;;;N;;;;; +1F6C5;LEFT LUGGAGE;So;0;ON;;;;;N;;;;; +1F6C6;TRIANGLE WITH ROUNDED CORNERS;So;0;ON;;;;;N;;;;; +1F6C7;PROHIBITED SIGN;So;0;ON;;;;;N;;;;; +1F6C8;CIRCLED INFORMATION SOURCE;So;0;ON;;;;;N;;;;; +1F6C9;BOYS SYMBOL;So;0;ON;;;;;N;;;;; +1F6CA;GIRLS SYMBOL;So;0;ON;;;;;N;;;;; +1F6CB;COUCH AND LAMP;So;0;ON;;;;;N;;;;; +1F6CC;SLEEPING ACCOMMODATION;So;0;ON;;;;;N;;;;; +1F6CD;SHOPPING BAGS;So;0;ON;;;;;N;;;;; +1F6CE;BELLHOP BELL;So;0;ON;;;;;N;;;;; +1F6CF;BED;So;0;ON;;;;;N;;;;; +1F6D0;PLACE OF WORSHIP;So;0;ON;;;;;N;;;;; +1F6D1;OCTAGONAL SIGN;So;0;ON;;;;;N;;;;; +1F6D2;SHOPPING TROLLEY;So;0;ON;;;;;N;;;;; +1F6D3;STUPA;So;0;ON;;;;;N;;;;; +1F6D4;PAGODA;So;0;ON;;;;;N;;;;; +1F6D5;HINDU TEMPLE;So;0;ON;;;;;N;;;;; +1F6E0;HAMMER AND WRENCH;So;0;ON;;;;;N;;;;; +1F6E1;SHIELD;So;0;ON;;;;;N;;;;; +1F6E2;OIL DRUM;So;0;ON;;;;;N;;;;; +1F6E3;MOTORWAY;So;0;ON;;;;;N;;;;; +1F6E4;RAILWAY TRACK;So;0;ON;;;;;N;;;;; +1F6E5;MOTOR BOAT;So;0;ON;;;;;N;;;;; +1F6E6;UP-POINTING MILITARY AIRPLANE;So;0;ON;;;;;N;;;;; +1F6E7;UP-POINTING AIRPLANE;So;0;ON;;;;;N;;;;; +1F6E8;UP-POINTING SMALL AIRPLANE;So;0;ON;;;;;N;;;;; +1F6E9;SMALL AIRPLANE;So;0;ON;;;;;N;;;;; +1F6EA;NORTHEAST-POINTING AIRPLANE;So;0;ON;;;;;N;;;;; +1F6EB;AIRPLANE DEPARTURE;So;0;ON;;;;;N;;;;; +1F6EC;AIRPLANE ARRIVING;So;0;ON;;;;;N;;;;; +1F6F0;SATELLITE;So;0;ON;;;;;N;;;;; +1F6F1;ONCOMING FIRE ENGINE;So;0;ON;;;;;N;;;;; +1F6F2;DIESEL LOCOMOTIVE;So;0;ON;;;;;N;;;;; +1F6F3;PASSENGER SHIP;So;0;ON;;;;;N;;;;; +1F6F4;SCOOTER;So;0;ON;;;;;N;;;;; +1F6F5;MOTOR SCOOTER;So;0;ON;;;;;N;;;;; +1F6F6;CANOE;So;0;ON;;;;;N;;;;; +1F6F7;SLED;So;0;ON;;;;;N;;;;; +1F6F8;FLYING SAUCER;So;0;ON;;;;;N;;;;; +1F6F9;SKATEBOARD;So;0;ON;;;;;N;;;;; +1F6FA;AUTO RICKSHAW;So;0;ON;;;;;N;;;;; +1F700;ALCHEMICAL SYMBOL FOR QUINTESSENCE;So;0;ON;;;;;N;;;;; +1F701;ALCHEMICAL SYMBOL FOR AIR;So;0;ON;;;;;N;;;;; +1F702;ALCHEMICAL SYMBOL FOR FIRE;So;0;ON;;;;;N;;;;; +1F703;ALCHEMICAL SYMBOL FOR EARTH;So;0;ON;;;;;N;;;;; +1F704;ALCHEMICAL SYMBOL FOR WATER;So;0;ON;;;;;N;;;;; +1F705;ALCHEMICAL SYMBOL FOR AQUAFORTIS;So;0;ON;;;;;N;;;;; +1F706;ALCHEMICAL SYMBOL FOR AQUA REGIA;So;0;ON;;;;;N;;;;; +1F707;ALCHEMICAL SYMBOL FOR AQUA REGIA-2;So;0;ON;;;;;N;;;;; +1F708;ALCHEMICAL SYMBOL FOR AQUA VITAE;So;0;ON;;;;;N;;;;; +1F709;ALCHEMICAL SYMBOL FOR AQUA VITAE-2;So;0;ON;;;;;N;;;;; +1F70A;ALCHEMICAL SYMBOL FOR VINEGAR;So;0;ON;;;;;N;;;;; +1F70B;ALCHEMICAL SYMBOL FOR VINEGAR-2;So;0;ON;;;;;N;;;;; +1F70C;ALCHEMICAL SYMBOL FOR VINEGAR-3;So;0;ON;;;;;N;;;;; +1F70D;ALCHEMICAL SYMBOL FOR SULFUR;So;0;ON;;;;;N;;;;; +1F70E;ALCHEMICAL SYMBOL FOR PHILOSOPHERS SULFUR;So;0;ON;;;;;N;;;;; +1F70F;ALCHEMICAL SYMBOL FOR BLACK SULFUR;So;0;ON;;;;;N;;;;; +1F710;ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE;So;0;ON;;;;;N;;;;; +1F711;ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE-2;So;0;ON;;;;;N;;;;; +1F712;ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE-3;So;0;ON;;;;;N;;;;; +1F713;ALCHEMICAL SYMBOL FOR CINNABAR;So;0;ON;;;;;N;;;;; +1F714;ALCHEMICAL SYMBOL FOR SALT;So;0;ON;;;;;N;;;;; +1F715;ALCHEMICAL SYMBOL FOR NITRE;So;0;ON;;;;;N;;;;; +1F716;ALCHEMICAL SYMBOL FOR VITRIOL;So;0;ON;;;;;N;;;;; +1F717;ALCHEMICAL SYMBOL FOR VITRIOL-2;So;0;ON;;;;;N;;;;; +1F718;ALCHEMICAL SYMBOL FOR ROCK SALT;So;0;ON;;;;;N;;;;; +1F719;ALCHEMICAL SYMBOL FOR ROCK SALT-2;So;0;ON;;;;;N;;;;; +1F71A;ALCHEMICAL SYMBOL FOR GOLD;So;0;ON;;;;;N;;;;; +1F71B;ALCHEMICAL SYMBOL FOR SILVER;So;0;ON;;;;;N;;;;; +1F71C;ALCHEMICAL SYMBOL FOR IRON ORE;So;0;ON;;;;;N;;;;; +1F71D;ALCHEMICAL SYMBOL FOR IRON ORE-2;So;0;ON;;;;;N;;;;; +1F71E;ALCHEMICAL SYMBOL FOR CROCUS OF IRON;So;0;ON;;;;;N;;;;; +1F71F;ALCHEMICAL SYMBOL FOR REGULUS OF IRON;So;0;ON;;;;;N;;;;; +1F720;ALCHEMICAL SYMBOL FOR COPPER ORE;So;0;ON;;;;;N;;;;; +1F721;ALCHEMICAL SYMBOL FOR IRON-COPPER ORE;So;0;ON;;;;;N;;;;; +1F722;ALCHEMICAL SYMBOL FOR SUBLIMATE OF COPPER;So;0;ON;;;;;N;;;;; +1F723;ALCHEMICAL SYMBOL FOR CROCUS OF COPPER;So;0;ON;;;;;N;;;;; +1F724;ALCHEMICAL SYMBOL FOR CROCUS OF COPPER-2;So;0;ON;;;;;N;;;;; +1F725;ALCHEMICAL SYMBOL FOR COPPER ANTIMONIATE;So;0;ON;;;;;N;;;;; +1F726;ALCHEMICAL SYMBOL FOR SALT OF COPPER ANTIMONIATE;So;0;ON;;;;;N;;;;; +1F727;ALCHEMICAL SYMBOL FOR SUBLIMATE OF SALT OF COPPER;So;0;ON;;;;;N;;;;; +1F728;ALCHEMICAL SYMBOL FOR VERDIGRIS;So;0;ON;;;;;N;;;;; +1F729;ALCHEMICAL SYMBOL FOR TIN ORE;So;0;ON;;;;;N;;;;; +1F72A;ALCHEMICAL SYMBOL FOR LEAD ORE;So;0;ON;;;;;N;;;;; +1F72B;ALCHEMICAL SYMBOL FOR ANTIMONY ORE;So;0;ON;;;;;N;;;;; +1F72C;ALCHEMICAL SYMBOL FOR SUBLIMATE OF ANTIMONY;So;0;ON;;;;;N;;;;; +1F72D;ALCHEMICAL SYMBOL FOR SALT OF ANTIMONY;So;0;ON;;;;;N;;;;; +1F72E;ALCHEMICAL SYMBOL FOR SUBLIMATE OF SALT OF ANTIMONY;So;0;ON;;;;;N;;;;; +1F72F;ALCHEMICAL SYMBOL FOR VINEGAR OF ANTIMONY;So;0;ON;;;;;N;;;;; +1F730;ALCHEMICAL SYMBOL FOR REGULUS OF ANTIMONY;So;0;ON;;;;;N;;;;; +1F731;ALCHEMICAL SYMBOL FOR REGULUS OF ANTIMONY-2;So;0;ON;;;;;N;;;;; +1F732;ALCHEMICAL SYMBOL FOR REGULUS;So;0;ON;;;;;N;;;;; +1F733;ALCHEMICAL SYMBOL FOR REGULUS-2;So;0;ON;;;;;N;;;;; +1F734;ALCHEMICAL SYMBOL FOR REGULUS-3;So;0;ON;;;;;N;;;;; +1F735;ALCHEMICAL SYMBOL FOR REGULUS-4;So;0;ON;;;;;N;;;;; +1F736;ALCHEMICAL SYMBOL FOR ALKALI;So;0;ON;;;;;N;;;;; +1F737;ALCHEMICAL SYMBOL FOR ALKALI-2;So;0;ON;;;;;N;;;;; +1F738;ALCHEMICAL SYMBOL FOR MARCASITE;So;0;ON;;;;;N;;;;; +1F739;ALCHEMICAL SYMBOL FOR SAL-AMMONIAC;So;0;ON;;;;;N;;;;; +1F73A;ALCHEMICAL SYMBOL FOR ARSENIC;So;0;ON;;;;;N;;;;; +1F73B;ALCHEMICAL SYMBOL FOR REALGAR;So;0;ON;;;;;N;;;;; +1F73C;ALCHEMICAL SYMBOL FOR REALGAR-2;So;0;ON;;;;;N;;;;; +1F73D;ALCHEMICAL SYMBOL FOR AURIPIGMENT;So;0;ON;;;;;N;;;;; +1F73E;ALCHEMICAL SYMBOL FOR BISMUTH ORE;So;0;ON;;;;;N;;;;; +1F73F;ALCHEMICAL SYMBOL FOR TARTAR;So;0;ON;;;;;N;;;;; +1F740;ALCHEMICAL SYMBOL FOR TARTAR-2;So;0;ON;;;;;N;;;;; +1F741;ALCHEMICAL SYMBOL FOR QUICK LIME;So;0;ON;;;;;N;;;;; +1F742;ALCHEMICAL SYMBOL FOR BORAX;So;0;ON;;;;;N;;;;; +1F743;ALCHEMICAL SYMBOL FOR BORAX-2;So;0;ON;;;;;N;;;;; +1F744;ALCHEMICAL SYMBOL FOR BORAX-3;So;0;ON;;;;;N;;;;; +1F745;ALCHEMICAL SYMBOL FOR ALUM;So;0;ON;;;;;N;;;;; +1F746;ALCHEMICAL SYMBOL FOR OIL;So;0;ON;;;;;N;;;;; +1F747;ALCHEMICAL SYMBOL FOR SPIRIT;So;0;ON;;;;;N;;;;; +1F748;ALCHEMICAL SYMBOL FOR TINCTURE;So;0;ON;;;;;N;;;;; +1F749;ALCHEMICAL SYMBOL FOR GUM;So;0;ON;;;;;N;;;;; +1F74A;ALCHEMICAL SYMBOL FOR WAX;So;0;ON;;;;;N;;;;; +1F74B;ALCHEMICAL SYMBOL FOR POWDER;So;0;ON;;;;;N;;;;; +1F74C;ALCHEMICAL SYMBOL FOR CALX;So;0;ON;;;;;N;;;;; +1F74D;ALCHEMICAL SYMBOL FOR TUTTY;So;0;ON;;;;;N;;;;; +1F74E;ALCHEMICAL SYMBOL FOR CAPUT MORTUUM;So;0;ON;;;;;N;;;;; +1F74F;ALCHEMICAL SYMBOL FOR SCEPTER OF JOVE;So;0;ON;;;;;N;;;;; +1F750;ALCHEMICAL SYMBOL FOR CADUCEUS;So;0;ON;;;;;N;;;;; +1F751;ALCHEMICAL SYMBOL FOR TRIDENT;So;0;ON;;;;;N;;;;; +1F752;ALCHEMICAL SYMBOL FOR STARRED TRIDENT;So;0;ON;;;;;N;;;;; +1F753;ALCHEMICAL SYMBOL FOR LODESTONE;So;0;ON;;;;;N;;;;; +1F754;ALCHEMICAL SYMBOL FOR SOAP;So;0;ON;;;;;N;;;;; +1F755;ALCHEMICAL SYMBOL FOR URINE;So;0;ON;;;;;N;;;;; +1F756;ALCHEMICAL SYMBOL FOR HORSE DUNG;So;0;ON;;;;;N;;;;; +1F757;ALCHEMICAL SYMBOL FOR ASHES;So;0;ON;;;;;N;;;;; +1F758;ALCHEMICAL SYMBOL FOR POT ASHES;So;0;ON;;;;;N;;;;; +1F759;ALCHEMICAL SYMBOL FOR BRICK;So;0;ON;;;;;N;;;;; +1F75A;ALCHEMICAL SYMBOL FOR POWDERED BRICK;So;0;ON;;;;;N;;;;; +1F75B;ALCHEMICAL SYMBOL FOR AMALGAM;So;0;ON;;;;;N;;;;; +1F75C;ALCHEMICAL SYMBOL FOR STRATUM SUPER STRATUM;So;0;ON;;;;;N;;;;; +1F75D;ALCHEMICAL SYMBOL FOR STRATUM SUPER STRATUM-2;So;0;ON;;;;;N;;;;; +1F75E;ALCHEMICAL SYMBOL FOR SUBLIMATION;So;0;ON;;;;;N;;;;; +1F75F;ALCHEMICAL SYMBOL FOR PRECIPITATE;So;0;ON;;;;;N;;;;; +1F760;ALCHEMICAL SYMBOL FOR DISTILL;So;0;ON;;;;;N;;;;; +1F761;ALCHEMICAL SYMBOL FOR DISSOLVE;So;0;ON;;;;;N;;;;; +1F762;ALCHEMICAL SYMBOL FOR DISSOLVE-2;So;0;ON;;;;;N;;;;; +1F763;ALCHEMICAL SYMBOL FOR PURIFY;So;0;ON;;;;;N;;;;; +1F764;ALCHEMICAL SYMBOL FOR PUTREFACTION;So;0;ON;;;;;N;;;;; +1F765;ALCHEMICAL SYMBOL FOR CRUCIBLE;So;0;ON;;;;;N;;;;; +1F766;ALCHEMICAL SYMBOL FOR CRUCIBLE-2;So;0;ON;;;;;N;;;;; +1F767;ALCHEMICAL SYMBOL FOR CRUCIBLE-3;So;0;ON;;;;;N;;;;; +1F768;ALCHEMICAL SYMBOL FOR CRUCIBLE-4;So;0;ON;;;;;N;;;;; +1F769;ALCHEMICAL SYMBOL FOR CRUCIBLE-5;So;0;ON;;;;;N;;;;; +1F76A;ALCHEMICAL SYMBOL FOR ALEMBIC;So;0;ON;;;;;N;;;;; +1F76B;ALCHEMICAL SYMBOL FOR BATH OF MARY;So;0;ON;;;;;N;;;;; +1F76C;ALCHEMICAL SYMBOL FOR BATH OF VAPOURS;So;0;ON;;;;;N;;;;; +1F76D;ALCHEMICAL SYMBOL FOR RETORT;So;0;ON;;;;;N;;;;; +1F76E;ALCHEMICAL SYMBOL FOR HOUR;So;0;ON;;;;;N;;;;; +1F76F;ALCHEMICAL SYMBOL FOR NIGHT;So;0;ON;;;;;N;;;;; +1F770;ALCHEMICAL SYMBOL FOR DAY-NIGHT;So;0;ON;;;;;N;;;;; +1F771;ALCHEMICAL SYMBOL FOR MONTH;So;0;ON;;;;;N;;;;; +1F772;ALCHEMICAL SYMBOL FOR HALF DRAM;So;0;ON;;;;;N;;;;; +1F773;ALCHEMICAL SYMBOL FOR HALF OUNCE;So;0;ON;;;;;N;;;;; +1F780;BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;; +1F781;BLACK UP-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;; +1F782;BLACK RIGHT-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;; +1F783;BLACK DOWN-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;; +1F784;BLACK SLIGHTLY SMALL CIRCLE;So;0;ON;;;;;N;;;;; +1F785;MEDIUM BOLD WHITE CIRCLE;So;0;ON;;;;;N;;;;; +1F786;BOLD WHITE CIRCLE;So;0;ON;;;;;N;;;;; +1F787;HEAVY WHITE CIRCLE;So;0;ON;;;;;N;;;;; +1F788;VERY HEAVY WHITE CIRCLE;So;0;ON;;;;;N;;;;; +1F789;EXTREMELY HEAVY WHITE CIRCLE;So;0;ON;;;;;N;;;;; +1F78A;WHITE CIRCLE CONTAINING BLACK SMALL CIRCLE;So;0;ON;;;;;N;;;;; +1F78B;ROUND TARGET;So;0;ON;;;;;N;;;;; +1F78C;BLACK TINY SQUARE;So;0;ON;;;;;N;;;;; +1F78D;BLACK SLIGHTLY SMALL SQUARE;So;0;ON;;;;;N;;;;; +1F78E;LIGHT WHITE SQUARE;So;0;ON;;;;;N;;;;; +1F78F;MEDIUM WHITE SQUARE;So;0;ON;;;;;N;;;;; +1F790;BOLD WHITE SQUARE;So;0;ON;;;;;N;;;;; +1F791;HEAVY WHITE SQUARE;So;0;ON;;;;;N;;;;; +1F792;VERY HEAVY WHITE SQUARE;So;0;ON;;;;;N;;;;; +1F793;EXTREMELY HEAVY WHITE SQUARE;So;0;ON;;;;;N;;;;; +1F794;WHITE SQUARE CONTAINING BLACK VERY SMALL SQUARE;So;0;ON;;;;;N;;;;; +1F795;WHITE SQUARE CONTAINING BLACK MEDIUM SQUARE;So;0;ON;;;;;N;;;;; +1F796;SQUARE TARGET;So;0;ON;;;;;N;;;;; +1F797;BLACK TINY DIAMOND;So;0;ON;;;;;N;;;;; +1F798;BLACK VERY SMALL DIAMOND;So;0;ON;;;;;N;;;;; +1F799;BLACK MEDIUM SMALL DIAMOND;So;0;ON;;;;;N;;;;; +1F79A;WHITE DIAMOND CONTAINING BLACK VERY SMALL DIAMOND;So;0;ON;;;;;N;;;;; +1F79B;WHITE DIAMOND CONTAINING BLACK MEDIUM DIAMOND;So;0;ON;;;;;N;;;;; +1F79C;DIAMOND TARGET;So;0;ON;;;;;N;;;;; +1F79D;BLACK TINY LOZENGE;So;0;ON;;;;;N;;;;; +1F79E;BLACK VERY SMALL LOZENGE;So;0;ON;;;;;N;;;;; +1F79F;BLACK MEDIUM SMALL LOZENGE;So;0;ON;;;;;N;;;;; +1F7A0;WHITE LOZENGE CONTAINING BLACK SMALL LOZENGE;So;0;ON;;;;;N;;;;; +1F7A1;THIN GREEK CROSS;So;0;ON;;;;;N;;;;; +1F7A2;LIGHT GREEK CROSS;So;0;ON;;;;;N;;;;; +1F7A3;MEDIUM GREEK CROSS;So;0;ON;;;;;N;;;;; +1F7A4;BOLD GREEK CROSS;So;0;ON;;;;;N;;;;; +1F7A5;VERY BOLD GREEK CROSS;So;0;ON;;;;;N;;;;; +1F7A6;VERY HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;; +1F7A7;EXTREMELY HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;; +1F7A8;THIN SALTIRE;So;0;ON;;;;;N;;;;; +1F7A9;LIGHT SALTIRE;So;0;ON;;;;;N;;;;; +1F7AA;MEDIUM SALTIRE;So;0;ON;;;;;N;;;;; +1F7AB;BOLD SALTIRE;So;0;ON;;;;;N;;;;; +1F7AC;HEAVY SALTIRE;So;0;ON;;;;;N;;;;; +1F7AD;VERY HEAVY SALTIRE;So;0;ON;;;;;N;;;;; +1F7AE;EXTREMELY HEAVY SALTIRE;So;0;ON;;;;;N;;;;; +1F7AF;LIGHT FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +1F7B0;MEDIUM FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +1F7B1;BOLD FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +1F7B2;HEAVY FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +1F7B3;VERY HEAVY FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +1F7B4;EXTREMELY HEAVY FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +1F7B5;LIGHT SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +1F7B6;MEDIUM SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +1F7B7;BOLD SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +1F7B8;HEAVY SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +1F7B9;VERY HEAVY SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +1F7BA;EXTREMELY HEAVY SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +1F7BB;LIGHT EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +1F7BC;MEDIUM EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +1F7BD;BOLD EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +1F7BE;HEAVY EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +1F7BF;VERY HEAVY EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;; +1F7C0;LIGHT THREE POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +1F7C1;MEDIUM THREE POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +1F7C2;THREE POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +1F7C3;MEDIUM THREE POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;; +1F7C4;LIGHT FOUR POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +1F7C5;MEDIUM FOUR POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +1F7C6;FOUR POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +1F7C7;MEDIUM FOUR POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;; +1F7C8;REVERSE LIGHT FOUR POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;; +1F7C9;LIGHT FIVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +1F7CA;HEAVY FIVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +1F7CB;MEDIUM SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +1F7CC;HEAVY SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +1F7CD;SIX POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;; +1F7CE;MEDIUM EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +1F7CF;HEAVY EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +1F7D0;VERY HEAVY EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +1F7D1;HEAVY EIGHT POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;; +1F7D2;LIGHT TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +1F7D3;HEAVY TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;; +1F7D4;HEAVY TWELVE POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;; +1F7D5;CIRCLED TRIANGLE;So;0;ON;;;;;N;;;;; +1F7D6;NEGATIVE CIRCLED TRIANGLE;So;0;ON;;;;;N;;;;; +1F7D7;CIRCLED SQUARE;So;0;ON;;;;;N;;;;; +1F7D8;NEGATIVE CIRCLED SQUARE;So;0;ON;;;;;N;;;;; +1F7E0;LARGE ORANGE CIRCLE;So;0;ON;;;;;N;;;;; +1F7E1;LARGE YELLOW CIRCLE;So;0;ON;;;;;N;;;;; +1F7E2;LARGE GREEN CIRCLE;So;0;ON;;;;;N;;;;; +1F7E3;LARGE PURPLE CIRCLE;So;0;ON;;;;;N;;;;; +1F7E4;LARGE BROWN CIRCLE;So;0;ON;;;;;N;;;;; +1F7E5;LARGE RED SQUARE;So;0;ON;;;;;N;;;;; +1F7E6;LARGE BLUE SQUARE;So;0;ON;;;;;N;;;;; +1F7E7;LARGE ORANGE SQUARE;So;0;ON;;;;;N;;;;; +1F7E8;LARGE YELLOW SQUARE;So;0;ON;;;;;N;;;;; +1F7E9;LARGE GREEN SQUARE;So;0;ON;;;;;N;;;;; +1F7EA;LARGE PURPLE SQUARE;So;0;ON;;;;;N;;;;; +1F7EB;LARGE BROWN SQUARE;So;0;ON;;;;;N;;;;; +1F800;LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F801;UPWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F802;RIGHTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F803;DOWNWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F804;LEFTWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F805;UPWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F806;RIGHTWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F807;DOWNWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F808;LEFTWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F809;UPWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F80A;RIGHTWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F80B;DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F810;LEFTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +1F811;UPWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +1F812;RIGHTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +1F813;DOWNWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +1F814;LEFTWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +1F815;UPWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +1F816;RIGHTWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +1F817;DOWNWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +1F818;HEAVY LEFTWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +1F819;HEAVY UPWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +1F81A;HEAVY RIGHTWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +1F81B;HEAVY DOWNWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +1F81C;HEAVY LEFTWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +1F81D;HEAVY UPWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +1F81E;HEAVY RIGHTWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +1F81F;HEAVY DOWNWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; +1F820;LEFTWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT;So;0;ON;;;;;N;;;;; +1F821;UPWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT;So;0;ON;;;;;N;;;;; +1F822;RIGHTWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT;So;0;ON;;;;;N;;;;; +1F823;DOWNWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT;So;0;ON;;;;;N;;;;; +1F824;LEFTWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT;So;0;ON;;;;;N;;;;; +1F825;UPWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT;So;0;ON;;;;;N;;;;; +1F826;RIGHTWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT;So;0;ON;;;;;N;;;;; +1F827;DOWNWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT;So;0;ON;;;;;N;;;;; +1F828;LEFTWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT;So;0;ON;;;;;N;;;;; +1F829;UPWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT;So;0;ON;;;;;N;;;;; +1F82A;RIGHTWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT;So;0;ON;;;;;N;;;;; +1F82B;DOWNWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT;So;0;ON;;;;;N;;;;; +1F82C;LEFTWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT;So;0;ON;;;;;N;;;;; +1F82D;UPWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT;So;0;ON;;;;;N;;;;; +1F82E;RIGHTWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT;So;0;ON;;;;;N;;;;; +1F82F;DOWNWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT;So;0;ON;;;;;N;;;;; +1F830;LEFTWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT;So;0;ON;;;;;N;;;;; +1F831;UPWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT;So;0;ON;;;;;N;;;;; +1F832;RIGHTWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT;So;0;ON;;;;;N;;;;; +1F833;DOWNWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT;So;0;ON;;;;;N;;;;; +1F834;LEFTWARDS FINGER-POST ARROW;So;0;ON;;;;;N;;;;; +1F835;UPWARDS FINGER-POST ARROW;So;0;ON;;;;;N;;;;; +1F836;RIGHTWARDS FINGER-POST ARROW;So;0;ON;;;;;N;;;;; +1F837;DOWNWARDS FINGER-POST ARROW;So;0;ON;;;;;N;;;;; +1F838;LEFTWARDS SQUARED ARROW;So;0;ON;;;;;N;;;;; +1F839;UPWARDS SQUARED ARROW;So;0;ON;;;;;N;;;;; +1F83A;RIGHTWARDS SQUARED ARROW;So;0;ON;;;;;N;;;;; +1F83B;DOWNWARDS SQUARED ARROW;So;0;ON;;;;;N;;;;; +1F83C;LEFTWARDS COMPRESSED ARROW;So;0;ON;;;;;N;;;;; +1F83D;UPWARDS COMPRESSED ARROW;So;0;ON;;;;;N;;;;; +1F83E;RIGHTWARDS COMPRESSED ARROW;So;0;ON;;;;;N;;;;; +1F83F;DOWNWARDS COMPRESSED ARROW;So;0;ON;;;;;N;;;;; +1F840;LEFTWARDS HEAVY COMPRESSED ARROW;So;0;ON;;;;;N;;;;; +1F841;UPWARDS HEAVY COMPRESSED ARROW;So;0;ON;;;;;N;;;;; +1F842;RIGHTWARDS HEAVY COMPRESSED ARROW;So;0;ON;;;;;N;;;;; +1F843;DOWNWARDS HEAVY COMPRESSED ARROW;So;0;ON;;;;;N;;;;; +1F844;LEFTWARDS HEAVY ARROW;So;0;ON;;;;;N;;;;; +1F845;UPWARDS HEAVY ARROW;So;0;ON;;;;;N;;;;; +1F846;RIGHTWARDS HEAVY ARROW;So;0;ON;;;;;N;;;;; +1F847;DOWNWARDS HEAVY ARROW;So;0;ON;;;;;N;;;;; +1F850;LEFTWARDS SANS-SERIF ARROW;So;0;ON;;;;;N;;;;; +1F851;UPWARDS SANS-SERIF ARROW;So;0;ON;;;;;N;;;;; +1F852;RIGHTWARDS SANS-SERIF ARROW;So;0;ON;;;;;N;;;;; +1F853;DOWNWARDS SANS-SERIF ARROW;So;0;ON;;;;;N;;;;; +1F854;NORTH WEST SANS-SERIF ARROW;So;0;ON;;;;;N;;;;; +1F855;NORTH EAST SANS-SERIF ARROW;So;0;ON;;;;;N;;;;; +1F856;SOUTH EAST SANS-SERIF ARROW;So;0;ON;;;;;N;;;;; +1F857;SOUTH WEST SANS-SERIF ARROW;So;0;ON;;;;;N;;;;; +1F858;LEFT RIGHT SANS-SERIF ARROW;So;0;ON;;;;;N;;;;; +1F859;UP DOWN SANS-SERIF ARROW;So;0;ON;;;;;N;;;;; +1F860;WIDE-HEADED LEFTWARDS LIGHT BARB ARROW;So;0;ON;;;;;N;;;;; +1F861;WIDE-HEADED UPWARDS LIGHT BARB ARROW;So;0;ON;;;;;N;;;;; +1F862;WIDE-HEADED RIGHTWARDS LIGHT BARB ARROW;So;0;ON;;;;;N;;;;; +1F863;WIDE-HEADED DOWNWARDS LIGHT BARB ARROW;So;0;ON;;;;;N;;;;; +1F864;WIDE-HEADED NORTH WEST LIGHT BARB ARROW;So;0;ON;;;;;N;;;;; +1F865;WIDE-HEADED NORTH EAST LIGHT BARB ARROW;So;0;ON;;;;;N;;;;; +1F866;WIDE-HEADED SOUTH EAST LIGHT BARB ARROW;So;0;ON;;;;;N;;;;; +1F867;WIDE-HEADED SOUTH WEST LIGHT BARB ARROW;So;0;ON;;;;;N;;;;; +1F868;WIDE-HEADED LEFTWARDS BARB ARROW;So;0;ON;;;;;N;;;;; +1F869;WIDE-HEADED UPWARDS BARB ARROW;So;0;ON;;;;;N;;;;; +1F86A;WIDE-HEADED RIGHTWARDS BARB ARROW;So;0;ON;;;;;N;;;;; +1F86B;WIDE-HEADED DOWNWARDS BARB ARROW;So;0;ON;;;;;N;;;;; +1F86C;WIDE-HEADED NORTH WEST BARB ARROW;So;0;ON;;;;;N;;;;; +1F86D;WIDE-HEADED NORTH EAST BARB ARROW;So;0;ON;;;;;N;;;;; +1F86E;WIDE-HEADED SOUTH EAST BARB ARROW;So;0;ON;;;;;N;;;;; +1F86F;WIDE-HEADED SOUTH WEST BARB ARROW;So;0;ON;;;;;N;;;;; +1F870;WIDE-HEADED LEFTWARDS MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;; +1F871;WIDE-HEADED UPWARDS MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;; +1F872;WIDE-HEADED RIGHTWARDS MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;; +1F873;WIDE-HEADED DOWNWARDS MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;; +1F874;WIDE-HEADED NORTH WEST MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;; +1F875;WIDE-HEADED NORTH EAST MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;; +1F876;WIDE-HEADED SOUTH EAST MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;; +1F877;WIDE-HEADED SOUTH WEST MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;; +1F878;WIDE-HEADED LEFTWARDS HEAVY BARB ARROW;So;0;ON;;;;;N;;;;; +1F879;WIDE-HEADED UPWARDS HEAVY BARB ARROW;So;0;ON;;;;;N;;;;; +1F87A;WIDE-HEADED RIGHTWARDS HEAVY BARB ARROW;So;0;ON;;;;;N;;;;; +1F87B;WIDE-HEADED DOWNWARDS HEAVY BARB ARROW;So;0;ON;;;;;N;;;;; +1F87C;WIDE-HEADED NORTH WEST HEAVY BARB ARROW;So;0;ON;;;;;N;;;;; +1F87D;WIDE-HEADED NORTH EAST HEAVY BARB ARROW;So;0;ON;;;;;N;;;;; +1F87E;WIDE-HEADED SOUTH EAST HEAVY BARB ARROW;So;0;ON;;;;;N;;;;; +1F87F;WIDE-HEADED SOUTH WEST HEAVY BARB ARROW;So;0;ON;;;;;N;;;;; +1F880;WIDE-HEADED LEFTWARDS VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;; +1F881;WIDE-HEADED UPWARDS VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;; +1F882;WIDE-HEADED RIGHTWARDS VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;; +1F883;WIDE-HEADED DOWNWARDS VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;; +1F884;WIDE-HEADED NORTH WEST VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;; +1F885;WIDE-HEADED NORTH EAST VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;; +1F886;WIDE-HEADED SOUTH EAST VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;; +1F887;WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;; +1F890;LEFTWARDS TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F891;UPWARDS TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F892;RIGHTWARDS TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F893;DOWNWARDS TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F894;LEFTWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F895;UPWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F896;RIGHTWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F897;DOWNWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; +1F898;LEFTWARDS ARROW WITH NOTCHED TAIL;So;0;ON;;;;;N;;;;; +1F899;UPWARDS ARROW WITH NOTCHED TAIL;So;0;ON;;;;;N;;;;; +1F89A;RIGHTWARDS ARROW WITH NOTCHED TAIL;So;0;ON;;;;;N;;;;; +1F89B;DOWNWARDS ARROW WITH NOTCHED TAIL;So;0;ON;;;;;N;;;;; +1F89C;HEAVY ARROW SHAFT WIDTH ONE;So;0;ON;;;;;N;;;;; +1F89D;HEAVY ARROW SHAFT WIDTH TWO THIRDS;So;0;ON;;;;;N;;;;; +1F89E;HEAVY ARROW SHAFT WIDTH ONE HALF;So;0;ON;;;;;N;;;;; +1F89F;HEAVY ARROW SHAFT WIDTH ONE THIRD;So;0;ON;;;;;N;;;;; +1F8A0;LEFTWARDS BOTTOM-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;; +1F8A1;RIGHTWARDS BOTTOM SHADED WHITE ARROW;So;0;ON;;;;;N;;;;; +1F8A2;LEFTWARDS TOP SHADED WHITE ARROW;So;0;ON;;;;;N;;;;; +1F8A3;RIGHTWARDS TOP SHADED WHITE ARROW;So;0;ON;;;;;N;;;;; +1F8A4;LEFTWARDS LEFT-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;; +1F8A5;RIGHTWARDS RIGHT-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;; +1F8A6;LEFTWARDS RIGHT-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;; +1F8A7;RIGHTWARDS LEFT-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;; +1F8A8;LEFTWARDS BACK-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;; +1F8A9;RIGHTWARDS BACK-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;; +1F8AA;LEFTWARDS FRONT-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;; +1F8AB;RIGHTWARDS FRONT-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;; +1F8AC;WHITE ARROW SHAFT WIDTH ONE;So;0;ON;;;;;N;;;;; +1F8AD;WHITE ARROW SHAFT WIDTH TWO THIRDS;So;0;ON;;;;;N;;;;; +1F900;CIRCLED CROSS FORMEE WITH FOUR DOTS;So;0;ON;;;;;N;;;;; +1F901;CIRCLED CROSS FORMEE WITH TWO DOTS;So;0;ON;;;;;N;;;;; +1F902;CIRCLED CROSS FORMEE;So;0;ON;;;;;N;;;;; +1F903;LEFT HALF CIRCLE WITH FOUR DOTS;So;0;ON;;;;;N;;;;; +1F904;LEFT HALF CIRCLE WITH THREE DOTS;So;0;ON;;;;;N;;;;; +1F905;LEFT HALF CIRCLE WITH TWO DOTS;So;0;ON;;;;;N;;;;; +1F906;LEFT HALF CIRCLE WITH DOT;So;0;ON;;;;;N;;;;; +1F907;LEFT HALF CIRCLE;So;0;ON;;;;;N;;;;; +1F908;DOWNWARD FACING HOOK;So;0;ON;;;;;N;;;;; +1F909;DOWNWARD FACING NOTCHED HOOK;So;0;ON;;;;;N;;;;; +1F90A;DOWNWARD FACING HOOK WITH DOT;So;0;ON;;;;;N;;;;; +1F90B;DOWNWARD FACING NOTCHED HOOK WITH DOT;So;0;ON;;;;;N;;;;; +1F90D;WHITE HEART;So;0;ON;;;;;N;;;;; +1F90E;BROWN HEART;So;0;ON;;;;;N;;;;; +1F90F;PINCHING HAND;So;0;ON;;;;;N;;;;; +1F910;ZIPPER-MOUTH FACE;So;0;ON;;;;;N;;;;; +1F911;MONEY-MOUTH FACE;So;0;ON;;;;;N;;;;; +1F912;FACE WITH THERMOMETER;So;0;ON;;;;;N;;;;; +1F913;NERD FACE;So;0;ON;;;;;N;;;;; +1F914;THINKING FACE;So;0;ON;;;;;N;;;;; +1F915;FACE WITH HEAD-BANDAGE;So;0;ON;;;;;N;;;;; +1F916;ROBOT FACE;So;0;ON;;;;;N;;;;; +1F917;HUGGING FACE;So;0;ON;;;;;N;;;;; +1F918;SIGN OF THE HORNS;So;0;ON;;;;;N;;;;; +1F919;CALL ME HAND;So;0;ON;;;;;N;;;;; +1F91A;RAISED BACK OF HAND;So;0;ON;;;;;N;;;;; +1F91B;LEFT-FACING FIST;So;0;ON;;;;;N;;;;; +1F91C;RIGHT-FACING FIST;So;0;ON;;;;;N;;;;; +1F91D;HANDSHAKE;So;0;ON;;;;;N;;;;; +1F91E;HAND WITH INDEX AND MIDDLE FINGERS CROSSED;So;0;ON;;;;;N;;;;; +1F91F;I LOVE YOU HAND SIGN;So;0;ON;;;;;N;;;;; +1F920;FACE WITH COWBOY HAT;So;0;ON;;;;;N;;;;; +1F921;CLOWN FACE;So;0;ON;;;;;N;;;;; +1F922;NAUSEATED FACE;So;0;ON;;;;;N;;;;; +1F923;ROLLING ON THE FLOOR LAUGHING;So;0;ON;;;;;N;;;;; +1F924;DROOLING FACE;So;0;ON;;;;;N;;;;; +1F925;LYING FACE;So;0;ON;;;;;N;;;;; +1F926;FACE PALM;So;0;ON;;;;;N;;;;; +1F927;SNEEZING FACE;So;0;ON;;;;;N;;;;; +1F928;FACE WITH ONE EYEBROW RAISED;So;0;ON;;;;;N;;;;; +1F929;GRINNING FACE WITH STAR EYES;So;0;ON;;;;;N;;;;; +1F92A;GRINNING FACE WITH ONE LARGE AND ONE SMALL EYE;So;0;ON;;;;;N;;;;; +1F92B;FACE WITH FINGER COVERING CLOSED LIPS;So;0;ON;;;;;N;;;;; +1F92C;SERIOUS FACE WITH SYMBOLS COVERING MOUTH;So;0;ON;;;;;N;;;;; +1F92D;SMILING FACE WITH SMILING EYES AND HAND COVERING MOUTH;So;0;ON;;;;;N;;;;; +1F92E;FACE WITH OPEN MOUTH VOMITING;So;0;ON;;;;;N;;;;; +1F92F;SHOCKED FACE WITH EXPLODING HEAD;So;0;ON;;;;;N;;;;; +1F930;PREGNANT WOMAN;So;0;ON;;;;;N;;;;; +1F931;BREAST-FEEDING;So;0;ON;;;;;N;;;;; +1F932;PALMS UP TOGETHER;So;0;ON;;;;;N;;;;; +1F933;SELFIE;So;0;ON;;;;;N;;;;; +1F934;PRINCE;So;0;ON;;;;;N;;;;; +1F935;MAN IN TUXEDO;So;0;ON;;;;;N;;;;; +1F936;MOTHER CHRISTMAS;So;0;ON;;;;;N;;;;; +1F937;SHRUG;So;0;ON;;;;;N;;;;; +1F938;PERSON DOING CARTWHEEL;So;0;ON;;;;;N;;;;; +1F939;JUGGLING;So;0;ON;;;;;N;;;;; +1F93A;FENCER;So;0;ON;;;;;N;;;;; +1F93B;MODERN PENTATHLON;So;0;ON;;;;;N;;;;; +1F93C;WRESTLERS;So;0;ON;;;;;N;;;;; +1F93D;WATER POLO;So;0;ON;;;;;N;;;;; +1F93E;HANDBALL;So;0;ON;;;;;N;;;;; +1F93F;DIVING MASK;So;0;ON;;;;;N;;;;; +1F940;WILTED FLOWER;So;0;ON;;;;;N;;;;; +1F941;DRUM WITH DRUMSTICKS;So;0;ON;;;;;N;;;;; +1F942;CLINKING GLASSES;So;0;ON;;;;;N;;;;; +1F943;TUMBLER GLASS;So;0;ON;;;;;N;;;;; +1F944;SPOON;So;0;ON;;;;;N;;;;; +1F945;GOAL NET;So;0;ON;;;;;N;;;;; +1F946;RIFLE;So;0;ON;;;;;N;;;;; +1F947;FIRST PLACE MEDAL;So;0;ON;;;;;N;;;;; +1F948;SECOND PLACE MEDAL;So;0;ON;;;;;N;;;;; +1F949;THIRD PLACE MEDAL;So;0;ON;;;;;N;;;;; +1F94A;BOXING GLOVE;So;0;ON;;;;;N;;;;; +1F94B;MARTIAL ARTS UNIFORM;So;0;ON;;;;;N;;;;; +1F94C;CURLING STONE;So;0;ON;;;;;N;;;;; +1F94D;LACROSSE STICK AND BALL;So;0;ON;;;;;N;;;;; +1F94E;SOFTBALL;So;0;ON;;;;;N;;;;; +1F94F;FLYING DISC;So;0;ON;;;;;N;;;;; +1F950;CROISSANT;So;0;ON;;;;;N;;;;; +1F951;AVOCADO;So;0;ON;;;;;N;;;;; +1F952;CUCUMBER;So;0;ON;;;;;N;;;;; +1F953;BACON;So;0;ON;;;;;N;;;;; +1F954;POTATO;So;0;ON;;;;;N;;;;; +1F955;CARROT;So;0;ON;;;;;N;;;;; +1F956;BAGUETTE BREAD;So;0;ON;;;;;N;;;;; +1F957;GREEN SALAD;So;0;ON;;;;;N;;;;; +1F958;SHALLOW PAN OF FOOD;So;0;ON;;;;;N;;;;; +1F959;STUFFED FLATBREAD;So;0;ON;;;;;N;;;;; +1F95A;EGG;So;0;ON;;;;;N;;;;; +1F95B;GLASS OF MILK;So;0;ON;;;;;N;;;;; +1F95C;PEANUTS;So;0;ON;;;;;N;;;;; +1F95D;KIWIFRUIT;So;0;ON;;;;;N;;;;; +1F95E;PANCAKES;So;0;ON;;;;;N;;;;; +1F95F;DUMPLING;So;0;ON;;;;;N;;;;; +1F960;FORTUNE COOKIE;So;0;ON;;;;;N;;;;; +1F961;TAKEOUT BOX;So;0;ON;;;;;N;;;;; +1F962;CHOPSTICKS;So;0;ON;;;;;N;;;;; +1F963;BOWL WITH SPOON;So;0;ON;;;;;N;;;;; +1F964;CUP WITH STRAW;So;0;ON;;;;;N;;;;; +1F965;COCONUT;So;0;ON;;;;;N;;;;; +1F966;BROCCOLI;So;0;ON;;;;;N;;;;; +1F967;PIE;So;0;ON;;;;;N;;;;; +1F968;PRETZEL;So;0;ON;;;;;N;;;;; +1F969;CUT OF MEAT;So;0;ON;;;;;N;;;;; +1F96A;SANDWICH;So;0;ON;;;;;N;;;;; +1F96B;CANNED FOOD;So;0;ON;;;;;N;;;;; +1F96C;LEAFY GREEN;So;0;ON;;;;;N;;;;; +1F96D;MANGO;So;0;ON;;;;;N;;;;; +1F96E;MOON CAKE;So;0;ON;;;;;N;;;;; +1F96F;BAGEL;So;0;ON;;;;;N;;;;; +1F970;SMILING FACE WITH SMILING EYES AND THREE HEARTS;So;0;ON;;;;;N;;;;; +1F971;YAWNING FACE;So;0;ON;;;;;N;;;;; +1F973;FACE WITH PARTY HORN AND PARTY HAT;So;0;ON;;;;;N;;;;; +1F974;FACE WITH UNEVEN EYES AND WAVY MOUTH;So;0;ON;;;;;N;;;;; +1F975;OVERHEATED FACE;So;0;ON;;;;;N;;;;; +1F976;FREEZING FACE;So;0;ON;;;;;N;;;;; +1F97A;FACE WITH PLEADING EYES;So;0;ON;;;;;N;;;;; +1F97B;SARI;So;0;ON;;;;;N;;;;; +1F97C;LAB COAT;So;0;ON;;;;;N;;;;; +1F97D;GOGGLES;So;0;ON;;;;;N;;;;; +1F97E;HIKING BOOT;So;0;ON;;;;;N;;;;; +1F97F;FLAT SHOE;So;0;ON;;;;;N;;;;; +1F980;CRAB;So;0;ON;;;;;N;;;;; +1F981;LION FACE;So;0;ON;;;;;N;;;;; +1F982;SCORPION;So;0;ON;;;;;N;;;;; +1F983;TURKEY;So;0;ON;;;;;N;;;;; +1F984;UNICORN FACE;So;0;ON;;;;;N;;;;; +1F985;EAGLE;So;0;ON;;;;;N;;;;; +1F986;DUCK;So;0;ON;;;;;N;;;;; +1F987;BAT;So;0;ON;;;;;N;;;;; +1F988;SHARK;So;0;ON;;;;;N;;;;; +1F989;OWL;So;0;ON;;;;;N;;;;; +1F98A;FOX FACE;So;0;ON;;;;;N;;;;; +1F98B;BUTTERFLY;So;0;ON;;;;;N;;;;; +1F98C;DEER;So;0;ON;;;;;N;;;;; +1F98D;GORILLA;So;0;ON;;;;;N;;;;; +1F98E;LIZARD;So;0;ON;;;;;N;;;;; +1F98F;RHINOCEROS;So;0;ON;;;;;N;;;;; +1F990;SHRIMP;So;0;ON;;;;;N;;;;; +1F991;SQUID;So;0;ON;;;;;N;;;;; +1F992;GIRAFFE FACE;So;0;ON;;;;;N;;;;; +1F993;ZEBRA FACE;So;0;ON;;;;;N;;;;; +1F994;HEDGEHOG;So;0;ON;;;;;N;;;;; +1F995;SAUROPOD;So;0;ON;;;;;N;;;;; +1F996;T-REX;So;0;ON;;;;;N;;;;; +1F997;CRICKET;So;0;ON;;;;;N;;;;; +1F998;KANGAROO;So;0;ON;;;;;N;;;;; +1F999;LLAMA;So;0;ON;;;;;N;;;;; +1F99A;PEACOCK;So;0;ON;;;;;N;;;;; +1F99B;HIPPOPOTAMUS;So;0;ON;;;;;N;;;;; +1F99C;PARROT;So;0;ON;;;;;N;;;;; +1F99D;RACCOON;So;0;ON;;;;;N;;;;; +1F99E;LOBSTER;So;0;ON;;;;;N;;;;; +1F99F;MOSQUITO;So;0;ON;;;;;N;;;;; +1F9A0;MICROBE;So;0;ON;;;;;N;;;;; +1F9A1;BADGER;So;0;ON;;;;;N;;;;; +1F9A2;SWAN;So;0;ON;;;;;N;;;;; +1F9A5;SLOTH;So;0;ON;;;;;N;;;;; +1F9A6;OTTER;So;0;ON;;;;;N;;;;; +1F9A7;ORANGUTAN;So;0;ON;;;;;N;;;;; +1F9A8;SKUNK;So;0;ON;;;;;N;;;;; +1F9A9;FLAMINGO;So;0;ON;;;;;N;;;;; +1F9AA;OYSTER;So;0;ON;;;;;N;;;;; +1F9AE;GUIDE DOG;So;0;ON;;;;;N;;;;; +1F9AF;PROBING CANE;So;0;ON;;;;;N;;;;; +1F9B0;EMOJI COMPONENT RED HAIR;So;0;ON;;;;;N;;;;; +1F9B1;EMOJI COMPONENT CURLY HAIR;So;0;ON;;;;;N;;;;; +1F9B2;EMOJI COMPONENT BALD;So;0;ON;;;;;N;;;;; +1F9B3;EMOJI COMPONENT WHITE HAIR;So;0;ON;;;;;N;;;;; +1F9B4;BONE;So;0;ON;;;;;N;;;;; +1F9B5;LEG;So;0;ON;;;;;N;;;;; +1F9B6;FOOT;So;0;ON;;;;;N;;;;; +1F9B7;TOOTH;So;0;ON;;;;;N;;;;; +1F9B8;SUPERHERO;So;0;ON;;;;;N;;;;; +1F9B9;SUPERVILLAIN;So;0;ON;;;;;N;;;;; +1F9BA;SAFETY VEST;So;0;ON;;;;;N;;;;; +1F9BB;EAR WITH HEARING AID;So;0;ON;;;;;N;;;;; +1F9BC;MOTORIZED WHEELCHAIR;So;0;ON;;;;;N;;;;; +1F9BD;MANUAL WHEELCHAIR;So;0;ON;;;;;N;;;;; +1F9BE;MECHANICAL ARM;So;0;ON;;;;;N;;;;; +1F9BF;MECHANICAL LEG;So;0;ON;;;;;N;;;;; +1F9C0;CHEESE WEDGE;So;0;ON;;;;;N;;;;; +1F9C1;CUPCAKE;So;0;ON;;;;;N;;;;; +1F9C2;SALT SHAKER;So;0;ON;;;;;N;;;;; +1F9C3;BEVERAGE BOX;So;0;ON;;;;;N;;;;; +1F9C4;GARLIC;So;0;ON;;;;;N;;;;; +1F9C5;ONION;So;0;ON;;;;;N;;;;; +1F9C6;FALAFEL;So;0;ON;;;;;N;;;;; +1F9C7;WAFFLE;So;0;ON;;;;;N;;;;; +1F9C8;BUTTER;So;0;ON;;;;;N;;;;; +1F9C9;MATE DRINK;So;0;ON;;;;;N;;;;; +1F9CA;ICE CUBE;So;0;ON;;;;;N;;;;; +1F9CD;STANDING PERSON;So;0;ON;;;;;N;;;;; +1F9CE;KNEELING PERSON;So;0;ON;;;;;N;;;;; +1F9CF;DEAF PERSON;So;0;ON;;;;;N;;;;; +1F9D0;FACE WITH MONOCLE;So;0;ON;;;;;N;;;;; +1F9D1;ADULT;So;0;ON;;;;;N;;;;; +1F9D2;CHILD;So;0;ON;;;;;N;;;;; +1F9D3;OLDER ADULT;So;0;ON;;;;;N;;;;; +1F9D4;BEARDED PERSON;So;0;ON;;;;;N;;;;; +1F9D5;PERSON WITH HEADSCARF;So;0;ON;;;;;N;;;;; +1F9D6;PERSON IN STEAMY ROOM;So;0;ON;;;;;N;;;;; +1F9D7;PERSON CLIMBING;So;0;ON;;;;;N;;;;; +1F9D8;PERSON IN LOTUS POSITION;So;0;ON;;;;;N;;;;; +1F9D9;MAGE;So;0;ON;;;;;N;;;;; +1F9DA;FAIRY;So;0;ON;;;;;N;;;;; +1F9DB;VAMPIRE;So;0;ON;;;;;N;;;;; +1F9DC;MERPERSON;So;0;ON;;;;;N;;;;; +1F9DD;ELF;So;0;ON;;;;;N;;;;; +1F9DE;GENIE;So;0;ON;;;;;N;;;;; +1F9DF;ZOMBIE;So;0;ON;;;;;N;;;;; +1F9E0;BRAIN;So;0;ON;;;;;N;;;;; +1F9E1;ORANGE HEART;So;0;ON;;;;;N;;;;; +1F9E2;BILLED CAP;So;0;ON;;;;;N;;;;; +1F9E3;SCARF;So;0;ON;;;;;N;;;;; +1F9E4;GLOVES;So;0;ON;;;;;N;;;;; +1F9E5;COAT;So;0;ON;;;;;N;;;;; +1F9E6;SOCKS;So;0;ON;;;;;N;;;;; +1F9E7;RED GIFT ENVELOPE;So;0;ON;;;;;N;;;;; +1F9E8;FIRECRACKER;So;0;ON;;;;;N;;;;; +1F9E9;JIGSAW PUZZLE PIECE;So;0;ON;;;;;N;;;;; +1F9EA;TEST TUBE;So;0;ON;;;;;N;;;;; +1F9EB;PETRI DISH;So;0;ON;;;;;N;;;;; +1F9EC;DNA DOUBLE HELIX;So;0;ON;;;;;N;;;;; +1F9ED;COMPASS;So;0;ON;;;;;N;;;;; +1F9EE;ABACUS;So;0;ON;;;;;N;;;;; +1F9EF;FIRE EXTINGUISHER;So;0;ON;;;;;N;;;;; +1F9F0;TOOLBOX;So;0;ON;;;;;N;;;;; +1F9F1;BRICK;So;0;ON;;;;;N;;;;; +1F9F2;MAGNET;So;0;ON;;;;;N;;;;; +1F9F3;LUGGAGE;So;0;ON;;;;;N;;;;; +1F9F4;LOTION BOTTLE;So;0;ON;;;;;N;;;;; +1F9F5;SPOOL OF THREAD;So;0;ON;;;;;N;;;;; +1F9F6;BALL OF YARN;So;0;ON;;;;;N;;;;; +1F9F7;SAFETY PIN;So;0;ON;;;;;N;;;;; +1F9F8;TEDDY BEAR;So;0;ON;;;;;N;;;;; +1F9F9;BROOM;So;0;ON;;;;;N;;;;; +1F9FA;BASKET;So;0;ON;;;;;N;;;;; +1F9FB;ROLL OF PAPER;So;0;ON;;;;;N;;;;; +1F9FC;BAR OF SOAP;So;0;ON;;;;;N;;;;; +1F9FD;SPONGE;So;0;ON;;;;;N;;;;; +1F9FE;RECEIPT;So;0;ON;;;;;N;;;;; +1F9FF;NAZAR AMULET;So;0;ON;;;;;N;;;;; +1FA00;NEUTRAL CHESS KING;So;0;ON;;;;;N;;;;; +1FA01;NEUTRAL CHESS QUEEN;So;0;ON;;;;;N;;;;; +1FA02;NEUTRAL CHESS ROOK;So;0;ON;;;;;N;;;;; +1FA03;NEUTRAL CHESS BISHOP;So;0;ON;;;;;N;;;;; +1FA04;NEUTRAL CHESS KNIGHT;So;0;ON;;;;;N;;;;; +1FA05;NEUTRAL CHESS PAWN;So;0;ON;;;;;N;;;;; +1FA06;WHITE CHESS KNIGHT ROTATED FORTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA07;BLACK CHESS KNIGHT ROTATED FORTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA08;NEUTRAL CHESS KNIGHT ROTATED FORTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA09;WHITE CHESS KING ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0A;WHITE CHESS QUEEN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0B;WHITE CHESS ROOK ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0C;WHITE CHESS BISHOP ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0D;WHITE CHESS KNIGHT ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0E;WHITE CHESS PAWN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0F;BLACK CHESS KING ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA10;BLACK CHESS QUEEN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA11;BLACK CHESS ROOK ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA12;BLACK CHESS BISHOP ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA13;BLACK CHESS KNIGHT ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA14;BLACK CHESS PAWN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA15;NEUTRAL CHESS KING ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA16;NEUTRAL CHESS QUEEN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA17;NEUTRAL CHESS ROOK ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA18;NEUTRAL CHESS BISHOP ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA19;NEUTRAL CHESS KNIGHT ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA1A;NEUTRAL CHESS PAWN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA1B;WHITE CHESS KNIGHT ROTATED ONE HUNDRED THIRTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA1C;BLACK CHESS KNIGHT ROTATED ONE HUNDRED THIRTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA1D;NEUTRAL CHESS KNIGHT ROTATED ONE HUNDRED THIRTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA1E;WHITE CHESS TURNED KING;So;0;ON;;;;;N;;;;; +1FA1F;WHITE CHESS TURNED QUEEN;So;0;ON;;;;;N;;;;; +1FA20;WHITE CHESS TURNED ROOK;So;0;ON;;;;;N;;;;; +1FA21;WHITE CHESS TURNED BISHOP;So;0;ON;;;;;N;;;;; +1FA22;WHITE CHESS TURNED KNIGHT;So;0;ON;;;;;N;;;;; +1FA23;WHITE CHESS TURNED PAWN;So;0;ON;;;;;N;;;;; +1FA24;BLACK CHESS TURNED KING;So;0;ON;;;;;N;;;;; +1FA25;BLACK CHESS TURNED QUEEN;So;0;ON;;;;;N;;;;; +1FA26;BLACK CHESS TURNED ROOK;So;0;ON;;;;;N;;;;; +1FA27;BLACK CHESS TURNED BISHOP;So;0;ON;;;;;N;;;;; +1FA28;BLACK CHESS TURNED KNIGHT;So;0;ON;;;;;N;;;;; +1FA29;BLACK CHESS TURNED PAWN;So;0;ON;;;;;N;;;;; +1FA2A;NEUTRAL CHESS TURNED KING;So;0;ON;;;;;N;;;;; +1FA2B;NEUTRAL CHESS TURNED QUEEN;So;0;ON;;;;;N;;;;; +1FA2C;NEUTRAL CHESS TURNED ROOK;So;0;ON;;;;;N;;;;; +1FA2D;NEUTRAL CHESS TURNED BISHOP;So;0;ON;;;;;N;;;;; +1FA2E;NEUTRAL CHESS TURNED KNIGHT;So;0;ON;;;;;N;;;;; +1FA2F;NEUTRAL CHESS TURNED PAWN;So;0;ON;;;;;N;;;;; +1FA30;WHITE CHESS KNIGHT ROTATED TWO HUNDRED TWENTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA31;BLACK CHESS KNIGHT ROTATED TWO HUNDRED TWENTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA32;NEUTRAL CHESS KNIGHT ROTATED TWO HUNDRED TWENTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA33;WHITE CHESS KING ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA34;WHITE CHESS QUEEN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA35;WHITE CHESS ROOK ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA36;WHITE CHESS BISHOP ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA37;WHITE CHESS KNIGHT ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA38;WHITE CHESS PAWN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA39;BLACK CHESS KING ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3A;BLACK CHESS QUEEN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3B;BLACK CHESS ROOK ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3C;BLACK CHESS BISHOP ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3D;BLACK CHESS KNIGHT ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3E;BLACK CHESS PAWN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3F;NEUTRAL CHESS KING ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA40;NEUTRAL CHESS QUEEN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA41;NEUTRAL CHESS ROOK ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA42;NEUTRAL CHESS BISHOP ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA43;NEUTRAL CHESS KNIGHT ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA44;NEUTRAL CHESS PAWN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA45;WHITE CHESS KNIGHT ROTATED THREE HUNDRED FIFTEEN DEGREES;So;0;ON;;;;;N;;;;; +1FA46;BLACK CHESS KNIGHT ROTATED THREE HUNDRED FIFTEEN DEGREES;So;0;ON;;;;;N;;;;; +1FA47;NEUTRAL CHESS KNIGHT ROTATED THREE HUNDRED FIFTEEN DEGREES;So;0;ON;;;;;N;;;;; +1FA48;WHITE CHESS EQUIHOPPER;So;0;ON;;;;;N;;;;; +1FA49;BLACK CHESS EQUIHOPPER;So;0;ON;;;;;N;;;;; +1FA4A;NEUTRAL CHESS EQUIHOPPER;So;0;ON;;;;;N;;;;; +1FA4B;WHITE CHESS EQUIHOPPER ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA4C;BLACK CHESS EQUIHOPPER ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA4D;NEUTRAL CHESS EQUIHOPPER ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA4E;WHITE CHESS KNIGHT-QUEEN;So;0;ON;;;;;N;;;;; +1FA4F;WHITE CHESS KNIGHT-ROOK;So;0;ON;;;;;N;;;;; +1FA50;WHITE CHESS KNIGHT-BISHOP;So;0;ON;;;;;N;;;;; +1FA51;BLACK CHESS KNIGHT-QUEEN;So;0;ON;;;;;N;;;;; +1FA52;BLACK CHESS KNIGHT-ROOK;So;0;ON;;;;;N;;;;; +1FA53;BLACK CHESS KNIGHT-BISHOP;So;0;ON;;;;;N;;;;; +1FA60;XIANGQI RED GENERAL;So;0;ON;;;;;N;;;;; +1FA61;XIANGQI RED MANDARIN;So;0;ON;;;;;N;;;;; +1FA62;XIANGQI RED ELEPHANT;So;0;ON;;;;;N;;;;; +1FA63;XIANGQI RED HORSE;So;0;ON;;;;;N;;;;; +1FA64;XIANGQI RED CHARIOT;So;0;ON;;;;;N;;;;; +1FA65;XIANGQI RED CANNON;So;0;ON;;;;;N;;;;; +1FA66;XIANGQI RED SOLDIER;So;0;ON;;;;;N;;;;; +1FA67;XIANGQI BLACK GENERAL;So;0;ON;;;;;N;;;;; +1FA68;XIANGQI BLACK MANDARIN;So;0;ON;;;;;N;;;;; +1FA69;XIANGQI BLACK ELEPHANT;So;0;ON;;;;;N;;;;; +1FA6A;XIANGQI BLACK HORSE;So;0;ON;;;;;N;;;;; +1FA6B;XIANGQI BLACK CHARIOT;So;0;ON;;;;;N;;;;; +1FA6C;XIANGQI BLACK CANNON;So;0;ON;;;;;N;;;;; +1FA6D;XIANGQI BLACK SOLDIER;So;0;ON;;;;;N;;;;; +1FA70;BALLET SHOES;So;0;ON;;;;;N;;;;; +1FA71;ONE-PIECE SWIMSUIT;So;0;ON;;;;;N;;;;; +1FA72;BRIEFS;So;0;ON;;;;;N;;;;; +1FA73;SHORTS;So;0;ON;;;;;N;;;;; +1FA78;DROP OF BLOOD;So;0;ON;;;;;N;;;;; +1FA79;ADHESIVE BANDAGE;So;0;ON;;;;;N;;;;; +1FA7A;STETHOSCOPE;So;0;ON;;;;;N;;;;; +1FA80;YO-YO;So;0;ON;;;;;N;;;;; +1FA81;KITE;So;0;ON;;;;;N;;;;; +1FA82;PARACHUTE;So;0;ON;;;;;N;;;;; +1FA90;RINGED PLANET;So;0;ON;;;;;N;;;;; +1FA91;CHAIR;So;0;ON;;;;;N;;;;; +1FA92;RAZOR;So;0;ON;;;;;N;;;;; +1FA93;AXE;So;0;ON;;;;;N;;;;; +1FA94;DIYA LAMP;So;0;ON;;;;;N;;;;; +1FA95;BANJO;So;0;ON;;;;;N;;;;; +20000;;Lo;0;L;;;;;N;;;;; +2A6D6;;Lo;0;L;;;;;N;;;;; +2A700;;Lo;0;L;;;;;N;;;;; +2B734;;Lo;0;L;;;;;N;;;;; +2B740;;Lo;0;L;;;;;N;;;;; +2B81D;;Lo;0;L;;;;;N;;;;; +2B820;;Lo;0;L;;;;;N;;;;; +2CEA1;;Lo;0;L;;;;;N;;;;; +2CEB0;;Lo;0;L;;;;;N;;;;; +2EBE0;;Lo;0;L;;;;;N;;;;; +2F800;CJK COMPATIBILITY IDEOGRAPH-2F800;Lo;0;L;4E3D;;;;N;;;;; +2F801;CJK COMPATIBILITY IDEOGRAPH-2F801;Lo;0;L;4E38;;;;N;;;;; +2F802;CJK COMPATIBILITY IDEOGRAPH-2F802;Lo;0;L;4E41;;;;N;;;;; +2F803;CJK COMPATIBILITY IDEOGRAPH-2F803;Lo;0;L;20122;;;;N;;;;; +2F804;CJK COMPATIBILITY IDEOGRAPH-2F804;Lo;0;L;4F60;;;;N;;;;; +2F805;CJK COMPATIBILITY IDEOGRAPH-2F805;Lo;0;L;4FAE;;;;N;;;;; +2F806;CJK COMPATIBILITY IDEOGRAPH-2F806;Lo;0;L;4FBB;;;;N;;;;; +2F807;CJK COMPATIBILITY IDEOGRAPH-2F807;Lo;0;L;5002;;;;N;;;;; +2F808;CJK COMPATIBILITY IDEOGRAPH-2F808;Lo;0;L;507A;;;;N;;;;; +2F809;CJK COMPATIBILITY IDEOGRAPH-2F809;Lo;0;L;5099;;;;N;;;;; +2F80A;CJK COMPATIBILITY IDEOGRAPH-2F80A;Lo;0;L;50E7;;;;N;;;;; +2F80B;CJK COMPATIBILITY IDEOGRAPH-2F80B;Lo;0;L;50CF;;;;N;;;;; +2F80C;CJK COMPATIBILITY IDEOGRAPH-2F80C;Lo;0;L;349E;;;;N;;;;; +2F80D;CJK COMPATIBILITY IDEOGRAPH-2F80D;Lo;0;L;2063A;;;;N;;;;; +2F80E;CJK COMPATIBILITY IDEOGRAPH-2F80E;Lo;0;L;514D;;;;N;;;;; +2F80F;CJK COMPATIBILITY IDEOGRAPH-2F80F;Lo;0;L;5154;;;;N;;;;; +2F810;CJK COMPATIBILITY IDEOGRAPH-2F810;Lo;0;L;5164;;;;N;;;;; +2F811;CJK COMPATIBILITY IDEOGRAPH-2F811;Lo;0;L;5177;;;;N;;;;; +2F812;CJK COMPATIBILITY IDEOGRAPH-2F812;Lo;0;L;2051C;;;;N;;;;; +2F813;CJK COMPATIBILITY IDEOGRAPH-2F813;Lo;0;L;34B9;;;;N;;;;; +2F814;CJK COMPATIBILITY IDEOGRAPH-2F814;Lo;0;L;5167;;;;N;;;;; +2F815;CJK COMPATIBILITY IDEOGRAPH-2F815;Lo;0;L;518D;;;;N;;;;; +2F816;CJK COMPATIBILITY IDEOGRAPH-2F816;Lo;0;L;2054B;;;;N;;;;; +2F817;CJK COMPATIBILITY IDEOGRAPH-2F817;Lo;0;L;5197;;;;N;;;;; +2F818;CJK COMPATIBILITY IDEOGRAPH-2F818;Lo;0;L;51A4;;;;N;;;;; +2F819;CJK COMPATIBILITY IDEOGRAPH-2F819;Lo;0;L;4ECC;;;;N;;;;; +2F81A;CJK COMPATIBILITY IDEOGRAPH-2F81A;Lo;0;L;51AC;;;;N;;;;; +2F81B;CJK COMPATIBILITY IDEOGRAPH-2F81B;Lo;0;L;51B5;;;;N;;;;; +2F81C;CJK COMPATIBILITY IDEOGRAPH-2F81C;Lo;0;L;291DF;;;;N;;;;; +2F81D;CJK COMPATIBILITY IDEOGRAPH-2F81D;Lo;0;L;51F5;;;;N;;;;; +2F81E;CJK COMPATIBILITY IDEOGRAPH-2F81E;Lo;0;L;5203;;;;N;;;;; +2F81F;CJK COMPATIBILITY IDEOGRAPH-2F81F;Lo;0;L;34DF;;;;N;;;;; +2F820;CJK COMPATIBILITY IDEOGRAPH-2F820;Lo;0;L;523B;;;;N;;;;; +2F821;CJK COMPATIBILITY IDEOGRAPH-2F821;Lo;0;L;5246;;;;N;;;;; +2F822;CJK COMPATIBILITY IDEOGRAPH-2F822;Lo;0;L;5272;;;;N;;;;; +2F823;CJK COMPATIBILITY IDEOGRAPH-2F823;Lo;0;L;5277;;;;N;;;;; +2F824;CJK COMPATIBILITY IDEOGRAPH-2F824;Lo;0;L;3515;;;;N;;;;; +2F825;CJK COMPATIBILITY IDEOGRAPH-2F825;Lo;0;L;52C7;;;;N;;;;; +2F826;CJK COMPATIBILITY IDEOGRAPH-2F826;Lo;0;L;52C9;;;;N;;;;; +2F827;CJK COMPATIBILITY IDEOGRAPH-2F827;Lo;0;L;52E4;;;;N;;;;; +2F828;CJK COMPATIBILITY IDEOGRAPH-2F828;Lo;0;L;52FA;;;;N;;;;; +2F829;CJK COMPATIBILITY IDEOGRAPH-2F829;Lo;0;L;5305;;;;N;;;;; +2F82A;CJK COMPATIBILITY IDEOGRAPH-2F82A;Lo;0;L;5306;;;;N;;;;; +2F82B;CJK COMPATIBILITY IDEOGRAPH-2F82B;Lo;0;L;5317;;;;N;;;;; +2F82C;CJK COMPATIBILITY IDEOGRAPH-2F82C;Lo;0;L;5349;;;;N;;;;; +2F82D;CJK COMPATIBILITY IDEOGRAPH-2F82D;Lo;0;L;5351;;;;N;;;;; +2F82E;CJK COMPATIBILITY IDEOGRAPH-2F82E;Lo;0;L;535A;;;;N;;;;; +2F82F;CJK COMPATIBILITY IDEOGRAPH-2F82F;Lo;0;L;5373;;;;N;;;;; +2F830;CJK COMPATIBILITY IDEOGRAPH-2F830;Lo;0;L;537D;;;;N;;;;; +2F831;CJK COMPATIBILITY IDEOGRAPH-2F831;Lo;0;L;537F;;;;N;;;;; +2F832;CJK COMPATIBILITY IDEOGRAPH-2F832;Lo;0;L;537F;;;;N;;;;; +2F833;CJK COMPATIBILITY IDEOGRAPH-2F833;Lo;0;L;537F;;;;N;;;;; +2F834;CJK COMPATIBILITY IDEOGRAPH-2F834;Lo;0;L;20A2C;;;;N;;;;; +2F835;CJK COMPATIBILITY IDEOGRAPH-2F835;Lo;0;L;7070;;;;N;;;;; +2F836;CJK COMPATIBILITY IDEOGRAPH-2F836;Lo;0;L;53CA;;;;N;;;;; +2F837;CJK COMPATIBILITY IDEOGRAPH-2F837;Lo;0;L;53DF;;;;N;;;;; +2F838;CJK COMPATIBILITY IDEOGRAPH-2F838;Lo;0;L;20B63;;;;N;;;;; +2F839;CJK COMPATIBILITY IDEOGRAPH-2F839;Lo;0;L;53EB;;;;N;;;;; +2F83A;CJK COMPATIBILITY IDEOGRAPH-2F83A;Lo;0;L;53F1;;;;N;;;;; +2F83B;CJK COMPATIBILITY IDEOGRAPH-2F83B;Lo;0;L;5406;;;;N;;;;; +2F83C;CJK COMPATIBILITY IDEOGRAPH-2F83C;Lo;0;L;549E;;;;N;;;;; +2F83D;CJK COMPATIBILITY IDEOGRAPH-2F83D;Lo;0;L;5438;;;;N;;;;; +2F83E;CJK COMPATIBILITY IDEOGRAPH-2F83E;Lo;0;L;5448;;;;N;;;;; +2F83F;CJK COMPATIBILITY IDEOGRAPH-2F83F;Lo;0;L;5468;;;;N;;;;; +2F840;CJK COMPATIBILITY IDEOGRAPH-2F840;Lo;0;L;54A2;;;;N;;;;; +2F841;CJK COMPATIBILITY IDEOGRAPH-2F841;Lo;0;L;54F6;;;;N;;;;; +2F842;CJK COMPATIBILITY IDEOGRAPH-2F842;Lo;0;L;5510;;;;N;;;;; +2F843;CJK COMPATIBILITY IDEOGRAPH-2F843;Lo;0;L;5553;;;;N;;;;; +2F844;CJK COMPATIBILITY IDEOGRAPH-2F844;Lo;0;L;5563;;;;N;;;;; +2F845;CJK COMPATIBILITY IDEOGRAPH-2F845;Lo;0;L;5584;;;;N;;;;; +2F846;CJK COMPATIBILITY IDEOGRAPH-2F846;Lo;0;L;5584;;;;N;;;;; +2F847;CJK COMPATIBILITY IDEOGRAPH-2F847;Lo;0;L;5599;;;;N;;;;; +2F848;CJK COMPATIBILITY IDEOGRAPH-2F848;Lo;0;L;55AB;;;;N;;;;; +2F849;CJK COMPATIBILITY IDEOGRAPH-2F849;Lo;0;L;55B3;;;;N;;;;; +2F84A;CJK COMPATIBILITY IDEOGRAPH-2F84A;Lo;0;L;55C2;;;;N;;;;; +2F84B;CJK COMPATIBILITY IDEOGRAPH-2F84B;Lo;0;L;5716;;;;N;;;;; +2F84C;CJK COMPATIBILITY IDEOGRAPH-2F84C;Lo;0;L;5606;;;;N;;;;; +2F84D;CJK COMPATIBILITY IDEOGRAPH-2F84D;Lo;0;L;5717;;;;N;;;;; +2F84E;CJK COMPATIBILITY IDEOGRAPH-2F84E;Lo;0;L;5651;;;;N;;;;; +2F84F;CJK COMPATIBILITY IDEOGRAPH-2F84F;Lo;0;L;5674;;;;N;;;;; +2F850;CJK COMPATIBILITY IDEOGRAPH-2F850;Lo;0;L;5207;;;;N;;;;; +2F851;CJK COMPATIBILITY IDEOGRAPH-2F851;Lo;0;L;58EE;;;;N;;;;; +2F852;CJK COMPATIBILITY IDEOGRAPH-2F852;Lo;0;L;57CE;;;;N;;;;; +2F853;CJK COMPATIBILITY IDEOGRAPH-2F853;Lo;0;L;57F4;;;;N;;;;; +2F854;CJK COMPATIBILITY IDEOGRAPH-2F854;Lo;0;L;580D;;;;N;;;;; +2F855;CJK COMPATIBILITY IDEOGRAPH-2F855;Lo;0;L;578B;;;;N;;;;; +2F856;CJK COMPATIBILITY IDEOGRAPH-2F856;Lo;0;L;5832;;;;N;;;;; +2F857;CJK COMPATIBILITY IDEOGRAPH-2F857;Lo;0;L;5831;;;;N;;;;; +2F858;CJK COMPATIBILITY IDEOGRAPH-2F858;Lo;0;L;58AC;;;;N;;;;; +2F859;CJK COMPATIBILITY IDEOGRAPH-2F859;Lo;0;L;214E4;;;;N;;;;; +2F85A;CJK COMPATIBILITY IDEOGRAPH-2F85A;Lo;0;L;58F2;;;;N;;;;; +2F85B;CJK COMPATIBILITY IDEOGRAPH-2F85B;Lo;0;L;58F7;;;;N;;;;; +2F85C;CJK COMPATIBILITY IDEOGRAPH-2F85C;Lo;0;L;5906;;;;N;;;;; +2F85D;CJK COMPATIBILITY IDEOGRAPH-2F85D;Lo;0;L;591A;;;;N;;;;; +2F85E;CJK COMPATIBILITY IDEOGRAPH-2F85E;Lo;0;L;5922;;;;N;;;;; +2F85F;CJK COMPATIBILITY IDEOGRAPH-2F85F;Lo;0;L;5962;;;;N;;;;; +2F860;CJK COMPATIBILITY IDEOGRAPH-2F860;Lo;0;L;216A8;;;;N;;;;; +2F861;CJK COMPATIBILITY IDEOGRAPH-2F861;Lo;0;L;216EA;;;;N;;;;; +2F862;CJK COMPATIBILITY IDEOGRAPH-2F862;Lo;0;L;59EC;;;;N;;;;; +2F863;CJK COMPATIBILITY IDEOGRAPH-2F863;Lo;0;L;5A1B;;;;N;;;;; +2F864;CJK COMPATIBILITY IDEOGRAPH-2F864;Lo;0;L;5A27;;;;N;;;;; +2F865;CJK COMPATIBILITY IDEOGRAPH-2F865;Lo;0;L;59D8;;;;N;;;;; +2F866;CJK COMPATIBILITY IDEOGRAPH-2F866;Lo;0;L;5A66;;;;N;;;;; +2F867;CJK COMPATIBILITY IDEOGRAPH-2F867;Lo;0;L;36EE;;;;N;;;;; +2F868;CJK COMPATIBILITY IDEOGRAPH-2F868;Lo;0;L;36FC;;;;N;;;;; +2F869;CJK COMPATIBILITY IDEOGRAPH-2F869;Lo;0;L;5B08;;;;N;;;;; +2F86A;CJK COMPATIBILITY IDEOGRAPH-2F86A;Lo;0;L;5B3E;;;;N;;;;; +2F86B;CJK COMPATIBILITY IDEOGRAPH-2F86B;Lo;0;L;5B3E;;;;N;;;;; +2F86C;CJK COMPATIBILITY IDEOGRAPH-2F86C;Lo;0;L;219C8;;;;N;;;;; +2F86D;CJK COMPATIBILITY IDEOGRAPH-2F86D;Lo;0;L;5BC3;;;;N;;;;; +2F86E;CJK COMPATIBILITY IDEOGRAPH-2F86E;Lo;0;L;5BD8;;;;N;;;;; +2F86F;CJK COMPATIBILITY IDEOGRAPH-2F86F;Lo;0;L;5BE7;;;;N;;;;; +2F870;CJK COMPATIBILITY IDEOGRAPH-2F870;Lo;0;L;5BF3;;;;N;;;;; +2F871;CJK COMPATIBILITY IDEOGRAPH-2F871;Lo;0;L;21B18;;;;N;;;;; +2F872;CJK COMPATIBILITY IDEOGRAPH-2F872;Lo;0;L;5BFF;;;;N;;;;; +2F873;CJK COMPATIBILITY IDEOGRAPH-2F873;Lo;0;L;5C06;;;;N;;;;; +2F874;CJK COMPATIBILITY IDEOGRAPH-2F874;Lo;0;L;5F53;;;;N;;;;; +2F875;CJK COMPATIBILITY IDEOGRAPH-2F875;Lo;0;L;5C22;;;;N;;;;; +2F876;CJK COMPATIBILITY IDEOGRAPH-2F876;Lo;0;L;3781;;;;N;;;;; +2F877;CJK COMPATIBILITY IDEOGRAPH-2F877;Lo;0;L;5C60;;;;N;;;;; +2F878;CJK COMPATIBILITY IDEOGRAPH-2F878;Lo;0;L;5C6E;;;;N;;;;; +2F879;CJK COMPATIBILITY IDEOGRAPH-2F879;Lo;0;L;5CC0;;;;N;;;;; +2F87A;CJK COMPATIBILITY IDEOGRAPH-2F87A;Lo;0;L;5C8D;;;;N;;;;; +2F87B;CJK COMPATIBILITY IDEOGRAPH-2F87B;Lo;0;L;21DE4;;;;N;;;;; +2F87C;CJK COMPATIBILITY IDEOGRAPH-2F87C;Lo;0;L;5D43;;;;N;;;;; +2F87D;CJK COMPATIBILITY IDEOGRAPH-2F87D;Lo;0;L;21DE6;;;;N;;;;; +2F87E;CJK COMPATIBILITY IDEOGRAPH-2F87E;Lo;0;L;5D6E;;;;N;;;;; +2F87F;CJK COMPATIBILITY IDEOGRAPH-2F87F;Lo;0;L;5D6B;;;;N;;;;; +2F880;CJK COMPATIBILITY IDEOGRAPH-2F880;Lo;0;L;5D7C;;;;N;;;;; +2F881;CJK COMPATIBILITY IDEOGRAPH-2F881;Lo;0;L;5DE1;;;;N;;;;; +2F882;CJK COMPATIBILITY IDEOGRAPH-2F882;Lo;0;L;5DE2;;;;N;;;;; +2F883;CJK COMPATIBILITY IDEOGRAPH-2F883;Lo;0;L;382F;;;;N;;;;; +2F884;CJK COMPATIBILITY IDEOGRAPH-2F884;Lo;0;L;5DFD;;;;N;;;;; +2F885;CJK COMPATIBILITY IDEOGRAPH-2F885;Lo;0;L;5E28;;;;N;;;;; +2F886;CJK COMPATIBILITY IDEOGRAPH-2F886;Lo;0;L;5E3D;;;;N;;;;; +2F887;CJK COMPATIBILITY IDEOGRAPH-2F887;Lo;0;L;5E69;;;;N;;;;; +2F888;CJK COMPATIBILITY IDEOGRAPH-2F888;Lo;0;L;3862;;;;N;;;;; +2F889;CJK COMPATIBILITY IDEOGRAPH-2F889;Lo;0;L;22183;;;;N;;;;; +2F88A;CJK COMPATIBILITY IDEOGRAPH-2F88A;Lo;0;L;387C;;;;N;;;;; +2F88B;CJK COMPATIBILITY IDEOGRAPH-2F88B;Lo;0;L;5EB0;;;;N;;;;; +2F88C;CJK COMPATIBILITY IDEOGRAPH-2F88C;Lo;0;L;5EB3;;;;N;;;;; +2F88D;CJK COMPATIBILITY IDEOGRAPH-2F88D;Lo;0;L;5EB6;;;;N;;;;; +2F88E;CJK COMPATIBILITY IDEOGRAPH-2F88E;Lo;0;L;5ECA;;;;N;;;;; +2F88F;CJK COMPATIBILITY IDEOGRAPH-2F88F;Lo;0;L;2A392;;;;N;;;;; +2F890;CJK COMPATIBILITY IDEOGRAPH-2F890;Lo;0;L;5EFE;;;9;N;;;;; +2F891;CJK COMPATIBILITY IDEOGRAPH-2F891;Lo;0;L;22331;;;;N;;;;; +2F892;CJK COMPATIBILITY IDEOGRAPH-2F892;Lo;0;L;22331;;;;N;;;;; +2F893;CJK COMPATIBILITY IDEOGRAPH-2F893;Lo;0;L;8201;;;;N;;;;; +2F894;CJK COMPATIBILITY IDEOGRAPH-2F894;Lo;0;L;5F22;;;;N;;;;; +2F895;CJK COMPATIBILITY IDEOGRAPH-2F895;Lo;0;L;5F22;;;;N;;;;; +2F896;CJK COMPATIBILITY IDEOGRAPH-2F896;Lo;0;L;38C7;;;;N;;;;; +2F897;CJK COMPATIBILITY IDEOGRAPH-2F897;Lo;0;L;232B8;;;;N;;;;; +2F898;CJK COMPATIBILITY IDEOGRAPH-2F898;Lo;0;L;261DA;;;;N;;;;; +2F899;CJK COMPATIBILITY IDEOGRAPH-2F899;Lo;0;L;5F62;;;;N;;;;; +2F89A;CJK COMPATIBILITY IDEOGRAPH-2F89A;Lo;0;L;5F6B;;;;N;;;;; +2F89B;CJK COMPATIBILITY IDEOGRAPH-2F89B;Lo;0;L;38E3;;;;N;;;;; +2F89C;CJK COMPATIBILITY IDEOGRAPH-2F89C;Lo;0;L;5F9A;;;;N;;;;; +2F89D;CJK COMPATIBILITY IDEOGRAPH-2F89D;Lo;0;L;5FCD;;;;N;;;;; +2F89E;CJK COMPATIBILITY IDEOGRAPH-2F89E;Lo;0;L;5FD7;;;;N;;;;; +2F89F;CJK COMPATIBILITY IDEOGRAPH-2F89F;Lo;0;L;5FF9;;;;N;;;;; +2F8A0;CJK COMPATIBILITY IDEOGRAPH-2F8A0;Lo;0;L;6081;;;;N;;;;; +2F8A1;CJK COMPATIBILITY IDEOGRAPH-2F8A1;Lo;0;L;393A;;;;N;;;;; +2F8A2;CJK COMPATIBILITY IDEOGRAPH-2F8A2;Lo;0;L;391C;;;;N;;;;; +2F8A3;CJK COMPATIBILITY IDEOGRAPH-2F8A3;Lo;0;L;6094;;;;N;;;;; +2F8A4;CJK COMPATIBILITY IDEOGRAPH-2F8A4;Lo;0;L;226D4;;;;N;;;;; +2F8A5;CJK COMPATIBILITY IDEOGRAPH-2F8A5;Lo;0;L;60C7;;;;N;;;;; +2F8A6;CJK COMPATIBILITY IDEOGRAPH-2F8A6;Lo;0;L;6148;;;;N;;;;; +2F8A7;CJK COMPATIBILITY IDEOGRAPH-2F8A7;Lo;0;L;614C;;;;N;;;;; +2F8A8;CJK COMPATIBILITY IDEOGRAPH-2F8A8;Lo;0;L;614E;;;;N;;;;; +2F8A9;CJK COMPATIBILITY IDEOGRAPH-2F8A9;Lo;0;L;614C;;;;N;;;;; +2F8AA;CJK COMPATIBILITY IDEOGRAPH-2F8AA;Lo;0;L;617A;;;;N;;;;; +2F8AB;CJK COMPATIBILITY IDEOGRAPH-2F8AB;Lo;0;L;618E;;;;N;;;;; +2F8AC;CJK COMPATIBILITY IDEOGRAPH-2F8AC;Lo;0;L;61B2;;;;N;;;;; +2F8AD;CJK COMPATIBILITY IDEOGRAPH-2F8AD;Lo;0;L;61A4;;;;N;;;;; +2F8AE;CJK COMPATIBILITY IDEOGRAPH-2F8AE;Lo;0;L;61AF;;;;N;;;;; +2F8AF;CJK COMPATIBILITY IDEOGRAPH-2F8AF;Lo;0;L;61DE;;;;N;;;;; +2F8B0;CJK COMPATIBILITY IDEOGRAPH-2F8B0;Lo;0;L;61F2;;;;N;;;;; +2F8B1;CJK COMPATIBILITY IDEOGRAPH-2F8B1;Lo;0;L;61F6;;;;N;;;;; +2F8B2;CJK COMPATIBILITY IDEOGRAPH-2F8B2;Lo;0;L;6210;;;;N;;;;; +2F8B3;CJK COMPATIBILITY IDEOGRAPH-2F8B3;Lo;0;L;621B;;;;N;;;;; +2F8B4;CJK COMPATIBILITY IDEOGRAPH-2F8B4;Lo;0;L;625D;;;;N;;;;; +2F8B5;CJK COMPATIBILITY IDEOGRAPH-2F8B5;Lo;0;L;62B1;;;;N;;;;; +2F8B6;CJK COMPATIBILITY IDEOGRAPH-2F8B6;Lo;0;L;62D4;;;;N;;;;; +2F8B7;CJK COMPATIBILITY IDEOGRAPH-2F8B7;Lo;0;L;6350;;;;N;;;;; +2F8B8;CJK COMPATIBILITY IDEOGRAPH-2F8B8;Lo;0;L;22B0C;;;;N;;;;; +2F8B9;CJK COMPATIBILITY IDEOGRAPH-2F8B9;Lo;0;L;633D;;;;N;;;;; +2F8BA;CJK COMPATIBILITY IDEOGRAPH-2F8BA;Lo;0;L;62FC;;;;N;;;;; +2F8BB;CJK COMPATIBILITY IDEOGRAPH-2F8BB;Lo;0;L;6368;;;;N;;;;; +2F8BC;CJK COMPATIBILITY IDEOGRAPH-2F8BC;Lo;0;L;6383;;;;N;;;;; +2F8BD;CJK COMPATIBILITY IDEOGRAPH-2F8BD;Lo;0;L;63E4;;;;N;;;;; +2F8BE;CJK COMPATIBILITY IDEOGRAPH-2F8BE;Lo;0;L;22BF1;;;;N;;;;; +2F8BF;CJK COMPATIBILITY IDEOGRAPH-2F8BF;Lo;0;L;6422;;;;N;;;;; +2F8C0;CJK COMPATIBILITY IDEOGRAPH-2F8C0;Lo;0;L;63C5;;;;N;;;;; +2F8C1;CJK COMPATIBILITY IDEOGRAPH-2F8C1;Lo;0;L;63A9;;;;N;;;;; +2F8C2;CJK COMPATIBILITY IDEOGRAPH-2F8C2;Lo;0;L;3A2E;;;;N;;;;; +2F8C3;CJK COMPATIBILITY IDEOGRAPH-2F8C3;Lo;0;L;6469;;;;N;;;;; +2F8C4;CJK COMPATIBILITY IDEOGRAPH-2F8C4;Lo;0;L;647E;;;;N;;;;; +2F8C5;CJK COMPATIBILITY IDEOGRAPH-2F8C5;Lo;0;L;649D;;;;N;;;;; +2F8C6;CJK COMPATIBILITY IDEOGRAPH-2F8C6;Lo;0;L;6477;;;;N;;;;; +2F8C7;CJK COMPATIBILITY IDEOGRAPH-2F8C7;Lo;0;L;3A6C;;;;N;;;;; +2F8C8;CJK COMPATIBILITY IDEOGRAPH-2F8C8;Lo;0;L;654F;;;;N;;;;; +2F8C9;CJK COMPATIBILITY IDEOGRAPH-2F8C9;Lo;0;L;656C;;;;N;;;;; +2F8CA;CJK COMPATIBILITY IDEOGRAPH-2F8CA;Lo;0;L;2300A;;;;N;;;;; +2F8CB;CJK COMPATIBILITY IDEOGRAPH-2F8CB;Lo;0;L;65E3;;;;N;;;;; +2F8CC;CJK COMPATIBILITY IDEOGRAPH-2F8CC;Lo;0;L;66F8;;;;N;;;;; +2F8CD;CJK COMPATIBILITY IDEOGRAPH-2F8CD;Lo;0;L;6649;;;;N;;;;; +2F8CE;CJK COMPATIBILITY IDEOGRAPH-2F8CE;Lo;0;L;3B19;;;;N;;;;; +2F8CF;CJK COMPATIBILITY IDEOGRAPH-2F8CF;Lo;0;L;6691;;;;N;;;;; +2F8D0;CJK COMPATIBILITY IDEOGRAPH-2F8D0;Lo;0;L;3B08;;;;N;;;;; +2F8D1;CJK COMPATIBILITY IDEOGRAPH-2F8D1;Lo;0;L;3AE4;;;;N;;;;; +2F8D2;CJK COMPATIBILITY IDEOGRAPH-2F8D2;Lo;0;L;5192;;;;N;;;;; +2F8D3;CJK COMPATIBILITY IDEOGRAPH-2F8D3;Lo;0;L;5195;;;;N;;;;; +2F8D4;CJK COMPATIBILITY IDEOGRAPH-2F8D4;Lo;0;L;6700;;;;N;;;;; +2F8D5;CJK COMPATIBILITY IDEOGRAPH-2F8D5;Lo;0;L;669C;;;;N;;;;; +2F8D6;CJK COMPATIBILITY IDEOGRAPH-2F8D6;Lo;0;L;80AD;;;;N;;;;; +2F8D7;CJK COMPATIBILITY IDEOGRAPH-2F8D7;Lo;0;L;43D9;;;;N;;;;; +2F8D8;CJK COMPATIBILITY IDEOGRAPH-2F8D8;Lo;0;L;6717;;;;N;;;;; +2F8D9;CJK COMPATIBILITY IDEOGRAPH-2F8D9;Lo;0;L;671B;;;;N;;;;; +2F8DA;CJK COMPATIBILITY IDEOGRAPH-2F8DA;Lo;0;L;6721;;;;N;;;;; +2F8DB;CJK COMPATIBILITY IDEOGRAPH-2F8DB;Lo;0;L;675E;;;;N;;;;; +2F8DC;CJK COMPATIBILITY IDEOGRAPH-2F8DC;Lo;0;L;6753;;;;N;;;;; +2F8DD;CJK COMPATIBILITY IDEOGRAPH-2F8DD;Lo;0;L;233C3;;;;N;;;;; +2F8DE;CJK COMPATIBILITY IDEOGRAPH-2F8DE;Lo;0;L;3B49;;;;N;;;;; +2F8DF;CJK COMPATIBILITY IDEOGRAPH-2F8DF;Lo;0;L;67FA;;;;N;;;;; +2F8E0;CJK COMPATIBILITY IDEOGRAPH-2F8E0;Lo;0;L;6785;;;;N;;;;; +2F8E1;CJK COMPATIBILITY IDEOGRAPH-2F8E1;Lo;0;L;6852;;;;N;;;;; +2F8E2;CJK COMPATIBILITY IDEOGRAPH-2F8E2;Lo;0;L;6885;;;;N;;;;; +2F8E3;CJK COMPATIBILITY IDEOGRAPH-2F8E3;Lo;0;L;2346D;;;;N;;;;; +2F8E4;CJK COMPATIBILITY IDEOGRAPH-2F8E4;Lo;0;L;688E;;;;N;;;;; +2F8E5;CJK COMPATIBILITY IDEOGRAPH-2F8E5;Lo;0;L;681F;;;;N;;;;; +2F8E6;CJK COMPATIBILITY IDEOGRAPH-2F8E6;Lo;0;L;6914;;;;N;;;;; +2F8E7;CJK COMPATIBILITY IDEOGRAPH-2F8E7;Lo;0;L;3B9D;;;;N;;;;; +2F8E8;CJK COMPATIBILITY IDEOGRAPH-2F8E8;Lo;0;L;6942;;;;N;;;;; +2F8E9;CJK COMPATIBILITY IDEOGRAPH-2F8E9;Lo;0;L;69A3;;;;N;;;;; +2F8EA;CJK COMPATIBILITY IDEOGRAPH-2F8EA;Lo;0;L;69EA;;;;N;;;;; +2F8EB;CJK COMPATIBILITY IDEOGRAPH-2F8EB;Lo;0;L;6AA8;;;;N;;;;; +2F8EC;CJK COMPATIBILITY IDEOGRAPH-2F8EC;Lo;0;L;236A3;;;;N;;;;; +2F8ED;CJK COMPATIBILITY IDEOGRAPH-2F8ED;Lo;0;L;6ADB;;;;N;;;;; +2F8EE;CJK COMPATIBILITY IDEOGRAPH-2F8EE;Lo;0;L;3C18;;;;N;;;;; +2F8EF;CJK COMPATIBILITY IDEOGRAPH-2F8EF;Lo;0;L;6B21;;;;N;;;;; +2F8F0;CJK COMPATIBILITY IDEOGRAPH-2F8F0;Lo;0;L;238A7;;;;N;;;;; +2F8F1;CJK COMPATIBILITY IDEOGRAPH-2F8F1;Lo;0;L;6B54;;;;N;;;;; +2F8F2;CJK COMPATIBILITY IDEOGRAPH-2F8F2;Lo;0;L;3C4E;;;;N;;;;; +2F8F3;CJK COMPATIBILITY IDEOGRAPH-2F8F3;Lo;0;L;6B72;;;;N;;;;; +2F8F4;CJK COMPATIBILITY IDEOGRAPH-2F8F4;Lo;0;L;6B9F;;;;N;;;;; +2F8F5;CJK COMPATIBILITY IDEOGRAPH-2F8F5;Lo;0;L;6BBA;;;;N;;;;; +2F8F6;CJK COMPATIBILITY IDEOGRAPH-2F8F6;Lo;0;L;6BBB;;;;N;;;;; +2F8F7;CJK COMPATIBILITY IDEOGRAPH-2F8F7;Lo;0;L;23A8D;;;;N;;;;; +2F8F8;CJK COMPATIBILITY IDEOGRAPH-2F8F8;Lo;0;L;21D0B;;;;N;;;;; +2F8F9;CJK COMPATIBILITY IDEOGRAPH-2F8F9;Lo;0;L;23AFA;;;;N;;;;; +2F8FA;CJK COMPATIBILITY IDEOGRAPH-2F8FA;Lo;0;L;6C4E;;;;N;;;;; +2F8FB;CJK COMPATIBILITY IDEOGRAPH-2F8FB;Lo;0;L;23CBC;;;;N;;;;; +2F8FC;CJK COMPATIBILITY IDEOGRAPH-2F8FC;Lo;0;L;6CBF;;;;N;;;;; +2F8FD;CJK COMPATIBILITY IDEOGRAPH-2F8FD;Lo;0;L;6CCD;;;;N;;;;; +2F8FE;CJK COMPATIBILITY IDEOGRAPH-2F8FE;Lo;0;L;6C67;;;;N;;;;; +2F8FF;CJK COMPATIBILITY IDEOGRAPH-2F8FF;Lo;0;L;6D16;;;;N;;;;; +2F900;CJK COMPATIBILITY IDEOGRAPH-2F900;Lo;0;L;6D3E;;;;N;;;;; +2F901;CJK COMPATIBILITY IDEOGRAPH-2F901;Lo;0;L;6D77;;;;N;;;;; +2F902;CJK COMPATIBILITY IDEOGRAPH-2F902;Lo;0;L;6D41;;;;N;;;;; +2F903;CJK COMPATIBILITY IDEOGRAPH-2F903;Lo;0;L;6D69;;;;N;;;;; +2F904;CJK COMPATIBILITY IDEOGRAPH-2F904;Lo;0;L;6D78;;;;N;;;;; +2F905;CJK COMPATIBILITY IDEOGRAPH-2F905;Lo;0;L;6D85;;;;N;;;;; +2F906;CJK COMPATIBILITY IDEOGRAPH-2F906;Lo;0;L;23D1E;;;;N;;;;; +2F907;CJK COMPATIBILITY IDEOGRAPH-2F907;Lo;0;L;6D34;;;;N;;;;; +2F908;CJK COMPATIBILITY IDEOGRAPH-2F908;Lo;0;L;6E2F;;;;N;;;;; +2F909;CJK COMPATIBILITY IDEOGRAPH-2F909;Lo;0;L;6E6E;;;;N;;;;; +2F90A;CJK COMPATIBILITY IDEOGRAPH-2F90A;Lo;0;L;3D33;;;;N;;;;; +2F90B;CJK COMPATIBILITY IDEOGRAPH-2F90B;Lo;0;L;6ECB;;;;N;;;;; +2F90C;CJK COMPATIBILITY IDEOGRAPH-2F90C;Lo;0;L;6EC7;;;;N;;;;; +2F90D;CJK COMPATIBILITY IDEOGRAPH-2F90D;Lo;0;L;23ED1;;;;N;;;;; +2F90E;CJK COMPATIBILITY IDEOGRAPH-2F90E;Lo;0;L;6DF9;;;;N;;;;; +2F90F;CJK COMPATIBILITY IDEOGRAPH-2F90F;Lo;0;L;6F6E;;;;N;;;;; +2F910;CJK COMPATIBILITY IDEOGRAPH-2F910;Lo;0;L;23F5E;;;;N;;;;; +2F911;CJK COMPATIBILITY IDEOGRAPH-2F911;Lo;0;L;23F8E;;;;N;;;;; +2F912;CJK COMPATIBILITY IDEOGRAPH-2F912;Lo;0;L;6FC6;;;;N;;;;; +2F913;CJK COMPATIBILITY IDEOGRAPH-2F913;Lo;0;L;7039;;;;N;;;;; +2F914;CJK COMPATIBILITY IDEOGRAPH-2F914;Lo;0;L;701E;;;;N;;;;; +2F915;CJK COMPATIBILITY IDEOGRAPH-2F915;Lo;0;L;701B;;;;N;;;;; +2F916;CJK COMPATIBILITY IDEOGRAPH-2F916;Lo;0;L;3D96;;;;N;;;;; +2F917;CJK COMPATIBILITY IDEOGRAPH-2F917;Lo;0;L;704A;;;;N;;;;; +2F918;CJK COMPATIBILITY IDEOGRAPH-2F918;Lo;0;L;707D;;;;N;;;;; +2F919;CJK COMPATIBILITY IDEOGRAPH-2F919;Lo;0;L;7077;;;;N;;;;; +2F91A;CJK COMPATIBILITY IDEOGRAPH-2F91A;Lo;0;L;70AD;;;;N;;;;; +2F91B;CJK COMPATIBILITY IDEOGRAPH-2F91B;Lo;0;L;20525;;;;N;;;;; +2F91C;CJK COMPATIBILITY IDEOGRAPH-2F91C;Lo;0;L;7145;;;;N;;;;; +2F91D;CJK COMPATIBILITY IDEOGRAPH-2F91D;Lo;0;L;24263;;;;N;;;;; +2F91E;CJK COMPATIBILITY IDEOGRAPH-2F91E;Lo;0;L;719C;;;;N;;;;; +2F91F;CJK COMPATIBILITY IDEOGRAPH-2F91F;Lo;0;L;243AB;;;;N;;;;; +2F920;CJK COMPATIBILITY IDEOGRAPH-2F920;Lo;0;L;7228;;;;N;;;;; +2F921;CJK COMPATIBILITY IDEOGRAPH-2F921;Lo;0;L;7235;;;;N;;;;; +2F922;CJK COMPATIBILITY IDEOGRAPH-2F922;Lo;0;L;7250;;;;N;;;;; +2F923;CJK COMPATIBILITY IDEOGRAPH-2F923;Lo;0;L;24608;;;;N;;;;; +2F924;CJK COMPATIBILITY IDEOGRAPH-2F924;Lo;0;L;7280;;;;N;;;;; +2F925;CJK COMPATIBILITY IDEOGRAPH-2F925;Lo;0;L;7295;;;;N;;;;; +2F926;CJK COMPATIBILITY IDEOGRAPH-2F926;Lo;0;L;24735;;;;N;;;;; +2F927;CJK COMPATIBILITY IDEOGRAPH-2F927;Lo;0;L;24814;;;;N;;;;; +2F928;CJK COMPATIBILITY IDEOGRAPH-2F928;Lo;0;L;737A;;;;N;;;;; +2F929;CJK COMPATIBILITY IDEOGRAPH-2F929;Lo;0;L;738B;;;;N;;;;; +2F92A;CJK COMPATIBILITY IDEOGRAPH-2F92A;Lo;0;L;3EAC;;;;N;;;;; +2F92B;CJK COMPATIBILITY IDEOGRAPH-2F92B;Lo;0;L;73A5;;;;N;;;;; +2F92C;CJK COMPATIBILITY IDEOGRAPH-2F92C;Lo;0;L;3EB8;;;;N;;;;; +2F92D;CJK COMPATIBILITY IDEOGRAPH-2F92D;Lo;0;L;3EB8;;;;N;;;;; +2F92E;CJK COMPATIBILITY IDEOGRAPH-2F92E;Lo;0;L;7447;;;;N;;;;; +2F92F;CJK COMPATIBILITY IDEOGRAPH-2F92F;Lo;0;L;745C;;;;N;;;;; +2F930;CJK COMPATIBILITY IDEOGRAPH-2F930;Lo;0;L;7471;;;;N;;;;; +2F931;CJK COMPATIBILITY IDEOGRAPH-2F931;Lo;0;L;7485;;;;N;;;;; +2F932;CJK COMPATIBILITY IDEOGRAPH-2F932;Lo;0;L;74CA;;;;N;;;;; +2F933;CJK COMPATIBILITY IDEOGRAPH-2F933;Lo;0;L;3F1B;;;;N;;;;; +2F934;CJK COMPATIBILITY IDEOGRAPH-2F934;Lo;0;L;7524;;;;N;;;;; +2F935;CJK COMPATIBILITY IDEOGRAPH-2F935;Lo;0;L;24C36;;;;N;;;;; +2F936;CJK COMPATIBILITY IDEOGRAPH-2F936;Lo;0;L;753E;;;;N;;;;; +2F937;CJK COMPATIBILITY IDEOGRAPH-2F937;Lo;0;L;24C92;;;;N;;;;; +2F938;CJK COMPATIBILITY IDEOGRAPH-2F938;Lo;0;L;7570;;;;N;;;;; +2F939;CJK COMPATIBILITY IDEOGRAPH-2F939;Lo;0;L;2219F;;;;N;;;;; +2F93A;CJK COMPATIBILITY IDEOGRAPH-2F93A;Lo;0;L;7610;;;;N;;;;; +2F93B;CJK COMPATIBILITY IDEOGRAPH-2F93B;Lo;0;L;24FA1;;;;N;;;;; +2F93C;CJK COMPATIBILITY IDEOGRAPH-2F93C;Lo;0;L;24FB8;;;;N;;;;; +2F93D;CJK COMPATIBILITY IDEOGRAPH-2F93D;Lo;0;L;25044;;;;N;;;;; +2F93E;CJK COMPATIBILITY IDEOGRAPH-2F93E;Lo;0;L;3FFC;;;;N;;;;; +2F93F;CJK COMPATIBILITY IDEOGRAPH-2F93F;Lo;0;L;4008;;;;N;;;;; +2F940;CJK COMPATIBILITY IDEOGRAPH-2F940;Lo;0;L;76F4;;;;N;;;;; +2F941;CJK COMPATIBILITY IDEOGRAPH-2F941;Lo;0;L;250F3;;;;N;;;;; +2F942;CJK COMPATIBILITY IDEOGRAPH-2F942;Lo;0;L;250F2;;;;N;;;;; +2F943;CJK COMPATIBILITY IDEOGRAPH-2F943;Lo;0;L;25119;;;;N;;;;; +2F944;CJK COMPATIBILITY IDEOGRAPH-2F944;Lo;0;L;25133;;;;N;;;;; +2F945;CJK COMPATIBILITY IDEOGRAPH-2F945;Lo;0;L;771E;;;;N;;;;; +2F946;CJK COMPATIBILITY IDEOGRAPH-2F946;Lo;0;L;771F;;;;N;;;;; +2F947;CJK COMPATIBILITY IDEOGRAPH-2F947;Lo;0;L;771F;;;;N;;;;; +2F948;CJK COMPATIBILITY IDEOGRAPH-2F948;Lo;0;L;774A;;;;N;;;;; +2F949;CJK COMPATIBILITY IDEOGRAPH-2F949;Lo;0;L;4039;;;;N;;;;; +2F94A;CJK COMPATIBILITY IDEOGRAPH-2F94A;Lo;0;L;778B;;;;N;;;;; +2F94B;CJK COMPATIBILITY IDEOGRAPH-2F94B;Lo;0;L;4046;;;;N;;;;; +2F94C;CJK COMPATIBILITY IDEOGRAPH-2F94C;Lo;0;L;4096;;;;N;;;;; +2F94D;CJK COMPATIBILITY IDEOGRAPH-2F94D;Lo;0;L;2541D;;;;N;;;;; +2F94E;CJK COMPATIBILITY IDEOGRAPH-2F94E;Lo;0;L;784E;;;;N;;;;; +2F94F;CJK COMPATIBILITY IDEOGRAPH-2F94F;Lo;0;L;788C;;;;N;;;;; +2F950;CJK COMPATIBILITY IDEOGRAPH-2F950;Lo;0;L;78CC;;;;N;;;;; +2F951;CJK COMPATIBILITY IDEOGRAPH-2F951;Lo;0;L;40E3;;;;N;;;;; +2F952;CJK COMPATIBILITY IDEOGRAPH-2F952;Lo;0;L;25626;;;;N;;;;; +2F953;CJK COMPATIBILITY IDEOGRAPH-2F953;Lo;0;L;7956;;;;N;;;;; +2F954;CJK COMPATIBILITY IDEOGRAPH-2F954;Lo;0;L;2569A;;;;N;;;;; +2F955;CJK COMPATIBILITY IDEOGRAPH-2F955;Lo;0;L;256C5;;;;N;;;;; +2F956;CJK COMPATIBILITY IDEOGRAPH-2F956;Lo;0;L;798F;;;;N;;;;; +2F957;CJK COMPATIBILITY IDEOGRAPH-2F957;Lo;0;L;79EB;;;;N;;;;; +2F958;CJK COMPATIBILITY IDEOGRAPH-2F958;Lo;0;L;412F;;;;N;;;;; +2F959;CJK COMPATIBILITY IDEOGRAPH-2F959;Lo;0;L;7A40;;;;N;;;;; +2F95A;CJK COMPATIBILITY IDEOGRAPH-2F95A;Lo;0;L;7A4A;;;;N;;;;; +2F95B;CJK COMPATIBILITY IDEOGRAPH-2F95B;Lo;0;L;7A4F;;;;N;;;;; +2F95C;CJK COMPATIBILITY IDEOGRAPH-2F95C;Lo;0;L;2597C;;;;N;;;;; +2F95D;CJK COMPATIBILITY IDEOGRAPH-2F95D;Lo;0;L;25AA7;;;;N;;;;; +2F95E;CJK COMPATIBILITY IDEOGRAPH-2F95E;Lo;0;L;25AA7;;;;N;;;;; +2F95F;CJK COMPATIBILITY IDEOGRAPH-2F95F;Lo;0;L;7AEE;;;;N;;;;; +2F960;CJK COMPATIBILITY IDEOGRAPH-2F960;Lo;0;L;4202;;;;N;;;;; +2F961;CJK COMPATIBILITY IDEOGRAPH-2F961;Lo;0;L;25BAB;;;;N;;;;; +2F962;CJK COMPATIBILITY IDEOGRAPH-2F962;Lo;0;L;7BC6;;;;N;;;;; +2F963;CJK COMPATIBILITY IDEOGRAPH-2F963;Lo;0;L;7BC9;;;;N;;;;; +2F964;CJK COMPATIBILITY IDEOGRAPH-2F964;Lo;0;L;4227;;;;N;;;;; +2F965;CJK COMPATIBILITY IDEOGRAPH-2F965;Lo;0;L;25C80;;;;N;;;;; +2F966;CJK COMPATIBILITY IDEOGRAPH-2F966;Lo;0;L;7CD2;;;;N;;;;; +2F967;CJK COMPATIBILITY IDEOGRAPH-2F967;Lo;0;L;42A0;;;;N;;;;; +2F968;CJK COMPATIBILITY IDEOGRAPH-2F968;Lo;0;L;7CE8;;;;N;;;;; +2F969;CJK COMPATIBILITY IDEOGRAPH-2F969;Lo;0;L;7CE3;;;;N;;;;; +2F96A;CJK COMPATIBILITY IDEOGRAPH-2F96A;Lo;0;L;7D00;;;;N;;;;; +2F96B;CJK COMPATIBILITY IDEOGRAPH-2F96B;Lo;0;L;25F86;;;;N;;;;; +2F96C;CJK COMPATIBILITY IDEOGRAPH-2F96C;Lo;0;L;7D63;;;;N;;;;; +2F96D;CJK COMPATIBILITY IDEOGRAPH-2F96D;Lo;0;L;4301;;;;N;;;;; +2F96E;CJK COMPATIBILITY IDEOGRAPH-2F96E;Lo;0;L;7DC7;;;;N;;;;; +2F96F;CJK COMPATIBILITY IDEOGRAPH-2F96F;Lo;0;L;7E02;;;;N;;;;; +2F970;CJK COMPATIBILITY IDEOGRAPH-2F970;Lo;0;L;7E45;;;;N;;;;; +2F971;CJK COMPATIBILITY IDEOGRAPH-2F971;Lo;0;L;4334;;;;N;;;;; +2F972;CJK COMPATIBILITY IDEOGRAPH-2F972;Lo;0;L;26228;;;;N;;;;; +2F973;CJK COMPATIBILITY IDEOGRAPH-2F973;Lo;0;L;26247;;;;N;;;;; +2F974;CJK COMPATIBILITY IDEOGRAPH-2F974;Lo;0;L;4359;;;;N;;;;; +2F975;CJK COMPATIBILITY IDEOGRAPH-2F975;Lo;0;L;262D9;;;;N;;;;; +2F976;CJK COMPATIBILITY IDEOGRAPH-2F976;Lo;0;L;7F7A;;;;N;;;;; +2F977;CJK COMPATIBILITY IDEOGRAPH-2F977;Lo;0;L;2633E;;;;N;;;;; +2F978;CJK COMPATIBILITY IDEOGRAPH-2F978;Lo;0;L;7F95;;;;N;;;;; +2F979;CJK COMPATIBILITY IDEOGRAPH-2F979;Lo;0;L;7FFA;;;;N;;;;; +2F97A;CJK COMPATIBILITY IDEOGRAPH-2F97A;Lo;0;L;8005;;;;N;;;;; +2F97B;CJK COMPATIBILITY IDEOGRAPH-2F97B;Lo;0;L;264DA;;;;N;;;;; +2F97C;CJK COMPATIBILITY IDEOGRAPH-2F97C;Lo;0;L;26523;;;;N;;;;; +2F97D;CJK COMPATIBILITY IDEOGRAPH-2F97D;Lo;0;L;8060;;;;N;;;;; +2F97E;CJK COMPATIBILITY IDEOGRAPH-2F97E;Lo;0;L;265A8;;;;N;;;;; +2F97F;CJK COMPATIBILITY IDEOGRAPH-2F97F;Lo;0;L;8070;;;;N;;;;; +2F980;CJK COMPATIBILITY IDEOGRAPH-2F980;Lo;0;L;2335F;;;;N;;;;; +2F981;CJK COMPATIBILITY IDEOGRAPH-2F981;Lo;0;L;43D5;;;;N;;;;; +2F982;CJK COMPATIBILITY IDEOGRAPH-2F982;Lo;0;L;80B2;;;;N;;;;; +2F983;CJK COMPATIBILITY IDEOGRAPH-2F983;Lo;0;L;8103;;;;N;;;;; +2F984;CJK COMPATIBILITY IDEOGRAPH-2F984;Lo;0;L;440B;;;;N;;;;; +2F985;CJK COMPATIBILITY IDEOGRAPH-2F985;Lo;0;L;813E;;;;N;;;;; +2F986;CJK COMPATIBILITY IDEOGRAPH-2F986;Lo;0;L;5AB5;;;;N;;;;; +2F987;CJK COMPATIBILITY IDEOGRAPH-2F987;Lo;0;L;267A7;;;;N;;;;; +2F988;CJK COMPATIBILITY IDEOGRAPH-2F988;Lo;0;L;267B5;;;;N;;;;; +2F989;CJK COMPATIBILITY IDEOGRAPH-2F989;Lo;0;L;23393;;;;N;;;;; +2F98A;CJK COMPATIBILITY IDEOGRAPH-2F98A;Lo;0;L;2339C;;;;N;;;;; +2F98B;CJK COMPATIBILITY IDEOGRAPH-2F98B;Lo;0;L;8201;;;;N;;;;; +2F98C;CJK COMPATIBILITY IDEOGRAPH-2F98C;Lo;0;L;8204;;;;N;;;;; +2F98D;CJK COMPATIBILITY IDEOGRAPH-2F98D;Lo;0;L;8F9E;;;;N;;;;; +2F98E;CJK COMPATIBILITY IDEOGRAPH-2F98E;Lo;0;L;446B;;;;N;;;;; +2F98F;CJK COMPATIBILITY IDEOGRAPH-2F98F;Lo;0;L;8291;;;;N;;;;; +2F990;CJK COMPATIBILITY IDEOGRAPH-2F990;Lo;0;L;828B;;;;N;;;;; +2F991;CJK COMPATIBILITY IDEOGRAPH-2F991;Lo;0;L;829D;;;;N;;;;; +2F992;CJK COMPATIBILITY IDEOGRAPH-2F992;Lo;0;L;52B3;;;;N;;;;; +2F993;CJK COMPATIBILITY IDEOGRAPH-2F993;Lo;0;L;82B1;;;;N;;;;; +2F994;CJK COMPATIBILITY IDEOGRAPH-2F994;Lo;0;L;82B3;;;;N;;;;; +2F995;CJK COMPATIBILITY IDEOGRAPH-2F995;Lo;0;L;82BD;;;;N;;;;; +2F996;CJK COMPATIBILITY IDEOGRAPH-2F996;Lo;0;L;82E6;;;;N;;;;; +2F997;CJK COMPATIBILITY IDEOGRAPH-2F997;Lo;0;L;26B3C;;;;N;;;;; +2F998;CJK COMPATIBILITY IDEOGRAPH-2F998;Lo;0;L;82E5;;;;N;;;;; +2F999;CJK COMPATIBILITY IDEOGRAPH-2F999;Lo;0;L;831D;;;;N;;;;; +2F99A;CJK COMPATIBILITY IDEOGRAPH-2F99A;Lo;0;L;8363;;;;N;;;;; +2F99B;CJK COMPATIBILITY IDEOGRAPH-2F99B;Lo;0;L;83AD;;;;N;;;;; +2F99C;CJK COMPATIBILITY IDEOGRAPH-2F99C;Lo;0;L;8323;;;;N;;;;; +2F99D;CJK COMPATIBILITY IDEOGRAPH-2F99D;Lo;0;L;83BD;;;;N;;;;; +2F99E;CJK COMPATIBILITY IDEOGRAPH-2F99E;Lo;0;L;83E7;;;;N;;;;; +2F99F;CJK COMPATIBILITY IDEOGRAPH-2F99F;Lo;0;L;8457;;;;N;;;;; +2F9A0;CJK COMPATIBILITY IDEOGRAPH-2F9A0;Lo;0;L;8353;;;;N;;;;; +2F9A1;CJK COMPATIBILITY IDEOGRAPH-2F9A1;Lo;0;L;83CA;;;;N;;;;; +2F9A2;CJK COMPATIBILITY IDEOGRAPH-2F9A2;Lo;0;L;83CC;;;;N;;;;; +2F9A3;CJK COMPATIBILITY IDEOGRAPH-2F9A3;Lo;0;L;83DC;;;;N;;;;; +2F9A4;CJK COMPATIBILITY IDEOGRAPH-2F9A4;Lo;0;L;26C36;;;;N;;;;; +2F9A5;CJK COMPATIBILITY IDEOGRAPH-2F9A5;Lo;0;L;26D6B;;;;N;;;;; +2F9A6;CJK COMPATIBILITY IDEOGRAPH-2F9A6;Lo;0;L;26CD5;;;;N;;;;; +2F9A7;CJK COMPATIBILITY IDEOGRAPH-2F9A7;Lo;0;L;452B;;;;N;;;;; +2F9A8;CJK COMPATIBILITY IDEOGRAPH-2F9A8;Lo;0;L;84F1;;;;N;;;;; +2F9A9;CJK COMPATIBILITY IDEOGRAPH-2F9A9;Lo;0;L;84F3;;;;N;;;;; +2F9AA;CJK COMPATIBILITY IDEOGRAPH-2F9AA;Lo;0;L;8516;;;;N;;;;; +2F9AB;CJK COMPATIBILITY IDEOGRAPH-2F9AB;Lo;0;L;273CA;;;;N;;;;; +2F9AC;CJK COMPATIBILITY IDEOGRAPH-2F9AC;Lo;0;L;8564;;;;N;;;;; +2F9AD;CJK COMPATIBILITY IDEOGRAPH-2F9AD;Lo;0;L;26F2C;;;;N;;;;; +2F9AE;CJK COMPATIBILITY IDEOGRAPH-2F9AE;Lo;0;L;455D;;;;N;;;;; +2F9AF;CJK COMPATIBILITY IDEOGRAPH-2F9AF;Lo;0;L;4561;;;;N;;;;; +2F9B0;CJK COMPATIBILITY IDEOGRAPH-2F9B0;Lo;0;L;26FB1;;;;N;;;;; +2F9B1;CJK COMPATIBILITY IDEOGRAPH-2F9B1;Lo;0;L;270D2;;;;N;;;;; +2F9B2;CJK COMPATIBILITY IDEOGRAPH-2F9B2;Lo;0;L;456B;;;;N;;;;; +2F9B3;CJK COMPATIBILITY IDEOGRAPH-2F9B3;Lo;0;L;8650;;;;N;;;;; +2F9B4;CJK COMPATIBILITY IDEOGRAPH-2F9B4;Lo;0;L;865C;;;;N;;;;; +2F9B5;CJK COMPATIBILITY IDEOGRAPH-2F9B5;Lo;0;L;8667;;;;N;;;;; +2F9B6;CJK COMPATIBILITY IDEOGRAPH-2F9B6;Lo;0;L;8669;;;;N;;;;; +2F9B7;CJK COMPATIBILITY IDEOGRAPH-2F9B7;Lo;0;L;86A9;;;;N;;;;; +2F9B8;CJK COMPATIBILITY IDEOGRAPH-2F9B8;Lo;0;L;8688;;;;N;;;;; +2F9B9;CJK COMPATIBILITY IDEOGRAPH-2F9B9;Lo;0;L;870E;;;;N;;;;; +2F9BA;CJK COMPATIBILITY IDEOGRAPH-2F9BA;Lo;0;L;86E2;;;;N;;;;; +2F9BB;CJK COMPATIBILITY IDEOGRAPH-2F9BB;Lo;0;L;8779;;;;N;;;;; +2F9BC;CJK COMPATIBILITY IDEOGRAPH-2F9BC;Lo;0;L;8728;;;;N;;;;; +2F9BD;CJK COMPATIBILITY IDEOGRAPH-2F9BD;Lo;0;L;876B;;;;N;;;;; +2F9BE;CJK COMPATIBILITY IDEOGRAPH-2F9BE;Lo;0;L;8786;;;;N;;;;; +2F9BF;CJK COMPATIBILITY IDEOGRAPH-2F9BF;Lo;0;L;45D7;;;;N;;;;; +2F9C0;CJK COMPATIBILITY IDEOGRAPH-2F9C0;Lo;0;L;87E1;;;;N;;;;; +2F9C1;CJK COMPATIBILITY IDEOGRAPH-2F9C1;Lo;0;L;8801;;;;N;;;;; +2F9C2;CJK COMPATIBILITY IDEOGRAPH-2F9C2;Lo;0;L;45F9;;;;N;;;;; +2F9C3;CJK COMPATIBILITY IDEOGRAPH-2F9C3;Lo;0;L;8860;;;;N;;;;; +2F9C4;CJK COMPATIBILITY IDEOGRAPH-2F9C4;Lo;0;L;8863;;;;N;;;;; +2F9C5;CJK COMPATIBILITY IDEOGRAPH-2F9C5;Lo;0;L;27667;;;;N;;;;; +2F9C6;CJK COMPATIBILITY IDEOGRAPH-2F9C6;Lo;0;L;88D7;;;;N;;;;; +2F9C7;CJK COMPATIBILITY IDEOGRAPH-2F9C7;Lo;0;L;88DE;;;;N;;;;; +2F9C8;CJK COMPATIBILITY IDEOGRAPH-2F9C8;Lo;0;L;4635;;;;N;;;;; +2F9C9;CJK COMPATIBILITY IDEOGRAPH-2F9C9;Lo;0;L;88FA;;;;N;;;;; +2F9CA;CJK COMPATIBILITY IDEOGRAPH-2F9CA;Lo;0;L;34BB;;;;N;;;;; +2F9CB;CJK COMPATIBILITY IDEOGRAPH-2F9CB;Lo;0;L;278AE;;;;N;;;;; +2F9CC;CJK COMPATIBILITY IDEOGRAPH-2F9CC;Lo;0;L;27966;;;;N;;;;; +2F9CD;CJK COMPATIBILITY IDEOGRAPH-2F9CD;Lo;0;L;46BE;;;;N;;;;; +2F9CE;CJK COMPATIBILITY IDEOGRAPH-2F9CE;Lo;0;L;46C7;;;;N;;;;; +2F9CF;CJK COMPATIBILITY IDEOGRAPH-2F9CF;Lo;0;L;8AA0;;;;N;;;;; +2F9D0;CJK COMPATIBILITY IDEOGRAPH-2F9D0;Lo;0;L;8AED;;;;N;;;;; +2F9D1;CJK COMPATIBILITY IDEOGRAPH-2F9D1;Lo;0;L;8B8A;;;;N;;;;; +2F9D2;CJK COMPATIBILITY IDEOGRAPH-2F9D2;Lo;0;L;8C55;;;;N;;;;; +2F9D3;CJK COMPATIBILITY IDEOGRAPH-2F9D3;Lo;0;L;27CA8;;;;N;;;;; +2F9D4;CJK COMPATIBILITY IDEOGRAPH-2F9D4;Lo;0;L;8CAB;;;;N;;;;; +2F9D5;CJK COMPATIBILITY IDEOGRAPH-2F9D5;Lo;0;L;8CC1;;;;N;;;;; +2F9D6;CJK COMPATIBILITY IDEOGRAPH-2F9D6;Lo;0;L;8D1B;;;;N;;;;; +2F9D7;CJK COMPATIBILITY IDEOGRAPH-2F9D7;Lo;0;L;8D77;;;;N;;;;; +2F9D8;CJK COMPATIBILITY IDEOGRAPH-2F9D8;Lo;0;L;27F2F;;;;N;;;;; +2F9D9;CJK COMPATIBILITY IDEOGRAPH-2F9D9;Lo;0;L;20804;;;;N;;;;; +2F9DA;CJK COMPATIBILITY IDEOGRAPH-2F9DA;Lo;0;L;8DCB;;;;N;;;;; +2F9DB;CJK COMPATIBILITY IDEOGRAPH-2F9DB;Lo;0;L;8DBC;;;;N;;;;; +2F9DC;CJK COMPATIBILITY IDEOGRAPH-2F9DC;Lo;0;L;8DF0;;;;N;;;;; +2F9DD;CJK COMPATIBILITY IDEOGRAPH-2F9DD;Lo;0;L;208DE;;;;N;;;;; +2F9DE;CJK COMPATIBILITY IDEOGRAPH-2F9DE;Lo;0;L;8ED4;;;;N;;;;; +2F9DF;CJK COMPATIBILITY IDEOGRAPH-2F9DF;Lo;0;L;8F38;;;;N;;;;; +2F9E0;CJK COMPATIBILITY IDEOGRAPH-2F9E0;Lo;0;L;285D2;;;;N;;;;; +2F9E1;CJK COMPATIBILITY IDEOGRAPH-2F9E1;Lo;0;L;285ED;;;;N;;;;; +2F9E2;CJK COMPATIBILITY IDEOGRAPH-2F9E2;Lo;0;L;9094;;;;N;;;;; +2F9E3;CJK COMPATIBILITY IDEOGRAPH-2F9E3;Lo;0;L;90F1;;;;N;;;;; +2F9E4;CJK COMPATIBILITY IDEOGRAPH-2F9E4;Lo;0;L;9111;;;;N;;;;; +2F9E5;CJK COMPATIBILITY IDEOGRAPH-2F9E5;Lo;0;L;2872E;;;;N;;;;; +2F9E6;CJK COMPATIBILITY IDEOGRAPH-2F9E6;Lo;0;L;911B;;;;N;;;;; +2F9E7;CJK COMPATIBILITY IDEOGRAPH-2F9E7;Lo;0;L;9238;;;;N;;;;; +2F9E8;CJK COMPATIBILITY IDEOGRAPH-2F9E8;Lo;0;L;92D7;;;;N;;;;; +2F9E9;CJK COMPATIBILITY IDEOGRAPH-2F9E9;Lo;0;L;92D8;;;;N;;;;; +2F9EA;CJK COMPATIBILITY IDEOGRAPH-2F9EA;Lo;0;L;927C;;;;N;;;;; +2F9EB;CJK COMPATIBILITY IDEOGRAPH-2F9EB;Lo;0;L;93F9;;;;N;;;;; +2F9EC;CJK COMPATIBILITY IDEOGRAPH-2F9EC;Lo;0;L;9415;;;;N;;;;; +2F9ED;CJK COMPATIBILITY IDEOGRAPH-2F9ED;Lo;0;L;28BFA;;;;N;;;;; +2F9EE;CJK COMPATIBILITY IDEOGRAPH-2F9EE;Lo;0;L;958B;;;;N;;;;; +2F9EF;CJK COMPATIBILITY IDEOGRAPH-2F9EF;Lo;0;L;4995;;;;N;;;;; +2F9F0;CJK COMPATIBILITY IDEOGRAPH-2F9F0;Lo;0;L;95B7;;;;N;;;;; +2F9F1;CJK COMPATIBILITY IDEOGRAPH-2F9F1;Lo;0;L;28D77;;;;N;;;;; +2F9F2;CJK COMPATIBILITY IDEOGRAPH-2F9F2;Lo;0;L;49E6;;;;N;;;;; +2F9F3;CJK COMPATIBILITY IDEOGRAPH-2F9F3;Lo;0;L;96C3;;;;N;;;;; +2F9F4;CJK COMPATIBILITY IDEOGRAPH-2F9F4;Lo;0;L;5DB2;;;;N;;;;; +2F9F5;CJK COMPATIBILITY IDEOGRAPH-2F9F5;Lo;0;L;9723;;;;N;;;;; +2F9F6;CJK COMPATIBILITY IDEOGRAPH-2F9F6;Lo;0;L;29145;;;;N;;;;; +2F9F7;CJK COMPATIBILITY IDEOGRAPH-2F9F7;Lo;0;L;2921A;;;;N;;;;; +2F9F8;CJK COMPATIBILITY IDEOGRAPH-2F9F8;Lo;0;L;4A6E;;;;N;;;;; +2F9F9;CJK COMPATIBILITY IDEOGRAPH-2F9F9;Lo;0;L;4A76;;;;N;;;;; +2F9FA;CJK COMPATIBILITY IDEOGRAPH-2F9FA;Lo;0;L;97E0;;;;N;;;;; +2F9FB;CJK COMPATIBILITY IDEOGRAPH-2F9FB;Lo;0;L;2940A;;;;N;;;;; +2F9FC;CJK COMPATIBILITY IDEOGRAPH-2F9FC;Lo;0;L;4AB2;;;;N;;;;; +2F9FD;CJK COMPATIBILITY IDEOGRAPH-2F9FD;Lo;0;L;29496;;;;N;;;;; +2F9FE;CJK COMPATIBILITY IDEOGRAPH-2F9FE;Lo;0;L;980B;;;;N;;;;; +2F9FF;CJK COMPATIBILITY IDEOGRAPH-2F9FF;Lo;0;L;980B;;;;N;;;;; +2FA00;CJK COMPATIBILITY IDEOGRAPH-2FA00;Lo;0;L;9829;;;;N;;;;; +2FA01;CJK COMPATIBILITY IDEOGRAPH-2FA01;Lo;0;L;295B6;;;;N;;;;; +2FA02;CJK COMPATIBILITY IDEOGRAPH-2FA02;Lo;0;L;98E2;;;;N;;;;; +2FA03;CJK COMPATIBILITY IDEOGRAPH-2FA03;Lo;0;L;4B33;;;;N;;;;; +2FA04;CJK COMPATIBILITY IDEOGRAPH-2FA04;Lo;0;L;9929;;;;N;;;;; +2FA05;CJK COMPATIBILITY IDEOGRAPH-2FA05;Lo;0;L;99A7;;;;N;;;;; +2FA06;CJK COMPATIBILITY IDEOGRAPH-2FA06;Lo;0;L;99C2;;;;N;;;;; +2FA07;CJK COMPATIBILITY IDEOGRAPH-2FA07;Lo;0;L;99FE;;;;N;;;;; +2FA08;CJK COMPATIBILITY IDEOGRAPH-2FA08;Lo;0;L;4BCE;;;;N;;;;; +2FA09;CJK COMPATIBILITY IDEOGRAPH-2FA09;Lo;0;L;29B30;;;;N;;;;; +2FA0A;CJK COMPATIBILITY IDEOGRAPH-2FA0A;Lo;0;L;9B12;;;;N;;;;; +2FA0B;CJK COMPATIBILITY IDEOGRAPH-2FA0B;Lo;0;L;9C40;;;;N;;;;; +2FA0C;CJK COMPATIBILITY IDEOGRAPH-2FA0C;Lo;0;L;9CFD;;;;N;;;;; +2FA0D;CJK COMPATIBILITY IDEOGRAPH-2FA0D;Lo;0;L;4CCE;;;;N;;;;; +2FA0E;CJK COMPATIBILITY IDEOGRAPH-2FA0E;Lo;0;L;4CED;;;;N;;;;; +2FA0F;CJK COMPATIBILITY IDEOGRAPH-2FA0F;Lo;0;L;9D67;;;;N;;;;; +2FA10;CJK COMPATIBILITY IDEOGRAPH-2FA10;Lo;0;L;2A0CE;;;;N;;;;; +2FA11;CJK COMPATIBILITY IDEOGRAPH-2FA11;Lo;0;L;4CF8;;;;N;;;;; +2FA12;CJK COMPATIBILITY IDEOGRAPH-2FA12;Lo;0;L;2A105;;;;N;;;;; +2FA13;CJK COMPATIBILITY IDEOGRAPH-2FA13;Lo;0;L;2A20E;;;;N;;;;; +2FA14;CJK COMPATIBILITY IDEOGRAPH-2FA14;Lo;0;L;2A291;;;;N;;;;; +2FA15;CJK COMPATIBILITY IDEOGRAPH-2FA15;Lo;0;L;9EBB;;;;N;;;;; +2FA16;CJK COMPATIBILITY IDEOGRAPH-2FA16;Lo;0;L;4D56;;;;N;;;;; +2FA17;CJK COMPATIBILITY IDEOGRAPH-2FA17;Lo;0;L;9EF9;;;;N;;;;; +2FA18;CJK COMPATIBILITY IDEOGRAPH-2FA18;Lo;0;L;9EFE;;;;N;;;;; +2FA19;CJK COMPATIBILITY IDEOGRAPH-2FA19;Lo;0;L;9F05;;;;N;;;;; +2FA1A;CJK COMPATIBILITY IDEOGRAPH-2FA1A;Lo;0;L;9F0F;;;;N;;;;; +2FA1B;CJK COMPATIBILITY IDEOGRAPH-2FA1B;Lo;0;L;9F16;;;;N;;;;; +2FA1C;CJK COMPATIBILITY IDEOGRAPH-2FA1C;Lo;0;L;9F3B;;;;N;;;;; +2FA1D;CJK COMPATIBILITY IDEOGRAPH-2FA1D;Lo;0;L;2A600;;;;N;;;;; +E0001;LANGUAGE TAG;Cf;0;BN;;;;;N;;;;; +E0020;TAG SPACE;Cf;0;BN;;;;;N;;;;; +E0021;TAG EXCLAMATION MARK;Cf;0;BN;;;;;N;;;;; +E0022;TAG QUOTATION MARK;Cf;0;BN;;;;;N;;;;; +E0023;TAG NUMBER SIGN;Cf;0;BN;;;;;N;;;;; +E0024;TAG DOLLAR SIGN;Cf;0;BN;;;;;N;;;;; +E0025;TAG PERCENT SIGN;Cf;0;BN;;;;;N;;;;; +E0026;TAG AMPERSAND;Cf;0;BN;;;;;N;;;;; +E0027;TAG APOSTROPHE;Cf;0;BN;;;;;N;;;;; +E0028;TAG LEFT PARENTHESIS;Cf;0;BN;;;;;N;;;;; +E0029;TAG RIGHT PARENTHESIS;Cf;0;BN;;;;;N;;;;; +E002A;TAG ASTERISK;Cf;0;BN;;;;;N;;;;; +E002B;TAG PLUS SIGN;Cf;0;BN;;;;;N;;;;; +E002C;TAG COMMA;Cf;0;BN;;;;;N;;;;; +E002D;TAG HYPHEN-MINUS;Cf;0;BN;;;;;N;;;;; +E002E;TAG FULL STOP;Cf;0;BN;;;;;N;;;;; +E002F;TAG SOLIDUS;Cf;0;BN;;;;;N;;;;; +E0030;TAG DIGIT ZERO;Cf;0;BN;;;;;N;;;;; +E0031;TAG DIGIT ONE;Cf;0;BN;;;;;N;;;;; +E0032;TAG DIGIT TWO;Cf;0;BN;;;;;N;;;;; +E0033;TAG DIGIT THREE;Cf;0;BN;;;;;N;;;;; +E0034;TAG DIGIT FOUR;Cf;0;BN;;;;;N;;;;; +E0035;TAG DIGIT FIVE;Cf;0;BN;;;;;N;;;;; +E0036;TAG DIGIT SIX;Cf;0;BN;;;;;N;;;;; +E0037;TAG DIGIT SEVEN;Cf;0;BN;;;;;N;;;;; +E0038;TAG DIGIT EIGHT;Cf;0;BN;;;;;N;;;;; +E0039;TAG DIGIT NINE;Cf;0;BN;;;;;N;;;;; +E003A;TAG COLON;Cf;0;BN;;;;;N;;;;; +E003B;TAG SEMICOLON;Cf;0;BN;;;;;N;;;;; +E003C;TAG LESS-THAN SIGN;Cf;0;BN;;;;;N;;;;; +E003D;TAG EQUALS SIGN;Cf;0;BN;;;;;N;;;;; +E003E;TAG GREATER-THAN SIGN;Cf;0;BN;;;;;N;;;;; +E003F;TAG QUESTION MARK;Cf;0;BN;;;;;N;;;;; +E0040;TAG COMMERCIAL AT;Cf;0;BN;;;;;N;;;;; +E0041;TAG LATIN CAPITAL LETTER A;Cf;0;BN;;;;;N;;;;; +E0042;TAG LATIN CAPITAL LETTER B;Cf;0;BN;;;;;N;;;;; +E0043;TAG LATIN CAPITAL LETTER C;Cf;0;BN;;;;;N;;;;; +E0044;TAG LATIN CAPITAL LETTER D;Cf;0;BN;;;;;N;;;;; +E0045;TAG LATIN CAPITAL LETTER E;Cf;0;BN;;;;;N;;;;; +E0046;TAG LATIN CAPITAL LETTER F;Cf;0;BN;;;;;N;;;;; +E0047;TAG LATIN CAPITAL LETTER G;Cf;0;BN;;;;;N;;;;; +E0048;TAG LATIN CAPITAL LETTER H;Cf;0;BN;;;;;N;;;;; +E0049;TAG LATIN CAPITAL LETTER I;Cf;0;BN;;;;;N;;;;; +E004A;TAG LATIN CAPITAL LETTER J;Cf;0;BN;;;;;N;;;;; +E004B;TAG LATIN CAPITAL LETTER K;Cf;0;BN;;;;;N;;;;; +E004C;TAG LATIN CAPITAL LETTER L;Cf;0;BN;;;;;N;;;;; +E004D;TAG LATIN CAPITAL LETTER M;Cf;0;BN;;;;;N;;;;; +E004E;TAG LATIN CAPITAL LETTER N;Cf;0;BN;;;;;N;;;;; +E004F;TAG LATIN CAPITAL LETTER O;Cf;0;BN;;;;;N;;;;; +E0050;TAG LATIN CAPITAL LETTER P;Cf;0;BN;;;;;N;;;;; +E0051;TAG LATIN CAPITAL LETTER Q;Cf;0;BN;;;;;N;;;;; +E0052;TAG LATIN CAPITAL LETTER R;Cf;0;BN;;;;;N;;;;; +E0053;TAG LATIN CAPITAL LETTER S;Cf;0;BN;;;;;N;;;;; +E0054;TAG LATIN CAPITAL LETTER T;Cf;0;BN;;;;;N;;;;; +E0055;TAG LATIN CAPITAL LETTER U;Cf;0;BN;;;;;N;;;;; +E0056;TAG LATIN CAPITAL LETTER V;Cf;0;BN;;;;;N;;;;; +E0057;TAG LATIN CAPITAL LETTER W;Cf;0;BN;;;;;N;;;;; +E0058;TAG LATIN CAPITAL LETTER X;Cf;0;BN;;;;;N;;;;; +E0059;TAG LATIN CAPITAL LETTER Y;Cf;0;BN;;;;;N;;;;; +E005A;TAG LATIN CAPITAL LETTER Z;Cf;0;BN;;;;;N;;;;; +E005B;TAG LEFT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;; +E005C;TAG REVERSE SOLIDUS;Cf;0;BN;;;;;N;;;;; +E005D;TAG RIGHT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;; +E005E;TAG CIRCUMFLEX ACCENT;Cf;0;BN;;;;;N;;;;; +E005F;TAG LOW LINE;Cf;0;BN;;;;;N;;;;; +E0060;TAG GRAVE ACCENT;Cf;0;BN;;;;;N;;;;; +E0061;TAG LATIN SMALL LETTER A;Cf;0;BN;;;;;N;;;;; +E0062;TAG LATIN SMALL LETTER B;Cf;0;BN;;;;;N;;;;; +E0063;TAG LATIN SMALL LETTER C;Cf;0;BN;;;;;N;;;;; +E0064;TAG LATIN SMALL LETTER D;Cf;0;BN;;;;;N;;;;; +E0065;TAG LATIN SMALL LETTER E;Cf;0;BN;;;;;N;;;;; +E0066;TAG LATIN SMALL LETTER F;Cf;0;BN;;;;;N;;;;; +E0067;TAG LATIN SMALL LETTER G;Cf;0;BN;;;;;N;;;;; +E0068;TAG LATIN SMALL LETTER H;Cf;0;BN;;;;;N;;;;; +E0069;TAG LATIN SMALL LETTER I;Cf;0;BN;;;;;N;;;;; +E006A;TAG LATIN SMALL LETTER J;Cf;0;BN;;;;;N;;;;; +E006B;TAG LATIN SMALL LETTER K;Cf;0;BN;;;;;N;;;;; +E006C;TAG LATIN SMALL LETTER L;Cf;0;BN;;;;;N;;;;; +E006D;TAG LATIN SMALL LETTER M;Cf;0;BN;;;;;N;;;;; +E006E;TAG LATIN SMALL LETTER N;Cf;0;BN;;;;;N;;;;; +E006F;TAG LATIN SMALL LETTER O;Cf;0;BN;;;;;N;;;;; +E0070;TAG LATIN SMALL LETTER P;Cf;0;BN;;;;;N;;;;; +E0071;TAG LATIN SMALL LETTER Q;Cf;0;BN;;;;;N;;;;; +E0072;TAG LATIN SMALL LETTER R;Cf;0;BN;;;;;N;;;;; +E0073;TAG LATIN SMALL LETTER S;Cf;0;BN;;;;;N;;;;; +E0074;TAG LATIN SMALL LETTER T;Cf;0;BN;;;;;N;;;;; +E0075;TAG LATIN SMALL LETTER U;Cf;0;BN;;;;;N;;;;; +E0076;TAG LATIN SMALL LETTER V;Cf;0;BN;;;;;N;;;;; +E0077;TAG LATIN SMALL LETTER W;Cf;0;BN;;;;;N;;;;; +E0078;TAG LATIN SMALL LETTER X;Cf;0;BN;;;;;N;;;;; +E0079;TAG LATIN SMALL LETTER Y;Cf;0;BN;;;;;N;;;;; +E007A;TAG LATIN SMALL LETTER Z;Cf;0;BN;;;;;N;;;;; +E007B;TAG LEFT CURLY BRACKET;Cf;0;BN;;;;;N;;;;; +E007C;TAG VERTICAL LINE;Cf;0;BN;;;;;N;;;;; +E007D;TAG RIGHT CURLY BRACKET;Cf;0;BN;;;;;N;;;;; +E007E;TAG TILDE;Cf;0;BN;;;;;N;;;;; +E007F;CANCEL TAG;Cf;0;BN;;;;;N;;;;; +E0100;VARIATION SELECTOR-17;Mn;0;NSM;;;;;N;;;;; +E0101;VARIATION SELECTOR-18;Mn;0;NSM;;;;;N;;;;; +E0102;VARIATION SELECTOR-19;Mn;0;NSM;;;;;N;;;;; +E0103;VARIATION SELECTOR-20;Mn;0;NSM;;;;;N;;;;; +E0104;VARIATION SELECTOR-21;Mn;0;NSM;;;;;N;;;;; +E0105;VARIATION SELECTOR-22;Mn;0;NSM;;;;;N;;;;; +E0106;VARIATION SELECTOR-23;Mn;0;NSM;;;;;N;;;;; +E0107;VARIATION SELECTOR-24;Mn;0;NSM;;;;;N;;;;; +E0108;VARIATION SELECTOR-25;Mn;0;NSM;;;;;N;;;;; +E0109;VARIATION SELECTOR-26;Mn;0;NSM;;;;;N;;;;; +E010A;VARIATION SELECTOR-27;Mn;0;NSM;;;;;N;;;;; +E010B;VARIATION SELECTOR-28;Mn;0;NSM;;;;;N;;;;; +E010C;VARIATION SELECTOR-29;Mn;0;NSM;;;;;N;;;;; +E010D;VARIATION SELECTOR-30;Mn;0;NSM;;;;;N;;;;; +E010E;VARIATION SELECTOR-31;Mn;0;NSM;;;;;N;;;;; +E010F;VARIATION SELECTOR-32;Mn;0;NSM;;;;;N;;;;; +E0110;VARIATION SELECTOR-33;Mn;0;NSM;;;;;N;;;;; +E0111;VARIATION SELECTOR-34;Mn;0;NSM;;;;;N;;;;; +E0112;VARIATION SELECTOR-35;Mn;0;NSM;;;;;N;;;;; +E0113;VARIATION SELECTOR-36;Mn;0;NSM;;;;;N;;;;; +E0114;VARIATION SELECTOR-37;Mn;0;NSM;;;;;N;;;;; +E0115;VARIATION SELECTOR-38;Mn;0;NSM;;;;;N;;;;; +E0116;VARIATION SELECTOR-39;Mn;0;NSM;;;;;N;;;;; +E0117;VARIATION SELECTOR-40;Mn;0;NSM;;;;;N;;;;; +E0118;VARIATION SELECTOR-41;Mn;0;NSM;;;;;N;;;;; +E0119;VARIATION SELECTOR-42;Mn;0;NSM;;;;;N;;;;; +E011A;VARIATION SELECTOR-43;Mn;0;NSM;;;;;N;;;;; +E011B;VARIATION SELECTOR-44;Mn;0;NSM;;;;;N;;;;; +E011C;VARIATION SELECTOR-45;Mn;0;NSM;;;;;N;;;;; +E011D;VARIATION SELECTOR-46;Mn;0;NSM;;;;;N;;;;; +E011E;VARIATION SELECTOR-47;Mn;0;NSM;;;;;N;;;;; +E011F;VARIATION SELECTOR-48;Mn;0;NSM;;;;;N;;;;; +E0120;VARIATION SELECTOR-49;Mn;0;NSM;;;;;N;;;;; +E0121;VARIATION SELECTOR-50;Mn;0;NSM;;;;;N;;;;; +E0122;VARIATION SELECTOR-51;Mn;0;NSM;;;;;N;;;;; +E0123;VARIATION SELECTOR-52;Mn;0;NSM;;;;;N;;;;; +E0124;VARIATION SELECTOR-53;Mn;0;NSM;;;;;N;;;;; +E0125;VARIATION SELECTOR-54;Mn;0;NSM;;;;;N;;;;; +E0126;VARIATION SELECTOR-55;Mn;0;NSM;;;;;N;;;;; +E0127;VARIATION SELECTOR-56;Mn;0;NSM;;;;;N;;;;; +E0128;VARIATION SELECTOR-57;Mn;0;NSM;;;;;N;;;;; +E0129;VARIATION SELECTOR-58;Mn;0;NSM;;;;;N;;;;; +E012A;VARIATION SELECTOR-59;Mn;0;NSM;;;;;N;;;;; +E012B;VARIATION SELECTOR-60;Mn;0;NSM;;;;;N;;;;; +E012C;VARIATION SELECTOR-61;Mn;0;NSM;;;;;N;;;;; +E012D;VARIATION SELECTOR-62;Mn;0;NSM;;;;;N;;;;; +E012E;VARIATION SELECTOR-63;Mn;0;NSM;;;;;N;;;;; +E012F;VARIATION SELECTOR-64;Mn;0;NSM;;;;;N;;;;; +E0130;VARIATION SELECTOR-65;Mn;0;NSM;;;;;N;;;;; +E0131;VARIATION SELECTOR-66;Mn;0;NSM;;;;;N;;;;; +E0132;VARIATION SELECTOR-67;Mn;0;NSM;;;;;N;;;;; +E0133;VARIATION SELECTOR-68;Mn;0;NSM;;;;;N;;;;; +E0134;VARIATION SELECTOR-69;Mn;0;NSM;;;;;N;;;;; +E0135;VARIATION SELECTOR-70;Mn;0;NSM;;;;;N;;;;; +E0136;VARIATION SELECTOR-71;Mn;0;NSM;;;;;N;;;;; +E0137;VARIATION SELECTOR-72;Mn;0;NSM;;;;;N;;;;; +E0138;VARIATION SELECTOR-73;Mn;0;NSM;;;;;N;;;;; +E0139;VARIATION SELECTOR-74;Mn;0;NSM;;;;;N;;;;; +E013A;VARIATION SELECTOR-75;Mn;0;NSM;;;;;N;;;;; +E013B;VARIATION SELECTOR-76;Mn;0;NSM;;;;;N;;;;; +E013C;VARIATION SELECTOR-77;Mn;0;NSM;;;;;N;;;;; +E013D;VARIATION SELECTOR-78;Mn;0;NSM;;;;;N;;;;; +E013E;VARIATION SELECTOR-79;Mn;0;NSM;;;;;N;;;;; +E013F;VARIATION SELECTOR-80;Mn;0;NSM;;;;;N;;;;; +E0140;VARIATION SELECTOR-81;Mn;0;NSM;;;;;N;;;;; +E0141;VARIATION SELECTOR-82;Mn;0;NSM;;;;;N;;;;; +E0142;VARIATION SELECTOR-83;Mn;0;NSM;;;;;N;;;;; +E0143;VARIATION SELECTOR-84;Mn;0;NSM;;;;;N;;;;; +E0144;VARIATION SELECTOR-85;Mn;0;NSM;;;;;N;;;;; +E0145;VARIATION SELECTOR-86;Mn;0;NSM;;;;;N;;;;; +E0146;VARIATION SELECTOR-87;Mn;0;NSM;;;;;N;;;;; +E0147;VARIATION SELECTOR-88;Mn;0;NSM;;;;;N;;;;; +E0148;VARIATION SELECTOR-89;Mn;0;NSM;;;;;N;;;;; +E0149;VARIATION SELECTOR-90;Mn;0;NSM;;;;;N;;;;; +E014A;VARIATION SELECTOR-91;Mn;0;NSM;;;;;N;;;;; +E014B;VARIATION SELECTOR-92;Mn;0;NSM;;;;;N;;;;; +E014C;VARIATION SELECTOR-93;Mn;0;NSM;;;;;N;;;;; +E014D;VARIATION SELECTOR-94;Mn;0;NSM;;;;;N;;;;; +E014E;VARIATION SELECTOR-95;Mn;0;NSM;;;;;N;;;;; +E014F;VARIATION SELECTOR-96;Mn;0;NSM;;;;;N;;;;; +E0150;VARIATION SELECTOR-97;Mn;0;NSM;;;;;N;;;;; +E0151;VARIATION SELECTOR-98;Mn;0;NSM;;;;;N;;;;; +E0152;VARIATION SELECTOR-99;Mn;0;NSM;;;;;N;;;;; +E0153;VARIATION SELECTOR-100;Mn;0;NSM;;;;;N;;;;; +E0154;VARIATION SELECTOR-101;Mn;0;NSM;;;;;N;;;;; +E0155;VARIATION SELECTOR-102;Mn;0;NSM;;;;;N;;;;; +E0156;VARIATION SELECTOR-103;Mn;0;NSM;;;;;N;;;;; +E0157;VARIATION SELECTOR-104;Mn;0;NSM;;;;;N;;;;; +E0158;VARIATION SELECTOR-105;Mn;0;NSM;;;;;N;;;;; +E0159;VARIATION SELECTOR-106;Mn;0;NSM;;;;;N;;;;; +E015A;VARIATION SELECTOR-107;Mn;0;NSM;;;;;N;;;;; +E015B;VARIATION SELECTOR-108;Mn;0;NSM;;;;;N;;;;; +E015C;VARIATION SELECTOR-109;Mn;0;NSM;;;;;N;;;;; +E015D;VARIATION SELECTOR-110;Mn;0;NSM;;;;;N;;;;; +E015E;VARIATION SELECTOR-111;Mn;0;NSM;;;;;N;;;;; +E015F;VARIATION SELECTOR-112;Mn;0;NSM;;;;;N;;;;; +E0160;VARIATION SELECTOR-113;Mn;0;NSM;;;;;N;;;;; +E0161;VARIATION SELECTOR-114;Mn;0;NSM;;;;;N;;;;; +E0162;VARIATION SELECTOR-115;Mn;0;NSM;;;;;N;;;;; +E0163;VARIATION SELECTOR-116;Mn;0;NSM;;;;;N;;;;; +E0164;VARIATION SELECTOR-117;Mn;0;NSM;;;;;N;;;;; +E0165;VARIATION SELECTOR-118;Mn;0;NSM;;;;;N;;;;; +E0166;VARIATION SELECTOR-119;Mn;0;NSM;;;;;N;;;;; +E0167;VARIATION SELECTOR-120;Mn;0;NSM;;;;;N;;;;; +E0168;VARIATION SELECTOR-121;Mn;0;NSM;;;;;N;;;;; +E0169;VARIATION SELECTOR-122;Mn;0;NSM;;;;;N;;;;; +E016A;VARIATION SELECTOR-123;Mn;0;NSM;;;;;N;;;;; +E016B;VARIATION SELECTOR-124;Mn;0;NSM;;;;;N;;;;; +E016C;VARIATION SELECTOR-125;Mn;0;NSM;;;;;N;;;;; +E016D;VARIATION SELECTOR-126;Mn;0;NSM;;;;;N;;;;; +E016E;VARIATION SELECTOR-127;Mn;0;NSM;;;;;N;;;;; +E016F;VARIATION SELECTOR-128;Mn;0;NSM;;;;;N;;;;; +E0170;VARIATION SELECTOR-129;Mn;0;NSM;;;;;N;;;;; +E0171;VARIATION SELECTOR-130;Mn;0;NSM;;;;;N;;;;; +E0172;VARIATION SELECTOR-131;Mn;0;NSM;;;;;N;;;;; +E0173;VARIATION SELECTOR-132;Mn;0;NSM;;;;;N;;;;; +E0174;VARIATION SELECTOR-133;Mn;0;NSM;;;;;N;;;;; +E0175;VARIATION SELECTOR-134;Mn;0;NSM;;;;;N;;;;; +E0176;VARIATION SELECTOR-135;Mn;0;NSM;;;;;N;;;;; +E0177;VARIATION SELECTOR-136;Mn;0;NSM;;;;;N;;;;; +E0178;VARIATION SELECTOR-137;Mn;0;NSM;;;;;N;;;;; +E0179;VARIATION SELECTOR-138;Mn;0;NSM;;;;;N;;;;; +E017A;VARIATION SELECTOR-139;Mn;0;NSM;;;;;N;;;;; +E017B;VARIATION SELECTOR-140;Mn;0;NSM;;;;;N;;;;; +E017C;VARIATION SELECTOR-141;Mn;0;NSM;;;;;N;;;;; +E017D;VARIATION SELECTOR-142;Mn;0;NSM;;;;;N;;;;; +E017E;VARIATION SELECTOR-143;Mn;0;NSM;;;;;N;;;;; +E017F;VARIATION SELECTOR-144;Mn;0;NSM;;;;;N;;;;; +E0180;VARIATION SELECTOR-145;Mn;0;NSM;;;;;N;;;;; +E0181;VARIATION SELECTOR-146;Mn;0;NSM;;;;;N;;;;; +E0182;VARIATION SELECTOR-147;Mn;0;NSM;;;;;N;;;;; +E0183;VARIATION SELECTOR-148;Mn;0;NSM;;;;;N;;;;; +E0184;VARIATION SELECTOR-149;Mn;0;NSM;;;;;N;;;;; +E0185;VARIATION SELECTOR-150;Mn;0;NSM;;;;;N;;;;; +E0186;VARIATION SELECTOR-151;Mn;0;NSM;;;;;N;;;;; +E0187;VARIATION SELECTOR-152;Mn;0;NSM;;;;;N;;;;; +E0188;VARIATION SELECTOR-153;Mn;0;NSM;;;;;N;;;;; +E0189;VARIATION SELECTOR-154;Mn;0;NSM;;;;;N;;;;; +E018A;VARIATION SELECTOR-155;Mn;0;NSM;;;;;N;;;;; +E018B;VARIATION SELECTOR-156;Mn;0;NSM;;;;;N;;;;; +E018C;VARIATION SELECTOR-157;Mn;0;NSM;;;;;N;;;;; +E018D;VARIATION SELECTOR-158;Mn;0;NSM;;;;;N;;;;; +E018E;VARIATION SELECTOR-159;Mn;0;NSM;;;;;N;;;;; +E018F;VARIATION SELECTOR-160;Mn;0;NSM;;;;;N;;;;; +E0190;VARIATION SELECTOR-161;Mn;0;NSM;;;;;N;;;;; +E0191;VARIATION SELECTOR-162;Mn;0;NSM;;;;;N;;;;; +E0192;VARIATION SELECTOR-163;Mn;0;NSM;;;;;N;;;;; +E0193;VARIATION SELECTOR-164;Mn;0;NSM;;;;;N;;;;; +E0194;VARIATION SELECTOR-165;Mn;0;NSM;;;;;N;;;;; +E0195;VARIATION SELECTOR-166;Mn;0;NSM;;;;;N;;;;; +E0196;VARIATION SELECTOR-167;Mn;0;NSM;;;;;N;;;;; +E0197;VARIATION SELECTOR-168;Mn;0;NSM;;;;;N;;;;; +E0198;VARIATION SELECTOR-169;Mn;0;NSM;;;;;N;;;;; +E0199;VARIATION SELECTOR-170;Mn;0;NSM;;;;;N;;;;; +E019A;VARIATION SELECTOR-171;Mn;0;NSM;;;;;N;;;;; +E019B;VARIATION SELECTOR-172;Mn;0;NSM;;;;;N;;;;; +E019C;VARIATION SELECTOR-173;Mn;0;NSM;;;;;N;;;;; +E019D;VARIATION SELECTOR-174;Mn;0;NSM;;;;;N;;;;; +E019E;VARIATION SELECTOR-175;Mn;0;NSM;;;;;N;;;;; +E019F;VARIATION SELECTOR-176;Mn;0;NSM;;;;;N;;;;; +E01A0;VARIATION SELECTOR-177;Mn;0;NSM;;;;;N;;;;; +E01A1;VARIATION SELECTOR-178;Mn;0;NSM;;;;;N;;;;; +E01A2;VARIATION SELECTOR-179;Mn;0;NSM;;;;;N;;;;; +E01A3;VARIATION SELECTOR-180;Mn;0;NSM;;;;;N;;;;; +E01A4;VARIATION SELECTOR-181;Mn;0;NSM;;;;;N;;;;; +E01A5;VARIATION SELECTOR-182;Mn;0;NSM;;;;;N;;;;; +E01A6;VARIATION SELECTOR-183;Mn;0;NSM;;;;;N;;;;; +E01A7;VARIATION SELECTOR-184;Mn;0;NSM;;;;;N;;;;; +E01A8;VARIATION SELECTOR-185;Mn;0;NSM;;;;;N;;;;; +E01A9;VARIATION SELECTOR-186;Mn;0;NSM;;;;;N;;;;; +E01AA;VARIATION SELECTOR-187;Mn;0;NSM;;;;;N;;;;; +E01AB;VARIATION SELECTOR-188;Mn;0;NSM;;;;;N;;;;; +E01AC;VARIATION SELECTOR-189;Mn;0;NSM;;;;;N;;;;; +E01AD;VARIATION SELECTOR-190;Mn;0;NSM;;;;;N;;;;; +E01AE;VARIATION SELECTOR-191;Mn;0;NSM;;;;;N;;;;; +E01AF;VARIATION SELECTOR-192;Mn;0;NSM;;;;;N;;;;; +E01B0;VARIATION SELECTOR-193;Mn;0;NSM;;;;;N;;;;; +E01B1;VARIATION SELECTOR-194;Mn;0;NSM;;;;;N;;;;; +E01B2;VARIATION SELECTOR-195;Mn;0;NSM;;;;;N;;;;; +E01B3;VARIATION SELECTOR-196;Mn;0;NSM;;;;;N;;;;; +E01B4;VARIATION SELECTOR-197;Mn;0;NSM;;;;;N;;;;; +E01B5;VARIATION SELECTOR-198;Mn;0;NSM;;;;;N;;;;; +E01B6;VARIATION SELECTOR-199;Mn;0;NSM;;;;;N;;;;; +E01B7;VARIATION SELECTOR-200;Mn;0;NSM;;;;;N;;;;; +E01B8;VARIATION SELECTOR-201;Mn;0;NSM;;;;;N;;;;; +E01B9;VARIATION SELECTOR-202;Mn;0;NSM;;;;;N;;;;; +E01BA;VARIATION SELECTOR-203;Mn;0;NSM;;;;;N;;;;; +E01BB;VARIATION SELECTOR-204;Mn;0;NSM;;;;;N;;;;; +E01BC;VARIATION SELECTOR-205;Mn;0;NSM;;;;;N;;;;; +E01BD;VARIATION SELECTOR-206;Mn;0;NSM;;;;;N;;;;; +E01BE;VARIATION SELECTOR-207;Mn;0;NSM;;;;;N;;;;; +E01BF;VARIATION SELECTOR-208;Mn;0;NSM;;;;;N;;;;; +E01C0;VARIATION SELECTOR-209;Mn;0;NSM;;;;;N;;;;; +E01C1;VARIATION SELECTOR-210;Mn;0;NSM;;;;;N;;;;; +E01C2;VARIATION SELECTOR-211;Mn;0;NSM;;;;;N;;;;; +E01C3;VARIATION SELECTOR-212;Mn;0;NSM;;;;;N;;;;; +E01C4;VARIATION SELECTOR-213;Mn;0;NSM;;;;;N;;;;; +E01C5;VARIATION SELECTOR-214;Mn;0;NSM;;;;;N;;;;; +E01C6;VARIATION SELECTOR-215;Mn;0;NSM;;;;;N;;;;; +E01C7;VARIATION SELECTOR-216;Mn;0;NSM;;;;;N;;;;; +E01C8;VARIATION SELECTOR-217;Mn;0;NSM;;;;;N;;;;; +E01C9;VARIATION SELECTOR-218;Mn;0;NSM;;;;;N;;;;; +E01CA;VARIATION SELECTOR-219;Mn;0;NSM;;;;;N;;;;; +E01CB;VARIATION SELECTOR-220;Mn;0;NSM;;;;;N;;;;; +E01CC;VARIATION SELECTOR-221;Mn;0;NSM;;;;;N;;;;; +E01CD;VARIATION SELECTOR-222;Mn;0;NSM;;;;;N;;;;; +E01CE;VARIATION SELECTOR-223;Mn;0;NSM;;;;;N;;;;; +E01CF;VARIATION SELECTOR-224;Mn;0;NSM;;;;;N;;;;; +E01D0;VARIATION SELECTOR-225;Mn;0;NSM;;;;;N;;;;; +E01D1;VARIATION SELECTOR-226;Mn;0;NSM;;;;;N;;;;; +E01D2;VARIATION SELECTOR-227;Mn;0;NSM;;;;;N;;;;; +E01D3;VARIATION SELECTOR-228;Mn;0;NSM;;;;;N;;;;; +E01D4;VARIATION SELECTOR-229;Mn;0;NSM;;;;;N;;;;; +E01D5;VARIATION SELECTOR-230;Mn;0;NSM;;;;;N;;;;; +E01D6;VARIATION SELECTOR-231;Mn;0;NSM;;;;;N;;;;; +E01D7;VARIATION SELECTOR-232;Mn;0;NSM;;;;;N;;;;; +E01D8;VARIATION SELECTOR-233;Mn;0;NSM;;;;;N;;;;; +E01D9;VARIATION SELECTOR-234;Mn;0;NSM;;;;;N;;;;; +E01DA;VARIATION SELECTOR-235;Mn;0;NSM;;;;;N;;;;; +E01DB;VARIATION SELECTOR-236;Mn;0;NSM;;;;;N;;;;; +E01DC;VARIATION SELECTOR-237;Mn;0;NSM;;;;;N;;;;; +E01DD;VARIATION SELECTOR-238;Mn;0;NSM;;;;;N;;;;; +E01DE;VARIATION SELECTOR-239;Mn;0;NSM;;;;;N;;;;; +E01DF;VARIATION SELECTOR-240;Mn;0;NSM;;;;;N;;;;; +E01E0;VARIATION SELECTOR-241;Mn;0;NSM;;;;;N;;;;; +E01E1;VARIATION SELECTOR-242;Mn;0;NSM;;;;;N;;;;; +E01E2;VARIATION SELECTOR-243;Mn;0;NSM;;;;;N;;;;; +E01E3;VARIATION SELECTOR-244;Mn;0;NSM;;;;;N;;;;; +E01E4;VARIATION SELECTOR-245;Mn;0;NSM;;;;;N;;;;; +E01E5;VARIATION SELECTOR-246;Mn;0;NSM;;;;;N;;;;; +E01E6;VARIATION SELECTOR-247;Mn;0;NSM;;;;;N;;;;; +E01E7;VARIATION SELECTOR-248;Mn;0;NSM;;;;;N;;;;; +E01E8;VARIATION SELECTOR-249;Mn;0;NSM;;;;;N;;;;; +E01E9;VARIATION SELECTOR-250;Mn;0;NSM;;;;;N;;;;; +E01EA;VARIATION SELECTOR-251;Mn;0;NSM;;;;;N;;;;; +E01EB;VARIATION SELECTOR-252;Mn;0;NSM;;;;;N;;;;; +E01EC;VARIATION SELECTOR-253;Mn;0;NSM;;;;;N;;;;; +E01ED;VARIATION SELECTOR-254;Mn;0;NSM;;;;;N;;;;; +E01EE;VARIATION SELECTOR-255;Mn;0;NSM;;;;;N;;;;; +E01EF;VARIATION SELECTOR-256;Mn;0;NSM;;;;;N;;;;; +F0000;;Co;0;L;;;;;N;;;;; +FFFFD;;Co;0;L;;;;;N;;;;; +100000;;Co;0;L;;;;;N;;;;; +10FFFD;;Co;0;L;;;;;N;;;;; diff --git a/libc/unicode/wcsnwidth.c b/libc/unicode/wcsnwidth.c new file mode 100644 index 00000000..fdc33458 --- /dev/null +++ b/libc/unicode/wcsnwidth.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/unicode/unicode.h" + +/** + * Returns monospace display width of wide character string. + */ +int wcsnwidth(const wchar_t *pwcs, size_t n) { + int w, width = 0; + for (; *pwcs && n-- > 0; pwcs++) { + if ((w = wcwidth(*pwcs)) < 0) { + return -1; + } else { + width += w; + } + } + return width; +} diff --git a/libc/unicode/wcswidth.c b/libc/unicode/wcswidth.c new file mode 100644 index 00000000..cfd9e2c7 --- /dev/null +++ b/libc/unicode/wcswidth.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/limits.h" +#include "libc/unicode/unicode.h" + +/** + * Returns monospace display width of wide character string. + */ +int wcswidth(const wchar_t *pwcs) { + return wcsnwidth(pwcs, SIZE_MAX); +} diff --git a/libc/unicode/wcwidth.c b/libc/unicode/wcwidth.c new file mode 100644 index 00000000..a5e369f1 --- /dev/null +++ b/libc/unicode/wcwidth.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/unicode/unicode.h" + +/** + * Returns cell width of monospace character. + */ +int wcwidth(wchar_t ucs) { + if (ucs == 0) return 0; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) { + return -1; + } else if (0 <= ucs && ucs < kCombiningCharsBits && + bt(kCombiningChars, ucs)) { + return 0; + } else if (0 <= ucs && ucs < kEastAsianWidthBits) { + return 1 + bt(kEastAsianWidth, ucs); + } else { + return 1; + } +} diff --git a/libc/wave.h b/libc/wave.h new file mode 100644 index 00000000..2f2a1855 --- /dev/null +++ b/libc/wave.h @@ -0,0 +1,37 @@ +#ifndef COSMOPOLITAN_LIBC_WAVE_H_ +#define COSMOPOLITAN_LIBC_WAVE_H_ + +#define kWaveAlign 4 + +#define kWaveMagnumRiff 0x46464952u /* "RIFF" */ +#define kWaveMagnumWave 0x46464952u /* "WAVE" */ + +#define WAVE_AUDIOFORMAT_PCM 1 + +#define WAVE_OFFSET_CHUNK_ID 0 +#define WAVE_OFFSET_CHUNK_SIZE 4 +#define WAVE_OFFSET_FORMAT 8 +#define WAVE_OFFSET_SUBCHUNK_1_ID 12 +#define WAVE_OFFSET_SUBCHUNK_1_SIZE 16 +#define WAVE_OFFSET_AUDIOFORMAT 20 +#define WAVE_OFFSET_CHANNELS 22 +#define WAVE_OFFSET_SAMPLERATE 24 +#define WAVE_OFFSET_BYTERATE 28 +#define WAVE_OFFSET_BLOCKALIGN 32 +#define WAVE_OFFSET_BITSPERSAMPLE 34 +#define WAVE_OFFSET_SUBCHUNK_2_ID 36 +/* #define WAVE_OFFSET_SUBCHUNK_2_ID 40 */ + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/** + * @fileoverview RIFF WAVE data structures. + */ + +#define WAVE_MAGIC(P) read64le(P) +#define WAVE_MAGIC_WRITE(P) read64le(P) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_WAVE_H_ */ diff --git a/libc/x/bingblit.c b/libc/x/bingblit.c new file mode 100644 index 00000000..31c15fbe --- /dev/null +++ b/libc/x/bingblit.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/fmt/bing.h" +#include "libc/x/x.h" + +short *bingblit(int ys, int xs, unsigned char M[ys][xs], int yn, int xn) { + int y, x; + short *s, *p; + p = s = xcalloc(yn * (1 + xn) + 1, sizeof(short)); + for (y = 0; y < yn; ++y) { + *p++ = '\n'; + for (x = 0; x < xn; ++x) { + *p++ = bing(M[y][x], 0); + } + } + *p = '\0'; + return s; +} diff --git a/libc/x/unbingbuf.c b/libc/x/unbingbuf.c new file mode 100644 index 00000000..a5906a83 --- /dev/null +++ b/libc/x/unbingbuf.c @@ -0,0 +1,51 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/fmt/bing.h" +#include "libc/log/check.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" + +/** + * Decodes human-readable CP437 glyphs into binary, e.g. + * + * char binged[5]; + * char golden[5] = "\0\1\2\3\4"; + * unbingbuf(binged, sizeof(binged), u" ☺☻♥♦", -1); + * CHECK_EQ(0, memcmp(binged, golden, 5)); + * + * @param buf is caller owned + * @param size is byte length of buf + * @param glyphs is UCS-2 encoded CP437 representation of binary data + * @param fill if -1 will memset any remaining buffer space + * @note no NUL terminator is added to end of buf + * @see tunbing(), unbingstr(), unbing() + */ +void *unbingbuf(void *buf, size_t size, const char16_t *glyphs, int fill) { + int b; + char *p, *pe; + for (p = buf, pe = p + size; p < pe && *glyphs; ++p, ++glyphs) { + *p = (b = unbing(*glyphs)) & 0xff; + DCHECK_NE(-1, b, "%`'hc ∉ IBMCP437\n", *glyphs); + } + if (fill != -1) memset(p, fill, pe - p); + return buf; +} diff --git a/libc/x/unbingstr.c b/libc/x/unbingstr.c new file mode 100644 index 00000000..8c12aa0a --- /dev/null +++ b/libc/x/unbingstr.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/fmt/bing.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" + +/** + * Decodes human-readable CP437 glyphs into binary, e.g. + * + * CHECK_EQ(0, memcmp(gc(unbingstr(u" ☺☻♥♦")), "\0\1\2\3\4", 5)); + * + * @param buf is caller owned + * @param size is byte length of buf + * @param glyphs is UCS-2 encoded CP437 representation of binary data + * @param fill if -1 will memset any remaining buffer space + * @note no NUL terminator is added to end of buf + * @see tunbing(), unbingbuf(), unbing() + */ +mallocesque void *unbingstr(const char16_t *s) { + size_t size; + size = strlen16(s); + return unbingbuf(malloc(size), size, s, -1); +} diff --git a/libc/x/x.h b/libc/x/x.h new file mode 100644 index 00000000..d12a7e47 --- /dev/null +++ b/libc/x/x.h @@ -0,0 +1,114 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#ifndef COSMOPOLITAN_LIBC_X_H_ +#define COSMOPOLITAN_LIBC_X_H_ +#include "libc/calls/struct/timespec.h" +#include "libc/calls/struct/timeval.h" +#include "libc/fmt/pflink.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § eXtended apis ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│─╝ + Standard Library veneers for folks not building embedded RTOS */ + +#define _XPNN paramsnonnull() +#define _XRET nothrow nocallback nodiscard returnsnonnull +#define _XMAL returnspointerwithnoaliases _XRET +#define _XMALPG returnsaligned((PAGESIZE)) _XMAL + +struct FILE; +struct sigaction; +struct timeval; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § eXtended apis » system calls ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +int xsigaction(int, void *, uint64_t, uint64_t, struct sigaction *); +int xwrite(int, const void *, uint64_t); + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § eXtended apis » memory ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +char *xdtoa(double) _XMAL; +char *xasprintf(const char *, ...) printfesque(1) paramsnonnull((1)) _XMAL; +char *xvasprintf(const char *, va_list) _XPNN _XMAL; +char *xgetline(struct FILE *) _XPNN mallocesque; +void *xmalloc(size_t) attributeallocsize((1)) _XMAL; +void *xrealloc(void *, size_t) attributeallocsize((2)) _XRET; +void *xcalloc(size_t, size_t) attributeallocsize((1, 2)) _XMAL; +void *xvalloc(size_t) attributeallocsize((1)) _XMALPG; +void *xmemalign(size_t, size_t) attributeallocalign((1)) + attributeallocsize((2)) _XMAL; +char *xstrdup(const char *) _XPNN _XMAL; +char *xstrcat(const char *, ...) paramsnonnull((1)) nullterminated() _XMAL; +char *xstrmul(const char *, size_t) paramsnonnull((1)) _XMAL; +char *xinet_ntop(int, const void *) _XPNN _XMAL; +char *xaescapec(const char *) _XPNN _XMAL; +char *xaescapesh(const char *) _XPNN _XMAL; +char *xaescapeshq(const char *) _XPNN _XMAL; +char *xaescape(const char *, int (*)(char *, unsigned, const char *, + unsigned)) _XPNN hidden _XMAL; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § eXtended apis » time ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +char *xiso8601i(int) mallocesque; +char *xiso8601tv(struct timeval *) mallocesque; +char *xiso8601ts(struct timespec *) mallocesque; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § eXtended apis » input / output ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +char *xslurp(const char *) _XPNN _XMALPG nodiscard; + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § eXtended apis » safety ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#define xstrcat(...) (xstrcat)(__VA_ARGS__, NULL) + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § eXtended apis » generic typing ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#if __STDC_VERSION__ + 0 >= 201112 + +#define xiso8601(TS) \ + _Generic(*(TS), struct timeval : xiso8601tv, default : xiso8601ts)(TS) + +#endif /* C11 */ + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ cosmopolitan § eXtended apis » link-time optimizations ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +#define xasprintf(FMT, ...) (xasprintf)(PFLINK(FMT), ##__VA_ARGS__) +#define xvasprintf(FMT, VA) (xvasprintf)(PFLINK(FMT), VA) +#endif + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_X_H_ */ diff --git a/libc/x/x.mk b/libc/x/x.mk new file mode 100644 index 00000000..3c160c55 --- /dev/null +++ b/libc/x/x.mk @@ -0,0 +1,72 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ +# +# SYNOPSIS +# +# Cosmopolitan Extended Memory & Formatting Functions +# +# DESCRIPTION +# +# This package implements nonstandard APIs that've been spotted in a +# substantial number of independent codebases. + +PKGS += LIBC_X + +LIBC_X_ARTIFACTS += LIBC_X_A +LIBC_X = $(LIBC_X_A_DEPS) $(LIBC_X_A) +LIBC_X_A = o/$(MODE)/libc/x/x.a +LIBC_X_A_FILES := $(wildcard libc/x/*) +LIBC_X_A_HDRS = $(filter %.h,$(LIBC_X_A_FILES)) +LIBC_X_A_SRCS_S = $(filter %.S,$(LIBC_X_A_FILES)) +LIBC_X_A_SRCS_C = $(filter %.c,$(LIBC_X_A_FILES)) + +LIBC_X_A_SRCS = \ + $(LIBC_X_A_SRCS_S) \ + $(LIBC_X_A_SRCS_C) + +LIBC_X_A_OBJS = \ + $(LIBC_X_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_X_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_X_A_SRCS_C:%.c=o/$(MODE)/%.o) + +LIBC_X_A_CHECKS = \ + $(LIBC_X_A).pkg \ + $(LIBC_X_A_HDRS:%=o/$(MODE)/%.ok) + +LIBC_X_A_DIRECTDEPS = \ + LIBC_CALLS \ + LIBC_ESCAPE \ + LIBC_FMT \ + LIBC_LOG \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_STDIO \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_TIME \ + THIRD_PARTY_DTOA + +LIBC_X_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_X_A_DIRECTDEPS),$($(x)))) + +$(LIBC_X_A): libc/x/ \ + $(LIBC_X_A).pkg \ + $(LIBC_X_A_OBJS) + +$(LIBC_X_A).pkg: \ + $(LIBC_X_A_OBJS) \ + $(foreach x,$(LIBC_X_A_DIRECTDEPS),$($(x)_A).pkg) + +LIBC_X_LIBS = $(foreach x,$(LIBC_X_ARTIFACTS),$($(x))) +LIBC_X_SRCS = $(foreach x,$(LIBC_X_ARTIFACTS),$($(x)_SRCS)) +LIBC_X_HDRS = $(foreach x,$(LIBC_X_ARTIFACTS),$($(x)_HDRS)) +LIBC_X_BINS = $(foreach x,$(LIBC_X_ARTIFACTS),$($(x)_BINS)) +LIBC_X_CHECKS = $(foreach x,$(LIBC_X_ARTIFACTS),$($(x)_CHECKS)) +LIBC_X_OBJS = $(foreach x,$(LIBC_X_ARTIFACTS),$($(x)_OBJS)) +LIBC_X_TESTS = $(foreach x,$(LIBC_X_ARTIFACTS),$($(x)_TESTS)) +$(LIBC_X_OBJS): $(BUILD_FILES) libc/x/x.mk + +.PHONY: o/$(MODE)/libc/x +o/$(MODE)/libc/x: $(LIBC_X_CHECKS) diff --git a/libc/x/xaescape.c b/libc/x/xaescape.c new file mode 100644 index 00000000..bb9f7dbe --- /dev/null +++ b/libc/x/xaescape.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/escape/escape.h" +#include "libc/log/log.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/x/x.h" + +/** + * Aspects 2-arity memory op with allocating behavior. + * Used to turn FOO() into aFOO() without too much duplicated code. + */ +char *xaescape(const char *unescaped, + int impl(char *escaped, unsigned size, const char *unescaped, + unsigned length)) { + char *escaped = NULL; + if (aescape(&escaped, 32, unescaped, strlen(unescaped), impl) == -1) { + die(); + } + return escaped; +} diff --git a/libc/x/xaescapec.c b/libc/x/xaescapec.c new file mode 100644 index 00000000..54e93162 --- /dev/null +++ b/libc/x/xaescapec.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/escape/escape.h" +#include "libc/x/x.h" + +/** + * Delegates NUL-terminated string to escapec() or dies. + * + * The surrounding quotes are *not* included. Death hapens only on + * allocation error or int32 overflow, which are extremely unlikely. + * + * @return escaped string which must make its way to free() + */ +char *xaescapec(const char *unescaped) { return xaescape(unescaped, escapec); } diff --git a/libc/x/xaescapesh.c b/libc/x/xaescapesh.c new file mode 100644 index 00000000..fcaf4a16 --- /dev/null +++ b/libc/x/xaescapesh.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/escape/escape.h" +#include "libc/x/x.h" + +/** + * Delegates NUL-terminated string to escapesh() or dies. + * + * The surrounding single quotes are *not* included. Death hapens only + * on allocation error or int32 overflow. + * + * @return escaped string which must make its way to free() + * @see xaescapeshq() which adds quotes + */ +char *xaescapesh(const char *unescaped) { + return xaescape(unescaped, escapesh); +} diff --git a/libc/x/xaescapeshq.c b/libc/x/xaescapeshq.c new file mode 100644 index 00000000..e0f73c2c --- /dev/null +++ b/libc/x/xaescapeshq.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/escape/escape.h" +#include "libc/runtime/gc.h" +#include "libc/x/x.h" + +/** + * Single-quotes string for bourne shell. + * + * @return escaped string which must make its way to free() + */ +char *xaescapeshq(const char *unescaped) { + return xasprintf("'%s'", gc(xaescape(unescaped, escapesh))); +} diff --git a/libc/x/xasprintf.c b/libc/x/xasprintf.c new file mode 100644 index 00000000..fea569b5 --- /dev/null +++ b/libc/x/xasprintf.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/x/x.h" + +/** + * Returns dynamically formatted string. + * + * @return must be free()'d or gc()'d + * @note greatest of all C functions + */ +char *(xasprintf)(const char *fmt, ...) { + char *res; + va_list va; + va_start(va, fmt); + res = (xvasprintf)(fmt, va); + va_end(va); + return res; +} diff --git a/libc/x/xcalloc.c b/libc/x/xcalloc.c new file mode 100644 index 00000000..99df2901 --- /dev/null +++ b/libc/x/xcalloc.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/x/x.h" + +/** + * Allocates initialized memory, or dies. + */ +void *xcalloc(size_t count, size_t size) { + void *res = calloc(count, size); + if (!res) die(); + return res; +} diff --git a/libc/x/xdtoa.c b/libc/x/xdtoa.c new file mode 100644 index 00000000..626e0461 --- /dev/null +++ b/libc/x/xdtoa.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/mem/mem.h" +#include "libc/x/x.h" +#include "third_party/dtoa/dtoa.h" + +/** + * Converts double to string w/ high-accuracy the easy way. + * + * @see gc(), free() + */ +char *xdtoa(double d) { + char buf[32]; + return xstrdup(g_fmt(buf, d)); +} diff --git a/libc/x/xgetline.c b/libc/x/xgetline.c new file mode 100644 index 00000000..d17bae0e --- /dev/null +++ b/libc/x/xgetline.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/mem/mem.h" +#include "libc/stdio/stdio.h" +#include "libc/x/x.h" + +/** + * Reads line from stream. + * + * @return allocated line that needs free() and usually chomp() too, + * or NULL on ferror() or feof() + * @see getline() for a more difficult api + */ +char *xgetline(FILE *f) { + char *res; + size_t n, got; + n = 0; + res = NULL; + if ((got = getdelim(&res, &n, '\n', f)) <= 0) { + free(res); + res = NULL; + } + return res; +} diff --git a/libc/x/xiso8601.c b/libc/x/xiso8601.c new file mode 100644 index 00000000..675d38ff --- /dev/null +++ b/libc/x/xiso8601.c @@ -0,0 +1,79 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/struct/timespec.h" +#include "libc/calls/struct/timeval.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/mem/mem.h" +#include "libc/sysv/consts/clock.h" +#include "libc/time/struct/tm.h" +#include "libc/time/time.h" +#include "libc/x/x.h" + +STATIC_YOINK("stoa"); +STATIC_YOINK("ntoa"); + +/** + * @fileoverview Timestamps in One True Format w/o toil. + */ + +static char *xiso8601$impl(struct timespec *opt_ts, int sswidth) { + struct tm tm; + struct timespec ts; + int64_t sec, subsec; + char timebuf[64], zonebuf[8]; + if (opt_ts) { + sec = opt_ts->tv_sec; + subsec = opt_ts->tv_nsec; + } else { + errno = 0; + clock_gettime(CLOCK_REALTIME, &ts); + sec = ts.tv_sec; + subsec = ts.tv_nsec; + sswidth = 9; + if (errno == ENOSYS) { + subsec /= 1000; + sswidth = 6; + } + } + if (IsWindows() && sswidth == 9) { + subsec /= 100; + sswidth = 7; /* windows nt uses hectonanoseconds */ + } + localtime_r(&sec, &tm); + strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%S", &tm); + strftime(zonebuf, sizeof(zonebuf), "%z", &tm); + return (xasprintf)("%s.%0*ld%s", timebuf, sswidth, subsec, zonebuf); +} + +/** + * Returns allocated string representation of nanosecond timestamp. + */ +char *xiso8601ts(struct timespec *opt_ts) { + return xiso8601$impl(opt_ts, 9); +} + +/** + * Returns allocated string representation of microsecond timestamp. + */ +char *xiso8601tv(struct timeval *opt_tv) { + return xiso8601$impl( + opt_tv ? &(struct timespec){opt_tv->tv_sec, opt_tv->tv_usec} : NULL, 6); +} diff --git a/libc/x/xmalloc.c b/libc/x/xmalloc.c new file mode 100644 index 00000000..07672e07 --- /dev/null +++ b/libc/x/xmalloc.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/x/x.h" + +/** + * Allocates uninitialized memory, or dies. + */ +void *xmalloc(size_t bytes) { + void *res = malloc(bytes); + if (!res) die(); + return res; +} diff --git a/libc/x/xmemalign.c b/libc/x/xmemalign.c new file mode 100644 index 00000000..0c3833c3 --- /dev/null +++ b/libc/x/xmemalign.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/x/x.h" + +/** + * Allocates aligned memory, or dies. + */ +void *xmemalign(size_t alignment, size_t bytes) { + void *res = memalign(alignment, bytes); + if (!res) die(); + return res; +} diff --git a/libc/x/xrealloc.c b/libc/x/xrealloc.c new file mode 100644 index 00000000..49ef11af --- /dev/null +++ b/libc/x/xrealloc.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/x/x.h" + +/** + * Relocates, extends, and/or shrinks memory──or die. + * + * This API is fabulous since it categorically eliminates an extremely + * common type of memory bug, by simply redefining it as a crash. + */ +void *xrealloc(void *p1, size_t newsize) { + void *p2 = realloc(p1, newsize); + if (!p2) die(); + return p2; +} diff --git a/libc/x/xsigaction.c b/libc/x/xsigaction.c new file mode 100644 index 00000000..d6555f39 --- /dev/null +++ b/libc/x/xsigaction.c @@ -0,0 +1,53 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/sig.h" +#include "libc/x/x.h" + +/** + * Installs handler for kernel interrupt, e.g.: + * + * onctrlc(sig) { exit(128+sig); } + * CHECK_NE(-1, xsigaction(SIGINT, onctrlc, SA_RESETHAND, 0, 0)); + * + * @param sig can be SIGINT, SIGTERM, etc. + * @param handler is SIG_DFL, SIG_IGN, or a pointer to a 0≤arity≤3 + * callback function passed (sig, siginfo_t *, ucontext_t *). + * @param flags can have SA_RESETHAND, SA_RESTART, SA_SIGINFO, etc. + * @param mask is 1ul«SIG₁[…|1ul«SIGₙ] bitset to block in handler + * @param old optionally receives previous handler + * @return 0 on success, or -1 w/ errno + * @see libc/sysv/consts.sh + * @asyncsignalsafe + */ +int xsigaction(int sig, void *handler, uint64_t flags, uint64_t mask, + struct sigaction *old) { + /* This API is superior to sigaction() because (1) it offers feature + parity; (2) compiler emits 1/3rd as much binary code at call-site; + and (3) it removes typing that just whines without added saftey. */ + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = handler; + sa.sa_flags = flags; + memcpy(&sa.sa_mask, &mask, sizeof(mask)); + return sigaction(sig, &sa, old); +} diff --git a/libc/x/xstrcat.c b/libc/x/xstrcat.c new file mode 100644 index 00000000..028b526a --- /dev/null +++ b/libc/x/xstrcat.c @@ -0,0 +1,64 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" +#include "libc/x/x.h" + +/** + * Concatenates strings / chars to newly allocated memory, e.g. + * + * xstrcat("hi", ' ', "there") + * + * Or without the C99 helper macro: + * + * (xstrcat)("hi", ' ', "there", NULL) + * + * This goes twice as fast as the more powerful xasprintf(). It's not + * quadratic like strcat(). It's much slower than high-effort stpcpy(), + * particularly with string literals. + * + * @see gc() + */ +char *(xstrcat)(const char *s, ...) { + char *p, b[2]; + va_list va; + size_t i, n, n2, l; + p = NULL; + i = n = 0; + va_start(va, s); + do { + if ((intptr_t)s > 0 && (intptr_t)s <= 255) { + b[0] = (unsigned char)(intptr_t)s; + b[1] = '\0'; + s = b; + l = 1; + } else { + l = strlen(s); + } + if ((n2 = i + l + 16) >= n) { + p = xrealloc(p, (n = n2 + (n2 >> 1))); + } + memcpy(p + i, s, l + 1); + i += l; + } while ((s = va_arg(va, const char *))); + va_end(va); + return p; +} diff --git a/libc/x/xstrdup.c b/libc/x/xstrdup.c new file mode 100644 index 00000000..d65f05b1 --- /dev/null +++ b/libc/x/xstrdup.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/x/x.h" + +/** + * Allocates new copy of string, or dies. + */ +char *xstrdup(const char *s) { + void *res = strdup(s); + if (!res) die(); + return res; +} diff --git a/libc/x/xstrmul.c b/libc/x/xstrmul.c new file mode 100644 index 00000000..a41eb80a --- /dev/null +++ b/libc/x/xstrmul.c @@ -0,0 +1,33 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/sizemultiply.h" +#include "libc/log/check.h" +#include "libc/str/str.h" +#include "libc/x/x.h" + +char *xstrmul(const char *s, size_t n) { + char *p; + size_t i, m, size; + m = strlen(s); + p = xcalloc(n + 1, m); + for (i = 0; i < n; ++i) memcpy(p + i * m, s, m); + p[i * m] = '\0'; + return p; +} diff --git a/libc/x/xvalloc.c b/libc/x/xvalloc.c new file mode 100644 index 00000000..d932a100 --- /dev/null +++ b/libc/x/xvalloc.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/x/x.h" + +/** + * Allocates page-aligned memory, or dies. + */ +void *xvalloc(size_t size) { + void *res = valloc(size); + if (!res) die(); + return res; +} diff --git a/libc/x/xvasprintf.c b/libc/x/xvasprintf.c new file mode 100644 index 00000000..8fa59411 --- /dev/null +++ b/libc/x/xvasprintf.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/x/x.h" + +/** + * Returns dynamically formatted string. + * + * @return fully formatted string, which must be free()'d + * @see xasprintf() + */ +char *(xvasprintf)(const char *fmt, va_list va) { + char *buf; + if ((vasprintf)(&buf, fmt, va) == -1) die(); + return buf; +} diff --git a/libc/x/xwrite.c b/libc/x/xwrite.c new file mode 100644 index 00000000..152e9adc --- /dev/null +++ b/libc/x/xwrite.c @@ -0,0 +1,44 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/errno.h" +#include "libc/x/x.h" + +/** + * Writes data uninterruptibly. + * + * @return 0 on success, or -1 w/ errno + */ +int xwrite(int fd, const void *p, uint64_t n) { + int64_t i; + uint64_t m; + const char *buf; + buf = p; + while (n) { + m = n; + do { + i = write(fd, buf, m); + } while (i < 0 && errno == EINTR); + if (i < 0) return -1; + buf += i; + n -= i; + } + return 0; +} diff --git a/libc/zip.h b/libc/zip.h new file mode 100644 index 00000000..4b118e60 --- /dev/null +++ b/libc/zip.h @@ -0,0 +1,159 @@ +#ifndef COSMOPOLITAN_LIBC_ZIP_H_ +#define COSMOPOLITAN_LIBC_ZIP_H_ +#include "libc/bits/bits.h" +#include "libc/macros.h" +#include "libc/str/str.h" + +/** + * @fileoverview PKZIP Data Structures. + */ + +#define kZipAlign 2 + +#define kZipCosmopolitanVersion 1 + +#define kZipOsDos 0 +#define kZipOsAmiga 1 +#define kZipOsOpenvms 2 +#define kZipOsUnix 3 +#define kZipOsVmcms 4 +#define kZipOsAtarist 5 +#define kZipOsOs2hpfs 6 +#define kZipOsMacintosh 7 +#define kZipOsZsystem 8 +#define kZipOsCpm 9 +#define kZipOsWindowsntfs 10 +#define kZipOsMvsos390zos 11 +#define kZipOsVse 12 +#define kZipOsAcornrisc 13 +#define kZipOsVfat 14 +#define kZipOsAltmvs 15 +#define kZipOsBeos 16 +#define kZipOsTandem 17 +#define kZipOsOs400 18 +#define kZipOsOsxdarwin 19 + +#define kZipEra1989 10 /* PKZIP 1.0 */ +#define kZipEra1993 20 /* PKZIP 2.0: deflate/subdir/etc. support */ +#define kZipEra2001 45 /* PKZIP 4.5: kZipExtraZip64 support */ + +#define kZipIattrBinary 0 +#define kZipIattrAscii 1 + +#define kZipCompressionNone 0 +#define kZipCompressionDeflate 8 + +#define kZipCdirHdrMagic 0x06054b50 /* PK♣♠ "PK\5\6" */ +#define kZipCdirHdrMinSize 22 +#define kZipCdirAlign 64 /* our choice; actually 2 */ +#define kZipCdirHdrLinkableSize \ + ROUNDUP(kZipCfileHdrMinSize + PATH_MAX, kZipCdirAlign) + +#define kZipCfileHdrMagic 0x02014b50 /* PK☺☻ "PK\1\2" */ +#define kZipCfileHdrMinSize 46 +#define kZipCfileOffsetGeneralflag 8 +#define kZipCfileOffsetCompressionmethod 10 +#define kZipCfileOffsetLastmodifiedtime 12 +#define kZipCfileOffsetLastmodifieddate 14 +#define kZipCfileOffsetCrc32 16 +#define kZipCfileOffsetCompressedsize 20 +#define kZipCfileOffsetExternalattributes 38 +#define kZipCfileOffsetOffset 42 + +#define kZipLfileHdrMagic 0x04034b50 /* PK♥♦ "PK\3\4" */ +#define kZipLfileHdrMinSize 30 +#define kZipLfileOffsetGeneralflag 6 +#define kZipLfileOffsetCompressionmethod 8 +#define kZipLfileOffsetLastmodifiedtime 10 +#define kZipLfileOffsetLastmodifieddate 12 +#define kZipLfileOffsetCrc32 14 +#define kZipLfileOffsetCompressedsize 18 + +#define kZipGflagUtf8 0x800 + +#define kZipExtraHdrSize 4 +#define kZipExtraZip64 0x0001 +#define kZipExtraNtfs 0x000a +#define kZipExtraNtfsFiletimes 0x0001 + +#define kZipCfileMagic "PK\001\002" + +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +/* end of central directory record */ +#define ZIP_CDIR_MAGIC(P) read32le(P) +#define ZIP_CDIR_DISK(P) read16le((P) + 4) +#define ZIP_CDIR_STARTINGDISK(P) read16le((P) + 6) +#define ZIP_CDIR_RECORDSONDISK(P) read16le((P) + 8) +#define ZIP_CDIR_RECORDS(P) read16le((P) + 10) +#define ZIP_CDIR_SIZE(P) read32le((P) + 12) +#define ZIP_CDIR_OFFSET(P) read32le((P) + 16) +#define ZIP_CDIR_COMMENTSIZE(P) read16le((P) + 20) +#define ZIP_CDIR_COMMENT(P) (&(P)[22]) +#define ZIP_CDIR_HDRSIZE(P) (ZIP_CDIR_COMMENTSIZE(P) + kZipCdirHdrMinSize) + +/* central directory file header */ +#define ZIP_CFILE_MAGIC(P) read32le(P) +#define ZIP_CFILE_VERSIONMADE(P) ((P)[4]) +#define ZIP_CFILE_FILEATTRCOMPAT(P) ((P)[5]) +#define ZIP_CFILE_VERSIONNEED(P) ((P)[6]) +#define ZIP_CFILE_OSNEED(P) ((P)[7]) +#define ZIP_CFILE_GENERALFLAG(P) read16le((P) + kZipCfileOffsetGeneralflag) +#define ZIP_CFILE_COMPRESSIONMETHOD(P) \ + read16le((P) + kZipCfileOffsetCompressionmethod) +#define ZIP_CFILE_LASTMODIFIEDTIME(P) \ + read16le((P) + kZipCfileOffsetLastmodifiedtime) /* @see DOS_TIME() */ +#define ZIP_CFILE_LASTMODIFIEDDATE(P) \ + read16le((P) + kZipCfileOffsetLastmodifieddate) /* @see DOS_DATE() */ +#define ZIP_CFILE_CRC32(P) read32le((P) + kZipCfileOffsetCrc32) +#define ZIP_CFILE_COMPRESSEDSIZE(P) READ32LE(P + kZipCfileOffsetCompressedsize) +#define ZIP_CFILE_UNCOMPRESSEDSIZE(P) read32le((P) + 24) +#define ZIP_CFILE_NAMESIZE(P) read16le((P) + 28) +#define ZIP_CFILE_EXTRASIZE(P) read16le((P) + 30) +#define ZIP_CFILE_COMMENTSIZE(P) read16le((P) + 32) +#define ZIP_CFILE_DISK(P) read16le((P) + 34) +#define ZIP_CFILE_INTERNALATTRIBUTES(P) read16le((P) + 36) +#define ZIP_CFILE_EXTERNALATTRIBUTES(P) \ + read32le((P) + kZipCfileOffsetExternalattributes) +#define ZIP_CFILE_OFFSET(P) read32le((P) + kZipCfileOffsetOffset) +#define ZIP_CFILE_NAME(P) ((const char *)(&(P)[46])) /* not nul-terminated */ +#define ZIP_CFILE_EXTRA(P) (&(P)[46 + ZIP_CFILE_NAMESIZE(P)]) +#define ZIP_CFILE_COMMENT(P) \ + (&(P)[46 + ZIP_CFILE_NAMESIZE(P) + ZIP_CFILE_EXTRASIZE(P)]) +#define ZIP_CFILE_HDRSIZE(P) \ + (ZIP_CFILE_NAMESIZE(P) + ZIP_CFILE_EXTRASIZE(P) + ZIP_CFILE_COMMENTSIZE(P) + \ + kZipCfileHdrMinSize) + +/* central directory file header */ +#define ZIP_LFILE_MAGIC(P) read32le(P) +#define ZIP_LFILE_VERSIONNEED(P) ((P)[4]) +#define ZIP_LFILE_OSNEED(P) ((P)[5]) +#define ZIP_LFILE_GENERALFLAG(P) read16le((P) + kZipLfileOffsetGeneralflag) +#define ZIP_LFILE_COMPRESSIONMETHOD(P) \ + read16le((P) + kZipLfileOffsetCompressionmethod) +#define ZIP_LFILE_LASTMODIFIEDTIME(P) \ + read16le((P) + kZipLfileOffsetLastmodifiedtime) /* @see DOS_TIME() */ +#define ZIP_LFILE_LASTMODIFIEDDATE(P) \ + read16le((P) + kZipLfileOffsetLastmodifieddate) /* @see DOS_DATE() */ +#define ZIP_LFILE_CRC32(P) read32le((P) + kZipLfileOffsetCrc32) +#define ZIP_LFILE_COMPRESSEDSIZE(P) \ + read32le((P) + kZipLfileOffsetCompressedsize) +#define ZIP_LFILE_UNCOMPRESSEDSIZE(P) read32le((P) + 22) +#define ZIP_LFILE_NAMESIZE(P) read16le((P) + 26) +#define ZIP_LFILE_EXTRASIZE(P) read16le((P) + 28) +#define ZIP_LFILE_NAME(P) ((const char *)(&(P)[30])) +#define ZIP_LFILE_EXTRA(P) (&(P)[30 + ZIP_LFILE_NAMESIZE(P)]) +#define ZIP_LFILE_HDRSIZE(P) \ + (ZIP_LFILE_NAMESIZE(P) + ZIP_LFILE_EXTRASIZE(P) + kZipLfileHdrMinSize) +#define ZIP_LFILE_CONTENT(P) ((P) + ZIP_LFILE_HDRSIZE(P)) +#define ZIP_LFILE_SIZE(P) (ZIP_LFILE_HDRSIZE(P) + ZIP_LFILE_COMPRESSEDSIZE(P)) + +#define ZIP_EXTRA_HEADERID(P) read16le(P) +#define ZIP_EXTRA_CONTENTSIZE(P) read16le((P) + 2) +#define ZIP_EXTRA_CONTENT(P) (&(P)[4]) +#define ZIP_EXTRA_SIZE(P) (ZIP_EXTRA_CONTENTSIZE(P) + kZipExtraHdrSize) + +uint8_t *zipfindcentraldir(const uint8_t *, size_t); + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_ZIP_H_ */ diff --git a/libc/zipos/close.c b/libc/zipos/close.c new file mode 100644 index 00000000..f70959f2 --- /dev/null +++ b/libc/zipos/close.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/internal.h" +#include "libc/mem/mem.h" +#include "libc/zipos/zipos.h" + +/** + * Closes compressed object. + * + * @param fd is vetted by close() + */ +int __zipos_close(struct ZiposHandle *h) { + if (h) { + munmap(h->map, h->mapsize); + free(h); + } + return 0; +} diff --git a/libc/zipos/find.c b/libc/zipos/find.c new file mode 100644 index 00000000..5b581861 --- /dev/null +++ b/libc/zipos/find.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/relocations.h" +#include "libc/assert.h" +#include "libc/runtime/rbx.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/zip.h" +#include "libc/zipos/zipos.h" + +ssize_t __zipos_find(const struct ZiposUri *name) { + size_t i, cf; + assert(ZIP_CDIR_MAGIC(__zip_end) == kZipCdirHdrMagic); + for (i = 0, cf = ZIP_CDIR_OFFSET(__zip_end); i < ZIP_CDIR_RECORDS(__zip_end); + ++i, cf += ZIP_CFILE_HDRSIZE(&_base[0] + cf)) { + assert(ZIP_CFILE_MAGIC(&_base[0] + cf) == kZipCfileHdrMagic); + if (name->len == ZIP_CFILE_NAMESIZE(&_base[0] + cf) && + memcmp(name->path, ZIP_CFILE_NAME(&_base[0] + cf), name->len) == 0) { + return cf; + } + } + return -1; +} diff --git a/libc/zipos/fstat.c b/libc/zipos/fstat.c new file mode 100644 index 00000000..d33e435a --- /dev/null +++ b/libc/zipos/fstat.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/zipos/zipos.h" + +/** + * Reads file metadata from αcτµαlly pδrταblε εxεcµταblε object store. + * + * @param uri is obtained via __zipos_parseuri() + * @asyncsignalsafe + */ +int __zipos_fstat(const struct ZiposHandle *h, struct stat *st) { + return __zipos_stat_impl(h->cfile, st); +} diff --git a/libc/zipos/open.c b/libc/zipos/open.c new file mode 100644 index 00000000..8e5d89bd --- /dev/null +++ b/libc/zipos/open.c @@ -0,0 +1,148 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/relocations.h" +#include "libc/assert.h" +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/sigset.h" +#include "libc/calls/struct/stat.h" +#include "libc/conv/sizemultiply.h" +#include "libc/dce.h" +#include "libc/macros.h" +#include "libc/mem/mem.h" +#include "libc/runtime/rbx.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/str/undeflate.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/prot.h" +#include "libc/sysv/consts/sig.h" +#include "libc/sysv/errfuns.h" +#include "libc/zip.h" +#include "libc/zipos/zipos.h" +#include "third_party/zlib/zlib.h" + +static int __zipos_inflate_fast(struct ZiposHandle *h, uint8_t *data, + size_t size) { + int rc; + z_stream zs; + zs.opaque = &h; + zs.next_in = data; + zs.avail_in = size; + zs.total_in = size; + zs.next_out = h->mem; + zs.avail_out = h->size; + zs.total_out = h->size; + zs.zfree = Z_NULL; + zs.zalloc = Z_NULL; + if (inflateInit2(&zs, -MAX_WBITS) == Z_OK) { + switch (inflate(&zs, Z_NO_FLUSH)) { + case Z_STREAM_END: + rc = 0; + break; + case Z_MEM_ERROR: + rc = enomem(); + break; + case Z_DATA_ERROR: + rc = eio(); + break; + case Z_NEED_DICT: + rc = enotsup(); /* TODO(jart): Z_NEED_DICT */ + break; + default: + abort(); + } + inflateEnd(&zs); + } else { + rc = enomem(); + } + return rc; +} + +static int __zipos_inflate_tiny(struct ZiposHandle *h, uint8_t *data, + size_t size) { + struct DeflateState ds; + return undeflate(h->mem, h->size, data, size, &ds) != -1 ? 0 : eio(); +} + +static int __zipos_load(size_t cf, unsigned flags, int mode) { + int fd; + size_t lf; + struct ZiposHandle *h; + lf = ZIP_CFILE_OFFSET(&_base[0] + cf); + assert(ZIP_LFILE_MAGIC(&_base[0] + lf) == kZipLfileHdrMagic); + assert(ZIP_LFILE_COMPRESSIONMETHOD(&_base[0] + lf) == kZipCompressionNone || + ZIP_LFILE_COMPRESSIONMETHOD(&_base[0] + lf) == kZipCompressionDeflate); + if ((fd = createfd()) == -1) return -1; + if (!(h = calloc(1, sizeof(*h)))) return -1; + h->cfile = cf; + if ((h->size = ZIP_LFILE_UNCOMPRESSEDSIZE(&_base[0] + lf))) { + if (ZIP_LFILE_COMPRESSIONMETHOD(&_base[0] + lf)) { + assert(ZIP_LFILE_COMPRESSEDSIZE(&_base[0] + lf)); + h->mapsize = ROUNDUP(h->size + FRAMESIZE, FRAMESIZE); + if ((h->map = mapanon(h->mapsize)) != MAP_FAILED) { + h->mem = h->map + FRAMESIZE / 2; + if ((IsTiny() ? __zipos_inflate_tiny : __zipos_inflate_fast)( + h, ZIP_LFILE_CONTENT(&_base[0] + lf), + ZIP_LFILE_COMPRESSEDSIZE(&_base[0] + lf)) == -1) { + fd = -1; + } + } else { + fd = -1; + } + } else { + h->mem = ZIP_LFILE_CONTENT(&_base[0] + lf); + } + } + if (!IsTiny() && fd != -1 && + crc32_z(0, h->mem, h->size) != ZIP_LFILE_CRC32(&_base[0] + lf)) { + fd = eio(); + } + if (fd != -1) { + g_fds.p[fd].kind = kFdZip; + g_fds.p[fd].handle = (intptr_t)h; + g_fds.p[fd].flags = flags; + } else { + __zipos_close(h); + } + return fd; +} + +/** + * Loads compressed file from αcτµαlly pδrταblε εxεcµταblε object store. + * + * @param uri is obtained via __zipos_parseuri() + * @asyncsignalsafe + */ +int __zipos_open(const struct ZiposUri *name, unsigned flags, int mode) { + int fd; + ssize_t cf; + sigset_t oldmask; + assert((flags & O_ACCMODE) == O_RDONLY); + sigprocmask(SIG_BLOCK, &kSigsetFull, &oldmask); + if ((cf = __zipos_find(name)) != -1) { + fd = __zipos_load(cf, flags, mode); + } else { + fd = enoent(); + } + sigprocmask(SIG_SETMASK, &oldmask, NULL); + return fd; +} diff --git a/libc/zipos/parseuri.c b/libc/zipos/parseuri.c new file mode 100644 index 00000000..b2dd794d --- /dev/null +++ b/libc/zipos/parseuri.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" +#include "libc/zipos/zipos.h" + +const char kZiposSchemePrefix[4] = "zip:"; + +/** + * Extracts information about ZIP URI if it is one. + */ +ssize_t __zipos_parseuri(const char *uri, struct ZiposUri *out) { + size_t len; + if ((len = strlen(uri)) >= sizeof(kZiposSchemePrefix) && len < PATH_MAX && + memcmp(uri, kZiposSchemePrefix, sizeof(kZiposSchemePrefix)) == 0) { + out->path = uri + sizeof(kZiposSchemePrefix); + return (out->len = len - sizeof(kZiposSchemePrefix)); + } else { + return -1; + } +} diff --git a/libc/zipos/read.c b/libc/zipos/read.c new file mode 100644 index 00000000..4120af07 --- /dev/null +++ b/libc/zipos/read.c @@ -0,0 +1,44 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/bits/safemacros.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/iovec.h" +#include "libc/str/str.h" +#include "libc/zipos/zipos.h" + +/** + * Reads data from zip store object. + * + * @return [1..size] bytes on success, 0 on EOF, or -1 w/ errno; with + * exception of size==0, in which case return zero means no error + * @asyncsignalsafe + */ +ssize_t __zipos_read(struct ZiposHandle *h, const struct iovec *iov, + size_t iovlen, ssize_t opt_offset) { + size_t i, b, x, y; + x = y = opt_offset != -1 ? opt_offset : h->pos; + for (i = 0; i < iovlen && y < h->size; ++i, y += b) { + b = min(iov[i].iov_len, h->size - y); + memcpy(iov[i].iov_base, h->mem + y, b); + } + if (opt_offset != -1) h->pos = y; + return y - x; +} diff --git a/libc/zipos/stat-impl.c b/libc/zipos/stat-impl.c new file mode 100644 index 00000000..9f082085 --- /dev/null +++ b/libc/zipos/stat-impl.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/calls/struct/stat.h" +#include "libc/runtime/rbx.h" +#include "libc/str/str.h" +#include "libc/zip.h" +#include "libc/zipos/zipos.h" + +int __zipos_stat_impl(size_t cf, struct stat *st) { + memset(st, 0, sizeof(*st)); + if (ZIP_CFILE_FILEATTRCOMPAT(&_base[0] + cf) == kZipOsUnix) { + st->st_mode = ZIP_CFILE_EXTERNALATTRIBUTES(&_base[0] + cf) >> 16; + } else { + st->st_mode = 0100644; + } + st->st_size = ZIP_CFILE_UNCOMPRESSEDSIZE(&_base[0] + cf); + st->st_blocks = roundup(ZIP_CFILE_COMPRESSEDSIZE(&_base[0] + cf), 512) / 512; + return 0; +} diff --git a/libc/zipos/stat.c b/libc/zipos/stat.c new file mode 100644 index 00000000..8586dcba --- /dev/null +++ b/libc/zipos/stat.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/sysv/errfuns.h" +#include "libc/zipos/zipos.h" + +/** + * Reads file metadata from αcτµαlly pδrταblε εxεcµταblε object store. + * + * @param uri is obtained via __zipos_parseuri() + * @asyncsignalsafe + */ +int __zipos_stat(const struct ZiposUri *name, struct stat *st) { + ssize_t cf; + if ((cf = __zipos_find(name)) != -1) { + return __zipos_stat_impl(cf, st); + } else { + return enoent(); + } +} diff --git a/libc/zipos/zipcentraldir.S b/libc/zipos/zipcentraldir.S new file mode 100644 index 00000000..9acf3cbe --- /dev/null +++ b/libc/zipos/zipcentraldir.S @@ -0,0 +1,58 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/relocations.h" +#include "libc/zip.h" +#include "libc/macros.h" + +/ ZIP Central Directory. + .section .piro.data.sort.zip.3,"a",@progbits + .hidden __zip_start + .globl __zip_start + .type __zip_start,@object + .align kZipCdirAlign +__zip_start: + .previous/* + ... + decentralized content + ... + */.section .piro.data.sort.zip.5,"a",@progbits + .align kZipCdirAlign +__zip_end: + .long kZipCdirHdrMagic # magic + .short 0 # disk + .short 0 # starting disk + .short v_zip_records # records on disk + .short v_zip_records # records + .long v_zip_cdirsize # size of central directory + .long RVA(__zip_start) # central directory offset + .short v_zip_commentsize # comment size + .endobj __zip_end,globl,hidden + .weak v_zip_records + .weak v_zip_cdirsize + .weak v_zip_commentsize + .previous + + yoink __zipos_close + yoink __zipos_fstat + yoink __zipos_open + yoink __zipos_parseuri + yoink __zipos_read + yoink __zipos_stat + yoink __FILE__ diff --git a/libc/zipos/zipos.h b/libc/zipos/zipos.h new file mode 100644 index 00000000..6ca3661f --- /dev/null +++ b/libc/zipos/zipos.h @@ -0,0 +1,39 @@ +#ifndef COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_ +#define COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct stat; +struct iovec; + +struct ZiposUri { + const char *path; + size_t len; +}; + +struct ZiposHandle { + uint8_t *mem; /* deflated file base */ + size_t size; /* byte length of file */ + size_t pos; /* read/write byte offset state */ + uint32_t cfile; /* central directory entry rva */ + uint8_t *map; + size_t mapsize; +}; + +extern const char kZiposSchemePrefix[4]; + +ssize_t __zipos_parseuri(const char *, struct ZiposUri *); +ssize_t __zipos_find(const struct ZiposUri *); +int __zipos_close(struct ZiposHandle *); +int __zipos_open(const struct ZiposUri *, unsigned, int); +int __zipos_stat(const struct ZiposUri *, struct stat *); +int __zipos_fstat(const struct ZiposHandle *, struct stat *); +int __zipos_stat_impl(size_t, struct stat *); +ssize_t __zipos_read(struct ZiposHandle *, const struct iovec *, size_t, + ssize_t); +ssize_t __zipos_write(struct ZiposHandle *, const struct iovec *, size_t, + ssize_t); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_ */ diff --git a/libc/zipos/zipos.mk b/libc/zipos/zipos.mk new file mode 100644 index 00000000..49632418 --- /dev/null +++ b/libc/zipos/zipos.mk @@ -0,0 +1,58 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += LIBC_ZIPOS + +LIBC_ZIPOS_ARTIFACTS += LIBC_ZIPOS_A +LIBC_ZIPOS = $(LIBC_ZIPOS_A_DEPS) $(LIBC_ZIPOS_A) +LIBC_ZIPOS_A = o/$(MODE)/libc/zipos/zipos.a +LIBC_ZIPOS_A_FILES := $(wildcard libc/zipos/*) +LIBC_ZIPOS_A_HDRS = $(filter %.h,$(LIBC_ZIPOS_A_FILES)) +LIBC_ZIPOS_A_SRCS_S = $(filter %.S,$(LIBC_ZIPOS_A_FILES)) +LIBC_ZIPOS_A_SRCS_C = $(filter %.c,$(LIBC_ZIPOS_A_FILES)) + +LIBC_ZIPOS_A_SRCS = \ + $(LIBC_ZIPOS_A_SRCS_S) \ + $(LIBC_ZIPOS_A_SRCS_C) + +LIBC_ZIPOS_A_OBJS = \ + $(LIBC_ZIPOS_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(LIBC_ZIPOS_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(LIBC_ZIPOS_A_SRCS_C:%.c=o/$(MODE)/%.o) + +LIBC_ZIPOS_A_CHECKS = \ + $(LIBC_ZIPOS_A).pkg \ + $(LIBC_ZIPOS_A_HDRS:%=o/$(MODE)/%.ok) + +LIBC_ZIPOS_A_DIRECTDEPS = \ + LIBC_CALLS \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_SYSV \ + LIBC_STR \ + LIBC_STUBS \ + THIRD_PARTY_ZLIB + +LIBC_ZIPOS_A_DEPS := \ + $(call uniq,$(foreach zipos,$(LIBC_ZIPOS_A_DIRECTDEPS),$($(zipos)))) + +$(LIBC_ZIPOS_A):libc/zipos/ \ + $(LIBC_ZIPOS_A).pkg \ + $(LIBC_ZIPOS_A_OBJS) + +$(LIBC_ZIPOS_A).pkg: \ + $(LIBC_ZIPOS_A_OBJS) \ + $(foreach zipos,$(LIBC_ZIPOS_A_DIRECTDEPS),$($(zipos)_A).pkg) + +LIBC_ZIPOS_LIBS = $(foreach zipos,$(LIBC_ZIPOS_ARTIFACTS),$($(zipos))) +LIBC_ZIPOS_SRCS = $(foreach zipos,$(LIBC_ZIPOS_ARTIFACTS),$($(zipos)_SRCS)) +LIBC_ZIPOS_HDRS = $(foreach zipos,$(LIBC_ZIPOS_ARTIFACTS),$($(zipos)_HDRS)) +LIBC_ZIPOS_BINS = $(foreach zipos,$(LIBC_ZIPOS_ARTIFACTS),$($(zipos)_BINS)) +LIBC_ZIPOS_CHECKS = $(foreach zipos,$(LIBC_ZIPOS_ARTIFACTS),$($(zipos)_CHECKS)) +LIBC_ZIPOS_OBJS = $(foreach zipos,$(LIBC_ZIPOS_ARTIFACTS),$($(zipos)_OBJS)) +LIBC_ZIPOS_TESTS = $(foreach zipos,$(LIBC_ZIPOS_ARTIFACTS),$($(zipos)_TESTS)) +$(LIBC_ZIPOS_OBJS): $(BUILD_FILES) libc/zipos/zipos.mk + +.PHONY: o/$(MODE)/libc/zipos +o/$(MODE)/libc/zipos: $(LIBC_ZIPOS_CHECKS) diff --git a/net/http/clearhttprequest.c b/net/http/clearhttprequest.c new file mode 100644 index 00000000..10798e27 --- /dev/null +++ b/net/http/clearhttprequest.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/bits/bits.h" +#include "libc/bits/pushpop.h" +#include "net/http/http.h" + +void clearhttprequest(struct HttpRequest *req) { + req->uri.i = pushpop(0); + req->method.i = pushpop(0); + req->version.i = pushpop(0); + req->scratch.i = pushpop(0); + critbit0_clear(&req->headers); +} diff --git a/net/http/csscolor.h b/net/http/csscolor.h new file mode 100644 index 00000000..34b5ef16 --- /dev/null +++ b/net/http/csscolor.h @@ -0,0 +1,662 @@ +#ifndef COSMOPOLITAN_NET_HTTP_CSSCOLOR_H_ +#define COSMOPOLITAN_NET_HTTP_CSSCOLOR_H_ + +#define ALICEBLUE 0xFFFFF8F0u +#define ANTIQUEWHITE 0xFFD7EBFAu +#define ANTIQUEWHITE1 0xFFDBEFFFu +#define ANTIQUEWHITE2 0xFFCCDFEEu +#define ANTIQUEWHITE3 0xFFB0C0CDu +#define ANTIQUEWHITE4 0xFF78838Bu +#define AQUAMARINE 0xFFD4FF7Fu +#define AQUAMARINE1 0xFFD4FF7Fu +#define AQUAMARINE2 0xFFC6EE76u +#define AQUAMARINE3 0xFFAACD66u +#define AQUAMARINE4 0xFF748B45u +#define AZURE 0xFFFFFFF0u +#define AZURE1 0xFFFFFFF0u +#define AZURE2 0xFFEEEEE0u +#define AZURE3 0xFFCDCDC1u +#define AZURE4 0xFF8B8B83u +#define BEIGE 0xFFDCF5F5u +#define BISQUE 0xFFC4E4FFu +#define BISQUE1 0xFFC4E4FFu +#define BISQUE2 0xFFB7D5EEu +#define BISQUE3 0xFF9EB7CDu +#define BISQUE4 0xFF6B7D8Bu +#define BLACK 0xFF000000u +#define BLANCHEDALMOND 0xFFCDEBFFu +#define BLUE 0xFFFF0000u +#define BLUE1 0xFFFF0000u +#define BLUE2 0xFFEE0000u +#define BLUE3 0xFFCD0000u +#define BLUE4 0xFF8B0000u +#define BLUEVIOLET 0xFFE22B8Au +#define BROWN 0xFF2A2AA5u +#define BROWN1 0xFF4040FFu +#define BROWN2 0xFF3B3BEEu +#define BROWN3 0xFF3333CDu +#define BROWN4 0xFF23238Bu +#define BURLYWOOD 0xFF87B8DEu +#define BURLYWOOD1 0xFF9BD3FFu +#define BURLYWOOD2 0xFF91C5EEu +#define BURLYWOOD3 0xFF7DAACDu +#define BURLYWOOD4 0xFF55738Bu +#define CADETBLUE 0xFFA09E5Fu +#define CADETBLUE1 0xFFFFF598u +#define CADETBLUE2 0xFFEEE58Eu +#define CADETBLUE3 0xFFCDC57Au +#define CADETBLUE4 0xFF8B8653u +#define CHARTREUSE 0xFF00FF7Fu +#define CHARTREUSE1 0xFF00FF7Fu +#define CHARTREUSE2 0xFF00EE76u +#define CHARTREUSE3 0xFF00CD66u +#define CHARTREUSE4 0xFF008B45u +#define CHOCOLATE 0xFF1E69D2u +#define CHOCOLATE1 0xFF247FFFu +#define CHOCOLATE2 0xFF2176EEu +#define CHOCOLATE3 0xFF1D66CDu +#define CHOCOLATE4 0xFF13458Bu +#define CORAL 0xFF507FFFu +#define CORAL1 0xFF5672FFu +#define CORAL2 0xFF506AEEu +#define CORAL3 0xFF455BCDu +#define CORAL4 0xFF2F3E8Bu +#define CORNFLOWERBLUE 0xFFED9564u +#define CORNSILK 0xFFDCF8FFu +#define CORNSILK1 0xFFDCF8FFu +#define CORNSILK2 0xFFCDE8EEu +#define CORNSILK3 0xFFB1C8CDu +#define CORNSILK4 0xFF78888Bu +#define CYAN 0xFFFFFF00u +#define CYAN1 0xFFFFFF00u +#define CYAN2 0xFFEEEE00u +#define CYAN3 0xFFCDCD00u +#define CYAN4 0xFF8B8B00u +#define DARKBLUE 0xFF8B0000u +#define DARKCYAN 0xFF8B8B00u +#define DARKGOLDENROD 0xFF0B86B8u +#define DARKGOLDENROD1 0xFF0FB9FFu +#define DARKGOLDENROD2 0xFF0EADEEu +#define DARKGOLDENROD3 0xFF0C95CDu +#define DARKGOLDENROD4 0xFF08658Bu +#define DARKGRAY 0xFFA9A9A9u +#define DARKGREEN 0xFF006400u +#define DARKGREY 0xFFA9A9A9u +#define DARKKHAKI 0xFF6BB7BDu +#define DARKMAGENTA 0xFF8B008Bu +#define DARKOLIVEGREEN 0xFF2F6B55u +#define DARKOLIVEGREEN1 0xFF70FFCAu +#define DARKOLIVEGREEN2 0xFF68EEBCu +#define DARKOLIVEGREEN3 0xFF5ACDA2u +#define DARKOLIVEGREEN4 0xFF3D8B6Eu +#define DARKORANGE 0xFF008CFFu +#define DARKORANGE1 0xFF007FFFu +#define DARKORANGE2 0xFF0076EEu +#define DARKORANGE3 0xFF0066CDu +#define DARKORANGE4 0xFF00458Bu +#define DARKORCHID 0xFFCC3299u +#define DARKORCHID1 0xFFFF3EBFu +#define DARKORCHID2 0xFFEE3AB2u +#define DARKORCHID3 0xFFCD329Au +#define DARKORCHID4 0xFF8B2268u +#define DARKRED 0xFF00008Bu +#define DARKSALMON 0xFF7A96E9u +#define DARKSEAGREEN 0xFF8FBC8Fu +#define DARKSEAGREEN1 0xFFC1FFC1u +#define DARKSEAGREEN2 0xFFB4EEB4u +#define DARKSEAGREEN3 0xFF9BCD9Bu +#define DARKSEAGREEN4 0xFF698B69u +#define DARKSLATEBLUE 0xFF8B3D48u +#define DARKSLATEGRAY 0xFF4F4F2Fu +#define DARKSLATEGRAY1 0xFFFFFF97u +#define DARKSLATEGRAY2 0xFFEEEE8Du +#define DARKSLATEGRAY3 0xFFCDCD79u +#define DARKSLATEGRAY4 0xFF8B8B52u +#define DARKSLATEGREY 0xFF4F4F2Fu +#define DARKTURQUOISE 0xFFD1CE00u +#define DARKVIOLET 0xFFD30094u +#define DEEPPINK 0xFF9314FFu +#define DEEPPINK1 0xFF9314FFu +#define DEEPPINK2 0xFF8912EEu +#define DEEPPINK3 0xFF7610CDu +#define DEEPPINK4 0xFF500A8Bu +#define DEEPSKYBLUE 0xFFFFBF00u +#define DEEPSKYBLUE1 0xFFFFBF00u +#define DEEPSKYBLUE2 0xFFEEB200u +#define DEEPSKYBLUE3 0xFFCD9A00u +#define DEEPSKYBLUE4 0xFF8B6800u +#define DIMGRAY 0xFF696969u +#define DIMGREY 0xFF696969u +#define DODGERBLUE 0xFFFF901Eu +#define DODGERBLUE1 0xFFFF901Eu +#define DODGERBLUE2 0xFFEE861Cu +#define DODGERBLUE3 0xFFCD7418u +#define DODGERBLUE4 0xFF8B4E10u +#define FIREBRICK 0xFF2222B2u +#define FIREBRICK1 0xFF3030FFu +#define FIREBRICK2 0xFF2C2CEEu +#define FIREBRICK3 0xFF2626CDu +#define FIREBRICK4 0xFF1A1A8Bu +#define FLORALWHITE 0xFFF0FAFFu +#define FORESTGREEN 0xFF228B22u +#define GAINSBORO 0xFFDCDCDCu +#define GHOSTWHITE 0xFFFFF8F8u +#define GOLD 0xFF00D7FFu +#define GOLD1 0xFF00D7FFu +#define GOLD2 0xFF00C9EEu +#define GOLD3 0xFF00ADCDu +#define GOLD4 0xFF00758Bu +#define GOLDENROD 0xFF20A5DAu +#define GOLDENROD1 0xFF25C1FFu +#define GOLDENROD2 0xFF22B4EEu +#define GOLDENROD3 0xFF1D9BCDu +#define GOLDENROD4 0xFF14698Bu +#define GRAY 0xFFBEBEBEu +#define GRAY0 0xFF000000u +#define GRAY1 0xFF030303u +#define GRAY10 0xFF1A1A1Au +#define GRAY100 0xFFFFFFFFu +#define GRAY11 0xFF1C1C1Cu +#define GRAY12 0xFF1F1F1Fu +#define GRAY13 0xFF212121u +#define GRAY14 0xFF242424u +#define GRAY15 0xFF262626u +#define GRAY16 0xFF292929u +#define GRAY17 0xFF2B2B2Bu +#define GRAY18 0xFF2E2E2Eu +#define GRAY19 0xFF303030u +#define GRAY2 0xFF050505u +#define GRAY20 0xFF333333u +#define GRAY21 0xFF363636u +#define GRAY22 0xFF383838u +#define GRAY23 0xFF3B3B3Bu +#define GRAY24 0xFF3D3D3Du +#define GRAY25 0xFF404040u +#define GRAY26 0xFF424242u +#define GRAY27 0xFF454545u +#define GRAY28 0xFF474747u +#define GRAY29 0xFF4A4A4Au +#define GRAY3 0xFF080808u +#define GRAY30 0xFF4D4D4Du +#define GRAY31 0xFF4F4F4Fu +#define GRAY32 0xFF525252u +#define GRAY33 0xFF545454u +#define GRAY34 0xFF575757u +#define GRAY35 0xFF595959u +#define GRAY36 0xFF5C5C5Cu +#define GRAY37 0xFF5E5E5Eu +#define GRAY38 0xFF616161u +#define GRAY39 0xFF636363u +#define GRAY4 0xFF0A0A0Au +#define GRAY40 0xFF666666u +#define GRAY41 0xFF696969u +#define GRAY42 0xFF6B6B6Bu +#define GRAY43 0xFF6E6E6Eu +#define GRAY44 0xFF707070u +#define GRAY45 0xFF737373u +#define GRAY46 0xFF757575u +#define GRAY47 0xFF787878u +#define GRAY48 0xFF7A7A7Au +#define GRAY49 0xFF7D7D7Du +#define GRAY5 0xFF0D0D0Du +#define GRAY50 0xFF7F7F7Fu +#define GRAY51 0xFF828282u +#define GRAY52 0xFF858585u +#define GRAY53 0xFF878787u +#define GRAY54 0xFF8A8A8Au +#define GRAY55 0xFF8C8C8Cu +#define GRAY56 0xFF8F8F8Fu +#define GRAY57 0xFF919191u +#define GRAY58 0xFF949494u +#define GRAY59 0xFF969696u +#define GRAY6 0xFF0F0F0Fu +#define GRAY60 0xFF999999u +#define GRAY61 0xFF9C9C9Cu +#define GRAY62 0xFF9E9E9Eu +#define GRAY63 0xFFA1A1A1u +#define GRAY64 0xFFA3A3A3u +#define GRAY65 0xFFA6A6A6u +#define GRAY66 0xFFA8A8A8u +#define GRAY67 0xFFABABABu +#define GRAY68 0xFFADADADu +#define GRAY69 0xFFB0B0B0u +#define GRAY7 0xFF121212u +#define GRAY70 0xFFB3B3B3u +#define GRAY71 0xFFB5B5B5u +#define GRAY72 0xFFB8B8B8u +#define GRAY73 0xFFBABABAu +#define GRAY74 0xFFBDBDBDu +#define GRAY75 0xFFBFBFBFu +#define GRAY76 0xFFC2C2C2u +#define GRAY77 0xFFC4C4C4u +#define GRAY78 0xFFC7C7C7u +#define GRAY79 0xFFC9C9C9u +#define GRAY8 0xFF141414u +#define GRAY80 0xFFCCCCCCu +#define GRAY81 0xFFCFCFCFu +#define GRAY82 0xFFD1D1D1u +#define GRAY83 0xFFD4D4D4u +#define GRAY84 0xFFD6D6D6u +#define GRAY85 0xFFD9D9D9u +#define GRAY86 0xFFDBDBDBu +#define GRAY87 0xFFDEDEDEu +#define GRAY88 0xFFE0E0E0u +#define GRAY89 0xFFE3E3E3u +#define GRAY9 0xFF171717u +#define GRAY90 0xFFE5E5E5u +#define GRAY91 0xFFE8E8E8u +#define GRAY92 0xFFEBEBEBu +#define GRAY93 0xFFEDEDEDu +#define GRAY94 0xFFF0F0F0u +#define GRAY95 0xFFF2F2F2u +#define GRAY96 0xFFF5F5F5u +#define GRAY97 0xFFF7F7F7u +#define GRAY98 0xFFFAFAFAu +#define GRAY99 0xFFFCFCFCu +#define GREEN 0xFF00FF00u +#define GREEN1 0xFF00FF00u +#define GREEN2 0xFF00EE00u +#define GREEN3 0xFF00CD00u +#define GREEN4 0xFF008B00u +#define GREENYELLOW 0xFF2FFFADu +#define GREY 0xFFBEBEBEu +#define GREY0 0xFF000000u +#define GREY1 0xFF030303u +#define GREY10 0xFF1A1A1Au +#define GREY100 0xFFFFFFFFu +#define GREY11 0xFF1C1C1Cu +#define GREY12 0xFF1F1F1Fu +#define GREY13 0xFF212121u +#define GREY14 0xFF242424u +#define GREY15 0xFF262626u +#define GREY16 0xFF292929u +#define GREY17 0xFF2B2B2Bu +#define GREY18 0xFF2E2E2Eu +#define GREY19 0xFF303030u +#define GREY2 0xFF050505u +#define GREY20 0xFF333333u +#define GREY21 0xFF363636u +#define GREY22 0xFF383838u +#define GREY23 0xFF3B3B3Bu +#define GREY24 0xFF3D3D3Du +#define GREY25 0xFF404040u +#define GREY26 0xFF424242u +#define GREY27 0xFF454545u +#define GREY28 0xFF474747u +#define GREY29 0xFF4A4A4Au +#define GREY3 0xFF080808u +#define GREY30 0xFF4D4D4Du +#define GREY31 0xFF4F4F4Fu +#define GREY32 0xFF525252u +#define GREY33 0xFF545454u +#define GREY34 0xFF575757u +#define GREY35 0xFF595959u +#define GREY36 0xFF5C5C5Cu +#define GREY37 0xFF5E5E5Eu +#define GREY38 0xFF616161u +#define GREY39 0xFF636363u +#define GREY4 0xFF0A0A0Au +#define GREY40 0xFF666666u +#define GREY41 0xFF696969u +#define GREY42 0xFF6B6B6Bu +#define GREY43 0xFF6E6E6Eu +#define GREY44 0xFF707070u +#define GREY45 0xFF737373u +#define GREY46 0xFF757575u +#define GREY47 0xFF787878u +#define GREY48 0xFF7A7A7Au +#define GREY49 0xFF7D7D7Du +#define GREY5 0xFF0D0D0Du +#define GREY50 0xFF7F7F7Fu +#define GREY51 0xFF828282u +#define GREY52 0xFF858585u +#define GREY53 0xFF878787u +#define GREY54 0xFF8A8A8Au +#define GREY55 0xFF8C8C8Cu +#define GREY56 0xFF8F8F8Fu +#define GREY57 0xFF919191u +#define GREY58 0xFF949494u +#define GREY59 0xFF969696u +#define GREY6 0xFF0F0F0Fu +#define GREY60 0xFF999999u +#define GREY61 0xFF9C9C9Cu +#define GREY62 0xFF9E9E9Eu +#define GREY63 0xFFA1A1A1u +#define GREY64 0xFFA3A3A3u +#define GREY65 0xFFA6A6A6u +#define GREY66 0xFFA8A8A8u +#define GREY67 0xFFABABABu +#define GREY68 0xFFADADADu +#define GREY69 0xFFB0B0B0u +#define GREY7 0xFF121212u +#define GREY70 0xFFB3B3B3u +#define GREY71 0xFFB5B5B5u +#define GREY72 0xFFB8B8B8u +#define GREY73 0xFFBABABAu +#define GREY74 0xFFBDBDBDu +#define GREY75 0xFFBFBFBFu +#define GREY76 0xFFC2C2C2u +#define GREY77 0xFFC4C4C4u +#define GREY78 0xFFC7C7C7u +#define GREY79 0xFFC9C9C9u +#define GREY8 0xFF141414u +#define GREY80 0xFFCCCCCCu +#define GREY81 0xFFCFCFCFu +#define GREY82 0xFFD1D1D1u +#define GREY83 0xFFD4D4D4u +#define GREY84 0xFFD6D6D6u +#define GREY85 0xFFD9D9D9u +#define GREY86 0xFFDBDBDBu +#define GREY87 0xFFDEDEDEu +#define GREY88 0xFFE0E0E0u +#define GREY89 0xFFE3E3E3u +#define GREY9 0xFF171717u +#define GREY90 0xFFE5E5E5u +#define GREY91 0xFFE8E8E8u +#define GREY92 0xFFEBEBEBu +#define GREY93 0xFFEDEDEDu +#define GREY94 0xFFF0F0F0u +#define GREY95 0xFFF2F2F2u +#define GREY96 0xFFF5F5F5u +#define GREY97 0xFFF7F7F7u +#define GREY98 0xFFFAFAFAu +#define GREY99 0xFFFCFCFCu +#define HONEYDEW 0xFFF0FFF0u +#define HONEYDEW1 0xFFF0FFF0u +#define HONEYDEW2 0xFFE0EEE0u +#define HONEYDEW3 0xFFC1CDC1u +#define HONEYDEW4 0xFF838B83u +#define HOTPINK 0xFFB469FFu +#define HOTPINK1 0xFFB46EFFu +#define HOTPINK2 0xFFA76AEEu +#define HOTPINK3 0xFF9060CDu +#define HOTPINK4 0xFF623A8Bu +#define INDIANRED 0xFF5C5CCDu +#define INDIANRED1 0xFF6A6AFFu +#define INDIANRED2 0xFF6363EEu +#define INDIANRED3 0xFF5555CDu +#define INDIANRED4 0xFF3A3A8Bu +#define IVORY 0xFFF0FFFFu +#define IVORY1 0xFFF0FFFFu +#define IVORY2 0xFFE0EEEEu +#define IVORY3 0xFFC1CDCDu +#define IVORY4 0xFF838B8Bu +#define KHAKI 0xFF8CE6F0u +#define KHAKI1 0xFF8FF6FFu +#define KHAKI2 0xFF85E6EEu +#define KHAKI3 0xFF73C6CDu +#define KHAKI4 0xFF4E868Bu +#define LAVENDER 0xFFFAE6E6u +#define LAVENDERBLUSH 0xFFF5F0FFu +#define LAVENDERBLUSH1 0xFFF5F0FFu +#define LAVENDERBLUSH2 0xFFE5E0EEu +#define LAVENDERBLUSH3 0xFFC5C1CDu +#define LAVENDERBLUSH4 0xFF86838Bu +#define LAWNGREEN 0xFF00FC7Cu +#define LEMONCHIFFON 0xFFCDFAFFu +#define LEMONCHIFFON1 0xFFCDFAFFu +#define LEMONCHIFFON2 0xFFBFE9EEu +#define LEMONCHIFFON3 0xFFA5C9CDu +#define LEMONCHIFFON4 0xFF70898Bu +#define LIGHTBLUE 0xFFE6D8ADu +#define LIGHTBLUE1 0xFFFFEFBFu +#define LIGHTBLUE2 0xFFEEDFB2u +#define LIGHTBLUE3 0xFFCDC09Au +#define LIGHTBLUE4 0xFF8B8368u +#define LIGHTCORAL 0xFF8080F0u +#define LIGHTCYAN 0xFFFFFFE0u +#define LIGHTCYAN1 0xFFFFFFE0u +#define LIGHTCYAN2 0xFFEEEED1u +#define LIGHTCYAN3 0xFFCDCDB4u +#define LIGHTCYAN4 0xFF8B8B7Au +#define LIGHTGOLDENROD 0xFF82DDEEu +#define LIGHTGOLDENROD1 0xFF8BECFFu +#define LIGHTGOLDENROD2 0xFF82DCEEu +#define LIGHTGOLDENROD3 0xFF70BECDu +#define LIGHTGOLDENROD4 0xFF4C818Bu +#define LIGHTGOLDENRODYELLOW 0xFFD2FAFAu +#define LIGHTGRAY 0xFFD3D3D3u +#define LIGHTGREEN 0xFF90EE90u +#define LIGHTGREY 0xFFD3D3D3u +#define LIGHTPINK 0xFFC1B6FFu +#define LIGHTPINK1 0xFFB9AEFFu +#define LIGHTPINK2 0xFFADA2EEu +#define LIGHTPINK3 0xFF958CCDu +#define LIGHTPINK4 0xFF655F8Bu +#define LIGHTSALMON 0xFF7AA0FFu +#define LIGHTSALMON1 0xFF7AA0FFu +#define LIGHTSALMON2 0xFF7295EEu +#define LIGHTSALMON3 0xFF6281CDu +#define LIGHTSALMON4 0xFF42578Bu +#define LIGHTSEAGREEN 0xFFAAB220u +#define LIGHTSKYBLUE 0xFFFACE87u +#define LIGHTSKYBLUE1 0xFFFFE2B0u +#define LIGHTSKYBLUE2 0xFFEED3A4u +#define LIGHTSKYBLUE3 0xFFCDB68Du +#define LIGHTSKYBLUE4 0xFF8B7B60u +#define LIGHTSLATEBLUE 0xFFFF7084u +#define LIGHTSLATEGRAY 0xFF998877u +#define LIGHTSLATEGREY 0xFF998877u +#define LIGHTSTEELBLUE 0xFFDEC4B0u +#define LIGHTSTEELBLUE1 0xFFFFE1CAu +#define LIGHTSTEELBLUE2 0xFFEED2BCu +#define LIGHTSTEELBLUE3 0xFFCDB5A2u +#define LIGHTSTEELBLUE4 0xFF8B7B6Eu +#define LIGHTYELLOW 0xFFE0FFFFu +#define LIGHTYELLOW1 0xFFE0FFFFu +#define LIGHTYELLOW2 0xFFD1EEEEu +#define LIGHTYELLOW3 0xFFB4CDCDu +#define LIGHTYELLOW4 0xFF7A8B8Bu +#define LIMEGREEN 0xFF32CD32u +#define LINEN 0xFFE6F0FAu +#define MAGENTA 0xFFFF00FFu +#define MAGENTA1 0xFFFF00FFu +#define MAGENTA2 0xFFEE00EEu +#define MAGENTA3 0xFFCD00CDu +#define MAGENTA4 0xFF8B008Bu +#define MAROON 0xFF6030B0u +#define MAROON1 0xFFB334FFu +#define MAROON2 0xFFA730EEu +#define MAROON3 0xFF9029CDu +#define MAROON4 0xFF621C8Bu +#define MEDIUMAQUAMARINE 0xFFAACD66u +#define MEDIUMBLUE 0xFFCD0000u +#define MEDIUMORCHID 0xFFD355BAu +#define MEDIUMORCHID1 0xFFFF66E0u +#define MEDIUMORCHID2 0xFFEE5FD1u +#define MEDIUMORCHID3 0xFFCD52B4u +#define MEDIUMORCHID4 0xFF8B377Au +#define MEDIUMPURPLE 0xFFDB7093u +#define MEDIUMPURPLE1 0xFFFF82ABu +#define MEDIUMPURPLE2 0xFFEE799Fu +#define MEDIUMPURPLE3 0xFFCD6889u +#define MEDIUMPURPLE4 0xFF8B475Du +#define MEDIUMSEAGREEN 0xFF71B33Cu +#define MEDIUMSLATEBLUE 0xFFEE687Bu +#define MEDIUMSPRINGGREEN 0xFF9AFA00u +#define MEDIUMTURQUOISE 0xFFCCD148u +#define MEDIUMVIOLETRED 0xFF8515C7u +#define MIDNIGHTBLUE 0xFF701919u +#define MINTCREAM 0xFFFAFFF5u +#define MISTYROSE 0xFFE1E4FFu +#define MISTYROSE1 0xFFE1E4FFu +#define MISTYROSE2 0xFFD2D5EEu +#define MISTYROSE3 0xFFB5B7CDu +#define MISTYROSE4 0xFF7B7D8Bu +#define MOCCASIN 0xFFB5E4FFu +#define NAVAJOWHITE 0xFFADDEFFu +#define NAVAJOWHITE1 0xFFADDEFFu +#define NAVAJOWHITE2 0xFFA1CFEEu +#define NAVAJOWHITE3 0xFF8BB3CDu +#define NAVAJOWHITE4 0xFF5E798Bu +#define NAVY 0xFF800000u +#define NAVYBLUE 0xFF800000u +#define OLDLACE 0xFFE6F5FDu +#define OLIVEDRAB 0xFF238E6Bu +#define OLIVEDRAB1 0xFF3EFFC0u +#define OLIVEDRAB2 0xFF3AEEB3u +#define OLIVEDRAB3 0xFF32CD9Au +#define OLIVEDRAB4 0xFF228B69u +#define ORANGE 0xFF00A5FFu +#define ORANGE1 0xFF00A5FFu +#define ORANGE2 0xFF009AEEu +#define ORANGE3 0xFF0085CDu +#define ORANGE4 0xFF005A8Bu +#define ORANGERED 0xFF0045FFu +#define ORANGERED1 0xFF0045FFu +#define ORANGERED2 0xFF0040EEu +#define ORANGERED3 0xFF0037CDu +#define ORANGERED4 0xFF00258Bu +#define ORCHID 0xFFD670DAu +#define ORCHID1 0xFFFA83FFu +#define ORCHID2 0xFFE97AEEu +#define ORCHID3 0xFFC969CDu +#define ORCHID4 0xFF89478Bu +#define PALEGOLDENROD 0xFFAAE8EEu +#define PALEGREEN 0xFF98FB98u +#define PALEGREEN1 0xFF9AFF9Au +#define PALEGREEN2 0xFF90EE90u +#define PALEGREEN3 0xFF7CCD7Cu +#define PALEGREEN4 0xFF548B54u +#define PALETURQUOISE 0xFFEEEEAFu +#define PALETURQUOISE1 0xFFFFFFBBu +#define PALETURQUOISE2 0xFFEEEEAEu +#define PALETURQUOISE3 0xFFCDCD96u +#define PALETURQUOISE4 0xFF8B8B66u +#define PALEVIOLETRED 0xFF9370DBu +#define PALEVIOLETRED1 0xFFAB82FFu +#define PALEVIOLETRED2 0xFF9F79EEu +#define PALEVIOLETRED3 0xFF8968CDu +#define PALEVIOLETRED4 0xFF5D478Bu +#define PAPAYAWHIP 0xFFD5EFFFu +#define PEACHPUFF 0xFFB9DAFFu +#define PEACHPUFF1 0xFFB9DAFFu +#define PEACHPUFF2 0xFFADCBEEu +#define PEACHPUFF3 0xFF95AFCDu +#define PEACHPUFF4 0xFF65778Bu +#define PERU 0xFF3F85CDu +#define PINK 0xFFCBC0FFu +#define PINK1 0xFFC5B5FFu +#define PINK2 0xFFB8A9EEu +#define PINK3 0xFF9E91CDu +#define PINK4 0xFF6C638Bu +#define PLUM 0xFFDDA0DDu +#define PLUM1 0xFFFFBBFFu +#define PLUM2 0xFFEEAEEEu +#define PLUM3 0xFFCD96CDu +#define PLUM4 0xFF8B668Bu +#define POWDERBLUE 0xFFE6E0B0u +#define PURPLE 0xFFF020A0u +#define PURPLE1 0xFFFF309Bu +#define PURPLE2 0xFFEE2C91u +#define PURPLE3 0xFFCD267Du +#define PURPLE4 0xFF8B1A55u +#define RED 0xFF0000FFu +#define RED1 0xFF0000FFu +#define RED2 0xFF0000EEu +#define RED3 0xFF0000CDu +#define RED4 0xFF00008Bu +#define ROSYBROWN 0xFF8F8FBCu +#define ROSYBROWN1 0xFFC1C1FFu +#define ROSYBROWN2 0xFFB4B4EEu +#define ROSYBROWN3 0xFF9B9BCDu +#define ROSYBROWN4 0xFF69698Bu +#define ROYALBLUE 0xFFE16941u +#define ROYALBLUE1 0xFFFF7648u +#define ROYALBLUE2 0xFFEE6E43u +#define ROYALBLUE3 0xFFCD5F3Au +#define ROYALBLUE4 0xFF8B4027u +#define SADDLEBROWN 0xFF13458Bu +#define SALMON 0xFF7280FAu +#define SALMON1 0xFF698CFFu +#define SALMON2 0xFF6282EEu +#define SALMON3 0xFF5470CDu +#define SALMON4 0xFF394C8Bu +#define SANDYBROWN 0xFF60A4F4u +#define SEAGREEN 0xFF578B2Eu +#define SEAGREEN1 0xFF9FFF54u +#define SEAGREEN2 0xFF94EE4Eu +#define SEAGREEN3 0xFF80CD43u +#define SEAGREEN4 0xFF578B2Eu +#define SEASHELL 0xFFEEF5FFu +#define SEASHELL1 0xFFEEF5FFu +#define SEASHELL2 0xFFDEE5EEu +#define SEASHELL3 0xFFBFC5CDu +#define SEASHELL4 0xFF82868Bu +#define SIENNA 0xFF2D52A0u +#define SIENNA1 0xFF4782FFu +#define SIENNA2 0xFF4279EEu +#define SIENNA3 0xFF3968CDu +#define SIENNA4 0xFF26478Bu +#define SKYBLUE 0xFFEBCE87u +#define SKYBLUE1 0xFFFFCE87u +#define SKYBLUE2 0xFFEEC07Eu +#define SKYBLUE3 0xFFCDA66Cu +#define SKYBLUE4 0xFF8B704Au +#define SLATEBLUE 0xFFCD5A6Au +#define SLATEBLUE1 0xFFFF6F83u +#define SLATEBLUE2 0xFFEE677Au +#define SLATEBLUE3 0xFFCD5969u +#define SLATEBLUE4 0xFF8B3C47u +#define SLATEGRAY 0xFF908070u +#define SLATEGRAY1 0xFFFFE2C6u +#define SLATEGRAY2 0xFFEED3B9u +#define SLATEGRAY3 0xFFCDB69Fu +#define SLATEGRAY4 0xFF8B7B6Cu +#define SLATEGREY 0xFF908070u +#define SNOW 0xFFFAFAFFu +#define SNOW1 0xFFFAFAFFu +#define SNOW2 0xFFE9E9EEu +#define SNOW3 0xFFC9C9CDu +#define SNOW4 0xFF89898Bu +#define SPRINGGREEN 0xFF7FFF00u +#define SPRINGGREEN1 0xFF7FFF00u +#define SPRINGGREEN2 0xFF76EE00u +#define SPRINGGREEN3 0xFF66CD00u +#define SPRINGGREEN4 0xFF458B00u +#define STEELBLUE 0xFFB48246u +#define STEELBLUE1 0xFFFFB863u +#define STEELBLUE2 0xFFEEAC5Cu +#define STEELBLUE3 0xFFCD944Fu +#define STEELBLUE4 0xFF8B6436u +#define TAN 0xFF8CB4D2u +#define TAN1 0xFF4FA5FFu +#define TAN2 0xFF499AEEu +#define TAN3 0xFF3F85CDu +#define TAN4 0xFF2B5A8Bu +#define THISTLE 0xFFD8BFD8u +#define THISTLE1 0xFFFFE1FFu +#define THISTLE2 0xFFEED2EEu +#define THISTLE3 0xFFCDB5CDu +#define THISTLE4 0xFF8B7B8Bu +#define TOMATO 0xFF4763FFu +#define TOMATO1 0xFF4763FFu +#define TOMATO2 0xFF425CEEu +#define TOMATO3 0xFF394FCDu +#define TOMATO4 0xFF26368Bu +#define TURQUOISE 0xFFD0E040u +#define TURQUOISE1 0xFFFFF500u +#define TURQUOISE2 0xFFEEE500u +#define TURQUOISE3 0xFFCDC500u +#define TURQUOISE4 0xFF8B8600u +#define VIOLET 0xFFEE82EEu +#define VIOLETRED 0xFF9020D0u +#define VIOLETRED1 0xFF963EFFu +#define VIOLETRED2 0xFF8C3AEEu +#define VIOLETRED3 0xFF7832CDu +#define VIOLETRED4 0xFF52228Bu +#define WHEAT 0xFFB3DEF5u +#define WHEAT1 0xFFBAE7FFu +#define WHEAT2 0xFFAED8EEu +#define WHEAT3 0xFF96BACDu +#define WHEAT4 0xFF667E8Bu +#define WHITE 0xFFFFFFFFu +#define WHITESMOKE 0xFFF5F5F5u +#define YELLOW 0xFF00FFFFu +#define YELLOW1 0xFF00FFFFu +#define YELLOW2 0xFF00EEEEu +#define YELLOW3 0xFF00CDCDu +#define YELLOW4 0xFF008B8Bu +#define YELLOWGREEN 0xFF32CD9Au + +#endif /* COSMOPOLITAN_NET_HTTP_CSSCOLOR_H_ */ diff --git a/net/http/freehttprequest.c b/net/http/freehttprequest.c new file mode 100644 index 00000000..eb47efa5 --- /dev/null +++ b/net/http/freehttprequest.c @@ -0,0 +1,33 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/runtime/runtime.h" +#include "net/http/http.h" + +void freehttprequest(struct HttpRequest **req) { + if (*req) { + critbit0_clear(&(*req)->headers); + free_s(&(*req)->method.p); + free_s(&(*req)->scratch.p); + free_s(&(*req)->uri.p); + free_s(&(*req)->version.p); + free_s(req); + } +} diff --git a/net/http/gethttpheader.c b/net/http/gethttpheader.c new file mode 100644 index 00000000..882f89b8 --- /dev/null +++ b/net/http/gethttpheader.c @@ -0,0 +1,33 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "net/http/gethttpheader.inc" +#include "net/http/http.h" + +/** + * Returns small number for HTTP header, or 0 if not found. + */ +enum HttpHeader gethttpheader(const char *str, unsigned int len) { + const struct HttpHeaderSlot *slot; + if ((slot = in_word_set(str, len))) { + return slot->code; + } else { + return 0; + } +} diff --git a/net/http/gethttpheader.gperf b/net/http/gethttpheader.gperf new file mode 100644 index 00000000..e60bb2ba --- /dev/null +++ b/net/http/gethttpheader.gperf @@ -0,0 +1,62 @@ +%{ +#include "libc/str/str.h" +#include "net/http/http.h" +#define GPERF_DOWNCASE +%} +%compare-strncmp +%ignore-case +%language=ANSI-C +%pic +%readonly-tables +%struct-type +struct HttpHeaderSlot { unsigned char name; unsigned char code; }; +%% +Accept, kHttpAccept +Accept-Charset, kHttpAcceptCharset +Accept-Encoding, kHttpAcceptEncoding +Accept-Language, kHttpAcceptLanguage +Age, kHttpAge +Allow, kHttpAllow +Authorization, kHttpAuthorization +Cache-Control, kHttpCacheControl +Chunked, kHttpChunked +Close, kHttpClose +Connection, kHttpConnection +Content-Base, kHttpContentBase +Content-Encoding, kHttpContentEncoding +Content-Language, kHttpContentLanguage +Content-Length, kHttpContentLength +Content-Location, kHttpContentLocation +Content-Md5, kHttpContentMd5 +Content-Range, kHttpContentRange +Content-Type, kHttpContentType +Date, kHttpDate +Etag, kHttpEtag +Expires, kHttpExpires +From, kHttpFrom +Host, kHttpHost +If-Match, kHttpIfMatch +If-Modified-Since, kHttpIfModifiedSince +If-None-Match, kHttpIfNoneMatch +If-Range, kHttpIfRange +If-Unmodified-Since, kHttpIfUnmodifiedSince +Keep-Alive, kHttpKeepAlive +Max-Forwards, kHttpMaxForwards +Pragma, kHttpPragma +Proxy-Authenticate, kHttpProxyAuthenticate +Proxy-Authorization, kHttpProxyAuthorization +Proxy-Connection, kHttpProxyConnection +Range, kHttpRange +Referer, kHttpReferer +Transfer-Encoding, kHttpTransferEncoding +Upgrade, kHttpUpgrade +User-Agent, kHttpUserAgent +Via, kHttpVia +Location, kHttpLocation +Public, kHttpPublic +Retry-After, kHttpRetryAfter +Server, kHttpServer +Vary, kHttpVary +Warning, kHttpWarning +WWW-Authenticate, kHttpWwwAuthenticate +Last-Modified, kHttpLastModified diff --git a/net/http/gethttpheader.inc b/net/http/gethttpheader.inc new file mode 100644 index 00000000..b55752b6 --- /dev/null +++ b/net/http/gethttpheader.inc @@ -0,0 +1,397 @@ +/* ANSI-C code produced by gperf version 3.0.4 */ +/* Command-line: gperf net/http/gethttpheader.gperf */ +/* Computed positions: -k'1,9,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "net/http/gethttpheader.gperf" + +#include "libc/str/str.h" +#include "net/http/http.h" +#define GPERF_DOWNCASE +#line 12 "net/http/gethttpheader.gperf" +struct HttpHeaderSlot { unsigned char name; unsigned char code; }; + +#define TOTAL_KEYWORDS 49 +#define MIN_WORD_LENGTH 3 +#define MAX_WORD_LENGTH 19 +#define MIN_HASH_VALUE 5 +#define MAX_HASH_VALUE 72 +/* maximum key range = 68, duplicates = 0 */ + +#ifndef GPERF_DOWNCASE +#define GPERF_DOWNCASE 1 +static unsigned char gperf_downcase[256] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255 + }; +#endif + +#ifndef GPERF_CASE_STRNCMP +#define GPERF_CASE_STRNCMP 1 +static int +gperf_case_strncmp (register const char *s1, register const char *s2, register unsigned int n) +{ + for (; n > 0;) + { + unsigned char c1 = gperf_downcase[(unsigned char)*s1++]; + unsigned char c2 = gperf_downcase[(unsigned char)*s2++]; + if (c1 != 0 && c1 == c2) + { + n--; + continue; + } + return (int)c1 - (int)c2; + } + return 0; +} +#endif + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +hash (register const char *str, register unsigned int len) +{ + static const unsigned char asso_values[] = + { + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 0, 73, 73, 73, 73, + 73, 73, 73, 0, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 5, 20, 0, 15, 0, + 0, 45, 20, 5, 73, 10, 35, 5, 5, 5, + 20, 73, 5, 30, 0, 0, 15, 20, 73, 15, + 73, 73, 73, 73, 73, 73, 73, 5, 20, 0, + 15, 0, 0, 45, 20, 5, 73, 10, 35, 5, + 5, 5, 20, 73, 5, 30, 0, 0, 15, 20, + 73, 15, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[8]]; + /*FALLTHROUGH*/ + case 8: + case 7: + case 6: + case 5: + case 4: + case 3: + case 2: + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +struct stringpool_t + { + char stringpool_str5[sizeof("Close")]; + char stringpool_str7[sizeof("Upgrade")]; + char stringpool_str8[sizeof("Age")]; + char stringpool_str9[sizeof("From")]; + char stringpool_str10[sizeof("Range")]; + char stringpool_str11[sizeof("Accept")]; + char stringpool_str12[sizeof("Content-Type")]; + char stringpool_str13[sizeof("If-Range")]; + char stringpool_str15[sizeof("User-Agent")]; + char stringpool_str16[sizeof("Content-Md5")]; + char stringpool_str17[sizeof("Referer")]; + char stringpool_str18[sizeof("Content-Range")]; + char stringpool_str19[sizeof("Date")]; + char stringpool_str20[sizeof("Connection")]; + char stringpool_str21[sizeof("Retry-After")]; + char stringpool_str22[sizeof("Chunked")]; + char stringpool_str23[sizeof("Via")]; + char stringpool_str24[sizeof("Host")]; + char stringpool_str25[sizeof("Accept-Language")]; + char stringpool_str26[sizeof("Public")]; + char stringpool_str27[sizeof("If-Modified-Since")]; + char stringpool_str28[sizeof("Authorization")]; + char stringpool_str29[sizeof("If-Unmodified-Since")]; + char stringpool_str30[sizeof("Allow")]; + char stringpool_str31[sizeof("Pragma")]; + char stringpool_str32[sizeof("Content-Base")]; + char stringpool_str33[sizeof("If-Match")]; + char stringpool_str34[sizeof("Vary")]; + char stringpool_str35[sizeof("Keep-Alive")]; + char stringpool_str36[sizeof("WWW-Authenticate")]; + char stringpool_str37[sizeof("Expires")]; + char stringpool_str38[sizeof("Proxy-Authenticate")]; + char stringpool_str39[sizeof("Accept-Charset")]; + char stringpool_str41[sizeof("Server")]; + char stringpool_str43[sizeof("If-None-Match")]; + char stringpool_str44[sizeof("Proxy-Authorization")]; + char stringpool_str46[sizeof("Proxy-Connection")]; + char stringpool_str48[sizeof("Location")]; + char stringpool_str49[sizeof("Etag")]; + char stringpool_str51[sizeof("Content-Language")]; + char stringpool_str52[sizeof("Max-Forwards")]; + char stringpool_str53[sizeof("Cache-Control")]; + char stringpool_str56[sizeof("Content-Location")]; + char stringpool_str61[sizeof("Content-Encoding")]; + char stringpool_str62[sizeof("Transfer-Encoding")]; + char stringpool_str68[sizeof("Last-Modified")]; + char stringpool_str69[sizeof("Content-Length")]; + char stringpool_str70[sizeof("Accept-Encoding")]; + char stringpool_str72[sizeof("Warning")]; + }; +static const struct stringpool_t stringpool_contents = + { + "Close", + "Upgrade", + "Age", + "From", + "Range", + "Accept", + "Content-Type", + "If-Range", + "User-Agent", + "Content-Md5", + "Referer", + "Content-Range", + "Date", + "Connection", + "Retry-After", + "Chunked", + "Via", + "Host", + "Accept-Language", + "Public", + "If-Modified-Since", + "Authorization", + "If-Unmodified-Since", + "Allow", + "Pragma", + "Content-Base", + "If-Match", + "Vary", + "Keep-Alive", + "WWW-Authenticate", + "Expires", + "Proxy-Authenticate", + "Accept-Charset", + "Server", + "If-None-Match", + "Proxy-Authorization", + "Proxy-Connection", + "Location", + "Etag", + "Content-Language", + "Max-Forwards", + "Cache-Control", + "Content-Location", + "Content-Encoding", + "Transfer-Encoding", + "Last-Modified", + "Content-Length", + "Accept-Encoding", + "Warning" + }; +#define stringpool ((const char *) &stringpool_contents) +#ifdef __GNUC__ +__inline +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +const struct HttpHeaderSlot * +in_word_set (register const char *str, register unsigned int len) +{ + static const struct HttpHeaderSlot wordlist[] = + { + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 23 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str5, kHttpClose }, + {-1}, +#line 52 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str7, kHttpUpgrade }, +#line 18 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str8, kHttpAge }, +#line 36 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str9, kHttpFrom }, +#line 49 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str10, kHttpRange }, +#line 14 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str11, kHttpAccept }, +#line 32 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str12, kHttpContentType }, +#line 41 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str13, kHttpIfRange }, + {-1}, +#line 53 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str15, kHttpUserAgent }, +#line 30 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str16, kHttpContentMd5 }, +#line 50 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str17, kHttpReferer }, +#line 31 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str18, kHttpContentRange }, +#line 33 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str19, kHttpDate }, +#line 24 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str20, kHttpConnection }, +#line 57 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str21, kHttpRetryAfter }, +#line 22 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str22, kHttpChunked }, +#line 54 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str23, kHttpVia }, +#line 37 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str24, kHttpHost }, +#line 17 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str25, kHttpAcceptLanguage }, +#line 56 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str26, kHttpPublic }, +#line 39 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str27, kHttpIfModifiedSince }, +#line 20 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str28, kHttpAuthorization }, +#line 42 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str29, kHttpIfUnmodifiedSince }, +#line 19 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str30, kHttpAllow }, +#line 45 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str31, kHttpPragma }, +#line 25 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str32, kHttpContentBase }, +#line 38 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str33, kHttpIfMatch }, +#line 59 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str34, kHttpVary }, +#line 43 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str35, kHttpKeepAlive }, +#line 61 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str36, kHttpWwwAuthenticate }, +#line 35 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str37, kHttpExpires }, +#line 46 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str38, kHttpProxyAuthenticate }, +#line 15 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str39, kHttpAcceptCharset }, + {-1}, +#line 58 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str41, kHttpServer }, + {-1}, +#line 40 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str43, kHttpIfNoneMatch }, +#line 47 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str44, kHttpProxyAuthorization }, + {-1}, +#line 48 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str46, kHttpProxyConnection }, + {-1}, +#line 55 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str48, kHttpLocation }, +#line 34 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str49, kHttpEtag }, + {-1}, +#line 27 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str51, kHttpContentLanguage }, +#line 44 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str52, kHttpMaxForwards }, +#line 21 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str53, kHttpCacheControl }, + {-1}, {-1}, +#line 29 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str56, kHttpContentLocation }, + {-1}, {-1}, {-1}, {-1}, +#line 26 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str61, kHttpContentEncoding }, +#line 51 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str62, kHttpTransferEncoding }, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 62 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str68, kHttpLastModified }, +#line 28 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str69, kHttpContentLength }, +#line 16 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str70, kHttpAcceptEncoding }, + {-1}, +#line 60 "net/http/gethttpheader.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str72, kHttpWarning } + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int o = wordlist[key].name; + if (o >= 0) + { + register const char *s = o + stringpool; + + if ((((unsigned char)*str ^ (unsigned char)*s) & ~32) == 0 && !gperf_case_strncmp (str, s, len) && s[len] == '\0') + return &wordlist[key]; + } + } + } + return 0; +} diff --git a/net/http/geturischeme.gperf b/net/http/geturischeme.gperf new file mode 100644 index 00000000..8c70ccb6 --- /dev/null +++ b/net/http/geturischeme.gperf @@ -0,0 +1,24 @@ +%{ +#include "libc/str/str.h" +#include "net/http/uri.h" +#define GPERF_DOWNCASE +%} +%compare-strncmp +%ignore-case +%language=ANSI-C +%pic +%readonly-tables +%struct-type +struct UriSchemeSlot { unsigned char name; unsigned char code; }; +%% +http,kUriSchemeHttp +https,kUriSchemeHttps +file,kUriSchemeFile +data,kUriSchemeData +zip,kUriSchemeZip +sip,kUriSchemeSip +sips,kUriSchemeSips +tel,kUriSchemeTel +ssh,kUriSchemeSsh +gs,kUriSchemeGs +s3,kUriSchemeS3 diff --git a/net/http/geturischeme.inc b/net/http/geturischeme.inc new file mode 100644 index 00000000..ededd61c --- /dev/null +++ b/net/http/geturischeme.inc @@ -0,0 +1,219 @@ +/* ANSI-C code produced by gperf version 3.0.4 */ +/* Command-line: gperf net/http/geturischeme.gperf */ +/* Computed positions: -k'1-2' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "net/http/geturischeme.gperf" + +#include "libc/str/str.h" +#include "net/http/uri.h" +#define GPERF_DOWNCASE +#line 12 "net/http/geturischeme.gperf" +struct UriSchemeSlot { unsigned char name; unsigned char code; }; + +#define TOTAL_KEYWORDS 11 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 5 +#define MIN_HASH_VALUE 2 +#define MAX_HASH_VALUE 19 +/* maximum key range = 18, duplicates = 0 */ + +#ifndef GPERF_DOWNCASE +#define GPERF_DOWNCASE 1 +static unsigned char gperf_downcase[256] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255 + }; +#endif + +#ifndef GPERF_CASE_STRNCMP +#define GPERF_CASE_STRNCMP 1 +static int +gperf_case_strncmp (register const char *s1, register const char *s2, register unsigned int n) +{ + for (; n > 0;) + { + unsigned char c1 = gperf_downcase[(unsigned char)*s1++]; + unsigned char c2 = gperf_downcase[(unsigned char)*s2++]; + if (c1 != 0 && c1 == c2) + { + n--; + continue; + } + return (int)c1 - (int)c2; + } + return 0; +} +#endif + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +hash (register const char *str, register unsigned int len) +{ + static const unsigned char asso_values[] = + { + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 5, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 10, 20, 20, 5, 15, + 5, 0, 0, 5, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 0, 0, 20, 20, 20, 20, 20, + 5, 20, 20, 20, 20, 20, 20, 10, 20, 20, + 5, 15, 5, 0, 0, 5, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 0, 0, 20, 20, 20, + 20, 20, 5, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20 + }; + return len + asso_values[(unsigned char)str[1]] + asso_values[(unsigned char)str[0]]; +} + +struct stringpool_t + { + char stringpool_str2[sizeof("gs")]; + char stringpool_str3[sizeof("ssh")]; + char stringpool_str4[sizeof("http")]; + char stringpool_str5[sizeof("https")]; + char stringpool_str7[sizeof("s3")]; + char stringpool_str8[sizeof("sip")]; + char stringpool_str9[sizeof("sips")]; + char stringpool_str13[sizeof("zip")]; + char stringpool_str14[sizeof("file")]; + char stringpool_str18[sizeof("tel")]; + char stringpool_str19[sizeof("data")]; + }; +static const struct stringpool_t stringpool_contents = + { + "gs", + "ssh", + "http", + "https", + "s3", + "sip", + "sips", + "zip", + "file", + "tel", + "data" + }; +#define stringpool ((const char *) &stringpool_contents) +#ifdef __GNUC__ +__inline +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +const struct UriSchemeSlot * +in_word_set (register const char *str, register unsigned int len) +{ + static const struct UriSchemeSlot wordlist[] = + { + {-1}, {-1}, +#line 23 "net/http/geturischeme.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str2,kUriSchemeGs}, +#line 22 "net/http/geturischeme.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str3,kUriSchemeSsh}, +#line 14 "net/http/geturischeme.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str4,kUriSchemeHttp}, +#line 15 "net/http/geturischeme.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str5,kUriSchemeHttps}, + {-1}, +#line 24 "net/http/geturischeme.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str7,kUriSchemeS3}, +#line 19 "net/http/geturischeme.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str8,kUriSchemeSip}, +#line 20 "net/http/geturischeme.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str9,kUriSchemeSips}, + {-1}, {-1}, {-1}, +#line 18 "net/http/geturischeme.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str13,kUriSchemeZip}, +#line 16 "net/http/geturischeme.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str14,kUriSchemeFile}, + {-1}, {-1}, {-1}, +#line 21 "net/http/geturischeme.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str18,kUriSchemeTel}, +#line 17 "net/http/geturischeme.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str19,kUriSchemeData} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int o = wordlist[key].name; + if (o >= 0) + { + register const char *s = o + stringpool; + + if ((((unsigned char)*str ^ (unsigned char)*s) & ~32) == 0 && !gperf_case_strncmp (str, s, len) && s[len] == '\0') + return &wordlist[key]; + } + } + } + return 0; +} diff --git a/net/http/http.h b/net/http/http.h new file mode 100644 index 00000000..c44983e5 --- /dev/null +++ b/net/http/http.h @@ -0,0 +1,82 @@ +#ifndef COSMOPOLITAN_LIBC_HTTP_HTTP_H_ +#define COSMOPOLITAN_LIBC_HTTP_HTTP_H_ +#include "libc/alg/alg.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct FILE; + +enum HttpHeader { + kHttpAccept = 1, + kHttpAcceptCharset, + kHttpAcceptEncoding, + kHttpAcceptLanguage, + kHttpAge, + kHttpAllow, + kHttpAuthorization, + kHttpCacheControl, + kHttpChunked, + kHttpClose, + kHttpConnection, + kHttpContentBase, + kHttpContentEncoding, + kHttpContentLanguage, + kHttpContentLength, + kHttpContentLocation, + kHttpContentMd5, + kHttpContentRange, + kHttpContentType, + kHttpDate, + kHttpEtag, + kHttpExpires, + kHttpFrom, + kHttpHost, + kHttpIfMatch, + kHttpIfModifiedSince, + kHttpIfNoneMatch, + kHttpIfRange, + kHttpIfUnmodifiedSince, + kHttpKeepAlive, + kHttpMaxForwards, + kHttpPragma, + kHttpProxyAuthenticate, + kHttpProxyAuthorization, + kHttpProxyConnection, + kHttpRange, + kHttpReferer, + kHttpTransferEncoding, + kHttpUpgrade, + kHttpUserAgent, + kHttpVia, + kHttpLocation, + kHttpPublic, + kHttpRetryAfter, + kHttpServer, + kHttpVary, + kHttpWarning, + kHttpWwwAuthenticate, + kHttpLastModified, +}; + +struct HttpStr { + char *p; + size_t i, n; +}; + +struct HttpRequest { + struct HttpStr uri; /* /foo/bar.html, etc. */ + struct HttpStr method; /* "GET", "POST", etc. */ + struct critbit0 headers; /* TreeMultiMap<"key:value"> (no space delims) */ + struct HttpStr version; /* "HTTP/1.1", etc. */ + struct HttpStr scratch; /* "HTTP/1.1", etc. */ +}; + +int parsehttprequest(struct HttpRequest *, struct FILE *) paramsnonnull(); +void clearhttprequest(struct HttpRequest *) paramsnonnull(); +void freehttprequest(struct HttpRequest **) paramsnonnull(); +int negotiatehttprequest(int, const char *, uint32_t *, char *, uint32_t *, + uint32_t *, bool, long double); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_HTTP_HTTP_H_ */ diff --git a/net/http/http.mk b/net/http/http.mk new file mode 100644 index 00000000..a8b219f0 --- /dev/null +++ b/net/http/http.mk @@ -0,0 +1,68 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += NET_HTTP + +NET_HTTP_ARTIFACTS += NET_HTTP_A +NET_HTTP = $(NET_HTTP_A_DEPS) $(NET_HTTP_A) +NET_HTTP_A = o/$(MODE)/net/http/http.a +NET_HTTP_A_FILES := $(wildcard net/http/*) +NET_HTTP_A_HDRS = $(filter %.h,$(NET_HTTP_A_FILES)) +NET_HTTP_A_SRCS_S = $(filter %.S,$(NET_HTTP_A_FILES)) +NET_HTTP_A_SRCS_C = $(filter %.c,$(NET_HTTP_A_FILES)) +NET_HTTP_A_SRCS_R = $(filter %.rl,$(NET_HTTP_A_FILES)) + +NET_HTTP_A_SRCS = \ + $(NET_HTTP_A_SRCS_S) \ + $(NET_HTTP_A_SRCS_C) \ + $(NET_HTTP_A_SRCS_R) + +NET_HTTP_A_OBJS = \ + $(NET_HTTP_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(NET_HTTP_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(NET_HTTP_A_SRCS_C:%.c=o/$(MODE)/%.o) \ + $(NET_HTTP_A_SRCS_R:%.rl=o/$(MODE)/%.o) + +NET_HTTP_A_CHECKS = \ + $(NET_HTTP_A).pkg \ + $(NET_HTTP_A_HDRS:%=o/$(MODE)/%.ok) + +NET_HTTP_A_DIRECTDEPS = \ + LIBC_ALG \ + LIBC_CALLS \ + LIBC_CONV \ + LIBC_FMT \ + LIBC_LOG \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_SOCK \ + LIBC_STDIO \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_TIME \ + LIBC_X + +NET_HTTP_A_DEPS := \ + $(call uniq,$(foreach x,$(NET_HTTP_A_DIRECTDEPS),$($(x)))) + +$(NET_HTTP_A): net/http/ \ + $(NET_HTTP_A).pkg \ + $(NET_HTTP_A_OBJS) + +$(NET_HTTP_A).pkg: \ + $(NET_HTTP_A_OBJS) \ + $(foreach x,$(NET_HTTP_A_DIRECTDEPS),$($(x)_A).pkg) + +NET_HTTP_LIBS = $(foreach x,$(NET_HTTP_ARTIFACTS),$($(x))) +NET_HTTP_SRCS = $(foreach x,$(NET_HTTP_ARTIFACTS),$($(x)_SRCS)) +NET_HTTP_HDRS = $(foreach x,$(NET_HTTP_ARTIFACTS),$($(x)_HDRS)) +NET_HTTP_CHECKS = $(foreach x,$(NET_HTTP_ARTIFACTS),$($(x)_CHECKS)) +NET_HTTP_OBJS = $(foreach x,$(NET_HTTP_ARTIFACTS),$($(x)_OBJS)) + +$(NET_HTTP_OBJS): $(BUILD_FILES) net/http/http.mk + +.PRECIOUS: $(NET_HTTP_A_SRCS_R:%.rl=build/bootstrap/%.c) +.PHONY: o/$(MODE)/net/http +o/$(MODE)/net/http: \ + $(NET_HTTP_CHECKS) \ + $(NET_HTTP_A_SRCS_R:%.rl=%.svgz) diff --git a/net/http/method.gperf b/net/http/method.gperf new file mode 100644 index 00000000..2f319ef7 --- /dev/null +++ b/net/http/method.gperf @@ -0,0 +1,24 @@ +DELETE +GET +HEAD +POST +PUT +CONNECT +OPTIONS +TRACE +COPY +CHECKOUT +LOCK +M-SEARCH +MERGE +MKACTIVITY +MKCOL +MOVE +NOTIFY +PATCH +PROPFIND +PROPPATCH +REPORT +SUBSCRIBE +UNLOCK +UNSUBSCRIBE diff --git a/net/http/negotiatehttprequest.c b/net/http/negotiatehttprequest.c new file mode 100644 index 00000000..50e9e787 --- /dev/null +++ b/net/http/negotiatehttprequest.c @@ -0,0 +1,107 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/calls/calls.h" +#include "libc/macros.h" +#include "libc/math.h" +#include "libc/sock/sock.h" +#include "libc/sysv/consts/poll.h" +#include "libc/sysv/consts/shut.h" +#include "libc/sysv/errfuns.h" +#include "libc/time/time.h" +#include "net/http/http.h" + +static pureconst long AsMilliseconds(long double ts) { + return ts * 1e3 + .5; +} + +/** + * Negotiates HTTP request. + * + * This function blocks until a response header is consumed. We assume + * the response header is smaller than *inout_respsize. We're agnostic + * to the various different i/o paradigms. Goal is really good latency. + * + * @param singleshot should be true w/ connection: close + * @return 0 on success, or -1 w/ errno + */ +int negotiatehttprequest(int sock, const char *req, uint32_t *inout_reqsize, + char *resp, uint32_t *inout_respsize, + uint32_t *out_resphdrsize, bool singleshot, + long double timeout) { + ssize_t rc; + struct pollfd fd; + const char *body; + long double start, now, deadline; + uint32_t transmitted, received, exchanged, remaining; + fd.fd = sock; + received = 0; + transmitted = 0; + fd.events = POLLOUT | POLLIN; + deadline = (start = now = nowl()) + timeout; + do { + if ((rc = poll(&fd, 1, MAX(0, AsMilliseconds(deadline - now)))) == 1) { + if (fd.revents & POLLHUP) { + econnreset(); + break; + } + if (fd.revents & (POLLIN | POLLERR)) { + remaining = *inout_respsize - received - 1; + if ((rc = recv(fd.fd, resp + received, remaining, 0)) != -1) { + exchanged = rc; + body = memmem(resp + (received >= 4 ? received - 4 : 0), exchanged, + "\r\n\r\n", 4); + received += exchanged; + if (body) { + resp[received] = '\0'; + *inout_respsize = received; + *inout_reqsize = transmitted; + *out_resphdrsize = body - resp; + return 0; + } + if (exchanged == remaining) { + emsgsize(); + break; + } + } else { + break; + } + } + if (fd.revents & POLLOUT) { + remaining = *inout_reqsize - transmitted; + if ((rc = send(fd.fd, req + transmitted, remaining, 0)) != -1) { + exchanged = rc; + transmitted += exchanged; + if (exchanged == remaining) { + if (singleshot) shutdown(fd.fd, SHUT_WR); + fd.events &= ~POLLOUT; + } + } else { + break; + } + } + } else { + if (!rc) etimedout(); + break; + } + } while ((now = nowl()) < deadline); + close(fd.fd); + return -1; +} diff --git a/net/http/parsehttprequest.c b/net/http/parsehttprequest.c new file mode 100644 index 00000000..556189cf --- /dev/null +++ b/net/http/parsehttprequest.c @@ -0,0 +1,133 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/alg/arraylist.h" +#include "libc/limits.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" +#include "libc/x/x.h" +#include "net/http/http.h" + +enum ParseHttpRequestState { + METHOD, + URI, + VERSION, + HKEY, + HSEP, + HVAL, + CR1, + LF1, + LF2 +}; + +/** + * Parses req line and headers of HTTP req. + * + * This parser is very lax. All decoding is ISO-8859-1. A 1mB upper + * bound on memory is enforced. + */ +int parsehttprequest(struct HttpRequest *req, FILE *f) { + enum ParseHttpRequestState state = METHOD; + int toto = 0; + clearhttprequest(req); + while (true) { + char ch; + { + int c = fgetc(f); + if (c == -1) { + if (toto && !ferror(f)) { + return ebadmsg(); /* RFC7230 § 3.4 */ + } + return -1; + } + ch = (unsigned char)c; + } + if (++toto == UINT16_MAX) { + return ebadmsg(); /* RFC7230 § 3.2.5 */ + } + switch (state) { + case METHOD: + if (ch == '\r' || ch == '\n') break; /* RFC7230 § 3.5 */ + if (ch == ' ') { + if (req->method.i == 0) return ebadmsg(); + state = URI; + } else { + append(&req->method, &ch); + } + break; + case URI: + if (ch == ' ') { + if (req->uri.i == 0) return ebadmsg(); + state = VERSION; + } else { + append(&req->uri, &ch); + } + break; + case VERSION: + if (ch == '\r' || ch == '\n') { + state = ch == '\r' ? CR1 : LF1; + } else { + append(&req->version, &ch); + } + break; + case CR1: + if (ch != '\n') return ebadmsg(); + state = LF1; + break; + case LF1: + if (ch == '\r') { + state = LF2; + break; + } else if (ch == '\n') { + return 0; + } else if (ch == ' ' || ch == '\t') { /* line folding!!! */ + return eprotonosupport(); /* RFC7230 § 3.2.4 */ + } + state = HKEY; + /* εpsilon transition */ + case HKEY: + if (ch == ':') state = HSEP; + ch = tolower(ch); + append(&req->scratch, &ch); + break; + case HSEP: + if (ch == ' ' || ch == '\t') break; + state = HVAL; + /* εpsilon transition */ + case HVAL: + if (ch == '\r' || ch == '\n') { + state = ch == '\r' ? CR1 : LF1; + ch = '\0'; + } + append(&req->scratch, &ch); + if (!ch) { + critbit0_insert(&req->headers, req->scratch.p); + req->scratch.i = 0; + } + break; + case LF2: + if (ch == '\n') return 0; + return ebadmsg(); + default: + unreachable; + } + } +} diff --git a/net/http/rfc2068 b/net/http/rfc2068 new file mode 100644 index 00000000..e16e4fdf --- /dev/null +++ b/net/http/rfc2068 @@ -0,0 +1,9075 @@ + + + + + + +Network Working Group R. Fielding +Request for Comments: 2068 UC Irvine +Category: Standards Track J. Gettys + J. Mogul + DEC + H. Frystyk + T. Berners-Lee + MIT/LCS + January 1997 + + + Hypertext Transfer Protocol -- HTTP/1.1 + +Status of this Memo + + This document specifies an Internet standards track protocol for the + Internet community, and requests discussion and suggestions for + improvements. Please refer to the current edition of the "Internet + Official Protocol Standards" (STD 1) for the standardization state + and status of this protocol. Distribution of this memo is unlimited. + +Abstract + + The Hypertext Transfer Protocol (HTTP) is an application-level + protocol for distributed, collaborative, hypermedia information + systems. It is a generic, stateless, object-oriented protocol which + can be used for many tasks, such as name servers and distributed + object management systems, through extension of its request methods. + A feature of HTTP is the typing and negotiation of data + representation, allowing systems to be built independently of the + data being transferred. + + HTTP has been in use by the World-Wide Web global information + initiative since 1990. This specification defines the protocol + referred to as "HTTP/1.1". + +Table of Contents + + 1 Introduction.............................................7 + 1.1 Purpose ..............................................7 + 1.2 Requirements .........................................7 + 1.3 Terminology ..........................................8 + 1.4 Overall Operation ...................................11 + 2 Notational Conventions and Generic Grammar..............13 + 2.1 Augmented BNF .......................................13 + 2.2 Basic Rules .........................................15 + 3 Protocol Parameters.....................................17 + 3.1 HTTP Version ........................................17 + + + +Fielding, et. al. Standards Track [Page 1] + +RFC 2068 HTTP/1.1 January 1997 + + + 3.2 Uniform Resource Identifiers ........................18 + 3.2.1 General Syntax ...................................18 + 3.2.2 http URL .........................................19 + 3.2.3 URI Comparison ...................................20 + 3.3 Date/Time Formats ...................................21 + 3.3.1 Full Date ........................................21 + 3.3.2 Delta Seconds ....................................22 + 3.4 Character Sets ......................................22 + 3.5 Content Codings .....................................23 + 3.6 Transfer Codings ....................................24 + 3.7 Media Types .........................................25 + 3.7.1 Canonicalization and Text Defaults ...............26 + 3.7.2 Multipart Types ..................................27 + 3.8 Product Tokens ......................................28 + 3.9 Quality Values ......................................28 + 3.10 Language Tags ......................................28 + 3.11 Entity Tags ........................................29 + 3.12 Range Units ........................................30 + 4 HTTP Message............................................30 + 4.1 Message Types .......................................30 + 4.2 Message Headers .....................................31 + 4.3 Message Body ........................................32 + 4.4 Message Length ......................................32 + 4.5 General Header Fields ...............................34 + 5 Request.................................................34 + 5.1 Request-Line ........................................34 + 5.1.1 Method ...........................................35 + 5.1.2 Request-URI ......................................35 + 5.2 The Resource Identified by a Request ................37 + 5.3 Request Header Fields ...............................37 + 6 Response................................................38 + 6.1 Status-Line .........................................38 + 6.1.1 Status Code and Reason Phrase ....................39 + 6.2 Response Header Fields ..............................41 + 7 Entity..................................................41 + 7.1 Entity Header Fields ................................41 + 7.2 Entity Body .........................................42 + 7.2.1 Type .............................................42 + 7.2.2 Length ...........................................43 + 8 Connections.............................................43 + 8.1 Persistent Connections ..............................43 + 8.1.1 Purpose ..........................................43 + 8.1.2 Overall Operation ................................44 + 8.1.3 Proxy Servers ....................................45 + 8.1.4 Practical Considerations .........................45 + 8.2 Message Transmission Requirements ...................46 + 9 Method Definitions......................................48 + 9.1 Safe and Idempotent Methods .........................48 + + + +Fielding, et. al. Standards Track [Page 2] + +RFC 2068 HTTP/1.1 January 1997 + + + 9.1.1 Safe Methods .....................................48 + 9.1.2 Idempotent Methods ...............................49 + 9.2 OPTIONS .............................................49 + 9.3 GET .................................................50 + 9.4 HEAD ................................................50 + 9.5 POST ................................................51 + 9.6 PUT .................................................52 + 9.7 DELETE ..............................................53 + 9.8 TRACE ...............................................53 + 10 Status Code Definitions................................53 + 10.1 Informational 1xx ..................................54 + 10.1.1 100 Continue ....................................54 + 10.1.2 101 Switching Protocols .........................54 + 10.2 Successful 2xx .....................................54 + 10.2.1 200 OK ..........................................54 + 10.2.2 201 Created .....................................55 + 10.2.3 202 Accepted ....................................55 + 10.2.4 203 Non-Authoritative Information ...............55 + 10.2.5 204 No Content ..................................55 + 10.2.6 205 Reset Content ...............................56 + 10.2.7 206 Partial Content .............................56 + 10.3 Redirection 3xx ....................................56 + 10.3.1 300 Multiple Choices ............................57 + 10.3.2 301 Moved Permanently ...........................57 + 10.3.3 302 Moved Temporarily ...........................58 + 10.3.4 303 See Other ...................................58 + 10.3.5 304 Not Modified ................................58 + 10.3.6 305 Use Proxy ...................................59 + 10.4 Client Error 4xx ...................................59 + 10.4.1 400 Bad Request .................................60 + 10.4.2 401 Unauthorized ................................60 + 10.4.3 402 Payment Required ............................60 + 10.4.4 403 Forbidden ...................................60 + 10.4.5 404 Not Found ...................................60 + 10.4.6 405 Method Not Allowed ..........................61 + 10.4.7 406 Not Acceptable ..............................61 + 10.4.8 407 Proxy Authentication Required ...............61 + 10.4.9 408 Request Timeout .............................62 + 10.4.10 409 Conflict ...................................62 + 10.4.11 410 Gone .......................................62 + 10.4.12 411 Length Required ............................63 + 10.4.13 412 Precondition Failed ........................63 + 10.4.14 413 Request Entity Too Large ...................63 + 10.4.15 414 Request-URI Too Long .......................63 + 10.4.16 415 Unsupported Media Type .....................63 + 10.5 Server Error 5xx ...................................64 + 10.5.1 500 Internal Server Error .......................64 + 10.5.2 501 Not Implemented .............................64 + + + +Fielding, et. al. Standards Track [Page 3] + +RFC 2068 HTTP/1.1 January 1997 + + + 10.5.3 502 Bad Gateway .................................64 + 10.5.4 503 Service Unavailable .........................64 + 10.5.5 504 Gateway Timeout .............................64 + 10.5.6 505 HTTP Version Not Supported ..................65 + 11 Access Authentication..................................65 + 11.1 Basic Authentication Scheme ........................66 + 11.2 Digest Authentication Scheme .......................67 + 12 Content Negotiation....................................67 + 12.1 Server-driven Negotiation ..........................68 + 12.2 Agent-driven Negotiation ...........................69 + 12.3 Transparent Negotiation ............................70 + 13 Caching in HTTP........................................70 + 13.1.1 Cache Correctness ...............................72 + 13.1.2 Warnings ........................................73 + 13.1.3 Cache-control Mechanisms ........................74 + 13.1.4 Explicit User Agent Warnings ....................74 + 13.1.5 Exceptions to the Rules and Warnings ............75 + 13.1.6 Client-controlled Behavior ......................75 + 13.2 Expiration Model ...................................75 + 13.2.1 Server-Specified Expiration .....................75 + 13.2.2 Heuristic Expiration ............................76 + 13.2.3 Age Calculations ................................77 + 13.2.4 Expiration Calculations .........................79 + 13.2.5 Disambiguating Expiration Values ................80 + 13.2.6 Disambiguating Multiple Responses ...............80 + 13.3 Validation Model ...................................81 + 13.3.1 Last-modified Dates .............................82 + 13.3.2 Entity Tag Cache Validators .....................82 + 13.3.3 Weak and Strong Validators ......................82 + 13.3.4 Rules for When to Use Entity Tags and Last- + modified Dates..........................................85 + 13.3.5 Non-validating Conditionals .....................86 + 13.4 Response Cachability ...............................86 + 13.5 Constructing Responses From Caches .................87 + 13.5.1 End-to-end and Hop-by-hop Headers ...............88 + 13.5.2 Non-modifiable Headers ..........................88 + 13.5.3 Combining Headers ...............................89 + 13.5.4 Combining Byte Ranges ...........................90 + 13.6 Caching Negotiated Responses .......................90 + 13.7 Shared and Non-Shared Caches .......................91 + 13.8 Errors or Incomplete Response Cache Behavior .......91 + 13.9 Side Effects of GET and HEAD .......................92 + 13.10 Invalidation After Updates or Deletions ...........92 + 13.11 Write-Through Mandatory ...........................93 + 13.12 Cache Replacement .................................93 + 13.13 History Lists .....................................93 + 14 Header Field Definitions...............................94 + 14.1 Accept .............................................95 + + + +Fielding, et. al. Standards Track [Page 4] + +RFC 2068 HTTP/1.1 January 1997 + + + 14.2 Accept-Charset .....................................97 + 14.3 Accept-Encoding ....................................97 + 14.4 Accept-Language ....................................98 + 14.5 Accept-Ranges ......................................99 + 14.6 Age ................................................99 + 14.7 Allow .............................................100 + 14.8 Authorization .....................................100 + 14.9 Cache-Control .....................................101 + 14.9.1 What is Cachable ...............................103 + 14.9.2 What May be Stored by Caches ...................103 + 14.9.3 Modifications of the Basic Expiration Mechanism 104 + 14.9.4 Cache Revalidation and Reload Controls .........105 + 14.9.5 No-Transform Directive .........................107 + 14.9.6 Cache Control Extensions .......................108 + 14.10 Connection .......................................109 + 14.11 Content-Base .....................................109 + 14.12 Content-Encoding .................................110 + 14.13 Content-Language .................................110 + 14.14 Content-Length ...................................111 + 14.15 Content-Location .................................112 + 14.16 Content-MD5 ......................................113 + 14.17 Content-Range ....................................114 + 14.18 Content-Type .....................................116 + 14.19 Date .............................................116 + 14.20 ETag .............................................117 + 14.21 Expires ..........................................117 + 14.22 From .............................................118 + 14.23 Host .............................................119 + 14.24 If-Modified-Since ................................119 + 14.25 If-Match .........................................121 + 14.26 If-None-Match ....................................122 + 14.27 If-Range .........................................123 + 14.28 If-Unmodified-Since ..............................124 + 14.29 Last-Modified ....................................124 + 14.30 Location .........................................125 + 14.31 Max-Forwards .....................................125 + 14.32 Pragma ...........................................126 + 14.33 Proxy-Authenticate ...............................127 + 14.34 Proxy-Authorization ..............................127 + 14.35 Public ...........................................127 + 14.36 Range ............................................128 + 14.36.1 Byte Ranges ...................................128 + 14.36.2 Range Retrieval Requests ......................130 + 14.37 Referer ..........................................131 + 14.38 Retry-After ......................................131 + 14.39 Server ...........................................132 + 14.40 Transfer-Encoding ................................132 + 14.41 Upgrade ..........................................132 + + + +Fielding, et. al. Standards Track [Page 5] + +RFC 2068 HTTP/1.1 January 1997 + + + 14.42 User-Agent .......................................134 + 14.43 Vary .............................................134 + 14.44 Via ..............................................135 + 14.45 Warning ..........................................137 + 14.46 WWW-Authenticate .................................139 + 15 Security Considerations...............................139 + 15.1 Authentication of Clients .........................139 + 15.2 Offering a Choice of Authentication Schemes .......140 + 15.3 Abuse of Server Log Information ...................141 + 15.4 Transfer of Sensitive Information .................141 + 15.5 Attacks Based On File and Path Names ..............142 + 15.6 Personal Information ..............................143 + 15.7 Privacy Issues Connected to Accept Headers ........143 + 15.8 DNS Spoofing ......................................144 + 15.9 Location Headers and Spoofing .....................144 + 16 Acknowledgments.......................................144 + 17 References............................................146 + 18 Authors' Addresses....................................149 + 19 Appendices............................................150 + 19.1 Internet Media Type message/http ..................150 + 19.2 Internet Media Type multipart/byteranges ..........150 + 19.3 Tolerant Applications .............................151 + 19.4 Differences Between HTTP Entities and + MIME Entities...........................................152 + 19.4.1 Conversion to Canonical Form ...................152 + 19.4.2 Conversion of Date Formats .....................153 + 19.4.3 Introduction of Content-Encoding ...............153 + 19.4.4 No Content-Transfer-Encoding ...................153 + 19.4.5 HTTP Header Fields in Multipart Body-Parts .....153 + 19.4.6 Introduction of Transfer-Encoding ..............154 + 19.4.7 MIME-Version ...................................154 + 19.5 Changes from HTTP/1.0 .............................154 + 19.5.1 Changes to Simplify Multi-homed Web Servers and + Conserve IP Addresses .................................155 + 19.6 Additional Features ...............................156 + 19.6.1 Additional Request Methods .....................156 + 19.6.2 Additional Header Field Definitions ............156 + 19.7 Compatibility with Previous Versions ..............160 + 19.7.1 Compatibility with HTTP/1.0 Persistent + Connections............................................161 + + + + + + + + + + + +Fielding, et. al. Standards Track [Page 6] + +RFC 2068 HTTP/1.1 January 1997 + + +1 Introduction + +1.1 Purpose + + The Hypertext Transfer Protocol (HTTP) is an application-level + protocol for distributed, collaborative, hypermedia information + systems. HTTP has been in use by the World-Wide Web global + information initiative since 1990. The first version of HTTP, + referred to as HTTP/0.9, was a simple protocol for raw data transfer + across the Internet. HTTP/1.0, as defined by RFC 1945 [6], improved + the protocol by allowing messages to be in the format of MIME-like + messages, containing metainformation about the data transferred and + modifiers on the request/response semantics. However, HTTP/1.0 does + not sufficiently take into consideration the effects of hierarchical + proxies, caching, the need for persistent connections, and virtual + hosts. In addition, the proliferation of incompletely-implemented + applications calling themselves "HTTP/1.0" has necessitated a + protocol version change in order for two communicating applications + to determine each other's true capabilities. + + This specification defines the protocol referred to as "HTTP/1.1". + This protocol includes more stringent requirements than HTTP/1.0 in + order to ensure reliable implementation of its features. + + Practical information systems require more functionality than simple + retrieval, including search, front-end update, and annotation. HTTP + allows an open-ended set of methods that indicate the purpose of a + request. It builds on the discipline of reference provided by the + Uniform Resource Identifier (URI) [3][20], as a location (URL) [4] or + name (URN) , for indicating the resource to which a method is to be + applied. Messages are passed in a format similar to that used by + Internet mail as defined by the Multipurpose Internet Mail Extensions + (MIME). + + HTTP is also used as a generic protocol for communication between + user agents and proxies/gateways to other Internet systems, including + those supported by the SMTP [16], NNTP [13], FTP [18], Gopher [2], + and WAIS [10] protocols. In this way, HTTP allows basic hypermedia + access to resources available from diverse applications. + +1.2 Requirements + + This specification uses the same words as RFC 1123 [8] for defining + the significance of each particular requirement. These words are: + + MUST + This word or the adjective "required" means that the item is an + absolute requirement of the specification. + + + +Fielding, et. al. Standards Track [Page 7] + +RFC 2068 HTTP/1.1 January 1997 + + + SHOULD + This word or the adjective "recommended" means that there may + exist valid reasons in particular circumstances to ignore this + item, but the full implications should be understood and the case + carefully weighed before choosing a different course. + + MAY + This word or the adjective "optional" means that this item is + truly optional. One vendor may choose to include the item because + a particular marketplace requires it or because it enhances the + product, for example; another vendor may omit the same item. + + An implementation is not compliant if it fails to satisfy one or more + of the MUST requirements for the protocols it implements. An + implementation that satisfies all the MUST and all the SHOULD + requirements for its protocols is said to be "unconditionally + compliant"; one that satisfies all the MUST requirements but not all + the SHOULD requirements for its protocols is said to be + "conditionally compliant." + +1.3 Terminology + + This specification uses a number of terms to refer to the roles + played by participants in, and objects of, the HTTP communication. + + connection + A transport layer virtual circuit established between two programs + for the purpose of communication. + + message + The basic unit of HTTP communication, consisting of a structured + sequence of octets matching the syntax defined in section 4 and + transmitted via the connection. + + request + An HTTP request message, as defined in section 5. + + response + An HTTP response message, as defined in section 6. + + resource + A network data object or service that can be identified by a URI, + as defined in section 3.2. Resources may be available in multiple + representations (e.g. multiple languages, data formats, size, + resolutions) or vary in other ways. + + + + + + +Fielding, et. al. Standards Track [Page 8] + +RFC 2068 HTTP/1.1 January 1997 + + + entity + The information transferred as the payload of a request or + response. An entity consists of metainformation in the form of + entity-header fields and content in the form of an entity-body, as + described in section 7. + + representation + An entity included with a response that is subject to content + negotiation, as described in section 12. There may exist multiple + representations associated with a particular response status. + + content negotiation + The mechanism for selecting the appropriate representation when + servicing a request, as described in section 12. The + representation of entities in any response can be negotiated + (including error responses). + + variant + A resource may have one, or more than one, representation(s) + associated with it at any given instant. Each of these + representations is termed a `variant.' Use of the term `variant' + does not necessarily imply that the resource is subject to content + negotiation. + + client + A program that establishes connections for the purpose of sending + requests. + + user agent + The client which initiates a request. These are often browsers, + editors, spiders (web-traversing robots), or other end user tools. + + server + An application program that accepts connections in order to + service requests by sending back responses. Any given program may + be capable of being both a client and a server; our use of these + terms refers only to the role being performed by the program for a + particular connection, rather than to the program's capabilities + in general. Likewise, any server may act as an origin server, + proxy, gateway, or tunnel, switching behavior based on the nature + of each request. + + origin server + The server on which a given resource resides or is to be created. + + + + + + + +Fielding, et. al. Standards Track [Page 9] + +RFC 2068 HTTP/1.1 January 1997 + + + proxy + An intermediary program which acts as both a server and a client + for the purpose of making requests on behalf of other clients. + Requests are serviced internally or by passing them on, with + possible translation, to other servers. A proxy must implement + both the client and server requirements of this specification. + + gateway + A server which acts as an intermediary for some other server. + Unlike a proxy, a gateway receives requests as if it were the + origin server for the requested resource; the requesting client + may not be aware that it is communicating with a gateway. + + tunnel + An intermediary program which is acting as a blind relay between + two connections. Once active, a tunnel is not considered a party + to the HTTP communication, though the tunnel may have been + initiated by an HTTP request. The tunnel ceases to exist when both + ends of the relayed connections are closed. + + cache + A program's local store of response messages and the subsystem + that controls its message storage, retrieval, and deletion. A + cache stores cachable responses in order to reduce the response + time and network bandwidth consumption on future, equivalent + requests. Any client or server may include a cache, though a cache + cannot be used by a server that is acting as a tunnel. + + cachable + A response is cachable if a cache is allowed to store a copy of + the response message for use in answering subsequent requests. The + rules for determining the cachability of HTTP responses are + defined in section 13. Even if a resource is cachable, there may + be additional constraints on whether a cache can use the cached + copy for a particular request. + + first-hand + A response is first-hand if it comes directly and without + unnecessary delay from the origin server, perhaps via one or more + proxies. A response is also first-hand if its validity has just + been checked directly with the origin server. + + explicit expiration time + The time at which the origin server intends that an entity should + no longer be returned by a cache without further validation. + + + + + + +Fielding, et. al. Standards Track [Page 10] + +RFC 2068 HTTP/1.1 January 1997 + + + heuristic expiration time + An expiration time assigned by a cache when no explicit expiration + time is available. + + age + The age of a response is the time since it was sent by, or + successfully validated with, the origin server. + + freshness lifetime + The length of time between the generation of a response and its + expiration time. + + fresh + A response is fresh if its age has not yet exceeded its freshness + lifetime. + + stale + A response is stale if its age has passed its freshness lifetime. + + semantically transparent + A cache behaves in a "semantically transparent" manner, with + respect to a particular response, when its use affects neither the + requesting client nor the origin server, except to improve + performance. When a cache is semantically transparent, the client + receives exactly the same response (except for hop-by-hop headers) + that it would have received had its request been handled directly + by the origin server. + + validator + A protocol element (e.g., an entity tag or a Last-Modified time) + that is used to find out whether a cache entry is an equivalent + copy of an entity. + +1.4 Overall Operation + + The HTTP protocol is a request/response protocol. A client sends a + request to the server in the form of a request method, URI, and + protocol version, followed by a MIME-like message containing request + modifiers, client information, and possible body content over a + connection with a server. The server responds with a status line, + including the message's protocol version and a success or error code, + followed by a MIME-like message containing server information, entity + metainformation, and possible entity-body content. The relationship + between HTTP and MIME is described in appendix 19.4. + + + + + + + +Fielding, et. al. Standards Track [Page 11] + +RFC 2068 HTTP/1.1 January 1997 + + + Most HTTP communication is initiated by a user agent and consists of + a request to be applied to a resource on some origin server. In the + simplest case, this may be accomplished via a single connection (v) + between the user agent (UA) and the origin server (O). + + request chain ------------------------> + UA -------------------v------------------- O + <----------------------- response chain + + A more complicated situation occurs when one or more intermediaries + are present in the request/response chain. There are three common + forms of intermediary: proxy, gateway, and tunnel. A proxy is a + forwarding agent, receiving requests for a URI in its absolute form, + rewriting all or part of the message, and forwarding the reformatted + request toward the server identified by the URI. A gateway is a + receiving agent, acting as a layer above some other server(s) and, if + necessary, translating the requests to the underlying server's + protocol. A tunnel acts as a relay point between two connections + without changing the messages; tunnels are used when the + communication needs to pass through an intermediary (such as a + firewall) even when the intermediary cannot understand the contents + of the messages. + + request chain --------------------------------------> + UA -----v----- A -----v----- B -----v----- C -----v----- O + <------------------------------------- response chain + + The figure above shows three intermediaries (A, B, and C) between the + user agent and origin server. A request or response message that + travels the whole chain will pass through four separate connections. + This distinction is important because some HTTP communication options + may apply only to the connection with the nearest, non-tunnel + neighbor, only to the end-points of the chain, or to all connections + along the chain. Although the diagram is linear, each participant + may be engaged in multiple, simultaneous communications. For example, + B may be receiving requests from many clients other than A, and/or + forwarding requests to servers other than C, at the same time that it + is handling A's request. + + Any party to the communication which is not acting as a tunnel may + employ an internal cache for handling requests. The effect of a cache + is that the request/response chain is shortened if one of the + participants along the chain has a cached response applicable to that + request. The following illustrates the resulting chain if B has a + cached copy of an earlier response from O (via C) for a request which + has not been cached by UA or A. + + + + + +Fielding, et. al. Standards Track [Page 12] + +RFC 2068 HTTP/1.1 January 1997 + + + request chain ----------> + UA -----v----- A -----v----- B - - - - - - C - - - - - - O + <--------- response chain + + Not all responses are usefully cachable, and some requests may + contain modifiers which place special requirements on cache behavior. + HTTP requirements for cache behavior and cachable responses are + defined in section 13. + + In fact, there are a wide variety of architectures and configurations + of caches and proxies currently being experimented with or deployed + across the World Wide Web; these systems include national hierarchies + of proxy caches to save transoceanic bandwidth, systems that + broadcast or multicast cache entries, organizations that distribute + subsets of cached data via CD-ROM, and so on. HTTP systems are used + in corporate intranets over high-bandwidth links, and for access via + PDAs with low-power radio links and intermittent connectivity. The + goal of HTTP/1.1 is to support the wide diversity of configurations + already deployed while introducing protocol constructs that meet the + needs of those who build web applications that require high + reliability and, failing that, at least reliable indications of + failure. + + HTTP communication usually takes place over TCP/IP connections. The + default port is TCP 80, but other ports can be used. This does not + preclude HTTP from being implemented on top of any other protocol on + the Internet, or on other networks. HTTP only presumes a reliable + transport; any protocol that provides such guarantees can be used; + the mapping of the HTTP/1.1 request and response structures onto the + transport data units of the protocol in question is outside the scope + of this specification. + + In HTTP/1.0, most implementations used a new connection for each + request/response exchange. In HTTP/1.1, a connection may be used for + one or more request/response exchanges, although connections may be + closed for a variety of reasons (see section 8.1). + +2 Notational Conventions and Generic Grammar + +2.1 Augmented BNF + + All of the mechanisms specified in this document are described in + both prose and an augmented Backus-Naur Form (BNF) similar to that + used by RFC 822 [9]. Implementers will need to be familiar with the + notation in order to understand this specification. The augmented BNF + includes the following constructs: + + + + + +Fielding, et. al. Standards Track [Page 13] + +RFC 2068 HTTP/1.1 January 1997 + + +name = definition + The name of a rule is simply the name itself (without any enclosing + "<" and ">") and is separated from its definition by the equal "=" + character. Whitespace is only significant in that indentation of + continuation lines is used to indicate a rule definition that spans + more than one line. Certain basic rules are in uppercase, such as + SP, LWS, HT, CRLF, DIGIT, ALPHA, etc. Angle brackets are used + within definitions whenever their presence will facilitate + discerning the use of rule names. + +"literal" + Quotation marks surround literal text. Unless stated otherwise, the + text is case-insensitive. + +rule1 | rule2 + Elements separated by a bar ("|") are alternatives, e.g., "yes | + no" will accept yes or no. + +(rule1 rule2) + Elements enclosed in parentheses are treated as a single element. + Thus, "(elem (foo | bar) elem)" allows the token sequences "elem + foo elem" and "elem bar elem". + +*rule + The character "*" preceding an element indicates repetition. The + full form is "*element" indicating at least and at most + occurrences of element. Default values are 0 and infinity so + that "*(element)" allows any number, including zero; "1*element" + requires at least one; and "1*2element" allows one or two. + +[rule] + Square brackets enclose optional elements; "[foo bar]" is + equivalent to "*1(foo bar)". + +N rule + Specific repetition: "(element)" is equivalent to + "*(element)"; that is, exactly occurrences of (element). + Thus 2DIGIT is a 2-digit number, and 3ALPHA is a string of three + alphabetic characters. + +#rule + A construct "#" is defined, similar to "*", for defining lists of + elements. The full form is "#element " indicating at least + and at most elements, each separated by one or more commas + (",") and optional linear whitespace (LWS). This makes the usual + form of lists very easy; a rule such as "( *LWS element *( *LWS "," + *LWS element )) " can be shown as "1#element". Wherever this + construct is used, null elements are allowed, but do not contribute + + + +Fielding, et. al. Standards Track [Page 14] + +RFC 2068 HTTP/1.1 January 1997 + + + to the count of elements present. That is, "(element), , (element) + " is permitted, but counts as only two elements. Therefore, where + at least one element is required, at least one non-null element + must be present. Default values are 0 and infinity so that + "#element" allows any number, including zero; "1#element" requires + at least one; and "1#2element" allows one or two. + +; comment + A semi-colon, set off some distance to the right of rule text, + starts a comment that continues to the end of line. This is a + simple way of including useful notes in parallel with the + specifications. + +implied *LWS + The grammar described by this specification is word-based. Except + where noted otherwise, linear whitespace (LWS) can be included + between any two adjacent words (token or quoted-string), and + between adjacent tokens and delimiters (tspecials), without + changing the interpretation of a field. At least one delimiter + (tspecials) must exist between any two tokens, since they would + otherwise be interpreted as a single token. + +2.2 Basic Rules + + The following rules are used throughout this specification to + describe basic parsing constructs. The US-ASCII coded character set + is defined by ANSI X3.4-1986 [21]. + + OCTET = + CHAR = + UPALPHA = + LOALPHA = + ALPHA = UPALPHA | LOALPHA + DIGIT = + CTL = + CR = + LF = + SP = + HT = + <"> = + + + + + + + + + + +Fielding, et. al. Standards Track [Page 15] + +RFC 2068 HTTP/1.1 January 1997 + + + HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all + protocol elements except the entity-body (see appendix 19.3 for + tolerant applications). The end-of-line marker within an entity-body + is defined by its associated media type, as described in section 3.7. + + CRLF = CR LF + + HTTP/1.1 headers can be folded onto multiple lines if the + continuation line begins with a space or horizontal tab. All linear + white space, including folding, has the same semantics as SP. + + LWS = [CRLF] 1*( SP | HT ) + + The TEXT rule is only used for descriptive field contents and values + that are not intended to be interpreted by the message parser. Words + of *TEXT may contain characters from character sets other than ISO + 8859-1 [22] only when encoded according to the rules of RFC 1522 + [14]. + + TEXT = + + Hexadecimal numeric characters are used in several protocol elements. + + HEX = "A" | "B" | "C" | "D" | "E" | "F" + | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT + + Many HTTP/1.1 header field values consist of words separated by LWS + or special characters. These special characters MUST be in a quoted + string to be used within a parameter value. + + token = 1* + + tspecials = "(" | ")" | "<" | ">" | "@" + | "," | ";" | ":" | "\" | <"> + | "/" | "[" | "]" | "?" | "=" + | "{" | "}" | SP | HT + + Comments can be included in some HTTP header fields by surrounding + the comment text with parentheses. Comments are only allowed in + fields containing "comment" as part of their field value definition. + In all other fields, parentheses are considered part of the field + value. + + comment = "(" *( ctext | comment ) ")" + ctext = + + + + + +Fielding, et. al. Standards Track [Page 16] + +RFC 2068 HTTP/1.1 January 1997 + + + A string of text is parsed as a single word if it is quoted using + double-quote marks. + + quoted-string = ( <"> *(qdtext) <"> ) + + qdtext = > + + The backslash character ("\") may be used as a single-character quoting + mechanism only within quoted-string and comment constructs. + + quoted-pair = "\" CHAR + +3 Protocol Parameters + +3.1 HTTP Version + + HTTP uses a "." numbering scheme to indicate versions + of the protocol. The protocol versioning policy is intended to allow + the sender to indicate the format of a message and its capacity for + understanding further HTTP communication, rather than the features + obtained via that communication. No change is made to the version + number for the addition of message components which do not affect + communication behavior or which only add to extensible field values. + The number is incremented when the changes made to the + protocol add features which do not change the general message parsing + algorithm, but which may add to the message semantics and imply + additional capabilities of the sender. The number is + incremented when the format of a message within the protocol is + changed. + + The version of an HTTP message is indicated by an HTTP-Version field + in the first line of the message. + + HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT + + Note that the major and minor numbers MUST be treated as separate + integers and that each may be incremented higher than a single digit. + Thus, HTTP/2.4 is a lower version than HTTP/2.13, which in turn is + lower than HTTP/12.3. Leading zeros MUST be ignored by recipients and + MUST NOT be sent. + + Applications sending Request or Response messages, as defined by this + specification, MUST include an HTTP-Version of "HTTP/1.1". Use of + this version number indicates that the sending application is at + least conditionally compliant with this specification. + + The HTTP version of an application is the highest HTTP version for + which the application is at least conditionally compliant. + + + +Fielding, et. al. Standards Track [Page 17] + +RFC 2068 HTTP/1.1 January 1997 + + + Proxy and gateway applications must be careful when forwarding + messages in protocol versions different from that of the application. + Since the protocol version indicates the protocol capability of the + sender, a proxy/gateway MUST never send a message with a version + indicator which is greater than its actual version; if a higher + version request is received, the proxy/gateway MUST either downgrade + the request version, respond with an error, or switch to tunnel + behavior. Requests with a version lower than that of the + proxy/gateway's version MAY be upgraded before being forwarded; the + proxy/gateway's response to that request MUST be in the same major + version as the request. + + Note: Converting between versions of HTTP may involve modification + of header fields required or forbidden by the versions involved. + +3.2 Uniform Resource Identifiers + + URIs have been known by many names: WWW addresses, Universal Document + Identifiers, Universal Resource Identifiers , and finally the + combination of Uniform Resource Locators (URL) and Names (URN). As + far as HTTP is concerned, Uniform Resource Identifiers are simply + formatted strings which identify--via name, location, or any other + characteristic--a resource. + +3.2.1 General Syntax + + URIs in HTTP can be represented in absolute form or relative to some + known base URI, depending upon the context of their use. The two + forms are differentiated by the fact that absolute URIs always begin + with a scheme name followed by a colon. + + URI = ( absoluteURI | relativeURI ) [ "#" fragment ] + + absoluteURI = scheme ":" *( uchar | reserved ) + + relativeURI = net_path | abs_path | rel_path + + net_path = "//" net_loc [ abs_path ] + abs_path = "/" rel_path + rel_path = [ path ] [ ";" params ] [ "?" query ] + + path = fsegment *( "/" segment ) + fsegment = 1*pchar + segment = *pchar + + params = param *( ";" param ) + param = *( pchar | "/" ) + + + + +Fielding, et. al. Standards Track [Page 18] + +RFC 2068 HTTP/1.1 January 1997 + + + scheme = 1*( ALPHA | DIGIT | "+" | "-" | "." ) + net_loc = *( pchar | ";" | "?" ) + + query = *( uchar | reserved ) + fragment = *( uchar | reserved ) + + pchar = uchar | ":" | "@" | "&" | "=" | "+" + uchar = unreserved | escape + unreserved = ALPHA | DIGIT | safe | extra | national + + escape = "%" HEX HEX + reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" + extra = "!" | "*" | "'" | "(" | ")" | "," + safe = "$" | "-" | "_" | "." + unsafe = CTL | SP | <"> | "#" | "%" | "<" | ">" + national = + + For definitive information on URL syntax and semantics, see RFC 1738 + [4] and RFC 1808 [11]. The BNF above includes national characters not + allowed in valid URLs as specified by RFC 1738, since HTTP servers + are not restricted in the set of unreserved characters allowed to + represent the rel_path part of addresses, and HTTP proxies may + receive requests for URIs not defined by RFC 1738. + + The HTTP protocol does not place any a priori limit on the length of + a URI. Servers MUST be able to handle the URI of any resource they + serve, and SHOULD be able to handle URIs of unbounded length if they + provide GET-based forms that could generate such URIs. A server + SHOULD return 414 (Request-URI Too Long) status if a URI is longer + than the server can handle (see section 10.4.15). + + Note: Servers should be cautious about depending on URI lengths + above 255 bytes, because some older client or proxy implementations + may not properly support these lengths. + +3.2.2 http URL + + The "http" scheme is used to locate network resources via the HTTP + protocol. This section defines the scheme-specific syntax and + semantics for http URLs. + + + + + + + + + + +Fielding, et. al. Standards Track [Page 19] + +RFC 2068 HTTP/1.1 January 1997 + + + http_URL = "http:" "//" host [ ":" port ] [ abs_path ] + + host = + + port = *DIGIT + + If the port is empty or not given, port 80 is assumed. The semantics + are that the identified resource is located at the server listening + for TCP connections on that port of that host, and the Request-URI + for the resource is abs_path. The use of IP addresses in URL's SHOULD + be avoided whenever possible (see RFC 1900 [24]). If the abs_path is + not present in the URL, it MUST be given as "/" when used as a + Request-URI for a resource (section 5.1.2). + +3.2.3 URI Comparison + + When comparing two URIs to decide if they match or not, a client + SHOULD use a case-sensitive octet-by-octet comparison of the entire + URIs, with these exceptions: + + o A port that is empty or not given is equivalent to the default + port for that URI; + + o Comparisons of host names MUST be case-insensitive; + + o Comparisons of scheme names MUST be case-insensitive; + + o An empty abs_path is equivalent to an abs_path of "/". + + Characters other than those in the "reserved" and "unsafe" sets (see + section 3.2) are equivalent to their ""%" HEX HEX" encodings. + + For example, the following three URIs are equivalent: + + http://abc.com:80/~smith/home.html + http://ABC.com/%7Esmith/home.html + http://ABC.com:/%7esmith/home.html + + + + + + + + + + + + +Fielding, et. al. Standards Track [Page 20] + +RFC 2068 HTTP/1.1 January 1997 + + +3.3 Date/Time Formats + +3.3.1 Full Date + + HTTP applications have historically allowed three different formats + for the representation of date/time stamps: + + Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 + Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036 + Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format + + The first format is preferred as an Internet standard and represents + a fixed-length subset of that defined by RFC 1123 (an update to RFC + 822). The second format is in common use, but is based on the + obsolete RFC 850 [12] date format and lacks a four-digit year. + HTTP/1.1 clients and servers that parse the date value MUST accept + all three formats (for compatibility with HTTP/1.0), though they MUST + only generate the RFC 1123 format for representing HTTP-date values + in header fields. + + Note: Recipients of date values are encouraged to be robust in + accepting date values that may have been sent by non-HTTP + applications, as is sometimes the case when retrieving or posting + messages via proxies/gateways to SMTP or NNTP. + + All HTTP date/time stamps MUST be represented in Greenwich Mean Time + (GMT), without exception. This is indicated in the first two formats + by the inclusion of "GMT" as the three-letter abbreviation for time + zone, and MUST be assumed when reading the asctime format. + + HTTP-date = rfc1123-date | rfc850-date | asctime-date + + rfc1123-date = wkday "," SP date1 SP time SP "GMT" + rfc850-date = weekday "," SP date2 SP time SP "GMT" + asctime-date = wkday SP date3 SP time SP 4DIGIT + + date1 = 2DIGIT SP month SP 4DIGIT + ; day month year (e.g., 02 Jun 1982) + date2 = 2DIGIT "-" month "-" 2DIGIT + ; day-month-year (e.g., 02-Jun-82) + date3 = month SP ( 2DIGIT | ( SP 1DIGIT )) + ; month day (e.g., Jun 2) + + time = 2DIGIT ":" 2DIGIT ":" 2DIGIT + ; 00:00:00 - 23:59:59 + + wkday = "Mon" | "Tue" | "Wed" + | "Thu" | "Fri" | "Sat" | "Sun" + + + +Fielding, et. al. Standards Track [Page 21] + +RFC 2068 HTTP/1.1 January 1997 + + + weekday = "Monday" | "Tuesday" | "Wednesday" + | "Thursday" | "Friday" | "Saturday" | "Sunday" + + month = "Jan" | "Feb" | "Mar" | "Apr" + | "May" | "Jun" | "Jul" | "Aug" + | "Sep" | "Oct" | "Nov" | "Dec" + + Note: HTTP requirements for the date/time stamp format apply only + to their usage within the protocol stream. Clients and servers are + not required to use these formats for user presentation, request + logging, etc. + +3.3.2 Delta Seconds + + Some HTTP header fields allow a time value to be specified as an + integer number of seconds, represented in decimal, after the time + that the message was received. + + delta-seconds = 1*DIGIT + +3.4 Character Sets + + HTTP uses the same definition of the term "character set" as that + described for MIME: + + The term "character set" is used in this document to refer to a + method used with one or more tables to convert a sequence of octets + into a sequence of characters. Note that unconditional conversion + in the other direction is not required, in that not all characters + may be available in a given character set and a character set may + provide more than one sequence of octets to represent a particular + character. This definition is intended to allow various kinds of + character encodings, from simple single-table mappings such as US- + ASCII to complex table switching methods such as those that use ISO + 2022's techniques. However, the definition associated with a MIME + character set name MUST fully specify the mapping to be performed + from octets to characters. In particular, use of external profiling + information to determine the exact mapping is not permitted. + + Note: This use of the term "character set" is more commonly + referred to as a "character encoding." However, since HTTP and MIME + share the same registry, it is important that the terminology also + be shared. + + + + + + + + +Fielding, et. al. Standards Track [Page 22] + +RFC 2068 HTTP/1.1 January 1997 + + + HTTP character sets are identified by case-insensitive tokens. The + complete set of tokens is defined by the IANA Character Set registry + [19]. + + charset = token + + Although HTTP allows an arbitrary token to be used as a charset + value, any token that has a predefined value within the IANA + Character Set registry MUST represent the character set defined by + that registry. Applications SHOULD limit their use of character sets + to those defined by the IANA registry. + +3.5 Content Codings + + Content coding values indicate an encoding transformation that has + been or can be applied to an entity. Content codings are primarily + used to allow a document to be compressed or otherwise usefully + transformed without losing the identity of its underlying media type + and without loss of information. Frequently, the entity is stored in + coded form, transmitted directly, and only decoded by the recipient. + + content-coding = token + + All content-coding values are case-insensitive. HTTP/1.1 uses + content-coding values in the Accept-Encoding (section 14.3) and + Content-Encoding (section 14.12) header fields. Although the value + describes the content-coding, what is more important is that it + indicates what decoding mechanism will be required to remove the + encoding. + + The Internet Assigned Numbers Authority (IANA) acts as a registry for + content-coding value tokens. Initially, the registry contains the + following tokens: + + gzip An encoding format produced by the file compression program "gzip" + (GNU zip) as described in RFC 1952 [25]. This format is a Lempel- + Ziv coding (LZ77) with a 32 bit CRC. + + compress + The encoding format produced by the common UNIX file compression + program "compress". This format is an adaptive Lempel-Ziv-Welch + coding (LZW). + + + + + + + + + +Fielding, et. al. Standards Track [Page 23] + +RFC 2068 HTTP/1.1 January 1997 + + + Note: Use of program names for the identification of encoding + formats is not desirable and should be discouraged for future + encodings. Their use here is representative of historical practice, + not good design. For compatibility with previous implementations of + HTTP, applications should consider "x-gzip" and "x-compress" to be + equivalent to "gzip" and "compress" respectively. + + deflate The "zlib" format defined in RFC 1950[31] in combination with + the "deflate" compression mechanism described in RFC 1951[29]. + + New content-coding value tokens should be registered; to allow + interoperability between clients and servers, specifications of the + content coding algorithms needed to implement a new value should be + publicly available and adequate for independent implementation, and + conform to the purpose of content coding defined in this section. + +3.6 Transfer Codings + + Transfer coding values are used to indicate an encoding + transformation that has been, can be, or may need to be applied to an + entity-body in order to ensure "safe transport" through the network. + This differs from a content coding in that the transfer coding is a + property of the message, not of the original entity. + + transfer-coding = "chunked" | transfer-extension + + transfer-extension = token + + All transfer-coding values are case-insensitive. HTTP/1.1 uses + transfer coding values in the Transfer-Encoding header field (section + 14.40). + + Transfer codings are analogous to the Content-Transfer-Encoding + values of MIME , which were designed to enable safe transport of + binary data over a 7-bit transport service. However, safe transport + has a different focus for an 8bit-clean transfer protocol. In HTTP, + the only unsafe characteristic of message-bodies is the difficulty in + determining the exact body length (section 7.2.2), or the desire to + encrypt data over a shared transport. + + The chunked encoding modifies the body of a message in order to + transfer it as a series of chunks, each with its own size indicator, + followed by an optional footer containing entity-header fields. This + allows dynamically-produced content to be transferred along with the + information necessary for the recipient to verify that it has + received the full message. + + + + + +Fielding, et. al. Standards Track [Page 24] + +RFC 2068 HTTP/1.1 January 1997 + + + Chunked-Body = *chunk + "0" CRLF + footer + CRLF + + chunk = chunk-size [ chunk-ext ] CRLF + chunk-data CRLF + + hex-no-zero = + + chunk-size = hex-no-zero *HEX + chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-value ] ) + chunk-ext-name = token + chunk-ext-val = token | quoted-string + chunk-data = chunk-size(OCTET) + + footer = *entity-header + + The chunked encoding is ended by a zero-sized chunk followed by the + footer, which is terminated by an empty line. The purpose of the + footer is to provide an efficient way to supply information about an + entity that is generated dynamically; applications MUST NOT send + header fields in the footer which are not explicitly defined as being + appropriate for the footer, such as Content-MD5 or future extensions + to HTTP for digital signatures or other facilities. + + An example process for decoding a Chunked-Body is presented in + appendix 19.4.6. + + All HTTP/1.1 applications MUST be able to receive and decode the + "chunked" transfer coding, and MUST ignore transfer coding extensions + they do not understand. A server which receives an entity-body with a + transfer-coding it does not understand SHOULD return 501 + (Unimplemented), and close the connection. A server MUST NOT send + transfer-codings to an HTTP/1.0 client. + +3.7 Media Types + + HTTP uses Internet Media Types in the Content-Type (section 14.18) + and Accept (section 14.1) header fields in order to provide open and + extensible data typing and type negotiation. + + media-type = type "/" subtype *( ";" parameter ) + type = token + subtype = token + + Parameters may follow the type/subtype in the form of attribute/value + pairs. + + + +Fielding, et. al. Standards Track [Page 25] + +RFC 2068 HTTP/1.1 January 1997 + + + parameter = attribute "=" value + attribute = token + value = token | quoted-string + + The type, subtype, and parameter attribute names are case- + insensitive. Parameter values may or may not be case-sensitive, + depending on the semantics of the parameter name. Linear white space + (LWS) MUST NOT be used between the type and subtype, nor between an + attribute and its value. User agents that recognize the media-type + MUST process (or arrange to be processed by any external applications + used to process that type/subtype by the user agent) the parameters + for that MIME type as described by that type/subtype definition to + the and inform the user of any problems discovered. + + Note: some older HTTP applications do not recognize media type + parameters. When sending data to older HTTP applications, + implementations should only use media type parameters when they are + required by that type/subtype definition. + + Media-type values are registered with the Internet Assigned Number + Authority (IANA). The media type registration process is outlined in + RFC 2048 [17]. Use of non-registered media types is discouraged. + +3.7.1 Canonicalization and Text Defaults + + Internet media types are registered with a canonical form. In + general, an entity-body transferred via HTTP messages MUST be + represented in the appropriate canonical form prior to its + transmission; the exception is "text" types, as defined in the next + paragraph. + + When in canonical form, media subtypes of the "text" type use CRLF as + the text line break. HTTP relaxes this requirement and allows the + transport of text media with plain CR or LF alone representing a line + break when it is done consistently for an entire entity-body. HTTP + applications MUST accept CRLF, bare CR, and bare LF as being + representative of a line break in text media received via HTTP. In + addition, if the text is represented in a character set that does not + use octets 13 and 10 for CR and LF respectively, as is the case for + some multi-byte character sets, HTTP allows the use of whatever octet + sequences are defined by that character set to represent the + equivalent of CR and LF for line breaks. This flexibility regarding + line breaks applies only to text media in the entity-body; a bare CR + or LF MUST NOT be substituted for CRLF within any of the HTTP control + structures (such as header fields and multipart boundaries). + + If an entity-body is encoded with a Content-Encoding, the underlying + data MUST be in a form defined above prior to being encoded. + + + +Fielding, et. al. Standards Track [Page 26] + +RFC 2068 HTTP/1.1 January 1997 + + + The "charset" parameter is used with some media types to define the + character set (section 3.4) of the data. When no explicit charset + parameter is provided by the sender, media subtypes of the "text" + type are defined to have a default charset value of "ISO-8859-1" when + received via HTTP. Data in character sets other than "ISO-8859-1" or + its subsets MUST be labeled with an appropriate charset value. + + Some HTTP/1.0 software has interpreted a Content-Type header without + charset parameter incorrectly to mean "recipient should guess." + Senders wishing to defeat this behavior MAY include a charset + parameter even when the charset is ISO-8859-1 and SHOULD do so when + it is known that it will not confuse the recipient. + + Unfortunately, some older HTTP/1.0 clients did not deal properly with + an explicit charset parameter. HTTP/1.1 recipients MUST respect the + charset label provided by the sender; and those user agents that have + a provision to "guess" a charset MUST use the charset from the + content-type field if they support that charset, rather than the + recipient's preference, when initially displaying a document. + +3.7.2 Multipart Types + + MIME provides for a number of "multipart" types -- encapsulations of + one or more entities within a single message-body. All multipart + types share a common syntax, as defined in MIME [7], and MUST + include a boundary parameter as part of the media type value. The + message body is itself a protocol element and MUST therefore use only + CRLF to represent line breaks between body-parts. Unlike in MIME, the + epilogue of any multipart message MUST be empty; HTTP applications + MUST NOT transmit the epilogue (even if the original multipart + contains an epilogue). + + In HTTP, multipart body-parts MAY contain header fields which are + significant to the meaning of that part. A Content-Location header + field (section 14.15) SHOULD be included in the body-part of each + enclosed entity that can be identified by a URL. + + In general, an HTTP user agent SHOULD follow the same or similar + behavior as a MIME user agent would upon receipt of a multipart type. + If an application receives an unrecognized multipart subtype, the + application MUST treat it as being equivalent to "multipart/mixed". + + Note: The "multipart/form-data" type has been specifically defined + for carrying form data suitable for processing via the POST request + method, as described in RFC 1867 [15]. + + + + + + +Fielding, et. al. Standards Track [Page 27] + +RFC 2068 HTTP/1.1 January 1997 + + +3.8 Product Tokens + + Product tokens are used to allow communicating applications to + identify themselves by software name and version. Most fields using + product tokens also allow sub-products which form a significant part + of the application to be listed, separated by whitespace. By + convention, the products are listed in order of their significance + for identifying the application. + + product = token ["/" product-version] + product-version = token + + Examples: + + User-Agent: CERN-LineMode/2.15 libwww/2.17b3 + Server: Apache/0.8.4 + + Product tokens should be short and to the point -- use of them for + advertising or other non-essential information is explicitly + forbidden. Although any token character may appear in a product- + version, this token SHOULD only be used for a version identifier + (i.e., successive versions of the same product SHOULD only differ in + the product-version portion of the product value). + +3.9 Quality Values + + HTTP content negotiation (section 12) uses short "floating point" + numbers to indicate the relative importance ("weight") of various + negotiable parameters. A weight is normalized to a real number in the + range 0 through 1, where 0 is the minimum and 1 the maximum value. + HTTP/1.1 applications MUST NOT generate more than three digits after + the decimal point. User configuration of these values SHOULD also be + limited in this fashion. + + qvalue = ( "0" [ "." 0*3DIGIT ] ) + | ( "1" [ "." 0*3("0") ] ) + + "Quality values" is a misnomer, since these values merely represent + relative degradation in desired quality. + +3.10 Language Tags + + A language tag identifies a natural language spoken, written, or + otherwise conveyed by human beings for communication of information + to other human beings. Computer languages are explicitly excluded. + HTTP uses language tags within the Accept-Language and Content- + Language fields. + + + + +Fielding, et. al. Standards Track [Page 28] + +RFC 2068 HTTP/1.1 January 1997 + + + The syntax and registry of HTTP language tags is the same as that + defined by RFC 1766 [1]. In summary, a language tag is composed of 1 + or more parts: A primary language tag and a possibly empty series of + subtags: + + language-tag = primary-tag *( "-" subtag ) + + primary-tag = 1*8ALPHA + subtag = 1*8ALPHA + + Whitespace is not allowed within the tag and all tags are case- + insensitive. The name space of language tags is administered by the + IANA. Example tags include: + + en, en-US, en-cockney, i-cherokee, x-pig-latin + + where any two-letter primary-tag is an ISO 639 language abbreviation + and any two-letter initial subtag is an ISO 3166 country code. (The + last three tags above are not registered tags; all but the last are + examples of tags which could be registered in future.) + +3.11 Entity Tags + + Entity tags are used for comparing two or more entities from the same + requested resource. HTTP/1.1 uses entity tags in the ETag (section + 14.20), If-Match (section 14.25), If-None-Match (section 14.26), and + If-Range (section 14.27) header fields. The definition of how they + are used and compared as cache validators is in section 13.3.3. An + entity tag consists of an opaque quoted string, possibly prefixed by + a weakness indicator. + + entity-tag = [ weak ] opaque-tag + + weak = "W/" + opaque-tag = quoted-string + + A "strong entity tag" may be shared by two entities of a resource + only if they are equivalent by octet equality. + + A "weak entity tag," indicated by the "W/" prefix, may be shared by + two entities of a resource only if the entities are equivalent and + could be substituted for each other with no significant change in + semantics. A weak entity tag can only be used for weak comparison. + + An entity tag MUST be unique across all versions of all entities + associated with a particular resource. A given entity tag value may + be used for entities obtained by requests on different URIs without + implying anything about the equivalence of those entities. + + + +Fielding, et. al. Standards Track [Page 29] + +RFC 2068 HTTP/1.1 January 1997 + + +3.12 Range Units + + HTTP/1.1 allows a client to request that only part (a range of) the + response entity be included within the response. HTTP/1.1 uses range + units in the Range (section 14.36) and Content-Range (section 14.17) + header fields. An entity may be broken down into subranges according + to various structural units. + + range-unit = bytes-unit | other-range-unit + + bytes-unit = "bytes" + other-range-unit = token + +The only range unit defined by HTTP/1.1 is "bytes". HTTP/1.1 + implementations may ignore ranges specified using other units. + HTTP/1.1 has been designed to allow implementations of applications + that do not depend on knowledge of ranges. + +4 HTTP Message + +4.1 Message Types + + HTTP messages consist of requests from client to server and responses + from server to client. + + HTTP-message = Request | Response ; HTTP/1.1 messages + + Request (section 5) and Response (section 6) messages use the generic + message format of RFC 822 [9] for transferring entities (the payload + of the message). Both types of message consist of a start-line, one + or more header fields (also known as "headers"), an empty line (i.e., + a line with nothing preceding the CRLF) indicating the end of the + header fields, and an optional message-body. + + generic-message = start-line + *message-header + CRLF + [ message-body ] + + start-line = Request-Line | Status-Line + + In the interest of robustness, servers SHOULD ignore any empty + line(s) received where a Request-Line is expected. In other words, if + the server is reading the protocol stream at the beginning of a + message and receives a CRLF first, it should ignore the CRLF. + + + + + + +Fielding, et. al. Standards Track [Page 30] + +RFC 2068 HTTP/1.1 January 1997 + + + Note: certain buggy HTTP/1.0 client implementations generate an + extra CRLF's after a POST request. To restate what is explicitly + forbidden by the BNF, an HTTP/1.1 client must not preface or follow + a request with an extra CRLF. + +4.2 Message Headers + + HTTP header fields, which include general-header (section 4.5), + request-header (section 5.3), response-header (section 6.2), and + entity-header (section 7.1) fields, follow the same generic format as + that given in Section 3.1 of RFC 822 [9]. Each header field consists + of a name followed by a colon (":") and the field value. Field names + are case-insensitive. The field value may be preceded by any amount + of LWS, though a single SP is preferred. Header fields can be + extended over multiple lines by preceding each extra line with at + least one SP or HT. Applications SHOULD follow "common form" when + generating HTTP constructs, since there might exist some + implementations that fail to accept anything beyond the common forms. + + message-header = field-name ":" [ field-value ] CRLF + + field-name = token + field-value = *( field-content | LWS ) + + field-content = + + The order in which header fields with differing field names are + received is not significant. However, it is "good practice" to send + general-header fields first, followed by request-header or response- + header fields, and ending with the entity-header fields. + + Multiple message-header fields with the same field-name may be + present in a message if and only if the entire field-value for that + header field is defined as a comma-separated list [i.e., #(values)]. + It MUST be possible to combine the multiple header fields into one + "field-name: field-value" pair, without changing the semantics of the + message, by appending each subsequent field-value to the first, each + separated by a comma. The order in which header fields with the same + field-name are received is therefore significant to the + interpretation of the combined field value, and thus a proxy MUST NOT + change the order of these field values when a message is forwarded. + + + + + + + + +Fielding, et. al. Standards Track [Page 31] + +RFC 2068 HTTP/1.1 January 1997 + + +4.3 Message Body + + The message-body (if any) of an HTTP message is used to carry the + entity-body associated with the request or response. The message-body + differs from the entity-body only when a transfer coding has been + applied, as indicated by the Transfer-Encoding header field (section + 14.40). + + message-body = entity-body + | + + Transfer-Encoding MUST be used to indicate any transfer codings + applied by an application to ensure safe and proper transfer of the + message. Transfer-Encoding is a property of the message, not of the + entity, and thus can be added or removed by any application along the + request/response chain. + + The rules for when a message-body is allowed in a message differ for + requests and responses. + + The presence of a message-body in a request is signaled by the + inclusion of a Content-Length or Transfer-Encoding header field in + the request's message-headers. A message-body MAY be included in a + request only when the request method (section 5.1.1) allows an + entity-body. + + For response messages, whether or not a message-body is included with + a message is dependent on both the request method and the response + status code (section 6.1.1). All responses to the HEAD request method + MUST NOT include a message-body, even though the presence of entity- + header fields might lead one to believe they do. All 1xx + (informational), 204 (no content), and 304 (not modified) responses + MUST NOT include a message-body. All other responses do include a + message-body, although it may be of zero length. + +4.4 Message Length + + When a message-body is included with a message, the length of that + body is determined by one of the following (in order of precedence): + + 1. Any response message which MUST NOT include a message-body + (such as the 1xx, 204, and 304 responses and any response to a HEAD + request) is always terminated by the first empty line after the + header fields, regardless of the entity-header fields present in the + message. + + 2. If a Transfer-Encoding header field (section 14.40) is present and + indicates that the "chunked" transfer coding has been applied, then + + + +Fielding, et. al. Standards Track [Page 32] + +RFC 2068 HTTP/1.1 January 1997 + + + the length is defined by the chunked encoding (section 3.6). + + 3. If a Content-Length header field (section 14.14) is present, its + value in bytes represents the length of the message-body. + + 4. If the message uses the media type "multipart/byteranges", which is + self-delimiting, then that defines the length. This media type MUST + NOT be used unless the sender knows that the recipient can parse it; + the presence in a request of a Range header with multiple byte-range + specifiers implies that the client can parse multipart/byteranges + responses. + + 5. By the server closing the connection. (Closing the connection + cannot be used to indicate the end of a request body, since that + would leave no possibility for the server to send back a response.) + + For compatibility with HTTP/1.0 applications, HTTP/1.1 requests + containing a message-body MUST include a valid Content-Length header + field unless the server is known to be HTTP/1.1 compliant. If a + request contains a message-body and a Content-Length is not given, + the server SHOULD respond with 400 (bad request) if it cannot + determine the length of the message, or with 411 (length required) if + it wishes to insist on receiving a valid Content-Length. + + All HTTP/1.1 applications that receive entities MUST accept the + "chunked" transfer coding (section 3.6), thus allowing this mechanism + to be used for messages when the message length cannot be determined + in advance. + + Messages MUST NOT include both a Content-Length header field and the + "chunked" transfer coding. If both are received, the Content-Length + MUST be ignored. + + When a Content-Length is given in a message where a message-body is + allowed, its field value MUST exactly match the number of OCTETs in + the message-body. HTTP/1.1 user agents MUST notify the user when an + invalid length is received and detected. + + + + + + + + + + + + + + +Fielding, et. al. Standards Track [Page 33] + +RFC 2068 HTTP/1.1 January 1997 + + +4.5 General Header Fields + + There are a few header fields which have general applicability for + both request and response messages, but which do not apply to the + entity being transferred. These header fields apply only to the + message being transmitted. + + general-header = Cache-Control ; Section 14.9 + | Connection ; Section 14.10 + | Date ; Section 14.19 + | Pragma ; Section 14.32 + | Transfer-Encoding ; Section 14.40 + | Upgrade ; Section 14.41 + | Via ; Section 14.44 + + General-header field names can be extended reliably only in + combination with a change in the protocol version. However, new or + experimental header fields may be given the semantics of general + header fields if all parties in the communication recognize them to + be general-header fields. Unrecognized header fields are treated as + entity-header fields. + +5 Request + + A request message from a client to a server includes, within the + first line of that message, the method to be applied to the resource, + the identifier of the resource, and the protocol version in use. + + Request = Request-Line ; Section 5.1 + *( general-header ; Section 4.5 + | request-header ; Section 5.3 + | entity-header ) ; Section 7.1 + CRLF + [ message-body ] ; Section 7.2 + +5.1 Request-Line + + The Request-Line begins with a method token, followed by the + Request-URI and the protocol version, and ending with CRLF. The + elements are separated by SP characters. No CR or LF are allowed + except in the final CRLF sequence. + + Request-Line = Method SP Request-URI SP HTTP-Version CRLF + + + + + + + + +Fielding, et. al. Standards Track [Page 34] + +RFC 2068 HTTP/1.1 January 1997 + + +5.1.1 Method + + The Method token indicates the method to be performed on the resource + identified by the Request-URI. The method is case-sensitive. + + Method = "OPTIONS" ; Section 9.2 + | "GET" ; Section 9.3 + | "HEAD" ; Section 9.4 + | "POST" ; Section 9.5 + | "PUT" ; Section 9.6 + | "DELETE" ; Section 9.7 + | "TRACE" ; Section 9.8 + | extension-method + + extension-method = token + + The list of methods allowed by a resource can be specified in an + Allow header field (section 14.7). The return code of the response + always notifies the client whether a method is currently allowed on a + resource, since the set of allowed methods can change dynamically. + Servers SHOULD return the status code 405 (Method Not Allowed) if the + method is known by the server but not allowed for the requested + resource, and 501 (Not Implemented) if the method is unrecognized or + not implemented by the server. The list of methods known by a server + can be listed in a Public response-header field (section 14.35). + + The methods GET and HEAD MUST be supported by all general-purpose + servers. All other methods are optional; however, if the above + methods are implemented, they MUST be implemented with the same + semantics as those specified in section 9. + +5.1.2 Request-URI + + The Request-URI is a Uniform Resource Identifier (section 3.2) and + identifies the resource upon which to apply the request. + + Request-URI = "*" | absoluteURI | abs_path + + The three options for Request-URI are dependent on the nature of the + request. The asterisk "*" means that the request does not apply to a + particular resource, but to the server itself, and is only allowed + when the method used does not necessarily apply to a resource. One + example would be + + OPTIONS * HTTP/1.1 + + The absoluteURI form is required when the request is being made to a + proxy. The proxy is requested to forward the request or service it + + + +Fielding, et. al. Standards Track [Page 35] + +RFC 2068 HTTP/1.1 January 1997 + + + from a valid cache, and return the response. Note that the proxy MAY + forward the request on to another proxy or directly to the server + specified by the absoluteURI. In order to avoid request loops, a + proxy MUST be able to recognize all of its server names, including + any aliases, local variations, and the numeric IP address. An example + Request-Line would be: + + GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1 + + To allow for transition to absoluteURIs in all requests in future + versions of HTTP, all HTTP/1.1 servers MUST accept the absoluteURI + form in requests, even though HTTP/1.1 clients will only generate + them in requests to proxies. + + The most common form of Request-URI is that used to identify a + resource on an origin server or gateway. In this case the absolute + path of the URI MUST be transmitted (see section 3.2.1, abs_path) as + the Request-URI, and the network location of the URI (net_loc) MUST + be transmitted in a Host header field. For example, a client wishing + to retrieve the resource above directly from the origin server would + create a TCP connection to port 80 of the host "www.w3.org" and send + the lines: + + GET /pub/WWW/TheProject.html HTTP/1.1 + Host: www.w3.org + + followed by the remainder of the Request. Note that the absolute path + cannot be empty; if none is present in the original URI, it MUST be + given as "/" (the server root). + + If a proxy receives a request without any path in the Request-URI and + the method specified is capable of supporting the asterisk form of + request, then the last proxy on the request chain MUST forward the + request with "*" as the final Request-URI. For example, the request + + OPTIONS http://www.ics.uci.edu:8001 HTTP/1.1 + + would be forwarded by the proxy as + + OPTIONS * HTTP/1.1 + Host: www.ics.uci.edu:8001 + + after connecting to port 8001 of host "www.ics.uci.edu". + + The Request-URI is transmitted in the format specified in section + 3.2.1. The origin server MUST decode the Request-URI in order to + properly interpret the request. Servers SHOULD respond to invalid + Request-URIs with an appropriate status code. + + + +Fielding, et. al. Standards Track [Page 36] + +RFC 2068 HTTP/1.1 January 1997 + + + In requests that they forward, proxies MUST NOT rewrite the + "abs_path" part of a Request-URI in any way except as noted above to + replace a null abs_path with "*", no matter what the proxy does in + its internal implementation. + + Note: The "no rewrite" rule prevents the proxy from changing the + meaning of the request when the origin server is improperly using a + non-reserved URL character for a reserved purpose. Implementers + should be aware that some pre-HTTP/1.1 proxies have been known to + rewrite the Request-URI. + +5.2 The Resource Identified by a Request + + HTTP/1.1 origin servers SHOULD be aware that the exact resource + identified by an Internet request is determined by examining both the + Request-URI and the Host header field. + + An origin server that does not allow resources to differ by the + requested host MAY ignore the Host header field value. (But see + section 19.5.1 for other requirements on Host support in HTTP/1.1.) + + An origin server that does differentiate resources based on the host + requested (sometimes referred to as virtual hosts or vanity + hostnames) MUST use the following rules for determining the requested + resource on an HTTP/1.1 request: + + 1. If Request-URI is an absoluteURI, the host is part of the + Request-URI. Any Host header field value in the request MUST be + ignored. + + 2. If the Request-URI is not an absoluteURI, and the request + includes a Host header field, the host is determined by the Host + header field value. + + 3. If the host as determined by rule 1 or 2 is not a valid host on + the server, the response MUST be a 400 (Bad Request) error + message. + + Recipients of an HTTP/1.0 request that lacks a Host header field MAY + attempt to use heuristics (e.g., examination of the URI path for + something unique to a particular host) in order to determine what + exact resource is being requested. + +5.3 Request Header Fields + + The request-header fields allow the client to pass additional + information about the request, and about the client itself, to the + server. These fields act as request modifiers, with semantics + + + +Fielding, et. al. Standards Track [Page 37] + +RFC 2068 HTTP/1.1 January 1997 + + + equivalent to the parameters on a programming language method + invocation. + + request-header = Accept ; Section 14.1 + | Accept-Charset ; Section 14.2 + | Accept-Encoding ; Section 14.3 + | Accept-Language ; Section 14.4 + | Authorization ; Section 14.8 + | From ; Section 14.22 + | Host ; Section 14.23 + | If-Modified-Since ; Section 14.24 + | If-Match ; Section 14.25 + | If-None-Match ; Section 14.26 + | If-Range ; Section 14.27 + | If-Unmodified-Since ; Section 14.28 + | Max-Forwards ; Section 14.31 + | Proxy-Authorization ; Section 14.34 + | Range ; Section 14.36 + | Referer ; Section 14.37 + | User-Agent ; Section 14.42 + + Request-header field names can be extended reliably only in + combination with a change in the protocol version. However, new or + experimental header fields MAY be given the semantics of request- + header fields if all parties in the communication recognize them to + be request-header fields. Unrecognized header fields are treated as + entity-header fields. + +6 Response + + After receiving and interpreting a request message, a server responds + with an HTTP response message. + + Response = Status-Line ; Section 6.1 + *( general-header ; Section 4.5 + | response-header ; Section 6.2 + | entity-header ) ; Section 7.1 + CRLF + [ message-body ] ; Section 7.2 + +6.1 Status-Line + + The first line of a Response message is the Status-Line, consisting + of the protocol version followed by a numeric status code and its + associated textual phrase, with each element separated by SP + characters. No CR or LF is allowed except in the final CRLF + sequence. + + + + +Fielding, et. al. Standards Track [Page 38] + +RFC 2068 HTTP/1.1 January 1997 + + + Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF + +6.1.1 Status Code and Reason Phrase + + The Status-Code element is a 3-digit integer result code of the + attempt to understand and satisfy the request. These codes are fully + defined in section 10. The Reason-Phrase is intended to give a short + textual description of the Status-Code. The Status-Code is intended + for use by automata and the Reason-Phrase is intended for the human + user. The client is not required to examine or display the Reason- + Phrase. + + The first digit of the Status-Code defines the class of response. The + last two digits do not have any categorization role. There are 5 + values for the first digit: + + o 1xx: Informational - Request received, continuing process + + o 2xx: Success - The action was successfully received, understood, + and accepted + + o 3xx: Redirection - Further action must be taken in order to + complete the request + + o 4xx: Client Error - The request contains bad syntax or cannot be + fulfilled + + o 5xx: Server Error - The server failed to fulfill an apparently + valid request + + The individual values of the numeric status codes defined for + HTTP/1.1, and an example set of corresponding Reason-Phrase's, are + presented below. The reason phrases listed here are only recommended + -- they may be replaced by local equivalents without affecting the + protocol. + + Status-Code = "100" ; Continue + | "101" ; Switching Protocols + | "200" ; OK + | "201" ; Created + | "202" ; Accepted + | "203" ; Non-Authoritative Information + | "204" ; No Content + | "205" ; Reset Content + | "206" ; Partial Content + | "300" ; Multiple Choices + | "301" ; Moved Permanently + | "302" ; Moved Temporarily + + + +Fielding, et. al. Standards Track [Page 39] + +RFC 2068 HTTP/1.1 January 1997 + + + | "303" ; See Other + | "304" ; Not Modified + | "305" ; Use Proxy + | "400" ; Bad Request + | "401" ; Unauthorized + | "402" ; Payment Required + | "403" ; Forbidden + | "404" ; Not Found + | "405" ; Method Not Allowed + | "406" ; Not Acceptable + | "407" ; Proxy Authentication Required + | "408" ; Request Time-out + | "409" ; Conflict + | "410" ; Gone + | "411" ; Length Required + | "412" ; Precondition Failed + | "413" ; Request Entity Too Large + | "414" ; Request-URI Too Large + | "415" ; Unsupported Media Type + | "500" ; Internal Server Error + | "501" ; Not Implemented + | "502" ; Bad Gateway + | "503" ; Service Unavailable + | "504" ; Gateway Time-out + | "505" ; HTTP Version not supported + | extension-code + + extension-code = 3DIGIT + + Reason-Phrase = * + + HTTP status codes are extensible. HTTP applications are not required + to understand the meaning of all registered status codes, though such + understanding is obviously desirable. However, applications MUST + understand the class of any status code, as indicated by the first + digit, and treat any unrecognized response as being equivalent to the + x00 status code of that class, with the exception that an + unrecognized response MUST NOT be cached. For example, if an + unrecognized status code of 431 is received by the client, it can + safely assume that there was something wrong with its request and + treat the response as if it had received a 400 status code. In such + cases, user agents SHOULD present to the user the entity returned + with the response, since that entity is likely to include human- + readable information which will explain the unusual status. + + + + + + + +Fielding, et. al. Standards Track [Page 40] + +RFC 2068 HTTP/1.1 January 1997 + + +6.2 Response Header Fields + + The response-header fields allow the server to pass additional + information about the response which cannot be placed in the Status- + Line. These header fields give information about the server and about + further access to the resource identified by the Request-URI. + + response-header = Age ; Section 14.6 + | Location ; Section 14.30 + | Proxy-Authenticate ; Section 14.33 + | Public ; Section 14.35 + | Retry-After ; Section 14.38 + | Server ; Section 14.39 + | Vary ; Section 14.43 + | Warning ; Section 14.45 + | WWW-Authenticate ; Section 14.46 + + Response-header field names can be extended reliably only in + combination with a change in the protocol version. However, new or + experimental header fields MAY be given the semantics of response- + header fields if all parties in the communication recognize them to + be response-header fields. Unrecognized header fields are treated as + entity-header fields. + +7 Entity + + Request and Response messages MAY transfer an entity if not otherwise + restricted by the request method or response status code. An entity + consists of entity-header fields and an entity-body, although some + responses will only include the entity-headers. + + In this section, both sender and recipient refer to either the client + or the server, depending on who sends and who receives the entity. + +7.1 Entity Header Fields + + Entity-header fields define optional metainformation about the + entity-body or, if no body is present, about the resource identified + by the request. + + + + + + + + + + + + +Fielding, et. al. Standards Track [Page 41] + +RFC 2068 HTTP/1.1 January 1997 + + + entity-header = Allow ; Section 14.7 + | Content-Base ; Section 14.11 + | Content-Encoding ; Section 14.12 + | Content-Language ; Section 14.13 + | Content-Length ; Section 14.14 + | Content-Location ; Section 14.15 + | Content-MD5 ; Section 14.16 + | Content-Range ; Section 14.17 + | Content-Type ; Section 14.18 + | ETag ; Section 14.20 + | Expires ; Section 14.21 + | Last-Modified ; Section 14.29 + | extension-header + + extension-header = message-header + + The extension-header mechanism allows additional entity-header fields + to be defined without changing the protocol, but these fields cannot + be assumed to be recognizable by the recipient. Unrecognized header + fields SHOULD be ignored by the recipient and forwarded by proxies. + +7.2 Entity Body + + The entity-body (if any) sent with an HTTP request or response is in + a format and encoding defined by the entity-header fields. + + entity-body = *OCTET + + An entity-body is only present in a message when a message-body is + present, as described in section 4.3. The entity-body is obtained + from the message-body by decoding any Transfer-Encoding that may have + been applied to ensure safe and proper transfer of the message. + +7.2.1 Type + + When an entity-body is included with a message, the data type of that + body is determined via the header fields Content-Type and Content- + Encoding. These define a two-layer, ordered encoding model: + + entity-body := Content-Encoding( Content-Type( data ) ) + + Content-Type specifies the media type of the underlying data. + Content-Encoding may be used to indicate any additional content + codings applied to the data, usually for the purpose of data + compression, that are a property of the requested resource. There is + no default encoding. + + + + + +Fielding, et. al. Standards Track [Page 42] + +RFC 2068 HTTP/1.1 January 1997 + + + Any HTTP/1.1 message containing an entity-body SHOULD include a + Content-Type header field defining the media type of that body. If + and only if the media type is not given by a Content-Type field, the + recipient MAY attempt to guess the media type via inspection of its + content and/or the name extension(s) of the URL used to identify the + resource. If the media type remains unknown, the recipient SHOULD + treat it as type "application/octet-stream". + +7.2.2 Length + + The length of an entity-body is the length of the message-body after + any transfer codings have been removed. Section 4.4 defines how the + length of a message-body is determined. + +8 Connections + +8.1 Persistent Connections + +8.1.1 Purpose + + Prior to persistent connections, a separate TCP connection was + established to fetch each URL, increasing the load on HTTP servers + and causing congestion on the Internet. The use of inline images and + other associated data often requires a client to make multiple + requests of the same server in a short amount of time. Analyses of + these performance problems are available [30][27]; analysis and + results from a prototype implementation are in [26]. + + Persistent HTTP connections have a number of advantages: + + o By opening and closing fewer TCP connections, CPU time is saved, + and memory used for TCP protocol control blocks is also saved. + o HTTP requests and responses can be pipelined on a connection. + Pipelining allows a client to make multiple requests without + waiting for each response, allowing a single TCP connection to be + used much more efficiently, with much lower elapsed time. + o Network congestion is reduced by reducing the number of packets + caused by TCP opens, and by allowing TCP sufficient time to + determine the congestion state of the network. + o HTTP can evolve more gracefully; since errors can be reported + without the penalty of closing the TCP connection. Clients using + future versions of HTTP might optimistically try a new feature, but + if communicating with an older server, retry with old semantics + after an error is reported. + + HTTP implementations SHOULD implement persistent connections. + + + + + +Fielding, et. al. Standards Track [Page 43] + +RFC 2068 HTTP/1.1 January 1997 + + +8.1.2 Overall Operation + + A significant difference between HTTP/1.1 and earlier versions of + HTTP is that persistent connections are the default behavior of any + HTTP connection. That is, unless otherwise indicated, the client may + assume that the server will maintain a persistent connection. + + Persistent connections provide a mechanism by which a client and a + server can signal the close of a TCP connection. This signaling takes + place using the Connection header field. Once a close has been + signaled, the client MUST not send any more requests on that + connection. + +8.1.2.1 Negotiation + + An HTTP/1.1 server MAY assume that a HTTP/1.1 client intends to + maintain a persistent connection unless a Connection header including + the connection-token "close" was sent in the request. If the server + chooses to close the connection immediately after sending the + response, it SHOULD send a Connection header including the + connection-token close. + + An HTTP/1.1 client MAY expect a connection to remain open, but would + decide to keep it open based on whether the response from a server + contains a Connection header with the connection-token close. In case + the client does not want to maintain a connection for more than that + request, it SHOULD send a Connection header including the + connection-token close. + + If either the client or the server sends the close token in the + Connection header, that request becomes the last one for the + connection. + + Clients and servers SHOULD NOT assume that a persistent connection is + maintained for HTTP versions less than 1.1 unless it is explicitly + signaled. See section 19.7.1 for more information on backwards + compatibility with HTTP/1.0 clients. + + In order to remain persistent, all messages on the connection must + have a self-defined message length (i.e., one not defined by closure + of the connection), as described in section 4.4. + +8.1.2.2 Pipelining + + A client that supports persistent connections MAY "pipeline" its + requests (i.e., send multiple requests without waiting for each + response). A server MUST send its responses to those requests in the + same order that the requests were received. + + + +Fielding, et. al. Standards Track [Page 44] + +RFC 2068 HTTP/1.1 January 1997 + + + Clients which assume persistent connections and pipeline immediately + after connection establishment SHOULD be prepared to retry their + connection if the first pipelined attempt fails. If a client does + such a retry, it MUST NOT pipeline before it knows the connection is + persistent. Clients MUST also be prepared to resend their requests if + the server closes the connection before sending all of the + corresponding responses. + +8.1.3 Proxy Servers + + It is especially important that proxies correctly implement the + properties of the Connection header field as specified in 14.2.1. + + The proxy server MUST signal persistent connections separately with + its clients and the origin servers (or other proxy servers) that it + connects to. Each persistent connection applies to only one transport + link. + + A proxy server MUST NOT establish a persistent connection with an + HTTP/1.0 client. + +8.1.4 Practical Considerations + + Servers will usually have some time-out value beyond which they will + no longer maintain an inactive connection. Proxy servers might make + this a higher value since it is likely that the client will be making + more connections through the same server. The use of persistent + connections places no requirements on the length of this time-out for + either the client or the server. + + When a client or server wishes to time-out it SHOULD issue a graceful + close on the transport connection. Clients and servers SHOULD both + constantly watch for the other side of the transport close, and + respond to it as appropriate. If a client or server does not detect + the other side's close promptly it could cause unnecessary resource + drain on the network. + + A client, server, or proxy MAY close the transport connection at any + time. For example, a client MAY have started to send a new request at + the same time that the server has decided to close the "idle" + connection. From the server's point of view, the connection is being + closed while it was idle, but from the client's point of view, a + request is in progress. + + This means that clients, servers, and proxies MUST be able to recover + from asynchronous close events. Client software SHOULD reopen the + transport connection and retransmit the aborted request without user + interaction so long as the request method is idempotent (see section + + + +Fielding, et. al. Standards Track [Page 45] + +RFC 2068 HTTP/1.1 January 1997 + + + 9.1.2); other methods MUST NOT be automatically retried, although + user agents MAY offer a human operator the choice of retrying the + request. + + However, this automatic retry SHOULD NOT be repeated if the second + request fails. + + Servers SHOULD always respond to at least one request per connection, + if at all possible. Servers SHOULD NOT close a connection in the + middle of transmitting a response, unless a network or client failure + is suspected. + + Clients that use persistent connections SHOULD limit the number of + simultaneous connections that they maintain to a given server. A + single-user client SHOULD maintain AT MOST 2 connections with any + server or proxy. A proxy SHOULD use up to 2*N connections to another + server or proxy, where N is the number of simultaneously active + users. These guidelines are intended to improve HTTP response times + and avoid congestion of the Internet or other networks. + +8.2 Message Transmission Requirements + +General requirements: + +o HTTP/1.1 servers SHOULD maintain persistent connections and use + TCP's flow control mechanisms to resolve temporary overloads, + rather than terminating connections with the expectation that + clients will retry. The latter technique can exacerbate network + congestion. + +o An HTTP/1.1 (or later) client sending a message-body SHOULD monitor + the network connection for an error status while it is transmitting + the request. If the client sees an error status, it SHOULD + immediately cease transmitting the body. If the body is being sent + using a "chunked" encoding (section 3.6), a zero length chunk and + empty footer MAY be used to prematurely mark the end of the + message. If the body was preceded by a Content-Length header, the + client MUST close the connection. + +o An HTTP/1.1 (or later) client MUST be prepared to accept a 100 + (Continue) status followed by a regular response. + +o An HTTP/1.1 (or later) server that receives a request from a + HTTP/1.0 (or earlier) client MUST NOT transmit the 100 (continue) + response; it SHOULD either wait for the request to be completed + normally (thus avoiding an interrupted request) or close the + connection prematurely. + + + + +Fielding, et. al. Standards Track [Page 46] + +RFC 2068 HTTP/1.1 January 1997 + + + Upon receiving a method subject to these requirements from an + HTTP/1.1 (or later) client, an HTTP/1.1 (or later) server MUST either + respond with 100 (Continue) status and continue to read from the + input stream, or respond with an error status. If it responds with an + error status, it MAY close the transport (TCP) connection or it MAY + continue to read and discard the rest of the request. It MUST NOT + perform the requested method if it returns an error status. + + Clients SHOULD remember the version number of at least the most + recently used server; if an HTTP/1.1 client has seen an HTTP/1.1 or + later response from the server, and it sees the connection close + before receiving any status from the server, the client SHOULD retry + the request without user interaction so long as the request method is + idempotent (see section 9.1.2); other methods MUST NOT be + automatically retried, although user agents MAY offer a human + operator the choice of retrying the request.. If the client does + retry the request, the client + + o MUST first send the request header fields, and then + + o MUST wait for the server to respond with either a 100 (Continue) + response, in which case the client should continue, or with an + error status. + + If an HTTP/1.1 client has not seen an HTTP/1.1 or later response from + the server, it should assume that the server implements HTTP/1.0 or + older and will not use the 100 (Continue) response. If in this case + the client sees the connection close before receiving any status from + the server, the client SHOULD retry the request. If the client does + retry the request to this HTTP/1.0 server, it should use the + following "binary exponential backoff" algorithm to be assured of + obtaining a reliable response: + + 1. Initiate a new connection to the server + + 2. Transmit the request-headers + + 3. Initialize a variable R to the estimated round-trip time to the + server (e.g., based on the time it took to establish the + connection), or to a constant value of 5 seconds if the round-trip + time is not available. + + 4. Compute T = R * (2**N), where N is the number of previous retries + of this request. + + 5. Wait either for an error response from the server, or for T seconds + (whichever comes first) + + + + +Fielding, et. al. Standards Track [Page 47] + +RFC 2068 HTTP/1.1 January 1997 + + + 6. If no error response is received, after T seconds transmit the body + of the request. + + 7. If client sees that the connection is closed prematurely, repeat + from step 1 until the request is accepted, an error response is + received, or the user becomes impatient and terminates the retry + process. + + No matter what the server version, if an error status is received, + the client + + o MUST NOT continue and + + o MUST close the connection if it has not completed sending the + message. + + An HTTP/1.1 (or later) client that sees the connection close after + receiving a 100 (Continue) but before receiving any other status + SHOULD retry the request, and need not wait for 100 (Continue) + response (but MAY do so if this simplifies the implementation). + +9 Method Definitions + + The set of common methods for HTTP/1.1 is defined below. Although + this set can be expanded, additional methods cannot be assumed to + share the same semantics for separately extended clients and servers. + + The Host request-header field (section 14.23) MUST accompany all + HTTP/1.1 requests. + +9.1 Safe and Idempotent Methods + +9.1.1 Safe Methods + + Implementers should be aware that the software represents the user in + their interactions over the Internet, and should be careful to allow + the user to be aware of any actions they may take which may have an + unexpected significance to themselves or others. + + In particular, the convention has been established that the GET and + HEAD methods should never have the significance of taking an action + other than retrieval. These methods should be considered "safe." This + allows user agents to represent other methods, such as POST, PUT and + DELETE, in a special way, so that the user is made aware of the fact + that a possibly unsafe action is being requested. + + Naturally, it is not possible to ensure that the server does not + generate side-effects as a result of performing a GET request; in + + + +Fielding, et. al. Standards Track [Page 48] + +RFC 2068 HTTP/1.1 January 1997 + + + fact, some dynamic resources consider that a feature. The important + distinction here is that the user did not request the side-effects, + so therefore cannot be held accountable for them. + +9.1.2 Idempotent Methods + + Methods may also have the property of "idempotence" in that (aside + from error or expiration issues) the side-effects of N > 0 identical + requests is the same as for a single request. The methods GET, HEAD, + PUT and DELETE share this property. + +9.2 OPTIONS + + The OPTIONS method represents a request for information about the + communication options available on the request/response chain + identified by the Request-URI. This method allows the client to + determine the options and/or requirements associated with a resource, + or the capabilities of a server, without implying a resource action + or initiating a resource retrieval. + + Unless the server's response is an error, the response MUST NOT + include entity information other than what can be considered as + communication options (e.g., Allow is appropriate, but Content-Type + is not). Responses to this method are not cachable. + + If the Request-URI is an asterisk ("*"), the OPTIONS request is + intended to apply to the server as a whole. A 200 response SHOULD + include any header fields which indicate optional features + implemented by the server (e.g., Public), including any extensions + not defined by this specification, in addition to any applicable + general or response-header fields. As described in section 5.1.2, an + "OPTIONS *" request can be applied through a proxy by specifying the + destination server in the Request-URI without any path information. + + If the Request-URI is not an asterisk, the OPTIONS request applies + only to the options that are available when communicating with that + resource. A 200 response SHOULD include any header fields which + indicate optional features implemented by the server and applicable + to that resource (e.g., Allow), including any extensions not defined + by this specification, in addition to any applicable general or + response-header fields. If the OPTIONS request passes through a + proxy, the proxy MUST edit the response to exclude those options + which apply to a proxy's capabilities and which are known to be + unavailable through that proxy. + + + + + + + +Fielding, et. al. Standards Track [Page 49] + +RFC 2068 HTTP/1.1 January 1997 + + +9.3 GET + + The GET method means retrieve whatever information (in the form of an + entity) is identified by the Request-URI. If the Request-URI refers + to a data-producing process, it is the produced data which shall be + returned as the entity in the response and not the source text of the + process, unless that text happens to be the output of the process. + + The semantics of the GET method change to a "conditional GET" if the + request message includes an If-Modified-Since, If-Unmodified-Since, + If-Match, If-None-Match, or If-Range header field. A conditional GET + method requests that the entity be transferred only under the + circumstances described by the conditional header field(s). The + conditional GET method is intended to reduce unnecessary network + usage by allowing cached entities to be refreshed without requiring + multiple requests or transferring data already held by the client. + + The semantics of the GET method change to a "partial GET" if the + request message includes a Range header field. A partial GET requests + that only part of the entity be transferred, as described in section + 14.36. The partial GET method is intended to reduce unnecessary + network usage by allowing partially-retrieved entities to be + completed without transferring data already held by the client. + + The response to a GET request is cachable if and only if it meets the + requirements for HTTP caching described in section 13. + +9.4 HEAD + + The HEAD method is identical to GET except that the server MUST NOT + return a message-body in the response. The metainformation contained + in the HTTP headers in response to a HEAD request SHOULD be identical + to the information sent in response to a GET request. This method can + be used for obtaining metainformation about the entity implied by the + request without transferring the entity-body itself. This method is + often used for testing hypertext links for validity, accessibility, + and recent modification. + + The response to a HEAD request may be cachable in the sense that the + information contained in the response may be used to update a + previously cached entity from that resource. If the new field values + indicate that the cached entity differs from the current entity (as + would be indicated by a change in Content-Length, Content-MD5, ETag + or Last-Modified), then the cache MUST treat the cache entry as + stale. + + + + + + +Fielding, et. al. Standards Track [Page 50] + +RFC 2068 HTTP/1.1 January 1997 + + +9.5 POST + + The POST method is used to request that the destination server accept + the entity enclosed in the request as a new subordinate of the + resource identified by the Request-URI in the Request-Line. POST is + designed to allow a uniform method to cover the following functions: + + o Annotation of existing resources; + + o Posting a message to a bulletin board, newsgroup, mailing list, + or similar group of articles; + + o Providing a block of data, such as the result of submitting a + form, to a data-handling process; + + o Extending a database through an append operation. + + The actual function performed by the POST method is determined by the + server and is usually dependent on the Request-URI. The posted entity + is subordinate to that URI in the same way that a file is subordinate + to a directory containing it, a news article is subordinate to a + newsgroup to which it is posted, or a record is subordinate to a + database. + + The action performed by the POST method might not result in a + resource that can be identified by a URI. In this case, either 200 + (OK) or 204 (No Content) is the appropriate response status, + depending on whether or not the response includes an entity that + describes the result. + + If a resource has been created on the origin server, the response + SHOULD be 201 (Created) and contain an entity which describes the + status of the request and refers to the new resource, and a Location + header (see section 14.30). + + Responses to this method are not cachable, unless the response + includes appropriate Cache-Control or Expires header fields. However, + the 303 (See Other) response can be used to direct the user agent to + retrieve a cachable resource. + + POST requests must obey the message transmission requirements set out + in section 8.2. + + + + + + + + + +Fielding, et. al. Standards Track [Page 51] + +RFC 2068 HTTP/1.1 January 1997 + + +9.6 PUT + + The PUT method requests that the enclosed entity be stored under the + supplied Request-URI. If the Request-URI refers to an already + existing resource, the enclosed entity SHOULD be considered as a + modified version of the one residing on the origin server. If the + Request-URI does not point to an existing resource, and that URI is + capable of being defined as a new resource by the requesting user + agent, the origin server can create the resource with that URI. If a + new resource is created, the origin server MUST inform the user agent + via the 201 (Created) response. If an existing resource is modified, + either the 200 (OK) or 204 (No Content) response codes SHOULD be sent + to indicate successful completion of the request. If the resource + could not be created or modified with the Request-URI, an appropriate + error response SHOULD be given that reflects the nature of the + problem. The recipient of the entity MUST NOT ignore any Content-* + (e.g. Content-Range) headers that it does not understand or implement + and MUST return a 501 (Not Implemented) response in such cases. + + If the request passes through a cache and the Request-URI identifies + one or more currently cached entities, those entries should be + treated as stale. Responses to this method are not cachable. + + The fundamental difference between the POST and PUT requests is + reflected in the different meaning of the Request-URI. The URI in a + POST request identifies the resource that will handle the enclosed + entity. That resource may be a data-accepting process, a gateway to + some other protocol, or a separate entity that accepts annotations. + In contrast, the URI in a PUT request identifies the entity enclosed + with the request -- the user agent knows what URI is intended and the + server MUST NOT attempt to apply the request to some other resource. + If the server desires that the request be applied to a different URI, + it MUST send a 301 (Moved Permanently) response; the user agent MAY + then make its own decision regarding whether or not to redirect the + request. + + A single resource MAY be identified by many different URIs. For + example, an article may have a URI for identifying "the current + version" which is separate from the URI identifying each particular + version. In this case, a PUT request on a general URI may result in + several other URIs being defined by the origin server. + + HTTP/1.1 does not define how a PUT method affects the state of an + origin server. + + PUT requests must obey the message transmission requirements set out + in section 8.2. + + + + +Fielding, et. al. Standards Track [Page 52] + +RFC 2068 HTTP/1.1 January 1997 + + +9.7 DELETE + + The DELETE method requests that the origin server delete the resource + identified by the Request-URI. This method MAY be overridden by human + intervention (or other means) on the origin server. The client cannot + be guaranteed that the operation has been carried out, even if the + status code returned from the origin server indicates that the action + has been completed successfully. However, the server SHOULD not + indicate success unless, at the time the response is given, it + intends to delete the resource or move it to an inaccessible + location. + + A successful response SHOULD be 200 (OK) if the response includes an + entity describing the status, 202 (Accepted) if the action has not + yet been enacted, or 204 (No Content) if the response is OK but does + not include an entity. + + If the request passes through a cache and the Request-URI identifies + one or more currently cached entities, those entries should be + treated as stale. Responses to this method are not cachable. + +9.8 TRACE + + The TRACE method is used to invoke a remote, application-layer loop- + back of the request message. The final recipient of the request + SHOULD reflect the message received back to the client as the + entity-body of a 200 (OK) response. The final recipient is either the + origin server or the first proxy or gateway to receive a Max-Forwards + value of zero (0) in the request (see section 14.31). A TRACE request + MUST NOT include an entity. + + TRACE allows the client to see what is being received at the other + end of the request chain and use that data for testing or diagnostic + information. The value of the Via header field (section 14.44) is of + particular interest, since it acts as a trace of the request chain. + Use of the Max-Forwards header field allows the client to limit the + length of the request chain, which is useful for testing a chain of + proxies forwarding messages in an infinite loop. + + If successful, the response SHOULD contain the entire request message + in the entity-body, with a Content-Type of "message/http". Responses + to this method MUST NOT be cached. + +10 Status Code Definitions + + Each Status-Code is described below, including a description of which + method(s) it can follow and any metainformation required in the + response. + + + +Fielding, et. al. Standards Track [Page 53] + +RFC 2068 HTTP/1.1 January 1997 + + +10.1 Informational 1xx + + This class of status code indicates a provisional response, + consisting only of the Status-Line and optional headers, and is + terminated by an empty line. Since HTTP/1.0 did not define any 1xx + status codes, servers MUST NOT send a 1xx response to an HTTP/1.0 + client except under experimental conditions. + +10.1.1 100 Continue + + The client may continue with its request. This interim response is + used to inform the client that the initial part of the request has + been received and has not yet been rejected by the server. The client + SHOULD continue by sending the remainder of the request or, if the + request has already been completed, ignore this response. The server + MUST send a final response after the request has been completed. + +10.1.2 101 Switching Protocols + + The server understands and is willing to comply with the client's + request, via the Upgrade message header field (section 14.41), for a + change in the application protocol being used on this connection. The + server will switch protocols to those defined by the response's + Upgrade header field immediately after the empty line which + terminates the 101 response. + + The protocol should only be switched when it is advantageous to do + so. For example, switching to a newer version of HTTP is + advantageous over older versions, and switching to a real-time, + synchronous protocol may be advantageous when delivering resources + that use such features. + +10.2 Successful 2xx + + This class of status code indicates that the client's request was + successfully received, understood, and accepted. + +10.2.1 200 OK + + The request has succeeded. The information returned with the response + is dependent on the method used in the request, for example: + + GET an entity corresponding to the requested resource is sent in the + response; + + HEAD the entity-header fields corresponding to the requested resource + are sent in the response without any message-body; + + + + +Fielding, et. al. Standards Track [Page 54] + +RFC 2068 HTTP/1.1 January 1997 + + + POST an entity describing or containing the result of the action; + + TRACE an entity containing the request message as received by the end + server. + +10.2.2 201 Created + + The request has been fulfilled and resulted in a new resource being + created. The newly created resource can be referenced by the URI(s) + returned in the entity of the response, with the most specific URL + for the resource given by a Location header field. The origin server + MUST create the resource before returning the 201 status code. If the + action cannot be carried out immediately, the server should respond + with 202 (Accepted) response instead. + +10.2.3 202 Accepted + + The request has been accepted for processing, but the processing has + not been completed. The request MAY or MAY NOT eventually be acted + upon, as it MAY be disallowed when processing actually takes place. + There is no facility for re-sending a status code from an + asynchronous operation such as this. + + The 202 response is intentionally non-committal. Its purpose is to + allow a server to accept a request for some other process (perhaps a + batch-oriented process that is only run once per day) without + requiring that the user agent's connection to the server persist + until the process is completed. The entity returned with this + response SHOULD include an indication of the request's current status + and either a pointer to a status monitor or some estimate of when the + user can expect the request to be fulfilled. + +10.2.4 203 Non-Authoritative Information + + The returned metainformation in the entity-header is not the + definitive set as available from the origin server, but is gathered + from a local or a third-party copy. The set presented MAY be a subset + or superset of the original version. For example, including local + annotation information about the resource MAY result in a superset of + the metainformation known by the origin server. Use of this response + code is not required and is only appropriate when the response would + otherwise be 200 (OK). + +10.2.5 204 No Content + + The server has fulfilled the request but there is no new information + to send back. If the client is a user agent, it SHOULD NOT change its + document view from that which caused the request to be sent. This + + + +Fielding, et. al. Standards Track [Page 55] + +RFC 2068 HTTP/1.1 January 1997 + + + response is primarily intended to allow input for actions to take + place without causing a change to the user agent's active document + view. The response MAY include new metainformation in the form of + entity-headers, which SHOULD apply to the document currently in the + user agent's active view. + + The 204 response MUST NOT include a message-body, and thus is always + terminated by the first empty line after the header fields. + +10.2.6 205 Reset Content + + The server has fulfilled the request and the user agent SHOULD reset + the document view which caused the request to be sent. This response + is primarily intended to allow input for actions to take place via + user input, followed by a clearing of the form in which the input is + given so that the user can easily initiate another input action. The + response MUST NOT include an entity. + +10.2.7 206 Partial Content + + The server has fulfilled the partial GET request for the resource. + The request must have included a Range header field (section 14.36) + indicating the desired range. The response MUST include either a + Content-Range header field (section 14.17) indicating the range + included with this response, or a multipart/byteranges Content-Type + including Content-Range fields for each part. If multipart/byteranges + is not used, the Content-Length header field in the response MUST + match the actual number of OCTETs transmitted in the message-body. + + A cache that does not support the Range and Content-Range headers + MUST NOT cache 206 (Partial) responses. + +10.3 Redirection 3xx + + This class of status code indicates that further action needs to be + taken by the user agent in order to fulfill the request. The action + required MAY be carried out by the user agent without interaction + with the user if and only if the method used in the second request is + GET or HEAD. A user agent SHOULD NOT automatically redirect a request + more than 5 times, since such redirections usually indicate an + infinite loop. + + + + + + + + + + +Fielding, et. al. Standards Track [Page 56] + +RFC 2068 HTTP/1.1 January 1997 + + +10.3.1 300 Multiple Choices + + The requested resource corresponds to any one of a set of + representations, each with its own specific location, and agent- + driven negotiation information (section 12) is being provided so that + the user (or user agent) can select a preferred representation and + redirect its request to that location. + + Unless it was a HEAD request, the response SHOULD include an entity + containing a list of resource characteristics and location(s) from + which the user or user agent can choose the one most appropriate. The + entity format is specified by the media type given in the Content- + Type header field. Depending upon the format and the capabilities of + the user agent, selection of the most appropriate choice may be + performed automatically. However, this specification does not define + any standard for such automatic selection. + + If the server has a preferred choice of representation, it SHOULD + include the specific URL for that representation in the Location + field; user agents MAY use the Location field value for automatic + redirection. This response is cachable unless indicated otherwise. + +10.3.2 301 Moved Permanently + + The requested resource has been assigned a new permanent URI and any + future references to this resource SHOULD be done using one of the + returned URIs. Clients with link editing capabilities SHOULD + automatically re-link references to the Request-URI to one or more of + the new references returned by the server, where possible. This + response is cachable unless indicated otherwise. + + If the new URI is a location, its URL SHOULD be given by the Location + field in the response. Unless the request method was HEAD, the entity + of the response SHOULD contain a short hypertext note with a + hyperlink to the new URI(s). + + If the 301 status code is received in response to a request other + than GET or HEAD, the user agent MUST NOT automatically redirect the + request unless it can be confirmed by the user, since this might + change the conditions under which the request was issued. + + Note: When automatically redirecting a POST request after receiving + a 301 status code, some existing HTTP/1.0 user agents will + erroneously change it into a GET request. + + + + + + + +Fielding, et. al. Standards Track [Page 57] + +RFC 2068 HTTP/1.1 January 1997 + + +10.3.3 302 Moved Temporarily + + The requested resource resides temporarily under a different URI. + Since the redirection may be altered on occasion, the client SHOULD + continue to use the Request-URI for future requests. This response is + only cachable if indicated by a Cache-Control or Expires header + field. + + If the new URI is a location, its URL SHOULD be given by the Location + field in the response. Unless the request method was HEAD, the entity + of the response SHOULD contain a short hypertext note with a + hyperlink to the new URI(s). + + If the 302 status code is received in response to a request other + than GET or HEAD, the user agent MUST NOT automatically redirect the + request unless it can be confirmed by the user, since this might + change the conditions under which the request was issued. + + Note: When automatically redirecting a POST request after receiving + a 302 status code, some existing HTTP/1.0 user agents will + erroneously change it into a GET request. + +10.3.4 303 See Other + + The response to the request can be found under a different URI and + SHOULD be retrieved using a GET method on that resource. This method + exists primarily to allow the output of a POST-activated script to + redirect the user agent to a selected resource. The new URI is not a + substitute reference for the originally requested resource. The 303 + response is not cachable, but the response to the second (redirected) + request MAY be cachable. + + If the new URI is a location, its URL SHOULD be given by the Location + field in the response. Unless the request method was HEAD, the entity + of the response SHOULD contain a short hypertext note with a + hyperlink to the new URI(s). + +10.3.5 304 Not Modified + + If the client has performed a conditional GET request and access is + allowed, but the document has not been modified, the server SHOULD + respond with this status code. The response MUST NOT contain a + message-body. + + + + + + + + +Fielding, et. al. Standards Track [Page 58] + +RFC 2068 HTTP/1.1 January 1997 + + + The response MUST include the following header fields: + + o Date + + o ETag and/or Content-Location, if the header would have been sent in + a 200 response to the same request + + o Expires, Cache-Control, and/or Vary, if the field-value might + differ from that sent in any previous response for the same variant + + If the conditional GET used a strong cache validator (see section + 13.3.3), the response SHOULD NOT include other entity-headers. + Otherwise (i.e., the conditional GET used a weak validator), the + response MUST NOT include other entity-headers; this prevents + inconsistencies between cached entity-bodies and updated headers. + + If a 304 response indicates an entity not currently cached, then the + cache MUST disregard the response and repeat the request without the + conditional. + + If a cache uses a received 304 response to update a cache entry, the + cache MUST update the entry to reflect any new field values given in + the response. + + The 304 response MUST NOT include a message-body, and thus is always + terminated by the first empty line after the header fields. + +10.3.6 305 Use Proxy + + The requested resource MUST be accessed through the proxy given by + the Location field. The Location field gives the URL of the proxy. + The recipient is expected to repeat the request via the proxy. + +10.4 Client Error 4xx + + The 4xx class of status code is intended for cases in which the + client seems to have erred. Except when responding to a HEAD request, + the server SHOULD include an entity containing an explanation of the + error situation, and whether it is a temporary or permanent + condition. These status codes are applicable to any request method. + User agents SHOULD display any included entity to the user. + + Note: If the client is sending data, a server implementation using + TCP should be careful to ensure that the client acknowledges + receipt of the packet(s) containing the response, before the server + closes the input connection. If the client continues sending data + to the server after the close, the server's TCP stack will send a + reset packet to the client, which may erase the client's + + + +Fielding, et. al. Standards Track [Page 59] + +RFC 2068 HTTP/1.1 January 1997 + + + unacknowledged input buffers before they can be read and + interpreted by the HTTP application. + +10.4.1 400 Bad Request + + The request could not be understood by the server due to malformed + syntax. The client SHOULD NOT repeat the request without + modifications. + +10.4.2 401 Unauthorized + + The request requires user authentication. The response MUST include a + WWW-Authenticate header field (section 14.46) containing a challenge + applicable to the requested resource. The client MAY repeat the + request with a suitable Authorization header field (section 14.8). If + the request already included Authorization credentials, then the 401 + response indicates that authorization has been refused for those + credentials. If the 401 response contains the same challenge as the + prior response, and the user agent has already attempted + authentication at least once, then the user SHOULD be presented the + entity that was given in the response, since that entity MAY include + relevant diagnostic information. HTTP access authentication is + explained in section 11. + +10.4.3 402 Payment Required + + This code is reserved for future use. + +10.4.4 403 Forbidden + + The server understood the request, but is refusing to fulfill it. + Authorization will not help and the request SHOULD NOT be repeated. + If the request method was not HEAD and the server wishes to make + public why the request has not been fulfilled, it SHOULD describe the + reason for the refusal in the entity. This status code is commonly + used when the server does not wish to reveal exactly why the request + has been refused, or when no other response is applicable. + +10.4.5 404 Not Found + + The server has not found anything matching the Request-URI. No + indication is given of whether the condition is temporary or + permanent. + + + + + + + + +Fielding, et. al. Standards Track [Page 60] + +RFC 2068 HTTP/1.1 January 1997 + + + If the server does not wish to make this information available to the + client, the status code 403 (Forbidden) can be used instead. The 410 + (Gone) status code SHOULD be used if the server knows, through some + internally configurable mechanism, that an old resource is + permanently unavailable and has no forwarding address. + +10.4.6 405 Method Not Allowed + + The method specified in the Request-Line is not allowed for the + resource identified by the Request-URI. The response MUST include an + Allow header containing a list of valid methods for the requested + resource. + +10.4.7 406 Not Acceptable + + The resource identified by the request is only capable of generating + response entities which have content characteristics not acceptable + according to the accept headers sent in the request. + + Unless it was a HEAD request, the response SHOULD include an entity + containing a list of available entity characteristics and location(s) + from which the user or user agent can choose the one most + appropriate. The entity format is specified by the media type given + in the Content-Type header field. Depending upon the format and the + capabilities of the user agent, selection of the most appropriate + choice may be performed automatically. However, this specification + does not define any standard for such automatic selection. + + Note: HTTP/1.1 servers are allowed to return responses which are + not acceptable according to the accept headers sent in the request. + In some cases, this may even be preferable to sending a 406 + response. User agents are encouraged to inspect the headers of an + incoming response to determine if it is acceptable. If the response + could be unacceptable, a user agent SHOULD temporarily stop receipt + of more data and query the user for a decision on further actions. + +10.4.8 407 Proxy Authentication Required + + This code is similar to 401 (Unauthorized), but indicates that the + client MUST first authenticate itself with the proxy. The proxy MUST + return a Proxy-Authenticate header field (section 14.33) containing a + challenge applicable to the proxy for the requested resource. The + client MAY repeat the request with a suitable Proxy-Authorization + header field (section 14.34). HTTP access authentication is explained + in section 11. + + + + + + +Fielding, et. al. Standards Track [Page 61] + +RFC 2068 HTTP/1.1 January 1997 + + +10.4.9 408 Request Timeout + + The client did not produce a request within the time that the server + was prepared to wait. The client MAY repeat the request without + modifications at any later time. + +10.4.10 409 Conflict + + The request could not be completed due to a conflict with the current + state of the resource. This code is only allowed in situations where + it is expected that the user might be able to resolve the conflict + and resubmit the request. The response body SHOULD include enough + information for the user to recognize the source of the conflict. + Ideally, the response entity would include enough information for the + user or user agent to fix the problem; however, that may not be + possible and is not required. + + Conflicts are most likely to occur in response to a PUT request. If + versioning is being used and the entity being PUT includes changes to + a resource which conflict with those made by an earlier (third-party) + request, the server MAY use the 409 response to indicate that it + can't complete the request. In this case, the response entity SHOULD + contain a list of the differences between the two versions in a + format defined by the response Content-Type. + +10.4.11 410 Gone + + The requested resource is no longer available at the server and no + forwarding address is known. This condition SHOULD be considered + permanent. Clients with link editing capabilities SHOULD delete + references to the Request-URI after user approval. If the server does + not know, or has no facility to determine, whether or not the + condition is permanent, the status code 404 (Not Found) SHOULD be + used instead. This response is cachable unless indicated otherwise. + + The 410 response is primarily intended to assist the task of web + maintenance by notifying the recipient that the resource is + intentionally unavailable and that the server owners desire that + remote links to that resource be removed. Such an event is common for + limited-time, promotional services and for resources belonging to + individuals no longer working at the server's site. It is not + necessary to mark all permanently unavailable resources as "gone" or + to keep the mark for any length of time -- that is left to the + discretion of the server owner. + + + + + + + +Fielding, et. al. Standards Track [Page 62] + +RFC 2068 HTTP/1.1 January 1997 + + +10.4.12 411 Length Required + + The server refuses to accept the request without a defined Content- + Length. The client MAY repeat the request if it adds a valid + Content-Length header field containing the length of the message-body + in the request message. + +10.4.13 412 Precondition Failed + + The precondition given in one or more of the request-header fields + evaluated to false when it was tested on the server. This response + code allows the client to place preconditions on the current resource + metainformation (header field data) and thus prevent the requested + method from being applied to a resource other than the one intended. + +10.4.14 413 Request Entity Too Large + + The server is refusing to process a request because the request + entity is larger than the server is willing or able to process. The + server may close the connection to prevent the client from continuing + the request. + + If the condition is temporary, the server SHOULD include a Retry- + After header field to indicate that it is temporary and after what + time the client may try again. + +10.4.15 414 Request-URI Too Long + + The server is refusing to service the request because the Request-URI + is longer than the server is willing to interpret. This rare + condition is only likely to occur when a client has improperly + converted a POST request to a GET request with long query + information, when the client has descended into a URL "black hole" of + redirection (e.g., a redirected URL prefix that points to a suffix of + itself), or when the server is under attack by a client attempting to + exploit security holes present in some servers using fixed-length + buffers for reading or manipulating the Request-URI. + +10.4.16 415 Unsupported Media Type + + The server is refusing to service the request because the entity of + the request is in a format not supported by the requested resource + for the requested method. + + + + + + + + +Fielding, et. al. Standards Track [Page 63] + +RFC 2068 HTTP/1.1 January 1997 + + +10.5 Server Error 5xx + + Response status codes beginning with the digit "5" indicate cases in + which the server is aware that it has erred or is incapable of + performing the request. Except when responding to a HEAD request, the + server SHOULD include an entity containing an explanation of the + error situation, and whether it is a temporary or permanent + condition. User agents SHOULD display any included entity to the + user. These response codes are applicable to any request method. + +10.5.1 500 Internal Server Error + + The server encountered an unexpected condition which prevented it + from fulfilling the request. + +10.5.2 501 Not Implemented + + The server does not support the functionality required to fulfill the + request. This is the appropriate response when the server does not + recognize the request method and is not capable of supporting it for + any resource. + +10.5.3 502 Bad Gateway + + The server, while acting as a gateway or proxy, received an invalid + response from the upstream server it accessed in attempting to + fulfill the request. + +10.5.4 503 Service Unavailable + + The server is currently unable to handle the request due to a + temporary overloading or maintenance of the server. The implication + is that this is a temporary condition which will be alleviated after + some delay. If known, the length of the delay may be indicated in a + Retry-After header. If no Retry-After is given, the client SHOULD + handle the response as it would for a 500 response. + + Note: The existence of the 503 status code does not imply that a + server must use it when becoming overloaded. Some servers may wish + to simply refuse the connection. + +10.5.5 504 Gateway Timeout + + The server, while acting as a gateway or proxy, did not receive a + timely response from the upstream server it accessed in attempting to + complete the request. + + + + + +Fielding, et. al. Standards Track [Page 64] + +RFC 2068 HTTP/1.1 January 1997 + + +10.5.6 505 HTTP Version Not Supported + + The server does not support, or refuses to support, the HTTP protocol + version that was used in the request message. The server is + indicating that it is unable or unwilling to complete the request + using the same major version as the client, as described in section + 3.1, other than with this error message. The response SHOULD contain + an entity describing why that version is not supported and what other + protocols are supported by that server. + +11 Access Authentication + + HTTP provides a simple challenge-response authentication mechanism + which MAY be used by a server to challenge a client request and by a + client to provide authentication information. It uses an extensible, + case-insensitive token to identify the authentication scheme, + followed by a comma-separated list of attribute-value pairs which + carry the parameters necessary for achieving authentication via that + scheme. + + auth-scheme = token + + auth-param = token "=" quoted-string + + The 401 (Unauthorized) response message is used by an origin server + to challenge the authorization of a user agent. This response MUST + include a WWW-Authenticate header field containing at least one + challenge applicable to the requested resource. + + challenge = auth-scheme 1*SP realm *( "," auth-param ) + + realm = "realm" "=" realm-value + realm-value = quoted-string + + The realm attribute (case-insensitive) is required for all + authentication schemes which issue a challenge. The realm value + (case-sensitive), in combination with the canonical root URL (see + section 5.1.2) of the server being accessed, defines the protection + space. These realms allow the protected resources on a server to be + partitioned into a set of protection spaces, each with its own + authentication scheme and/or authorization database. The realm value + is a string, generally assigned by the origin server, which may have + additional semantics specific to the authentication scheme. + + A user agent that wishes to authenticate itself with a server-- + usually, but not necessarily, after receiving a 401 or 411 response- + -MAY do so by including an Authorization header field with the + request. The Authorization field value consists of credentials + + + +Fielding, et. al. Standards Track [Page 65] + +RFC 2068 HTTP/1.1 January 1997 + + + containing the authentication information of the user agent for the + realm of the resource being requested. + + credentials = basic-credentials + | auth-scheme #auth-param + + The domain over which credentials can be automatically applied by a + user agent is determined by the protection space. If a prior request + has been authorized, the same credentials MAY be reused for all other + requests within that protection space for a period of time determined + by the authentication scheme, parameters, and/or user preference. + Unless otherwise defined by the authentication scheme, a single + protection space cannot extend outside the scope of its server. + + If the server does not wish to accept the credentials sent with a + request, it SHOULD return a 401 (Unauthorized) response. The response + MUST include a WWW-Authenticate header field containing the (possibly + new) challenge applicable to the requested resource and an entity + explaining the refusal. + + The HTTP protocol does not restrict applications to this simple + challenge-response mechanism for access authentication. Additional + mechanisms MAY be used, such as encryption at the transport level or + via message encapsulation, and with additional header fields + specifying authentication information. However, these additional + mechanisms are not defined by this specification. + + Proxies MUST be completely transparent regarding user agent + authentication. That is, they MUST forward the WWW-Authenticate and + Authorization headers untouched, and follow the rules found in + section 14.8. + + HTTP/1.1 allows a client to pass authentication information to and + from a proxy via the Proxy-Authenticate and Proxy-Authorization + headers. + +11.1 Basic Authentication Scheme + + The "basic" authentication scheme is based on the model that the user + agent must authenticate itself with a user-ID and a password for each + realm. The realm value should be considered an opaque string which + can only be compared for equality with other realms on that server. + The server will service the request only if it can validate the + user-ID and password for the protection space of the Request-URI. + There are no optional authentication parameters. + + + + + + +Fielding, et. al. Standards Track [Page 66] + +RFC 2068 HTTP/1.1 January 1997 + + + Upon receipt of an unauthorized request for a URI within the + protection space, the server MAY respond with a challenge like the + following: + + WWW-Authenticate: Basic realm="WallyWorld" + + where "WallyWorld" is the string assigned by the server to identify + the protection space of the Request-URI. + + To receive authorization, the client sends the userid and password, + separated by a single colon (":") character, within a base64 encoded + string in the credentials. + + basic-credentials = "Basic" SP basic-cookie + + basic-cookie = + + user-pass = userid ":" password + + userid = * + + password = *TEXT + + Userids might be case sensitive. + + If the user agent wishes to send the userid "Aladdin" and password + "open sesame", it would use the following header field: + + Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== + + See section 15 for security considerations associated with Basic + authentication. + +11.2 Digest Authentication Scheme + + A digest authentication for HTTP is specified in RFC 2069 [32]. + +12 Content Negotiation + + Most HTTP responses include an entity which contains information for + interpretation by a human user. Naturally, it is desirable to supply + the user with the "best available" entity corresponding to the + request. Unfortunately for servers and caches, not all users have + the same preferences for what is "best," and not all user agents are + equally capable of rendering all entity types. For that reason, HTTP + has provisions for several mechanisms for "content negotiation" -- + the process of selecting the best representation for a given response + + + +Fielding, et. al. Standards Track [Page 67] + +RFC 2068 HTTP/1.1 January 1997 + + + when there are multiple representations available. + + Note: This is not called "format negotiation" because the alternate + representations may be of the same media type, but use different + capabilities of that type, be in different languages, etc. + + Any response containing an entity-body MAY be subject to negotiation, + including error responses. + + There are two kinds of content negotiation which are possible in + HTTP: server-driven and agent-driven negotiation. These two kinds of + negotiation are orthogonal and thus may be used separately or in + combination. One method of combination, referred to as transparent + negotiation, occurs when a cache uses the agent-driven negotiation + information provided by the origin server in order to provide + server-driven negotiation for subsequent requests. + +12.1 Server-driven Negotiation + + If the selection of the best representation for a response is made by + an algorithm located at the server, it is called server-driven + negotiation. Selection is based on the available representations of + the response (the dimensions over which it can vary; e.g. language, + content-coding, etc.) and the contents of particular header fields in + the request message or on other information pertaining to the request + (such as the network address of the client). + + Server-driven negotiation is advantageous when the algorithm for + selecting from among the available representations is difficult to + describe to the user agent, or when the server desires to send its + "best guess" to the client along with the first response (hoping to + avoid the round-trip delay of a subsequent request if the "best + guess" is good enough for the user). In order to improve the server's + guess, the user agent MAY include request header fields (Accept, + Accept-Language, Accept-Encoding, etc.) which describe its + preferences for such a response. + + Server-driven negotiation has disadvantages: + +1. It is impossible for the server to accurately determine what might be + "best" for any given user, since that would require complete + knowledge of both the capabilities of the user agent and the intended + use for the response (e.g., does the user want to view it on screen + or print it on paper?). + +2. Having the user agent describe its capabilities in every request can + be both very inefficient (given that only a small percentage of + responses have multiple representations) and a potential violation of + + + +Fielding, et. al. Standards Track [Page 68] + +RFC 2068 HTTP/1.1 January 1997 + + + the user's privacy. + +3. It complicates the implementation of an origin server and the + algorithms for generating responses to a request. + +4. It may limit a public cache's ability to use the same response for + multiple user's requests. + + HTTP/1.1 includes the following request-header fields for enabling + server-driven negotiation through description of user agent + capabilities and user preferences: Accept (section 14.1), Accept- + Charset (section 14.2), Accept-Encoding (section 14.3), Accept- + Language (section 14.4), and User-Agent (section 14.42). However, an + origin server is not limited to these dimensions and MAY vary the + response based on any aspect of the request, including information + outside the request-header fields or within extension header fields + not defined by this specification. + + HTTP/1.1 origin servers MUST include an appropriate Vary header field + (section 14.43) in any cachable response based on server-driven + negotiation. The Vary header field describes the dimensions over + which the response might vary (i.e. the dimensions over which the + origin server picks its "best guess" response from multiple + representations). + + HTTP/1.1 public caches MUST recognize the Vary header field when it + is included in a response and obey the requirements described in + section 13.6 that describes the interactions between caching and + content negotiation. + +12.2 Agent-driven Negotiation + + With agent-driven negotiation, selection of the best representation + for a response is performed by the user agent after receiving an + initial response from the origin server. Selection is based on a list + of the available representations of the response included within the + header fields (this specification reserves the field-name Alternates, + as described in appendix 19.6.2.1) or entity-body of the initial + response, with each representation identified by its own URI. + Selection from among the representations may be performed + automatically (if the user agent is capable of doing so) or manually + by the user selecting from a generated (possibly hypertext) menu. + + Agent-driven negotiation is advantageous when the response would vary + over commonly-used dimensions (such as type, language, or encoding), + when the origin server is unable to determine a user agent's + capabilities from examining the request, and generally when public + caches are used to distribute server load and reduce network usage. + + + +Fielding, et. al. Standards Track [Page 69] + +RFC 2068 HTTP/1.1 January 1997 + + + Agent-driven negotiation suffers from the disadvantage of needing a + second request to obtain the best alternate representation. This + second request is only efficient when caching is used. In addition, + this specification does not define any mechanism for supporting + automatic selection, though it also does not prevent any such + mechanism from being developed as an extension and used within + HTTP/1.1. + + HTTP/1.1 defines the 300 (Multiple Choices) and 406 (Not Acceptable) + status codes for enabling agent-driven negotiation when the server is + unwilling or unable to provide a varying response using server-driven + negotiation. + +12.3 Transparent Negotiation + + Transparent negotiation is a combination of both server-driven and + agent-driven negotiation. When a cache is supplied with a form of the + list of available representations of the response (as in agent-driven + negotiation) and the dimensions of variance are completely understood + by the cache, then the cache becomes capable of performing server- + driven negotiation on behalf of the origin server for subsequent + requests on that resource. + + Transparent negotiation has the advantage of distributing the + negotiation work that would otherwise be required of the origin + server and also removing the second request delay of agent-driven + negotiation when the cache is able to correctly guess the right + response. + + This specification does not define any mechanism for transparent + negotiation, though it also does not prevent any such mechanism from + being developed as an extension and used within HTTP/1.1. An HTTP/1.1 + cache performing transparent negotiation MUST include a Vary header + field in the response (defining the dimensions of its variance) if it + is cachable to ensure correct interoperation with all HTTP/1.1 + clients. The agent-driven negotiation information supplied by the + origin server SHOULD be included with the transparently negotiated + response. + +13 Caching in HTTP + + HTTP is typically used for distributed information systems, where + performance can be improved by the use of response caches. The + HTTP/1.1 protocol includes a number of elements intended to make + caching work as well as possible. Because these elements are + inextricable from other aspects of the protocol, and because they + interact with each other, it is useful to describe the basic caching + design of HTTP separately from the detailed descriptions of methods, + + + +Fielding, et. al. Standards Track [Page 70] + +RFC 2068 HTTP/1.1 January 1997 + + + headers, response codes, etc. + + Caching would be useless if it did not significantly improve + performance. The goal of caching in HTTP/1.1 is to eliminate the need + to send requests in many cases, and to eliminate the need to send + full responses in many other cases. The former reduces the number of + network round-trips required for many operations; we use an + "expiration" mechanism for this purpose (see section 13.2). The + latter reduces network bandwidth requirements; we use a "validation" + mechanism for this purpose (see section 13.3). + + Requirements for performance, availability, and disconnected + operation require us to be able to relax the goal of semantic + transparency. The HTTP/1.1 protocol allows origin servers, caches, + and clients to explicitly reduce transparency when necessary. + However, because non-transparent operation may confuse non-expert + users, and may be incompatible with certain server applications (such + as those for ordering merchandise), the protocol requires that + transparency be relaxed + + o only by an explicit protocol-level request when relaxed by client + or origin server + + o only with an explicit warning to the end user when relaxed by cache + or client + + + + + + + + + + + + + + + + + + + + + + + + + + +Fielding, et. al. Standards Track [Page 71] + +RFC 2068 HTTP/1.1 January 1997 + + + Therefore, the HTTP/1.1 protocol provides these important elements: + + 1. Protocol features that provide full semantic transparency when this + is required by all parties. + + 2. Protocol features that allow an origin server or user agent to + explicitly request and control non-transparent operation. + + 3. Protocol features that allow a cache to attach warnings to + responses that do not preserve the requested approximation of + semantic transparency. + + A basic principle is that it must be possible for the clients to + detect any potential relaxation of semantic transparency. + + Note: The server, cache, or client implementer may be faced with + design decisions not explicitly discussed in this specification. If + a decision may affect semantic transparency, the implementer ought + to err on the side of maintaining transparency unless a careful and + complete analysis shows significant benefits in breaking + transparency. + +13.1.1 Cache Correctness + + A correct cache MUST respond to a request with the most up-to-date + response held by the cache that is appropriate to the request (see + sections 13.2.5, 13.2.6, and 13.12) which meets one of the following + conditions: + + 1. It has been checked for equivalence with what the origin server + would have returned by revalidating the response with the origin + server (section 13.3); + + 2. It is "fresh enough" (see section 13.2). In the default case, this + means it meets the least restrictive freshness requirement of the + client, server, and cache (see section 14.9); if the origin server + so specifies, it is the freshness requirement of the origin server + alone. + + 3. It includes a warning if the freshness demand of the client or the + origin server is violated (see section 13.1.5 and 14.45). + + 4. It is an appropriate 304 (Not Modified), 305 (Proxy Redirect), or + error (4xx or 5xx) response message. + + If the cache can not communicate with the origin server, then a + correct cache SHOULD respond as above if the response can be + correctly served from the cache; if not it MUST return an error or + + + +Fielding, et. al. Standards Track [Page 72] + +RFC 2068 HTTP/1.1 January 1997 + + + warning indicating that there was a communication failure. + + If a cache receives a response (either an entire response, or a 304 + (Not Modified) response) that it would normally forward to the + requesting client, and the received response is no longer fresh, the + cache SHOULD forward it to the requesting client without adding a new + Warning (but without removing any existing Warning headers). A cache + SHOULD NOT attempt to revalidate a response simply because that + response became stale in transit; this might lead to an infinite + loop. An user agent that receives a stale response without a Warning + MAY display a warning indication to the user. + +13.1.2 Warnings + + Whenever a cache returns a response that is neither first-hand nor + "fresh enough" (in the sense of condition 2 in section 13.1.1), it + must attach a warning to that effect, using a Warning response- + header. This warning allows clients to take appropriate action. + + Warnings may be used for other purposes, both cache-related and + otherwise. The use of a warning, rather than an error status code, + distinguish these responses from true failures. + + Warnings are always cachable, because they never weaken the + transparency of a response. This means that warnings can be passed to + HTTP/1.0 caches without danger; such caches will simply pass the + warning along as an entity-header in the response. + + Warnings are assigned numbers between 0 and 99. This specification + defines the code numbers and meanings of each currently assigned + warnings, allowing a client or cache to take automated action in some + (but not all) cases. + + Warnings also carry a warning text. The text may be in any + appropriate natural language (perhaps based on the client's Accept + headers), and include an optional indication of what character set is + used. + + Multiple warnings may be attached to a response (either by the origin + server or by a cache), including multiple warnings with the same code + number. For example, a server may provide the same warning with texts + in both English and Basque. + + When multiple warnings are attached to a response, it may not be + practical or reasonable to display all of them to the user. This + version of HTTP does not specify strict priority rules for deciding + which warnings to display and in what order, but does suggest some + heuristics. + + + +Fielding, et. al. Standards Track [Page 73] + +RFC 2068 HTTP/1.1 January 1997 + + + The Warning header and the currently defined warnings are described + in section 14.45. + +13.1.3 Cache-control Mechanisms + + The basic cache mechanisms in HTTP/1.1 (server-specified expiration + times and validators) are implicit directives to caches. In some + cases, a server or client may need to provide explicit directives to + the HTTP caches. We use the Cache-Control header for this purpose. + + The Cache-Control header allows a client or server to transmit a + variety of directives in either requests or responses. These + directives typically override the default caching algorithms. As a + general rule, if there is any apparent conflict between header + values, the most restrictive interpretation should be applied (that + is, the one that is most likely to preserve semantic transparency). + However, in some cases, Cache-Control directives are explicitly + specified as weakening the approximation of semantic transparency + (for example, "max-stale" or "public"). + + The Cache-Control directives are described in detail in section 14.9. + +13.1.4 Explicit User Agent Warnings + + Many user agents make it possible for users to override the basic + caching mechanisms. For example, the user agent may allow the user to + specify that cached entities (even explicitly stale ones) are never + validated. Or the user agent might habitually add "Cache-Control: + max-stale=3600" to every request. The user should have to explicitly + request either non-transparent behavior, or behavior that results in + abnormally ineffective caching. + + If the user has overridden the basic caching mechanisms, the user + agent should explicitly indicate to the user whenever this results in + the display of information that might not meet the server's + transparency requirements (in particular, if the displayed entity is + known to be stale). Since the protocol normally allows the user agent + to determine if responses are stale or not, this indication need only + be displayed when this actually happens. The indication need not be a + dialog box; it could be an icon (for example, a picture of a rotting + fish) or some other visual indicator. + + If the user has overridden the caching mechanisms in a way that would + abnormally reduce the effectiveness of caches, the user agent should + continually display an indication (for example, a picture of currency + in flames) so that the user does not inadvertently consume excess + resources or suffer from excessive latency. + + + + +Fielding, et. al. Standards Track [Page 74] + +RFC 2068 HTTP/1.1 January 1997 + + +13.1.5 Exceptions to the Rules and Warnings + + In some cases, the operator of a cache may choose to configure it to + return stale responses even when not requested by clients. This + decision should not be made lightly, but may be necessary for reasons + of availability or performance, especially when the cache is poorly + connected to the origin server. Whenever a cache returns a stale + response, it MUST mark it as such (using a Warning header). This + allows the client software to alert the user that there may be a + potential problem. + + It also allows the user agent to take steps to obtain a first-hand or + fresh response. For this reason, a cache SHOULD NOT return a stale + response if the client explicitly requests a first-hand or fresh one, + unless it is impossible to comply for technical or policy reasons. + +13.1.6 Client-controlled Behavior + + While the origin server (and to a lesser extent, intermediate caches, + by their contribution to the age of a response) are the primary + source of expiration information, in some cases the client may need + to control a cache's decision about whether to return a cached + response without validating it. Clients do this using several + directives of the Cache-Control header. + + A client's request may specify the maximum age it is willing to + accept of an unvalidated response; specifying a value of zero forces + the cache(s) to revalidate all responses. A client may also specify + the minimum time remaining before a response expires. Both of these + options increase constraints on the behavior of caches, and so cannot + further relax the cache's approximation of semantic transparency. + + A client may also specify that it will accept stale responses, up to + some maximum amount of staleness. This loosens the constraints on the + caches, and so may violate the origin server's specified constraints + on semantic transparency, but may be necessary to support + disconnected operation, or high availability in the face of poor + connectivity. + +13.2 Expiration Model + +13.2.1 Server-Specified Expiration + + HTTP caching works best when caches can entirely avoid making + requests to the origin server. The primary mechanism for avoiding + requests is for an origin server to provide an explicit expiration + time in the future, indicating that a response may be used to satisfy + subsequent requests. In other words, a cache can return a fresh + + + +Fielding, et. al. Standards Track [Page 75] + +RFC 2068 HTTP/1.1 January 1997 + + + response without first contacting the server. + + Our expectation is that servers will assign future explicit + expiration times to responses in the belief that the entity is not + likely to change, in a semantically significant way, before the + expiration time is reached. This normally preserves semantic + transparency, as long as the server's expiration times are carefully + chosen. + + The expiration mechanism applies only to responses taken from a cache + and not to first-hand responses forwarded immediately to the + requesting client. + + If an origin server wishes to force a semantically transparent cache + to validate every request, it may assign an explicit expiration time + in the past. This means that the response is always stale, and so the + cache SHOULD validate it before using it for subsequent requests. See + section 14.9.4 for a more restrictive way to force revalidation. + + If an origin server wishes to force any HTTP/1.1 cache, no matter how + it is configured, to validate every request, it should use the + "must-revalidate" Cache-Control directive (see section 14.9). + + Servers specify explicit expiration times using either the Expires + header, or the max-age directive of the Cache-Control header. + + An expiration time cannot be used to force a user agent to refresh + its display or reload a resource; its semantics apply only to caching + mechanisms, and such mechanisms need only check a resource's + expiration status when a new request for that resource is initiated. + See section 13.13 for explanation of the difference between caches + and history mechanisms. + +13.2.2 Heuristic Expiration + + Since origin servers do not always provide explicit expiration times, + HTTP caches typically assign heuristic expiration times, employing + algorithms that use other header values (such as the Last-Modified + time) to estimate a plausible expiration time. The HTTP/1.1 + specification does not provide specific algorithms, but does impose + worst-case constraints on their results. Since heuristic expiration + times may compromise semantic transparency, they should be used + cautiously, and we encourage origin servers to provide explicit + expiration times as much as possible. + + + + + + + +Fielding, et. al. Standards Track [Page 76] + +RFC 2068 HTTP/1.1 January 1997 + + +13.2.3 Age Calculations + + In order to know if a cached entry is fresh, a cache needs to know if + its age exceeds its freshness lifetime. We discuss how to calculate + the latter in section 13.2.4; this section describes how to calculate + the age of a response or cache entry. + + In this discussion, we use the term "now" to mean "the current value + of the clock at the host performing the calculation." Hosts that use + HTTP, but especially hosts running origin servers and caches, should + use NTP [28] or some similar protocol to synchronize their clocks to + a globally accurate time standard. + + Also note that HTTP/1.1 requires origin servers to send a Date header + with every response, giving the time at which the response was + generated. We use the term "date_value" to denote the value of the + Date header, in a form appropriate for arithmetic operations. + + HTTP/1.1 uses the Age response-header to help convey age information + between caches. The Age header value is the sender's estimate of the + amount of time since the response was generated at the origin server. + In the case of a cached response that has been revalidated with the + origin server, the Age value is based on the time of revalidation, + not of the original response. + + In essence, the Age value is the sum of the time that the response + has been resident in each of the caches along the path from the + origin server, plus the amount of time it has been in transit along + network paths. + + We use the term "age_value" to denote the value of the Age header, in + a form appropriate for arithmetic operations. + + A response's age can be calculated in two entirely independent ways: + + 1. now minus date_value, if the local clock is reasonably well + synchronized to the origin server's clock. If the result is + negative, the result is replaced by zero. + + 2. age_value, if all of the caches along the response path + implement HTTP/1.1. + + Given that we have two independent ways to compute the age of a + response when it is received, we can combine these as + + corrected_received_age = max(now - date_value, age_value) + + and as long as we have either nearly synchronized clocks or all- + + + +Fielding, et. al. Standards Track [Page 77] + +RFC 2068 HTTP/1.1 January 1997 + + + HTTP/1.1 paths, one gets a reliable (conservative) result. + + Note that this correction is applied at each HTTP/1.1 cache along the + path, so that if there is an HTTP/1.0 cache in the path, the correct + received age is computed as long as the receiving cache's clock is + nearly in sync. We don't need end-to-end clock synchronization + (although it is good to have), and there is no explicit clock + synchronization step. + + Because of network-imposed delays, some significant interval may pass + from the time that a server generates a response and the time it is + received at the next outbound cache or client. If uncorrected, this + delay could result in improperly low ages. + + Because the request that resulted in the returned Age value must have + been initiated prior to that Age value's generation, we can correct + for delays imposed by the network by recording the time at which the + request was initiated. Then, when an Age value is received, it MUST + be interpreted relative to the time the request was initiated, not + the time that the response was received. This algorithm results in + conservative behavior no matter how much delay is experienced. So, we + compute: + + corrected_initial_age = corrected_received_age + + (now - request_time) + + where "request_time" is the time (according to the local clock) when + the request that elicited this response was sent. + + Summary of age calculation algorithm, when a cache receives a + response: + + /* + * age_value + * is the value of Age: header received by the cache with + * this response. + * date_value + * is the value of the origin server's Date: header + * request_time + * is the (local) time when the cache made the request + * that resulted in this cached response + * response_time + * is the (local) time when the cache received the + * response + * now + * is the current (local) time + */ + apparent_age = max(0, response_time - date_value); + + + +Fielding, et. al. Standards Track [Page 78] + +RFC 2068 HTTP/1.1 January 1997 + + + corrected_received_age = max(apparent_age, age_value); + response_delay = response_time - request_time; + corrected_initial_age = corrected_received_age + response_delay; + resident_time = now - response_time; + current_age = corrected_initial_age + resident_time; + + When a cache sends a response, it must add to the + corrected_initial_age the amount of time that the response was + resident locally. It must then transmit this total age, using the Age + header, to the next recipient cache. + + Note that a client cannot reliably tell that a response is first- + hand, but the presence of an Age header indicates that a response + is definitely not first-hand. Also, if the Date in a response is + earlier than the client's local request time, the response is + probably not first-hand (in the absence of serious clock skew). + +13.2.4 Expiration Calculations + + In order to decide whether a response is fresh or stale, we need to + compare its freshness lifetime to its age. The age is calculated as + described in section 13.2.3; this section describes how to calculate + the freshness lifetime, and to determine if a response has expired. + In the discussion below, the values can be represented in any form + appropriate for arithmetic operations. + + We use the term "expires_value" to denote the value of the Expires + header. We use the term "max_age_value" to denote an appropriate + value of the number of seconds carried by the max-age directive of + the Cache-Control header in a response (see section 14.10. + + The max-age directive takes priority over Expires, so if max-age is + present in a response, the calculation is simply: + + freshness_lifetime = max_age_value + + Otherwise, if Expires is present in the response, the calculation is: + + freshness_lifetime = expires_value - date_value + + Note that neither of these calculations is vulnerable to clock skew, + since all of the information comes from the origin server. + + If neither Expires nor Cache-Control: max-age appears in the + response, and the response does not include other restrictions on + caching, the cache MAY compute a freshness lifetime using a + heuristic. If the value is greater than 24 hours, the cache must + attach Warning 13 to any response whose age is more than 24 hours if + + + +Fielding, et. al. Standards Track [Page 79] + +RFC 2068 HTTP/1.1 January 1997 + + + such warning has not already been added. + + Also, if the response does have a Last-Modified time, the heuristic + expiration value SHOULD be no more than some fraction of the interval + since that time. A typical setting of this fraction might be 10%. + + The calculation to determine if a response has expired is quite + simple: + + response_is_fresh = (freshness_lifetime > current_age) + +13.2.5 Disambiguating Expiration Values + + Because expiration values are assigned optimistically, it is possible + for two caches to contain fresh values for the same resource that are + different. + + If a client performing a retrieval receives a non-first-hand response + for a request that was already fresh in its own cache, and the Date + header in its existing cache entry is newer than the Date on the new + response, then the client MAY ignore the response. If so, it MAY + retry the request with a "Cache-Control: max-age=0" directive (see + section 14.9), to force a check with the origin server. + + If a cache has two fresh responses for the same representation with + different validators, it MUST use the one with the more recent Date + header. This situation may arise because the cache is pooling + responses from other caches, or because a client has asked for a + reload or a revalidation of an apparently fresh cache entry. + +13.2.6 Disambiguating Multiple Responses + + Because a client may be receiving responses via multiple paths, so + that some responses flow through one set of caches and other + responses flow through a different set of caches, a client may + receive responses in an order different from that in which the origin + server sent them. We would like the client to use the most recently + generated response, even if older responses are still apparently + fresh. + + Neither the entity tag nor the expiration value can impose an + ordering on responses, since it is possible that a later response + intentionally carries an earlier expiration time. However, the + HTTP/1.1 specification requires the transmission of Date headers on + every response, and the Date values are ordered to a granularity of + one second. + + + + + +Fielding, et. al. Standards Track [Page 80] + +RFC 2068 HTTP/1.1 January 1997 + + + When a client tries to revalidate a cache entry, and the response it + receives contains a Date header that appears to be older than the one + for the existing entry, then the client SHOULD repeat the request + unconditionally, and include + + Cache-Control: max-age=0 + + to force any intermediate caches to validate their copies directly + with the origin server, or + + Cache-Control: no-cache + + to force any intermediate caches to obtain a new copy from the origin + server. + + If the Date values are equal, then the client may use either response + (or may, if it is being extremely prudent, request a new response). + Servers MUST NOT depend on clients being able to choose + deterministically between responses generated during the same second, + if their expiration times overlap. + +13.3 Validation Model + + When a cache has a stale entry that it would like to use as a + response to a client's request, it first has to check with the origin + server (or possibly an intermediate cache with a fresh response) to + see if its cached entry is still usable. We call this "validating" + the cache entry. Since we do not want to have to pay the overhead of + retransmitting the full response if the cached entry is good, and we + do not want to pay the overhead of an extra round trip if the cached + entry is invalid, the HTTP/1.1 protocol supports the use of + conditional methods. + + The key protocol features for supporting conditional methods are + those concerned with "cache validators." When an origin server + generates a full response, it attaches some sort of validator to it, + which is kept with the cache entry. When a client (user agent or + proxy cache) makes a conditional request for a resource for which it + has a cache entry, it includes the associated validator in the + request. + + The server then checks that validator against the current validator + for the entity, and, if they match, it responds with a special status + code (usually, 304 (Not Modified)) and no entity-body. Otherwise, it + returns a full response (including entity-body). Thus, we avoid + transmitting the full response if the validator matches, and we avoid + an extra round trip if it does not match. + + + + +Fielding, et. al. Standards Track [Page 81] + +RFC 2068 HTTP/1.1 January 1997 + + + Note: the comparison functions used to decide if validators match + are defined in section 13.3.3. + + In HTTP/1.1, a conditional request looks exactly the same as a normal + request for the same resource, except that it carries a special + header (which includes the validator) that implicitly turns the + method (usually, GET) into a conditional. + + The protocol includes both positive and negative senses of cache- + validating conditions. That is, it is possible to request either that + a method be performed if and only if a validator matches or if and + only if no validators match. + + Note: a response that lacks a validator may still be cached, and + served from cache until it expires, unless this is explicitly + prohibited by a Cache-Control directive. However, a cache cannot do + a conditional retrieval if it does not have a validator for the + entity, which means it will not be refreshable after it expires. + +13.3.1 Last-modified Dates + + The Last-Modified entity-header field value is often used as a cache + validator. In simple terms, a cache entry is considered to be valid + if the entity has not been modified since the Last-Modified value. + +13.3.2 Entity Tag Cache Validators + + The ETag entity-header field value, an entity tag, provides for an + "opaque" cache validator. This may allow more reliable validation in + situations where it is inconvenient to store modification dates, + where the one-second resolution of HTTP date values is not + sufficient, or where the origin server wishes to avoid certain + paradoxes that may arise from the use of modification dates. + + Entity Tags are described in section 3.11. The headers used with + entity tags are described in sections 14.20, 14.25, 14.26 and 14.43. + +13.3.3 Weak and Strong Validators + + Since both origin servers and caches will compare two validators to + decide if they represent the same or different entities, one normally + would expect that if the entity (the entity-body or any entity- + headers) changes in any way, then the associated validator would + change as well. If this is true, then we call this validator a + "strong validator." + + However, there may be cases when a server prefers to change the + validator only on semantically significant changes, and not when + + + +Fielding, et. al. Standards Track [Page 82] + +RFC 2068 HTTP/1.1 January 1997 + + + insignificant aspects of the entity change. A validator that does not + always change when the resource changes is a "weak validator." + + Entity tags are normally "strong validators," but the protocol + provides a mechanism to tag an entity tag as "weak." One can think of + a strong validator as one that changes whenever the bits of an entity + changes, while a weak value changes whenever the meaning of an entity + changes. Alternatively, one can think of a strong validator as part + of an identifier for a specific entity, while a weak validator is + part of an identifier for a set of semantically equivalent entities. + + Note: One example of a strong validator is an integer that is + incremented in stable storage every time an entity is changed. + + An entity's modification time, if represented with one-second + resolution, could be a weak validator, since it is possible that + the resource may be modified twice during a single second. + + Support for weak validators is optional; however, weak validators + allow for more efficient caching of equivalent objects; for + example, a hit counter on a site is probably good enough if it is + updated every few days or weeks, and any value during that period + is likely "good enough" to be equivalent. + + A "use" of a validator is either when a client generates a request + and includes the validator in a validating header field, or when a + server compares two validators. + + Strong validators are usable in any context. Weak validators are only + usable in contexts that do not depend on exact equality of an entity. + For example, either kind is usable for a conditional GET of a full + entity. However, only a strong validator is usable for a sub-range + retrieval, since otherwise the client may end up with an internally + inconsistent entity. + + The only function that the HTTP/1.1 protocol defines on validators is + comparison. There are two validator comparison functions, depending + on whether the comparison context allows the use of weak validators + or not: + + o The strong comparison function: in order to be considered equal, + both validators must be identical in every way, and neither may be + weak. + o The weak comparison function: in order to be considered equal, both + validators must be identical in every way, but either or both of + them may be tagged as "weak" without affecting the result. + + The weak comparison function MAY be used for simple (non-subrange) + + + +Fielding, et. al. Standards Track [Page 83] + +RFC 2068 HTTP/1.1 January 1997 + + + GET requests. The strong comparison function MUST be used in all + other cases. + + An entity tag is strong unless it is explicitly tagged as weak. + Section 3.11 gives the syntax for entity tags. + + A Last-Modified time, when used as a validator in a request, is + implicitly weak unless it is possible to deduce that it is strong, + using the following rules: + + o The validator is being compared by an origin server to the actual + current validator for the entity and, + o That origin server reliably knows that the associated entity did + not change twice during the second covered by the presented + validator. +or + + o The validator is about to be used by a client in an If-Modified- + Since or If-Unmodified-Since header, because the client has a cache + entry for the associated entity, and + o That cache entry includes a Date value, which gives the time when + the origin server sent the original response, and + o The presented Last-Modified time is at least 60 seconds before the + Date value. +or + + o The validator is being compared by an intermediate cache to the + validator stored in its cache entry for the entity, and + o That cache entry includes a Date value, which gives the time when + the origin server sent the original response, and + o The presented Last-Modified time is at least 60 seconds before the + Date value. + + This method relies on the fact that if two different responses were + sent by the origin server during the same second, but both had the + same Last-Modified time, then at least one of those responses would + have a Date value equal to its Last-Modified time. The arbitrary 60- + second limit guards against the possibility that the Date and Last- + Modified values are generated from different clocks, or at somewhat + different times during the preparation of the response. An + implementation may use a value larger than 60 seconds, if it is + believed that 60 seconds is too short. + + If a client wishes to perform a sub-range retrieval on a value for + which it has only a Last-Modified time and no opaque validator, it + may do this only if the Last-Modified time is strong in the sense + described here. + + + + +Fielding, et. al. Standards Track [Page 84] + +RFC 2068 HTTP/1.1 January 1997 + + + A cache or origin server receiving a cache-conditional request, other + than a full-body GET request, MUST use the strong comparison function + to evaluate the condition. + + These rules allow HTTP/1.1 caches and clients to safely perform sub- + range retrievals on values that have been obtained from HTTP/1.0 + servers. + +13.3.4 Rules for When to Use Entity Tags and Last-modified Dates + + We adopt a set of rules and recommendations for origin servers, + clients, and caches regarding when various validator types should be + used, and for what purposes. + + HTTP/1.1 origin servers: + + o SHOULD send an entity tag validator unless it is not feasible to + generate one. + o MAY send a weak entity tag instead of a strong entity tag, if + performance considerations support the use of weak entity tags, or + if it is unfeasible to send a strong entity tag. + o SHOULD send a Last-Modified value if it is feasible to send one, + unless the risk of a breakdown in semantic transparency that could + result from using this date in an If-Modified-Since header would + lead to serious problems. + + In other words, the preferred behavior for an HTTP/1.1 origin server + is to send both a strong entity tag and a Last-Modified value. + + In order to be legal, a strong entity tag MUST change whenever the + associated entity value changes in any way. A weak entity tag SHOULD + change whenever the associated entity changes in a semantically + significant way. + + Note: in order to provide semantically transparent caching, an + origin server must avoid reusing a specific strong entity tag value + for two different entities, or reusing a specific weak entity tag + value for two semantically different entities. Cache entries may + persist for arbitrarily long periods, regardless of expiration + times, so it may be inappropriate to expect that a cache will never + again attempt to validate an entry using a validator that it + obtained at some point in the past. + + HTTP/1.1 clients: + + o If an entity tag has been provided by the origin server, MUST + use that entity tag in any cache-conditional request (using + If-Match or If-None-Match). + + + +Fielding, et. al. Standards Track [Page 85] + +RFC 2068 HTTP/1.1 January 1997 + + + o If only a Last-Modified value has been provided by the origin + server, SHOULD use that value in non-subrange cache-conditional + requests (using If-Modified-Since). + o If only a Last-Modified value has been provided by an HTTP/1.0 + origin server, MAY use that value in subrange cache-conditional + requests (using If-Unmodified-Since:). The user agent should + provide a way to disable this, in case of difficulty. + o If both an entity tag and a Last-Modified value have been + provided by the origin server, SHOULD use both validators in + cache-conditional requests. This allows both HTTP/1.0 and + HTTP/1.1 caches to respond appropriately. + + An HTTP/1.1 cache, upon receiving a request, MUST use the most + restrictive validator when deciding whether the client's cache entry + matches the cache's own cache entry. This is only an issue when the + request contains both an entity tag and a last-modified-date + validator (If-Modified-Since or If-Unmodified-Since). + + A note on rationale: The general principle behind these rules is + that HTTP/1.1 servers and clients should transmit as much non- + redundant information as is available in their responses and + requests. HTTP/1.1 systems receiving this information will make the + most conservative assumptions about the validators they receive. + + HTTP/1.0 clients and caches will ignore entity tags. Generally, + last-modified values received or used by these systems will support + transparent and efficient caching, and so HTTP/1.1 origin servers + should provide Last-Modified values. In those rare cases where the + use of a Last-Modified value as a validator by an HTTP/1.0 system + could result in a serious problem, then HTTP/1.1 origin servers + should not provide one. + +13.3.5 Non-validating Conditionals + + The principle behind entity tags is that only the service author + knows the semantics of a resource well enough to select an + appropriate cache validation mechanism, and the specification of any + validator comparison function more complex than byte-equality would + open up a can of worms. Thus, comparisons of any other headers + (except Last-Modified, for compatibility with HTTP/1.0) are never + used for purposes of validating a cache entry. + +13.4 Response Cachability + + Unless specifically constrained by a Cache-Control (section 14.9) + directive, a caching system may always store a successful response + (see section 13.8) as a cache entry, may return it without validation + if it is fresh, and may return it after successful validation. If + + + +Fielding, et. al. Standards Track [Page 86] + +RFC 2068 HTTP/1.1 January 1997 + + + there is neither a cache validator nor an explicit expiration time + associated with a response, we do not expect it to be cached, but + certain caches may violate this expectation (for example, when little + or no network connectivity is available). A client can usually detect + that such a response was taken from a cache by comparing the Date + header to the current time. + + Note that some HTTP/1.0 caches are known to violate this + expectation without providing any Warning. + + However, in some cases it may be inappropriate for a cache to retain + an entity, or to return it in response to a subsequent request. This + may be because absolute semantic transparency is deemed necessary by + the service author, or because of security or privacy considerations. + Certain Cache-Control directives are therefore provided so that the + server can indicate that certain resource entities, or portions + thereof, may not be cached regardless of other considerations. + + Note that section 14.8 normally prevents a shared cache from saving + and returning a response to a previous request if that request + included an Authorization header. + + A response received with a status code of 200, 203, 206, 300, 301 or + 410 may be stored by a cache and used in reply to a subsequent + request, subject to the expiration mechanism, unless a Cache-Control + directive prohibits caching. However, a cache that does not support + the Range and Content-Range headers MUST NOT cache 206 (Partial + Content) responses. + + A response received with any other status code MUST NOT be returned + in a reply to a subsequent request unless there are Cache-Control + directives or another header(s) that explicitly allow it. For + example, these include the following: an Expires header (section + 14.21); a "max-age", "must-revalidate", "proxy-revalidate", "public" + or "private" Cache-Control directive (section 14.9). + +13.5 Constructing Responses From Caches + + The purpose of an HTTP cache is to store information received in + response to requests, for use in responding to future requests. In + many cases, a cache simply returns the appropriate parts of a + response to the requester. However, if the cache holds a cache entry + based on a previous response, it may have to combine parts of a new + response with what is held in the cache entry. + + + + + + + +Fielding, et. al. Standards Track [Page 87] + +RFC 2068 HTTP/1.1 January 1997 + + +13.5.1 End-to-end and Hop-by-hop Headers + + For the purpose of defining the behavior of caches and non-caching + proxies, we divide HTTP headers into two categories: + + o End-to-end headers, which must be transmitted to the + ultimate recipient of a request or response. End-to-end + headers in responses must be stored as part of a cache entry + and transmitted in any response formed from a cache entry. + o Hop-by-hop headers, which are meaningful only for a single + transport-level connection, and are not stored by caches or + forwarded by proxies. + + The following HTTP/1.1 headers are hop-by-hop headers: + + o Connection + o Keep-Alive + o Public + o Proxy-Authenticate + o Transfer-Encoding + o Upgrade + + All other headers defined by HTTP/1.1 are end-to-end headers. + + Hop-by-hop headers introduced in future versions of HTTP MUST be + listed in a Connection header, as described in section 14.10. + +13.5.2 Non-modifiable Headers + + Some features of the HTTP/1.1 protocol, such as Digest + Authentication, depend on the value of certain end-to-end headers. A + cache or non-caching proxy SHOULD NOT modify an end-to-end header + unless the definition of that header requires or specifically allows + that. + + A cache or non-caching proxy MUST NOT modify any of the following + fields in a request or response, nor may it add any of these fields + if not already present: + + o Content-Location + o ETag + o Expires + o Last-Modified + + + + + + + + +Fielding, et. al. Standards Track [Page 88] + +RFC 2068 HTTP/1.1 January 1997 + + + A cache or non-caching proxy MUST NOT modify or add any of the + following fields in a response that contains the no-transform Cache- + Control directive, or in any request: + + o Content-Encoding + o Content-Length + o Content-Range + o Content-Type + + A cache or non-caching proxy MAY modify or add these fields in a + response that does not include no-transform, but if it does so, it + MUST add a Warning 14 (Transformation applied) if one does not + already appear in the response. + + Warning: unnecessary modification of end-to-end headers may cause + authentication failures if stronger authentication mechanisms are + introduced in later versions of HTTP. Such authentication + mechanisms may rely on the values of header fields not listed here. + +13.5.3 Combining Headers + + When a cache makes a validating request to a server, and the server + provides a 304 (Not Modified) response, the cache must construct a + response to send to the requesting client. The cache uses the + entity-body stored in the cache entry as the entity-body of this + outgoing response. The end-to-end headers stored in the cache entry + are used for the constructed response, except that any end-to-end + headers provided in the 304 response MUST replace the corresponding + headers from the cache entry. Unless the cache decides to remove the + cache entry, it MUST also replace the end-to-end headers stored with + the cache entry with corresponding headers received in the incoming + response. + + In other words, the set of end-to-end headers received in the + incoming response overrides all corresponding end-to-end headers + stored with the cache entry. The cache may add Warning headers (see + section 14.45) to this set. + + If a header field-name in the incoming response matches more than one + header in the cache entry, all such old headers are replaced. + + Note: this rule allows an origin server to use a 304 (Not Modified) + response to update any header associated with a previous response + for the same entity, although it might not always be meaningful or + correct to do so. This rule does not allow an origin server to use + a 304 (not Modified) response to entirely delete a header that it + had provided with a previous response. + + + + +Fielding, et. al. Standards Track [Page 89] + +RFC 2068 HTTP/1.1 January 1997 + + +13.5.4 Combining Byte Ranges + + A response may transfer only a subrange of the bytes of an entity- + body, either because the request included one or more Range + specifications, or because a connection was broken prematurely. After + several such transfers, a cache may have received several ranges of + the same entity-body. + + If a cache has a stored non-empty set of subranges for an entity, and + an incoming response transfers another subrange, the cache MAY + combine the new subrange with the existing set if both the following + conditions are met: + + o Both the incoming response and the cache entry must have a cache + validator. + o The two cache validators must match using the strong comparison + function (see section 13.3.3). + + If either requirement is not meant, the cache must use only the most + recent partial response (based on the Date values transmitted with + every response, and using the incoming response if these values are + equal or missing), and must discard the other partial information. + +13.6 Caching Negotiated Responses + + Use of server-driven content negotiation (section 12), as indicated + by the presence of a Vary header field in a response, alters the + conditions and procedure by which a cache can use the response for + subsequent requests. + + A server MUST use the Vary header field (section 14.43) to inform a + cache of what header field dimensions are used to select among + multiple representations of a cachable response. A cache may use the + selected representation (the entity included with that particular + response) for replying to subsequent requests on that resource only + when the subsequent requests have the same or equivalent values for + all header fields specified in the Vary response-header. Requests + with a different value for one or more of those header fields would + be forwarded toward the origin server. + + If an entity tag was assigned to the representation, the forwarded + request SHOULD be conditional and include the entity tags in an If- + None-Match header field from all its cache entries for the Request- + URI. This conveys to the server the set of entities currently held by + the cache, so that if any one of these entities matches the requested + entity, the server can use the ETag header in its 304 (Not Modified) + response to tell the cache which entry is appropriate. If the + entity-tag of the new response matches that of an existing entry, the + + + +Fielding, et. al. Standards Track [Page 90] + +RFC 2068 HTTP/1.1 January 1997 + + + new response SHOULD be used to update the header fields of the + existing entry, and the result MUST be returned to the client. + + The Vary header field may also inform the cache that the + representation was selected using criteria not limited to the + request-headers; in this case, a cache MUST NOT use the response in a + reply to a subsequent request unless the cache relays the new request + to the origin server in a conditional request and the server responds + with 304 (Not Modified), including an entity tag or Content-Location + that indicates which entity should be used. + + If any of the existing cache entries contains only partial content + for the associated entity, its entity-tag SHOULD NOT be included in + the If-None-Match header unless the request is for a range that would + be fully satisfied by that entry. + + If a cache receives a successful response whose Content-Location + field matches that of an existing cache entry for the same Request- + URI, whose entity-tag differs from that of the existing entry, and + whose Date is more recent than that of the existing entry, the + existing entry SHOULD NOT be returned in response to future requests, + and should be deleted from the cache. + +13.7 Shared and Non-Shared Caches + + For reasons of security and privacy, it is necessary to make a + distinction between "shared" and "non-shared" caches. A non-shared + cache is one that is accessible only to a single user. Accessibility + in this case SHOULD be enforced by appropriate security mechanisms. + All other caches are considered to be "shared." Other sections of + this specification place certain constraints on the operation of + shared caches in order to prevent loss of privacy or failure of + access controls. + +13.8 Errors or Incomplete Response Cache Behavior + + A cache that receives an incomplete response (for example, with fewer + bytes of data than specified in a Content-Length header) may store + the response. However, the cache MUST treat this as a partial + response. Partial responses may be combined as described in section + 13.5.4; the result might be a full response or might still be + partial. A cache MUST NOT return a partial response to a client + without explicitly marking it as such, using the 206 (Partial + Content) status code. A cache MUST NOT return a partial response + using a status code of 200 (OK). + + If a cache receives a 5xx response while attempting to revalidate an + entry, it may either forward this response to the requesting client, + + + +Fielding, et. al. Standards Track [Page 91] + +RFC 2068 HTTP/1.1 January 1997 + + + or act as if the server failed to respond. In the latter case, it MAY + return a previously received response unless the cached entry + includes the "must-revalidate" Cache-Control directive (see section + 14.9). + +13.9 Side Effects of GET and HEAD + + Unless the origin server explicitly prohibits the caching of their + responses, the application of GET and HEAD methods to any resources + SHOULD NOT have side effects that would lead to erroneous behavior if + these responses are taken from a cache. They may still have side + effects, but a cache is not required to consider such side effects in + its caching decisions. Caches are always expected to observe an + origin server's explicit restrictions on caching. + + We note one exception to this rule: since some applications have + traditionally used GETs and HEADs with query URLs (those containing a + "?" in the rel_path part) to perform operations with significant side + effects, caches MUST NOT treat responses to such URLs as fresh unless + the server provides an explicit expiration time. This specifically + means that responses from HTTP/1.0 servers for such URIs should not + be taken from a cache. See section 9.1.1 for related information. + +13.10 Invalidation After Updates or Deletions + + The effect of certain methods at the origin server may cause one or + more existing cache entries to become non-transparently invalid. That + is, although they may continue to be "fresh," they do not accurately + reflect what the origin server would return for a new request. + + There is no way for the HTTP protocol to guarantee that all such + cache entries are marked invalid. For example, the request that + caused the change at the origin server may not have gone through the + proxy where a cache entry is stored. However, several rules help + reduce the likelihood of erroneous behavior. + + In this section, the phrase "invalidate an entity" means that the + cache should either remove all instances of that entity from its + storage, or should mark these as "invalid" and in need of a mandatory + revalidation before they can be returned in response to a subsequent + request. + + + + + + + + + + +Fielding, et. al. Standards Track [Page 92] + +RFC 2068 HTTP/1.1 January 1997 + + + Some HTTP methods may invalidate an entity. This is either the entity + referred to by the Request-URI, or by the Location or Content- + Location response-headers (if present). These methods are: + + o PUT + o DELETE + o POST + + In order to prevent denial of service attacks, an invalidation based + on the URI in a Location or Content-Location header MUST only be + performed if the host part is the same as in the Request-URI. + +13.11 Write-Through Mandatory + + All methods that may be expected to cause modifications to the origin + server's resources MUST be written through to the origin server. This + currently includes all methods except for GET and HEAD. A cache MUST + NOT reply to such a request from a client before having transmitted + the request to the inbound server, and having received a + corresponding response from the inbound server. This does not prevent + a cache from sending a 100 (Continue) response before the inbound + server has replied. + + The alternative (known as "write-back" or "copy-back" caching) is not + allowed in HTTP/1.1, due to the difficulty of providing consistent + updates and the problems arising from server, cache, or network + failure prior to write-back. + +13.12 Cache Replacement + + If a new cachable (see sections 14.9.2, 13.2.5, 13.2.6 and 13.8) + response is received from a resource while any existing responses for + the same resource are cached, the cache SHOULD use the new response + to reply to the current request. It may insert it into cache storage + and may, if it meets all other requirements, use it to respond to any + future requests that would previously have caused the old response to + be returned. If it inserts the new response into cache storage it + should follow the rules in section 13.5.3. + + Note: a new response that has an older Date header value than + existing cached responses is not cachable. + +13.13 History Lists + + User agents often have history mechanisms, such as "Back" buttons and + history lists, which can be used to redisplay an entity retrieved + earlier in a session. + + + + +Fielding, et. al. Standards Track [Page 93] + +RFC 2068 HTTP/1.1 January 1997 + + + History mechanisms and caches are different. In particular history + mechanisms SHOULD NOT try to show a semantically transparent view of + the current state of a resource. Rather, a history mechanism is meant + to show exactly what the user saw at the time when the resource was + retrieved. + + By default, an expiration time does not apply to history mechanisms. + If the entity is still in storage, a history mechanism should display + it even if the entity has expired, unless the user has specifically + configured the agent to refresh expired history documents. + + This should not be construed to prohibit the history mechanism from + telling the user that a view may be stale. + + Note: if history list mechanisms unnecessarily prevent users from + viewing stale resources, this will tend to force service authors to + avoid using HTTP expiration controls and cache controls when they + would otherwise like to. Service authors may consider it important + that users not be presented with error messages or warning messages + when they use navigation controls (such as BACK) to view previously + fetched resources. Even though sometimes such resources ought not + to cached, or ought to expire quickly, user interface + considerations may force service authors to resort to other means + of preventing caching (e.g. "once-only" URLs) in order not to + suffer the effects of improperly functioning history mechanisms. + +14 Header Field Definitions + + This section defines the syntax and semantics of all standard + HTTP/1.1 header fields. For entity-header fields, both sender and + recipient refer to either the client or the server, depending on who + sends and who receives the entity. + + + + + + + + + + + + + + + + + + + +Fielding, et. al. Standards Track [Page 94] + +RFC 2068 HTTP/1.1 January 1997 + + +14.1 Accept + + The Accept request-header field can be used to specify certain media + types which are acceptable for the response. Accept headers can be + used to indicate that the request is specifically limited to a small + set of desired types, as in the case of a request for an in-line + image. + + Accept = "Accept" ":" + #( media-range [ accept-params ] ) + + media-range = ( "*/*" + | ( type "/" "*" ) + | ( type "/" subtype ) + ) *( ";" parameter ) + + accept-params = ";" "q" "=" qvalue *( accept-extension ) + + accept-extension = ";" token [ "=" ( token | quoted-string ) ] + + The asterisk "*" character is used to group media types into ranges, + with "*/*" indicating all media types and "type/*" indicating all + subtypes of that type. The media-range MAY include media type + parameters that are applicable to that range. + + Each media-range MAY be followed by one or more accept-params, + beginning with the "q" parameter for indicating a relative quality + factor. The first "q" parameter (if any) separates the media-range + parameter(s) from the accept-params. Quality factors allow the user + or user agent to indicate the relative degree of preference for that + media-range, using the qvalue scale from 0 to 1 (section 3.9). The + default value is q=1. + + Note: Use of the "q" parameter name to separate media type + parameters from Accept extension parameters is due to historical + practice. Although this prevents any media type parameter named + "q" from being used with a media range, such an event is believed + to be unlikely given the lack of any "q" parameters in the IANA + media type registry and the rare usage of any media type parameters + in Accept. Future media types should be discouraged from + registering any parameter named "q". + + The example + + Accept: audio/*; q=0.2, audio/basic + + SHOULD be interpreted as "I prefer audio/basic, but send me any audio + type if it is the best available after an 80% mark-down in quality." + + + +Fielding, et. al. Standards Track [Page 95] + +RFC 2068 HTTP/1.1 January 1997 + + + If no Accept header field is present, then it is assumed that the + client accepts all media types. If an Accept header field is present, + and if the server cannot send a response which is acceptable + according to the combined Accept field value, then the server SHOULD + send a 406 (not acceptable) response. + + A more elaborate example is + + Accept: text/plain; q=0.5, text/html, + text/x-dvi; q=0.8, text/x-c + + Verbally, this would be interpreted as "text/html and text/x-c are + the preferred media types, but if they do not exist, then send the + text/x-dvi entity, and if that does not exist, send the text/plain + entity." + + Media ranges can be overridden by more specific media ranges or + specific media types. If more than one media range applies to a given + type, the most specific reference has precedence. For example, + + Accept: text/*, text/html, text/html;level=1, */* + + have the following precedence: + + 1) text/html;level=1 + 2) text/html + 3) text/* + 4) */* + + The media type quality factor associated with a given type is + determined by finding the media range with the highest precedence + which matches that type. For example, + + Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1, + text/html;level=2;q=0.4, */*;q=0.5 + + would cause the following values to be associated: + + text/html;level=1 = 1 + text/html = 0.7 + text/plain = 0.3 + image/jpeg = 0.5 + text/html;level=2 = 0.4 + text/html;level=3 = 0.7 + + Note: A user agent may be provided with a default set of quality + values for certain media ranges. However, unless the user agent is + a closed system which cannot interact with other rendering agents, + + + +Fielding, et. al. Standards Track [Page 96] + +RFC 2068 HTTP/1.1 January 1997 + + + this default set should be configurable by the user. + +14.2 Accept-Charset + + The Accept-Charset request-header field can be used to indicate what + character sets are acceptable for the response. This field allows + clients capable of understanding more comprehensive or special- + purpose character sets to signal that capability to a server which is + capable of representing documents in those character sets. The ISO- + 8859-1 character set can be assumed to be acceptable to all user + agents. + + Accept-Charset = "Accept-Charset" ":" + 1#( charset [ ";" "q" "=" qvalue ] ) + + Character set values are described in section 3.4. Each charset may + be given an associated quality value which represents the user's + preference for that charset. The default value is q=1. An example is + + Accept-Charset: iso-8859-5, unicode-1-1;q=0.8 + + If no Accept-Charset header is present, the default is that any + character set is acceptable. If an Accept-Charset header is present, + and if the server cannot send a response which is acceptable + according to the Accept-Charset header, then the server SHOULD send + an error response with the 406 (not acceptable) status code, though + the sending of an unacceptable response is also allowed. + +14.3 Accept-Encoding + + The Accept-Encoding request-header field is similar to Accept, but + restricts the content-coding values (section 14.12) which are + acceptable in the response. + + Accept-Encoding = "Accept-Encoding" ":" + #( content-coding ) + + An example of its use is + + Accept-Encoding: compress, gzip + + If no Accept-Encoding header is present in a request, the server MAY + assume that the client will accept any content coding. If an Accept- + Encoding header is present, and if the server cannot send a response + which is acceptable according to the Accept-Encoding header, then the + server SHOULD send an error response with the 406 (Not Acceptable) + status code. + + + + +Fielding, et. al. Standards Track [Page 97] + +RFC 2068 HTTP/1.1 January 1997 + + + An empty Accept-Encoding value indicates none are acceptable. + +14.4 Accept-Language + + The Accept-Language request-header field is similar to Accept, but + restricts the set of natural languages that are preferred as a + response to the request. + + Accept-Language = "Accept-Language" ":" + 1#( language-range [ ";" "q" "=" qvalue ] ) + + language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" ) + + Each language-range MAY be given an associated quality value which + represents an estimate of the user's preference for the languages + specified by that range. The quality value defaults to "q=1". For + example, + + Accept-Language: da, en-gb;q=0.8, en;q=0.7 + + would mean: "I prefer Danish, but will accept British English and + other types of English." A language-range matches a language-tag if + it exactly equals the tag, or if it exactly equals a prefix of the + tag such that the first tag character following the prefix is "-". + The special range "*", if present in the Accept-Language field, + matches every tag not matched by any other range present in the + Accept-Language field. + + Note: This use of a prefix matching rule does not imply that + language tags are assigned to languages in such a way that it is + always true that if a user understands a language with a certain + tag, then this user will also understand all languages with tags + for which this tag is a prefix. The prefix rule simply allows the + use of prefix tags if this is the case. + + The language quality factor assigned to a language-tag by the + Accept-Language field is the quality value of the longest language- + range in the field that matches the language-tag. If no language- + range in the field matches the tag, the language quality factor + assigned is 0. If no Accept-Language header is present in the + request, the server SHOULD assume that all languages are equally + acceptable. If an Accept-Language header is present, then all + languages which are assigned a quality factor greater than 0 are + acceptable. + + It may be contrary to the privacy expectations of the user to send an + Accept-Language header with the complete linguistic preferences of + the user in every request. For a discussion of this issue, see + + + +Fielding, et. al. Standards Track [Page 98] + +RFC 2068 HTTP/1.1 January 1997 + + + section 15.7. + + Note: As intelligibility is highly dependent on the individual + user, it is recommended that client applications make the choice of + linguistic preference available to the user. If the choice is not + made available, then the Accept-Language header field must not be + given in the request. + +14.5 Accept-Ranges + + The Accept-Ranges response-header field allows the server to indicate + its acceptance of range requests for a resource: + + Accept-Ranges = "Accept-Ranges" ":" acceptable-ranges + + acceptable-ranges = 1#range-unit | "none" + + Origin servers that accept byte-range requests MAY send + + Accept-Ranges: bytes + + but are not required to do so. Clients MAY generate byte-range + requests without having received this header for the resource + involved. + + Servers that do not accept any kind of range request for a resource + MAY send + + Accept-Ranges: none + + to advise the client not to attempt a range request. + +14.6 Age + + The Age response-header field conveys the sender's estimate of the + amount of time since the response (or its revalidation) was generated + at the origin server. A cached response is "fresh" if its age does + not exceed its freshness lifetime. Age values are calculated as + specified in section 13.2.3. + + Age = "Age" ":" age-value + + age-value = delta-seconds + + Age values are non-negative decimal integers, representing time in + seconds. + + + + + +Fielding, et. al. Standards Track [Page 99] + +RFC 2068 HTTP/1.1 January 1997 + + + If a cache receives a value larger than the largest positive integer + it can represent, or if any of its age calculations overflows, it + MUST transmit an Age header with a value of 2147483648 (2^31). + HTTP/1.1 caches MUST send an Age header in every response. Caches + SHOULD use an arithmetic type of at least 31 bits of range. + +14.7 Allow + + The Allow entity-header field lists the set of methods supported by + the resource identified by the Request-URI. The purpose of this field + is strictly to inform the recipient of valid methods associated with + the resource. An Allow header field MUST be present in a 405 (Method + Not Allowed) response. + + Allow = "Allow" ":" 1#method + + Example of use: + + Allow: GET, HEAD, PUT + + This field cannot prevent a client from trying other methods. + However, the indications given by the Allow header field value SHOULD + be followed. The actual set of allowed methods is defined by the + origin server at the time of each request. + + The Allow header field MAY be provided with a PUT request to + recommend the methods to be supported by the new or modified + resource. The server is not required to support these methods and + SHOULD include an Allow header in the response giving the actual + supported methods. + + A proxy MUST NOT modify the Allow header field even if it does not + understand all the methods specified, since the user agent MAY have + other means of communicating with the origin server. + + The Allow header field does not indicate what methods are implemented + at the server level. Servers MAY use the Public response-header field + (section 14.35) to describe what methods are implemented on the + server as a whole. + +14.8 Authorization + + A user agent that wishes to authenticate itself with a server-- + usually, but not necessarily, after receiving a 401 response--MAY do + so by including an Authorization request-header field with the + request. The Authorization field value consists of credentials + containing the authentication information of the user agent for the + realm of the resource being requested. + + + +Fielding, et. al. Standards Track [Page 100] + +RFC 2068 HTTP/1.1 January 1997 + + + Authorization = "Authorization" ":" credentials + + HTTP access authentication is described in section 11. If a request + is authenticated and a realm specified, the same credentials SHOULD + be valid for all other requests within this realm. + + When a shared cache (see section 13.7) receives a request containing + an Authorization field, it MUST NOT return the corresponding response + as a reply to any other request, unless one of the following specific + exceptions holds: + + 1. If the response includes the "proxy-revalidate" Cache-Control + directive, the cache MAY use that response in replying to a + subsequent request, but a proxy cache MUST first revalidate it with + the origin server, using the request-headers from the new request + to allow the origin server to authenticate the new request. + 2. If the response includes the "must-revalidate" Cache-Control + directive, the cache MAY use that response in replying to a + subsequent request, but all caches MUST first revalidate it with + the origin server, using the request-headers from the new request + to allow the origin server to authenticate the new request. + 3. If the response includes the "public" Cache-Control directive, it + may be returned in reply to any subsequent request. + +14.9 Cache-Control + + The Cache-Control general-header field is used to specify directives + that MUST be obeyed by all caching mechanisms along the + request/response chain. The directives specify behavior intended to + prevent caches from adversely interfering with the request or + response. These directives typically override the default caching + algorithms. Cache directives are unidirectional in that the presence + of a directive in a request does not imply that the same directive + should be given in the response. + + Note that HTTP/1.0 caches may not implement Cache-Control and may + only implement Pragma: no-cache (see section 14.32). + + Cache directives must be passed through by a proxy or gateway + application, regardless of their significance to that application, + since the directives may be applicable to all recipients along the + request/response chain. It is not possible to specify a cache- + directive for a specific cache. + + Cache-Control = "Cache-Control" ":" 1#cache-directive + + cache-directive = cache-request-directive + | cache-response-directive + + + +Fielding, et. al. Standards Track [Page 101] + +RFC 2068 HTTP/1.1 January 1997 + + + cache-request-directive = + "no-cache" [ "=" <"> 1#field-name <"> ] + | "no-store" + | "max-age" "=" delta-seconds + | "max-stale" [ "=" delta-seconds ] + | "min-fresh" "=" delta-seconds + | "only-if-cached" + | cache-extension + + cache-response-directive = + "public" + | "private" [ "=" <"> 1#field-name <"> ] + | "no-cache" [ "=" <"> 1#field-name <"> ] + | "no-store" + | "no-transform" + | "must-revalidate" + | "proxy-revalidate" + | "max-age" "=" delta-seconds + | cache-extension + + cache-extension = token [ "=" ( token | quoted-string ) ] + + When a directive appears without any 1#field-name parameter, the + directive applies to the entire request or response. When such a + directive appears with a 1#field-name parameter, it applies only to + the named field or fields, and not to the rest of the request or + response. This mechanism supports extensibility; implementations of + future versions of the HTTP protocol may apply these directives to + header fields not defined in HTTP/1.1. + + The cache-control directives can be broken down into these general + categories: + + o Restrictions on what is cachable; these may only be imposed by the + origin server. + o Restrictions on what may be stored by a cache; these may be imposed + by either the origin server or the user agent. + o Modifications of the basic expiration mechanism; these may be + imposed by either the origin server or the user agent. + o Controls over cache revalidation and reload; these may only be + imposed by a user agent. + o Control over transformation of entities. + o Extensions to the caching system. + + + + + + + + +Fielding, et. al. Standards Track [Page 102] + +RFC 2068 HTTP/1.1 January 1997 + + +14.9.1 What is Cachable + + By default, a response is cachable if the requirements of the request + method, request header fields, and the response status indicate that + it is cachable. Section 13.4 summarizes these defaults for + cachability. The following Cache-Control response directives allow an + origin server to override the default cachability of a response: + +public + Indicates that the response is cachable by any cache, even if it + would normally be non-cachable or cachable only within a non-shared + cache. (See also Authorization, section 14.8, for additional + details.) + +private + Indicates that all or part of the response message is intended for a + single user and MUST NOT be cached by a shared cache. This allows an + origin server to state that the specified parts of the response are + intended for only one user and are not a valid response for requests + by other users. A private (non-shared) cache may cache the response. + + Note: This usage of the word private only controls where the + response may be cached, and cannot ensure the privacy of the + message content. + +no-cache + Indicates that all or part of the response message MUST NOT be cached + anywhere. This allows an origin server to prevent caching even by + caches that have been configured to return stale responses to client + requests. + + Note: Most HTTP/1.0 caches will not recognize or obey this + directive. + +14.9.2 What May be Stored by Caches + + The purpose of the no-store directive is to prevent the inadvertent + release or retention of sensitive information (for example, on backup + tapes). The no-store directive applies to the entire message, and may + be sent either in a response or in a request. If sent in a request, a + cache MUST NOT store any part of either this request or any response + to it. If sent in a response, a cache MUST NOT store any part of + either this response or the request that elicited it. This directive + applies to both non-shared and shared caches. "MUST NOT store" in + this context means that the cache MUST NOT intentionally store the + information in non-volatile storage, and MUST make a best-effort + attempt to remove the information from volatile storage as promptly + as possible after forwarding it. + + + +Fielding, et. al. Standards Track [Page 103] + +RFC 2068 HTTP/1.1 January 1997 + + + Even when this directive is associated with a response, users may + explicitly store such a response outside of the caching system (e.g., + with a "Save As" dialog). History buffers may store such responses as + part of their normal operation. + + The purpose of this directive is to meet the stated requirements of + certain users and service authors who are concerned about accidental + releases of information via unanticipated accesses to cache data + structures. While the use of this directive may improve privacy in + some cases, we caution that it is NOT in any way a reliable or + sufficient mechanism for ensuring privacy. In particular, malicious + or compromised caches may not recognize or obey this directive; and + communications networks may be vulnerable to eavesdropping. + +14.9.3 Modifications of the Basic Expiration Mechanism + + The expiration time of an entity may be specified by the origin + server using the Expires header (see section 14.21). Alternatively, + it may be specified using the max-age directive in a response. + + If a response includes both an Expires header and a max-age + directive, the max-age directive overrides the Expires header, even + if the Expires header is more restrictive. This rule allows an origin + server to provide, for a given response, a longer expiration time to + an HTTP/1.1 (or later) cache than to an HTTP/1.0 cache. This may be + useful if certain HTTP/1.0 caches improperly calculate ages or + expiration times, perhaps due to desynchronized clocks. + + Note: most older caches, not compliant with this specification, do + not implement any Cache-Control directives. An origin server + wishing to use a Cache-Control directive that restricts, but does + not prevent, caching by an HTTP/1.1-compliant cache may exploit the + requirement that the max-age directive overrides the Expires + header, and the fact that non-HTTP/1.1-compliant caches do not + observe the max-age directive. + + Other directives allow an user agent to modify the basic expiration + mechanism. These directives may be specified on a request: + + max-age + Indicates that the client is willing to accept a response whose age + is no greater than the specified time in seconds. Unless max-stale + directive is also included, the client is not willing to accept a + stale response. + + min-fresh + Indicates that the client is willing to accept a response whose + freshness lifetime is no less than its current age plus the + + + +Fielding, et. al. Standards Track [Page 104] + +RFC 2068 HTTP/1.1 January 1997 + + + specified time in seconds. That is, the client wants a response + that will still be fresh for at least the specified number of + seconds. + + max-stale + Indicates that the client is willing to accept a response that has + exceeded its expiration time. If max-stale is assigned a value, + then the client is willing to accept a response that has exceeded + its expiration time by no more than the specified number of + seconds. If no value is assigned to max-stale, then the client is + willing to accept a stale response of any age. + + If a cache returns a stale response, either because of a max-stale + directive on a request, or because the cache is configured to + override the expiration time of a response, the cache MUST attach a + Warning header to the stale response, using Warning 10 (Response is + stale). + +14.9.4 Cache Revalidation and Reload Controls + + Sometimes an user agent may want or need to insist that a cache + revalidate its cache entry with the origin server (and not just with + the next cache along the path to the origin server), or to reload its + cache entry from the origin server. End-to-end revalidation may be + necessary if either the cache or the origin server has overestimated + the expiration time of the cached response. End-to-end reload may be + necessary if the cache entry has become corrupted for some reason. + + End-to-end revalidation may be requested either when the client does + not have its own local cached copy, in which case we call it + "unspecified end-to-end revalidation", or when the client does have a + local cached copy, in which case we call it "specific end-to-end + revalidation." + + The client can specify these three kinds of action using Cache- + Control request directives: + + End-to-end reload + The request includes a "no-cache" Cache-Control directive or, for + compatibility with HTTP/1.0 clients, "Pragma: no-cache". No field + names may be included with the no-cache directive in a request. The + server MUST NOT use a cached copy when responding to such a + request. + + Specific end-to-end revalidation + The request includes a "max-age=0" Cache-Control directive, which + forces each cache along the path to the origin server to revalidate + its own entry, if any, with the next cache or server. The initial + + + +Fielding, et. al. Standards Track [Page 105] + +RFC 2068 HTTP/1.1 January 1997 + + + request includes a cache-validating conditional with the client's + current validator. + + Unspecified end-to-end revalidation + The request includes "max-age=0" Cache-Control directive, which + forces each cache along the path to the origin server to revalidate + its own entry, if any, with the next cache or server. The initial + request does not include a cache-validating conditional; the first + cache along the path (if any) that holds a cache entry for this + resource includes a cache-validating conditional with its current + validator. + + When an intermediate cache is forced, by means of a max-age=0 + directive, to revalidate its own cache entry, and the client has + supplied its own validator in the request, the supplied validator may + differ from the validator currently stored with the cache entry. In + this case, the cache may use either validator in making its own + request without affecting semantic transparency. + + However, the choice of validator may affect performance. The best + approach is for the intermediate cache to use its own validator when + making its request. If the server replies with 304 (Not Modified), + then the cache should return its now validated copy to the client + with a 200 (OK) response. If the server replies with a new entity and + cache validator, however, the intermediate cache should compare the + returned validator with the one provided in the client's request, + using the strong comparison function. If the client's validator is + equal to the origin server's, then the intermediate cache simply + returns 304 (Not Modified). Otherwise, it returns the new entity with + a 200 (OK) response. + + If a request includes the no-cache directive, it should not include + min-fresh, max-stale, or max-age. + + In some cases, such as times of extremely poor network connectivity, + a client may want a cache to return only those responses that it + currently has stored, and not to reload or revalidate with the origin + server. To do this, the client may include the only-if-cached + directive in a request. If it receives this directive, a cache SHOULD + either respond using a cached entry that is consistent with the other + constraints of the request, or respond with a 504 (Gateway Timeout) + status. However, if a group of caches is being operated as a unified + system with good internal connectivity, such a request MAY be + forwarded within that group of caches. + + Because a cache may be configured to ignore a server's specified + expiration time, and because a client request may include a max-stale + directive (which has a similar effect), the protocol also includes a + + + +Fielding, et. al. Standards Track [Page 106] + +RFC 2068 HTTP/1.1 January 1997 + + + mechanism for the origin server to require revalidation of a cache + entry on any subsequent use. When the must-revalidate directive is + present in a response received by a cache, that cache MUST NOT use + the entry after it becomes stale to respond to a subsequent request + without first revalidating it with the origin server. (I.e., the + cache must do an end-to-end revalidation every time, if, based solely + on the origin server's Expires or max-age value, the cached response + is stale.) + + The must-revalidate directive is necessary to support reliable + operation for certain protocol features. In all circumstances an + HTTP/1.1 cache MUST obey the must-revalidate directive; in + particular, if the cache cannot reach the origin server for any + reason, it MUST generate a 504 (Gateway Timeout) response. + + Servers should send the must-revalidate directive if and only if + failure to revalidate a request on the entity could result in + incorrect operation, such as a silently unexecuted financial + transaction. Recipients MUST NOT take any automated action that + violates this directive, and MUST NOT automatically provide an + unvalidated copy of the entity if revalidation fails. + + Although this is not recommended, user agents operating under severe + connectivity constraints may violate this directive but, if so, MUST + explicitly warn the user that an unvalidated response has been + provided. The warning MUST be provided on each unvalidated access, + and SHOULD require explicit user confirmation. + + The proxy-revalidate directive has the same meaning as the must- + revalidate directive, except that it does not apply to non-shared + user agent caches. It can be used on a response to an authenticated + request to permit the user's cache to store and later return the + response without needing to revalidate it (since it has already been + authenticated once by that user), while still requiring proxies that + service many users to revalidate each time (in order to make sure + that each user has been authenticated). Note that such authenticated + responses also need the public cache control directive in order to + allow them to be cached at all. + +14.9.5 No-Transform Directive + + Implementers of intermediate caches (proxies) have found it useful to + convert the media type of certain entity bodies. A proxy might, for + example, convert between image formats in order to save cache space + or to reduce the amount of traffic on a slow link. HTTP has to date + been silent on these transformations. + + + + + +Fielding, et. al. Standards Track [Page 107] + +RFC 2068 HTTP/1.1 January 1997 + + + Serious operational problems have already occurred, however, when + these transformations have been applied to entity bodies intended for + certain kinds of applications. For example, applications for medical + imaging, scientific data analysis and those using end-to-end + authentication, all depend on receiving an entity body that is bit + for bit identical to the original entity-body. + + Therefore, if a response includes the no-transform directive, an + intermediate cache or proxy MUST NOT change those headers that are + listed in section 13.5.2 as being subject to the no-transform + directive. This implies that the cache or proxy must not change any + aspect of the entity-body that is specified by these headers. + +14.9.6 Cache Control Extensions + + The Cache-Control header field can be extended through the use of one + or more cache-extension tokens, each with an optional assigned value. + Informational extensions (those which do not require a change in + cache behavior) may be added without changing the semantics of other + directives. Behavioral extensions are designed to work by acting as + modifiers to the existing base of cache directives. Both the new + directive and the standard directive are supplied, such that + applications which do not understand the new directive will default + to the behavior specified by the standard directive, and those that + understand the new directive will recognize it as modifying the + requirements associated with the standard directive. In this way, + extensions to the Cache-Control directives can be made without + requiring changes to the base protocol. + + This extension mechanism depends on a HTTP cache obeying all of the + cache-control directives defined for its native HTTP-version, obeying + certain extensions, and ignoring all directives that it does not + understand. + + For example, consider a hypothetical new response directive called + "community" which acts as a modifier to the "private" directive. We + define this new directive to mean that, in addition to any non-shared + cache, any cache which is shared only by members of the community + named within its value may cache the response. An origin server + wishing to allow the "UCI" community to use an otherwise private + response in their shared cache(s) may do so by including + + Cache-Control: private, community="UCI" + + A cache seeing this header field will act correctly even if the cache + does not understand the "community" cache-extension, since it will + also see and understand the "private" directive and thus default to + the safe behavior. + + + +Fielding, et. al. Standards Track [Page 108] + +RFC 2068 HTTP/1.1 January 1997 + + + Unrecognized cache-directives MUST be ignored; it is assumed that any + cache-directive likely to be unrecognized by an HTTP/1.1 cache will + be combined with standard directives (or the response's default + cachability) such that the cache behavior will remain minimally + correct even if the cache does not understand the extension(s). + +14.10 Connection + + The Connection general-header field allows the sender to specify + options that are desired for that particular connection and MUST NOT + be communicated by proxies over further connections. + + The Connection header has the following grammar: + + Connection-header = "Connection" ":" 1#(connection-token) + connection-token = token + + HTTP/1.1 proxies MUST parse the Connection header field before a + message is forwarded and, for each connection-token in this field, + remove any header field(s) from the message with the same name as the + connection-token. Connection options are signaled by the presence of + a connection-token in the Connection header field, not by any + corresponding additional header field(s), since the additional header + field may not be sent if there are no parameters associated with that + connection option. HTTP/1.1 defines the "close" connection option + for the sender to signal that the connection will be closed after + completion of the response. For example, + + Connection: close + + in either the request or the response header fields indicates that + the connection should not be considered `persistent' (section 8.1) + after the current request/response is complete. + + HTTP/1.1 applications that do not support persistent connections MUST + include the "close" connection option in every message. + +14.11 Content-Base + + The Content-Base entity-header field may be used to specify the base + URI for resolving relative URLs within the entity. This header field + is described as Base in RFC 1808, which is expected to be revised. + + Content-Base = "Content-Base" ":" absoluteURI + + If no Content-Base field is present, the base URI of an entity is + defined either by its Content-Location (if that Content-Location URI + is an absolute URI) or the URI used to initiate the request, in that + + + +Fielding, et. al. Standards Track [Page 109] + +RFC 2068 HTTP/1.1 January 1997 + + + order of precedence. Note, however, that the base URI of the contents + within the entity-body may be redefined within that entity-body. + +14.12 Content-Encoding + + The Content-Encoding entity-header field is used as a modifier to the + media-type. When present, its value indicates what additional content + codings have been applied to the entity-body, and thus what decoding + mechanisms MUST be applied in order to obtain the media-type + referenced by the Content-Type header field. Content-Encoding is + primarily used to allow a document to be compressed without losing + the identity of its underlying media type. + + Content-Encoding = "Content-Encoding" ":" 1#content-coding + + Content codings are defined in section 3.5. An example of its use is + + Content-Encoding: gzip + + The Content-Encoding is a characteristic of the entity identified by + the Request-URI. Typically, the entity-body is stored with this + encoding and is only decoded before rendering or analogous usage. + + If multiple encodings have been applied to an entity, the content + codings MUST be listed in the order in which they were applied. + + Additional information about the encoding parameters MAY be provided + by other entity-header fields not defined by this specification. + +14.13 Content-Language + + The Content-Language entity-header field describes the natural + language(s) of the intended audience for the enclosed entity. Note + that this may not be equivalent to all the languages used within the + entity-body. + + Content-Language = "Content-Language" ":" 1#language-tag + + Language tags are defined in section 3.10. The primary purpose of + Content-Language is to allow a user to identify and differentiate + entities according to the user's own preferred language. Thus, if the + body content is intended only for a Danish-literate audience, the + appropriate field is + + Content-Language: da + + If no Content-Language is specified, the default is that the content + is intended for all language audiences. This may mean that the sender + + + +Fielding, et. al. Standards Track [Page 110] + +RFC 2068 HTTP/1.1 January 1997 + + + does not consider it to be specific to any natural language, or that + the sender does not know for which language it is intended. + + Multiple languages MAY be listed for content that is intended for + multiple audiences. For example, a rendition of the "Treaty of + Waitangi," presented simultaneously in the original Maori and English + versions, would call for + + Content-Language: mi, en + + However, just because multiple languages are present within an entity + does not mean that it is intended for multiple linguistic audiences. + An example would be a beginner's language primer, such as "A First + Lesson in Latin," which is clearly intended to be used by an + English-literate audience. In this case, the Content-Language should + only include "en". + + Content-Language may be applied to any media type -- it is not + limited to textual documents. + +14.14 Content-Length + + The Content-Length entity-header field indicates the size of the + message-body, in decimal number of octets, sent to the recipient or, + in the case of the HEAD method, the size of the entity-body that + would have been sent had the request been a GET. + + Content-Length = "Content-Length" ":" 1*DIGIT + + An example is + + Content-Length: 3495 + + Applications SHOULD use this field to indicate the size of the + message-body to be transferred, regardless of the media type of the + entity. It must be possible for the recipient to reliably determine + the end of HTTP/1.1 requests containing an entity-body, e.g., because + the request has a valid Content-Length field, uses Transfer-Encoding: + chunked or a multipart body. + + Any Content-Length greater than or equal to zero is a valid value. + Section 4.4 describes how to determine the length of a message-body + if a Content-Length is not given. + + + + + + + + +Fielding, et. al. Standards Track [Page 111] + +RFC 2068 HTTP/1.1 January 1997 + + + Note: The meaning of this field is significantly different from the + corresponding definition in MIME, where it is an optional field + used within the "message/external-body" content-type. In HTTP, it + SHOULD be sent whenever the message's length can be determined + prior to being transferred. + +14.15 Content-Location + + The Content-Location entity-header field may be used to supply the + resource location for the entity enclosed in the message. In the case + where a resource has multiple entities associated with it, and those + entities actually have separate locations by which they might be + individually accessed, the server should provide a Content-Location + for the particular variant which is returned. In addition, a server + SHOULD provide a Content-Location for the resource corresponding to + the response entity. + + Content-Location = "Content-Location" ":" + ( absoluteURI | relativeURI ) + + If no Content-Base header field is present, the value of Content- + Location also defines the base URL for the entity (see section + 14.11). + + The Content-Location value is not a replacement for the original + requested URI; it is only a statement of the location of the resource + corresponding to this particular entity at the time of the request. + Future requests MAY use the Content-Location URI if the desire is to + identify the source of that particular entity. + + A cache cannot assume that an entity with a Content-Location + different from the URI used to retrieve it can be used to respond to + later requests on that Content-Location URI. However, the Content- + Location can be used to differentiate between multiple entities + retrieved from a single requested resource, as described in section + 13.6. + + If the Content-Location is a relative URI, the URI is interpreted + relative to any Content-Base URI provided in the response. If no + Content-Base is provided, the relative URI is interpreted relative to + the Request-URI. + + + + + + + + + + +Fielding, et. al. Standards Track [Page 112] + +RFC 2068 HTTP/1.1 January 1997 + + +14.16 Content-MD5 + + The Content-MD5 entity-header field, as defined in RFC 1864 [23], is + an MD5 digest of the entity-body for the purpose of providing an + end-to-end message integrity check (MIC) of the entity-body. (Note: a + MIC is good for detecting accidental modification of the entity-body + in transit, but is not proof against malicious attacks.) + + Content-MD5 = "Content-MD5" ":" md5-digest + + md5-digest = + + The Content-MD5 header field may be generated by an origin server to + function as an integrity check of the entity-body. Only origin + servers may generate the Content-MD5 header field; proxies and + gateways MUST NOT generate it, as this would defeat its value as an + end-to-end integrity check. Any recipient of the entity-body, + including gateways and proxies, MAY check that the digest value in + this header field matches that of the entity-body as received. + + The MD5 digest is computed based on the content of the entity-body, + including any Content-Encoding that has been applied, but not + including any Transfer-Encoding that may have been applied to the + message-body. If the message is received with a Transfer-Encoding, + that encoding must be removed prior to checking the Content-MD5 value + against the received entity. + + This has the result that the digest is computed on the octets of the + entity-body exactly as, and in the order that, they would be sent if + no Transfer-Encoding were being applied. + + HTTP extends RFC 1864 to permit the digest to be computed for MIME + composite media-types (e.g., multipart/* and message/rfc822), but + this does not change how the digest is computed as defined in the + preceding paragraph. + + Note: There are several consequences of this. The entity-body for + composite types may contain many body-parts, each with its own MIME + and HTTP headers (including Content-MD5, Content-Transfer-Encoding, + and Content-Encoding headers). If a body-part has a Content- + Transfer-Encoding or Content-Encoding header, it is assumed that + the content of the body-part has had the encoding applied, and the + body-part is included in the Content-MD5 digest as is -- i.e., + after the application. The Transfer-Encoding header field is not + allowed within body-parts. + + Note: while the definition of Content-MD5 is exactly the same for + HTTP as in RFC 1864 for MIME entity-bodies, there are several ways + + + +Fielding, et. al. Standards Track [Page 113] + +RFC 2068 HTTP/1.1 January 1997 + + + in which the application of Content-MD5 to HTTP entity-bodies + differs from its application to MIME entity-bodies. One is that + HTTP, unlike MIME, does not use Content-Transfer-Encoding, and does + use Transfer-Encoding and Content-Encoding. Another is that HTTP + more frequently uses binary content types than MIME, so it is worth + noting that, in such cases, the byte order used to compute the + digest is the transmission byte order defined for the type. Lastly, + HTTP allows transmission of text types with any of several line + break conventions and not just the canonical form using CRLF. + Conversion of all line breaks to CRLF should not be done before + computing or checking the digest: the line break convention used in + the text actually transmitted should be left unaltered when + computing the digest. + +14.17 Content-Range + + The Content-Range entity-header is sent with a partial entity-body to + specify where in the full entity-body the partial body should be + inserted. It also indicates the total size of the full entity-body. + When a server returns a partial response to a client, it must + describe both the extent of the range covered by the response, and + the length of the entire entity-body. + + Content-Range = "Content-Range" ":" content-range-spec + + content-range-spec = byte-content-range-spec + + byte-content-range-spec = bytes-unit SP first-byte-pos "-" + last-byte-pos "/" entity-length + + entity-length = 1*DIGIT + + Unlike byte-ranges-specifier values, a byte-content-range-spec may + only specify one range, and must contain absolute byte positions for + both the first and last byte of the range. + + A byte-content-range-spec whose last-byte-pos value is less than its + first-byte-pos value, or whose entity-length value is less than or + equal to its last-byte-pos value, is invalid. The recipient of an + invalid byte-content-range-spec MUST ignore it and any content + transferred along with it. + + + + + + + + + + +Fielding, et. al. Standards Track [Page 114] + +RFC 2068 HTTP/1.1 January 1997 + + + Examples of byte-content-range-spec values, assuming that the entity + contains a total of 1234 bytes: + + o The first 500 bytes: + + bytes 0-499/1234 + + o The second 500 bytes: + + bytes 500-999/1234 + + o All except for the first 500 bytes: + + bytes 500-1233/1234 + + o The last 500 bytes: + + bytes 734-1233/1234 + + When an HTTP message includes the content of a single range (for + example, a response to a request for a single range, or to a request + for a set of ranges that overlap without any holes), this content is + transmitted with a Content-Range header, and a Content-Length header + showing the number of bytes actually transferred. For example, + + HTTP/1.1 206 Partial content + Date: Wed, 15 Nov 1995 06:25:24 GMT + Last-modified: Wed, 15 Nov 1995 04:58:08 GMT + Content-Range: bytes 21010-47021/47022 + Content-Length: 26012 + Content-Type: image/gif + + When an HTTP message includes the content of multiple ranges (for + example, a response to a request for multiple non-overlapping + ranges), these are transmitted as a multipart MIME message. The + multipart MIME content-type used for this purpose is defined in this + specification to be "multipart/byteranges". See appendix 19.2 for its + definition. + + A client that cannot decode a MIME multipart/byteranges message + should not ask for multiple byte-ranges in a single request. + + When a client requests multiple byte-ranges in one request, the + server SHOULD return them in the order that they appeared in the + request. + + If the server ignores a byte-range-spec because it is invalid, the + server should treat the request as if the invalid Range header field + + + +Fielding, et. al. Standards Track [Page 115] + +RFC 2068 HTTP/1.1 January 1997 + + + did not exist. (Normally, this means return a 200 response containing + the full entity). The reason is that the only time a client will make + such an invalid request is when the entity is smaller than the entity + retrieved by a prior request. + +14.18 Content-Type + + The Content-Type entity-header field indicates the media type of the + entity-body sent to the recipient or, in the case of the HEAD method, + the media type that would have been sent had the request been a GET. + + Content-Type = "Content-Type" ":" media-type + Media types are defined in section 3.7. An example of the field is + + Content-Type: text/html; charset=ISO-8859-4 + + Further discussion of methods for identifying the media type of an + entity is provided in section 7.2.1. + +14.19 Date + + The Date general-header field represents the date and time at which + the message was originated, having the same semantics as orig-date in + RFC 822. The field value is an HTTP-date, as described in section + 3.3.1. + + Date = "Date" ":" HTTP-date + + An example is + + Date: Tue, 15 Nov 1994 08:12:31 GMT + + If a message is received via direct connection with the user agent + (in the case of requests) or the origin server (in the case of + responses), then the date can be assumed to be the current date at + the receiving end. However, since the date--as it is believed by the + origin--is important for evaluating cached responses, origin servers + MUST include a Date header field in all responses. Clients SHOULD + only send a Date header field in messages that include an entity- + body, as in the case of the PUT and POST requests, and even then it + is optional. A received message which does not have a Date header + field SHOULD be assigned one by the recipient if the message will be + cached by that recipient or gatewayed via a protocol which requires a + Date. + + + + + + + +Fielding, et. al. Standards Track [Page 116] + +RFC 2068 HTTP/1.1 January 1997 + + + In theory, the date SHOULD represent the moment just before the + entity is generated. In practice, the date can be generated at any + time during the message origination without affecting its semantic + value. + + The format of the Date is an absolute date and time as defined by + HTTP-date in section 3.3; it MUST be sent in RFC1123 [8]-date format. + +14.20 ETag + + The ETag entity-header field defines the entity tag for the + associated entity. The headers used with entity tags are described in + sections 14.20, 14.25, 14.26 and 14.43. The entity tag may be used + for comparison with other entities from the same resource (see + section 13.3.2). + + ETag = "ETag" ":" entity-tag + + Examples: + + ETag: "xyzzy" + ETag: W/"xyzzy" + ETag: "" + +14.21 Expires + + The Expires entity-header field gives the date/time after which the + response should be considered stale. A stale cache entry may not + normally be returned by a cache (either a proxy cache or an user + agent cache) unless it is first validated with the origin server (or + with an intermediate cache that has a fresh copy of the entity). See + section 13.2 for further discussion of the expiration model. + + The presence of an Expires field does not imply that the original + resource will change or cease to exist at, before, or after that + time. + + The format is an absolute date and time as defined by HTTP-date in + section 3.3; it MUST be in RFC1123-date format: + + Expires = "Expires" ":" HTTP-date + + + + + + + + + + +Fielding, et. al. Standards Track [Page 117] + +RFC 2068 HTTP/1.1 January 1997 + + + An example of its use is + + Expires: Thu, 01 Dec 1994 16:00:00 GMT + + Note: if a response includes a Cache-Control field with the max-age + directive, that directive overrides the Expires field. + + HTTP/1.1 clients and caches MUST treat other invalid date formats, + especially including the value "0", as in the past (i.e., "already + expired"). + + To mark a response as "already expired," an origin server should use + an Expires date that is equal to the Date header value. (See the + rules for expiration calculations in section 13.2.4.) + + To mark a response as "never expires," an origin server should use an + Expires date approximately one year from the time the response is + sent. HTTP/1.1 servers should not send Expires dates more than one + year in the future. + + The presence of an Expires header field with a date value of some + time in the future on an response that otherwise would by default be + non-cacheable indicates that the response is cachable, unless + indicated otherwise by a Cache-Control header field (section 14.9). + +14.22 From + + The From request-header field, if given, SHOULD contain an Internet + e-mail address for the human user who controls the requesting user + agent. The address SHOULD be machine-usable, as defined by mailbox + in RFC 822 (as updated by RFC 1123 ): + + From = "From" ":" mailbox + + An example is: + + From: webmaster@w3.org + + This header field MAY be used for logging purposes and as a means for + identifying the source of invalid or unwanted requests. It SHOULD NOT + be used as an insecure form of access protection. The interpretation + of this field is that the request is being performed on behalf of the + person given, who accepts responsibility for the method performed. In + particular, robot agents SHOULD include this header so that the + person responsible for running the robot can be contacted if problems + occur on the receiving end. + + + + + +Fielding, et. al. Standards Track [Page 118] + +RFC 2068 HTTP/1.1 January 1997 + + + The Internet e-mail address in this field MAY be separate from the + Internet host which issued the request. For example, when a request + is passed through a proxy the original issuer's address SHOULD be + used. + + Note: The client SHOULD not send the From header field without the + user's approval, as it may conflict with the user's privacy + interests or their site's security policy. It is strongly + recommended that the user be able to disable, enable, and modify + the value of this field at any time prior to a request. + +14.23 Host + + The Host request-header field specifies the Internet host and port + number of the resource being requested, as obtained from the original + URL given by the user or referring resource (generally an HTTP URL, + as described in section 3.2.2). The Host field value MUST represent + the network location of the origin server or gateway given by the + original URL. This allows the origin server or gateway to + differentiate between internally-ambiguous URLs, such as the root "/" + URL of a server for multiple host names on a single IP address. + + Host = "Host" ":" host [ ":" port ] ; Section 3.2.2 + + A "host" without any trailing port information implies the default + port for the service requested (e.g., "80" for an HTTP URL). For + example, a request on the origin server for + MUST include: + + GET /pub/WWW/ HTTP/1.1 + Host: www.w3.org + + A client MUST include a Host header field in all HTTP/1.1 request + messages on the Internet (i.e., on any message corresponding to a + request for a URL which includes an Internet host address for the + service being requested). If the Host field is not already present, + an HTTP/1.1 proxy MUST add a Host field to the request message prior + to forwarding it on the Internet. All Internet-based HTTP/1.1 servers + MUST respond with a 400 status code to any HTTP/1.1 request message + which lacks a Host header field. + + See sections 5.2 and 19.5.1 for other requirements relating to Host. + +14.24 If-Modified-Since + + The If-Modified-Since request-header field is used with the GET + method to make it conditional: if the requested variant has not been + modified since the time specified in this field, an entity will not + + + +Fielding, et. al. Standards Track [Page 119] + +RFC 2068 HTTP/1.1 January 1997 + + + be returned from the server; instead, a 304 (not modified) response + will be returned without any message-body. + + If-Modified-Since = "If-Modified-Since" ":" HTTP-date + + An example of the field is: + + If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT + + A GET method with an If-Modified-Since header and no Range header + requests that the identified entity be transferred only if it has + been modified since the date given by the If-Modified-Since header. + The algorithm for determining this includes the following cases: + + a)If the request would normally result in anything other than a 200 + (OK) status, or if the passed If-Modified-Since date is invalid, the + response is exactly the same as for a normal GET. A date which is + later than the server's current time is invalid. + + b)If the variant has been modified since the If-Modified-Since date, + the response is exactly the same as for a normal GET. + + c)If the variant has not been modified since a valid If-Modified-Since + date, the server MUST return a 304 (Not Modified) response. + + The purpose of this feature is to allow efficient updates of cached + information with a minimum amount of transaction overhead. + + Note that the Range request-header field modifies the meaning of + If-Modified-Since; see section 14.36 for full details. + + Note that If-Modified-Since times are interpreted by the server, + whose clock may not be synchronized with the client. + + Note that if a client uses an arbitrary date in the If-Modified-Since + header instead of a date taken from the Last-Modified header for the + same request, the client should be aware of the fact that this date + is interpreted in the server's understanding of time. The client + should consider unsynchronized clocks and rounding problems due to + the different encodings of time between the client and server. This + includes the possibility of race conditions if the document has + changed between the time it was first requested and the If-Modified- + Since date of a subsequent request, and the possibility of clock- + skew-related problems if the If-Modified-Since date is derived from + the client's clock without correction to the server's clock. + Corrections for different time bases between client and server are at + best approximate due to network latency. + + + + +Fielding, et. al. Standards Track [Page 120] + +RFC 2068 HTTP/1.1 January 1997 + + +14.25 If-Match + + The If-Match request-header field is used with a method to make it + conditional. A client that has one or more entities previously + obtained from the resource can verify that one of those entities is + current by including a list of their associated entity tags in the + If-Match header field. The purpose of this feature is to allow + efficient updates of cached information with a minimum amount of + transaction overhead. It is also used, on updating requests, to + prevent inadvertent modification of the wrong version of a resource. + As a special case, the value "*" matches any current entity of the + resource. + + If-Match = "If-Match" ":" ( "*" | 1#entity-tag ) + + If any of the entity tags match the entity tag of the entity that + would have been returned in the response to a similar GET request + (without the If-Match header) on that resource, or if "*" is given + and any current entity exists for that resource, then the server MAY + perform the requested method as if the If-Match header field did not + exist. + + A server MUST use the strong comparison function (see section 3.11) + to compare the entity tags in If-Match. + + If none of the entity tags match, or if "*" is given and no current + entity exists, the server MUST NOT perform the requested method, and + MUST return a 412 (Precondition Failed) response. This behavior is + most useful when the client wants to prevent an updating method, such + as PUT, from modifying a resource that has changed since the client + last retrieved it. + + If the request would, without the If-Match header field, result in + anything other than a 2xx status, then the If-Match header MUST be + ignored. + + The meaning of "If-Match: *" is that the method SHOULD be performed + if the representation selected by the origin server (or by a cache, + possibly using the Vary mechanism, see section 14.43) exists, and + MUST NOT be performed if the representation does not exist. + + + + + + + + + + + +Fielding, et. al. Standards Track [Page 121] + +RFC 2068 HTTP/1.1 January 1997 + + + A request intended to update a resource (e.g., a PUT) MAY include an + If-Match header field to signal that the request method MUST NOT be + applied if the entity corresponding to the If-Match value (a single + entity tag) is no longer a representation of that resource. This + allows the user to indicate that they do not wish the request to be + successful if the resource has been changed without their knowledge. + Examples: + + If-Match: "xyzzy" + If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz" + If-Match: * + +14.26 If-None-Match + + The If-None-Match request-header field is used with a method to make + it conditional. A client that has one or more entities previously + obtained from the resource can verify that none of those entities is + current by including a list of their associated entity tags in the + If-None-Match header field. The purpose of this feature is to allow + efficient updates of cached information with a minimum amount of + transaction overhead. It is also used, on updating requests, to + prevent inadvertent modification of a resource which was not known to + exist. + + As a special case, the value "*" matches any current entity of the + resource. + + If-None-Match = "If-None-Match" ":" ( "*" | 1#entity-tag ) + + If any of the entity tags match the entity tag of the entity that + would have been returned in the response to a similar GET request + (without the If-None-Match header) on that resource, or if "*" is + given and any current entity exists for that resource, then the + server MUST NOT perform the requested method. Instead, if the request + method was GET or HEAD, the server SHOULD respond with a 304 (Not + Modified) response, including the cache-related entity-header fields + (particularly ETag) of one of the entities that matched. For all + other request methods, the server MUST respond with a status of 412 + (Precondition Failed). + + See section 13.3.3 for rules on how to determine if two entity tags + match. The weak comparison function can only be used with GET or HEAD + requests. + + If none of the entity tags match, or if "*" is given and no current + entity exists, then the server MAY perform the requested method as if + the If-None-Match header field did not exist. + + + + +Fielding, et. al. Standards Track [Page 122] + +RFC 2068 HTTP/1.1 January 1997 + + + If the request would, without the If-None-Match header field, result + in anything other than a 2xx status, then the If-None-Match header + MUST be ignored. + + The meaning of "If-None-Match: *" is that the method MUST NOT be + performed if the representation selected by the origin server (or by + a cache, possibly using the Vary mechanism, see section 14.43) + exists, and SHOULD be performed if the representation does not exist. + This feature may be useful in preventing races between PUT + operations. + + Examples: + + If-None-Match: "xyzzy" + If-None-Match: W/"xyzzy" + If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz" + If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz" + If-None-Match: * + +14.27 If-Range + + If a client has a partial copy of an entity in its cache, and wishes + to have an up-to-date copy of the entire entity in its cache, it + could use the Range request-header with a conditional GET (using + either or both of If-Unmodified-Since and If-Match.) However, if the + condition fails because the entity has been modified, the client + would then have to make a second request to obtain the entire current + entity-body. + + The If-Range header allows a client to "short-circuit" the second + request. Informally, its meaning is `if the entity is unchanged, send + me the part(s) that I am missing; otherwise, send me the entire new + entity.' + + If-Range = "If-Range" ":" ( entity-tag | HTTP-date ) + + If the client has no entity tag for an entity, but does have a Last- + Modified date, it may use that date in a If-Range header. (The server + can distinguish between a valid HTTP-date and any form of entity-tag + by examining no more than two characters.) The If-Range header should + only be used together with a Range header, and must be ignored if the + request does not include a Range header, or if the server does not + support the sub-range operation. + + + + + + + + +Fielding, et. al. Standards Track [Page 123] + +RFC 2068 HTTP/1.1 January 1997 + + + If the entity tag given in the If-Range header matches the current + entity tag for the entity, then the server should provide the + specified sub-range of the entity using a 206 (Partial content) + response. If the entity tag does not match, then the server should + return the entire entity using a 200 (OK) response. + +14.28 If-Unmodified-Since + + The If-Unmodified-Since request-header field is used with a method to + make it conditional. If the requested resource has not been modified + since the time specified in this field, the server should perform the + requested operation as if the If-Unmodified-Since header were not + present. + + If the requested variant has been modified since the specified time, + the server MUST NOT perform the requested operation, and MUST return + a 412 (Precondition Failed). + + If-Unmodified-Since = "If-Unmodified-Since" ":" HTTP-date + + An example of the field is: + + If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT + + If the request normally (i.e., without the If-Unmodified-Since + header) would result in anything other than a 2xx status, the If- + Unmodified-Since header should be ignored. + + If the specified date is invalid, the header is ignored. + +14.29 Last-Modified + + The Last-Modified entity-header field indicates the date and time at + which the origin server believes the variant was last modified. + + Last-Modified = "Last-Modified" ":" HTTP-date + + An example of its use is + + Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT + + The exact meaning of this header field depends on the implementation + of the origin server and the nature of the original resource. For + files, it may be just the file system last-modified time. For + entities with dynamically included parts, it may be the most recent + of the set of last-modify times for its component parts. For database + gateways, it may be the last-update time stamp of the record. For + virtual objects, it may be the last time the internal state changed. + + + +Fielding, et. al. Standards Track [Page 124] + +RFC 2068 HTTP/1.1 January 1997 + + + An origin server MUST NOT send a Last-Modified date which is later + than the server's time of message origination. In such cases, where + the resource's last modification would indicate some time in the + future, the server MUST replace that date with the message + origination date. + + An origin server should obtain the Last-Modified value of the entity + as close as possible to the time that it generates the Date value of + its response. This allows a recipient to make an accurate assessment + of the entity's modification time, especially if the entity changes + near the time that the response is generated. + + HTTP/1.1 servers SHOULD send Last-Modified whenever feasible. + +14.30 Location + + The Location response-header field is used to redirect the recipient + to a location other than the Request-URI for completion of the + request or identification of a new resource. For 201 (Created) + responses, the Location is that of the new resource which was created + by the request. For 3xx responses, the location SHOULD indicate the + server's preferred URL for automatic redirection to the resource. The + field value consists of a single absolute URL. + + Location = "Location" ":" absoluteURI + + An example is + + Location: http://www.w3.org/pub/WWW/People.html + + Note: The Content-Location header field (section 14.15) differs + from Location in that the Content-Location identifies the original + location of the entity enclosed in the request. It is therefore + possible for a response to contain header fields for both Location + and Content-Location. Also see section 13.10 for cache requirements + of some methods. + +14.31 Max-Forwards + + The Max-Forwards request-header field may be used with the TRACE + method (section 14.31) to limit the number of proxies or gateways + that can forward the request to the next inbound server. This can be + useful when the client is attempting to trace a request chain which + appears to be failing or looping in mid-chain. + + Max-Forwards = "Max-Forwards" ":" 1*DIGIT + + + + + +Fielding, et. al. Standards Track [Page 125] + +RFC 2068 HTTP/1.1 January 1997 + + + The Max-Forwards value is a decimal integer indicating the remaining + number of times this request message may be forwarded. + + Each proxy or gateway recipient of a TRACE request containing a Max- + Forwards header field SHOULD check and update its value prior to + forwarding the request. If the received value is zero (0), the + recipient SHOULD NOT forward the request; instead, it SHOULD respond + as the final recipient with a 200 (OK) response containing the + received request message as the response entity-body (as described in + section 9.8). If the received Max-Forwards value is greater than + zero, then the forwarded message SHOULD contain an updated Max- + Forwards field with a value decremented by one (1). + + The Max-Forwards header field SHOULD be ignored for all other methods + defined by this specification and for any extension methods for which + it is not explicitly referred to as part of that method definition. + +14.32 Pragma + + The Pragma general-header field is used to include implementation- + specific directives that may apply to any recipient along the + request/response chain. All pragma directives specify optional + behavior from the viewpoint of the protocol; however, some systems + MAY require that behavior be consistent with the directives. + + Pragma = "Pragma" ":" 1#pragma-directive + + pragma-directive = "no-cache" | extension-pragma + extension-pragma = token [ "=" ( token | quoted-string ) ] + + When the no-cache directive is present in a request message, an + application SHOULD forward the request toward the origin server even + if it has a cached copy of what is being requested. This pragma + directive has the same semantics as the no-cache cache-directive (see + section 14.9) and is defined here for backwards compatibility with + HTTP/1.0. Clients SHOULD include both header fields when a no-cache + request is sent to a server not known to be HTTP/1.1 compliant. + + Pragma directives MUST be passed through by a proxy or gateway + application, regardless of their significance to that application, + since the directives may be applicable to all recipients along the + request/response chain. It is not possible to specify a pragma for a + specific recipient; however, any pragma directive not relevant to a + recipient SHOULD be ignored by that recipient. + + + + + + + +Fielding, et. al. Standards Track [Page 126] + +RFC 2068 HTTP/1.1 January 1997 + + + HTTP/1.1 clients SHOULD NOT send the Pragma request-header. HTTP/1.1 + caches SHOULD treat "Pragma: no-cache" as if the client had sent + "Cache-Control: no-cache". No new Pragma directives will be defined + in HTTP. + +14.33 Proxy-Authenticate + + The Proxy-Authenticate response-header field MUST be included as part + of a 407 (Proxy Authentication Required) response. The field value + consists of a challenge that indicates the authentication scheme and + parameters applicable to the proxy for this Request-URI. + + Proxy-Authenticate = "Proxy-Authenticate" ":" challenge + + The HTTP access authentication process is described in section 11. + Unlike WWW-Authenticate, the Proxy-Authenticate header field applies + only to the current connection and SHOULD NOT be passed on to + downstream clients. However, an intermediate proxy may need to obtain + its own credentials by requesting them from the downstream client, + which in some circumstances will appear as if the proxy is forwarding + the Proxy-Authenticate header field. + +14.34 Proxy-Authorization + + The Proxy-Authorization request-header field allows the client to + identify itself (or its user) to a proxy which requires + authentication. The Proxy-Authorization field value consists of + credentials containing the authentication information of the user + agent for the proxy and/or realm of the resource being requested. + + Proxy-Authorization = "Proxy-Authorization" ":" credentials + + The HTTP access authentication process is described in section 11. + Unlike Authorization, the Proxy-Authorization header field applies + only to the next outbound proxy that demanded authentication using + the Proxy-Authenticate field. When multiple proxies are used in a + chain, the Proxy-Authorization header field is consumed by the first + outbound proxy that was expecting to receive credentials. A proxy MAY + relay the credentials from the client request to the next proxy if + that is the mechanism by which the proxies cooperatively authenticate + a given request. + +14.35 Public + + The Public response-header field lists the set of methods supported + by the server. The purpose of this field is strictly to inform the + recipient of the capabilities of the server regarding unusual + methods. The methods listed may or may not be applicable to the + + + +Fielding, et. al. Standards Track [Page 127] + +RFC 2068 HTTP/1.1 January 1997 + + + Request-URI; the Allow header field (section 14.7) MAY be used to + indicate methods allowed for a particular URI. + + Public = "Public" ":" 1#method + + Example of use: + + Public: OPTIONS, MGET, MHEAD, GET, HEAD + + This header field applies only to the server directly connected to + the client (i.e., the nearest neighbor in a chain of connections). If + the response passes through a proxy, the proxy MUST either remove the + Public header field or replace it with one applicable to its own + capabilities. + +14.36 Range + +14.36.1 Byte Ranges + + Since all HTTP entities are represented in HTTP messages as sequences + of bytes, the concept of a byte range is meaningful for any HTTP + entity. (However, not all clients and servers need to support byte- + range operations.) + + Byte range specifications in HTTP apply to the sequence of bytes in + the entity-body (not necessarily the same as the message-body). + + A byte range operation may specify a single range of bytes, or a set + of ranges within a single entity. + + ranges-specifier = byte-ranges-specifier + + byte-ranges-specifier = bytes-unit "=" byte-range-set + + byte-range-set = 1#( byte-range-spec | suffix-byte-range-spec ) + + byte-range-spec = first-byte-pos "-" [last-byte-pos] + + first-byte-pos = 1*DIGIT + + last-byte-pos = 1*DIGIT + + The first-byte-pos value in a byte-range-spec gives the byte-offset + of the first byte in a range. The last-byte-pos value gives the + byte-offset of the last byte in the range; that is, the byte + positions specified are inclusive. Byte offsets start at zero. + + + + + +Fielding, et. al. Standards Track [Page 128] + +RFC 2068 HTTP/1.1 January 1997 + + + If the last-byte-pos value is present, it must be greater than or + equal to the first-byte-pos in that byte-range-spec, or the byte- + range-spec is invalid. The recipient of an invalid byte-range-spec + must ignore it. + + If the last-byte-pos value is absent, or if the value is greater than + or equal to the current length of the entity-body, last-byte-pos is + taken to be equal to one less than the current length of the entity- + body in bytes. + + By its choice of last-byte-pos, a client can limit the number of + bytes retrieved without knowing the size of the entity. + + suffix-byte-range-spec = "-" suffix-length + + suffix-length = 1*DIGIT + + A suffix-byte-range-spec is used to specify the suffix of the + entity-body, of a length given by the suffix-length value. (That is, + this form specifies the last N bytes of an entity-body.) If the + entity is shorter than the specified suffix-length, the entire + entity-body is used. + + Examples of byte-ranges-specifier values (assuming an entity-body of + length 10000): + + o The first 500 bytes (byte offsets 0-499, inclusive): + + bytes=0-499 + + o The second 500 bytes (byte offsets 500-999, inclusive): + + bytes=500-999 + + o The final 500 bytes (byte offsets 9500-9999, inclusive): + + bytes=-500 + + o Or + + bytes=9500- + + o The first and last bytes only (bytes 0 and 9999): + + bytes=0-0,-1 + + + + + + +Fielding, et. al. Standards Track [Page 129] + +RFC 2068 HTTP/1.1 January 1997 + + + o Several legal but not canonical specifications of the second + 500 bytes (byte offsets 500-999, inclusive): + + bytes=500-600,601-999 + + bytes=500-700,601-999 + +14.36.2 Range Retrieval Requests + + HTTP retrieval requests using conditional or unconditional GET + methods may request one or more sub-ranges of the entity, instead of + the entire entity, using the Range request header, which applies to + the entity returned as the result of the request: + + Range = "Range" ":" ranges-specifier + + A server MAY ignore the Range header. However, HTTP/1.1 origin + servers and intermediate caches SHOULD support byte ranges when + possible, since Range supports efficient recovery from partially + failed transfers, and supports efficient partial retrieval of large + entities. + + If the server supports the Range header and the specified range or + ranges are appropriate for the entity: + + o The presence of a Range header in an unconditional GET modifies + what is returned if the GET is otherwise successful. In other + words, the response carries a status code of 206 (Partial + Content) instead of 200 (OK). + + o The presence of a Range header in a conditional GET (a request + using one or both of If-Modified-Since and If-None-Match, or + one or both of If-Unmodified-Since and If-Match) modifies what + is returned if the GET is otherwise successful and the condition + is true. It does not affect the 304 (Not Modified) response + returned if the conditional is false. + + In some cases, it may be more appropriate to use the If-Range header + (see section 14.27) in addition to the Range header. + + If a proxy that supports ranges receives a Range request, forwards + the request to an inbound server, and receives an entire entity in + reply, it SHOULD only return the requested range to its client. It + SHOULD store the entire received response in its cache, if that is + consistent with its cache allocation policies. + + + + + + +Fielding, et. al. Standards Track [Page 130] + +RFC 2068 HTTP/1.1 January 1997 + + +14.37 Referer + + The Referer[sic] request-header field allows the client to specify, + for the server's benefit, the address (URI) of the resource from + which the Request-URI was obtained (the "referrer", although the + header field is misspelled.) The Referer request-header allows a + server to generate lists of back-links to resources for interest, + logging, optimized caching, etc. It also allows obsolete or mistyped + links to be traced for maintenance. The Referer field MUST NOT be + sent if the Request-URI was obtained from a source that does not have + its own URI, such as input from the user keyboard. + + Referer = "Referer" ":" ( absoluteURI | relativeURI ) + + Example: + + Referer: http://www.w3.org/hypertext/DataSources/Overview.html + + If the field value is a partial URI, it SHOULD be interpreted + relative to the Request-URI. The URI MUST NOT include a fragment. + + Note: Because the source of a link may be private information or + may reveal an otherwise private information source, it is strongly + recommended that the user be able to select whether or not the + Referer field is sent. For example, a browser client could have a + toggle switch for browsing openly/anonymously, which would + respectively enable/disable the sending of Referer and From + information. + +14.38 Retry-After + + The Retry-After response-header field can be used with a 503 (Service + Unavailable) response to indicate how long the service is expected to + be unavailable to the requesting client. The value of this field can + be either an HTTP-date or an integer number of seconds (in decimal) + after the time of the response. + + Retry-After = "Retry-After" ":" ( HTTP-date | delta-seconds ) + + Two examples of its use are + + Retry-After: Fri, 31 Dec 1999 23:59:59 GMT + Retry-After: 120 + + In the latter example, the delay is 2 minutes. + + + + + + +Fielding, et. al. Standards Track [Page 131] + +RFC 2068 HTTP/1.1 January 1997 + + +14.39 Server + + The Server response-header field contains information about the + software used by the origin server to handle the request. The field + can contain multiple product tokens (section 3.8) and comments + identifying the server and any significant subproducts. The product + tokens are listed in order of their significance for identifying the + application. + + Server = "Server" ":" 1*( product | comment ) + + Example: + + Server: CERN/3.0 libwww/2.17 + + If the response is being forwarded through a proxy, the proxy + application MUST NOT modify the Server response-header. Instead, it + SHOULD include a Via field (as described in section 14.44). + + Note: Revealing the specific software version of the server may + allow the server machine to become more vulnerable to attacks + against software that is known to contain security holes. Server + implementers are encouraged to make this field a configurable + option. + +14.40 Transfer-Encoding + + The Transfer-Encoding general-header field indicates what (if any) + type of transformation has been applied to the message body in order + to safely transfer it between the sender and the recipient. This + differs from the Content-Encoding in that the transfer coding is a + property of the message, not of the entity. + + Transfer-Encoding = "Transfer-Encoding" ":" 1#transfer- + coding + + Transfer codings are defined in section 3.6. An example is: + + Transfer-Encoding: chunked + + Many older HTTP/1.0 applications do not understand the Transfer- + Encoding header. + +14.41 Upgrade + + The Upgrade general-header allows the client to specify what + additional communication protocols it supports and would like to use + if the server finds it appropriate to switch protocols. The server + + + +Fielding, et. al. Standards Track [Page 132] + +RFC 2068 HTTP/1.1 January 1997 + + + MUST use the Upgrade header field within a 101 (Switching Protocols) + response to indicate which protocol(s) are being switched. + + Upgrade = "Upgrade" ":" 1#product + + For example, + + Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 + + The Upgrade header field is intended to provide a simple mechanism + for transition from HTTP/1.1 to some other, incompatible protocol. It + does so by allowing the client to advertise its desire to use another + protocol, such as a later version of HTTP with a higher major version + number, even though the current request has been made using HTTP/1.1. + This eases the difficult transition between incompatible protocols by + allowing the client to initiate a request in the more commonly + supported protocol while indicating to the server that it would like + to use a "better" protocol if available (where "better" is determined + by the server, possibly according to the nature of the method and/or + resource being requested). + + The Upgrade header field only applies to switching application-layer + protocols upon the existing transport-layer connection. Upgrade + cannot be used to insist on a protocol change; its acceptance and use + by the server is optional. The capabilities and nature of the + application-layer communication after the protocol change is entirely + dependent upon the new protocol chosen, although the first action + after changing the protocol MUST be a response to the initial HTTP + request containing the Upgrade header field. + + The Upgrade header field only applies to the immediate connection. + Therefore, the upgrade keyword MUST be supplied within a Connection + header field (section 14.10) whenever Upgrade is present in an + HTTP/1.1 message. + + The Upgrade header field cannot be used to indicate a switch to a + protocol on a different connection. For that purpose, it is more + appropriate to use a 301, 302, 303, or 305 redirection response. + + This specification only defines the protocol name "HTTP" for use by + the family of Hypertext Transfer Protocols, as defined by the HTTP + version rules of section 3.1 and future updates to this + specification. Any token can be used as a protocol name; however, it + will only be useful if both the client and server associate the name + with the same protocol. + + + + + + +Fielding, et. al. Standards Track [Page 133] + +RFC 2068 HTTP/1.1 January 1997 + + +14.42 User-Agent + + The User-Agent request-header field contains information about the + user agent originating the request. This is for statistical purposes, + the tracing of protocol violations, and automated recognition of user + agents for the sake of tailoring responses to avoid particular user + agent limitations. User agents SHOULD include this field with + requests. The field can contain multiple product tokens (section 3.8) + and comments identifying the agent and any subproducts which form a + significant part of the user agent. By convention, the product tokens + are listed in order of their significance for identifying the + application. + + User-Agent = "User-Agent" ":" 1*( product | comment ) + + Example: + + User-Agent: CERN-LineMode/2.15 libwww/2.17b3 + +14.43 Vary + + The Vary response-header field is used by a server to signal that the + response entity was selected from the available representations of + the response using server-driven negotiation (section 12). Field- + names listed in Vary headers are those of request-headers. The Vary + field value indicates either that the given set of header fields + encompass the dimensions over which the representation might vary, or + that the dimensions of variance are unspecified ("*") and thus may + vary over any aspect of future requests. + + Vary = "Vary" ":" ( "*" | 1#field-name ) + + An HTTP/1.1 server MUST include an appropriate Vary header field with + any cachable response that is subject to server-driven negotiation. + Doing so allows a cache to properly interpret future requests on that + resource and informs the user agent about the presence of negotiation + on that resource. A server SHOULD include an appropriate Vary header + field with a non-cachable response that is subject to server-driven + negotiation, since this might provide the user agent with useful + information about the dimensions over which the response might vary. + + The set of header fields named by the Vary field value is known as + the "selecting" request-headers. + + When the cache receives a subsequent request whose Request-URI + specifies one or more cache entries including a Vary header, the + cache MUST NOT use such a cache entry to construct a response to the + new request unless all of the headers named in the cached Vary header + + + +Fielding, et. al. Standards Track [Page 134] + +RFC 2068 HTTP/1.1 January 1997 + + + are present in the new request, and all of the stored selecting + request-headers from the previous request match the corresponding + headers in the new request. + + The selecting request-headers from two requests are defined to match + if and only if the selecting request-headers in the first request can + be transformed to the selecting request-headers in the second request + by adding or removing linear whitespace (LWS) at places where this is + allowed by the corresponding BNF, and/or combining multiple message- + header fields with the same field name following the rules about + message headers in section 4.2. + + A Vary field value of "*" signals that unspecified parameters, + possibly other than the contents of request-header fields (e.g., the + network address of the client), play a role in the selection of the + response representation. Subsequent requests on that resource can + only be properly interpreted by the origin server, and thus a cache + MUST forward a (possibly conditional) request even when it has a + fresh response cached for the resource. See section 13.6 for use of + the Vary header by caches. + + A Vary field value consisting of a list of field-names signals that + the representation selected for the response is based on a selection + algorithm which considers ONLY the listed request-header field values + in selecting the most appropriate representation. A cache MAY assume + that the same selection will be made for future requests with the + same values for the listed field names, for the duration of time in + which the response is fresh. + + The field-names given are not limited to the set of standard + request-header fields defined by this specification. Field names are + case-insensitive. + +14.44 Via + + The Via general-header field MUST be used by gateways and proxies to + indicate the intermediate protocols and recipients between the user + agent and the server on requests, and between the origin server and + the client on responses. It is analogous to the "Received" field of + RFC 822 and is intended to be used for tracking message forwards, + avoiding request loops, and identifying the protocol capabilities of + all senders along the request/response chain. + + + + + + + + + +Fielding, et. al. Standards Track [Page 135] + +RFC 2068 HTTP/1.1 January 1997 + + + Via = "Via" ":" 1#( received-protocol received-by [ comment ] ) + + received-protocol = [ protocol-name "/" ] protocol-version + protocol-name = token + protocol-version = token + received-by = ( host [ ":" port ] ) | pseudonym + pseudonym = token + + The received-protocol indicates the protocol version of the message + received by the server or client along each segment of the + request/response chain. The received-protocol version is appended to + the Via field value when the message is forwarded so that information + about the protocol capabilities of upstream applications remains + visible to all recipients. + + The protocol-name is optional if and only if it would be "HTTP". The + received-by field is normally the host and optional port number of a + recipient server or client that subsequently forwarded the message. + However, if the real host is considered to be sensitive information, + it MAY be replaced by a pseudonym. If the port is not given, it MAY + be assumed to be the default port of the received-protocol. + + Multiple Via field values represent each proxy or gateway that has + forwarded the message. Each recipient MUST append its information + such that the end result is ordered according to the sequence of + forwarding applications. + + Comments MAY be used in the Via header field to identify the software + of the recipient proxy or gateway, analogous to the User-Agent and + Server header fields. However, all comments in the Via field are + optional and MAY be removed by any recipient prior to forwarding the + message. + + For example, a request message could be sent from an HTTP/1.0 user + agent to an internal proxy code-named "fred", which uses HTTP/1.1 to + forward the request to a public proxy at nowhere.com, which completes + the request by forwarding it to the origin server at www.ics.uci.edu. + The request received by www.ics.uci.edu would then have the following + Via header field: + + Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) + + Proxies and gateways used as a portal through a network firewall + SHOULD NOT, by default, forward the names and ports of hosts within + the firewall region. This information SHOULD only be propagated if + explicitly enabled. If not enabled, the received-by host of any host + behind the firewall SHOULD be replaced by an appropriate pseudonym + for that host. + + + +Fielding, et. al. Standards Track [Page 136] + +RFC 2068 HTTP/1.1 January 1997 + + + For organizations that have strong privacy requirements for hiding + internal structures, a proxy MAY combine an ordered subsequence of + Via header field entries with identical received-protocol values into + a single such entry. For example, + + Via: 1.0 ricky, 1.1 ethel, 1.1 fred, 1.0 lucy + + could be collapsed to + + Via: 1.0 ricky, 1.1 mertz, 1.0 lucy + + Applications SHOULD NOT combine multiple entries unless they are all + under the same organizational control and the hosts have already been + replaced by pseudonyms. Applications MUST NOT combine entries which + have different received-protocol values. + +14.45 Warning + + The Warning response-header field is used to carry additional + information about the status of a response which may not be reflected + by the response status code. This information is typically, though + not exclusively, used to warn about a possible lack of semantic + transparency from caching operations. + + Warning headers are sent with responses using: + + Warning = "Warning" ":" 1#warning-value + + warning-value = warn-code SP warn-agent SP warn-text + warn-code = 2DIGIT + warn-agent = ( host [ ":" port ] ) | pseudonym + ; the name or pseudonym of the server adding + ; the Warning header, for use in debugging + warn-text = quoted-string + + A response may carry more than one Warning header. + + The warn-text should be in a natural language and character set that + is most likely to be intelligible to the human user receiving the + response. This decision may be based on any available knowledge, + such as the location of the cache or user, the Accept-Language field + in a request, the Content-Language field in a response, etc. The + default language is English and the default character set is ISO- + 8859-1. + + If a character set other than ISO-8859-1 is used, it MUST be encoded + in the warn-text using the method described in RFC 1522 [14]. + + + + +Fielding, et. al. Standards Track [Page 137] + +RFC 2068 HTTP/1.1 January 1997 + + + Any server or cache may add Warning headers to a response. New + Warning headers should be added after any existing Warning headers. A + cache MUST NOT delete any Warning header that it received with a + response. However, if a cache successfully validates a cache entry, + it SHOULD remove any Warning headers previously attached to that + entry except as specified for specific Warning codes. It MUST then + add any Warning headers received in the validating response. In other + words, Warning headers are those that would be attached to the most + recent relevant response. + + When multiple Warning headers are attached to a response, the user + agent SHOULD display as many of them as possible, in the order that + they appear in the response. If it is not possible to display all of + the warnings, the user agent should follow these heuristics: + + o Warnings that appear early in the response take priority over those + appearing later in the response. + o Warnings in the user's preferred character set take priority over + warnings in other character sets but with identical warn-codes and + warn-agents. + + Systems that generate multiple Warning headers should order them with + this user agent behavior in mind. + + This is a list of the currently-defined warn-codes, each with a + recommended warn-text in English, and a description of its meaning. + +10 Response is stale + MUST be included whenever the returned response is stale. A cache may + add this warning to any response, but may never remove it until the + response is known to be fresh. + +11 Revalidation failed + MUST be included if a cache returns a stale response because an + attempt to revalidate the response failed, due to an inability to + reach the server. A cache may add this warning to any response, but + may never remove it until the response is successfully revalidated. + +12 Disconnected operation + SHOULD be included if the cache is intentionally disconnected from + the rest of the network for a period of time. + +13 Heuristic expiration + MUST be included if the cache heuristically chose a freshness + lifetime greater than 24 hours and the response's age is greater than + 24 hours. + + + + + +Fielding, et. al. Standards Track [Page 138] + +RFC 2068 HTTP/1.1 January 1997 + + +14 Transformation applied + MUST be added by an intermediate cache or proxy if it applies any + transformation changing the content-coding (as specified in the + Content-Encoding header) or media-type (as specified in the + Content-Type header) of the response, unless this Warning code + already appears in the response. MUST NOT be deleted from a response + even after revalidation. + +99 Miscellaneous warning + The warning text may include arbitrary information to be presented to + a human user, or logged. A system receiving this warning MUST NOT + take any automated action. + +14.46 WWW-Authenticate + + The WWW-Authenticate response-header field MUST be included in 401 + (Unauthorized) response messages. The field value consists of at + least one challenge that indicates the authentication scheme(s) and + parameters applicable to the Request-URI. + + WWW-Authenticate = "WWW-Authenticate" ":" 1#challenge + + The HTTP access authentication process is described in section 11. + User agents MUST take special care in parsing the WWW-Authenticate + field value if it contains more than one challenge, or if more than + one WWW-Authenticate header field is provided, since the contents of + a challenge may itself contain a comma-separated list of + authentication parameters. + +15 Security Considerations + + This section is meant to inform application developers, information + providers, and users of the security limitations in HTTP/1.1 as + described by this document. The discussion does not include + definitive solutions to the problems revealed, though it does make + some suggestions for reducing security risks. + +15.1 Authentication of Clients + + The Basic authentication scheme is not a secure method of user + authentication, nor does it in any way protect the entity, which is + transmitted in clear text across the physical network used as the + carrier. HTTP does not prevent additional authentication schemes and + encryption mechanisms from being employed to increase security or the + addition of enhancements (such as schemes to use one-time passwords) + to Basic authentication. + + + + + +Fielding, et. al. Standards Track [Page 139] + +RFC 2068 HTTP/1.1 January 1997 + + + The most serious flaw in Basic authentication is that it results in + the essentially clear text transmission of the user's password over + the physical network. It is this problem which Digest Authentication + attempts to address. + + Because Basic authentication involves the clear text transmission of + passwords it SHOULD never be used (without enhancements) to protect + sensitive or valuable information. + + A common use of Basic authentication is for identification purposes + -- requiring the user to provide a user name and password as a means + of identification, for example, for purposes of gathering accurate + usage statistics on a server. When used in this way it is tempting to + think that there is no danger in its use if illicit access to the + protected documents is not a major concern. This is only correct if + the server issues both user name and password to the users and in + particular does not allow the user to choose his or her own password. + The danger arises because naive users frequently reuse a single + password to avoid the task of maintaining multiple passwords. + + If a server permits users to select their own passwords, then the + threat is not only illicit access to documents on the server but also + illicit access to the accounts of all users who have chosen to use + their account password. If users are allowed to choose their own + password that also means the server must maintain files containing + the (presumably encrypted) passwords. Many of these may be the + account passwords of users perhaps at distant sites. The owner or + administrator of such a system could conceivably incur liability if + this information is not maintained in a secure fashion. + + Basic Authentication is also vulnerable to spoofing by counterfeit + servers. If a user can be led to believe that he is connecting to a + host containing information protected by basic authentication when in + fact he is connecting to a hostile server or gateway then the + attacker can request a password, store it for later use, and feign an + error. This type of attack is not possible with Digest Authentication + [32]. Server implementers SHOULD guard against the possibility of + this sort of counterfeiting by gateways or CGI scripts. In particular + it is very dangerous for a server to simply turn over a connection to + a gateway since that gateway can then use the persistent connection + mechanism to engage in multiple transactions with the client while + impersonating the original server in a way that is not detectable by + the client. + +15.2 Offering a Choice of Authentication Schemes + + An HTTP/1.1 server may return multiple challenges with a 401 + (Authenticate) response, and each challenge may use a different + + + +Fielding, et. al. Standards Track [Page 140] + +RFC 2068 HTTP/1.1 January 1997 + + + scheme. The order of the challenges returned to the user agent is in + the order that the server would prefer they be chosen. The server + should order its challenges with the "most secure" authentication + scheme first. A user agent should choose as the challenge to be made + to the user the first one that the user agent understands. + + When the server offers choices of authentication schemes using the + WWW-Authenticate header, the "security" of the authentication is only + as malicious user could capture the set of challenges and try to + authenticate him/herself using the weakest of the authentication + schemes. Thus, the ordering serves more to protect the user's + credentials than the server's information. + + A possible man-in-the-middle (MITM) attack would be to add a weak + authentication scheme to the set of choices, hoping that the client + will use one that exposes the user's credentials (e.g. password). For + this reason, the client should always use the strongest scheme that + it understands from the choices accepted. + + An even better MITM attack would be to remove all offered choices, + and to insert a challenge that requests Basic authentication. For + this reason, user agents that are concerned about this kind of attack + could remember the strongest authentication scheme ever requested by + a server and produce a warning message that requires user + confirmation before using a weaker one. A particularly insidious way + to mount such a MITM attack would be to offer a "free" proxy caching + service to gullible users. + +15.3 Abuse of Server Log Information + + A server is in the position to save personal data about a user's + requests which may identify their reading patterns or subjects of + interest. This information is clearly confidential in nature and its + handling may be constrained by law in certain countries. People using + the HTTP protocol to provide data are responsible for ensuring that + such material is not distributed without the permission of any + individuals that are identifiable by the published results. + +15.4 Transfer of Sensitive Information + + Like any generic data transfer protocol, HTTP cannot regulate the + content of the data that is transferred, nor is there any a priori + method of determining the sensitivity of any particular piece of + information within the context of any given request. Therefore, + applications SHOULD supply as much control over this information as + possible to the provider of that information. Four header fields are + worth special mention in this context: Server, Via, Referer and From. + + + + +Fielding, et. al. Standards Track [Page 141] + +RFC 2068 HTTP/1.1 January 1997 + + + Revealing the specific software version of the server may allow the + server machine to become more vulnerable to attacks against software + that is known to contain security holes. Implementers SHOULD make the + Server header field a configurable option. + + Proxies which serve as a portal through a network firewall SHOULD + take special precautions regarding the transfer of header information + that identifies the hosts behind the firewall. In particular, they + SHOULD remove, or replace with sanitized versions, any Via fields + generated behind the firewall. + + The Referer field allows reading patterns to be studied and reverse + links drawn. Although it can be very useful, its power can be abused + if user details are not separated from the information contained in + the Referer. Even when the personal information has been removed, the + Referer field may indicate a private document's URI whose publication + would be inappropriate. + + The information sent in the From field might conflict with the user's + privacy interests or their site's security policy, and hence it + SHOULD NOT be transmitted without the user being able to disable, + enable, and modify the contents of the field. The user MUST be able + to set the contents of this field within a user preference or + application defaults configuration. + + We suggest, though do not require, that a convenient toggle interface + be provided for the user to enable or disable the sending of From and + Referer information. + +15.5 Attacks Based On File and Path Names + + Implementations of HTTP origin servers SHOULD be careful to restrict + the documents returned by HTTP requests to be only those that were + intended by the server administrators. If an HTTP server translates + HTTP URIs directly into file system calls, the server MUST take + special care not to serve files that were not intended to be + delivered to HTTP clients. For example, UNIX, Microsoft Windows, and + other operating systems use ".." as a path component to indicate a + directory level above the current one. On such a system, an HTTP + server MUST disallow any such construct in the Request-URI if it + would otherwise allow access to a resource outside those intended to + be accessible via the HTTP server. Similarly, files intended for + reference only internally to the server (such as access control + files, configuration files, and script code) MUST be protected from + inappropriate retrieval, since they might contain sensitive + information. Experience has shown that minor bugs in such HTTP server + implementations have turned into security risks. + + + + +Fielding, et. al. Standards Track [Page 142] + +RFC 2068 HTTP/1.1 January 1997 + + +15.6 Personal Information + + HTTP clients are often privy to large amounts of personal information + (e.g. the user's name, location, mail address, passwords, encryption + keys, etc.), and SHOULD be very careful to prevent unintentional + leakage of this information via the HTTP protocol to other sources. + We very strongly recommend that a convenient interface be provided + for the user to control dissemination of such information, and that + designers and implementers be particularly careful in this area. + History shows that errors in this area are often both serious + security and/or privacy problems, and often generate highly adverse + publicity for the implementer's company. + +15.7 Privacy Issues Connected to Accept Headers + + Accept request-headers can reveal information about the user to all + servers which are accessed. The Accept-Language header in particular + can reveal information the user would consider to be of a private + nature, because the understanding of particular languages is often + strongly correlated to the membership of a particular ethnic group. + User agents which offer the option to configure the contents of an + Accept-Language header to be sent in every request are strongly + encouraged to let the configuration process include a message which + makes the user aware of the loss of privacy involved. + + An approach that limits the loss of privacy would be for a user agent + to omit the sending of Accept-Language headers by default, and to ask + the user whether it should start sending Accept-Language headers to a + server if it detects, by looking for any Vary response-header fields + generated by the server, that such sending could improve the quality + of service. + + Elaborate user-customized accept header fields sent in every request, + in particular if these include quality values, can be used by servers + as relatively reliable and long-lived user identifiers. Such user + identifiers would allow content providers to do click-trail tracking, + and would allow collaborating content providers to match cross-server + click-trails or form submissions of individual users. Note that for + many users not behind a proxy, the network address of the host + running the user agent will also serve as a long-lived user + identifier. In environments where proxies are used to enhance + privacy, user agents should be conservative in offering accept header + configuration options to end users. As an extreme privacy measure, + proxies could filter the accept headers in relayed requests. General + purpose user agents which provide a high degree of header + configurability should warn users about the loss of privacy which can + be involved. + + + + +Fielding, et. al. Standards Track [Page 143] + +RFC 2068 HTTP/1.1 January 1997 + + +15.8 DNS Spoofing + + Clients using HTTP rely heavily on the Domain Name Service, and are + thus generally prone to security attacks based on the deliberate + mis-association of IP addresses and DNS names. Clients need to be + cautious in assuming the continuing validity of an IP number/DNS name + association. + + In particular, HTTP clients SHOULD rely on their name resolver for + confirmation of an IP number/DNS name association, rather than + caching the result of previous host name lookups. Many platforms + already can cache host name lookups locally when appropriate, and + they SHOULD be configured to do so. These lookups should be cached, + however, only when the TTL (Time To Live) information reported by the + name server makes it likely that the cached information will remain + useful. + + If HTTP clients cache the results of host name lookups in order to + achieve a performance improvement, they MUST observe the TTL + information reported by DNS. + + If HTTP clients do not observe this rule, they could be spoofed when + a previously-accessed server's IP address changes. As network + renumbering is expected to become increasingly common, the + possibility of this form of attack will grow. Observing this + requirement thus reduces this potential security vulnerability. + + This requirement also improves the load-balancing behavior of clients + for replicated servers using the same DNS name and reduces the + likelihood of a user's experiencing failure in accessing sites which + use that strategy. + +15.9 Location Headers and Spoofing + + If a single server supports multiple organizations that do not trust + one another, then it must check the values of Location and Content- + Location headers in responses that are generated under control of + said organizations to make sure that they do not attempt to + invalidate resources over which they have no authority. + +16 Acknowledgments + + This specification makes heavy use of the augmented BNF and generic + constructs defined by David H. Crocker for RFC 822. Similarly, it + reuses many of the definitions provided by Nathaniel Borenstein and + Ned Freed for MIME. We hope that their inclusion in this + specification will help reduce past confusion over the relationship + between HTTP and Internet mail message formats. + + + +Fielding, et. al. Standards Track [Page 144] + +RFC 2068 HTTP/1.1 January 1997 + + + The HTTP protocol has evolved considerably over the past four years. + It has benefited from a large and active developer community--the + many people who have participated on the www-talk mailing list--and + it is that community which has been most responsible for the success + of HTTP and of the World-Wide Web in general. Marc Andreessen, Robert + Cailliau, Daniel W. Connolly, Bob Denny, John Franks, Jean-Francois + Groff, Phillip M. Hallam-Baker, Hakon W. Lie, Ari Luotonen, Rob + McCool, Lou Montulli, Dave Raggett, Tony Sanders, and Marc + VanHeyningen deserve special recognition for their efforts in + defining early aspects of the protocol. + + This document has benefited greatly from the comments of all those + participating in the HTTP-WG. In addition to those already mentioned, + the following individuals have contributed to this specification: + + Gary Adams Albert Lunde + Harald Tveit Alvestrand John C. Mallery + Keith Ball Jean-Philippe Martin-Flatin + Brian Behlendorf Larry Masinter + Paul Burchard Mitra + Maurizio Codogno David Morris + Mike Cowlishaw Gavin Nicol + Roman Czyborra Bill Perry + Michael A. Dolan Jeffrey Perry + David J. Fiander Scott Powers + Alan Freier Owen Rees + Marc Hedlund Luigi Rizzo + Greg Herlihy David Robinson + Koen Holtman Marc Salomon + Alex Hopmann Rich Salz + Bob Jernigan Allan M. Schiffman + Shel Kaphan Jim Seidman + Rohit Khare Chuck Shotton + John Klensin Eric W. Sink + Martijn Koster Simon E. Spero + Alexei Kosut Richard N. Taylor + David M. Kristol Robert S. Thau + Daniel LaLiberte Bill (BearHeart) Weinman + Ben Laurie Francois Yergeau + Paul J. Leach Mary Ellen Zurko + Daniel DuBois + + Much of the content and presentation of the caching design is due to + suggestions and comments from individuals including: Shel Kaphan, + Paul Leach, Koen Holtman, David Morris, and Larry Masinter. + + + + + + +Fielding, et. al. Standards Track [Page 145] + +RFC 2068 HTTP/1.1 January 1997 + + + Most of the specification of ranges is based on work originally done + by Ari Luotonen and John Franks, with additional input from Steve + Zilles. + + Thanks to the "cave men" of Palo Alto. You know who you are. + + Jim Gettys (the current editor of this document) wishes particularly + to thank Roy Fielding, the previous editor of this document, along + with John Klensin, Jeff Mogul, Paul Leach, Dave Kristol, Koen + Holtman, John Franks, Alex Hopmann, and Larry Masinter for their + help. + +17 References + + [1] Alvestrand, H., "Tags for the identification of languages", RFC + 1766, UNINETT, March 1995. + + [2] Anklesaria, F., McCahill, M., Lindner, P., Johnson, D., Torrey, + D., and B. Alberti. "The Internet Gopher Protocol: (a distributed + document search and retrieval protocol)", RFC 1436, University of + Minnesota, March 1993. + + [3] Berners-Lee, T., "Universal Resource Identifiers in WWW", A + Unifying Syntax for the Expression of Names and Addresses of Objects + on the Network as used in the World-Wide Web", RFC 1630, CERN, June + 1994. + + [4] Berners-Lee, T., Masinter, L., and M. McCahill, "Uniform Resource + Locators (URL)", RFC 1738, CERN, Xerox PARC, University of Minnesota, + December 1994. + + [5] Berners-Lee, T., and D. Connolly, "HyperText Markup Language + Specification - 2.0", RFC 1866, MIT/LCS, November 1995. + + [6] Berners-Lee, T., Fielding, R., and H. Frystyk, "Hypertext + Transfer Protocol -- HTTP/1.0.", RFC 1945 MIT/LCS, UC Irvine, May + 1996. + + [7] Freed, N., and N. Borenstein, "Multipurpose Internet Mail + Extensions (MIME) Part One: Format of Internet Message Bodies", RFC + 2045, Innosoft, First Virtual, November 1996. + + [8] Braden, R., "Requirements for Internet hosts - application and + support", STD 3, RFC 1123, IETF, October 1989. + + [9] Crocker, D., "Standard for the Format of ARPA Internet Text + Messages", STD 11, RFC 822, UDEL, August 1982. + + + + +Fielding, et. al. Standards Track [Page 146] + +RFC 2068 HTTP/1.1 January 1997 + + + [10] Davis, F., Kahle, B., Morris, H., Salem, J., Shen, T., Wang, R., + Sui, J., and M. Grinbaum. "WAIS Interface Protocol Prototype + Functional Specification", (v1.5), Thinking Machines Corporation, + April 1990. + + [11] Fielding, R., "Relative Uniform Resource Locators", RFC 1808, UC + Irvine, June 1995. + + [12] Horton, M., and R. Adams. "Standard for interchange of USENET + messages", RFC 1036, AT&T Bell Laboratories, Center for Seismic + Studies, December 1987. + + [13] Kantor, B., and P. Lapsley. "Network News Transfer Protocol." A + Proposed Standard for the Stream-Based Transmission of News", RFC + 977, UC San Diego, UC Berkeley, February 1986. + + [14] Moore, K., "MIME (Multipurpose Internet Mail Extensions) Part + Three: Message Header Extensions for Non-ASCII Text", RFC 2047, + University of Tennessee, November 1996. + + [15] Nebel, E., and L. Masinter. "Form-based File Upload in HTML", + RFC 1867, Xerox Corporation, November 1995. + + [16] Postel, J., "Simple Mail Transfer Protocol", STD 10, RFC 821, + USC/ISI, August 1982. + + [17] Postel, J., "Media Type Registration Procedure", RFC 2048, + USC/ISI, November 1996. + + [18] Postel, J., and J. Reynolds, "File Transfer Protocol (FTP)", STD + 9, RFC 959, USC/ISI, October 1985. + + [19] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC + 1700, USC/ISI, October 1994. + + [20] Sollins, K., and L. Masinter, "Functional Requirements for + Uniform Resource Names", RFC 1737, MIT/LCS, Xerox Corporation, + December 1994. + + [21] US-ASCII. Coded Character Set - 7-Bit American Standard Code for + Information Interchange. Standard ANSI X3.4-1986, ANSI, 1986. + + [22] ISO-8859. International Standard -- Information Processing -- + 8-bit Single-Byte Coded Graphic Character Sets -- + Part 1: Latin alphabet No. 1, ISO 8859-1:1987. + Part 2: Latin alphabet No. 2, ISO 8859-2, 1987. + Part 3: Latin alphabet No. 3, ISO 8859-3, 1988. + Part 4: Latin alphabet No. 4, ISO 8859-4, 1988. + + + +Fielding, et. al. Standards Track [Page 147] + +RFC 2068 HTTP/1.1 January 1997 + + + Part 5: Latin/Cyrillic alphabet, ISO 8859-5, 1988. + Part 6: Latin/Arabic alphabet, ISO 8859-6, 1987. + Part 7: Latin/Greek alphabet, ISO 8859-7, 1987. + Part 8: Latin/Hebrew alphabet, ISO 8859-8, 1988. + Part 9: Latin alphabet No. 5, ISO 8859-9, 1990. + + [23] Meyers, J., and M. Rose "The Content-MD5 Header Field", RFC + 1864, Carnegie Mellon, Dover Beach Consulting, October, 1995. + + [24] Carpenter, B., and Y. Rekhter, "Renumbering Needs Work", RFC + 1900, IAB, February 1996. + + [25] Deutsch, P., "GZIP file format specification version 4.3." RFC + 1952, Aladdin Enterprises, May 1996. + + [26] Venkata N. Padmanabhan and Jeffrey C. Mogul. Improving HTTP + Latency. Computer Networks and ISDN Systems, v. 28, pp. 25-35, Dec. + 1995. Slightly revised version of paper in Proc. 2nd International + WWW Conf. '94: Mosaic and the Web, Oct. 1994, which is available at + http://www.ncsa.uiuc.edu/SDG/IT94/Proceedings/DDay/mogul/ + HTTPLatency.html. + + [27] Joe Touch, John Heidemann, and Katia Obraczka, "Analysis of HTTP + Performance", , + USC/Information Sciences Institute, June 1996 + + [28] Mills, D., "Network Time Protocol, Version 3, Specification, + Implementation and Analysis", RFC 1305, University of Delaware, March + 1992. + + [29] Deutsch, P., "DEFLATE Compressed Data Format Specification + version 1.3." RFC 1951, Aladdin Enterprises, May 1996. + + [30] Spero, S., "Analysis of HTTP Performance Problems" + . + + [31] Deutsch, P., and J-L. Gailly, "ZLIB Compressed Data Format + Specification version 3.3", RFC 1950, Aladdin Enterprises, Info-ZIP, + May 1996. + + [32] Franks, J., Hallam-Baker, P., Hostetler, J., Leach, P., + Luotonen, A., Sink, E., and L. Stewart, "An Extension to HTTP : + Digest Access Authentication", RFC 2069, January 1997. + + + + + + + + +Fielding, et. al. Standards Track [Page 148] + +RFC 2068 HTTP/1.1 January 1997 + + +18 Authors' Addresses + + Roy T. Fielding + Department of Information and Computer Science + University of California + Irvine, CA 92717-3425, USA + + Fax: +1 (714) 824-4056 + EMail: fielding@ics.uci.edu + + + Jim Gettys + MIT Laboratory for Computer Science + 545 Technology Square + Cambridge, MA 02139, USA + + Fax: +1 (617) 258 8682 + EMail: jg@w3.org + + + Jeffrey C. Mogul + Western Research Laboratory + Digital Equipment Corporation + 250 University Avenue + Palo Alto, California, 94305, USA + + EMail: mogul@wrl.dec.com + + + Henrik Frystyk Nielsen + W3 Consortium + MIT Laboratory for Computer Science + 545 Technology Square + Cambridge, MA 02139, USA + + Fax: +1 (617) 258 8682 + EMail: frystyk@w3.org + + + Tim Berners-Lee + Director, W3 Consortium + MIT Laboratory for Computer Science + 545 Technology Square + Cambridge, MA 02139, USA + + Fax: +1 (617) 258 8682 + EMail: timbl@w3.org + + + + +Fielding, et. al. Standards Track [Page 149] + +RFC 2068 HTTP/1.1 January 1997 + + +19 Appendices + +19.1 Internet Media Type message/http + + In addition to defining the HTTP/1.1 protocol, this document serves + as the specification for the Internet media type "message/http". The + following is to be registered with IANA. + + Media Type name: message + Media subtype name: http + Required parameters: none + Optional parameters: version, msgtype + + version: The HTTP-Version number of the enclosed message + (e.g., "1.1"). If not present, the version can be + determined from the first line of the body. + + msgtype: The message type -- "request" or "response". If not + present, the type can be determined from the first + line of the body. + + Encoding considerations: only "7bit", "8bit", or "binary" are + permitted + + Security considerations: none + +19.2 Internet Media Type multipart/byteranges + + When an HTTP message includes the content of multiple ranges (for + example, a response to a request for multiple non-overlapping + ranges), these are transmitted as a multipart MIME message. The + multipart media type for this purpose is called + "multipart/byteranges". + + The multipart/byteranges media type includes two or more parts, each + with its own Content-Type and Content-Range fields. The parts are + separated using a MIME boundary parameter. + + Media Type name: multipart + Media subtype name: byteranges + Required parameters: boundary + Optional parameters: none + + Encoding considerations: only "7bit", "8bit", or "binary" are + permitted + + Security considerations: none + + + + +Fielding, et. al. Standards Track [Page 150] + +RFC 2068 HTTP/1.1 January 1997 + + +For example: + + HTTP/1.1 206 Partial content + Date: Wed, 15 Nov 1995 06:25:24 GMT + Last-modified: Wed, 15 Nov 1995 04:58:08 GMT + Content-type: multipart/byteranges; boundary=THIS_STRING_SEPARATES + + --THIS_STRING_SEPARATES + Content-type: application/pdf + Content-range: bytes 500-999/8000 + + ...the first range... + --THIS_STRING_SEPARATES + Content-type: application/pdf + Content-range: bytes 7000-7999/8000 + + ...the second range + --THIS_STRING_SEPARATES-- + +19.3 Tolerant Applications + + Although this document specifies the requirements for the generation + of HTTP/1.1 messages, not all applications will be correct in their + implementation. We therefore recommend that operational applications + be tolerant of deviations whenever those deviations can be + interpreted unambiguously. + + Clients SHOULD be tolerant in parsing the Status-Line and servers + tolerant when parsing the Request-Line. In particular, they SHOULD + accept any amount of SP or HT characters between fields, even though + only a single SP is required. + + The line terminator for message-header fields is the sequence CRLF. + However, we recommend that applications, when parsing such headers, + recognize a single LF as a line terminator and ignore the leading CR. + + The character set of an entity-body should be labeled as the lowest + common denominator of the character codes used within that body, with + the exception that no label is preferred over the labels US-ASCII or + ISO-8859-1. + + Additional rules for requirements on parsing and encoding of dates + and other potential problems with date encodings include: + + o HTTP/1.1 clients and caches should assume that an RFC-850 date + which appears to be more than 50 years in the future is in fact + in the past (this helps solve the "year 2000" problem). + + + + +Fielding, et. al. Standards Track [Page 151] + +RFC 2068 HTTP/1.1 January 1997 + + + o An HTTP/1.1 implementation may internally represent a parsed + Expires date as earlier than the proper value, but MUST NOT + internally represent a parsed Expires date as later than the + proper value. + + o All expiration-related calculations must be done in GMT. The + local time zone MUST NOT influence the calculation or comparison + of an age or expiration time. + + o If an HTTP header incorrectly carries a date value with a time + zone other than GMT, it must be converted into GMT using the most + conservative possible conversion. + +19.4 Differences Between HTTP Entities and MIME Entities + + HTTP/1.1 uses many of the constructs defined for Internet Mail (RFC + 822) and the Multipurpose Internet Mail Extensions (MIME ) to allow + entities to be transmitted in an open variety of representations and + with extensible mechanisms. However, MIME [7] discusses mail, and + HTTP has a few features that are different from those described in + MIME. These differences were carefully chosen to optimize + performance over binary connections, to allow greater freedom in the + use of new media types, to make date comparisons easier, and to + acknowledge the practice of some early HTTP servers and clients. + + This appendix describes specific areas where HTTP differs from MIME. + Proxies and gateways to strict MIME environments SHOULD be aware of + these differences and provide the appropriate conversions where + necessary. Proxies and gateways from MIME environments to HTTP also + need to be aware of the differences because some conversions may be + required. + +19.4.1 Conversion to Canonical Form + + MIME requires that an Internet mail entity be converted to canonical + form prior to being transferred. Section 3.7.1 of this document + describes the forms allowed for subtypes of the "text" media type + when transmitted over HTTP. MIME requires that content with a type of + "text" represent line breaks as CRLF and forbids the use of CR or LF + outside of line break sequences. HTTP allows CRLF, bare CR, and bare + LF to indicate a line break within text content when a message is + transmitted over HTTP. + + Where it is possible, a proxy or gateway from HTTP to a strict MIME + environment SHOULD translate all line breaks within the text media + types described in section 3.7.1 of this document to the MIME + canonical form of CRLF. Note, however, that this may be complicated + by the presence of a Content-Encoding and by the fact that HTTP + + + +Fielding, et. al. Standards Track [Page 152] + +RFC 2068 HTTP/1.1 January 1997 + + + allows the use of some character sets which do not use octets 13 and + 10 to represent CR and LF, as is the case for some multi-byte + character sets. + +19.4.2 Conversion of Date Formats + + HTTP/1.1 uses a restricted set of date formats (section 3.3.1) to + simplify the process of date comparison. Proxies and gateways from + other protocols SHOULD ensure that any Date header field present in a + message conforms to one of the HTTP/1.1 formats and rewrite the date + if necessary. + +19.4.3 Introduction of Content-Encoding + + MIME does not include any concept equivalent to HTTP/1.1's Content- + Encoding header field. Since this acts as a modifier on the media + type, proxies and gateways from HTTP to MIME-compliant protocols MUST + either change the value of the Content-Type header field or decode + the entity-body before forwarding the message. (Some experimental + applications of Content-Type for Internet mail have used a media-type + parameter of ";conversions=" to perform an equivalent + function as Content-Encoding. However, this parameter is not part of + MIME.) + +19.4.4 No Content-Transfer-Encoding + + HTTP does not use the Content-Transfer-Encoding (CTE) field of MIME. + Proxies and gateways from MIME-compliant protocols to HTTP MUST + remove any non-identity CTE ("quoted-printable" or "base64") encoding + prior to delivering the response message to an HTTP client. + + Proxies and gateways from HTTP to MIME-compliant protocols are + responsible for ensuring that the message is in the correct format + and encoding for safe transport on that protocol, where "safe + transport" is defined by the limitations of the protocol being used. + Such a proxy or gateway SHOULD label the data with an appropriate + Content-Transfer-Encoding if doing so will improve the likelihood of + safe transport over the destination protocol. + +19.4.5 HTTP Header Fields in Multipart Body-Parts + + In MIME, most header fields in multipart body-parts are generally + ignored unless the field name begins with "Content-". In HTTP/1.1, + multipart body-parts may contain any HTTP header fields which are + significant to the meaning of that part. + + + + + + +Fielding, et. al. Standards Track [Page 153] + +RFC 2068 HTTP/1.1 January 1997 + + +19.4.6 Introduction of Transfer-Encoding + + HTTP/1.1 introduces the Transfer-Encoding header field (section + 14.40). Proxies/gateways MUST remove any transfer coding prior to + forwarding a message via a MIME-compliant protocol. + + A process for decoding the "chunked" transfer coding (section 3.6) + can be represented in pseudo-code as: + + length := 0 + read chunk-size, chunk-ext (if any) and CRLF + while (chunk-size > 0) { + read chunk-data and CRLF + append chunk-data to entity-body + length := length + chunk-size + read chunk-size and CRLF + } + read entity-header + while (entity-header not empty) { + append entity-header to existing header fields + read entity-header + } + Content-Length := length + Remove "chunked" from Transfer-Encoding + +19.4.7 MIME-Version + + HTTP is not a MIME-compliant protocol (see appendix 19.4). However, + HTTP/1.1 messages may include a single MIME-Version general-header + field to indicate what version of the MIME protocol was used to + construct the message. Use of the MIME-Version header field indicates + that the message is in full compliance with the MIME protocol. + Proxies/gateways are responsible for ensuring full compliance (where + possible) when exporting HTTP messages to strict MIME environments. + + MIME-Version = "MIME-Version" ":" 1*DIGIT "." 1*DIGIT + + MIME version "1.0" is the default for use in HTTP/1.1. However, + HTTP/1.1 message parsing and semantics are defined by this document + and not the MIME specification. + +19.5 Changes from HTTP/1.0 + + This section summarizes major differences between versions HTTP/1.0 + and HTTP/1.1. + + + + + + +Fielding, et. al. Standards Track [Page 154] + +RFC 2068 HTTP/1.1 January 1997 + + +19.5.1 Changes to Simplify Multi-homed Web Servers and Conserve IP + Addresses + + The requirements that clients and servers support the Host request- + header, report an error if the Host request-header (section 14.23) is + missing from an HTTP/1.1 request, and accept absolute URIs (section + 5.1.2) are among the most important changes defined by this + specification. + + Older HTTP/1.0 clients assumed a one-to-one relationship of IP + addresses and servers; there was no other established mechanism for + distinguishing the intended server of a request than the IP address + to which that request was directed. The changes outlined above will + allow the Internet, once older HTTP clients are no longer common, to + support multiple Web sites from a single IP address, greatly + simplifying large operational Web servers, where allocation of many + IP addresses to a single host has created serious problems. The + Internet will also be able to recover the IP addresses that have been + allocated for the sole purpose of allowing special-purpose domain + names to be used in root-level HTTP URLs. Given the rate of growth of + the Web, and the number of servers already deployed, it is extremely + important that all implementations of HTTP (including updates to + existing HTTP/1.0 applications) correctly implement these + requirements: + + o Both clients and servers MUST support the Host request-header. + + o Host request-headers are required in HTTP/1.1 requests. + + o Servers MUST report a 400 (Bad Request) error if an HTTP/1.1 + request does not include a Host request-header. + + o Servers MUST accept absolute URIs. + + + + + + + + + + + + + + + + + + +Fielding, et. al. Standards Track [Page 155] + +RFC 2068 HTTP/1.1 January 1997 + + +19.6 Additional Features + + This appendix documents protocol elements used by some existing HTTP + implementations, but not consistently and correctly across most + HTTP/1.1 applications. Implementers should be aware of these + features, but cannot rely upon their presence in, or interoperability + with, other HTTP/1.1 applications. Some of these describe proposed + experimental features, and some describe features that experimental + deployment found lacking that are now addressed in the base HTTP/1.1 + specification. + +19.6.1 Additional Request Methods + +19.6.1.1 PATCH + + The PATCH method is similar to PUT except that the entity contains a + list of differences between the original version of the resource + identified by the Request-URI and the desired content of the resource + after the PATCH action has been applied. The list of differences is + in a format defined by the media type of the entity (e.g., + "application/diff") and MUST include sufficient information to allow + the server to recreate the changes necessary to convert the original + version of the resource to the desired version. + + If the request passes through a cache and the Request-URI identifies + a currently cached entity, that entity MUST be removed from the + cache. Responses to this method are not cachable. + + The actual method for determining how the patched resource is placed, + and what happens to its predecessor, is defined entirely by the + origin server. If the original version of the resource being patched + included a Content-Version header field, the request entity MUST + include a Derived-From header field corresponding to the value of the + original Content-Version header field. Applications are encouraged to + use these fields for constructing versioning relationships and + resolving version conflicts. + + PATCH requests must obey the message transmission requirements set + out in section 8.2. + + Caches that implement PATCH should invalidate cached responses as + defined in section 13.10 for PUT. + +19.6.1.2 LINK + + The LINK method establishes one or more Link relationships between + the existing resource identified by the Request-URI and other + existing resources. The difference between LINK and other methods + + + +Fielding, et. al. Standards Track [Page 156] + +RFC 2068 HTTP/1.1 January 1997 + + + allowing links to be established between resources is that the LINK + method does not allow any message-body to be sent in the request and + does not directly result in the creation of new resources. + + If the request passes through a cache and the Request-URI identifies + a currently cached entity, that entity MUST be removed from the + cache. Responses to this method are not cachable. + + Caches that implement LINK should invalidate cached responses as + defined in section 13.10 for PUT. + +19.6.1.3 UNLINK + + The UNLINK method removes one or more Link relationships from the + existing resource identified by the Request-URI. These relationships + may have been established using the LINK method or by any other + method supporting the Link header. The removal of a link to a + resource does not imply that the resource ceases to exist or becomes + inaccessible for future references. + + If the request passes through a cache and the Request-URI identifies + a currently cached entity, that entity MUST be removed from the + cache. Responses to this method are not cachable. + + Caches that implement UNLINK should invalidate cached responses as + defined in section 13.10 for PUT. + +19.6.2 Additional Header Field Definitions + +19.6.2.1 Alternates + + The Alternates response-header field has been proposed as a means for + the origin server to inform the client about other available + representations of the requested resource, along with their + distinguishing attributes, and thus providing a more reliable means + for a user agent to perform subsequent selection of another + representation which better fits the desires of its user (described + as agent-driven negotiation in section 12). + + + + + + + + + + + + + +Fielding, et. al. Standards Track [Page 157] + +RFC 2068 HTTP/1.1 January 1997 + + + The Alternates header field is orthogonal to the Vary header field in + that both may coexist in a message without affecting the + interpretation of the response or the available representations. It + is expected that Alternates will provide a significant improvement + over the server-driven negotiation provided by the Vary field for + those resources that vary over common dimensions like type and + language. + + The Alternates header field will be defined in a future + specification. + +19.6.2.2 Content-Version + + The Content-Version entity-header field defines the version tag + associated with a rendition of an evolving entity. Together with the + Derived-From field described in section 19.6.2.3, it allows a group + of people to work simultaneously on the creation of a work as an + iterative process. The field should be used to allow evolution of a + particular work along a single path rather than derived works or + renditions in different representations. + + Content-Version = "Content-Version" ":" quoted-string + + Examples of the Content-Version field include: + + Content-Version: "2.1.2" + Content-Version: "Fred 19950116-12:26:48" + Content-Version: "2.5a4-omega7" + +19.6.2.3 Derived-From + + The Derived-From entity-header field can be used to indicate the + version tag of the resource from which the enclosed entity was + derived before modifications were made by the sender. This field is + used to help manage the process of merging successive changes to a + resource, particularly when such changes are being made in parallel + and from multiple sources. + + Derived-From = "Derived-From" ":" quoted-string + + An example use of the field is: + + Derived-From: "2.1.1" + + The Derived-From field is required for PUT and PATCH requests if the + entity being sent was previously retrieved from the same URI and a + Content-Version header was included with the entity when it was last + retrieved. + + + +Fielding, et. al. Standards Track [Page 158] + +RFC 2068 HTTP/1.1 January 1997 + + +19.6.2.4 Link + + The Link entity-header field provides a means for describing a + relationship between two resources, generally between the requested + resource and some other resource. An entity MAY include multiple Link + values. Links at the metainformation level typically indicate + relationships like hierarchical structure and navigation paths. The + Link field is semantically equivalent to the element in + HTML.[5] + + Link = "Link" ":" #("<" URI ">" *( ";" link-param ) + + link-param = ( ( "rel" "=" relationship ) + | ( "rev" "=" relationship ) + | ( "title" "=" quoted-string ) + | ( "anchor" "=" <"> URI <"> ) + | ( link-extension ) ) + + link-extension = token [ "=" ( token | quoted-string ) ] + + relationship = sgml-name + | ( <"> sgml-name *( SP sgml-name) <"> ) + + sgml-name = ALPHA *( ALPHA | DIGIT | "." | "-" ) + + Relationship values are case-insensitive and MAY be extended within + the constraints of the sgml-name syntax. The title parameter MAY be + used to label the destination of a link such that it can be used as + identification within a human-readable menu. The anchor parameter MAY + be used to indicate a source anchor other than the entire current + resource, such as a fragment of this resource or a third resource. + + Examples of usage include: + + Link: ; rel="Previous" + + Link: ; rev="Made"; title="Tim Berners-Lee" + + The first example indicates that chapter2 is previous to this + resource in a logical navigation path. The second indicates that the + person responsible for making the resource available is identified by + the given e-mail address. + +19.6.2.5 URI + + The URI header field has, in past versions of this specification, + been used as a combination of the existing Location, Content- + Location, and Vary header fields as well as the future Alternates + + + +Fielding, et. al. Standards Track [Page 159] + +RFC 2068 HTTP/1.1 January 1997 + + + field (above). Its primary purpose has been to include a list of + additional URIs for the resource, including names and mirror + locations. However, it has become clear that the combination of many + different functions within this single field has been a barrier to + consistently and correctly implementing any of those functions. + Furthermore, we believe that the identification of names and mirror + locations would be better performed via the Link header field. The + URI header field is therefore deprecated in favor of those other + fields. + + URI-header = "URI" ":" 1#( "<" URI ">" ) + +19.7 Compatibility with Previous Versions + + It is beyond the scope of a protocol specification to mandate + compliance with previous versions. HTTP/1.1 was deliberately + designed, however, to make supporting previous versions easy. It is + worth noting that at the time of composing this specification, we + would expect commercial HTTP/1.1 servers to: + + o recognize the format of the Request-Line for HTTP/0.9, 1.0, and 1.1 + requests; + + o understand any valid request in the format of HTTP/0.9, 1.0, or + 1.1; + + o respond appropriately with a message in the same major version used + by the client. + + And we would expect HTTP/1.1 clients to: + + o recognize the format of the Status-Line for HTTP/1.0 and 1.1 + responses; + + o understand any valid response in the format of HTTP/0.9, 1.0, or + 1.1. + + For most implementations of HTTP/1.0, each connection is established + by the client prior to the request and closed by the server after + sending the response. A few implementations implement the Keep-Alive + version of persistent connections described in section 19.7.1.1. + + + + + + + + + + +Fielding, et. al. Standards Track [Page 160] + +RFC 2068 HTTP/1.1 January 1997 + + +19.7.1 Compatibility with HTTP/1.0 Persistent Connections + + Some clients and servers may wish to be compatible with some previous + implementations of persistent connections in HTTP/1.0 clients and + servers. Persistent connections in HTTP/1.0 must be explicitly + negotiated as they are not the default behavior. HTTP/1.0 + experimental implementations of persistent connections are faulty, + and the new facilities in HTTP/1.1 are designed to rectify these + problems. The problem was that some existing 1.0 clients may be + sending Keep-Alive to a proxy server that doesn't understand + Connection, which would then erroneously forward it to the next + inbound server, which would establish the Keep-Alive connection and + result in a hung HTTP/1.0 proxy waiting for the close on the + response. The result is that HTTP/1.0 clients must be prevented from + using Keep-Alive when talking to proxies. + + However, talking to proxies is the most important use of persistent + connections, so that prohibition is clearly unacceptable. Therefore, + we need some other mechanism for indicating a persistent connection + is desired, which is safe to use even when talking to an old proxy + that ignores Connection. Persistent connections are the default for + HTTP/1.1 messages; we introduce a new keyword (Connection: close) for + declaring non-persistence. + + The following describes the original HTTP/1.0 form of persistent + connections. + + When it connects to an origin server, an HTTP client MAY send the + Keep-Alive connection-token in addition to the Persist connection- + token: + + Connection: Keep-Alive + + An HTTP/1.0 server would then respond with the Keep-Alive connection + token and the client may proceed with an HTTP/1.0 (or Keep-Alive) + persistent connection. + + An HTTP/1.1 server may also establish persistent connections with + HTTP/1.0 clients upon receipt of a Keep-Alive connection token. + However, a persistent connection with an HTTP/1.0 client cannot make + use of the chunked transfer-coding, and therefore MUST use a + Content-Length for marking the ending boundary of each message. + + A client MUST NOT send the Keep-Alive connection token to a proxy + server as HTTP/1.0 proxy servers do not obey the rules of HTTP/1.1 + for parsing the Connection header field. + + + + + +Fielding, et. al. Standards Track [Page 161] + +RFC 2068 HTTP/1.1 January 1997 + + +19.7.1.1 The Keep-Alive Header + + When the Keep-Alive connection-token has been transmitted with a + request or a response, a Keep-Alive header field MAY also be + included. The Keep-Alive header field takes the following form: + + Keep-Alive-header = "Keep-Alive" ":" 0# keepalive-param + + keepalive-param = param-name "=" value + + The Keep-Alive header itself is optional, and is used only if a + parameter is being sent. HTTP/1.1 does not define any parameters. + + If the Keep-Alive header is sent, the corresponding connection token + MUST be transmitted. The Keep-Alive header MUST be ignored if + received without the connection token. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Fielding, et. al. Standards Track [Page 162] + diff --git a/net/http/rfc2396 b/net/http/rfc2396 new file mode 100644 index 00000000..5bd52110 --- /dev/null +++ b/net/http/rfc2396 @@ -0,0 +1,2243 @@ + + + + + + +Network Working Group T. Berners-Lee +Request for Comments: 2396 MIT/LCS +Updates: 1808, 1738 R. Fielding +Category: Standards Track U.C. Irvine + L. Masinter + Xerox Corporation + August 1998 + + + Uniform Resource Identifiers (URI): Generic Syntax + +Status of this Memo + + This document specifies an Internet standards track protocol for the + Internet community, and requests discussion and suggestions for + improvements. Please refer to the current edition of the "Internet + Official Protocol Standards" (STD 1) for the standardization state + and status of this protocol. Distribution of this memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (1998). All Rights Reserved. + +IESG Note + + This paper describes a "superset" of operations that can be applied + to URI. It consists of both a grammar and a description of basic + functionality for URI. To understand what is a valid URI, both the + grammar and the associated description have to be studied. Some of + the functionality described is not applicable to all URI schemes, and + some operations are only possible when certain media types are + retrieved using the URI, regardless of the scheme used. + +Abstract + + A Uniform Resource Identifier (URI) is a compact string of characters + for identifying an abstract or physical resource. This document + defines the generic syntax of URI, including both absolute and + relative forms, and guidelines for their use; it revises and replaces + the generic definitions in RFC 1738 and RFC 1808. + + This document defines a grammar that is a superset of all valid URI, + such that an implementation can parse the common components of a URI + reference without knowing the scheme-specific requirements of every + possible identifier type. This document does not define a generative + grammar for URI; that task will be performed by the individual + specifications of each URI scheme. + + + + +Berners-Lee, et. al. Standards Track [Page 1] + +RFC 2396 URI Generic Syntax August 1998 + + +1. Introduction + + Uniform Resource Identifiers (URI) provide a simple and extensible + means for identifying a resource. This specification of URI syntax + and semantics is derived from concepts introduced by the World Wide + Web global information initiative, whose use of such objects dates + from 1990 and is described in "Universal Resource Identifiers in WWW" + [RFC1630]. The specification of URI is designed to meet the + recommendations laid out in "Functional Recommendations for Internet + Resource Locators" [RFC1736] and "Functional Requirements for Uniform + Resource Names" [RFC1737]. + + This document updates and merges "Uniform Resource Locators" + [RFC1738] and "Relative Uniform Resource Locators" [RFC1808] in order + to define a single, generic syntax for all URI. It excludes those + portions of RFC 1738 that defined the specific syntax of individual + URL schemes; those portions will be updated as separate documents, as + will the process for registration of new URI schemes. This document + does not discuss the issues and recommendation for dealing with + characters outside of the US-ASCII character set [ASCII]; those + recommendations are discussed in a separate document. + + All significant changes from the prior RFCs are noted in Appendix G. + +1.1 Overview of URI + + URI are characterized by the following definitions: + + Uniform + Uniformity provides several benefits: it allows different types + of resource identifiers to be used in the same context, even + when the mechanisms used to access those resources may differ; + it allows uniform semantic interpretation of common syntactic + conventions across different types of resource identifiers; it + allows introduction of new types of resource identifiers + without interfering with the way that existing identifiers are + used; and, it allows the identifiers to be reused in many + different contexts, thus permitting new applications or + protocols to leverage a pre-existing, large, and widely-used + set of resource identifiers. + + Resource + A resource can be anything that has identity. Familiar + examples include an electronic document, an image, a service + (e.g., "today's weather report for Los Angeles"), and a + collection of other resources. Not all resources are network + "retrievable"; e.g., human beings, corporations, and bound + books in a library can also be considered resources. + + + +Berners-Lee, et. al. Standards Track [Page 2] + +RFC 2396 URI Generic Syntax August 1998 + + + The resource is the conceptual mapping to an entity or set of + entities, not necessarily the entity which corresponds to that + mapping at any particular instance in time. Thus, a resource + can remain constant even when its content---the entities to + which it currently corresponds---changes over time, provided + that the conceptual mapping is not changed in the process. + + Identifier + An identifier is an object that can act as a reference to + something that has identity. In the case of URI, the object is + a sequence of characters with a restricted syntax. + + Having identified a resource, a system may perform a variety of + operations on the resource, as might be characterized by such words + as `access', `update', `replace', or `find attributes'. + +1.2. URI, URL, and URN + + A URI can be further classified as a locator, a name, or both. The + term "Uniform Resource Locator" (URL) refers to the subset of URI + that identify resources via a representation of their primary access + mechanism (e.g., their network "location"), rather than identifying + the resource by name or by some other attribute(s) of that resource. + The term "Uniform Resource Name" (URN) refers to the subset of URI + that are required to remain globally unique and persistent even when + the resource ceases to exist or becomes unavailable. + + The URI scheme (Section 3.1) defines the namespace of the URI, and + thus may further restrict the syntax and semantics of identifiers + using that scheme. This specification defines those elements of the + URI syntax that are either required of all URI schemes or are common + to many URI schemes. It thus defines the syntax and semantics that + are needed to implement a scheme-independent parsing mechanism for + URI references, such that the scheme-dependent handling of a URI can + be postponed until the scheme-dependent semantics are needed. We use + the term URL below when describing syntax or semantics that only + apply to locators. + + Although many URL schemes are named after protocols, this does not + imply that the only way to access the URL's resource is via the named + protocol. Gateways, proxies, caches, and name resolution services + might be used to access some resources, independent of the protocol + of their origin, and the resolution of some URL may require the use + of more than one protocol (e.g., both DNS and HTTP are typically used + to access an "http" URL's resource when it can't be found in a local + cache). + + + + + +Berners-Lee, et. al. Standards Track [Page 3] + +RFC 2396 URI Generic Syntax August 1998 + + + A URN differs from a URL in that it's primary purpose is persistent + labeling of a resource with an identifier. That identifier is drawn + from one of a set of defined namespaces, each of which has its own + set name structure and assignment procedures. The "urn" scheme has + been reserved to establish the requirements for a standardized URN + namespace, as defined in "URN Syntax" [RFC2141] and its related + specifications. + + Most of the examples in this specification demonstrate URL, since + they allow the most varied use of the syntax and often have a + hierarchical namespace. A parser of the URI syntax is capable of + parsing both URL and URN references as a generic URI; once the scheme + is determined, the scheme-specific parsing can be performed on the + generic URI components. In other words, the URI syntax is a superset + of the syntax of all URI schemes. + +1.3. Example URI + + The following examples illustrate URI that are in common use. + + ftp://ftp.is.co.za/rfc/rfc1808.txt + -- ftp scheme for File Transfer Protocol services + + gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles + -- gopher scheme for Gopher and Gopher+ Protocol services + + http://www.math.uio.no/faq/compression-faq/part1.html + -- http scheme for Hypertext Transfer Protocol services + + mailto:mduerst@ifi.unizh.ch + -- mailto scheme for electronic mail addresses + + news:comp.infosystems.www.servers.unix + -- news scheme for USENET news groups and articles + + telnet://melvyl.ucop.edu/ + -- telnet scheme for interactive services via the TELNET Protocol + +1.4. Hierarchical URI and Relative Forms + + An absolute identifier refers to a resource independent of the + context in which the identifier is used. In contrast, a relative + identifier refers to a resource by describing the difference within a + hierarchical namespace between the current context and an absolute + identifier of the resource. + + + + + + +Berners-Lee, et. al. Standards Track [Page 4] + +RFC 2396 URI Generic Syntax August 1998 + + + Some URI schemes support a hierarchical naming system, where the + hierarchy of the name is denoted by a "/" delimiter separating the + components in the scheme. This document defines a scheme-independent + `relative' form of URI reference that can be used in conjunction with + a `base' URI (of a hierarchical scheme) to produce another URI. The + syntax of hierarchical URI is described in Section 3; the relative + URI calculation is described in Section 5. + +1.5. URI Transcribability + + The URI syntax was designed with global transcribability as one of + its main concerns. A URI is a sequence of characters from a very + limited set, i.e. the letters of the basic Latin alphabet, digits, + and a few special characters. A URI may be represented in a variety + of ways: e.g., ink on paper, pixels on a screen, or a sequence of + octets in a coded character set. The interpretation of a URI depends + only on the characters used and not how those characters are + represented in a network protocol. + + The goal of transcribability can be described by a simple scenario. + Imagine two colleagues, Sam and Kim, sitting in a pub at an + international conference and exchanging research ideas. Sam asks Kim + for a location to get more information, so Kim writes the URI for the + research site on a napkin. Upon returning home, Sam takes out the + napkin and types the URI into a computer, which then retrieves the + information to which Kim referred. + + There are several design concerns revealed by the scenario: + + o A URI is a sequence of characters, which is not always + represented as a sequence of octets. + + o A URI may be transcribed from a non-network source, and thus + should consist of characters that are most likely to be able to + be typed into a computer, within the constraints imposed by + keyboards (and related input devices) across languages and + locales. + + o A URI often needs to be remembered by people, and it is easier + for people to remember a URI when it consists of meaningful + components. + + These design concerns are not always in alignment. For example, it + is often the case that the most meaningful name for a URI component + would require characters that cannot be typed into some systems. The + ability to transcribe the resource identifier from one medium to + another was considered more important than having its URI consist of + the most meaningful of components. In local and regional contexts + + + +Berners-Lee, et. al. Standards Track [Page 5] + +RFC 2396 URI Generic Syntax August 1998 + + + and with improving technology, users might benefit from being able to + use a wider range of characters; such use is not defined in this + document. + +1.6. Syntax Notation and Common Elements + + This document uses two conventions to describe and define the syntax + for URI. The first, called the layout form, is a general description + of the order of components and component separators, as in + + /;? + + The component names are enclosed in angle-brackets and any characters + outside angle-brackets are literal separators. Whitespace should be + ignored. These descriptions are used informally and do not define + the syntax requirements. + + The second convention is a BNF-like grammar, used to define the + formal URI syntax. The grammar is that of [RFC822], except that "|" + is used to designate alternatives. Briefly, rules are separated from + definitions by an equal "=", indentation is used to continue a rule + definition over more than one line, literals are quoted with "", + parentheses "(" and ")" are used to group elements, optional elements + are enclosed in "[" and "]" brackets, and elements may be preceded + with * to designate n or more repetitions of the following + element; n defaults to 0. + + Unlike many specifications that use a BNF-like grammar to define the + bytes (octets) allowed by a protocol, the URI grammar is defined in + terms of characters. Each literal in the grammar corresponds to the + character it represents, rather than to the octet encoding of that + character in any particular coded character set. How a URI is + represented in terms of bits and bytes on the wire is dependent upon + the character encoding of the protocol used to transport it, or the + charset of the document which contains it. + + The following definitions are common to many elements: + + alpha = lowalpha | upalpha + + lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | + "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | + "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" + + upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | + "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | + "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" + + + + +Berners-Lee, et. al. Standards Track [Page 6] + +RFC 2396 URI Generic Syntax August 1998 + + + digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | + "8" | "9" + + alphanum = alpha | digit + + The complete URI syntax is collected in Appendix A. + +2. URI Characters and Escape Sequences + + URI consist of a restricted set of characters, primarily chosen to + aid transcribability and usability both in computer systems and in + non-computer communications. Characters used conventionally as + delimiters around URI were excluded. The restricted set of + characters consists of digits, letters, and a few graphic symbols + were chosen from those common to most of the character encodings and + input facilities available to Internet users. + + uric = reserved | unreserved | escaped + + Within a URI, characters are either used as delimiters, or to + represent strings of data (octets) within the delimited portions. + Octets are either represented directly by a character (using the US- + ASCII character for that octet [ASCII]) or by an escape encoding. + This representation is elaborated below. + +2.1 URI and non-ASCII characters + + The relationship between URI and characters has been a source of + confusion for characters that are not part of US-ASCII. To describe + the relationship, it is useful to distinguish between a "character" + (as a distinguishable semantic entity) and an "octet" (an 8-bit + byte). There are two mappings, one from URI characters to octets, and + a second from octets to original characters: + + URI character sequence->octet sequence->original character sequence + + A URI is represented as a sequence of characters, not as a sequence + of octets. That is because URI might be "transported" by means that + are not through a computer network, e.g., printed on paper, read over + the radio, etc. + + A URI scheme may define a mapping from URI characters to octets; + whether this is done depends on the scheme. Commonly, within a + delimited component of a URI, a sequence of characters may be used to + represent a sequence of octets. For example, the character "a" + represents the octet 97 (decimal), while the character sequence "%", + "0", "a" represents the octet 10 (decimal). + + + + +Berners-Lee, et. al. Standards Track [Page 7] + +RFC 2396 URI Generic Syntax August 1998 + + + There is a second translation for some resources: the sequence of + octets defined by a component of the URI is subsequently used to + represent a sequence of characters. A 'charset' defines this mapping. + There are many charsets in use in Internet protocols. For example, + UTF-8 [UTF-8] defines a mapping from sequences of octets to sequences + of characters in the repertoire of ISO 10646. + + In the simplest case, the original character sequence contains only + characters that are defined in US-ASCII, and the two levels of + mapping are simple and easily invertible: each 'original character' + is represented as the octet for the US-ASCII code for it, which is, + in turn, represented as either the US-ASCII character, or else the + "%" escape sequence for that octet. + + For original character sequences that contain non-ASCII characters, + however, the situation is more difficult. Internet protocols that + transmit octet sequences intended to represent character sequences + are expected to provide some way of identifying the charset used, if + there might be more than one [RFC2277]. However, there is currently + no provision within the generic URI syntax to accomplish this + identification. An individual URI scheme may require a single + charset, define a default charset, or provide a way to indicate the + charset used. + + It is expected that a systematic treatment of character encoding + within URI will be developed as a future modification of this + specification. + +2.2. Reserved Characters + + Many URI include components consisting of or delimited by, certain + special characters. These characters are called "reserved", since + their usage within the URI component is limited to their reserved + purpose. If the data for a URI component would conflict with the + reserved purpose, then the conflicting data must be escaped before + forming the URI. + + reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | + "$" | "," + + The "reserved" syntax class above refers to those characters that are + allowed within a URI, but which may not be allowed within a + particular component of the generic URI syntax; they are used as + delimiters of the components described in Section 3. + + + + + + + +Berners-Lee, et. al. Standards Track [Page 8] + +RFC 2396 URI Generic Syntax August 1998 + + + Characters in the "reserved" set are not reserved in all contexts. + The set of characters actually reserved within any given URI + component is defined by that component. In general, a character is + reserved if the semantics of the URI changes if the character is + replaced with its escaped US-ASCII encoding. + +2.3. Unreserved Characters + + Data characters that are allowed in a URI but do not have a reserved + purpose are called unreserved. These include upper and lower case + letters, decimal digits, and a limited set of punctuation marks and + symbols. + + unreserved = alphanum | mark + + mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" + + Unreserved characters can be escaped without changing the semantics + of the URI, but this should not be done unless the URI is being used + in a context that does not allow the unescaped character to appear. + +2.4. Escape Sequences + + Data must be escaped if it does not have a representation using an + unreserved character; this includes data that does not correspond to + a printable character of the US-ASCII coded character set, or that + corresponds to any US-ASCII character that is disallowed, as + explained below. + +2.4.1. Escaped Encoding + + An escaped octet is encoded as a character triplet, consisting of the + percent character "%" followed by the two hexadecimal digits + representing the octet code. For example, "%20" is the escaped + encoding for the US-ASCII space character. + + escaped = "%" hex hex + hex = digit | "A" | "B" | "C" | "D" | "E" | "F" | + "a" | "b" | "c" | "d" | "e" | "f" + +2.4.2. When to Escape and Unescape + + A URI is always in an "escaped" form, since escaping or unescaping a + completed URI might change its semantics. Normally, the only time + escape encodings can safely be made is when the URI is being created + from its component parts; each component may have its own set of + characters that are reserved, so only the mechanism responsible for + generating or interpreting that component can determine whether or + + + +Berners-Lee, et. al. Standards Track [Page 9] + +RFC 2396 URI Generic Syntax August 1998 + + + not escaping a character will change its semantics. Likewise, a URI + must be separated into its components before the escaped characters + within those components can be safely decoded. + + In some cases, data that could be represented by an unreserved + character may appear escaped; for example, some of the unreserved + "mark" characters are automatically escaped by some systems. If the + given URI scheme defines a canonicalization algorithm, then + unreserved characters may be unescaped according to that algorithm. + For example, "%7e" is sometimes used instead of "~" in an http URL + path, but the two are equivalent for an http URL. + + Because the percent "%" character always has the reserved purpose of + being the escape indicator, it must be escaped as "%25" in order to + be used as data within a URI. Implementers should be careful not to + escape or unescape the same string more than once, since unescaping + an already unescaped string might lead to misinterpreting a percent + data character as another escaped character, or vice versa in the + case of escaping an already escaped string. + +2.4.3. Excluded US-ASCII Characters + + Although they are disallowed within the URI syntax, we include here a + description of those US-ASCII characters that have been excluded and + the reasons for their exclusion. + + The control characters in the US-ASCII coded character set are not + used within a URI, both because they are non-printable and because + they are likely to be misinterpreted by some control mechanisms. + + control = + + The space character is excluded because significant spaces may + disappear and insignificant spaces may be introduced when URI are + transcribed or typeset or subjected to the treatment of word- + processing programs. Whitespace is also used to delimit URI in many + contexts. + + space = + + The angle-bracket "<" and ">" and double-quote (") characters are + excluded because they are often used as the delimiters around URI in + text documents and protocol fields. The character "#" is excluded + because it is used to delimit a URI from a fragment identifier in URI + references (Section 4). The percent character "%" is excluded because + it is used for the encoding of escaped characters. + + delims = "<" | ">" | "#" | "%" | <"> + + + +Berners-Lee, et. al. Standards Track [Page 10] + +RFC 2396 URI Generic Syntax August 1998 + + + Other characters are excluded because gateways and other transport + agents are known to sometimes modify such characters, or they are + used as delimiters. + + unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`" + + Data corresponding to excluded characters must be escaped in order to + be properly represented within a URI. + +3. URI Syntactic Components + + The URI syntax is dependent upon the scheme. In general, absolute + URI are written as follows: + + : + + An absolute URI contains the name of the scheme being used () + followed by a colon (":") and then a string (the ) whose interpretation depends on the scheme. + + The URI syntax does not require that the scheme-specific-part have + any general structure or set of semantics which is common among all + URI. However, a subset of URI do share a common syntax for + representing hierarchical relationships within the namespace. This + "generic URI" syntax consists of a sequence of four main components: + + ://? + + each of which, except , may be absent from a particular URI. + For example, some URI schemes do not allow an component, + and others do not use a component. + + absoluteURI = scheme ":" ( hier_part | opaque_part ) + + URI that are hierarchical in nature use the slash "/" character for + separating hierarchical components. For some file systems, a "/" + character (used to denote the hierarchical structure of a URI) is the + delimiter used to construct a file name hierarchy, and thus the URI + path will look similar to a file pathname. This does NOT imply that + the resource is a file or that the URI maps to an actual filesystem + pathname. + + hier_part = ( net_path | abs_path ) [ "?" query ] + + net_path = "//" authority [ abs_path ] + + abs_path = "/" path_segments + + + + +Berners-Lee, et. al. Standards Track [Page 11] + +RFC 2396 URI Generic Syntax August 1998 + + + URI that do not make use of the slash "/" character for separating + hierarchical components are considered opaque by the generic URI + parser. + + opaque_part = uric_no_slash *uric + + uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" | + "&" | "=" | "+" | "$" | "," + + We use the term to refer to both the and + constructs, since they are mutually exclusive for any + given URI and can be parsed as a single component. + +3.1. Scheme Component + + Just as there are many different methods of access to resources, + there are a variety of schemes for identifying such resources. The + URI syntax consists of a sequence of components separated by reserved + characters, with the first component defining the semantics for the + remainder of the URI string. + + Scheme names consist of a sequence of characters beginning with a + lower case letter and followed by any combination of lower case + letters, digits, plus ("+"), period ("."), or hyphen ("-"). For + resiliency, programs interpreting URI should treat upper case letters + as equivalent to lower case in scheme names (e.g., allow "HTTP" as + well as "http"). + + scheme = alpha *( alpha | digit | "+" | "-" | "." ) + + Relative URI references are distinguished from absolute URI in that + they do not begin with a scheme name. Instead, the scheme is + inherited from the base URI, as described in Section 5.2. + +3.2. Authority Component + + Many URI schemes include a top hierarchical element for a naming + authority, such that the namespace defined by the remainder of the + URI is governed by that authority. This authority component is + typically defined by an Internet-based server or a scheme-specific + registry of naming authorities. + + authority = server | reg_name + + The authority component is preceded by a double slash "//" and is + terminated by the next slash "/", question-mark "?", or by the end of + the URI. Within the authority component, the characters ";", ":", + "@", "?", and "/" are reserved. + + + +Berners-Lee, et. al. Standards Track [Page 12] + +RFC 2396 URI Generic Syntax August 1998 + + + An authority component is not required for a URI scheme to make use + of relative references. A base URI without an authority component + implies that any relative reference will also be without an authority + component. + +3.2.1. Registry-based Naming Authority + + The structure of a registry-based naming authority is specific to the + URI scheme, but constrained to the allowed characters for an + authority component. + + reg_name = 1*( unreserved | escaped | "$" | "," | + ";" | ":" | "@" | "&" | "=" | "+" ) + +3.2.2. Server-based Naming Authority + + URL schemes that involve the direct use of an IP-based protocol to a + specified server on the Internet use a common syntax for the server + component of the URI's scheme-specific data: + + @: + + where may consist of a user name and, optionally, scheme- + specific information about how to gain authorization to access the + server. The parts "@" and ":" may be omitted. + + server = [ [ userinfo "@" ] hostport ] + + The user information, if present, is followed by a commercial at-sign + "@". + + userinfo = *( unreserved | escaped | + ";" | ":" | "&" | "=" | "+" | "$" | "," ) + + Some URL schemes use the format "user:password" in the userinfo + field. This practice is NOT RECOMMENDED, because the passing of + authentication information in clear text (such as URI) has proven to + be a security risk in almost every case where it has been used. + + The host is a domain name of a network host, or its IPv4 address as a + set of four decimal digit groups separated by ".". Literal IPv6 + addresses are not supported. + + hostport = host [ ":" port ] + host = hostname | IPv4address + hostname = *( domainlabel "." ) toplabel [ "." ] + domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum + toplabel = alpha | alpha *( alphanum | "-" ) alphanum + + + +Berners-Lee, et. al. Standards Track [Page 13] + +RFC 2396 URI Generic Syntax August 1998 + + + IPv4address = 1*digit "." 1*digit "." 1*digit "." 1*digit + port = *digit + + Hostnames take the form described in Section 3 of [RFC1034] and + Section 2.1 of [RFC1123]: a sequence of domain labels separated by + ".", each domain label starting and ending with an alphanumeric + character and possibly also containing "-" characters. The rightmost + domain label of a fully qualified domain name will never start with a + digit, thus syntactically distinguishing domain names from IPv4 + addresses, and may be followed by a single "." if it is necessary to + distinguish between the complete domain name and any local domain. + To actually be "Uniform" as a resource locator, a URL hostname should + be a fully qualified domain name. In practice, however, the host + component may be a local domain literal. + + Note: A suitable representation for including a literal IPv6 + address as the host part of a URL is desired, but has not yet been + determined or implemented in practice. + + The port is the network port number for the server. Most schemes + designate protocols that have a default port number. Another port + number may optionally be supplied, in decimal, separated from the + host by a colon. If the port is omitted, the default port number is + assumed. + +3.3. Path Component + + The path component contains data, specific to the authority (or the + scheme if there is no authority component), identifying the resource + within the scope of that scheme and authority. + + path = [ abs_path | opaque_part ] + + path_segments = segment *( "/" segment ) + segment = *pchar *( ";" param ) + param = *pchar + + pchar = unreserved | escaped | + ":" | "@" | "&" | "=" | "+" | "$" | "," + + The path may consist of a sequence of path segments separated by a + single slash "/" character. Within a path segment, the characters + "/", ";", "=", and "?" are reserved. Each path segment may include a + sequence of parameters, indicated by the semicolon ";" character. + The parameters are not significant to the parsing of relative + references. + + + + + +Berners-Lee, et. al. Standards Track [Page 14] + +RFC 2396 URI Generic Syntax August 1998 + + +3.4. Query Component + + The query component is a string of information to be interpreted by + the resource. + + query = *uric + + Within a query component, the characters ";", "/", "?", ":", "@", + "&", "=", "+", ",", and "$" are reserved. + +4. URI References + + The term "URI-reference" is used here to denote the common usage of a + resource identifier. A URI reference may be absolute or relative, + and may have additional information attached in the form of a + fragment identifier. However, "the URI" that results from such a + reference includes only the absolute URI after the fragment + identifier (if any) is removed and after any relative URI is resolved + to its absolute form. Although it is possible to limit the + discussion of URI syntax and semantics to that of the absolute + result, most usage of URI is within general URI references, and it is + impossible to obtain the URI from such a reference without also + parsing the fragment and resolving the relative form. + + URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] + + The syntax for relative URI is a shortened form of that for absolute + URI, where some prefix of the URI is missing and certain path + components ("." and "..") have a special meaning when, and only when, + interpreting a relative path. The relative URI syntax is defined in + Section 5. + +4.1. Fragment Identifier + + When a URI reference is used to perform a retrieval action on the + identified resource, the optional fragment identifier, separated from + the URI by a crosshatch ("#") character, consists of additional + reference information to be interpreted by the user agent after the + retrieval action has been successfully completed. As such, it is not + part of a URI, but is often used in conjunction with a URI. + + fragment = *uric + + The semantics of a fragment identifier is a property of the data + resulting from a retrieval action, regardless of the type of URI used + in the reference. Therefore, the format and interpretation of + fragment identifiers is dependent on the media type [RFC2046] of the + retrieval result. The character restrictions described in Section 2 + + + +Berners-Lee, et. al. Standards Track [Page 15] + +RFC 2396 URI Generic Syntax August 1998 + + + for URI also apply to the fragment in a URI-reference. Individual + media types may define additional restrictions or structure within + the fragment for specifying different types of "partial views" that + can be identified within that media type. + + A fragment identifier is only meaningful when a URI reference is + intended for retrieval and the result of that retrieval is a document + for which the identified fragment is consistently defined. + +4.2. Same-document References + + A URI reference that does not contain a URI is a reference to the + current document. In other words, an empty URI reference within a + document is interpreted as a reference to the start of that document, + and a reference containing only a fragment identifier is a reference + to the identified fragment of that document. Traversal of such a + reference should not result in an additional retrieval action. + However, if the URI reference occurs in a context that is always + intended to result in a new request, as in the case of HTML's FORM + element, then an empty URI reference represents the base URI of the + current document and should be replaced by that URI when transformed + into a request. + +4.3. Parsing a URI Reference + + A URI reference is typically parsed according to the four main + components and fragment identifier in order to determine what + components are present and whether the reference is relative or + absolute. The individual components are then parsed for their + subparts and, if not opaque, to verify their validity. + + Although the BNF defines what is allowed in each component, it is + ambiguous in terms of differentiating between an authority component + and a path component that begins with two slash characters. The + greedy algorithm is used for disambiguation: the left-most matching + rule soaks up as much of the URI reference string as it is capable of + matching. In other words, the authority component wins. + + Readers familiar with regular expressions should see Appendix B for a + concrete parsing example and test oracle. + +5. Relative URI References + + It is often the case that a group or "tree" of documents has been + constructed to serve a common purpose; the vast majority of URI in + these documents point to resources within the tree rather than + + + + + +Berners-Lee, et. al. Standards Track [Page 16] + +RFC 2396 URI Generic Syntax August 1998 + + + outside of it. Similarly, documents located at a particular site are + much more likely to refer to other resources at that site than to + resources at remote sites. + + Relative addressing of URI allows document trees to be partially + independent of their location and access scheme. For instance, it is + possible for a single set of hypertext documents to be simultaneously + accessible and traversable via each of the "file", "http", and "ftp" + schemes if the documents refer to each other using relative URI. + Furthermore, such document trees can be moved, as a whole, without + changing any of the relative references. Experience within the WWW + has demonstrated that the ability to perform relative referencing is + necessary for the long-term usability of embedded URI. + + The syntax for relative URI takes advantage of the syntax + of (Section 3) in order to express a reference that is + relative to the namespace of another hierarchical URI. + + relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ] + + A relative reference beginning with two slash characters is termed a + network-path reference, as defined by in Section 3. Such + references are rarely used. + + A relative reference beginning with a single slash character is + termed an absolute-path reference, as defined by in + Section 3. + + A relative reference that does not begin with a scheme name or a + slash character is termed a relative-path reference. + + rel_path = rel_segment [ abs_path ] + + rel_segment = 1*( unreserved | escaped | + ";" | "@" | "&" | "=" | "+" | "$" | "," ) + + Within a relative-path reference, the complete path segments "." and + ".." have special meanings: "the current hierarchy level" and "the + level above this hierarchy level", respectively. Although this is + very similar to their use within Unix-based filesystems to indicate + directory levels, these path components are only considered special + when resolving a relative-path reference to its absolute form + (Section 5.2). + + Authors should be aware that a path segment which contains a colon + character cannot be used as the first segment of a relative URI path + (e.g., "this:that"), because it would be mistaken for a scheme name. + + + + +Berners-Lee, et. al. Standards Track [Page 17] + +RFC 2396 URI Generic Syntax August 1998 + + + It is therefore necessary to precede such segments with other + segments (e.g., "./this:that") in order for them to be referenced as + a relative path. + + It is not necessary for all URI within a given scheme to be + restricted to the syntax, since the hierarchical + properties of that syntax are only necessary when relative URI are + used within a particular document. Documents can only make use of + relative URI when their base URI fits within the syntax. + It is assumed that any document which contains a relative reference + will also have a base URI that obeys the syntax. In other words, + relative URI cannot be used within a document that has an unsuitable + base URI. + + Some URI schemes do not allow a hierarchical syntax matching the + syntax, and thus cannot use relative references. + +5.1. Establishing a Base URI + + The term "relative URI" implies that there exists some absolute "base + URI" against which the relative reference is applied. Indeed, the + base URI is necessary to define the semantics of any relative URI + reference; without it, a relative reference is meaningless. In order + for relative URI to be usable within a document, the base URI of that + document must be known to the parser. + + The base URI of a document can be established in one of four ways, + listed below in order of precedence. The order of precedence can be + thought of in terms of layers, where the innermost defined base URI + has the highest precedence. This can be visualized graphically as: + + .----------------------------------------------------------. + | .----------------------------------------------------. | + | | .----------------------------------------------. | | + | | | .----------------------------------------. | | | + | | | | .----------------------------------. | | | | + | | | | | | | | | | + | | | | `----------------------------------' | | | | + | | | | (5.1.1) Base URI embedded in the | | | | + | | | | document's content | | | | + | | | `----------------------------------------' | | | + | | | (5.1.2) Base URI of the encapsulating entity | | | + | | | (message, document, or none). | | | + | | `----------------------------------------------' | | + | | (5.1.3) URI used to retrieve the entity | | + | `----------------------------------------------------' | + | (5.1.4) Default Base URI is application-dependent | + `----------------------------------------------------------' + + + +Berners-Lee, et. al. Standards Track [Page 18] + +RFC 2396 URI Generic Syntax August 1998 + + +5.1.1. Base URI within Document Content + + Within certain document media types, the base URI of the document can + be embedded within the content itself such that it can be readily + obtained by a parser. This can be useful for descriptive documents, + such as tables of content, which may be transmitted to others through + protocols other than their usual retrieval context (e.g., E-Mail or + USENET news). + + It is beyond the scope of this document to specify how, for each + media type, the base URI can be embedded. It is assumed that user + agents manipulating such media types will be able to obtain the + appropriate syntax from that media type's specification. An example + of how the base URI can be embedded in the Hypertext Markup Language + (HTML) [RFC1866] is provided in Appendix D. + + A mechanism for embedding the base URI within MIME container types + (e.g., the message and multipart types) is defined by MHTML + [RFC2110]. Protocols that do not use the MIME message header syntax, + but which do allow some form of tagged metainformation to be included + within messages, may define their own syntax for defining the base + URI as part of a message. + +5.1.2. Base URI from the Encapsulating Entity + + If no base URI is embedded, the base URI of a document is defined by + the document's retrieval context. For a document that is enclosed + within another entity (such as a message or another document), the + retrieval context is that entity; thus, the default base URI of the + document is the base URI of the entity in which the document is + encapsulated. + +5.1.3. Base URI from the Retrieval URI + + If no base URI is embedded and the document is not encapsulated + within some other entity (e.g., the top level of a composite entity), + then, if a URI was used to retrieve the base document, that URI shall + be considered the base URI. Note that if the retrieval was the + result of a redirected request, the last URI used (i.e., that which + resulted in the actual retrieval of the document) is the base URI. + +5.1.4. Default Base URI + + If none of the conditions described in Sections 5.1.1--5.1.3 apply, + then the base URI is defined by the context of the application. + Since this definition is necessarily application-dependent, failing + + + + + +Berners-Lee, et. al. Standards Track [Page 19] + +RFC 2396 URI Generic Syntax August 1998 + + + to define the base URI using one of the other methods may result in + the same content being interpreted differently by different types of + application. + + It is the responsibility of the distributor(s) of a document + containing relative URI to ensure that the base URI for that document + can be established. It must be emphasized that relative URI cannot + be used reliably in situations where the document's base URI is not + well-defined. + +5.2. Resolving Relative References to Absolute Form + + This section describes an example algorithm for resolving URI + references that might be relative to a given base URI. + + The base URI is established according to the rules of Section 5.1 and + parsed into the four main components as described in Section 3. Note + that only the scheme component is required to be present in the base + URI; the other components may be empty or undefined. A component is + undefined if its preceding separator does not appear in the URI + reference; the path component is never undefined, though it may be + empty. The base URI's query component is not used by the resolution + algorithm and may be discarded. + + For each URI reference, the following steps are performed in order: + + 1) The URI reference is parsed into the potential four components and + fragment identifier, as described in Section 4.3. + + 2) If the path component is empty and the scheme, authority, and + query components are undefined, then it is a reference to the + current document and we are done. Otherwise, the reference URI's + query and fragment components are defined as found (or not found) + within the URI reference and not inherited from the base URI. + + 3) If the scheme component is defined, indicating that the reference + starts with a scheme name, then the reference is interpreted as an + absolute URI and we are done. Otherwise, the reference URI's + scheme is inherited from the base URI's scheme component. + + Due to a loophole in prior specifications [RFC1630], some parsers + allow the scheme name to be present in a relative URI if it is the + same as the base URI scheme. Unfortunately, this can conflict + with the correct parsing of non-hierarchical URI. For backwards + compatibility, an implementation may work around such references + by removing the scheme if it matches that of the base URI and the + scheme is known to always use the syntax. The parser + + + + +Berners-Lee, et. al. Standards Track [Page 20] + +RFC 2396 URI Generic Syntax August 1998 + + + can then continue with the steps below for the remainder of the + reference components. Validating parsers should mark such a + misformed relative reference as an error. + + 4) If the authority component is defined, then the reference is a + network-path and we skip to step 7. Otherwise, the reference + URI's authority is inherited from the base URI's authority + component, which will also be undefined if the URI scheme does not + use an authority component. + + 5) If the path component begins with a slash character ("/"), then + the reference is an absolute-path and we skip to step 7. + + 6) If this step is reached, then we are resolving a relative-path + reference. The relative path needs to be merged with the base + URI's path. Although there are many ways to do this, we will + describe a simple method using a separate string buffer. + + a) All but the last segment of the base URI's path component is + copied to the buffer. In other words, any characters after the + last (right-most) slash character, if any, are excluded. + + b) The reference's path component is appended to the buffer + string. + + c) All occurrences of "./", where "." is a complete path segment, + are removed from the buffer string. + + d) If the buffer string ends with "." as a complete path segment, + that "." is removed. + + e) All occurrences of "/../", where is a + complete path segment not equal to "..", are removed from the + buffer string. Removal of these path segments is performed + iteratively, removing the leftmost matching pattern on each + iteration, until no matching pattern remains. + + f) If the buffer string ends with "/..", where + is a complete path segment not equal to "..", that + "/.." is removed. + + g) If the resulting buffer string still begins with one or more + complete path segments of "..", then the reference is + considered to be in error. Implementations may handle this + error by retaining these components in the resolved path (i.e., + treating them as part of the final URI), by removing them from + the resolved path (i.e., discarding relative levels above the + root), or by avoiding traversal of the reference. + + + +Berners-Lee, et. al. Standards Track [Page 21] + +RFC 2396 URI Generic Syntax August 1998 + + + h) The remaining buffer string is the reference URI's new path + component. + + 7) The resulting URI components, including any inherited from the + base URI, are recombined to give the absolute form of the URI + reference. Using pseudocode, this would be + + result = "" + + if scheme is defined then + append scheme to result + append ":" to result + + if authority is defined then + append "//" to result + append authority to result + + append path to result + + if query is defined then + append "?" to result + append query to result + + if fragment is defined then + append "#" to result + append fragment to result + + return result + + Note that we must be careful to preserve the distinction between a + component that is undefined, meaning that its separator was not + present in the reference, and a component that is empty, meaning + that the separator was present and was immediately followed by the + next component separator or the end of the reference. + + The above algorithm is intended to provide an example by which the + output of implementations can be tested -- implementation of the + algorithm itself is not required. For example, some systems may find + it more efficient to implement step 6 as a pair of segment stacks + being merged, rather than as a series of string pattern replacements. + + Note: Some WWW client applications will fail to separate the + reference's query component from its path component before merging + the base and reference paths in step 6 above. This may result in + a loss of information if the query component contains the strings + "/../" or "/./". + + Resolution examples are provided in Appendix C. + + + +Berners-Lee, et. al. Standards Track [Page 22] + +RFC 2396 URI Generic Syntax August 1998 + + +6. URI Normalization and Equivalence + + In many cases, different URI strings may actually identify the + identical resource. For example, the host names used in URL are + actually case insensitive, and the URL is + equivalent to . In general, the rules for + equivalence and definition of a normal form, if any, are scheme + dependent. When a scheme uses elements of the common syntax, it will + also use the common syntax equivalence rules, namely that the scheme + and hostname are case insensitive and a URL with an explicit ":port", + where the port is the default for the scheme, is equivalent to one + where the port is elided. + +7. Security Considerations + + A URI does not in itself pose a security threat. Users should beware + that there is no general guarantee that a URL, which at one time + located a given resource, will continue to do so. Nor is there any + guarantee that a URL will not locate a different resource at some + later point in time, due to the lack of any constraint on how a given + authority apportions its namespace. Such a guarantee can only be + obtained from the person(s) controlling that namespace and the + resource in question. A specific URI scheme may include additional + semantics, such as name persistence, if those semantics are required + of all naming authorities for that scheme. + + It is sometimes possible to construct a URL such that an attempt to + perform a seemingly harmless, idempotent operation, such as the + retrieval of an entity associated with the resource, will in fact + cause a possibly damaging remote operation to occur. The unsafe URL + is typically constructed by specifying a port number other than that + reserved for the network protocol in question. The client + unwittingly contacts a site that is in fact running a different + protocol. The content of the URL contains instructions that, when + interpreted according to this other protocol, cause an unexpected + operation. An example has been the use of a gopher URL to cause an + unintended or impersonating message to be sent via a SMTP server. + + Caution should be used when using any URL that specifies a port + number other than the default for the protocol, especially when it is + a number within the reserved space. + + Care should be taken when a URL contains escaped delimiters for a + given protocol (for example, CR and LF characters for telnet + protocols) that these are not unescaped before transmission. This + might violate the protocol, but avoids the potential for such + + + + + +Berners-Lee, et. al. Standards Track [Page 23] + +RFC 2396 URI Generic Syntax August 1998 + + + characters to be used to simulate an extra operation or parameter in + that protocol, which might lead to an unexpected and possibly harmful + remote operation to be performed. + + It is clearly unwise to use a URL that contains a password which is + intended to be secret. In particular, the use of a password within + the 'userinfo' component of a URL is strongly disrecommended except + in those rare cases where the 'password' parameter is intended to be + public. + +8. Acknowledgements + + This document was derived from RFC 1738 [RFC1738] and RFC 1808 + [RFC1808]; the acknowledgements in those specifications still apply. + In addition, contributions by Gisle Aas, Martin Beet, Martin Duerst, + Jim Gettys, Martijn Koster, Dave Kristol, Daniel LaLiberte, Foteos + Macrides, James Marshall, Ryan Moats, Keith Moore, and Lauren Wood + are gratefully acknowledged. + +9. References + + [RFC2277] Alvestrand, H., "IETF Policy on Character Sets and + Languages", BCP 18, RFC 2277, January 1998. + + [RFC1630] Berners-Lee, T., "Universal Resource Identifiers in WWW: A + Unifying Syntax for the Expression of Names and Addresses + of Objects on the Network as used in the World-Wide Web", + RFC 1630, June 1994. + + [RFC1738] Berners-Lee, T., Masinter, L., and M. McCahill, Editors, + "Uniform Resource Locators (URL)", RFC 1738, December 1994. + + [RFC1866] Berners-Lee T., and D. Connolly, "HyperText Markup Language + Specification -- 2.0", RFC 1866, November 1995. + + [RFC1123] Braden, R., Editor, "Requirements for Internet Hosts -- + Application and Support", STD 3, RFC 1123, October 1989. + + [RFC822] Crocker, D., "Standard for the Format of ARPA Internet Text + Messages", STD 11, RFC 822, August 1982. + + [RFC1808] Fielding, R., "Relative Uniform Resource Locators", RFC + 1808, June 1995. + + [RFC2046] Freed, N., and N. Borenstein, "Multipurpose Internet Mail + Extensions (MIME) Part Two: Media Types", RFC 2046, + November 1996. + + + + +Berners-Lee, et. al. Standards Track [Page 24] + +RFC 2396 URI Generic Syntax August 1998 + + + [RFC1736] Kunze, J., "Functional Recommendations for Internet + Resource Locators", RFC 1736, February 1995. + + [RFC2141] Moats, R., "URN Syntax", RFC 2141, May 1997. + + [RFC1034] Mockapetris, P., "Domain Names - Concepts and Facilities", + STD 13, RFC 1034, November 1987. + + [RFC2110] Palme, J., and A. Hopmann, "MIME E-mail Encapsulation of + Aggregate Documents, such as HTML (MHTML)", RFC 2110, March + 1997. + + [RFC1737] Sollins, K., and L. Masinter, "Functional Requirements for + Uniform Resource Names", RFC 1737, December 1994. + + [ASCII] US-ASCII. "Coded Character Set -- 7-bit American Standard + Code for Information Interchange", ANSI X3.4-1986. + + [UTF-8] Yergeau, F., "UTF-8, a transformation format of ISO 10646", + RFC 2279, January 1998. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Berners-Lee, et. al. Standards Track [Page 25] + +RFC 2396 URI Generic Syntax August 1998 + + +10. Authors' Addresses + + Tim Berners-Lee + World Wide Web Consortium + MIT Laboratory for Computer Science, NE43-356 + 545 Technology Square + Cambridge, MA 02139 + + Fax: +1(617)258-8682 + EMail: timbl@w3.org + + + Roy T. Fielding + Department of Information and Computer Science + University of California, Irvine + Irvine, CA 92697-3425 + + Fax: +1(949)824-1715 + EMail: fielding@ics.uci.edu + + + Larry Masinter + Xerox PARC + 3333 Coyote Hill Road + Palo Alto, CA 94034 + + Fax: +1(415)812-4333 + EMail: masinter@parc.xerox.com + + + + + + + + + + + + + + + + + + + + + + + +Berners-Lee, et. al. Standards Track [Page 26] + +RFC 2396 URI Generic Syntax August 1998 + + +A. Collected BNF for URI + + URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] + absoluteURI = scheme ":" ( hier_part | opaque_part ) + relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ] + + hier_part = ( net_path | abs_path ) [ "?" query ] + opaque_part = uric_no_slash *uric + + uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" | + "&" | "=" | "+" | "$" | "," + + net_path = "//" authority [ abs_path ] + abs_path = "/" path_segments + rel_path = rel_segment [ abs_path ] + + rel_segment = 1*( unreserved | escaped | + ";" | "@" | "&" | "=" | "+" | "$" | "," ) + + scheme = alpha *( alpha | digit | "+" | "-" | "." ) + + authority = server | reg_name + + reg_name = 1*( unreserved | escaped | "$" | "," | + ";" | ":" | "@" | "&" | "=" | "+" ) + + server = [ [ userinfo "@" ] hostport ] + userinfo = *( unreserved | escaped | + ";" | ":" | "&" | "=" | "+" | "$" | "," ) + + hostport = host [ ":" port ] + host = hostname | IPv4address + hostname = *( domainlabel "." ) toplabel [ "." ] + domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum + toplabel = alpha | alpha *( alphanum | "-" ) alphanum + IPv4address = 1*digit "." 1*digit "." 1*digit "." 1*digit + port = *digit + + path = [ abs_path | opaque_part ] + path_segments = segment *( "/" segment ) + segment = *pchar *( ";" param ) + param = *pchar + pchar = unreserved | escaped | + ":" | "@" | "&" | "=" | "+" | "$" | "," + + query = *uric + + fragment = *uric + + + +Berners-Lee, et. al. Standards Track [Page 27] + +RFC 2396 URI Generic Syntax August 1998 + + + uric = reserved | unreserved | escaped + reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | + "$" | "," + unreserved = alphanum | mark + mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | + "(" | ")" + + escaped = "%" hex hex + hex = digit | "A" | "B" | "C" | "D" | "E" | "F" | + "a" | "b" | "c" | "d" | "e" | "f" + + alphanum = alpha | digit + alpha = lowalpha | upalpha + + lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | + "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | + "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" + upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | + "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | + "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" + digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | + "8" | "9" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Berners-Lee, et. al. Standards Track [Page 28] + +RFC 2396 URI Generic Syntax August 1998 + + +B. Parsing a URI Reference with a Regular Expression + + As described in Section 4.3, the generic URI syntax is not sufficient + to disambiguate the components of some forms of URI. Since the + "greedy algorithm" described in that section is identical to the + disambiguation method used by POSIX regular expressions, it is + natural and commonplace to use a regular expression for parsing the + potential four components and fragment identifier of a URI reference. + + The following line is the regular expression for breaking-down a URI + reference into its components. + + ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? + 12 3 4 5 6 7 8 9 + + The numbers in the second line above are only to assist readability; + they indicate the reference points for each subexpression (i.e., each + paired parenthesis). We refer to the value matched for subexpression + as $. For example, matching the above expression to + + http://www.ics.uci.edu/pub/ietf/uri/#Related + + results in the following subexpression matches: + + $1 = http: + $2 = http + $3 = //www.ics.uci.edu + $4 = www.ics.uci.edu + $5 = /pub/ietf/uri/ + $6 = + $7 = + $8 = #Related + $9 = Related + + where indicates that the component is not present, as is + the case for the query component in the above example. Therefore, we + can determine the value of the four components and fragment as + + scheme = $2 + authority = $4 + path = $5 + query = $7 + fragment = $9 + + and, going in the opposite direction, we can recreate a URI reference + from its components using the algorithm in step 7 of Section 5.2. + + + + + +Berners-Lee, et. al. Standards Track [Page 29] + +RFC 2396 URI Generic Syntax August 1998 + + +C. Examples of Resolving Relative URI References + + Within an object with a well-defined base URI of + + http://a/b/c/d;p?q + + the relative URI would be resolved as follows: + +C.1. Normal Examples + + g:h = g:h + g = http://a/b/c/g + ./g = http://a/b/c/g + g/ = http://a/b/c/g/ + /g = http://a/g + //g = http://g + ?y = http://a/b/c/?y + g?y = http://a/b/c/g?y + #s = (current document)#s + g#s = http://a/b/c/g#s + g?y#s = http://a/b/c/g?y#s + ;x = http://a/b/c/;x + g;x = http://a/b/c/g;x + g;x?y#s = http://a/b/c/g;x?y#s + . = http://a/b/c/ + ./ = http://a/b/c/ + .. = http://a/b/ + ../ = http://a/b/ + ../g = http://a/b/g + ../.. = http://a/ + ../../ = http://a/ + ../../g = http://a/g + +C.2. Abnormal Examples + + Although the following abnormal examples are unlikely to occur in + normal practice, all URI parsers should be capable of resolving them + consistently. Each example uses the same base as above. + + An empty reference refers to the start of the current document. + + <> = (current document) + + Parsers must be careful in handling the case where there are more + relative path ".." segments than there are hierarchical levels in the + base URI's path. Note that the ".." syntax cannot be used to change + the authority component of a URI. + + + + +Berners-Lee, et. al. Standards Track [Page 30] + +RFC 2396 URI Generic Syntax August 1998 + + + ../../../g = http://a/../g + ../../../../g = http://a/../../g + + In practice, some implementations strip leading relative symbolic + elements (".", "..") after applying a relative URI calculation, based + on the theory that compensating for obvious author errors is better + than allowing the request to fail. Thus, the above two references + will be interpreted as "http://a/g" by some implementations. + + Similarly, parsers must avoid treating "." and ".." as special when + they are not complete components of a relative path. + + /./g = http://a/./g + /../g = http://a/../g + g. = http://a/b/c/g. + .g = http://a/b/c/.g + g.. = http://a/b/c/g.. + ..g = http://a/b/c/..g + + Less likely are cases where the relative URI uses unnecessary or + nonsensical forms of the "." and ".." complete path segments. + + ./../g = http://a/b/g + ./g/. = http://a/b/c/g/ + g/./h = http://a/b/c/g/h + g/../h = http://a/b/c/h + g;x=1/./y = http://a/b/c/g;x=1/y + g;x=1/../y = http://a/b/c/y + + All client applications remove the query component from the base URI + before resolving relative URI. However, some applications fail to + separate the reference's query and/or fragment components from a + relative path before merging it with the base path. This error is + rarely noticed, since typical usage of a fragment never includes the + hierarchy ("/") character, and the query component is not normally + used within relative references. + + g?y/./x = http://a/b/c/g?y/./x + g?y/../x = http://a/b/c/g?y/../x + g#s/./x = http://a/b/c/g#s/./x + g#s/../x = http://a/b/c/g#s/../x + + + + + + + + + + +Berners-Lee, et. al. Standards Track [Page 31] + +RFC 2396 URI Generic Syntax August 1998 + + + Some parsers allow the scheme name to be present in a relative URI if + it is the same as the base URI scheme. This is considered to be a + loophole in prior specifications of partial URI [RFC1630]. Its use + should be avoided. + + http:g = http:g ; for validating parsers + | http://a/b/c/g ; for backwards compatibility + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Berners-Lee, et. al. Standards Track [Page 32] + +RFC 2396 URI Generic Syntax August 1998 + + +D. Embedding the Base URI in HTML documents + + It is useful to consider an example of how the base URI of a document + can be embedded within the document's content. In this appendix, we + describe how documents written in the Hypertext Markup Language + (HTML) [RFC1866] can include an embedded base URI. This appendix + does not form a part of the URI specification and should not be + considered as anything more than a descriptive example. + + HTML defines a special element "BASE" which, when present in the + "HEAD" portion of a document, signals that the parser should use the + BASE element's "HREF" attribute as the base URI for resolving any + relative URI. The "HREF" attribute must be an absolute URI. Note + that, in HTML, element and attribute names are case-insensitive. For + example: + + + + An example HTML document + + + ... a hypertext anchor ... + + + A parser reading the example document should interpret the given + relative URI "../x" as representing the absolute URI + + + + regardless of the context in which the example document was obtained. + + + + + + + + + + + + + + + + + + + + + +Berners-Lee, et. al. Standards Track [Page 33] + +RFC 2396 URI Generic Syntax August 1998 + + +E. Recommendations for Delimiting URI in Context + + URI are often transmitted through formats that do not provide a clear + context for their interpretation. For example, there are many + occasions when URI are included in plain text; examples include text + sent in electronic mail, USENET news messages, and, most importantly, + printed on paper. In such cases, it is important to be able to + delimit the URI from the rest of the text, and in particular from + punctuation marks that might be mistaken for part of the URI. + + In practice, URI are delimited in a variety of ways, but usually + within double-quotes "http://test.com/", angle brackets + , or just using whitespace + + http://test.com/ + + These wrappers do not form part of the URI. + + In the case where a fragment identifier is associated with a URI + reference, the fragment would be placed within the brackets as well + (separated from the URI with a "#" character). + + In some cases, extra whitespace (spaces, linebreaks, tabs, etc.) may + need to be added to break long URI across lines. The whitespace + should be ignored when extracting the URI. + + No whitespace should be introduced after a hyphen ("-") character. + Because some typesetters and printers may (erroneously) introduce a + hyphen at the end of line when breaking a line, the interpreter of a + URI containing a line break immediately after a hyphen should ignore + all unescaped whitespace around the line break, and should be aware + that the hyphen may or may not actually be part of the URI. + + Using <> angle brackets around each URI is especially recommended as + a delimiting style for URI that contain whitespace. + + The prefix "URL:" (with or without a trailing space) was recommended + as a way to used to help distinguish a URL from other bracketed + designators, although this is not common in practice. + + For robustness, software that accepts user-typed URI should attempt + to recognize and strip both delimiters and embedded whitespace. + + For example, the text: + + + + + + + +Berners-Lee, et. al. Standards Track [Page 34] + +RFC 2396 URI Generic Syntax August 1998 + + + Yes, Jim, I found it under "http://www.w3.org/Addressing/", + but you can probably pick it up from . Note the warning in . + + contains the URI references + + http://www.w3.org/Addressing/ + ftp://ds.internic.net/rfc/ + http://www.ics.uci.edu/pub/ietf/uri/historical.html#WARNING + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Berners-Lee, et. al. Standards Track [Page 35] + +RFC 2396 URI Generic Syntax August 1998 + + +F. Abbreviated URLs + + The URL syntax was designed for unambiguous reference to network + resources and extensibility via the URL scheme. However, as URL + identification and usage have become commonplace, traditional media + (television, radio, newspapers, billboards, etc.) have increasingly + used abbreviated URL references. That is, a reference consisting of + only the authority and path portions of the identified resource, such + as + + www.w3.org/Addressing/ + + or simply the DNS hostname on its own. Such references are primarily + intended for human interpretation rather than machine, with the + assumption that context-based heuristics are sufficient to complete + the URL (e.g., most hostnames beginning with "www" are likely to have + a URL prefix of "http://"). Although there is no standard set of + heuristics for disambiguating abbreviated URL references, many client + implementations allow them to be entered by the user and + heuristically resolved. It should be noted that such heuristics may + change over time, particularly when new URL schemes are introduced. + + Since an abbreviated URL has the same syntax as a relative URL path, + abbreviated URL references cannot be used in contexts where relative + URLs are expected. This limits the use of abbreviated URLs to places + where there is no defined base URL, such as dialog boxes and off-line + advertisements. + + + + + + + + + + + + + + + + + + + + + + + + +Berners-Lee, et. al. Standards Track [Page 36] + +RFC 2396 URI Generic Syntax August 1998 + + +G. Summary of Non-editorial Changes + +G.1. Additions + + Section 4 (URI References) was added to stem the confusion regarding + "what is a URI" and how to describe fragment identifiers given that + they are not part of the URI, but are part of the URI syntax and + parsing concerns. In addition, it provides a reference definition + for use by other IETF specifications (HTML, HTTP, etc.) that have + previously attempted to redefine the URI syntax in order to account + for the presence of fragment identifiers in URI references. + + Section 2.4 was rewritten to clarify a number of misinterpretations + and to leave room for fully internationalized URI. + + Appendix F on abbreviated URLs was added to describe the shortened + references often seen on television and magazine advertisements and + explain why they are not used in other contexts. + +G.2. Modifications from both RFC 1738 and RFC 1808 + + Changed to URI syntax instead of just URL. + + Confusion regarding the terms "character encoding", the URI + "character set", and the escaping of characters with % + equivalents has (hopefully) been reduced. Many of the BNF rule names + regarding the character sets have been changed to more accurately + describe their purpose and to encompass all "characters" rather than + just US-ASCII octets. Unless otherwise noted here, these + modifications do not affect the URI syntax. + + Both RFC 1738 and RFC 1808 refer to the "reserved" set of characters + as if URI-interpreting software were limited to a single set of + characters with a reserved purpose (i.e., as meaning something other + than the data to which the characters correspond), and that this set + was fixed by the URI scheme. However, this has not been true in + practice; any character that is interpreted differently when it is + escaped is, in effect, reserved. Furthermore, the interpreting + engine on a HTTP server is often dependent on the resource, not just + the URI scheme. The description of reserved characters has been + changed accordingly. + + The plus "+", dollar "$", and comma "," characters have been added to + those in the "reserved" set, since they are treated as reserved + within the query component. + + + + + + +Berners-Lee, et. al. Standards Track [Page 37] + +RFC 2396 URI Generic Syntax August 1998 + + + The tilde "~" character was added to those in the "unreserved" set, + since it is extensively used on the Internet in spite of the + difficulty to transcribe it with some keyboards. + + The syntax for URI scheme has been changed to require that all + schemes begin with an alpha character. + + The "user:password" form in the previous BNF was changed to a + "userinfo" token, and the possibility that it might be + "user:password" made scheme specific. In particular, the use of + passwords in the clear is not even suggested by the syntax. + + The question-mark "?" character was removed from the set of allowed + characters for the userinfo in the authority component, since testing + showed that many applications treat it as reserved for separating the + query component from the rest of the URI. + + The semicolon ";" character was added to those stated as being + reserved within the authority component, since several new schemes + are using it as a separator within userinfo to indicate the type of + user authentication. + + RFC 1738 specified that the path was separated from the authority + portion of a URI by a slash. RFC 1808 followed suit, but with a + fudge of carrying around the separator as a "prefix" in order to + describe the parsing algorithm. RFC 1630 never had this problem, + since it considered the slash to be part of the path. In writing + this specification, it was found to be impossible to accurately + describe and retain the difference between the two URI + and + without either considering the slash to be part of the path (as + corresponds to actual practice) or creating a separate component just + to hold that slash. We chose the former. + +G.3. Modifications from RFC 1738 + + The definition of specific URL schemes and their scheme-specific + syntax and semantics has been moved to separate documents. + + The URL host was defined as a fully-qualified domain name. However, + many URLs are used without fully-qualified domain names (in contexts + for which the full qualification is not necessary), without any host + (as in some file URLs), or with a host of "localhost". + + The URL port is now *digit instead of 1*digit, since systems are + expected to handle the case where the ":" separator between host and + port is supplied without a port. + + + + +Berners-Lee, et. al. Standards Track [Page 38] + +RFC 2396 URI Generic Syntax August 1998 + + + The recommendations for delimiting URI in context (Appendix E) have + been adjusted to reflect current practice. + +G.4. Modifications from RFC 1808 + + RFC 1808 (Section 4) defined an empty URL reference (a reference + containing nothing aside from the fragment identifier) as being a + reference to the base URL. Unfortunately, that definition could be + interpreted, upon selection of such a reference, as a new retrieval + action on that resource. Since the normal intent of such references + is for the user agent to change its view of the current document to + the beginning of the specified fragment within that document, not to + make an additional request of the resource, a description of how to + correctly interpret an empty reference has been added in Section 4. + + The description of the mythical Base header field has been replaced + with a reference to the Content-Location header field defined by + MHTML [RFC2110]. + + RFC 1808 described various schemes as either having or not having the + properties of the generic URI syntax. However, the only requirement + is that the particular document containing the relative references + have a base URI that abides by the generic URI syntax, regardless of + the URI scheme, so the associated description has been updated to + reflect that. + + The BNF term has been replaced with , since the + latter more accurately describes its use and purpose. Likewise, the + authority is no longer restricted to the IP server syntax. + + Extensive testing of current client applications demonstrated that + the majority of deployed systems do not use the ";" character to + indicate trailing parameter information, and that the presence of a + semicolon in a path segment does not affect the relative parsing of + that segment. Therefore, parameters have been removed as a separate + component and may now appear in any path segment. Their influence + has been removed from the algorithm for resolving a relative URI + reference. The resolution examples in Appendix C have been modified + to reflect this change. + + Implementations are now allowed to work around misformed relative + references that are prefixed by the same scheme as the base URI, but + only for schemes known to use the syntax. + + + + + + + + +Berners-Lee, et. al. Standards Track [Page 39] + +RFC 2396 URI Generic Syntax August 1998 + + +H. Full Copyright Statement + + Copyright (C) The Internet Society (1998). All Rights Reserved. + + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it + or assist in its implementation may be prepared, copied, published + and distributed, in whole or in part, without restriction of any + kind, provided that the above copyright notice and this paragraph are + included on all such copies and derivative works. However, this + document itself may not be modified in any way, such as by removing + the copyright notice or references to the Internet Society or other + Internet organizations, except as needed for the purpose of + developing Internet standards in which case the procedures for + copyrights defined in the Internet Standards process must be + followed, or as required to translate it into languages other than + English. + + The limited permissions granted above are perpetual and will not be + revoked by the Internet Society or its successors or assigns. + + This document and the information contained herein is provided on an + "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING + TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION + HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + + + + + + + + + + + + + + + + + + + + + + + +Berners-Lee, et. al. Standards Track [Page 40] + diff --git a/net/http/todo.S b/net/http/todo.S new file mode 100644 index 00000000..e04b612d --- /dev/null +++ b/net/http/todo.S @@ -0,0 +1,51 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +/ TODO(jart): FIX ME + + .globl "o//net/http/uricspn.c" + .equ "o//net/http/uricspn.c",. + .globl "o//net/http/uriparse.c" + .equ "o//net/http/uriparse.c",. + + .globl "o/rel/net/http/uricspn.c" + .equ "o/rel/net/http/uricspn.c",. + .globl "o/rel/net/http/uriparse.c" + .equ "o/rel/net/http/uriparse.c",. + + .globl "o/tiny/net/http/uricspn.c" + .equ "o/tiny/net/http/uricspn.c",. + .globl "o/tiny/net/http/uriparse.c" + .equ "o/tiny/net/http/uriparse.c",. + + .globl "o/dbg/net/http/uricspn.c" + .equ "o/dbg/net/http/uricspn.c",. + .globl "o/dbg/net/http/uriparse.c" + .equ "o/dbg/net/http/uriparse.c",. + + .globl "o/opt/net/http/uricspn.c" + .equ "o/opt/net/http/uricspn.c",. + .globl "o/opt/net/http/uriparse.c" + .equ "o/opt/net/http/uriparse.c",. + + .globl "o/ansi/net/http/uricspn.c" + .equ "o/ansi/net/http/uricspn.c",. + .globl "o/ansi/net/http/uriparse.c" + .equ "o/ansi/net/http/uriparse.c",. diff --git a/net/http/uri.h b/net/http/uri.h new file mode 100644 index 00000000..7d8c4240 --- /dev/null +++ b/net/http/uri.h @@ -0,0 +1,106 @@ +#ifndef COSMOPOLITAN_NET_HTTP_URI_H_ +#define COSMOPOLITAN_NET_HTTP_URI_H_ +#include "libc/dns/dns.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +enum UriScheme { + kUriSchemeHttp = 1, + kUriSchemeHttps, + kUriSchemeFile, + kUriSchemeData, + kUriSchemeZip, + kUriSchemeSip, + kUriSchemeSips, + kUriSchemeTel, + kUriSchemeSsh, + kUriSchemeGs, + kUriSchemeS3 +}; + +struct Uri { + /* + * e.g. "", "http", "sip", "http", "dns+http", etc. + */ + struct UriSlice { + /* + * !i && !n means absent + * i && !n means empty + */ + unsigned i, n; + } scheme; + + /* + * Holds remainder for exotic URI schemes, e.g. data. + */ + struct UriSlice opaque; + + /* + * e.g. sip:user@host, //user:pass@host + */ + struct UriSlice userinfo; + + /* + * e.g. "", "example.com", "1.2.3.4", "::1", etc. + */ + struct UriSlice host; + + /* + * e.g. "", "5060", "80", etc. + */ + struct UriSlice port; + + /* + * e.g. /dir/index.html means + * - memcmp("/dir/index.html", + * p + segs.p[0].i, + * (segs.p[segs.i - 1].n + + * (segs.p[segs.i - 1].i - + * segs.p[0].i))) == 0 + * - memcmp("/dir", p + segs.p[0].i, segs.p[0].n) == 0 + * - memcmp("/index.html", p + segs.p[1].i, segs.p[1].n) == 0 + */ + struct UriSlices { + unsigned i, n; + struct UriSlice *p; + } segs; + + /* e.g. ;lr;isup-oli=00;day=tuesday */ + struct UriKeyvals { + unsigned i, n; + struct UriKeyval { + struct UriSlice k, v; + } * p; + } params; + + /* + * e.g. /dir;super=rare/index.html + * + * let 𝑖 ∈ [0,params.i) + * paramsegs.p[𝑖].r ∈ [0,segs.i] + */ + struct UriRefs { + unsigned i, n; + struct UriRef { + unsigned r; + } * p; + } paramsegs; + + /* e.g. ?boop&subject=project%20x&lol=cat */ + struct UriKeyvals queries; + + /* e.g. #anchor */ + struct UriSlice fragment; +}; + +int uricspn(const char *data, size_t size); +int uriparse(struct Uri *, const char *, size_t) paramsnonnull((1)); +enum UriScheme urischeme(struct UriSlice, const char *) + paramsnonnull() nosideeffect; +struct UriSlice uripath(const struct Uri *) paramsnonnull() nosideeffect; +char *urislice2cstr(char *, size_t, struct UriSlice, const char *, const char *) + paramsnonnull((1, 4)); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_NET_HTTP_URI_H_ */ diff --git a/net/http/uricspn-avx.S b/net/http/uricspn-avx.S new file mode 100644 index 00000000..4c0facdc --- /dev/null +++ b/net/http/uricspn-avx.S @@ -0,0 +1,62 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +/ Verifies buffer contains only URI characters. +/ +/ @param %rdi is data which should be 32-byte aligned +/ @param %rsi is byte length of data +/ @return number of kosher bytes +/ @cost 10x faster than fastest Ragel code +uricspn$avx: + .leafprologue + .profilable + vmovaps .Luric(%rip),%xmm0 + mov $14,%eax + mov %rsi,%rdx + xor %esi,%esi +0: vmovdqu (%rdi,%rsi),%xmm1 + vmovdqu 16(%rdi,%rsi),%xmm2 + vpcmpestri $0b00010100,%xmm1,%xmm0 + jc 1f + jo 1f + add $16,%rsi + sub $16,%rdx + vpcmpestri $0b00010100,%xmm2,%xmm0 + jc 1f + jo 1f + add $16,%rsi + sub $16,%rdx + jmp 0b +1: lea (%rsi,%rcx),%rax + .leafepilogue + .endfn uricspn$avx,globl,hidden + + .rodata.cst16 +.Luric: .byte '!,'! + .byte '$,'; + .byte '=,'= + .byte '?,'Z + .byte '_,'_ + .byte 'a,'z + .byte '~,'~ + .byte 0,0 + .endobj .Luric + .previous diff --git a/net/http/uricspn.rl b/net/http/uricspn.rl new file mode 100644 index 00000000..85f67464 --- /dev/null +++ b/net/http/uricspn.rl @@ -0,0 +1,69 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/sysv/errfuns.h" +#include "net/http/uri.h" + +#define static + +/* clang-format off */ +%% machine uricspn; +%% write data; +/* clang-format on */ + +int uricspn(const char *data, size_t size) { + int uricspn$avx(const char *, size_t) hidden; + const char *p, *pe; + int cs; + + assert(data || !size); + assert(size <= 0x7ffff000); + assert(size <= 0x7ffff000); + + if (X86_HAVE(AVX)) { + return uricspn$avx(data, size); + } + + p = data; + pe = data + size; + + /* clang-format off */ + + %%{ + mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"; + reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","; + unreserved = alnum | mark; + uric = reserved | unreserved | "%"; + machina := uric*; + }%% + + %% write init; + cs = uricspn_en_machina; + %% write exec; + + /* clang-format on */ + + if (cs >= uricspn_first_final) { + return p - data; + } else { + return einval(); + } +} diff --git a/net/http/uricspn.svgz b/net/http/uricspn.svgz new file mode 100644 index 00000000..f6ab643b Binary files /dev/null and b/net/http/uricspn.svgz differ diff --git a/net/http/uriparse.rl b/net/http/uriparse.rl new file mode 100644 index 00000000..0f46ee33 --- /dev/null +++ b/net/http/uriparse.rl @@ -0,0 +1,246 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/dce.h" +#include "libc/dns/dns.h" +#include "libc/log/log.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" +#include "net/http/uri.h" + +#define static + +/* clang-format off */ +%% machine uriparse; +%% write data; +/* clang-format on */ + +/** + * Parses URI. + * + * This is a general URL parser. It's typically used for HTTP. Support + * for the bonus syntax needed by SIP is provided. The whirlwhind tour + * of the URI rabbit hole is as follows: + * + * /foo.html + * //justine.local/foo.html + * http://justine.local/foo.html + * http://bettersearchengine.local/search.cgi?q=my%20query + * file:///etc/passwd + * gs://bucket/object.txt + * zip:///usr/share/zoneinfo/GMT + * sip:127.0.0.1:5060;lr + * sip:+12125650666@gateway.example + * sip:bob%20barker:priceisright@[dead:beef::666]:5060;isup-oli=00 + * data:video/mpeg;base64,gigabytesofhex + * + * This parser operates on slices rather than C strings. It performs + * slicing and validation only. Operations like turning "%20"→" " or + * "80"→80 and perfect hashing can be done later, if needed. + * + * The Uri object is owned by the caller; it has a lifecycle like the + * following: + * + * struct Uri uri; + * memset(&uri, 0, sizeof(uri)); + * + * uriparse(&uri, s1, strlen(s1)); + * CHECK_EQ(kUriSchemeHttp, urischeme(uri->scheme, s1)); + * + * uriparse(&uri, s2, strlen(s2)); + * printf("host = %`.*s\n", uri->host.n, s2 + uri->host.i); + * + * Inner arrays may be granted memory by the caller. The uri->𝐴.i field + * is cleared at the mark of this function. No more than uri->𝐴.n items + * can be inserted. If we need more than that, then ENOMEM is returned + * rather than dynamically extending uri->𝐴.p. However, if uri->𝐴.n==0, + * we assume caller doesn't care about uri->𝐴 and its data is discarded. + * + * @param uri is owned by caller + * @param p is caller-owned uri string; won't copy/alias/mutate + * @return 0 on success, or -1 w/ errno + * @see RFC2396: Uniform Resource Identifiers (URI): Generic Syntax + * @see RFC3261: SIP: Session Initiation Protocol + */ +int uriparse(struct Uri *uri, const char *p, size_t size) { + unsigned zero, cs; + struct UriKeyval kv; + const char *pe, *eof, *buf, *mark; + + assert(p || !size); + assert(size <= 0x7ffff000); + +#define ABSENT ((struct UriSlice){zero, zero}) +#define SLICE ((struct UriSlice){mark - buf, p - mark}) + + cs = zero = VEIL("r", 0u); + eof = pe = (mark = buf = p) + size; + + uri->scheme = ABSENT; + uri->opaque = ABSENT; + uri->userinfo = ABSENT; + uri->host = ABSENT; + uri->port = ABSENT; + uri->fragment = ABSENT; + uri->segs.i = zero; + uri->paramsegs.i = zero; + uri->params.i = zero; + uri->queries.i = zero; + + /* clang-format off */ + + %%{ + action Mark { mark = p; } + action SetScheme { uri->scheme = SLICE; } + action SetFragment { uri->fragment = SLICE; } + action SetUserinfo { uri->userinfo = SLICE; } + action SetHost { uri->host = SLICE; } + action SetPort { uri->port = SLICE; } + + action SetKey { + kv.k = SLICE; + kv.v = (struct UriSlice){zero, zero}; + } + + action SetVal { + kv.v = SLICE; + } + + action RestartSegs { + uri->segs.i = zero; + uri->paramsegs.i = zero; + } + + action AppendParam { + if (uri->params.n) { + if (uri->params.i < uri->params.n) { + uri->params.p[uri->params.i++] = kv; + } else { + return enomem(); + } + } + } + + action AppendQuery { + if (uri->queries.n) { + if (uri->queries.i < uri->queries.n) { + uri->queries.p[uri->queries.i++] = kv; + } else { + return enomem(); + } + } + } + + action AppendSegment { + if (p > mark && uri->segs.n) { + if (uri->segs.i < uri->segs.n) { + uri->segs.p[uri->segs.i++] = SLICE; + } else { + return enomem(); + } + } + } + + action HandleOpaquePart { + switch (urischeme(uri->scheme, buf)) { + case kUriSchemeSip: + case kUriSchemeSips: + --p; + fgoto sip; + default: + if (uricspn(p, pe - p) == pe - p) { + uri->opaque = (struct UriSlice){p - buf, pe - p}; + return zero; + } else { + return einval(); + } + } + } + + mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"; + reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","; + unreserved = alnum | mark; + ipv4c = digit | "."; + ipv6c = xdigit | "." | ":"; + hostc = alnum | "-" | "."; + telc = digit | "+" | "-"; + schemec = alnum | "+" | "-" | "."; + userinfoc = unreserved | "&" | "=" | "+" | "$" | "," | "?" | ":"; + paramc = unreserved | "[" | "]" | ":" | "&" | "+" | "$"; + queryc = unreserved | "[" | "]" | "/" | "?" | ":" | "+" | "$"; + pathc = unreserved | ":" | "@" | "&" | "=" | "+" | "$" | ","; + relc = unreserved | ";" | "@" | "&" | "=" | "+" | "$" | ","; + uric = reserved | unreserved; + + escaped = "%" xdigit xdigit; + pathchar = escaped | pathc; + urichar = escaped | uric; + relchar = escaped | relc; + userinfochar = escaped | userinfoc; + paramchar = escaped | paramc; + querychar = escaped | queryc; + + paramkey = paramchar+ >Mark %SetKey; + paramval = paramchar+ >Mark %SetVal; + param = ";" paramkey ( "=" paramval )? %AppendParam; + + querykey = querychar+ >Mark %SetKey; + queryval = querychar+ >Mark %SetVal; + query = querykey ( "=" queryval )? %AppendQuery; + queries = "?" query ( "&" query )*; + + scheme = ( alpha @Mark schemec* ) ":" @SetScheme; + userinfo = userinfochar+ >Mark "@" @SetUserinfo; + host6 = "[" ( ipv6c+ >Mark %SetHost ) "]"; + host = host6 | ( ( ipv4c | hostc | telc )+ >Mark %SetHost ); + port = digit+ >Mark %SetPort; + hostport = host ( ":" port )?; + authority = userinfo? hostport; + segment = pathchar+ %AppendSegment param*; + rel_segment = relchar+ >Mark %AppendSegment; + path_segments = segment ( "/" @Mark segment )*; + abs_path = "/" @Mark path_segments; + net_path = "//" authority abs_path? >RestartSegs; + hier_part = ( net_path | abs_path ) queries?; + rel_path = rel_segment abs_path?; + opaque_part = ( urichar -- "/" ) @HandleOpaquePart; + fragment = "#" urichar* >Mark %SetFragment; + relativeURI = ( net_path | abs_path | rel_path ) queries?; + absoluteURI = scheme ( hier_part | opaque_part ); + sip := authority >Mark param*; + uri := ( relativeURI | absoluteURI )? fragment?; + }%% + + %% write init; + cs = uriparse_en_uri; + %% write exec; + + /* clang-format on */ + + if (cs >= uriparse_first_final) { + if (uri->host.n <= DNS_NAME_MAX && uri->port.n <= 6) { + return zero; + } else { + return eoverflow(); + } + } else { + return einval(); + } +} diff --git a/net/http/uriparse.svgz b/net/http/uriparse.svgz new file mode 100644 index 00000000..f6ab643b Binary files /dev/null and b/net/http/uriparse.svgz differ diff --git a/net/http/uripath.c b/net/http/uripath.c new file mode 100644 index 00000000..aef7aa3e --- /dev/null +++ b/net/http/uripath.c @@ -0,0 +1,31 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "net/http/uri.h" + +struct UriSlice uripath(const struct Uri *uri) { + if (uri->segs.i) { + return (struct UriSlice){ + uri->segs.p[0].i, + (uri->segs.p[uri->segs.i - 1].n + + (uri->segs.p[uri->segs.i - 1].i - uri->segs.p[0].i))}; + } else { + return (struct UriSlice){0, 0}; + } +} diff --git a/net/http/urischeme.c b/net/http/urischeme.c new file mode 100644 index 00000000..d91a8382 --- /dev/null +++ b/net/http/urischeme.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "net/http/geturischeme.inc" +#include "net/http/uri.h" + +/** + * Returns nonzero numeric code for resource paradigms we like. + * + * Lookups are case-insensitive and performed using a hash table that's + * literally perfect. + */ +enum UriScheme urischeme(struct UriSlice scheme, const char *str) { + const struct UriSchemeSlot *slot; + if ((slot = in_word_set(str + scheme.i, scheme.n))) { + return slot->code; + } else { + return 0; + } +} diff --git a/net/http/urislice2cstr.c b/net/http/urislice2cstr.c new file mode 100644 index 00000000..3955d5cf --- /dev/null +++ b/net/http/urislice2cstr.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" +#include "net/http/uri.h" + +char *urislice2cstr(char *buf, size_t size, struct UriSlice slice, + const char *uristr, const char *defaultval) { + /* TODO(jart): Unescape */ + if (slice.n && slice.n + 1 < size) { + memcpy(buf, uristr + slice.i, slice.n); + } else if (defaultval) { + memcpy(buf, defaultval, (slice.n = strlen(defaultval))); + } else { + slice.n = 0; + } + buf[slice.n] = '\0'; + return buf; +} diff --git a/net/net.mk b/net/net.mk new file mode 100644 index 00000000..949419a4 --- /dev/null +++ b/net/net.mk @@ -0,0 +1,5 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +.PHONY: o/$(MODE)/net +o/$(MODE)/net: o/$(MODE)/net/http diff --git a/test/ape/lib/flattenhighmemory_test.c b/test/ape/lib/flattenhighmemory_test.c new file mode 100644 index 00000000..6da4846a --- /dev/null +++ b/test/ape/lib/flattenhighmemory_test.c @@ -0,0 +1,25 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/testlib.h" + +TEST(flattenhighmemory, test) { + /* EXPECT_EQ(0, flattenhighmemory()); */ + /* EXPECT_STREQ("", flattenhighmemory()); */ +} diff --git a/test/ape/lib/getpagetableentry_test.c b/test/ape/lib/getpagetableentry_test.c new file mode 100644 index 00000000..d61eb664 --- /dev/null +++ b/test/ape/lib/getpagetableentry_test.c @@ -0,0 +1,66 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" +#include "libc/mem/mem.h" +#include "libc/runtime/gc.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(getpagetableentry, testLowestAddress) { + static struct PageTable pml4t; + static struct PageTable stack[3]; + uint64_t ptsp = (uintptr_t)&stack + sizeof(stack); + memset(&pml4t, 0, sizeof(pml4t)); + memset(&stack, 0, sizeof(stack)); + uint64_t vaddr = 0; + uint64_t paddr = 0x31337000; + *getpagetableentry(vaddr, 3, &pml4t, &ptsp) = paddr | PAGE_V; + EXPECT_EQ(&stack[2].p[0], pml4t.p[0] & PAGE_TA); /* pml4t → pdpt */ + EXPECT_EQ(&stack[1].p[0], stack[2].p[0] & PAGE_TA); /* pdpt → pdt */ + EXPECT_EQ(&stack[0].p[0], stack[1].p[0] & PAGE_TA); /* pdt → pd */ + EXPECT_EQ(stack[0].p[0] & PAGE_TA, paddr); /* page */ + EXPECT_EQ(&stack, ptsp); + EXPECT_TRUE(pml4t.p[0] & PAGE_V); + EXPECT_TRUE(stack[2].p[0] & PAGE_V); + EXPECT_TRUE(stack[1].p[0] & PAGE_V); + EXPECT_TRUE(stack[0].p[0] & PAGE_V); + EXPECT_FALSE(stack[0].p[1] & PAGE_V); +} + +TEST(getpagetableentry, testHigherAddress) { + static struct PageTable pml4t; + static struct PageTable stack[3]; + uint64_t ptsp = (uintptr_t)&stack + sizeof(stack); + memset(&pml4t, 0, sizeof(pml4t)); + memset(&stack, 0, sizeof(stack)); + uint64_t vaddr = 0x133731337000; + uint64_t paddr = 0x123000; + *getpagetableentry(vaddr, 3, &pml4t, &ptsp) = paddr | PAGE_V; + EXPECT_EQ(&stack[2].p[0], pml4t.p[38] & PAGE_TA); /* pml4t → pdpt */ + EXPECT_EQ(&stack[1].p[0], stack[2].p[220] & PAGE_TA); /* pdpt → pdt */ + EXPECT_EQ(&stack[0].p[0], stack[1].p[393] & PAGE_TA); /* pdt → pd */ + EXPECT_EQ(stack[0].p[311] & PAGE_TA, paddr); /* page */ + EXPECT_EQ(&stack, ptsp); + EXPECT_TRUE(pml4t.p[38] & PAGE_V); + EXPECT_TRUE(stack[2].p[220] & PAGE_V); + EXPECT_TRUE(stack[1].p[393] & PAGE_V); + EXPECT_TRUE(stack[0].p[311] & PAGE_V); + EXPECT_FALSE(stack[0].p[0] & PAGE_V); +} diff --git a/test/ape/lib/smapsort_test.c b/test/ape/lib/smapsort_test.c new file mode 100644 index 00000000..d1ad4c8a --- /dev/null +++ b/test/ape/lib/smapsort_test.c @@ -0,0 +1,81 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/lib/pc.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(smapsort, testEmpty_doesntOverrunBuffer) { + struct SmapEntry *smap = tmalloc(sizeof(struct SmapEntry)); + memset(smap, 0, sizeof(struct SmapEntry)); + smapsort(smap); + EXPECT_EQ(0, smap[0].addr); + EXPECT_EQ(0, smap[0].size); + tfree(smap); +} + +/* TEST(smapsort, testSorted_doesNothing) { */ +/* struct SmapEntry *smap = tmalloc(4 * sizeof(struct SmapEntry)); */ +/* memset(smap, 0, 4 * sizeof(struct SmapEntry)); */ +/* smap[0].addr = 0; */ +/* smap[0].size = 0x7000; */ +/* smap[0].type = kMemoryUsable; */ +/* smap[1].addr = 0x7000; */ +/* smap[1].size = 0x1000; */ +/* smap[1].type = kMemoryUnusable; */ +/* smap[2].addr = 0x14000; */ +/* smap[2].size = 0x1000; */ +/* smap[2].type = kMemoryBad; */ +/* smapsort(smap); */ +/* EXPECT_EQ(0, smap[0].addr); */ +/* EXPECT_EQ(0x7000, smap[0].size); */ +/* EXPECT_EQ(kMemoryUsable, smap[0].type); */ +/* EXPECT_EQ(0x7000, smap[1].addr); */ +/* EXPECT_EQ(0x1000, smap[1].size); */ +/* EXPECT_EQ(kMemoryUnusable, smap[1].type); */ +/* EXPECT_EQ(0x14000, smap[2].addr); */ +/* EXPECT_EQ(0x1000, smap[2].size); */ +/* EXPECT_EQ(kMemoryBad, smap[2].type); */ +/* tfree(smap); */ +/* } */ + +/* TEST(smapsort, testUnsorted_sortsByAddress) { */ +/* struct SmapEntry *smap = tmalloc(4 * sizeof(struct SmapEntry)); */ +/* memset(smap, 0, 4 * sizeof(struct SmapEntry)); */ +/* smap[2].addr = 0; */ +/* smap[2].size = 0x7000; */ +/* smap[2].type = kMemoryUsable; */ +/* smap[0].addr = 0x7000; */ +/* smap[0].size = 0x1000; */ +/* smap[0].type = kMemoryUnusable; */ +/* smap[1].addr = 0x14000; */ +/* smap[1].size = 0x1000; */ +/* smap[1].type = kMemoryBad; */ +/* smapsort(smap); */ +/* EXPECT_EQ(0, smap[0].addr); */ +/* EXPECT_EQ(0x7000, smap[0].size); */ +/* EXPECT_EQ(kMemoryUsable, smap[0].type); */ +/* EXPECT_EQ(0x7000, smap[1].addr); */ +/* EXPECT_EQ(0x1000, smap[1].size); */ +/* EXPECT_EQ(kMemoryUnusable, smap[1].type); */ +/* EXPECT_EQ(0x14000, smap[2].addr); */ +/* EXPECT_EQ(0x1000, smap[2].size); */ +/* EXPECT_EQ(kMemoryBad, smap[2].type); */ +/* tfree(smap); */ +/* } */ diff --git a/test/ape/lib/test.mk b/test/ape/lib/test.mk new file mode 100644 index 00000000..bc56a3cd --- /dev/null +++ b/test/ape/lib/test.mk @@ -0,0 +1,52 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_APE_LIB + +TEST_APE_LIB_SRCS := $(wildcard test/ape/lib/*.c) +TEST_APE_LIB_SRCS_TEST = $(filter %_test.c,$(TEST_APE_LIB_SRCS)) +TEST_APE_LIB_COMS = $(TEST_APE_LIB_OBJS:%.o=%.com) + +TEST_APE_LIB_OBJS = \ + $(TEST_APE_LIB_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_APE_LIB_SRCS:%.c=o/$(MODE)/%.o) + +TEST_APE_LIB_BINS = \ + $(TEST_APE_LIB_COMS) \ + $(TEST_APE_LIB_COMS:%=%.dbg) + +TEST_APE_LIB_TESTS = \ + $(TEST_APE_LIB_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_APE_LIB_CHECKS = \ + $(TEST_APE_LIB_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_APE_LIB_DIRECTDEPS = \ + APE_LIB \ + LIBC_CALLS_HEFTY \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_TESTLIB \ + LIBC_X + +TEST_APE_LIB_DEPS := \ + $(call uniq,$(foreach x,$(TEST_APE_LIB_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/ape/lib.pkg: \ + $(TEST_APE_LIB_OBJS) \ + $(foreach x,$(TEST_APE_LIB_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/ape/lib/%.com.dbg: \ + $(TEST_APE_LIB_DEPS) \ + o/$(MODE)/test/ape/lib/%.o \ + o/$(MODE)/test/ape/lib.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +.PHONY: o/$(MODE)/test/ape/lib +o/$(MODE)/test/ape/lib: $(TEST_APE_LIB_BINS) \ + $(TEST_APE_LIB_CHECKS) diff --git a/test/ape/test.mk b/test/ape/test.mk new file mode 100644 index 00000000..cd60a65f --- /dev/null +++ b/test/ape/test.mk @@ -0,0 +1,5 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +.PHONY: o/$(MODE)/test/ape +o/$(MODE)/test/ape: o/$(MODE)/test/ape/lib diff --git a/test/dsp/core/dct_test.c b/test/dsp/core/dct_test.c new file mode 100644 index 00000000..9e767607 --- /dev/null +++ b/test/dsp/core/dct_test.c @@ -0,0 +1,88 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "libc/math.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" +#include "libc/time/time.h" +#include "tool/viz/lib/formatstringtable-testlib.h" + +TEST(dct, test) { + float M[8][8] /* clang-format off */ = { + {.509804, .513725, .094118, .219608, .027451, .294118, .172549, .658824}, + {.019608, .070588, .196078, .015686, .172549, .458824, .713725, .294118}, + {.380392, .341176, .235294, .737255, .741176, .968627, .607843, .12549}, + {.560784, .843137, .639216, .929412, .756863, .113725, .643137, .435294}, + {.878431, .576471, .737255, .356863, .8, .878431, .682353, .866667}, + {.780392, .070588, .866667, .607843, .792157, .47451, .427451, .043137}, + {.133333, .976471, .698039, .662745, .035294, .207843, .831373, .627451}, + {.313725, .580392, .858824, .631373, .784314, .972549, .27451, .94902}, + } /* clang-format on */; + dctjpeg(M); + EXPECT_FLTMATRIXEQ(5, rint, 8, 8, M, "\n\ +32.86666 -1.46274 -1.4456 -.43895 -1.17255 .19084 .05736 .01672\n\ +-9.41551 -2.72135 3.7228 5.47448 .74604 .91144 -1.22542 -.41829\n\ +-6.32875 -4.21755 4.42546 -3.86307 -1.93691 -2.1173 1.00377 -1.0752\n\ +-2.58232 3.67887 5.65331 -.25753 .89732 1.09837 .93163 .61133\n\ + 4.23922 1.36747 3.29469 -1.63407 2.78039 -3.0021 .7602 -.21367\n\ + -.11643 3.93022 .80678 -3.70514 .13347 .54381 -2.15087 -.52343\n\ + .64248 1.19093 -2.94494 2.66037 1.6624 .04414 .99807 .00514\n\ + .61622 -.76318 .75918 .41939 -.38075 -.30623 .09867 -.19237"); +} + +/* TEST(dct, test2) { */ +/* float M[8][8] /\* clang-format off *\/ = { */ +/* {.5,.5,.5,.5,.5,.5,.5,.5}, */ +/* {.5,.5,.5,.5,.5,.5,.5,.5}, */ +/* {.5,.5,.5,.5,.5,.5,.5,.5}, */ +/* {.5,.5,.5,.5,.5,.5,.5,.5}, */ +/* {.5,.5,.5,.5,.5,.5,.5,.5}, */ +/* {.5,.5,.5,.5,.5,.5,.5,.5}, */ +/* {.5,.5,.5,.5,.5,.5,.5,.5}, */ +/* {.5,.5,.5,.5,.5,.5,.5,.5}, */ +/* } /\* clang-format on *\/; */ +/* dctjpeg(M); */ +/* EXPECT_FLTMATRIXEQ(5, rint, 8, 8, M, "\n\ */ +/* 32.86666 -1.46274 -1.4456 -.43895 -1.17255 .19084 .05736 .01672\n\ */ +/* -9.41551 -2.72135 3.7228 5.47448 .74604 .91144 -1.22542 -.41829\n\ */ +/* -6.32875 -4.21755 4.42546 -3.86307 -1.93691 -2.1173 1.00377 -1.0752\n\ */ +/* -2.58232 3.67887 5.65331 -.25753 .89732 1.09837 .93163 .61133\n\ */ +/* 4.23922 1.36747 3.29469 -1.63407 2.78039 -3.0021 .7602 -.21367\n\ */ +/* -.11643 3.93022 .80678 -3.70514 .13347 .54381 -2.15087 -.52343\n\ */ +/* .64248 1.19093 -2.94494 2.66037 1.6624 .04414 .99807 .00514\n\ */ +/* .61622 -.76318 .75918 .41939 -.38075 -.30623 .09867 -.19237"); */ +/* } */ + +BENCH(dct, bench) { + float M[8][8] /* clang-format off */ = { + {.101961, .486275, .082353, .082353, .937255, .321569, .14902, .270588}, + {.384314, .062745, .152941, .003922, .921569, .015686, .247059, 0}, + {.760784, .023529, .411765, .443137, .862745, .85098, .435294, .631373}, + {.309804, .141176, .54902, .984314, .478431, .6, .364706, .643137}, + {.780392, .811765, .458824, .964706, .439216, .941176, .321569, .313725}, + {.596078, .207843, .133333, .345098, .278431, .192157, .52549, .627451}, + {.952941, .090196, .290196, .717647, .686275, .713725, .54902, .411765}, + {.109804, .121569, .403922, .27451, .470588, .007843, .168627, .105882}, + } /* clang-format on */; + void *data = tgc(tmalloc(sizeof(M))); + EZBENCH2("dct", memcpy(data, M, sizeof(M)), EXPROPRIATE(dctjpeg(data))); +} diff --git a/test/dsp/core/dgemm_test.c b/test/dsp/core/dgemm_test.c new file mode 100644 index 00000000..f396cb91 --- /dev/null +++ b/test/dsp/core/dgemm_test.c @@ -0,0 +1,65 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/xmmintrin.h" +#include "libc/log/log.h" +#include "libc/macros.h" +#include "libc/math.h" +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" +#include "third_party/blas/blas.h" +#include "tool/viz/lib/formatstringtable-testlib.h" + +TEST(dgemm, test) { + double alpha, beta; + long m, n, k, lda, ldb, ldc; + double A[3][3] = {{1 / 8.}, {6 / 8.}, {1 / 8.}}; + double B[1][3] = {{1 / 8., 6 / 8., 1 / 8.}}; + double C[3][3] = {0}; + m = 3; + n = 3; + k = 1; + lda = 3; + ldb = 3; + ldc = 3; + beta = 1; + alpha = 1; + dgemm_("T", "T", &m, &n, &k, &alpha, &A[0][0], &lda, &B[0][0], &ldb, &beta, + &C[0][0], &ldc); + EXPECT_DBLMATRIXEQ(6, rint, 3, 3, C, "\n\ +.015625 .09375 .015625\n\ + .09375 .5625 .09375\n\ +.015625 .09375 .015625"); +} + +void dgemmer(long m, long n, long k, void *A, long lda, void *B, long ldb, + void *C, long ldc) { + double alpha, beta; + beta = 1; + alpha = 1; + dgemm_("N", "N", &m, &n, &k, &alpha, A, &lda, B, &ldb, &beta, C, &ldc); +} + +BENCH(dgemm, bench) { + double(*A)[128][128] = tgc(tmalloc(128 * 128 * 8)); + double(*B)[128][128] = tgc(tmalloc(128 * 128 * 8)); + double(*C)[128][128] = tgc(tmalloc(128 * 128 * 8)); + EZBENCH2("dgemm_", donothing, dgemmer(128, 128, 128, A, 128, B, 128, C, 128)); +} diff --git a/test/dsp/core/float2short_test.c b/test/dsp/core/float2short_test.c new file mode 100644 index 00000000..bacbcb77 --- /dev/null +++ b/test/dsp/core/float2short_test.c @@ -0,0 +1,84 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "dsp/mpeg/mpeg.h" +#include "libc/log/check.h" +#include "libc/macros.h" +#include "libc/rand/rand.h" +#include "libc/runtime/buffer.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +short pcm[8][8]; +float binary32[8][8]; +struct GuardedBuffer b1, b2; + +TEST(float2short, test) { + binary32[0][0] = -0.5; + binary32[0][1] = 0.0; + binary32[0][2] = 0.5; + float2short(8, pcm, binary32); + EXPECT_EQ(-16384, pcm[0][0]); + EXPECT_EQ(0, pcm[0][1]); + EXPECT_EQ(16384, pcm[0][2]); +} + +TEST(float2short, testOverflow) { + binary32[0][0] = -1.1; + binary32[0][1] = -1.0; + binary32[0][2] = 1.0; + binary32[0][3] = 1.1; + float2short(8, pcm, binary32); + EXPECT_EQ(-32768, pcm[0][0]); + EXPECT_EQ(-32768, pcm[0][1]); + EXPECT_EQ(32767, pcm[0][2]); + EXPECT_EQ(32767, pcm[0][3]); +} + +void unclamped(size_t n, short pcm16[n][8], const float binary32[n][8]) { + size_t i, j; + for (i = 0; i < n; ++i) { + for (j = 0; j < 8; ++j) { + pcm16[i][j] = binary32[i][j] * 32768; + } + } +} + +plm_samples_t samps; + +void randomizeaudio(void) { + size_t i; + for (i = 0; i < ARRAYLEN(samps.interleaved); ++i) { + samps.interleaved[i] = randf(); + } +} + +void float2short_pure(void) { + float2short(ARRAYLEN(samps.interleaved) / 8, pcm, (void *)samps.interleaved); +} + +void float2short_unclamped(void) { + unclamped(ARRAYLEN(samps.interleaved) / 8, pcm, (void *)samps.interleaved); +} + +BENCH(float2short, audioframe) { + EZBENCH(randomizeaudio(), float2short_pure()); + EZBENCH(randomizeaudio(), float2short_unclamped()); +} diff --git a/test/dsp/core/gamma_test.c b/test/dsp/core/gamma_test.c new file mode 100644 index 00000000..80d4c1f9 --- /dev/null +++ b/test/dsp/core/gamma_test.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "libc/math.h" +#include "libc/testlib/testlib.h" + +TEST(gamma, test) { + int i; + double g, x, a, b; + g = 2.4; + for (i = 0; i < 256; ++i) { + x = i; + x /= 255; + a = rgb2stdpc(x, g); + b = tv2pcgamma(rgb2stdtv(x), g); + ASSERT_EQ(true, fabs(a - b) < .000000001, "%d %f %f %f", i, x, a, b); + } +} diff --git a/test/dsp/core/getintegercoefficients8_test.c b/test/dsp/core/getintegercoefficients8_test.c new file mode 100644 index 00000000..d789deba --- /dev/null +++ b/test/dsp/core/getintegercoefficients8_test.c @@ -0,0 +1,62 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "dsp/core/q.h" +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +long I[8]; + +TEST(GetIntegerCoefficients8, testBt601Vectors) { + const struct { + int m, L, H; + double r[8]; + long n[8]; + } V[] = { + {8, 16, 235, {.299, .587, .114}, {77, 150, 29}}, + {9, 16, 235, {.299, .587, .114}, {153, 301, 58}}, + {10, 16, 235, {.299, .587, .114}, {306, 601, 117}}, + {11, + 16, + 235, + {.299, .587, .114, 1, 1, 1}, + {612, 1202, 234, 2048, 2048, 2048}}, + {12, 16, 235, {.299, .587, .114}, {1225, 2404, 467}}, + {13, 16, 235, {.299, .587, .114}, {2449, 4809, 934}}, + {14, 16, 235, {.299, .587, .114}, {4899, 9617, 1868}}, + {15, 16, 235, {.299, .587, .114}, {9798, 19235, 3735}}, + {16, 16, 235, {.299, .587, .114}, {19595, 38470, 7471}}, + }; + long i, got[8]; + for (i = 0; i < ARRAYLEN(V); ++i) { + GetIntegerCoefficients8(got, V[i].r, V[i].m, V[i].L, V[i].H); + EXPECT_EQ(0, memcmp(V[i].n, got, sizeof(got)), + "got={%ld,%ld,%ld,%ld,%ld,%ld}, want={%ld,%ld,%ld,%ld,%ld,%ld}", + got[0], got[1], got[2], got[3], got[4], got[5], V[i].n[0], + V[i].n[1], V[i].n[2], V[i].n[3], V[i].n[4], V[i].n[5]); + } +} + +BENCH(GetIntegerCoefficients8, bench) { + double C[8] = {.299, .587, .114, .299, .587, .114, .114, .114}; + EZBENCH2("GetIntegerCoefficients8", donothing, + GetIntegerCoefficients8(I, C, 11, 16, 232)); +} diff --git a/test/dsp/core/getintegercoefficients_test.c b/test/dsp/core/getintegercoefficients_test.c new file mode 100644 index 00000000..58393efc --- /dev/null +++ b/test/dsp/core/getintegercoefficients_test.c @@ -0,0 +1,89 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "dsp/core/q.h" +#include "libc/macros.h" +#include "libc/runtime/gc.h" +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +long I[6]; + +TEST(GetIntegerCoefficients, testBt601Vectors) { + const struct { + int m, L, H; + double r[6]; + long n[6]; + } V[] = { + {8, 16, 235, {.299, .587, .114}, {77, 150, 29}}, + {9, 16, 235, {.299, .587, .114}, {153, 301, 58}}, + {10, 16, 235, {.299, .587, .114}, {306, 601, 117}}, + {11, + 16, + 235, + {.299, .587, .114, 1, 1, 1}, + {612, 1202, IsTiny() ? 233 : 234, 2048, 2048, 2048}}, + {12, 16, 235, {.299, .587, .114}, {1225, 2404, 467}}, + {13, 16, 235, {.299, .587, .114}, {2449, 4809, 934}}, + {14, 16, 235, {.299, .587, .114}, {4899, 9617, 1868}}, + {15, 16, 235, {.299, .587, .114}, {9798, 19235, IsTiny() ? 3736 : 3735}}, + {16, 16, 235, {.299, .587, .114}, {19595, 38470, 7471}}, + }; + long i, got[6]; + for (i = 0; i < ARRAYLEN(V); ++i) { + GetIntegerCoefficients(got, V[i].r, V[i].m, V[i].L, V[i].H); + EXPECT_EQ(0, memcmp(V[i].n, got, sizeof(got)), + "got={%ld,%ld,%ld,%ld,%ld,%ld}, want={%ld,%ld,%ld,%ld,%ld,%ld}", + got[0], got[1], got[2], got[3], got[4], got[5], V[i].n[0], + V[i].n[1], V[i].n[2], V[i].n[3], V[i].n[4], V[i].n[5]); + } +} + +TEST(GetIntegerCoefficients, testForYCbCr2Rgb) { + double C[6] = {.299, .587, .114}; + GetIntegerCoefficients(I, C, 11, 16, 232); + EXPECT_EQ(612, I[0]); + EXPECT_EQ(1202, I[1]); + EXPECT_EQ(IsTiny() ? 233 : 234, I[2]); +} + +TEST(GetIntegerCoefficients, testForGaussian) { +#define G(A, B, C, D, E) lrint((A + 4 * B + 6 * C + 4 * D + E) / 16.) + double C[6] = {1 / 16., 4 / 16., 6 / 16., 4 / 16., 1 / 16.}; + long M = 22, N[6], B[6] = {12, 191, 174, 205, 35}; + GetIntegerCoefficients(N, C, M, 0, 255); + EXPECT_EQ(262144, N[0]); + EXPECT_EQ(1048576, N[1]); + EXPECT_EQ(1572864, N[2]); + EXPECT_EQ(1048576, N[3]); + EXPECT_EQ(262144, N[4]); + EXPECT_EQ(G(B[0], B[1], B[2], B[3], B[4]), + (N[0] * B[0] + N[1] * B[1] + N[2] * B[2] + N[3] * B[3] + + N[4] * B[4] + N[5] * B[5] + (1l << (M - 1))) >> + M); +} + +BENCH(GetIntegerCoefficients, bench) { + double C[6] = {.299, .587, .114}; + EZBENCH2("getintegercoefficients", donothing, + GetIntegerCoefficients(I, C, 11, 16, 232)); +} diff --git a/test/dsp/core/illumination_test.c b/test/dsp/core/illumination_test.c new file mode 100644 index 00000000..b9034fbf --- /dev/null +++ b/test/dsp/core/illumination_test.c @@ -0,0 +1,50 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "dsp/core/illumination.h" +#include "libc/log/log.h" +#include "libc/math.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" +#include "tool/viz/lib/formatstringtable-testlib.h" + +TEST(GetChromaticAdaptationMatrix, testSuperiorIlluminationBannedInCalifornia) { + double M[3][3]; + GetChromaticAdaptationMatrix(M, kIlluminantD65, kIlluminantA); + EXPECT_DBLMATRIXEQ(5, rint, 3, 3, M, "\n\ +1.21646 .11099 -.15493\n\ + .15333 .91523 -.056\n\ +-.02395 .0359 .31475"); +} + +TEST(GetChromaticAdaptationMatrix, testD65ToD50_soWeCanCieLab) { + double M[3][3]; + GetChromaticAdaptationMatrix(M, kIlluminantD65, kIlluminantD50); + EXPECT_DBLMATRIXEQ(6, rint, 3, 3, M, "\n\ +1.047811 .022887 -.050127\n\ + .029542 .990484 -.017049\n\ +-.009234 .015044 .752132"); +} + +BENCH(GetChromaticAdaptationMatrix, bench) { + double M[3][3]; + EZBENCH2("GetChromaticAdaptationMatrix", donothing, + GetChromaticAdaptationMatrix(M, kIlluminantD65, kIlluminantA)); +} diff --git a/test/dsp/core/inv3_test.c b/test/dsp/core/inv3_test.c new file mode 100644 index 00000000..3cd54be0 --- /dev/null +++ b/test/dsp/core/inv3_test.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "dsp/core/illumination.h" +#include "libc/math.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" +#include "tool/viz/lib/formatstringtable-testlib.h" + +TEST(inv3, test) { + double M[3][3]; + inv3(M, kBradford, det3(kBradford)); + EXPECT_DBLMATRIXEQ(7, rint, 3, 3, M, "\n\ + .9869929 -.1470543 .1599627\n\ + .4323053 .5183603 .0492912\n\ +-.0085287 .0400428 .9684867"); +} + +BENCH(inv3, bench) { + double M[3][3], d; + EZBENCH2("det3", donothing, EXPROPRIATE((d = det3(kBradford)))); + EZBENCH2("inv3", donothing, EXPROPRIATE(inv3(M, kBradford, d))); +} diff --git a/test/dsp/core/sad16x8n_test.c b/test/dsp/core/sad16x8n_test.c new file mode 100644 index 00000000..861a4ce6 --- /dev/null +++ b/test/dsp/core/sad16x8n_test.c @@ -0,0 +1,108 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "dsp/mpeg/mpeg.h" +#include "libc/limits.h" +#include "libc/log/check.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/rand/rand.h" +#include "libc/runtime/buffer.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +void addsw$pure(size_t n, short x[n][8], const short y[n][8]) { + size_t i, j; + for (i = 0; i < n; ++i) { + for (j = 0; j < 8; ++j) { + x[i][j] = MIN(MAX(x[i][j] + y[i][j], INT16_MIN), INT16_MAX); + } + } +} + +short *pcm1; +short *pcm2; +struct GuardedBuffer b1, b2; + +TEST(sad16x8n, test) { + CHECK_NOTNULL((pcm1 = balloc(&b1, 32, 128 * 2))); + CHECK_NOTNULL((pcm2 = balloc(&b2, 32, 128 * 2))); + pcm1[0] = 0; + pcm2[0] = 0; + pcm1[1] = 23; + pcm2[1] = 10; + pcm1[2] = 23; + pcm2[2] = -10; + pcm1[3] = 23; + pcm2[3] = -46; + pcm1[120 + 0] = 0; + pcm2[120 + 0] = 0; + pcm1[120 + 1] = 23; + pcm2[120 + 1] = 10; + pcm1[120 + 2] = 23; + pcm2[120 + 2] = -10; + pcm1[120 + 3] = 23; + pcm2[120 + 3] = -46; + sad16x8n(128 / 8, (void *)pcm1, (void *)pcm2); + EXPECT_EQ(0, pcm1[0]); + EXPECT_EQ(33, pcm1[1]); + EXPECT_EQ(13, pcm1[2]); + EXPECT_EQ(-23, pcm1[3]); + EXPECT_EQ(0, pcm1[120 + 0]); + EXPECT_EQ(33, pcm1[120 + 1]); + EXPECT_EQ(13, pcm1[120 + 2]); + EXPECT_EQ(-23, pcm1[120 + 3]); + bfree(&b1); + bfree(&b2); +} + +////////////////////////////////////////////////////////////////////// +// audio frame mixing latency: ~60ns (sse2 10x faster than pure) +// +// 1f ~= 14ms (cd quality) +// (1.0 / 41000) * (1.0 / 2) * (1152 / 1.0) +// +// 1f ~= 845µs (dolby truehd) +// (1.0 / 192000) * (1.0 / 7.1) * (1152 / 1.0) +// +// @note plm frame always has exactly 1152 floats + +void randomizeaudio(void) { + size_t i; + for (i = 0; i < PLM_AUDIO_SAMPLES_PER_FRAME; ++i) { + pcm1[i] = (rand() - INT_MAX / 2) % INT16_MAX; + pcm2[i] = (rand() - INT_MAX / 2) % INT16_MAX; + } +} + +void sad16x8n_sse2(void) { + sad16x8n(PLM_AUDIO_SAMPLES_PER_FRAME / 8, (void *)pcm1, (void *)pcm2); +} +void sad16x8n_pure(void) { + addsw$pure(PLM_AUDIO_SAMPLES_PER_FRAME / 8, (void *)pcm1, (void *)pcm2); +} + +BENCH(sad16x8n, audioframe) { + CHECK_NOTNULL((pcm1 = balloc(&b1, 32, PLM_AUDIO_SAMPLES_PER_FRAME * 2))); + CHECK_NOTNULL((pcm2 = balloc(&b2, 32, PLM_AUDIO_SAMPLES_PER_FRAME * 2))); + EZBENCH(randomizeaudio(), sad16x8n_pure()); + EZBENCH(randomizeaudio(), sad16x8n_sse2()); + bfree(&b1); + bfree(&b2); +} diff --git a/test/dsp/core/scalevolume_test.c b/test/dsp/core/scalevolume_test.c new file mode 100644 index 00000000..1de3d110 --- /dev/null +++ b/test/dsp/core/scalevolume_test.c @@ -0,0 +1,161 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/core.h" +#include "dsp/mpeg/mpeg.h" +#include "libc/limits.h" +#include "libc/log/check.h" +#include "libc/macros.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/rand/rand.h" +#include "libc/runtime/buffer.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +short pcm[8][8]; + +TEST(scalevolume, testIncreaseVolumeByOneIncrement) { + pcm[0][0] = INT16_MIN; + pcm[0][1] = INT16_MIN / 2; + pcm[0][2] = -2; + pcm[0][3] = -1; + pcm[0][4] = 0; + pcm[0][5] = 1; + pcm[0][6] = 2; + pcm[0][7] = INT16_MAX / 2; + pcm[1][0] = INT16_MAX; + scalevolume(ARRAYLEN(pcm), pcm, 1); + EXPECT_EQ(INT16_MIN, pcm[0][0]); + EXPECT_EQ(INT16_MIN, pcm[0][1]); + EXPECT_EQ(-4, pcm[0][2]); + EXPECT_EQ(-2, pcm[0][3]); + EXPECT_EQ(0, pcm[0][4]); + EXPECT_EQ(2, pcm[0][5]); + EXPECT_EQ(4, pcm[0][6]); + EXPECT_EQ(INT16_MAX - 1, pcm[0][7]); + EXPECT_EQ(INT16_MAX, pcm[1][0]); +} + +TEST(scalevolume, testDecreaseVolumeByOneIncrement) { + pcm[0][0] = INT16_MIN; + pcm[0][1] = INT16_MIN / 2; + pcm[0][2] = -2; + pcm[0][3] = -1; + pcm[0][4] = 0; + pcm[0][5] = 1; + pcm[0][6] = 2; + pcm[0][7] = INT16_MAX / 2; + pcm[1][0] = INT16_MAX; + scalevolume(ARRAYLEN(pcm), pcm, -1); + EXPECT_EQ(INT16_MIN / 2, pcm[0][0]); + EXPECT_EQ(INT16_MIN / 4, pcm[0][1]); + EXPECT_EQ(-1, pcm[0][2]); + EXPECT_EQ(-1, pcm[0][3]); + EXPECT_EQ(0, pcm[0][4]); + EXPECT_EQ(0, pcm[0][5]); + EXPECT_EQ(1, pcm[0][6]); + EXPECT_EQ(INT16_MAX / 4, pcm[0][7]); + EXPECT_EQ(INT16_MAX / 2, pcm[1][0]); +} + +TEST(scalevolume, testScaleByZero_doesNothing) { + pcm[0][0] = INT16_MIN; + pcm[0][1] = INT16_MIN / 2; + pcm[0][2] = -2; + pcm[0][3] = -1; + pcm[0][4] = 0; + pcm[0][5] = 1; + pcm[0][6] = 2; + pcm[0][7] = INT16_MAX / 2; + pcm[1][0] = INT16_MAX; + scalevolume(ARRAYLEN(pcm), pcm, 0); + EXPECT_EQ(INT16_MIN, pcm[0][0]); + EXPECT_EQ(INT16_MIN / 2, pcm[0][1]); + EXPECT_EQ(-2, pcm[0][2]); + EXPECT_EQ(-1, pcm[0][3]); + EXPECT_EQ(0, pcm[0][4]); + EXPECT_EQ(1, pcm[0][5]); + EXPECT_EQ(2, pcm[0][6]); + EXPECT_EQ(INT16_MAX / 2, pcm[0][7]); + EXPECT_EQ(INT16_MAX, pcm[1][0]); +} + +TEST(scalevolume, testBiggestScale_justSaturates) { + pcm[0][0] = INT16_MIN; + pcm[0][1] = INT16_MIN / 2; + pcm[0][2] = -2; + pcm[0][3] = -1; + pcm[0][4] = 0; + pcm[0][5] = 1; + pcm[0][6] = 2; + pcm[0][7] = INT16_MAX / 2; + pcm[1][0] = INT16_MAX; + scalevolume(ARRAYLEN(pcm), pcm, 123); + EXPECT_EQ(INT16_MIN, pcm[0][0]); + EXPECT_EQ(INT16_MIN, pcm[0][1]); + EXPECT_EQ(INT16_MIN, pcm[0][2]); + EXPECT_EQ(INT16_MIN, pcm[0][3]); + EXPECT_EQ(0, pcm[0][4]); + EXPECT_EQ(INT16_MAX, pcm[0][5]); + EXPECT_EQ(INT16_MAX, pcm[0][6]); + EXPECT_EQ(INT16_MAX, pcm[0][7]); + EXPECT_EQ(INT16_MAX, pcm[1][0]); +} + +TEST(scalevolume, testSmallestScale_justSaturates) { + pcm[0][0] = INT16_MIN; + pcm[0][1] = INT16_MIN / 2; + pcm[0][2] = -2; + pcm[0][3] = -1; + pcm[0][4] = 0; + pcm[0][5] = 1; + pcm[0][6] = 2; + pcm[0][7] = INT16_MAX / 2; + pcm[1][0] = INT16_MAX; + scalevolume(ARRAYLEN(pcm), pcm, -123); + EXPECT_EQ(-1, pcm[0][0]); + EXPECT_EQ(-1, pcm[0][1]); + EXPECT_EQ(-1, pcm[0][2]); + EXPECT_EQ(-1, pcm[0][3]); + EXPECT_EQ(0, pcm[0][4]); + EXPECT_EQ(0, pcm[0][5]); + EXPECT_EQ(0, pcm[0][6]); + EXPECT_EQ(0, pcm[0][7]); + EXPECT_EQ(0, pcm[1][0]); +} + +////////////////////////////////////////////////////////////////////// +// audio volume adjustment latency: +// - ~1µs w/ -Os +// - ~500ns w/ -O3 +// - ~200ns w/ -O3 -march=skylake MODE=rel + +void randomizeaudio(void) { + rngset(pcm, sizeof(pcm), rand64, -1); +} + +void scalevolume_pure(int amt) { + scalevolume(ARRAYLEN(pcm), pcm, amt); +} + +BENCH(scalevolume, audioframe) { + EZBENCH(randomizeaudio(), scalevolume_pure(0)); + EZBENCH(randomizeaudio(), scalevolume_pure(1)); + EZBENCH(randomizeaudio(), scalevolume_pure(15)); +} diff --git a/test/dsp/core/test.mk b/test/dsp/core/test.mk new file mode 100644 index 00000000..cd4c9576 --- /dev/null +++ b/test/dsp/core/test.mk @@ -0,0 +1,51 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_DSP_CORE + +TEST_DSP_CORE_SRCS := $(wildcard test/dsp/core/*.c) +TEST_DSP_CORE_SRCS_TEST = $(filter %_test.c,$(TEST_DSP_CORE_SRCS)) +TEST_DSP_CORE_COMS = $(TEST_DSP_CORE_OBJS:%.o=%.com) +TEST_DSP_CORE_BINS = $(TEST_DSP_CORE_COMS) $(TEST_DSP_CORE_COMS:%=%.dbg) + +TEST_DSP_CORE_OBJS = \ + $(TEST_DSP_CORE_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_DSP_CORE_SRCS:%.c=o/$(MODE)/%.o) + +TEST_DSP_CORE_TESTS = \ + $(TEST_DSP_CORE_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_DSP_CORE_CHECKS = \ + $(TEST_DSP_CORE_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_DSP_CORE_DIRECTDEPS = \ + DSP_CORE \ + DSP_MPEG \ + LIBC_TINYMATH \ + LIBC_LOG \ + LIBC_RUNTIME \ + LIBC_RAND \ + LIBC_TESTLIB \ + TOOL_VIZ_LIB \ + THIRD_PARTY_BLAS \ + THIRD_PARTY_COMPILER_RT + +TEST_DSP_CORE_DEPS := \ + $(call uniq,$(foreach x,$(TEST_DSP_CORE_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/dsp/core/core.pkg: \ + $(TEST_DSP_CORE_OBJS) \ + $(foreach x,$(TEST_DSP_CORE_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/dsp/core/%.com.dbg: \ + $(TEST_DSP_CORE_DEPS) \ + o/$(MODE)/test/dsp/core/%.o \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +.PHONY: o/$(MODE)/test/dsp/core +o/$(MODE)/test/dsp/core: \ + $(TEST_DSP_CORE_BINS) \ + $(TEST_DSP_CORE_CHECKS) diff --git a/test/dsp/scale/magikarp_test.c b/test/dsp/scale/magikarp_test.c new file mode 100644 index 00000000..60dd1ec3 --- /dev/null +++ b/test/dsp/scale/magikarp_test.c @@ -0,0 +1,155 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/scale/scale.h" +#include "libc/fmt/bing.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" +#include "tool/viz/lib/formatstringtable-testlib.h" + +TEST(magikarp, testConvolve) { + signed char K[8] = {-1, -3, 3, 17, 17, 3, -3, -1}; + EXPECT_BINEQ( + u"λλ  λλ  λλ  λλ  " + u"λλ  λλ  λλ  λλ  " + u"λλ  λλ  λλ  λλ  ", + cDecimate2xUint8x8(32 * 3, + tgc(tunbing(u"λλλλ    λλλλ    λλλλ    λλλλ    " + u"λλλλ    λλλλ    λλλλ    λλλλ    " + u"λλλλ    λλλλ    λλλλ    λλλλ    ")), + K)); +} + +TEST(magikarp, testConvolveMin1) { + signed char K[8] = {-1, -3, 3, 17, 17, 3, -3, -1}; + EXPECT_BINEQ( + u"λλ  λλ  λλ  λλ  " + u"λλ  λλ  λλ  λλ  " + u"λλ  λλ  λλ  λλ  ", + cDecimate2xUint8x8(32 * 3 - 1, + tgc(tunbing(u"λλλλ    λλλλ    λλλλ    λλλλ    " + u"λλλλ    λλλλ    λλλλ    λλλλ    " + u"λλλλ    λλλλ    λλλλ    λλλλ   ")), + K)); +} + +TEST(magikarp, testConvolve2) { + signed char K[8] = {-1, -3, 3, 17, 17, 3, -3, -1}; + EXPECT_BINEQ( + u" ☻♣•○♂♪☼◄‼§↨↓←↔▼" + u"!#%‘)+-/13579;=⁇" + u"ACEGIKMOQSUWY[]_" + u"acegikmoqsuwy{}⌂" + u"üâàçëïìÅæôòùÖ¢¥ƒ" + u"íúѺ⌐½¡»▒│╡╖╣╗╜┐" + u"┴├┼╟╔╦═╧╤╙╒╫┘█▌▀" + u"ßπστΘδφ∩±≤⌡≈∙√²λ", + cDecimate2xUint8x8(256, + tgc(tunbing(u" ☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼" + u" !“#$%&‘()*+,-./0123456789:;<=>⁇" + u"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[╲]^_" + u"`abcdefghijklmnopqrstuvwxyz{|}~⌂" + u"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥€ƒ" + u"áíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐" + u"└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀" + u"αßΓπΣσμτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■λ")), + K)); +} + +const char kDieWelle[] = "\ +nnooooooppppppppppqqqqqqqqqqqqqqqqqqqqqqqqqppppppppppoooooonn\ +ooooooppppppppqqqqqqqqqqpppppppppppppqqqqqqqqqqppppppppoooooo\ +oooopppppppqqqqqqqpppppppppppppppppppppppppqqqqqqqpppppppoooo\ +oopppppppqqqqqqppppppppppoooooooooooppppppppppqqqqqqpppppppoo\ +pppppppqqqqqpppppppoooooooonnnnnnnoooooooopppppppqqqqqppppppp\ +pppppqqqqqppppppooooonnnnnnnmmmmmnnnnnnnoooooppppppqqqqqppppp\ +ppppqqqqppppppooonnnnnmmmmmmmmmmmmmmmmmnnnnnoooppppppqqqqpppp\ +ppqqqqqpppppooonnnmmmmmlllllllllllllllmmmmmnnnooopppppqqqqqpp\ +pqqqqqppppooonnnmmmmlllllllllllllllllllllmmmmnnnoooppppqqqqqp\ +qqqqpppppooonnmmmlllllllllllllllllllllllllllmmmnnooopppppqqqq\ +qqqqppppooonnmmmllllllllllllmmmmmllllllllllllmmmnnoooppppqqqq\ +qqqppppooonnmmmlllllllllmmmnnnnnnnmmmlllllllllmmmnnoooppppqqq\ +qqpppppoonnmmmllllllllmmnoopqqqqqpoonmmllllllllmmmnnoopppppqq\ +qqppppooonnmmllllllllmnnpqrsuvvvusrqpnnmllllllllmmnnoooppppqq\ +qqppppoonnmmmlllllllmmnpqsuxyyyyyxusqpnmmlllllllmmmnnooppppqq\ +qqppppoonnmmmlllllllmnoprtxyyyyyyyxtrponmlllllllmmmnnooppppqq\ +qqppppoonnmmmlllllllmnoprtwyyyyyyywtrponmlllllllmmmnnooppppqq\ +qqppppoonnnmmlllllllmmnoprtvxyyyxvtrponmmlllllllmmnnnooppppqq\ +qqppppooonnmmllllllllmmnopqrsssssrqponmmllllllllmmnnoooppppqq\ +qqqppppoonnnmmlllllllllmmnnoopppoonnmmlllllllllmmnnnooppppqqq\ +qqqpppppoonnmmmllllllllllmmmmmmmmmmmllllllllllmmmnnoopppppqqq\ +qqqqppppooonnnmmmlllllllllllllllllllllllllllmmmnnnoooppppqqqq\ +pqqqqpppppoonnnmmmlllllllllllllllllllllllllmmmnnnoopppppqqqqp\ +ppqqqqpppppooonnnmmmmlllllllllllllllllllmmmmnnnooopppppqqqqpp\ +pppqqqqppppppooonnnnmmmmmlllllllllllmmmmmnnnnoooppppppqqqqppp\ +ppppqqqqqppppppoooonnnnnmmmmmmmmmmmmmnnnnnooooppppppqqqqqpppp\ +ppppppqqqqqpppppppooooonnnnnnnnnnnnnnnooooopppppppqqqqqpppppp\ +opppppppqqqqqppppppppoooooooooooooooooooppppppppqqqqqpppppppo\ +ooopppppppqqqqqqpppppppppppppppppppppppppppppqqqqqqpppppppooo\ +ooooopppppppqqqqqqqqqpppppppppppppppppppqqqqqqqqqpppppppooooo\ +noooooopppppppppqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpppppppppoooooon\ +nnnooooooopppppppppppqqqqqqqqqqqqqqqqqqqpppppppppppooooooonnn"; + +TEST(magikarp, testHalfYX) { + static unsigned char M[32][61]; + memcpy(M, kDieWelle, sizeof(M)); + Magikarp2xY(32, 61, M, 32, 61); + Magikarp2xX(32, 61, M, 16, 61); + EXPECT_STREQ(u"\n\ +nooppppqqqqqqqqqqqqqqqqqpppooon\n\ +opppqqqqqppppoppoppppqqqqqppppo\n\ +ppqqqqpppooooommmoooopppqqqqppp\n\ +pqqqppponmmllllllllmmmnpppqqqqp\n\ +qqqppoomllllllllllllllmnoppqqqq\n\ +qqppoomlllllllmmmllllllmnoppqqq\n\ +qppponlllllmoqttspnlllllmnoppqq\n\ +qpponmllllmosyzz{vqnllllmmoppqq\n\ +qpponmllllmorwzzyupnllllmmoppqq\n\ +qqpponlllllloprrqomlllllmnoppqq\n\ +qqpponnmlllllllllllllllmnnppqqq\n\ +qqqppponmlllllllllllllnooppqqqp\n\ +pqqqqpppoommmlllllmmmoopppqqqpp\n\ +pppqqqqpppooooooooooppppqqqqppp\n\ +oopppqqqqqqpppppppppqqqqqqpppoo\n\ +noopopppqqqqqqqqqqqqqqqppoooonn", + gc(bingblit(32, 61, M, 16, 31))); +} + +#define HDX (1920 / 4) +#define HDY (1080 / 4) + +BENCH(magikarp, bench) { /* 30ms */ + unsigned char kMagkern[16] = {4, 12, 12, 4}; + signed char kMagikarp[16] = {-1, -3, 3, 17, 17, 3, -3, -1}; + unsigned char(*Me)[HDY][HDX] = tgc(tmalloc((HDX + 1) * (HDY + 1))); + unsigned char(*Mo)[HDY][HDX] = tgc(tmalloc((HDX + 1) * (HDY + 1))); + if (X86_HAVE(AVX)) { + EZBENCH2("Decimate2xUint8x8", donothing, + cDecimate2xUint8x8((HDX * HDY - 16 - 8) / 2 / 8 * 8, (void *)Me, + kMagikarp)); + } + EZBENCH2("cDecimate2xUint8x8", donothing, + cDecimate2xUint8x8((HDX * HDY - 16 - 8) / 2 / 8 * 8, (void *)Me, + kMagikarp)); + EZBENCH2("Magikarp2xY", donothing, Magikarp2xY(HDY, HDX, *Me, HDY, HDX)); + EZBENCH2("Magikarp2xX", donothing, Magikarp2xX(HDY, HDX, *Mo, HDY, HDX)); +} diff --git a/test/dsp/scale/scale_test.c b/test/dsp/scale/scale_test.c new file mode 100644 index 00000000..fafedba5 --- /dev/null +++ b/test/dsp/scale/scale_test.c @@ -0,0 +1,423 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/c1331.h" +#include "dsp/core/c161.h" +#include "dsp/core/core.h" +#include "dsp/core/half.h" +#include "dsp/scale/scale.h" +#include "libc/fmt/bing.h" +#include "libc/macros.h" +#include "libc/mem/mem.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" +#include "tool/viz/lib/formatstringtable-testlib.h" + +void *AbsoluteDifference(int yn, int xn, unsigned char C[yn][xn], int ays, + int axs, const unsigned char A[ays][axs], int bys, + int bxs, const unsigned char B[bys][bxs]) { + int y, x; + for (y = 0; y < yn; ++y) { + for (x = 0; x < xn; ++x) { + C[y][x] = ABS(A[y][x] - B[y][x]); + } + } + return C; +} + +const char kDieWelle[] = "\ +pppppppppppppppppoooooooooooooooooooooooooooppppppppppppppppp\ +pmpppppppppppooooooonnnnnnnnnnnnnnnnnnnnnooooooopppppppppppsp\ +ppppppppppoooooonnnnnnnnmmmmmmmmmmmmmnnnnnnnnoooooopppppppppp\ +ppppppppooooonnnnnnmmmmmmmmmmmmmmmmmmmmmmmnnnnnnooooopppppppp\ +ppppppoooonnnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnnnoooopppppp\ +ppppoooonnnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnnnoooopppp\ +pppoooonnnnmmmmmmmmmmmmmmmnnnnnnnnnmmmmmmmmmmmmmmmnnnnooooppp\ +ppooonnnnmmmmmmmmmmmmnnnnnnooooooonnnnnnmmmmmmmmmmmmnnnnooopp\ +pooonnnnmmmmmmmmmmnnnnoooopppppppppoooonnnnmmmmmmmmmmnnnnooop\ +ooonnnnmmmmmmmmmnnnooopppqqqqrrrqqqqpppooonnnmmmmmmmmmnnnnooo\ +oonnnnmmmmmmmmmnnnooppqqrrsssssssssrrqqppoonnnmmmmmmmmmnnnnoo\ +oonnnmmmmmmmmmnnooppqrrssttuuuuuuuttssrrqppoonnmmmmmmmmmnnnoo\ +onnnnmmmmmmmmnnoopqqrsstuuvvvvvvvvvuutssrqqpoonnmmmmmmmmnnnno\ +onnnmmmmmmmmnnnoppqrsttuvvwwwxxxwwwvvuttsrqpponnnmmmmmmmmnnno\ +onnnmmmmmmmmnnoopqrrstuvvwxxxyyyxxxwvvutsrrqpoonnmmmmmmmmnnno\ +onnnmmmmmmmmnnoopqrsttuvwwxxyyyyyxxwwvuttsrqpoonnmmmmmmmmnnno\ +onnnmmmmmmmmnnoopqrsstuvwwxxyyyyyxxwwvutssrqpoonnmmmmmmmmnnno\ +onnnmmmmmmmmnnoopqqrstuuvwwxxxxxxxwwvuutsrqqpoonnmmmmmmmmnnno\ +onnnmmmmmmmmmnnoopqrrstuuvvwwwwwwwvvuutsrrqpoonnmmmmmmmmmnnno\ +oonnnmmmmmmmmnnnoppqqrssttuuvvvvvuuttssrqqpponnnmmmmmmmmnnnoo\ +oonnnmmmmmmmmmnnnooppqrrssstttttttsssrrqppoonnnmmmmmmmmmnnnoo\ +ooonnnmmmmmmmmmmnnoooppqqrrrrrrrrrrrqqppooonnmmmmmmmmmmnnnooo\ +oooonnnmmmmmmmmmmnnnnoooppppqqqqqppppooonnnnmmmmmmmmmmnnnoooo\ +poooonnnnmmmmmmmmmmmnnnnooooooooooooonnnnmmmmmmmmmmmnnnnoooop\ +ppoooonnnnmmmmmmmmmmmmmnnnnnnnnnnnnnnnmmmmmmmmmmmmmnnnnoooopp\ +ppppoooonnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnnoooopppp\ +pppppoooonnnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnnnooooppppp\ +pppppppooooonnnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnnnoooooppppppp\ +pppppppppooooonnnnnnnmmmmmmmmmmmmmmmmmmmnnnnnnnoooooppppppppp\ +pppppppppppooooooonnnnnnnnnnnnnnnnnnnnnnnnnoooooooppppppppppp\ +prpppppppppppppoooooooonnnnnnnnnnnnnnnooooooooppppppppppppptp\ +pppppppppppppppppppoooooooooooooooooooooooppppppppppppppppppp"; + +TEST(gyarados, testIdentityDifference) { + unsigned char A[1][32][62]; + unsigned char B[1][32][62]; + memcpy(A, kDieWelle, sizeof(A)); + EzGyarados(1, 32, 61, B, 1, 32, 61, A, 0, 1, 32, 61, 32, 61, 1, 1, 0, 0); + AbsoluteDifference(32, 62, B[0], 32, 62, B[0], 32, 62, A[0]); + EXPECT_STREQ(u"\n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                           ☺ \n\ +                                                             ", + gc(bingblit(32, 61, B[0], 32, 61))); +} + +TEST(gyarados, testHalfYX) { + static unsigned char M[1][32][61]; + memcpy(M, kDieWelle, sizeof(M)); + EzGyarados(1, 32, 61, M, 1, 32, 61, M, 0, 1, 16, 31, 32, 61, 2, 2, 0, 0); + EXPECT_STREQ(u"\n\ +ppppppppoooooooooooooopppppppqp\n\ +pppppoonnnmmmmmmmmmmmnnoooppppp\n\ +ppponnnmmmmmmmmmmmmmmmmmnnooppp\n\ +poonnmmmmmmmmnnnnnmmmmmmmmnnopp\n\ +oonnmmmmmnnoppqqppoonnmmmmmnnop\n\ +onnmmmmnooqrsttttsrqponmmmmmnno\n\ +onmmmmnopqstvwwwwvutrqonmmmmnno\n\ +onmmmmnoqrtvwxyyyxwusrpommmmmno\n\ +onmmmmnoprtvwxyyyxvusqpnmmmmmno\n\ +onmmmmmnpqrtuvwwvutsrponmmmmnno\n\ +onnmmmmmnopqrssssrrqoonmmmmmnoo\n\ +oonnmmmmmmnnoopppponnmmmmmmnoop\n\ +pponnmmmmmmmmmmmmmmmmmmmmnnoopp\n\ +pppoonnmmmmmmmmmmmmmmmmnnoopppp\n\ +pppppooonnnmmmmmmmmnnnooopppppp\n\ +pppppppppooooooooooooppppppppqp", + gc(bingblit(32, 61, M[0], 16, 31))); +} + +TEST(gyarados, testHalfY) { + static unsigned char M[1][32][61]; + memcpy(M, kDieWelle, sizeof(M)); + EzGyarados(1, 32, 61, M, 1, 32, 61, M, 0, 1, 16, 61, 32, 61, 2, 1, 0, 0); + EXPECT_STREQ(u"\n\ +popppppppppppppppooooooooooooooooooooooooooopppppppppppppppqp\n\ +ppppppppppooononnnnnmmmmmmmmmmmmmmmmmmmmmnnnnnonooopppppppppp\n\ +ppppppoononnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnonoopppppp\n\ +pppoononnmmmmmmmmmmmmmmmmmnnnnnnnnnmmmmmmmmmmmmmmmmmnnonooppp\n\ +poonnnnmmmmmmmmmmmnnnnoooppppqqqppppooonnnnmmmmmmmmmmmnnnnoop\n\ +oonnnnmmmmmmmmmnooppqqrrsstttttttttssrrqqppoonmmmmmmmmmnnnnoo\n\ +onnnnmmmmmmmnnnoppqqsttuvvwwwwwwwwwvvuttsqqpponnnmmmmmmmnnnno\n\ +onnnmmmmmmmmnnoopqrsttuvwwxxyyyyyxxwwvuttsrqpoonnmmmmmmmmnnno\n\ +onnnmmmmmmmmnnoopqrsstuvwwxxyyyyyxxwwvutssrqpoonnmmmmmmmmnnno\n\ +oonnnmmmmmmmmnnoopprrsttuuvvwwwwwvvuuttsrrppoonnmmmmmmmmnnnoo\n\ +ooonnmmmmmmmmmmmnooooqqqrrrsssssssrrrqqqoooonmmmmmmmmmmmnnooo\n\ +pooonnnmmmmmmmmmmmmmnnnnopoopppppooponnnnmmmmmmmmmmmmmnnnooop\n\ +ppppoononnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnonoopppp\n\ +pppppppoonoonnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnoonooppppppp\n\ +pppppppppppoooooonnnnnnmmmmmmmmmmmmmmmnnnnnnoooooopppppppppqp\n\ +pqpppppppppppppppppoooooooooooooooooooooooppppppppppppppppprp", + gc(bingblit(32, 61, M[0], 16, 61))); +} + +TEST(Magikarp2xY, testDecimateY) { + static unsigned char M[1][32][61], G[1][16][61], D[1][16][61]; + memcpy(M, kDieWelle, sizeof(M)); + EzGyarados(1, 32, 61, G, 1, 32, 61, M, 0, 1, 16, 61, 32, 61, 2, 1, 0, 0); + EXPECT_STREQ(u"\n\ +popppppppppppppppooooooooooooooooooooooooooopppppppppppppppqp\n\ +ppppppppppooononnnnnmmmmmmmmmmmmmmmmmmmmmnnnnnonooopppppppppp\n\ +ppppppoononnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnonoopppppp\n\ +pppoononnmmmmmmmmmmmmmmmmmnnnnnnnnnmmmmmmmmmmmmmmmmmnnonooppp\n\ +poonnnnmmmmmmmmmmmnnnnoooppppqqqppppooonnnnmmmmmmmmmmmnnnnoop\n\ +oonnnnmmmmmmmmmnooppqqrrsstttttttttssrrqqppoonmmmmmmmmmnnnnoo\n\ +onnnnmmmmmmmnnnoppqqsttuvvwwwwwwwwwvvuttsqqpponnnmmmmmmmnnnno\n\ +onnnmmmmmmmmnnoopqrsttuvwwxxyyyyyxxwwvuttsrqpoonnmmmmmmmmnnno\n\ +onnnmmmmmmmmnnoopqrsstuvwwxxyyyyyxxwwvutssrqpoonnmmmmmmmmnnno\n\ +oonnnmmmmmmmmnnoopprrsttuuvvwwwwwvvuuttsrrppoonnmmmmmmmmnnnoo\n\ +ooonnmmmmmmmmmmmnooooqqqrrrsssssssrrrqqqoooonmmmmmmmmmmmnnooo\n\ +pooonnnmmmmmmmmmmmmmnnnnopoopppppooponnnnmmmmmmmmmmmmmnnnooop\n\ +ppppoononnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnonoopppp\n\ +pppppppoonoonnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnoonooppppppp\n\ +pppppppppppoooooonnnnnnmmmmmmmmmmmmmmmnnnnnnoooooopppppppppqp\n\ +pqpppppppppppppppppoooooooooooooooooooooooppppppppppppppppprp", + gc(bingblit(16, 61, G[0], 16, 61))); + Magikarp2xY(32, 61, M[0], 32, 61); + AbsoluteDifference(16, 61, D[0], 16, 61, G[0], 16, 61, M[0]); + EXPECT_STREQ(u"\n\ +pnpppppppppppppppoooooooooooooooooooooooooooppppppppppppppprp\n\ +ppppppppppooooonnnnmmmmmmmmmmmmmmmmmmmmmmmnnnnooooopppppppppp\n\ +ppppppoononnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnonoopppppp\n\ +pppoononnmmmmmmmmmmmmmmmmmnnnnnnnnnmmmmmmmmmmmmmmmmmnnonooppp\n\ +poonnnnmmmmmmmmmmmnnnnoooppppqqqppppooonnnnmmmmmmmmmmmnnnnoop\n\ +oonnnnmmmmmmmmmnooppqqrrsstttttttttssrrqqppoonmmmmmmmmmnnnnoo\n\ +onnnnmmmmmmmnnnoppqrsttuvvwwwwwwwwwvvuttsrqpponnnmmmmmmmnnnno\n\ +onnnmmmmmmmmnnoopqrsttuvwwxxyyyyyxxwwvuttsrqpoonnmmmmmmmmnnno\n\ +onnnmmmmmmmmnnoopqrsstuvwwxxyyyyyxxwwvutssrqpoonnmmmmmmmmnnno\n\ +oonnnmmmmmmmmnnoopprrsttuuvvwwwwwvvuuttsrrppoonnmmmmmmmmnnnoo\n\ +ooonnmmmmmmmmmmmnoopoqqqrrsssssssssrrqqqopoonmmmmmmmmmmmnnooo\n\ +pooonnnmmmmmmmmmmmmmnnnnoooopppppoooonnnnmmmmmmmmmmmmmnnnooop\n\ +ppppoononnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnonoopppp\n\ +pppppppoonoonnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnoonooppppppp\n\ +pppppppppppoooooonnnnmmmmmmmmmmmmmmmmmmmnnnnooooooppppppppppp\n\ +pqpppppppppppppppppoooooooooooooooooooooooppppppppppppppppprp", + gc(bingblit(16, 61, M[0], 16, 61))); + EXPECT_STREQ(u"\n\ + ☺                                                         ☺ \n\ +             ☺     ☺                     ☺     ☺             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                   ☺                     ☺                   \n\ +                                                             \n\ +                                                             \n\ +                                                             \n\ +                   ☺      ☺       ☺      ☺                   \n\ +                         ☺         ☺                         \n\ +                                                             \n\ +                                                             \n\ +                     ☺☺               ☺☺                   ☺ \n\ +                                                             ", + gc(bingblit(16, 61, D[0], 16, 61))); +} + +TEST(Magikarp2xX, testDecimateX) { + static unsigned char M[1][32][61], G[1][32][31], D[32][31]; + memcpy(M, kDieWelle, sizeof(M)); + EzGyarados(1, 32, 31, G, 1, 32, 61, M, 0, 1, 32, 31, 32, 61, 1, 2, 0, 0); + EXPECT_STREQ(u"\n\ +pppppppppoooooooooooooppppppppp\n\ +oppppppooonnnnnnnnnnooooppppprp\n\ +pppppooonnnnmmmmmmmnnnooopppppp\n\ +ppppooonnmmmmmmmmmmmmnnnooppppp\n\ +pppoonnmmmmmmmmmmmmmmmmnnnopppp\n\ +ppoonnmmmmmmmmmmmmmmmmmmnnooppp\n\ +ppoonnmmmmmmmnnnnmmmmmmmmnnoopp\n\ +ponnnmmmmmmnnnooonnnmmmmmmnnopp\n\ +ponnmmmmmnnooppppoonnmmmmmnnnop\n\ +oonnmmmmnoopqqrrqqpoonmmmmmnnoo\n\ +onnmmmmmnopqrsssssqponnmmmmnnoo\n\ +onmmmmmnopqstuuuutsrqoommmmmnoo\n\ +onnmmmmnpqrtuvvvvvtsrponmmmmnno\n\ +onmmmmnopqtuvwxxwwutsqonmmmmmno\n\ +onmmmmnoqrsvwxyyxxvusqpnmmmmmno\n\ +onmmmmnopstvwxyyyxwutronmmmmmno\n\ +onmmmmnopstvwxyyyxwtsrpnmmmmmno\n\ +onmmmmnoprtuvxxxxwvurqpnmmmmmno\n\ +onmmmmmnpqsuvwwwwvutrqonmmmmmno\n\ +onmmmmmnoqrstuvvvutrqponmmmmnoo\n\ +onmmmmmnnoqrsttttssqponmmmmmnoo\n\ +oonmmmmmnooqrrrrrrqpoommmmmmnoo\n\ +oonmmmmmmnnoppqqppoonnmmmmmnooo\n\ +poonnmmmmmnnoooooonnmmmmmmnnoop\n\ +poonnmmmmmmmnnnnnnnmmmmmmnnoopp\n\ +ppoonnmmmmmmmmmmmmmmmmmmmnooppp\n\ +pppoonnmmmmmmmmmmmmmmmmmnnooppp\n\ +ppppoonnmmmmmmmmmmmmmmnnooopppp\n\ +pppppoonnnmmmmmmmmmmnnnoooppppp\n\ +ppppppooonnnnnnnnnnnnoooopppppp\n\ +qpppppppoooonnnnnnnoooopppppprp\n\ +ppppppppppooooooooooopppppppppp", + gc(bingblit(32, 31, G[0], 32, 31))); + Magikarp2xX(32, 61, M[0], 32, 61); + EXPECT_STREQ(u"\n\ +pppppppppoooooooooooooppppppppp\n\ +nppppppooonnnnnnnnnnooooppppprp\n\ +pppppooonnnnmmmmmmnnnnooopppppp\n\ +ppppooonnnmmmmmmmmmmmnnnooppppp\n\ +pppoonnnmmmmmmmmmmmmmmmnnoopppp\n\ +ppoonnnmmmmmmmmmmmmmmmmmnnooppp\n\ +ppoonnmmmmmmmnnnnnmmmmmmmnnoopp\n\ +ponnnmmmmmnnnoooonnnmmmmmmnnopp\n\ +ponnmmmmmnnoopppppoonnmmmmnnnop\n\ +oonnmmmmnoopqqrrqqpponmmmmmnnoo\n\ +onnmmmmmnopqrsssssrqpnnmmmmnnoo\n\ +onmmmmmnopqstuuuutsrqoommmmmnoo\n\ +onnmmmmnpqrtuvvvvvtsrponmmmmnno\n\ +onmmmmnnpqtuvwxxwwutsponmmmmmno\n\ +onmmmmnoqrsvwxyyxxvurronmmmmmno\n\ +onmmmmnopstvwxyyyxwutronmmmmmno\n\ +onmmmmnopssvwxyyyxwtsronmmmmmno\n\ +onmmmmnopqtuvxxxxwvurqpnmmmmmno\n\ +onmmmmmnorsuvwwwwvutrqonmmmmmno\n\ +onmmmmmnoqrstuvvvutrqpnnmmmmnoo\n\ +onmmmmmnnoqrsttttssqponmmmmmnoo\n\ +oonmmmmmnooqrrrrrrqpoommmmmmnoo\n\ +oonmmmmmnnnoppqqqpponnmmmmmnooo\n\ +poonnmmmmmnnooooooonnmmmmmnnoop\n\ +poonnmmmmmmnnnnnnnnmmmmmmnnoopp\n\ +ppoonnmmmmmmmmmmmmmmmmmmnnooppp\n\ +pppoonnmmmmmmmmmmmmmmmmnnnooppp\n\ +ppppoonnnmmmmmmmmmmmmmnnooopppp\n\ +pppppoonnnnmmmmmmmmmnnnoooppppp\n\ +ppppppooonnnnnnnnnnnnoooopppppp\n\ +qpppppppoooonnnnnnnoooopppppprp\n\ +ppppppppppooooooooooopppppppppp", + gc(bingblit(32, 61, M[0], 32, 31))); + AbsoluteDifference(32, 31, D, 32, 31, G[0], 32, 61, M[0]); + EXPECT_STREQ(u"\n\ +                               \n\ +☺                              \n\ +                  ☺            \n\ +         ☺                     \n\ +       ☺                 ☺     \n\ +      ☺                        \n\ +                 ☺             \n\ +          ☺  ☺                 \n\ +                 ☺ ☺ ☺         \n\ +                   ☺           \n\ +                  ☺☺☺          \n\ +                               \n\ +                               \n\ +       ☺             ☺         \n\ +                    ☺☺☺        \n\ +                               \n\ +          ☺           ☺        \n\ +         ☺                     \n\ +        ☺☺                     \n\ +                      ☺        \n\ +                               \n\ +                               \n\ +        ☺       ☺ ☺            \n\ +                  ☺ ☺          \n\ +           ☺                   \n\ +                        ☺      \n\ +                       ☺       \n\ +        ☺                      \n\ +          ☺                    \n\ +                               \n\ +                               \n\ +                               ", + gc(bingblit(32, 31, D, 32, 31))); +} + +TEST(magikarp_vs_gyarados, testHalf) { + static unsigned char M[1][32][61], G[1][16][31], D[16][31]; + memcpy(M, kDieWelle, sizeof(M)); + EzGyarados(1, 16, 31, G, 1, 32, 61, M, 0, 1, 16, 31, 32, 61, 32. / 16., + 61. / 31., 0, 0); + Magikarp2xY(32, 61, M[0], 32, 61); + Magikarp2xX(32, 61, M[0], 16, 61); + AbsoluteDifference(16, 31, D, 16, 32, G[0], 32, 61, M[0]); + EXPECT_STREQ(u"\n\ +oppppppppooooooooooooopppppppqp\n\ +pppppooonnmmmmmmmmmmmnnoopppppp\n\ +ppponnmmmmmmmmmmmmmmmmmmnnnpppp\n\ +ppnommmmmmmmmnnnnnmmmmmmmmnoopp\n\ +pnnnmmmmmnnoppqqpponnnmmmmmnnop\n\ +onnmmmmmopqrstttttsrqpnmmmmnnoo\n\ +onnmmmnnpqtuvwwwwwutsponmmmmnno\n\ +onmmmmnopstvwxyyyxwutronmmmmmno\n\ +onmmmmnopssvwxyyyxwtsronmmmmmno\n\ +onmmmmmooqstuvwwwvusrponmmmmnoo\n\ +oommmmmmnopqrsssssqqpommmmmmnoo\n\ +ponmmmmmmmnnoopppoonnmmmmmmnoop\n\ +ppoonmmmmmmmmmmmmmmmmmmmmmonppp\n\ +ppppnonmmmmmmmmmmmmmmmmmooopppp\n\ +ppppppooonnmmmmmmmmmnnooopppppp\n\ +qpppppppppoooooooooooppppppppqp", + gc(bingblit(32, 61, M[0], 16, 31))); + EXPECT_STREQ(u"\n\ +ppppppppooooooooooooooopppppppp\n\ +pppppoonnnmmmmmmmmmmmnnnooppppp\n\ +pppoonnmmmmmmmmmmmmmmmmmnnooppp\n\ +poonnmmmmmmmmnnnnnmmmmmmmmnnoop\n\ +oonnmmmmmnnoppqqqpponnmmmmmnnoo\n\ +onnmmmmnnoqrstttttsrqonnmmmmnno\n\ +onmmmmnnpqstuwwwwwutsqpnnmmmmno\n\ +onmmmmnoprtuwxyzyxwutrponmmmmno\n\ +onmmmmnoprsuwxyyyxwusrponmmmmno\n\ +onmmmmmnoqrtuvwwwvutrqonmmmmmno\n\ +onnmmmmmnopqrsssssrqponmmmmmnno\n\ +oonnmmmmmmnnoopppoonnmmmmmmnnoo\n\ +ppoonmmmmmmmmmmmmmmmmmmmmmnoopp\n\ +pppoonnmmmmmmmmmmmmmmmmmnnooppp\n\ +pppppooonnnmmmmmmmmmnnnoooppppp\n\ +pppppppppoooooooooooooppppppppq", + gc(bingblit(16, 31, G[0], 16, 31))); + EXPECT_STREQ(u"\n\ +☺       ☺             ☺      ☺ \n\ +    ☺ ☺☺ ☺          ☺          \n\ + ☺☺☺ ☺                ☺☺☺☺☻   ☺\n\ +☻☻☺☻      ☺☺☺  ☺☺☺     ☺☺☻☺☺ ☺☻\n\ +♥☺☺☺ ☺☺☻♥☻♥☻☺ ☺☻☻☻☻☺☺☺ ☺☺☻☻☺ ☺♥\n\ +☻☺ ☺☻♦♣♠♣♦♥☻☺☺☻♥♣♠♣♣♦♥☺☺☺☻☻ ☺☻☻\n\ +☺ ☻♦♠••○•♠♥☻☺♥♦♠•○••♠♥☻ ☻☻☺ ☺☺☻\n\ + ☻♣•◘◙◙◙◙♠♦☺☻♦•○◙◙◙◘•♣☺☺☻☺   ☺☺\n\ +☺♦♠◘◙♂♂◙○♣♦☺♦♠○◙♂♂◙•♠♦ ☺☺    ☺☺\n\ +☻♦•◘○◙◙◘•♦☺☻♦•○◙◙○◘♠♦☺  ☺   ☺☻☺\n\ +☺☻♣♠♠♠♠♠♦☻ ☻♦♠♠♠♠♠♥♥☺ ☻☺☺   ☺☻☻\n\ +☻ ☺♥♥♥☻☻☺☺☺☺☻☻♥♥☻☺ ☺☻♥☻☻☺  ☺☻☻♥\n\ +♥♥☻☻☺         ☺☻☻♥♥♥♥♥☻☻☺☺☻☺♥♥♥\n\ +♥♥♥♥☺☻☺    ☺☺☻☻♥♥♥♥♥♥♥♥☻  ☺☻☻♥♥\n\ +♥♥♥♥♥♥☺☺☺☺☺☻♥♥♥♥♥♥♥♥☻☻☺☺☺ ☺☺☺☺☺\n\ +☻☺☺☺☺☺☺   ☺☺☺☺☺☻oooooppppppppqp", + gc(bingblit(16, 31, D, 16, 31))); +} + +#define HDX (1920 / 4) +#define HDY (1080 / 4) + +#if 0 +BENCH(Magikarp, bench) { + unsigned char(*Me)[HDY][HDX] = tgc(tmalloc(HDX * HDY)); + unsigned char(*Mo)[HDY][HDX] = tgc(tmalloc(HDX * HDY)); + EZBENCH2("Magikarp2xY [even]", donothing, + Magikarp2xY(HDX, HDY, *Me, HDX, HDY)); + EZBENCH2("Magikarp2xY [odd]", donothing, + Magikarp2xY(HDX, HDY, *Mo, HDX, HDY)); + EZBENCH2("Magikarp2xX [even]", donothing, + Magikarp2xX(HDX, HDY, *Me, HDX, HDY)); + EZBENCH2("Magikarp2xX [odd]", donothing, + Magikarp2xX(HDX, HDY, *Mo, HDX, HDY)); +} +#endif diff --git a/test/dsp/scale/test.mk b/test/dsp/scale/test.mk new file mode 100644 index 00000000..be459fd2 --- /dev/null +++ b/test/dsp/scale/test.mk @@ -0,0 +1,57 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_DSP_SCALE + +TEST_DSP_SCALE_SRCS := $(wildcard test/dsp/scale/*.c) +TEST_DSP_SCALE_SRCS_TEST = $(filter %_test.c,$(TEST_DSP_SCALE_SRCS)) +TEST_DSP_SCALE_COMS = $(TEST_DSP_SCALE_OBJS:%.o=%.com) +TEST_DSP_SCALE_BINS = $(TEST_DSP_SCALE_COMS) $(TEST_DSP_SCALE_COMS:%=%.dbg) + +TEST_DSP_SCALE_OBJS = \ + $(TEST_DSP_SCALE_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_DSP_SCALE_SRCS:%.c=o/$(MODE)/%.o) + +TEST_DSP_SCALE_TESTS = \ + $(TEST_DSP_SCALE_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_DSP_SCALE_CHECKS = \ + $(TEST_DSP_SCALE_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_DSP_SCALE_DIRECTDEPS = \ + DSP_CORE \ + DSP_SCALE \ + LIBC_TINYMATH \ + LIBC_LOG \ + LIBC_RUNTIME \ + LIBC_FMT \ + LIBC_MEM \ + LIBC_STDIO \ + LIBC_X \ + LIBC_RAND \ + LIBC_NEXGEN32E \ + LIBC_STR \ + TOOL_VIZ_LIB \ + LIBC_STUBS \ + LIBC_TESTLIB + +TEST_DSP_SCALE_DEPS := \ + $(call uniq,$(foreach x,$(TEST_DSP_SCALE_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/dsp/scale/scale.pkg: \ + $(TEST_DSP_SCALE_OBJS) \ + $(foreach x,$(TEST_DSP_SCALE_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/dsp/scale/%.com.dbg: \ + $(TEST_DSP_SCALE_DEPS) \ + o/$(MODE)/test/dsp/scale/%.o \ + o/$(MODE)/test/dsp/scale/scale.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +.PHONY: o/$(MODE)/test/dsp/scale +o/$(MODE)/test/dsp/scale: \ + $(TEST_DSP_SCALE_BINS) \ + $(TEST_DSP_SCALE_CHECKS) diff --git a/test/dsp/test.mk b/test/dsp/test.mk new file mode 100644 index 00000000..0ba552c2 --- /dev/null +++ b/test/dsp/test.mk @@ -0,0 +1,7 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +.PHONY: o/$(MODE)/test/dsp +o/$(MODE)/test/dsp: o/$(MODE)/test/dsp/core \ + o/$(MODE)/test/dsp/scale \ + o/$(MODE)/test/dsp/tty diff --git a/test/dsp/tty/rgb2ansi_test.c b/test/dsp/tty/rgb2ansi_test.c new file mode 100644 index 00000000..c98b6328 --- /dev/null +++ b/test/dsp/tty/rgb2ansi_test.c @@ -0,0 +1,65 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/quant.h" +#include "libc/testlib/testlib.h" + +struct TtyRgb res; + +TEST(rgb2ansi, testDesaturatedPurple_isQuantizedBetterThanEuclideanDistance) { + ttyquantinit(kTtyQuantXterm256, kTtyQuantRgb, kTtyBlocksUnicode); + + /* + * the challenge to the xterm256 palette is that it was likely + * intended for just syntax highlighting, rather than accurately + * modeling the natural phenomenon of illumination. + * + * as a syntax highlighting palette, it focuses mostly on bright + * saturated colors, while also providing a really good greyscale for + * everything else. + * + * as such, if one were to project the colors of this palette into a + * three-dimensional space, we might see something like an HSV cone, + * where all the color samples are projected mostly around the outside + * of the cone, and the greyscale dots tracing through the middle. + * + * if we want to convert an a real color into an xterm color, we can + * use euclidean distance functions to pick the closest color, such as + * sum of squared distance. however this will only work well if it's + * either a pure grey color, or a bright saturated one. + * + * but euclidean distance doesnt work well for the sorts of colors + * that are generally used for things like film, which conservatively + * edits for the colors more towards the middle of the space; and as + * such, which basically causes the distance function to pick greys + * for almost everything. + */ + + res = rgb2tty(0x56, 0x38, 0x66); + + /* EXPECT_NE(0x4e, res.r); */ + /* EXPECT_NE(0x4e, res.g); */ + /* EXPECT_NE(0x4e, res.b); */ + /* EXPECT_NE(239, res.xt); */ + + /* EXPECT_EQ(0x5f, res.r); */ + /* EXPECT_EQ(0x00, res.g); */ + /* EXPECT_EQ(0x5f, res.b); */ + /* EXPECT_EQ(53, res.xt); */ +} diff --git a/test/dsp/tty/rgb2xterm256_test.c b/test/dsp/tty/rgb2xterm256_test.c new file mode 100644 index 00000000..d5ff1ab3 --- /dev/null +++ b/test/dsp/tty/rgb2xterm256_test.c @@ -0,0 +1,47 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/rgb2xterm256.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +TEST(rgb2xterm256, test) { + EXPECT_EQ(196, rgb2xterm256v2(0xff, 0x00, 0x00)); /* red */ + EXPECT_EQ(46, rgb2xterm256v2(0x00, 0xff, 0x00)); /* green */ + EXPECT_EQ(21, rgb2xterm256v2(0x00, 0x00, 0xff)); /* blue */ + EXPECT_EQ(226, rgb2xterm256v2(0xff, 0xff, 0x00)); /* yellow */ + EXPECT_EQ(208, rgb2xterm256v2(0xff, 0x80, 0x00)); /* orange */ +} + +TEST(rgb2xterm256, testRedBlack) { + EXPECT_EQ(16, rgb2xterm256v2(0, 0, 0)); + EXPECT_EQ(16, rgb2xterm256v2(12, 0, 0)); + EXPECT_EQ(232, rgb2xterm256v2(13, 0, 0)); + EXPECT_EQ(233, rgb2xterm256v2(39, 0, 0)); + EXPECT_EQ(233, rgb2xterm256v2(40, 0, 0)); + EXPECT_EQ(52, rgb2xterm256v2(53, 0, 0)); + EXPECT_EQ(88, rgb2xterm256v2(115, 0, 0)); + EXPECT_EQ(88, rgb2xterm256v2(116, 0, 0)); +} + +//////////////////////////////////////////////////////////////////////////////// + +BENCH(rgb2xterm256v2, bench) { + EZBENCH(donothing, rgb2xterm256v2(0xff, 0x80, 0x00)); +} diff --git a/test/dsp/tty/test.mk b/test/dsp/tty/test.mk new file mode 100644 index 00000000..4481046f --- /dev/null +++ b/test/dsp/tty/test.mk @@ -0,0 +1,51 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_DSP_TTY + +TEST_DSP_TTY_SRCS := $(wildcard test/dsp/tty/*.c) +TEST_DSP_TTY_SRCS_TEST = $(filter %_test.c,$(TEST_DSP_TTY_SRCS)) +TEST_DSP_TTY_COMS = $(TEST_DSP_TTY_OBJS:%.o=%.com) +TEST_DSP_TTY_BINS = $(TEST_DSP_TTY_COMS) $(TEST_DSP_TTY_COMS:%=%.dbg) + +TEST_DSP_TTY_OBJS = \ + $(TEST_DSP_TTY_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_DSP_TTY_SRCS:%.c=o/$(MODE)/%.o) + +TEST_DSP_TTY_TESTS = \ + $(TEST_DSP_TTY_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_DSP_TTY_CHECKS = \ + $(TEST_DSP_TTY_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_DSP_TTY_DIRECTDEPS = \ + DSP_TTY \ + LIBC_TINYMATH \ + LIBC_LOG \ + LIBC_RUNTIME \ + LIBC_RAND \ + LIBC_NEXGEN32E \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_TESTLIB + +TEST_DSP_TTY_DEPS := \ + $(call uniq,$(foreach x,$(TEST_DSP_TTY_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/dsp/tty/tty.pkg: \ + $(TEST_DSP_TTY_OBJS) \ + $(foreach x,$(TEST_DSP_TTY_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/dsp/tty/%.com.dbg: \ + $(TEST_DSP_TTY_DEPS) \ + o/$(MODE)/test/dsp/tty/%.o \ + o/$(MODE)/test/dsp/tty/tty.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +.PHONY: o/$(MODE)/test/dsp/tty +o/$(MODE)/test/dsp/tty: \ + $(TEST_DSP_TTY_BINS) \ + $(TEST_DSP_TTY_CHECKS) diff --git a/test/dsp/tty/ttymove_test.c b/test/dsp/tty/ttymove_test.c new file mode 100644 index 00000000..92f57f0c --- /dev/null +++ b/test/dsp/tty/ttymove_test.c @@ -0,0 +1,191 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/tty.h" +#include "libc/bits/bits.h" +#include "libc/rand/rand.h" +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +char p[16]; +struct TtyCursor c; + +void SetUp(void) { rngset(p, sizeof(p), rand64, -1); } + +TEST(ttymove, sameCoord_doesNothing) { + c.y = 0; + c.x = 0; + EXPECT_EQ(0, ttymove(&c, p, 0, 0) - p); + EXPECT_STREQ("", p); + EXPECT_EQ(0, c.y); + EXPECT_EQ(0, c.x); +} + +TEST(ttymove, crlf) { + c.y = 0; + c.x = 10; + EXPECT_EQ(2, ttymove(&c, p, 1, 0) - p); + EXPECT_STREQ("\r\n", p); + EXPECT_EQ(1, c.y); + EXPECT_EQ(0, c.x); +} + +TEST(ttymove, cr) { + c.y = 7; + c.x = 10; + EXPECT_EQ(1, ttymove(&c, p, 7, 0) - p); + EXPECT_STREQ("\r", p); + EXPECT_EQ(7, c.y); + EXPECT_EQ(0, c.x); +} + +TEST(ttymove, forwardOne) { + c.y = 0; + c.x = 10; + EXPECT_EQ(3, ttymove(&c, p, 0, 11) - p); + EXPECT_STREQ("\e[C", p); + EXPECT_EQ(0, c.y); + EXPECT_EQ(11, c.x); +} + +TEST(ttymove, forwardTwo) { + c.y = 0; + c.x = 0; + EXPECT_EQ(4, ttymove(&c, p, 0, 2) - p); + EXPECT_STREQ("\e[2C", p); + EXPECT_EQ(0, c.y); + EXPECT_EQ(2, c.x); +} + +TEST(ttymove, forwardHuge_moves255increments) { + c.y = 0; + c.x = 0; + EXPECT_EQ(6 + 3, ttymove(&c, p, 0, 256) - p); + EXPECT_STREQ("\e[255C\e[C", p); + EXPECT_EQ(0, c.y); + EXPECT_EQ(256, c.x); +} + +TEST(ttymove, topleft) { + c.y = 1000; + c.x = 888; + EXPECT_EQ(3, ttymove(&c, p, 0, 0) - p); + EXPECT_STREQ("\e[H", p); + EXPECT_EQ(0, c.y); + EXPECT_EQ(0, c.x); +} + +#define MOVE(WANT, Y, X) \ + EXPECT_EQ(strlen(WANT), ttymove(&c, p, Y, X) - p); \ + EXPECT_STREQ(WANT, p); \ + EXPECT_EQ(Y, c.y); \ + EXPECT_EQ(X, c.x) + +TEST(ttymove, absoluteYandX_is1indexed) { + c.y = 1000; + c.x = 888; + MOVE("\e[4;3H", 3, 2); +} + +TEST(ttymove, absoluteYandX_implicit1y) { + c.y = 1000; + c.x = 888; + MOVE("\e[;3H", 0, 2); +} + +TEST(ttymove, absoluteYandX_implicit1x) { + c.y = 1000; + c.x = 888; + MOVE("\e[4H", 3, 0); +} + +TEST(ttymove, up) { + c.y = 70, c.x = 70; + MOVE("\eM", 69, 70); + c.y = 70, c.x = 70; + MOVE("\e[2A", 68, 70); +} + +TEST(ttymove, down) { + c.y = 70, c.x = 70; + MOVE("\eD", 71, 70); + c.y = 70, c.x = 70; + MOVE("\e[2B", 72, 70); +} + +TEST(ttymove, right) { + c.y = 70, c.x = 70; + MOVE("\e[C", 70, 71); + c.y = 70, c.x = 70; + MOVE("\e[2C", 70, 72); + c.y = 70, c.x = 0; + MOVE("\e[123C", 70, 123); +} + +TEST(ttymove, left) { + c.y = 70, c.x = 70; + MOVE("\e[D", 70, 69); + c.y = 70, c.x = 70; + MOVE("\e[2D", 70, 68); +} + +/* TEST(ttymove, bench_absmove) { */ +/* EZBENCH( */ +/* { */ +/* c.y = 70; */ +/* c.x = 30; */ +/* }, */ +/* ttymove(&c, p, 7, 9)); */ +/* ASSERT_STREQ("\e[8;10H", p); */ +/* } */ + +/* TEST(ttymove, bench_crlf) { */ +/* EZBENCH( */ +/* { */ +/* c.y = 0; */ +/* c.x = 10; */ +/* }, */ +/* ttymove(&c, p, 1, 0)); */ +/* ASSERT_STREQ("\r\n", p); */ +/* } */ + +/* TEST(ttymove, bench_forward1) { */ +/* EZBENCH( */ +/* { */ +/* c.y = 0; */ +/* c.x = 10; */ +/* }, */ +/* ttymove(&c, p, 0, 11)); */ +/* ASSERT_STREQ("\e[C", p); */ +/* } */ + +/* TEST(ttymove, bench_forward2) { */ +/* int y2, x2; */ +/* EZBENCH( */ +/* { */ +/* y2 = rand32() & 127; */ +/* x2 = rand32() & 127; */ +/* c.y = rand32() & 127; */ +/* c.x = rand32() & 127; */ +/* }, */ +/* ttymove(&c, p, y2, x2)); */ +/* int z; */ +/* EZBENCH(z = rand32() & 127, _memcpy(&z, "\e[2C", 4)); */ +/* } */ diff --git a/test/dsp/tty/ttyraster_test.c b/test/dsp/tty/ttyraster_test.c new file mode 100644 index 00000000..371a0878 --- /dev/null +++ b/test/dsp/tty/ttyraster_test.c @@ -0,0 +1,152 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/quant.h" +#include "libc/bits/progn.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" +#include "net/http/csscolor.h" + +/*TODO(jart): Re-enable me + +static const struct TtyRgb kBlack = {0, 0, 0, 16}; +static const struct TtyRgb kWhite = {255, 255, 255, 231}; +static const struct TtyRgb kRed = {0xff, 0, 0, 196}; + +char vtbuf[128]; + +void ttyraster_true_setup(void) { + ttyquantinit(kTtyQuantTrue, kTtyQuantRgb, kTtyBlocksUnicode); +} + +void ttyraster2x2_true(void) { + ttyraster(vtbuf, + (const struct TtyRgb *)(unsigned[2][2]){ + {DARKRED, GRAY1}, + {DARKRED, DARKRED}, + }, + 2, 2, kBlack, kBlack); +} + +TEST(ttyraster, testCorner) { + ttyraster_true_setup(); + EXPECT_STREQ("\e[48;2;139;0;0;38;2;3;3;3m▝", + PROGN(ttyraster2x2_true(), vtbuf)); +} + +TEST(ttyraster, testFullBlock_favorsSpace) { + ttyquantinit(kTtyQuantTrue, kTtyQuantRgb, kTtyBlocksUnicode); + ttyraster(vtbuf, + (struct TtyRgb *)(unsigned[2][2]){ + {DARKRED, DARKRED}, + {DARKRED, DARKRED}, + }, + 2, 2, kBlack, kBlack); + EXPECT_STREQ("\e[48;2;139;0;0m ", vtbuf); +} + +TEST(ttyraster, testFullBlock_favorsUnicodeWhenCurrenttFgMatchesButNotBg) { + ttyquantinit(kTtyQuantTrue, kTtyQuantRgb, kTtyBlocksUnicode); + ttyraster(vtbuf, + (struct TtyRgb *)(unsigned[2][4]){ + {DARKRED, GRAY1, GRAY1, GRAY1}, + {DARKRED, DARKRED, GRAY1, GRAY1}, + }, + 2, 4, kBlack, kBlack); + EXPECT_STREQ("\e[48;2;139;0;0;38;2;3;3;3m▝█", vtbuf); +} + +TEST(ttyraster, testFullBlock_forcesSwitchBackToSpaceForRuns) { + ttyquantinit(kTtyQuantTrue, kTtyQuantRgb, kTtyBlocksUnicode); + ttyraster(vtbuf, + (struct TtyRgb *)(unsigned[2][8]){ + {DARKRED, GRAY1, GRAY1, GRAY1, GRAY1, GRAY1, GRAY1, GRAY1}, + {DARKRED, DARKRED, GRAY1, GRAY1, GRAY1, GRAY1, GRAY1, GRAY1}, + }, + 2, 8, kBlack, kBlack); + EXPECT_STREQ("\e[48;2;139;0;0;38;2;3;3;3m▝█\e[48;2;3;3;3m ", vtbuf); +} + +//////////////////////////////////////////////////////////////////////////////// + +TEST(ttyraster_cp437, testSide) { + ttyquantinit(kTtyQuantTrue, kTtyQuantRgb, kTtyBlocksCp437); + ttyraster(vtbuf, + (const struct TtyRgb *)(unsigned[2][2]){ + {DARKRED, GRAY1}, + {DARKRED, GRAY1}, + }, + 2, 2, kBlack, kBlack); + EXPECT_STREQ("\e[48;2;3;3;3;38;2;139;0;0m▌", vtbuf); +} + +//////////////////////////////////////////////////////////////////////////////// + +void ttyraster_xterm256_setup(void) { + ttyquantinit(kTtyQuantXterm256, kTtyQuantRgb, kTtyBlocksUnicode); +} + +void ttyraster2x2_xterm256(void) { + ttyraster(vtbuf, + (const struct TtyRgb *)(struct TtyRgb[2][2]){ + {kBlack, kWhite}, + {kBlack, kBlack}, + }, + 2, 2, kRed, kRed); +} + +TEST(ttyraster_xterm256, testCorner) { + ttyraster_xterm256_setup(); + ttyraster2x2_xterm256(); + EXPECT_STREQ("\e[48;5;16;38;5;231m▝", vtbuf); +} + +void ttyraster6x2_xterm256(void) { + ttyraster(vtbuf, + (const struct TtyRgb *)(struct TtyRgb[2][6]){ + {kBlack, kWhite, kBlack, kWhite, kBlack, kWhite}, + {kBlack, kBlack, kBlack, kBlack, kBlack, kBlack}, + }, + 2, 6, kRed, kRed); +} + +TEST(ttyraster_xterm256, testCornerRepeat3) { + ttyraster_xterm256_setup(); + ttyraster6x2_xterm256(); + EXPECT_STREQ("\e[48;5;16;38;5;231m▝▝▝", vtbuf); +} + +//////////////////////////////////////////////////////////////////////////////// + +BENCH(ttyraster_true, bench) { + ttyraster_true_setup(); + EZBENCH(donothing, ttyraster2x2_true()); +} + +BENCH(ttyraster_xterm256, bench2) { + ttyraster_xterm256_setup(); + EZBENCH(donothing, ttyraster2x2_xterm256()); +} + +BENCH(ttyraster_xterm256, bench6) { + ttyraster_xterm256_setup(); + EZBENCH(donothing, ttyraster6x2_xterm256()); +} + +*/ diff --git a/test/dsp/tty/windex_test.c b/test/dsp/tty/windex_test.c new file mode 100644 index 00000000..5e874981 --- /dev/null +++ b/test/dsp/tty/windex_test.c @@ -0,0 +1,130 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/tty/windex.h" +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/limits.h" +#include "libc/macros.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +unsigned windex$k8(short *, size_t) hidden; +unsigned windex$avx2(short *, size_t) hidden; +unsigned windex$sse4(short *, size_t) hidden; + +const short kW[64] aligned(32) = { + 8281, 3883, 1365, 1786, 9006, 3681, 5563, 8013, 5787, 9063, 2923, + 3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905, + 2465, 9122, 9563, 1290, 4474, 3988, 9920, 8325, 1088, 2915, 33, + 1085, 7806, 3248, 1186, 1357, 6738, 1311, 1092, 6195, 7089, 6631, + 1261, 1364, 9007, 8289, 1409, 1090, 8358, 1502, 7658, 2668, 3522, + 1730, 2041, 7707, 5096, 6876, 1324, 1242, 5283, 0x7fff, +}; + +const short kW2[32] aligned(32) = { + 8281, 1, 1365, 1786, 9006, 3681, 5563, 8013, 5787, 9063, 2923, + 3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905, + 2465, 9122, 9563, 1290, 4474, 3988, 9920, 8325, 1088, 2915, +}; + +const short kW3[64] aligned(32) = { + 8281, 0x7fff, 1365, 1786, 9006, 3681, 5563, 8013, 5787, 9063, 2923, + 3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905, + 2465, 9122, 9563, 1290, 4474, 3988, 9920, 8325, 1088, 2915, 33, + 1085, 7806, 3248, 1186, 1357, 6738, 1311, 1092, 6195, 7089, 6631, + 1261, 1364, 9007, 8289, 1409, 1090, 8358, 1502, 7658, 2668, 3522, + 1730, 2041, 7707, 5096, 6876, 1324, 1242, 7, 0x7fff, +}; + +#define TestIt(impl, index, value, n, array) \ + ({ \ + short *a = memcpy(tgc(tmemalign(32, n * 2)), array, n * 2); \ + unsigned res = impl(array, n); \ + ASSERT_EQ(index, res); \ + ASSERT_EQ(value, a[res]); \ + }) + +TEST(windex, testRealWorldPicks) { + const short kPicks[96] aligned(32) = { + 103, 85, 145, 146, 121, 103, 145, 187, 146, 189, + 121, 103, 139, 121, 63, 105, 105, 147, 60, 103, + 103, 146, 121, 103, 139, 121, 139, 121, 157, 139, + 199, 200, 163, 223, 164, 225, 81, 141, 105, 165, + 78, 139, 103, 164, 61, 103, 103, 145, 79, 139, + 103, 163, 21, 63, 21, 81, 63, 45, 105, 106, + 106, 107, 102, 103, 103, 104, 64, 107, 107, 150, + 82, 143, 107, 168, 108, 109, 109, 110, 21, 64, + 21, 82, 105, 106, 64, 46, 106, 107, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + }; + /* multiple valid answers are fine if it's deterministic */ + TestIt(windex$k8, 52, 21, ARRAYLEN(kPicks), kPicks); + if (X86_HAVE(AVX2)) TestIt(windex$avx2, 78, 21, ARRAYLEN(kPicks), kPicks); + if (X86_HAVE(SSE4_2)) TestIt(windex$sse4, 80, 21, ARRAYLEN(kPicks), kPicks); +} + +TEST(windex, test) { + TestIt(windex, 13, 32, ARRAYLEN(kW), kW); + TestIt(windex, 1, 1, ARRAYLEN(kW2), kW2); + TestIt(windex, 62, 7, ARRAYLEN(kW3), kW3); +} + +TEST(windex$avx2, test) { + if (X86_HAVE(AVX2)) { + TestIt(windex$avx2, 13, 32, ARRAYLEN(kW), kW); + TestIt(windex$avx2, 1, 1, ARRAYLEN(kW2), kW2); + TestIt(windex$avx2, 62, 7, ARRAYLEN(kW3), kW3); + } +} + +TEST(windex$sse4, test) { + if (X86_HAVE(SSE4_2)) { + TestIt(windex$sse4, 13, 32, ARRAYLEN(kW), kW); + TestIt(windex$sse4, 1, 1, ARRAYLEN(kW2), kW2); + TestIt(windex$sse4, 62, 7, ARRAYLEN(kW3), kW3); + } +} + +TEST(windex$k8, test) { + TestIt(windex$k8, 13, 32, ARRAYLEN(kW), kW); + TestIt(windex$k8, 1, 1, ARRAYLEN(kW2), kW2); + TestIt(windex$k8, 62, 7, ARRAYLEN(kW3), kW3); +} + +//////////////////////////////////////////////////////////////////////////////// + +BENCH(windex, bench) { + EZBENCH(donothing, windex(kW, ARRAYLEN(kW))); +} +BENCH(windex$k8, bench) { + EZBENCH(donothing, windex$k8(kW, ARRAYLEN(kW))); +} +BENCH(windex$avx2, bench) { + if (X86_HAVE(AVX2)) { + EZBENCH(donothing, windex$avx2(kW, ARRAYLEN(kW))); + } +} +BENCH(windex$sse4, bench) { + if (X86_HAVE(SSE4_2)) { + EZBENCH(donothing, windex$sse4(kW, ARRAYLEN(kW))); + } +} diff --git a/test/libc/alg/arraylist_test.c b/test/libc/alg/arraylist_test.c new file mode 100644 index 00000000..a9989554 --- /dev/null +++ b/test/libc/alg/arraylist_test.c @@ -0,0 +1,97 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/alg/arraylist.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +struct string { + size_t i, n; + char *p; +}; + +struct string16 { + size_t i, n; + char16_t *p; +}; + +struct ArrayListInteger { + size_t i, n; + int *p; +}; + +TEST(append, worksGreatForScalars) { + char c = 'a'; + struct string s; + memset(&s, 0, sizeof(s)); + for (size_t i = 0; i < 1024; ++i) ASSERT_EQ(i, append(&s, &c)); + ASSERT_EQ(1024, s.i); + for (size_t i = 0; i < s.i; ++i) ASSERT_EQ('a', s.p[i]); + free_s(&s.p); +} + +TEST(append, isGenericallyTyped) { + int c = 0x31337; + struct ArrayListInteger s; + memset(&s, 0, sizeof(s)); + for (size_t i = 0; i < 1024; ++i) ASSERT_EQ(i, append(&s, &c)); + ASSERT_EQ(1024, s.i); + ASSERT_GT(malloc_usable_size(s.p), 1024 * sizeof(int)); + for (size_t i = 0; i < s.i; ++i) ASSERT_EQ(0x31337, s.p[i]); + free_s(&s.p); +} + +TEST(concat, worksGreatForStrings) { + const char *ks = + "Und wird die Welt auch in Flammen stehen\n" + "Wir werden wieder auferstehen\n"; + struct string s; + memset(&s, 0, sizeof(s)); + ASSERT_EQ(0, concat(&s, ks, strlen(ks))); + ASSERT_EQ(strlen(ks), concat(&s, ks, strlen(ks) + 1)); + ASSERT_STREQ( + "Und wird die Welt auch in Flammen stehen\n" + "Wir werden wieder auferstehen\n" + "Und wird die Welt auch in Flammen stehen\n" + "Wir werden wieder auferstehen\n", + s.p); + ASSERT_EQ(strlen(ks) * 2 + 1, s.i); + free_s(&s.p); +} + +TEST(concat, isGenericallyTyped) { + const char16_t *ks = + u"Drum hoch die Fäuste, hoch zum Licht.\n" + u"Unsere schwarzen Seelen bekommt ihr nicht.\n"; + struct string16 s; + memset(&s, 0, sizeof(s)); + ASSERT_EQ(0, concat(&s, ks, strlen16(ks))); + ASSERT_EQ(strlen16(ks), concat(&s, ks, strlen16(ks) + 1)); + ASSERT_STREQ( + u"Drum hoch die Fäuste, hoch zum Licht.\n" + u"Unsere schwarzen Seelen bekommt ihr nicht.\n" + u"Drum hoch die Fäuste, hoch zum Licht.\n" + u"Unsere schwarzen Seelen bekommt ihr nicht.\n", + s.p); + ASSERT_EQ(strlen16(ks) * 2 + 1, s.i); + free_s(&s.p); +} diff --git a/test/libc/alg/bisectcarleft_test.c b/test/libc/alg/bisectcarleft_test.c new file mode 100644 index 00000000..fa2b9bb2 --- /dev/null +++ b/test/libc/alg/bisectcarleft_test.c @@ -0,0 +1,58 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/alg/bisectcarleft.h" +#include "libc/bits/bits.h" +#include "libc/macros.h" +#include "libc/runtime/runtime.h" +#include "libc/testlib/testlib.h" + +TEST(bisectcarleft, testEmpty) { + const int32_t cells[][2] = {}; + EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 123)); +} + +TEST(bisectcarleft, testOneEntry) { + const int32_t cells[][2] = {{123, 31337}}; + EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 122)); + EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 123)); + EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 124)); +} + +TEST(bisectcarleft, testNegativity_usesSignedBehavior) { + const int32_t cells[][2] = {{-2, 31337}}; + EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), -3)); + EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), -2)); + EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), -1)); +} + +TEST(bisectcarleft, testMultipleEntries) { + const int32_t cells[][2] = {{00, 0}, {11, 0}, {20, 0}, {33, 0}, {40, 0}, + {50, 0}, {60, 0}, {70, 0}, {80, 0}, {90, 0}}; + EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 10)); + EXPECT_EQ(1, bisectcarleft(cells, ARRAYLEN(cells), 11)); + EXPECT_EQ(1, bisectcarleft(cells, ARRAYLEN(cells), 12)); + EXPECT_EQ(1, bisectcarleft(cells, ARRAYLEN(cells), 19)); + EXPECT_EQ(2, bisectcarleft(cells, ARRAYLEN(cells), 20)); + EXPECT_EQ(2, bisectcarleft(cells, ARRAYLEN(cells), 21)); + EXPECT_EQ(2, bisectcarleft(cells, ARRAYLEN(cells), 32)); + EXPECT_EQ(3, bisectcarleft(cells, ARRAYLEN(cells), 33)); + EXPECT_EQ(3, bisectcarleft(cells, ARRAYLEN(cells), 34)); +} diff --git a/test/libc/alg/comparator_test.c b/test/libc/alg/comparator_test.c new file mode 100644 index 00000000..80584f55 --- /dev/null +++ b/test/libc/alg/comparator_test.c @@ -0,0 +1,110 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/bits/bits.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(comparator, testByteCompare) { + char *b1 = tmalloc(1); + char *b2 = tmalloc(1); + /* sign doesn't matter */ + EXPECT_EQ(cmpsb(memcpy(b1, "a", 1), memcpy(b2, "a", 1)), 0); + EXPECT_LT(cmpsb(memcpy(b1, "a", 1), memcpy(b2, "z", 1)), 0); + EXPECT_GT(cmpsb(memcpy(b1, "z", 1), memcpy(b2, "a", 1)), 0); + EXPECT_EQ(cmpub(memcpy(b1, "a", 1), memcpy(b2, "a", 1)), 0); + EXPECT_LT(cmpub(memcpy(b1, "a", 1), memcpy(b2, "z", 1)), 0); + EXPECT_GT(cmpub(memcpy(b1, "z", 1), memcpy(b2, "a", 1)), 0); + /* sign matters */ + EXPECT_EQ(cmpsb(memcpy(b1, "\xf0", 1), memcpy(b2, "\xf0", 1)), 0); + EXPECT_LT(cmpsb(memcpy(b1, "\xf0", 1), memcpy(b2, "\x10", 1)), 0); + EXPECT_GT(cmpsb(memcpy(b1, "\x10", 1), memcpy(b2, "\xf0", 1)), 0); + EXPECT_EQ(cmpub(memcpy(b1, "\xf0", 1), memcpy(b2, "\xf0", 1)), 0); + EXPECT_GT(cmpub(memcpy(b1, "\xf0", 1), memcpy(b2, "\x10", 1)), 0); + EXPECT_LT(cmpub(memcpy(b1, "\x10", 1), memcpy(b2, "\xf0", 1)), 0); + /* two's complement bane */ + EXPECT_GT(cmpsb(memcpy(b1, "\x7f", 1), memcpy(b2, "\x80", 1)), 0); + EXPECT_LT(cmpub(memcpy(b1, "\x7f", 1), memcpy(b2, "\x80", 1)), 0); + tfree(b2); + tfree(b1); +} + +TEST(comparator, testWordCompare) { + char *b1 = tmalloc(2); + char *b2 = tmalloc(2); + EXPECT_EQ(cmpsw(memcpy(b1, "\x00\x80", 2), memcpy(b2, "\x00\x80", 2)), 0); + EXPECT_GT(cmpsw(memcpy(b1, "\x00\x7f", 2), memcpy(b2, "\x00\x80", 2)), 0); + EXPECT_LT(cmpsw(memcpy(b1, "\x00\x80", 2), memcpy(b2, "\x00\x7f", 2)), 0); + EXPECT_EQ(cmpuw(memcpy(b1, "\x00\x80", 2), memcpy(b2, "\x00\x80", 2)), 0); + EXPECT_LT(cmpuw(memcpy(b1, "\x00\x7f", 2), memcpy(b2, "\x00\x80", 2)), 0); + EXPECT_GT(cmpuw(memcpy(b1, "\x00\x80", 2), memcpy(b2, "\x00\x7f", 2)), 0); + tfree(b2); + tfree(b1); +} + +TEST(comparator, testDoublewordCompare) { + char *b1 = tmalloc(4); + char *b2 = tmalloc(4); + EXPECT_EQ(cmpsl(memcpy(b1, "\x00\x00\x00\x80", 4), + memcpy(b2, "\x00\x00\x00\x80", 4)), + 0); + EXPECT_GT(cmpsl(memcpy(b1, "\x00\x00\x00\x7f", 4), + memcpy(b2, "\x00\x00\x00\x80", 4)), + 0); + EXPECT_LT(cmpsl(memcpy(b1, "\x00\x00\x00\x80", 4), + memcpy(b2, "\x00\x00\x00\x7f", 4)), + 0); + EXPECT_EQ(cmpul(memcpy(b1, "\x00\x00\x00\x80", 4), + memcpy(b2, "\x00\x00\x00\x80", 4)), + 0); + EXPECT_LT(cmpul(memcpy(b1, "\x00\x00\x00\x7f", 4), + memcpy(b2, "\x00\x00\x00\x80", 4)), + 0); + EXPECT_GT(cmpul(memcpy(b1, "\x00\x00\x00\x80", 4), + memcpy(b2, "\x00\x00\x00\x7f", 4)), + 0); + tfree(b2); + tfree(b1); +} + +TEST(comparator, testQuadwordCompare) { + char *b1 = tmalloc(8); + char *b2 = tmalloc(8); + EXPECT_EQ(cmpsq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x80", 8), + memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x80", 8)), + 0); + EXPECT_GT(cmpsq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x7f", 8), + memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x80", 8)), + 0); + EXPECT_LT(cmpsq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x80", 8), + memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x7f", 8)), + 0); + EXPECT_EQ(cmpuq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x80", 8), + memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x80", 8)), + 0); + EXPECT_LT(cmpuq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x7f", 8), + memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x80", 8)), + 0); + EXPECT_GT(cmpuq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x80", 8), + memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x7f", 8)), + 0); + tfree(b2); + tfree(b1); +} diff --git a/test/libc/alg/critbit0_test.c b/test/libc/alg/critbit0_test.c new file mode 100644 index 00000000..3941f437 --- /dev/null +++ b/test/libc/alg/critbit0_test.c @@ -0,0 +1,125 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/bits/bits.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +struct Bog { + unsigned i; + unsigned n; + const char *p[]; +}; + +static testonly nodiscard struct Bog *NewBog(unsigned n) { + struct Bog *res = malloc(sizeof(struct Bog) + sizeof(const char *) * n); + res->i = 0; + res->n = n; + return res; +} +static testonly void ClearBog(struct Bog *bog) { bog->i = 0; } +static testonly void FreeBog(struct Bog **bog) { free(*bog), *bog = NULL; } + +static const char *const elems[] = {"a", "aa", "aaz", "abz", + "bba", "bbc", "bbd", NULL}; + +testonly static void MakeTree(struct critbit0 *tree) { + memset(tree, 0, sizeof(*tree)); + for (unsigned i = 0; elems[i]; ++i) { + ASSERT_EQ(true, critbit0_insert(tree, elems[i])); + } +} + +TEST(critbit0, testContains) { + struct critbit0 tree[1]; + MakeTree(tree); + for (unsigned i = 0; elems[i]; ++i) { + if (!critbit0_contains(tree, elems[i])) abort(); + } + critbit0_clear(tree); +} + +static const char *const elems2[] = {"a", "aa", "b", "bb", "ab", + "ba", "aba", "bab", NULL}; + +TEST(critbit0, testDelete) { + struct critbit0 tree = {0}; + for (unsigned i = 1; elems2[i]; ++i) { + critbit0_clear(&tree); + for (unsigned j = 0; j < i; ++j) critbit0_insert(&tree, elems2[j]); + for (unsigned j = 0; j < i; ++j) { + if (!critbit0_contains(&tree, elems2[j])) abort(); + } + for (unsigned j = 0; j < i; ++j) { + if (1 != critbit0_delete(&tree, elems2[j])) abort(); + } + for (unsigned j = 0; j < i; ++j) { + if (critbit0_contains(&tree, elems2[j])) abort(); + } + } + critbit0_clear(&tree); +} + +static testonly intptr_t allprefixed_cb(const char *elem, void *arg) { + struct Bog *bog = arg; + ASSERT_LT(bog->i, bog->n); + bog->p[bog->i++] = elem; + return 0; +} + +TEST(critbit0, testAllPrefixed) { + struct critbit0 tree[1]; + MakeTree(tree); + struct Bog *a = NewBog(4); + ASSERT_EQ(0, critbit0_allprefixed(tree, "a", allprefixed_cb, a)); + ASSERT_EQ(4, a->i); + ASSERT_STREQ("a", a->p[0]); + ASSERT_STREQ("aa", a->p[1]); + ASSERT_STREQ("aaz", a->p[2]); + ASSERT_STREQ("abz", a->p[3]); + ClearBog(a); + ASSERT_EQ(0, critbit0_allprefixed(tree, "aa", allprefixed_cb, a)); + ASSERT_EQ(2, a->i); + ASSERT_STREQ("aa", a->p[0]); + ASSERT_STREQ("aaz", a->p[1]); + critbit0_clear(tree); + FreeBog(&a); +} + +static testonly intptr_t allprefixed_cb_halt(const char *elem, void *arg) { + struct Bog *bog = arg; + ASSERT_LT(bog->i, bog->n); + bog->p[bog->i++] = elem; + return strcmp(elem, "aa") == 0 ? 123 : 0; +} + +TEST(critbit0, testAllPrefixed_haltOnNonzero) { + struct critbit0 tree[1]; + MakeTree(tree); + struct Bog *a = NewBog(4); + ASSERT_EQ(123, critbit0_allprefixed(tree, "a", allprefixed_cb_halt, a)); + ASSERT_EQ(2, a->i); + ASSERT_STREQ("a", a->p[0]); + ASSERT_STREQ("aa", a->p[1]); + critbit0_clear(tree); + FreeBog(&a); +} diff --git a/test/libc/alg/djbsort_test.c b/test/libc/alg/djbsort_test.c new file mode 100644 index 00000000..35bb550b --- /dev/null +++ b/test/libc/alg/djbsort_test.c @@ -0,0 +1,87 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/limits.h" +#include "libc/log/log.h" +#include "libc/macros.h" +#include "libc/mem/mem.h" +#include "libc/nexgen32e/nexgen32e.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/rand/rand.h" +#include "libc/runtime/gc.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +void djbsort$avx2(int32_t *, long); + +size_t n; +int32_t *a, *b, *c; + +TEST(djbsort, test4) { + static const int kA[] = {4, 3, 2, 1}; + n = ARRAYLEN(kA); + a = memcpy(tgc(tmalloc(n * 4)), kA, n * 4); + b = memcpy(tgc(tmalloc(n * 4)), kA, n * 4); + c = memcpy(tgc(tmalloc(n * 4)), kA, n * 4); + insertionsort(n, a); + djbsort$avx2(b, n); + djbsort(n, c); + ASSERT_EQ(0, memcmp(a, b, n * 4)); + ASSERT_EQ(0, memcmp(a, c, n * 4)); +} + +TEST(djbsort, test64) { + static const int kA[64] = { + -578159677, -506496753, 627992389, -1352456426, -632122174, + -1439460768, -1910607416, INT_MAX, 828129452, 388318786, + 1361377655, 178046, -250539006, -933303681, 553663398, + 801377571, 1798551167, 1926219590, 1322300030, 2005832294, + 190425814, 1896617905, -549032465, -930529122, 953163359, + -1290004523, 447201234, 1351982281, 458539920, 791518325, + -1086386708, 291355635, INT_MIN, -1891018285, 1780601656, + 1324222158, 1182663010, -1223576562, -676035738, 1367175631, + -1016599422, 1619595549, -783089669, -663931695, -1082674213, + 1369114774, -1944970907, 196888289, 1400094001, -1170906601, + 835635598, 1506409902, -1528765785, 1132926680, -351522751, + -1737707221, -209740191, -1857759507, -353087096, 763588876, + -1323943608, -1219421355, -582289873, 1062699814, + }; + n = ARRAYLEN(kA); + a = memcpy(tgc(tmalloc(n * 4)), kA, n * 4); + b = memcpy(tgc(tmalloc(n * 4)), kA, n * 4); + c = memcpy(tgc(tmalloc(n * 4)), kA, n * 4); + insertionsort(n, a); + djbsort(n, c); + ASSERT_EQ(0, memcmp(a, c, n * 4)); + if (X86_HAVE(AVX2)) { + djbsort$avx2(b, n); + ASSERT_EQ(0, memcmp(a, b, n * 4)); + } +} + +BENCH(djbsort, bench) { + n = 256; + a = gc(memalign(32, n * 4)); + EZBENCH2("insertionsort[255]", rngset(a, n * 4, rand64, -1), + insertionsort(n, a)); + EZBENCH2("djbsort[255]", rngset(a, n * 4, rand64, -1), djbsort(n, a)); +} diff --git a/test/libc/alg/memmem_test.c b/test/libc/alg/memmem_test.c new file mode 100644 index 00000000..4d4bd6e8 --- /dev/null +++ b/test/libc/alg/memmem_test.c @@ -0,0 +1,116 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/bits/bits.h" +#include "libc/str/internal.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +void *(*memmemi)(const void *, size_t, const void *, size_t) = memmem; +FIXTURE(memmem, tiny) { + memmemi = tinymemmem; +} + +#define MakeMemory(SL) memcpy(tmalloc(sizeof(SL) - 1), SL, sizeof(SL) - 1) + +TEST(memmem, test) { + char *needle = MakeMemory("abcdefgh"); + char *haystk = MakeMemory("acccccccbbbbbbbbabcdefghdddddddd"); + EXPECT_BINEQ(u"abcdefghdddddddd", memmemi(haystk, 32, needle, 8)); + memcpy(needle, "aaaaaaaa", 8); + memcpy(haystk, "acccccccbbbbbbbbaaaaaaaadddddddd", 32); + EXPECT_BINEQ(u"aaaaaaaadddddddd", memmemi(haystk, 32, needle, 8)); + tfree(haystk); + tfree(needle); +} + +TEST(memmem, testNoMatch) { + char *needle = MakeMemory("abcdefzh"); + char *haystk = MakeMemory("acccccccbbbbbbbbabcdefghdddddddd"); + EXPECT_EQ(NULL, memmemi(haystk, 32, needle, 8)); + tfree(haystk); + tfree(needle); +} + +TEST(memmem, testStartOfMemory) { + char *needle = MakeMemory("acccc"); + char *haystk = MakeMemory("acccccccbbbbbbbbabcdefghdddddddd"); + EXPECT_EQ(&haystk[0], memmemi(haystk, 32, needle, 5)); + tfree(haystk); + tfree(needle); +} + +TEST(memmem, testEndOfMemory) { + char *needle = MakeMemory("123"); + char *haystk = MakeMemory("abc123"); + EXPECT_EQ(&haystk[3], memmemi(haystk, 6, needle, 3)); + tfree(haystk); + tfree(needle); +} + +TEST(memmem, testCrossesSseRegister) { + char *needle = MakeMemory("eeeeeeeeeeeeefffffffffffff"); + char *haystk = MakeMemory("eeeeeeeeeeeeeeeeffffffffffffffffrrrrrrrrrrrrrrrr"); + EXPECT_EQ(&haystk[3], memmemi(haystk, 16 * 3, needle, 26)); + tfree(haystk); + tfree(needle); +} + +TEST(memmem, testHasNulCharacters) { + char *needle = MakeMemory("eeeeeeeeeeeee\0ffffffffffff"); + char *haystk = + MakeMemory("eeeeeeeeeeeeeeee\0fffffffffffffffrrrrrrrrrrrrrrrr"); + EXPECT_EQ(&haystk[3], memmemi(haystk, 16 * 3, needle, 26)); + tfree(haystk); + tfree(needle); +} + +TEST(memmem, testWeird) { + char *needle = MakeMemory("-*-+-+-+-+-+-+-+"); + char *haystk = MakeMemory("-+-+-+-+-+-+-+-*-+-+-+-+-+-+-+-+"); + EXPECT_EQ(14, (intptr_t)memmemi(haystk, 32, needle, 16) - (intptr_t)haystk); + tfree(haystk); + tfree(needle); +} + +TEST(memmem, testEmptyNeedle_matchesStartOfHaystack) { + char *needle = tmalloc(0); + char *haystk = MakeMemory("-+-+-+-+-+-+-+-*-+-+-+-+-+-+-+-+"); + EXPECT_EQ(0, (intptr_t)memmemi(haystk, 32, needle, 0) - (intptr_t)haystk); + tfree(haystk); + tfree(needle); +} + +TEST(memmem, testEmptyHaystack_alwaysReturnsNull) { + char *needle = MakeMemory("-*-+-+-+-+-+-+-+"); + char *haystk = tmalloc(0); + EXPECT_EQ(NULL, memmemi(haystk, 0, needle, 16)); + EXPECT_EQ(NULL, memmemi(haystk, 0, needle, 1)); + tfree(haystk); + tfree(needle); +} + +TEST(memmem, testEmptyHaystackAndNeedle_returnsHaystack) { + char *needle = tmalloc(0); + char *haystk = tmalloc(0); + EXPECT_EQ(haystk, memmemi(haystk, 0, needle, 0)); + tfree(haystk); + tfree(needle); +} diff --git a/test/libc/alg/qsort_test.c b/test/libc/alg/qsort_test.c new file mode 100644 index 00000000..8437ee8d --- /dev/null +++ b/test/libc/alg/qsort_test.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/bits/bits.h" +#include "libc/macros.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(qsort, test) { + const int32_t A[][2] = {{4, 'a'}, {65, 'b'}, {2, 'c'}, {-31, 'd'}, + {0, 'e'}, {99, 'f'}, {2, 'g'}, {83, 'h'}, + {782, 'i'}, {1, 'j'}}; + const int32_t B[][2] = {{-31, 'd'}, {0, 'e'}, {1, 'j'}, {2, 'c'}, + {2, 'g'}, {4, 'a'}, {65, 'b'}, {83, 'h'}, + {99, 'f'}, {782, 'i'}}; + int32_t(*M)[2] = tmalloc(sizeof(A)); + memcpy(M, B, sizeof(A)); + qsort(M, ARRAYLEN(A), sizeof(*M), cmpsl); + EXPECT_EQ(0, memcmp(M, B, sizeof(B))); + tfree(M); +} diff --git a/test/libc/alg/replacestr_test.c b/test/libc/alg/replacestr_test.c new file mode 100644 index 00000000..80c17f48 --- /dev/null +++ b/test/libc/alg/replacestr_test.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/errno.h" +#include "libc/testlib/testlib.h" + +#define S(x) x +#define REPLACESTR replacestr +#include "test/libc/alg/replacestr_test.inc" +#undef REPLACESTR +#undef S + +#define S(x) u##x +#define REPLACESTR replacestr16 +#include "test/libc/alg/replacestr_test.inc" +#undef REPLACESTR +#undef S + +/* #define S(x) L##x */ +/* #define REPLACESTR replacewcs */ +/* #include "test/libc/alg/replacestr_test.inc" */ +/* #undef REPLACESTR */ +/* #undef S */ diff --git a/test/libc/alg/replacestr_test.inc b/test/libc/alg/replacestr_test.inc new file mode 100644 index 00000000..e300f677 --- /dev/null +++ b/test/libc/alg/replacestr_test.inc @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +TEST(REPLACESTR, demo) { + EXPECT_STREQ(S("hello friends"), + replacestr(S("hello world"), S("world"), S("friends"))); + EXPECT_STREQ(S("bbbbbbbb"), replacestr(S("aaaa"), S("a"), S("bb"))); +} + +TEST(REPLACESTR, emptyString) { + EXPECT_STREQ(S(""), replacestr(S(""), S("x"), S("y"))); +} + +TEST(REPLACESTR, emptyNeedle) { + EXPECT_EQ(NULL, replacestr(S("a"), S(""), S("a"))); + EXPECT_EQ(EINVAL, errno); +} + +TEST(REPLACESTR, needleInReplacement_doesntExplode) { + EXPECT_STREQ(S("xxxxxxx"), replacestr(S("x"), S("x"), S("xxxxxxx"))); +} diff --git a/test/libc/alg/reverse_test.c b/test/libc/alg/reverse_test.c new file mode 100644 index 00000000..f0cacd6c --- /dev/null +++ b/test/libc/alg/reverse_test.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/reverse.h" +#include "libc/dce.h" +#include "libc/macros.h" +#include "libc/testlib/testlib.h" + +TEST(reverse, test) { + /* this test gets DCE'd :) */ + int A[3] = {1, 2, 3}; + reverse(A, ARRAYLEN(A)); + EXPECT_EQ(3, A[0]); + EXPECT_EQ(2, A[1]); + EXPECT_EQ(1, A[2]); +} + +TEST(reverse, testEmpty) { + int A[3] = {1, 2, 3}; + reverse(A, 0); + EXPECT_EQ(1, A[0]); + EXPECT_EQ(2, A[1]); + EXPECT_EQ(3, A[2]); +} diff --git a/test/libc/alg/strstr_test.c b/test/libc/alg/strstr_test.c new file mode 100644 index 00000000..4a41787b --- /dev/null +++ b/test/libc/alg/strstr_test.c @@ -0,0 +1,84 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/bits/bits.h" +#include "libc/dce.h" +#include "libc/mem/mem.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/runtime/gc.h" +#include "libc/str/internal.h" +#include "libc/testlib/testlib.h" + +#define MAKESTRING(NAME, VALUE) \ + char *NAME = strcpy(tmalloc(sizeof(VALUE) + 16), VALUE) + +char *strstr$kmp(const char *haystak, const char *needle) { + return memmem(haystak, strlen(haystak), needle, strlen(needle)); +} + +char *(*strstri)(const char *, const char *) = strstr$kmp; + +FIXTURE(strstr, sse42) { + if (X86_HAVE(SSE4_2)) { + strstri = strstr$sse42; + } +} + +TEST(strstr, test_emptyString_isFoundAtBeginning) { + MAKESTRING(haystack, "abc123def"); + ASSERT_STREQ(&haystack[0], strstri(haystack, gc(strdup("")))); + ASSERT_STREQ(&haystack[0], strstr(haystack, gc(strdup("")))); + tfree(haystack); +} + +TEST(strstr, test_notFound) { + MAKESTRING(haystack, "abc123def"); + ASSERT_EQ(NULL, strstri(haystack, gc(strdup("xyz")))); + ASSERT_EQ(NULL, strstr(haystack, gc(strdup("xyz")))); + tfree(haystack); +} + +TEST(strstr, test_middleOfString) { + MAKESTRING(haystack, "abc123def"); + ASSERT_STREQ(&haystack[3], strstri(haystack, gc(strdup("123")))); + ASSERT_STREQ(&haystack[3], strstr(haystack, gc(strdup("123")))); + tfree(haystack); +} + +TEST(strstr, test_endOfString) { + MAKESTRING(haystack, "abc123def"); + ASSERT_STREQ(&haystack[8], strstri(haystack, gc(strdup("f")))); + ASSERT_STREQ(&haystack[8], strstr(haystack, gc(strdup("f")))); + tfree(haystack); +} + +TEST(strstr, test_secondXmmWord) { + MAKESTRING(haystack, "eeeeeeeeeeeeeeeebbbbbbbbbbb123"); + ASSERT_STREQ(&haystack[27], strstri(haystack, gc(strdup("123")))); + ASSERT_STREQ(&haystack[27], strstr(haystack, gc(strdup("123")))); + tfree(haystack); +} + +TEST(strstr, test_overlapsXmmWords) { + MAKESTRING(haystack, "eeeeeeeeeeeeeeeebbbbbbbbbbbbbbb"); + ASSERT_STREQ(&haystack[15], strstri(haystack, gc(strdup("eb")))); + ASSERT_STREQ(&haystack[15], strstr(haystack, gc(strdup("eb")))); + tfree(haystack); +} diff --git a/test/libc/alg/tarjan_test.c b/test/libc/alg/tarjan_test.c new file mode 100644 index 00000000..7e252ba6 --- /dev/null +++ b/test/libc/alg/tarjan_test.c @@ -0,0 +1,126 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/macros.h" +#include "libc/testlib/testlib.h" + +STATIC_YOINK("realloc"); + +TEST(tarjan, empty_doesNothing) { + uint32_t sorted_vertices[1] = {-1u}; + uint32_t edges[][2] = {{0, 0}}; + uint32_t vertex_count = 0; + uint32_t edge_count = 0; + tarjan(vertex_count, (void *)edges, edge_count, sorted_vertices, NULL, NULL); + ASSERT_EQ(-1u, sorted_vertices[0]); +} + +TEST(tarjan, topologicalSort_noCycles) { + enum VertexIndex { A = 0, B = 1, C = 2, D = 3 }; + const char *const vertices[] = {[A] = "A", [B] = "B", [C] = "C", [D] = "D"}; + uint32_t edges[][2] = { + {A /* depends on → */, B /* which must come before A */}, + {A /* depends on → */, C /* which must come before A */}, + {A /* depends on → */, D /* which must come before A */}, + {B /* depends on → */, C /* which must come before B */}, + {B /* depends on → */, D /* which must come before B */}}; + /* + $ tsort <d_name, "foo")) hasfoo = true; + if (strcmp(ent->d_name, "bar")) hasbar = true; + } + EXPECT_TRUE(hasfoo); + EXPECT_TRUE(hasbar); + EXPECT_NE(-1, closedir(dir)); + + EXPECT_NE(-1, unlink(file2)); + EXPECT_NE(-1, unlink(file1)); + EXPECT_NE(-1, rmdir(dpath)); +} diff --git a/test/libc/calls/hefty/mkntcmdline_test.c b/test/libc/calls/hefty/mkntcmdline_test.c new file mode 100644 index 00000000..7848ded3 --- /dev/null +++ b/test/libc/calls/hefty/mkntcmdline_test.c @@ -0,0 +1,77 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/hefty/ntspawn.h" +#include "libc/errno.h" +#include "libc/mem/mem.h" +#include "libc/runtime/gc.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(mkntcmdline, emptyArgvList_isntValidCommandLine) { + char *argv[] = {NULL}; + EXPECT_EQ(NULL, gc(mkntcmdline(argv))); + EXPECT_EQ(EINVAL, errno); +} + +TEST(mkntcmdline, emptyArgs_isEmptyString) { + char *argv[] = {"", NULL}; + EXPECT_STREQ(u"", gc(mkntcmdline(argv))); +} + +TEST(mkntcmdline, ignoranceIsBliss) { + char *argv[] = {"echo", "hello", "world", NULL}; + EXPECT_STREQ(u"echo hello world", gc(mkntcmdline(argv))); +} + +TEST(mkntcmdline, spaceInArgument_getQuotesWrappedAround) { + char *argv[] = {"echo", "hello there", "world", NULL}; + EXPECT_STREQ(u"echo \"hello there\" world", gc(mkntcmdline(argv))); +} + +TEST(mkntcmdline, justQuote) { + char *argv[] = {"\"", NULL}; + EXPECT_STREQ(u"\"\\\"\"", gc(mkntcmdline(argv))); +} + +TEST(mkntcmdline, justSlash) { + char *argv[] = {"\\", NULL}; + EXPECT_STREQ(u"\\", gc(mkntcmdline(argv))); +} + +TEST(mkntcmdline, justSlashQuote) { + char *argv[] = {"\\\"", NULL}; + EXPECT_STREQ(u"\"\\\\\\\"\"" /* "\\\"" */, gc(mkntcmdline(argv))); +} + +TEST(mkntcmdline, basicQuoting) { + char *argv[] = {"a\"b c", "d", NULL}; + EXPECT_STREQ(u"\"a\\\"b c\" d" /* "a\"b c" d */, gc(mkntcmdline(argv))); +} + +TEST(mkntcmdline, testUnicode) { + char *argv1[] = { + gc(strdup("(╯°□°)╯")), + gc(strdup("要依法治国是赞美那些谁是公义的和惩罚恶人。 - 韩非")), + NULL, + }; + EXPECT_STREQ( + u"(╯°□°)╯ \"要依法治国是赞美那些谁是公义的和惩罚恶人。 - 韩非\"", + gc(mkntcmdline(memcpy(gc(malloc(sizeof(argv1))), argv1, sizeof(argv1))))); +} diff --git a/test/libc/calls/hefty/mkntenvblock_test.c b/test/libc/calls/hefty/mkntenvblock_test.c new file mode 100644 index 00000000..8130e68a --- /dev/null +++ b/test/libc/calls/hefty/mkntenvblock_test.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/gc.h" +#include "libc/calls/hefty/ntspawn.h" +#include "libc/testlib/testlib.h" + +TEST(mkntenvblock, emptyList_onlyOutputsDoubleNulStringTerminator) { + char *envp[] = {NULL}; + ASSERT_BINEQ(u"  ", gc(mkntenvblock(envp))); +} + +TEST(mkntenvblock, envp_becomesSortedDoubleNulTerminatedUtf16String) { + char *envp[] = {"u=b", "c=d", "韩=非", "uh=d", "hduc=d", NULL}; + ASSERT_BINEQ( + u"c = d   " + u"h d u c = d   " + u"u = b   " + u"u h = d   " + u"Θù= ^ù  " + u"  ", + gc(mkntenvblock(envp))); +} diff --git a/test/libc/calls/hefty/sortenvp_test.c b/test/libc/calls/hefty/sortenvp_test.c new file mode 100644 index 00000000..86d8100f --- /dev/null +++ b/test/libc/calls/hefty/sortenvp_test.c @@ -0,0 +1,33 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/gc.h" +#include "libc/calls/hefty/ntspawn.h" +#include "libc/testlib/testlib.h" + +TEST(sortenvp, test) { + char *envp[] = {"u=b", "c=d", "韩=非", "uh=d", "hduc=d", NULL}; + char **sortedenvp = gc(sortenvp(envp)); + EXPECT_STREQ("c=d", sortedenvp[0]); + EXPECT_STREQ("hduc=d", sortedenvp[1]); + EXPECT_STREQ("u=b", sortedenvp[2]); + EXPECT_STREQ("uh=d", sortedenvp[3]); + EXPECT_STREQ("韩=非", sortedenvp[4]); + EXPECT_EQ(NULL, sortedenvp[5]); +} diff --git a/test/libc/calls/hefty/spawnve_test.c b/test/libc/calls/hefty/spawnve_test.c new file mode 100644 index 00000000..e64575ac --- /dev/null +++ b/test/libc/calls/hefty/spawnve_test.c @@ -0,0 +1,74 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/hefty/spawn.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/auxv.h" +#include "libc/sysv/consts/exit.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/testlib/testlib.h" + +#define CMD (IsWindows() ? "cmd" : "sh") +#define ARG (IsWindows() ? "/c" : "-c") +#define COD (IsWindows() ? "echo %BOOP%" : "echo $BOOP") +#define OUT (IsWindows() ? u"hello♪◙" : u"hello◙") + +TEST(spawnve, testIpc) { + ssize_t got; + int pid, wstatus; + char buf[16] = {0}; + int tubes[3] = {STDIN_FILENO, -1, STDERR_FILENO}; + errno = 0; + setenv("BOOP", "hello", true); + ASSERT_EQ(0, errno); + ASSERT_NE(-1, (pid = spawnlp(0, tubes, CMD, CMD, ARG, COD, NULL))); + ASSERT_EQ(0, errno); + ASSERT_NE(-1, (got = read(tubes[1], buf, sizeof(buf)))); + ASSERT_EQ(0, errno); + ASSERT_NE(-1, waitpid(pid, &wstatus, 0)); + ASSERT_EQ(0, errno); + EXPECT_EQ(0, WEXITSTATUS(wstatus)); + EXPECT_BINEQ(OUT, buf); +} + +TEST(spawnve, testExit) { + int pid, wstatus; + ASSERT_NE(-1, (pid = spawnlp(0, NULL, CMD, CMD, ARG, "exit 42", NULL))); + ASSERT_NE(-1, waitpid(pid, &wstatus, 0)); + EXPECT_EQ(42, WEXITSTATUS(wstatus)); +} + +TEST(spawnve, testSpawnSelf) { + int pid, wstatus; + ASSERT_NE(-1, + (pid = spawnlp(0, NULL, (const char *)getauxval(AT_EXECFN), + program_invocation_name, "--testSpawnSelf", NULL))); + ASSERT_NE(-1, waitpid(pid, &wstatus, 0)); + EXPECT_EQ(123, WEXITSTATUS(wstatus)); +} +static textstartup void onspawnself() { + if (g_argc > 1 && strcmp(g_argv[1], "--testSpawnSelf") == 0) { + _exit(123); + } +} +const void *const onspawnself_ctor[] initarray = {onspawnself}; diff --git a/test/libc/calls/mkntpath_test.c b/test/libc/calls/mkntpath_test.c new file mode 100644 index 00000000..e26ed2d5 --- /dev/null +++ b/test/libc/calls/mkntpath_test.c @@ -0,0 +1,45 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/gc.h" +#include "libc/calls/internal.h" +#include "libc/testlib/testlib.h" + +char16_t p[PATH_MAX]; + +TEST(mkntpath, testEmpty) { + EXPECT_EQ(0, mkntpath("", p)); + EXPECT_STREQ(u"", p); +} + +TEST(mkntpath, testSlashes) { + /* + * The Windows command prompt works fine with all reasonable + * unix-style paths. There only seems to be one exception, and that's + * all it takes to make the feature entirely useless to us, similar to + * the law of noncontradiction. We address the issue as follows: + */ + EXPECT_EQ(9, mkntpath("o/foo.com", p)); + EXPECT_STREQ(u"o\\foo.com", p); +} + +TEST(mkntpath, testUnicode) { + EXPECT_EQ(20, mkntpath("C:\\𐌰𐌱𐌲𐌳\\𐌴𐌵𐌶𐌷", p)); + EXPECT_STREQ(u"C:\\𐌰𐌱𐌲𐌳\\𐌴𐌵𐌶𐌷", p); +} diff --git a/test/libc/calls/signal_test.c b/test/libc/calls/signal_test.c new file mode 100644 index 00000000..fa2bbfc0 --- /dev/null +++ b/test/libc/calls/signal_test.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/log/check.h" +#include "libc/log/log.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/sig.h" +#include "libc/testlib/testlib.h" + +testonly void OnCtrlC(int sig) { _exit(0); } + +TEST(signal, test) { + if (IsWindows()) return; /* omg */ + ASSERT_NE(SIG_ERR, signal(SIGINT, OnCtrlC)); + ASSERT_NE(-1, raise(SIGINT)); + die(); +} diff --git a/test/libc/calls/stat_test.c b/test/libc/calls/stat_test.c new file mode 100644 index 00000000..00efacd0 --- /dev/null +++ b/test/libc/calls/stat_test.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/struct/stat.h" +#include "libc/nt/files.h" +#include "libc/runtime/gc.h" +#include "libc/runtime/runtime.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +char *pathname; +struct stat st; + +TEST(stat_000, setupFiles) { + mkdir("o", 0755); + mkdir("o/tmp", 0755); +} + +TEST(stat_010, testEmptyFile_sizeIsZero) { + pathname = defer( + unlink, + gc(xasprintf("o/tmp/%s.%d", program_invocation_short_name, getpid()))); + ASSERT_NE(-1, touch(pathname, 0755)); + EXPECT_NE(-1, stat(pathname, &st)); + EXPECT_EQ(0, st.st_size); +} diff --git a/test/libc/calls/test.mk b/test/libc/calls/test.mk new file mode 100644 index 00000000..13e115e4 --- /dev/null +++ b/test/libc/calls/test.mk @@ -0,0 +1,60 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_CALLS + +TEST_LIBC_CALLS_SRCS := \ + $(wildcard test/libc/calls/*.c) \ + $(wildcard test/libc/calls/hefty/*.c) +TEST_LIBC_CALLS_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_CALLS_SRCS)) +TEST_LIBC_CALLS_COMS = $(TEST_LIBC_CALLS_OBJS:%.o=%.com) + +TEST_LIBC_CALLS_OBJS = \ + $(TEST_LIBC_CALLS_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_CALLS_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_CALLS_BINS = \ + $(TEST_LIBC_CALLS_COMS) \ + $(TEST_LIBC_CALLS_COMS:%=%.dbg) + +TEST_LIBC_CALLS_TESTS = \ + $(TEST_LIBC_CALLS_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_CALLS_CHECKS = \ + $(TEST_LIBC_CALLS_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_CALLS_DIRECTDEPS = \ + LIBC_CALLS \ + LIBC_CALLS_HEFTY \ + LIBC_FMT \ + LIBC_LOG \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_STR \ + LIBC_RAND \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_TESTLIB \ + LIBC_X + +TEST_LIBC_CALLS_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_CALLS_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/calls/calls.pkg: \ + $(TEST_LIBC_CALLS_OBJS) \ + $(foreach x,$(TEST_LIBC_CALLS_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/calls/%.com.dbg: \ + $(TEST_LIBC_CALLS_DEPS) \ + o/$(MODE)/test/libc/calls/%.o \ + o/$(MODE)/test/libc/calls/calls.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +.PHONY: o/$(MODE)/test/libc/calls +o/$(MODE)/test/libc/calls: \ + $(TEST_LIBC_CALLS_BINS) \ + $(TEST_LIBC_CALLS_CHECKS) diff --git a/test/libc/conv/basename_test.c b/test/libc/conv/basename_test.c new file mode 100644 index 00000000..964b58f8 --- /dev/null +++ b/test/libc/conv/basename_test.c @@ -0,0 +1,44 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/conv/conv.h" +#include "libc/testlib/testlib.h" + +TEST(basename, test) { + EXPECT_STREQ("", basename("")); + EXPECT_STREQ("hello", basename("hello")); + EXPECT_STREQ("there", basename("hello/there")); + EXPECT_STREQ("yo", basename("hello/there/yo")); +} + +TEST(basename, testTrailingSlash_isIgnored) { + /* should be "foo" but basename() doesn't allocate memory */ + EXPECT_STREQ("foo/", basename("foo/")); + EXPECT_STREQ("foo//", basename("foo//")); +} + +TEST(basename, testOnlySlashes_oneSlashOnlyVasily) { + EXPECT_STREQ("/", basename("///")); +} + +TEST(basename, testWindows_isGrantedRespect) { + EXPECT_STREQ("there", basename("hello\\there")); + EXPECT_STREQ("yo", basename("hello\\there\\yo")); +} diff --git a/test/libc/conv/llog10_test.c b/test/libc/conv/llog10_test.c new file mode 100644 index 00000000..5cd3e832 --- /dev/null +++ b/test/libc/conv/llog10_test.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/conv/conv.h" +#include "libc/limits.h" +#include "libc/testlib/testlib.h" + +TEST(llog10, test) { + EXPECT_EQ(0, llog10(1)); + EXPECT_EQ(0, llog10(2)); + EXPECT_EQ(0, llog10(9)); + EXPECT_EQ(1, llog10(10)); + EXPECT_EQ(1, llog10(11)); + EXPECT_EQ(1, llog10(99)); + EXPECT_EQ(2, llog10(100)); + EXPECT_EQ(2, llog10(101)); + EXPECT_EQ(9, llog10(INT_MAX)); + EXPECT_EQ(12, llog10(1000000000000)); +} diff --git a/test/libc/conv/sizemultiply_test.c b/test/libc/conv/sizemultiply_test.c new file mode 100644 index 00000000..5d583de9 --- /dev/null +++ b/test/libc/conv/sizemultiply_test.c @@ -0,0 +1,50 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/conv/sizemultiply.h" +#include "libc/limits.h" +#include "libc/testlib/testlib.h" + +size_t out; + +TEST(sizemultiply, testMultiplication) { + EXPECT_TRUE(sizemultiply(&out, 7, 11)); + EXPECT_EQ(7 * 11, out); + EXPECT_TRUE(sizemultiply(&out, 11, 7)); + EXPECT_EQ(7 * 11, out); + EXPECT_TRUE(sizemultiply(&out, 0, 11)); + EXPECT_EQ(0 * 11, out); + EXPECT_TRUE(sizemultiply(&out, 11, 0)); + EXPECT_EQ(0 * 11, out); +} + +TEST(sizemultiply, testOverflow_alwaysReturnsSizeMax) { + EXPECT_FALSE(sizemultiply(&out, 7, SIZE_MAX)); + EXPECT_EQ(SIZE_MAX, out); + EXPECT_FALSE(sizemultiply(&out, SIZE_MAX, 7)); + EXPECT_EQ(SIZE_MAX, out); +} + +TEST(sizemultiply, testOverflow_closeButNoCigar) { + EXPECT_TRUE(sizemultiply(&out, SIZE_MAX, 1)); + EXPECT_EQ(SIZE_MAX, out); + EXPECT_TRUE(sizemultiply(&out, 1, SIZE_MAX)); + EXPECT_EQ(SIZE_MAX, out); +} diff --git a/test/libc/conv/strtoimax_test.c b/test/libc/conv/strtoimax_test.c new file mode 100644 index 00000000..e7406a4c --- /dev/null +++ b/test/libc/conv/strtoimax_test.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/conv/conv.h" +#include "libc/testlib/testlib.h" + +/* todo(jart): work on this more */ + +TEST(strtoimax, testZero) { EXPECT_EQ(0, strtoimax("0", NULL, 0)); } +TEST(strtoimax, testDecimal) { EXPECT_EQ(-123, strtoimax("-123", NULL, 0)); } +TEST(strtoimax, testHex) { EXPECT_EQ(-255, strtoimax("-0xff", NULL, 0)); } +TEST(strtoimax, testOctal) { EXPECT_EQ(-123, strtoimax("-0173", NULL, 0)); } + +TEST(strtoimax, testLimits) { + EXPECT_EQ( + ((uintmax_t)0xffffffffffffffff) << 64 | (uintmax_t)0xffffffffffffffff, + strtoimax("-1", NULL, 0)); + EXPECT_EQ( + ((uintmax_t)0x7fffffffffffffff) << 64 | (uintmax_t)0xffffffffffffffff, + strtoimax("0x7fffffffffffffffffffffffffffffff", NULL, 0)); +} diff --git a/test/libc/conv/strtoumax_test.c b/test/libc/conv/strtoumax_test.c new file mode 100644 index 00000000..c8824b44 --- /dev/null +++ b/test/libc/conv/strtoumax_test.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/conv/conv.h" +#include "libc/limits.h" +#include "libc/testlib/testlib.h" + +TEST(strtoumax, testZero) { EXPECT_EQ(UINTMAX_MIN, strtoumax("0", NULL, 0)); } +TEST(strtoumax, testDecimal) { EXPECT_EQ(123, strtoumax("123", NULL, 0)); } +TEST(strtoumax, testHex) { EXPECT_EQ(255, strtoumax("0xff", NULL, 0)); } +TEST(strtoumax, testOctal) { EXPECT_EQ(123, strtoumax("0173", NULL, 0)); } + +TEST(strtoumax, testMaximum) { + EXPECT_EQ(UINTMAX_MAX, + strtoumax("340282366920938463463374607431768211455", NULL, 0)); + EXPECT_EQ(UINTMAX_MAX, + strtoumax("0xffffffffffffffffffffffffffffffff", NULL, 0)); +} diff --git a/test/libc/conv/test.mk b/test/libc/conv/test.mk new file mode 100644 index 00000000..a665a6ad --- /dev/null +++ b/test/libc/conv/test.mk @@ -0,0 +1,57 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_CONV + +TEST_LIBC_CONV_SRCS := $(wildcard test/libc/conv/*.c) +TEST_LIBC_CONV_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_CONV_SRCS)) +TEST_LIBC_CONV_COMS = $(TEST_LIBC_CONV_OBJS:%.o=%.com) + +TEST_LIBC_CONV_OBJS = \ + $(TEST_LIBC_CONV_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_CONV_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_CONV_BINS = \ + $(TEST_LIBC_CONV_COMS) \ + $(TEST_LIBC_CONV_COMS:%=%.dbg) + +TEST_LIBC_CONV_TESTS = \ + $(TEST_LIBC_CONV_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_CONV_CHECKS = \ + $(TEST_LIBC_CONV_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_CONV_DIRECTDEPS = \ + LIBC_CONV \ + LIBC_NEXGEN32E \ + LIBC_STUBS \ + LIBC_TESTLIB + +TEST_LIBC_CONV_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_CONV_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/conv/conv.pkg: \ + $(TEST_LIBC_CONV_OBJS) \ + $(foreach x,$(TEST_LIBC_CONV_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/conv/%.com.dbg: \ + $(TEST_LIBC_CONV_DEPS) \ + o/$(MODE)/test/libc/conv/%.o \ + o/$(MODE)/test/libc/conv/conv.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +$(TEST_LIBC_CONV_OBJS): \ + $(BUILD_FILES) \ + test/libc/conv/test.mk + +$(TEST_LIBC_CONV_OBJS): \ + DEFAULT_CCFLAGS += \ + -fno-builtin + +.PHONY: o/$(MODE)/test/libc/conv +o/$(MODE)/test/libc/conv: \ + $(TEST_LIBC_CONV_BINS) \ + $(TEST_LIBC_CONV_CHECKS) diff --git a/test/libc/conv/timevaltofiletime_test.c b/test/libc/conv/timevaltofiletime_test.c new file mode 100644 index 00000000..15c09f13 --- /dev/null +++ b/test/libc/conv/timevaltofiletime_test.c @@ -0,0 +1,33 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/struct/timeval.h" +#include "libc/conv/conv.h" +#include "libc/nt/struct/filetime.h" +#include "libc/testlib/testlib.h" +#include "libc/time/time.h" + +TEST(timevaltofiletime, roundTrip) { + struct timeval tv1, tv2; + tv1.tv_sec = 31337; + tv1.tv_usec = 1337; + filetimetotimeval(&tv2, timevaltofiletime(&tv1)); + EXPECT_EQ(31337, tv2.tv_sec); + EXPECT_EQ(1337, tv2.tv_usec); +} diff --git a/test/libc/crypto/rijndael_test.c b/test/libc/crypto/rijndael_test.c new file mode 100644 index 00000000..45a47a6f --- /dev/null +++ b/test/libc/crypto/rijndael_test.c @@ -0,0 +1,333 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/crypto/rijndael.h" +#include "libc/dce.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +/** + * Test vectors published by: + * + * Morris Dworkin + * National Institute of Standards and Technology + * Recommendation for Block Cipher Modes of Operation: Methods and Techniques + * SP 800-38A (DOI) + * December 2001 + */ + +FIXTURE(rijndael, disableHardwareExtensions) { + memset((/*unconst*/ void *)kCpuids, 0, sizeof(kCpuids)); +} + +/** + * F.1.1: ECB-AES128.Encrypt + * + * Key 2b7e151628aed2a6abf7158809cf4f3c + * + * Block No. 1 + * Plaintext 6bc1bee22e409f96e93d7e117393172a + * Input Block 6bc1bee22e409f96e93d7e117393172a + * Output Block 3ad77bb40d7a3660a89ecaf32466ef97 + * Ciphertext 3ad77bb40d7a3660a89ecaf32466ef97 + * + * Block No. 2 + * Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 + * Input Block ae2d8a571e03ac9c9eb76fac45af8e51 + * Output Block f5d3d58503b9699de785895a96fdbaaf + * Ciphertext f5d3d58503b9699de785895a96fdbaaf + * + * Block No. 3 + * Plaintext 30c81c46a35ce411e5fbc1191a0a52ef + * Input Block 30c81c46a35ce411e5fbc1191a0a52ef + * Output Block 43b1cd7f598ece23881b00e3ed030688 + * Ciphertext 43b1cd7f598ece23881b00e3ed030688 + * + * Block No. 4 + * Plaintext f69f2445df4f9b17ad2b417be66c3710 + * Input Block f69f2445df4f9b17ad2b417be66c3710 + * Output Block 7b0c785e27e8ad3f8223207104725dd4 + * Ciphertext 7b0c785e27e8ad3f8223207104725dd4 + */ +TEST(aes128, testNistEcbRijndael) { + struct Rijndael ctx; + aes_block_t k1, block; + unhexbuf(&k1, 16, "2b7e151628aed2a6abf7158809cf4f3c"); + rijndaelinit(&ctx, 10, k1, k1); + unhexbuf(&block, 16, "6bc1bee22e409f96e93d7e117393172a"); + block = rijndael(10, block, &ctx); + EXPECT_BINEQ("3ad77bb40d7a3660a89ecaf32466ef97", &block); + unhexbuf(&block, 16, "ae2d8a571e03ac9c9eb76fac45af8e51"); + block = rijndael(10, block, &ctx); + EXPECT_BINEQ("f5d3d58503b9699de785895a96fdbaaf", &block); + unhexbuf(&block, 16, "30c81c46a35ce411e5fbc1191a0a52ef"); + block = rijndael(10, block, &ctx); + EXPECT_BINEQ("43b1cd7f598ece23881b00e3ed030688", &block); + unhexbuf(&block, 16, "f69f2445df4f9b17ad2b417be66c3710"); + block = rijndael(10, block, &ctx); + EXPECT_BINEQ("7b0c785e27e8ad3f8223207104725dd4", &block); +} + +/** + * F.1.2: ECB-AES128.Decrypt + * + * Key 2b7e151628aed2a6abf7158809cf4f3c + * + * Block No. 1 + * Plaintext 3ad77bb40d7a3660a89ecaf32466ef97 + * Input Block 3ad77bb40d7a3660a89ecaf32466ef97 + * Output Block 6bc1bee22e409f96e93d7e117393172a + * Ciphertext 6bc1bee22e409f96e93d7e117393172a + * + * Block No. 2 + * Plaintext f5d3d58503b9699de785895a96fdbaaf + * Input Block f5d3d58503b9699de785895a96fdbaaf + * Output Block ae2d8a571e03ac9c9eb76fac45af8e51 + * Ciphertext ae2d8a571e03ac9c9eb76fac45af8e51 + * + * Block No. 3 + * Plaintext 43b1cd7f598ece23881b00e3ed030688 + * Input Block 43b1cd7f598ece23881b00e3ed030688 + * Output Block 30c81c46a35ce411e5fbc1191a0a52ef + * Ciphertext 30c81c46a35ce411e5fbc1191a0a52ef + * + * Block No. 4 + * Plaintext 7b0c785e27e8ad3f8223207104725dd4 + * Input Block 7b0c785e27e8ad3f8223207104725dd4 + * Output Block f69f2445df4f9b17ad2b417be66c3710 + * Ciphertext f69f2445df4f9b17ad2b417be66c3710 + */ +TEST(aes128, testNistEcbUnrijndael) { + struct Rijndael ctx; + aes_block_t k1, block; + unhexbuf(&k1, 16, "2b7e151628aed2a6abf7158809cf4f3c"); + unrijndaelinit(&ctx, 10, k1, k1); + unhexbuf(&block, 16, "3ad77bb40d7a3660a89ecaf32466ef97"); + block = unrijndael(10, block, &ctx); + EXPECT_BINEQ("6bc1bee22e409f96e93d7e117393172a", &block); + unhexbuf(&block, 16, "f5d3d58503b9699de785895a96fdbaaf"); + block = unrijndael(10, block, &ctx); + EXPECT_BINEQ("ae2d8a571e03ac9c9eb76fac45af8e51", &block); + unhexbuf(&block, 16, "43b1cd7f598ece23881b00e3ed030688"); + block = unrijndael(10, block, &ctx); + EXPECT_BINEQ("30c81c46a35ce411e5fbc1191a0a52ef", &block); + unhexbuf(&block, 16, "7b0c785e27e8ad3f8223207104725dd4"); + block = unrijndael(10, block, &ctx); + EXPECT_BINEQ("f69f2445df4f9b17ad2b417be66c3710", &block); +} + +/** + * F.1.3: ECB-AES192.Encrypt + * + * Key 8e73b0f7da0e6452c810f32b809079e5 + * 62f8ead2522c6b7b + * + * Block No. 1 + * Plaintext 6bc1bee22e409f96e93d7e117393172a + * Input Block 6bc1bee22e409f96e93d7e117393172a + * Output Block bd334f1d6e45f25ff712a214571fa5cc + * Ciphertext bd334f1d6e45f25ff712a214571fa5cc + * + * Block No. 2 + * Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 + * Input Block ae2d8a571e03ac9c9eb76fac45af8e51 + * Output Block 974104846d0ad3ad7734ecb3ecee4eef + * Ciphertext 974104846d0ad3ad7734ecb3ecee4eef + * + * Block No. 3 + * Plaintext 30c81c46a35ce411e5fbc1191a0a52ef + * Input Block 30c81c46a35ce411e5fbc1191a0a52ef + * Output Block ef7afd2270e2e60adce0ba2face6444e + * Ciphertext ef7afd2270e2e60adce0ba2face6444e + * + * Block No. 4 + * Plaintext f69f2445df4f9b17ad2b417be66c3710 + * Input Block f69f2445df4f9b17ad2b417be66c3710 + * Output Block 9a4b41ba738d6c72fb16691603c18e0e + * Ciphertext 9a4b41ba738d6c72fb16691603c18e0e + */ +TEST(aes192, testNistEcbRijndael) { + struct Rijndael ctx; + aes_block_t k1, k2, block; + unhexbuf(&k1, 16, "8e73b0f7da0e6452c810f32b809079e5"); + unhexbuf(&k2, 16, "62f8ead2522c6b7bDEADBEEFFEEDFACE"); + rijndaelinit(&ctx, 12, k1, k2); + unhexbuf(&block, 16, "6bc1bee22e409f96e93d7e117393172a"); + block = rijndael(12, block, &ctx); + EXPECT_BINEQ("bd334f1d6e45f25ff712a214571fa5cc", &block); + unhexbuf(&block, 16, "ae2d8a571e03ac9c9eb76fac45af8e51"); + block = rijndael(12, block, &ctx); + EXPECT_BINEQ("974104846d0ad3ad7734ecb3ecee4eef", &block); + unhexbuf(&block, 16, "30c81c46a35ce411e5fbc1191a0a52ef"); + block = rijndael(12, block, &ctx); + EXPECT_BINEQ("ef7afd2270e2e60adce0ba2face6444e", &block); + unhexbuf(&block, 16, "f69f2445df4f9b17ad2b417be66c3710"); + block = rijndael(12, block, &ctx); + EXPECT_BINEQ("9a4b41ba738d6c72fb16691603c18e0e", &block); +} + +/** + * F.1.4: ECB-AES192.Decrypt + * + * Key 8e73b0f7da0e6452c810f32b809079e5 + * 62f8ead2522c6b7b + * + * Block No. 1 + * Plaintext bd334f1d6e45f25ff712a214571fa5cc + * Input Block bd334f1d6e45f25ff712a214571fa5cc + * Output Block 6bc1bee22e409f96e93d7e117393172a + * Ciphertext 6bc1bee22e409f96e93d7e117393172a + * + * Block No. 2 + * Plaintext 974104846d0ad3ad7734ecb3ecee4eef + * Input Block 974104846d0ad3ad7734ecb3ecee4eef + * Output Block ae2d8a571e03ac9c9eb76fac45af8e51 + * Ciphertext ae2d8a571e03ac9c9eb76fac45af8e51 + * + * Block No. 3 + * Plaintext ef7afd2270e2e60adce0ba2face6444e + * Input Block ef7afd2270e2e60adce0ba2face6444e + * Output Block 30c81c46a35ce411e5fbc1191a0a52ef + * Ciphertext 30c81c46a35ce411e5fbc1191a0a52ef + * + * Block No. 4 + * Plaintext 9a4b41ba738d6c72fb16691603c18e0e + * Input Block 9a4b41ba738d6c72fb16691603c18e0e + * Output Block f69f2445df4f9b17ad2b417be66c3710 + * Ciphertext f69f2445df4f9b17ad2b417be66c3710 + */ +TEST(aes192, testNistEcbUnrijndael) { + struct Rijndael ctx; + aes_block_t k1, k2, block; + unhexbuf(&k1, 16, "8e73b0f7da0e6452c810f32b809079e5"); + unhexbuf(&k2, 16, "62f8ead2522c6b7bDEADBEEFFEEDFACE"); + unrijndaelinit(&ctx, 12, k1, k2); + unhexbuf(&block, 16, "bd334f1d6e45f25ff712a214571fa5cc"); + block = unrijndael(12, block, &ctx); + EXPECT_BINEQ("6bc1bee22e409f96e93d7e117393172a", &block); + unhexbuf(&block, 16, "974104846d0ad3ad7734ecb3ecee4eef"); + block = unrijndael(12, block, &ctx); + EXPECT_BINEQ("ae2d8a571e03ac9c9eb76fac45af8e51", &block); + unhexbuf(&block, 16, "ef7afd2270e2e60adce0ba2face6444e"); + block = unrijndael(12, block, &ctx); + EXPECT_BINEQ("30c81c46a35ce411e5fbc1191a0a52ef", &block); + unhexbuf(&block, 16, "9a4b41ba738d6c72fb16691603c18e0e"); + block = unrijndael(12, block, &ctx); + EXPECT_BINEQ("f69f2445df4f9b17ad2b417be66c3710", &block); +} + +/** + * F.1.5: ECB-AES256.Encrypt + * + * Key 603deb1015ca71be2b73aef0857d7781 + * 1f352c073b6108d72d9810a30914dff4 + * + * Block No. 1 + * Plaintext 6bc1bee22e409f96e93d7e117393172a + * Input Block 6bc1bee22e409f96e93d7e117393172a + * Output Block f3eed1bdb5d2a03c064b5a7e3db181f8 + * Ciphertext f3eed1bdb5d2a03c064b5a7e3db181f8 + * + * Block No. 2 + * Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 + * Input Block ae2d8a571e03ac9c9eb76fac45af8e51 + * Output Block 591ccb10d410ed26dc5ba74a31362870 + * Ciphertext 591ccb10d410ed26dc5ba74a31362870 + * + * Block No. 3 + * Plaintext 30c81c46a35ce411e5fbc1191a0a52ef + * Input Block 30c81c46a35ce411e5fbc1191a0a52ef + * Output Block b6ed21b99ca6f4f9f153e7b1beafed1d + * Ciphertext b6ed21b99ca6f4f9f153e7b1beafed1d + * + * Block No. 4 + * Plaintext f69f2445df4f9b17ad2b417be66c3710 + * Input Block f69f2445df4f9b17ad2b417be66c3710 + * Output Block 23304b7a39f9f3ff067d8d8f9e24ecc7 + * Ciphertext 23304b7a39f9f3ff067d8d8f9e24ecc7 + */ +TEST(aes256, testNistEcbRijndael) { + struct Rijndael ctx; + aes_block_t k1, k2, block; + unhexbuf(&k1, 16, "603deb1015ca71be2b73aef0857d7781"); + unhexbuf(&k2, 16, "1f352c073b6108d72d9810a30914dff4"); + rijndaelinit(&ctx, 14, k1, k2); + unhexbuf(&block, 16, "6bc1bee22e409f96e93d7e117393172a"); + block = rijndael(14, block, &ctx); + EXPECT_BINEQ("f3eed1bdb5d2a03c064b5a7e3db181f8", &block); + unhexbuf(&block, 16, "ae2d8a571e03ac9c9eb76fac45af8e51"); + block = rijndael(14, block, &ctx); + EXPECT_BINEQ("591ccb10d410ed26dc5ba74a31362870", &block); + unhexbuf(&block, 16, "30c81c46a35ce411e5fbc1191a0a52ef"); + block = rijndael(14, block, &ctx); + EXPECT_BINEQ("b6ed21b99ca6f4f9f153e7b1beafed1d", &block); + unhexbuf(&block, 16, "f69f2445df4f9b17ad2b417be66c3710"); + block = rijndael(14, block, &ctx); + EXPECT_BINEQ("23304b7a39f9f3ff067d8d8f9e24ecc7", &block); +} + +/** + * F.1.6: ECB-AES256.Decrypt + * + * Key 603deb1015ca71be2b73aef0857d7781 + * 1f352c073b6108d72d9810a30914dff4 + * + * Block No. 1 + * Input Block f3eed1bdb5d2a03c064b5a7e3db181f8 + * Plaintext f3eed1bdb5d2a03c064b5a7e3db181f8 + * Ciphertext 6bc1bee22e409f96e93d7e117393172a + * Output Block 6bc1bee22e409f96e93d7e117393172a + * + * Block No. 2 + * Input Block 591ccb10d410ed26dc5ba74a31362870 + * Plaintext 591ccb10d410ed26dc5ba74a31362870 + * Ciphertext ae2d8a571e03ac9c9eb76fac45af8e51 + * Output Block ae2d8a571e03ac9c9eb76fac45af8e51 + * + * Block No. 3 + * Input Block b6ed21b99ca6f4f9f153e7b1beafed1d + * Plaintext b6ed21b99ca6f4f9f153e7b1beafed1d + * Ciphertext 30c81c46a35ce411e5fbc1191a0a52ef + * Output Block 30c81c46a35ce411e5fbc1191a0a52ef + * + * Block No. 4 + * Input Block 23304b7a39f9f3ff067d8d8f9e24ecc7 + * Plaintext 23304b7a39f9f3ff067d8d8f9e24ecc7 + * Ciphertext f69f2445df4f9b17ad2b417be66c3710 + * Output Block f69f2445df4f9b17ad2b417be66c3710 + */ +TEST(aes256, testNistEcbUnrijndael) { + struct Rijndael ctx; + aes_block_t k1, k2, block; + unhexbuf(&k1, 16, "603deb1015ca71be2b73aef0857d7781"); + unhexbuf(&k2, 16, "1f352c073b6108d72d9810a30914dff4"); + unrijndaelinit(&ctx, 14, k1, k2); + unhexbuf(&block, 16, "f3eed1bdb5d2a03c064b5a7e3db181f8"); + block = unrijndael(14, block, &ctx); + EXPECT_BINEQ("6bc1bee22e409f96e93d7e117393172a", &block); + unhexbuf(&block, 16, "591ccb10d410ed26dc5ba74a31362870"); + block = unrijndael(14, block, &ctx); + EXPECT_BINEQ("ae2d8a571e03ac9c9eb76fac45af8e51", &block); + unhexbuf(&block, 16, "b6ed21b99ca6f4f9f153e7b1beafed1d"); + block = unrijndael(14, block, &ctx); + EXPECT_BINEQ("30c81c46a35ce411e5fbc1191a0a52ef", &block); + unhexbuf(&block, 16, "23304b7a39f9f3ff067d8d8f9e24ecc7"); + block = unrijndael(14, block, &ctx); + EXPECT_BINEQ("f69f2445df4f9b17ad2b417be66c3710", &block); +} diff --git a/test/libc/crypto/test.mk b/test/libc/crypto/test.mk new file mode 100644 index 00000000..5772e2ec --- /dev/null +++ b/test/libc/crypto/test.mk @@ -0,0 +1,49 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_CRYPTO + +TEST_LIBC_CRYPTO_SRCS := $(wildcard test/libc/crypto/*.c) +TEST_LIBC_CRYPTO_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_CRYPTO_SRCS)) +TEST_LIBC_CRYPTO_COMS = $(TEST_LIBC_CRYPTO_OBJS:%.o=%.com) + +TEST_LIBC_CRYPTO_OBJS = \ + $(TEST_LIBC_CRYPTO_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_CRYPTO_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_CRYPTO_BINS = \ + $(TEST_LIBC_CRYPTO_COMS) \ + $(TEST_LIBC_CRYPTO_COMS:%=%.dbg) + +TEST_LIBC_CRYPTO_TESTS = \ + $(TEST_LIBC_CRYPTO_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_CRYPTO_CHECKS = \ + $(TEST_LIBC_CRYPTO_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_CRYPTO_DIRECTDEPS = \ + LIBC_CRYPTO \ + LIBC_NEXGEN32E \ + LIBC_STUBS \ + LIBC_TESTLIB + +TEST_LIBC_CRYPTO_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_CRYPTO_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/crypto/crypto.pkg: \ + $(TEST_LIBC_CRYPTO_OBJS) \ + $(foreach x,$(TEST_LIBC_CRYPTO_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/crypto/%.com.dbg: \ + $(TEST_LIBC_CRYPTO_DEPS) \ + o/$(MODE)/test/libc/crypto/%.o \ + o/$(MODE)/test/libc/crypto/crypto.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +.PHONY: o/$(MODE)/test/libc/crypto +o/$(MODE)/test/libc/crypto: \ + $(TEST_LIBC_CRYPTO_BINS) \ + $(TEST_LIBC_CRYPTO_CHECKS) diff --git a/test/libc/dns/dnsheader_test.c b/test/libc/dns/dnsheader_test.c new file mode 100644 index 00000000..d7a371be --- /dev/null +++ b/test/libc/dns/dnsheader_test.c @@ -0,0 +1,48 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dns/dns.h" +#include "libc/dns/dnsheader.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(serializednsheader, test) { + struct DnsHeader header; + memset(&header, 0, sizeof(header)); + header.id = 255; + header.bf1 = true; + header.qdcount = 1; + uint8_t *buf = tmalloc(12); + ASSERT_EQ(12, serializednsheader(buf, 12, header)); + EXPECT_BINEQ(u" λ☺  ☺      ", buf); + tfree(buf); +} + +TEST(serializednsheader, fuzzSymmetry) { + uint8_t *buf = tmalloc(12); + struct DnsHeader *in = tmalloc(sizeof(struct DnsHeader)); + struct DnsHeader *out = tmalloc(sizeof(struct DnsHeader)); + ASSERT_EQ(12, serializednsheader(buf, 12, *in)); + ASSERT_EQ(12, deserializednsheader(out, buf, 12)); + ASSERT_EQ(0, memcmp(in, out, 12)); + tfree(out); + tfree(in); + tfree(buf); +} diff --git a/test/libc/dns/dnsnamecmp_test.c b/test/libc/dns/dnsnamecmp_test.c new file mode 100644 index 00000000..e5c5a5d8 --- /dev/null +++ b/test/libc/dns/dnsnamecmp_test.c @@ -0,0 +1,101 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dns/dns.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(dnsnamecmp, testEmpty) { + char *A = strcpy(tmalloc(1), ""); + char *B = strcpy(tmalloc(1), ""); + EXPECT_EQ(dnsnamecmp(A, B), 0); + EXPECT_EQ(dnsnamecmp(A, A), 0); + tfree(B); + tfree(A); +} + +TEST(dnsnamecmp, testDotless_caseInsensitiveBehavior) { + char *A = tmalloc(2); + char *B = tmalloc(2); + EXPECT_EQ(dnsnamecmp(strcpy(A, "a"), strcpy(B, "a")), 0); + EXPECT_EQ(dnsnamecmp(A, A), 0); + EXPECT_EQ(dnsnamecmp(strcpy(A, "a"), strcpy(B, "A")), 0); + EXPECT_EQ(dnsnamecmp(strcpy(A, "A"), strcpy(B, "a")), 0); + EXPECT_LT(dnsnamecmp(strcpy(A, "a"), strcpy(B, "b")), 0); + EXPECT_LT(dnsnamecmp(strcpy(A, "a"), strcpy(B, "B")), 0); + EXPECT_GT(dnsnamecmp(strcpy(A, "d"), strcpy(B, "a")), 0); + tfree(B); + tfree(A); +} + +TEST(dnsnamecmp, testMultiLabel_lexiReverse) { + char *A = tmalloc(16); + char *B = tmalloc(16); + EXPECT_EQ(dnsnamecmp(strcpy(A, "a.example"), strcpy(B, "a.example")), 0); + EXPECT_GT(dnsnamecmp(strcpy(A, "b.example"), strcpy(B, "a.example")), 0); + EXPECT_LT(dnsnamecmp(strcpy(A, "b.example"), strcpy(B, "a.examplz")), 0); + EXPECT_GT(dnsnamecmp(strcpy(A, "a.zxample"), strcpy(B, "a.examplz")), 0); + EXPECT_EQ(dnsnamecmp(strcpy(A, "c.a.example"), strcpy(B, "c.a.example")), 0); + EXPECT_GT(dnsnamecmp(strcpy(A, "d.a.example"), strcpy(B, "c.a.example")), 0); + EXPECT_LT(dnsnamecmp(strcpy(A, "cat.example"), strcpy(B, "lol.example")), 0); + tfree(B); + tfree(A); +} + +TEST(dnsnamecmp, testTldDotQualifier_canBeEqualToDottedNames) { + char *A = tmalloc(16); + char *B = tmalloc(16); + EXPECT_EQ(dnsnamecmp(strcpy(B, "aaa.example."), strcpy(A, "aaa.example")), 0); + tfree(B); + tfree(A); +} + +TEST(dnsnamecmp, testFullyQualified_alwaysComesFirst) { + char *A = tmalloc(16); + char *B = tmalloc(16); + EXPECT_LT(dnsnamecmp(strcpy(B, "aaa.example."), strcpy(A, "zzz")), 0); + EXPECT_LT(dnsnamecmp(strcpy(B, "zzz.example."), strcpy(A, "aaa")), 0); + EXPECT_GT(dnsnamecmp(strcpy(A, "zzz"), strcpy(B, "aaa.example.")), 0); + EXPECT_GT(dnsnamecmp(strcpy(A, "aaa"), strcpy(B, "zzz.example.")), 0); + tfree(B); + tfree(A); +} + +TEST(dnsnamecmp, testLikelySld_alwaysComesBeforeLocalName) { + char *A = tmalloc(16); + char *B = tmalloc(16); + EXPECT_LT(dnsnamecmp(strcpy(B, "z.e"), strcpy(A, "a")), 0); + EXPECT_LT(dnsnamecmp(strcpy(B, "aaa.example"), strcpy(A, "zzz")), 0); + EXPECT_LT(dnsnamecmp(strcpy(B, "zzz.example"), strcpy(A, "aaa")), 0); + EXPECT_GT(dnsnamecmp(strcpy(A, "zzz"), strcpy(B, "aaa.example")), 0); + EXPECT_GT(dnsnamecmp(strcpy(A, "aaa"), strcpy(B, "zzz.example")), 0); + tfree(B); + tfree(A); +} + +TEST(dnsnamecmp, testLikelySubdomain_alwaysComesAfterSld) { + char *A = tmalloc(16); + char *B = tmalloc(16); + EXPECT_LT(dnsnamecmp(strcpy(B, "a.e"), strcpy(A, "z.a.e")), 0); + EXPECT_GT(dnsnamecmp(strcpy(A, "z.a.e"), strcpy(B, "a.e")), 0); + EXPECT_LT(dnsnamecmp(strcpy(B, "b.e"), strcpy(A, "a.b.e")), 0); + EXPECT_GT(dnsnamecmp(strcpy(A, "a.b.e"), strcpy(B, "b.e")), 0); + tfree(B); + tfree(A); +} diff --git a/test/libc/dns/dnsquestion_test.c b/test/libc/dns/dnsquestion_test.c new file mode 100644 index 00000000..0b3f8a25 --- /dev/null +++ b/test/libc/dns/dnsquestion_test.c @@ -0,0 +1,50 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dns/dns.h" +#include "libc/dns/dnsquestion.h" +#include "libc/errno.h" +#include "libc/testlib/testlib.h" + +TEST(serializednsquestion, test) { + uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1 + 4); + char *name = tstrdup("foo.bar"); + struct DnsQuestion dq; + dq.qname = name; + dq.qtype = 0x0201; + dq.qclass = 0x0102; + EXPECT_EQ(1 + 3 + 1 + 3 + 1 + 4, + serializednsquestion(buf, 1 + 3 + 1 + 3 + 1 + 4, dq)); + EXPECT_BINEQ(u"♥foo♥bar ☻☺☺☻", buf); + tfree(name); + tfree(buf); +} + +TEST(serializednsquestion, testNoSpace) { + uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1 + 3); + char *name = tstrdup("foo.bar"); + struct DnsQuestion dq; + dq.qname = name; + dq.qtype = 0x0201; + dq.qclass = 0x0102; + EXPECT_EQ(-1, serializednsquestion(buf, 1 + 3 + 1 + 3 + 1 + 3, dq)); + EXPECT_EQ(ENOSPC, errno); + tfree(name); + tfree(buf); +} diff --git a/test/libc/dns/parsehoststxt_test.c b/test/libc/dns/parsehoststxt_test.c new file mode 100644 index 00000000..f4607c69 --- /dev/null +++ b/test/libc/dns/parsehoststxt_test.c @@ -0,0 +1,84 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dns/hoststxt.h" +#include "libc/mem/mem.h" +#include "libc/sock/sock.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/af.h" +#include "libc/testlib/testlib.h" + +static const char *ParseIp(unsigned char ip[4]) { + static char g_ipbuf[16]; + return inet_ntop(AF_INET, ip, g_ipbuf, sizeof(g_ipbuf)); +} + +TEST(parsehoststxt, testEmpty) { + struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt)); + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + ASSERT_EQ(0, parsehoststxt(ht, f)); + ASSERT_EQ(0, ht->entries.i); + freehoststxt(&ht); + fclose(f); +} + +TEST(parsehoststxt, testCorrectlyTokenizesAndSorts) { + const char kInput[] = + "# this is a comment\n" + "# IP HOST1 HOST2\n" + "203.0.113.1 lol.example. lol\n" + "203.0.113.2 cat.example. cat\n"; + struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt)); + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + ASSERT_EQ(strlen(kInput), fwrite(kInput, 1, strlen(kInput), f)); + ASSERT_EQ(0, parsehoststxt(ht, f)); + sorthoststxt(ht); + ASSERT_EQ(4, ht->entries.i); + EXPECT_STREQ("cat.example.", &ht->strings.p[ht->entries.p[0].name]); + EXPECT_STREQ("cat.example.", &ht->strings.p[ht->entries.p[0].canon]); + EXPECT_STREQ("203.0.113.2", ParseIp(ht->entries.p[0].ip)); + EXPECT_STREQ("lol.example.", &ht->strings.p[ht->entries.p[1].name]); + EXPECT_STREQ("lol.example.", &ht->strings.p[ht->entries.p[1].canon]); + EXPECT_STREQ("203.0.113.1", ParseIp(ht->entries.p[1].ip)); + EXPECT_STREQ("cat", &ht->strings.p[ht->entries.p[2].name]); + EXPECT_STREQ("cat.example.", &ht->strings.p[ht->entries.p[2].canon]); + EXPECT_STREQ("203.0.113.2", ParseIp(ht->entries.p[2].ip)); + EXPECT_STREQ("lol", &ht->strings.p[ht->entries.p[3].name]); + EXPECT_STREQ("lol.example.", &ht->strings.p[ht->entries.p[3].canon]); + EXPECT_STREQ("203.0.113.1", ParseIp(ht->entries.p[3].ip)); + freehoststxt(&ht); + fclose(f); +} + +TEST(parsehoststxt, testIpv6_isIgnored) { + const char kInput[] = + "::1 boop\n" + "203.0.113.2 cat # ignore me\n"; + struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt)); + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + ASSERT_EQ(strlen(kInput), fwrite(kInput, 1, strlen(kInput), f)); + ASSERT_EQ(0, parsehoststxt(ht, f)); + ASSERT_EQ(1, ht->entries.i); + EXPECT_STREQ("cat", &ht->strings.p[ht->entries.p[0].name]); + EXPECT_STREQ("cat", &ht->strings.p[ht->entries.p[0].canon]); + EXPECT_STREQ("203.0.113.2", ParseIp(ht->entries.p[0].ip)); + freehoststxt(&ht); + fclose(f); +} diff --git a/test/libc/dns/parseresolvconf_test.c b/test/libc/dns/parseresolvconf_test.c new file mode 100644 index 00000000..bca827f0 --- /dev/null +++ b/test/libc/dns/parseresolvconf_test.c @@ -0,0 +1,76 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dns/dns.h" +#include "libc/dns/hoststxt.h" +#include "libc/dns/resolvconf.h" +#include "libc/mem/mem.h" +#include "libc/sock/sock.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/af.h" +#include "libc/testlib/testlib.h" + +static const char *FormatIp(struct sockaddr_in *ip) { + static char g_ipbuf[16]; + return inet_ntop(ip->sin_family, &ip->sin_addr.s_addr, g_ipbuf, 16); +} + +TEST(parseresolvconf, testEmpty) { + struct ResolvConf *rv = calloc(1, sizeof(struct ResolvConf)); + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + ASSERT_EQ(0, parseresolvconf(rv, f)); + ASSERT_EQ(0, rv->nameservers.i); + freeresolvconf(&rv); + fclose(f); +} + +TEST(parseresolvconf, testCorrectlyTokenizes) { + const char kInput[] = + "# this is a comment\n" + "nameserver 203.0.113.2 \n" + " nameserver 203.0.113.1\n"; + struct ResolvConf *rv = calloc(1, sizeof(struct ResolvConf)); + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + ASSERT_EQ(strlen(kInput), fwrite(kInput, 1, strlen(kInput), f)); + ASSERT_EQ(2, parseresolvconf(rv, f)); + ASSERT_EQ(2, rv->nameservers.i); + EXPECT_EQ(AF_INET, rv->nameservers.p[0].sin_family); + EXPECT_EQ(DNS_PORT, ntohs(rv->nameservers.p[0].sin_port)); + EXPECT_STREQ("203.0.113.2", FormatIp(&rv->nameservers.p[0])); + EXPECT_EQ(AF_INET, rv->nameservers.p[1].sin_family); + EXPECT_EQ(DNS_PORT, ntohs(rv->nameservers.p[1].sin_port)); + EXPECT_STREQ("203.0.113.1", FormatIp(&rv->nameservers.p[1])); + freeresolvconf(&rv); + fclose(f); +} + +TEST(parseresolvconf, testSearchLocal_setsLoopback) { + const char kInput[] = "search local # boop\n"; + struct ResolvConf *rv = calloc(1, sizeof(struct ResolvConf)); + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + ASSERT_EQ(strlen(kInput), fwrite(kInput, 1, strlen(kInput), f)); + ASSERT_EQ(1, parseresolvconf(rv, f)); + ASSERT_EQ(1, rv->nameservers.i); + EXPECT_EQ(AF_INET, rv->nameservers.p[0].sin_family); + EXPECT_EQ(DNS_PORT, ntohs(rv->nameservers.p[0].sin_port)); + EXPECT_STREQ("127.0.0.1", FormatIp(&rv->nameservers.p[0])); + freeresolvconf(&rv); + fclose(f); +} diff --git a/test/libc/dns/pascalifydnsname_test.c b/test/libc/dns/pascalifydnsname_test.c new file mode 100644 index 00000000..300016e7 --- /dev/null +++ b/test/libc/dns/pascalifydnsname_test.c @@ -0,0 +1,79 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dns/dns.h" +#include "libc/errno.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(pascalifydnsname, testEmpty) { + uint8_t *buf = tmalloc(1); + char *name = tstrdup(""); + EXPECT_EQ(0, pascalifydnsname(buf, 1, name)); + EXPECT_BINEQ(u" ", buf); + tfree(name); + tfree(buf); +} + +TEST(pascalifydnsname, testOneLabel) { + uint8_t *buf = tmalloc(1 + 3 + 1); + char *name = tstrdup("foo"); + EXPECT_EQ(1 + 3, pascalifydnsname(buf, 1 + 3 + 1, name)); + EXPECT_BINEQ(u"♥foo ", buf); + tfree(name); + tfree(buf); +} + +TEST(pascalifydnsname, testTwoLabels) { + uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1); + char *name = tstrdup("foo.bar"); + EXPECT_EQ(1 + 3 + 1 + 3, pascalifydnsname(buf, 1 + 3 + 1 + 3 + 1, name)); + EXPECT_BINEQ(u"♥foo♥bar ", buf); + tfree(name); + tfree(buf); +} + +TEST(pascalifydnsname, testFqdnDot_isntIncluded) { + uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1); + char *name = tstrdup("foo.bar."); + EXPECT_EQ(1 + 3 + 1 + 3, pascalifydnsname(buf, 1 + 3 + 1 + 3 + 1, name)); + EXPECT_BINEQ(u"♥foo♥bar ", buf); + tfree(name); + tfree(buf); +} + +TEST(pascalifydnsname, testTooLong) { + uint8_t *buf = tmalloc(1); + char *name = tmalloc(1000); + memset(name, '.', 999); + name[999] = '\0'; + EXPECT_EQ(-1, pascalifydnsname(buf, 1, name)); + EXPECT_EQ(ENAMETOOLONG, errno); + tfree(name); + tfree(buf); +} + +TEST(pascalifydnsname, testNoSpace) { + uint8_t *buf = tmalloc(1); + char *name = tstrdup("foo"); + EXPECT_EQ(-1, pascalifydnsname(buf, 1, name)); + EXPECT_EQ(ENOSPC, errno); + tfree(name); + tfree(buf); +} diff --git a/test/libc/dns/resolvehoststxt_test.c b/test/libc/dns/resolvehoststxt_test.c new file mode 100644 index 00000000..93a05d64 --- /dev/null +++ b/test/libc/dns/resolvehoststxt_test.c @@ -0,0 +1,83 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dns/dns.h" +#include "libc/dns/hoststxt.h" +#include "libc/mem/mem.h" +#include "libc/sock/sock.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/af.h" +#include "libc/testlib/testlib.h" + +static const char *EzIp4Lookup(const struct HostsTxt *ht, const char *name) { + struct sockaddr_in addr4; + if (resolvehoststxt(ht, AF_INET, name, (void *)&addr4, + sizeof(struct sockaddr_in), NULL) > 0) { + static char g_ipbuf[16]; + return inet_ntop(AF_INET, &addr4.sin_addr, g_ipbuf, sizeof(g_ipbuf)); + } else { + return NULL; + } +} + +static const char *EzCanonicalize(const struct HostsTxt *ht, const char *name) { + const char *res; + return resolvehoststxt(ht, AF_INET, name, NULL, 0, &res) > 0 ? res : NULL; +} + +static const char kInput[] = "127.0.0.1 localhost\n" + "203.0.113.1 lol.example. lol\n" + "203.0.113.2 cat.example. cat\n"; + +TEST(resolvehoststxt, testBasicLookups) { + struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt)); + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + ASSERT_EQ(strlen(kInput), fwrite(kInput, 1, strlen(kInput), f)); + ASSERT_EQ(0, parsehoststxt(ht, f)); + sorthoststxt(ht); + ASSERT_EQ(5, ht->entries.i); + EXPECT_STREQ("127.0.0.1", EzIp4Lookup(ht, "localhost")); + EXPECT_STREQ("203.0.113.1", EzIp4Lookup(ht, "lol")); + EXPECT_STREQ("203.0.113.1", EzIp4Lookup(ht, "lol.example")); + EXPECT_STREQ("203.0.113.1", EzIp4Lookup(ht, "lol.example.")); + EXPECT_STREQ("203.0.113.2", EzIp4Lookup(ht, "cat")); + EXPECT_STREQ("203.0.113.2", EzIp4Lookup(ht, "cat.example.")); + EXPECT_EQ(NULL, EzIp4Lookup(ht, "boop")); + freehoststxt(&ht); + fclose(f); +} + +TEST(resolvehoststxt, testCanonicalize) { + struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt)); + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + ASSERT_EQ(strlen(kInput), fwrite(kInput, 1, strlen(kInput), f)); + ASSERT_EQ(0, parsehoststxt(ht, f)); + sorthoststxt(ht); + ASSERT_EQ(5, ht->entries.i); + EXPECT_STREQ("localhost", EzCanonicalize(ht, "localhost")); + EXPECT_STREQ("lol.example.", EzCanonicalize(ht, "lol")); + EXPECT_STREQ("lol.example.", EzCanonicalize(ht, "lol.example")); + EXPECT_STREQ("lol.example.", EzCanonicalize(ht, "lol.example.")); + EXPECT_STREQ("cat.example.", EzCanonicalize(ht, "cat")); + EXPECT_STREQ("cat.example.", EzCanonicalize(ht, "cat.example.")); + EXPECT_EQ(NULL, EzCanonicalize(ht, "boop")); + freehoststxt(&ht); + fclose(f); +} diff --git a/test/libc/dns/test.mk b/test/libc/dns/test.mk new file mode 100644 index 00000000..cf7936a1 --- /dev/null +++ b/test/libc/dns/test.mk @@ -0,0 +1,59 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_DNS + +TEST_LIBC_DNS_SRCS := $(wildcard test/libc/dns/*.c) +TEST_LIBC_DNS_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_DNS_SRCS)) +TEST_LIBC_DNS_COMS = $(TEST_LIBC_DNS_OBJS:%.o=%.com) + +TEST_LIBC_DNS_OBJS = \ + $(TEST_LIBC_DNS_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_DNS_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_DNS_BINS = \ + $(TEST_LIBC_DNS_COMS) \ + $(TEST_LIBC_DNS_COMS:%=%.dbg) + +TEST_LIBC_DNS_TESTS = \ + $(TEST_LIBC_DNS_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_DNS_CHECKS = \ + $(TEST_LIBC_DNS_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_DNS_DIRECTDEPS = \ + LIBC_CALLS_HEFTY \ + LIBC_DNS \ + LIBC_FMT \ + LIBC_LOG \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_SOCK \ + LIBC_STDIO \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_TESTLIB \ + LIBC_X + +TEST_LIBC_DNS_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_DNS_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/dns/dns.pkg: \ + $(TEST_LIBC_DNS_OBJS) \ + $(foreach x,$(TEST_LIBC_DNS_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/dns/%.com.dbg: \ + $(TEST_LIBC_DNS_DEPS) \ + o/$(MODE)/test/libc/dns/%.o \ + o/$(MODE)/test/libc/dns/dns.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +.PHONY: o/$(MODE)/test/libc/dns +o/$(MODE)/test/libc/dns: \ + $(TEST_LIBC_DNS_BINS) \ + $(TEST_LIBC_DNS_CHECKS) diff --git a/test/libc/fmt/palandprintf_test.c b/test/libc/fmt/palandprintf_test.c new file mode 100644 index 00000000..853263b4 --- /dev/null +++ b/test/libc/fmt/palandprintf_test.c @@ -0,0 +1,653 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│ +╚══════════════════════════════════════════════════════════════════════════════╝ +│ @author (c) Marco Paland (info@paland.com) │ +│ 2014-2019, PALANDesign Hannover, Germany │ +│ │ +│ @license The MIT License (MIT) │ +│ │ +│ Permission is hereby granted, free of charge, to any person obtaining a copy │ +│ of this software and associated documentation files (the "Software"), to deal│ +│ in the Software without restriction, including without limitation the rights │ +│ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell │ +│ copies of the Software, and to permit persons to whom the Software is │ +│ furnished to do so, subject to the following conditions: │ +│ │ +│ The above copyright notice and this permission notice shall be included in │ +│ all copies or substantial portions of the Software. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR │ +│ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, │ +│ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE │ +│ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER │ +│ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,│ +│ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN │ +│ THE SOFTWARE. │ +└─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/progn.h" +#include "libc/bits/pushpop.h" +#include "libc/bits/safemacros.h" +#include "libc/errno.h" +#include "libc/fmt/fmt.h" +#include "libc/math.h" +#include "libc/mem/mem.h" +#include "libc/runtime/gc.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +static char buffer[128]; +#define Format(...) PROGN(snprintf(buffer, sizeof(buffer), __VA_ARGS__), buffer) + +TEST(sprintf, test_space_flag) { + EXPECT_STREQ(" 42", Format("% d", 42)); + EXPECT_STREQ("-42", Format("% d", -42)); + EXPECT_STREQ(" 42", Format("% 5d", 42)); + EXPECT_STREQ(" -42", Format("% 5d", -42)); + EXPECT_STREQ(" 42", Format("% 15d", 42)); + EXPECT_STREQ(" -42", Format("% 15d", -42)); + EXPECT_STREQ(" -42", Format("% 15d", -42)); + EXPECT_STREQ(" -42.987", Format("% 15.3f", -42.987)); + EXPECT_STREQ(" 42.987", Format("% 15.3f", 42.987)); + EXPECT_STREQ("Hello testing", Format("% s", "Hello testing")); + EXPECT_STREQ(" 1024", Format("% d", 1024)); + EXPECT_STREQ("-1024", Format("% d", -1024)); + EXPECT_STREQ(" 1024", Format("% i", 1024)); + EXPECT_STREQ("-1024", Format("% i", -1024)); + EXPECT_STREQ("1024", Format("% u", 1024)); + EXPECT_STREQ("4294966272", Format("% u", 4294966272U)); + EXPECT_STREQ("777", Format("% o", 511)); + EXPECT_STREQ("37777777001", Format("% o", 4294966785U)); + EXPECT_STREQ("1234abcd", Format("% x", 305441741)); + EXPECT_STREQ("edcb5433", Format("% x", 3989525555U)); + EXPECT_STREQ("1234ABCD", Format("% X", 305441741)); + EXPECT_STREQ("EDCB5433", Format("% X", 3989525555U)); + EXPECT_STREQ("x", Format("% c", 'x')); +} + +TEST(sprintf, test_plus_flag) { + EXPECT_STREQ("+42", Format("%+d", 42)); + EXPECT_STREQ("-42", Format("%+d", -42)); + EXPECT_STREQ(" +42", Format("%+5d", 42)); + EXPECT_STREQ(" -42", Format("%+5d", -42)); + EXPECT_STREQ(" +42", Format("%+15d", 42)); + EXPECT_STREQ(" -42", Format("%+15d", -42)); + EXPECT_STREQ("+1024", Format("%+d", 1024)); + EXPECT_STREQ("-1024", Format("%+d", -1024)); + EXPECT_STREQ("+1024", Format("%+i", 1024)); + EXPECT_STREQ("-1024", Format("%+i", -1024)); + EXPECT_STREQ("1024", Format("%+u", 1024)); + EXPECT_STREQ("4294966272", Format("%+u", 4294966272U)); + EXPECT_STREQ("777", Format("%+o", 511)); + EXPECT_STREQ("37777777001", Format("%+o", 4294966785U)); + EXPECT_STREQ("1234abcd", Format("%+x", 305441741)); + EXPECT_STREQ("edcb5433", Format("%+x", 3989525555U)); + EXPECT_STREQ("1234ABCD", Format("%+X", 305441741)); + EXPECT_STREQ("EDCB5433", Format("%+X", 3989525555U)); + EXPECT_STREQ("+", Format("%+.0d", 0)); +} + +TEST(sprintf, test_flag0) { + EXPECT_STREQ("42", Format("%0d", 42)); + EXPECT_STREQ("42", Format("%0ld", 42L)); + EXPECT_STREQ("-42", Format("%0d", -42)); + EXPECT_STREQ("00042", Format("%05d", 42)); + EXPECT_STREQ("-0042", Format("%05d", -42)); + EXPECT_STREQ("000000000000042", Format("%015d", 42)); + EXPECT_STREQ("-00000000000042", Format("%015d", -42)); + EXPECT_STREQ("000000000042.12", Format("%015.2f", 42.1234)); + EXPECT_STREQ("00000000042.988", Format("%015.3f", 42.9876)); + EXPECT_STREQ("-00000042.98760", Format("%015.5f", -42.9876)); +} + +TEST(sprintf, test_flag_minus) { + EXPECT_STREQ("42", Format("%-d", 42)); + EXPECT_STREQ("-42", Format("%-d", -42)); + EXPECT_STREQ("42 ", Format("%-5d", 42)); + EXPECT_STREQ("-42 ", Format("%-5d", -42)); + EXPECT_STREQ("42 ", Format("%-15d", 42)); + EXPECT_STREQ("-42 ", Format("%-15d", -42)); + EXPECT_STREQ("42", Format("%-0d", 42)); + EXPECT_STREQ("-42", Format("%-0d", -42)); + EXPECT_STREQ("42 ", Format("%-05d", 42)); + EXPECT_STREQ("-42 ", Format("%-05d", -42)); + EXPECT_STREQ("42 ", Format("%-015d", 42)); + EXPECT_STREQ("-42 ", Format("%-015d", -42)); + EXPECT_STREQ("42", Format("%0-d", 42)); + EXPECT_STREQ("-42", Format("%0-d", -42)); + EXPECT_STREQ("42 ", Format("%0-5d", 42)); + EXPECT_STREQ("-42 ", Format("%0-5d", -42)); + EXPECT_STREQ("42 ", Format("%0-15d", 42)); + EXPECT_STREQ("-42 ", Format("%0-15d", -42)); +} + +TEST(sprintf, testAlternativeFormatting) { + EXPECT_STREQ("0", Format("%#x", 0)); + EXPECT_STREQ("", Format("%#.0x", 0)); + EXPECT_STREQ("0", Format("%#.1x", 0)); + EXPECT_STREQ("", Format("%#.0llx", (long long)0)); + EXPECT_STREQ("0x0000614e", Format("%#.8x", 0x614e)); + EXPECT_STREQ("0b110", Format("%#b", 6)); +} + +TEST(sprintf, testHexBasePrefix_onlyConsumesLeadingZeroes) { + /* TODO(jart): Upstream bug fix for this behavior. */ + EXPECT_STREQ("0x01", Format("%#04x", 0x1)); + EXPECT_STREQ("0x12", Format("%#04x", 0x12)); + EXPECT_STREQ("0x123", Format("%#04x", 0x123)); + EXPECT_STREQ("0x1234", Format("%#04x", 0x1234)); +} + +TEST(sprintf, testBinaryBasePrefix_onlyConsumesLeadingZeroes) { + EXPECT_STREQ("0b01", Format("%#04b", 0b1)); + EXPECT_STREQ("0b10", Format("%#04b", 0b10)); + EXPECT_STREQ("0b101", Format("%#04b", 0b101)); + EXPECT_STREQ("0b1010", Format("%#04b", 0b1010)); +} + +TEST(sprintf, testOctalBasePrefix_onlyConsumesLeadingZeroes) { + EXPECT_STREQ("0001", Format("%#04o", 01)); + EXPECT_STREQ("0010", Format("%#04o", 010)); + EXPECT_STREQ("0101", Format("%#04o", 0101)); + EXPECT_STREQ("01010", Format("%#04o", 01010)); +} + +TEST(sprintf, test_specifier) { + EXPECT_STREQ("Hello testing", Format("Hello testing")); + EXPECT_STREQ("Hello testing", Format("%s", "Hello testing")); + EXPECT_STREQ("1024", Format("%d", 1024)); + EXPECT_STREQ("-1024", Format("%d", -1024)); + EXPECT_STREQ("1024", Format("%i", 1024)); + EXPECT_STREQ("-1024", Format("%i", -1024)); + EXPECT_STREQ("1024", Format("%u", 1024)); + EXPECT_STREQ("4294966272", Format("%u", 4294966272U)); + EXPECT_STREQ("777", Format("%o", 511)); + EXPECT_STREQ("37777777001", Format("%o", 4294966785U)); + EXPECT_STREQ("1234abcd", Format("%x", 305441741)); + EXPECT_STREQ("edcb5433", Format("%x", 3989525555U)); + EXPECT_STREQ("1234ABCD", Format("%X", 305441741)); + EXPECT_STREQ("EDCB5433", Format("%X", 3989525555U)); + EXPECT_STREQ("%", Format("%%")); +} + +TEST(sprintf, test_width) { + EXPECT_STREQ("Hello testing", Format("%1s", "Hello testing")); + EXPECT_STREQ("1024", Format("%1d", 1024)); + EXPECT_STREQ("-1024", Format("%1d", -1024)); + EXPECT_STREQ("1024", Format("%1i", 1024)); + EXPECT_STREQ("-1024", Format("%1i", -1024)); + EXPECT_STREQ("1024", Format("%1u", 1024)); + EXPECT_STREQ("4294966272", Format("%1u", 4294966272U)); + EXPECT_STREQ("777", Format("%1o", 511)); + EXPECT_STREQ("37777777001", Format("%1o", 4294966785U)); + EXPECT_STREQ("1234abcd", Format("%1x", 305441741)); + EXPECT_STREQ("edcb5433", Format("%1x", 3989525555U)); + EXPECT_STREQ("1234ABCD", Format("%1X", 305441741)); + EXPECT_STREQ("EDCB5433", Format("%1X", 3989525555U)); + EXPECT_STREQ("x", Format("%1c", 'x')); +} + +TEST(sprintf, test_width_20) { + /* TODO(jart): wut */ + /* sprintf(buffer, "%20s", "Hello"); */ + /* printf("'%s' %d\n", buffer, strlen(buffer)); */ + /* EXPECT_STREQ(" Hello", buffer); */ + EXPECT_STREQ(" 1024", Format("%20d", 1024)); + EXPECT_STREQ(" -1024", Format("%20d", -1024)); + EXPECT_STREQ(" 1024", Format("%20i", 1024)); + EXPECT_STREQ(" -1024", Format("%20i", -1024)); + EXPECT_STREQ(" 1024", Format("%20u", 1024)); + EXPECT_STREQ(" 4294966272", Format("%20u", 4294966272U)); + EXPECT_STREQ(" 777", Format("%20o", 511)); + EXPECT_STREQ(" 37777777001", Format("%20o", 4294966785U)); + EXPECT_STREQ(" 1234abcd", Format("%20x", 305441741)); + EXPECT_STREQ(" edcb5433", Format("%20x", 3989525555U)); + EXPECT_STREQ(" 1234ABCD", Format("%20X", 305441741)); + EXPECT_STREQ(" EDCB5433", Format("%20X", 3989525555U)); + EXPECT_STREQ(" x", Format("%20c", 'x')); +} + +TEST(sprintf, test_width_star_20) { + EXPECT_STREQ(" Hello", Format("%*s", 20, "Hello")); + EXPECT_STREQ(" 1024", Format("%*d", 20, 1024)); + EXPECT_STREQ(" -1024", Format("%*d", 20, -1024)); + EXPECT_STREQ(" 1024", Format("%*i", 20, 1024)); + EXPECT_STREQ(" -1024", Format("%*i", 20, -1024)); + EXPECT_STREQ(" 1024", Format("%*u", 20, 1024)); + EXPECT_STREQ(" 4294966272", Format("%*u", 20, 4294966272U)); + EXPECT_STREQ(" 777", Format("%*o", 20, 511)); + EXPECT_STREQ(" 37777777001", Format("%*o", 20, 4294966785U)); + EXPECT_STREQ(" 1234abcd", Format("%*x", 20, 305441741)); + EXPECT_STREQ(" edcb5433", Format("%*x", 20, 3989525555U)); + EXPECT_STREQ(" 1234ABCD", Format("%*X", 20, 305441741)); + EXPECT_STREQ(" EDCB5433", Format("%*X", 20, 3989525555U)); + EXPECT_STREQ(" x", Format("%*c", 20, 'x')); +} + +TEST(sprintf, test_width_minus_20) { + EXPECT_STREQ("Hello ", Format("%-20s", "Hello")); + EXPECT_STREQ("1024 ", Format("%-20d", 1024)); + EXPECT_STREQ("-1024 ", Format("%-20d", -1024)); + EXPECT_STREQ("1024 ", Format("%-20i", 1024)); + EXPECT_STREQ("-1024 ", Format("%-20i", -1024)); + EXPECT_STREQ("1024 ", Format("%-20u", 1024)); + EXPECT_STREQ("1024.1234 ", Format("%-20.4f", 1024.1234)); + EXPECT_STREQ("4294966272 ", Format("%-20u", 4294966272U)); + EXPECT_STREQ("777 ", Format("%-20o", 511)); + EXPECT_STREQ("37777777001 ", Format("%-20o", 4294966785U)); + EXPECT_STREQ("1234abcd ", Format("%-20x", 305441741)); + EXPECT_STREQ("edcb5433 ", Format("%-20x", 3989525555U)); + EXPECT_STREQ("1234ABCD ", Format("%-20X", 305441741)); + EXPECT_STREQ("EDCB5433 ", Format("%-20X", 3989525555U)); + EXPECT_STREQ("x ", Format("%-20c", 'x')); + EXPECT_STREQ("| 9| |9 | | 9|", Format("|%5d| |%-2d| |%5d|", 9, 9, 9)); + EXPECT_STREQ("| 10| |10| | 10|", + Format("|%5d| |%-2d| |%5d|", 10, 10, 10)); + EXPECT_STREQ("| 9| |9 | | 9|", + Format("|%5d| |%-12d| |%5d|", 9, 9, 9)); + EXPECT_STREQ("| 10| |10 | | 10|", + Format("|%5d| |%-12d| |%5d|", 10, 10, 10)); +} + +TEST(sprintf, test_width_0_minus_20) { + EXPECT_STREQ("Hello ", Format("%0-20s", "Hello")); + EXPECT_STREQ("1024 ", Format("%0-20d", 1024)); + EXPECT_STREQ("-1024 ", Format("%0-20d", -1024)); + EXPECT_STREQ("1024 ", Format("%0-20i", 1024)); + EXPECT_STREQ("-1024 ", Format("%0-20i", -1024)); + EXPECT_STREQ("1024 ", Format("%0-20u", 1024)); + EXPECT_STREQ("4294966272 ", Format("%0-20u", 4294966272U)); + EXPECT_STREQ("777 ", Format("%0-20o", 511)); + EXPECT_STREQ("37777777001 ", Format("%0-20o", 4294966785U)); + EXPECT_STREQ("1234abcd ", Format("%0-20x", 305441741)); + EXPECT_STREQ("edcb5433 ", Format("%0-20x", 3989525555U)); + EXPECT_STREQ("1234ABCD ", Format("%0-20X", 305441741)); + EXPECT_STREQ("EDCB5433 ", Format("%0-20X", 3989525555U)); + EXPECT_STREQ("x ", Format("%0-20c", 'x')); +} + +TEST(sprintf, test_padding_20) { + EXPECT_STREQ("00000000000000001024", Format("%020d", 1024)); + EXPECT_STREQ("-0000000000000001024", Format("%020d", -1024)); + EXPECT_STREQ("00000000000000001024", Format("%020i", 1024)); + EXPECT_STREQ("-0000000000000001024", Format("%020i", -1024)); + EXPECT_STREQ("00000000000000001024", Format("%020u", 1024)); + EXPECT_STREQ("00000000004294966272", Format("%020u", 4294966272U)); + EXPECT_STREQ("00000000000000000777", Format("%020o", 511)); + EXPECT_STREQ("00000000037777777001", Format("%020o", 4294966785U)); + EXPECT_STREQ("0000000000001234abcd", Format("%020x", 305441741)); + EXPECT_STREQ("000000000000edcb5433", Format("%020x", 3989525555U)); + EXPECT_STREQ("0000000000001234ABCD", Format("%020X", 305441741)); + EXPECT_STREQ("000000000000EDCB5433", Format("%020X", 3989525555U)); +} + +TEST(sprintf, test_padding_dot_20) { + EXPECT_STREQ("00000000000000001024", Format("%.20d", 1024)); + EXPECT_STREQ("-00000000000000001024", Format("%.20d", -1024)); + EXPECT_STREQ("00000000000000001024", Format("%.20i", 1024)); + EXPECT_STREQ("-00000000000000001024", Format("%.20i", -1024)); + EXPECT_STREQ("00000000000000001024", Format("%.20u", 1024)); + EXPECT_STREQ("00000000004294966272", Format("%.20u", 4294966272U)); + EXPECT_STREQ("00000000000000000777", Format("%.20o", 511)); + EXPECT_STREQ("00000000037777777001", Format("%.20o", 4294966785U)); + EXPECT_STREQ("0000000000001234abcd", Format("%.20x", 305441741)); + EXPECT_STREQ("000000000000edcb5433", Format("%.20x", 3989525555U)); + EXPECT_STREQ("0000000000001234ABCD", Format("%.20X", 305441741)); + EXPECT_STREQ("000000000000EDCB5433", Format("%.20X", 3989525555U)); +} + +TEST(sprintf, test_padding_pound_020) { + EXPECT_STREQ("00000000000000001024", Format("%#020d", 1024)); + EXPECT_STREQ("-0000000000000001024", Format("%#020d", -1024)); + EXPECT_STREQ("00000000000000001024", Format("%#020i", 1024)); + EXPECT_STREQ("-0000000000000001024", Format("%#020i", -1024)); + EXPECT_STREQ("00000000000000001024", Format("%#020u", 1024)); + EXPECT_STREQ("00000000004294966272", Format("%#020u", 4294966272U)); + EXPECT_STREQ("00000000000000000777", Format("%#020o", 511)); + EXPECT_STREQ("00000000037777777001", Format("%#020o", 4294966785U)); + EXPECT_STREQ("0x00000000001234abcd", Format("%#020x", 305441741)); + EXPECT_STREQ("0x0000000000edcb5433", Format("%#020x", 3989525555U)); + EXPECT_STREQ("0x00000000001234ABCD", Format("%#020X", 305441741)); + EXPECT_STREQ("0x0000000000EDCB5433", Format("%#020X", 3989525555U)); +} + +TEST(sprintf, test_padding_pound_20) { + EXPECT_STREQ(" 1024", Format("%#20d", 1024)); + EXPECT_STREQ(" -1024", Format("%#20d", -1024)); + EXPECT_STREQ(" 1024", Format("%#20i", 1024)); + EXPECT_STREQ(" -1024", Format("%#20i", -1024)); + EXPECT_STREQ(" 1024", Format("%#20u", 1024)); + EXPECT_STREQ(" 4294966272", Format("%#20u", 4294966272U)); + EXPECT_STREQ(" 0777", Format("%#20o", 511)); + EXPECT_STREQ(" 037777777001", Format("%#20o", 4294966785U)); + EXPECT_STREQ(" 0x1234abcd", Format("%#20x", 305441741)); + EXPECT_STREQ(" 0xedcb5433", Format("%#20x", 3989525555U)); + EXPECT_STREQ(" 0x1234ABCD", Format("%#20X", 305441741)); + EXPECT_STREQ(" 0xEDCB5433", Format("%#20X", 3989525555U)); +} + +TEST(sprintf, test_padding_20_point_5) { + EXPECT_STREQ(" 01024", Format("%20.5d", 1024)); + EXPECT_STREQ(" -01024", Format("%20.5d", -1024)); + EXPECT_STREQ(" 01024", Format("%20.5i", 1024)); + EXPECT_STREQ(" -01024", Format("%20.5i", -1024)); + EXPECT_STREQ(" 01024", Format("%20.5u", 1024)); + EXPECT_STREQ(" 4294966272", Format("%20.5u", 4294966272U)); + EXPECT_STREQ(" 00777", Format("%20.5o", 511)); + EXPECT_STREQ(" 37777777001", Format("%20.5o", 4294966785U)); + EXPECT_STREQ(" 1234abcd", Format("%20.5x", 305441741)); + EXPECT_STREQ(" 00edcb5433", Format("%20.10x", 3989525555U)); + EXPECT_STREQ(" 1234ABCD", Format("%20.5X", 305441741)); + EXPECT_STREQ(" 00EDCB5433", Format("%20.10X", 3989525555U)); +} + +TEST(sprintf, test_padding_neg_numbers) { + /* space padding */ + EXPECT_STREQ("-5", Format("% 1d", -5)); + EXPECT_STREQ("-5", Format("% 2d", -5)); + EXPECT_STREQ(" -5", Format("% 3d", -5)); + EXPECT_STREQ(" -5", Format("% 4d", -5)); + /* zero padding */ + EXPECT_STREQ("-5", Format("%01d", -5)); + EXPECT_STREQ("-5", Format("%02d", -5)); + EXPECT_STREQ("-05", Format("%03d", -5)); + EXPECT_STREQ("-005", Format("%04d", -5)); +} + +TEST(sprintf, test_float_padding_neg_numbers) { + /* space padding */ + EXPECT_STREQ("-5.0", Format("% 3.1f", -5.)); + EXPECT_STREQ("-5.0", Format("% 4.1f", -5.)); + EXPECT_STREQ(" -5.0", Format("% 5.1f", -5.)); + /* zero padding */ + EXPECT_STREQ("-5.0", Format("%03.1f", -5.)); + EXPECT_STREQ("-5.0", Format("%04.1f", -5.)); + EXPECT_STREQ("-05.0", Format("%05.1f", -5.)); + /* zero padding no decimal point */ + EXPECT_STREQ("-5", Format("%01.0f", -5.)); + EXPECT_STREQ("-5", Format("%02.0f", -5.)); + EXPECT_STREQ("-05", Format("%03.0f", -5.)); +} + +TEST(sprintf, test_length) { + EXPECT_STREQ("", Format("%.0s", "Hello testing")); + EXPECT_STREQ(" ", Format("%20.0s", "Hello testing")); + EXPECT_STREQ("", Format("%.s", "Hello testing")); + EXPECT_STREQ(" ", Format("%20.s", "Hello testing")); + EXPECT_STREQ(" 1024", Format("%20.0d", 1024)); + EXPECT_STREQ(" -1024", Format("%20.0d", -1024)); + EXPECT_STREQ(" ", Format("%20.d", 0)); + EXPECT_STREQ(" 1024", Format("%20.0i", 1024)); + EXPECT_STREQ(" -1024", Format("%20.i", -1024)); + EXPECT_STREQ(" ", Format("%20.i", 0)); + EXPECT_STREQ(" 1024", Format("%20.u", 1024)); + EXPECT_STREQ(" 4294966272", Format("%20.0u", 4294966272U)); + EXPECT_STREQ(" ", Format("%20.u", 0U)); + EXPECT_STREQ(" 777", Format("%20.o", 511)); + EXPECT_STREQ(" 37777777001", Format("%20.0o", 4294966785U)); + EXPECT_STREQ(" ", Format("%20.o", 0U)); + EXPECT_STREQ(" 1234abcd", Format("%20.x", 305441741)); + EXPECT_STREQ(" 1234abcd", + Format("%50.x", 305441741)); + EXPECT_STREQ(" 1234abcd 12345", + Format("%50.x%10.u", 305441741, 12345)); + EXPECT_STREQ(" edcb5433", Format("%20.0x", 3989525555U)); + EXPECT_STREQ(" ", Format("%20.x", 0U)); + EXPECT_STREQ(" 1234ABCD", Format("%20.X", 305441741)); + EXPECT_STREQ(" EDCB5433", Format("%20.0X", 3989525555U)); + EXPECT_STREQ(" ", Format("%20.X", 0U)); + EXPECT_STREQ(" ", Format("%02.0u", 0U)); + EXPECT_STREQ(" ", Format("%02.0d", 0)); +} + +TEST(sprintf, test_float) { +#ifndef __FINITE_MATH_ONLY__ + EXPECT_STREQ("nan", Format("%.4f", NAN)); +#endif + EXPECT_STREQ("3.1415", Format("%.4f", 3.1415354)); + EXPECT_STREQ("30343.142", Format("%.3f", 30343.1415354)); + EXPECT_STREQ("34", Format("%.0f", 34.1415354)); + EXPECT_STREQ("1", Format("%.0f", 1.3)); + EXPECT_STREQ("2", Format("%.0f", 1.55)); + EXPECT_STREQ("1.6", Format("%.1f", 1.64)); + EXPECT_STREQ("42.90", Format("%.2f", 42.8952)); + EXPECT_STREQ("42.895200000", Format("%.9f", 42.8952)); + EXPECT_STREQ("42.8952230000", Format("%.10f", 42.895223)); + /* this testcase checks, that the precision is truncated to 9 digits. */ + /* a perfect working float should return the whole number */ + EXPECT_STREQ("42.895223123000", Format("%.12f", 42.89522312345678)); + /* this testcase checks, that the precision is truncated AND rounded to 9 */ + /* digits. a perfect working float should return the whole number */ + EXPECT_STREQ("42.895223877000", Format("%.12f", 42.89522387654321)); + EXPECT_STREQ(" 42.90", Format("%6.2f", 42.8952)); + EXPECT_STREQ("+42.90", Format("%+6.2f", 42.8952)); + EXPECT_STREQ("+42.9", Format("%+5.1f", 42.9252)); + EXPECT_STREQ("42.500000", Format("%f", 42.5)); + EXPECT_STREQ("42.5", Format("%.1f", 42.5)); + EXPECT_STREQ("42167.000000", Format("%f", 42167.0)); + EXPECT_STREQ("-12345.987654321", Format("%.9f", -12345.987654321)); + EXPECT_STREQ("4.0", Format("%.1f", 3.999)); + EXPECT_STREQ("4", Format("%.0f", 3.5)); + EXPECT_STREQ("4", Format("%.0f", 4.5)); + EXPECT_STREQ("3", Format("%.0f", 3.49)); + EXPECT_STREQ("3.5", Format("%.1f", 3.49)); + EXPECT_STREQ("a0.5 ", Format("a%-5.1f", 0.5)); + EXPECT_STREQ("a0.5 end", Format("a%-5.1fend", 0.5)); + /* out of range in the moment, need to be fixed by someone */ + EXPECT_STREQ("INFINITY", Format("%.1f", 1E20)); +} + +TEST(sprintf, test_types) { + EXPECT_STREQ("0", Format("%i", 0)); + EXPECT_STREQ("1234", Format("%i", 1234)); + EXPECT_STREQ("32767", Format("%i", 32767)); + EXPECT_STREQ("-32767", Format("%i", -32767)); + EXPECT_STREQ("30", Format("%li", 30L)); + EXPECT_STREQ("-2147483647", Format("%li", -2147483647L)); + EXPECT_STREQ("2147483647", Format("%li", 2147483647L)); + EXPECT_STREQ("30", Format("%lli", 30LL)); + EXPECT_STREQ("-9223372036854775807", Format("%lli", -9223372036854775807LL)); + EXPECT_STREQ("9223372036854775807", Format("%lli", 9223372036854775807LL)); + EXPECT_STREQ("100000", Format("%lu", 100000L)); + EXPECT_STREQ("4294967295", Format("%lu", 0xFFFFFFFFL)); + EXPECT_STREQ("281474976710656", Format("%llu", 281474976710656LLU)); + EXPECT_STREQ("18446744073709551615", Format("%llu", 18446744073709551615LLU)); + EXPECT_STREQ("2147483647", Format("%zu", 2147483647UL)); + EXPECT_STREQ("2147483647", Format("%zd", 2147483647UL)); + if (sizeof(size_t) == sizeof(long)) { + EXPECT_STREQ("-2147483647", Format("%zi", -2147483647L)); + } else { + EXPECT_STREQ("-2147483647", Format("%zi", -2147483647LL)); + } + EXPECT_STREQ("1110101001100000", Format("%b", 60000)); + EXPECT_STREQ("101111000110000101001110", Format("%lb", 12345678L)); + EXPECT_STREQ("165140", Format("%o", 60000)); + EXPECT_STREQ("57060516", Format("%lo", 12345678L)); + EXPECT_STREQ("12345678", Format("%lx", 0x12345678L)); + EXPECT_STREQ("1234567891234567", Format("%llx", 0x1234567891234567LLU)); + EXPECT_STREQ("abcdefab", Format("%lx", 0xabcdefabL)); + EXPECT_STREQ("ABCDEFAB", Format("%lX", 0xabcdefabL)); + EXPECT_STREQ("v", Format("%c", 'v')); + EXPECT_STREQ("wv", Format("%cv", 'w')); + EXPECT_STREQ("A Test", Format("%s", "A Test")); + EXPECT_STREQ("255", Format("%hhu", 0xFFFFUL)); + EXPECT_STREQ("a", Format("%tx", &buffer[10] - &buffer[0])); + /* TBD */ + EXPECT_STREQ("-2147483647", Format("%ji", (intmax_t)-2147483647L)); +} + +TEST(sprintf, testOverflow_truncationNotSaturation) { + errno = 0; + EXPECT_STREQ("13398", Format("%hu", 0x123456UL)); + EXPECT_EQ(ERANGE, errno); + errno = 0; + EXPECT_STREQ("Test16 65535", Format("%s%hhi %hu", "Test", 10000, 0xFFFFFFFF)); + EXPECT_EQ(ERANGE, errno); +} + +TEST(sprintf, test_pointer) { + sprintf(buffer, "%p", (void *)0x1234U); + if (sizeof(void *) == 4U) { + EXPECT_STREQ("00001234", buffer); + } else { + EXPECT_STREQ("000000001234", buffer); + } + sprintf(buffer, "%p", (void *)0x12345678U); + if (sizeof(void *) == 4U) { + EXPECT_STREQ("12345678", buffer); + } else { + EXPECT_STREQ("000012345678", buffer); + } + sprintf(buffer, "%p-%p", (void *)0x12345678U, (void *)0x7EDCBA98U); + if (sizeof(void *) == 4U) { + EXPECT_STREQ("12345678-7edcba98", buffer); + } else { + EXPECT_STREQ("000012345678-00007edcba98", buffer); + } + if (sizeof(uintptr_t) == sizeof(uint64_t)) { + sprintf(buffer, "%p", (void *)(uintptr_t)0xFFFFFFFFU); + EXPECT_STREQ("0000ffffffff", buffer); + } else { + sprintf(buffer, "%p", (void *)(uintptr_t)0xFFFFFFFFU); + EXPECT_STREQ("ffffffff", buffer); + } +} + +TEST(sprintf, test_unknown_flag) { + EXPECT_STREQ("kmarco", Format("%kmarco", 42, 37)); +} + +TEST(sprintf, test_buffer_length) { + int ret; + /* EXPECT_EQ(4, snprintf(pushpop(NULL), 10, "%s", "Test")); */ + EXPECT_EQ(4, snprintf(pushpop(NULL), 0, "%s", "Test")); + buffer[0] = (char)0xA5; + ret = snprintf(buffer, 0, "%s", "Test"); + EXPECT_TRUE(buffer[0] == (char)0xA5); + EXPECT_TRUE(ret == 4); + buffer[0] = (char)0xCC; + snprintf(buffer, 1, "%s", pushpop(&"Test"[0])); + EXPECT_TRUE(buffer[0] == '\0'); + snprintf(buffer, 2, "%s", pushpop(&"Hello"[0])); + EXPECT_STREQ("H", buffer); +} + +TEST(sprintf, test_ret_value) { + int ret; + ret = snprintf(buffer, 6, "0%s", "1234"); + EXPECT_STREQ("01234", buffer); + EXPECT_TRUE(ret == 5); + ret = snprintf(buffer, 6, "0%s", pushpop(&"12345"[0])); + EXPECT_STREQ("01234", buffer); + EXPECT_TRUE(ret == 6); /* '5' is truncated */ + ret = snprintf(buffer, 6, "0%s", pushpop(&"1234567"[0])); + EXPECT_STREQ("01234", buffer); + EXPECT_TRUE(ret == 8); /* '567' are truncated */ + ret = snprintf(buffer, 10, pushpop(&"hello, world"[0])); + EXPECT_TRUE(ret == 12); + ret = snprintf(buffer, 3, "%d", pushpop(10000)); + EXPECT_TRUE(ret == 5); + EXPECT_TRUE(strlen(buffer) == 2U); + EXPECT_TRUE(buffer[0] == '1'); + EXPECT_TRUE(buffer[1] == '0'); + EXPECT_TRUE(buffer[2] == '\0'); +} + +TEST(sprintf, test_misc) { + EXPECT_STREQ("53000atest-20 bit", + Format("%u%u%ctest%d %s", 5, 3000, 'a', -20, "bit")); + EXPECT_STREQ("0.33", Format("%.*f", 2, 0.33333333)); + EXPECT_STREQ("1", Format("%.*d", -1, 1)); + EXPECT_STREQ("foo", Format("%.3s", "foobar")); + EXPECT_STREQ(" ", Format("% .0d", 0)); + EXPECT_STREQ(" 00004", Format("%10.5d", 4)); + EXPECT_STREQ("hi x", Format("%*sx", -3, "hi")); +} + +TEST(sprintf, test_snprintf) { + snprintf(buffer, 100U, "%d", -1000); + EXPECT_STREQ("-1000", buffer); + snprintf(buffer, 3U, "%d", pushpop(-1000)); + EXPECT_STREQ("-1", buffer); +} + +testonly void vsnprintf_builder_1(char *buf, ...) { + va_list args; + va_start(args, buf); + vsnprintf(buf, 100U, "%d", args); + va_end(args); +} + +testonly void vsnprintf_builder_3(char *buf, ...) { + va_list args; + va_start(args, buf); + vsnprintf(buf, 100U, "%d %d %s", args); + va_end(args); +} + +TEST(sprintf, test_vsnprintf) { + vsnprintf_builder_1(buffer, -1); + EXPECT_STREQ("-1", buffer); + vsnprintf_builder_3(buffer, 3, -1000, "test"); + EXPECT_STREQ("3 -1000 test", buffer); +} + +TEST(xasprintf, test) { + void *pp; + ASSERT_STREQ("hello 123", (pp = xasprintf("hello %d", 123))); + free(pp); +} + +TEST(xasprintf, pointer_doesntShowNonCanonicalZeroes) { + ASSERT_STREQ("100000000010", gc(xasprintf("%p", 0x0000100000000010))); + ASSERT_STREQ("0x100000000010", gc(xasprintf("%#p", 0x0000100000000010))); +} + +TEST(xasprintf, nonCanonicalPointer_discardsHighBits_ratherThanSaturate) { + ASSERT_STREQ("100000000010", gc(xasprintf("%p", 0x1000100000000010))); + ASSERT_STREQ("0x100000000010", gc(xasprintf("%#p", 0x1000100000000010))); + ASSERT_STREQ("7fffffffffff", gc(xasprintf("%p", 0x7fffffffffff))); + ASSERT_STREQ("0x7fffffffffff", gc(xasprintf("%#p", 0x7fffffffffff))); +} + +TEST(snprintf, testFixedWidthString_wontOverrunInput) { + const int N = 2; + char *buf = tmalloc(N + 1); + char *inp = memcpy(tmalloc(N), "hi", N); + EXPECT_EQ(2, snprintf(buf, N + 1, "%.*s", N, inp)); + EXPECT_BINEQ(u"hi ", buf); + tfree(inp); + tfree(buf); +} + +TEST(snprintf, testFixedWidthStringIsNull_wontOverrunBuffer) { + int N = 3; + char *buf = tmalloc(N + 1); + EXPECT_EQ(6, snprintf(buf, N + 1, "%.*s", pushpop(N), pushpop(NULL))); + EXPECT_BINEQ(u"(nu ", buf); + EXPECT_EQ(6, snprintf(buf, N + 1, "%#.*s", pushpop(N), pushpop(NULL))); + EXPECT_BINEQ(u"(nu ", buf); + EXPECT_EQ(4, snprintf(buf, N + 1, "%`.*s", pushpop(N), pushpop(NULL))); + EXPECT_BINEQ(u"NUL ", buf); + EXPECT_EQ(4, snprintf(buf, N + 1, "%`#.*s", pushpop(N), pushpop(NULL))); + EXPECT_BINEQ(u"NUL ", buf); + tfree(buf); +} + +TEST(snprintf, testFixedWidthStringIsNull_wontLeakMemory) { + int N = 16; + char *buf = tmalloc(N + 1); + memset(buf, 0, N + 1); + EXPECT_EQ(6, snprintf(buf, N + 1, "%.*s", pushpop(N), pushpop(NULL))); + EXPECT_BINEQ(u"(null)           ", buf); + memset(buf, 0, N + 1); + EXPECT_EQ(6, snprintf(buf, N + 1, "%#.*s", pushpop(N), pushpop(NULL))); + EXPECT_BINEQ(u"(null)           ", buf); + memset(buf, 0, N + 1); + EXPECT_EQ(4, snprintf(buf, N + 1, "%`.*s", pushpop(N), pushpop(NULL))); + EXPECT_BINEQ(u"NULL             ", buf); + memset(buf, 0, N + 1); + EXPECT_EQ(4, snprintf(buf, N + 1, "%`#.*s", pushpop(N), pushpop(NULL))); + EXPECT_BINEQ(u"NULL             ", buf); + tfree(buf); +} diff --git a/test/libc/fmt/sprintf_s.inc b/test/libc/fmt/sprintf_s.inc new file mode 100644 index 00000000..37e1c82a --- /dev/null +++ b/test/libc/fmt/sprintf_s.inc @@ -0,0 +1,76 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +/* MODE=tiny makes these dependencies optional */ +STATIC_YOINK("strnwidth"); +STATIC_YOINK("strnwidth16"); +STATIC_YOINK("wcsnwidth"); + +TEST(SUITE(sprintf), testStringLength) { + ASSERT_STREQ("This", Format(FORMAT("%.4"), STRING("This is a test"))); + ASSERT_STREQ("test", Format(FORMAT("%.4"), STRING("test"))); + ASSERT_STREQ("123", Format(FORMAT("%.7"), STRING("123"))); + ASSERT_STREQ("", Format(FORMAT("%.7"), STRING(""))); + ASSERT_STREQ("1234ab", Format(FORMAT("%.4") FORMAT("%.2"), STRING("123456"), + STRING("abcdef"))); + ASSERT_STREQ(FORMAT(".2"), Format(FORMAT("%.4.2"), STRING("123456"))); + ASSERT_STREQ("123", Format(FORMAT("%.*"), 3, STRING("123456"))); +} + +TEST(SUITE(sprintf), testCharacterCounting) { + ASSERT_STREQ(" ♥♦♣♠☺☻▲", Format(FORMAT("%16"), STRING("♥♦♣♠☺☻▲"))); +} + +TEST(SUITE(snprintf), testTableFlip) { + EXPECT_STREQ("Table flip ", Format("%-20ls", L"Table flip")); + EXPECT_STREQ("(╯°□°)╯︵ ┻━┻ ", Format("%-20ls", L"(╯°□°)╯︵ ┻━┻")); + EXPECT_STREQ("ちゃぶ台返し ", Format("%-20ls", L"ちゃぶ台返し")); + EXPECT_STREQ(" (╯°□°)╯︵ ┻━┻", Format("%20ls", L"(╯°□°)╯︵ ┻━┻")); + EXPECT_STREQ(" ちゃぶ台返し", Format("%20ls", L"ちゃぶ台返し")); +} + +TEST(SUITE(snprintf), testCombiningWidth) { + EXPECT_STREQ("H̲E̲L̲L̲O̲ ", + Format("%-10ls", L"H\u0332E\u0332L\u0332L\u0332O\u0332")); + EXPECT_STREQ(" H̲E̲L̲L̲O̲", + Format("%10hs", u"H\u0332E\u0332L\u0332L\u0332O\u0332")); +} + +TEST(SUITE(snprintf), testQuoting) { + EXPECT_STREQ("\\\"hi┻\\'━┻", Format("%'s", "\"hi┻'━┻")); + EXPECT_STREQ(STRINGIFY("\"hi┻\'━┻"), Format("%`'s", "\"hi┻'━┻")); + EXPECT_STREQ(STRINGIFY("\177\"hi┻\'━┻"), Format("%`'s", "\x7f\"hi┻'━┻")); +} + +TEST(SUITE(snprintf), testBing_cString_stopsAtNulTerminator) { + EXPECT_STREQ("♥♦♣♠", Format("%#s", "\3\4\5\6\0\3\4\5\6")); +} + +TEST(SUITE(snprintf), testBing_precisionString_showsTrueBinary) { + EXPECT_STREQ("♥♦♣♠ ♥♦♣♠", Format("%#.*s", 9, "\3\4\5\6\0\3\4\5\6")); +} + +TEST(SUITE(snprintf), testStringPrecision_showsTrueBinary) { + EXPECT_STREQ("\3\4\0", Format("%.*s", 3, "\3\4\0")); +} + +TEST(SUITE(snprintf), testPrecision_usesCodepointCount) { + EXPECT_STREQ("ちゃぶ台返し", Format("%.*s", 6, "ちゃぶ台返し")); +} diff --git a/test/libc/fmt/sprintf_s_test.c b/test/libc/fmt/sprintf_s_test.c new file mode 100644 index 00000000..9e95c054 --- /dev/null +++ b/test/libc/fmt/sprintf_s_test.c @@ -0,0 +1,60 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/progn.h" +#include "libc/bits/safemacros.h" +#include "libc/fmt/fmt.h" +#include "libc/testlib/testlib.h" + +static char buffer[128]; + +#define Format(...) PROGN(snprintf(buffer, sizeof(buffer), __VA_ARGS__), buffer) + +/** + * @fileoverview String formatting tests. + * + * We use textual includes here to test UTF-8, UTF-16, and UTF-32 at the + * same time, since Cosmopolitan is designed to support them all without + * conditions. + */ + +#define SUITE(NAME) NAME##s +#define FORMAT(STR) STR "s" +#define STRING(STR) STR +#include "test/libc/fmt/sprintf_s.inc" +#undef SUITE +#undef FORMAT +#undef STRING + +#define SUITE(NAME) NAME##hs +#define FORMAT(STR) STR "hs" +#define STRING(STR) u##STR +#include "test/libc/fmt/sprintf_s.inc" +#undef SUITE +#undef FORMAT +#undef STRING + +#define SUITE(NAME) NAME##ls +#define FORMAT(STR) STR "ls" +#define STRING(STR) L##STR +#include "test/libc/fmt/sprintf_s.inc" +#undef SUITE +#undef FORMAT +#undef STRING diff --git a/test/libc/fmt/sscanf_test.c b/test/libc/fmt/sscanf_test.c new file mode 100644 index 00000000..b3056d6a --- /dev/null +++ b/test/libc/fmt/sscanf_test.c @@ -0,0 +1,144 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/errno.h" +#include "libc/fmt/fmt.h" +#include "libc/limits.h" +#include "libc/mem/mem.h" +#include "libc/testlib/testlib.h" + +#define sscanf1(STR, FMT) \ + ({ \ + errno = 0; \ + intmax_t x = 0; \ + EXPECT_EQ(1, sscanf(STR, FMT, &x)); \ + x; \ + }) + +TEST(sscanf, testMultiple) { + int a, b, c; + ASSERT_EQ(3, sscanf("123 123 123", "%d %x %o", &a, &b, &c)); + EXPECT_EQ(123, a); + EXPECT_EQ(0x123, b); + EXPECT_EQ(0123, c); +} + +TEST(sscanf, testDecimal) { + EXPECT_EQ(123, sscanf1("123", "%d")); + EXPECT_EQ(123, sscanf1("123", "%n")); + EXPECT_EQ(123, sscanf1("123", "%u")); + EXPECT_EQ((uint32_t)-123, sscanf1("-123", "%d")); +} + +TEST(sscanf, testHex) { + EXPECT_EQ(0x123, sscanf1("123", "%x")); + EXPECT_EQ(0x123, sscanf1("0x123", "%x")); + EXPECT_EQ(0x123, sscanf1("0123", "%x")); + EXPECT_EQ(INTMAX_MAX, + sscanf1("170141183460469231731687303715884105727", "%jd")); + EXPECT_EQ(INTMAX_MIN, + sscanf1("-170141183460469231731687303715884105728", "%jd")); + EXPECT_EQ(UINTMAX_MAX, sscanf1("0xffffffffffffffffffffffffffffffff", "%jx")); +} + +TEST(sscanf, testOctal) { + EXPECT_EQ(0123, sscanf1("123", "%o")); + EXPECT_EQ(0123, sscanf1("0123", "%o")); +} + +TEST(sscanf, testNonDirectiveCharacterMatching) { + EXPECT_EQ(0, sscanf("", "")); + EXPECT_EQ(0, sscanf("%", "%%")); +} + +TEST(sscanf, testCharacter) { + char c = 0; + EXPECT_EQ(1, sscanf("a", "%c", &c)); + EXPECT_EQ('a', c); +} + +TEST(sscanf, testStringBuffer) { + char s1[32], s2[32]; + ASSERT_EQ(2, sscanf("abc xyz", "%s %s", s1, s2)); + EXPECT_STREQ("abc", &s1[0]); + EXPECT_STREQ("xyz", &s2[0]); +} + +TEST(sscanf, testStringBuffer_gothicUtf8ToUtf8_roundTrips) { + char s1[64], s2[64]; + ASSERT_EQ(2, sscanf("𐌰𐌱𐌲𐌳 𐌴𐌵𐌶𐌷", "%63s %63s", s1, s2)); + EXPECT_STREQ("𐌰𐌱𐌲𐌳", s1); + EXPECT_STREQ("𐌴𐌵𐌶𐌷", s2); +} + +TEST(sscanf, testStringBuffer_gothicUtf8ToUtf16) { + char16_t s1[64], s2[64]; + ASSERT_EQ(2, sscanf("𐌰𐌱𐌲𐌳 𐌴𐌵𐌶𐌷", "%63hs %63hs", s1, s2)); + EXPECT_STREQ(u"𐌰𐌱𐌲𐌳", s1); + EXPECT_STREQ(u"𐌴𐌵𐌶𐌷", s2); +} + +TEST(sscanf, testStringBuffer_gothicUtf8ToUtf32) { + wchar_t s1[64], s2[64]; + ASSERT_EQ(2, sscanf("𐌰𐌱𐌲𐌳 𐌴𐌵𐌶𐌷", "%63ls %63ls", s1, s2)); + EXPECT_STREQ(L"𐌰𐌱𐌲𐌳", s1); + EXPECT_STREQ(L"𐌴𐌵𐌶𐌷", s2); +} + +TEST(sscanf, testStringBuffer_allocatingBehavior) { + char *s1, *s2; + ASSERT_EQ(2, sscanf("𐌰𐌱𐌲𐌳 𐌴𐌵𐌶𐌷", "%ms %ms", &s1, &s2)); + EXPECT_STREQ("𐌰𐌱𐌲𐌳", s1); + EXPECT_STREQ("𐌴𐌵𐌶𐌷", s2); + free(s1); + free(s2); +} + +TEST(sscanf, testPracticalBusinessApplication) { + unsigned start, stop; + char width; + ASSERT_EQ(1, sscanf("0BF3..", "%x", &start)); + EXPECT_EQ(0x0BF3, start); + ASSERT_EQ(3, sscanf("0BF3..0BF8;N # So [6] TAMIL DAY SIGN", + "%x..%x;%c", &start, &stop, &width)); + EXPECT_EQ(0x0BF3, start); + EXPECT_EQ(0x0BF8, stop); + EXPECT_EQ('N', width); +} + +TEST(sscanf, socketListenUri) { + char proto[4]; + unsigned char ip4[4]; + uint16_t port; + ASSERT_EQ(6, sscanf("tcp:127.0.0.1:31337", "%3s:%hhu.%hhu.%hhu.%hhu:%hu", + proto, &ip4[0], &ip4[1], &ip4[2], &ip4[3], &port)); + ASSERT_STREQ("tcp", proto); + ASSERT_EQ(127, ip4[0]); + ASSERT_EQ(0, ip4[1]); + ASSERT_EQ(0, ip4[2]); + ASSERT_EQ(1, ip4[3]); + ASSERT_EQ(31337, port); +} + +TEST(sscanf, testDiscard_notIncludedInCount) { + char buf[8]; + ASSERT_EQ(1, sscanf("hello there", "%*s %8s", buf)); + EXPECT_STREQ("there", buf); +} diff --git a/test/libc/fmt/strerror_test.c b/test/libc/fmt/strerror_test.c new file mode 100644 index 00000000..f79e05ac --- /dev/null +++ b/test/libc/fmt/strerror_test.c @@ -0,0 +1,54 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/fmt/fmt.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +/* + * If these tests break, it's probably because + * libc/sysv/consts.sh changed and + * libc/sysv/kErrnoNames.S needs updating. + */ + +TEST(strerror, enosys) { + if (IsTiny()) return; + EXPECT_STARTSWITH("ENOSYS", strerror(ENOSYS)); +} + +TEST(strerror, symbolizingTheseNumbersAsErrorsIsHeresyInUnixStyle) { + EXPECT_STARTSWITH("E?/err=0/errno:0/GetLastError:0", strerror(0)); + EXPECT_STARTSWITH("E?", strerror(-1)); +} + +TEST(strerror, enotconn_orLinkerIsntUsingLocaleC_orCodeIsOutOfSync) { + if (IsTiny()) return; + EXPECT_STARTSWITH("ENOTCONN", strerror(ENOTCONN)); +} + +TEST(strerror, exfull_orLinkerIsntUsingLocaleC_orCodeIsOutOfSync) { + if (IsLinux() && !IsTiny()) { + EXPECT_STARTSWITH("EXFULL", strerror(EXFULL)); + } else { + EXPECT_STARTSWITH("E?", strerror(EXFULL)); + } +} diff --git a/test/libc/fmt/test.mk b/test/libc/fmt/test.mk new file mode 100644 index 00000000..4a422081 --- /dev/null +++ b/test/libc/fmt/test.mk @@ -0,0 +1,55 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_FMT + +TEST_LIBC_FMT_SRCS := $(wildcard test/libc/fmt/*.c) +TEST_LIBC_FMT_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_FMT_SRCS)) +TEST_LIBC_FMT_COMS = $(TEST_LIBC_FMT_OBJS:%.o=%.com) +TEST_LIBC_FMT_BINS = $(TEST_LIBC_FMT_COMS) $(TEST_LIBC_FMT_COMS:%=%.dbg) +TEST_LIBC_FMT_TESTS = $(TEST_LIBC_FMT_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_FMT_OBJS = \ + $(TEST_LIBC_FMT_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_FMT_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_FMT_CHECKS = \ + $(TEST_LIBC_FMT_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_FMT_DIRECTDEPS = \ + LIBC_CALLS_HEFTY \ + LIBC_FMT \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_TESTLIB \ + LIBC_UNICODE \ + LIBC_X + +TEST_LIBC_FMT_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_FMT_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/fmt/fmt.pkg: \ + $(TEST_LIBC_FMT_OBJS) \ + $(foreach x,$(TEST_LIBC_FMT_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/fmt/%.com.dbg: \ + $(TEST_LIBC_FMT_DEPS) \ + o/$(MODE)/test/libc/fmt/%.o \ + o/$(MODE)/test/libc/fmt/fmt.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +$(TEST_LIBC_FMT_OBJS): \ + $(BUILD_FILES) \ + test/libc/fmt/test.mk + +.PHONY: o/$(MODE)/test/libc/fmt +o/$(MODE)/test/libc/fmt: \ + $(TEST_LIBC_FMT_BINS) \ + $(TEST_LIBC_FMT_CHECKS) diff --git a/test/libc/intrin/packuswb_test.c b/test/libc/intrin/packuswb_test.c new file mode 100644 index 00000000..bbd4eef9 --- /dev/null +++ b/test/libc/intrin/packuswb_test.c @@ -0,0 +1,70 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/intrin/packsswb.h" +#include "libc/intrin/packuswb.h" +#include "libc/limits.h" +#include "libc/nexgen32e/kcpuids.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +const short S[8] = {0, 128, -128, 255, SHRT_MAX, SHRT_MIN, 0, 0}; + +TEST(packuswb, test) { + unsigned char B[16] = {0}; + packuswb(B, S, S); + EXPECT_EQ(0, B[0]); + EXPECT_EQ(128, B[1]); + EXPECT_EQ(0, B[2]); + EXPECT_EQ(255, B[3]); + EXPECT_EQ(255, B[4]); + EXPECT_EQ(0, B[5]); + EXPECT_EQ(0, B[6]); + EXPECT_EQ(0, B[7]); + EXPECT_EQ(0, B[8]); + EXPECT_EQ(128, B[9]); + EXPECT_EQ(0, B[10]); + EXPECT_EQ(255, B[11]); + EXPECT_EQ(255, B[12]); + EXPECT_EQ(0, B[13]); + EXPECT_EQ(0, B[14]); + EXPECT_EQ(0, B[15]); +} + +TEST(packsswb, test) { + const short S[8] = {0, 128, -128, 255, SHRT_MAX, SHRT_MIN, 0, 0}; + signed char B[16] = {0}; + packsswb(B, S, S); + EXPECT_EQ(0, B[0]); + EXPECT_EQ(127, B[1]); + EXPECT_EQ(-128, B[2]); + EXPECT_EQ(127, B[3]); + EXPECT_EQ(127, B[4]); + EXPECT_EQ(-128, B[5]); + EXPECT_EQ(0, B[6]); + EXPECT_EQ(0, B[7]); + EXPECT_EQ(0, B[8]); + EXPECT_EQ(127, B[9]); + EXPECT_EQ(-128, B[10]); + EXPECT_EQ(127, B[11]); + EXPECT_EQ(127, B[12]); + EXPECT_EQ(-128, B[13]); + EXPECT_EQ(0, B[14]); + EXPECT_EQ(0, B[15]); +} diff --git a/test/libc/intrin/paddw_test.c b/test/libc/intrin/paddw_test.c new file mode 100644 index 00000000..8c0c0b82 --- /dev/null +++ b/test/libc/intrin/paddw_test.c @@ -0,0 +1,55 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/intrin/paddsw.h" +#include "libc/intrin/paddw.h" +#include "libc/limits.h" +#include "libc/testlib/testlib.h" + +TEST(paddw, test) { + short A[8] = {7}; + short B[8] = {11}; + short C[8]; + paddw(C, A, B); + EXPECT_EQ(18, C[0]); +} + +TEST(paddsw, test) { + short A[8] = {7}; + short B[8] = {11}; + short C[8]; + paddsw(C, A, B); + EXPECT_EQ(18, C[0]); +} + +TEST(paddw, testOverflow_wrapsAround) { + short A[8] = {SHRT_MAX, SHRT_MIN}; + short B[8] = {1, -1}; + paddw(A, A, B); + EXPECT_EQ(SHRT_MIN, A[0]); + EXPECT_EQ(SHRT_MAX, A[1]); +} + +TEST(paddsw, testOverflow_saturates) { + short A[8] = {SHRT_MAX, SHRT_MIN}; + short B[8] = {1, -1}; + paddsw(A, A, B); + EXPECT_EQ(SHRT_MAX, A[0]); + EXPECT_EQ(SHRT_MIN, A[1]); +} diff --git a/test/libc/intrin/palignr_test.c b/test/libc/intrin/palignr_test.c new file mode 100644 index 00000000..7d2b9249 --- /dev/null +++ b/test/libc/intrin/palignr_test.c @@ -0,0 +1,87 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/intrin/palignr.h" +#include "libc/testlib/testlib.h" + +const int A[4] = {1, 2, 3, 4}; +const int B[4] = {5, 6, 7, 8}; + +TEST(palignr, testLeftpad) { + int C[4] = {0}; + palignr(C, B, A, 12); + EXPECT_EQ(4, C[0]); + EXPECT_EQ(5, C[1]); + EXPECT_EQ(6, C[2]); + EXPECT_EQ(7, C[3]); +} + +TEST(palignr, test0) { + int C[4]; + palignr(C, B, A, 0); + EXPECT_EQ(1, C[0]); + EXPECT_EQ(2, C[1]); + EXPECT_EQ(3, C[2]); + EXPECT_EQ(4, C[3]); +} + +TEST(palignr, test4) { + int C[4]; + palignr(C, B, A, 4); + EXPECT_EQ(2, C[0]); + EXPECT_EQ(3, C[1]); + EXPECT_EQ(4, C[2]); + EXPECT_EQ(5, C[3]); +} + +TEST(palignr, test12) { + int C[4]; + palignr(C, B, A, 12); + EXPECT_EQ(4, C[0]); + EXPECT_EQ(5, C[1]); + EXPECT_EQ(6, C[2]); + EXPECT_EQ(7, C[3]); +} + +TEST(palignr, test16) { + int C[4]; + palignr(C, B, A, 16); + EXPECT_EQ(5, C[0]); + EXPECT_EQ(6, C[1]); + EXPECT_EQ(7, C[2]); + EXPECT_EQ(8, C[3]); +} + +TEST(palignr, test20) { + int C[4] = {-1, -1, -1, -1}; + palignr(C, B, A, 20); + EXPECT_EQ(6, C[0]); + EXPECT_EQ(7, C[1]); + EXPECT_EQ(8, C[2]); + EXPECT_EQ(0, C[3]); +} + +TEST(palignr, test32) { + int C[4] = {-1, -1, -1, -1}; + palignr(C, B, A, 32); + EXPECT_EQ(0, C[0]); + EXPECT_EQ(0, C[1]); + EXPECT_EQ(0, C[2]); + EXPECT_EQ(0, C[3]); +} diff --git a/test/libc/intrin/phaddsw_test.c b/test/libc/intrin/phaddsw_test.c new file mode 100644 index 00000000..c377e536 --- /dev/null +++ b/test/libc/intrin/phaddsw_test.c @@ -0,0 +1,46 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/intrin/phaddsw.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" +#include "tool/viz/lib/formatstringtable-testlib.h" +/* clang-format off */ + +FIXTURE(phaddsw, disableHardwareExtensions) { + memset((/*unconst*/ void *)kCpuids, 0, sizeof(kCpuids)); +} + +TEST(phaddsw, testOverflow_saturates) { + short M[2][8] = { + {0x7fff, 0, 0x7fff, 1, 0x7fff, 0x7fff, 20777, -16389}, + {-28040, 13318, -1336, -24798, -13876, 3599, -7346, -23575}, + }; + phaddsw(M[0], M[0], M[1]); + EXPECT_SHRTMATRIXEQ(2, 8, M, "\n\ + 32767 32767 32767 4388 -14722 -26134 -10277 -30921\n\ +-28040 13318 -1336 -24798 -13876 3599 -7346 -23575"); +} + +TEST(phaddsw, testAliasing_isOk) { + short M[1][8] = {{0,1,2,3,4,5,6,7}}; + phaddsw(M[0],M[0],M[0]); + EXPECT_SHRTMATRIXEQ(1, 8, M, "\n\ + 1 5 9 13 1 5 9 13"); +} diff --git a/test/libc/intrin/phaddw_test.c b/test/libc/intrin/phaddw_test.c new file mode 100644 index 00000000..99c8319d --- /dev/null +++ b/test/libc/intrin/phaddw_test.c @@ -0,0 +1,48 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/intrin/phaddw.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" +#include "tool/viz/lib/formatstringtable-testlib.h" +/* clang-format off */ + +FIXTURE(phaddw, disableHardwareExtensions) { + memset((/*unconst*/ void *)kCpuids, 0, sizeof(kCpuids)); +} + +TEST(phaddw, testOverflow_wrapsAround) { + short M[2][8] = { + {0x7fff, 0, 0x7fff, 1, 13004, -30425, 20777, -16389}, + {-28040, 13318, -1336, -24798, -13876, 3599, -7346, -23575}, + }; + phaddw(M[0], M[0], M[1]); + EXPECT_SHRTMATRIXEQ(2, 8, M, "\n\ + 32767 -32768 -17421 4388 -14722 -26134 -10277 -30921\n\ +-28040 13318 -1336 -24798 -13876 3599 -7346 -23575"); +} + +TEST(phaddw, testAliasing_isOk) { + short M[1][8] = { + {0,1, 2,3, 4,5, 6,7}, + }; + phaddw(M[0],M[0],M[0]); + EXPECT_SHRTMATRIXEQ(1, 8, M, "\n\ + 1 5 9 13 1 5 9 13"); +} diff --git a/test/libc/intrin/pmulhrsw_test.c b/test/libc/intrin/pmulhrsw_test.c new file mode 100644 index 00000000..9d9736d5 --- /dev/null +++ b/test/libc/intrin/pmulhrsw_test.c @@ -0,0 +1,116 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/core/q.h" +#include "libc/intrin/pmulhrsw.h" +#include "libc/macros.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" +#include "tool/viz/lib/formatstringtable-testlib.h" + +#define ACCURACY powf(10, -4) + +#define FOR8(STMT) \ + for (y = 0; y < 8; ++y) { \ + STMT; \ + } + +#define FOR88(STMT) \ + for (y = 0; y < 8; ++y) { \ + for (x = 0; x < 8; ++x) { \ + STMT; \ + } \ + } + +FIXTURE(pmulhrsw, disableHardwareExtensions) { + memset((/*unconst*/ void *)kCpuids, 0, sizeof(kCpuids)); +} + +TEST(pmulhrsw, testLimits) { + int i; + short A[8], B[8]; + const short kPmulhrswTorture[][3] = { + {SHRT_MIN, SHRT_MIN, SHRT_MIN}, + {SHRT_MIN, -1, 1}, + {SHRT_MIN, 0, 0}, + {SHRT_MIN, 1, -1}, + {-1, SHRT_MIN, 1}, + {-1, -1, 0}, + {-1, 0, 0}, + {-1, 1, 0}, + {-1, SHRT_MAX, -1}, + {0, SHRT_MIN, 0}, + {0, -1, 0}, + {0, 0, 0}, + {0, 1, 0}, + {0, SHRT_MAX, 0}, + {1, SHRT_MIN, -1}, + {1, -1, 0}, + {1, 0, 0}, + {1, 1, 0}, + {1, SHRT_MAX, 1}, + {SHRT_MAX, -1, -1}, + {SHRT_MAX, 0, 0}, + {SHRT_MAX, 1, 1}, + }; + memset(A, 0, sizeof(A)); + memset(B, 0, sizeof(B)); + for (i = 0; i < ARRAYLEN(kPmulhrswTorture); ++i) { + A[0] = kPmulhrswTorture[i][0]; + B[0] = kPmulhrswTorture[i][1]; + pmulhrsw(A, A, B); + EXPECT_EQ(kPmulhrswTorture[i][2], A[0], "pmulhrsw(%hd,%hd)→%hd", + kPmulhrswTorture[i][0], kPmulhrswTorture[i][1], A[0]); + } +} + +TEST(pmulhrsw, testFakeFloat) { + int y, x; + float R[8][8]; + float Q[8][8]; + short QQ[8][8]; + short QD[8][8]; + short QM[8][8]; + float D[8][8] = /* clang-format off */ { + {.929142, .147545, .17061, .765948, .874296, .925816, .073955, .10664}, + {.986743, .311924, .550892, .789301, .873408, .743376, .434021, .143184}, + {.405694, .080979, .894841, .625169, .465688, .877854, .97371, .264295}, + {.781549, .20985, .599735, .943491, .059135, .045806, .770352, .081862}, + {.584684, .701568, .022328, .177048, .412809, .185355, .992654, .252167}, + {.327565, .693878, .722431, .84546, .060729, .383725, .589365, .435534}, + {.942854, .62579, .177928, .809653, .143087, .624792, .851914, .072192}, + {.750157, .968502, .270052, .087784, .406716, .510766, .959699, .416836}, + }; + float M[8][8] = { + {.009407, .882863, .000511, .565419, .69844, .035758, .817049, .249922}, + {.072144, .703228, .479622, .121608, .288279, .55492, .387912, .140278}, + {.047205, .748263, .683692, .805669, .137764, .858753, .787804, .059591}, + {.682286, .787778, .503573, .473795, .437378, .573171, .135995, .341236}, + {.588849, .723929, .624155, .710336, .480396, .462433, .865392, .071378}, + {.598636, .575209, .758356, .518674, .043861, .542574, .355843, .02014}, + {.359636, .95607, .698256, .492859, .149454, .795121, .790219, .357014}, + {.401603, .928426, .416429, .11747, .643411, .907285, .074102, .411959}, + } /* clang-format on */; + FOR88(QD[y][x] = F2Q(15, D[y][x])); + FOR88(QM[y][x] = F2Q(15, M[y][x])); + FOR8(pmulhrsw(QQ[y], QD[y], QM[y])); + FOR88(Q[y][x] = Q2F(15, QQ[y][x])); + FOR88(R[y][x] = D[y][x] * M[y][x]); + FOR88(EXPECT_TRUE(ACCURACY > Q[y][x] - R[y][x])); +} diff --git a/test/libc/intrin/psraw_test.c b/test/libc/intrin/psraw_test.c new file mode 100644 index 00000000..505efb43 --- /dev/null +++ b/test/libc/intrin/psraw_test.c @@ -0,0 +1,38 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/intrin/psraw.h" +#include "libc/limits.h" +#include "libc/testlib/testlib.h" + +TEST(psraw, testPositive) { + short A[8] = {1, 2, SHRT_MAX}; + psraw(A, A, 1); + EXPECT_EQ(0, A[0]); + EXPECT_EQ(1, A[1]); + EXPECT_EQ(SHRT_MAX / 2, A[2]); +} + +TEST(psraw, testNegative) { + short A[8] = {-1, -2, SHRT_MIN}; + psraw(A, A, 1); + EXPECT_EQ(-1, A[0]); + EXPECT_EQ(-1, A[1]); + EXPECT_EQ(SHRT_MIN / 2, A[2]); +} diff --git a/test/libc/intrin/test.mk b/test/libc/intrin/test.mk new file mode 100644 index 00000000..3a714a8c --- /dev/null +++ b/test/libc/intrin/test.mk @@ -0,0 +1,51 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_INTRIN + +TEST_LIBC_INTRIN_SRCS := $(wildcard test/libc/intrin/*.c) +TEST_LIBC_INTRIN_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_INTRIN_SRCS)) +TEST_LIBC_INTRIN_COMS = $(TEST_LIBC_INTRIN_OBJS:%.o=%.com) + +TEST_LIBC_INTRIN_OBJS = \ + $(TEST_LIBC_INTRIN_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_INTRIN_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_INTRIN_BINS = \ + $(TEST_LIBC_INTRIN_COMS) \ + $(TEST_LIBC_INTRIN_COMS:%=%.dbg) + +TEST_LIBC_INTRIN_TESTS = \ + $(TEST_LIBC_INTRIN_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_INTRIN_CHECKS = \ + $(TEST_LIBC_INTRIN_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_INTRIN_DIRECTDEPS = \ + LIBC_INTRIN \ + LIBC_NEXGEN32E \ + LIBC_STUBS \ + LIBC_TINYMATH \ + TOOL_VIZ_LIB \ + LIBC_TESTLIB + +TEST_LIBC_INTRIN_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_INTRIN_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/intrin/intrin.pkg: \ + $(TEST_LIBC_INTRIN_OBJS) \ + $(foreach x,$(TEST_LIBC_INTRIN_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/intrin/%.com.dbg: \ + $(TEST_LIBC_INTRIN_DEPS) \ + o/$(MODE)/test/libc/intrin/%.o \ + o/$(MODE)/test/libc/intrin/intrin.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +.PHONY: o/$(MODE)/test/libc/intrin +o/$(MODE)/test/libc/intrin: \ + $(TEST_LIBC_INTRIN_BINS) \ + $(TEST_LIBC_INTRIN_CHECKS) diff --git a/test/libc/math/exp_test.c b/test/libc/math/exp_test.c new file mode 100644 index 00000000..34aa8023 --- /dev/null +++ b/test/libc/math/exp_test.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/runtime/gc.h" +#include "libc/stdio/stdio.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +TEST(exp, test) { + ASSERT_STREQ("7.389056", gc(xasprintf("%f", exp(2.0)))); + ASSERT_STREQ("6.389056", gc(xasprintf("%f", expm1(2.0)))); + ASSERT_STREQ("6.389056", gc(xasprintf("%f", exp(2.0) - 1.0))); +} diff --git a/test/libc/math/pow10_test.c b/test/libc/math/pow10_test.c new file mode 100644 index 00000000..844b0403 --- /dev/null +++ b/test/libc/math/pow10_test.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/testlib/testlib.h" + +TEST(pow10, testLdbl) { + EXPECT_LDBL_EQ(1, pow10l(0)); + EXPECT_LDBL_EQ(10, pow10l(1)); + EXPECT_LDBL_EQ(100, pow10l(2)); +} + +TEST(pow10, testDouble) { + EXPECT_DOUBLE_EQ(1, pow10(0)); + EXPECT_DOUBLE_EQ(10, pow10(1)); + EXPECT_DOUBLE_EQ(100, pow10(2)); +} + +TEST(pow10, testFloat) { + EXPECT_FLOAT_EQ(1, pow10f(0)); + EXPECT_FLOAT_EQ(10, pow10f(1)); + EXPECT_FLOAT_EQ(100, pow10f(2)); +} diff --git a/test/libc/math/powl_test.c b/test/libc/math/powl_test.c new file mode 100644 index 00000000..03217bdb --- /dev/null +++ b/test/libc/math/powl_test.c @@ -0,0 +1,52 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/testlib/testlib.h" + +long double x, y, z; + +COMBO(x, pos1) { x = +1.3L; } +COMBO(x, pos2) { x = +2.3L; } +COMBO(y, pos1) { y = +1.3L; } +COMBO(y, pos2) { y = +2.3L; } +COMBO(z, pi) { z = M_PI; } +COMBO(z, e) { z = M_E; } + +TEST(powl, lolgebra) { + /* EXPECT_LDBL_EQ(1, powl(x, 0)); */ + /* EXPECT_LDBL_EQ(x, powl(x, 1)); */ + /* EXPECT_LDBL_EQ(powl(x, -1), 1.0L / x); */ + /* EXPECT_LDBL_EQ(powl(x, 0.5), sqrtl(x)); */ + /* EXPECT_LDBL_EQ(powl(x, y) * powl(x, z), powl(x, y + z)); */ + /* EXPECT_LDBL_EQ(powl(x, y) * powl(z, y), powl(x * z, y)); */ + /* EXPECT_LDBL_EQ(powl(x, y) / x, powl(x, y - 1)); */ + /* EXPECT_LDBL_EQ(x / powl(y, z), x * powl(y, -z)); */ + /* EXPECT_LDBL_EQ(powi(x, 0), 1); */ + /* EXPECT_LDBL_EQ(powi(x, 1), x); */ + /* EXPECT_LDBL_EQ(powi(x, -1), 1 / x); */ + /* EXPECT_LDBL_EQ(powi(1, x), 1); */ + /* EXPECT_LDBL_EQ(powi(x, y) * powi(z, y), powi(x * z, y)); */ +} + +TEST(powl, testConstants) { + EXPECT_LDBL_EQ(16, powl(2, 4)); + /* TODO(jart): We need a better AlmostEqual() */ + /* EXPECT_LDBL_EQ(3.347061799072891e+62, powl(1337.31337, 20)); */ +} diff --git a/test/libc/math/round_test.c b/test/libc/math/round_test.c new file mode 100644 index 00000000..5fa65779 --- /dev/null +++ b/test/libc/math/round_test.c @@ -0,0 +1,77 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/runtime/gc.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +TEST(round, test) { + EXPECT_STREQ("-3", gc(xdtoa(round(-2.5)))); + EXPECT_STREQ("-2", gc(xdtoa(round(-1.5)))); + EXPECT_STREQ("-1", gc(xdtoa(round(-.5)))); + EXPECT_STREQ("1", gc(xdtoa(round(.5)))); + EXPECT_STREQ("2", gc(xdtoa(round(1.5)))); + EXPECT_STREQ("3", gc(xdtoa(round(2.5)))); +} + +TEST(round, testCornerCases) { + EXPECT_STREQ("-0", gc(xdtoa(round(-0.0)))); + EXPECT_STREQ("NAN", gc(xdtoa(round(NAN)))); + EXPECT_STREQ("-NAN", gc(xdtoa(round(-NAN)))); + EXPECT_STREQ("INFINITY", gc(xdtoa(round(INFINITY)))); + EXPECT_STREQ("-INFINITY", gc(xdtoa(round(-INFINITY)))); +} + +TEST(lround, test) { + EXPECT_EQ(-3, lround(-2.5)); + EXPECT_EQ(-2, lround(-1.5)); + EXPECT_EQ(-1, lround(-.5)); + EXPECT_EQ(0, lround(-.0)); + EXPECT_EQ(1, lround(.5)); + EXPECT_EQ(2, lround(1.5)); + EXPECT_EQ(3, lround(2.5)); +} + +TEST(roundf, test) { + EXPECT_STREQ("-3", gc(xdtoa(roundf(-2.5)))); + EXPECT_STREQ("-2", gc(xdtoa(roundf(-1.5)))); + EXPECT_STREQ("-1", gc(xdtoa(roundf(-.5)))); + EXPECT_STREQ("1", gc(xdtoa(roundf(.5)))); + EXPECT_STREQ("2", gc(xdtoa(roundf(1.5)))); + EXPECT_STREQ("3", gc(xdtoa(roundf(2.5)))); +} + +TEST(roundf, testCornerCases) { + EXPECT_STREQ("-0", gc(xdtoa(roundf(-0.0)))); + EXPECT_STREQ("NAN", gc(xdtoa(roundf(NAN)))); + EXPECT_STREQ("-NAN", gc(xdtoa(roundf(-NAN)))); + EXPECT_STREQ("INFINITY", gc(xdtoa(roundf(INFINITY)))); + EXPECT_STREQ("-INFINITY", gc(xdtoa(roundf(-INFINITY)))); +} + +TEST(lroundf, test) { + EXPECT_EQ(-3, lroundf(-2.5)); + EXPECT_EQ(-2, lroundf(-1.5)); + EXPECT_EQ(-1, lroundf(-.5)); + EXPECT_EQ(0, lroundf(-.0)); + EXPECT_EQ(1, lroundf(.5)); + EXPECT_EQ(2, lroundf(1.5)); + EXPECT_EQ(3, lroundf(2.5)); +} diff --git a/test/libc/math/test.mk b/test/libc/math/test.mk new file mode 100644 index 00000000..e40458ed --- /dev/null +++ b/test/libc/math/test.mk @@ -0,0 +1,56 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_MATH + +TEST_LIBC_MATH_SRCS := $(wildcard test/libc/math/*.c) +TEST_LIBC_MATH_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_MATH_SRCS)) +TEST_LIBC_MATH_COMS = $(TEST_LIBC_MATH_OBJS:%.o=%.com) + +TEST_LIBC_MATH_OBJS = \ + $(TEST_LIBC_MATH_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_MATH_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_MATH_BINS = \ + $(TEST_LIBC_MATH_COMS) \ + $(TEST_LIBC_MATH_COMS:%=%.dbg) + +TEST_LIBC_MATH_TESTS = $(TEST_LIBC_MATH_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_MATH_CHECKS = \ + $(TEST_LIBC_MATH_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_MATH_DIRECTDEPS = \ + LIBC_CALLS_HEFTY \ + LIBC_FMT \ + LIBC_TINYMATH \ + LIBC_MEM \ + LIBC_RUNTIME \ + LIBC_STUBS \ + LIBC_TESTLIB \ + LIBC_X + +TEST_LIBC_MATH_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_MATH_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/math/math.pkg: \ + $(TEST_LIBC_MATH_OBJS) \ + $(foreach x,$(TEST_LIBC_MATH_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/math/%.com.dbg: \ + $(TEST_LIBC_MATH_DEPS) \ + o/$(MODE)/test/libc/math/%.o \ + o/$(MODE)/test/libc/math/math.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +$(TEST_LIBC_MATH_OBJS): \ + DEFAULT_CCFLAGS += \ + -fno-builtin + +.PHONY: o/$(MODE)/test/libc/math +o/$(MODE)/test/libc/math: \ + $(TEST_LIBC_MATH_BINS) \ + $(TEST_LIBC_MATH_CHECKS) diff --git a/test/libc/mem/malloc_test.c b/test/libc/mem/malloc_test.c new file mode 100644 index 00000000..6d2af58a --- /dev/null +++ b/test/libc/mem/malloc_test.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/mem/mem.h" +#include "libc/testlib/testlib.h" + +TEST(malloc, test) { free(malloc(123)); } diff --git a/test/libc/mem/strdup_test.c b/test/libc/mem/strdup_test.c new file mode 100644 index 00000000..775dfe6d --- /dev/null +++ b/test/libc/mem/strdup_test.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/mem/mem.h" +#include "libc/testlib/testlib.h" + +char *s2; + +TEST(strdup, test) { + EXPECT_STREQ("hello", (s2 = strdup("hello"))); + EXPECT_NE((intptr_t) "hello", (intptr_t)s2); + free(s2); +} + +TEST(strndup, test) { + EXPECT_STREQ("hello", (s2 = strndup("hello", 8))); + EXPECT_NE((intptr_t) "hello", (intptr_t)s2); + free(s2); +} + +TEST(strndup, tooLong_truncatesWithNul) { + EXPECT_STREQ("hell", (s2 = strndup("hello", 4))); + free(s2); +} diff --git a/test/libc/mem/test.mk b/test/libc/mem/test.mk new file mode 100644 index 00000000..56dfe494 --- /dev/null +++ b/test/libc/mem/test.mk @@ -0,0 +1,51 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_MEM + +TEST_LIBC_MEM_SRCS := $(wildcard test/libc/mem/*.c) +TEST_LIBC_MEM_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_MEM_SRCS)) +TEST_LIBC_MEM_COMS = $(TEST_LIBC_MEM_OBJS:%.o=%.com) + +TEST_LIBC_MEM_OBJS = \ + $(TEST_LIBC_MEM_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_MEM_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_MEM_BINS = \ + $(TEST_LIBC_MEM_COMS) \ + $(TEST_LIBC_MEM_COMS:%=%.dbg) + +TEST_LIBC_MEM_TESTS = $(TEST_LIBC_MEM_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_MEM_CHECKS = \ + $(TEST_LIBC_MEM_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_MEM_DIRECTDEPS = \ + LIBC_MEM \ + LIBC_STUBS \ + LIBC_TESTLIB + +TEST_LIBC_MEM_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_MEM_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/mem/mem.pkg: \ + $(TEST_LIBC_MEM_OBJS) \ + $(foreach x,$(TEST_LIBC_MEM_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/mem/%.com.dbg: \ + $(TEST_LIBC_MEM_DEPS) \ + o/$(MODE)/test/libc/mem/%.o \ + o/$(MODE)/test/libc/mem/mem.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +$(TEST_LIBC_MEM_OBJS): \ + DEFAULT_CCFLAGS += \ + -fno-builtin + +.PHONY: o/$(MODE)/test/libc/mem +o/$(MODE)/test/libc/mem: \ + $(TEST_LIBC_MEM_BINS) \ + $(TEST_LIBC_MEM_CHECKS) diff --git a/test/libc/nexgen32e/crc32_test.c b/test/libc/nexgen32e/crc32_test.c new file mode 100644 index 00000000..d4a9e186 --- /dev/null +++ b/test/libc/nexgen32e/crc32_test.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/str/str.h" +#include "libc/testlib/hyperion.h" +#include "libc/testlib/testlib.h" + +uint32_t crc32(uint32_t, const void *, int); +uint32_t crc32$pclmul(uint32_t, const void *, size_t); +uint32_t crc32$pclmul2(uint32_t, const void *, size_t); + +TEST(crc32, testBigText) { + size_t size; + size = kHyperionSize; + EXPECT_EQ(0xe9ded8e6, crc32(0, kHyperion, size)); + EXPECT_EQ(0xe9ded8e6, crc32_z(0, kHyperion, size)); + if (X86_HAVE(PCLMUL)) { + size = ROUNDDOWN(size, 64); + EXPECT_EQ(0xc7adc04f, crc32(0, kHyperion, size)); + EXPECT_EQ(0xc7adc04f, crc32_z(0, kHyperion, size)); + EXPECT_EQ(0xc7adc04f, + 0xffffffffu ^ crc32$pclmul(0 ^ 0xffffffffu, kHyperion, size)); + } +} diff --git a/test/libc/nexgen32e/lz4decode_test.c b/test/libc/nexgen32e/lz4decode_test.c new file mode 100644 index 00000000..aa42d21a --- /dev/null +++ b/test/libc/nexgen32e/lz4decode_test.c @@ -0,0 +1,96 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/log/check.h" +#include "libc/nexgen32e/kompressor.h" +#include "libc/nexgen32e/lz4.h" +#include "libc/runtime/ezmap.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(lz4, decompress_emptyStringWithoutChecksum) { + /* lz4 -9 --content-size --no-frame-crc /tmp/empty - | hexdump -C */ + static char kLz4Data[] = {0x04, 0x22, 0x4d, 0x18, 0x60, 0x40, + 0x82, 0x00, 0x00, 0x00, 0x00}; + char *src = memcpy(tmalloc(sizeof(kLz4Data)), kLz4Data, sizeof(kLz4Data)); + char *dst = tmalloc(1); + *dst = 'z'; + ASSERT_EQ(dst, lz4decode(dst, src)); + ASSERT_EQ('z', *dst); + tfree(dst); + tfree(src); +} + +TEST(lz4, decompress_oneLetterWithoutChecksum) { + /* printf a >oneletter */ + /* lz4 -9 --content-size --no-frame-crc oneletter /dev/stdout | hexdump -C */ + static char kLz4Data[] = {0x04, 0x22, 0x4d, 0x18, 0x68, 0x40, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x01, + 0x00, 0x00, 0x80, 0x61, 0x00, 0x00, 0x00, 0x00}; + char *src = memcpy(tmalloc(sizeof(kLz4Data)), kLz4Data, sizeof(kLz4Data)); + char *dst = tmalloc(1); + ASSERT_EQ(dst + 1, lz4decode(dst, src)); + ASSERT_EQ('a', *dst); + tfree(dst); + tfree(src); +} + +TEST(lz4, decompress_runLengthDecode) { + /* printf aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >/tmp/a */ + /* lz4 -9 --content-size --no-frame-crc /tmp/a - | hexdump -vC */ + static char kLz4Data[] = { + 0x04, 0x22, 0x4d, 0x18, 0x68, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x0b, 0x00, 0x00, 0x00, 0x1f, 0x61, 0x01, 0x00, 0x07, + 0x50, 0x61, 0x61, 0x61, 0x61, 0x61, 0x00, 0x00, 0x00, 0x00}; + char *src = memcpy(tmalloc(sizeof(kLz4Data)), kLz4Data, sizeof(kLz4Data)); + const char *want = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + char *dst = tmalloc(strlen(want)); + ASSERT_EQ(dst + strlen(want), lz4decode(dst, src)); + ASSERT_STREQN(want, dst, strlen(want)); + tfree(dst); + tfree(src); +} + +TEST(lz4, zoneFileGmt) { + if (!fileexists("usr/share/zoneinfo.dict.lz4")) return; + struct MappedFile dict, gmt; + CHECK_NE(-1, mapfileread("usr/share/zoneinfo.dict.lz4", &dict)); + CHECK_NE(-1, mapfileread("usr/share/zoneinfo/GMT.lz4", &gmt)); + size_t mapsize, gmtsize; + char *mapping, *gmtdata; + lz4decode((gmtdata = lz4decode( + (mapping = mapanon( + (mapsize = roundup( + LZ4_FRAME_BLOCKCONTENTSIZE(lz4check(dict.addr)) + + (gmtsize = LZ4_FRAME_BLOCKCONTENTSIZE( + lz4check(gmt.addr))), + FRAMESIZE)))), + dict.addr)), + gmt.addr); + ASSERT_BINEQ( + u"TZif2                  ☺   ☺           ☺   ♦      GMT   TZif2   " + u"               ☺   ☺       ☺   ☺   ♦°              GMT   ◙GMT0◙", + gmtdata); + munmap(mapping, mapsize); + unmapfile(&dict); + unmapfile(&gmt); +} diff --git a/test/libc/nexgen32e/memeqmask_test.c b/test/libc/nexgen32e/memeqmask_test.c new file mode 100644 index 00000000..74dacca0 --- /dev/null +++ b/test/libc/nexgen32e/memeqmask_test.c @@ -0,0 +1,103 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/runtime/buffer.h" +#include "libc/runtime/gc.h" +#include "libc/runtime/mappings.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +#define ALIGN 128 +#define BUFSIZE (8 * 32) +#define MASKSIZE (BUFSIZE / CHAR_BIT) + +const char kX[] = "aaaaaaaaeeeeeeeeeeeeeeeeeeeeeeee" + "e e" + "e e" + "e e" + "e e" + "e e" + "e e" + "eeeeeeeeeeeeeeeeeeeeeeeeeeeeee-e"; + +const char kY[] = "aaaaaaaaefffffffffffeffffffffff-" + "f z-" + "f f" + "f f" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "f f" + "f f" + "ffffffffffffffffffffffffffffff-f"; + +const char kM[] = "11111111100000000000100000000000" + "01111111111111111111111111111100" + "01111111111111111111111111111110" + "01111111111111111111111111111110" + "00000000000000000000000000000000" + "01111111111111111111111111111110" + "01111111111111111111111111111110" + "00000000000000000000000000000010"; + +nodiscard char *binify(uint8_t *data, size_t size) { + uint8_t b; + size_t i, j; + char *s, *p; + p = s = xmalloc(size * CHAR_BIT + 1); + for (i = 0; i < size; ++i) { + b = data[i]; + for (j = 0; j < CHAR_BIT; ++j) { + *p++ = "01"[b & 1]; + b >>= 1; + } + } + *p = '\0'; + return s; +} + +TEST(memeqmask, test) { + struct GuardedBuffer x = {}, y = {}, m = {}; + memcpy(balloc(&x, ALIGN, BUFSIZE), kX, BUFSIZE); + memcpy(balloc(&y, ALIGN, BUFSIZE), kY, BUFSIZE); + balloc(&m, ALIGN, MASKSIZE); + EXPECT_EQ((intptr_t)m.p, (intptr_t)memeqmask(m.p, x.p, y.p, BUFSIZE)); + EXPECT_STREQ(kM, gc(binify(m.p, MASKSIZE))); + bfree(&m); + bfree(&x); + bfree(&y); +} + +#if 0 +#include "libc/rand/rand.h" +#include "libc/testlib/ezbench.h" +TEST(memeqmask, bench) { + size_t len = 64 * 1024; + char *m = xmemalign(64, DIMMASK(len)); + char *x = xmemalign(64, len); + char *y = xmemalign(64, len); + EZBENCH( + { + rngset(x, len, rand64, -1); + rngset(y, len, rand64, -1); + }, + memeqmask(m, x, y, len)); +} +#endif diff --git a/test/libc/nexgen32e/strsak32_test.c b/test/libc/nexgen32e/strsak32_test.c new file mode 100644 index 00000000..85f96752 --- /dev/null +++ b/test/libc/nexgen32e/strsak32_test.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/nexgen32e/nexgen32e.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(strsak32, test) { + EXPECT_EQ(0, wcslen(L"")); + EXPECT_EQ(1, wcslen(L"1")); + EXPECT_EQ(5, wcslen(L"hello")); +} diff --git a/test/libc/nexgen32e/strtolower_test.c b/test/libc/nexgen32e/strtolower_test.c new file mode 100644 index 00000000..68a4b87c --- /dev/null +++ b/test/libc/nexgen32e/strtolower_test.c @@ -0,0 +1,58 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/nexgen32e/nexgen32e.h" +#include "libc/rand/rand.h" +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +TEST(strtolower, testAligned) { + char s[128] = "AZCDabcdABCDabcdABCDabcdABCDabcdABCDabcd"; + EXPECT_STREQ("azcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", strtolower(s)); +} + +TEST(strtolower, testUnaligned) { + char s[128] = "AZCDabcdABCDabcdABCDabcdABCDabcdABCDabcd"; + strtolower(s + 1); + EXPECT_STREQ("Azcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", s); +} + +TEST(strtoupper, testAligned) { + char s[128] = "AZCDabcdABCDabcdA0CDabcdABCDabcdABCDabcd"; + EXPECT_STREQ("AZCDABCDABCDABCDA0CDABCDABCDABCDABCDABCD", strtoupper(s)); +} + +TEST(strtoupper, testUnaligned) { + char s[128] = "aZCDabcdABCDabcdABCDabcdABCDabcdABCDabcd"; + strtoupper(s + 1); + EXPECT_STREQ("aZCDABCDABCDABCDABCDABCDABCDABCDABCDABCD", s); +} + +BENCH(strtolower, bench) { + size_t size = FRAMESIZE; + char *data = tgc(tmalloc(size)); + EZBENCH2( + "strtolower", + { + rngset(data, size, rand64, -1); + data[size - 1] = 0; + }, + strtolower(data)); +} diff --git a/test/libc/nexgen32e/test.mk b/test/libc/nexgen32e/test.mk new file mode 100644 index 00000000..8cb7cebd --- /dev/null +++ b/test/libc/nexgen32e/test.mk @@ -0,0 +1,68 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_NEXGEN32E + +TEST_LIBC_NEXGEN32E_SRCS := \ + $(wildcard test/libc/nexgen32e/*.c) +TEST_LIBC_NEXGEN32E_SRCS_TEST = \ + $(filter %_test.c,$(TEST_LIBC_NEXGEN32E_SRCS)) + +TEST_LIBC_NEXGEN32E_OBJS = \ + $(TEST_LIBC_NEXGEN32E_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_NEXGEN32E_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_NEXGEN32E_COMS = \ + $(TEST_LIBC_NEXGEN32E_OBJS:%.o=%.com) + +TEST_LIBC_NEXGEN32E_BINS = \ + $(TEST_LIBC_NEXGEN32E_COMS) \ + $(TEST_LIBC_NEXGEN32E_COMS:%=%.dbg) + +TEST_LIBC_NEXGEN32E_TESTS = \ + $(TEST_LIBC_NEXGEN32E_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_NEXGEN32E_CHECKS = \ + $(TEST_LIBC_NEXGEN32E_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_NEXGEN32E_DIRECTDEPS = \ + LIBC_ALG \ + LIBC_CALLS \ + LIBC_CALLS_HEFTY \ + LIBC_FMT \ + LIBC_LOG \ + LIBC_STDIO \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RAND \ + LIBC_RUNTIME \ + LIBC_STUBS \ + LIBC_STR \ + LIBC_TESTLIB \ + LIBC_X \ + TOOL_VIZ_LIB + +TEST_LIBC_NEXGEN32E_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_NEXGEN32E_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/nexgen32e/nexgen32e.pkg: \ + $(TEST_LIBC_NEXGEN32E_OBJS) \ + $(foreach x,$(TEST_LIBC_NEXGEN32E_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/nexgen32e/%.com.dbg: \ + $(TEST_LIBC_NEXGEN32E_DEPS) \ + o/$(MODE)/test/libc/nexgen32e/%.o \ + o/$(MODE)/test/libc/nexgen32e/nexgen32e.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +$(TEST_LIBC_NEXGEN32E_OBJS): \ + DEFAULT_CCFLAGS += \ + -fno-builtin + +.PHONY: o/$(MODE)/test/libc/nexgen32e +o/$(MODE)/test/libc/nexgen32e: \ + $(TEST_LIBC_NEXGEN32E_BINS) \ + $(TEST_LIBC_NEXGEN32E_CHECKS) diff --git a/test/libc/rand/devrand_test.c b/test/libc/rand/devrand_test.c new file mode 100644 index 00000000..262ab91d --- /dev/null +++ b/test/libc/rand/devrand_test.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/rand/rand.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(devrand, test) { + if (IsWindows()) return; + const size_t kSize = 8; + void *A = tmalloc(kSize); + void *B = tmalloc(kSize); + memset(A, 0, kSize); + memset(B, 0, kSize); + EXPECT_EQ(0, devrand(A, kSize)); + EXPECT_EQ(0, devrand(B, kSize)); + EXPECT_BINNE(u"        ", A); + EXPECT_BINNE(u"        ", B); + EXPECT_NE(0, memcmp(A, B, kSize)); + tfree(B); + tfree(A); +} diff --git a/test/libc/rand/rand_test.c b/test/libc/rand/rand_test.c new file mode 100644 index 00000000..2c9e2724 --- /dev/null +++ b/test/libc/rand/rand_test.c @@ -0,0 +1,45 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/rand/rand.h" +#include "libc/testlib/testlib.h" + +TEST(rand002, alwaysReturnsPositiveNumbers) { + for (unsigned i = 0; i < 100; ++i) { + ASSERT_GT(rand(), 0); + } +} + +TEST(rand003, srandSmokeTest) { + srand(1); + ASSERT_EQ(908834774, rand()); + srand(1); + ASSERT_EQ(908834774, rand()); + srand(7); + ASSERT_EQ(1059165278, rand()); +} + +TEST(rand004, rand32SmokeTest) { + ASSERT_TRUE(rand32() != rand32() || rand32() != rand32() || + rand32() != rand32() || rand32() != rand32()); +} + +TEST(rand005, rand64SmokeTest) { + ASSERT_TRUE(rand64() != rand64() || rand64() != rand64()); +} diff --git a/test/libc/rand/test.mk b/test/libc/rand/test.mk new file mode 100644 index 00000000..6586ea6a --- /dev/null +++ b/test/libc/rand/test.mk @@ -0,0 +1,59 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_RAND + +TEST_LIBC_RAND_SRCS := $(wildcard test/libc/rand/*.c) +TEST_LIBC_RAND_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_RAND_SRCS)) +TEST_LIBC_RAND_COMS = $(TEST_LIBC_RAND_OBJS:%.o=%.com) +TEST_LIBC_RAND_BINS = $(TEST_LIBC_RAND_COMS) $(TEST_LIBC_RAND_COMS:%=%.dbg) + +TEST_LIBC_RAND_OBJS = \ + $(TEST_LIBC_RAND_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_RAND_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_RAND_TESTS = $(TEST_LIBC_RAND_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_RAND_CHECKS = \ + $(TEST_LIBC_RAND_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_RAND_DIRECTDEPS = \ + LIBC_CALLS_HEFTY \ + LIBC_FMT \ + LIBC_NEXGEN32E \ + LIBC_RAND \ + LIBC_RUNTIME \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_TESTLIB \ + LIBC_X + +TEST_LIBC_RAND_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_RAND_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/rand/rand.pkg: \ + $(TEST_LIBC_RAND_OBJS) \ + $(foreach x,$(TEST_LIBC_RAND_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/rand/%.com.dbg: \ + $(TEST_LIBC_RAND_DEPS) \ + o/$(MODE)/test/libc/rand/%.o \ + o/$(MODE)/test/libc/rand/rand.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +$(TEST_LIBC_RAND_OBJS): \ + $(BUILD_FILES) \ + test/libc/rand/test.mk + +$(TEST_LIBC_RAND_OBJS): \ + DEFAULT_CCFLAGS += \ + -fno-builtin + +.PHONY: o/$(MODE)/test/libc/rand +o/$(MODE)/test/libc/rand: \ + $(TEST_LIBC_RAND_BINS) \ + $(TEST_LIBC_RAND_CHECKS) diff --git a/test/libc/runtime/arch_prctl_test.c b/test/libc/runtime/arch_prctl_test.c new file mode 100644 index 00000000..8faece1c --- /dev/null +++ b/test/libc/runtime/arch_prctl_test.c @@ -0,0 +1,72 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/calls/calls.h" +#include "libc/testlib/testlib.h" + +TEST(arch_prctl, fs) { + if (IsLinux() || IsOpenbsd()) { + uint64_t n, x; + x = 0xdeadbeef; + arch_prctl(ARCH_SET_FS, &x); + ASSERT_NE(-1, arch_prctl(ARCH_GET_FS, (intptr_t)&n)); + ASSERT_EQ((intptr_t)&x, n); + ASSERT_EQ(0xdeadbeef, fs((int64_t *)0)); + } +} + +TEST(arch_prctl, pointerRebasingFs) { + if (IsLinux() || IsOpenbsd()) { + unsigned long s[] = {0x0706050403020100, 0x0f0e0d0c0b0a0908}; + ASSERT_EQ(0x0706050403020100, s[0]); + ASSERT_EQ(0, arch_prctl(ARCH_SET_FS, 1)); + ASSERT_EQ(0x0807060504030201, fs(&s[0])); + ASSERT_EQ(0, arch_prctl(ARCH_SET_FS, 2)); + ASSERT_EQ(0x0908070605040302, fs(&s[0])); + intptr_t fs; + ASSERT_EQ(0, arch_prctl(ARCH_GET_FS, &fs)); + ASSERT_EQ(2, fs); + } +} + +TEST(arch_prctl, gs) { + if (IsLinux()) { + uint64_t n, x; + x = 0xdeadbeef; + arch_prctl(ARCH_SET_GS, &x); + ASSERT_NE(-1, arch_prctl(ARCH_GET_GS, (intptr_t)&n)); + ASSERT_EQ((intptr_t)&x, n); + ASSERT_EQ(0xdeadbeef, gs((int64_t *)0)); + } +} + +TEST(arch_prctl, pointerRebasing) { + if (IsLinux()) { + unsigned long s[] = {0x0706050403020100, 0x0f0e0d0c0b0a0908}; + ASSERT_EQ(0x0706050403020100, s[0]); + ASSERT_EQ(0, arch_prctl(ARCH_SET_GS, 1)); + ASSERT_EQ(0x0807060504030201, gs(&s[0])); + ASSERT_EQ(0, arch_prctl(ARCH_SET_GS, 2)); + ASSERT_EQ(0x0908070605040302, gs(&s[0])); + intptr_t gs; + ASSERT_EQ(0, arch_prctl(ARCH_GET_GS, &gs)); + ASSERT_EQ(2, gs); + } +} diff --git a/test/libc/runtime/balloc_test.c b/test/libc/runtime/balloc_test.c new file mode 100644 index 00000000..dee08c88 --- /dev/null +++ b/test/libc/runtime/balloc_test.c @@ -0,0 +1,105 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/calls/ucontext.h" +#include "libc/runtime/buffer.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/prot.h" +#include "libc/sysv/consts/sa.h" +#include "libc/sysv/consts/sig.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" +#include "third_party/xed/x86.h" + +char *p; +bool segfaulted_; +struct GuardedBuffer b_; +struct sigaction oldsegv_; +struct XedDecodedInst xedd_; + +void RestrictPage(void *addr, unsigned flags) { + addr = (void *)rounddown((intptr_t)addr, PAGESIZE); + EXPECT_NE(-1, mprotect(addr, PAGESIZE, flags)); +} + +void OnSegLol(int sig, struct siginfo *si, struct ucontext *uc) { + size_t i; + uint8_t *rip; + segfaulted_ = true; + rip = (uint8_t *)uc->uc_mcontext.rip; + RestrictPage(rip, PROT_READ | PROT_WRITE | PROT_EXEC); + ASSERT_EQ(XED_ERROR_NONE, + xed_instruction_length_decode(xed_decoded_inst_zero_set_mode( + &xedd_, XED_MACHINE_MODE_LONG_64), + rip, XED_MAX_INSTRUCTION_BYTES)); + for (i = 0; i < xedd_.decoded_length; ++i) rip[i] = 0x90; /* NOP */ + RestrictPage(rip, PROT_READ | PROT_EXEC); +} + +void SetUp(void) { + segfaulted_ = false; + memset(&b_, 0, sizeof(b_)); + ASSERT_NE(-1, xsigaction(SIGSEGV, OnSegLol, SA_RESETHAND | SA_RESTART, 0, + &oldsegv_)); +} + +void TearDown(void) { + EXPECT_NE(-1, sigaction(SIGSEGV, &oldsegv_, NULL)); + bfree(&b_); + EXPECT_EQ(NULL, b_.p); +} + +TEST(balloc, createsGuardPage) { + ASSERT_NE(NULL, (p = balloc(&b_, 1, 1))); + EXPECT_EQ(p, b_.p); + p[0] = '.'; + ASSERT_FALSE(segfaulted_); + /* TODO(jart): fix me!!! */ + /* p[1 + __BIGGEST_ALIGNMENT__] = '!'; */ + /* EXPECT_TRUE(segfaulted_); */ +} + +TEST(balloc, aligned_roundsUp) { + ASSERT_NE(NULL, (p = balloc(&b_, 128, 1))); + EXPECT_EQ(0, (intptr_t)b_.p & 127); + p[127] = '.'; + ASSERT_FALSE(segfaulted_); + /* TODO(jart): fix me!!! */ + /* p[128 + __BIGGEST_ALIGNMENT__] = '!'; */ + /* EXPECT_TRUE(segfaulted_); */ +} + +TEST(balloc, multipleCalls_avoidsNeedlessSyscalls) { + size_t c; + c = g_syscount; + ASSERT_NE(NULL, (p = balloc(&b_, 1, 31337))); + EXPECT_GT(g_syscount, c); + c = g_syscount; + ASSERT_NE(NULL, (p = balloc(&b_, 1, 31337 / 2))); + EXPECT_EQ(g_syscount, c); + c = g_syscount; + ASSERT_NE(NULL, (p = balloc(&b_, 1, 31337 * 2))); + EXPECT_GT(g_syscount, c); +} diff --git a/test/libc/runtime/gc_test.c b/test/libc/runtime/gc_test.c new file mode 100644 index 00000000..55c780ad --- /dev/null +++ b/test/libc/runtime/gc_test.c @@ -0,0 +1,81 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/mem/mem.h" +#include "libc/runtime/gc.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/o.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +/* TODO(jart): calling malloc_usable_size was a terrible idea */ + +TEST(todo_jart, broken_in_opt_native_mode) { + (void)0; + (void)0; +} + +int64_t fd; + +TEST(gc, usageExample_c11) { + fd = open("/dev/null", O_WRONLY); + defer(close_s, &fd); + char *msg = gc(xasprintf("%d + %d = %d", 2, 2, 2 + 2)); + write(fd, msg, strlen(msg)); +} + +TEST(gc, checkMallocUsableSizeWorksTheWayWeHopeItDoes) { + char *p = malloc(32); + EXPECT_GE(malloc_usable_size(p), 32); + free(p); + EXPECT_GE(malloc_usable_size(p), 0); +} + +noinline void function1of1(char *p) { + EXPECT_GE(malloc_usable_size(gc(p)), 32); +} +TEST(gc, testOne) { + char *p = malloc(32); + function1of1(p); + EXPECT_EQ(malloc_usable_size(p), 0); +} + +noinline void function2of2(char *p1, char *p2) { + EXPECT_GE(malloc_usable_size(p1), 32); + EXPECT_GE(malloc_usable_size(p2), 64); + gc(p2); + EXPECT_GE(malloc_usable_size(p1), 32); + EXPECT_GE(malloc_usable_size(p2), 64); +} +noinline void function1of2(char *p1, char *p2) { + EXPECT_GE(malloc_usable_size(p1), 32); + EXPECT_GE(malloc_usable_size(p2), 64); + function2of2(gc(p1), p2); + EXPECT_GE(malloc_usable_size(p1), 32); + EXPECT_GE(malloc_usable_size(p2), 0); +} +TEST(gc, testTwo) { + char *p1 = malloc(32); + char *p2 = malloc(64); + function1of2(p1, p2); + EXPECT_GE(malloc_usable_size(p1), 0); + EXPECT_GE(malloc_usable_size(p2), 0); +} diff --git a/test/libc/runtime/getdosargv_test.c b/test/libc/runtime/getdosargv_test.c new file mode 100644 index 00000000..a5a1863b --- /dev/null +++ b/test/libc/runtime/getdosargv_test.c @@ -0,0 +1,171 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/internal.h" +#include "libc/testlib/testlib.h" + +TEST(getdosargv, empty) { + size_t max = 4; + size_t size = ARG_MAX; + char *buf = tmalloc(size * sizeof(char)); + char **argv = tmalloc(max * sizeof(char *)); + EXPECT_EQ(0, getdosargv(u"", buf, size, argv, max)); + EXPECT_EQ(NULL, argv[0]); + tfree(argv); + tfree(buf); +} + +TEST(getdosargv, emptyish) { + size_t max = 4; + size_t size = ARG_MAX; + char *buf = tmalloc(size * sizeof(char)); + char **argv = tmalloc(max * sizeof(char *)); + EXPECT_EQ(0, getdosargv(u" ", buf, size, argv, max)); + EXPECT_EQ(NULL, argv[0]); + tfree(argv); + tfree(buf); +} + +TEST(getdosargv, basicUsage) { + size_t max = 4; + size_t size = ARG_MAX; + char *buf = tmalloc(size * sizeof(char)); + char **argv = tmalloc(max * sizeof(char *)); + EXPECT_EQ(3, getdosargv(u"a\t \"b c\" d ", buf, size, argv, max)); + EXPECT_STREQ("a", argv[0]); + EXPECT_STREQ("b c", argv[1]); + EXPECT_STREQ("d", argv[2]); + EXPECT_EQ(NULL, argv[3]); + tfree(argv); + tfree(buf); +} + +TEST(getdosargv, advancedUsage) { + size_t max = 4; + size_t size = ARG_MAX; + char *buf = tmalloc(size * sizeof(char)); + char **argv = tmalloc(max * sizeof(char *)); + EXPECT_EQ(2, getdosargv(u"(╯°□°)╯︵ ┻━┻", buf, size, argv, max)); + EXPECT_STREQ("(╯°□°)╯︵", argv[0]); + EXPECT_STREQ("┻━┻", argv[1]); + EXPECT_EQ(NULL, argv[2]); + tfree(argv); + tfree(buf); +} + +TEST(getdosargv, testAegeanGothicSupplementaryPlanes) { + size_t max = 4; /* these symbols are almost as old as dos */ + size_t size = ARG_MAX; + char *buf = tmalloc(size * sizeof(char)); + char **argv = tmalloc(max * sizeof(char *)); + EXPECT_EQ(2, getdosargv(u"𐄷𐄸𐄹𐄺𐄻𐄼 𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷", buf, size, argv, max)); + EXPECT_STREQ("𐄷𐄸𐄹𐄺𐄻𐄼", argv[0]); + EXPECT_STREQ("𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷", argv[1]); + EXPECT_EQ(NULL, argv[2]); + tfree(argv); + tfree(buf); +} + +TEST(getdosargv, realWorldUsage) { + size_t max = 512; + size_t size = ARG_MAX; + char *buf = tmalloc(size * sizeof(char)); + char **argv = tmalloc(max * sizeof(char *)); + EXPECT_EQ(5, getdosargv(u"C:\\Users\\jtunn\\printargs.com oh yes yes yes", + buf, size, argv, max)); + EXPECT_STREQ("C:\\Users\\jtunn\\printargs.com", argv[0]); + EXPECT_STREQ("oh", argv[1]); + EXPECT_STREQ("yes", argv[2]); + EXPECT_STREQ("yes", argv[3]); + EXPECT_STREQ("yes", argv[4]); + EXPECT_EQ(NULL, argv[5]); + tfree(argv); + tfree(buf); +} + +TEST(getdosargv, bufferOverrun_countIsStillAccurate_truncatesMemoryWithGrace) { + size_t max = 3; + size_t size = 7; + char *buf = tmalloc(size * sizeof(char)); + char **argv = tmalloc(max * sizeof(char *)); + EXPECT_EQ(3, getdosargv(u"a\t \"b c\" d ", buf, size, argv, max)); + EXPECT_STREQ("a", argv[0]); + EXPECT_STREQ("b c", argv[1]); + EXPECT_EQ(NULL, argv[2]); + tfree(argv); + tfree(buf); +} + +TEST(getdosargv, pureScanningMode) { + size_t max = 0; + size_t size = 0; + char *buf = NULL; + char **argv = NULL; + EXPECT_EQ(3, getdosargv(u"a b c", buf, size, argv, max)); +} + +TEST(getdosargv, justSlashQuote) { + size_t max = 4, size = 16; + char *buf = tmalloc(size * sizeof(char)); + char **argv = tmalloc(max * sizeof(char *)); + EXPECT_EQ(1, getdosargv(u"\"\\\\\\\"\"", buf, size, argv, max)); + EXPECT_STREQ("\\\"", argv[0]); + tfree(argv); + tfree(buf); +} + +TEST(getdosargv, quoteInMiddleOfArg_wontSplitArg) { + size_t max = 4, size = 16; + char *buf = tmalloc(size * sizeof(char)); + char **argv = tmalloc(max * sizeof(char *)); + EXPECT_EQ(1, getdosargv(u"hi\"\"there", buf, size, argv, max)); + EXPECT_STREQ("hithere", argv[0]); + max = 4, size = 16; + EXPECT_EQ(1, getdosargv(u"hi\" \"there", buf, size, argv, max)); + EXPECT_STREQ("hi there", argv[0]); + tfree(argv); + tfree(buf); +} + +TEST(getdosargv, waqQuoting1) { + size_t max = 4; + size_t size = ARG_MAX; + char *buf = tmalloc(size * sizeof(char)); + char **argv = tmalloc(max * sizeof(char *)); + EXPECT_EQ(2, + getdosargv(u"a\\\\\"\"\"\"\"\"\"\"b c\" d", buf, size, argv, max)); + EXPECT_STREQ("a\\\"\"b", argv[0]); + EXPECT_STREQ("c d", argv[1]); + EXPECT_EQ(NULL, argv[2]); + tfree(argv); + tfree(buf); +} + +TEST(getdosargv, waqQuoting2) { + size_t max = 4; + size_t size = ARG_MAX; + char *buf = tmalloc(size * sizeof(char)); + char **argv = tmalloc(max * sizeof(char *)); + EXPECT_EQ(2, getdosargv(u"\"a\\\"b c\" d", buf, size, argv, max)); + EXPECT_STREQ("a\"b c", argv[0]); + EXPECT_STREQ("d", argv[1]); + EXPECT_EQ(NULL, argv[2]); + tfree(argv); + tfree(buf); +} diff --git a/test/libc/runtime/getdosenviron_test.c b/test/libc/runtime/getdosenviron_test.c new file mode 100644 index 00000000..ee909c21 --- /dev/null +++ b/test/libc/runtime/getdosenviron_test.c @@ -0,0 +1,103 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/getdosenviron.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(getdosenviron, testOneVariable) { +#define kEnv u"A=Und wird die Welt auch in Flammen stehen\0" + size_t max = 2; + size_t size = sizeof(kEnv) >> 1; + char *block = tmalloc(size); + char16_t *env = memcpy(tmalloc(sizeof(kEnv)), kEnv, sizeof(kEnv)); + char **envp = tmalloc(max * sizeof(char *)); + EXPECT_EQ(1, getdosenviron(env, block, size, envp, max)); + EXPECT_STREQ("A=Und wird die Welt auch in Flammen stehen", envp[0]); + EXPECT_EQ(NULL, envp[1]); + ASSERT_BINEQ(u"A=Und wird die Welt auch in Flammen stehen  ", block); + tfree(envp); + tfree(env); + tfree(block); +#undef kEnv +} + +TEST(getdosenviron, testTwoVariables) { +#define kEnv \ + (u"𐌰𐌱𐌲𐌳=Und wird die Welt auch in Flammen stehen\0" \ + u"𐌴𐌵𐌶𐌷=Wir werden wieder auferstehen\0") + size_t max = 3; + size_t size = 1024; + char *block = tmalloc(size); + char16_t *env = memcpy(tmalloc(sizeof(kEnv)), kEnv, sizeof(kEnv)); + char **envp = tmalloc(max * sizeof(char *)); + EXPECT_EQ(2, getdosenviron(env, block, size, envp, max)); + EXPECT_STREQ("𐌰𐌱𐌲𐌳=Und wird die Welt auch in Flammen stehen", envp[0]); + EXPECT_STREQ("𐌴𐌵𐌶𐌷=Wir werden wieder auferstehen", envp[1]); + EXPECT_EQ(NULL, envp[2]); + tfree(envp); + tfree(env); + tfree(block); +#undef kEnv +} + +TEST(getdosenviron, testOverrun_truncatesWithGrace) { +#define kEnv u"A=Und wird die Welt auch in Flammen stehen\0" + size_t max = 2; + size_t size = sizeof(kEnv) >> 2; + char *block = tmalloc(size); + char16_t *env = memcpy(tmalloc(sizeof(kEnv)), kEnv, sizeof(kEnv)); + char **envp = tmalloc(max * sizeof(char *)); + EXPECT_EQ(1, getdosenviron(env, block, size, envp, max)); + EXPECT_STREQ("A=Und wird die Welt ", envp[0]); + EXPECT_EQ(NULL, envp[1]); + ASSERT_BINEQ(u"A=Und wird die Welt   ", block); + tfree(envp); + tfree(env); + tfree(block); +#undef kEnv +} + +TEST(getdosenviron, testEmpty_doesntTouchMemory) { + EXPECT_EQ(0, getdosenviron(u"", NULL, 0, NULL, 0)); +} + +TEST(getdosenviron, testEmpty_zeroTerminatesWheneverPossible_1) { + size_t max = 1; + char **envp = tmalloc(max * sizeof(char *)); + EXPECT_EQ(0, getdosenviron(u"", NULL, 0, envp, max)); + EXPECT_EQ(NULL, envp[0]); + tfree(envp); +} + +TEST(getdosenviron, testEmpty_zeroTerminatesWheneverPossible_2) { + size_t size = 1; + char *block = tmalloc(size); + EXPECT_EQ(0, getdosenviron(u"", block, size, NULL, 0)); + EXPECT_BINEQ(u" ", block); + tfree(block); +} + +TEST(getdosenviron, testEmpty_zeroTerminatesWheneverPossible_3) { + size_t size = 2; + char *block = tmalloc(size); + EXPECT_EQ(0, getdosenviron(u"", block, size, NULL, 0)); + EXPECT_BINEQ(u"  ", block); + tfree(block); +} diff --git a/test/libc/runtime/grow_test.c b/test/libc/runtime/grow_test.c new file mode 100644 index 00000000..51c474b0 --- /dev/null +++ b/test/libc/runtime/grow_test.c @@ -0,0 +1,98 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/pushpop.h" +#include "libc/limits.h" +#include "libc/macros.h" +#include "libc/mem/mem.h" +#include "libc/runtime/mappings.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(grow, testNull_hasAllocatingBehavior) { + void *p = NULL; + size_t capacity = 0; + EXPECT_TRUE(grow(&p, &capacity, 1, 0)); + EXPECT_NE(NULL, p); + EXPECT_EQ(32, capacity); + free_s(&p); +} + +TEST(grow, testCapacity_isInUnits_withTerminatorGuarantee) { + void *p = NULL; + size_t capacity = 0; + EXPECT_TRUE(grow(&p, &capacity, 8, 0)); + EXPECT_NE(NULL, p); + EXPECT_EQ(32 / 8 + 1, capacity); + free_s(&p); +} + +TEST(grow, testStackMemory_convertsToDynamic) { + int A[] = {1, 2, 3}; + int *p = A; + size_t capacity = ARRAYLEN(A); + EXPECT_FALSE(isheap(p)); + EXPECT_TRUE(grow(&p, &capacity, sizeof(int), 0)); + EXPECT_TRUE(isheap(p)); + EXPECT_GT(capacity, ARRAYLEN(A)); + EXPECT_EQ(1, p[0]); + EXPECT_EQ(2, p[1]); + EXPECT_EQ(3, p[2]); + p[0] = 7; + EXPECT_EQ(1, A[0]); + free(p); +} + +TEST(grow, testGrowth_clearsNewMemory) { + size_t i, capacity = 123; + char *p = malloc(capacity); + memset(p, 'a', capacity); + EXPECT_TRUE(grow(&p, &capacity, 1, 0)); + EXPECT_GT(capacity, 123); + for (i = 0; i < 123; ++i) ASSERT_EQ('a', p[i]); + for (i = 123; i < capacity; ++i) ASSERT_EQ(0, p[i]); + free_s(&p); +} + +TEST(grow, testBonusParam_willGoAboveAndBeyond) { + size_t capacity = 32; + char *p = malloc(capacity); + EXPECT_TRUE(grow(&p, &capacity, 1, 0)); + EXPECT_LT(capacity, 1024); + free_s(&p); + p = malloc((capacity = 32)); + EXPECT_TRUE(grow(&p, &capacity, 1, 1024)); + EXPECT_GT(capacity, 1024); + free_s(&p); +} + +TEST(grow, testOverflow_returnsFalseAndDoesNotFree) { + int A[] = {1, 2, 3}; + int *p = A; + size_t capacity = ARRAYLEN(A); + EXPECT_FALSE(isheap(p)); + EXPECT_FALSE(grow(&p, &capacity, pushpop(SIZE_MAX), 0)); + EXPECT_FALSE(isheap(p)); + EXPECT_EQ(capacity, ARRAYLEN(A)); + EXPECT_EQ(1, p[0]); + EXPECT_EQ(2, p[1]); + EXPECT_EQ(3, p[2]); + free_s(&p); +} diff --git a/test/libc/runtime/heapsortcar_test.c b/test/libc/runtime/heapsortcar_test.c new file mode 100644 index 00000000..fab29e3b --- /dev/null +++ b/test/libc/runtime/heapsortcar_test.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/bits/bits.h" +#include "libc/macros.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(heapsortcar, test) { + int32_t A[][2] = {{4, 'a'}, {65, 'b'}, {2, 'c'}, {-31, 'd'}, {0, 'e'}, + {99, 'f'}, {2, 'g'}, {83, 'h'}, {782, 'i'}, {1, 'j'}}; + const int32_t B[][2] = {{-31, 'd'}, {0, 'e'}, {1, 'j'}, {2, 'c'}, + {2, 'g'}, {4, 'a'}, {65, 'b'}, {83, 'h'}, + {99, 'f'}, {782, 'i'}}; + unsigned n = ARRAYLEN(A); + heapsortcar(A, n); + ASSERT_EQ(0, memcmp(&A[0], &B[0], sizeof(A))); +} diff --git a/test/libc/runtime/itsatrap_test.c b/test/libc/runtime/itsatrap_test.c new file mode 100644 index 00000000..214552ee --- /dev/null +++ b/test/libc/runtime/itsatrap_test.c @@ -0,0 +1,248 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/limits.h" +#include "libc/runtime/runtime.h" +#include "libc/testlib/testlib.h" + +/** + * @fileoverview Tests for arithmetic overflow traps. + * + * This module assumes -ftrapv, but not -fsanitize=undefined; since + * Ubsan provides a superset trapping functionality, and therefore + * overrides the prior. The nice thing about -ftrapv is that it doesn't + * leak huge amounts of information into the binary. So it's appropriate + * to enable in a release build. + * + * @note LLVM's implementation of the runtime for this crashes due to + * relying on undefined behavior lool, the very thing the flag was + * meant to help prevent, so we don't get punked by the compiler + * @see __addvsi3, __mulvsi3, etc. + */ + +bool overflowed_; + +void __on_arithmetic_overflow(void) { + overflowed_ = true; +} + +void SetUp(void) { + overflowed_ = false; +} + +/* 32-BIT SIGNED NEGATION */ + +TEST(__negvsi2, testMax) { + EXPECT_EQ(-INT_MAX, -VEIL("r", INT_MAX)); + EXPECT_FALSE(overflowed_); +} + +TEST(__negvsi2, testMin0) { + EXPROPRIATE(-VEIL("r", INT_MIN)); + EXPECT_TRUE(overflowed_); +} + +/* 64-BIT SIGNED NEGATION */ + +TEST(__negvdi2, testMax) { + EXPECT_EQ(-LONG_MAX, -VEIL("r", LONG_MAX)); + EXPECT_FALSE(overflowed_); +} + +TEST(__negvdi2, testMin0) { + EXPROPRIATE(-VEIL("r", LONG_MIN)); + EXPECT_TRUE(overflowed_); +} + +/* 32-BIT SIGNED MULTIPLICATION */ + +TEST(__mulvsi3, testMin0) { + EXPECT_EQ(0, 0 * VEIL("r", INT_MIN)); + EXPECT_FALSE(overflowed_); +} + +TEST(__mulvsi3, testMin1) { + EXPECT_EQ(INT_MIN, 1 * VEIL("r", INT_MIN)); + EXPECT_FALSE(overflowed_); +} + +TEST(__mulvsi3, testMin2) { + EXPROPRIATE(2 * VEIL("r", INT_MIN)); + EXPECT_TRUE(overflowed_); +} + +TEST(__mulvsi3, testMax0) { + EXPECT_EQ(0, 0 * VEIL("r", INT_MAX)); + EXPECT_FALSE(overflowed_); +} + +TEST(__mulvsi3, testMax1) { + EXPECT_EQ(INT_MAX, 1 * VEIL("r", INT_MAX)); + EXPECT_FALSE(overflowed_); +} + +TEST(__mulvsi3, testMax2) { + EXPROPRIATE(2 * VEIL("r", INT_MAX)); + EXPECT_TRUE(overflowed_); +} + +TEST(__mulvsi3, test7) { + EXPECT_EQ(0x70000000, 7 * VEIL("r", 0x10000000)); + EXPECT_FALSE(overflowed_); +} + +TEST(__mulvsi3, test8) { + EXPROPRIATE(8 * VEIL("r", 0x10000000)); + EXPECT_TRUE(overflowed_); +} + +TEST(__mulvsi3, test31337) { + EXPROPRIATE(0x31337 * VEIL("r", 0x31337)); + EXPECT_TRUE(overflowed_); +} + +TEST(__mulvsi3, standAndDeliver_aNegativeTimesANegativeEqualsAPositive) { + EXPECT_EQ(25, -5 * VEIL("r", -5)); + EXPECT_FALSE(overflowed_); +} + +/* 64-BIT SIGNED MULTIPLICATION */ + +TEST(__mulvdi3, testMin0) { + EXPECT_EQ(0, 0 * VEIL("r", LONG_MIN)); + EXPECT_FALSE(overflowed_); +} + +TEST(__mulvdi3, testMin1) { + EXPECT_EQ(LONG_MIN, 1 * VEIL("r", LONG_MIN)); + EXPECT_FALSE(overflowed_); +} + +TEST(__mulvdi3, testMin2) { + EXPROPRIATE(2 * VEIL("r", LONG_MIN)); + EXPECT_TRUE(overflowed_); +} + +TEST(__mulvdi3, testMax0) { + EXPECT_EQ(0, 0 * VEIL("r", LONG_MAX)); + EXPECT_FALSE(overflowed_); +} + +TEST(__mulvdi3, testMax1) { + EXPECT_EQ(LONG_MAX, 1 * VEIL("r", LONG_MAX)); + EXPECT_FALSE(overflowed_); +} + +TEST(__mulvdi3, testMax2) { + EXPROPRIATE(2 * VEIL("r", LONG_MAX)); + EXPECT_TRUE(overflowed_); +} + +TEST(__mulvdi3, test7) { + EXPECT_EQ(0x7000000000000000l, 7 * VEIL("r", 0x1000000000000000l)); + EXPECT_FALSE(overflowed_); +} + +TEST(__mulvdi3, test8) { + EXPROPRIATE(8 * VEIL("r", 0x1000000000000000l)); + EXPECT_TRUE(overflowed_); +} + +TEST(__mulvdi3, test31337) { + EXPROPRIATE(0x3133700000000l * VEIL("r", 0x3133700000000l)); + EXPECT_TRUE(overflowed_); +} + +TEST(__mulvdi3, standAndDeliver_aNegativeTimesANegativeEqualsAPositive) { + EXPECT_EQ(25l, -5l * VEIL("r", -5l)); + EXPECT_FALSE(overflowed_); +} + +/* 32-BIT SIGNED ADDITION */ + +TEST(__addvsi3, testMin1) { + EXPECT_EQ(INT_MIN + 1, 1 + VEIL("r", INT_MIN)); + EXPECT_FALSE(overflowed_); +} + +TEST(__addvsi3, testMax1) { + EXPROPRIATE(1 + VEIL("r", INT_MAX)); + EXPECT_TRUE(overflowed_); +} + +TEST(__addvsi3, testNegPos) { + EXPECT_EQ(2, -2 + VEIL("r", 4)); + EXPECT_FALSE(overflowed_); +} + +TEST(__addvsi3, testPosNeg) { + EXPECT_EQ(-2, 2 + VEIL("r", -4)); + EXPECT_FALSE(overflowed_); +} + +/* 64-BIT SIGNED ADDITION */ + +TEST(__addvdi3, testMin1) { + EXPECT_EQ(LONG_MIN + 1, 1 + VEIL("r", LONG_MIN)); + EXPECT_FALSE(overflowed_); +} + +TEST(__addvdi3, testMax1) { + EXPROPRIATE(1 + VEIL("r", LONG_MAX)); + EXPECT_TRUE(overflowed_); +} + +TEST(__addvdi3, testNegPos) { + EXPECT_EQ(2l, -2l + VEIL("r", 4l)); + EXPECT_FALSE(overflowed_); +} + +TEST(__addvdi3, testPosNeg) { + EXPECT_EQ(-2l, 2l + VEIL("r", -4l)); + EXPECT_FALSE(overflowed_); +} + +/* 32-BIT SIGNED SUBTRACTION */ + +TEST(__subvsi3, testMin1) { + EXPROPRIATE(VEIL("r", INT_MIN) - 1); + EXPECT_TRUE(overflowed_); +} + +TEST(__subvsi3, testMax1) { + EXPECT_EQ(INT_MAX - 1, VEIL("r", INT_MAX) - 1); + EXPECT_FALSE(overflowed_); +} + +TEST(__subvsi3, testPosNeg) { + EXPECT_EQ(-2, 2 - VEIL("r", 4)); + EXPECT_FALSE(overflowed_); +} + +/* 64-BIT SIGNED SUBTRACTION */ + +TEST(__subvdi3, testMin1) { + EXPROPRIATE(VEIL("r", LONG_MIN) - 1); + EXPECT_TRUE(overflowed_); +} + +TEST(__subvdi3, testMax1) { + EXPECT_EQ(LONG_MAX - 1, VEIL("r", LONG_MAX) - 1); + EXPECT_FALSE(overflowed_); +} diff --git a/test/libc/runtime/mappings_test.c b/test/libc/runtime/mappings_test.c new file mode 100644 index 00000000..68048cd0 --- /dev/null +++ b/test/libc/runtime/mappings_test.c @@ -0,0 +1,58 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/limits.h" +#include "libc/macros.h" +#include "libc/runtime/mappings.h" +#include "libc/testlib/testlib.h" + +#define ADDR + +struct MemoryCoord stack = ADDRSIZE_TO_COORD(0x7fffffff0000L, 0x00010000); +struct MemoryCoord heap3 = ADDRSIZE_TO_COORD(0x200000020000L, 0x00010000); +struct MemoryCoord heap2 = ADDRSIZE_TO_COORD(0x200000010000L, 0x00010000); +struct MemoryCoord heap1 = ADDRSIZE_TO_COORD(0x200000000000L, 0x00010000); +struct MemoryCoord heapa = ADDRSIZE_TO_COORD(0x200000000000L, 0x00030000); +struct MemoryCoord progg = ADDRSIZE_TO_COORD(0x000000400000L, 0x00010000); +struct MemoryCoord bane = ADDRSIZE_TO_COORD(0xffff800000080000L, 0x00010000); + +TEST(isoverlapping, test) { + EXPECT_FALSE(ISOVERLAPPING(stack, heap3)); + EXPECT_FALSE(ISOVERLAPPING(heap1, heap2)); + EXPECT_FALSE(ISOVERLAPPING(heap2, heap3)); + EXPECT_FALSE(ISOVERLAPPING(heap1, heap3)); + EXPECT_TRUE(ISOVERLAPPING(heapa, heap1)); + EXPECT_TRUE(ISOVERLAPPING(heapa, heap3)); +} + +TEST(findmapping, limits) { + ASSERT_EQ(INT_MAX, ADDR_TO_COORD(0x7fffffff0000L)); + ASSERT_EQ(INT_MIN, ADDR_TO_COORD(-0x800000000000L)); +} + +TEST(findmapping, test) { + struct MemoryCoord c[] = {bane, progg, heap1, heap2, heap3, stack}; + EXPECT_EQ(6, ARRAYLEN(c)); + EXPECT_EQ(0, findmapping_(ADDR_TO_COORD(-0x800000000000UL), c, 6)); + EXPECT_EQ(1, findmapping_(ADDR_TO_COORD(-42), c, 6)); + EXPECT_EQ(1, findmapping_(ADDR_TO_COORD(0x000000300000L), c, 6)); + EXPECT_EQ(2, findmapping_(ADDR_TO_COORD(0x000000400000L), c, 6)); + EXPECT_EQ(6, findmapping_(ADDR_TO_COORD(0x7fffffffffffL), c, 6)); +} diff --git a/test/libc/runtime/mmap_test.c b/test/libc/runtime/mmap_test.c new file mode 100644 index 00000000..8cb1c06f --- /dev/null +++ b/test/libc/runtime/mmap_test.c @@ -0,0 +1,146 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/xchg.h" +#include "libc/calls/calls.h" +#include "libc/fmt/fmt.h" +#include "libc/runtime/gc.h" +#include "libc/runtime/mappings.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/msync.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/prot.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +unsigned m1; + +TEST(mmap, testMapUnmapAnonAnyAddr) { + void *p; + m1 = _mm.i; + EXPECT_NE(MAP_FAILED, (p = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + EXPECT_EQ(m1 + 1, _mm.i); + EXPECT_NE(-1, munmap(p, FRAMESIZE)); + EXPECT_EQ(m1 + 0, _mm.i); +} + +TEST(mmap, testMunmapUnmapsMultiple) { + void *p1, *p2; + m1 = _mm.i; + EXPECT_NE(MAP_FAILED, (p1 = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + EXPECT_NE(MAP_FAILED, (p2 = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + if ((intptr_t)p1 > (intptr_t)p2) xchg(&p1, &p2); + EXPECT_EQ(m1 + 2, _mm.i); + EXPECT_NE(-1, munmap(p1, (intptr_t)p2 + (intptr_t)FRAMESIZE - (intptr_t)p1)); + EXPECT_EQ(m1 + 0, _mm.i); +} + +TEST(mmap, testPartialUnmapRight) { + if (1) return; /* naaah */ + char *p; + m1 = _mm.i; + EXPECT_NE(MAP_FAILED, (p = mmap(NULL, FRAMESIZE * 2, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + EXPECT_EQ(m1 + 1, _mm.i); + EXPECT_NE(-1, munmap(p + FRAMESIZE, FRAMESIZE)); + EXPECT_EQ(m1 + 1, _mm.i); + EXPECT_NE(-1, munmap(p, FRAMESIZE)); + EXPECT_EQ(m1 + 0, _mm.i); +} + +TEST(mmap, testPartialUnmapLeft) { + if (1) return; /* naaah */ + char *p; + m1 = _mm.i; + EXPECT_NE(MAP_FAILED, (p = mmap(NULL, FRAMESIZE * 2, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + EXPECT_EQ(m1 + 1, _mm.i); + EXPECT_NE(-1, munmap(p, FRAMESIZE)); + EXPECT_EQ(m1 + 1, _mm.i); + EXPECT_NE(-1, munmap(p + FRAMESIZE, FRAMESIZE)); + EXPECT_EQ(m1 + 0, _mm.i); +} + +TEST(mmap, testMapFile) { + int fd; + char *p; + char path[PATH_MAX]; + sprintf(path, "%s%s.%d", kTmpPath, program_invocation_short_name, getpid()); + m1 = _mm.i; + ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644))); + EXPECT_EQ(5, write(fd, "hello", 5)); + EXPECT_NE(-1, fdatasync(fd)); + EXPECT_NE(MAP_FAILED, (p = mmap(NULL, 5, PROT_READ, MAP_PRIVATE, fd, 0))); + EXPECT_EQ(m1 + 1, _mm.i); + EXPECT_STREQ("hello", p); + EXPECT_NE(-1, munmap(p, 5)); + EXPECT_EQ(m1 + 0, _mm.i); + EXPECT_NE(-1, close(fd)); + EXPECT_NE(-1, unlink(path)); +} + +TEST(mmap, testMapFile_fdGetsClosed_makesNoDifference) { + int fd; + char *p, buf[16], path[PATH_MAX]; + sprintf(path, "%s%s.%d", kTmpPath, program_invocation_short_name, getpid()); + m1 = _mm.i; + ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644))); + EXPECT_EQ(5, write(fd, "hello", 5)); + EXPECT_NE(-1, fdatasync(fd)); + EXPECT_NE(MAP_FAILED, + (p = mmap(NULL, 5, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0))); + EXPECT_NE(-1, close(fd)); + EXPECT_EQ(m1 + 1, _mm.i); + EXPECT_STREQ("hello", p); + p[1] = 'a'; + EXPECT_NE(-1, msync(p, PAGESIZE, MS_SYNC)); + ASSERT_NE(-1, (fd = open(path, O_RDONLY))); + EXPECT_EQ(5, read(fd, buf, 5)); + EXPECT_STREQN("hallo", buf, 5); + EXPECT_NE(-1, close(fd)); + EXPECT_NE(-1, munmap(p, 5)); + EXPECT_EQ(m1 + 0, _mm.i); + EXPECT_NE(-1, unlink(path)); +} + +TEST(mmap, testMapFixed_destroysEverythingInItsPath) { + m1 = _mm.i; + EXPECT_NE(MAP_FAILED, mmap((void *)(kFixedMappingsStart + FRAMESIZE * 0), + FRAMESIZE, PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); + EXPECT_NE(MAP_FAILED, mmap((void *)(kFixedMappingsStart + FRAMESIZE * 1), + FRAMESIZE, PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); + EXPECT_NE(MAP_FAILED, mmap((void *)(kFixedMappingsStart + FRAMESIZE * 2), + FRAMESIZE, PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); + ASSERT_EQ(m1 + 3, _mm.i); + EXPECT_NE(MAP_FAILED, mmap((void *)(kFixedMappingsStart + FRAMESIZE * 0), + FRAMESIZE * 3, PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); + ASSERT_EQ(m1 + 1, _mm.i); + EXPECT_NE(-1, munmap((void *)kFixedMappingsStart, FRAMESIZE * 3)); +} diff --git a/test/libc/runtime/ringalloc_test.c b/test/libc/runtime/ringalloc_test.c new file mode 100644 index 00000000..f5495aeb --- /dev/null +++ b/test/libc/runtime/ringalloc_test.c @@ -0,0 +1,48 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/ring.h" +#include "libc/testlib/testlib.h" + +TEST(ringalloc, testMagic) { + char *p; + size_t n; + struct RingBuffer ring = {}; + n = FRAMESIZE * 2; + EXPECT_NE(NULL, ringalloc(&ring, n)); + if ((p = ring.p)) { + EXPECT_EQ(0, p[0]); + EXPECT_EQ(0, p[7]); + EXPECT_EQ(0, p[n + 0]); + EXPECT_EQ(0, p[n + 7]); + p[0] = 23; + p[7] = 123; + EXPECT_EQ(23, p[0]); + EXPECT_EQ(123, p[7]); + EXPECT_EQ(23, p[n + 0]); + EXPECT_EQ(123, p[n + 7]); + } + EXPECT_NE(-1, ringfree(&ring)); +} + +TEST(ringalloc, testFrameSized) { + struct RingBuffer ring = {}; + EXPECT_NE(NULL, ringalloc(&ring, FRAMESIZE)); + EXPECT_NE(-1, ringfree(&ring)); +} diff --git a/test/libc/runtime/test.mk b/test/libc/runtime/test.mk new file mode 100644 index 00000000..072560b0 --- /dev/null +++ b/test/libc/runtime/test.mk @@ -0,0 +1,71 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_RUNTIME + +TEST_LIBC_RUNTIME_SRCS := $(wildcard test/libc/runtime/*.c) +TEST_LIBC_RUNTIME_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_RUNTIME_SRCS)) +TEST_LIBC_RUNTIME_COMS = $(TEST_LIBC_RUNTIME_OBJS:%.o=%.com) + +TEST_LIBC_RUNTIME_OBJS = \ + $(TEST_LIBC_RUNTIME_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_RUNTIME_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_RUNTIME_BINS = \ + $(TEST_LIBC_RUNTIME_COMS) \ + $(TEST_LIBC_RUNTIME_COMS:%=%.dbg) + +TEST_LIBC_RUNTIME_TESTS = \ + $(TEST_LIBC_RUNTIME_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_RUNTIME_CHECKS = \ + $(TEST_LIBC_RUNTIME_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_RUNTIME_DIRECTDEPS = \ + LIBC_CALLS \ + LIBC_CALLS_HEFTY \ + LIBC_FMT \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_STDIO \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_TESTLIB \ + LIBC_X \ + THIRD_PARTY_XED + +TEST_LIBC_RUNTIME_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_RUNTIME_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/runtime/runtime.pkg: \ + $(TEST_LIBC_RUNTIME_OBJS) \ + $(foreach x,$(TEST_LIBC_RUNTIME_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/runtime/%.com.dbg: \ + $(TEST_LIBC_RUNTIME_DEPS) \ + o/$(MODE)/test/libc/runtime/%.o \ + o/$(MODE)/test/libc/runtime/runtime.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +$(TEST_LIBC_RUNTIME_OBJS): \ + DEFAULT_CCFLAGS += \ + -fno-builtin + +o/$(MODE)/test/libc/runtime/getenv_test.com.runs: \ + o/$(MODE)/test/libc/runtime/getenv_test.com + @HELLO=THERE build/runit $@ $< + +o/$(MODE)/test/libc/runtime/itsatrap_test.o: \ + OVERRIDE_CFLAGS += \ + -fno-sanitize=all \ + -ftrapv + +.PHONY: o/$(MODE)/test/libc/runtime +o/$(MODE)/test/libc/runtime: \ + $(TEST_LIBC_RUNTIME_BINS) \ + $(TEST_LIBC_RUNTIME_CHECKS) diff --git a/test/libc/sock/inet_ntop_test.c b/test/libc/sock/inet_ntop_test.c new file mode 100644 index 00000000..fdf7df2e --- /dev/null +++ b/test/libc/sock/inet_ntop_test.c @@ -0,0 +1,63 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/errno.h" +#include "libc/sock/sock.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/af.h" +#include "libc/testlib/testlib.h" + +TEST(inet_ntop, test) { + char buf[16]; + uint8_t localhost[4] = {127, 0, 0, 1}; + EXPECT_STREQ("127.0.0.1", inet_ntop(AF_INET, localhost, buf, sizeof(buf))); +} + +TEST(inet_ntop, testMax) { + char buf[16]; + uint8_t localhost[4] = {255, 255, 255, 255}; + EXPECT_STREQ("255.255.255.255", + inet_ntop(AF_INET, localhost, buf, sizeof(buf))); +} + +TEST(inet_ntop, testBadFamily) { + char buf[16] = "hi"; + uint8_t localhost[4] = {127, 0, 0, 1}; + ASSERT_EQ(NULL, inet_ntop(666, localhost, buf, sizeof(buf))); + EXPECT_EQ(EAFNOSUPPORT, errno); + ASSERT_STREQ("", buf); +} + +TEST(inet_ntop, testNoSpace) { + char *buf = memcpy(tmalloc(16), "hi", 3); + uint8_t localhost[4] = {127, 0, 0, 1}; + ASSERT_EQ(NULL, inet_ntop(AF_INET, localhost, buf, 0)); + EXPECT_EQ(ENOSPC, errno); + ASSERT_STREQ("hi", buf); + ASSERT_EQ(NULL, inet_ntop(AF_INET, localhost, buf, 7)); + ASSERT_STREQ("", buf); + tfree(buf); +} + +TEST(inet_ntop, testSqueeze) { + char *buf = memcpy(tmalloc(8), "hi", 3); + uint8_t localhost[4] = {0, 0, 0, 0}; + ASSERT_STREQ("0.0.0.0", inet_ntop(AF_INET, localhost, buf, 8)); + tfree(buf); +} diff --git a/test/libc/sock/inet_pton_test.c b/test/libc/sock/inet_pton_test.c new file mode 100644 index 00000000..0189e71f --- /dev/null +++ b/test/libc/sock/inet_pton_test.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/progn.h" +#include "libc/bits/safemacros.h" +#include "libc/sock/sock.h" +#include "libc/sysv/consts/af.h" +#include "libc/sysv/consts/inaddr.h" +#include "libc/testlib/testlib.h" + +TEST(inet_pton, testLocalhost) { + uint32_t addr; + EXPECT_EQ(htonl(INADDR_LOOPBACK), + PROGN(ASSERT_EQ(1, inet_pton(AF_INET, "127.0.0.1", &addr)), addr)); +} + +TEST(inet_pton, testBadAddresses) { + uint32_t addr; + ASSERT_EQ(0, inet_pton(AF_INET, "127.0.0", &addr)); + ASSERT_EQ(0, inet_pton(AF_INET, "256.0.0.1", &addr)); +} + +TEST(inet_pton, testBadFamily) { + uint32_t addr = 666; + ASSERT_EQ(-1, inet_pton(666, "127.0.0.1", &addr)); +} diff --git a/test/libc/sock/poll_test.c b/test/libc/sock/poll_test.c new file mode 100644 index 00000000..1a5b0bc2 --- /dev/null +++ b/test/libc/sock/poll_test.c @@ -0,0 +1,80 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/macros.h" +#include "libc/runtime/gc.h" +#include "libc/sock/sock.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/limits.h" +#include "libc/sysv/consts/poll.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" +#include "tool/decode/lib/flagger.h" +#include "tool/decode/lib/pollnames.h" + +#if 0 /* todo(jart): fix me */ + +#define POLL(FDS, TIMEOUT) \ + poll(((struct pollfd[])FDS), ARRAYLEN(((struct pollfd[])FDS)), TIMOUT) + +nodiscard char *FormatPollFd(struct pollfd *pol) { + return xasprintf("fd:%d revents:%s", pol->fd, + gc(recreateflags(kPollNames, pol->revents))); +} + +TEST(poll, testNegativeOneFd_completelyIgnored) { + struct pollfd fds[] = {{-1}}; + EXPECT_EQ(0, poll(fds, ARRAYLEN(fds), 0)); + EXPECT_STREQ("fd:-1 revents:0", gc(FormatPollFd(&fds[0]))); +} + +TEST(poll, demo) { + int rw[2]; + char buf[2] = "hi"; + ASSERT_NE(-1, pipe(rw)); + ASSERT_EQ(2, write(rw[1], buf, sizeof(buf))); /* produce */ + { + struct pollfd fds[] = {{rw[0], POLLIN}, {rw[1], POLLOUT}}; + EXPECT_EQ(2, poll(fds, ARRAYLEN(fds), 0)); + system(gc(xasprintf("ls -l /proc/%d/fd", getpid()))); + EXPECT_STREQ("fd:3 revents:POLLIN", gc(FormatPollFd(fds + 0))); + EXPECT_STREQ("fd:4 revents:POLLOUT", gc(FormatPollFd(&fds[1]))); + } + ASSERT_EQ(2, read(rw[0], buf, sizeof(buf))); /* consume */ + { + struct pollfd fds[] = {{rw[0], POLLIN}, {rw[1], POLLOUT}}; + EXPECT_EQ(1, poll(fds, ARRAYLEN(fds), 0)); + EXPECT_STREQ("fd:3 revents:0", gc(FormatPollFd(&fds[0]))); + EXPECT_STREQ("fd:4 revents:POLLOUT", gc(FormatPollFd(&fds[1]))); + } + ASSERT_NE(-1, close(rw[1])); /* close producer */ + { + struct pollfd fds[] = {{rw[0], POLLIN}, {rw[1], POLLOUT}}; + EXPECT_EQ(2, poll(fds, ARRAYLEN(fds), 0)); + EXPECT_STREQ("fd:3 revents:POLLHUP", gc(FormatPollFd(&fds[0]))); + EXPECT_STREQ("fd:4 revents:POLLNVAL", gc(FormatPollFd(&fds[1]))); + } + ASSERT_NE(-1, close(rw[0])); /* close consumer */ +} + +#endif diff --git a/test/libc/sock/test.mk b/test/libc/sock/test.mk new file mode 100644 index 00000000..dbe2c69d --- /dev/null +++ b/test/libc/sock/test.mk @@ -0,0 +1,61 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_SOCK + +TEST_LIBC_SOCK_SRCS := $(wildcard test/libc/sock/*.c) +TEST_LIBC_SOCK_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_SOCK_SRCS)) +TEST_LIBC_SOCK_COMS = $(TEST_LIBC_SOCK_OBJS:%.o=%.com) + +TEST_LIBC_SOCK_OBJS = \ + $(TEST_LIBC_SOCK_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_SOCK_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_SOCK_BINS = \ + $(TEST_LIBC_SOCK_COMS) \ + $(TEST_LIBC_SOCK_COMS:%=%.dbg) + +TEST_LIBC_SOCK_TESTS = \ + $(TEST_LIBC_SOCK_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_SOCK_CHECKS = \ + $(TEST_LIBC_SOCK_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_SOCK_DIRECTDEPS = \ + LIBC_CALLS \ + LIBC_CALLS_HEFTY \ + LIBC_STDIO \ + LIBC_FMT \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_SOCK \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_TESTLIB \ + LIBC_X \ + TOOL_DECODE_LIB + +TEST_LIBC_SOCK_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_SOCK_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/sock/sock.pkg: \ + $(TEST_LIBC_SOCK_OBJS) \ + $(foreach x,$(TEST_LIBC_SOCK_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/sock/%.com.dbg: \ + $(TEST_LIBC_SOCK_DEPS) \ + o/$(MODE)/test/libc/sock/%.o \ + o/$(MODE)/test/libc/sock/sock.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +$(TEST_LIBC_SOCK_OBJS): \ + $(BUILD_FILES) \ + test/libc/sock/test.mk + +.PHONY: o/$(MODE)/test/libc/sock +o/$(MODE)/test/libc/sock: \ + $(TEST_LIBC_SOCK_BINS) \ + $(TEST_LIBC_SOCK_CHECKS) diff --git a/test/libc/stdio/fgetc_test.c b/test/libc/stdio/fgetc_test.c new file mode 100644 index 00000000..2ad41cd6 --- /dev/null +++ b/test/libc/stdio/fgetc_test.c @@ -0,0 +1,70 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/stdio/stdio.h" +#include "libc/testlib/testlib.h" + +int pipefd[2]; +FILE *f, *reader, *writer; + +TEST(fgetc, testEnd) { + f = fmemopen(NULL, BUFSIZ, "r+"); + EXPECT_EQ(EOF, fgetc(f)); + EXPECT_TRUE(feof(f)); + EXPECT_FALSE(ferror(f)); + EXPECT_EQ(0, fclose(f)); +} + +TEST(fgetwc, testEnd) { + f = fmemopen(NULL, BUFSIZ, "r+"); + EXPECT_EQ(WEOF, fgetwc(f)); + EXPECT_TRUE(feof(f)); + EXPECT_FALSE(ferror(f)); + EXPECT_EQ(0, fclose(f)); +} + +TEST(fgetwc, testMultibyte) { + f = fmemopen(NULL, BUFSIZ, "r+"); + EXPECT_EQ(L'𝑥', fputwc(L'𝑥', f)); + EXPECT_EQ(L'𝑦', fputwc(L'𝑦', f)); + EXPECT_EQ(L'𝑧', fputwc(L'𝑧', f)); + EXPECT_EQ(L'𝑥', fgetwc(f)); + EXPECT_EQ(L'𝑦', fgetwc(f)); + EXPECT_EQ(L'𝑧', fgetwc(f)); + EXPECT_EQ(WEOF, fgetwc(f)); + EXPECT_TRUE(feof(f)); + fclose(f); +} + +TEST(fgetc, testPipe) { + ASSERT_NE(-1, pipe(pipefd)); + writer = fdopen(pipefd[1], "w"); + reader = fdopen(pipefd[0], "r"); + EXPECT_EQ('a', fputc('a', writer)); + EXPECT_EQ('b', fputc('b', writer)); + EXPECT_EQ('c', fputc('c', writer)); + EXPECT_EQ(3, fflush(writer)); + EXPECT_EQ('a', fgetc(reader)); + EXPECT_EQ('b', fgetc(reader)); + EXPECT_EQ('c', fgetc(reader)); + EXPECT_EQ(0, fclose(reader)); + EXPECT_EQ(0, fclose(writer)); +} diff --git a/test/libc/stdio/fgetwc_test.c b/test/libc/stdio/fgetwc_test.c new file mode 100644 index 00000000..1e1cc796 --- /dev/null +++ b/test/libc/stdio/fgetwc_test.c @@ -0,0 +1,56 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/stdio/stdio.h" +#include "libc/testlib/testlib.h" + +TEST(fgetwc, testAscii_oneChar) { + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + EXPECT_EQ('A', fputc('A', f)); + EXPECT_EQ('A', fgetc(f)); + fclose(f); +} + +TEST(fgetwc, testAscii_twoChar) { + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + EXPECT_EQ('A', fputc('A', f)); + EXPECT_EQ('B', fputc('B', f)); + EXPECT_EQ('A', fgetc(f)); + EXPECT_EQ('B', fgetc(f)); + fclose(f); +} + +TEST(fgetwc, testUnicode_oneChar) { + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + EXPECT_EQ(L'𐌰', fputwc(L'𐌰', f)); + EXPECT_EQ(L'𐌰', fgetwc(f)); + fclose(f); +} + +TEST(fgetwc, testUnicode_oneChar_writtenAsRawUtf8) { + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + EXPECT_EQ(0xF0, fputc(0xF0, f)); + EXPECT_EQ(0x90, fputc(0x90, f)); + EXPECT_EQ(0x8C, fputc(0x8C, f)); + EXPECT_EQ(0xB0, fputc(0xB0, f)); + EXPECT_EQ(L'𐌰', fgetwc(f)); + EXPECT_EQ(-1u, fgetwc(f)); + fclose(f); +} diff --git a/test/libc/stdio/getline_test.c b/test/libc/stdio/getline_test.c new file mode 100644 index 00000000..22b3f0c2 --- /dev/null +++ b/test/libc/stdio/getline_test.c @@ -0,0 +1,75 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/mem/mem.h" +#include "libc/stdio/stdio.h" +#include "libc/testlib/testlib.h" + +TEST(getline, testEmpty) { + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + char *line = NULL; + size_t linesize = 0; + EXPECT_EQ(-1, getline(&line, &linesize, f)); + EXPECT_TRUE(feof(f)); + EXPECT_FALSE(ferror(f)); + EXPECT_EQ(0, fclose(f)); + free(line); +} + +TEST(getline, testOneWithoutLineFeed) { + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + ASSERT_EQ(5, fwrite("hello", 1, 5, f)); + char *line = NULL; + size_t linesize = 0; + ASSERT_EQ(5, getline(&line, &linesize, f)); + EXPECT_STREQ("hello", line); + EXPECT_TRUE(feof(f)); + EXPECT_FALSE(ferror(f)); + ASSERT_EQ(-1, getline(&line, &linesize, f)); + EXPECT_EQ(0, fclose(f)); + free(line); +} + +TEST(getline, testTwoLines) { + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + ASSERT_EQ(12, fwrite("hello\nthere\n", 1, 12, f)); + char *line = NULL; + size_t linesize = 0; + ASSERT_EQ(6, getline(&line, &linesize, f)); + EXPECT_STREQ("hello\n", line); + EXPECT_FALSE(feof(f) | ferror(f)); + ASSERT_EQ(6, getline(&line, &linesize, f)); + EXPECT_STREQ("there\n", line); + ASSERT_EQ(-1, getline(&line, &linesize, f)); + EXPECT_STREQ("", line); + EXPECT_EQ(0, fclose(f)); + free(line); +} + +TEST(getline, testBinaryLine_countExcludesOnlyTheBonusNul) { + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + fwrite("he\0\3o\n", 1, 6, f); + char *line = NULL; + size_t linesize = 0; + ASSERT_EQ(6, getline(&line, &linesize, f)); + EXPECT_BINEQ(u"he ♥o◙ ", line); + fclose(f); + free(line); +} diff --git a/test/libc/stdio/mkostempsm_test.c b/test/libc/stdio/mkostempsm_test.c new file mode 100644 index 00000000..13995311 --- /dev/null +++ b/test/libc/stdio/mkostempsm_test.c @@ -0,0 +1,81 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/errno.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/internal.h" +#include "libc/stdio/temp.h" +#include "libc/sysv/consts/o.h" +#include "libc/testlib/testlib.h" + +#define MODE() \ + ({ \ + va_list va; \ + unsigned Mode; \ + va_start(va, flags); \ + Mode = va_arg(va, unsigned); \ + va_end(va); \ + Mode; \ + }) + +static int MockOpen1(const char *file, int flags, ...) { + static bool once; + ASSERT_FALSE(once); + once = true; + EXPECT_STREQ("/tmp/mkostemps.ctre5m", file); + EXPECT_EQ(O_RDWR | O_CREAT | O_EXCL, flags); + EXPECT_EQ(0600, MODE()); + return 123; +} + +TEST(mkostempsm, test1) { + uint64_t rando = 1; + char path[PATH_MAX] = "/tmp/mkostemps.XXXXXX"; + EXPECT_EQ(123L, mkostempsmi(path, 0, 0, &rando, 0600, MockOpen1)); + EXPECT_STREQ("/tmp/mkostemps.ctre5m", path); +} + +static int MockOpen2(const char *file, int flags, ...) { + static int state; + switch (state) { + case 0: + state = 1; + EXPECT_STREQ("/tmp/mkostemps.ctre5m", file); + EXPECT_EQ((unsigned)(O_RDWR | O_CREAT | O_EXCL), flags); + EXPECT_EQ(0600, MODE()); + errno = EEXIST; + return -1; + case 1: + state = 1; + EXPECT_STREQ("/tmp/mkostemps.jl1h61", file); + EXPECT_EQ((unsigned)(O_RDWR | O_CREAT | O_EXCL), flags); + EXPECT_EQ(0600, MODE()); + return 123; + default: + abort(); + } +} + +TEST(mkostempsm, test2) { + uint64_t rando = 1; + char path[PATH_MAX] = "/tmp/mkostemps.XXXXXX"; + EXPECT_EQ(123, mkostempsmi(path, 0, 0, &rando, 0600, MockOpen2)); + EXPECT_STREQ("/tmp/mkostemps.jl1h61", path); +} diff --git a/test/libc/stdio/system_test.c b/test/libc/stdio/system_test.c new file mode 100644 index 00000000..d2479b1d --- /dev/null +++ b/test/libc/stdio/system_test.c @@ -0,0 +1,25 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdio/stdio.h" +#include "libc/calls/calls.h" +#include "libc/testlib/testlib.h" + +TEST(system, nullParam_testsIfSystemHasShell) { ASSERT_EQ(true, system(NULL)); } +TEST(system, test) { ASSERT_EQ(42, WEXITSTATUS(system("exit 42"))); } diff --git a/test/libc/stdio/test.mk b/test/libc/stdio/test.mk new file mode 100644 index 00000000..d6e56863 --- /dev/null +++ b/test/libc/stdio/test.mk @@ -0,0 +1,60 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_STDIO + +TEST_LIBC_STDIO_SRCS := $(wildcard test/libc/stdio/*.c) +TEST_LIBC_STDIO_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_STDIO_SRCS)) +TEST_LIBC_STDIO_COMS = $(TEST_LIBC_STDIO_OBJS:%.o=%.com) + +TEST_LIBC_STDIO_OBJS = \ + $(TEST_LIBC_STDIO_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_STDIO_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_STDIO_BINS = \ + $(TEST_LIBC_STDIO_COMS) \ + $(TEST_LIBC_STDIO_COMS:%=%.dbg) + +TEST_LIBC_STDIO_TESTS = \ + $(TEST_LIBC_STDIO_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_STDIO_CHECKS = \ + $(TEST_LIBC_STDIO_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_STDIO_DIRECTDEPS = \ + LIBC_CALLS \ + LIBC_CALLS_HEFTY \ + LIBC_FMT \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_STDIO \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_TESTLIB \ + LIBC_X + +TEST_LIBC_STDIO_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_STDIO_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/stdio/stdio.pkg: \ + $(TEST_LIBC_STDIO_OBJS) \ + $(foreach x,$(TEST_LIBC_STDIO_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/stdio/%.com.dbg: \ + $(TEST_LIBC_STDIO_DEPS) \ + o/$(MODE)/test/libc/stdio/%.o \ + o/$(MODE)/test/libc/stdio/stdio.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +$(TEST_LIBC_STDIO_OBJS): \ + DEFAULT_CCFLAGS += \ + -fno-builtin + +.PHONY: o/$(MODE)/test/libc/stdio +o/$(MODE)/test/libc/stdio: \ + $(TEST_LIBC_STDIO_BINS) \ + $(TEST_LIBC_STDIO_CHECKS) diff --git a/test/libc/str/crc32c_test.c b/test/libc/str/crc32c_test.c new file mode 100644 index 00000000..3c1d61bb --- /dev/null +++ b/test/libc/str/crc32c_test.c @@ -0,0 +1,50 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +#define FANATICS "Fanatics" + +static const char hyperion[] = + FANATICS " have their dreams, wherewith they weave / " + "A paradise for a sect; the savage too / " + "From forth the loftiest fashion of his sleep / " + "..."; + +TEST(crc32c, test) { + EXPECT_EQ(0, crc32c(0, "", 0)); + EXPECT_EQ(crc32c(0, "hello", 5), crc32c(0, "hello", 5)); + EXPECT_EQ(0xe3069283, crc32c(0, "123456789", 9)); + EXPECT_EQ(0x6d6eefba, crc32c(0, hyperion, strlen(hyperion))); + EXPECT_EQ(0x6d6eefba, crc32c(crc32c(0, FANATICS, strlen(FANATICS)), + hyperion + strlen(FANATICS), + strlen(hyperion) - strlen(FANATICS))); +} + +uint32_t crc32c$pure(uint32_t, const char *, size_t) hidden; +uint32_t crc32c$sse42(uint32_t, const char *, size_t) hidden; +FIXTURE(crc32c, pure) { *(void **)(&crc32c) = (void *)crc32c$pure; } +FIXTURE(crc32c, sse42) { + if (X86_HAVE(SSE4_2)) { + *(void **)(&crc32c) = (void *)crc32c$sse42; + } +} diff --git a/test/libc/str/getutf16_test.c b/test/libc/str/getutf16_test.c new file mode 100644 index 00000000..0b60cf14 --- /dev/null +++ b/test/libc/str/getutf16_test.c @@ -0,0 +1,50 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(getutf16, testNul) { + wint_t wc; + EXPECT_EQ(1, getutf16(u"", &wc)); + EXPECT_EQ('\0', wc); + EXPECT_EQ(1, (getutf16)(u"", &wc)); + EXPECT_EQ('\0', wc); +} + +TEST(getutf16, testBasic) { + wint_t wc; + EXPECT_EQ(1, getutf16(u"h", &wc)); + EXPECT_EQ('h', wc); + EXPECT_EQ(1, (getutf16)(u"h", &wc)); + EXPECT_EQ('h', wc); +} + +TEST(getutf16, testAegeanNumberSupplementaryPlane) { + wint_t wc; + EXPECT_EQ(4, tpdecode("𐄷", &wc)); + EXPECT_EQ(4, tpdecode("\xF0\x90\x84\xB7", &wc)); + EXPECT_EQ(0x10137, wc); + EXPECT_EQ(2, strlen16(u"𐄷")); + EXPECT_EQ(2, getutf16(u"𐄷", &wc)); + EXPECT_EQ(0x10137, wc); + EXPECT_EQ(2, (getutf16)(u"𐄷", &wc)); + EXPECT_EQ(0x10137, wc); +} diff --git a/test/libc/str/isnotplaintext_test.c b/test/libc/str/isnotplaintext_test.c new file mode 100644 index 00000000..2260806d --- /dev/null +++ b/test/libc/str/isnotplaintext_test.c @@ -0,0 +1,43 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/hyperion.h" +#include "libc/testlib/testlib.h" + +#if 0 +void *isnotplaintext(const void *, size_t) + __attribute__((__pure__, __leaf__, __nothrow__)); +#endif + +TEST(isnotplaintext, test) { + EXPECT_EQ(NULL, isnotplaintext(kHyperion, kHyperionSize)); + EXPECT_STREQ("", isnotplaintext(kHyperion, kHyperionSize + 1)); +} + +char *doit(char *data, size_t size) { + data = isnotplaintext(data, size); + asm volatile("" : "+r"(data)); + return data; +} + +BENCH(isnotplaintext, bench) { + EZBENCH(donothing, doit(kHyperion, kHyperionSize)); +} diff --git a/test/libc/str/memccpy_test.c b/test/libc/str/memccpy_test.c new file mode 100644 index 00000000..4f2c0b3e --- /dev/null +++ b/test/libc/str/memccpy_test.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(memccpy, testStringCopy) { + char buf[16]; + EXPECT_EQ(buf + 3, memccpy(buf, "hi", '\0', sizeof(buf))); + EXPECT_STREQ("hi", buf); +} + +TEST(memccpy, testOverflow) { + char buf[1]; + EXPECT_EQ(NULL, memccpy(buf, "hi", '\0', sizeof(buf))); +} + +TEST(memccpy, testZeroLength_doesNothing) { + char buf[1]; + EXPECT_EQ(NULL, memccpy(buf, "hi", '\0', 0)); +} diff --git a/test/libc/str/memcpy_test.c b/test/libc/str/memcpy_test.c new file mode 100644 index 00000000..b74c668a --- /dev/null +++ b/test/libc/str/memcpy_test.c @@ -0,0 +1,83 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(memcpy, memcpy) { + char *b1, *b2; + for (unsigned n = 0; n < 1026; ++n) { + b1 = tmalloc(n); + b2 = tmalloc(n); + ASSERT_EQ(b1, memcpy(b1, b2, n)); + ASSERT_EQ(0, memcmp(b1, b2, n)); + tfree(b2); + tfree(b1); + } +} + +TEST(memcpy, memcpyDirect) { + char *b1, *b2; + for (unsigned n = 0; n < 1026; ++n) { + b1 = tmalloc(n); + b2 = tmalloc(n); + ASSERT_EQ(b1, (memcpy)(b1, b2, n)); + ASSERT_EQ(0, memcmp(b1, b2, n)); + tfree(b2); + tfree(b1); + } +} + +TEST(memcpy, mempcpy) { + char *b1, *b2; + for (unsigned n = 0; n < 1026; ++n) { + b1 = tmalloc(n); + b2 = tmalloc(n); + ASSERT_EQ(b1 + n, mempcpy(b1, b2, n)); + ASSERT_EQ(0, memcmp(b1, b2, n)); + tfree(b2); + tfree(b1); + } +} + +TEST(memcpy, mempcpyDirect) { + char *b1, *b2; + for (unsigned n = 0; n < 1026; ++n) { + b1 = tmalloc(n); + b2 = tmalloc(n); + ASSERT_EQ(b1 + n, (mempcpy)(b1, b2, n)); + ASSERT_EQ(0, memcmp(b1, b2, n)); + tfree(b2); + tfree(b1); + } +} + +TEST(memcpy, overlapping_isFineIfCopyingBackwards) { + for (size_t i = 0; i < 32; ++i) { + char *b1 = tmalloc(64 + i); + char *b2 = tmalloc(64 + i); + memcpy(b1, b2, 64); + memcpy(b1, b1 + i, 64 - i); + memmove(b2, b2 + i, 64 - i); + ASSERT_EQ(0, memcmp(b1, b2, 64)); + tfree(b2); + tfree(b1); + } +} diff --git a/test/libc/str/memfrob_test.c b/test/libc/str/memfrob_test.c new file mode 100644 index 00000000..0d3ca4c8 --- /dev/null +++ b/test/libc/str/memfrob_test.c @@ -0,0 +1,29 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(memfrob, test) { + char buf[6]; + EXPECT_STREQ("*****", memfrob(memcpy(buf, "\0\0\0\0\0", 6), 5)); + EXPECT_STREQ("BOFFE", memfrob(strcpy(buf, "hello"), 5)); + EXPECT_STREQ("hello", memfrob(memfrob(strcpy(buf, "hello"), 5), 5)); +} diff --git a/test/libc/str/memmove_test.c b/test/libc/str/memmove_test.c new file mode 100644 index 00000000..8c821f0f --- /dev/null +++ b/test/libc/str/memmove_test.c @@ -0,0 +1,56 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +#define N 256 +#define S 7 + +TEST(memmove, overlapping) { + for (size_t i = 0; i < N; i += S) { + for (size_t j = 10; j < N; j += S) { + char *b1 = tmalloc(N); + char *b2 = tmalloc(N); + size_t n = min(N - i, N - j); + memcpy(b2, b1 + i, n); + ASSERT_EQ(b1 + j, memmove(b1 + j, b1 + i, n)); + ASSERT_EQ(0, memcmp(b1 + j, b2, n)); + tfree(b2); + tfree(b1); + } + } +} + +TEST(memmove, overlappingDirect) { + for (size_t i = 0; i < N; i += S) { + for (size_t j = 10; j < N; j += S) { + char *b1 = tmalloc(N); + char *b2 = tmalloc(N); + size_t n = min(N - i, N - j); + memcpy(b2, b1 + i, n); + ASSERT_EQ(b1 + j, (memmove)(b1 + j, b1 + i, n)); + ASSERT_EQ(0, memcmp(b1 + j, b2, n)); + tfree(b2); + tfree(b1); + } + } +} diff --git a/test/libc/str/pututf16_test.c b/test/libc/str/pututf16_test.c new file mode 100644 index 00000000..67f3b754 --- /dev/null +++ b/test/libc/str/pututf16_test.c @@ -0,0 +1,76 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" +#include "libc/unicode/unicode.h" + +unsigned n; +size_t size; +wchar_t *str; +char16_t *b, *buf; + +TEST(pututf16, testEmpty) { + EXPECT_EQ(0, pututf16(NULL, 0, u'j', false)); + EXPECT_EQ(0, (pututf16)(NULL, 0, u'j', false)); +} + +TEST(pututf16, testNul) { + size = 1; + buf = tmalloc(size * sizeof(char16_t)); + EXPECT_EQ(1, pututf16(buf, size, u'\0', false)); + EXPECT_EQ(u'\0', buf[0]); + buf[0] = '\7'; + EXPECT_EQ(1, (pututf16)(buf, size, u'\0', false)); + EXPECT_EQ(u'\0', buf[0]); + tfree(buf); +} + +TEST(pututf16, testAscii) { + size = 1; + buf = tmalloc(size * sizeof(char16_t)); + EXPECT_EQ(1, pututf16(buf, size, u'j', false)); + EXPECT_EQ(u'j', buf[0]); + EXPECT_EQ(1, (pututf16)(buf, size, u't', false)); + EXPECT_EQ(u't', buf[0]); + tfree(buf); +} + +TEST(pututf16, testGothicSupplementaryPlane) { + size = 2; + buf = tmalloc(size * sizeof(char16_t)); + EXPECT_EQ(2, pututf16(buf, size, L'𐌰', false)); + EXPECT_STREQN(u"𐌰", buf, 1); + EXPECT_EQ(2, (pututf16)(buf, size, L'𐌱', false)); + EXPECT_STREQN(u"𐌱", buf, 1); + tfree(buf); +} + +TEST(pututf16, testEmojiAndEmojiPresentationModifier_areBothInAstralPlanes) { + n = 8; + b = tgc(tmalloc(sizeof(char16_t) * n)); + str = L"\U0001F466\U0001F3FF"; + memset(b, 0, n * sizeof(char16_t)); + EXPECT_EQ(2, pututf16(b, n, str[0], false)); + EXPECT_BINEQ(u"=╪f▄    ", b); + memset(b, 0, n * sizeof(char16_t)); + EXPECT_EQ(2, pututf16(b, n, str[1], false)); + EXPECT_BINEQ(u"<╪λ▀    ", b); +} diff --git a/test/libc/str/sha256_test.c b/test/libc/str/sha256_test.c new file mode 100644 index 00000000..76dcac3b --- /dev/null +++ b/test/libc/str/sha256_test.c @@ -0,0 +1,39 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" +#include "libc/testlib/hyperion.h" +#include "libc/testlib/testlib.h" + +uint8_t *sha256(const char *s) { + static uint8_t hash[32]; + struct Sha256Ctx ctx; + sha256_init(&ctx); + sha256_update(&ctx, (const uint8_t *)s, strlen(s)); + sha256_final(&ctx, hash); + return hash; +} + +TEST(sha256, test) { + EXPECT_BINEQ(u",≥M║_░ú♫&Φ;*┼╣Γ€←▬▲╲▼ºB^s♦3bôïÿ$", sha256("hello")); +} + +TEST(sha256, testNontrivialSize) { + EXPECT_BINEQ(u"╨╒║☺ª↨╨╒ù€»╝∞nfÑ4Æ╒Tn╫╕`eóA¿↑[3╬", sha256(kHyperion)); +} diff --git a/test/libc/str/sigset_test.c b/test/libc/str/sigset_test.c new file mode 100644 index 00000000..6deb4321 --- /dev/null +++ b/test/libc/str/sigset_test.c @@ -0,0 +1,63 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" +#include "libc/str/str.h" +#include "libc/calls/sigbits.h" +#include "libc/calls/calls.h" +#include "libc/testlib/testlib.h" + +sigset_t ss; + +TEST(sigemptyset, test) { + EXPECT_EQ(0, sigemptyset(&ss)); + EXPECT_BINEQ(u"        ", &ss); +} + +TEST(sigfillset, test) { + EXPECT_EQ(0, sigfillset(&ss)); + EXPECT_BINEQ(u"λλλλλλλλ", &ss); +} + +TEST(sigaddset, test) { + sigemptyset(&ss); + EXPECT_EQ(0, sigaddset(&ss, 1)); + EXPECT_BINEQ(u"☺       ", &ss); + EXPECT_EQ(0, sigaddset(&ss, 64)); + EXPECT_BINEQ(u"☺      Ç", &ss); +} + +TEST(sigdelset, test) { + sigfillset(&ss); + EXPECT_EQ(0, sigdelset(&ss, 1)); + EXPECT_BINEQ(u"■λλλλλλλ", &ss); + EXPECT_EQ(0, sigdelset(&ss, 64)); + EXPECT_BINEQ(u"■λλλλλλ⌂", &ss); +} + +TEST(sigismember, test) { + sigfillset(&ss); + EXPECT_TRUE(sigismember(&ss, 1)); + sigdelset(&ss, 1); + EXPECT_FALSE(sigismember(&ss, 1)); + EXPECT_TRUE(sigismember(&ss, 64)); + sigdelset(&ss, 64); + EXPECT_FALSE(sigismember(&ss, 64)); +} diff --git a/test/libc/str/str_test.c b/test/libc/str/str_test.c new file mode 100644 index 00000000..266b1f7c --- /dev/null +++ b/test/libc/str/str_test.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(strlen16, testEmpty) { EXPECT_EQ(0, strlen(u"")); } +TEST(strlen16, testAscii) { EXPECT_EQ(5, strlen(u"hello")); } + +TEST(strlen16, testUnicode) { + EXPECT_EQ(28, strlen(u"αcτµαlly pδrταblε εxεcµταblε")); +} + +TEST(strclen, testAegeanNumberSupplementaryPlane) { + EXPECT_EQ(36, strlen("𐄷𐄸𐄹𐄺𐄻𐄼𐄽𐄾𐄿")); + EXPECT_EQ(18, strlen(u"𐄷𐄸𐄹𐄺𐄻𐄼𐄽𐄾𐄿")); + EXPECT_EQ(9, strlen(L"𐄷𐄸𐄹𐄺𐄻𐄼𐄽𐄾𐄿")); + EXPECT_EQ(9, strclen("𐄷𐄸𐄹𐄺𐄻𐄼𐄽𐄾𐄿")); + EXPECT_EQ(9, strclen(u"𐄷𐄸𐄹𐄺𐄻𐄼𐄽𐄾𐄿")); + EXPECT_EQ(9, strclen(L"𐄷𐄸𐄹𐄺𐄻𐄼𐄽𐄾𐄿")); +} + +TEST(strlen16, testCoolKidNulTerminator) { + EXPECT_EQ(2, strlen((const char16_t *)"\x00\xd8\x00\xdc\x00")); +} diff --git a/test/libc/str/strchr_test.c b/test/libc/str/strchr_test.c new file mode 100644 index 00000000..cfce6b82 --- /dev/null +++ b/test/libc/str/strchr_test.c @@ -0,0 +1,64 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(strchr, blank) { + const char *const blank = ""; + EXPECT_EQ(NULL, strchr(blank, '#')); + EXPECT_EQ(blank, strchr(blank, '\0')); +} + +TEST(strchr, text) { + char buf[] = "hellothere"; + EXPECT_STREQ("there", strchr(buf, 't')); +} +TEST(rawmemchr, text) { + char buf[] = "hellothere"; + EXPECT_STREQ("there", rawmemchr(buf, 't')); +} +TEST(strchrnul, text) { + char buf[] = "hellothere"; + EXPECT_STREQ("there", strchrnul(buf, 't')); +} + +TEST(strchr, nulTerminator) { + char buf[] = "hellothere"; + EXPECT_STREQ("", strchr(buf, '\0')); +} +TEST(rawmemchr, nulTerminator) { + char buf[] = "hellothere"; + EXPECT_STREQ("", rawmemchr(buf, '\0')); +} +TEST(strchrnul, nulTerminator) { + char buf[] = "hellothere"; + EXPECT_STREQ("", strchrnul(buf, '\0')); +} + +TEST(strchr, notFound_returnsNul) { + char buf[] = "hellothere"; + EXPECT_EQ(NULL, strchr(buf, 'z')); +} +TEST(strchrnul, notFound_returnsPointerToNulByte) { + char buf[] = "hi"; + EXPECT_STREQ("", strchrnul(buf, 'z')); + EXPECT_EQ(&buf[2], strchrnul(buf, 'z')); +} diff --git a/test/libc/str/strcmp_test.c b/test/libc/str/strcmp_test.c new file mode 100644 index 00000000..c7cb07fd --- /dev/null +++ b/test/libc/str/strcmp_test.c @@ -0,0 +1,587 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/dce.h" +#include "libc/macros.h" +#include "libc/nexgen32e/cachesize.h" +#include "libc/nexgen32e/tinystrcmp.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/rand/rand.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +int memcmp$sse2(const void *, const void *, size_t) hidden; +int memcmp$avx2(const void *, const void *, size_t) hidden; +int (*memcmpi)(const void *, const void *, size_t) = memcmp$sse2; + +int strcmp$k8(const char *, const char *) hidden; +int strcmp$avx(const char *, const char *) hidden; +int (*strcmpi)(const char *, const char *) = tinystrcmp; + +int strncmp$k8(const char *, const char *, size_t) hidden; +int strncmp$avx(const char *, const char *, size_t) hidden; +int (*strncmpi)(const char *, const char *, size_t) = tinystrncmp; + +FIXTURE(strcmp, avx) { + if (X86_HAVE(AVX)) { + strcmpi = strcmp$avx; + strncmpi = strncmp$avx; + } + if (X86_HAVE(AVX2)) { + memcmpi = memcmp$avx2; + } +} + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ test/libc/str/strcmp_test.c § emptiness ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +TEST(strcmp, emptyString) { + EXPECT_EQ(0, strcmpi("", "")); + EXPECT_NE(0, strcmpi("", "a")); +} + +TEST(strcasecmp, emptyString) { + EXPECT_EQ(0, strcasecmp("", "")); + EXPECT_NE(0, strcasecmp("", "a")); +} + +TEST(strcmp16, emptyString) { + EXPECT_EQ(0, strcmp16(u"", u"")); + EXPECT_NE(0, strcmp16(u"", u"a")); +} + +TEST(strcasecmp16, emptyString) { + EXPECT_EQ(0, strcasecmp16(u"", u"")); + EXPECT_NE(0, strcasecmp16(u"", u"a")); +} + +TEST(wcscmp, emptyString) { + EXPECT_EQ(0, wcscmp(L"", L"")); + EXPECT_NE(0, wcscmp(L"", L"a")); +} + +TEST(wcscasecmp, emptyString) { + EXPECT_EQ(0, wcscasecmp(L"", L"")); + EXPECT_NE(0, wcscasecmp(L"", L"a")); +} + +TEST(strncmp, emptyString) { + char *s1 = strcpy(tmalloc(1), ""); + char *s2 = strcpy(tmalloc(1), ""); + ASSERT_EQ(0, strncmpi(s1, s2, 0)); + ASSERT_EQ(0, strncmpi(s1, s2, 1)); + ASSERT_EQ(0, strncmpi(s1, s2, -1)); + ASSERT_EQ(0, strncmpi(s1, s1, -1)); + ASSERT_EQ(0, strncmpi(s2, s2, -1)); + tfree(s2); + tfree(s1); +} + +TEST(strncasecmp, emptyString) { + char *s1 = strcpy(tmalloc(1), ""); + char *s2 = strcpy(tmalloc(1), ""); + ASSERT_EQ(0, strncasecmp(s1, s2, 0)); + ASSERT_EQ(0, strncasecmp(s1, s2, 1)); + ASSERT_EQ(0, strncasecmp(s1, s2, -1)); + ASSERT_EQ(0, strncasecmp(s1, s1, -1)); + ASSERT_EQ(0, strncasecmp(s2, s2, -1)); + tfree(s2); + tfree(s1); +} + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ test/libc/str/strcmp_test.c § inequality ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +TEST(strncmp, testInequality) { + char *s1 = strcpy(tmalloc(2), "1"); + char *s2 = strcpy(tmalloc(1), ""); + ASSERT_EQ(0, strncmpi(s1, s2, 0)); + ASSERT_EQ('1', strncmpi(s1, s2, 1)); + ASSERT_EQ(-'1', strncmpi(s2, s1, 1)); + tfree(s2); + tfree(s1); +} + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ test/libc/str/strcmp_test.c § does it work? ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +TEST(memcmp, test) { + EXPECT_EQ(memcmpi("\200", "\200", 1), 0); + EXPECT_LT(memcmpi("\177", "\200", 1), 0); + EXPECT_GT(memcmpi("\200", "\177", 1), 0); + EXPECT_EQ(memcmpi("", "", 0), 0); + EXPECT_EQ(memcmpi("a", "a", 1), 0); + EXPECT_GT(memcmpi("a", "A", 1), 0); + EXPECT_LT(memcmpi("A", "a", 1), 0); + EXPECT_LT(memcmpi("\001", "\377", 1), 0); + EXPECT_GT(memcmpi("\377", "\001", 1), 0); + EXPECT_EQ(memcmpi("a", "aa", 1), 0); + EXPECT_EQ(memcmpi("aa", "a", 1), 0); + EXPECT_LT(memcmpi("a", "aa", 2), 0); + EXPECT_GT(memcmpi("aa", "a", 2), 0); + EXPECT_LT(memcmpi("aaaaaaaaaaaaaaa\001", "aaaaaaaaaaaaaaa\377", 16), 0); + EXPECT_GT(memcmpi("aaaaaaaaaaaaaaa\377", "aaaaaaaaaaaaaaa\001", 16), 0); + EXPECT_LT(memcmpi("aaaaaaaaaaaaaaaa\001", "aaaaaaaaaaaaaaaa\377", 17), 0); + EXPECT_GT(memcmpi("aaaaaaaaaaaaaaaa\377", "aaaaaaaaaaaaaaaa\001", 17), 0); + EXPECT_LT(memcmpi("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\001", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\377", 32), + 0); + EXPECT_GT(memcmpi("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\377", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\001", 32), + 0); + EXPECT_LT(memcmpi("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\001", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\377", 33), + 0); + EXPECT_GT(memcmpi("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\377", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\001", 33), + 0); + EXPECT_LT(memcmpi("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\001", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\377", 34), + 0); + EXPECT_GT(memcmpi("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\377", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\001", 34), + 0); +} + +TEST(strcmp, testItWorks) { + EXPECT_EQ(strcmpi("", ""), 0); + EXPECT_EQ(strcmpi("a", "a"), 0); + EXPECT_GT(strcmpi("a", "A"), 0); + EXPECT_LT(strcmpi("A", "a"), 0); + EXPECT_LT(strcmpi("\001", "\377"), 0); + EXPECT_GT(strcmpi("\377", "\001"), 0); + EXPECT_LT(strcmpi("a", "aa"), 0); + EXPECT_GT(strcmpi("aa", "a"), 0); + EXPECT_LT(strcmpi("a\000", "aa\000"), 0); + EXPECT_GT(strcmpi("aa\000", "a\000"), 0); + EXPECT_LT(strcmpi("aaaaaaaaaaaaaaa\001", "aaaaaaaaaaaaaaa\377"), 0); + EXPECT_GT(strcmpi("aaaaaaaaaaaaaaa\377", "aaaaaaaaaaaaaaa\001"), 0); + EXPECT_LT(strcmpi("aaaaaaaaaaaaaaaa\001", "aaaaaaaaaaaaaaaa\377"), 0); + EXPECT_GT(strcmpi("aaaaaaaaaaaaaaaa\377", "aaaaaaaaaaaaaaaa\001"), 0); + EXPECT_LT(strcmpi("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\001", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\377"), + 0); + EXPECT_GT(strcmpi("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\377", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\001"), + 0); + EXPECT_LT(strcmpi("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\001", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\377"), + 0); + EXPECT_GT(strcmpi("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\377", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\001"), + 0); + EXPECT_LT(strcmpi("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\001", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\377"), + 0); + EXPECT_GT(strcmpi("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\377", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\001"), + 0); +} + +TEST(strcasecmp, testItWorks) { + EXPECT_EQ(strcasecmp("", ""), 0); + EXPECT_EQ(strcasecmp("a", "a"), 0); + EXPECT_EQ(strcasecmp("a", "A"), 0); + EXPECT_EQ(strcasecmp("A", "a"), 0); + EXPECT_LT(strcasecmp("a", "z"), 0); + EXPECT_GT(strcasecmp("z", "a"), 0); + EXPECT_LT(strcasecmp("\001", "\377"), 0); + EXPECT_GT(strcasecmp("\377", "\001"), 0); + EXPECT_LT(strcasecmp("a", "aa"), 0); + EXPECT_GT(strcasecmp("aa", "a"), 0); + EXPECT_LT(strcasecmp("a\000", "aa\000"), 0); + EXPECT_GT(strcasecmp("aa\000", "a\000"), 0); + EXPECT_LT(strcasecmp("aaaaaaaaaaaaaaa\001", "aaaaaaaaaaaaaaa\377"), 0); + EXPECT_GT(strcasecmp("aaaaaaaaaaaaaaa\377", "aaaaaaaaaaaaaaa\001"), 0); + EXPECT_LT(strcasecmp("aaaaaaaaaaaaaaaa\001", "aaaaaaaaaaaaaaaa\377"), 0); + EXPECT_GT(strcasecmp("aaaaaaaaaaaaaaaa\377", "aaaaaaaaaaaaaaaa\001"), 0); + EXPECT_LT(strcasecmp("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\001", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\377"), + 0); + EXPECT_GT(strcasecmp("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\377", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\001"), + 0); + EXPECT_LT(strcasecmp("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\001", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\377"), + 0); + EXPECT_GT(strcasecmp("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\377", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\001"), + 0); + EXPECT_LT(strcasecmp("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\001", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\377"), + 0); + EXPECT_GT(strcasecmp("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\377", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\001"), + 0); +} + +TEST(strcmp16, testItWorks) { + EXPECT_EQ(strcmp16(u"", u""), 0); + EXPECT_EQ(strcmp16(u"a", u"a"), 0); + EXPECT_GT(strcmp16(u"a", u"A"), 0); + EXPECT_LT(strcmp16(u"A", u"a"), 0); + EXPECT_LT(strcmp16(u"\001", u"\377"), 0); + EXPECT_GT(strcmp16(u"\377", u"\001"), 0); + EXPECT_LT(strcmp16(u"a", u"aa"), 0); + EXPECT_GT(strcmp16(u"aa", u"a"), 0); + EXPECT_LT(strcmp16(u"a\000", u"aa\000"), 0); + EXPECT_GT(strcmp16(u"aa\000", u"a\000"), 0); + EXPECT_LT(strcmp16(u"aaaaaaaaaaaaaaa\001", u"aaaaaaaaaaaaaaa\377"), 0); + EXPECT_GT(strcmp16(u"aaaaaaaaaaaaaaa\377", u"aaaaaaaaaaaaaaa\001"), 0); + EXPECT_LT(strcmp16(u"aaaaaaaaaaaaaaaa\001", u"aaaaaaaaaaaaaaaa\377"), 0); + EXPECT_GT(strcmp16(u"aaaaaaaaaaaaaaaa\377", u"aaaaaaaaaaaaaaaa\001"), 0); + EXPECT_LT(strcmp16(u"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\001", + u"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\377"), + 0); + EXPECT_GT(strcmp16(u"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\377", + u"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\001"), + 0); + EXPECT_LT(strcmp16(u"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\001", + u"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\377"), + 0); + EXPECT_GT(strcmp16(u"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\377", + u"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\001"), + 0); + EXPECT_LT(strcmp16(u"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\001", + u"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\377"), + 0); + EXPECT_GT(strcmp16(u"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\377", + u"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\001"), + 0); +} + +TEST(wcscmp, testItWorks) { + EXPECT_EQ(wcscmp(L"", L""), 0); + EXPECT_EQ(wcscmp(L"a", L"a"), 0); + EXPECT_GT(wcscmp(L"a", L"A"), 0); + EXPECT_LT(wcscmp(L"A", L"a"), 0); + EXPECT_LT(wcscmp(L"\001", L"\377"), 0); + EXPECT_GT(wcscmp(L"\377", L"\001"), 0); + EXPECT_LT(wcscmp(L"a", L"aa"), 0); + EXPECT_GT(wcscmp(L"aa", L"a"), 0); + EXPECT_LT(wcscmp(L"a", L"aa"), 0); + EXPECT_GT(wcscmp(L"aa", L"a"), 0); + EXPECT_LT(wcscmp(L"aaaaaaaaaaaaaaa\001", L"aaaaaaaaaaaaaaa\377"), 0); + EXPECT_GT(wcscmp(L"aaaaaaaaaaaaaaa\377", L"aaaaaaaaaaaaaaa\001"), 0); + EXPECT_LT(wcscmp(L"aaaaaaaaaaaaaaaa\001", L"aaaaaaaaaaaaaaaa\377"), 0); + EXPECT_GT(wcscmp(L"aaaaaaaaaaaaaaaa\377", L"aaaaaaaaaaaaaaaa\001"), 0); + EXPECT_LT(wcscmp(L"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\001", + L"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\377"), + 0); + EXPECT_GT(wcscmp(L"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\377", + L"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaa\001"), + 0); + EXPECT_LT(wcscmp(L"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\001", + L"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\377"), + 0); + EXPECT_GT(wcscmp(L"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\377", + L"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaa\001"), + 0); + EXPECT_LT(wcscmp(L"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\001", + L"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\377"), + 0); + EXPECT_GT(wcscmp(L"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\377", + L"aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\001"), + 0); +} + +TEST(strcasecmp, testItWorksCase) { + EXPECT_EQ(0, strcasecmp("hello", "HELLO")); + EXPECT_EQ(0, strcasecmp("hello", "Hello")); + EXPECT_EQ(0, strcasecmp("hello", "hello")); + EXPECT_NE(0, strcasecmp("hello", "yello")); +} + +TEST(strcasecmp16, testItWorksCase) { + EXPECT_EQ(0, strcasecmp16(u"hello", u"HELLO")); + EXPECT_EQ(0, strcasecmp16(u"hello", u"Hello")); + EXPECT_EQ(0, strcasecmp16(u"hello", u"hello")); + EXPECT_NE(0, strcasecmp16(u"hello", u"yello")); +} + +TEST(wcscasecmp, testItWorksCase) { + EXPECT_EQ(0, wcscasecmp(L"hello", L"HELLO")); + EXPECT_EQ(0, wcscasecmp(L"hello", L"Hello")); + EXPECT_EQ(0, wcscasecmp(L"hello", L"hello")); + EXPECT_NE(0, wcscasecmp(L"hello", L"yello")); +} + +TEST(strcasecmp8to16, testItWorksCase) { + EXPECT_EQ(0, strcasecmp8to16("hello", u"HELLO")); + EXPECT_EQ(0, strcasecmp8to16("hello", u"Hello")); + EXPECT_EQ(0, strcasecmp8to16("hello", u"hello")); + EXPECT_NE(0, strcasecmp8to16("hello", u"yello")); +} + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ test/libc/str/strcmp_test.c § nontrivial length ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +TEST(strncmp, testEqualManyNs) { + char *s1 = tmalloc(PAGESIZE); + char *s2 = tmalloc(PAGESIZE); + memset(s1, 7, PAGESIZE); + memset(s2, 7, PAGESIZE); + s1[PAGESIZE - 1] = '\0'; + s2[PAGESIZE - 1] = '\0'; + for (unsigned i = 1; i <= 128; ++i) { + ASSERT_EQ(0, strncmpi(s1 + PAGESIZE - i, s2 + PAGESIZE - i, i + 0)); + ASSERT_EQ(0, strncmpi(s1 + PAGESIZE - i, s2 + PAGESIZE - i, i + 1)); + } + tfree(s2); + tfree(s1); +} + +TEST(strncmp, testNotEqualManyNs) { + char *s1 = tmalloc(PAGESIZE); + char *s2 = tmalloc(PAGESIZE); + for (unsigned i = 1; i <= 128; ++i) { + memset(s1, 7, PAGESIZE); + memset(s2, 7, PAGESIZE); + s1[PAGESIZE - 1] = (unsigned char)0; + s2[PAGESIZE - 1] = (unsigned char)255; + ASSERT_EQ(-255, strncmpi(s1 + PAGESIZE - i, s2 + PAGESIZE - i, i + 0)); + ASSERT_EQ(-255, strncmpi(s1 + PAGESIZE - i, s2 + PAGESIZE - i, i + 1)); + } + tfree(s2); + tfree(s1); +} + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ test/libc/str/strcmp_test.c § nul termination vs. explicit length ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +TEST(strncmp, testStringNulTerminatesBeforeExplicitLength) { + const char kRdi[] = ""; + const char kRsi[] = "TZ=America/Los_Angeles"; + char *rdi = memcpy(tmalloc(sizeof(kRdi)), kRdi, sizeof(kRdi)); + char *rsi = memcpy(tmalloc(sizeof(kRsi)), kRsi, sizeof(kRsi)); + size_t rdx = 3; + EXPECT_EQ(strncmpi(rdi, rdi, rdx), 0); + EXPECT_LT(strncmpi(rdi, rsi, rdx), 0); + EXPECT_GT(strncmpi(rsi, rdi, rdx), 0); + tfree(rsi); + tfree(rdi); +} + +TEST(strncasecmp, testStringNulTerminatesBeforeExplicitLength) { + const char kRdi[] = ""; + const char kRsi[] = "TZ=America/Los_Angeles"; + char *rdi = memcpy(tmalloc(sizeof(kRdi)), kRdi, sizeof(kRdi)); + char *rsi = memcpy(tmalloc(sizeof(kRsi)), kRsi, sizeof(kRsi)); + size_t rdx = 3; + EXPECT_EQ(strncasecmp(rdi, rdi, rdx), 0); + EXPECT_LT(strncasecmp(rdi, rsi, rdx), 0); + EXPECT_GT(strncasecmp(rsi, rdi, rdx), 0); + tfree(rsi); + tfree(rdi); +} + +TEST(strncmp16, testStringNulTerminatesBeforeExplicitLength) { + const char16_t kRdi[] = u""; + const char16_t kRsi[] = u"TZ=America/Los_Angeles"; + char16_t *rdi = memcpy(tmalloc(sizeof(kRdi)), kRdi, sizeof(kRdi)); + char16_t *rsi = memcpy(tmalloc(sizeof(kRsi)), kRsi, sizeof(kRsi)); + size_t rdx = 3; + EXPECT_EQ(strncmp16(rdi, rdi, rdx), 0); + EXPECT_LT(strncmp16(rdi, rsi, rdx), 0); + EXPECT_GT(strncmp16(rsi, rdi, rdx), 0); + tfree(rsi); + tfree(rdi); +} + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ test/libc/str/strcmp_test.c § two's complement bane ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +TEST(strcmp, testTwosComplementBane_hasUnsignedBehavior) { + EXPECT_EQ(strcmpi("\200", "\200"), 0); + EXPECT_LT(strcmpi("\x7f", "\x80"), 0); + EXPECT_GT(strcmpi("\x80", "\x7f"), 0); +} + +TEST(strcasecmp, testTwosComplementBane_hasUnsignedBehavior) { + EXPECT_EQ(strcasecmp("\200", "\200"), 0); + EXPECT_LT(strcasecmp("\x7f", "\x80"), 0); + EXPECT_GT(strcasecmp("\x80", "\x7f"), 0); +} + +TEST(memcmp, testTwosComplementBane_unsignedBehavior) { + EXPECT_EQ(memcmpi("\200", "\200", 1), 0); + EXPECT_LT(memcmpi("\177", "\200", 1), 0); + EXPECT_GT(memcmpi("\200", "\177", 1), 0); + EXPECT_EQ(memcmpi("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\200", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\200", 34), + 0); + EXPECT_LT(memcmpi("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\177", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\200", 34), + 0); + EXPECT_GT(memcmpi("aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\200", + "aaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaa\177", 34), + 0); +} + +TEST(strcmp16, testTwosComplementBane_hasUnsignedBehavior) { + char16_t *B1 = tmalloc(8); + char16_t *B2 = tmalloc(8); + B1[1] = L'\0'; + B2[1] = L'\0'; + EXPECT_EQ(strcmp16(memcpy(B1, "\x00\x80", 2), memcpy(B2, "\x00\x80", 2)), 0); + EXPECT_LT(strcmp16(memcpy(B1, "\xff\x7f", 2), memcpy(B2, "\x00\x80", 2)), 0); + EXPECT_GT(strcmp16(memcpy(B1, "\x00\x80", 2), memcpy(B2, "\xff\x7f", 2)), 0); + tfree(B2); + tfree(B1); +} + +TEST(strncmp16, testTwosComplementBane_hasUnsignedBehavior) { + char16_t *B1 = tmalloc(4); + char16_t *B2 = tmalloc(4); + EXPECT_EQ(strncmp16(memcpy(B1, "\x00\x80", 2), memcpy(B2, "\x00\x80", 2), 1), + 0); + EXPECT_LT(strncmp16(memcpy(B1, "\xff\x7f", 2), memcpy(B2, "\x00\x80", 2), 1), + 0); + EXPECT_GT(strncmp16(memcpy(B1, "\x00\x80", 2), memcpy(B2, "\xff\x7f", 2), 1), + 0); + tfree(B2); + tfree(B1); +} + +TEST(wcscmp, testTwosComplementBane_hasSignedBehavior) { + wchar_t *B1 = tmalloc(8); + wchar_t *B2 = tmalloc(8); + B1[1] = L'\0'; + B2[1] = L'\0'; + EXPECT_EQ(wcscmp(memcpy(B1, "\x00\x00\x00\x80", 4), + memcpy(B2, "\x00\x00\x00\x80", 4)), + 0); + EXPECT_GT(wcscmp(memcpy(B1, "\xff\xff\xff\x7f", 4), + memcpy(B2, "\x00\x00\x00\x80", 4)), + 0); + EXPECT_LT(wcscmp(memcpy(B1, "\x00\x00\x00\x80", 4), + memcpy(B2, "\xff\xff\xff\x7f", 4)), + 0); + tfree(B2); + tfree(B1); +} + +TEST(wcsncmp, testTwosComplementBane_hasSignedBehavior) { + wchar_t *B1 = tmalloc(4); + wchar_t *B2 = tmalloc(4); + EXPECT_EQ(wcsncmp(memcpy(B1, "\x00\x00\x00\x80", 4), + memcpy(B2, "\x00\x00\x00\x80", 4), 1), + 0); + EXPECT_GT(wcsncmp(memcpy(B1, "\xff\xff\xff\x7f", 4), + memcpy(B2, "\x00\x00\x00\x80", 4), 1), + 0); + EXPECT_LT(wcsncmp(memcpy(B1, "\x00\x00\x00\x80", 4), + memcpy(B2, "\xff\xff\xff\x7f", 4), 1), + 0); + tfree(B2); + tfree(B1); +} + +/*───────────────────────────────────────────────────────────────────────────│─╗ +│ test/libc/str/strcmp_test.c § benchmarks ─╬─│┼ +╚────────────────────────────────────────────────────────────────────────────│*/ + +testonly noinline int strcmp$pure(const char *a, const char *b) { + for (; *a == *b; a++, b++) { + if (!*a) break; + } + return (*a & 0xff) - (*b & 0xff); +} + +testonly noinline int strcasecmp$pure(const char *a, const char *b) { + for (; *a && *b; a++, b++) { + if (!(*a == *b || tolower(*a & 0xff) == tolower(*b & 0xff))) { + break; + } + } + return tolower(*a & 0xff) - tolower(*b & 0xff); +} + +char *randomize_buf2str(size_t size, char data[size]) { + rngset(data, size, rand64, -1); + data[size - 1] = '\0'; + return data; +} + +char *longstringislong(size_t size, char data[size]) { + unsigned i; + randomize_buf2str(size, data); + for (i = 0; i < size; ++i) { + data[i] |= 1u << (i & 5); + } + data[size - 1] = '\0'; + return data; +} + +void randomize_buf2str_dupe(size_t size, char data[size], char dupe[size]) { + randomize_buf2str(size, data); + memcpy(dupe, data, size); +} + +void longstringislong_dupe(size_t size, char data[size], char dupe[size]) { + longstringislong(size, data); + memcpy(dupe, data, size); +} + +BENCH(bench_00_strcmp, bench) { + size_t size; + char *dupe, *data; + size = ROUNDDOWN(getcachesize(kCpuCacheTypeData, 1) / 2, PAGESIZE); + data = tgc(tmalloc(size)); + dupe = tgc(tmalloc(size)); + EZBENCH2("strcmp [identity]", longstringislong(size, data), + EXPROPRIATE(strcmp(VEIL("r", data), data))); + EZBENCH2("strcmp [short dupe]", randomize_buf2str_dupe(size, data, dupe), + EXPROPRIATE(strcmp(VEIL("r", data), VEIL("r", dupe)))); + EZBENCH2("strcmp$pure [short dupe]", randomize_buf2str_dupe(size, data, dupe), + EXPROPRIATE(strcmp$pure(VEIL("r", data), VEIL("r", dupe)))); + EZBENCH2("strcmp [long dupe]", longstringislong_dupe(size, data, dupe), + EXPROPRIATE(strcmp(VEIL("r", data), VEIL("r", dupe)))); + EZBENCH2("strcmp$pure [long dupe]", longstringislong_dupe(size, data, dupe), + EXPROPRIATE(strcmp$pure(VEIL("r", data), VEIL("r", dupe)))); +} + +BENCH(bench_01_strcasecmp, bench) { + size_t size; + char *dupe, *data; + size = ROUNDDOWN(getcachesize(kCpuCacheTypeData, 1) / 2, PAGESIZE); + data = tgc(tmalloc(size)); + dupe = tgc(tmalloc(size)); + EZBENCH2("strcasecmp [identity]", longstringislong(size, data), + EXPROPRIATE(strcasecmp(VEIL("r", data), data))); + EZBENCH2("strcasecmp [short dupe]", randomize_buf2str_dupe(size, data, dupe), + EXPROPRIATE(strcasecmp(VEIL("r", data), VEIL("r", dupe)))); + EZBENCH2("strcasecmp$pure [short dupe]", + randomize_buf2str_dupe(size, data, dupe), + EXPROPRIATE(strcasecmp$pure(VEIL("r", data), VEIL("r", dupe)))); + EZBENCH2("strcasecmp [long dupe]", longstringislong_dupe(size, data, dupe), + EXPROPRIATE(strcasecmp(VEIL("r", data), VEIL("r", dupe)))); + EZBENCH2("strcasecmp$pure [long dupe]", + longstringislong_dupe(size, data, dupe), + EXPROPRIATE(strcasecmp$pure(VEIL("r", data), VEIL("r", dupe)))); +} diff --git a/test/libc/str/strlen_test.c b/test/libc/str/strlen_test.c new file mode 100644 index 00000000..7199b799 --- /dev/null +++ b/test/libc/str/strlen_test.c @@ -0,0 +1,131 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/macros.h" +#include "libc/nexgen32e/tinystrlen.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +char u8[] = "utf-8 ☻"; +char16_t u16[] = u"utf16 ☻"; +wchar_t u32[] = L"utf32 ☻"; + +TEST(strlen, usageExample_c11) { + EXPECT_EQ(6 + 3, strlen(u8)); + EXPECT_EQ(7, strlen(u16)); + EXPECT_EQ(7, strlen(u32)); +} + +TEST(strlen, usageExample_c99) { + EXPECT_EQ(6 + 3, strlen(u8)); + EXPECT_EQ(7, strlen16(u16)); + EXPECT_EQ(7, wcslen(u32)); +} + +TEST(strlen, whatMemoryLooksLike) { + EXPECT_BINEQ(u"utf-8 Γÿ╗ ", u8); /* ← thompson-pike encoded */ + EXPECT_BINEQ(u"u t f 1 6   ;&  ", u16); + EXPECT_BINEQ(u"u   t   f   3   2       ;&      ", u32); +} + +TEST(strlen, test_const) { + const char buf[] = "hellothere"; + ASSERT_EQ(0, strlen("")); + ASSERT_EQ(0, strnlen("e", 0)); + ASSERT_EQ(10, strlen(buf)); +} + +TEST(strlen, test_nonconst) { + char buf[256]; + unsigned i; + for (i = 0; i < 255; ++i) buf[i] = i + 1; + buf[i] = '\0'; + ASSERT_EQ(255, strlen(buf)); +} + +TEST(strnlen, testconst) { + ASSERT_EQ(0, strnlen_s(NULL, 3)); + ASSERT_EQ(0, strnlen("", 3)); + ASSERT_EQ(0, strnlen("a", 0)); + ASSERT_EQ(3, strnlen("123", 3)); + ASSERT_EQ(2, strnlen("123", 2)); + ASSERT_EQ(3, strnlen("123", 4)); +} + +TEST(strlen, testnonconst) { + char buf[256]; + unsigned i; + for (i = 0; i < 255; ++i) buf[i] = i + 1; + buf[i] = '\0'; + ASSERT_EQ(255, strlen(buf)); +} + +TEST(strnlen_s, null_ReturnsZero) { + ASSERT_EQ(0, strnlen_s(NULL, 3)); +} + +TEST(strnlen, nulNotFound_ReturnsSize) { + int sizes[] = {1, 2, 7, 8, 15, 16, 31, 32, 33}; + for (unsigned i = 0; i < ARRAYLEN(sizes); ++i) { + char *buf = tmalloc(sizes[i]); + memset(buf, ' ', sizes[i]); + ASSERT_EQ(sizes[i], strnlen(buf, sizes[i])); + tfree(buf); + } +} + +TEST(strnlen_s, nulNotFound_ReturnsZero) { + char buf[3] = {1, 2, 3}; + ASSERT_EQ(0, strnlen_s(buf, 3)); +} + +TEST(tinystrlen, test) { + ASSERT_EQ(0, tinystrlen("")); + ASSERT_EQ(1, tinystrlen("a")); + ASSERT_EQ(3, tinystrlen("123")); +} + +TEST(tinywcslen, test) { + ASSERT_EQ(0, tinywcslen(L"")); + ASSERT_EQ(1, tinywcslen(L"a")); + ASSERT_EQ(3, tinywcslen(L"123")); +} + +TEST(tinywcsnlen, test) { + EXPECT_EQ(0, tinywcsnlen(L"", 3)); + EXPECT_EQ(0, tinywcsnlen(L"a", 0)); + EXPECT_EQ(3, tinywcsnlen(L"123", 3)); + EXPECT_EQ(2, tinywcsnlen(L"123", 2)); + EXPECT_EQ(3, tinywcsnlen(L"123", 4)); +} + +TEST(tinystrlen16, test) { + ASSERT_EQ(0, tinystrlen16(u"")); + ASSERT_EQ(1, tinystrlen16(u"a")); + ASSERT_EQ(3, tinystrlen16(u"123")); +} + +TEST(tinystrnlen16, test) { + EXPECT_EQ(0, tinystrnlen16(u"", 3)); + EXPECT_EQ(0, tinystrnlen16(u"a", 0)); + EXPECT_EQ(3, tinystrnlen16(u"123", 3)); + EXPECT_EQ(2, tinystrnlen16(u"123", 2)); + EXPECT_EQ(3, tinystrnlen16(u"123", 4)); +} diff --git a/test/libc/str/strrchr_test.c b/test/libc/str/strrchr_test.c new file mode 100644 index 00000000..44dd5bbe --- /dev/null +++ b/test/libc/str/strrchr_test.c @@ -0,0 +1,45 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +#define T(NAME) NAME +#define S(S) S +#define C(C) C +#include "test/libc/str/strrchr_test.inc" +#undef C +#undef S +#undef T + +#define T(NAME) NAME##16 +#define S(S) u##S +#define C(C) u##C +#include "test/libc/str/strrchr_test.inc" +#undef C +#undef S +#undef T + +#define T(NAME) NAME##32 +#define S(S) L##S +#define C(C) L##C +#include "test/libc/str/strrchr_test.inc" +#undef C +#undef S +#undef T diff --git a/test/libc/str/strrchr_test.inc b/test/libc/str/strrchr_test.inc new file mode 100644 index 00000000..87f7da6c --- /dev/null +++ b/test/libc/str/strrchr_test.inc @@ -0,0 +1,47 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ + +TEST(T(strrchr), test) { + EXPECT_EQ(NULL, strrchr(S("hello"), C('z'))); + EXPECT_STREQ(S("lo"), strrchr(S("hello"), C('l'))); + EXPECT_STREQ(S("llo"), strchr(S("hello"), C('l'))); + EXPECT_STREQ(S("hello"), strrchr(S("hello"), C('h'))); + EXPECT_STREQ(S("ello"), strrchr(S("hello"), C('e'))); + EXPECT_STREQ(S("o"), strrchr(S("hello"), C('o'))); +} + +TEST(T(strrchr), simdVectorStuffIsntBroken) { + EXPECT_EQ(NULL, strrchr(S("--------------------------------"), C('x'))); + EXPECT_STREQ(S("x"), strrchr(S("-------------------------------x"), C('x'))); + EXPECT_STREQ(S("x-------------------------------"), + strrchr(S("x-------------------------------"), C('x'))); + EXPECT_STREQ(S("x") S("z-------------------------------"), + strrchr(S("x") S("z-------------------------------"), C('x'))); + EXPECT_STREQ(S("x-------------------------------") + S("y-------------------------------"), + strrchr(S("x-------------------------------") + S("y-------------------------------"), + C('x'))); + EXPECT_STREQ(S("x") S("z-------------------------------") + S("y-------------------------------"), + strrchr(S("x") S("z-------------------------------") + S("y-------------------------------"), + C('x'))); +} diff --git a/test/libc/str/strtok_r_test.c b/test/libc/str/strtok_r_test.c new file mode 100644 index 00000000..a54bb714 --- /dev/null +++ b/test/libc/str/strtok_r_test.c @@ -0,0 +1,65 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(strtok_r, testEmpty) { + static const char *const kInput = ""; + static const char *const kSeparators = "/"; + char *s = strcpy(tmalloc(strlen(kInput) + 1), kInput); + char *state; + EXPECT_EQ(NULL, strtok_r(s, kSeparators, &state)); + tfree(s); +} + +TEST(strtok_r, test) { + static const char *const kInput = ".,lol..cat.."; + static const char *const kSeparators = ".,"; + char *s = strcpy(tmalloc(strlen(kInput) + 1), kInput); + char *state; + EXPECT_STREQ("lol", strtok_r(s, kSeparators, &state)); + EXPECT_STREQ("cat", strtok_r(NULL, kSeparators, &state)); + EXPECT_EQ(NULL, strtok_r(NULL, kSeparators, &state)); + EXPECT_EQ(NULL, strtok_r(NULL, kSeparators, &state)); + tfree(s); +} + +TEST(strtok, test) { + static const char *const kInput = ".,lol..cat.."; + static const char *const kSeparators = ".,"; + char *s = strcpy(tmalloc(strlen(kInput) + 1), kInput); + EXPECT_STREQ("lol", strtok(s, kSeparators)); + EXPECT_STREQ("cat", strtok(NULL, kSeparators)); + EXPECT_EQ(NULL, strtok(NULL, kSeparators)); + EXPECT_EQ(NULL, strtok(NULL, kSeparators)); + tfree(s); +} + +TEST(strtok_r, testHostsTxtLine) { + static const char *const kInput = "203.0.113.1 lol.example. lol"; + static const char *const kSeparators = " \t"; + char *s = strcpy(tmalloc(strlen(kInput) + 1), kInput); + char *state; + EXPECT_STREQ("203.0.113.1", strtok_r(s, kSeparators, &state)); + EXPECT_STREQ("lol.example.", strtok_r(NULL, kSeparators, &state)); + EXPECT_STREQ("lol", strtok_r(NULL, kSeparators, &state)); + EXPECT_EQ(NULL, strtok_r(NULL, kSeparators, &state)); + tfree(s); +} diff --git a/test/libc/str/strtolower_test.c b/test/libc/str/strtolower_test.c new file mode 100644 index 00000000..95d057dd --- /dev/null +++ b/test/libc/str/strtolower_test.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(strntolower, test) { + char s[128] = "ABCD"; + strntolower(s, -1); + EXPECT_STREQ("abcd", s); +} + +TEST(strntolower, testLong) { + char s[128] = "ABCDabcdABCDabcdABCDabcdABCDabcdABCDabcd"; + strntolower(s, -1); + EXPECT_STREQ("abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", s); +} diff --git a/test/libc/str/test.mk b/test/libc/str/test.mk new file mode 100644 index 00000000..2bf473db --- /dev/null +++ b/test/libc/str/test.mk @@ -0,0 +1,70 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_STR + +TEST_LIBC_STR_SRCS := $(wildcard test/libc/str/*.c) +TEST_LIBC_STR_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_STR_SRCS)) +TEST_LIBC_STR_COMS = $(TEST_LIBC_STR_OBJS:%.o=%.com) + +TEST_LIBC_STR_OBJS = \ + $(TEST_LIBC_STR_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_STR_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_STR_BINS = \ + $(TEST_LIBC_STR_COMS) \ + $(TEST_LIBC_STR_COMS:%=%.dbg) + +TEST_LIBC_STR_TESTS = \ + $(TEST_LIBC_STR_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_STR_CHECKS = \ + $(TEST_LIBC_STR_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_STR_DIRECTDEPS = \ + LIBC_CALLS_HEFTY \ + LIBC_FMT \ + LIBC_NEXGEN32E \ + LIBC_STDIO \ + LIBC_MEM \ + LIBC_RUNTIME \ + LIBC_STR \ + LIBC_RAND \ + LIBC_UNICODE \ + LIBC_CALLS \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_TESTLIB \ + LIBC_LOG \ + LIBC_X \ + LIBC_ZIPOS \ + THIRD_PARTY_ZLIB + +TEST_LIBC_STR_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_STR_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/str/str.pkg: \ + $(TEST_LIBC_STR_OBJS) \ + $(foreach x,$(TEST_LIBC_STR_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/str/tpenc_test.o: \ + OVERRIDE_CFLAGS += \ + $(TRADITIONAL) + +o/$(MODE)/test/libc/str/%.com.dbg: \ + $(TEST_LIBC_STR_DEPS) \ + o/$(MODE)/test/libc/str/%.o \ + o/$(MODE)/test/libc/str/str.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +$(TEST_LIBC_STR_OBJS): \ + DEFAULT_CCFLAGS += \ + -fno-builtin + +.PHONY: o/$(MODE)/test/libc/str +o/$(MODE)/test/libc/str: \ + $(TEST_LIBC_STR_BINS) \ + $(TEST_LIBC_STR_CHECKS) diff --git a/test/libc/str/tpdecode_test.c b/test/libc/str/tpdecode_test.c new file mode 100644 index 00000000..4c0e51d0 --- /dev/null +++ b/test/libc/str/tpdecode_test.c @@ -0,0 +1,80 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/progn.h" +#include "libc/bits/safemacros.h" +#include "libc/errno.h" +#include "libc/fmt/bing.h" +#include "libc/limits.h" +#include "libc/runtime/gc.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +wint_t wc; + +TEST(tpdecode, testGlyph) { + EXPECT_EQ(u'→', PROGN(ASSERT_EQ(3, tpdecode("→", &wc)), wc)); + EXPECT_EQ(L'𐌰', PROGN(ASSERT_EQ(4, tpdecode("𐌰𐌱𐌲𐌳", &wc)), wc)); + EXPECT_EQ(u'ち', PROGN(ASSERT_EQ(3, tpdecode("ち", &wc)), wc)); + EXPECT_EQ(u'‱', PROGN(ASSERT_EQ(3, tpdecode("‱", &wc)), wc)); +} + +TEST(tpdecode, testNul_canonicalizesWithFiniteOverlongConsumption) { + EXPECT_EQ('\0', PROGN(ASSERT_EQ(1, tpdecode("\0\0\0\0", &wc)), wc)); + EXPECT_EQ('\0', + PROGN(ASSERT_EQ(2, tpdecode(gc(unbingstr(u"└ÇÇÇÇÇ")), &wc)), wc)); + EXPECT_EQ('\0', + PROGN(ASSERT_EQ(3, tpdecode(gc(unbingstr(u"αÇÇÇÇÇ")), &wc)), wc)); + EXPECT_EQ('\0', + PROGN(ASSERT_EQ(4, tpdecode(gc(unbingstr(u"≡ÇÇÇÇÇ")), &wc)), wc)); + EXPECT_EQ('\0', + PROGN(ASSERT_EQ(5, tpdecode(gc(unbingstr(u"°ÇÇÇÇÇ")), &wc)), wc)); + EXPECT_EQ('\0', + PROGN(ASSERT_EQ(6, tpdecode(gc(unbingstr(u"ⁿÇÇÇÇÇ")), &wc)), wc)); +} + +TEST(tpdecode, testSynchronization_skipsLeadingContinuations) { + EXPECT_EQ('a', + PROGN(EXPECT_EQ(7, tpdecode(gc(unbingstr(u"Ç╗╝╜╛┐a")), &wc)), wc)); +} + +TEST(tpdecode, testSpace) { + EXPECT_EQ(0x20, PROGN(ASSERT_EQ(1, tpdecode(" ", &wc)), wc)); +} + +TEST(tpdecode, testNegativeNumbers) { + EXPECT_EQ(-1, PROGN(ASSERT_EQ(6, tpdecode(gc(unbingstr(u"λ┐┐┐┐┐")), &wc)), + (wchar_t)wc)); + EXPECT_EQ(INT_MIN, + PROGN(ASSERT_EQ(6, tpdecode(gc(unbingstr(u"■ÇÇÇÇÇ")), &wc)), + (wchar_t)wc)); + EXPECT_EQ(0x80000000u, + PROGN(ASSERT_EQ(6, tpdecode(gc(unbingstr(u"■ÇÇÇÇÇ")), &wc)), wc)); + EXPECT_EQ(0xC0000000u, + PROGN(ASSERT_EQ(6, tpdecode(gc(unbingstr(u"λÇÇÇÇÇ")), &wc)), wc)); +} + +TEST(tpdecode, testInvalidEncoding_endOfString) { + EXPECT_EQ(u'�', PROGN(EXPECT_EQ(-1, tpdecode(gc(unbingstr(u"≡")), &wc)), wc)); +} + +TEST(tpdecode, testInvalidEncoding_tooFewContinuations) { + EXPECT_EQ(u'�', PROGN(EXPECT_EQ(-1, tpdecode(gc(unbingstr(u"≡")), &wc)), wc)); +} diff --git a/test/libc/str/tpenc_test.c b/test/libc/str/tpenc_test.c new file mode 100644 index 00000000..64f2fff9 --- /dev/null +++ b/test/libc/str/tpenc_test.c @@ -0,0 +1,52 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/limits.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/str/tpenc.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" + +STATIC_YOINK("strwidth"); + +volatile uint64_t v; + +TEST(tpenc, test) { + EXPECT_EQ(0, tpenc(0)); + EXPECT_EQ(1, tpenc(1)); + EXPECT_EQ(' ', tpenc(' ')); + EXPECT_EQ(0x7f, tpenc(0x7f)); + EXPECT_EQ(0x008496E2, tpenc(L'▄')); + EXPECT_EQ(0x8080808080FEul, tpenc(INT_MIN)); +} + +uint64_t Tpenc(int x) { + return (v = tpenc(x)); +} + +BENCH(tpenc, bench) { + EZBENCH(donothing, Tpenc(0)); + EZBENCH(donothing, Tpenc(1)); + EZBENCH(donothing, Tpenc(' ')); + EZBENCH(donothing, Tpenc(0x7f)); + EZBENCH(donothing, Tpenc(L'▄')); + EZBENCH(donothing, Tpenc(INT_MIN)); + fprintf(stderr, "\n"); +} diff --git a/test/libc/str/tpencode_test.c b/test/libc/str/tpencode_test.c new file mode 100644 index 00000000..0aa2afa6 --- /dev/null +++ b/test/libc/str/tpencode_test.c @@ -0,0 +1,61 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/bits/progn.h" +#include "libc/bits/safemacros.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +char buf[8]; + +TEST(tpencode, testNul) { + ASSERT_BINEQ(u" ", PROGN(ASSERT_EQ(1, tpencode(buf, 8, 0, false)), buf)); + ASSERT_BINEQ(u" ", PROGN(ASSERT_EQ(1, (tpencode)(buf, 8, 0, false)), buf)); +} + +TEST(tpencode, testSpace) { + ASSERT_BINEQ(u" ", PROGN(ASSERT_EQ(1, tpencode(buf, 8, 0x20, false)), buf)); + ASSERT_BINEQ(u" ", PROGN(ASSERT_EQ(1, (tpencode)(buf, 8, 0x20, false)), buf)); +} + +TEST(tpencode, testGlyph) { + ASSERT_BINEQ(u"ΓåÆ", PROGN(ASSERT_EQ(3, tpencode(buf, 8, u'→', false)), buf)); + ASSERT_BINEQ(u"ΓåÆ", + PROGN(ASSERT_EQ(3, (tpencode)(buf, 8, u'→', false)), buf)); +} + +TEST(tpencode, testMathematicalNotMuhPolicyDrivenBehavior_negativeOne) { + ASSERT_BINEQ(u"λ┐┐┐┐┐", + PROGN(ASSERT_EQ(6, tpencode(buf, 8, -1, false)), buf)); + ASSERT_BINEQ(u"λ┐┐┐┐┐", + PROGN(ASSERT_EQ(6, (tpencode)(buf, 8, -1, false)), buf)); +} + +TEST(tpencode, testMathematicalNotMuhPolicyDrivenBehavior_twosComplementBane) { + ASSERT_BINEQ(u"■ÇÇÇÇÇ", + PROGN(ASSERT_EQ(6, tpencode(buf, 8, 0x80000000, false)), buf)); + ASSERT_BINEQ(u"■ÇÇÇÇÇ", + PROGN(ASSERT_EQ(6, (tpencode)(buf, 8, 0x80000000, false)), buf)); +} + +TEST(tpencode, testMathematicalNotMuhPolicyDrivenBehavior_nonCanonicalNul) { + ASSERT_BINEQ(u"└Ç", PROGN(ASSERT_EQ(2, tpencode(buf, 8, 0, true)), buf)); + ASSERT_BINEQ(u"└Ç", PROGN(ASSERT_EQ(2, (tpencode)(buf, 8, 0, true)), buf)); +} diff --git a/test/libc/str/tprecode8to16_test.c b/test/libc/str/tprecode8to16_test.c new file mode 100644 index 00000000..208dc170 --- /dev/null +++ b/test/libc/str/tprecode8to16_test.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" + +TEST(tprecode8to16, test) { + size_t size = 8; + char16_t *buf = tmalloc(size * sizeof(char16_t)); + EXPECT_EQ(7, tprecode8to16(buf, size, "hello☻♥")); + EXPECT_STREQ(u"hello☻♥", buf); + tfree(buf); +} diff --git a/test/libc/str/undeflate_test.c b/test/libc/str/undeflate_test.c new file mode 100644 index 00000000..d84bf042 --- /dev/null +++ b/test/libc/str/undeflate_test.c @@ -0,0 +1,166 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/struct/stat.h" +#include "libc/errno.h" +#include "libc/log/check.h" +#include "libc/macros.h" +#include "libc/mem/mem.h" +#include "libc/runtime/gc.h" +#include "libc/runtime/rbx.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/symbols.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/str/undeflate.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/prot.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/hyperion.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" +#include "libc/zip.h" +#include "third_party/zlib/zlib.h" + +STATIC_YOINK("libc/testlib/hyperion.txt"); + +TEST(undeflate, testEmbeddedPlaintextConstant) { + EXPECT_STARTSWITH("The fall of Hyperion - a Dream", kHyperion); +} + +TEST(undeflate, testStatCentralDirectory_notFound_noSysCalls) { + uint64_t c; + struct stat st; + c = g_syscount; + ASSERT_EQ(-1, stat("zip:doge.txt", &st)); + ASSERT_EQ(0, g_syscount - c); + ASSERT_EQ(ENOENT, errno); +} + +TEST(undeflate, testStatCentralDirectory_isFound_noSysCalls) { + uint64_t c; + struct stat st = {0}; + c = g_syscount; + ASSERT_NE(-1, stat("zip:libc/testlib/hyperion.txt", &st)); + ASSERT_TRUE(S_ISREG(st.st_mode)); + ASSERT_EQ(kHyperionSize, st.st_size); + ASSERT_EQ(0, g_syscount - c); +} + +TEST(undeflate, testOpenReadCloseEmbeddedZip) { + int fd; + char *data; + ASSERT_NE(-1, (fd = open("zip:libc/testlib/hyperion.txt", O_RDONLY))); + ASSERT_NE(NULL, (data = gc(malloc(kHyperionSize)))); + ASSERT_EQ(kHyperionSize, read(fd, data, kHyperionSize)); + EXPECT_EQ(0, memcmp(kHyperion, data, kHyperionSize)); + EXPECT_NE(-1, close(fd)); +} + +TEST(undeflate, testEmbeddedCompressedZipFile_theHardWay) { + int fd; + size_t i; + bool found; + struct stat st; + struct DeflateState ds; + uint8_t *map, *cd, *cf, *lf, *data; + found = false; + ASSERT_NE(-1, (fd = open(findcombinary(), O_RDONLY))); + ASSERT_NE(-1, fstat(fd, &st)); + ASSERT_NE(MAP_FAILED, + (map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0))); + ASSERT_NE(NULL, (cd = zipfindcentraldir(map, st.st_size))); + ASSERT_GE(ZIP_CDIR_RECORDS(cd), 1); + for (i = 0, cf = map + ZIP_CDIR_OFFSET(cd); i < ZIP_CDIR_RECORDS(cd); + ++i, cf += ZIP_CFILE_HDRSIZE(cf)) { + if (strncmp("libc/testlib/hyperion.txt", ZIP_CFILE_NAME(cf), + ZIP_CFILE_NAMESIZE(cf)) == 0) { + lf = map + ZIP_CFILE_OFFSET(cf); + ASSERT_EQ(kZipCompressionDeflate, ZIP_LFILE_COMPRESSIONMETHOD(lf)); + ASSERT_EQ(kHyperionSize, ZIP_LFILE_UNCOMPRESSEDSIZE(lf)); + undeflate((data = gc(xmalloc(ZIP_LFILE_UNCOMPRESSEDSIZE(lf) * 24))), + ZIP_LFILE_UNCOMPRESSEDSIZE(lf), ZIP_LFILE_CONTENT(lf), + ZIP_LFILE_COMPRESSEDSIZE(lf), &ds); + ASSERT_EQ(ZIP_LFILE_CRC32(lf), + crc32_z(0, data, ZIP_LFILE_UNCOMPRESSEDSIZE(lf))); + ASSERT_EQ(0, memcmp(kHyperion, data, ZIP_LFILE_UNCOMPRESSEDSIZE(lf))); + found = true; + break; + } + } + ASSERT_NE(-1, munmap(map, st.st_size)); + ASSERT_NE(-1, close(fd)); + ASSERT_TRUE(found); +} + +//////////////////////////////////////////////////////////////////////////////// + +uint8_t *buf_; +size_t bufsize_; +uint8_t *data_; +size_t compressedsize_; +size_t uncompressedsize_; +struct DeflateState ds_; + +void Inflate(void) { + z_stream stream; + stream.next_in = data_; + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.avail_in = compressedsize_; + stream.total_in = compressedsize_; + stream.next_out = buf_; + stream.avail_out = bufsize_; + stream.total_out = bufsize_; + CHECK_EQ(Z_OK, inflateInit2(&stream, -MAX_WBITS)); + CHECK_NE(Z_BUF_ERROR, inflate(&stream, Z_NO_FLUSH)); + CHECK_EQ(Z_OK, inflateEnd(&stream)); +} + +void Undeflate(void) { + undeflate(buf_, uncompressedsize_, data_, compressedsize_, &ds_); +} + +static size_t GetLocalFile(const char *name) { + size_t i, cf, namesize; + namesize = strlen(name); + for (i = 0, cf = ZIP_CDIR_OFFSET(__zip_end); i < ZIP_CDIR_RECORDS(__zip_end); + ++i, cf += ZIP_CFILE_HDRSIZE(cf)) { + if (namesize == ZIP_CFILE_NAMESIZE(&_base[0] + cf) && + memcmp(name, ZIP_CFILE_NAME(&_base[0] + cf), namesize) == 0) { + return ZIP_CFILE_OFFSET(&_base[0] + cf); + } + } + abort(); +} + +BENCH(undeflate, bench) { + size_t lf; + lf = GetLocalFile("libc/testlib/hyperion.txt"); + data_ = ZIP_LFILE_CONTENT(&_base[0] + lf); + compressedsize_ = ZIP_LFILE_COMPRESSEDSIZE(&_base[0] + lf); + uncompressedsize_ = ZIP_LFILE_UNCOMPRESSEDSIZE(&_base[0] + lf); + bufsize_ = ROUNDUP(uncompressedsize_, FRAMESIZE / 2); + buf_ = gc(malloc(bufsize_)); + EZBENCH(donothing, Inflate()); + EZBENCH(donothing, Undeflate()); +} diff --git a/test/libc/str/varint_test.c b/test/libc/str/varint_test.c new file mode 100644 index 00000000..d5c41bc2 --- /dev/null +++ b/test/libc/str/varint_test.c @@ -0,0 +1,301 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/fmt/bing.h" +#include "libc/limits.h" +#include "libc/macros.h" +#include "libc/runtime/gc.h" +#include "libc/str/str.h" +#include "libc/str/varint.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +#define TV(X, B, I) __FILE__, __LINE__, #X, X, #B, B, #I, I + +static const struct VarintTestVectors { + const char *file; + int line; + const char *xcode; + uint64_t x; + const char *bcode; + uint16_t b[11]; + const char *icode; + uint8_t i; +} kv[] = { + {TV(0x0000000000000000ul, u"          ", 1)}, + {TV(0x0000000000000001ul, u"☺         ", 1)}, + {TV(0x0000000000000003ul, u"♥         ", 1)}, + {TV(0x0000000000000007ul, u"•         ", 1)}, + {TV(0x000000000000000ful, u"☼         ", 1)}, + {TV(0x000000000000001ful, u"▼         ", 1)}, + {TV(0x000000000000003ful, u"⁇         ", 1)}, + {TV(0x000000000000007ful, u"⌂         ", 1)}, + {TV(0x00000000000000fful, u"λ☺        ", 2)}, + {TV(0x00000000000001fful, u"λ♥        ", 2)}, + {TV(0x00000000000003fful, u"λ•        ", 2)}, + {TV(0x00000000000007fful, u"λ☼        ", 2)}, + {TV(0x0000000000000ffful, u"λ▼        ", 2)}, + {TV(0x0000000000001ffful, u"λ⁇        ", 2)}, + {TV(0x0000000000003ffful, u"λ⌂        ", 2)}, + {TV(0x0000000000007ffful, u"λλ☺       ", 3)}, + {TV(0x000000000000fffful, u"λλ♥       ", 3)}, + {TV(0x000000000001fffful, u"λλ•       ", 3)}, + {TV(0x000000000003fffful, u"λλ☼       ", 3)}, + {TV(0x000000000007fffful, u"λλ▼       ", 3)}, + {TV(0x00000000000ffffful, u"λλ⁇       ", 3)}, + {TV(0x00000000001ffffful, u"λλ⌂       ", 3)}, + {TV(0x00000000003ffffful, u"λλλ☺      ", 4)}, + {TV(0x00000000007ffffful, u"λλλ♥      ", 4)}, + {TV(0x0000000000fffffful, u"λλλ•      ", 4)}, + {TV(0x0000000001fffffful, u"λλλ☼      ", 4)}, + {TV(0x0000000003fffffful, u"λλλ▼      ", 4)}, + {TV(0x0000000007fffffful, u"λλλ⁇      ", 4)}, + {TV(0x000000000ffffffful, u"λλλ⌂      ", 4)}, + {TV(0x000000001ffffffful, u"λλλλ☺     ", 5)}, + {TV(0x000000003ffffffful, u"λλλλ♥     ", 5)}, + {TV(0x000000007ffffffful, u"λλλλ•     ", 5)}, + {TV(0x00000000fffffffful, u"λλλλ☼     ", 5)}, + {TV(0x00000001fffffffful, u"λλλλ▼     ", 5)}, + {TV(0x00000003fffffffful, u"λλλλ⁇     ", 5)}, + {TV(0x00000007fffffffful, u"λλλλ⌂     ", 5)}, + {TV(0x0000000ffffffffful, u"λλλλλ☺    ", 6)}, + {TV(0x0000001ffffffffful, u"λλλλλ♥    ", 6)}, + {TV(0x0000003ffffffffful, u"λλλλλ•    ", 6)}, + {TV(0x0000007ffffffffful, u"λλλλλ☼    ", 6)}, + {TV(0x000000fffffffffful, u"λλλλλ▼    ", 6)}, + {TV(0x000001fffffffffful, u"λλλλλ⁇    ", 6)}, + {TV(0x000003fffffffffful, u"λλλλλ⌂    ", 6)}, + {TV(0x000007fffffffffful, u"λλλλλλ☺   ", 7)}, + {TV(0x00000ffffffffffful, u"λλλλλλ♥   ", 7)}, + {TV(0x00001ffffffffffful, u"λλλλλλ•   ", 7)}, + {TV(0x00003ffffffffffful, u"λλλλλλ☼   ", 7)}, + {TV(0x00007ffffffffffful, u"λλλλλλ▼   ", 7)}, + {TV(0x0000fffffffffffful, u"λλλλλλ⁇   ", 7)}, + {TV(0x0001fffffffffffful, u"λλλλλλ⌂   ", 7)}, + {TV(0x0003fffffffffffful, u"λλλλλλλ☺  ", 8)}, + {TV(0x0007fffffffffffful, u"λλλλλλλ♥  ", 8)}, + {TV(0x000ffffffffffffful, u"λλλλλλλ•  ", 8)}, + {TV(0x001ffffffffffffful, u"λλλλλλλ☼  ", 8)}, + {TV(0x003ffffffffffffful, u"λλλλλλλ▼  ", 8)}, + {TV(0x007ffffffffffffful, u"λλλλλλλ⁇  ", 8)}, + {TV(0x00fffffffffffffful, u"λλλλλλλ⌂  ", 8)}, + {TV(0x01fffffffffffffful, u"λλλλλλλλ☺ ", 9)}, + {TV(0x03fffffffffffffful, u"λλλλλλλλ♥ ", 9)}, + {TV(0x07fffffffffffffful, u"λλλλλλλλ• ", 9)}, + {TV(0x0ffffffffffffffful, u"λλλλλλλλ☼ ", 9)}, + {TV(0x1ffffffffffffffful, u"λλλλλλλλ▼ ", 9)}, + {TV(0x3ffffffffffffffful, u"λλλλλλλλ⁇ ", 9)}, + {TV(0x7ffffffffffffffful, u"λλλλλλλλ⌂ ", 9)}, + {TV(0xfffffffffffffffful, u"λλλλλλλλλ☺", 10)}, +}; + +const struct ZigzagTestVectors { + const char *file; + int line; + const char *xcode; + int64_t x; + const char *bcode; + uint16_t b[11]; + const char *icode; + uint8_t i; +} kz[] = { + {TV(0, u" ", 1)}, + {TV(1, u"☻", 1)}, + {TV(-1, u"☺", 1)}, + {TV(2, u"♦", 1)}, + {TV(-2, u"♥", 1)}, + {TV(4, u"◘", 1)}, + {TV(-4, u"•", 1)}, + {TV(8, u"►", 1)}, + {TV(-8, u"☼", 1)}, + {TV(16, u" ", 1)}, + {TV(-16, u"▼", 1)}, + {TV(32, u"@", 1)}, + {TV(-32, u"⁇", 1)}, + {TV(64, u"Ç☺", 2)}, + {TV(-64, u"⌂", 1)}, + {TV(128, u"Ç☻", 2)}, + {TV(-128, u"λ☺", 2)}, + {TV(256, u"Ç♦", 2)}, + {TV(-256, u"λ♥", 2)}, + {TV(512, u"Ç◘", 2)}, + {TV(-512, u"λ•", 2)}, + {TV(1024, u"Ç►", 2)}, + {TV(-1024, u"λ☼", 2)}, + {TV(2048, u"Ç ", 2)}, + {TV(-2048, u"λ▼", 2)}, + {TV(4096, u"Ç@", 2)}, + {TV(-4096, u"λ⁇", 2)}, + {TV(8192, u"ÇÇ☺", 3)}, + {TV(-8192, u"λ⌂", 2)}, + {TV(16384, u"ÇÇ☻", 3)}, + {TV(-16384, u"λλ☺", 3)}, + {TV(32768, u"ÇÇ♦", 3)}, + {TV(-32768, u"λλ♥", 3)}, + {TV(65536, u"ÇÇ◘", 3)}, + {TV(-65536, u"λλ•", 3)}, + {TV(131072, u"ÇÇ►", 3)}, + {TV(-131072, u"λλ☼", 3)}, + {TV(262144, u"ÇÇ ", 3)}, + {TV(-262144, u"λλ▼", 3)}, + {TV(524288, u"ÇÇ@", 3)}, + {TV(-524288, u"λλ⁇", 3)}, + {TV(1048576, u"ÇÇÇ☺", 4)}, + {TV(-1048576, u"λλ⌂", 3)}, + {TV(2097152, u"ÇÇÇ☻", 4)}, + {TV(-2097152, u"λλλ☺", 4)}, + {TV(4194304, u"ÇÇÇ♦", 4)}, + {TV(-4194304, u"λλλ♥", 4)}, + {TV(8388608, u"ÇÇÇ◘", 4)}, + {TV(-8388608, u"λλλ•", 4)}, + {TV(16777216, u"ÇÇÇ►", 4)}, + {TV(-16777216, u"λλλ☼", 4)}, + {TV(33554432, u"ÇÇÇ ", 4)}, + {TV(-33554432, u"λλλ▼", 4)}, + {TV(67108864, u"ÇÇÇ@", 4)}, + {TV(-67108864, u"λλλ⁇", 4)}, + {TV(134217728, u"ÇÇÇÇ☺", 5)}, + {TV(-134217728, u"λλλ⌂", 4)}, + {TV(268435456, u"ÇÇÇÇ☻", 5)}, + {TV(-268435456, u"λλλλ☺", 5)}, + {TV(536870912, u"ÇÇÇÇ♦", 5)}, + {TV(-536870912, u"λλλλ♥", 5)}, + {TV(1073741824, u"ÇÇÇÇ◘", 5)}, + {TV(-1073741824, u"λλλλ•", 5)}, + {TV(2147483648, u"ÇÇÇÇ►", 5)}, + {TV(-2147483648, u"λλλλ☼", 5)}, + {TV(4294967296, u"ÇÇÇÇ ", 5)}, + {TV(-4294967296, u"λλλλ▼", 5)}, + {TV(8589934592, u"ÇÇÇÇ@", 5)}, + {TV(-8589934592, u"λλλλ⁇", 5)}, + {TV(17179869184, u"ÇÇÇÇÇ☺", 6)}, + {TV(-17179869184, u"λλλλ⌂", 5)}, + {TV(34359738368, u"ÇÇÇÇÇ☻", 6)}, + {TV(-34359738368, u"λλλλλ☺", 6)}, + {TV(68719476736, u"ÇÇÇÇÇ♦", 6)}, + {TV(-68719476736, u"λλλλλ♥", 6)}, + {TV(137438953472, u"ÇÇÇÇÇ◘", 6)}, + {TV(-137438953472, u"λλλλλ•", 6)}, + {TV(274877906944, u"ÇÇÇÇÇ►", 6)}, + {TV(-274877906944, u"λλλλλ☼", 6)}, + {TV(549755813888, u"ÇÇÇÇÇ ", 6)}, + {TV(-549755813888, u"λλλλλ▼", 6)}, + {TV(1099511627776, u"ÇÇÇÇÇ@", 6)}, + {TV(-1099511627776, u"λλλλλ⁇", 6)}, + {TV(2199023255552, u"ÇÇÇÇÇÇ☺", 7)}, + {TV(-2199023255552, u"λλλλλ⌂", 6)}, + {TV(4398046511104, u"ÇÇÇÇÇÇ☻", 7)}, + {TV(-4398046511104, u"λλλλλλ☺", 7)}, + {TV(8796093022208, u"ÇÇÇÇÇÇ♦", 7)}, + {TV(-8796093022208, u"λλλλλλ♥", 7)}, + {TV(17592186044416, u"ÇÇÇÇÇÇ◘", 7)}, + {TV(-17592186044416, u"λλλλλλ•", 7)}, + {TV(35184372088832, u"ÇÇÇÇÇÇ►", 7)}, + {TV(-35184372088832, u"λλλλλλ☼", 7)}, + {TV(70368744177664, u"ÇÇÇÇÇÇ ", 7)}, + {TV(-70368744177664, u"λλλλλλ▼", 7)}, + {TV(140737488355328, u"ÇÇÇÇÇÇ@", 7)}, + {TV(-140737488355328, u"λλλλλλ⁇", 7)}, + {TV(281474976710656, u"ÇÇÇÇÇÇÇ☺", 8)}, + {TV(-281474976710656, u"λλλλλλ⌂", 7)}, + {TV(562949953421312, u"ÇÇÇÇÇÇÇ☻", 8)}, + {TV(-562949953421312, u"λλλλλλλ☺", 8)}, + {TV(1125899906842624, u"ÇÇÇÇÇÇÇ♦", 8)}, + {TV(-1125899906842624, u"λλλλλλλ♥", 8)}, + {TV(2251799813685248, u"ÇÇÇÇÇÇÇ◘", 8)}, + {TV(-2251799813685248, u"λλλλλλλ•", 8)}, + {TV(4503599627370496, u"ÇÇÇÇÇÇÇ►", 8)}, + {TV(-4503599627370496, u"λλλλλλλ☼", 8)}, + {TV(9007199254740992, u"ÇÇÇÇÇÇÇ ", 8)}, + {TV(-9007199254740992, u"λλλλλλλ▼", 8)}, + {TV(18014398509481984, u"ÇÇÇÇÇÇÇ@", 8)}, + {TV(-18014398509481984, u"λλλλλλλ⁇", 8)}, + {TV(36028797018963968, u"ÇÇÇÇÇÇÇÇ☺", 9)}, + {TV(-36028797018963968, u"λλλλλλλ⌂", 8)}, + {TV(72057594037927936, u"ÇÇÇÇÇÇÇÇ☻", 9)}, + {TV(-72057594037927936, u"λλλλλλλλ☺", 9)}, + {TV(144115188075855872, u"ÇÇÇÇÇÇÇÇ♦", 9)}, + {TV(-144115188075855872, u"λλλλλλλλ♥", 9)}, + {TV(288230376151711744, u"ÇÇÇÇÇÇÇÇ◘", 9)}, + {TV(-288230376151711744, u"λλλλλλλλ•", 9)}, + {TV(576460752303423488, u"ÇÇÇÇÇÇÇÇ►", 9)}, + {TV(-576460752303423488, u"λλλλλλλλ☼", 9)}, + {TV(1152921504606846976, u"ÇÇÇÇÇÇÇÇ ", 9)}, + {TV(-1152921504606846976, u"λλλλλλλλ▼", 9)}, + {TV(2305843009213693952, u"ÇÇÇÇÇÇÇÇ@", 9)}, + {TV(-2305843009213693952, u"λλλλλλλλ⁇", 9)}, + {TV(4611686018427387904, u"ÇÇÇÇÇÇÇÇÇ☺", 10)}, + {TV(-4611686018427387904, u"λλλλλλλλ⌂", 9)}, + {TV(INT64_MIN, u"λλλλλλλλλ☺", 10)}, + {TV(INT64_MAX, u"■λλλλλλλλ☺", 10)}, /* wut */ +}; + +TEST(writevint, test) { + size_t i; + uint8_t b[10], *p; + for (i = 0; i < ARRAYLEN(kv); ++i) { + memset(b, 0, sizeof(b)); + p = writevint(b, kv[i].x); + __TEST_EQ(assert, kz[i].file, kz[i].line, __FUNCTION__, kz[i].icode, + kz[i].xcode, kv[i].i, p - b); + assertBinaryEquals$cp437(kz[i].file, kz[i].line, __FUNCTION__, kv[i].b, b, + strlen(kv[i].b), "", false); + } +} + +TEST(readvint, test) { + size_t i; + uint64_t x; + uint8_t *b, *p; + for (i = 0; i < ARRAYLEN(kv); ++i) { + b = gc(unbingstr(kv[i].b)); + p = readvint(b, b + strlen(kv[i].b), &x); + __TEST_EQ(assert, kv[i].file, kv[i].line, __FUNCTION__, kv[i].icode, + kv[i].xcode, kv[i].i, (intptr_t)(p - b)); + assertBinaryEquals$cp437(kv[i].file, kv[i].line, __FUNCTION__, kv[i].b, b, + strlen(kv[i].b), "", false); + } +} + +TEST(writesint, test) { + size_t i; + uint8_t b[10], *p; + for (i = 0; i < ARRAYLEN(kz); ++i) { + memset(b, 0, sizeof(b)); + p = writesint(b, kz[i].x); + __TEST_EQ(assert, kz[i].file, kz[i].line, __FUNCTION__, kz[i].icode, + kz[i].xcode, kz[i].i, (intptr_t)(p - b)); + assertBinaryEquals$cp437(kz[i].file, kz[i].line, __FUNCTION__, kz[i].b, b, + strlen(kz[i].b), "", false); + } +} + +TEST(readsint, test) { + size_t i; + int64_t x; + uint8_t *b, *p; + for (i = 0; i < ARRAYLEN(kz); ++i) { + b = gc(unbingstr(kz[i].b)); + p = readsint(b, b + strlen(kz[i].b), &x); + __TEST_EQ(assert, kz[i].file, kz[i].line, __FUNCTION__, kz[i].icode, + kz[i].xcode, kz[i].i, (intptr_t)(p - b)); + assertBinaryEquals$cp437(kz[i].file, kz[i].line, __FUNCTION__, kz[i].b, b, + strlen(kz[i].b), "", false); + } +} diff --git a/test/libc/test.mk b/test/libc/test.mk new file mode 100644 index 00000000..32889e72 --- /dev/null +++ b/test/libc/test.mk @@ -0,0 +1,25 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +.PHONY: o/$(MODE)/test/libc +o/$(MODE)/test/libc: \ + o/$(MODE)/test/libc/alg \ + o/$(MODE)/test/libc/bits \ + o/$(MODE)/test/libc/calls \ + o/$(MODE)/test/libc/conv \ + o/$(MODE)/test/libc/dns \ + o/$(MODE)/test/libc/fmt \ + o/$(MODE)/test/libc/intrin \ + o/$(MODE)/test/libc/math \ + o/$(MODE)/test/libc/mem \ + o/$(MODE)/test/libc/nexgen32e \ + o/$(MODE)/test/libc/rand \ + o/$(MODE)/test/libc/runtime \ + o/$(MODE)/test/libc/sock \ + o/$(MODE)/test/libc/stdio \ + o/$(MODE)/test/libc/str \ + o/$(MODE)/test/libc/time \ + o/$(MODE)/test/libc/tinymath \ + o/$(MODE)/test/libc/unicode \ + o/$(MODE)/test/libc/x \ + o/$(MODE)/test/libc/xed diff --git a/test/libc/time/clock_gettime_test.c b/test/libc/time/clock_gettime_test.c new file mode 100644 index 00000000..9e38f86e --- /dev/null +++ b/test/libc/time/clock_gettime_test.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/conv.h" +#include "libc/runtime/gc.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/clock.h" +#include "libc/testlib/testlib.h" +#include "libc/time/time.h" +#include "libc/calls/struct/timespec.h" +#include "libc/x/x.h" + +TEST(clock_gettime, testClockRealtime) { + struct timeval tv; + struct timespec ts; + EXPECT_NE(-1, gettimeofday(&tv, NULL)); + EXPECT_NE(-1, clock_gettime(CLOCK_REALTIME, &ts)); + EXPECT_LT((unsigned)abs(ts.tv_sec - tv.tv_sec), 5u); +} diff --git a/test/libc/time/dsleep_test.c b/test/libc/time/dsleep_test.c new file mode 100644 index 00000000..f11b81e6 --- /dev/null +++ b/test/libc/time/dsleep_test.c @@ -0,0 +1,46 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/struct/sigset.h" +#include "libc/log/log.h" +#include "libc/nexgen32e/nexgen32e.h" +#include "libc/sysv/consts/clock.h" +#include "libc/sysv/consts/sig.h" +#include "libc/testlib/testlib.h" +#include "libc/time/time.h" +#include "libc/x/x.h" + +TEST(fastdiv, test) { + long x = 123000000321; + EXPECT_EQ(123, div1000000000int64(x)); + EXPECT_EQ(321, mod1000000000int64(x)); +} + +TEST(dsleep, test) { + sigset_t oldmask; + long double t1, t2; + sigprocmask(SIG_BLOCK, &kSigsetFull, &oldmask); + sched_yield(); + t1 = dtime(CLOCK_MONOTONIC); + dsleep(0.001L); + t2 = dtime(CLOCK_MONOTONIC); + sigprocmask(SIG_SETMASK, &oldmask, NULL); + ASSERT_LDBL_GT(t2 - t1, 0.0005L); +} diff --git a/test/libc/time/strftime_test.c b/test/libc/time/strftime_test.c new file mode 100644 index 00000000..be0891ef --- /dev/null +++ b/test/libc/time/strftime_test.c @@ -0,0 +1,68 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/runtime/runtime.h" +#include "libc/testlib/testlib.h" +#include "libc/time/time.h" + +textstartup static void strftime_test_init(void) { setenv("TZ", "GST", true); } +const void *const strftime_test_ctor[] initarray = {strftime_test_init}; + +testonly char *FormatTime(const char *fmt, struct tm *tm) { + static char buf[64]; + strftime(buf, sizeof(buf), fmt, tm); + return &buf[0]; +} + +TEST(strftime_100, iso8601_ShakaZuluTime) { + int64_t t = 0x5cd04d0e; + ASSERT_STREQ("2019-05-06T15:04:46Z", + FormatTime("%Y-%m-%dT%H:%M:%SZ", gmtime(&t))); +} + +TEST(strftime_100, rfc2822_ShakaZuluTime) { + int64_t t = 0x5cd04d0e; + ASSERT_STREQ("Mon, 06 May 2019 15:04:46 +0000", + FormatTime("%a, %d %b %Y %T %z", gmtime(&t))); +} + +TEST(strftime_100, rfc822_ShakaZuluTime) { + int64_t t = 0x5cd04d0e; + ASSERT_STREQ("Mon, 06 May 19 15:04:46 +0000", + FormatTime("%a, %d %b %y %T %z", gmtime(&t))); +} + +TEST(strftime_201, iso8601_GoogleStandardTime) { + int64_t t = 0x5cd04d0e; + ASSERT_STREQ("2019-05-06T08:04:46PDT", + FormatTime("%Y-%m-%dT%H:%M:%S%Z", localtime(&t))); +} + +TEST(strftime_201, rfc2822_GoogleStandardTime) { + int64_t t = 0x5cd04d0e; + ASSERT_STREQ("Mon, 06 May 2019 08:04:46 -0700", + FormatTime("%a, %d %b %Y %T %z", localtime(&t))); +} + +TEST(strftime_201, rfc822_GoogleStandardTime) { + int64_t t = 0x5cd04d0e; + ASSERT_STREQ("Mon, 06 May 19 08:04:46 -0700", + FormatTime("%a, %d %b %y %T %z", localtime(&t))); +} diff --git a/test/libc/time/test.mk b/test/libc/time/test.mk new file mode 100644 index 00000000..7ea990e3 --- /dev/null +++ b/test/libc/time/test.mk @@ -0,0 +1,51 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_TIME + +TEST_LIBC_TIME_SRCS := $(wildcard test/libc/time/*.c) +TEST_LIBC_TIME_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_TIME_SRCS)) +TEST_LIBC_TIME_COMS = $(TEST_LIBC_TIME_OBJS:%.o=%.com) +TEST_LIBC_TIME_BINS = $(TEST_LIBC_TIME_COMS) $(TEST_LIBC_TIME_COMS:%=%.dbg) + +TEST_LIBC_TIME_OBJS = \ + $(TEST_LIBC_TIME_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_TIME_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_TIME_TESTS = $(TEST_LIBC_TIME_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) +TEST_LIBC_TIME_CHECKS = \ + $(TEST_LIBC_TIME_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_TIME_DIRECTDEPS = \ + LIBC_CALLS \ + LIBC_CALLS_HEFTY \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_LOG \ + LIBC_TESTLIB \ + LIBC_TIME \ + LIBC_X + +TEST_LIBC_TIME_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_TIME_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/time/time.pkg: \ + $(TEST_LIBC_TIME_OBJS) \ + $(foreach x,$(TEST_LIBC_TIME_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/time/%.com.dbg: \ + $(TEST_LIBC_TIME_DEPS) \ + o/$(MODE)/test/libc/time/%.o \ + o/$(MODE)/test/libc/time/time.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +.PHONY: o/$(MODE)/test/libc/time +o/$(MODE)/test/libc/time: \ + $(TEST_LIBC_TIME_BINS) \ + $(TEST_LIBC_TIME_CHECKS) diff --git a/test/libc/tinymath/powl_test.c b/test/libc/tinymath/powl_test.c new file mode 100644 index 00000000..3210a133 --- /dev/null +++ b/test/libc/tinymath/powl_test.c @@ -0,0 +1,60 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/runtime/gc.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" +#include "libc/tinymath/tinymath.h" +#include "libc/x/x.h" +#include "third_party/dtoa/dtoa.h" + +TEST(powl, testLongDouble) { + /* .4248496805467504836322459796959084815827285786480897 */ + EXPECT_STARTSWITH(".4248496805467504", gc(xdtoa(powl(0.7, 2.4)))); + EXPECT_STARTSWITH(".4248496805467504", gc(xdtoa(tinymath_powl(0.7, 2.4)))); +} + +TEST(powl, testDouble) { + EXPECT_STARTSWITH(".4248496805467504", gc(xdtoa(pow(0.7, 2.4)))); + EXPECT_STARTSWITH(".4248496805467504", gc(xdtoa(tinymath_pow(0.7, 2.4)))); +} + +TEST(powl, testFloat) { + EXPECT_STARTSWITH(".4248496", gc(xdtoa(powf(0.7f, 2.4f)))); + EXPECT_STARTSWITH(".4248496", gc(xdtoa(tinymath_powf(0.7f, 2.4f)))); +} + +static long double do_powl(void) { + return CONCEAL("t", tinymath_powl(CONCEAL("t", 0.7), CONCEAL("t", 0.2))); +} + +static double do_pow(void) { + return CONCEAL("x", tinymath_pow(CONCEAL("x", 0.7), CONCEAL("x", 0.2))); +} + +static float do_powf(void) { + return CONCEAL("x", tinymath_powf(CONCEAL("x", 0.7f), CONCEAL("x", 0.2f))); +} + +BENCH(powl, bench) { + EZBENCH2("powl", donothing, do_powl()); /* ~61ns */ + EZBENCH2("pow", donothing, do_pow()); /* ~64ns */ + EZBENCH2("powf", donothing, do_powf()); /* ~64ns */ +} diff --git a/test/libc/tinymath/round_test.c b/test/libc/tinymath/round_test.c new file mode 100644 index 00000000..44dede04 --- /dev/null +++ b/test/libc/tinymath/round_test.c @@ -0,0 +1,120 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/nexgen32e/x86feature.h" +#include "libc/runtime/gc.h" +#include "libc/testlib/testlib.h" +#include "libc/tinymath/tinymath.h" +#include "libc/x/x.h" + +float tinymath_roundf$k8(float); +double tinymath_round$k8(double); + +TEST(round, test) { + EXPECT_STREQ("-3", gc(xdtoa(tinymath_round(-2.5)))); + EXPECT_STREQ("-2", gc(xdtoa(tinymath_round(-1.5)))); + EXPECT_STREQ("-1", gc(xdtoa(tinymath_round(-.5)))); + EXPECT_STREQ("1", gc(xdtoa(tinymath_round(.5)))); + EXPECT_STREQ("2", gc(xdtoa(tinymath_round(1.5)))); + EXPECT_STREQ("3", gc(xdtoa(tinymath_round(2.5)))); +} + +TEST(round, testCornerCases) { + EXPECT_STREQ("-0", gc(xdtoa(tinymath_round(-0.0)))); + EXPECT_STREQ("NAN", gc(xdtoa(tinymath_round(NAN)))); + EXPECT_STREQ("-NAN", gc(xdtoa(tinymath_round(-NAN)))); + EXPECT_STREQ("INFINITY", gc(xdtoa(tinymath_round(INFINITY)))); + EXPECT_STREQ("-INFINITY", gc(xdtoa(tinymath_round(-INFINITY)))); +} + +TEST(lround, test) { + EXPECT_EQ(-3, tinymath_lround(-2.5)); + EXPECT_EQ(-2, tinymath_lround(-1.5)); + EXPECT_EQ(-1, tinymath_lround(-.5)); + EXPECT_EQ(0, tinymath_lround(-.0)); + EXPECT_EQ(1, tinymath_lround(.5)); + EXPECT_EQ(2, tinymath_lround(1.5)); + EXPECT_EQ(3, tinymath_lround(2.5)); +} + +TEST(roundf, test) { + EXPECT_STREQ("-3", gc(xdtoa(tinymath_roundf(-2.5)))); + EXPECT_STREQ("-2", gc(xdtoa(tinymath_roundf(-1.5)))); + EXPECT_STREQ("-1", gc(xdtoa(tinymath_roundf(-.5)))); + EXPECT_STREQ("1", gc(xdtoa(tinymath_roundf(.5)))); + EXPECT_STREQ("2", gc(xdtoa(tinymath_roundf(1.5)))); + EXPECT_STREQ("3", gc(xdtoa(tinymath_roundf(2.5)))); +} + +TEST(roundf, testCornerCases) { + EXPECT_STREQ("-0", gc(xdtoa(tinymath_roundf(-0.0)))); + EXPECT_STREQ("NAN", gc(xdtoa(tinymath_roundf(NAN)))); + EXPECT_STREQ("-NAN", gc(xdtoa(tinymath_roundf(-NAN)))); + EXPECT_STREQ("INFINITY", gc(xdtoa(tinymath_roundf(INFINITY)))); + EXPECT_STREQ("-INFINITY", gc(xdtoa(tinymath_roundf(-INFINITY)))); +} + +TEST(lroundf, test) { + EXPECT_EQ(-3, tinymath_lroundf(-2.5)); + EXPECT_EQ(-2, tinymath_lroundf(-1.5)); + EXPECT_EQ(-1, tinymath_lroundf(-.5)); + EXPECT_EQ(0, tinymath_lroundf(-.0)); + EXPECT_EQ(1, tinymath_lroundf(.5)); + EXPECT_EQ(2, tinymath_lroundf(1.5)); + EXPECT_EQ(3, tinymath_lroundf(2.5)); +} + +#if !X86_NEED(SSE4_2) + +TEST(round$k8, test) { + EXPECT_STREQ("-3", gc(xdtoa(tinymath_round$k8(-2.5)))); + EXPECT_STREQ("-2", gc(xdtoa(tinymath_round$k8(-1.5)))); + EXPECT_STREQ("-1", gc(xdtoa(tinymath_round$k8(-.5)))); + EXPECT_STREQ("1", gc(xdtoa(tinymath_round$k8(.5)))); + EXPECT_STREQ("2", gc(xdtoa(tinymath_round$k8(1.5)))); + EXPECT_STREQ("3", gc(xdtoa(tinymath_round$k8(2.5)))); +} + +TEST(roundf$k8, test) { + EXPECT_STREQ("-3", gc(xdtoa(tinymath_roundf$k8(-2.5)))); + EXPECT_STREQ("-2", gc(xdtoa(tinymath_roundf$k8(-1.5)))); + EXPECT_STREQ("-1", gc(xdtoa(tinymath_roundf$k8(-.5)))); + EXPECT_STREQ("1", gc(xdtoa(tinymath_roundf$k8(.5)))); + EXPECT_STREQ("2", gc(xdtoa(tinymath_roundf$k8(1.5)))); + EXPECT_STREQ("3", gc(xdtoa(tinymath_roundf$k8(2.5)))); +} + +TEST(round$k8, testCornerCases) { + EXPECT_STREQ("-0", gc(xdtoa(tinymath_round$k8(-0.0)))); + EXPECT_STREQ("NAN", gc(xdtoa(tinymath_round$k8(NAN)))); + EXPECT_STREQ("-NAN", gc(xdtoa(tinymath_round$k8(-NAN)))); + EXPECT_STREQ("INFINITY", gc(xdtoa(tinymath_round$k8(INFINITY)))); + EXPECT_STREQ("-INFINITY", gc(xdtoa(tinymath_round$k8(-INFINITY)))); +} + +TEST(roundf$k8, testCornerCases) { + EXPECT_STREQ("-0", gc(xdtoa(tinymath_roundf$k8(-0.0)))); + EXPECT_STREQ("NAN", gc(xdtoa(tinymath_roundf$k8(NAN)))); + EXPECT_STREQ("-NAN", gc(xdtoa(tinymath_roundf$k8(-NAN)))); + EXPECT_STREQ("INFINITY", gc(xdtoa(tinymath_roundf$k8(INFINITY)))); + EXPECT_STREQ("-INFINITY", gc(xdtoa(tinymath_roundf$k8(-INFINITY)))); +} + +#endif diff --git a/test/libc/tinymath/sinl_test.c b/test/libc/tinymath/sinl_test.c new file mode 100644 index 00000000..74cf6c45 --- /dev/null +++ b/test/libc/tinymath/sinl_test.c @@ -0,0 +1,46 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" +#include "third_party/dtoa/dtoa.h" + +char buf[32]; + +TEST(sinl, testLongDouble) { + EXPECT_STREQ(".479425538604203", g_fmt(buf, sinl(0.5))); + EXPECT_STREQ("-.479425538604203", g_fmt(buf, sinl(-0.5))); +} + +TEST(sinl, testDouble) { + EXPECT_STREQ(".479425538604203", g_fmt(buf, sin(0.5))); + EXPECT_STREQ("-.479425538604203", g_fmt(buf, sin(-0.5))); +} + +TEST(sinl, testFloat) { + EXPECT_STARTSWITH(".4794255", g_fmt(buf, sinf(0.5f))); + EXPECT_STARTSWITH("-.4794255", g_fmt(buf, sinf(-0.5f))); +} + +BENCH(sinl, bench) { + EZBENCH(donothing, sinl(0.7)); /* ~30ns */ + EZBENCH(donothing, sin(0.7)); /* ~35ns */ + EZBENCH(donothing, sinf(0.7f)); /* ~35ns */ +} diff --git a/test/libc/tinymath/test.mk b/test/libc/tinymath/test.mk new file mode 100644 index 00000000..1f10bf02 --- /dev/null +++ b/test/libc/tinymath/test.mk @@ -0,0 +1,57 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_TINYMATH + +TEST_LIBC_TINYMATH_SRCS := $(wildcard test/libc/tinymath/*.c) +TEST_LIBC_TINYMATH_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_TINYMATH_SRCS)) +TEST_LIBC_TINYMATH_COMS = $(TEST_LIBC_TINYMATH_OBJS:%.o=%.com) + +TEST_LIBC_TINYMATH_OBJS = \ + $(TEST_LIBC_TINYMATH_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_TINYMATH_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_TINYMATH_BINS = \ + $(TEST_LIBC_TINYMATH_COMS) \ + $(TEST_LIBC_TINYMATH_COMS:%=%.dbg) + +TEST_LIBC_TINYMATH_TESTS = $(TEST_LIBC_TINYMATH_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_TINYMATH_CHECKS = \ + $(TEST_LIBC_TINYMATH_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_TINYMATH_DIRECTDEPS = \ + LIBC_CALLS_HEFTY \ + LIBC_FMT \ + LIBC_TINYMATH \ + LIBC_MEM \ + LIBC_RUNTIME \ + LIBC_STUBS \ + LIBC_TESTLIB \ + LIBC_X \ + THIRD_PARTY_DTOA + +TEST_LIBC_TINYMATH_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_TINYMATH_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/tinymath/tinymath.pkg: \ + $(TEST_LIBC_TINYMATH_OBJS) \ + $(foreach x,$(TEST_LIBC_TINYMATH_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/tinymath/%.com.dbg: \ + $(TEST_LIBC_TINYMATH_DEPS) \ + o/$(MODE)/test/libc/tinymath/%.o \ + o/$(MODE)/test/libc/tinymath/tinymath.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +$(TEST_LIBC_TINYMATH_OBJS): \ + DEFAULT_CCFLAGS += \ + -fno-builtin + +.PHONY: o/$(MODE)/test/libc/tinymath +o/$(MODE)/test/libc/tinymath: \ + $(TEST_LIBC_TINYMATH_BINS) \ + $(TEST_LIBC_TINYMATH_CHECKS) diff --git a/test/libc/unicode/test.mk b/test/libc/unicode/test.mk new file mode 100644 index 00000000..b75762dd --- /dev/null +++ b/test/libc/unicode/test.mk @@ -0,0 +1,50 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_UNICODE + +TEST_LIBC_UNICODE_SRCS := $(wildcard test/libc/unicode/*.c) +TEST_LIBC_UNICODE_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_UNICODE_SRCS)) +TEST_LIBC_UNICODE_COMS = $(TEST_LIBC_UNICODE_OBJS:%.o=%.com) + +TEST_LIBC_UNICODE_OBJS = \ + $(TEST_LIBC_UNICODE_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_UNICODE_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_UNICODE_BINS = \ + $(TEST_LIBC_UNICODE_COMS) \ + $(TEST_LIBC_UNICODE_COMS:%=%.dbg) + +TEST_LIBC_UNICODE_TESTS = \ + $(TEST_LIBC_UNICODE_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_UNICODE_CHECKS = \ + $(TEST_LIBC_UNICODE_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_UNICODE_DIRECTDEPS = \ + LIBC_NEXGEN32E \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_TESTLIB \ + LIBC_UNICODE + +TEST_LIBC_UNICODE_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_UNICODE_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/unicode/unicode.pkg: \ + $(TEST_LIBC_UNICODE_OBJS) \ + $(foreach x,$(TEST_LIBC_UNICODE_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/unicode/%.com.dbg: \ + $(TEST_LIBC_UNICODE_DEPS) \ + o/$(MODE)/test/libc/unicode/%.o \ + o/$(MODE)/test/libc/unicode/unicode.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +.PHONY: o/$(MODE)/test/libc/unicode +o/$(MODE)/test/libc/unicode: \ + $(TEST_LIBC_UNICODE_BINS) \ + $(TEST_LIBC_UNICODE_CHECKS) diff --git a/test/libc/unicode/wcwidth_test.c b/test/libc/unicode/wcwidth_test.c new file mode 100644 index 00000000..bb357afe --- /dev/null +++ b/test/libc/unicode/wcwidth_test.c @@ -0,0 +1,85 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" +#include "libc/unicode/unicode.h" + +TEST(strwidth, testCjkWidesAndCombiningLowLines_withThompsonPikeEncoding) { + /*───────────────────────────────────────────────────┬─*/ + EXPECT_EQ(20, strwidth(/**/ "𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷▒▒▒▒▒▒▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(20, strwidth(/**/ "(╯°□°)╯𐄻︵ ̲┻̲━̲┻▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(20, strwidth(/**/ "ちゃぶ台返し▒▒▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(20, strclen(/*─*/ "𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷▒▒▒▒▒▒▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(22, strclen(/*─*/ "(╯°□°)╯𐄻︵ ̲┻̲━̲┻▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(14, strclen(/*─*/ "ちゃぶ台返し▒▒▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(68, strlen(/*──*/ "𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷▒▒▒▒▒▒▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(56, strlen(/*──*/ "(╯°□°)╯𐄻︵ ̲┻̲━̲┻▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(42, strlen(/*──*/ "ちゃぶ台返し▒▒▒▒▒▒▒▒" /*│*/)); + /*───────────────────────────────────────────────────┴─*/ +} + +TEST(strwidth16, testCjkWidesAndCombiningLowLines_lengthIsNotShorts) { + /*──────────────────────────────────────────────────────┬─*/ + EXPECT_EQ(20, strwidth16(/**/ u"𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷▒▒▒▒▒▒▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(20, strwidth16(/**/ u"(╯°□°)╯𐄻︵ ̲┻̲━̲┻▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(20, strwidth16(/**/ u"ちゃぶ台返し▒▒▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(20, strclen16(/*─*/ u"𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷▒▒▒▒▒▒▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(22, strclen16(/*─*/ u"(╯°□°)╯𐄻︵ ̲┻̲━̲┻▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(14, strclen16(/*─*/ u"ちゃぶ台返し▒▒▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(28, strlen16(/*──*/ u"𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷▒▒▒▒▒▒▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(23, strlen16(/*──*/ u"(╯°□°)╯𐄻︵ ̲┻̲━̲┻▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(14, strlen16(/*──*/ u"ちゃぶ台返し▒▒▒▒▒▒▒▒" /*│*/)); + /*──────────────────────────────────────────────────────┴─*/ +} + +TEST(wcwidth, testCjkWidesAndCombiningLowLines_widthIsNotLength) { + /*────────────────────────────────────────────────────┬─*/ + EXPECT_EQ(20, wcswidth(/**/ L"Table flip▒▒▒▒▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(20, wcswidth(/**/ L"(╯°□°)╯︵ ̲┻̲━̲┻▒▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(20, wcswidth(/**/ L"ちゃぶ台返し▒▒▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(20, wcslen(/*──*/ L"Table flip▒▒▒▒▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(22, wcslen(/*──*/ L"(╯°□°)╯︵ ̲┻̲━̲┻▒▒▒▒▒▒▒" /*│*/)); + EXPECT_EQ(14, wcslen(/*──*/ L"ちゃぶ台返し▒▒▒▒▒▒▒▒" /*│*/)); + /*────────────────────────────────────────────────────┴─*/ +} + +TEST(strwidth, testEmoji_cosmoHelpsYouBuildInclusiveProductsEasily) { + /* ┌─If this line is solid your terminal + │ is respectful and inclusive towards + │ our friends w/ rich and interesting + │ backgrounds that aren't Anglo-Saxon + │ + │ ┌─This line being solid, means your + │ │ terminal needs a patch to address + │ │ issues concerning racism + │ │ + ──────────────────────────────────────┼─┼─*/ + EXPECT_EQ(02, wcswidth(/**/ L"👦🏿" /*- │ - */)); + /*────────────────────────────────────┼─┼─*/ +} + +TEST(strwidth, tab) { + EXPECT_EQ(32, strwidth("mov 0x0(%rip),%rcx \t")); +} + +TEST(wcwidth, block) { + EXPECT_EQ(1, wcwidth(u'▄')); +} diff --git a/test/libc/x/test.mk b/test/libc/x/test.mk new file mode 100644 index 00000000..c0415657 --- /dev/null +++ b/test/libc/x/test.mk @@ -0,0 +1,53 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_X + +TEST_LIBC_X_SRCS := $(wildcard test/libc/x/*.c) +TEST_LIBC_X_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_X_SRCS)) +TEST_LIBC_X_COMS = $(TEST_LIBC_X_OBJS:%.o=%.com) + +TEST_LIBC_X_OBJS = \ + $(TEST_LIBC_X_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_X_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_X_BINS = \ + $(TEST_LIBC_X_COMS) \ + $(TEST_LIBC_X_COMS:%=%.dbg) + +TEST_LIBC_X_TESTS = \ + $(TEST_LIBC_X_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_X_CHECKS = \ + $(TEST_LIBC_X_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_X_DIRECTDEPS = \ + LIBC_FMT \ + LIBC_MEM \ + LIBC_STDIO \ + LIBC_STR \ + LIBC_RUNTIME \ + LIBC_X \ + LIBC_STUBS \ + LIBC_TESTLIB + +TEST_LIBC_X_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_X_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/x/x.pkg: \ + $(TEST_LIBC_X_OBJS) \ + $(foreach x,$(TEST_LIBC_X_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/x/%.com.dbg: \ + $(TEST_LIBC_X_DEPS) \ + o/$(MODE)/test/libc/x/%.o \ + o/$(MODE)/test/libc/x/x.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +.PHONY: o/$(MODE)/test/libc/x +o/$(MODE)/test/libc/x: \ + $(TEST_LIBC_X_BINS) \ + $(TEST_LIBC_X_CHECKS) diff --git a/test/libc/x/xasprintf_test.c b/test/libc/x/xasprintf_test.c new file mode 100644 index 00000000..f5fa9ce1 --- /dev/null +++ b/test/libc/x/xasprintf_test.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/gc.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +TEST(xasprintf, test) { + EXPECT_STREQ("hi.there", gc(xasprintf("%s.%s", "hi", "there"))); +} diff --git a/test/libc/x/xstrcat_test.c b/test/libc/x/xstrcat_test.c new file mode 100644 index 00000000..390dcb6e --- /dev/null +++ b/test/libc/x/xstrcat_test.c @@ -0,0 +1,32 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/gc.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +TEST(xstrcat, test) { + EXPECT_STREQ("hi", gc(xstrcat("hi"))); + EXPECT_STREQ("hithere", gc(xstrcat("hi", "there"))); +} + +TEST(xstrcat, pointerAbuse) { + EXPECT_STREQ("hi there", gc(xstrcat("hi", ' ', "there"))); + EXPECT_STREQ("hi there\n", gc(xstrcat("hi", ' ', "there", '\n'))); +} diff --git a/test/libc/xed/lib.h b/test/libc/xed/lib.h new file mode 100644 index 00000000..97b0c80d --- /dev/null +++ b/test/libc/xed/lib.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_TEST_LIBC_XED_LIB_H_ +#define COSMOPOLITAN_TEST_LIBC_XED_LIB_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +int ild(const char16_t *codez); +int ildreal(const char16_t *codez); +int ildlegacy(const char16_t *codez); +uint8_t *unbingx86op(const char16_t *codez) nodiscard; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_TEST_LIBC_XED_LIB_H_ */ diff --git a/test/libc/xed/test.mk b/test/libc/xed/test.mk new file mode 100644 index 00000000..f58cc65f --- /dev/null +++ b/test/libc/xed/test.mk @@ -0,0 +1,102 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +TEST_LIBC_XED_FILES := $(wildcard test/libc/xed/*) +TEST_LIBC_XED_HDRS = $(filter %.h,$(TEST_LIBC_XED_FILES)) + +#─────────────────────────────────────────────────────────────────────────────── + +PKGS += TEST_LIBC_XED_TESTLIB + +TEST_LIBC_XED_TESTLIB_SRCS = \ + $(TEST_LIBC_XED_TESTLIB_A_SRCS) + +TEST_LIBC_XED_TESTLIB_OBJS = \ + $(TEST_LIBC_XED_TESTLIB_A_OBJS) + +TEST_LIBC_XED_TESTLIB = \ + $(TEST_LIBC_XED_TESTLIB_A_DEPS) \ + $(TEST_LIBC_XED_TESTLIB_A) + +TEST_LIBC_XED_TESTLIB_A = o/$(MODE)/test/libc/xed/testlib.a +TEST_LIBC_XED_TESTLIB_A_SRCS = $(filter %_lib.c,$(TEST_LIBC_XED_FILES)) + +TEST_LIBC_XED_TESTLIB_A_OBJS = \ + $(TEST_LIBC_XED_TESTLIB_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_XED_TESTLIB_A_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_XED_TESTLIB_A_DIRECTDEPS = \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_STUBS \ + LIBC_TESTLIB \ + LIBC_X \ + THIRD_PARTY_XED + +TEST_LIBC_XED_TESTLIB_A_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_XED_TESTLIB_A_DIRECTDEPS),$($(x)))) + +$(TEST_LIBC_XED_TESTLIB_A).pkg: \ + $(TEST_LIBC_XED_TESTLIB_A_OBJS) \ + $(foreach x,$(TEST_LIBC_XED_TESTLIB_A_DIRECTDEPS),$($(x)_A).pkg) + +$(TEST_LIBC_XED_TESTLIB_A): \ + test/libc/xed/ \ + $(TEST_LIBC_XED_TESTLIB_A).pkg \ + $(TEST_LIBC_XED_TESTLIB_A_OBJS) + +#─────────────────────────────────────────────────────────────────────────────── + +PKGS += TEST_LIBC_XED + +TEST_LIBC_XED_SRCS = $(filter %_test.c,$(TEST_LIBC_XED_FILES)) +TEST_LIBC_XED_COMS = $(TEST_LIBC_XED_OBJS:%.o=%.com) + +TEST_LIBC_XED_OBJS = \ + $(TEST_LIBC_XED_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_LIBC_XED_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_XED_BINS = \ + $(TEST_LIBC_XED_COMS) \ + $(TEST_LIBC_XED_COMS:%=%.dbg) + +TEST_LIBC_XED_TESTS = \ + $(TEST_LIBC_XED_SRCS:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_XED_CHECKS = \ + $(TEST_LIBC_XED_SRCS:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_XED_DIRECTDEPS = \ + LIBC_CALLS_HEFTY \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_RUNTIME \ + LIBC_STUBS \ + LIBC_TESTLIB \ + TEST_LIBC_XED_TESTLIB \ + THIRD_PARTY_XED + +TEST_LIBC_XED_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_XED_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/xed/xed.pkg: \ + $(TEST_LIBC_XED_OBJS) \ + $(foreach x,$(TEST_LIBC_XED_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/libc/xed/%.com.dbg: \ + $(TEST_LIBC_XED_DEPS) \ + o/$(MODE)/test/libc/xed/%.o \ + o/$(MODE)/test/libc/xed/xed.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +#─────────────────────────────────────────────────────────────────────────────── + +.PHONY: o/$(MODE)/test/libc/xed +o/$(MODE)/test/libc/xed: \ + $(TEST_LIBC_XED_BINS) \ + $(TEST_LIBC_XED_CHECKS) diff --git a/test/libc/xed/x86ild_lib.c b/test/libc/xed/x86ild_lib.c new file mode 100644 index 00000000..b6252b50 --- /dev/null +++ b/test/libc/xed/x86ild_lib.c @@ -0,0 +1,69 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/fmt/bing.h" +#include "libc/macros.h" +#include "libc/runtime/gc.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" +#include "test/libc/xed/lib.h" +#include "third_party/xed/x86.h" + +testonly nodiscard uint8_t *unbingx86op(const char16_t *codez) { + size_t len; + len = strlen(codez); + return unbingbuf(xmalloc(ROUNDUP(len, 16)), len, codez, 0x90); +} + +/** + * Long mode instruction length decoder. + */ +testonly int ild(const char16_t *codez) { + struct XedDecodedInst xedd; + enum XedError error; + error = xed_instruction_length_decode( + xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64), + gc(unbingx86op(codez)), strlen16(codez) + 16); + return error == XED_ERROR_NONE ? xedd.decoded_length : -error; +} + +/** + * Real mode instruction length decoder. + */ +testonly int ildreal(const char16_t *codez) { + struct XedDecodedInst xedd; + enum XedError error; + error = xed_instruction_length_decode( + xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_REAL), + gc(unbingx86op(codez)), strlen16(codez) + 16); + return error == XED_ERROR_NONE ? xedd.decoded_length : -error; +} + +/** + * Legacy mode instruction length decoder. + */ +testonly int ildlegacy(const char16_t *codez) { + struct XedDecodedInst xedd; + enum XedError error; + error = xed_instruction_length_decode( + xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LEGACY_32), + gc(unbingx86op(codez)), strlen16(codez) + 16); + return error == XED_ERROR_NONE ? xedd.decoded_length : -error; +} diff --git a/test/libc/xed/x86ild_popular_binary_test.c b/test/libc/xed/x86ild_popular_binary_test.c new file mode 100644 index 00000000..16b3f3e4 --- /dev/null +++ b/test/libc/xed/x86ild_popular_binary_test.c @@ -0,0 +1,2794 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/testlib.h" +#include "test/libc/xed/lib.h" +#include "third_party/xed/x86.h" + +TEST(x86ild, test_4883EC00) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_IMMb + ISA_SET: I86 + SHORT: sub rsp, 0x0 + */ + EXPECT_EQ(4, ild(u"Hâ∞ ")); +} + +TEST(x86ild, test_483D00000000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_OrAX_IMMz + ISA_SET: I86 + SHORT: cmp rax, 0x0 + */ + EXPECT_EQ(6, ild(u"H=    ")); +} + +TEST(x86ild, test_48F7F6) { + /* + ICLASS: DIV + CATEGORY: BINARY + EXTENSION: BASE + IFORM: DIV_GPRv + ISA_SET: I86 + SHORT: div rsi + */ + EXPECT_EQ(3, ild(u"H≈÷")); +} + +TEST(x86ild, test_4839F1) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp rcx, rsi + */ + EXPECT_EQ(3, ild(u"H9±")); +} + +TEST(x86ild, test_4839F0) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp rax, rsi + */ + EXPECT_EQ(3, ild(u"H9≡")); +} + +TEST(x86ild, test_807B0000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMb_IMMb_80r7 + ISA_SET: I86 + SHORT: cmp byte ptr [rbx], 0x0 + */ + EXPECT_EQ(4, ild(u"Ç{  ")); +} + +TEST(x86ild, test_4839D0) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp rax, rdx + */ + EXPECT_EQ(3, ild(u"H9╨")); +} + +TEST(x86ild, test_3C00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_AL_IMMb + ISA_SET: I86 + SHORT: cmp al, 0x0 + */ + EXPECT_EQ(2, ild(u"< ")); +} + +TEST(x86ild, test_4883F800) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp rax, 0x0 + */ + EXPECT_EQ(4, ild(u"Hâ° ")); +} + +TEST(x86ild, test_FEC8) { + /* + ICLASS: DEC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: DEC_GPR8 + ISA_SET: I86 + SHORT: dec al + */ + EXPECT_EQ(2, ild(u"■╚")); +} + +TEST(x86ild, test_4801D0) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rax, rdx + */ + EXPECT_EQ(3, ild(u"H☺╨")); +} + +TEST(x86ild, test_83F800) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp eax, 0x0 + */ + EXPECT_EQ(3, ild(u"â° ")); +} + +TEST(x86ild, test_4883FA00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp rdx, 0x0 + */ + EXPECT_EQ(4, ild(u"Hâ· ")); +} + +TEST(x86ild, test_3D00000000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_OrAX_IMMz + ISA_SET: I86 + SHORT: cmp eax, 0x0 + */ + EXPECT_EQ(5, ild(u"=    ")); +} + +TEST(x86ild, test_6683F800) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp ax, 0x0 + */ + EXPECT_EQ(4, ild(u"fâ° ")); +} + +TEST(x86ild, test_80FA00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPR8_IMMb_80r7 + ISA_SET: I86 + SHORT: cmp dl, 0x0 + */ + EXPECT_EQ(3, ild(u"Ç· ")); +} + +TEST(x86ild, test_6683FA00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp dx, 0x0 + */ + EXPECT_EQ(4, ild(u"fâ· ")); +} + +TEST(x86ild, test_83FA00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp edx, 0x0 + */ + EXPECT_EQ(3, ild(u"â· ")); +} + +TEST(x86ild, test_663D0000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_OrAX_IMMz + ISA_SET: I86 + SHORT: cmp ax, 0x0 + */ + EXPECT_EQ(4, ild(u"f=  ")); +} + +TEST(x86ild, test_83FE00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp esi, 0x0 + */ + EXPECT_EQ(3, ild(u"â■ ")); +} + +TEST(x86ild, test_4883C400) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_IMMb + ISA_SET: I86 + SHORT: add rsp, 0x0 + */ + EXPECT_EQ(4, ild(u"Hâ─ ")); +} + +TEST(x86ild, test_01D2) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add edx, edx + */ + EXPECT_EQ(2, ild(u"☺╥")); +} + +TEST(x86ild, test_80F900) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPR8_IMMb_80r7 + ISA_SET: I86 + SHORT: cmp cl, 0x0 + */ + EXPECT_EQ(3, ild(u"Ç∙ ")); +} + +TEST(x86ild, test_4801C8) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rax, rcx + */ + EXPECT_EQ(3, ild(u"H☺╚")); +} + +TEST(x86ild, test_4883F900) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp rcx, 0x0 + */ + EXPECT_EQ(4, ild(u"Hâ∙ ")); +} + +TEST(x86ild, test_4839C2) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp rdx, rax + */ + EXPECT_EQ(3, ild(u"H9┬")); +} + +TEST(x86ild, test_01C0) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add eax, eax + */ + EXPECT_EQ(2, ild(u"☺└")); +} + +TEST(x86ild, test_83FF00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp edi, 0x0 + */ + EXPECT_EQ(3, ild(u"âλ ")); +} + +TEST(x86ild, test_4183FC00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp r12d, 0x0 + */ + EXPECT_EQ(4, ild(u"Aâⁿ ")); +} + +TEST(x86ild, test_01D0) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add eax, edx + */ + EXPECT_EQ(2, ild(u"☺╨")); +} + +TEST(x86ild, test_6683F900) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp cx, 0x0 + */ + EXPECT_EQ(4, ild(u"fâ∙ ")); +} + +TEST(x86ild, test_4883C300) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_IMMb + ISA_SET: I86 + SHORT: add rbx, 0x0 + */ + EXPECT_EQ(4, ild(u"Hâ├ ")); +} + +TEST(x86ild, test_0000) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_MEMb_GPR8 + ISA_SET: I86 + SHORT: add byte ptr [rax], al + */ + EXPECT_EQ(2, ild(u"  ")); +} + +TEST(x86ild, test_FECA) { + /* + ICLASS: DEC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: DEC_GPR8 + ISA_SET: I86 + SHORT: dec dl + */ + EXPECT_EQ(2, ild(u"■╩")); +} + +TEST(x86ild, test_4801C2) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rdx, rax + */ + EXPECT_EQ(3, ild(u"H☺┬")); +} + +TEST(x86ild, test_807F0000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMb_IMMb_80r7 + ISA_SET: I86 + SHORT: cmp byte ptr [rdi], 0x0 + */ + EXPECT_EQ(4, ild(u"Ç⌂  ")); +} + +TEST(x86ild, test_4801C1) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rcx, rax + */ + EXPECT_EQ(3, ild(u"H☺┴")); +} + +TEST(x86ild, test_FFC3) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc ebx + */ + EXPECT_EQ(2, ild(u"λ├")); +} + +TEST(x86ild, test_83F900) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp ecx, 0x0 + */ + EXPECT_EQ(3, ild(u"â∙ ")); +} + +TEST(x86ild, test_83E800) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_IMMb + ISA_SET: I86 + SHORT: sub eax, 0x0 + */ + EXPECT_EQ(3, ild(u"âΦ ")); +} + +TEST(x86ild, test_FFCE) { + /* + ICLASS: DEC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: DEC_GPRv_FFr1 + ISA_SET: I86 + SHORT: dec esi + */ + EXPECT_EQ(2, ild(u"λ╬")); +} + +TEST(x86ild, test_83780000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMv_IMMb + ISA_SET: I86 + SHORT: cmp dword ptr [rax], 0x0 + */ + EXPECT_EQ(4, ild(u"âx  ")); +} + +TEST(x86ild, test_81FF00000000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMz + ISA_SET: I86 + SHORT: cmp edi, 0x0 + */ + EXPECT_EQ(6, ild(u"üλ    ")); +} + +TEST(x86ild, test_FFC8) { + /* + ICLASS: DEC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: DEC_GPRv_FFr1 + ISA_SET: I86 + SHORT: dec eax + */ + EXPECT_EQ(2, ild(u"λ╚")); +} + +TEST(x86ild, test_80780000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMb_IMMb_80r7 + ISA_SET: I86 + SHORT: cmp byte ptr [rax], 0x0 + */ + EXPECT_EQ(4, ild(u"Çx  ")); +} + +TEST(x86ild, test_4839C8) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp rax, rcx + */ + EXPECT_EQ(3, ild(u"H9╚")); +} + +TEST(x86ild, test_803800) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMb_IMMb_80r7 + ISA_SET: I86 + SHORT: cmp byte ptr [rax], 0x0 + */ + EXPECT_EQ(3, ild(u"Ç8 ")); +} + +TEST(x86ild, test_4883E800) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_IMMb + ISA_SET: I86 + SHORT: sub rax, 0x0 + */ + EXPECT_EQ(4, ild(u"HâΦ ")); +} + +TEST(x86ild, test_4080FE00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPR8_IMMb_80r7 + ISA_SET: I86 + SHORT: cmp sil, 0x0 + */ + EXPECT_EQ(4, ild(u"@Ç■ ")); +} + +TEST(x86ild, test_FFC5) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc ebp + */ + EXPECT_EQ(2, ild(u"λ┼")); +} + +TEST(x86ild, test_807D0000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMb_IMMb_80r7 + ISA_SET: I86 + SHORT: cmp byte ptr [rbp], 0x0 + */ + EXPECT_EQ(4, ild(u"Ç}  ")); +} + +TEST(x86ild, test_4883C000) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_IMMb + ISA_SET: I86 + SHORT: add rax, 0x0 + */ + EXPECT_EQ(4, ild(u"Hâ└ ")); +} + +TEST(x86ild, test_480500000000) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_OrAX_IMMz + ISA_SET: I86 + SHORT: add rax, 0x0 + */ + EXPECT_EQ(6, ild(u"H♣    ")); +} + +TEST(x86ild, test_00FF) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPR8_GPR8_00 + ISA_SET: I86 + SHORT: add bh, bh + */ + EXPECT_EQ(2, ild(u" λ")); +} + +TEST(x86ild, test_FFC1) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc ecx + */ + EXPECT_EQ(2, ild(u"λ┴")); +} + +TEST(x86ild, test_83B80000000000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMv_IMMb + ISA_SET: I86 + SHORT: cmp dword ptr [rax], 0x0 + */ + EXPECT_EQ(7, ild(u"â╕     ")); +} + +TEST(x86ild, test_48FFC0) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc rax + */ + EXPECT_EQ(3, ild(u"Hλ└")); +} + +TEST(x86ild, test_4881FF00000000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMz + ISA_SET: I86 + SHORT: cmp rdi, 0x0 + */ + EXPECT_EQ(7, ild(u"Hüλ    ")); +} + +TEST(x86ild, test_4839CA) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp rdx, rcx + */ + EXPECT_EQ(3, ild(u"H9╩")); +} + +TEST(x86ild, test_4839C1) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp rcx, rax + */ + EXPECT_EQ(3, ild(u"H9┴")); +} + +TEST(x86ild, test_4801DF) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rdi, rbx + */ + EXPECT_EQ(3, ild(u"H☺▀")); +} + +TEST(x86ild, test_19C0) { + /* + ICLASS: SBB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SBB_GPRv_GPRv_19 + ISA_SET: I86 + SHORT: sbb eax, eax + */ + EXPECT_EQ(2, ild(u"↓└")); +} + +TEST(x86ild, test_833D0000000000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMv_IMMb + ISA_SET: I86 + SHORT: cmp dword ptr [rip], 0x0 + */ + EXPECT_EQ(7, ild(u"â=     ")); +} + +TEST(x86ild, test_4801F0) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rax, rsi + */ + EXPECT_EQ(3, ild(u"H☺≡")); +} + +TEST(x86ild, test_4801C0) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rax, rax + */ + EXPECT_EQ(3, ild(u"H☺└")); +} + +TEST(x86ild, test_FFCA) { + /* + ICLASS: DEC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: DEC_GPRv_FFr1 + ISA_SET: I86 + SHORT: dec edx + */ + EXPECT_EQ(2, ild(u"λ╩")); +} + +TEST(x86ild, test_FEC9) { + /* + ICLASS: DEC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: DEC_GPR8 + ISA_SET: I86 + SHORT: dec cl + */ + EXPECT_EQ(2, ild(u"■╔")); +} + +TEST(x86ild, test_83FB00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp ebx, 0x0 + */ + EXPECT_EQ(3, ild(u"â√ ")); +} + +TEST(x86ild, test_48FFC8) { + /* + ICLASS: DEC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: DEC_GPRv_FFr1 + ISA_SET: I86 + SHORT: dec rax + */ + EXPECT_EQ(3, ild(u"Hλ╚")); +} + +TEST(x86ild, test_48FFC2) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc rdx + */ + EXPECT_EQ(3, ild(u"Hλ┬")); +} + +TEST(x86ild, test_48F7F7) { + /* + ICLASS: DIV + CATEGORY: BINARY + EXTENSION: BASE + IFORM: DIV_GPRv + ISA_SET: I86 + SHORT: div rdi + */ + EXPECT_EQ(3, ild(u"H≈≈")); +} + +TEST(x86ild, test_4883FB00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp rbx, 0x0 + */ + EXPECT_EQ(4, ild(u"Hâ√ ")); +} + +TEST(x86ild, test_4839F8) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp rax, rdi + */ + EXPECT_EQ(3, ild(u"H9°")); +} + +TEST(x86ild, test_4801D1) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rcx, rdx + */ + EXPECT_EQ(3, ild(u"H☺╤")); +} + +TEST(x86ild, test_4801CA) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rdx, rcx + */ + EXPECT_EQ(3, ild(u"H☺╩")); +} + +TEST(x86ild, test_4080FF00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPR8_IMMb_80r7 + ISA_SET: I86 + SHORT: cmp dil, 0x0 + */ + EXPECT_EQ(4, ild(u"@Çλ ")); +} + +TEST(x86ild, test_FFC2) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc edx + */ + EXPECT_EQ(2, ild(u"λ┬")); +} + +TEST(x86ild, test_FFC0) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc eax + */ + EXPECT_EQ(2, ild(u"λ└")); +} + +TEST(x86ild, test_83FD00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp ebp, 0x0 + */ + EXPECT_EQ(3, ild(u"â² ")); +} + +TEST(x86ild, test_83C200) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_IMMb + ISA_SET: I86 + SHORT: add edx, 0x0 + */ + EXPECT_EQ(3, ild(u"â┬ ")); +} + +TEST(x86ild, test_83C100) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_IMMb + ISA_SET: I86 + SHORT: add ecx, 0x0 + */ + EXPECT_EQ(3, ild(u"â┴ ")); +} + +TEST(x86ild, test_4881EC00000000) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_IMMz + ISA_SET: I86 + SHORT: sub rsp, 0x0 + */ + EXPECT_EQ(7, ild(u"Hü∞    ")); +} + +TEST(x86ild, test_4881C400000000) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_IMMz + ISA_SET: I86 + SHORT: add rsp, 0x0 + */ + EXPECT_EQ(7, ild(u"Hü─    ")); +} + +TEST(x86ild, test_482D00000000) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_OrAX_IMMz + ISA_SET: I86 + SHORT: sub rax, 0x0 + */ + EXPECT_EQ(6, ild(u"H-    ")); +} + +TEST(x86ild, test_4801C6) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rsi, rax + */ + EXPECT_EQ(3, ild(u"H☺╞")); +} + +TEST(x86ild, test_4439F3) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp ebx, r14d + */ + EXPECT_EQ(3, ild(u"D9≤")); +} + +TEST(x86ild, test_41FFC8) { + /* + ICLASS: DEC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: DEC_GPRv_FFr1 + ISA_SET: I86 + SHORT: dec r8d + */ + EXPECT_EQ(3, ild(u"Aλ╚")); +} + +TEST(x86ild, test_41FFC4) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc r12d + */ + EXPECT_EQ(3, ild(u"Aλ─")); +} + +TEST(x86ild, test_4183FD00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp r13d, 0x0 + */ + EXPECT_EQ(4, ild(u"Aâ² ")); +} + +TEST(x86ild, test_4180F800) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPR8_IMMb_80r7 + ISA_SET: I86 + SHORT: cmp r8b, 0x0 + */ + EXPECT_EQ(4, ild(u"Aǰ ")); +} + +TEST(x86ild, test_39F1) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp ecx, esi + */ + EXPECT_EQ(2, ild(u"9±")); +} + +TEST(x86ild, test_39F0) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp eax, esi + */ + EXPECT_EQ(2, ild(u"9≡")); +} + +TEST(x86ild, test_FFC6) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc esi + */ + EXPECT_EQ(2, ild(u"λ╞")); +} + +TEST(x86ild, test_837D0000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMv_IMMb + ISA_SET: I86 + SHORT: cmp dword ptr [rbp], 0x0 + */ + EXPECT_EQ(4, ild(u"â}  ")); +} + +TEST(x86ild, test_833CD50000000000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMv_IMMb + ISA_SET: I86 + SHORT: cmp dword ptr [rdx*8], 0x0 + */ + EXPECT_EQ(8, ild(u"â<╒     ")); +} + +TEST(x86ild, test_81EB00000000) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_IMMz + ISA_SET: I86 + SHORT: sub ebx, 0x0 + */ + EXPECT_EQ(6, ild(u"üδ    ")); +} + +TEST(x86ild, test_807A0000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMb_IMMb_80r7 + ISA_SET: I86 + SHORT: cmp byte ptr [rdx], 0x0 + */ + EXPECT_EQ(4, ild(u"Çz  ")); +} + +TEST(x86ild, test_4C01C0) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rax, r8 + */ + EXPECT_EQ(3, ild(u"L☺└")); +} + +TEST(x86ild, test_49FFC0) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc r8 + */ + EXPECT_EQ(3, ild(u"Iλ└")); +} + +TEST(x86ild, test_4901D1) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add r9, rdx + */ + EXPECT_EQ(3, ild(u"I☺╤")); +} + +TEST(x86ild, test_48FFC7) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc rdi + */ + EXPECT_EQ(3, ild(u"Hλ╟")); +} + +TEST(x86ild, test_48FFC1) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc rcx + */ + EXPECT_EQ(3, ild(u"Hλ┴")); +} + +TEST(x86ild, test_4883FF00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp rdi, 0x0 + */ + EXPECT_EQ(4, ild(u"Hâλ ")); +} + +TEST(x86ild, test_4883EB00) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_IMMb + ISA_SET: I86 + SHORT: sub rbx, 0x0 + */ + EXPECT_EQ(4, ild(u"Hâδ ")); +} + +TEST(x86ild, test_4883C200) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_IMMb + ISA_SET: I86 + SHORT: add rdx, 0x0 + */ + EXPECT_EQ(4, ild(u"Hâ┬ ")); +} + +TEST(x86ild, test_4839D8) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp rax, rbx + */ + EXPECT_EQ(3, ild(u"H9╪")); +} + +TEST(x86ild, test_48034700) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_MEMv + ISA_SET: I86 + SHORT: add rax, qword ptr [rdi] + */ + EXPECT_EQ(4, ild(u"H♥G ")); +} + +TEST(x86ild, test_4801F2) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rdx, rsi + */ + EXPECT_EQ(3, ild(u"H☺≥")); +} + +TEST(x86ild, test_4539FE) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp r14d, r15d + */ + EXPECT_EQ(3, ild(u"E9■")); +} + +TEST(x86ild, test_4429E1) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_GPRv_29 + ISA_SET: I86 + SHORT: sub ecx, r12d + */ + EXPECT_EQ(3, ild(u"D)ß")); +} + +TEST(x86ild, test_41807C240000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMb_IMMb_80r7 + ISA_SET: I86 + SHORT: cmp byte ptr [r12], 0x0 + */ + EXPECT_EQ(6, ild(u"AÇ|$  ")); +} + +TEST(x86ild, test_39D0) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp eax, edx + */ + EXPECT_EQ(2, ild(u"9╨")); +} + +TEST(x86ild, test_39C2) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp edx, eax + */ + EXPECT_EQ(2, ild(u"9┬")); +} + +TEST(x86ild, test_39C1) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp ecx, eax + */ + EXPECT_EQ(2, ild(u"9┴")); +} + +TEST(x86ild, test_0FAFC2) { + /* + ICLASS: IMUL + CATEGORY: BINARY + EXTENSION: BASE + IFORM: IMUL_GPRv_GPRv + ISA_SET: I86 + SHORT: imul eax, edx + */ + EXPECT_EQ(3, ild(u"☼»┬")); +} + +TEST(x86ild, test_01C1) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add ecx, eax + */ + EXPECT_EQ(2, ild(u"☺┴")); +} + +TEST(x86ild, test_FE4300) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_MEMb + ISA_SET: I86 + SHORT: inc byte ptr [rbx] + */ + EXPECT_EQ(3, ild(u"■C ")); +} + +TEST(x86ild, test_F7DB) { + /* + ICLASS: NEG + CATEGORY: BINARY + EXTENSION: BASE + IFORM: NEG_GPRv + ISA_SET: I86 + SHORT: neg ebx + */ + EXPECT_EQ(2, ild(u"≈█")); +} + +TEST(x86ild, test_F77500) { + /* + ICLASS: DIV + CATEGORY: BINARY + EXTENSION: BASE + IFORM: DIV_MEMv + ISA_SET: I86 + SHORT: div dword ptr [rbp] + */ + EXPECT_EQ(3, ild(u"≈u ")); +} + +TEST(x86ild, test_83EA00) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_IMMb + ISA_SET: I86 + SHORT: sub edx, 0x0 + */ + EXPECT_EQ(3, ild(u"âΩ ")); +} + +TEST(x86ild, test_83E900) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_IMMb + ISA_SET: I86 + SHORT: sub ecx, 0x0 + */ + EXPECT_EQ(3, ild(u"âΘ ")); +} + +TEST(x86ild, test_83C700) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_IMMb + ISA_SET: I86 + SHORT: add edi, 0x0 + */ + EXPECT_EQ(3, ild(u"â╟ ")); +} + +TEST(x86ild, test_837F0000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMv_IMMb + ISA_SET: I86 + SHORT: cmp dword ptr [rdi], 0x0 + */ + EXPECT_EQ(4, ild(u"â⌂  ")); +} + +TEST(x86ild, test_833C2400) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMv_IMMb + ISA_SET: I86 + SHORT: cmp dword ptr [rsp], 0x0 + */ + EXPECT_EQ(4, ild(u"â<$ ")); +} + +TEST(x86ild, test_81FA00000000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMz + ISA_SET: I86 + SHORT: cmp edx, 0x0 + */ + EXPECT_EQ(6, ild(u"ü·    ")); +} + +TEST(x86ild, test_803D0000000000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMb_IMMb_80r7 + ISA_SET: I86 + SHORT: cmp byte ptr [rip], 0x0 + */ + EXPECT_EQ(7, ild(u"Ç=     ")); +} + +TEST(x86ild, test_6683780000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMv_IMMb + ISA_SET: I86 + SHORT: cmp word ptr [rax], 0x0 + */ + EXPECT_EQ(5, ild(u"fâx  ")); +} + +TEST(x86ild, test_6681FD0000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMz + ISA_SET: I86 + SHORT: cmp bp, 0x0 + */ + EXPECT_EQ(5, ild(u"fü²  ")); +} + +TEST(x86ild, test_6681FA0000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMz + ISA_SET: I86 + SHORT: cmp dx, 0x0 + */ + EXPECT_EQ(5, ild(u"fü·  ")); +} + +TEST(x86ild, test_6681C20000) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_IMMz + ISA_SET: I86 + SHORT: add dx, 0x0 + */ + EXPECT_EQ(5, ild(u"fü┬  ")); +} + +TEST(x86ild, test_6639D0) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp ax, dx + */ + EXPECT_EQ(3, ild(u"f9╨")); +} + +TEST(x86ild, test_6639CA) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp dx, cx + */ + EXPECT_EQ(3, ild(u"f9╩")); +} + +TEST(x86ild, test_4C29C0) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_GPRv_29 + ISA_SET: I86 + SHORT: sub rax, r8 + */ + EXPECT_EQ(3, ild(u"L)└")); +} + +TEST(x86ild, test_4C034F00) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_MEMv + ISA_SET: I86 + SHORT: add r9, qword ptr [rdi] + */ + EXPECT_EQ(4, ild(u"L♥O ")); +} + +TEST(x86ild, test_4C01E8) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rax, r13 + */ + EXPECT_EQ(3, ild(u"L☺Φ")); +} + +TEST(x86ild, test_4C01E0) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rax, r12 + */ + EXPECT_EQ(3, ild(u"L☺α")); +} + +TEST(x86ild, test_49FFC5) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc r13 + */ + EXPECT_EQ(3, ild(u"Iλ┼")); +} + +TEST(x86ild, test_49F7F1) { + /* + ICLASS: DIV + CATEGORY: BINARY + EXTENSION: BASE + IFORM: DIV_GPRv + ISA_SET: I86 + SHORT: div r9 + */ + EXPECT_EQ(3, ild(u"I≈±")); +} + +TEST(x86ild, test_49F7DC) { + /* + ICLASS: NEG + CATEGORY: BINARY + EXTENSION: BASE + IFORM: NEG_GPRv + ISA_SET: I86 + SHORT: neg r12 + */ + EXPECT_EQ(3, ild(u"I≈▄")); +} + +TEST(x86ild, test_4929C2) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_GPRv_29 + ISA_SET: I86 + SHORT: sub r10, rax + */ + EXPECT_EQ(3, ild(u"I)┬")); +} + +TEST(x86ild, test_48FFC9) { + /* + ICLASS: DEC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: DEC_GPRv_FFr1 + ISA_SET: I86 + SHORT: dec rcx + */ + EXPECT_EQ(3, ild(u"Hλ╔")); +} + +TEST(x86ild, test_48FFC6) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc rsi + */ + EXPECT_EQ(3, ild(u"Hλ╞")); +} + +TEST(x86ild, test_48FFC5) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc rbp + */ + EXPECT_EQ(3, ild(u"Hλ┼")); +} + +TEST(x86ild, test_48F7F1) { + /* + ICLASS: DIV + CATEGORY: BINARY + EXTENSION: BASE + IFORM: DIV_GPRv + ISA_SET: I86 + SHORT: div rcx + */ + EXPECT_EQ(3, ild(u"H≈±")); +} + +TEST(x86ild, test_48F7DB) { + /* + ICLASS: NEG + CATEGORY: BINARY + EXTENSION: BASE + IFORM: NEG_GPRv + ISA_SET: I86 + SHORT: neg rbx + */ + EXPECT_EQ(3, ild(u"H≈█")); +} + +TEST(x86ild, test_4883FE00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp rsi, 0x0 + */ + EXPECT_EQ(4, ild(u"Hâ■ ")); +} + +TEST(x86ild, test_48837F0000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMv_IMMb + ISA_SET: I86 + SHORT: cmp qword ptr [rdi], 0x0 + */ + EXPECT_EQ(5, ild(u"Hâ⌂  ")); +} + +TEST(x86ild, test_4881EE00000000) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_IMMz + ISA_SET: I86 + SHORT: sub rsi, 0x0 + */ + EXPECT_EQ(7, ild(u"Hüε    ")); +} + +TEST(x86ild, test_4881EB00000000) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_IMMz + ISA_SET: I86 + SHORT: sub rbx, 0x0 + */ + EXPECT_EQ(7, ild(u"Hüδ    ")); +} + +TEST(x86ild, test_4839F2) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp rdx, rsi + */ + EXPECT_EQ(3, ild(u"H9≥")); +} + +TEST(x86ild, test_4839D6) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp rsi, rdx + */ + EXPECT_EQ(3, ild(u"H9╓")); +} + +TEST(x86ild, test_4839C7) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp rdi, rax + */ + EXPECT_EQ(3, ild(u"H9╟")); +} + +TEST(x86ild, test_4829DA) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_GPRv_29 + ISA_SET: I86 + SHORT: sub rdx, rbx + */ + EXPECT_EQ(3, ild(u"H)┌")); +} + +TEST(x86ild, test_480FAFD0) { + /* + ICLASS: IMUL + CATEGORY: BINARY + EXTENSION: BASE + IFORM: IMUL_GPRv_GPRv + ISA_SET: I86 + SHORT: imul rdx, rax + */ + EXPECT_EQ(4, ild(u"H☼»╨")); +} + +TEST(x86ild, test_480FAFCA) { + /* + ICLASS: IMUL + CATEGORY: BINARY + EXTENSION: BASE + IFORM: IMUL_GPRv_GPRv + ISA_SET: I86 + SHORT: imul rcx, rdx + */ + EXPECT_EQ(4, ild(u"H☼»╩")); +} + +TEST(x86ild, test_480FAFC8) { + /* + ICLASS: IMUL + CATEGORY: BINARY + EXTENSION: BASE + IFORM: IMUL_GPRv_GPRv + ISA_SET: I86 + SHORT: imul rcx, rax + */ + EXPECT_EQ(4, ild(u"H☼»╚")); +} + +TEST(x86ild, test_48035300) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_MEMv + ISA_SET: I86 + SHORT: add rdx, qword ptr [rbx] + */ + EXPECT_EQ(4, ild(u"H♥S ")); +} + +TEST(x86ild, test_4801F8) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rax, rdi + */ + EXPECT_EQ(3, ild(u"H☺°")); +} + +TEST(x86ild, test_4801EF) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rdi, rbp + */ + EXPECT_EQ(3, ild(u"H☺∩")); +} + +TEST(x86ild, test_4801DE) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rsi, rbx + */ + EXPECT_EQ(3, ild(u"H☺▐")); +} + +TEST(x86ild, test_4801D2) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add rdx, rdx + */ + EXPECT_EQ(3, ild(u"H☺╥")); +} + +TEST(x86ild, test_4539F4) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp r12d, r14d + */ + EXPECT_EQ(3, ild(u"E9⌠")); +} + +TEST(x86ild, test_4539EF) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp r15d, r13d + */ + EXPECT_EQ(3, ild(u"E9∩")); +} + +TEST(x86ild, test_4539EE) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp r14d, r13d + */ + EXPECT_EQ(3, ild(u"E9ε")); +} + +TEST(x86ild, test_4529C4) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_GPRv_29 + ISA_SET: I86 + SHORT: sub r12d, r8d + */ + EXPECT_EQ(3, ild(u"E)─")); +} + +TEST(x86ild, test_4501E4) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add r12d, r12d + */ + EXPECT_EQ(3, ild(u"E☺Σ")); +} + +TEST(x86ild, test_4501E2) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add r10d, r12d + */ + EXPECT_EQ(3, ild(u"E☺Γ")); +} + +TEST(x86ild, test_4439E8) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp eax, r13d + */ + EXPECT_EQ(3, ild(u"D9Φ")); +} + +TEST(x86ild, test_4439E5) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp ebp, r12d + */ + EXPECT_EQ(3, ild(u"D9σ")); +} + +TEST(x86ild, test_4439E3) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp ebx, r12d + */ + EXPECT_EQ(3, ild(u"D9π")); +} + +TEST(x86ild, test_4439E1) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp ecx, r12d + */ + EXPECT_EQ(3, ild(u"D9ß")); +} + +TEST(x86ild, test_4439C9) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp ecx, r9d + */ + EXPECT_EQ(3, ild(u"D9╔")); +} + +TEST(x86ild, test_4439C7) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp edi, r8d + */ + EXPECT_EQ(3, ild(u"D9╟")); +} + +TEST(x86ild, test_4439C5) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp ebp, r8d + */ + EXPECT_EQ(3, ild(u"D9┼")); +} + +TEST(x86ild, test_4439C2) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp edx, r8d + */ + EXPECT_EQ(3, ild(u"D9┬")); +} + +TEST(x86ild, test_4438C1) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPR8_GPR8_38 + ISA_SET: I86 + SHORT: cmp cl, r8b + */ + EXPECT_EQ(3, ild(u"D8┴")); +} + +TEST(x86ild, test_4429DD) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_GPRv_29 + ISA_SET: I86 + SHORT: sub ebp, r11d + */ + EXPECT_EQ(3, ild(u"D)▌")); +} + +TEST(x86ild, test_4429D1) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_GPRv_29 + ISA_SET: I86 + SHORT: sub ecx, r10d + */ + EXPECT_EQ(3, ild(u"D)╤")); +} + +TEST(x86ild, test_4429C0) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_GPRv_29 + ISA_SET: I86 + SHORT: sub eax, r8d + */ + EXPECT_EQ(3, ild(u"D)└")); +} + +TEST(x86ild, test_4401E8) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add eax, r13d + */ + EXPECT_EQ(3, ild(u"D☺Φ")); +} + +TEST(x86ild, test_4401C8) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add eax, r9d + */ + EXPECT_EQ(3, ild(u"D☺╚")); +} + +TEST(x86ild, test_41FFCF) { + /* + ICLASS: DEC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: DEC_GPRv_FFr1 + ISA_SET: I86 + SHORT: dec r15d + */ + EXPECT_EQ(3, ild(u"Aλ╧")); +} + +TEST(x86ild, test_41FFC7) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc r15d + */ + EXPECT_EQ(3, ild(u"Aλ╟")); +} + +TEST(x86ild, test_41FFC6) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc r14d + */ + EXPECT_EQ(3, ild(u"Aλ╞")); +} + +TEST(x86ild, test_41FFC2) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc r10d + */ + EXPECT_EQ(3, ild(u"Aλ┬")); +} + +TEST(x86ild, test_41FFC1) { + /* + ICLASS: INC + CATEGORY: BINARY + EXTENSION: BASE + IFORM: INC_GPRv_FFr0 + ISA_SET: I86 + SHORT: inc r9d + */ + EXPECT_EQ(3, ild(u"Aλ┴")); +} + +TEST(x86ild, test_4183FE00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp r14d, 0x0 + */ + EXPECT_EQ(4, ild(u"Aâ■ ")); +} + +TEST(x86ild, test_4183FB00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp r11d, 0x0 + */ + EXPECT_EQ(4, ild(u"Aâ√ ")); +} + +TEST(x86ild, test_4183F900) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp r9d, 0x0 + */ + EXPECT_EQ(4, ild(u"Aâ∙ ")); +} + +TEST(x86ild, test_4183F800) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMb + ISA_SET: I86 + SHORT: cmp r8d, 0x0 + */ + EXPECT_EQ(4, ild(u"Aâ° ")); +} + +TEST(x86ild, test_4181F800000000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_IMMz + ISA_SET: I86 + SHORT: cmp r8d, 0x0 + */ + EXPECT_EQ(7, ild(u"Aü°    ")); +} + +TEST(x86ild, test_4180F900) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPR8_IMMb_80r7 + ISA_SET: I86 + SHORT: cmp r9b, 0x0 + */ + EXPECT_EQ(4, ild(u"AÇ∙ ")); +} + +TEST(x86ild, test_41803C0000) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMb_IMMb_80r7 + ISA_SET: I86 + SHORT: cmp byte ptr [r8+rax*1], 0x0 + */ + EXPECT_EQ(5, ild(u"AÇ<  ")); +} + +TEST(x86ild, test_4139F5) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp r13d, esi + */ + EXPECT_EQ(3, ild(u"A9⌡")); +} + +TEST(x86ild, test_4139EE) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp r14d, ebp + */ + EXPECT_EQ(3, ild(u"A9ε")); +} + +TEST(x86ild, test_4139EC) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp r12d, ebp + */ + EXPECT_EQ(3, ild(u"A9∞")); +} + +TEST(x86ild, test_4139DD) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp r13d, ebx + */ + EXPECT_EQ(3, ild(u"A9▌")); +} + +TEST(x86ild, test_4139D1) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp r9d, edx + */ + EXPECT_EQ(3, ild(u"A9╤")); +} + +TEST(x86ild, test_4139D0) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp r8d, edx + */ + EXPECT_EQ(3, ild(u"A9╨")); +} + +TEST(x86ild, test_4139C6) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp r14d, eax + */ + EXPECT_EQ(3, ild(u"A9╞")); +} + +TEST(x86ild, test_4139C4) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp r12d, eax + */ + EXPECT_EQ(3, ild(u"A9─")); +} + +TEST(x86ild, test_4139C1) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp r9d, eax + */ + EXPECT_EQ(3, ild(u"A9┴")); +} + +TEST(x86ild, test_4138ED) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPR8_GPR8_38 + ISA_SET: I86 + SHORT: cmp r13b, bpl + */ + EXPECT_EQ(3, ild(u"A8φ")); +} + +TEST(x86ild, test_4129CC) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_GPRv_29 + ISA_SET: I86 + SHORT: sub r12d, ecx + */ + EXPECT_EQ(3, ild(u"A)╠")); +} + +TEST(x86ild, test_4038F1) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPR8_GPR8_38 + ISA_SET: I86 + SHORT: cmp cl, sil + */ + EXPECT_EQ(3, ild(u"@8±")); +} + +TEST(x86ild, test_3A5300) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPR8_MEMb + ISA_SET: I86 + SHORT: cmp dl, byte ptr [rbx] + */ + EXPECT_EQ(3, ild(u":S ")); +} + +TEST(x86ild, test_3A4B00) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPR8_MEMb + ISA_SET: I86 + SHORT: cmp cl, byte ptr [rbx] + */ + EXPECT_EQ(3, ild(u":K ")); +} + +TEST(x86ild, test_3A4300) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPR8_MEMb + ISA_SET: I86 + SHORT: cmp al, byte ptr [rbx] + */ + EXPECT_EQ(3, ild(u":C ")); +} + +TEST(x86ild, test_39F9) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp ecx, edi + */ + EXPECT_EQ(2, ild(u"9∙")); +} + +TEST(x86ild, test_39F7) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp edi, esi + */ + EXPECT_EQ(2, ild(u"9≈")); +} + +TEST(x86ild, test_39EB) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp ebx, ebp + */ + EXPECT_EQ(2, ild(u"9δ")); +} + +TEST(x86ild, test_39D8) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp eax, ebx + */ + EXPECT_EQ(2, ild(u"9╪")); +} + +TEST(x86ild, test_39CA) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp edx, ecx + */ + EXPECT_EQ(2, ild(u"9╩")); +} + +TEST(x86ild, test_39C5) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp ebp, eax + */ + EXPECT_EQ(2, ild(u"9┼")); +} + +TEST(x86ild, test_39C3) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_GPRv_GPRv_39 + ISA_SET: I86 + SHORT: cmp ebx, eax + */ + EXPECT_EQ(2, ild(u"9├")); +} + +TEST(x86ild, test_385700) { + /* + ICLASS: CMP + CATEGORY: BINARY + EXTENSION: BASE + IFORM: CMP_MEMb_GPR8 + ISA_SET: I86 + SHORT: cmp byte ptr [rdi], dl + */ + EXPECT_EQ(3, ild(u"8W ")); +} + +TEST(x86ild, test_29E8) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_GPRv_29 + ISA_SET: I86 + SHORT: sub eax, ebp + */ + EXPECT_EQ(2, ild(u")Φ")); +} + +TEST(x86ild, test_29DD) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_GPRv_29 + ISA_SET: I86 + SHORT: sub ebp, ebx + */ + EXPECT_EQ(2, ild(u")▌")); +} + +TEST(x86ild, test_29C5) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_GPRv_29 + ISA_SET: I86 + SHORT: sub ebp, eax + */ + EXPECT_EQ(2, ild(u")┼")); +} + +TEST(x86ild, test_29C3) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_GPRv_29 + ISA_SET: I86 + SHORT: sub ebx, eax + */ + EXPECT_EQ(2, ild(u")├")); +} + +TEST(x86ild, test_29C2) { + /* + ICLASS: SUB + CATEGORY: BINARY + EXTENSION: BASE + IFORM: SUB_GPRv_GPRv_29 + ISA_SET: I86 + SHORT: sub edx, eax + */ + EXPECT_EQ(2, ild(u")┬")); +} + +TEST(x86ild, test_01FE) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add esi, edi + */ + EXPECT_EQ(2, ild(u"☺■")); +} + +TEST(x86ild, test_01F0) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add eax, esi + */ + EXPECT_EQ(2, ild(u"☺≡")); +} + +TEST(x86ild, test_01D6) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add esi, edx + */ + EXPECT_EQ(2, ild(u"☺╓")); +} + +TEST(x86ild, test_01C9) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add ecx, ecx + */ + EXPECT_EQ(2, ild(u"☺╔")); +} + +TEST(x86ild, test_01C8) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add eax, ecx + */ + EXPECT_EQ(2, ild(u"☺╚")); +} + +TEST(x86ild, test_01C5) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add ebp, eax + */ + EXPECT_EQ(2, ild(u"☺┼")); +} + +TEST(x86ild, test_01C2) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPRv_GPRv_01 + ISA_SET: I86 + SHORT: add edx, eax + */ + EXPECT_EQ(2, ild(u"☺┬")); +} + +TEST(x86ild, test_01B000000000) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_MEMv_GPRv + ISA_SET: I86 + SHORT: add dword ptr [rax], esi + */ + EXPECT_EQ(6, ild(u"☺░    ")); +} + +TEST(x86ild, test_00C1) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_GPR8_GPR8_00 + ISA_SET: I86 + SHORT: add cl, al + */ + EXPECT_EQ(2, ild(u" ┴")); +} + +TEST(x86ild, test_00B800000000) { + /* + ICLASS: ADD + CATEGORY: BINARY + EXTENSION: BASE + IFORM: ADD_MEMb_GPR8 + ISA_SET: I86 + SHORT: add byte ptr [rax], bh + */ + EXPECT_EQ(6, ild(u" ╕    ")); +} diff --git a/test/libc/xed/x86ild_popular_cmov_test.c b/test/libc/xed/x86ild_popular_cmov_test.c new file mode 100644 index 00000000..ddb6a001 --- /dev/null +++ b/test/libc/xed/x86ild_popular_cmov_test.c @@ -0,0 +1,226 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/testlib.h" +#include "test/libc/xed/lib.h" +#include "third_party/xed/x86.h" + +TEST(x86ild, test_0F45C2) { + /* + ICLASS: CMOVNZ + CATEGORY: CMOV + EXTENSION: BASE + IFORM: CMOVNZ_GPRv_GPRv + ISA_SET: CMOV + SHORT: cmovnz eax, edx + */ + ASSERT_EQ(3, ild(u"☼E┬")); +} + +TEST(x86ild, test_0F47F8) { + /* + ICLASS: CMOVNBE + CATEGORY: CMOV + EXTENSION: BASE + IFORM: CMOVNBE_GPRv_GPRv + ISA_SET: CMOV + SHORT: cmovnbe edi, eax + */ + ASSERT_EQ(3, ild(u"☼G°")); +} + +TEST(x86ild, test_480F44F0) { + /* + ICLASS: CMOVZ + CATEGORY: CMOV + EXTENSION: BASE + IFORM: CMOVZ_GPRv_GPRv + ISA_SET: CMOV + SHORT: cmovz rsi, rax + */ + ASSERT_EQ(4, ild(u"H☼D≡")); +} + +TEST(x86ild, test_0F44C2) { + /* + ICLASS: CMOVZ + CATEGORY: CMOV + EXTENSION: BASE + IFORM: CMOVZ_GPRv_GPRv + ISA_SET: CMOV + SHORT: cmovz eax, edx + */ + ASSERT_EQ(3, ild(u"☼D┬")); +} + +TEST(x86ild, test_0F47E8) { + /* + ICLASS: CMOVNBE + CATEGORY: CMOV + EXTENSION: BASE + IFORM: CMOVNBE_GPRv_GPRv + ISA_SET: CMOV + SHORT: cmovnbe ebp, eax + */ + ASSERT_EQ(3, ild(u"☼GΦ")); +} + +TEST(x86ild, test_0F45C3) { + /* + ICLASS: CMOVNZ + CATEGORY: CMOV + EXTENSION: BASE + IFORM: CMOVNZ_GPRv_GPRv + ISA_SET: CMOV + SHORT: cmovnz eax, ebx + */ + ASSERT_EQ(3, ild(u"☼E├")); +} + +TEST(x86ild, test_0F44C7) { + /* + ICLASS: CMOVZ + CATEGORY: CMOV + EXTENSION: BASE + IFORM: CMOVZ_GPRv_GPRv + ISA_SET: CMOV + SHORT: cmovz eax, edi + */ + ASSERT_EQ(3, ild(u"☼D╟")); +} + +TEST(x86ild, test_480F44F2) { + /* + ICLASS: CMOVZ + CATEGORY: CMOV + EXTENSION: BASE + IFORM: CMOVZ_GPRv_GPRv + ISA_SET: CMOV + SHORT: cmovz rsi, rdx + */ + ASSERT_EQ(4, ild(u"H☼D≥")); +} + +TEST(x86ild, test_480F44C7) { + /* + ICLASS: CMOVZ + CATEGORY: CMOV + EXTENSION: BASE + IFORM: CMOVZ_GPRv_GPRv + ISA_SET: CMOV + SHORT: cmovz rax, rdi + */ + ASSERT_EQ(4, ild(u"H☼D╟")); +} + +TEST(x86ild, test_440F45F2) { + /* + ICLASS: CMOVNZ + CATEGORY: CMOV + EXTENSION: BASE + IFORM: CMOVNZ_GPRv_GPRv + ISA_SET: CMOV + SHORT: cmovnz r14d, edx + */ + ASSERT_EQ(4, ild(u"D☼E≥")); +} + +TEST(x86ild, test_440F45F0) { + /* + ICLASS: CMOVNZ + CATEGORY: CMOV + EXTENSION: BASE + IFORM: CMOVNZ_GPRv_GPRv + ISA_SET: CMOV + SHORT: cmovnz r14d, eax + */ + ASSERT_EQ(4, ild(u"D☼E≡")); +} + +TEST(x86ild, test_0F4DC8) { + /* + ICLASS: CMOVNL + CATEGORY: CMOV + EXTENSION: BASE + IFORM: CMOVNL_GPRv_GPRv + ISA_SET: CMOV + SHORT: cmovnl ecx, eax + */ + ASSERT_EQ(3, ild(u"☼M╚")); +} + +TEST(x86ild, test_0F46D8) { + /* + ICLASS: CMOVBE + CATEGORY: CMOV + EXTENSION: BASE + IFORM: CMOVBE_GPRv_GPRv + ISA_SET: CMOV + SHORT: cmovbe ebx, eax + */ + ASSERT_EQ(3, ild(u"☼F╪")); +} + +TEST(x86ild, test_0F46CF) { + /* + ICLASS: CMOVBE + CATEGORY: CMOV + EXTENSION: BASE + IFORM: CMOVBE_GPRv_GPRv + ISA_SET: CMOV + SHORT: cmovbe ecx, edi + */ + ASSERT_EQ(3, ild(u"☼F╧")); +} + +TEST(x86ild, test_0F46C1) { + /* + ICLASS: CMOVBE + CATEGORY: CMOV + EXTENSION: BASE + IFORM: CMOVBE_GPRv_GPRv + ISA_SET: CMOV + SHORT: cmovbe eax, ecx + */ + ASSERT_EQ(3, ild(u"☼F┴")); +} + +TEST(x86ild, test_0F45C6) { + /* + ICLASS: CMOVNZ + CATEGORY: CMOV + EXTENSION: BASE + IFORM: CMOVNZ_GPRv_GPRv + ISA_SET: CMOV + SHORT: cmovnz eax, esi + */ + ASSERT_EQ(3, ild(u"☼E╞")); +} + +TEST(x86ild, test_0F44D0) { + /* + ICLASS: CMOVZ + CATEGORY: CMOV + EXTENSION: BASE + IFORM: CMOVZ_GPRv_GPRv + ISA_SET: CMOV + SHORT: cmovz edx, eax + */ + ASSERT_EQ(3, ild(u"☼D╨")); +} diff --git a/test/libc/xed/x86ild_popular_i186_test.c b/test/libc/xed/x86ild_popular_i186_test.c new file mode 100644 index 00000000..c70568c0 --- /dev/null +++ b/test/libc/xed/x86ild_popular_i186_test.c @@ -0,0 +1,830 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/testlib.h" +#include "test/libc/xed/lib.h" +#include "third_party/xed/x86.h" + +/** + * @fileoverview GCC's popular i186+ instruction w/ NexGen32e encoding. + */ + +TEST(x86ild, test_C0E800) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPR8_IMMb + ISA_SET: I186 + SHORT: shr al, 0x0 + */ + ASSERT_EQ(3, ild(u"└Φ ")); +} + +TEST(x86ild, test_C1EE00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr esi, 0x0 + */ + ASSERT_EQ(3, ild(u"┴ε ")); +} + +TEST(x86ild, test_48C1E000) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl rax, 0x0 + */ + ASSERT_EQ(4, ild(u"H┴α ")); +} + +TEST(x86ild, test_66C1EE00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr si, 0x0 + */ + ASSERT_EQ(4, ild(u"f┴ε ")); +} + +TEST(x86ild, test_486BC000) { + /* + ICLASS: IMUL + CATEGORY: BINARY + EXTENSION: BASE + IFORM: IMUL_GPRv_GPRv_IMMb + ISA_SET: I186 + SHORT: imul rax, rax, 0x0 + */ + ASSERT_EQ(4, ild(u"Hk└ ")); +} + +TEST(x86ild, test_C1E000) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl eax, 0x0 + */ + ASSERT_EQ(3, ild(u"┴α ")); +} + +TEST(x86ild, test_486BED00) { + /* + ICLASS: IMUL + CATEGORY: BINARY + EXTENSION: BASE + IFORM: IMUL_GPRv_GPRv_IMMb + ISA_SET: I186 + SHORT: imul rbp, rbp, 0x0 + */ + ASSERT_EQ(4, ild(u"Hkφ ")); +} + +TEST(x86ild, test_69D000000000) { + /* + ICLASS: IMUL + CATEGORY: BINARY + EXTENSION: BASE + IFORM: IMUL_GPRv_GPRv_IMMz + ISA_SET: I186 + SHORT: imul edx, eax, 0x0 + */ + ASSERT_EQ(6, ild(u"i╨    ")); +} + +TEST(x86ild, test_48C1EA00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr rdx, 0x0 + */ + ASSERT_EQ(4, ild(u"H┴Ω ")); +} + +TEST(x86ild, test_C0EA00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPR8_IMMb + ISA_SET: I186 + SHORT: shr dl, 0x0 + */ + ASSERT_EQ(3, ild(u"└Ω ")); +} + +TEST(x86ild, test_C1E200) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl edx, 0x0 + */ + ASSERT_EQ(3, ild(u"┴Γ ")); +} + +TEST(x86ild, test_C1E600) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl esi, 0x0 + */ + ASSERT_EQ(3, ild(u"┴μ ")); +} + +TEST(x86ild, test_66C1EA00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr dx, 0x0 + */ + ASSERT_EQ(4, ild(u"f┴Ω ")); +} + +TEST(x86ild, test_486BD200) { + /* + ICLASS: IMUL + CATEGORY: BINARY + EXTENSION: BASE + IFORM: IMUL_GPRv_GPRv_IMMb + ISA_SET: I186 + SHORT: imul rdx, rdx, 0x0 + */ + ASSERT_EQ(4, ild(u"Hk╥ ")); +} + +TEST(x86ild, test_C0EA83) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPR8_IMMb + ISA_SET: I186 + SHORT: shr dl, 0x83 + */ + ASSERT_EQ(3, ild(u"└Ωâ")); +} + +TEST(x86ild, test_C1E800) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr eax, 0x0 + */ + ASSERT_EQ(3, ild(u"┴Φ ")); +} + +TEST(x86ild, test_C1EA00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr edx, 0x0 + */ + ASSERT_EQ(3, ild(u"┴Ω ")); +} + +TEST(x86ild, test_48C1E500) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl rbp, 0x0 + */ + ASSERT_EQ(4, ild(u"H┴σ ")); +} + +TEST(x86ild, test_66C1E800) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr ax, 0x0 + */ + ASSERT_EQ(4, ild(u"f┴Φ ")); +} + +TEST(x86ild, test_C1E700) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl edi, 0x0 + */ + ASSERT_EQ(3, ild(u"┴τ ")); +} + +TEST(x86ild, test_C0E900) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPR8_IMMb + ISA_SET: I186 + SHORT: shr cl, 0x0 + */ + ASSERT_EQ(3, ild(u"└Θ ")); +} + +TEST(x86ild, test_C1E100) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl ecx, 0x0 + */ + ASSERT_EQ(3, ild(u"┴ß ")); +} + +TEST(x86ild, test_48C1E200) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl rdx, 0x0 + */ + ASSERT_EQ(4, ild(u"H┴Γ ")); +} + +TEST(x86ild, test_40C0EE00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPR8_IMMb + ISA_SET: I186 + SHORT: shr sil, 0x0 + */ + ASSERT_EQ(4, ild(u"@└ε ")); +} + +TEST(x86ild, test_69C000000000) { + /* + ICLASS: IMUL + CATEGORY: BINARY + EXTENSION: BASE + IFORM: IMUL_GPRv_GPRv_IMMz + ISA_SET: I186 + SHORT: imul eax, eax, 0x0 + */ + ASSERT_EQ(6, ild(u"i└    ")); +} + +TEST(x86ild, test_48C1E800) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr rax, 0x0 + */ + ASSERT_EQ(4, ild(u"H┴Φ ")); +} + +TEST(x86ild, test_C0E883) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPR8_IMMb + ISA_SET: I186 + SHORT: shr al, 0x83 + */ + ASSERT_EQ(3, ild(u"└Φâ")); +} + +TEST(x86ild, test_48C1E100) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl rcx, 0x0 + */ + ASSERT_EQ(4, ild(u"H┴ß ")); +} + +TEST(x86ild, test_4869C000000000) { + /* + ICLASS: IMUL + CATEGORY: BINARY + EXTENSION: BASE + IFORM: IMUL_GPRv_GPRv_IMMz + ISA_SET: I186 + SHORT: imul rax, rax, 0x0 + */ + ASSERT_EQ(7, ild(u"Hi└    ")); +} + +TEST(x86ild, test_48C1E700) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl rdi, 0x0 + */ + ASSERT_EQ(4, ild(u"H┴τ ")); +} + +TEST(x86ild, test_41C0E800) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPR8_IMMb + ISA_SET: I186 + SHORT: shr r8b, 0x0 + */ + ASSERT_EQ(4, ild(u"A└Φ ")); +} + +TEST(x86ild, test_C0E8C0) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPR8_IMMb + ISA_SET: I186 + SHORT: shr al, 0xc0 + */ + ASSERT_EQ(3, ild(u"└Φ└")); +} + +TEST(x86ild, test_C0EA66) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPR8_IMMb + ISA_SET: I186 + SHORT: shr dl, 0x66 + */ + ASSERT_EQ(3, ild(u"└Ωf")); +} + +TEST(x86ild, test_48C1E600) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl rsi, 0x0 + */ + ASSERT_EQ(4, ild(u"H┴μ ")); +} + +TEST(x86ild, test_C0E848) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPR8_IMMb + ISA_SET: I186 + SHORT: shr al, 0x48 + */ + ASSERT_EQ(3, ild(u"└ΦH")); +} + +TEST(x86ild, test_4869D200000000) { + /* + ICLASS: IMUL + CATEGORY: BINARY + EXTENSION: BASE + IFORM: IMUL_GPRv_GPRv_IMMz + ISA_SET: I186 + SHORT: imul rdx, rdx, 0x0 + */ + ASSERT_EQ(7, ild(u"Hi╥    ")); +} + +TEST(x86ild, test_C1E900) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr ecx, 0x0 + */ + ASSERT_EQ(3, ild(u"┴Θ ")); +} + +TEST(x86ild, test_40C0ED00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPR8_IMMb + ISA_SET: I186 + SHORT: shr bpl, 0x0 + */ + ASSERT_EQ(4, ild(u"@└φ ")); +} + +TEST(x86ild, test_C1EF00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr edi, 0x0 + */ + ASSERT_EQ(3, ild(u"┴∩ ")); +} + +TEST(x86ild, test_66C1EF00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr di, 0x0 + */ + ASSERT_EQ(4, ild(u"f┴∩ ")); +} + +TEST(x86ild, test_486BCA00) { + /* + ICLASS: IMUL + CATEGORY: BINARY + EXTENSION: BASE + IFORM: IMUL_GPRv_GPRv_IMMb + ISA_SET: I186 + SHORT: imul rcx, rdx, 0x0 + */ + ASSERT_EQ(4, ild(u"Hk╩ ")); +} + +TEST(x86ild, test_41C1EA00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr r10d, 0x0 + */ + ASSERT_EQ(4, ild(u"A┴Ω ")); +} + +TEST(x86ild, test_41C1E000) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl r8d, 0x0 + */ + ASSERT_EQ(4, ild(u"A┴α ")); +} + +TEST(x86ild, test_40C0EF00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPR8_IMMb + ISA_SET: I186 + SHORT: shr dil, 0x0 + */ + ASSERT_EQ(4, ild(u"@└∩ ")); +} + +TEST(x86ild, test_49C1E000) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl r8, 0x0 + */ + ASSERT_EQ(4, ild(u"I┴α ")); +} + +TEST(x86ild, test_41C1E800) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr r8d, 0x0 + */ + ASSERT_EQ(4, ild(u"A┴Φ ")); +} + +TEST(x86ild, test_41C1E200) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl r10d, 0x0 + */ + ASSERT_EQ(4, ild(u"A┴Γ ")); +} + +TEST(x86ild, test_41C0E900) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPR8_IMMb + ISA_SET: I186 + SHORT: shr r9b, 0x0 + */ + ASSERT_EQ(4, ild(u"A└Θ ")); +} + +TEST(x86ild, test_C0EAC0) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPR8_IMMb + ISA_SET: I186 + SHORT: shr dl, 0xc0 + */ + ASSERT_EQ(3, ild(u"└Ω└")); +} + +TEST(x86ild, test_66C1E900) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr cx, 0x0 + */ + ASSERT_EQ(4, ild(u"f┴Θ ")); +} + +TEST(x86ild, test_48C1F800) { + /* + ICLASS: SAR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SAR_GPRv_IMMb + ISA_SET: I186 + SHORT: sar rax, 0x0 + */ + ASSERT_EQ(4, ild(u"H┴° ")); +} + +TEST(x86ild, test_41C1EB00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr r11d, 0x0 + */ + ASSERT_EQ(4, ild(u"A┴δ ")); +} + +TEST(x86ild, test_41C1E300) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl r11d, 0x0 + */ + ASSERT_EQ(4, ild(u"A┴π ")); +} + +TEST(x86ild, test_C1ED00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr ebp, 0x0 + */ + ASSERT_EQ(3, ild(u"┴φ ")); +} + +TEST(x86ild, test_C1EB00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr ebx, 0x0 + */ + ASSERT_EQ(3, ild(u"┴δ ")); +} + +TEST(x86ild, test_C1E500) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl ebp, 0x0 + */ + ASSERT_EQ(3, ild(u"┴σ ")); +} + +TEST(x86ild, test_69D800000000) { + /* + ICLASS: IMUL + CATEGORY: BINARY + EXTENSION: BASE + IFORM: IMUL_GPRv_GPRv_IMMz + ISA_SET: I186 + SHORT: imul ebx, eax, 0x0 + */ + ASSERT_EQ(6, ild(u"i╪    ")); +} + +TEST(x86ild, test_6641C1EE00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr r14w, 0x0 + */ + ASSERT_EQ(5, ild(u"fA┴ε ")); +} + +TEST(x86ild, test_6641C1ED00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr r13w, 0x0 + */ + ASSERT_EQ(5, ild(u"fA┴φ ")); +} + +TEST(x86ild, test_6641C1E800) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr r8w, 0x0 + */ + ASSERT_EQ(5, ild(u"fA┴Φ ")); +} + +TEST(x86ild, test_49C1E100) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl r9, 0x0 + */ + ASSERT_EQ(4, ild(u"I┴ß ")); +} + +TEST(x86ild, test_48C1FE74) { + /* + ICLASS: SAR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SAR_GPRv_IMMb + ISA_SET: I186 + SHORT: sar rsi, 0x74 + */ + ASSERT_EQ(4, ild(u"H┴■t")); +} + +TEST(x86ild, test_48C1FE00) { + /* + ICLASS: SAR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SAR_GPRv_IMMb + ISA_SET: I186 + SHORT: sar rsi, 0x0 + */ + ASSERT_EQ(4, ild(u"H┴■ ")); +} + +TEST(x86ild, test_48C1FB00) { + /* + ICLASS: SAR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SAR_GPRv_IMMb + ISA_SET: I186 + SHORT: sar rbx, 0x0 + */ + ASSERT_EQ(4, ild(u"H┴√ ")); +} + +TEST(x86ild, test_41C1EE00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr r14d, 0x0 + */ + ASSERT_EQ(4, ild(u"A┴ε ")); +} + +TEST(x86ild, test_41C1EC00) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_IMMb + ISA_SET: I186 + SHORT: shr r12d, 0x0 + */ + ASSERT_EQ(4, ild(u"A┴∞ ")); +} + +TEST(x86ild, test_41C1E700) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_IMMb_C1r4 + ISA_SET: I186 + SHORT: shl r15d, 0x0 + */ + ASSERT_EQ(4, ild(u"A┴τ ")); +} diff --git a/test/libc/xed/x86ild_popular_i386_test.c b/test/libc/xed/x86ild_popular_i386_test.c new file mode 100644 index 00000000..3343f009 --- /dev/null +++ b/test/libc/xed/x86ild_popular_i386_test.c @@ -0,0 +1,1754 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/testlib.h" +#include "test/libc/xed/lib.h" +#include "third_party/xed/x86.h" + +/** + * @fileoverview GCC's popular i386+ instruction w/ NexGen32e encoding. + */ + +TEST(x86ild, test_400FB6C5) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx eax, bpl + */ + ASSERT_EQ(4, ild(u"@☼╢┼")); +} + +TEST(x86ild, test_0FB6C0) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx eax, al + */ + ASSERT_EQ(3, ild(u"☼╢└")); +} + +TEST(x86ild, test_0FB6E8) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx ebp, al + */ + ASSERT_EQ(3, ild(u"☼╢Φ")); +} + +TEST(x86ild, test_0F95C0) { + /* + ICLASS: SETNZ + CATEGORY: SETCC + EXTENSION: BASE + IFORM: SETNZ_GPR8 + ISA_SET: I386 + SHORT: setnz al + */ + ASSERT_EQ(3, ild(u"☼ò└")); +} + +TEST(x86ild, test_0F94C0) { + /* + ICLASS: SETZ + CATEGORY: SETCC + EXTENSION: BASE + IFORM: SETZ_GPR8 + ISA_SET: I386 + SHORT: setz al + */ + ASSERT_EQ(3, ild(u"☼ö└")); +} + +TEST(x86ild, test_400FB6D5) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx edx, bpl + */ + ASSERT_EQ(4, ild(u"@☼╢╒")); +} + +TEST(x86ild, test_0FB6D0) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx edx, al + */ + ASSERT_EQ(3, ild(u"☼╢╨")); +} + +TEST(x86ild, test_0F95C2) { + /* + ICLASS: SETNZ + CATEGORY: SETCC + EXTENSION: BASE + IFORM: SETNZ_GPR8 + ISA_SET: I386 + SHORT: setnz dl + */ + ASSERT_EQ(3, ild(u"☼ò┬")); +} + +TEST(x86ild, test_0F94C2) { + /* + ICLASS: SETZ + CATEGORY: SETCC + EXTENSION: BASE + IFORM: SETZ_GPR8 + ISA_SET: I386 + SHORT: setz dl + */ + ASSERT_EQ(3, ild(u"☼ö┬")); +} + +TEST(x86ild, test_0FB6D2) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx edx, dl + */ + ASSERT_EQ(3, ild(u"☼╢╥")); +} + +TEST(x86ild, test_0FBE841200000000) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_MEMb + ISA_SET: I386 + SHORT: movsx eax, byte ptr [rdx+rdx*1] + */ + ASSERT_EQ(8, ild(u"☼╛ä↕    ")); +} + +TEST(x86ild, test_0FB64000) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx eax, byte ptr [rax] + */ + ASSERT_EQ(4, ild(u"☼╢@ ")); +} + +TEST(x86ild, test_0FBE04D500000000) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_MEMb + ISA_SET: I386 + SHORT: movsx eax, byte ptr [rdx*8] + */ + ASSERT_EQ(8, ild(u"☼╛♦╒    ")); +} + +TEST(x86ild, test_0FBE8000000000) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_MEMb + ISA_SET: I386 + SHORT: movsx eax, byte ptr [rax] + */ + ASSERT_EQ(7, ild(u"☼╛Ç    ")); +} + +TEST(x86ild, test_0FB64800) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx ecx, byte ptr [rax] + */ + ASSERT_EQ(4, ild(u"☼╢H ")); +} + +TEST(x86ild, test_0FB64700) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx eax, byte ptr [rdi] + */ + ASSERT_EQ(4, ild(u"☼╢G ")); +} + +TEST(x86ild, test_0FB65700) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx edx, byte ptr [rdi] + */ + ASSERT_EQ(4, ild(u"☼╢W ")); +} + +TEST(x86ild, test_0FB6C2) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx eax, dl + */ + ASSERT_EQ(3, ild(u"☼╢┬")); +} + +TEST(x86ild, test_0FB67000) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx esi, byte ptr [rax] + */ + ASSERT_EQ(4, ild(u"☼╢p ")); +} + +TEST(x86ild, test_0FB68000000000) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx eax, byte ptr [rax] + */ + ASSERT_EQ(7, ild(u"☼╢Ç    ")); +} + +TEST(x86ild, test_0FB6C9) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx ecx, cl + */ + ASSERT_EQ(3, ild(u"☼╢╔")); +} + +TEST(x86ild, test_0FBE4100) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_MEMb + ISA_SET: I386 + SHORT: movsx eax, byte ptr [rcx] + */ + ASSERT_EQ(4, ild(u"☼╛A ")); +} + +TEST(x86ild, test_0F94C1) { + /* + ICLASS: SETZ + CATEGORY: SETCC + EXTENSION: BASE + IFORM: SETZ_GPR8 + ISA_SET: I386 + SHORT: setz cl + */ + ASSERT_EQ(3, ild(u"☼ö┴")); +} + +TEST(x86ild, test_0FB6841200000000) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx eax, byte ptr [rdx+rdx*1] + */ + ASSERT_EQ(8, ild(u"☼╢ä↕    ")); +} + +TEST(x86ild, test_400FB6F6) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx esi, sil + */ + ASSERT_EQ(4, ild(u"@☼╢÷")); +} + +TEST(x86ild, test_0FBAE500) { + /* + ICLASS: BT + CATEGORY: BITBYTE + EXTENSION: BASE + IFORM: BT_GPRv_IMMb + ISA_SET: I386 + SHORT: bt ebp, 0x0 + */ + ASSERT_EQ(4, ild(u"☼║σ ")); +} + +TEST(x86ild, test_0FB6C1) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx eax, cl + */ + ASSERT_EQ(3, ild(u"☼╢┴")); +} + +TEST(x86ild, test_0FBE4600) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_MEMb + ISA_SET: I386 + SHORT: movsx eax, byte ptr [rsi] + */ + ASSERT_EQ(4, ild(u"☼╛F ")); +} + +TEST(x86ild, test_0FB77800) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMw + ISA_SET: I386 + SHORT: movzx edi, word ptr [rax] + */ + ASSERT_EQ(4, ild(u"☼╖x ")); +} + +TEST(x86ild, test_0FB68700000000) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx eax, byte ptr [rdi] + */ + ASSERT_EQ(7, ild(u"☼╢ç    ")); +} + +TEST(x86ild, test_0FB67F00) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx edi, byte ptr [rdi] + */ + ASSERT_EQ(4, ild(u"☼╢⌂ ")); +} + +TEST(x86ild, test_0FB64F00) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx ecx, byte ptr [rdi] + */ + ASSERT_EQ(4, ild(u"☼╢O ")); +} + +TEST(x86ild, test_0FB604D500000000) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx eax, byte ptr [rdx*8] + */ + ASSERT_EQ(8, ild(u"☼╢♦╒    ")); +} + +TEST(x86ild, test_0FB78000000000) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMw + ISA_SET: I386 + SHORT: movzx eax, word ptr [rax] + */ + ASSERT_EQ(7, ild(u"☼╖Ç    ")); +} + +TEST(x86ild, test_0FB74700) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMw + ISA_SET: I386 + SHORT: movzx eax, word ptr [rdi] + */ + ASSERT_EQ(4, ild(u"☼╖G ")); +} + +TEST(x86ild, test_0F96C0) { + /* + ICLASS: SETBE + CATEGORY: SETCC + EXTENSION: BASE + IFORM: SETBE_GPR8 + ISA_SET: I386 + SHORT: setbe al + */ + ASSERT_EQ(3, ild(u"☼û└")); +} + +TEST(x86ild, test_0FB74500) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMw + ISA_SET: I386 + SHORT: movzx eax, word ptr [rbp] + */ + ASSERT_EQ(4, ild(u"☼╖E ")); +} + +TEST(x86ild, test_0FB6C8) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx ecx, al + */ + ASSERT_EQ(3, ild(u"☼╢╚")); +} + +TEST(x86ild, test_440FB67500) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx r14d, byte ptr [rbp] + */ + ASSERT_EQ(5, ild(u"D☼╢u ")); +} + +TEST(x86ild, test_0FBE5600) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_MEMb + ISA_SET: I386 + SHORT: movsx edx, byte ptr [rsi] + */ + ASSERT_EQ(4, ild(u"☼╛V ")); +} + +TEST(x86ild, test_0FB7F6) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR16 + ISA_SET: I386 + SHORT: movzx esi, si + */ + ASSERT_EQ(3, ild(u"☼╖÷")); +} + +TEST(x86ild, test_0FB7840000000000) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMw + ISA_SET: I386 + SHORT: movzx eax, word ptr [rax+rax*1] + */ + ASSERT_EQ(8, ild(u"☼╖ä     ")); +} + +TEST(x86ild, test_0FB67D00) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx edi, byte ptr [rbp] + */ + ASSERT_EQ(4, ild(u"☼╢} ")); +} + +TEST(x86ild, test_0FB64B00) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx ecx, byte ptr [rbx] + */ + ASSERT_EQ(4, ild(u"☼╢K ")); +} + +TEST(x86ild, test_0FB64300) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx eax, byte ptr [rbx] + */ + ASSERT_EQ(4, ild(u"☼╢C ")); +} + +TEST(x86ild, test_0FB64100) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx eax, byte ptr [rcx] + */ + ASSERT_EQ(4, ild(u"☼╢A ")); +} + +TEST(x86ild, test_F3AB) { + /* + ICLASS: REP_STOSD + CATEGORY: STRINGOP + EXTENSION: BASE + IFORM: REP_STOSD + ISA_SET: I386 + SHORT: rep stosd dword ptr [rdi] + */ + ASSERT_EQ(2, ild(u"≤½")); +} + +TEST(x86ild, test_480FBE04D500000000) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_MEMb + ISA_SET: I386 + SHORT: movsx rax, byte ptr [rdx*8] + */ + ASSERT_EQ(9, ild(u"H☼╛♦╒    ")); +} + +TEST(x86ild, test_400FB6CD) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx ecx, bpl + */ + ASSERT_EQ(4, ild(u"@☼╢═")); +} + +TEST(x86ild, test_400FB6C7) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx eax, dil + */ + ASSERT_EQ(4, ild(u"@☼╢╟")); +} + +TEST(x86ild, test_0FBE4E00) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_MEMb + ISA_SET: I386 + SHORT: movsx ecx, byte ptr [rsi] + */ + ASSERT_EQ(4, ild(u"☼╛N ")); +} + +TEST(x86ild, test_0FBE0CD500000000) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_MEMb + ISA_SET: I386 + SHORT: movsx ecx, byte ptr [rdx*8] + */ + ASSERT_EQ(8, ild(u"☼╛♀╒    ")); +} + +TEST(x86ild, test_0FB7C0) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR16 + ISA_SET: I386 + SHORT: movzx eax, ax + */ + ASSERT_EQ(3, ild(u"☼╖└")); +} + +TEST(x86ild, test_0FB6CA) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx ecx, dl + */ + ASSERT_EQ(3, ild(u"☼╢╩")); +} + +TEST(x86ild, test_0FB68200000000) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx eax, byte ptr [rdx] + */ + ASSERT_EQ(7, ild(u"☼╢é    ")); +} + +TEST(x86ild, test_0FB67300) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx esi, byte ptr [rbx] + */ + ASSERT_EQ(4, ild(u"☼╢s ")); +} + +TEST(x86ild, test_0FB65300) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx edx, byte ptr [rbx] + */ + ASSERT_EQ(4, ild(u"☼╢S ")); +} + +TEST(x86ild, test_450FB6C0) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx r8d, r8b + */ + ASSERT_EQ(4, ild(u"E☼╢└")); +} + +TEST(x86ild, test_0FBE8100000000) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_MEMb + ISA_SET: I386 + SHORT: movsx eax, byte ptr [rcx] + */ + ASSERT_EQ(7, ild(u"☼╛ü    ")); +} + +TEST(x86ild, test_0FBE4F00) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_MEMb + ISA_SET: I386 + SHORT: movsx ecx, byte ptr [rdi] + */ + ASSERT_EQ(4, ild(u"☼╛O ")); +} + +TEST(x86ild, test_0FBE4700) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_MEMb + ISA_SET: I386 + SHORT: movsx eax, byte ptr [rdi] + */ + ASSERT_EQ(4, ild(u"☼╛G ")); +} + +TEST(x86ild, test_0FBE049500000000) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_MEMb + ISA_SET: I386 + SHORT: movsx eax, byte ptr [rdx*4] + */ + ASSERT_EQ(8, ild(u"☼╛♦ò    ")); +} + +TEST(x86ild, test_0FB7C7) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR16 + ISA_SET: I386 + SHORT: movzx eax, di + */ + ASSERT_EQ(3, ild(u"☼╖╟")); +} + +TEST(x86ild, test_0FB75700) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMw + ISA_SET: I386 + SHORT: movzx edx, word ptr [rdi] + */ + ASSERT_EQ(4, ild(u"☼╖W ")); +} + +TEST(x86ild, test_0FB6742400) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx esi, byte ptr [rsp] + */ + ASSERT_EQ(5, ild(u"☼╢t$ ")); +} + +TEST(x86ild, test_0FB630) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx esi, byte ptr [rax] + */ + ASSERT_EQ(3, ild(u"☼╢0")); +} + +TEST(x86ild, test_0FB62F) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx ebp, byte ptr [rdi] + */ + ASSERT_EQ(3, ild(u"☼╢/")); +} + +TEST(x86ild, test_0FB600) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx eax, byte ptr [rax] + */ + ASSERT_EQ(3, ild(u"☼╢ ")); +} + +TEST(x86ild, test_66400FBEC7) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movsx ax, dil + */ + ASSERT_EQ(5, ild(u"f@☼╛╟")); +} + +TEST(x86ild, test_480FBFF6) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_GPR16 + ISA_SET: I386 + SHORT: movsx rsi, si + */ + ASSERT_EQ(4, ild(u"H☼┐÷")); +} + +TEST(x86ild, test_480FBFC7) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_GPR16 + ISA_SET: I386 + SHORT: movsx rax, di + */ + ASSERT_EQ(4, ild(u"H☼┐╟")); +} + +TEST(x86ild, test_480FBF12) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_MEMw + ISA_SET: I386 + SHORT: movsx rdx, word ptr [rdx] + */ + ASSERT_EQ(4, ild(u"H☼┐↕")); +} + +TEST(x86ild, test_480FBEF6) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movsx rsi, sil + */ + ASSERT_EQ(4, ild(u"H☼╛÷")); +} + +TEST(x86ild, test_480FBEC7) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movsx rax, dil + */ + ASSERT_EQ(4, ild(u"H☼╛╟")); +} + +TEST(x86ild, test_480FBE12) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_MEMb + ISA_SET: I386 + SHORT: movsx rdx, byte ptr [rdx] + */ + ASSERT_EQ(4, ild(u"H☼╛↕")); +} + +TEST(x86ild, test_480FA3D1) { + /* + ICLASS: BT + CATEGORY: BITBYTE + EXTENSION: BASE + IFORM: BT_GPRv_GPRv + ISA_SET: I386 + SHORT: bt rcx, rdx + */ + ASSERT_EQ(4, ild(u"H☼ú╤")); +} + +TEST(x86ild, test_480FA3D0) { + /* + ICLASS: BT + CATEGORY: BITBYTE + EXTENSION: BASE + IFORM: BT_GPRv_GPRv + ISA_SET: I386 + SHORT: bt rax, rdx + */ + ASSERT_EQ(4, ild(u"H☼ú╨")); +} + +TEST(x86ild, test_480FA3CE) { + /* + ICLASS: BT + CATEGORY: BITBYTE + EXTENSION: BASE + IFORM: BT_GPRv_GPRv + ISA_SET: I386 + SHORT: bt rsi, rcx + */ + ASSERT_EQ(4, ild(u"H☼ú╬")); +} + +TEST(x86ild, test_450FB7C0) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR16 + ISA_SET: I386 + SHORT: movzx r8d, r8w + */ + ASSERT_EQ(4, ild(u"E☼╖└")); +} + +TEST(x86ild, test_450FB67500) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx r14d, byte ptr [r13] + */ + ASSERT_EQ(5, ild(u"E☼╢u ")); +} + +TEST(x86ild, test_450FB63424) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx r14d, byte ptr [r12] + */ + ASSERT_EQ(5, ild(u"E☼╢4$")); +} + +TEST(x86ild, test_450FB60C00) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx r9d, byte ptr [r8+rax*1] + */ + ASSERT_EQ(5, ild(u"E☼╢♀ ")); +} + +TEST(x86ild, test_440FB66B00) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx r13d, byte ptr [rbx] + */ + ASSERT_EQ(5, ild(u"D☼╢k ")); +} + +TEST(x86ild, test_440FB64700) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx r8d, byte ptr [rdi] + */ + ASSERT_EQ(5, ild(u"D☼╢G ")); +} + +TEST(x86ild, test_440FB62F) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx r13d, byte ptr [rdi] + */ + ASSERT_EQ(4, ild(u"D☼╢/")); +} + +TEST(x86ild, test_440FB62C08) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx r13d, byte ptr [rax+rcx*1] + */ + ASSERT_EQ(5, ild(u"D☼╢,◘")); +} + +TEST(x86ild, test_440FB627) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx r12d, byte ptr [rdi] + */ + ASSERT_EQ(4, ild(u"D☼╢‘")); +} + +TEST(x86ild, test_440FB62430) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx r12d, byte ptr [rax+rsi*1] + */ + ASSERT_EQ(5, ild(u"D☼╢$0")); +} + +TEST(x86ild, test_440FB620) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx r12d, byte ptr [rax] + */ + ASSERT_EQ(4, ild(u"D☼╢ ")); +} + +TEST(x86ild, test_440FB607) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx r8d, byte ptr [rdi] + */ + ASSERT_EQ(4, ild(u"D☼╢•")); +} + +TEST(x86ild, test_410FB7442400) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMw + ISA_SET: I386 + SHORT: movzx eax, word ptr [r12] + */ + ASSERT_EQ(6, ild(u"A☼╖D$ ")); +} + +TEST(x86ild, test_410FB67C2C00) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx edi, byte ptr [r12+rbp*1] + */ + ASSERT_EQ(6, ild(u"A☼╢|, ")); +} + +TEST(x86ild, test_410FB6442400) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx eax, byte ptr [r12] + */ + ASSERT_EQ(6, ild(u"A☼╢D$ ")); +} + +TEST(x86ild, test_410FB63400) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx esi, byte ptr [r8+rax*1] + */ + ASSERT_EQ(5, ild(u"A☼╢4 ")); +} + +TEST(x86ild, test_410FB62C10) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx ebp, byte ptr [r8+rdx*1] + */ + ASSERT_EQ(5, ild(u"A☼╢,►")); +} + +TEST(x86ild, test_410F95C4) { + /* + ICLASS: SETNZ + CATEGORY: SETCC + EXTENSION: BASE + IFORM: SETNZ_GPR8 + ISA_SET: I386 + SHORT: setnz r12b + */ + ASSERT_EQ(4, ild(u"A☼ò─")); +} + +TEST(x86ild, test_410F94C0) { + /* + ICLASS: SETZ + CATEGORY: SETCC + EXTENSION: BASE + IFORM: SETZ_GPR8 + ISA_SET: I386 + SHORT: setz r8b + */ + ASSERT_EQ(4, ild(u"A☼ö└")); +} + +TEST(x86ild, test_400FBEC7) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movsx eax, dil + */ + ASSERT_EQ(4, ild(u"@☼╛╟")); +} + +TEST(x86ild, test_400FB6FF) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx edi, dil + */ + ASSERT_EQ(4, ild(u"@☼╢λ")); +} + +TEST(x86ild, test_400FB6CE) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx ecx, sil + */ + ASSERT_EQ(4, ild(u"@☼╢╬")); +} + +TEST(x86ild, test_400F9EC5) { + /* + ICLASS: SETLE + CATEGORY: SETCC + EXTENSION: BASE + IFORM: SETLE_GPR8 + ISA_SET: I386 + SHORT: setle bpl + */ + ASSERT_EQ(4, ild(u"@☼€┼")); +} + +TEST(x86ild, test_400F94C7) { + /* + ICLASS: SETZ + CATEGORY: SETCC + EXTENSION: BASE + IFORM: SETZ_GPR8 + ISA_SET: I386 + SHORT: setz dil + */ + ASSERT_EQ(4, ild(u"@☼ö╟")); +} + +TEST(x86ild, test_400F94C6) { + /* + ICLASS: SETZ + CATEGORY: SETCC + EXTENSION: BASE + IFORM: SETZ_GPR8 + ISA_SET: I386 + SHORT: setz sil + */ + ASSERT_EQ(4, ild(u"@☼ö╞")); +} + +TEST(x86ild, test_0FBFF8) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_GPR16 + ISA_SET: I386 + SHORT: movsx edi, ax + */ + ASSERT_EQ(3, ild(u"☼┐°")); +} + +TEST(x86ild, test_0FBFC7) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_GPR16 + ISA_SET: I386 + SHORT: movsx eax, di + */ + ASSERT_EQ(3, ild(u"☼┐╟")); +} + +TEST(x86ild, test_0FBEF8) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movsx edi, al + */ + ASSERT_EQ(3, ild(u"☼╛°")); +} + +TEST(x86ild, test_0FBE4A00) { + /* + ICLASS: MOVSX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVSX_GPRv_MEMb + ISA_SET: I386 + SHORT: movsx ecx, byte ptr [rdx] + */ + ASSERT_EQ(4, ild(u"☼╛J ")); +} + +TEST(x86ild, test_0FB7FA) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR16 + ISA_SET: I386 + SHORT: movzx edi, dx + */ + ASSERT_EQ(3, ild(u"☼╖·")); +} + +TEST(x86ild, test_0FB7D2) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR16 + ISA_SET: I386 + SHORT: movzx edx, dx + */ + ASSERT_EQ(3, ild(u"☼╖╥")); +} + +TEST(x86ild, test_0FB7742400) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMw + ISA_SET: I386 + SHORT: movzx esi, word ptr [rsp] + */ + ASSERT_EQ(5, ild(u"☼╖t$ ")); +} + +TEST(x86ild, test_0FB75000) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMw + ISA_SET: I386 + SHORT: movzx edx, word ptr [rax] + */ + ASSERT_EQ(4, ild(u"☼╖P ")); +} + +TEST(x86ild, test_0FB74600) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMw + ISA_SET: I386 + SHORT: movzx eax, word ptr [rsi] + */ + ASSERT_EQ(4, ild(u"☼╖F ")); +} + +TEST(x86ild, test_0FB74200) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMw + ISA_SET: I386 + SHORT: movzx eax, word ptr [rdx] + */ + ASSERT_EQ(4, ild(u"☼╖B ")); +} + +TEST(x86ild, test_0FB739) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMw + ISA_SET: I386 + SHORT: movzx edi, word ptr [rcx] + */ + ASSERT_EQ(3, ild(u"☼╖9")); +} + +TEST(x86ild, test_0FB700) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMw + ISA_SET: I386 + SHORT: movzx eax, word ptr [rax] + */ + ASSERT_EQ(3, ild(u"☼╖ ")); +} + +TEST(x86ild, test_0FB6F9) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx edi, cl + */ + ASSERT_EQ(3, ild(u"☼╢∙")); +} + +TEST(x86ild, test_0FB6F2) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx esi, dl + */ + ASSERT_EQ(3, ild(u"☼╢≥")); +} + +TEST(x86ild, test_0FB6F1) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx esi, cl + */ + ASSERT_EQ(3, ild(u"☼╢±")); +} + +TEST(x86ild, test_0FB6F0) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_GPR8 + ISA_SET: I386 + SHORT: movzx esi, al + */ + ASSERT_EQ(3, ild(u"☼╢≡")); +} + +TEST(x86ild, test_0FB69C2400000000) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx ebx, byte ptr [rsp] + */ + ASSERT_EQ(8, ild(u"☼╢£$    ")); +} + +TEST(x86ild, test_0FB6941100000000) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx edx, byte ptr [rcx+rdx*1] + */ + ASSERT_EQ(8, ild(u"☼╢ö◄    ")); +} + +TEST(x86ild, test_0FB68C1000000000) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx ecx, byte ptr [rax+rdx*1] + */ + ASSERT_EQ(8, ild(u"☼╢î►    ")); +} + +TEST(x86ild, test_0FB67B00) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx edi, byte ptr [rbx] + */ + ASSERT_EQ(4, ild(u"☼╢{ ")); +} + +TEST(x86ild, test_0FB65F00) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx ebx, byte ptr [rdi] + */ + ASSERT_EQ(4, ild(u"☼╢_ ")); +} + +TEST(x86ild, test_0FB65800) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx ebx, byte ptr [rax] + */ + ASSERT_EQ(4, ild(u"☼╢X ")); +} + +TEST(x86ild, test_0FB65200) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx edx, byte ptr [rdx] + */ + ASSERT_EQ(4, ild(u"☼╢R ")); +} + +TEST(x86ild, test_0FB65000) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx edx, byte ptr [rax] + */ + ASSERT_EQ(4, ild(u"☼╢P ")); +} + +TEST(x86ild, test_0FB64600) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx eax, byte ptr [rsi] + */ + ASSERT_EQ(4, ild(u"☼╢F ")); +} + +TEST(x86ild, test_0FB6443700) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx eax, byte ptr [rdi+rsi*1] + */ + ASSERT_EQ(5, ild(u"☼╢D7 ")); +} + +TEST(x86ild, test_0FB63F) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx edi, byte ptr [rdi] + */ + ASSERT_EQ(3, ild(u"☼╢⁇")); +} + +TEST(x86ild, test_0FB63C08) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx edi, byte ptr [rax+rcx*1] + */ + ASSERT_EQ(4, ild(u"☼╢<◘")); +} + +TEST(x86ild, test_0FB63430) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx esi, byte ptr [rax+rsi*1] + */ + ASSERT_EQ(4, ild(u"☼╢40")); +} + +TEST(x86ild, test_0FB610) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx edx, byte ptr [rax] + */ + ASSERT_EQ(3, ild(u"☼╢►")); +} + +TEST(x86ild, test_0FB60F) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx ecx, byte ptr [rdi] + */ + ASSERT_EQ(3, ild(u"☼╢☼")); +} + +TEST(x86ild, test_0FB60CD500000000) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx ecx, byte ptr [rdx*8] + */ + ASSERT_EQ(8, ild(u"☼╢♀╒    ")); +} + +TEST(x86ild, test_0FB60C08) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx ecx, byte ptr [rax+rcx*1] + */ + ASSERT_EQ(4, ild(u"☼╢♀◘")); +} + +TEST(x86ild, test_0FB608) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx ecx, byte ptr [rax] + */ + ASSERT_EQ(3, ild(u"☼╢◘")); +} + +TEST(x86ild, test_0FB607) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx eax, byte ptr [rdi] + */ + ASSERT_EQ(3, ild(u"☼╢•")); +} + +TEST(x86ild, test_0FB6049500000000) { + /* + ICLASS: MOVZX + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOVZX_GPRv_MEMb + ISA_SET: I386 + SHORT: movzx eax, byte ptr [rdx*4] + */ + ASSERT_EQ(8, ild(u"☼╢♦ò    ")); +} + +TEST(x86ild, test_0FA3D0) { + /* + ICLASS: BT + CATEGORY: BITBYTE + EXTENSION: BASE + IFORM: BT_GPRv_GPRv + ISA_SET: I386 + SHORT: bt eax, edx + */ + ASSERT_EQ(3, ild(u"☼ú╨")); +} + +TEST(x86ild, test_0F9CC1) { + /* + ICLASS: SETL + CATEGORY: SETCC + EXTENSION: BASE + IFORM: SETL_GPR8 + ISA_SET: I386 + SHORT: setl cl + */ + ASSERT_EQ(3, ild(u"☼£┴")); +} + +TEST(x86ild, test_0F97C1) { + /* + ICLASS: SETNBE + CATEGORY: SETCC + EXTENSION: BASE + IFORM: SETNBE_GPR8 + ISA_SET: I386 + SHORT: setnbe cl + */ + ASSERT_EQ(3, ild(u"☼ù┴")); +} + +TEST(x86ild, test_0F96C2) { + /* + ICLASS: SETBE + CATEGORY: SETCC + EXTENSION: BASE + IFORM: SETBE_GPR8 + ISA_SET: I386 + SHORT: setbe dl + */ + ASSERT_EQ(3, ild(u"☼û┬")); +} + +TEST(x86ild, test_0F95C1) { + /* + ICLASS: SETNZ + CATEGORY: SETCC + EXTENSION: BASE + IFORM: SETNZ_GPR8 + ISA_SET: I386 + SHORT: setnz cl + */ + ASSERT_EQ(3, ild(u"☼ò┴")); +} diff --git a/test/libc/xed/x86ild_popular_i86_test.c b/test/libc/xed/x86ild_popular_i86_test.c new file mode 100644 index 00000000..fc86101c --- /dev/null +++ b/test/libc/xed/x86ild_popular_i86_test.c @@ -0,0 +1,7426 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/testlib.h" +#include "test/libc/xed/lib.h" +#include "third_party/xed/x86.h" + +/** + * @fileoverview GCC's popular i386+ instruction w/ NexGen32e encoding. + */ + +TEST(x86ild, test_E800000000) { + /* + ICLASS: CALL_NEAR + CATEGORY: CALL + EXTENSION: BASE + IFORM: CALL_NEAR_RELBRd + ISA_SET: I86 + SHORT: call 0x5 + */ + EXPECT_EQ(5, ild(u"Φ    ")); + EXPECT_EQ(5, ildlegacy(u"Φ    ")); + EXPECT_EQ(3, ildreal(u"Φ  ")); +} + +TEST(x86ild, test_C3) { + /* + ICLASS: RET_NEAR + CATEGORY: RET + EXTENSION: BASE + IFORM: RET_NEAR + ISA_SET: I86 + SHORT: ret + */ + EXPECT_EQ(1, ild(u"├")); +} + +TEST(x86ild, test_5A) { + /* + ICLASS: POP + CATEGORY: POP + EXTENSION: BASE + IFORM: POP_GPRv_58 + ISA_SET: I86 + SHORT: pop rdx + */ + EXPECT_EQ(1, ild(u"Z")); +} + +TEST(x86ild, test_4889DF) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rdi, rbx + */ + EXPECT_EQ(3, ild(u"Hë▀")); +} + +TEST(x86ild, test_BA00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov edx, 0x0 + */ + EXPECT_EQ(5, ild(u"║    ")); +} + +TEST(x86ild, test_7500) { + /* + ICLASS: JNZ + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JNZ_RELBRb + ISA_SET: I86 + SHORT: jnz 0x2 + */ + EXPECT_EQ(2, ild(u"u ")); +} + +TEST(x86ild, test_B800000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov eax, 0x0 + */ + EXPECT_EQ(5, ild(u"╕    ")); +} + +TEST(x86ild, test_7400) { + /* + ICLASS: JZ + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JZ_RELBRb + ISA_SET: I86 + SHORT: jz 0x2 + */ + EXPECT_EQ(2, ild(u"t ")); +} + +TEST(x86ild, test_BE00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov esi, 0x0 + */ + EXPECT_EQ(5, ild(u"╛    ")); +} + +TEST(x86ild, test_4889C1) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rcx, rax + */ + EXPECT_EQ(3, ild(u"Hë┴")); +} + +TEST(x86ild, test_EB00) { + /* + ICLASS: JMP + CATEGORY: UNCOND_BR + EXTENSION: BASE + IFORM: JMP_RELBRb + ISA_SET: I86 + SHORT: jmp 0x2 + */ + EXPECT_EQ(2, ild(u"δ ")); +} + +TEST(x86ild, test_8B34D500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov esi, dword ptr [rdx*8] + */ + EXPECT_EQ(7, ild(u"ï4╒    ")); +} + +TEST(x86ild, test_E900000000) { + /* + ICLASS: JMP + CATEGORY: UNCOND_BR + EXTENSION: BASE + IFORM: JMP_RELBRd + ISA_SET: I86 + SHORT: jmp 0x5 + */ + EXPECT_EQ(5, ild(u"Θ    ")); +} + +TEST(x86ild, test_8B7300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov esi, dword ptr [rbx] + */ + EXPECT_EQ(3, ild(u"ïs ")); +} + +TEST(x86ild, test_8B04D500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov eax, dword ptr [rdx*8] + */ + EXPECT_EQ(7, ild(u"ï♦╒    ")); +} + +TEST(x86ild, test_89D0) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov eax, edx + */ + EXPECT_EQ(2, ild(u"ë╨")); +} + +TEST(x86ild, test_0F8400000000) { + /* + ICLASS: JZ + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JZ_RELBRd + ISA_SET: I86 + SHORT: jz 0x6 + */ + EXPECT_EQ(6, ild(u"☼ä    ")); +} + +TEST(x86ild, test_8B14CD00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [rcx*8] + */ + EXPECT_EQ(7, ild(u"ï¶═    ")); +} + +TEST(x86ild, test_8B34CD00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov esi, dword ptr [rcx*8] + */ + EXPECT_EQ(7, ild(u"ï4═    ")); +} + +TEST(x86ild, test_8A4300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov al, byte ptr [rbx] + */ + EXPECT_EQ(3, ild(u"èC ")); +} + +TEST(x86ild, test_8B4700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov eax, dword ptr [rdi] + */ + EXPECT_EQ(3, ild(u"ïG ")); +} + +TEST(x86ild, test_5B) { + /* + ICLASS: POP + CATEGORY: POP + EXTENSION: BASE + IFORM: POP_GPRv_58 + ISA_SET: I86 + SHORT: pop rbx + */ + EXPECT_EQ(1, ild(u"[")); +} + +TEST(x86ild, test_66C705000000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_IMMz + ISA_SET: I86 + SHORT: mov word ptr [rip], 0x0 + */ + EXPECT_EQ(9, ild(u"f╟♣      ")); +} + +TEST(x86ild, test_8A4700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov al, byte ptr [rdi] + */ + EXPECT_EQ(3, ild(u"èG ")); +} + +TEST(x86ild, test_FFD0) { + /* + ICLASS: CALL_NEAR + CATEGORY: CALL + EXTENSION: BASE + IFORM: CALL_NEAR_GPRv + ISA_SET: I86 + SHORT: call rax + */ + EXPECT_EQ(2, ild(u"λ╨")); +} + +TEST(x86ild, test_C7050000000000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_IMMz + ISA_SET: I86 + SHORT: mov dword ptr [rip], 0x0 + */ + EXPECT_EQ(10, ild(u"╟♣        ")); +} + +TEST(x86ild, test_53) { + /* + ICLASS: PUSH + CATEGORY: PUSH + EXTENSION: BASE + IFORM: PUSH_GPRv_50 + ISA_SET: I86 + SHORT: push rbx + */ + EXPECT_EQ(1, ild(u"S")); +} + +TEST(x86ild, test_0F8500000000) { + /* + ICLASS: JNZ + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JNZ_RELBRd + ISA_SET: I86 + SHORT: jnz 0x6 + */ + EXPECT_EQ(6, ild(u"☼à    ")); +} + +TEST(x86ild, test_C6050000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_IMMb + ISA_SET: I86 + SHORT: mov byte ptr [rip], 0x0 + */ + EXPECT_EQ(7, ild(u"╞♣     ")); +} + +TEST(x86ild, test_668B7300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov si, word ptr [rbx] + */ + EXPECT_EQ(4, ild(u"fïs ")); +} + +TEST(x86ild, test_488B4300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rax, qword ptr [rbx] + */ + EXPECT_EQ(4, ild(u"HïC ")); +} + +TEST(x86ild, test_BF00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov edi, 0x0 + */ + EXPECT_EQ(5, ild(u"┐    ")); +} + +TEST(x86ild, test_4889FB) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rbx, rdi + */ + EXPECT_EQ(3, ild(u"Hë√")); +} + +TEST(x86ild, test_48B80000000000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov rax, 0x0 + */ + EXPECT_EQ(10, ild(u"H╕        ")); +} + +TEST(x86ild, test_48BA0000000000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov rdx, 0x0 + */ + EXPECT_EQ(10, ild(u"H║        ")); +} + +TEST(x86ild, test_488B5300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdx, qword ptr [rbx] + */ + EXPECT_EQ(4, ild(u"HïS ")); +} + +TEST(x86ild, test_66898200000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov word ptr [rdx], ax + */ + EXPECT_EQ(7, ild(u"fëé    ")); +} + +TEST(x86ild, test_66894700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov word ptr [rdi], ax + */ + EXPECT_EQ(4, ild(u"fëG ")); +} + +TEST(x86ild, test_7700) { + /* + ICLASS: JNBE + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JNBE_RELBRb + ISA_SET: I86 + SHORT: jnbe 0x2 + */ + EXPECT_EQ(2, ild(u"w ")); +} + +TEST(x86ild, test_894700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rdi], eax + */ + EXPECT_EQ(3, ild(u"ëG ")); +} + +TEST(x86ild, test_66899000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov word ptr [rax], dx + */ + EXPECT_EQ(7, ild(u"fëÉ    ")); +} + +TEST(x86ild, test_4889D0) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rax, rdx + */ + EXPECT_EQ(3, ild(u"Hë╨")); +} + +TEST(x86ild, test_668B4700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ax, word ptr [rdi] + */ + EXPECT_EQ(4, ild(u"fïG ")); +} + +TEST(x86ild, test_89C2) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edx, eax + */ + EXPECT_EQ(2, ild(u"ë┬")); +} + +TEST(x86ild, test_668B8000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ax, word ptr [rax] + */ + EXPECT_EQ(7, ild(u"fïÇ    ")); +} + +TEST(x86ild, test_668B9500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov dx, word ptr [rbp] + */ + EXPECT_EQ(7, ild(u"fïò    ")); +} + +TEST(x86ild, test_5D) { + /* + ICLASS: POP + CATEGORY: POP + EXTENSION: BASE + IFORM: POP_GPRv_58 + ISA_SET: I86 + SHORT: pop rbp + */ + EXPECT_EQ(1, ild(u"]")); +} + +TEST(x86ild, test_55) { + /* + ICLASS: PUSH + CATEGORY: PUSH + EXTENSION: BASE + IFORM: PUSH_GPRv_50 + ISA_SET: I86 + SHORT: push rbp + */ + EXPECT_EQ(1, ild(u"U")); +} + +TEST(x86ild, test_89C8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov eax, ecx + */ + EXPECT_EQ(2, ild(u"ë╚")); +} + +TEST(x86ild, test_8B0CD500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ecx, dword ptr [rdx*8] + */ + EXPECT_EQ(7, ild(u"ï♀╒    ")); +} + +TEST(x86ild, test_8A4F00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov cl, byte ptr [rdi] + */ + EXPECT_EQ(3, ild(u"èO ")); +} + +TEST(x86ild, test_8B148500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [rax*4] + */ + EXPECT_EQ(7, ild(u"ï¶à    ")); +} + +TEST(x86ild, test_8A5300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov dl, byte ptr [rbx] + */ + EXPECT_EQ(3, ild(u"èS ")); +} + +TEST(x86ild, test_884F00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rdi], cl + */ + EXPECT_EQ(3, ild(u"êO ")); +} + +TEST(x86ild, test_8B8000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov eax, dword ptr [rax] + */ + EXPECT_EQ(6, ild(u"ïÇ    ")); +} + +TEST(x86ild, test_8B9500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [rbp] + */ + EXPECT_EQ(6, ild(u"ïò    ")); +} + +TEST(x86ild, test_8A5700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov dl, byte ptr [rdi] + */ + EXPECT_EQ(3, ild(u"èW ")); +} + +TEST(x86ild, test_884300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rbx], al + */ + EXPECT_EQ(3, ild(u"êC ")); +} + +TEST(x86ild, test_884700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rdi], al + */ + EXPECT_EQ(3, ild(u"êG ")); +} + +TEST(x86ild, test_8A4800) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov cl, byte ptr [rax] + */ + EXPECT_EQ(3, ild(u"èH ")); +} + +TEST(x86ild, test_66C780000000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_IMMz + ISA_SET: I86 + SHORT: mov word ptr [rax], 0x0 + */ + EXPECT_EQ(9, ild(u"f╟Ç      ")); +} + +TEST(x86ild, test_885700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rdi], dl + */ + EXPECT_EQ(3, ild(u"êW ")); +} + +TEST(x86ild, test_8B5700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [rdi] + */ + EXPECT_EQ(3, ild(u"ïW ")); +} + +TEST(x86ild, test_48C7050000000000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_IMMz + ISA_SET: I86 + SHORT: mov qword ptr [rip], 0x0 + */ + EXPECT_EQ(11, ild(u"H╟♣        ")); +} + +TEST(x86ild, test_8B4300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov eax, dword ptr [rbx] + */ + EXPECT_EQ(3, ild(u"ïC ")); +} + +TEST(x86ild, test_E200) { + /* + ICLASS: LOOP + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: LOOP_RELBRb + ISA_SET: I86 + SHORT: loop 0x2 + */ + EXPECT_EQ(2, ild(u"Γ ")); +} + +TEST(x86ild, test_8B049500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov eax, dword ptr [rdx*4] + */ + EXPECT_EQ(7, ild(u"ï♦ò    ")); +} + +TEST(x86ild, test_89F0) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov eax, esi + */ + EXPECT_EQ(2, ild(u"ë≡")); +} + +TEST(x86ild, test_668B5300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov dx, word ptr [rbx] + */ + EXPECT_EQ(4, ild(u"fïS ")); +} + +TEST(x86ild, test_8B7700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov esi, dword ptr [rdi] + */ + EXPECT_EQ(3, ild(u"ïw ")); +} + +TEST(x86ild, test_66897700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov word ptr [rdi], si + */ + EXPECT_EQ(4, ild(u"fëw ")); +} + +TEST(x86ild, test_66894300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov word ptr [rbx], ax + */ + EXPECT_EQ(4, ild(u"fëC ")); +} + +TEST(x86ild, test_8902) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rdx], eax + */ + EXPECT_EQ(2, ild(u"ë☻")); +} + +TEST(x86ild, test_408A7000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov sil, byte ptr [rax] + */ + EXPECT_EQ(4, ild(u"@èp ")); +} + +TEST(x86ild, test_88C2) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov dl, al + */ + EXPECT_EQ(2, ild(u"ê┬")); +} + +TEST(x86ild, test_668B14AD00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov dx, word ptr [rbp*4] + */ + EXPECT_EQ(8, ild(u"fï¶¡    ")); +} + +TEST(x86ild, test_668B4300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ax, word ptr [rbx] + */ + EXPECT_EQ(4, ild(u"fïC ")); +} + +TEST(x86ild, test_4088CE) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov sil, cl + */ + EXPECT_EQ(3, ild(u"@ê╬")); +} + +TEST(x86ild, test_89C1) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov ecx, eax + */ + EXPECT_EQ(2, ild(u"ë┴")); +} + +TEST(x86ild, test_8B14D500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [rdx*8] + */ + EXPECT_EQ(7, ild(u"ï¶╒    ")); +} + +TEST(x86ild, test_8B149500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [rdx*4] + */ + EXPECT_EQ(7, ild(u"ï¶ò    ")); +} + +TEST(x86ild, test_884B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rbx], cl + */ + EXPECT_EQ(3, ild(u"êK ")); +} + +TEST(x86ild, test_488B4700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rax, qword ptr [rdi] + */ + EXPECT_EQ(4, ild(u"HïG ")); +} + +TEST(x86ild, test_8B4F00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ecx, dword ptr [rdi] + */ + EXPECT_EQ(3, ild(u"ïO ")); +} + +TEST(x86ild, test_8A08) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov cl, byte ptr [rax] + */ + EXPECT_EQ(2, ild(u"è◘")); +} + +TEST(x86ild, test_668B5700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov dx, word ptr [rdi] + */ + EXPECT_EQ(4, ild(u"fïW ")); +} + +TEST(x86ild, test_C6470000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_IMMb + ISA_SET: I86 + SHORT: mov byte ptr [rdi], 0x0 + */ + EXPECT_EQ(4, ild(u"╞G  ")); +} + +TEST(x86ild, test_66895700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov word ptr [rdi], dx + */ + EXPECT_EQ(4, ild(u"fëW ")); +} + +TEST(x86ild, test_FF24D500000000) { + /* + ICLASS: JMP + CATEGORY: UNCOND_BR + EXTENSION: BASE + IFORM: JMP_MEMv + ISA_SET: I86 + SHORT: jmp qword ptr [rdx*8] + */ + EXPECT_EQ(7, ild(u"λ$╒    ")); +} + +TEST(x86ild, test_8A4B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov cl, byte ptr [rbx] + */ + EXPECT_EQ(3, ild(u"èK ")); +} + +TEST(x86ild, test_7200) { + /* + ICLASS: JB + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JB_RELBRb + ISA_SET: I86 + SHORT: jb 0x2 + */ + EXPECT_EQ(2, ild(u"r ")); +} + +TEST(x86ild, test_88C1) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov cl, al + */ + EXPECT_EQ(2, ild(u"ê┴")); +} + +TEST(x86ild, test_668B14D500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov dx, word ptr [rdx*8] + */ + EXPECT_EQ(8, ild(u"fï¶╒    ")); +} + +TEST(x86ild, test_8A4000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov al, byte ptr [rax] + */ + EXPECT_EQ(3, ild(u"è@ ")); +} + +TEST(x86ild, test_C6430000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_IMMb + ISA_SET: I86 + SHORT: mov byte ptr [rbx], 0x0 + */ + EXPECT_EQ(4, ild(u"╞C  ")); +} + +TEST(x86ild, test_8B14ED00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [rbp*8] + */ + EXPECT_EQ(7, ild(u"ï¶φ    ")); +} + +TEST(x86ild, test_668B14ED00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov dx, word ptr [rbp*8] + */ + EXPECT_EQ(8, ild(u"fï¶φ    ")); +} + +TEST(x86ild, test_408A7300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov sil, byte ptr [rbx] + */ + EXPECT_EQ(4, ild(u"@ès ")); +} + +TEST(x86ild, test_7800) { + /* + ICLASS: JS + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JS_RELBRb + ISA_SET: I86 + SHORT: js 0x2 + */ + EXPECT_EQ(2, ild(u"x ")); +} + +TEST(x86ild, test_40887300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rbx], sil + */ + EXPECT_EQ(4, ild(u"@ês ")); +} + +TEST(x86ild, test_48890500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rip], rax + */ + EXPECT_EQ(7, ild(u"Hë♣    ")); +} + +TEST(x86ild, test_B900000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov ecx, 0x0 + */ + EXPECT_EQ(5, ild(u"╣    ")); +} + +TEST(x86ild, test_8B742400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov esi, dword ptr [rsp] + */ + EXPECT_EQ(4, ild(u"ït$ ")); +} + +TEST(x86ild, test_89F2) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edx, esi + */ + EXPECT_EQ(2, ild(u"ë≥")); +} + +TEST(x86ild, test_4088F7) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov dil, sil + */ + EXPECT_EQ(3, ild(u"@ê≈")); +} + +TEST(x86ild, test_668B942D00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov dx, word ptr [rbp+rbp*1] + */ + EXPECT_EQ(8, ild(u"fïö-    ")); +} + +TEST(x86ild, test_408A7700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov sil, byte ptr [rdi] + */ + EXPECT_EQ(4, ild(u"@èw ")); +} + +TEST(x86ild, test_89742400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rsp], esi + */ + EXPECT_EQ(4, ild(u"ët$ ")); +} + +TEST(x86ild, test_4889EF) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rdi, rbp + */ + EXPECT_EQ(3, ild(u"Hë∩")); +} + +TEST(x86ild, test_7900) { + /* + ICLASS: JNS + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JNS_RELBRb + ISA_SET: I86 + SHORT: jns 0x2 + */ + EXPECT_EQ(2, ild(u"y ")); +} + +TEST(x86ild, test_89FF) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edi, edi + */ + EXPECT_EQ(2, ild(u"ëλ")); +} + +TEST(x86ild, test_89CE) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov esi, ecx + */ + EXPECT_EQ(2, ild(u"ë╬")); +} + +TEST(x86ild, test_7600) { + /* + ICLASS: JBE + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JBE_RELBRb + ISA_SET: I86 + SHORT: jbe 0x2 + */ + EXPECT_EQ(2, ild(u"v ")); +} + +TEST(x86ild, test_4889C6) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rsi, rax + */ + EXPECT_EQ(3, ild(u"Hë╞")); +} + +TEST(x86ild, test_8B048500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov eax, dword ptr [rax*4] + */ + EXPECT_EQ(7, ild(u"ï♦à    ")); +} + +TEST(x86ild, test_415C) { + /* + ICLASS: POP + CATEGORY: POP + EXTENSION: BASE + IFORM: POP_GPRv_58 + ISA_SET: I86 + SHORT: pop r12 + */ + EXPECT_EQ(2, ild(u"A╲")); +} + +TEST(x86ild, test_488B04C500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rax, qword ptr [rax*8] + */ + EXPECT_EQ(8, ild(u"Hï♦┼    ")); +} + +TEST(x86ild, test_885300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rbx], dl + */ + EXPECT_EQ(3, ild(u"êS ")); +} + +TEST(x86ild, test_4889FD) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rbp, rdi + */ + EXPECT_EQ(3, ild(u"Hë²")); +} + +TEST(x86ild, test_4088F0) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov al, sil + */ + EXPECT_EQ(3, ild(u"@ê≡")); +} + +TEST(x86ild, test_89442400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rsp], eax + */ + EXPECT_EQ(4, ild(u"ëD$ ")); +} + +TEST(x86ild, test_894300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rbx], eax + */ + EXPECT_EQ(3, ild(u"ëC ")); +} + +TEST(x86ild, test_88D0) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov al, dl + */ + EXPECT_EQ(2, ild(u"ê╨")); +} + +TEST(x86ild, test_4154) { + /* + ICLASS: PUSH + CATEGORY: PUSH + EXTENSION: BASE + IFORM: PUSH_GPRv_50 + ISA_SET: I86 + SHORT: push r12 + */ + EXPECT_EQ(2, ild(u"AT")); +} + +TEST(x86ild, test_7300) { + /* + ICLASS: JNB + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JNB_RELBRb + ISA_SET: I86 + SHORT: jnb 0x2 + */ + EXPECT_EQ(2, ild(u"s ")); +} + +TEST(x86ild, test_448A4700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov r8b, byte ptr [rdi] + */ + EXPECT_EQ(4, ild(u"DèG ")); +} + +TEST(x86ild, test_89F7) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edi, esi + */ + EXPECT_EQ(2, ild(u"ë≈")); +} + +TEST(x86ild, test_89C0) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov eax, eax + */ + EXPECT_EQ(2, ild(u"ë└")); +} + +TEST(x86ild, test_668B4F00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov cx, word ptr [rdi] + */ + EXPECT_EQ(4, ild(u"fïO ")); +} + +TEST(x86ild, test_BB00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov ebx, 0x0 + */ + EXPECT_EQ(5, ild(u"╗    ")); +} + +TEST(x86ild, test_88C8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov al, cl + */ + EXPECT_EQ(2, ild(u"ê╚")); +} + +TEST(x86ild, test_66894F00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov word ptr [rdi], cx + */ + EXPECT_EQ(4, ild(u"fëO ")); +} + +TEST(x86ild, test_415D) { + /* + ICLASS: POP + CATEGORY: POP + EXTENSION: BASE + IFORM: POP_GPRv_58 + ISA_SET: I86 + SHORT: pop r13 + */ + EXPECT_EQ(2, ild(u"A]")); +} + +TEST(x86ild, test_FFE0) { + /* + ICLASS: JMP + CATEGORY: UNCOND_BR + EXTENSION: BASE + IFORM: JMP_GPRv + ISA_SET: I86 + SHORT: jmp rax + */ + EXPECT_EQ(2, ild(u"λα")); +} + +TEST(x86ild, test_FFD2) { + /* + ICLASS: CALL_NEAR + CATEGORY: CALL + EXTENSION: BASE + IFORM: CALL_NEAR_GPRv + ISA_SET: I86 + SHORT: call rdx + */ + EXPECT_EQ(2, ild(u"λ╥")); +} + +TEST(x86ild, test_FF24C500000000) { + /* + ICLASS: JMP + CATEGORY: UNCOND_BR + EXTENSION: BASE + IFORM: JMP_MEMv + ISA_SET: I86 + SHORT: jmp qword ptr [rax*8] + */ + EXPECT_EQ(7, ild(u"λ$┼    ")); +} + +TEST(x86ild, test_E000) { + /* + ICLASS: LOOPNE + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: LOOPNE_RELBRb + ISA_SET: I86 + SHORT: loopne 0x2 + */ + EXPECT_EQ(2, ild(u"α ")); +} + +TEST(x86ild, test_8B4000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov eax, dword ptr [rax] + */ + EXPECT_EQ(3, ild(u"ï@ ")); +} + +TEST(x86ild, test_89D1) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov ecx, edx + */ + EXPECT_EQ(2, ild(u"ë╤")); +} + +TEST(x86ild, test_8B14AD00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [rbp*4] + */ + EXPECT_EQ(7, ild(u"ï¶¡    ")); +} + +TEST(x86ild, test_895700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rdi], edx + */ + EXPECT_EQ(3, ild(u"ëW ")); +} + +TEST(x86ild, test_488B5700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdx, qword ptr [rdi] + */ + EXPECT_EQ(4, ild(u"HïW ")); +} + +TEST(x86ild, test_4155) { + /* + ICLASS: PUSH + CATEGORY: PUSH + EXTENSION: BASE + IFORM: PUSH_GPRv_50 + ISA_SET: I86 + SHORT: push r13 + */ + EXPECT_EQ(2, ild(u"AU")); +} + +TEST(x86ild, test_668B840000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ax, word ptr [rax+rax*1] + */ + EXPECT_EQ(8, ild(u"fïä     ")); +} + +TEST(x86ild, test_488B8000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rax, qword ptr [rax] + */ + EXPECT_EQ(7, ild(u"HïÇ    ")); +} + +TEST(x86ild, test_488B4B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rcx, qword ptr [rbx] + */ + EXPECT_EQ(4, ild(u"HïK ")); +} + +TEST(x86ild, test_0F8700000000) { + /* + ICLASS: JNBE + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JNBE_RELBRd + ISA_SET: I86 + SHORT: jnbe 0x6 + */ + EXPECT_EQ(6, ild(u"☼ç    ")); +} + +TEST(x86ild, test_8B5300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [rbx] + */ + EXPECT_EQ(3, ild(u"ïS ")); +} + +TEST(x86ild, test_668B048500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ax, word ptr [rax*4] + */ + EXPECT_EQ(8, ild(u"fï♦à    ")); +} + +TEST(x86ild, test_66898100000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov word ptr [rcx], ax + */ + EXPECT_EQ(7, ild(u"fëü    ")); +} + +TEST(x86ild, test_488B17) { + /* + ICLASS: MOV + CATEGORY: DATAXFER +g EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdx, qword ptr [rdi] + */ + EXPECT_EQ(3, ild(u"Hï↨")); +} + +TEST(x86ild, test_4889C2) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rdx, rax + */ + EXPECT_EQ(3, ild(u"Hë┬")); +} + +TEST(x86ild, test_C7400000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_IMMz + ISA_SET: I86 + SHORT: mov dword ptr [rax], 0x0 + */ + EXPECT_EQ(7, ild(u"╟@     ")); +} + +TEST(x86ild, test_4C89E7) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rdi, r12 + */ + EXPECT_EQ(3, ild(u"Lëτ")); +} + +TEST(x86ild, test_488B3B) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdi, qword ptr [rbx] + */ + EXPECT_EQ(3, ild(u"Hï;")); +} + +TEST(x86ild, test_4889EE) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rsi, rbp + */ + EXPECT_EQ(3, ild(u"Hëε")); +} + +TEST(x86ild, test_4488C0) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov al, r8b + */ + EXPECT_EQ(3, ild(u"Dê└")); +} + +TEST(x86ild, test_415E) { + /* + ICLASS: POP + CATEGORY: POP + EXTENSION: BASE + IFORM: POP_GPRv_58 + ISA_SET: I86 + SHORT: pop r14 + */ + EXPECT_EQ(2, ild(u"A^")); +} + +TEST(x86ild, test_4156) { + /* + ICLASS: PUSH + CATEGORY: PUSH + EXTENSION: BASE + IFORM: PUSH_GPRv_50 + ISA_SET: I86 + SHORT: push r14 + */ + EXPECT_EQ(2, ild(u"AV")); +} + +TEST(x86ild, test_8B542400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [rsp] + */ + EXPECT_EQ(4, ild(u"ïT$ ")); +} + +TEST(x86ild, test_89C7) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edi, eax + */ + EXPECT_EQ(2, ild(u"ë╟")); +} + +TEST(x86ild, test_488B8700000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rax, qword ptr [rdi] + */ + EXPECT_EQ(7, ild(u"Hïç    ")); +} + +TEST(x86ild, test_448A4F00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov r9b, byte ptr [rdi] + */ + EXPECT_EQ(4, ild(u"DèO ")); +} + +TEST(x86ild, test_408A30) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov sil, byte ptr [rax] + */ + EXPECT_EQ(3, ild(u"@è0")); +} + +TEST(x86ild, test_4189C6) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r14d, eax + */ + EXPECT_EQ(3, ild(u"Aë╞")); +} + +TEST(x86ild, test_897300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rbx], esi + */ + EXPECT_EQ(3, ild(u"ës ")); +} + +TEST(x86ild, test_894F00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rdi], ecx + */ + EXPECT_EQ(3, ild(u"ëO ")); +} + +TEST(x86ild, test_4489E6) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov esi, r12d + */ + EXPECT_EQ(3, ild(u"Dëμ")); +} + +TEST(x86ild, test_4488C8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov al, r9b + */ + EXPECT_EQ(3, ild(u"Dê╚")); +} + +TEST(x86ild, test_8A10) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov dl, byte ptr [rax] + */ + EXPECT_EQ(2, ild(u"è►")); +} + +TEST(x86ild, test_894200) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rdx], eax + */ + EXPECT_EQ(3, ild(u"ëB ")); +} + +TEST(x86ild, test_88D1) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov cl, dl + */ + EXPECT_EQ(2, ild(u"ê╤")); +} + +TEST(x86ild, test_58) { + /* + ICLASS: POP + CATEGORY: POP + EXTENSION: BASE + IFORM: POP_GPRv_58 + ISA_SET: I86 + SHORT: pop rax + */ + EXPECT_EQ(1, ild(u"X")); +} + +TEST(x86ild, test_48B90000000000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov rcx, 0x0 + */ + EXPECT_EQ(10, ild(u"H╣        ")); +} + +TEST(x86ild, test_488B14D500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdx, qword ptr [rdx*8] + */ + EXPECT_EQ(8, ild(u"Hï¶╒    ")); +} + +TEST(x86ild, test_4489F2) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edx, r14d + */ + EXPECT_EQ(3, ild(u"Dë≥")); +} + +TEST(x86ild, test_4489EA) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edx, r13d + */ + EXPECT_EQ(3, ild(u"DëΩ")); +} + +TEST(x86ild, test_8B04BD00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov eax, dword ptr [rdi*4] + */ + EXPECT_EQ(7, ild(u"ï♦╜    ")); +} + +TEST(x86ild, test_89F1) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov ecx, esi + */ + EXPECT_EQ(2, ild(u"ë±")); +} + +TEST(x86ild, test_488B7F00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdi, qword ptr [rdi] + */ + EXPECT_EQ(4, ild(u"Hï⌂ ")); +} + +TEST(x86ild, test_4488C2) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov dl, r8b + */ + EXPECT_EQ(3, ild(u"Dê┬")); +} + +TEST(x86ild, test_4189C4) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r12d, eax + */ + EXPECT_EQ(3, ild(u"Aë─")); +} + +TEST(x86ild, test_8A049500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov al, byte ptr [rdx*4] + */ + EXPECT_EQ(7, ild(u"è♦ò    ")); +} + +TEST(x86ild, test_89F6) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov esi, esi + */ + EXPECT_EQ(2, ild(u"ë÷")); +} + +TEST(x86ild, test_89EE) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov esi, ebp + */ + EXPECT_EQ(2, ild(u"ëε")); +} + +TEST(x86ild, test_89DE) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov esi, ebx + */ + EXPECT_EQ(2, ild(u"ë▐")); +} + +TEST(x86ild, test_89DA) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edx, ebx + */ + EXPECT_EQ(2, ild(u"ë┌")); +} + +TEST(x86ild, test_89C3) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov ebx, eax + */ + EXPECT_EQ(2, ild(u"ë├")); +} + +TEST(x86ild, test_7E00) { + /* + ICLASS: JLE + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JLE_RELBRb + ISA_SET: I86 + SHORT: jle 0x2 + */ + EXPECT_EQ(2, ild(u"~ ")); +} + +TEST(x86ild, test_66897300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov word ptr [rbx], si + */ + EXPECT_EQ(4, ild(u"fës ")); +} + +TEST(x86ild, test_4889F3) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rbx, rsi + */ + EXPECT_EQ(3, ild(u"Hë≤")); +} + +TEST(x86ild, test_4489C1) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov ecx, r8d + */ + EXPECT_EQ(3, ild(u"Dë┴")); +} + +TEST(x86ild, test_40886B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rbx], bpl + */ + EXPECT_EQ(4, ild(u"@êk ")); +} + +TEST(x86ild, test_C7800000000000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_IMMz + ISA_SET: I86 + SHORT: mov dword ptr [rax], 0x0 + */ + EXPECT_EQ(10, ild(u"╟Ç        ")); +} + +TEST(x86ild, test_C7420000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_IMMz + ISA_SET: I86 + SHORT: mov dword ptr [rdx], 0x0 + */ + EXPECT_EQ(7, ild(u"╟B     ")); +} + +TEST(x86ild, test_899000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rax], edx + */ + EXPECT_EQ(6, ild(u"ëÉ    ")); +} + +TEST(x86ild, test_59) { + /* + ICLASS: POP + CATEGORY: POP + EXTENSION: BASE + IFORM: POP_GPRv_58 + ISA_SET: I86 + SHORT: pop rcx + */ + EXPECT_EQ(1, ild(u"Y")); +} + +TEST(x86ild, test_48D3E2) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_CL_D3r4 + ISA_SET: I86 + SHORT: shl rdx, cl + */ + EXPECT_EQ(3, ild(u"H╙Γ")); +} + +TEST(x86ild, test_48C7470000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_IMMz + ISA_SET: I86 + SHORT: mov qword ptr [rdi], 0x0 + */ + EXPECT_EQ(8, ild(u"H╟G     ")); +} + +TEST(x86ild, test_488B4F00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rcx, qword ptr [rdi] + */ + EXPECT_EQ(4, ild(u"HïO ")); +} + +TEST(x86ild, test_4863F6) { + /* + ICLASS: MOVSXD + CATEGORY: DATAXFER + EXTENSION: LONGMODE + IFORM: MOVSXD_GPRv_GPR32 + ISA_SET: LONGMODE + SHORT: movsxd rsi, esi + */ + EXPECT_EQ(3, ild(u"Hc÷")); +} + +TEST(x86ild, test_4489E2) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edx, r12d + */ + EXPECT_EQ(3, ild(u"DëΓ")); +} + +TEST(x86ild, test_415F) { + /* + ICLASS: POP + CATEGORY: POP + EXTENSION: BASE + IFORM: POP_GPRv_58 + ISA_SET: I86 + SHORT: pop r15 + */ + EXPECT_EQ(2, ild(u"A_")); +} + +TEST(x86ild, test_4157) { + /* + ICLASS: PUSH + CATEGORY: PUSH + EXTENSION: BASE + IFORM: PUSH_GPRv_50 + ISA_SET: I86 + SHORT: push r15 + */ + EXPECT_EQ(2, ild(u"AW")); +} + +TEST(x86ild, test_408A6B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov bpl, byte ptr [rbx] + */ + EXPECT_EQ(4, ild(u"@èk ")); +} + +TEST(x86ild, test_4088C6) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov sil, al + */ + EXPECT_EQ(3, ild(u"@ê╞")); +} + +TEST(x86ild, test_8A4600) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov al, byte ptr [rsi] + */ + EXPECT_EQ(3, ild(u"èF ")); +} + +TEST(x86ild, test_8A04D500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov al, byte ptr [rdx*8] + */ + EXPECT_EQ(7, ild(u"è♦╒    ")); +} + +TEST(x86ild, test_89F8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov eax, edi + */ + EXPECT_EQ(2, ild(u"ë°")); +} + +TEST(x86ild, test_89C6) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov esi, eax + */ + EXPECT_EQ(2, ild(u"ë╞")); +} + +TEST(x86ild, test_89542400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rsp], edx + */ + EXPECT_EQ(4, ild(u"ëT$ ")); +} + +TEST(x86ild, test_88CA) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov dl, cl + */ + EXPECT_EQ(2, ild(u"ê╩")); +} + +TEST(x86ild, test_4C89EF) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rdi, r13 + */ + EXPECT_EQ(3, ild(u"Lë∩")); +} + +TEST(x86ild, test_48C70700000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_IMMz + ISA_SET: I86 + SHORT: mov qword ptr [rdi], 0x0 + */ + EXPECT_EQ(7, ild(u"H╟•    ")); +} + +TEST(x86ild, test_48897700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rdi], rsi + */ + EXPECT_EQ(4, ild(u"Hëw ")); +} + +TEST(x86ild, test_448B6C2400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r13d, dword ptr [rsp] + */ + EXPECT_EQ(5, ild(u"Dïl$ ")); +} + +TEST(x86ild, test_FF24CD00000000) { + /* + ICLASS: JMP + CATEGORY: UNCOND_BR + EXTENSION: BASE + IFORM: JMP_MEMv + ISA_SET: I86 + SHORT: jmp qword ptr [rcx*8] + */ + EXPECT_EQ(7, ild(u"λ$═    ")); +} + +TEST(x86ild, test_F2AE) { + /* + ICLASS: REPNE_SCASB + CATEGORY: STRINGOP + EXTENSION: BASE + IFORM: REPNE_SCASB + ISA_SET: I86 + SHORT: repne scasb byte ptr [rdi] + */ + EXPECT_EQ(2, ild(u"≥«")); +} + +TEST(x86ild, test_E90083E000) { + /* + ICLASS: JMP + CATEGORY: UNCOND_BR + EXTENSION: BASE + IFORM: JMP_RELBRd + ISA_SET: I86 + SHORT: jmp 0xe08305 + */ + EXPECT_EQ(5, ild(u"Θ âα ")); +} + +TEST(x86ild, test_C7040700000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_IMMz + ISA_SET: I86 + SHORT: mov dword ptr [rdi+rax*1], 0x0 + */ + EXPECT_EQ(7, ild(u"╟♦•    ")); +} + +TEST(x86ild, test_C644240000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_IMMb + ISA_SET: I86 + SHORT: mov byte ptr [rsp], 0x0 + */ + EXPECT_EQ(5, ild(u"╞D$  ")); +} + +TEST(x86ild, test_8B9200000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [rdx] + */ + EXPECT_EQ(6, ild(u"ïÆ    ")); +} + +TEST(x86ild, test_8B7D00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edi, dword ptr [rbp] + */ + EXPECT_EQ(3, ild(u"ï} ")); +} + +TEST(x86ild, test_8A8000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov al, byte ptr [rax] + */ + EXPECT_EQ(6, ild(u"èÇ    ")); +} + +TEST(x86ild, test_8A5000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov dl, byte ptr [rax] + */ + EXPECT_EQ(3, ild(u"èP ")); +} + +TEST(x86ild, test_89F5) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov ebp, esi + */ + EXPECT_EQ(2, ild(u"ë⌡")); +} + +TEST(x86ild, test_89EA) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edx, ebp + */ + EXPECT_EQ(2, ild(u"ëΩ")); +} + +TEST(x86ild, test_89E8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov eax, ebp + */ + EXPECT_EQ(2, ild(u"ëΦ")); +} + +TEST(x86ild, test_668B7B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov di, word ptr [rbx] + */ + EXPECT_EQ(4, ild(u"fï{ ")); +} + +TEST(x86ild, test_4989FC) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r12, rdi + */ + EXPECT_EQ(3, ild(u"Iëⁿ")); +} + +TEST(x86ild, test_48D3E0) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_CL_D3r4 + ISA_SET: I86 + SHORT: shl rax, cl + */ + EXPECT_EQ(3, ild(u"H╙α")); +} + +TEST(x86ild, test_48BE0000000000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov rsi, 0x0 + */ + EXPECT_EQ(10, ild(u"H╛        ")); +} + +TEST(x86ild, test_488B6F00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rbp, qword ptr [rdi] + */ + EXPECT_EQ(4, ild(u"Hïo ")); +} + +TEST(x86ild, test_488B5500) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdx, qword ptr [rbp] + */ + EXPECT_EQ(4, ild(u"HïU ")); +} + +TEST(x86ild, test_4889E5) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rbp, rsp + */ + EXPECT_EQ(3, ild(u"Hëσ")); +} + +TEST(x86ild, test_4889D5) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rbp, rdx + */ + EXPECT_EQ(3, ild(u"Hë╒")); +} + +TEST(x86ild, test_448B442400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r8d, dword ptr [rsp] + */ + EXPECT_EQ(5, ild(u"DïD$ ")); +} + +TEST(x86ild, test_4488C6) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov sil, r8b + */ + EXPECT_EQ(3, ild(u"Dê╞")); +} + +TEST(x86ild, test_4189C5) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r13d, eax + */ + EXPECT_EQ(3, ild(u"Aë┼")); +} + +TEST(x86ild, test_0F8D00000000) { + /* + ICLASS: JNL + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JNL_RELBRd + ISA_SET: I86 + SHORT: jnl 0x6 + */ + EXPECT_EQ(6, ild(u"☼ì    ")); +} + +TEST(x86ild, test_C6400000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_IMMb + ISA_SET: I86 + SHORT: mov byte ptr [rax], 0x0 + */ + EXPECT_EQ(4, ild(u"╞@  ")); +} + +TEST(x86ild, test_B000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_IMMb_B0 + ISA_SET: I86 + SHORT: mov al, 0x0 + */ + EXPECT_EQ(2, ild(u"░ ")); +} + +TEST(x86ild, test_8BB900000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edi, dword ptr [rcx] + */ + EXPECT_EQ(6, ild(u"ï╣    ")); +} + +TEST(x86ild, test_8BB000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov esi, dword ptr [rax] + */ + EXPECT_EQ(6, ild(u"ï░    ")); +} + +TEST(x86ild, test_8A00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov al, byte ptr [rax] + */ + EXPECT_EQ(2, ild(u"è ")); +} + +TEST(x86ild, test_89C5) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov ebp, eax + */ + EXPECT_EQ(2, ild(u"ë┼")); +} + +TEST(x86ild, test_896A00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rdx], ebp + */ + EXPECT_EQ(3, ild(u"ëj ")); +} + +TEST(x86ild, test_8802) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rdx], al + */ + EXPECT_EQ(2, ild(u"ê☻")); +} + +TEST(x86ild, test_7F00) { + /* + ICLASS: JNLE + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JNLE_RELBRb + ISA_SET: I86 + SHORT: jnle 0x2 + */ + EXPECT_EQ(2, ild(u"⌂ ")); +} + +TEST(x86ild, test_7D00) { + /* + ICLASS: JNL + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JNL_RELBRb + ISA_SET: I86 + SHORT: jnl 0x2 + */ + EXPECT_EQ(2, ild(u"} ")); +} + +TEST(x86ild, test_668B7700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov si, word ptr [rdi] + */ + EXPECT_EQ(4, ild(u"fïw ")); +} + +TEST(x86ild, test_48D3EA) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_CL + ISA_SET: I86 + SHORT: shr rdx, cl + */ + EXPECT_EQ(3, ild(u"H╙Ω")); +} + +TEST(x86ild, test_488B3D00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdi, qword ptr [rip] + */ + EXPECT_EQ(7, ild(u"Hï=    ")); +} + +TEST(x86ild, test_488B14DD00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdx, qword ptr [rbx*8] + */ + EXPECT_EQ(8, ild(u"Hï¶▌    ")); +} + +TEST(x86ild, test_488B0500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rax, qword ptr [rip] + */ + EXPECT_EQ(7, ild(u"Hï♣    ")); +} + +TEST(x86ild, test_4889FE) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rsi, rdi + */ + EXPECT_EQ(3, ild(u"Hë■")); +} + +TEST(x86ild, test_4889D9) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rcx, rbx + */ + EXPECT_EQ(3, ild(u"Hë┘")); +} + +TEST(x86ild, test_4889C8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rax, rcx + */ + EXPECT_EQ(3, ild(u"Hë╚")); +} + +TEST(x86ild, test_4889C3) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rbx, rax + */ + EXPECT_EQ(3, ild(u"Hë├")); +} + +TEST(x86ild, test_488937) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rdi], rsi + */ + EXPECT_EQ(3, ild(u"Hë7")); +} + +TEST(x86ild, test_4863C9) { + /* + ICLASS: MOVSXD + CATEGORY: DATAXFER + EXTENSION: LONGMODE + IFORM: MOVSXD_GPRv_GPR32 + ISA_SET: LONGMODE + SHORT: movsxd rcx, ecx + */ + EXPECT_EQ(3, ild(u"Hc╔")); +} + +TEST(x86ild, test_448B7C2400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r15d, dword ptr [rsp] + */ + EXPECT_EQ(5, ild(u"Dï|$ ")); +} + +TEST(x86ild, test_448A5700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov r10b, byte ptr [rdi] + */ + EXPECT_EQ(4, ild(u"DèW ")); +} + +TEST(x86ild, test_448A4300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov r8b, byte ptr [rbx] + */ + EXPECT_EQ(4, ild(u"DèC ")); +} + +TEST(x86ild, test_4488D2) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov dl, r10b + */ + EXPECT_EQ(3, ild(u"Dê╥")); +} + +TEST(x86ild, test_4488C9) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov cl, r9b + */ + EXPECT_EQ(3, ild(u"Dê╔")); +} + +TEST(x86ild, test_41BC00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov r12d, 0x0 + */ + EXPECT_EQ(6, ild(u"A╝    ")); +} + +TEST(x86ild, test_4189F5) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r13d, esi + */ + EXPECT_EQ(3, ild(u"Aë⌡")); +} + +TEST(x86ild, test_40887700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rdi], sil + */ + EXPECT_EQ(4, ild(u"@êw ")); +} + +TEST(x86ild, test_decode) { + /* + */ + EXPECT_EQ(2, ild(u"▐═")); +} + +TEST(x86ild, test_D3E0) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_CL_D3r4 + ISA_SET: I86 + SHORT: shl eax, cl + */ + EXPECT_EQ(2, ild(u"╙α")); +} + +TEST(x86ild, test_BD00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov ebp, 0x0 + */ + EXPECT_EQ(5, ild(u"╜    ")); +} + +TEST(x86ild, test_8B4B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ecx, dword ptr [rbx] + */ + EXPECT_EQ(3, ild(u"ïK ")); +} + +TEST(x86ild, test_8B07) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov eax, dword ptr [rdi] + */ + EXPECT_EQ(2, ild(u"ï•")); +} + +TEST(x86ild, test_8A9000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov dl, byte ptr [rax] + */ + EXPECT_EQ(6, ild(u"èÉ    ")); +} + +TEST(x86ild, test_8A4A00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov cl, byte ptr [rdx] + */ + EXPECT_EQ(3, ild(u"èJ ")); +} + +TEST(x86ild, test_8A4500) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov al, byte ptr [rbp] + */ + EXPECT_EQ(3, ild(u"èE ")); +} + +TEST(x86ild, test_8A14D500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov dl, byte ptr [rdx*8] + */ + EXPECT_EQ(7, ild(u"è¶╒    ")); +} + +TEST(x86ild, test_8A0CD500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov cl, byte ptr [rdx*8] + */ + EXPECT_EQ(7, ild(u"è♀╒    ")); +} + +TEST(x86ild, test_8A0C08) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov cl, byte ptr [rax+rcx*1] + */ + EXPECT_EQ(3, ild(u"è♀◘")); +} + +TEST(x86ild, test_89D6) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov esi, edx + */ + EXPECT_EQ(2, ild(u"ë╓")); +} + +TEST(x86ild, test_89D5) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov ebp, edx + */ + EXPECT_EQ(2, ild(u"ë╒")); +} + +TEST(x86ild, test_897700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rdi], esi + */ + EXPECT_EQ(3, ild(u"ëw ")); +} + +TEST(x86ild, test_895A00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rdx], ebx + */ + EXPECT_EQ(3, ild(u"ëZ ")); +} + +TEST(x86ild, test_895000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rax], edx + */ + EXPECT_EQ(3, ild(u"ëP ")); +} + +TEST(x86ild, test_8910) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rax], edx + */ + EXPECT_EQ(2, ild(u"ë►")); +} + +TEST(x86ild, test_7C00) { + /* + ICLASS: JL + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JL_RELBRb + ISA_SET: I86 + SHORT: jl 0x2 + */ + EXPECT_EQ(2, ild(u"| ")); +} + +TEST(x86ild, test_4C89C1) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rcx, r8 + */ + EXPECT_EQ(3, ild(u"Lë┴")); +} + +TEST(x86ild, test_498B5500) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdx, qword ptr [r13] + */ + EXPECT_EQ(4, ild(u"IïU ")); +} + +TEST(x86ild, test_4989D5) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r13, rdx + */ + EXPECT_EQ(3, ild(u"Ië╒")); +} + +TEST(x86ild, test_48D3E8) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_CL + ISA_SET: I86 + SHORT: shr rax, cl + */ + EXPECT_EQ(3, ild(u"H╙Φ")); +} + +TEST(x86ild, test_48C7430000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_IMMz + ISA_SET: I86 + SHORT: mov qword ptr [rbx], 0x0 + */ + EXPECT_EQ(8, ild(u"H╟C     ")); +} + +TEST(x86ild, test_4898) { + /* + ICLASS: CDQE + CATEGORY: CONVERT + EXTENSION: LONGMODE + IFORM: CDQE + ISA_SET: LONGMODE + SHORT: cdqe + */ + EXPECT_EQ(2, ild(u"Hÿ")); +} + +TEST(x86ild, test_488B9600000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdx, qword ptr [rsi] + */ + EXPECT_EQ(7, ild(u"Hïû    ")); +} + +TEST(x86ild, test_488B0B) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rcx, qword ptr [rbx] + */ + EXPECT_EQ(3, ild(u"Hï♂")); +} + +TEST(x86ild, test_4889F7) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rdi, rsi + */ + EXPECT_EQ(3, ild(u"Hë≈")); +} + +TEST(x86ild, test_4889F5) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rbp, rsi + */ + EXPECT_EQ(3, ild(u"Hë⌡")); +} + +TEST(x86ild, test_4889F0) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rax, rsi + */ + EXPECT_EQ(3, ild(u"Hë≡")); +} + +TEST(x86ild, test_4889DE) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rsi, rbx + */ + EXPECT_EQ(3, ild(u"Hë▐")); +} + +TEST(x86ild, test_4889D1) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rcx, rdx + */ + EXPECT_EQ(3, ild(u"Hë╤")); +} + +TEST(x86ild, test_4889CE) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rsi, rcx + */ + EXPECT_EQ(3, ild(u"Hë╬")); +} + +TEST(x86ild, test_4889C7) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rdi, rax + */ + EXPECT_EQ(3, ild(u"Hë╟")); +} + +TEST(x86ild, test_48893D00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rip], rdi + */ + EXPECT_EQ(7, ild(u"Hë=    ")); +} + +TEST(x86ild, test_48893500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rip], rsi + */ + EXPECT_EQ(7, ild(u"Hë5    ")); +} + +TEST(x86ild, test_48891500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rip], rdx + */ + EXPECT_EQ(7, ild(u"Hë§    ")); +} + +TEST(x86ild, test_488903) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rbx], rax + */ + EXPECT_EQ(3, ild(u"Hë♥")); +} + +TEST(x86ild, test_4489FF) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edi, r15d + */ + EXPECT_EQ(3, ild(u"Dëλ")); +} + +TEST(x86ild, test_4489E7) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edi, r12d + */ + EXPECT_EQ(3, ild(u"Dëτ")); +} + +TEST(x86ild, test_4489E0) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov eax, r12d + */ + EXPECT_EQ(3, ild(u"Dëα")); +} + +TEST(x86ild, test_4489D9) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov ecx, r11d + */ + EXPECT_EQ(3, ild(u"Dë┘")); +} + +TEST(x86ild, test_4488D0) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov al, r10b + */ + EXPECT_EQ(3, ild(u"Dê╨")); +} + +TEST(x86ild, test_41BE00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov r14d, 0x0 + */ + EXPECT_EQ(6, ild(u"A╛    ")); +} + +TEST(x86ild, test_41B900000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov r9d, 0x0 + */ + EXPECT_EQ(6, ild(u"A╣    ")); +} + +TEST(x86ild, test_4189E8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r8d, ebp + */ + EXPECT_EQ(3, ild(u"AëΦ")); +} + +TEST(x86ild, test_4189D0) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r8d, edx + */ + EXPECT_EQ(3, ild(u"Aë╨")); +} + +TEST(x86ild, test_4189C7) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r15d, eax + */ + EXPECT_EQ(3, ild(u"Aë╟")); +} + +TEST(x86ild, test_4188C0) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov r8b, al + */ + EXPECT_EQ(3, ild(u"Aê└")); +} + +TEST(x86ild, test_408A7B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov dil, byte ptr [rbx] + */ + EXPECT_EQ(4, ild(u"@è{ ")); +} + +TEST(x86ild, test_4088F1) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov cl, sil + */ + EXPECT_EQ(3, ild(u"@ê±")); +} + +TEST(x86ild, test_4088D6) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov sil, dl + */ + EXPECT_EQ(3, ild(u"@ê╓")); +} + +TEST(x86ild, test_4088C7) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov dil, al + */ + EXPECT_EQ(3, ild(u"@ê╟")); +} + +TEST(x86ild, test_0F8300000000) { + /* + ICLASS: JNB + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JNB_RELBRd + ISA_SET: I86 + SHORT: jnb 0x6 + */ + EXPECT_EQ(6, ild(u"☼â    ")); +} + +TEST(x86ild, test_FF24F500000000) { + /* + ICLASS: JMP + CATEGORY: UNCOND_BR + EXTENSION: BASE + IFORM: JMP_MEMv + ISA_SET: I86 + SHORT: jmp qword ptr [rsi*8] + */ + EXPECT_EQ(7, ild(u"λ$⌡    ")); +} + +TEST(x86ild, test_E80083E200) { + /* + ICLASS: CALL_NEAR + CATEGORY: CALL + EXTENSION: BASE + IFORM: CALL_NEAR_RELBRd + ISA_SET: I86 + SHORT: call 0xe28305 + */ + EXPECT_EQ(5, ild(u"Φ âΓ ")); +} + +TEST(x86ild, test_D3E7) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_CL_D3r4 + ISA_SET: I86 + SHORT: shl edi, cl + */ + EXPECT_EQ(2, ild(u"╙τ")); +} + +TEST(x86ild, test_D2C1) { + /* + ICLASS: ROL + CATEGORY: ROTATE + EXTENSION: BASE + IFORM: ROL_GPR8_CL + ISA_SET: I86 + SHORT: rol cl, cl + */ + EXPECT_EQ(2, ild(u"╥┴")); +} + +TEST(x86ild, test_C784240000000000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_IMMz + ISA_SET: I86 + SHORT: mov dword ptr [rsp], 0x0 + */ + EXPECT_EQ(11, ild(u"╟ä$        ")); +} + +TEST(x86ild, test_C744240000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_IMMz + ISA_SET: I86 + SHORT: mov dword ptr [rsp], 0x0 + */ + EXPECT_EQ(8, ild(u"╟D$     ")); +} + +TEST(x86ild, test_C6840E0000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_IMMb + ISA_SET: I86 + SHORT: mov byte ptr [rsi+rcx*1], 0x0 + */ + EXPECT_EQ(8, ild(u"╞ä♫     ")); +} + +TEST(x86ild, test_C6420000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_IMMb + ISA_SET: I86 + SHORT: mov byte ptr [rdx], 0x0 + */ + EXPECT_EQ(4, ild(u"╞B  ")); +} + +TEST(x86ild, test_C60700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_IMMb + ISA_SET: I86 + SHORT: mov byte ptr [rdi], 0x0 + */ + EXPECT_EQ(3, ild(u"╞• ")); +} + +TEST(x86ild, test_C60600) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_IMMb + ISA_SET: I86 + SHORT: mov byte ptr [rsi], 0x0 + */ + EXPECT_EQ(3, ild(u"╞♠ ")); +} + +TEST(x86ild, test_8BB200000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov esi, dword ptr [rdx] + */ + EXPECT_EQ(6, ild(u"ï▓    ")); +} + +TEST(x86ild, test_8B7F00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edi, dword ptr [rdi] + */ + EXPECT_EQ(3, ild(u"ï⌂ ")); +} + +TEST(x86ild, test_8B7C2400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edi, dword ptr [rsp] + */ + EXPECT_EQ(4, ild(u"ï|$ ")); +} + +TEST(x86ild, test_8B7B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edi, dword ptr [rbx] + */ + EXPECT_EQ(3, ild(u"ï{ ")); +} + +TEST(x86ild, test_8B5100) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [rcx] + */ + EXPECT_EQ(3, ild(u"ïQ ")); +} + +TEST(x86ild, test_8B4C2400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ecx, dword ptr [rsp] + */ + EXPECT_EQ(4, ild(u"ïL$ ")); +} + +TEST(x86ild, test_8B16) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [rsi] + */ + EXPECT_EQ(2, ild(u"ï▬")); +} + +TEST(x86ild, test_8B10) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [rax] + */ + EXPECT_EQ(2, ild(u"ï►")); +} + +TEST(x86ild, test_8B0C8500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ecx, dword ptr [rax*4] + */ + EXPECT_EQ(7, ild(u"ï♀à    ")); +} + +TEST(x86ild, test_8B04FD00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov eax, dword ptr [rdi*8] + */ + EXPECT_EQ(7, ild(u"ï♦²    ")); +} + +TEST(x86ild, test_8B04C500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov eax, dword ptr [rax*8] + */ + EXPECT_EQ(7, ild(u"ï♦┼    ")); +} + +TEST(x86ild, test_8B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov eax, dword ptr [rax] + */ + EXPECT_EQ(2, ild(u"ï ")); +} + +TEST(x86ild, test_8A14C500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov dl, byte ptr [rax*8] + */ + EXPECT_EQ(7, ild(u"è¶┼    ")); +} + +TEST(x86ild, test_8A0401) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov al, byte ptr [rcx+rax*1] + */ + EXPECT_EQ(3, ild(u"è♦☺")); +} + +TEST(x86ild, test_89FB) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov ebx, edi + */ + EXPECT_EQ(2, ild(u"ë√")); +} + +TEST(x86ild, test_89DF) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edi, ebx + */ + EXPECT_EQ(2, ild(u"ë▀")); +} + +TEST(x86ild, test_89D8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov eax, ebx + */ + EXPECT_EQ(2, ild(u"ë╪")); +} + +TEST(x86ild, test_89CB) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov ebx, ecx + */ + EXPECT_EQ(2, ild(u"ë╦")); +} + +TEST(x86ild, test_899A00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rdx], ebx + */ + EXPECT_EQ(6, ild(u"ëÜ    ")); +} + +TEST(x86ild, test_894B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rbx], ecx + */ + EXPECT_EQ(3, ild(u"ëK ")); +} + +TEST(x86ild, test_890424) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rsp], eax + */ + EXPECT_EQ(3, ild(u"ë♦$")); +} + +TEST(x86ild, test_8810) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rax], dl + */ + EXPECT_EQ(2, ild(u"ê►")); +} + +TEST(x86ild, test_66C747000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_IMMz + ISA_SET: I86 + SHORT: mov word ptr [rdi], 0x0 + */ + EXPECT_EQ(6, ild(u"f╟G   ")); +} + +TEST(x86ild, test_668910) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov word ptr [rax], dx + */ + EXPECT_EQ(3, ild(u"fë►")); +} + +TEST(x86ild, test_4D89EC) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r12, r13 + */ + EXPECT_EQ(3, ild(u"Më∞")); +} + +TEST(x86ild, test_4C89FA) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rdx, r15 + */ + EXPECT_EQ(3, ild(u"Lë·")); +} + +TEST(x86ild, test_4C89E6) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rsi, r12 + */ + EXPECT_EQ(3, ild(u"Lëμ")); +} + +TEST(x86ild, test_4C89D0) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rax, r10 + */ + EXPECT_EQ(3, ild(u"Lë╨")); +} + +TEST(x86ild, test_49D3E0) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_CL_D3r4 + ISA_SET: I86 + SHORT: shl r8, cl + */ + EXPECT_EQ(3, ild(u"I╙α")); +} + +TEST(x86ild, test_4989F4) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r12, rsi + */ + EXPECT_EQ(3, ild(u"Ië⌠")); +} + +TEST(x86ild, test_4989C4) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r12, rax + */ + EXPECT_EQ(3, ild(u"Ië─")); +} + +TEST(x86ild, test_48BF0000000000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov rdi, 0x0 + */ + EXPECT_EQ(10, ild(u"H┐        ")); +} + +TEST(x86ild, test_488B9100000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdx, qword ptr [rcx] + */ + EXPECT_EQ(7, ild(u"Hïæ    ")); +} + +TEST(x86ild, test_488B7700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rsi, qword ptr [rdi] + */ + EXPECT_EQ(4, ild(u"Hïw ")); +} + +TEST(x86ild, test_488B5200) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdx, qword ptr [rdx] + */ + EXPECT_EQ(4, ild(u"HïR ")); +} + +TEST(x86ild, test_488B04D0) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rax, qword ptr [rax+rdx*8] + */ + EXPECT_EQ(4, ild(u"Hï♦╨")); +} + +TEST(x86ild, test_4889E9) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rcx, rbp + */ + EXPECT_EQ(3, ild(u"HëΘ")); +} + +TEST(x86ild, test_4889E7) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rdi, rsp + */ + EXPECT_EQ(3, ild(u"Hëτ")); +} + +TEST(x86ild, test_4889D7) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rdi, rdx + */ + EXPECT_EQ(3, ild(u"Hë╫")); +} + +TEST(x86ild, test_4889CD) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rbp, rcx + */ + EXPECT_EQ(3, ild(u"Hë═")); +} + +TEST(x86ild, test_48895700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rdi], rdx + */ + EXPECT_EQ(4, ild(u"HëW ")); +} + +TEST(x86ild, test_48894700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rdi], rax + */ + EXPECT_EQ(4, ild(u"HëG ")); +} + +TEST(x86ild, test_48894300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rbx], rax + */ + EXPECT_EQ(4, ild(u"HëC ")); +} + +TEST(x86ild, test_488910) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rax], rdx + */ + EXPECT_EQ(3, ild(u"Hë►")); +} + +TEST(x86ild, test_48890D00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rip], rcx + */ + EXPECT_EQ(7, ild(u"Hë♪    ")); +} + +TEST(x86ild, test_488902) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rdx], rax + */ + EXPECT_EQ(3, ild(u"Hë☻")); +} + +TEST(x86ild, test_4863D2) { + /* + ICLASS: MOVSXD + CATEGORY: DATAXFER + EXTENSION: LONGMODE + IFORM: MOVSXD_GPRv_GPR32 + ISA_SET: LONGMODE + SHORT: movsxd rdx, edx + */ + EXPECT_EQ(3, ild(u"Hc╥")); +} + +TEST(x86ild, test_4589CA) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r10d, r9d + */ + EXPECT_EQ(3, ild(u"Eë╩")); +} + +TEST(x86ild, test_4588C8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov r8b, r9b + */ + EXPECT_EQ(3, ild(u"Eê╚")); +} + +TEST(x86ild, test_4489FA) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edx, r15d + */ + EXPECT_EQ(3, ild(u"Dë·")); +} + +TEST(x86ild, test_4489F7) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edi, r14d + */ + EXPECT_EQ(3, ild(u"Dë≈")); +} + +TEST(x86ild, test_4489EF) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edi, r13d + */ + EXPECT_EQ(3, ild(u"Dë∩")); +} + +TEST(x86ild, test_4489E1) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov ecx, r12d + */ + EXPECT_EQ(3, ild(u"Dëß")); +} + +TEST(x86ild, test_4489442400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rsp], r8d + */ + EXPECT_EQ(5, ild(u"DëD$ ")); +} + +TEST(x86ild, test_4488CA) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov dl, r9b + */ + EXPECT_EQ(3, ild(u"Dê╩")); +} + +TEST(x86ild, test_44885300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rbx], r10b + */ + EXPECT_EQ(4, ild(u"DêS ")); +} + +TEST(x86ild, test_44884300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rbx], r8b + */ + EXPECT_EQ(4, ild(u"DêC ")); +} + +TEST(x86ild, test_428B148D00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [r9*4] + */ + EXPECT_EQ(8, ild(u"Bï¶ì    ")); +} + +TEST(x86ild, test_41D3E0) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_CL_D3r4 + ISA_SET: I86 + SHORT: shl r8d, cl + */ + EXPECT_EQ(3, ild(u"A╙α")); +} + +TEST(x86ild, test_41BF00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov r15d, 0x0 + */ + EXPECT_EQ(6, ild(u"A┐    ")); +} + +TEST(x86ild, test_41BD00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov r13d, 0x0 + */ + EXPECT_EQ(6, ild(u"A╜    ")); +} + +TEST(x86ild, test_41B800000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMv + ISA_SET: I86 + SHORT: mov r8d, 0x0 + */ + EXPECT_EQ(6, ild(u"A╕    ")); +} + +TEST(x86ild, test_4189F4) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r12d, esi + */ + EXPECT_EQ(3, ild(u"Aë⌠")); +} + +TEST(x86ild, test_4189F2) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r10d, esi + */ + EXPECT_EQ(3, ild(u"Aë≥")); +} + +TEST(x86ild, test_4189C8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r8d, ecx + */ + EXPECT_EQ(3, ild(u"Aë╚")); +} + +TEST(x86ild, test_4088F9) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov cl, dil + */ + EXPECT_EQ(3, ild(u"@ê∙")); +} + +TEST(x86ild, test_4088F2) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov dl, sil + */ + EXPECT_EQ(3, ild(u"@ê≥")); +} + +TEST(x86ild, test_4088E8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov al, bpl + */ + EXPECT_EQ(3, ild(u"@êΦ")); +} + +TEST(x86ild, test_0F8900000000) { + /* + ICLASS: JNS + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JNS_RELBRd + ISA_SET: I86 + SHORT: jns 0x6 + */ + EXPECT_EQ(6, ild(u"☼ë    ")); +} + +TEST(x86ild, test_0F8600000000) { + /* + ICLASS: JBE + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JBE_RELBRd + ISA_SET: I86 + SHORT: jbe 0x6 + */ + EXPECT_EQ(6, ild(u"☼å    ")); +} + +TEST(x86ild, test_FF14C500000000) { + /* + ICLASS: CALL_NEAR + CATEGORY: CALL + EXTENSION: BASE + IFORM: CALL_NEAR_MEMv + ISA_SET: I86 + SHORT: call qword ptr [rax*8] + */ + EXPECT_EQ(7, ild(u"λ¶┼    ")); +} + +TEST(x86ild, test_F3C3) { + /* + ICLASS: RET_NEAR + CATEGORY: RET + EXTENSION: BASE + IFORM: RET_NEAR + ISA_SET: I86 + SHORT: ret + */ + EXPECT_EQ(2, ild(u"≤├")); +} + +TEST(x86ild, test_F3A4) { + /* + ICLASS: REP_MOVSB + CATEGORY: STRINGOP + EXTENSION: BASE + IFORM: REP_MOVSB + ISA_SET: I86 + SHORT: rep movsb byte ptr [rdi], byte ptr [rsi] + */ + EXPECT_EQ(2, ild(u"≤ñ")); +} + +TEST(x86ild, test_D3E2) { + /* + ICLASS: SHL + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHL_GPRv_CL_D3r4 + ISA_SET: I86 + SHORT: shl edx, cl + */ + EXPECT_EQ(2, ild(u"╙Γ")); +} + +TEST(x86ild, test_C6040300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_IMMb + ISA_SET: I86 + SHORT: mov byte ptr [rbx+rax*1], 0x0 + */ + EXPECT_EQ(4, ild(u"╞♦♥ ")); +} + +TEST(x86ild, test_C60100) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_IMMb + ISA_SET: I86 + SHORT: mov byte ptr [rcx], 0x0 + */ + EXPECT_EQ(3, ild(u"╞☺ ")); +} + +TEST(x86ild, test_B200) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_IMMb_B0 + ISA_SET: I86 + SHORT: mov dl, 0x0 + */ + EXPECT_EQ(2, ild(u"▓ ")); +} + +TEST(x86ild, test_8B8100000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov eax, dword ptr [rcx] + */ + EXPECT_EQ(6, ild(u"ïü    ")); +} + +TEST(x86ild, test_8B7500) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov esi, dword ptr [rbp] + */ + EXPECT_EQ(3, ild(u"ïu ")); +} + +TEST(x86ild, test_8B6800) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ebp, dword ptr [rax] + */ + EXPECT_EQ(3, ild(u"ïh ")); +} + +TEST(x86ild, test_8B4800) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ecx, dword ptr [rax] + */ + EXPECT_EQ(3, ild(u"ïH ")); +} + +TEST(x86ild, test_8B4500) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov eax, dword ptr [rbp] + */ + EXPECT_EQ(3, ild(u"ïE ")); +} + +TEST(x86ild, test_8B3F) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edi, dword ptr [rdi] + */ + EXPECT_EQ(2, ild(u"ï?")); +} + +TEST(x86ild, test_8B3C24) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edi, dword ptr [rsp] + */ + EXPECT_EQ(3, ild(u"ï<$")); +} + +TEST(x86ild, test_8B348500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov esi, dword ptr [rax*4] + */ + EXPECT_EQ(7, ild(u"ï4à    ")); +} + +TEST(x86ild, test_8B28) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ebp, dword ptr [rax] + */ + EXPECT_EQ(2, ild(u"ï(")); +} + +TEST(x86ild, test_8B1E) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ebx, dword ptr [rsi] + */ + EXPECT_EQ(2, ild(u"ï▲")); +} + +TEST(x86ild, test_8B1500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [rip] + */ + EXPECT_EQ(6, ild(u"ï§    ")); +} + +TEST(x86ild, test_8B14F500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [rsi*8] + */ + EXPECT_EQ(7, ild(u"ï¶⌡    ")); +} + +TEST(x86ild, test_8B14C500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov edx, dword ptr [rax*8] + */ + EXPECT_EQ(7, ild(u"ï¶┼    ")); +} + +TEST(x86ild, test_8B0CCD00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ecx, dword ptr [rcx*8] + */ + EXPECT_EQ(7, ild(u"ï♀═    ")); +} + +TEST(x86ild, test_8B0CBD00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ecx, dword ptr [rdi*4] + */ + EXPECT_EQ(7, ild(u"ï♀╜    ")); +} + +TEST(x86ild, test_8B0CB500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ecx, dword ptr [rsi*4] + */ + EXPECT_EQ(7, ild(u"ï♀╡    ")); +} + +TEST(x86ild, test_8B0C8D00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov ecx, dword ptr [rcx*4] + */ + EXPECT_EQ(7, ild(u"ï♀ì    ")); +} + +TEST(x86ild, test_8B06) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov eax, dword ptr [rsi] + */ + EXPECT_EQ(2, ild(u"ï♠")); +} + +TEST(x86ild, test_8B04B500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov eax, dword ptr [rsi*4] + */ + EXPECT_EQ(7, ild(u"ï♦╡    ")); +} + +TEST(x86ild, test_8A9200000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov dl, byte ptr [rdx] + */ + EXPECT_EQ(6, ild(u"èÆ    ")); +} + +TEST(x86ild, test_8A8900000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov cl, byte ptr [rcx] + */ + EXPECT_EQ(6, ild(u"èë    ")); +} + +TEST(x86ild, test_8A841000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov al, byte ptr [rax+rdx*1] + */ + EXPECT_EQ(7, ild(u"èä►    ")); +} + +TEST(x86ild, test_8A542400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov dl, byte ptr [rsp] + */ + EXPECT_EQ(4, ild(u"èT$ ")); +} + +TEST(x86ild, test_8A4E00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov cl, byte ptr [rsi] + */ + EXPECT_EQ(3, ild(u"èN ")); +} + +TEST(x86ild, test_8A4D00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov cl, byte ptr [rbp] + */ + EXPECT_EQ(3, ild(u"èM ")); +} + +TEST(x86ild, test_8A14F500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov dl, byte ptr [rsi*8] + */ + EXPECT_EQ(7, ild(u"è¶⌡    ")); +} + +TEST(x86ild, test_8A149500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov dl, byte ptr [rdx*4] + */ + EXPECT_EQ(7, ild(u"è¶ò    ")); +} + +TEST(x86ild, test_8A1411) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov dl, byte ptr [rcx+rdx*1] + */ + EXPECT_EQ(3, ild(u"è¶◄")); +} + +TEST(x86ild, test_8A140A) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov dl, byte ptr [rdx+rcx*1] + */ + EXPECT_EQ(3, ild(u"è¶◙")); +} + +TEST(x86ild, test_8A1402) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov dl, byte ptr [rdx+rax*1] + */ + EXPECT_EQ(3, ild(u"è¶☻")); +} + +TEST(x86ild, test_8A0C01) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov cl, byte ptr [rcx+rax*1] + */ + EXPECT_EQ(3, ild(u"è♀☺")); +} + +TEST(x86ild, test_8A06) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov al, byte ptr [rsi] + */ + EXPECT_EQ(2, ild(u"è♠")); +} + +TEST(x86ild, test_8A0406) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov al, byte ptr [rsi+rax*1] + */ + EXPECT_EQ(3, ild(u"è♦♠")); +} + +TEST(x86ild, test_8A0402) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov al, byte ptr [rdx+rax*1] + */ + EXPECT_EQ(3, ild(u"è♦☻")); +} + +TEST(x86ild, test_89F9) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov ecx, edi + */ + EXPECT_EQ(2, ild(u"ë∙")); +} + +TEST(x86ild, test_89F3) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov ebx, esi + */ + EXPECT_EQ(2, ild(u"ë≤")); +} + +TEST(x86ild, test_89E9) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov ecx, ebp + */ + EXPECT_EQ(2, ild(u"ëΘ")); +} + +TEST(x86ild, test_89D7) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edi, edx + */ + EXPECT_EQ(2, ild(u"ë╫")); +} + +TEST(x86ild, test_89D3) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov ebx, edx + */ + EXPECT_EQ(2, ild(u"ë╙")); +} + +TEST(x86ild, test_89AA00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rdx], ebp + */ + EXPECT_EQ(6, ild(u"묠   ")); +} + +TEST(x86ild, test_89942400000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rsp], edx + */ + EXPECT_EQ(7, ild(u"ëö$    ")); +} + +TEST(x86ild, test_898200000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rdx], eax + */ + EXPECT_EQ(6, ild(u"ëé    ")); +} + +TEST(x86ild, test_897C2400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rsp], edi + */ + EXPECT_EQ(4, ild(u"ë|$ ")); +} + +TEST(x86ild, test_895D00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rbp], ebx + */ + EXPECT_EQ(3, ild(u"ë] ")); +} + +TEST(x86ild, test_895800) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rax], ebx + */ + EXPECT_EQ(3, ild(u"ëX ")); +} + +TEST(x86ild, test_894C2400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rsp], ecx + */ + EXPECT_EQ(4, ild(u"ëL$ ")); +} + +TEST(x86ild, test_894500) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rbp], eax + */ + EXPECT_EQ(3, ild(u"ëE ")); +} + +TEST(x86ild, test_893D00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rip], edi + */ + EXPECT_EQ(6, ild(u"ë=    ")); +} + +TEST(x86ild, test_891500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rip], edx + */ + EXPECT_EQ(6, ild(u"ë§    ")); +} + +TEST(x86ild, test_8903) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rbx], eax + */ + EXPECT_EQ(2, ild(u"ë♥")); +} + +TEST(x86ild, test_88540700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rdi+rax*1], dl + */ + EXPECT_EQ(4, ild(u"êT• ")); +} + +TEST(x86ild, test_88540300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rbx+rax*1], dl + */ + EXPECT_EQ(4, ild(u"êT♥ ")); +} + +TEST(x86ild, test_885100) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rcx], dl + */ + EXPECT_EQ(3, ild(u"êQ ")); +} + +TEST(x86ild, test_88442400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rsp], al + */ + EXPECT_EQ(4, ild(u"êD$ ")); +} + +TEST(x86ild, test_88441400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rsp+rdx*1], al + */ + EXPECT_EQ(4, ild(u"êD¶ ")); +} + +TEST(x86ild, test_880C33) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rbx+rsi*1], cl + */ + EXPECT_EQ(3, ild(u"ê♀3")); +} + +TEST(x86ild, test_66C782000000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_IMMz + ISA_SET: I86 + SHORT: mov word ptr [rdx], 0x0 + */ + EXPECT_EQ(9, ild(u"f╟é      ")); +} + +TEST(x86ild, test_6690) { + /* + ICLASS: NOP + CATEGORY: NOP + EXTENSION: BASE + IFORM: NOP_90 + ISA_SET: I86 + SHORT: data16 nop + */ + EXPECT_EQ(2, ild(u"fÉ")); +} + +TEST(x86ild, test_668B940000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov dx, word ptr [rax+rax*1] + */ + EXPECT_EQ(8, ild(u"fïö     ")); +} + +TEST(x86ild, test_668B4B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov cx, word ptr [rbx] + */ + EXPECT_EQ(4, ild(u"fïK ")); +} + +TEST(x86ild, test_66897B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov word ptr [rbx], di + */ + EXPECT_EQ(4, ild(u"fë{ ")); +} + +TEST(x86ild, test_66894B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov word ptr [rbx], cx + */ + EXPECT_EQ(4, ild(u"fëK ")); +} + +TEST(x86ild, test_668902) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov word ptr [rdx], ax + */ + EXPECT_EQ(3, ild(u"fë☻")); +} + +TEST(x86ild, test_66448B7500) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r14w, word ptr [rbp] + */ + EXPECT_EQ(5, ild(u"fDïu ")); +} + +TEST(x86ild, test_66448B6F00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r13w, word ptr [rdi] + */ + EXPECT_EQ(5, ild(u"fDïo ")); +} + +TEST(x86ild, test_66448B4700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r8w, word ptr [rdi] + */ + EXPECT_EQ(5, ild(u"fDïG ")); +} + +TEST(x86ild, test_4D89C3) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r11, r8 + */ + EXPECT_EQ(3, ild(u"Më├")); +} + +TEST(x86ild, test_4D63EE) { + /* + ICLASS: MOVSXD + CATEGORY: DATAXFER + EXTENSION: LONGMODE + IFORM: MOVSXD_GPRv_GPR32 + ISA_SET: LONGMODE + SHORT: movsxd r13, r14d + */ + EXPECT_EQ(3, ild(u"Mcε")); +} + +TEST(x86ild, test_4D63C0) { + /* + ICLASS: MOVSXD + CATEGORY: DATAXFER + EXTENSION: LONGMODE + IFORM: MOVSXD_GPRv_GPR32 + ISA_SET: LONGMODE + SHORT: movsxd r8, r8d + */ + EXPECT_EQ(3, ild(u"Mc└")); +} + +TEST(x86ild, test_4C8B7700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r14, qword ptr [rdi] + */ + EXPECT_EQ(4, ild(u"Lïw ")); +} + +TEST(x86ild, test_4C8B6F00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r13, qword ptr [rdi] + */ + EXPECT_EQ(4, ild(u"Lïo ")); +} + +TEST(x86ild, test_4C8B6D00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r13, qword ptr [rbp] + */ + EXPECT_EQ(4, ild(u"Lïm ")); +} + +TEST(x86ild, test_4C8B6700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r12, qword ptr [rdi] + */ + EXPECT_EQ(4, ild(u"Lïg ")); +} + +TEST(x86ild, test_4C8B6300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r12, qword ptr [rbx] + */ + EXPECT_EQ(4, ild(u"Lïc ")); +} + +TEST(x86ild, test_4C8B4700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r8, qword ptr [rdi] + */ + EXPECT_EQ(4, ild(u"LïG ")); +} + +TEST(x86ild, test_4C8B4300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r8, qword ptr [rbx] + */ + EXPECT_EQ(4, ild(u"LïC ")); +} + +TEST(x86ild, test_4C8B2500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r12, qword ptr [rip] + */ + EXPECT_EQ(7, ild(u"Lï%    ")); +} + +TEST(x86ild, test_4C89EE) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rsi, r13 + */ + EXPECT_EQ(3, ild(u"Lëε")); +} + +TEST(x86ild, test_4C89EA) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rdx, r13 + */ + EXPECT_EQ(3, ild(u"LëΩ")); +} + +TEST(x86ild, test_4C89CE) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rsi, r9 + */ + EXPECT_EQ(3, ild(u"Lë╬")); +} + +TEST(x86ild, test_4C89C6) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rsi, r8 + */ + EXPECT_EQ(3, ild(u"Lë╞")); +} + +TEST(x86ild, test_4C897300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rbx], r14 + */ + EXPECT_EQ(4, ild(u"Lës ")); +} + +TEST(x86ild, test_4C896300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rbx], r12 + */ + EXPECT_EQ(4, ild(u"Lëc ")); +} + +TEST(x86ild, test_4A8B34C500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rsi, qword ptr [r8*8] + */ + EXPECT_EQ(8, ild(u"Jï4┼    ")); +} + +TEST(x86ild, test_49D3ED) { + /* + ICLASS: SHR + CATEGORY: SHIFT + EXTENSION: BASE + IFORM: SHR_GPRv_CL + ISA_SET: I86 + SHORT: shr r13, cl + */ + EXPECT_EQ(3, ild(u"I╙φ")); +} + +TEST(x86ild, test_4989FD) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r13, rdi + */ + EXPECT_EQ(3, ild(u"Ië²")); +} + +TEST(x86ild, test_4989F6) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r14, rsi + */ + EXPECT_EQ(3, ild(u"Ië÷")); +} + +TEST(x86ild, test_4989F5) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r13, rsi + */ + EXPECT_EQ(3, ild(u"Ië⌡")); +} + +TEST(x86ild, test_4989F2) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r10, rsi + */ + EXPECT_EQ(3, ild(u"Ië≥")); +} + +TEST(x86ild, test_4989E4) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r12, rsp + */ + EXPECT_EQ(3, ild(u"IëΣ")); +} + +TEST(x86ild, test_4989D0) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r8, rdx + */ + EXPECT_EQ(3, ild(u"Ië╨")); +} + +TEST(x86ild, test_4989CD) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r13, rcx + */ + EXPECT_EQ(3, ild(u"Ië═")); +} + +TEST(x86ild, test_4989C5) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r13, rax + */ + EXPECT_EQ(3, ild(u"Ië┼")); +} + +TEST(x86ild, test_4963F7) { + /* + ICLASS: MOVSXD + CATEGORY: DATAXFER + EXTENSION: LONGMODE + IFORM: MOVSXD_GPRv_GPR32 + ISA_SET: LONGMODE + SHORT: movsxd rsi, r15d + */ + EXPECT_EQ(3, ild(u"Ic≈")); +} + +TEST(x86ild, test_48D3C0) { + /* + ICLASS: ROL + CATEGORY: ROTATE + EXTENSION: BASE + IFORM: ROL_GPRv_CL + ISA_SET: I86 + SHORT: rol rax, cl + */ + EXPECT_EQ(3, ild(u"H╙└")); +} + +TEST(x86ild, test_48C7C000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_IMMz + ISA_SET: I86 + SHORT: mov rax, 0x0 + */ + EXPECT_EQ(7, ild(u"H╟└    ")); +} + +TEST(x86ild, test_48C70300000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_IMMz + ISA_SET: I86 + SHORT: mov qword ptr [rbx], 0x0 + */ + EXPECT_EQ(7, ild(u"H╟♥    ")); +} + +TEST(x86ild, test_488B9000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdx, qword ptr [rax] + */ + EXPECT_EQ(7, ild(u"HïÉ    ")); +} + +TEST(x86ild, test_488B8600000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rax, qword ptr [rsi] + */ + EXPECT_EQ(7, ild(u"Hïå    ")); +} + +TEST(x86ild, test_488B7B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdi, qword ptr [rbx] + */ + EXPECT_EQ(4, ild(u"Hï{ ")); +} + +TEST(x86ild, test_488B7300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rsi, qword ptr [rbx] + */ + EXPECT_EQ(4, ild(u"Hïs ")); +} + +TEST(x86ild, test_488B4500) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rax, qword ptr [rbp] + */ + EXPECT_EQ(4, ild(u"HïE ")); +} + +TEST(x86ild, test_488B4100) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rax, qword ptr [rcx] + */ + EXPECT_EQ(4, ild(u"HïA ")); +} + +TEST(x86ild, test_488B37) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rsi, qword ptr [rdi] + */ + EXPECT_EQ(3, ild(u"Hï7")); +} + +TEST(x86ild, test_488B3424) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rsi, qword ptr [rsp] + */ + EXPECT_EQ(4, ild(u"Hï4$")); +} + +TEST(x86ild, test_488B33) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rsi, qword ptr [rbx] + */ + EXPECT_EQ(3, ild(u"Hï3")); +} + +TEST(x86ild, test_488B1D00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rbx, qword ptr [rip] + */ + EXPECT_EQ(7, ild(u"Hï↔    ")); +} + +TEST(x86ild, test_488B14CA) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdx, qword ptr [rdx+rcx*8] + */ + EXPECT_EQ(4, ild(u"Hï¶╩")); +} + +TEST(x86ild, test_488B13) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdx, qword ptr [rbx] + */ + EXPECT_EQ(3, ild(u"Hï‼")); +} + +TEST(x86ild, test_488B12) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rdx, qword ptr [rdx] + */ + EXPECT_EQ(3, ild(u"Hï↕")); +} + +TEST(x86ild, test_488B0D00000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rcx, qword ptr [rip] + */ + EXPECT_EQ(7, ild(u"Hï♪    ")); +} + +TEST(x86ild, test_488B07) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rax, qword ptr [rdi] + */ + EXPECT_EQ(3, ild(u"Hï•")); +} + +TEST(x86ild, test_488B04F500000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rax, qword ptr [rsi*8] + */ + EXPECT_EQ(8, ild(u"Hï♦⌡    ")); +} + +TEST(x86ild, test_488B03) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rax, qword ptr [rbx] + */ + EXPECT_EQ(3, ild(u"Hï♥")); +} + +TEST(x86ild, test_488B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov rax, qword ptr [rax] + */ + EXPECT_EQ(3, ild(u"Hï ")); +} + +TEST(x86ild, test_4889FA) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rdx, rdi + */ + EXPECT_EQ(3, ild(u"Hë·")); +} + +TEST(x86ild, test_4889F8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rax, rdi + */ + EXPECT_EQ(3, ild(u"Hë°")); +} + +TEST(x86ild, test_4889F1) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rcx, rsi + */ + EXPECT_EQ(3, ild(u"Hë±")); +} + +TEST(x86ild, test_4889D6) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rsi, rdx + */ + EXPECT_EQ(3, ild(u"Hë╓")); +} + +TEST(x86ild, test_4889D3) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rbx, rdx + */ + EXPECT_EQ(3, ild(u"Hë╙")); +} + +TEST(x86ild, test_4889CA) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rdx, rcx + */ + EXPECT_EQ(3, ild(u"Hë╩")); +} + +TEST(x86ild, test_4889C5) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov rbp, rax + */ + EXPECT_EQ(3, ild(u"Hë┼")); +} + +TEST(x86ild, test_48895300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rbx], rdx + */ + EXPECT_EQ(4, ild(u"HëS ")); +} + +TEST(x86ild, test_48893424) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rsp], rsi + */ + EXPECT_EQ(4, ild(u"Hë4$")); +} + +TEST(x86ild, test_488917) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rdi], rdx + */ + EXPECT_EQ(3, ild(u"Hë↨")); +} + +TEST(x86ild, test_488913) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rbx], rdx + */ + EXPECT_EQ(3, ild(u"Hë‼")); +} + +TEST(x86ild, test_488907) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rdi], rax + */ + EXPECT_EQ(3, ild(u"Hë•")); +} + +TEST(x86ild, test_488906) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov qword ptr [rsi], rax + */ + EXPECT_EQ(3, ild(u"Hë♠")); +} + +TEST(x86ild, test_4863F8) { + /* + ICLASS: MOVSXD + CATEGORY: DATAXFER + EXTENSION: LONGMODE + IFORM: MOVSXD_GPRv_GPR32 + ISA_SET: LONGMODE + SHORT: movsxd rdi, eax + */ + EXPECT_EQ(3, ild(u"Hc°")); +} + +TEST(x86ild, test_4863D0) { + /* + ICLASS: MOVSXD + CATEGORY: DATAXFER + EXTENSION: LONGMODE + IFORM: MOVSXD_GPRv_GPR32 + ISA_SET: LONGMODE + SHORT: movsxd rdx, eax + */ + EXPECT_EQ(3, ild(u"Hc╨")); +} + +TEST(x86ild, test_4863C8) { + /* + ICLASS: MOVSXD + CATEGORY: DATAXFER + EXTENSION: LONGMODE + IFORM: MOVSXD_GPRv_GPR32 + ISA_SET: LONGMODE + SHORT: movsxd rcx, eax + */ + EXPECT_EQ(3, ild(u"Hc╚")); +} + +TEST(x86ild, test_4863C7) { + /* + ICLASS: MOVSXD + CATEGORY: DATAXFER + EXTENSION: LONGMODE + IFORM: MOVSXD_GPRv_GPR32 + ISA_SET: LONGMODE + SHORT: movsxd rax, edi + */ + EXPECT_EQ(3, ild(u"Hc╟")); +} + +TEST(x86ild, test_486312) { + /* + ICLASS: MOVSXD + CATEGORY: DATAXFER + EXTENSION: LONGMODE + IFORM: MOVSXD_GPRv_MEMd + ISA_SET: LONGMODE + SHORT: movsxd rdx, dword ptr [rdx] + */ + EXPECT_EQ(3, ild(u"Hc↕")); +} + +TEST(x86ild, test_47882C0E) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [r14+r9*1], r13b + */ + EXPECT_EQ(4, ild(u"Gê,♫")); +} + +TEST(x86ild, test_458B9000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r10d, dword ptr [r8] + */ + EXPECT_EQ(7, ild(u"EïÉ    ")); +} + +TEST(x86ild, test_4589D8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r8d, r11d + */ + EXPECT_EQ(3, ild(u"Eë╪")); +} + +TEST(x86ild, test_4589CB) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r11d, r9d + */ + EXPECT_EQ(3, ild(u"Eë╦")); +} + +TEST(x86ild, test_4589C1) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r9d, r8d + */ + EXPECT_EQ(3, ild(u"Eë┴")); +} + +TEST(x86ild, test_4588F8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov r8b, r15b + */ + EXPECT_EQ(3, ild(u"Eê°")); +} + +TEST(x86ild, test_4588D3) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov r11b, r10b + */ + EXPECT_EQ(3, ild(u"Eê╙")); +} + +TEST(x86ild, test_4588D1) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov r9b, r10b + */ + EXPECT_EQ(3, ild(u"Eê╤")); +} + +TEST(x86ild, test_4588C7) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov r15b, r8b + */ + EXPECT_EQ(3, ild(u"Eê╟")); +} + +TEST(x86ild, test_45883424) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [r12], r14b + */ + EXPECT_EQ(4, ild(u"Eê4$")); +} + +TEST(x86ild, test_448B8100000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r8d, dword ptr [rcx] + */ + EXPECT_EQ(7, ild(u"Dïü    ")); +} + +TEST(x86ild, test_448B7D00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r15d, dword ptr [rbp] + */ + EXPECT_EQ(4, ild(u"Dï} ")); +} + +TEST(x86ild, test_448B7700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r14d, dword ptr [rdi] + */ + EXPECT_EQ(4, ild(u"Dïw ")); +} + +TEST(x86ild, test_448B6700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r12d, dword ptr [rdi] + */ + EXPECT_EQ(4, ild(u"Dïg ")); +} + +TEST(x86ild, test_448B4700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r8d, dword ptr [rdi] + */ + EXPECT_EQ(4, ild(u"DïG ")); +} + +TEST(x86ild, test_448B4500) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r8d, dword ptr [rbp] + */ + EXPECT_EQ(4, ild(u"DïE ")); +} + +TEST(x86ild, test_448B0424) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov r8d, dword ptr [rsp] + */ + EXPECT_EQ(4, ild(u"Dï♦$")); +} + +TEST(x86ild, test_448A5300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov r10b, byte ptr [rbx] + */ + EXPECT_EQ(4, ild(u"DèS ")); +} + +TEST(x86ild, test_448A4E00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov r9b, byte ptr [rsi] + */ + EXPECT_EQ(4, ild(u"DèN ")); +} + +TEST(x86ild, test_448A4600) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov r8b, byte ptr [rsi] + */ + EXPECT_EQ(4, ild(u"DèF ")); +} + +TEST(x86ild, test_448A01) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov r8b, byte ptr [rcx] + */ + EXPECT_EQ(3, ild(u"Dè☺")); +} + +TEST(x86ild, test_4489E9) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov ecx, r13d + */ + EXPECT_EQ(3, ild(u"DëΘ")); +} + +TEST(x86ild, test_4489E8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov eax, r13d + */ + EXPECT_EQ(3, ild(u"DëΦ")); +} + +TEST(x86ild, test_4489CE) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov esi, r9d + */ + EXPECT_EQ(3, ild(u"Dë╬")); +} + +TEST(x86ild, test_4489C8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov eax, r9d + */ + EXPECT_EQ(3, ild(u"Dë╚")); +} + +TEST(x86ild, test_4489C2) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov edx, r8d + */ + EXPECT_EQ(3, ild(u"Dë┬")); +} + +TEST(x86ild, test_4489C0) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov eax, r8d + */ + EXPECT_EQ(3, ild(u"Dë└")); +} + +TEST(x86ild, test_44898900000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [rcx], r9d + */ + EXPECT_EQ(7, ild(u"Dëë    ")); +} + +TEST(x86ild, test_4488E8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov al, r13b + */ + EXPECT_EQ(3, ild(u"DêΦ")); +} + +TEST(x86ild, test_4488D9) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov cl, r11b + */ + EXPECT_EQ(3, ild(u"Dê┘")); +} + +TEST(x86ild, test_4488CE) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov sil, r9b + */ + EXPECT_EQ(3, ild(u"Dê╬")); +} + +TEST(x86ild, test_4488CD) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov bpl, r9b + */ + EXPECT_EQ(3, ild(u"Dê═")); +} + +TEST(x86ild, test_4488C5) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov bpl, r8b + */ + EXPECT_EQ(3, ild(u"Dê┼")); +} + +TEST(x86ild, test_44886300) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rbx], r12b + */ + EXPECT_EQ(4, ild(u"Dêc ")); +} + +TEST(x86ild, test_44884B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rbx], r9b + */ + EXPECT_EQ(4, ild(u"DêK ")); +} + +TEST(x86ild, test_44884700) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rdi], r8b + */ + EXPECT_EQ(4, ild(u"DêG ")); +} + +TEST(x86ild, test_44884000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rax], r8b + */ + EXPECT_EQ(4, ild(u"Dê@ ")); +} + +TEST(x86ild, test_43C6040E00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_IMMb + ISA_SET: I86 + SHORT: mov byte ptr [r14+r9*1], 0x0 + */ + EXPECT_EQ(5, ild(u"C╞♦♫ ")); +} + +TEST(x86ild, test_428A1400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov dl, byte ptr [rax+r8*1] + */ + EXPECT_EQ(4, ild(u"Bè¶ ")); +} + +TEST(x86ild, test_428A0406) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov al, byte ptr [rsi+r8*1] + */ + EXPECT_EQ(4, ild(u"Bè♦♠")); +} + +TEST(x86ild, test_42880407) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rdi+r8*1], al + */ + EXPECT_EQ(4, ild(u"Bê♦•")); +} + +TEST(x86ild, test_41FF14C4) { + /* + ICLASS: CALL_NEAR + CATEGORY: CALL + EXTENSION: BASE + IFORM: CALL_NEAR_MEMv + ISA_SET: I86 + SHORT: call qword ptr [r12+rax*8] + */ + EXPECT_EQ(4, ild(u"Aλ¶─")); +} + +TEST(x86ild, test_41C6042400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_IMMb + ISA_SET: I86 + SHORT: mov byte ptr [r12], 0x0 + */ + EXPECT_EQ(5, ild(u"A╞♦$ ")); +} + +TEST(x86ild, test_41C60000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_IMMb + ISA_SET: I86 + SHORT: mov byte ptr [r8], 0x0 + */ + EXPECT_EQ(4, ild(u"A╞  ")); +} + +TEST(x86ild, test_418B8000000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_MEMv + ISA_SET: I86 + SHORT: mov eax, dword ptr [r8] + */ + EXPECT_EQ(7, ild(u"AïÇ    ")); +} + +TEST(x86ild, test_418A0C14) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov cl, byte ptr [r12+rdx*1] + */ + EXPECT_EQ(4, ild(u"Aè♀¶")); +} + +TEST(x86ild, test_418A0404) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov al, byte ptr [r12+rax*1] + */ + EXPECT_EQ(4, ild(u"Aè♦♦")); +} + +TEST(x86ild, test_418A0400) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov al, byte ptr [r8+rax*1] + */ + EXPECT_EQ(4, ild(u"Aè♦ ")); +} + +TEST(x86ild, test_4189FB) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r11d, edi + */ + EXPECT_EQ(3, ild(u"Aë√")); +} + +TEST(x86ild, test_4189F8) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r8d, edi + */ + EXPECT_EQ(3, ild(u"Aë°")); +} + +TEST(x86ild, test_4189DC) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r12d, ebx + */ + EXPECT_EQ(3, ild(u"Aë▄")); +} + +TEST(x86ild, test_4189D7) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r15d, edx + */ + EXPECT_EQ(3, ild(u"Aë╫")); +} + +TEST(x86ild, test_4189D6) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r14d, edx + */ + EXPECT_EQ(3, ild(u"Aë╓")); +} + +TEST(x86ild, test_4189D3) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r11d, edx + */ + EXPECT_EQ(3, ild(u"Aë╙")); +} + +TEST(x86ild, test_4189CB) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r11d, ecx + */ + EXPECT_EQ(3, ild(u"Aë╦")); +} + +TEST(x86ild, test_4189C1) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r9d, eax + */ + EXPECT_EQ(3, ild(u"Aë┴")); +} + +TEST(x86ild, test_4189C0) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPRv_GPRv_89 + ISA_SET: I86 + SHORT: mov r8d, eax + */ + EXPECT_EQ(3, ild(u"Aë└")); +} + +TEST(x86ild, test_41898800000000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMv_GPRv + ISA_SET: I86 + SHORT: mov dword ptr [r8], ecx + */ + EXPECT_EQ(7, ild(u"Aëê    ")); +} + +TEST(x86ild, test_4188F2) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov r10b, sil + */ + EXPECT_EQ(3, ild(u"Aê≥")); +} + +TEST(x86ild, test_4188CE) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov r14b, cl + */ + EXPECT_EQ(3, ild(u"Aê╬")); +} + +TEST(x86ild, test_4188C3) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov r11b, al + */ + EXPECT_EQ(3, ild(u"Aê├")); +} + +TEST(x86ild, test_4188C2) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov r10b, al + */ + EXPECT_EQ(3, ild(u"Aê┬")); +} + +TEST(x86ild, test_4188C1) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov r9b, al + */ + EXPECT_EQ(3, ild(u"Aê┴")); +} + +TEST(x86ild, test_41885000) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [r8], dl + */ + EXPECT_EQ(4, ild(u"AêP ")); +} + +TEST(x86ild, test_4158) { + /* + ICLASS: POP + CATEGORY: POP + EXTENSION: BASE + IFORM: POP_GPRv_58 + ISA_SET: I86 + SHORT: pop r8 + */ + EXPECT_EQ(2, ild(u"AX")); +} + +TEST(x86ild, test_40B600) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_IMMb_B0 + ISA_SET: I86 + SHORT: mov sil, 0x0 + */ + EXPECT_EQ(3, ild(u"@╢ ")); +} + +TEST(x86ild, test_408A7D00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_MEMb + ISA_SET: I86 + SHORT: mov dil, byte ptr [rbp] + */ + EXPECT_EQ(4, ild(u"@è} ")); +} + +TEST(x86ild, test_4088FA) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov dl, dil + */ + EXPECT_EQ(3, ild(u"@ê·")); +} + +TEST(x86ild, test_4088EA) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov dl, bpl + */ + EXPECT_EQ(3, ild(u"@êΩ")); +} + +TEST(x86ild, test_4088D7) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov dil, dl + */ + EXPECT_EQ(3, ild(u"@ê╫")); +} + +TEST(x86ild, test_4088C5) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_GPR8_GPR8_88 + ISA_SET: I86 + SHORT: mov bpl, al + */ + EXPECT_EQ(3, ild(u"@ê┼")); +} + +TEST(x86ild, test_40887B00) { + /* + ICLASS: MOV + CATEGORY: DATAXFER + EXTENSION: BASE + IFORM: MOV_MEMb_GPR8 + ISA_SET: I86 + SHORT: mov byte ptr [rbx], dil + */ + EXPECT_EQ(4, ild(u"@ê{ ")); +} + +TEST(x86ild, test_0F8E00000000) { + /* + ICLASS: JLE + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JLE_RELBRd + ISA_SET: I86 + SHORT: jle 0x6 + */ + EXPECT_EQ(6, ild(u"☼Ä    ")); +} + +TEST(x86ild, test_0F8800000000) { + /* + ICLASS: JS + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JS_RELBRd + ISA_SET: I86 + SHORT: js 0x6 + */ + EXPECT_EQ(6, ild(u"☼ê    ")); +} + +TEST(x86ild, test_0F8200000000) { + /* + ICLASS: JB + CATEGORY: COND_BR + EXTENSION: BASE + IFORM: JB_RELBRd + ISA_SET: I86 + SHORT: jb 0x6 + */ + EXPECT_EQ(6, ild(u"☼é    ")); +} diff --git a/test/libc/xed/x86ild_popular_logical_test.c b/test/libc/xed/x86ild_popular_logical_test.c new file mode 100644 index 00000000..e8990567 --- /dev/null +++ b/test/libc/xed/x86ild_popular_logical_test.c @@ -0,0 +1,2206 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/testlib.h" +#include "test/libc/xed/lib.h" +#include "third_party/xed/x86.h" + +TEST(x86ild, test_85C0) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test eax, eax + */ + ASSERT_EQ(2, ild(u"à└")); +} + +TEST(x86ild, test_31D2) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor edx, edx + */ + ASSERT_EQ(2, ild(u"1╥")); +} + +TEST(x86ild, test_81E600000000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMz + ISA_SET: I86 + SHORT: and esi, 0x0 + */ + ASSERT_EQ(6, ild(u"üμ    ")); +} + +TEST(x86ild, test_31C0) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor eax, eax + */ + ASSERT_EQ(2, ild(u"1└")); +} + +TEST(x86ild, test_83E100) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMb + ISA_SET: I86 + SHORT: and ecx, 0x0 + */ + ASSERT_EQ(3, ild(u"âß ")); +} + +TEST(x86ild, test_83E000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMb + ISA_SET: I86 + SHORT: and eax, 0x0 + */ + ASSERT_EQ(3, ild(u"âα ")); +} + +TEST(x86ild, test_83E200) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMb + ISA_SET: I86 + SHORT: and edx, 0x0 + */ + ASSERT_EQ(3, ild(u"âΓ ")); +} + +TEST(x86ild, test_F6430000) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_MEMb_IMMb_F6r0 + ISA_SET: I86 + SHORT: test byte ptr [rbx], 0x0 + */ + ASSERT_EQ(4, ild(u"÷C  ")); +} + +TEST(x86ild, test_66250000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_OrAX_IMMz + ISA_SET: I86 + SHORT: and ax, 0x0 + */ + ASSERT_EQ(4, ild(u"f%  ")); +} + +TEST(x86ild, test_2500000000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_OrAX_IMMz + ISA_SET: I86 + SHORT: and eax, 0x0 + */ + ASSERT_EQ(5, ild(u"%    ")); +} + +TEST(x86ild, test_09D0) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or eax, edx + */ + ASSERT_EQ(2, ild(u"○╨")); +} + +TEST(x86ild, test_48234300) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_MEMv + ISA_SET: I86 + SHORT: and rax, qword ptr [rbx] + */ + ASSERT_EQ(4, ild(u"H#C ")); +} + +TEST(x86ild, test_83C800) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_IMMb + ISA_SET: I86 + SHORT: or eax, 0x0 + */ + ASSERT_EQ(3, ild(u"â╚ ")); +} + +TEST(x86ild, test_0C00) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_AL_IMMb + ISA_SET: I86 + SHORT: or al, 0x0 + */ + ASSERT_EQ(2, ild(u"♀ ")); +} + +TEST(x86ild, test_31C9) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor ecx, ecx + */ + ASSERT_EQ(2, ild(u"1╔")); +} + +TEST(x86ild, test_804F0000) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_MEMb_IMMb_80r1 + ISA_SET: I86 + SHORT: or byte ptr [rdi], 0x0 + */ + ASSERT_EQ(4, ild(u"ÇO  ")); +} + +TEST(x86ild, test_09F1) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or ecx, esi + */ + ASSERT_EQ(2, ild(u"○±")); +} + +TEST(x86ild, test_6681E20000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMz + ISA_SET: I86 + SHORT: and dx, 0x0 + */ + ASSERT_EQ(5, ild(u"füΓ  ")); +} + +TEST(x86ild, test_09C8) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or eax, ecx + */ + ASSERT_EQ(2, ild(u"○╚")); +} + +TEST(x86ild, test_83E600) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMb + ISA_SET: I86 + SHORT: and esi, 0x0 + */ + ASSERT_EQ(3, ild(u"âμ ")); +} + +TEST(x86ild, test_80CC00) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPR8_IMMb_80r1 + ISA_SET: I86 + SHORT: or ah, 0x0 + */ + ASSERT_EQ(3, ild(u"Ç╠ ")); +} + +TEST(x86ild, test_09C2) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or edx, eax + */ + ASSERT_EQ(2, ild(u"○┬")); +} + +TEST(x86ild, test_6681E60000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMz + ISA_SET: I86 + SHORT: and si, 0x0 + */ + ASSERT_EQ(5, ild(u"füμ  ")); +} + +TEST(x86ild, test_660D0000) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_OrAX_IMMz + ISA_SET: I86 + SHORT: or ax, 0x0 + */ + ASSERT_EQ(4, ild(u"f♪  ")); +} + +TEST(x86ild, test_09C6) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or esi, eax + */ + ASSERT_EQ(2, ild(u"○╞")); +} + +TEST(x86ild, test_83CA00) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_IMMb + ISA_SET: I86 + SHORT: or edx, 0x0 + */ + ASSERT_EQ(3, ild(u"â╩ ")); +} + +TEST(x86ild, test_6681E10000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMz + ISA_SET: I86 + SHORT: and cx, 0x0 + */ + ASSERT_EQ(5, ild(u"füß  ")); +} + +TEST(x86ild, test_80E200) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPR8_IMMb_80r4 + ISA_SET: I86 + SHORT: and dl, 0x0 + */ + ASSERT_EQ(3, ild(u"ÇΓ ")); +} + +TEST(x86ild, test_09FE) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or esi, edi + */ + ASSERT_EQ(2, ild(u"○■")); +} + +TEST(x86ild, test_F6470000) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_MEMb_IMMb_F6r0 + ISA_SET: I86 + SHORT: test byte ptr [rdi], 0x0 + */ + ASSERT_EQ(4, ild(u"÷G  ")); +} + +TEST(x86ild, test_4885C0) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test rax, rax + */ + ASSERT_EQ(3, ild(u"Hà└")); +} + +TEST(x86ild, test_83F200) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_IMMb + ISA_SET: I86 + SHORT: xor edx, 0x0 + */ + ASSERT_EQ(3, ild(u"â≥ ")); +} + +TEST(x86ild, test_0D00000000) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_OrAX_IMMz + ISA_SET: I86 + SHORT: or eax, 0x0 + */ + ASSERT_EQ(5, ild(u"♪    ")); +} + +TEST(x86ild, test_84C0) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPR8_GPR8 + ISA_SET: I86 + SHORT: test al, al + */ + ASSERT_EQ(2, ild(u"ä└")); +} + +TEST(x86ild, test_A800) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_AL_IMMb + ISA_SET: I86 + SHORT: test al, 0x0 + */ + ASSERT_EQ(2, ild(u"¿ ")); +} + +TEST(x86ild, test_81E200000000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMz + ISA_SET: I86 + SHORT: and edx, 0x0 + */ + ASSERT_EQ(6, ild(u"üΓ    ")); +} + +TEST(x86ild, test_F6450000) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_MEMb_IMMb_F6r0 + ISA_SET: I86 + SHORT: test byte ptr [rbp], 0x0 + */ + ASSERT_EQ(4, ild(u"÷E  ")); +} + +TEST(x86ild, test_80670000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_MEMb_IMMb_80r4 + ISA_SET: I86 + SHORT: and byte ptr [rdi], 0x0 + */ + ASSERT_EQ(4, ild(u"Çg  ")); +} + +TEST(x86ild, test_4885D2) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test rdx, rdx + */ + ASSERT_EQ(3, ild(u"Hà╥")); +} + +TEST(x86ild, test_83F100) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_IMMb + ISA_SET: I86 + SHORT: xor ecx, 0x0 + */ + ASSERT_EQ(3, ild(u"â± ")); +} + +TEST(x86ild, test_81E100000000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMz + ISA_SET: I86 + SHORT: and ecx, 0x0 + */ + ASSERT_EQ(6, ild(u"üß    ")); +} + +TEST(x86ild, test_80E100) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPR8_IMMb_80r4 + ISA_SET: I86 + SHORT: and cl, 0x0 + */ + ASSERT_EQ(3, ild(u"Çß ")); +} + +TEST(x86ild, test_84D2) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPR8_GPR8 + ISA_SET: I86 + SHORT: test dl, dl + */ + ASSERT_EQ(2, ild(u"ä╥")); +} + +TEST(x86ild, test_6681CA0000) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_IMMz + ISA_SET: I86 + SHORT: or dx, 0x0 + */ + ASSERT_EQ(5, ild(u"fü╩  ")); +} + +TEST(x86ild, test_09C1) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or ecx, eax + */ + ASSERT_EQ(2, ild(u"○┴")); +} + +TEST(x86ild, test_804B0000) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_MEMb_IMMb_80r1 + ISA_SET: I86 + SHORT: or byte ptr [rbx], 0x0 + */ + ASSERT_EQ(4, ild(u"ÇK  ")); +} + +TEST(x86ild, test_4885FF) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test rdi, rdi + */ + ASSERT_EQ(3, ild(u"Hàλ")); +} + +TEST(x86ild, test_85F6) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test esi, esi + */ + ASSERT_EQ(2, ild(u"à÷")); +} + +TEST(x86ild, test_4585ED) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test r13d, r13d + */ + ASSERT_EQ(3, ild(u"Eàφ")); +} + +TEST(x86ild, test_84C9) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPR8_GPR8 + ISA_SET: I86 + SHORT: test cl, cl + */ + ASSERT_EQ(2, ild(u"ä╔")); +} + +TEST(x86ild, test_83F000) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_IMMb + ISA_SET: I86 + SHORT: xor eax, 0x0 + */ + ASSERT_EQ(3, ild(u"â≡ ")); +} + +TEST(x86ild, test_09F2) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or edx, esi + */ + ASSERT_EQ(2, ild(u"○≥")); +} + +TEST(x86ild, test_4183E000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMb + ISA_SET: I86 + SHORT: and r8d, 0x0 + */ + ASSERT_EQ(4, ild(u"Aâα ")); +} + +TEST(x86ild, test_85D2) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test edx, edx + */ + ASSERT_EQ(2, ild(u"à╥")); +} + +TEST(x86ild, test_83E700) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMb + ISA_SET: I86 + SHORT: and edi, 0x0 + */ + ASSERT_EQ(3, ild(u"âτ ")); +} + +TEST(x86ild, test_31F6) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor esi, esi + */ + ASSERT_EQ(2, ild(u"1÷")); +} + +TEST(x86ild, test_668167000000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_MEMv_IMMz + ISA_SET: I86 + SHORT: and word ptr [rdi], 0x0 + */ + ASSERT_EQ(6, ild(u"füg   ")); +} + +TEST(x86ild, test_09F0) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or eax, esi + */ + ASSERT_EQ(2, ild(u"○≡")); +} + +TEST(x86ild, test_81E700000000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMz + ISA_SET: I86 + SHORT: and edi, 0x0 + */ + ASSERT_EQ(6, ild(u"üτ    ")); +} + +TEST(x86ild, test_66F743000000) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_MEMv_IMMz_F7r0 + ISA_SET: I86 + SHORT: test word ptr [rbx], 0x0 + */ + ASSERT_EQ(6, ild(u"f≈C   ")); +} + +TEST(x86ild, test_40F6C500) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPR8_IMMb_F6r0 + ISA_SET: I86 + SHORT: test bpl, 0x0 + */ + ASSERT_EQ(4, ild(u"@÷┼ ")); +} + +TEST(x86ild, test_80CA00) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPR8_IMMb_80r1 + ISA_SET: I86 + SHORT: or dl, 0x0 + */ + ASSERT_EQ(3, ild(u"Ç╩ ")); +} + +TEST(x86ild, test_48235300) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_MEMv + ISA_SET: I86 + SHORT: and rdx, qword ptr [rbx] + */ + ASSERT_EQ(4, ild(u"H#S ")); +} + +TEST(x86ild, test_31DB) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor ebx, ebx + */ + ASSERT_EQ(2, ild(u"1█")); +} + +TEST(x86ild, test_25000083E2) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_OrAX_IMMz + ISA_SET: I86 + SHORT: and eax, 0xe2830000 + */ + ASSERT_EQ(5, ild(u"%  âΓ")); +} + +TEST(x86ild, test_24D5) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_AL_IMMb + ISA_SET: I86 + SHORT: and al, 0xd5 + */ + ASSERT_EQ(2, ild(u"$╒")); +} + +TEST(x86ild, test_F6C200) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPR8_IMMb_F6r0 + ISA_SET: I86 + SHORT: test dl, 0x0 + */ + ASSERT_EQ(3, ild(u"÷┬ ")); +} + +TEST(x86ild, test_80630000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_MEMb_IMMb_80r4 + ISA_SET: I86 + SHORT: and byte ptr [rbx], 0x0 + */ + ASSERT_EQ(4, ild(u"Çc  ")); +} + +TEST(x86ild, test_4409D0) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or eax, r10d + */ + ASSERT_EQ(3, ild(u"D○╨")); +} + +TEST(x86ild, test_4409C0) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or eax, r8d + */ + ASSERT_EQ(3, ild(u"D○└")); +} + +TEST(x86ild, test_4183F000) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_IMMb + ISA_SET: I86 + SHORT: xor r8d, 0x0 + */ + ASSERT_EQ(4, ild(u"Aâ≡ ")); +} + +TEST(x86ild, test_40F6C600) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPR8_IMMb_F6r0 + ISA_SET: I86 + SHORT: test sil, 0x0 + */ + ASSERT_EQ(4, ild(u"@÷╞ ")); +} + +TEST(x86ild, test_4080E600) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPR8_IMMb_80r4 + ISA_SET: I86 + SHORT: and sil, 0x0 + */ + ASSERT_EQ(4, ild(u"@Çμ ")); +} + +TEST(x86ild, test_09CA) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or edx, ecx + */ + ASSERT_EQ(2, ild(u"○╩")); +} + +TEST(x86ild, test_85ED) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test ebp, ebp + */ + ASSERT_EQ(2, ild(u"àφ")); +} + +TEST(x86ild, test_83E500) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMb + ISA_SET: I86 + SHORT: and ebp, 0x0 + */ + ASSERT_EQ(3, ild(u"âσ ")); +} + +TEST(x86ild, test_834A0000) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_MEMv_IMMb + ISA_SET: I86 + SHORT: or dword ptr [rdx], 0x0 + */ + ASSERT_EQ(4, ild(u"âJ  ")); +} + +TEST(x86ild, test_4183F100) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_IMMb + ISA_SET: I86 + SHORT: xor r9d, 0x0 + */ + ASSERT_EQ(4, ild(u"Aâ± ")); +} + +TEST(x86ild, test_4183E200) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMb + ISA_SET: I86 + SHORT: and r10d, 0x0 + */ + ASSERT_EQ(4, ild(u"AâΓ ")); +} + +TEST(x86ild, test_4180E100) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPR8_IMMb_80r4 + ISA_SET: I86 + SHORT: and r9b, 0x0 + */ + ASSERT_EQ(4, ild(u"AÇß ")); +} + +TEST(x86ild, test_4180E000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPR8_IMMb_80r4 + ISA_SET: I86 + SHORT: and r8b, 0x0 + */ + ASSERT_EQ(4, ild(u"AÇα ")); +} + +TEST(x86ild, test_85DB) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test ebx, ebx + */ + ASSERT_EQ(2, ild(u"à█")); +} + +TEST(x86ild, test_81480000000000) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_MEMv_IMMz + ISA_SET: I86 + SHORT: or dword ptr [rax], 0x0 + */ + ASSERT_EQ(7, ild(u"üH     ")); +} + +TEST(x86ild, test_80CE00) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPR8_IMMb_80r1 + ISA_SET: I86 + SHORT: or dh, 0x0 + */ + ASSERT_EQ(3, ild(u"Ç╬ ")); +} + +TEST(x86ild, test_66F747000000) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_MEMv_IMMz_F7r0 + ISA_SET: I86 + SHORT: test word ptr [rdi], 0x0 + */ + ASSERT_EQ(6, ild(u"f≈G   ")); +} + +TEST(x86ild, test_48F7D2) { + /* + ICLASS: NOT + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: NOT_GPRv + ISA_SET: I86 + SHORT: not rdx + */ + ASSERT_EQ(3, ild(u"H≈╥")); +} + +TEST(x86ild, test_4585F6) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test r14d, r14d + */ + ASSERT_EQ(3, ild(u"Eà÷")); +} + +TEST(x86ild, test_4183E100) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMb + ISA_SET: I86 + SHORT: and r9d, 0x0 + */ + ASSERT_EQ(4, ild(u"Aâß ")); +} + +TEST(x86ild, test_4084F6) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPR8_GPR8 + ISA_SET: I86 + SHORT: test sil, sil + */ + ASSERT_EQ(3, ild(u"@ä÷")); +} + +TEST(x86ild, test_31ED) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor ebp, ebp + */ + ASSERT_EQ(2, ild(u"1φ")); +} + +TEST(x86ild, test_09F8) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or eax, edi + */ + ASSERT_EQ(2, ild(u"○°")); +} + +TEST(x86ild, test_85FF) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test edi, edi + */ + ASSERT_EQ(2, ild(u"àλ")); +} + +TEST(x86ild, test_83F600) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_IMMb + ISA_SET: I86 + SHORT: xor esi, 0x0 + */ + ASSERT_EQ(3, ild(u"â÷ ")); +} + +TEST(x86ild, test_81CA00000000) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_IMMz + ISA_SET: I86 + SHORT: or edx, 0x0 + */ + ASSERT_EQ(6, ild(u"ü╩    ")); +} + +TEST(x86ild, test_81490000000000) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_MEMv_IMMz + ISA_SET: I86 + SHORT: or dword ptr [rcx], 0x0 + */ + ASSERT_EQ(7, ild(u"üI     ")); +} + +TEST(x86ild, test_4D85ED) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test r13, r13 + */ + ASSERT_EQ(3, ild(u"Màφ")); +} + +TEST(x86ild, test_4D85E4) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test r12, r12 + */ + ASSERT_EQ(3, ild(u"MàΣ")); +} + +TEST(x86ild, test_48F7D0) { + /* + ICLASS: NOT + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: NOT_GPRv + ISA_SET: I86 + SHORT: not rax + */ + ASSERT_EQ(3, ild(u"H≈╨")); +} + +TEST(x86ild, test_4885F6) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test rsi, rsi + */ + ASSERT_EQ(3, ild(u"Hà÷")); +} + +TEST(x86ild, test_4585C0) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test r8d, r8d + */ + ASSERT_EQ(3, ild(u"Eà└")); +} + +TEST(x86ild, test_4183F200) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_IMMb + ISA_SET: I86 + SHORT: xor r10d, 0x0 + */ + ASSERT_EQ(4, ild(u"Aâ≥ ")); +} + +TEST(x86ild, test_31FF) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor edi, edi + */ + ASSERT_EQ(2, ild(u"1λ")); +} + +TEST(x86ild, test_2400) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_AL_IMMb + ISA_SET: I86 + SHORT: and al, 0x0 + */ + ASSERT_EQ(2, ild(u"$ ")); +} + +TEST(x86ild, test_F7D1) { + /* + ICLASS: NOT + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: NOT_GPRv + ISA_SET: I86 + SHORT: not ecx + */ + ASSERT_EQ(2, ild(u"≈╤")); +} + +TEST(x86ild, test_F7430000000000) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_MEMv_IMMz_F7r0 + ISA_SET: I86 + SHORT: test dword ptr [rbx], 0x0 + */ + ASSERT_EQ(7, ild(u"≈C     ")); +} + +TEST(x86ild, test_83C900) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_IMMb + ISA_SET: I86 + SHORT: or ecx, 0x0 + */ + ASSERT_EQ(3, ild(u"â╔ ")); +} + +TEST(x86ild, test_814E0000000000) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_MEMv_IMMz + ISA_SET: I86 + SHORT: or dword ptr [rsi], 0x0 + */ + ASSERT_EQ(7, ild(u"üN     ")); +} + +TEST(x86ild, test_80C900) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPR8_IMMb_80r1 + ISA_SET: I86 + SHORT: or cl, 0x0 + */ + ASSERT_EQ(3, ild(u"Ç╔ ")); +} + +TEST(x86ild, test_668163000000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_MEMv_IMMz + ISA_SET: I86 + SHORT: and word ptr [rbx], 0x0 + */ + ASSERT_EQ(6, ild(u"füc   ")); +} + +TEST(x86ild, test_4883C900) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_IMMb + ISA_SET: I86 + SHORT: or rcx, 0x0 + */ + ASSERT_EQ(4, ild(u"Hâ╔ ")); +} + +TEST(x86ild, test_4585E4) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test r12d, r12d + */ + ASSERT_EQ(3, ild(u"EàΣ")); +} + +TEST(x86ild, test_4531F6) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor r14d, r14d + */ + ASSERT_EQ(3, ild(u"E1÷")); +} + +TEST(x86ild, test_4531ED) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor r13d, r13d + */ + ASSERT_EQ(3, ild(u"E1φ")); +} + +TEST(x86ild, test_4531E4) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor r12d, r12d + */ + ASSERT_EQ(3, ild(u"E1Σ")); +} + +TEST(x86ild, test_4531D2) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor r10d, r10d + */ + ASSERT_EQ(3, ild(u"E1╥")); +} + +TEST(x86ild, test_4531C9) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor r9d, r9d + */ + ASSERT_EQ(3, ild(u"E1╔")); +} + +TEST(x86ild, test_4531C0) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor r8d, r8d + */ + ASSERT_EQ(3, ild(u"E1└")); +} + +TEST(x86ild, test_4409D8) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or eax, r11d + */ + ASSERT_EQ(3, ild(u"D○╪")); +} + +TEST(x86ild, test_4409C7) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or edi, r8d + */ + ASSERT_EQ(3, ild(u"D○╟")); +} + +TEST(x86ild, test_4183E400) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMb + ISA_SET: I86 + SHORT: and r12d, 0x0 + */ + ASSERT_EQ(4, ild(u"AâΣ ")); +} + +TEST(x86ild, test_4181E600000000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMz + ISA_SET: I86 + SHORT: and r14d, 0x0 + */ + ASSERT_EQ(7, ild(u"Aüμ    ")); +} + +TEST(x86ild, test_4180E200) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPR8_IMMb_80r4 + ISA_SET: I86 + SHORT: and r10b, 0x0 + */ + ASSERT_EQ(4, ild(u"AÇΓ ")); +} + +TEST(x86ild, test_4109C0) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or r8d, eax + */ + ASSERT_EQ(3, ild(u"A○└")); +} + +TEST(x86ild, test_21C2) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_GPRv_21 + ISA_SET: I86 + SHORT: and edx, eax + */ + ASSERT_EQ(2, ild(u"!┬")); +} + +TEST(x86ild, test_09FA) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or edx, edi + */ + ASSERT_EQ(2, ild(u"○·")); +} + +TEST(x86ild, test_09E8) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or eax, ebp + */ + ASSERT_EQ(2, ild(u"○Φ")); +} + +TEST(x86ild, test_F7470000000000) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_MEMv_IMMz_F7r0 + ISA_SET: I86 + SHORT: test dword ptr [rdi], 0x0 + */ + ASSERT_EQ(7, ild(u"≈G     ")); +} + +TEST(x86ild, test_F7400000000000) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_MEMv_IMMz_F7r0 + ISA_SET: I86 + SHORT: test dword ptr [rax], 0x0 + */ + ASSERT_EQ(7, ild(u"≈@     ")); +} + +TEST(x86ild, test_F6040800) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_MEMb_IMMb_F6r0 + ISA_SET: I86 + SHORT: test byte ptr [rax+rcx*1], 0x0 + */ + ASSERT_EQ(4, ild(u"÷♦◘ ")); +} + +TEST(x86ild, test_85C9) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test ecx, ecx + */ + ASSERT_EQ(2, ild(u"à╔")); +} + +TEST(x86ild, test_83F700) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_IMMb + ISA_SET: I86 + SHORT: xor edi, 0x0 + */ + ASSERT_EQ(3, ild(u"â≈ ")); +} + +TEST(x86ild, test_83490000) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_MEMv_IMMb + ISA_SET: I86 + SHORT: or dword ptr [rcx], 0x0 + */ + ASSERT_EQ(4, ild(u"âI  ")); +} + +TEST(x86ild, test_81670000000000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_MEMv_IMMz + ISA_SET: I86 + SHORT: and dword ptr [rdi], 0x0 + */ + ASSERT_EQ(7, ild(u"üg     ")); +} + +TEST(x86ild, test_81630000000000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_MEMv_IMMz + ISA_SET: I86 + SHORT: and dword ptr [rbx], 0x0 + */ + ASSERT_EQ(7, ild(u"üc     ")); +} + +TEST(x86ild, test_66A90000) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_OrAX_IMMz + ISA_SET: I86 + SHORT: test ax, 0x0 + */ + ASSERT_EQ(4, ild(u"f⌐  ")); +} + +TEST(x86ild, test_6685F6) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test si, si + */ + ASSERT_EQ(3, ild(u"fà÷")); +} + +TEST(x86ild, test_6685D2) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test dx, dx + */ + ASSERT_EQ(3, ild(u"fà╥")); +} + +TEST(x86ild, test_6685C0) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test ax, ax + */ + ASSERT_EQ(3, ild(u"fà└")); +} + +TEST(x86ild, test_6681E70000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMz + ISA_SET: I86 + SHORT: and di, 0x0 + */ + ASSERT_EQ(5, ild(u"füτ  ")); +} + +TEST(x86ild, test_66350000) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_OrAX_IMMz + ISA_SET: I86 + SHORT: xor ax, 0x0 + */ + ASSERT_EQ(4, ild(u"f5  ")); +} + +TEST(x86ild, test_4D85D2) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test r10, r10 + */ + ASSERT_EQ(3, ild(u"Mà╥")); +} + +TEST(x86ild, test_4D21E8) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_GPRv_21 + ISA_SET: I86 + SHORT: and r8, r13 + */ + ASSERT_EQ(3, ild(u"M!Φ")); +} + +TEST(x86ild, test_4C31C0) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor rax, r8 + */ + ASSERT_EQ(3, ild(u"L1└")); +} + +TEST(x86ild, test_4921C2) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_GPRv_21 + ISA_SET: I86 + SHORT: and r10, rax + */ + ASSERT_EQ(3, ild(u"I!┬")); +} + +TEST(x86ild, test_48F7D1) { + /* + ICLASS: NOT + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: NOT_GPRv + ISA_SET: I86 + SHORT: not rcx + */ + ASSERT_EQ(3, ild(u"H≈╤")); +} + +TEST(x86ild, test_48859000000000) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_MEMv_GPRv + ISA_SET: I86 + SHORT: test qword ptr [rax], rdx + */ + ASSERT_EQ(7, ild(u"HàÉ    ")); +} + +TEST(x86ild, test_48854200) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_MEMv_GPRv + ISA_SET: I86 + SHORT: test qword ptr [rdx], rax + */ + ASSERT_EQ(4, ild(u"HàB ")); +} + +TEST(x86ild, test_488514C7) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_MEMv_GPRv + ISA_SET: I86 + SHORT: test qword ptr [rdi+rax*8], rdx + */ + ASSERT_EQ(4, ild(u"Hà¶╟")); +} + +TEST(x86ild, test_488504D500000000) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_MEMv_GPRv + ISA_SET: I86 + SHORT: test qword ptr [rdx*8], rax + */ + ASSERT_EQ(8, ild(u"Hà♦╒    ")); +} + +TEST(x86ild, test_4883E400) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMb + ISA_SET: I86 + SHORT: and rsp, 0x0 + */ + ASSERT_EQ(4, ild(u"HâΣ ")); +} + +TEST(x86ild, test_4883CB00) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_IMMb + ISA_SET: I86 + SHORT: or rbx, 0x0 + */ + ASSERT_EQ(4, ild(u"Hâ╦ ")); +} + +TEST(x86ild, test_4883CA00) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_IMMb + ISA_SET: I86 + SHORT: or rdx, 0x0 + */ + ASSERT_EQ(4, ild(u"Hâ╩ ")); +} + +TEST(x86ild, test_4831ED) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor rbp, rbp + */ + ASSERT_EQ(3, ild(u"H1φ")); +} + +TEST(x86ild, test_48234B00) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_MEMv + ISA_SET: I86 + SHORT: and rcx, qword ptr [rbx] + */ + ASSERT_EQ(4, ild(u"H#K ")); +} + +TEST(x86ild, test_482306) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_MEMv + ISA_SET: I86 + SHORT: and rax, qword ptr [rsi] + */ + ASSERT_EQ(3, ild(u"H#♠")); +} + +TEST(x86ild, test_4821F8) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_GPRv_21 + ISA_SET: I86 + SHORT: and rax, rdi + */ + ASSERT_EQ(3, ild(u"H!°")); +} + +TEST(x86ild, test_480B5700) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_MEMv + ISA_SET: I86 + SHORT: or rdx, qword ptr [rdi] + */ + ASSERT_EQ(4, ild(u"H♂W ")); +} + +TEST(x86ild, test_4809D0) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or rax, rdx + */ + ASSERT_EQ(3, ild(u"H○╨")); +} + +TEST(x86ild, test_4585FF) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPRv_GPRv + ISA_SET: I86 + SHORT: test r15d, r15d + */ + ASSERT_EQ(3, ild(u"Eàλ")); +} + +TEST(x86ild, test_4584D2) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPR8_GPR8 + ISA_SET: I86 + SHORT: test r10b, r10b + */ + ASSERT_EQ(3, ild(u"Eä╥")); +} + +TEST(x86ild, test_4531FF) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor r15d, r15d + */ + ASSERT_EQ(3, ild(u"E1λ")); +} + +TEST(x86ild, test_4531DB) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor r11d, r11d + */ + ASSERT_EQ(3, ild(u"E1█")); +} + +TEST(x86ild, test_4509DA) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or r10d, r11d + */ + ASSERT_EQ(3, ild(u"E○┌")); +} + +TEST(x86ild, test_4509C8) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or r8d, r9d + */ + ASSERT_EQ(3, ild(u"E○╚")); +} + +TEST(x86ild, test_450801) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_MEMb_GPR8 + ISA_SET: I86 + SHORT: or byte ptr [r9], r8b + */ + ASSERT_EQ(3, ild(u"E◘☺")); +} + +TEST(x86ild, test_4431C0) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_GPRv_31 + ISA_SET: I86 + SHORT: xor eax, r8d + */ + ASSERT_EQ(3, ild(u"D1└")); +} + +TEST(x86ild, test_4421C1) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_GPRv_21 + ISA_SET: I86 + SHORT: and ecx, r8d + */ + ASSERT_EQ(3, ild(u"D!┴")); +} + +TEST(x86ild, test_4409C8) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or eax, r9d + */ + ASSERT_EQ(3, ild(u"D○╚")); +} + +TEST(x86ild, test_4183F300) { + /* + ICLASS: XOR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: XOR_GPRv_IMMb + ISA_SET: I86 + SHORT: xor r11d, 0x0 + */ + ASSERT_EQ(4, ild(u"Aâ≤ ")); +} + +TEST(x86ild, test_4183E700) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMb + ISA_SET: I86 + SHORT: and r15d, 0x0 + */ + ASSERT_EQ(4, ild(u"Aâτ ")); +} + +TEST(x86ild, test_4183E600) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMb + ISA_SET: I86 + SHORT: and r14d, 0x0 + */ + ASSERT_EQ(4, ild(u"Aâμ ")); +} + +TEST(x86ild, test_4183E300) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMb + ISA_SET: I86 + SHORT: and r11d, 0x0 + */ + ASSERT_EQ(4, ild(u"Aâπ ")); +} + +TEST(x86ild, test_4181E700000000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMz + ISA_SET: I86 + SHORT: and r15d, 0x0 + */ + ASSERT_EQ(7, ild(u"Aüτ    ")); +} + +TEST(x86ild, test_4181E500000000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMz + ISA_SET: I86 + SHORT: and r13d, 0x0 + */ + ASSERT_EQ(7, ild(u"Aüσ    ")); +} + +TEST(x86ild, test_4181E000000000) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_IMMz + ISA_SET: I86 + SHORT: and r8d, 0x0 + */ + ASSERT_EQ(7, ild(u"Aüα    ")); +} + +TEST(x86ild, test_4109D4) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPRv_GPRv_09 + ISA_SET: I86 + SHORT: or r12d, edx + */ + ASSERT_EQ(3, ild(u"A○╘")); +} + +TEST(x86ild, test_4084FF) { + /* + ICLASS: TEST + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: TEST_GPR8_GPR8 + ISA_SET: I86 + SHORT: test dil, dil + */ + ASSERT_EQ(3, ild(u"@äλ")); +} + +TEST(x86ild, test_224300) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPR8_MEMb + ISA_SET: I86 + SHORT: and al, byte ptr [rbx] + */ + ASSERT_EQ(3, ild(u"“C ")); +} + +TEST(x86ild, test_21F9) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_GPRv_21 + ISA_SET: I86 + SHORT: and ecx, edi + */ + ASSERT_EQ(2, ild(u"!∙")); +} + +TEST(x86ild, test_21F8) { + /* + ICLASS: AND + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: AND_GPRv_GPRv_21 + ISA_SET: I86 + SHORT: and eax, edi + */ + ASSERT_EQ(2, ild(u"!°")); +} + +TEST(x86ild, test_093C8500000000) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_MEMv_GPRv + ISA_SET: I86 + SHORT: or dword ptr [rax*4], edi + */ + ASSERT_EQ(7, ild(u"○<à    ")); +} + +TEST(x86ild, test_08D1) { + /* + ICLASS: OR + CATEGORY: LOGICAL + EXTENSION: BASE + IFORM: OR_GPR8_GPR8_08 + ISA_SET: I86 + SHORT: or cl, dl + */ + ASSERT_EQ(2, ild(u"◘╤")); +} diff --git a/test/libc/xed/x86ild_popular_misc_test.c b/test/libc/xed/x86ild_popular_misc_test.c new file mode 100644 index 00000000..d00c9300 --- /dev/null +++ b/test/libc/xed/x86ild_popular_misc_test.c @@ -0,0 +1,1930 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/testlib.h" +#include "test/libc/xed/lib.h" +#include "third_party/xed/x86.h" + +TEST(x86ild, test_488D7300) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rsi, ptr [rbx] + */ + ASSERT_EQ(4, ild(u"Hìs ")); +} + +TEST(x86ild, test_488D0480) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rax+rax*4] + */ + ASSERT_EQ(4, ild(u"Hì♦Ç")); +} + +TEST(x86ild, test_488D0440) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rax+rax*2] + */ + ASSERT_EQ(4, ild(u"Hì♦@")); +} + +TEST(x86ild, test_8D148500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rax*4] + */ + ASSERT_EQ(7, ild(u"ì¶à    ")); +} + +TEST(x86ild, test_488D5000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdx, ptr [rax] + */ + ASSERT_EQ(4, ild(u"HìP ")); +} + +TEST(x86ild, test_488D1492) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdx, ptr [rdx+rdx*4] + */ + ASSERT_EQ(4, ild(u"Hì¶Æ")); +} + +TEST(x86ild, test_8D348D00000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea esi, ptr [rcx*4] + */ + ASSERT_EQ(7, ild(u"ì4ì    ")); +} + +TEST(x86ild, test_8D34CD00000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea esi, ptr [rcx*8] + */ + ASSERT_EQ(7, ild(u"ì4═    ")); +} + +TEST(x86ild, test_8D0C8500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea ecx, ptr [rax*4] + */ + ASSERT_EQ(7, ild(u"ì♀à    ")); +} + +TEST(x86ild, test_8D1400) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rax+rax*1] + */ + ASSERT_EQ(3, ild(u"ì¶ ")); +} + +TEST(x86ild, test_488D1401) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdx, ptr [rcx+rax*1] + */ + ASSERT_EQ(4, ild(u"Hì¶☺")); +} + +TEST(x86ild, test_488D14D2) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdx, ptr [rdx+rdx*8] + */ + ASSERT_EQ(4, ild(u"Hì¶╥")); +} + +TEST(x86ild, test_488D1452) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdx, ptr [rdx+rdx*2] + */ + ASSERT_EQ(4, ild(u"Hì¶R")); +} + +TEST(x86ild, test_488D9000000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdx, ptr [rax] + */ + ASSERT_EQ(7, ild(u"HìÉ    ")); +} + +TEST(x86ild, test_488D04C0) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rax+rax*8] + */ + ASSERT_EQ(4, ild(u"Hì♦└")); +} + +TEST(x86ild, test_8D0CC500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea ecx, ptr [rax*8] + */ + ASSERT_EQ(7, ild(u"ì♀┼    ")); +} + +TEST(x86ild, test_488D8800000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rcx, ptr [rax] + */ + ASSERT_EQ(7, ild(u"Hìê    ")); +} + +TEST(x86ild, test_488D0C16) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rcx, ptr [rsi+rdx*1] + */ + ASSERT_EQ(4, ild(u"Hì♀▬")); +} + +TEST(x86ild, test_488D742400) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rsi, ptr [rsp] + */ + ASSERT_EQ(5, ild(u"Hìt$ ")); +} + +TEST(x86ild, test_488D7C2400) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdi, ptr [rsp] + */ + ASSERT_EQ(5, ild(u"Hì|$ ")); +} + +TEST(x86ild, test_8D540200) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rdx+rax*1] + */ + ASSERT_EQ(4, ild(u"ìT☻ ")); +} + +TEST(x86ild, test_488D0452) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rdx+rdx*2] + */ + ASSERT_EQ(4, ild(u"Hì♦R")); +} + +TEST(x86ild, test_8D54D000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rax+rdx*8] + */ + ASSERT_EQ(4, ild(u"ìT╨ ")); +} + +TEST(x86ild, test_8D14C500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rax*8] + */ + ASSERT_EQ(7, ild(u"ì¶┼    ")); +} + +TEST(x86ild, test_488D4800) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rcx, ptr [rax] + */ + ASSERT_EQ(4, ild(u"HìH ")); +} + +TEST(x86ild, test_488D0C10) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rcx, ptr [rax+rdx*1] + */ + ASSERT_EQ(4, ild(u"Hì♀►")); +} + +TEST(x86ild, test_8D14D0) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rax+rdx*8] + */ + ASSERT_EQ(3, ild(u"ì¶╨")); +} + +TEST(x86ild, test_498D3408) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rsi, ptr [r8+rcx*1] + */ + ASSERT_EQ(4, ild(u"Iì4◘")); +} + +TEST(x86ild, test_488D340A) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rsi, ptr [rdx+rcx*1] + */ + ASSERT_EQ(4, ild(u"Hì4◙")); +} + +TEST(x86ild, test_8D5500) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rbp] + */ + ASSERT_EQ(3, ild(u"ìU ")); +} + +TEST(x86ild, test_8D349500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea esi, ptr [rdx*4] + */ + ASSERT_EQ(7, ild(u"ì4ò    ")); +} + +TEST(x86ild, test_488DB000000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rsi, ptr [rax] + */ + ASSERT_EQ(7, ild(u"Hì░    ")); +} + +TEST(x86ild, test_8D541000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rax+rdx*1] + */ + ASSERT_EQ(4, ild(u"ìT► ")); +} + +TEST(x86ild, test_8D4200) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rdx] + */ + ASSERT_EQ(3, ild(u"ìB ")); +} + +TEST(x86ild, test_8D3CF500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edi, ptr [rsi*8] + */ + ASSERT_EQ(7, ild(u"ì<⌡    ")); +} + +TEST(x86ild, test_8D3409) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea esi, ptr [rcx+rcx*1] + */ + ASSERT_EQ(3, ild(u"ì4○")); +} + +TEST(x86ild, test_8D0C00) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea ecx, ptr [rax+rax*1] + */ + ASSERT_EQ(3, ild(u"ì♀ ")); +} + +TEST(x86ild, test_8D0448) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rax+rcx*2] + */ + ASSERT_EQ(3, ild(u"ì♦H")); +} + +TEST(x86ild, test_488D542400) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdx, ptr [rsp] + */ + ASSERT_EQ(5, ild(u"HìT$ ")); +} + +TEST(x86ild, test_8D5000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rax] + */ + ASSERT_EQ(3, ild(u"ìP ")); +} + +TEST(x86ild, test_8D1450) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rax+rdx*2] + */ + ASSERT_EQ(3, ild(u"ì¶P")); +} + +TEST(x86ild, test_8D0490) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rax+rdx*4] + */ + ASSERT_EQ(3, ild(u"ì♦É")); +} + +TEST(x86ild, test_4C8D0431) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r8, ptr [rcx+rsi*1] + */ + ASSERT_EQ(4, ild(u"Lì♦1")); +} + +TEST(x86ild, test_488DB100000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rsi, ptr [rcx] + */ + ASSERT_EQ(7, ild(u"Hì▒    ")); +} + +TEST(x86ild, test_8D4E00) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea ecx, ptr [rsi] + */ + ASSERT_EQ(3, ild(u"ìN ")); +} + +TEST(x86ild, test_8D440200) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rdx+rax*1] + */ + ASSERT_EQ(4, ild(u"ìD☻ ")); +} + +TEST(x86ild, test_8D1490) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rax+rdx*4] + */ + ASSERT_EQ(3, ild(u"ì¶É")); +} + +TEST(x86ild, test_8D1482) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rdx+rax*4] + */ + ASSERT_EQ(3, ild(u"ì¶é")); +} + +TEST(x86ild, test_8D1401) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rcx+rax*1] + */ + ASSERT_EQ(3, ild(u"ì¶☺")); +} + +TEST(x86ild, test_8D0412) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rdx+rdx*1] + */ + ASSERT_EQ(3, ild(u"ì♦↕")); +} + +TEST(x86ild, test_4C8D0416) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r8, ptr [rsi+rdx*1] + */ + ASSERT_EQ(4, ild(u"Lì♦▬")); +} + +TEST(x86ild, test_498D1430) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdx, ptr [r8+rsi*1] + */ + ASSERT_EQ(4, ild(u"Iì¶0")); +} + +TEST(x86ild, test_488D8A00000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rcx, ptr [rdx] + */ + ASSERT_EQ(7, ild(u"Hìè    ")); +} + +TEST(x86ild, test_488D4700) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rdi] + */ + ASSERT_EQ(4, ild(u"HìG ")); +} + +TEST(x86ild, test_488D340E) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rsi, ptr [rsi+rcx*1] + */ + ASSERT_EQ(4, ild(u"Hì4♫")); +} + +TEST(x86ild, test_488D3401) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rsi, ptr [rcx+rax*1] + */ + ASSERT_EQ(4, ild(u"Hì4☺")); +} + +TEST(x86ild, test_488D1431) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdx, ptr [rcx+rsi*1] + */ + ASSERT_EQ(4, ild(u"Hì¶1")); +} + +TEST(x86ild, test_488D0C49) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rcx, ptr [rcx+rcx*2] + */ + ASSERT_EQ(4, ild(u"Hì♀I")); +} + +TEST(x86ild, test_488D048500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rax*4] + */ + ASSERT_EQ(8, ild(u"Hì♦à    ")); +} + +TEST(x86ild, test_488D040E) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rsi+rcx*1] + */ + ASSERT_EQ(4, ild(u"Hì♦♫")); +} + +TEST(x86ild, test_8D9300000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rbx] + */ + ASSERT_EQ(6, ild(u"ìô    ")); +} + +TEST(x86ild, test_8D7900) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edi, ptr [rcx] + */ + ASSERT_EQ(3, ild(u"ìy ")); +} + +TEST(x86ild, test_8D5600) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rsi] + */ + ASSERT_EQ(3, ild(u"ìV ")); +} + +TEST(x86ild, test_8D545000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rax+rdx*2] + */ + ASSERT_EQ(4, ild(u"ìTP ")); +} + +TEST(x86ild, test_8D4800) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea ecx, ptr [rax] + */ + ASSERT_EQ(3, ild(u"ìH ")); +} + +TEST(x86ild, test_8D4700) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rdi] + */ + ASSERT_EQ(3, ild(u"ìG ")); +} + +TEST(x86ild, test_8D4600) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rsi] + */ + ASSERT_EQ(3, ild(u"ìF ")); +} + +TEST(x86ild, test_8D0CF500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea ecx, ptr [rsi*8] + */ + ASSERT_EQ(7, ild(u"ì♀⌡    ")); +} + +TEST(x86ild, test_8D0CB500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea ecx, ptr [rsi*4] + */ + ASSERT_EQ(7, ild(u"ì♀╡    ")); +} + +TEST(x86ild, test_8D0C9500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea ecx, ptr [rdx*4] + */ + ASSERT_EQ(7, ild(u"ì♀ò    ")); +} + +TEST(x86ild, test_8D04B500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rsi*4] + */ + ASSERT_EQ(7, ild(u"ì♦╡    ")); +} + +TEST(x86ild, test_4F8D0C49) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r9, ptr [r9+r9*2] + */ + ASSERT_EQ(4, ild(u"Oì♀I")); +} + +TEST(x86ild, test_498D7C2400) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdi, ptr [r12] + */ + ASSERT_EQ(5, ild(u"Iì|$ ")); +} + +TEST(x86ild, test_488DB800000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdi, ptr [rax] + */ + ASSERT_EQ(7, ild(u"Hì╕    ")); +} + +TEST(x86ild, test_488D4C2400) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rcx, ptr [rsp] + */ + ASSERT_EQ(5, ild(u"HìL$ ")); +} + +TEST(x86ild, test_488D442400) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rsp] + */ + ASSERT_EQ(5, ild(u"HìD$ ")); +} + +TEST(x86ild, test_488D3CC500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdi, ptr [rax*8] + */ + ASSERT_EQ(8, ild(u"Hì<┼    ")); +} + +TEST(x86ild, test_488D3402) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rsi, ptr [rdx+rax*1] + */ + ASSERT_EQ(4, ild(u"Hì4☻")); +} + +TEST(x86ild, test_488D040A) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rdx+rcx*1] + */ + ASSERT_EQ(4, ild(u"Hì♦◙")); +} + +TEST(x86ild, test_488D0408) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rax+rcx*1] + */ + ASSERT_EQ(4, ild(u"Hì♦◘")); +} + +TEST(x86ild, test_448D4100) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r8d, ptr [rcx] + */ + ASSERT_EQ(4, ild(u"DìA ")); +} + +TEST(x86ild, test_418D442400) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [r12] + */ + ASSERT_EQ(5, ild(u"AìD$ ")); +} + +TEST(x86ild, test_8D8A00000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea ecx, ptr [rdx] + */ + ASSERT_EQ(6, ild(u"ìè    ")); +} + +TEST(x86ild, test_8D8300000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rbx] + */ + ASSERT_EQ(6, ild(u"ìâ    ")); +} + +TEST(x86ild, test_8D7100) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea esi, ptr [rcx] + */ + ASSERT_EQ(3, ild(u"ìq ")); +} + +TEST(x86ild, test_8D4D00) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea ecx, ptr [rbp] + */ + ASSERT_EQ(3, ild(u"ìM ")); +} + +TEST(x86ild, test_8D4500) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rbp] + */ + ASSERT_EQ(3, ild(u"ìE ")); +} + +TEST(x86ild, test_8D44F000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rax+rsi*8] + */ + ASSERT_EQ(4, ild(u"ìD≡ ")); +} + +TEST(x86ild, test_8D449000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rax+rdx*4] + */ + ASSERT_EQ(4, ild(u"ìDÉ ")); +} + +TEST(x86ild, test_8D441500) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rbp+rdx*1] + */ + ASSERT_EQ(4, ild(u"ìD§ ")); +} + +TEST(x86ild, test_8D440A00) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rdx+rcx*1] + */ + ASSERT_EQ(4, ild(u"ìD◙ ")); +} + +TEST(x86ild, test_8D440100) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rcx+rax*1] + */ + ASSERT_EQ(4, ild(u"ìD☺ ")); +} + +TEST(x86ild, test_8D4100) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rcx] + */ + ASSERT_EQ(3, ild(u"ìA ")); +} + +TEST(x86ild, test_8D3CB500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edi, ptr [rsi*4] + */ + ASSERT_EQ(7, ild(u"ì<╡    ")); +} + +TEST(x86ild, test_8D34D500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea esi, ptr [rdx*8] + */ + ASSERT_EQ(7, ild(u"ì4╒    ")); +} + +TEST(x86ild, test_8D34C500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea esi, ptr [rax*8] + */ + ASSERT_EQ(7, ild(u"ì4┼    ")); +} + +TEST(x86ild, test_8D3412) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea esi, ptr [rdx+rdx*1] + */ + ASSERT_EQ(3, ild(u"ì4↕")); +} + +TEST(x86ild, test_8D14F500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rsi*8] + */ + ASSERT_EQ(7, ild(u"ì¶⌡    ")); +} + +TEST(x86ild, test_8D14BD00000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rdi*4] + */ + ASSERT_EQ(7, ild(u"ì¶╜    ")); +} + +TEST(x86ild, test_8D1451) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [rcx+rdx*2] + */ + ASSERT_EQ(3, ild(u"ì¶Q")); +} + +TEST(x86ild, test_8D0CD500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea ecx, ptr [rdx*8] + */ + ASSERT_EQ(7, ild(u"ì♀╒    ")); +} + +TEST(x86ild, test_8D04FD00000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rdi*8] + */ + ASSERT_EQ(7, ild(u"ì♦²    ")); +} + +TEST(x86ild, test_8D049500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rdx*4] + */ + ASSERT_EQ(7, ild(u"ì♦ò    ")); +} + +TEST(x86ild, test_8D0488) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rax+rcx*4] + */ + ASSERT_EQ(3, ild(u"ì♦ê")); +} + +TEST(x86ild, test_8D0409) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [rcx+rcx*1] + */ + ASSERT_EQ(3, ild(u"ì♦○")); +} + +TEST(x86ild, test_4E8D0C06) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r9, ptr [rsi+r8*1] + */ + ASSERT_EQ(4, ild(u"Nì♀♠")); +} + +TEST(x86ild, test_4D8D6C2400) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r13, ptr [r12] + */ + ASSERT_EQ(5, ild(u"Mìl$ ")); +} + +TEST(x86ild, test_4D8D0431) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r8, ptr [r9+rsi*1] + */ + ASSERT_EQ(4, ild(u"Mì♦1")); +} + +TEST(x86ild, test_4C8D642400) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r12, ptr [rsp] + */ + ASSERT_EQ(5, ild(u"Lìd$ ")); +} + +TEST(x86ild, test_4C8D4100) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r8, ptr [rcx] + */ + ASSERT_EQ(4, ild(u"LìA ")); +} + +TEST(x86ild, test_4C8D0C19) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r9, ptr [rcx+rbx*1] + */ + ASSERT_EQ(4, ild(u"Lì♀↓")); +} + +TEST(x86ild, test_4C8D0402) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r8, ptr [rdx+rax*1] + */ + ASSERT_EQ(4, ild(u"Lì♦☻")); +} + +TEST(x86ild, test_4A8D0C07) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rcx, ptr [rdi+r8*1] + */ + ASSERT_EQ(4, ild(u"Jì♀•")); +} + +TEST(x86ild, test_488DA800000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rbp, ptr [rax] + */ + ASSERT_EQ(7, ild(u"Hì¿    ")); +} + +TEST(x86ild, test_488D5700) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdx, ptr [rdi] + */ + ASSERT_EQ(4, ild(u"HìW ")); +} + +TEST(x86ild, test_488D4200) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rdx] + */ + ASSERT_EQ(4, ild(u"HìB ")); +} + +TEST(x86ild, test_488D3C7F) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdi, ptr [rdi+rdi*2] + */ + ASSERT_EQ(4, ild(u"Hì<⌂")); +} + +TEST(x86ild, test_488D3500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rsi, ptr [rip] + */ + ASSERT_EQ(7, ild(u"Hì5    ")); +} + +TEST(x86ild, test_488D34F7) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rsi, ptr [rdi+rsi*8] + */ + ASSERT_EQ(4, ild(u"Hì4≈")); +} + +TEST(x86ild, test_488D3476) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rsi, ptr [rsi+rsi*2] + */ + ASSERT_EQ(4, ild(u"Hì4v")); +} + +TEST(x86ild, test_488D3410) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rsi, ptr [rax+rdx*1] + */ + ASSERT_EQ(4, ild(u"Hì4►")); +} + +TEST(x86ild, test_488D3408) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rsi, ptr [rax+rcx*1] + */ + ASSERT_EQ(4, ild(u"Hì4◘")); +} + +TEST(x86ild, test_488D2CD500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rbp, ptr [rdx*8] + */ + ASSERT_EQ(8, ild(u"Hì,╒    ")); +} + +TEST(x86ild, test_488D14B0) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdx, ptr [rax+rsi*4] + */ + ASSERT_EQ(4, ild(u"Hì¶░")); +} + +TEST(x86ild, test_488D1496) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdx, ptr [rsi+rdx*4] + */ + ASSERT_EQ(4, ild(u"Hì¶û")); +} + +TEST(x86ild, test_488D1406) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rdx, ptr [rsi+rax*1] + */ + ASSERT_EQ(4, ild(u"Hì¶♠")); +} + +TEST(x86ild, test_488D0C02) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rcx, ptr [rdx+rax*1] + */ + ASSERT_EQ(4, ild(u"Hì♀☻")); +} + +TEST(x86ild, test_488D04FD00000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rdi*8] + */ + ASSERT_EQ(8, ild(u"Hì♦²    ")); +} + +TEST(x86ild, test_488D04F500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rsi*8] + */ + ASSERT_EQ(8, ild(u"Hì♦⌡    ")); +} + +TEST(x86ild, test_488D04CD00000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rcx*8] + */ + ASSERT_EQ(8, ild(u"Hì♦═    ")); +} + +TEST(x86ild, test_488D04B0) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rax+rsi*4] + */ + ASSERT_EQ(4, ild(u"Hì♦░")); +} + +TEST(x86ild, test_488D049500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rdx*4] + */ + ASSERT_EQ(8, ild(u"Hì♦ò    ")); +} + +TEST(x86ild, test_488D0486) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rsi+rax*4] + */ + ASSERT_EQ(4, ild(u"Hì♦å")); +} + +TEST(x86ild, test_488D0482) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rdx+rax*4] + */ + ASSERT_EQ(4, ild(u"Hì♦é")); +} + +TEST(x86ild, test_488D0430) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea rax, ptr [rax+rsi*1] + */ + ASSERT_EQ(4, ild(u"Hì♦0")); +} + +TEST(x86ild, test_468D240A) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r12d, ptr [rdx+r9*1] + */ + ASSERT_EQ(4, ild(u"Fì$◙")); +} + +TEST(x86ild, test_468D0CD500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r9d, ptr [r10*8] + */ + ASSERT_EQ(8, ild(u"Fì♀╒    ")); +} + +TEST(x86ild, test_468D0CC500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r9d, ptr [r8*8] + */ + ASSERT_EQ(8, ild(u"Fì♀┼    ")); +} + +TEST(x86ild, test_468D0C06) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r9d, ptr [rsi+r8*1] + */ + ASSERT_EQ(4, ild(u"Fì♀♠")); +} + +TEST(x86ild, test_458D7E00) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r15d, ptr [r14] + */ + ASSERT_EQ(4, ild(u"Eì~ ")); +} + +TEST(x86ild, test_458D3401) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r14d, ptr [r9+rax*1] + */ + ASSERT_EQ(4, ild(u"Eì4☺")); +} + +TEST(x86ild, test_448D7000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r14d, ptr [rax] + */ + ASSERT_EQ(4, ild(u"Dìp ")); +} + +TEST(x86ild, test_448D4800) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r9d, ptr [rax] + */ + ASSERT_EQ(4, ild(u"DìH ")); +} + +TEST(x86ild, test_448D4600) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r8d, ptr [rsi] + */ + ASSERT_EQ(4, ild(u"DìF ")); +} + +TEST(x86ild, test_448D14C500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r10d, ptr [rax*8] + */ + ASSERT_EQ(8, ild(u"Dì¶┼    ")); +} + +TEST(x86ild, test_448D148500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r10d, ptr [rax*4] + */ + ASSERT_EQ(8, ild(u"Dì¶à    ")); +} + +TEST(x86ild, test_448D04F500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r8d, ptr [rsi*8] + */ + ASSERT_EQ(8, ild(u"Dì♦⌡    ")); +} + +TEST(x86ild, test_448D04B500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r8d, ptr [rsi*4] + */ + ASSERT_EQ(8, ild(u"Dì♦╡    ")); +} + +TEST(x86ild, test_448D043F) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea r8d, ptr [rdi+rdi*1] + */ + ASSERT_EQ(4, ild(u"Dì♦⁇")); +} + +TEST(x86ild, test_428D34C500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea esi, ptr [r8*8] + */ + ASSERT_EQ(8, ild(u"Bì4┼    ")); +} + +TEST(x86ild, test_428D348500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea esi, ptr [r8*4] + */ + ASSERT_EQ(8, ild(u"Bì4à    ")); +} + +TEST(x86ild, test_428D2C30) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea ebp, ptr [rax+r14*1] + */ + ASSERT_EQ(4, ild(u"Bì,0")); +} + +TEST(x86ild, test_428D0CB500000000) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea ecx, ptr [r14*4] + */ + ASSERT_EQ(8, ild(u"Bì♀╡    ")); +} + +TEST(x86ild, test_418D741500) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea esi, ptr [r13+rdx*1] + */ + ASSERT_EQ(5, ild(u"Aìt§ ")); +} + +TEST(x86ild, test_418D6B00) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea ebp, ptr [r11] + */ + ASSERT_EQ(4, ild(u"Aìk ")); +} + +TEST(x86ild, test_418D5600) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea edx, ptr [r14] + */ + ASSERT_EQ(4, ild(u"AìV ")); +} + +TEST(x86ild, test_418D4C2400) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea ecx, ptr [r12] + */ + ASSERT_EQ(5, ild(u"AìL$ ")); +} + +TEST(x86ild, test_418D4700) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [r15] + */ + ASSERT_EQ(4, ild(u"AìG ")); +} + +TEST(x86ild, test_418D440C00) { + /* + ICLASS: LEA + CATEGORY: MISC + EXTENSION: BASE + IFORM: LEA_GPRv_AGEN + ISA_SET: I86 + SHORT: lea eax, ptr [r12+rcx*1] + */ + ASSERT_EQ(5, ild(u"AìD♀ ")); +} diff --git a/test/libc/xed/x86ild_test.c b/test/libc/xed/x86ild_test.c new file mode 100644 index 00000000..1e078688 --- /dev/null +++ b/test/libc/xed/x86ild_test.c @@ -0,0 +1,99 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/gc.h" +#include "libc/testlib/testlib.h" +#include "test/libc/xed/lib.h" +#include "third_party/xed/x86.h" + +/** + * @fileoverview Instruction Length Decoding Tests. + * + * It is demonstrated that our 3.5kb x86 parser supports all legal x86 + * instruction set architectures and addressing modes since the 1970's, + * including the really complicated ones, e.g. avx512; or the unpopular + * ones, e.g. amd 3dnow. + */ + +TEST(x86ild, testSomeThingsNeverChange) { + ASSERT_EQ(3, ildreal(u"â└↨")); /* add $23,%ax */ + ASSERT_EQ(3, ildlegacy(u"â└↨")); /* add $23,%eax */ + ASSERT_EQ(3, ild(u"â└↨")); /* add $23,%eax */ +} + +TEST(x86ild, testSomeThingsDoChange) { + ASSERT_EQ(3, ildreal(u"♣7‼ÉÉ")); /* add $0x1337,%ax */ + ASSERT_EQ(5, ildlegacy(u"♣7‼ÉÉ")); /* add $0x90901337,%eax */ + ASSERT_EQ(5, ild(u"♣7‼ÉÉ")); /* add $0x90901337,%eax */ + ASSERT_EQ(1, ildreal(u"@É")); /* inc %ax */ + ASSERT_EQ(1, ildlegacy(u"@É")); /* inc %eax */ + ASSERT_EQ(2, ild(u"@É")); /* rex xchg %eax,%eax */ +} + +TEST(x86ild, testHugeInstructions) { + ASSERT_EQ(10, ild(u"H║       Ç")); /* movabs $0x8000000000000000,%rdx */ + ASSERT_EQ(11, ild(u"H╟♣8l   É  ")); /* movq $0x209000,0x6c38(%rip) */ + ASSERT_EQ(12, ild(u"H╟ä$á       ")); /* movq $0x0,0xa0(%rsp) */ +} + +TEST(x86ild, testLaughOutLoudLargeCanonicalInstructions) { + ASSERT_EQ(15, /* lock addl $0x12331337,%fs:-0x1337(%ebx,%esi,1) */ + ildreal(u"≡dfgüä3╔∞λλ7‼3↕")); +} + +TEST(x86ild, testEncodingDisagreements) { + ASSERT_EQ(13, /* lock addw $0x1337,%fs:-0x1337(%ebx,%esi,1) */ + ild(u"fg≡düä3╔∞λλ7‼")); /* ← xed encoding */ + ASSERT_EQ(13, /* lock addw $0x1337,%fs:-0x1337(%ebx,%esi,1) */ + ild(u"dgf≡üä3╔∞λλ7‼")); /* ← gas encoding */ +} + +TEST(x86ild, testOverlongInstructions) { + ASSERT_EQ(3, ild(u"≤≤É")); /* rep pause */ + ASSERT_EQ(-XED_ERROR_BUFFER_TOO_SHORT /* suboptimal error code */, + ildreal(u"≡≡≡≡dfgüä3╔∞λλ7‼3↕")); +} + +TEST(x86ild, testAvx512_inRealMode_throwsError) { + ASSERT_EQ(-XED_ERROR_INVALID_MODE, ildreal(u"bßTXYö∟¶♦  ")); +} + +TEST(x86ild, testAvx512) { + ASSERT_EQ(6, /* vaddps %zmm17,%zmm16,%zmm16 */ + ild(u"b¡|@X┴")); + ASSERT_EQ(11, /* vmulps 0x414(%rsp,%rbx,1){1to16},%zmm5,%zmm18 */ + ild(u"bßTXYö∟¶♦  ")); +} + +TEST(x86ild, testCascadeLake_advancedNeuralNetworkInstructions) { + ASSERT_EQ(6, ild(u"b≥m◘P╦")); /* vpdpbusd %xmm3,%xmm2,%xmm1 */ + ASSERT_EQ(11 /* vpdpbusd 0x10000000(%rcx,%r14,8),%xmm2,%xmm1 */, + ild(u"b▓m◘Pî±   ►")); +} + +TEST(x86ild, testAmd3dnow) { + ASSERT_EQ(4, ild(u"☼☼╚ª")); /* pfrcpit1 %mm0,%mm1 */ + struct XedDecodedInst xedd; + ASSERT_EQ( + 0, xed_instruction_length_decode( + xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LEGACY_32), + gc(unbingx86op(u"☼☼╚ª")), 4)); + ASSERT_EQ(true, xedd.operands.amd3dnow); + ASSERT_EQ(0xa6, xedd.operands.nominal_opcode); +} diff --git a/test/libc/xed/x86ild_widenop_test.c b/test/libc/xed/x86ild_widenop_test.c new file mode 100644 index 00000000..9df4fb4d --- /dev/null +++ b/test/libc/xed/x86ild_widenop_test.c @@ -0,0 +1,106 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/testlib.h" +#include "test/libc/xed/lib.h" +#include "third_party/xed/x86.h" + +/** + * @fileoverview Hefty NOPs. + */ + +TEST(x86ild, test_nop9_660F1F840000000000) { + /* + ICLASS: NOP + CATEGORY: WIDENOP + EXTENSION: BASE + IFORM: NOP_MEMv_GPRv_0F1F + ISA_SET: FAT_NOP + SHORT: nop word ptr [rax+rax*1], ax + */ + ASSERT_EQ(9, ild(u"f☼▼ä     ")); +} + +TEST(x86ild, test_nop8_0F1F840000000000) { + /* nopl 0x00000000(%rax,%rax,1) */ + ASSERT_EQ(8, ild(u"☼▼ä     ")); +} + +TEST(x86ild, test_nop7_0F1F8000000000) { + /* nopl 0x00000000(%rax) */ + ASSERT_EQ(7, ild(u"☼▼Ç    ")); +} + +TEST(x86ild, test_nop6_660F1F440000) { + /* + ICLASS: NOP + CATEGORY: WIDENOP + EXTENSION: BASE + IFORM: NOP_MEMv_GPRv_0F1F + ISA_SET: FAT_NOP + SHORT: nop word ptr [rax+rax*1], ax + */ + ASSERT_EQ(6, ild(u"f☼▼D  ")); +} + +TEST(x86ild, test_nop5_0F1F440000) { + /* + ICLASS: NOP + CATEGORY: WIDENOP + EXTENSION: BASE + IFORM: NOP_MEMv_GPRv_0F1F + ISA_SET: FAT_NOP + SHORT: nop dword ptr [rax+rax*1], eax + */ + ASSERT_EQ(5, ild(u"☼▼D  ")); +} + +TEST(x86ild, test_nop4_0F1F4000) { + /* + ICLASS: NOP + CATEGORY: WIDENOP + EXTENSION: BASE + IFORM: NOP_MEMv_GPRv_0F1F + ISA_SET: FAT_NOP + SHORT: nop dword ptr [rax], eax + */ + ASSERT_EQ(4, ild(u"☼▼@ ")); +} + +TEST(x86ild, test_nop3_0F1F00) { + /* + ICLASS: NOP + CATEGORY: WIDENOP + EXTENSION: BASE + IFORM: NOP_MEMv_GPRv_0F1F + ISA_SET: FAT_NOP + SHORT: nop dword ptr [rax], eax + */ + ASSERT_EQ(3, ild(u"☼▼ ")); +} + +TEST(x86ild, test_nop2_6690) { + /* xchg %ax,%ax */ + ASSERT_EQ(2, ild(u"fÉ")); +} + +TEST(x86ild, test_nop1_90) { + /* xchg %eax,%eax */ + ASSERT_EQ(1, ild(u"É")); +} diff --git a/test/net/http/parsehttprequest_test.c b/test/net/http/parsehttprequest_test.c new file mode 100644 index 00000000..838a87d1 --- /dev/null +++ b/test/net/http/parsehttprequest_test.c @@ -0,0 +1,70 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/mem/mem.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" +#include "net/http/http.h" + +TEST(parsehttprequest, testEmpty) { + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + struct HttpRequest *req = calloc(1, sizeof(struct HttpRequest)); + EXPECT_EQ(-1, parsehttprequest(req, f)); + EXPECT_TRUE(feof(f)); + freehttprequest(&req); + fclose(f); +} + +TEST(parsehttprequest, testNoHeaders) { + const char kMessage[] = "GET /foo HTTP/1.0\r\n" + "\r\n"; + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + ASSERT_EQ(1, fwrite(kMessage, strlen(kMessage), 1, f)); + struct HttpRequest *req = calloc(1, sizeof(struct HttpRequest)); + EXPECT_EQ(0, parsehttprequest(req, f)); + EXPECT_STREQN("GET", req->method.p, req->method.i); + EXPECT_STREQN("/foo", req->uri.p, req->uri.i); + EXPECT_STREQN("HTTP/1.0", req->version.p, req->version.i); + EXPECT_EQ(0, req->headers.count); + freehttprequest(&req); + fclose(f); +} + +TEST(parsehttprequest, testSomeHeaders) { + const char kMessage[] = "GET /foo?bar%20hi HTTP/1.0\r\n" + "Host: foo.example\r\n" + "Content-Length: 0\r\n" + "\r\n"; + FILE *f = fmemopen(NULL, BUFSIZ, "r+"); + ASSERT_EQ(1, fwrite(kMessage, strlen(kMessage), 1, f)); + struct HttpRequest *req = calloc(1, sizeof(struct HttpRequest)); + EXPECT_EQ(0, parsehttprequest(req, f)); + EXPECT_STREQN("GET", req->method.p, req->method.i); + EXPECT_STREQN("/foo?bar%20hi", req->uri.p, req->uri.i); + EXPECT_STREQN("HTTP/1.0", req->version.p, req->version.i); + EXPECT_EQ(2, req->headers.count); + EXPECT_STREQ("host:foo.example", critbit0_get(&req->headers, "host:")); + EXPECT_STREQ("content-length:0", + critbit0_get(&req->headers, "content-length:")); + EXPECT_EQ(NULL, critbit0_get(&req->headers, "content:")); + freehttprequest(&req); + fclose(f); +} diff --git a/test/net/http/test.mk b/test/net/http/test.mk new file mode 100644 index 00000000..17a77729 --- /dev/null +++ b/test/net/http/test.mk @@ -0,0 +1,43 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_NET_HTTP + +TEST_NET_HTTP_SRCS := $(wildcard test/net/http/*.c) +TEST_NET_HTTP_SRCS_TEST = $(filter %_test.c,$(TEST_NET_HTTP_SRCS)) +TEST_NET_HTTP_COMS = $(TEST_NET_HTTP_OBJS:%.o=%.com) +TEST_NET_HTTP_BINS = $(TEST_NET_HTTP_COMS) $(TEST_NET_HTTP_COMS:%=%.dbg) + +TEST_NET_HTTP_OBJS = \ + $(TEST_NET_HTTP_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_NET_HTTP_SRCS:%.c=o/$(MODE)/%.o) + +TEST_NET_HTTP_TESTS = \ + $(TEST_NET_HTTP_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_NET_HTTP_CHECKS = \ + $(TEST_NET_HTTP_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_NET_HTTP_DIRECTDEPS = \ + NET_HTTP \ + LIBC_TESTLIB + +TEST_NET_HTTP_DEPS := \ + $(call uniq,$(foreach x,$(TEST_NET_HTTP_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/net/http/http.pkg: \ + $(TEST_NET_HTTP_OBJS) \ + $(foreach x,$(TEST_NET_HTTP_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/net/http/%.com.dbg: \ + $(TEST_NET_HTTP_DEPS) \ + o/$(MODE)/test/net/http/%.o \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +.PHONY: o/$(MODE)/test/net/http +o/$(MODE)/test/net/http: \ + $(TEST_NET_HTTP_BINS) \ + $(TEST_NET_HTTP_CHECKS) diff --git a/test/net/http/uricspn_test.c b/test/net/http/uricspn_test.c new file mode 100644 index 00000000..015aa6d8 --- /dev/null +++ b/test/net/http/uricspn_test.c @@ -0,0 +1,60 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" +#include "net/http/uri.h" + +alignas(32) const char kWinsockIcoPngBase64[] = "\ +base64,iVBORw0KGgoAAAANSUhEUgAAAJcAAACXCAYAAAAYn8l5AAAABmJLR0QA/\ +wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4woLByMP6uwgW\ +QAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAMeSURBVHja7\ +d1BcuIwEAVQPMW94GbAzeBkZJepUXpw01ixDO+tE0PML+lHtsV0v9/vO+jgj1OAc\ +CFcIFwIF8IFP+wrvzRNkzP3y7a4YmTkQrgQLnitc/XqA3GX+9SrU/+ei8vl8uMnT\ +qeTkQvTIggXwoVC36mOJhZa3Upm5ALhQrjQuV6jT2HkQrgQLhAuNlLo+96Z6q5XI\ +xcIF8KFzrXbWTDt0jTf4AkrIxfChXCBcCFcCBcIF8LFO9iP/gajx9jXMvrj80Yuh\ +AuEC52r2q9G6jnRxWQX7Y1cCBfCBcLFxxb6tsBH5f12uz08xvV6Lb328Xh8+nfO5\ +/NsyVfwjVwIF8IFa3auzALpXL96pRst0dWinta+loVWIxfChXCBcCFcCBcIF8LFe\ +xn+6Z+5xc5oYTOzQJr5mcrFbYxcCBfCBcKFQv9AexdC9U7UueMueWwjFwgXwoVwO\ +QUIF8IFwkV3e6dgfdETQ5knmIxcmBZBuBAuUOgH1Rb6LRZ8IxfChXDBt+le2N9nq\ +a0a222VRn/aJrp5sO1CS22XlPkC9fa1R/tuIiMXwoVwgXDx5oV+ruCPJlrI7LXfa\ +XsuMouo1YXWXv8IGLkwLSJcMGbnyrzWmqK/s31/Ue+pdJr2uNECbrvoXP0cen2eR\ +i5MiwgXCBf9DX8n6ta+lCmzkFkp+FGhb89N9Yu52uMs9eVYRi5MiwgXbKdzba0TV\ +h7NjzpY5i7Tpb78tD1OZrE408GMXJgWES4QLhT6zRf8qAxXFlqXKu+Vgp/5xyX6u\ +41cmBYRLvg7dS5xJyqPzW2HFH0Ev9mxKjJ3wRq5MC0iXCBc9FdaRM38DzD6o/kjF\ +frRy7uRC+FCuOBlpUVUnjzJhQvXo+8PaxEV0yLCBU9xs+Cg2ies1+5g0RPfRi5Mi\ +wgXCBcK/UeYe3Ims6ia2RN1zfJu5MK0iHDBQy5cj/AhFLZd6inarskWSpgWES4QL\ +sZkEXUAS227VJU5ti2UMC0iXKBzfUIPW3vbqrm96qP3Z+TCtIhwgXCh0POfAt1T5\ +i6Nw+Ew+/6MXJgWES7Quejf74xcdPMFQQsgQ0YEZnUAAAAASUVORK5CYII="; + +size_t size; + +void SetUp(void) { + size = strlen(kWinsockIcoPngBase64); +} +BENCH(strlen, bench) { + EZBENCH(donothing, (size = strlen(kWinsockIcoPngBase64))); +} +TEST(uricspn, test) { + EXPECT_EQ(size, uricspn(kWinsockIcoPngBase64, size)); +} +BENCH(uricspn, bench) { + EZBENCH(donothing, uricspn(kWinsockIcoPngBase64, size)); +} diff --git a/test/net/http/uriparse_test.c b/test/net/http/uriparse_test.c new file mode 100644 index 00000000..77370020 --- /dev/null +++ b/test/net/http/uriparse_test.c @@ -0,0 +1,139 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "libc/errno.h" +#include "libc/log/log.h" +#include "libc/macros.h" +#include "libc/mem/mem.h" +#include "libc/runtime/gc.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" +#include "net/http/uri.h" + +#define URIPARSE(URI) uriparse(&uri, (p = URI), (size = sizeof(URI) - 1)) + +static const char kHttpCosmopolitanVideoUrl[] = + "http://cosmopolitan.storage.googleapis.com/pub/vid/blankspace.mpg"; + +static const char kSipPriceIsTortureUri[] = + "sip:bob%20barker:priceisright@[dead:beef::666]:5060;isup-oli=00"; + +static const char kWinsockIcoPngBase64[] = "\ +base64,iVBORw0KGgoAAAANSUhEUgAAAJcAAACXCAYAAAAYn8l5AAAABmJLR0QA/\ +wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4woLByMP6uwgW\ +QAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAMeSURBVHja7\ +d1BcuIwEAVQPMW94GbAzeBkZJepUXpw01ixDO+tE0PML+lHtsV0v9/vO+jgj1OAc\ +CFcIFwIF8IFP+wrvzRNkzP3y7a4YmTkQrgQLnitc/XqA3GX+9SrU/+ei8vl8uMnT\ +qeTkQvTIggXwoVC36mOJhZa3Upm5ALhQrjQuV6jT2HkQrgQLhAuNlLo+96Z6q5XI\ +xcIF8KFzrXbWTDt0jTf4AkrIxfChXCBcCFcCBcIF8LFO9iP/gajx9jXMvrj80Yuh\ +AuEC52r2q9G6jnRxWQX7Y1cCBfCBcLFxxb6tsBH5f12uz08xvV6Lb328Xh8+nfO5\ +/NsyVfwjVwIF8IFa3auzALpXL96pRst0dWinta+loVWIxfChXCBcCFcCBcIF8LFe\ +xn+6Z+5xc5oYTOzQJr5mcrFbYxcCBfCBcKFQv9AexdC9U7UueMueWwjFwgXwoVwO\ +QUIF8IFwkV3e6dgfdETQ5knmIxcmBZBuBAuUOgH1Rb6LRZ8IxfChXDBt+le2N9nq\ +a0a222VRn/aJrp5sO1CS22XlPkC9fa1R/tuIiMXwoVwgXDx5oV+ruCPJlrI7LXfa\ +XsuMouo1YXWXv8IGLkwLSJcMGbnyrzWmqK/s31/Ue+pdJr2uNECbrvoXP0cen2eR\ +i5MiwgXCBf9DX8n6ta+lCmzkFkp+FGhb89N9Yu52uMs9eVYRi5MiwgXbKdzba0TV\ +h7NjzpY5i7Tpb78tD1OZrE408GMXJgWES4QLhT6zRf8qAxXFlqXKu+Vgp/5xyX6u\ +41cmBYRLvg7dS5xJyqPzW2HFH0Ev9mxKjJ3wRq5MC0iXCBc9FdaRM38DzD6o/kjF\ +frRy7uRC+FCuOBlpUVUnjzJhQvXo+8PaxEV0yLCBU9xs+Cg2ies1+5g0RPfRi5Mi\ +wgXCBcK/UeYe3Ims6ia2RN1zfJu5MK0iHDBQy5cj/AhFLZd6inarskWSpgWES4QL\ +sZkEXUAS227VJU5ti2UMC0iXKBzfUIPW3vbqrm96qP3Z+TCtIhwgXCh0POfAt1T5\ +i6Nw+Ew+/6MXJgWES7Quejf74xcdPMFQQsgQ0YEZnUAAAAASUVORK5CYII="; + +static size_t size; +static const char *p; +static struct Uri uri; +static struct UriMem { + struct UriSlice segs[8]; + struct UriRef paramsegs[8]; + struct UriKeyval params[4], queries[4]; +} urimem_; + +INITIALIZER(100, _init_uri, { + uri.segs.n = ARRAYLEN(urimem_.segs); + uri.segs.p = urimem_.segs; + uri.params.n = ARRAYLEN(urimem_.params); + uri.params.p = urimem_.params; + uri.queries.n = ARRAYLEN(urimem_.queries); + uri.queries.p = urimem_.queries; + uri.paramsegs.n = ARRAYLEN(urimem_.paramsegs); + uri.paramsegs.p = urimem_.paramsegs; +}) + +TEST(uriparse, sipPstnUri) { + EXPECT_NE(-1, URIPARSE("sip:+12125650666")); + EXPECT_STREQ("sip", gc(strndup(p + uri.scheme.i, uri.scheme.n))); + EXPECT_STREQ("+12125650666", gc(strndup(p + uri.host.i, uri.host.n))); + EXPECT_STREQ("", gc(strndup(p + uri.opaque.i, uri.opaque.n))); +} + +TEST(uriparse, printVideoUrl) { + EXPECT_NE(-1, URIPARSE(kHttpCosmopolitanVideoUrl)); + EXPECT_STREQ("http", gc(strndup(p + uri.scheme.i, uri.scheme.n))); + EXPECT_STREQ("cosmopolitan.storage.googleapis.com", + gc(strndup(p + uri.host.i, uri.host.n))); + EXPECT_STREQ("", gc(strndup(p + uri.port.i, uri.port.n))); + EXPECT_STREQ("/pub/vid/blankspace.mpg", + gc(strndup(p + uri.segs.p[0].i, + (uri.segs.p[uri.segs.i - 1].n + + (uri.segs.p[uri.segs.i - 1].i - uri.segs.p[0].i))))); +} + +TEST(uriparse, localRelativeFile) { + EXPECT_NE(-1, URIPARSE("blankspace.mpg")); + EXPECT_STREQ("", gc(strndup(p + uri.scheme.i, uri.scheme.n))); + EXPECT_STREQ("", gc(strndup(p + uri.host.i, uri.host.n))); + EXPECT_STREQ("", gc(strndup(p + uri.port.i, uri.port.n))); + EXPECT_STREQ("blankspace.mpg", + gc(strndup(p + uri.segs.p[0].i, + (uri.segs.p[uri.segs.i - 1].n + + (uri.segs.p[uri.segs.i - 1].i - uri.segs.p[0].i))))); +} + +TEST(uriparse, badPort_einval) { + EXPECT_EQ(-1, URIPARSE("http://hello.example:http/")); + EXPECT_EQ(EINVAL, errno); +} + +TEST(uriparse, datauri) { + size = strlen((p = gc(xstrcat("data:image/png;", kWinsockIcoPngBase64)))); + EXPECT_NE(-1, uriparse(&uri, p, size)); + EXPECT_EQ(5, uri.opaque.i); + EXPECT_EQ(size - 5, uri.opaque.n); +} + +//////////////////////////////////////////////////////////////////////////////// + +BENCH(uriparse, bench) { + EZBENCH(donothing, URIPARSE("sip:+12125650666")); + EZBENCH(donothing, URIPARSE("http://hello.example")); + EZBENCH(donothing, URIPARSE(kHttpCosmopolitanVideoUrl)); + EZBENCH(donothing, URIPARSE(kSipPriceIsTortureUri)); +} + +BENCH(uriparse, bigWinsockIcoPngUri) { + const char *BigDataIconUri; + BigDataIconUri = gc(xstrcat("data:image/png;", kWinsockIcoPngBase64)); + size = strlen(kWinsockIcoPngBase64); + EZBENCH(donothing, uriparse(&uri, BigDataIconUri, size)); +} diff --git a/test/net/http/urischeme_test.c b/test/net/http/urischeme_test.c new file mode 100644 index 00000000..62ca423a --- /dev/null +++ b/test/net/http/urischeme_test.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" +#include "net/http/uri.h" + +TEST(urischeme, test) { + EXPECT_EQ(kUriSchemeSip, urischeme((struct UriSlice){0, 3}, "sips")); +} + +BENCH(urischeme, bench) { + EZBENCH(donothing, urischeme((struct UriSlice){0, 3}, "sips")); +} diff --git a/test/net/test.mk b/test/net/test.mk new file mode 100644 index 00000000..4d3db11e --- /dev/null +++ b/test/net/test.mk @@ -0,0 +1,5 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +.PHONY: o/$(MODE)/test/net +o/$(MODE)/test/net: o/$(MODE)/test/net/http diff --git a/test/test.mk b/test/test.mk new file mode 100644 index 00000000..ac1c02d1 --- /dev/null +++ b/test/test.mk @@ -0,0 +1,9 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +.PHONY: o/$(MODE)/test +o/$(MODE)/test: o/$(MODE)/test/ape \ + o/$(MODE)/test/dsp \ + o/$(MODE)/test/libc \ + o/$(MODE)/test/net \ + o/$(MODE)/test/tool diff --git a/test/tool/build/lib/interner_test.c b/test/tool/build/lib/interner_test.c new file mode 100644 index 00000000..d14152b7 --- /dev/null +++ b/test/tool/build/lib/interner_test.c @@ -0,0 +1,56 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/mem/mem.h" +#include "libc/runtime/gc.h" +#include "libc/str/str.h" +#include "libc/testlib/hyperion.h" +#include "libc/testlib/testlib.h" +#include "tool/build/lib/interner.h" + +TEST(interner, test) { + struct Interner *t = defer(freeinterner, newinterner()); + EXPECT_STREQ("hi", &t->p[intern(t, gc(strdup("hi")))]); + EXPECT_STREQ("there", &t->p[intern(t, gc(strdup("there")))]); + EXPECT_STREQ("hi", &t->p[intern(t, gc(strdup("hi")))]); + EXPECT_STREQ("there", &t->p[intern(t, gc(strdup("there")))]); + EXPECT_BINEQ(u"hi there  ", t->p); + EXPECT_EQ(strlen("hi") + 1 + strlen("there") + 1, t->i); +} + +TEST(interner, testWordCount) { + struct Interner *t = defer(freeinterner, newinterner()); + size_t i, j; + char word[16]; + for (i = 0, j = 0; i < kHyperionSize; ++i) { + if (isalpha(kHyperion[i]) || kHyperion[i] == '\'') { + word[j++] = tolower(kHyperion[i]); + } else if (j) { + word[j] = '\0'; + intern(t, word); + j = 0; + } + } + EXPECT_BINEQ(u"the fall of hyperion a dream", t->p); + /* 1547 = grep -Po "['a-zA-Z]+" hyperion.txt | tr A-Z a-z | dedupe | wc -l */ + EXPECT_EQ(1548, interncount(t)); + EXPECT_EQ(10502, t->i); + EXPECT_LT(t->i, t->n); + EXPECT_EQ('\0', t->p[t->i]); +} diff --git a/test/tool/build/lib/test.mk b/test/tool/build/lib/test.mk new file mode 100644 index 00000000..886990be --- /dev/null +++ b/test/tool/build/lib/test.mk @@ -0,0 +1,52 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_TOOL_BUILD_LIB + +TEST_TOOL_BUILD_LIB_SRCS := $(wildcard test/tool/build/lib/*.c) +TEST_TOOL_BUILD_LIB_SRCS_TEST = $(filter %_test.c,$(TEST_TOOL_BUILD_LIB_SRCS)) +TEST_TOOL_BUILD_LIB_COMS = $(TEST_TOOL_BUILD_LIB_OBJS:%.o=%.com) + +TEST_TOOL_BUILD_LIB_OBJS = \ + $(TEST_TOOL_BUILD_LIB_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_TOOL_BUILD_LIB_SRCS:%.c=o/$(MODE)/%.o) + +TEST_TOOL_BUILD_LIB_BINS = \ + $(TEST_TOOL_BUILD_LIB_COMS) \ + $(TEST_TOOL_BUILD_LIB_COMS:%=%.dbg) + +TEST_TOOL_BUILD_LIB_TESTS = \ + $(TEST_TOOL_BUILD_LIB_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_TOOL_BUILD_LIB_CHECKS = \ + $(TEST_TOOL_BUILD_LIB_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_TOOL_BUILD_LIB_DIRECTDEPS = \ + LIBC_X \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_STUBS \ + LIBC_TESTLIB \ + TOOL_BUILD_LIB + +TEST_TOOL_BUILD_LIB_DEPS := \ + $(call uniq,$(foreach x,$(TEST_TOOL_BUILD_LIB_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/tool/build/lib/buildlib.pkg: \ + $(TEST_TOOL_BUILD_LIB_OBJS) \ + $(foreach x,$(TEST_TOOL_BUILD_LIB_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/tool/build/lib/%.com.dbg: \ + $(TEST_TOOL_BUILD_LIB_DEPS) \ + o/$(MODE)/test/tool/build/lib/%.o \ + o/$(MODE)/test/tool/build/lib/buildlib.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +.PHONY: o/$(MODE)/test/tool/build/lib +o/$(MODE)/test/tool/build/lib: \ + $(TEST_TOOL_BUILD_LIB_BINS) \ + $(TEST_TOOL_BUILD_LIB_CHECKS) diff --git a/test/tool/build/test.mk b/test/tool/build/test.mk new file mode 100644 index 00000000..45106bb3 --- /dev/null +++ b/test/tool/build/test.mk @@ -0,0 +1,6 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +.PHONY: o/$(MODE)/test/tool/build +o/$(MODE)/test/tool/build: \ + o/$(MODE)/test/tool/build/lib diff --git a/test/tool/test.mk b/test/tool/test.mk new file mode 100644 index 00000000..066943cf --- /dev/null +++ b/test/tool/test.mk @@ -0,0 +1,7 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +.PHONY: o/$(MODE)/test/tool +o/$(MODE)/test/tool: \ + o/$(MODE)/test/tool/build \ + o/$(MODE)/test/tool/viz diff --git a/test/tool/viz/lib/bilinearscale_test.c b/test/tool/viz/lib/bilinearscale_test.c new file mode 100644 index 00000000..358bcf37 --- /dev/null +++ b/test/tool/viz/lib/bilinearscale_test.c @@ -0,0 +1,146 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/log/log.h" +#include "libc/rand/rand.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" +#include "tool/viz/lib/bilinearscale.h" +#include "tool/viz/lib/graphic.h" + +TEST(BilinearScale, testWindmill_1x1_to_2x2) { + EXPECT_BINEQ( + u"λλ" + u"λλ", + BilinearScale(1, 2, 2, tgc(tmalloc(1 * 2 * 2)), 1, 1, 1, + tgc(tunbing(u"λ")), 0, 1, 2, 2, 1, 1, .5, .5, 0, 0)); +} + +TEST(BilinearScale, testWindmill_4x4_to_2x2) { + EXPECT_BINEQ(u"λ " + u" λ", + BilinearScale(1, 2, 2, tgc(tmalloc(2 * 2)), 1, 4, 4, + tgc(tunbing(u"λλ  " + u"λλ  " + u"  λλ" + u"  λλ")), + 0, 1, 2, 2, 4, 4, 2, 2, 0, 0)); +} + +TEST(BilinearScale, testWindmill_8x8_to_4x4) { + EXPECT_BINEQ(u"λλ  " + u"λλ  " + u"  λλ" + u"  λλ", + BilinearScale(1, 4, 4, tgc(tmalloc(4 * 4)), 1, 8, 8, + tgc(tunbing(u"λλλλ    " + u"λλλλ    " + u"λλλλ    " + u"λλλλ    " + u"    λλλλ" + u"    λλλλ" + u"    λλλλ" + u"    λλλλ")), + 0, 1, 4, 4, 8, 8, 2, 2, 0, 0)); +} + +TEST(BilinearScale, testWindmill_4x4_to_8x8) { + EXPECT_BINEQ(u"λλλλ┐   " + u"λλλλ┐   " + u"λλλλ┐   " + u"λλλλ┐   " + u"┐┐┐┐ƒ⁇⁇⁇" + u"    ⁇λλλ" + u"    ⁇λλλ" + u"    ⁇λλλ", + BilinearScale(1, 8, 8, tgc(tmalloc(8 * 8)), 1, 4, 4, + tgc(tunbing(u"λλ  " + u"λλ  " + u"  λλ" + u"  λλ")), + 0, 1, 8, 8, 4, 4, .5, .5, 0, 0)); +} + +TEST(BilinearScale, testWindmill_5x5_to_8x8_withRatioIntent) { + EXPECT_BINEQ(u"λλλλλ   " + u"λλλλλ   " + u"λλλλλ   " + u"¬¬¬╞λTTT" + u"   Tλλλλ" + u"     λλλ" + u"     λλλ" + u"     λλλ", + BilinearScale(1, 8, 8, tgc(tmalloc(8 * 8)), 1, 5, 5, + tgc(tunbing(u"λλλ  " + u"λλλ  " + u"  λλλ" + u"   λλ" + u"   λλ")), + 0, 1, 8, 8, 5, 5, 2 / 3., 2 / 3., 0, 0)); +} + +TEST(BilinearScale, testWindmill_5x5_to_8x8_withoutRatioIntent) { + EXPECT_BINEQ(u"λλλλλÅ  " + u"λλλλλÅ  " + u"λλλλλÅ  " + u"╧╧╧╪λñ//" + u"   /λλλλ" + u"   →Å└λλ" + u"     oλλ" + u"     oλλ", + BilinearScale(1, 8, 8, tgc(tmalloc(8 * 8)), 1, 5, 5, + tgc(tunbing(u"λλλ  " + u"λλλ  " + u"  λλλ" + u"   λλ" + u"   λλ")), + 0, 1, 8, 8, 5, 5, 5 / 8., 5 / 8., 0, 0)); +} + +TEST(BilinearScale, testNyquistTorture) { + EXPECT_BINEQ(u"███ " + u"████" + u" ███" + u"███ ", + BilinearScale(1, 4, 4, tgc(tmalloc(4 * 4)), 1, 8, 8, + tgc(tunbing(u"█ █ █ " + u" █ █ █ " + u"█ █ █ █ " + u" █ █ █ █" + u" █ █ █ " + u" █ █ █ " + u"█ █ █ " + u" █ █ ")), + 0, 1, 4, 4, 8, 8, 2, 2, 0, 0)); +} + +BENCH(BilinearScale, Bench) { + void *src, *dst; + double c, w1, h1, w2, h2; + c = 3; + w1 = 1920; + h1 = 1080; + w2 = 1136; + h2 = 136; + src = tgc(tmemalign(32, w1 * h1 * c)); + dst = tgc(tmemalign(32, w2 * h2 * c)); + EZBENCH2("BilinearScale", donothing, + BilinearScale(c, h2, w2, dst, c, h1, w1, src, 0, c, h2, w2, h1, w1, + h2 / h1, w2 / w1, 0, 0)); +} diff --git a/test/tool/viz/lib/convoindex_test.c b/test/tool/viz/lib/convoindex_test.c new file mode 100644 index 00000000..3d7a9005 --- /dev/null +++ b/test/tool/viz/lib/convoindex_test.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/gc.h" +#include "libc/testlib/testlib.h" +#include "tool/viz/lib/convolution.h" + +TEST(convoindex, test) { + unsigned *ix; + ix = gc(convoindex(2, 2, 2)); + ix += 2; + EXPECT_EQ(0, ix[-2]); + EXPECT_EQ(0, ix[-1]); + EXPECT_EQ(0, ix[+0]); + EXPECT_EQ(1, ix[+1]); + EXPECT_EQ(1, ix[+2]); + EXPECT_EQ(1, ix[+3]); +} diff --git a/test/tool/viz/lib/fun_test.c b/test/tool/viz/lib/fun_test.c new file mode 100644 index 00000000..a43e7826 --- /dev/null +++ b/test/tool/viz/lib/fun_test.c @@ -0,0 +1,333 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/log/check.h" +#include "libc/macros.h" +#include "libc/rand/rand.h" +#include "libc/runtime/gc.h" +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" +#include "tool/viz/lib/ycbcr.h" + +#define C1331(A, B, C, D) \ + ({ \ + unsigned short Ax, Bx; \ + unsigned char Al, Bl, Cl, Dl; \ + Al = (A); \ + Bl = (B); \ + Cl = (C); \ + Dl = (D); \ + Bx = Bl; \ + Bx += Cl; \ + Bx *= 3; \ + Ax = Al; \ + Ax += Dl; \ + Ax += Bx; \ + Ax += 4; \ + Ax >>= 3; \ + Al = Ax; \ + Al; \ + }) + +TEST(C1331, test) { + EXPECT_EQ(0, C1331(0, 0, 0, 0)); + EXPECT_EQ(255, C1331(255, 255, 255, 255)); + EXPECT_EQ(79, C1331(33, 100, 77, 69)); + EXPECT_EQ(80, C1331(39, 100, 77, 69)); +} + +#define C161(A, B, C) \ + ({ \ + short Dx; \ + unsigned char Dl; \ + unsigned char Al, Bl, Cl; \ + unsigned short Ax, Bx, Cx; \ + Al = (A); \ + Bl = (B); \ + Cl = (C); \ + \ + Bx = Bl; \ + Bx += 3; \ + Bx >>= 1; \ + Bx += Bl; \ + \ + Ax = Al; \ + Ax += 4; \ + Ax >>= 2; \ + \ + Cx = Cl; \ + Cx += 4; \ + Cx >>= 2; \ + \ + Dx = Bx; \ + Dx -= Ax; \ + Dx -= Cx; \ + \ + Dx = MAX(0, Dx); \ + Dx = MIN(255, Dx); \ + Dl = Dx; \ + Dl; \ + }) + +TEST(C161, test) { + EXPECT_EQ(0, C161(0, 0, 0)); + EXPECT_EQ(255, C161(255, 255, 255)); + EXPECT_EQ(124, C161(33, 100, 69)); /* 124.50 = 3/2.*100 -1/4.*33 -1/4.*69 */ + EXPECT_EQ(124, C161(33, 100, 70)); /* 124.25 = 3/2.*100 -1/4.*33 -1/4.*70 */ + EXPECT_EQ(126, C161(33, 101, 69)); /* 126.00 = 3/2.*101 -1/4.*33 -1/4.*69 */ +} + +#define C121(A, B, C) \ + ({ \ + short Dx; \ + unsigned char Dl; \ + unsigned char Al, Bl, Cl; \ + unsigned short Ax, Bx, Cx; \ + Al = (A); \ + Bl = (B); \ + Cl = (C); \ + \ + Bx = Bl; \ + Bx += 3; \ + Bx >>= 1; \ + Bx += Bl; \ + \ + Ax = Al; \ + Ax += 4; \ + Ax >>= 2; \ + \ + Cx = Cl; \ + Cx += 4; \ + Cx >>= 2; \ + \ + Dx = Bx; \ + Dx -= Ax; \ + Dx -= Cx; \ + \ + Dx = MAX(0, Dx); \ + Dx = MIN(255, Dx); \ + Dl = Dx; \ + Dl; \ + }) + +TEST(C121, test) { + EXPECT_EQ(0, C161(0, 0, 0)); + EXPECT_EQ(255, C161(255, 255, 255)); + EXPECT_EQ(124, C161(33, 100, 69)); /* 124.50 = 3/2.*100 -1/4.*33 -1/4.*69 */ + EXPECT_EQ(124, C161(33, 100, 70)); /* 124.25 = 3/2.*100 -1/4.*33 -1/4.*70 */ + EXPECT_EQ(126, C161(33, 101, 69)); /* 126.00 = 3/2.*101 -1/4.*33 -1/4.*69 */ +} + +#define BLERP(A, B, P) \ + ({ \ + unsigned char Al, Bl, Cl, Dl; \ + unsigned short Bx; \ + Al = (A); \ + Bl = (B); \ + Cl = MAX(Al, Bl); \ + Al = MIN(Al, Bl); \ + Dl = Cl - Al; \ + Bl = (P); \ + Bx = Bl; \ + Bx *= Dl; \ + Bx += 255; \ + Bx >>= 8; \ + Bx += Al; \ + Al = Bx; \ + Al; \ + }) + +TEST(BLERP, test) { + EXPECT_EQ(0, BLERP(0, 0, 128)); + EXPECT_EQ(255, BLERP(255, 255, 128)); + EXPECT_EQ(64, BLERP(0, 128, 128)); + EXPECT_EQ(64, BLERP(128, 0, 128)); + EXPECT_EQ(32, BLERP(0, 128, 64)); + EXPECT_EQ(32, BLERP(128, 0, 64)); + EXPECT_EQ(8, BLERP(0, 128, 16)); + EXPECT_EQ(8, BLERP(128, 0, 16)); + EXPECT_EQ(0, BLERP(0, 128, 0)); + EXPECT_EQ(0, BLERP(128, 0, 0)); + EXPECT_EQ(128, BLERP(0, 128, 255)); + EXPECT_EQ(128, BLERP(128, 0, 255)); +} + +#define MIX(A, B) \ + ({ \ + short Ax, Bx; \ + Ax = (A); \ + Bx = (B); \ + Ax += Bx; \ + Ax += 1; \ + Ax /= 2; \ + Ax; \ + }) + +TEST(MIX, test) { + EXPECT_EQ(0, MIX(0, 0)); + EXPECT_EQ(255, MIX(255, 255)); + EXPECT_EQ(64, MIX(0, 128)); + EXPECT_EQ(64, MIX(128, 0)); + EXPECT_EQ(127, MIX(0, 254)); +} + +void ExpandLuminosityRange(unsigned n, unsigned char *Y) { + unsigned i, j; + unsigned char b[16]; + unsigned short s[16]; + CHECK_ALIGNED(16, Y); + for (i = 0; i < n; i += 16) { + memcpy(b, Y + i, 16); + for (j = 0; j < 16; ++j) b[j] = MAX(0, b[j] - 16); + for (j = 0; j < 16; ++j) s[j] = b[j]; + for (j = 0; j < 16; ++j) s[j] *= 150; + for (j = 0; j < 16; ++j) s[j] /= 128; + for (j = 0; j < 16; ++j) s[j] = MIN(255, s[j]); + for (j = 0; j < 16; ++j) b[j] = s[j]; + memcpy(Y + i, b, 16); + } +} + +TEST(ExpandLuminosityRange, test) { + unsigned char Y[32]; + Y[0] = 0; + ExpandLuminosityRange(16, Y); + EXPECT_EQ(0, Y[0]); + Y[0] = 16; + ExpandLuminosityRange(16, Y); + EXPECT_EQ(0, Y[0]); + Y[0] = 17; + ExpandLuminosityRange(16, Y); + EXPECT_EQ(1, Y[0]); + Y[0] = 128; + ExpandLuminosityRange(16, Y); + EXPECT_EQ(131, Y[0]); + Y[0] = 233; + ExpandLuminosityRange(16, Y); + EXPECT_EQ(254, Y[0]); + Y[0] = 235; + ExpandLuminosityRange(16, Y); + EXPECT_EQ(255, Y[0]); + Y[0] = 255; + ExpandLuminosityRange(16, Y); + EXPECT_EQ(255, Y[0]); +} + +#if 1 +void NtscItu601YCbCrToStandardRgb(unsigned n, unsigned char *restrict Y, + unsigned char *restrict Cb, + unsigned char *restrict Cr) { + unsigned i; + short r, g, b; + unsigned char y; + for (i = 0; i < n; ++i) { + y = MIN(255, (MIN(235, MAX(16, Y[i])) - 16) * 150 / 128); + r = y + ((Cr[i] + ((Cr[i] * 103) / 256)) - 179); + g = y - (((Cb[i] * 88) / 256) - 44 + ((Cr[i] * 183) / 256) - 91); + b = y + ((Cb[i] + ((Cb[i] * 198) / 256)) - 227); + Y[i] = MIN(255, MAX(0, r)); + Cb[i] = MIN(255, MAX(0, g)); + Cr[i] = MIN(255, MAX(0, b)); + } +} +#else +void NtscItu601YCbCrToStandardRgb(size_t n, unsigned char *restrict Y, + unsigned char *restrict Cb, + unsigned char *restrict Cr) { + unsigned i; + short y, gb, gr, r, g, b; + unsigned char gs, cb, cr; + unsigned short bw, ky, kr, kb, kgb, kgr; + for (i = 0; i < n; ++i) { + y = Y[i]; + cb = Cb[i]; + cr = Cr[i]; + y -= 16; /* luminance (expand tv range [16,235] for pc [0,255]) */ + y = MAX(0, y); + y = MIN(234 - 16, y); + ky = y; + ky *= 150; + ky /= 128; + gs = ky; + kr = cr; /* red */ + kr *= 103; + kr /= 256; + kr += cr; + r = kr; + r -= 179; + r += gs; + kb = cb; /* blue */ + kb *= 198; + kb /= 256; + kb += cb; + b = kb; + b -= 227; + b += gs; + kgb = cb; /* green */ + kgb *= 88; + kgb /= 256; + gb = kgb; + gb -= 44; + kgr = cr; + kgr *= 183; + kgr /= 256; + gr = kgr; + gr -= 91; + g = gs; + g -= gr; + g -= gb; + r = MAX(0, r); /* clamp */ + g = MAX(0, g); + b = MAX(0, b); + r = MIN(255, r); + g = MIN(255, g); + b = MIN(255, b); + Y[i] = r; + Cb[i] = g; + Cr[i] = b; + } +} +#endif + +TEST(NtscItu601YCbCrToStandardRgb, testWhite) { + unsigned char a, b, c; + a = 234; + b = 128; + c = 128; + NtscItu601YCbCrToStandardRgb(1, &a, &b, &c); + EXPECT_EQ(255, a); + EXPECT_EQ(255, b); + EXPECT_EQ(255, c); + a = 235; + b = 128; + c = 128; + NtscItu601YCbCrToStandardRgb(1, &a, &b, &c); + EXPECT_EQ(255, a); + EXPECT_EQ(255, b); + EXPECT_EQ(255, c); + a = 255; + b = 128; + c = 128; + NtscItu601YCbCrToStandardRgb(1, &a, &b, &c); + EXPECT_EQ(255, a); + EXPECT_EQ(255, b); + EXPECT_EQ(255, c); +} diff --git a/test/tool/viz/lib/halfblit_test.c b/test/tool/viz/lib/halfblit_test.c new file mode 100644 index 00000000..b0a4b6ea --- /dev/null +++ b/test/tool/viz/lib/halfblit_test.c @@ -0,0 +1,45 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/testlib/testlib.h" +#include "tool/viz/lib/halfblit.h" + +TEST(halfblit, test_4x4_to_2x2) { + EXPECT_BINEQ(u" ☺" + u"►◄", + halfblit(2, tgc(tunbing(u" ☺☻♥" + u"►◄↕‼" + u"♀♪♫☼" + u"∟↔▲▼")))); +} + +TEST(halfblit, test_8x8_to_4x4) { + EXPECT_BINEQ(u" ☺☻♥" + u"►◄↕‼" + u"◘○◙♂" + u"↑↓→←", + halfblit(4, tgc(tunbing(u" ☺☻♥♦♣♠•" + u"►◄↕‼¶§▬↨" + u"◘○◙♂♀♪♫☼" + u"↑↓→←∟↔▲▼" + u"01234567" + u"░▒▓│┤╡╢╖" + u"╕╣║╗╝╜╛┐" + u"89:;<=>?")))); +} diff --git a/test/tool/viz/lib/test.mk b/test/tool/viz/lib/test.mk new file mode 100644 index 00000000..631862fb --- /dev/null +++ b/test/tool/viz/lib/test.mk @@ -0,0 +1,62 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_TOOL_VIZ_LIB + +TEST_TOOL_VIZ_LIB_SRCS := $(wildcard test/tool/viz/lib/*.c) +TEST_TOOL_VIZ_LIB_SRCS_TEST = $(filter %_test.c,$(TEST_TOOL_VIZ_LIB_SRCS)) +TEST_TOOL_VIZ_LIB_COMS = $(TEST_TOOL_VIZ_LIB_OBJS:%.o=%.com) + +TEST_TOOL_VIZ_LIB_OBJS = \ + $(TEST_TOOL_VIZ_LIB_SRCS:%=o/$(MODE)/%.zip.o) \ + $(TEST_TOOL_VIZ_LIB_SRCS:%.c=o/$(MODE)/%.o) + +TEST_TOOL_VIZ_LIB_BINS = \ + $(TEST_TOOL_VIZ_LIB_COMS) \ + $(TEST_TOOL_VIZ_LIB_COMS:%=%.dbg) + +TEST_TOOL_VIZ_LIB_TESTS = \ + $(TEST_TOOL_VIZ_LIB_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_TOOL_VIZ_LIB_CHECKS = \ + $(TEST_TOOL_VIZ_LIB_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_TOOL_VIZ_LIB_DIRECTDEPS = \ + DSP_MPEG \ + LIBC_FMT \ + LIBC_LOG \ + LIBC_UNICODE \ + LIBC_TIME \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_ALG \ + LIBC_RAND \ + LIBC_STDIO \ + LIBC_STUBS \ + LIBC_TINYMATH \ + LIBC_TESTLIB \ + LIBC_X \ + TOOL_VIZ_LIB \ + THIRD_PARTY_AVIR + +TEST_TOOL_VIZ_LIB_DEPS := \ + $(call uniq,$(foreach x,$(TEST_TOOL_VIZ_LIB_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/tool/viz/lib/vizlib.pkg: \ + $(TEST_TOOL_VIZ_LIB_OBJS) \ + $(foreach x,$(TEST_TOOL_VIZ_LIB_DIRECTDEPS),$($(x)_A).pkg) + +o/$(MODE)/test/tool/viz/lib/%.com.dbg: \ + $(TEST_TOOL_VIZ_LIB_DEPS) \ + o/$(MODE)/test/tool/viz/lib/%.o \ + o/$(MODE)/test/tool/viz/lib/vizlib.pkg \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE) + @$(APELINK) + +.PHONY: o/$(MODE)/test/tool/viz/lib +o/$(MODE)/test/tool/viz/lib: \ + $(TEST_TOOL_VIZ_LIB_BINS) \ + $(TEST_TOOL_VIZ_LIB_CHECKS) diff --git a/test/tool/viz/lib/ycbcr2rgb2_test.c b/test/tool/viz/lib/ycbcr2rgb2_test.c new file mode 100644 index 00000000..e8dc180d --- /dev/null +++ b/test/tool/viz/lib/ycbcr2rgb2_test.c @@ -0,0 +1,90 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "dsp/mpeg/mpeg.h" +#include "libc/macros.h" +#include "libc/rand/rand.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/testlib/ezbench.h" +#include "libc/testlib/testlib.h" +#include "libc/time/time.h" +#include "tool/viz/lib/graphic.h" +#include "tool/viz/lib/ycbcr.h" + +#if 0 +__v4sf fRGBA[4][3]; +unsigned char iRGB[3][8][8]; +unsigned char uRGB[4][4][3]; + +unsigned char kY[16][16] = { + {16, 43, 16, 43}, + {70, 97, 70, 97}, + {16, 43, 16, 43}, + {70, 97, 70, 97}, +}; + +unsigned char kCb[8][8] = { + {240, 240}, + {240, 240}, +}; + +unsigned char kCr[8][8] = { + {35, 35}, + {35, 35}, +}; + +plm_frame_t kFrame = { + .width = 4, + .height = 4, + .y = {.width = 16, .height = 16, .data = (void *)kY}, + .cb = {.width = 8, .height = 8, .data = (void *)kCb}, + .cr = {.width = 8, .height = 8, .data = (void *)kCr}, +}; + +TEST(ycbcr2rgb, testMyImpl) { + memset(iRGB, 0, sizeof(iRGB)); + YCbCr2RGB(1, iRGB, kY, kCb, kCr); + EXPECT_EQ(0, iRGB[0][0][0]); + EXPECT_BINEQ(u" " + u" ", + iRGB[1]); +} + +TEST(ycbcr2rgb, testReferenceImpl) { + memset(uRGB, 0, sizeof(uRGB)); + plm_frame_to_rgb(&kFrame, (void *)uRGB); + EXPECT_BINEQ(u" :╓", uRGB[0][0]); + EXPECT_BINEQ(u" U±", uRGB[0][1]); + EXPECT_BINEQ(u" :╓", uRGB[0][2]); + EXPECT_BINEQ(u" U±", uRGB[0][3]); + EXPECT_BINEQ(u" pλ", uRGB[1][0]); + EXPECT_BINEQ(u" ïλ", uRGB[1][1]); + EXPECT_BINEQ(u" pλ", uRGB[1][2]); + EXPECT_BINEQ(u" ïλ", uRGB[1][3]); + EXPECT_BINEQ(u" :╓", uRGB[2][0]); + EXPECT_BINEQ(u" U±", uRGB[2][1]); + EXPECT_BINEQ(u" :╓", uRGB[2][2]); + EXPECT_BINEQ(u" U±", uRGB[2][3]); + EXPECT_BINEQ(u" pλ", uRGB[3][0]); + EXPECT_BINEQ(u" ïλ", uRGB[3][1]); + EXPECT_BINEQ(u" pλ", uRGB[3][2]); + EXPECT_BINEQ(u" ïλ", uRGB[3][3]); +} +#endif diff --git a/test/tool/viz/test.mk b/test/tool/viz/test.mk new file mode 100644 index 00000000..e97cba50 --- /dev/null +++ b/test/tool/viz/test.mk @@ -0,0 +1,6 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +.PHONY: o/$(MODE)/test/tool/viz +o/$(MODE)/test/tool/viz: \ + o/$(MODE)/test/tool/viz/lib diff --git a/third_party/avir/LICENSE b/third_party/avir/LICENSE new file mode 100644 index 00000000..19aecd7c --- /dev/null +++ b/third_party/avir/LICENSE @@ -0,0 +1,26 @@ +AVIR License Agreement + +The MIT License (MIT) + +AVIR Copyright (c) 2015-2019 Aleksey Vaneev + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +Please credit the author of this library in your documentation in the +following way: "AVIR image resizing algorithm designed by Aleksey Vaneev" diff --git a/third_party/avir/README.cosmo b/third_party/avir/README.cosmo new file mode 100644 index 00000000..345cac31 --- /dev/null +++ b/third_party/avir/README.cosmo @@ -0,0 +1,5 @@ +commit 7dd9515ef6aed6fb6d565ee12754703bdc46b3b0 +Author: Aleksey Vaneev +Date: Mon Jul 29 07:43:23 2019 +0300 + + Version 2.4 release. diff --git a/third_party/avir/README.md b/third_party/avir/README.md new file mode 100644 index 00000000..bab3b1b5 --- /dev/null +++ b/third_party/avir/README.md @@ -0,0 +1,367 @@ +# AVIR # +## Introduction ## +Keywords: image resize, image resizer, image resizing, image scaling, +image scaler, image resize c++, image resizer c++ + +Please consider supporting the author on [Patreon](https://www.patreon.com/aleksey_vaneev). + +Me, Aleksey Vaneev, is happy to offer you an open source image resizing / +scaling library which has reached a production level of quality, and is +ready to be incorporated into any project. This library features routines +for both down- and upsizing of 8- and 16-bit, 1 to 4-channel images. Image +resizing routines were implemented in multi-platform C++ code, and have a +high level of optimality. Beside resizing, this library offers a sub-pixel +shift operation. Built-in sRGB gamma correction is available. + +The resizing algorithm at first produces 2X upsized image (relative to the +source image size, or relative to the destination image size if downsizing is +performed) and then performs interpolation using a bank of sinc function-based +fractional delay filters. At the last stage a correction filter is applied +which fixes smoothing introduced at previous steps. + +The resizing algorithm was designed to provide the best visual quality. The +author even believes this algorithm provides the "ultimate" level of +quality (for an orthogonal resizing) which cannot be increased further: no +math exists to provide a better frequency response, better anti-aliasing +quality and at the same time having less ringing artifacts: these are 3 +elements that define any resizing algorithm's quality; in AVIR practice these +elements have a high correlation to each other, so they can be represented by +a single parameter (AVIR offers several parameter sets with varying quality). +Algorithm's time performance turned out to be very good as well (for the +"ultimate" image quality). + +An important element utilized by this algorithm is the so called Peaked Cosine +window function, which is applied over sinc function in all filters. Please +consult the documentation for more details. + +Note that since AVIR implements orthogonal resizing, it may exhibit diagonal +aliasing artifacts. These artifacts are usually suppressed by EWA or radial +filtering techniques. EWA-like technique is not implemented in AVIR, because +it requires considerably more computing resources and may produce a blurred +image. + +As a bonus, a faster `LANCIR` image resizing algorithm is also offered as a +part of this library. But the main focus of this documentation is the original +AVIR image resizing algorithm. + +AVIR does not offer affine and non-linear image transformations "out of the +box". Since upsizing is a relatively fast operation in AVIR (required time +scales linearly with the output image area), affine and non-linear +transformations can be implemented in steps: 4- to 8-times upsizing, +transformation via bilinear interpolation, downsizing (linear proportional +affine transformations can probably skip the downsizing step). This should not +compromise the transformation quality much as bilinear interpolation's +problems will mostly reside in spectral area without useful signal, with a +maximum of 0.7 dB high-frequency attenuation for 4-times upsizing, and 0.17 dB +attenuation for 8-times upsizing. This approach is probably as time efficient +as performing a high-quality transform over the input image directly (the only +serious drawback is the increased memory requirement). Note that affine +transformations that change image proportions should first apply proportion +change during upsizing. + +*AVIR is devoted to women. Your digital photos can look good at any size!* + +## Requirements ## +C++ compiler and system with efficient "float" floating point (24-bit +mantissa) type support. This library can also internally use the "double" and +SIMD floating point types during resizing if needed. This library does not +have dependencies beside the standard C library. + +## Links ## +* [Documentation](https://www.voxengo.com/public/avir/Documentation/) + +## Usage Information ## +The image resizer is represented by the `avir::CImageResizer<>` class, which +is a single front-end class for the whole library. Basically, you do not need +to use nor understand any other classes beside this class. + +The code of the library resides in the "avir" C++ namespace, effectively +isolating it from all other code. The code is thread-safe. You need just +a single resizer object per running application, at any time, even when +resizing images concurrently. + +To resize images in your application, simply add 3 lines of code: + + #include "avir.h" + avir :: CImageResizer<> ImageResizer( 8 ); + ImageResizer.resizeImage( InBuf, 640, 480, 0, OutBuf, 1024, 768, 3, 0 ); + (multi-threaded operation requires additional coding, see the documentation) + +For low-ringing performance: + + avir :: CImageResizer<> ImageResizer( 8, 0, avir :: CImageResizerParamsLR() ); + +To use the built-in gamma correction, an object of the +`avir::CImageResizerVars` class with its variable `UseSRGBGamma` set to "true" +should be supplied to the `resizeImage()` function. Note that the gamma +correction is applied to all channels (e.g. alpha-channel) in the current +implementation. + + avir :: CImageResizerVars Vars; + Vars.UseSRGBGamma = true; + +Dithering (error-diffusion dither which is perceptually good) can be enabled +this way: + + typedef avir :: fpclass_def< float, float, + avir :: CImageResizerDithererErrdINL< float > > fpclass_dith; + avir :: CImageResizer< fpclass_dith > ImageResizer( 8 ); + +The library is able to process images of any bit depth: this includes 8-bit, +16-bit, float and double types. Larger integer and signed integer types are +not supported. Supported source and destination image sizes are only limited +by the available system memory. + +The code of this library was commented in the [Doxygen](http://www.doxygen.org/) +style. To generate the documentation locally you may run the +`doxygen ./other/avirdoxy.txt` command from the library's directory. Note that +the code was suitably documented allowing you to make modifications, and to +gain full understanding of the algorithm. + +Preliminary tests show that this library (compiled with Intel C++ Compiler +18.2 with AVX2 instructions enabled, without explicit SIMD resizing code) can +resize 8-bit RGB 5184x3456 (17.9 Mpixel) 3-channel image down to 1920x1280 +(2.5 Mpixel) image in 245 milliseconds, utilizing a single thread, on Intel +Core i7-7700K processor-based system without overclocking. This scales down to +74 milliseconds if 8 threads are utilized. + +Multi-threaded operation is not provided by this library "out of the box". +The multi-threaded (horizontally-threaded) infrastructure is available, but +requires additional system-specific interfacing code for engagement. + +## SIMD Usage Information ## +This library is capable of using SIMD floating point types for internal +variables. This means that up to 4 color channels can be processed in +parallel. Since the default interleaved processing algorithm itself remains +non-SIMD, the use of SIMD internal types is not practical for 1- and 2-channel +image resizing (due to overhead). SIMD internal type can be used this way: + + #include "avir_float4_sse.h" + avir :: CImageResizer< avir :: fpclass_float4 > ImageResizer( 8 ); + +For 1-channel and 2-channel image resizing when AVX instructions are allowed +it may be reasonable to utilize de-interleaved SIMD processing algorithm. +While it gives no performance benefit if the "float4" SSE processing type is +used, it offers some performance boost if the "float8" AVX processing type is +used (given dithering is not performed, or otherwise performance is reduced at +the dithering stage since recursive dithering cannot be parallelized). The +internal type remains non-SIMD "float". De-interleaved algorithm can be used +this way: + + #include "avir_float8_avx.h" + avir :: CImageResizer< avir :: fpclass_float8_dil > ImageResizer( 8 ); + +It's important to note that on the latest Intel processors (i7-7700K and +probably later) the use of the aforementioned SIMD-specific resizing code may +not be justifiable, or may be even counter-productive due to many factors: +memory bandwidth bottleneck, increased efficiency of processor's circuitry +utilization and out-of-order execution, automatic SIMD optimizations performed +by the compiler. This is at least true when compiling 64-bit code with Intel +C++ Compiler 18.2 with /QxSSE4.2, or especially with the /QxCORE-AVX2 option. +SSE-specific resizing code may still be a little bit more efficient for +4-channel image resizing. + +## Notes ## +This library was tested for compatibility with [GNU C++](http://gcc.gnu.org/), +[Microsoft Visual C++](http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-products) +and [Intel C++](http://software.intel.com/en-us/c-compilers) compilers, on 32- +and 64-bit Windows, macOS and CentOS Linux. The code was also tested with +Dr.Memory/Win32 for the absence of uninitialized or unaddressable memory +accesses. + +All code is fully "inline", without the need to compile any source files. The +memory footprint of the library itself is very modest, except that the size of +the temporary image buffers depends on the input and output image sizes, and +is proportionally large. + +The "heart" of resizing algorithm's quality resides in the parameters defined +via the `avir::CImageResizerParams` structure. While the default set of +parameters that offers a good quality was already provided, there is +(probably) still a place for improvement exists, and the default parameters +may change in a future update. If you need to recall an exact set of +parameters, simply save them locally for a later use. + +When the algorithm is run with no resizing applied (k=1), the result of +resizing will not be an exact, but a very close copy of the source image. The +reason for such inexactness is that the image is always low-pass filtered at +first to reduce aliasing during subsequent resizing, and at last filtered by a +correction filter. Such approach allows algorithm to maintain a stable level +of quality regardless of the resizing "k" factor used. + +This library includes a binary command line tool "imageresize" for major +desktop platforms. This tool was designed to be used as a demonstration of +library's performance, and as a reference, it is multi-threaded (the `-t` +switch can be used to control the number of threads utilized). This tool uses +plain "float" processing (no explicit SIMD) and relies on automatic compiler +optimization (with Win64 binary being the "main" binary as it was compiled +with the best ICC optimization options for the time being). This tool uses the +following libraries: +* turbojpeg Copyright (c) 2009-2013 D. R. Commander +* libpng Copyright (c) 1998-2013 Glenn Randers-Pehrson +* zlib Copyright (c) 1995-2013 Jean-loup Gailly and Mark Adler + +Note that you can enable gamma-correction with the `-g` switch. However, +sometimes gamma-correction produces "greenish/reddish/bluish haze" since +low-amplitude oscillations produced by resizing at object boundaries are +amplified by gamma correction. This can also have an effect of reduced +contrast. + +## Interpolation Discussion ## +The use of certain low-pass filters and 2X upsampling in this library is +hardly debatable, because they are needed to attain a certain anti-aliasing +effect and keep ringing artifacts low. But the use of sinc function-based +interpolation filter that is 18 taps-long (may be higher, up to 36 taps in +practice) can be questioned, because even in 0th order case such +interpolation filter requires 18 multiply-add operations. Comparatively, an +optimal Hermite or cubic interpolation spline requires 8 multiply and 11 add +operations. + +One of the reasons 18-tap filter is preferred, is because due to memory +bandwidth limitations using a lower-order filter does not provide any +significant performance increase (e.g. 14-tap filter is less than 5% more +efficient overall). At the same time, in comparison to cubic spline, 18-tap +filter embeds a low-pass filter that rejects signal above 0.5\*pi (provides +additional anti-aliasing filtering), and this filter has a consistent shape at +all fractional offsets. Splines have a varying low-pass filter shape at +different fractional offsets (e.g. no low-pass filtering at 0.0 offset, +and maximal low-pass filtering at 0.5 offset). 18-tap filter also offers a +superior stop-band attenuation which almost guarantees absence of artifacts if +the image is considerably sharpened afterwards. + +## Why 2X upsizing in AVIR? ## +Classic approaches to image resizing do not perform an additional 2X upsizing. +So, why such upsizing is needed at all in AVIR? Indeed, image resizing can be +implemented using a single interpolation filter which is applied to the source +image directly. However, such approach has limitations: + +First of all, speaking about non-2X-upsized resizing, during upsizing the +interpolation filter has to be tuned to a frequency close to pi (Nyquist) in +order to reduce high-frequency smoothing: this reduces the space left for +filter optimization. Beside that, during downsizing, a filter that performs +well and predictable when tuned to frequencies close to the Nyquist frequency, +may become distorted in its spectral shape when it is tuned to lower +frequencies. That is why it is usually a good idea to have filter's stop-band +begin below Nyquist so that the transition band's shape remains stable at any +lower-frequency setting. At the same time, this requirement complicates a +further corrective filtering, because correction filter may become too steep +at the point where the stop-band begins. + +Secondly, speaking about non-2X-upsized resizing, filter has to be very short +(with a base length of 5-7 taps, further multiplied by the resizing factor) or +otherwise the ringing artifacts will be very strong: it is a general rule that +the steeper the filter is around signal frequencies being removed the higher +the ringing artifacts are. That is why it is preferred to move steep +transitions into the spectral area with a quieter signal. A short filter also +means it cannot provide a strong "beyond-Nyquist" stop-band attenuation, so an +interpolated image will look a bit edgy or not very clean due to stop-band +artifacts. + +To sum up, only additional controlled 2X upsizing provides enough spectral +space to design interpolation filter without visible ringing artifacts yet +providing a strong stop-band attenuation and stable spectral characteristics +(good at any resizing "k" factor). Moreover, 2X upsizing becomes very +important in maintaining a good resizing quality when downsizing and upsizing +by small "k" factors, in the range 0.5 to 2: resizing approaches that do not +perform 2X upsizing usually cannot design a good interpolation filter for such +factors just because there is not enough spectral space available. + +## Why Peaked Cosine in AVIR? ## +First of all, AVIR is a general solution to image resizing problem. That is +why it should not be directly compared to "spline interpolation" or "Lanczos +resampling", because the latter two are only means to design interpolation +filters, and they can be implemented in a variety of ways, even in sub-optimal +ways. Secondly, with only a minimal effort AVIR can be changed to use any +existing interpolation formula and any window function, but this is just not +needed. + +An effort was made to compare Peaked Cosine to Lanczos window function, and +here is the author's opinion. Peaked Cosine has two degrees of freedom whereas +Lanczos has one degree of freedom. While both functions can be used with +acceptable results, Peaked Cosine window function used in automatic parameter +optimization really pushes the limits of frequency response linearity, +anti-aliasing strength (stop-band attenuation) and low-ringing performance +which Lanczos cannot usually achieve. This is true at least when using a +general-purpose downhill simplex optimization method. Lanczos window has good +(but not better) characteristics in several special cases (certain "k" +factors) which makes it of limited use in a general solution such as AVIR. + +Among other window functions (Kaiser, Gaussian, Cauchy, Poisson, generalized +cosine windows) there are no better candidates as well. It looks like Peaked +Cosine function's scalability (it retains stable, almost continously-variable +spectral characteristics at any window parameter values), and its ability to +create "desirable" pass-band ripple in the frequency response near the cutoff +point contribute to its better overall quality. Somehow Peaked Cosine window +function optimization manages to converge to reasonable states in most cases +(that is why AVIR library comes with a set of equally robust, but distinctive +parameter sets) whereas all other window functions tend to produce +unpredictable optimization results. + +The only disadvantage of Peaked Cosine window function is that usable filters +windowed by this function tend to be longer than "usual" (with Kaiser window +being the "golden standard" for filter length per decibel of stop-band +attenuation). This is a price that should be paid for stable spectral +characteristics. + +## LANCIR ## + +As a part of AVIR library, the `CLancIR` class is also offered which is an +optimal implementation of *Lanczos* image resizing filter. This class has a +similar programmatic interface to AVIR, but it is not thread-safe: each +executing thread should have its own `CLancIR` object. This class was designed +for cases of batch processing of same-sized frames like in video encoding. + +LANCIR offers up to 200% faster image resizing in comparison to AVIR. The +quality difference is, however, debatable. Note that while LANCIR can take +8- and 16-bit and float image buffers, its precision is limited to 8-bit +resizing. + +LANCIR should be seen as a bonus and as some kind of quality comparison. +LANCIR uses Lanczos filter "a" parameter equal to 3 which is similar to AVIR's +default setting. + +## Change log ## +Version 2.4: + +* Removed outdated `_mm_reset()` function calls from the SIMD code. +* Changed `float4 round()` to use SSE2 rounding features, avoiding use of +64-bit registers. + +Version 2.3: + +* Implemented CLancIR image resizing algorithm. +* Fixed a minor image offset on image upsizing. + +Version 2.2: + +* Released AVIR under a permissive MIT license agreement. + +Version 2.1: + +* Fixed error-diffusion dither problems introduced in the previous version. +* Added the `-1` switch to the `imageresize` to enable 1-bit output for +dither's quality evaluation (use together with the `-d` switch). +* Added the `--algparams=` switch to the `imageresize` to control resizing +quality (replaces the `--low-ring` switch). +* Added `avir :: CImageResizerParamsULR` parameter set for lowest-ringing +performance possible (not considerably different to +`avir :: CImageResizerParamsLR`, but a bit lower ringing). + +Version 2.0: + +* Minor inner loop optimizations. +* Lifted the supported image size constraint by switching buffer addressing to +`size_t` from `int`, now image size is limited by the available system memory. +* Added several useful switches to the `imageresize` utility. +* Now `imageresize` does not apply gamma-correction by default. +* Fixed scaling of bit depth-reduction operation. +* Improved error-diffusion dither's signal-to-noise ratio. +* Compiled binaries with AVX2 instruction set (SSE4 for macOS). + +## Users ## +This library is used by: + + * [Contaware.com](http://www.contaware.com/) + +Please drop me a note at aleksey.vaneev@gmail.com and I will include a link to +your software product to the list of users. This list is important at +maintaining confidence in this library among the interested parties. diff --git a/third_party/avir/avir.h b/third_party/avir/avir.h new file mode 100644 index 00000000..5396da35 --- /dev/null +++ b/third_party/avir/avir.h @@ -0,0 +1,17065 @@ +/* clang-format off */ +//$ nobt +//$ nocpp + +/** + * @file avir.h + * + * @brief The "main" inclusion file with all required classes and functions. + * + * This is the "main" inclusion file for the "AVIR" image resizer. This + * inclusion file contains implementation of the AVIR image resizing algorithm + * in its entirety. Also includes several classes and functions that can be + * useful elsewhere. + * + * AVIR Copyright (c) 2015-2019 Aleksey Vaneev + * + * @mainpage + * + * @section intro_sec Introduction + * + * Description is available at https://github.com/avaneev/avir + * + * AVIR is devoted to women. Your digital photos can look good at any size! + * + * @section license License + * + * AVIR License Agreement + * + * The MIT License (MIT) + * + * Copyright (c) 2015-2019 Aleksey Vaneev + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Please credit the author of this library in your documentation in the + * following way: "AVIR image resizing algorithm designed by Aleksey Vaneev" + * + * @version 2.4 + */ + +#ifndef AVIR_CIMAGERESIZER_INCLUDED +#define AVIR_CIMAGERESIZER_INCLUDED + +#include "third_party/avir/notice.h" +#include "libc/bits/xmmintrin.h" +#include "libc/str/str.h" +#include "libc/mem/mem.h" +#include "libc/bits/bits.h" +#include "libc/math.h" + +namespace avir { + +/** + * The macro defines AVIR version string. + */ + +#define AVIR_VERSION "2.4" + +/** + * The macro equals to "pi" constant, fills 53-bit floating point mantissa. + * Undefined at the end of file. + */ + +#define AVIR_PI 3.1415926535897932 + +/** + * The macro equals to "pi divided by 2" constant, fills 53-bit floating + * point mantissa. Undefined at the end of file. + */ + +#define AVIR_PId2 1.5707963267948966 + +/** + * Rounding function, based on the (int) typecast. Biased result. Not suitable + * for numbers >= 2^31. + * + * @param d Value to round. + * @return Rounded value. Some bias may be introduced. + */ + +template +inline T round(const T d) { + return (d < 0.0 ? -(T)(int)((T)0.5 - d) : (T)(int)(d + (T)0.5)); +} + +/** + * Template function "clamps" (clips) the specified value so that it is not + * lesser than "minv", and not greater than "maxv". + * + * @param Value Value to clamp. + * @param minv Minimal allowed value. + * @param maxv Maximal allowed value. + * @return The clamped value. + */ + +template +inline T clamp(const T& Value, const T minv, const T maxv) { + if (Value < minv) { + return (minv); + } else if (Value > maxv) { + return (maxv); + } else { + return (Value); + } +} + +/** + * Power 2.4 approximation function, designed for sRGB gamma correction. + * + * @param x Argument, in the range 0.09 to 1. + * @return Value raised into power 2.4, approximate. + */ + +template +inline T pow24_sRGB(const T x) { + const double x2 = x * x; + const double x3 = x2 * x; + const double x4 = x2 * x2; + + return ((T)(0.0985766365536824 + 0.839474952656502 * x2 + + 0.363287814061725 * x3 - + 0.0125559718896615 / (0.12758338921578 + 0.290283465468235 * x) - + 0.231757513261358 * x - 0.0395365717969074 * x4)); +} + +/** + * Power 1/2.4 approximation function, designed for sRGB gamma correction. + * + * @param x Argument, in the range 0.003 to 1. + * @return Value raised into power 1/2.4, approximate. + */ + +template +inline T pow24i_sRGB(const T x) { + const double sx = sqrt(x); + const double ssx = sqrt(sx); + const double sssx = sqrt(ssx); + + return ((T)(0.000213364515060263 + 0.0149409239419218 * x + + 0.433973412731747 * sx + + ssx * (0.659628181609715 * sssx - 0.0380957908841466 - + 0.0706476137208521 * sx))); +} + +/** + * Function approximately linearizes the sRGB gamma value. + * + * @param s sRGB gamma value, in the range 0 to 1. + * @return Linearized sRGB gamma value, approximated. + */ + +template +inline T convertSRGB2Lin(const T s) { + const T a = (T)0.055; + + if (s <= (T)0.04045) { + return (s / (T)12.92); + } + + return (pow24_sRGB((s + a) / ((T)1 + a))); +} + +/** + * Function approximately de-linearizes the linear gamma value. + * + * @param s Linear gamma value, in the range 0 to 1. + * @return sRGB gamma value, approximated. + */ + +template +inline T convertLin2SRGB(const T s) { + const T a = (T)0.055; + + if (s <= (T)0.0031308) { + return ((T)12.92 * s); + } + + return (((T)1 + a) * pow24i_sRGB(s) - a); +} + +/** + * Function converts (via typecast) specified array of type T1 values of + * length l into array of type T2 values. If T1 is the same as T2, copy + * operation is performed. When copying data at overlapping address spaces, + * "op" should be lower than "ip". + * + * @param ip Input buffer. + * @param[out] op Output buffer. + * @param l The number of elements to copy. + * @param ip Input buffer pointer increment. + * @param op Output buffer pointer increment. + */ + +template +inline void copyArray(const T1* ip, T2* op, int l, const int ipinc = 1, + const int opinc = 1) { + while (l > 0) { + *op = (T2)*ip; + op += opinc; + ip += ipinc; + l--; + } +} + +/** + * Function adds values located in array "ip" to array "op". + * + * @param ip Input buffer. + * @param[out] op Output buffer. + * @param l The number of elements to add. + * @param ip Input buffer pointer increment. + * @param op Output buffer pointer increment. + */ + +template +inline void addArray(const T1* ip, T2* op, int l, const int ipinc = 1, + const int opinc = 1) { + while (l > 0) { + *op += *ip; + op += opinc; + ip += ipinc; + l--; + } +} + +/** + * Function that replicates a set of adjacent elements several times in a row. + * This operation is usually used to replicate pixels at the start or end of + * image's scanline. + * + * @param ip Source array. + * @param ipl Source array length (usually 1..4, but can be any number). + * @param[out] op Destination buffer. + * @param l Number of times the source array should be replicated (the + * destination buffer should be able to hold ipl * l number of elements). + * @param opinc Destination buffer position increment after replicating the + * source array. This value should be equal to at least ipl. + */ + +template +inline void replicateArray(const T1* const ip, const int ipl, T2* op, int l, + const int opinc) { + if (ipl == 1) { + while (l > 0) { + op[0] = ip[0]; + op += opinc; + l--; + } + } else if (ipl == 4) { + while (l > 0) { + op[0] = ip[0]; + op[1] = ip[1]; + op[2] = ip[2]; + op[3] = ip[3]; + op += opinc; + l--; + } + } else if (ipl == 3) { + while (l > 0) { + op[0] = ip[0]; + op[1] = ip[1]; + op[2] = ip[2]; + op += opinc; + l--; + } + } else if (ipl == 2) { + while (l > 0) { + op[0] = ip[0]; + op[1] = ip[1]; + op += opinc; + l--; + } + } else { + while (l > 0) { + int i; + + for (i = 0; i < ipl; i++) { + op[i] = ip[i]; + } + + op += opinc; + l--; + } + } +} + +/** + * Function calculates frequency response of the specified FIR filter at the + * specified circular frequency. Phase can be calculated as atan2( im, re ). + * Function uses computationally-efficient oscillators instead of "cos" and + * "sin" functions. + * + * @param flt FIR filter's coefficients. + * @param fltlen Number of coefficients (taps) in the filter. + * @param th Circular frequency [0; pi]. + * @param[out] re0 Resulting real part of the complex frequency response. + * @param[out] im0 Resulting imaginary part of the complex frequency response. + * @param fltlat Filter's latency in samples (taps). + */ + +template +inline void calcFIRFilterResponse(const T* flt, int fltlen, const double th, + double& re0, double& im0, + const int fltlat = 0) { + const double sincr = 2.0 * cos(th); + double cvalue1; + double svalue1; + + if (fltlat == 0) { + cvalue1 = 1.0; + svalue1 = 0.0; + } else { + cvalue1 = cos(-fltlat * th); + svalue1 = sin(-fltlat * th); + } + + double cvalue2 = cos(-(fltlat + 1) * th); + double svalue2 = sin(-(fltlat + 1) * th); + + double re = 0.0; + double im = 0.0; + + while (fltlen > 0) { + re += cvalue1 * flt[0]; + im += svalue1 * flt[0]; + flt++; + fltlen--; + + double tmp = cvalue1; + cvalue1 = sincr * cvalue1 - cvalue2; + cvalue2 = tmp; + + tmp = svalue1; + svalue1 = sincr * svalue1 - svalue2; + svalue2 = tmp; + } + + re0 = re; + im0 = im; +} + +/** + * Function normalizes FIR filter so that its frequency response at DC is + * equal to DCGain. + * + * @param[in,out] p Filter coefficients. + * @param l Filter length. + * @param DCGain Filter's gain at DC. + * @param pstep "p" array step. + */ + +template +inline void normalizeFIRFilter(T* const p, const int l, const double DCGain, + const int pstep = 1) { + double s = 0.0; + T* pp = p; + int i = l; + + while (i > 0) { + s += *pp; + pp += pstep; + i--; + } + + s = DCGain / s; + pp = p; + i = l; + + while (i > 0) { + *pp = (T)(*pp * s); + pp += pstep; + i--; + } +} + +/** + * @brief Memory buffer class for element array storage, with capacity + * tracking. + * + * Allows easier handling of memory blocks allocation and automatic + * deallocation for arrays (buffers) consisting of elements of specified + * class. Tracks buffer's capacity in "int" variable; unsuitable for + * allocation of very large memory blocks (with more than 2 billion elements). + * + * This class manages memory space only - it does not perform element class + * construction (initialization) operations. Buffer's required memory address + * alignment specification is supported. + * + * Uses standard library to allocate and deallocate memory. + * + * @tparam T Buffer element's type. + * @tparam capint Buffer capacity's type to use. Use size_t for large buffers. + */ + +template +class CBuffer { + public: + CBuffer() : Data(NULL), DataAligned(NULL), Capacity(0), Alignment(0) {} + + /** + * Constructor creates the buffer with the specified capacity. + * + * @param aCapacity Buffer's capacity. + * @param aAlignment Buffer's required memory address alignment. 0 - use + * stdlib's default alignment. + */ + + CBuffer(const capint aCapacity, const int aAlignment = 0) { + allocinit(aCapacity, aAlignment); + } + + CBuffer(const CBuffer& Source) { + allocinit(Source.Capacity, Source.Alignment); + memcpy(DataAligned, Source.DataAligned, Capacity * sizeof(T)); + } + + ~CBuffer() { freeData(); } + + CBuffer& operator=(const CBuffer& Source) { + alloc(Source.Capacity, Source.Alignment); + memcpy(DataAligned, Source.DataAligned, Capacity * sizeof(T)); + return (*this); + } + + /** + * Function allocates memory so that the specified number of elements + * can be stored in *this buffer object. + * + * @param aCapacity Storage for this number of elements to allocate. + * @param aAlignment Buffer's required memory address alignment, + * power-of-2 values only. 0 - use stdlib's default alignment. + */ + + void alloc(const capint aCapacity, const int aAlignment = 0) { + freeData(); + allocinit(aCapacity, aAlignment); + } + + /** + * Function deallocates any previously allocated buffer. + */ + + void free() { + freeData(); + Data = NULL; + DataAligned = NULL; + Capacity = 0; + Alignment = 0; + } + + /** + * @return The capacity of the element buffer. + */ + + capint getCapacity() const { return (Capacity); } + + /** + * Function "forces" *this buffer to have an arbitary capacity. Calling + * this function invalidates all further operations except deleting *this + * object. This function should not be usually used at all. Function can + * be used to "model" certain buffer capacity without calling a costly + * memory allocation function. + * + * @param NewCapacity A new "forced" capacity. + */ + + void forceCapacity(const capint NewCapacity) { Capacity = NewCapacity; } + + /** + * Function reallocates *this buffer to a larger size so that it will be + * able to hold the specified number of elements. Downsizing is not + * performed. Alignment is not changed. + * + * @param NewCapacity New (increased) capacity. + * @param DoDataCopy "True" if data in the buffer should be retained. + */ + + void increaseCapacity(const capint NewCapacity, + const bool DoDataCopy = true) { + if (NewCapacity < Capacity) { + return; + } + + if (DoDataCopy) { + const capint PrevCapacity = Capacity; + T* const PrevData = Data; + T* const PrevDataAligned = DataAligned; + + allocinit(NewCapacity, Alignment); + memcpy(DataAligned, PrevDataAligned, PrevCapacity * sizeof(T)); + + ::free(PrevData); + } else { + ::free(Data); + allocinit(NewCapacity, Alignment); + } + } + + /** + * Function "truncates" (reduces) capacity of the buffer without + * reallocating it. Alignment is not changed. + * + * @param NewCapacity New required capacity. + */ + + void truncateCapacity(const capint NewCapacity) { + if (NewCapacity >= Capacity) { + return; + } + + Capacity = NewCapacity; + } + + /** + * Function increases capacity so that the specified number of + * elements can be stored. This function increases the previous capacity + * value by third the current capacity value until space for the required + * number of elements is available. Alignment is not changed. + * + * @param ReqCapacity Required capacity. + */ + + void updateCapacity(const capint ReqCapacity) { + if (ReqCapacity <= Capacity) { + return; + } + + capint NewCapacity = Capacity; + + while (NewCapacity < ReqCapacity) { + NewCapacity += NewCapacity / 3 + 1; + } + + increaseCapacity(NewCapacity); + } + + operator T*() const { return (DataAligned); } + + private: + T* Data; ///< Element buffer pointer. + ///< + T* DataAligned; ///< Memory address-aligned element buffer pointer. + ///< + capint Capacity; ///< Element buffer capacity. + ///< + int Alignment; ///< Memory address alignment in use. 0 - use stdlib's + ///< default alignment. + ///< + + /** + * Internal element buffer allocation function used during object + * construction. + * + * @param aCapacity Storage for this number of elements to allocate. + * @param aAlignment Buffer's required memory address alignment. 0 - use + * stdlib's default alignment. + */ + + void allocinit(const capint aCapacity, const int aAlignment) { + if (aAlignment == 0) { + Data = (T*)::malloc(aCapacity * sizeof(T)); + DataAligned = Data; + Alignment = 0; + } else { + Data = (T*)::malloc(aCapacity * sizeof(T) + aAlignment); + DataAligned = alignptr(Data, aAlignment); + Alignment = aAlignment; + } + + Capacity = aCapacity; + } + + /** + * Function frees a previously allocated Data buffer. + */ + + void freeData() { ::free(Data); } + + /** + * Function modifies the specified pointer so that it becomes memory + * address-aligned. + * + * @param ptr Pointer to align. + * @param align Alignment in bytes to apply. + * @return Pointer aligned to align bytes. Works with power-of-2 + * alignments only. If no alignment is necessary, "align" bytes will be + * added to the pointer value. + */ + + template + inline Tp alignptr(const Tp ptr, const uintptr_t align) { + return ((Tp)((uintptr_t)ptr + align - ((uintptr_t)ptr & (align - 1)))); + } +}; + +/** + * Function optimizes the length of the symmetric-odd FIR filter by removing + * left- and rightmost elements that are below specific threshold. + * + * Synthetic test shows that filter gets optimized in 2..3% of cases and in + * each such case optimization reduces filter length by 6..8%. Optimization, + * however, may skew the results of algorithm modeling and complexity + * calculation leading to a choice of a less optimal algorithm. + * + * @param[in,out] Flt Buffer that contains filter being optimized. + * @param[in,out] FltLatency Variable that holds the current latency of the + * filter. May be adjusted on function return. + * @param Threshold Threshold level. + */ + +template +inline void optimizeFIRFilter(CBuffer& Flt, int& FltLatency, + T const Threshold = (T)0.00001) { + int i; + + // Optimize length. + + for (i = 0; i <= FltLatency; i++) { + if (fabs(Flt[i]) >= Threshold || i == FltLatency) { + if (i > 0) { + const int NewCapacity = Flt.getCapacity() - i * 2; + copyArray(&Flt[i], &Flt[0], NewCapacity); + Flt.truncateCapacity(NewCapacity); + FltLatency -= i; + } + + break; + } + } +} + +/** + * @brief Array of structured objects. + * + * Implements allocation of a linear array of objects of class T (which are + * initialized), addressable via operator[]. Each object is created via the + * "operator new". New object insertions are quick since implementation uses + * prior space allocation (capacity), thus not requiring frequent memory block + * reallocations. + * + * @tparam T Array element's type. + */ + +template +class CStructArray { + public: + CStructArray() : ItemCount(0) {} + + CStructArray(const CStructArray& Source) + : ItemCount(0), Items(Source.getItemCount()) { + while (ItemCount < Source.getItemCount()) { + Items[ItemCount] = new T(Source[ItemCount]); + ItemCount++; + } + } + + ~CStructArray() { clear(); } + + CStructArray& operator=(const CStructArray& Source) { + clear(); + + const int NewCount = Source.ItemCount; + Items.updateCapacity(NewCount); + + while (ItemCount < NewCount) { + Items[ItemCount] = new T(Source[ItemCount]); + ItemCount++; + } + + return (*this); + } + + T& operator[](const int Index) { return (*Items[Index]); } + + const T& operator[](const int Index) const { return (*Items[Index]); } + + /** + * Function creates a new object of type T with the default constructor + * and adds this object to the array. + * + * @return Reference to a newly added object. + */ + + T& add() { + if (ItemCount == Items.getCapacity()) { + Items.increaseCapacity(ItemCount * 3 / 2 + 1); + } + + Items[ItemCount] = new T(); + ItemCount++; + + return ((*this)[ItemCount - 1]); + } + + /** + * Function changes number of allocated items. New items are created with + * the default constructor. If NewCount is below the current item count, + * items that are above NewCount range will be destructed. + * + * @param NewCount New requested item count. + */ + + void setItemCount(const int NewCount) { + if (NewCount > ItemCount) { + Items.increaseCapacity(NewCount); + + while (ItemCount < NewCount) { + Items[ItemCount] = new T(); + ItemCount++; + } + } else { + while (ItemCount > NewCount) { + ItemCount--; + delete Items[ItemCount]; + } + } + } + + /** + * Function erases all items of *this array. + */ + + void clear() { + while (ItemCount > 0) { + ItemCount--; + delete Items[ItemCount]; + } + } + + /** + * @return The number of allocated items. + */ + + int getItemCount() const { return (ItemCount); } + + private: + int ItemCount; ///< The number of items available in the array. + ///< + CBuffer Items; ///< Element buffer. + ///< +}; + +/** + * @brief Sine signal generator class. + * + * Class implements sine signal generator without biasing, with + * constructor-based initalization only. This generator uses oscillator + * instead of "sin" function. + */ + +class CSineGen { + public: + /** + * Constructor initializes *this sine signal generator. + * + * @param si Sine function increment, in radians. + * @param ph Starting phase, in radians. Add 0.5 * AVIR_PI for cosine + * function. + */ + + CSineGen(const double si, const double ph) + : svalue1(sin(ph)), svalue2(sin(ph - si)), sincr(2.0 * cos(si)) {} + + /** + * @return The next value of the sine function, without biasing. + */ + + double generate() { + const double res = svalue1; + + svalue1 = sincr * res - svalue2; + svalue2 = res; + + return (res); + } + + private: + double svalue1; ///< Current sine value. + ///< + double svalue2; ///< Previous sine value. + ///< + double sincr; ///< Sine value increment. + ///< +}; + +/** + * @brief Peaked Cosine window function generator class. + * + * Class implements Peaked Cosine window function generator. Generates the + * right-handed half of the window function. The Alpha parameter of this + * window function offers the control of the balance between the early and + * later taps of the filter. E.g. at Alpha=1 both early and later taps are + * attenuated, but at Alpha=4 mostly later taps are attenuated. This offers a + * great control over ringing artifacts produced by a low-pass filter in image + * processing, without compromising achieved image sharpness. + */ + +class CDSPWindowGenPeakedCosine { + public: + /** + * Constructor initializes *this window function generator. + * + * @param aAlpha Alpha parameter, affects the peak shape (peak + * augmentation) of the window function. Should be >= 1.0. + * @param aLen2 Half filter's length (non-truncated). + */ + + CDSPWindowGenPeakedCosine(const double aAlpha, const double aLen2) + : Alpha(aAlpha), + Len2(aLen2), + wn(0), + w1(AVIR_PId2 / Len2, AVIR_PI * 0.5) {} + + /** + * @return The next Peaked Cosine window function coefficient. + */ + + double generate() { + const double h = pow(wn / Len2, Alpha); + wn++; + + return (w1.generate() * (1.0 - h)); + } + + private: + double Alpha; ///< Alpha parameter, affects the peak shape of window. + ///< + double Len2; ///< Half length of the window function. + ///< + int wn; ///< Window function integer position. 0 - center of the + ///< window function. + ///< + CSineGen w1; ///< Sine-wave generator. + ///< +}; + +/** + * @brief FIR filter-based equalizer generator. + * + * Class implements an object used to generate symmetric-odd FIR filters with + * the specified frequency response (aka paragraphic equalizer). The + * calculated filter is windowed by the Peaked Cosine window function. + * + * In image processing, due to short length of filters being used (6-8 taps) + * the resulting frequency response of the filter is approximate and may be + * mathematically imperfect, but still adequate to the visual requirements. + * + * On a side note, this equalizer generator can be successfully used for audio + * signal equalization as well: for example, it is used in almost the same + * form in Voxengo Marvel GEQ equalizer plug-in. + * + * Filter generation is based on decomposition of frequency range into + * spectral bands, with each band represented by linear and ramp "kernels". + * When the filter is built, these kernels are combined together with + * different weights that approximate the required frequency response. + */ + +class CDSPFIREQ { + public: + /** + * Function initializes *this object with the required parameters. The + * gain of frequencies beyond the MinFreq..MaxFreq range are controlled by + * the first and the last band's gain. + * + * @param SampleRate Processing sample rate (use 2 for image processing). + * @param aFilterLength Required filter length in samples (taps). The + * actual filter length is truncated to an integer value. + * @param aBandCount Number of band crossover points required to control, + * including bands at MinFreq and MaxFreq. + * @param MinFreq Minimal frequency that should be controlled. + * @param MaxFreq Maximal frequency that should be controlled. + * @param IsLogBands "True" if the bands should be spaced logarithmically. + * @param WFAlpha Peaked Cosine window function's Alpha parameter. + */ + + void init(const double SampleRate, const double aFilterLength, + const int aBandCount, const double MinFreq, const double MaxFreq, + const bool IsLogBands, const double WFAlpha) { + FilterLength = aFilterLength; + BandCount = aBandCount; + + CenterFreqs.alloc(BandCount); + + z = (int)ceil(FilterLength * 0.5); + zi = z + (z & 1); + z2 = z * 2; + + CBuffer oscbuf(z2); + initOscBuf(oscbuf); + + CBuffer winbuf(z); + initWinBuf(winbuf, WFAlpha); + + UseFirstVirtBand = (MinFreq > 0.0); + const int k = zi * (BandCount + (UseFirstVirtBand ? 1 : 0)); + Kernels1.alloc(k); + Kernels2.alloc(k); + + double m; // Frequency step multiplier. + double mo; // Frequency step offset (addition). + + if (IsLogBands) { + m = exp(log(MaxFreq / MinFreq) / (BandCount - 1)); + mo = 0.0; + } else { + m = 1.0; + mo = (MaxFreq - MinFreq) / (BandCount - 1); + } + + double f = MinFreq; + double x1 = 0.0; + double x2; + int si; + + if (UseFirstVirtBand) { + si = 0; + } else { + si = 1; + CenterFreqs[0] = 0.0; + f = f * m + mo; + } + + double* kernbuf1 = &Kernels1[0]; + double* kernbuf2 = &Kernels2[0]; + int i; + + for (i = si; i < BandCount; i++) { + x2 = f * 2.0 / SampleRate; + CenterFreqs[i] = x2; + + fillBandKernel(x1, x2, kernbuf1, kernbuf2, oscbuf, winbuf); + + kernbuf1 += zi; + kernbuf2 += zi; + x1 = x2; + f = f * m + mo; + } + + if (x1 < 1.0) { + UseLastVirtBand = true; + fillBandKernel(x1, 1.0, kernbuf1, kernbuf2, oscbuf, winbuf); + } else { + UseLastVirtBand = false; + } + } + + /** + * @return Filter's length, in samples (taps). + */ + + int getFilterLength() const { return (z2 - 1); } + + /** + * @return Filter's latency (group delay), in samples (taps). + */ + + int getFilterLatency() const { return (z - 1); } + + /** + * Function creates symmetric-odd FIR filter with the specified gain + * levels at band crossover points. + * + * @param BandGains Array of linear gain levels, count=BandCount specified + * in the init() function. + * @param[out] Filter Output filter buffer, length = getFilterLength(). + */ + + void buildFilter(const double* const BandGains, double* const Filter) { + const double* kernbuf1 = &Kernels1[0]; + const double* kernbuf2 = &Kernels2[0]; + double x1 = 0.0; + double y1 = BandGains[0]; + double x2; + double y2; + + int i; + int si; + + if (UseFirstVirtBand) { + si = 1; + x2 = CenterFreqs[0]; + y2 = y1; + } else { + si = 2; + x2 = CenterFreqs[1]; + y2 = BandGains[1]; + } + + copyBandKernel(Filter, kernbuf1, kernbuf2, y1 - y2, x1 * y2 - x2 * y1); + + kernbuf1 += zi; + kernbuf2 += zi; + x1 = x2; + y1 = y2; + + for (i = si; i < BandCount; i++) { + x2 = CenterFreqs[i]; + y2 = BandGains[i]; + + addBandKernel(Filter, kernbuf1, kernbuf2, y1 - y2, x1 * y2 - x2 * y1); + + kernbuf1 += zi; + kernbuf2 += zi; + x1 = x2; + y1 = y2; + } + + if (UseLastVirtBand) { + addBandKernel(Filter, kernbuf1, kernbuf2, y1 - y2, x1 * y2 - y1); + } + + for (i = 0; i < z - 1; i++) { + Filter[z + i] = Filter[z - 2 - i]; + } + } + + /** + * Function calculates filter's length (in samples) and latency depending + * on the required non-truncated filter length. + * + * @param aFilterLength Required filter length in samples (non-truncated). + * @param[out] Latency Resulting latency (group delay) of the filter, + * in samples (taps). + * @return Filter length in samples (taps). + */ + + static int calcFilterLength(const double aFilterLength, int& Latency) { + const int l = (int)ceil(aFilterLength * 0.5); + Latency = l - 1; + + return (l * 2 - 1); + } + + private: + double FilterLength; ///< Length of filter. + ///< + int z; ///< Equals (int) ceil( FilterLength * 0.5 ). + ///< + int zi; ///< Equals "z" if z is even, or z + 1 if z is odd. Used as a + ///< Kernels1 and Kernels2 size multiplier and kernel buffer + ///< increment to make sure each kernel buffer is 16-byte aligned. + ///< + int z2; ///< Equals z * 2. + ///< + int BandCount; ///< Number of controllable bands. + ///< + CBuffer CenterFreqs; ///< Center frequencies for all bands, + ///< normalized to 0.0-1.0 range. + ///< + CBuffer Kernels1; ///< Half-length kernel buffers for each + ///< spectral band (linear part). + ///< + CBuffer Kernels2; ///< Half-length kernel buffers for each + ///< spectral band (ramp part). + ///< + bool UseFirstVirtBand; ///< "True" if the first virtual band + ///< (between 0.0 and MinFreq) should be used. The + ///< first virtual band won't be used if MinFreq + ///< equals 0.0. + ///< + bool UseLastVirtBand; ///< "True" if the last virtual band (between + ///< MaxFreq and SampleRate * 0.5) should be used. The + ///< last virtual band won't be used if MaxFreq * 2.0 + ///< equals SampleRate. + ///< + + /** + * Function initializes the "oscbuf" used in the fillBandKernel() + * function. + * + * @param oscbuf Oscillator buffer, length = z * 2. + */ + + void initOscBuf(double* oscbuf) const { + int i = z; + + while (i > 0) { + oscbuf[0] = 0.0; + oscbuf[1] = 1.0; + oscbuf += 2; + i--; + } + } + + /** + * Function initializes window function buffer. This function generates + * Peaked Cosine window function. + * + * @param winbuf Windowing buffer. + * @param Alpha Peaked Cosine alpha parameter. + */ + + void initWinBuf(double* winbuf, const double Alpha) const { + CDSPWindowGenPeakedCosine wf(Alpha, FilterLength * 0.5); + int i; + + for (i = 1; i <= z; i++) { + winbuf[z - i] = wf.generate(); + } + } + + /** + * Function fills first half of symmetric-odd FIR kernel for the band. + * This function should be called successively for adjacent bands. + * Previous band's x2 should be equal to current band's x1. A band kernel + * consists of 2 elements: linear kernel and ramp kernel. + * + * @param x1 Band's left corner frequency (0..1). + * @param x2 Band's right corner frequency (0..1). + * @param kernbuf1 Band kernel buffer 1 (linear part), length = z. + * @param kernbuf2 Band kernel buffer 2 (ramp part), length = z. + * @param oscbuf Oscillation buffer. Before the first call of the + * fillBandKernel() should be initialized with the call of the + * initOscBuf() function. + * @param winbuf Buffer that contains windowing function. + */ + + void fillBandKernel(const double x1, const double x2, double* kernbuf1, + double* kernbuf2, double* oscbuf, + const double* const winbuf) { + const double s2_incr = AVIR_PI * x2; + const double s2_coeff = 2.0 * cos(s2_incr); + + double s2_value1 = sin(s2_incr * (-z + 1)); + double c2_value1 = sin(s2_incr * (-z + 1) + AVIR_PI * 0.5); + oscbuf[0] = sin(s2_incr * -z); + oscbuf[1] = sin(s2_incr * -z + AVIR_PI * 0.5); + + int ks; + + for (ks = 1; ks < z; ks++) { + const int ks2 = ks * 2; + const double s1_value1 = oscbuf[ks2]; + const double c1_value1 = oscbuf[ks2 + 1]; + oscbuf[ks2] = s2_value1; + oscbuf[ks2 + 1] = c2_value1; + + const double x = AVIR_PI * (ks - z); + const double v0 = winbuf[ks - 1] / ((x1 - x2) * x); + + kernbuf1[ks - 1] = + (x2 * s2_value1 - x1 * s1_value1 + (c2_value1 - c1_value1) / x) * v0; + + kernbuf2[ks - 1] = (s2_value1 - s1_value1) * v0; + + s2_value1 = s2_coeff * s2_value1 - oscbuf[ks2 - 2]; + c2_value1 = s2_coeff * c2_value1 - oscbuf[ks2 - 1]; + } + + kernbuf1[z - 1] = (x2 * x2 - x1 * x1) / (x1 - x2) * 0.5; + kernbuf2[z - 1] = -1.0; + } + + /** + * Function copies band kernel's elements to the output buffer. + * + * @param outbuf Output buffer. + * @param kernbuf1 Kernel buffer 1 (linear part). + * @param kernbuf2 Kernel buffer 2 (ramp part). + * @param c Multiplier for linear kernel element. + * @param d Multiplier for ramp kernel element. + */ + + void copyBandKernel(double* outbuf, const double* const kernbuf1, + const double* const kernbuf2, const double c, + const double d) const { + int ks; + + for (ks = 0; ks < z; ks++) { + outbuf[ks] = c * kernbuf1[ks] + d * kernbuf2[ks]; + } + } + + /** + * Function adds band kernel's elements to the output buffer. + * + * @param outbuf Output buffer. + * @param kernbuf1 Kernel buffer 1 (linear part). + * @param kernbuf2 Kernel buffer 2 (ramp part). + * @param c Multiplier for linear kernel element. + * @param d Multiplier for ramp kernel element. + */ + + void addBandKernel(double* outbuf, const double* const kernbuf1, + const double* const kernbuf2, const double c, + const double d) const { + int ks; + + for (ks = 0; ks < z; ks++) { + outbuf[ks] += c * kernbuf1[ks] + d * kernbuf2[ks]; + } + } +}; + +/** + * @brief Low-pass filter windowed by Peaked Cosine window function. + * + * This class implements calculation of linear-phase symmetric-odd FIR + * low-pass filter windowed by the Peaked Cosine window function, for image + * processing applications. + */ + +class CDSPPeakedCosineLPF { + public: + int fl2; ///< Half filter's length, excluding the peak value. This value + ///< can be also used as filter's latency in samples (taps). + ///< + int FilterLen; ///< Filter's length in samples (taps). + ///< + + /** + * Constructor initalizes *this object. + * + * @param aLen2 Half-length (non-truncated) of low-pass filter, in samples + * (taps). + * @param aFreq2 Low-pass filter's corner frequency [0; pi]. + * @param aAlpha Peaked Cosine window function Alpha parameter. + */ + + CDSPPeakedCosineLPF(const double aLen2, const double aFreq2, + const double aAlpha) + : fl2((int)ceil(aLen2) - 1), + FilterLen(fl2 + fl2 + 1), + Len2(aLen2), + Freq2(aFreq2), + Alpha(aAlpha) {} + + /** + * Function generates a linear-phase low-pass filter windowed by Peaked + * Cosine window function. + * + * @param[out] op Output buffer, length = FilterLen (fl2 * 2 + 1). + * @param DCGain Required gain at DC. The resulting filter will be + * normalized to achieve this DC gain. + */ + + template + void generateLPF(T* op, const double DCGain) { + CDSPWindowGenPeakedCosine wf(Alpha, Len2); + CSineGen f2(Freq2, 0.0); + + op += fl2; + T* op2 = op; + f2.generate(); + int t = 1; + + *op = (T)(Freq2 * wf.generate() / AVIR_PI); + double s = *op; + + while (t <= fl2) { + const double v = f2.generate() * wf.generate() / t / AVIR_PI; + op++; + op2--; + *op = (T)v; + *op2 = (T)v; + s += *op + *op2; + t++; + } + + t = FilterLen; + s = DCGain / s; + + while (t > 0) { + *op2 = (T)(*op2 * s); + op2++; + t--; + } + } + + private: + double Len2; ///< Half-length (non-truncated) of low-pass filter, in + ///< samples (taps). + ///< + double Freq2; ///< Low-pass filter's corner frequency. + ///< + double Alpha; ///< Peaked Cosine window function Alpha parameter. + ///< +}; + +/** + * @brief Buffer class for parametrized low-pass filter. + * + * This class extends the CBuffer< double > class by adding several variables + * that define a symmetric-odd FIR low-pass filter windowed by Peaked Cosine + * window function. This class can be used to compare filters without + * comparing their buffer contents. + */ + +class CFltBuffer : public CBuffer { + public: + double Len2; ///< Half-length (non-truncated) of low-pass filters, in + ///< samples (taps). + ///< + double Freq; ///< Low-pass filter's corner frequency. + ///< + double Alpha; ///< Peaked Cosine window function Alpha parameter. + ///< + double DCGain; ///< DC gain applied to the filter. + ///< + + CFltBuffer() + : CBuffer(), Len2(0.0), Freq(0.0), Alpha(0.0), DCGain(0.0) {} + + /** + * @param b2 Filter buffer to compare *this object to. + * @return Operator returns "true" if both filters have same parameters. + */ + + bool operator==(const CFltBuffer& b2) const { + return (Len2 == b2.Len2 && Freq == b2.Freq && Alpha == b2.Alpha && + DCGain == b2.DCGain); + } +}; + +/** + * @brief Sinc function-based fractional delay filter bank. + * + * Class implements storage and initialization of a bank of sinc + * function-based fractional delay filters, expressed as 1st order polynomial + * interpolation coefficients. The filters are produced from a single "long" + * windowed low-pass filter. Also supports 0th-order ("nearest neighbor") + * interpolation. + * + * This class also supports multiplication of each fractional delay filter by + * an external filter (usually a low-pass filter). + * + * @tparam fptype Specifies storage type of the filter coefficients bank. The + * filters are initially calculated using the "double" precision. + */ + +template +class CDSPFracFilterBankLin { + public: + CDSPFracFilterBankLin() : Order(-1) {} + + /** + * Copy constructor copies a limited set of parameters of the source + * filter bank. The actual filters are not copied. Such copying is used + * during filtering steps "modeling" stage. A further init() function + * call is required. + * + * @param s Source filter bank. + */ + + void copyInitParams(const CDSPFracFilterBankLin& s) { + WFLen2 = s.WFLen2; + WFFreq = s.WFFreq; + WFAlpha = s.WFAlpha; + FracCount = s.FracCount; + Order = s.Order; + Alignment = s.Alignment; + SrcFilterLen = s.SrcFilterLen; + FilterLen = s.FilterLen; + FilterSize = s.FilterSize; + IsSrcTableBuilt = false; + ExtFilter = s.ExtFilter; + TableFillFlags.alloc(s.TableFillFlags.getCapacity()); + int i; + + // Copy table fill flags, but shifted so that further initialization + // is still possible (such feature should not be used, though). + + for (i = 0; i < TableFillFlags.getCapacity(); i++) { + TableFillFlags[i] = (uint8_t)(s.TableFillFlags[i] << 2); + } + } + + /** + * Operator compares *this filter bank and another filter bank and returns + * "true" if their parameters are equal. Alignment is not taken into + * account. + * + * @param s Filter bank to compare to. + * @return "True" if compared banks have equal parameters. + */ + + bool operator==(const CDSPFracFilterBankLin& s) const { + return (Order == s.Order && WFLen2 == s.WFLen2 && WFFreq == s.WFFreq && + WFAlpha == s.WFAlpha && FracCount == s.FracCount && + ExtFilter == s.ExtFilter); + } + + /** + * Function initializes (builds) the filter bank based on the supplied + * parameters. If the supplied parameters are equal to previously defined + * parameters, function does nothing (alignment is assumed to be never + * changing between the init() function calls). + * + * @param ReqFracCount Required number of fractional delays in the filter + * bank. The minimal value is 2. + * @param ReqOrder Required order of the interpolation polynomial + * (0 or 1). + * @param BaseLen Low-pass filter's base length, in samples (taps). + * Affects the actual length of the filter and its overall steepness. + * @param Cutoff Low-pass filter's normalized cutoff frequency [0; 1]. + * @param aWFAlpha Peaked Cosine window function's Alpha parameter. + * @param aExtFilter External filter to apply to each fractional delay + * filter. + * @param aAlignment Memory alignment of the filter bank, power-of-2 + * value. 0 - use default stdlib alignment. + * @param FltLenAlign Filter's length alignment, power-of-2 value. + */ + + void init(const int ReqFracCount, const int ReqOrder, const double BaseLen, + const double Cutoff, const double aWFAlpha, + const CFltBuffer& aExtFilter, const int aAlignment = 0, + const int FltLenAlign = 1) { + double NewWFLen2 = 0.5 * BaseLen * ReqFracCount; + double NewWFFreq = AVIR_PI * Cutoff / ReqFracCount; + double NewWFAlpha = aWFAlpha; + + if (ReqOrder == Order && NewWFLen2 == WFLen2 && NewWFFreq == WFFreq && + NewWFAlpha == WFAlpha && ReqFracCount == FracCount && + aExtFilter == ExtFilter) { + IsInitRequired = false; + return; + } + + WFLen2 = NewWFLen2; + WFFreq = NewWFFreq; + WFAlpha = NewWFAlpha; + FracCount = ReqFracCount; + Order = ReqOrder; + Alignment = aAlignment; + ExtFilter = aExtFilter; + + CDSPPeakedCosineLPF p(WFLen2, WFFreq, WFAlpha); + SrcFilterLen = (p.fl2 / ReqFracCount + 1) * 2; + + const int ElementSize = ReqOrder + 1; + FilterLen = SrcFilterLen; + + if (ExtFilter.getCapacity() > 0) { + FilterLen += ExtFilter.getCapacity() - 1; + } + + FilterLen = (FilterLen + FltLenAlign - 1) & ~(FltLenAlign - 1); + FilterSize = FilterLen * ElementSize; + IsSrcTableBuilt = false; + IsInitRequired = true; + } + + /** + * @return The length of each fractional delay filter, in samples (taps). + * Always an even value. + */ + + int getFilterLen() const { return (FilterLen); } + + /** + * @return The number of fractional filters in use by *this bank. + */ + + int getFracCount() const { return (FracCount); } + + /** + * @return The order of the interpolation polynomial. + */ + + int getOrder() const { return (Order); } + + /** + * Function returns the pointer to the specified interpolation table + * filter. + * + * @param i Filter (fractional delay) index, in the range 0 to + * ReqFracCount - 1, inclusive. + * @return Pointer to filter. Higher order polynomial coefficients are + * stored after after previous order coefficients, separated by FilterLen + * elements. + */ + + const fptype* getFilter(const int i) { + if (!IsSrcTableBuilt) { + buildSrcTable(); + } + + fptype* const Res = &Table[i * FilterSize]; + + if ((TableFillFlags[i] & 2) == 0) { + createFilter(i); + TableFillFlags[i] |= 2; + + if (Order > 0) { + createFilter(i + 1); + const fptype* const Res2 = Res + FilterSize; + fptype* const op = Res + FilterLen; + int j; + + // Create higher-order interpolation coefficients (linear + // interpolation). + + for (j = 0; j < FilterLen; j++) { + op[j] = Res2[j] - Res[j]; + } + } + } + + return (Res); + } + + /** + * Function makes sure all fractional delay filters were created. + */ + + void createAllFilters() { + int i; + + for (i = 0; i < FracCount; i++) { + getFilter(i); + } + } + + /** + * Function returns an approximate initialization complexity, expressed in + * the number of multiply-add operations. This includes fractional delay + * filters calculation and multiplication by an external filter. This + * function can only be called after the init() function. + * + * @param FracUseMap Fractional delays use map, each element corresponds + * to a single fractional delay, will be compared to the internal table + * fill flags. This map should include 0 and 1 values only. + * @return The complexity of the initialization, expressed in the number + * of multiply-add operations. + */ + + int calcInitComplexity(const CBuffer& FracUseMap) const { + const int FltInitCost = 65; // Cost to initialize a single sample + // of the fractional delay filter. + const int FltUseCost = + FilterLen * Order + + SrcFilterLen * ExtFilter.getCapacity(); // Cost to use a single + // fractional delay filter. + const int ucb[2] = {0, FltUseCost}; + int ic; + int i; + + if (IsInitRequired) { + ic = FracCount * SrcFilterLen * FltInitCost; + + for (i = 0; i < FracCount; i++) { + ic += ucb[FracUseMap[i]]; + } + } else { + ic = 0; + + for (i = 0; i < FracCount; i++) { + if (FracUseMap[i] != 0) { + ic += ucb[TableFillFlags[i] == 0 ? 1 : 0]; + } + } + } + + return (ic); + } + + private: + static const int InterpPoints = 2; ///< The maximal number of points the + ///< interpolation is based on. + ///< + double WFLen2; ///< Window function's Len2 parameter. + ///< + double WFFreq; ///< Window function's Freq parameter. + ///< + double WFAlpha; ///< Window function's Alpha parameter. + ///< + int FracCount; ///< The required number of fractional delay filters. + ///< + int Order; ///< The order of the interpolation polynomial. + ///< + int Alignment; ///< The required filter table alignment. + ///< + int SrcFilterLen; ///< Length of the "source" filters. This is always an + ///< even value. + ///< + int FilterLen; ///< Specifies the number of samples (taps) each fractional + ///< delay filter has. This is always an even value, adjusted + ///< by the FltLenAlign. + ///< + int FilterSize; ///< The size of a single filter element, equals + ///< FilterLen * ElementSize. + ///< + bool IsInitRequired; ///< "True" if SrcTable filter table initialization + ///< is required. This value is available only after the + ///< call to the init() function. + ///< + CBuffer Table; ///< Interpolation table, size equals to + ///< ReqFracCount * FilterLen * ElementSize. + ///< + CBuffer + TableFillFlags; ///< Contains ReqFracCount + 1 + ///< elements. Bit 0 of every element is 1 if Table + ///< already contains the filter from SrcTable filtered + ///< by ExtFilter. Bit 1 of every element means higher + ///< order coefficients were filled for the filter. + ///< + CFltBuffer ExtFilter; ///< External filter that should be applied to every + ///< fractional delay filter. Can be empty. Half of + ///< this filter's capacity is used as latency (group + ///< delay) value of the filter. + ///< + CBuffer SrcTable; ///< Source table of delay filters, contains + ///< ReqFracCount + 1 elements. This table is used + ///< to fill the Table with the actual filters, + ///< filtered by an external filter. + ///< + bool IsSrcTableBuilt; ///< "True" if the SrcTable was built already. This + ///< variable is set to "false" in the init() function. + ///< + + /** + * Function builds source table used in the createFilter() function. + */ + + void buildSrcTable() { + IsSrcTableBuilt = true; + IsInitRequired = false; + + CDSPPeakedCosineLPF p(WFLen2, WFFreq, WFAlpha); + + const int BufLen = SrcFilterLen * FracCount + InterpPoints - 1; + const int BufOffs = InterpPoints / 2 - 1; + const int BufCenter = SrcFilterLen * FracCount / 2 + BufOffs; + + CBuffer Buf(BufLen); + memset(Buf, 0, (BufCenter - p.fl2) * sizeof(double)); + int i = BufLen - BufCenter - p.fl2 - 1; + memset(&Buf[BufLen - i], 0, i * sizeof(double)); + + p.generateLPF(&Buf[BufCenter - p.fl2], FracCount); + + SrcTable.alloc((FracCount + 1) * SrcFilterLen); + TableFillFlags.alloc(FracCount + 1); + int j; + double* op0 = SrcTable; + + for (i = FracCount; i >= 0; i--) { + TableFillFlags[i] = 0; + double* p = Buf + BufOffs + i; + + for (j = 0; j < SrcFilterLen; j++) { + op0[0] = p[0]; + op0++; + p += FracCount; + } + } + + Table.alloc((FracCount + 1) * FilterSize, Alignment); + } + + /** + * Function creates the specified filter in the Table by copying it from + * the SrcTable and filtering by ExtFilter. Function does nothing if + * filter was already created. + * + * @param k Filter index to create, in the range 0 to FracCount, + * inclusive. + */ + + void createFilter(const int k) { + if (TableFillFlags[k] != 0) { + return; + } + + TableFillFlags[k] |= 1; + const int ExtFilterLatency = ExtFilter.getCapacity() / 2; + const int ResLatency = ExtFilterLatency + SrcFilterLen / 2; + int ResLen = SrcFilterLen; + + if (ExtFilter.getCapacity() > 0) { + ResLen += ExtFilter.getCapacity() - 1; + } + + const int ResOffs = FilterLen / 2 - ResLatency; + fptype* op = &Table[k * FilterSize]; + int i; + + for (i = 0; i < ResOffs; i++) { + op[i] = 0.0; + } + + for (i = ResOffs + ResLen; i < FilterLen; i++) { + op[i] = 0.0; + } + + op += ResOffs; + const double* const srcflt = &SrcTable[k * SrcFilterLen]; + + if (ExtFilter.getCapacity() == 0) { + for (i = 0; i < ResLen; i++) { + op[i] = (fptype)srcflt[i]; + } + + return; + } + + // Perform convolution of extflt and srcflt. + + const double* const extflt = &ExtFilter[0]; + int j; + + for (j = 0; j < ResLen; j++) { + int k = 0; + int l = j - ExtFilter.getCapacity() + 1; + int r = l + ExtFilter.getCapacity(); + + if (l < 0) { + k -= l; + l = 0; + } + + if (r > SrcFilterLen) { + r = SrcFilterLen; + } + + const double* const extfltb = extflt + k; + const double* const srcfltb = srcflt + l; + double s = 0.0; + l = r - l; + + for (i = 0; i < l; i++) { + s += extfltb[i] * srcfltb[i]; + } + + op[j] = (fptype)s; + } + } +}; + +/** + * @brief Thread pool for multi-threaded image resizing operation. + * + * This base class is used to organize a multi-threaded image resizing + * operation. The thread pool should consist of threads that initially wait + * for a signal. Upon receiving a signal (via the startAllWorkloads() + * function) each previously added thread should execute its workload's + * process() function once, and return to the wait signal state again. The + * thread pool should be also able to efficiently wait for all workloads to + * finish via the waitAllWorkloadsToFinish() function. + * + * The image resizing algorithm makes calls to functions of this class. + */ + +class CImageResizerThreadPool { + public: + CImageResizerThreadPool() {} + + virtual ~CImageResizerThreadPool() {} + + /** + * @brief Thread pool's workload object class. + * + * This class should be used as a base class for objects that perform the + * actual work spread over several threads. + */ + + class CWorkload { + public: + virtual ~CWorkload() {} + + /** + * Function that gets called from the thread when thread pool's + * startAllWorkloads() function is called. + */ + + virtual void process() = 0; + }; + + /** + * @return The suggested number of workloads (and their associated + * threads) to add. The minimal value this function can return is 1. The + * usual value may depend on the number of physical and virtual cores + * present in the system, and on other considerations. + */ + + virtual int getSuggestedWorkloadCount() const { return (1); } + + /** + * Function adds a new workload (and possibly thread) to the thread pool. + * The caller decides how many parallel workloads (and threads) it + * requires, but this number will not exceed the value returned by the + * getSuggestedWorkloadCount() function. It is implementation-specific how + * many workloads to associate with a single thread. But for efficiency + * reasons each workload should be associated with its own thread. + * + * Note that the same set of workload objects will be processed each time + * the startAllWorkloads() function is called. This means that workload + * objects are added only once. The caller changes the state of the + * workload objects and then calls the startAllWorkloads() function to + * process them. + * + * @param Workload Workload object whose process() function will be called + * from within the thread when the startAllWorkloads() function is called. + */ + + virtual void addWorkload(CWorkload* const Workload) {} + + /** + * Function starts all workloads associated with threads previously added + * via the addWorkload() function. It is assumed that this function + * performs the necessary "memory barrier" (or "cache sync") kind of + * operation so that all threads catch up the prior changes made to the + * workload objects during their wait state. + */ + + virtual void startAllWorkloads() {} + + /** + * Function waits for all workloads to finish. + */ + + virtual void waitAllWorkloadsToFinish() {} + + /** + * Function removes all workloads previously added via the addWorkload() + * function. This function gets called only after the + * waitAllWorkloadsToFinish() function call. + */ + + virtual void removeAllWorkloads() {} +}; + +/** + * @brief Resizing algorithm parameters structure. + * + * This structure holds all selectable parameters used by the resizing + * algorithm at various stages, for both downsizing and upsizing. There are no + * other parameters exist that can optimize the performance of the resizing + * algorithm. Filter length parameters can take fractional values. + * + * Beside quality, these parameters (except Alpha parameters) directly affect + * the computative cost of the resizing algorithm. It is possible to trade + * the visual quality for computative cost. + * + * Anti-alias filtering during downsizing can be defined as a considerable + * reduction of contrast of smallest features of an image. Unfortunately, such + * de-contrasting partially affects features of all sizes thus producing a + * non-linearity of frequency response. All pre-defined parameter sets are + * described by 3 values separated by slashes. The first value is the + * de-contrasting factor of small features (which are being removed) while + * the second value is the de-contrasting factor of large features (which + * should remain intact), with value of 1 equating to "no contrast change". + * The third value is the optimization score (see below), with value of 0 + * equating to the "perfect" linearity of frequency response. + * + * The pre-defined parameter sets offered by this library were auto-optimized + * for the given LPFltBaseLen, IntFltLen and CorrFltAlpha values. The + * optimization goal was to minimize the score: the sum of squares of the + * difference between original and processed images (which was not actually + * resized, k=1). The original image was a 0.5 megapixel uniformly-distributed + * white-noise image with pixel intensities in the 0-1 range. Such goal + * converges very well and produces filtering system with the flattest + * frequency response possible for the given constraints. With this goal, + * increasing the LPFltBaseLen value reduces the general amount of aliasing + * artifacts. + */ + +struct CImageResizerParams { + double CorrFltAlpha; ///< Alpha parameter of the Peaked Cosine window + ///< function used on the correction filter. The + ///< "usable" values are in the narrow range 1.0 to 1.5. + ///< + double CorrFltLen; ///< Correction filter's length in samples (taps). The + ///< "usable" range is narrow, 5.5 to 8, as to minimize + ///< the "overcorrection" which is mathematically precise, + ///< but visually unacceptable. + ///< + double IntFltAlpha; ///< Alpha parameter of the Peaked Cosine window + ///< function used on the interpolation low-pass filter. + ///< The "usable" values are in the range 1.5 to 2.5. + ///< + double IntFltCutoff; ///< Interpolation low-pass filter's cutoff frequency + ///< (normalized, [0; 1]). The "usable" range is 0.6 to + ///< 0.8. + ///< + double IntFltLen; ///< Interpolation low-pass filter's length in samples + ///< (taps). The length value should be at least 18 or + ///< otherwise a "dark grid" artifact will be introduced if + ///< a further sharpening is applied. IntFltLen together + ///< with other IntFlt parameters should be tuned in a way + ///< that produces the flattest frequency response in 0-0.5 + ///< normalized frequency range (this range is due to 2X + ///< upsampling). + ///< + double LPFltAlpha; ///< Alpha parameter of the Peaked Cosine window + ///< function used on the low-pass filter. The "usable" + ///< values are in the range 1.5 to 6.5. + ///< + double LPFltBaseLen; ///< Base length of the low-pass (aka anti-aliasing + ///< or reconstruction) filter, in samples (taps), + ///< further adjusted by the actual cutoff frequency, + ///< upsampling and downsampling factors. The "usable" + ///< range is between 6 and 9. + ///< + double LPFltCutoffMult; ///< Low-pass filter's cutoff frequency + ///< multiplier. This value can be both below and + ///< above 1.0 as low-pass filters are inserted on + ///< downsampling and upsampling steps and always + ///< have corner frequency equal to or below 0.5pi. + ///< This multiplier shifts low-pass filter's corner + ///< frequency towards lower (if below 1.0) or higher + ///< (if above 1.0) frequencies. This multiplier can + ///< be way below 1.0 since any additional + ///< high-frequency damping will be partially + ///< corrected by the correction filter. The "usable" + ///< range is 0.3 to 1.0. + ///< + + CImageResizerParams() + : HBFltAlpha(1.75395), HBFltCutoff(0.40356), HBFltLen(22.00000) {} + + double HBFltAlpha; ///< Half-band filter's Alpha. Assigned internally. + ///< + double HBFltCutoff; ///< Half-band filter's cutoff point [0; 1]. Assigned + ///< internally. + ///< + double HBFltLen; ///< Length of the half-band low-pass filter. Assigned + ///< internally. Internally used to perform 2X or higher + ///< downsampling. These filter parameters should be treated + ///< as "technical" and do not require adjustment as they + ///< were tuned to suit all combinations of other + ///< parameters. This half-band filter provides a wide + ///< transition band (for minimal ringing artifacts) and a + ///< high stop-band attenuation (for minimal aliasing). + ///< +}; + +/** + * @brief The default set of resizing algorithm parameters + * (10.01/1.029/0.019169). + * + * This is the default set of resizing parameters that was designed to deliver + * a sharp image while still providing a low amount of ringing artifacts, and + * having a reasonable computational cost. + */ + +struct CImageResizerParamsDef : public CImageResizerParams { + CImageResizerParamsDef() { + CorrFltAlpha = 1.0; // 10.01/1.88/1.029(522.43)/0.019169:258648,446808 + CorrFltLen = 6.30770; + IntFltAlpha = 2.27825; + IntFltCutoff = 0.75493; + IntFltLen = 18.0; + LPFltAlpha = 3.40127; + LPFltBaseLen = 7.78; + LPFltCutoffMult = 0.78797; + } +}; + +/** + * @brief Set of resizing algorithm parameters for ultra-low-ringing + * performance (7.69/1.069/0.000245). + * + * This set of resizing algorithm parameters offers the lowest amount of + * ringing this library is capable of providing while still offering a decent + * quality. Low ringing is attained at the expense of higher aliasing + * artifacts and a slightly reduced contrast. + */ + +struct CImageResizerParamsULR : public CImageResizerParams { + CImageResizerParamsULR() { + CorrFltAlpha = 1.0; // 7.69/1.97/1.069(31445.45)/0.000245:258627,436845 + CorrFltLen = 5.83280; + IntFltAlpha = 2.11453; + IntFltCutoff = 0.73986; + IntFltLen = 18.0; + LPFltAlpha = 1.73455; + LPFltBaseLen = 6.40; + LPFltCutoffMult = 0.61314; + } +}; + +/** + * @brief Set of resizing algorithm parameters for low-ringing performance + * (7.86/1.065/0.000106). + * + * This set of resizing algorithm parameters offers a very low-ringing + * performance at the expense of higher aliasing artifacts and a slightly + * reduced contrast. + */ + +struct CImageResizerParamsLR : public CImageResizerParams { + CImageResizerParamsLR() { + CorrFltAlpha = 1.0; // 7.86/1.96/1.065(73865.02)/0.000106:258636,437381 + CorrFltLen = 5.87671; + IntFltAlpha = 2.25322; + IntFltCutoff = 0.74090; + IntFltLen = 18.0; + LPFltAlpha = 1.79306; + LPFltBaseLen = 7.00; + LPFltCutoffMult = 0.68881; + } +}; + +/** + * @brief Set of resizing algorithm parameters for lower-ringing performance + * (8.86/1.046/0.010168). + * + * This set of resizing algorithm parameters offers a lower-ringing + * performance in comparison to the default setting, at the expense of higher + * aliasing artifacts and a slightly reduced contrast. + */ + +struct CImageResizerParamsLow : public CImageResizerParams { + CImageResizerParamsLow() { + CorrFltAlpha = 1.0; // 8.86/1.92/1.046(871.54)/0.010168:258647,442252 + CorrFltLen = 6.09757; + IntFltAlpha = 2.36704; + IntFltCutoff = 0.74674; + IntFltLen = 18.0; + LPFltAlpha = 2.19427; + LPFltBaseLen = 7.66; + LPFltCutoffMult = 0.75380; + } +}; + +/** + * @brief Set of resizing algorithm parameters for low-aliasing + * resizing (11.81/1.012/0.038379). + * + * This set of resizing algorithm parameters offers a considerable + * anti-aliasing performance with a good frequency response linearity (and + * contrast). This is an intermediate setting between the default and Ultra + * parameters. + */ + +struct CImageResizerParamsHigh : public CImageResizerParams { + CImageResizerParamsHigh() { + CorrFltAlpha = 1.0; // 11.81/1.83/1.012(307.84)/0.038379:258660,452719 + CorrFltLen = 6.80909; + IntFltAlpha = 2.44917; + IntFltCutoff = 0.75856; + IntFltLen = 18.0; + LPFltAlpha = 4.39527; + LPFltBaseLen = 8.18; + LPFltCutoffMult = 0.79172; + } +}; + +/** + * @brief Set of resizing algorithm parameters for ultra low-aliasing + * resizing (13.65/1.001/0.000483). + * + * This set of resizing algorithm parameters offers a very considerable + * anti-aliasing performance with a good frequency response linearity (and + * contrast). This set of parameters is computationally expensive and may + * produce ringing artifacts on sharp features. + */ + +struct CImageResizerParamsUltra : public CImageResizerParams { + CImageResizerParamsUltra() { + CorrFltAlpha = 1.0; // 13.65/1.79/1.001(28288.41)/0.000483:258658,457974 + CorrFltLen = 7.48060; + IntFltAlpha = 1.93750; + IntFltCutoff = 0.75462; + IntFltLen = 18.0; + LPFltAlpha = 5.55209; + LPFltBaseLen = 8.34; + LPFltCutoffMult = 0.78002; + } +}; + +/** + * @brief Image resizing variables class. + * + * This is an utility "catch all" class that defines various variables used + * during image resizing. Several variables that are explicitly initialized in + * this class' constructor are also used as additional "input" variables to + * the image resizing function. These variables will not be changed by the + * avir::CImageResizer<>::resizeImage() function. + */ + +class CImageResizerVars { + public: + int ElCount; ///< The number of "fptype" elements used to store 1 pixel. + ///< + int ElCountIO; ///< The number of source and destination image's elements + ///< used to store 1 pixel. + ///< + int fppack; ///< The number of atomic types stored in a single "fptype" + ///< element. + ///< + int fpalign; ///< Suggested alignment size in bytes. This is not a + ///< required alignment, because image resizing algorithm cannot + ///< be made to have a strictly aligned data access in all cases + ///< (e.g. de-interleaved interpolation cannot perform aligned + ///< accesses). + ///< + int elalign; ///< Length alignment of arrays of elements. This applies to + ///< filters and intermediate buffers: this constant forces + ///< filters and scanlines to have a length which is a multiple + ///< of this value, for more efficient SIMD implementation. + ///< + int packmode; ///< 0 if interleaved packing, 1 if de-interleaved. + ///< + int BufLen[2]; ///< Intermediate buffers' lengths in "fptype" elements. + int BufOffs[2]; ///< Offsets into the intermediate buffers, used to + ///< provide prefix elements required during processing so + ///< that no "out of range" access happens. This offset is a + ///< multiple of ElCount if pixels are stored in interleaved + ///< form. + ///< + double k; ///< Resizing step coefficient, updated to reflect the actually + ///< used coefficient during resizing. + ///< + double o; ///< Starting pixel offset inside the source image, updated to + ///< reflect the actually used offset during resizing. + ///< + int ResizeStep; ///< Index of the resizing step in the latest filtering + ///< steps array. + ///< + double InGammaMult; ///< Input gamma multiplier, used to convert input + ///< data to 0 to 1 range. 0.0 if no gamma is in use. + ///< + double OutGammaMult; ///< Output gamma multiplier, used to convert data to + ///< 0 to 255/65535 range. 0.0 if no gamma is in use. + ///< + + double ox; ///< Start X pixel offset within source image (can be + ///< negative). Positive offset moves image to the left. + ///< + double oy; ///< Start Y pixel offset within source image (can be + ///< negative). Positive offset moves image to the top. + ///< + CImageResizerThreadPool* + ThreadPool; ///< Thread pool to be used by the + ///< image resizing function. Set to NULL to use + ///< single-threaded processing. + ///< + bool UseSRGBGamma; ///< Perform sRGB gamma linearization (correction). + ///< + int BuildMode; ///< The build mode to use, for debugging purposes. Set to + ///< -1 to select a minimal-complexity mode automatically. All + ///< build modes deliver similar results with minor + ///< deviations. + ///< + int RndSeed; ///< Random seed parameter. This parameter may be incremented + ///< after each random generator initialization. The use of this + ///< variable depends on the ditherer implementation. + ///< + + CImageResizerVars() + : ox(0.0), + oy(0.0), + ThreadPool(NULL), + UseSRGBGamma(false), + BuildMode(-1), + RndSeed(0) {} +}; + +/** + * @brief Image resizer's filtering step class. + * + * Class defines data to perform a single filtering step over a whole + * horizontal or vertical scanline. Resizing consists of 1 or more steps that + * may be performed before the actual resizing takes place. Filtering may also + * follow a resizing step. Each step must ensure that scanline data contains + * enough pixels to perform the next step (which may be resizing) without + * exceeding scanline's bounds. + * + * A derived class must implement several "const" and "static" functions that + * are used to perform the actual filtering in interleaved or de-interleaved + * mode. + * + * @tparam fptype Floating point type to use for storing pixel elements. SIMD + * types can be used: in this case each element may hold a whole pixel. + * @tparam fptypeatom The atomic type the "fptype" consists of. + */ + +template +class CImageResizerFilterStep { + public: + bool IsUpsample; ///< "True" if this step is an upsampling step, "false" + ///< if downsampling step. Should be set to "false" if + ///< ResampleFactor equals 0. + ///< + int ResampleFactor; ///< Resample factor (>=1). If 0, this is a resizing + ///< step. This value should be >1 if IsUpsample equals + ///< "true". + ///< + CBuffer Flt; ///< Filter to use at this step. + ///< + CFltBuffer FltOrig; ///< Originally-designed filter. This buffer may not + ///< be assigned. Assigned by filters that precede the + ///< resizing step if such filter is planned to be + ///< embedded into the interpolation filter as "external" + ///< filter. If IsUpsample=true and this filter buffer is + ///< not empty, the upsampling step will not itself apply + ///< any filtering over upsampled input scanline. + ///< + double DCGain; ///< DC gain which was applied to the filter. Not defined + ///< if ResampleFactor = 0. + ///< + int FltLatency; ///< Filter's latency (group delay, shift) in pixels. + ///< + const CImageResizerVars* Vars; ///< Image resizing-related variables. + ///< + int InLen; ///< Input scanline's length in pixels. + ///< + int InBuf; ///< Input buffer index, 0 or 1. + ///< + int InPrefix; ///< Required input prefix pixels. These prefix pixels will + ///< be filled with source scanline's first pixel value. If + ///< IsUpsample is "true", this is the additional number of + ///< times the first pixel will be filtered before processing + ///< scanline, this number is also reflected in the OutPrefix. + ///< + int InSuffix; ///< Required input suffix pixels. These suffix pixels will + ///< be filled with source scanline's last pixel value. If + ///< IsUpsample is "true", this is the additional number of + ///< times the last pixel will be filtered before processing + ///< scanline, this number is also reflected in the OutSuffix. + ///< + int InElIncr; ///< Pixel element increment within the input buffer, used + ///< during de-interleaved processing: in this case each + ///< image's channel is stored independently, InElIncr elements + ///< apart. + ///< + int OutLen; ///< Length of the resulting scanline. + ///< + int OutBuf; ///< Output buffer index. 0 or 1; 2 for the last step. + ///< + int OutPrefix; ///< Required output prefix pixels. These prefix pixels + ///< will not be pre-filled with any values. Value is valid + ///< only if IsUpsample equals "true". + ///< + int OutSuffix; ///< Required input suffix pixels. These suffix pixels will + ///< not be pre-filled with any values. Value is valid only if + ///< IsUpsample equals "true". + ///< + int OutElIncr; ///< Pixel element increment within the output buffer, used + ///< during de-interleaved processing. Equals to the + ///< InBufElIncr of the next step. + ///< + CBuffer PrefixDC; ///< DC component fluctuations added at the + ///< start of the resulting scanline, used when + ///< IsUpsample equals "true". + ///< + CBuffer SuffixDC; ///< DC component fluctuations added at the + ///< end of the resulting scanline, used when + ///< IsUpsample equals "true". + ///< + int EdgePixelCount; ///< The number of edge pixels added. Affects the + ///< initial position within the input scanline, used to + ///< produce edge pixels. This variable is used and + ///< should be defined when IsUpsample=false and + ///< ResampleFactor>0. When assigning this variable it is + ///< also necessary to update InPrefix, OutLen and Vars.o + ///< variables. + ///< + static const int EdgePixelCountDef = + 3; ///< The default number of pixels + ///< additionally produced at scanline edges during filtering. This is + ///< required to reduce edge artifacts. + ///< + + /** + * @brief Resizing position structure. + * + * Structure holds resizing position and pointer to fractional delay + * filter. + */ + + struct CResizePos { + int SrcPosInt; ///< Source scanline position. + ///< + int fti; ///< Fractional delay filter index. + ///< + const fptype* ftp; ///< Fractional delay filter pointer. + ///< + fptypeatom x; ///< Interpolation coefficient between delay filters. + ///< + int SrcOffs; ///< Source scanline offset. + ///< + }; + + /** + * @brief Resizing positions buffer class. + * + * This class combines buffer together with variables that define resizing + * stepping. + */ + + class CRPosBuf : public CBuffer { + public: + double k; ///< Resizing step. + ///< + double o; ///< Resizing offset. + ///< + int FracCount; ///< The number of fractional delay filters in a filter + ///< bank used together with this buffer. + ///< + }; + + /** + * @brief Resizing positions buffer array class. + * + * This class combines structure array of the CRPosBuf class objects with + * the function that locates or creates buffer with the required resizing + * stepping. + */ + + class CRPosBufArray : public CStructArray { + public: + using CStructArray::add; + using CStructArray::getItemCount; + + /** + * Function returns the resizing positions buffer with the required + * stepping. If no such buffer exists, it is created. + * + * @param k Resizing step. + * @param o Resizing offset. + * @param FracCount The number of fractional delay filters in a filter + * bank used together with this buffer. + * @return Reference to the CRPosBuf object. + */ + + CRPosBuf& getRPosBuf(const double k, const double o, const int FracCount) { + int i; + + for (i = 0; i < getItemCount(); i++) { + CRPosBuf& Buf = (*this)[i]; + + if (Buf.k == k && Buf.o == o && Buf.FracCount == FracCount) { + return (Buf); + } + } + + CRPosBuf& NewBuf = add(); + NewBuf.k = k; + NewBuf.o = o; + NewBuf.FracCount = FracCount; + + return (NewBuf); + } + }; + + CRPosBuf* RPosBuf; ///< Resizing positions buffer. Used when + ///< ResampleFactor equals 0 (resizing step). + ///< + CDSPFracFilterBankLin* FltBank; ///< Filter bank in use by *this + ///< resizing step. + ///< +}; + +/** + * @brief Interleaved filtering steps implementation class. + * + * This class implements scanline filtering functions in interleaved mode. + * This means that each pixel is processed independently, not in groups. + * + * @tparam fptype Floating point type to use for storing pixel elements. SIMD + * types can be used: in this case each element may hold a whole pixel. + * @tparam fptypeatom The atomic type the "fptype" consists of. + */ + +template +class CImageResizerFilterStepINL + : public CImageResizerFilterStep { + public: + using CImageResizerFilterStep::IsUpsample; + using CImageResizerFilterStep::ResampleFactor; + using CImageResizerFilterStep::Flt; + using CImageResizerFilterStep::FltOrig; + using CImageResizerFilterStep::FltLatency; + using CImageResizerFilterStep::Vars; + using CImageResizerFilterStep::InLen; + using CImageResizerFilterStep::InPrefix; + using CImageResizerFilterStep::InSuffix; + using CImageResizerFilterStep::OutLen; + using CImageResizerFilterStep::OutPrefix; + using CImageResizerFilterStep::OutSuffix; + using CImageResizerFilterStep::PrefixDC; + using CImageResizerFilterStep::SuffixDC; + using CImageResizerFilterStep::RPosBuf; + using CImageResizerFilterStep::FltBank; + using CImageResizerFilterStep::EdgePixelCount; + + /** + * Function performs "packing" of a scanline and type conversion. + * Scanline, depending on the "fptype" can be potentially stored as a + * packed SIMD values having a certain atomic type. If required, the sRGB + * gamma correction is applied. + * + * @param ip Input scanline. + * @param op0 Output scanline. + * @param l0 The number of pixels to "pack". + */ + + template + void packScanline(const Tin* ip, fptype* const op0, const int l0) const { + const int ElCount = Vars->ElCount; + const int ElCountIO = Vars->ElCountIO; + fptype* op = op0; + int l = l0; + + if (!Vars->UseSRGBGamma) { + if (ElCountIO == 1) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op; + v[0] = (fptypeatom)ip[0]; + op += ElCount; + ip++; + l--; + } + } else if (ElCountIO == 4) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op; + v[0] = (fptypeatom)ip[0]; + v[1] = (fptypeatom)ip[1]; + v[2] = (fptypeatom)ip[2]; + v[3] = (fptypeatom)ip[3]; + op += ElCount; + ip += 4; + l--; + } + } else if (ElCountIO == 3) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op; + v[0] = (fptypeatom)ip[0]; + v[1] = (fptypeatom)ip[1]; + v[2] = (fptypeatom)ip[2]; + op += ElCount; + ip += 3; + l--; + } + } else if (ElCountIO == 2) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op; + v[0] = (fptypeatom)ip[0]; + v[1] = (fptypeatom)ip[1]; + op += ElCount; + ip += 2; + l--; + } + } + } else { + const fptypeatom gm = (fptypeatom)Vars->InGammaMult; + + if (ElCountIO == 1) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op; + v[0] = convertSRGB2Lin((fptypeatom)ip[0] * gm); + op += ElCount; + ip++; + l--; + } + } else if (ElCountIO == 4) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op; + v[0] = convertSRGB2Lin((fptypeatom)ip[0] * gm); + v[1] = convertSRGB2Lin((fptypeatom)ip[1] * gm); + v[2] = convertSRGB2Lin((fptypeatom)ip[2] * gm); + v[3] = convertSRGB2Lin((fptypeatom)ip[3] * gm); + op += ElCount; + ip += 4; + l--; + } + } else if (ElCountIO == 3) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op; + v[0] = convertSRGB2Lin((fptypeatom)ip[0] * gm); + v[1] = convertSRGB2Lin((fptypeatom)ip[1] * gm); + v[2] = convertSRGB2Lin((fptypeatom)ip[2] * gm); + op += ElCount; + ip += 3; + l--; + } + } else if (ElCountIO == 2) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op; + v[0] = convertSRGB2Lin((fptypeatom)ip[0] * gm); + v[1] = convertSRGB2Lin((fptypeatom)ip[1] * gm); + op += ElCount; + ip += 2; + l--; + } + } + } + + const int ZeroCount = ElCount * Vars->fppack - ElCountIO; + op = op0; + l = l0; + + if (ZeroCount == 1) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op + ElCountIO; + v[0] = (fptypeatom)0; + op += ElCount; + l--; + } + } else if (ZeroCount == 2) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op + ElCountIO; + v[0] = (fptypeatom)0; + v[1] = (fptypeatom)0; + op += ElCount; + l--; + } + } else if (ZeroCount == 3) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op + ElCountIO; + v[0] = (fptypeatom)0; + v[1] = (fptypeatom)0; + v[2] = (fptypeatom)0; + op += ElCount; + l--; + } + } + } + + /** + * Function applies Linear to sRGB gamma correction to the specified + * scanline. + * + * @param p Scanline. + * @param l The number of pixels to de-linearize. + * @param Vars0 Image resizing-related variables. + */ + + static void applySRGBGamma(fptype* p, int l, const CImageResizerVars& Vars0) { + const int ElCount = Vars0.ElCount; + const int ElCountIO = Vars0.ElCountIO; + const fptypeatom gm = (fptypeatom)Vars0.OutGammaMult; + + if (ElCountIO == 1) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)p; + v[0] = convertLin2SRGB(v[0]) * gm; + p += ElCount; + l--; + } + } else if (ElCountIO == 4) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)p; + v[0] = convertLin2SRGB(v[0]) * gm; + v[1] = convertLin2SRGB(v[1]) * gm; + v[2] = convertLin2SRGB(v[2]) * gm; + v[3] = convertLin2SRGB(v[3]) * gm; + p += ElCount; + l--; + } + } else if (ElCountIO == 3) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)p; + v[0] = convertLin2SRGB(v[0]) * gm; + v[1] = convertLin2SRGB(v[1]) * gm; + v[2] = convertLin2SRGB(v[2]) * gm; + p += ElCount; + l--; + } + } else if (ElCountIO == 2) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)p; + v[0] = convertLin2SRGB(v[0]) * gm; + v[1] = convertLin2SRGB(v[1]) * gm; + p += ElCount; + l--; + } + } + } + + /** + * Function converts vertical scanline to horizontal scanline. This + * function is called by the image resizer when image is resized + * vertically. This means that the vertical scanline is stored in the + * same format produced by the packScanline() and maintained by other + * filtering functions. + * + * @param ip Input vertical scanline. + * @param op Output buffer (temporary buffer used during resizing). + * @param SrcLen The number of pixels in the input scanline, also used to + * calculate input buffer increment. + * @param SrcIncr Input buffer increment to the next vertical pixel. + */ + + void convertVtoH(const fptype* ip, fptype* op, const int SrcLen, + const int SrcIncr) const { + const int ElCount = Vars->ElCount; + int j; + + if (ElCount == 1) { + for (j = 0; j < SrcLen; j++) { + op[0] = ip[0]; + ip += SrcIncr; + op++; + } + } else if (ElCount == 4) { + for (j = 0; j < SrcLen; j++) { + op[0] = ip[0]; + op[1] = ip[1]; + op[2] = ip[2]; + op[3] = ip[3]; + ip += SrcIncr; + op += 4; + } + } else if (ElCount == 3) { + for (j = 0; j < SrcLen; j++) { + op[0] = ip[0]; + op[1] = ip[1]; + op[2] = ip[2]; + ip += SrcIncr; + op += 3; + } + } else if (ElCount == 2) { + for (j = 0; j < SrcLen; j++) { + op[0] = ip[0]; + op[1] = ip[1]; + ip += SrcIncr; + op += 2; + } + } + } + + /** + * Function performs "unpacking" of a scanline and type conversion + * (truncation is used when floating point is converted to integer). + * Scanline, depending on the "fptype" can be potentially stored as a + * packed SIMD values having a certain atomic type. The unpacking function + * assumes that scanline is stored in the style produced by the + * packScanline() function. + * + * @param ip Input scanline. + * @param op Output scanline. + * @param l The number of pixels to "unpack". + * @param Vars0 Image resizing-related variables. + */ + + template + static void unpackScanline(const fptype* ip, Tout* op, int l, + const CImageResizerVars& Vars0) { + const int ElCount = Vars0.ElCount; + const int ElCountIO = Vars0.ElCountIO; + + if (ElCountIO == 1) { + while (l > 0) { + const fptypeatom* v = (const fptypeatom*)ip; + op[0] = (Tout)v[0]; + ip += ElCount; + op++; + l--; + } + } else if (ElCountIO == 4) { + while (l > 0) { + const fptypeatom* v = (const fptypeatom*)ip; + op[0] = (Tout)v[0]; + op[1] = (Tout)v[1]; + op[2] = (Tout)v[2]; + op[3] = (Tout)v[3]; + ip += ElCount; + op += 4; + l--; + } + } else if (ElCountIO == 3) { + while (l > 0) { + const fptypeatom* v = (const fptypeatom*)ip; + op[0] = (Tout)v[0]; + op[1] = (Tout)v[1]; + op[2] = (Tout)v[2]; + ip += ElCount; + op += 3; + l--; + } + } else if (ElCountIO == 2) { + while (l > 0) { + const fptypeatom* v = (const fptypeatom*)ip; + op[0] = (Tout)v[0]; + op[1] = (Tout)v[1]; + ip += ElCount; + op += 2; + l--; + } + } + } + + /** + * Function prepares input scanline buffer for *this filtering step. + * Left- and right-most pixels are replicated to make sure no buffer + * overrun happens. Such approach also allows to bypass any pointer + * range checks. + * + * @param Src Source buffer. + */ + + void prepareInBuf(fptype* Src) const { + if (IsUpsample || InPrefix + InSuffix == 0) { + return; + } + + const int ElCount = Vars->ElCount; + replicateArray(Src, ElCount, Src - ElCount, InPrefix, -ElCount); + + Src += (InLen - 1) * ElCount; + replicateArray(Src, ElCount, Src + ElCount, InSuffix, ElCount); + } + + /** + * Function peforms scanline upsampling with filtering. + * + * @param Src Source scanline buffer (length = this -> InLen). Source + * scanline increment will be equal to ElCount. + * @param Dst Destination scanline buffer. + */ + + void doUpsample(const fptype* const Src, fptype* const Dst) const { + const int ElCount = Vars->ElCount; + fptype* op0 = &Dst[-OutPrefix * ElCount]; + memset(&op0->value, 0, (OutPrefix + OutLen + OutSuffix) * ElCount * sizeof(op0->value)); + + const fptype* ip = Src; + const int opstep = ElCount * ResampleFactor; + int l; + + if (FltOrig.getCapacity() > 0) { + // Do not perform filtering, only upsample. + + op0 += (OutPrefix % ResampleFactor) * ElCount; + l = OutPrefix / ResampleFactor; + + if (ElCount == 1) { + while (l > 0) { + op0[0] = ip[0]; + op0 += opstep; + l--; + } + + l = InLen - 1; + + while (l > 0) { + op0[0] = ip[0]; + op0 += opstep; + ip += ElCount; + l--; + } + + l = OutSuffix / ResampleFactor; + + while (l >= 0) { + op0[0] = ip[0]; + op0 += opstep; + l--; + } + } else if (ElCount == 4) { + while (l > 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0[2] = ip[2]; + op0[3] = ip[3]; + op0 += opstep; + l--; + } + + l = InLen - 1; + + while (l > 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0[2] = ip[2]; + op0[3] = ip[3]; + op0 += opstep; + ip += ElCount; + l--; + } + + l = OutSuffix / ResampleFactor; + + while (l >= 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0[2] = ip[2]; + op0[3] = ip[3]; + op0 += opstep; + l--; + } + } else if (ElCount == 3) { + while (l > 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0[2] = ip[2]; + op0 += opstep; + l--; + } + + l = InLen - 1; + + while (l > 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0[2] = ip[2]; + op0 += opstep; + ip += ElCount; + l--; + } + + l = OutSuffix / ResampleFactor; + + while (l >= 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0[2] = ip[2]; + op0 += opstep; + l--; + } + } else if (ElCount == 2) { + while (l > 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0 += opstep; + l--; + } + + l = InLen - 1; + + while (l > 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0 += opstep; + ip += ElCount; + l--; + } + + l = OutSuffix / ResampleFactor; + + while (l >= 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0 += opstep; + l--; + } + } + + return; + } + + const fptype* const f = Flt; + const int flen = Flt.getCapacity(); + fptype* op; + int i; + + if (ElCount == 1) { + l = InPrefix; + + while (l > 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[i] += f[i] * ip[0]; + } + + op0 += opstep; + l--; + } + + l = InLen - 1; + + while (l > 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[i] += f[i] * ip[0]; + } + + ip += ElCount; + op0 += opstep; + l--; + } + + l = InSuffix; + + while (l >= 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[i] += f[i] * ip[0]; + } + + op0 += opstep; + l--; + } + } else if (ElCount == 4) { + l = InPrefix; + + while (l > 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op[2] += f[i] * ip[2]; + op[3] += f[i] * ip[3]; + op += 4; + } + + op0 += opstep; + l--; + } + + l = InLen - 1; + + while (l > 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op[2] += f[i] * ip[2]; + op[3] += f[i] * ip[3]; + op += 4; + } + + ip += ElCount; + op0 += opstep; + l--; + } + + l = InSuffix; + + while (l >= 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op[2] += f[i] * ip[2]; + op[3] += f[i] * ip[3]; + op += 4; + } + + op0 += opstep; + l--; + } + } else if (ElCount == 3) { + l = InPrefix; + + while (l > 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op[2] += f[i] * ip[2]; + op += 3; + } + + op0 += opstep; + l--; + } + + l = InLen - 1; + + while (l > 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op[2] += f[i] * ip[2]; + op += 3; + } + + ip += ElCount; + op0 += opstep; + l--; + } + + l = InSuffix; + + while (l >= 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op[2] += f[i] * ip[2]; + op += 3; + } + + op0 += opstep; + l--; + } + } else if (ElCount == 2) { + l = InPrefix; + + while (l > 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op += 2; + } + + op0 += opstep; + l--; + } + + l = InLen - 1; + + while (l > 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op += 2; + } + + ip += ElCount; + op0 += opstep; + l--; + } + + l = InSuffix; + + while (l >= 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op += 2; + } + + op0 += opstep; + l--; + } + } + + op = op0; + const fptype* dc = SuffixDC; + l = SuffixDC.getCapacity(); + + if (ElCount == 1) { + for (i = 0; i < l; i++) { + op[i] += ip[0] * dc[i]; + } + } else if (ElCount == 4) { + while (l > 0) { + op[0] += ip[0] * dc[0]; + op[1] += ip[1] * dc[0]; + op[2] += ip[2] * dc[0]; + op[3] += ip[3] * dc[0]; + dc++; + op += 4; + l--; + } + } else if (ElCount == 3) { + while (l > 0) { + op[0] += ip[0] * dc[0]; + op[1] += ip[1] * dc[0]; + op[2] += ip[2] * dc[0]; + dc++; + op += 3; + l--; + } + } else if (ElCount == 2) { + while (l > 0) { + op[0] += ip[0] * dc[0]; + op[1] += ip[1] * dc[0]; + dc++; + op += 2; + l--; + } + } + + ip = Src; + op = Dst - InPrefix * opstep; + dc = PrefixDC; + l = PrefixDC.getCapacity(); + + if (ElCount == 1) { + for (i = 0; i < l; i++) { + op[i] += ip[0] * dc[i]; + } + } else if (ElCount == 4) { + while (l > 0) { + op[0] += ip[0] * dc[0]; + op[1] += ip[1] * dc[0]; + op[2] += ip[2] * dc[0]; + op[3] += ip[3] * dc[0]; + dc++; + op += 4; + l--; + } + } else if (ElCount == 3) { + while (l > 0) { + op[0] += ip[0] * dc[0]; + op[1] += ip[1] * dc[0]; + op[2] += ip[2] * dc[0]; + dc++; + op += 3; + l--; + } + } else if (ElCount == 2) { + while (l > 0) { + op[0] += ip[0] * dc[0]; + op[1] += ip[1] * dc[0]; + dc++; + op += 2; + l--; + } + } + } + + /** + * Function peforms scanline filtering with optional downsampling. + * Function makes use of the symmetry of the filter. + * + * @param Src Source scanline buffer (length = this -> InLen). Source + * scanline increment will be equal to ElCount. + * @param Dst Destination scanline buffer. + * @param DstIncr Destination scanline buffer increment, used for + * horizontal or vertical scanline stepping. + */ + + void doFilter(const fptype* const Src, fptype* Dst, const int DstIncr) const { + const int ElCount = Vars->ElCount; + const fptype* const f = &Flt[FltLatency]; + const int flen = FltLatency + 1; + const int ipstep = ElCount * ResampleFactor; + const fptype* ip = Src - EdgePixelCount * ipstep; + const fptype* ip1; + const fptype* ip2; + int l = OutLen; + int i; + + if (ElCount == 1) { + while (l > 0) { + fptype s = f[0] * ip[0]; + ip1 = ip; + ip2 = ip; + + for (i = 1; i < flen; i++) { + ip1++; + ip2--; + s += f[i] * (ip1[0] + ip2[0]); + } + + Dst[0] = s; + Dst += DstIncr; + ip += ipstep; + l--; + } + } else if (ElCount == 4) { + while (l > 0) { + fptype s1 = f[0] * ip[0]; + fptype s2 = f[0] * ip[1]; + fptype s3 = f[0] * ip[2]; + fptype s4 = f[0] * ip[3]; + ip1 = ip; + ip2 = ip; + + for (i = 1; i < flen; i++) { + ip1 += 4; + ip2 -= 4; + s1 += f[i] * (ip1[0] + ip2[0]); + s2 += f[i] * (ip1[1] + ip2[1]); + s3 += f[i] * (ip1[2] + ip2[2]); + s4 += f[i] * (ip1[3] + ip2[3]); + } + + Dst[0] = s1; + Dst[1] = s2; + Dst[2] = s3; + Dst[3] = s4; + Dst += DstIncr; + ip += ipstep; + l--; + } + } else if (ElCount == 3) { + while (l > 0) { + fptype s1 = f[0] * ip[0]; + fptype s2 = f[0] * ip[1]; + fptype s3 = f[0] * ip[2]; + ip1 = ip; + ip2 = ip; + + for (i = 1; i < flen; i++) { + ip1 += 3; + ip2 -= 3; + s1 += f[i] * (ip1[0] + ip2[0]); + s2 += f[i] * (ip1[1] + ip2[1]); + s3 += f[i] * (ip1[2] + ip2[2]); + } + + Dst[0] = s1; + Dst[1] = s2; + Dst[2] = s3; + Dst += DstIncr; + ip += ipstep; + l--; + } + } else if (ElCount == 2) { + while (l > 0) { + fptype s1 = f[0] * ip[0]; + fptype s2 = f[0] * ip[1]; + ip1 = ip; + ip2 = ip; + + for (i = 1; i < flen; i++) { + ip1 += 2; + ip2 -= 2; + s1 += f[i] * (ip1[0] + ip2[0]); + s2 += f[i] * (ip1[1] + ip2[1]); + } + + Dst[0] = s1; + Dst[1] = s2; + Dst += DstIncr; + ip += ipstep; + l--; + } + } + } + + /** + * Function performs resizing of a single scanline. This function does + * not "know" about the length of the source scanline buffer. This buffer + * should be padded with enough pixels so that ( SrcPos - FilterLenD2 ) is + * always >= 0 and ( SrcPos + ( DstLineLen - 1 ) * k + FilterLenD2 + 1 ) + * does not exceed source scanline's buffer length. SrcLine's increment is + * assumed to be equal to ElCount. + * + * @param SrcLine Source scanline buffer. + * @param DstLine Destination (resized) scanline buffer. + * @param DstLineIncr Destination scanline position increment, used for + * horizontal or vertical scanline stepping. + * @param xx Temporary buffer, of size FltBank -> getFilterLen(), must be + * aligned by fpclass :: fpalign. + */ + + void doResize(const fptype* SrcLine, fptype* DstLine, const int DstLineIncr, + fptype* const) const { + const int IntFltLen = FltBank->getFilterLen(); + const int ElCount = Vars->ElCount; + const typename CImageResizerFilterStep::CResizePos* + rpos = &(*RPosBuf)[0]; + + const typename CImageResizerFilterStep< + fptype, fptypeatom>::CResizePos* const rpose = rpos + OutLen; + +#define AVIR_RESIZE_PART1 \ + while (rpos < rpose) { \ + const fptype x = (fptype)rpos->x; \ + const fptype* const ftp = rpos->ftp; \ + const fptype* const ftp2 = ftp + IntFltLen; \ + const fptype* Src = SrcLine + rpos->SrcOffs; \ + int i; + +#define AVIR_RESIZE_PART1nx \ + while (rpos < rpose) { \ + const fptype* const ftp = rpos->ftp; \ + const fptype* Src = SrcLine + rpos->SrcOffs; \ + int i; + +#define AVIR_RESIZE_PART2 \ + DstLine += DstLineIncr; \ + rpos++; \ + } + + if (FltBank->getOrder() == 1) { + if (ElCount == 1) { + AVIR_RESIZE_PART1 + + fptype sum = 0.0; + + for (i = 0; i < IntFltLen; i++) { + sum += (ftp[i] + ftp2[i] * x) * Src[i]; + } + + DstLine[0] = sum; + + AVIR_RESIZE_PART2 + } else if (ElCount == 4) { + AVIR_RESIZE_PART1 + + fptype sum[4]; + sum[0] = 0.0; + sum[1] = 0.0; + sum[2] = 0.0; + sum[3] = 0.0; + + for (i = 0; i < IntFltLen; i++) { + const fptype xx = ftp[i] + ftp2[i] * x; + sum[0] += xx * Src[0]; + sum[1] += xx * Src[1]; + sum[2] += xx * Src[2]; + sum[3] += xx * Src[3]; + Src += 4; + } + + DstLine[0] = sum[0]; + DstLine[1] = sum[1]; + DstLine[2] = sum[2]; + DstLine[3] = sum[3]; + + AVIR_RESIZE_PART2 + } else if (ElCount == 3) { + AVIR_RESIZE_PART1 + + fptype sum[3]; + sum[0] = 0.0; + sum[1] = 0.0; + sum[2] = 0.0; + + for (i = 0; i < IntFltLen; i++) { + const fptype xx = ftp[i] + ftp2[i] * x; + sum[0] += xx * Src[0]; + sum[1] += xx * Src[1]; + sum[2] += xx * Src[2]; + Src += 3; + } + + DstLine[0] = sum[0]; + DstLine[1] = sum[1]; + DstLine[2] = sum[2]; + + AVIR_RESIZE_PART2 + } else if (ElCount == 2) { + AVIR_RESIZE_PART1 + + fptype sum[2]; + sum[0] = 0.0; + sum[1] = 0.0; + + for (i = 0; i < IntFltLen; i++) { + const fptype xx = ftp[i] + ftp2[i] * x; + sum[0] += xx * Src[0]; + sum[1] += xx * Src[1]; + Src += 2; + } + + DstLine[0] = sum[0]; + DstLine[1] = sum[1]; + + AVIR_RESIZE_PART2 + } + } else { + if (ElCount == 1) { + AVIR_RESIZE_PART1nx + + fptype sum = 0.0; + + for (i = 0; i < IntFltLen; i++) { + sum += ftp[i] * Src[i]; + } + + DstLine[0] = sum; + + AVIR_RESIZE_PART2 + } else if (ElCount == 4) { + AVIR_RESIZE_PART1nx + + fptype sum[4]; + sum[0] = 0.0; + sum[1] = 0.0; + sum[2] = 0.0; + sum[3] = 0.0; + + for (i = 0; i < IntFltLen; i++) { + const fptype xx = ftp[i]; + sum[0] += xx * Src[0]; + sum[1] += xx * Src[1]; + sum[2] += xx * Src[2]; + sum[3] += xx * Src[3]; + Src += 4; + } + + DstLine[0] = sum[0]; + DstLine[1] = sum[1]; + DstLine[2] = sum[2]; + DstLine[3] = sum[3]; + + AVIR_RESIZE_PART2 + } else if (ElCount == 3) { + AVIR_RESIZE_PART1nx + + fptype sum[3]; + sum[0] = 0.0; + sum[1] = 0.0; + sum[2] = 0.0; + + for (i = 0; i < IntFltLen; i++) { + const fptype xx = ftp[i]; + sum[0] += xx * Src[0]; + sum[1] += xx * Src[1]; + sum[2] += xx * Src[2]; + Src += 3; + } + + DstLine[0] = sum[0]; + DstLine[1] = sum[1]; + DstLine[2] = sum[2]; + + AVIR_RESIZE_PART2 + } else if (ElCount == 2) { + AVIR_RESIZE_PART1nx + + fptype sum[2]; + sum[0] = 0.0; + sum[1] = 0.0; + + for (i = 0; i < IntFltLen; i++) { + const fptype xx = ftp[i]; + sum[0] += xx * Src[0]; + sum[1] += xx * Src[1]; + Src += 2; + } + + DstLine[0] = sum[0]; + DstLine[1] = sum[1]; + + AVIR_RESIZE_PART2 + } + } + } +#undef AVIR_RESIZE_PART2 +#undef AVIR_RESIZE_PART1nx +#undef AVIR_RESIZE_PART1 +}; + +/** + * @brief Image resizer's default dithering class. + * + * This class defines an object that performs rounding, clipping and dithering + * operations over horizontal scanline pixels before scanline is stored in the + * output buffer. + * + * The ditherer should expect the same storage order of the pixels in a + * scanline as used in the "filtering step" class. So, a separate ditherer + * class should be defined for each scanline pixel storage style. The default + * ditherer implements a simple rounding without dithering: it can be used for + * an efficient dithering method which can be multi-threaded. + * + * @tparam fptype Floating point type to use for storing pixel data. SIMD + * types can be used. + */ + +template +class CImageResizerDithererDefINL { + public: + /** + * Function initializes the ditherer object. + * + * @param aLen Scanline length in pixels to process. + * @param aVars Image resizing-related variables. + * @param aTrMul Bit-depth truncation multiplier. 1 - no additional + * truncation. + * @param aPkOut Peak output value allowed. + */ + + void init(const int aLen, const CImageResizerVars& aVars, const double aTrMul, + const double aPkOut) { + Len = aLen; + Vars = &aVars; + LenE = aLen * Vars->ElCount; + TrMul0 = aTrMul; + PkOut0 = aPkOut; + } + + /** + * @return "True" if dithering is recursive relative to scanlines meaning + * multi-threaded execution is not supported by this dithering method. + */ + + static bool isRecursive() { return (false); } + + /** + * Function performs rounding and clipping operations. + * + * @param ResScanline The buffer containing the final scanline. + */ + + void dither(fptype* const ResScanline) const { + const fptype c0 = 0.0; + const fptype PkOut = (fptype)PkOut0; + int j; + + if (TrMul0 == 1.0) { + // Optimization - do not perform bit depth truncation. + + for (j = 0; j < LenE; j++) { + ResScanline[j] = clamp(round(ResScanline[j]), c0, PkOut); + } + } else { + const fptype TrMul = (fptype)TrMul0; + + for (j = 0; j < LenE; j++) { + const fptype z0 = round(ResScanline[j] / TrMul) * TrMul; + ResScanline[j] = clamp(z0, c0, PkOut); + } + } + } + + protected: + int Len; ///< Scanline's length in pixels. + ///< + const CImageResizerVars* Vars; ///< Image resizing-related variables. + ///< + int LenE; ///< = LenE * ElCount. + ///< + double TrMul0; ///< Bit-depth truncation multiplier. + ///< + double PkOut0; ///< Peak output value allowed. + ///< +}; + +/** + * @brief Image resizer's error-diffusion dithering class, interleaved mode. + * + * This ditherer implements error-diffusion dithering which looks good, and + * whose results are compressed by PNG well. This implementation uses + * weighting coefficients obtained via machine optimization and visual + * evaluation. + * + * @tparam fptype Floating point type to use for storing pixel data. SIMD + * types can be used. + */ + +template +class CImageResizerDithererErrdINL + : public CImageResizerDithererDefINL { + public: + /** + * Function initializes the ditherer object. + * + * @param aLen Scanline length in pixels to process. + * @param aVars Image resizing-related variables. + * @param aTrMul Bit-depth truncation multiplier. 1 - no additional + * truncation. + * @param aPkOut Peak output value allowed. + */ + + void init(const int aLen, const CImageResizerVars& aVars, const double aTrMul, + const double aPkOut) { + CImageResizerDithererDefINL::init(aLen, aVars, aTrMul, aPkOut); + + ResScanlineDith0.alloc(LenE + Vars->ElCount, sizeof(fptype)); + ResScanlineDith = ResScanlineDith0 + Vars->ElCount; + int i; + + for (i = 0; i < LenE + Vars->ElCount; i++) { + ResScanlineDith0[i] = 0.0; + } + } + + static bool isRecursive() { return (true); } + + void dither(fptype* const ResScanline) { + const int ElCount = Vars->ElCount; + const fptype c0 = 0.0; + const fptype TrMul = (fptype)TrMul0; + const fptype PkOut = (fptype)PkOut0; + int j; + + for (j = 0; j < LenE; j++) { + ResScanline[j] += ResScanlineDith[j]; + ResScanlineDith[j] = 0.0; + } + + for (j = 0; j < LenE - ElCount; j++) { + // Perform rounding, noise estimation and saturation. + + const fptype z0 = round(ResScanline[j] / TrMul) * TrMul; + const fptype Noise = ResScanline[j] - z0; + ResScanline[j] = clamp(z0, c0, PkOut); + + ResScanline[j + ElCount] += Noise * (fptype)0.364842; + ResScanlineDith[j - ElCount] += Noise * (fptype)0.207305; + ResScanlineDith[j] += Noise * (fptype)0.364842; + ResScanlineDith[j + ElCount] += Noise * (fptype)0.063011; + } + + while (j < LenE) { + const fptype z0 = round(ResScanline[j] / TrMul) * TrMul; + const fptype Noise = ResScanline[j] - z0; + ResScanline[j] = clamp(z0, c0, PkOut); + + ResScanlineDith[j - ElCount] += Noise * (fptype)0.207305; + ResScanlineDith[j] += Noise * (fptype)0.364842; + j++; + } + } + + protected: + using CImageResizerDithererDefINL::Len; + using CImageResizerDithererDefINL::Vars; + using CImageResizerDithererDefINL::LenE; + using CImageResizerDithererDefINL::TrMul0; + using CImageResizerDithererDefINL::PkOut0; + + CBuffer ResScanlineDith0; ///< Error diffusion buffer. + ///< + fptype* ResScanlineDith; ///< Error diffusion buffer pointer which skips + ///< the first ElCount elements. + ///< +}; + +/** + * @brief Floating-point processing definition and abstraction class. + * + * This class defines several constants and typedefs that point to classes + * that should be used by the image resizing algorithm. Such "definition + * class" can be used to define alternative scanline processing algorithms + * (e.g. SIMD) and image scanline packing styles used during processing. This + * class also offers an abstraction layer for dithering, rounding and + * clamping (saturation) operation. + * + * The fpclass_def class can be used to define processing using both SIMD and + * non-SIMD types, but using algorithms that are operate on interleaved pixels + * and non-SIMD optimized themselves. + * + * @tparam afptype Floating point type to use for storing intermediate data + * and variables. For variables that are not used in intensive calculations + * the "double" type is always used. On the latest Intel processors (like + * i7-4770K) there is almost no performance difference between "double" and + * "float". Image quality differences between "double" and "float" are not + * apparent on 8-bit images. At the same time the "float" uses half amount of + * working memory the "double" type uses. SIMD types can be used. The + * functions round() and clamp() in the "avir" or other visible namespace + * should be available for the specified type. SIMD types allow to perform + * resizing of images with more than 4 channels, to be exact 4 * SIMD element + * number (e.g. 16 for float4), without modification of the image resizing + * algorithm required. + * @tparam afptypeatom The atomic type the "afptype" consists of. + * @tparam adith Ditherer class to use during processing. + */ + +template > +class fpclass_def { + public: + typedef afptype fptype; ///< Floating-point type to use during processing. + ///< + typedef afptypeatom fptypeatom; ///< Atomic type "fptype" consists of. + ///< + static const int fppack = + sizeof(fptype) / + sizeof(fptypeatom); ///< + ///< The number of atomic types stored in a single + ///< "fptype" element. + ///< + static const int fpalign = + sizeof(fptype); ///< Suggested alignment size + ///< in bytes. This is not a required alignment, because + ///< image resizing algorithm cannot be made to have a + ///< strictly aligned data access at all steps (e.g. + ///< interpolation cannot perform aligned accesses). + ///< + static const int elalign = + 1; ///< Length alignment of arrays of elements. + ///< This applies to filters and intermediate buffers: this constant + ///< forces filters and scanlines to have a length which is a multiple + ///< of this value, for more efficient SIMD implementation. + ///< + static const int packmode = 0; ///< 0 if interleaved packing, 1 if + ///< de-interleaved. + ///< + typedef CImageResizerFilterStepINL + CFilterStep; ///< + ///< Filtering step class to use during processing. + ///< + typedef adith CDitherer; ///< Ditherer class to use during processing. + ///< +}; + +/** + * @brief Image resizer class. + * + * The object of this class can be used to resize 1-4 channel images to any + * required size. Resizing is performed by utilizing interpolated sinc + * fractional delay filters plus (if necessary) a cascade of built-in + * sinc function-based 2X upsampling or 2X downsampling stages, followed by a + * correction filtering. + * + * Object of this class can be allocated on stack. + * + * @tparam fpclass Floating-point processing definition class to use. See + * avir::fpclass_def for more details. + */ + +template > +class CImageResizer { + public: + /** + * Constructor initializes the resizer. + * + * @param aResBitDepth Required bit depth of resulting image (1-16). If + * integer value output is used (e.g. uint8_t), the bit depth also affects + * rounding: for example, if aResBitDepth=6 and "Tout" is uint8_t, the + * result will be rounded to 6 most significant bits (2 least significant + * bits truncated, with dithering applied). + * @param aSrcBitDepth Source image's real bit-depth. Set to 0 to use + * aResBitDepth. + * @param aParams Resizing algorithm's parameters to use. Leave out for + * default values. Can be useful when performing automatic optimization of + * parameters. + */ + + CImageResizer(const int aResBitDepth = 8, const int aSrcBitDepth = 0, + const CImageResizerParams& aParams = CImageResizerParamsDef()) + : Params(aParams), ResBitDepth(aResBitDepth) { + SrcBitDepth = (aSrcBitDepth == 0 ? ResBitDepth : aSrcBitDepth); + + initFilterBank(FixedFilterBank, 1.0, false, CFltBuffer()); + FixedFilterBank.createAllFilters(); + } + + /** + * Function resizes image. + * + * @param SrcBuf Source image buffer. + * @param SrcWidth Source image width. + * @param SrcHeight Source image height. + * @param SrcScanlineSize Physical size of source scanline in elements + * (not bytes). If this value is below 1, SrcWidth * ElCountIO will be + * used as the physical source scanline size. + * @param[out] NewBuf Buffer to accept the resized image. Can be equal to + * SrcBuf if the size of the resized image is smaller or equal to source + * image in size. + * @param NewWidth New image width. + * @param NewHeight New image height. + * @param ElCountIO The number of elements (channels) used to store each + * source and destination pixel (1-4). + * @param k Resizing step (one output pixel corresponds to "k" input + * pixels). A downsizing factor if > 1.0; upsizing factor if <= 1.0. + * Multiply by -1 if you would like to bypass "ox" and "oy" adjustment + * which is done by default to produce a centered image. If step value + * equals 0, the step value will be chosen automatically and independently + * for horizontal and vertical resizing. + * @param[in,out] aVars Pointer to variables structure to be passed to the + * image resizing function. Can be NULL. Only variables that are + * initialized in default constructor of this structure are accepted by + * this function. These variables will not be changed by this function. + * All other variables can be modified by this function. The access to + * this object is not thread-safe, each concurrent instance of this + * function should use a separate aVars object. + * @tparam Tin Input buffer element's type. Can be uint8_t (0-255 value + * range), uint16_t (0-65535 value range), float (0.0-1.0 value range), + * double (0.0-1.0 value range). Larger integer types are treated as + * uint16_t. Signed integer types are unsupported. + * @tparam Tout Output buffer element's type. Can be uint8_t (0-255 value + * range), uint16_t (0-65535 value range), float (0.0-1.0 value range), + * double (0.0-1.0 value range). Larger integer types are treated as + * uint16_t. Signed integer types are unsupported. + */ + + template + void resizeImage(const Tin* const SrcBuf, const int SrcWidth, + const int SrcHeight, int SrcScanlineSize, Tout* const NewBuf, + const int NewWidth, const int NewHeight, const int ElCountIO, + const double k, + CImageResizerVars* const aVars = NULL) const { + if (SrcWidth == 0 || SrcHeight == 0) { + memset(NewBuf, 0, (size_t)NewWidth * NewHeight * sizeof(Tout)); + + return; + } else if (NewWidth == 0 || NewHeight == 0) { + return; + } + + CImageResizerVars DefVars; + CImageResizerVars& Vars = (aVars == NULL ? DefVars : *aVars); + + CImageResizerThreadPool DefThreadPool; + CImageResizerThreadPool& ThreadPool = + (Vars.ThreadPool == NULL ? DefThreadPool : *Vars.ThreadPool); + + // Define resizing steps, also optionally modify offsets so that + // resizing produces a "centered" image. + + double kx; + double ky; + double ox = Vars.ox; + double oy = Vars.oy; + + if (k == 0.0) { + if (NewWidth > SrcWidth) { + kx = (double)(SrcWidth - 1) / (NewWidth - 1); + } else { + kx = (double)SrcWidth / NewWidth; + ox += (kx - 1.0) * 0.5; + } + + if (NewHeight > SrcHeight) { + ky = (double)(SrcHeight - 1) / (NewHeight - 1); + } else { + ky = (double)SrcHeight / NewHeight; + oy += (ky - 1.0) * 0.5; + } + } else if (k > 0.0) { + kx = k; + ky = k; + + if (k > 1.0) { + const double ko = (k - 1.0) * 0.5; + ox += ko; + oy += ko; + } + } else { + kx = -k; + ky = -k; + } + + // Evaluate pre-multipliers used on the output stage. + + const bool IsInFloat = ((Tin)0.4 != 0); + const bool IsOutFloat = ((Tout)0.4 != 0); + double OutMul; // Output multiplier. + + if (Vars.UseSRGBGamma) { + if (IsInFloat) { + Vars.InGammaMult = 1.0; + } else { + Vars.InGammaMult = 1.0 / (sizeof(Tin) == 1 ? 255.0 : 65535.0); + } + + if (IsOutFloat) { + Vars.OutGammaMult = 1.0; + } else { + Vars.OutGammaMult = (sizeof(Tout) == 1 ? 255.0 : 65535.0); + } + + OutMul = 1.0; + } else { + if (IsOutFloat) { + OutMul = 1.0; + } else { + OutMul = (sizeof(Tout) == 1 ? 255.0 : 65535.0); + } + + if (!IsInFloat) { + OutMul /= (sizeof(Tin) == 1 ? 255.0 : 65535.0); + } + } + + // Fill widely-used variables. + + const int ElCount = (ElCountIO + fpclass ::fppack - 1) / fpclass ::fppack; + + const int NewWidthE = NewWidth * ElCount; + + if (SrcScanlineSize < 1) { + SrcScanlineSize = SrcWidth * ElCountIO; + } + + Vars.ElCount = ElCount; + Vars.ElCountIO = ElCountIO; + Vars.fppack = fpclass ::fppack; + Vars.fpalign = fpclass ::fpalign; + Vars.elalign = fpclass ::elalign; + Vars.packmode = fpclass ::packmode; + + // Horizontal scanline filtering and resizing. + + CDSPFracFilterBankLin FltBank; + CFilterSteps FltSteps; + typename CFilterStep ::CRPosBufArray RPosBufArray; + CBuffer UsedFracMap; + + // Perform the filtering steps modeling at various modes, find the + // most efficient mode for both horizontal and vertical resizing. + + int UseBuildMode = 1; + const int BuildModeCount = (FixedFilterBank.getOrder() == 0 ? 4 : 2); + + int m; + + if (Vars.BuildMode >= 0) { + UseBuildMode = Vars.BuildMode; + } else { + int BestScore = 0x7FFFFFFF; + + for (m = 0; m < BuildModeCount; m++) { + CDSPFracFilterBankLin TmpBank; + CFilterSteps TmpSteps; + Vars.k = kx; + Vars.o = ox; + buildFilterSteps(TmpSteps, Vars, TmpBank, OutMul, m, true); + updateFilterStepBuffers(TmpSteps, Vars, RPosBufArray, SrcWidth, + NewWidth); + + fillUsedFracMap(TmpSteps[Vars.ResizeStep], UsedFracMap); + const int c = calcComplexity(TmpSteps, Vars, UsedFracMap, SrcHeight); + + if (c < BestScore) { + UseBuildMode = m; + BestScore = c; + } + } + } + + // Perform the actual filtering steps building. + + Vars.k = kx; + Vars.o = ox; + buildFilterSteps(FltSteps, Vars, FltBank, OutMul, UseBuildMode, false); + + updateFilterStepBuffers(FltSteps, Vars, RPosBufArray, SrcWidth, NewWidth); + + updateBufLenAndRPosPtrs(FltSteps, Vars, NewWidth); + + const int ThreadCount = ThreadPool.getSuggestedWorkloadCount(); + // Includes the current thread. + + CStructArray > td; + td.setItemCount(ThreadCount); + int i; + + for (i = 0; i < ThreadCount; i++) { + if (i > 0) { + ThreadPool.addWorkload(&td[i]); + } + + td[i].init(i, ThreadCount, FltSteps, Vars); + + td[i].initScanlineQueue(td[i].sopResizeH, SrcHeight, SrcWidth); + } + + CBuffer FltBuf( + (size_t)NewWidthE * SrcHeight, + fpclass ::fpalign); // Temporary buffer that receives + // horizontally-filtered and resized image. + + for (i = 0; i < SrcHeight; i++) { + td[i % ThreadCount].addScanlineToQueue( + (void*)&SrcBuf[(size_t)i * SrcScanlineSize], + &FltBuf[(size_t)i * NewWidthE]); + } + + ThreadPool.startAllWorkloads(); + td[0].processScanlineQueue(); + ThreadPool.waitAllWorkloadsToFinish(); + + // Vertical scanline filtering and resizing, reuse previously defined + // filtering steps if possible. + + const int PrevUseBuildMode = UseBuildMode; + + if (Vars.BuildMode >= 0) { + UseBuildMode = Vars.BuildMode; + } else { + CImageResizerVars TmpVars(Vars); + int BestScore = 0x7FFFFFFF; + + for (m = 0; m < BuildModeCount; m++) { + CDSPFracFilterBankLin TmpBank; + TmpBank.copyInitParams(FltBank); + CFilterSteps TmpSteps; + TmpVars.k = ky; + TmpVars.o = oy; + buildFilterSteps(TmpSteps, TmpVars, TmpBank, 1.0, m, true); + updateFilterStepBuffers(TmpSteps, TmpVars, RPosBufArray, SrcHeight, + NewHeight); + + fillUsedFracMap(TmpSteps[TmpVars.ResizeStep], UsedFracMap); + + const int c = calcComplexity(TmpSteps, TmpVars, UsedFracMap, NewWidth); + + if (c < BestScore) { + UseBuildMode = m; + BestScore = c; + } + } + } + + Vars.k = ky; + Vars.o = oy; + + if (UseBuildMode == PrevUseBuildMode && ky == kx) { + if (OutMul != 1.0) { + modifyCorrFilterDCGain(FltSteps, 1.0 / OutMul); + } + } else { + buildFilterSteps(FltSteps, Vars, FltBank, 1.0, UseBuildMode, false); + } + + updateFilterStepBuffers(FltSteps, Vars, RPosBufArray, SrcHeight, NewHeight); + + updateBufLenAndRPosPtrs(FltSteps, Vars, NewWidth); + + if (IsOutFloat && sizeof(FltBuf[0]) == sizeof(Tout) && + fpclass ::packmode == 0) { + // In-place output. + + for (i = 0; i < ThreadCount; i++) { + td[i].initScanlineQueue(td[i].sopResizeV, NewWidth, SrcHeight, + NewWidthE, NewWidthE); + } + + for (i = 0; i < NewWidth; i++) { + td[i % ThreadCount].addScanlineToQueue( + &FltBuf[(size_t)i * ElCount], + (fptype*)&NewBuf[(size_t)i * ElCount]); + } + + ThreadPool.startAllWorkloads(); + td[0].processScanlineQueue(); + ThreadPool.waitAllWorkloadsToFinish(); + ThreadPool.removeAllWorkloads(); + + return; + } + + CBuffer ResBuf((size_t)NewWidthE * NewHeight, + fpclass ::fpalign); + + for (i = 0; i < ThreadCount; i++) { + td[i].initScanlineQueue(td[i].sopResizeV, NewWidth, SrcHeight, NewWidthE, + NewWidthE); + } + + const int im = (fpclass ::packmode == 0 ? ElCount : 1); + + for (i = 0; i < NewWidth; i++) { + td[i % ThreadCount].addScanlineToQueue(&FltBuf[(size_t)i * im], + &ResBuf[(size_t)i * im]); + } + + ThreadPool.startAllWorkloads(); + td[0].processScanlineQueue(); + ThreadPool.waitAllWorkloadsToFinish(); + + if (IsOutFloat) { + // Perform output, but skip dithering. + + for (i = 0; i < ThreadCount; i++) { + td[i].initScanlineQueue(td[i].sopUnpackH, NewHeight, NewWidth); + } + + for (i = 0; i < NewHeight; i++) { + td[i % ThreadCount].addScanlineToQueue( + &ResBuf[(size_t)i * NewWidthE], + &NewBuf[(size_t)i * NewWidth * ElCountIO]); + } + + ThreadPool.startAllWorkloads(); + td[0].processScanlineQueue(); + ThreadPool.waitAllWorkloadsToFinish(); + ThreadPool.removeAllWorkloads(); + + return; + } + + // Perform output with dithering (for integer output only). + + int TruncBits; // The number of lower bits to truncate and dither. + int OutRange; // Output range. + + if (sizeof(Tout) == 1) { + TruncBits = 8 - ResBitDepth; + OutRange = 255; + } else { + TruncBits = 16 - ResBitDepth; + OutRange = 65535; + } + + const double PkOut = OutRange; + const double TrMul = + (TruncBits > 0 ? PkOut / (OutRange >> TruncBits) : 1.0); + + if (CDitherer ::isRecursive()) { + td[0].getDitherer().init(NewWidth, Vars, TrMul, PkOut); + + if (Vars.UseSRGBGamma) { + for (i = 0; i < NewHeight; i++) { + fptype* const ResScanline = &ResBuf[(size_t)i * NewWidthE]; + + CFilterStep ::applySRGBGamma(ResScanline, NewWidth, Vars); + + td[0].getDitherer().dither(ResScanline); + + CFilterStep ::unpackScanline( + ResScanline, &NewBuf[(size_t)i * NewWidth * ElCountIO], NewWidth, + Vars); + } + } else { + for (i = 0; i < NewHeight; i++) { + fptype* const ResScanline = &ResBuf[(size_t)i * NewWidthE]; + + td[0].getDitherer().dither(ResScanline); + + CFilterStep ::unpackScanline( + ResScanline, &NewBuf[(size_t)i * NewWidth * ElCountIO], NewWidth, + Vars); + } + } + } else { + for (i = 0; i < ThreadCount; i++) { + td[i].initScanlineQueue(td[i].sopDitherAndUnpackH, NewHeight, NewWidth); + + td[i].getDitherer().init(NewWidth, Vars, TrMul, PkOut); + } + + for (i = 0; i < NewHeight; i++) { + td[i % ThreadCount].addScanlineToQueue( + &ResBuf[(size_t)i * NewWidthE], + &NewBuf[(size_t)i * NewWidth * ElCountIO]); + } + + ThreadPool.startAllWorkloads(); + td[0].processScanlineQueue(); + ThreadPool.waitAllWorkloadsToFinish(); + } + + ThreadPool.removeAllWorkloads(); + } + + private: + typedef typename fpclass ::fptype fptype; ///< Floating-point type to use + ///< during processing. + ///< + typedef typename fpclass ::CFilterStep + CFilterStep; ///< Filtering step + ///< class to use during processing. + ///< + typedef typename fpclass ::CDitherer CDitherer; ///< Ditherer class to + ///< use during processing. + ///< + CImageResizerParams Params; ///< Algorithm's parameters currently in use. + ///< + int SrcBitDepth; ///< Bit resolution of the source image. + ///< + int ResBitDepth; ///< Bit resolution of the resulting image. + ///< + CDSPFracFilterBankLin + FixedFilterBank; ///< Fractional delay + ///< filter bank with fixed characteristics, mainly for + ///< upsizing cases. + ///< + + /** + * @brief Filtering steps array. + * + * The object of this class stores filtering steps together. + */ + + typedef CStructArray CFilterSteps; + + /** + * Function initializes the filter bank in the specified resizing step + * according to the source and resulting image bit depths. + * + * @param FltBank Filter bank to initialize. + * @param CutoffMult Cutoff multiplier, 0 to 1. 1 corresponds to 0.5pi + * cutoff point. + * @param ForceHiOrder "True" if a high-order interpolation should be + * forced which requires considerably less resources for initialization. + * @param ExtFilter External filter to apply to interpolation filter. + */ + + void initFilterBank(CDSPFracFilterBankLin& FltBank, + const double CutoffMult, const bool ForceHiOrder, + const CFltBuffer& ExtFilter) const { + const int IntBitDepth = + (ResBitDepth > SrcBitDepth ? ResBitDepth : SrcBitDepth); + + const double SNR = -6.02 * (IntBitDepth + 3); + int UseOrder; + int FracCount; // The number of fractional delay filters sampled by + // the filter bank. This variable affects the + // signal-to-noise ratio at interpolation stage. + // Theoretically, at UseOrder==1, 8-bit image resizing + // requires 66.2 dB SNR or 11. 16-bit resizing requires + // 114.4 dB SNR or 150. At UseOrder=0 the required number of + // filters is exponentially higher. + + if (ForceHiOrder || IntBitDepth > 8) { + UseOrder = 1; // -146 dB max + FracCount = (int)ceil(0.23134052 * exp(-0.058062929 * SNR)); + } else { + UseOrder = 0; // -72 dB max + FracCount = (int)ceil(0.33287686 * exp(-0.11334583 * SNR)); + } + + if (FracCount < 2) { + FracCount = 2; + } + + FltBank.init(FracCount, UseOrder, Params.IntFltLen / CutoffMult, + Params.IntFltCutoff * CutoffMult, Params.IntFltAlpha, + ExtFilter, fpclass ::fpalign, fpclass ::elalign); + } + + /** + * Function allocates filter buffer taking "fpclass" alignments into + * account. The allocated buffer may be larger than the requested size: in + * this case the additional elements will be zeroed by this function. + * + * @param Flt Filter buffer. + * @param ReqCapacity The required filter buffer's capacity. + * @param IsModel "True" if filtering steps modeling is performed without + * actual filter allocation. + * @param FltExt If non-NULL this variable will receive the number of + * elements the filter was extended by. + */ + + static void allocFilter(CBuffer& Flt, const int ReqCapacity, + const bool IsModel = false, + int* const FltExt = NULL) { + int UseCapacity = + (ReqCapacity + fpclass ::elalign - 1) & ~(fpclass ::elalign - 1); + + int Ext = UseCapacity - ReqCapacity; + + if (FltExt != NULL) { + *FltExt = Ext; + } + + if (IsModel) { + Flt.forceCapacity(UseCapacity); + return; + } + + Flt.alloc(UseCapacity, fpclass ::fpalign); + + while (Ext > 0) { + Ext--; + Flt[ReqCapacity + Ext] = 0.0; + } + } + + /** + * Function assigns filter parameters to the specified filtering step + * object. + * + * @param fs Filtering step to assign parameter to. This step cannot be + * the last step if ResampleFactor greater than 1 was specified. + * @param IsUpsample "True" if upsampling step. Should be set to "false" + * if FltCutoff is negative. + * @param ResampleFactor Resampling factor of this filter (>=1). + * @param FltCutoff Filter cutoff point. This value will be divided by the + * ResampleFactor if IsUpsample equals "true". If zero value was + * specified, the "half-band" predefined filter will be created. In this + * case the ResampleFactor will modify the filter cutoff point. + * @param DCGain DC gain to apply to the filter. Assigned to filtering + * step's DCGain variable. + * @param UseFltOrig "True" if the originally-designed filter should be + * left in filtering step's FltOrig buffer. Otherwise it will be freed. + * @param IsModel "True" if filtering steps modeling is performed without + * actual filter building. + */ + + void assignFilterParams(CFilterStep& fs, const bool IsUpsample, + const int ResampleFactor, const double FltCutoff, + const double DCGain, const bool UseFltOrig, + const bool IsModel) const { + double FltAlpha; + double Len2; + double Freq; + + if (FltCutoff == 0.0) { + const double m = 2.0 / ResampleFactor; + FltAlpha = Params.HBFltAlpha; + Len2 = 0.5 * Params.HBFltLen / m; + Freq = AVIR_PI * Params.HBFltCutoff * m; + } else { + FltAlpha = Params.LPFltAlpha; + Len2 = 0.25 * Params.LPFltBaseLen / FltCutoff; + Freq = AVIR_PI * Params.LPFltCutoffMult * FltCutoff; + } + + if (IsUpsample) { + Len2 *= ResampleFactor; + Freq /= ResampleFactor; + fs.DCGain = DCGain * ResampleFactor; + } else { + fs.DCGain = DCGain; + } + + fs.FltOrig.Len2 = Len2; + fs.FltOrig.Freq = Freq; + fs.FltOrig.Alpha = FltAlpha; + fs.FltOrig.DCGain = fs.DCGain; + + CDSPPeakedCosineLPF w(Len2, Freq, FltAlpha); + + fs.IsUpsample = IsUpsample; + fs.ResampleFactor = ResampleFactor; + fs.FltLatency = w.fl2; + + int FltExt; // Filter's extension due to fpclass :: elalign. + + if (IsModel) { + allocFilter(fs.Flt, w.FilterLen, true, &FltExt); + + if (UseFltOrig) { + // Allocate a real buffer even in modeling mode since this + // filter may be copied by the filter bank. + + fs.FltOrig.alloc(w.FilterLen); + memset(&fs.FltOrig[0], 0, w.FilterLen * sizeof(fs.FltOrig[0])); + } + } else { + fs.FltOrig.alloc(w.FilterLen); + + w.generateLPF(&fs.FltOrig[0], 1.0); + optimizeFIRFilter(fs.FltOrig, fs.FltLatency); + normalizeFIRFilter(&fs.FltOrig[0], fs.FltOrig.getCapacity(), fs.DCGain); + + allocFilter(fs.Flt, fs.FltOrig.getCapacity(), false, &FltExt); + copyArray(&fs.FltOrig[0], &fs.Flt[0], fs.FltOrig.getCapacity()); + + if (!UseFltOrig) { + fs.FltOrig.free(); + } + } + + if (IsUpsample) { + int l = fs.Flt.getCapacity() - fs.FltLatency - ResampleFactor - FltExt; + + allocFilter(fs.PrefixDC, l, IsModel); + allocFilter(fs.SuffixDC, fs.FltLatency, IsModel); + + if (IsModel) { + return; + } + + // Create prefix and suffix "tails" used during upsampling. + + const fptype* ip = &fs.Flt[fs.FltLatency + ResampleFactor]; + copyArray(ip, &fs.PrefixDC[0], l); + + while (true) { + ip += ResampleFactor; + l -= ResampleFactor; + + if (l <= 0) { + break; + } + + addArray(ip, &fs.PrefixDC[0], l); + } + + l = fs.FltLatency; + fptype* op = &fs.SuffixDC[0]; + copyArray(&fs.Flt[0], op, l); + + while (true) { + op += ResampleFactor; + l -= ResampleFactor; + + if (l <= 0) { + break; + } + + addArray(&fs.Flt[0], op, l); + } + } else if (!UseFltOrig) { + fs.EdgePixelCount = fs.EdgePixelCountDef; + } + } + + /** + * Function adds a correction filter that tries to achieve a linear + * frequency response at all frequencies. The actual resulting response + * may feature a slight damping of the highest frequencies since a + * suitably short correction filter cannot fix steep high-frequency + * damping. + * + * This function assumes that the resizing step is currently the last + * step, even if it was not inserted yet: this allows placement of the + * correction filter both before and after the resizing step. + * + * @param Steps Filtering steps. + * @param bw Resulting bandwidth relative to the original bandwidth (which + * is 1.0), usually 1/k. Should be <= 1.0. + * @param IsPreCorrection "True" if the filtering step was already created + * and it is first in the Steps array. "True" also adds edge pixels to + * reduce edge artifacts. + * @param IsModel "True" if filtering steps modeling is performed without + * actual filter building. + */ + + void addCorrectionFilter(CFilterSteps& Steps, const double bw, + const bool IsPreCorrection, + const bool IsModel) const { + CFilterStep& fs = (IsPreCorrection ? Steps[0] : Steps.add()); + fs.IsUpsample = false; + fs.ResampleFactor = 1; + fs.DCGain = 1.0; + fs.EdgePixelCount = (IsPreCorrection ? fs.EdgePixelCountDef : 0); + + if (IsModel) { + allocFilter( + fs.Flt, + CDSPFIREQ ::calcFilterLength(Params.CorrFltLen, fs.FltLatency), true); + + return; + } + + const int BinCount = 65; // Frequency response bins to control. + const int BinCount1 = BinCount - 1; + double curbw = 1.0; // Bandwidth of the filter at the current step. + int i; + int j; + double re; + double im; + + CBuffer Bins(BinCount); // Adjustment introduced by all + // steps at all frequencies of interest. + + for (j = 0; j < BinCount; j++) { + Bins[j] = 1.0; + } + + const int si = (IsPreCorrection ? 1 : 0); + + for (i = si; i < Steps.getItemCount() - (si ^ 1); i++) { + const CFilterStep& fs = Steps[i]; + + if (fs.IsUpsample) { + curbw *= fs.ResampleFactor; + + if (fs.FltOrig.getCapacity() > 0) { + continue; + } + } + + const double dcg = 1.0 / fs.DCGain; // DC gain correction. + const fptype* Flt; + int FltLen; + + if (fs.ResampleFactor == 0) { + Flt = fs.FltBank->getFilter(0); + FltLen = fs.FltBank->getFilterLen(); + } else { + Flt = &fs.Flt[0]; + FltLen = fs.Flt.getCapacity(); + } + + // Calculate frequency response adjustment introduced by the + // filter at this step, within the bounds of bandwidth of + // interest. + + for (j = 0; j < BinCount; j++) { + const double th = AVIR_PI * bw / curbw * j / BinCount1; + + calcFIRFilterResponse(Flt, FltLen, th, re, im); + + Bins[j] /= sqrt(re * re + im * im) * dcg; + } + + if (!fs.IsUpsample && fs.ResampleFactor > 1) { + curbw /= fs.ResampleFactor; + } + } + + // Calculate filter. + + CDSPFIREQ EQ; + EQ.init(bw * 2.0, Params.CorrFltLen, BinCount, 0.0, bw, false, + Params.CorrFltAlpha); + + fs.FltLatency = EQ.getFilterLatency(); + + CBuffer Filter(EQ.getFilterLength()); + EQ.buildFilter(Bins, &Filter[0]); + normalizeFIRFilter(&Filter[0], Filter.getCapacity(), 1.0); + optimizeFIRFilter(Filter, fs.FltLatency); + normalizeFIRFilter(&Filter[0], Filter.getCapacity(), 1.0); + + allocFilter(fs.Flt, Filter.getCapacity()); + copyArray(&Filter[0], &fs.Flt[0], Filter.getCapacity()); + + // Print a theoretically achieved final frequency response at various + // feature sizes (from DC to 1 pixel). Values above 255 means features + // become brighter, values below 255 means features become dimmer. + + /* const double sbw = ( bw > 1.0 ? 1.0 / bw : 1.0 ); + + for( j = 0; j < BinCount; j++ ) + { + const double th = AVIR_PI * sbw * j / BinCount1; + + calcFIRFilterResponse( &fs.Flt[ 0 ], + fs.Flt.getCapacity(), th, re, im ); + + printf( "%f\n", sqrt( re * re + im * im ) / Bins[ j + ] * 255 ); + } + + printf( "***\n" );*/ + } + + /** + * Function adds a sharpening filter if image is being upsized. Such + * sharpening allows to spot interpolation filter's stop-band attenuation: + * if attenuation is too weak, a "dark grid" and other artifacts may + * become visible. + * + * It is assumed that 40 decibel stop-band attenuation should be + * considered a required minimum: this allows application of (deliberately + * strong) 64X sharpening without spotting any artifacts. + * + * @param Steps Filtering steps. + * @param bw Resulting bandwidth relative to the original bandwidth (which + * is 1.0), usually 1/k. + * @param IsModel "True" if filtering steps modeling is performed without + * actual filter building. + */ + + static void addSharpenTest(CFilterSteps& Steps, const double bw, + const bool IsModel) { + if (bw <= 1.0) { + return; + } + + const double FltLen = 10.0 * bw; + + CFilterStep& fs = Steps.add(); + fs.IsUpsample = false; + fs.ResampleFactor = 1; + fs.DCGain = 1.0; + fs.EdgePixelCount = 0; + + if (IsModel) { + allocFilter(fs.Flt, CDSPFIREQ ::calcFilterLength(FltLen, fs.FltLatency), + true); + + return; + } + + const int BinCount = 200; + CBuffer Bins(BinCount); + int Thresh = (int)round(BinCount / bw * 1.75); + + if (Thresh > BinCount) { + Thresh = BinCount; + } + + int j; + + for (j = 0; j < Thresh; j++) { + Bins[j] = 1.0; + } + + for (j = Thresh; j < BinCount; j++) { + Bins[j] = 256.0; + } + + CDSPFIREQ EQ; + EQ.init(bw * 2.0, FltLen, BinCount, 0.0, bw, false, 1.7); + + fs.FltLatency = EQ.getFilterLatency(); + + CBuffer Filter(EQ.getFilterLength()); + EQ.buildFilter(Bins, &Filter[0]); + normalizeFIRFilter(&Filter[0], Filter.getCapacity(), 1.0); + optimizeFIRFilter(Filter, fs.FltLatency); + normalizeFIRFilter(&Filter[0], Filter.getCapacity(), 1.0); + + allocFilter(fs.Flt, Filter.getCapacity()); + copyArray(&Filter[0], &fs.Flt[0], Filter.getCapacity()); + + /* for( j = 0; j < BinCount; j++ ) + { + const double th = AVIR_PI * j / ( BinCount - 1 ); + double re; + double im; + + calcFIRFilterResponse( &fs.Flt[ 0 ], + fs.Flt.getCapacity(), th, re, im ); + + printf( "%f\n", sqrt( re * re + im * im )); + } + + printf( "***\n" );*/ + } + + /** + * Function builds sequence of filtering steps depending on the specified + * resizing coefficient. The last steps included are always the resizing + * step then (possibly) the correction step. + * + * @param Steps Array that receives filtering steps. + * @param[out] Vars Variables object. + * @param FltBank Filter bank to initialize and use. + * @param DCGain The overall DC gain to apply. This DC gain is applied to + * the first filtering step only (upsampling or filtering step). + * @param ModeFlags Build mode flags to use. This is a bitmap of switches + * that enable or disable certain algorithm features. + * @param IsModel "True" if filtering steps modeling is performed without + * the actual filter allocation and building. + */ + + void buildFilterSteps(CFilterSteps& Steps, CImageResizerVars& Vars, + CDSPFracFilterBankLin& FltBank, + const double DCGain, const int ModeFlags, + const bool IsModel) const { + Steps.clear(); + + const bool DoFltAndIntCombo = + ((ModeFlags & 1) != 0); // Do filter + // and interpolator combining. + const bool ForceHiOrderInt = + ((ModeFlags & 2) != 0); // Force use + // of a higher-order interpolation. + const bool UseHalfband = ((ModeFlags & 4) != 0); // Use half-band + // filter. + + const double bw = 1.0 / Vars.k; // Resulting bandwidth. + const int UpsampleFactor = ((int)floor(Vars.k) < 2 ? 2 : 1); + double IntCutoffMult; // Interpolation filter cutoff multiplier. + CFilterStep* ReuseStep; // If not NULL, resizing step should use + // this step object instead of creating a new one. + CFilterStep* ExtFltStep; // Use FltOrig of this step as the external + // filter to applied to the interpolator. + bool IsPreCorrection; // "True" if the correction filter is applied + // first. + double FltCutoff; // Cutoff frequency of the first filtering step. + double corrbw; ///< Bandwidth at the correction step. + + if (Vars.k <= 1.0) { + IsPreCorrection = true; + FltCutoff = 1.0; + corrbw = 1.0; + Steps.add(); + } else { + IsPreCorrection = false; + FltCutoff = bw; + corrbw = bw; + } + + // Add 1 upsampling or several downsampling filters. + + if (UpsampleFactor > 1) { + CFilterStep& fs = Steps.add(); + assignFilterParams(fs, true, UpsampleFactor, FltCutoff, DCGain, + DoFltAndIntCombo, IsModel); + + IntCutoffMult = FltCutoff * 2.0 / UpsampleFactor; + ReuseStep = NULL; + ExtFltStep = (DoFltAndIntCombo ? &fs : NULL); + } else { + int DownsampleFactor; + + while (true) { + DownsampleFactor = (int)floor(0.5 / FltCutoff); + bool DoHBFltAdd; + + if (DownsampleFactor > 16) { + // Add half-band filter unconditionally in order to keep + // filter lengths lower for more precise frequency + // response and less edge artifacts. + + DoHBFltAdd = true; + DownsampleFactor = 16; + } else { + DoHBFltAdd = (UseHalfband && DownsampleFactor > 1); + } + + if (DoHBFltAdd) { + assignFilterParams(Steps.add(), false, DownsampleFactor, 0.0, 1.0, + false, IsModel); + + FltCutoff *= DownsampleFactor; + } else { + if (DownsampleFactor < 1) { + DownsampleFactor = 1; + } + + break; + } + } + + CFilterStep& fs = Steps.add(); + assignFilterParams(fs, false, DownsampleFactor, FltCutoff, DCGain, + DoFltAndIntCombo, IsModel); + + IntCutoffMult = FltCutoff / 0.5; + + if (DoFltAndIntCombo) { + ReuseStep = &fs; + ExtFltStep = &fs; + } else { + IntCutoffMult *= DownsampleFactor; + ReuseStep = NULL; + ExtFltStep = NULL; + } + } + + // Insert resizing and correction steps. + + CFilterStep& fs = (ReuseStep == NULL ? Steps.add() : *ReuseStep); + + Vars.ResizeStep = Steps.getItemCount() - 1; + fs.IsUpsample = false; + fs.ResampleFactor = 0; + fs.DCGain = (ExtFltStep == NULL ? 1.0 : ExtFltStep->DCGain); + + initFilterBank(FltBank, IntCutoffMult, ForceHiOrderInt, + (ExtFltStep == NULL ? fs.FltOrig : ExtFltStep->FltOrig)); + + if (FltBank == FixedFilterBank) { + fs.FltBank = (CDSPFracFilterBankLin*)&FixedFilterBank; + } else { + fs.FltBank = &FltBank; + } + + addCorrectionFilter(Steps, corrbw, IsPreCorrection, IsModel); + + // addSharpenTest( Steps, bw, IsModel ); + } + + /** + * Function extends *this upsampling step so that it produces more + * upsampled pixels that cover the prefix and suffix needs of the next + * step. After the call to this function the InPrefix and InSuffix + * variables of the next step will be set to zero. + * + * @param fs Upsampling filtering step. + * @param NextStep The next step structure. + */ + + static void extendUpsample(CFilterStep& fs, CFilterStep& NextStep) { + fs.InPrefix = + (NextStep.InPrefix + fs.ResampleFactor - 1) / fs.ResampleFactor; + + fs.OutPrefix += fs.InPrefix * fs.ResampleFactor; + NextStep.InPrefix = 0; + + fs.InSuffix = + (NextStep.InSuffix + fs.ResampleFactor - 1) / fs.ResampleFactor; + + fs.OutSuffix += fs.InSuffix * fs.ResampleFactor; + NextStep.InSuffix = 0; + } + + /** + * Function fills resizing step's RPosBuf array, excluding the actual + * "ftp" pointers and "SrcOffs" offsets. + * + * This array should be cleared if the resizing step or offset were + * changed. Otherwise this function only fills the elements required to + * cover resizing step's OutLen. + * + * This function is called by the updateFilterStepBuffers() function. + * + * @param fs Resizing step. + * @param Vars Variables object. + */ + + static void fillRPosBuf(CFilterStep& fs, const CImageResizerVars& Vars) { + const int PrevLen = fs.RPosBuf->getCapacity(); + + if (fs.OutLen > PrevLen) { + fs.RPosBuf->increaseCapacity(fs.OutLen); + } + + typename CFilterStep ::CResizePos* rpos = &(*fs.RPosBuf)[PrevLen]; + const int FracCount = fs.FltBank->getFracCount(); + const double o = Vars.o; + const double k = Vars.k; + int i; + + for (i = PrevLen; i < fs.OutLen; i++) { + const double SrcPos = o + k * i; + const int SrcPosInt = (int)floor(SrcPos); + const double x = (SrcPos - SrcPosInt) * FracCount; + const int fti = (int)x; + rpos->x = (typename fpclass ::fptypeatom)(x - fti); + rpos->fti = fti; + rpos->SrcPosInt = SrcPosInt; + rpos++; + } + } + + /** + * Function updates filtering step buffer lengths depending on the + * specified source and new scanline lengths. This function should be + * called after the buildFilterSteps() function. + * + * @param Steps Array that receives filtering steps. + * @param[out] Vars Variables object, will receive buffer size and length. + * This function expects "k" and "o" variable values that will be + * adjusted by this function. + * @param RPosBufArray Resizing position buffers array, used to obtain + * buffer to initialize and use (will be reused if it is already fully or + * partially filled). + * @param SrcLen Source scanline's length in pixels. + * @param NewLen New scanline's length in pixels. + */ + + static void updateFilterStepBuffers( + CFilterSteps& Steps, CImageResizerVars& Vars, + typename CFilterStep ::CRPosBufArray& RPosBufArray, int SrcLen, + const int NewLen) { + int upstep = -1; + int InBuf = 0; + int i; + + for (i = 0; i < Steps.getItemCount(); i++) { + CFilterStep& fs = Steps[i]; + + fs.Vars = &Vars; + fs.InLen = SrcLen; + fs.InBuf = InBuf; + fs.OutBuf = (InBuf + 1) & 1; + + if (fs.IsUpsample) { + upstep = i; + Vars.k *= fs.ResampleFactor; + Vars.o *= fs.ResampleFactor; + fs.InPrefix = 0; + fs.InSuffix = 0; + fs.OutLen = fs.InLen * fs.ResampleFactor; + fs.OutPrefix = fs.FltLatency; + fs.OutSuffix = fs.Flt.getCapacity() - fs.FltLatency - fs.ResampleFactor; + + int l0 = fs.OutPrefix + fs.OutLen + fs.OutSuffix; + int l = fs.InLen * fs.ResampleFactor + fs.SuffixDC.getCapacity(); + + if (l > l0) { + fs.OutSuffix += l - l0; + } + + l0 = fs.OutLen + fs.OutSuffix; + + if (fs.PrefixDC.getCapacity() > l0) { + fs.OutSuffix += fs.PrefixDC.getCapacity() - l0; + } + } else if (fs.ResampleFactor == 0) { + const int FilterLenD2 = fs.FltBank->getFilterLen() / 2; + const int FilterLenD21 = FilterLenD2 - 1; + + const int ResizeLPix = (int)floor(Vars.o) - FilterLenD21; + fs.InPrefix = (ResizeLPix < 0 ? -ResizeLPix : 0); + const int ResizeRPix = + (int)floor(Vars.o + (NewLen - 1) * Vars.k) + FilterLenD2 + 1; + + fs.InSuffix = (ResizeRPix > fs.InLen ? ResizeRPix - fs.InLen : 0); + + fs.OutLen = NewLen; + fs.RPosBuf = &RPosBufArray.getRPosBuf(Vars.k, Vars.o, + fs.FltBank->getFracCount()); + + fillRPosBuf(fs, Vars); + } else { + Vars.k /= fs.ResampleFactor; + Vars.o /= fs.ResampleFactor; + Vars.o += fs.EdgePixelCount; + + fs.InPrefix = fs.FltLatency; + fs.InSuffix = fs.Flt.getCapacity() - fs.FltLatency - 1; + + // Additionally extend OutLen to produce more precise edge + // pixels. + + fs.OutLen = (fs.InLen + fs.ResampleFactor - 1) / fs.ResampleFactor + + fs.EdgePixelCount; + + fs.InSuffix += (fs.OutLen - 1) * fs.ResampleFactor + 1 - fs.InLen; + + fs.InPrefix += fs.EdgePixelCount * fs.ResampleFactor; + fs.OutLen += fs.EdgePixelCount; + } + + InBuf = fs.OutBuf; + SrcLen = fs.OutLen; + } + + Steps[Steps.getItemCount() - 1].OutBuf = 2; + + if (upstep != -1) { + extendUpsample(Steps[upstep], Steps[upstep + 1]); + } + } + + /** + * Function calculates an optimal intermediate buffer length that will + * cover all needs of the specified filtering steps. This function should + * be called after the updateFilterStepBuffers() function. + * + * Function also updates resizing step's RPosBuf pointers to the filter + * bank and SrcOffs values. + * + * @param Steps Filtering steps. + * @param[out] Vars Variables object, will receive buffer size and length. + * @param ResElIncr Resulting (final) element increment, used to produce + * de-interleaved result. For horizontal processing this value is equal + * to last step's OutLen, for vertical processing this value is equal to + * resulting image's width. + */ + + static void updateBufLenAndRPosPtrs(CFilterSteps& Steps, + CImageResizerVars& Vars, + const int ResElIncr) { + int MaxPrefix[2] = {0, 0}; + int MaxLen[2] = {0, 0}; + int i; + + for (i = 0; i < Steps.getItemCount(); i++) { + CFilterStep& fs = Steps[i]; + const int ib = fs.InBuf; + + if (fs.InPrefix > MaxPrefix[ib]) { + MaxPrefix[ib] = fs.InPrefix; + } + + int l = fs.InLen + fs.InSuffix; + + if (l > MaxLen[ib]) { + MaxLen[ib] = l; + } + + fs.InElIncr = fs.InPrefix + l; + + if (fs.OutBuf == 2) { + break; + } + + const int ob = fs.OutBuf; + + if (fs.IsUpsample) { + if (fs.OutPrefix > MaxPrefix[ob]) { + MaxPrefix[ob] = fs.OutPrefix; + } + + l = fs.OutLen + fs.OutSuffix; + + if (l > MaxLen[ob]) { + MaxLen[ob] = l; + } + } else { + if (fs.OutLen > MaxLen[ob]) { + MaxLen[ob] = fs.OutLen; + } + } + } + + // Update OutElIncr values of all steps. + + for (i = 0; i < Steps.getItemCount(); i++) { + CFilterStep& fs = Steps[i]; + + if (fs.OutBuf == 2) { + fs.OutElIncr = ResElIncr; + break; + } + + CFilterStep& fs2 = Steps[i + 1]; + + if (fs.IsUpsample) { + fs.OutElIncr = fs.OutPrefix + fs.OutLen + fs.OutSuffix; + + if (fs.OutElIncr > fs2.InElIncr) { + fs2.InElIncr = fs.OutElIncr; + } else { + fs.OutElIncr = fs2.InElIncr; + } + } else { + fs.OutElIncr = fs2.InElIncr; + } + } + + // Update temporary buffer's length. + + for (i = 0; i < 2; i++) { + Vars.BufLen[i] = MaxPrefix[i] + MaxLen[i]; + Vars.BufOffs[i] = MaxPrefix[i]; + + if (Vars.packmode == 0) { + Vars.BufOffs[i] *= Vars.ElCount; + } + + Vars.BufLen[i] *= Vars.ElCount; + } + + // Update RPosBuf pointers and SrcOffs. + + CFilterStep& fs = Steps[Vars.ResizeStep]; + typename CFilterStep ::CResizePos* rpos = &(*fs.RPosBuf)[0]; + const int em = (fpclass ::packmode == 0 ? Vars.ElCount : 1); + const int FilterLenD21 = fs.FltBank->getFilterLen() / 2 - 1; + + for (i = 0; i < fs.OutLen; i++) { + rpos->ftp = fs.FltBank->getFilter(rpos->fti); + rpos->SrcOffs = (rpos->SrcPosInt - FilterLenD21) * em; + rpos++; + } + } + + /** + * Function modifies the overall (DC) gain of the correction filter in the + * pre-built filtering steps array. + * + * @param Steps Filtering steps. + * @param m Multiplier to apply to the correction filter. + */ + + void modifyCorrFilterDCGain(CFilterSteps& Steps, const double m) const { + CBuffer* Flt; + const int z = Steps.getItemCount() - 1; + + if (!Steps[z].IsUpsample && Steps[z].ResampleFactor == 1) { + Flt = &Steps[z].Flt; + } else { + Flt = &Steps[0].Flt; + } + + int i; + + for (i = 0; i < Flt->getCapacity(); i++) { + (*Flt)[i] = (fptype)((double)(*Flt)[i] * m); + } + } + + /** + * Function builds a map of used fractional delay filters based on the + * resizing positions buffer. + * + * @param fs Resizing step. + * @param[out] UsedFracMap Map of used fractional delay filters. + */ + + static void fillUsedFracMap(const CFilterStep& fs, + CBuffer& UsedFracMap) { + const int FracCount = fs.FltBank->getFracCount(); + UsedFracMap.increaseCapacity(FracCount, false); + memset(&UsedFracMap[0], 0, FracCount * sizeof(UsedFracMap[0])); + + typename CFilterStep ::CResizePos* rpos = &(*fs.RPosBuf)[0]; + int i; + + for (i = 0; i < fs.OutLen; i++) { + UsedFracMap[rpos->fti] |= 1; + rpos++; + } + } + + /** + * Function calculates the overall filtering steps complexity per + * scanline. Each complexity unit corresponds to a single multiply-add + * operation. Data copy and pointer math operations are not included in + * this calculation, it is assumed that they correlate to the multiply-add + * operations. Calculation also does not include final rounding, dithering + * and clamping operations since they cannot be optimized out anyway. + * + * Calculation of the CRPosBuf buffer is not included since it cannot be + * avoided. + * + * This function should be called after the updateFilterStepBuffers() + * function. + * + * @param Steps Filtering steps array. + * @param Vars Variables object. + * @param UsedFracMap The map of used fractional delay filters. + * @param ScanlineCount Scanline count. + */ + + static int calcComplexity(const CFilterSteps& Steps, + const CImageResizerVars& Vars, + const CBuffer& UsedFracMap, + const int ScanlineCount) { + int fcnum; // Filter complexity multiplier numerator. + int fcdenom; // Filter complexity multiplier denominator. + + if (Vars.packmode != 0) { + fcnum = 1; + fcdenom = 1; + } else { + // In interleaved processing mode, filters require 1 less + // multiplication per 2 multiply-add instructions. + + fcnum = 3; + fcdenom = 4; + } + + int s = 0; // Complexity per one scanline. + int s2 = 0; // Complexity per all scanlines. + int i; + + for (i = 0; i < Steps.getItemCount(); i++) { + const CFilterStep& fs = Steps[i]; + + s2 += 65 * fs.Flt.getCapacity(); // Filter creation complexity. + + if (fs.IsUpsample) { + if (fs.FltOrig.getCapacity() > 0) { + continue; + } + + s += (fs.Flt.getCapacity() * (fs.InPrefix + fs.InLen + fs.InSuffix) + + fs.SuffixDC.getCapacity() + fs.PrefixDC.getCapacity()) * + Vars.ElCount; + } else if (fs.ResampleFactor == 0) { + s += fs.FltBank->getFilterLen() * + (fs.FltBank->getOrder() + Vars.ElCount) * fs.OutLen; + + s2 += fs.FltBank->calcInitComplexity(UsedFracMap); + } else { + s += fs.Flt.getCapacity() * Vars.ElCount * fs.OutLen * fcnum / fcdenom; + } + } + + return (s + s2 / ScanlineCount); + } + + /** + * @brief Thread-isolated data used for scanline processing. + * + * This structure holds data necessary for image's horizontal or vertical + * scanline processing, including scanline processing queue. + * + * @tparam Tin Source element data type. Intermediate buffers store data + * in floating point format. + * @tparam Tout Destination element data type. Intermediate buffers store + * data in floating point format. + */ + + template + class CThreadData : public CImageResizerThreadPool ::CWorkload { + public: + virtual void process() { processScanlineQueue(); } + + /** + * This enumeration lists possible scanline operations. + */ + + enum EScanlineOperation { + sopResizeH, ///< Resize horizontal scanline. + ///< + sopResizeV, ///< Resize vertical scanline. + ///< + sopDitherAndUnpackH, ///< Dither and unpack horizontal scanline. + ///< + sopUnpackH ///< Unpack horizontal scanline. + ///< + }; + + /** + * Function initializes *this thread data object and assigns certain + * variables provided by the higher level code. + * + * @param aThreadIndex Index of this thread data (0-based). + * @param aThreadCount Total number of threads used during processing. + * @param aSteps Filtering steps. + * @param aVars Image resizer variables. + */ + + void init(const int aThreadIndex, const int aThreadCount, + const CFilterSteps& aSteps, const CImageResizerVars& aVars) { + ThreadIndex = aThreadIndex; + ThreadCount = aThreadCount; + Steps = &aSteps; + Vars = &aVars; + } + + /** + * Function initializes scanline processing queue, and updates + * capacities of intermediate buffers. + * + * @param aOp Operation to perform over scanline. + * @param TotalLines The total number of scanlines that will be + * processed by all threads. + * @param aSrcLen Source scanline length in pixels. + * @param aSrcIncr Source scanline buffer increment. Ignored in + * horizontal scanline processing. + * @param aResIncr Resulting scanline buffer increment. Ignored in + * horizontal scanline processing. + */ + + void initScanlineQueue(const EScanlineOperation aOp, const int TotalLines, + const int aSrcLen, const int aSrcIncr = 0, + const int aResIncr = 0) { + const int l = Vars->BufLen[0] + Vars->BufLen[1]; + + if (Bufs.getCapacity() < l) { + Bufs.alloc(l, fpclass ::fpalign); + } + + BufPtrs[0] = Bufs + Vars->BufOffs[0]; + BufPtrs[1] = Bufs + Vars->BufLen[0] + Vars->BufOffs[1]; + + int j; + int ml = 0; + + for (j = 0; j < Steps->getItemCount(); j++) { + const CFilterStep& fs = (*Steps)[j]; + + if (fs.ResampleFactor == 0 && ml < fs.FltBank->getFilterLen()) { + ml = fs.FltBank->getFilterLen(); + } + } + + TmpFltBuf.alloc(ml, fpclass ::fpalign); + ScanlineOp = aOp; + SrcLen = aSrcLen; + SrcIncr = aSrcIncr; + ResIncr = aResIncr; + QueueLen = 0; + Queue.increaseCapacity((TotalLines + ThreadCount - 1) / ThreadCount, + false); + } + + /** + * Function adds a scanline to the queue buffer. The + * initScanlineQueue() function should be called before calling this + * function. The number of calls to this add function should not + * exceed the TotalLines spread over all threads. + * + * @param SrcBuf Source scanline buffer. + * @param ResBuf Resulting scanline buffer. + */ + + void addScanlineToQueue(void* const SrcBuf, void* const ResBuf) { + Queue[QueueLen].SrcBuf = SrcBuf; + Queue[QueueLen].ResBuf = ResBuf; + QueueLen++; + } + + /** + * Function processes all queued scanlines. + */ + + void processScanlineQueue() { + int i; + + switch (ScanlineOp) { + case sopResizeH: { + for (i = 0; i < QueueLen; i++) { + resizeScanlineH((Tin*)Queue[i].SrcBuf, (fptype*)Queue[i].ResBuf); + } + + break; + } + + case sopResizeV: { + for (i = 0; i < QueueLen; i++) { + resizeScanlineV((fptype*)Queue[i].SrcBuf, (fptype*)Queue[i].ResBuf); + } + + break; + } + + case sopDitherAndUnpackH: { + if (Vars->UseSRGBGamma) { + for (i = 0; i < QueueLen; i++) { + CFilterStep ::applySRGBGamma((fptype*)Queue[i].SrcBuf, SrcLen, + *Vars); + + Ditherer.dither((fptype*)Queue[i].SrcBuf); + + CFilterStep ::unpackScanline((fptype*)Queue[i].SrcBuf, + (Tout*)Queue[i].ResBuf, SrcLen, + *Vars); + } + } else { + for (i = 0; i < QueueLen; i++) { + Ditherer.dither((fptype*)Queue[i].SrcBuf); + + CFilterStep ::unpackScanline((fptype*)Queue[i].SrcBuf, + (Tout*)Queue[i].ResBuf, SrcLen, + *Vars); + } + } + + break; + } + + case sopUnpackH: { + if (Vars->UseSRGBGamma) { + for (i = 0; i < QueueLen; i++) { + CFilterStep ::applySRGBGamma((fptype*)Queue[i].SrcBuf, SrcLen, + *Vars); + + CFilterStep ::unpackScanline((fptype*)Queue[i].SrcBuf, + (Tout*)Queue[i].ResBuf, SrcLen, + *Vars); + } + } else { + for (i = 0; i < QueueLen; i++) { + CFilterStep ::unpackScanline((fptype*)Queue[i].SrcBuf, + (Tout*)Queue[i].ResBuf, SrcLen, + *Vars); + } + } + + break; + } + } + } + + /** + * Function returns ditherer object associated with *this thread data + * object. + */ + + CDitherer& getDitherer() { return (Ditherer); } + + private: + int ThreadIndex; ///< Thread index. + ///< + int ThreadCount; ///< Thread count. + ///< + const CFilterSteps* Steps; ///< Filtering steps. + ///< + const CImageResizerVars* Vars; ///< Image resizer variables. + ///< + CBuffer Bufs; ///< Flip-flop intermediate buffers. + ///< + fptype* BufPtrs[3]; ///< Flip-flop buffer pointers (referenced by + ///< filtering step's InBuf and OutBuf indices). + ///< + CBuffer + TmpFltBuf; ///< Temporary buffer used in the + ///< doResize() function, aligned by fpclass :: fpalign. + ///< + EScanlineOperation ScanlineOp; ///< Operation to perform over + ///< scanline. + ///< + int SrcLen; ///< Source scanline length in the last queue. + ///< + int SrcIncr; ///< Source scanline buffer increment in the last queue. + ///< + int ResIncr; ///< Resulting scanline buffer increment in the last + ///< queue. + ///< + CDitherer Ditherer; ///< Ditherer object to use. + ///< + + /** + * @brief Scanline processing queue item. + * + * Scanline processing queue item. + */ + + struct CQueueItem { + void* SrcBuf; ///< Source scanline buffer, will by typecasted to + ///< Tin or fptype*. + ///< + void* ResBuf; ///< Resulting scanline buffer, will by typecasted + ///< to Tout or fptype*. + ///< + }; + + CBuffer Queue; ///< Scanline processing queue. + ///< + int QueueLen; ///< Queue length. + ///< + + /** + * Function resizes a single horizontal scanline. + * + * @param SrcBuf Source scanline buffer. Can be either horizontal or + * vertical. + * @param ResBuf Resulting scanline buffer. + */ + + void resizeScanlineH(const Tin* const SrcBuf, fptype* const ResBuf) { + (*Steps)[0].packScanline(SrcBuf, BufPtrs[0], SrcLen); + BufPtrs[2] = ResBuf; + int j; + + for (j = 0; j < Steps->getItemCount(); j++) { + const CFilterStep& fs = (*Steps)[j]; + fs.prepareInBuf(BufPtrs[fs.InBuf]); + const int DstIncr = (Vars->packmode == 0 ? Vars->ElCount : 1); + + if (fs.ResampleFactor != 0) { + if (fs.IsUpsample) { + fs.doUpsample(BufPtrs[fs.InBuf], BufPtrs[fs.OutBuf]); + } else { + fs.doFilter(BufPtrs[fs.InBuf], BufPtrs[fs.OutBuf], DstIncr); + } + } else { + fs.doResize(BufPtrs[fs.InBuf], BufPtrs[fs.OutBuf], DstIncr, + TmpFltBuf); + } + } + } + + /** + * Function resizes a single vertical scanline. + * + * @param SrcBuf Source scanline buffer. Can be either horizontal or + * vertical. + * @param ResBuf Resulting scanline buffer. + */ + + void resizeScanlineV(const fptype* const SrcBuf, fptype* const ResBuf) { + (*Steps)[0].convertVtoH(SrcBuf, BufPtrs[0], SrcLen, SrcIncr); + + BufPtrs[2] = ResBuf; + int j; + + for (j = 0; j < Steps->getItemCount(); j++) { + const CFilterStep& fs = (*Steps)[j]; + fs.prepareInBuf(BufPtrs[fs.InBuf]); + const int DstIncr = + (fs.OutBuf == 2 ? ResIncr + : (Vars->packmode == 0 ? Vars->ElCount : 1)); + + if (fs.ResampleFactor != 0) { + if (fs.IsUpsample) { + fs.doUpsample(BufPtrs[fs.InBuf], BufPtrs[fs.OutBuf]); + } else { + fs.doFilter(BufPtrs[fs.InBuf], BufPtrs[fs.OutBuf], DstIncr); + } + } else { + fs.doResize(BufPtrs[fs.InBuf], BufPtrs[fs.OutBuf], DstIncr, + TmpFltBuf); + } + } + } + }; +}; + +#undef AVIR_PI +#undef AVIR_PId2 + +} // namespace avir + +#endif // AVIR_CIMAGERESIZER_INCLUDED +//$ nobt +//$ nocpp + +/** + * @file avir.h + * + * @brief The "main" inclusion file with all required classes and functions. + * + * This is the "main" inclusion file for the "AVIR" image resizer. This + * inclusion file contains implementation of the AVIR image resizing algorithm + * in its entirety. Also includes several classes and functions that can be + * useful elsewhere. + * + * AVIR Copyright (c) 2015-2019 Aleksey Vaneev + * + * @mainpage + * + * @section intro_sec Introduction + * + * Description is available at https://github.com/avaneev/avir + * + * AVIR is devoted to women. Your digital photos can look good at any size! + * + * @section license License + * + * AVIR License Agreement + * + * The MIT License (MIT) + * + * Copyright (c) 2015-2019 Aleksey Vaneev + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Please credit the author of this library in your documentation in the + * following way: "AVIR image resizing algorithm designed by Aleksey Vaneev" + * + * @version 2.4 + */ + +#ifndef AVIR_CIMAGERESIZER_INCLUDED +#define AVIR_CIMAGERESIZER_INCLUDED + +#include +#include +#include +#include + +namespace avir { + +/** + * The macro defines AVIR version string. + */ + +#define AVIR_VERSION "2.4" + +/** + * The macro equals to "pi" constant, fills 53-bit floating point mantissa. + * Undefined at the end of file. + */ + +#define AVIR_PI 3.1415926535897932 + +/** + * The macro equals to "pi divided by 2" constant, fills 53-bit floating + * point mantissa. Undefined at the end of file. + */ + +#define AVIR_PId2 1.5707963267948966 + +/** + * Rounding function, based on the (int) typecast. Biased result. Not suitable + * for numbers >= 2^31. + * + * @param d Value to round. + * @return Rounded value. Some bias may be introduced. + */ + +template +inline T round(const T d) { + return (d < 0.0 ? -(T)(int)((T)0.5 - d) : (T)(int)(d + (T)0.5)); +} + +/** + * Template function "clamps" (clips) the specified value so that it is not + * lesser than "minv", and not greater than "maxv". + * + * @param Value Value to clamp. + * @param minv Minimal allowed value. + * @param maxv Maximal allowed value. + * @return The clamped value. + */ + +template +inline T clamp(const T& Value, const T minv, const T maxv) { + if (Value < minv) { + return (minv); + } else if (Value > maxv) { + return (maxv); + } else { + return (Value); + } +} + +/** + * Power 2.4 approximation function, designed for sRGB gamma correction. + * + * @param x Argument, in the range 0.09 to 1. + * @return Value raised into power 2.4, approximate. + */ + +template +inline T pow24_sRGB(const T x) { + const double x2 = x * x; + const double x3 = x2 * x; + const double x4 = x2 * x2; + + return ((T)(0.0985766365536824 + 0.839474952656502 * x2 + + 0.363287814061725 * x3 - + 0.0125559718896615 / (0.12758338921578 + 0.290283465468235 * x) - + 0.231757513261358 * x - 0.0395365717969074 * x4)); +} + +/** + * Power 1/2.4 approximation function, designed for sRGB gamma correction. + * + * @param x Argument, in the range 0.003 to 1. + * @return Value raised into power 1/2.4, approximate. + */ + +template +inline T pow24i_sRGB(const T x) { + const double sx = sqrt(x); + const double ssx = sqrt(sx); + const double sssx = sqrt(ssx); + + return ((T)(0.000213364515060263 + 0.0149409239419218 * x + + 0.433973412731747 * sx + + ssx * (0.659628181609715 * sssx - 0.0380957908841466 - + 0.0706476137208521 * sx))); +} + +/** + * Function approximately linearizes the sRGB gamma value. + * + * @param s sRGB gamma value, in the range 0 to 1. + * @return Linearized sRGB gamma value, approximated. + */ + +template +inline T convertSRGB2Lin(const T s) { + const T a = (T)0.055; + + if (s <= (T)0.04045) { + return (s / (T)12.92); + } + + return (pow24_sRGB((s + a) / ((T)1 + a))); +} + +/** + * Function approximately de-linearizes the linear gamma value. + * + * @param s Linear gamma value, in the range 0 to 1. + * @return sRGB gamma value, approximated. + */ + +template +inline T convertLin2SRGB(const T s) { + const T a = (T)0.055; + + if (s <= (T)0.0031308) { + return ((T)12.92 * s); + } + + return (((T)1 + a) * pow24i_sRGB(s) - a); +} + +/** + * Function converts (via typecast) specified array of type T1 values of + * length l into array of type T2 values. If T1 is the same as T2, copy + * operation is performed. When copying data at overlapping address spaces, + * "op" should be lower than "ip". + * + * @param ip Input buffer. + * @param[out] op Output buffer. + * @param l The number of elements to copy. + * @param ip Input buffer pointer increment. + * @param op Output buffer pointer increment. + */ + +template +inline void copyArray(const T1* ip, T2* op, int l, const int ipinc = 1, + const int opinc = 1) { + while (l > 0) { + *op = (T2)*ip; + op += opinc; + ip += ipinc; + l--; + } +} + +/** + * Function adds values located in array "ip" to array "op". + * + * @param ip Input buffer. + * @param[out] op Output buffer. + * @param l The number of elements to add. + * @param ip Input buffer pointer increment. + * @param op Output buffer pointer increment. + */ + +template +inline void addArray(const T1* ip, T2* op, int l, const int ipinc = 1, + const int opinc = 1) { + while (l > 0) { + *op += *ip; + op += opinc; + ip += ipinc; + l--; + } +} + +/** + * Function that replicates a set of adjacent elements several times in a row. + * This operation is usually used to replicate pixels at the start or end of + * image's scanline. + * + * @param ip Source array. + * @param ipl Source array length (usually 1..4, but can be any number). + * @param[out] op Destination buffer. + * @param l Number of times the source array should be replicated (the + * destination buffer should be able to hold ipl * l number of elements). + * @param opinc Destination buffer position increment after replicating the + * source array. This value should be equal to at least ipl. + */ + +template +inline void replicateArray(const T1* const ip, const int ipl, T2* op, int l, + const int opinc) { + if (ipl == 1) { + while (l > 0) { + op[0] = ip[0]; + op += opinc; + l--; + } + } else if (ipl == 4) { + while (l > 0) { + op[0] = ip[0]; + op[1] = ip[1]; + op[2] = ip[2]; + op[3] = ip[3]; + op += opinc; + l--; + } + } else if (ipl == 3) { + while (l > 0) { + op[0] = ip[0]; + op[1] = ip[1]; + op[2] = ip[2]; + op += opinc; + l--; + } + } else if (ipl == 2) { + while (l > 0) { + op[0] = ip[0]; + op[1] = ip[1]; + op += opinc; + l--; + } + } else { + while (l > 0) { + int i; + + for (i = 0; i < ipl; i++) { + op[i] = ip[i]; + } + + op += opinc; + l--; + } + } +} + +/** + * Function calculates frequency response of the specified FIR filter at the + * specified circular frequency. Phase can be calculated as atan2( im, re ). + * Function uses computationally-efficient oscillators instead of "cos" and + * "sin" functions. + * + * @param flt FIR filter's coefficients. + * @param fltlen Number of coefficients (taps) in the filter. + * @param th Circular frequency [0; pi]. + * @param[out] re0 Resulting real part of the complex frequency response. + * @param[out] im0 Resulting imaginary part of the complex frequency response. + * @param fltlat Filter's latency in samples (taps). + */ + +template +inline void calcFIRFilterResponse(const T* flt, int fltlen, const double th, + double& re0, double& im0, + const int fltlat = 0) { + const double sincr = 2.0 * cos(th); + double cvalue1; + double svalue1; + + if (fltlat == 0) { + cvalue1 = 1.0; + svalue1 = 0.0; + } else { + cvalue1 = cos(-fltlat * th); + svalue1 = sin(-fltlat * th); + } + + double cvalue2 = cos(-(fltlat + 1) * th); + double svalue2 = sin(-(fltlat + 1) * th); + + double re = 0.0; + double im = 0.0; + + while (fltlen > 0) { + re += cvalue1 * flt[0]; + im += svalue1 * flt[0]; + flt++; + fltlen--; + + double tmp = cvalue1; + cvalue1 = sincr * cvalue1 - cvalue2; + cvalue2 = tmp; + + tmp = svalue1; + svalue1 = sincr * svalue1 - svalue2; + svalue2 = tmp; + } + + re0 = re; + im0 = im; +} + +/** + * Function normalizes FIR filter so that its frequency response at DC is + * equal to DCGain. + * + * @param[in,out] p Filter coefficients. + * @param l Filter length. + * @param DCGain Filter's gain at DC. + * @param pstep "p" array step. + */ + +template +inline void normalizeFIRFilter(T* const p, const int l, const double DCGain, + const int pstep = 1) { + double s = 0.0; + T* pp = p; + int i = l; + + while (i > 0) { + s += *pp; + pp += pstep; + i--; + } + + s = DCGain / s; + pp = p; + i = l; + + while (i > 0) { + *pp = (T)(*pp * s); + pp += pstep; + i--; + } +} + +/** + * @brief Memory buffer class for element array storage, with capacity + * tracking. + * + * Allows easier handling of memory blocks allocation and automatic + * deallocation for arrays (buffers) consisting of elements of specified + * class. Tracks buffer's capacity in "int" variable; unsuitable for + * allocation of very large memory blocks (with more than 2 billion elements). + * + * This class manages memory space only - it does not perform element class + * construction (initialization) operations. Buffer's required memory address + * alignment specification is supported. + * + * Uses standard library to allocate and deallocate memory. + * + * @tparam T Buffer element's type. + * @tparam capint Buffer capacity's type to use. Use size_t for large buffers. + */ + +template +class CBuffer { + public: + CBuffer() : Data(NULL), DataAligned(NULL), Capacity(0), Alignment(0) {} + + /** + * Constructor creates the buffer with the specified capacity. + * + * @param aCapacity Buffer's capacity. + * @param aAlignment Buffer's required memory address alignment. 0 - use + * stdlib's default alignment. + */ + + CBuffer(const capint aCapacity, const int aAlignment = 0) { + allocinit(aCapacity, aAlignment); + } + + CBuffer(const CBuffer& Source) { + allocinit(Source.Capacity, Source.Alignment); + memcpy(DataAligned, Source.DataAligned, Capacity * sizeof(T)); + } + + ~CBuffer() { freeData(); } + + CBuffer& operator=(const CBuffer& Source) { + alloc(Source.Capacity, Source.Alignment); + memcpy(DataAligned, Source.DataAligned, Capacity * sizeof(T)); + return (*this); + } + + /** + * Function allocates memory so that the specified number of elements + * can be stored in *this buffer object. + * + * @param aCapacity Storage for this number of elements to allocate. + * @param aAlignment Buffer's required memory address alignment, + * power-of-2 values only. 0 - use stdlib's default alignment. + */ + + void alloc(const capint aCapacity, const int aAlignment = 0) { + freeData(); + allocinit(aCapacity, aAlignment); + } + + /** + * Function deallocates any previously allocated buffer. + */ + + void free() { + freeData(); + Data = NULL; + DataAligned = NULL; + Capacity = 0; + Alignment = 0; + } + + /** + * @return The capacity of the element buffer. + */ + + capint getCapacity() const { return (Capacity); } + + /** + * Function "forces" *this buffer to have an arbitary capacity. Calling + * this function invalidates all further operations except deleting *this + * object. This function should not be usually used at all. Function can + * be used to "model" certain buffer capacity without calling a costly + * memory allocation function. + * + * @param NewCapacity A new "forced" capacity. + */ + + void forceCapacity(const capint NewCapacity) { Capacity = NewCapacity; } + + /** + * Function reallocates *this buffer to a larger size so that it will be + * able to hold the specified number of elements. Downsizing is not + * performed. Alignment is not changed. + * + * @param NewCapacity New (increased) capacity. + * @param DoDataCopy "True" if data in the buffer should be retained. + */ + + void increaseCapacity(const capint NewCapacity, + const bool DoDataCopy = true) { + if (NewCapacity < Capacity) { + return; + } + + if (DoDataCopy) { + const capint PrevCapacity = Capacity; + T* const PrevData = Data; + T* const PrevDataAligned = DataAligned; + + allocinit(NewCapacity, Alignment); + memcpy(DataAligned, PrevDataAligned, PrevCapacity * sizeof(T)); + + ::free(PrevData); + } else { + ::free(Data); + allocinit(NewCapacity, Alignment); + } + } + + /** + * Function "truncates" (reduces) capacity of the buffer without + * reallocating it. Alignment is not changed. + * + * @param NewCapacity New required capacity. + */ + + void truncateCapacity(const capint NewCapacity) { + if (NewCapacity >= Capacity) { + return; + } + + Capacity = NewCapacity; + } + + /** + * Function increases capacity so that the specified number of + * elements can be stored. This function increases the previous capacity + * value by third the current capacity value until space for the required + * number of elements is available. Alignment is not changed. + * + * @param ReqCapacity Required capacity. + */ + + void updateCapacity(const capint ReqCapacity) { + if (ReqCapacity <= Capacity) { + return; + } + + capint NewCapacity = Capacity; + + while (NewCapacity < ReqCapacity) { + NewCapacity += NewCapacity / 3 + 1; + } + + increaseCapacity(NewCapacity); + } + + operator T*() const { return (DataAligned); } + + private: + T* Data; ///< Element buffer pointer. + ///< + T* DataAligned; ///< Memory address-aligned element buffer pointer. + ///< + capint Capacity; ///< Element buffer capacity. + ///< + int Alignment; ///< Memory address alignment in use. 0 - use stdlib's + ///< default alignment. + ///< + + /** + * Internal element buffer allocation function used during object + * construction. + * + * @param aCapacity Storage for this number of elements to allocate. + * @param aAlignment Buffer's required memory address alignment. 0 - use + * stdlib's default alignment. + */ + + void allocinit(const capint aCapacity, const int aAlignment) { + if (aAlignment == 0) { + Data = (T*)::malloc(aCapacity * sizeof(T)); + DataAligned = Data; + Alignment = 0; + } else { + Data = (T*)::malloc(aCapacity * sizeof(T) + aAlignment); + DataAligned = alignptr(Data, aAlignment); + Alignment = aAlignment; + } + + Capacity = aCapacity; + } + + /** + * Function frees a previously allocated Data buffer. + */ + + void freeData() { ::free(Data); } + + /** + * Function modifies the specified pointer so that it becomes memory + * address-aligned. + * + * @param ptr Pointer to align. + * @param align Alignment in bytes to apply. + * @return Pointer aligned to align bytes. Works with power-of-2 + * alignments only. If no alignment is necessary, "align" bytes will be + * added to the pointer value. + */ + + template + inline Tp alignptr(const Tp ptr, const uintptr_t align) { + return ((Tp)((uintptr_t)ptr + align - ((uintptr_t)ptr & (align - 1)))); + } +}; + +/** + * Function optimizes the length of the symmetric-odd FIR filter by removing + * left- and rightmost elements that are below specific threshold. + * + * Synthetic test shows that filter gets optimized in 2..3% of cases and in + * each such case optimization reduces filter length by 6..8%. Optimization, + * however, may skew the results of algorithm modeling and complexity + * calculation leading to a choice of a less optimal algorithm. + * + * @param[in,out] Flt Buffer that contains filter being optimized. + * @param[in,out] FltLatency Variable that holds the current latency of the + * filter. May be adjusted on function return. + * @param Threshold Threshold level. + */ + +template +inline void optimizeFIRFilter(CBuffer& Flt, int& FltLatency, + T const Threshold = (T)0.00001) { + int i; + + // Optimize length. + + for (i = 0; i <= FltLatency; i++) { + if (fabs(Flt[i]) >= Threshold || i == FltLatency) { + if (i > 0) { + const int NewCapacity = Flt.getCapacity() - i * 2; + copyArray(&Flt[i], &Flt[0], NewCapacity); + Flt.truncateCapacity(NewCapacity); + FltLatency -= i; + } + + break; + } + } +} + +/** + * @brief Array of structured objects. + * + * Implements allocation of a linear array of objects of class T (which are + * initialized), addressable via operator[]. Each object is created via the + * "operator new". New object insertions are quick since implementation uses + * prior space allocation (capacity), thus not requiring frequent memory block + * reallocations. + * + * @tparam T Array element's type. + */ + +template +class CStructArray { + public: + CStructArray() : ItemCount(0) {} + + CStructArray(const CStructArray& Source) + : ItemCount(0), Items(Source.getItemCount()) { + while (ItemCount < Source.getItemCount()) { + Items[ItemCount] = new T(Source[ItemCount]); + ItemCount++; + } + } + + ~CStructArray() { clear(); } + + CStructArray& operator=(const CStructArray& Source) { + clear(); + + const int NewCount = Source.ItemCount; + Items.updateCapacity(NewCount); + + while (ItemCount < NewCount) { + Items[ItemCount] = new T(Source[ItemCount]); + ItemCount++; + } + + return (*this); + } + + T& operator[](const int Index) { return (*Items[Index]); } + + const T& operator[](const int Index) const { return (*Items[Index]); } + + /** + * Function creates a new object of type T with the default constructor + * and adds this object to the array. + * + * @return Reference to a newly added object. + */ + + T& add() { + if (ItemCount == Items.getCapacity()) { + Items.increaseCapacity(ItemCount * 3 / 2 + 1); + } + + Items[ItemCount] = new T(); + ItemCount++; + + return ((*this)[ItemCount - 1]); + } + + /** + * Function changes number of allocated items. New items are created with + * the default constructor. If NewCount is below the current item count, + * items that are above NewCount range will be destructed. + * + * @param NewCount New requested item count. + */ + + void setItemCount(const int NewCount) { + if (NewCount > ItemCount) { + Items.increaseCapacity(NewCount); + + while (ItemCount < NewCount) { + Items[ItemCount] = new T(); + ItemCount++; + } + } else { + while (ItemCount > NewCount) { + ItemCount--; + delete Items[ItemCount]; + } + } + } + + /** + * Function erases all items of *this array. + */ + + void clear() { + while (ItemCount > 0) { + ItemCount--; + delete Items[ItemCount]; + } + } + + /** + * @return The number of allocated items. + */ + + int getItemCount() const { return (ItemCount); } + + private: + int ItemCount; ///< The number of items available in the array. + ///< + CBuffer Items; ///< Element buffer. + ///< +}; + +/** + * @brief Sine signal generator class. + * + * Class implements sine signal generator without biasing, with + * constructor-based initalization only. This generator uses oscillator + * instead of "sin" function. + */ + +class CSineGen { + public: + /** + * Constructor initializes *this sine signal generator. + * + * @param si Sine function increment, in radians. + * @param ph Starting phase, in radians. Add 0.5 * AVIR_PI for cosine + * function. + */ + + CSineGen(const double si, const double ph) + : svalue1(sin(ph)), svalue2(sin(ph - si)), sincr(2.0 * cos(si)) {} + + /** + * @return The next value of the sine function, without biasing. + */ + + double generate() { + const double res = svalue1; + + svalue1 = sincr * res - svalue2; + svalue2 = res; + + return (res); + } + + private: + double svalue1; ///< Current sine value. + ///< + double svalue2; ///< Previous sine value. + ///< + double sincr; ///< Sine value increment. + ///< +}; + +/** + * @brief Peaked Cosine window function generator class. + * + * Class implements Peaked Cosine window function generator. Generates the + * right-handed half of the window function. The Alpha parameter of this + * window function offers the control of the balance between the early and + * later taps of the filter. E.g. at Alpha=1 both early and later taps are + * attenuated, but at Alpha=4 mostly later taps are attenuated. This offers a + * great control over ringing artifacts produced by a low-pass filter in image + * processing, without compromising achieved image sharpness. + */ + +class CDSPWindowGenPeakedCosine { + public: + /** + * Constructor initializes *this window function generator. + * + * @param aAlpha Alpha parameter, affects the peak shape (peak + * augmentation) of the window function. Should be >= 1.0. + * @param aLen2 Half filter's length (non-truncated). + */ + + CDSPWindowGenPeakedCosine(const double aAlpha, const double aLen2) + : Alpha(aAlpha), + Len2(aLen2), + wn(0), + w1(AVIR_PId2 / Len2, AVIR_PI * 0.5) {} + + /** + * @return The next Peaked Cosine window function coefficient. + */ + + double generate() { + const double h = pow(wn / Len2, Alpha); + wn++; + + return (w1.generate() * (1.0 - h)); + } + + private: + double Alpha; ///< Alpha parameter, affects the peak shape of window. + ///< + double Len2; ///< Half length of the window function. + ///< + int wn; ///< Window function integer position. 0 - center of the + ///< window function. + ///< + CSineGen w1; ///< Sine-wave generator. + ///< +}; + +/** + * @brief FIR filter-based equalizer generator. + * + * Class implements an object used to generate symmetric-odd FIR filters with + * the specified frequency response (aka paragraphic equalizer). The + * calculated filter is windowed by the Peaked Cosine window function. + * + * In image processing, due to short length of filters being used (6-8 taps) + * the resulting frequency response of the filter is approximate and may be + * mathematically imperfect, but still adequate to the visual requirements. + * + * On a side note, this equalizer generator can be successfully used for audio + * signal equalization as well: for example, it is used in almost the same + * form in Voxengo Marvel GEQ equalizer plug-in. + * + * Filter generation is based on decomposition of frequency range into + * spectral bands, with each band represented by linear and ramp "kernels". + * When the filter is built, these kernels are combined together with + * different weights that approximate the required frequency response. + */ + +class CDSPFIREQ { + public: + /** + * Function initializes *this object with the required parameters. The + * gain of frequencies beyond the MinFreq..MaxFreq range are controlled by + * the first and the last band's gain. + * + * @param SampleRate Processing sample rate (use 2 for image processing). + * @param aFilterLength Required filter length in samples (taps). The + * actual filter length is truncated to an integer value. + * @param aBandCount Number of band crossover points required to control, + * including bands at MinFreq and MaxFreq. + * @param MinFreq Minimal frequency that should be controlled. + * @param MaxFreq Maximal frequency that should be controlled. + * @param IsLogBands "True" if the bands should be spaced logarithmically. + * @param WFAlpha Peaked Cosine window function's Alpha parameter. + */ + + void init(const double SampleRate, const double aFilterLength, + const int aBandCount, const double MinFreq, const double MaxFreq, + const bool IsLogBands, const double WFAlpha) { + FilterLength = aFilterLength; + BandCount = aBandCount; + + CenterFreqs.alloc(BandCount); + + z = (int)ceil(FilterLength * 0.5); + zi = z + (z & 1); + z2 = z * 2; + + CBuffer oscbuf(z2); + initOscBuf(oscbuf); + + CBuffer winbuf(z); + initWinBuf(winbuf, WFAlpha); + + UseFirstVirtBand = (MinFreq > 0.0); + const int k = zi * (BandCount + (UseFirstVirtBand ? 1 : 0)); + Kernels1.alloc(k); + Kernels2.alloc(k); + + double m; // Frequency step multiplier. + double mo; // Frequency step offset (addition). + + if (IsLogBands) { + m = exp(log(MaxFreq / MinFreq) / (BandCount - 1)); + mo = 0.0; + } else { + m = 1.0; + mo = (MaxFreq - MinFreq) / (BandCount - 1); + } + + double f = MinFreq; + double x1 = 0.0; + double x2; + int si; + + if (UseFirstVirtBand) { + si = 0; + } else { + si = 1; + CenterFreqs[0] = 0.0; + f = f * m + mo; + } + + double* kernbuf1 = &Kernels1[0]; + double* kernbuf2 = &Kernels2[0]; + int i; + + for (i = si; i < BandCount; i++) { + x2 = f * 2.0 / SampleRate; + CenterFreqs[i] = x2; + + fillBandKernel(x1, x2, kernbuf1, kernbuf2, oscbuf, winbuf); + + kernbuf1 += zi; + kernbuf2 += zi; + x1 = x2; + f = f * m + mo; + } + + if (x1 < 1.0) { + UseLastVirtBand = true; + fillBandKernel(x1, 1.0, kernbuf1, kernbuf2, oscbuf, winbuf); + } else { + UseLastVirtBand = false; + } + } + + /** + * @return Filter's length, in samples (taps). + */ + + int getFilterLength() const { return (z2 - 1); } + + /** + * @return Filter's latency (group delay), in samples (taps). + */ + + int getFilterLatency() const { return (z - 1); } + + /** + * Function creates symmetric-odd FIR filter with the specified gain + * levels at band crossover points. + * + * @param BandGains Array of linear gain levels, count=BandCount specified + * in the init() function. + * @param[out] Filter Output filter buffer, length = getFilterLength(). + */ + + void buildFilter(const double* const BandGains, double* const Filter) { + const double* kernbuf1 = &Kernels1[0]; + const double* kernbuf2 = &Kernels2[0]; + double x1 = 0.0; + double y1 = BandGains[0]; + double x2; + double y2; + + int i; + int si; + + if (UseFirstVirtBand) { + si = 1; + x2 = CenterFreqs[0]; + y2 = y1; + } else { + si = 2; + x2 = CenterFreqs[1]; + y2 = BandGains[1]; + } + + copyBandKernel(Filter, kernbuf1, kernbuf2, y1 - y2, x1 * y2 - x2 * y1); + + kernbuf1 += zi; + kernbuf2 += zi; + x1 = x2; + y1 = y2; + + for (i = si; i < BandCount; i++) { + x2 = CenterFreqs[i]; + y2 = BandGains[i]; + + addBandKernel(Filter, kernbuf1, kernbuf2, y1 - y2, x1 * y2 - x2 * y1); + + kernbuf1 += zi; + kernbuf2 += zi; + x1 = x2; + y1 = y2; + } + + if (UseLastVirtBand) { + addBandKernel(Filter, kernbuf1, kernbuf2, y1 - y2, x1 * y2 - y1); + } + + for (i = 0; i < z - 1; i++) { + Filter[z + i] = Filter[z - 2 - i]; + } + } + + /** + * Function calculates filter's length (in samples) and latency depending + * on the required non-truncated filter length. + * + * @param aFilterLength Required filter length in samples (non-truncated). + * @param[out] Latency Resulting latency (group delay) of the filter, + * in samples (taps). + * @return Filter length in samples (taps). + */ + + static int calcFilterLength(const double aFilterLength, int& Latency) { + const int l = (int)ceil(aFilterLength * 0.5); + Latency = l - 1; + + return (l * 2 - 1); + } + + private: + double FilterLength; ///< Length of filter. + ///< + int z; ///< Equals (int) ceil( FilterLength * 0.5 ). + ///< + int zi; ///< Equals "z" if z is even, or z + 1 if z is odd. Used as a + ///< Kernels1 and Kernels2 size multiplier and kernel buffer + ///< increment to make sure each kernel buffer is 16-byte aligned. + ///< + int z2; ///< Equals z * 2. + ///< + int BandCount; ///< Number of controllable bands. + ///< + CBuffer CenterFreqs; ///< Center frequencies for all bands, + ///< normalized to 0.0-1.0 range. + ///< + CBuffer Kernels1; ///< Half-length kernel buffers for each + ///< spectral band (linear part). + ///< + CBuffer Kernels2; ///< Half-length kernel buffers for each + ///< spectral band (ramp part). + ///< + bool UseFirstVirtBand; ///< "True" if the first virtual band + ///< (between 0.0 and MinFreq) should be used. The + ///< first virtual band won't be used if MinFreq + ///< equals 0.0. + ///< + bool UseLastVirtBand; ///< "True" if the last virtual band (between + ///< MaxFreq and SampleRate * 0.5) should be used. The + ///< last virtual band won't be used if MaxFreq * 2.0 + ///< equals SampleRate. + ///< + + /** + * Function initializes the "oscbuf" used in the fillBandKernel() + * function. + * + * @param oscbuf Oscillator buffer, length = z * 2. + */ + + void initOscBuf(double* oscbuf) const { + int i = z; + + while (i > 0) { + oscbuf[0] = 0.0; + oscbuf[1] = 1.0; + oscbuf += 2; + i--; + } + } + + /** + * Function initializes window function buffer. This function generates + * Peaked Cosine window function. + * + * @param winbuf Windowing buffer. + * @param Alpha Peaked Cosine alpha parameter. + */ + + void initWinBuf(double* winbuf, const double Alpha) const { + CDSPWindowGenPeakedCosine wf(Alpha, FilterLength * 0.5); + int i; + + for (i = 1; i <= z; i++) { + winbuf[z - i] = wf.generate(); + } + } + + /** + * Function fills first half of symmetric-odd FIR kernel for the band. + * This function should be called successively for adjacent bands. + * Previous band's x2 should be equal to current band's x1. A band kernel + * consists of 2 elements: linear kernel and ramp kernel. + * + * @param x1 Band's left corner frequency (0..1). + * @param x2 Band's right corner frequency (0..1). + * @param kernbuf1 Band kernel buffer 1 (linear part), length = z. + * @param kernbuf2 Band kernel buffer 2 (ramp part), length = z. + * @param oscbuf Oscillation buffer. Before the first call of the + * fillBandKernel() should be initialized with the call of the + * initOscBuf() function. + * @param winbuf Buffer that contains windowing function. + */ + + void fillBandKernel(const double x1, const double x2, double* kernbuf1, + double* kernbuf2, double* oscbuf, + const double* const winbuf) { + const double s2_incr = AVIR_PI * x2; + const double s2_coeff = 2.0 * cos(s2_incr); + + double s2_value1 = sin(s2_incr * (-z + 1)); + double c2_value1 = sin(s2_incr * (-z + 1) + AVIR_PI * 0.5); + oscbuf[0] = sin(s2_incr * -z); + oscbuf[1] = sin(s2_incr * -z + AVIR_PI * 0.5); + + int ks; + + for (ks = 1; ks < z; ks++) { + const int ks2 = ks * 2; + const double s1_value1 = oscbuf[ks2]; + const double c1_value1 = oscbuf[ks2 + 1]; + oscbuf[ks2] = s2_value1; + oscbuf[ks2 + 1] = c2_value1; + + const double x = AVIR_PI * (ks - z); + const double v0 = winbuf[ks - 1] / ((x1 - x2) * x); + + kernbuf1[ks - 1] = + (x2 * s2_value1 - x1 * s1_value1 + (c2_value1 - c1_value1) / x) * v0; + + kernbuf2[ks - 1] = (s2_value1 - s1_value1) * v0; + + s2_value1 = s2_coeff * s2_value1 - oscbuf[ks2 - 2]; + c2_value1 = s2_coeff * c2_value1 - oscbuf[ks2 - 1]; + } + + kernbuf1[z - 1] = (x2 * x2 - x1 * x1) / (x1 - x2) * 0.5; + kernbuf2[z - 1] = -1.0; + } + + /** + * Function copies band kernel's elements to the output buffer. + * + * @param outbuf Output buffer. + * @param kernbuf1 Kernel buffer 1 (linear part). + * @param kernbuf2 Kernel buffer 2 (ramp part). + * @param c Multiplier for linear kernel element. + * @param d Multiplier for ramp kernel element. + */ + + void copyBandKernel(double* outbuf, const double* const kernbuf1, + const double* const kernbuf2, const double c, + const double d) const { + int ks; + + for (ks = 0; ks < z; ks++) { + outbuf[ks] = c * kernbuf1[ks] + d * kernbuf2[ks]; + } + } + + /** + * Function adds band kernel's elements to the output buffer. + * + * @param outbuf Output buffer. + * @param kernbuf1 Kernel buffer 1 (linear part). + * @param kernbuf2 Kernel buffer 2 (ramp part). + * @param c Multiplier for linear kernel element. + * @param d Multiplier for ramp kernel element. + */ + + void addBandKernel(double* outbuf, const double* const kernbuf1, + const double* const kernbuf2, const double c, + const double d) const { + int ks; + + for (ks = 0; ks < z; ks++) { + outbuf[ks] += c * kernbuf1[ks] + d * kernbuf2[ks]; + } + } +}; + +/** + * @brief Low-pass filter windowed by Peaked Cosine window function. + * + * This class implements calculation of linear-phase symmetric-odd FIR + * low-pass filter windowed by the Peaked Cosine window function, for image + * processing applications. + */ + +class CDSPPeakedCosineLPF { + public: + int fl2; ///< Half filter's length, excluding the peak value. This value + ///< can be also used as filter's latency in samples (taps). + ///< + int FilterLen; ///< Filter's length in samples (taps). + ///< + + /** + * Constructor initalizes *this object. + * + * @param aLen2 Half-length (non-truncated) of low-pass filter, in samples + * (taps). + * @param aFreq2 Low-pass filter's corner frequency [0; pi]. + * @param aAlpha Peaked Cosine window function Alpha parameter. + */ + + CDSPPeakedCosineLPF(const double aLen2, const double aFreq2, + const double aAlpha) + : fl2((int)ceil(aLen2) - 1), + FilterLen(fl2 + fl2 + 1), + Len2(aLen2), + Freq2(aFreq2), + Alpha(aAlpha) {} + + /** + * Function generates a linear-phase low-pass filter windowed by Peaked + * Cosine window function. + * + * @param[out] op Output buffer, length = FilterLen (fl2 * 2 + 1). + * @param DCGain Required gain at DC. The resulting filter will be + * normalized to achieve this DC gain. + */ + + template + void generateLPF(T* op, const double DCGain) { + CDSPWindowGenPeakedCosine wf(Alpha, Len2); + CSineGen f2(Freq2, 0.0); + + op += fl2; + T* op2 = op; + f2.generate(); + int t = 1; + + *op = (T)(Freq2 * wf.generate() / AVIR_PI); + double s = *op; + + while (t <= fl2) { + const double v = f2.generate() * wf.generate() / t / AVIR_PI; + op++; + op2--; + *op = (T)v; + *op2 = (T)v; + s += *op + *op2; + t++; + } + + t = FilterLen; + s = DCGain / s; + + while (t > 0) { + *op2 = (T)(*op2 * s); + op2++; + t--; + } + } + + private: + double Len2; ///< Half-length (non-truncated) of low-pass filter, in + ///< samples (taps). + ///< + double Freq2; ///< Low-pass filter's corner frequency. + ///< + double Alpha; ///< Peaked Cosine window function Alpha parameter. + ///< +}; + +/** + * @brief Buffer class for parametrized low-pass filter. + * + * This class extends the CBuffer< double > class by adding several variables + * that define a symmetric-odd FIR low-pass filter windowed by Peaked Cosine + * window function. This class can be used to compare filters without + * comparing their buffer contents. + */ + +class CFltBuffer : public CBuffer { + public: + double Len2; ///< Half-length (non-truncated) of low-pass filters, in + ///< samples (taps). + ///< + double Freq; ///< Low-pass filter's corner frequency. + ///< + double Alpha; ///< Peaked Cosine window function Alpha parameter. + ///< + double DCGain; ///< DC gain applied to the filter. + ///< + + CFltBuffer() + : CBuffer(), Len2(0.0), Freq(0.0), Alpha(0.0), DCGain(0.0) {} + + /** + * @param b2 Filter buffer to compare *this object to. + * @return Operator returns "true" if both filters have same parameters. + */ + + bool operator==(const CFltBuffer& b2) const { + return (Len2 == b2.Len2 && Freq == b2.Freq && Alpha == b2.Alpha && + DCGain == b2.DCGain); + } +}; + +/** + * @brief Sinc function-based fractional delay filter bank. + * + * Class implements storage and initialization of a bank of sinc + * function-based fractional delay filters, expressed as 1st order polynomial + * interpolation coefficients. The filters are produced from a single "long" + * windowed low-pass filter. Also supports 0th-order ("nearest neighbor") + * interpolation. + * + * This class also supports multiplication of each fractional delay filter by + * an external filter (usually a low-pass filter). + * + * @tparam fptype Specifies storage type of the filter coefficients bank. The + * filters are initially calculated using the "double" precision. + */ + +template +class CDSPFracFilterBankLin { + public: + CDSPFracFilterBankLin() : Order(-1) {} + + /** + * Copy constructor copies a limited set of parameters of the source + * filter bank. The actual filters are not copied. Such copying is used + * during filtering steps "modeling" stage. A further init() function + * call is required. + * + * @param s Source filter bank. + */ + + void copyInitParams(const CDSPFracFilterBankLin& s) { + WFLen2 = s.WFLen2; + WFFreq = s.WFFreq; + WFAlpha = s.WFAlpha; + FracCount = s.FracCount; + Order = s.Order; + Alignment = s.Alignment; + SrcFilterLen = s.SrcFilterLen; + FilterLen = s.FilterLen; + FilterSize = s.FilterSize; + IsSrcTableBuilt = false; + ExtFilter = s.ExtFilter; + TableFillFlags.alloc(s.TableFillFlags.getCapacity()); + int i; + + // Copy table fill flags, but shifted so that further initialization + // is still possible (such feature should not be used, though). + + for (i = 0; i < TableFillFlags.getCapacity(); i++) { + TableFillFlags[i] = (uint8_t)(s.TableFillFlags[i] << 2); + } + } + + /** + * Operator compares *this filter bank and another filter bank and returns + * "true" if their parameters are equal. Alignment is not taken into + * account. + * + * @param s Filter bank to compare to. + * @return "True" if compared banks have equal parameters. + */ + + bool operator==(const CDSPFracFilterBankLin& s) const { + return (Order == s.Order && WFLen2 == s.WFLen2 && WFFreq == s.WFFreq && + WFAlpha == s.WFAlpha && FracCount == s.FracCount && + ExtFilter == s.ExtFilter); + } + + /** + * Function initializes (builds) the filter bank based on the supplied + * parameters. If the supplied parameters are equal to previously defined + * parameters, function does nothing (alignment is assumed to be never + * changing between the init() function calls). + * + * @param ReqFracCount Required number of fractional delays in the filter + * bank. The minimal value is 2. + * @param ReqOrder Required order of the interpolation polynomial + * (0 or 1). + * @param BaseLen Low-pass filter's base length, in samples (taps). + * Affects the actual length of the filter and its overall steepness. + * @param Cutoff Low-pass filter's normalized cutoff frequency [0; 1]. + * @param aWFAlpha Peaked Cosine window function's Alpha parameter. + * @param aExtFilter External filter to apply to each fractional delay + * filter. + * @param aAlignment Memory alignment of the filter bank, power-of-2 + * value. 0 - use default stdlib alignment. + * @param FltLenAlign Filter's length alignment, power-of-2 value. + */ + + void init(const int ReqFracCount, const int ReqOrder, const double BaseLen, + const double Cutoff, const double aWFAlpha, + const CFltBuffer& aExtFilter, const int aAlignment = 0, + const int FltLenAlign = 1) { + double NewWFLen2 = 0.5 * BaseLen * ReqFracCount; + double NewWFFreq = AVIR_PI * Cutoff / ReqFracCount; + double NewWFAlpha = aWFAlpha; + + if (ReqOrder == Order && NewWFLen2 == WFLen2 && NewWFFreq == WFFreq && + NewWFAlpha == WFAlpha && ReqFracCount == FracCount && + aExtFilter == ExtFilter) { + IsInitRequired = false; + return; + } + + WFLen2 = NewWFLen2; + WFFreq = NewWFFreq; + WFAlpha = NewWFAlpha; + FracCount = ReqFracCount; + Order = ReqOrder; + Alignment = aAlignment; + ExtFilter = aExtFilter; + + CDSPPeakedCosineLPF p(WFLen2, WFFreq, WFAlpha); + SrcFilterLen = (p.fl2 / ReqFracCount + 1) * 2; + + const int ElementSize = ReqOrder + 1; + FilterLen = SrcFilterLen; + + if (ExtFilter.getCapacity() > 0) { + FilterLen += ExtFilter.getCapacity() - 1; + } + + FilterLen = (FilterLen + FltLenAlign - 1) & ~(FltLenAlign - 1); + FilterSize = FilterLen * ElementSize; + IsSrcTableBuilt = false; + IsInitRequired = true; + } + + /** + * @return The length of each fractional delay filter, in samples (taps). + * Always an even value. + */ + + int getFilterLen() const { return (FilterLen); } + + /** + * @return The number of fractional filters in use by *this bank. + */ + + int getFracCount() const { return (FracCount); } + + /** + * @return The order of the interpolation polynomial. + */ + + int getOrder() const { return (Order); } + + /** + * Function returns the pointer to the specified interpolation table + * filter. + * + * @param i Filter (fractional delay) index, in the range 0 to + * ReqFracCount - 1, inclusive. + * @return Pointer to filter. Higher order polynomial coefficients are + * stored after after previous order coefficients, separated by FilterLen + * elements. + */ + + const fptype* getFilter(const int i) { + if (!IsSrcTableBuilt) { + buildSrcTable(); + } + + fptype* const Res = &Table[i * FilterSize]; + + if ((TableFillFlags[i] & 2) == 0) { + createFilter(i); + TableFillFlags[i] |= 2; + + if (Order > 0) { + createFilter(i + 1); + const fptype* const Res2 = Res + FilterSize; + fptype* const op = Res + FilterLen; + int j; + + // Create higher-order interpolation coefficients (linear + // interpolation). + + for (j = 0; j < FilterLen; j++) { + op[j] = Res2[j] - Res[j]; + } + } + } + + return (Res); + } + + /** + * Function makes sure all fractional delay filters were created. + */ + + void createAllFilters() { + int i; + + for (i = 0; i < FracCount; i++) { + getFilter(i); + } + } + + /** + * Function returns an approximate initialization complexity, expressed in + * the number of multiply-add operations. This includes fractional delay + * filters calculation and multiplication by an external filter. This + * function can only be called after the init() function. + * + * @param FracUseMap Fractional delays use map, each element corresponds + * to a single fractional delay, will be compared to the internal table + * fill flags. This map should include 0 and 1 values only. + * @return The complexity of the initialization, expressed in the number + * of multiply-add operations. + */ + + int calcInitComplexity(const CBuffer& FracUseMap) const { + const int FltInitCost = 65; // Cost to initialize a single sample + // of the fractional delay filter. + const int FltUseCost = + FilterLen * Order + + SrcFilterLen * ExtFilter.getCapacity(); // Cost to use a single + // fractional delay filter. + const int ucb[2] = {0, FltUseCost}; + int ic; + int i; + + if (IsInitRequired) { + ic = FracCount * SrcFilterLen * FltInitCost; + + for (i = 0; i < FracCount; i++) { + ic += ucb[FracUseMap[i]]; + } + } else { + ic = 0; + + for (i = 0; i < FracCount; i++) { + if (FracUseMap[i] != 0) { + ic += ucb[TableFillFlags[i] == 0 ? 1 : 0]; + } + } + } + + return (ic); + } + + private: + static const int InterpPoints = 2; ///< The maximal number of points the + ///< interpolation is based on. + ///< + double WFLen2; ///< Window function's Len2 parameter. + ///< + double WFFreq; ///< Window function's Freq parameter. + ///< + double WFAlpha; ///< Window function's Alpha parameter. + ///< + int FracCount; ///< The required number of fractional delay filters. + ///< + int Order; ///< The order of the interpolation polynomial. + ///< + int Alignment; ///< The required filter table alignment. + ///< + int SrcFilterLen; ///< Length of the "source" filters. This is always an + ///< even value. + ///< + int FilterLen; ///< Specifies the number of samples (taps) each fractional + ///< delay filter has. This is always an even value, adjusted + ///< by the FltLenAlign. + ///< + int FilterSize; ///< The size of a single filter element, equals + ///< FilterLen * ElementSize. + ///< + bool IsInitRequired; ///< "True" if SrcTable filter table initialization + ///< is required. This value is available only after the + ///< call to the init() function. + ///< + CBuffer Table; ///< Interpolation table, size equals to + ///< ReqFracCount * FilterLen * ElementSize. + ///< + CBuffer + TableFillFlags; ///< Contains ReqFracCount + 1 + ///< elements. Bit 0 of every element is 1 if Table + ///< already contains the filter from SrcTable filtered + ///< by ExtFilter. Bit 1 of every element means higher + ///< order coefficients were filled for the filter. + ///< + CFltBuffer ExtFilter; ///< External filter that should be applied to every + ///< fractional delay filter. Can be empty. Half of + ///< this filter's capacity is used as latency (group + ///< delay) value of the filter. + ///< + CBuffer SrcTable; ///< Source table of delay filters, contains + ///< ReqFracCount + 1 elements. This table is used + ///< to fill the Table with the actual filters, + ///< filtered by an external filter. + ///< + bool IsSrcTableBuilt; ///< "True" if the SrcTable was built already. This + ///< variable is set to "false" in the init() function. + ///< + + /** + * Function builds source table used in the createFilter() function. + */ + + void buildSrcTable() { + IsSrcTableBuilt = true; + IsInitRequired = false; + + CDSPPeakedCosineLPF p(WFLen2, WFFreq, WFAlpha); + + const int BufLen = SrcFilterLen * FracCount + InterpPoints - 1; + const int BufOffs = InterpPoints / 2 - 1; + const int BufCenter = SrcFilterLen * FracCount / 2 + BufOffs; + + CBuffer Buf(BufLen); + memset(Buf, 0, (BufCenter - p.fl2) * sizeof(double)); + int i = BufLen - BufCenter - p.fl2 - 1; + memset(&Buf[BufLen - i], 0, i * sizeof(double)); + + p.generateLPF(&Buf[BufCenter - p.fl2], FracCount); + abort(); + + SrcTable.alloc((FracCount + 1) * SrcFilterLen); + TableFillFlags.alloc(FracCount + 1); + int j; + double* op0 = SrcTable; + + for (i = FracCount; i >= 0; i--) { + TableFillFlags[i] = 0; + double* p = Buf + BufOffs + i; + + for (j = 0; j < SrcFilterLen; j++) { + op0[0] = p[0]; + op0++; + p += FracCount; + } + } + + Table.alloc((FracCount + 1) * FilterSize, Alignment); + } + + /** + * Function creates the specified filter in the Table by copying it from + * the SrcTable and filtering by ExtFilter. Function does nothing if + * filter was already created. + * + * @param k Filter index to create, in the range 0 to FracCount, + * inclusive. + */ + + void createFilter(const int k) { + if (TableFillFlags[k] != 0) { + return; + } + + TableFillFlags[k] |= 1; + const int ExtFilterLatency = ExtFilter.getCapacity() / 2; + const int ResLatency = ExtFilterLatency + SrcFilterLen / 2; + int ResLen = SrcFilterLen; + + if (ExtFilter.getCapacity() > 0) { + ResLen += ExtFilter.getCapacity() - 1; + } + + const int ResOffs = FilterLen / 2 - ResLatency; + fptype* op = &Table[k * FilterSize]; + int i; + + for (i = 0; i < ResOffs; i++) { + op[i] = 0.0; + } + + for (i = ResOffs + ResLen; i < FilterLen; i++) { + op[i] = 0.0; + } + + op += ResOffs; + const double* const srcflt = &SrcTable[k * SrcFilterLen]; + + if (ExtFilter.getCapacity() == 0) { + for (i = 0; i < ResLen; i++) { + op[i] = (fptype)srcflt[i]; + } + + return; + } + + // Perform convolution of extflt and srcflt. + + const double* const extflt = &ExtFilter[0]; + int j; + + for (j = 0; j < ResLen; j++) { + int k = 0; + int l = j - ExtFilter.getCapacity() + 1; + int r = l + ExtFilter.getCapacity(); + + if (l < 0) { + k -= l; + l = 0; + } + + if (r > SrcFilterLen) { + r = SrcFilterLen; + } + + const double* const extfltb = extflt + k; + const double* const srcfltb = srcflt + l; + double s = 0.0; + l = r - l; + + for (i = 0; i < l; i++) { + s += extfltb[i] * srcfltb[i]; + } + + op[j] = (fptype)s; + } + } +}; + +/** + * @brief Thread pool for multi-threaded image resizing operation. + * + * This base class is used to organize a multi-threaded image resizing + * operation. The thread pool should consist of threads that initially wait + * for a signal. Upon receiving a signal (via the startAllWorkloads() + * function) each previously added thread should execute its workload's + * process() function once, and return to the wait signal state again. The + * thread pool should be also able to efficiently wait for all workloads to + * finish via the waitAllWorkloadsToFinish() function. + * + * The image resizing algorithm makes calls to functions of this class. + */ + +class CImageResizerThreadPool { + public: + CImageResizerThreadPool() {} + + virtual ~CImageResizerThreadPool() {} + + /** + * @brief Thread pool's workload object class. + * + * This class should be used as a base class for objects that perform the + * actual work spread over several threads. + */ + + class CWorkload { + public: + virtual ~CWorkload() {} + + /** + * Function that gets called from the thread when thread pool's + * startAllWorkloads() function is called. + */ + + virtual void process() = 0; + }; + + /** + * @return The suggested number of workloads (and their associated + * threads) to add. The minimal value this function can return is 1. The + * usual value may depend on the number of physical and virtual cores + * present in the system, and on other considerations. + */ + + virtual int getSuggestedWorkloadCount() const { return (1); } + + /** + * Function adds a new workload (and possibly thread) to the thread pool. + * The caller decides how many parallel workloads (and threads) it + * requires, but this number will not exceed the value returned by the + * getSuggestedWorkloadCount() function. It is implementation-specific how + * many workloads to associate with a single thread. But for efficiency + * reasons each workload should be associated with its own thread. + * + * Note that the same set of workload objects will be processed each time + * the startAllWorkloads() function is called. This means that workload + * objects are added only once. The caller changes the state of the + * workload objects and then calls the startAllWorkloads() function to + * process them. + * + * @param Workload Workload object whose process() function will be called + * from within the thread when the startAllWorkloads() function is called. + */ + + virtual void addWorkload(CWorkload* const Workload) {} + + /** + * Function starts all workloads associated with threads previously added + * via the addWorkload() function. It is assumed that this function + * performs the necessary "memory barrier" (or "cache sync") kind of + * operation so that all threads catch up the prior changes made to the + * workload objects during their wait state. + */ + + virtual void startAllWorkloads() {} + + /** + * Function waits for all workloads to finish. + */ + + virtual void waitAllWorkloadsToFinish() {} + + /** + * Function removes all workloads previously added via the addWorkload() + * function. This function gets called only after the + * waitAllWorkloadsToFinish() function call. + */ + + virtual void removeAllWorkloads() {} +}; + +/** + * @brief Resizing algorithm parameters structure. + * + * This structure holds all selectable parameters used by the resizing + * algorithm at various stages, for both downsizing and upsizing. There are no + * other parameters exist that can optimize the performance of the resizing + * algorithm. Filter length parameters can take fractional values. + * + * Beside quality, these parameters (except Alpha parameters) directly affect + * the computative cost of the resizing algorithm. It is possible to trade + * the visual quality for computative cost. + * + * Anti-alias filtering during downsizing can be defined as a considerable + * reduction of contrast of smallest features of an image. Unfortunately, such + * de-contrasting partially affects features of all sizes thus producing a + * non-linearity of frequency response. All pre-defined parameter sets are + * described by 3 values separated by slashes. The first value is the + * de-contrasting factor of small features (which are being removed) while + * the second value is the de-contrasting factor of large features (which + * should remain intact), with value of 1 equating to "no contrast change". + * The third value is the optimization score (see below), with value of 0 + * equating to the "perfect" linearity of frequency response. + * + * The pre-defined parameter sets offered by this library were auto-optimized + * for the given LPFltBaseLen, IntFltLen and CorrFltAlpha values. The + * optimization goal was to minimize the score: the sum of squares of the + * difference between original and processed images (which was not actually + * resized, k=1). The original image was a 0.5 megapixel uniformly-distributed + * white-noise image with pixel intensities in the 0-1 range. Such goal + * converges very well and produces filtering system with the flattest + * frequency response possible for the given constraints. With this goal, + * increasing the LPFltBaseLen value reduces the general amount of aliasing + * artifacts. + */ + +struct CImageResizerParams { + double CorrFltAlpha; ///< Alpha parameter of the Peaked Cosine window + ///< function used on the correction filter. The + ///< "usable" values are in the narrow range 1.0 to 1.5. + ///< + double CorrFltLen; ///< Correction filter's length in samples (taps). The + ///< "usable" range is narrow, 5.5 to 8, as to minimize + ///< the "overcorrection" which is mathematically precise, + ///< but visually unacceptable. + ///< + double IntFltAlpha; ///< Alpha parameter of the Peaked Cosine window + ///< function used on the interpolation low-pass filter. + ///< The "usable" values are in the range 1.5 to 2.5. + ///< + double IntFltCutoff; ///< Interpolation low-pass filter's cutoff frequency + ///< (normalized, [0; 1]). The "usable" range is 0.6 to + ///< 0.8. + ///< + double IntFltLen; ///< Interpolation low-pass filter's length in samples + ///< (taps). The length value should be at least 18 or + ///< otherwise a "dark grid" artifact will be introduced if + ///< a further sharpening is applied. IntFltLen together + ///< with other IntFlt parameters should be tuned in a way + ///< that produces the flattest frequency response in 0-0.5 + ///< normalized frequency range (this range is due to 2X + ///< upsampling). + ///< + double LPFltAlpha; ///< Alpha parameter of the Peaked Cosine window + ///< function used on the low-pass filter. The "usable" + ///< values are in the range 1.5 to 6.5. + ///< + double LPFltBaseLen; ///< Base length of the low-pass (aka anti-aliasing + ///< or reconstruction) filter, in samples (taps), + ///< further adjusted by the actual cutoff frequency, + ///< upsampling and downsampling factors. The "usable" + ///< range is between 6 and 9. + ///< + double LPFltCutoffMult; ///< Low-pass filter's cutoff frequency + ///< multiplier. This value can be both below and + ///< above 1.0 as low-pass filters are inserted on + ///< downsampling and upsampling steps and always + ///< have corner frequency equal to or below 0.5pi. + ///< This multiplier shifts low-pass filter's corner + ///< frequency towards lower (if below 1.0) or higher + ///< (if above 1.0) frequencies. This multiplier can + ///< be way below 1.0 since any additional + ///< high-frequency damping will be partially + ///< corrected by the correction filter. The "usable" + ///< range is 0.3 to 1.0. + ///< + + CImageResizerParams() + : HBFltAlpha(1.75395), HBFltCutoff(0.40356), HBFltLen(22.00000) {} + + double HBFltAlpha; ///< Half-band filter's Alpha. Assigned internally. + ///< + double HBFltCutoff; ///< Half-band filter's cutoff point [0; 1]. Assigned + ///< internally. + ///< + double HBFltLen; ///< Length of the half-band low-pass filter. Assigned + ///< internally. Internally used to perform 2X or higher + ///< downsampling. These filter parameters should be treated + ///< as "technical" and do not require adjustment as they + ///< were tuned to suit all combinations of other + ///< parameters. This half-band filter provides a wide + ///< transition band (for minimal ringing artifacts) and a + ///< high stop-band attenuation (for minimal aliasing). + ///< +}; + +/** + * @brief The default set of resizing algorithm parameters + * (10.01/1.029/0.019169). + * + * This is the default set of resizing parameters that was designed to deliver + * a sharp image while still providing a low amount of ringing artifacts, and + * having a reasonable computational cost. + */ + +struct CImageResizerParamsDef : public CImageResizerParams { + CImageResizerParamsDef() { + CorrFltAlpha = 1.0; // 10.01/1.88/1.029(522.43)/0.019169:258648,446808 + CorrFltLen = 6.30770; + IntFltAlpha = 2.27825; + IntFltCutoff = 0.75493; + IntFltLen = 18.0; + LPFltAlpha = 3.40127; + LPFltBaseLen = 7.78; + LPFltCutoffMult = 0.78797; + } +}; + +/** + * @brief Set of resizing algorithm parameters for ultra-low-ringing + * performance (7.69/1.069/0.000245). + * + * This set of resizing algorithm parameters offers the lowest amount of + * ringing this library is capable of providing while still offering a decent + * quality. Low ringing is attained at the expense of higher aliasing + * artifacts and a slightly reduced contrast. + */ + +struct CImageResizerParamsULR : public CImageResizerParams { + CImageResizerParamsULR() { + CorrFltAlpha = 1.0; // 7.69/1.97/1.069(31445.45)/0.000245:258627,436845 + CorrFltLen = 5.83280; + IntFltAlpha = 2.11453; + IntFltCutoff = 0.73986; + IntFltLen = 18.0; + LPFltAlpha = 1.73455; + LPFltBaseLen = 6.40; + LPFltCutoffMult = 0.61314; + } +}; + +/** + * @brief Set of resizing algorithm parameters for low-ringing performance + * (7.86/1.065/0.000106). + * + * This set of resizing algorithm parameters offers a very low-ringing + * performance at the expense of higher aliasing artifacts and a slightly + * reduced contrast. + */ + +struct CImageResizerParamsLR : public CImageResizerParams { + CImageResizerParamsLR() { + CorrFltAlpha = 1.0; // 7.86/1.96/1.065(73865.02)/0.000106:258636,437381 + CorrFltLen = 5.87671; + IntFltAlpha = 2.25322; + IntFltCutoff = 0.74090; + IntFltLen = 18.0; + LPFltAlpha = 1.79306; + LPFltBaseLen = 7.00; + LPFltCutoffMult = 0.68881; + } +}; + +/** + * @brief Set of resizing algorithm parameters for lower-ringing performance + * (8.86/1.046/0.010168). + * + * This set of resizing algorithm parameters offers a lower-ringing + * performance in comparison to the default setting, at the expense of higher + * aliasing artifacts and a slightly reduced contrast. + */ + +struct CImageResizerParamsLow : public CImageResizerParams { + CImageResizerParamsLow() { + CorrFltAlpha = 1.0; // 8.86/1.92/1.046(871.54)/0.010168:258647,442252 + CorrFltLen = 6.09757; + IntFltAlpha = 2.36704; + IntFltCutoff = 0.74674; + IntFltLen = 18.0; + LPFltAlpha = 2.19427; + LPFltBaseLen = 7.66; + LPFltCutoffMult = 0.75380; + } +}; + +/** + * @brief Set of resizing algorithm parameters for low-aliasing + * resizing (11.81/1.012/0.038379). + * + * This set of resizing algorithm parameters offers a considerable + * anti-aliasing performance with a good frequency response linearity (and + * contrast). This is an intermediate setting between the default and Ultra + * parameters. + */ + +struct CImageResizerParamsHigh : public CImageResizerParams { + CImageResizerParamsHigh() { + CorrFltAlpha = 1.0; // 11.81/1.83/1.012(307.84)/0.038379:258660,452719 + CorrFltLen = 6.80909; + IntFltAlpha = 2.44917; + IntFltCutoff = 0.75856; + IntFltLen = 18.0; + LPFltAlpha = 4.39527; + LPFltBaseLen = 8.18; + LPFltCutoffMult = 0.79172; + } +}; + +/** + * @brief Set of resizing algorithm parameters for ultra low-aliasing + * resizing (13.65/1.001/0.000483). + * + * This set of resizing algorithm parameters offers a very considerable + * anti-aliasing performance with a good frequency response linearity (and + * contrast). This set of parameters is computationally expensive and may + * produce ringing artifacts on sharp features. + */ + +struct CImageResizerParamsUltra : public CImageResizerParams { + CImageResizerParamsUltra() { + CorrFltAlpha = 1.0; // 13.65/1.79/1.001(28288.41)/0.000483:258658,457974 + CorrFltLen = 7.48060; + IntFltAlpha = 1.93750; + IntFltCutoff = 0.75462; + IntFltLen = 18.0; + LPFltAlpha = 5.55209; + LPFltBaseLen = 8.34; + LPFltCutoffMult = 0.78002; + } +}; + +/** + * @brief Image resizing variables class. + * + * This is an utility "catch all" class that defines various variables used + * during image resizing. Several variables that are explicitly initialized in + * this class' constructor are also used as additional "input" variables to + * the image resizing function. These variables will not be changed by the + * avir::CImageResizer<>::resizeImage() function. + */ + +class CImageResizerVars { + public: + int ElCount; ///< The number of "fptype" elements used to store 1 pixel. + ///< + int ElCountIO; ///< The number of source and destination image's elements + ///< used to store 1 pixel. + ///< + int fppack; ///< The number of atomic types stored in a single "fptype" + ///< element. + ///< + int fpalign; ///< Suggested alignment size in bytes. This is not a + ///< required alignment, because image resizing algorithm cannot + ///< be made to have a strictly aligned data access in all cases + ///< (e.g. de-interleaved interpolation cannot perform aligned + ///< accesses). + ///< + int elalign; ///< Length alignment of arrays of elements. This applies to + ///< filters and intermediate buffers: this constant forces + ///< filters and scanlines to have a length which is a multiple + ///< of this value, for more efficient SIMD implementation. + ///< + int packmode; ///< 0 if interleaved packing, 1 if de-interleaved. + ///< + int BufLen[2]; ///< Intermediate buffers' lengths in "fptype" elements. + int BufOffs[2]; ///< Offsets into the intermediate buffers, used to + ///< provide prefix elements required during processing so + ///< that no "out of range" access happens. This offset is a + ///< multiple of ElCount if pixels are stored in interleaved + ///< form. + ///< + double k; ///< Resizing step coefficient, updated to reflect the actually + ///< used coefficient during resizing. + ///< + double o; ///< Starting pixel offset inside the source image, updated to + ///< reflect the actually used offset during resizing. + ///< + int ResizeStep; ///< Index of the resizing step in the latest filtering + ///< steps array. + ///< + double InGammaMult; ///< Input gamma multiplier, used to convert input + ///< data to 0 to 1 range. 0.0 if no gamma is in use. + ///< + double OutGammaMult; ///< Output gamma multiplier, used to convert data to + ///< 0 to 255/65535 range. 0.0 if no gamma is in use. + ///< + + double ox; ///< Start X pixel offset within source image (can be + ///< negative). Positive offset moves image to the left. + ///< + double oy; ///< Start Y pixel offset within source image (can be + ///< negative). Positive offset moves image to the top. + ///< + CImageResizerThreadPool* + ThreadPool; ///< Thread pool to be used by the + ///< image resizing function. Set to NULL to use + ///< single-threaded processing. + ///< + bool UseSRGBGamma; ///< Perform sRGB gamma linearization (correction). + ///< + int BuildMode; ///< The build mode to use, for debugging purposes. Set to + ///< -1 to select a minimal-complexity mode automatically. All + ///< build modes deliver similar results with minor + ///< deviations. + ///< + int RndSeed; ///< Random seed parameter. This parameter may be incremented + ///< after each random generator initialization. The use of this + ///< variable depends on the ditherer implementation. + ///< + + CImageResizerVars() + : ox(0.0), + oy(0.0), + ThreadPool(NULL), + UseSRGBGamma(false), + BuildMode(-1), + RndSeed(0) {} +}; + +/** + * @brief Image resizer's filtering step class. + * + * Class defines data to perform a single filtering step over a whole + * horizontal or vertical scanline. Resizing consists of 1 or more steps that + * may be performed before the actual resizing takes place. Filtering may also + * follow a resizing step. Each step must ensure that scanline data contains + * enough pixels to perform the next step (which may be resizing) without + * exceeding scanline's bounds. + * + * A derived class must implement several "const" and "static" functions that + * are used to perform the actual filtering in interleaved or de-interleaved + * mode. + * + * @tparam fptype Floating point type to use for storing pixel elements. SIMD + * types can be used: in this case each element may hold a whole pixel. + * @tparam fptypeatom The atomic type the "fptype" consists of. + */ + +template +class CImageResizerFilterStep { + public: + bool IsUpsample; ///< "True" if this step is an upsampling step, "false" + ///< if downsampling step. Should be set to "false" if + ///< ResampleFactor equals 0. + ///< + int ResampleFactor; ///< Resample factor (>=1). If 0, this is a resizing + ///< step. This value should be >1 if IsUpsample equals + ///< "true". + ///< + CBuffer Flt; ///< Filter to use at this step. + ///< + CFltBuffer FltOrig; ///< Originally-designed filter. This buffer may not + ///< be assigned. Assigned by filters that precede the + ///< resizing step if such filter is planned to be + ///< embedded into the interpolation filter as "external" + ///< filter. If IsUpsample=true and this filter buffer is + ///< not empty, the upsampling step will not itself apply + ///< any filtering over upsampled input scanline. + ///< + double DCGain; ///< DC gain which was applied to the filter. Not defined + ///< if ResampleFactor = 0. + ///< + int FltLatency; ///< Filter's latency (group delay, shift) in pixels. + ///< + const CImageResizerVars* Vars; ///< Image resizing-related variables. + ///< + int InLen; ///< Input scanline's length in pixels. + ///< + int InBuf; ///< Input buffer index, 0 or 1. + ///< + int InPrefix; ///< Required input prefix pixels. These prefix pixels will + ///< be filled with source scanline's first pixel value. If + ///< IsUpsample is "true", this is the additional number of + ///< times the first pixel will be filtered before processing + ///< scanline, this number is also reflected in the OutPrefix. + ///< + int InSuffix; ///< Required input suffix pixels. These suffix pixels will + ///< be filled with source scanline's last pixel value. If + ///< IsUpsample is "true", this is the additional number of + ///< times the last pixel will be filtered before processing + ///< scanline, this number is also reflected in the OutSuffix. + ///< + int InElIncr; ///< Pixel element increment within the input buffer, used + ///< during de-interleaved processing: in this case each + ///< image's channel is stored independently, InElIncr elements + ///< apart. + ///< + int OutLen; ///< Length of the resulting scanline. + ///< + int OutBuf; ///< Output buffer index. 0 or 1; 2 for the last step. + ///< + int OutPrefix; ///< Required output prefix pixels. These prefix pixels + ///< will not be pre-filled with any values. Value is valid + ///< only if IsUpsample equals "true". + ///< + int OutSuffix; ///< Required input suffix pixels. These suffix pixels will + ///< not be pre-filled with any values. Value is valid only if + ///< IsUpsample equals "true". + ///< + int OutElIncr; ///< Pixel element increment within the output buffer, used + ///< during de-interleaved processing. Equals to the + ///< InBufElIncr of the next step. + ///< + CBuffer PrefixDC; ///< DC component fluctuations added at the + ///< start of the resulting scanline, used when + ///< IsUpsample equals "true". + ///< + CBuffer SuffixDC; ///< DC component fluctuations added at the + ///< end of the resulting scanline, used when + ///< IsUpsample equals "true". + ///< + int EdgePixelCount; ///< The number of edge pixels added. Affects the + ///< initial position within the input scanline, used to + ///< produce edge pixels. This variable is used and + ///< should be defined when IsUpsample=false and + ///< ResampleFactor>0. When assigning this variable it is + ///< also necessary to update InPrefix, OutLen and Vars.o + ///< variables. + ///< + static const int EdgePixelCountDef = + 3; ///< The default number of pixels + ///< additionally produced at scanline edges during filtering. This is + ///< required to reduce edge artifacts. + ///< + + /** + * @brief Resizing position structure. + * + * Structure holds resizing position and pointer to fractional delay + * filter. + */ + + struct CResizePos { + int SrcPosInt; ///< Source scanline position. + ///< + int fti; ///< Fractional delay filter index. + ///< + const fptype* ftp; ///< Fractional delay filter pointer. + ///< + fptypeatom x; ///< Interpolation coefficient between delay filters. + ///< + int SrcOffs; ///< Source scanline offset. + ///< + }; + + /** + * @brief Resizing positions buffer class. + * + * This class combines buffer together with variables that define resizing + * stepping. + */ + + class CRPosBuf : public CBuffer { + public: + double k; ///< Resizing step. + ///< + double o; ///< Resizing offset. + ///< + int FracCount; ///< The number of fractional delay filters in a filter + ///< bank used together with this buffer. + ///< + }; + + /** + * @brief Resizing positions buffer array class. + * + * This class combines structure array of the CRPosBuf class objects with + * the function that locates or creates buffer with the required resizing + * stepping. + */ + + class CRPosBufArray : public CStructArray { + public: + using CStructArray::add; + using CStructArray::getItemCount; + + /** + * Function returns the resizing positions buffer with the required + * stepping. If no such buffer exists, it is created. + * + * @param k Resizing step. + * @param o Resizing offset. + * @param FracCount The number of fractional delay filters in a filter + * bank used together with this buffer. + * @return Reference to the CRPosBuf object. + */ + + CRPosBuf& getRPosBuf(const double k, const double o, const int FracCount) { + int i; + + for (i = 0; i < getItemCount(); i++) { + CRPosBuf& Buf = (*this)[i]; + + if (Buf.k == k && Buf.o == o && Buf.FracCount == FracCount) { + return (Buf); + } + } + + CRPosBuf& NewBuf = add(); + NewBuf.k = k; + NewBuf.o = o; + NewBuf.FracCount = FracCount; + + return (NewBuf); + } + }; + + CRPosBuf* RPosBuf; ///< Resizing positions buffer. Used when + ///< ResampleFactor equals 0 (resizing step). + ///< + CDSPFracFilterBankLin* FltBank; ///< Filter bank in use by *this + ///< resizing step. + ///< +}; + +/** + * @brief Interleaved filtering steps implementation class. + * + * This class implements scanline filtering functions in interleaved mode. + * This means that each pixel is processed independently, not in groups. + * + * @tparam fptype Floating point type to use for storing pixel elements. SIMD + * types can be used: in this case each element may hold a whole pixel. + * @tparam fptypeatom The atomic type the "fptype" consists of. + */ + +template +class CImageResizerFilterStepINL + : public CImageResizerFilterStep { + public: + using CImageResizerFilterStep::IsUpsample; + using CImageResizerFilterStep::ResampleFactor; + using CImageResizerFilterStep::Flt; + using CImageResizerFilterStep::FltOrig; + using CImageResizerFilterStep::FltLatency; + using CImageResizerFilterStep::Vars; + using CImageResizerFilterStep::InLen; + using CImageResizerFilterStep::InPrefix; + using CImageResizerFilterStep::InSuffix; + using CImageResizerFilterStep::OutLen; + using CImageResizerFilterStep::OutPrefix; + using CImageResizerFilterStep::OutSuffix; + using CImageResizerFilterStep::PrefixDC; + using CImageResizerFilterStep::SuffixDC; + using CImageResizerFilterStep::RPosBuf; + using CImageResizerFilterStep::FltBank; + using CImageResizerFilterStep::EdgePixelCount; + + /** + * Function performs "packing" of a scanline and type conversion. + * Scanline, depending on the "fptype" can be potentially stored as a + * packed SIMD values having a certain atomic type. If required, the sRGB + * gamma correction is applied. + * + * @param ip Input scanline. + * @param op0 Output scanline. + * @param l0 The number of pixels to "pack". + */ + + template + void packScanline(const Tin* ip, fptype* const op0, const int l0) const { + const int ElCount = Vars->ElCount; + const int ElCountIO = Vars->ElCountIO; + fptype* op = op0; + int l = l0; + + if (!Vars->UseSRGBGamma) { + if (ElCountIO == 1) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op; + v[0] = (fptypeatom)ip[0]; + op += ElCount; + ip++; + l--; + } + } else if (ElCountIO == 4) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op; + v[0] = (fptypeatom)ip[0]; + v[1] = (fptypeatom)ip[1]; + v[2] = (fptypeatom)ip[2]; + v[3] = (fptypeatom)ip[3]; + op += ElCount; + ip += 4; + l--; + } + } else if (ElCountIO == 3) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op; + v[0] = (fptypeatom)ip[0]; + v[1] = (fptypeatom)ip[1]; + v[2] = (fptypeatom)ip[2]; + op += ElCount; + ip += 3; + l--; + } + } else if (ElCountIO == 2) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op; + v[0] = (fptypeatom)ip[0]; + v[1] = (fptypeatom)ip[1]; + op += ElCount; + ip += 2; + l--; + } + } + } else { + const fptypeatom gm = (fptypeatom)Vars->InGammaMult; + + if (ElCountIO == 1) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op; + v[0] = convertSRGB2Lin((fptypeatom)ip[0] * gm); + op += ElCount; + ip++; + l--; + } + } else if (ElCountIO == 4) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op; + v[0] = convertSRGB2Lin((fptypeatom)ip[0] * gm); + v[1] = convertSRGB2Lin((fptypeatom)ip[1] * gm); + v[2] = convertSRGB2Lin((fptypeatom)ip[2] * gm); + v[3] = convertSRGB2Lin((fptypeatom)ip[3] * gm); + op += ElCount; + ip += 4; + l--; + } + } else if (ElCountIO == 3) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op; + v[0] = convertSRGB2Lin((fptypeatom)ip[0] * gm); + v[1] = convertSRGB2Lin((fptypeatom)ip[1] * gm); + v[2] = convertSRGB2Lin((fptypeatom)ip[2] * gm); + op += ElCount; + ip += 3; + l--; + } + } else if (ElCountIO == 2) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op; + v[0] = convertSRGB2Lin((fptypeatom)ip[0] * gm); + v[1] = convertSRGB2Lin((fptypeatom)ip[1] * gm); + op += ElCount; + ip += 2; + l--; + } + } + } + + const int ZeroCount = ElCount * Vars->fppack - ElCountIO; + op = op0; + l = l0; + + if (ZeroCount == 1) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op + ElCountIO; + v[0] = (fptypeatom)0; + op += ElCount; + l--; + } + } else if (ZeroCount == 2) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op + ElCountIO; + v[0] = (fptypeatom)0; + v[1] = (fptypeatom)0; + op += ElCount; + l--; + } + } else if (ZeroCount == 3) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)op + ElCountIO; + v[0] = (fptypeatom)0; + v[1] = (fptypeatom)0; + v[2] = (fptypeatom)0; + op += ElCount; + l--; + } + } + } + + /** + * Function applies Linear to sRGB gamma correction to the specified + * scanline. + * + * @param p Scanline. + * @param l The number of pixels to de-linearize. + * @param Vars0 Image resizing-related variables. + */ + + static void applySRGBGamma(fptype* p, int l, const CImageResizerVars& Vars0) { + const int ElCount = Vars0.ElCount; + const int ElCountIO = Vars0.ElCountIO; + const fptypeatom gm = (fptypeatom)Vars0.OutGammaMult; + + if (ElCountIO == 1) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)p; + v[0] = convertLin2SRGB(v[0]) * gm; + p += ElCount; + l--; + } + } else if (ElCountIO == 4) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)p; + v[0] = convertLin2SRGB(v[0]) * gm; + v[1] = convertLin2SRGB(v[1]) * gm; + v[2] = convertLin2SRGB(v[2]) * gm; + v[3] = convertLin2SRGB(v[3]) * gm; + p += ElCount; + l--; + } + } else if (ElCountIO == 3) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)p; + v[0] = convertLin2SRGB(v[0]) * gm; + v[1] = convertLin2SRGB(v[1]) * gm; + v[2] = convertLin2SRGB(v[2]) * gm; + p += ElCount; + l--; + } + } else if (ElCountIO == 2) { + while (l > 0) { + fptypeatom* v = (fptypeatom*)p; + v[0] = convertLin2SRGB(v[0]) * gm; + v[1] = convertLin2SRGB(v[1]) * gm; + p += ElCount; + l--; + } + } + } + + /** + * Function converts vertical scanline to horizontal scanline. This + * function is called by the image resizer when image is resized + * vertically. This means that the vertical scanline is stored in the + * same format produced by the packScanline() and maintained by other + * filtering functions. + * + * @param ip Input vertical scanline. + * @param op Output buffer (temporary buffer used during resizing). + * @param SrcLen The number of pixels in the input scanline, also used to + * calculate input buffer increment. + * @param SrcIncr Input buffer increment to the next vertical pixel. + */ + + void convertVtoH(const fptype* ip, fptype* op, const int SrcLen, + const int SrcIncr) const { + const int ElCount = Vars->ElCount; + int j; + + if (ElCount == 1) { + for (j = 0; j < SrcLen; j++) { + op[0] = ip[0]; + ip += SrcIncr; + op++; + } + } else if (ElCount == 4) { + for (j = 0; j < SrcLen; j++) { + op[0] = ip[0]; + op[1] = ip[1]; + op[2] = ip[2]; + op[3] = ip[3]; + ip += SrcIncr; + op += 4; + } + } else if (ElCount == 3) { + for (j = 0; j < SrcLen; j++) { + op[0] = ip[0]; + op[1] = ip[1]; + op[2] = ip[2]; + ip += SrcIncr; + op += 3; + } + } else if (ElCount == 2) { + for (j = 0; j < SrcLen; j++) { + op[0] = ip[0]; + op[1] = ip[1]; + ip += SrcIncr; + op += 2; + } + } + } + + /** + * Function performs "unpacking" of a scanline and type conversion + * (truncation is used when floating point is converted to integer). + * Scanline, depending on the "fptype" can be potentially stored as a + * packed SIMD values having a certain atomic type. The unpacking function + * assumes that scanline is stored in the style produced by the + * packScanline() function. + * + * @param ip Input scanline. + * @param op Output scanline. + * @param l The number of pixels to "unpack". + * @param Vars0 Image resizing-related variables. + */ + + template + static void unpackScanline(const fptype* ip, Tout* op, int l, + const CImageResizerVars& Vars0) { + const int ElCount = Vars0.ElCount; + const int ElCountIO = Vars0.ElCountIO; + + if (ElCountIO == 1) { + while (l > 0) { + const fptypeatom* v = (const fptypeatom*)ip; + op[0] = (Tout)v[0]; + ip += ElCount; + op++; + l--; + } + } else if (ElCountIO == 4) { + while (l > 0) { + const fptypeatom* v = (const fptypeatom*)ip; + op[0] = (Tout)v[0]; + op[1] = (Tout)v[1]; + op[2] = (Tout)v[2]; + op[3] = (Tout)v[3]; + ip += ElCount; + op += 4; + l--; + } + } else if (ElCountIO == 3) { + while (l > 0) { + const fptypeatom* v = (const fptypeatom*)ip; + op[0] = (Tout)v[0]; + op[1] = (Tout)v[1]; + op[2] = (Tout)v[2]; + ip += ElCount; + op += 3; + l--; + } + } else if (ElCountIO == 2) { + while (l > 0) { + const fptypeatom* v = (const fptypeatom*)ip; + op[0] = (Tout)v[0]; + op[1] = (Tout)v[1]; + ip += ElCount; + op += 2; + l--; + } + } + } + + /** + * Function prepares input scanline buffer for *this filtering step. + * Left- and right-most pixels are replicated to make sure no buffer + * overrun happens. Such approach also allows to bypass any pointer + * range checks. + * + * @param Src Source buffer. + */ + + void prepareInBuf(fptype* Src) const { + if (IsUpsample || InPrefix + InSuffix == 0) { + return; + } + + const int ElCount = Vars->ElCount; + replicateArray(Src, ElCount, Src - ElCount, InPrefix, -ElCount); + + Src += (InLen - 1) * ElCount; + replicateArray(Src, ElCount, Src + ElCount, InSuffix, ElCount); + } + + /** + * Function peforms scanline upsampling with filtering. + * + * @param Src Source scanline buffer (length = this -> InLen). Source + * scanline increment will be equal to ElCount. + * @param Dst Destination scanline buffer. + */ + + void doUpsample(const fptype* const Src, fptype* const Dst) const { + const int ElCount = Vars->ElCount; + fptype* op0 = &Dst[-OutPrefix * ElCount]; + memset(op0, 0, (OutPrefix + OutLen + OutSuffix) * ElCount * sizeof(fptype)); + + const fptype* ip = Src; + const int opstep = ElCount * ResampleFactor; + int l; + + if (FltOrig.getCapacity() > 0) { + // Do not perform filtering, only upsample. + + op0 += (OutPrefix % ResampleFactor) * ElCount; + l = OutPrefix / ResampleFactor; + + if (ElCount == 1) { + while (l > 0) { + op0[0] = ip[0]; + op0 += opstep; + l--; + } + + l = InLen - 1; + + while (l > 0) { + op0[0] = ip[0]; + op0 += opstep; + ip += ElCount; + l--; + } + + l = OutSuffix / ResampleFactor; + + while (l >= 0) { + op0[0] = ip[0]; + op0 += opstep; + l--; + } + } else if (ElCount == 4) { + while (l > 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0[2] = ip[2]; + op0[3] = ip[3]; + op0 += opstep; + l--; + } + + l = InLen - 1; + + while (l > 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0[2] = ip[2]; + op0[3] = ip[3]; + op0 += opstep; + ip += ElCount; + l--; + } + + l = OutSuffix / ResampleFactor; + + while (l >= 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0[2] = ip[2]; + op0[3] = ip[3]; + op0 += opstep; + l--; + } + } else if (ElCount == 3) { + while (l > 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0[2] = ip[2]; + op0 += opstep; + l--; + } + + l = InLen - 1; + + while (l > 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0[2] = ip[2]; + op0 += opstep; + ip += ElCount; + l--; + } + + l = OutSuffix / ResampleFactor; + + while (l >= 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0[2] = ip[2]; + op0 += opstep; + l--; + } + } else if (ElCount == 2) { + while (l > 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0 += opstep; + l--; + } + + l = InLen - 1; + + while (l > 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0 += opstep; + ip += ElCount; + l--; + } + + l = OutSuffix / ResampleFactor; + + while (l >= 0) { + op0[0] = ip[0]; + op0[1] = ip[1]; + op0 += opstep; + l--; + } + } + + return; + } + + const fptype* const f = Flt; + const int flen = Flt.getCapacity(); + fptype* op; + int i; + + if (ElCount == 1) { + l = InPrefix; + + while (l > 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[i] += f[i] * ip[0]; + } + + op0 += opstep; + l--; + } + + l = InLen - 1; + + while (l > 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[i] += f[i] * ip[0]; + } + + ip += ElCount; + op0 += opstep; + l--; + } + + l = InSuffix; + + while (l >= 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[i] += f[i] * ip[0]; + } + + op0 += opstep; + l--; + } + } else if (ElCount == 4) { + l = InPrefix; + + while (l > 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op[2] += f[i] * ip[2]; + op[3] += f[i] * ip[3]; + op += 4; + } + + op0 += opstep; + l--; + } + + l = InLen - 1; + + while (l > 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op[2] += f[i] * ip[2]; + op[3] += f[i] * ip[3]; + op += 4; + } + + ip += ElCount; + op0 += opstep; + l--; + } + + l = InSuffix; + + while (l >= 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op[2] += f[i] * ip[2]; + op[3] += f[i] * ip[3]; + op += 4; + } + + op0 += opstep; + l--; + } + } else if (ElCount == 3) { + l = InPrefix; + + while (l > 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op[2] += f[i] * ip[2]; + op += 3; + } + + op0 += opstep; + l--; + } + + l = InLen - 1; + + while (l > 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op[2] += f[i] * ip[2]; + op += 3; + } + + ip += ElCount; + op0 += opstep; + l--; + } + + l = InSuffix; + + while (l >= 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op[2] += f[i] * ip[2]; + op += 3; + } + + op0 += opstep; + l--; + } + } else if (ElCount == 2) { + l = InPrefix; + + while (l > 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op += 2; + } + + op0 += opstep; + l--; + } + + l = InLen - 1; + + while (l > 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op += 2; + } + + ip += ElCount; + op0 += opstep; + l--; + } + + l = InSuffix; + + while (l >= 0) { + op = op0; + + for (i = 0; i < flen; i++) { + op[0] += f[i] * ip[0]; + op[1] += f[i] * ip[1]; + op += 2; + } + + op0 += opstep; + l--; + } + } + + op = op0; + const fptype* dc = SuffixDC; + l = SuffixDC.getCapacity(); + + if (ElCount == 1) { + for (i = 0; i < l; i++) { + op[i] += ip[0] * dc[i]; + } + } else if (ElCount == 4) { + while (l > 0) { + op[0] += ip[0] * dc[0]; + op[1] += ip[1] * dc[0]; + op[2] += ip[2] * dc[0]; + op[3] += ip[3] * dc[0]; + dc++; + op += 4; + l--; + } + } else if (ElCount == 3) { + while (l > 0) { + op[0] += ip[0] * dc[0]; + op[1] += ip[1] * dc[0]; + op[2] += ip[2] * dc[0]; + dc++; + op += 3; + l--; + } + } else if (ElCount == 2) { + while (l > 0) { + op[0] += ip[0] * dc[0]; + op[1] += ip[1] * dc[0]; + dc++; + op += 2; + l--; + } + } + + ip = Src; + op = Dst - InPrefix * opstep; + dc = PrefixDC; + l = PrefixDC.getCapacity(); + + if (ElCount == 1) { + for (i = 0; i < l; i++) { + op[i] += ip[0] * dc[i]; + } + } else if (ElCount == 4) { + while (l > 0) { + op[0] += ip[0] * dc[0]; + op[1] += ip[1] * dc[0]; + op[2] += ip[2] * dc[0]; + op[3] += ip[3] * dc[0]; + dc++; + op += 4; + l--; + } + } else if (ElCount == 3) { + while (l > 0) { + op[0] += ip[0] * dc[0]; + op[1] += ip[1] * dc[0]; + op[2] += ip[2] * dc[0]; + dc++; + op += 3; + l--; + } + } else if (ElCount == 2) { + while (l > 0) { + op[0] += ip[0] * dc[0]; + op[1] += ip[1] * dc[0]; + dc++; + op += 2; + l--; + } + } + } + + /** + * Function peforms scanline filtering with optional downsampling. + * Function makes use of the symmetry of the filter. + * + * @param Src Source scanline buffer (length = this -> InLen). Source + * scanline increment will be equal to ElCount. + * @param Dst Destination scanline buffer. + * @param DstIncr Destination scanline buffer increment, used for + * horizontal or vertical scanline stepping. + */ + + void doFilter(const fptype* const Src, fptype* Dst, const int DstIncr) const { + const int ElCount = Vars->ElCount; + const fptype* const f = &Flt[FltLatency]; + const int flen = FltLatency + 1; + const int ipstep = ElCount * ResampleFactor; + const fptype* ip = Src - EdgePixelCount * ipstep; + const fptype* ip1; + const fptype* ip2; + int l = OutLen; + int i; + + if (ElCount == 1) { + while (l > 0) { + fptype s = f[0] * ip[0]; + ip1 = ip; + ip2 = ip; + + for (i = 1; i < flen; i++) { + ip1++; + ip2--; + s += f[i] * (ip1[0] + ip2[0]); + } + + Dst[0] = s; + Dst += DstIncr; + ip += ipstep; + l--; + } + } else if (ElCount == 4) { + while (l > 0) { + fptype s1 = f[0] * ip[0]; + fptype s2 = f[0] * ip[1]; + fptype s3 = f[0] * ip[2]; + fptype s4 = f[0] * ip[3]; + ip1 = ip; + ip2 = ip; + + for (i = 1; i < flen; i++) { + ip1 += 4; + ip2 -= 4; + s1 += f[i] * (ip1[0] + ip2[0]); + s2 += f[i] * (ip1[1] + ip2[1]); + s3 += f[i] * (ip1[2] + ip2[2]); + s4 += f[i] * (ip1[3] + ip2[3]); + } + + Dst[0] = s1; + Dst[1] = s2; + Dst[2] = s3; + Dst[3] = s4; + Dst += DstIncr; + ip += ipstep; + l--; + } + } else if (ElCount == 3) { + while (l > 0) { + fptype s1 = f[0] * ip[0]; + fptype s2 = f[0] * ip[1]; + fptype s3 = f[0] * ip[2]; + ip1 = ip; + ip2 = ip; + + for (i = 1; i < flen; i++) { + ip1 += 3; + ip2 -= 3; + s1 += f[i] * (ip1[0] + ip2[0]); + s2 += f[i] * (ip1[1] + ip2[1]); + s3 += f[i] * (ip1[2] + ip2[2]); + } + + Dst[0] = s1; + Dst[1] = s2; + Dst[2] = s3; + Dst += DstIncr; + ip += ipstep; + l--; + } + } else if (ElCount == 2) { + while (l > 0) { + fptype s1 = f[0] * ip[0]; + fptype s2 = f[0] * ip[1]; + ip1 = ip; + ip2 = ip; + + for (i = 1; i < flen; i++) { + ip1 += 2; + ip2 -= 2; + s1 += f[i] * (ip1[0] + ip2[0]); + s2 += f[i] * (ip1[1] + ip2[1]); + } + + Dst[0] = s1; + Dst[1] = s2; + Dst += DstIncr; + ip += ipstep; + l--; + } + } + } + + /** + * Function performs resizing of a single scanline. This function does + * not "know" about the length of the source scanline buffer. This buffer + * should be padded with enough pixels so that ( SrcPos - FilterLenD2 ) is + * always >= 0 and ( SrcPos + ( DstLineLen - 1 ) * k + FilterLenD2 + 1 ) + * does not exceed source scanline's buffer length. SrcLine's increment is + * assumed to be equal to ElCount. + * + * @param SrcLine Source scanline buffer. + * @param DstLine Destination (resized) scanline buffer. + * @param DstLineIncr Destination scanline position increment, used for + * horizontal or vertical scanline stepping. + * @param xx Temporary buffer, of size FltBank -> getFilterLen(), must be + * aligned by fpclass :: fpalign. + */ + + void doResize(const fptype* SrcLine, fptype* DstLine, const int DstLineIncr, + fptype* const) const { + const int IntFltLen = FltBank->getFilterLen(); + const int ElCount = Vars->ElCount; + const typename CImageResizerFilterStep::CResizePos* + rpos = &(*RPosBuf)[0]; + + const typename CImageResizerFilterStep< + fptype, fptypeatom>::CResizePos* const rpose = rpos + OutLen; + +#define AVIR_RESIZE_PART1 \ + while (rpos < rpose) { \ + const fptype x = (fptype)rpos->x; \ + const fptype* const ftp = rpos->ftp; \ + const fptype* const ftp2 = ftp + IntFltLen; \ + const fptype* Src = SrcLine + rpos->SrcOffs; \ + int i; + +#define AVIR_RESIZE_PART1nx \ + while (rpos < rpose) { \ + const fptype* const ftp = rpos->ftp; \ + const fptype* Src = SrcLine + rpos->SrcOffs; \ + int i; + +#define AVIR_RESIZE_PART2 \ + DstLine += DstLineIncr; \ + rpos++; \ + } + + if (FltBank->getOrder() == 1) { + if (ElCount == 1) { + AVIR_RESIZE_PART1 + + fptype sum = 0.0; + + for (i = 0; i < IntFltLen; i++) { + sum += (ftp[i] + ftp2[i] * x) * Src[i]; + } + + DstLine[0] = sum; + + AVIR_RESIZE_PART2 + } else if (ElCount == 4) { + AVIR_RESIZE_PART1 + + fptype sum[4]; + sum[0] = 0.0; + sum[1] = 0.0; + sum[2] = 0.0; + sum[3] = 0.0; + + for (i = 0; i < IntFltLen; i++) { + const fptype xx = ftp[i] + ftp2[i] * x; + sum[0] += xx * Src[0]; + sum[1] += xx * Src[1]; + sum[2] += xx * Src[2]; + sum[3] += xx * Src[3]; + Src += 4; + } + + DstLine[0] = sum[0]; + DstLine[1] = sum[1]; + DstLine[2] = sum[2]; + DstLine[3] = sum[3]; + + AVIR_RESIZE_PART2 + } else if (ElCount == 3) { + AVIR_RESIZE_PART1 + + fptype sum[3]; + sum[0] = 0.0; + sum[1] = 0.0; + sum[2] = 0.0; + + for (i = 0; i < IntFltLen; i++) { + const fptype xx = ftp[i] + ftp2[i] * x; + sum[0] += xx * Src[0]; + sum[1] += xx * Src[1]; + sum[2] += xx * Src[2]; + Src += 3; + } + + DstLine[0] = sum[0]; + DstLine[1] = sum[1]; + DstLine[2] = sum[2]; + + AVIR_RESIZE_PART2 + } else if (ElCount == 2) { + AVIR_RESIZE_PART1 + + fptype sum[2]; + sum[0] = 0.0; + sum[1] = 0.0; + + for (i = 0; i < IntFltLen; i++) { + const fptype xx = ftp[i] + ftp2[i] * x; + sum[0] += xx * Src[0]; + sum[1] += xx * Src[1]; + Src += 2; + } + + DstLine[0] = sum[0]; + DstLine[1] = sum[1]; + + AVIR_RESIZE_PART2 + } + } else { + if (ElCount == 1) { + AVIR_RESIZE_PART1nx + + fptype sum = 0.0; + + for (i = 0; i < IntFltLen; i++) { + sum += ftp[i] * Src[i]; + } + + DstLine[0] = sum; + + AVIR_RESIZE_PART2 + } else if (ElCount == 4) { + AVIR_RESIZE_PART1nx + + fptype sum[4]; + sum[0] = 0.0; + sum[1] = 0.0; + sum[2] = 0.0; + sum[3] = 0.0; + + for (i = 0; i < IntFltLen; i++) { + const fptype xx = ftp[i]; + sum[0] += xx * Src[0]; + sum[1] += xx * Src[1]; + sum[2] += xx * Src[2]; + sum[3] += xx * Src[3]; + Src += 4; + } + + DstLine[0] = sum[0]; + DstLine[1] = sum[1]; + DstLine[2] = sum[2]; + DstLine[3] = sum[3]; + + AVIR_RESIZE_PART2 + } else if (ElCount == 3) { + AVIR_RESIZE_PART1nx + + fptype sum[3]; + sum[0] = 0.0; + sum[1] = 0.0; + sum[2] = 0.0; + + for (i = 0; i < IntFltLen; i++) { + const fptype xx = ftp[i]; + sum[0] += xx * Src[0]; + sum[1] += xx * Src[1]; + sum[2] += xx * Src[2]; + Src += 3; + } + + DstLine[0] = sum[0]; + DstLine[1] = sum[1]; + DstLine[2] = sum[2]; + + AVIR_RESIZE_PART2 + } else if (ElCount == 2) { + AVIR_RESIZE_PART1nx + + fptype sum[2]; + sum[0] = 0.0; + sum[1] = 0.0; + + for (i = 0; i < IntFltLen; i++) { + const fptype xx = ftp[i]; + sum[0] += xx * Src[0]; + sum[1] += xx * Src[1]; + Src += 2; + } + + DstLine[0] = sum[0]; + DstLine[1] = sum[1]; + + AVIR_RESIZE_PART2 + } + } + } +#undef AVIR_RESIZE_PART2 +#undef AVIR_RESIZE_PART1nx +#undef AVIR_RESIZE_PART1 +}; + +/** + * @brief Image resizer's default dithering class. + * + * This class defines an object that performs rounding, clipping and dithering + * operations over horizontal scanline pixels before scanline is stored in the + * output buffer. + * + * The ditherer should expect the same storage order of the pixels in a + * scanline as used in the "filtering step" class. So, a separate ditherer + * class should be defined for each scanline pixel storage style. The default + * ditherer implements a simple rounding without dithering: it can be used for + * an efficient dithering method which can be multi-threaded. + * + * @tparam fptype Floating point type to use for storing pixel data. SIMD + * types can be used. + */ + +template +class CImageResizerDithererDefINL { + public: + /** + * Function initializes the ditherer object. + * + * @param aLen Scanline length in pixels to process. + * @param aVars Image resizing-related variables. + * @param aTrMul Bit-depth truncation multiplier. 1 - no additional + * truncation. + * @param aPkOut Peak output value allowed. + */ + + void init(const int aLen, const CImageResizerVars& aVars, const double aTrMul, + const double aPkOut) { + Len = aLen; + Vars = &aVars; + LenE = aLen * Vars->ElCount; + TrMul0 = aTrMul; + PkOut0 = aPkOut; + } + + /** + * @return "True" if dithering is recursive relative to scanlines meaning + * multi-threaded execution is not supported by this dithering method. + */ + + static bool isRecursive() { return (false); } + + /** + * Function performs rounding and clipping operations. + * + * @param ResScanline The buffer containing the final scanline. + */ + + void dither(fptype* const ResScanline) const { + const fptype c0 = 0.0; + const fptype PkOut = (fptype)PkOut0; + int j; + + if (TrMul0 == 1.0) { + // Optimization - do not perform bit depth truncation. + + for (j = 0; j < LenE; j++) { + ResScanline[j] = clamp(round(ResScanline[j]), c0, PkOut); + } + } else { + const fptype TrMul = (fptype)TrMul0; + + for (j = 0; j < LenE; j++) { + const fptype z0 = round(ResScanline[j] / TrMul) * TrMul; + ResScanline[j] = clamp(z0, c0, PkOut); + } + } + } + + protected: + int Len; ///< Scanline's length in pixels. + ///< + const CImageResizerVars* Vars; ///< Image resizing-related variables. + ///< + int LenE; ///< = LenE * ElCount. + ///< + double TrMul0; ///< Bit-depth truncation multiplier. + ///< + double PkOut0; ///< Peak output value allowed. + ///< +}; + +/** + * @brief Image resizer's error-diffusion dithering class, interleaved mode. + * + * This ditherer implements error-diffusion dithering which looks good, and + * whose results are compressed by PNG well. This implementation uses + * weighting coefficients obtained via machine optimization and visual + * evaluation. + * + * @tparam fptype Floating point type to use for storing pixel data. SIMD + * types can be used. + */ + +template +class CImageResizerDithererErrdINL + : public CImageResizerDithererDefINL { + public: + /** + * Function initializes the ditherer object. + * + * @param aLen Scanline length in pixels to process. + * @param aVars Image resizing-related variables. + * @param aTrMul Bit-depth truncation multiplier. 1 - no additional + * truncation. + * @param aPkOut Peak output value allowed. + */ + + void init(const int aLen, const CImageResizerVars& aVars, const double aTrMul, + const double aPkOut) { + CImageResizerDithererDefINL::init(aLen, aVars, aTrMul, aPkOut); + + ResScanlineDith0.alloc(LenE + Vars->ElCount, sizeof(fptype)); + ResScanlineDith = ResScanlineDith0 + Vars->ElCount; + int i; + + for (i = 0; i < LenE + Vars->ElCount; i++) { + ResScanlineDith0[i] = 0.0; + } + } + + static bool isRecursive() { return (true); } + + void dither(fptype* const ResScanline) { + const int ElCount = Vars->ElCount; + const fptype c0 = 0.0; + const fptype TrMul = (fptype)TrMul0; + const fptype PkOut = (fptype)PkOut0; + int j; + + for (j = 0; j < LenE; j++) { + ResScanline[j] += ResScanlineDith[j]; + ResScanlineDith[j] = 0.0; + } + + for (j = 0; j < LenE - ElCount; j++) { + // Perform rounding, noise estimation and saturation. + + const fptype z0 = round(ResScanline[j] / TrMul) * TrMul; + const fptype Noise = ResScanline[j] - z0; + ResScanline[j] = clamp(z0, c0, PkOut); + + ResScanline[j + ElCount] += Noise * (fptype)0.364842; + ResScanlineDith[j - ElCount] += Noise * (fptype)0.207305; + ResScanlineDith[j] += Noise * (fptype)0.364842; + ResScanlineDith[j + ElCount] += Noise * (fptype)0.063011; + } + + while (j < LenE) { + const fptype z0 = round(ResScanline[j] / TrMul) * TrMul; + const fptype Noise = ResScanline[j] - z0; + ResScanline[j] = clamp(z0, c0, PkOut); + + ResScanlineDith[j - ElCount] += Noise * (fptype)0.207305; + ResScanlineDith[j] += Noise * (fptype)0.364842; + j++; + } + } + + protected: + using CImageResizerDithererDefINL::Len; + using CImageResizerDithererDefINL::Vars; + using CImageResizerDithererDefINL::LenE; + using CImageResizerDithererDefINL::TrMul0; + using CImageResizerDithererDefINL::PkOut0; + + CBuffer ResScanlineDith0; ///< Error diffusion buffer. + ///< + fptype* ResScanlineDith; ///< Error diffusion buffer pointer which skips + ///< the first ElCount elements. + ///< +}; + +/** + * @brief Floating-point processing definition and abstraction class. + * + * This class defines several constants and typedefs that point to classes + * that should be used by the image resizing algorithm. Such "definition + * class" can be used to define alternative scanline processing algorithms + * (e.g. SIMD) and image scanline packing styles used during processing. This + * class also offers an abstraction layer for dithering, rounding and + * clamping (saturation) operation. + * + * The fpclass_def class can be used to define processing using both SIMD and + * non-SIMD types, but using algorithms that are operate on interleaved pixels + * and non-SIMD optimized themselves. + * + * @tparam afptype Floating point type to use for storing intermediate data + * and variables. For variables that are not used in intensive calculations + * the "double" type is always used. On the latest Intel processors (like + * i7-4770K) there is almost no performance difference between "double" and + * "float". Image quality differences between "double" and "float" are not + * apparent on 8-bit images. At the same time the "float" uses half amount of + * working memory the "double" type uses. SIMD types can be used. The + * functions round() and clamp() in the "avir" or other visible namespace + * should be available for the specified type. SIMD types allow to perform + * resizing of images with more than 4 channels, to be exact 4 * SIMD element + * number (e.g. 16 for float4), without modification of the image resizing + * algorithm required. + * @tparam afptypeatom The atomic type the "afptype" consists of. + * @tparam adith Ditherer class to use during processing. + */ + +template > +class fpclass_def { + public: + typedef afptype fptype; ///< Floating-point type to use during processing. + ///< + typedef afptypeatom fptypeatom; ///< Atomic type "fptype" consists of. + ///< + static const int fppack = + sizeof(fptype) / + sizeof(fptypeatom); ///< + ///< The number of atomic types stored in a single + ///< "fptype" element. + ///< + static const int fpalign = + sizeof(fptype); ///< Suggested alignment size + ///< in bytes. This is not a required alignment, because + ///< image resizing algorithm cannot be made to have a + ///< strictly aligned data access at all steps (e.g. + ///< interpolation cannot perform aligned accesses). + ///< + static const int elalign = + 1; ///< Length alignment of arrays of elements. + ///< This applies to filters and intermediate buffers: this constant + ///< forces filters and scanlines to have a length which is a multiple + ///< of this value, for more efficient SIMD implementation. + ///< + static const int packmode = 0; ///< 0 if interleaved packing, 1 if + ///< de-interleaved. + ///< + typedef CImageResizerFilterStepINL + CFilterStep; ///< + ///< Filtering step class to use during processing. + ///< + typedef adith CDitherer; ///< Ditherer class to use during processing. + ///< +}; + +/** + * @brief Image resizer class. + * + * The object of this class can be used to resize 1-4 channel images to any + * required size. Resizing is performed by utilizing interpolated sinc + * fractional delay filters plus (if necessary) a cascade of built-in + * sinc function-based 2X upsampling or 2X downsampling stages, followed by a + * correction filtering. + * + * Object of this class can be allocated on stack. + * + * @tparam fpclass Floating-point processing definition class to use. See + * avir::fpclass_def for more details. + */ + +template > +class CImageResizer { + public: + /** + * Constructor initializes the resizer. + * + * @param aResBitDepth Required bit depth of resulting image (1-16). If + * integer value output is used (e.g. uint8_t), the bit depth also affects + * rounding: for example, if aResBitDepth=6 and "Tout" is uint8_t, the + * result will be rounded to 6 most significant bits (2 least significant + * bits truncated, with dithering applied). + * @param aSrcBitDepth Source image's real bit-depth. Set to 0 to use + * aResBitDepth. + * @param aParams Resizing algorithm's parameters to use. Leave out for + * default values. Can be useful when performing automatic optimization of + * parameters. + */ + + CImageResizer(const int aResBitDepth = 8, const int aSrcBitDepth = 0, + const CImageResizerParams& aParams = CImageResizerParamsDef()) + : Params(aParams), ResBitDepth(aResBitDepth) { + SrcBitDepth = (aSrcBitDepth == 0 ? ResBitDepth : aSrcBitDepth); + + initFilterBank(FixedFilterBank, 1.0, false, CFltBuffer()); + FixedFilterBank.createAllFilters(); + } + + /** + * Function resizes image. + * + * @param SrcBuf Source image buffer. + * @param SrcWidth Source image width. + * @param SrcHeight Source image height. + * @param SrcScanlineSize Physical size of source scanline in elements + * (not bytes). If this value is below 1, SrcWidth * ElCountIO will be + * used as the physical source scanline size. + * @param[out] NewBuf Buffer to accept the resized image. Can be equal to + * SrcBuf if the size of the resized image is smaller or equal to source + * image in size. + * @param NewWidth New image width. + * @param NewHeight New image height. + * @param ElCountIO The number of elements (channels) used to store each + * source and destination pixel (1-4). + * @param k Resizing step (one output pixel corresponds to "k" input + * pixels). A downsizing factor if > 1.0; upsizing factor if <= 1.0. + * Multiply by -1 if you would like to bypass "ox" and "oy" adjustment + * which is done by default to produce a centered image. If step value + * equals 0, the step value will be chosen automatically and independently + * for horizontal and vertical resizing. + * @param[in,out] aVars Pointer to variables structure to be passed to the + * image resizing function. Can be NULL. Only variables that are + * initialized in default constructor of this structure are accepted by + * this function. These variables will not be changed by this function. + * All other variables can be modified by this function. The access to + * this object is not thread-safe, each concurrent instance of this + * function should use a separate aVars object. + * @tparam Tin Input buffer element's type. Can be uint8_t (0-255 value + * range), uint16_t (0-65535 value range), float (0.0-1.0 value range), + * double (0.0-1.0 value range). Larger integer types are treated as + * uint16_t. Signed integer types are unsupported. + * @tparam Tout Output buffer element's type. Can be uint8_t (0-255 value + * range), uint16_t (0-65535 value range), float (0.0-1.0 value range), + * double (0.0-1.0 value range). Larger integer types are treated as + * uint16_t. Signed integer types are unsupported. + */ + + template + void resizeImage(const Tin* const SrcBuf, const int SrcWidth, + const int SrcHeight, int SrcScanlineSize, Tout* const NewBuf, + const int NewWidth, const int NewHeight, const int ElCountIO, + const double k, + CImageResizerVars* const aVars = NULL) const { + if (SrcWidth == 0 || SrcHeight == 0) { + memset(NewBuf, 0, (size_t)NewWidth * NewHeight * sizeof(Tout)); + + return; + } else if (NewWidth == 0 || NewHeight == 0) { + return; + } + + CImageResizerVars DefVars; + CImageResizerVars& Vars = (aVars == NULL ? DefVars : *aVars); + + CImageResizerThreadPool DefThreadPool; + CImageResizerThreadPool& ThreadPool = + (Vars.ThreadPool == NULL ? DefThreadPool : *Vars.ThreadPool); + + // Define resizing steps, also optionally modify offsets so that + // resizing produces a "centered" image. + + double kx; + double ky; + double ox = Vars.ox; + double oy = Vars.oy; + + if (k == 0.0) { + if (NewWidth > SrcWidth) { + kx = (double)(SrcWidth - 1) / (NewWidth - 1); + } else { + kx = (double)SrcWidth / NewWidth; + ox += (kx - 1.0) * 0.5; + } + + if (NewHeight > SrcHeight) { + ky = (double)(SrcHeight - 1) / (NewHeight - 1); + } else { + ky = (double)SrcHeight / NewHeight; + oy += (ky - 1.0) * 0.5; + } + } else if (k > 0.0) { + kx = k; + ky = k; + + if (k > 1.0) { + const double ko = (k - 1.0) * 0.5; + ox += ko; + oy += ko; + } + } else { + kx = -k; + ky = -k; + } + + // Evaluate pre-multipliers used on the output stage. + + const bool IsInFloat = ((Tin)0.4 != 0); + const bool IsOutFloat = ((Tout)0.4 != 0); + double OutMul; // Output multiplier. + + if (Vars.UseSRGBGamma) { + if (IsInFloat) { + Vars.InGammaMult = 1.0; + } else { + Vars.InGammaMult = 1.0 / (sizeof(Tin) == 1 ? 255.0 : 65535.0); + } + + if (IsOutFloat) { + Vars.OutGammaMult = 1.0; + } else { + Vars.OutGammaMult = (sizeof(Tout) == 1 ? 255.0 : 65535.0); + } + + OutMul = 1.0; + } else { + if (IsOutFloat) { + OutMul = 1.0; + } else { + OutMul = (sizeof(Tout) == 1 ? 255.0 : 65535.0); + } + + if (!IsInFloat) { + OutMul /= (sizeof(Tin) == 1 ? 255.0 : 65535.0); + } + } + + // Fill widely-used variables. + + const int ElCount = (ElCountIO + fpclass ::fppack - 1) / fpclass ::fppack; + + const int NewWidthE = NewWidth * ElCount; + + if (SrcScanlineSize < 1) { + SrcScanlineSize = SrcWidth * ElCountIO; + } + + Vars.ElCount = ElCount; + Vars.ElCountIO = ElCountIO; + Vars.fppack = fpclass ::fppack; + Vars.fpalign = fpclass ::fpalign; + Vars.elalign = fpclass ::elalign; + Vars.packmode = fpclass ::packmode; + + // Horizontal scanline filtering and resizing. + + CDSPFracFilterBankLin FltBank; + CFilterSteps FltSteps; + typename CFilterStep ::CRPosBufArray RPosBufArray; + CBuffer UsedFracMap; + + // Perform the filtering steps modeling at various modes, find the + // most efficient mode for both horizontal and vertical resizing. + + int UseBuildMode = 1; + const int BuildModeCount = (FixedFilterBank.getOrder() == 0 ? 4 : 2); + + int m; + + if (Vars.BuildMode >= 0) { + UseBuildMode = Vars.BuildMode; + } else { + int BestScore = 0x7FFFFFFF; + + for (m = 0; m < BuildModeCount; m++) { + CDSPFracFilterBankLin TmpBank; + CFilterSteps TmpSteps; + Vars.k = kx; + Vars.o = ox; + buildFilterSteps(TmpSteps, Vars, TmpBank, OutMul, m, true); + updateFilterStepBuffers(TmpSteps, Vars, RPosBufArray, SrcWidth, + NewWidth); + + fillUsedFracMap(TmpSteps[Vars.ResizeStep], UsedFracMap); + const int c = calcComplexity(TmpSteps, Vars, UsedFracMap, SrcHeight); + + if (c < BestScore) { + UseBuildMode = m; + BestScore = c; + } + } + } + + // Perform the actual filtering steps building. + + Vars.k = kx; + Vars.o = ox; + buildFilterSteps(FltSteps, Vars, FltBank, OutMul, UseBuildMode, false); + + updateFilterStepBuffers(FltSteps, Vars, RPosBufArray, SrcWidth, NewWidth); + + updateBufLenAndRPosPtrs(FltSteps, Vars, NewWidth); + + const int ThreadCount = ThreadPool.getSuggestedWorkloadCount(); + // Includes the current thread. + + CStructArray > td; + td.setItemCount(ThreadCount); + int i; + + for (i = 0; i < ThreadCount; i++) { + if (i > 0) { + ThreadPool.addWorkload(&td[i]); + } + + td[i].init(i, ThreadCount, FltSteps, Vars); + + td[i].initScanlineQueue(td[i].sopResizeH, SrcHeight, SrcWidth); + } + + CBuffer FltBuf( + (size_t)NewWidthE * SrcHeight, + fpclass ::fpalign); // Temporary buffer that receives + // horizontally-filtered and resized image. + + for (i = 0; i < SrcHeight; i++) { + td[i % ThreadCount].addScanlineToQueue( + (void*)&SrcBuf[(size_t)i * SrcScanlineSize], + &FltBuf[(size_t)i * NewWidthE]); + } + + ThreadPool.startAllWorkloads(); + td[0].processScanlineQueue(); + ThreadPool.waitAllWorkloadsToFinish(); + + // Vertical scanline filtering and resizing, reuse previously defined + // filtering steps if possible. + + const int PrevUseBuildMode = UseBuildMode; + + if (Vars.BuildMode >= 0) { + UseBuildMode = Vars.BuildMode; + } else { + CImageResizerVars TmpVars(Vars); + int BestScore = 0x7FFFFFFF; + + for (m = 0; m < BuildModeCount; m++) { + CDSPFracFilterBankLin TmpBank; + TmpBank.copyInitParams(FltBank); + CFilterSteps TmpSteps; + TmpVars.k = ky; + TmpVars.o = oy; + buildFilterSteps(TmpSteps, TmpVars, TmpBank, 1.0, m, true); + updateFilterStepBuffers(TmpSteps, TmpVars, RPosBufArray, SrcHeight, + NewHeight); + + fillUsedFracMap(TmpSteps[TmpVars.ResizeStep], UsedFracMap); + + const int c = calcComplexity(TmpSteps, TmpVars, UsedFracMap, NewWidth); + + if (c < BestScore) { + UseBuildMode = m; + BestScore = c; + } + } + } + + Vars.k = ky; + Vars.o = oy; + + if (UseBuildMode == PrevUseBuildMode && ky == kx) { + if (OutMul != 1.0) { + modifyCorrFilterDCGain(FltSteps, 1.0 / OutMul); + } + } else { + buildFilterSteps(FltSteps, Vars, FltBank, 1.0, UseBuildMode, false); + } + + updateFilterStepBuffers(FltSteps, Vars, RPosBufArray, SrcHeight, NewHeight); + + updateBufLenAndRPosPtrs(FltSteps, Vars, NewWidth); + + if (IsOutFloat && sizeof(FltBuf[0]) == sizeof(Tout) && + fpclass ::packmode == 0) { + // In-place output. + + for (i = 0; i < ThreadCount; i++) { + td[i].initScanlineQueue(td[i].sopResizeV, NewWidth, SrcHeight, + NewWidthE, NewWidthE); + } + + for (i = 0; i < NewWidth; i++) { + td[i % ThreadCount].addScanlineToQueue( + &FltBuf[(size_t)i * ElCount], + (fptype*)&NewBuf[(size_t)i * ElCount]); + } + + ThreadPool.startAllWorkloads(); + td[0].processScanlineQueue(); + ThreadPool.waitAllWorkloadsToFinish(); + ThreadPool.removeAllWorkloads(); + + return; + } + + CBuffer ResBuf((size_t)NewWidthE * NewHeight, + fpclass ::fpalign); + + for (i = 0; i < ThreadCount; i++) { + td[i].initScanlineQueue(td[i].sopResizeV, NewWidth, SrcHeight, NewWidthE, + NewWidthE); + } + + const int im = (fpclass ::packmode == 0 ? ElCount : 1); + + for (i = 0; i < NewWidth; i++) { + td[i % ThreadCount].addScanlineToQueue(&FltBuf[(size_t)i * im], + &ResBuf[(size_t)i * im]); + } + + ThreadPool.startAllWorkloads(); + td[0].processScanlineQueue(); + ThreadPool.waitAllWorkloadsToFinish(); + + if (IsOutFloat) { + // Perform output, but skip dithering. + + for (i = 0; i < ThreadCount; i++) { + td[i].initScanlineQueue(td[i].sopUnpackH, NewHeight, NewWidth); + } + + for (i = 0; i < NewHeight; i++) { + td[i % ThreadCount].addScanlineToQueue( + &ResBuf[(size_t)i * NewWidthE], + &NewBuf[(size_t)i * NewWidth * ElCountIO]); + } + + ThreadPool.startAllWorkloads(); + td[0].processScanlineQueue(); + ThreadPool.waitAllWorkloadsToFinish(); + ThreadPool.removeAllWorkloads(); + + return; + } + + // Perform output with dithering (for integer output only). + + int TruncBits; // The number of lower bits to truncate and dither. + int OutRange; // Output range. + + if (sizeof(Tout) == 1) { + TruncBits = 8 - ResBitDepth; + OutRange = 255; + } else { + TruncBits = 16 - ResBitDepth; + OutRange = 65535; + } + + const double PkOut = OutRange; + const double TrMul = + (TruncBits > 0 ? PkOut / (OutRange >> TruncBits) : 1.0); + + if (CDitherer ::isRecursive()) { + td[0].getDitherer().init(NewWidth, Vars, TrMul, PkOut); + + if (Vars.UseSRGBGamma) { + for (i = 0; i < NewHeight; i++) { + fptype* const ResScanline = &ResBuf[(size_t)i * NewWidthE]; + + CFilterStep ::applySRGBGamma(ResScanline, NewWidth, Vars); + + td[0].getDitherer().dither(ResScanline); + + CFilterStep ::unpackScanline( + ResScanline, &NewBuf[(size_t)i * NewWidth * ElCountIO], NewWidth, + Vars); + } + } else { + for (i = 0; i < NewHeight; i++) { + fptype* const ResScanline = &ResBuf[(size_t)i * NewWidthE]; + + td[0].getDitherer().dither(ResScanline); + + CFilterStep ::unpackScanline( + ResScanline, &NewBuf[(size_t)i * NewWidth * ElCountIO], NewWidth, + Vars); + } + } + } else { + for (i = 0; i < ThreadCount; i++) { + td[i].initScanlineQueue(td[i].sopDitherAndUnpackH, NewHeight, NewWidth); + + td[i].getDitherer().init(NewWidth, Vars, TrMul, PkOut); + } + + for (i = 0; i < NewHeight; i++) { + td[i % ThreadCount].addScanlineToQueue( + &ResBuf[(size_t)i * NewWidthE], + &NewBuf[(size_t)i * NewWidth * ElCountIO]); + } + + ThreadPool.startAllWorkloads(); + td[0].processScanlineQueue(); + ThreadPool.waitAllWorkloadsToFinish(); + } + + ThreadPool.removeAllWorkloads(); + } + + private: + typedef typename fpclass ::fptype fptype; ///< Floating-point type to use + ///< during processing. + ///< + typedef typename fpclass ::CFilterStep + CFilterStep; ///< Filtering step + ///< class to use during processing. + ///< + typedef typename fpclass ::CDitherer CDitherer; ///< Ditherer class to + ///< use during processing. + ///< + CImageResizerParams Params; ///< Algorithm's parameters currently in use. + ///< + int SrcBitDepth; ///< Bit resolution of the source image. + ///< + int ResBitDepth; ///< Bit resolution of the resulting image. + ///< + CDSPFracFilterBankLin + FixedFilterBank; ///< Fractional delay + ///< filter bank with fixed characteristics, mainly for + ///< upsizing cases. + ///< + + /** + * @brief Filtering steps array. + * + * The object of this class stores filtering steps together. + */ + + typedef CStructArray CFilterSteps; + + /** + * Function initializes the filter bank in the specified resizing step + * according to the source and resulting image bit depths. + * + * @param FltBank Filter bank to initialize. + * @param CutoffMult Cutoff multiplier, 0 to 1. 1 corresponds to 0.5pi + * cutoff point. + * @param ForceHiOrder "True" if a high-order interpolation should be + * forced which requires considerably less resources for initialization. + * @param ExtFilter External filter to apply to interpolation filter. + */ + + void initFilterBank(CDSPFracFilterBankLin& FltBank, + const double CutoffMult, const bool ForceHiOrder, + const CFltBuffer& ExtFilter) const { + const int IntBitDepth = + (ResBitDepth > SrcBitDepth ? ResBitDepth : SrcBitDepth); + + const double SNR = -6.02 * (IntBitDepth + 3); + int UseOrder; + int FracCount; // The number of fractional delay filters sampled by + // the filter bank. This variable affects the + // signal-to-noise ratio at interpolation stage. + // Theoretically, at UseOrder==1, 8-bit image resizing + // requires 66.2 dB SNR or 11. 16-bit resizing requires + // 114.4 dB SNR or 150. At UseOrder=0 the required number of + // filters is exponentially higher. + + if (ForceHiOrder || IntBitDepth > 8) { + UseOrder = 1; // -146 dB max + FracCount = (int)ceil(0.23134052 * exp(-0.058062929 * SNR)); + } else { + UseOrder = 0; // -72 dB max + FracCount = (int)ceil(0.33287686 * exp(-0.11334583 * SNR)); + } + + if (FracCount < 2) { + FracCount = 2; + } + + FltBank.init(FracCount, UseOrder, Params.IntFltLen / CutoffMult, + Params.IntFltCutoff * CutoffMult, Params.IntFltAlpha, + ExtFilter, fpclass ::fpalign, fpclass ::elalign); + } + + /** + * Function allocates filter buffer taking "fpclass" alignments into + * account. The allocated buffer may be larger than the requested size: in + * this case the additional elements will be zeroed by this function. + * + * @param Flt Filter buffer. + * @param ReqCapacity The required filter buffer's capacity. + * @param IsModel "True" if filtering steps modeling is performed without + * actual filter allocation. + * @param FltExt If non-NULL this variable will receive the number of + * elements the filter was extended by. + */ + + static void allocFilter(CBuffer& Flt, const int ReqCapacity, + const bool IsModel = false, + int* const FltExt = NULL) { + int UseCapacity = + (ReqCapacity + fpclass ::elalign - 1) & ~(fpclass ::elalign - 1); + + int Ext = UseCapacity - ReqCapacity; + + if (FltExt != NULL) { + *FltExt = Ext; + } + + if (IsModel) { + Flt.forceCapacity(UseCapacity); + return; + } + + Flt.alloc(UseCapacity, fpclass ::fpalign); + + while (Ext > 0) { + Ext--; + Flt[ReqCapacity + Ext] = 0.0; + } + } + + /** + * Function assigns filter parameters to the specified filtering step + * object. + * + * @param fs Filtering step to assign parameter to. This step cannot be + * the last step if ResampleFactor greater than 1 was specified. + * @param IsUpsample "True" if upsampling step. Should be set to "false" + * if FltCutoff is negative. + * @param ResampleFactor Resampling factor of this filter (>=1). + * @param FltCutoff Filter cutoff point. This value will be divided by the + * ResampleFactor if IsUpsample equals "true". If zero value was + * specified, the "half-band" predefined filter will be created. In this + * case the ResampleFactor will modify the filter cutoff point. + * @param DCGain DC gain to apply to the filter. Assigned to filtering + * step's DCGain variable. + * @param UseFltOrig "True" if the originally-designed filter should be + * left in filtering step's FltOrig buffer. Otherwise it will be freed. + * @param IsModel "True" if filtering steps modeling is performed without + * actual filter building. + */ + + void assignFilterParams(CFilterStep& fs, const bool IsUpsample, + const int ResampleFactor, const double FltCutoff, + const double DCGain, const bool UseFltOrig, + const bool IsModel) const { + double FltAlpha; + double Len2; + double Freq; + + if (FltCutoff == 0.0) { + const double m = 2.0 / ResampleFactor; + FltAlpha = Params.HBFltAlpha; + Len2 = 0.5 * Params.HBFltLen / m; + Freq = AVIR_PI * Params.HBFltCutoff * m; + } else { + FltAlpha = Params.LPFltAlpha; + Len2 = 0.25 * Params.LPFltBaseLen / FltCutoff; + Freq = AVIR_PI * Params.LPFltCutoffMult * FltCutoff; + } + + if (IsUpsample) { + Len2 *= ResampleFactor; + Freq /= ResampleFactor; + fs.DCGain = DCGain * ResampleFactor; + } else { + fs.DCGain = DCGain; + } + + fs.FltOrig.Len2 = Len2; + fs.FltOrig.Freq = Freq; + fs.FltOrig.Alpha = FltAlpha; + fs.FltOrig.DCGain = fs.DCGain; + + CDSPPeakedCosineLPF w(Len2, Freq, FltAlpha); + + fs.IsUpsample = IsUpsample; + fs.ResampleFactor = ResampleFactor; + fs.FltLatency = w.fl2; + + int FltExt; // Filter's extension due to fpclass :: elalign. + + if (IsModel) { + allocFilter(fs.Flt, w.FilterLen, true, &FltExt); + + if (UseFltOrig) { + // Allocate a real buffer even in modeling mode since this + // filter may be copied by the filter bank. + + fs.FltOrig.alloc(w.FilterLen); + memset(&fs.FltOrig[0], 0, w.FilterLen * sizeof(fs.FltOrig[0])); + } + } else { + fs.FltOrig.alloc(w.FilterLen); + + w.generateLPF(&fs.FltOrig[0], 1.0); + optimizeFIRFilter(fs.FltOrig, fs.FltLatency); + normalizeFIRFilter(&fs.FltOrig[0], fs.FltOrig.getCapacity(), fs.DCGain); + + allocFilter(fs.Flt, fs.FltOrig.getCapacity(), false, &FltExt); + copyArray(&fs.FltOrig[0], &fs.Flt[0], fs.FltOrig.getCapacity()); + + if (!UseFltOrig) { + fs.FltOrig.free(); + } + } + + if (IsUpsample) { + int l = fs.Flt.getCapacity() - fs.FltLatency - ResampleFactor - FltExt; + + allocFilter(fs.PrefixDC, l, IsModel); + allocFilter(fs.SuffixDC, fs.FltLatency, IsModel); + + if (IsModel) { + return; + } + + // Create prefix and suffix "tails" used during upsampling. + + const fptype* ip = &fs.Flt[fs.FltLatency + ResampleFactor]; + copyArray(ip, &fs.PrefixDC[0], l); + + while (true) { + ip += ResampleFactor; + l -= ResampleFactor; + + if (l <= 0) { + break; + } + + addArray(ip, &fs.PrefixDC[0], l); + } + + l = fs.FltLatency; + fptype* op = &fs.SuffixDC[0]; + copyArray(&fs.Flt[0], op, l); + + while (true) { + op += ResampleFactor; + l -= ResampleFactor; + + if (l <= 0) { + break; + } + + addArray(&fs.Flt[0], op, l); + } + } else if (!UseFltOrig) { + fs.EdgePixelCount = fs.EdgePixelCountDef; + } + } + + /** + * Function adds a correction filter that tries to achieve a linear + * frequency response at all frequencies. The actual resulting response + * may feature a slight damping of the highest frequencies since a + * suitably short correction filter cannot fix steep high-frequency + * damping. + * + * This function assumes that the resizing step is currently the last + * step, even if it was not inserted yet: this allows placement of the + * correction filter both before and after the resizing step. + * + * @param Steps Filtering steps. + * @param bw Resulting bandwidth relative to the original bandwidth (which + * is 1.0), usually 1/k. Should be <= 1.0. + * @param IsPreCorrection "True" if the filtering step was already created + * and it is first in the Steps array. "True" also adds edge pixels to + * reduce edge artifacts. + * @param IsModel "True" if filtering steps modeling is performed without + * actual filter building. + */ + + void addCorrectionFilter(CFilterSteps& Steps, const double bw, + const bool IsPreCorrection, + const bool IsModel) const { + CFilterStep& fs = (IsPreCorrection ? Steps[0] : Steps.add()); + fs.IsUpsample = false; + fs.ResampleFactor = 1; + fs.DCGain = 1.0; + fs.EdgePixelCount = (IsPreCorrection ? fs.EdgePixelCountDef : 0); + + if (IsModel) { + allocFilter( + fs.Flt, + CDSPFIREQ ::calcFilterLength(Params.CorrFltLen, fs.FltLatency), true); + + return; + } + + const int BinCount = 65; // Frequency response bins to control. + const int BinCount1 = BinCount - 1; + double curbw = 1.0; // Bandwidth of the filter at the current step. + int i; + int j; + double re; + double im; + + CBuffer Bins(BinCount); // Adjustment introduced by all + // steps at all frequencies of interest. + + for (j = 0; j < BinCount; j++) { + Bins[j] = 1.0; + } + + const int si = (IsPreCorrection ? 1 : 0); + + for (i = si; i < Steps.getItemCount() - (si ^ 1); i++) { + const CFilterStep& fs = Steps[i]; + + if (fs.IsUpsample) { + curbw *= fs.ResampleFactor; + + if (fs.FltOrig.getCapacity() > 0) { + continue; + } + } + + const double dcg = 1.0 / fs.DCGain; // DC gain correction. + const fptype* Flt; + int FltLen; + + if (fs.ResampleFactor == 0) { + Flt = fs.FltBank->getFilter(0); + FltLen = fs.FltBank->getFilterLen(); + } else { + Flt = &fs.Flt[0]; + FltLen = fs.Flt.getCapacity(); + } + + // Calculate frequency response adjustment introduced by the + // filter at this step, within the bounds of bandwidth of + // interest. + + for (j = 0; j < BinCount; j++) { + const double th = AVIR_PI * bw / curbw * j / BinCount1; + + calcFIRFilterResponse(Flt, FltLen, th, re, im); + + Bins[j] /= sqrt(re * re + im * im) * dcg; + } + + if (!fs.IsUpsample && fs.ResampleFactor > 1) { + curbw /= fs.ResampleFactor; + } + } + + // Calculate filter. + + CDSPFIREQ EQ; + EQ.init(bw * 2.0, Params.CorrFltLen, BinCount, 0.0, bw, false, + Params.CorrFltAlpha); + + fs.FltLatency = EQ.getFilterLatency(); + + CBuffer Filter(EQ.getFilterLength()); + EQ.buildFilter(Bins, &Filter[0]); + normalizeFIRFilter(&Filter[0], Filter.getCapacity(), 1.0); + optimizeFIRFilter(Filter, fs.FltLatency); + normalizeFIRFilter(&Filter[0], Filter.getCapacity(), 1.0); + + allocFilter(fs.Flt, Filter.getCapacity()); + copyArray(&Filter[0], &fs.Flt[0], Filter.getCapacity()); + + // Print a theoretically achieved final frequency response at various + // feature sizes (from DC to 1 pixel). Values above 255 means features + // become brighter, values below 255 means features become dimmer. + + /* const double sbw = ( bw > 1.0 ? 1.0 / bw : 1.0 ); + + for( j = 0; j < BinCount; j++ ) + { + const double th = AVIR_PI * sbw * j / BinCount1; + + calcFIRFilterResponse( &fs.Flt[ 0 ], + fs.Flt.getCapacity(), th, re, im ); + + printf( "%f\n", sqrt( re * re + im * im ) / Bins[ j + ] * 255 ); + } + + printf( "***\n" );*/ + } + + /** + * Function adds a sharpening filter if image is being upsized. Such + * sharpening allows to spot interpolation filter's stop-band attenuation: + * if attenuation is too weak, a "dark grid" and other artifacts may + * become visible. + * + * It is assumed that 40 decibel stop-band attenuation should be + * considered a required minimum: this allows application of (deliberately + * strong) 64X sharpening without spotting any artifacts. + * + * @param Steps Filtering steps. + * @param bw Resulting bandwidth relative to the original bandwidth (which + * is 1.0), usually 1/k. + * @param IsModel "True" if filtering steps modeling is performed without + * actual filter building. + */ + + static void addSharpenTest(CFilterSteps& Steps, const double bw, + const bool IsModel) { + if (bw <= 1.0) { + return; + } + + const double FltLen = 10.0 * bw; + + CFilterStep& fs = Steps.add(); + fs.IsUpsample = false; + fs.ResampleFactor = 1; + fs.DCGain = 1.0; + fs.EdgePixelCount = 0; + + if (IsModel) { + allocFilter(fs.Flt, CDSPFIREQ ::calcFilterLength(FltLen, fs.FltLatency), + true); + + return; + } + + const int BinCount = 200; + CBuffer Bins(BinCount); + int Thresh = (int)round(BinCount / bw * 1.75); + + if (Thresh > BinCount) { + Thresh = BinCount; + } + + int j; + + for (j = 0; j < Thresh; j++) { + Bins[j] = 1.0; + } + + for (j = Thresh; j < BinCount; j++) { + Bins[j] = 256.0; + } + + CDSPFIREQ EQ; + EQ.init(bw * 2.0, FltLen, BinCount, 0.0, bw, false, 1.7); + + fs.FltLatency = EQ.getFilterLatency(); + + CBuffer Filter(EQ.getFilterLength()); + EQ.buildFilter(Bins, &Filter[0]); + normalizeFIRFilter(&Filter[0], Filter.getCapacity(), 1.0); + optimizeFIRFilter(Filter, fs.FltLatency); + normalizeFIRFilter(&Filter[0], Filter.getCapacity(), 1.0); + + allocFilter(fs.Flt, Filter.getCapacity()); + copyArray(&Filter[0], &fs.Flt[0], Filter.getCapacity()); + + /* for( j = 0; j < BinCount; j++ ) + { + const double th = AVIR_PI * j / ( BinCount - 1 ); + double re; + double im; + + calcFIRFilterResponse( &fs.Flt[ 0 ], + fs.Flt.getCapacity(), th, re, im ); + + printf( "%f\n", sqrt( re * re + im * im )); + } + + printf( "***\n" );*/ + } + + /** + * Function builds sequence of filtering steps depending on the specified + * resizing coefficient. The last steps included are always the resizing + * step then (possibly) the correction step. + * + * @param Steps Array that receives filtering steps. + * @param[out] Vars Variables object. + * @param FltBank Filter bank to initialize and use. + * @param DCGain The overall DC gain to apply. This DC gain is applied to + * the first filtering step only (upsampling or filtering step). + * @param ModeFlags Build mode flags to use. This is a bitmap of switches + * that enable or disable certain algorithm features. + * @param IsModel "True" if filtering steps modeling is performed without + * the actual filter allocation and building. + */ + + void buildFilterSteps(CFilterSteps& Steps, CImageResizerVars& Vars, + CDSPFracFilterBankLin& FltBank, + const double DCGain, const int ModeFlags, + const bool IsModel) const { + Steps.clear(); + + const bool DoFltAndIntCombo = + ((ModeFlags & 1) != 0); // Do filter + // and interpolator combining. + const bool ForceHiOrderInt = + ((ModeFlags & 2) != 0); // Force use + // of a higher-order interpolation. + const bool UseHalfband = ((ModeFlags & 4) != 0); // Use half-band + // filter. + + const double bw = 1.0 / Vars.k; // Resulting bandwidth. + const int UpsampleFactor = ((int)floor(Vars.k) < 2 ? 2 : 1); + double IntCutoffMult; // Interpolation filter cutoff multiplier. + CFilterStep* ReuseStep; // If not NULL, resizing step should use + // this step object instead of creating a new one. + CFilterStep* ExtFltStep; // Use FltOrig of this step as the external + // filter to applied to the interpolator. + bool IsPreCorrection; // "True" if the correction filter is applied + // first. + double FltCutoff; // Cutoff frequency of the first filtering step. + double corrbw; ///< Bandwidth at the correction step. + + if (Vars.k <= 1.0) { + IsPreCorrection = true; + FltCutoff = 1.0; + corrbw = 1.0; + Steps.add(); + } else { + IsPreCorrection = false; + FltCutoff = bw; + corrbw = bw; + } + + // Add 1 upsampling or several downsampling filters. + + if (UpsampleFactor > 1) { + CFilterStep& fs = Steps.add(); + assignFilterParams(fs, true, UpsampleFactor, FltCutoff, DCGain, + DoFltAndIntCombo, IsModel); + + IntCutoffMult = FltCutoff * 2.0 / UpsampleFactor; + ReuseStep = NULL; + ExtFltStep = (DoFltAndIntCombo ? &fs : NULL); + } else { + int DownsampleFactor; + + while (true) { + DownsampleFactor = (int)floor(0.5 / FltCutoff); + bool DoHBFltAdd; + + if (DownsampleFactor > 16) { + // Add half-band filter unconditionally in order to keep + // filter lengths lower for more precise frequency + // response and less edge artifacts. + + DoHBFltAdd = true; + DownsampleFactor = 16; + } else { + DoHBFltAdd = (UseHalfband && DownsampleFactor > 1); + } + + if (DoHBFltAdd) { + assignFilterParams(Steps.add(), false, DownsampleFactor, 0.0, 1.0, + false, IsModel); + + FltCutoff *= DownsampleFactor; + } else { + if (DownsampleFactor < 1) { + DownsampleFactor = 1; + } + + break; + } + } + + CFilterStep& fs = Steps.add(); + assignFilterParams(fs, false, DownsampleFactor, FltCutoff, DCGain, + DoFltAndIntCombo, IsModel); + + IntCutoffMult = FltCutoff / 0.5; + + if (DoFltAndIntCombo) { + ReuseStep = &fs; + ExtFltStep = &fs; + } else { + IntCutoffMult *= DownsampleFactor; + ReuseStep = NULL; + ExtFltStep = NULL; + } + } + + // Insert resizing and correction steps. + + CFilterStep& fs = (ReuseStep == NULL ? Steps.add() : *ReuseStep); + + Vars.ResizeStep = Steps.getItemCount() - 1; + fs.IsUpsample = false; + fs.ResampleFactor = 0; + fs.DCGain = (ExtFltStep == NULL ? 1.0 : ExtFltStep->DCGain); + + initFilterBank(FltBank, IntCutoffMult, ForceHiOrderInt, + (ExtFltStep == NULL ? fs.FltOrig : ExtFltStep->FltOrig)); + + if (FltBank == FixedFilterBank) { + fs.FltBank = (CDSPFracFilterBankLin*)&FixedFilterBank; + } else { + fs.FltBank = &FltBank; + } + + addCorrectionFilter(Steps, corrbw, IsPreCorrection, IsModel); + + // addSharpenTest( Steps, bw, IsModel ); + } + + /** + * Function extends *this upsampling step so that it produces more + * upsampled pixels that cover the prefix and suffix needs of the next + * step. After the call to this function the InPrefix and InSuffix + * variables of the next step will be set to zero. + * + * @param fs Upsampling filtering step. + * @param NextStep The next step structure. + */ + + static void extendUpsample(CFilterStep& fs, CFilterStep& NextStep) { + fs.InPrefix = + (NextStep.InPrefix + fs.ResampleFactor - 1) / fs.ResampleFactor; + + fs.OutPrefix += fs.InPrefix * fs.ResampleFactor; + NextStep.InPrefix = 0; + + fs.InSuffix = + (NextStep.InSuffix + fs.ResampleFactor - 1) / fs.ResampleFactor; + + fs.OutSuffix += fs.InSuffix * fs.ResampleFactor; + NextStep.InSuffix = 0; + } + + /** + * Function fills resizing step's RPosBuf array, excluding the actual + * "ftp" pointers and "SrcOffs" offsets. + * + * This array should be cleared if the resizing step or offset were + * changed. Otherwise this function only fills the elements required to + * cover resizing step's OutLen. + * + * This function is called by the updateFilterStepBuffers() function. + * + * @param fs Resizing step. + * @param Vars Variables object. + */ + + static void fillRPosBuf(CFilterStep& fs, const CImageResizerVars& Vars) { + const int PrevLen = fs.RPosBuf->getCapacity(); + + if (fs.OutLen > PrevLen) { + fs.RPosBuf->increaseCapacity(fs.OutLen); + } + + typename CFilterStep ::CResizePos* rpos = &(*fs.RPosBuf)[PrevLen]; + const int FracCount = fs.FltBank->getFracCount(); + const double o = Vars.o; + const double k = Vars.k; + int i; + + for (i = PrevLen; i < fs.OutLen; i++) { + const double SrcPos = o + k * i; + const int SrcPosInt = (int)floor(SrcPos); + const double x = (SrcPos - SrcPosInt) * FracCount; + const int fti = (int)x; + rpos->x = (typename fpclass ::fptypeatom)(x - fti); + rpos->fti = fti; + rpos->SrcPosInt = SrcPosInt; + rpos++; + } + } + + /** + * Function updates filtering step buffer lengths depending on the + * specified source and new scanline lengths. This function should be + * called after the buildFilterSteps() function. + * + * @param Steps Array that receives filtering steps. + * @param[out] Vars Variables object, will receive buffer size and length. + * This function expects "k" and "o" variable values that will be + * adjusted by this function. + * @param RPosBufArray Resizing position buffers array, used to obtain + * buffer to initialize and use (will be reused if it is already fully or + * partially filled). + * @param SrcLen Source scanline's length in pixels. + * @param NewLen New scanline's length in pixels. + */ + + static void updateFilterStepBuffers( + CFilterSteps& Steps, CImageResizerVars& Vars, + typename CFilterStep ::CRPosBufArray& RPosBufArray, int SrcLen, + const int NewLen) { + int upstep = -1; + int InBuf = 0; + int i; + + for (i = 0; i < Steps.getItemCount(); i++) { + CFilterStep& fs = Steps[i]; + + fs.Vars = &Vars; + fs.InLen = SrcLen; + fs.InBuf = InBuf; + fs.OutBuf = (InBuf + 1) & 1; + + if (fs.IsUpsample) { + upstep = i; + Vars.k *= fs.ResampleFactor; + Vars.o *= fs.ResampleFactor; + fs.InPrefix = 0; + fs.InSuffix = 0; + fs.OutLen = fs.InLen * fs.ResampleFactor; + fs.OutPrefix = fs.FltLatency; + fs.OutSuffix = fs.Flt.getCapacity() - fs.FltLatency - fs.ResampleFactor; + + int l0 = fs.OutPrefix + fs.OutLen + fs.OutSuffix; + int l = fs.InLen * fs.ResampleFactor + fs.SuffixDC.getCapacity(); + + if (l > l0) { + fs.OutSuffix += l - l0; + } + + l0 = fs.OutLen + fs.OutSuffix; + + if (fs.PrefixDC.getCapacity() > l0) { + fs.OutSuffix += fs.PrefixDC.getCapacity() - l0; + } + } else if (fs.ResampleFactor == 0) { + const int FilterLenD2 = fs.FltBank->getFilterLen() / 2; + const int FilterLenD21 = FilterLenD2 - 1; + + const int ResizeLPix = (int)floor(Vars.o) - FilterLenD21; + fs.InPrefix = (ResizeLPix < 0 ? -ResizeLPix : 0); + const int ResizeRPix = + (int)floor(Vars.o + (NewLen - 1) * Vars.k) + FilterLenD2 + 1; + + fs.InSuffix = (ResizeRPix > fs.InLen ? ResizeRPix - fs.InLen : 0); + + fs.OutLen = NewLen; + fs.RPosBuf = &RPosBufArray.getRPosBuf(Vars.k, Vars.o, + fs.FltBank->getFracCount()); + + fillRPosBuf(fs, Vars); + } else { + Vars.k /= fs.ResampleFactor; + Vars.o /= fs.ResampleFactor; + Vars.o += fs.EdgePixelCount; + + fs.InPrefix = fs.FltLatency; + fs.InSuffix = fs.Flt.getCapacity() - fs.FltLatency - 1; + + // Additionally extend OutLen to produce more precise edge + // pixels. + + fs.OutLen = (fs.InLen + fs.ResampleFactor - 1) / fs.ResampleFactor + + fs.EdgePixelCount; + + fs.InSuffix += (fs.OutLen - 1) * fs.ResampleFactor + 1 - fs.InLen; + + fs.InPrefix += fs.EdgePixelCount * fs.ResampleFactor; + fs.OutLen += fs.EdgePixelCount; + } + + InBuf = fs.OutBuf; + SrcLen = fs.OutLen; + } + + Steps[Steps.getItemCount() - 1].OutBuf = 2; + + if (upstep != -1) { + extendUpsample(Steps[upstep], Steps[upstep + 1]); + } + } + + /** + * Function calculates an optimal intermediate buffer length that will + * cover all needs of the specified filtering steps. This function should + * be called after the updateFilterStepBuffers() function. + * + * Function also updates resizing step's RPosBuf pointers to the filter + * bank and SrcOffs values. + * + * @param Steps Filtering steps. + * @param[out] Vars Variables object, will receive buffer size and length. + * @param ResElIncr Resulting (final) element increment, used to produce + * de-interleaved result. For horizontal processing this value is equal + * to last step's OutLen, for vertical processing this value is equal to + * resulting image's width. + */ + + static void updateBufLenAndRPosPtrs(CFilterSteps& Steps, + CImageResizerVars& Vars, + const int ResElIncr) { + int MaxPrefix[2] = {0, 0}; + int MaxLen[2] = {0, 0}; + int i; + + for (i = 0; i < Steps.getItemCount(); i++) { + CFilterStep& fs = Steps[i]; + const int ib = fs.InBuf; + + if (fs.InPrefix > MaxPrefix[ib]) { + MaxPrefix[ib] = fs.InPrefix; + } + + int l = fs.InLen + fs.InSuffix; + + if (l > MaxLen[ib]) { + MaxLen[ib] = l; + } + + fs.InElIncr = fs.InPrefix + l; + + if (fs.OutBuf == 2) { + break; + } + + const int ob = fs.OutBuf; + + if (fs.IsUpsample) { + if (fs.OutPrefix > MaxPrefix[ob]) { + MaxPrefix[ob] = fs.OutPrefix; + } + + l = fs.OutLen + fs.OutSuffix; + + if (l > MaxLen[ob]) { + MaxLen[ob] = l; + } + } else { + if (fs.OutLen > MaxLen[ob]) { + MaxLen[ob] = fs.OutLen; + } + } + } + + // Update OutElIncr values of all steps. + + for (i = 0; i < Steps.getItemCount(); i++) { + CFilterStep& fs = Steps[i]; + + if (fs.OutBuf == 2) { + fs.OutElIncr = ResElIncr; + break; + } + + CFilterStep& fs2 = Steps[i + 1]; + + if (fs.IsUpsample) { + fs.OutElIncr = fs.OutPrefix + fs.OutLen + fs.OutSuffix; + + if (fs.OutElIncr > fs2.InElIncr) { + fs2.InElIncr = fs.OutElIncr; + } else { + fs.OutElIncr = fs2.InElIncr; + } + } else { + fs.OutElIncr = fs2.InElIncr; + } + } + + // Update temporary buffer's length. + + for (i = 0; i < 2; i++) { + Vars.BufLen[i] = MaxPrefix[i] + MaxLen[i]; + Vars.BufOffs[i] = MaxPrefix[i]; + + if (Vars.packmode == 0) { + Vars.BufOffs[i] *= Vars.ElCount; + } + + Vars.BufLen[i] *= Vars.ElCount; + } + + // Update RPosBuf pointers and SrcOffs. + + CFilterStep& fs = Steps[Vars.ResizeStep]; + typename CFilterStep ::CResizePos* rpos = &(*fs.RPosBuf)[0]; + const int em = (fpclass ::packmode == 0 ? Vars.ElCount : 1); + const int FilterLenD21 = fs.FltBank->getFilterLen() / 2 - 1; + + for (i = 0; i < fs.OutLen; i++) { + rpos->ftp = fs.FltBank->getFilter(rpos->fti); + rpos->SrcOffs = (rpos->SrcPosInt - FilterLenD21) * em; + rpos++; + } + } + + /** + * Function modifies the overall (DC) gain of the correction filter in the + * pre-built filtering steps array. + * + * @param Steps Filtering steps. + * @param m Multiplier to apply to the correction filter. + */ + + void modifyCorrFilterDCGain(CFilterSteps& Steps, const double m) const { + CBuffer* Flt; + const int z = Steps.getItemCount() - 1; + + if (!Steps[z].IsUpsample && Steps[z].ResampleFactor == 1) { + Flt = &Steps[z].Flt; + } else { + Flt = &Steps[0].Flt; + } + + int i; + + for (i = 0; i < Flt->getCapacity(); i++) { + (*Flt)[i] = (fptype)((double)(*Flt)[i] * m); + } + } + + /** + * Function builds a map of used fractional delay filters based on the + * resizing positions buffer. + * + * @param fs Resizing step. + * @param[out] UsedFracMap Map of used fractional delay filters. + */ + + static void fillUsedFracMap(const CFilterStep& fs, + CBuffer& UsedFracMap) { + const int FracCount = fs.FltBank->getFracCount(); + UsedFracMap.increaseCapacity(FracCount, false); + memset(&UsedFracMap[0], 0, FracCount * sizeof(UsedFracMap[0])); + + typename CFilterStep ::CResizePos* rpos = &(*fs.RPosBuf)[0]; + int i; + + for (i = 0; i < fs.OutLen; i++) { + UsedFracMap[rpos->fti] |= 1; + rpos++; + } + } + + /** + * Function calculates the overall filtering steps complexity per + * scanline. Each complexity unit corresponds to a single multiply-add + * operation. Data copy and pointer math operations are not included in + * this calculation, it is assumed that they correlate to the multiply-add + * operations. Calculation also does not include final rounding, dithering + * and clamping operations since they cannot be optimized out anyway. + * + * Calculation of the CRPosBuf buffer is not included since it cannot be + * avoided. + * + * This function should be called after the updateFilterStepBuffers() + * function. + * + * @param Steps Filtering steps array. + * @param Vars Variables object. + * @param UsedFracMap The map of used fractional delay filters. + * @param ScanlineCount Scanline count. + */ + + static int calcComplexity(const CFilterSteps& Steps, + const CImageResizerVars& Vars, + const CBuffer& UsedFracMap, + const int ScanlineCount) { + int fcnum; // Filter complexity multiplier numerator. + int fcdenom; // Filter complexity multiplier denominator. + + if (Vars.packmode != 0) { + fcnum = 1; + fcdenom = 1; + } else { + // In interleaved processing mode, filters require 1 less + // multiplication per 2 multiply-add instructions. + + fcnum = 3; + fcdenom = 4; + } + + int s = 0; // Complexity per one scanline. + int s2 = 0; // Complexity per all scanlines. + int i; + + for (i = 0; i < Steps.getItemCount(); i++) { + const CFilterStep& fs = Steps[i]; + + s2 += 65 * fs.Flt.getCapacity(); // Filter creation complexity. + + if (fs.IsUpsample) { + if (fs.FltOrig.getCapacity() > 0) { + continue; + } + + s += (fs.Flt.getCapacity() * (fs.InPrefix + fs.InLen + fs.InSuffix) + + fs.SuffixDC.getCapacity() + fs.PrefixDC.getCapacity()) * + Vars.ElCount; + } else if (fs.ResampleFactor == 0) { + s += fs.FltBank->getFilterLen() * + (fs.FltBank->getOrder() + Vars.ElCount) * fs.OutLen; + + s2 += fs.FltBank->calcInitComplexity(UsedFracMap); + } else { + s += fs.Flt.getCapacity() * Vars.ElCount * fs.OutLen * fcnum / fcdenom; + } + } + + return (s + s2 / ScanlineCount); + } + + /** + * @brief Thread-isolated data used for scanline processing. + * + * This structure holds data necessary for image's horizontal or vertical + * scanline processing, including scanline processing queue. + * + * @tparam Tin Source element data type. Intermediate buffers store data + * in floating point format. + * @tparam Tout Destination element data type. Intermediate buffers store + * data in floating point format. + */ + + template + class CThreadData : public CImageResizerThreadPool ::CWorkload { + public: + virtual void process() { processScanlineQueue(); } + + /** + * This enumeration lists possible scanline operations. + */ + + enum EScanlineOperation { + sopResizeH, ///< Resize horizontal scanline. + ///< + sopResizeV, ///< Resize vertical scanline. + ///< + sopDitherAndUnpackH, ///< Dither and unpack horizontal scanline. + ///< + sopUnpackH ///< Unpack horizontal scanline. + ///< + }; + + /** + * Function initializes *this thread data object and assigns certain + * variables provided by the higher level code. + * + * @param aThreadIndex Index of this thread data (0-based). + * @param aThreadCount Total number of threads used during processing. + * @param aSteps Filtering steps. + * @param aVars Image resizer variables. + */ + + void init(const int aThreadIndex, const int aThreadCount, + const CFilterSteps& aSteps, const CImageResizerVars& aVars) { + ThreadIndex = aThreadIndex; + ThreadCount = aThreadCount; + Steps = &aSteps; + Vars = &aVars; + } + + /** + * Function initializes scanline processing queue, and updates + * capacities of intermediate buffers. + * + * @param aOp Operation to perform over scanline. + * @param TotalLines The total number of scanlines that will be + * processed by all threads. + * @param aSrcLen Source scanline length in pixels. + * @param aSrcIncr Source scanline buffer increment. Ignored in + * horizontal scanline processing. + * @param aResIncr Resulting scanline buffer increment. Ignored in + * horizontal scanline processing. + */ + + void initScanlineQueue(const EScanlineOperation aOp, const int TotalLines, + const int aSrcLen, const int aSrcIncr = 0, + const int aResIncr = 0) { + const int l = Vars->BufLen[0] + Vars->BufLen[1]; + + if (Bufs.getCapacity() < l) { + Bufs.alloc(l, fpclass ::fpalign); + } + + BufPtrs[0] = Bufs + Vars->BufOffs[0]; + BufPtrs[1] = Bufs + Vars->BufLen[0] + Vars->BufOffs[1]; + + int j; + int ml = 0; + + for (j = 0; j < Steps->getItemCount(); j++) { + const CFilterStep& fs = (*Steps)[j]; + + if (fs.ResampleFactor == 0 && ml < fs.FltBank->getFilterLen()) { + ml = fs.FltBank->getFilterLen(); + } + } + + TmpFltBuf.alloc(ml, fpclass ::fpalign); + ScanlineOp = aOp; + SrcLen = aSrcLen; + SrcIncr = aSrcIncr; + ResIncr = aResIncr; + QueueLen = 0; + Queue.increaseCapacity((TotalLines + ThreadCount - 1) / ThreadCount, + false); + } + + /** + * Function adds a scanline to the queue buffer. The + * initScanlineQueue() function should be called before calling this + * function. The number of calls to this add function should not + * exceed the TotalLines spread over all threads. + * + * @param SrcBuf Source scanline buffer. + * @param ResBuf Resulting scanline buffer. + */ + + void addScanlineToQueue(void* const SrcBuf, void* const ResBuf) { + Queue[QueueLen].SrcBuf = SrcBuf; + Queue[QueueLen].ResBuf = ResBuf; + QueueLen++; + } + + /** + * Function processes all queued scanlines. + */ + + void processScanlineQueue() { + int i; + + switch (ScanlineOp) { + case sopResizeH: { + for (i = 0; i < QueueLen; i++) { + resizeScanlineH((Tin*)Queue[i].SrcBuf, (fptype*)Queue[i].ResBuf); + } + + break; + } + + case sopResizeV: { + for (i = 0; i < QueueLen; i++) { + resizeScanlineV((fptype*)Queue[i].SrcBuf, (fptype*)Queue[i].ResBuf); + } + + break; + } + + case sopDitherAndUnpackH: { + if (Vars->UseSRGBGamma) { + for (i = 0; i < QueueLen; i++) { + CFilterStep ::applySRGBGamma((fptype*)Queue[i].SrcBuf, SrcLen, + *Vars); + + Ditherer.dither((fptype*)Queue[i].SrcBuf); + + CFilterStep ::unpackScanline((fptype*)Queue[i].SrcBuf, + (Tout*)Queue[i].ResBuf, SrcLen, + *Vars); + } + } else { + for (i = 0; i < QueueLen; i++) { + Ditherer.dither((fptype*)Queue[i].SrcBuf); + + CFilterStep ::unpackScanline((fptype*)Queue[i].SrcBuf, + (Tout*)Queue[i].ResBuf, SrcLen, + *Vars); + } + } + + break; + } + + case sopUnpackH: { + if (Vars->UseSRGBGamma) { + for (i = 0; i < QueueLen; i++) { + CFilterStep ::applySRGBGamma((fptype*)Queue[i].SrcBuf, SrcLen, + *Vars); + + CFilterStep ::unpackScanline((fptype*)Queue[i].SrcBuf, + (Tout*)Queue[i].ResBuf, SrcLen, + *Vars); + } + } else { + for (i = 0; i < QueueLen; i++) { + CFilterStep ::unpackScanline((fptype*)Queue[i].SrcBuf, + (Tout*)Queue[i].ResBuf, SrcLen, + *Vars); + } + } + + break; + } + } + } + + /** + * Function returns ditherer object associated with *this thread data + * object. + */ + + CDitherer& getDitherer() { return (Ditherer); } + + private: + int ThreadIndex; ///< Thread index. + ///< + int ThreadCount; ///< Thread count. + ///< + const CFilterSteps* Steps; ///< Filtering steps. + ///< + const CImageResizerVars* Vars; ///< Image resizer variables. + ///< + CBuffer Bufs; ///< Flip-flop intermediate buffers. + ///< + fptype* BufPtrs[3]; ///< Flip-flop buffer pointers (referenced by + ///< filtering step's InBuf and OutBuf indices). + ///< + CBuffer + TmpFltBuf; ///< Temporary buffer used in the + ///< doResize() function, aligned by fpclass :: fpalign. + ///< + EScanlineOperation ScanlineOp; ///< Operation to perform over + ///< scanline. + ///< + int SrcLen; ///< Source scanline length in the last queue. + ///< + int SrcIncr; ///< Source scanline buffer increment in the last queue. + ///< + int ResIncr; ///< Resulting scanline buffer increment in the last + ///< queue. + ///< + CDitherer Ditherer; ///< Ditherer object to use. + ///< + + /** + * @brief Scanline processing queue item. + * + * Scanline processing queue item. + */ + + struct CQueueItem { + void* SrcBuf; ///< Source scanline buffer, will by typecasted to + ///< Tin or fptype*. + ///< + void* ResBuf; ///< Resulting scanline buffer, will by typecasted + ///< to Tout or fptype*. + ///< + }; + + CBuffer Queue; ///< Scanline processing queue. + ///< + int QueueLen; ///< Queue length. + ///< + + /** + * Function resizes a single horizontal scanline. + * + * @param SrcBuf Source scanline buffer. Can be either horizontal or + * vertical. + * @param ResBuf Resulting scanline buffer. + */ + + void resizeScanlineH(const Tin* const SrcBuf, fptype* const ResBuf) { + (*Steps)[0].packScanline(SrcBuf, BufPtrs[0], SrcLen); + BufPtrs[2] = ResBuf; + int j; + + for (j = 0; j < Steps->getItemCount(); j++) { + const CFilterStep& fs = (*Steps)[j]; + fs.prepareInBuf(BufPtrs[fs.InBuf]); + const int DstIncr = (Vars->packmode == 0 ? Vars->ElCount : 1); + + if (fs.ResampleFactor != 0) { + if (fs.IsUpsample) { + fs.doUpsample(BufPtrs[fs.InBuf], BufPtrs[fs.OutBuf]); + } else { + fs.doFilter(BufPtrs[fs.InBuf], BufPtrs[fs.OutBuf], DstIncr); + } + } else { + fs.doResize(BufPtrs[fs.InBuf], BufPtrs[fs.OutBuf], DstIncr, + TmpFltBuf); + } + } + } + + /** + * Function resizes a single vertical scanline. + * + * @param SrcBuf Source scanline buffer. Can be either horizontal or + * vertical. + * @param ResBuf Resulting scanline buffer. + */ + + void resizeScanlineV(const fptype* const SrcBuf, fptype* const ResBuf) { + (*Steps)[0].convertVtoH(SrcBuf, BufPtrs[0], SrcLen, SrcIncr); + + BufPtrs[2] = ResBuf; + int j; + + for (j = 0; j < Steps->getItemCount(); j++) { + const CFilterStep& fs = (*Steps)[j]; + fs.prepareInBuf(BufPtrs[fs.InBuf]); + const int DstIncr = + (fs.OutBuf == 2 ? ResIncr + : (Vars->packmode == 0 ? Vars->ElCount : 1)); + + if (fs.ResampleFactor != 0) { + if (fs.IsUpsample) { + fs.doUpsample(BufPtrs[fs.InBuf], BufPtrs[fs.OutBuf]); + } else { + fs.doFilter(BufPtrs[fs.InBuf], BufPtrs[fs.OutBuf], DstIncr); + } + } else { + fs.doResize(BufPtrs[fs.InBuf], BufPtrs[fs.OutBuf], DstIncr, + TmpFltBuf); + } + } + } + }; +}; + +#undef AVIR_PI +#undef AVIR_PId2 + +} // namespace avir + +#endif // AVIR_CIMAGERESIZER_INCLUDED +/* clang-format off */ +//$ nobt +//$ nocpp +#include "libc/calls/calls.h" + +/** + * @file avir.h + * + * @brief The "main" inclusion file with all required classes and functions. + * + * This is the "main" inclusion file for the "AVIR" image resizer. This + * inclusion file contains implementation of the AVIR image resizing algorithm + * in its entirety. Also includes several classes and functions that can be + * useful elsewhere. + * + * AVIR Copyright (c) 2015-2019 Aleksey Vaneev + * + * @mainpage + * + * @section intro_sec Introduction + * + * Description is available at https://github.com/avaneev/avir + * + * AVIR is devoted to women. Your digital photos can look good at any size! + * + * @section license License + * + * AVIR License Agreement + * + * The MIT License (MIT) + * + * Copyright (c) 2015-2019 Aleksey Vaneev + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Please credit the author of this library in your documentation in the + * following way: "AVIR image resizing algorithm designed by Aleksey Vaneev" + * + * @version 2.4 + */ + +#ifndef AVIR_CIMAGERESIZER_INCLUDED +#define AVIR_CIMAGERESIZER_INCLUDED + +#include +#include +#include +#include + +namespace avir { + +/** + * The macro defines AVIR version string. + */ + +#define AVIR_VERSION "2.4" + +/** + * The macro equals to "pi" constant, fills 53-bit floating point mantissa. + * Undefined at the end of file. + */ + +#define AVIR_PI 3.1415926535897932 + +/** + * The macro equals to "pi divided by 2" constant, fills 53-bit floating + * point mantissa. Undefined at the end of file. + */ + +#define AVIR_PId2 1.5707963267948966 + +/** + * Rounding function, based on the (int) typecast. Biased result. Not suitable + * for numbers >= 2^31. + * + * @param d Value to round. + * @return Rounded value. Some bias may be introduced. + */ + +template< class T > +inline T round( const T d ) +{ + return( d < 0.0 ? -(T) (int) ( (T) 0.5 - d ) : (T) (int) ( d + (T) 0.5 )); +} + +/** + * Template function "clamps" (clips) the specified value so that it is not + * lesser than "minv", and not greater than "maxv". + * + * @param Value Value to clamp. + * @param minv Minimal allowed value. + * @param maxv Maximal allowed value. + * @return The clamped value. + */ + +template< class T > +inline T clamp( const T& Value, const T minv, const T maxv ) +{ + if( Value < minv ) + { + return( minv ); + } + else + if( Value > maxv ) + { + return( maxv ); + } + else + { + return( Value ); + } +} + +/** + * Power 2.4 approximation function, designed for sRGB gamma correction. + * + * @param x Argument, in the range 0.09 to 1. + * @return Value raised into power 2.4, approximate. + */ + +template< class T > +inline T pow24_sRGB( const T x ) +{ + const double x2 = x * x; + const double x3 = x2 * x; + const double x4 = x2 * x2; + + return( (T) ( 0.0985766365536824 + 0.839474952656502 * x2 + + 0.363287814061725 * x3 - 0.0125559718896615 / + ( 0.12758338921578 + 0.290283465468235 * x ) - + 0.231757513261358 * x - 0.0395365717969074 * x4 )); +} + +/** + * Power 1/2.4 approximation function, designed for sRGB gamma correction. + * + * @param x Argument, in the range 0.003 to 1. + * @return Value raised into power 1/2.4, approximate. + */ + +template< class T > +inline T pow24i_sRGB( const T x ) +{ + const double sx = sqrt( x ); + const double ssx = sqrt( sx ); + const double sssx = sqrt( ssx ); + + return( (T) ( 0.000213364515060263 + 0.0149409239419218 * x + + 0.433973412731747 * sx + ssx * ( 0.659628181609715 * sssx - + 0.0380957908841466 - 0.0706476137208521 * sx ))); +} + +/** + * Function approximately linearizes the sRGB gamma value. + * + * @param s sRGB gamma value, in the range 0 to 1. + * @return Linearized sRGB gamma value, approximated. + */ + +template< class T > +inline T convertSRGB2Lin( const T s ) +{ + const T a = (T) 0.055; + + if( s <= (T) 0.04045 ) + { + return( s / (T) 12.92 ); + } + + return( pow24_sRGB(( s + a ) / ( (T) 1 + a ))); +} + +/** + * Function approximately de-linearizes the linear gamma value. + * + * @param s Linear gamma value, in the range 0 to 1. + * @return sRGB gamma value, approximated. + */ + +template< class T > +inline T convertLin2SRGB( const T s ) +{ + const T a = (T) 0.055; + + if( s <= (T) 0.0031308 ) + { + return( (T) 12.92 * s ); + } + + return(( (T) 1 + a ) * pow24i_sRGB( s ) - a ); +} + +/** + * Function converts (via typecast) specified array of type T1 values of + * length l into array of type T2 values. If T1 is the same as T2, copy + * operation is performed. When copying data at overlapping address spaces, + * "op" should be lower than "ip". + * + * @param ip Input buffer. + * @param[out] op Output buffer. + * @param l The number of elements to copy. + * @param ip Input buffer pointer increment. + * @param op Output buffer pointer increment. + */ + +template< class T1, class T2 > +inline void copyArray( const T1* ip, T2* op, int l, + const int ipinc = 1, const int opinc = 1 ) +{ + while( l > 0 ) + { + *op = (T2) *ip; + op += opinc; + ip += ipinc; + l--; + } +} + +/** + * Function adds values located in array "ip" to array "op". + * + * @param ip Input buffer. + * @param[out] op Output buffer. + * @param l The number of elements to add. + * @param ip Input buffer pointer increment. + * @param op Output buffer pointer increment. + */ + +template< class T1, class T2 > +inline void addArray( const T1* ip, T2* op, int l, + const int ipinc = 1, const int opinc = 1 ) +{ + while( l > 0 ) + { + *op += *ip; + op += opinc; + ip += ipinc; + l--; + } +} + +/** + * Function that replicates a set of adjacent elements several times in a row. + * This operation is usually used to replicate pixels at the start or end of + * image's scanline. + * + * @param ip Source array. + * @param ipl Source array length (usually 1..4, but can be any number). + * @param[out] op Destination buffer. + * @param l Number of times the source array should be replicated (the + * destination buffer should be able to hold ipl * l number of elements). + * @param opinc Destination buffer position increment after replicating the + * source array. This value should be equal to at least ipl. + */ + +template< class T1, class T2 > +inline void replicateArray( const T1* const ip, const int ipl, T2* op, int l, + const int opinc ) +{ + if( ipl == 1 ) + { + while( l > 0 ) + { + op[ 0 ] = ip[ 0 ]; + op += opinc; + l--; + } + } + else + if( ipl == 4 ) + { + while( l > 0 ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op[ 2 ] = ip[ 2 ]; + op[ 3 ] = ip[ 3 ]; + op += opinc; + l--; + } + } + else + if( ipl == 3 ) + { + while( l > 0 ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op[ 2 ] = ip[ 2 ]; + op += opinc; + l--; + } + } + else + if( ipl == 2 ) + { + while( l > 0 ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op += opinc; + l--; + } + } + else + { + while( l > 0 ) + { + int i; + + for( i = 0; i < ipl; i++ ) + { + op[ i ] = ip[ i ]; + } + + op += opinc; + l--; + } + } +} + +/** + * Function calculates frequency response of the specified FIR filter at the + * specified circular frequency. Phase can be calculated as atan2( im, re ). + * Function uses computationally-efficient oscillators instead of "cos" and + * "sin" functions. + * + * @param flt FIR filter's coefficients. + * @param fltlen Number of coefficients (taps) in the filter. + * @param th Circular frequency [0; pi]. + * @param[out] re0 Resulting real part of the complex frequency response. + * @param[out] im0 Resulting imaginary part of the complex frequency response. + * @param fltlat Filter's latency in samples (taps). + */ + +template< class T > +inline void calcFIRFilterResponse( const T* flt, int fltlen, + const double th, double& re0, double& im0, const int fltlat = 0 ) +{ + const double sincr = 2.0 * cos( th ); + double cvalue1; + double svalue1; + + if( fltlat == 0 ) + { + cvalue1 = 1.0; + svalue1 = 0.0; + } + else + { + cvalue1 = cos( -fltlat * th ); + svalue1 = sin( -fltlat * th ); + } + + double cvalue2 = cos( -( fltlat + 1 ) * th ); + double svalue2 = sin( -( fltlat + 1 ) * th ); + + double re = 0.0; + double im = 0.0; + + while( fltlen > 0 ) + { + re += cvalue1 * flt[ 0 ]; + im += svalue1 * flt[ 0 ]; + flt++; + fltlen--; + + double tmp = cvalue1; + cvalue1 = sincr * cvalue1 - cvalue2; + cvalue2 = tmp; + + tmp = svalue1; + svalue1 = sincr * svalue1 - svalue2; + svalue2 = tmp; + } + + re0 = re; + im0 = im; +} + +/** + * Function normalizes FIR filter so that its frequency response at DC is + * equal to DCGain. + * + * @param[in,out] p Filter coefficients. + * @param l Filter length. + * @param DCGain Filter's gain at DC. + * @param pstep "p" array step. + */ + +template< class T > +inline void normalizeFIRFilter( T* const p, const int l, const double DCGain, + const int pstep = 1 ) +{ + double s = 0.0; + T* pp = p; + int i = l; + + while( i > 0 ) + { + s += *pp; + pp += pstep; + i--; + } + + s = DCGain / s; + pp = p; + i = l; + + while( i > 0 ) + { + *pp = (T) ( *pp * s ); + pp += pstep; + i--; + } +} + +/** + * @brief Memory buffer class for element array storage, with capacity + * tracking. + * + * Allows easier handling of memory blocks allocation and automatic + * deallocation for arrays (buffers) consisting of elements of specified + * class. Tracks buffer's capacity in "int" variable; unsuitable for + * allocation of very large memory blocks (with more than 2 billion elements). + * + * This class manages memory space only - it does not perform element class + * construction (initialization) operations. Buffer's required memory address + * alignment specification is supported. + * + * Uses standard library to allocate and deallocate memory. + * + * @tparam T Buffer element's type. + * @tparam capint Buffer capacity's type to use. Use size_t for large buffers. + */ + +template< class T, typename capint = int > +class CBuffer +{ +public: + CBuffer() + : Data( NULL ) + , DataAligned( NULL ) + , Capacity( 0 ) + , Alignment( 0 ) + { + } + + /** + * Constructor creates the buffer with the specified capacity. + * + * @param aCapacity Buffer's capacity. + * @param aAlignment Buffer's required memory address alignment. 0 - use + * stdlib's default alignment. + */ + + CBuffer( const capint aCapacity, const int aAlignment = 0 ) + { + allocinit( aCapacity, aAlignment ); + } + + CBuffer( const CBuffer& Source ) + { + allocinit( Source.Capacity, Source.Alignment ); + memcpy( DataAligned, Source.DataAligned, Capacity * sizeof( T )); + } + + ~CBuffer() + { + freeData(); + } + + CBuffer& operator = ( const CBuffer& Source ) + { + alloc( Source.Capacity, Source.Alignment ); + memcpy( DataAligned, Source.DataAligned, Capacity * sizeof( T )); + return( *this ); + } + + /** + * Function allocates memory so that the specified number of elements + * can be stored in *this buffer object. + * + * @param aCapacity Storage for this number of elements to allocate. + * @param aAlignment Buffer's required memory address alignment, + * power-of-2 values only. 0 - use stdlib's default alignment. + */ + + void alloc( const capint aCapacity, const int aAlignment = 0 ) + { + freeData(); + allocinit( aCapacity, aAlignment ); + } + + /** + * Function deallocates any previously allocated buffer. + */ + + void free() + { + freeData(); + Data = NULL; + DataAligned = NULL; + Capacity = 0; + Alignment = 0; + } + + /** + * @return The capacity of the element buffer. + */ + + capint getCapacity() const + { + return( Capacity ); + } + + /** + * Function "forces" *this buffer to have an arbitary capacity. Calling + * this function invalidates all further operations except deleting *this + * object. This function should not be usually used at all. Function can + * be used to "model" certain buffer capacity without calling a costly + * memory allocation function. + * + * @param NewCapacity A new "forced" capacity. + */ + + void forceCapacity( const capint NewCapacity ) + { + Capacity = NewCapacity; + } + + /** + * Function reallocates *this buffer to a larger size so that it will be + * able to hold the specified number of elements. Downsizing is not + * performed. Alignment is not changed. + * + * @param NewCapacity New (increased) capacity. + * @param DoDataCopy "True" if data in the buffer should be retained. + */ + + void increaseCapacity( const capint NewCapacity, + const bool DoDataCopy = true ) + { + if( NewCapacity < Capacity ) + { + return; + } + + if( DoDataCopy ) + { + const capint PrevCapacity = Capacity; + T* const PrevData = Data; + T* const PrevDataAligned = DataAligned; + + allocinit( NewCapacity, Alignment ); + memcpy( DataAligned, PrevDataAligned, PrevCapacity * sizeof( T )); + + :: free( PrevData ); + } + else + { + :: free( Data ); + allocinit( NewCapacity, Alignment ); + } + } + + /** + * Function "truncates" (reduces) capacity of the buffer without + * reallocating it. Alignment is not changed. + * + * @param NewCapacity New required capacity. + */ + + void truncateCapacity( const capint NewCapacity ) + { + if( NewCapacity >= Capacity ) + { + return; + } + + Capacity = NewCapacity; + } + + /** + * Function increases capacity so that the specified number of + * elements can be stored. This function increases the previous capacity + * value by third the current capacity value until space for the required + * number of elements is available. Alignment is not changed. + * + * @param ReqCapacity Required capacity. + */ + + void updateCapacity( const capint ReqCapacity ) + { + if( ReqCapacity <= Capacity ) + { + return; + } + + capint NewCapacity = Capacity; + + while( NewCapacity < ReqCapacity ) + { + NewCapacity += NewCapacity / 3 + 1; + } + + increaseCapacity( NewCapacity ); + } + + operator T* () const + { + return( DataAligned ); + } + +private: + T* Data; ///< Element buffer pointer. + ///< + T* DataAligned; ///< Memory address-aligned element buffer pointer. + ///< + capint Capacity; ///< Element buffer capacity. + ///< + int Alignment; ///< Memory address alignment in use. 0 - use stdlib's + ///< default alignment. + ///< + + /** + * Internal element buffer allocation function used during object + * construction. + * + * @param aCapacity Storage for this number of elements to allocate. + * @param aAlignment Buffer's required memory address alignment. 0 - use + * stdlib's default alignment. + */ + + void allocinit( const capint aCapacity, const int aAlignment ) + { + if( aAlignment == 0 ) + { + Data = (T*) :: malloc( aCapacity * sizeof( T )); + DataAligned = Data; + Alignment = 0; + } + else + { + Data = (T*) :: malloc( aCapacity * sizeof( T ) + aAlignment ); + DataAligned = alignptr( Data, aAlignment ); + Alignment = aAlignment; + } + + Capacity = aCapacity; + } + + /** + * Function frees a previously allocated Data buffer. + */ + + void freeData() + { + :: free( Data ); + } + + /** + * Function modifies the specified pointer so that it becomes memory + * address-aligned. + * + * @param ptr Pointer to align. + * @param align Alignment in bytes to apply. + * @return Pointer aligned to align bytes. Works with power-of-2 + * alignments only. If no alignment is necessary, "align" bytes will be + * added to the pointer value. + */ + + template< class Tp > + inline Tp alignptr( const Tp ptr, const uintptr_t align ) + { + return( (Tp) ( (uintptr_t) ptr + align - + ( (uintptr_t) ptr & ( align - 1 ))) ); + } +}; + +/** + * Function optimizes the length of the symmetric-odd FIR filter by removing + * left- and rightmost elements that are below specific threshold. + * + * Synthetic test shows that filter gets optimized in 2..3% of cases and in + * each such case optimization reduces filter length by 6..8%. Optimization, + * however, may skew the results of algorithm modeling and complexity + * calculation leading to a choice of a less optimal algorithm. + * + * @param[in,out] Flt Buffer that contains filter being optimized. + * @param[in,out] FltLatency Variable that holds the current latency of the + * filter. May be adjusted on function return. + * @param Threshold Threshold level. + */ + +template< class T > +inline void optimizeFIRFilter( CBuffer< T >& Flt, int& FltLatency, + T const Threshold = (T) 0.00001 ) +{ + int i; + + // Optimize length. + + for( i = 0; i <= FltLatency; i++ ) + { + if( fabs( Flt[ i ]) >= Threshold || i == FltLatency ) + { + if( i > 0 ) + { + const int NewCapacity = Flt.getCapacity() - i * 2; + copyArray( &Flt[ i ], &Flt[ 0 ], NewCapacity ); + Flt.truncateCapacity( NewCapacity ); + FltLatency -= i; + } + + break; + } + } +} + +/** + * @brief Array of structured objects. + * + * Implements allocation of a linear array of objects of class T (which are + * initialized), addressable via operator[]. Each object is created via the + * "operator new". New object insertions are quick since implementation uses + * prior space allocation (capacity), thus not requiring frequent memory block + * reallocations. + * + * @tparam T Array element's type. + */ + +template< class T > +class CStructArray +{ +public: + CStructArray() + : ItemCount( 0 ) + { + } + + CStructArray( const CStructArray& Source ) + : ItemCount( 0 ) + , Items( Source.getItemCount() ) + { + while( ItemCount < Source.getItemCount() ) + { + Items[ ItemCount ] = new T( Source[ ItemCount ]); + ItemCount++; + } + } + + ~CStructArray() + { + clear(); + } + + CStructArray& operator = ( const CStructArray& Source ) + { + clear(); + + const int NewCount = Source.ItemCount; + Items.updateCapacity( NewCount ); + + while( ItemCount < NewCount ) + { + Items[ ItemCount ] = new T( Source[ ItemCount ]); + ItemCount++; + } + + return( *this ); + } + + T& operator []( const int Index ) + { + return( *Items[ Index ]); + } + + const T& operator []( const int Index ) const + { + return( *Items[ Index ]); + } + + /** + * Function creates a new object of type T with the default constructor + * and adds this object to the array. + * + * @return Reference to a newly added object. + */ + + T& add() + { + if( ItemCount == Items.getCapacity() ) + { + Items.increaseCapacity( ItemCount * 3 / 2 + 1 ); + } + + Items[ ItemCount ] = new T(); + ItemCount++; + + return( (*this)[ ItemCount - 1 ]); + } + + /** + * Function changes number of allocated items. New items are created with + * the default constructor. If NewCount is below the current item count, + * items that are above NewCount range will be destructed. + * + * @param NewCount New requested item count. + */ + + void setItemCount( const int NewCount ) + { + if( NewCount > ItemCount ) + { + Items.increaseCapacity( NewCount ); + + while( ItemCount < NewCount ) + { + Items[ ItemCount ] = new T(); + ItemCount++; + } + } + else + { + while( ItemCount > NewCount ) + { + ItemCount--; + delete Items[ ItemCount ]; + } + } + } + + /** + * Function erases all items of *this array. + */ + + void clear() + { + while( ItemCount > 0 ) + { + ItemCount--; + delete Items[ ItemCount ]; + } + } + + /** + * @return The number of allocated items. + */ + + int getItemCount() const + { + return( ItemCount ); + } + +private: + int ItemCount; ///< The number of items available in the array. + ///< + CBuffer< T* > Items; ///< Element buffer. + ///< +}; + +/** + * @brief Sine signal generator class. + * + * Class implements sine signal generator without biasing, with + * constructor-based initalization only. This generator uses oscillator + * instead of "sin" function. + */ + +class CSineGen +{ +public: + /** + * Constructor initializes *this sine signal generator. + * + * @param si Sine function increment, in radians. + * @param ph Starting phase, in radians. Add 0.5 * AVIR_PI for cosine + * function. + */ + + CSineGen( const double si, const double ph ) + : svalue1( sin( ph )) + , svalue2( sin( ph - si )) + , sincr( 2.0 * cos( si )) + { + } + + /** + * @return The next value of the sine function, without biasing. + */ + + double generate() + { + const double res = svalue1; + + svalue1 = sincr * res - svalue2; + svalue2 = res; + + return( res ); + } + +private: + double svalue1; ///< Current sine value. + ///< + double svalue2; ///< Previous sine value. + ///< + double sincr; ///< Sine value increment. + ///< +}; + +/** + * @brief Peaked Cosine window function generator class. + * + * Class implements Peaked Cosine window function generator. Generates the + * right-handed half of the window function. The Alpha parameter of this + * window function offers the control of the balance between the early and + * later taps of the filter. E.g. at Alpha=1 both early and later taps are + * attenuated, but at Alpha=4 mostly later taps are attenuated. This offers a + * great control over ringing artifacts produced by a low-pass filter in image + * processing, without compromising achieved image sharpness. + */ + +class CDSPWindowGenPeakedCosine +{ +public: + /** + * Constructor initializes *this window function generator. + * + * @param aAlpha Alpha parameter, affects the peak shape (peak + * augmentation) of the window function. Should be >= 1.0. + * @param aLen2 Half filter's length (non-truncated). + */ + + CDSPWindowGenPeakedCosine( const double aAlpha, const double aLen2 ) + : Alpha( aAlpha ) + , Len2( aLen2 ) + , wn( 0 ) + , w1( AVIR_PId2 / Len2, AVIR_PI * 0.5 ) + { + } + + /** + * @return The next Peaked Cosine window function coefficient. + */ + + double generate() + { + const double h = pow( wn / Len2, Alpha ); + wn++; + + return( w1.generate() * ( 1.0 - h )); + } + +private: + double Alpha; ///< Alpha parameter, affects the peak shape of window. + ///< + double Len2; ///< Half length of the window function. + ///< + int wn; ///< Window function integer position. 0 - center of the + ///< window function. + ///< + CSineGen w1; ///< Sine-wave generator. + ///< +}; + +/** + * @brief FIR filter-based equalizer generator. + * + * Class implements an object used to generate symmetric-odd FIR filters with + * the specified frequency response (aka paragraphic equalizer). The + * calculated filter is windowed by the Peaked Cosine window function. + * + * In image processing, due to short length of filters being used (6-8 taps) + * the resulting frequency response of the filter is approximate and may be + * mathematically imperfect, but still adequate to the visual requirements. + * + * On a side note, this equalizer generator can be successfully used for audio + * signal equalization as well: for example, it is used in almost the same + * form in Voxengo Marvel GEQ equalizer plug-in. + * + * Filter generation is based on decomposition of frequency range into + * spectral bands, with each band represented by linear and ramp "kernels". + * When the filter is built, these kernels are combined together with + * different weights that approximate the required frequency response. + */ + +class CDSPFIREQ +{ +public: + /** + * Function initializes *this object with the required parameters. The + * gain of frequencies beyond the MinFreq..MaxFreq range are controlled by + * the first and the last band's gain. + * + * @param SampleRate Processing sample rate (use 2 for image processing). + * @param aFilterLength Required filter length in samples (taps). The + * actual filter length is truncated to an integer value. + * @param aBandCount Number of band crossover points required to control, + * including bands at MinFreq and MaxFreq. + * @param MinFreq Minimal frequency that should be controlled. + * @param MaxFreq Maximal frequency that should be controlled. + * @param IsLogBands "True" if the bands should be spaced logarithmically. + * @param WFAlpha Peaked Cosine window function's Alpha parameter. + */ + + void init( const double SampleRate, const double aFilterLength, + const int aBandCount, const double MinFreq, const double MaxFreq, + const bool IsLogBands, const double WFAlpha ) + { + FilterLength = aFilterLength; + BandCount = aBandCount; + + CenterFreqs.alloc( BandCount ); + + z = (int) ceil( FilterLength * 0.5 ); + zi = z + ( z & 1 ); + z2 = z * 2; + + CBuffer< double > oscbuf( z2 ); + initOscBuf( oscbuf ); + + CBuffer< double > winbuf( z ); + initWinBuf( winbuf, WFAlpha ); + + UseFirstVirtBand = ( MinFreq > 0.0 ); + const int k = zi * ( BandCount + ( UseFirstVirtBand ? 1 : 0 )); + Kernels1.alloc( k ); + Kernels2.alloc( k ); + + double m; // Frequency step multiplier. + double mo; // Frequency step offset (addition). + + if( IsLogBands ) + { + m = exp( log( MaxFreq / MinFreq ) / ( BandCount - 1 )); + mo = 0.0; + } + else + { + m = 1.0; + mo = ( MaxFreq - MinFreq ) / ( BandCount - 1 ); + } + + double f = MinFreq; + double x1 = 0.0; + double x2; + int si; + + if( UseFirstVirtBand ) + { + si = 0; + } + else + { + si = 1; + CenterFreqs[ 0 ] = 0.0; + f = f * m + mo; + } + + double* kernbuf1 = &Kernels1[ 0 ]; + double* kernbuf2 = &Kernels2[ 0 ]; + int i; + + for( i = si; i < BandCount; i++ ) + { + x2 = f * 2.0 / SampleRate; + CenterFreqs[ i ] = x2; + + fillBandKernel( x1, x2, kernbuf1, kernbuf2, oscbuf, winbuf ); + + kernbuf1 += zi; + kernbuf2 += zi; + x1 = x2; + f = f * m + mo; + } + + if( x1 < 1.0 ) + { + UseLastVirtBand = true; + fillBandKernel( x1, 1.0, kernbuf1, kernbuf2, oscbuf, winbuf ); + } + else + { + UseLastVirtBand = false; + } + } + + /** + * @return Filter's length, in samples (taps). + */ + + int getFilterLength() const + { + return( z2 - 1 ); + } + + /** + * @return Filter's latency (group delay), in samples (taps). + */ + + int getFilterLatency() const + { + return( z - 1 ); + } + + /** + * Function creates symmetric-odd FIR filter with the specified gain + * levels at band crossover points. + * + * @param BandGains Array of linear gain levels, count=BandCount specified + * in the init() function. + * @param[out] Filter Output filter buffer, length = getFilterLength(). + */ + + void buildFilter( const double* const BandGains, double* const Filter ) + { + const double* kernbuf1 = &Kernels1[ 0 ]; + const double* kernbuf2 = &Kernels2[ 0 ]; + double x1 = 0.0; + double y1 = BandGains[ 0 ]; + double x2; + double y2; + + int i; + int si; + + if( UseFirstVirtBand ) + { + si = 1; + x2 = CenterFreqs[ 0 ]; + y2 = y1; + } + else + { + si = 2; + x2 = CenterFreqs[ 1 ]; + y2 = BandGains[ 1 ]; + } + + copyBandKernel( Filter, kernbuf1, kernbuf2, y1 - y2, + x1 * y2 - x2 * y1 ); + + kernbuf1 += zi; + kernbuf2 += zi; + x1 = x2; + y1 = y2; + + for( i = si; i < BandCount; i++ ) + { + x2 = CenterFreqs[ i ]; + y2 = BandGains[ i ]; + + addBandKernel( Filter, kernbuf1, kernbuf2, y1 - y2, + x1 * y2 - x2 * y1 ); + + kernbuf1 += zi; + kernbuf2 += zi; + x1 = x2; + y1 = y2; + } + + if( UseLastVirtBand ) + { + addBandKernel( Filter, kernbuf1, kernbuf2, y1 - y2, + x1 * y2 - y1 ); + } + + for( i = 0; i < z - 1; i++ ) + { + Filter[ z + i ] = Filter[ z - 2 - i ]; + } + } + + /** + * Function calculates filter's length (in samples) and latency depending + * on the required non-truncated filter length. + * + * @param aFilterLength Required filter length in samples (non-truncated). + * @param[out] Latency Resulting latency (group delay) of the filter, + * in samples (taps). + * @return Filter length in samples (taps). + */ + + static int calcFilterLength( const double aFilterLength, int& Latency ) + { + const int l = (int) ceil( aFilterLength * 0.5 ); + Latency = l - 1; + + return( l * 2 - 1 ); + } + +private: + double FilterLength; ///< Length of filter. + ///< + int z; ///< Equals (int) ceil( FilterLength * 0.5 ). + ///< + int zi; ///< Equals "z" if z is even, or z + 1 if z is odd. Used as a + ///< Kernels1 and Kernels2 size multiplier and kernel buffer increment + ///< to make sure each kernel buffer is 16-byte aligned. + ///< + int z2; ///< Equals z * 2. + ///< + int BandCount; ///< Number of controllable bands. + ///< + CBuffer< double > CenterFreqs; ///< Center frequencies for all bands, + ///< normalized to 0.0-1.0 range. + ///< + CBuffer< double > Kernels1; ///< Half-length kernel buffers for each + ///< spectral band (linear part). + ///< + CBuffer< double > Kernels2; ///< Half-length kernel buffers for each + ///< spectral band (ramp part). + ///< + bool UseFirstVirtBand; ///< "True" if the first virtual band + ///< (between 0.0 and MinFreq) should be used. The first virtual band + ///< won't be used if MinFreq equals 0.0. + ///< + bool UseLastVirtBand; ///< "True" if the last virtual band (between + ///< MaxFreq and SampleRate * 0.5) should be used. The last virtual + ///< band won't be used if MaxFreq * 2.0 equals SampleRate. + ///< + + /** + * Function initializes the "oscbuf" used in the fillBandKernel() + * function. + * + * @param oscbuf Oscillator buffer, length = z * 2. + */ + + void initOscBuf( double* oscbuf ) const + { + int i = z; + + while( i > 0 ) + { + oscbuf[ 0 ] = 0.0; + oscbuf[ 1 ] = 1.0; + oscbuf += 2; + i--; + } + } + + /** + * Function initializes window function buffer. This function generates + * Peaked Cosine window function. + * + * @param winbuf Windowing buffer. + * @param Alpha Peaked Cosine alpha parameter. + */ + + void initWinBuf( double* winbuf, const double Alpha ) const + { + CDSPWindowGenPeakedCosine wf( Alpha, FilterLength * 0.5 ); + int i; + + for( i = 1; i <= z; i++ ) + { + winbuf[ z - i ] = wf.generate(); + } + } + + /** + * Function fills first half of symmetric-odd FIR kernel for the band. + * This function should be called successively for adjacent bands. + * Previous band's x2 should be equal to current band's x1. A band kernel + * consists of 2 elements: linear kernel and ramp kernel. + * + * @param x1 Band's left corner frequency (0..1). + * @param x2 Band's right corner frequency (0..1). + * @param kernbuf1 Band kernel buffer 1 (linear part), length = z. + * @param kernbuf2 Band kernel buffer 2 (ramp part), length = z. + * @param oscbuf Oscillation buffer. Before the first call of the + * fillBandKernel() should be initialized with the call of the + * initOscBuf() function. + * @param winbuf Buffer that contains windowing function. + */ + + void fillBandKernel( const double x1, const double x2, double* kernbuf1, + double* kernbuf2, double* oscbuf, const double* const winbuf ) + { + const double s2_incr = AVIR_PI * x2; + const double s2_coeff = 2.0 * cos( s2_incr ); + + double s2_value1 = sin( s2_incr * ( -z + 1 )); + double c2_value1 = sin( s2_incr * ( -z + 1 ) + AVIR_PI * 0.5 ); + oscbuf[ 0 ] = sin( s2_incr * -z ); + oscbuf[ 1 ] = sin( s2_incr * -z + AVIR_PI * 0.5 ); + + int ks; + + for( ks = 1; ks < z; ks++ ) + { + const int ks2 = ks * 2; + const double s1_value1 = oscbuf[ ks2 ]; + const double c1_value1 = oscbuf[ ks2 + 1 ]; + oscbuf[ ks2 ] = s2_value1; + oscbuf[ ks2 + 1 ] = c2_value1; + + const double x = AVIR_PI * ( ks - z ); + const double v0 = winbuf[ ks - 1 ] / (( x1 - x2 ) * x ); + + kernbuf1[ ks - 1 ] = ( x2 * s2_value1 - x1 * s1_value1 + + ( c2_value1 - c1_value1 ) / x ) * v0; + + kernbuf2[ ks - 1 ] = ( s2_value1 - s1_value1 ) * v0; + + s2_value1 = s2_coeff * s2_value1 - oscbuf[ ks2 - 2 ]; + c2_value1 = s2_coeff * c2_value1 - oscbuf[ ks2 - 1 ]; + } + + kernbuf1[ z - 1 ] = ( x2 * x2 - x1 * x1 ) / ( x1 - x2 ) * 0.5; + kernbuf2[ z - 1 ] = -1.0; + } + + /** + * Function copies band kernel's elements to the output buffer. + * + * @param outbuf Output buffer. + * @param kernbuf1 Kernel buffer 1 (linear part). + * @param kernbuf2 Kernel buffer 2 (ramp part). + * @param c Multiplier for linear kernel element. + * @param d Multiplier for ramp kernel element. + */ + + void copyBandKernel( double* outbuf, const double* const kernbuf1, + const double* const kernbuf2, const double c, const double d ) const + { + int ks; + + for( ks = 0; ks < z; ks++ ) + { + outbuf[ ks ] = c * kernbuf1[ ks ] + d * kernbuf2[ ks ]; + } + } + + /** + * Function adds band kernel's elements to the output buffer. + * + * @param outbuf Output buffer. + * @param kernbuf1 Kernel buffer 1 (linear part). + * @param kernbuf2 Kernel buffer 2 (ramp part). + * @param c Multiplier for linear kernel element. + * @param d Multiplier for ramp kernel element. + */ + + void addBandKernel( double* outbuf, const double* const kernbuf1, + const double* const kernbuf2, const double c, const double d ) const + { + int ks; + + for( ks = 0; ks < z; ks++ ) + { + outbuf[ ks ] += c * kernbuf1[ ks ] + d * kernbuf2[ ks ]; + } + } +}; + +/** + * @brief Low-pass filter windowed by Peaked Cosine window function. + * + * This class implements calculation of linear-phase symmetric-odd FIR + * low-pass filter windowed by the Peaked Cosine window function, for image + * processing applications. + */ + +class CDSPPeakedCosineLPF +{ +public: + int fl2; ///< Half filter's length, excluding the peak value. This value + ///< can be also used as filter's latency in samples (taps). + ///< + int FilterLen; ///< Filter's length in samples (taps). + ///< + + /** + * Constructor initalizes *this object. + * + * @param aLen2 Half-length (non-truncated) of low-pass filter, in samples + * (taps). + * @param aFreq2 Low-pass filter's corner frequency [0; pi]. + * @param aAlpha Peaked Cosine window function Alpha parameter. + */ + + CDSPPeakedCosineLPF( const double aLen2, const double aFreq2, + const double aAlpha ) + : fl2( (int) ceil( aLen2 ) - 1 ) + , FilterLen( fl2 + fl2 + 1 ) + , Len2( aLen2 ) + , Freq2( aFreq2 ) + , Alpha( aAlpha ) + { + } + + /** + * Function generates a linear-phase low-pass filter windowed by Peaked + * Cosine window function. + * + * @param[out] op Output buffer, length = FilterLen (fl2 * 2 + 1). + * @param DCGain Required gain at DC. The resulting filter will be + * normalized to achieve this DC gain. + */ + + template< class T > + void generateLPF( T* op, const double DCGain ) + { + CDSPWindowGenPeakedCosine wf( Alpha, Len2 ); + CSineGen f2( Freq2, 0.0 ); + + op += fl2; + T* op2 = op; + f2.generate(); + int t = 1; + + *op = (T) ( Freq2 * wf.generate() / AVIR_PI ); + double s = *op; + + while( t <= fl2 ) + { + const double v = f2.generate() * wf.generate() / t / AVIR_PI; + op++; + op2--; + *op = (T) v; + *op2 = (T) v; + s += *op + *op2; + t++; + } + + t = FilterLen; + s = DCGain / s; + + while( t > 0 ) + { + *op2 = (T) ( *op2 * s ); + op2++; + t--; + } + } + +private: + double Len2; ///< Half-length (non-truncated) of low-pass filter, in + ///< samples (taps). + ///< + double Freq2; ///< Low-pass filter's corner frequency. + ///< + double Alpha; ///< Peaked Cosine window function Alpha parameter. + ///< +}; + +/** + * @brief Buffer class for parametrized low-pass filter. + * + * This class extends the CBuffer< double > class by adding several variables + * that define a symmetric-odd FIR low-pass filter windowed by Peaked Cosine + * window function. This class can be used to compare filters without + * comparing their buffer contents. + */ + +class CFltBuffer : public CBuffer< double > +{ +public: + double Len2; ///< Half-length (non-truncated) of low-pass filters, in + ///< samples (taps). + ///< + double Freq; ///< Low-pass filter's corner frequency. + ///< + double Alpha; ///< Peaked Cosine window function Alpha parameter. + ///< + double DCGain; ///< DC gain applied to the filter. + ///< + + CFltBuffer() + : CBuffer< double >() + , Len2( 0.0 ) + , Freq( 0.0 ) + , Alpha( 0.0 ) + , DCGain( 0.0 ) + { + } + + /** + * @param b2 Filter buffer to compare *this object to. + * @return Operator returns "true" if both filters have same parameters. + */ + + bool operator == ( const CFltBuffer& b2 ) const + { + return( Len2 == b2.Len2 && Freq == b2.Freq && Alpha == b2.Alpha && + DCGain == b2.DCGain ); + } +}; + +/** + * @brief Sinc function-based fractional delay filter bank. + * + * Class implements storage and initialization of a bank of sinc + * function-based fractional delay filters, expressed as 1st order polynomial + * interpolation coefficients. The filters are produced from a single "long" + * windowed low-pass filter. Also supports 0th-order ("nearest neighbor") + * interpolation. + * + * This class also supports multiplication of each fractional delay filter by + * an external filter (usually a low-pass filter). + * + * @tparam fptype Specifies storage type of the filter coefficients bank. The + * filters are initially calculated using the "double" precision. + */ + +template< class fptype > +class CDSPFracFilterBankLin +{ +public: + CDSPFracFilterBankLin() + : Order( -1 ) + { + } + + /** + * Copy constructor copies a limited set of parameters of the source + * filter bank. The actual filters are not copied. Such copying is used + * during filtering steps "modeling" stage. A further init() function + * call is required. + * + * @param s Source filter bank. + */ + + void copyInitParams( const CDSPFracFilterBankLin& s ) + { + WFLen2 = s.WFLen2; + WFFreq = s.WFFreq; + WFAlpha = s.WFAlpha; + FracCount = s.FracCount; + Order = s.Order; + Alignment = s.Alignment; + SrcFilterLen = s.SrcFilterLen; + FilterLen = s.FilterLen; + FilterSize = s.FilterSize; + IsSrcTableBuilt = false; + ExtFilter = s.ExtFilter; + TableFillFlags.alloc( s.TableFillFlags.getCapacity() ); + int i; + + // Copy table fill flags, but shifted so that further initialization + // is still possible (such feature should not be used, though). + + for( i = 0; i < TableFillFlags.getCapacity(); i++ ) + { + TableFillFlags[ i ] = (uint8_t) ( s.TableFillFlags[ i ] << 2 ); + } + } + + /** + * Operator compares *this filter bank and another filter bank and returns + * "true" if their parameters are equal. Alignment is not taken into + * account. + * + * @param s Filter bank to compare to. + * @return "True" if compared banks have equal parameters. + */ + + bool operator == ( const CDSPFracFilterBankLin& s ) const + { + return( Order == s.Order && WFLen2 == s.WFLen2 && + WFFreq == s.WFFreq && WFAlpha == s.WFAlpha && + FracCount == s.FracCount && ExtFilter == s.ExtFilter ); + } + + /** + * Function initializes (builds) the filter bank based on the supplied + * parameters. If the supplied parameters are equal to previously defined + * parameters, function does nothing (alignment is assumed to be never + * changing between the init() function calls). + * + * @param ReqFracCount Required number of fractional delays in the filter + * bank. The minimal value is 2. + * @param ReqOrder Required order of the interpolation polynomial + * (0 or 1). + * @param BaseLen Low-pass filter's base length, in samples (taps). + * Affects the actual length of the filter and its overall steepness. + * @param Cutoff Low-pass filter's normalized cutoff frequency [0; 1]. + * @param aWFAlpha Peaked Cosine window function's Alpha parameter. + * @param aExtFilter External filter to apply to each fractional delay + * filter. + * @param aAlignment Memory alignment of the filter bank, power-of-2 + * value. 0 - use default stdlib alignment. + * @param FltLenAlign Filter's length alignment, power-of-2 value. + */ + + void init( const int ReqFracCount, const int ReqOrder, + const double BaseLen, const double Cutoff, const double aWFAlpha, + const CFltBuffer& aExtFilter, const int aAlignment = 0, + const int FltLenAlign = 1 ) + { + double NewWFLen2 = 0.5 * BaseLen * ReqFracCount; + double NewWFFreq = AVIR_PI * Cutoff / ReqFracCount; + double NewWFAlpha = aWFAlpha; + + if( ReqOrder == Order && NewWFLen2 == WFLen2 && NewWFFreq == WFFreq && + NewWFAlpha == WFAlpha && ReqFracCount == FracCount && + aExtFilter == ExtFilter ) + { + IsInitRequired = false; + return; + } + + WFLen2 = NewWFLen2; + WFFreq = NewWFFreq; + WFAlpha = NewWFAlpha; + FracCount = ReqFracCount; + Order = ReqOrder; + Alignment = aAlignment; + ExtFilter = aExtFilter; + + CDSPPeakedCosineLPF p( WFLen2, WFFreq, WFAlpha ); + SrcFilterLen = ( p.fl2 / ReqFracCount + 1 ) * 2; + + const int ElementSize = ReqOrder + 1; + FilterLen = SrcFilterLen; + + if( ExtFilter.getCapacity() > 0 ) + { + FilterLen += ExtFilter.getCapacity() - 1; + } + + FilterLen = ( FilterLen + FltLenAlign - 1 ) & ~( FltLenAlign - 1 ); + FilterSize = FilterLen * ElementSize; + IsSrcTableBuilt = false; + IsInitRequired = true; + } + + /** + * @return The length of each fractional delay filter, in samples (taps). + * Always an even value. + */ + + int getFilterLen() const + { + return( FilterLen ); + } + + /** + * @return The number of fractional filters in use by *this bank. + */ + + int getFracCount() const + { + return( FracCount ); + } + + /** + * @return The order of the interpolation polynomial. + */ + + int getOrder() const + { + return( Order ); + } + + /** + * Function returns the pointer to the specified interpolation table + * filter. + * + * @param i Filter (fractional delay) index, in the range 0 to + * ReqFracCount - 1, inclusive. + * @return Pointer to filter. Higher order polynomial coefficients are + * stored after after previous order coefficients, separated by FilterLen + * elements. + */ + + const fptype* getFilter( const int i ) + { + if( !IsSrcTableBuilt ) + { + buildSrcTable(); + } + + fptype* const Res = &Table[ i * FilterSize ]; + + if(( TableFillFlags[ i ] & 2 ) == 0 ) + { + createFilter( i ); + TableFillFlags[ i ] |= 2; + + if( Order > 0 ) + { + createFilter( i + 1 ); + const fptype* const Res2 = Res + FilterSize; + fptype* const op = Res + FilterLen; + int j; + + // Create higher-order interpolation coefficients (linear + // interpolation). + + for( j = 0; j < FilterLen; j++ ) + { + op[ j ] = Res2[ j ] - Res[ j ]; + } + } + } + + return( Res ); + } + + /** + * Function makes sure all fractional delay filters were created. + */ + + void createAllFilters() + { + int i; + + for( i = 0; i < FracCount; i++ ) + { + getFilter( i ); + } + } + + /** + * Function returns an approximate initialization complexity, expressed in + * the number of multiply-add operations. This includes fractional delay + * filters calculation and multiplication by an external filter. This + * function can only be called after the init() function. + * + * @param FracUseMap Fractional delays use map, each element corresponds + * to a single fractional delay, will be compared to the internal table + * fill flags. This map should include 0 and 1 values only. + * @return The complexity of the initialization, expressed in the number + * of multiply-add operations. + */ + + int calcInitComplexity( const CBuffer< uint8_t >& FracUseMap ) const + { + const int FltInitCost = 65; // Cost to initialize a single sample + // of the fractional delay filter. + const int FltUseCost = FilterLen * Order + + SrcFilterLen * ExtFilter.getCapacity(); // Cost to use a single + // fractional delay filter. + const int ucb[ 2 ] = { 0, FltUseCost }; + int ic; + int i; + + if( IsInitRequired ) + { + ic = FracCount * SrcFilterLen * FltInitCost; + + for( i = 0; i < FracCount; i++ ) + { + ic += ucb[ FracUseMap[ i ]]; + } + } + else + { + ic = 0; + + for( i = 0; i < FracCount; i++ ) + { + if( FracUseMap[ i ] != 0 ) + { + ic += ucb[ TableFillFlags[ i ] == 0 ? 1 : 0 ]; + } + } + } + + return( ic ); + } + +private: + static const int InterpPoints = 2; ///< The maximal number of points the + ///< interpolation is based on. + ///< + double WFLen2; ///< Window function's Len2 parameter. + ///< + double WFFreq; ///< Window function's Freq parameter. + ///< + double WFAlpha; ///< Window function's Alpha parameter. + ///< + int FracCount; ///< The required number of fractional delay filters. + ///< + int Order; ///< The order of the interpolation polynomial. + ///< + int Alignment; ///< The required filter table alignment. + ///< + int SrcFilterLen; ///< Length of the "source" filters. This is always an + ///< even value. + ///< + int FilterLen; ///< Specifies the number of samples (taps) each fractional + ///< delay filter has. This is always an even value, adjusted by the + ///< FltLenAlign. + ///< + int FilterSize; ///< The size of a single filter element, equals + ///< FilterLen * ElementSize. + ///< + bool IsInitRequired; ///< "True" if SrcTable filter table initialization + ///< is required. This value is available only after the call to the + ///< init() function. + ///< + CBuffer< fptype > Table; ///< Interpolation table, size equals to + ///< ReqFracCount * FilterLen * ElementSize. + ///< + CBuffer< uint8_t > TableFillFlags; ///< Contains ReqFracCount + 1 + ///< elements. Bit 0 of every element is 1 if Table already contains + ///< the filter from SrcTable filtered by ExtFilter. Bit 1 of every + ///< element means higher order coefficients were filled for the + ///< filter. + ///< + CFltBuffer ExtFilter; ///< External filter that should be applied to every + ///< fractional delay filter. Can be empty. Half of this filter's + ///< capacity is used as latency (group delay) value of the filter. + ///< + CBuffer< double > SrcTable; ///< Source table of delay filters, contains + ///< ReqFracCount + 1 elements. This table is used to fill the Table + ///< with the actual filters, filtered by an external filter. + ///< + bool IsSrcTableBuilt; ///< "True" if the SrcTable was built already. This + ///< variable is set to "false" in the init() function. + ///< + + /** + * Function builds source table used in the createFilter() function. + */ + + void buildSrcTable() + { + IsSrcTableBuilt = true; + IsInitRequired = false; + + CDSPPeakedCosineLPF p( WFLen2, WFFreq, WFAlpha ); + + const int BufLen = SrcFilterLen * FracCount + InterpPoints - 1; + const int BufOffs = InterpPoints / 2 - 1; + const int BufCenter = SrcFilterLen * FracCount / 2 + BufOffs; + + CBuffer< double > Buf( BufLen ); + memset( Buf, 0, ( BufCenter - p.fl2 ) * sizeof( double )); + int i = BufLen - BufCenter - p.fl2 - 1; + memset( &Buf[ BufLen - i ], 0, i * sizeof( double )); + + p.generateLPF( &Buf[ BufCenter - p.fl2 ], FracCount ); asm("int3"); + + SrcTable.alloc(( FracCount + 1 ) * SrcFilterLen ); + TableFillFlags.alloc( FracCount + 1 ); + int j; + double* op0 = SrcTable; + + for( i = FracCount; i >= 0; i-- ) + { + TableFillFlags[ i ] = 0; + double* p = Buf + BufOffs + i; + + for( j = 0; j < SrcFilterLen; j++ ) + { + op0[ 0 ] = p[ 0 ]; + op0++; + p += FracCount; + } + } + + Table.alloc(( FracCount + 1 ) * FilterSize, Alignment ); + } + + /** + * Function creates the specified filter in the Table by copying it from + * the SrcTable and filtering by ExtFilter. Function does nothing if + * filter was already created. + * + * @param k Filter index to create, in the range 0 to FracCount, + * inclusive. + */ + + void createFilter( const int k ) + { + if( TableFillFlags[ k ] != 0 ) + { + return; + } + + TableFillFlags[ k ] |= 1; + const int ExtFilterLatency = ExtFilter.getCapacity() / 2; + const int ResLatency = ExtFilterLatency + SrcFilterLen / 2; + int ResLen = SrcFilterLen; + + if( ExtFilter.getCapacity() > 0 ) + { + ResLen += ExtFilter.getCapacity() - 1; + } + + const int ResOffs = FilterLen / 2 - ResLatency; + fptype* op = &Table[ k * FilterSize ]; + int i; + + for( i = 0; i < ResOffs; i++ ) + { + op[ i ] = 0.0; + } + + for( i = ResOffs + ResLen; i < FilterLen; i++ ) + { + op[ i ] = 0.0; + } + + op += ResOffs; + const double* const srcflt = &SrcTable[ k * SrcFilterLen ]; + + if( ExtFilter.getCapacity() == 0 ) + { + for( i = 0; i < ResLen; i++ ) + { + op[ i ] = (fptype) srcflt[ i ]; + } + + return; + } + + // Perform convolution of extflt and srcflt. + + const double* const extflt = &ExtFilter[ 0 ]; + int j; + + for( j = 0; j < ResLen; j++ ) + { + int k = 0; + int l = j - ExtFilter.getCapacity() + 1; + int r = l + ExtFilter.getCapacity(); + + if( l < 0 ) + { + k -= l; + l = 0; + } + + if( r > SrcFilterLen ) + { + r = SrcFilterLen; + } + + const double* const extfltb = extflt + k; + const double* const srcfltb = srcflt + l; + double s = 0.0; + l = r - l; + + for( i = 0; i < l; i++ ) + { + s += extfltb[ i ] * srcfltb[ i ]; + } + + op[ j ] = (fptype) s; + } + } +}; + +/** + * @brief Thread pool for multi-threaded image resizing operation. + * + * This base class is used to organize a multi-threaded image resizing + * operation. The thread pool should consist of threads that initially wait + * for a signal. Upon receiving a signal (via the startAllWorkloads() + * function) each previously added thread should execute its workload's + * process() function once, and return to the wait signal state again. The + * thread pool should be also able to efficiently wait for all workloads to + * finish via the waitAllWorkloadsToFinish() function. + * + * The image resizing algorithm makes calls to functions of this class. + */ + +class CImageResizerThreadPool +{ +public: + CImageResizerThreadPool() + { + } + + virtual ~CImageResizerThreadPool() + { + } + + /** + * @brief Thread pool's workload object class. + * + * This class should be used as a base class for objects that perform the + * actual work spread over several threads. + */ + + class CWorkload + { + public: + virtual ~CWorkload() + { + } + + /** + * Function that gets called from the thread when thread pool's + * startAllWorkloads() function is called. + */ + + virtual void process() = 0; + }; + + /** + * @return The suggested number of workloads (and their associated + * threads) to add. The minimal value this function can return is 1. The + * usual value may depend on the number of physical and virtual cores + * present in the system, and on other considerations. + */ + + virtual int getSuggestedWorkloadCount() const + { + return( 1 ); + } + + /** + * Function adds a new workload (and possibly thread) to the thread pool. + * The caller decides how many parallel workloads (and threads) it + * requires, but this number will not exceed the value returned by the + * getSuggestedWorkloadCount() function. It is implementation-specific how + * many workloads to associate with a single thread. But for efficiency + * reasons each workload should be associated with its own thread. + * + * Note that the same set of workload objects will be processed each time + * the startAllWorkloads() function is called. This means that workload + * objects are added only once. The caller changes the state of the + * workload objects and then calls the startAllWorkloads() function to + * process them. + * + * @param Workload Workload object whose process() function will be called + * from within the thread when the startAllWorkloads() function is called. + */ + + virtual void addWorkload( CWorkload* const Workload ) + { + } + + /** + * Function starts all workloads associated with threads previously added + * via the addWorkload() function. It is assumed that this function + * performs the necessary "memory barrier" (or "cache sync") kind of + * operation so that all threads catch up the prior changes made to the + * workload objects during their wait state. + */ + + virtual void startAllWorkloads() + { + } + + /** + * Function waits for all workloads to finish. + */ + + virtual void waitAllWorkloadsToFinish() + { + } + + /** + * Function removes all workloads previously added via the addWorkload() + * function. This function gets called only after the + * waitAllWorkloadsToFinish() function call. + */ + + virtual void removeAllWorkloads() + { + } +}; + +/** + * @brief Resizing algorithm parameters structure. + * + * This structure holds all selectable parameters used by the resizing + * algorithm at various stages, for both downsizing and upsizing. There are no + * other parameters exist that can optimize the performance of the resizing + * algorithm. Filter length parameters can take fractional values. + * + * Beside quality, these parameters (except Alpha parameters) directly affect + * the computative cost of the resizing algorithm. It is possible to trade + * the visual quality for computative cost. + * + * Anti-alias filtering during downsizing can be defined as a considerable + * reduction of contrast of smallest features of an image. Unfortunately, such + * de-contrasting partially affects features of all sizes thus producing a + * non-linearity of frequency response. All pre-defined parameter sets are + * described by 3 values separated by slashes. The first value is the + * de-contrasting factor of small features (which are being removed) while + * the second value is the de-contrasting factor of large features (which + * should remain intact), with value of 1 equating to "no contrast change". + * The third value is the optimization score (see below), with value of 0 + * equating to the "perfect" linearity of frequency response. + * + * The pre-defined parameter sets offered by this library were auto-optimized + * for the given LPFltBaseLen, IntFltLen and CorrFltAlpha values. The + * optimization goal was to minimize the score: the sum of squares of the + * difference between original and processed images (which was not actually + * resized, k=1). The original image was a 0.5 megapixel uniformly-distributed + * white-noise image with pixel intensities in the 0-1 range. Such goal + * converges very well and produces filtering system with the flattest + * frequency response possible for the given constraints. With this goal, + * increasing the LPFltBaseLen value reduces the general amount of aliasing + * artifacts. + */ + +struct CImageResizerParams +{ + double CorrFltAlpha; ///< Alpha parameter of the Peaked Cosine window + ///< function used on the correction filter. The "usable" values are + ///< in the narrow range 1.0 to 1.5. + ///< + double CorrFltLen; ///< Correction filter's length in samples (taps). The + ///< "usable" range is narrow, 5.5 to 8, as to minimize the + ///< "overcorrection" which is mathematically precise, but visually + ///< unacceptable. + ///< + double IntFltAlpha; ///< Alpha parameter of the Peaked Cosine window + ///< function used on the interpolation low-pass filter. The "usable" + ///< values are in the range 1.5 to 2.5. + ///< + double IntFltCutoff; ///< Interpolation low-pass filter's cutoff frequency + ///< (normalized, [0; 1]). The "usable" range is 0.6 to 0.8. + ///< + double IntFltLen; ///< Interpolation low-pass filter's length in samples + ///< (taps). The length value should be at least 18 or otherwise a + ///< "dark grid" artifact will be introduced if a further sharpening + ///< is applied. IntFltLen together with other IntFlt parameters + ///< should be tuned in a way that produces the flattest frequency + ///< response in 0-0.5 normalized frequency range (this range is due + ///< to 2X upsampling). + ///< + double LPFltAlpha; ///< Alpha parameter of the Peaked Cosine window + ///< function used on the low-pass filter. The "usable" values are + ///< in the range 1.5 to 6.5. + ///< + double LPFltBaseLen; ///< Base length of the low-pass (aka anti-aliasing + ///< or reconstruction) filter, in samples (taps), further adjusted by + ///< the actual cutoff frequency, upsampling and downsampling factors. + ///< The "usable" range is between 6 and 9. + ///< + double LPFltCutoffMult; ///< Low-pass filter's cutoff frequency + ///< multiplier. This value can be both below and above 1.0 as + ///< low-pass filters are inserted on downsampling and upsampling + ///< steps and always have corner frequency equal to or below 0.5pi. + ///< This multiplier shifts low-pass filter's corner frequency towards + ///< lower (if below 1.0) or higher (if above 1.0) frequencies. This + ///< multiplier can be way below 1.0 since any additional + ///< high-frequency damping will be partially corrected by the + ///< correction filter. The "usable" range is 0.3 to 1.0. + ///< + + CImageResizerParams() + : HBFltAlpha( 1.75395 ) + , HBFltCutoff( 0.40356 ) + , HBFltLen( 22.00000 ) + { + } + + double HBFltAlpha; ///< Half-band filter's Alpha. Assigned internally. + ///< + double HBFltCutoff; ///< Half-band filter's cutoff point [0; 1]. Assigned + ///< internally. + ///< + double HBFltLen; ///< Length of the half-band low-pass filter. Assigned + ///< internally. Internally used to perform 2X or higher downsampling. + ///< These filter parameters should be treated as "technical" and do + ///< not require adjustment as they were tuned to suit all + ///< combinations of other parameters. This half-band filter provides + ///< a wide transition band (for minimal ringing artifacts) and a high + ///< stop-band attenuation (for minimal aliasing). + ///< +}; + +/** + * @brief The default set of resizing algorithm parameters + * (10.01/1.029/0.019169). + * + * This is the default set of resizing parameters that was designed to deliver + * a sharp image while still providing a low amount of ringing artifacts, and + * having a reasonable computational cost. + */ + +struct CImageResizerParamsDef : public CImageResizerParams +{ + CImageResizerParamsDef() + { + CorrFltAlpha = 1.0;//10.01/1.88/1.029(522.43)/0.019169:258648,446808 + CorrFltLen = 6.30770; + IntFltAlpha = 2.27825; + IntFltCutoff = 0.75493; + IntFltLen = 18.0; + LPFltAlpha = 3.40127; + LPFltBaseLen = 7.78; + LPFltCutoffMult = 0.78797; + } +}; + +/** + * @brief Set of resizing algorithm parameters for ultra-low-ringing + * performance (7.69/1.069/0.000245). + * + * This set of resizing algorithm parameters offers the lowest amount of + * ringing this library is capable of providing while still offering a decent + * quality. Low ringing is attained at the expense of higher aliasing + * artifacts and a slightly reduced contrast. + */ + +struct CImageResizerParamsULR : public CImageResizerParams +{ + CImageResizerParamsULR() + { + CorrFltAlpha = 1.0;//7.69/1.97/1.069(31445.45)/0.000245:258627,436845 + CorrFltLen = 5.83280; + IntFltAlpha = 2.11453; + IntFltCutoff = 0.73986; + IntFltLen = 18.0; + LPFltAlpha = 1.73455; + LPFltBaseLen = 6.40; + LPFltCutoffMult = 0.61314; + } +}; + +/** + * @brief Set of resizing algorithm parameters for low-ringing performance + * (7.86/1.065/0.000106). + * + * This set of resizing algorithm parameters offers a very low-ringing + * performance at the expense of higher aliasing artifacts and a slightly + * reduced contrast. + */ + +struct CImageResizerParamsLR : public CImageResizerParams +{ + CImageResizerParamsLR() + { + CorrFltAlpha = 1.0;//7.86/1.96/1.065(73865.02)/0.000106:258636,437381 + CorrFltLen = 5.87671; + IntFltAlpha = 2.25322; + IntFltCutoff = 0.74090; + IntFltLen = 18.0; + LPFltAlpha = 1.79306; + LPFltBaseLen = 7.00; + LPFltCutoffMult = 0.68881; + } +}; + +/** + * @brief Set of resizing algorithm parameters for lower-ringing performance + * (8.86/1.046/0.010168). + * + * This set of resizing algorithm parameters offers a lower-ringing + * performance in comparison to the default setting, at the expense of higher + * aliasing artifacts and a slightly reduced contrast. + */ + +struct CImageResizerParamsLow : public CImageResizerParams +{ + CImageResizerParamsLow() + { + CorrFltAlpha = 1.0;//8.86/1.92/1.046(871.54)/0.010168:258647,442252 + CorrFltLen = 6.09757; + IntFltAlpha = 2.36704; + IntFltCutoff = 0.74674; + IntFltLen = 18.0; + LPFltAlpha = 2.19427; + LPFltBaseLen = 7.66; + LPFltCutoffMult = 0.75380; + } +}; + +/** + * @brief Set of resizing algorithm parameters for low-aliasing + * resizing (11.81/1.012/0.038379). + * + * This set of resizing algorithm parameters offers a considerable + * anti-aliasing performance with a good frequency response linearity (and + * contrast). This is an intermediate setting between the default and Ultra + * parameters. + */ + +struct CImageResizerParamsHigh : public CImageResizerParams +{ + CImageResizerParamsHigh() + { + CorrFltAlpha = 1.0;//11.81/1.83/1.012(307.84)/0.038379:258660,452719 + CorrFltLen = 6.80909; + IntFltAlpha = 2.44917; + IntFltCutoff = 0.75856; + IntFltLen = 18.0; + LPFltAlpha = 4.39527; + LPFltBaseLen = 8.18; + LPFltCutoffMult = 0.79172; + } +}; + +/** + * @brief Set of resizing algorithm parameters for ultra low-aliasing + * resizing (13.65/1.001/0.000483). + * + * This set of resizing algorithm parameters offers a very considerable + * anti-aliasing performance with a good frequency response linearity (and + * contrast). This set of parameters is computationally expensive and may + * produce ringing artifacts on sharp features. + */ + +struct CImageResizerParamsUltra : public CImageResizerParams +{ + CImageResizerParamsUltra() + { + CorrFltAlpha = 1.0;//13.65/1.79/1.001(28288.41)/0.000483:258658,457974 + CorrFltLen = 7.48060; + IntFltAlpha = 1.93750; + IntFltCutoff = 0.75462; + IntFltLen = 18.0; + LPFltAlpha = 5.55209; + LPFltBaseLen = 8.34; + LPFltCutoffMult = 0.78002; + } +}; + +/** + * @brief Image resizing variables class. + * + * This is an utility "catch all" class that defines various variables used + * during image resizing. Several variables that are explicitly initialized in + * this class' constructor are also used as additional "input" variables to + * the image resizing function. These variables will not be changed by the + * avir::CImageResizer<>::resizeImage() function. + */ + +class CImageResizerVars +{ +public: + int ElCount; ///< The number of "fptype" elements used to store 1 pixel. + ///< + int ElCountIO; ///< The number of source and destination image's elements + ///< used to store 1 pixel. + ///< + int fppack; ///< The number of atomic types stored in a single "fptype" + ///< element. + ///< + int fpalign; ///< Suggested alignment size in bytes. This is not a + ///< required alignment, because image resizing algorithm cannot be + ///< made to have a strictly aligned data access in all cases (e.g. + ///< de-interleaved interpolation cannot perform aligned accesses). + ///< + int elalign; ///< Length alignment of arrays of elements. This applies to + ///< filters and intermediate buffers: this constant forces filters + ///< and scanlines to have a length which is a multiple of this value, + ///< for more efficient SIMD implementation. + ///< + int packmode; ///< 0 if interleaved packing, 1 if de-interleaved. + ///< + int BufLen[ 2 ]; ///< Intermediate buffers' lengths in "fptype" elements. + int BufOffs[ 2 ]; ///< Offsets into the intermediate buffers, used to + ///< provide prefix elements required during processing so that no + ///< "out of range" access happens. This offset is a multiple of + ///< ElCount if pixels are stored in interleaved form. + ///< + double k; ///< Resizing step coefficient, updated to reflect the actually + ///< used coefficient during resizing. + ///< + double o; ///< Starting pixel offset inside the source image, updated to + ///< reflect the actually used offset during resizing. + ///< + int ResizeStep; ///< Index of the resizing step in the latest filtering + ///< steps array. + ///< + double InGammaMult; ///< Input gamma multiplier, used to convert input + ///< data to 0 to 1 range. 0.0 if no gamma is in use. + ///< + double OutGammaMult; ///< Output gamma multiplier, used to convert data to + ///< 0 to 255/65535 range. 0.0 if no gamma is in use. + ///< + + double ox; ///< Start X pixel offset within source image (can be + ///< negative). Positive offset moves image to the left. + ///< + double oy; ///< Start Y pixel offset within source image (can be + ///< negative). Positive offset moves image to the top. + ///< + CImageResizerThreadPool* ThreadPool; ///< Thread pool to be used by the + ///< image resizing function. Set to NULL to use single-threaded + ///< processing. + ///< + bool UseSRGBGamma; ///< Perform sRGB gamma linearization (correction). + ///< + int BuildMode; ///< The build mode to use, for debugging purposes. Set to + ///< -1 to select a minimal-complexity mode automatically. All build + ///< modes deliver similar results with minor deviations. + ///< + int RndSeed; ///< Random seed parameter. This parameter may be incremented + ///< after each random generator initialization. The use of this + ///< variable depends on the ditherer implementation. + ///< + + CImageResizerVars() + : ox( 0.0 ) + , oy( 0.0 ) + , ThreadPool( NULL ) + , UseSRGBGamma( false ) + , BuildMode( -1 ) + , RndSeed( 0 ) + { + } +}; + +/** + * @brief Image resizer's filtering step class. + * + * Class defines data to perform a single filtering step over a whole + * horizontal or vertical scanline. Resizing consists of 1 or more steps that + * may be performed before the actual resizing takes place. Filtering may also + * follow a resizing step. Each step must ensure that scanline data contains + * enough pixels to perform the next step (which may be resizing) without + * exceeding scanline's bounds. + * + * A derived class must implement several "const" and "static" functions that + * are used to perform the actual filtering in interleaved or de-interleaved + * mode. + * + * @tparam fptype Floating point type to use for storing pixel elements. SIMD + * types can be used: in this case each element may hold a whole pixel. + * @tparam fptypeatom The atomic type the "fptype" consists of. + */ + +template< class fptype, class fptypeatom > +class CImageResizerFilterStep +{ +public: + bool IsUpsample; ///< "True" if this step is an upsampling step, "false" + ///< if downsampling step. Should be set to "false" if ResampleFactor + ///< equals 0. + ///< + int ResampleFactor; ///< Resample factor (>=1). If 0, this is a resizing + ///< step. This value should be >1 if IsUpsample equals "true". + ///< + CBuffer< fptype > Flt; ///< Filter to use at this step. + ///< + CFltBuffer FltOrig; ///< Originally-designed filter. This buffer may not + ///< be assigned. Assigned by filters that precede the resizing step + ///< if such filter is planned to be embedded into the interpolation + ///< filter as "external" filter. If IsUpsample=true and this filter + ///< buffer is not empty, the upsampling step will not itself apply + ///< any filtering over upsampled input scanline. + ///< + double DCGain; ///< DC gain which was applied to the filter. Not defined + ///< if ResampleFactor = 0. + ///< + int FltLatency; ///< Filter's latency (group delay, shift) in pixels. + ///< + const CImageResizerVars* Vars; ///< Image resizing-related variables. + ///< + int InLen; ///< Input scanline's length in pixels. + ///< + int InBuf; ///< Input buffer index, 0 or 1. + ///< + int InPrefix; ///< Required input prefix pixels. These prefix pixels will + ///< be filled with source scanline's first pixel value. If IsUpsample + ///< is "true", this is the additional number of times the first pixel + ///< will be filtered before processing scanline, this number is also + ///< reflected in the OutPrefix. + ///< + int InSuffix; ///< Required input suffix pixels. These suffix pixels will + ///< be filled with source scanline's last pixel value. If IsUpsample + ///< is "true", this is the additional number of times the last pixel + ///< will be filtered before processing scanline, this number is also + ///< reflected in the OutSuffix. + ///< + int InElIncr; ///< Pixel element increment within the input buffer, used + ///< during de-interleaved processing: in this case each image's + ///< channel is stored independently, InElIncr elements apart. + ///< + int OutLen; ///< Length of the resulting scanline. + ///< + int OutBuf; ///< Output buffer index. 0 or 1; 2 for the last step. + ///< + int OutPrefix; ///< Required output prefix pixels. These prefix pixels + ///< will not be pre-filled with any values. Value is valid only if + ///< IsUpsample equals "true". + ///< + int OutSuffix; ///< Required input suffix pixels. These suffix pixels will + ///< not be pre-filled with any values. Value is valid only if + ///< IsUpsample equals "true". + ///< + int OutElIncr; ///< Pixel element increment within the output buffer, used + ///< during de-interleaved processing. Equals to the InBufElIncr of + ///< the next step. + ///< + CBuffer< fptype > PrefixDC; ///< DC component fluctuations added at the + ///< start of the resulting scanline, used when IsUpsample equals + ///< "true". + ///< + CBuffer< fptype > SuffixDC; ///< DC component fluctuations added at the + ///< end of the resulting scanline, used when IsUpsample equals + ///< "true". + ///< + int EdgePixelCount; ///< The number of edge pixels added. Affects the + ///< initial position within the input scanline, used to produce edge + ///< pixels. This variable is used and should be defined when + ///< IsUpsample=false and ResampleFactor>0. When assigning this + ///< variable it is also necessary to update InPrefix, OutLen and + ///< Vars.o variables. + ///< + static const int EdgePixelCountDef = 3; ///< The default number of pixels + ///< additionally produced at scanline edges during filtering. This is + ///< required to reduce edge artifacts. + ///< + + /** + * @brief Resizing position structure. + * + * Structure holds resizing position and pointer to fractional delay + * filter. + */ + + struct CResizePos + { + int SrcPosInt; ///< Source scanline position. + ///< + int fti; ///< Fractional delay filter index. + ///< + const fptype* ftp; ///< Fractional delay filter pointer. + ///< + fptypeatom x; ///< Interpolation coefficient between delay filters. + ///< + int SrcOffs; ///< Source scanline offset. + ///< + }; + + /** + * @brief Resizing positions buffer class. + * + * This class combines buffer together with variables that define resizing + * stepping. + */ + + class CRPosBuf : public CBuffer< CResizePos > + { + public: + double k; ///< Resizing step. + ///< + double o; ///< Resizing offset. + ///< + int FracCount; ///< The number of fractional delay filters in a filter + ///< bank used together with this buffer. + ///< + }; + + /** + * @brief Resizing positions buffer array class. + * + * This class combines structure array of the CRPosBuf class objects with + * the function that locates or creates buffer with the required resizing + * stepping. + */ + + class CRPosBufArray : public CStructArray< CRPosBuf > + { + public: + using CStructArray< CRPosBuf > :: add; + using CStructArray< CRPosBuf > :: getItemCount; + + /** + * Function returns the resizing positions buffer with the required + * stepping. If no such buffer exists, it is created. + * + * @param k Resizing step. + * @param o Resizing offset. + * @param FracCount The number of fractional delay filters in a filter + * bank used together with this buffer. + * @return Reference to the CRPosBuf object. + */ + + CRPosBuf& getRPosBuf( const double k, const double o, + const int FracCount ) + { + int i; + + for( i = 0; i < getItemCount(); i++ ) + { + CRPosBuf& Buf = (*this)[ i ]; + + if( Buf.k == k && Buf.o == o && Buf.FracCount == FracCount ) + { + return( Buf ); + } + } + + CRPosBuf& NewBuf = add(); + NewBuf.k = k; + NewBuf.o = o; + NewBuf.FracCount = FracCount; + + return( NewBuf ); + } + }; + + CRPosBuf* RPosBuf; ///< Resizing positions buffer. Used when + ///< ResampleFactor equals 0 (resizing step). + ///< + CDSPFracFilterBankLin< fptype >* FltBank; ///< Filter bank in use by *this + ///< resizing step. + ///< +}; + +/** + * @brief Interleaved filtering steps implementation class. + * + * This class implements scanline filtering functions in interleaved mode. + * This means that each pixel is processed independently, not in groups. + * + * @tparam fptype Floating point type to use for storing pixel elements. SIMD + * types can be used: in this case each element may hold a whole pixel. + * @tparam fptypeatom The atomic type the "fptype" consists of. + */ + +template< class fptype, class fptypeatom > +class CImageResizerFilterStepINL : + public CImageResizerFilterStep< fptype, fptypeatom > +{ +public: + using CImageResizerFilterStep< fptype, fptypeatom > :: IsUpsample; + using CImageResizerFilterStep< fptype, fptypeatom > :: ResampleFactor; + using CImageResizerFilterStep< fptype, fptypeatom > :: Flt; + using CImageResizerFilterStep< fptype, fptypeatom > :: FltOrig; + using CImageResizerFilterStep< fptype, fptypeatom > :: FltLatency; + using CImageResizerFilterStep< fptype, fptypeatom > :: Vars; + using CImageResizerFilterStep< fptype, fptypeatom > :: InLen; + using CImageResizerFilterStep< fptype, fptypeatom > :: InPrefix; + using CImageResizerFilterStep< fptype, fptypeatom > :: InSuffix; + using CImageResizerFilterStep< fptype, fptypeatom > :: OutLen; + using CImageResizerFilterStep< fptype, fptypeatom > :: OutPrefix; + using CImageResizerFilterStep< fptype, fptypeatom > :: OutSuffix; + using CImageResizerFilterStep< fptype, fptypeatom > :: PrefixDC; + using CImageResizerFilterStep< fptype, fptypeatom > :: SuffixDC; + using CImageResizerFilterStep< fptype, fptypeatom > :: RPosBuf; + using CImageResizerFilterStep< fptype, fptypeatom > :: FltBank; + using CImageResizerFilterStep< fptype, fptypeatom > :: EdgePixelCount; + + /** + * Function performs "packing" of a scanline and type conversion. + * Scanline, depending on the "fptype" can be potentially stored as a + * packed SIMD values having a certain atomic type. If required, the sRGB + * gamma correction is applied. + * + * @param ip Input scanline. + * @param op0 Output scanline. + * @param l0 The number of pixels to "pack". + */ + + template< class Tin > + void packScanline( const Tin* ip, fptype* const op0, const int l0 ) const + { + const int ElCount = Vars -> ElCount; + const int ElCountIO = Vars -> ElCountIO; + fptype* op = op0; + int l = l0; + + if( !Vars -> UseSRGBGamma ) + { + if( ElCountIO == 1 ) + { + while( l > 0 ) + { + fptypeatom* v = (fptypeatom*) op; + v[ 0 ] = (fptypeatom) ip[ 0 ]; + op += ElCount; + ip++; + l--; + } + } + else + if( ElCountIO == 4 ) + { + while( l > 0 ) + { + fptypeatom* v = (fptypeatom*) op; + v[ 0 ] = (fptypeatom) ip[ 0 ]; + v[ 1 ] = (fptypeatom) ip[ 1 ]; + v[ 2 ] = (fptypeatom) ip[ 2 ]; + v[ 3 ] = (fptypeatom) ip[ 3 ]; + op += ElCount; + ip += 4; + l--; + } + } + else + if( ElCountIO == 3 ) + { + while( l > 0 ) + { + fptypeatom* v = (fptypeatom*) op; + v[ 0 ] = (fptypeatom) ip[ 0 ]; + v[ 1 ] = (fptypeatom) ip[ 1 ]; + v[ 2 ] = (fptypeatom) ip[ 2 ]; + op += ElCount; + ip += 3; + l--; + } + } + else + if( ElCountIO == 2 ) + { + while( l > 0 ) + { + fptypeatom* v = (fptypeatom*) op; + v[ 0 ] = (fptypeatom) ip[ 0 ]; + v[ 1 ] = (fptypeatom) ip[ 1 ]; + op += ElCount; + ip += 2; + l--; + } + } + } + else + { + const fptypeatom gm = (fptypeatom) Vars -> InGammaMult; + + if( ElCountIO == 1 ) + { + while( l > 0 ) + { + fptypeatom* v = (fptypeatom*) op; + v[ 0 ] = convertSRGB2Lin( (fptypeatom) ip[ 0 ] * gm ); + op += ElCount; + ip++; + l--; + } + } + else + if( ElCountIO == 4 ) + { + while( l > 0 ) + { + fptypeatom* v = (fptypeatom*) op; + v[ 0 ] = convertSRGB2Lin( (fptypeatom) ip[ 0 ] * gm ); + v[ 1 ] = convertSRGB2Lin( (fptypeatom) ip[ 1 ] * gm ); + v[ 2 ] = convertSRGB2Lin( (fptypeatom) ip[ 2 ] * gm ); + v[ 3 ] = convertSRGB2Lin( (fptypeatom) ip[ 3 ] * gm ); + op += ElCount; + ip += 4; + l--; + } + } + else + if( ElCountIO == 3 ) + { + while( l > 0 ) + { + fptypeatom* v = (fptypeatom*) op; + v[ 0 ] = convertSRGB2Lin( (fptypeatom) ip[ 0 ] * gm ); + v[ 1 ] = convertSRGB2Lin( (fptypeatom) ip[ 1 ] * gm ); + v[ 2 ] = convertSRGB2Lin( (fptypeatom) ip[ 2 ] * gm ); + op += ElCount; + ip += 3; + l--; + } + } + else + if( ElCountIO == 2 ) + { + while( l > 0 ) + { + fptypeatom* v = (fptypeatom*) op; + v[ 0 ] = convertSRGB2Lin( (fptypeatom) ip[ 0 ] * gm ); + v[ 1 ] = convertSRGB2Lin( (fptypeatom) ip[ 1 ] * gm ); + op += ElCount; + ip += 2; + l--; + } + } + } + + const int ZeroCount = ElCount * Vars -> fppack - ElCountIO; + op = op0; + l = l0; + + if( ZeroCount == 1 ) + { + while( l > 0 ) + { + fptypeatom* v = (fptypeatom*) op + ElCountIO; + v[ 0 ] = (fptypeatom) 0; + op += ElCount; + l--; + } + } + else + if( ZeroCount == 2 ) + { + while( l > 0 ) + { + fptypeatom* v = (fptypeatom*) op + ElCountIO; + v[ 0 ] = (fptypeatom) 0; + v[ 1 ] = (fptypeatom) 0; + op += ElCount; + l--; + } + } + else + if( ZeroCount == 3 ) + { + while( l > 0 ) + { + fptypeatom* v = (fptypeatom*) op + ElCountIO; + v[ 0 ] = (fptypeatom) 0; + v[ 1 ] = (fptypeatom) 0; + v[ 2 ] = (fptypeatom) 0; + op += ElCount; + l--; + } + } + } + + /** + * Function applies Linear to sRGB gamma correction to the specified + * scanline. + * + * @param p Scanline. + * @param l The number of pixels to de-linearize. + * @param Vars0 Image resizing-related variables. + */ + + static void applySRGBGamma( fptype* p, int l, + const CImageResizerVars& Vars0 ) + { + const int ElCount = Vars0.ElCount; + const int ElCountIO = Vars0.ElCountIO; + const fptypeatom gm = (fptypeatom) Vars0.OutGammaMult; + + if( ElCountIO == 1 ) + { + while( l > 0 ) + { + fptypeatom* v = (fptypeatom*) p; + v[ 0 ] = convertLin2SRGB( v[ 0 ]) * gm; + p += ElCount; + l--; + } + } + else + if( ElCountIO == 4 ) + { + while( l > 0 ) + { + fptypeatom* v = (fptypeatom*) p; + v[ 0 ] = convertLin2SRGB( v[ 0 ]) * gm; + v[ 1 ] = convertLin2SRGB( v[ 1 ]) * gm; + v[ 2 ] = convertLin2SRGB( v[ 2 ]) * gm; + v[ 3 ] = convertLin2SRGB( v[ 3 ]) * gm; + p += ElCount; + l--; + } + } + else + if( ElCountIO == 3 ) + { + while( l > 0 ) + { + fptypeatom* v = (fptypeatom*) p; + v[ 0 ] = convertLin2SRGB( v[ 0 ]) * gm; + v[ 1 ] = convertLin2SRGB( v[ 1 ]) * gm; + v[ 2 ] = convertLin2SRGB( v[ 2 ]) * gm; + p += ElCount; + l--; + } + } + else + if( ElCountIO == 2 ) + { + while( l > 0 ) + { + fptypeatom* v = (fptypeatom*) p; + v[ 0 ] = convertLin2SRGB( v[ 0 ]) * gm; + v[ 1 ] = convertLin2SRGB( v[ 1 ]) * gm; + p += ElCount; + l--; + } + } + } + + /** + * Function converts vertical scanline to horizontal scanline. This + * function is called by the image resizer when image is resized + * vertically. This means that the vertical scanline is stored in the + * same format produced by the packScanline() and maintained by other + * filtering functions. + * + * @param ip Input vertical scanline. + * @param op Output buffer (temporary buffer used during resizing). + * @param SrcLen The number of pixels in the input scanline, also used to + * calculate input buffer increment. + * @param SrcIncr Input buffer increment to the next vertical pixel. + */ + + void convertVtoH( const fptype* ip, fptype* op, const int SrcLen, + const int SrcIncr ) const + { + const int ElCount = Vars -> ElCount; + int j; + + if( ElCount == 1 ) + { + for( j = 0; j < SrcLen; j++ ) + { + op[ 0 ] = ip[ 0 ]; + ip += SrcIncr; + op++; + } + } + else + if( ElCount == 4 ) + { + for( j = 0; j < SrcLen; j++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op[ 2 ] = ip[ 2 ]; + op[ 3 ] = ip[ 3 ]; + ip += SrcIncr; + op += 4; + } + } + else + if( ElCount == 3 ) + { + for( j = 0; j < SrcLen; j++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op[ 2 ] = ip[ 2 ]; + ip += SrcIncr; + op += 3; + } + } + else + if( ElCount == 2 ) + { + for( j = 0; j < SrcLen; j++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + ip += SrcIncr; + op += 2; + } + } + } + + /** + * Function performs "unpacking" of a scanline and type conversion + * (truncation is used when floating point is converted to integer). + * Scanline, depending on the "fptype" can be potentially stored as a + * packed SIMD values having a certain atomic type. The unpacking function + * assumes that scanline is stored in the style produced by the + * packScanline() function. + * + * @param ip Input scanline. + * @param op Output scanline. + * @param l The number of pixels to "unpack". + * @param Vars0 Image resizing-related variables. + */ + + template< class Tout > + static void unpackScanline( const fptype* ip, Tout* op, int l, + const CImageResizerVars& Vars0 ) + { + const int ElCount = Vars0.ElCount; + const int ElCountIO = Vars0.ElCountIO; + /* dprintf(2, "BOOP ElCount=%d ElCountIO=%d l=%d op=%p\n", ElCount, ElCountIO, l, op); */ + + if( ElCountIO == 1 ) + { + while( l > 0 ) + { + const fptypeatom* v = (const fptypeatom*) ip; + op[ 0 ] = (Tout) v[ 0 ]; + ip += ElCount; + op++; + l--; + } + } + else + if( ElCountIO == 4 ) + { + while( l > 0 ) + { + const fptypeatom* v = (const fptypeatom*) ip; + op[ 0 ] = (Tout) v[ 0 ]; + op[ 1 ] = (Tout) v[ 1 ]; + op[ 2 ] = (Tout) v[ 2 ]; + op[ 3 ] = (Tout) v[ 3 ]; + ip += ElCount; + op += 4; + l--; + } + } + else + if( ElCountIO == 3 ) + { + while( l > 0 ) + { + const fptypeatom* v = (const fptypeatom*) ip; + /* DebugBreak(); */ + /* dprintf(2, "BOOP ElCount=%d ElCountIO=%d l=%d op=%p v=%p v[0]=%d\n", ElCount, ElCountIO, l, op, v, (Tout)v[0]); */ + op[ 0 ] = (Tout) v[ 0 ]; + op[ 1 ] = (Tout) v[ 1 ]; + op[ 2 ] = (Tout) v[ 2 ]; + ip += ElCount; + op += 3; + l--; + } + } + else + if( ElCountIO == 2 ) + { + while( l > 0 ) + { + const fptypeatom* v = (const fptypeatom*) ip; + op[ 0 ] = (Tout) v[ 0 ]; + op[ 1 ] = (Tout) v[ 1 ]; + ip += ElCount; + op += 2; + l--; + } + } + } + + /** + * Function prepares input scanline buffer for *this filtering step. + * Left- and right-most pixels are replicated to make sure no buffer + * overrun happens. Such approach also allows to bypass any pointer + * range checks. + * + * @param Src Source buffer. + */ + + void prepareInBuf( fptype* Src ) const + { + if( IsUpsample || InPrefix + InSuffix == 0 ) + { + return; + } + + const int ElCount = Vars -> ElCount; + replicateArray( Src, ElCount, Src - ElCount, InPrefix, -ElCount ); + + Src += ( InLen - 1 ) * ElCount; + replicateArray( Src, ElCount, Src + ElCount, InSuffix, ElCount ); + } + + /** + * Function peforms scanline upsampling with filtering. + * + * @param Src Source scanline buffer (length = this -> InLen). Source + * scanline increment will be equal to ElCount. + * @param Dst Destination scanline buffer. + */ + + void doUpsample( const fptype* const Src, fptype* const Dst ) const + { + const int ElCount = Vars -> ElCount; + fptype* op0 = &Dst[ -OutPrefix * ElCount ]; + memset( op0, 0, ( OutPrefix + OutLen + OutSuffix ) * ElCount * + sizeof( fptype )); + + const fptype* ip = Src; + const int opstep = ElCount * ResampleFactor; + int l; + + if( FltOrig.getCapacity() > 0 ) + { + // Do not perform filtering, only upsample. + + op0 += ( OutPrefix % ResampleFactor ) * ElCount; + l = OutPrefix / ResampleFactor; + + if( ElCount == 1 ) + { + while( l > 0 ) + { + op0[ 0 ] = ip[ 0 ]; + op0 += opstep; + l--; + } + + l = InLen - 1; + + while( l > 0 ) + { + op0[ 0 ] = ip[ 0 ]; + op0 += opstep; + ip += ElCount; + l--; + } + + l = OutSuffix / ResampleFactor; + + while( l >= 0 ) + { + op0[ 0 ] = ip[ 0 ]; + op0 += opstep; + l--; + } + } + else + if( ElCount == 4 ) + { + while( l > 0 ) + { + op0[ 0 ] = ip[ 0 ]; + op0[ 1 ] = ip[ 1 ]; + op0[ 2 ] = ip[ 2 ]; + op0[ 3 ] = ip[ 3 ]; + op0 += opstep; + l--; + } + + l = InLen - 1; + + while( l > 0 ) + { + op0[ 0 ] = ip[ 0 ]; + op0[ 1 ] = ip[ 1 ]; + op0[ 2 ] = ip[ 2 ]; + op0[ 3 ] = ip[ 3 ]; + op0 += opstep; + ip += ElCount; + l--; + } + + l = OutSuffix / ResampleFactor; + + while( l >= 0 ) + { + op0[ 0 ] = ip[ 0 ]; + op0[ 1 ] = ip[ 1 ]; + op0[ 2 ] = ip[ 2 ]; + op0[ 3 ] = ip[ 3 ]; + op0 += opstep; + l--; + } + } + else + if( ElCount == 3 ) + { + while( l > 0 ) + { + op0[ 0 ] = ip[ 0 ]; + op0[ 1 ] = ip[ 1 ]; + op0[ 2 ] = ip[ 2 ]; + op0 += opstep; + l--; + } + + l = InLen - 1; + + while( l > 0 ) + { + op0[ 0 ] = ip[ 0 ]; + op0[ 1 ] = ip[ 1 ]; + op0[ 2 ] = ip[ 2 ]; + op0 += opstep; + ip += ElCount; + l--; + } + + l = OutSuffix / ResampleFactor; + + while( l >= 0 ) + { + op0[ 0 ] = ip[ 0 ]; + op0[ 1 ] = ip[ 1 ]; + op0[ 2 ] = ip[ 2 ]; + op0 += opstep; + l--; + } + } + else + if( ElCount == 2 ) + { + while( l > 0 ) + { + op0[ 0 ] = ip[ 0 ]; + op0[ 1 ] = ip[ 1 ]; + op0 += opstep; + l--; + } + + l = InLen - 1; + + while( l > 0 ) + { + op0[ 0 ] = ip[ 0 ]; + op0[ 1 ] = ip[ 1 ]; + op0 += opstep; + ip += ElCount; + l--; + } + + l = OutSuffix / ResampleFactor; + + while( l >= 0 ) + { + op0[ 0 ] = ip[ 0 ]; + op0[ 1 ] = ip[ 1 ]; + op0 += opstep; + l--; + } + } + + return; + } + + const fptype* const f = Flt; + const int flen = Flt.getCapacity(); + fptype* op; + int i; + + if( ElCount == 1 ) + { + l = InPrefix; + + while( l > 0 ) + { + op = op0; + + for( i = 0; i < flen; i++ ) + { + op[ i ] += f[ i ] * ip[ 0 ]; + } + + op0 += opstep; + l--; + } + + l = InLen - 1; + + while( l > 0 ) + { + op = op0; + + for( i = 0; i < flen; i++ ) + { + op[ i ] += f[ i ] * ip[ 0 ]; + } + + ip += ElCount; + op0 += opstep; + l--; + } + + l = InSuffix; + + while( l >= 0 ) + { + op = op0; + + for( i = 0; i < flen; i++ ) + { + op[ i ] += f[ i ] * ip[ 0 ]; + } + + op0 += opstep; + l--; + } + } + else + if( ElCount == 4 ) + { + l = InPrefix; + + while( l > 0 ) + { + op = op0; + + for( i = 0; i < flen; i++ ) + { + op[ 0 ] += f[ i ] * ip[ 0 ]; + op[ 1 ] += f[ i ] * ip[ 1 ]; + op[ 2 ] += f[ i ] * ip[ 2 ]; + op[ 3 ] += f[ i ] * ip[ 3 ]; + op += 4; + } + + op0 += opstep; + l--; + } + + l = InLen - 1; + + while( l > 0 ) + { + op = op0; + + for( i = 0; i < flen; i++ ) + { + op[ 0 ] += f[ i ] * ip[ 0 ]; + op[ 1 ] += f[ i ] * ip[ 1 ]; + op[ 2 ] += f[ i ] * ip[ 2 ]; + op[ 3 ] += f[ i ] * ip[ 3 ]; + op += 4; + } + + ip += ElCount; + op0 += opstep; + l--; + } + + l = InSuffix; + + while( l >= 0 ) + { + op = op0; + + for( i = 0; i < flen; i++ ) + { + op[ 0 ] += f[ i ] * ip[ 0 ]; + op[ 1 ] += f[ i ] * ip[ 1 ]; + op[ 2 ] += f[ i ] * ip[ 2 ]; + op[ 3 ] += f[ i ] * ip[ 3 ]; + op += 4; + } + + op0 += opstep; + l--; + } + } + else + if( ElCount == 3 ) + { + l = InPrefix; + + while( l > 0 ) + { + op = op0; + + for( i = 0; i < flen; i++ ) + { + op[ 0 ] += f[ i ] * ip[ 0 ]; + op[ 1 ] += f[ i ] * ip[ 1 ]; + op[ 2 ] += f[ i ] * ip[ 2 ]; + op += 3; + } + + op0 += opstep; + l--; + } + + l = InLen - 1; + + while( l > 0 ) + { + op = op0; + + for( i = 0; i < flen; i++ ) + { + op[ 0 ] += f[ i ] * ip[ 0 ]; + op[ 1 ] += f[ i ] * ip[ 1 ]; + op[ 2 ] += f[ i ] * ip[ 2 ]; + op += 3; + } + + ip += ElCount; + op0 += opstep; + l--; + } + + l = InSuffix; + + while( l >= 0 ) + { + op = op0; + + for( i = 0; i < flen; i++ ) + { + op[ 0 ] += f[ i ] * ip[ 0 ]; + op[ 1 ] += f[ i ] * ip[ 1 ]; + op[ 2 ] += f[ i ] * ip[ 2 ]; + op += 3; + } + + op0 += opstep; + l--; + } + } + else + if( ElCount == 2 ) + { + l = InPrefix; + + while( l > 0 ) + { + op = op0; + + for( i = 0; i < flen; i++ ) + { + op[ 0 ] += f[ i ] * ip[ 0 ]; + op[ 1 ] += f[ i ] * ip[ 1 ]; + op += 2; + } + + op0 += opstep; + l--; + } + + l = InLen - 1; + + while( l > 0 ) + { + op = op0; + + for( i = 0; i < flen; i++ ) + { + op[ 0 ] += f[ i ] * ip[ 0 ]; + op[ 1 ] += f[ i ] * ip[ 1 ]; + op += 2; + } + + ip += ElCount; + op0 += opstep; + l--; + } + + l = InSuffix; + + while( l >= 0 ) + { + op = op0; + + for( i = 0; i < flen; i++ ) + { + op[ 0 ] += f[ i ] * ip[ 0 ]; + op[ 1 ] += f[ i ] * ip[ 1 ]; + op += 2; + } + + op0 += opstep; + l--; + } + } + + op = op0; + const fptype* dc = SuffixDC; + l = SuffixDC.getCapacity(); + + if( ElCount == 1 ) + { + for( i = 0; i < l; i++ ) + { + op[ i ] += ip[ 0 ] * dc[ i ]; + } + } + else + if( ElCount == 4 ) + { + while( l > 0 ) + { + op[ 0 ] += ip[ 0 ] * dc[ 0 ]; + op[ 1 ] += ip[ 1 ] * dc[ 0 ]; + op[ 2 ] += ip[ 2 ] * dc[ 0 ]; + op[ 3 ] += ip[ 3 ] * dc[ 0 ]; + dc++; + op += 4; + l--; + } + } + else + if( ElCount == 3 ) + { + while( l > 0 ) + { + op[ 0 ] += ip[ 0 ] * dc[ 0 ]; + op[ 1 ] += ip[ 1 ] * dc[ 0 ]; + op[ 2 ] += ip[ 2 ] * dc[ 0 ]; + dc++; + op += 3; + l--; + } + } + else + if( ElCount == 2 ) + { + while( l > 0 ) + { + op[ 0 ] += ip[ 0 ] * dc[ 0 ]; + op[ 1 ] += ip[ 1 ] * dc[ 0 ]; + dc++; + op += 2; + l--; + } + } + + ip = Src; + op = Dst - InPrefix * opstep; + dc = PrefixDC; + l = PrefixDC.getCapacity(); + + if( ElCount == 1 ) + { + for( i = 0; i < l; i++ ) + { + op[ i ] += ip[ 0 ] * dc[ i ]; + } + } + else + if( ElCount == 4 ) + { + while( l > 0 ) + { + op[ 0 ] += ip[ 0 ] * dc[ 0 ]; + op[ 1 ] += ip[ 1 ] * dc[ 0 ]; + op[ 2 ] += ip[ 2 ] * dc[ 0 ]; + op[ 3 ] += ip[ 3 ] * dc[ 0 ]; + dc++; + op += 4; + l--; + } + } + else + if( ElCount == 3 ) + { + while( l > 0 ) + { + op[ 0 ] += ip[ 0 ] * dc[ 0 ]; + op[ 1 ] += ip[ 1 ] * dc[ 0 ]; + op[ 2 ] += ip[ 2 ] * dc[ 0 ]; + dc++; + op += 3; + l--; + } + } + else + if( ElCount == 2 ) + { + while( l > 0 ) + { + op[ 0 ] += ip[ 0 ] * dc[ 0 ]; + op[ 1 ] += ip[ 1 ] * dc[ 0 ]; + dc++; + op += 2; + l--; + } + } + } + + /** + * Function peforms scanline filtering with optional downsampling. + * Function makes use of the symmetry of the filter. + * + * @param Src Source scanline buffer (length = this -> InLen). Source + * scanline increment will be equal to ElCount. + * @param Dst Destination scanline buffer. + * @param DstIncr Destination scanline buffer increment, used for + * horizontal or vertical scanline stepping. + */ + + void doFilter( const fptype* const Src, fptype* Dst, + const int DstIncr ) const + { + const int ElCount = Vars -> ElCount; + const fptype* const f = &Flt[ FltLatency ]; + const int flen = FltLatency + 1; + const int ipstep = ElCount * ResampleFactor; + const fptype* ip = Src - EdgePixelCount * ipstep; + const fptype* ip1; + const fptype* ip2; + int l = OutLen; + int i; + + if( ElCount == 1 ) + { + while( l > 0 ) + { + fptype s = f[ 0 ] * ip[ 0 ]; + ip1 = ip; + ip2 = ip; + + for( i = 1; i < flen; i++ ) + { + ip1++; + ip2--; + s += f[ i ] * ( ip1[ 0 ] + ip2[ 0 ]); + } + + Dst[ 0 ] = s; + Dst += DstIncr; + ip += ipstep; + l--; + } + } + else + if( ElCount == 4 ) + { + while( l > 0 ) + { + fptype s1 = f[ 0 ] * ip[ 0 ]; + fptype s2 = f[ 0 ] * ip[ 1 ]; + fptype s3 = f[ 0 ] * ip[ 2 ]; + fptype s4 = f[ 0 ] * ip[ 3 ]; + ip1 = ip; + ip2 = ip; + + for( i = 1; i < flen; i++ ) + { + ip1 += 4; + ip2 -= 4; + s1 += f[ i ] * ( ip1[ 0 ] + ip2[ 0 ]); + s2 += f[ i ] * ( ip1[ 1 ] + ip2[ 1 ]); + s3 += f[ i ] * ( ip1[ 2 ] + ip2[ 2 ]); + s4 += f[ i ] * ( ip1[ 3 ] + ip2[ 3 ]); + } + + Dst[ 0 ] = s1; + Dst[ 1 ] = s2; + Dst[ 2 ] = s3; + Dst[ 3 ] = s4; + Dst += DstIncr; + ip += ipstep; + l--; + } + } + else + if( ElCount == 3 ) + { + while( l > 0 ) + { + fptype s1 = f[ 0 ] * ip[ 0 ]; + fptype s2 = f[ 0 ] * ip[ 1 ]; + fptype s3 = f[ 0 ] * ip[ 2 ]; + ip1 = ip; + ip2 = ip; + + for( i = 1; i < flen; i++ ) + { + ip1 += 3; + ip2 -= 3; + s1 += f[ i ] * ( ip1[ 0 ] + ip2[ 0 ]); + s2 += f[ i ] * ( ip1[ 1 ] + ip2[ 1 ]); + s3 += f[ i ] * ( ip1[ 2 ] + ip2[ 2 ]); + } + + Dst[ 0 ] = s1; + Dst[ 1 ] = s2; + Dst[ 2 ] = s3; + Dst += DstIncr; + ip += ipstep; + l--; + } + } + else + if( ElCount == 2 ) + { + while( l > 0 ) + { + fptype s1 = f[ 0 ] * ip[ 0 ]; + fptype s2 = f[ 0 ] * ip[ 1 ]; + ip1 = ip; + ip2 = ip; + + for( i = 1; i < flen; i++ ) + { + ip1 += 2; + ip2 -= 2; + s1 += f[ i ] * ( ip1[ 0 ] + ip2[ 0 ]); + s2 += f[ i ] * ( ip1[ 1 ] + ip2[ 1 ]); + } + + Dst[ 0 ] = s1; + Dst[ 1 ] = s2; + Dst += DstIncr; + ip += ipstep; + l--; + } + } + } + + /** + * Function performs resizing of a single scanline. This function does + * not "know" about the length of the source scanline buffer. This buffer + * should be padded with enough pixels so that ( SrcPos - FilterLenD2 ) is + * always >= 0 and ( SrcPos + ( DstLineLen - 1 ) * k + FilterLenD2 + 1 ) + * does not exceed source scanline's buffer length. SrcLine's increment is + * assumed to be equal to ElCount. + * + * @param SrcLine Source scanline buffer. + * @param DstLine Destination (resized) scanline buffer. + * @param DstLineIncr Destination scanline position increment, used for + * horizontal or vertical scanline stepping. + * @param xx Temporary buffer, of size FltBank -> getFilterLen(), must be + * aligned by fpclass :: fpalign. + */ + + void doResize( const fptype* SrcLine, fptype* DstLine, + const int DstLineIncr, fptype* const ) const + { + const int IntFltLen = FltBank -> getFilterLen(); + const int ElCount = Vars -> ElCount; + const typename CImageResizerFilterStep< fptype, fptypeatom > :: + CResizePos* rpos = &(*RPosBuf)[ 0 ]; + + const typename CImageResizerFilterStep< fptype, fptypeatom > :: + CResizePos* const rpose = rpos + OutLen; + +#define AVIR_RESIZE_PART1 \ + while( rpos < rpose ) \ + { \ + const fptype x = (fptype) rpos -> x; \ + const fptype* const ftp = rpos -> ftp; \ + const fptype* const ftp2 = ftp + IntFltLen; \ + const fptype* Src = SrcLine + rpos -> SrcOffs; \ + int i; + +#define AVIR_RESIZE_PART1nx \ + while( rpos < rpose ) \ + { \ + const fptype* const ftp = rpos -> ftp; \ + const fptype* Src = SrcLine + rpos -> SrcOffs; \ + int i; + +#define AVIR_RESIZE_PART2 \ + DstLine += DstLineIncr; \ + rpos++; \ + } + + if( FltBank -> getOrder() == 1 ) + { + if( ElCount == 1 ) + { + AVIR_RESIZE_PART1 + + fptype sum = 0.0; + + for( i = 0; i < IntFltLen; i++ ) + { + sum += ( ftp[ i ] + ftp2[ i ] * x ) * Src[ i ]; + } + + DstLine[ 0 ] = sum; + + AVIR_RESIZE_PART2 + } + else + if( ElCount == 4 ) + { + AVIR_RESIZE_PART1 + + fptype sum[ 4 ]; + sum[ 0 ] = 0.0; + sum[ 1 ] = 0.0; + sum[ 2 ] = 0.0; + sum[ 3 ] = 0.0; + + for( i = 0; i < IntFltLen; i++ ) + { + const fptype xx = ftp[ i ] + ftp2[ i ] * x; + sum[ 0 ] += xx * Src[ 0 ]; + sum[ 1 ] += xx * Src[ 1 ]; + sum[ 2 ] += xx * Src[ 2 ]; + sum[ 3 ] += xx * Src[ 3 ]; + Src += 4; + } + + DstLine[ 0 ] = sum[ 0 ]; + DstLine[ 1 ] = sum[ 1 ]; + DstLine[ 2 ] = sum[ 2 ]; + DstLine[ 3 ] = sum[ 3 ]; + + AVIR_RESIZE_PART2 + } + else + if( ElCount == 3 ) + { + AVIR_RESIZE_PART1 + + fptype sum[ 3 ]; + sum[ 0 ] = 0.0; + sum[ 1 ] = 0.0; + sum[ 2 ] = 0.0; + + for( i = 0; i < IntFltLen; i++ ) + { + const fptype xx = ftp[ i ] + ftp2[ i ] * x; + sum[ 0 ] += xx * Src[ 0 ]; + sum[ 1 ] += xx * Src[ 1 ]; + sum[ 2 ] += xx * Src[ 2 ]; + Src += 3; + } + + DstLine[ 0 ] = sum[ 0 ]; + DstLine[ 1 ] = sum[ 1 ]; + DstLine[ 2 ] = sum[ 2 ]; + + AVIR_RESIZE_PART2 + } + else + if( ElCount == 2 ) + { + AVIR_RESIZE_PART1 + + fptype sum[ 2 ]; + sum[ 0 ] = 0.0; + sum[ 1 ] = 0.0; + + for( i = 0; i < IntFltLen; i++ ) + { + const fptype xx = ftp[ i ] + ftp2[ i ] * x; + sum[ 0 ] += xx * Src[ 0 ]; + sum[ 1 ] += xx * Src[ 1 ]; + Src += 2; + } + + DstLine[ 0 ] = sum[ 0 ]; + DstLine[ 1 ] = sum[ 1 ]; + + AVIR_RESIZE_PART2 + } + } + else + { + if( ElCount == 1 ) + { + AVIR_RESIZE_PART1nx + + fptype sum = 0.0; + + for( i = 0; i < IntFltLen; i++ ) + { + sum += ftp[ i ] * Src[ i ]; + } + + DstLine[ 0 ] = sum; + + AVIR_RESIZE_PART2 + } + else + if( ElCount == 4 ) + { + AVIR_RESIZE_PART1nx + + fptype sum[ 4 ]; + sum[ 0 ] = 0.0; + sum[ 1 ] = 0.0; + sum[ 2 ] = 0.0; + sum[ 3 ] = 0.0; + + for( i = 0; i < IntFltLen; i++ ) + { + const fptype xx = ftp[ i ]; + sum[ 0 ] += xx * Src[ 0 ]; + sum[ 1 ] += xx * Src[ 1 ]; + sum[ 2 ] += xx * Src[ 2 ]; + sum[ 3 ] += xx * Src[ 3 ]; + Src += 4; + } + + DstLine[ 0 ] = sum[ 0 ]; + DstLine[ 1 ] = sum[ 1 ]; + DstLine[ 2 ] = sum[ 2 ]; + DstLine[ 3 ] = sum[ 3 ]; + + AVIR_RESIZE_PART2 + } + else + if( ElCount == 3 ) + { + AVIR_RESIZE_PART1nx + + fptype sum[ 3 ]; + sum[ 0 ] = 0.0; + sum[ 1 ] = 0.0; + sum[ 2 ] = 0.0; + + for( i = 0; i < IntFltLen; i++ ) + { + const fptype xx = ftp[ i ]; + sum[ 0 ] += xx * Src[ 0 ]; + sum[ 1 ] += xx * Src[ 1 ]; + sum[ 2 ] += xx * Src[ 2 ]; + Src += 3; + } + + DstLine[ 0 ] = sum[ 0 ]; + DstLine[ 1 ] = sum[ 1 ]; + DstLine[ 2 ] = sum[ 2 ]; + + AVIR_RESIZE_PART2 + } + else + if( ElCount == 2 ) + { + AVIR_RESIZE_PART1nx + + fptype sum[ 2 ]; + sum[ 0 ] = 0.0; + sum[ 1 ] = 0.0; + + for( i = 0; i < IntFltLen; i++ ) + { + const fptype xx = ftp[ i ]; + sum[ 0 ] += xx * Src[ 0 ]; + sum[ 1 ] += xx * Src[ 1 ]; + Src += 2; + } + + DstLine[ 0 ] = sum[ 0 ]; + DstLine[ 1 ] = sum[ 1 ]; + + AVIR_RESIZE_PART2 + } + } + } +#undef AVIR_RESIZE_PART2 +#undef AVIR_RESIZE_PART1nx +#undef AVIR_RESIZE_PART1 +}; + +/** + * @brief Image resizer's default dithering class. + * + * This class defines an object that performs rounding, clipping and dithering + * operations over horizontal scanline pixels before scanline is stored in the + * output buffer. + * + * The ditherer should expect the same storage order of the pixels in a + * scanline as used in the "filtering step" class. So, a separate ditherer + * class should be defined for each scanline pixel storage style. The default + * ditherer implements a simple rounding without dithering: it can be used for + * an efficient dithering method which can be multi-threaded. + * + * @tparam fptype Floating point type to use for storing pixel data. SIMD + * types can be used. + */ + +template< class fptype > +class CImageResizerDithererDefINL +{ +public: + /** + * Function initializes the ditherer object. + * + * @param aLen Scanline length in pixels to process. + * @param aVars Image resizing-related variables. + * @param aTrMul Bit-depth truncation multiplier. 1 - no additional + * truncation. + * @param aPkOut Peak output value allowed. + */ + + void init( const int aLen, const CImageResizerVars& aVars, + const double aTrMul, const double aPkOut ) + { + Len = aLen; + Vars = &aVars; + LenE = aLen * Vars -> ElCount; + TrMul0 = aTrMul; + PkOut0 = aPkOut; + } + + /** + * @return "True" if dithering is recursive relative to scanlines meaning + * multi-threaded execution is not supported by this dithering method. + */ + + static bool isRecursive() + { + return( false ); + } + + /** + * Function performs rounding and clipping operations. + * + * @param ResScanline The buffer containing the final scanline. + */ + + void dither( fptype* const ResScanline ) const + { + const fptype c0 = 0.0; + const fptype PkOut = (fptype) PkOut0; + int j; + + if( TrMul0 == 1.0 ) + { + // Optimization - do not perform bit depth truncation. + + for( j = 0; j < LenE; j++ ) + { + ResScanline[ j ] = clamp( round( ResScanline[ j ]), c0, + PkOut ); + } + } + else + { + const fptype TrMul = (fptype) TrMul0; + + for( j = 0; j < LenE; j++ ) + { + const fptype z0 = round( ResScanline[ j ] / TrMul ) * TrMul; + ResScanline[ j ] = clamp( z0, c0, PkOut ); + } + } + } + +protected: + int Len; ///< Scanline's length in pixels. + ///< + const CImageResizerVars* Vars; ///< Image resizing-related variables. + ///< + int LenE; ///< = LenE * ElCount. + ///< + double TrMul0; ///< Bit-depth truncation multiplier. + ///< + double PkOut0; ///< Peak output value allowed. + ///< +}; + +/** + * @brief Image resizer's error-diffusion dithering class, interleaved mode. + * + * This ditherer implements error-diffusion dithering which looks good, and + * whose results are compressed by PNG well. This implementation uses + * weighting coefficients obtained via machine optimization and visual + * evaluation. + * + * @tparam fptype Floating point type to use for storing pixel data. SIMD + * types can be used. + */ + +template< class fptype > +class CImageResizerDithererErrdINL : + public CImageResizerDithererDefINL< fptype > +{ +public: + /** + * Function initializes the ditherer object. + * + * @param aLen Scanline length in pixels to process. + * @param aVars Image resizing-related variables. + * @param aTrMul Bit-depth truncation multiplier. 1 - no additional + * truncation. + * @param aPkOut Peak output value allowed. + */ + + void init( const int aLen, const CImageResizerVars& aVars, + const double aTrMul, const double aPkOut ) + { + CImageResizerDithererDefINL< fptype > :: init( aLen, aVars, aTrMul, + aPkOut ); + + ResScanlineDith0.alloc( LenE + Vars -> ElCount, sizeof( fptype )); + ResScanlineDith = ResScanlineDith0 + Vars -> ElCount; + int i; + + for( i = 0; i < LenE + Vars -> ElCount; i++ ) + { + ResScanlineDith0[ i ] = 0.0; + } + } + + static bool isRecursive() + { + return( true ); + } + + void dither( fptype* const ResScanline ) + { + const int ElCount = Vars -> ElCount; + const fptype c0 = 0.0; + const fptype TrMul = (fptype) TrMul0; + const fptype PkOut = (fptype) PkOut0; + int j; + + for( j = 0; j < LenE; j++ ) + { + ResScanline[ j ] += ResScanlineDith[ j ]; + ResScanlineDith[ j ] = 0.0; + } + + for( j = 0; j < LenE - ElCount; j++ ) + { + // Perform rounding, noise estimation and saturation. + + const fptype z0 = round( ResScanline[ j ] / TrMul ) * TrMul; + const fptype Noise = ResScanline[ j ] - z0; + ResScanline[ j ] = clamp( z0, c0, PkOut ); + + ResScanline[ j + ElCount ] += Noise * (fptype) 0.364842; + ResScanlineDith[ j - ElCount ] += Noise * (fptype) 0.207305; + ResScanlineDith[ j ] += Noise * (fptype) 0.364842; + ResScanlineDith[ j + ElCount ] += Noise * (fptype) 0.063011; + } + + while( j < LenE ) + { + const fptype z0 = round( ResScanline[ j ] / TrMul ) * TrMul; + const fptype Noise = ResScanline[ j ] - z0; + ResScanline[ j ] = clamp( z0, c0, PkOut ); + + ResScanlineDith[ j - ElCount ] += Noise * (fptype) 0.207305; + ResScanlineDith[ j ] += Noise * (fptype) 0.364842; + j++; + } + } + +protected: + using CImageResizerDithererDefINL< fptype > :: Len; + using CImageResizerDithererDefINL< fptype > :: Vars; + using CImageResizerDithererDefINL< fptype > :: LenE; + using CImageResizerDithererDefINL< fptype > :: TrMul0; + using CImageResizerDithererDefINL< fptype > :: PkOut0; + + CBuffer< fptype > ResScanlineDith0; ///< Error diffusion buffer. + ///< + fptype* ResScanlineDith; ///< Error diffusion buffer pointer which skips + ///< the first ElCount elements. + ///< +}; + +/** + * @brief Floating-point processing definition and abstraction class. + * + * This class defines several constants and typedefs that point to classes + * that should be used by the image resizing algorithm. Such "definition + * class" can be used to define alternative scanline processing algorithms + * (e.g. SIMD) and image scanline packing styles used during processing. This + * class also offers an abstraction layer for dithering, rounding and + * clamping (saturation) operation. + * + * The fpclass_def class can be used to define processing using both SIMD and + * non-SIMD types, but using algorithms that are operate on interleaved pixels + * and non-SIMD optimized themselves. + * + * @tparam afptype Floating point type to use for storing intermediate data + * and variables. For variables that are not used in intensive calculations + * the "double" type is always used. On the latest Intel processors (like + * i7-4770K) there is almost no performance difference between "double" and + * "float". Image quality differences between "double" and "float" are not + * apparent on 8-bit images. At the same time the "float" uses half amount of + * working memory the "double" type uses. SIMD types can be used. The + * functions round() and clamp() in the "avir" or other visible namespace + * should be available for the specified type. SIMD types allow to perform + * resizing of images with more than 4 channels, to be exact 4 * SIMD element + * number (e.g. 16 for float4), without modification of the image resizing + * algorithm required. + * @tparam afptypeatom The atomic type the "afptype" consists of. + * @tparam adith Ditherer class to use during processing. + */ + +template< class afptype, class afptypeatom = afptype, + class adith = CImageResizerDithererDefINL< afptype > > +class fpclass_def +{ +public: + typedef afptype fptype; ///< Floating-point type to use during processing. + ///< + typedef afptypeatom fptypeatom; ///< Atomic type "fptype" consists of. + ///< + static const int fppack = sizeof( fptype ) / sizeof( fptypeatom ); ///< + ///< The number of atomic types stored in a single "fptype" element. + ///< + static const int fpalign = sizeof( fptype ); ///< Suggested alignment size + ///< in bytes. This is not a required alignment, because image + ///< resizing algorithm cannot be made to have a strictly aligned data + ///< access at all steps (e.g. interpolation cannot perform aligned + ///< accesses). + ///< + static const int elalign = 1; ///< Length alignment of arrays of elements. + ///< This applies to filters and intermediate buffers: this constant + ///< forces filters and scanlines to have a length which is a multiple + ///< of this value, for more efficient SIMD implementation. + ///< + static const int packmode = 0; ///< 0 if interleaved packing, 1 if + ///< de-interleaved. + ///< + typedef CImageResizerFilterStepINL< fptype, fptypeatom > CFilterStep; ///< + ///< Filtering step class to use during processing. + ///< + typedef adith CDitherer; ///< Ditherer class to use during processing. + ///< +}; + +/** + * @brief Image resizer class. + * + * The object of this class can be used to resize 1-4 channel images to any + * required size. Resizing is performed by utilizing interpolated sinc + * fractional delay filters plus (if necessary) a cascade of built-in + * sinc function-based 2X upsampling or 2X downsampling stages, followed by a + * correction filtering. + * + * Object of this class can be allocated on stack. + * + * @tparam fpclass Floating-point processing definition class to use. See + * avir::fpclass_def for more details. + */ + +template< class fpclass = fpclass_def< float > > +class CImageResizer +{ +public: + /** + * Constructor initializes the resizer. + * + * @param aResBitDepth Required bit depth of resulting image (1-16). If + * integer value output is used (e.g. uint8_t), the bit depth also affects + * rounding: for example, if aResBitDepth=6 and "Tout" is uint8_t, the + * result will be rounded to 6 most significant bits (2 least significant + * bits truncated, with dithering applied). + * @param aSrcBitDepth Source image's real bit-depth. Set to 0 to use + * aResBitDepth. + * @param aParams Resizing algorithm's parameters to use. Leave out for + * default values. Can be useful when performing automatic optimization of + * parameters. + */ + + CImageResizer( const int aResBitDepth = 8, const int aSrcBitDepth = 0, + const CImageResizerParams& aParams = CImageResizerParamsDef() ) + : Params( aParams ) + , ResBitDepth( aResBitDepth ) + { + SrcBitDepth = ( aSrcBitDepth == 0 ? ResBitDepth : aSrcBitDepth ); + + initFilterBank( FixedFilterBank, 1.0, false, CFltBuffer() ); + FixedFilterBank.createAllFilters(); + } + + /** + * Function resizes image. + * + * @param SrcBuf Source image buffer. + * @param SrcWidth Source image width. + * @param SrcHeight Source image height. + * @param SrcScanlineSize Physical size of source scanline in elements + * (not bytes). If this value is below 1, SrcWidth * ElCountIO will be + * used as the physical source scanline size. + * @param[out] NewBuf Buffer to accept the resized image. Can be equal to + * SrcBuf if the size of the resized image is smaller or equal to source + * image in size. + * @param NewWidth New image width. + * @param NewHeight New image height. + * @param ElCountIO The number of elements (channels) used to store each + * source and destination pixel (1-4). + * @param k Resizing step (one output pixel corresponds to "k" input + * pixels). A downsizing factor if > 1.0; upsizing factor if <= 1.0. + * Multiply by -1 if you would like to bypass "ox" and "oy" adjustment + * which is done by default to produce a centered image. If step value + * equals 0, the step value will be chosen automatically and independently + * for horizontal and vertical resizing. + * @param[in,out] aVars Pointer to variables structure to be passed to the + * image resizing function. Can be NULL. Only variables that are + * initialized in default constructor of this structure are accepted by + * this function. These variables will not be changed by this function. + * All other variables can be modified by this function. The access to + * this object is not thread-safe, each concurrent instance of this + * function should use a separate aVars object. + * @tparam Tin Input buffer element's type. Can be uint8_t (0-255 value + * range), uint16_t (0-65535 value range), float (0.0-1.0 value range), + * double (0.0-1.0 value range). Larger integer types are treated as + * uint16_t. Signed integer types are unsupported. + * @tparam Tout Output buffer element's type. Can be uint8_t (0-255 value + * range), uint16_t (0-65535 value range), float (0.0-1.0 value range), + * double (0.0-1.0 value range). Larger integer types are treated as + * uint16_t. Signed integer types are unsupported. + */ + + template< class Tin, class Tout > + void resizeImage( const Tin* const SrcBuf, const int SrcWidth, + const int SrcHeight, int SrcScanlineSize, Tout* const NewBuf, + const int NewWidth, const int NewHeight, const int ElCountIO, + const double k, CImageResizerVars* const aVars = NULL ) const + { + if( SrcWidth == 0 || SrcHeight == 0 ) + { + memset( NewBuf, 0, (size_t) NewWidth * NewHeight * + sizeof( Tout )); + + return; + } + else + if( NewWidth == 0 || NewHeight == 0 ) + { + return; + } + + CImageResizerVars DefVars; + CImageResizerVars& Vars = ( aVars == NULL ? DefVars : *aVars ); + + CImageResizerThreadPool DefThreadPool; + CImageResizerThreadPool& ThreadPool = ( Vars.ThreadPool == NULL ? + DefThreadPool : *Vars.ThreadPool ); + + // Define resizing steps, also optionally modify offsets so that + // resizing produces a "centered" image. + + double kx; + double ky; + double ox = Vars.ox; + double oy = Vars.oy; + + if( k == 0.0 ) + { + if( NewWidth > SrcWidth ) + { + kx = (double) ( SrcWidth - 1 ) / ( NewWidth - 1 ); + } + else + { + kx = (double) SrcWidth / NewWidth; + ox += ( kx - 1.0 ) * 0.5; + } + + if( NewHeight > SrcHeight ) + { + ky = (double) ( SrcHeight - 1 ) / ( NewHeight - 1 ); + } + else + { + ky = (double) SrcHeight / NewHeight; + oy += ( ky - 1.0 ) * 0.5; + } + } + else + if( k > 0.0 ) + { + kx = k; + ky = k; + + if( k > 1.0 ) + { + const double ko = ( k - 1.0 ) * 0.5; + ox += ko; + oy += ko; + } + } + else + { + kx = -k; + ky = -k; + } + + // Evaluate pre-multipliers used on the output stage. + + const bool IsInFloat = ( (Tin) 0.4 != 0 ); + const bool IsOutFloat = ( (Tout) 0.4 != 0 ); + double OutMul; // Output multiplier. + + if( Vars.UseSRGBGamma ) + { + if( IsInFloat ) + { + Vars.InGammaMult = 1.0; + } + else + { + Vars.InGammaMult = + 1.0 / ( sizeof( Tin ) == 1 ? 255.0 : 65535.0 ); + } + + if( IsOutFloat ) + { + Vars.OutGammaMult = 1.0; + } + else + { + Vars.OutGammaMult = ( sizeof( Tout ) == 1 ? 255.0 : 65535.0 ); + } + + OutMul = 1.0; + } + else + { + if( IsOutFloat ) + { + OutMul = 1.0; + } + else + { + OutMul = ( sizeof( Tout ) == 1 ? 255.0 : 65535.0 ); + } + + if( !IsInFloat ) + { + OutMul /= ( sizeof( Tin ) == 1 ? 255.0 : 65535.0 ); + } + } + + // Fill widely-used variables. + + const int ElCount = ( ElCountIO + fpclass :: fppack - 1 ) / + fpclass :: fppack; + + const int NewWidthE = NewWidth * ElCount; + + if( SrcScanlineSize < 1 ) + { + SrcScanlineSize = SrcWidth * ElCountIO; + } + + Vars.ElCount = ElCount; + Vars.ElCountIO = ElCountIO; + Vars.fppack = fpclass :: fppack; + Vars.fpalign = fpclass :: fpalign; + Vars.elalign = fpclass :: elalign; + Vars.packmode = fpclass :: packmode; + + // Horizontal scanline filtering and resizing. + + CDSPFracFilterBankLin< fptype > FltBank; + CFilterSteps FltSteps; + typename CFilterStep :: CRPosBufArray RPosBufArray; + CBuffer< uint8_t > UsedFracMap; + + // Perform the filtering steps modeling at various modes, find the + // most efficient mode for both horizontal and vertical resizing. + + int UseBuildMode = 1; + const int BuildModeCount = + ( FixedFilterBank.getOrder() == 0 ? 4 : 2 ); + + int m; + + if( Vars.BuildMode >= 0 ) + { + UseBuildMode = Vars.BuildMode; + } + else + { + int BestScore = 0x7FFFFFFF; + + for( m = 0; m < BuildModeCount; m++ ) + { + CDSPFracFilterBankLin< fptype > TmpBank; + CFilterSteps TmpSteps; + Vars.k = kx; + Vars.o = ox; + buildFilterSteps( TmpSteps, Vars, TmpBank, OutMul, m, true ); + updateFilterStepBuffers( TmpSteps, Vars, RPosBufArray, + SrcWidth, NewWidth ); + + fillUsedFracMap( TmpSteps[ Vars.ResizeStep ], UsedFracMap ); + const int c = calcComplexity( TmpSteps, Vars, UsedFracMap, + SrcHeight ); + + if( c < BestScore ) + { + UseBuildMode = m; + BestScore = c; + } + } + } + + // Perform the actual filtering steps building. + + Vars.k = kx; + Vars.o = ox; + buildFilterSteps( FltSteps, Vars, FltBank, OutMul, UseBuildMode, + false ); + + updateFilterStepBuffers( FltSteps, Vars, RPosBufArray, SrcWidth, + NewWidth ); + + updateBufLenAndRPosPtrs( FltSteps, Vars, NewWidth ); + + const int ThreadCount = ThreadPool.getSuggestedWorkloadCount(); + // Includes the current thread. + + CStructArray< CThreadData< Tin, Tout > > td; + td.setItemCount( ThreadCount ); + int i; + + for( i = 0; i < ThreadCount; i++ ) + { + if( i > 0 ) + { + ThreadPool.addWorkload( &td[ i ]); + } + + td[ i ].init( i, ThreadCount, FltSteps, Vars ); + + td[ i ].initScanlineQueue( td[ i ].sopResizeH, SrcHeight, + SrcWidth ); + } + + CBuffer< fptype, size_t > FltBuf( (size_t) NewWidthE * SrcHeight, + fpclass :: fpalign ); // Temporary buffer that receives + // horizontally-filtered and resized image. + + for( i = 0; i < SrcHeight; i++ ) + { + td[ i % ThreadCount ].addScanlineToQueue( + (void*) &SrcBuf[ (size_t) i * SrcScanlineSize ], + &FltBuf[ (size_t) i * NewWidthE ]); + } + + ThreadPool.startAllWorkloads(); + td[ 0 ].processScanlineQueue(); + ThreadPool.waitAllWorkloadsToFinish(); + + // Vertical scanline filtering and resizing, reuse previously defined + // filtering steps if possible. + + const int PrevUseBuildMode = UseBuildMode; + + if( Vars.BuildMode >= 0 ) + { + UseBuildMode = Vars.BuildMode; + } + else + { + CImageResizerVars TmpVars( Vars ); + int BestScore = 0x7FFFFFFF; + + for( m = 0; m < BuildModeCount; m++ ) + { + CDSPFracFilterBankLin< fptype > TmpBank; + TmpBank.copyInitParams( FltBank ); + CFilterSteps TmpSteps; + TmpVars.k = ky; + TmpVars.o = oy; + buildFilterSteps( TmpSteps, TmpVars, TmpBank, 1.0, m, true ); + updateFilterStepBuffers( TmpSteps, TmpVars, RPosBufArray, + SrcHeight, NewHeight ); + + fillUsedFracMap( TmpSteps[ TmpVars.ResizeStep ], + UsedFracMap ); + + const int c = calcComplexity( TmpSteps, TmpVars, UsedFracMap, + NewWidth ); + + if( c < BestScore ) + { + UseBuildMode = m; + BestScore = c; + } + } + } + + Vars.k = ky; + Vars.o = oy; + + if( UseBuildMode == PrevUseBuildMode && ky == kx ) + { + if( OutMul != 1.0 ) + { + modifyCorrFilterDCGain( FltSteps, 1.0 / OutMul ); + } + } + else + { + buildFilterSteps( FltSteps, Vars, FltBank, 1.0, UseBuildMode, + false ); + } + + updateFilterStepBuffers( FltSteps, Vars, RPosBufArray, SrcHeight, + NewHeight ); + + updateBufLenAndRPosPtrs( FltSteps, Vars, NewWidth ); + + if( IsOutFloat && sizeof( FltBuf[ 0 ]) == sizeof( Tout ) && + fpclass :: packmode == 0 ) + { + // In-place output. + + for( i = 0; i < ThreadCount; i++ ) + { + td[ i ].initScanlineQueue( td[ i ].sopResizeV, NewWidth, + SrcHeight, NewWidthE, NewWidthE ); + } + + for( i = 0; i < NewWidth; i++ ) + { + td[ i % ThreadCount ].addScanlineToQueue( + &FltBuf[ (size_t) i * ElCount ], + (fptype*) &NewBuf[ (size_t) i * ElCount ]); + } + + ThreadPool.startAllWorkloads(); + td[ 0 ].processScanlineQueue(); + ThreadPool.waitAllWorkloadsToFinish(); + ThreadPool.removeAllWorkloads(); + + return; + } + + CBuffer< fptype, size_t > ResBuf( (size_t) NewWidthE * NewHeight, + fpclass :: fpalign ); + + for( i = 0; i < ThreadCount; i++ ) + { + td[ i ].initScanlineQueue( td[ i ].sopResizeV, NewWidth, + SrcHeight, NewWidthE, NewWidthE ); + } + + const int im = ( fpclass :: packmode == 0 ? ElCount : 1 ); + + for( i = 0; i < NewWidth; i++ ) + { + td[ i % ThreadCount ].addScanlineToQueue( + &FltBuf[ (size_t) i * im ], &ResBuf[ (size_t) i * im ]); + } + + ThreadPool.startAllWorkloads(); + td[ 0 ].processScanlineQueue(); + ThreadPool.waitAllWorkloadsToFinish(); + + if( IsOutFloat ) + { + // Perform output, but skip dithering. + + for( i = 0; i < ThreadCount; i++ ) + { + td[ i ].initScanlineQueue( td[ i ].sopUnpackH, + NewHeight, NewWidth ); + } + + for( i = 0; i < NewHeight; i++ ) + { + td[ i % ThreadCount ].addScanlineToQueue( + &ResBuf[ (size_t) i * NewWidthE ], + &NewBuf[ (size_t) i * NewWidth * ElCountIO ]); + } + + ThreadPool.startAllWorkloads(); + td[ 0 ].processScanlineQueue(); + ThreadPool.waitAllWorkloadsToFinish(); + ThreadPool.removeAllWorkloads(); + + return; + } + + // Perform output with dithering (for integer output only). + + int TruncBits; // The number of lower bits to truncate and dither. + int OutRange; // Output range. + + if( sizeof( Tout ) == 1 ) + { + TruncBits = 8 - ResBitDepth; + OutRange = 255; + } + else + { + TruncBits = 16 - ResBitDepth; + OutRange = 65535; + } + + const double PkOut = OutRange; + const double TrMul = ( TruncBits > 0 ? + PkOut / ( OutRange >> TruncBits ) : 1.0 ); + + if( CDitherer :: isRecursive() ) + { + td[ 0 ].getDitherer().init( NewWidth, Vars, TrMul, PkOut ); + + if( Vars.UseSRGBGamma ) + { + for( i = 0; i < NewHeight; i++ ) + { + fptype* const ResScanline = + &ResBuf[ (size_t) i * NewWidthE ]; + + CFilterStep :: applySRGBGamma( ResScanline, NewWidth, + Vars ); + + td[ 0 ].getDitherer().dither( ResScanline ); + + CFilterStep :: unpackScanline( ResScanline, + &NewBuf[ (size_t) i * NewWidth * ElCountIO ], + NewWidth, Vars ); + } + } + else + { + for( i = 0; i < NewHeight; i++ ) + { + fptype* const ResScanline = + &ResBuf[ (size_t) i * NewWidthE ]; + + td[ 0 ].getDitherer().dither( ResScanline ); + + CFilterStep :: unpackScanline( ResScanline, + &NewBuf[ (size_t) i * NewWidth * ElCountIO ], + NewWidth, Vars ); + } + } + } + else + { + for( i = 0; i < ThreadCount; i++ ) + { + td[ i ].initScanlineQueue( td[ i ].sopDitherAndUnpackH, + NewHeight, NewWidth ); + + td[ i ].getDitherer().init( NewWidth, Vars, TrMul, PkOut ); + } + + for( i = 0; i < NewHeight; i++ ) + { + td[ i % ThreadCount ].addScanlineToQueue( + &ResBuf[ (size_t) i * NewWidthE ], + &NewBuf[ (size_t) i * NewWidth * ElCountIO ]); + } + + ThreadPool.startAllWorkloads(); + td[ 0 ].processScanlineQueue(); + ThreadPool.waitAllWorkloadsToFinish(); + } + + ThreadPool.removeAllWorkloads(); + } + +private: + typedef typename fpclass :: fptype fptype; ///< Floating-point type to use + ///< during processing. + ///< + typedef typename fpclass :: CFilterStep CFilterStep; ///< Filtering step + ///< class to use during processing. + ///< + typedef typename fpclass :: CDitherer CDitherer; ///< Ditherer class to + ///< use during processing. + ///< + CImageResizerParams Params; ///< Algorithm's parameters currently in use. + ///< + int SrcBitDepth; ///< Bit resolution of the source image. + ///< + int ResBitDepth; ///< Bit resolution of the resulting image. + ///< + CDSPFracFilterBankLin< fptype > FixedFilterBank; ///< Fractional delay + ///< filter bank with fixed characteristics, mainly for upsizing + ///< cases. + ///< + + /** + * @brief Filtering steps array. + * + * The object of this class stores filtering steps together. + */ + + typedef CStructArray< CFilterStep > CFilterSteps; + + /** + * Function initializes the filter bank in the specified resizing step + * according to the source and resulting image bit depths. + * + * @param FltBank Filter bank to initialize. + * @param CutoffMult Cutoff multiplier, 0 to 1. 1 corresponds to 0.5pi + * cutoff point. + * @param ForceHiOrder "True" if a high-order interpolation should be + * forced which requires considerably less resources for initialization. + * @param ExtFilter External filter to apply to interpolation filter. + */ + + void initFilterBank( CDSPFracFilterBankLin< fptype >& FltBank, + const double CutoffMult, const bool ForceHiOrder, + const CFltBuffer& ExtFilter ) const + { + const int IntBitDepth = ( ResBitDepth > SrcBitDepth ? ResBitDepth : + SrcBitDepth ); + + const double SNR = -6.02 * ( IntBitDepth + 3 ); + int UseOrder; + int FracCount; // The number of fractional delay filters sampled by + // the filter bank. This variable affects the signal-to-noise + // ratio at interpolation stage. Theoretically, at UseOrder==1, + // 8-bit image resizing requires 66.2 dB SNR or 11. 16-bit + // resizing requires 114.4 dB SNR or 150. At UseOrder=0 the + // required number of filters is exponentially higher. + + if( ForceHiOrder || IntBitDepth > 8 ) + { + UseOrder = 1; // -146 dB max + FracCount = (int) ceil( 0.23134052 * exp( -0.058062929 * SNR )); + } + else + { + UseOrder = 0; // -72 dB max + FracCount = (int) ceil( 0.33287686 * exp( -0.11334583 * SNR )); + } + + if( FracCount < 2 ) + { + FracCount = 2; + } + + FltBank.init( FracCount, UseOrder, Params.IntFltLen / CutoffMult, + Params.IntFltCutoff * CutoffMult, Params.IntFltAlpha, ExtFilter, + fpclass :: fpalign, fpclass :: elalign ); + } + + /** + * Function allocates filter buffer taking "fpclass" alignments into + * account. The allocated buffer may be larger than the requested size: in + * this case the additional elements will be zeroed by this function. + * + * @param Flt Filter buffer. + * @param ReqCapacity The required filter buffer's capacity. + * @param IsModel "True" if filtering steps modeling is performed without + * actual filter allocation. + * @param FltExt If non-NULL this variable will receive the number of + * elements the filter was extended by. + */ + + static void allocFilter( CBuffer< fptype >& Flt, const int ReqCapacity, + const bool IsModel = false, int* const FltExt = NULL ) + { + int UseCapacity = ( ReqCapacity + fpclass :: elalign - 1 ) & + ~( fpclass :: elalign - 1 ); + + int Ext = UseCapacity - ReqCapacity; + + if( FltExt != NULL ) + { + *FltExt = Ext; + } + + if( IsModel ) + { + Flt.forceCapacity( UseCapacity ); + return; + } + + Flt.alloc( UseCapacity, fpclass :: fpalign ); + + while( Ext > 0 ) + { + Ext--; + Flt[ ReqCapacity + Ext ] = 0.0; + } + } + + /** + * Function assigns filter parameters to the specified filtering step + * object. + * + * @param fs Filtering step to assign parameter to. This step cannot be + * the last step if ResampleFactor greater than 1 was specified. + * @param IsUpsample "True" if upsampling step. Should be set to "false" + * if FltCutoff is negative. + * @param ResampleFactor Resampling factor of this filter (>=1). + * @param FltCutoff Filter cutoff point. This value will be divided by the + * ResampleFactor if IsUpsample equals "true". If zero value was + * specified, the "half-band" predefined filter will be created. In this + * case the ResampleFactor will modify the filter cutoff point. + * @param DCGain DC gain to apply to the filter. Assigned to filtering + * step's DCGain variable. + * @param UseFltOrig "True" if the originally-designed filter should be + * left in filtering step's FltOrig buffer. Otherwise it will be freed. + * @param IsModel "True" if filtering steps modeling is performed without + * actual filter building. + */ + + void assignFilterParams( CFilterStep& fs, const bool IsUpsample, + const int ResampleFactor, const double FltCutoff, const double DCGain, + const bool UseFltOrig, const bool IsModel ) const + { + double FltAlpha; + double Len2; + double Freq; + + if( FltCutoff == 0.0 ) + { + const double m = 2.0 / ResampleFactor; + FltAlpha = Params.HBFltAlpha; + Len2 = 0.5 * Params.HBFltLen / m; + Freq = AVIR_PI * Params.HBFltCutoff * m; + } + else + { + FltAlpha = Params.LPFltAlpha; + Len2 = 0.25 * Params.LPFltBaseLen / FltCutoff; + Freq = AVIR_PI * Params.LPFltCutoffMult * FltCutoff; + } + + if( IsUpsample ) + { + Len2 *= ResampleFactor; + Freq /= ResampleFactor; + fs.DCGain = DCGain * ResampleFactor; + } + else + { + fs.DCGain = DCGain; + } + + fs.FltOrig.Len2 = Len2; + fs.FltOrig.Freq = Freq; + fs.FltOrig.Alpha = FltAlpha; + fs.FltOrig.DCGain = fs.DCGain; + + CDSPPeakedCosineLPF w( Len2, Freq, FltAlpha ); + + fs.IsUpsample = IsUpsample; + fs.ResampleFactor = ResampleFactor; + fs.FltLatency = w.fl2; + + int FltExt; // Filter's extension due to fpclass :: elalign. + + if( IsModel ) + { + allocFilter( fs.Flt, w.FilterLen, true, &FltExt ); + + if( UseFltOrig ) + { + // Allocate a real buffer even in modeling mode since this + // filter may be copied by the filter bank. + + fs.FltOrig.alloc( w.FilterLen ); + memset( &fs.FltOrig[ 0 ], 0, + w.FilterLen * sizeof( fs.FltOrig[ 0 ])); + } + } + else + { + fs.FltOrig.alloc( w.FilterLen ); + + w.generateLPF( &fs.FltOrig[ 0 ], 1.0 ); + optimizeFIRFilter( fs.FltOrig, fs.FltLatency ); + normalizeFIRFilter( &fs.FltOrig[ 0 ], fs.FltOrig.getCapacity(), + fs.DCGain ); + + allocFilter( fs.Flt, fs.FltOrig.getCapacity(), false, &FltExt ); + copyArray( &fs.FltOrig[ 0 ], &fs.Flt[ 0 ], + fs.FltOrig.getCapacity() ); + + if( !UseFltOrig ) + { + fs.FltOrig.free(); + } + } + + if( IsUpsample ) + { + int l = fs.Flt.getCapacity() - fs.FltLatency - ResampleFactor - + FltExt; + + allocFilter( fs.PrefixDC, l, IsModel ); + allocFilter( fs.SuffixDC, fs.FltLatency, IsModel ); + + if( IsModel ) + { + return; + } + + // Create prefix and suffix "tails" used during upsampling. + + const fptype* ip = &fs.Flt[ fs.FltLatency + ResampleFactor ]; + copyArray( ip, &fs.PrefixDC[ 0 ], l ); + + while( true ) + { + ip += ResampleFactor; + l -= ResampleFactor; + + if( l <= 0 ) + { + break; + } + + addArray( ip, &fs.PrefixDC[ 0 ], l ); + } + + l = fs.FltLatency; + fptype* op = &fs.SuffixDC[ 0 ]; + copyArray( &fs.Flt[ 0 ], op, l ); + + while( true ) + { + op += ResampleFactor; + l -= ResampleFactor; + + if( l <= 0 ) + { + break; + } + + addArray( &fs.Flt[ 0 ], op, l ); + } + } + else + if( !UseFltOrig ) + { + fs.EdgePixelCount = fs.EdgePixelCountDef; + } + } + + /** + * Function adds a correction filter that tries to achieve a linear + * frequency response at all frequencies. The actual resulting response + * may feature a slight damping of the highest frequencies since a + * suitably short correction filter cannot fix steep high-frequency + * damping. + * + * This function assumes that the resizing step is currently the last + * step, even if it was not inserted yet: this allows placement of the + * correction filter both before and after the resizing step. + * + * @param Steps Filtering steps. + * @param bw Resulting bandwidth relative to the original bandwidth (which + * is 1.0), usually 1/k. Should be <= 1.0. + * @param IsPreCorrection "True" if the filtering step was already created + * and it is first in the Steps array. "True" also adds edge pixels to + * reduce edge artifacts. + * @param IsModel "True" if filtering steps modeling is performed without + * actual filter building. + */ + + void addCorrectionFilter( CFilterSteps& Steps, const double bw, + const bool IsPreCorrection, const bool IsModel ) const + { + CFilterStep& fs = ( IsPreCorrection ? Steps[ 0 ] : Steps.add() ); + fs.IsUpsample = false; + fs.ResampleFactor = 1; + fs.DCGain = 1.0; + fs.EdgePixelCount = ( IsPreCorrection ? fs.EdgePixelCountDef : 0 ); + + if( IsModel ) + { + allocFilter( fs.Flt, CDSPFIREQ :: calcFilterLength( + Params.CorrFltLen, fs.FltLatency ), true ); + + return; + } + + const int BinCount = 65; // Frequency response bins to control. + const int BinCount1 = BinCount - 1; + double curbw = 1.0; // Bandwidth of the filter at the current step. + int i; + int j; + double re; + double im; + + CBuffer< double > Bins( BinCount ); // Adjustment introduced by all + // steps at all frequencies of interest. + + for( j = 0; j < BinCount; j++ ) + { + Bins[ j ] = 1.0; + } + + const int si = ( IsPreCorrection ? 1 : 0 ); + + for( i = si; i < Steps.getItemCount() - ( si ^ 1 ); i++ ) + { + const CFilterStep& fs = Steps[ i ]; + + if( fs.IsUpsample ) + { + curbw *= fs.ResampleFactor; + + if( fs.FltOrig.getCapacity() > 0 ) + { + continue; + } + } + + const double dcg = 1.0 / fs.DCGain; // DC gain correction. + const fptype* Flt; + int FltLen; + + if( fs.ResampleFactor == 0 ) + { + Flt = fs.FltBank -> getFilter( 0 ); + FltLen = fs.FltBank -> getFilterLen(); + } + else + { + Flt = &fs.Flt[ 0 ]; + FltLen = fs.Flt.getCapacity(); + } + + // Calculate frequency response adjustment introduced by the + // filter at this step, within the bounds of bandwidth of + // interest. + + for( j = 0; j < BinCount; j++ ) + { + const double th = AVIR_PI * bw / curbw * j / BinCount1; + + calcFIRFilterResponse( Flt, FltLen, th, re, im ); + + Bins[ j ] /= sqrt( re * re + im * im ) * dcg; + } + + if( !fs.IsUpsample && fs.ResampleFactor > 1 ) + { + curbw /= fs.ResampleFactor; + } + } + + // Calculate filter. + + CDSPFIREQ EQ; + EQ.init( bw * 2.0, Params.CorrFltLen, BinCount, 0.0, bw, false, + Params.CorrFltAlpha ); + + fs.FltLatency = EQ.getFilterLatency(); + + CBuffer< double > Filter( EQ.getFilterLength() ); + EQ.buildFilter( Bins, &Filter[ 0 ]); + normalizeFIRFilter( &Filter[ 0 ], Filter.getCapacity(), 1.0 ); + optimizeFIRFilter( Filter, fs.FltLatency ); + normalizeFIRFilter( &Filter[ 0 ], Filter.getCapacity(), 1.0 ); + + allocFilter( fs.Flt, Filter.getCapacity() ); + copyArray( &Filter[ 0 ], &fs.Flt[ 0 ], Filter.getCapacity() ); + + // Print a theoretically achieved final frequency response at various + // feature sizes (from DC to 1 pixel). Values above 255 means features + // become brighter, values below 255 means features become dimmer. + +/* const double sbw = ( bw > 1.0 ? 1.0 / bw : 1.0 ); + + for( j = 0; j < BinCount; j++ ) + { + const double th = AVIR_PI * sbw * j / BinCount1; + + calcFIRFilterResponse( &fs.Flt[ 0 ], fs.Flt.getCapacity(), + th, re, im ); + + printf( "%f\n", sqrt( re * re + im * im ) / Bins[ j ] * 255 ); + } + + printf( "***\n" );*/ + } + + /** + * Function adds a sharpening filter if image is being upsized. Such + * sharpening allows to spot interpolation filter's stop-band attenuation: + * if attenuation is too weak, a "dark grid" and other artifacts may + * become visible. + * + * It is assumed that 40 decibel stop-band attenuation should be + * considered a required minimum: this allows application of (deliberately + * strong) 64X sharpening without spotting any artifacts. + * + * @param Steps Filtering steps. + * @param bw Resulting bandwidth relative to the original bandwidth (which + * is 1.0), usually 1/k. + * @param IsModel "True" if filtering steps modeling is performed without + * actual filter building. + */ + + static void addSharpenTest( CFilterSteps& Steps, const double bw, + const bool IsModel ) + { + if( bw <= 1.0 ) + { + return; + } + + const double FltLen = 10.0 * bw; + + CFilterStep& fs = Steps.add(); + fs.IsUpsample = false; + fs.ResampleFactor = 1; + fs.DCGain = 1.0; + fs.EdgePixelCount = 0; + + if( IsModel ) + { + allocFilter( fs.Flt, CDSPFIREQ :: calcFilterLength( FltLen, + fs.FltLatency ), true ); + + return; + } + + const int BinCount = 200; + CBuffer< double > Bins( BinCount ); + int Thresh = (int) round( BinCount / bw * 1.75 ); + + if( Thresh > BinCount ) + { + Thresh = BinCount; + } + + int j; + + for( j = 0; j < Thresh; j++ ) + { + Bins[ j ] = 1.0; + } + + for( j = Thresh; j < BinCount; j++ ) + { + Bins[ j ] = 256.0; + } + + CDSPFIREQ EQ; + EQ.init( bw * 2.0, FltLen, BinCount, 0.0, bw, false, 1.7 ); + + fs.FltLatency = EQ.getFilterLatency(); + + CBuffer< double > Filter( EQ.getFilterLength() ); + EQ.buildFilter( Bins, &Filter[ 0 ]); + normalizeFIRFilter( &Filter[ 0 ], Filter.getCapacity(), 1.0 ); + optimizeFIRFilter( Filter, fs.FltLatency ); + normalizeFIRFilter( &Filter[ 0 ], Filter.getCapacity(), 1.0 ); + + allocFilter( fs.Flt, Filter.getCapacity() ); + copyArray( &Filter[ 0 ], &fs.Flt[ 0 ], Filter.getCapacity() ); + +/* for( j = 0; j < BinCount; j++ ) + { + const double th = AVIR_PI * j / ( BinCount - 1 ); + double re; + double im; + + calcFIRFilterResponse( &fs.Flt[ 0 ], fs.Flt.getCapacity(), + th, re, im ); + + printf( "%f\n", sqrt( re * re + im * im )); + } + + printf( "***\n" );*/ + } + + /** + * Function builds sequence of filtering steps depending on the specified + * resizing coefficient. The last steps included are always the resizing + * step then (possibly) the correction step. + * + * @param Steps Array that receives filtering steps. + * @param[out] Vars Variables object. + * @param FltBank Filter bank to initialize and use. + * @param DCGain The overall DC gain to apply. This DC gain is applied to + * the first filtering step only (upsampling or filtering step). + * @param ModeFlags Build mode flags to use. This is a bitmap of switches + * that enable or disable certain algorithm features. + * @param IsModel "True" if filtering steps modeling is performed without + * the actual filter allocation and building. + */ + + void buildFilterSteps( CFilterSteps& Steps, CImageResizerVars& Vars, + CDSPFracFilterBankLin< fptype >& FltBank, const double DCGain, + const int ModeFlags, const bool IsModel ) const + { + Steps.clear(); + + const bool DoFltAndIntCombo = (( ModeFlags & 1 ) != 0 ); // Do filter + // and interpolator combining. + const bool ForceHiOrderInt = (( ModeFlags & 2 ) != 0 ); // Force use + // of a higher-order interpolation. + const bool UseHalfband = (( ModeFlags & 4 ) != 0 ); // Use half-band + // filter. + + const double bw = 1.0 / Vars.k; // Resulting bandwidth. + const int UpsampleFactor = ( (int) floor( Vars.k ) < 2 ? 2 : 1 ); + double IntCutoffMult; // Interpolation filter cutoff multiplier. + CFilterStep* ReuseStep; // If not NULL, resizing step should use + // this step object instead of creating a new one. + CFilterStep* ExtFltStep; // Use FltOrig of this step as the external + // filter to applied to the interpolator. + bool IsPreCorrection; // "True" if the correction filter is applied + // first. + double FltCutoff; // Cutoff frequency of the first filtering step. + double corrbw; ///< Bandwidth at the correction step. + + if( Vars.k <= 1.0 ) + { + IsPreCorrection = true; + FltCutoff = 1.0; + corrbw = 1.0; + Steps.add(); + } + else + { + IsPreCorrection = false; + FltCutoff = bw; + corrbw = bw; + } + + // Add 1 upsampling or several downsampling filters. + + if( UpsampleFactor > 1 ) + { + CFilterStep& fs = Steps.add(); + assignFilterParams( fs, true, UpsampleFactor, FltCutoff, DCGain, + DoFltAndIntCombo, IsModel ); + + IntCutoffMult = FltCutoff * 2.0 / UpsampleFactor; + ReuseStep = NULL; + ExtFltStep = ( DoFltAndIntCombo ? &fs : NULL ); + } + else + { + int DownsampleFactor; + + while( true ) + { + DownsampleFactor = (int) floor( 0.5 / FltCutoff ); + bool DoHBFltAdd; + + if( DownsampleFactor > 16 ) + { + // Add half-band filter unconditionally in order to keep + // filter lengths lower for more precise frequency + // response and less edge artifacts. + + DoHBFltAdd = true; + DownsampleFactor = 16; + } + else + { + DoHBFltAdd = ( UseHalfband && DownsampleFactor > 1 ); + } + + if( DoHBFltAdd ) + { + assignFilterParams( Steps.add(), false, DownsampleFactor, + 0.0, 1.0, false, IsModel ); + + FltCutoff *= DownsampleFactor; + } + else + { + if( DownsampleFactor < 1 ) + { + DownsampleFactor = 1; + } + + break; + } + } + + CFilterStep& fs = Steps.add(); + assignFilterParams( fs, false, DownsampleFactor, FltCutoff, + DCGain, DoFltAndIntCombo, IsModel ); + + IntCutoffMult = FltCutoff / 0.5; + + if( DoFltAndIntCombo ) + { + ReuseStep = &fs; + ExtFltStep = &fs; + } + else + { + IntCutoffMult *= DownsampleFactor; + ReuseStep = NULL; + ExtFltStep = NULL; + } + } + + // Insert resizing and correction steps. + + CFilterStep& fs = ( ReuseStep == NULL ? Steps.add() : *ReuseStep ); + + Vars.ResizeStep = Steps.getItemCount() - 1; + fs.IsUpsample = false; + fs.ResampleFactor = 0; + fs.DCGain = ( ExtFltStep == NULL ? 1.0 : ExtFltStep -> DCGain ); + + initFilterBank( FltBank, IntCutoffMult, ForceHiOrderInt, + ( ExtFltStep == NULL ? fs.FltOrig : ExtFltStep -> FltOrig )); + + if( FltBank == FixedFilterBank ) + { + fs.FltBank = (CDSPFracFilterBankLin< fptype >*) &FixedFilterBank; + } + else + { + fs.FltBank = &FltBank; + } + + addCorrectionFilter( Steps, corrbw, IsPreCorrection, IsModel ); + + //addSharpenTest( Steps, bw, IsModel ); + } + + /** + * Function extends *this upsampling step so that it produces more + * upsampled pixels that cover the prefix and suffix needs of the next + * step. After the call to this function the InPrefix and InSuffix + * variables of the next step will be set to zero. + * + * @param fs Upsampling filtering step. + * @param NextStep The next step structure. + */ + + static void extendUpsample( CFilterStep& fs, CFilterStep& NextStep ) + { + fs.InPrefix = ( NextStep.InPrefix + fs.ResampleFactor - 1 ) / + fs.ResampleFactor; + + fs.OutPrefix += fs.InPrefix * fs.ResampleFactor; + NextStep.InPrefix = 0; + + fs.InSuffix = ( NextStep.InSuffix + fs.ResampleFactor - 1 ) / + fs.ResampleFactor; + + fs.OutSuffix += fs.InSuffix * fs.ResampleFactor; + NextStep.InSuffix = 0; + } + + /** + * Function fills resizing step's RPosBuf array, excluding the actual + * "ftp" pointers and "SrcOffs" offsets. + * + * This array should be cleared if the resizing step or offset were + * changed. Otherwise this function only fills the elements required to + * cover resizing step's OutLen. + * + * This function is called by the updateFilterStepBuffers() function. + * + * @param fs Resizing step. + * @param Vars Variables object. + */ + + static void fillRPosBuf( CFilterStep& fs, const CImageResizerVars& Vars ) + { + const int PrevLen = fs.RPosBuf -> getCapacity(); + + if( fs.OutLen > PrevLen ) + { + fs.RPosBuf -> increaseCapacity( fs.OutLen ); + } + + typename CFilterStep :: CResizePos* rpos = &(*fs.RPosBuf)[ PrevLen ]; + const int FracCount = fs.FltBank -> getFracCount(); + const double o = Vars.o; + const double k = Vars.k; + int i; + + for( i = PrevLen; i < fs.OutLen; i++ ) + { + const double SrcPos = o + k * i; + const int SrcPosInt = (int) floor( SrcPos ); + const double x = ( SrcPos - SrcPosInt ) * FracCount; + const int fti = (int) x; + rpos -> x = (typename fpclass :: fptypeatom) ( x - fti ); + rpos -> fti = fti; + rpos -> SrcPosInt = SrcPosInt; + rpos++; + } + } + + /** + * Function updates filtering step buffer lengths depending on the + * specified source and new scanline lengths. This function should be + * called after the buildFilterSteps() function. + * + * @param Steps Array that receives filtering steps. + * @param[out] Vars Variables object, will receive buffer size and length. + * This function expects "k" and "o" variable values that will be + * adjusted by this function. + * @param RPosBufArray Resizing position buffers array, used to obtain + * buffer to initialize and use (will be reused if it is already fully or + * partially filled). + * @param SrcLen Source scanline's length in pixels. + * @param NewLen New scanline's length in pixels. + */ + + static void updateFilterStepBuffers( CFilterSteps& Steps, + CImageResizerVars& Vars, + typename CFilterStep :: CRPosBufArray& RPosBufArray, int SrcLen, + const int NewLen ) + { + int upstep = -1; + int InBuf = 0; + int i; + + for( i = 0; i < Steps.getItemCount(); i++ ) + { + CFilterStep& fs = Steps[ i ]; + + fs.Vars = &Vars; + fs.InLen = SrcLen; + fs.InBuf = InBuf; + fs.OutBuf = ( InBuf + 1 ) & 1; + + if( fs.IsUpsample ) + { + upstep = i; + Vars.k *= fs.ResampleFactor; + Vars.o *= fs.ResampleFactor; + fs.InPrefix = 0; + fs.InSuffix = 0; + fs.OutLen = fs.InLen * fs.ResampleFactor; + fs.OutPrefix = fs.FltLatency; + fs.OutSuffix = fs.Flt.getCapacity() - fs.FltLatency - + fs.ResampleFactor; + + int l0 = fs.OutPrefix + fs.OutLen + fs.OutSuffix; + int l = fs.InLen * fs.ResampleFactor + + fs.SuffixDC.getCapacity(); + + if( l > l0 ) + { + fs.OutSuffix += l - l0; + } + + l0 = fs.OutLen + fs.OutSuffix; + + if( fs.PrefixDC.getCapacity() > l0 ) + { + fs.OutSuffix += fs.PrefixDC.getCapacity() - l0; + } + } + else + if( fs.ResampleFactor == 0 ) + { + const int FilterLenD2 = fs.FltBank -> getFilterLen() / 2; + const int FilterLenD21 = FilterLenD2 - 1; + + const int ResizeLPix = (int) floor( Vars.o ) - FilterLenD21; + fs.InPrefix = ( ResizeLPix < 0 ? -ResizeLPix : 0 ); + const int ResizeRPix = (int) floor( Vars.o + + ( NewLen - 1 ) * Vars.k ) + FilterLenD2 + 1; + + fs.InSuffix = ( ResizeRPix > fs.InLen ? + ResizeRPix - fs.InLen : 0 ); + + fs.OutLen = NewLen; + fs.RPosBuf = &RPosBufArray.getRPosBuf( Vars.k, Vars.o, + fs.FltBank -> getFracCount() ); + + fillRPosBuf( fs, Vars ); + } + else + { + Vars.k /= fs.ResampleFactor; + Vars.o /= fs.ResampleFactor; + Vars.o += fs.EdgePixelCount; + + fs.InPrefix = fs.FltLatency; + fs.InSuffix = fs.Flt.getCapacity() - fs.FltLatency - 1; + + // Additionally extend OutLen to produce more precise edge + // pixels. + + fs.OutLen = ( fs.InLen + fs.ResampleFactor - 1 ) / + fs.ResampleFactor + fs.EdgePixelCount; + + fs.InSuffix += ( fs.OutLen - 1 ) * fs.ResampleFactor + 1 - + fs.InLen; + + fs.InPrefix += fs.EdgePixelCount * fs.ResampleFactor; + fs.OutLen += fs.EdgePixelCount; + } + + InBuf = fs.OutBuf; + SrcLen = fs.OutLen; + } + + Steps[ Steps.getItemCount() - 1 ].OutBuf = 2; + + if( upstep != -1 ) + { + extendUpsample( Steps[ upstep ], Steps[ upstep + 1 ]); + } + } + + /** + * Function calculates an optimal intermediate buffer length that will + * cover all needs of the specified filtering steps. This function should + * be called after the updateFilterStepBuffers() function. + * + * Function also updates resizing step's RPosBuf pointers to the filter + * bank and SrcOffs values. + * + * @param Steps Filtering steps. + * @param[out] Vars Variables object, will receive buffer size and length. + * @param ResElIncr Resulting (final) element increment, used to produce + * de-interleaved result. For horizontal processing this value is equal + * to last step's OutLen, for vertical processing this value is equal to + * resulting image's width. + */ + + static void updateBufLenAndRPosPtrs( CFilterSteps& Steps, + CImageResizerVars& Vars, const int ResElIncr ) + { + int MaxPrefix[ 2 ] = { 0, 0 }; + int MaxLen[ 2 ] = { 0, 0 }; + int i; + + for( i = 0; i < Steps.getItemCount(); i++ ) + { + CFilterStep& fs = Steps[ i ]; + const int ib = fs.InBuf; + + if( fs.InPrefix > MaxPrefix[ ib ]) + { + MaxPrefix[ ib ] = fs.InPrefix; + } + + int l = fs.InLen + fs.InSuffix; + + if( l > MaxLen[ ib ]) + { + MaxLen[ ib ] = l; + } + + fs.InElIncr = fs.InPrefix + l; + + if( fs.OutBuf == 2 ) + { + break; + } + + const int ob = fs.OutBuf; + + if( fs.IsUpsample ) + { + if( fs.OutPrefix > MaxPrefix[ ob ]) + { + MaxPrefix[ ob ] = fs.OutPrefix; + } + + l = fs.OutLen + fs.OutSuffix; + + if( l > MaxLen[ ob ]) + { + MaxLen[ ob ] = l; + } + } + else + { + if( fs.OutLen > MaxLen[ ob ]) + { + MaxLen[ ob ] = fs.OutLen; + } + } + } + + // Update OutElIncr values of all steps. + + for( i = 0; i < Steps.getItemCount(); i++ ) + { + CFilterStep& fs = Steps[ i ]; + + if( fs.OutBuf == 2 ) + { + fs.OutElIncr = ResElIncr; + break; + } + + CFilterStep& fs2 = Steps[ i + 1 ]; + + if( fs.IsUpsample ) + { + fs.OutElIncr = fs.OutPrefix + fs.OutLen + fs.OutSuffix; + + if( fs.OutElIncr > fs2.InElIncr ) + { + fs2.InElIncr = fs.OutElIncr; + } + else + { + fs.OutElIncr = fs2.InElIncr; + } + } + else + { + fs.OutElIncr = fs2.InElIncr; + } + } + + // Update temporary buffer's length. + + for( i = 0; i < 2; i++ ) + { + Vars.BufLen[ i ] = MaxPrefix[ i ] + MaxLen[ i ]; + Vars.BufOffs[ i ] = MaxPrefix[ i ]; + + if( Vars.packmode == 0 ) + { + Vars.BufOffs[ i ] *= Vars.ElCount; + } + + Vars.BufLen[ i ] *= Vars.ElCount; + } + + // Update RPosBuf pointers and SrcOffs. + + CFilterStep& fs = Steps[ Vars.ResizeStep ]; + typename CFilterStep :: CResizePos* rpos = &(*fs.RPosBuf)[ 0 ]; + const int em = ( fpclass :: packmode == 0 ? Vars.ElCount : 1 ); + const int FilterLenD21 = fs.FltBank -> getFilterLen() / 2 - 1; + + for( i = 0; i < fs.OutLen; i++ ) + { + rpos -> ftp = fs.FltBank -> getFilter( rpos -> fti ); + rpos -> SrcOffs = ( rpos -> SrcPosInt - FilterLenD21 ) * em; + rpos++; + } + } + + /** + * Function modifies the overall (DC) gain of the correction filter in the + * pre-built filtering steps array. + * + * @param Steps Filtering steps. + * @param m Multiplier to apply to the correction filter. + */ + + void modifyCorrFilterDCGain( CFilterSteps& Steps, const double m ) const + { + CBuffer< fptype >* Flt; + const int z = Steps.getItemCount() - 1; + + if( !Steps[ z ].IsUpsample && Steps[ z ].ResampleFactor == 1 ) + { + Flt = &Steps[ z ].Flt; + } + else + { + Flt = &Steps[ 0 ].Flt; + } + + int i; + + for( i = 0; i < Flt -> getCapacity(); i++ ) + { + (*Flt)[ i ] = (fptype) ( (double) (*Flt)[ i ] * m ); + } + } + + /** + * Function builds a map of used fractional delay filters based on the + * resizing positions buffer. + * + * @param fs Resizing step. + * @param[out] UsedFracMap Map of used fractional delay filters. + */ + + static void fillUsedFracMap( const CFilterStep& fs, + CBuffer< uint8_t >& UsedFracMap ) + { + const int FracCount = fs.FltBank -> getFracCount(); + UsedFracMap.increaseCapacity( FracCount, false ); + memset( &UsedFracMap[ 0 ], 0, FracCount * sizeof( UsedFracMap[ 0 ])); + + typename CFilterStep :: CResizePos* rpos = &(*fs.RPosBuf)[ 0 ]; + int i; + + for( i = 0; i < fs.OutLen; i++ ) + { + UsedFracMap[ rpos -> fti ] |= 1; + rpos++; + } + } + + /** + * Function calculates the overall filtering steps complexity per + * scanline. Each complexity unit corresponds to a single multiply-add + * operation. Data copy and pointer math operations are not included in + * this calculation, it is assumed that they correlate to the multiply-add + * operations. Calculation also does not include final rounding, dithering + * and clamping operations since they cannot be optimized out anyway. + * + * Calculation of the CRPosBuf buffer is not included since it cannot be + * avoided. + * + * This function should be called after the updateFilterStepBuffers() + * function. + * + * @param Steps Filtering steps array. + * @param Vars Variables object. + * @param UsedFracMap The map of used fractional delay filters. + * @param ScanlineCount Scanline count. + */ + + static int calcComplexity( const CFilterSteps& Steps, + const CImageResizerVars& Vars, const CBuffer< uint8_t >& UsedFracMap, + const int ScanlineCount ) + { + int fcnum; // Filter complexity multiplier numerator. + int fcdenom; // Filter complexity multiplier denominator. + + if( Vars.packmode != 0 ) + { + fcnum = 1; + fcdenom = 1; + } + else + { + // In interleaved processing mode, filters require 1 less + // multiplication per 2 multiply-add instructions. + + fcnum = 3; + fcdenom = 4; + } + + int s = 0; // Complexity per one scanline. + int s2 = 0; // Complexity per all scanlines. + int i; + + for( i = 0; i < Steps.getItemCount(); i++ ) + { + const CFilterStep& fs = Steps[ i ]; + + s2 += 65 * fs.Flt.getCapacity(); // Filter creation complexity. + + if( fs.IsUpsample ) + { + if( fs.FltOrig.getCapacity() > 0 ) + { + continue; + } + + s += ( fs.Flt.getCapacity() * + ( fs.InPrefix + fs.InLen + fs.InSuffix ) + + fs.SuffixDC.getCapacity() + fs.PrefixDC.getCapacity() ) * + Vars.ElCount; + } + else + if( fs.ResampleFactor == 0 ) + { + s += fs.FltBank -> getFilterLen() * + ( fs.FltBank -> getOrder() + Vars.ElCount ) * fs.OutLen; + + s2 += fs.FltBank -> calcInitComplexity( UsedFracMap ); + } + else + { + s += fs.Flt.getCapacity() * Vars.ElCount * fs.OutLen * + fcnum / fcdenom; + } + } + + return( s + s2 / ScanlineCount ); + } + + /** + * @brief Thread-isolated data used for scanline processing. + * + * This structure holds data necessary for image's horizontal or vertical + * scanline processing, including scanline processing queue. + * + * @tparam Tin Source element data type. Intermediate buffers store data + * in floating point format. + * @tparam Tout Destination element data type. Intermediate buffers store + * data in floating point format. + */ + + template< class Tin, class Tout > + class CThreadData : public CImageResizerThreadPool :: CWorkload + { + public: + virtual void process() + { + processScanlineQueue(); + } + + /** + * This enumeration lists possible scanline operations. + */ + + enum EScanlineOperation + { + sopResizeH, ///< Resize horizontal scanline. + ///< + sopResizeV, ///< Resize vertical scanline. + ///< + sopDitherAndUnpackH, ///< Dither and unpack horizontal scanline. + ///< + sopUnpackH ///< Unpack horizontal scanline. + ///< + }; + + /** + * Function initializes *this thread data object and assigns certain + * variables provided by the higher level code. + * + * @param aThreadIndex Index of this thread data (0-based). + * @param aThreadCount Total number of threads used during processing. + * @param aSteps Filtering steps. + * @param aVars Image resizer variables. + */ + + void init( const int aThreadIndex, const int aThreadCount, + const CFilterSteps& aSteps, const CImageResizerVars& aVars ) + { + ThreadIndex = aThreadIndex; + ThreadCount = aThreadCount; + Steps = &aSteps; + Vars = &aVars; + } + + /** + * Function initializes scanline processing queue, and updates + * capacities of intermediate buffers. + * + * @param aOp Operation to perform over scanline. + * @param TotalLines The total number of scanlines that will be + * processed by all threads. + * @param aSrcLen Source scanline length in pixels. + * @param aSrcIncr Source scanline buffer increment. Ignored in + * horizontal scanline processing. + * @param aResIncr Resulting scanline buffer increment. Ignored in + * horizontal scanline processing. + */ + + void initScanlineQueue( const EScanlineOperation aOp, + const int TotalLines, const int aSrcLen, const int aSrcIncr = 0, + const int aResIncr = 0 ) + { + const int l = Vars -> BufLen[ 0 ] + Vars -> BufLen[ 1 ]; + + if( Bufs.getCapacity() < l ) + { + Bufs.alloc( l, fpclass :: fpalign ); + } + + BufPtrs[ 0 ] = Bufs + Vars -> BufOffs[ 0 ]; + BufPtrs[ 1 ] = Bufs + Vars -> BufLen[ 0 ] + Vars -> BufOffs[ 1 ]; + + int j; + int ml = 0; + + for( j = 0; j < Steps -> getItemCount(); j++ ) + { + const CFilterStep& fs = (*Steps)[ j ]; + + if( fs.ResampleFactor == 0 && + ml < fs.FltBank -> getFilterLen() ) + { + ml = fs.FltBank -> getFilterLen(); + } + } + + TmpFltBuf.alloc( ml, fpclass :: fpalign ); + ScanlineOp = aOp; + SrcLen = aSrcLen; + SrcIncr = aSrcIncr; + ResIncr = aResIncr; + QueueLen = 0; + Queue.increaseCapacity(( TotalLines + ThreadCount - 1 ) / + ThreadCount, false ); + } + + /** + * Function adds a scanline to the queue buffer. The + * initScanlineQueue() function should be called before calling this + * function. The number of calls to this add function should not + * exceed the TotalLines spread over all threads. + * + * @param SrcBuf Source scanline buffer. + * @param ResBuf Resulting scanline buffer. + */ + + void addScanlineToQueue( void* const SrcBuf, void* const ResBuf ) + { + Queue[ QueueLen ].SrcBuf = SrcBuf; + Queue[ QueueLen ].ResBuf = ResBuf; + QueueLen++; + } + + /** + * Function processes all queued scanlines. + */ + + void processScanlineQueue() + { + int i; + + switch( ScanlineOp ) + { + case sopResizeH: + { + for( i = 0; i < QueueLen; i++ ) + { + resizeScanlineH( (Tin*) Queue[ i ].SrcBuf, + (fptype*) Queue[ i ].ResBuf ); + } + + break; + } + + case sopResizeV: + { + for( i = 0; i < QueueLen; i++ ) + { + resizeScanlineV( (fptype*) Queue[ i ].SrcBuf, + (fptype*) Queue[ i ].ResBuf ); + } + + break; + } + + case sopDitherAndUnpackH: + { + if( Vars -> UseSRGBGamma ) + { + for( i = 0; i < QueueLen; i++ ) + { + CFilterStep :: applySRGBGamma( + (fptype*) Queue[ i ].SrcBuf, SrcLen, *Vars ); + + Ditherer.dither( (fptype*) Queue[ i ].SrcBuf ); + + CFilterStep :: unpackScanline( + (fptype*) Queue[ i ].SrcBuf, + (Tout*) Queue[ i ].ResBuf, SrcLen, *Vars ); + } + } + else + { + for( i = 0; i < QueueLen; i++ ) + { + Ditherer.dither( (fptype*) Queue[ i ].SrcBuf ); + + CFilterStep :: unpackScanline( + (fptype*) Queue[ i ].SrcBuf, + (Tout*) Queue[ i ].ResBuf, SrcLen, *Vars ); + } + } + + break; + } + + case sopUnpackH: + { + if( Vars -> UseSRGBGamma ) + { + for( i = 0; i < QueueLen; i++ ) + { + CFilterStep :: applySRGBGamma( + (fptype*) Queue[ i ].SrcBuf, SrcLen, *Vars ); + + CFilterStep :: unpackScanline( + (fptype*) Queue[ i ].SrcBuf, + (Tout*) Queue[ i ].ResBuf, SrcLen, *Vars ); + } + } + else + { + for( i = 0; i < QueueLen; i++ ) + { + CFilterStep :: unpackScanline( + (fptype*) Queue[ i ].SrcBuf, + (Tout*) Queue[ i ].ResBuf, SrcLen, *Vars ); + } + } + + break; + } + } + } + + /** + * Function returns ditherer object associated with *this thread data + * object. + */ + + CDitherer& getDitherer() + { + return( Ditherer ); + } + + private: + int ThreadIndex; ///< Thread index. + ///< + int ThreadCount; ///< Thread count. + ///< + const CFilterSteps* Steps; ///< Filtering steps. + ///< + const CImageResizerVars* Vars; ///< Image resizer variables. + ///< + CBuffer< fptype > Bufs; ///< Flip-flop intermediate buffers. + ///< + fptype* BufPtrs[ 3 ]; ///< Flip-flop buffer pointers (referenced by + ///< filtering step's InBuf and OutBuf indices). + ///< + CBuffer< fptype > TmpFltBuf; ///< Temporary buffer used in the + ///< doResize() function, aligned by fpclass :: fpalign. + ///< + EScanlineOperation ScanlineOp; ///< Operation to perform over + ///< scanline. + ///< + int SrcLen; ///< Source scanline length in the last queue. + ///< + int SrcIncr; ///< Source scanline buffer increment in the last queue. + ///< + int ResIncr; ///< Resulting scanline buffer increment in the last + ///< queue. + ///< + CDitherer Ditherer; ///< Ditherer object to use. + ///< + + /** + * @brief Scanline processing queue item. + * + * Scanline processing queue item. + */ + + struct CQueueItem + { + void* SrcBuf; ///< Source scanline buffer, will by typecasted to + ///< Tin or fptype*. + ///< + void* ResBuf; ///< Resulting scanline buffer, will by typecasted + ///< to Tout or fptype*. + ///< + }; + + CBuffer< CQueueItem > Queue; ///< Scanline processing queue. + ///< + int QueueLen; ///< Queue length. + ///< + + /** + * Function resizes a single horizontal scanline. + * + * @param SrcBuf Source scanline buffer. Can be either horizontal or + * vertical. + * @param ResBuf Resulting scanline buffer. + */ + + void resizeScanlineH( const Tin* const SrcBuf, fptype* const ResBuf ) + { + (*Steps)[ 0 ].packScanline( SrcBuf, BufPtrs[ 0 ], SrcLen ); + BufPtrs[ 2 ] = ResBuf; + int j; + + for( j = 0; j < Steps -> getItemCount(); j++ ) + { + const CFilterStep& fs = (*Steps)[ j ]; + fs.prepareInBuf( BufPtrs[ fs.InBuf ]); + const int DstIncr = + ( Vars -> packmode == 0 ? Vars -> ElCount : 1 ); + + if( fs.ResampleFactor != 0 ) + { + if( fs.IsUpsample ) + { + fs.doUpsample( BufPtrs[ fs.InBuf ], + BufPtrs[ fs.OutBuf ]); + } + else + { + fs.doFilter( BufPtrs[ fs.InBuf ], + BufPtrs[ fs.OutBuf ], DstIncr ); + } + } + else + { + fs.doResize( BufPtrs[ fs.InBuf ], BufPtrs[ fs.OutBuf ], + DstIncr, TmpFltBuf ); + } + } + } + + /** + * Function resizes a single vertical scanline. + * + * @param SrcBuf Source scanline buffer. Can be either horizontal or + * vertical. + * @param ResBuf Resulting scanline buffer. + */ + + void resizeScanlineV( const fptype* const SrcBuf, + fptype* const ResBuf ) + { + (*Steps)[ 0 ].convertVtoH( SrcBuf, BufPtrs[ 0 ], SrcLen, + SrcIncr ); + + BufPtrs[ 2 ] = ResBuf; + int j; + + for( j = 0; j < Steps -> getItemCount(); j++ ) + { + const CFilterStep& fs = (*Steps)[ j ]; + fs.prepareInBuf( BufPtrs[ fs.InBuf ]); + const int DstIncr = ( fs.OutBuf == 2 ? ResIncr : + ( Vars -> packmode == 0 ? Vars -> ElCount : 1 )); + + if( fs.ResampleFactor != 0 ) + { + if( fs.IsUpsample ) + { + fs.doUpsample( BufPtrs[ fs.InBuf ], + BufPtrs[ fs.OutBuf ]); + } + else + { + fs.doFilter( BufPtrs[ fs.InBuf ], + BufPtrs[ fs.OutBuf ], DstIncr ); + } + } + else + { + fs.doResize( BufPtrs[ fs.InBuf ], BufPtrs[ fs.OutBuf ], + DstIncr, TmpFltBuf ); + } + } + } + }; +}; + +#undef AVIR_PI +#undef AVIR_PId2 + +} // namespace avir + +#endif // AVIR_CIMAGERESIZER_INCLUDED diff --git a/third_party/avir/avir.mk b/third_party/avir/avir.mk new file mode 100644 index 00000000..dff90ea8 --- /dev/null +++ b/third_party/avir/avir.mk @@ -0,0 +1,71 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += THIRD_PARTY_AVIR + +THIRD_PARTY_AVIR_ARTIFACTS += THIRD_PARTY_AVIR_A +THIRD_PARTY_AVIR = $(THIRD_PARTY_AVIR_A_DEPS) $(THIRD_PARTY_AVIR_A) +THIRD_PARTY_AVIR_A = o/$(MODE)/third_party/avir/avir.a +THIRD_PARTY_AVIR_A_CHECKS = $(THIRD_PARTY_AVIR_A).pkg +THIRD_PARTY_AVIR_A_FILES := $(wildcard third_party/avir/*) +THIRD_PARTY_AVIR_A_SRCS_S = $(filter %.S,$(THIRD_PARTY_AVIR_A_FILES)) +THIRD_PARTY_AVIR_A_SRCS_C = $(filter %.c,$(THIRD_PARTY_AVIR_A_FILES)) +THIRD_PARTY_AVIR_A_SRCS_X = $(filter %.cc,$(THIRD_PARTY_AVIR_A_FILES)) + +THIRD_PARTY_AVIR_A_HDRS = \ + $(filter %.h,$(THIRD_PARTY_AVIR_A_FILES)) \ + $(filter %.hpp,$(THIRD_PARTY_AVIR_A_FILES)) + +THIRD_PARTY_AVIR_A_SRCS = \ + $(THIRD_PARTY_AVIR_A_SRCS_S) \ + $(THIRD_PARTY_AVIR_A_SRCS_C) \ + $(THIRD_PARTY_AVIR_A_SRCS_X) + +THIRD_PARTY_AVIR_A_OBJS = \ + $(THIRD_PARTY_AVIR_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(THIRD_PARTY_AVIR_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(THIRD_PARTY_AVIR_A_SRCS_C:%.c=o/$(MODE)/%.o) \ + $(THIRD_PARTY_AVIR_A_SRCS_X:%.cc=o/$(MODE)/%.o) + +THIRD_PARTY_AVIR_A_DIRECTDEPS = \ + DSP_CORE \ + LIBC_NEXGEN32E \ + LIBC_BITS \ + LIBC_MEM \ + LIBC_CALLS \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_FMT \ + LIBC_UNICODE \ + LIBC_LOG \ + LIBC_TINYMATH + +$(THIRD_PARTY_AVIR_A).pkg: \ + $(THIRD_PARTY_AVIR_A_OBJS) \ + $(foreach x,$(THIRD_PARTY_AVIR_A_DIRECTDEPS),$($(x)_A).pkg) + +$(THIRD_PARTY_AVIR_A): \ + third_party/avir/ \ + $(THIRD_PARTY_AVIR_A).pkg \ + $(THIRD_PARTY_AVIR_A_OBJS) + +#o/$(MODE)/third_party/avir/lanczos1b.o: \ + CXX = clang++-10 + +o/$(MODE)/third_party/avir/lanczos1b.o \ +o/$(MODE)/third_party/avir/lanczos.o: \ + OVERRIDE_CXXFLAGS += \ + $(MATHEMATICAL) + +THIRD_PARTY_AVIR_A_DEPS := \ + $(call uniq,$(foreach x,$(THIRD_PARTY_AVIR_A_DIRECTDEPS),$($(x)))) + +THIRD_PARTY_AVIR_LIBS = $(foreach x,$(THIRD_PARTY_AVIR_ARTIFACTS),$($(x))) +THIRD_PARTY_AVIR_SRCS = $(foreach x,$(THIRD_PARTY_AVIR_ARTIFACTS),$($(x)_SRCS)) +THIRD_PARTY_AVIR_HDRS = $(foreach x,$(THIRD_PARTY_AVIR_ARTIFACTS),$($(x)_HDRS)) +THIRD_PARTY_AVIR_CHECKS = $(foreach x,$(THIRD_PARTY_AVIR_ARTIFACTS),$($(x)_CHECKS)) +THIRD_PARTY_AVIR_OBJS = $(foreach x,$(THIRD_PARTY_AVIR_ARTIFACTS),$($(x)_OBJS)) +THIRD_PARTY_AVIR_TESTS = $(foreach x,$(THIRD_PARTY_AVIR_ARTIFACTS),$($(x)_TESTS)) + +.PHONY: o/$(MODE)/third_party/avir +o/$(MODE)/third_party/avir: $(THIRD_PARTY_AVIR_A_CHECKS) diff --git a/third_party/avir/avir1.h b/third_party/avir/avir1.h new file mode 100644 index 00000000..541811b8 --- /dev/null +++ b/third_party/avir/avir1.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_AVIR1_H_ +#define COSMOPOLITAN_THIRD_PARTY_AVIR_AVIR1_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct avir1 { + void *p; +}; + +void avir1init(struct avir1 *self); +void avir1free(struct avir1 *self); +void avir1(struct avir1 *resizer, size_t dyn, size_t dxn, void *dst, + size_t dstsize, size_t syn, size_t sxn, size_t ssw, const void *src, + size_t srcsize); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_AVIR1_H_ */ diff --git a/third_party/avir/avir_dil.h b/third_party/avir/avir_dil.h new file mode 100644 index 00000000..e7047312 --- /dev/null +++ b/third_party/avir/avir_dil.h @@ -0,0 +1,1013 @@ +/* clang-format off */ +//$ nobt +//$ nocpp + +/** + * @file avir_dil.h + * + * @brief Inclusion file for de-interleaved image resizing functions. + * + * This file includes the "CImageResizerFilterStepDIL" class which implements + * image resizing functions in de-interleaved mode. + * + * AVIR Copyright (c) 2015-2019 Aleksey Vaneev + */ + +namespace avir { + +/** + * @brief De-interleaved filtering steps implementation class. + * + * This class implements scanline filtering functions in de-interleaved mode. + * This means that pixels are processed in groups. + * + * @tparam fptype Floating point type to use for storing pixel elements. + * SIMD types cannot be used. + * @tparam fptypesimd The SIMD type used to store a pack of "fptype" values. + */ + +template< class fptype, class fptypesimd > +class CImageResizerFilterStepDIL : + public CImageResizerFilterStep< fptype, fptype > +{ +public: + using CImageResizerFilterStep< fptype, fptype > :: IsUpsample; + using CImageResizerFilterStep< fptype, fptype > :: ResampleFactor; + using CImageResizerFilterStep< fptype, fptype > :: Flt; + using CImageResizerFilterStep< fptype, fptype > :: FltOrig; + using CImageResizerFilterStep< fptype, fptype > :: FltLatency; + using CImageResizerFilterStep< fptype, fptype > :: Vars; + using CImageResizerFilterStep< fptype, fptype > :: InLen; + using CImageResizerFilterStep< fptype, fptype > :: InPrefix; + using CImageResizerFilterStep< fptype, fptype > :: InSuffix; + using CImageResizerFilterStep< fptype, fptype > :: InElIncr; + using CImageResizerFilterStep< fptype, fptype > :: OutLen; + using CImageResizerFilterStep< fptype, fptype > :: OutPrefix; + using CImageResizerFilterStep< fptype, fptype > :: OutSuffix; + using CImageResizerFilterStep< fptype, fptype > :: OutElIncr; + using CImageResizerFilterStep< fptype, fptype > :: PrefixDC; + using CImageResizerFilterStep< fptype, fptype > :: SuffixDC; + using CImageResizerFilterStep< fptype, fptype > :: RPosBuf; + using CImageResizerFilterStep< fptype, fptype > :: FltBank; + using CImageResizerFilterStep< fptype, fptype > :: EdgePixelCount; + + /** + * Function performs "packing" (de-interleaving) of a scanline and type + * conversion. If required, the sRGB gamma correction is applied. + * + * @param ip0 Input scanline, pixel elements interleaved. + * @param op0 Output scanline, pixel elements are grouped, "l" elements + * apart. + * @param l The number of pixels to "pack". + */ + + template< class Tin > + void packScanline( const Tin* const ip0, fptype* const op0, + const int l ) const + { + const int ElCount = Vars -> ElCount; + int j; + + if( !Vars -> UseSRGBGamma ) + { + for( j = 0; j < ElCount; j++ ) + { + const Tin* ip = ip0 + j; + fptype* const op = op0 + j * InElIncr; + int i; + + for( i = 0; i < l; i++ ) + { + op[ i ] = (fptype) *ip; + ip += ElCount; + } + } + } + else + { + const fptype gm = (fptype) Vars -> InGammaMult; + + for( j = 0; j < ElCount; j++ ) + { + const Tin* ip = ip0 + j; + fptype* const op = op0 + j * InElIncr; + int i; + + for( i = 0; i < l; i++ ) + { + op[ i ] = convertSRGB2Lin( (fptype) *ip * gm ); + ip += ElCount; + } + } + } + } + + /** + * Function applies Linear to sRGB gamma correction to the specified + * scanline. + * + * @param p Scanline. + * @param l The number of pixels to de-linearize. + * @param Vars0 Image resizing-related variables. + */ + + static void applySRGBGamma( fptype* const p0, const int l, + const CImageResizerVars& Vars0 ) + { + const int ElCount = Vars0.ElCount; + const fptype gm = (fptype) Vars0.OutGammaMult; + int j; + + for( j = 0; j < ElCount; j++ ) + { + fptype* const p = p0 + j * l; + int i; + + for( i = 0; i < l; i++ ) + { + p[ i ] = convertLin2SRGB( p[ i ]) * gm; + } + } + } + + /** + * Function converts vertical scanline to horizontal scanline. This + * function is called by the image resizer when image is resized + * vertically. This means that the vertical scanline is stored in the + * same format produced by the packScanline() and maintained by other + * filtering functions. + * + * @param ip Input vertical scanline, pixel elements are grouped, SrcLen + * elements apart. + * @param op Output buffer (temporary buffer used during resizing), pixel + * elements are grouped, "l" elements apart. + * @param SrcLen The number of pixels in the input scanline, also used to + * calculate input buffer increment. + * @param SrcIncr Input buffer increment to the next vertical pixel. + */ + + void convertVtoH( const fptype* ip, fptype* op, const int SrcLen, + const int SrcIncr ) const + { + const int ElCount = Vars -> ElCount; + const int SrcElIncr = SrcIncr / ElCount; + const int ips1 = SrcElIncr; + const int ips2 = SrcElIncr * 2; + const int ips3 = SrcElIncr * 3; + const int ops1 = InElIncr; + const int ops2 = InElIncr * 2; + const int ops3 = InElIncr * 3; + int j; + + if( ElCount == 1 ) + { + for( j = 0; j < SrcLen; j++ ) + { + op[ 0 ] = ip[ 0 ]; + ip += SrcIncr; + op++; + } + } + else + if( ElCount == 4 ) + { + for( j = 0; j < SrcLen; j++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ ops1 ] = ip[ ips1 ]; + op[ ops2 ] = ip[ ips2 ]; + op[ ops3 ] = ip[ ips3 ]; + ip += SrcIncr; + op++; + } + } + else + if( ElCount == 3 ) + { + for( j = 0; j < SrcLen; j++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ ops1 ] = ip[ ips1 ]; + op[ ops2 ] = ip[ ips2 ]; + ip += SrcIncr; + op++; + } + } + else + if( ElCount == 2 ) + { + for( j = 0; j < SrcLen; j++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ ops1 ] = ip[ ips1 ]; + ip += SrcIncr; + op++; + } + } + } + + /** + * Function performs "unpacking" of a scanline and type conversion + * (truncation is used when floating point is converted to integer). + * The unpacking function assumes that scanline is stored in the style + * produced by the packScanline() function. + * + * @param ip0 Input scanline, pixel elements are grouped, "l" elements + * apart. + * @param op0 Output scanline, pixel elements are interleaved. + * @param l The number of pixels to "unpack". + * @param Vars0 Image resizing-related variables. ElCount is assumed to be + * equal to ElCountIO. + */ + + template< class Tout > + static void unpackScanline( const fptype* const ip0, Tout* const op0, + const int l, const CImageResizerVars& Vars0 ) + { + const int ElCount = Vars0.ElCount; + int j; + + for( j = 0; j < ElCount; j++ ) + { + const fptype* const ip = ip0 + j * l; + Tout* op = op0 + j; + int i; + + for( i = 0; i < l; i++ ) + { + *op = (Tout) ip[ i ]; + op += ElCount; + } + } + } + + /** + * Function prepares input scanline buffer for *this filtering step. + * Left- and right-most pixels are replicated to make sure no buffer + * overrun happens. Such approach also allows to bypass any pointer + * range checks. + * + * @param Src Source buffer. + */ + + void prepareInBuf( fptype* Src ) const + { + if( IsUpsample || InPrefix + InSuffix == 0 ) + { + return; + } + + int j; + + for( j = 0; j < Vars -> ElCount; j++ ) + { + replicateArray( Src, 1, Src - InPrefix, InPrefix, 1 ); + fptype* const Src2 = Src + InLen - 1; + replicateArray( Src2, 1, Src2 + 1, InSuffix, 1 ); + Src += InElIncr; + } + } + + /** + * Function peforms scanline upsampling with filtering. + * + * @param Src Source scanline buffer (length = this -> InLen). Source + * scanline increment will be equal to ElCount. + * @param Dst Destination scanline buffer. + */ + + void doUpsample( const fptype* Src, fptype* Dst ) const + { + const int elalign = Vars -> elalign; + const int opstep = ResampleFactor; + const fptype* const f = Flt; + const int flen = Flt.getCapacity(); + int l; + int i; + int j; + + for( j = 0; j < Vars -> ElCount; j++ ) + { + const fptype* ip = Src; + fptype* op0 = &Dst[ -OutPrefix ]; + memset( op0, 0, ( OutPrefix + OutLen + OutSuffix ) * + sizeof( fptype )); + + if( FltOrig.getCapacity() > 0 ) + { + // Do not perform filtering, only upsample. + + op0 += OutPrefix % ResampleFactor; + l = OutPrefix / ResampleFactor; + + while( l > 0 ) + { + op0[ 0 ] = ip[ 0 ]; + op0 += opstep; + l--; + } + + l = InLen - 1; + + while( l > 0 ) + { + op0[ 0 ] = ip[ 0 ]; + op0 += opstep; + ip++; + l--; + } + + l = OutSuffix / ResampleFactor; + + while( l >= 0 ) + { + op0[ 0 ] = ip[ 0 ]; + op0 += opstep; + l--; + } + + Src += InElIncr; + Dst += OutElIncr; + continue; + } + + l = InPrefix; + fptypesimd ipv = (fptypesimd) ip[ 0 ]; + + while( l > 0 ) + { + for( i = 0; i < flen; i += elalign ) + { + fptypesimd :: addu( op0 + i, + fptypesimd :: load( f + i ) * ipv ); + } + + op0 += opstep; + l--; + } + + l = InLen - 1; + + while( l > 0 ) + { + ipv = (fptypesimd) ip[ 0 ]; + + for( i = 0; i < flen; i += elalign ) + { + fptypesimd :: addu( op0 + i, + fptypesimd :: load( f + i ) * ipv ); + } + + ip++; + op0 += opstep; + l--; + } + + l = InSuffix; + ipv = (fptypesimd) ip[ 0 ]; + + while( l >= 0 ) + { + for( i = 0; i < flen; i += elalign ) + { + fptypesimd :: addu( op0 + i, + fptypesimd :: load( f + i ) * ipv ); + } + + op0 += opstep; + l--; + } + + const fptype* dc = SuffixDC; + l = SuffixDC.getCapacity(); + + for( i = 0; i < l; i += elalign ) + { + fptypesimd :: addu( op0 + i, + fptypesimd :: load( dc + i ) * ipv ); + } + + ipv = (fptypesimd) Src[ 0 ]; + op0 = Dst - InPrefix * opstep; + dc = PrefixDC; + l = PrefixDC.getCapacity(); + + for( i = 0; i < l; i += elalign ) + { + fptypesimd :: addu( op0 + i, + fptypesimd :: load( dc + i ) * ipv ); + } + + Src += InElIncr; + Dst += OutElIncr; + } + } + + /** + * Function peforms scanline filtering with optional downsampling. + * Function makes use of the symmetry of the filter. + * + * @param Src Source scanline buffer (length = this -> InLen). Source + * scanline increment will be equal to 1. + * @param Dst Destination scanline buffer. + * @param DstIncr Destination scanline buffer increment, used for + * horizontal or vertical scanline stepping. + */ + + void doFilter( const fptype* const Src, fptype* Dst, + const int DstIncr ) const + { + const int ElCount = Vars -> ElCount; + const int elalign = Vars -> elalign; + const fptype* const f = &Flt[ 0 ]; + const int flen = Flt.getCapacity(); + const int ipstep = ResampleFactor; + int i; + int j; + + if( ElCount == 1 ) + { + const fptype* ip = Src - EdgePixelCount * ipstep - FltLatency; + fptype* op = Dst; + int l = OutLen; + + while( l > 0 ) + { + fptypesimd s = fptypesimd :: load( f ) * + fptypesimd :: loadu( ip ); + + for( i = elalign; i < flen; i += elalign ) + { + s += fptypesimd :: load( f + i ) * + fptypesimd :: loadu( ip + i ); + } + + op[ 0 ] = s.hadd(); + op += DstIncr; + ip += ipstep; + l--; + } + } + else + if( DstIncr == 1 ) + { + for( j = 0; j < ElCount; j++ ) + { + const fptype* ip = Src - EdgePixelCount * ipstep - + FltLatency + j * InElIncr; + + fptype* op = Dst + j * OutElIncr; + int l = OutLen; + + while( l > 0 ) + { + fptypesimd s = fptypesimd :: load( f ) * + fptypesimd :: loadu( ip ); + + for( i = elalign; i < flen; i += elalign ) + { + s += fptypesimd :: load( f + i ) * + fptypesimd :: loadu( ip + i ); + } + + op[ 0 ] = s.hadd(); + op += DstIncr; + ip += ipstep; + l--; + } + } + } + else + { + const fptype* ip0 = Src - EdgePixelCount * ipstep - FltLatency; + fptype* op0 = Dst; + int l = OutLen; + + while( l > 0 ) + { + const fptype* ip = ip0; + fptype* op = op0; + + for( j = 0; j < ElCount; j++ ) + { + fptypesimd s = fptypesimd :: load( f ) * + fptypesimd :: loadu( ip ); + + for( i = elalign; i < flen; i += elalign ) + { + s += fptypesimd :: load( f + i ) * + fptypesimd :: loadu( ip + i ); + } + + op[ 0 ] = s.hadd(); + ip += InElIncr; + op += OutElIncr; + } + + ip0 += ipstep; + op0 += DstIncr; + l--; + } + } + } + + /** + * Function performs resizing of a single scanline. This function does + * not "know" about the length of the source scanline buffer. This buffer + * should be padded with enough pixels so that ( SrcPos - FilterLenD2 ) is + * always >= 0 and ( SrcPos + ( DstLineLen - 1 ) * k + FilterLenD2 + 1 ) + * does not exceed source scanline's buffer length. SrcLine's increment is + * assumed to be equal to 1. + * + * @param SrcLine Source scanline buffer. + * @param DstLine Destination (resized) scanline buffer. + * @param DstLineIncr Destination scanline position increment, used for + * horizontal or vertical scanline stepping. + * @param xx Temporary buffer, of size FltBank -> getFilterLen(), must be + * aligned by fpclass :: fpalign. + */ + + void doResize( const fptype* SrcLine, fptype* DstLine, + int DstLineIncr, fptype* const xx ) const + { + const int IntFltLen = FltBank -> getFilterLen(); + const int ElCount = Vars -> ElCount; + const int elalign = Vars -> elalign; + const typename CImageResizerFilterStep< fptype, fptype > :: + CResizePos* rpos = &(*RPosBuf)[ 0 ]; + + int DstLineLen = OutLen; + int i; + int j; + +#define AVIR_RESIZE_PART1 \ + while( DstLineLen > 0 ) \ + { \ + const fptypesimd x = (fptypesimd) rpos -> x; \ + const fptype* ftp = rpos -> ftp; \ + const fptype* ftp2 = rpos -> ftp + IntFltLen; \ + const fptype* Src = SrcLine + rpos -> SrcOffs; + +#define AVIR_RESIZE_PART1nx \ + while( DstLineLen > 0 ) \ + { \ + const fptype* ftp = rpos -> ftp; \ + const fptype* Src = SrcLine + rpos -> SrcOffs; + +#define AVIR_RESIZE_PART2 \ + DstLine += DstLineIncr; \ + rpos++; \ + DstLineLen--; \ + } + + if( ElCount == 1 ) + { + if( FltBank -> getOrder() == 1 ) + { + AVIR_RESIZE_PART1 + + fptypesimd sum = ( fptypesimd :: load( ftp ) + + fptypesimd :: load( ftp2 ) * x ) * + fptypesimd :: loadu( Src ); + + for( i = elalign; i < IntFltLen; i += elalign ) + { + sum += ( fptypesimd :: load( ftp + i ) + + fptypesimd :: load( ftp2 + i ) * x ) * + fptypesimd :: loadu( Src + i ); + } + + DstLine[ 0 ] = sum.hadd(); + + AVIR_RESIZE_PART2 + } + else + { + AVIR_RESIZE_PART1nx + + fptypesimd sum = fptypesimd :: load( ftp ) * + fptypesimd :: loadu( Src ); + + for( i = elalign; i < IntFltLen; i += elalign ) + { + sum += fptypesimd :: load( ftp + i ) * + fptypesimd :: loadu( Src + i ); + } + + DstLine[ 0 ] = sum.hadd(); + + AVIR_RESIZE_PART2 + } + } + else + if( DstLineIncr == 1 ) + { + // Horizontal-oriented processing, element loop is outer. + + const int SrcIncr = InElIncr; + const int DstLineElIncr = OutElIncr - DstLineIncr * DstLineLen; + + if( FltBank -> getOrder() == 1 ) + { + for( j = 0; j < ElCount; j++ ) + { + AVIR_RESIZE_PART1 + + fptypesimd sum = 0.0; + + for( i = 0; i < IntFltLen; i += elalign ) + { + sum += ( fptypesimd :: load( ftp + i ) + + fptypesimd :: load( ftp2 + i ) * x ) * + fptypesimd :: loadu( Src + i ); + } + + DstLine[ 0 ] = sum.hadd(); + + AVIR_RESIZE_PART2 + + DstLine += DstLineElIncr; + SrcLine += SrcIncr; + DstLineLen = OutLen; + rpos = &(*RPosBuf)[ 0 ]; + } + } + else + { + for( j = 0; j < ElCount; j++ ) + { + AVIR_RESIZE_PART1nx + + fptypesimd sum = fptypesimd :: load( ftp ) * + fptypesimd :: loadu( Src ); + + for( i = elalign; i < IntFltLen; i += elalign ) + { + sum += fptypesimd :: load( ftp + i ) * + fptypesimd :: loadu( Src + i ); + } + + DstLine[ 0 ] = sum.hadd(); + + AVIR_RESIZE_PART2 + + DstLine += DstLineElIncr; + SrcLine += SrcIncr; + DstLineLen = OutLen; + rpos = &(*RPosBuf)[ 0 ]; + } + } + } + else + { + const int SrcIncr = InElIncr; + const int DstLineElIncr = OutElIncr; + DstLineIncr -= DstLineElIncr * ElCount; + + if( FltBank -> getOrder() == 1 ) + { + AVIR_RESIZE_PART1 + + for( i = 0; i < IntFltLen; i += elalign ) + { + ( fptypesimd :: load( ftp + i ) + + fptypesimd :: load( ftp2 + i ) * x ).store( xx + i ); + } + + for( j = 0; j < ElCount; j++ ) + { + fptypesimd sum = fptypesimd :: load( xx ) * + fptypesimd :: loadu( Src ); + + for( i = elalign; i < IntFltLen; i += elalign ) + { + sum += fptypesimd :: load( xx + i ) * + fptypesimd :: loadu( Src + i ); + } + + DstLine[ 0 ] = sum.hadd(); + DstLine += DstLineElIncr; + Src += SrcIncr; + } + + AVIR_RESIZE_PART2 + } + else + { + AVIR_RESIZE_PART1nx + + for( j = 0; j < ElCount; j++ ) + { + fptypesimd sum = fptypesimd :: load( ftp ) * + fptypesimd :: loadu( Src ); + + for( i = elalign; i < IntFltLen; i += elalign ) + { + sum += fptypesimd :: load( ftp + i ) * + fptypesimd :: loadu( Src + i ); + } + + DstLine[ 0 ] = sum.hadd(); + DstLine += DstLineElIncr; + Src += SrcIncr; + } + + AVIR_RESIZE_PART2 + } + } + +#undef AVIR_RESIZE_PART2 +#undef AVIR_RESIZE_PART1nx +#undef AVIR_RESIZE_PART1 + } +}; + +/** + * @brief Image resizer's default de-interleaved dithering class. + * + * This class defines an object that performs rounding, clipping and dithering + * operations over horizontal scanline pixels before scanline is stored in the + * output buffer. + * + * This ditherer implementation uses de-interleaved SIMD algorithm. + * + * @tparam fptype Floating point type to use for storing pixel data. SIMD + * types cannot be used. + * @tparam fptypesimd The SIMD type used to store a pack of "fptype" values. + */ + +template< class fptype, class fptypesimd > +class CImageResizerDithererDefDIL +{ +public: + /** + * Function initializes the ditherer object. + * + * @param aLen Scanline length in pixels to process. + * @param aVars Image resizing-related variables. + * @param aTrMul Bit-depth truncation multiplier. 1 - no additional + * truncation. + * @param aPkOut Peak output value allowed. + */ + + void init( const int aLen, const CImageResizerVars& aVars, + const double aTrMul, const double aPkOut ) + { + Len = aLen; + Vars = &aVars; + LenE = aLen * Vars -> ElCount; + TrMul0 = aTrMul; + PkOut0 = aPkOut; + } + + /** + * @return "True" if dithering is recursive relative to scanlines meaning + * multi-threaded execution is not supported by this dithering method. + */ + + static bool isRecursive() + { + return( false ); + } + + /** + * Function performs rounding and clipping operations. + * + * @param ResScanline The buffer containing the final scanline. + */ + + void dither( fptype* const ResScanline ) const + { + const int elalign = Vars -> elalign; + const fptypesimd c0 = 0.0; + const fptypesimd PkOut = (fptypesimd) PkOut0; + int j; + + if( TrMul0 == 1.0 ) + { + // Optimization - do not perform bit truncation. + + for( j = 0; j < LenE - elalign; j += elalign ) + { + const fptypesimd z0 = round( + fptypesimd :: loadu( ResScanline + j )); + + clamp( z0, c0, PkOut ).storeu( ResScanline + j ); + } + + const int lim = LenE - j; + const fptypesimd z0 = round( + fptypesimd :: loadu( ResScanline + j, lim )); + + clamp( z0, c0, PkOut ).storeu( ResScanline + j, lim ); + } + else + { + const fptypesimd TrMul = (fptypesimd) TrMul0; + + for( j = 0; j < LenE - elalign; j += elalign ) + { + const fptypesimd z0 = round( + fptypesimd :: loadu( ResScanline + j ) / TrMul ) * TrMul; + + clamp( z0, c0, PkOut ).storeu( ResScanline + j ); + } + + const int lim = LenE - j; + const fptypesimd z0 = round( + fptypesimd :: loadu( ResScanline + j, lim ) / TrMul ) * TrMul; + + clamp( z0, c0, PkOut ).storeu( ResScanline + j, lim ); + } + } + +protected: + int Len; ///< Scanline's length in pixels. + ///< + const CImageResizerVars* Vars; ///< Image resizing-related variables. + ///< + int LenE; ///< = LenE * ElCount. + ///< + double TrMul0; ///< Bit-depth truncation multiplier. + ///< + double PkOut0; ///< Peak output value allowed. + ///< +}; + +/** + * @brief Image resizer's error-diffusion dithering class, de-interleaved + * mode. + * + * This ditherer implements error-diffusion dithering which looks good, and + * whose results are compressed by PNG well. + * + * @tparam fptype Floating point type to use for storing pixel data. SIMD + * types cannot be used. + * @tparam fptypesimd Processing type, SIMD can be used. + */ + +template< class fptype, class fptypesimd > +class CImageResizerDithererErrdDIL +{ +public: + /** + * Function initializes the ditherer object. + * + * @param aLen Scanline length in pixels to process. + * @param aVars Image resizing-related variables. + * @param aTrMul Bit-depth truncation multiplier. 1 - no additional + * truncation. + * @param aPkOut Peak output value allowed. + */ + + void init( const int aLen, const CImageResizerVars& aVars, + const double aTrMul, const double aPkOut ) + { + Len = aLen; + Vars = &aVars; + LenE = aLen * Vars -> ElCount; + TrMul0 = aTrMul; + PkOut0 = aPkOut; + + ResScanlineDith0.alloc( LenE + Vars -> ElCount, sizeof( fptype )); + ResScanlineDith = ResScanlineDith0 + Vars -> ElCount; + int i; + + for( i = 0; i < LenE + Vars -> ElCount; i++ ) + { + ResScanlineDith0[ i ] = 0.0; + } + } + + static bool isRecursive() + { + return( true ); + } + + void dither( fptype* const ResScanline ) + { + const int ea = Vars -> elalign; + const fptypesimd c0 = 0.0; + const fptypesimd TrMul = (fptypesimd) TrMul0; + const fptypesimd PkOut = (fptypesimd) PkOut0; + int j; + + for( j = 0; j < LenE - ea; j += ea ) + { + fptypesimd :: addu( ResScanline + j, + fptypesimd :: loadu( ResScanlineDith + j )); + + c0.storeu( ResScanlineDith + j ); + } + + int lim = LenE - j; + fptypesimd :: addu( ResScanline + j, + fptypesimd :: loadu( ResScanlineDith + j, lim ), lim ); + + c0.storeu( ResScanlineDith + j, lim ); + + const int Len1 = Len - 1; + fptype* rs = ResScanline; + fptype* rsd = ResScanlineDith; + int i; + + for( i = 0; i < Vars -> ElCount; i++ ) + { + for( j = 0; j < Len1; j++ ) + { + // Perform rounding, noise estimation and saturation. + + fptype* const rsj = rs + j; + const fptype z0 = round( rsj[ 0 ] / TrMul ) * TrMul; + const fptype Noise = rsj[ 0 ] - z0; + rsj[ 0 ] = clamp( z0, (fptype) 0.0, PkOut ); + + fptype* const rsdj = rsd + j; + rsj[ 1 ] += Noise * (fptype) 0.364842; + rsdj[ -1 ] += Noise * (fptype) 0.207305; + rsdj[ 0 ] += Noise * (fptype) 0.364842; + rsdj[ 1 ] += Noise * (fptype) 0.063011; + } + + // Process the last pixel element in scanline. + + const fptype z1 = round( rs[ Len1 ] / TrMul ) * TrMul; + const fptype Noise2 = rs[ Len1 ] - z1; + rs[ Len1 ] = clamp( z1, c0, PkOut ); + + rsd[ Len1 - 1 ] += Noise2 * (fptype) 0.207305; + rsd[ Len1 ] += Noise2 * (fptype) 0.364842; + + rs += Len; + rsd += Len; + } + } + +protected: + int Len; ///< Scanline's length in pixels. + ///< + const CImageResizerVars* Vars; ///< Image resizing-related variables. + ///< + int LenE; ///< = LenE * ElCount. + ///< + double TrMul0; ///< Bit-depth truncation multiplier. + ///< + double PkOut0; ///< Peak output value allowed. + ///< + CBuffer< fptype > ResScanlineDith0; ///< Error propagation buffer for + ///< dithering, first pixel unused. + ///< + fptype* ResScanlineDith; ///< Error propagation buffer pointer which skips + ///< the first ElCount elements. + ///< +}; + +/** + * @brief Floating-point processing definition and abstraction class for + * de-interleaved processing. + * + * This class defines several constants and typedefs that point to classes + * that should be used by the image resizing algorithm. This implementation + * points to de-interleaved processing classes. + * + * @tparam afptype Floating point type to use for storing intermediate data + * and variables. SIMD types should not be used. + * @tparam afptypesimd SIMD type used to perform processing. + * @tparam adith Ditherer class to use during processing. + */ + +template< class afptype, class afptypesimd, + class adith = CImageResizerDithererDefDIL< afptype, afptypesimd > > +class fpclass_def_dil +{ +public: + typedef afptype fptype; ///< Floating-point type to use during processing. + ///< + typedef afptype fptypeatom; ///< Atomic type "fptype" consists of. + ///< + static const int fppack = 1; ///< The number of atomic types stored in a + ///< single "fptype" element. + ///< + static const int fpalign = sizeof( afptypesimd ); ///< Suggested alignment + ///< size in bytes. This is not a required alignment, because image + ///< resizing algorithm cannot be made to have a strictly aligned data + ///< access in all cases (e.g. de-interleaved interpolation cannot + ///< perform aligned accesses). + ///< + static const int elalign = sizeof( afptypesimd ) / sizeof( afptype ); ///< + ///< Length alignment of arrays of elements. This applies to filters + ///< and intermediate buffers: this constant forces filters and + ///< scanlines to have a length which is a multiple of this value, for + ///< more efficient SIMD implementation. + ///< + static const int packmode = 1; ///< 0 if interleaved packing, 1 if + ///< de-interleaved. + ///< + typedef CImageResizerFilterStepDIL< fptype, afptypesimd > CFilterStep; ///< + ///< Filtering step class to use during processing. + ///< + typedef adith CDitherer; ///< Ditherer class to use during processing. + ///< +}; + +} // namespace avir diff --git a/third_party/avir/avir_float4_sse.h b/third_party/avir/avir_float4_sse.h new file mode 100644 index 00000000..115e2ddc --- /dev/null +++ b/third_party/avir/avir_float4_sse.h @@ -0,0 +1,323 @@ +/* clang-format off */ +//$ nobt +//$ nocpp + +/** + * @file avir_float4_sse.h + * + * @brief Inclusion file for the "float4" type. + * + * This file includes the "float4" SSE-based type used for SIMD variable + * storage and processing. + * + * AVIR Copyright (c) 2015-2019 Aleksey Vaneev + */ + +#ifndef AVIR_FLOAT4_SSE_INCLUDED +#define AVIR_FLOAT4_SSE_INCLUDED + +#include "third_party/avir/avir.h" +#include "libc/bits/mmintrin.h" +#include "libc/bits/xmmintrin.h" +#include "libc/bits/xmmintrin.h" +#include "libc/bits/emmintrin.h" + +namespace avir { + +/** + * @brief SIMD packed 4-float type. + * + * This class implements a packed 4-float type that can be used to perform + * parallel computation using SIMD instructions on SSE-enabled processors. + * This class can be used as the "fptype" argument of the avir::fpclass_def + * class. + */ + +class float4 +{ +public: + float4() + { + } + + float4( const float4& s ) + : value( s.value ) + { + } + + float4( const __m128 s ) + : value( s ) + { + } + + float4( const float s ) + : value( _mm_set1_ps( s )) + { + } + + float4& operator = ( const float4& s ) + { + value = s.value; + return( *this ); + } + + float4& operator = ( const __m128 s ) + { + value = s; + return( *this ); + } + + float4& operator = ( const float s ) + { + value = _mm_set1_ps( s ); + return( *this ); + } + + operator float () const + { + return( _mm_cvtss_f32( value )); + } + + /** + * @param p Pointer to memory from where the value should be loaded, + * should be 16-byte aligned. + * @return float4 value loaded from the specified memory location. + */ + + static float4 load( const float* const p ) + { + return( _mm_load_ps( p )); + } + + /** + * @param p Pointer to memory from where the value should be loaded, + * may have any alignment. + * @return float4 value loaded from the specified memory location. + */ + + static float4 loadu( const float* const p ) + { + return( _mm_loadu_ps( p )); + } + + /** + * @param p Pointer to memory from where the value should be loaded, + * may have any alignment. + * @param lim The maximum number of elements to load, >0. + * @return float4 value loaded from the specified memory location, with + * elements beyond "lim" set to 0. + */ + + static float4 loadu( const float* const p, int lim ) + { + if( lim > 2 ) + { + if( lim > 3 ) + { + return( _mm_loadu_ps( p )); + } + else + { + return( _mm_set_ps( 0.0f, p[ 2 ], p[ 1 ], p[ 0 ])); + } + } + else + { + if( lim == 2 ) + { + return( _mm_set_ps( 0.0f, 0.0f, p[ 1 ], p[ 0 ])); + } + else + { + return( _mm_load_ss( p )); + } + } + } + + /** + * Function stores *this value to the specified memory location. + * + * @param[out] p Output memory location, should be 16-byte aligned. + */ + + void store( float* const p ) const + { + _mm_store_ps( p, value ); + } + + /** + * Function stores *this value to the specified memory location. + * + * @param[out] p Output memory location, may have any alignment. + */ + + void storeu( float* const p ) const + { + _mm_storeu_ps( p, value ); + } + + /** + * Function stores "lim" lower elements of *this value to the specified + * memory location. + * + * @param[out] p Output memory location, may have any alignment. + * @param lim The number of lower elements to store, >0. + */ + + void storeu( float* const p, int lim ) const + { + if( lim > 2 ) + { + if( lim > 3 ) + { + _mm_storeu_ps( p, value ); + } + else + { + _mm_storel_pi( (__m64*) p, value ); + _mm_store_ss( p + 2, _mm_movehl_ps( value, value )); + } + } + else + { + if( lim == 2 ) + { + _mm_storel_pi( (__m64*) p, value ); + } + else + { + _mm_store_ss( p, value ); + } + } + } + + float4& operator += ( const float4& s ) + { + value = _mm_add_ps( value, s.value ); + return( *this ); + } + + float4& operator -= ( const float4& s ) + { + value = _mm_sub_ps( value, s.value ); + return( *this ); + } + + float4& operator *= ( const float4& s ) + { + value = _mm_mul_ps( value, s.value ); + return( *this ); + } + + float4& operator /= ( const float4& s ) + { + value = _mm_div_ps( value, s.value ); + return( *this ); + } + + float4 operator + ( const float4& s ) const + { + return( _mm_add_ps( value, s.value )); + } + + float4 operator - ( const float4& s ) const + { + return( _mm_sub_ps( value, s.value )); + } + + float4 operator * ( const float4& s ) const + { + return( _mm_mul_ps( value, s.value )); + } + + float4 operator / ( const float4& s ) const + { + return( _mm_div_ps( value, s.value )); + } + + /** + * @return Horizontal sum of elements. + */ + + float hadd() const + { + const __m128 v = _mm_add_ps( value, _mm_movehl_ps( value, value )); + const __m128 res = _mm_add_ss( v, _mm_shuffle_ps( v, v, 1 )); + return( _mm_cvtss_f32( res )); + } + + /** + * Function performs in-place addition of a value located in memory and + * the specified value. + * + * @param p Pointer to value where addition happens. May be unaligned. + * @param v Value to add. + */ + + static void addu( float* const p, const float4& v ) + { + ( loadu( p ) + v ).storeu( p ); + } + + /** + * Function performs in-place addition of a value located in memory and + * the specified value. Limited to the specfied number of elements. + * + * @param p Pointer to value where addition happens. May be unaligned. + * @param v Value to add. + * @param lim The element number limit, >0. + */ + + static void addu( float* const p, const float4& v, const int lim ) + { + ( loadu( p, lim ) + v ).storeu( p, lim ); + } + + __m128 value; ///< Packed value of 4 floats. + ///< +}; + +/** + * SIMD rounding function, exact result. + * + * @param v Value to round. + * @return Rounded SIMD value. + */ + +inline float4 round( const float4& v ) +{ + unsigned int prevrm = _MM_GET_ROUNDING_MODE(); + _MM_SET_ROUNDING_MODE( _MM_ROUND_NEAREST ); + + const __m128 res = _mm_cvtepi32_ps( _mm_cvtps_epi32( v.value )); + + _MM_SET_ROUNDING_MODE( prevrm ); + + return( res ); +} + +/** + * SIMD function "clamps" (clips) the specified packed values so that they are + * not lesser than "minv", and not greater than "maxv". + * + * @param Value Value to clamp. + * @param minv Minimal allowed value. + * @param maxv Maximal allowed value. + * @return The clamped value. + */ + +inline float4 clamp( const float4& Value, const float4& minv, + const float4& maxv ) +{ + return( _mm_min_ps( _mm_max_ps( Value.value, minv.value ), maxv.value )); +} + +typedef fpclass_def< avir :: float4, float > fpclass_float4; ///< + ///< Class that can be used as the "fpclass" template parameter of the + ///< avir::CImageResizer class to perform calculation using default + ///< interleaved algorithm, using SIMD float4 type. + ///< + +} // namespace avir + +#endif // AVIR_FLOAT4_SSE_INCLUDED diff --git a/third_party/avir/avir_float8_avx.h b/third_party/avir/avir_float8_avx.h new file mode 100644 index 00000000..ce00cd06 --- /dev/null +++ b/third_party/avir/avir_float8_avx.h @@ -0,0 +1,365 @@ +/* clang-format off */ +//$ nobt +//$ nocpp + +/** + * @file avir_float8_avx.h + * + * @brief Inclusion file for the "float8" type. + * + * This file includes the "float8" AVX-based type used for SIMD variable + * storage and processing. + * + * AVIR Copyright (c) 2015-2019 Aleksey Vaneev + */ + +#ifndef AVIR_FLOAT8_AVX_INCLUDED +#define AVIR_FLOAT8_AVX_INCLUDED + +#include "libc/bits/mmintrin.h" +#include "libc/bits/avxintrin.h" +#include "libc/bits/smmintrin.h" +#include "libc/bits/pmmintrin.h" +#include "libc/bits/avx2intrin.h" +#include "libc/bits/xmmintrin.h" +#include "third_party/avir/avir_dil.h" + +namespace avir { + +/** + * @brief SIMD packed 8-float type. + * + * This class implements a packed 8-float type that can be used to perform + * parallel computation using SIMD instructions on AVX-enabled processors. + * This class can be used as the "fptype" argument of the avir::fpclass_def + * or avir::fpclass_def_dil class. + */ + +class float8 +{ +public: + float8() + { + } + + float8( const float8& s ) + : value( s.value ) + { + } + + float8( const __m256 s ) + : value( s ) + { + } + + float8( const float s ) + : value( _mm256_set1_ps( s )) + { + } + + float8& operator = ( const float8& s ) + { + value = s.value; + return( *this ); + } + + float8& operator = ( const __m256 s ) + { + value = s; + return( *this ); + } + + float8& operator = ( const float s ) + { + value = _mm256_set1_ps( s ); + return( *this ); + } + + operator float () const + { + return( _mm_cvtss_f32( _mm256_extractf128_ps( value, 0 ))); + } + + /** + * @param p Pointer to memory from where the value should be loaded, + * should be 32-byte aligned. + * @return float8 value loaded from the specified memory location. + */ + + static float8 load( const float* const p ) + { + return( _mm256_load_ps( p )); + } + + /** + * @param p Pointer to memory from where the value should be loaded, + * may have any alignment. + * @return float8 value loaded from the specified memory location. + */ + + static float8 loadu( const float* const p ) + { + return( _mm256_loadu_ps( p )); + } + + /** + * @param p Pointer to memory from where the value should be loaded, + * may have any alignment. + * @param lim The maximum number of elements to load, >0. + * @return float8 value loaded from the specified memory location, with + * elements beyond "lim" set to 0. + */ + + static float8 loadu( const float* const p, const int lim ) + { + __m128 lo; + __m128 hi; + + if( lim > 4 ) + { + lo = _mm_loadu_ps( p ); + hi = loadu4( p + 4, lim - 4 ); + } + else + { + lo = loadu4( p, lim ); + hi = _mm_setzero_ps(); + } + + return( _mm256_insertf128_ps( _mm256_castps128_ps256( lo ), hi, 1 )); + } + + /** + * Function stores *this value to the specified memory location. + * + * @param[out] p Output memory location, should be 32-byte aligned. + */ + + void store( float* const p ) const + { + _mm256_store_ps( p, value ); + } + + /** + * Function stores *this value to the specified memory location. + * + * @param[out] p Output memory location, may have any alignment. + */ + + void storeu( float* const p ) const + { + _mm256_storeu_ps( p, value ); + } + + /** + * Function stores "lim" lower elements of *this value to the specified + * memory location. + * + * @param[out] p Output memory location, may have any alignment. + * @param lim The number of lower elements to store, >0. + */ + + void storeu( float* p, int lim ) const + { + __m128 v; + + if( lim > 4 ) + { + _mm_storeu_ps( p, _mm256_extractf128_ps( value, 0 )); + v = _mm256_extractf128_ps( value, 1 ); + p += 4; + lim -= 4; + } + else + { + v = _mm256_extractf128_ps( value, 0 ); + } + + if( lim > 2 ) + { + if( lim > 3 ) + { + _mm_storeu_ps( p, v ); + } + else + { + _mm_storel_pi( (__m64*) p, v ); + _mm_store_ss( p + 2, _mm_movehl_ps( v, v )); + } + } + else + { + if( lim == 2 ) + { + _mm_storel_pi( (__m64*) p, v ); + } + else + { + _mm_store_ss( p, v ); + } + } + } + + float8& operator += ( const float8& s ) + { + value = _mm256_add_ps( value, s.value ); + return( *this ); + } + + float8& operator -= ( const float8& s ) + { + value = _mm256_sub_ps( value, s.value ); + return( *this ); + } + + float8& operator *= ( const float8& s ) + { + value = _mm256_mul_ps( value, s.value ); + return( *this ); + } + + float8& operator /= ( const float8& s ) + { + value = _mm256_div_ps( value, s.value ); + return( *this ); + } + + float8 operator + ( const float8& s ) const + { + return( _mm256_add_ps( value, s.value )); + } + + float8 operator - ( const float8& s ) const + { + return( _mm256_sub_ps( value, s.value )); + } + + float8 operator * ( const float8& s ) const + { + return( _mm256_mul_ps( value, s.value )); + } + + float8 operator / ( const float8& s ) const + { + return( _mm256_div_ps( value, s.value )); + } + + /** + * @return Horizontal sum of elements. + */ + + float hadd() const + { + __m128 v = _mm_add_ps( _mm256_extractf128_ps( value, 0 ), + _mm256_extractf128_ps( value, 1 )); + + v = _mm_hadd_ps( v, v ); + v = _mm_hadd_ps( v, v ); + return( _mm_cvtss_f32( v )); + } + + /** + * Function performs in-place addition of a value located in memory and + * the specified value. + * + * @param p Pointer to value where addition happens. May be unaligned. + * @param v Value to add. + */ + + static void addu( float* const p, const float8& v ) + { + ( loadu( p ) + v ).storeu( p ); + } + + /** + * Function performs in-place addition of a value located in memory and + * the specified value. Limited to the specfied number of elements. + * + * @param p Pointer to value where addition happens. May be unaligned. + * @param v Value to add. + * @param lim The element number limit, >0. + */ + + static void addu( float* const p, const float8& v, const int lim ) + { + ( loadu( p, lim ) + v ).storeu( p, lim ); + } + + __m256 value; ///< Packed value of 8 floats. + ///< + +private: + /** + * @param p Pointer to memory from where the value should be loaded, + * may have any alignment. + * @param lim The maximum number of elements to load, >0. + * @return __m128 value loaded from the specified memory location, with + * elements beyond "lim" set to 0. + */ + + static __m128 loadu4( const float* const p, const int lim ) + { + if( lim > 2 ) + { + if( lim > 3 ) + { + return( _mm_loadu_ps( p )); + } + else + { + return( _mm_set_ps( 0.0f, p[ 2 ], p[ 1 ], p[ 0 ])); + } + } + else + { + if( lim == 2 ) + { + return( _mm_set_ps( 0.0f, 0.0f, p[ 1 ], p[ 0 ])); + } + else + { + return( _mm_load_ss( p )); + } + } + } +}; + +/** + * SIMD rounding function, exact result. + * + * @param v Value to round. + * @return Rounded SIMD value. + */ + +inline float8 round( const float8& v ) +{ + return( _mm256_round_ps( v.value, + ( _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC ))); +} + +/** + * SIMD function "clamps" (clips) the specified packed values so that they are + * not lesser than "minv", and not greater than "maxv". + * + * @param Value Value to clamp. + * @param minv Minimal allowed value. + * @param maxv Maximal allowed value. + * @return The clamped value. + */ + +inline float8 clamp( const float8& Value, const float8& minv, + const float8& maxv ) +{ + return( _mm256_min_ps( _mm256_max_ps( Value.value, minv.value ), + maxv.value )); +} + +typedef fpclass_def_dil< float, avir :: float8 > fpclass_float8_dil; ///< + ///< Class that can be used as the "fpclass" template parameter of the + ///< avir::CImageResizer class to perform calculation using + ///< de-interleaved SIMD algorithm, using SIMD float8 type. + ///< + +} // namespace avir + +#endif // AVIR_FLOAT8_AVX_INCLUDED diff --git a/third_party/avir/lancir.h b/third_party/avir/lancir.h new file mode 100644 index 00000000..22055fcb --- /dev/null +++ b/third_party/avir/lancir.h @@ -0,0 +1,1494 @@ +// clang-format off +//$ nobt +//$ nocpp + +/** + * @file lancir.h + * + * @brief The self-contained "lancir" inclusion file. + * + * This is the self-contained inclusion file for the "LANCIR" image resizer, + * part of the AVIR library. + * + * AVIR Copyright (c) 2015-2019 Aleksey Vaneev + * + * @mainpage + * + * @section intro_sec Introduction + * + * Description is available at https://github.com/avaneev/avir + * + * @section license License + * + * AVIR License Agreement + * + * The MIT License (MIT) + * + * Copyright (c) 2015-2019 Aleksey Vaneev + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef AVIR_CLANCIR_INCLUDED +#define AVIR_CLANCIR_INCLUDED + +#include "third_party/avir/notice.h" +#include "libc/str/str.h" +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/log/check.h" +#include "libc/macros.h" +#include "libc/math.h" + +namespace avir { + +/** + * The macro equals to "pi" constant, fills 53-bit floating point mantissa. + * Undefined at the end of file. + */ + +#define LANCIR_PI 3.1415926535897932 + +/** + * @brief LANCIR image resizer class. + * + * The object of this class can be used to resize 1-4 channel images to any + * required size. Resizing is performed by utilizing Lanczos filters, with + * 8-bit precision. This class offers a kind of "optimal" Lanczos resampling + * implementation. + * + * Object of this class can be allocated on stack. + * + * Note that object of this class does not free temporary buffers and + * variables after the resizeImage() call (until object's destruction), these + * buffers are reused on subsequent calls making batch resizing of same-size + * images faster. This means resizing is not thread-safe: a separate object + * should be created for each thread. + */ + +class CLancIR +{ +private: + CLancIR( const CLancIR& ) + { + // Unsupported. + } + + CLancIR& operator = ( const CLancIR& ) + { + // Unsupported. + return( *this ); + } + +public: + CLancIR() + : FltBuf( NULL ) + , FltBufLen( 0 ) + , spv( NULL ) + , spvlen( 0 ) + { + } + + ~CLancIR() + { + delete[] FltBuf; + delete[] spv; + } + + /** + * Function resizes image. + * + * @param SrcBuf Source image buffer. + * @param SrcWidth Source image width. + * @param SrcHeight Source image height. + * @param SrcScanlineSize Physical size of source scanline in elements + * (not bytes). If this value is below 1, SrcWidth * ElCount will be + * used as the physical source scanline size. + * @param[out] NewBuf Buffer to accept the resized image. Can be equal to + * SrcBuf if the size of the resized image is smaller or equal to source + * image in size. + * @param NewWidth New image width. + * @param NewHeight New image height. + * @param ElCount The number of elements (channels) used to store each + * source and destination pixel (1-4). + * @param kx0 Resizing step - horizontal (one output pixel corresponds to + * "k" input pixels). A downsizing factor if > 1.0; upsizing factor + * if <= 1.0. Multiply by -1 if you would like to bypass "ox" and "oy" + * adjustment which is done by default to produce a centered image. If + * step value equals 0, the step value will be chosen automatically. + * @param ky0 Resizing step - vertical. Same as "kx". + * @param ox Start X pixel offset within source image (can be negative). + * Positive offset moves the image to the left. + * @param oy Start Y pixel offset within source image (can be negative). + * Positive offset moves the image to the top. + * @tparam T Input and output buffer element's type. Can be uint8_t + * (0-255 value range), uint16_t (0-65535 value range), float + * (any value range), double (any value range). Larger integer types are + * treated as uint16_t. Signed integer types are unsupported. + */ + + template< class T > + void resizeImage( const T* const SrcBuf, const int SrcWidth, + const int SrcHeight, int SrcScanlineSize, T* const NewBuf, + const int NewWidth, const int NewHeight, const int ElCount, + const double kx0 = 0.0, const double ky0 = 0.0, double ox = 0.0, + double oy = 0.0 ) + { + if( NewWidth <= 0 || NewHeight <= 0 ) + { + return; + } + + if( SrcWidth <= 0 || SrcHeight <= 0 ) + { + handleEmptySrcCornerCase( NewBuf, (size_t) NewWidth * NewHeight * sizeof( T ) ); + return; + } + + const double la = 3.0; // Lanczos "a". + double kx; + double ky; + + if( kx0 == 0.0 ) + { + if( NewWidth > SrcWidth ) + { + kx = (double) ( SrcWidth - 1 ) / ( NewWidth - 1 ); + } + else + { + kx = (double) SrcWidth / NewWidth; + ox += ( kx - 1.0 ) * 0.5; + } + } + else + if( kx0 > 0.0 ) + { + kx = kx0; + + if( kx0 > 1.0 ) + { + ox += ( kx0 - 1.0 ) * 0.5; + } + } + else + { + kx = -kx0; + } + + if( ky0 == 0.0 ) + { + if( NewHeight > SrcHeight ) + { + ky = (double) ( SrcHeight - 1 ) / ( NewHeight - 1 ); + } + else + { + ky = (double) SrcHeight / NewHeight; + oy += ( ky - 1.0 ) * 0.5; + } + } + else + if( ky0 > 0.0 ) + { + ky = ky0; + + if( ky0 > 1.0 ) + { + oy += ( ky0 - 1.0 ) * 0.5; + } + } + else + { + ky = -ky0; + } + + if( rfh.update( la, kx )) + { + rsh.reset(); + rsv.reset(); + } + + CResizeFilters* rfv; // Pointer to resizing filters for vertical + // resizing, may equal to "rfh" if the same stepping is in use. + + if( ky == kx ) + { + rfv = &rfh; + } + else + { + rfv = &rfv0; + + if( rfv0.update( la, ky )) + { + rsv.reset(); + } + } + + rsh.update( kx, ox, ElCount, SrcWidth, NewWidth, rfh ); + rsv.update( ky, oy, ElCount, SrcHeight, NewHeight, *rfv ); + + const int NewWidthE = NewWidth * ElCount; + + if( SrcScanlineSize < 1 ) + { + SrcScanlineSize = SrcWidth * ElCount; + } + + // Allocate/resize temporary buffer. + + const size_t FltBufLenNew = (size_t) NewWidthE * (size_t) SrcHeight; + + if( FltBufLenNew > FltBufLen ) + { + free( FltBuf ); + FltBufLen = FltBufLenNew; + FltBuf = (float *) memalign( 32, sizeof(float) * FltBufLen ); + CHECK_NOTNULL(FltBuf); + } + + // Perform horizontal resizing. + + const T* ips = SrcBuf; + float* op = FltBuf; + size_t i; + + if( ElCount == 3 ) + { + for( i = 0; i < SrcHeight; i++ ) + { + copyScanline3h( ips, rsh, SrcWidth ); + resize3( op, NewWidth, rsh.pos, rfh.KernelLen ); + ips += SrcScanlineSize; + op += NewWidthE; + } + } + else + if( ElCount == 1 ) + { + for( i = 0; i < SrcHeight; i++ ) + { + copyScanline1h( ips, rsh, SrcWidth ); + resize1( op, NewWidth, rsh.pos, rfh.KernelLen ); + ips += SrcScanlineSize; + op += NewWidthE; + } + } + else + if( ElCount == 4 ) + { + for( i = 0; i < SrcHeight; i++ ) + { + copyScanline4h( ips, rsh, SrcWidth ); + resize4( op, NewWidth, rsh.pos, rfh.KernelLen ); + ips += SrcScanlineSize; + op += NewWidthE; + } + } + else + if( ElCount == 2 ) + { + for( i = 0; i < SrcHeight; i++ ) + { + copyScanline2h( ips, rsh, SrcWidth ); + resize2( op, NewWidth, rsh.pos, rfh.KernelLen ); + ips += SrcScanlineSize; + op += NewWidthE; + } + } + + // Perform vertical resizing. + + const int spvlennew = NewHeight * ElCount; + + if( spvlennew > spvlen ) + { + free( spv ); + spvlen = spvlennew; + spv = (float *) memalign( 32, sizeof(float) * spvlen ); + } + + const bool IsIOFloat = ( (T) 0.25 != 0 ); + const int Clamp = ( sizeof( T ) == 1 ? 255 : 65535 ); + const float* ip = FltBuf; + T* opd = NewBuf; + + if( ElCount == 3 ) + { + for( i = 0; i < NewWidth; i++ ) + { + copyScanline3v( ip, rsv, SrcHeight, NewWidthE ); + resize3( spv, NewHeight, rsv.pos, rfv -> KernelLen ); + copyOutput3( spv, opd, NewHeight, NewWidthE, IsIOFloat, + Clamp ); + + ip += 3; + opd += 3; + } + } + else + if( ElCount == 1 ) + { + for( i = 0; i < NewWidth; i++ ) + { + copyScanline1v( ip, rsv, SrcHeight, NewWidthE ); + resize1( spv, NewHeight, rsv.pos, rfv -> KernelLen ); + copyOutput1( spv, opd, NewHeight, NewWidthE, IsIOFloat, + Clamp ); + + ip++; + opd++; + } + } + else + if( ElCount == 4 ) + { + for( i = 0; i < NewWidth; i++ ) + { + copyScanline4v( ip, rsv, SrcHeight, NewWidthE ); + resize4( spv, NewHeight, rsv.pos, rfv -> KernelLen ); + copyOutput4( spv, opd, NewHeight, NewWidthE, IsIOFloat, + Clamp ); + + ip += 4; + opd += 4; + } + } + else + if( ElCount == 2 ) + { + for( i = 0; i < NewWidth; i++ ) + { + copyScanline2v( ip, rsv, SrcHeight, NewWidthE ); + resize2( spv, NewHeight, rsv.pos, rfv -> KernelLen ); + copyOutput2( spv, opd, NewHeight, NewWidthE, IsIOFloat, + Clamp ); + + ip += 2; + opd += 2; + } + } + } + +protected: + float* FltBuf; ///< Intermediate resizing buffer. + ///< + size_t FltBufLen; ///< Intermediate resizing buffer length. + ///< + float* spv; ///< Scanline buffer for vertical resizing. + ///< + unsigned spvlen; ///< Length of "spv". + ///< + + /** + * Function rounds a value and applies clamping. + * + * @param v Value to round and clamp. + * @param Clamp High clamp level, low level is 0. + */ + static int roundclamp( const float v, const int Clamp ) +#define roundclamp(V, CLAMP) ((CLAMP)==255?MAX(0, MIN(255, lrintf(V))):(roundclamp)(V, CLAMP)) + { + if( Clamp == 255 ) { + return MAX(0, MIN(255, lrintf(v))); + } else { + if( v <= 0.0f ) + { + return( 0 ); + } + const int vr = (int) ( v + 0.5f ); + if( vr > Clamp ) + { + return( Clamp ); + } + return( vr ); + } + } + + /** + * Function performs final output of the resized scanline data to the + * destination image buffer. Variants for 1-4-channel image. + * + * @param ip Input resized scanline. + * @param op Output image buffer. + * @param l Pixel count. + * @param opinc "op" increment, should account ElCount. + * @param IsIOFloat "True" if float output and no clamping is necessary. + * @param Clamp Clamp high level, used if IsIOFloat is "false". + */ + + template< class T > + static void copyOutput1( const float* ip, T* op, int l, const int opinc, + const bool IsIOFloat, const int Clamp ) + { + if( IsIOFloat ) + { + while( l > 0 ) + { + op[ 0 ] = (T) ip[ 0 ]; + ip++; + op += opinc; + l--; + } + } + else + { + while( l > 0 ) + { + op[ 0 ] = (T) roundclamp( ip[ 0 ], Clamp ); + ip++; + op += opinc; + l--; + } + } + } + + template< class T > + static void copyOutput2( const float* ip, T* op, int l, const int opinc, + const bool IsIOFloat, const int Clamp ) + { + if( IsIOFloat ) + { + while( l > 0 ) + { + op[ 0 ] = (T) ip[ 0 ]; + op[ 1 ] = (T) ip[ 1 ]; + ip += 2; + op += opinc; + l--; + } + } + else + { + while( l > 0 ) + { + op[ 0 ] = (T) roundclamp( ip[ 0 ], Clamp ); + op[ 1 ] = (T) roundclamp( ip[ 1 ], Clamp ); + ip += 2; + op += opinc; + l--; + } + } + } + + template< class T > + static void copyOutput3( const float* ip, T* op, int l, const int opinc, + const bool IsIOFloat, const int Clamp ) + { + if( IsIOFloat ) + { + while( l > 0 ) + { + op[ 0 ] = (T) ip[ 0 ]; + op[ 1 ] = (T) ip[ 1 ]; + op[ 2 ] = (T) ip[ 2 ]; + ip += 3; + op += opinc; + l--; + } + } + else + { + while( l > 0 ) + { + op[ 0 ] = (T) roundclamp( ip[ 0 ], Clamp ); + op[ 1 ] = (T) roundclamp( ip[ 1 ], Clamp ); + op[ 2 ] = (T) roundclamp( ip[ 2 ], Clamp ); + ip += 3; + op += opinc; + l--; + } + } + } + + template< class T > + static void copyOutput4( const float* ip, T* op, int l, const int opinc, + const bool IsIOFloat, const int Clamp ) + { + if( IsIOFloat ) + { + while( l > 0 ) + { + op[ 0 ] = (T) ip[ 0 ]; + op[ 1 ] = (T) ip[ 1 ]; + op[ 2 ] = (T) ip[ 2 ]; + op[ 3 ] = (T) ip[ 3 ]; + ip += 4; + op += opinc; + l--; + } + } + else + { + while( l > 0 ) + { + op[ 0 ] = (T) roundclamp( ip[ 0 ], Clamp ); + op[ 1 ] = (T) roundclamp( ip[ 1 ], Clamp ); + op[ 2 ] = (T) roundclamp( ip[ 2 ], Clamp ); + op[ 3 ] = (T) roundclamp( ip[ 3 ], Clamp ); + ip += 4; + op += opinc; + l--; + } + } + } + + class CResizeScanline; + + /** + * Class implements fractional delay filter bank calculation. + */ + + class CResizeFilters + { + friend class CResizeScanline; + + public: + int KernelLen; ///< Resampling filter kernel length, taps. Available + ///< after the update() function call. + ///< + + CResizeFilters() + : FilterBuf( NULL ) + , Filters( NULL ) + , Prevla( -1.0 ) + , Prevk( -1.0 ) + , FilterBufLen( 0 ) + , FiltersLen( 0 ) + { + } + + ~CResizeFilters() + { + free( FilterBuf ); + delete[] Filters; + } + + /** + * Function updates the resizing filter bank. + * + * @param la Lanczos "a" parameter value. + * @param k Resizing step. + * @return "True" if update occured and resizing positions should be + * updated unconditionally. + */ + + bool update( const double la, const double k ) + { + if( la == Prevla && k == Prevk ) + { + return( false ); + } + + Prevla = la; + Prevk = k; + + NormFreq = ( k <= 1.0 ? 1.0 : 1.0 / k ); + Freq = LANCIR_PI * NormFreq; + + if( Freq > LANCIR_PI ) + { + Freq = LANCIR_PI; + } + + FreqA = LANCIR_PI * NormFreq / la; + Len2 = la / NormFreq; + fl2 = (int) ceil( Len2 ); + KernelLen = fl2 + fl2; + + FracCount = 607; // For 8-bit precision. + FracFill = 0; + + const int FilterBufLenNew = FracCount * KernelLen; + + if( FilterBufLenNew > FilterBufLen ) + { + free( FilterBuf ); + FilterBufLen = FilterBufLenNew; + FilterBuf = (float *) memalign( 32, sizeof(float) * FilterBufLen ); + CHECK_NOTNULL(FilterBuf); + } + + if( FracCount > FiltersLen ) + { + delete[] Filters; + FiltersLen = FracCount; + Filters = new float*[ FiltersLen ]; + } + + memset( Filters, 0, FracCount * sizeof( float* )); + + return( true ); + } + + /** + * Function returns filter at the specified fractional offset. This + * function can only be called before the prior update() function + * call. + * + * @param x Fractional offset, [0; 1). + */ + + float* getFilter( const double x ) + { + const int Frac = (int) floor( x * FracCount ); + + if( Filters[ Frac ] == NULL ) + { + Filters[ Frac ] = FilterBuf + FracFill * KernelLen; + FracFill++; + makeFilter( 1.0 - (double) Frac / FracCount, Filters[ Frac ]); + normalizeFilter( Filters[ Frac ]); + } + + return( Filters[ Frac ]); + } + + protected: + double NormFreq; ///< Normalized frequency of the filter. + ///< + double Freq; ///< Circular frequency of the filter. + ///< + double FreqA; ///< Circular frequency of the window function. + ///< + double Len2; ///< Half resampling filter length, unrounded. + ///< + int fl2; ///< Half resampling length, integer. + ///< + int FracCount; ///< The number of fractional positions for which + ///< filters are created. + ///< + int FracFill; ///< The number of fractional positions filled in the + ///< filter buffer. + ///< + float* FilterBuf; ///< Buffer that holds all filters. + ///< + float** Filters; ///< Fractional delay filters for all positions. + ///< Filter pointers equal NULL if filter was not yet created. + ///< + double Prevla; ///< Previous "la". + ///< + double Prevk; ///< Previous "k". + ///< + int FilterBufLen; ///< Allocated length of FilterBuf in elements. + ///< + int FiltersLen; ///< Allocated length of Filters in elements. + ///< + + /** + * @brief Sine signal generator class. + * + * Class implements sine signal generator without biasing, with + * constructor-based initalization only. This generator uses + * oscillator instead of "sin" function. + */ + + class CSinGen + { + public: + /** + * Constructor initializes *this sine signal generator. + * + * @param si Sine function increment, in radians. + * @param ph Starting phase, in radians. Add 0.5 * LANCIR_PI for + * cosine function. + * @param g Gain value. + */ + + CSinGen( const double si, const double ph, const double g = 1.0 ) + : svalue1( sin( ph ) * g ) + , svalue2( sin( ph - si ) * g ) + , sincr( 2.0 * cos( si )) + { + } + + /** + * @return The next value of the sine function, without biasing. + */ + + double generate() + { + const double res = svalue1; + + svalue1 = sincr * res - svalue2; + svalue2 = res; + + return( res ); + } + + private: + double svalue1; ///< Current sine value. + ///< + double svalue2; ///< Previous sine value. + ///< + double sincr; ///< Sine value increment. + ///< + }; + + /** + * Function creates filter for the specified fractional delay. The + * update() function should be called prior to calling this function. + * + * @param FracDelay Fractional delay, 0 to 1, inclusive. + * @param[out] Output filter buffer. + * @tparam T Output buffer type. + */ + + template< class T > + void makeFilter( const double FracDelay, T* op ) const + { + CSinGen f( Freq, Freq * ( FracDelay - fl2 )); + CSinGen fw( FreqA, FreqA * ( FracDelay - fl2 ), Len2 ); + + int t = -fl2; + + if( t + FracDelay < -Len2 ) + { + f.generate(); + fw.generate(); + *op = (T) 0.0; + op++; + t++; + } + + int mt = ( FracDelay >= 1.0 - 1e-13 && FracDelay <= 1.0 + 1e-13 ? + -1 : 0 ); + + while( t < mt ) + { + double ut = ( t + FracDelay ) * LANCIR_PI; + *op = (T) ( f.generate() * fw.generate() / ( ut * ut )); + op++; + t++; + } + + double ut = t + FracDelay; + + if( fabs( ut ) <= 1e-13 ) + { + *op = (T) NormFreq; + f.generate(); + fw.generate(); + } + else + { + ut *= LANCIR_PI; + *op = (T) ( f.generate() * fw.generate() / ( ut * ut )); + } + + mt = fl2 - 2; + + while( t < mt ) + { + op++; + t++; + ut = ( t + FracDelay ) * LANCIR_PI; + *op = (T) ( f.generate() * fw.generate() / ( ut * ut )); + } + + op++; + t++; + ut = t + FracDelay; + + if( ut > Len2 ) + { + *op = (T) 0.0; + } + else + { + ut *= LANCIR_PI; + *op = (T) ( f.generate() * fw.generate() / ( ut * ut )); + } + } + + /** + * Function normalizes the specified filter so that it has unity gain + * at DC. + * + * @param p Filter buffer pointer. + * @tparam T Filter buffer type. + */ + + template< class T > + void normalizeFilter( T* const p ) const + { + double s = 0.0; + size_t i; + + for( i = 0; i < KernelLen; i++ ) + { + s += p[ i ]; + } + + s = 1.0 / s; + + for( i = 0; i < KernelLen; i++ ) + { + p[ i ] = (T) ( p[ i ] * s ); + } + } + }; + + /** + * Structure defines source scanline positioning and filters for each + * destination pixel. + */ + + struct CResizePos + { + const float* ip; ///< Source image pixel pointer. + ///< + float* flt; ///< Fractional delay filter. + ///< + }; + + /** + * Class contains resizing positioning and a temporary scanline buffer, + * prepares source scanline positions for resize filtering. + */ + + class CResizeScanline + { + public: + int padl; ///< Left-padding (in pixels) required for source scanline. + ///< Available after the update() function call. + ///< + int padr; ///< Right-padding (in pixels) required for source scanline. + ///< Available after the update() function call. + ///< + float* sp; ///< Source scanline buffer, with "padl" and "padr" + ///< padding. + ///< + CResizePos* pos; ///< Source scanline pointers (point to "sp") + ///< and filters for each destination pixel position. Available + ///< after the update() function call. + ///< + + CResizeScanline() + : sp( NULL ) + , pos( NULL ) + , PrevSrcLen( -1 ) + , PrevDstLen( -1 ) + , Prevk( 0.0 ) + , Prevo( 0.0 ) + , PrevElCount( 0 ) + , splen( 0 ) + , poslen( 0 ) + { + } + + ~CResizeScanline() + { + free( sp ); + delete[] pos; + } + + /** + * Function "resets" *this object so that the next update() call fully + * updates the position buffer. Reset is necessary if the filter + * object was updated. + */ + + void reset() + { + PrevSrcLen = -1; + } + + /** + * Function updates resizing positions, updates "padl", "padr" and + * "pos" buffer. + * + * @param k Resizing step. + * @param o0 Initial source image offset. + * @param SrcLen Source image scanline length, used to create a + * scanline buffer without length pre-calculation. + * @param DstLen Destination image scanline length. + * @param rf Resizing filters object. + */ + + void update( const double k, const double o0, const int ElCount, + const int SrcLen, const size_t DstLen, CResizeFilters& rf ) + { + if( SrcLen == PrevSrcLen && DstLen == PrevDstLen && + k == Prevk && o0 == Prevo && ElCount == PrevElCount ) + { + return; + } + + PrevSrcLen = SrcLen; + PrevDstLen = DstLen; + Prevk = k; + Prevo = o0; + PrevElCount = ElCount; + + const int fl2m1 = rf.fl2 - 1; + padl = fl2m1 - (int) floor( o0 ); + + if( padl < 0 ) + { + padl = 0; + } + + padr = (int) floor( o0 + k * ( DstLen - 1 )) + rf.fl2 + 1 - + SrcLen; + + if( padr < 0 ) + { + padr = 0; + } + + const int splennew = ( padl + SrcLen + padr ) * ElCount; + + if( splennew > splen ) + { + free( sp ); + splen = splennew; + sp = (float *) memalign( 32, sizeof(float) * splen ); + CHECK_NOTNULL(sp); + } + + if( DstLen > poslen ) + { + delete[] pos; + poslen = DstLen; + pos = new CResizePos[ poslen ]; + } + + const float* const spo = sp + ( padl - fl2m1 ) * ElCount; + size_t i; + + for( i = 0; i < DstLen; i++ ) + { + const double o = o0 + k * i; + const int ix = (int) floor( o ); + pos[ i ].ip = spo + ix * ElCount; + pos[ i ].flt = rf.getFilter( o - ix ); + } + } + + protected: + int PrevSrcLen; ///< Previous SrcLen. + ///< + int PrevDstLen; ///< Previous DstLen. + ///< + double Prevk; ///< Previous "k". + ///< + double Prevo; ///< Previous "o". + ///< + int PrevElCount; ///< Previous pixel element count. + ///< + int splen; ///< Allocated "sp" buffer length. + ///< + int poslen; ///< Allocated "pos" buffer length. + ///< + }; + + CResizeFilters rfh; ///< Resizing filters for horizontal resizing. + ///< + CResizeFilters rfv0; ///< Resizing filters for vertical resizing (may not + ///< be in use). + ///< + CResizeScanline rsh; ///< Horizontal resize scanline. + ///< + CResizeScanline rsv; ///< Vertical resize scanline. + ///< + + /** + * Function copies scanline from the source buffer in its native format + * to internal scanline buffer, in preparation for horizontal resizing. + * Variants for 1-4-channel images. + * + * @param ip Source scanline buffer. + * @param rs Scanline resizing positions object. + * @param l Source scanline length, in pixels. + * @param ipinc "ip" increment per pixel. + */ + + template< class T > + static void copyScanline1h( const T* ip, CResizeScanline& rs, const int l ) + { + float* op = rs.sp; + int i; + + DCHECK_ALIGNED(32, op); + + for( i = 0; i < rs.padl; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op++; + } + + for( i = 0; i < l - 1; i++ ) + { + op[ 0 ] = ip[ 0 ]; + ip++; + op++; + } + + for( i = 0; i <= rs.padr; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op++; + } + } + + template< class T > + static void copyScanline2h( const T* ip, CResizeScanline& rs, const int l ) + { + float* op = rs.sp; + int i; + + for( i = 0; i < rs.padl; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op += 2; + } + + for( i = 0; i < l - 1; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + ip += 2; + op += 2; + } + + for( i = 0; i <= rs.padr; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op += 2; + } + } + + template< class T > + static void copyScanline3h( const T* ip, CResizeScanline& rs, const int l ) + { + float* op = rs.sp; + int i; + + for( i = 0; i < rs.padl; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op[ 2 ] = ip[ 2 ]; + op += 3; + } + + for( i = 0; i < l - 1; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op[ 2 ] = ip[ 2 ]; + ip += 3; + op += 3; + } + + for( i = 0; i <= rs.padr; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op[ 2 ] = ip[ 2 ]; + op += 3; + } + } + + template< class T > + static void copyScanline4h( const T* ip, CResizeScanline& rs, const size_t l ) + { + float* op = rs.sp; + size_t i; + + for( i = 0; i < rs.padl; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op[ 2 ] = ip[ 2 ]; + op[ 3 ] = ip[ 3 ]; + op += 4; + } + + for( i = 0; i < l - 1; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op[ 2 ] = ip[ 2 ]; + op[ 3 ] = ip[ 3 ]; + ip += 4; + op += 4; + } + + for( i = 0; i <= rs.padr; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op[ 2 ] = ip[ 2 ]; + op[ 3 ] = ip[ 3 ]; + op += 4; + } + } + + /** + * Function copies scanline from the source buffer in its native format + * to internal scanline buffer, in preparation for vertical resizing. + * Variants for 1-4-channel images. + * + * @param ip Source scanline buffer. + * @param rs Scanline resizing positions object. + * @param l Source scanline length, in pixels. + * @param ipinc "ip" increment per pixel. + */ + + template< class T > + static void copyScanline1v( const T* ip, CResizeScanline& rs, const int l, + const int ipinc ) + { + float* op = rs.sp; + int i; + + DCHECK_ALIGNED(32, op); + + for( i = 0; i < rs.padl; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op++; + } + + for( i = 0; i < l - 1; i++ ) + { + op[ 0 ] = ip[ 0 ]; + ip += ipinc; + op++; + } + + for( i = 0; i <= rs.padr; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op++; + } + } + + template< class T > + static void copyScanline2v( const T* ip, CResizeScanline& rs, const int l, + const int ipinc ) + { + float* op = rs.sp; + int i; + + for( i = 0; i < rs.padl; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op += 2; + } + + for( i = 0; i < l - 1; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + ip += ipinc; + op += 2; + } + + for( i = 0; i <= rs.padr; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op += 2; + } + } + + template< class T > + static void copyScanline3v( const T* ip, CResizeScanline& rs, const int l, + const int ipinc ) + { + float* op = rs.sp; + int i; + + for( i = 0; i < rs.padl; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op[ 2 ] = ip[ 2 ]; + op += 3; + } + + for( i = 0; i < l - 1; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op[ 2 ] = ip[ 2 ]; + ip += ipinc; + op += 3; + } + + for( i = 0; i <= rs.padr; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op[ 2 ] = ip[ 2 ]; + op += 3; + } + } + + template< class T > + static void copyScanline4v( const T* ip, CResizeScanline& rs, const size_t l, + const int ipinc ) + { + float* op = rs.sp; + size_t i; + + for( i = 0; i < rs.padl; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op[ 2 ] = ip[ 2 ]; + op[ 3 ] = ip[ 3 ]; + op += 4; + } + + for( i = 0; i < l - 1; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op[ 2 ] = ip[ 2 ]; + op[ 3 ] = ip[ 3 ]; + ip += ipinc; + op += 4; + } + + for( i = 0; i <= rs.padr; i++ ) + { + op[ 0 ] = ip[ 0 ]; + op[ 1 ] = ip[ 1 ]; + op[ 2 ] = ip[ 2 ]; + op[ 3 ] = ip[ 3 ]; + op += 4; + } + } + + #define LANCIR_LF_PRE \ + CResizePos* const rpe = rp + DstLen; \ + while( rp < rpe ) \ + { \ + const float* ip = rp -> ip; \ + const float* const flt = rp -> flt; + + #define LANCIR_LF_POST \ + rp++; \ + } + + static void resize1_kl6( float* op, int DstLen, CResizePos* rp ) + { + LANCIR_LF_PRE + op[ 0 ] = + flt[ 0 ] * ip[ 0 ] + + flt[ 1 ] * ip[ 1 ] + + flt[ 2 ] * ip[ 2 ] + + flt[ 3 ] * ip[ 3 ] + + flt[ 4 ] * ip[ 4 ] + + flt[ 5 ] * ip[ 5 ]; + op++; + LANCIR_LF_POST + } + + static void resize1_kln( float* op, int DstLen, CResizePos* rp, const int kl ) + { + LANCIR_LF_PRE + float sum = 0.0; + int i; + for( i = 0; i < kl; i++ ) + { + sum += flt[ i ] * ip[ i ]; + } + op[ 0 ] = sum; + op++; + LANCIR_LF_POST + } + + /** + * Function performs internal scanline resizing. Variants for 1-4-channel + * images. + * + * @param op Destination buffer. + * @param DstLen Destination length, in pixels. + * @param rp Resizing positions and filters. + * @param kl Filter kernel length, in taps. + */ + static void resize1( float* op, int DstLen, CResizePos* rp, const int kl ) + { + if( kl == 6 ) + { + resize1_kl6( op, DstLen, rp ); + } + else + { + resize1_kln( op, DstLen, rp, kl ); + } + } + + static void resize2( float* op, int DstLen, CResizePos* rp, const int kl ) + { + if( kl == 6 ) + { + LANCIR_LF_PRE + op[ 0 ] = + flt[ 0 ] * ip[ 0 ] + + flt[ 1 ] * ip[ 2 ] + + flt[ 2 ] * ip[ 4 ] + + flt[ 3 ] * ip[ 6 ] + + flt[ 4 ] * ip[ 8 ] + + flt[ 5 ] * ip[ 10 ]; + + op[ 1 ] = + flt[ 0 ] * ip[ 1 ] + + flt[ 1 ] * ip[ 3 ] + + flt[ 2 ] * ip[ 5 ] + + flt[ 3 ] * ip[ 7 ] + + flt[ 4 ] * ip[ 9 ] + + flt[ 5 ] * ip[ 11 ]; + + op += 2; + LANCIR_LF_POST + } + else + { + LANCIR_LF_PRE + float sum[ 2 ]; + sum[ 0 ] = 0.0; + sum[ 1 ] = 0.0; + int i; + + for( i = 0; i < kl; i++ ) + { + const float xx = flt[ i ]; + sum[ 0 ] += xx * ip[ 0 ]; + sum[ 1 ] += xx * ip[ 1 ]; + ip += 2; + } + + op[ 0 ] = sum[ 0 ]; + op[ 1 ] = sum[ 1 ]; + op += 2; + LANCIR_LF_POST + } + } + + static void resize3( float* op, int DstLen, CResizePos* rp, const int kl ) + { + if( kl == 6 ) + { + LANCIR_LF_PRE + op[ 0 ] = + flt[ 0 ] * ip[ 0 ] + + flt[ 1 ] * ip[ 3 ] + + flt[ 2 ] * ip[ 6 ] + + flt[ 3 ] * ip[ 9 ] + + flt[ 4 ] * ip[ 12 ] + + flt[ 5 ] * ip[ 15 ]; + + op[ 1 ] = + flt[ 0 ] * ip[ 1 ] + + flt[ 1 ] * ip[ 4 ] + + flt[ 2 ] * ip[ 7 ] + + flt[ 3 ] * ip[ 10 ] + + flt[ 4 ] * ip[ 13 ] + + flt[ 5 ] * ip[ 16 ]; + + op[ 2 ] = + flt[ 0 ] * ip[ 2 ] + + flt[ 1 ] * ip[ 5 ] + + flt[ 2 ] * ip[ 8 ] + + flt[ 3 ] * ip[ 11 ] + + flt[ 4 ] * ip[ 14 ] + + flt[ 5 ] * ip[ 17 ]; + + op += 3; + LANCIR_LF_POST + } + else + { + LANCIR_LF_PRE + float sum[ 3 ]; + sum[ 0 ] = 0.0; + sum[ 1 ] = 0.0; + sum[ 2 ] = 0.0; + int i; + + for( i = 0; i < kl; i++ ) + { + const float xx = flt[ i ]; + sum[ 0 ] += xx * ip[ 0 ]; + sum[ 1 ] += xx * ip[ 1 ]; + sum[ 2 ] += xx * ip[ 2 ]; + ip += 3; + } + + op[ 0 ] = sum[ 0 ]; + op[ 1 ] = sum[ 1 ]; + op[ 2 ] = sum[ 2 ]; + op += 3; + LANCIR_LF_POST + } + } + + static optimizespeed void resize4( float* op, int DstLen, CResizePos* rp, const size_t kl ) + { + LANCIR_LF_PRE + float sum[ 4 ]; + sum[ 0 ] = 0.0; + sum[ 1 ] = 0.0; + sum[ 2 ] = 0.0; + sum[ 3 ] = 0.0; + size_t i; + + for( i = 0; i < kl; i++ ) + { + const float xx = flt[ i ]; + sum[ 0 ] += xx * ip[ 0 ]; + sum[ 1 ] += xx * ip[ 1 ]; + sum[ 2 ] += xx * ip[ 2 ]; + sum[ 3 ] += xx * ip[ 3 ]; + ip += 4; + } + + op[ 0 ] = sum[ 0 ]; + op[ 1 ] = sum[ 1 ]; + op[ 2 ] = sum[ 2 ]; + op[ 3 ] = sum[ 3 ]; + op += 4; + LANCIR_LF_POST + } + + #undef LANCIR_LF_PRE + #undef LANCIR_LF_POST + + static relegated nooptimize noinline void handleEmptySrcCornerCase( + void * const NewBuf, const size_t Size ) + { + memset( NewBuf, 0, Size ); + } +}; + +#undef LANCIR_PI + +} // namespace avir + +#endif // AVIR_CLANCIR_INCLUDED diff --git a/third_party/avir/lanczos.cc b/third_party/avir/lanczos.cc new file mode 100644 index 00000000..ae4c8b49 --- /dev/null +++ b/third_party/avir/lanczos.cc @@ -0,0 +1,40 @@ +/*-*-mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8-*-│ +│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/limits.h" +#include "libc/log/check.h" +#include "libc/log/log.h" +#include "third_party/avir/lanczos.h" +namespace { +#include "third_party/avir/lancir.h" +} // namespace + +/** + * Does Lanczos interpolation. + * @note computers w/o AVX2+FMA need to call BilinearScale() + */ +void lanczos(unsigned dyn, unsigned dxn, void *restrict dst, unsigned syn, + unsigned sxn, const void *restrict src, unsigned sw) { + avir::CLancIR lanczos; + DCHECK_ALIGNED(64, dst); + DCHECK_ALIGNED(64, src); + LOGF("%10s%5zux×%-5zu→%5zu×%-5zu", "lanczos", sxn, syn, dxn, dyn); + lanczos.resizeImage((const float *)src, sxn, syn, sw, (float *)dst, dxn, dyn, + 4); +} diff --git a/third_party/avir/lanczos.h b/third_party/avir/lanczos.h new file mode 100644 index 00000000..18395a7e --- /dev/null +++ b/third_party/avir/lanczos.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS_H_ +#define COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +void lanczos(unsigned, unsigned, void *, unsigned, unsigned, const void *, + unsigned); +void lanczos3(unsigned, unsigned, void *, unsigned, unsigned, const void *, + unsigned); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS_H_ */ diff --git a/third_party/avir/lanczos1.cc b/third_party/avir/lanczos1.cc new file mode 100644 index 00000000..c35751d6 --- /dev/null +++ b/third_party/avir/lanczos1.cc @@ -0,0 +1,77 @@ +/*-*-mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8-*-│ +│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/xmmintrin.h" +#include "libc/limits.h" +#include "libc/log/log.h" +#include "libc/runtime/runtime.h" +#include "third_party/avir/lanczos1.h" +namespace { +#include "third_party/avir/lanczos1.hpp" +} // namespace + +void lanczos1init(struct lanczos1 *resizer) { + lanczos1free(resizer); + resizer->p = new Lanczos1Impl; +} + +void lanczos1free(struct lanczos1 *resizer) { + Lanczos1Impl *impl; + if (!resizer->p) return; + impl = (Lanczos1Impl *)resizer->p; + delete impl; + resizer->p = nullptr; +} + +/** + * Resizes image plane w/ Lanczos interpolation, e.g. + * + * struct lanczos1 scaler = {0}; + * lanczos1init(&scaler); + * lanczos1(&scaler, ...); + * lanczos1free(&scaler); + * + * @param dyn is destination height + * @param dxn is destination width + * @param dst is destination unsigned char array + * @param dstsize is number of bytes in dst + * @param syn is source height + * @param sxn is source width + * @param ssw is number of unsigned chars per scanline in src + * @param src is source unsigned char array + * @param srcsize is number of bytes in src + */ +void lanczos1(struct lanczos1 *resizer, size_t dyn, size_t dxn, void *dst, + size_t dstsize, size_t syn, size_t sxn, size_t ssw, + const void *src, size_t srcsize) { + Lanczos1Impl *impl; + unsigned int roundhouse; + LOGF("%10s%5zux×%-5zu→%5zu×%-5zu", "lanczos1", sxn, syn, dxn, dyn); + CHECK_LE(dstsize, INT_MAX); + CHECK_LE(srcsize, INT_MAX); + CHECK_LE(sizeof(unsigned char) * 1 * dyn * dxn, dstsize); + CHECK_LE(sizeof(unsigned char) * 1 * syn * sxn, srcsize); + CHECK_LE(sizeof(unsigned char) * syn * ssw, srcsize); + roundhouse = _MM_GET_ROUNDING_MODE(); + _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST); + impl = (Lanczos1Impl *)resizer->p; + impl->lanczos.resizeImage((const unsigned char *)src, sxn, syn, ssw, + (unsigned char *)dst, dxn, dyn, 1); + _MM_SET_ROUNDING_MODE(roundhouse); +} diff --git a/third_party/avir/lanczos1.h b/third_party/avir/lanczos1.h new file mode 100644 index 00000000..490841ff --- /dev/null +++ b/third_party/avir/lanczos1.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1_H_ +#define COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct lanczos1 { + void *p; +}; + +void lanczos1init(struct lanczos1 *self); +void lanczos1free(struct lanczos1 *self); +void lanczos1(struct lanczos1 *self, size_t dyn, size_t dxn, void *dst, + size_t dstsize, size_t syn, size_t sxn, size_t ssw, + const void *src, size_t srcsize) paramsnonnull(); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1_H_ */ diff --git a/third_party/avir/lanczos1.hpp b/third_party/avir/lanczos1.hpp new file mode 100644 index 00000000..07e9bd6a --- /dev/null +++ b/third_party/avir/lanczos1.hpp @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1_HPP_ +#define COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1_HPP_ +#include "third_party/avir/lancir.h" + +struct Lanczos1Impl { + Lanczos1Impl() : lanczos{} { + } + avir::CLancIR lanczos; +}; + +#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1_HPP_ */ diff --git a/third_party/avir/lanczos1b.cc b/third_party/avir/lanczos1b.cc new file mode 100644 index 00000000..9ec2bace --- /dev/null +++ b/third_party/avir/lanczos1b.cc @@ -0,0 +1,31 @@ +/*-*-mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8-*-│ +│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/bits.h" +#include "third_party/avir/lanczos1b.h" +namespace { +#include "third_party/avir/lancir.h" +} // namespace + +void lanczos1b(size_t dyn, size_t dxn, unsigned char *restrict dst, size_t syn, + size_t sxn, const unsigned char *restrict src) { + avir::CLancIR lanczos; + LOGF("%10s%5zux×%-5zu→%5zu×%-5zu", "lanczos1b", sxn, syn, dxn, dyn); + lanczos.resizeImage(src, sxn, syn, roundup2pow(sxn) * 4, dst, dxn, dyn, 4); +} diff --git a/third_party/avir/lanczos1b.h b/third_party/avir/lanczos1b.h new file mode 100644 index 00000000..2e21c734 --- /dev/null +++ b/third_party/avir/lanczos1b.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1B_H_ +#define COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1B_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +void lanczos1b(size_t dyn, size_t dxn, unsigned char *restrict dst, size_t syn, + size_t sxn, const unsigned char *restrict src); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1B_H_ */ diff --git a/third_party/avir/lanczos1f.cc b/third_party/avir/lanczos1f.cc new file mode 100644 index 00000000..5e0036e9 --- /dev/null +++ b/third_party/avir/lanczos1f.cc @@ -0,0 +1,63 @@ +/*-*-mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8-*-│ +│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/xmmintrin.h" +#include "libc/runtime/runtime.h" +#include "third_party/avir/lanczos1f.h" +namespace { +#include "third_party/avir/lanczos1f.hpp" +} // namespace + +void lanczos1finit(struct lanczos1f *resizer) { + lanczos1ffree(resizer); + resizer->p = new Lanczos1fImpl; +} + +void lanczos1ffree(struct lanczos1f *resizer) { + Lanczos1fImpl *impl; + if (!resizer->p) return; + impl = (Lanczos1fImpl *)resizer->p; + delete impl; + resizer->p = nullptr; +} + +/** + * Resizes image plane w/ Lanczos interpolation, e.g. + * + * struct lanczos1f scaler = {0}; + * lanczos1finit(&scaler); + * lanczos1f(&scaler, ...); + * lanczos1ffree(&scaler); + * + * @param dyn is destination height + * @param dxn is destination width + * @param dst is destination unsigned char array + * @param syn is source height + * @param sxn is source width + * @param ssw is number of unsigned chars per scanline in src + * @param src is source unsigned char array + */ +void lanczos1f(struct lanczos1f *resizer, size_t dyn, size_t dxn, void *dst, + size_t syn, size_t sxn, size_t ssw, const void *src, double ky0, + double kx0, double oy, double ox) { + Lanczos1fImpl *impl; + impl = (Lanczos1fImpl *)resizer->p; + impl->lanczos.resizeImage((const float *)src, sxn, syn, ssw, (float *)dst, + dxn, dyn, 1, kx0, ky0, ox, oy); +} diff --git a/third_party/avir/lanczos1f.h b/third_party/avir/lanczos1f.h new file mode 100644 index 00000000..cba61c32 --- /dev/null +++ b/third_party/avir/lanczos1f.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1F_H_ +#define COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1F_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct lanczos1f { + void *p; +}; + +void lanczos1finit(struct lanczos1f *); +void lanczos1ffree(struct lanczos1f *); +void lanczos1f(struct lanczos1f *, size_t, size_t, void *, size_t, size_t, + size_t, const void *, double, double, double, double) + paramsnonnull(); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1F_H_ */ diff --git a/third_party/avir/lanczos1f.hpp b/third_party/avir/lanczos1f.hpp new file mode 100644 index 00000000..cc821058 --- /dev/null +++ b/third_party/avir/lanczos1f.hpp @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1F_HPP_ +#define COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1F_HPP_ +#include "third_party/avir/lancir.h" + +struct Lanczos1fImpl { + Lanczos1fImpl() : lanczos{} { + } + avir::CLancIR lanczos; +}; + +#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1F_HPP_ */ diff --git a/third_party/avir/lanczos3.cc b/third_party/avir/lanczos3.cc new file mode 100644 index 00000000..d64e8f7f --- /dev/null +++ b/third_party/avir/lanczos3.cc @@ -0,0 +1,30 @@ +/*-*-mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8-*-│ +│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "third_party/avir/lanczos.h" +namespace { +#include "third_party/avir/lancir.h" +} + +void lanczos3(unsigned dyn, unsigned dxn, void *dst, unsigned syn, unsigned sxn, + const void *src, unsigned sw) { + avir::CLancIR lanczos; + lanczos.resizeImage((const float *)src, sxn, syn, sw, (float *)dst, dxn, dyn, + 3, -1, -2); +} diff --git a/third_party/avir/notice.h b/third_party/avir/notice.h new file mode 100644 index 00000000..2ca1f2c4 --- /dev/null +++ b/third_party/avir/notice.h @@ -0,0 +1,11 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_NOTICE_H_ +#define COSMOPOLITAN_THIRD_PARTY_AVIR_NOTICE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +asm(".ident\t\"\\n\\n\ +AVIR (MIT License)\\n\ +Copyright 2015-2019 Aleksey Vaneev\""); +asm(".include \"libc/disclaimer.inc\""); + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_NOTICE_H_ */ diff --git a/third_party/avir/resize.cc b/third_party/avir/resize.cc new file mode 100644 index 00000000..d7d7eba9 --- /dev/null +++ b/third_party/avir/resize.cc @@ -0,0 +1,48 @@ +/*-*-mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8-*-│ +│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "third_party/avir/resize.h" +namespace { +#include "third_party/avir/avir_float4_sse.h" +} // namespace + +struct ResizerImpl { + ResizerImpl() : resizer{8, 8, avir::CImageResizerParamsULR()} {} + avir::CImageResizer resizer; +}; + +void NewResizer(Resizer *resizer, int aResBitDepth, int aSrcBitDepth) { + FreeResizer(resizer); + resizer->p = new ResizerImpl(); +} + +void FreeResizer(Resizer *resizer) { + if (!resizer->p) return; + delete (ResizerImpl *)resizer->p; + resizer->p = nullptr; +} + +void ResizeImage(Resizer *resizer, float *Dest, int DestHeight, int DestWidth, + const float *Src, int SrcHeight, int SrcWidth) { + ResizerImpl *impl = (ResizerImpl *)resizer->p; + int SrcScanLineSize = 0; + double ResizingStep = 0; + impl->resizer.resizeImage(Src, SrcWidth, SrcHeight, SrcScanLineSize, Dest, + DestWidth, DestHeight, 4, ResizingStep); +} diff --git a/third_party/avir/resize.h b/third_party/avir/resize.h new file mode 100644 index 00000000..6d4871bf --- /dev/null +++ b/third_party/avir/resize.h @@ -0,0 +1,17 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_RESIZE_H_ +#define COSMOPOLITAN_THIRD_PARTY_AVIR_RESIZE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct Resizer { + void *p; +}; + +void FreeResizer(struct Resizer *) paramsnonnull(); +void NewResizer(struct Resizer *, int, int) paramsnonnull(); +void ResizeImage(struct Resizer *, float *, int, int, const float *, int, int) + paramsnonnull(); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_RESIZE_H_ */ diff --git a/third_party/blas/blas.h b/third_party/blas/blas.h new file mode 100644 index 00000000..98fb8f1d --- /dev/null +++ b/third_party/blas/blas.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_BLAS_BLAS_H_ +#define COSMOPOLITAN_THIRD_PARTY_BLAS_BLAS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +int dgemm_(char *transa, char *transb, long *m, long *n, long *k, double *alpha, + double *A /*['N'?k:m][1≤m≤lda]*/, long *lda, + double *B /*['N'?k:n][1≤n≤ldb]*/, long *ldb, double *beta, + double *C /*[n][1≤m≤ldc]*/, long *ldc); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_BLAS_BLAS_H_ */ diff --git a/third_party/blas/blas.mk b/third_party/blas/blas.mk new file mode 100644 index 00000000..7122c6fe --- /dev/null +++ b/third_party/blas/blas.mk @@ -0,0 +1,59 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += THIRD_PARTY_BLAS + +THIRD_PARTY_BLAS_ARTIFACTS += THIRD_PARTY_BLAS_A +THIRD_PARTY_BLAS = $(THIRD_PARTY_BLAS_A_DEPS) $(THIRD_PARTY_BLAS_A) +THIRD_PARTY_BLAS_A = o/$(MODE)/third_party/blas/blas.a +THIRD_PARTY_BLAS_A_FILES := $(wildcard third_party/blas/*) +THIRD_PARTY_BLAS_A_HDRS = $(filter %.h,$(THIRD_PARTY_BLAS_A_FILES)) +THIRD_PARTY_BLAS_A_SRCS_S = $(filter %.S,$(THIRD_PARTY_BLAS_A_FILES)) +THIRD_PARTY_BLAS_A_SRCS_C = $(filter %.c,$(THIRD_PARTY_BLAS_A_FILES)) + +THIRD_PARTY_BLAS_A_SRCS = \ + $(THIRD_PARTY_BLAS_A_SRCS_S) \ + $(THIRD_PARTY_BLAS_A_SRCS_C) + +THIRD_PARTY_BLAS_A_OBJS = \ + $(THIRD_PARTY_BLAS_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(THIRD_PARTY_BLAS_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(THIRD_PARTY_BLAS_A_SRCS_C:%.c=o/$(MODE)/%.o) + +THIRD_PARTY_BLAS_A_CHECKS = \ + $(THIRD_PARTY_BLAS_A).pkg \ + $(THIRD_PARTY_BLAS_A_HDRS:%=o/$(MODE)/%.ok) + +THIRD_PARTY_BLAS_A_DIRECTDEPS = \ + LIBC_STUBS \ + LIBC_NEXGEN32E \ + THIRD_PARTY_F2C + +THIRD_PARTY_BLAS_A_DEPS := \ + $(call uniq,$(foreach x,$(THIRD_PARTY_BLAS_A_DIRECTDEPS),$($(x)))) + +$(THIRD_PARTY_BLAS_A_OBJS): \ + OVERRIDE_CFLAGS += \ + -O3 #$(MATHEMATICAL) + +#$(THIRD_PARTY_BLAS_A_OBJS): \ + CC = $(CLANG) + +$(THIRD_PARTY_BLAS_A): \ + third_party/blas/ \ + $(THIRD_PARTY_BLAS_A).pkg \ + $(THIRD_PARTY_BLAS_A_OBJS) + +$(THIRD_PARTY_BLAS_A).pkg: \ + $(THIRD_PARTY_BLAS_A_OBJS) \ + $(foreach x,$(THIRD_PARTY_BLAS_A_DIRECTDEPS),$($(x)_A).pkg) + +THIRD_PARTY_BLAS_LIBS = $(foreach x,$(THIRD_PARTY_BLAS_ARTIFACTS),$($(x))) +THIRD_PARTY_BLAS_SRCS = $(foreach x,$(THIRD_PARTY_BLAS_ARTIFACTS),$($(x)_SRCS)) +THIRD_PARTY_BLAS_HDRS = $(foreach x,$(THIRD_PARTY_BLAS_ARTIFACTS),$($(x)_HDRS)) +THIRD_PARTY_BLAS_CHECKS = $(foreach x,$(THIRD_PARTY_BLAS_ARTIFACTS),$($(x)_CHECKS)) +THIRD_PARTY_BLAS_OBJS = $(foreach x,$(THIRD_PARTY_BLAS_ARTIFACTS),$($(x)_OBJS)) +$(THIRD_PARTY_BLAS_OBJS): $(BUILD_FILES) third_party/blas/blas.mk + +.PHONY: o/$(MODE)/third_party/blas +o/$(MODE)/third_party/blas: $(THIRD_PARTY_BLAS_CHECKS) diff --git a/third_party/blas/dgemm.f b/third_party/blas/dgemm.f new file mode 100644 index 00000000..3a60ca4e --- /dev/null +++ b/third_party/blas/dgemm.f @@ -0,0 +1,384 @@ +*> \brief \b DGEMM +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE DGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION ALPHA,BETA +* INTEGER K,LDA,LDB,LDC,M,N +* CHARACTER TRANSA,TRANSB +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A(LDA,*),B(LDB,*),C(LDC,*) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DGEMM performs one of the matrix-matrix operations +*> +*> C := alpha*op( A )*op( B ) + beta*C, +*> +*> where op( X ) is one of +*> +*> op( X ) = X or op( X ) = X**T, +*> +*> alpha and beta are scalars, and A, B and C are matrices, with op( A ) +*> an m by k matrix, op( B ) a k by n matrix and C an m by n matrix. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] TRANSA +*> \verbatim +*> TRANSA is CHARACTER*1 +*> On entry, TRANSA specifies the form of op( A ) to be used in +*> the matrix multiplication as follows: +*> +*> TRANSA = 'N' or 'n', op( A ) = A. +*> +*> TRANSA = 'T' or 't', op( A ) = A**T. +*> +*> TRANSA = 'C' or 'c', op( A ) = A**T. +*> \endverbatim +*> +*> \param[in] TRANSB +*> \verbatim +*> TRANSB is CHARACTER*1 +*> On entry, TRANSB specifies the form of op( B ) to be used in +*> the matrix multiplication as follows: +*> +*> TRANSB = 'N' or 'n', op( B ) = B. +*> +*> TRANSB = 'T' or 't', op( B ) = B**T. +*> +*> TRANSB = 'C' or 'c', op( B ) = B**T. +*> \endverbatim +*> +*> \param[in] M +*> \verbatim +*> M is INTEGER +*> On entry, M specifies the number of rows of the matrix +*> op( A ) and of the matrix C. M must be at least zero. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> On entry, N specifies the number of columns of the matrix +*> op( B ) and the number of columns of the matrix C. N must be +*> at least zero. +*> \endverbatim +*> +*> \param[in] K +*> \verbatim +*> K is INTEGER +*> On entry, K specifies the number of columns of the matrix +*> op( A ) and the number of rows of the matrix op( B ). K must +*> be at least zero. +*> \endverbatim +*> +*> \param[in] ALPHA +*> \verbatim +*> ALPHA is DOUBLE PRECISION. +*> On entry, ALPHA specifies the scalar alpha. +*> \endverbatim +*> +*> \param[in] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension ( LDA, ka ), where ka is +*> k when TRANSA = 'N' or 'n', and is m otherwise. +*> Before entry with TRANSA = 'N' or 'n', the leading m by k +*> part of the array A must contain the matrix A, otherwise +*> the leading k by m part of the array A must contain the +*> matrix A. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> On entry, LDA specifies the first dimension of A as declared +*> in the calling (sub) program. When TRANSA = 'N' or 'n' then +*> LDA must be at least max( 1, m ), otherwise LDA must be at +*> least max( 1, k ). +*> \endverbatim +*> +*> \param[in] B +*> \verbatim +*> B is DOUBLE PRECISION array, dimension ( LDB, kb ), where kb is +*> n when TRANSB = 'N' or 'n', and is k otherwise. +*> Before entry with TRANSB = 'N' or 'n', the leading k by n +*> part of the array B must contain the matrix B, otherwise +*> the leading n by k part of the array B must contain the +*> matrix B. +*> \endverbatim +*> +*> \param[in] LDB +*> \verbatim +*> LDB is INTEGER +*> On entry, LDB specifies the first dimension of B as declared +*> in the calling (sub) program. When TRANSB = 'N' or 'n' then +*> LDB must be at least max( 1, k ), otherwise LDB must be at +*> least max( 1, n ). +*> \endverbatim +*> +*> \param[in] BETA +*> \verbatim +*> BETA is DOUBLE PRECISION. +*> On entry, BETA specifies the scalar beta. When BETA is +*> supplied as zero then C need not be set on input. +*> \endverbatim +*> +*> \param[in,out] C +*> \verbatim +*> C is DOUBLE PRECISION array, dimension ( LDC, N ) +*> Before entry, the leading m by n part of the array C must +*> contain the matrix C, except when beta is zero, in which +*> case C need not be set on entry. +*> On exit, the array C is overwritten by the m by n matrix +*> ( alpha*op( A )*op( B ) + beta*C ). +*> \endverbatim +*> +*> \param[in] LDC +*> \verbatim +*> LDC is INTEGER +*> On entry, LDC specifies the first dimension of C as declared +*> in the calling (sub) program. LDC must be at least +*> max( 1, m ). +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date December 2016 +* +*> \ingroup double_blas_level3 +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> Level 3 Blas routine. +*> +*> -- Written on 8-February-1989. +*> Jack Dongarra, Argonne National Laboratory. +*> Iain Duff, AERE Harwell. +*> Jeremy Du Croz, Numerical Algorithms Group Ltd. +*> Sven Hammarling, Numerical Algorithms Group Ltd. +*> \endverbatim +*> +* ===================================================================== + SUBROUTINE DGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC) +* +* -- Reference BLAS level3 routine (version 3.7.0) -- +* -- Reference BLAS is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* December 2016 +* +* .. Scalar Arguments .. + DOUBLE PRECISION ALPHA,BETA + INTEGER K,LDA,LDB,LDC,M,N + CHARACTER TRANSA,TRANSB +* .. +* .. Array Arguments .. + DOUBLE PRECISION A(LDA,*),B(LDB,*),C(LDC,*) +* .. +* +* ===================================================================== +* +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Local Scalars .. + DOUBLE PRECISION TEMP + INTEGER I,INFO,J,L,NCOLA,NROWA,NROWB + LOGICAL NOTA,NOTB +* .. +* .. Parameters .. + DOUBLE PRECISION ONE,ZERO + PARAMETER (ONE=1.0D+0,ZERO=0.0D+0) +* .. +* +* Set NOTA and NOTB as true if A and B respectively are not +* transposed and set NROWA, NCOLA and NROWB as the number of rows +* and columns of A and the number of rows of B respectively. +* + NOTA = LSAME(TRANSA,'N') + NOTB = LSAME(TRANSB,'N') + IF (NOTA) THEN + NROWA = M + NCOLA = K + ELSE + NROWA = K + NCOLA = M + END IF + IF (NOTB) THEN + NROWB = K + ELSE + NROWB = N + END IF +* +* Test the input parameters. +* + INFO = 0 + IF ((.NOT.NOTA) .AND. (.NOT.LSAME(TRANSA,'C')) .AND. + + (.NOT.LSAME(TRANSA,'T'))) THEN + INFO = 1 + ELSE IF ((.NOT.NOTB) .AND. (.NOT.LSAME(TRANSB,'C')) .AND. + + (.NOT.LSAME(TRANSB,'T'))) THEN + INFO = 2 + ELSE IF (M.LT.0) THEN + INFO = 3 + ELSE IF (N.LT.0) THEN + INFO = 4 + ELSE IF (K.LT.0) THEN + INFO = 5 + ELSE IF (LDA.LT.MAX(1,NROWA)) THEN + INFO = 8 + ELSE IF (LDB.LT.MAX(1,NROWB)) THEN + INFO = 10 + ELSE IF (LDC.LT.MAX(1,M)) THEN + INFO = 13 + END IF + IF (INFO.NE.0) THEN + CALL XERBLA('DGEMM ',INFO) + RETURN + END IF +* +* Quick return if possible. +* + IF ((M.EQ.0) .OR. (N.EQ.0) .OR. + + (((ALPHA.EQ.ZERO).OR. (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN +* +* And if alpha.eq.zero. +* + IF (ALPHA.EQ.ZERO) THEN + IF (BETA.EQ.ZERO) THEN + DO 20 J = 1,N + DO 10 I = 1,M + C(I,J) = ZERO + 10 CONTINUE + 20 CONTINUE + ELSE + DO 40 J = 1,N + DO 30 I = 1,M + C(I,J) = BETA*C(I,J) + 30 CONTINUE + 40 CONTINUE + END IF + RETURN + END IF +* +* Start the operations. +* + IF (NOTB) THEN + IF (NOTA) THEN +* +* Form C := alpha*A*B + beta*C. +* + DO 90 J = 1,N + IF (BETA.EQ.ZERO) THEN + DO 50 I = 1,M + C(I,J) = ZERO + 50 CONTINUE + ELSE IF (BETA.NE.ONE) THEN + DO 60 I = 1,M + C(I,J) = BETA*C(I,J) + 60 CONTINUE + END IF + DO 80 L = 1,K + TEMP = ALPHA*B(L,J) + DO 70 I = 1,M + C(I,J) = C(I,J) + TEMP*A(I,L) + 70 CONTINUE + 80 CONTINUE + 90 CONTINUE + ELSE +* +* Form C := alpha*A**T*B + beta*C +* + DO 120 J = 1,N + DO 110 I = 1,M + TEMP = ZERO + DO 100 L = 1,K + TEMP = TEMP + A(L,I)*B(L,J) + 100 CONTINUE + IF (BETA.EQ.ZERO) THEN + C(I,J) = ALPHA*TEMP + ELSE + C(I,J) = ALPHA*TEMP + BETA*C(I,J) + END IF + 110 CONTINUE + 120 CONTINUE + END IF + ELSE + IF (NOTA) THEN +* +* Form C := alpha*A*B**T + beta*C +* + DO 170 J = 1,N + IF (BETA.EQ.ZERO) THEN + DO 130 I = 1,M + C(I,J) = ZERO + 130 CONTINUE + ELSE IF (BETA.NE.ONE) THEN + DO 140 I = 1,M + C(I,J) = BETA*C(I,J) + 140 CONTINUE + END IF + DO 160 L = 1,K + TEMP = ALPHA*B(J,L) + DO 150 I = 1,M + C(I,J) = C(I,J) + TEMP*A(I,L) + 150 CONTINUE + 160 CONTINUE + 170 CONTINUE + ELSE +* +* Form C := alpha*A**T*B**T + beta*C +* + DO 200 J = 1,N + DO 190 I = 1,M + TEMP = ZERO + DO 180 L = 1,K + TEMP = TEMP + A(L,I)*B(J,L) + 180 CONTINUE + IF (BETA.EQ.ZERO) THEN + C(I,J) = ALPHA*TEMP + ELSE + C(I,J) = ALPHA*TEMP + BETA*C(I,J) + END IF + 190 CONTINUE + 200 CONTINUE + END IF + END IF +* + RETURN +* +* End of DGEMM . +* + END diff --git a/third_party/blas/dgemm_.S b/third_party/blas/dgemm_.S new file mode 100644 index 00000000..26d64620 --- /dev/null +++ b/third_party/blas/dgemm_.S @@ -0,0 +1,1102 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +/ Multiplies matrices. + .p2align 4 +dgemm_: push %r15 + mov %rdi,%r15 + push %r14 + mov %r8,%r14 + push %r13 + mov %rsi,%r13 + mov $.LC1,%esi + push %r12 + push %rbp + push %rbx + sub $248,%rsp + mov %rcx,8(%rsp) + mov 352(%rsp),%rcx + mov %rdx,(%rsp) + mov $1,%edx + mov 304(%rsp),%rbx + mov (%rcx),%ecx + mov 344(%rsp),%rbp + mov %r9,24(%rsp) + mov %ecx,16(%rsp) + mov 328(%rsp),%rcx + mov (%rcx),%ecx + mov %ecx,32(%rsp) + mov 312(%rsp),%rcx + mov (%rcx),%ecx + mov %ecx,40(%rsp) + mov $1,%ecx + call lsame_ + mov $1,%ecx + mov $1,%edx + mov %r13,%rdi + mov %eax,%r12d + mov $.LC1,%esi + call lsame_ + test %r12d,%r12d + mov 320(%rsp),%r11 + mov %eax,%r8d + je .L2 + mov (%rsp),%rax + mov (%rax),%r10d + mov %r10d,%r9d + test %r8d,%r8d + jne .L3 + movl $0,236(%rsp) + mov 8(%rsp),%rax + mov (%rax),%eax + mov %eax,48(%rsp) +.L103: mov $1,%ecx + mov $1,%edx + mov $.LC2,%esi + mov %r13,%rdi + mov %r11,320(%rsp) + mov %r8d,64(%rsp) + mov %r10d,56(%rsp) + call lsame_ + mov 56(%rsp),%r10d + mov 64(%rsp),%r8d + test %eax,%eax + mov 320(%rsp),%r11 + jne .L156 + mov $1,%ecx + mov $1,%edx + mov $.LC3,%esi + mov %r13,%rdi + mov %r11,320(%rsp) + mov %r8d,64(%rsp) + mov %r10d,56(%rsp) + call lsame_ + test %eax,%eax + jne .L155 + movl $2,236(%rsp) + jmp .L8 + .p2align 4,,10 + .p2align 3 +.L2: mov %r11,320(%rsp) + mov (%r14),%r10d + mov %eax,64(%rsp) + test %eax,%eax + je .L5 + mov $1,%ecx + mov $1,%edx + mov $.LC2,%esi + mov %r15,%rdi + mov %r10d,48(%rsp) + mov %r10d,56(%rsp) + movl $0,236(%rsp) + call lsame_ + mov 56(%rsp),%r10d + mov 64(%rsp),%r8d + test %eax,%eax + mov 320(%rsp),%r11 + je .L145 +.L156: mov (%rsp),%rax + mov (%rax),%r9d +.L6: test %r9d,%r9d + js .L160 +.L9: mov 8(%rsp),%rax + mov (%rax),%eax + test %eax,%eax + js .L161 + mov (%r14),%r13d + test %r13d,%r13d + js .L162 + mov 312(%rsp),%rdi + mov $1,%edx + test %r10d,%r10d + mov %r10d,%ecx + cmovle %edx,%ecx + cmp %ecx,(%rdi) + jge .L12 + movl $8,236(%rsp) + jmp .L8 +.L3: movl $0,236(%rsp) + mov (%r14),%eax + mov %eax,48(%rsp) + test %r9d,%r9d + jns .L9 +.L160: movl $3,236(%rsp) +.L8: mov $6,%edx + lea 236(%rsp),%rsi + mov $.LC5,%edi + call xerbla_ +.L1: add $248,%rsp + pop %rbx + pop %rbp + pop %r12 + pop %r13 + pop %r14 + pop %r15 + ret +.L161: movl $4,236(%rsp) + jmp .L8 +.L5: mov 8(%rsp),%rax + mov $1,%ecx + mov $1,%edx + mov %r15,%rdi + mov $.LC2,%esi + mov %r10d,56(%rsp) + movl $0,236(%rsp) + mov (%rax),%eax + mov %eax,48(%rsp) + call lsame_ + mov 56(%rsp),%r10d + mov 64(%rsp),%r8d + test %eax,%eax + mov 320(%rsp),%r11 + jne .L103 + mov $1,%ecx + mov $1,%edx + mov $.LC3,%esi + mov %r15,%rdi + mov %r11,320(%rsp) + mov %r8d,64(%rsp) + mov %r10d,56(%rsp) + call lsame_ + mov 56(%rsp),%r10d + mov 64(%rsp),%r8d + test %eax,%eax + mov 320(%rsp),%r11 + jne .L103 +.L104: movl $1,236(%rsp) + jmp .L8 +.L162: movl $5,236(%rsp) + jmp .L8 +.L12: mov 48(%rsp),%ecx + mov 328(%rsp),%rdi + test %ecx,%ecx + cmovle %edx,%ecx + cmp %ecx,(%rdi) + jl .L163 + mov 352(%rsp),%rcx + test %r9d,%r9d + cmovg %r9d,%edx + cmp %edx,(%rcx) + jge .L14 + movl $13,236(%rsp) + jmp .L8 +.L145: mov $1,%ecx + mov $1,%edx + mov $.LC3,%esi + mov %r15,%rdi + mov %r11,320(%rsp) + mov %r8d,64(%rsp) + mov %r10d,56(%rsp) + call lsame_ + test %eax,%eax + je .L104 +.L155: mov (%rsp),%rax + mov 56(%rsp),%r10d + mov 64(%rsp),%r8d + mov 320(%rsp),%r11 + mov (%rax),%r9d + jmp .L6 +.L163: movl $10,236(%rsp) + jmp .L8 + .p2align 4,,10 + .p2align 3 +.L14: test %r9d,%r9d + je .L1 + test %eax,%eax + je .L1 + movslq 16(%rsp),%rcx + mov $0,%edx + pxor %xmm3,%xmm3 + test %rcx,%rcx + cmovns %rcx,%rdx + mov 24(%rsp),%rcx + movsd (%rcx),%xmm2 + mov %rdx,48(%rsp) + ucomisd %xmm3,%xmm2 + jp .L119 + jne .L119 + mov 336(%rsp),%rbx + movsd (%rbx),%xmm1 + ucomisd .LC4(%rip),%xmm1 + jp .L100 + je .L1 +.L100: ucomisd %xmm3,%xmm1 + jnp .L164 +.L21: mov 48(%rsp),%rbx + mov %r9d,%r8d + mov %r9d,%r10d + mov %r9d,%r11d + shrl %r8d + mov %rbp,%rsi + add $1,%eax + and $-2,%r10d + lea 0(,%rbx,8),%r12 + sal $4,%r8 + or $1,%r11d + mov $-1,%rcx + mov $1,%edi + movddup %xmm1,%xmm2 + .p2align 4,,10 + .p2align 3 +.L28: cmp $1,%r9d + je .L106 + lea (%rsi,%r8),%r13 + mov %rsi,%rdx + .p2align 4,,10 + .p2align 3 +.L27: movupd (%rdx),%xmm0 + add $16,%rdx + mulpd %xmm2,%xmm0 + movups %xmm0,-16(%rdx) + cmp %rdx,%r13 + jne .L27 + movslq %r11d,%rdx + cmp %r9d,%r10d + je .L29 +.L25: add %rcx,%rdx + lea 0(%rbp,%rdx,8),%rdx + movsd (%rdx),%xmm0 + mulsd %xmm1,%xmm0 + movsd %xmm0,(%rdx) +.L29: add $1,%edi + add %rbx,%rcx + add %r12,%rsi + cmp %edi,%eax + jne .L28 + jmp .L1 +.L119: test %r13d,%r13d + jne .L20 + mov 336(%rsp),%rcx + movsd .LC4(%rip),%xmm0 + ucomisd (%rcx),%xmm0 + jnp .L165 +.L20: movslq 32(%rsp),%rcx + xor %edx,%edx + test %rcx,%rcx + cmovs %rdx,%rcx + mov %rcx,%rsi + mov %rcx,56(%rsp) + notq %rsi + mov %rsi,72(%rsp) + movslq 40(%rsp),%rsi + test %rsi,%rsi + cmovns %rsi,%rdx + mov %rdx,%rsi + mov %rdx,(%rsp) + mov %rdx,%rdi + notq %rsi + mov %rsi,80(%rsp) + test %r8d,%r8d + je .L30 + test %r12d,%r12d + jne .L166 + mov 48(%rsp),%rcx + add $1,%eax + lea -1(%r9),%edx + mov %r13d,%r8d + mov %eax,32(%rsp) + lea 8(%rbp,%rdx,8),%r10 + notq %rdx + shrl %r8d + sal $3,%rcx + mov $1,%r14d + mov %r13d,%ebp + mov %r13d,%r12d + mov %rcx,16(%rsp) + mov 56(%rsp),%rcx + mov %r11,%rdi + and $-2,%ebp + mov 336(%rsp),%rax + sal $4,%r8 + or $1,%r12d + lea 8(%rbx),%r15 + sal $3,%rcx + mov %r14d,8(%rsp) + mov (%rsp),%r14 + mov $-1,%rsi + movsd (%rax),%xmm5 + lea 0(,%rdx,8),%rax + mov %rcx,24(%rsp) + mov %rax,40(%rsp) + .p2align 4,,10 + .p2align 3 +.L64: mov 40(%rsp),%rax + mov $-1,%rcx + lea (%rax,%r10),%r9 + .p2align 4,,10 + .p2align 3 +.L63: test %r13d,%r13d + je .L111 + cmp $1,%r13d + je .L112 + lea (%r15,%rcx,8),%rdx + xor %eax,%eax + pxor %xmm4,%xmm4 + .p2align 4,,10 + .p2align 3 +.L58: movupd (%rdx,%rax),%xmm0 + movupd (%rdi,%rax),%xmm7 + add $16,%rax + mulpd %xmm7,%xmm0 + addpd %xmm0,%xmm4 + cmp %r8,%rax + jne .L58 + movapd %xmm4,%xmm1 + movslq %r12d,%rax + unpckhpd %xmm4,%xmm1 + addpd %xmm4,%xmm1 + cmp %ebp,%r13d + je .L55 +.L56: lea (%rcx,%rax),%rdx + add %rsi,%rax + movsd (%rbx,%rdx,8),%xmm0 + mulsd (%r11,%rax,8),%xmm0 + addsd %xmm0,%xmm1 +.L55: mulsd %xmm2,%xmm1 + ucomisd %xmm3,%xmm5 + jp .L60 + jne .L60 +.L157: movsd %xmm1,(%r9) + add $8,%r9 + add %r14,%rcx + cmp %r10,%r9 + jne .L63 + addl $1,8(%rsp) + add 16(%rsp),%r10 + mov 8(%rsp),%eax + add 56(%rsp),%rsi + add 24(%rsp),%rdi + cmp 32(%rsp),%eax + jne .L64 + jmp .L1 + .p2align 4,,10 + .p2align 3 +.L60: movsd (%r9),%xmm0 + mulsd %xmm5,%xmm0 + addsd %xmm0,%xmm1 + jmp .L157 + .p2align 4,,10 + .p2align 3 +.L111: movapd %xmm3,%xmm1 + jmp .L55 +.L112: mov $1,%eax + movapd %xmm3,%xmm1 + jmp .L56 +.L30: test %r12d,%r12d + jne .L167 + sub $1,%eax + lea -1(%r9),%esi + mov 48(%rsp),%rcx + movq $1,64(%rsp) + add $2,%rax + lea 8(%rbp,%rsi,8),%r14 + mov 56(%rsp),%rbp + mov %r11,16(%rsp) + mov %rax,88(%rsp) + mov 336(%rsp),%rax + sal $3,%rcx + mov %rcx,80(%rsp) + mov %rbp,%rcx + lea 0(,%rbp,8),%rdx + movsd (%rax),%xmm4 + mov (%rsp),%rax + sal $4,%rcx + sal $3,%rax + mov %rax,8(%rsp) + lea -1(%r13),%eax + mov %eax,24(%rsp) + mov %r13d,%eax + shrl %eax + sal $4,%rax + mov %rax,40(%rsp) + mov %r13d,%eax + and $-2,%eax + mov %eax,32(%rsp) + mov %r13d,%eax + or $1,%eax + mov %eax,56(%rsp) + mov %rsi,%rax + notq %rax + sal $3,%rax + mov %rax,96(%rsp) + .p2align 4,,10 + .p2align 3 +.L98: mov 96(%rsp),%rax + mov 72(%rsp),%rdi + mov %rbx,%r10 + mov $-1,%r9 + lea (%rax,%r14),%rsi + mov 64(%rsp),%rax + mov %rax,%r12 + add %rbp,%rax + add %rdi,%rax + add %rdi,%r12 + mov %rax,48(%rsp) + .p2align 4,,10 + .p2align 3 +.L97: test %r13d,%r13d + je .L117 + cmpl $2,24(%rsp) + jbe .L118 + mov 40(%rsp),%rax + mov 16(%rsp),%rdi + pxor %xmm1,%xmm1 + lea (%rax,%r10),%r8 + mov %r10,%rax + .p2align 4,,10 + .p2align 3 +.L92: movsd (%rdi),%xmm0 + movupd (%rax),%xmm6 + add $16,%rax + movhpd (%rdi,%rdx),%xmm0 + add %rcx,%rdi + mulpd %xmm6,%xmm0 + addpd %xmm0,%xmm1 + cmp %r8,%rax + jne .L92 + movapd %xmm1,%xmm0 + unpckhpd %xmm1,%xmm0 + addpd %xmm0,%xmm1 + cmp 32(%rsp),%r13d + je .L89 + mov 56(%rsp),%eax +.L90: movslq %eax,%r8 + mov %rbp,%rdi + imul %r8,%rdi + add %r9,%r8 + lea (%r12,%rdi),%r15 + movsd (%r11,%r15,8),%xmm0 + mulsd (%rbx,%r8,8),%xmm0 + lea 1(%rax),%r8d + addsd %xmm0,%xmm1 + cmp %r8d,%r13d + jl .L89 + add %rbp,%rdi + movslq %r8d,%r8 + add $2,%eax + lea (%r12,%rdi),%r15 + add %r9,%r8 + movsd (%r11,%r15,8),%xmm0 + mulsd (%rbx,%r8,8),%xmm0 + addsd %xmm0,%xmm1 + cmp %eax,%r13d + jl .L89 + cltq + add 48(%rsp),%rdi + add %r9,%rax + movsd (%r11,%rdi,8),%xmm0 + mulsd (%rbx,%rax,8),%xmm0 + addsd %xmm0,%xmm1 +.L89: mulsd %xmm2,%xmm1 + ucomisd %xmm3,%xmm4 + jp .L94 + jne .L94 +.L158: movsd %xmm1,(%rsi) + add $8,%rsi + add (%rsp),%r9 + add 8(%rsp),%r10 + cmp %r14,%rsi + jne .L97 + addq $1,64(%rsp) + add 80(%rsp),%r14 + addq $8,16(%rsp) + mov 64(%rsp),%rax + cmp 88(%rsp),%rax + jne .L98 + jmp .L1 + .p2align 4,,10 + .p2align 3 +.L94: movsd (%rsi),%xmm0 + mulsd %xmm4,%xmm0 + addsd %xmm0,%xmm1 + jmp .L158 + .p2align 4,,10 + .p2align 3 +.L117: movapd %xmm3,%xmm1 + jmp .L89 +.L118: movapd %xmm3,%xmm1 + mov $1,%eax + jmp .L90 +.L164: jne .L21 + mov 48(%rsp),%r12 + lea 1(%rax),%r14d + lea -1(%r9),%eax + mov $1,%ebx + lea 8(,%rax,8),%r13 + sal $3,%r12 + .p2align 4,,10 + .p2align 3 +.L24: mov %rbp,%rdi + mov %r13,%rdx + xor %esi,%esi + add $1,%ebx + call memset + add %r12,%rbp + cmp %ebx,%r14d + jne .L24 + jmp .L1 +.L167: sub $1,%eax + mov 72(%rsp),%rsi + mov %r9d,%r15d + mov %rbp,%r12 + add $2,%rax + mov 336(%rsp),%rcx + movq $1,24(%rsp) + shrl %r15d + mov %rax,64(%rsp) + mov %r9d,%eax + sal $4,%r15 + movsd .LC4(%rip),%xmm7 + and $-2,%eax + movsd (%rcx),%xmm5 + mov 48(%rsp),%rcx + mov %r11,320(%rsp) + mov %eax,8(%rsp) + mov %r9d,%eax + mov $-1,%r14 + or $1,%eax + sal $3,%rcx + movddup %xmm5,%xmm6 + mov %eax,16(%rsp) + lea -1(%r9),%eax + mov %rcx,40(%rsp) + mov 80(%rsp),%rcx + mov %eax,88(%rsp) + lea 8(,%rax,8),%rax + mov %rax,208(%rsp) + lea (%rdx,%rdx),%rax + add %rax,%rcx + mov %rax,96(%rsp) + mov 56(%rsp),%rax + mov %rcx,128(%rsp) + mov %rax,%rcx + sal $4,%rcx + mov %rcx,112(%rsp) + mov %rax,%rcx + lea (%rsi,%rax,2),%rax + lea (%r11,%rax,8),%rax + mov %rax,144(%rsp) + mov %rdx,%rax + sal $4,%rax + mov %rax,136(%rsp) + mov %rcx,%rax + negq %rax + sal $3,%rax + mov %rax,152(%rsp) + lea 0(,%rdx,8),%rax + mov %rax,168(%rsp) + mov %r9d,%eax + shr $2,%eax + sal $5,%rax + mov %rax,104(%rsp) + mov %r9d,%eax + and $-4,%eax + mov %eax,200(%rsp) + add $1,%eax + mov %eax,192(%rsp) + lea 0(,%rcx,8),%rax + mov %r13d,%ecx + mov %r9d,%r13d + mov %rax,216(%rsp) + .p2align 4,,10 + .p2align 3 +.L77: ucomisd %xmm3,%xmm5 + jnp .L168 +.L68: ucomisd %xmm7,%xmm5 + jp .L123 + jne .L123 +.L71: test %ecx,%ecx + je .L69 + cmp $2,%ecx + jle .L114 + mov 144(%rsp),%rax + mov 24(%rsp),%rdi + mov %r15,160(%rsp) + mov $-1,%r10 + mov 128(%rsp),%rsi + lea (%rax,%rdi,8),%r11 + mov 104(%rsp),%rdi + mov %rbx,%rax + mov %rsi,32(%rsp) + mov $2,%esi + mov %esi,%r15d +.L82: mov 152(%rsp),%rsi + cmpl $2,88(%rsp) + movsd (%r11,%rsi),%xmm10 + mulsd %xmm2,%xmm10 + jbe .L169 + movsd (%r11),%xmm11 + mov 168(%rsp),%rsi + movddup %xmm10,%xmm9 + xor %edx,%edx + mulsd %xmm2,%xmm11 + lea (%rax,%rsi),%r8 + mov %r12,%rsi + movddup %xmm11,%xmm8 + .p2align 4,,10 + .p2align 3 +.L88: movupd 16(%rax,%rdx),%xmm0 + movupd 16(%r8,%rdx),%xmm1 + add $32,%rsi + movupd -16(%rsi),%xmm4 + mulpd %xmm9,%xmm0 + mulpd %xmm8,%xmm1 + addpd %xmm4,%xmm0 + movupd -32(%rsi),%xmm4 + addpd %xmm1,%xmm0 + movupd (%rax,%rdx),%xmm1 + mulpd %xmm9,%xmm1 + movups %xmm0,-16(%rsi) + addpd %xmm4,%xmm1 + movupd (%r8,%rdx),%xmm4 + add $32,%rdx + mulpd %xmm8,%xmm4 + addpd %xmm4,%xmm1 + movups %xmm1,-32(%rsi) + cmp %rdi,%rdx + jne .L88 + cmp %r13d,200(%rsp) + je .L81 + mov 192(%rsp),%edx +.L79: movslq %edx,%rsi + lea (%r14,%rsi),%r8 + lea (%r10,%rsi),%r9 + add 32(%rsp),%rsi + movsd (%rbx,%rsi,8),%xmm1 + movsd (%rbx,%r9,8),%xmm0 + lea 0(%rbp,%r8,8),%r8 + lea 1(%rdx),%esi + mulsd %xmm11,%xmm1 + mulsd %xmm10,%xmm0 + addsd (%r8),%xmm0 + addsd %xmm1,%xmm0 + movsd %xmm0,(%r8) + cmp %esi,%r13d + jl .L81 + movslq %esi,%rsi + add $2,%edx + lea (%r10,%rsi),%r9 + lea (%r14,%rsi),%r8 + movsd (%rbx,%r9,8),%xmm0 + mov 32(%rsp),%r9 + lea 0(%rbp,%r8,8),%r8 + mulsd %xmm10,%xmm0 + add %r9,%rsi + movsd (%rbx,%rsi,8),%xmm1 + addsd (%r8),%xmm0 + mulsd %xmm11,%xmm1 + addsd %xmm1,%xmm0 + movsd %xmm0,(%r8) + cmp %edx,%r13d + jl .L81 + movslq %edx,%rdx + lea (%r14,%rdx),%rsi + lea (%r10,%rdx),%r8 + add %r9,%rdx + mulsd (%rbx,%rdx,8),%xmm11 + lea 0(%rbp,%rsi,8),%rsi + mulsd (%rbx,%r8,8),%xmm10 + addsd (%rsi),%xmm10 + addsd %xmm10,%xmm11 + movsd %xmm11,(%rsi) +.L81: mov 96(%rsp),%rdx + lea 1(%r15),%esi + add $2,%r15d + add %rdx,32(%rsp) + add 112(%rsp),%r11 + add 136(%rsp),%rax + add %rdx,%r10 + cmp %r15d,%ecx + jg .L82 + mov 160(%rsp),%r15 +.L78: mov 56(%rsp),%rdi + movslq %esi,%rdx + mov (%rsp),%r8 + lea 8(%rbx),%r10 + mov 72(%rsp),%rax + add 24(%rsp),%rax + imul %rdx,%rdi + mov 216(%rsp),%r9 + imul %r8,%rdx + add 80(%rsp),%rdx + add %rdi,%rax + mov 320(%rsp),%rdi + lea (%rdi,%rax,8),%rdi + .p2align 4,,10 + .p2align 3 +.L86: movsd (%rdi),%xmm0 + mulsd %xmm2,%xmm0 + cmp $1,%r13d + je .L116 + lea (%r10,%rdx,8),%r11 + movddup %xmm0,%xmm4 + xor %eax,%eax + .p2align 4,,10 + .p2align 3 +.L84: movupd (%r11,%rax),%xmm1 + movupd (%r12,%rax),%xmm13 + mulpd %xmm4,%xmm1 + addpd %xmm13,%xmm1 + movups %xmm1,(%r12,%rax) + add $16,%rax + cmp %r15,%rax + jne .L84 + cmp 8(%rsp),%r13d + je .L85 + movslq 16(%rsp),%rax +.L83: lea (%r14,%rax),%r11 + add %rdx,%rax + lea 0(%rbp,%r11,8),%r11 + mulsd (%rbx,%rax,8),%xmm0 + addsd (%r11),%xmm0 + movsd %xmm0,(%r11) +.L85: add $1,%esi + add %r9,%rdi + add %r8,%rdx + cmp %esi,%ecx + jge .L86 +.L69: addq $1,24(%rsp) + add 48(%rsp),%r14 + mov 24(%rsp),%rax + add 40(%rsp),%r12 + cmp 64(%rsp),%rax + jne .L77 + jmp .L1 +.L116: mov $1,%eax + jmp .L83 +.L168: jne .L68 + mov 208(%rsp),%rdx + xor %esi,%esi + mov %r12,%rdi + mov %ecx,204(%rsp) + movaps %xmm6,176(%rsp) + movsd %xmm5,160(%rsp) + movsd %xmm2,32(%rsp) + call memset + mov .LC4(%rip),%rax + movsd 32(%rsp),%xmm2 + pxor %xmm3,%xmm3 + movsd 160(%rsp),%xmm5 + mov 204(%rsp),%ecx + movapd 176(%rsp),%xmm6 + movq %rax,%xmm7 + jmp .L71 +.L123: cmp $1,%r13d + je .L113 + lea (%r15,%r12),%rdx + mov %r12,%rax + .p2align 4,,10 + .p2align 3 +.L75: movupd (%rax),%xmm0 + add $16,%rax + mulpd %xmm6,%xmm0 + movups %xmm0,-16(%rax) + cmp %rdx,%rax + jne .L75 + cmp 8(%rsp),%r13d + je .L71 + movslq 16(%rsp),%rax +.L73: add %r14,%rax + lea 0(%rbp,%rax,8),%rax + movsd (%rax),%xmm0 + mulsd %xmm5,%xmm0 + movsd %xmm0,(%rax) + jmp .L71 +.L166: add $1,%eax + mov %r9d,%r15d + sal $3,%rcx + mov %r9d,%r8d + mov %eax,32(%rsp) + mov %r9d,%eax + shrl %r15d + mov %rbp,%r12 + or $1,%eax + mov %rcx,40(%rsp) + sub $8,%r11 + mov %r13d,%ecx + mov %eax,8(%rsp) + lea -1(%r9),%eax + sal $4,%r15 + and $-2,%r8d + mov %eax,96(%rsp) + lea 8(,%rax,8),%rax + mov 336(%rsp),%rdx + mov $-1,%r14 + mov %rax,192(%rsp) + lea (%rdi,%rdi),%rax + movsd .LC4(%rip),%xmm7 + mov %r9d,%r13d + add %rax,%rsi + mov %rax,88(%rsp) + mov %rdi,%rax + movsd (%rdx),%xmm5 + mov 48(%rsp),%rdx + sal $4,%rdi + lea 0(,%rax,8),%rax + mov %rsi,72(%rsp) + mov %rax,152(%rsp) + mov %r9d,%eax + movddup %xmm5,%xmm6 + shr $2,%eax + sal $3,%rdx + mov %rdi,104(%rsp) + sal $5,%rax + mov %rdx,56(%rsp) + mov %rax,64(%rsp) + mov %r9d,%eax + and $-4,%eax + movl $1,16(%rsp) + mov %eax,144(%rsp) + add $1,%eax + mov %eax,160(%rsp) + .p2align 4,,10 + .p2align 3 +.L43: ucomisd %xmm3,%xmm5 + jnp .L170 +.L34: ucomisd %xmm7,%xmm5 + jp .L121 + jne .L121 +.L37: test %ecx,%ecx + je .L35 + cmp $2,%ecx + jle .L108 + mov 72(%rsp),%rdi + mov %r15,128(%rsp) + lea 16(%r11),%rsi + mov %rbx,%rax + mov $2,%edx + mov %r8d,112(%rsp) + mov $-1,%r10 + mov %rdi,24(%rsp) + mov 64(%rsp),%rdi + mov %edx,%r8d + mov %r11,136(%rsp) + mov %rsi,%r11 +.L48: movsd -8(%r11),%xmm10 + cmpl $2,96(%rsp) + mulsd %xmm2,%xmm10 + jbe .L171 + movsd (%r11),%xmm11 + mov 152(%rsp),%rsi + movddup %xmm10,%xmm9 + xor %edx,%edx + mulsd %xmm2,%xmm11 + lea (%rsi,%rax),%r9 + mov %r12,%rsi + movddup %xmm11,%xmm8 + .p2align 4,,10 + .p2align 3 +.L54: movupd 16(%rax,%rdx),%xmm0 + movupd 16(%r9,%rdx),%xmm1 + add $32,%rsi + movupd -16(%rsi),%xmm4 + mulpd %xmm9,%xmm0 + mulpd %xmm8,%xmm1 + addpd %xmm4,%xmm0 + movupd -32(%rsi),%xmm4 + addpd %xmm1,%xmm0 + movupd (%rax,%rdx),%xmm1 + mulpd %xmm9,%xmm1 + movups %xmm0,-16(%rsi) + addpd %xmm4,%xmm1 + movupd (%r9,%rdx),%xmm4 + add $32,%rdx + mulpd %xmm8,%xmm4 + addpd %xmm4,%xmm1 + movups %xmm1,-32(%rsi) + cmp %rdi,%rdx + jne .L54 + cmp %r13d,144(%rsp) + je .L47 + mov 160(%rsp),%edx +.L45: movslq %edx,%rsi + lea (%r14,%rsi),%r9 + lea (%r10,%rsi),%r15 + add 24(%rsp),%rsi + movsd (%rbx,%rsi,8),%xmm1 + movsd (%rbx,%r15,8),%xmm0 + lea 0(%rbp,%r9,8),%r9 + lea 1(%rdx),%esi + mulsd %xmm11,%xmm1 + mulsd %xmm10,%xmm0 + addsd (%r9),%xmm0 + addsd %xmm1,%xmm0 + movsd %xmm0,(%r9) + cmp %esi,%r13d + jl .L47 + movslq %esi,%rsi + add $2,%edx + lea (%r10,%rsi),%r15 + lea (%r14,%rsi),%r9 + movsd (%rbx,%r15,8),%xmm0 + mov 24(%rsp),%r15 + lea 0(%rbp,%r9,8),%r9 + mulsd %xmm10,%xmm0 + add %r15,%rsi + movsd (%rbx,%rsi,8),%xmm1 + addsd (%r9),%xmm0 + mulsd %xmm11,%xmm1 + addsd %xmm1,%xmm0 + movsd %xmm0,(%r9) + cmp %edx,%r13d + jl .L47 + movslq %edx,%rdx + lea (%r14,%rdx),%rsi + lea (%r10,%rdx),%r9 + add %r15,%rdx + mulsd (%rbx,%rdx,8),%xmm11 + lea 0(%rbp,%rsi,8),%rsi + mulsd (%rbx,%r9,8),%xmm10 + addsd (%rsi),%xmm10 + addsd %xmm10,%xmm11 + movsd %xmm11,(%rsi) +.L47: mov 88(%rsp),%rsi + lea 1(%r8),%edx + add $2,%r8d + add %rsi,24(%rsp) + add 104(%rsp),%rax + add $16,%r11 + add %rsi,%r10 + cmp %r8d,%ecx + jg .L48 + mov 128(%rsp),%r15 + mov 112(%rsp),%r8d + mov 136(%rsp),%r11 +.L44: mov (%rsp),%r9 + movslq %edx,%rdx + lea 8(%rbx),%rdi + mov %r9,%rsi + imul %rdx,%rsi + add 80(%rsp),%rsi + .p2align 4,,10 + .p2align 3 +.L52: movsd (%r11,%rdx,8),%xmm0 + mulsd %xmm2,%xmm0 + cmp $1,%r13d + je .L110 + lea (%rdi,%rsi,8),%r10 + movddup %xmm0,%xmm4 + xor %eax,%eax + .p2align 4,,10 + .p2align 3 +.L50: movupd (%r10,%rax),%xmm1 + movupd (%r12,%rax),%xmm12 + mulpd %xmm4,%xmm1 + addpd %xmm12,%xmm1 + movups %xmm1,(%r12,%rax) + add $16,%rax + cmp %rax,%r15 + jne .L50 + cmp %r8d,%r13d + je .L51 + movslq 8(%rsp),%rax +.L49: lea (%r14,%rax),%r10 + add %rsi,%rax + lea 0(%rbp,%r10,8),%r10 + mulsd (%rbx,%rax,8),%xmm0 + addsd (%r10),%xmm0 + movsd %xmm0,(%r10) +.L51: add $1,%rdx + add %r9,%rsi + cmp %edx,%ecx + jge .L52 +.L35: addl $1,16(%rsp) + add 48(%rsp),%r14 + mov 16(%rsp),%eax + add 56(%rsp),%r12 + add 40(%rsp),%r11 + cmp 32(%rsp),%eax + jne .L43 + jmp .L1 +.L110: mov $1,%eax + jmp .L49 +.L170: jne .L34 + mov 192(%rsp),%rdx + xor %esi,%esi + mov %r12,%rdi + mov %r11,168(%rsp) + mov %r8d,200(%rsp) + mov %ecx,136(%rsp) + movaps %xmm6,112(%rsp) + movsd %xmm5,128(%rsp) + movsd %xmm2,24(%rsp) + call memset + mov .LC4(%rip),%rax + pxor %xmm3,%xmm3 + movsd 24(%rsp),%xmm2 + movsd 128(%rsp),%xmm5 + movapd 112(%rsp),%xmm6 + mov 136(%rsp),%ecx + mov 200(%rsp),%r8d + movq %rax,%xmm7 + mov 168(%rsp),%r11 + jmp .L37 +.L121: cmp $1,%r13d + je .L107 + lea (%r15,%r12),%rdx + mov %r12,%rax + .p2align 4,,10 + .p2align 3 +.L41: movupd (%rax),%xmm0 + add $16,%rax + mulpd %xmm6,%xmm0 + movups %xmm0,-16(%rax) + cmp %rax,%rdx + jne .L41 + cmp %r8d,%r13d + je .L37 + movslq 8(%rsp),%rax +.L39: add %r14,%rax + lea 0(%rbp,%rax,8),%rax + movsd (%rax),%xmm0 + mulsd %xmm5,%xmm0 + movsd %xmm0,(%rax) + jmp .L37 +.L108: mov $1,%edx + jmp .L44 +.L114: mov $1,%esi + jmp .L78 +.L106: mov $1,%edx + jmp .L25 +.L171: movsd (%r11),%xmm11 + mov $1,%edx + mulsd %xmm2,%xmm11 + jmp .L45 +.L169: movsd (%r11),%xmm11 + mov $1,%edx + mulsd %xmm2,%xmm11 + jmp .L79 +.L107: mov $1,%eax + jmp .L39 +.L113: mov $1,%eax + jmp .L73 +.L165: je .L1 + jmp .L20 + .endfn dgemm_,globl + + .rodata.cst8 +.LC4: .double 1 + + .rodata.str1.1 +.LC1: .string "N" +.LC2: .string "C" +.LC3: .string "T" +.LC5: .string "DGEMM " diff --git a/third_party/blas/lsame.c b/third_party/blas/lsame.c new file mode 100644 index 00000000..928377fd --- /dev/null +++ b/third_party/blas/lsame.c @@ -0,0 +1,155 @@ +/* lsame.f -- translated by f2c (version 20191129). + You must link the resulting object file with libf2c: + on Microsoft Windows system, link with libf2c.lib; + on Linux or Unix systems, link with .../path/to/libf2c.a -lm + or, if you install libf2c.a in a standard place, with -lf2c -lm + -- in that order, at the end of the command line, as in + cc *.o -lf2c -lm + Source for libf2c is in /netlib/f2c/libf2c.zip, e.g., + + http://www.netlib.org/f2c/libf2c.zip +*/ + +#include "third_party/f2c/f2c.h" + +/* > \brief \b LSAME */ + +/* =========== DOCUMENTATION =========== */ + +/* Online html documentation available at */ +/* http://www.netlib.org/lapack/explore-html/ */ + +/* Definition: */ +/* =========== */ + +/* LOGICAL FUNCTION LSAME(CA,CB) */ + +/* .. Scalar Arguments .. */ +/* CHARACTER CA,CB */ +/* .. */ + +/* > \par Purpose: */ +/* ============= */ +/* > */ +/* > \verbatim */ +/* > */ +/* > LSAME returns .TRUE. if CA is the same letter as CB regardless of */ +/* > case. */ +/* > \endverbatim */ + +/* Arguments: */ +/* ========== */ + +/* > \param[in] CA */ +/* > \verbatim */ +/* > CA is CHARACTER*1 */ +/* > \endverbatim */ +/* > */ +/* > \param[in] CB */ +/* > \verbatim */ +/* > CB is CHARACTER*1 */ +/* > CA and CB specify the single characters to be compared. */ +/* > \endverbatim */ + +/* Authors: */ +/* ======== */ + +/* > \author Univ. of Tennessee */ +/* > \author Univ. of California Berkeley */ +/* > \author Univ. of Colorado Denver */ +/* > \author NAG Ltd. */ + +/* > \date December 2016 */ + +/* > \ingroup aux_blas */ + +/* ===================================================================== */ +logical lsame_(char *ca, char *cb) { + /* System generated locals */ + logical ret_val; + + /* Local variables */ + static integer inta, intb, zcode; + + /* -- Reference BLAS level1 routine (version 3.1) -- */ + /* -- Reference BLAS is a software package provided by Univ. of Tennessee, + * -- */ + /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- + */ + /* December 2016 */ + + /* .. Scalar Arguments .. */ + /* .. */ + + /* ===================================================================== */ + + /* .. Intrinsic Functions .. */ + /* .. */ + /* .. Local Scalars .. */ + /* .. */ + + /* Test if the characters are equal */ + + ret_val = *(unsigned char *)ca == *(unsigned char *)cb; + if (ret_val) { + return ret_val; + } + + /* Now test for equivalence if both characters are alphabetic. */ + + zcode = 'Z'; + + /* Use 'Z' rather than 'A' so that ASCII can be detected on Prime */ + /* machines, on which ICHAR returns a value with bit 8 set. */ + /* ICHAR('A') on Prime machines returns 193 which is the same as */ + /* ICHAR('A') on an EBCDIC machine. */ + + inta = *(unsigned char *)ca; + intb = *(unsigned char *)cb; + + if (zcode == 90 || zcode == 122) { + + /* ASCII is assumed - ZCODE is the ASCII code of either lower or */ + /* upper case 'Z'. */ + + if (inta >= 97 && inta <= 122) { + inta += -32; + } + if (intb >= 97 && intb <= 122) { + intb += -32; + } + + } else if (zcode == 233 || zcode == 169) { + + /* EBCDIC is assumed - ZCODE is the EBCDIC code of either lower or */ + /* upper case 'Z'. */ + + if (inta >= 129 && inta <= 137 || inta >= 145 && inta <= 153 || + inta >= 162 && inta <= 169) { + inta += 64; + } + if (intb >= 129 && intb <= 137 || intb >= 145 && intb <= 153 || + intb >= 162 && intb <= 169) { + intb += 64; + } + + } else if (zcode == 218 || zcode == 250) { + + /* ASCII is assumed, on Prime machines - ZCODE is the ASCII code */ + /* plus 128 of either lower or upper case 'Z'. */ + + if (inta >= 225 && inta <= 250) { + inta += -32; + } + if (intb >= 225 && intb <= 250) { + intb += -32; + } + } + ret_val = inta == intb; + + /* RETURN */ + + /* End of LSAME */ + + return ret_val; +} /* lsame_ */ diff --git a/third_party/blas/lsame.f b/third_party/blas/lsame.f new file mode 100644 index 00000000..d8194786 --- /dev/null +++ b/third_party/blas/lsame.f @@ -0,0 +1,125 @@ +*> \brief \b LSAME +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* LOGICAL FUNCTION LSAME(CA,CB) +* +* .. Scalar Arguments .. +* CHARACTER CA,CB +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> LSAME returns .TRUE. if CA is the same letter as CB regardless of +*> case. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] CA +*> \verbatim +*> CA is CHARACTER*1 +*> \endverbatim +*> +*> \param[in] CB +*> \verbatim +*> CB is CHARACTER*1 +*> CA and CB specify the single characters to be compared. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date December 2016 +* +*> \ingroup aux_blas +* +* ===================================================================== + LOGICAL FUNCTION LSAME(CA,CB) +* +* -- Reference BLAS level1 routine (version 3.1) -- +* -- Reference BLAS is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* December 2016 +* +* .. Scalar Arguments .. + CHARACTER CA,CB +* .. +* +* ===================================================================== +* +* .. Intrinsic Functions .. + INTRINSIC ICHAR +* .. +* .. Local Scalars .. + INTEGER INTA,INTB,ZCODE +* .. +* +* Test if the characters are equal +* + LSAME = CA .EQ. CB + IF (LSAME) RETURN +* +* Now test for equivalence if both characters are alphabetic. +* + ZCODE = ICHAR('Z') +* +* Use 'Z' rather than 'A' so that ASCII can be detected on Prime +* machines, on which ICHAR returns a value with bit 8 set. +* ICHAR('A') on Prime machines returns 193 which is the same as +* ICHAR('A') on an EBCDIC machine. +* + INTA = ICHAR(CA) + INTB = ICHAR(CB) +* + IF (ZCODE.EQ.90 .OR. ZCODE.EQ.122) THEN +* +* ASCII is assumed - ZCODE is the ASCII code of either lower or +* upper case 'Z'. +* + IF (INTA.GE.97 .AND. INTA.LE.122) INTA = INTA - 32 + IF (INTB.GE.97 .AND. INTB.LE.122) INTB = INTB - 32 +* + ELSE IF (ZCODE.EQ.233 .OR. ZCODE.EQ.169) THEN +* +* EBCDIC is assumed - ZCODE is the EBCDIC code of either lower or +* upper case 'Z'. +* + IF (INTA.GE.129 .AND. INTA.LE.137 .OR. + + INTA.GE.145 .AND. INTA.LE.153 .OR. + + INTA.GE.162 .AND. INTA.LE.169) INTA = INTA + 64 + IF (INTB.GE.129 .AND. INTB.LE.137 .OR. + + INTB.GE.145 .AND. INTB.LE.153 .OR. + + INTB.GE.162 .AND. INTB.LE.169) INTB = INTB + 64 +* + ELSE IF (ZCODE.EQ.218 .OR. ZCODE.EQ.250) THEN +* +* ASCII is assumed, on Prime machines - ZCODE is the ASCII code +* plus 128 of either lower or upper case 'Z'. +* + IF (INTA.GE.225 .AND. INTA.LE.250) INTA = INTA - 32 + IF (INTB.GE.225 .AND. INTB.LE.250) INTB = INTB - 32 + END IF + LSAME = INTA .EQ. INTB +* +* RETURN +* +* End of LSAME +* + END diff --git a/third_party/blas/xerbla.c b/third_party/blas/xerbla.c new file mode 100644 index 00000000..11faa36b --- /dev/null +++ b/third_party/blas/xerbla.c @@ -0,0 +1,121 @@ +/* xerbla.f -- translated by f2c (version 20191129). + You must link the resulting object file with libf2c: + on Microsoft Windows system, link with libf2c.lib; + on Linux or Unix systems, link with .../path/to/libf2c.a -lm + or, if you install libf2c.a in a standard place, with -lf2c -lm + -- in that order, at the end of the command line, as in + cc *.o -lf2c -lm + Source for libf2c is in /netlib/f2c/libf2c.zip, e.g., + + http://www.netlib.org/f2c/libf2c.zip +*/ + +#include "third_party/f2c/f2c.h" + +/* Table of constant values */ + +static integer c__1 = 1; + +/* > \brief \b XERBLA */ + +/* =========== DOCUMENTATION =========== */ + +/* Online html documentation available at */ +/* http://www.netlib.org/lapack/explore-html/ */ + +/* Definition: */ +/* =========== */ + +/* SUBROUTINE XERBLA( SRNAME, INFO ) */ + +/* .. Scalar Arguments .. */ +/* CHARACTER*(*) SRNAME */ +/* INTEGER INFO */ +/* .. */ + +/* > \par Purpose: */ +/* ============= */ +/* > */ +/* > \verbatim */ +/* > */ +/* > XERBLA is an error handler for the LAPACK routines. */ +/* > It is called by an LAPACK routine if an input parameter has an */ +/* > invalid value. A message is printed and execution stops. */ +/* > */ +/* > Installers may consider modifying the STOP statement in order to */ +/* > call system-specific exception-handling facilities. */ +/* > \endverbatim */ + +/* Arguments: */ +/* ========== */ + +/* > \param[in] SRNAME */ +/* > \verbatim */ +/* > SRNAME is CHARACTER*(*) */ +/* > The name of the routine which called XERBLA. */ +/* > \endverbatim */ +/* > */ +/* > \param[in] INFO */ +/* > \verbatim */ +/* > INFO is INTEGER */ +/* > The position of the invalid parameter in the parameter list */ +/* > of the calling routine. */ +/* > \endverbatim */ + +/* Authors: */ +/* ======== */ + +/* > \author Univ. of Tennessee */ +/* > \author Univ. of California Berkeley */ +/* > \author Univ. of Colorado Denver */ +/* > \author NAG Ltd. */ + +/* > \date December 2016 */ + +/* > \ingroup aux_blas */ + +/* ===================================================================== */ +/* Subroutine */ int xerbla_(char *srname, integer *info, ftnlen srname_len) { + /* Format strings */ + static char fmt_9999[] = + "(\002 ** On entry to \002,a,\002 parameter num" + "ber \002,i2,\002 had \002,\002an illegal value\002)"; + + /* Builtin functions */ + integer s_wsfe(cilist *), do_fio(integer *, char *, ftnlen), e_wsfe(void); + /* Subroutine */ int s_stop(char *, ftnlen); + + /* Local variables */ + extern doublereal trmlen_(char *, ftnlen); + + /* Fortran I/O blocks */ + static cilist io___1 = {0, 6, 0, fmt_9999, 0}; + + /* -- Reference BLAS level1 routine (version 3.7.0) -- */ + /* -- Reference BLAS is a software package provided by Univ. of Tennessee, + * -- */ + /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- + */ + /* December 2016 */ + + /* .. Scalar Arguments .. */ + /* .. */ + + /* ===================================================================== */ + + /* .. Intrinsic Functions .. */ + /* INTRINSIC LEN_TRIM */ + /* .. */ + /* .. Executable Statements .. */ + + s_wsfe(&io___1); + do_fio(&c__1, srname, (integer)trmlen_(srname, srname_len)); + do_fio(&c__1, (char *)&(*info), (ftnlen)sizeof(integer)); + e_wsfe(); + + s_stop("", (ftnlen)0); + + /* End of XERBLA */ + + return 0; +} /* xerbla_ */ diff --git a/third_party/blas/xerbla.f b/third_party/blas/xerbla.f new file mode 100644 index 00000000..788e3785 --- /dev/null +++ b/third_party/blas/xerbla.f @@ -0,0 +1,89 @@ +*> \brief \b XERBLA +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE XERBLA( SRNAME, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER*(*) SRNAME +* INTEGER INFO +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> XERBLA is an error handler for the LAPACK routines. +*> It is called by an LAPACK routine if an input parameter has an +*> invalid value. A message is printed and execution stops. +*> +*> Installers may consider modifying the STOP statement in order to +*> call system-specific exception-handling facilities. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] SRNAME +*> \verbatim +*> SRNAME is CHARACTER*(*) +*> The name of the routine which called XERBLA. +*> \endverbatim +*> +*> \param[in] INFO +*> \verbatim +*> INFO is INTEGER +*> The position of the invalid parameter in the parameter list +*> of the calling routine. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date December 2016 +* +*> \ingroup aux_blas +* +* ===================================================================== + SUBROUTINE XERBLA( SRNAME, INFO ) +* +* -- Reference BLAS level1 routine (version 3.7.0) -- +* -- Reference BLAS is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* December 2016 +* +* .. Scalar Arguments .. + CHARACTER*(*) SRNAME + INTEGER INFO +* .. +* +* ===================================================================== +* +* .. Intrinsic Functions .. +* INTRINSIC LEN_TRIM +* .. +* .. Executable Statements .. +* + WRITE( *, FMT = 9999 )SRNAME( 1:TRMLEN( SRNAME ) ), INFO +* + STOP +* + 9999 FORMAT( ' ** On entry to ', A, ' parameter number ', I2, ' had ', + $ 'an illegal value' ) +* +* End of XERBLA +* + END diff --git a/third_party/bzip2/.clang-format b/third_party/bzip2/.clang-format new file mode 100644 index 00000000..ff4feef4 --- /dev/null +++ b/third_party/bzip2/.clang-format @@ -0,0 +1,125 @@ +--- +Language: Cpp +# BasedOnStyle: WebKit +AccessModifierOffset: -4 +AlignAfterOpenBracket: DontAlign +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: false +AlignTrailingComments: false +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: All +BreakBeforeBraces: WebKit +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeComma +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: false +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + - Regex: '.*' + Priority: 1 +IncludeIsMainRegex: '(Test)?$' +IndentCaseLabels: false +IndentPPDirectives: None +IndentWidth: 4 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: Inner +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 4 +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 4 +UseTab: Always +... diff --git a/third_party/bzip2/bzip2.mk b/third_party/bzip2/bzip2.mk new file mode 100644 index 00000000..a2461c93 --- /dev/null +++ b/third_party/bzip2/bzip2.mk @@ -0,0 +1,35 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ +# Description: +# bzip2 is a compression format. + +PKGS += THIRD_PARTY_BZIP2 + +THIRD_PARTY_BZIP2_BINS = \ + o/$(MODE)/third_party/bzip2/µbunzip2.com \ + o/$(MODE)/third_party/bzip2/µbunzip2.com.dbg + +THIRD_PARTY_BZIP2_OBJS = \ + o/$(MODE)/third_party/bzip2/µbunzip2.o + +THIRD_PARTY_BZIP2_DEPS := $(call uniq, \ + $(LIBC_STR) \ + $(LIBC_STDIO)) + +$(THIRD_PARTY_BZIP2_OBJS): \ + DEFAULT_CPPFLAGS += \ + -DHAVE_CONFIG_H + +o/$(MODE)/third_party/bzip2/µbunzip2.com.dbg: \ + $(THIRD_PARTY_BZIP2_DEPS) \ + $(THIRD_PARTY_BZIP2_OBJS) \ + $(CRT) \ + $(APE) + @$(APELINK) + +$(THIRD_PARTY_BZIP2_OBJS): \ + $(BUILD_FILES) \ + third_party/bzip2/bzip2.mk + +.PHONY: o/$(MODE)/third_party/bzip2 +o/$(MODE)/third_party/bzip2: $(THIRD_PARTY_BZIP2_BINS) diff --git a/third_party/bzip2/µbunzip2.c b/third_party/bzip2/µbunzip2.c new file mode 100644 index 00000000..fea1f5fd --- /dev/null +++ b/third_party/bzip2/µbunzip2.c @@ -0,0 +1,569 @@ +/* micro-bunzip, a small, simple bzip2 decompression implementation. + Copyright 2003 by Rob Landley (rob@landley.net). + + Based on bzip2 decompression code by Julian R Seward (jseward@acm.org), + which also acknowledges contributions by Mike Burrows, David Wheeler, + Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten, + Robert Sedgewick, and Jon L. Bentley. + + I hereby release this code under the GNU Library General Public License + (LGPL) version 2, available at http://www.gnu.org/copyleft/lgpl.html +*/ + +#include "libc/calls/calls.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/fileno.h" + +/* Constants for huffman coding */ +#define MAX_GROUPS 6 +#define GROUP_SIZE 50 /* 64 would have been more efficient */ +#define MAX_HUFCODE_BITS 20 /* Longest huffman code allowed */ +#define MAX_SYMBOLS 258 /* 256 literals + RUNA + RUNB */ +#define SYMBOL_RUNA 0 +#define SYMBOL_RUNB 1 + +/* Status return values */ +#define RETVAL_OK 0 +#define RETVAL_LAST_BLOCK (-1) +#define RETVAL_NOT_BZIP_DATA (-2) +#define RETVAL_UNEXPECTED_INPUT_EOF (-3) +#define RETVAL_UNEXPECTED_OUTPUT_EOF (-4) +#define RETVAL_DATA_ERROR (-5) +#define RETVAL_OUT_OF_MEMORY (-6) +#define RETVAL_OBSOLETE_INPUT (-7) + +/* Other housekeeping constants */ +#define IOBUF_SIZE 4096 + +char *bunzip_errors[] = { NULL, "Bad file checksum", "Not bzip data", + "Unexpected input EOF", "Unexpected output EOF", "Data error", + "Out of memory", "Obsolete (pre 0.9.5) bzip format not supported." }; + +/* This is what we know about each huffman coding group */ +struct group_data { + int limit[MAX_HUFCODE_BITS], base[MAX_HUFCODE_BITS], permute[MAX_SYMBOLS]; + char minLen, maxLen; +}; + +/* Structure holding all the housekeeping data, including IO buffers and + memory that persists between calls to bunzip */ +typedef struct { + /* For I/O error handling */ + jmp_buf jmpbuf; + /* Input stream, input buffer, input bit buffer */ + int64_t in_fd, inbufCount, inbufPos; + unsigned char *inbuf; + unsigned int inbufBitCount, inbufBits; + /* Output buffer */ + char outbuf[IOBUF_SIZE]; + int outbufPos; + /* The CRC values stored in the block header and calculated from the data */ + unsigned int crc32Table[256], headerCRC, dataCRC, totalCRC; + /* Intermediate buffer and its size (in bytes) */ + unsigned int *dbuf, dbufSize; + /* State for interrupting output loop */ + int writePos, writeRun, writeCount, writeCurrent; + + /* These things are a bit too big to go on the stack */ + unsigned char selectors[32768]; /* nSelectors=15 bits */ + struct group_data groups[MAX_GROUPS]; /* huffman coding tables */ +} bunzip_data; + +/* Return the next nnn bits of input. All reads from the compressed + input are done through this function. All reads are big endian */ +static unsigned int get_bits(bunzip_data *bd, char bits_wanted) +{ + unsigned int bits = 0; + + /* If we need to get more data from the byte buffer, do so. (Loop + getting one byte at a time to enforce endianness and avoid + unaligned access.) */ + while (bd->inbufBitCount < bits_wanted) { + /* If we need to read more data from file into byte buffer, do so */ + if (bd->inbufPos == bd->inbufCount) { + if (!(bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE))) + longjmp(bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF); + bd->inbufPos = 0; + } + /* Avoid 32-bit overflow (dump bit buffer to top of output) */ + if (bd->inbufBitCount >= 24) { + bits = bd->inbufBits & ((1u << bd->inbufBitCount) - 1); + bits_wanted -= bd->inbufBitCount; + bits <<= bits_wanted; + bd->inbufBitCount = 0; + } + /* Grab next 8 bits of input from buffer. */ + bd->inbufBits = (bd->inbufBits << 8) | bd->inbuf[bd->inbufPos++]; + bd->inbufBitCount += 8; + } + /* Calculate result */ + bd->inbufBitCount -= bits_wanted; + bits |= (bd->inbufBits >> bd->inbufBitCount) & ((1u << bits_wanted) - 1); + + return bits; +} + +/* Decompress a block of text to into intermediate buffer */ + +static int read_bunzip_data(bunzip_data *bd) +{ + struct group_data *hufGroup; + int dbufCount, nextSym, dbufSize, origPtr, groupCount, *base, *limit, + selector, i, j, k, t, runPos, symCount, symTotal, nSelectors, + byteCount[256]; + unsigned char uc, symToByte[256], mtfSymbol[256], *selectors; + unsigned int *dbuf; + + /* Read in header signature (borrowing mtfSymbol for temp space). */ + for (i = 0; i < 6; i++) + mtfSymbol[i] = get_bits(bd, 8); + mtfSymbol[6] = 0; + /* Read CRC (which is stored big endian). */ + bd->headerCRC = get_bits(bd, 32); + /* Is this the last block (with CRC for file)? */ + if (!strcmp((char *)mtfSymbol, "\x17\x72\x45\x38\x50\x90")) + return RETVAL_LAST_BLOCK; + /* If it's not a valid data block, barf. */ + if (strcmp((char *)mtfSymbol, "\x31\x41\x59\x26\x53\x59")) + return RETVAL_NOT_BZIP_DATA; + + dbuf = bd->dbuf; + dbufSize = bd->dbufSize; + selectors = bd->selectors; + /* We can add support for blockRandomised if anybody complains. + There was some code for this in busybox 1.0.0-pre3, but nobody + ever noticed that it didn't actually work. */ + if (get_bits(bd, 1)) + return RETVAL_OBSOLETE_INPUT; + if ((origPtr = get_bits(bd, 24)) > dbufSize) + return RETVAL_DATA_ERROR; + /* mapping table: if some byte values are never used (encoding + things like ascii text), the compression code removes the gaps to + have fewer symbols to deal with, and writes a sparse bitfield + indicating which values were present. We make a translation table + to convert the symbols back to the corresponding bytes. */ + t = get_bits(bd, 16); + memset(symToByte, 0, 256); + symTotal = 0; + for (i = 0; i < 16; i++) { + if (t & (1u << (15 - i))) { + k = get_bits(bd, 16); + for (j = 0; j < 16; j++) + if (k & (1u << (15 - j))) + symToByte[symTotal++] = (16 * i) + j; + } + } + /* How many different huffman coding groups does this block use? */ + groupCount = get_bits(bd, 3); + if (groupCount < 2 || groupCount > MAX_GROUPS) + return RETVAL_DATA_ERROR; + /* nSelectors: Every GROUP_SIZE many symbols we select a new huffman + coding group. Read in the group selector list, which is stored as + MTF encoded bit runs. */ + if (!(nSelectors = get_bits(bd, 15))) + return RETVAL_DATA_ERROR; + for (i = 0; i < groupCount; i++) + mtfSymbol[i] = i; + for (i = 0; i < nSelectors; i++) { + /* Get next value */ + for (j = 0; get_bits(bd, 1); j++) + if (j >= groupCount) + return RETVAL_DATA_ERROR; + /* Decode MTF to get the next selector */ + uc = mtfSymbol[j]; + memmove(mtfSymbol + 1, mtfSymbol, j); + mtfSymbol[0] = selectors[i] = uc; + } + /* Read the huffman coding tables for each group, which code for symTotal + literal symbols, plus two run symbols (RUNA, RUNB) */ + symCount = symTotal + 2; + for (j = 0; j < groupCount; j++) { + unsigned char length[MAX_SYMBOLS], temp[MAX_HUFCODE_BITS + 1]; + int minLen, maxLen, pp; + /* Read lengths */ + t = get_bits(bd, 5); + for (i = 0; i < symCount; i++) { + for (;;) { + if (t < 1 || t > MAX_HUFCODE_BITS) + return RETVAL_DATA_ERROR; + if (!get_bits(bd, 1)) + break; + if (!get_bits(bd, 1)) + t++; + else + t--; + } + length[i] = t; + } + /* Find largest and smallest lengths in this group */ + minLen = maxLen = length[0]; + for (i = 1; i < symCount; i++) { + if (length[i] > maxLen) + maxLen = length[i]; + else if (length[i] < minLen) + minLen = length[i]; + } + /* Calculate permute[], base[], and limit[] tables from length[]. + * + * permute[] is the lookup table for converting huffman coded symbols + * into decoded symbols. base[] is the amount to subtract from the + * value of a huffman symbol of a given length when using permute[]. + * + * limit[] indicates the largest numerical value a symbol with a given + * number of bits can have. It lets us know when to stop reading. + * + * To use these, keep reading bits until value<=limit[bitcount] or + * you've read over 20 bits (error). Then the decoded symbol + * equals permute[hufcode_value-base[hufcode_bitcount]]. + */ + hufGroup = bd->groups + j; + hufGroup->minLen = minLen; + hufGroup->maxLen = maxLen; + /* Note that minLen can't be smaller than 1, so we adjust the + base and limit array pointers so we're not always wasting the + first entry. We do this again when using them (during symbol + decoding).*/ + base = hufGroup->base - 1; + limit = hufGroup->limit - 1; + /* Calculate permute[] */ + pp = 0; + for (i = minLen; i <= maxLen; i++) + for (t = 0; t < symCount; t++) + if (length[t] == i) + hufGroup->permute[pp++] = t; + /* Count cumulative symbols coded for at each bit length */ + for (i = minLen; i <= maxLen; i++) + temp[i] = limit[i] = 0; + for (i = 0; i < symCount; i++) + temp[length[i]]++; + /* Calculate limit[] (the largest symbol-coding value at each + bit length, which is (previous limit<<1)+symbols at this + level), and base[] (number of symbols to ignore at each bit + length, which is limit-cumulative count of symbols coded for + already). */ + pp = t = 0; + for (i = minLen; i < maxLen; i++) { + pp += temp[i]; + limit[i] = pp - 1; + pp <<= 1; + base[i + 1] = pp - (t += temp[i]); + } + limit[maxLen] = pp + temp[maxLen] - 1; + base[minLen] = 0; + } + /* We've finished reading and digesting the block header. Now read this + block's huffman coded symbols from the file and undo the huffman + coding and run length encoding, saving the result into + dbuf[dbufCount++]=uc */ + + /* Initialize symbol occurrence counters and symbol mtf table */ + memset(byteCount, 0, 256 * sizeof(int)); + for (i = 0; i < 256; i++) + mtfSymbol[i] = (unsigned char)i; + /* Loop through compressed symbols */ + runPos = dbufCount = symCount = selector = 0; + for (;;) { + /* Determine which huffman coding group to use. */ + if (!(symCount--)) { + symCount = GROUP_SIZE - 1; + if (selector >= nSelectors) + return RETVAL_DATA_ERROR; + hufGroup = bd->groups + selectors[selector++]; + base = hufGroup->base - 1; + limit = hufGroup->limit - 1; + } + /* Read next huffman-coded symbol */ + i = hufGroup->minLen; + j = get_bits(bd, i); + for (;;) { + if (i > hufGroup->maxLen) + return RETVAL_DATA_ERROR; + if (j <= limit[i]) + break; + i++; + + j = (j << 1) | get_bits(bd, 1); + } + /* Huffman decode nextSym (with bounds checking) */ + j -= base[i]; + if (j < 0 || j >= MAX_SYMBOLS) + return RETVAL_DATA_ERROR; + nextSym = hufGroup->permute[j]; + /* If this is a repeated run, loop collecting data */ + if (nextSym == SYMBOL_RUNA || nextSym == SYMBOL_RUNB) { + /* If this is the start of a new run, zero out counter */ + if (!runPos) { + runPos = 1; + t = 0; + } + /* Neat trick that saves 1 symbol: instead of or-ing 0 or 1 + at each bit position, add 1 or 2 instead. For example, + 1011 is 1<<0 + 1<<1 + 2<<2. 1010 is 2<<0 + 2<<1 + 1<<2. + You can make any bit pattern that way using 1 less symbol + than the basic or 0/1 method (except all bits 0, which + would use no symbols, but a run of length 0 doesn't mean + anything in this context). Thus space is saved. */ + if (nextSym == SYMBOL_RUNA) + t += runPos; + else + t += 2 * runPos; + runPos <<= 1; + continue; + } + /* When we hit the first non-run symbol after a run, we now know + how many times to repeat the last literal, so append that + many copies to our buffer of decoded symbols (dbuf) now. (The + last literal used is the one at the head of the mtfSymbol + array.) */ + if (runPos) { + runPos = 0; + if (dbufCount + t >= dbufSize) + return RETVAL_DATA_ERROR; + + uc = symToByte[mtfSymbol[0]]; + byteCount[uc] += t; + while (t--) + dbuf[dbufCount++] = uc; + } + /* Is this the terminating symbol? */ + if (nextSym > symTotal) + break; + /* At this point, the symbol we just decoded indicates a new + literal character. Subtract one to get the position in the + MTF array at which this literal is currently to be found. + (Note that the result can't be -1 or 0, because 0 and 1 are + RUNA and RUNB. Another instance of the first symbol in the + mtf array, position 0, would have been handled as part of a + run.) */ + if (dbufCount >= dbufSize) + return RETVAL_DATA_ERROR; + i = nextSym - 1; + uc = mtfSymbol[i]; + memmove(mtfSymbol + 1, mtfSymbol, i); + mtfSymbol[0] = uc; + uc = symToByte[uc]; + /* We have our literal byte. Save it into dbuf. */ + byteCount[uc]++; + dbuf[dbufCount++] = (unsigned int)uc; + } + /* At this point, we've finished reading huffman-coded symbols and + compressed runs from the input stream. There are dbufCount many + of them in dbuf[]. Now undo the Burrows-Wheeler transform on + dbuf. See http://dogma.net/markn/articles/bwt/bwt.htm */ + + /* Now we know what dbufCount is, do a better sanity check on origPtr. */ + if (origPtr < 0 || origPtr >= dbufCount) + return RETVAL_DATA_ERROR; + /* Turn byteCount into cumulative occurrence counts of 0 to n-1. */ + j = 0; + for (i = 0; i < 256; i++) { + k = j + byteCount[i]; + byteCount[i] = j; + j = k; + } + /* Figure out what order dbuf would be in if we sorted it. */ + for (i = 0; i < dbufCount; i++) { + uc = (unsigned char)(dbuf[i] & 0xff); + dbuf[byteCount[uc]] |= (i << 8); + byteCount[uc]++; + } + /* blockRandomised support would go here. */ + + /* Using i as position, j as previous character, t as current character, + and uc as run count */ + bd->dataCRC = 0xffffffffL; + /* Decode first byte by hand to initialize "previous" byte. Note + that it doesn't get output, and if the first three characters are + identical it doesn't qualify as a run (hence uc=255, which will + either wrap to 1 or get reset). */ + if (dbufCount) { + bd->writePos = dbuf[origPtr]; + bd->writeCurrent = (unsigned char)(bd->writePos & 0xff); + bd->writePos >>= 8; + bd->writeRun = -1; + } + bd->writeCount = dbufCount; + + return RETVAL_OK; +} + +/* Flush output buffer to disk */ +static void flush_bunzip_outbuf(bunzip_data *bd, int64_t out_fd) +{ + if (bd->outbufPos) { + if (write(out_fd, bd->outbuf, bd->outbufPos) != bd->outbufPos) + longjmp(bd->jmpbuf, RETVAL_UNEXPECTED_OUTPUT_EOF); + bd->outbufPos = 0; + } +} + +/* Undo burrows-wheeler transform on intermediate buffer to produce output. + If !len, write up to len bytes of data to buf. Otherwise write to out_fd. + Returns len ? bytes written : RETVAL_OK. Notice all errors negative #'s. */ +static int write_bunzip_data( + bunzip_data *bd, int64_t out_fd, char *outbuf, int len) +{ + unsigned int *dbuf = bd->dbuf; + int count, pos, current, run, copies, outbyte, previous, gotcount = 0; + + for (;;) { + /* If last read was short due to end of file, return last block now */ + if (bd->writeCount < 0) + return bd->writeCount; + /* If we need to refill dbuf, do it. */ + if (!bd->writeCount) { + int i = read_bunzip_data(bd); + if (i) { + if (i == RETVAL_LAST_BLOCK) { + bd->writeCount = i; + return gotcount; + } else + return i; + } + } + /* Loop generating output */ + count = bd->writeCount; + pos = bd->writePos; + current = bd->writeCurrent; + run = bd->writeRun; + while (count) { + /* If somebody (like busybox tar) wants a certain number of + bytes of data from memory instead of written to a file, + humor them */ + if (len && bd->outbufPos >= len) + goto dataus_interruptus; + count--; + /* Follow sequence vector to undo Burrows-Wheeler transform */ + previous = current; + pos = dbuf[pos]; + current = pos & 0xff; + pos >>= 8; + /* Whenever we see 3 consecutive copies of the same byte, + the 4th is a repeat count */ + if (run++ == 3) { + copies = current; + outbyte = previous; + current = -1; + } else { + copies = 1; + outbyte = current; + } + /* Output bytes to buffer, flushing to file if necessary */ + while (copies--) { + if (bd->outbufPos == IOBUF_SIZE) + flush_bunzip_outbuf(bd, out_fd); + bd->outbuf[bd->outbufPos++] = outbyte; + bd->dataCRC = (bd->dataCRC << 8) + ^ bd->crc32Table[(bd->dataCRC >> 24) ^ outbyte]; + } + if (current != previous) + run = 0; + } + /* Decompression of this block completed successfully */ + bd->dataCRC = ~(bd->dataCRC); + bd->totalCRC + = ((bd->totalCRC << 1) | (bd->totalCRC >> 31)) ^ bd->dataCRC; + /* If this block had a CRC error, force file level CRC error. */ + if (bd->dataCRC != bd->headerCRC) { + bd->totalCRC = bd->headerCRC + 1; + return RETVAL_LAST_BLOCK; + } + dataus_interruptus: + bd->writeCount = count; + if (len) { + gotcount += bd->outbufPos; + memcpy(outbuf, bd->outbuf, len); + /* If we got enough data, checkpoint loop state and return */ + if ((len -= bd->outbufPos) < 1) { + bd->outbufPos -= len; + if (bd->outbufPos) + memmove(bd->outbuf, bd->outbuf + len, bd->outbufPos); + bd->writePos = pos; + bd->writeCurrent = current; + bd->writeRun = run; + return gotcount; + } + } + } +} + +/* Allocate the structure, read file header. If !len, src_fd contains + filehandle to read from. Else inbuf contains data. */ +static int start_bunzip(bunzip_data **bdp, int64_t src_fd, char *inbuf, int len) +{ + bunzip_data *bd; + unsigned int i, j, c; + + /* Figure out how much data to allocate */ + i = sizeof(bunzip_data); + if (!len) + i += IOBUF_SIZE; + /* Allocate bunzip_data. Most fields initialize to zero. */ + if (!(bd = *bdp = malloc(i))) + return RETVAL_OUT_OF_MEMORY; + memset(bd, 0, sizeof(bunzip_data)); + if (len) { + bd->inbuf = (unsigned char *)inbuf; + bd->inbufCount = len; + bd->in_fd = -1; + } else { + bd->inbuf = (unsigned char *)(bd + 1); + bd->in_fd = src_fd; + } + /* Init the CRC32 table (big endian) */ + for (i = 0; i < 256; i++) { + c = i << 24; + for (j = 8; j; j--) + c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1); + bd->crc32Table[i] = c; + } + /* Setup for I/O error handling via longjmp */ + i = setjmp(bd->jmpbuf); + if (i) + return i; + /* Ensure that file starts with "BZh" */ + for (i = 0; i < 3; i++) + if (get_bits(bd, 8) != "BZh"[i]) + return RETVAL_NOT_BZIP_DATA; + /* Next byte ascii '1'-'9', indicates block size in units of 100k of + uncompressed data. Allocate intermediate buffer for block. */ + i = get_bits(bd, 8); + if (i < '1' || i > '9') + return RETVAL_NOT_BZIP_DATA; + bd->dbufSize = 100000 * (i - '0'); + if (!(bd->dbuf = malloc(bd->dbufSize * sizeof(int)))) + return RETVAL_OUT_OF_MEMORY; + return RETVAL_OK; +} + +/* Example usage: decompress src_fd to dst_fd. (Stops at end of bzip data, + not end of file.) */ +static char *uncompressStream(int64_t src_fd, int64_t dst_fd) +{ + bunzip_data *bd; + int i; + if (!(i = start_bunzip(&bd, src_fd, 0, 0))) { + i = write_bunzip_data(bd, dst_fd, 0, 0); + if (i == RETVAL_LAST_BLOCK && bd->headerCRC == bd->totalCRC) + i = RETVAL_OK; + } + flush_bunzip_outbuf(bd, dst_fd); + if (bd->dbuf) + free(bd->dbuf); + free(bd); + return bunzip_errors[-i]; +} + +int main(int argc, char *argv[]) +{ + char *err; + if (!(err = uncompressStream(STDIN_FILENO, STDOUT_FILENO))) { + return 0; + } else { + fprintf(stderr, "\n%s\n", err); + return 1; + } +} diff --git a/third_party/compiler_rt/absvdi2.c b/third_party/compiler_rt/absvdi2.c new file mode 100644 index 00000000..bf9077ca --- /dev/null +++ b/third_party/compiler_rt/absvdi2.c @@ -0,0 +1,32 @@ +/* clang-format off */ +/*===-- absvdi2.c - Implement __absvdi2 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + *===----------------------------------------------------------------------=== + * + * This file implements __absvdi2 for the compiler_rt library. + * + *===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: absolute value */ + +/* Effects: aborts if abs(x) < 0 */ + +COMPILER_RT_ABI di_int +__absvdi2(di_int a) +{ + const int N = (int)(sizeof(di_int) * CHAR_BIT); + if (a == ((di_int)1 << (N-1))) + compilerrt_abort(); + const di_int t = a >> (N - 1); + return (a ^ t) - t; +} diff --git a/third_party/compiler_rt/absvsi2.c b/third_party/compiler_rt/absvsi2.c new file mode 100644 index 00000000..cf60b620 --- /dev/null +++ b/third_party/compiler_rt/absvsi2.c @@ -0,0 +1,32 @@ +/* clang-format off */ +/* ===-- absvsi2.c - Implement __absvsi2 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __absvsi2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: absolute value */ + +/* Effects: aborts if abs(x) < 0 */ + +COMPILER_RT_ABI si_int +__absvsi2(si_int a) +{ + const int N = (int)(sizeof(si_int) * CHAR_BIT); + if (a == (1 << (N-1))) + compilerrt_abort(); + const si_int t = a >> (N - 1); + return (a ^ t) - t; +} diff --git a/third_party/compiler_rt/absvti2.c b/third_party/compiler_rt/absvti2.c new file mode 100644 index 00000000..86f1a0b8 --- /dev/null +++ b/third_party/compiler_rt/absvti2.c @@ -0,0 +1,37 @@ +/* clang-format off */ +/* ===-- absvti2.c - Implement __absvdi2 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __absvti2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: absolute value */ + +/* Effects: aborts if abs(x) < 0 */ + +COMPILER_RT_ABI ti_int +__absvti2(ti_int a) +{ + const int N = (int)(sizeof(ti_int) * CHAR_BIT); + if (a == ((ti_int)1 << (N-1))) + compilerrt_abort(); + const ti_int s = a >> (N - 1); + return (a ^ s) - s; +} + +#endif /* CRT_HAS_128BIT */ + diff --git a/third_party/compiler_rt/adddf3.c b/third_party/compiler_rt/adddf3.c new file mode 100644 index 00000000..8dfba884 --- /dev/null +++ b/third_party/compiler_rt/adddf3.c @@ -0,0 +1,33 @@ +/* clang-format off */ +//===-- lib/adddf3.c - Double-precision addition ------------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements double-precision soft-float addition with the IEEE-754 +// default rounding (to nearest, ties to even). +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define DOUBLE_PRECISION +#include "third_party/compiler_rt/fp_add_impl.inc" + +COMPILER_RT_ABI double __adddf3(double a, double b){ + return __addXf3__(a, b); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI double __aeabi_dadd(double a, double b) { + return __adddf3(a, b); +} +#else +AEABI_RTABI double __aeabi_dadd(double a, double b) COMPILER_RT_ALIAS(__adddf3); +#endif +#endif diff --git a/third_party/compiler_rt/addsf3.c b/third_party/compiler_rt/addsf3.c new file mode 100644 index 00000000..909eabea --- /dev/null +++ b/third_party/compiler_rt/addsf3.c @@ -0,0 +1,33 @@ +/* clang-format off */ +//===-- lib/addsf3.c - Single-precision addition ------------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements single-precision soft-float addition with the IEEE-754 +// default rounding (to nearest, ties to even). +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SINGLE_PRECISION +#include "third_party/compiler_rt/fp_add_impl.inc" + +COMPILER_RT_ABI float __addsf3(float a, float b) { + return __addXf3__(a, b); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI float __aeabi_fadd(float a, float b) { + return __addsf3(a, b); +} +#else +AEABI_RTABI float __aeabi_fadd(float a, float b) COMPILER_RT_ALIAS(__addsf3); +#endif +#endif diff --git a/third_party/compiler_rt/addtf3.c b/third_party/compiler_rt/addtf3.c new file mode 100644 index 00000000..c01000c9 --- /dev/null +++ b/third_party/compiler_rt/addtf3.c @@ -0,0 +1,28 @@ +/* clang-format off */ +//===-- lib/addtf3.c - Quad-precision addition --------------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements quad-precision soft-float addition with the IEEE-754 +// default rounding (to nearest, ties to even). +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +#include "third_party/compiler_rt/fp_add_impl.inc" + +COMPILER_RT_ABI long double __addtf3(long double a, long double b){ + return __addXf3__(a, b); +} + +#endif diff --git a/third_party/compiler_rt/ashldi3.c b/third_party/compiler_rt/ashldi3.c new file mode 100644 index 00000000..edb6a650 --- /dev/null +++ b/third_party/compiler_rt/ashldi3.c @@ -0,0 +1,48 @@ +/* clang-format off */ +/* ====-- ashldi3.c - Implement __ashldi3 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __ashldi3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a << b */ + +/* Precondition: 0 <= b < bits_in_dword */ + +COMPILER_RT_ABI di_int +__ashldi3(di_int a, si_int b) +{ + const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT); + dwords input; + dwords result; + input.all = a; + if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */ + { + result.s.low = 0; + result.s.high = input.s.low << (b - bits_in_word); + } + else /* 0 <= b < bits_in_word */ + { + if (b == 0) + return a; + result.s.low = input.s.low << b; + result.s.high = (input.s.high << b) | (input.s.low >> (bits_in_word - b)); + } + return result.all; +} + +#if defined(__ARM_EABI__) +AEABI_RTABI di_int __aeabi_llsl(di_int a, si_int b) COMPILER_RT_ALIAS(__ashldi3); +#endif diff --git a/third_party/compiler_rt/ashlti3.c b/third_party/compiler_rt/ashlti3.c new file mode 100644 index 00000000..d361156a --- /dev/null +++ b/third_party/compiler_rt/ashlti3.c @@ -0,0 +1,48 @@ +/* clang-format off */ +/* ===-- ashlti3.c - Implement __ashlti3 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __ashlti3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: a << b */ + +/* Precondition: 0 <= b < bits_in_tword */ + +COMPILER_RT_ABI ti_int +__ashlti3(ti_int a, si_int b) +{ + const int bits_in_dword = (int)(sizeof(di_int) * CHAR_BIT); + twords input; + twords result; + input.all = a; + if (b & bits_in_dword) /* bits_in_dword <= b < bits_in_tword */ + { + result.s.low = 0; + result.s.high = input.s.low << (b - bits_in_dword); + } + else /* 0 <= b < bits_in_dword */ + { + if (b == 0) + return a; + result.s.low = input.s.low << b; + result.s.high = (input.s.high << b) | (input.s.low >> (bits_in_dword - b)); + } + return result.all; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/ashrdi3.c b/third_party/compiler_rt/ashrdi3.c new file mode 100644 index 00000000..84422714 --- /dev/null +++ b/third_party/compiler_rt/ashrdi3.c @@ -0,0 +1,49 @@ +/* clang-format off */ +/*===-- ashrdi3.c - Implement __ashrdi3 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __ashrdi3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: arithmetic a >> b */ + +/* Precondition: 0 <= b < bits_in_dword */ + +COMPILER_RT_ABI di_int +__ashrdi3(di_int a, si_int b) +{ + const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT); + dwords input; + dwords result; + input.all = a; + if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */ + { + /* result.s.high = input.s.high < 0 ? -1 : 0 */ + result.s.high = input.s.high >> (bits_in_word - 1); + result.s.low = input.s.high >> (b - bits_in_word); + } + else /* 0 <= b < bits_in_word */ + { + if (b == 0) + return a; + result.s.high = input.s.high >> b; + result.s.low = (input.s.high << (bits_in_word - b)) | (input.s.low >> b); + } + return result.all; +} + +#if defined(__ARM_EABI__) +AEABI_RTABI di_int __aeabi_lasr(di_int a, si_int b) COMPILER_RT_ALIAS(__ashrdi3); +#endif diff --git a/third_party/compiler_rt/ashrti3.c b/third_party/compiler_rt/ashrti3.c new file mode 100644 index 00000000..4c3cc3d5 --- /dev/null +++ b/third_party/compiler_rt/ashrti3.c @@ -0,0 +1,49 @@ +/* clang-format off */ +/* ===-- ashrti3.c - Implement __ashrti3 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __ashrti3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: arithmetic a >> b */ + +/* Precondition: 0 <= b < bits_in_tword */ + +COMPILER_RT_ABI ti_int +__ashrti3(ti_int a, si_int b) +{ + const int bits_in_dword = (int)(sizeof(di_int) * CHAR_BIT); + twords input; + twords result; + input.all = a; + if (b & bits_in_dword) /* bits_in_dword <= b < bits_in_tword */ + { + /* result.s.high = input.s.high < 0 ? -1 : 0 */ + result.s.high = input.s.high >> (bits_in_dword - 1); + result.s.low = input.s.high >> (b - bits_in_dword); + } + else /* 0 <= b < bits_in_dword */ + { + if (b == 0) + return a; + result.s.high = input.s.high >> b; + result.s.low = (input.s.high << (bits_in_dword - b)) | (input.s.low >> b); + } + return result.all; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/assembly.h b/third_party/compiler_rt/assembly.h new file mode 100644 index 00000000..a479aae5 --- /dev/null +++ b/third_party/compiler_rt/assembly.h @@ -0,0 +1,205 @@ +/* clang-format off */ +/* ===-- assembly.h - compiler-rt assembler support macros -----------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file defines macros for use in compiler-rt assembler source. + * This file is not part of the interface of this library. + * + * ===----------------------------------------------------------------------=== + */ + +#ifndef COMPILERRT_ASSEMBLY_H +#define COMPILERRT_ASSEMBLY_H + +#if defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__) +#define SEPARATOR @ +#else +#define SEPARATOR ; +#endif + +#if defined(__APPLE__) +#define HIDDEN(name) .private_extern name +#define LOCAL_LABEL(name) L_##name +// tell linker it can break up file at label boundaries +#define FILE_LEVEL_DIRECTIVE .subsections_via_symbols +#define SYMBOL_IS_FUNC(name) +#define CONST_SECTION .const + +#define NO_EXEC_STACK_DIRECTIVE + +#elif defined(__ELF__) + +#define HIDDEN(name) .hidden name +#define LOCAL_LABEL(name) .L_##name +#define FILE_LEVEL_DIRECTIVE +#if defined(__arm__) +#define SYMBOL_IS_FUNC(name) .type name,%function +#else +#define SYMBOL_IS_FUNC(name) .type name,@function +#endif +#define CONST_SECTION .section .rodata + +#if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \ + defined(__linux__) +#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits +#else +#define NO_EXEC_STACK_DIRECTIVE +#endif + +#else // !__APPLE__ && !__ELF__ + +#define HIDDEN(name) +#define LOCAL_LABEL(name) .L ## name +#define FILE_LEVEL_DIRECTIVE +#define SYMBOL_IS_FUNC(name) \ + .def name SEPARATOR \ + .scl 2 SEPARATOR \ + .type 32 SEPARATOR \ + .endef +#define CONST_SECTION .section .rdata,"rd" + +#define NO_EXEC_STACK_DIRECTIVE + +#endif + +#if defined(__arm__) + +/* + * Determine actual [ARM][THUMB[1][2]] ISA using compiler predefined macros: + * - for '-mthumb -march=armv6' compiler defines '__thumb__' + * - for '-mthumb -march=armv7' compiler defines '__thumb__' and '__thumb2__' + */ +#if defined(__thumb2__) || defined(__thumb__) +#define DEFINE_CODE_STATE .thumb SEPARATOR +#define DECLARE_FUNC_ENCODING .thumb_func SEPARATOR +#if defined(__thumb2__) +#define USE_THUMB_2 +#define IT(cond) it cond +#define ITT(cond) itt cond +#define ITE(cond) ite cond +#else +#define USE_THUMB_1 +#define IT(cond) +#define ITT(cond) +#define ITE(cond) +#endif // defined(__thumb__2) +#else // !defined(__thumb2__) && !defined(__thumb__) +#define DEFINE_CODE_STATE .arm SEPARATOR +#define DECLARE_FUNC_ENCODING +#define IT(cond) +#define ITT(cond) +#define ITE(cond) +#endif + +#if defined(USE_THUMB_1) && defined(USE_THUMB_2) +#error "USE_THUMB_1 and USE_THUMB_2 can't be defined together." +#endif + +#if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5 +#define ARM_HAS_BX +#endif +#if !defined(__ARM_FEATURE_CLZ) && !defined(USE_THUMB_1) && \ + (__ARM_ARCH >= 6 || (__ARM_ARCH == 5 && !defined(__ARM_ARCH_5__))) +#define __ARM_FEATURE_CLZ +#endif + +#ifdef ARM_HAS_BX +#define JMP(r) bx r +#define JMPc(r, c) bx##c r +#else +#define JMP(r) mov pc, r +#define JMPc(r, c) mov##c pc, r +#endif + +// pop {pc} can't switch Thumb mode on ARMv4T +#if __ARM_ARCH >= 5 +#define POP_PC() pop {pc} +#else +#define POP_PC() \ + pop {ip}; \ + JMP(ip) +#endif + +#if defined(USE_THUMB_2) +#define WIDE(op) op.w +#else +#define WIDE(op) op +#endif +#else // !defined(__arm) +#define DECLARE_FUNC_ENCODING +#define DEFINE_CODE_STATE +#endif + +#define GLUE2(a, b) a##b +#define GLUE(a, b) GLUE2(a, b) +#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name) + +#ifdef VISIBILITY_HIDDEN +#define DECLARE_SYMBOL_VISIBILITY(name) \ + HIDDEN(SYMBOL_NAME(name)) SEPARATOR +#else +#define DECLARE_SYMBOL_VISIBILITY(name) +#endif + +#define DEFINE_COMPILERRT_FUNCTION(name) \ + DEFINE_CODE_STATE \ + FILE_LEVEL_DIRECTIVE SEPARATOR \ + .globl SYMBOL_NAME(name) SEPARATOR \ + SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ + DECLARE_SYMBOL_VISIBILITY(name) \ + DECLARE_FUNC_ENCODING \ + SYMBOL_NAME(name): + +#define DEFINE_COMPILERRT_THUMB_FUNCTION(name) \ + DEFINE_CODE_STATE \ + FILE_LEVEL_DIRECTIVE SEPARATOR \ + .globl SYMBOL_NAME(name) SEPARATOR \ + SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ + DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \ + .thumb_func SEPARATOR \ + SYMBOL_NAME(name): + +#define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \ + DEFINE_CODE_STATE \ + FILE_LEVEL_DIRECTIVE SEPARATOR \ + .globl SYMBOL_NAME(name) SEPARATOR \ + SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ + HIDDEN(SYMBOL_NAME(name)) SEPARATOR \ + DECLARE_FUNC_ENCODING \ + SYMBOL_NAME(name): + +#define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \ + DEFINE_CODE_STATE \ + .globl name SEPARATOR \ + SYMBOL_IS_FUNC(name) SEPARATOR \ + HIDDEN(name) SEPARATOR \ + DECLARE_FUNC_ENCODING \ + name: + +#define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target) \ + .globl SYMBOL_NAME(name) SEPARATOR \ + SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ + DECLARE_SYMBOL_VISIBILITY(SYMBOL_NAME(name)) SEPARATOR \ + .set SYMBOL_NAME(name), SYMBOL_NAME(target) SEPARATOR + +#if defined(__ARM_EABI__) +#define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) \ + DEFINE_COMPILERRT_FUNCTION_ALIAS(aeabi_name, name) +#else +#define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) +#endif + +#ifdef __ELF__ +#define END_COMPILERRT_FUNCTION(name) \ + .size SYMBOL_NAME(name), . - SYMBOL_NAME(name) +#else +#define END_COMPILERRT_FUNCTION(name) +#endif + +#endif /* COMPILERRT_ASSEMBLY_H */ diff --git a/third_party/compiler_rt/bswapdi2.c b/third_party/compiler_rt/bswapdi2.c new file mode 100644 index 00000000..e3e61e90 --- /dev/null +++ b/third_party/compiler_rt/bswapdi2.c @@ -0,0 +1,30 @@ +/* clang-format off */ +/* ===-- bswapdi2.c - Implement __bswapdi2 ---------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __bswapdi2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +COMPILER_RT_ABI uint64_t __bswapdi2(uint64_t u) { + return ( + (((u)&0xff00000000000000ULL) >> 56) | + (((u)&0x00ff000000000000ULL) >> 40) | + (((u)&0x0000ff0000000000ULL) >> 24) | + (((u)&0x000000ff00000000ULL) >> 8) | + (((u)&0x00000000ff000000ULL) << 8) | + (((u)&0x0000000000ff0000ULL) << 24) | + (((u)&0x000000000000ff00ULL) << 40) | + (((u)&0x00000000000000ffULL) << 56)); +} diff --git a/third_party/compiler_rt/bswapsi2.c b/third_party/compiler_rt/bswapsi2.c new file mode 100644 index 00000000..01c34c47 --- /dev/null +++ b/third_party/compiler_rt/bswapsi2.c @@ -0,0 +1,26 @@ +/* clang-format off */ +/* ===-- bswapsi2.c - Implement __bswapsi2 ---------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __bswapsi2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +COMPILER_RT_ABI uint32_t __bswapsi2(uint32_t u) { + return ( + (((u)&0xff000000) >> 24) | + (((u)&0x00ff0000) >> 8) | + (((u)&0x0000ff00) << 8) | + (((u)&0x000000ff) << 24)); +} diff --git a/third_party/compiler_rt/clear_cache.c b/third_party/compiler_rt/clear_cache.c new file mode 100644 index 00000000..e139f29e --- /dev/null +++ b/third_party/compiler_rt/clear_cache.c @@ -0,0 +1,183 @@ +/* clang-format off */ +/* ===-- clear_cache.c - Implement __clear_cache ---------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#if __APPLE__ + #include +#endif + +#if defined(_WIN32) +/* Forward declare Win32 APIs since the GCC mode driver does not handle the + newer SDKs as well as needed. */ +uint32_t FlushInstructionCache(uintptr_t hProcess, void *lpBaseAddress, + uintptr_t dwSize); +uintptr_t GetCurrentProcess(void); +#endif + +#if defined(__linux__) && defined(__mips__) + #if defined(__ANDROID__) && defined(__LP64__) + /* + * clear_mips_cache - Invalidates instruction cache for Mips. + */ + static void clear_mips_cache(const void* Addr, size_t Size) { + __asm__ volatile ( + ".set push\n" + ".set noreorder\n" + ".set noat\n" + "beq %[Size], $zero, 20f\n" /* If size == 0, branch around. */ + "nop\n" + "daddu %[Size], %[Addr], %[Size]\n" /* Calculate end address + 1 */ + "rdhwr $v0, $1\n" /* Get step size for SYNCI. + $1 is $HW_SYNCI_Step */ + "beq $v0, $zero, 20f\n" /* If no caches require + synchronization, branch + around. */ + "nop\n" + "10:\n" + "synci 0(%[Addr])\n" /* Synchronize all caches around + address. */ + "daddu %[Addr], %[Addr], $v0\n" /* Add step size. */ + "sltu $at, %[Addr], %[Size]\n" /* Compare current with end + address. */ + "bne $at, $zero, 10b\n" /* Branch if more to do. */ + "nop\n" + "sync\n" /* Clear memory hazards. */ + "20:\n" + "bal 30f\n" + "nop\n" + "30:\n" + "daddiu $ra, $ra, 12\n" /* $ra has a value of $pc here. + Add offset of 12 to point to the + instruction after the last nop. + */ + "jr.hb $ra\n" /* Return, clearing instruction + hazards. */ + "nop\n" + ".set pop\n" + : [Addr] "+r"(Addr), [Size] "+r"(Size) + :: "at", "ra", "v0", "memory" + ); + } + #endif +#endif + +/* + * The compiler generates calls to __clear_cache() when creating + * trampoline functions on the stack for use with nested functions. + * It is expected to invalidate the instruction cache for the + * specified range. + */ + +void __clear_cache(void *start, void *end) { +#if __i386__ || __x86_64__ || defined(_M_IX86) || defined(_M_X64) +/* + * Intel processors have a unified instruction and data cache + * so there is nothing to do + */ +#elif defined(_WIN32) && (defined(__arm__) || defined(__aarch64__)) + FlushInstructionCache(GetCurrentProcess(), start, end - start); +#elif defined(__arm__) && !defined(__APPLE__) + #if defined(__FreeBSD__) || defined(__NetBSD__) + struct arm_sync_icache_args arg; + + arg.addr = (uintptr_t)start; + arg.len = (uintptr_t)end - (uintptr_t)start; + + sysarch(ARM_SYNC_ICACHE, &arg); + #elif defined(__linux__) + /* + * We used to include asm/unistd.h for the __ARM_NR_cacheflush define, but + * it also brought many other unused defines, as well as a dependency on + * kernel headers to be installed. + * + * This value is stable at least since Linux 3.13 and should remain so for + * compatibility reasons, warranting it's re-definition here. + */ + #define __ARM_NR_cacheflush 0x0f0002 + register int start_reg __asm("r0") = (int) (intptr_t) start; + const register int end_reg __asm("r1") = (int) (intptr_t) end; + const register int flags __asm("r2") = 0; + const register int syscall_nr __asm("r7") = __ARM_NR_cacheflush; + __asm __volatile("svc 0x0" + : "=r"(start_reg) + : "r"(syscall_nr), "r"(start_reg), "r"(end_reg), + "r"(flags)); + assert(start_reg == 0 && "Cache flush syscall failed."); + #else + compilerrt_abort(); + #endif +#elif defined(__linux__) && defined(__mips__) + const uintptr_t start_int = (uintptr_t) start; + const uintptr_t end_int = (uintptr_t) end; + #if defined(__ANDROID__) && defined(__LP64__) + // Call synci implementation for short address range. + const uintptr_t address_range_limit = 256; + if ((end_int - start_int) <= address_range_limit) { + clear_mips_cache(start, (end_int - start_int)); + } else { + syscall(__NR_cacheflush, start, (end_int - start_int), BCACHE); + } + #else + syscall(__NR_cacheflush, start, (end_int - start_int), BCACHE); + #endif +#elif defined(__mips__) && defined(__OpenBSD__) + cacheflush(start, (uintptr_t)end - (uintptr_t)start, BCACHE); +#elif defined(__aarch64__) && !defined(__APPLE__) + uint64_t xstart = (uint64_t)(uintptr_t) start; + uint64_t xend = (uint64_t)(uintptr_t) end; + uint64_t addr; + + // Get Cache Type Info + uint64_t ctr_el0; + __asm __volatile("mrs %0, ctr_el0" : "=r"(ctr_el0)); + + /* + * dc & ic instructions must use 64bit registers so we don't use + * uintptr_t in case this runs in an IPL32 environment. + */ + const size_t dcache_line_size = 4 << ((ctr_el0 >> 16) & 15); + for (addr = xstart & ~(dcache_line_size - 1); addr < xend; + addr += dcache_line_size) + __asm __volatile("dc cvau, %0" :: "r"(addr)); + __asm __volatile("dsb ish"); + + const size_t icache_line_size = 4 << ((ctr_el0 >> 0) & 15); + for (addr = xstart & ~(icache_line_size - 1); addr < xend; + addr += icache_line_size) + __asm __volatile("ic ivau, %0" :: "r"(addr)); + __asm __volatile("isb sy"); +#elif defined (__powerpc64__) + const size_t line_size = 32; + const size_t len = (uintptr_t)end - (uintptr_t)start; + + const uintptr_t mask = ~(line_size - 1); + const uintptr_t start_line = ((uintptr_t)start) & mask; + const uintptr_t end_line = ((uintptr_t)start + len + line_size - 1) & mask; + + for (uintptr_t line = start_line; line < end_line; line += line_size) + __asm__ volatile("dcbf 0, %0" : : "r"(line)); + __asm__ volatile("sync"); + + for (uintptr_t line = start_line; line < end_line; line += line_size) + __asm__ volatile("icbi 0, %0" : : "r"(line)); + __asm__ volatile("isync"); +#else + #if __APPLE__ + /* On Darwin, sys_icache_invalidate() provides this functionality */ + sys_icache_invalidate(start, end-start); + #else + compilerrt_abort(); + #endif +#endif +} diff --git a/third_party/compiler_rt/clzdi2.c b/third_party/compiler_rt/clzdi2.c new file mode 100644 index 00000000..b2e4e222 --- /dev/null +++ b/third_party/compiler_rt/clzdi2.c @@ -0,0 +1,43 @@ +/* clang-format off */ +/* ===-- clzdi2.c - Implement __clzdi2 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __clzdi2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: the number of leading 0-bits */ + +#if !defined(__clang__) && \ + ((defined(__sparc__) && defined(__arch64__)) || \ + defined(__mips64) || \ + (defined(__riscv) && __SIZEOF_POINTER__ >= 8)) +/* On 64-bit architectures with neither a native clz instruction nor a native + * ctz instruction, gcc resolves __builtin_clz to __clzdi2 rather than + * __clzsi2, leading to infinite recursion. */ +#define __builtin_clz(a) __clzsi2(a) +extern si_int __clzsi2(si_int); +#endif + +/* Precondition: a != 0 */ + +COMPILER_RT_ABI si_int +__clzdi2(di_int a) +{ + dwords x; + x.all = a; + const si_int f = -(x.s.high == 0); + return __builtin_clz((x.s.high & ~f) | (x.s.low & f)) + + (f & ((si_int)(sizeof(si_int) * CHAR_BIT))); +} diff --git a/third_party/compiler_rt/clzsi2.c b/third_party/compiler_rt/clzsi2.c new file mode 100644 index 00000000..32d52e74 --- /dev/null +++ b/third_party/compiler_rt/clzsi2.c @@ -0,0 +1,56 @@ +/* clang-format off */ +/* ===-- clzsi2.c - Implement __clzsi2 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __clzsi2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: the number of leading 0-bits */ + +/* Precondition: a != 0 */ + +COMPILER_RT_ABI si_int +__clzsi2(si_int a) +{ + su_int x = (su_int)a; + si_int t = ((x & 0xFFFF0000) == 0) << 4; /* if (x is small) t = 16 else 0 */ + x >>= 16 - t; /* x = [0 - 0xFFFF] */ + su_int r = t; /* r = [0, 16] */ + /* return r + clz(x) */ + t = ((x & 0xFF00) == 0) << 3; + x >>= 8 - t; /* x = [0 - 0xFF] */ + r += t; /* r = [0, 8, 16, 24] */ + /* return r + clz(x) */ + t = ((x & 0xF0) == 0) << 2; + x >>= 4 - t; /* x = [0 - 0xF] */ + r += t; /* r = [0, 4, 8, 12, 16, 20, 24, 28] */ + /* return r + clz(x) */ + t = ((x & 0xC) == 0) << 1; + x >>= 2 - t; /* x = [0 - 3] */ + r += t; /* r = [0 - 30] and is even */ + /* return r + clz(x) */ +/* switch (x) + * { + * case 0: + * return r + 2; + * case 1: + * return r + 1; + * case 2: + * case 3: + * return r; + * } + */ + return r + ((2 - x) & -((x & 2) == 0)); +} diff --git a/third_party/compiler_rt/clzti2.c b/third_party/compiler_rt/clzti2.c new file mode 100644 index 00000000..4894b43d --- /dev/null +++ b/third_party/compiler_rt/clzti2.c @@ -0,0 +1,36 @@ +/* clang-format off */ +/* ===-- clzti2.c - Implement __clzti2 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __clzti2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: the number of leading 0-bits */ + +/* Precondition: a != 0 */ + +COMPILER_RT_ABI si_int +__clzti2(ti_int a) +{ + twords x; + x.all = a; + const di_int f = -(x.s.high == 0); + return __builtin_clzll((x.s.high & ~f) | (x.s.low & f)) + + ((si_int)f & ((si_int)(sizeof(di_int) * CHAR_BIT))); +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/cmpdi2.c b/third_party/compiler_rt/cmpdi2.c new file mode 100644 index 00000000..5aabf4fe --- /dev/null +++ b/third_party/compiler_rt/cmpdi2.c @@ -0,0 +1,54 @@ +/* clang-format off */ +/* ===-- cmpdi2.c - Implement __cmpdi2 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __cmpdi2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: if (a < b) returns 0 +* if (a == b) returns 1 +* if (a > b) returns 2 +*/ + +COMPILER_RT_ABI si_int +__cmpdi2(di_int a, di_int b) +{ + dwords x; + x.all = a; + dwords y; + y.all = b; + if (x.s.high < y.s.high) + return 0; + if (x.s.high > y.s.high) + return 2; + if (x.s.low < y.s.low) + return 0; + if (x.s.low > y.s.low) + return 2; + return 1; +} + +#ifdef __ARM_EABI__ +/* Returns: if (a < b) returns -1 +* if (a == b) returns 0 +* if (a > b) returns 1 +*/ +COMPILER_RT_ABI si_int +__aeabi_lcmp(di_int a, di_int b) +{ + return __cmpdi2(a, b) - 1; +} +#endif + diff --git a/third_party/compiler_rt/cmpti2.c b/third_party/compiler_rt/cmpti2.c new file mode 100644 index 00000000..0e4d86c6 --- /dev/null +++ b/third_party/compiler_rt/cmpti2.c @@ -0,0 +1,45 @@ +/* clang-format off */ +/* ===-- cmpti2.c - Implement __cmpti2 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __cmpti2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: if (a < b) returns 0 + * if (a == b) returns 1 + * if (a > b) returns 2 + */ + +COMPILER_RT_ABI si_int +__cmpti2(ti_int a, ti_int b) +{ + twords x; + x.all = a; + twords y; + y.all = b; + if (x.s.high < y.s.high) + return 0; + if (x.s.high > y.s.high) + return 2; + if (x.s.low < y.s.low) + return 0; + if (x.s.low > y.s.low) + return 2; + return 1; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/comparedf2.c b/third_party/compiler_rt/comparedf2.c new file mode 100644 index 00000000..6912f490 --- /dev/null +++ b/third_party/compiler_rt/comparedf2.c @@ -0,0 +1,156 @@ +/* clang-format off */ +//===-- lib/comparedf2.c - Double-precision comparisons -----------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// // This file implements the following soft-float comparison routines: +// +// __eqdf2 __gedf2 __unorddf2 +// __ledf2 __gtdf2 +// __ltdf2 +// __nedf2 +// +// The semantics of the routines grouped in each column are identical, so there +// is a single implementation for each, and wrappers to provide the other names. +// +// The main routines behave as follows: +// +// __ledf2(a,b) returns -1 if a < b +// 0 if a == b +// 1 if a > b +// 1 if either a or b is NaN +// +// __gedf2(a,b) returns -1 if a < b +// 0 if a == b +// 1 if a > b +// -1 if either a or b is NaN +// +// __unorddf2(a,b) returns 0 if both a and b are numbers +// 1 if either a or b is NaN +// +// Note that __ledf2( ) and __gedf2( ) are identical except in their handling of +// NaN values. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define DOUBLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +enum LE_RESULT { + LE_LESS = -1, + LE_EQUAL = 0, + LE_GREATER = 1, + LE_UNORDERED = 1 +}; + +COMPILER_RT_ABI enum LE_RESULT +__ledf2(fp_t a, fp_t b) { + + const srep_t aInt = toRep(a); + const srep_t bInt = toRep(b); + const rep_t aAbs = aInt & absMask; + const rep_t bAbs = bInt & absMask; + + // If either a or b is NaN, they are unordered. + if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED; + + // If a and b are both zeros, they are equal. + if ((aAbs | bAbs) == 0) return LE_EQUAL; + + // If at least one of a and b is positive, we get the same result comparing + // a and b as signed integers as we would with a floating-point compare. + if ((aInt & bInt) >= 0) { + if (aInt < bInt) return LE_LESS; + else if (aInt == bInt) return LE_EQUAL; + else return LE_GREATER; + } + + // Otherwise, both are negative, so we need to flip the sense of the + // comparison to get the correct result. (This assumes a twos- or ones- + // complement integer representation; if integers are represented in a + // sign-magnitude representation, then this flip is incorrect). + else { + if (aInt > bInt) return LE_LESS; + else if (aInt == bInt) return LE_EQUAL; + else return LE_GREATER; + } +} + +#if defined(__ELF__) +// Alias for libgcc compatibility +FNALIAS(__cmpdf2, __ledf2); +#endif + +enum GE_RESULT { + GE_LESS = -1, + GE_EQUAL = 0, + GE_GREATER = 1, + GE_UNORDERED = -1 // Note: different from LE_UNORDERED +}; + +COMPILER_RT_ABI enum GE_RESULT +__gedf2(fp_t a, fp_t b) { + + const srep_t aInt = toRep(a); + const srep_t bInt = toRep(b); + const rep_t aAbs = aInt & absMask; + const rep_t bAbs = bInt & absMask; + + if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED; + if ((aAbs | bAbs) == 0) return GE_EQUAL; + if ((aInt & bInt) >= 0) { + if (aInt < bInt) return GE_LESS; + else if (aInt == bInt) return GE_EQUAL; + else return GE_GREATER; + } else { + if (aInt > bInt) return GE_LESS; + else if (aInt == bInt) return GE_EQUAL; + else return GE_GREATER; + } +} + +COMPILER_RT_ABI int +__unorddf2(fp_t a, fp_t b) { + const rep_t aAbs = toRep(a) & absMask; + const rep_t bAbs = toRep(b) & absMask; + return aAbs > infRep || bAbs > infRep; +} + +// The following are alternative names for the preceding routines. + +COMPILER_RT_ABI enum LE_RESULT +__eqdf2(fp_t a, fp_t b) { + return __ledf2(a, b); +} + +COMPILER_RT_ABI enum LE_RESULT +__ltdf2(fp_t a, fp_t b) { + return __ledf2(a, b); +} + +COMPILER_RT_ABI enum LE_RESULT +__nedf2(fp_t a, fp_t b) { + return __ledf2(a, b); +} + +COMPILER_RT_ABI enum GE_RESULT +__gtdf2(fp_t a, fp_t b) { + return __gedf2(a, b); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI int __aeabi_dcmpun(fp_t a, fp_t b) { + return __unorddf2(a, b); +} +#else +AEABI_RTABI int __aeabi_dcmpun(fp_t a, fp_t b) COMPILER_RT_ALIAS(__unorddf2); +#endif +#endif diff --git a/third_party/compiler_rt/comparesf2.c b/third_party/compiler_rt/comparesf2.c new file mode 100644 index 00000000..bf1ad804 --- /dev/null +++ b/third_party/compiler_rt/comparesf2.c @@ -0,0 +1,156 @@ +/* clang-format off */ +//===-- lib/comparesf2.c - Single-precision comparisons -----------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the following soft-fp_t comparison routines: +// +// __eqsf2 __gesf2 __unordsf2 +// __lesf2 __gtsf2 +// __ltsf2 +// __nesf2 +// +// The semantics of the routines grouped in each column are identical, so there +// is a single implementation for each, and wrappers to provide the other names. +// +// The main routines behave as follows: +// +// __lesf2(a,b) returns -1 if a < b +// 0 if a == b +// 1 if a > b +// 1 if either a or b is NaN +// +// __gesf2(a,b) returns -1 if a < b +// 0 if a == b +// 1 if a > b +// -1 if either a or b is NaN +// +// __unordsf2(a,b) returns 0 if both a and b are numbers +// 1 if either a or b is NaN +// +// Note that __lesf2( ) and __gesf2( ) are identical except in their handling of +// NaN values. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SINGLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +enum LE_RESULT { + LE_LESS = -1, + LE_EQUAL = 0, + LE_GREATER = 1, + LE_UNORDERED = 1 +}; + +COMPILER_RT_ABI enum LE_RESULT +__lesf2(fp_t a, fp_t b) { + + const srep_t aInt = toRep(a); + const srep_t bInt = toRep(b); + const rep_t aAbs = aInt & absMask; + const rep_t bAbs = bInt & absMask; + + // If either a or b is NaN, they are unordered. + if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED; + + // If a and b are both zeros, they are equal. + if ((aAbs | bAbs) == 0) return LE_EQUAL; + + // If at least one of a and b is positive, we get the same result comparing + // a and b as signed integers as we would with a fp_ting-point compare. + if ((aInt & bInt) >= 0) { + if (aInt < bInt) return LE_LESS; + else if (aInt == bInt) return LE_EQUAL; + else return LE_GREATER; + } + + // Otherwise, both are negative, so we need to flip the sense of the + // comparison to get the correct result. (This assumes a twos- or ones- + // complement integer representation; if integers are represented in a + // sign-magnitude representation, then this flip is incorrect). + else { + if (aInt > bInt) return LE_LESS; + else if (aInt == bInt) return LE_EQUAL; + else return LE_GREATER; + } +} + +#if defined(__ELF__) +// Alias for libgcc compatibility +FNALIAS(__cmpsf2, __lesf2); +#endif + +enum GE_RESULT { + GE_LESS = -1, + GE_EQUAL = 0, + GE_GREATER = 1, + GE_UNORDERED = -1 // Note: different from LE_UNORDERED +}; + +COMPILER_RT_ABI enum GE_RESULT +__gesf2(fp_t a, fp_t b) { + + const srep_t aInt = toRep(a); + const srep_t bInt = toRep(b); + const rep_t aAbs = aInt & absMask; + const rep_t bAbs = bInt & absMask; + + if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED; + if ((aAbs | bAbs) == 0) return GE_EQUAL; + if ((aInt & bInt) >= 0) { + if (aInt < bInt) return GE_LESS; + else if (aInt == bInt) return GE_EQUAL; + else return GE_GREATER; + } else { + if (aInt > bInt) return GE_LESS; + else if (aInt == bInt) return GE_EQUAL; + else return GE_GREATER; + } +} + +COMPILER_RT_ABI int +__unordsf2(fp_t a, fp_t b) { + const rep_t aAbs = toRep(a) & absMask; + const rep_t bAbs = toRep(b) & absMask; + return aAbs > infRep || bAbs > infRep; +} + +// The following are alternative names for the preceding routines. + +COMPILER_RT_ABI enum LE_RESULT +__eqsf2(fp_t a, fp_t b) { + return __lesf2(a, b); +} + +COMPILER_RT_ABI enum LE_RESULT +__ltsf2(fp_t a, fp_t b) { + return __lesf2(a, b); +} + +COMPILER_RT_ABI enum LE_RESULT +__nesf2(fp_t a, fp_t b) { + return __lesf2(a, b); +} + +COMPILER_RT_ABI enum GE_RESULT +__gtsf2(fp_t a, fp_t b) { + return __gesf2(a, b); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI int __aeabi_fcmpun(fp_t a, fp_t b) { + return __unordsf2(a, b); +} +#else +AEABI_RTABI int __aeabi_fcmpun(fp_t a, fp_t b) COMPILER_RT_ALIAS(__unordsf2); +#endif +#endif diff --git a/third_party/compiler_rt/comparetf2.c b/third_party/compiler_rt/comparetf2.c new file mode 100644 index 00000000..9fe48521 --- /dev/null +++ b/third_party/compiler_rt/comparetf2.c @@ -0,0 +1,141 @@ +/* clang-format off */ +//===-- lib/comparetf2.c - Quad-precision comparisons -------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// // This file implements the following soft-float comparison routines: +// +// __eqtf2 __getf2 __unordtf2 +// __letf2 __gttf2 +// __lttf2 +// __netf2 +// +// The semantics of the routines grouped in each column are identical, so there +// is a single implementation for each, and wrappers to provide the other names. +// +// The main routines behave as follows: +// +// __letf2(a,b) returns -1 if a < b +// 0 if a == b +// 1 if a > b +// 1 if either a or b is NaN +// +// __getf2(a,b) returns -1 if a < b +// 0 if a == b +// 1 if a > b +// -1 if either a or b is NaN +// +// __unordtf2(a,b) returns 0 if both a and b are numbers +// 1 if either a or b is NaN +// +// Note that __letf2( ) and __getf2( ) are identical except in their handling of +// NaN values. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +enum LE_RESULT { + LE_LESS = -1, + LE_EQUAL = 0, + LE_GREATER = 1, + LE_UNORDERED = 1 +}; + +COMPILER_RT_ABI enum LE_RESULT __letf2(fp_t a, fp_t b) { + + const srep_t aInt = toRep(a); + const srep_t bInt = toRep(b); + const rep_t aAbs = aInt & absMask; + const rep_t bAbs = bInt & absMask; + + // If either a or b is NaN, they are unordered. + if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED; + + // If a and b are both zeros, they are equal. + if ((aAbs | bAbs) == 0) return LE_EQUAL; + + // If at least one of a and b is positive, we get the same result comparing + // a and b as signed integers as we would with a floating-point compare. + if ((aInt & bInt) >= 0) { + if (aInt < bInt) return LE_LESS; + else if (aInt == bInt) return LE_EQUAL; + else return LE_GREATER; + } + else { + // Otherwise, both are negative, so we need to flip the sense of the + // comparison to get the correct result. (This assumes a twos- or ones- + // complement integer representation; if integers are represented in a + // sign-magnitude representation, then this flip is incorrect). + if (aInt > bInt) return LE_LESS; + else if (aInt == bInt) return LE_EQUAL; + else return LE_GREATER; + } +} + +#if defined(__ELF__) +// Alias for libgcc compatibility +FNALIAS(__cmptf2, __letf2); +#endif + +enum GE_RESULT { + GE_LESS = -1, + GE_EQUAL = 0, + GE_GREATER = 1, + GE_UNORDERED = -1 // Note: different from LE_UNORDERED +}; + +COMPILER_RT_ABI enum GE_RESULT __getf2(fp_t a, fp_t b) { + + const srep_t aInt = toRep(a); + const srep_t bInt = toRep(b); + const rep_t aAbs = aInt & absMask; + const rep_t bAbs = bInt & absMask; + + if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED; + if ((aAbs | bAbs) == 0) return GE_EQUAL; + if ((aInt & bInt) >= 0) { + if (aInt < bInt) return GE_LESS; + else if (aInt == bInt) return GE_EQUAL; + else return GE_GREATER; + } else { + if (aInt > bInt) return GE_LESS; + else if (aInt == bInt) return GE_EQUAL; + else return GE_GREATER; + } +} + +COMPILER_RT_ABI int __unordtf2(fp_t a, fp_t b) { + const rep_t aAbs = toRep(a) & absMask; + const rep_t bAbs = toRep(b) & absMask; + return aAbs > infRep || bAbs > infRep; +} + +// The following are alternative names for the preceding routines. + +COMPILER_RT_ABI enum LE_RESULT __eqtf2(fp_t a, fp_t b) { + return __letf2(a, b); +} + +COMPILER_RT_ABI enum LE_RESULT __lttf2(fp_t a, fp_t b) { + return __letf2(a, b); +} + +COMPILER_RT_ABI enum LE_RESULT __netf2(fp_t a, fp_t b) { + return __letf2(a, b); +} + +COMPILER_RT_ABI enum GE_RESULT __gttf2(fp_t a, fp_t b) { + return __getf2(a, b); +} + +#endif diff --git a/third_party/compiler_rt/compiler_rt.mk b/third_party/compiler_rt/compiler_rt.mk new file mode 100644 index 00000000..9b8a9089 --- /dev/null +++ b/third_party/compiler_rt/compiler_rt.mk @@ -0,0 +1,60 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += THIRD_PARTY_COMPILER_RT + +THIRD_PARTY_COMPILER_RT_ARTIFACTS += THIRD_PARTY_COMPILER_RT_A +THIRD_PARTY_COMPILER_RT = $(THIRD_PARTY_COMPILER_RT_A_DEPS) $(THIRD_PARTY_COMPILER_RT_A) +THIRD_PARTY_COMPILER_RT_A = o/$(MODE)/third_party/compiler_rt/compiler_rt.a +THIRD_PARTY_COMPILER_RT_A_FILES := \ + $(wildcard third_party/compiler_rt/*) \ + $(wildcard third_party/compiler_rt/nexgen32e/*) +THIRD_PARTY_COMPILER_RT_A_HDRS = $(filter %.h,$(THIRD_PARTY_COMPILER_RT_A_FILES)) +THIRD_PARTY_COMPILER_RT_A_SRCS_S = $(filter %.S,$(THIRD_PARTY_COMPILER_RT_A_FILES)) +THIRD_PARTY_COMPILER_RT_A_SRCS_C = $(filter %.c,$(THIRD_PARTY_COMPILER_RT_A_FILES)) + +THIRD_PARTY_COMPILER_RT_A_SRCS = \ + $(THIRD_PARTY_COMPILER_RT_A_SRCS_S) \ + $(THIRD_PARTY_COMPILER_RT_A_SRCS_C) + +THIRD_PARTY_COMPILER_RT_A_OBJS = \ + $(THIRD_PARTY_COMPILER_RT_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(THIRD_PARTY_COMPILER_RT_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(THIRD_PARTY_COMPILER_RT_A_SRCS_C:%.c=o/$(MODE)/%.o) + +THIRD_PARTY_COMPILER_RT_A_CHECKS = \ + $(THIRD_PARTY_COMPILER_RT_A).pkg \ + $(THIRD_PARTY_COMPILER_RT_A_HDRS:%=o/$(MODE)/%.ok) + +THIRD_PARTY_COMPILER_RT_A_DIRECTDEPS = \ + LIBC_MATH \ + LIBC_STUBS + +THIRD_PARTY_COMPILER_RT_A_DEPS := \ + $(call uniq,$(foreach x,$(THIRD_PARTY_COMPILER_RT_A_DIRECTDEPS),$($(x)))) + +$(THIRD_PARTY_COMPILER_RT_A): \ + third_party/compiler_rt/ \ + $(THIRD_PARTY_COMPILER_RT_A).pkg \ + $(THIRD_PARTY_COMPILER_RT_A_OBJS) + +$(THIRD_PARTY_COMPILER_RT_A).pkg: \ + $(THIRD_PARTY_COMPILER_RT_A_OBJS) \ + $(foreach x,$(THIRD_PARTY_COMPILER_RT_A_DIRECTDEPS),$($(x)_A).pkg) + +$(THIRD_PARTY_COMPILER_RT_A_OBJS): \ + DEFAULT_COPTS += \ + -DCRT_HAS_128BIT + +o/$(MODE)/third_party/compiler_rt/multc3.o \ +o/$(MODE)/third_party/compiler_rt/divtc3.o: \ + DEFAULT_COPTS += \ + -w + +THIRD_PARTY_COMPILER_RT_LIBS = $(foreach x,$(THIRD_PARTY_COMPILER_RT_ARTIFACTS),$($(x))) +THIRD_PARTY_COMPILER_RT_SRCS = $(foreach x,$(THIRD_PARTY_COMPILER_RT_ARTIFACTS),$($(x)_SRCS)) +THIRD_PARTY_COMPILER_RT_CHECKS = $(foreach x,$(THIRD_PARTY_COMPILER_RT_ARTIFACTS),$($(x)_CHECKS)) +THIRD_PARTY_COMPILER_RT_OBJS = $(foreach x,$(THIRD_PARTY_COMPILER_RT_ARTIFACTS),$($(x)_OBJS)) + +.PHONY: o/$(MODE)/third_party/compiler_rt +o/$(MODE)/third_party/compiler_rt: $(THIRD_PARTY_COMPILER_RT_CHECKS) diff --git a/third_party/compiler_rt/comprt.S b/third_party/compiler_rt/comprt.S new file mode 100644 index 00000000..077838b5 --- /dev/null +++ b/third_party/compiler_rt/comprt.S @@ -0,0 +1,50 @@ +#include "libc/macros.h" + +/ Nop ref this to force pull the license into linkage. + .section .yoink +huge_compiler_rt_license: + int3 + .endobj huge_compiler_rt_license,globl,hidden + .previous + +.ident "\n +compiler_rt (Licensed MIT) +Copyright (c) 2009-2015 by the contributors listed in: +github.com/llvm-mirror/compiler-rt/blob/master/CREDITS.TXT" + +.ident "\n +compiler_rt (Licensed \"University of Illinois/NCSA Open Source License\") +Copyright (c) 2009-2018 by the contributors listed in: +github.com/llvm-mirror/compiler-rt/blob/master/CREDITS.TXT +All rights reserved. + +Developed by: + + LLVM Team + University of Illinois at Urbana-Champaign + http://llvm.org + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the \"Software\"), to deal with +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + +THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE +SOFTWARE." diff --git a/third_party/compiler_rt/ctzdi2.c b/third_party/compiler_rt/ctzdi2.c new file mode 100644 index 00000000..6fae2400 --- /dev/null +++ b/third_party/compiler_rt/ctzdi2.c @@ -0,0 +1,43 @@ +/* clang-format off */ +/* ===-- ctzdi2.c - Implement __ctzdi2 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __ctzdi2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: the number of trailing 0-bits */ + +#if !defined(__clang__) && \ + ((defined(__sparc__) && defined(__arch64__)) || \ + defined(__mips64) || \ + (defined(__riscv) && __SIZEOF_POINTER__ >= 8)) +/* On 64-bit architectures with neither a native clz instruction nor a native + * ctz instruction, gcc resolves __builtin_ctz to __ctzdi2 rather than + * __ctzsi2, leading to infinite recursion. */ +#define __builtin_ctz(a) __ctzsi2(a) +extern si_int __ctzsi2(si_int); +#endif + +/* Precondition: a != 0 */ + +COMPILER_RT_ABI si_int +__ctzdi2(di_int a) +{ + dwords x; + x.all = a; + const si_int f = -(x.s.low == 0); + return __builtin_ctz((x.s.high & f) | (x.s.low & ~f)) + + (f & ((si_int)(sizeof(si_int) * CHAR_BIT))); +} diff --git a/third_party/compiler_rt/ctzsi2.c b/third_party/compiler_rt/ctzsi2.c new file mode 100644 index 00000000..42f57be5 --- /dev/null +++ b/third_party/compiler_rt/ctzsi2.c @@ -0,0 +1,60 @@ +/* clang-format off */ +/* ===-- ctzsi2.c - Implement __ctzsi2 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __ctzsi2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: the number of trailing 0-bits */ + +/* Precondition: a != 0 */ + +COMPILER_RT_ABI si_int +__ctzsi2(si_int a) +{ + su_int x = (su_int)a; + si_int t = ((x & 0x0000FFFF) == 0) << 4; /* if (x has no small bits) t = 16 else 0 */ + x >>= t; /* x = [0 - 0xFFFF] + higher garbage bits */ + su_int r = t; /* r = [0, 16] */ + /* return r + ctz(x) */ + t = ((x & 0x00FF) == 0) << 3; + x >>= t; /* x = [0 - 0xFF] + higher garbage bits */ + r += t; /* r = [0, 8, 16, 24] */ + /* return r + ctz(x) */ + t = ((x & 0x0F) == 0) << 2; + x >>= t; /* x = [0 - 0xF] + higher garbage bits */ + r += t; /* r = [0, 4, 8, 12, 16, 20, 24, 28] */ + /* return r + ctz(x) */ + t = ((x & 0x3) == 0) << 1; + x >>= t; + x &= 3; /* x = [0 - 3] */ + r += t; /* r = [0 - 30] and is even */ + /* return r + ctz(x) */ + +/* The branch-less return statement below is equivalent + * to the following switch statement: + * switch (x) + * { + * case 0: + * return r + 2; + * case 2: + * return r + 1; + * case 1: + * case 3: + * return r; + * } + */ + return r + ((2 - (x >> 1)) & -((x & 1) == 0)); +} diff --git a/third_party/compiler_rt/ctzti2.c b/third_party/compiler_rt/ctzti2.c new file mode 100644 index 00000000..981b1089 --- /dev/null +++ b/third_party/compiler_rt/ctzti2.c @@ -0,0 +1,36 @@ +/* clang-format off */ +/* ===-- ctzti2.c - Implement __ctzti2 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __ctzti2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: the number of trailing 0-bits */ + +/* Precondition: a != 0 */ + +COMPILER_RT_ABI si_int +__ctzti2(ti_int a) +{ + twords x; + x.all = a; + const di_int f = -(x.s.low == 0); + return __builtin_ctzll((x.s.high & f) | (x.s.low & ~f)) + + ((si_int)f & ((si_int)(sizeof(di_int) * CHAR_BIT))); +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/divdc3.c b/third_party/compiler_rt/divdc3.c new file mode 100644 index 00000000..ac2320c0 --- /dev/null +++ b/third_party/compiler_rt/divdc3.c @@ -0,0 +1,58 @@ +/* clang-format off */ +/* ===-- divdc3.c - Implement __divdc3 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __divdc3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define DOUBLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" +#include "third_party/compiler_rt/int_lib.h" +#include "third_party/compiler_rt/int_math.h" + +/* Returns: the quotient of (a + ib) / (c + id) */ + +COMPILER_RT_ABI Dcomplex __divdc3(double __a, double __b, double __c, + double __d) { + int __ilogbw = 0; + double __logbw = __compiler_rt_logb(crt_fmax(crt_fabs(__c), crt_fabs(__d))); + if (crt_isfinite(__logbw)) { + __ilogbw = (int)__logbw; + __c = crt_scalbn(__c, -__ilogbw); + __d = crt_scalbn(__d, -__ilogbw); + } + double __denom = __c * __c + __d * __d; + Dcomplex z; + COMPLEX_REAL(z) = crt_scalbn((__a * __c + __b * __d) / __denom, -__ilogbw); + COMPLEX_IMAGINARY(z) = + crt_scalbn((__b * __c - __a * __d) / __denom, -__ilogbw); + if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z))) { + if ((__denom == 0.0) && (!crt_isnan(__a) || !crt_isnan(__b))) { + COMPLEX_REAL(z) = crt_copysign(CRT_INFINITY, __c) * __a; + COMPLEX_IMAGINARY(z) = crt_copysign(CRT_INFINITY, __c) * __b; + } else if ((crt_isinf(__a) || crt_isinf(__b)) && crt_isfinite(__c) && + crt_isfinite(__d)) { + __a = crt_copysign(crt_isinf(__a) ? 1.0 : 0.0, __a); + __b = crt_copysign(crt_isinf(__b) ? 1.0 : 0.0, __b); + COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d); + COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d); + } else if (crt_isinf(__logbw) && __logbw > 0.0 && crt_isfinite(__a) && + crt_isfinite(__b)) { + __c = crt_copysign(crt_isinf(__c) ? 1.0 : 0.0, __c); + __d = crt_copysign(crt_isinf(__d) ? 1.0 : 0.0, __d); + COMPLEX_REAL(z) = 0.0 * (__a * __c + __b * __d); + COMPLEX_IMAGINARY(z) = 0.0 * (__b * __c - __a * __d); + } + } + return z; +} diff --git a/third_party/compiler_rt/divdf3.c b/third_party/compiler_rt/divdf3.c new file mode 100644 index 00000000..42078c61 --- /dev/null +++ b/third_party/compiler_rt/divdf3.c @@ -0,0 +1,197 @@ +/* clang-format off */ +//===-- lib/divdf3.c - Double-precision division ------------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements double-precision soft-float division +// with the IEEE-754 default rounding (to nearest, ties to even). +// +// For simplicity, this implementation currently flushes denormals to zero. +// It should be a fairly straightforward exercise to implement gradual +// underflow with correct rounding. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define DOUBLE_PRECISION +#include "libc/literal.h" +#include "third_party/compiler_rt/fp_lib.inc" + +COMPILER_RT_ABI fp_t +__divdf3(fp_t a, fp_t b) { + + const unsigned int aExponent = toRep(a) >> significandBits & maxExponent; + const unsigned int bExponent = toRep(b) >> significandBits & maxExponent; + const rep_t quotientSign = (toRep(a) ^ toRep(b)) & signBit; + + rep_t aSignificand = toRep(a) & significandMask; + rep_t bSignificand = toRep(b) & significandMask; + int scale = 0; + + // Detect if a or b is zero, denormal, infinity, or NaN. + if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) { + + const rep_t aAbs = toRep(a) & absMask; + const rep_t bAbs = toRep(b) & absMask; + + // NaN / anything = qNaN + if (aAbs > infRep) return fromRep(toRep(a) | quietBit); + // anything / NaN = qNaN + if (bAbs > infRep) return fromRep(toRep(b) | quietBit); + + if (aAbs == infRep) { + // infinity / infinity = NaN + if (bAbs == infRep) return fromRep(qnanRep); + // infinity / anything else = +/- infinity + else return fromRep(aAbs | quotientSign); + } + + // anything else / infinity = +/- 0 + if (bAbs == infRep) return fromRep(quotientSign); + + if (!aAbs) { + // zero / zero = NaN + if (!bAbs) return fromRep(qnanRep); + // zero / anything else = +/- zero + else return fromRep(quotientSign); + } + // anything else / zero = +/- infinity + if (!bAbs) return fromRep(infRep | quotientSign); + + // one or both of a or b is denormal, the other (if applicable) is a + // normal number. Renormalize one or both of a and b, and set scale to + // include the necessary exponent adjustment. + if (aAbs < implicitBit) scale += normalize(&aSignificand); + if (bAbs < implicitBit) scale -= normalize(&bSignificand); + } + + // Or in the implicit significand bit. (If we fell through from the + // denormal path it was already set by normalize( ), but setting it twice + // won't hurt anything.) + aSignificand |= implicitBit; + bSignificand |= implicitBit; + int quotientExponent = aExponent - bExponent + scale; + + // Align the significand of b as a Q31 fixed-point number in the range + // [1, 2.0) and get a Q32 approximate reciprocal using a small minimax + // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This + // is accurate to about 3.5 binary digits. + const uint32_t q31b = bSignificand >> 21; + uint32_t recip32 = UINT32_C(0x7504f333) - q31b; + + // Now refine the reciprocal estimate using a Newton-Raphson iteration: + // + // x1 = x0 * (2 - x0 * b) + // + // This doubles the number of correct binary digits in the approximation + // with each iteration, so after three iterations, we have about 28 binary + // digits of accuracy. + uint32_t correction32; + correction32 = -((uint64_t)recip32 * q31b >> 32); + recip32 = (uint64_t)recip32 * correction32 >> 31; + correction32 = -((uint64_t)recip32 * q31b >> 32); + recip32 = (uint64_t)recip32 * correction32 >> 31; + correction32 = -((uint64_t)recip32 * q31b >> 32); + recip32 = (uint64_t)recip32 * correction32 >> 31; + + // recip32 might have overflowed to exactly zero in the preceding + // computation if the high word of b is exactly 1.0. This would sabotage + // the full-width final stage of the computation that follows, so we adjust + // recip32 downward by one bit. + recip32--; + + // We need to perform one more iteration to get us to 56 binary digits; + // The last iteration needs to happen with extra precision. + const uint32_t q63blo = bSignificand << 11; + uint64_t correction, reciprocal; + correction = -((uint64_t)recip32*q31b + ((uint64_t)recip32*q63blo >> 32)); + uint32_t cHi = correction >> 32; + uint32_t cLo = correction; + reciprocal = (uint64_t)recip32*cHi + ((uint64_t)recip32*cLo >> 32); + + // We already adjusted the 32-bit estimate, now we need to adjust the final + // 64-bit reciprocal estimate downward to ensure that it is strictly smaller + // than the infinitely precise exact reciprocal. Because the computation + // of the Newton-Raphson step is truncating at every step, this adjustment + // is small; most of the work is already done. + reciprocal -= 2; + + // The numerical reciprocal is accurate to within 2^-56, lies in the + // interval [0.5, 1.0), and is strictly smaller than the true reciprocal + // of b. Multiplying a by this reciprocal thus gives a numerical q = a/b + // in Q53 with the following properties: + // + // 1. q < a/b + // 2. q is in the interval [0.5, 2.0) + // 3. the error in q is bounded away from 2^-53 (actually, we have a + // couple of bits to spare, but this is all we need). + + // We need a 64 x 64 multiply high to compute q, which isn't a basic + // operation in C, so we need to be a little bit fussy. + rep_t quotient, quotientLo; + wideMultiply(aSignificand << 2, reciprocal, "ient, "ientLo); + + // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0). + // In either case, we are going to compute a residual of the form + // + // r = a - q*b + // + // We know from the construction of q that r satisfies: + // + // 0 <= r < ulp(q)*b + // + // if r is greater than 1/2 ulp(q)*b, then q rounds up. Otherwise, we + // already have the correct result. The exact halfway case cannot occur. + // We also take this time to right shift quotient if it falls in the [1,2) + // range and adjust the exponent accordingly. + rep_t residual; + if (quotient < (implicitBit << 1)) { + residual = (aSignificand << 53) - quotient * bSignificand; + quotientExponent--; + } else { + quotient >>= 1; + residual = (aSignificand << 52) - quotient * bSignificand; + } + + const int writtenExponent = quotientExponent + exponentBias; + + if (writtenExponent >= maxExponent) { + // If we have overflowed the exponent, return infinity. + return fromRep(infRep | quotientSign); + } + + else if (writtenExponent < 1) { + // Flush denormals to zero. In the future, it would be nice to add + // code to round them correctly. + return fromRep(quotientSign); + } + + else { + const bool round = (residual << 1) > bSignificand; + // Clear the implicit bit + rep_t absResult = quotient & significandMask; + // Insert the exponent + absResult |= (rep_t)writtenExponent << significandBits; + // Round + absResult += round; + // Insert the sign and return + const double result = fromRep(absResult | quotientSign); + return result; + } +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI fp_t __aeabi_ddiv(fp_t a, fp_t b) { + return __divdf3(a, b); +} +#else +AEABI_RTABI fp_t __aeabi_ddiv(fp_t a, fp_t b) COMPILER_RT_ALIAS(__divdf3); +#endif +#endif diff --git a/third_party/compiler_rt/divdi3.c b/third_party/compiler_rt/divdi3.c new file mode 100644 index 00000000..1c8b2cf2 --- /dev/null +++ b/third_party/compiler_rt/divdi3.c @@ -0,0 +1,32 @@ +/* clang-format off */ +/* ===-- divdi3.c - Implement __divdi3 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __divdi3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a / b */ + +COMPILER_RT_ABI di_int +__divdi3(di_int a, di_int b) +{ + const int bits_in_dword_m1 = (int)(sizeof(di_int) * CHAR_BIT) - 1; + di_int s_a = a >> bits_in_dword_m1; /* s_a = a < 0 ? -1 : 0 */ + di_int s_b = b >> bits_in_dword_m1; /* s_b = b < 0 ? -1 : 0 */ + a = (a ^ s_a) - s_a; /* negate if s_a == -1 */ + b = (b ^ s_b) - s_b; /* negate if s_b == -1 */ + s_a ^= s_b; /*sign of quotient */ + return (__udivmoddi4(a, b, (du_int*)0) ^ s_a) - s_a; /* negate if s_a == -1 */ +} diff --git a/third_party/compiler_rt/divmoddi4.c b/third_party/compiler_rt/divmoddi4.c new file mode 100644 index 00000000..0080c639 --- /dev/null +++ b/third_party/compiler_rt/divmoddi4.c @@ -0,0 +1,28 @@ +/* clang-format off */ +/*===-- divmoddi4.c - Implement __divmoddi4 --------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __divmoddi4 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a / b, *rem = a % b */ + +COMPILER_RT_ABI di_int +__divmoddi4(di_int a, di_int b, di_int* rem) +{ + di_int d = __divdi3(a,b); + *rem = a - (d*b); + return d; +} diff --git a/third_party/compiler_rt/divmodsi4.c b/third_party/compiler_rt/divmodsi4.c new file mode 100644 index 00000000..20ed8359 --- /dev/null +++ b/third_party/compiler_rt/divmodsi4.c @@ -0,0 +1,30 @@ +/* clang-format off */ +/*===-- divmodsi4.c - Implement __divmodsi4 --------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __divmodsi4 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a / b, *rem = a % b */ + +COMPILER_RT_ABI si_int +__divmodsi4(si_int a, si_int b, si_int* rem) +{ + si_int d = __divsi3(a,b); + *rem = a - (d*b); + return d; +} + + diff --git a/third_party/compiler_rt/divsc3.c b/third_party/compiler_rt/divsc3.c new file mode 100644 index 00000000..d651b948 --- /dev/null +++ b/third_party/compiler_rt/divsc3.c @@ -0,0 +1,66 @@ +/* clang-format off */ +/*===-- divsc3.c - Implement __divsc3 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __divsc3 for the compiler_rt library. + * + *===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SINGLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" +#include "third_party/compiler_rt/int_lib.h" +#include "third_party/compiler_rt/int_math.h" + +/* Returns: the quotient of (a + ib) / (c + id) */ + +COMPILER_RT_ABI Fcomplex +__divsc3(float __a, float __b, float __c, float __d) +{ + int __ilogbw = 0; + float __logbw = + __compiler_rt_logbf(crt_fmaxf(crt_fabsf(__c), crt_fabsf(__d))); + if (crt_isfinite(__logbw)) + { + __ilogbw = (int)__logbw; + __c = crt_scalbnf(__c, -__ilogbw); + __d = crt_scalbnf(__d, -__ilogbw); + } + float __denom = __c * __c + __d * __d; + Fcomplex z; + COMPLEX_REAL(z) = crt_scalbnf((__a * __c + __b * __d) / __denom, -__ilogbw); + COMPLEX_IMAGINARY(z) = crt_scalbnf((__b * __c - __a * __d) / __denom, -__ilogbw); + if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z))) + { + if ((__denom == 0) && (!crt_isnan(__a) || !crt_isnan(__b))) + { + COMPLEX_REAL(z) = crt_copysignf(CRT_INFINITY, __c) * __a; + COMPLEX_IMAGINARY(z) = crt_copysignf(CRT_INFINITY, __c) * __b; + } + else if ((crt_isinf(__a) || crt_isinf(__b)) && + crt_isfinite(__c) && crt_isfinite(__d)) + { + __a = crt_copysignf(crt_isinf(__a) ? 1 : 0, __a); + __b = crt_copysignf(crt_isinf(__b) ? 1 : 0, __b); + COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d); + COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d); + } + else if (crt_isinf(__logbw) && __logbw > 0 && + crt_isfinite(__a) && crt_isfinite(__b)) + { + __c = crt_copysignf(crt_isinf(__c) ? 1 : 0, __c); + __d = crt_copysignf(crt_isinf(__d) ? 1 : 0, __d); + COMPLEX_REAL(z) = 0 * (__a * __c + __b * __d); + COMPLEX_IMAGINARY(z) = 0 * (__b * __c - __a * __d); + } + } + return z; +} diff --git a/third_party/compiler_rt/divsf3.c b/third_party/compiler_rt/divsf3.c new file mode 100644 index 00000000..d93e977a --- /dev/null +++ b/third_party/compiler_rt/divsf3.c @@ -0,0 +1,181 @@ +/* clang-format off */ +//===-- lib/divsf3.c - Single-precision division ------------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements single-precision soft-float division +// with the IEEE-754 default rounding (to nearest, ties to even). +// +// For simplicity, this implementation currently flushes denormals to zero. +// It should be a fairly straightforward exercise to implement gradual +// underflow with correct rounding. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SINGLE_PRECISION +#include "libc/literal.h" +#include "third_party/compiler_rt/fp_lib.inc" + +COMPILER_RT_ABI fp_t +__divsf3(fp_t a, fp_t b) { + + const unsigned int aExponent = toRep(a) >> significandBits & maxExponent; + const unsigned int bExponent = toRep(b) >> significandBits & maxExponent; + const rep_t quotientSign = (toRep(a) ^ toRep(b)) & signBit; + + rep_t aSignificand = toRep(a) & significandMask; + rep_t bSignificand = toRep(b) & significandMask; + int scale = 0; + + // Detect if a or b is zero, denormal, infinity, or NaN. + if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) { + + const rep_t aAbs = toRep(a) & absMask; + const rep_t bAbs = toRep(b) & absMask; + + // NaN / anything = qNaN + if (aAbs > infRep) return fromRep(toRep(a) | quietBit); + // anything / NaN = qNaN + if (bAbs > infRep) return fromRep(toRep(b) | quietBit); + + if (aAbs == infRep) { + // infinity / infinity = NaN + if (bAbs == infRep) return fromRep(qnanRep); + // infinity / anything else = +/- infinity + else return fromRep(aAbs | quotientSign); + } + + // anything else / infinity = +/- 0 + if (bAbs == infRep) return fromRep(quotientSign); + + if (!aAbs) { + // zero / zero = NaN + if (!bAbs) return fromRep(qnanRep); + // zero / anything else = +/- zero + else return fromRep(quotientSign); + } + // anything else / zero = +/- infinity + if (!bAbs) return fromRep(infRep | quotientSign); + + // one or both of a or b is denormal, the other (if applicable) is a + // normal number. Renormalize one or both of a and b, and set scale to + // include the necessary exponent adjustment. + if (aAbs < implicitBit) scale += normalize(&aSignificand); + if (bAbs < implicitBit) scale -= normalize(&bSignificand); + } + + // Or in the implicit significand bit. (If we fell through from the + // denormal path it was already set by normalize( ), but setting it twice + // won't hurt anything.) + aSignificand |= implicitBit; + bSignificand |= implicitBit; + int quotientExponent = aExponent - bExponent + scale; + + // Align the significand of b as a Q31 fixed-point number in the range + // [1, 2.0) and get a Q32 approximate reciprocal using a small minimax + // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This + // is accurate to about 3.5 binary digits. + uint32_t q31b = bSignificand << 8; + uint32_t reciprocal = UINT32_C(0x7504f333) - q31b; + + // Now refine the reciprocal estimate using a Newton-Raphson iteration: + // + // x1 = x0 * (2 - x0 * b) + // + // This doubles the number of correct binary digits in the approximation + // with each iteration, so after three iterations, we have about 28 binary + // digits of accuracy. + uint32_t correction; + correction = -((uint64_t)reciprocal * q31b >> 32); + reciprocal = (uint64_t)reciprocal * correction >> 31; + correction = -((uint64_t)reciprocal * q31b >> 32); + reciprocal = (uint64_t)reciprocal * correction >> 31; + correction = -((uint64_t)reciprocal * q31b >> 32); + reciprocal = (uint64_t)reciprocal * correction >> 31; + + // Exhaustive testing shows that the error in reciprocal after three steps + // is in the interval [-0x1.f58108p-31, 0x1.d0e48cp-29], in line with our + // expectations. We bump the reciprocal by a tiny value to force the error + // to be strictly positive (in the range [0x1.4fdfp-37,0x1.287246p-29], to + // be specific). This also causes 1/1 to give a sensible approximation + // instead of zero (due to overflow). + reciprocal -= 2; + + // The numerical reciprocal is accurate to within 2^-28, lies in the + // interval [0x1.000000eep-1, 0x1.fffffffcp-1], and is strictly smaller + // than the true reciprocal of b. Multiplying a by this reciprocal thus + // gives a numerical q = a/b in Q24 with the following properties: + // + // 1. q < a/b + // 2. q is in the interval [0x1.000000eep-1, 0x1.fffffffcp0) + // 3. the error in q is at most 2^-24 + 2^-27 -- the 2^24 term comes + // from the fact that we truncate the product, and the 2^27 term + // is the error in the reciprocal of b scaled by the maximum + // possible value of a. As a consequence of this error bound, + // either q or nextafter(q) is the correctly rounded + rep_t quotient = (uint64_t)reciprocal*(aSignificand << 1) >> 32; + + // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0). + // In either case, we are going to compute a residual of the form + // + // r = a - q*b + // + // We know from the construction of q that r satisfies: + // + // 0 <= r < ulp(q)*b + // + // if r is greater than 1/2 ulp(q)*b, then q rounds up. Otherwise, we + // already have the correct result. The exact halfway case cannot occur. + // We also take this time to right shift quotient if it falls in the [1,2) + // range and adjust the exponent accordingly. + rep_t residual; + if (quotient < (implicitBit << 1)) { + residual = (aSignificand << 24) - quotient * bSignificand; + quotientExponent--; + } else { + quotient >>= 1; + residual = (aSignificand << 23) - quotient * bSignificand; + } + + const int writtenExponent = quotientExponent + exponentBias; + + if (writtenExponent >= maxExponent) { + // If we have overflowed the exponent, return infinity. + return fromRep(infRep | quotientSign); + } + + else if (writtenExponent < 1) { + // Flush denormals to zero. In the future, it would be nice to add + // code to round them correctly. + return fromRep(quotientSign); + } + + else { + const bool round = (residual << 1) > bSignificand; + // Clear the implicit bit + rep_t absResult = quotient & significandMask; + // Insert the exponent + absResult |= (rep_t)writtenExponent << significandBits; + // Round + absResult += round; + // Insert the sign and return + return fromRep(absResult | quotientSign); + } +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI fp_t __aeabi_fdiv(fp_t a, fp_t b) { + return __divsf3(a, b); +} +#else +AEABI_RTABI fp_t __aeabi_fdiv(fp_t a, fp_t b) COMPILER_RT_ALIAS(__divsf3); +#endif +#endif diff --git a/third_party/compiler_rt/divsi3.c b/third_party/compiler_rt/divsi3.c new file mode 100644 index 00000000..0737b05b --- /dev/null +++ b/third_party/compiler_rt/divsi3.c @@ -0,0 +1,42 @@ +/* clang-format off */ +/* ===-- divsi3.c - Implement __divsi3 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __divsi3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a / b */ + +COMPILER_RT_ABI si_int +__divsi3(si_int a, si_int b) +{ + const int bits_in_word_m1 = (int)(sizeof(si_int) * CHAR_BIT) - 1; + si_int s_a = a >> bits_in_word_m1; /* s_a = a < 0 ? -1 : 0 */ + si_int s_b = b >> bits_in_word_m1; /* s_b = b < 0 ? -1 : 0 */ + a = (a ^ s_a) - s_a; /* negate if s_a == -1 */ + b = (b ^ s_b) - s_b; /* negate if s_b == -1 */ + s_a ^= s_b; /* sign of quotient */ + /* + * On CPUs without unsigned hardware division support, + * this calls __udivsi3 (notice the cast to su_int). + * On CPUs with unsigned hardware division support, + * this uses the unsigned division instruction. + */ + return ((su_int)a/(su_int)b ^ s_a) - s_a; /* negate if s_a == -1 */ +} + +#if defined(__ARM_EABI__) +AEABI_RTABI si_int __aeabi_idiv(si_int a, si_int b) COMPILER_RT_ALIAS(__divsi3); +#endif diff --git a/third_party/compiler_rt/divtc3.c b/third_party/compiler_rt/divtc3.c new file mode 100644 index 00000000..262bffda --- /dev/null +++ b/third_party/compiler_rt/divtc3.c @@ -0,0 +1,66 @@ +/* clang-format off */ +/*===-- divtc3.c - Implement __divtc3 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __divtc3 for the compiler_rt library. + * + *===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" +#include "third_party/compiler_rt/int_lib.h" +#include "third_party/compiler_rt/int_math.h" + +/* Returns: the quotient of (a + ib) / (c + id) */ + +COMPILER_RT_ABI Lcomplex +__divtc3(long double __a, long double __b, long double __c, long double __d) +{ + int __ilogbw = 0; + long double __logbw = + __compiler_rt_logbl(crt_fmaxl(crt_fabsl(__c), crt_fabsl(__d))); + if (crt_isfinite(__logbw)) + { + __ilogbw = (int)__logbw; + __c = crt_scalbnl(__c, -__ilogbw); + __d = crt_scalbnl(__d, -__ilogbw); + } + long double __denom = __c * __c + __d * __d; + Lcomplex z; + COMPLEX_REAL(z) = crt_scalbnl((__a * __c + __b * __d) / __denom, -__ilogbw); + COMPLEX_IMAGINARY(z) = crt_scalbnl((__b * __c - __a * __d) / __denom, -__ilogbw); + if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z))) + { + if ((__denom == 0.0) && (!crt_isnan(__a) || !crt_isnan(__b))) + { + COMPLEX_REAL(z) = crt_copysignl(CRT_INFINITY, __c) * __a; + COMPLEX_IMAGINARY(z) = crt_copysignl(CRT_INFINITY, __c) * __b; + } + else if ((crt_isinf(__a) || crt_isinf(__b)) && + crt_isfinite(__c) && crt_isfinite(__d)) + { + __a = crt_copysignl(crt_isinf(__a) ? 1.0 : 0.0, __a); + __b = crt_copysignl(crt_isinf(__b) ? 1.0 : 0.0, __b); + COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d); + COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d); + } + else if (crt_isinf(__logbw) && __logbw > 0.0 && + crt_isfinite(__a) && crt_isfinite(__b)) + { + __c = crt_copysignl(crt_isinf(__c) ? 1.0 : 0.0, __c); + __d = crt_copysignl(crt_isinf(__d) ? 1.0 : 0.0, __d); + COMPLEX_REAL(z) = 0.0 * (__a * __c + __b * __d); + COMPLEX_IMAGINARY(z) = 0.0 * (__b * __c - __a * __d); + } + } + return z; +} diff --git a/third_party/compiler_rt/divtf3.c b/third_party/compiler_rt/divtf3.c new file mode 100644 index 00000000..3d5f2625 --- /dev/null +++ b/third_party/compiler_rt/divtf3.c @@ -0,0 +1,207 @@ +/* clang-format off */ +//===-- lib/divtf3.c - Quad-precision division --------------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements quad-precision soft-float division +// with the IEEE-754 default rounding (to nearest, ties to even). +// +// For simplicity, this implementation currently flushes denormals to zero. +// It should be a fairly straightforward exercise to implement gradual +// underflow with correct rounding. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "libc/literal.h" +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +COMPILER_RT_ABI fp_t __divtf3(fp_t a, fp_t b) { + + const unsigned int aExponent = toRep(a) >> significandBits & maxExponent; + const unsigned int bExponent = toRep(b) >> significandBits & maxExponent; + const rep_t quotientSign = (toRep(a) ^ toRep(b)) & signBit; + + rep_t aSignificand = toRep(a) & significandMask; + rep_t bSignificand = toRep(b) & significandMask; + int scale = 0; + + // Detect if a or b is zero, denormal, infinity, or NaN. + if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) { + + const rep_t aAbs = toRep(a) & absMask; + const rep_t bAbs = toRep(b) & absMask; + + // NaN / anything = qNaN + if (aAbs > infRep) return fromRep(toRep(a) | quietBit); + // anything / NaN = qNaN + if (bAbs > infRep) return fromRep(toRep(b) | quietBit); + + if (aAbs == infRep) { + // infinity / infinity = NaN + if (bAbs == infRep) return fromRep(qnanRep); + // infinity / anything else = +/- infinity + else return fromRep(aAbs | quotientSign); + } + + // anything else / infinity = +/- 0 + if (bAbs == infRep) return fromRep(quotientSign); + + if (!aAbs) { + // zero / zero = NaN + if (!bAbs) return fromRep(qnanRep); + // zero / anything else = +/- zero + else return fromRep(quotientSign); + } + // anything else / zero = +/- infinity + if (!bAbs) return fromRep(infRep | quotientSign); + + // one or both of a or b is denormal, the other (if applicable) is a + // normal number. Renormalize one or both of a and b, and set scale to + // include the necessary exponent adjustment. + if (aAbs < implicitBit) scale += normalize(&aSignificand); + if (bAbs < implicitBit) scale -= normalize(&bSignificand); + } + + // Or in the implicit significand bit. (If we fell through from the + // denormal path it was already set by normalize( ), but setting it twice + // won't hurt anything.) + aSignificand |= implicitBit; + bSignificand |= implicitBit; + int quotientExponent = aExponent - bExponent + scale; + + // Align the significand of b as a Q63 fixed-point number in the range + // [1, 2.0) and get a Q64 approximate reciprocal using a small minimax + // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This + // is accurate to about 3.5 binary digits. + const uint64_t q63b = bSignificand >> 49; + uint64_t recip64 = UINT64_C(0x7504f333F9DE6484) - q63b; + // 0x7504f333F9DE6484 / 2^64 + 1 = 3/4 + 1/sqrt(2) + + // Now refine the reciprocal estimate using a Newton-Raphson iteration: + // + // x1 = x0 * (2 - x0 * b) + // + // This doubles the number of correct binary digits in the approximation + // with each iteration. + uint64_t correction64; + correction64 = -((rep_t)recip64 * q63b >> 64); + recip64 = (rep_t)recip64 * correction64 >> 63; + correction64 = -((rep_t)recip64 * q63b >> 64); + recip64 = (rep_t)recip64 * correction64 >> 63; + correction64 = -((rep_t)recip64 * q63b >> 64); + recip64 = (rep_t)recip64 * correction64 >> 63; + correction64 = -((rep_t)recip64 * q63b >> 64); + recip64 = (rep_t)recip64 * correction64 >> 63; + correction64 = -((rep_t)recip64 * q63b >> 64); + recip64 = (rep_t)recip64 * correction64 >> 63; + + // recip64 might have overflowed to exactly zero in the preceeding + // computation if the high word of b is exactly 1.0. This would sabotage + // the full-width final stage of the computation that follows, so we adjust + // recip64 downward by one bit. + recip64--; + + // We need to perform one more iteration to get us to 112 binary digits; + // The last iteration needs to happen with extra precision. + const uint64_t q127blo = bSignificand << 15; + rep_t correction, reciprocal; + + // NOTE: This operation is equivalent to __multi3, which is not implemented + // in some architechure + rep_t r64q63, r64q127, r64cH, r64cL, dummy; + wideMultiply((rep_t)recip64, (rep_t)q63b, &dummy, &r64q63); + wideMultiply((rep_t)recip64, (rep_t)q127blo, &dummy, &r64q127); + + correction = -(r64q63 + (r64q127 >> 64)); + + uint64_t cHi = correction >> 64; + uint64_t cLo = correction; + + wideMultiply((rep_t)recip64, (rep_t)cHi, &dummy, &r64cH); + wideMultiply((rep_t)recip64, (rep_t)cLo, &dummy, &r64cL); + + reciprocal = r64cH + (r64cL >> 64); + + // We already adjusted the 64-bit estimate, now we need to adjust the final + // 128-bit reciprocal estimate downward to ensure that it is strictly smaller + // than the infinitely precise exact reciprocal. Because the computation + // of the Newton-Raphson step is truncating at every step, this adjustment + // is small; most of the work is already done. + reciprocal -= 2; + + // The numerical reciprocal is accurate to within 2^-112, lies in the + // interval [0.5, 1.0), and is strictly smaller than the true reciprocal + // of b. Multiplying a by this reciprocal thus gives a numerical q = a/b + // in Q127 with the following properties: + // + // 1. q < a/b + // 2. q is in the interval [0.5, 2.0) + // 3. the error in q is bounded away from 2^-113 (actually, we have a + // couple of bits to spare, but this is all we need). + + // We need a 128 x 128 multiply high to compute q, which isn't a basic + // operation in C, so we need to be a little bit fussy. + rep_t quotient, quotientLo; + wideMultiply(aSignificand << 2, reciprocal, "ient, "ientLo); + + // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0). + // In either case, we are going to compute a residual of the form + // + // r = a - q*b + // + // We know from the construction of q that r satisfies: + // + // 0 <= r < ulp(q)*b + // + // if r is greater than 1/2 ulp(q)*b, then q rounds up. Otherwise, we + // already have the correct result. The exact halfway case cannot occur. + // We also take this time to right shift quotient if it falls in the [1,2) + // range and adjust the exponent accordingly. + rep_t residual; + rep_t qb; + + if (quotient < (implicitBit << 1)) { + wideMultiply(quotient, bSignificand, &dummy, &qb); + residual = (aSignificand << 113) - qb; + quotientExponent--; + } else { + quotient >>= 1; + wideMultiply(quotient, bSignificand, &dummy, &qb); + residual = (aSignificand << 112) - qb; + } + + const int writtenExponent = quotientExponent + exponentBias; + + if (writtenExponent >= maxExponent) { + // If we have overflowed the exponent, return infinity. + return fromRep(infRep | quotientSign); + } + else if (writtenExponent < 1) { + // Flush denormals to zero. In the future, it would be nice to add + // code to round them correctly. + return fromRep(quotientSign); + } + else { + const bool round = (residual << 1) >= bSignificand; + // Clear the implicit bit + rep_t absResult = quotient & significandMask; + // Insert the exponent + absResult |= (rep_t)writtenExponent << significandBits; + // Round + absResult += round; + // Insert the sign and return + const long double result = fromRep(absResult | quotientSign); + return result; + } +} + +#endif diff --git a/third_party/compiler_rt/divti3.c b/third_party/compiler_rt/divti3.c new file mode 100644 index 00000000..48bbe58a --- /dev/null +++ b/third_party/compiler_rt/divti3.c @@ -0,0 +1,36 @@ +/* clang-format off */ +/* ===-- divti3.c - Implement __divti3 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __divti3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: a / b */ + +COMPILER_RT_ABI ti_int +__divti3(ti_int a, ti_int b) +{ + const int bits_in_tword_m1 = (int)(sizeof(ti_int) * CHAR_BIT) - 1; + ti_int s_a = a >> bits_in_tword_m1; /* s_a = a < 0 ? -1 : 0 */ + ti_int s_b = b >> bits_in_tword_m1; /* s_b = b < 0 ? -1 : 0 */ + a = (a ^ s_a) - s_a; /* negate if s_a == -1 */ + b = (b ^ s_b) - s_b; /* negate if s_b == -1 */ + s_a ^= s_b; /* sign of quotient */ + return (__udivmodti4(a, b, (tu_int*)0) ^ s_a) - s_a; /* negate if s_a == -1 */ +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/divxc3.c b/third_party/compiler_rt/divxc3.c new file mode 100644 index 00000000..aa77db02 --- /dev/null +++ b/third_party/compiler_rt/divxc3.c @@ -0,0 +1,66 @@ +/* clang-format off */ +/* ===-- divxc3.c - Implement __divxc3 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __divxc3 for the compiler_rt library. + * + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#if !_ARCH_PPC + +#include "third_party/compiler_rt/int_lib.h" +#include "third_party/compiler_rt/int_math.h" + +/* Returns: the quotient of (a + ib) / (c + id) */ + +COMPILER_RT_ABI Lcomplex +__divxc3(long double __a, long double __b, long double __c, long double __d) +{ + int __ilogbw = 0; + long double __logbw = crt_logbl(crt_fmaxl(crt_fabsl(__c), crt_fabsl(__d))); + if (crt_isfinite(__logbw)) + { + __ilogbw = (int)__logbw; + __c = crt_scalbnl(__c, -__ilogbw); + __d = crt_scalbnl(__d, -__ilogbw); + } + long double __denom = __c * __c + __d * __d; + Lcomplex z; + COMPLEX_REAL(z) = crt_scalbnl((__a * __c + __b * __d) / __denom, -__ilogbw); + COMPLEX_IMAGINARY(z) = crt_scalbnl((__b * __c - __a * __d) / __denom, -__ilogbw); + if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z))) + { + if ((__denom == 0) && (!crt_isnan(__a) || !crt_isnan(__b))) + { + COMPLEX_REAL(z) = crt_copysignl(CRT_INFINITY, __c) * __a; + COMPLEX_IMAGINARY(z) = crt_copysignl(CRT_INFINITY, __c) * __b; + } + else if ((crt_isinf(__a) || crt_isinf(__b)) && + crt_isfinite(__c) && crt_isfinite(__d)) + { + __a = crt_copysignl(crt_isinf(__a) ? 1 : 0, __a); + __b = crt_copysignl(crt_isinf(__b) ? 1 : 0, __b); + COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c + __b * __d); + COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__b * __c - __a * __d); + } + else if (crt_isinf(__logbw) && __logbw > 0 && + crt_isfinite(__a) && crt_isfinite(__b)) + { + __c = crt_copysignl(crt_isinf(__c) ? 1 : 0, __c); + __d = crt_copysignl(crt_isinf(__d) ? 1 : 0, __d); + COMPLEX_REAL(z) = 0 * (__a * __c + __b * __d); + COMPLEX_IMAGINARY(z) = 0 * (__b * __c - __a * __d); + } + } + return z; +} + +#endif diff --git a/third_party/compiler_rt/extenddftf2.c b/third_party/compiler_rt/extenddftf2.c new file mode 100644 index 00000000..f4ad3ed9 --- /dev/null +++ b/third_party/compiler_rt/extenddftf2.c @@ -0,0 +1,26 @@ +/* clang-format off */ +//===-- lib/extenddftf2.c - double -> quad conversion -------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +#define SRC_DOUBLE +#define DST_QUAD +#include "third_party/compiler_rt/fp_extend_impl.inc" + +COMPILER_RT_ABI long double __extenddftf2(double a) { + return __extendXfYf2__(a); +} + +#endif diff --git a/third_party/compiler_rt/extendhfsf2.c b/third_party/compiler_rt/extendhfsf2.c new file mode 100644 index 00000000..8d5361dc --- /dev/null +++ b/third_party/compiler_rt/extendhfsf2.c @@ -0,0 +1,36 @@ +/* clang-format off */ +//===-- lib/extendhfsf2.c - half -> single conversion -------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SRC_HALF +#define DST_SINGLE +#include "third_party/compiler_rt/fp_extend_impl.inc" + +// Use a forwarding definition and noinline to implement a poor man's alias, +// as there isn't a good cross-platform way of defining one. +COMPILER_RT_ABI __attribute__((__noinline__)) float __extendhfsf2(uint16_t a) { + return __extendXfYf2__(a); +} + +COMPILER_RT_ABI float __gnu_h2f_ieee(uint16_t a) { + return __extendhfsf2(a); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI float __aeabi_h2f(uint16_t a) { + return __extendhfsf2(a); +} +#else +AEABI_RTABI float __aeabi_h2f(uint16_t a) COMPILER_RT_ALIAS(__extendhfsf2); +#endif +#endif diff --git a/third_party/compiler_rt/extendsfdf2.c b/third_party/compiler_rt/extendsfdf2.c new file mode 100644 index 00000000..528b162f --- /dev/null +++ b/third_party/compiler_rt/extendsfdf2.c @@ -0,0 +1,30 @@ +/* clang-format off */ +//===-- lib/extendsfdf2.c - single -> double conversion -----------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SRC_SINGLE +#define DST_DOUBLE +#include "third_party/compiler_rt/fp_extend_impl.inc" + +COMPILER_RT_ABI double __extendsfdf2(float a) { + return __extendXfYf2__(a); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI double __aeabi_f2d(float a) { + return __extendsfdf2(a); +} +#else +AEABI_RTABI double __aeabi_f2d(float a) COMPILER_RT_ALIAS(__extendsfdf2); +#endif +#endif diff --git a/third_party/compiler_rt/extendsftf2.c b/third_party/compiler_rt/extendsftf2.c new file mode 100644 index 00000000..6997ba73 --- /dev/null +++ b/third_party/compiler_rt/extendsftf2.c @@ -0,0 +1,26 @@ +/* clang-format off */ +//===-- lib/extendsftf2.c - single -> quad conversion -------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +#define SRC_SINGLE +#define DST_QUAD +#include "third_party/compiler_rt/fp_extend_impl.inc" + +COMPILER_RT_ABI long double __extendsftf2(float a) { + return __extendXfYf2__(a); +} + +#endif diff --git a/third_party/compiler_rt/ffsdi2.c b/third_party/compiler_rt/ffsdi2.c new file mode 100644 index 00000000..69852050 --- /dev/null +++ b/third_party/compiler_rt/ffsdi2.c @@ -0,0 +1,36 @@ +/* clang-format off */ +/* ===-- ffsdi2.c - Implement __ffsdi2 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __ffsdi2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: the index of the least significant 1-bit in a, or + * the value zero if a is zero. The least significant bit is index one. + */ + +COMPILER_RT_ABI si_int +__ffsdi2(di_int a) +{ + dwords x; + x.all = a; + if (x.s.low == 0) + { + if (x.s.high == 0) + return 0; + return __builtin_ctz(x.s.high) + (1 + sizeof(si_int) * CHAR_BIT); + } + return __builtin_ctz(x.s.low) + 1; +} diff --git a/third_party/compiler_rt/ffssi2.c b/third_party/compiler_rt/ffssi2.c new file mode 100644 index 00000000..e5140c49 --- /dev/null +++ b/third_party/compiler_rt/ffssi2.c @@ -0,0 +1,32 @@ +/* clang-format off */ +/* ===-- ffssi2.c - Implement __ffssi2 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __ffssi2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: the index of the least significant 1-bit in a, or + * the value zero if a is zero. The least significant bit is index one. + */ + +COMPILER_RT_ABI si_int +__ffssi2(si_int a) +{ + if (a == 0) + { + return 0; + } + return __builtin_ctz(a) + 1; +} diff --git a/third_party/compiler_rt/ffsti2.c b/third_party/compiler_rt/ffsti2.c new file mode 100644 index 00000000..a004168b --- /dev/null +++ b/third_party/compiler_rt/ffsti2.c @@ -0,0 +1,40 @@ +/* clang-format off */ +/* ===-- ffsti2.c - Implement __ffsti2 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __ffsti2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: the index of the least significant 1-bit in a, or + * the value zero if a is zero. The least significant bit is index one. + */ + +COMPILER_RT_ABI si_int +__ffsti2(ti_int a) +{ + twords x; + x.all = a; + if (x.s.low == 0) + { + if (x.s.high == 0) + return 0; + return __builtin_ctzll(x.s.high) + (1 + sizeof(di_int) * CHAR_BIT); + } + return __builtin_ctzll(x.s.low) + 1; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/fixdfdi.c b/third_party/compiler_rt/fixdfdi.c new file mode 100644 index 00000000..5af27de3 --- /dev/null +++ b/third_party/compiler_rt/fixdfdi.c @@ -0,0 +1,58 @@ +/* clang-format off */ +/* ===-- fixdfdi.c - Implement __fixdfdi -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define DOUBLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#ifndef __SOFT_FP__ +/* Support for systems that have hardware floating-point; can set the invalid + * flag as a side-effect of computation. + */ + +COMPILER_RT_ABI du_int __fixunsdfdi(double a); + +COMPILER_RT_ABI di_int +__fixdfdi(double a) +{ + if (a < 0.0) { + return -__fixunsdfdi(-a); + } + return __fixunsdfdi(a); +} + +#else +/* Support for systems that don't have hardware floating-point; there are no + * flags to set, and we don't want to code-gen to an unknown soft-float + * implementation. + */ + +typedef di_int fixint_t; +typedef du_int fixuint_t; +#include "third_party/compiler_rt/fp_fixint_impl.inc" + +COMPILER_RT_ABI di_int +__fixdfdi(fp_t a) { + return __fixint(a); +} + +#endif + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI di_int __aeabi_d2lz(fp_t a) { + return __fixdfdi(a); +} +#else +AEABI_RTABI di_int __aeabi_d2lz(fp_t a) COMPILER_RT_ALIAS(__fixdfdi); +#endif +#endif diff --git a/third_party/compiler_rt/fixdfsi.c b/third_party/compiler_rt/fixdfsi.c new file mode 100644 index 00000000..6d8b176c --- /dev/null +++ b/third_party/compiler_rt/fixdfsi.c @@ -0,0 +1,33 @@ +/* clang-format off */ +/* ===-- fixdfsi.c - Implement __fixdfsi -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define DOUBLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" +typedef si_int fixint_t; +typedef su_int fixuint_t; +#include "third_party/compiler_rt/fp_fixint_impl.inc" + +COMPILER_RT_ABI si_int +__fixdfsi(fp_t a) { + return __fixint(a); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI si_int __aeabi_d2iz(fp_t a) { + return __fixdfsi(a); +} +#else +AEABI_RTABI si_int __aeabi_d2iz(fp_t a) COMPILER_RT_ALIAS(__fixdfsi); +#endif +#endif diff --git a/third_party/compiler_rt/fixdfti.c b/third_party/compiler_rt/fixdfti.c new file mode 100644 index 00000000..a3cd5013 --- /dev/null +++ b/third_party/compiler_rt/fixdfti.c @@ -0,0 +1,29 @@ +/* clang-format off */ +/* ===-- fixdfti.c - Implement __fixdfti -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT +#define DOUBLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +typedef ti_int fixint_t; +typedef tu_int fixuint_t; +#include "third_party/compiler_rt/fp_fixint_impl.inc" + +COMPILER_RT_ABI ti_int +__fixdfti(fp_t a) { + return __fixint(a); +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/fixsfdi.c b/third_party/compiler_rt/fixsfdi.c new file mode 100644 index 00000000..f774a5b7 --- /dev/null +++ b/third_party/compiler_rt/fixsfdi.c @@ -0,0 +1,58 @@ +/* clang-format off */ +/* ===-- fixsfdi.c - Implement __fixsfdi -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SINGLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#ifndef __SOFT_FP__ +/* Support for systems that have hardware floating-point; can set the invalid + * flag as a side-effect of computation. + */ + +COMPILER_RT_ABI du_int __fixunssfdi(float a); + +COMPILER_RT_ABI di_int +__fixsfdi(float a) +{ + if (a < 0.0f) { + return -__fixunssfdi(-a); + } + return __fixunssfdi(a); +} + +#else +/* Support for systems that don't have hardware floating-point; there are no + * flags to set, and we don't want to code-gen to an unknown soft-float + * implementation. + */ + +typedef di_int fixint_t; +typedef du_int fixuint_t; +#include "third_party/compiler_rt/fp_fixint_impl.inc" + +COMPILER_RT_ABI di_int +__fixsfdi(fp_t a) { + return __fixint(a); +} + +#endif + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI di_int __aeabi_f2lz(fp_t a) { + return __fixsfdi(a); +} +#else +AEABI_RTABI di_int __aeabi_f2lz(fp_t a) COMPILER_RT_ALIAS(__fixsfdi); +#endif +#endif diff --git a/third_party/compiler_rt/fixsfsi.c b/third_party/compiler_rt/fixsfsi.c new file mode 100644 index 00000000..9104d21d --- /dev/null +++ b/third_party/compiler_rt/fixsfsi.c @@ -0,0 +1,33 @@ +/* clang-format off */ +/* ===-- fixsfsi.c - Implement __fixsfsi -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SINGLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" +typedef si_int fixint_t; +typedef su_int fixuint_t; +#include "third_party/compiler_rt/fp_fixint_impl.inc" + +COMPILER_RT_ABI si_int +__fixsfsi(fp_t a) { + return __fixint(a); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI si_int __aeabi_f2iz(fp_t a) { + return __fixsfsi(a); +} +#else +AEABI_RTABI si_int __aeabi_f2iz(fp_t a) COMPILER_RT_ALIAS(__fixsfsi); +#endif +#endif diff --git a/third_party/compiler_rt/fixsfti.c b/third_party/compiler_rt/fixsfti.c new file mode 100644 index 00000000..3d080e9d --- /dev/null +++ b/third_party/compiler_rt/fixsfti.c @@ -0,0 +1,29 @@ +/* clang-format off */ +/* ===-- fixsfti.c - Implement __fixsfti -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT +#define SINGLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +typedef ti_int fixint_t; +typedef tu_int fixuint_t; +#include "third_party/compiler_rt/fp_fixint_impl.inc" + +COMPILER_RT_ABI ti_int +__fixsfti(fp_t a) { + return __fixint(a); +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/fixtfdi.c b/third_party/compiler_rt/fixtfdi.c new file mode 100644 index 00000000..d7c280a1 --- /dev/null +++ b/third_party/compiler_rt/fixtfdi.c @@ -0,0 +1,26 @@ +/* clang-format off */ +/* ===-- fixtfdi.c - Implement __fixtfdi -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +typedef di_int fixint_t; +typedef du_int fixuint_t; +#include "third_party/compiler_rt/fp_fixint_impl.inc" + +COMPILER_RT_ABI di_int +__fixtfdi(fp_t a) { + return __fixint(a); +} +#endif diff --git a/third_party/compiler_rt/fixtfsi.c b/third_party/compiler_rt/fixtfsi.c new file mode 100644 index 00000000..25341cf7 --- /dev/null +++ b/third_party/compiler_rt/fixtfsi.c @@ -0,0 +1,26 @@ +/* clang-format off */ +/* ===-- fixtfsi.c - Implement __fixtfsi -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +typedef si_int fixint_t; +typedef su_int fixuint_t; +#include "third_party/compiler_rt/fp_fixint_impl.inc" + +COMPILER_RT_ABI si_int +__fixtfsi(fp_t a) { + return __fixint(a); +} +#endif diff --git a/third_party/compiler_rt/fixtfti.c b/third_party/compiler_rt/fixtfti.c new file mode 100644 index 00000000..0d7c7d06 --- /dev/null +++ b/third_party/compiler_rt/fixtfti.c @@ -0,0 +1,26 @@ +/* clang-format off */ +/* ===-- fixtfti.c - Implement __fixtfti -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +typedef ti_int fixint_t; +typedef tu_int fixuint_t; +#include "third_party/compiler_rt/fp_fixint_impl.inc" + +COMPILER_RT_ABI ti_int +__fixtfti(fp_t a) { + return __fixint(a); +} +#endif diff --git a/third_party/compiler_rt/fixunsdfdi.c b/third_party/compiler_rt/fixunsdfdi.c new file mode 100644 index 00000000..72ad0e86 --- /dev/null +++ b/third_party/compiler_rt/fixunsdfdi.c @@ -0,0 +1,55 @@ +/* clang-format off */ +/* ===-- fixunsdfdi.c - Implement __fixunsdfdi -----------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define DOUBLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#ifndef __SOFT_FP__ +/* Support for systems that have hardware floating-point; can set the invalid + * flag as a side-effect of computation. + */ + +COMPILER_RT_ABI du_int +__fixunsdfdi(double a) +{ + if (a <= 0.0) return 0; + su_int high = a / 4294967296.f; /* a / 0x1p32f; */ + su_int low = a - (double)high * 4294967296.f; /* high * 0x1p32f; */ + return ((du_int)high << 32) | low; +} + +#else +/* Support for systems that don't have hardware floating-point; there are no + * flags to set, and we don't want to code-gen to an unknown soft-float + * implementation. + */ + +typedef du_int fixuint_t; +#include "third_party/compiler_rt/fp_fixuint_impl.inc" + +COMPILER_RT_ABI du_int +__fixunsdfdi(fp_t a) { + return __fixuint(a); +} + +#endif + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI du_int __aeabi_d2ulz(fp_t a) { + return __fixunsdfdi(a); +} +#else +AEABI_RTABI du_int __aeabi_d2ulz(fp_t a) COMPILER_RT_ALIAS(__fixunsdfdi); +#endif +#endif diff --git a/third_party/compiler_rt/fixunsdfsi.c b/third_party/compiler_rt/fixunsdfsi.c new file mode 100644 index 00000000..d36652d1 --- /dev/null +++ b/third_party/compiler_rt/fixunsdfsi.c @@ -0,0 +1,32 @@ +/* clang-format off */ +/* ===-- fixunsdfsi.c - Implement __fixunsdfsi -----------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define DOUBLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" +typedef su_int fixuint_t; +#include "third_party/compiler_rt/fp_fixuint_impl.inc" + +COMPILER_RT_ABI su_int +__fixunsdfsi(fp_t a) { + return __fixuint(a); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI su_int __aeabi_d2uiz(fp_t a) { + return __fixunsdfsi(a); +} +#else +AEABI_RTABI su_int __aeabi_d2uiz(fp_t a) COMPILER_RT_ALIAS(__fixunsdfsi); +#endif +#endif diff --git a/third_party/compiler_rt/fixunsdfti.c b/third_party/compiler_rt/fixunsdfti.c new file mode 100644 index 00000000..2451e1b8 --- /dev/null +++ b/third_party/compiler_rt/fixunsdfti.c @@ -0,0 +1,26 @@ +/* clang-format off */ +/* ===-- fixunsdfti.c - Implement __fixunsdfti -----------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT +#define DOUBLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" +typedef tu_int fixuint_t; +#include "third_party/compiler_rt/fp_fixuint_impl.inc" + +COMPILER_RT_ABI tu_int +__fixunsdfti(fp_t a) { + return __fixuint(a); +} +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/fixunssfdi.c b/third_party/compiler_rt/fixunssfdi.c new file mode 100644 index 00000000..bc7da50f --- /dev/null +++ b/third_party/compiler_rt/fixunssfdi.c @@ -0,0 +1,56 @@ +/* clang-format off */ +/* ===-- fixunssfdi.c - Implement __fixunssfdi -----------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SINGLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#ifndef __SOFT_FP__ +/* Support for systems that have hardware floating-point; can set the invalid + * flag as a side-effect of computation. + */ + +COMPILER_RT_ABI du_int +__fixunssfdi(float a) +{ + if (a <= 0.0f) return 0; + double da = a; + su_int high = da / 4294967296.f; /* da / 0x1p32f; */ + su_int low = da - (double)high * 4294967296.f; /* high * 0x1p32f; */ + return ((du_int)high << 32) | low; +} + +#else +/* Support for systems that don't have hardware floating-point; there are no + * flags to set, and we don't want to code-gen to an unknown soft-float + * implementation. + */ + +typedef du_int fixuint_t; +#include "third_party/compiler_rt/fp_fixuint_impl.inc" + +COMPILER_RT_ABI du_int +__fixunssfdi(fp_t a) { + return __fixuint(a); +} + +#endif + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI du_int __aeabi_f2ulz(fp_t a) { + return __fixunssfdi(a); +} +#else +AEABI_RTABI du_int __aeabi_f2ulz(fp_t a) COMPILER_RT_ALIAS(__fixunssfdi); +#endif +#endif diff --git a/third_party/compiler_rt/fixunssfsi.c b/third_party/compiler_rt/fixunssfsi.c new file mode 100644 index 00000000..cb532701 --- /dev/null +++ b/third_party/compiler_rt/fixunssfsi.c @@ -0,0 +1,36 @@ +/* clang-format off */ +/* ===-- fixunssfsi.c - Implement __fixunssfsi -----------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __fixunssfsi for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SINGLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" +typedef su_int fixuint_t; +#include "third_party/compiler_rt/fp_fixuint_impl.inc" + +COMPILER_RT_ABI su_int +__fixunssfsi(fp_t a) { + return __fixuint(a); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI su_int __aeabi_f2uiz(fp_t a) { + return __fixunssfsi(a); +} +#else +AEABI_RTABI su_int __aeabi_f2uiz(fp_t a) COMPILER_RT_ALIAS(__fixunssfsi); +#endif +#endif diff --git a/third_party/compiler_rt/fixunssfti.c b/third_party/compiler_rt/fixunssfti.c new file mode 100644 index 00000000..0a9e936c --- /dev/null +++ b/third_party/compiler_rt/fixunssfti.c @@ -0,0 +1,29 @@ +/* clang-format off */ +/* ===-- fixunssfti.c - Implement __fixunssfti -----------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __fixunssfti for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SINGLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) +typedef tu_int fixuint_t; +#include "third_party/compiler_rt/fp_fixuint_impl.inc" + +COMPILER_RT_ABI tu_int +__fixunssfti(fp_t a) { + return __fixuint(a); +} +#endif diff --git a/third_party/compiler_rt/fixunstfdi.c b/third_party/compiler_rt/fixunstfdi.c new file mode 100644 index 00000000..7b032b61 --- /dev/null +++ b/third_party/compiler_rt/fixunstfdi.c @@ -0,0 +1,25 @@ +/* clang-format off */ +/* ===-- fixunstfdi.c - Implement __fixunstfdi -----------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +typedef du_int fixuint_t; +#include "third_party/compiler_rt/fp_fixuint_impl.inc" + +COMPILER_RT_ABI du_int +__fixunstfdi(fp_t a) { + return __fixuint(a); +} +#endif diff --git a/third_party/compiler_rt/fixunstfsi.c b/third_party/compiler_rt/fixunstfsi.c new file mode 100644 index 00000000..3195c359 --- /dev/null +++ b/third_party/compiler_rt/fixunstfsi.c @@ -0,0 +1,25 @@ +/* clang-format off */ +/* ===-- fixunstfsi.c - Implement __fixunstfsi -----------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +typedef su_int fixuint_t; +#include "third_party/compiler_rt/fp_fixuint_impl.inc" + +COMPILER_RT_ABI su_int +__fixunstfsi(fp_t a) { + return __fixuint(a); +} +#endif diff --git a/third_party/compiler_rt/fixunstfti.c b/third_party/compiler_rt/fixunstfti.c new file mode 100644 index 00000000..474bfa56 --- /dev/null +++ b/third_party/compiler_rt/fixunstfti.c @@ -0,0 +1,25 @@ +/* clang-format off */ +/* ===-- fixunstfsi.c - Implement __fixunstfsi -----------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +typedef tu_int fixuint_t; +#include "third_party/compiler_rt/fp_fixuint_impl.inc" + +COMPILER_RT_ABI tu_int +__fixunstfti(fp_t a) { + return __fixuint(a); +} +#endif diff --git a/third_party/compiler_rt/fixunsxfdi.c b/third_party/compiler_rt/fixunsxfdi.c new file mode 100644 index 00000000..0049baa7 --- /dev/null +++ b/third_party/compiler_rt/fixunsxfdi.c @@ -0,0 +1,49 @@ +/* clang-format off */ +/* ===-- fixunsxfdi.c - Implement __fixunsxfdi -----------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __fixunsxfdi for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#if !_ARCH_PPC + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: convert a to a unsigned long long, rounding toward zero. + * Negative values all become zero. + */ + +/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes + * du_int is a 64 bit integral type + * value in long double is representable in du_int or is negative + * (no range checking performed) + */ + +/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | + * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm + */ + +COMPILER_RT_ABI du_int +__fixunsxfdi(long double a) +{ + long_double_bits fb; + fb.f = a; + int e = (fb.u.high.s.low & 0x00007FFF) - 16383; + if (e < 0 || (fb.u.high.s.low & 0x00008000)) + return 0; + if ((unsigned)e > sizeof(du_int) * CHAR_BIT) + return ~(du_int)0; + return fb.u.low.all >> (63 - e); +} + +#endif diff --git a/third_party/compiler_rt/fixunsxfsi.c b/third_party/compiler_rt/fixunsxfsi.c new file mode 100644 index 00000000..82b843a8 --- /dev/null +++ b/third_party/compiler_rt/fixunsxfsi.c @@ -0,0 +1,48 @@ +/* clang-format off */ +/* ===-- fixunsxfsi.c - Implement __fixunsxfsi -----------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __fixunsxfsi for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#if !_ARCH_PPC + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: convert a to a unsigned int, rounding toward zero. + * Negative values all become zero. + */ + +/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes + * su_int is a 32 bit integral type + * value in long double is representable in su_int or is negative + */ + +/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | + * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm + */ + +COMPILER_RT_ABI su_int +__fixunsxfsi(long double a) +{ + long_double_bits fb; + fb.f = a; + int e = (fb.u.high.s.low & 0x00007FFF) - 16383; + if (e < 0 || (fb.u.high.s.low & 0x00008000)) + return 0; + if ((unsigned)e > sizeof(su_int) * CHAR_BIT) + return ~(su_int)0; + return fb.u.low.s.high >> (31 - e); +} + +#endif /* !_ARCH_PPC */ diff --git a/third_party/compiler_rt/fixunsxfti.c b/third_party/compiler_rt/fixunsxfti.c new file mode 100644 index 00000000..f3b0d272 --- /dev/null +++ b/third_party/compiler_rt/fixunsxfti.c @@ -0,0 +1,53 @@ +/* clang-format off */ +/* ===-- fixunsxfti.c - Implement __fixunsxfti -----------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __fixunsxfti for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: convert a to a unsigned long long, rounding toward zero. + * Negative values all become zero. + */ + +/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes + * tu_int is a 128 bit integral type + * value in long double is representable in tu_int or is negative + */ + +/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | + * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm + */ + +COMPILER_RT_ABI tu_int +__fixunsxfti(long double a) +{ + long_double_bits fb; + fb.f = a; + int e = (fb.u.high.s.low & 0x00007FFF) - 16383; + if (e < 0 || (fb.u.high.s.low & 0x00008000)) + return 0; + if ((unsigned)e > sizeof(tu_int) * CHAR_BIT) + return ~(tu_int)0; + tu_int r = fb.u.low.all; + if (e > 63) + r <<= (e - 63); + else + r >>= (63 - e); + return r; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/fixxfdi.c b/third_party/compiler_rt/fixxfdi.c new file mode 100644 index 00000000..269aa0e9 --- /dev/null +++ b/third_party/compiler_rt/fixxfdi.c @@ -0,0 +1,51 @@ +/* clang-format off */ +/* ===-- fixxfdi.c - Implement __fixxfdi -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __fixxfdi for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#if !_ARCH_PPC + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: convert a to a signed long long, rounding toward zero. */ + +/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes + * di_int is a 64 bit integral type + * value in long double is representable in di_int (no range checking performed) + */ + +/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | + * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm + */ + +COMPILER_RT_ABI di_int +__fixxfdi(long double a) +{ + const di_int di_max = (di_int)((~(du_int)0) / 2); + const di_int di_min = -di_max - 1; + long_double_bits fb; + fb.f = a; + int e = (fb.u.high.s.low & 0x00007FFF) - 16383; + if (e < 0) + return 0; + if ((unsigned)e >= sizeof(di_int) * CHAR_BIT) + return a > 0 ? di_max : di_min; + di_int s = -(si_int)((fb.u.high.s.low & 0x00008000) >> 15); + di_int r = fb.u.low.all; + r = (du_int)r >> (63 - e); + return (r ^ s) - s; +} + +#endif /* !_ARCH_PPC */ diff --git a/third_party/compiler_rt/fixxfti.c b/third_party/compiler_rt/fixxfti.c new file mode 100644 index 00000000..e344acdc --- /dev/null +++ b/third_party/compiler_rt/fixxfti.c @@ -0,0 +1,54 @@ +/* clang-format off */ +/* ===-- fixxfti.c - Implement __fixxfti -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __fixxfti for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: convert a to a signed long long, rounding toward zero. */ + +/* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes + * ti_int is a 128 bit integral type + * value in long double is representable in ti_int + */ + +/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | + * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm + */ + +COMPILER_RT_ABI ti_int +__fixxfti(long double a) +{ + const ti_int ti_max = (ti_int)((~(tu_int)0) / 2); + const ti_int ti_min = -ti_max - 1; + long_double_bits fb; + fb.f = a; + int e = (fb.u.high.s.low & 0x00007FFF) - 16383; + if (e < 0) + return 0; + ti_int s = -(si_int)((fb.u.high.s.low & 0x00008000) >> 15); + ti_int r = fb.u.low.all; + if ((unsigned)e >= sizeof(ti_int) * CHAR_BIT) + return a > 0 ? ti_max : ti_min; + if (e > 63) + r <<= (e - 63); + else + r >>= (63 - e); + return (r ^ s) - s; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/floatdidf.c b/third_party/compiler_rt/floatdidf.c new file mode 100644 index 00000000..aed5781f --- /dev/null +++ b/third_party/compiler_rt/floatdidf.c @@ -0,0 +1,119 @@ +/* clang-format off */ +/*===-- floatdidf.c - Implement __floatdidf -------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + *===----------------------------------------------------------------------=== + * + * This file implements __floatdidf for the compiler_rt library. + * + *===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "libc/literal.h" +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: convert a to a double, rounding toward even. */ + +/* Assumption: double is a IEEE 64 bit floating point type + * di_int is a 64 bit integral type + */ + +/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ + +#ifndef __SOFT_FP__ +/* Support for systems that have hardware floating-point; we'll set the inexact flag + * as a side-effect of this computation. + */ + +COMPILER_RT_ABI double +__floatdidf(di_int a) +{ + static const double twop52 = 4503599627370496.0; // 0x1.0p52 + static const double twop32 = 4294967296.0; // 0x1.0p32 + + union { int64_t x; double d; } low = { .d = twop52 }; + + const double high = (int32_t)(a >> 32) * twop32; + low.x |= a & INT64_C(0x00000000ffffffff); + + const double result = (high - twop52) + low.d; + return result; +} + +#else +/* Support for systems that don't have hardware floating-point; there are no flags to + * set, and we don't want to code-gen to an unknown soft-float implementation. + */ + +COMPILER_RT_ABI double +__floatdidf(di_int a) +{ + if (a == 0) + return 0.0; + const unsigned N = sizeof(di_int) * CHAR_BIT; + const di_int s = a >> (N-1); + a = (a ^ s) - s; + int sd = N - __builtin_clzll(a); /* number of significant digits */ + int e = sd - 1; /* exponent */ + if (sd > DBL_MANT_DIG) + { + /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx + * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR + * 12345678901234567890123456 + * 1 = msb 1 bit + * P = bit DBL_MANT_DIG-1 bits to the right of 1 + * Q = bit DBL_MANT_DIG bits to the right of 1 + * R = "or" of all bits to the right of Q + */ + switch (sd) + { + case DBL_MANT_DIG + 1: + a <<= 1; + break; + case DBL_MANT_DIG + 2: + break; + default: + a = ((du_int)a >> (sd - (DBL_MANT_DIG+2))) | + ((a & ((du_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0); + }; + /* finish: */ + a |= (a & 4) != 0; /* Or P into R */ + ++a; /* round - this step may add a significant bit */ + a >>= 2; /* dump Q and R */ + /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */ + if (a & ((du_int)1 << DBL_MANT_DIG)) + { + a >>= 1; + ++e; + } + /* a is now rounded to DBL_MANT_DIG bits */ + } + else + { + a <<= (DBL_MANT_DIG - sd); + /* a is now rounded to DBL_MANT_DIG bits */ + } + double_bits fb; + fb.u.s.high = ((su_int)s & 0x80000000) | /* sign */ + ((e + 1023) << 20) | /* exponent */ + ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */ + fb.u.s.low = (su_int)a; /* mantissa-low */ + return fb.f; +} +#endif + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI double __aeabi_l2d(di_int a) { + return __floatdidf(a); +} +#else +AEABI_RTABI double __aeabi_l2d(di_int a) COMPILER_RT_ALIAS(__floatdidf); +#endif +#endif diff --git a/third_party/compiler_rt/floatdisf.c b/third_party/compiler_rt/floatdisf.c new file mode 100644 index 00000000..a508ced5 --- /dev/null +++ b/third_party/compiler_rt/floatdisf.c @@ -0,0 +1,91 @@ +/* clang-format off */ +/*===-- floatdisf.c - Implement __floatdisf -------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + *===----------------------------------------------------------------------=== + * + * This file implements __floatdisf for the compiler_rt library. + * + *===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +/* Returns: convert a to a float, rounding toward even.*/ + +/* Assumption: float is a IEEE 32 bit floating point type + * di_int is a 64 bit integral type + */ + +/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ + +#include "third_party/compiler_rt/int_lib.h" + +COMPILER_RT_ABI float +__floatdisf(di_int a) +{ + if (a == 0) + return 0.0F; + const unsigned N = sizeof(di_int) * CHAR_BIT; + const di_int s = a >> (N-1); + a = (a ^ s) - s; + int sd = N - __builtin_clzll(a); /* number of significant digits */ + int e = sd - 1; /* exponent */ + if (sd > FLT_MANT_DIG) + { + /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx + * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR + * 12345678901234567890123456 + * 1 = msb 1 bit + * P = bit FLT_MANT_DIG-1 bits to the right of 1 + * Q = bit FLT_MANT_DIG bits to the right of 1 + * R = "or" of all bits to the right of Q + */ + switch (sd) + { + case FLT_MANT_DIG + 1: + a <<= 1; + break; + case FLT_MANT_DIG + 2: + break; + default: + a = ((du_int)a >> (sd - (FLT_MANT_DIG+2))) | + ((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0); + }; + /* finish: */ + a |= (a & 4) != 0; /* Or P into R */ + ++a; /* round - this step may add a significant bit */ + a >>= 2; /* dump Q and R */ + /* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */ + if (a & ((du_int)1 << FLT_MANT_DIG)) + { + a >>= 1; + ++e; + } + /* a is now rounded to FLT_MANT_DIG bits */ + } + else + { + a <<= (FLT_MANT_DIG - sd); + /* a is now rounded to FLT_MANT_DIG bits */ + } + float_bits fb; + fb.u = ((su_int)s & 0x80000000) | /* sign */ + ((e + 127) << 23) | /* exponent */ + ((su_int)a & 0x007FFFFF); /* mantissa */ + return fb.f; +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI float __aeabi_l2f(di_int a) { + return __floatdisf(a); +} +#else +AEABI_RTABI float __aeabi_l2f(di_int a) COMPILER_RT_ALIAS(__floatdisf); +#endif +#endif diff --git a/third_party/compiler_rt/floatditf.c b/third_party/compiler_rt/floatditf.c new file mode 100644 index 00000000..5cfdea1b --- /dev/null +++ b/third_party/compiler_rt/floatditf.c @@ -0,0 +1,53 @@ +/* clang-format off */ +//===-- lib/floatditf.c - integer -> quad-precision conversion ----*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements di_int to quad-precision conversion for the +// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even +// mode. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +COMPILER_RT_ABI fp_t __floatditf(di_int a) { + + const int aWidth = sizeof a * CHAR_BIT; + + // Handle zero as a special case to protect clz + if (a == 0) + return fromRep(0); + + // All other cases begin by extracting the sign and absolute value of a + rep_t sign = 0; + du_int aAbs = (du_int)a; + if (a < 0) { + sign = signBit; + aAbs = ~(du_int)a + 1U; + } + + // Exponent of (fp_t)a is the width of abs(a). + const int exponent = (aWidth - 1) - __builtin_clzll(aAbs); + rep_t result; + + // Shift a into the significand field, rounding if it is a right-shift + const int shift = significandBits - exponent; + result = (rep_t)aAbs << shift ^ implicitBit; + + // Insert the exponent + result += (rep_t)(exponent + exponentBias) << significandBits; + // Insert the sign bit and return + return fromRep(result | sign); +} + +#endif diff --git a/third_party/compiler_rt/floatdixf.c b/third_party/compiler_rt/floatdixf.c new file mode 100644 index 00000000..8043e160 --- /dev/null +++ b/third_party/compiler_rt/floatdixf.c @@ -0,0 +1,49 @@ +/* clang-format off */ +/* ===-- floatdixf.c - Implement __floatdixf -------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __floatdixf for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#if !_ARCH_PPC + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: convert a to a long double, rounding toward even. */ + +/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits + * di_int is a 64 bit integral type + */ + +/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | + * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm + */ + +COMPILER_RT_ABI long double +__floatdixf(di_int a) +{ + if (a == 0) + return 0.0; + const unsigned N = sizeof(di_int) * CHAR_BIT; + const di_int s = a >> (N-1); + a = (a ^ s) - s; + int clz = __builtin_clzll(a); + int e = (N - 1) - clz ; /* exponent */ + long_double_bits fb; + fb.u.high.s.low = ((su_int)s & 0x00008000) | /* sign */ + (e + 16383); /* exponent */ + fb.u.low.all = a << clz; /* mantissa */ + return fb.f; +} + +#endif /* !_ARCH_PPC */ diff --git a/third_party/compiler_rt/floatsidf.c b/third_party/compiler_rt/floatsidf.c new file mode 100644 index 00000000..0c06a653 --- /dev/null +++ b/third_party/compiler_rt/floatsidf.c @@ -0,0 +1,64 @@ +/* clang-format off */ +//===-- lib/floatsidf.c - integer -> double-precision conversion --*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements integer to double-precision conversion for the +// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even +// mode. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define DOUBLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#include "third_party/compiler_rt/int_lib.h" + +COMPILER_RT_ABI fp_t +__floatsidf(int a) { + + const int aWidth = sizeof a * CHAR_BIT; + + // Handle zero as a special case to protect clz + if (a == 0) + return fromRep(0); + + // All other cases begin by extracting the sign and absolute value of a + rep_t sign = 0; + if (a < 0) { + sign = signBit; + a = -a; + } + + // Exponent of (fp_t)a is the width of abs(a). + const int exponent = (aWidth - 1) - __builtin_clz(a); + rep_t result; + + // Shift a into the significand field and clear the implicit bit. Extra + // cast to unsigned int is necessary to get the correct behavior for + // the input INT_MIN. + const int shift = significandBits - exponent; + result = (rep_t)(unsigned int)a << shift ^ implicitBit; + + // Insert the exponent + result += (rep_t)(exponent + exponentBias) << significandBits; + // Insert the sign bit and return + return fromRep(result | sign); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI fp_t __aeabi_i2d(int a) { + return __floatsidf(a); +} +#else +AEABI_RTABI fp_t __aeabi_i2d(int a) COMPILER_RT_ALIAS(__floatsidf); +#endif +#endif diff --git a/third_party/compiler_rt/floatsisf.c b/third_party/compiler_rt/floatsisf.c new file mode 100644 index 00000000..41435333 --- /dev/null +++ b/third_party/compiler_rt/floatsisf.c @@ -0,0 +1,70 @@ +/* clang-format off */ +//===-- lib/floatsisf.c - integer -> single-precision conversion --*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements integer to single-precision conversion for the +// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even +// mode. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SINGLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#include "third_party/compiler_rt/int_lib.h" + +COMPILER_RT_ABI fp_t +__floatsisf(int a) { + + const int aWidth = sizeof a * CHAR_BIT; + + // Handle zero as a special case to protect clz + if (a == 0) + return fromRep(0); + + // All other cases begin by extracting the sign and absolute value of a + rep_t sign = 0; + if (a < 0) { + sign = signBit; + a = -a; + } + + // Exponent of (fp_t)a is the width of abs(a). + const int exponent = (aWidth - 1) - __builtin_clz(a); + rep_t result; + + // Shift a into the significand field, rounding if it is a right-shift + if (exponent <= significandBits) { + const int shift = significandBits - exponent; + result = (rep_t)a << shift ^ implicitBit; + } else { + const int shift = exponent - significandBits; + result = (rep_t)a >> shift ^ implicitBit; + rep_t round = (rep_t)a << (typeWidth - shift); + if (round > signBit) result++; + if (round == signBit) result += result & 1; + } + + // Insert the exponent + result += (rep_t)(exponent + exponentBias) << significandBits; + // Insert the sign bit and return + return fromRep(result | sign); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI fp_t __aeabi_i2f(int a) { + return __floatsisf(a); +} +#else +AEABI_RTABI fp_t __aeabi_i2f(int a) COMPILER_RT_ALIAS(__floatsisf); +#endif +#endif diff --git a/third_party/compiler_rt/floatsitf.c b/third_party/compiler_rt/floatsitf.c new file mode 100644 index 00000000..f872cff8 --- /dev/null +++ b/third_party/compiler_rt/floatsitf.c @@ -0,0 +1,53 @@ +/* clang-format off */ +//===-- lib/floatsitf.c - integer -> quad-precision conversion ----*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements integer to quad-precision conversion for the +// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even +// mode. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +COMPILER_RT_ABI fp_t __floatsitf(int a) { + + const int aWidth = sizeof a * CHAR_BIT; + + // Handle zero as a special case to protect clz + if (a == 0) + return fromRep(0); + + // All other cases begin by extracting the sign and absolute value of a + rep_t sign = 0; + unsigned aAbs = (unsigned)a; + if (a < 0) { + sign = signBit; + aAbs = ~(unsigned)a + 1U; + } + + // Exponent of (fp_t)a is the width of abs(a). + const int exponent = (aWidth - 1) - __builtin_clz(aAbs); + rep_t result; + + // Shift a into the significand field and clear the implicit bit. + const int shift = significandBits - exponent; + result = (rep_t)aAbs << shift ^ implicitBit; + + // Insert the exponent + result += (rep_t)(exponent + exponentBias) << significandBits; + // Insert the sign bit and return + return fromRep(result | sign); +} + +#endif diff --git a/third_party/compiler_rt/floattidf.c b/third_party/compiler_rt/floattidf.c new file mode 100644 index 00000000..63e8906d --- /dev/null +++ b/third_party/compiler_rt/floattidf.c @@ -0,0 +1,86 @@ +/* clang-format off */ +/* ===-- floattidf.c - Implement __floattidf -------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __floattidf for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: convert a to a double, rounding toward even.*/ + +/* Assumption: double is a IEEE 64 bit floating point type + * ti_int is a 128 bit integral type + */ + +/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ + +COMPILER_RT_ABI double +__floattidf(ti_int a) +{ + if (a == 0) + return 0.0; + const unsigned N = sizeof(ti_int) * CHAR_BIT; + const ti_int s = a >> (N-1); + a = (a ^ s) - s; + int sd = N - __clzti2(a); /* number of significant digits */ + int e = sd - 1; /* exponent */ + if (sd > DBL_MANT_DIG) + { + /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx + * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR + * 12345678901234567890123456 + * 1 = msb 1 bit + * P = bit DBL_MANT_DIG-1 bits to the right of 1 + * Q = bit DBL_MANT_DIG bits to the right of 1 + * R = "or" of all bits to the right of Q + */ + switch (sd) + { + case DBL_MANT_DIG + 1: + a <<= 1; + break; + case DBL_MANT_DIG + 2: + break; + default: + a = ((tu_int)a >> (sd - (DBL_MANT_DIG+2))) | + ((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0); + }; + /* finish: */ + a |= (a & 4) != 0; /* Or P into R */ + ++a; /* round - this step may add a significant bit */ + a >>= 2; /* dump Q and R */ + /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */ + if (a & ((tu_int)1 << DBL_MANT_DIG)) + { + a >>= 1; + ++e; + } + /* a is now rounded to DBL_MANT_DIG bits */ + } + else + { + a <<= (DBL_MANT_DIG - sd); + /* a is now rounded to DBL_MANT_DIG bits */ + } + double_bits fb; + fb.u.s.high = ((su_int)s & 0x80000000) | /* sign */ + ((e + 1023) << 20) | /* exponent */ + ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */ + fb.u.s.low = (su_int)a; /* mantissa-low */ + return fb.f; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/floattisf.c b/third_party/compiler_rt/floattisf.c new file mode 100644 index 00000000..8caae762 --- /dev/null +++ b/third_party/compiler_rt/floattisf.c @@ -0,0 +1,85 @@ +/* clang-format off */ +/* ===-- floattisf.c - Implement __floattisf -------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __floattisf for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: convert a to a float, rounding toward even. */ + +/* Assumption: float is a IEEE 32 bit floating point type + * ti_int is a 128 bit integral type + */ + +/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ + +COMPILER_RT_ABI float +__floattisf(ti_int a) +{ + if (a == 0) + return 0.0F; + const unsigned N = sizeof(ti_int) * CHAR_BIT; + const ti_int s = a >> (N-1); + a = (a ^ s) - s; + int sd = N - __clzti2(a); /* number of significant digits */ + int e = sd - 1; /* exponent */ + if (sd > FLT_MANT_DIG) + { + /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx + * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR + * 12345678901234567890123456 + * 1 = msb 1 bit + * P = bit FLT_MANT_DIG-1 bits to the right of 1 + * Q = bit FLT_MANT_DIG bits to the right of 1 + * R = "or" of all bits to the right of Q + */ + switch (sd) + { + case FLT_MANT_DIG + 1: + a <<= 1; + break; + case FLT_MANT_DIG + 2: + break; + default: + a = ((tu_int)a >> (sd - (FLT_MANT_DIG+2))) | + ((a & ((tu_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0); + }; + /* finish: */ + a |= (a & 4) != 0; /* Or P into R */ + ++a; /* round - this step may add a significant bit */ + a >>= 2; /* dump Q and R */ + /* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */ + if (a & ((tu_int)1 << FLT_MANT_DIG)) + { + a >>= 1; + ++e; + } + /* a is now rounded to FLT_MANT_DIG bits */ + } + else + { + a <<= (FLT_MANT_DIG - sd); + /* a is now rounded to FLT_MANT_DIG bits */ + } + float_bits fb; + fb.u = ((su_int)s & 0x80000000) | /* sign */ + ((e + 127) << 23) | /* exponent */ + ((su_int)a & 0x007FFFFF); /* mantissa */ + return fb.f; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/floattitf.c b/third_party/compiler_rt/floattitf.c new file mode 100644 index 00000000..eb1c2ffa --- /dev/null +++ b/third_party/compiler_rt/floattitf.c @@ -0,0 +1,85 @@ +/* clang-format off */ +//===-- lib/floattitf.c - int128 -> quad-precision conversion -----*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements ti_int to quad-precision conversion for the +// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even +// mode. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: convert a ti_int to a fp_t, rounding toward even. */ + +/* Assumption: fp_t is a IEEE 128 bit floating point type + * ti_int is a 128 bit integral type + */ + +/* seee eeee eeee eeee mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | + * mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm + */ + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +COMPILER_RT_ABI fp_t +__floattitf(ti_int a) { + if (a == 0) + return 0.0; + const unsigned N = sizeof(ti_int) * CHAR_BIT; + const ti_int s = a >> (N-1); + a = (a ^ s) - s; + int sd = N - __clzti2(a); /* number of significant digits */ + int e = sd - 1; /* exponent */ + if (sd > LDBL_MANT_DIG) { + /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx + * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR + * 12345678901234567890123456 + * 1 = msb 1 bit + * P = bit LDBL_MANT_DIG-1 bits to the right of 1 + * Q = bit LDBL_MANT_DIG bits to the right of 1 + * R = "or" of all bits to the right of Q + */ + switch (sd) { + case LDBL_MANT_DIG + 1: + a <<= 1; + break; + case LDBL_MANT_DIG + 2: + break; + default: + a = ((tu_int)a >> (sd - (LDBL_MANT_DIG+2))) | + ((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0); + }; + /* finish: */ + a |= (a & 4) != 0; /* Or P into R */ + ++a; /* round - this step may add a significant bit */ + a >>= 2; /* dump Q and R */ + /* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */ + if (a & ((tu_int)1 << LDBL_MANT_DIG)) { + a >>= 1; + ++e; + } + /* a is now rounded to LDBL_MANT_DIG bits */ + } else { + a <<= (LDBL_MANT_DIG - sd); + /* a is now rounded to LDBL_MANT_DIG bits */ + } + + long_double_bits fb; + fb.u.high.all = (s & 0x8000000000000000LL) /* sign */ + | (du_int)(e + 16383) << 48 /* exponent */ + | ((a >> 64) & 0x0000ffffffffffffLL); /* significand */ + fb.u.low.all = (du_int)(a); + return fb.f; +} + +#endif diff --git a/third_party/compiler_rt/floattixf.c b/third_party/compiler_rt/floattixf.c new file mode 100644 index 00000000..1236afa0 --- /dev/null +++ b/third_party/compiler_rt/floattixf.c @@ -0,0 +1,87 @@ +/* clang-format off */ +/* ===-- floattixf.c - Implement __floattixf -------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __floattixf for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: convert a to a long double, rounding toward even. */ + +/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits + * ti_int is a 128 bit integral type + */ + +/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | + * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm + */ + +COMPILER_RT_ABI long double +__floattixf(ti_int a) +{ + if (a == 0) + return 0.0; + const unsigned N = sizeof(ti_int) * CHAR_BIT; + const ti_int s = a >> (N-1); + a = (a ^ s) - s; + int sd = N - __clzti2(a); /* number of significant digits */ + int e = sd - 1; /* exponent */ + if (sd > LDBL_MANT_DIG) + { + /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx + * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR + * 12345678901234567890123456 + * 1 = msb 1 bit + * P = bit LDBL_MANT_DIG-1 bits to the right of 1 + * Q = bit LDBL_MANT_DIG bits to the right of 1 + * R = "or" of all bits to the right of Q + */ + switch (sd) + { + case LDBL_MANT_DIG + 1: + a <<= 1; + break; + case LDBL_MANT_DIG + 2: + break; + default: + a = ((tu_int)a >> (sd - (LDBL_MANT_DIG+2))) | + ((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0); + }; + /* finish: */ + a |= (a & 4) != 0; /* Or P into R */ + ++a; /* round - this step may add a significant bit */ + a >>= 2; /* dump Q and R */ + /* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */ + if (a & ((tu_int)1 << LDBL_MANT_DIG)) + { + a >>= 1; + ++e; + } + /* a is now rounded to LDBL_MANT_DIG bits */ + } + else + { + a <<= (LDBL_MANT_DIG - sd); + /* a is now rounded to LDBL_MANT_DIG bits */ + } + long_double_bits fb; + fb.u.high.s.low = ((su_int)s & 0x8000) | /* sign */ + (e + 16383); /* exponent */ + fb.u.low.all = (du_int)a; /* mantissa */ + return fb.f; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/floatundidf.c b/third_party/compiler_rt/floatundidf.c new file mode 100644 index 00000000..3f450789 --- /dev/null +++ b/third_party/compiler_rt/floatundidf.c @@ -0,0 +1,118 @@ +/* clang-format off */ +/* ===-- floatundidf.c - Implement __floatundidf ---------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __floatundidf for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +/* Returns: convert a to a double, rounding toward even. */ + +/* Assumption: double is a IEEE 64 bit floating point type + * du_int is a 64 bit integral type + */ + +/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ + +#include "libc/literal.h" +#include "third_party/compiler_rt/int_lib.h" + +#ifndef __SOFT_FP__ +/* Support for systems that have hardware floating-point; we'll set the inexact flag + * as a side-effect of this computation. + */ + +COMPILER_RT_ABI double +__floatundidf(du_int a) +{ + static const double twop52 = 4503599627370496.0; // 0x1.0p52 + static const double twop84 = 19342813113834066795298816.0; // 0x1.0p84 + static const double twop84_plus_twop52 = 19342813118337666422669312.0; // 0x1.00000001p84 + + union { uint64_t x; double d; } high = { .d = twop84 }; + union { uint64_t x; double d; } low = { .d = twop52 }; + + high.x |= a >> 32; + low.x |= a & UINT64_C(0x00000000ffffffff); + + const double result = (high.d - twop84_plus_twop52) + low.d; + return result; +} + +#else +/* Support for systems that don't have hardware floating-point; there are no flags to + * set, and we don't want to code-gen to an unknown soft-float implementation. + */ + +COMPILER_RT_ABI double +__floatundidf(du_int a) +{ + if (a == 0) + return 0.0; + const unsigned N = sizeof(du_int) * CHAR_BIT; + int sd = N - __builtin_clzll(a); /* number of significant digits */ + int e = sd - 1; /* exponent */ + if (sd > DBL_MANT_DIG) + { + /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx + * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR + * 12345678901234567890123456 + * 1 = msb 1 bit + * P = bit DBL_MANT_DIG-1 bits to the right of 1 + * Q = bit DBL_MANT_DIG bits to the right of 1 + * R = "or" of all bits to the right of Q + */ + switch (sd) + { + case DBL_MANT_DIG + 1: + a <<= 1; + break; + case DBL_MANT_DIG + 2: + break; + default: + a = (a >> (sd - (DBL_MANT_DIG+2))) | + ((a & ((du_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0); + }; + /* finish: */ + a |= (a & 4) != 0; /* Or P into R */ + ++a; /* round - this step may add a significant bit */ + a >>= 2; /* dump Q and R */ + /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */ + if (a & ((du_int)1 << DBL_MANT_DIG)) + { + a >>= 1; + ++e; + } + /* a is now rounded to DBL_MANT_DIG bits */ + } + else + { + a <<= (DBL_MANT_DIG - sd); + /* a is now rounded to DBL_MANT_DIG bits */ + } + double_bits fb; + fb.u.s.high = ((e + 1023) << 20) | /* exponent */ + ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */ + fb.u.s.low = (su_int)a; /* mantissa-low */ + return fb.f; +} +#endif + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI double __aeabi_ul2d(du_int a) { + return __floatundidf(a); +} +#else +AEABI_RTABI double __aeabi_ul2d(du_int a) COMPILER_RT_ALIAS(__floatundidf); +#endif +#endif diff --git a/third_party/compiler_rt/floatundisf.c b/third_party/compiler_rt/floatundisf.c new file mode 100644 index 00000000..179d1895 --- /dev/null +++ b/third_party/compiler_rt/floatundisf.c @@ -0,0 +1,88 @@ +/* clang-format off */ +/*===-- floatundisf.c - Implement __floatundisf ---------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __floatundisf for the compiler_rt library. + * + *===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +/* Returns: convert a to a float, rounding toward even. */ + +/* Assumption: float is a IEEE 32 bit floating point type + * du_int is a 64 bit integral type + */ + +/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ + +#include "third_party/compiler_rt/int_lib.h" + +COMPILER_RT_ABI float +__floatundisf(du_int a) +{ + if (a == 0) + return 0.0F; + const unsigned N = sizeof(du_int) * CHAR_BIT; + int sd = N - __builtin_clzll(a); /* number of significant digits */ + int e = sd - 1; /* 8 exponent */ + if (sd > FLT_MANT_DIG) + { + /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx + * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR + * 12345678901234567890123456 + * 1 = msb 1 bit + * P = bit FLT_MANT_DIG-1 bits to the right of 1 + * Q = bit FLT_MANT_DIG bits to the right of 1 + * R = "or" of all bits to the right of Q + */ + switch (sd) + { + case FLT_MANT_DIG + 1: + a <<= 1; + break; + case FLT_MANT_DIG + 2: + break; + default: + a = (a >> (sd - (FLT_MANT_DIG+2))) | + ((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0); + }; + /* finish: */ + a |= (a & 4) != 0; /* Or P into R */ + ++a; /* round - this step may add a significant bit */ + a >>= 2; /* dump Q and R */ + /* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */ + if (a & ((du_int)1 << FLT_MANT_DIG)) + { + a >>= 1; + ++e; + } + /* a is now rounded to FLT_MANT_DIG bits */ + } + else + { + a <<= (FLT_MANT_DIG - sd); + /* a is now rounded to FLT_MANT_DIG bits */ + } + float_bits fb; + fb.u = ((e + 127) << 23) | /* exponent */ + ((su_int)a & 0x007FFFFF); /* mantissa */ + return fb.f; +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI float __aeabi_ul2f(du_int a) { + return __floatundisf(a); +} +#else +AEABI_RTABI float __aeabi_ul2f(du_int a) COMPILER_RT_ALIAS(__floatundisf); +#endif +#endif diff --git a/third_party/compiler_rt/floatunditf.c b/third_party/compiler_rt/floatunditf.c new file mode 100644 index 00000000..9a37481f --- /dev/null +++ b/third_party/compiler_rt/floatunditf.c @@ -0,0 +1,43 @@ +/* clang-format off */ +//===-- lib/floatunditf.c - uint -> quad-precision conversion -----*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements du_int to quad-precision conversion for the +// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even +// mode. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +COMPILER_RT_ABI fp_t __floatunditf(du_int a) { + + const int aWidth = sizeof a * CHAR_BIT; + + // Handle zero as a special case to protect clz + if (a == 0) return fromRep(0); + + // Exponent of (fp_t)a is the width of abs(a). + const int exponent = (aWidth - 1) - __builtin_clzll(a); + rep_t result; + + // Shift a into the significand field and clear the implicit bit. + const int shift = significandBits - exponent; + result = (rep_t)a << shift ^ implicitBit; + + // Insert the exponent + result += (rep_t)(exponent + exponentBias) << significandBits; + return fromRep(result); +} + +#endif diff --git a/third_party/compiler_rt/floatundixf.c b/third_party/compiler_rt/floatundixf.c new file mode 100644 index 00000000..69ba1dae --- /dev/null +++ b/third_party/compiler_rt/floatundixf.c @@ -0,0 +1,45 @@ +/* clang-format off */ +/* ===-- floatundixf.c - Implement __floatundixf ---------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __floatundixf for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#if !_ARCH_PPC + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: convert a to a long double, rounding toward even. */ + +/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits + * du_int is a 64 bit integral type + */ + +/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | + * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm + */ +COMPILER_RT_ABI long double +__floatundixf(du_int a) +{ + if (a == 0) + return 0.0; + const unsigned N = sizeof(du_int) * CHAR_BIT; + int clz = __builtin_clzll(a); + int e = (N - 1) - clz ; /* exponent */ + long_double_bits fb; + fb.u.high.s.low = (e + 16383); /* exponent */ + fb.u.low.all = a << clz; /* mantissa */ + return fb.f; +} + +#endif /* _ARCH_PPC */ diff --git a/third_party/compiler_rt/floatunsidf.c b/third_party/compiler_rt/floatunsidf.c new file mode 100644 index 00000000..e06933eb --- /dev/null +++ b/third_party/compiler_rt/floatunsidf.c @@ -0,0 +1,53 @@ +/* clang-format off */ +//===-- lib/floatunsidf.c - uint -> double-precision conversion ---*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements unsigned integer to double-precision conversion for the +// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even +// mode. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define DOUBLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#include "third_party/compiler_rt/int_lib.h" + +COMPILER_RT_ABI fp_t +__floatunsidf(unsigned int a) { + + const int aWidth = sizeof a * CHAR_BIT; + + // Handle zero as a special case to protect clz + if (a == 0) return fromRep(0); + + // Exponent of (fp_t)a is the width of abs(a). + const int exponent = (aWidth - 1) - __builtin_clz(a); + rep_t result; + + // Shift a into the significand field and clear the implicit bit. + const int shift = significandBits - exponent; + result = (rep_t)a << shift ^ implicitBit; + + // Insert the exponent + result += (rep_t)(exponent + exponentBias) << significandBits; + return fromRep(result); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI fp_t __aeabi_ui2d(unsigned int a) { + return __floatunsidf(a); +} +#else +AEABI_RTABI fp_t __aeabi_ui2d(unsigned int a) COMPILER_RT_ALIAS(__floatunsidf); +#endif +#endif diff --git a/third_party/compiler_rt/floatunsisf.c b/third_party/compiler_rt/floatunsisf.c new file mode 100644 index 00000000..37ada245 --- /dev/null +++ b/third_party/compiler_rt/floatunsisf.c @@ -0,0 +1,61 @@ +/* clang-format off */ +//===-- lib/floatunsisf.c - uint -> single-precision conversion ---*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements unsigned integer to single-precision conversion for the +// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even +// mode. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SINGLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#include "third_party/compiler_rt/int_lib.h" + +COMPILER_RT_ABI fp_t +__floatunsisf(unsigned int a) { + + const int aWidth = sizeof a * CHAR_BIT; + + // Handle zero as a special case to protect clz + if (a == 0) return fromRep(0); + + // Exponent of (fp_t)a is the width of abs(a). + const int exponent = (aWidth - 1) - __builtin_clz(a); + rep_t result; + + // Shift a into the significand field, rounding if it is a right-shift + if (exponent <= significandBits) { + const int shift = significandBits - exponent; + result = (rep_t)a << shift ^ implicitBit; + } else { + const int shift = exponent - significandBits; + result = (rep_t)a >> shift ^ implicitBit; + rep_t round = (rep_t)a << (typeWidth - shift); + if (round > signBit) result++; + if (round == signBit) result += result & 1; + } + + // Insert the exponent + result += (rep_t)(exponent + exponentBias) << significandBits; + return fromRep(result); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI fp_t __aeabi_ui2f(unsigned int a) { + return __floatunsisf(a); +} +#else +AEABI_RTABI fp_t __aeabi_ui2f(unsigned int a) COMPILER_RT_ALIAS(__floatunsisf); +#endif +#endif diff --git a/third_party/compiler_rt/floatunsitf.c b/third_party/compiler_rt/floatunsitf.c new file mode 100644 index 00000000..439ef857 --- /dev/null +++ b/third_party/compiler_rt/floatunsitf.c @@ -0,0 +1,43 @@ +/* clang-format off */ +//===-- lib/floatunsitf.c - uint -> quad-precision conversion -----*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements unsigned integer to quad-precision conversion for the +// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even +// mode. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +COMPILER_RT_ABI fp_t __floatunsitf(unsigned int a) { + + const int aWidth = sizeof a * CHAR_BIT; + + // Handle zero as a special case to protect clz + if (a == 0) return fromRep(0); + + // Exponent of (fp_t)a is the width of abs(a). + const int exponent = (aWidth - 1) - __builtin_clz(a); + rep_t result; + + // Shift a into the significand field and clear the implicit bit. + const int shift = significandBits - exponent; + result = (rep_t)a << shift ^ implicitBit; + + // Insert the exponent + result += (rep_t)(exponent + exponentBias) << significandBits; + return fromRep(result); +} + +#endif diff --git a/third_party/compiler_rt/floatuntidf.c b/third_party/compiler_rt/floatuntidf.c new file mode 100644 index 00000000..d3d206d8 --- /dev/null +++ b/third_party/compiler_rt/floatuntidf.c @@ -0,0 +1,83 @@ +/* clang-format off */ +/* ===-- floatuntidf.c - Implement __floatuntidf ---------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __floatuntidf for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: convert a to a double, rounding toward even. */ + +/* Assumption: double is a IEEE 64 bit floating point type + * tu_int is a 128 bit integral type + */ + +/* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ + +COMPILER_RT_ABI double +__floatuntidf(tu_int a) +{ + if (a == 0) + return 0.0; + const unsigned N = sizeof(tu_int) * CHAR_BIT; + int sd = N - __clzti2(a); /* number of significant digits */ + int e = sd - 1; /* exponent */ + if (sd > DBL_MANT_DIG) + { + /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx + * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR + * 12345678901234567890123456 + * 1 = msb 1 bit + * P = bit DBL_MANT_DIG-1 bits to the right of 1 + * Q = bit DBL_MANT_DIG bits to the right of 1 + * R = "or" of all bits to the right of Q + */ + switch (sd) + { + case DBL_MANT_DIG + 1: + a <<= 1; + break; + case DBL_MANT_DIG + 2: + break; + default: + a = (a >> (sd - (DBL_MANT_DIG+2))) | + ((a & ((tu_int)(-1) >> ((N + DBL_MANT_DIG+2) - sd))) != 0); + }; + /* finish: */ + a |= (a & 4) != 0; /* Or P into R */ + ++a; /* round - this step may add a significant bit */ + a >>= 2; /* dump Q and R */ + /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */ + if (a & ((tu_int)1 << DBL_MANT_DIG)) + { + a >>= 1; + ++e; + } + /* a is now rounded to DBL_MANT_DIG bits */ + } + else + { + a <<= (DBL_MANT_DIG - sd); + /* a is now rounded to DBL_MANT_DIG bits */ + } + double_bits fb; + fb.u.s.high = ((e + 1023) << 20) | /* exponent */ + ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */ + fb.u.s.low = (su_int)a; /* mantissa-low */ + return fb.f; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/floatuntisf.c b/third_party/compiler_rt/floatuntisf.c new file mode 100644 index 00000000..79b78c9b --- /dev/null +++ b/third_party/compiler_rt/floatuntisf.c @@ -0,0 +1,82 @@ +/* clang-format off */ +/* ===-- floatuntisf.c - Implement __floatuntisf ---------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __floatuntisf for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: convert a to a float, rounding toward even. */ + +/* Assumption: float is a IEEE 32 bit floating point type + * tu_int is a 128 bit integral type + */ + +/* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ + +COMPILER_RT_ABI float +__floatuntisf(tu_int a) +{ + if (a == 0) + return 0.0F; + const unsigned N = sizeof(tu_int) * CHAR_BIT; + int sd = N - __clzti2(a); /* number of significant digits */ + int e = sd - 1; /* exponent */ + if (sd > FLT_MANT_DIG) + { + /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx + * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR + * 12345678901234567890123456 + * 1 = msb 1 bit + * P = bit FLT_MANT_DIG-1 bits to the right of 1 + * Q = bit FLT_MANT_DIG bits to the right of 1 + * R = "or" of all bits to the right of Q + */ + switch (sd) + { + case FLT_MANT_DIG + 1: + a <<= 1; + break; + case FLT_MANT_DIG + 2: + break; + default: + a = (a >> (sd - (FLT_MANT_DIG+2))) | + ((a & ((tu_int)(-1) >> ((N + FLT_MANT_DIG+2) - sd))) != 0); + }; + /* finish: */ + a |= (a & 4) != 0; /* Or P into R */ + ++a; /* round - this step may add a significant bit */ + a >>= 2; /* dump Q and R */ + /* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */ + if (a & ((tu_int)1 << FLT_MANT_DIG)) + { + a >>= 1; + ++e; + } + /* a is now rounded to FLT_MANT_DIG bits */ + } + else + { + a <<= (FLT_MANT_DIG - sd); + /* a is now rounded to FLT_MANT_DIG bits */ + } + float_bits fb; + fb.u = ((e + 127) << 23) | /* exponent */ + ((su_int)a & 0x007FFFFF); /* mantissa */ + return fb.f; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/floatuntitf.c b/third_party/compiler_rt/floatuntitf.c new file mode 100644 index 00000000..1b135526 --- /dev/null +++ b/third_party/compiler_rt/floatuntitf.c @@ -0,0 +1,82 @@ +/* clang-format off */ +//===-- lib/floatuntitf.c - uint128 -> quad-precision conversion --*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements tu_int to quad-precision conversion for the +// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even +// mode. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: convert a tu_int to a fp_t, rounding toward even. */ + +/* Assumption: fp_t is a IEEE 128 bit floating point type + * tu_int is a 128 bit integral type + */ + +/* seee eeee eeee eeee mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | + * mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm + */ + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +COMPILER_RT_ABI fp_t +__floatuntitf(tu_int a) { + if (a == 0) + return 0.0; + const unsigned N = sizeof(tu_int) * CHAR_BIT; + int sd = N - __clzti2(a); /* number of significant digits */ + int e = sd - 1; /* exponent */ + if (sd > LDBL_MANT_DIG) { + /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx + * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR + * 12345678901234567890123456 + * 1 = msb 1 bit + * P = bit LDBL_MANT_DIG-1 bits to the right of 1 + * Q = bit LDBL_MANT_DIG bits to the right of 1 + * R = "or" of all bits to the right of Q + */ + switch (sd) { + case LDBL_MANT_DIG + 1: + a <<= 1; + break; + case LDBL_MANT_DIG + 2: + break; + default: + a = (a >> (sd - (LDBL_MANT_DIG+2))) | + ((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0); + }; + /* finish: */ + a |= (a & 4) != 0; /* Or P into R */ + ++a; /* round - this step may add a significant bit */ + a >>= 2; /* dump Q and R */ + /* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */ + if (a & ((tu_int)1 << LDBL_MANT_DIG)) { + a >>= 1; + ++e; + } + /* a is now rounded to LDBL_MANT_DIG bits */ + } else { + a <<= (LDBL_MANT_DIG - sd); + /* a is now rounded to LDBL_MANT_DIG bits */ + } + + long_double_bits fb; + fb.u.high.all = (du_int)(e + 16383) << 48 /* exponent */ + | ((a >> 64) & 0x0000ffffffffffffLL); /* significand */ + fb.u.low.all = (du_int)(a); + return fb.f; +} + +#endif diff --git a/third_party/compiler_rt/floatuntixf.c b/third_party/compiler_rt/floatuntixf.c new file mode 100644 index 00000000..03c2e68c --- /dev/null +++ b/third_party/compiler_rt/floatuntixf.c @@ -0,0 +1,84 @@ +/* clang-format off */ +/* ===-- floatuntixf.c - Implement __floatuntixf ---------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __floatuntixf for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: convert a to a long double, rounding toward even. */ + +/* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits + * tu_int is a 128 bit integral type + */ + +/* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | + * 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm + */ + +COMPILER_RT_ABI long double +__floatuntixf(tu_int a) +{ + if (a == 0) + return 0.0; + const unsigned N = sizeof(tu_int) * CHAR_BIT; + int sd = N - __clzti2(a); /* number of significant digits */ + int e = sd - 1; /* exponent */ + if (sd > LDBL_MANT_DIG) + { + /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx + * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR + * 12345678901234567890123456 + * 1 = msb 1 bit + * P = bit LDBL_MANT_DIG-1 bits to the right of 1 + * Q = bit LDBL_MANT_DIG bits to the right of 1 + * R = "or" of all bits to the right of Q + */ + switch (sd) + { + case LDBL_MANT_DIG + 1: + a <<= 1; + break; + case LDBL_MANT_DIG + 2: + break; + default: + a = (a >> (sd - (LDBL_MANT_DIG+2))) | + ((a & ((tu_int)(-1) >> ((N + LDBL_MANT_DIG+2) - sd))) != 0); + }; + /* finish: */ + a |= (a & 4) != 0; /* Or P into R */ + ++a; /* round - this step may add a significant bit */ + a >>= 2; /* dump Q and R */ + /* a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits */ + if (a & ((tu_int)1 << LDBL_MANT_DIG)) + { + a >>= 1; + ++e; + } + /* a is now rounded to LDBL_MANT_DIG bits */ + } + else + { + a <<= (LDBL_MANT_DIG - sd); + /* a is now rounded to LDBL_MANT_DIG bits */ + } + long_double_bits fb; + fb.u.high.s.low = (e + 16383); /* exponent */ + fb.u.low.all = (du_int)a; /* mantissa */ + return fb.f; +} + +#endif diff --git a/third_party/compiler_rt/fp_add_impl.inc b/third_party/compiler_rt/fp_add_impl.inc new file mode 100644 index 00000000..9d36c18e --- /dev/null +++ b/third_party/compiler_rt/fp_add_impl.inc @@ -0,0 +1,146 @@ +/* clang-format off */ +//===----- lib/fp_add_impl.inc - floaing point addition -----------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements soft-float addition with the IEEE-754 default rounding +// (to nearest, ties to even). +// +//===----------------------------------------------------------------------===// + +#include "libc/literal.h" +#include "third_party/compiler_rt/fp_lib.inc" + +static __inline fp_t __addXf3__(fp_t a, fp_t b) { + rep_t aRep = toRep(a); + rep_t bRep = toRep(b); + const rep_t aAbs = aRep & absMask; + const rep_t bAbs = bRep & absMask; + + // Detect if a or b is zero, infinity, or NaN. + if (aAbs - REP_C(1) >= infRep - REP_C(1) || + bAbs - REP_C(1) >= infRep - REP_C(1)) { + // NaN + anything = qNaN + if (aAbs > infRep) return fromRep(toRep(a) | quietBit); + // anything + NaN = qNaN + if (bAbs > infRep) return fromRep(toRep(b) | quietBit); + + if (aAbs == infRep) { + // +/-infinity + -/+infinity = qNaN + if ((toRep(a) ^ toRep(b)) == signBit) return fromRep(qnanRep); + // +/-infinity + anything remaining = +/- infinity + else return a; + } + + // anything remaining + +/-infinity = +/-infinity + if (bAbs == infRep) return b; + + // zero + anything = anything + if (!aAbs) { + // but we need to get the sign right for zero + zero + if (!bAbs) return fromRep(toRep(a) & toRep(b)); + else return b; + } + + // anything + zero = anything + if (!bAbs) return a; + } + + // Swap a and b if necessary so that a has the larger absolute value. + if (bAbs > aAbs) { + const rep_t temp = aRep; + aRep = bRep; + bRep = temp; + } + + // Extract the exponent and significand from the (possibly swapped) a and b. + int aExponent = aRep >> significandBits & maxExponent; + int bExponent = bRep >> significandBits & maxExponent; + rep_t aSignificand = aRep & significandMask; + rep_t bSignificand = bRep & significandMask; + + // Normalize any denormals, and adjust the exponent accordingly. + if (aExponent == 0) aExponent = normalize(&aSignificand); + if (bExponent == 0) bExponent = normalize(&bSignificand); + + // The sign of the result is the sign of the larger operand, a. If they + // have opposite signs, we are performing a subtraction; otherwise addition. + const rep_t resultSign = aRep & signBit; + const bool subtraction = (aRep ^ bRep) & signBit; + + // Shift the significands to give us round, guard and sticky, and or in the + // implicit significand bit. (If we fell through from the denormal path it + // was already set by normalize( ), but setting it twice won't hurt + // anything.) + aSignificand = (aSignificand | implicitBit) << 3; + bSignificand = (bSignificand | implicitBit) << 3; + + // Shift the significand of b by the difference in exponents, with a sticky + // bottom bit to get rounding correct. + const unsigned int align = aExponent - bExponent; + if (align) { + if (align < typeWidth) { + const bool sticky = bSignificand << (typeWidth - align); + bSignificand = bSignificand >> align | sticky; + } else { + bSignificand = 1; // sticky; b is known to be non-zero. + } + } + if (subtraction) { + aSignificand -= bSignificand; + // If a == -b, return +zero. + if (aSignificand == 0) return fromRep(0); + + // If partial cancellation occured, we need to left-shift the result + // and adjust the exponent: + if (aSignificand < implicitBit << 3) { + const int shift = rep_clz(aSignificand) - rep_clz(implicitBit << 3); + aSignificand <<= shift; + aExponent -= shift; + } + } + else /* addition */ { + aSignificand += bSignificand; + + // If the addition carried up, we need to right-shift the result and + // adjust the exponent: + if (aSignificand & implicitBit << 4) { + const bool sticky = aSignificand & 1; + aSignificand = aSignificand >> 1 | sticky; + aExponent += 1; + } + } + + // If we have overflowed the type, return +/- infinity: + if (aExponent >= maxExponent) return fromRep(infRep | resultSign); + + if (aExponent <= 0) { + // Result is denormal before rounding; the exponent is zero and we + // need to shift the significand. + const int shift = 1 - aExponent; + const bool sticky = aSignificand << (typeWidth - shift); + aSignificand = aSignificand >> shift | sticky; + aExponent = 0; + } + + // Low three bits are round, guard, and sticky. + const int roundGuardSticky = aSignificand & 0x7; + + // Shift the significand into place, and mask off the implicit bit. + rep_t result = aSignificand >> 3 & significandMask; + + // Insert the exponent and sign. + result |= (rep_t)aExponent << significandBits; + result |= resultSign; + + // Final rounding. The result may overflow to infinity, but that is the + // correct result in that case. + if (roundGuardSticky > 0x4) result++; + if (roundGuardSticky == 0x4) result += result & 1; + return fromRep(result); +} diff --git a/third_party/compiler_rt/fp_extend_common.inc b/third_party/compiler_rt/fp_extend_common.inc new file mode 100644 index 00000000..fd669401 --- /dev/null +++ b/third_party/compiler_rt/fp_extend_common.inc @@ -0,0 +1,93 @@ +/* clang-format off */ +//===-lib/fp_extend.h - low precision -> high precision conversion -*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Set source and destination setting +// +//===----------------------------------------------------------------------===// + +#ifndef FP_EXTEND_HEADER +#define FP_EXTEND_HEADER + +#include "libc/literal.h" +#include "third_party/compiler_rt/int_lib.h" + +#if defined SRC_SINGLE +typedef float src_t; +typedef uint32_t src_rep_t; +#define SRC_REP_C UINT32_C +static const int srcSigBits = 23; +#define src_rep_t_clz __builtin_clz + +#elif defined SRC_DOUBLE +typedef double src_t; +typedef uint64_t src_rep_t; +#define SRC_REP_C UINT64_C +static const int srcSigBits = 52; +static __inline int src_rep_t_clz(src_rep_t a) { +#if defined __LP64__ + return __builtin_clzl(a); +#else + if (a & REP_C(0xffffffff00000000)) + return __builtin_clz(a >> 32); + else + return 32 + __builtin_clz(a & REP_C(0xffffffff)); +#endif +} + +#elif defined SRC_HALF +typedef uint16_t src_t; +typedef uint16_t src_rep_t; +#define SRC_REP_C UINT16_C +static const int srcSigBits = 10; +#define src_rep_t_clz __builtin_clz + +#else +#error Source should be half, single, or double precision! +#endif //end source precision + +#undef DST_REP_C + +#if defined DST_SINGLE +typedef float dst_t; +typedef uint32_t dst_rep_t; +#define DST_REP_C UINT32_C +static const int dstSigBits = 23; + +#elif defined DST_DOUBLE +typedef double dst_t; +typedef uint64_t dst_rep_t; +#define DST_REP_C UINT64_C +static const int dstSigBits = 52; + +#elif defined DST_QUAD +typedef long double dst_t; +typedef __uint128_t dst_rep_t; +#define DST_REP_C (__uint128_t) +static const int dstSigBits = 112; + +#else +#error Destination should be single, double, or quad precision! +#endif //end destination precision + +// End of specialization parameters. Two helper routines for conversion to and +// from the representation of floating-point data as integer values follow. + +static __inline src_rep_t srcToRep(src_t x) { + const union { src_t f; src_rep_t i; } rep = {.f = x}; + return rep.i; +} + +static __inline dst_t dstFromRep(dst_rep_t x) { + const union { dst_t f; dst_rep_t i; } rep = {.i = x}; + return rep.f; +} +// End helper routines. Conversion implementation follows. + +#endif //FP_EXTEND_HEADER diff --git a/third_party/compiler_rt/fp_extend_impl.inc b/third_party/compiler_rt/fp_extend_impl.inc new file mode 100644 index 00000000..42ac6eeb --- /dev/null +++ b/third_party/compiler_rt/fp_extend_impl.inc @@ -0,0 +1,110 @@ +/* clang-format off */ +//=-lib/fp_extend_impl.inc - low precision -> high precision conversion -*-- -// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements a fairly generic conversion from a narrower to a wider +// IEEE-754 floating-point type. The constants and types defined following the +// includes below parameterize the conversion. +// +// It does not support types that don't use the usual IEEE-754 interchange +// formats; specifically, some work would be needed to adapt it to +// (for example) the Intel 80-bit format or PowerPC double-double format. +// +// Note please, however, that this implementation is only intended to support +// *widening* operations; if you need to convert to a *narrower* floating-point +// type (e.g. double -> float), then this routine will not do what you want it +// to. +// +// It also requires that integer types at least as large as both formats +// are available on the target platform; this may pose a problem when trying +// to add support for quad on some 32-bit systems, for example. You also may +// run into trouble finding an appropriate CLZ function for wide source types; +// you will likely need to roll your own on some platforms. +// +// Finally, the following assumptions are made: +// +// 1. floating-point types and integer types have the same endianness on the +// target platform +// +// 2. quiet NaNs, if supported, are indicated by the leading bit of the +// significand field being set +// +//===----------------------------------------------------------------------===// + +#include "libc/literal.h" +#include "third_party/compiler_rt/fp_extend_common.inc" + +static __inline dst_t __extendXfYf2__(src_t a) { + // Various constants whose values follow from the type parameters. + // Any reasonable optimizer will fold and propagate all of these. + const int srcBits = sizeof(src_t)*CHAR_BIT; + const int srcExpBits = srcBits - srcSigBits - 1; + const int srcInfExp = (1u << srcExpBits) - 1; + const int srcExpBias = srcInfExp >> 1; + + const src_rep_t srcMinNormal = SRC_REP_C(1) << srcSigBits; + const src_rep_t srcInfinity = (src_rep_t)srcInfExp << srcSigBits; + const src_rep_t srcSignMask = SRC_REP_C(1) << (srcSigBits + srcExpBits); + const src_rep_t srcAbsMask = srcSignMask - 1; + const src_rep_t srcQNaN = SRC_REP_C(1) << (srcSigBits - 1); + const src_rep_t srcNaNCode = srcQNaN - 1; + + const int dstBits = sizeof(dst_t)*CHAR_BIT; + const int dstExpBits = dstBits - dstSigBits - 1; + const int dstInfExp = (1u << dstExpBits) - 1; + const int dstExpBias = dstInfExp >> 1; + + const dst_rep_t dstMinNormal = DST_REP_C(1) << dstSigBits; + + // Break a into a sign and representation of the absolute value + const src_rep_t aRep = srcToRep(a); + const src_rep_t aAbs = aRep & srcAbsMask; + const src_rep_t sign = aRep & srcSignMask; + dst_rep_t absResult; + + // If sizeof(src_rep_t) < sizeof(int), the subtraction result is promoted + // to (signed) int. To avoid that, explicitly cast to src_rep_t. + if ((src_rep_t)(aAbs - srcMinNormal) < srcInfinity - srcMinNormal) { + // a is a normal number. + // Extend to the destination type by shifting the significand and + // exponent into the proper position and rebiasing the exponent. + absResult = (dst_rep_t)aAbs << (dstSigBits - srcSigBits); + absResult += (dst_rep_t)(dstExpBias - srcExpBias) << dstSigBits; + } + + else if (aAbs >= srcInfinity) { + // a is NaN or infinity. + // Conjure the result by beginning with infinity, then setting the qNaN + // bit (if needed) and right-aligning the rest of the trailing NaN + // payload field. + absResult = (dst_rep_t)dstInfExp << dstSigBits; + absResult |= (dst_rep_t)(aAbs & srcQNaN) << (dstSigBits - srcSigBits); + absResult |= (dst_rep_t)(aAbs & srcNaNCode) << (dstSigBits - srcSigBits); + } + + else if (aAbs) { + // a is denormal. + // renormalize the significand and clear the leading bit, then insert + // the correct adjusted exponent in the destination type. + const int scale = src_rep_t_clz(aAbs) - src_rep_t_clz(srcMinNormal); + absResult = (dst_rep_t)aAbs << (dstSigBits - srcSigBits + scale); + absResult ^= dstMinNormal; + const int resultExponent = dstExpBias - srcExpBias - scale + 1; + absResult |= (dst_rep_t)resultExponent << dstSigBits; + } + + else { + // a is zero. + absResult = 0; + } + + // Apply the signbit to (dst_t)abs(a). + const dst_rep_t result = absResult | (dst_rep_t)sign << (dstBits - srcBits); + return dstFromRep(result); +} diff --git a/third_party/compiler_rt/fp_fixint_impl.inc b/third_party/compiler_rt/fp_fixint_impl.inc new file mode 100644 index 00000000..287bdb5d --- /dev/null +++ b/third_party/compiler_rt/fp_fixint_impl.inc @@ -0,0 +1,42 @@ +/* clang-format off */ +//===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements float to integer conversion for the +// compiler-rt library. +// +//===----------------------------------------------------------------------===// + +#include "third_party/compiler_rt/fp_lib.inc" + +static __inline fixint_t __fixint(fp_t a) { + const fixint_t fixint_max = (fixint_t)((~(fixuint_t)0) / 2); + const fixint_t fixint_min = -fixint_max - 1; + // Break a into sign, exponent, significand + const rep_t aRep = toRep(a); + const rep_t aAbs = aRep & absMask; + const fixint_t sign = aRep & signBit ? -1 : 1; + const int exponent = (aAbs >> significandBits) - exponentBias; + const rep_t significand = (aAbs & significandMask) | implicitBit; + + // If exponent is negative, the result is zero. + if (exponent < 0) + return 0; + + // If the value is too large for the integer type, saturate. + if ((unsigned)exponent >= sizeof(fixint_t) * CHAR_BIT) + return sign == 1 ? fixint_max : fixint_min; + + // If 0 <= exponent < significandBits, right shift to get the result. + // Otherwise, shift left. + if (exponent < significandBits) + return sign * (significand >> (significandBits - exponent)); + else + return sign * ((fixint_t)significand << (exponent - significandBits)); +} diff --git a/third_party/compiler_rt/fp_fixuint_impl.inc b/third_party/compiler_rt/fp_fixuint_impl.inc new file mode 100644 index 00000000..870e1d89 --- /dev/null +++ b/third_party/compiler_rt/fp_fixuint_impl.inc @@ -0,0 +1,40 @@ +/* clang-format off */ +//===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements float to unsigned integer conversion for the +// compiler-rt library. +// +//===----------------------------------------------------------------------===// + +#include "third_party/compiler_rt/fp_lib.inc" + +static __inline fixuint_t __fixuint(fp_t a) { + // Break a into sign, exponent, significand + const rep_t aRep = toRep(a); + const rep_t aAbs = aRep & absMask; + const int sign = aRep & signBit ? -1 : 1; + const int exponent = (aAbs >> significandBits) - exponentBias; + const rep_t significand = (aAbs & significandMask) | implicitBit; + + // If either the value or the exponent is negative, the result is zero. + if (sign == -1 || exponent < 0) + return 0; + + // If the value is too large for the integer type, saturate. + if ((unsigned)exponent >= sizeof(fixuint_t) * CHAR_BIT) + return ~(fixuint_t)0; + + // If 0 <= exponent < significandBits, right shift to get the result. + // Otherwise, shift left. + if (exponent < significandBits) + return significand >> (significandBits - exponent); + else + return (fixuint_t)significand << (exponent - significandBits); +} diff --git a/third_party/compiler_rt/fp_lib.inc b/third_party/compiler_rt/fp_lib.inc new file mode 100644 index 00000000..da19ec91 --- /dev/null +++ b/third_party/compiler_rt/fp_lib.inc @@ -0,0 +1,314 @@ +/* clang-format off */ +//===-- lib/fp_lib.h - Floating-point utilities -------------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a configuration header for soft-float routines in compiler-rt. +// This file does not provide any part of the compiler-rt interface, but defines +// many useful constants and utility routines that are used in the +// implementation of the soft-float routines in compiler-rt. +// +// Assumes that float, double and long double correspond to the IEEE-754 +// binary32, binary64 and binary 128 types, respectively, and that integer +// endianness matches floating point endianness on the target platform. +// +//===----------------------------------------------------------------------===// + +#ifndef FP_LIB_HEADER +#define FP_LIB_HEADER + +#include "libc/literal.h" +#include "third_party/compiler_rt/int_lib.h" +#include "third_party/compiler_rt/int_math.h" + +#if defined SINGLE_PRECISION + +typedef uint32_t rep_t; +typedef int32_t srep_t; +typedef float fp_t; +#define REP_C UINT32_C +#define significandBits 23 + +static __inline int rep_clz(rep_t a) { + return __builtin_clz(a); +} + +// 32x32 --> 64 bit multiply +static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) { + const uint64_t product = (uint64_t)a*b; + *hi = product >> 32; + *lo = product; +} +COMPILER_RT_ABI fp_t __addsf3(fp_t a, fp_t b); + +#elif defined DOUBLE_PRECISION + +typedef uint64_t rep_t; +typedef int64_t srep_t; +typedef double fp_t; +#define REP_C UINT64_C +#define significandBits 52 + +static __inline int rep_clz(rep_t a) { +#if defined __LP64__ + return __builtin_clzl(a); +#else + if (a & REP_C(0xffffffff00000000)) + return __builtin_clz(a >> 32); + else + return 32 + __builtin_clz(a & REP_C(0xffffffff)); +#endif +} + +#define loWord(a) (a & 0xffffffffU) +#define hiWord(a) (a >> 32) + +// 64x64 -> 128 wide multiply for platforms that don't have such an operation; +// many 64-bit platforms have this operation, but they tend to have hardware +// floating-point, so we don't bother with a special case for them here. +static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) { + // Each of the component 32x32 -> 64 products + const uint64_t plolo = loWord(a) * loWord(b); + const uint64_t plohi = loWord(a) * hiWord(b); + const uint64_t philo = hiWord(a) * loWord(b); + const uint64_t phihi = hiWord(a) * hiWord(b); + // Sum terms that contribute to lo in a way that allows us to get the carry + const uint64_t r0 = loWord(plolo); + const uint64_t r1 = hiWord(plolo) + loWord(plohi) + loWord(philo); + *lo = r0 + (r1 << 32); + // Sum terms contributing to hi with the carry from lo + *hi = hiWord(plohi) + hiWord(philo) + hiWord(r1) + phihi; +} +#undef loWord +#undef hiWord + +COMPILER_RT_ABI fp_t __adddf3(fp_t a, fp_t b); + +#elif defined QUAD_PRECISION +#if __LDBL_MANT_DIG__ == 113 +#define CRT_LDBL_128BIT +typedef __uint128_t rep_t; +typedef __int128_t srep_t; +typedef long double fp_t; +#define REP_C (__uint128_t) +// Note: Since there is no explicit way to tell compiler the constant is a +// 128-bit integer, we let the constant be casted to 128-bit integer +#define significandBits 112 + +static __inline int rep_clz(rep_t a) { + const union + { + __uint128_t ll; +#if _YUGA_BIG_ENDIAN + struct { uint64_t high, low; } s; +#else + struct { uint64_t low, high; } s; +#endif + } uu = { .ll = a }; + + uint64_t word; + uint64_t add; + + if (uu.s.high){ + word = uu.s.high; + add = 0; + } + else{ + word = uu.s.low; + add = 64; + } + return __builtin_clzll(word) + add; +} + +#define Word_LoMask UINT64_C(0x00000000ffffffff) +#define Word_HiMask UINT64_C(0xffffffff00000000) +#define Word_FullMask UINT64_C(0xffffffffffffffff) +#define Word_1(a) (uint64_t)((a >> 96) & Word_LoMask) +#define Word_2(a) (uint64_t)((a >> 64) & Word_LoMask) +#define Word_3(a) (uint64_t)((a >> 32) & Word_LoMask) +#define Word_4(a) (uint64_t)(a & Word_LoMask) + +// 128x128 -> 256 wide multiply for platforms that don't have such an operation; +// many 64-bit platforms have this operation, but they tend to have hardware +// floating-point, so we don't bother with a special case for them here. +static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) { + + const uint64_t product11 = Word_1(a) * Word_1(b); + const uint64_t product12 = Word_1(a) * Word_2(b); + const uint64_t product13 = Word_1(a) * Word_3(b); + const uint64_t product14 = Word_1(a) * Word_4(b); + const uint64_t product21 = Word_2(a) * Word_1(b); + const uint64_t product22 = Word_2(a) * Word_2(b); + const uint64_t product23 = Word_2(a) * Word_3(b); + const uint64_t product24 = Word_2(a) * Word_4(b); + const uint64_t product31 = Word_3(a) * Word_1(b); + const uint64_t product32 = Word_3(a) * Word_2(b); + const uint64_t product33 = Word_3(a) * Word_3(b); + const uint64_t product34 = Word_3(a) * Word_4(b); + const uint64_t product41 = Word_4(a) * Word_1(b); + const uint64_t product42 = Word_4(a) * Word_2(b); + const uint64_t product43 = Word_4(a) * Word_3(b); + const uint64_t product44 = Word_4(a) * Word_4(b); + + const __uint128_t sum0 = (__uint128_t)product44; + const __uint128_t sum1 = (__uint128_t)product34 + + (__uint128_t)product43; + const __uint128_t sum2 = (__uint128_t)product24 + + (__uint128_t)product33 + + (__uint128_t)product42; + const __uint128_t sum3 = (__uint128_t)product14 + + (__uint128_t)product23 + + (__uint128_t)product32 + + (__uint128_t)product41; + const __uint128_t sum4 = (__uint128_t)product13 + + (__uint128_t)product22 + + (__uint128_t)product31; + const __uint128_t sum5 = (__uint128_t)product12 + + (__uint128_t)product21; + const __uint128_t sum6 = (__uint128_t)product11; + + const __uint128_t r0 = (sum0 & Word_FullMask) + + ((sum1 & Word_LoMask) << 32); + const __uint128_t r1 = (sum0 >> 64) + + ((sum1 >> 32) & Word_FullMask) + + (sum2 & Word_FullMask) + + ((sum3 << 32) & Word_HiMask); + + *lo = r0 + (r1 << 64); + *hi = (r1 >> 64) + + (sum1 >> 96) + + (sum2 >> 64) + + (sum3 >> 32) + + sum4 + + (sum5 << 32) + + (sum6 << 64); +} +#undef Word_1 +#undef Word_2 +#undef Word_3 +#undef Word_4 +#undef Word_HiMask +#undef Word_LoMask +#undef Word_FullMask +#endif // __LDBL_MANT_DIG__ == 113 +#else +#error SINGLE_PRECISION, DOUBLE_PRECISION or QUAD_PRECISION must be defined. +#endif + +#if defined(SINGLE_PRECISION) || defined(DOUBLE_PRECISION) || defined(CRT_LDBL_128BIT) +#define typeWidth (sizeof(rep_t)*CHAR_BIT) +#define exponentBits (typeWidth - significandBits - 1) +#define maxExponent ((1u << exponentBits) - 1) +#define exponentBias (maxExponent >> 1) + +#define implicitBit (REP_C(1) << significandBits) +#define significandMask (implicitBit - 1U) +#define signBit (REP_C(1) << (significandBits + exponentBits)) +#define absMask (signBit - 1U) +#define exponentMask (absMask ^ significandMask) +#define oneRep ((rep_t)exponentBias << significandBits) +#define infRep exponentMask +#define quietBit (implicitBit >> 1) +#define qnanRep (exponentMask | quietBit) + +static __inline rep_t toRep(fp_t x) { + const union { fp_t f; rep_t i; } rep = {.f = x}; + return rep.i; +} + +static __inline fp_t fromRep(rep_t x) { + const union { fp_t f; rep_t i; } rep = {.i = x}; + return rep.f; +} + +static __inline int normalize(rep_t *significand) { + const int shift = rep_clz(*significand) - rep_clz(implicitBit); + *significand <<= shift; + return 1 - shift; +} + +static __inline void wideLeftShift(rep_t *hi, rep_t *lo, int count) { + *hi = *hi << count | *lo >> (typeWidth - count); + *lo = *lo << count; +} + +static __inline void wideRightShiftWithSticky(rep_t *hi, rep_t *lo, unsigned int count) { + if (count < typeWidth) { + const bool sticky = *lo << (typeWidth - count); + *lo = *hi << (typeWidth - count) | *lo >> count | sticky; + *hi = *hi >> count; + } + else if (count < 2*typeWidth) { + const bool sticky = *hi << (2*typeWidth - count) | *lo; + *lo = *hi >> (count - typeWidth) | sticky; + *hi = 0; + } else { + const bool sticky = *hi | *lo; + *lo = sticky; + *hi = 0; + } +} + +// Implements logb methods (logb, logbf, logbl) for IEEE-754. This avoids +// pulling in a libm dependency from compiler-rt, but is not meant to replace +// it (i.e. code calling logb() should get the one from libm, not this), hence +// the __compiler_rt prefix. +static __inline fp_t __compiler_rt_logbX(fp_t x) { + rep_t rep = toRep(x); + int exp = (rep & exponentMask) >> significandBits; + + // Abnormal cases: + // 1) +/- inf returns +inf; NaN returns NaN + // 2) 0.0 returns -inf + if (exp == maxExponent) { + if (((rep & signBit) == 0) || (x != x)) { + return x; // NaN or +inf: return x + } else { + return -x; // -inf: return -x + } + } else if (x == 0.0) { + // 0.0: return -inf + return fromRep(infRep | signBit); + } + + if (exp != 0) { + // Normal number + return exp - exponentBias; // Unbias exponent + } else { + // Subnormal number; normalize and repeat + rep &= absMask; + const int shift = 1 - normalize(&rep); + exp = (rep & exponentMask) >> significandBits; + return exp - exponentBias - shift; // Unbias exponent + } +} +#endif + +#if defined(SINGLE_PRECISION) +static __inline fp_t __compiler_rt_logbf(fp_t x) { + return __compiler_rt_logbX(x); +} +#elif defined(DOUBLE_PRECISION) +static __inline fp_t __compiler_rt_logb(fp_t x) { + return __compiler_rt_logbX(x); +} +#elif defined(QUAD_PRECISION) + #if defined(CRT_LDBL_128BIT) +static __inline fp_t __compiler_rt_logbl(fp_t x) { + return __compiler_rt_logbX(x); +} + #else +// The generic implementation only works for ieee754 floating point. For other +// floating point types, continue to rely on the libm implementation for now. +static __inline long double __compiler_rt_logbl(long double x) { + return crt_logbl(x); +} + #endif +#endif + +#endif // FP_LIB_HEADER diff --git a/third_party/compiler_rt/fp_mul_impl.inc b/third_party/compiler_rt/fp_mul_impl.inc new file mode 100644 index 00000000..f77d133f --- /dev/null +++ b/third_party/compiler_rt/fp_mul_impl.inc @@ -0,0 +1,118 @@ +/* clang-format off */ +//===---- lib/fp_mul_impl.inc - floating point multiplication -----*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements soft-float multiplication with the IEEE-754 default +// rounding (to nearest, ties to even). +// +//===----------------------------------------------------------------------===// + +#include "libc/literal.h" +#include "third_party/compiler_rt/fp_lib.inc" + +static __inline fp_t __mulXf3__(fp_t a, fp_t b) { + const unsigned int aExponent = toRep(a) >> significandBits & maxExponent; + const unsigned int bExponent = toRep(b) >> significandBits & maxExponent; + const rep_t productSign = (toRep(a) ^ toRep(b)) & signBit; + + rep_t aSignificand = toRep(a) & significandMask; + rep_t bSignificand = toRep(b) & significandMask; + int scale = 0; + + // Detect if a or b is zero, denormal, infinity, or NaN. + if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) { + + const rep_t aAbs = toRep(a) & absMask; + const rep_t bAbs = toRep(b) & absMask; + + // NaN * anything = qNaN + if (aAbs > infRep) return fromRep(toRep(a) | quietBit); + // anything * NaN = qNaN + if (bAbs > infRep) return fromRep(toRep(b) | quietBit); + + if (aAbs == infRep) { + // infinity * non-zero = +/- infinity + if (bAbs) return fromRep(aAbs | productSign); + // infinity * zero = NaN + else return fromRep(qnanRep); + } + + if (bAbs == infRep) { + //? non-zero * infinity = +/- infinity + if (aAbs) return fromRep(bAbs | productSign); + // zero * infinity = NaN + else return fromRep(qnanRep); + } + + // zero * anything = +/- zero + if (!aAbs) return fromRep(productSign); + // anything * zero = +/- zero + if (!bAbs) return fromRep(productSign); + + // one or both of a or b is denormal, the other (if applicable) is a + // normal number. Renormalize one or both of a and b, and set scale to + // include the necessary exponent adjustment. + if (aAbs < implicitBit) scale += normalize(&aSignificand); + if (bAbs < implicitBit) scale += normalize(&bSignificand); + } + + // Or in the implicit significand bit. (If we fell through from the + // denormal path it was already set by normalize( ), but setting it twice + // won't hurt anything.) + aSignificand |= implicitBit; + bSignificand |= implicitBit; + + // Get the significand of a*b. Before multiplying the significands, shift + // one of them left to left-align it in the field. Thus, the product will + // have (exponentBits + 2) integral digits, all but two of which must be + // zero. Normalizing this result is just a conditional left-shift by one + // and bumping the exponent accordingly. + rep_t productHi, productLo; + wideMultiply(aSignificand, bSignificand << exponentBits, + &productHi, &productLo); + + int productExponent = aExponent + bExponent - exponentBias + scale; + + // Normalize the significand, adjust exponent if needed. + if (productHi & implicitBit) productExponent++; + else wideLeftShift(&productHi, &productLo, 1); + + // If we have overflowed the type, return +/- infinity. + if (productExponent >= maxExponent) return fromRep(infRep | productSign); + + if (productExponent <= 0) { + // Result is denormal before rounding + // + // If the result is so small that it just underflows to zero, return + // a zero of the appropriate sign. Mathematically there is no need to + // handle this case separately, but we make it a special case to + // simplify the shift logic. + const unsigned int shift = REP_C(1) - (unsigned int)productExponent; + if (shift >= typeWidth) return fromRep(productSign); + + // Otherwise, shift the significand of the result so that the round + // bit is the high bit of productLo. + wideRightShiftWithSticky(&productHi, &productLo, shift); + } + else { + // Result is normal before rounding; insert the exponent. + productHi &= significandMask; + productHi |= (rep_t)productExponent << significandBits; + } + + // Insert the sign of the result: + productHi |= productSign; + + // Final rounding. The final result may overflow to infinity, or underflow + // to zero, but those are the correct results in those cases. We use the + // default IEEE-754 round-to-nearest, ties-to-even rounding mode. + if (productLo > signBit) productHi++; + if (productLo == signBit) productHi += productHi & 1; + return fromRep(productHi); +} diff --git a/third_party/compiler_rt/fp_trunc.inc b/third_party/compiler_rt/fp_trunc.inc new file mode 100644 index 00000000..54da3359 --- /dev/null +++ b/third_party/compiler_rt/fp_trunc.inc @@ -0,0 +1,137 @@ +/* clang-format off */ +//= lib/fp_trunc_impl.inc - high precision -> low precision conversion *-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements a fairly generic conversion from a wider to a narrower +// IEEE-754 floating-point type in the default (round to nearest, ties to even) +// rounding mode. The constants and types defined following the includes below +// parameterize the conversion. +// +// This routine can be trivially adapted to support conversions to +// half-precision or from quad-precision. It does not support types that don't +// use the usual IEEE-754 interchange formats; specifically, some work would be +// needed to adapt it to (for example) the Intel 80-bit format or PowerPC +// double-double format. +// +// Note please, however, that this implementation is only intended to support +// *narrowing* operations; if you need to convert to a *wider* floating-point +// type (e.g. float -> double), then this routine will not do what you want it +// to. +// +// It also requires that integer types at least as large as both formats +// are available on the target platform; this may pose a problem when trying +// to add support for quad on some 32-bit systems, for example. +// +// Finally, the following assumptions are made: +// +// 1. floating-point types and integer types have the same endianness on the +// target platform +// +// 2. quiet NaNs, if supported, are indicated by the leading bit of the +// significand field being set +// +//===----------------------------------------------------------------------===// + +#include "third_party/compiler_rt/fp_trunc_common.inc" +#include "libc/literal.h" + +static __inline dst_t __truncXfYf2__(src_t a) { + // Various constants whose values follow from the type parameters. + // Any reasonable optimizer will fold and propagate all of these. + const int srcBits = sizeof(src_t)*CHAR_BIT; + const int srcExpBits = srcBits - srcSigBits - 1; + const int srcInfExp = (1u << srcExpBits) - 1; + const int srcExpBias = srcInfExp >> 1; + + const src_rep_t srcMinNormal = SRC_REP_C(1) << srcSigBits; + const src_rep_t srcSignificandMask = srcMinNormal - 1; + const src_rep_t srcInfinity = (src_rep_t)srcInfExp << srcSigBits; + const src_rep_t srcSignMask = SRC_REP_C(1) << (srcSigBits + srcExpBits); + const src_rep_t srcAbsMask = srcSignMask - 1; + const src_rep_t roundMask = (SRC_REP_C(1) << (srcSigBits - dstSigBits)) - 1; + const src_rep_t halfway = SRC_REP_C(1) << (srcSigBits - dstSigBits - 1); + const src_rep_t srcQNaN = SRC_REP_C(1) << (srcSigBits - 1); + const src_rep_t srcNaNCode = srcQNaN - 1; + + const int dstBits = sizeof(dst_t)*CHAR_BIT; + const int dstExpBits = dstBits - dstSigBits - 1; + const int dstInfExp = (1u << dstExpBits) - 1; + const int dstExpBias = dstInfExp >> 1; + + const int underflowExponent = srcExpBias + 1 - dstExpBias; + const int overflowExponent = srcExpBias + dstInfExp - dstExpBias; + const src_rep_t underflow = (src_rep_t)underflowExponent << srcSigBits; + const src_rep_t overflow = (src_rep_t)overflowExponent << srcSigBits; + + const dst_rep_t dstQNaN = DST_REP_C(1) << (dstSigBits - 1); + const dst_rep_t dstNaNCode = dstQNaN - 1; + + // Break a into a sign and representation of the absolute value + const src_rep_t aRep = srcToRep(a); + const src_rep_t aAbs = aRep & srcAbsMask; + const src_rep_t sign = aRep & srcSignMask; + dst_rep_t absResult; + + if (aAbs - underflow < aAbs - overflow) { + // The exponent of a is within the range of normal numbers in the + // destination format. We can convert by simply right-shifting with + // rounding and adjusting the exponent. + absResult = aAbs >> (srcSigBits - dstSigBits); + absResult -= (dst_rep_t)(srcExpBias - dstExpBias) << dstSigBits; + + const src_rep_t roundBits = aAbs & roundMask; + // Round to nearest + if (roundBits > halfway) + absResult++; + // Ties to even + else if (roundBits == halfway) + absResult += absResult & 1; + } + else if (aAbs > srcInfinity) { + // a is NaN. + // Conjure the result by beginning with infinity, setting the qNaN + // bit and inserting the (truncated) trailing NaN field. + absResult = (dst_rep_t)dstInfExp << dstSigBits; + absResult |= dstQNaN; + absResult |= ((aAbs & srcNaNCode) >> (srcSigBits - dstSigBits)) & dstNaNCode; + } + else if (aAbs >= overflow) { + // a overflows to infinity. + absResult = (dst_rep_t)dstInfExp << dstSigBits; + } + else { + // a underflows on conversion to the destination type or is an exact + // zero. The result may be a denormal or zero. Extract the exponent + // to get the shift amount for the denormalization. + const int aExp = aAbs >> srcSigBits; + const int shift = srcExpBias - dstExpBias - aExp + 1; + + const src_rep_t significand = (aRep & srcSignificandMask) | srcMinNormal; + + // Right shift by the denormalization amount with sticky. + if (shift > srcSigBits) { + absResult = 0; + } else { + const bool sticky = significand << (srcBits - shift); + src_rep_t denormalizedSignificand = significand >> shift | sticky; + absResult = denormalizedSignificand >> (srcSigBits - dstSigBits); + const src_rep_t roundBits = denormalizedSignificand & roundMask; + // Round to nearest + if (roundBits > halfway) + absResult++; + // Ties to even + else if (roundBits == halfway) + absResult += absResult & 1; + } + } + + // Apply the signbit to (dst_t)abs(a). + const dst_rep_t result = absResult | sign >> (srcBits - dstBits); + return dstFromRep(result); +} diff --git a/third_party/compiler_rt/fp_trunc_common.inc b/third_party/compiler_rt/fp_trunc_common.inc new file mode 100644 index 00000000..bd4e9fb8 --- /dev/null +++ b/third_party/compiler_rt/fp_trunc_common.inc @@ -0,0 +1,77 @@ +/* clang-format off */ +//=== lib/fp_trunc.h - high precision -> low precision conversion *- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Set source and destination precision setting +// +//===----------------------------------------------------------------------===// + +#ifndef FP_TRUNC_HEADER +#define FP_TRUNC_HEADER + +#include "third_party/compiler_rt/int_lib.h" + +#if defined SRC_SINGLE +typedef float src_t; +typedef uint32_t src_rep_t; +#define SRC_REP_C UINT32_C +static const int srcSigBits = 23; + +#elif defined SRC_DOUBLE +typedef double src_t; +typedef uint64_t src_rep_t; +#define SRC_REP_C UINT64_C +static const int srcSigBits = 52; + +#elif defined SRC_QUAD +typedef long double src_t; +typedef __uint128_t src_rep_t; +#define SRC_REP_C (__uint128_t) +static const int srcSigBits = 112; + +#else +#error Source should be double precision or quad precision! +#endif //end source precision + +#if defined DST_DOUBLE +typedef double dst_t; +typedef uint64_t dst_rep_t; +#define DST_REP_C UINT64_C +static const int dstSigBits = 52; + +#elif defined DST_SINGLE +typedef float dst_t; +typedef uint32_t dst_rep_t; +#define DST_REP_C UINT32_C +static const int dstSigBits = 23; + +#elif defined DST_HALF +typedef uint16_t dst_t; +typedef uint16_t dst_rep_t; +#define DST_REP_C UINT16_C +static const int dstSigBits = 10; + +#else +#error Destination should be single precision or double precision! +#endif //end destination precision + +// End of specialization parameters. Two helper routines for conversion to and +// from the representation of floating-point data as integer values follow. + +static __inline src_rep_t srcToRep(src_t x) { + const union { src_t f; src_rep_t i; } rep = {.f = x}; + return rep.i; +} + +static __inline dst_t dstFromRep(dst_rep_t x) { + const union { dst_t f; dst_rep_t i; } rep = {.i = x}; + return rep.f; +} + +#endif // FP_TRUNC_HEADER diff --git a/third_party/compiler_rt/fp_trunc_impl.inc b/third_party/compiler_rt/fp_trunc_impl.inc new file mode 100644 index 00000000..d029883b --- /dev/null +++ b/third_party/compiler_rt/fp_trunc_impl.inc @@ -0,0 +1,137 @@ +/* clang-format off */ +//= lib/fp_trunc_impl.inc - high precision -> low precision conversion *-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements a fairly generic conversion from a wider to a narrower +// IEEE-754 floating-point type in the default (round to nearest, ties to even) +// rounding mode. The constants and types defined following the includes below +// parameterize the conversion. +// +// This routine can be trivially adapted to support conversions to +// half-precision or from quad-precision. It does not support types that don't +// use the usual IEEE-754 interchange formats; specifically, some work would be +// needed to adapt it to (for example) the Intel 80-bit format or PowerPC +// double-double format. +// +// Note please, however, that this implementation is only intended to support +// *narrowing* operations; if you need to convert to a *wider* floating-point +// type (e.g. float -> double), then this routine will not do what you want it +// to. +// +// It also requires that integer types at least as large as both formats +// are available on the target platform; this may pose a problem when trying +// to add support for quad on some 32-bit systems, for example. +// +// Finally, the following assumptions are made: +// +// 1. floating-point types and integer types have the same endianness on the +// target platform +// +// 2. quiet NaNs, if supported, are indicated by the leading bit of the +// significand field being set +// +//===----------------------------------------------------------------------===// + +#include "libc/literal.h" +#include "third_party/compiler_rt/fp_trunc_common.inc" + +static __inline dst_t __truncXfYf2__(src_t a) { + // Various constants whose values follow from the type parameters. + // Any reasonable optimizer will fold and propagate all of these. + const int srcBits = sizeof(src_t)*CHAR_BIT; + const int srcExpBits = srcBits - srcSigBits - 1; + const int srcInfExp = (1u << srcExpBits) - 1; + const int srcExpBias = srcInfExp >> 1; + + const src_rep_t srcMinNormal = SRC_REP_C(1) << srcSigBits; + const src_rep_t srcSignificandMask = srcMinNormal - 1; + const src_rep_t srcInfinity = (src_rep_t)srcInfExp << srcSigBits; + const src_rep_t srcSignMask = SRC_REP_C(1) << (srcSigBits + srcExpBits); + const src_rep_t srcAbsMask = srcSignMask - 1; + const src_rep_t roundMask = (SRC_REP_C(1) << (srcSigBits - dstSigBits)) - 1; + const src_rep_t halfway = SRC_REP_C(1) << (srcSigBits - dstSigBits - 1); + const src_rep_t srcQNaN = SRC_REP_C(1) << (srcSigBits - 1); + const src_rep_t srcNaNCode = srcQNaN - 1; + + const int dstBits = sizeof(dst_t)*CHAR_BIT; + const int dstExpBits = dstBits - dstSigBits - 1; + const int dstInfExp = (1u << dstExpBits) - 1; + const int dstExpBias = dstInfExp >> 1; + + const int underflowExponent = srcExpBias + 1 - dstExpBias; + const int overflowExponent = srcExpBias + dstInfExp - dstExpBias; + const src_rep_t underflow = (src_rep_t)underflowExponent << srcSigBits; + const src_rep_t overflow = (src_rep_t)overflowExponent << srcSigBits; + + const dst_rep_t dstQNaN = DST_REP_C(1) << (dstSigBits - 1); + const dst_rep_t dstNaNCode = dstQNaN - 1; + + // Break a into a sign and representation of the absolute value + const src_rep_t aRep = srcToRep(a); + const src_rep_t aAbs = aRep & srcAbsMask; + const src_rep_t sign = aRep & srcSignMask; + dst_rep_t absResult; + + if (aAbs - underflow < aAbs - overflow) { + // The exponent of a is within the range of normal numbers in the + // destination format. We can convert by simply right-shifting with + // rounding and adjusting the exponent. + absResult = aAbs >> (srcSigBits - dstSigBits); + absResult -= (dst_rep_t)(srcExpBias - dstExpBias) << dstSigBits; + + const src_rep_t roundBits = aAbs & roundMask; + // Round to nearest + if (roundBits > halfway) + absResult++; + // Ties to even + else if (roundBits == halfway) + absResult += absResult & 1; + } + else if (aAbs > srcInfinity) { + // a is NaN. + // Conjure the result by beginning with infinity, setting the qNaN + // bit and inserting the (truncated) trailing NaN field. + absResult = (dst_rep_t)dstInfExp << dstSigBits; + absResult |= dstQNaN; + absResult |= ((aAbs & srcNaNCode) >> (srcSigBits - dstSigBits)) & dstNaNCode; + } + else if (aAbs >= overflow) { + // a overflows to infinity. + absResult = (dst_rep_t)dstInfExp << dstSigBits; + } + else { + // a underflows on conversion to the destination type or is an exact + // zero. The result may be a denormal or zero. Extract the exponent + // to get the shift amount for the denormalization. + const int aExp = aAbs >> srcSigBits; + const int shift = srcExpBias - dstExpBias - aExp + 1; + + const src_rep_t significand = (aRep & srcSignificandMask) | srcMinNormal; + + // Right shift by the denormalization amount with sticky. + if (shift > srcSigBits) { + absResult = 0; + } else { + const bool sticky = significand << (srcBits - shift); + src_rep_t denormalizedSignificand = significand >> shift | sticky; + absResult = denormalizedSignificand >> (srcSigBits - dstSigBits); + const src_rep_t roundBits = denormalizedSignificand & roundMask; + // Round to nearest + if (roundBits > halfway) + absResult++; + // Ties to even + else if (roundBits == halfway) + absResult += absResult & 1; + } + } + + // Apply the signbit to (dst_t)abs(a). + const dst_rep_t result = absResult | sign >> (srcBits - dstBits); + return dstFromRep(result); +} diff --git a/third_party/compiler_rt/int_endianness.h b/third_party/compiler_rt/int_endianness.h new file mode 100644 index 00000000..f5cd4bdf --- /dev/null +++ b/third_party/compiler_rt/int_endianness.h @@ -0,0 +1,23 @@ +/* clang-format off */ +/* ===-- int_endianness.h - configuration header for compiler-rt ------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file is a configuration header for compiler-rt. + * This file is not part of the interface of this library. + * + * ===----------------------------------------------------------------------=== + */ + +#ifndef INT_ENDIANNESS_H +#define INT_ENDIANNESS_H + +#define _YUGA_LITTLE_ENDIAN 1 +#define _YUGA_BIG_ENDIAN 0 + +#endif /* INT_ENDIANNESS_H */ diff --git a/third_party/compiler_rt/int_lib.h b/third_party/compiler_rt/int_lib.h new file mode 100644 index 00000000..9e80c3a6 --- /dev/null +++ b/third_party/compiler_rt/int_lib.h @@ -0,0 +1,120 @@ +/* clang-format off */ +/* ===-- int_lib.h - configuration header for compiler-rt -----------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file is a configuration header for compiler-rt. + * This file is not part of the interface of this library. + * + * ===----------------------------------------------------------------------=== + */ + +#ifndef INT_LIB_H +#define INT_LIB_H + +/* Assumption: lool univac arithmetic */ +/* Assumption: lool cray signed shift */ +/* Assumption: lool pdp11 float byte order */ + +#if defined(__ELF__) +#define FNALIAS(alias_name, original_name) \ + void alias_name() __attribute__((__alias__(#original_name))) +#define COMPILER_RT_ALIAS(aliasee) __attribute__((__alias__(#aliasee))) +#else +#define FNALIAS(alias, name) _Pragma("GCC error(\"alias unsupported on this file format\")") +#define COMPILER_RT_ALIAS(aliasee) _Pragma("GCC error(\"alias unsupported on this file format\")") +#endif + +/* ABI macro definitions */ + +#if __ARM_EABI__ +# ifdef COMPILER_RT_ARMHF_TARGET +# define COMPILER_RT_ABI +# else +# define COMPILER_RT_ABI __attribute__((__pcs__("aapcs"))) +# endif +#else +# define COMPILER_RT_ABI +#endif + +#define AEABI_RTABI __attribute__((__pcs__("aapcs"))) + +#ifdef _MSC_VER +#define ALWAYS_INLINE __forceinline +#define NORETURN __declspec(noreturn) +#define UNUSED +#else +#define ALWAYS_INLINE __attribute__((__always_inline__)) +#define NORETURN __attribute__((__noreturn__)) +#define UNUSED __attribute__((__unused__)) +#endif + +#include "libc/literal.h" +#include "libc/math.h" + +/* Include the commonly used internal type definitions. */ +#include "third_party/compiler_rt/int_types.h" + +/* Include internal utility function declarations. */ +#include "third_party/compiler_rt/int_util.h" + +COMPILER_RT_ABI si_int __paritysi2(si_int a); +COMPILER_RT_ABI si_int __paritydi2(di_int a); + +COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b); +COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b); +COMPILER_RT_ABI su_int __udivsi3(su_int n, su_int d); + +COMPILER_RT_ABI su_int __udivmodsi4(su_int a, su_int b, su_int* rem); +COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int* rem); +#ifdef CRT_HAS_128BIT +COMPILER_RT_ABI si_int __clzti2(ti_int a); +COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem); +#endif + +/* Definitions for builtins unavailable on MSVC */ +#if defined(_MSC_VER) && !defined(__clang__) +#include + +uint32_t __inline __builtin_ctz(uint32_t value) { + unsigned long trailing_zero = 0; + if (_BitScanForward(&trailing_zero, value)) + return trailing_zero; + return 32; +} + +uint32_t __inline __builtin_clz(uint32_t value) { + unsigned long leading_zero = 0; + if (_BitScanReverse(&leading_zero, value)) + return 31 - leading_zero; + return 32; +} + +#if defined(_M_ARM) || defined(_M_X64) +uint32_t __inline __builtin_clzll(uint64_t value) { + unsigned long leading_zero = 0; + if (_BitScanReverse64(&leading_zero, value)) + return 63 - leading_zero; + return 64; +} +#else +uint32_t __inline __builtin_clzll(uint64_t value) { + if (value == 0) + return 64; + uint32_t msh = (uint32_t)(value >> 32); + uint32_t lsh = (uint32_t)(value & 0xFFFFFFFF); + if (msh != 0) + return __builtin_clz(msh); + return 32 + __builtin_clz(lsh); +} +#endif + +#define __builtin_clzl __builtin_clzll +#endif /* defined(_MSC_VER) && !defined(__clang__) */ + +#endif /* INT_LIB_H */ diff --git a/third_party/compiler_rt/int_math.h b/third_party/compiler_rt/int_math.h new file mode 100644 index 00000000..721478ab --- /dev/null +++ b/third_party/compiler_rt/int_math.h @@ -0,0 +1,105 @@ +/* clang-format off */ +/* ===-- int_math.h - internal math inlines ---------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===-----------------------------------------------------------------------=== + * + * This file is not part of the interface of this library. + * + * This file defines substitutes for the libm functions used in some of the + * compiler-rt implementations, defined in such a way that there is not a direct + * dependency on libm or math.h. Instead, we use the compiler builtin versions + * where available. This reduces our dependencies on the system SDK by foisting + * the responsibility onto the compiler. + * + * ===-----------------------------------------------------------------------=== + */ + +#ifndef INT_MATH_H +#define INT_MATH_H + +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +#define CRT_INFINITY INFINITY +#else +#define CRT_INFINITY __builtin_huge_valf() +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +#define crt_isfinite(x) _finite((x)) +#define crt_isinf(x) !_finite((x)) +#define crt_isnan(x) _isnan((x)) +#else +/* Define crt_isfinite in terms of the builtin if available, otherwise provide + * an alternate version in terms of our other functions. This supports some + * versions of GCC which didn't have __builtin_isfinite. + */ +#if __has_builtin(__builtin_isfinite) +# define crt_isfinite(x) __builtin_isfinite((x)) +#elif defined(__GNUC__) +# define crt_isfinite(x) \ + __extension__(({ \ + __typeof((x)) x_ = (x); \ + !crt_isinf(x_) && !crt_isnan(x_); \ + })) +#else +# error "Do not know how to check for infinity" +#endif /* __has_builtin(__builtin_isfinite) */ +#define crt_isinf(x) __builtin_isinf((x)) +#define crt_isnan(x) __builtin_isnan((x)) +#endif /* _MSC_VER */ + +#if defined(_MSC_VER) && !defined(__clang__) +#define crt_copysign(x, y) copysign((x), (y)) +#define crt_copysignf(x, y) copysignf((x), (y)) +#define crt_copysignl(x, y) copysignl((x), (y)) +#else +#define crt_copysign(x, y) __builtin_copysign((x), (y)) +#define crt_copysignf(x, y) __builtin_copysignf((x), (y)) +#define crt_copysignl(x, y) __builtin_copysignl((x), (y)) +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +#define crt_fabs(x) fabs((x)) +#define crt_fabsf(x) fabsf((x)) +#define crt_fabsl(x) fabs((x)) +#else +#define crt_fabs(x) __builtin_fabs((x)) +#define crt_fabsf(x) __builtin_fabsf((x)) +#define crt_fabsl(x) __builtin_fabsl((x)) +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +#define crt_fmax(x, y) __max((x), (y)) +#define crt_fmaxf(x, y) __max((x), (y)) +#define crt_fmaxl(x, y) __max((x), (y)) +#else +#define crt_fmax(x, y) __builtin_fmax((x), (y)) +#define crt_fmaxf(x, y) __builtin_fmaxf((x), (y)) +#define crt_fmaxl(x, y) __builtin_fmaxl((x), (y)) +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +#define crt_logbl(x) logbl((x)) +#else +#define crt_logbl(x) __builtin_logbl((x)) +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +#define crt_scalbn(x, y) scalbn((x), (y)) +#define crt_scalbnf(x, y) scalbnf((x), (y)) +#define crt_scalbnl(x, y) scalbnl((x), (y)) +#else +#define crt_scalbn(x, y) __builtin_scalbn((x), (y)) +#define crt_scalbnf(x, y) __builtin_scalbnf((x), (y)) +#define crt_scalbnl(x, y) __builtin_scalbnl((x), (y)) +#endif + +#endif /* INT_MATH_H */ diff --git a/third_party/compiler_rt/int_types.h b/third_party/compiler_rt/int_types.h new file mode 100644 index 00000000..02654e29 --- /dev/null +++ b/third_party/compiler_rt/int_types.h @@ -0,0 +1,162 @@ +/* clang-format off */ +/* clang-format off */ +/* ===-- int_lib.h - configuration header for compiler-rt -----------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file is not part of the interface of this library. + * + * This file defines various standard types, most importantly a number of unions + * used to access parts of larger types. + * + * ===----------------------------------------------------------------------=== + */ + +#ifndef INT_TYPES_H +#define INT_TYPES_H + +#include "third_party/compiler_rt/int_endianness.h" + +/* si_int is defined in Linux sysroot's asm-generic/siginfo.h */ +#ifdef si_int +#undef si_int +#endif +typedef int si_int; +typedef unsigned su_int; + +typedef long long di_int; +typedef unsigned long long du_int; + +typedef union +{ + di_int all; + struct + { +#if _YUGA_LITTLE_ENDIAN + su_int low; + si_int high; +#else + si_int high; + su_int low; +#endif /* _YUGA_LITTLE_ENDIAN */ + }s; +} dwords; + +typedef union +{ + du_int all; + struct + { +#if _YUGA_LITTLE_ENDIAN + su_int low; + su_int high; +#else + su_int high; + su_int low; +#endif /* _YUGA_LITTLE_ENDIAN */ + }s; +} udwords; + +#ifdef CRT_HAS_128BIT +typedef int ti_int __attribute__ ((mode (TI))); +typedef unsigned tu_int __attribute__ ((mode (TI))); + +typedef union +{ + ti_int all; + struct + { +#if _YUGA_LITTLE_ENDIAN + du_int low; + di_int high; +#else + di_int high; + du_int low; +#endif /* _YUGA_LITTLE_ENDIAN */ + }s; +} twords; + +typedef union +{ + tu_int all; + struct + { +#if _YUGA_LITTLE_ENDIAN + du_int low; + du_int high; +#else + du_int high; + du_int low; +#endif /* _YUGA_LITTLE_ENDIAN */ + }s; +} utwords; + +static __inline ti_int make_ti(di_int h, di_int l) { + twords r; + r.s.high = h; + r.s.low = l; + return r.all; +} + +static __inline tu_int make_tu(du_int h, du_int l) { + utwords r; + r.s.high = h; + r.s.low = l; + return r.all; +} + +#endif /* CRT_HAS_128BIT */ + +typedef union +{ + su_int u; + float f; +} float_bits; + +typedef union +{ + udwords u; + double f; +} double_bits; + +typedef struct +{ +#if _YUGA_LITTLE_ENDIAN + udwords low; + udwords high; +#else + udwords high; + udwords low; +#endif /* _YUGA_LITTLE_ENDIAN */ +} uqwords; + +typedef union +{ + uqwords u; + long double f; +} long_double_bits; + +#if __STDC_VERSION__ >= 199901L +typedef float _Complex Fcomplex; +typedef double _Complex Dcomplex; +typedef long double _Complex Lcomplex; + +#define COMPLEX_REAL(x) __real__(x) +#define COMPLEX_IMAGINARY(x) __imag__(x) +#else +typedef struct { float real, imaginary; } Fcomplex; + +typedef struct { double real, imaginary; } Dcomplex; + +typedef struct { long double real, imaginary; } Lcomplex; + +#define COMPLEX_REAL(x) (x).real +#define COMPLEX_IMAGINARY(x) (x).imaginary +#endif +#endif /* INT_TYPES_H */ + diff --git a/third_party/compiler_rt/int_util.h b/third_party/compiler_rt/int_util.h new file mode 100644 index 00000000..73e99dac --- /dev/null +++ b/third_party/compiler_rt/int_util.h @@ -0,0 +1,37 @@ +/* clang-format off */ +/* ===-- int_util.h - internal utility functions ----------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===-----------------------------------------------------------------------=== + * + * This file is not part of the interface of this library. + * + * This file defines non-inline utilities which are available for use in the + * library. The function definitions themselves are all contained in int_util.c + * which will always be compiled into any compiler-rt library. + * + * ===-----------------------------------------------------------------------=== + */ + +#ifndef INT_UTIL_H +#define INT_UTIL_H +#include "libc/runtime/runtime.h" + +/** \brief Trigger a program abort (or panic for kernel code). */ +#define compilerrt_abort() abort() + +/* #define compilerrt_abort() __compilerrt_abort_impl(__FILE__, __LINE__, __func__) */ + +noreturn void __compilerrt_abort_impl(const char *file, int line, + const char *function); + +#define COMPILE_TIME_ASSERT(expr) COMPILE_TIME_ASSERT1(expr, __COUNTER__) +#define COMPILE_TIME_ASSERT1(expr, cnt) COMPILE_TIME_ASSERT2(expr, cnt) +#define COMPILE_TIME_ASSERT2(expr, cnt) \ + typedef char ct_assert_##cnt[(expr) ? 1 : -1] UNUSED + +#endif /* INT_UTIL_H */ diff --git a/third_party/compiler_rt/lshrdi3.c b/third_party/compiler_rt/lshrdi3.c new file mode 100644 index 00000000..02fedf83 --- /dev/null +++ b/third_party/compiler_rt/lshrdi3.c @@ -0,0 +1,48 @@ +/* clang-format off */ +/* ===-- lshrdi3.c - Implement __lshrdi3 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __lshrdi3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: logical a >> b */ + +/* Precondition: 0 <= b < bits_in_dword */ + +COMPILER_RT_ABI di_int +__lshrdi3(di_int a, si_int b) +{ + const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT); + udwords input; + udwords result; + input.all = a; + if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */ + { + result.s.high = 0; + result.s.low = input.s.high >> (b - bits_in_word); + } + else /* 0 <= b < bits_in_word */ + { + if (b == 0) + return a; + result.s.high = input.s.high >> b; + result.s.low = (input.s.high << (bits_in_word - b)) | (input.s.low >> b); + } + return result.all; +} + +#if defined(__ARM_EABI__) +AEABI_RTABI di_int __aeabi_llsr(di_int a, si_int b) COMPILER_RT_ALIAS(__lshrdi3); +#endif diff --git a/third_party/compiler_rt/lshrti3.c b/third_party/compiler_rt/lshrti3.c new file mode 100644 index 00000000..7deb749e --- /dev/null +++ b/third_party/compiler_rt/lshrti3.c @@ -0,0 +1,48 @@ +/* clang-format off */ +/* ===-- lshrti3.c - Implement __lshrti3 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __lshrti3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: logical a >> b */ + +/* Precondition: 0 <= b < bits_in_tword */ + +COMPILER_RT_ABI ti_int +__lshrti3(ti_int a, si_int b) +{ + const int bits_in_dword = (int)(sizeof(di_int) * CHAR_BIT); + utwords input; + utwords result; + input.all = a; + if (b & bits_in_dword) /* bits_in_dword <= b < bits_in_tword */ + { + result.s.high = 0; + result.s.low = input.s.high >> (b - bits_in_dword); + } + else /* 0 <= b < bits_in_dword */ + { + if (b == 0) + return a; + result.s.high = input.s.high >> b; + result.s.low = (input.s.high << (bits_in_dword - b)) | (input.s.low >> b); + } + return result.all; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/mingw_fixfloat.c b/third_party/compiler_rt/mingw_fixfloat.c new file mode 100644 index 00000000..6078cc2e --- /dev/null +++ b/third_party/compiler_rt/mingw_fixfloat.c @@ -0,0 +1,39 @@ +/* clang-format off */ +/* ===-- mingw_fixfloat.c - Wrap int/float conversions for arm/windows -----=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +COMPILER_RT_ABI di_int __fixdfdi(double a); +COMPILER_RT_ABI di_int __fixsfdi(float a); +COMPILER_RT_ABI du_int __fixunsdfdi(double a); +COMPILER_RT_ABI du_int __fixunssfdi(float a); +COMPILER_RT_ABI double __floatdidf(di_int a); +COMPILER_RT_ABI float __floatdisf(di_int a); +COMPILER_RT_ABI double __floatundidf(du_int a); +COMPILER_RT_ABI float __floatundisf(du_int a); + +COMPILER_RT_ABI di_int __dtoi64(double a) { return __fixdfdi(a); } + +COMPILER_RT_ABI di_int __stoi64(float a) { return __fixsfdi(a); } + +COMPILER_RT_ABI du_int __dtou64(double a) { return __fixunsdfdi(a); } + +COMPILER_RT_ABI du_int __stou64(float a) { return __fixunssfdi(a); } + +COMPILER_RT_ABI double __i64tod(di_int a) { return __floatdidf(a); } + +COMPILER_RT_ABI float __i64tos(di_int a) { return __floatdisf(a); } + +COMPILER_RT_ABI double __u64tod(du_int a) { return __floatundidf(a); } + +COMPILER_RT_ABI float __u64tos(du_int a) { return __floatundisf(a); } diff --git a/third_party/compiler_rt/moddi3.c b/third_party/compiler_rt/moddi3.c new file mode 100644 index 00000000..62bb2851 --- /dev/null +++ b/third_party/compiler_rt/moddi3.c @@ -0,0 +1,33 @@ +/* clang-format off */ +/*===-- moddi3.c - Implement __moddi3 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __moddi3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a % b */ + +COMPILER_RT_ABI di_int +__moddi3(di_int a, di_int b) +{ + const int bits_in_dword_m1 = (int)(sizeof(di_int) * CHAR_BIT) - 1; + di_int s = b >> bits_in_dword_m1; /* s = b < 0 ? -1 : 0 */ + b = (b ^ s) - s; /* negate if s == -1 */ + s = a >> bits_in_dword_m1; /* s = a < 0 ? -1 : 0 */ + a = (a ^ s) - s; /* negate if s == -1 */ + du_int r; + __udivmoddi4(a, b, &r); + return ((di_int)r ^ s) - s; /* negate if s == -1 */ +} diff --git a/third_party/compiler_rt/modsi3.c b/third_party/compiler_rt/modsi3.c new file mode 100644 index 00000000..7d65ae3e --- /dev/null +++ b/third_party/compiler_rt/modsi3.c @@ -0,0 +1,26 @@ +/* clang-format off */ +/* ===-- modsi3.c - Implement __modsi3 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __modsi3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a % b */ + +COMPILER_RT_ABI si_int +__modsi3(si_int a, si_int b) +{ + return a - __divsi3(a, b) * b; +} diff --git a/third_party/compiler_rt/modti3.c b/third_party/compiler_rt/modti3.c new file mode 100644 index 00000000..5a30fd22 --- /dev/null +++ b/third_party/compiler_rt/modti3.c @@ -0,0 +1,37 @@ +/* clang-format off */ +/* ===-- modti3.c - Implement __modti3 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __modti3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/*Returns: a % b */ + +COMPILER_RT_ABI ti_int +__modti3(ti_int a, ti_int b) +{ + const int bits_in_tword_m1 = (int)(sizeof(ti_int) * CHAR_BIT) - 1; + ti_int s = b >> bits_in_tword_m1; /* s = b < 0 ? -1 : 0 */ + b = (b ^ s) - s; /* negate if s == -1 */ + s = a >> bits_in_tword_m1; /* s = a < 0 ? -1 : 0 */ + a = (a ^ s) - s; /* negate if s == -1 */ + tu_int r; + __udivmodti4(a, b, &r); + return ((ti_int)r ^ s) - s; /* negate if s == -1 */ +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/muldc3.c b/third_party/compiler_rt/muldc3.c new file mode 100644 index 00000000..5b54fe39 --- /dev/null +++ b/third_party/compiler_rt/muldc3.c @@ -0,0 +1,76 @@ +/* clang-format off */ +/* ===-- muldc3.c - Implement __muldc3 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __muldc3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" +#include "third_party/compiler_rt/int_math.h" + +/* Returns: the product of a + ib and c + id */ + +COMPILER_RT_ABI Dcomplex +__muldc3(double __a, double __b, double __c, double __d) +{ + double __ac = __a * __c; + double __bd = __b * __d; + double __ad = __a * __d; + double __bc = __b * __c; + Dcomplex z; + COMPLEX_REAL(z) = __ac - __bd; + COMPLEX_IMAGINARY(z) = __ad + __bc; + if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z))) + { + int __recalc = 0; + if (crt_isinf(__a) || crt_isinf(__b)) + { + __a = crt_copysign(crt_isinf(__a) ? 1 : 0, __a); + __b = crt_copysign(crt_isinf(__b) ? 1 : 0, __b); + if (crt_isnan(__c)) + __c = crt_copysign(0, __c); + if (crt_isnan(__d)) + __d = crt_copysign(0, __d); + __recalc = 1; + } + if (crt_isinf(__c) || crt_isinf(__d)) + { + __c = crt_copysign(crt_isinf(__c) ? 1 : 0, __c); + __d = crt_copysign(crt_isinf(__d) ? 1 : 0, __d); + if (crt_isnan(__a)) + __a = crt_copysign(0, __a); + if (crt_isnan(__b)) + __b = crt_copysign(0, __b); + __recalc = 1; + } + if (!__recalc && (crt_isinf(__ac) || crt_isinf(__bd) || + crt_isinf(__ad) || crt_isinf(__bc))) + { + if (crt_isnan(__a)) + __a = crt_copysign(0, __a); + if (crt_isnan(__b)) + __b = crt_copysign(0, __b); + if (crt_isnan(__c)) + __c = crt_copysign(0, __c); + if (crt_isnan(__d)) + __d = crt_copysign(0, __d); + __recalc = 1; + } + if (__recalc) + { + COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c - __b * __d); + COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__a * __d + __b * __c); + } + } + return z; +} diff --git a/third_party/compiler_rt/muldf3.c b/third_party/compiler_rt/muldf3.c new file mode 100644 index 00000000..07fe0a17 --- /dev/null +++ b/third_party/compiler_rt/muldf3.c @@ -0,0 +1,33 @@ +/* clang-format off */ +//===-- lib/muldf3.c - Double-precision multiplication ------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements double-precision soft-float multiplication +// with the IEEE-754 default rounding (to nearest, ties to even). +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define DOUBLE_PRECISION +#include "third_party/compiler_rt/fp_mul_impl.inc" + +COMPILER_RT_ABI fp_t __muldf3(fp_t a, fp_t b) { + return __mulXf3__(a, b); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI fp_t __aeabi_dmul(fp_t a, fp_t b) { + return __muldf3(a, b); +} +#else +AEABI_RTABI fp_t __aeabi_dmul(fp_t a, fp_t b) COMPILER_RT_ALIAS(__muldf3); +#endif +#endif diff --git a/third_party/compiler_rt/muldi3.c b/third_party/compiler_rt/muldi3.c new file mode 100644 index 00000000..ecf3065c --- /dev/null +++ b/third_party/compiler_rt/muldi3.c @@ -0,0 +1,61 @@ +/* clang-format off */ +/* ===-- muldi3.c - Implement __muldi3 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __muldi3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a * b */ + +static +di_int +__muldsi3(su_int a, su_int b) +{ + dwords r; + const int bits_in_word_2 = (int)(sizeof(si_int) * CHAR_BIT) / 2; + const su_int lower_mask = (su_int)~0 >> bits_in_word_2; + r.s.low = (a & lower_mask) * (b & lower_mask); + su_int t = r.s.low >> bits_in_word_2; + r.s.low &= lower_mask; + t += (a >> bits_in_word_2) * (b & lower_mask); + r.s.low += (t & lower_mask) << bits_in_word_2; + r.s.high = t >> bits_in_word_2; + t = r.s.low >> bits_in_word_2; + r.s.low &= lower_mask; + t += (b >> bits_in_word_2) * (a & lower_mask); + r.s.low += (t & lower_mask) << bits_in_word_2; + r.s.high += t >> bits_in_word_2; + r.s.high += (a >> bits_in_word_2) * (b >> bits_in_word_2); + return r.all; +} + +/* Returns: a * b */ + +COMPILER_RT_ABI di_int +__muldi3(di_int a, di_int b) +{ + dwords x; + x.all = a; + dwords y; + y.all = b; + dwords r; + r.all = __muldsi3(x.s.low, y.s.low); + r.s.high += x.s.high * y.s.low + x.s.low * y.s.high; + return r.all; +} + +#if defined(__ARM_EABI__) +AEABI_RTABI di_int __aeabi_lmul(di_int a, di_int b) COMPILER_RT_ALIAS(__muldi3); +#endif diff --git a/third_party/compiler_rt/mulodi4.c b/third_party/compiler_rt/mulodi4.c new file mode 100644 index 00000000..d5637f58 --- /dev/null +++ b/third_party/compiler_rt/mulodi4.c @@ -0,0 +1,61 @@ +/* clang-format off */ +/*===-- mulodi4.c - Implement __mulodi4 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __mulodi4 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a * b */ + +/* Effects: sets *overflow to 1 if a * b overflows */ + +COMPILER_RT_ABI di_int +__mulodi4(di_int a, di_int b, int* overflow) +{ + const int N = (int)(sizeof(di_int) * CHAR_BIT); + const di_int MIN = (di_int)1 << (N-1); + const di_int MAX = ~MIN; + *overflow = 0; + di_int result = a * b; + if (a == MIN) + { + if (b != 0 && b != 1) + *overflow = 1; + return result; + } + if (b == MIN) + { + if (a != 0 && a != 1) + *overflow = 1; + return result; + } + di_int sa = a >> (N - 1); + di_int abs_a = (a ^ sa) - sa; + di_int sb = b >> (N - 1); + di_int abs_b = (b ^ sb) - sb; + if (abs_a < 2 || abs_b < 2) + return result; + if (sa == sb) + { + if (abs_a > MAX / abs_b) + *overflow = 1; + } + else + { + if (abs_a > MIN / -abs_b) + *overflow = 1; + } + return result; +} diff --git a/third_party/compiler_rt/mulosi4.c b/third_party/compiler_rt/mulosi4.c new file mode 100644 index 00000000..083b33a6 --- /dev/null +++ b/third_party/compiler_rt/mulosi4.c @@ -0,0 +1,61 @@ +/* clang-format off */ +/*===-- mulosi4.c - Implement __mulosi4 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __mulosi4 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a * b */ + +/* Effects: sets *overflow to 1 if a * b overflows */ + +COMPILER_RT_ABI si_int +__mulosi4(si_int a, si_int b, int* overflow) +{ + const int N = (int)(sizeof(si_int) * CHAR_BIT); + const si_int MIN = (si_int)1 << (N-1); + const si_int MAX = ~MIN; + *overflow = 0; + si_int result = a * b; + if (a == MIN) + { + if (b != 0 && b != 1) + *overflow = 1; + return result; + } + if (b == MIN) + { + if (a != 0 && a != 1) + *overflow = 1; + return result; + } + si_int sa = a >> (N - 1); + si_int abs_a = (a ^ sa) - sa; + si_int sb = b >> (N - 1); + si_int abs_b = (b ^ sb) - sb; + if (abs_a < 2 || abs_b < 2) + return result; + if (sa == sb) + { + if (abs_a > MAX / abs_b) + *overflow = 1; + } + else + { + if (abs_a > MIN / -abs_b) + *overflow = 1; + } + return result; +} diff --git a/third_party/compiler_rt/muloti4.c b/third_party/compiler_rt/muloti4.c new file mode 100644 index 00000000..8589c3b4 --- /dev/null +++ b/third_party/compiler_rt/muloti4.c @@ -0,0 +1,65 @@ +/* clang-format off */ +/*===-- muloti4.c - Implement __muloti4 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __muloti4 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: a * b */ + +/* Effects: sets *overflow to 1 if a * b overflows */ + +COMPILER_RT_ABI ti_int +__muloti4(ti_int a, ti_int b, int* overflow) +{ + const int N = (int)(sizeof(ti_int) * CHAR_BIT); + const ti_int MIN = (ti_int)1 << (N-1); + const ti_int MAX = ~MIN; + *overflow = 0; + ti_int result = a * b; + if (a == MIN) + { + if (b != 0 && b != 1) + *overflow = 1; + return result; + } + if (b == MIN) + { + if (a != 0 && a != 1) + *overflow = 1; + return result; + } + ti_int sa = a >> (N - 1); + ti_int abs_a = (a ^ sa) - sa; + ti_int sb = b >> (N - 1); + ti_int abs_b = (b ^ sb) - sb; + if (abs_a < 2 || abs_b < 2) + return result; + if (sa == sb) + { + if (abs_a > MAX / abs_b) + *overflow = 1; + } + else + { + if (abs_a > MIN / -abs_b) + *overflow = 1; + } + return result; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/mulsc3.c b/third_party/compiler_rt/mulsc3.c new file mode 100644 index 00000000..519d1862 --- /dev/null +++ b/third_party/compiler_rt/mulsc3.c @@ -0,0 +1,76 @@ +/* clang-format off */ +/* ===-- mulsc3.c - Implement __mulsc3 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __mulsc3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" +#include "third_party/compiler_rt/int_math.h" + +/* Returns: the product of a + ib and c + id */ + +COMPILER_RT_ABI Fcomplex +__mulsc3(float __a, float __b, float __c, float __d) +{ + float __ac = __a * __c; + float __bd = __b * __d; + float __ad = __a * __d; + float __bc = __b * __c; + Fcomplex z; + COMPLEX_REAL(z) = __ac - __bd; + COMPLEX_IMAGINARY(z) = __ad + __bc; + if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z))) + { + int __recalc = 0; + if (crt_isinf(__a) || crt_isinf(__b)) + { + __a = crt_copysignf(crt_isinf(__a) ? 1 : 0, __a); + __b = crt_copysignf(crt_isinf(__b) ? 1 : 0, __b); + if (crt_isnan(__c)) + __c = crt_copysignf(0, __c); + if (crt_isnan(__d)) + __d = crt_copysignf(0, __d); + __recalc = 1; + } + if (crt_isinf(__c) || crt_isinf(__d)) + { + __c = crt_copysignf(crt_isinf(__c) ? 1 : 0, __c); + __d = crt_copysignf(crt_isinf(__d) ? 1 : 0, __d); + if (crt_isnan(__a)) + __a = crt_copysignf(0, __a); + if (crt_isnan(__b)) + __b = crt_copysignf(0, __b); + __recalc = 1; + } + if (!__recalc && (crt_isinf(__ac) || crt_isinf(__bd) || + crt_isinf(__ad) || crt_isinf(__bc))) + { + if (crt_isnan(__a)) + __a = crt_copysignf(0, __a); + if (crt_isnan(__b)) + __b = crt_copysignf(0, __b); + if (crt_isnan(__c)) + __c = crt_copysignf(0, __c); + if (crt_isnan(__d)) + __d = crt_copysignf(0, __d); + __recalc = 1; + } + if (__recalc) + { + COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c - __b * __d); + COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__a * __d + __b * __c); + } + } + return z; +} diff --git a/third_party/compiler_rt/mulsf3.c b/third_party/compiler_rt/mulsf3.c new file mode 100644 index 00000000..d3a6437f --- /dev/null +++ b/third_party/compiler_rt/mulsf3.c @@ -0,0 +1,33 @@ +/* clang-format off */ +//===-- lib/mulsf3.c - Single-precision multiplication ------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements single-precision soft-float multiplication +// with the IEEE-754 default rounding (to nearest, ties to even). +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SINGLE_PRECISION +#include "third_party/compiler_rt/fp_mul_impl.inc" + +COMPILER_RT_ABI fp_t __mulsf3(fp_t a, fp_t b) { + return __mulXf3__(a, b); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI fp_t __aeabi_fmul(fp_t a, fp_t b) { + return __mulsf3(a, b); +} +#else +AEABI_RTABI fp_t __aeabi_fmul(fp_t a, fp_t b) COMPILER_RT_ALIAS(__mulsf3); +#endif +#endif diff --git a/third_party/compiler_rt/multc3.c b/third_party/compiler_rt/multc3.c new file mode 100644 index 00000000..e6dc3ab5 --- /dev/null +++ b/third_party/compiler_rt/multc3.c @@ -0,0 +1,62 @@ +/* clang-third_party/compiler_rt/format off */ +/* ===-- multc3.c - Implement __multc3 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __multc3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" +#include "third_party/compiler_rt/int_math.h" + +/* Returns: the product of a + ib and c + id */ + +COMPILER_RT_ABI long double _Complex __multc3(long double a, long double b, + long double c, long double d) { + long double ac = a * c; + long double bd = b * d; + long double ad = a * d; + long double bc = b * c; + long double _Complex z; + __real__ z = ac - bd; + __imag__ z = ad + bc; + if (crt_isnan(__real__ z) && crt_isnan(__imag__ z)) { + int recalc = 0; + if (crt_isinf(a) || crt_isinf(b)) { + a = crt_copysignl(crt_isinf(a) ? 1 : 0, a); + b = crt_copysignl(crt_isinf(b) ? 1 : 0, b); + if (crt_isnan(c)) c = crt_copysignl(0, c); + if (crt_isnan(d)) d = crt_copysignl(0, d); + recalc = 1; + } + if (crt_isinf(c) || crt_isinf(d)) { + c = crt_copysignl(crt_isinf(c) ? 1 : 0, c); + d = crt_copysignl(crt_isinf(d) ? 1 : 0, d); + if (crt_isnan(a)) a = crt_copysignl(0, a); + if (crt_isnan(b)) b = crt_copysignl(0, b); + recalc = 1; + } + if (!recalc && + (crt_isinf(ac) || crt_isinf(bd) || crt_isinf(ad) || crt_isinf(bc))) { + if (crt_isnan(a)) a = crt_copysignl(0, a); + if (crt_isnan(b)) b = crt_copysignl(0, b); + if (crt_isnan(c)) c = crt_copysignl(0, c); + if (crt_isnan(d)) d = crt_copysignl(0, d); + recalc = 1; + } + if (recalc) { + __real__ z = CRT_INFINITY * (a * c - b * d); + __imag__ z = CRT_INFINITY * (a * d + b * c); + } + } + return z; +} diff --git a/third_party/compiler_rt/multf3.c b/third_party/compiler_rt/multf3.c new file mode 100644 index 00000000..23f1c472 --- /dev/null +++ b/third_party/compiler_rt/multf3.c @@ -0,0 +1,28 @@ +/* clang-format off */ +//===-- lib/multf3.c - Quad-precision multiplication --------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements quad-precision soft-float multiplication +// with the IEEE-754 default rounding (to nearest, ties to even). +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +#include "third_party/compiler_rt/fp_mul_impl.inc" + +COMPILER_RT_ABI fp_t __multf3(fp_t a, fp_t b) { + return __mulXf3__(a, b); +} + +#endif diff --git a/third_party/compiler_rt/multi3.c b/third_party/compiler_rt/multi3.c new file mode 100644 index 00000000..130a47b9 --- /dev/null +++ b/third_party/compiler_rt/multi3.c @@ -0,0 +1,61 @@ +/* clang-format off */ +/* ===-- multi3.c - Implement __multi3 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + +STATIC_YOINK("huge_compiler_rt_license"); + + * This file implements __multi3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: a * b */ + +static +ti_int +__mulddi3(du_int a, du_int b) +{ + twords r; + const int bits_in_dword_2 = (int)(sizeof(di_int) * CHAR_BIT) / 2; + const du_int lower_mask = (du_int)~0 >> bits_in_dword_2; + r.s.low = (a & lower_mask) * (b & lower_mask); + du_int t = r.s.low >> bits_in_dword_2; + r.s.low &= lower_mask; + t += (a >> bits_in_dword_2) * (b & lower_mask); + r.s.low += (t & lower_mask) << bits_in_dword_2; + r.s.high = t >> bits_in_dword_2; + t = r.s.low >> bits_in_dword_2; + r.s.low &= lower_mask; + t += (b >> bits_in_dword_2) * (a & lower_mask); + r.s.low += (t & lower_mask) << bits_in_dword_2; + r.s.high += t >> bits_in_dword_2; + r.s.high += (a >> bits_in_dword_2) * (b >> bits_in_dword_2); + return r.all; +} + +/* Returns: a * b */ + +COMPILER_RT_ABI ti_int +__multi3(ti_int a, ti_int b) +{ + twords x; + x.all = a; + twords y; + y.all = b; + twords r; + r.all = __mulddi3(x.s.low, y.s.low); + r.s.high += x.s.high * y.s.low + x.s.low * y.s.high; + return r.all; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/mulxc3.c b/third_party/compiler_rt/mulxc3.c new file mode 100644 index 00000000..43cf4af7 --- /dev/null +++ b/third_party/compiler_rt/mulxc3.c @@ -0,0 +1,80 @@ +/* clang-format off */ +/* ===-- mulxc3.c - Implement __mulxc3 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __mulxc3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#if !_ARCH_PPC + +#include "third_party/compiler_rt/int_lib.h" +#include "third_party/compiler_rt/int_math.h" + +/* Returns: the product of a + ib and c + id */ + +COMPILER_RT_ABI Lcomplex +__mulxc3(long double __a, long double __b, long double __c, long double __d) +{ + long double __ac = __a * __c; + long double __bd = __b * __d; + long double __ad = __a * __d; + long double __bc = __b * __c; + Lcomplex z; + COMPLEX_REAL(z) = __ac - __bd; + COMPLEX_IMAGINARY(z) = __ad + __bc; + if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z))) + { + int __recalc = 0; + if (crt_isinf(__a) || crt_isinf(__b)) + { + __a = crt_copysignl(crt_isinf(__a) ? 1 : 0, __a); + __b = crt_copysignl(crt_isinf(__b) ? 1 : 0, __b); + if (crt_isnan(__c)) + __c = crt_copysignl(0, __c); + if (crt_isnan(__d)) + __d = crt_copysignl(0, __d); + __recalc = 1; + } + if (crt_isinf(__c) || crt_isinf(__d)) + { + __c = crt_copysignl(crt_isinf(__c) ? 1 : 0, __c); + __d = crt_copysignl(crt_isinf(__d) ? 1 : 0, __d); + if (crt_isnan(__a)) + __a = crt_copysignl(0, __a); + if (crt_isnan(__b)) + __b = crt_copysignl(0, __b); + __recalc = 1; + } + if (!__recalc && (crt_isinf(__ac) || crt_isinf(__bd) || + crt_isinf(__ad) || crt_isinf(__bc))) + { + if (crt_isnan(__a)) + __a = crt_copysignl(0, __a); + if (crt_isnan(__b)) + __b = crt_copysignl(0, __b); + if (crt_isnan(__c)) + __c = crt_copysignl(0, __c); + if (crt_isnan(__d)) + __d = crt_copysignl(0, __d); + __recalc = 1; + } + if (__recalc) + { + COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c - __b * __d); + COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__a * __d + __b * __c); + } + } + return z; +} + +#endif diff --git a/third_party/compiler_rt/negdf2.c b/third_party/compiler_rt/negdf2.c new file mode 100644 index 00000000..25df24dd --- /dev/null +++ b/third_party/compiler_rt/negdf2.c @@ -0,0 +1,33 @@ +/* clang-format off */ +//===-- lib/negdf2.c - double-precision negation ------------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements double-precision soft-float negation. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define DOUBLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +COMPILER_RT_ABI fp_t +__negdf2(fp_t a) { + return fromRep(toRep(a) ^ signBit); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI fp_t __aeabi_dneg(fp_t a) { + return __negdf2(a); +} +#else +AEABI_RTABI fp_t __aeabi_dneg(fp_t a) COMPILER_RT_ALIAS(__negdf2); +#endif +#endif diff --git a/third_party/compiler_rt/negdi2.c b/third_party/compiler_rt/negdi2.c new file mode 100644 index 00000000..8389752b --- /dev/null +++ b/third_party/compiler_rt/negdi2.c @@ -0,0 +1,29 @@ +/* clang-format off */ +/* ===-- negdi2.c - Implement __negdi2 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __negdi2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: -a */ + +COMPILER_RT_ABI di_int +__negdi2(di_int a) +{ + /* Note: this routine is here for API compatibility; any sane compiler + * should expand it inline. + */ + return -a; +} diff --git a/third_party/compiler_rt/negsf2.c b/third_party/compiler_rt/negsf2.c new file mode 100644 index 00000000..acae8a2b --- /dev/null +++ b/third_party/compiler_rt/negsf2.c @@ -0,0 +1,33 @@ +/* clang-format off */ +//===-- lib/negsf2.c - single-precision negation ------------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements single-precision soft-float negation. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SINGLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +COMPILER_RT_ABI fp_t +__negsf2(fp_t a) { + return fromRep(toRep(a) ^ signBit); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI fp_t __aeabi_fneg(fp_t a) { + return __negsf2(a); +} +#else +AEABI_RTABI fp_t __aeabi_fneg(fp_t a) COMPILER_RT_ALIAS(__negsf2); +#endif +#endif diff --git a/third_party/compiler_rt/negti2.c b/third_party/compiler_rt/negti2.c new file mode 100644 index 00000000..457cf71a --- /dev/null +++ b/third_party/compiler_rt/negti2.c @@ -0,0 +1,33 @@ +/* clang-format off */ +/* ===-- negti2.c - Implement __negti2 -------------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __negti2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: -a */ + +COMPILER_RT_ABI ti_int +__negti2(ti_int a) +{ + /* Note: this routine is here for API compatibility; any sane compiler + * should expand it inline. + */ + return -a; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/nexgen32e/chkstk.S b/third_party/compiler_rt/nexgen32e/chkstk.S new file mode 100644 index 00000000..10687ae9 --- /dev/null +++ b/third_party/compiler_rt/nexgen32e/chkstk.S @@ -0,0 +1,43 @@ +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. + +#include "third_party/compiler_rt/assembly.h" + +// _chkstk routine +// This routine is windows specific +// http://msdn.microsoft.com/en-us/library/ms648426.aspx + +// Notes from r227519 +// MSVC x64s __chkstk and cygmings ___chkstk_ms do not adjust %rsp +// themselves. It also does not clobber %rax so we can reuse it when +// adjusting %rsp. + +#ifdef __x86_64__ + + .section .yoink + nop huge_compiler_rt_license + .previous + +.text +.balign 4 +DEFINE_COMPILERRT_FUNCTION(___chkstk_ms) + push %rcx + push %rax + cmp $0x1000,%rax + lea 24(%rsp),%rcx + jb 1f +2: + sub $0x1000,%rcx + test %rcx,(%rcx) + sub $0x1000,%rax + cmp $0x1000,%rax + ja 2b +1: + sub %rax,%rcx + test %rcx,(%rcx) + pop %rax + pop %rcx + ret +END_COMPILERRT_FUNCTION(___chkstk_ms) + +#endif // __x86_64__ diff --git a/third_party/compiler_rt/nexgen32e/chkstk2.S b/third_party/compiler_rt/nexgen32e/chkstk2.S new file mode 100644 index 00000000..004e376b --- /dev/null +++ b/third_party/compiler_rt/nexgen32e/chkstk2.S @@ -0,0 +1,46 @@ +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. + +#include "third_party/compiler_rt/assembly.h" + +#ifdef __x86_64__ + + .section .yoink + nop huge_compiler_rt_license + .previous + +// _chkstk (_alloca) routine - probe stack between %rsp and (%rsp-%rax) in 4k increments, +// then decrement %rsp by %rax. Preserves all registers except %rsp and flags. +// This routine is windows specific +// http://msdn.microsoft.com/en-us/library/ms648426.aspx + +.text +.balign 4 +DEFINE_COMPILERRT_FUNCTION(__alloca) + mov %rcx,%rax // x64 _alloca is a normal function with parameter in rcx + // fallthrough +DEFINE_COMPILERRT_FUNCTION(___chkstk) + push %rcx + cmp $0x1000,%rax + lea 16(%rsp),%rcx // rsp before calling this routine -> rcx + jb 1f +2: + sub $0x1000,%rcx + test %rcx,(%rcx) + sub $0x1000,%rax + cmp $0x1000,%rax + ja 2b +1: + sub %rax,%rcx + test %rcx,(%rcx) + + lea 8(%rsp),%rax // load pointer to the return address into rax + mov %rcx,%rsp // install the new top of stack pointer into rsp + mov -8(%rax),%rcx // restore rcx + push (%rax) // push return address onto the stack + sub %rsp,%rax // restore the original value in rax + ret +END_COMPILERRT_FUNCTION(___chkstk) +END_COMPILERRT_FUNCTION(__alloca) + +#endif // __x86_64__ diff --git a/third_party/compiler_rt/nexgen32e/floatdidf.c b/third_party/compiler_rt/nexgen32e/floatdidf.c new file mode 100644 index 00000000..73dc4792 --- /dev/null +++ b/third_party/compiler_rt/nexgen32e/floatdidf.c @@ -0,0 +1,19 @@ +/* clang-format off */ +/* This file is distributed under the University of Illinois Open Source + * License. See LICENSE.TXT for details. + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +/* double __floatdidf(di_int a); */ + +#if defined(__x86_64__) || defined(_M_X64) + +#include "third_party/compiler_rt/int_lib.h" + +double __floatdidf(int64_t a) +{ + return (double)a; +} + +#endif /* __x86_64__ */ diff --git a/third_party/compiler_rt/nexgen32e/floatdisf.c b/third_party/compiler_rt/nexgen32e/floatdisf.c new file mode 100644 index 00000000..5d5fcd2d --- /dev/null +++ b/third_party/compiler_rt/nexgen32e/floatdisf.c @@ -0,0 +1,17 @@ +/* clang-format off */ +/* This file is distributed under the University of Illinois Open Source + * License. See LICENSE.TXT for details. + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#if defined(__x86_64__) || defined(_M_X64) + +#include "third_party/compiler_rt/int_lib.h" + +float __floatdisf(int64_t a) +{ + return (float)a; +} + +#endif /* __x86_64__ */ diff --git a/third_party/compiler_rt/nexgen32e/floatdixf.c b/third_party/compiler_rt/nexgen32e/floatdixf.c new file mode 100644 index 00000000..48b2ea4e --- /dev/null +++ b/third_party/compiler_rt/nexgen32e/floatdixf.c @@ -0,0 +1,19 @@ +/* clang-format off */ +/* This file is distributed under the University of Illinois Open Source + * License. See LICENSE.TXT for details. + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +/* long double __floatdixf(di_int a); */ + +#ifdef __x86_64__ + +#include "third_party/compiler_rt/int_lib.h" + +long double __floatdixf(int64_t a) +{ + return (long double)a; +} + +#endif /* __i386__ */ diff --git a/third_party/compiler_rt/nexgen32e/floatundidf.S b/third_party/compiler_rt/nexgen32e/floatundidf.S new file mode 100644 index 00000000..b7c9074e --- /dev/null +++ b/third_party/compiler_rt/nexgen32e/floatundidf.S @@ -0,0 +1,56 @@ +//===-- floatundidf.S - Implement __floatundidf for x86_64 ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements __floatundidf for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include "third_party/compiler_rt/assembly.h" + +// double __floatundidf(du_int a); + +#ifdef __x86_64__ + + .section .yoink + nop huge_compiler_rt_license + .previous + +CONST_SECTION + + .balign 16 +twop52: + .quad 0x4330000000000000 + + .balign 16 +twop84_plus_twop52: + .quad 0x4530000000100000 + + .balign 16 +twop84: + .quad 0x4530000000000000 + +#define REL_ADDR(_a) (_a)(%rip) + +.text +.balign 4 +DEFINE_COMPILERRT_FUNCTION(__floatundidf) + movd %edi, %xmm0 // low 32 bits of a + shrq $32, %rdi // high 32 bits of a + orq REL_ADDR(twop84), %rdi // 0x1p84 + a_hi (no rounding occurs) + orpd REL_ADDR(twop52), %xmm0 // 0x1p52 + a_lo (no rounding occurs) + movd %rdi, %xmm1 + subsd REL_ADDR(twop84_plus_twop52), %xmm1 // a_hi - 0x1p52 (no rounding occurs) + addsd %xmm1, %xmm0 // a_hi + a_lo (round happens here) + ret +END_COMPILERRT_FUNCTION(__floatundidf) + +#endif // __x86_64__ + +NO_EXEC_STACK_DIRECTIVE + diff --git a/third_party/compiler_rt/nexgen32e/floatundisf.S b/third_party/compiler_rt/nexgen32e/floatundisf.S new file mode 100644 index 00000000..416633e0 --- /dev/null +++ b/third_party/compiler_rt/nexgen32e/floatundisf.S @@ -0,0 +1,42 @@ +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. + +#include "third_party/compiler_rt/assembly.h" + +// float __floatundisf(du_int a); + +#ifdef __x86_64__ + + .section .yoink + nop huge_compiler_rt_license + .previous + +CONST_SECTION + + .balign 16 +two: + .single 2.0 + +#define REL_ADDR(_a) (_a)(%rip) + +.text +.balign 4 +DEFINE_COMPILERRT_FUNCTION(__floatundisf) + movq $1, %rsi + testq %rdi, %rdi + js 1f + cvtsi2ssq %rdi, %xmm0 + ret + +1: andq %rdi, %rsi + shrq %rdi + orq %rsi, %rdi + cvtsi2ssq %rdi, %xmm0 + mulss REL_ADDR(two), %xmm0 + ret +END_COMPILERRT_FUNCTION(__floatundisf) + +#endif // __x86_64__ + +NO_EXEC_STACK_DIRECTIVE + diff --git a/third_party/compiler_rt/nexgen32e/floatundixf.S b/third_party/compiler_rt/nexgen32e/floatundixf.S new file mode 100644 index 00000000..5ff61044 --- /dev/null +++ b/third_party/compiler_rt/nexgen32e/floatundixf.S @@ -0,0 +1,75 @@ +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. + +#include "third_party/compiler_rt/assembly.h" + +// long double __floatundixf(du_int a); + +#ifdef __x86_64__ + + .section .yoink + nop huge_compiler_rt_license + .previous + +CONST_SECTION + + .balign 16 +twop64: + .quad 0x43f0000000000000 + +#define REL_ADDR(_a) (_a)(%rip) + + .text + + .balign 4 +DEFINE_COMPILERRT_FUNCTION(__floatundixf) + movq %rdi, -8(%rsp) + fildq -8(%rsp) + test %rdi, %rdi + js 1f + ret +1: faddl REL_ADDR(twop64) + ret +END_COMPILERRT_FUNCTION(__floatundixf) + +#endif // __x86_64__ + + +/* Branch-free implementation is ever so slightly slower, but more beautiful. + It is likely superior for inlining, so I kept it around for future reference. + +#ifdef __x86_64__ + +CONST_SECTION + + .balign 4 +twop52: + .quad 0x4330000000000000 +twop84_plus_twop52_neg: + .quad 0xc530000000100000 +twop84: + .quad 0x4530000000000000 + +#define REL_ADDR(_a) (_a)(%rip) + +.text +.balign 4 +DEFINE_COMPILERRT_FUNCTION(__floatundixf) + movl %edi, %esi // low 32 bits of input + shrq $32, %rdi // hi 32 bits of input + orq REL_ADDR(twop84), %rdi // 2^84 + hi (as a double) + orq REL_ADDR(twop52), %rsi // 2^52 + lo (as a double) + movq %rdi, -8(%rsp) + movq %rsi, -16(%rsp) + fldl REL_ADDR(twop84_plus_twop52_neg) + faddl -8(%rsp) // hi - 2^52 (as double extended, no rounding occurs) + faddl -16(%rsp) // hi + lo (as double extended) + ret +END_COMPILERRT_FUNCTION(__floatundixf) + +#endif // __x86_64__ + +*/ + +NO_EXEC_STACK_DIRECTIVE + diff --git a/third_party/compiler_rt/os_version_check.c b/third_party/compiler_rt/os_version_check.c new file mode 100644 index 00000000..590e3473 --- /dev/null +++ b/third_party/compiler_rt/os_version_check.c @@ -0,0 +1,204 @@ +/* clang-format off */ +/* ===-- os_version_check.c - OS version checking -------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements the function __isOSVersionAtLeast, used by + * Objective-C's @available + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#ifdef __APPLE__ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* These three variables hold the host's OS version. */ +static int32_t GlobalMajor, GlobalMinor, GlobalSubminor; +static dispatch_once_t DispatchOnceCounter; + +typedef CFDataRef (*CFDataCreateWithBytesNoCopyFuncTy)(CFAllocatorRef, + const UInt8 *, CFIndex, + CFAllocatorRef); +typedef CFPropertyListRef (*CFPropertyListCreateWithDataFuncTy)( + CFAllocatorRef, CFDataRef, CFOptionFlags, CFPropertyListFormat *, + CFErrorRef *); +typedef CFPropertyListRef (*CFPropertyListCreateFromXMLDataFuncTy)( + CFAllocatorRef, CFDataRef, CFOptionFlags, CFStringRef *); +typedef CFStringRef (*CFStringCreateWithCStringNoCopyFuncTy)(CFAllocatorRef, + const char *, + CFStringEncoding, + CFAllocatorRef); +typedef const void *(*CFDictionaryGetValueFuncTy)(CFDictionaryRef, + const void *); +typedef CFTypeID (*CFGetTypeIDFuncTy)(CFTypeRef); +typedef CFTypeID (*CFStringGetTypeIDFuncTy)(void); +typedef Boolean (*CFStringGetCStringFuncTy)(CFStringRef, char *, CFIndex, + CFStringEncoding); +typedef void (*CFReleaseFuncTy)(CFTypeRef); + +/* Find and parse the SystemVersion.plist file. */ +static void parseSystemVersionPList(void *Unused) { + (void)Unused; + /* Load CoreFoundation dynamically */ + const void *NullAllocator = dlsym(RTLD_DEFAULT, "kCFAllocatorNull"); + if (!NullAllocator) + return; + const CFAllocatorRef kCFAllocatorNull = + *(const CFAllocatorRef *)NullAllocator; + CFDataCreateWithBytesNoCopyFuncTy CFDataCreateWithBytesNoCopyFunc = + (CFDataCreateWithBytesNoCopyFuncTy)dlsym(RTLD_DEFAULT, + "CFDataCreateWithBytesNoCopy"); + if (!CFDataCreateWithBytesNoCopyFunc) + return; + CFPropertyListCreateWithDataFuncTy CFPropertyListCreateWithDataFunc = + (CFPropertyListCreateWithDataFuncTy)dlsym( + RTLD_DEFAULT, "CFPropertyListCreateWithData"); +/* CFPropertyListCreateWithData was introduced only in macOS 10.6+, so it + * will be NULL on earlier OS versions. */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + CFPropertyListCreateFromXMLDataFuncTy CFPropertyListCreateFromXMLDataFunc = + (CFPropertyListCreateFromXMLDataFuncTy)dlsym( + RTLD_DEFAULT, "CFPropertyListCreateFromXMLData"); +#pragma clang diagnostic pop + /* CFPropertyListCreateFromXMLDataFunc is deprecated in macOS 10.10, so it + * might be NULL in future OS versions. */ + if (!CFPropertyListCreateWithDataFunc && !CFPropertyListCreateFromXMLDataFunc) + return; + CFStringCreateWithCStringNoCopyFuncTy CFStringCreateWithCStringNoCopyFunc = + (CFStringCreateWithCStringNoCopyFuncTy)dlsym( + RTLD_DEFAULT, "CFStringCreateWithCStringNoCopy"); + if (!CFStringCreateWithCStringNoCopyFunc) + return; + CFDictionaryGetValueFuncTy CFDictionaryGetValueFunc = + (CFDictionaryGetValueFuncTy)dlsym(RTLD_DEFAULT, "CFDictionaryGetValue"); + if (!CFDictionaryGetValueFunc) + return; + CFGetTypeIDFuncTy CFGetTypeIDFunc = + (CFGetTypeIDFuncTy)dlsym(RTLD_DEFAULT, "CFGetTypeID"); + if (!CFGetTypeIDFunc) + return; + CFStringGetTypeIDFuncTy CFStringGetTypeIDFunc = + (CFStringGetTypeIDFuncTy)dlsym(RTLD_DEFAULT, "CFStringGetTypeID"); + if (!CFStringGetTypeIDFunc) + return; + CFStringGetCStringFuncTy CFStringGetCStringFunc = + (CFStringGetCStringFuncTy)dlsym(RTLD_DEFAULT, "CFStringGetCString"); + if (!CFStringGetCStringFunc) + return; + CFReleaseFuncTy CFReleaseFunc = + (CFReleaseFuncTy)dlsym(RTLD_DEFAULT, "CFRelease"); + if (!CFReleaseFunc) + return; + + char *PListPath = "/System/Library/CoreServices/SystemVersion.plist"; + +#if TARGET_OS_SIMULATOR + char *PListPathPrefix = getenv("IPHONE_SIMULATOR_ROOT"); + if (!PListPathPrefix) + return; + char FullPath[strlen(PListPathPrefix) + strlen(PListPath) + 1]; + strcpy(FullPath, PListPathPrefix); + strcat(FullPath, PListPath); + PListPath = FullPath; +#endif + FILE *PropertyList = fopen(PListPath, "r"); + if (!PropertyList) + return; + + /* Dynamically allocated stuff. */ + CFDictionaryRef PListRef = NULL; + CFDataRef FileContentsRef = NULL; + UInt8 *PListBuf = NULL; + + fseek(PropertyList, 0, SEEK_END); + long PListFileSize = ftell(PropertyList); + if (PListFileSize < 0) + goto Fail; + rewind(PropertyList); + + PListBuf = malloc((size_t)PListFileSize); + if (!PListBuf) + goto Fail; + + size_t NumRead = fread(PListBuf, 1, (size_t)PListFileSize, PropertyList); + if (NumRead != (size_t)PListFileSize) + goto Fail; + + /* Get the file buffer into CF's format. We pass in a null allocator here * + * because we free PListBuf ourselves */ + FileContentsRef = (*CFDataCreateWithBytesNoCopyFunc)( + NULL, PListBuf, (CFIndex)NumRead, kCFAllocatorNull); + if (!FileContentsRef) + goto Fail; + + if (CFPropertyListCreateWithDataFunc) + PListRef = (*CFPropertyListCreateWithDataFunc)( + NULL, FileContentsRef, kCFPropertyListImmutable, NULL, NULL); + else + PListRef = (*CFPropertyListCreateFromXMLDataFunc)( + NULL, FileContentsRef, kCFPropertyListImmutable, NULL); + if (!PListRef) + goto Fail; + + CFStringRef ProductVersion = (*CFStringCreateWithCStringNoCopyFunc)( + NULL, "ProductVersion", kCFStringEncodingASCII, kCFAllocatorNull); + if (!ProductVersion) + goto Fail; + CFTypeRef OpaqueValue = (*CFDictionaryGetValueFunc)(PListRef, ProductVersion); + (*CFReleaseFunc)(ProductVersion); + if (!OpaqueValue || + (*CFGetTypeIDFunc)(OpaqueValue) != (*CFStringGetTypeIDFunc)()) + goto Fail; + + char VersionStr[32]; + if (!(*CFStringGetCStringFunc)((CFStringRef)OpaqueValue, VersionStr, + sizeof(VersionStr), kCFStringEncodingUTF8)) + goto Fail; + sscanf(VersionStr, "%d.%d.%d", &GlobalMajor, &GlobalMinor, &GlobalSubminor); + +Fail: + if (PListRef) + (*CFReleaseFunc)(PListRef); + if (FileContentsRef) + (*CFReleaseFunc)(FileContentsRef); + free(PListBuf); + fclose(PropertyList); +} + +int32_t __isOSVersionAtLeast(int32_t Major, int32_t Minor, int32_t Subminor) { + /* Populate the global version variables, if they haven't already. */ + dispatch_once_f(&DispatchOnceCounter, NULL, parseSystemVersionPList); + + if (Major < GlobalMajor) + return 1; + if (Major > GlobalMajor) + return 0; + if (Minor < GlobalMinor) + return 1; + if (Minor > GlobalMinor) + return 0; + return Subminor <= GlobalSubminor; +} + +#else + +/* Silence an empty translation unit warning. */ +typedef int unused; + +#endif diff --git a/third_party/compiler_rt/paritydi2.c b/third_party/compiler_rt/paritydi2.c new file mode 100644 index 00000000..b08396e9 --- /dev/null +++ b/third_party/compiler_rt/paritydi2.c @@ -0,0 +1,28 @@ +/* clang-format off */ +/* ===-- paritydi2.c - Implement __paritydi2 -------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __paritydi2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: 1 if number of bits is odd else returns 0 */ + +COMPILER_RT_ABI si_int +__paritydi2(di_int a) +{ + dwords x; + x.all = a; + return __paritysi2(x.s.high ^ x.s.low); +} diff --git a/third_party/compiler_rt/paritysi2.c b/third_party/compiler_rt/paritysi2.c new file mode 100644 index 00000000..2b54c747 --- /dev/null +++ b/third_party/compiler_rt/paritysi2.c @@ -0,0 +1,30 @@ +/* clang-format off */ +/* ===-- paritysi2.c - Implement __paritysi2 -------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __paritysi2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: 1 if number of bits is odd else returns 0 */ + +COMPILER_RT_ABI si_int +__paritysi2(si_int a) +{ + su_int x = (su_int)a; + x ^= x >> 16; + x ^= x >> 8; + x ^= x >> 4; + return (0x6996 >> (x & 0xF)) & 1; +} diff --git a/third_party/compiler_rt/parityti2.c b/third_party/compiler_rt/parityti2.c new file mode 100644 index 00000000..0105965e --- /dev/null +++ b/third_party/compiler_rt/parityti2.c @@ -0,0 +1,32 @@ +/* clang-format off */ +/* ===-- parityti2.c - Implement __parityti2 -------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __parityti2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: 1 if number of bits is odd else returns 0 */ + +COMPILER_RT_ABI si_int +__parityti2(ti_int a) +{ + twords x; + x.all = a; + return __paritydi2(x.s.high ^ x.s.low); +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/popcountdi2.c b/third_party/compiler_rt/popcountdi2.c new file mode 100644 index 00000000..9ce66b27 --- /dev/null +++ b/third_party/compiler_rt/popcountdi2.c @@ -0,0 +1,39 @@ +/* clang-format off */ +/* ===-- popcountdi2.c - Implement __popcountdi2 ----------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __popcountdi2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: count of 1 bits */ + +COMPILER_RT_ABI si_int +__popcountdi2(di_int a) +{ + du_int x2 = (du_int)a; + x2 = x2 - ((x2 >> 1) & 0x5555555555555555uLL); + /* Every 2 bits holds the sum of every pair of bits (32) */ + x2 = ((x2 >> 2) & 0x3333333333333333uLL) + (x2 & 0x3333333333333333uLL); + /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) (16) */ + x2 = (x2 + (x2 >> 4)) & 0x0F0F0F0F0F0F0F0FuLL; + /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) (8) */ + su_int x = (su_int)(x2 + (x2 >> 32)); + /* The lower 32 bits hold four 16 bit sums (5 significant bits). */ + /* Upper 32 bits are garbage */ + x = x + (x >> 16); + /* The lower 16 bits hold two 32 bit sums (6 significant bits). */ + /* Upper 16 bits are garbage */ + return (x + (x >> 8)) & 0x0000007F; /* (7 significant bits) */ +} diff --git a/third_party/compiler_rt/popcountsi2.c b/third_party/compiler_rt/popcountsi2.c new file mode 100644 index 00000000..b427e66c --- /dev/null +++ b/third_party/compiler_rt/popcountsi2.c @@ -0,0 +1,36 @@ +/* clang-format off */ +/* ===-- popcountsi2.c - Implement __popcountsi2 ---------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __popcountsi2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: count of 1 bits */ + +COMPILER_RT_ABI si_int +__popcountsi2(si_int a) +{ + su_int x = (su_int)a; + x = x - ((x >> 1) & 0x55555555); + /* Every 2 bits holds the sum of every pair of bits */ + x = ((x >> 2) & 0x33333333) + (x & 0x33333333); + /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) */ + x = (x + (x >> 4)) & 0x0F0F0F0F; + /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) */ + x = (x + (x >> 16)); + /* The lower 16 bits hold two 8 bit sums (5 significant bits).*/ + /* Upper 16 bits are garbage */ + return (x + (x >> 8)) & 0x0000003F; /* (6 significant bits) */ +} diff --git a/third_party/compiler_rt/popcountti2.c b/third_party/compiler_rt/popcountti2.c new file mode 100644 index 00000000..cc2afb24 --- /dev/null +++ b/third_party/compiler_rt/popcountti2.c @@ -0,0 +1,47 @@ +/* clang-format off */ +/* ===-- popcountti2.c - Implement __popcountti2 ----------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __popcountti2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: count of 1 bits */ + +COMPILER_RT_ABI si_int +__popcountti2(ti_int a) +{ + tu_int x3 = (tu_int)a; + x3 = x3 - ((x3 >> 1) & (((tu_int)0x5555555555555555uLL << 64) | + 0x5555555555555555uLL)); + /* Every 2 bits holds the sum of every pair of bits (64) */ + x3 = ((x3 >> 2) & (((tu_int)0x3333333333333333uLL << 64) | 0x3333333333333333uLL)) + + (x3 & (((tu_int)0x3333333333333333uLL << 64) | 0x3333333333333333uLL)); + /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) (32) */ + x3 = (x3 + (x3 >> 4)) + & (((tu_int)0x0F0F0F0F0F0F0F0FuLL << 64) | 0x0F0F0F0F0F0F0F0FuLL); + /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) (16) */ + du_int x2 = (du_int)(x3 + (x3 >> 64)); + /* Every 8 bits holds the sum of every 8-set of bits (5 significant bits) (8) */ + su_int x = (su_int)(x2 + (x2 >> 32)); + /* Every 8 bits holds the sum of every 8-set of bits (6 significant bits) (4) */ + x = x + (x >> 16); + /* Every 8 bits holds the sum of every 8-set of bits (7 significant bits) (2) */ + /* Upper 16 bits are garbage */ + return (x + (x >> 8)) & 0xFF; /* (8 significant bits) */ +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/powidf2.c b/third_party/compiler_rt/powidf2.c new file mode 100644 index 00000000..8120ea91 --- /dev/null +++ b/third_party/compiler_rt/powidf2.c @@ -0,0 +1,37 @@ +/* clang-format off */ +/* ===-- powidf2.cpp - Implement __powidf2 ---------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __powidf2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a ^ b */ + +COMPILER_RT_ABI double +__powidf2(double a, si_int b) +{ + const int recip = b < 0; + double r = 1; + while (1) + { + if (b & 1) + r *= a; + b /= 2; + if (b == 0) + break; + a *= a; + } + return recip ? 1/r : r; +} diff --git a/third_party/compiler_rt/powisf2.c b/third_party/compiler_rt/powisf2.c new file mode 100644 index 00000000..7a12977e --- /dev/null +++ b/third_party/compiler_rt/powisf2.c @@ -0,0 +1,37 @@ +/* clang-format off */ +/*===-- powisf2.cpp - Implement __powisf2 ---------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __powisf2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a ^ b */ + +COMPILER_RT_ABI float +__powisf2(float a, si_int b) +{ + const int recip = b < 0; + float r = 1; + while (1) + { + if (b & 1) + r *= a; + b /= 2; + if (b == 0) + break; + a *= a; + } + return recip ? 1/r : r; +} diff --git a/third_party/compiler_rt/powitf2.c b/third_party/compiler_rt/powitf2.c new file mode 100644 index 00000000..611053bc --- /dev/null +++ b/third_party/compiler_rt/powitf2.c @@ -0,0 +1,41 @@ +/* clang-format off */ +/* ===-- powitf2.cpp - Implement __powitf2 ---------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __powitf2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#if _ARCH_PPC + +/* Returns: a ^ b */ + +COMPILER_RT_ABI long double +__powitf2(long double a, si_int b) +{ + const int recip = b < 0; + long double r = 1; + while (1) + { + if (b & 1) + r *= a; + b /= 2; + if (b == 0) + break; + a *= a; + } + return recip ? 1/r : r; +} + +#endif diff --git a/third_party/compiler_rt/powixf2.c b/third_party/compiler_rt/powixf2.c new file mode 100644 index 00000000..c7253c03 --- /dev/null +++ b/third_party/compiler_rt/powixf2.c @@ -0,0 +1,41 @@ +/* clang-format off */ +/* ===-- powixf2.cpp - Implement __powixf2 ---------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __powixf2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#if !_ARCH_PPC + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a ^ b */ + +COMPILER_RT_ABI long double +__powixf2(long double a, si_int b) +{ + const int recip = b < 0; + long double r = 1; + while (1) + { + if (b & 1) + r *= a; + b /= 2; + if (b == 0) + break; + a *= a; + } + return recip ? 1/r : r; +} + +#endif diff --git a/third_party/compiler_rt/subdf3.c b/third_party/compiler_rt/subdf3.c new file mode 100644 index 00000000..e60bcec2 --- /dev/null +++ b/third_party/compiler_rt/subdf3.c @@ -0,0 +1,35 @@ +/* clang-format off */ +//===-- lib/adddf3.c - Double-precision subtraction ---------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements double-precision soft-float subtraction with the +// IEEE-754 default rounding (to nearest, ties to even). +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define DOUBLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +// Subtraction; flip the sign bit of b and add. +COMPILER_RT_ABI fp_t +__subdf3(fp_t a, fp_t b) { + return __adddf3(a, fromRep(toRep(b) ^ signBit)); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI fp_t __aeabi_dsub(fp_t a, fp_t b) { + return __subdf3(a, b); +} +#else +AEABI_RTABI fp_t __aeabi_dsub(fp_t a, fp_t b) COMPILER_RT_ALIAS(__subdf3); +#endif +#endif diff --git a/third_party/compiler_rt/subsf3.c b/third_party/compiler_rt/subsf3.c new file mode 100644 index 00000000..586f3c76 --- /dev/null +++ b/third_party/compiler_rt/subsf3.c @@ -0,0 +1,35 @@ +/* clang-format off */ +//===-- lib/subsf3.c - Single-precision subtraction ---------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements single-precision soft-float subtraction with the +// IEEE-754 default rounding (to nearest, ties to even). +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SINGLE_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +// Subtraction; flip the sign bit of b and add. +COMPILER_RT_ABI fp_t +__subsf3(fp_t a, fp_t b) { + return __addsf3(a, fromRep(toRep(b) ^ signBit)); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI fp_t __aeabi_fsub(fp_t a, fp_t b) { + return __subsf3(a, b); +} +#else +AEABI_RTABI fp_t __aeabi_fsub(fp_t a, fp_t b) COMPILER_RT_ALIAS(__subsf3); +#endif +#endif diff --git a/third_party/compiler_rt/subtf3.c b/third_party/compiler_rt/subtf3.c new file mode 100644 index 00000000..56f30f1a --- /dev/null +++ b/third_party/compiler_rt/subtf3.c @@ -0,0 +1,30 @@ +/* clang-format off */ +//===-- lib/subtf3.c - Quad-precision subtraction -----------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements quad-precision soft-float subtraction with the +// IEEE-754 default rounding (to nearest, ties to even). +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +COMPILER_RT_ABI fp_t __addtf3(fp_t a, fp_t b); + +// Subtraction; flip the sign bit of b and add. +COMPILER_RT_ABI fp_t +__subtf3(fp_t a, fp_t b) { + return __addtf3(a, fromRep(toRep(b) ^ signBit)); +} + +#endif diff --git a/third_party/compiler_rt/trampoline_setup.c b/third_party/compiler_rt/trampoline_setup.c new file mode 100644 index 00000000..d6798b93 --- /dev/null +++ b/third_party/compiler_rt/trampoline_setup.c @@ -0,0 +1,51 @@ +/* clang-format off */ +/* ===----- trampoline_setup.c - Implement __trampoline_setup -------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +extern void __clear_cache(void* start, void* end); + +/* + * The ppc compiler generates calls to __trampoline_setup() when creating + * trampoline functions on the stack for use with nested functions. + * This function creates a custom 40-byte trampoline function on the stack + * which loads r11 with a pointer to the outer function's locals + * and then jumps to the target nested function. + */ + +#if __ppc__ && !defined(__powerpc64__) +COMPILER_RT_ABI void +__trampoline_setup(uint32_t* trampOnStack, int trampSizeAllocated, + const void* realFunc, void* localsPtr) +{ + /* should never happen, but if compiler did not allocate */ + /* enough space on stack for the trampoline, abort */ + if ( trampSizeAllocated < 40 ) + compilerrt_abort(); + + /* create trampoline */ + trampOnStack[0] = 0x7c0802a6; /* mflr r0 */ + trampOnStack[1] = 0x4800000d; /* bl Lbase */ + trampOnStack[2] = (uint32_t)realFunc; + trampOnStack[3] = (uint32_t)localsPtr; + trampOnStack[4] = 0x7d6802a6; /* Lbase: mflr r11 */ + trampOnStack[5] = 0x818b0000; /* lwz r12,0(r11) */ + trampOnStack[6] = 0x7c0803a6; /* mtlr r0 */ + trampOnStack[7] = 0x7d8903a6; /* mtctr r12 */ + trampOnStack[8] = 0x816b0004; /* lwz r11,4(r11) */ + trampOnStack[9] = 0x4e800420; /* bctr */ + + /* clear instruction cache */ + __clear_cache(trampOnStack, &trampOnStack[10]); +} +#endif /* __ppc__ && !defined(__powerpc64__) */ diff --git a/third_party/compiler_rt/truncdfhf2.c b/third_party/compiler_rt/truncdfhf2.c new file mode 100644 index 00000000..7b02a818 --- /dev/null +++ b/third_party/compiler_rt/truncdfhf2.c @@ -0,0 +1,29 @@ +/* clang-format off */ +//===-- lib/truncdfhf2.c - double -> half conversion --------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SRC_DOUBLE +#define DST_HALF +#include "third_party/compiler_rt/fp_trunc_impl.inc" + +COMPILER_RT_ABI uint16_t __truncdfhf2(double a) { + return __truncXfYf2__(a); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI uint16_t __aeabi_d2h(double a) { + return __truncdfhf2(a); +} +#else +AEABI_RTABI uint16_t __aeabi_d2h(double a) COMPILER_RT_ALIAS(__truncdfhf2); +#endif +#endif diff --git a/third_party/compiler_rt/truncdfsf2.c b/third_party/compiler_rt/truncdfsf2.c new file mode 100644 index 00000000..41ef176f --- /dev/null +++ b/third_party/compiler_rt/truncdfsf2.c @@ -0,0 +1,29 @@ +/* clang-format off */ +//===-- lib/truncdfsf2.c - double -> single conversion ------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SRC_DOUBLE +#define DST_SINGLE +#include "third_party/compiler_rt/fp_trunc_impl.inc" + +COMPILER_RT_ABI float __truncdfsf2(double a) { + return __truncXfYf2__(a); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI float __aeabi_d2f(double a) { + return __truncdfsf2(a); +} +#else +AEABI_RTABI float __aeabi_d2f(double a) COMPILER_RT_ALIAS(__truncdfsf2); +#endif +#endif diff --git a/third_party/compiler_rt/truncsfhf2.c b/third_party/compiler_rt/truncsfhf2.c new file mode 100644 index 00000000..5e0905f4 --- /dev/null +++ b/third_party/compiler_rt/truncsfhf2.c @@ -0,0 +1,35 @@ +/* clang-format off */ +//===-- lib/truncsfhf2.c - single -> half conversion --------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define SRC_SINGLE +#define DST_HALF +#include "third_party/compiler_rt/fp_trunc_impl.inc" + +// Use a forwarding definition and noinline to implement a poor man's alias, +// as there isn't a good cross-platform way of defining one. +COMPILER_RT_ABI __attribute__((__noinline__)) uint16_t __truncsfhf2(float a) { + return __truncXfYf2__(a); +} + +COMPILER_RT_ABI uint16_t __gnu_f2h_ieee(float a) { + return __truncsfhf2(a); +} + +#if defined(__ARM_EABI__) +#if defined(COMPILER_RT_ARMHF_TARGET) +AEABI_RTABI uint16_t __aeabi_f2h(float a) { + return __truncsfhf2(a); +} +#else +AEABI_RTABI uint16_t __aeabi_f2h(float a) COMPILER_RT_ALIAS(__truncsfhf2); +#endif +#endif diff --git a/third_party/compiler_rt/trunctfdf2.c b/third_party/compiler_rt/trunctfdf2.c new file mode 100644 index 00000000..61614e97 --- /dev/null +++ b/third_party/compiler_rt/trunctfdf2.c @@ -0,0 +1,25 @@ +/* clang-format off */ +//===-- lib/truncdfsf2.c - quad -> double conversion --------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +#define SRC_QUAD +#define DST_DOUBLE +#include "third_party/compiler_rt/fp_trunc_impl.inc" + +COMPILER_RT_ABI double __trunctfdf2(long double a) { + return __truncXfYf2__(a); +} + +#endif diff --git a/third_party/compiler_rt/trunctfsf2.c b/third_party/compiler_rt/trunctfsf2.c new file mode 100644 index 00000000..cc3ba6e9 --- /dev/null +++ b/third_party/compiler_rt/trunctfsf2.c @@ -0,0 +1,25 @@ +/* clang-format off */ +//===-- lib/trunctfsf2.c - quad -> single conversion --------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +STATIC_YOINK("huge_compiler_rt_license"); + +#define QUAD_PRECISION +#include "third_party/compiler_rt/fp_lib.inc" + +#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) +#define SRC_QUAD +#define DST_SINGLE +#include "third_party/compiler_rt/fp_trunc_impl.inc" + +COMPILER_RT_ABI float __trunctfsf2(long double a) { + return __truncXfYf2__(a); +} + +#endif diff --git a/third_party/compiler_rt/ucmpdi2.c b/third_party/compiler_rt/ucmpdi2.c new file mode 100644 index 00000000..6da61b61 --- /dev/null +++ b/third_party/compiler_rt/ucmpdi2.c @@ -0,0 +1,54 @@ +/* clang-format off */ +/* ===-- ucmpdi2.c - Implement __ucmpdi2 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __ucmpdi2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: if (a < b) returns 0 + * if (a == b) returns 1 + * if (a > b) returns 2 + */ + +COMPILER_RT_ABI si_int +__ucmpdi2(du_int a, du_int b) +{ + udwords x; + x.all = a; + udwords y; + y.all = b; + if (x.s.high < y.s.high) + return 0; + if (x.s.high > y.s.high) + return 2; + if (x.s.low < y.s.low) + return 0; + if (x.s.low > y.s.low) + return 2; + return 1; +} + +#ifdef __ARM_EABI__ +/* Returns: if (a < b) returns -1 +* if (a == b) returns 0 +* if (a > b) returns 1 +*/ +COMPILER_RT_ABI si_int +__aeabi_ulcmp(di_int a, di_int b) +{ + return __ucmpdi2(a, b) - 1; +} +#endif + diff --git a/third_party/compiler_rt/ucmpti2.c b/third_party/compiler_rt/ucmpti2.c new file mode 100644 index 00000000..41ca69c2 --- /dev/null +++ b/third_party/compiler_rt/ucmpti2.c @@ -0,0 +1,45 @@ +/* clang-format off */ +/* ===-- ucmpti2.c - Implement __ucmpti2 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __ucmpti2 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: if (a < b) returns 0 + * if (a == b) returns 1 + * if (a > b) returns 2 + */ + +COMPILER_RT_ABI si_int +__ucmpti2(tu_int a, tu_int b) +{ + utwords x; + x.all = a; + utwords y; + y.all = b; + if (x.s.high < y.s.high) + return 0; + if (x.s.high > y.s.high) + return 2; + if (x.s.low < y.s.low) + return 0; + if (x.s.low > y.s.low) + return 2; + return 1; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/udivdi3.c b/third_party/compiler_rt/udivdi3.c new file mode 100644 index 00000000..96ac0d61 --- /dev/null +++ b/third_party/compiler_rt/udivdi3.c @@ -0,0 +1,26 @@ +/* clang-format off */ +/* ===-- udivdi3.c - Implement __udivdi3 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __udivdi3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a / b */ + +COMPILER_RT_ABI du_int +__udivdi3(du_int a, du_int b) +{ + return __udivmoddi4(a, b, 0); +} diff --git a/third_party/compiler_rt/udivmoddi4.c b/third_party/compiler_rt/udivmoddi4.c new file mode 100644 index 00000000..2599d078 --- /dev/null +++ b/third_party/compiler_rt/udivmoddi4.c @@ -0,0 +1,234 @@ +/* clang-format off */ +/* ===-- udivmoddi4.c - Implement __udivmoddi4 -----------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __udivmoddi4 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Effects: if rem != 0, *rem = a % b + * Returns: a / b + */ + +/* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */ + +COMPILER_RT_ABI du_int +__udivmoddi4(du_int a, du_int b, du_int* rem) +{ + const unsigned n_uword_bits = sizeof(su_int) * CHAR_BIT; + const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT; + udwords n; + n.all = a; + udwords d; + d.all = b; + udwords q; + udwords r; + unsigned sr; + /* special cases, X is unknown, K != 0 */ + if (n.s.high == 0) + { + if (d.s.high == 0) + { + /* 0 X + * --- + * 0 X + */ + if (rem) + *rem = n.s.low % d.s.low; + return n.s.low / d.s.low; + } + /* 0 X + * --- + * K X + */ + if (rem) + *rem = n.s.low; + return 0; + } + /* n.s.high != 0 */ + if (d.s.low == 0) + { + if (d.s.high == 0) + { + /* K X + * --- + * 0 0 + */ + if (rem) + *rem = n.s.high % d.s.low; + return n.s.high / d.s.low; + } + /* d.s.high != 0 */ + if (n.s.low == 0) + { + /* K 0 + * --- + * K 0 + */ + if (rem) + { + r.s.high = n.s.high % d.s.high; + r.s.low = 0; + *rem = r.all; + } + return n.s.high / d.s.high; + } + /* K K + * --- + * K 0 + */ + if ((d.s.high & (d.s.high - 1)) == 0) /* if d is a power of 2 */ + { + if (rem) + { + r.s.low = n.s.low; + r.s.high = n.s.high & (d.s.high - 1); + *rem = r.all; + } + return n.s.high >> __builtin_ctz(d.s.high); + } + /* K K + * --- + * K 0 + */ + sr = __builtin_clz(d.s.high) - __builtin_clz(n.s.high); + /* 0 <= sr <= n_uword_bits - 2 or sr large */ + if (sr > n_uword_bits - 2) + { + if (rem) + *rem = n.all; + return 0; + } + ++sr; + /* 1 <= sr <= n_uword_bits - 1 */ + /* q.all = n.all << (n_udword_bits - sr); */ + q.s.low = 0; + q.s.high = n.s.low << (n_uword_bits - sr); + /* r.all = n.all >> sr; */ + r.s.high = n.s.high >> sr; + r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr); + } + else /* d.s.low != 0 */ + { + if (d.s.high == 0) + { + /* K X + * --- + * 0 K + */ + if ((d.s.low & (d.s.low - 1)) == 0) /* if d is a power of 2 */ + { + if (rem) + *rem = n.s.low & (d.s.low - 1); + if (d.s.low == 1) + return n.all; + sr = __builtin_ctz(d.s.low); + q.s.high = n.s.high >> sr; + q.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr); + return q.all; + } + /* K X + * --- + * 0 K + */ + sr = 1 + n_uword_bits + __builtin_clz(d.s.low) - __builtin_clz(n.s.high); + /* 2 <= sr <= n_udword_bits - 1 + * q.all = n.all << (n_udword_bits - sr); + * r.all = n.all >> sr; + */ + if (sr == n_uword_bits) + { + q.s.low = 0; + q.s.high = n.s.low; + r.s.high = 0; + r.s.low = n.s.high; + } + else if (sr < n_uword_bits) // 2 <= sr <= n_uword_bits - 1 + { + q.s.low = 0; + q.s.high = n.s.low << (n_uword_bits - sr); + r.s.high = n.s.high >> sr; + r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr); + } + else // n_uword_bits + 1 <= sr <= n_udword_bits - 1 + { + q.s.low = n.s.low << (n_udword_bits - sr); + q.s.high = (n.s.high << (n_udword_bits - sr)) | + (n.s.low >> (sr - n_uword_bits)); + r.s.high = 0; + r.s.low = n.s.high >> (sr - n_uword_bits); + } + } + else + { + /* K X + * --- + * K K + */ + sr = __builtin_clz(d.s.high) - __builtin_clz(n.s.high); + /* 0 <= sr <= n_uword_bits - 1 or sr large */ + if (sr > n_uword_bits - 1) + { + if (rem) + *rem = n.all; + return 0; + } + ++sr; + /* 1 <= sr <= n_uword_bits */ + /* q.all = n.all << (n_udword_bits - sr); */ + q.s.low = 0; + if (sr == n_uword_bits) + { + q.s.high = n.s.low; + r.s.high = 0; + r.s.low = n.s.high; + } + else + { + q.s.high = n.s.low << (n_uword_bits - sr); + r.s.high = n.s.high >> sr; + r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr); + } + } + } + /* Not a special case + * q and r are initialized with: + * q.all = n.all << (n_udword_bits - sr); + * r.all = n.all >> sr; + * 1 <= sr <= n_udword_bits - 1 + */ + su_int carry = 0; + for (; sr > 0; --sr) + { + /* r:q = ((r:q) << 1) | carry */ + r.s.high = (r.s.high << 1) | (r.s.low >> (n_uword_bits - 1)); + r.s.low = (r.s.low << 1) | (q.s.high >> (n_uword_bits - 1)); + q.s.high = (q.s.high << 1) | (q.s.low >> (n_uword_bits - 1)); + q.s.low = (q.s.low << 1) | carry; + /* carry = 0; + * if (r.all >= d.all) + * { + * r.all -= d.all; + * carry = 1; + * } + */ + const di_int s = (di_int)(d.all - r.all - 1) >> (n_udword_bits - 1); + carry = s & 1; + r.all -= d.all & s; + } + q.all = (q.all << 1) | carry; + if (rem) + *rem = r.all; + return q.all; +} diff --git a/third_party/compiler_rt/udivmodsi4.c b/third_party/compiler_rt/udivmodsi4.c new file mode 100644 index 00000000..386da175 --- /dev/null +++ b/third_party/compiler_rt/udivmodsi4.c @@ -0,0 +1,30 @@ +/* clang-format off */ +/*===-- udivmodsi4.c - Implement __udivmodsi4 ------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __udivmodsi4 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a / b, *rem = a % b */ + +COMPILER_RT_ABI su_int +__udivmodsi4(su_int a, su_int b, su_int* rem) +{ + si_int d = __udivsi3(a,b); + *rem = a - (d*b); + return d; +} + + diff --git a/third_party/compiler_rt/udivmodti4.c b/third_party/compiler_rt/udivmodti4.c new file mode 100644 index 00000000..e0109aa8 --- /dev/null +++ b/third_party/compiler_rt/udivmodti4.c @@ -0,0 +1,241 @@ +/* clang-format off */ +/* ===-- udivmodti4.c - Implement __udivmodti4 -----------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __udivmodti4 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Effects: if rem != 0, *rem = a % b + * Returns: a / b + */ + +/* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */ + +COMPILER_RT_ABI tu_int +__udivmodti4(tu_int a, tu_int b, tu_int* rem) +{ + const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT; + const unsigned n_utword_bits = sizeof(tu_int) * CHAR_BIT; + utwords n; + n.all = a; + utwords d; + d.all = b; + utwords q; + utwords r; + unsigned sr; + /* special cases, X is unknown, K != 0 */ + if (n.s.high == 0) + { + if (d.s.high == 0) + { + /* 0 X + * --- + * 0 X + */ + if (rem) + *rem = n.s.low % d.s.low; + return n.s.low / d.s.low; + } + /* 0 X + * --- + * K X + */ + if (rem) + *rem = n.s.low; + return 0; + } + /* n.s.high != 0 */ + if (d.s.low == 0) + { + if (d.s.high == 0) + { + /* K X + * --- + * 0 0 + */ + if (rem) + *rem = n.s.high % d.s.low; + return n.s.high / d.s.low; + } + /* d.s.high != 0 */ + if (n.s.low == 0) + { + /* K 0 + * --- + * K 0 + */ + if (rem) + { + r.s.high = n.s.high % d.s.high; + r.s.low = 0; + *rem = r.all; + } + return n.s.high / d.s.high; + } + /* K K + * --- + * K 0 + */ + if ((d.s.high & (d.s.high - 1)) == 0) /* if d is a power of 2 */ + { + if (rem) + { + r.s.low = n.s.low; + r.s.high = n.s.high & (d.s.high - 1); + *rem = r.all; + } + return n.s.high >> __builtin_ctzll(d.s.high); + } + /* K K + * --- + * K 0 + */ + sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high); + /* 0 <= sr <= n_udword_bits - 2 or sr large */ + if (sr > n_udword_bits - 2) + { + if (rem) + *rem = n.all; + return 0; + } + ++sr; + /* 1 <= sr <= n_udword_bits - 1 */ + /* q.all = n.all << (n_utword_bits - sr); */ + q.s.low = 0; + q.s.high = n.s.low << (n_udword_bits - sr); + /* r.all = n.all >> sr; */ + r.s.high = n.s.high >> sr; + r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr); + } + else /* d.s.low != 0 */ + { + if (d.s.high == 0) + { + /* K X + * --- + * 0 K + */ + if ((d.s.low & (d.s.low - 1)) == 0) /* if d is a power of 2 */ + { + if (rem) + *rem = n.s.low & (d.s.low - 1); + if (d.s.low == 1) + return n.all; + sr = __builtin_ctzll(d.s.low); + q.s.high = n.s.high >> sr; + q.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr); + return q.all; + } + /* K X + * --- + * 0 K + */ + sr = 1 + n_udword_bits + __builtin_clzll(d.s.low) + - __builtin_clzll(n.s.high); + /* 2 <= sr <= n_utword_bits - 1 + * q.all = n.all << (n_utword_bits - sr); + * r.all = n.all >> sr; + */ + if (sr == n_udword_bits) + { + q.s.low = 0; + q.s.high = n.s.low; + r.s.high = 0; + r.s.low = n.s.high; + } + else if (sr < n_udword_bits) // 2 <= sr <= n_udword_bits - 1 + { + q.s.low = 0; + q.s.high = n.s.low << (n_udword_bits - sr); + r.s.high = n.s.high >> sr; + r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr); + } + else // n_udword_bits + 1 <= sr <= n_utword_bits - 1 + { + q.s.low = n.s.low << (n_utword_bits - sr); + q.s.high = (n.s.high << (n_utword_bits - sr)) | + (n.s.low >> (sr - n_udword_bits)); + r.s.high = 0; + r.s.low = n.s.high >> (sr - n_udword_bits); + } + } + else + { + /* K X + * --- + * K K + */ + sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high); + /*0 <= sr <= n_udword_bits - 1 or sr large */ + if (sr > n_udword_bits - 1) + { + if (rem) + *rem = n.all; + return 0; + } + ++sr; + /* 1 <= sr <= n_udword_bits + * q.all = n.all << (n_utword_bits - sr); + * r.all = n.all >> sr; + */ + q.s.low = 0; + if (sr == n_udword_bits) + { + q.s.high = n.s.low; + r.s.high = 0; + r.s.low = n.s.high; + } + else + { + r.s.high = n.s.high >> sr; + r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr); + q.s.high = n.s.low << (n_udword_bits - sr); + } + } + } + /* Not a special case + * q and r are initialized with: + * q.all = n.all << (n_utword_bits - sr); + * r.all = n.all >> sr; + * 1 <= sr <= n_utword_bits - 1 + */ + su_int carry = 0; + for (; sr > 0; --sr) + { + /* r:q = ((r:q) << 1) | carry */ + r.s.high = (r.s.high << 1) | (r.s.low >> (n_udword_bits - 1)); + r.s.low = (r.s.low << 1) | (q.s.high >> (n_udword_bits - 1)); + q.s.high = (q.s.high << 1) | (q.s.low >> (n_udword_bits - 1)); + q.s.low = (q.s.low << 1) | carry; + /* carry = 0; + * if (r.all >= d.all) + * { + * r.all -= d.all; + * carry = 1; + * } + */ + const ti_int s = (ti_int)(d.all - r.all - 1) >> (n_utword_bits - 1); + carry = s & 1; + r.all -= d.all & s; + } + q.all = (q.all << 1) | carry; + if (rem) + *rem = r.all; + return q.all; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/udivsi3.c b/third_party/compiler_rt/udivsi3.c new file mode 100644 index 00000000..c293490b --- /dev/null +++ b/third_party/compiler_rt/udivsi3.c @@ -0,0 +1,71 @@ +/* clang-format off */ +/* ===-- udivsi3.c - Implement __udivsi3 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __udivsi3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a / b */ + +/* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */ + +/* This function should not call __divsi3! */ +COMPILER_RT_ABI su_int +__udivsi3(su_int n, su_int d) +{ + const unsigned n_uword_bits = sizeof(su_int) * CHAR_BIT; + su_int q; + su_int r; + unsigned sr; + /* special cases */ + if (d == 0) + return 0; /* ?! */ + if (n == 0) + return 0; + sr = __builtin_clz(d) - __builtin_clz(n); + /* 0 <= sr <= n_uword_bits - 1 or sr large */ + if (sr > n_uword_bits - 1) /* d > r */ + return 0; + if (sr == n_uword_bits - 1) /* d == 1 */ + return n; + ++sr; + /* 1 <= sr <= n_uword_bits - 1 */ + /* Not a special case */ + q = n << (n_uword_bits - sr); + r = n >> sr; + su_int carry = 0; + for (; sr > 0; --sr) + { + /* r:q = ((r:q) << 1) | carry */ + r = (r << 1) | (q >> (n_uword_bits - 1)); + q = (q << 1) | carry; + /* carry = 0; + * if (r.all >= d.all) + * { + * r.all -= d.all; + * carry = 1; + * } + */ + const si_int s = (si_int)(d - r - 1) >> (n_uword_bits - 1); + carry = s & 1; + r -= d & s; + } + q = (q << 1) | carry; + return q; +} + +#if defined(__ARM_EABI__) +AEABI_RTABI su_int __aeabi_uidiv(su_int n, su_int d) COMPILER_RT_ALIAS(__udivsi3); +#endif diff --git a/third_party/compiler_rt/udivti3.c b/third_party/compiler_rt/udivti3.c new file mode 100644 index 00000000..f4a6b362 --- /dev/null +++ b/third_party/compiler_rt/udivti3.c @@ -0,0 +1,30 @@ +/* clang-format off */ +/* ===-- udivti3.c - Implement __udivti3 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __udivti3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: a / b */ + +COMPILER_RT_ABI tu_int +__udivti3(tu_int a, tu_int b) +{ + return __udivmodti4(a, b, 0); +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/compiler_rt/umoddi3.c b/third_party/compiler_rt/umoddi3.c new file mode 100644 index 00000000..7edfc3de --- /dev/null +++ b/third_party/compiler_rt/umoddi3.c @@ -0,0 +1,28 @@ +/* clang-format off */ +/* ===-- umoddi3.c - Implement __umoddi3 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __umoddi3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a % b */ + +COMPILER_RT_ABI du_int +__umoddi3(du_int a, du_int b) +{ + du_int r; + __udivmoddi4(a, b, &r); + return r; +} diff --git a/third_party/compiler_rt/umodsi3.c b/third_party/compiler_rt/umodsi3.c new file mode 100644 index 00000000..62571a3b --- /dev/null +++ b/third_party/compiler_rt/umodsi3.c @@ -0,0 +1,26 @@ +/* clang-format off */ +/* ===-- umodsi3.c - Implement __umodsi3 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __umodsi3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +/* Returns: a % b */ + +COMPILER_RT_ABI su_int +__umodsi3(su_int a, su_int b) +{ + return a - __udivsi3(a, b) * b; +} diff --git a/third_party/compiler_rt/umodti3.c b/third_party/compiler_rt/umodti3.c new file mode 100644 index 00000000..399ecc1c --- /dev/null +++ b/third_party/compiler_rt/umodti3.c @@ -0,0 +1,32 @@ +/* clang-format off */ +/* ===-- umodti3.c - Implement __umodti3 -----------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __umodti3 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +STATIC_YOINK("huge_compiler_rt_license"); + +#include "third_party/compiler_rt/int_lib.h" + +#ifdef CRT_HAS_128BIT + +/* Returns: a % b */ + +COMPILER_RT_ABI tu_int +__umodti3(tu_int a, tu_int b) +{ + tu_int r; + __udivmodti4(a, b, &r); + return r; +} + +#endif /* CRT_HAS_128BIT */ diff --git a/third_party/dlmalloc/COPYING b/third_party/dlmalloc/COPYING new file mode 100644 index 00000000..3ce09cea --- /dev/null +++ b/third_party/dlmalloc/COPYING @@ -0,0 +1,10 @@ +/ Since dlmalloc is public domain, we intend to keep it that way. To the +/ extent possible under law, Justine Tunney has waived all copyright and +/ related or neighboring rights to her /third_party/dlmalloc changes, as +/ it is written in the following disclaimers: +/ • unlicense.org +/ • creativecommons.org/publicdomain/zero/1.0/ + +.ident "\n +dlmalloc (Public Domain CC0) +Credit: Doug Lea " diff --git a/third_party/dlmalloc/README b/third_party/dlmalloc/README new file mode 100644 index 00000000..7e9ced0c --- /dev/null +++ b/third_party/dlmalloc/README @@ -0,0 +1,825 @@ + + This is a version (aka dlmalloc) of malloc/free/realloc written by + Doug Lea and released to the public domain, as explained at + http://creativecommons.org/publicdomain/zero/1.0/ Send questions, + comments, complaints, performance data, etc to dl@cs.oswego.edu + + Version 2.8.6 Wed Aug 29 06:57:58 2012 Doug Lea + Note: There may be an updated version of this malloc obtainable at + ftp://gee.cs.oswego.edu/pub/misc/malloc.c + Check before installing! + +* Quickstart + + This library is all in one file to simplify the most common usage: + ftp it, compile it (-O3), and link it into another program. All of + the compile-time options default to reasonable values for use on + most platforms. You might later want to step through various + compile-time and dynamic tuning options. + + For convenience, an include file for code using this malloc is at: + ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.6.h + You don't really need this .h file unless you call functions not + defined in your system include files. The .h file contains only the + excerpts from this file needed for using this malloc on ANSI C/C++ + systems, so long as you haven't changed compile-time options about + naming and tuning parameters. If you do, then you can create your + own malloc.h that does include all settings by cutting at the point + indicated below. Note that you may already by default be using a C + library containing a malloc that is based on some version of this + malloc (for example in linux). You might still want to use the one + in this file to customize settings or to avoid overheads associated + with library versions. + +* Vital statistics: + + Supported pointer/size_t representation: 4 or 8 bytes + size_t MUST be an unsigned type of the same width as + pointers. (If you are using an ancient system that declares + size_t as a signed type, or need it to be a different width + than pointers, you can use a previous release of this malloc + (e.g. 2.7.2) supporting these.) + + Alignment: 8 bytes (minimum) + Is set to 16 for NexGen32e. + + Minimum overhead per allocated chunk: 4 or 8 bytes (if 4byte sizes) + 8 or 16 bytes (if 8byte sizes) + Each malloced chunk has a hidden word of overhead holding size + and status information, and additional cross-check word + if FOOTERS is defined. + + Minimum allocated size: 4-byte ptrs: 16 bytes (including overhead) + 8-byte ptrs: 32 bytes (including overhead) + + Even a request for zero bytes (i.e., malloc(0)) returns a + pointer to something of the minimum allocatable size. + The maximum overhead wastage (i.e., number of extra bytes + allocated than were requested in malloc) is less than or equal + to the minimum size, except for requests >= mmap_threshold that + are serviced via mmap(), where the worst case wastage is about + 32 bytes plus the remainder from a system page (the minimal + mmap unit); typically 4096 or 8192 bytes. + + Security: static-safe; optionally more or less + The "security" of malloc refers to the ability of malicious + code to accentuate the effects of errors (for example, freeing + space that is not currently malloc'ed or overwriting past the + ends of chunks) in code that calls malloc. This malloc + guarantees not to modify any memory locations below the base of + heap, i.e., static variables, even in the presence of usage + errors. The routines additionally detect most improper frees + and reallocs. All this holds as long as the static bookkeeping + for malloc itself is not corrupted by some other means. This + is only one aspect of security -- these checks do not, and + cannot, detect all possible programming errors. + + If FOOTERS is defined nonzero, then each allocated chunk + carries an additional check word to verify that it was malloced + from its space. These check words are the same within each + execution of a program using malloc, but differ across + executions, so externally crafted fake chunks cannot be + freed. This improves security by rejecting frees/reallocs that + could corrupt heap memory, in addition to the checks preventing + writes to statics that are always on. This may further improve + security at the expense of time and space overhead. (Note that + FOOTERS may also be worth using with MSPACES.) + + By default detected errors cause the program to abort (calling + "abort()"). You can override this to instead proceed past + errors by defining PROCEED_ON_ERROR. In this case, a bad free + has no effect, and a malloc that encounters a bad address + caused by user overwrites will ignore the bad address by + dropping pointers and indices to all known memory. This may + be appropriate for programs that should continue if at all + possible in the face of programming errors, although they may + run out of memory because dropped memory is never reclaimed. + + If you don't like either of these options, you can define + CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything + else. And if if you are sure that your program using malloc has + no errors or vulnerabilities, you can define TRUSTWORTHY to 1, + which might (or might not) provide a small performance improvement. + + It is also possible to limit the maximum total allocatable + space, using malloc_set_footprint_limit. This is not + designed as a security feature in itself (calls to set limits + are not screened or privileged), but may be useful as one + aspect of a secure implementation. + + Thread-safety: NOT thread-safe unless USE_LOCKS defined non-zero + When USE_LOCKS is defined, each public call to malloc, free, + etc is surrounded with a lock. By default, this uses a plain + pthread mutex, win32 critical section, or a spin-lock if if + available for the platform and not disabled by setting + USE_SPIN_LOCKS=0. However, if USE_RECURSIVE_LOCKS is defined, + recursive versions are used instead (which are not required for + base functionality but may be needed in layered extensions). + Using a global lock is not especially fast, and can be a major + bottleneck. It is designed only to provide minimal protection + in concurrent environments, and to provide a basis for + extensions. If you are using malloc in a concurrent program, + consider instead using nedmalloc + (http://www.nedprod.com/programs/portable/nedmalloc/) or + ptmalloc (See http://www.malloc.de), which are derived from + versions of this malloc. + + System requirements: Any combination of MORECORE and/or MMAP/MUNMAP + This malloc can use unix sbrk or any emulation (invoked using + the CALL_MORECORE macro) and/or mmap/munmap or any emulation + (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system + memory. On most unix systems, it tends to work best if both + MORECORE and MMAP are enabled. On Win32, it uses emulations + based on VirtualAlloc. It also uses common C library functions + like memset. + + Compliance: I believe it is compliant with the Single Unix Specification + (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably + others as well. + +* Overview of algorithms + + This is not the fastest, most space-conserving, most portable, or + most tunable malloc ever written. However it is among the fastest + while also being among the most space-conserving, portable and + tunable. Consistent balance across these factors results in a good + general-purpose allocator for malloc-intensive programs. + + In most ways, this malloc is a best-fit allocator. Generally, it + chooses the best-fitting existing chunk for a request, with ties + broken in approximately least-recently-used order. (This strategy + normally maintains low fragmentation.) However, for requests less + than 256bytes, it deviates from best-fit when there is not an + exactly fitting available chunk by preferring to use space adjacent + to that used for the previous small request, as well as by breaking + ties in approximately most-recently-used order. (These enhance + locality of series of small allocations.) And for very large requests + (>= 256Kb by default), it relies on system memory mapping + facilities, if supported. (This helps avoid carrying around and + possibly fragmenting memory used only for large chunks.) + + All operations (except malloc_stats and mallinfo) have execution + times that are bounded by a constant factor of the number of bits in + a size_t, not counting any clearing in calloc or copying in realloc, + or actions surrounding MORECORE and MMAP that have times + proportional to the number of non-contiguous regions returned by + system allocation routines, which is often just 1. In real-time + applications, you can optionally suppress segment traversals using + NO_SEGMENT_TRAVERSAL, which assures bounded execution even when + system allocators return non-contiguous spaces, at the typical + expense of carrying around more memory and increased fragmentation. + + The implementation is not very modular and seriously overuses + macros. Perhaps someday all C compilers will do as good a job + inlining modular code as can now be done by brute-force expansion, + but now, enough of them seem not to. + + Some compilers issue a lot of warnings about code that is + dead/unreachable only on some platforms, and also about intentional + uses of negation on unsigned types. All known cases of each can be + ignored. + + For a longer but out of date high-level description, see + http://gee.cs.oswego.edu/dl/html/malloc.html + +* MSPACES + If MSPACES is defined, then in addition to malloc, free, etc., + this file also defines mspace_malloc, mspace_free, etc. These + are versions of malloc routines that take an "mspace" argument + obtained using create_mspace, to control all internal bookkeeping. + If ONLY_MSPACES is defined, only these versions are compiled. + So if you would like to use this allocator for only some allocations, + and your system malloc for others, you can compile with + ONLY_MSPACES and then do something like... + static mspace mymspace = create_mspace(0,0); // for example + #define mymalloc(bytes) mspace_malloc(mymspace, bytes) + + (Note: If you only need one instance of an mspace, you can instead + use "USE_DL_PREFIX" to relabel the global malloc.) + + You can similarly create thread-local allocators by storing + mspaces as thread-locals. For example: + static __thread mspace tlms = 0; + void* tlmalloc(size_t bytes) { + if (tlms == 0) tlms = create_mspace(0, 0); + return mspace_malloc(tlms, bytes); + } + void tlfree(void* mem) { mspace_free(tlms, mem); } + + Unless FOOTERS is defined, each mspace is completely independent. + You cannot allocate from one and free to another (although + conformance is only weakly checked, so usage errors are not always + caught). If FOOTERS is defined, then each chunk carries around a tag + indicating its originating mspace, and frees are directed to their + originating spaces. Normally, this requires use of locks. + + ───────────────────────── Compile-time options ─────────────────────────── + +Be careful in setting #define values for numerical constants of type +size_t. On some systems, literal values are not automatically extended +to size_t precision unless they are explicitly casted. You can also +use the symbolic values SIZE_MAX, SIZE_T_ONE, etc below. + +WIN32 default: defined if _WIN32 defined + Defining WIN32 sets up defaults for MS environment and compilers. + Otherwise defaults are for unix. Beware that there seem to be some + cases where this malloc might not be a pure drop-in replacement for + Win32 malloc: Random-looking failures from Win32 GDI API's (eg; + SetDIBits()) may be due to bugs in some video driver implementations + when pixel buffers are malloc()ed, and the region spans more than + one VirtualAlloc()ed region. Because dlmalloc uses a small (64Kb) + default granularity, pixel buffers may straddle virtual allocation + regions more often than when using the Microsoft allocator. You can + avoid this by using VirtualAlloc() and VirtualFree() for all pixel + buffers rather than using malloc(). If this is not possible, + recompile this malloc with a larger DEFAULT_GRANULARITY. Note: + in cases where MSC and gcc (cygwin) are known to differ on WIN32, + conditions use _MSC_VER to distinguish them. + +DLMALLOC_EXPORT default: extern + Defines how public APIs are declared. If you want to export via a + Windows DLL, you might define this as + #define DLMALLOC_EXPORT extern __declspec(dllexport) + If you want a POSIX ELF shared object, you might use + #define DLMALLOC_EXPORT extern __attribute__((visibility("default"))) + +MALLOC_ALIGNMENT default: (size_t)(2 * sizeof(void *)) + Controls the minimum alignment for malloc'ed chunks. It must be a + power of two and at least 8, even on machines for which smaller + alignments would suffice. It may be defined as larger than this + though. Note however that code and data structures are optimized for + the case of 8-byte alignment. + +MSPACES default: 0 (false) + If true, compile in support for independent allocation spaces. + This is only supported if HAVE_MMAP is true. + +ONLY_MSPACES default: 0 (false) + If true, only compile in mspace versions, not regular versions. + +USE_LOCKS default: 0 (false) + Causes each call to each public routine to be surrounded with + pthread or WIN32 mutex lock/unlock. (If set true, this can be + overridden on a per-mspace basis for mspace versions.) If set to a + non-zero value other than 1, locks are used, but their + implementation is left out, so lock functions must be supplied manually, + as described below. + +USE_SPIN_LOCKS default: 1 iff USE_LOCKS and spin locks available + If true, uses custom spin locks for locking. This is currently + supported only gcc >= 4.1, older gccs on x86 platforms, and recent + MS compilers. Otherwise, posix locks or win32 critical sections are + used. + +USE_RECURSIVE_LOCKS default: not defined + If defined nonzero, uses recursive (aka reentrant) locks, otherwise + uses plain mutexes. This is not required for malloc proper, but may + be needed for layered allocators such as nedmalloc. + +LOCK_AT_FORK default: not defined + If defined nonzero, performs pthread_atfork upon initialization + to initialize child lock while holding parent lock. The implementation + assumes that pthread locks (not custom locks) are being used. In other + cases, you may need to customize the implementation. + +FOOTERS default: 0 + If true, provide extra checking and dispatching by placing + information in the footers of allocated chunks. This adds + space and time overhead. + +TRUSTWORTHY default: 0 + If true, omit checks for usage errors and heap space overwrites. + +USE_DL_PREFIX default: NOT defined + Causes compiler to prefix all public routines with the string 'dl'. + This can be useful when you only want to use this malloc in one part + of a program, using your regular system malloc elsewhere. + +MALLOC_INSPECT_ALL default: NOT defined + If defined, compiles malloc_inspect_all and mspace_inspect_all, that + perform traversal of all heap space. Unless access to these + functions is otherwise restricted, you probably do not want to + include them in secure implementations. + +MALLOC_ABORT default: defined as abort() + Defines how to abort on failed checks. On most systems, a failed + check cannot die with an "assert" or even print an informative + message, because the underlying print routines in turn call malloc, + which will fail again. Generally, the best policy is to simply call + abort(). It's not very useful to do more than this because many + errors due to overwriting will show up as address faults (null, odd + addresses etc) rather than malloc-triggered checks, so will also + abort. Also, most compilers know that abort() does not return, so + can better optimize code conditionally calling it. + +PROCEED_ON_ERROR default: defined as 0 (false) + Controls whether detected bad addresses cause them to bypassed + rather than aborting. If set, detected bad arguments to free and + realloc are ignored. And all bookkeeping information is zeroed out + upon a detected overwrite of freed heap space, thus losing the + ability to ever return it from malloc again, but enabling the + application to proceed. If PROCEED_ON_ERROR is defined, the + static variable malloc_corruption_error_count is compiled in + and can be examined to see if errors have occurred. This option + generates slower code than the default abort policy. + +DEBUG default: NOT defined + The DEBUG setting is mainly intended for people trying to modify + this code or diagnose problems when porting to new platforms. + However, it may also be able to better isolate user errors than just + using runtime checks. The assertions in the check routines spell + out in more detail the assumptions and invariants underlying the + algorithms. The checking is fairly extensive, and will slow down + execution noticeably. Calling malloc_stats or mallinfo with DEBUG + set will attempt to check every non-mmapped allocated and free chunk + in the course of computing the summaries. + +ABORT_ON_ASSERT_FAILURE default: defined as 1 (true) + Debugging assertion failures can be nearly impossible if your + version of the assert macro causes malloc to be called, which will + lead to a cascade of further failures, blowing the runtime stack. + ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(), + which will usually make debugging easier. + +MALLOC_FAILURE_ACTION default: sets errno to ENOMEM, or no-op on win32 + The action to take before "return 0" when malloc fails to be able to + return memory because there is none available. + +HAVE_MORECORE default: 1 (true) unless win32 or ONLY_MSPACES + True if this system supports sbrk or an emulation of it. + +MORECORE default: sbrk + The name of the sbrk-style system routine to call to obtain more + memory. See below for guidance on writing custom MORECORE + functions. The type of the argument to sbrk/MORECORE varies across + systems. It cannot be size_t, because it supports negative + arguments, so it is normally the signed type of the same width as + size_t (sometimes declared as "intptr_t"). It doesn't much matter + though. Internally, we only call it with arguments less than half + the max value of a size_t, which should work across all reasonable + possibilities, although sometimes generating compiler warnings. + +MORECORE_CONTIGUOUS default: 1 (true) if HAVE_MORECORE + If true, take advantage of fact that consecutive calls to MORECORE + with positive arguments always return contiguous increasing + addresses. This is true of unix sbrk. It does not hurt too much to + set it true anyway, since malloc copes with non-contiguities. + Setting it false when definitely non-contiguous saves time + and possibly wasted space it would take to discover this though. + +MORECORE_CANNOT_TRIM default: NOT defined + True if MORECORE cannot release space back to the system when given + negative arguments. This is generally necessary only if you are + using a hand-crafted MORECORE function that cannot handle negative + arguments. + +NO_SEGMENT_TRAVERSAL default: 0 + If non-zero, suppresses traversals of memory segments + returned by either MORECORE or CALL_MMAP. This disables + merging of segments that are contiguous, and selectively + releasing them to the OS if unused, but bounds execution times. + +HAVE_MMAP default: 1 (true) + True if this system supports mmap or an emulation of it. If so, and + HAVE_MORECORE is not true, MMAP is used for all system + allocation. If set and HAVE_MORECORE is true as well, MMAP is + primarily used to directly allocate very large blocks. It is also + used as a backup strategy in cases where MORECORE fails to provide + space from system. Note: A single call to MUNMAP is assumed to be + able to unmap memory that may have be allocated using multiple calls + to MMAP, so long as they are adjacent. + +HAVE_MREMAP default: 1 on linux, else 0 + If true realloc() uses mremap() to re-allocate large blocks and + extend or shrink allocation spaces. + +MMAP_CLEARS default: 1 except on WINCE. + True if mmap clears memory so calloc doesn't need to. This is true + for standard unix mmap using /dev/zero and on WIN32 except for WINCE. + +USE_BUILTIN_FFS default: 0 (i.e., not used) + Causes malloc to use the builtin ffs() function to compute indices. + Some compilers may recognize and intrinsify ffs to be faster than the + supplied C version. Also, the case of x86 using gcc is special-cased + to an asm instruction, so is already as fast as it can be, and so + this setting has no effect. Similarly for Win32 under recent MS compilers. + (On most x86s, the asm version is only slightly faster than the C version.) + +malloc_getpagesize default: derive from system includes, or 4096. + The system page size. To the extent possible, this malloc manages + memory from the system in page-size units. This may be (and + usually is) a function rather than a constant. This is ignored + if WIN32, where page size is determined using getSystemInfo during + initialization. + +NO_MALLINFO default: 0 + If defined, don't compile "mallinfo". This can be a simple way + of dealing with mismatches between system declarations and + those in this file. + +MALLINFO_FIELD_TYPE default: size_t + The type of the fields in the mallinfo struct. This was originally + defined as "int" in SVID etc, but is more usefully defined as + size_t. The value is used only if HAVE_USR_INCLUDE_MALLOC_H is not set + +NO_MALLOC_STATS default: 0 + If defined, don't compile "malloc_stats". This avoids calls to + fprintf and bringing in stdio dependencies you might not want. + +REALLOC_ZERO_BYTES_FREES default: not defined + This should be set if a call to realloc with zero bytes should + be the same as a call to free. Some people think it should. Otherwise, + since this malloc returns a unique pointer for malloc(0), so does + realloc(p, 0). + +LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H +LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H, LACKS_ERRNO_H +LACKS_STDLIB_H LACKS_SCHED_H LACKS_TIME_H default: NOT defined unless on WIN32 + Define these if your system does not have these header files. + You might need to manually insert some of the declarations they provide. + +DEFAULT_GRANULARITY default: page size if MORECORE_CONTIGUOUS, + system_info.dwAllocationGranularity in WIN32, + otherwise 64K. + Also settable using mallopt(M_GRANULARITY, x) + The unit for allocating and deallocating memory from the system. On + most systems with contiguous MORECORE, there is no reason to + make this more than a page. However, systems with MMAP tend to + either require or encourage larger granularities. You can increase + this value to prevent system allocation functions to be called so + often, especially if they are slow. The value must be at least one + page and must be a power of two. Setting to 0 causes initialization + to either page size or win32 region size. (Note: In previous + versions of malloc, the equivalent of this option was called + "TOP_PAD") + +DEFAULT_TRIM_THRESHOLD default: 2MB + Also settable using mallopt(M_TRIM_THRESHOLD, x) + The maximum amount of unused top-most memory to keep before + releasing via malloc_trim in free(). Automatic trimming is mainly + useful in long-lived programs using contiguous MORECORE. Because + trimming via sbrk can be slow on some systems, and can sometimes be + wasteful (in cases where programs immediately afterward allocate + more large chunks) the value should be high enough so that your + overall system performance would improve by releasing this much + memory. As a rough guide, you might set to a value close to the + average size of a process (program) running on your system. + Releasing this much memory would allow such a process to run in + memory. Generally, it is worth tuning trim thresholds when a + program undergoes phases where several large chunks are allocated + and released in ways that can reuse each other's storage, perhaps + mixed with phases where there are no such chunks at all. The trim + value must be greater than page size to have any useful effect. To + disable trimming completely, you can set to SIZE_MAX. Note that the trick + some people use of mallocing a huge space and then freeing it at + program startup, in an attempt to reserve system memory, doesn't + have the intended effect under automatic trimming, since that memory + will immediately be returned to the system. + +DEFAULT_MMAP_THRESHOLD default: 256K + Also settable using mallopt(M_MMAP_THRESHOLD, x) + The request size threshold for using MMAP to directly service a + request. Requests of at least this size that cannot be allocated + using already-existing space will be serviced via mmap. (If enough + normal freed space already exists it is used instead.) Using mmap + segregates relatively large chunks of memory so that they can be + individually obtained and released from the host system. A request + serviced through mmap is never reused by any other request (at least + not directly; the system may just so happen to remap successive + requests to the same locations). Segregating space in this way has + the benefits that: Mmapped space can always be individually released + back to the system, which helps keep the system level memory demands + of a long-lived program low. Also, mapped memory doesn't become + `locked' between other chunks, as can happen with normally allocated + chunks, which means that even trimming via malloc_trim would not + release them. However, it has the disadvantage that the space + cannot be reclaimed, consolidated, and then used to service later + requests, as happens with normal chunks. The advantages of mmap + nearly always outweigh disadvantages for "large" chunks, but the + value of "large" may vary across systems. The default is an + empirically derived value that works well in most systems. You can + disable mmap by setting to SIZE_MAX. + +MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP + The number of consolidated frees between checks to release + unused segments when freeing. When using non-contiguous segments, + especially with multiple mspaces, checking only for topmost space + doesn't always suffice to trigger trimming. To compensate for this, + free() will, with a period of MAX_RELEASE_CHECK_RATE (or the + current number of segments, if greater) try to release unused + segments to the OS when freeing chunks that result in + consolidation. The best value for this parameter is a compromise + between slowing down frees with relatively costly checks that + rarely trigger versus holding on to unused memory. To effectively + disable, set to SIZE_MAX. This may lead to a very slight speed + improvement at the expense of carrying around more memory. + +──────────────────────────────────────────────────────────────────────────────── + +History: + + v2.8.6 Wed Aug 29 06:57:58 2012 Doug Lea + * fix bad comparison in dlposix_memalign + * don't reuse adjusted asize in sys_alloc + * add LOCK_AT_FORK -- thanks to Kirill Artamonov for the suggestion + * reduce compiler warnings -- thanks to all who reported/suggested these + + v2.8.5 Sun May 22 10:26:02 2011 Doug Lea (dl at gee) + * Always perform unlink checks unless TRUSTWORTHY + * Add posix_memalign. + * Improve realloc to expand in more cases; expose realloc_in_place. + Thanks to Peter Buhr for the suggestion. + * Add footprint_limit, inspect_all, bulk_free. Thanks + to Barry Hayes and others for the suggestions. + * Internal refactorings to avoid calls while holding locks + * Use non-reentrant locks by default. Thanks to Roland McGrath + for the suggestion. + * Small fixes to mspace_destroy, reset_on_error. + * Various configuration extensions/changes. Thanks + to all who contributed these. + + V2.8.4a Thu Apr 28 14:39:43 2011 (dl at gee.cs.oswego.edu) + * Update Creative Commons URL + + V2.8.4 Wed May 27 09:56:23 2009 Doug Lea (dl at gee) + * Use zeros instead of prev foot for is_mmapped + * Add mspace_track_large_chunks; thanks to Jean Brouwers + * Fix set_inuse in internal_realloc; thanks to Jean Brouwers + * Fix insufficient sys_alloc padding when using 16byte alignment + * Fix bad error check in mspace_footprint + * Adaptations for ptmalloc; thanks to Wolfram Gloger. + * Reentrant spin locks; thanks to Earl Chew and others + * Win32 improvements; thanks to Niall Douglas and Earl Chew + * Add NO_SEGMENT_TRAVERSAL and MAX_RELEASE_CHECK_RATE options + * Extension hook in malloc_state + * Various small adjustments to reduce warnings on some compilers + * Various configuration extensions/changes for more platforms. Thanks + to all who contributed these. + + V2.8.3 Thu Sep 22 11:16:32 2005 Doug Lea (dl at gee) + * Add max_footprint functions + * Ensure all appropriate literals are size_t + * Fix conditional compilation problem for some #define settings + * Avoid concatenating segments with the one provided + in create_mspace_with_base + * Rename some variables to avoid compiler shadowing warnings + * Use explicit lock initialization. + * Better handling of sbrk interference. + * Simplify and fix segment insertion, trimming and mspace_destroy + * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x + * Thanks especially to Dennis Flanagan for help on these. + + V2.8.2 Sun Jun 12 16:01:10 2005 Doug Lea (dl at gee) + * Fix memalign brace error. + + V2.8.1 Wed Jun 8 16:11:46 2005 Doug Lea (dl at gee) + * Fix improper #endif nesting in C++ + * Add explicit casts needed for C++ + + V2.8.0 Mon May 30 14:09:02 2005 Doug Lea (dl at gee) + * Use trees for large bins + * Support mspaces + * Use segments to unify sbrk-based and mmap-based system allocation, + removing need for emulation on most platforms without sbrk. + * Default safety checks + * Optional footer checks. Thanks to William Robertson for the idea. + * Internal code refactoring + * Incorporate suggestions and platform-specific changes. + Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas, + Aaron Bachmann, Emery Berger, and others. + * Speed up non-fastbin processing enough to remove fastbins. + * Remove useless cfree() to avoid conflicts with other apps. + * Remove internal memcpy, memset. Compilers handle builtins better. + * Remove some options that no one ever used and rename others. + + V2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) + * Fix malloc_state bitmap array misdeclaration + + V2.7.1 Thu Jul 25 10:58:03 2002 Doug Lea (dl at gee) + * Allow tuning of FIRST_SORTED_BIN_SIZE + * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte. + * Better detection and support for non-contiguousness of MORECORE. + Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger + * Bypass most of malloc if no frees. Thanks To Emery Berger. + * Fix freeing of old top non-contiguous chunk im sysmalloc. + * Raised default trim and map thresholds to 256K. + * Fix mmap-related #defines. Thanks to Lubos Lunak. + * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield. + * Branch-free bin calculation + * Default trim and mmap thresholds now 256K. + + V2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee) + * Introduce independent_comalloc and independent_calloc. + Thanks to Michael Pachos for motivation and help. + * Make optional .h file available + * Allow > 2GB requests on 32bit systems. + * new WIN32 sbrk, mmap, munmap, lock code from . + Thanks also to Andreas Mueller , + and Anonymous. + * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for + helping test this.) + * memalign: check alignment arg + * realloc: don't try to shift chunks backwards, since this + leads to more fragmentation in some programs and doesn't + seem to help in any others. + * Collect all cases in malloc requiring system memory into sysmalloc + * Use mmap as backup to sbrk + * Place all internal state in malloc_state + * Introduce fastbins (although similar to 2.5.1) + * Many minor tunings and cosmetic improvements + * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK + * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS + Thanks to Tony E. Bennett and others. + * Include errno.h to support default failure action. + + V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee) + * return null for negative arguments + * Added Several WIN32 cleanups from Martin C. Fong + * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h' + (e.g. WIN32 platforms) + * Cleanup header file inclusion for WIN32 platforms + * Cleanup code to avoid Microsoft Visual C++ compiler complaints + * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing + memory allocation routines + * Set 'malloc_getpagesize' for WIN32 platforms (needs more work) + * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to + usage of 'assert' in non-WIN32 code + * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to + avoid infinite loop + * Always call 'fREe()' rather than 'free()' + + V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee) + * Fixed ordering problem with boundary-stamping + + V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee) + * Added pvalloc, as recommended by H.J. Liu + * Added 64bit pointer support mainly from Wolfram Gloger + * Added anonymously donated WIN32 sbrk emulation + * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen + * malloc_extend_top: fix mask error that caused wastage after + foreign sbrks + * Add linux mremap support code from HJ Liu + + V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee) + * Integrated most documentation with the code. + * Add support for mmap, with help from + Wolfram Gloger (Gloger@lrz.uni-muenchen.de). + * Use last_remainder in more cases. + * Pack bins using idea from colin@nyx10.cs.du.edu + * Use ordered bins instead of best-fit threshhold + * Eliminate block-local decls to simplify tracing and debugging. + * Support another case of realloc via move into top + * Fix error occuring when initial sbrk_base not word-aligned. + * Rely on page size for units instead of SBRK_UNIT to + avoid surprises about sbrk alignment conventions. + * Add mallinfo, mallopt. Thanks to Raymond Nijssen + (raymond@es.ele.tue.nl) for the suggestion. + * Add `pad' argument to malloc_trim and top_pad mallopt parameter. + * More precautions for cases where other routines call sbrk, + courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de). + * Added macros etc., allowing use in linux libc from + H.J. Lu (hjl@gnu.ai.mit.edu) + * Inverted this history list + + V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee) + * Re-tuned and fixed to behave more nicely with V2.6.0 changes. + * Removed all preallocation code since under current scheme + the work required to undo bad preallocations exceeds + the work saved in good cases for most test programs. + * No longer use return list or unconsolidated bins since + no scheme using them consistently outperforms those that don't + given above changes. + * Use best fit for very large chunks to prevent some worst-cases. + * Added some support for debugging + + V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee) + * Removed footers when chunks are in use. Thanks to + Paul Wilson (wilson@cs.texas.edu) for the suggestion. + + V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee) + * Added malloc_trim, with help from Wolfram Gloger + (wmglo@Dent.MED.Uni-Muenchen.DE). + + V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g) + + V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g) + * realloc: try to expand in both directions + * malloc: swap order of clean-bin strategy; + * realloc: only conditionally expand backwards + * Try not to scavenge used bins + * Use bin counts as a guide to preallocation + * Occasionally bin return list chunks in first scan + * Add a few optimizations from colin@nyx10.cs.du.edu + + V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g) + * faster bin computation & slightly different binning + * merged all consolidations to one part of malloc proper + (eliminating old malloc_find_space & malloc_clean_bin) + * Scan 2 returns chunks (not just 1) + * Propagate failure in realloc if malloc returns 0 + * Add stuff to allow compilation on non-ANSI compilers + from kpv@research.att.com + + V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu) + * removed potential for odd address access in prev_chunk + * removed dependency on getpagesize.h + * misc cosmetics and a bit more internal documentation + * anticosmetics: mangled names in macros to evade debugger strangeness + * tested on sparc, hp-700, dec-mips, rs6000 + with gcc & native cc (hp, dec only) allowing + Detlefs & Zorn comparison study (in SIGPLAN Notices.) + + Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu) + * Based loosely on libg++-1.2X malloc. (It retains some of the overall + structure of old version, but most details differ.) + +/* ──────────────────── Alternative MORECORE functions ─────────────────── */ + +/* + Guidelines for creating a custom version of MORECORE: + + * For best performance, MORECORE should allocate in multiples of pagesize. + * MORECORE may allocate more memory than requested. (Or even less, + but this will usually result in a malloc failure.) + * MORECORE must not allocate memory when given argument zero, but + instead return one past the end address of memory from previous + nonzero call. + * For best performance, consecutive calls to MORECORE with positive + arguments should return increasing addresses, indicating that + space has been contiguously extended. + * Even though consecutive calls to MORECORE need not return contiguous + addresses, it must be OK for malloc'ed chunks to span multiple + regions in those cases where they do happen to be contiguous. + * MORECORE need not handle negative arguments -- it may instead + just return MFAIL when given negative arguments. + Negative arguments are always multiples of pagesize. MORECORE + must not misinterpret negative args as large positive unsigned + args. You can suppress all such calls from even occurring by defining + MORECORE_CANNOT_TRIM, + + As an example alternative MORECORE, here is a custom allocator + kindly contributed for pre-OSX macOS. It uses virtually but not + necessarily physically contiguous non-paged memory (locked in, + present and won't get swapped out). You can use it by uncommenting + this section, adding some #includes, and setting up the appropriate + defines above: + + #define MORECORE osMoreCore + + There is also a shutdown routine that should somehow be called for + cleanup upon program exit. + + #define MAX_POOL_ENTRIES 100 + #define MINIMUM_MORECORE_SIZE (64 * 1024U) + static int next_os_pool; + void *our_os_pools[MAX_POOL_ENTRIES]; + + void *osMoreCore(int size) + { + void *ptr = 0; + static void *sbrk_top = 0; + + if (size > 0) + { + if (size < MINIMUM_MORECORE_SIZE) + size = MINIMUM_MORECORE_SIZE; + if (CurrentExecutionLevel() == kTaskLevel) + ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0); + if (ptr == 0) + { + return (void *) MFAIL; + } + // save ptrs so they can be freed during cleanup + our_os_pools[next_os_pool] = ptr; + next_os_pool++; + ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK); + sbrk_top = (char *) ptr + size; + return ptr; + } + else if (size < 0) + { + // we don't currently support shrink behavior + return (void *) MFAIL; + } + else + { + return sbrk_top; + } + } + + // cleanup any allocated memory pools + // called as last thing before shutting down driver + + void osCleanupMem(void) + { + void **ptr; + + for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++) + if (*ptr) + { + PoolDeallocate(*ptr); + *ptr = 0; + } + } + +*/ diff --git a/third_party/dlmalloc/README.cosmo b/third_party/dlmalloc/README.cosmo new file mode 100644 index 00000000..8a6be68b --- /dev/null +++ b/third_party/dlmalloc/README.cosmo @@ -0,0 +1,15 @@ +Numerous local changes were made while vendoring Doug Lee's original +dlmalloc sources. Those changes basically boil down to: + + 1. Fewer #ifdefs + 2. More modules (so linker can do a better job) + 3. Delete code we don't need (cf. Knight Capital) + 4. Readability / stylistic consistency + +Since we haven't made any genuine improvements to Doug Lee's legendary +allocator, we feel this folder faithfully presents his intended work, in +harmony with Cosmopolitan conventions. + +The only deleted code we're sure has compelling merit is the mspace +functionality. If we ever need memory pools, they might be more +appropriately vendored under //third_party/dlmalloc_mspace. diff --git a/third_party/dlmalloc/bulk_free.c b/third_party/dlmalloc/bulk_free.c new file mode 100644 index 00000000..656f8232 --- /dev/null +++ b/third_party/dlmalloc/bulk_free.c @@ -0,0 +1,56 @@ +#include "libc/mem/mem.h" +#include "third_party/dlmalloc/dlmalloc.h" + +/** + * Frees and clears (sets to NULL) each non-null pointer in the given + * array. This is likely to be faster than freeing them one-by-one. If + * footers are used, pointers that have been allocated in different + * mspaces are not freed or cleared, and the count of all such pointers + * is returned. For large arrays of pointers with poor locality, it may + * be worthwhile to sort this array before calling bulk_free. + */ +size_t bulk_free(void *array[], size_t nelem) { + /* + * Try to free all pointers in the given array. Note: this could be + * made faster, by delaying consolidation, at the price of disabling + * some user integrity checks, We still optimize some consolidations + * by combining adjacent chunks before freeing, which will occur often + * if allocated with ialloc or the array is sorted. + */ + size_t unfreed = 0; + if (!PREACTION(gm)) { + void **a; + void **fence = &(array[nelem]); + for (a = array; a != fence; ++a) { + void *mem = *a; + if (mem != 0) { + mchunkptr p = mem2chunk(ADDRESS_DEATH_ACTION(mem)); + size_t psize = chunksize(p); +#if FOOTERS + if (get_mstate_for(p) != gm) { + ++unfreed; + continue; + } +#endif + check_inuse_chunk(gm, p); + *a = 0; + if (RTCHECK(ok_address(gm, p) && ok_inuse(p))) { + void **b = a + 1; /* try to merge with next chunk */ + mchunkptr next = next_chunk(p); + if (b != fence && *b == chunk2mem(next)) { + size_t newsize = chunksize(next) + psize; + set_inuse(gm, p, newsize); + *b = chunk2mem(p); + } else + dlmalloc_dispose_chunk(gm, p, psize); + } else { + CORRUPTION_ERROR_ACTION(gm); + break; + } + } + } + if (should_trim(gm, gm->topsize)) dlmalloc_sys_trim(gm, 0); + POSTACTION(gm); + } + return unfreed; +} diff --git a/third_party/dlmalloc/dlindependent_calloc.c b/third_party/dlmalloc/dlindependent_calloc.c new file mode 100644 index 00000000..56772a04 --- /dev/null +++ b/third_party/dlmalloc/dlindependent_calloc.c @@ -0,0 +1,228 @@ +#include "libc/mem/mem.h" +#include "libc/str/str.h" +#include "third_party/dlmalloc/dlmalloc.h" + +/* + Common support for independent_X routines, handling + all of the combinations that can result. + The opts arg has: + bit 0 set if all elements are same size (using sizes[0]) + bit 1 set if elements should be zeroed +*/ +static void **ialloc(mstate m, size_t n_elements, size_t *sizes, int opts, + void *chunks[]) { + size_t element_size; /* chunksize of each element, if all same */ + size_t contents_size; /* total size of elements */ + size_t array_size; /* request size of pointer array */ + void *mem; /* malloced aggregate space */ + mchunkptr p; /* corresponding chunk */ + size_t remainder_size; /* remaining bytes while splitting */ + void **marray; /* either "chunks" or malloced ptr array */ + mchunkptr array_chunk; /* chunk for malloced ptr array */ + flag_t was_enabled; /* to disable mmap */ + size_t size; + size_t i; + + ensure_initialization(); + /* compute array length, if needed */ + if (chunks != 0) { + if (n_elements == 0) return chunks; /* nothing to do */ + marray = chunks; + array_size = 0; + } else { + /* if empty req, must still return chunk representing empty array */ + if (n_elements == 0) return (void **)dlmalloc(0); + marray = 0; + array_size = request2size(n_elements * (sizeof(void *))); + } + + /* compute total element size */ + if (opts & 0x1) { /* all-same-size */ + element_size = request2size(*sizes); + contents_size = n_elements * element_size; + } else { /* add up all the sizes */ + element_size = 0; + contents_size = 0; + for (i = 0; i != n_elements; ++i) contents_size += request2size(sizes[i]); + } + + size = contents_size + array_size; + + /* + Allocate the aggregate chunk. First disable direct-mmapping so + malloc won't use it, since we would not be able to later + free/realloc space internal to a segregated mmap region. + */ + was_enabled = use_mmap(m); + disable_mmap(m); + mem = dlmalloc(size - CHUNK_OVERHEAD); + if (was_enabled) enable_mmap(m); + if (mem == 0) return 0; + + if (PREACTION(m)) return 0; + p = mem2chunk(mem); + remainder_size = chunksize(p); + + assert(!is_mmapped(p)); + + if (opts & 0x2) { /* optionally clear the elements */ + memset((size_t *)mem, 0, remainder_size - SIZE_T_SIZE - array_size); + } + + /* If not provided, allocate the pointer array as final part of chunk */ + if (marray == 0) { + size_t array_chunk_size; + array_chunk = chunk_plus_offset(p, contents_size); + array_chunk_size = remainder_size - contents_size; + marray = ADDRESS_BIRTH_ACTION((void **)(chunk2mem(array_chunk))); + set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); + remainder_size = contents_size; + } + + /* split out elements */ + for (i = 0;; ++i) { + marray[i] = ADDRESS_BIRTH_ACTION(chunk2mem(p)); + if (i != n_elements - 1) { + if (element_size != 0) + size = element_size; + else + size = request2size(sizes[i]); + remainder_size -= size; + set_size_and_pinuse_of_inuse_chunk(m, p, size); + p = chunk_plus_offset(p, size); + } else { /* the final element absorbs any overallocation slop */ + set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); + break; + } + } + +#if DEBUG + MODE_DBG + 0 + if (marray != chunks) { + /* final element must have exactly exhausted chunk */ + if (element_size != 0) { + assert(remainder_size == element_size); + } else { + assert(remainder_size == request2size(sizes[i])); + } + check_inuse_chunk(m, mem2chunk(marray)); + } + for (i = 0; i != n_elements; ++i) check_inuse_chunk(m, mem2chunk(marray[i])); + +#endif /* DEBUG */ + + POSTACTION(m); + return marray; +} + +/** + * independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); + * + * independent_calloc is similar to calloc, but instead of returning a + * single cleared space, it returns an array of pointers to n_elements + * independent elements that can hold contents of size elem_size, each + * of which starts out cleared, and can be independently freed, + * realloc'ed etc. The elements are guaranteed to be adjacently + * allocated (this is not guaranteed to occur with multiple callocs or + * mallocs), which may also improve cache locality in some applications. + * + * The "chunks" argument is optional (i.e., may be null, which is + * probably the most typical usage). If it is null, the returned array + * is itself dynamically allocated and should also be freed when it is + * no longer needed. Otherwise, the chunks array must be of at least + * n_elements in length. It is filled in with the pointers to the + * chunks. + * + * In either case, independent_calloc returns this pointer array, or + * null if the allocation failed. * If n_elements is zero and "chunks" + * is null, it returns a chunk representing an array with zero elements + * (which should be freed if not wanted). + * + * Each element must be freed when it is no longer needed. This can be + * done all at once using bulk_free. + * + * independent_calloc simplifies and speeds up implementations of many + * kinds of pools. * It may also be useful when constructing large data + * structures that initially have a fixed number of fixed-sized nodes, + * but the number is not known at compile time, and some of the nodes + * may later need to be freed. For example: + * + * struct Node { int item; struct Node* next; }; + * struct Node* build_list() { + * struct Node **pool; + * int n = read_number_of_nodes_needed(); + * if (n <= 0) return 0; + * pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); + * if (pool == 0) die(); + * // organize into a linked list... + * struct Node* first = pool[0]; + * for (i = 0; i < n-1; ++i) + * pool[i]->next = pool[i+1]; + * free(pool); * // Can now free the array (or not, if it is needed later) + * return first; + * } + */ +void **dlindependent_calloc(size_t n_elements, size_t elem_size, + void *chunks[]) { + size_t sz = elem_size; /* serves as 1-element array */ + return ialloc(gm, n_elements, &sz, 3, chunks); +} + +/** + * independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); + * + * independent_comalloc allocates, all at once, a set of n_elements + * chunks with sizes indicated in the "sizes" array. It returns an array + * of pointers to these elements, each of which can be independently + * freed, realloc'ed etc. The elements are guaranteed to be adjacently + * allocated (this is not guaranteed to occur with multiple callocs or + * mallocs), which may also improve cache locality in some applications. + * + * The "chunks" argument is optional (i.e., may be null). If it is null + * the returned array is itself dynamically allocated and should also + * be freed when it is no longer needed. Otherwise, the chunks array + * must be of at least n_elements in length. It is filled in with the + * pointers to the chunks. + * + * In either case, independent_comalloc returns this pointer array, or + * null if the allocation failed. If n_elements is zero and chunks is + * null, it returns a chunk representing an array with zero elements + * (which should be freed if not wanted). + * + * Each element must be freed when it is no longer needed. This can be + * done all at once using bulk_free. + * + * independent_comallac differs from independent_calloc in that each + * element may have a different size, and also that it does not + * automatically clear elements. + * + * independent_comalloc can be used to speed up allocation in cases + * where several structs or objects must always be allocated at the + * same time. For example: + * + * struct Head { ... } + * struct Foot { ... } + * + * void send_message(char* msg) { + * int msglen = strlen(msg); + * size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; + * void* chunks[3]; + * if (independent_comalloc(3, sizes, chunks) == 0) + * die(); + * struct Head* head = (struct Head*)(chunks[0]); + * char* body = (char*)(chunks[1]); + * struct Foot* foot = (struct Foot*)(chunks[2]); + * // ... + * } + * + * In general though, independent_comalloc is worth using only for + * larger values of n_elements. For small values, you probably won't + * detect enough difference from series of malloc calls to bother. + * + * Overuse of independent_comalloc can increase overall memory usage, + * since it cannot reuse existing noncontiguous small chunks that might + * be available for some of the elements. + */ +void **dlindependent_comalloc(size_t n_elements, size_t sizes[], + void *chunks[]) { + return ialloc(gm, n_elements, sizes, 0, chunks); +} diff --git a/third_party/dlmalloc/dlmalloc-debug.c b/third_party/dlmalloc/dlmalloc-debug.c new file mode 100644 index 00000000..94292c18 --- /dev/null +++ b/third_party/dlmalloc/dlmalloc-debug.c @@ -0,0 +1,247 @@ +#include "third_party/dlmalloc/dlmalloc.h" + +/* Check properties of any chunk, whether free, inuse, mmapped etc */ +static void do_check_any_chunk(mstate m, mchunkptr p) { + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); +} + +/* Check properties of top chunk */ +void do_check_top_chunk(mstate m, mchunkptr p) { + msegmentptr sp = segment_holding(m, (char*)p); + size_t sz = p->head & ~INUSE_BITS; /* third-lowest bit can be set! */ + assert(sp != 0); + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); + assert(sz == m->topsize); + assert(sz > 0); + assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE); + assert(pinuse(p)); + assert(!pinuse(chunk_plus_offset(p, sz))); +} + +/* Check properties of (inuse) mmapped chunks */ +void do_check_mmapped_chunk(mstate m, mchunkptr p) { + size_t sz = chunksize(p); + size_t len = (sz + (p->prev_foot) + MMAP_FOOT_PAD); + assert(is_mmapped(p)); + assert(use_mmap(m)); + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); + assert(!is_small(sz)); + assert((len & (mparams.page_size - SIZE_T_ONE)) == 0); + assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD); + assert(chunk_plus_offset(p, sz + SIZE_T_SIZE)->head == 0); +} + +/* Check properties of inuse chunks */ +void do_check_inuse_chunk(mstate m, mchunkptr p) { + do_check_any_chunk(m, p); + assert(is_inuse(p)); + assert(next_pinuse(p)); + /* If not pinuse and not mmapped, previous chunk has OK offset */ + assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p); + if (is_mmapped(p)) do_check_mmapped_chunk(m, p); +} + +/* Check properties of free chunks */ +void do_check_free_chunk(mstate m, mchunkptr p) { + size_t sz = chunksize(p); + mchunkptr next = chunk_plus_offset(p, sz); + do_check_any_chunk(m, p); + assert(!is_inuse(p)); + assert(!next_pinuse(p)); + assert(!is_mmapped(p)); + if (p != m->dv && p != m->top) { + if (sz >= MIN_CHUNK_SIZE) { + assert((sz & CHUNK_ALIGN_MASK) == 0); + assert(is_aligned(chunk2mem(p))); + assert(next->prev_foot == sz); + assert(pinuse(p)); + assert(next == m->top || is_inuse(next)); + assert(p->fd->bk == p); + assert(p->bk->fd == p); + } else /* markers are always of size SIZE_T_SIZE */ + assert(sz == SIZE_T_SIZE); + } +} + +/* Check properties of malloced chunks at the point they are malloced */ +void do_check_malloced_chunk(mstate m, void* mem, size_t s) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + size_t sz = p->head & ~INUSE_BITS; + do_check_inuse_chunk(m, p); + assert((sz & CHUNK_ALIGN_MASK) == 0); + assert(sz >= MIN_CHUNK_SIZE); + assert(sz >= s); + /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */ + assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE)); + } +} + +/* Check a tree and its subtrees. */ +static void do_check_tree(mstate m, tchunkptr t) { + tchunkptr head = 0; + tchunkptr u = t; + bindex_t tindex = t->index; + size_t tsize = chunksize(t); + bindex_t idx; + compute_tree_index(tsize, idx); + assert(tindex == idx); + assert(tsize >= MIN_LARGE_SIZE); + assert(tsize >= minsize_for_tree_index(idx)); + assert((idx == NTREEBINS - 1) || (tsize < minsize_for_tree_index((idx + 1)))); + + do { /* traverse through chain of same-sized nodes */ + do_check_any_chunk(m, ((mchunkptr)u)); + assert(u->index == tindex); + assert(chunksize(u) == tsize); + assert(!is_inuse(u)); + assert(!next_pinuse(u)); + assert(u->fd->bk == u); + assert(u->bk->fd == u); + if (u->parent == 0) { + assert(u->child[0] == 0); + assert(u->child[1] == 0); + } else { + assert(head == 0); /* only one node on chain has parent */ + head = u; + assert(u->parent != u); + assert(u->parent->child[0] == u || u->parent->child[1] == u || + *((tbinptr*)(u->parent)) == u); + if (u->child[0] != 0) { + assert(u->child[0]->parent == u); + assert(u->child[0] != u); + do_check_tree(m, u->child[0]); + } + if (u->child[1] != 0) { + assert(u->child[1]->parent == u); + assert(u->child[1] != u); + do_check_tree(m, u->child[1]); + } + if (u->child[0] != 0 && u->child[1] != 0) { + assert(chunksize(u->child[0]) < chunksize(u->child[1])); + } + } + u = u->fd; + } while (u != t); + assert(head != 0); +} + +/* Check all the chunks in a treebin. */ +static void do_check_treebin(mstate m, bindex_t i) { + tbinptr* tb = treebin_at(m, i); + tchunkptr t = *tb; + int empty = (m->treemap & (1U << i)) == 0; + if (t == 0) assert(empty); + if (!empty) do_check_tree(m, t); +} + +/* Check all the chunks in a smallbin. */ +static void do_check_smallbin(mstate m, bindex_t i) { + sbinptr b = smallbin_at(m, i); + mchunkptr p = b->bk; + unsigned int empty = (m->smallmap & (1U << i)) == 0; + if (p == b) assert(empty); + if (!empty) { + for (; p != b; p = p->bk) { + size_t size = chunksize(p); + mchunkptr q; + /* each chunk claims to be free */ + do_check_free_chunk(m, p); + /* chunk belongs in bin */ + assert(small_index(size) == i); + assert(p->bk == b || chunksize(p->bk) == chunksize(p)); + /* chunk is followed by an inuse chunk */ + q = next_chunk(p); + if (q->head != FENCEPOST_HEAD) do_check_inuse_chunk(m, q); + } + } +} + +/* Find x in a bin. Used in other check functions. */ +static int bin_find(mstate m, mchunkptr x) { + size_t size = chunksize(x); + if (is_small(size)) { + bindex_t sidx = small_index(size); + sbinptr b = smallbin_at(m, sidx); + if (smallmap_is_marked(m, sidx)) { + mchunkptr p = b; + do { + if (p == x) return 1; + } while ((p = p->fd) != b); + } + } else { + bindex_t tidx; + compute_tree_index(size, tidx); + if (treemap_is_marked(m, tidx)) { + tchunkptr t = *treebin_at(m, tidx); + size_t sizebits = size << leftshift_for_tree_index(tidx); + while (t != 0 && chunksize(t) != size) { + t = t->child[(sizebits >> (SIZE_T_BITSIZE - SIZE_T_ONE)) & 1]; + sizebits <<= 1; + } + if (t != 0) { + tchunkptr u = t; + do { + if (u == (tchunkptr)x) return 1; + } while ((u = u->fd) != t); + } + } + } + return 0; +} + +/* Traverse each chunk and check it; return total */ +static size_t traverse_and_check(mstate m) { + size_t sum = 0; + if (is_initialized(m)) { + msegmentptr s = &m->seg; + sum += m->topsize + TOP_FOOT_SIZE; + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + mchunkptr lastq = 0; + assert(pinuse(q)); + while (segment_holds(s, q) && q != m->top && q->head != FENCEPOST_HEAD) { + sum += chunksize(q); + if (is_inuse(q)) { + assert(!bin_find(m, q)); + do_check_inuse_chunk(m, q); + } else { + assert(q == m->dv || bin_find(m, q)); + assert(lastq == 0 || is_inuse(lastq)); /* Not 2 consecutive free */ + do_check_free_chunk(m, q); + } + lastq = q; + q = next_chunk(q); + } + s = s->next; + } + } + return sum; +} + +/* Check all properties of malloc_state. */ +void do_check_malloc_state(mstate m) { + bindex_t i; + size_t total; + /* check bins */ + for (i = 0; i < NSMALLBINS; ++i) do_check_smallbin(m, i); + for (i = 0; i < NTREEBINS; ++i) do_check_treebin(m, i); + if (m->dvsize != 0) { /* check dv chunk */ + do_check_any_chunk(m, m->dv); + assert(m->dvsize == chunksize(m->dv)); + assert(m->dvsize >= MIN_CHUNK_SIZE); + assert(bin_find(m, m->dv) == 0); + } + if (m->top != 0) { /* check top chunk */ + do_check_top_chunk(m, m->top); + /*assert(m->topsize == chunksize(m->top)); redundant */ + assert(m->topsize > 0); + assert(bin_find(m, m->top) == 0); + } + total = traverse_and_check(m); + assert(total <= m->footprint); + assert(m->footprint <= m->max_footprint); +} diff --git a/third_party/dlmalloc/dlmalloc-usable.c b/third_party/dlmalloc/dlmalloc-usable.c new file mode 100644 index 00000000..5443694c --- /dev/null +++ b/third_party/dlmalloc/dlmalloc-usable.c @@ -0,0 +1,10 @@ +#include "libc/mem/mem.h" +#include "third_party/dlmalloc/dlmalloc.h" + +size_t dlmalloc_usable_size(const void* mem) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + if (is_inuse(p)) return chunksize(p) - overhead_for(p); + } + return 0; +} diff --git a/third_party/dlmalloc/dlmalloc.c b/third_party/dlmalloc/dlmalloc.c new file mode 100644 index 00000000..700d62b8 --- /dev/null +++ b/third_party/dlmalloc/dlmalloc.c @@ -0,0 +1,1033 @@ +#include "libc/bits/safemacros.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/sysinfo.h" +#include "libc/conv/conv.h" +#include "libc/conv/sizemultiply.h" +#include "libc/dce.h" +#include "libc/limits.h" +#include "libc/macros.h" +#include "libc/mem/mem.h" +#include "libc/nt/systeminfo.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/fileno.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" +#include "libc/sysv/errfuns.h" +#include "third_party/dlmalloc/dlmalloc.h" + +#define OOM_WARNING "warning: running out of physical memory\n" +#define is_global(M) ((M) == &_gm_) + +struct malloc_params mparams; +struct malloc_state _gm_; + +/** + * Acquires more system memory for dlmalloc. + * + * Each time dlmalloc needs 64kb, we ask for a 2mb page directory. The + * empty space could help with buffer overflow detection; mremap() has + * plenty of room to grow; and debuggability is greatly enhanced. This + * should have less page table overhead than in security blanket mode. + * Note that contiguous allocations are what Doug Lea recommends. + */ +static void *dlmalloc_requires_more_vespene_gas(size_t size) { + if (!IsTrustworthy()) { + size_t need = mallinfo().arena + size; + if (need > 8 * 1024 * 1024) { + struct sysinfo info; + if (sysinfo(&info) != -1) { + if (info.freeram < (info.totalram >> 1) && + need > info.totalram * info.mem_unit / 2) { + write(STDERR_FILENO, OOM_WARNING, strlen(OOM_WARNING)); + return NULL; + } + } + } + } + return mapanon(size); +} + +/* ─────────────────────────── mspace management ─────────────────────────── */ + +/* Initialize top chunk and its size */ +static void dlmalloc_init_top(mstate m, mchunkptr p, size_t psize) { + /* Ensure alignment */ + size_t offset = align_offset(chunk2mem(p)); + p = (mchunkptr)((char *)p + offset); + psize -= offset; + m->top = p; + m->topsize = psize; + p->head = psize | PINUSE_BIT; + /* set size of fake trailing chunk holding overhead space only once */ + chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; + m->trim_check = mparams.trim_threshold; /* reset on each update */ +} + +/* Initialize bins for a new mstate that is otherwise zeroed out */ +static void init_bins(mstate m) { + /* Establish circular links for smallbins */ + bindex_t i; + for (i = 0; i < NSMALLBINS; ++i) { + sbinptr bin = smallbin_at(m, i); + bin->fd = bin->bk = bin; + } +} + +/* Allocate chunk and prepend remainder with chunk in successor base. */ +static void *dlmalloc_prepend_alloc(mstate m, char *newbase, char *oldbase, + size_t nb) { + mchunkptr p = align_as_chunk(newbase); + mchunkptr oldfirst = align_as_chunk(oldbase); + size_t psize = (char *)oldfirst - (char *)p; + mchunkptr q = chunk_plus_offset(p, nb); + size_t qsize = psize - nb; + set_size_and_pinuse_of_inuse_chunk(m, p, nb); + assert((char *)oldfirst > (char *)q); + assert(pinuse(oldfirst)); + assert(qsize >= MIN_CHUNK_SIZE); + /* consolidate remainder with first chunk of old base */ + if (oldfirst == m->top) { + size_t tsize = m->topsize += qsize; + m->top = q; + q->head = tsize | PINUSE_BIT; + check_top_chunk(m, q); + } else if (oldfirst == m->dv) { + size_t dsize = m->dvsize += qsize; + m->dv = q; + set_size_and_pinuse_of_free_chunk(q, dsize); + } else { + if (!is_inuse(oldfirst)) { + size_t nsize = chunksize(oldfirst); + unlink_chunk(m, oldfirst, nsize); + oldfirst = chunk_plus_offset(oldfirst, nsize); + qsize += nsize; + } + set_free_with_pinuse(q, qsize, oldfirst); + insert_chunk(m, q, qsize); + check_free_chunk(m, q); + } + check_malloced_chunk(m, chunk2mem(p), nb); + return chunk2mem(p); +} + +/* Add a segment to hold a new noncontiguous region */ +static void dlmalloc_add_segment(mstate m, char *tbase, size_t tsize, + flag_t mmapped) { + /* Determine locations and sizes of segment, fenceposts, old top */ + char *old_top = (char *)m->top; + msegmentptr oldsp = segment_holding(m, old_top); + char *old_end = oldsp->base + oldsp->size; + size_t ssize = pad_request(sizeof(struct malloc_segment)); + char *rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + size_t offset = align_offset(chunk2mem(rawsp)); + char *asp = rawsp + offset; + char *csp = (asp < (old_top + MIN_CHUNK_SIZE)) ? old_top : asp; + mchunkptr sp = (mchunkptr)csp; + msegmentptr ss = (msegmentptr)(chunk2mem(sp)); + mchunkptr tnext = chunk_plus_offset(sp, ssize); + mchunkptr p = tnext; + int nfences = 0; + /* reset top to new space */ + dlmalloc_init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); + /* Set up segment record */ + assert(is_aligned(ss)); + set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); + *ss = m->seg; /* Push current record */ + m->seg.base = tbase; + m->seg.size = tsize; + m->seg.sflags = mmapped; + m->seg.next = ss; + /* Insert trailing fenceposts */ + for (;;) { + mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); + p->head = FENCEPOST_HEAD; + ++nfences; + if ((char *)(&(nextp->head)) < old_end) + p = nextp; + else + break; + } + assert(nfences >= 2); + /* Insert the rest of old top into a bin as an ordinary free chunk */ + if (csp != old_top) { + mchunkptr q = (mchunkptr)old_top; + size_t psize = csp - old_top; + mchunkptr tn = chunk_plus_offset(q, psize); + set_free_with_pinuse(q, psize, tn); + insert_chunk(m, q, psize); + } + check_top_chunk(m, m->top); +} + +/* ─────────────────────────── system integration ─────────────────────────── */ + +/* Return true if segment contains a segment link */ +static int has_segment_link(mstate m, msegmentptr ss) { + msegmentptr sp = &m->seg; + for (;;) { + if ((char *)sp >= ss->base && (char *)sp < ss->base + ss->size) return 1; + if ((sp = sp->next) == 0) return 0; + } +} + +/* + Directly mmapped chunks are set up with an offset to the start of + the mmapped region stored in the prev_foot field of the chunk. This + allows reconstruction of the required argument to MUNMAP when freed, + and also allows adjustment of the returned chunk to meet alignment + requirements (especially in memalign). +*/ + +/* For sys_alloc, enough padding to ensure can malloc request on success */ +#define SYS_ALLOC_PADDING (TOP_FOOT_SIZE + MALLOC_ALIGNMENT) + +static size_t mmap_align(size_t s) { + return granularity_align(s); +} + +/* Malloc using mmap */ +static void *mmap_alloc(mstate m, size_t nb) { + size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + if (m->footprint_limit != 0) { + size_t fp = m->footprint + mmsize; + if (fp <= m->footprint || fp > m->footprint_limit) return 0; + } + if (mmsize > nb) { /* Check for wrap around 0 */ + char *mm = (char *)(dlmalloc_requires_more_vespene_gas(mmsize)); + if (mm != CMFAIL) { + size_t offset = align_offset(chunk2mem(mm)); + size_t psize = mmsize - offset - MMAP_FOOT_PAD; + mchunkptr p = (mchunkptr)(mm + offset); + p->prev_foot = offset; + p->head = psize; + mark_inuse_foot(m, p, psize); + chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; + chunk_plus_offset(p, psize + SIZE_T_SIZE)->head = 0; + if (m->least_addr == 0 || mm < m->least_addr) m->least_addr = mm; + if ((m->footprint += mmsize) > m->max_footprint) + m->max_footprint = m->footprint; + assert(is_aligned(chunk2mem(p))); + check_mmapped_chunk(m, p); + return chunk2mem(p); + } + } + return 0; +} + +/* Realloc using mmap */ +static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb, int flags) { + size_t oldsize = chunksize(oldp); + if (is_small(nb)) return 0; /* Can't shrink mmap regions below small size */ + /* Keep old chunk if big enough but not too big */ + if (oldsize >= nb + SIZE_T_SIZE && + (oldsize - nb) <= (mparams.granularity << 1)) { + return oldp; + } else { + size_t offset = oldp->prev_foot; + size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; + size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + char *cp = mremap((char *)oldp - offset, oldmmsize, newmmsize, flags, 0); + if (cp != CMFAIL) { + mchunkptr newp = (mchunkptr)(cp + offset); + size_t psize = newmmsize - offset - MMAP_FOOT_PAD; + newp->head = psize; + mark_inuse_foot(m, newp, psize); + chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; + chunk_plus_offset(newp, psize + SIZE_T_SIZE)->head = 0; + if (cp < m->least_addr) m->least_addr = cp; + if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint) { + m->max_footprint = m->footprint; + } + check_mmapped_chunk(m, newp); + return newp; + } + } + return 0; +} + +/** + * Gets memory from system. + */ +static void *sys_alloc(mstate m, size_t nb) { + char *tbase = CMFAIL; + size_t tsize = 0; + flag_t mmap_flag = 0; + size_t asize; /* allocation size */ + + ensure_initialization(); + + /* Directly map large chunks, but only if already initialized */ + if (use_mmap(m) && nb >= mparams.mmap_threshold && m->topsize != 0) { + void *mem = mmap_alloc(m, nb); + if (mem != 0) return mem; + } + + asize = granularity_align(nb + SYS_ALLOC_PADDING); + if (asize <= nb) return 0; /* wraparound */ + if (m->footprint_limit != 0) { + size_t fp = m->footprint + asize; + if (fp <= m->footprint || fp > m->footprint_limit) return 0; + } + + if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ + char *mp = (char *)(dlmalloc_requires_more_vespene_gas(asize)); + if (mp != CMFAIL) { + tbase = mp; + tsize = asize; + mmap_flag = USE_MMAP_BIT; + } + } + + if (tbase != CMFAIL) { + if ((m->footprint += tsize) > m->max_footprint) + m->max_footprint = m->footprint; + + if (!is_initialized(m)) { /* first-time initialization */ + if (m->least_addr == 0 || tbase < m->least_addr) m->least_addr = tbase; + m->seg.base = tbase; + m->seg.size = tsize; + m->seg.sflags = mmap_flag; + m->magic = mparams.magic; + m->release_checks = MAX_RELEASE_CHECK_RATE; + init_bins(m); + if (is_global(m)) { + dlmalloc_init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); + } else { + /* Offset top by embedded malloc_state */ + mchunkptr mn = next_chunk(mem2chunk(m)); + dlmalloc_init_top( + m, mn, (size_t)((tbase + tsize) - (char *)mn) - TOP_FOOT_SIZE); + } + } + + else { + /* Try to merge with an existing segment */ + msegmentptr sp = &m->seg; + /* Only consider most recent segment if traversal suppressed */ + while (sp != 0 && tbase != sp->base + sp->size) + sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; + if (sp != 0 && !is_extern_segment(sp) && + (sp->sflags & USE_MMAP_BIT) == mmap_flag && + segment_holds(sp, m->top)) { /* append */ + sp->size += tsize; + dlmalloc_init_top(m, m->top, m->topsize + tsize); + } else { + if (tbase < m->least_addr) m->least_addr = tbase; + sp = &m->seg; + while (sp != 0 && sp->base != tbase + tsize) + sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; + if (sp != 0 && !is_extern_segment(sp) && + (sp->sflags & USE_MMAP_BIT) == mmap_flag) { + char *oldbase = sp->base; + sp->base = tbase; + sp->size += tsize; + return dlmalloc_prepend_alloc(m, tbase, oldbase, nb); + } else + dlmalloc_add_segment(m, tbase, tsize, mmap_flag); + } + } + + if (nb < m->topsize) { /* Allocate from new or extended top space */ + size_t rsize = m->topsize -= nb; + mchunkptr p = m->top; + mchunkptr r = m->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(m, p, nb); + check_top_chunk(m, m->top); + check_malloced_chunk(m, chunk2mem(p), nb); + return chunk2mem(p); + } + } + + enomem(); + return 0; +} + +/* Unmap and unlink any mmapped segments that don't contain used chunks */ +static size_t dlmalloc_release_unused_segments(mstate m) { + size_t released = 0; + int nsegs = 0; + msegmentptr pred = &m->seg; + msegmentptr sp = pred->next; + while (sp != 0) { + char *base = sp->base; + size_t size = sp->size; + msegmentptr next = sp->next; + ++nsegs; + if (is_mmapped_segment(sp) && !is_extern_segment(sp)) { + mchunkptr p = align_as_chunk(base); + size_t psize = chunksize(p); + /* Can unmap if first chunk holds entire segment and not pinned */ + if (!is_inuse(p) && (char *)p + psize >= base + size - TOP_FOOT_SIZE) { + tchunkptr tp = (tchunkptr)p; + assert(segment_holds(sp, (char *)sp)); + if (p == m->dv) { + m->dv = 0; + m->dvsize = 0; + } else { + unlink_large_chunk(m, tp); + } + if (munmap(base, size) == 0) { + released += size; + m->footprint -= size; + /* unlink obsoleted record */ + sp = pred; + sp->next = next; + } else { /* back out if cannot unmap */ + insert_large_chunk(m, tp, psize); + } + } + } + if (NO_SEGMENT_TRAVERSAL) /* scan only first segment */ + break; + pred = sp; + sp = next; + } + /* Reset check counter */ + m->release_checks = (((size_t)nsegs > (size_t)MAX_RELEASE_CHECK_RATE) + ? (size_t)nsegs + : (size_t)MAX_RELEASE_CHECK_RATE); + return released; +} + +int dlmalloc_sys_trim(mstate m, size_t pad) { + size_t released = 0; + ensure_initialization(); + if (pad < MAX_REQUEST && is_initialized(m)) { + pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ + if (m->topsize > pad) { + /* Shrink top space in granularity-size units, keeping at least one */ + size_t unit = mparams.granularity; + size_t extra = + ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - SIZE_T_ONE) * unit; + msegmentptr sp = segment_holding(m, (char *)m->top); + if (!is_extern_segment(sp)) { + if (is_mmapped_segment(sp)) { + if (HAVE_MMAP && sp->size >= extra && + !has_segment_link(m, sp)) { /* can't shrink if pinned */ + size_t newsize = sp->size - extra; + (void)newsize; /* placate people compiling -Wunused-variable */ + /* Prefer mremap, fall back to munmap */ + if ((mremap(sp->base, sp->size, newsize, 0, 0) != MAP_FAILED) || + (munmap(sp->base + newsize, extra) == 0)) { + released = extra; + } + } + } + } + if (released != 0) { + sp->size -= released; + m->footprint -= released; + dlmalloc_init_top(m, m->top, m->topsize - released); + check_top_chunk(m, m->top); + } + } + /* Unmap any unused mmapped segments */ + if (HAVE_MMAP) released += dlmalloc_release_unused_segments(m); + /* On failure, disable autotrim to avoid repeated failed future calls */ + if (released == 0 && m->topsize > m->trim_check) m->trim_check = SIZE_MAX; + } + return (released != 0) ? 1 : 0; +} + +/* ──────────────────────────── setting mparams ────────────────────────── */ + +#if LOCK_AT_FORK +static void pre_fork(void) { + ACQUIRE_LOCK(&(gm)->mutex); +} +static void post_fork_parent(void) { + RELEASE_LOCK(&(gm)->mutex); +} +static void post_fork_child(void) { + INITIAL_LOCK(&(gm)->mutex); +} +#endif /* LOCK_AT_FORK */ + +static noinline void dlmalloc_init(void) { +#ifdef NEED_GLOBAL_LOCK_INIT + if (malloc_global_mutex_status <= 0) init_malloc_global_mutex(); +#endif + ACQUIRE_MALLOC_GLOBAL_LOCK(); + + if (mparams.magic == 0) { + size_t magic; + size_t psize = PAGESIZE; + size_t gsize = max(g_ntsysteminfo.dwAllocationGranularity, 64 * 1024); + + /* Sanity-check configuration: + size_t must be unsigned and as wide as pointer type. + ints must be at least 4 bytes. + alignment must be at least 8. + Alignment, min chunk size, and page size must all be powers of 2. + */ + if ((sizeof(size_t) != sizeof(char *)) || (SIZE_MAX < MIN_CHUNK_SIZE) || + (sizeof(int) < 4) || (MALLOC_ALIGNMENT < (size_t)8U) || + ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT - SIZE_T_ONE)) != 0) || + ((MCHUNK_SIZE & (MCHUNK_SIZE - SIZE_T_ONE)) != 0) || + ((gsize & (gsize - SIZE_T_ONE)) != 0) || + ((psize & (psize - SIZE_T_ONE)) != 0)) + MALLOC_ABORT; + mparams.granularity = gsize; + mparams.page_size = psize; + mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; + mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; + mparams.default_mflags = + USE_LOCK_BIT | USE_MMAP_BIT | USE_NONCONTIGUOUS_BIT; + + /* Set up lock for main malloc area */ + gm->mflags = mparams.default_mflags; + (void)INITIAL_LOCK(&gm->mutex); +#if LOCK_AT_FORK + pthread_atfork(&pre_fork, &post_fork_parent, &post_fork_child); +#endif + + magic = kStartTsc; + magic |= (size_t)8U; /* ensure nonzero */ + magic &= ~(size_t)7U; /* improve chances of fault for bad values */ + /* Until memory modes commonly available, use volatile-write */ + (*(volatile size_t *)(&(mparams.magic))) = magic; + } + + RELEASE_MALLOC_GLOBAL_LOCK(); +} + +INITIALIZER(800, _init_dlmalloc, { dlmalloc_init(); }) + +/* ───────────────────────────── statistics ────────────────────────────── */ + +/* Consolidate and bin a chunk. Differs from exported versions + of free mainly in that the chunk need not be marked as inuse. +*/ +hidden void dlmalloc_dispose_chunk(mstate m, mchunkptr p, size_t psize) { + mchunkptr next = chunk_plus_offset(p, psize); + if (!pinuse(p)) { + mchunkptr prev; + size_t prevsize = p->prev_foot; + if (is_mmapped(p)) { + psize += prevsize + MMAP_FOOT_PAD; + if (munmap((char *)p - prevsize, psize) == 0) m->footprint -= psize; + return; + } + prev = chunk_minus_offset(p, prevsize); + psize += prevsize; + p = prev; + if (RTCHECK(ok_address(m, prev))) { /* consolidate backward */ + if (p != m->dv) { + unlink_chunk(m, p, prevsize); + } else if ((next->head & INUSE_BITS) == INUSE_BITS) { + m->dvsize = psize; + set_free_with_pinuse(p, psize, next); + return; + } + } else { + CORRUPTION_ERROR_ACTION(m); + return; + } + } + if (RTCHECK(ok_address(m, next))) { + if (!cinuse(next)) { /* consolidate forward */ + if (next == m->top) { + size_t tsize = m->topsize += psize; + m->top = p; + p->head = tsize | PINUSE_BIT; + if (p == m->dv) { + m->dv = 0; + m->dvsize = 0; + } + return; + } else if (next == m->dv) { + size_t dsize = m->dvsize += psize; + m->dv = p; + set_size_and_pinuse_of_free_chunk(p, dsize); + return; + } else { + size_t nsize = chunksize(next); + psize += nsize; + unlink_chunk(m, next, nsize); + set_size_and_pinuse_of_free_chunk(p, psize); + if (p == m->dv) { + m->dvsize = psize; + return; + } + } + } else { + set_free_with_pinuse(p, psize, next); + } + insert_chunk(m, p, psize); + } else { + CORRUPTION_ERROR_ACTION(m); + } +} + +/* ──────────────────────────── malloc ─────────────────────────── */ + +/* allocate a small request from the best fitting chunk in a treebin */ +static void *tmalloc_small(mstate m, size_t nb) { + tchunkptr t, v; + size_t rsize; + bindex_t i; + binmap_t leastbit = least_bit(m->treemap); + compute_bit2idx(leastbit, i); + v = t = *treebin_at(m, i); + rsize = chunksize(t) - nb; + while ((t = leftmost_child(t)) != 0) { + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + rsize = trem; + v = t; + } + } + if (RTCHECK(ok_address(m, v))) { + mchunkptr r = chunk_plus_offset(v, nb); + assert(chunksize(v) == rsize + nb); + if (RTCHECK(ok_next(v, r))) { + unlink_large_chunk(m, v); + if (rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(m, v, (rsize + nb)); + else { + set_size_and_pinuse_of_inuse_chunk(m, v, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(m, r, rsize); + } + return chunk2mem(v); + } + } + CORRUPTION_ERROR_ACTION(m); + return 0; +} + +/* allocate a large request from the best fitting chunk in a treebin */ +static void *tmalloc_large(mstate m, size_t nb) { + tchunkptr v = 0; + size_t rsize = -nb; /* Unsigned negation */ + tchunkptr t; + bindex_t idx; + compute_tree_index(nb, idx); + if ((t = *treebin_at(m, idx)) != 0) { + /* Traverse tree for this bin looking for node with size == nb */ + size_t sizebits = nb << leftshift_for_tree_index(idx); + tchunkptr rst = 0; /* The deepest untaken right subtree */ + for (;;) { + tchunkptr rt; + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + v = t; + if ((rsize = trem) == 0) break; + } + rt = t->child[1]; + t = t->child[(sizebits >> (SIZE_T_BITSIZE - SIZE_T_ONE)) & 1]; + if (rt != 0 && rt != t) rst = rt; + if (t == 0) { + t = rst; /* set t to least subtree holding sizes > nb */ + break; + } + sizebits <<= 1; + } + } + if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */ + binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; + if (leftbits != 0) { + bindex_t i; + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + t = *treebin_at(m, i); + } + } + while (t != 0) { /* find smallest of tree or subtree */ + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + rsize = trem; + v = t; + } + t = leftmost_child(t); + } + /* If dv is a better fit, return 0 so malloc will use it */ + if (v != 0 && rsize < (size_t)(m->dvsize - nb)) { + if (RTCHECK(ok_address(m, v))) { /* split */ + mchunkptr r = chunk_plus_offset(v, nb); + assert(chunksize(v) == rsize + nb); + if (RTCHECK(ok_next(v, r))) { + unlink_large_chunk(m, v); + if (rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(m, v, (rsize + nb)); + else { + set_size_and_pinuse_of_inuse_chunk(m, v, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + insert_chunk(m, r, rsize); + } + return chunk2mem(v); + } + } + CORRUPTION_ERROR_ACTION(m); + } + return 0; +} + +void *dlmalloc(size_t bytes) { + /* + Basic algorithm: + If a small request (< 256 bytes minus per-chunk overhead): + 1. If one exists, use a remainderless chunk in associated smallbin. + (Remainderless means that there are too few excess bytes to + represent as a chunk.) + 2. If it is big enough, use the dv chunk, which is normally the + chunk adjacent to the one used for the most recent small request. + 3. If one exists, split the smallest available chunk in a bin, + saving remainder in dv. + 4. If it is big enough, use the top chunk. + 5. If available, get memory from system and use it + Otherwise, for a large request: + 1. Find the smallest available binned chunk that fits, and use it + if it is better fitting than dv chunk, splitting if necessary. + 2. If better fitting than any binned chunk, use the dv chunk. + 3. If it is big enough, use the top chunk. + 4. If request size >= mmap threshold, try to directly mmap this chunk. + 5. If available, get memory from system and use it + + The ugly goto's here ensure that postaction occurs along all paths. + */ + +#if USE_LOCKS + ensure_initialization(); /* initialize in sys_alloc if not using locks */ +#endif + + if (!PREACTION(gm)) { + void *mem; + size_t nb; + if (bytes <= MAX_SMALL_REQUEST) { + bindex_t idx; + binmap_t smallbits; + nb = (bytes < MIN_REQUEST) ? MIN_CHUNK_SIZE : pad_request(bytes); + idx = small_index(nb); + smallbits = gm->smallmap >> idx; + + if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ + mchunkptr b, p; + idx += ~smallbits & 1; /* Uses next bin if idx empty */ + b = smallbin_at(gm, idx); + p = b->fd; + assert(chunksize(p) == small_index2size(idx)); + unlink_first_small_chunk(gm, b, p, idx); + set_inuse_and_pinuse(gm, p, small_index2size(idx)); + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (nb > gm->dvsize) { + if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ + mchunkptr b, p, r; + size_t rsize; + bindex_t i; + binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + b = smallbin_at(gm, i); + p = b->fd; + assert(chunksize(p) == small_index2size(i)); + unlink_first_small_chunk(gm, b, p, i); + rsize = small_index2size(i) - nb; + /* Fit here cannot be remainderless if 4byte sizes */ + if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(gm, p, small_index2size(i)); + else { + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + r = chunk_plus_offset(p, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(gm, r, rsize); + } + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) { + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + } + } else if (bytes >= MAX_REQUEST) { + nb = SIZE_MAX; /* Too big to allocate. Force failure (in sys alloc) */ + } else { + nb = pad_request(bytes); + if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) { + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + } + + if (nb <= gm->dvsize) { + size_t rsize = gm->dvsize - nb; + mchunkptr p = gm->dv; + if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ + mchunkptr r = gm->dv = chunk_plus_offset(p, nb); + gm->dvsize = rsize; + set_size_and_pinuse_of_free_chunk(r, rsize); + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + } else { /* exhaust dv */ + size_t dvs = gm->dvsize; + gm->dvsize = 0; + gm->dv = 0; + set_inuse_and_pinuse(gm, p, dvs); + } + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (nb < gm->topsize) { /* Split top */ + size_t rsize = gm->topsize -= nb; + mchunkptr p = gm->top; + mchunkptr r = gm->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + mem = chunk2mem(p); + check_top_chunk(gm, gm->top); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + mem = sys_alloc(gm, nb); + + postaction: + POSTACTION(gm); + return ADDRESS_BIRTH_ACTION(mem); + } + + return 0; +} + +/* ──────────────────────────── free ─────────────────────────── */ + +void dlfree(void *mem) { + /* + Consolidate freed chunks with preceeding or succeeding bordering + free chunks, if they exist, and then place in a bin. Intermixed + with special cases for top, dv, mmapped chunks, and usage errors. + */ + if (mem != 0) { + mem = ADDRESS_DEATH_ACTION(mem); + mchunkptr p = mem2chunk(mem); + +#if FOOTERS + mstate fm = get_mstate_for(p); + if (!ok_magic(fm)) { /* HELLO + * TRY #1: rm -rf o && make -j8 -O MODE=dbg + * TRY #2: gdb: p/x (long*)(p+(*(long*)(p-8)&~(1|2|3))) + * gdb: watch *0xDEADBEEF + */ + USAGE_ERROR_ACTION(fm, p); + return; + } +#else /* FOOTERS */ +#define fm gm +#endif /* FOOTERS */ + + if (!PREACTION(fm)) { + check_inuse_chunk(fm, p); + if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) { + size_t psize = chunksize(p); + mchunkptr next = chunk_plus_offset(p, psize); + if (!pinuse(p)) { + size_t prevsize = p->prev_foot; + if (is_mmapped(p)) { + psize += prevsize + MMAP_FOOT_PAD; + if (munmap((char *)p - prevsize, psize) == 0) + fm->footprint -= psize; + goto postaction; + } else { + mchunkptr prev = chunk_minus_offset(p, prevsize); + psize += prevsize; + p = prev; + if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ + if (p != fm->dv) { + unlink_chunk(fm, p, prevsize); + } else if ((next->head & INUSE_BITS) == INUSE_BITS) { + fm->dvsize = psize; + set_free_with_pinuse(p, psize, next); + goto postaction; + } + } else + goto erroraction; + } + } + + if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { + if (!cinuse(next)) { /* consolidate forward */ + if (next == fm->top) { + size_t tsize = fm->topsize += psize; + fm->top = p; + p->head = tsize | PINUSE_BIT; + if (p == fm->dv) { + fm->dv = 0; + fm->dvsize = 0; + } + if (should_trim(fm, tsize)) dlmalloc_sys_trim(fm, 0); + goto postaction; + } else if (next == fm->dv) { + size_t dsize = fm->dvsize += psize; + fm->dv = p; + set_size_and_pinuse_of_free_chunk(p, dsize); + goto postaction; + } else { + size_t nsize = chunksize(next); + psize += nsize; + unlink_chunk(fm, next, nsize); + set_size_and_pinuse_of_free_chunk(p, psize); + if (p == fm->dv) { + fm->dvsize = psize; + goto postaction; + } + } + } else + set_free_with_pinuse(p, psize, next); + + if (is_small(psize)) { + insert_small_chunk(fm, p, psize); + check_free_chunk(fm, p); + } else { + tchunkptr tp = (tchunkptr)p; + insert_large_chunk(fm, tp, psize); + check_free_chunk(fm, p); + if (--fm->release_checks == 0) dlmalloc_release_unused_segments(fm); + } + goto postaction; + } + } + erroraction: + USAGE_ERROR_ACTION(fm, p); + postaction: + POSTACTION(fm); + } + } +#if !FOOTERS +#undef fm +#endif /* FOOTERS */ +} + +void *dlcalloc(size_t n_elements, size_t elem_size) { + void *mem; + size_t req; + sizemultiply(&req, n_elements, elem_size); /* punts error */ + mem = dlmalloc(req); + if (mem != 0 && calloc_must_clear(mem2chunk(mem))) memset(mem, 0, req); + return mem; +} + +/* ──────────── Internal support for realloc, memalign, etc ────────────── */ + +/* Try to realloc; only in-place unless can_move true */ +hidden mchunkptr dlmalloc_try_realloc_chunk(mstate m, mchunkptr p, size_t nb, + int can_move) { + mchunkptr newp = 0; + size_t oldsize = chunksize(p); + mchunkptr next = chunk_plus_offset(p, oldsize); + if (RTCHECK(ok_address(m, p) && ok_inuse(p) && ok_next(p, next) && + ok_pinuse(next))) { + if (is_mmapped(p)) { + newp = mmap_resize(m, p, nb, can_move); + } else if (oldsize >= nb) { /* already big enough */ + size_t rsize = oldsize - nb; + if (rsize >= MIN_CHUNK_SIZE) { /* split off remainder */ + mchunkptr r = chunk_plus_offset(p, nb); + set_inuse(m, p, nb); + set_inuse(m, r, rsize); + dlmalloc_dispose_chunk(m, r, rsize); + } + newp = p; + } else if (next == m->top) { /* extend into top */ + if (oldsize + m->topsize > nb) { + size_t newsize = oldsize + m->topsize; + size_t newtopsize = newsize - nb; + mchunkptr newtop = chunk_plus_offset(p, nb); + set_inuse(m, p, nb); + newtop->head = newtopsize | PINUSE_BIT; + m->top = newtop; + m->topsize = newtopsize; + newp = p; + } + } else if (next == m->dv) { /* extend into dv */ + size_t dvs = m->dvsize; + if (oldsize + dvs >= nb) { + size_t dsize = oldsize + dvs - nb; + if (dsize >= MIN_CHUNK_SIZE) { + mchunkptr r = chunk_plus_offset(p, nb); + mchunkptr n = chunk_plus_offset(r, dsize); + set_inuse(m, p, nb); + set_size_and_pinuse_of_free_chunk(r, dsize); + clear_pinuse(n); + m->dvsize = dsize; + m->dv = r; + } else { /* exhaust dv */ + size_t newsize = oldsize + dvs; + set_inuse(m, p, newsize); + m->dvsize = 0; + m->dv = 0; + } + newp = p; + } + } else if (!cinuse(next)) { /* extend into next free chunk */ + size_t nextsize = chunksize(next); + if (oldsize + nextsize >= nb) { + size_t rsize = oldsize + nextsize - nb; + unlink_chunk(m, next, nextsize); + if (rsize < MIN_CHUNK_SIZE) { + size_t newsize = oldsize + nextsize; + set_inuse(m, p, newsize); + } else { + mchunkptr r = chunk_plus_offset(p, nb); + set_inuse(m, p, nb); + set_inuse(m, r, rsize); + dlmalloc_dispose_chunk(m, r, rsize); + } + newp = p; + } + } + } else { + USAGE_ERROR_ACTION(m, chunk2mem(p)); + } + return newp; +} + +void *dlrealloc(void *oldmem, size_t bytes) { + void *mem = 0; + if (oldmem == 0) { + mem = dlmalloc(bytes); + } else if (bytes >= MAX_REQUEST) { + enomem(); + } else if (bytes == 0) { + dlfree(oldmem); + } else { + size_t nb = request2size(bytes); + mchunkptr oldp = mem2chunk(oldmem); +#if !FOOTERS + mstate m = gm; +#else /* FOOTERS */ + mstate m = get_mstate_for(oldp); + if (!ok_magic(m)) { + USAGE_ERROR_ACTION(m, oldmem); + return 0; + } +#endif /* FOOTERS */ + if (!PREACTION(m)) { + mchunkptr newp = dlmalloc_try_realloc_chunk(m, oldp, nb, 1); + POSTACTION(m); + if (newp != 0) { + check_inuse_chunk(m, newp); + mem = chunk2mem(newp); + } else { + mem = dlmalloc(bytes); + if (mem != 0) { + size_t oc = chunksize(oldp) - overhead_for(oldp); + memcpy(mem, oldmem, (oc < bytes) ? oc : bytes); + dlfree(oldmem); + } + } + } + } + return mem; +} + +asm(".include \"third_party/dlmalloc/COPYING\""); diff --git a/third_party/dlmalloc/dlmalloc.h b/third_party/dlmalloc/dlmalloc.h new file mode 100644 index 00000000..575c7740 --- /dev/null +++ b/third_party/dlmalloc/dlmalloc.h @@ -0,0 +1,1258 @@ +#ifndef COSMOPOLITAN_LIBC_MEM_DLMALLOC_H_ +#define COSMOPOLITAN_LIBC_MEM_DLMALLOC_H_ +#include "libc/assert.h" +#include "libc/bits/bits.h" +#include "libc/calls/calls.h" +#include "libc/dce.h" +#include "libc/runtime/runtime.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +#if 0 +/** + * @fileoverview Internal header for Doug Lea's malloc. +*/ +#endif + +#define DLMALLOC_VERSION 20806 + +#ifndef FOOTERS +#define FOOTERS !IsTrustworthy() +#endif + +#define HAVE_MMAP 1 +#define HAVE_MREMAP 0 /* IsLinux() */ +#define MMAP_CLEARS 1 +#define MALLOC_ALIGNMENT __BIGGEST_ALIGNMENT__ +#define NO_SEGMENT_TRAVERSAL 1 +#define MAX_RELEASE_CHECK_RATE 128 +#define MALLOC_ABORT abort() +#define DEFAULT_GRANULARITY (64UL * 1024UL) +#define DEFAULT_TRIM_THRESHOLD (10UL * 1024UL * 1024UL) +#define DEFAULT_MMAP_THRESHOLD (256UL * 1024UL) +#define USE_LOCKS 0 +#define USE_SPIN_LOCKS 0 +#define LOCK_AT_FORK 0 +#define NSMALLBINS (32u) +#define NTREEBINS (32u) +#define SMALLBIN_SHIFT (3u) +#define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT) +#define TREEBIN_SHIFT (8u) +#define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT) +#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE) +#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD) +#define M_TRIM_THRESHOLD (-1) +#define M_GRANULARITY (-2) +#define M_MMAP_THRESHOLD (-3) + +/* ─────────────────── size_t and alignment properties ──────────────────── */ + +#define MALLINFO_FIELD_TYPE size_t + +/* The byte and bit size of a size_t */ +#define SIZE_T_SIZE (sizeof(size_t)) +#define SIZE_T_BITSIZE (sizeof(size_t) << 3) + +/* Some constants coerced to size_t */ +/* Annoying but necessary to avoid errors on some platforms */ +#define SIZE_T_ZERO 0UL +#define SIZE_T_ONE 1UL +#define SIZE_T_TWO 2UL +#define SIZE_T_FOUR 4UL +#define TWO_SIZE_T_SIZES (SIZE_T_SIZE << 1) +#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE << 2) +#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES + TWO_SIZE_T_SIZES) +#define HALF_SIZE_MAX (__SIZE_MAX__ / 2U) + +/* The bit mask value corresponding to MALLOC_ALIGNMENT */ +#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) + +/* True if address a has acceptable alignment */ +#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0) + +/* the number of bytes to offset an address to align it */ +#define align_offset(A) \ + ((((size_t)(A)&CHUNK_ALIGN_MASK) == 0) \ + ? 0 \ + : ((MALLOC_ALIGNMENT - ((size_t)(A)&CHUNK_ALIGN_MASK)) & \ + CHUNK_ALIGN_MASK)) + +/* ────────────────────────── MMAP preliminaries ───────────────────────── */ + +#define MFAIL MAP_FAILED +#define CMFAIL ((char *)MAP_FAILED) +#define MMAP_DEFAULT(s) dlmalloc_requires_more_vespene_gas(s) +#define MUNMAP_DEFAULT(a, s) munmap(a, s) +#define MMAP_PROT (PROT_READ | PROT_WRITE) +#define DIRECT_MMAP_DEFAULT(s) MMAP_DEFAULT(s) +#define USE_MMAP_BIT (SIZE_T_ONE) +#define CALL_MMAP(s) MMAP_DEFAULT(s) +#define CALL_MUNMAP(a, s) MUNMAP_DEFAULT((a), (s)) +#define CALL_DIRECT_MMAP(s) DIRECT_MMAP_DEFAULT(s) +#define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv)) +#define USE_NONCONTIGUOUS_BIT (4U) +#define EXTERN_BIT (8U) + +/* ─────────────────────────── Lock preliminaries ──────────────────────── */ + +/* + When locks are defined, there is one global lock, plus + one per-mspace lock. + + The global lock_ensures that mparams.magic and other unique + mparams values are initialized only once. It also protects + sequences of calls to MORECORE. In many cases sys_alloc requires + two calls, that should not be interleaved with calls by other + threads. This does not protect against direct calls to MORECORE + by other threads not using this lock, so there is still code to + cope the best we can on interference. + + Per-mspace locks surround calls to malloc, free, etc. + By default, locks are simple non-reentrant mutexes. + + Because lock-protected regions generally have bounded times, it is + OK to use the supplied simple spinlocks. Spinlocks are likely to + improve performance for lightly contended applications, but worsen + performance under heavy contention. + + If USE_LOCKS is > 1, the definitions of lock routines here are + bypassed, in which case you will need to define the type MLOCK_T, + and at least INITIAL_LOCK, DESTROY_LOCK, ACQUIRE_LOCK, RELEASE_LOCK + and TRY_LOCK. You must also declare a + static MLOCK_T malloc_global_mutex = { initialization values };. +*/ + +#define USE_LOCK_BIT (0U) +#define INITIAL_LOCK(l) (0) +#define DESTROY_LOCK(l) (0) +#define ACQUIRE_MALLOC_GLOBAL_LOCK() +#define RELEASE_MALLOC_GLOBAL_LOCK() + +/* ─────────────────────── Chunk representations ──────────────────────── */ + +/* + (The following includes lightly edited explanations by Colin Plumb.) + + The malloc_chunk declaration below is misleading (but accurate and + necessary). It declares a "view" into memory allowing access to + necessary fields at known offsets from a given base. + + Chunks of memory are maintained using a `boundary tag' method as + originally described by Knuth. (See the paper by Paul Wilson + ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such + techniques.) Sizes of free chunks are stored both in the front of + each chunk and at the end. This makes consolidating fragmented + chunks into bigger chunks fast. The head fields also hold bits + representing whether chunks are free or in use. + + Here are some pictures to make it clearer. They are "exploded" to + show that the state of a chunk can be thought of as extending from + the high 31 bits of the head field of its header through the + prev_foot and PINUSE_BIT bit of the following chunk header. + + A chunk that's in use looks like: + + chunk→ ┌───────────────────────────────────────────────────────────────┐ + │ Size of previous chunk (if P = 0) │ + └─────────────────────────────────────────────────────────────┬─┤ + ┌─────────────────────────────────────────────────────────────┐ │P│ + │ Size of this chunk 1│ └─┘ + mem→ ├───────────────────────────────────────────────────────────────┐ + │ │ + ├─ ─┤ + │ │ + ├─ ─┤ + │ : + ├─ size - sizeof(size_t) available payload bytes ─┤ + : │ + chunk→ ├─ ─┤ + │ │ + └───────────────────────────────────────────────────────────────┤ + ┌─────────────────────────────────────────────────────────────┐ |1│ + │ Size of next chunk (may or may not be in use) │ ├─┘ + mem→ └───────────────────────────────────────────────────────────────┘ + + And if it's free, it looks like this: + + chunk→ ┌─ ─┐ + │ User payload (must be in use, or we would have merged!) │ + └───────────────────────────────────────────────────────────────┤ + ┌─────────────────────────────────────────────────────────────┐ │P│ + │ Size of this chunk 0│ │─┘ + mem→ ├───────────────────────────────────────────────────────────────┤ + │ Next pointer │ + ├───────────────────────────────────────────────────────────────┤ + │ Prev pointer │ + ├───────────────────────────────────────────────────────────────┤ + │ : + ├─ size - sizeof(struct chunk) unused bytes ─┤ + : │ + chunk→ ├───────────────────────────────────────────────────────────────┤ + │ Size of this chunk │ + └───────────────────────────────────────────────────────────────┤ + ┌───────────────────────────────────────────────────────────────│0│ + │ Size of next chunk (must be in use, or we would have merged)| │─┘ + mem→ ├───────────────────────────────────────────────────────────────┤ + │ : + ├─ User payload ─┤ + : │ + └───────────────────────────────────────────────────────────────┤ + │0│ + └─┘ + Note that since we always merge adjacent free chunks, the chunks + adjacent to a free chunk must be in use. + + Given a pointer to a chunk (which can be derived trivially from the + payload pointer) we can, in O(1) time, find out whether the adjacent + chunks are free, and if so, unlink them from the lists that they + are on and merge them with the current chunk. + + Chunks always begin on even word boundaries, so the mem portion + (which is returned to the user) is also on an even word boundary, and + thus at least double-word aligned. + + The P (PINUSE_BIT) bit, stored in the unused low-order bit of the + chunk size (which is always a multiple of two words), is an in-use + bit for the *previous* chunk. If that bit is *clear*, then the + word before the current chunk size contains the previous chunk + size, and can be used to find the front of the previous chunk. + The very first chunk allocated always has this bit set, preventing + access to non-existent (or non-owned) memory. If pinuse is set for + any given chunk, then you CANNOT determine the size of the + previous chunk, and might even get a memory addressing fault when + trying to do so. + + The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of + the chunk size redundantly records whether the current chunk is + inuse (unless the chunk is mmapped). This redundancy enables usage + checks within free and realloc, and reduces indirection when freeing + and consolidating chunks. + + Each freshly allocated chunk must have both cinuse and pinuse set. + That is, each allocated chunk borders either a previously allocated + and still in-use chunk, or the base of its memory arena. This is + ensured by making all allocations from the `lowest' part of any + found chunk. Further, no free chunk physically borders another one, + so each free chunk is known to be preceded and followed by either + inuse chunks or the ends of memory. + + Note that the `foot' of the current chunk is actually represented + as the prev_foot of the NEXT chunk. This makes it easier to + deal with alignments etc but can be very confusing when trying + to extend or adapt this code. + + The exceptions to all this are + + 1. The special chunk `top' is the top-most available chunk (i.e., + the one bordering the end of available memory). It is treated + specially. Top is never included in any bin, is used only if + no other chunk is available, and is released back to the + system if it is very large (see M_TRIM_THRESHOLD). In effect, + the top chunk is treated as larger (and thus less well + fitting) than any other available chunk. The top chunk + doesn't update its trailing size field since there is no next + contiguous chunk that would have to index off it. However, + space is still allocated for it (TOP_FOOT_SIZE) to enable + separation or merging when space is extended. + + 3. Chunks allocated via mmap, have both cinuse and pinuse bits + cleared in their head fields. Because they are allocated + one-by-one, each must carry its own prev_foot field, which is + also used to hold the offset this chunk has within its mmapped + region, which is needed to preserve alignment. Each mmapped + chunk is trailed by the first two fields of a fake next-chunk + for sake of usage checks. + +*/ + +struct malloc_chunk { + size_t prev_foot; /* Size of previous chunk (if free). */ + size_t head; /* Size and inuse bits. */ + struct malloc_chunk *fd; /* double links -- used only if free. */ + struct malloc_chunk *bk; +}; + +typedef struct malloc_chunk mchunk; +typedef struct malloc_chunk *mchunkptr; +typedef struct malloc_chunk *sbinptr; /* The type of bins of chunks */ +typedef unsigned int bindex_t; /* Described below */ +typedef unsigned int binmap_t; /* Described below */ +typedef unsigned int flag_t; /* The type of various bit flag sets */ + +/* ─────────────────── Chunks sizes and alignments ─────────────────────── */ + +#define MCHUNK_SIZE (sizeof(mchunk)) + +#define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) + +/* MMapped chunks need a second word of overhead ... */ +#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) +/* ... and additional padding for fake next-chunk at foot */ +#define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) + +/* The smallest size we can malloc is an aligned minimal chunk */ +#define MIN_CHUNK_SIZE ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) + +/* conversion from malloc headers to user pointers, and back */ +#define chunk2mem(p) ((void *)((char *)(p) + TWO_SIZE_T_SIZES)) +#define mem2chunk(mem) ((mchunkptr)((char *)(mem)-TWO_SIZE_T_SIZES)) +/* chunk associated with aligned address A */ +#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) + +/* Bounds on request (not chunk) sizes. */ +#define MAX_REQUEST ((-MIN_CHUNK_SIZE) << 2) +#define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE) + +/* pad request bytes into a usable size */ +#define pad_request(req) \ + (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) + +/* pad request, checking for minimum (but not maximum) */ +#define request2size(req) \ + (((req) < MIN_REQUEST) ? MIN_CHUNK_SIZE : pad_request(req)) + +/* ────────────────── Operations on head and foot fields ───────────────── */ + +/* + The head field of a chunk is or'ed with PINUSE_BIT when previous + adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in + use, unless mmapped, in which case both bits are cleared. + + FLAG4_BIT is not used by this malloc, but might be useful in extensions. +*/ + +#define PINUSE_BIT (SIZE_T_ONE) +#define CINUSE_BIT (SIZE_T_TWO) +#define FLAG4_BIT (SIZE_T_FOUR) +#define INUSE_BITS (PINUSE_BIT | CINUSE_BIT) +#define FLAG_BITS (PINUSE_BIT | CINUSE_BIT | FLAG4_BIT) + +/* Head value for fenceposts */ +#define FENCEPOST_HEAD (INUSE_BITS | SIZE_T_SIZE) + +/* extraction of fields from head words */ +#define cinuse(p) ((p)->head & CINUSE_BIT) +#define pinuse(p) ((p)->head & PINUSE_BIT) +#define flag4inuse(p) ((p)->head & FLAG4_BIT) +#define is_inuse(p) (((p)->head & INUSE_BITS) != PINUSE_BIT) +#define is_mmapped(p) (((p)->head & INUSE_BITS) == 0) + +#define chunksize(p) ((p)->head & ~(FLAG_BITS)) + +#define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT) +#define set_flag4(p) ((p)->head |= FLAG4_BIT) +#define clear_flag4(p) ((p)->head &= ~FLAG4_BIT) + +/* Treat space at ptr +/- offset as a chunk */ +#define chunk_plus_offset(p, s) ((mchunkptr)(((char *)(p)) + (s))) +#define chunk_minus_offset(p, s) ((mchunkptr)(((char *)(p)) - (s))) + +/* Ptr to next or previous physical malloc_chunk. */ +#define next_chunk(p) ((mchunkptr)(((char *)(p)) + ((p)->head & ~FLAG_BITS))) +#define prev_chunk(p) ((mchunkptr)(((char *)(p)) - ((p)->prev_foot))) + +/* extract next chunk's pinuse bit */ +#define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT) + +/* Get/set size at footer */ +#define get_foot(p, s) (((mchunkptr)((char *)(p) + (s)))->prev_foot) +#define set_foot(p, s) (((mchunkptr)((char *)(p) + (s)))->prev_foot = (s)) + +/* Set size, pinuse bit, and foot */ +#define set_size_and_pinuse_of_free_chunk(p, s) \ + ((p)->head = (s | PINUSE_BIT), set_foot(p, s)) + +/* Set size, pinuse bit, foot, and clear next pinuse */ +#define set_free_with_pinuse(p, s, n) \ + (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s)) + +/* Get the internal overhead associated with chunk p */ +#define overhead_for(p) (is_mmapped(p) ? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) + +/* Return true if malloced space is not necessarily cleared */ + +#define calloc_must_clear(p) (!is_mmapped(p)) + +/* ────────────────────── Overlaid data structures ─────────────────────── */ + +/* + When chunks are not in use, they are treated as nodes of either + lists or trees. + + "Small" chunks are stored in circular doubly-linked lists, and look + like this: + + chunk→ ┌───────────────────────────────────────────────────────────────┐ + │ Size of previous chunk │ + ├───────────────────────────────────────────────────────────────┤ + `head:' │ Size of chunk, in bytes |P│ + mem→ ├───────────────────────────────────────────────────────────────┤ + │ Forward pointer to next chunk in list │ + ├───────────────────────────────────────────────────────────────┤ + │ Back pointer to previous chunk in list │ + ├───────────────────────────────────────────────────────────────┤ + . Unused space (may be 0 bytes long) . + . . + │ │ + nextchunk→ ├───────────────────────────────────────────────────────────────┤ + `foot:' │ Size of chunk, in bytes │ + └───────────────────────────────────────────────────────────────┘ + + Larger chunks are kept in a form of bitwise digital trees (aka + tries) keyed on chunksizes. Because malloc_tree_chunks are only for + free chunks greater than 256 bytes, their size doesn't impose any + constraints on user chunk sizes. Each node looks like: + + chunk→ ┌───────────────────────────────────────────────────────────────┐ + │ Size of previous chunk │ + ├─────────────────────────────────────────────────────────────┬─┤ + `head:' │ Size of chunk, in bytes │P│ + mem→ ├─────────────────────────────────────────────────────────────┴─┤ + │ Forward pointer to next chunk of same size │ + ├───────────────────────────────────────────────────────────────┤ + │ Back pointer to previous chunk of same size │ + ├───────────────────────────────────────────────────────────────┤ + │ Pointer to left child (child[0]) │ + ├───────────────────────────────────────────────────────────────┤ + │ Pointer to right child (child[1]) │ + ├───────────────────────────────────────────────────────────────┤ + │ Pointer to parent │ + ├───────────────────────────────────────────────────────────────┤ + │ bin index of this chunk │ + ├───────────────────────────────────────────────────────────────┤ + │ Unused space . + . │ + nextchunk→ ├───────────────────────────────────────────────────────────────┤ + `foot:' │ Size of chunk, in bytes │ + └───────────────────────────────────────────────────────────────┘ + + Each tree holding treenodes is a tree of unique chunk sizes. Chunks + of the same size are arranged in a circularly-linked list, with only + the oldest chunk (the next to be used, in our FIFO ordering) + actually in the tree. (Tree members are distinguished by a non-null + parent pointer.) If a chunk with the same size an an existing node + is inserted, it is linked off the existing node using pointers that + work in the same way as fd/bk pointers of small chunks. + + Each tree contains a power of 2 sized range of chunk sizes (the + smallest is 0x100 <= x < 0x180), which is is divided in half at each + tree level, with the chunks in the smaller half of the range (0x100 + <= x < 0x140 for the top nose) in the left subtree and the larger + half (0x140 <= x < 0x180) in the right subtree. This is, of course, + done by inspecting individual bits. + + Using these rules, each node's left subtree contains all smaller + sizes than its right subtree. However, the node at the root of each + subtree has no particular ordering relationship to either. (The + dividing line between the subtree sizes is based on trie relation.) + If we remove the last chunk of a given size from the interior of the + tree, we need to replace it with a leaf node. The tree ordering + rules permit a node to be replaced by any leaf below it. + + The smallest chunk in a tree (a common operation in a best-fit + allocator) can be found by walking a path to the leftmost leaf in + the tree. Unlike a usual binary tree, where we follow left child + pointers until we reach a null, here we follow the right child + pointer any time the left one is null, until we reach a leaf with + both child pointers null. The smallest chunk in the tree will be + somewhere along that path. + + The worst case number of steps to add, find, or remove a node is + bounded by the number of bits differentiating chunks within + bins. Under current bin calculations, this ranges from 6 up to 21 + (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case + is of course much better. +*/ + +struct malloc_tree_chunk { + /* The first four fields must be compatible with malloc_chunk */ + size_t prev_foot; + size_t head; + struct malloc_tree_chunk *fd; + struct malloc_tree_chunk *bk; + + struct malloc_tree_chunk *child[2]; + struct malloc_tree_chunk *parent; + bindex_t index; +}; + +typedef struct malloc_tree_chunk tchunk; +typedef struct malloc_tree_chunk *tchunkptr; +typedef struct malloc_tree_chunk *tbinptr; /* The type of bins of trees */ + +/* A little helper macro for trees */ +#define leftmost_child(t) ((t)->child[0] != 0 ? (t)->child[0] : (t)->child[1]) + +/* ───────────────────────────── Segments ──────────────────────────────── */ + +/* + Each malloc space may include non-contiguous segments, held in a + list headed by an embedded malloc_segment record representing the + top-most space. Segments also include flags holding properties of + the space. Large chunks that are directly allocated by mmap are not + included in this list. They are instead independently created and + destroyed without otherwise keeping track of them. + + Segment management mainly comes into play for spaces allocated by + MMAP. Any call to MMAP might or might not return memory that is + adjacent to an existing segment. MORECORE normally contiguously + extends the current space, so this space is almost always adjacent, + which is simpler and faster to deal with. (This is why MORECORE is + used preferentially to MMAP when both are available -- see + sys_alloc.) When allocating using MMAP, we don't use any of the + hinting mechanisms (inconsistently) supported in various + implementations of unix mmap, or distinguish reserving from + committing memory. Instead, we just ask for space, and exploit + contiguity when we get it. It is probably possible to do + better than this on some systems, but no general scheme seems + to be significantly better. + + Management entails a simpler variant of the consolidation scheme + used for chunks to reduce fragmentation -- new adjacent memory is + normally prepended or appended to an existing segment. However, + there are limitations compared to chunk consolidation that mostly + reflect the fact that segment processing is relatively infrequent + (occurring only when getting memory from system) and that we + don't expect to have huge numbers of segments: + + * Segments are not indexed, so traversal requires linear scans. (It + would be possible to index these, but is not worth the extra + overhead and complexity for most programs on most platforms.) + * New segments are only appended to old ones when holding top-most + memory; if they cannot be prepended to others, they are held in + different segments. + + Except for the top-most segment of an mstate, each segment record + is kept at the tail of its segment. Segments are added by pushing + segment records onto the list headed by &mstate.seg for the + containing mstate. + + Segment flags control allocation/merge/deallocation policies: + * If EXTERN_BIT set, then we did not allocate this segment, + and so should not try to deallocate or merge with others. + (This currently holds only for the initial segment passed + into create_mspace_with_base.) + * If USE_MMAP_BIT set, the segment may be merged with + other surrounding mmapped segments and trimmed/de-allocated + using munmap. + * If neither bit is set, then the segment was obtained using + MORECORE so can be merged with surrounding MORECORE'd segments + and deallocated/trimmed using MORECORE with negative arguments. +*/ + +struct malloc_segment { + char *base; /* base address */ + size_t size; /* allocated size */ + struct malloc_segment *next; /* ptr to next segment */ + flag_t sflags; /* mmap and extern flag */ +}; + +#define is_mmapped_segment(S) ((S)->sflags & USE_MMAP_BIT) +#define is_extern_segment(S) ((S)->sflags & EXTERN_BIT) + +typedef struct malloc_segment msegment; +typedef struct malloc_segment *msegmentptr; + +/* ──────────────────────────── malloc_state ───────────────────────────── */ + +/* + A malloc_state holds all of the bookkeeping for a space. + The main fields are: + + Top + The topmost chunk of the currently active segment. Its size is + cached in topsize. The actual size of topmost space is + topsize+TOP_FOOT_SIZE, which includes space reserved for adding + fenceposts and segment records if necessary when getting more + space from the system. The size at which to autotrim top is + cached from mparams in trim_check, except that it is disabled if + an autotrim fails. + + Designated victim (dv) + This is the preferred chunk for servicing small requests that + don't have exact fits. It is normally the chunk split off most + recently to service another small request. Its size is cached in + dvsize. The link fields of this chunk are not maintained since it + is not kept in a bin. + + SmallBins + An array of bin headers for free chunks. These bins hold chunks + with sizes less than MIN_LARGE_SIZE bytes. Each bin contains + chunks of all the same size, spaced 8 bytes apart. To simplify + use in double-linked lists, each bin header acts as a malloc_chunk + pointing to the real first node, if it exists (else pointing to + itself). This avoids special-casing for headers. But to avoid + waste, we allocate only the fd/bk pointers of bins, and then use + repositioning tricks to treat these as the fields of a chunk. + + TreeBins + Treebins are pointers to the roots of trees holding a range of + sizes. There are 2 equally spaced treebins for each power of two + from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything + larger. + + Bin maps + There is one bit map for small bins ("smallmap") and one for + treebins ("treemap). Each bin sets its bit when non-empty, and + clears the bit when empty. Bit operations are then used to avoid + bin-by-bin searching -- nearly all "search" is done without ever + looking at bins that won't be selected. The bit maps + conservatively use 32 bits per map word, even if on 64bit system. + For a good description of some of the bit-based techniques used + here, see Henry S. Warren Jr's book "Hacker's Delight" (and + supplement at http://hackersdelight.org/). Many of these are + intended to reduce the branchiness of paths through malloc etc, as + well as to reduce the number of memory locations read or written. + + Segments + A list of segments headed by an embedded malloc_segment record + representing the initial space. + + Address check support + The least_addr field is the least address ever obtained from + MORECORE or MMAP. Attempted frees and reallocs of any address less + than this are trapped (unless INSECURE is defined). + + Magic tag + A cross-check field that should always hold same value as mparams.magic. + + Max allowed footprint + The maximum allowed bytes to allocate from system (zero means no limit) + + Flags + Bits recording whether to use MMAP, locks, or contiguous MORECORE + + Statistics + Each space keeps track of current and maximum system memory + obtained via MORECORE or MMAP. + + Trim support + Fields holding the amount of unused topmost memory that should trigger + trimming, and a counter to force periodic scanning to release unused + non-topmost segments. + + Locking + If USE_LOCKS is defined, the "mutex" lock is acquired and released + around every public call using this mspace. + + Extension support + A void* pointer and a size_t field that can be used to help implement + extensions to this malloc. +*/ + +struct malloc_state { + binmap_t smallmap; + binmap_t treemap; + size_t dvsize; + size_t topsize; + char *least_addr; + mchunkptr dv; + mchunkptr top; + size_t trim_check; + size_t release_checks; + size_t magic; + mchunkptr smallbins[(NSMALLBINS + 1) * 2]; + tbinptr treebins[NTREEBINS]; + size_t footprint; + size_t max_footprint; + size_t footprint_limit; /* zero means no limit */ + flag_t mflags; + + msegment seg; + void *extp; /* Unused but available for extensions */ + size_t exts; +}; + +#define gm (&_gm_) +extern struct malloc_state _gm_; +typedef struct malloc_state *mstate; + +struct MallocStats { + size_t maxfp; + size_t fp; + size_t used; +}; + +/* ─────────────────────────────── Hooks ──────────────────────────────── */ + +#ifdef MTRACE /* TODO(jart): Add --mtrace flag for this */ +void *AddressBirthAction(void *); +void *AddressDeathAction(void *); +#define ADDRESS_BIRTH_ACTION(A) AddressBirthAction(A) +#define ADDRESS_DEATH_ACTION(A) AddressDeathAction(A) +#else +#define ADDRESS_BIRTH_ACTION(A) (A) +#define ADDRESS_DEATH_ACTION(A) (A) +#endif + +/* + PREACTION should be defined to return 0 on success, and nonzero on + failure. If you are not using locking, you can redefine these to do + anything you like. +*/ + +#define PREACTION(M) (0) +#define POSTACTION(M) + +/* + CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses. + USAGE_ERROR_ACTION is triggered on detected bad frees and + reallocs. The argument p is an address that might have triggered the + fault. It is ignored by the two predefined actions, but might be + useful in custom actions that try to help diagnose errors. +*/ + +#define CORRUPTION_ERROR_ACTION(m) MALLOC_ABORT +#define USAGE_ERROR_ACTION(m, p) MALLOC_ABORT + +/* True if segment S holds address A */ +#define segment_holds(S, A) \ + ((char *)(A) >= S->base && (char *)(A) < S->base + S->size) + +/* + TOP_FOOT_SIZE is padding at the end of a segment, including space + that may be needed to place segment records and fenceposts when new + noncontiguous segments are added. +*/ +#define TOP_FOOT_SIZE \ + (align_offset(chunk2mem(0)) + pad_request(sizeof(struct malloc_segment)) + \ + MIN_CHUNK_SIZE) + +/* ───────────── Global malloc_state and malloc_params ─────────────────── */ + +/* + malloc_params holds global properties, including those that can be + dynamically set using mallopt. There is a single instance, mparams, + initialized in init_mparams. Note that the non-zeroness of "magic" + also serves as an initialization flag. +*/ + +struct malloc_params { + size_t magic; + size_t page_size; + size_t granularity; + size_t mmap_threshold; + size_t trim_threshold; + flag_t default_mflags; +}; + +extern struct malloc_params mparams; + +#define ensure_initialization() \ + /* we use a constructor [jart] */ \ + assert(mparams.magic != 0) +/* (void)(mparams.magic != 0 || init_mparams()) */ + +#define is_initialized(M) ((M)->top != 0) +#define is_page_aligned(S) \ + (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0) +#define is_granularity_aligned(S) \ + (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0) + +/* ────────────────────────── system alloc setup ───────────────────────── */ + +/* Operations on mflags */ + +#define use_lock(M) ((M)->mflags & USE_LOCK_BIT) +#define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT) +#if USE_LOCKS +#define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT) +#else +#define disable_lock(M) +#endif + +#define use_mmap(M) ((M)->mflags & USE_MMAP_BIT) +#define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT) +#if HAVE_MMAP +#define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT) +#else +#define disable_mmap(M) +#endif + +#define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT) +#define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT) + +#define set_lock(M, L) \ + ((M)->mflags = \ + (L) ? ((M)->mflags | USE_LOCK_BIT) : ((M)->mflags & ~USE_LOCK_BIT)) + +/* page-align a size */ +#define page_align(S) \ + (((S) + (mparams.page_size - SIZE_T_ONE)) & ~(mparams.page_size - SIZE_T_ONE)) + +/* granularity-align a size */ +#define granularity_align(S) \ + (((S) + (mparams.granularity - SIZE_T_ONE)) & \ + ~(mparams.granularity - SIZE_T_ONE)) + +/* ──────────────────────── Operations on bin maps ─────────────────────── */ + +#define idx2bit(i) ((binmap_t)(1) << (i)) +#define mark_smallmap(M, i) ((M)->smallmap |= idx2bit(i)) +#define clear_smallmap(M, i) ((M)->smallmap &= ~idx2bit(i)) +#define smallmap_is_marked(M, i) ((M)->smallmap & idx2bit(i)) +#define mark_treemap(M, i) ((M)->treemap |= idx2bit(i)) +#define clear_treemap(M, i) ((M)->treemap &= ~idx2bit(i)) +#define treemap_is_marked(M, i) ((M)->treemap & idx2bit(i)) +#define least_bit(x) ((x) & -(x)) +#define left_bits(x) ((x << 1) | -(x << 1)) +#define same_or_left_bits(x) ((x) | -(x)) +#define compute_bit2idx(X, I) \ + { \ + unsigned int J; \ + J = __builtin_ctz(X); \ + I = (bindex_t)J; \ + } + +/* ──────────────────────────── Indexing Bins ──────────────────────────── */ + +#define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS) +#define small_index(s) (bindex_t)((s) >> SMALLBIN_SHIFT) +#define small_index2size(i) ((i) << SMALLBIN_SHIFT) +#define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE)) + +/* addressing by index. See above about smallbin repositioning */ +#define smallbin_at(M, i) ((sbinptr)((char *)&((M)->smallbins[(i) << 1]))) +#define treebin_at(M, i) (&((M)->treebins[i])) + +/* assign tree index for size S to variable I. */ +#define compute_tree_index(S, I) \ + { \ + unsigned int X = S >> TREEBIN_SHIFT; \ + if (X == 0) \ + I = 0; \ + else if (X > 0xFFFF) \ + I = NTREEBINS - 1; \ + else { \ + unsigned int K = \ + (unsigned)sizeof(X) * __CHAR_BIT__ - 1 - (unsigned)__builtin_clz(X); \ + I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT - 1)) & 1))); \ + } \ + } + +/* Bit representing maximum resolved size in a treebin at i */ +#define bit_for_tree_index(i) \ + (i == NTREEBINS - 1) ? (SIZE_T_BITSIZE - 1) : (((i) >> 1) + TREEBIN_SHIFT - 2) + +/* Shift placing maximum resolved bit in a treebin at i as sign bit */ +#define leftshift_for_tree_index(i) \ + ((i == NTREEBINS - 1) \ + ? 0 \ + : ((SIZE_T_BITSIZE - SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2))) + +/* The size of the smallest chunk held in bin with index i */ +#define minsize_for_tree_index(i) \ + ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \ + (((size_t)((i)&SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1))) + +/* ─────────────────────── Runtime Check Support ───────────────────────── */ + +/* + For security, the main invariant is that malloc/free/etc never + writes to a static address other than malloc_state, unless static + malloc_state itself has been corrupted, which cannot occur via + malloc (because of these checks). In essence this means that we + believe all pointers, sizes, maps etc held in malloc_state, but + check all of those linked or offsetted from other embedded data + structures. These checks are interspersed with main code in a way + that tends to minimize their run-time cost. + + When FOOTERS is defined, in addition to range checking, we also + verify footer fields of inuse chunks, which can be used guarantee + that the mstate controlling malloc/free is intact. This is a + streamlined version of the approach described by William Robertson + et al in "Run-time Detection of Heap-based Overflows" LISA'03 + http://www.usenix.org/events/lisa03/tech/robertson.html The footer + of an inuse chunk holds the xor of its mstate and a random seed, + that is checked upon calls to free() and realloc(). This is + (probabalistically) unguessable from outside the program, but can be + computed by any code successfully malloc'ing any chunk, so does not + itself provide protection against code that has already broken + security through some other means. Unlike Robertson et al, we + always dynamically check addresses of all offset chunks (previous, + next, etc). This turns out to be cheaper than relying on hashes. +*/ + +#if !IsTrustworthy() +/* Check if address a is at least as high as any from MORECORE or MMAP */ +#define ok_address(M, a) ((char *)(a) >= (M)->least_addr) +/* Check if address of next chunk n is higher than base chunk p */ +#define ok_next(p, n) ((char *)(p) < (char *)(n)) +/* Check if p has inuse status */ +#define ok_inuse(p) is_inuse(p) +/* Check if p has its pinuse bit on */ +#define ok_pinuse(p) pinuse(p) + +#else /* !IsTrustworthy() */ +#define ok_address(M, a) (1) +#define ok_next(b, n) (1) +#define ok_inuse(p) (1) +#define ok_pinuse(p) (1) +#endif /* !IsTrustworthy() */ + +#if (FOOTERS && !IsTrustworthy()) +/* Check if (alleged) mstate m has expected magic field */ +#define ok_magic(M) \ + ((uintptr_t)(M) <= 0x00007ffffffffffful && (M)->magic == mparams.magic) +#else /* (FOOTERS && !IsTrustworthy()) */ +#define ok_magic(M) (1) +#endif /* (FOOTERS && !IsTrustworthy()) */ + +/* In gcc, use __builtin_expect to minimize impact of checks */ +#if !IsTrustworthy() +#if defined(__GNUC__) && __GNUC__ >= 3 +#define RTCHECK(e) __builtin_expect(e, 1) +#else /* GNUC */ +#define RTCHECK(e) (e) +#endif /* GNUC */ +#else /* !IsTrustworthy() */ +#define RTCHECK(e) (1) +#endif /* !IsTrustworthy() */ + +/* macros to set up inuse chunks with or without footers */ + +#if !FOOTERS + +#define mark_inuse_foot(M, p, s) + +/* Macros for setting head/foot of non-mmapped chunks */ + +/* Set cinuse bit and pinuse bit of next chunk */ +#define set_inuse(M, p, s) \ + ((p)->head = (((p)->head & PINUSE_BIT) | s | CINUSE_BIT), \ + ((mchunkptr)(((char *)(p)) + (s)))->head |= PINUSE_BIT) + +/* Set cinuse and pinuse of this chunk and pinuse of next chunk */ +#define set_inuse_and_pinuse(M, p, s) \ + ((p)->head = (s | PINUSE_BIT | CINUSE_BIT), \ + ((mchunkptr)(((char *)(p)) + (s)))->head |= PINUSE_BIT) + +/* Set size, cinuse and pinuse bit of this chunk */ +#define set_size_and_pinuse_of_inuse_chunk(M, p, s) \ + ((p)->head = (s | PINUSE_BIT | CINUSE_BIT)) + +#else /* FOOTERS */ + +/* Set foot of inuse chunk to be xor of mstate and seed */ +#define mark_inuse_foot(M, p, s) \ + (((mchunkptr)((char *)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic)) + +#define get_mstate_for(p) \ + ((mstate)(((mchunkptr)((char *)(p) + (chunksize(p))))->prev_foot ^ \ + mparams.magic)) + +#define set_inuse(M, p, s) \ + ((p)->head = (((p)->head & PINUSE_BIT) | s | CINUSE_BIT), \ + (((mchunkptr)(((char *)(p)) + (s)))->head |= PINUSE_BIT), \ + mark_inuse_foot(M, p, s)) + +#define set_inuse_and_pinuse(M, p, s) \ + ((p)->head = (s | PINUSE_BIT | CINUSE_BIT), \ + (((mchunkptr)(((char *)(p)) + (s)))->head |= PINUSE_BIT), \ + mark_inuse_foot(M, p, s)) + +#define set_size_and_pinuse_of_inuse_chunk(M, p, s) \ + ((p)->head = (s | PINUSE_BIT | CINUSE_BIT), mark_inuse_foot(M, p, s)) + +#endif /* !FOOTERS */ + +/* Return segment holding given address */ +forceinline msegmentptr segment_holding(mstate m, char *addr) { + msegmentptr sp = &m->seg; + for (;;) { + if (addr >= sp->base && addr < sp->base + sp->size) return sp; + if ((sp = sp->next) == 0) return 0; + } +} + +/* ─────────────────────── Operations on smallbins ─────────────────────── */ + +/* + Various forms of linking and unlinking are defined as macros. Even + the ones for trees, which are very long but have very short typical + paths. This is ugly but reduces reliance on inlining support of + compilers. +*/ + +/* Link a free chunk into a smallbin */ +#define insert_small_chunk(M, P, S) \ + { \ + bindex_t I = small_index(S); \ + mchunkptr B = smallbin_at(M, I); \ + mchunkptr F = B; \ + assert(S >= MIN_CHUNK_SIZE); \ + if (!smallmap_is_marked(M, I)) \ + mark_smallmap(M, I); \ + else if (RTCHECK(ok_address(M, B->fd))) \ + F = B->fd; \ + else { \ + CORRUPTION_ERROR_ACTION(M); \ + } \ + B->fd = P; \ + F->bk = P; \ + P->fd = F; \ + P->bk = B; \ + } + +/* Unlink a chunk from a smallbin */ +#define unlink_small_chunk(M, P, S) \ + { \ + mchunkptr F = P->fd; \ + mchunkptr B = P->bk; \ + bindex_t I = small_index(S); \ + assert(P != B); \ + assert(P != F); \ + assert(chunksize(P) == small_index2size(I)); \ + if (RTCHECK(F == smallbin_at(M, I) || (ok_address(M, F) && F->bk == P))) { \ + if (B == F) { \ + clear_smallmap(M, I); \ + } else if (RTCHECK(B == smallbin_at(M, I) || \ + (ok_address(M, B) && B->fd == P))) { \ + F->bk = B; \ + B->fd = F; \ + } else { \ + CORRUPTION_ERROR_ACTION(M); \ + } \ + } else { \ + CORRUPTION_ERROR_ACTION(M); \ + } \ + } + +/* Unlink the first chunk from a smallbin */ +#define unlink_first_small_chunk(M, B, P, I) \ + { \ + mchunkptr F = P->fd; \ + assert(P != B); \ + assert(P != F); \ + assert(chunksize(P) == small_index2size(I)); \ + if (B == F) { \ + clear_smallmap(M, I); \ + } else if (RTCHECK(ok_address(M, F) && F->bk == P)) { \ + F->bk = B; \ + B->fd = F; \ + } else { \ + CORRUPTION_ERROR_ACTION(M); \ + } \ + } + +/* Replace dv node, binning the old one */ +/* Used only when dvsize known to be small */ +#define replace_dv(M, P, S) \ + { \ + size_t DVS = M->dvsize; \ + assert(is_small(DVS)); \ + if (DVS != 0) { \ + mchunkptr DV = M->dv; \ + insert_small_chunk(M, DV, DVS); \ + } \ + M->dvsize = S; \ + M->dv = P; \ + } + +/* ───────────────────────── Operations on trees ───────────────────────── */ + +/* Insert chunk into tree */ +#define insert_large_chunk(M, X, S) \ + { \ + tbinptr *H; \ + bindex_t I; \ + compute_tree_index(S, I); \ + H = treebin_at(M, I); \ + X->index = I; \ + X->child[0] = X->child[1] = 0; \ + if (!treemap_is_marked(M, I)) { \ + mark_treemap(M, I); \ + *H = X; \ + X->parent = (tchunkptr)H; \ + X->fd = X->bk = X; \ + } else { \ + tchunkptr T = *H; \ + size_t K = S << leftshift_for_tree_index(I); \ + for (;;) { \ + if (chunksize(T) != S) { \ + tchunkptr *C = \ + &(T->child[(K >> (SIZE_T_BITSIZE - SIZE_T_ONE)) & 1]); \ + K <<= 1; \ + if (*C != 0) \ + T = *C; \ + else if (RTCHECK(ok_address(M, C))) { \ + *C = X; \ + X->parent = T; \ + X->fd = X->bk = X; \ + break; \ + } else { \ + CORRUPTION_ERROR_ACTION(M); \ + break; \ + } \ + } else { \ + tchunkptr F = T->fd; \ + if (RTCHECK(ok_address(M, T) && ok_address(M, F))) { \ + T->fd = F->bk = X; \ + X->fd = F; \ + X->bk = T; \ + X->parent = 0; \ + break; \ + } else { \ + CORRUPTION_ERROR_ACTION(M); \ + break; \ + } \ + } \ + } \ + } \ + } + +/* + Unlink steps: + + 1. If x is a chained node, unlink it from its same-sized fd/bk links + and choose its bk node as its replacement. + 2. If x was the last node of its size, but not a leaf node, it must + be replaced with a leaf node (not merely one with an open left or + right), to make sure that lefts and rights of descendents + correspond properly to bit masks. We use the rightmost descendent + of x. We could use any other leaf, but this is easy to locate and + tends to counteract removal of leftmosts elsewhere, and so keeps + paths shorter than minimally guaranteed. This doesn't loop much + because on average a node in a tree is near the bottom. + 3. If x is the base of a chain (i.e., has parent links) relink + x's parent and children to x's replacement (or null if none). +*/ + +#define unlink_large_chunk(M, X) \ + { \ + tchunkptr XP = X->parent; \ + tchunkptr R; \ + if (X->bk != X) { \ + tchunkptr F = X->fd; \ + R = X->bk; \ + if (RTCHECK(ok_address(M, F) && F->bk == X && R->fd == X)) { \ + F->bk = R; \ + R->fd = F; \ + } else { \ + CORRUPTION_ERROR_ACTION(M); \ + } \ + } else { \ + tchunkptr *RP; \ + if (((R = *(RP = &(X->child[1]))) != 0) || \ + ((R = *(RP = &(X->child[0]))) != 0)) { \ + tchunkptr *CP; \ + while ((*(CP = &(R->child[1])) != 0) || \ + (*(CP = &(R->child[0])) != 0)) { \ + R = *(RP = CP); \ + } \ + if (RTCHECK(ok_address(M, RP))) \ + *RP = 0; \ + else { \ + CORRUPTION_ERROR_ACTION(M); \ + } \ + } \ + } \ + if (XP != 0) { \ + tbinptr *H = treebin_at(M, X->index); \ + if (X == *H) { \ + if ((*H = R) == 0) clear_treemap(M, X->index); \ + } else if (RTCHECK(ok_address(M, XP))) { \ + if (XP->child[0] == X) \ + XP->child[0] = R; \ + else \ + XP->child[1] = R; \ + } else \ + CORRUPTION_ERROR_ACTION(M); \ + if (R != 0) { \ + if (RTCHECK(ok_address(M, R))) { \ + tchunkptr C0, C1; \ + R->parent = XP; \ + if ((C0 = X->child[0]) != 0) { \ + if (RTCHECK(ok_address(M, C0))) { \ + R->child[0] = C0; \ + C0->parent = R; \ + } else \ + CORRUPTION_ERROR_ACTION(M); \ + } \ + if ((C1 = X->child[1]) != 0) { \ + if (RTCHECK(ok_address(M, C1))) { \ + R->child[1] = C1; \ + C1->parent = R; \ + } else \ + CORRUPTION_ERROR_ACTION(M); \ + } \ + } else \ + CORRUPTION_ERROR_ACTION(M); \ + } \ + } \ + } + +/* Relays to large vs small bin operations */ +#define insert_chunk(M, P, S) \ + if (is_small(S)) insert_small_chunk(M, P, S) else { \ + tchunkptr TP = (tchunkptr)(P); \ + insert_large_chunk(M, TP, S); \ + } +#define unlink_chunk(M, P, S) \ + if (is_small(S)) unlink_small_chunk(M, P, S) else { \ + tchunkptr TP = (tchunkptr)(P); \ + unlink_large_chunk(M, TP); \ + } + +#ifndef MORECORE_CANNOT_TRIM +#define should_trim(M, s) ((s) > (M)->trim_check) +#else /* MORECORE_CANNOT_TRIM */ +#define should_trim(M, s) (0) +#endif /* MORECORE_CANNOT_TRIM */ + +/* + TOP_FOOT_SIZE is padding at the end of a segment, including space + that may be needed to place segment records and fenceposts when new + noncontiguous segments are added. +*/ +#define TOP_FOOT_SIZE \ + (align_offset(chunk2mem(0)) + pad_request(sizeof(struct malloc_segment)) + \ + MIN_CHUNK_SIZE) + +/* ────────────────────────── Debugging setup ──────────────────────────── */ + +#if !(DEBUG + MODE_DBG + 0) +#define check_free_chunk(M, P) +#define check_inuse_chunk(M, P) +#define check_malloced_chunk(M, P, N) +#define check_mmapped_chunk(M, P) +#define check_malloc_state(M) +#define check_top_chunk(M, P) +#else /* DEBUG */ +#define check_free_chunk(M, P) do_check_free_chunk(M, P) +#define check_inuse_chunk(M, P) do_check_inuse_chunk(M, P) +#define check_top_chunk(M, P) do_check_top_chunk(M, P) +#define check_malloced_chunk(M, P, N) do_check_malloced_chunk(M, P, N) +#define check_mmapped_chunk(M, P) do_check_mmapped_chunk(M, P) +#define check_malloc_state(M) do_check_malloc_state(M) +#endif /* DEBUG */ + +void do_check_free_chunk(mstate m, mchunkptr p) hidden; +void do_check_inuse_chunk(mstate m, mchunkptr p) hidden; +void do_check_top_chunk(mstate m, mchunkptr p) hidden; +void do_check_malloced_chunk(mstate m, void *mem, size_t s) hidden; +void do_check_mmapped_chunk(mstate m, mchunkptr p) hidden; +void do_check_malloc_state(mstate m) hidden; + +/* ─────────────────────────── prototypes ──────────────────────────────── */ + +void *dlmalloc(size_t) hidden; +void *dlcalloc(size_t, size_t) hidden; +void dlfree(void *) nothrow nocallback hidden; +void *dlmemalign$impl(mstate, size_t, size_t) hidden; +void *dlrealloc(void *, size_t) hidden; +void *dlrealloc_in_place(void *, size_t) hidden; +void *dlvalloc(size_t) hidden; +void *dlpvalloc(size_t) hidden; +void *dlmemalign(size_t, size_t) hidden; +size_t dlmalloc_usable_size(const void *) hidden; +int dlposix_memalign(void **, size_t, size_t) hidden; +void **dlindependent_calloc(size_t, size_t, void *[]) hidden; +void **dlindependent_comalloc(size_t, size_t[], void *[]) hidden; +struct MallocStats dlmalloc_stats(mstate) hidden; +int dlmalloc_sys_trim(mstate, size_t) hidden; +void dlmalloc_dispose_chunk(mstate, mchunkptr, size_t) hidden; +mchunkptr dlmalloc_try_realloc_chunk(mstate, mchunkptr, size_t, int) hidden; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_MEM_DLMALLOC_H_ */ diff --git a/third_party/dlmalloc/dlmalloc.mk b/third_party/dlmalloc/dlmalloc.mk new file mode 100644 index 00000000..7a12392a --- /dev/null +++ b/third_party/dlmalloc/dlmalloc.mk @@ -0,0 +1,60 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += THIRD_PARTY_DLMALLOC + +THIRD_PARTY_DLMALLOC_ARTIFACTS += THIRD_PARTY_DLMALLOC_A +THIRD_PARTY_DLMALLOC = $(THIRD_PARTY_DLMALLOC_A_DEPS) $(THIRD_PARTY_DLMALLOC_A) +THIRD_PARTY_DLMALLOC_A = o/$(MODE)/third_party/dlmalloc/dlmalloc.a +THIRD_PARTY_DLMALLOC_A_FILES := $(wildcard third_party/dlmalloc/*) +THIRD_PARTY_DLMALLOC_A_HDRS = $(filter %.h,$(THIRD_PARTY_DLMALLOC_A_FILES)) +THIRD_PARTY_DLMALLOC_A_SRCS_S = $(filter %.S,$(THIRD_PARTY_DLMALLOC_A_FILES)) +THIRD_PARTY_DLMALLOC_A_SRCS_C = $(filter %.c,$(THIRD_PARTY_DLMALLOC_A_FILES)) + +THIRD_PARTY_DLMALLOC_A_SRCS = \ + $(THIRD_PARTY_DLMALLOC_A_SRCS_S) \ + $(THIRD_PARTY_DLMALLOC_A_SRCS_C) + +THIRD_PARTY_DLMALLOC_A_OBJS = \ + $(THIRD_PARTY_DLMALLOC_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(THIRD_PARTY_DLMALLOC_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(THIRD_PARTY_DLMALLOC_A_SRCS_C:%.c=o/$(MODE)/%.o) + +THIRD_PARTY_DLMALLOC_A_CHECKS = \ + $(THIRD_PARTY_DLMALLOC_A).pkg \ + $(THIRD_PARTY_DLMALLOC_A_HDRS:%=o/$(MODE)/%.ok) + +THIRD_PARTY_DLMALLOC_A_DIRECTDEPS = \ + LIBC_CALLS \ + LIBC_CONV \ + LIBC_FMT \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_SYSV_CALLS + +THIRD_PARTY_DLMALLOC_A_DEPS := \ + $(call uniq,$(foreach x,$(THIRD_PARTY_DLMALLOC_A_DIRECTDEPS),$($(x)))) + +$(THIRD_PARTY_DLMALLOC_A): \ + third_party/dlmalloc/ \ + $(THIRD_PARTY_DLMALLOC_A).pkg \ + $(THIRD_PARTY_DLMALLOC_A_OBJS) + +$(THIRD_PARTY_DLMALLOC_A).pkg: \ + $(THIRD_PARTY_DLMALLOC_A_OBJS) \ + $(foreach x,$(THIRD_PARTY_DLMALLOC_A_DIRECTDEPS),$($(x)_A).pkg) + +THIRD_PARTY_DLMALLOC_LIBS = $(foreach x,$(THIRD_PARTY_DLMALLOC_ARTIFACTS),$($(x))) +THIRD_PARTY_DLMALLOC_SRCS = $(foreach x,$(THIRD_PARTY_DLMALLOC_ARTIFACTS),$($(x)_SRCS)) +THIRD_PARTY_DLMALLOC_HDRS = $(foreach x,$(THIRD_PARTY_DLMALLOC_ARTIFACTS),$($(x)_HDRS)) +THIRD_PARTY_DLMALLOC_BINS = $(foreach x,$(THIRD_PARTY_DLMALLOC_ARTIFACTS),$($(x)_BINS)) +THIRD_PARTY_DLMALLOC_CHECKS = $(foreach x,$(THIRD_PARTY_DLMALLOC_ARTIFACTS),$($(x)_CHECKS)) +THIRD_PARTY_DLMALLOC_OBJS = $(foreach x,$(THIRD_PARTY_DLMALLOC_ARTIFACTS),$($(x)_OBJS)) +THIRD_PARTY_DLMALLOC_TESTS = $(foreach x,$(THIRD_PARTY_DLMALLOC_ARTIFACTS),$($(x)_TESTS)) +$(THIRD_PARTY_DLMALLOC_OBJS): $(BUILD_FILES) third_party/dlmalloc/dlmalloc.mk + +.PHONY: o/$(MODE)/third_party/dlmalloc +o/$(MODE)/third_party/dlmalloc: $(THIRD_PARTY_DLMALLOC_CHECKS) diff --git a/third_party/dlmalloc/dlmalloc_stats.c b/third_party/dlmalloc/dlmalloc_stats.c new file mode 100644 index 00000000..e3592ab4 --- /dev/null +++ b/third_party/dlmalloc/dlmalloc_stats.c @@ -0,0 +1,47 @@ +#include "third_party/dlmalloc/dlmalloc.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" + +/** + * Prints on stderr the amount of space obtained from the system (both + * via sbrk and mmap), the maximum amount (which may be more than + * current if malloc_trim and/or munmap got called), and the current + * number of bytes allocated via malloc (or realloc, etc) but not yet + * freed. Note that this is the number of bytes allocated, not the + * number requested. It will be larger than the number requested because + * of alignment and bookkeeping overhead. Because it includes alignment + * wastage as being in use, this figure may be greater than zero even + * when no user-level chunks are allocated. + * + * The reported current and maximum system memory can be inaccurate if a + * program makes other calls to system memory allocation functions + * (normally sbrk) outside of malloc. + * + * malloc_stats prints only the most commonly interesting statistics. + * More information can be obtained by calling mallinfo. + */ +struct MallocStats dlmalloc_stats(mstate m) { + struct MallocStats res; + memset(&res, 0, sizeof(res)); + ensure_initialization(); + if (!PREACTION(m)) { + check_malloc_state(m); + if (is_initialized(m)) { + msegmentptr s = &m->seg; + res.maxfp = m->max_footprint; + res.fp = m->footprint; + res.used = res.fp - (m->topsize + TOP_FOOT_SIZE); + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + while (segment_holds(s, q) && q != m->top && + q->head != FENCEPOST_HEAD) { + if (!is_inuse(q)) res.used -= chunksize(q); + q = next_chunk(q); + } + s = s->next; + } + } + POSTACTION(m); /* drop lock */ + } + return res; +} diff --git a/third_party/dlmalloc/dlmemalign-impl.c b/third_party/dlmalloc/dlmemalign-impl.c new file mode 100644 index 00000000..7d2f0819 --- /dev/null +++ b/third_party/dlmalloc/dlmemalign-impl.c @@ -0,0 +1,70 @@ +#include "libc/mem/mem.h" +#include "libc/sysv/errfuns.h" +#include "third_party/dlmalloc/dlmalloc.h" + +void* dlmemalign$impl(mstate m, size_t alignment, size_t bytes) { + void* mem = 0; + if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */ + alignment = MIN_CHUNK_SIZE; + if ((alignment & (alignment - SIZE_T_ONE)) != 0) { /* Ensure a power of 2 */ + size_t a = MALLOC_ALIGNMENT << 1; + while (a < alignment) a <<= 1; + alignment = a; + } + if (bytes >= MAX_REQUEST - alignment) { + if (m != 0) { /* Test isn't needed but avoids compiler warning */ + enomem(); + } + } else { + size_t nb = request2size(bytes); + size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; + mem = dlmalloc(req); + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + if (PREACTION(m)) return 0; + if ((((size_t)(mem)) & (alignment - 1)) != 0) { /* misaligned */ + /* + Find an aligned spot inside chunk. Since we need to give + back leading space in a chunk of at least MIN_CHUNK_SIZE, if + the first calculation places us at a spot with less than + MIN_CHUNK_SIZE leader, we can move to the next aligned spot. + We've allocated enough total room so that this is always + possible. + */ + char* br = (char*)mem2chunk((size_t)( + ((size_t)((char*)mem + alignment - SIZE_T_ONE)) & -alignment)); + char* pos = + ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE) ? br : br + alignment; + mchunkptr newp = (mchunkptr)pos; + size_t leadsize = pos - (char*)(p); + size_t newsize = chunksize(p) - leadsize; + if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */ + newp->prev_foot = p->prev_foot + leadsize; + newp->head = newsize; + } else { /* Otherwise, give back leader, use the rest */ + set_inuse(m, newp, newsize); + set_inuse(m, p, leadsize); + dlmalloc_dispose_chunk(m, p, leadsize); + } + p = newp; + } + /* Give back spare room at the end */ + if (!is_mmapped(p)) { + size_t size = chunksize(p); + if (size > nb + MIN_CHUNK_SIZE) { + size_t remainder_size = size - nb; + mchunkptr remainder = chunk_plus_offset(p, nb); + set_inuse(m, p, nb); + set_inuse(m, remainder, remainder_size); + dlmalloc_dispose_chunk(m, remainder, remainder_size); + } + } + mem = chunk2mem(p); + assert(chunksize(p) >= nb); + assert(((size_t)mem & (alignment - 1)) == 0); + check_inuse_chunk(m, p); + POSTACTION(m); + } + } + return ADDRESS_BIRTH_ACTION(mem); +} diff --git a/third_party/dlmalloc/dlmemalign.c b/third_party/dlmalloc/dlmemalign.c new file mode 100644 index 00000000..7687f2a8 --- /dev/null +++ b/third_party/dlmalloc/dlmemalign.c @@ -0,0 +1,9 @@ +#include "third_party/dlmalloc/dlmalloc.h" +#include "libc/mem/mem.h" + +void *dlmemalign(size_t alignment, size_t bytes) { + if (alignment <= MALLOC_ALIGNMENT) { + return dlmalloc(bytes); + } + return dlmemalign$impl(gm, alignment, bytes); +} diff --git a/third_party/dlmalloc/dlposix_memalign.c b/third_party/dlmalloc/dlposix_memalign.c new file mode 100644 index 00000000..d3bb5df1 --- /dev/null +++ b/third_party/dlmalloc/dlposix_memalign.c @@ -0,0 +1,25 @@ +#include "libc/errno.h" +#include "libc/mem/mem.h" +#include "third_party/dlmalloc/dlmalloc.h" + +int dlposix_memalign(void** pp, size_t alignment, size_t bytes) { + void* mem = 0; + if (alignment == MALLOC_ALIGNMENT) + mem = dlmalloc(bytes); + else { + size_t d = alignment / sizeof(void*); + size_t r = alignment % sizeof(void*); + if (r != 0 || d == 0 || (d & (d - SIZE_T_ONE)) != 0) + return EINVAL; + else if (bytes <= MAX_REQUEST - alignment) { + if (alignment < MIN_CHUNK_SIZE) alignment = MIN_CHUNK_SIZE; + mem = dlmemalign$impl(gm, alignment, bytes); + } + } + if (mem == 0) + return ENOMEM; + else { + *pp = mem; + return 0; + } +} diff --git a/third_party/dlmalloc/dlpvalloc.c b/third_party/dlmalloc/dlpvalloc.c new file mode 100644 index 00000000..f8209649 --- /dev/null +++ b/third_party/dlmalloc/dlpvalloc.c @@ -0,0 +1,10 @@ +#include "libc/mem/mem.h" +#include "third_party/dlmalloc/dlmalloc.h" + +void *dlpvalloc(size_t bytes) { + size_t pagesz; + ensure_initialization(); + pagesz = mparams.page_size; + return dlmemalign(pagesz, + (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); +} diff --git a/third_party/dlmalloc/dlrealloc_in_place.c b/third_party/dlmalloc/dlrealloc_in_place.c new file mode 100644 index 00000000..9c47c5a2 --- /dev/null +++ b/third_party/dlmalloc/dlrealloc_in_place.c @@ -0,0 +1,33 @@ +#include "libc/mem/mem.h" +#include "libc/sysv/errfuns.h" +#include "third_party/dlmalloc/dlmalloc.h" + +void *dlrealloc_in_place(void *oldmem, size_t bytes) { + void *mem = 0; + if (oldmem != 0) { + if (bytes >= MAX_REQUEST) { + enomem(); + } else { + size_t nb = request2size(bytes); + mchunkptr oldp = mem2chunk(oldmem); +#if !FOOTERS + mstate m = gm; +#else /* FOOTERS */ + mstate m = get_mstate_for(oldp); + if (!ok_magic(m)) { + USAGE_ERROR_ACTION(m, oldmem); + return 0; + } +#endif /* FOOTERS */ + if (!PREACTION(m)) { + mchunkptr newp = dlmalloc_try_realloc_chunk(m, oldp, nb, 0); + POSTACTION(m); + if (newp == oldp) { + check_inuse_chunk(m, newp); + mem = oldmem; + } + } + } + } + return mem; +} diff --git a/third_party/dlmalloc/dlvalloc.c b/third_party/dlmalloc/dlvalloc.c new file mode 100644 index 00000000..26222423 --- /dev/null +++ b/third_party/dlmalloc/dlvalloc.c @@ -0,0 +1,9 @@ +#include "libc/mem/mem.h" +#include "third_party/dlmalloc/dlmalloc.h" + +void *dlvalloc(size_t bytes) { + size_t pagesz; + ensure_initialization(); + pagesz = mparams.page_size; + return dlmemalign(pagesz, bytes); +} diff --git a/third_party/dlmalloc/mallinfo.c b/third_party/dlmalloc/mallinfo.c new file mode 100644 index 00000000..1bdf4c94 --- /dev/null +++ b/third_party/dlmalloc/mallinfo.c @@ -0,0 +1,60 @@ +#include "third_party/dlmalloc/dlmalloc.h" +#include "libc/mem/mem.h" + +/** + * Returns (by copy) a struct containing various summary statistics: + * + * arena: current total non-mmapped bytes allocated from system + * ordblks: the number of free chunks + * smblks: always zero. + * hblks: current number of mmapped regions + * hblkhd: total bytes held in mmapped regions + * usmblks: the maximum total allocated space. This will be greater + * than current total if trimming has occurred. + * fsmblks: always zero + * uordblks: current total allocated space (normal or mmapped) + * fordblks: total free space + * keepcost: the maximum number of bytes that could ideally be released + * back to system via malloc_trim. ("ideally" means that + * it ignores page restrictions etc.) + * + * Because these fields are ints, but internal bookkeeping may + * be kept as longs, the reported values may wrap around zero and + * thus be inaccurate. + */ +struct mallinfo mallinfo(void) { + struct mallinfo nm = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + ensure_initialization(); + if (!PREACTION(gm)) { + check_malloc_state(gm); + if (is_initialized(gm)) { + size_t nfree = SIZE_T_ONE; /* top always free */ + size_t mfree = gm->topsize + TOP_FOOT_SIZE; + size_t sum = mfree; + msegmentptr s = &gm->seg; + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + while (segment_holds(s, q) && q != gm->top && + q->head != FENCEPOST_HEAD) { + size_t sz = chunksize(q); + sum += sz; + if (!is_inuse(q)) { + mfree += sz; + ++nfree; + } + q = next_chunk(q); + } + s = s->next; + } + nm.arena = sum; + nm.ordblks = nfree; + nm.hblkhd = gm->footprint - sum; + nm.usmblks = gm->max_footprint; + nm.uordblks = gm->footprint - mfree; + nm.fordblks = mfree; + nm.keepcost = gm->topsize; + } + POSTACTION(gm); + } + return nm; +} diff --git a/third_party/dlmalloc/malloc_footprint.c b/third_party/dlmalloc/malloc_footprint.c new file mode 100644 index 00000000..541b5926 --- /dev/null +++ b/third_party/dlmalloc/malloc_footprint.c @@ -0,0 +1,12 @@ +#include "third_party/dlmalloc/dlmalloc.h" +#include "libc/mem/mem.h" + +/** + * Returns the number of bytes obtained from the system. The total + * number of bytes allocated by malloc, realloc etc., is less than this + * value. Unlike mallinfo, this function returns only a precomputed + * result, so can be called frequently to monitor memory consumption. + * Even if locks are otherwise defined, this function does not use them, + * so results might not be up to date. + */ +size_t malloc_footprint(void) { return gm->footprint; } diff --git a/third_party/dlmalloc/malloc_footprint_limit.c b/third_party/dlmalloc/malloc_footprint_limit.c new file mode 100644 index 00000000..24ecf624 --- /dev/null +++ b/third_party/dlmalloc/malloc_footprint_limit.c @@ -0,0 +1,15 @@ +#include "libc/limits.h" +#include "libc/mem/mem.h" +#include "third_party/dlmalloc/dlmalloc.h" + +/** + * Returns the number of bytes that the heap is allowed to obtain from + * the system, returning the last value returned by + * malloc_set_footprint_limit, or the maximum size_t value if never set. + * The returned value reflects a permission. There is no guarantee that + * this number of bytes can actually be obtained from the system. + */ +size_t malloc_footprint_limit(void) { + size_t maf = gm->footprint_limit; + return maf == 0 ? SIZE_MAX : maf; +} diff --git a/third_party/dlmalloc/malloc_inspect_all.c b/third_party/dlmalloc/malloc_inspect_all.c new file mode 100644 index 00000000..af4280e6 --- /dev/null +++ b/third_party/dlmalloc/malloc_inspect_all.c @@ -0,0 +1,71 @@ +#include "libc/mem/mem.h" +#include "third_party/dlmalloc/dlmalloc.h" + +static void internal_inspect_all(mstate m, + void (*handler)(void* start, void* end, + size_t used_bytes, + void* callback_arg), + void* arg) { + if (is_initialized(m)) { + mchunkptr top = m->top; + msegmentptr s; + for (s = &m->seg; s != 0; s = s->next) { + mchunkptr q = align_as_chunk(s->base); + while (segment_holds(s, q) && q->head != FENCEPOST_HEAD) { + mchunkptr next = next_chunk(q); + size_t sz = chunksize(q); + size_t used; + void* start; + if (is_inuse(q)) { + used = sz - CHUNK_OVERHEAD; /* must not be mmapped */ + start = chunk2mem(q); + } else { + used = 0; + if (is_small(sz)) { /* offset by possible bookkeeping */ + start = (void*)((char*)q + sizeof(struct malloc_chunk)); + } else { + start = (void*)((char*)q + sizeof(struct malloc_tree_chunk)); + } + } + if (start < (void*)next) /* skip if all space is bookkeeping */ + handler(start, next, used, arg); + if (q == top) break; + q = next; + } + } + } +} + +/** + * Traverses the heap and calls the given handler for each managed + * region, skipping all bytes that are (or may be) used for bookkeeping + * purposes. Traversal does not include include chunks that have been + * directly memory mapped. Each reported region begins at the start + * address, and continues up to but not including the end address. The + * first used_bytes of the region contain allocated data. If + * used_bytes is zero, the region is unallocated. The handler is + * invoked with the given callback argument. If locks are defined, they + * are held during the entire traversal. It is a bad idea to invoke + * other malloc functions from within the handler. + * + * For example, to count the number of in-use chunks with size greater + * than 1000, you could write: + * + * static int count = 0; + * void count_chunks(void* start, void* end, size_t used, void* arg) { + * if (used >= 1000) ++count; + * } + * + * then, + * + * malloc_inspect_all(count_chunks, NULL); + */ +void malloc_inspect_all(void (*handler)(void* start, void* end, + size_t used_bytes, void* callback_arg), + void* arg) { + ensure_initialization(); + if (!PREACTION(gm)) { + internal_inspect_all(gm, handler, arg); + POSTACTION(gm); + } +} diff --git a/third_party/dlmalloc/malloc_max_footprint.c b/third_party/dlmalloc/malloc_max_footprint.c new file mode 100644 index 00000000..b8941c17 --- /dev/null +++ b/third_party/dlmalloc/malloc_max_footprint.c @@ -0,0 +1,14 @@ +#include "third_party/dlmalloc/dlmalloc.h" +#include "libc/mem/mem.h" + +/** + * Returns the maximum number of bytes obtained from the system. This + * value will be greater than current footprint if deallocated space has + * been reclaimed by the system. The peak number of bytes allocated by + * malloc, realloc etc., is less than this value. Unlike mallinfo, this + * function returns only a precomputed result, so can be called + * frequently to monitor memory consumption. Even if locks are otherwise + * defined, this function does not use them, so results might not be up + * to date. + */ +size_t malloc_max_footprint(void) { return gm->max_footprint; } diff --git a/third_party/dlmalloc/malloc_set_footprint_limit.c b/third_party/dlmalloc/malloc_set_footprint_limit.c new file mode 100644 index 00000000..e50990a3 --- /dev/null +++ b/third_party/dlmalloc/malloc_set_footprint_limit.c @@ -0,0 +1,25 @@ +#include "libc/limits.h" +#include "libc/mem/mem.h" +#include "third_party/dlmalloc/dlmalloc.h" + +/** + * Sets the maximum number of bytes to obtain from the system, causing + * failure returns from malloc and related functions upon attempts to + * exceed this value. The argument value may be subject to page rounding + * to an enforceable limit; this actual value is returned. Using an + * argument of the maximum possible size_t effectively disables checks. + * If the argument is less than or equal to the current + * malloc_footprint, then all future allocations that require additional + * system memory will fail. However, invocation cannot retroactively + * deallocate existing used memory. + */ +size_t malloc_set_footprint_limit(size_t bytes) { + size_t result; /* invert sense of 0 */ + if (bytes == 0) result = granularity_align(1); /* Use minimal size */ + if (bytes == SIZE_MAX) { + result = 0; /* disable */ + } else { + result = granularity_align(bytes); + } + return gm->footprint_limit = result; +} diff --git a/third_party/dlmalloc/malloc_trim.c b/third_party/dlmalloc/malloc_trim.c new file mode 100644 index 00000000..828b2a12 --- /dev/null +++ b/third_party/dlmalloc/malloc_trim.c @@ -0,0 +1,31 @@ +#include "libc/mem/mem.h" +#include "third_party/dlmalloc/dlmalloc.h" + +/** + * If possible, gives memory back to the system (via negative arguments + * to sbrk) if there is unused memory at the `high' end of the malloc + * pool or in unused MMAP segments. You can call this after freeing + * large blocks of memory to potentially reduce the system-level memory + * requirements of a program. However, it cannot guarantee to reduce + * memory. Under some allocation patterns, some large free blocks of + * memory will be locked between two used chunks, so they cannot be + * given back to the system. + * + * The `pad' argument to malloc_trim represents the amount of free + * trailing space to leave untrimmed. If this argument is zero, only the + * minimum amount of memory to maintain internal data structures will be + * left. Non-zero arguments can be supplied to maintain enough trailing + * space to service future expected allocations without having to + * re-obtain memory from the system. + * + * @return 1 if it actually released any memory, else 0 + */ +int malloc_trim(size_t pad) { + int result = 0; + ensure_initialization(); + if (!PREACTION(gm)) { + result = dlmalloc_sys_trim(gm, pad); + POSTACTION(gm); + } + return result; +} diff --git a/third_party/dlmalloc/mallopt.c b/third_party/dlmalloc/mallopt.c new file mode 100644 index 00000000..4ee9e8ca --- /dev/null +++ b/third_party/dlmalloc/mallopt.c @@ -0,0 +1,42 @@ +#include "libc/limits.h" +#include "libc/mem/mem.h" +#include "third_party/dlmalloc/dlmalloc.h" + +/** + * Sets memory allocation parameter. + * + * The format is to provide a (parameter-number, parameter-value) pair. + * mallopt then sets the corresponding parameter to the argument value + * if it can (i.e., so long as the value is meaningful), and returns 1 + * if successful else 0. SVID/XPG/ANSI defines four standard param + * numbers for mallopt, normally defined in malloc.h. None of these are + * use in this malloc, so setting them has no effect. But this malloc + * also supports other options in mallopt: + * + * Symbol param # default allowed param values + * M_TRIM_THRESHOLD -1 2*1024*1024 any (-1U disables trimming) + * M_GRANULARITY -2 page size any power of 2 >= page size + * M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) + */ +bool32 mallopt(int param_number, int value) { + size_t val; + ensure_initialization(); + val = (value == -1) ? SIZE_MAX : (size_t)value; + switch (param_number) { + case M_TRIM_THRESHOLD: + mparams.trim_threshold = val; + return true; + case M_GRANULARITY: + if (val >= mparams.page_size && ((val & (val - 1)) == 0)) { + mparams.granularity = val; + return true; + } else { + return false; + } + case M_MMAP_THRESHOLD: + mparams.mmap_threshold = val; + return true; + default: + return false; + } +} diff --git a/third_party/dlmalloc/mtrace.c b/third_party/dlmalloc/mtrace.c new file mode 100644 index 00000000..038eea47 --- /dev/null +++ b/third_party/dlmalloc/mtrace.c @@ -0,0 +1,55 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/conv/itoa.h" +#include "libc/runtime/missioncritical.h" +#include "libc/str/str.h" +#include "third_party/dlmalloc/dlmalloc.h" + +static uintptr_t lastfree_; + +void *AddressBirthAction(void *addr) { + char buf[64], *p; + p = buf; + p = stpcpy(p, __FUNCTION__); + p = stpcpy(p, ": 0x"); + p += uint64toarray_radix16((uintptr_t)addr, p); + *p++ = '\n'; + __print(buf, p - buf); + if (lastfree_ == (uintptr_t)addr) { + lastfree_ = 0; + } + return addr; +} + +void *AddressDeathAction(void *addr) { + char buf[64], *p; + p = buf; + p = stpcpy(p, __FUNCTION__); + p = stpcpy(p, ": 0x"); + p += uint64toarray_radix16((uintptr_t)addr, p); + if (lastfree_ != (uintptr_t)addr) { + lastfree_ = (uintptr_t)addr; + } else { + p = stpcpy(p, " [OBVIOUS DOUBLE FREE]"); + } + *p++ = '\n'; + __print(buf, p - buf); + return addr; +} diff --git a/third_party/double-conversion/LICENSE b/third_party/double-conversion/LICENSE new file mode 100644 index 00000000..933718a9 --- /dev/null +++ b/third_party/double-conversion/LICENSE @@ -0,0 +1,26 @@ +Copyright 2006-2011, the V8 project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/double-conversion/README.cosmo b/third_party/double-conversion/README.cosmo new file mode 100644 index 00000000..e797015f --- /dev/null +++ b/third_party/double-conversion/README.cosmo @@ -0,0 +1 @@ +google/double-conversion@1dce44c4313a6f356fcfa4b3e8887f037ac0bf23 diff --git a/third_party/double-conversion/bignum-dtoa.cc b/third_party/double-conversion/bignum-dtoa.cc new file mode 100644 index 00000000..48d71545 --- /dev/null +++ b/third_party/double-conversion/bignum-dtoa.cc @@ -0,0 +1,621 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "libc/macros.h" +#include "libc/math.h" +#include "third_party/double-conversion/bignum-dtoa.h" +#include "third_party/double-conversion/bignum.h" +#include "third_party/double-conversion/ieee.h" + +asm(".ident\t\"\\n\\n\ +double-conversion (BSD-3)\\n\ +Copyright 2010 the V8 project authors\""); +asm(".include \"libc/disclaimer.inc\""); + +namespace double_conversion { + +static int NormalizedExponent(uint64_t significand, int exponent) { + DOUBLE_CONVERSION_ASSERT(significand != 0); + while ((significand & Double::kHiddenBit) == 0) { + significand = significand << 1; + exponent = exponent - 1; + } + return exponent; +} + +// Forward declarations: +// Returns an estimation of k such that 10^(k-1) <= v < 10^k. +static int EstimatePower(int exponent); +// Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator +// and denominator. +static void InitialScaledStartValues(uint64_t significand, int exponent, + bool lower_boundary_is_closer, + int estimated_power, + bool need_boundary_deltas, + Bignum* numerator, Bignum* denominator, + Bignum* delta_minus, Bignum* delta_plus); +// Multiplies numerator/denominator so that its values lies in the range 1-10. +// Returns decimal_point s.t. +// v = numerator'/denominator' * 10^(decimal_point-1) +// where numerator' and denominator' are the values of numerator and +// denominator after the call to this function. +static void FixupMultiply10(int estimated_power, bool is_even, + int* decimal_point, Bignum* numerator, + Bignum* denominator, Bignum* delta_minus, + Bignum* delta_plus); +// Generates digits from the left to the right and stops when the generated +// digits yield the shortest decimal representation of v. +static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator, + Bignum* delta_minus, Bignum* delta_plus, + bool is_even, Vector buffer, + int* length); +// Generates 'requested_digits' after the decimal point. +static void BignumToFixed(int requested_digits, int* decimal_point, + Bignum* numerator, Bignum* denominator, + Vector buffer, int* length); +// Generates 'count' digits of numerator/denominator. +// Once 'count' digits have been produced rounds the result depending on the +// remainder (remainders of exactly .5 round upwards). Might update the +// decimal_point when rounding up (for example for 0.9999). +static void GenerateCountedDigits(int count, int* decimal_point, + Bignum* numerator, Bignum* denominator, + Vector buffer, int* length); + +void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits, + Vector buffer, int* length, int* decimal_point) { + DOUBLE_CONVERSION_ASSERT(v > 0); + DOUBLE_CONVERSION_ASSERT(!Double(v).IsSpecial()); + uint64_t significand; + int exponent; + bool lower_boundary_is_closer; + if (mode == BIGNUM_DTOA_SHORTEST_SINGLE) { + float f = static_cast(v); + DOUBLE_CONVERSION_ASSERT(f == v); + significand = Single(f).Significand(); + exponent = Single(f).Exponent(); + lower_boundary_is_closer = Single(f).LowerBoundaryIsCloser(); + } else { + significand = Double(v).Significand(); + exponent = Double(v).Exponent(); + lower_boundary_is_closer = Double(v).LowerBoundaryIsCloser(); + } + bool need_boundary_deltas = + (mode == BIGNUM_DTOA_SHORTEST || mode == BIGNUM_DTOA_SHORTEST_SINGLE); + + bool is_even = (significand & 1) == 0; + int normalized_exponent = NormalizedExponent(significand, exponent); + // estimated_power might be too low by 1. + int estimated_power = EstimatePower(normalized_exponent); + + // Shortcut for Fixed. + // The requested digits correspond to the digits after the point. If the + // number is much too small, then there is no need in trying to get any + // digits. + if (mode == BIGNUM_DTOA_FIXED && -estimated_power - 1 > requested_digits) { + buffer[0] = '\0'; + *length = 0; + // Set decimal-point to -requested_digits. This is what Gay does. + // Note that it should not have any effect anyways since the string is + // empty. + *decimal_point = -requested_digits; + return; + } + + Bignum numerator; + Bignum denominator; + Bignum delta_minus; + Bignum delta_plus; + // Make sure the bignum can grow large enough. The smallest double equals + // 4e-324. In this case the denominator needs fewer than 324*4 binary digits. + // The maximum double is 1.7976931348623157e308 which needs fewer than + // 308*4 binary digits. + DOUBLE_CONVERSION_ASSERT(Bignum::kMaxSignificantBits >= 324 * 4); + InitialScaledStartValues(significand, exponent, lower_boundary_is_closer, + estimated_power, need_boundary_deltas, &numerator, + &denominator, &delta_minus, &delta_plus); + // We now have v = (numerator / denominator) * 10^estimated_power. + FixupMultiply10(estimated_power, is_even, decimal_point, &numerator, + &denominator, &delta_minus, &delta_plus); + // We now have v = (numerator / denominator) * 10^(decimal_point-1), and + // 1 <= (numerator + delta_plus) / denominator < 10 + switch (mode) { + case BIGNUM_DTOA_SHORTEST: + case BIGNUM_DTOA_SHORTEST_SINGLE: + GenerateShortestDigits(&numerator, &denominator, &delta_minus, + &delta_plus, is_even, buffer, length); + break; + case BIGNUM_DTOA_FIXED: + BignumToFixed(requested_digits, decimal_point, &numerator, &denominator, + buffer, length); + break; + case BIGNUM_DTOA_PRECISION: + GenerateCountedDigits(requested_digits, decimal_point, &numerator, + &denominator, buffer, length); + break; + default: + DOUBLE_CONVERSION_UNREACHABLE(); + } + buffer[*length] = '\0'; +} + +// The procedure starts generating digits from the left to the right and stops +// when the generated digits yield the shortest decimal representation of v. A +// decimal representation of v is a number lying closer to v than to any other +// double, so it converts to v when read. +// +// This is true if d, the decimal representation, is between m- and m+, the +// upper and lower boundaries. d must be strictly between them if !is_even. +// m- := (numerator - delta_minus) / denominator +// m+ := (numerator + delta_plus) / denominator +// +// Precondition: 0 <= (numerator+delta_plus) / denominator < 10. +// If 1 <= (numerator+delta_plus) / denominator < 10 then no leading 0 digit +// will be produced. This should be the standard precondition. +static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator, + Bignum* delta_minus, Bignum* delta_plus, + bool is_even, Vector buffer, + int* length) { + // Small optimization: if delta_minus and delta_plus are the same just reuse + // one of the two bignums. + if (Bignum::Equal(*delta_minus, *delta_plus)) { + delta_plus = delta_minus; + } + *length = 0; + for (;;) { + uint16_t digit; + digit = numerator->DivideModuloIntBignum(*denominator); + DOUBLE_CONVERSION_ASSERT( + digit <= 9); // digit is a uint16_t and therefore always positive. + // digit = numerator / denominator (integer division). + // numerator = numerator % denominator. + buffer[(*length)++] = static_cast(digit + '0'); + + // Can we stop already? + // If the remainder of the division is less than the distance to the lower + // boundary we can stop. In this case we simply round down (discarding the + // remainder). + // Similarly we test if we can round up (using the upper boundary). + bool in_delta_room_minus; + bool in_delta_room_plus; + if (is_even) { + in_delta_room_minus = Bignum::LessEqual(*numerator, *delta_minus); + } else { + in_delta_room_minus = Bignum::Less(*numerator, *delta_minus); + } + if (is_even) { + in_delta_room_plus = + Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0; + } else { + in_delta_room_plus = + Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0; + } + if (!in_delta_room_minus && !in_delta_room_plus) { + // Prepare for next iteration. + numerator->Times10(); + delta_minus->Times10(); + // We optimized delta_plus to be equal to delta_minus (if they share the + // same value). So don't multiply delta_plus if they point to the same + // object. + if (delta_minus != delta_plus) { + delta_plus->Times10(); + } + } else if (in_delta_room_minus && in_delta_room_plus) { + // Let's see if 2*numerator < denominator. + // If yes, then the next digit would be < 5 and we can round down. + int compare = Bignum::PlusCompare(*numerator, *numerator, *denominator); + if (compare < 0) { + // Remaining digits are less than .5. -> Round down (== do nothing). + } else if (compare > 0) { + // Remaining digits are more than .5 of denominator. -> Round up. + // Note that the last digit could not be a '9' as otherwise the whole + // loop would have stopped earlier. + // We still have an assert here in case the preconditions were not + // satisfied. + DOUBLE_CONVERSION_ASSERT(buffer[(*length) - 1] != '9'); + buffer[(*length) - 1]++; + } else { + // Halfway case. + // TODO(floitsch): need a way to solve half-way cases. + // For now let's round towards even (since this is what Gay seems to + // do). + + if ((buffer[(*length) - 1] - '0') % 2 == 0) { + // Round down => Do nothing. + } else { + DOUBLE_CONVERSION_ASSERT(buffer[(*length) - 1] != '9'); + buffer[(*length) - 1]++; + } + } + return; + } else if (in_delta_room_minus) { + // Round down (== do nothing). + return; + } else { // in_delta_room_plus + // Round up. + // Note again that the last digit could not be '9' since this would have + // stopped the loop earlier. + // We still have an DOUBLE_CONVERSION_ASSERT here, in case the + // preconditions were not satisfied. + DOUBLE_CONVERSION_ASSERT(buffer[(*length) - 1] != '9'); + buffer[(*length) - 1]++; + return; + } + } +} + +// Let v = numerator / denominator < 10. +// Then we generate 'count' digits of d = x.xxxxx... (without the decimal point) +// from left to right. Once 'count' digits have been produced we decide wether +// to round up or down. Remainders of exactly .5 round upwards. Numbers such +// as 9.999999 propagate a carry all the way, and change the +// exponent (decimal_point), when rounding upwards. +static void GenerateCountedDigits(int count, int* decimal_point, + Bignum* numerator, Bignum* denominator, + Vector buffer, int* length) { + DOUBLE_CONVERSION_ASSERT(count >= 0); + for (int i = 0; i < count - 1; ++i) { + uint16_t digit; + digit = numerator->DivideModuloIntBignum(*denominator); + DOUBLE_CONVERSION_ASSERT( + digit <= 9); // digit is a uint16_t and therefore always positive. + // digit = numerator / denominator (integer division). + // numerator = numerator % denominator. + buffer[i] = static_cast(digit + '0'); + // Prepare for next iteration. + numerator->Times10(); + } + // Generate the last digit. + uint16_t digit; + digit = numerator->DivideModuloIntBignum(*denominator); + if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) { + digit++; + } + DOUBLE_CONVERSION_ASSERT(digit <= 10); + buffer[count - 1] = static_cast(digit + '0'); + // Correct bad digits (in case we had a sequence of '9's). Propagate the + // carry until we hat a non-'9' or til we reach the first digit. + for (int i = count - 1; i > 0; --i) { + if (buffer[i] != '0' + 10) break; + buffer[i] = '0'; + buffer[i - 1]++; + } + if (buffer[0] == '0' + 10) { + // Propagate a carry past the top place. + buffer[0] = '1'; + (*decimal_point)++; + } + *length = count; +} + +// Generates 'requested_digits' after the decimal point. It might omit +// trailing '0's. If the input number is too small then no digits at all are +// generated (ex.: 2 fixed digits for 0.00001). +// +// Input verifies: 1 <= (numerator + delta) / denominator < 10. +static void BignumToFixed(int requested_digits, int* decimal_point, + Bignum* numerator, Bignum* denominator, + Vector buffer, int* length) { + // Note that we have to look at more than just the requested_digits, since + // a number could be rounded up. Example: v=0.5 with requested_digits=0. + // Even though the power of v equals 0 we can't just stop here. + if (-(*decimal_point) > requested_digits) { + // The number is definitively too small. + // Ex: 0.001 with requested_digits == 1. + // Set decimal-point to -requested_digits. This is what Gay does. + // Note that it should not have any effect anyways since the string is + // empty. + *decimal_point = -requested_digits; + *length = 0; + return; + } else if (-(*decimal_point) == requested_digits) { + // We only need to verify if the number rounds down or up. + // Ex: 0.04 and 0.06 with requested_digits == 1. + DOUBLE_CONVERSION_ASSERT(*decimal_point == -requested_digits); + // Initially the fraction lies in range (1, 10]. Multiply the denominator + // by 10 so that we can compare more easily. + denominator->Times10(); + if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) { + // If the fraction is >= 0.5 then we have to include the rounded + // digit. + buffer[0] = '1'; + *length = 1; + (*decimal_point)++; + } else { + // Note that we caught most of similar cases earlier. + *length = 0; + } + return; + } else { + // The requested digits correspond to the digits after the point. + // The variable 'needed_digits' includes the digits before the point. + int needed_digits = (*decimal_point) + requested_digits; + GenerateCountedDigits(needed_digits, decimal_point, numerator, denominator, + buffer, length); + } +} + +// Returns an estimation of k such that 10^(k-1) <= v < 10^k where +// v = f * 2^exponent and 2^52 <= f < 2^53. +// v is hence a normalized double with the given exponent. The output is an +// approximation for the exponent of the decimal approimation .digits * 10^k. +// +// The result might undershoot by 1 in which case 10^k <= v < 10^k+1. +// Note: this property holds for v's upper boundary m+ too. +// 10^k <= m+ < 10^k+1. +// (see explanation below). +// +// Examples: +// EstimatePower(0) => 16 +// EstimatePower(-52) => 0 +// +// Note: e >= 0 => EstimatedPower(e) > 0. No similar claim can be made for e<0. +static int EstimatePower(int exponent) { + // This function estimates log10 of v where v = f*2^e (with e == exponent). + // Note that 10^floor(log10(v)) <= v, but v <= 10^ceil(log10(v)). + // Note that f is bounded by its container size. Let p = 53 (the double's + // significand size). Then 2^(p-1) <= f < 2^p. + // + // Given that log10(v) == log2(v)/log2(10) and e+(len(f)-1) is quite close + // to log2(v) the function is simplified to (e+(len(f)-1)/log2(10)). + // The computed number undershoots by less than 0.631 (when we compute log3 + // and not log10). + // + // Optimization: since we only need an approximated result this computation + // can be performed on 64 bit integers. On x86/x64 architecture the speedup is + // not really measurable, though. + // + // Since we want to avoid overshooting we decrement by 1e10 so that + // floating-point imprecisions don't affect us. + // + // Explanation for v's boundary m+: the computation takes advantage of + // the fact that 2^(p-1) <= f < 2^p. Boundaries still satisfy this requirement + // (even for denormals where the delta can be much more important). + + const double k1Log10 = 0.30102999566398114; // 1/lg(10) + + // For doubles len(f) == 53 (don't forget the hidden bit). + const int kSignificandSize = Double::kSignificandSize; + double estimate = ceil((exponent + kSignificandSize - 1) * k1Log10 - 1e-10); + return static_cast(estimate); +} + +// See comments for InitialScaledStartValues. +static void InitialScaledStartValuesPositiveExponent( + uint64_t significand, int exponent, int estimated_power, + bool need_boundary_deltas, Bignum* numerator, Bignum* denominator, + Bignum* delta_minus, Bignum* delta_plus) { + // A positive exponent implies a positive power. + DOUBLE_CONVERSION_ASSERT(estimated_power >= 0); + // Since the estimated_power is positive we simply multiply the denominator + // by 10^estimated_power. + + // numerator = v. + numerator->AssignUInt64(significand); + numerator->ShiftLeft(exponent); + // denominator = 10^estimated_power. + denominator->AssignPowerUInt16(10, estimated_power); + + if (need_boundary_deltas) { + // Introduce a common denominator so that the deltas to the boundaries are + // integers. + denominator->ShiftLeft(1); + numerator->ShiftLeft(1); + // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common + // denominator (of 2) delta_plus equals 2^e. + delta_plus->AssignUInt16(1); + delta_plus->ShiftLeft(exponent); + // Same for delta_minus. The adjustments if f == 2^p-1 are done later. + delta_minus->AssignUInt16(1); + delta_minus->ShiftLeft(exponent); + } +} + +// See comments for InitialScaledStartValues +static void InitialScaledStartValuesNegativeExponentPositivePower( + uint64_t significand, int exponent, int estimated_power, + bool need_boundary_deltas, Bignum* numerator, Bignum* denominator, + Bignum* delta_minus, Bignum* delta_plus) { + // v = f * 2^e with e < 0, and with estimated_power >= 0. + // This means that e is close to 0 (have a look at how estimated_power is + // computed). + + // numerator = significand + // since v = significand * 2^exponent this is equivalent to + // numerator = v * / 2^-exponent + numerator->AssignUInt64(significand); + // denominator = 10^estimated_power * 2^-exponent (with exponent < 0) + denominator->AssignPowerUInt16(10, estimated_power); + denominator->ShiftLeft(-exponent); + + if (need_boundary_deltas) { + // Introduce a common denominator so that the deltas to the boundaries are + // integers. + denominator->ShiftLeft(1); + numerator->ShiftLeft(1); + // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common + // denominator (of 2) delta_plus equals 2^e. + // Given that the denominator already includes v's exponent the distance + // to the boundaries is simply 1. + delta_plus->AssignUInt16(1); + // Same for delta_minus. The adjustments if f == 2^p-1 are done later. + delta_minus->AssignUInt16(1); + } +} + +// See comments for InitialScaledStartValues +static void InitialScaledStartValuesNegativeExponentNegativePower( + uint64_t significand, int exponent, int estimated_power, + bool need_boundary_deltas, Bignum* numerator, Bignum* denominator, + Bignum* delta_minus, Bignum* delta_plus) { + // Instead of multiplying the denominator with 10^estimated_power we + // multiply all values (numerator and deltas) by 10^-estimated_power. + + // Use numerator as temporary container for power_ten. + Bignum* power_ten = numerator; + power_ten->AssignPowerUInt16(10, -estimated_power); + + if (need_boundary_deltas) { + // Since power_ten == numerator we must make a copy of 10^estimated_power + // before we complete the computation of the numerator. + // delta_plus = delta_minus = 10^estimated_power + delta_plus->AssignBignum(*power_ten); + delta_minus->AssignBignum(*power_ten); + } + + // numerator = significand * 2 * 10^-estimated_power + // since v = significand * 2^exponent this is equivalent to + // numerator = v * 10^-estimated_power * 2 * 2^-exponent. + // Remember: numerator has been abused as power_ten. So no need to assign it + // to itself. + DOUBLE_CONVERSION_ASSERT(numerator == power_ten); + numerator->MultiplyByUInt64(significand); + + // denominator = 2 * 2^-exponent with exponent < 0. + denominator->AssignUInt16(1); + denominator->ShiftLeft(-exponent); + + if (need_boundary_deltas) { + // Introduce a common denominator so that the deltas to the boundaries are + // integers. + numerator->ShiftLeft(1); + denominator->ShiftLeft(1); + // With this shift the boundaries have their correct value, since + // delta_plus = 10^-estimated_power, and + // delta_minus = 10^-estimated_power. + // These assignments have been done earlier. + // The adjustments if f == 2^p-1 (lower boundary is closer) are done later. + } +} + +// Let v = significand * 2^exponent. +// Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator +// and denominator. The functions GenerateShortestDigits and +// GenerateCountedDigits will then convert this ratio to its decimal +// representation d, with the required accuracy. +// Then d * 10^estimated_power is the representation of v. +// (Note: the fraction and the estimated_power might get adjusted before +// generating the decimal representation.) +// +// The initial start values consist of: +// - a scaled numerator: s.t. numerator/denominator == v / 10^estimated_power. +// - a scaled (common) denominator. +// optionally (used by GenerateShortestDigits to decide if it has the shortest +// decimal converting back to v): +// - v - m-: the distance to the lower boundary. +// - m+ - v: the distance to the upper boundary. +// +// v, m+, m-, and therefore v - m- and m+ - v all share the same denominator. +// +// Let ep == estimated_power, then the returned values will satisfy: +// v / 10^ep = numerator / denominator. +// v's boundarys m- and m+: +// m- / 10^ep == v / 10^ep - delta_minus / denominator +// m+ / 10^ep == v / 10^ep + delta_plus / denominator +// Or in other words: +// m- == v - delta_minus * 10^ep / denominator; +// m+ == v + delta_plus * 10^ep / denominator; +// +// Since 10^(k-1) <= v < 10^k (with k == estimated_power) +// or 10^k <= v < 10^(k+1) +// we then have 0.1 <= numerator/denominator < 1 +// or 1 <= numerator/denominator < 10 +// +// It is then easy to kickstart the digit-generation routine. +// +// The boundary-deltas are only filled if the mode equals BIGNUM_DTOA_SHORTEST +// or BIGNUM_DTOA_SHORTEST_SINGLE. + +static void InitialScaledStartValues(uint64_t significand, int exponent, + bool lower_boundary_is_closer, + int estimated_power, + bool need_boundary_deltas, + Bignum* numerator, Bignum* denominator, + Bignum* delta_minus, Bignum* delta_plus) { + if (exponent >= 0) { + InitialScaledStartValuesPositiveExponent( + significand, exponent, estimated_power, need_boundary_deltas, numerator, + denominator, delta_minus, delta_plus); + } else if (estimated_power >= 0) { + InitialScaledStartValuesNegativeExponentPositivePower( + significand, exponent, estimated_power, need_boundary_deltas, numerator, + denominator, delta_minus, delta_plus); + } else { + InitialScaledStartValuesNegativeExponentNegativePower( + significand, exponent, estimated_power, need_boundary_deltas, numerator, + denominator, delta_minus, delta_plus); + } + + if (need_boundary_deltas && lower_boundary_is_closer) { + // The lower boundary is closer at half the distance of "normal" numbers. + // Increase the common denominator and adapt all but the delta_minus. + denominator->ShiftLeft(1); // *2 + numerator->ShiftLeft(1); // *2 + delta_plus->ShiftLeft(1); // *2 + } +} + +// This routine multiplies numerator/denominator so that its values lies in the +// range 1-10. That is after a call to this function we have: +// 1 <= (numerator + delta_plus) /denominator < 10. +// Let numerator the input before modification and numerator' the argument +// after modification, then the output-parameter decimal_point is such that +// numerator / denominator * 10^estimated_power == +// numerator' / denominator' * 10^(decimal_point - 1) +// In some cases estimated_power was too low, and this is already the case. We +// then simply adjust the power so that 10^(k-1) <= v < 10^k (with k == +// estimated_power) but do not touch the numerator or denominator. +// Otherwise the routine multiplies the numerator and the deltas by 10. +static void FixupMultiply10(int estimated_power, bool is_even, + int* decimal_point, Bignum* numerator, + Bignum* denominator, Bignum* delta_minus, + Bignum* delta_plus) { + bool in_range; + if (is_even) { + // For IEEE doubles half-way cases (in decimal system numbers ending with 5) + // are rounded to the closest floating-point number with even significand. + in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0; + } else { + in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0; + } + if (in_range) { + // Since numerator + delta_plus >= denominator we already have + // 1 <= numerator/denominator < 10. Simply update the estimated_power. + *decimal_point = estimated_power + 1; + } else { + *decimal_point = estimated_power; + numerator->Times10(); + if (Bignum::Equal(*delta_minus, *delta_plus)) { + delta_minus->Times10(); + delta_plus->AssignBignum(*delta_minus); + } else { + delta_minus->Times10(); + delta_plus->Times10(); + } + } +} + +} // namespace double_conversion diff --git a/third_party/double-conversion/bignum-dtoa.h b/third_party/double-conversion/bignum-dtoa.h new file mode 100644 index 00000000..34b96199 --- /dev/null +++ b/third_party/double-conversion/bignum-dtoa.h @@ -0,0 +1,84 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef DOUBLE_CONVERSION_BIGNUM_DTOA_H_ +#define DOUBLE_CONVERSION_BIGNUM_DTOA_H_ + +#include "utils.h" + +namespace double_conversion { + +enum BignumDtoaMode { + // Return the shortest correct representation. + // For example the output of 0.299999999999999988897 is (the less accurate but + // correct) 0.3. + BIGNUM_DTOA_SHORTEST, + // Same as BIGNUM_DTOA_SHORTEST but for single-precision floats. + BIGNUM_DTOA_SHORTEST_SINGLE, + // Return a fixed number of digits after the decimal point. + // For instance fixed(0.1, 4) becomes 0.1000 + // If the input number is big, the output will be big. + BIGNUM_DTOA_FIXED, + // Return a fixed number of digits, no matter what the exponent is. + BIGNUM_DTOA_PRECISION +}; + +// Converts the given double 'v' to ascii. +// The result should be interpreted as buffer * 10^(point-length). +// The buffer will be null-terminated. +// +// The input v must be > 0 and different from NaN, and Infinity. +// +// The output depends on the given mode: +// - SHORTEST: produce the least amount of digits for which the internal +// identity requirement is still satisfied. If the digits are printed +// (together with the correct exponent) then reading this number will give +// 'v' again. The buffer will choose the representation that is closest to +// 'v'. If there are two at the same distance, than the number is round up. +// In this mode the 'requested_digits' parameter is ignored. +// - FIXED: produces digits necessary to print a given number with +// 'requested_digits' digits after the decimal point. The produced digits +// might be too short in which case the caller has to fill the gaps with '0's. +// Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2. +// Halfway cases are rounded up. The call toFixed(0.15, 2) thus returns +// buffer="2", point=0. +// Note: the length of the returned buffer has no meaning wrt the significance +// of its digits. That is, just because it contains '0's does not mean that +// any other digit would not satisfy the internal identity requirement. +// - PRECISION: produces 'requested_digits' where the first digit is not '0'. +// Even though the length of produced digits usually equals +// 'requested_digits', the function is allowed to return fewer digits, in +// which case the caller has to fill the missing digits with '0's. +// Halfway cases are again rounded up. +// 'BignumDtoa' expects the given buffer to be big enough to hold all digits +// and a terminating null-character. +void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits, + Vector buffer, int* length, int* point); + +} // namespace double_conversion + +#endif // DOUBLE_CONVERSION_BIGNUM_DTOA_H_ diff --git a/third_party/double-conversion/bignum.cc b/third_party/double-conversion/bignum.cc new file mode 100644 index 00000000..2b3a8a26 --- /dev/null +++ b/third_party/double-conversion/bignum.cc @@ -0,0 +1,775 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "libc/macros.h" +#include "third_party/double-conversion/bignum.h" +#include "third_party/double-conversion/utils.h" + +asm(".ident\t\"\\n\\n\ +double-conversion (BSD-3)\\n\ +Copyright 2010 the V8 project authors\""); +asm(".include \"libc/disclaimer.inc\""); + +namespace double_conversion { + +Bignum::Chunk& Bignum::RawBigit(const int index) { + DOUBLE_CONVERSION_ASSERT(static_cast(index) < kBigitCapacity); + return bigits_buffer_[index]; +} + +const Bignum::Chunk& Bignum::RawBigit(const int index) const { + DOUBLE_CONVERSION_ASSERT(static_cast(index) < kBigitCapacity); + return bigits_buffer_[index]; +} + +template +static int BitSize(const S value) { + (void)value; // Mark variable as used. + return 8 * sizeof(value); +} + +// Guaranteed to lie in one Bigit. +void Bignum::AssignUInt16(const uint16_t value) { + DOUBLE_CONVERSION_ASSERT(kBigitSize >= BitSize(value)); + Zero(); + if (value > 0) { + RawBigit(0) = value; + used_bigits_ = 1; + } +} + +void Bignum::AssignUInt64(uint64_t value) { + Zero(); + for (int i = 0; value > 0; ++i) { + RawBigit(i) = value & kBigitMask; + value >>= kBigitSize; + ++used_bigits_; + } +} + +void Bignum::AssignBignum(const Bignum& other) { + exponent_ = other.exponent_; + for (int i = 0; i < other.used_bigits_; ++i) { + RawBigit(i) = other.RawBigit(i); + } + used_bigits_ = other.used_bigits_; +} + +static uint64_t ReadUInt64(const Vector buffer, const int from, + const int digits_to_read) { + uint64_t result = 0; + for (int i = from; i < from + digits_to_read; ++i) { + const int digit = buffer[i] - '0'; + DOUBLE_CONVERSION_ASSERT(0 <= digit && digit <= 9); + result = result * 10 + digit; + } + return result; +} + +void Bignum::AssignDecimalString(const Vector value) { + // 2^64 = 18446744073709551616 > 10^19 + static const int kMaxUint64DecimalDigits = 19; + Zero(); + int length = value.length(); + unsigned pos = 0; + // Let's just say that each digit needs 4 bits. + while (length >= kMaxUint64DecimalDigits) { + const uint64_t digits = ReadUInt64(value, pos, kMaxUint64DecimalDigits); + pos += kMaxUint64DecimalDigits; + length -= kMaxUint64DecimalDigits; + MultiplyByPowerOfTen(kMaxUint64DecimalDigits); + AddUInt64(digits); + } + const uint64_t digits = ReadUInt64(value, pos, length); + MultiplyByPowerOfTen(length); + AddUInt64(digits); + Clamp(); +} + +static uint64_t HexCharValue(const int c) { + if ('0' <= c && c <= '9') { + return c - '0'; + } + if ('a' <= c && c <= 'f') { + return 10 + c - 'a'; + } + DOUBLE_CONVERSION_ASSERT('A' <= c && c <= 'F'); + return 10 + c - 'A'; +} + +// Unlike AssignDecimalString(), this function is "only" used +// for unit-tests and therefore not performance critical. +void Bignum::AssignHexString(Vector value) { + Zero(); + // Required capacity could be reduced by ignoring leading zeros. + EnsureCapacity(((value.length() * 4) + kBigitSize - 1) / kBigitSize); + DOUBLE_CONVERSION_ASSERT(sizeof(uint64_t) * 8 >= + kBigitSize + 4); // TODO: static_assert + // Accumulates converted hex digits until at least kBigitSize bits. + // Works with non-factor-of-four kBigitSizes. + uint64_t tmp = 0; // Accumulates converted hex digits until at least + for (int cnt = 0; !value.is_empty(); value.pop_back()) { + tmp |= (HexCharValue(value.last()) << cnt); + if ((cnt += 4) >= kBigitSize) { + RawBigit(used_bigits_++) = (tmp & kBigitMask); + cnt -= kBigitSize; + tmp >>= kBigitSize; + } + } + if (tmp > 0) { + RawBigit(used_bigits_++) = tmp; + } + Clamp(); +} + +void Bignum::AddUInt64(const uint64_t operand) { + if (operand == 0) { + return; + } + Bignum other; + other.AssignUInt64(operand); + AddBignum(other); +} + +void Bignum::AddBignum(const Bignum& other) { + DOUBLE_CONVERSION_ASSERT(IsClamped()); + DOUBLE_CONVERSION_ASSERT(other.IsClamped()); + + // If this has a greater exponent than other append zero-bigits to this. + // After this call exponent_ <= other.exponent_. + Align(other); + + // There are two possibilities: + // aaaaaaaaaaa 0000 (where the 0s represent a's exponent) + // bbbbb 00000000 + // ---------------- + // ccccccccccc 0000 + // or + // aaaaaaaaaa 0000 + // bbbbbbbbb 0000000 + // ----------------- + // cccccccccccc 0000 + // In both cases we might need a carry bigit. + + EnsureCapacity(1 + MAX(BigitLength(), other.BigitLength()) - exponent_); + Chunk carry = 0; + int bigit_pos = other.exponent_ - exponent_; + DOUBLE_CONVERSION_ASSERT(bigit_pos >= 0); + for (int i = used_bigits_; i < bigit_pos; ++i) { + RawBigit(i) = 0; + } + for (int i = 0; i < other.used_bigits_; ++i) { + const Chunk my = (bigit_pos < used_bigits_) ? RawBigit(bigit_pos) : 0; + const Chunk sum = my + other.RawBigit(i) + carry; + RawBigit(bigit_pos) = sum & kBigitMask; + carry = sum >> kBigitSize; + ++bigit_pos; + } + while (carry != 0) { + const Chunk my = (bigit_pos < used_bigits_) ? RawBigit(bigit_pos) : 0; + const Chunk sum = my + carry; + RawBigit(bigit_pos) = sum & kBigitMask; + carry = sum >> kBigitSize; + ++bigit_pos; + } + used_bigits_ = MAX(bigit_pos, static_cast(used_bigits_)); + DOUBLE_CONVERSION_ASSERT(IsClamped()); +} + +void Bignum::SubtractBignum(const Bignum& other) { + DOUBLE_CONVERSION_ASSERT(IsClamped()); + DOUBLE_CONVERSION_ASSERT(other.IsClamped()); + // We require this to be bigger than other. + DOUBLE_CONVERSION_ASSERT(LessEqual(other, *this)); + + Align(other); + + const int offset = other.exponent_ - exponent_; + Chunk borrow = 0; + int i; + for (i = 0; i < other.used_bigits_; ++i) { + DOUBLE_CONVERSION_ASSERT((borrow == 0) || (borrow == 1)); + const Chunk difference = RawBigit(i + offset) - other.RawBigit(i) - borrow; + RawBigit(i + offset) = difference & kBigitMask; + borrow = difference >> (kChunkSize - 1); + } + while (borrow != 0) { + const Chunk difference = RawBigit(i + offset) - borrow; + RawBigit(i + offset) = difference & kBigitMask; + borrow = difference >> (kChunkSize - 1); + ++i; + } + Clamp(); +} + +void Bignum::ShiftLeft(const int shift_amount) { + if (used_bigits_ == 0) { + return; + } + exponent_ += (shift_amount / kBigitSize); + const int local_shift = shift_amount % kBigitSize; + EnsureCapacity(used_bigits_ + 1); + BigitsShiftLeft(local_shift); +} + +void Bignum::MultiplyByUInt32(const uint32_t factor) { + if (factor == 1) { + return; + } + if (factor == 0) { + Zero(); + return; + } + if (used_bigits_ == 0) { + return; + } + // The product of a bigit with the factor is of size kBigitSize + 32. + // Assert that this number + 1 (for the carry) fits into double chunk. + DOUBLE_CONVERSION_ASSERT(kDoubleChunkSize >= kBigitSize + 32 + 1); + DoubleChunk carry = 0; + for (int i = 0; i < used_bigits_; ++i) { + const DoubleChunk product = + static_cast(factor) * RawBigit(i) + carry; + RawBigit(i) = static_cast(product & kBigitMask); + carry = (product >> kBigitSize); + } + while (carry != 0) { + EnsureCapacity(used_bigits_ + 1); + RawBigit(used_bigits_) = carry & kBigitMask; + used_bigits_++; + carry >>= kBigitSize; + } +} + +void Bignum::MultiplyByUInt64(const uint64_t factor) { + if (factor == 1) { + return; + } + if (factor == 0) { + Zero(); + return; + } + if (used_bigits_ == 0) { + return; + } + DOUBLE_CONVERSION_ASSERT(kBigitSize < 32); + uint64_t carry = 0; + const uint64_t low = factor & 0xFFFFFFFF; + const uint64_t high = factor >> 32; + for (int i = 0; i < used_bigits_; ++i) { + const uint64_t product_low = low * RawBigit(i); + const uint64_t product_high = high * RawBigit(i); + const uint64_t tmp = (carry & kBigitMask) + product_low; + RawBigit(i) = tmp & kBigitMask; + carry = (carry >> kBigitSize) + (tmp >> kBigitSize) + + (product_high << (32 - kBigitSize)); + } + while (carry != 0) { + EnsureCapacity(used_bigits_ + 1); + RawBigit(used_bigits_) = carry & kBigitMask; + used_bigits_++; + carry >>= kBigitSize; + } +} + +void Bignum::MultiplyByPowerOfTen(const int exponent) { + static const uint64_t kFive27 = + DOUBLE_CONVERSION_UINT64_2PART_C(0x6765c793, fa10079d); + static const uint16_t kFive1 = 5; + static const uint16_t kFive2 = kFive1 * 5; + static const uint16_t kFive3 = kFive2 * 5; + static const uint16_t kFive4 = kFive3 * 5; + static const uint16_t kFive5 = kFive4 * 5; + static const uint16_t kFive6 = kFive5 * 5; + static const uint32_t kFive7 = kFive6 * 5; + static const uint32_t kFive8 = kFive7 * 5; + static const uint32_t kFive9 = kFive8 * 5; + static const uint32_t kFive10 = kFive9 * 5; + static const uint32_t kFive11 = kFive10 * 5; + static const uint32_t kFive12 = kFive11 * 5; + static const uint32_t kFive13 = kFive12 * 5; + static const uint32_t kFive1_to_12[] = {kFive1, kFive2, kFive3, kFive4, + kFive5, kFive6, kFive7, kFive8, + kFive9, kFive10, kFive11, kFive12}; + + DOUBLE_CONVERSION_ASSERT(exponent >= 0); + + if (exponent == 0) { + return; + } + if (used_bigits_ == 0) { + return; + } + // We shift by exponent at the end just before returning. + int remaining_exponent = exponent; + while (remaining_exponent >= 27) { + MultiplyByUInt64(kFive27); + remaining_exponent -= 27; + } + while (remaining_exponent >= 13) { + MultiplyByUInt32(kFive13); + remaining_exponent -= 13; + } + if (remaining_exponent > 0) { + MultiplyByUInt32(kFive1_to_12[remaining_exponent - 1]); + } + ShiftLeft(exponent); +} + +void Bignum::Square() { + DOUBLE_CONVERSION_ASSERT(IsClamped()); + const int product_length = 2 * used_bigits_; + EnsureCapacity(product_length); + + // Comba multiplication: compute each column separately. + // Example: r = a2a1a0 * b2b1b0. + // r = 1 * a0b0 + + // 10 * (a1b0 + a0b1) + + // 100 * (a2b0 + a1b1 + a0b2) + + // 1000 * (a2b1 + a1b2) + + // 10000 * a2b2 + // + // In the worst case we have to accumulate nb-digits products of digit*digit. + // + // Assert that the additional number of bits in a DoubleChunk are enough to + // sum up used_digits of Bigit*Bigit. + if ((1 << (2 * (kChunkSize - kBigitSize))) <= used_bigits_) { + DOUBLE_CONVERSION_UNIMPLEMENTED(); + } + DoubleChunk accumulator = 0; + // First shift the digits so we don't overwrite them. + const int copy_offset = used_bigits_; + for (int i = 0; i < used_bigits_; ++i) { + RawBigit(copy_offset + i) = RawBigit(i); + } + // We have two loops to avoid some 'if's in the loop. + for (int i = 0; i < used_bigits_; ++i) { + // Process temporary digit i with power i. + // The sum of the two indices must be equal to i. + int bigit_index1 = i; + int bigit_index2 = 0; + // Sum all of the sub-products. + while (bigit_index1 >= 0) { + const Chunk chunk1 = RawBigit(copy_offset + bigit_index1); + const Chunk chunk2 = RawBigit(copy_offset + bigit_index2); + accumulator += static_cast(chunk1) * chunk2; + bigit_index1--; + bigit_index2++; + } + RawBigit(i) = static_cast(accumulator) & kBigitMask; + accumulator >>= kBigitSize; + } + for (int i = used_bigits_; i < product_length; ++i) { + int bigit_index1 = used_bigits_ - 1; + int bigit_index2 = i - bigit_index1; + // Invariant: sum of both indices is again equal to i. + // Inner loop runs 0 times on last iteration, emptying accumulator. + while (bigit_index2 < used_bigits_) { + const Chunk chunk1 = RawBigit(copy_offset + bigit_index1); + const Chunk chunk2 = RawBigit(copy_offset + bigit_index2); + accumulator += static_cast(chunk1) * chunk2; + bigit_index1--; + bigit_index2++; + } + // The overwritten RawBigit(i) will never be read in further loop + // iterations, because bigit_index1 and bigit_index2 are always greater than + // i - used_bigits_. + RawBigit(i) = static_cast(accumulator) & kBigitMask; + accumulator >>= kBigitSize; + } + // Since the result was guaranteed to lie inside the number the + // accumulator must be 0 now. + DOUBLE_CONVERSION_ASSERT(accumulator == 0); + + // Don't forget to update the used_digits and the exponent. + used_bigits_ = product_length; + exponent_ *= 2; + Clamp(); +} + +void Bignum::AssignPowerUInt16(uint16_t base, const int power_exponent) { + DOUBLE_CONVERSION_ASSERT(base != 0); + DOUBLE_CONVERSION_ASSERT(power_exponent >= 0); + if (power_exponent == 0) { + AssignUInt16(1); + return; + } + Zero(); + int shifts = 0; + // We expect base to be in range 2-32, and most often to be 10. + // It does not make much sense to implement different algorithms for counting + // the bits. + while ((base & 1) == 0) { + base >>= 1; + shifts++; + } + int bit_size = 0; + int tmp_base = base; + while (tmp_base != 0) { + tmp_base >>= 1; + bit_size++; + } + const int final_size = bit_size * power_exponent; + // 1 extra bigit for the shifting, and one for rounded final_size. + EnsureCapacity(final_size / kBigitSize + 2); + + // Left to Right exponentiation. + int mask = 1; + while (power_exponent >= mask) mask <<= 1; + + // The mask is now pointing to the bit above the most significant 1-bit of + // power_exponent. + // Get rid of first 1-bit; + mask >>= 2; + uint64_t this_value = base; + + bool delayed_multiplication = false; + const uint64_t max_32bits = 0xFFFFFFFF; + while (mask != 0 && this_value <= max_32bits) { + this_value = this_value * this_value; + // Verify that there is enough space in this_value to perform the + // multiplication. The first bit_size bits must be 0. + if ((power_exponent & mask) != 0) { + DOUBLE_CONVERSION_ASSERT(bit_size > 0); + const uint64_t base_bits_mask = + ~((static_cast(1) << (64 - bit_size)) - 1); + const bool high_bits_zero = (this_value & base_bits_mask) == 0; + if (high_bits_zero) { + this_value *= base; + } else { + delayed_multiplication = true; + } + } + mask >>= 1; + } + AssignUInt64(this_value); + if (delayed_multiplication) { + MultiplyByUInt32(base); + } + + // Now do the same thing as a bignum. + while (mask != 0) { + Square(); + if ((power_exponent & mask) != 0) { + MultiplyByUInt32(base); + } + mask >>= 1; + } + + // And finally add the saved shifts. + ShiftLeft(shifts * power_exponent); +} + +// Precondition: this/other < 16bit. +uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) { + DOUBLE_CONVERSION_ASSERT(IsClamped()); + DOUBLE_CONVERSION_ASSERT(other.IsClamped()); + DOUBLE_CONVERSION_ASSERT(other.used_bigits_ > 0); + + // Easy case: if we have less digits than the divisor than the result is 0. + // Note: this handles the case where this == 0, too. + if (BigitLength() < other.BigitLength()) { + return 0; + } + + Align(other); + + uint16_t result = 0; + + // Start by removing multiples of 'other' until both numbers have the same + // number of digits. + while (BigitLength() > other.BigitLength()) { + // This naive approach is extremely inefficient if `this` divided by other + // is big. This function is implemented for doubleToString where + // the result should be small (less than 10). + DOUBLE_CONVERSION_ASSERT(other.RawBigit(other.used_bigits_ - 1) >= + ((1 << kBigitSize) / 16)); + DOUBLE_CONVERSION_ASSERT(RawBigit(used_bigits_ - 1) < 0x10000); + // Remove the multiples of the first digit. + // Example this = 23 and other equals 9. -> Remove 2 multiples. + result += static_cast(RawBigit(used_bigits_ - 1)); + SubtractTimes(other, RawBigit(used_bigits_ - 1)); + } + + DOUBLE_CONVERSION_ASSERT(BigitLength() == other.BigitLength()); + + // Both bignums are at the same length now. + // Since other has more than 0 digits we know that the access to + // RawBigit(used_bigits_ - 1) is safe. + const Chunk this_bigit = RawBigit(used_bigits_ - 1); + const Chunk other_bigit = other.RawBigit(other.used_bigits_ - 1); + + if (other.used_bigits_ == 1) { + // Shortcut for easy (and common) case. + int quotient = this_bigit / other_bigit; + RawBigit(used_bigits_ - 1) = this_bigit - other_bigit * quotient; + DOUBLE_CONVERSION_ASSERT(quotient < 0x10000); + result += static_cast(quotient); + Clamp(); + return result; + } + + const int division_estimate = this_bigit / (other_bigit + 1); + DOUBLE_CONVERSION_ASSERT(division_estimate < 0x10000); + result += static_cast(division_estimate); + SubtractTimes(other, division_estimate); + + if (other_bigit * (division_estimate + 1) > this_bigit) { + // No need to even try to subtract. Even if other's remaining digits were 0 + // another subtraction would be too much. + return result; + } + + while (LessEqual(other, *this)) { + SubtractBignum(other); + result++; + } + return result; +} + +template +static int SizeInHexChars(S number) { + DOUBLE_CONVERSION_ASSERT(number > 0); + int result = 0; + while (number != 0) { + number >>= 4; + result++; + } + return result; +} + +static char HexCharOfValue(const int value) { + DOUBLE_CONVERSION_ASSERT(0 <= value && value <= 16); + if (value < 10) { + return static_cast(value + '0'); + } + return static_cast(value - 10 + 'A'); +} + +bool Bignum::ToHexString(char* buffer, const int buffer_size) const { + DOUBLE_CONVERSION_ASSERT(IsClamped()); + // Each bigit must be printable as separate hex-character. + DOUBLE_CONVERSION_ASSERT(kBigitSize % 4 == 0); + static const int kHexCharsPerBigit = kBigitSize / 4; + + if (used_bigits_ == 0) { + if (buffer_size < 2) { + return false; + } + buffer[0] = '0'; + buffer[1] = '\0'; + return true; + } + // We add 1 for the terminating '\0' character. + const int needed_chars = (BigitLength() - 1) * kHexCharsPerBigit + + SizeInHexChars(RawBigit(used_bigits_ - 1)) + 1; + if (needed_chars > buffer_size) { + return false; + } + int string_index = needed_chars - 1; + buffer[string_index--] = '\0'; + for (int i = 0; i < exponent_; ++i) { + for (int j = 0; j < kHexCharsPerBigit; ++j) { + buffer[string_index--] = '0'; + } + } + for (int i = 0; i < used_bigits_ - 1; ++i) { + Chunk current_bigit = RawBigit(i); + for (int j = 0; j < kHexCharsPerBigit; ++j) { + buffer[string_index--] = HexCharOfValue(current_bigit & 0xF); + current_bigit >>= 4; + } + } + // And finally the last bigit. + Chunk most_significant_bigit = RawBigit(used_bigits_ - 1); + while (most_significant_bigit != 0) { + buffer[string_index--] = HexCharOfValue(most_significant_bigit & 0xF); + most_significant_bigit >>= 4; + } + return true; +} + +Bignum::Chunk Bignum::BigitOrZero(const int index) const { + if (index >= BigitLength()) { + return 0; + } + if (index < exponent_) { + return 0; + } + return RawBigit(index - exponent_); +} + +int Bignum::Compare(const Bignum& a, const Bignum& b) { + DOUBLE_CONVERSION_ASSERT(a.IsClamped()); + DOUBLE_CONVERSION_ASSERT(b.IsClamped()); + const int bigit_length_a = a.BigitLength(); + const int bigit_length_b = b.BigitLength(); + if (bigit_length_a < bigit_length_b) { + return -1; + } + if (bigit_length_a > bigit_length_b) { + return +1; + } + for (int i = bigit_length_a - 1; i >= MIN(a.exponent_, b.exponent_); --i) { + const Chunk bigit_a = a.BigitOrZero(i); + const Chunk bigit_b = b.BigitOrZero(i); + if (bigit_a < bigit_b) { + return -1; + } + if (bigit_a > bigit_b) { + return +1; + } + // Otherwise they are equal up to this digit. Try the next digit. + } + return 0; +} + +int Bignum::PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c) { + DOUBLE_CONVERSION_ASSERT(a.IsClamped()); + DOUBLE_CONVERSION_ASSERT(b.IsClamped()); + DOUBLE_CONVERSION_ASSERT(c.IsClamped()); + if (a.BigitLength() < b.BigitLength()) { + return PlusCompare(b, a, c); + } + if (a.BigitLength() + 1 < c.BigitLength()) { + return -1; + } + if (a.BigitLength() > c.BigitLength()) { + return +1; + } + // The exponent encodes 0-bigits. So if there are more 0-digits in 'a' than + // 'b' has digits, then the bigit-length of 'a'+'b' must be equal to the one + // of 'a'. + if (a.exponent_ >= b.BigitLength() && a.BigitLength() < c.BigitLength()) { + return -1; + } + + Chunk borrow = 0; + // Starting at min_exponent all digits are == 0. So no need to compare them. + const int min_exponent = MIN(MIN(a.exponent_, b.exponent_), c.exponent_); + for (int i = c.BigitLength() - 1; i >= min_exponent; --i) { + const Chunk chunk_a = a.BigitOrZero(i); + const Chunk chunk_b = b.BigitOrZero(i); + const Chunk chunk_c = c.BigitOrZero(i); + const Chunk sum = chunk_a + chunk_b; + if (sum > chunk_c + borrow) { + return +1; + } else { + borrow = chunk_c + borrow - sum; + if (borrow > 1) { + return -1; + } + borrow <<= kBigitSize; + } + } + if (borrow == 0) { + return 0; + } + return -1; +} + +void Bignum::Clamp() { + while (used_bigits_ > 0 && RawBigit(used_bigits_ - 1) == 0) { + used_bigits_--; + } + if (used_bigits_ == 0) { + // Zero. + exponent_ = 0; + } +} + +void Bignum::Align(const Bignum& other) { + if (exponent_ > other.exponent_) { + // If "X" represents a "hidden" bigit (by the exponent) then we are in the + // following case (a == this, b == other): + // a: aaaaaaXXXX or a: aaaaaXXX + // b: bbbbbbX b: bbbbbbbbXX + // We replace some of the hidden digits (X) of a with 0 digits. + // a: aaaaaa000X or a: aaaaa0XX + const int zero_bigits = exponent_ - other.exponent_; + EnsureCapacity(used_bigits_ + zero_bigits); + for (int i = used_bigits_ - 1; i >= 0; --i) { + RawBigit(i + zero_bigits) = RawBigit(i); + } + for (int i = 0; i < zero_bigits; ++i) { + RawBigit(i) = 0; + } + used_bigits_ += zero_bigits; + exponent_ -= zero_bigits; + + DOUBLE_CONVERSION_ASSERT(used_bigits_ >= 0); + DOUBLE_CONVERSION_ASSERT(exponent_ >= 0); + } +} + +void Bignum::BigitsShiftLeft(const int shift_amount) { + DOUBLE_CONVERSION_ASSERT(shift_amount < kBigitSize); + DOUBLE_CONVERSION_ASSERT(shift_amount >= 0); + Chunk carry = 0; + for (int i = 0; i < used_bigits_; ++i) { + const Chunk new_carry = RawBigit(i) >> (kBigitSize - shift_amount); + RawBigit(i) = ((RawBigit(i) << shift_amount) + carry) & kBigitMask; + carry = new_carry; + } + if (carry != 0) { + RawBigit(used_bigits_) = carry; + used_bigits_++; + } +} + +void Bignum::SubtractTimes(const Bignum& other, const int factor) { + DOUBLE_CONVERSION_ASSERT(exponent_ <= other.exponent_); + if (factor < 3) { + for (int i = 0; i < factor; ++i) { + SubtractBignum(other); + } + return; + } + Chunk borrow = 0; + const int exponent_diff = other.exponent_ - exponent_; + for (int i = 0; i < other.used_bigits_; ++i) { + const DoubleChunk product = + static_cast(factor) * other.RawBigit(i); + const DoubleChunk remove = borrow + product; + const Chunk difference = + RawBigit(i + exponent_diff) - (remove & kBigitMask); + RawBigit(i + exponent_diff) = difference & kBigitMask; + borrow = static_cast((difference >> (kChunkSize - 1)) + + (remove >> kBigitSize)); + } + for (int i = other.used_bigits_ + exponent_diff; i < used_bigits_; ++i) { + if (borrow == 0) { + return; + } + const Chunk difference = RawBigit(i) - borrow; + RawBigit(i) = difference & kBigitMask; + borrow = difference >> (kChunkSize - 1); + } + Clamp(); +} + +} // namespace double_conversion diff --git a/third_party/double-conversion/bignum.h b/third_party/double-conversion/bignum.h new file mode 100644 index 00000000..ac6e712f --- /dev/null +++ b/third_party/double-conversion/bignum.h @@ -0,0 +1,153 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef DOUBLE_CONVERSION_BIGNUM_H_ +#define DOUBLE_CONVERSION_BIGNUM_H_ + +#include "third_party/double-conversion/utils.h" + +namespace double_conversion { + +class Bignum { + public: + // 3584 = 128 * 28. We can represent 2^3584 > 10^1000 accurately. + // This bignum can encode much bigger numbers, since it contains an + // exponent. + static const int kMaxSignificantBits = 3584; + + Bignum() : used_bigits_(0), exponent_(0) {} + + void AssignUInt16(const uint16_t value); + void AssignUInt64(uint64_t value); + void AssignBignum(const Bignum& other); + + void AssignDecimalString(const Vector value); + void AssignHexString(const Vector value); + + void AssignPowerUInt16(uint16_t base, const int exponent); + + void AddUInt64(const uint64_t operand); + void AddBignum(const Bignum& other); + // Precondition: this >= other. + void SubtractBignum(const Bignum& other); + + void Square(); + void ShiftLeft(const int shift_amount); + void MultiplyByUInt32(const uint32_t factor); + void MultiplyByUInt64(const uint64_t factor); + void MultiplyByPowerOfTen(const int exponent); + void Times10() { return MultiplyByUInt32(10); } + // Pseudocode: + // int result = this / other; + // this = this % other; + // In the worst case this function is in O(this/other). + uint16_t DivideModuloIntBignum(const Bignum& other); + + bool ToHexString(char* buffer, const int buffer_size) const; + + // Returns + // -1 if a < b, + // 0 if a == b, and + // +1 if a > b. + static int Compare(const Bignum& a, const Bignum& b); + static bool Equal(const Bignum& a, const Bignum& b) { + return Compare(a, b) == 0; + } + static bool LessEqual(const Bignum& a, const Bignum& b) { + return Compare(a, b) <= 0; + } + static bool Less(const Bignum& a, const Bignum& b) { + return Compare(a, b) < 0; + } + // Returns Compare(a + b, c); + static int PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c); + // Returns a + b == c + static bool PlusEqual(const Bignum& a, const Bignum& b, const Bignum& c) { + return PlusCompare(a, b, c) == 0; + } + // Returns a + b <= c + static bool PlusLessEqual(const Bignum& a, const Bignum& b, const Bignum& c) { + return PlusCompare(a, b, c) <= 0; + } + // Returns a + b < c + static bool PlusLess(const Bignum& a, const Bignum& b, const Bignum& c) { + return PlusCompare(a, b, c) < 0; + } + + private: + typedef uint32_t Chunk; + typedef uint64_t DoubleChunk; + + static const int kChunkSize = sizeof(Chunk) * 8; + static const int kDoubleChunkSize = sizeof(DoubleChunk) * 8; + // With bigit size of 28 we loose some bits, but a double still fits easily + // into two chunks, and more importantly we can use the Comba multiplication. + static const int kBigitSize = 28; + static const Chunk kBigitMask = (1 << kBigitSize) - 1; + // Every instance allocates kBigitLength chunks on the stack. Bignums cannot + // grow. There are no checks if the stack-allocated space is sufficient. + static const int kBigitCapacity = kMaxSignificantBits / kBigitSize; + + static void EnsureCapacity(const int size) { + if (size > kBigitCapacity) { + DOUBLE_CONVERSION_UNREACHABLE(); + } + } + void Align(const Bignum& other); + void Clamp(); + bool IsClamped() const { + return used_bigits_ == 0 || RawBigit(used_bigits_ - 1) != 0; + } + void Zero() { + used_bigits_ = 0; + exponent_ = 0; + } + // Requires this to have enough capacity (no tests done). + // Updates used_bigits_ if necessary. + // shift_amount must be < kBigitSize. + void BigitsShiftLeft(const int shift_amount); + // BigitLength includes the "hidden" bigits encoded in the exponent. + int BigitLength() const { return used_bigits_ + exponent_; } + Chunk& RawBigit(const int index); + const Chunk& RawBigit(const int index) const; + Chunk BigitOrZero(const int index) const; + void SubtractTimes(const Bignum& other, const int factor); + + // The Bignum's value is value(bigits_buffer_) * 2^(exponent_ * kBigitSize), + // where the value of the buffer consists of the lower kBigitSize bits of + // the first used_bigits_ Chunks in bigits_buffer_, first chunk has lowest + // significant bits. + int16_t used_bigits_; + int16_t exponent_; + Chunk bigits_buffer_[kBigitCapacity]; + + DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(Bignum); +}; + +} // namespace double_conversion + +#endif // DOUBLE_CONVERSION_BIGNUM_H_ diff --git a/third_party/double-conversion/diy-fp.h b/third_party/double-conversion/diy-fp.h new file mode 100644 index 00000000..a7e64799 --- /dev/null +++ b/third_party/double-conversion/diy-fp.h @@ -0,0 +1,140 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef DOUBLE_CONVERSION_DIY_FP_H_ +#define DOUBLE_CONVERSION_DIY_FP_H_ + +#include "third_party/double-conversion/utils.h" + +namespace double_conversion { + +// This "Do It Yourself Floating Point" class implements a floating-point number +// with a uint64 significand and an int exponent. Normalized DiyFp numbers will +// have the most significant bit of the significand set. +// Multiplication and Subtraction do not normalize their results. +// DiyFp store only non-negative numbers and are not designed to contain special +// doubles (NaN and Infinity). +class DiyFp { + public: + static const int kSignificandSize = 64; + + DiyFp() : f_(0), e_(0) {} + DiyFp(const uint64_t significand, const int32_t exponent) + : f_(significand), e_(exponent) {} + + // this -= other. + // The exponents of both numbers must be the same and the significand of this + // must be greater or equal than the significand of other. + // The result will not be normalized. + void Subtract(const DiyFp& other) { + DOUBLE_CONVERSION_ASSERT(e_ == other.e_); + DOUBLE_CONVERSION_ASSERT(f_ >= other.f_); + f_ -= other.f_; + } + + // Returns a - b. + // The exponents of both numbers must be the same and a must be greater + // or equal than b. The result will not be normalized. + static DiyFp Minus(const DiyFp& a, const DiyFp& b) { + DiyFp result = a; + result.Subtract(b); + return result; + } + + // this *= other. + void Multiply(const DiyFp& other) { + // Simply "emulates" a 128 bit multiplication. + // However: the resulting number only contains 64 bits. The least + // significant 64 bits are only used for rounding the most significant 64 + // bits. + const uint64_t kM32 = 0xFFFFFFFFU; + const uint64_t a = f_ >> 32; + const uint64_t b = f_ & kM32; + const uint64_t c = other.f_ >> 32; + const uint64_t d = other.f_ & kM32; + const uint64_t ac = a * c; + const uint64_t bc = b * c; + const uint64_t ad = a * d; + const uint64_t bd = b * d; + // By adding 1U << 31 to tmp we round the final result. + // Halfway cases will be rounded up. + const uint64_t tmp = (bd >> 32) + (ad & kM32) + (bc & kM32) + (1U << 31); + e_ += other.e_ + 64; + f_ = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32); + } + + // returns a * b; + static DiyFp Times(const DiyFp& a, const DiyFp& b) { + DiyFp result = a; + result.Multiply(b); + return result; + } + + void Normalize() { + DOUBLE_CONVERSION_ASSERT(f_ != 0); + uint64_t significand = f_; + int32_t exponent = e_; + + // This method is mainly called for normalizing boundaries. In general, + // boundaries need to be shifted by 10 bits, and we optimize for this case. + const uint64_t k10MSBits = + DOUBLE_CONVERSION_UINT64_2PART_C(0xFFC00000, 00000000); + while ((significand & k10MSBits) == 0) { + significand <<= 10; + exponent -= 10; + } + while ((significand & kUint64MSB) == 0) { + significand <<= 1; + exponent--; + } + f_ = significand; + e_ = exponent; + } + + static DiyFp Normalize(const DiyFp& a) { + DiyFp result = a; + result.Normalize(); + return result; + } + + uint64_t f() const { return f_; } + int32_t e() const { return e_; } + + void set_f(uint64_t new_value) { f_ = new_value; } + void set_e(int32_t new_value) { e_ = new_value; } + + private: + static const uint64_t kUint64MSB = + DOUBLE_CONVERSION_UINT64_2PART_C(0x80000000, 00000000); + + uint64_t f_; + int32_t e_; +}; + +} // namespace double_conversion + +#endif // DOUBLE_CONVERSION_DIY_FP_H_ diff --git a/third_party/double-conversion/double-conversion.mk b/third_party/double-conversion/double-conversion.mk new file mode 100644 index 00000000..b5fa1a34 --- /dev/null +++ b/third_party/double-conversion/double-conversion.mk @@ -0,0 +1,54 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += THIRD_PARTY_DOUBLE_CONVERSION + +THIRD_PARTY_DOUBLE_CONVERSION_ARTIFACTS += THIRD_PARTY_DOUBLE_CONVERSION_A +THIRD_PARTY_DOUBLE_CONVERSION = $(THIRD_PARTY_DOUBLE_CONVERSION_A_DEPS) $(THIRD_PARTY_DOUBLE_CONVERSION_A) +THIRD_PARTY_DOUBLE_CONVERSION_A = o/$(MODE)/third_party/double-conversion/double-conversion.a +THIRD_PARTY_DOUBLE_CONVERSION_A_FILES := $(wildcard third_party/double-conversion/*) +THIRD_PARTY_DOUBLE_CONVERSION_A_HDRS = $(filter %.h,$(THIRD_PARTY_DOUBLE_CONVERSION_A_FILES)) +THIRD_PARTY_DOUBLE_CONVERSION_A_SRCS_CC = $(filter %.cc,$(THIRD_PARTY_DOUBLE_CONVERSION_A_FILES)) + +THIRD_PARTY_DOUBLE_CONVERSION_A_SRCS = \ + $(THIRD_PARTY_DOUBLE_CONVERSION_A_SRCS_CC) + +THIRD_PARTY_DOUBLE_CONVERSION_A_OBJS = \ + $(THIRD_PARTY_DOUBLE_CONVERSION_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(THIRD_PARTY_DOUBLE_CONVERSION_A_SRCS_CC:%.cc=o/$(MODE)/%.o) + +THIRD_PARTY_DOUBLE_CONVERSION_A_CHECKS = \ + $(THIRD_PARTY_DOUBLE_CONVERSION_A).pkg \ + $(THIRD_PARTY_DOUBLE_CONVERSION_A_HDRS:%=o/$(MODE)/%.ok) + +THIRD_PARTY_DOUBLE_CONVERSION_A_DIRECTDEPS = \ + LIBC_STUBS + +THIRD_PARTY_DOUBLE_CONVERSION_A_DEPS := \ + $(call uniq,$(foreach x,$(THIRD_PARTY_DOUBLE_CONVERSION_A_DIRECTDEPS),$($(x)))) + +$(THIRD_PARTY_DOUBLE_CONVERSION_A): \ + third_party/double-conversion/ \ + $(THIRD_PARTY_DOUBLE_CONVERSION_A).pkg \ + $(THIRD_PARTY_DOUBLE_CONVERSION_A_OBJS) + +$(THIRD_PARTY_DOUBLE_CONVERSION_A).pkg: \ + $(THIRD_PARTY_DOUBLE_CONVERSION_A_OBJS) \ + $(foreach x,$(THIRD_PARTY_DOUBLE_CONVERSION_A_DIRECTDEPS),$($(x)_A).pkg) + +$(THIRD_PARTY_DOUBLE_CONVERSION_A_OBJS): \ + OVERRIDE_CXXFLAGS += \ + $(IEEE_MATH) \ + -fvisibility=hidden \ + -ffunction-sections \ + -fdata-sections + +THIRD_PARTY_DOUBLE_CONVERSION_LIBS = $(foreach x,$(THIRD_PARTY_DOUBLE_CONVERSION_ARTIFACTS),$($(x))) +THIRD_PARTY_DOUBLE_CONVERSION_SRCS = $(foreach x,$(THIRD_PARTY_DOUBLE_CONVERSION_ARTIFACTS),$($(x)_SRCS)) +THIRD_PARTY_DOUBLE_CONVERSION_HDRS = $(foreach x,$(THIRD_PARTY_DOUBLE_CONVERSION_ARTIFACTS),$($(x)_HDRS)) +THIRD_PARTY_DOUBLE_CONVERSION_CHECKS = $(foreach x,$(THIRD_PARTY_DOUBLE_CONVERSION_ARTIFACTS),$($(x)_CHECKS)) +THIRD_PARTY_DOUBLE_CONVERSION_OBJS = $(foreach x,$(THIRD_PARTY_DOUBLE_CONVERSION_ARTIFACTS),$($(x)_OBJS)) +$(THIRD_PARTY_DOUBLE_CONVERSION_OBJS): $(BUILD_FILES) third_party/double-conversion/double-conversion.mk + +.PHONY: o/$(MODE)/third_party/double-conversion +o/$(MODE)/third_party/double-conversion: $(THIRD_PARTY_DOUBLE_CONVERSION_CHECKS) diff --git a/third_party/double-conversion/ieee.h b/third_party/double-conversion/ieee.h new file mode 100644 index 00000000..c33742ff --- /dev/null +++ b/third_party/double-conversion/ieee.h @@ -0,0 +1,395 @@ +// Copyright 2012 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef DOUBLE_CONVERSION_DOUBLE_H_ +#define DOUBLE_CONVERSION_DOUBLE_H_ + +#include "third_party/double-conversion/diy-fp.h" + +namespace double_conversion { + +// We assume that doubles and uint64_t have the same endianness. +static uint64_t double_to_uint64(double d) { return BitCast(d); } +static double uint64_to_double(uint64_t d64) { return BitCast(d64); } +static uint32_t float_to_uint32(float f) { return BitCast(f); } +static float uint32_to_float(uint32_t d32) { return BitCast(d32); } + +// Helper functions for doubles. +class Double { + public: + static const uint64_t kSignMask = + DOUBLE_CONVERSION_UINT64_2PART_C(0x80000000, 00000000); + static const uint64_t kExponentMask = + DOUBLE_CONVERSION_UINT64_2PART_C(0x7FF00000, 00000000); + static const uint64_t kSignificandMask = + DOUBLE_CONVERSION_UINT64_2PART_C(0x000FFFFF, FFFFFFFF); + static const uint64_t kHiddenBit = + DOUBLE_CONVERSION_UINT64_2PART_C(0x00100000, 00000000); + static const int kPhysicalSignificandSize = 52; // Excludes the hidden bit. + static const int kSignificandSize = 53; + static const int kExponentBias = 0x3FF + kPhysicalSignificandSize; + static const int kMaxExponent = 0x7FF - kExponentBias; + + Double() : d64_(0) {} + explicit Double(double d) : d64_(double_to_uint64(d)) {} + explicit Double(uint64_t d64) : d64_(d64) {} + explicit Double(DiyFp diy_fp) : d64_(DiyFpToUint64(diy_fp)) {} + + // The value encoded by this Double must be greater or equal to +0.0. + // It must not be special (infinity, or NaN). + DiyFp AsDiyFp() const { + DOUBLE_CONVERSION_ASSERT(Sign() > 0); + DOUBLE_CONVERSION_ASSERT(!IsSpecial()); + return DiyFp(Significand(), Exponent()); + } + + // The value encoded by this Double must be strictly greater than 0. + DiyFp AsNormalizedDiyFp() const { + DOUBLE_CONVERSION_ASSERT(value() > 0.0); + uint64_t f = Significand(); + int e = Exponent(); + + // The current double could be a denormal. + while ((f & kHiddenBit) == 0) { + f <<= 1; + e--; + } + // Do the final shifts in one go. + f <<= DiyFp::kSignificandSize - kSignificandSize; + e -= DiyFp::kSignificandSize - kSignificandSize; + return DiyFp(f, e); + } + + // Returns the double's bit as uint64. + uint64_t AsUint64() const { return d64_; } + + // Returns the next greater double. Returns +infinity on input +infinity. + double NextDouble() const { + if (d64_ == kInfinity) return Double(kInfinity).value(); + if (Sign() < 0 && Significand() == 0) { + // -0.0 + return 0.0; + } + if (Sign() < 0) { + return Double(d64_ - 1).value(); + } else { + return Double(d64_ + 1).value(); + } + } + + double PreviousDouble() const { + if (d64_ == (kInfinity | kSignMask)) return -Infinity(); + if (Sign() < 0) { + return Double(d64_ + 1).value(); + } else { + if (Significand() == 0) return -0.0; + return Double(d64_ - 1).value(); + } + } + + int Exponent() const { + if (IsDenormal()) return kDenormalExponent; + + uint64_t d64 = AsUint64(); + int biased_e = + static_cast((d64 & kExponentMask) >> kPhysicalSignificandSize); + return biased_e - kExponentBias; + } + + uint64_t Significand() const { + uint64_t d64 = AsUint64(); + uint64_t significand = d64 & kSignificandMask; + if (!IsDenormal()) { + return significand + kHiddenBit; + } else { + return significand; + } + } + + // Returns true if the double is a denormal. + bool IsDenormal() const { + uint64_t d64 = AsUint64(); + return (d64 & kExponentMask) == 0; + } + + // We consider denormals not to be special. + // Hence only Infinity and NaN are special. + bool IsSpecial() const { + uint64_t d64 = AsUint64(); + return (d64 & kExponentMask) == kExponentMask; + } + + bool IsNan() const { + uint64_t d64 = AsUint64(); + return ((d64 & kExponentMask) == kExponentMask) && + ((d64 & kSignificandMask) != 0); + } + + bool IsInfinite() const { + uint64_t d64 = AsUint64(); + return ((d64 & kExponentMask) == kExponentMask) && + ((d64 & kSignificandMask) == 0); + } + + int Sign() const { + uint64_t d64 = AsUint64(); + return (d64 & kSignMask) == 0 ? 1 : -1; + } + + // Precondition: the value encoded by this Double must be greater or equal + // than +0.0. + DiyFp UpperBoundary() const { + DOUBLE_CONVERSION_ASSERT(Sign() > 0); + return DiyFp(Significand() * 2 + 1, Exponent() - 1); + } + + // Computes the two boundaries of this. + // The bigger boundary (m_plus) is normalized. The lower boundary has the same + // exponent as m_plus. + // Precondition: the value encoded by this Double must be greater than 0. + void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const { + DOUBLE_CONVERSION_ASSERT(value() > 0.0); + DiyFp v = this->AsDiyFp(); + DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1)); + DiyFp m_minus; + if (LowerBoundaryIsCloser()) { + m_minus = DiyFp((v.f() << 2) - 1, v.e() - 2); + } else { + m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1); + } + m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e())); + m_minus.set_e(m_plus.e()); + *out_m_plus = m_plus; + *out_m_minus = m_minus; + } + + bool LowerBoundaryIsCloser() const { + // The boundary is closer if the significand is of the form f == 2^p-1 then + // the lower boundary is closer. + // Think of v = 1000e10 and v- = 9999e9. + // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but + // at a distance of 1e8. + // The only exception is for the smallest normal: the largest denormal is + // at the same distance as its successor. + // Note: denormals have the same exponent as the smallest normals. + bool physical_significand_is_zero = ((AsUint64() & kSignificandMask) == 0); + return physical_significand_is_zero && (Exponent() != kDenormalExponent); + } + + double value() const { return uint64_to_double(d64_); } + + // Returns the significand size for a given order of magnitude. + // If v = f*2^e with 2^p-1 <= f <= 2^p then p+e is v's order of magnitude. + // This function returns the number of significant binary digits v will have + // once it's encoded into a double. In almost all cases this is equal to + // kSignificandSize. The only exceptions are denormals. They start with + // leading zeroes and their effective significand-size is hence smaller. + static int SignificandSizeForOrderOfMagnitude(int order) { + if (order >= (kDenormalExponent + kSignificandSize)) { + return kSignificandSize; + } + if (order <= kDenormalExponent) return 0; + return order - kDenormalExponent; + } + + static double Infinity() { return Double(kInfinity).value(); } + + static double NaN() { return Double(kNaN).value(); } + + private: + static const int kDenormalExponent = -kExponentBias + 1; + static const uint64_t kInfinity = + DOUBLE_CONVERSION_UINT64_2PART_C(0x7FF00000, 00000000); + static const uint64_t kNaN = + DOUBLE_CONVERSION_UINT64_2PART_C(0x7FF80000, 00000000); + + const uint64_t d64_; + + static uint64_t DiyFpToUint64(DiyFp diy_fp) { + uint64_t significand = diy_fp.f(); + int exponent = diy_fp.e(); + while (significand > kHiddenBit + kSignificandMask) { + significand >>= 1; + exponent++; + } + if (exponent >= kMaxExponent) { + return kInfinity; + } + if (exponent < kDenormalExponent) { + return 0; + } + while (exponent > kDenormalExponent && (significand & kHiddenBit) == 0) { + significand <<= 1; + exponent--; + } + uint64_t biased_exponent; + if (exponent == kDenormalExponent && (significand & kHiddenBit) == 0) { + biased_exponent = 0; + } else { + biased_exponent = static_cast(exponent + kExponentBias); + } + return (significand & kSignificandMask) | + (biased_exponent << kPhysicalSignificandSize); + } + + DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(Double); +}; + +class Single { + public: + static const uint32_t kSignMask = 0x80000000; + static const uint32_t kExponentMask = 0x7F800000; + static const uint32_t kSignificandMask = 0x007FFFFF; + static const uint32_t kHiddenBit = 0x00800000; + static const int kPhysicalSignificandSize = 23; // Excludes the hidden bit. + static const int kSignificandSize = 24; + + Single() : d32_(0) {} + explicit Single(float f) : d32_(float_to_uint32(f)) {} + explicit Single(uint32_t d32) : d32_(d32) {} + + // The value encoded by this Single must be greater or equal to +0.0. + // It must not be special (infinity, or NaN). + DiyFp AsDiyFp() const { + DOUBLE_CONVERSION_ASSERT(Sign() > 0); + DOUBLE_CONVERSION_ASSERT(!IsSpecial()); + return DiyFp(Significand(), Exponent()); + } + + // Returns the single's bit as uint64. + uint32_t AsUint32() const { return d32_; } + + int Exponent() const { + if (IsDenormal()) return kDenormalExponent; + + uint32_t d32 = AsUint32(); + int biased_e = + static_cast((d32 & kExponentMask) >> kPhysicalSignificandSize); + return biased_e - kExponentBias; + } + + uint32_t Significand() const { + uint32_t d32 = AsUint32(); + uint32_t significand = d32 & kSignificandMask; + if (!IsDenormal()) { + return significand + kHiddenBit; + } else { + return significand; + } + } + + // Returns true if the single is a denormal. + bool IsDenormal() const { + uint32_t d32 = AsUint32(); + return (d32 & kExponentMask) == 0; + } + + // We consider denormals not to be special. + // Hence only Infinity and NaN are special. + bool IsSpecial() const { + uint32_t d32 = AsUint32(); + return (d32 & kExponentMask) == kExponentMask; + } + + bool IsNan() const { + uint32_t d32 = AsUint32(); + return ((d32 & kExponentMask) == kExponentMask) && + ((d32 & kSignificandMask) != 0); + } + + bool IsInfinite() const { + uint32_t d32 = AsUint32(); + return ((d32 & kExponentMask) == kExponentMask) && + ((d32 & kSignificandMask) == 0); + } + + int Sign() const { + uint32_t d32 = AsUint32(); + return (d32 & kSignMask) == 0 ? 1 : -1; + } + + // Computes the two boundaries of this. + // The bigger boundary (m_plus) is normalized. The lower boundary has the same + // exponent as m_plus. + // Precondition: the value encoded by this Single must be greater than 0. + void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const { + DOUBLE_CONVERSION_ASSERT(value() > 0.0); + DiyFp v = this->AsDiyFp(); + DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1)); + DiyFp m_minus; + if (LowerBoundaryIsCloser()) { + m_minus = DiyFp((v.f() << 2) - 1, v.e() - 2); + } else { + m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1); + } + m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e())); + m_minus.set_e(m_plus.e()); + *out_m_plus = m_plus; + *out_m_minus = m_minus; + } + + // Precondition: the value encoded by this Single must be greater or equal + // than +0.0. + DiyFp UpperBoundary() const { + DOUBLE_CONVERSION_ASSERT(Sign() > 0); + return DiyFp(Significand() * 2 + 1, Exponent() - 1); + } + + bool LowerBoundaryIsCloser() const { + // The boundary is closer if the significand is of the form f == 2^p-1 then + // the lower boundary is closer. + // Think of v = 1000e10 and v- = 9999e9. + // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but + // at a distance of 1e8. + // The only exception is for the smallest normal: the largest denormal is + // at the same distance as its successor. + // Note: denormals have the same exponent as the smallest normals. + bool physical_significand_is_zero = ((AsUint32() & kSignificandMask) == 0); + return physical_significand_is_zero && (Exponent() != kDenormalExponent); + } + + float value() const { return uint32_to_float(d32_); } + + static float Infinity() { return Single(kInfinity).value(); } + + static float NaN() { return Single(kNaN).value(); } + + private: + static const int kExponentBias = 0x7F + kPhysicalSignificandSize; + static const int kDenormalExponent = -kExponentBias + 1; + static const int kMaxExponent = 0xFF - kExponentBias; + static const uint32_t kInfinity = 0x7F800000; + static const uint32_t kNaN = 0x7FC00000; + + const uint32_t d32_; + + DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(Single); +}; + +} // namespace double_conversion + +#endif // DOUBLE_CONVERSION_DOUBLE_H_ diff --git a/third_party/double-conversion/utils.h b/third_party/double-conversion/utils.h new file mode 100644 index 00000000..1255e561 --- /dev/null +++ b/third_party/double-conversion/utils.h @@ -0,0 +1,308 @@ +#ifndef DOUBLE_CONVERSION_UTILS_H_ +#define DOUBLE_CONVERSION_UTILS_H_ +#include "libc/assert.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" + +#ifndef DOUBLE_CONVERSION_ASSERT +#define DOUBLE_CONVERSION_ASSERT(condition) assert(condition); +#endif +#ifndef DOUBLE_CONVERSION_UNIMPLEMENTED +#define DOUBLE_CONVERSION_UNIMPLEMENTED() (abort()) +#endif +#ifndef DOUBLE_CONVERSION_NO_RETURN +#ifdef _MSC_VER +#define DOUBLE_CONVERSION_NO_RETURN __declspec(noreturn) +#else +#define DOUBLE_CONVERSION_NO_RETURN __attribute__((noreturn)) +#endif +#endif +#ifndef DOUBLE_CONVERSION_UNREACHABLE +#ifdef _MSC_VER +void DOUBLE_CONVERSION_NO_RETURN abort_noreturn(); +inline void abort_noreturn() { abort(); } +#define DOUBLE_CONVERSION_UNREACHABLE() (abort_noreturn()) +#else +#define DOUBLE_CONVERSION_UNREACHABLE() (abort()) +#endif +#endif + +#ifndef DOUBLE_CONVERSION_UNUSED +#ifdef __GNUC__ +#define DOUBLE_CONVERSION_UNUSED __attribute__((unused)) +#else +#define DOUBLE_CONVERSION_UNUSED +#endif +#endif + +// Double operations detection based on target architecture. +// Linux uses a 80bit wide floating point stack on x86. This induces double +// rounding, which in turn leads to wrong results. +// An easy way to test if the floating-point operations are correct is to +// evaluate: 89255.0/1e22. If the floating-point stack is 64 bits wide then +// the result is equal to 89255e-22. +// The best way to test this, is to create a division-function and to compare +// the output of the division with the expected result. (Inlining must be +// disabled.) +// On Linux,x86 89255e-22 != Div_double(89255.0/1e22) +// +// For example: +/* +// -- in div.c +double Div_double(double x, double y) { return x / y; } + +// -- in main.c +double Div_double(double x, double y); // Forward declaration. + +int main(int argc, char** argv) { + return Div_double(89255.0, 1e22) == 89255e-22; +} +*/ +// Run as follows ./main || echo "correct" +// +// If it prints "correct" then the architecture should be here, in the "correct" +// section. +#if defined(_M_X64) || defined(__x86_64__) || defined(__ARMEL__) || \ + defined(__avr32__) || defined(_M_ARM) || defined(_M_ARM64) || \ + defined(__hppa__) || defined(__ia64__) || defined(__mips__) || \ + defined(__nios2__) || defined(__powerpc__) || defined(__ppc__) || \ + defined(__ppc64__) || defined(_POWER) || defined(_ARCH_PPC) || \ + defined(_ARCH_PPC64) || defined(__sparc__) || defined(__sparc) || \ + defined(__s390__) || defined(__SH4__) || defined(__alpha__) || \ + defined(_MIPS_ARCH_MIPS32R2) || defined(__ARMEB__) || \ + defined(__AARCH64EL__) || defined(__aarch64__) || \ + defined(__AARCH64EB__) || defined(__riscv) || defined(__e2k__) || \ + defined(__or1k__) || defined(__arc__) || defined(__microblaze__) || \ + defined(__XTENSA__) || defined(__EMSCRIPTEN__) || defined(__wasm32__) +#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 +#elif defined(__mc68000__) || defined(__pnacl__) || defined(__native_client__) +#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS +#elif defined(_M_IX86) || defined(__i386__) || defined(__i386) +#if defined(_WIN32) +// Windows uses a 64bit wide floating point stack. +#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 +#else +#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS +#endif // _WIN32 +#else +#error Target architecture was not detected as supported by Double-Conversion. +#endif + +typedef uint16_t uc16; + +// The following macro works on both 32 and 64-bit platforms. +// Usage: instead of writing 0x1234567890123456 +// write DOUBLE_CONVERSION_UINT64_2PART_C(0x12345678,90123456); +#define DOUBLE_CONVERSION_UINT64_2PART_C(a, b) \ + (((static_cast(a) << 32) + 0x##b##u)) + +// The expression DOUBLE_CONVERSION_ARRAY_SIZE(a) is a compile-time constant of +// type size_t which represents the number of elements of the given array. You +// should only use DOUBLE_CONVERSION_ARRAY_SIZE on statically allocated arrays. +#ifndef DOUBLE_CONVERSION_ARRAY_SIZE +#define DOUBLE_CONVERSION_ARRAY_SIZE(a) \ + ((sizeof(a) / sizeof(*(a))) / \ + static_cast(!(sizeof(a) % sizeof(*(a))))) +#endif + +// A macro to disallow the evil copy constructor and operator= functions +// This should be used in the private: declarations for a class +#ifndef DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN +#define DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) +#endif + +// A macro to disallow all the implicit constructors, namely the +// default constructor, copy constructor and operator= functions. +// +// This should be used in the private: declarations for a class +// that wants to prevent anyone from instantiating it. This is +// especially useful for classes containing only static methods. +#ifndef DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS +#define DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ + TypeName(); \ + DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(TypeName) +#endif + +namespace double_conversion { + +inline int StrLength(const char* string) { + size_t length = strlen(string); + DOUBLE_CONVERSION_ASSERT(length == + static_cast(static_cast(length))); + return static_cast(length); +} + +// This is a simplified version of V8's Vector class. +template +class Vector { + public: + Vector() : start_(NULL), length_(0) {} + Vector(T* data, int len) : start_(data), length_(len) { + DOUBLE_CONVERSION_ASSERT(len == 0 || (len > 0 && data != NULL)); + } + + // Returns a vector using the same backing storage as this one, + // spanning from and including 'from', to but not including 'to'. + Vector SubVector(int from, int to) { + DOUBLE_CONVERSION_ASSERT(to <= length_); + DOUBLE_CONVERSION_ASSERT(from < to); + DOUBLE_CONVERSION_ASSERT(0 <= from); + return Vector(start() + from, to - from); + } + + // Returns the length of the vector. + int length() const { return length_; } + + // Returns whether or not the vector is empty. + bool is_empty() const { return length_ == 0; } + + // Returns the pointer to the start of the data in the vector. + T* start() const { return start_; } + + // Access individual vector elements - checks bounds in debug mode. + T& operator[](int index) const { + DOUBLE_CONVERSION_ASSERT(0 <= index && index < length_); + return start_[index]; + } + + T& first() { return start_[0]; } + + T& last() { return start_[length_ - 1]; } + + void pop_back() { + DOUBLE_CONVERSION_ASSERT(!is_empty()); + --length_; + } + + private: + T* start_; + int length_; +}; + +// Helper class for building result strings in a character buffer. The +// purpose of the class is to use safe operations that checks the +// buffer bounds on all operations in debug mode. +class StringBuilder { + public: + StringBuilder(char* buffer, int buffer_size) + : buffer_(buffer, buffer_size), position_(0) {} + + ~StringBuilder() { + if (!is_finalized()) Finalize(); + } + + int size() const { return buffer_.length(); } + + // Get the current position in the builder. + int position() const { + DOUBLE_CONVERSION_ASSERT(!is_finalized()); + return position_; + } + + // Reset the position. + void Reset() { position_ = 0; } + + // Add a single character to the builder. It is not allowed to add + // 0-characters; use the Finalize() method to terminate the string + // instead. + void AddCharacter(char c) { + DOUBLE_CONVERSION_ASSERT(c != '\0'); + DOUBLE_CONVERSION_ASSERT(!is_finalized() && position_ < buffer_.length()); + buffer_[position_++] = c; + } + + // Add an entire string to the builder. Uses strlen() internally to + // compute the length of the input string. + void AddString(const char* s) { AddSubstring(s, StrLength(s)); } + + // Add the first 'n' characters of the given string 's' to the + // builder. The input string must have enough characters. + void AddSubstring(const char* s, int n) { + DOUBLE_CONVERSION_ASSERT(!is_finalized() && + position_ + n < buffer_.length()); + DOUBLE_CONVERSION_ASSERT(static_cast(n) <= strlen(s)); + __builtin_memmove(&buffer_[position_], s, n); + position_ += n; + } + + // Add character padding to the builder. If count is non-positive, + // nothing is added to the builder. + void AddPadding(char c, int count) { + for (int i = 0; i < count; i++) { + AddCharacter(c); + } + } + + // Finalize the string by 0-terminating it and returning the buffer. + char* Finalize() { + DOUBLE_CONVERSION_ASSERT(!is_finalized() && position_ < buffer_.length()); + buffer_[position_] = '\0'; + // Make sure nobody managed to add a 0-character to the + // buffer while building the string. + DOUBLE_CONVERSION_ASSERT(strlen(buffer_.start()) == + static_cast(position_)); + position_ = -1; + DOUBLE_CONVERSION_ASSERT(is_finalized()); + return buffer_.start(); + } + + private: + Vector buffer_; + int position_; + + bool is_finalized() const { return position_ < 0; } + + DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder); +}; + +// The type-based aliasing rule allows the compiler to assume that pointers of +// different types (for some definition of different) never alias each other. +// Thus the following code does not work: +// +// float f = foo(); +// int fbits = *(int*)(&f); +// +// The compiler 'knows' that the int pointer can't refer to f since the types +// don't match, so the compiler may cache f in a register, leaving random data +// in fbits. Using C++ style casts makes no difference, however a pointer to +// char data is assumed to alias any other pointer. This is the 'memcpy +// exception'. +// +// Bit_cast uses the memcpy exception to move the bits from a variable of one +// type of a variable of another type. Of course the end result is likely to +// be implementation dependent. Most compilers (gcc-4.2 and MSVC 2005) +// will completely optimize BitCast away. +// +// There is an additional use for BitCast. +// Recent gccs will warn when they see casts that may result in breakage due to +// the type-based aliasing rule. If you have checked that there is no breakage +// you can use BitCast to cast one pointer type to another. This confuses gcc +// enough that it can no longer see that you have cast one pointer type to +// another thus avoiding the warning. +template +Dest BitCast(const Source& source) { + // Compile time assertion: sizeof(Dest) == sizeof(Source) + // A compile error here means your Dest and Source have different sizes. +#if __cplusplus >= 201103L + static_assert(sizeof(Dest) == sizeof(Source)); +#else + DOUBLE_CONVERSION_UNUSED + typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1]; +#endif + + Dest dest; + memmove(&dest, &source, sizeof(dest)); + return dest; +} + +template +Dest BitCast(Source* source) { + return BitCast(reinterpret_cast(source)); +} + +} // namespace double_conversion + +#endif // DOUBLE_CONVERSION_UTILS_H_ diff --git a/third_party/dtoa/dtoa.c b/third_party/dtoa/dtoa.c new file mode 100644 index 00000000..9fda286f --- /dev/null +++ b/third_party/dtoa/dtoa.c @@ -0,0 +1,6232 @@ +#include "libc/calls/calls.h" +#include "libc/limits.h" +#include "libc/math.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "third_party/dtoa/dtoa.h" + +#define IEEE_8087 1 +/* #define SET_INEXACT 1 */ + +#if __NO_MATH_ERRNO__ + 0 +#define NO_ERRNO 1 +#endif + +#if __FINITE_MATH_ONLY__ + 0 +#define NO_INFNAN_CHECK 1 +#endif + +asm(".ident\t\"\\n\\n\ +dtoa (MIT License)\\n\ +The author of this software is David M. Gay.\\n\ +Copyright (c) 1991, 2000, 2001 by Lucent Technologies.\""); +asm(".include \"libc/disclaimer.inc\""); + +/* clang-format off */ +/**************************************************************** + * + * The author of this software is David M. Gay. + * + * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + * + ***************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +/* On a machine with IEEE extended-precision registers, it is + * necessary to specify double-precision (53-bit) rounding precision + * before invoking strtod or dtoa. If the machine uses (the equivalent + * of) Intel 80x87 arithmetic, the call + * _control87(PC_53, MCW_PC); + * does this with many compilers. Whether this or another call is + * appropriate depends on the compiler; for this to work, it may be + * necessary to #include "float.h" or another system-dependent header + * file. + */ + +/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. + * (Note that IEEE arithmetic is disabled by gcc's -ffast-math flag.) + * + * This strtod returns a nearest machine number to the input decimal + * string (or sets errno to ERANGE). With IEEE arithmetic, ties are + * broken by the IEEE round-even rule. Otherwise ties are broken by + * biased rounding (add half and chop). + * + * Inspired loosely by William D. Clinger's paper "How to Read Floating + * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). + */ + +/* + * #define IEEE_8087 for IEEE-arithmetic machines where the least + * significant byte has the lowest address. + * #define IEEE_MC68k for IEEE-arithmetic machines where the most + * significant byte has the lowest address. + * #define Long int on machines with 32-bit ints and 64-bit longs. + * #define IBM for IBM mainframe-style floating-point arithmetic. + * #define VAX for VAX-style floating-point arithmetic (D_floating). + * #define No_leftright to omit left-right logic in fast floating-point + * computation of dtoa. This will cause dtoa modes 4 and 5 to be + * treated the same as modes 2 and 3 for some inputs. + * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 + * and strtod and dtoa should round accordingly. Unless Trust_FLT_ROUNDS + * is also #defined, fegetround() will be queried for the rounding mode. + * Note that both FLT_ROUNDS and fegetround() are specified by the C99 + * standard (and are specified to be consistent, with fesetround() + * affecting the value of FLT_ROUNDS), but that some (Linux) systems + * do not work correctly in this regard, so using fegetround() is more + * portable than using FLT_ROUNDS directly. + * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 + * and Honor_FLT_ROUNDS is not #defined. + * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines + * that use extended-precision instructions to compute rounded + * products and quotients) with IBM. + * #define ROUND_BIASED for IEEE-format with biased rounding and arithmetic + * that rounds toward +Infinity. + * #define ROUND_BIASED_without_Round_Up for IEEE-format with biased + * rounding when the underlying floating-point arithmetic uses + * unbiased rounding. This prevent using ordinary floating-point + * arithmetic when the result could be computed with one rounding error. + * #define Inaccurate_Divide for IEEE-format with correctly rounded + * products but inaccurate quotients, e.g., for Intel i860. + * #define NO_LONG_LONG on machines that do not have a "long long" + * integer type (of >= 64 bits). On such machines, you can + * #define Just_16 to store 16 bits per 32-bit Long when doing + * high-precision integer arithmetic. Whether this speeds things + * up or slows things down depends on the machine and the number + * being converted. If long long is available and the name is + * something other than "long long", #define Llong to be the name, + * and if "unsigned Llong" does not work as an unsigned version of + * Llong, #define #ULLong to be the corresponding unsigned type. + * #define Bad_float_h if your system lacks a float.h or if it does not + * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, + * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. + * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) + * if memory is available and otherwise does something you deem + * appropriate. If MALLOC is undefined, malloc will be invoked + * directly -- and assumed always to succeed. Similarly, if you + * want something other than the system's free() to be called to + * recycle memory acquired from MALLOC, #define FREE to be the + * name of the alternate routine. (FREE or free is only called in + * pathological cases, e.g., in a dtoa call after a dtoa return in + * mode 3 with thousands of digits requested.) + * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making + * memory allocations from a private pool of memory when possible. + * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, + * unless #defined to be a different length. This default length + * suffices to get rid of MALLOC calls except for unusual cases, + * such as decimal-to-binary conversion of a very long string of + * digits. The longest string dtoa can return is about 751 bytes + * long. For conversions by strtod of strings of 800 digits and + * all dtoa conversions in single-threaded executions with 8-byte + * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte + * pointers, PRIVATE_MEM >= 7112 appears adequate. + * #define NO_INFNAN_CHECK if you do not wish to have INFNAN_CHECK + * #defined automatically on IEEE systems. On such systems, + * when INFNAN_CHECK is #defined, strtod checks + * for Infinity and NaN (case insensitively). On some systems + * (e.g., some HP systems), it may be necessary to #define NAN_WORD0 + * appropriately -- to the most significant word of a quiet NaN. + * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) + * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, + * strtod also accepts (case insensitively) strings of the form + * NaN(x), where x is a string of hexadecimal digits and spaces; + * if there is only one string of hexadecimal digits, it is taken + * for the 52 fraction bits of the resulting NaN; if there are two + * or more strings of hex digits, the first is for the high 20 bits, + * the second and subsequent for the low 32 bits, with intervening + * white space ignored; but if this results in none of the 52 + * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 + * and NAN_WORD1 are used instead. + * #define MULTIPLE_THREADS if the system offers preemptively scheduled + * multiple threads. In this case, you must provide (or suitably + * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed + * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed + * in pow5mult, ensures lazy evaluation of only one copy of high + * powers of 5; omitting this lock would introduce a small + * probability of wasting memory, but would otherwise be harmless.) + * You must also invoke freedtoa(s) to free the value s returned by + * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. + + * When MULTIPLE_THREADS is #defined, this source file provides + * void set_max_dtoa_threads(unsigned int n); + * and expects + * unsigned int dtoa_get_threadno(void); + * to be available (possibly provided by + * #define dtoa_get_threadno omp_get_thread_num + * if OpenMP is in use or by + * #define dtoa_get_threadno pthread_self + * if Pthreads is in use), to return the current thread number. + * If set_max_dtoa_threads(n) was called and the current thread + * number is k with k < n, then calls on ACQUIRE_DTOA_LOCK(...) and + * FREE_DTOA_LOCK(...) are avoided; instead each thread with thread + * number < n has a separate copy of relevant data structures. + * After set_max_dtoa_threads(n), a call set_max_dtoa_threads(m) + * with m <= n has has no effect, but a call with m > n is honored. + * Such a call invokes REALLOC (assumed to be "realloc" if REALLOC + * is not #defined) to extend the size of the relevant array. + + * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that + * avoids underflows on inputs whose result does not underflow. + * If you #define NO_IEEE_Scale on a machine that uses IEEE-format + * floating-point numbers and flushes underflows to zero rather + * than implementing gradual underflow, then you must also #define + * Sudden_Underflow. + * #define USE_LOCALE to use the current locale's decimal_point value. + * #define SET_INEXACT if IEEE arithmetic is being used and extra + * computation should be done to set the inexact flag when the + * result is inexact and avoid setting inexact when the result + * is exact. In this case, dtoa.c must be compiled in + * an environment, perhaps provided by #include "dtoa.c" in a + * suitable wrapper, that defines two functions, + * int get_inexact(void); + * void clear_inexact(void); + * such that get_inexact() returns a nonzero value if the + * inexact bit is already set, and clear_inexact() sets the + * inexact bit to 0. When SET_INEXACT is #defined, strtod + * also does extra computations to set the underflow and overflow + * flags when appropriate (i.e., when the result is tiny and + * inexact or when it is a numeric value rounded to +-infinity). + * #define NO_ERRNO if strtod should not assign errno = ERANGE when + * the result overflows to +-Infinity or underflows to 0. + * When errno should be assigned, under seemingly rare conditions + * it may be necessary to define Set_errno(x) suitably, e.g., in + * a local errno.h, such as + * #include + * #define Set_errno(x) _set_errno(x) + * #define NO_HEX_FP to omit recognition of hexadecimal floating-point + * values by strtod. + * #define NO_STRTOD_BIGCOMP (on IEEE-arithmetic systems only for now) + * to disable logic for "fast" testing of very long input strings + * to strtod. This testing proceeds by initially truncating the + * input string, then if necessary comparing the whole string with + * a decimal expansion to decide close cases. This logic is only + * used for input more than STRTOD_DIGLIM digits long (default 40). + */ + +#ifndef Long +#define Long int +#endif +#ifndef ULong +typedef unsigned Long ULong; +#endif + +#ifdef DEBUG +#include "libc/assert.h" +#define Bug(x) {dprintf(STDERR_FILENO, "%s\n", x); exit(1);} +#define Debug(x) x +int dtoa_stats[7]; /* strtod_{64,96,bigcomp},dtoa_{exact,64,96,bigcomp} */ +#else +#define assert(x) /*nothing*/ +#define Debug(x) /*nothing*/ +#endif + +#include "libc/mem/mem.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +#ifdef Honor_FLT_ROUNDS +#ifndef Trust_FLT_ROUNDS +#include "libc/math.h" +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef MALLOC +extern void *MALLOC(size_t); +#else +#define MALLOC malloc +#endif + +#ifdef REALLOC +extern void *REALLOC(void*,size_t); +#else +#define REALLOC realloc +#endif + +#ifndef FREE +#define FREE free +#endif + +#ifdef __cplusplus + } +#endif + +#ifndef Omit_Private_Memory +#ifndef PRIVATE_MEM +#define PRIVATE_MEM 2304 +#endif +#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) +static double private_mem[PRIVATE_mem], *pmem_next; +INITIALIZER(300, _init_dtoa_pmem, {pmem_next = private_mem;}); +#endif + +#undef IEEE_Arith +#undef Avoid_Underflow +#ifdef IEEE_MC68k +#define IEEE_Arith +#endif +#ifdef IEEE_8087 +#define IEEE_Arith +#endif + +#ifdef IEEE_Arith +#ifndef NO_INFNAN_CHECK +#undef INFNAN_CHECK +#define INFNAN_CHECK +#endif +#else +#undef INFNAN_CHECK +#define NO_STRTOD_BIGCOMP +#endif + +#include "libc/errno.h" + +#ifdef NO_ERRNO /*{*/ +#undef Set_errno +#define Set_errno(x) +#else +#ifndef Set_errno +#define Set_errno(x) x() +#endif +#endif /*}*/ + +#ifdef Bad_float_h + +#ifdef IEEE_Arith +#define DBL_DIG 15 +#define DBL_MAX_10_EXP 308 +#define DBL_MAX_EXP 1024 +#define FLT_RADIX 2 +#endif /*IEEE_Arith*/ + +#ifdef IBM +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 75 +#define DBL_MAX_EXP 63 +#define FLT_RADIX 16 +#define DBL_MAX 7.2370055773322621e+75 +#endif + +#ifdef VAX +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 38 +#define DBL_MAX_EXP 127 +#define FLT_RADIX 2 +#define DBL_MAX 1.7014118346046923e+38 +#endif + +#ifndef LONG_MAX +#define LONG_MAX 2147483647 +#endif + +#else /* ifndef Bad_float_h */ +#include "libc/math.h" +#endif /* Bad_float_h */ + +#ifndef __MATH_H__ +#include "libc/math.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 +Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. +#endif + +#undef USE_BF96 + +#ifdef NO_LONG_LONG /*{{*/ +#undef ULLong +#ifdef Just_16 +#undef Pack_32 +/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. + * This makes some inner loops simpler and sometimes saves work + * during multiplications, but it often seems to make things slightly + * slower. Hence the default is now to store 32 bits per Long. + */ +#endif +#else /*}{ long long available */ +#ifndef Llong +#define Llong long long +#endif +#ifndef ULLong +#define ULLong unsigned Llong +#endif +#ifndef NO_BF96 /*{*/ +#define USE_BF96 + +#ifdef SET_INEXACT +#define dtoa_divmax 27 +#else +int dtoa_divmax; /* Permit experimenting: on some systems, 64-bit integer */ + /* division is slow enough that we may sometimes want to */ + /* avoid using it. We assume (but do not check) that */ + /* dtoa_divmax <= 27.*/ +INITIALIZER(300, _init_dtoa_divmax, {dtoa_divmax = 2;}); +#endif + +typedef struct BF96 { /* Normalized 96-bit software floating point numbers */ + unsigned int b0,b1,b2; /* b0 = most significant, binary point just to its left */ + int e; /* number represented = b * 2^e, with .5 <= b < 1 */ + } BF96; + + static const BF96 pten[667] = { + { 0xeef453d6, 0x923bd65a, 0x113faa29, -1136 }, + { 0x9558b466, 0x1b6565f8, 0x4ac7ca59, -1132 }, + { 0xbaaee17f, 0xa23ebf76, 0x5d79bcf0, -1129 }, + { 0xe95a99df, 0x8ace6f53, 0xf4d82c2c, -1126 }, + { 0x91d8a02b, 0xb6c10594, 0x79071b9b, -1122 }, + { 0xb64ec836, 0xa47146f9, 0x9748e282, -1119 }, + { 0xe3e27a44, 0x4d8d98b7, 0xfd1b1b23, -1116 }, + { 0x8e6d8c6a, 0xb0787f72, 0xfe30f0f5, -1112 }, + { 0xb208ef85, 0x5c969f4f, 0xbdbd2d33, -1109 }, + { 0xde8b2b66, 0xb3bc4723, 0xad2c7880, -1106 }, + { 0x8b16fb20, 0x3055ac76, 0x4c3bcb50, -1102 }, + { 0xaddcb9e8, 0x3c6b1793, 0xdf4abe24, -1099 }, + { 0xd953e862, 0x4b85dd78, 0xd71d6dad, -1096 }, + { 0x87d4713d, 0x6f33aa6b, 0x8672648c, -1092 }, + { 0xa9c98d8c, 0xcb009506, 0x680efdaf, -1089 }, + { 0xd43bf0ef, 0xfdc0ba48, 0x0212bd1b, -1086 }, + { 0x84a57695, 0xfe98746d, 0x014bb630, -1082 }, + { 0xa5ced43b, 0x7e3e9188, 0x419ea3bd, -1079 }, + { 0xcf42894a, 0x5dce35ea, 0x52064cac, -1076 }, + { 0x818995ce, 0x7aa0e1b2, 0x7343efeb, -1072 }, + { 0xa1ebfb42, 0x19491a1f, 0x1014ebe6, -1069 }, + { 0xca66fa12, 0x9f9b60a6, 0xd41a26e0, -1066 }, + { 0xfd00b897, 0x478238d0, 0x8920b098, -1063 }, + { 0x9e20735e, 0x8cb16382, 0x55b46e5f, -1059 }, + { 0xc5a89036, 0x2fddbc62, 0xeb2189f7, -1056 }, + { 0xf712b443, 0xbbd52b7b, 0xa5e9ec75, -1053 }, + { 0x9a6bb0aa, 0x55653b2d, 0x47b233c9, -1049 }, + { 0xc1069cd4, 0xeabe89f8, 0x999ec0bb, -1046 }, + { 0xf148440a, 0x256e2c76, 0xc00670ea, -1043 }, + { 0x96cd2a86, 0x5764dbca, 0x38040692, -1039 }, + { 0xbc807527, 0xed3e12bc, 0xc6050837, -1036 }, + { 0xeba09271, 0xe88d976b, 0xf7864a44, -1033 }, + { 0x93445b87, 0x31587ea3, 0x7ab3ee6a, -1029 }, + { 0xb8157268, 0xfdae9e4c, 0x5960ea05, -1026 }, + { 0xe61acf03, 0x3d1a45df, 0x6fb92487, -1023 }, + { 0x8fd0c162, 0x06306bab, 0xa5d3b6d4, -1019 }, + { 0xb3c4f1ba, 0x87bc8696, 0x8f48a489, -1016 }, + { 0xe0b62e29, 0x29aba83c, 0x331acdab, -1013 }, + { 0x8c71dcd9, 0xba0b4925, 0x9ff0c08b, -1009 }, + { 0xaf8e5410, 0x288e1b6f, 0x07ecf0ae, -1006 }, + { 0xdb71e914, 0x32b1a24a, 0xc9e82cd9, -1003 }, + { 0x892731ac, 0x9faf056e, 0xbe311c08, -999 }, + { 0xab70fe17, 0xc79ac6ca, 0x6dbd630a, -996 }, + { 0xd64d3d9d, 0xb981787d, 0x092cbbcc, -993 }, + { 0x85f04682, 0x93f0eb4e, 0x25bbf560, -989 }, + { 0xa76c5823, 0x38ed2621, 0xaf2af2b8, -986 }, + { 0xd1476e2c, 0x07286faa, 0x1af5af66, -983 }, + { 0x82cca4db, 0x847945ca, 0x50d98d9f, -979 }, + { 0xa37fce12, 0x6597973c, 0xe50ff107, -976 }, + { 0xcc5fc196, 0xfefd7d0c, 0x1e53ed49, -973 }, + { 0xff77b1fc, 0xbebcdc4f, 0x25e8e89c, -970 }, + { 0x9faacf3d, 0xf73609b1, 0x77b19161, -966 }, + { 0xc795830d, 0x75038c1d, 0xd59df5b9, -963 }, + { 0xf97ae3d0, 0xd2446f25, 0x4b057328, -960 }, + { 0x9becce62, 0x836ac577, 0x4ee367f9, -956 }, + { 0xc2e801fb, 0x244576d5, 0x229c41f7, -953 }, + { 0xf3a20279, 0xed56d48a, 0x6b435275, -950 }, + { 0x9845418c, 0x345644d6, 0x830a1389, -946 }, + { 0xbe5691ef, 0x416bd60c, 0x23cc986b, -943 }, + { 0xedec366b, 0x11c6cb8f, 0x2cbfbe86, -940 }, + { 0x94b3a202, 0xeb1c3f39, 0x7bf7d714, -936 }, + { 0xb9e08a83, 0xa5e34f07, 0xdaf5ccd9, -933 }, + { 0xe858ad24, 0x8f5c22c9, 0xd1b3400f, -930 }, + { 0x91376c36, 0xd99995be, 0x23100809, -926 }, + { 0xb5854744, 0x8ffffb2d, 0xabd40a0c, -923 }, + { 0xe2e69915, 0xb3fff9f9, 0x16c90c8f, -920 }, + { 0x8dd01fad, 0x907ffc3b, 0xae3da7d9, -916 }, + { 0xb1442798, 0xf49ffb4a, 0x99cd11cf, -913 }, + { 0xdd95317f, 0x31c7fa1d, 0x40405643, -910 }, + { 0x8a7d3eef, 0x7f1cfc52, 0x482835ea, -906 }, + { 0xad1c8eab, 0x5ee43b66, 0xda324365, -903 }, + { 0xd863b256, 0x369d4a40, 0x90bed43e, -900 }, + { 0x873e4f75, 0xe2224e68, 0x5a7744a6, -896 }, + { 0xa90de353, 0x5aaae202, 0x711515d0, -893 }, + { 0xd3515c28, 0x31559a83, 0x0d5a5b44, -890 }, + { 0x8412d999, 0x1ed58091, 0xe858790a, -886 }, + { 0xa5178fff, 0x668ae0b6, 0x626e974d, -883 }, + { 0xce5d73ff, 0x402d98e3, 0xfb0a3d21, -880 }, + { 0x80fa687f, 0x881c7f8e, 0x7ce66634, -876 }, + { 0xa139029f, 0x6a239f72, 0x1c1fffc1, -873 }, + { 0xc9874347, 0x44ac874e, 0xa327ffb2, -870 }, + { 0xfbe91419, 0x15d7a922, 0x4bf1ff9f, -867 }, + { 0x9d71ac8f, 0xada6c9b5, 0x6f773fc3, -863 }, + { 0xc4ce17b3, 0x99107c22, 0xcb550fb4, -860 }, + { 0xf6019da0, 0x7f549b2b, 0x7e2a53a1, -857 }, + { 0x99c10284, 0x4f94e0fb, 0x2eda7444, -853 }, + { 0xc0314325, 0x637a1939, 0xfa911155, -850 }, + { 0xf03d93ee, 0xbc589f88, 0x793555ab, -847 }, + { 0x96267c75, 0x35b763b5, 0x4bc1558b, -843 }, + { 0xbbb01b92, 0x83253ca2, 0x9eb1aaed, -840 }, + { 0xea9c2277, 0x23ee8bcb, 0x465e15a9, -837 }, + { 0x92a1958a, 0x7675175f, 0x0bfacd89, -833 }, + { 0xb749faed, 0x14125d36, 0xcef980ec, -830 }, + { 0xe51c79a8, 0x5916f484, 0x82b7e127, -827 }, + { 0x8f31cc09, 0x37ae58d2, 0xd1b2ecb8, -823 }, + { 0xb2fe3f0b, 0x8599ef07, 0x861fa7e6, -820 }, + { 0xdfbdcece, 0x67006ac9, 0x67a791e0, -817 }, + { 0x8bd6a141, 0x006042bd, 0xe0c8bb2c, -813 }, + { 0xaecc4991, 0x4078536d, 0x58fae9f7, -810 }, + { 0xda7f5bf5, 0x90966848, 0xaf39a475, -807 }, + { 0x888f9979, 0x7a5e012d, 0x6d8406c9, -803 }, + { 0xaab37fd7, 0xd8f58178, 0xc8e5087b, -800 }, + { 0xd5605fcd, 0xcf32e1d6, 0xfb1e4a9a, -797 }, + { 0x855c3be0, 0xa17fcd26, 0x5cf2eea0, -793 }, + { 0xa6b34ad8, 0xc9dfc06f, 0xf42faa48, -790 }, + { 0xd0601d8e, 0xfc57b08b, 0xf13b94da, -787 }, + { 0x823c1279, 0x5db6ce57, 0x76c53d08, -783 }, + { 0xa2cb1717, 0xb52481ed, 0x54768c4b, -780 }, + { 0xcb7ddcdd, 0xa26da268, 0xa9942f5d, -777 }, + { 0xfe5d5415, 0x0b090b02, 0xd3f93b35, -774 }, + { 0x9efa548d, 0x26e5a6e1, 0xc47bc501, -770 }, + { 0xc6b8e9b0, 0x709f109a, 0x359ab641, -767 }, + { 0xf867241c, 0x8cc6d4c0, 0xc30163d2, -764 }, + { 0x9b407691, 0xd7fc44f8, 0x79e0de63, -760 }, + { 0xc2109436, 0x4dfb5636, 0x985915fc, -757 }, + { 0xf294b943, 0xe17a2bc4, 0x3e6f5b7b, -754 }, + { 0x979cf3ca, 0x6cec5b5a, 0xa705992c, -750 }, + { 0xbd8430bd, 0x08277231, 0x50c6ff78, -747 }, + { 0xece53cec, 0x4a314ebd, 0xa4f8bf56, -744 }, + { 0x940f4613, 0xae5ed136, 0x871b7795, -740 }, + { 0xb9131798, 0x99f68584, 0x28e2557b, -737 }, + { 0xe757dd7e, 0xc07426e5, 0x331aeada, -734 }, + { 0x9096ea6f, 0x3848984f, 0x3ff0d2c8, -730 }, + { 0xb4bca50b, 0x065abe63, 0x0fed077a, -727 }, + { 0xe1ebce4d, 0xc7f16dfb, 0xd3e84959, -724 }, + { 0x8d3360f0, 0x9cf6e4bd, 0x64712dd7, -720 }, + { 0xb080392c, 0xc4349dec, 0xbd8d794d, -717 }, + { 0xdca04777, 0xf541c567, 0xecf0d7a0, -714 }, + { 0x89e42caa, 0xf9491b60, 0xf41686c4, -710 }, + { 0xac5d37d5, 0xb79b6239, 0x311c2875, -707 }, + { 0xd77485cb, 0x25823ac7, 0x7d633293, -704 }, + { 0x86a8d39e, 0xf77164bc, 0xae5dff9c, -700 }, + { 0xa8530886, 0xb54dbdeb, 0xd9f57f83, -697 }, + { 0xd267caa8, 0x62a12d66, 0xd072df63, -694 }, + { 0x8380dea9, 0x3da4bc60, 0x4247cb9e, -690 }, + { 0xa4611653, 0x8d0deb78, 0x52d9be85, -687 }, + { 0xcd795be8, 0x70516656, 0x67902e27, -684 }, + { 0x806bd971, 0x4632dff6, 0x00ba1cd8, -680 }, + { 0xa086cfcd, 0x97bf97f3, 0x80e8a40e, -677 }, + { 0xc8a883c0, 0xfdaf7df0, 0x6122cd12, -674 }, + { 0xfad2a4b1, 0x3d1b5d6c, 0x796b8057, -671 }, + { 0x9cc3a6ee, 0xc6311a63, 0xcbe33036, -667 }, + { 0xc3f490aa, 0x77bd60fc, 0xbedbfc44, -664 }, + { 0xf4f1b4d5, 0x15acb93b, 0xee92fb55, -661 }, + { 0x99171105, 0x2d8bf3c5, 0x751bdd15, -657 }, + { 0xbf5cd546, 0x78eef0b6, 0xd262d45a, -654 }, + { 0xef340a98, 0x172aace4, 0x86fb8971, -651 }, + { 0x9580869f, 0x0e7aac0e, 0xd45d35e6, -647 }, + { 0xbae0a846, 0xd2195712, 0x89748360, -644 }, + { 0xe998d258, 0x869facd7, 0x2bd1a438, -641 }, + { 0x91ff8377, 0x5423cc06, 0x7b6306a3, -637 }, + { 0xb67f6455, 0x292cbf08, 0x1a3bc84c, -634 }, + { 0xe41f3d6a, 0x7377eeca, 0x20caba5f, -631 }, + { 0x8e938662, 0x882af53e, 0x547eb47b, -627 }, + { 0xb23867fb, 0x2a35b28d, 0xe99e619a, -624 }, + { 0xdec681f9, 0xf4c31f31, 0x6405fa00, -621 }, + { 0x8b3c113c, 0x38f9f37e, 0xde83bc40, -617 }, + { 0xae0b158b, 0x4738705e, 0x9624ab50, -614 }, + { 0xd98ddaee, 0x19068c76, 0x3badd624, -611 }, + { 0x87f8a8d4, 0xcfa417c9, 0xe54ca5d7, -607 }, + { 0xa9f6d30a, 0x038d1dbc, 0x5e9fcf4c, -604 }, + { 0xd47487cc, 0x8470652b, 0x7647c320, -601 }, + { 0x84c8d4df, 0xd2c63f3b, 0x29ecd9f4, -597 }, + { 0xa5fb0a17, 0xc777cf09, 0xf4681071, -594 }, + { 0xcf79cc9d, 0xb955c2cc, 0x7182148d, -591 }, + { 0x81ac1fe2, 0x93d599bf, 0xc6f14cd8, -587 }, + { 0xa21727db, 0x38cb002f, 0xb8ada00e, -584 }, + { 0xca9cf1d2, 0x06fdc03b, 0xa6d90811, -581 }, + { 0xfd442e46, 0x88bd304a, 0x908f4a16, -578 }, + { 0x9e4a9cec, 0x15763e2e, 0x9a598e4e, -574 }, + { 0xc5dd4427, 0x1ad3cdba, 0x40eff1e1, -571 }, + { 0xf7549530, 0xe188c128, 0xd12bee59, -568 }, + { 0x9a94dd3e, 0x8cf578b9, 0x82bb74f8, -564 }, + { 0xc13a148e, 0x3032d6e7, 0xe36a5236, -561 }, + { 0xf18899b1, 0xbc3f8ca1, 0xdc44e6c3, -558 }, + { 0x96f5600f, 0x15a7b7e5, 0x29ab103a, -554 }, + { 0xbcb2b812, 0xdb11a5de, 0x7415d448, -551 }, + { 0xebdf6617, 0x91d60f56, 0x111b495b, -548 }, + { 0x936b9fce, 0xbb25c995, 0xcab10dd9, -544 }, + { 0xb84687c2, 0x69ef3bfb, 0x3d5d514f, -541 }, + { 0xe65829b3, 0x046b0afa, 0x0cb4a5a3, -538 }, + { 0x8ff71a0f, 0xe2c2e6dc, 0x47f0e785, -534 }, + { 0xb3f4e093, 0xdb73a093, 0x59ed2167, -531 }, + { 0xe0f218b8, 0xd25088b8, 0x306869c1, -528 }, + { 0x8c974f73, 0x83725573, 0x1e414218, -524 }, + { 0xafbd2350, 0x644eeacf, 0xe5d1929e, -521 }, + { 0xdbac6c24, 0x7d62a583, 0xdf45f746, -518 }, + { 0x894bc396, 0xce5da772, 0x6b8bba8c, -514 }, + { 0xab9eb47c, 0x81f5114f, 0x066ea92f, -511 }, + { 0xd686619b, 0xa27255a2, 0xc80a537b, -508 }, + { 0x8613fd01, 0x45877585, 0xbd06742c, -504 }, + { 0xa798fc41, 0x96e952e7, 0x2c481138, -501 }, + { 0xd17f3b51, 0xfca3a7a0, 0xf75a1586, -498 }, + { 0x82ef8513, 0x3de648c4, 0x9a984d73, -494 }, + { 0xa3ab6658, 0x0d5fdaf5, 0xc13e60d0, -491 }, + { 0xcc963fee, 0x10b7d1b3, 0x318df905, -488 }, + { 0xffbbcfe9, 0x94e5c61f, 0xfdf17746, -485 }, + { 0x9fd561f1, 0xfd0f9bd3, 0xfeb6ea8b, -481 }, + { 0xc7caba6e, 0x7c5382c8, 0xfe64a52e, -478 }, + { 0xf9bd690a, 0x1b68637b, 0x3dfdce7a, -475 }, + { 0x9c1661a6, 0x51213e2d, 0x06bea10c, -471 }, + { 0xc31bfa0f, 0xe5698db8, 0x486e494f, -468 }, + { 0xf3e2f893, 0xdec3f126, 0x5a89dba3, -465 }, + { 0x986ddb5c, 0x6b3a76b7, 0xf8962946, -461 }, + { 0xbe895233, 0x86091465, 0xf6bbb397, -458 }, + { 0xee2ba6c0, 0x678b597f, 0x746aa07d, -455 }, + { 0x94db4838, 0x40b717ef, 0xa8c2a44e, -451 }, + { 0xba121a46, 0x50e4ddeb, 0x92f34d62, -448 }, + { 0xe896a0d7, 0xe51e1566, 0x77b020ba, -445 }, + { 0x915e2486, 0xef32cd60, 0x0ace1474, -441 }, + { 0xb5b5ada8, 0xaaff80b8, 0x0d819992, -438 }, + { 0xe3231912, 0xd5bf60e6, 0x10e1fff6, -435 }, + { 0x8df5efab, 0xc5979c8f, 0xca8d3ffa, -431 }, + { 0xb1736b96, 0xb6fd83b3, 0xbd308ff8, -428 }, + { 0xddd0467c, 0x64bce4a0, 0xac7cb3f6, -425 }, + { 0x8aa22c0d, 0xbef60ee4, 0x6bcdf07a, -421 }, + { 0xad4ab711, 0x2eb3929d, 0x86c16c98, -418 }, + { 0xd89d64d5, 0x7a607744, 0xe871c7bf, -415 }, + { 0x87625f05, 0x6c7c4a8b, 0x11471cd7, -411 }, + { 0xa93af6c6, 0xc79b5d2d, 0xd598e40d, -408 }, + { 0xd389b478, 0x79823479, 0x4aff1d10, -405 }, + { 0x843610cb, 0x4bf160cb, 0xcedf722a, -401 }, + { 0xa54394fe, 0x1eedb8fe, 0xc2974eb4, -398 }, + { 0xce947a3d, 0xa6a9273e, 0x733d2262, -395 }, + { 0x811ccc66, 0x8829b887, 0x0806357d, -391 }, + { 0xa163ff80, 0x2a3426a8, 0xca07c2dc, -388 }, + { 0xc9bcff60, 0x34c13052, 0xfc89b393, -385 }, + { 0xfc2c3f38, 0x41f17c67, 0xbbac2078, -382 }, + { 0x9d9ba783, 0x2936edc0, 0xd54b944b, -378 }, + { 0xc5029163, 0xf384a931, 0x0a9e795e, -375 }, + { 0xf64335bc, 0xf065d37d, 0x4d4617b5, -372 }, + { 0x99ea0196, 0x163fa42e, 0x504bced1, -368 }, + { 0xc06481fb, 0x9bcf8d39, 0xe45ec286, -365 }, + { 0xf07da27a, 0x82c37088, 0x5d767327, -362 }, + { 0x964e858c, 0x91ba2655, 0x3a6a07f8, -358 }, + { 0xbbe226ef, 0xb628afea, 0x890489f7, -355 }, + { 0xeadab0ab, 0xa3b2dbe5, 0x2b45ac74, -352 }, + { 0x92c8ae6b, 0x464fc96f, 0x3b0b8bc9, -348 }, + { 0xb77ada06, 0x17e3bbcb, 0x09ce6ebb, -345 }, + { 0xe5599087, 0x9ddcaabd, 0xcc420a6a, -342 }, + { 0x8f57fa54, 0xc2a9eab6, 0x9fa94682, -338 }, + { 0xb32df8e9, 0xf3546564, 0x47939822, -335 }, + { 0xdff97724, 0x70297ebd, 0x59787e2b, -332 }, + { 0x8bfbea76, 0xc619ef36, 0x57eb4edb, -328 }, + { 0xaefae514, 0x77a06b03, 0xede62292, -325 }, + { 0xdab99e59, 0x958885c4, 0xe95fab36, -322 }, + { 0x88b402f7, 0xfd75539b, 0x11dbcb02, -318 }, + { 0xaae103b5, 0xfcd2a881, 0xd652bdc2, -315 }, + { 0xd59944a3, 0x7c0752a2, 0x4be76d33, -312 }, + { 0x857fcae6, 0x2d8493a5, 0x6f70a440, -308 }, + { 0xa6dfbd9f, 0xb8e5b88e, 0xcb4ccd50, -305 }, + { 0xd097ad07, 0xa71f26b2, 0x7e2000a4, -302 }, + { 0x825ecc24, 0xc873782f, 0x8ed40066, -298 }, + { 0xa2f67f2d, 0xfa90563b, 0x72890080, -295 }, + { 0xcbb41ef9, 0x79346bca, 0x4f2b40a0, -292 }, + { 0xfea126b7, 0xd78186bc, 0xe2f610c8, -289 }, + { 0x9f24b832, 0xe6b0f436, 0x0dd9ca7d, -285 }, + { 0xc6ede63f, 0xa05d3143, 0x91503d1c, -282 }, + { 0xf8a95fcf, 0x88747d94, 0x75a44c63, -279 }, + { 0x9b69dbe1, 0xb548ce7c, 0xc986afbe, -275 }, + { 0xc24452da, 0x229b021b, 0xfbe85bad, -272 }, + { 0xf2d56790, 0xab41c2a2, 0xfae27299, -269 }, + { 0x97c560ba, 0x6b0919a5, 0xdccd879f, -265 }, + { 0xbdb6b8e9, 0x05cb600f, 0x5400e987, -262 }, + { 0xed246723, 0x473e3813, 0x290123e9, -259 }, + { 0x9436c076, 0x0c86e30b, 0xf9a0b672, -255 }, + { 0xb9447093, 0x8fa89bce, 0xf808e40e, -252 }, + { 0xe7958cb8, 0x7392c2c2, 0xb60b1d12, -249 }, + { 0x90bd77f3, 0x483bb9b9, 0xb1c6f22b, -245 }, + { 0xb4ecd5f0, 0x1a4aa828, 0x1e38aeb6, -242 }, + { 0xe2280b6c, 0x20dd5232, 0x25c6da63, -239 }, + { 0x8d590723, 0x948a535f, 0x579c487e, -235 }, + { 0xb0af48ec, 0x79ace837, 0x2d835a9d, -232 }, + { 0xdcdb1b27, 0x98182244, 0xf8e43145, -229 }, + { 0x8a08f0f8, 0xbf0f156b, 0x1b8e9ecb, -225 }, + { 0xac8b2d36, 0xeed2dac5, 0xe272467e, -222 }, + { 0xd7adf884, 0xaa879177, 0x5b0ed81d, -219 }, + { 0x86ccbb52, 0xea94baea, 0x98e94712, -215 }, + { 0xa87fea27, 0xa539e9a5, 0x3f2398d7, -212 }, + { 0xd29fe4b1, 0x8e88640e, 0x8eec7f0d, -209 }, + { 0x83a3eeee, 0xf9153e89, 0x1953cf68, -205 }, + { 0xa48ceaaa, 0xb75a8e2b, 0x5fa8c342, -202 }, + { 0xcdb02555, 0x653131b6, 0x3792f412, -199 }, + { 0x808e1755, 0x5f3ebf11, 0xe2bbd88b, -195 }, + { 0xa0b19d2a, 0xb70e6ed6, 0x5b6aceae, -192 }, + { 0xc8de0475, 0x64d20a8b, 0xf245825a, -189 }, + { 0xfb158592, 0xbe068d2e, 0xeed6e2f0, -186 }, + { 0x9ced737b, 0xb6c4183d, 0x55464dd6, -182 }, + { 0xc428d05a, 0xa4751e4c, 0xaa97e14c, -179 }, + { 0xf5330471, 0x4d9265df, 0xd53dd99f, -176 }, + { 0x993fe2c6, 0xd07b7fab, 0xe546a803, -172 }, + { 0xbf8fdb78, 0x849a5f96, 0xde985204, -169 }, + { 0xef73d256, 0xa5c0f77c, 0x963e6685, -166 }, + { 0x95a86376, 0x27989aad, 0xdde70013, -162 }, + { 0xbb127c53, 0xb17ec159, 0x5560c018, -159 }, + { 0xe9d71b68, 0x9dde71af, 0xaab8f01e, -156 }, + { 0x92267121, 0x62ab070d, 0xcab39613, -152 }, + { 0xb6b00d69, 0xbb55c8d1, 0x3d607b97, -149 }, + { 0xe45c10c4, 0x2a2b3b05, 0x8cb89a7d, -146 }, + { 0x8eb98a7a, 0x9a5b04e3, 0x77f3608e, -142 }, + { 0xb267ed19, 0x40f1c61c, 0x55f038b2, -139 }, + { 0xdf01e85f, 0x912e37a3, 0x6b6c46de, -136 }, + { 0x8b61313b, 0xbabce2c6, 0x2323ac4b, -132 }, + { 0xae397d8a, 0xa96c1b77, 0xabec975e, -129 }, + { 0xd9c7dced, 0x53c72255, 0x96e7bd35, -126 }, + { 0x881cea14, 0x545c7575, 0x7e50d641, -122 }, + { 0xaa242499, 0x697392d2, 0xdde50bd1, -119 }, + { 0xd4ad2dbf, 0xc3d07787, 0x955e4ec6, -116 }, + { 0x84ec3c97, 0xda624ab4, 0xbd5af13b, -112 }, + { 0xa6274bbd, 0xd0fadd61, 0xecb1ad8a, -109 }, + { 0xcfb11ead, 0x453994ba, 0x67de18ed, -106 }, + { 0x81ceb32c, 0x4b43fcf4, 0x80eacf94, -102 }, + { 0xa2425ff7, 0x5e14fc31, 0xa1258379, -99 }, + { 0xcad2f7f5, 0x359a3b3e, 0x096ee458, -96 }, + { 0xfd87b5f2, 0x8300ca0d, 0x8bca9d6e, -93 }, + { 0x9e74d1b7, 0x91e07e48, 0x775ea264, -89 }, + { 0xc6120625, 0x76589dda, 0x95364afe, -86 }, + { 0xf79687ae, 0xd3eec551, 0x3a83ddbd, -83 }, + { 0x9abe14cd, 0x44753b52, 0xc4926a96, -79 }, + { 0xc16d9a00, 0x95928a27, 0x75b7053c, -76 }, + { 0xf1c90080, 0xbaf72cb1, 0x5324c68b, -73 }, + { 0x971da050, 0x74da7bee, 0xd3f6fc16, -69 }, + { 0xbce50864, 0x92111aea, 0x88f4bb1c, -66 }, + { 0xec1e4a7d, 0xb69561a5, 0x2b31e9e3, -63 }, + { 0x9392ee8e, 0x921d5d07, 0x3aff322e, -59 }, + { 0xb877aa32, 0x36a4b449, 0x09befeb9, -56 }, + { 0xe69594be, 0xc44de15b, 0x4c2ebe68, -53 }, + { 0x901d7cf7, 0x3ab0acd9, 0x0f9d3701, -49 }, + { 0xb424dc35, 0x095cd80f, 0x538484c1, -46 }, + { 0xe12e1342, 0x4bb40e13, 0x2865a5f2, -43 }, + { 0x8cbccc09, 0x6f5088cb, 0xf93f87b7, -39 }, + { 0xafebff0b, 0xcb24aafe, 0xf78f69a5, -36 }, + { 0xdbe6fece, 0xbdedd5be, 0xb573440e, -33 }, + { 0x89705f41, 0x36b4a597, 0x31680a88, -29 }, + { 0xabcc7711, 0x8461cefc, 0xfdc20d2b, -26 }, + { 0xd6bf94d5, 0xe57a42bc, 0x3d329076, -23 }, + { 0x8637bd05, 0xaf6c69b5, 0xa63f9a49, -19 }, + { 0xa7c5ac47, 0x1b478423, 0x0fcf80dc, -16 }, + { 0xd1b71758, 0xe219652b, 0xd3c36113, -13 }, + { 0x83126e97, 0x8d4fdf3b, 0x645a1cac, -9 }, + { 0xa3d70a3d, 0x70a3d70a, 0x3d70a3d7, -6 }, + { 0xcccccccc, 0xcccccccc, 0xcccccccc, -3 }, + { 0x80000000, 0x00000000, 0x00000000, 1 }, + { 0xa0000000, 0x00000000, 0x00000000, 4 }, + { 0xc8000000, 0x00000000, 0x00000000, 7 }, + { 0xfa000000, 0x00000000, 0x00000000, 10 }, + { 0x9c400000, 0x00000000, 0x00000000, 14 }, + { 0xc3500000, 0x00000000, 0x00000000, 17 }, + { 0xf4240000, 0x00000000, 0x00000000, 20 }, + { 0x98968000, 0x00000000, 0x00000000, 24 }, + { 0xbebc2000, 0x00000000, 0x00000000, 27 }, + { 0xee6b2800, 0x00000000, 0x00000000, 30 }, + { 0x9502f900, 0x00000000, 0x00000000, 34 }, + { 0xba43b740, 0x00000000, 0x00000000, 37 }, + { 0xe8d4a510, 0x00000000, 0x00000000, 40 }, + { 0x9184e72a, 0x00000000, 0x00000000, 44 }, + { 0xb5e620f4, 0x80000000, 0x00000000, 47 }, + { 0xe35fa931, 0xa0000000, 0x00000000, 50 }, + { 0x8e1bc9bf, 0x04000000, 0x00000000, 54 }, + { 0xb1a2bc2e, 0xc5000000, 0x00000000, 57 }, + { 0xde0b6b3a, 0x76400000, 0x00000000, 60 }, + { 0x8ac72304, 0x89e80000, 0x00000000, 64 }, + { 0xad78ebc5, 0xac620000, 0x00000000, 67 }, + { 0xd8d726b7, 0x177a8000, 0x00000000, 70 }, + { 0x87867832, 0x6eac9000, 0x00000000, 74 }, + { 0xa968163f, 0x0a57b400, 0x00000000, 77 }, + { 0xd3c21bce, 0xcceda100, 0x00000000, 80 }, + { 0x84595161, 0x401484a0, 0x00000000, 84 }, + { 0xa56fa5b9, 0x9019a5c8, 0x00000000, 87 }, + { 0xcecb8f27, 0xf4200f3a, 0x00000000, 90 }, + { 0x813f3978, 0xf8940984, 0x40000000, 94 }, + { 0xa18f07d7, 0x36b90be5, 0x50000000, 97 }, + { 0xc9f2c9cd, 0x04674ede, 0xa4000000, 100 }, + { 0xfc6f7c40, 0x45812296, 0x4d000000, 103 }, + { 0x9dc5ada8, 0x2b70b59d, 0xf0200000, 107 }, + { 0xc5371912, 0x364ce305, 0x6c280000, 110 }, + { 0xf684df56, 0xc3e01bc6, 0xc7320000, 113 }, + { 0x9a130b96, 0x3a6c115c, 0x3c7f4000, 117 }, + { 0xc097ce7b, 0xc90715b3, 0x4b9f1000, 120 }, + { 0xf0bdc21a, 0xbb48db20, 0x1e86d400, 123 }, + { 0x96769950, 0xb50d88f4, 0x13144480, 127 }, + { 0xbc143fa4, 0xe250eb31, 0x17d955a0, 130 }, + { 0xeb194f8e, 0x1ae525fd, 0x5dcfab08, 133 }, + { 0x92efd1b8, 0xd0cf37be, 0x5aa1cae5, 137 }, + { 0xb7abc627, 0x050305ad, 0xf14a3d9e, 140 }, + { 0xe596b7b0, 0xc643c719, 0x6d9ccd05, 143 }, + { 0x8f7e32ce, 0x7bea5c6f, 0xe4820023, 147 }, + { 0xb35dbf82, 0x1ae4f38b, 0xdda2802c, 150 }, + { 0xe0352f62, 0xa19e306e, 0xd50b2037, 153 }, + { 0x8c213d9d, 0xa502de45, 0x4526f422, 157 }, + { 0xaf298d05, 0x0e4395d6, 0x9670b12b, 160 }, + { 0xdaf3f046, 0x51d47b4c, 0x3c0cdd76, 163 }, + { 0x88d8762b, 0xf324cd0f, 0xa5880a69, 167 }, + { 0xab0e93b6, 0xefee0053, 0x8eea0d04, 170 }, + { 0xd5d238a4, 0xabe98068, 0x72a49045, 173 }, + { 0x85a36366, 0xeb71f041, 0x47a6da2b, 177 }, + { 0xa70c3c40, 0xa64e6c51, 0x999090b6, 180 }, + { 0xd0cf4b50, 0xcfe20765, 0xfff4b4e3, 183 }, + { 0x82818f12, 0x81ed449f, 0xbff8f10e, 187 }, + { 0xa321f2d7, 0x226895c7, 0xaff72d52, 190 }, + { 0xcbea6f8c, 0xeb02bb39, 0x9bf4f8a6, 193 }, + { 0xfee50b70, 0x25c36a08, 0x02f236d0, 196 }, + { 0x9f4f2726, 0x179a2245, 0x01d76242, 200 }, + { 0xc722f0ef, 0x9d80aad6, 0x424d3ad2, 203 }, + { 0xf8ebad2b, 0x84e0d58b, 0xd2e08987, 206 }, + { 0x9b934c3b, 0x330c8577, 0x63cc55f4, 210 }, + { 0xc2781f49, 0xffcfa6d5, 0x3cbf6b71, 213 }, + { 0xf316271c, 0x7fc3908a, 0x8bef464e, 216 }, + { 0x97edd871, 0xcfda3a56, 0x97758bf0, 220 }, + { 0xbde94e8e, 0x43d0c8ec, 0x3d52eeed, 223 }, + { 0xed63a231, 0xd4c4fb27, 0x4ca7aaa8, 226 }, + { 0x945e455f, 0x24fb1cf8, 0x8fe8caa9, 230 }, + { 0xb975d6b6, 0xee39e436, 0xb3e2fd53, 233 }, + { 0xe7d34c64, 0xa9c85d44, 0x60dbbca8, 236 }, + { 0x90e40fbe, 0xea1d3a4a, 0xbc8955e9, 240 }, + { 0xb51d13ae, 0xa4a488dd, 0x6babab63, 243 }, + { 0xe264589a, 0x4dcdab14, 0xc696963c, 246 }, + { 0x8d7eb760, 0x70a08aec, 0xfc1e1de5, 250 }, + { 0xb0de6538, 0x8cc8ada8, 0x3b25a55f, 253 }, + { 0xdd15fe86, 0xaffad912, 0x49ef0eb7, 256 }, + { 0x8a2dbf14, 0x2dfcc7ab, 0x6e356932, 260 }, + { 0xacb92ed9, 0x397bf996, 0x49c2c37f, 263 }, + { 0xd7e77a8f, 0x87daf7fb, 0xdc33745e, 266 }, + { 0x86f0ac99, 0xb4e8dafd, 0x69a028bb, 270 }, + { 0xa8acd7c0, 0x222311bc, 0xc40832ea, 273 }, + { 0xd2d80db0, 0x2aabd62b, 0xf50a3fa4, 276 }, + { 0x83c7088e, 0x1aab65db, 0x792667c6, 280 }, + { 0xa4b8cab1, 0xa1563f52, 0x577001b8, 283 }, + { 0xcde6fd5e, 0x09abcf26, 0xed4c0226, 286 }, + { 0x80b05e5a, 0xc60b6178, 0x544f8158, 290 }, + { 0xa0dc75f1, 0x778e39d6, 0x696361ae, 293 }, + { 0xc913936d, 0xd571c84c, 0x03bc3a19, 296 }, + { 0xfb587849, 0x4ace3a5f, 0x04ab48a0, 299 }, + { 0x9d174b2d, 0xcec0e47b, 0x62eb0d64, 303 }, + { 0xc45d1df9, 0x42711d9a, 0x3ba5d0bd, 306 }, + { 0xf5746577, 0x930d6500, 0xca8f44ec, 309 }, + { 0x9968bf6a, 0xbbe85f20, 0x7e998b13, 313 }, + { 0xbfc2ef45, 0x6ae276e8, 0x9e3fedd8, 316 }, + { 0xefb3ab16, 0xc59b14a2, 0xc5cfe94e, 319 }, + { 0x95d04aee, 0x3b80ece5, 0xbba1f1d1, 323 }, + { 0xbb445da9, 0xca61281f, 0x2a8a6e45, 326 }, + { 0xea157514, 0x3cf97226, 0xf52d09d7, 329 }, + { 0x924d692c, 0xa61be758, 0x593c2626, 333 }, + { 0xb6e0c377, 0xcfa2e12e, 0x6f8b2fb0, 336 }, + { 0xe498f455, 0xc38b997a, 0x0b6dfb9c, 339 }, + { 0x8edf98b5, 0x9a373fec, 0x4724bd41, 343 }, + { 0xb2977ee3, 0x00c50fe7, 0x58edec91, 346 }, + { 0xdf3d5e9b, 0xc0f653e1, 0x2f2967b6, 349 }, + { 0x8b865b21, 0x5899f46c, 0xbd79e0d2, 353 }, + { 0xae67f1e9, 0xaec07187, 0xecd85906, 356 }, + { 0xda01ee64, 0x1a708de9, 0xe80e6f48, 359 }, + { 0x884134fe, 0x908658b2, 0x3109058d, 363 }, + { 0xaa51823e, 0x34a7eede, 0xbd4b46f0, 366 }, + { 0xd4e5e2cd, 0xc1d1ea96, 0x6c9e18ac, 369 }, + { 0x850fadc0, 0x9923329e, 0x03e2cf6b, 373 }, + { 0xa6539930, 0xbf6bff45, 0x84db8346, 376 }, + { 0xcfe87f7c, 0xef46ff16, 0xe6126418, 379 }, + { 0x81f14fae, 0x158c5f6e, 0x4fcb7e8f, 383 }, + { 0xa26da399, 0x9aef7749, 0xe3be5e33, 386 }, + { 0xcb090c80, 0x01ab551c, 0x5cadf5bf, 389 }, + { 0xfdcb4fa0, 0x02162a63, 0x73d9732f, 392 }, + { 0x9e9f11c4, 0x014dda7e, 0x2867e7fd, 396 }, + { 0xc646d635, 0x01a1511d, 0xb281e1fd, 399 }, + { 0xf7d88bc2, 0x4209a565, 0x1f225a7c, 402 }, + { 0x9ae75759, 0x6946075f, 0x3375788d, 406 }, + { 0xc1a12d2f, 0xc3978937, 0x0052d6b1, 409 }, + { 0xf209787b, 0xb47d6b84, 0xc0678c5d, 412 }, + { 0x9745eb4d, 0x50ce6332, 0xf840b7ba, 416 }, + { 0xbd176620, 0xa501fbff, 0xb650e5a9, 419 }, + { 0xec5d3fa8, 0xce427aff, 0xa3e51f13, 422 }, + { 0x93ba47c9, 0x80e98cdf, 0xc66f336c, 426 }, + { 0xb8a8d9bb, 0xe123f017, 0xb80b0047, 429 }, + { 0xe6d3102a, 0xd96cec1d, 0xa60dc059, 432 }, + { 0x9043ea1a, 0xc7e41392, 0x87c89837, 436 }, + { 0xb454e4a1, 0x79dd1877, 0x29babe45, 439 }, + { 0xe16a1dc9, 0xd8545e94, 0xf4296dd6, 442 }, + { 0x8ce2529e, 0x2734bb1d, 0x1899e4a6, 446 }, + { 0xb01ae745, 0xb101e9e4, 0x5ec05dcf, 449 }, + { 0xdc21a117, 0x1d42645d, 0x76707543, 452 }, + { 0x899504ae, 0x72497eba, 0x6a06494a, 456 }, + { 0xabfa45da, 0x0edbde69, 0x0487db9d, 459 }, + { 0xd6f8d750, 0x9292d603, 0x45a9d284, 462 }, + { 0x865b8692, 0x5b9bc5c2, 0x0b8a2392, 466 }, + { 0xa7f26836, 0xf282b732, 0x8e6cac77, 469 }, + { 0xd1ef0244, 0xaf2364ff, 0x3207d795, 472 }, + { 0x8335616a, 0xed761f1f, 0x7f44e6bd, 476 }, + { 0xa402b9c5, 0xa8d3a6e7, 0x5f16206c, 479 }, + { 0xcd036837, 0x130890a1, 0x36dba887, 482 }, + { 0x80222122, 0x6be55a64, 0xc2494954, 486 }, + { 0xa02aa96b, 0x06deb0fd, 0xf2db9baa, 489 }, + { 0xc83553c5, 0xc8965d3d, 0x6f928294, 492 }, + { 0xfa42a8b7, 0x3abbf48c, 0xcb772339, 495 }, + { 0x9c69a972, 0x84b578d7, 0xff2a7604, 499 }, + { 0xc38413cf, 0x25e2d70d, 0xfef51385, 502 }, + { 0xf46518c2, 0xef5b8cd1, 0x7eb25866, 505 }, + { 0x98bf2f79, 0xd5993802, 0xef2f773f, 509 }, + { 0xbeeefb58, 0x4aff8603, 0xaafb550f, 512 }, + { 0xeeaaba2e, 0x5dbf6784, 0x95ba2a53, 515 }, + { 0x952ab45c, 0xfa97a0b2, 0xdd945a74, 519 }, + { 0xba756174, 0x393d88df, 0x94f97111, 522 }, + { 0xe912b9d1, 0x478ceb17, 0x7a37cd56, 525 }, + { 0x91abb422, 0xccb812ee, 0xac62e055, 529 }, + { 0xb616a12b, 0x7fe617aa, 0x577b986b, 532 }, + { 0xe39c4976, 0x5fdf9d94, 0xed5a7e85, 535 }, + { 0x8e41ade9, 0xfbebc27d, 0x14588f13, 539 }, + { 0xb1d21964, 0x7ae6b31c, 0x596eb2d8, 542 }, + { 0xde469fbd, 0x99a05fe3, 0x6fca5f8e, 545 }, + { 0x8aec23d6, 0x80043bee, 0x25de7bb9, 549 }, + { 0xada72ccc, 0x20054ae9, 0xaf561aa7, 552 }, + { 0xd910f7ff, 0x28069da4, 0x1b2ba151, 555 }, + { 0x87aa9aff, 0x79042286, 0x90fb44d2, 559 }, + { 0xa99541bf, 0x57452b28, 0x353a1607, 562 }, + { 0xd3fa922f, 0x2d1675f2, 0x42889b89, 565 }, + { 0x847c9b5d, 0x7c2e09b7, 0x69956135, 569 }, + { 0xa59bc234, 0xdb398c25, 0x43fab983, 572 }, + { 0xcf02b2c2, 0x1207ef2e, 0x94f967e4, 575 }, + { 0x8161afb9, 0x4b44f57d, 0x1d1be0ee, 579 }, + { 0xa1ba1ba7, 0x9e1632dc, 0x6462d92a, 582 }, + { 0xca28a291, 0x859bbf93, 0x7d7b8f75, 585 }, + { 0xfcb2cb35, 0xe702af78, 0x5cda7352, 588 }, + { 0x9defbf01, 0xb061adab, 0x3a088813, 592 }, + { 0xc56baec2, 0x1c7a1916, 0x088aaa18, 595 }, + { 0xf6c69a72, 0xa3989f5b, 0x8aad549e, 598 }, + { 0x9a3c2087, 0xa63f6399, 0x36ac54e2, 602 }, + { 0xc0cb28a9, 0x8fcf3c7f, 0x84576a1b, 605 }, + { 0xf0fdf2d3, 0xf3c30b9f, 0x656d44a2, 608 }, + { 0x969eb7c4, 0x7859e743, 0x9f644ae5, 612 }, + { 0xbc4665b5, 0x96706114, 0x873d5d9f, 615 }, + { 0xeb57ff22, 0xfc0c7959, 0xa90cb506, 618 }, + { 0x9316ff75, 0xdd87cbd8, 0x09a7f124, 622 }, + { 0xb7dcbf53, 0x54e9bece, 0x0c11ed6d, 625 }, + { 0xe5d3ef28, 0x2a242e81, 0x8f1668c8, 628 }, + { 0x8fa47579, 0x1a569d10, 0xf96e017d, 632 }, + { 0xb38d92d7, 0x60ec4455, 0x37c981dc, 635 }, + { 0xe070f78d, 0x3927556a, 0x85bbe253, 638 }, + { 0x8c469ab8, 0x43b89562, 0x93956d74, 642 }, + { 0xaf584166, 0x54a6babb, 0x387ac8d1, 645 }, + { 0xdb2e51bf, 0xe9d0696a, 0x06997b05, 648 }, + { 0x88fcf317, 0xf22241e2, 0x441fece3, 652 }, + { 0xab3c2fdd, 0xeeaad25a, 0xd527e81c, 655 }, + { 0xd60b3bd5, 0x6a5586f1, 0x8a71e223, 658 }, + { 0x85c70565, 0x62757456, 0xf6872d56, 662 }, + { 0xa738c6be, 0xbb12d16c, 0xb428f8ac, 665 }, + { 0xd106f86e, 0x69d785c7, 0xe13336d7, 668 }, + { 0x82a45b45, 0x0226b39c, 0xecc00246, 672 }, + { 0xa34d7216, 0x42b06084, 0x27f002d7, 675 }, + { 0xcc20ce9b, 0xd35c78a5, 0x31ec038d, 678 }, + { 0xff290242, 0xc83396ce, 0x7e670471, 681 }, + { 0x9f79a169, 0xbd203e41, 0x0f0062c6, 685 }, + { 0xc75809c4, 0x2c684dd1, 0x52c07b78, 688 }, + { 0xf92e0c35, 0x37826145, 0xa7709a56, 691 }, + { 0x9bbcc7a1, 0x42b17ccb, 0x88a66076, 695 }, + { 0xc2abf989, 0x935ddbfe, 0x6acff893, 698 }, + { 0xf356f7eb, 0xf83552fe, 0x0583f6b8, 701 }, + { 0x98165af3, 0x7b2153de, 0xc3727a33, 705 }, + { 0xbe1bf1b0, 0x59e9a8d6, 0x744f18c0, 708 }, + { 0xeda2ee1c, 0x7064130c, 0x1162def0, 711 }, + { 0x9485d4d1, 0xc63e8be7, 0x8addcb56, 715 }, + { 0xb9a74a06, 0x37ce2ee1, 0x6d953e2b, 718 }, + { 0xe8111c87, 0xc5c1ba99, 0xc8fa8db6, 721 }, + { 0x910ab1d4, 0xdb9914a0, 0x1d9c9892, 725 }, + { 0xb54d5e4a, 0x127f59c8, 0x2503beb6, 728 }, + { 0xe2a0b5dc, 0x971f303a, 0x2e44ae64, 731 }, + { 0x8da471a9, 0xde737e24, 0x5ceaecfe, 735 }, + { 0xb10d8e14, 0x56105dad, 0x7425a83e, 738 }, + { 0xdd50f199, 0x6b947518, 0xd12f124e, 741 }, + { 0x8a5296ff, 0xe33cc92f, 0x82bd6b70, 745 }, + { 0xace73cbf, 0xdc0bfb7b, 0x636cc64d, 748 }, + { 0xd8210bef, 0xd30efa5a, 0x3c47f7e0, 751 }, + { 0x8714a775, 0xe3e95c78, 0x65acfaec, 755 }, + { 0xa8d9d153, 0x5ce3b396, 0x7f1839a7, 758 }, + { 0xd31045a8, 0x341ca07c, 0x1ede4811, 761 }, + { 0x83ea2b89, 0x2091e44d, 0x934aed0a, 765 }, + { 0xa4e4b66b, 0x68b65d60, 0xf81da84d, 768 }, + { 0xce1de406, 0x42e3f4b9, 0x36251260, 771 }, + { 0x80d2ae83, 0xe9ce78f3, 0xc1d72b7c, 775 }, + { 0xa1075a24, 0xe4421730, 0xb24cf65b, 778 }, + { 0xc94930ae, 0x1d529cfc, 0xdee033f2, 781 }, + { 0xfb9b7cd9, 0xa4a7443c, 0x169840ef, 784 }, + { 0x9d412e08, 0x06e88aa5, 0x8e1f2895, 788 }, + { 0xc491798a, 0x08a2ad4e, 0xf1a6f2ba, 791 }, + { 0xf5b5d7ec, 0x8acb58a2, 0xae10af69, 794 }, + { 0x9991a6f3, 0xd6bf1765, 0xacca6da1, 798 }, + { 0xbff610b0, 0xcc6edd3f, 0x17fd090a, 801 }, + { 0xeff394dc, 0xff8a948e, 0xddfc4b4c, 804 }, + { 0x95f83d0a, 0x1fb69cd9, 0x4abdaf10, 808 }, + { 0xbb764c4c, 0xa7a4440f, 0x9d6d1ad4, 811 }, + { 0xea53df5f, 0xd18d5513, 0x84c86189, 814 }, + { 0x92746b9b, 0xe2f8552c, 0x32fd3cf5, 818 }, + { 0xb7118682, 0xdbb66a77, 0x3fbc8c33, 821 }, + { 0xe4d5e823, 0x92a40515, 0x0fabaf3f, 824 }, + { 0x8f05b116, 0x3ba6832d, 0x29cb4d87, 828 }, + { 0xb2c71d5b, 0xca9023f8, 0x743e20e9, 831 }, + { 0xdf78e4b2, 0xbd342cf6, 0x914da924, 834 }, + { 0x8bab8eef, 0xb6409c1a, 0x1ad089b6, 838 }, + { 0xae9672ab, 0xa3d0c320, 0xa184ac24, 841 }, + { 0xda3c0f56, 0x8cc4f3e8, 0xc9e5d72d, 844 }, + { 0x88658996, 0x17fb1871, 0x7e2fa67c, 848 }, + { 0xaa7eebfb, 0x9df9de8d, 0xddbb901b, 851 }, + { 0xd51ea6fa, 0x85785631, 0x552a7422, 854 }, + { 0x8533285c, 0x936b35de, 0xd53a8895, 858 }, + { 0xa67ff273, 0xb8460356, 0x8a892aba, 861 }, + { 0xd01fef10, 0xa657842c, 0x2d2b7569, 864 }, + { 0x8213f56a, 0x67f6b29b, 0x9c3b2962, 868 }, + { 0xa298f2c5, 0x01f45f42, 0x8349f3ba, 871 }, + { 0xcb3f2f76, 0x42717713, 0x241c70a9, 874 }, + { 0xfe0efb53, 0xd30dd4d7, 0xed238cd3, 877 }, + { 0x9ec95d14, 0x63e8a506, 0xf4363804, 881 }, + { 0xc67bb459, 0x7ce2ce48, 0xb143c605, 884 }, + { 0xf81aa16f, 0xdc1b81da, 0xdd94b786, 887 }, + { 0x9b10a4e5, 0xe9913128, 0xca7cf2b4, 891 }, + { 0xc1d4ce1f, 0x63f57d72, 0xfd1c2f61, 894 }, + { 0xf24a01a7, 0x3cf2dccf, 0xbc633b39, 897 }, + { 0x976e4108, 0x8617ca01, 0xd5be0503, 901 }, + { 0xbd49d14a, 0xa79dbc82, 0x4b2d8644, 904 }, + { 0xec9c459d, 0x51852ba2, 0xddf8e7d6, 907 }, + { 0x93e1ab82, 0x52f33b45, 0xcabb90e5, 911 }, + { 0xb8da1662, 0xe7b00a17, 0x3d6a751f, 914 }, + { 0xe7109bfb, 0xa19c0c9d, 0x0cc51267, 917 }, + { 0x906a617d, 0x450187e2, 0x27fb2b80, 921 }, + { 0xb484f9dc, 0x9641e9da, 0xb1f9f660, 924 }, + { 0xe1a63853, 0xbbd26451, 0x5e7873f8, 927 }, + { 0x8d07e334, 0x55637eb2, 0xdb0b487b, 931 }, + { 0xb049dc01, 0x6abc5e5f, 0x91ce1a9a, 934 }, + { 0xdc5c5301, 0xc56b75f7, 0x7641a140, 937 }, + { 0x89b9b3e1, 0x1b6329ba, 0xa9e904c8, 941 }, + { 0xac2820d9, 0x623bf429, 0x546345fa, 944 }, + { 0xd732290f, 0xbacaf133, 0xa97c1779, 947 }, + { 0x867f59a9, 0xd4bed6c0, 0x49ed8eab, 951 }, + { 0xa81f3014, 0x49ee8c70, 0x5c68f256, 954 }, + { 0xd226fc19, 0x5c6a2f8c, 0x73832eec, 957 }, + { 0x83585d8f, 0xd9c25db7, 0xc831fd53, 961 }, + { 0xa42e74f3, 0xd032f525, 0xba3e7ca8, 964 }, + { 0xcd3a1230, 0xc43fb26f, 0x28ce1bd2, 967 }, + { 0x80444b5e, 0x7aa7cf85, 0x7980d163, 971 }, + { 0xa0555e36, 0x1951c366, 0xd7e105bc, 974 }, + { 0xc86ab5c3, 0x9fa63440, 0x8dd9472b, 977 }, + { 0xfa856334, 0x878fc150, 0xb14f98f6, 980 }, + { 0x9c935e00, 0xd4b9d8d2, 0x6ed1bf9a, 984 }, + { 0xc3b83581, 0x09e84f07, 0x0a862f80, 987 }, + { 0xf4a642e1, 0x4c6262c8, 0xcd27bb61, 990 }, + { 0x98e7e9cc, 0xcfbd7dbd, 0x8038d51c, 994 }, + { 0xbf21e440, 0x03acdd2c, 0xe0470a63, 997 }, + { 0xeeea5d50, 0x04981478, 0x1858ccfc, 1000 }, + { 0x95527a52, 0x02df0ccb, 0x0f37801e, 1004 }, + { 0xbaa718e6, 0x8396cffd, 0xd3056025, 1007 }, + { 0xe950df20, 0x247c83fd, 0x47c6b82e, 1010 }, + { 0x91d28b74, 0x16cdd27e, 0x4cdc331d, 1014 }, + { 0xb6472e51, 0x1c81471d, 0xe0133fe4, 1017 }, + { 0xe3d8f9e5, 0x63a198e5, 0x58180fdd, 1020 }, + { 0x8e679c2f, 0x5e44ff8f, 0x570f09ea, 1024 }, + { 0xb201833b, 0x35d63f73, 0x2cd2cc65, 1027 }, + { 0xde81e40a, 0x034bcf4f, 0xf8077f7e, 1030 }, + { 0x8b112e86, 0x420f6191, 0xfb04afaf, 1034 }, + { 0xadd57a27, 0xd29339f6, 0x79c5db9a, 1037 }, + { 0xd94ad8b1, 0xc7380874, 0x18375281, 1040 }, + { 0x87cec76f, 0x1c830548, 0x8f229391, 1044 }, + { 0xa9c2794a, 0xe3a3c69a, 0xb2eb3875, 1047 }, + { 0xd433179d, 0x9c8cb841, 0x5fa60692, 1050 }, + { 0x849feec2, 0x81d7f328, 0xdbc7c41b, 1054 }, + { 0xa5c7ea73, 0x224deff3, 0x12b9b522, 1057 }, + { 0xcf39e50f, 0xeae16bef, 0xd768226b, 1060 }, + { 0x81842f29, 0xf2cce375, 0xe6a11583, 1064 }, + { 0xa1e53af4, 0x6f801c53, 0x60495ae3, 1067 }, + { 0xca5e89b1, 0x8b602368, 0x385bb19c, 1070 }, + { 0xfcf62c1d, 0xee382c42, 0x46729e03, 1073 }, + { 0x9e19db92, 0xb4e31ba9, 0x6c07a2c2, 1077 } + }; + static const short int Lhint[2098] = { + /*18,*/19, 19, 19, 19, 20, 20, 20, 21, 21, + 21, 22, 22, 22, 23, 23, 23, 23, 24, 24, + 24, 25, 25, 25, 26, 26, 26, 26, 27, 27, + 27, 28, 28, 28, 29, 29, 29, 29, 30, 30, + 30, 31, 31, 31, 32, 32, 32, 32, 33, 33, + 33, 34, 34, 34, 35, 35, 35, 35, 36, 36, + 36, 37, 37, 37, 38, 38, 38, 38, 39, 39, + 39, 40, 40, 40, 41, 41, 41, 41, 42, 42, + 42, 43, 43, 43, 44, 44, 44, 44, 45, 45, + 45, 46, 46, 46, 47, 47, 47, 47, 48, 48, + 48, 49, 49, 49, 50, 50, 50, 51, 51, 51, + 51, 52, 52, 52, 53, 53, 53, 54, 54, 54, + 54, 55, 55, 55, 56, 56, 56, 57, 57, 57, + 57, 58, 58, 58, 59, 59, 59, 60, 60, 60, + 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, + 63, 64, 64, 64, 65, 65, 65, 66, 66, 66, + 66, 67, 67, 67, 68, 68, 68, 69, 69, 69, + 69, 70, 70, 70, 71, 71, 71, 72, 72, 72, + 72, 73, 73, 73, 74, 74, 74, 75, 75, 75, + 75, 76, 76, 76, 77, 77, 77, 78, 78, 78, + 78, 79, 79, 79, 80, 80, 80, 81, 81, 81, + 82, 82, 82, 82, 83, 83, 83, 84, 84, 84, + 85, 85, 85, 85, 86, 86, 86, 87, 87, 87, + 88, 88, 88, 88, 89, 89, 89, 90, 90, 90, + 91, 91, 91, 91, 92, 92, 92, 93, 93, 93, + 94, 94, 94, 94, 95, 95, 95, 96, 96, 96, + 97, 97, 97, 97, 98, 98, 98, 99, 99, 99, + 100, 100, 100, 100, 101, 101, 101, 102, 102, 102, + 103, 103, 103, 103, 104, 104, 104, 105, 105, 105, + 106, 106, 106, 106, 107, 107, 107, 108, 108, 108, + 109, 109, 109, 110, 110, 110, 110, 111, 111, 111, + 112, 112, 112, 113, 113, 113, 113, 114, 114, 114, + 115, 115, 115, 116, 116, 116, 116, 117, 117, 117, + 118, 118, 118, 119, 119, 119, 119, 120, 120, 120, + 121, 121, 121, 122, 122, 122, 122, 123, 123, 123, + 124, 124, 124, 125, 125, 125, 125, 126, 126, 126, + 127, 127, 127, 128, 128, 128, 128, 129, 129, 129, + 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, + 133, 133, 133, 134, 134, 134, 134, 135, 135, 135, + 136, 136, 136, 137, 137, 137, 137, 138, 138, 138, + 139, 139, 139, 140, 140, 140, 141, 141, 141, 141, + 142, 142, 142, 143, 143, 143, 144, 144, 144, 144, + 145, 145, 145, 146, 146, 146, 147, 147, 147, 147, + 148, 148, 148, 149, 149, 149, 150, 150, 150, 150, + 151, 151, 151, 152, 152, 152, 153, 153, 153, 153, + 154, 154, 154, 155, 155, 155, 156, 156, 156, 156, + 157, 157, 157, 158, 158, 158, 159, 159, 159, 159, + 160, 160, 160, 161, 161, 161, 162, 162, 162, 162, + 163, 163, 163, 164, 164, 164, 165, 165, 165, 165, + 166, 166, 166, 167, 167, 167, 168, 168, 168, 169, + 169, 169, 169, 170, 170, 170, 171, 171, 171, 172, + 172, 172, 172, 173, 173, 173, 174, 174, 174, 175, + 175, 175, 175, 176, 176, 176, 177, 177, 177, 178, + 178, 178, 178, 179, 179, 179, 180, 180, 180, 181, + 181, 181, 181, 182, 182, 182, 183, 183, 183, 184, + 184, 184, 184, 185, 185, 185, 186, 186, 186, 187, + 187, 187, 187, 188, 188, 188, 189, 189, 189, 190, + 190, 190, 190, 191, 191, 191, 192, 192, 192, 193, + 193, 193, 193, 194, 194, 194, 195, 195, 195, 196, + 196, 196, 197, 197, 197, 197, 198, 198, 198, 199, + 199, 199, 200, 200, 200, 200, 201, 201, 201, 202, + 202, 202, 203, 203, 203, 203, 204, 204, 204, 205, + 205, 205, 206, 206, 206, 206, 207, 207, 207, 208, + 208, 208, 209, 209, 209, 209, 210, 210, 210, 211, + 211, 211, 212, 212, 212, 212, 213, 213, 213, 214, + 214, 214, 215, 215, 215, 215, 216, 216, 216, 217, + 217, 217, 218, 218, 218, 218, 219, 219, 219, 220, + 220, 220, 221, 221, 221, 221, 222, 222, 222, 223, + 223, 223, 224, 224, 224, 224, 225, 225, 225, 226, + 226, 226, 227, 227, 227, 228, 228, 228, 228, 229, + 229, 229, 230, 230, 230, 231, 231, 231, 231, 232, + 232, 232, 233, 233, 233, 234, 234, 234, 234, 235, + 235, 235, 236, 236, 236, 237, 237, 237, 237, 238, + 238, 238, 239, 239, 239, 240, 240, 240, 240, 241, + 241, 241, 242, 242, 242, 243, 243, 243, 243, 244, + 244, 244, 245, 245, 245, 246, 246, 246, 246, 247, + 247, 247, 248, 248, 248, 249, 249, 249, 249, 250, + 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, + 253, 253, 254, 254, 254, 255, 255, 255, 256, 256, + 256, 256, 257, 257, 257, 258, 258, 258, 259, 259, + 259, 259, 260, 260, 260, 261, 261, 261, 262, 262, + 262, 262, 263, 263, 263, 264, 264, 264, 265, 265, + 265, 265, 266, 266, 266, 267, 267, 267, 268, 268, + 268, 268, 269, 269, 269, 270, 270, 270, 271, 271, + 271, 271, 272, 272, 272, 273, 273, 273, 274, 274, + 274, 274, 275, 275, 275, 276, 276, 276, 277, 277, + 277, 277, 278, 278, 278, 279, 279, 279, 280, 280, + 280, 280, 281, 281, 281, 282, 282, 282, 283, 283, + 283, 283, 284, 284, 284, 285, 285, 285, 286, 286, + 286, 287, 287, 287, 287, 288, 288, 288, 289, 289, + 289, 290, 290, 290, 290, 291, 291, 291, 292, 292, + 292, 293, 293, 293, 293, 294, 294, 294, 295, 295, + 295, 296, 296, 296, 296, 297, 297, 297, 298, 298, + 298, 299, 299, 299, 299, 300, 300, 300, 301, 301, + 301, 302, 302, 302, 302, 303, 303, 303, 304, 304, + 304, 305, 305, 305, 305, 306, 306, 306, 307, 307, + 307, 308, 308, 308, 308, 309, 309, 309, 310, 310, + 310, 311, 311, 311, 311, 312, 312, 312, 313, 313, + 313, 314, 314, 314, 315, 315, 315, 315, 316, 316, + 316, 317, 317, 317, 318, 318, 318, 318, 319, 319, + 319, 320, 320, 320, 321, 321, 321, 321, 322, 322, + 322, 323, 323, 323, 324, 324, 324, 324, 325, 325, + 325, 326, 326, 326, 327, 327, 327, 327, 328, 328, + 328, 329, 329, 329, 330, 330, 330, 330, 331, 331, + 331, 332, 332, 332, 333, 333, 333, 333, 334, 334, + 334, 335, 335, 335, 336, 336, 336, 336, 337, 337, + 337, 338, 338, 338, 339, 339, 339, 339, 340, 340, + 340, 341, 341, 341, 342, 342, 342, 342, 343, 343, + 343, 344, 344, 344, 345, 345, 345, 346, 346, 346, + 346, 347, 347, 347, 348, 348, 348, 349, 349, 349, + 349, 350, 350, 350, 351, 351, 351, 352, 352, 352, + 352, 353, 353, 353, 354, 354, 354, 355, 355, 355, + 355, 356, 356, 356, 357, 357, 357, 358, 358, 358, + 358, 359, 359, 359, 360, 360, 360, 361, 361, 361, + 361, 362, 362, 362, 363, 363, 363, 364, 364, 364, + 364, 365, 365, 365, 366, 366, 366, 367, 367, 367, + 367, 368, 368, 368, 369, 369, 369, 370, 370, 370, + 370, 371, 371, 371, 372, 372, 372, 373, 373, 373, + 374, 374, 374, 374, 375, 375, 375, 376, 376, 376, + 377, 377, 377, 377, 378, 378, 378, 379, 379, 379, + 380, 380, 380, 380, 381, 381, 381, 382, 382, 382, + 383, 383, 383, 383, 384, 384, 384, 385, 385, 385, + 386, 386, 386, 386, 387, 387, 387, 388, 388, 388, + 389, 389, 389, 389, 390, 390, 390, 391, 391, 391, + 392, 392, 392, 392, 393, 393, 393, 394, 394, 394, + 395, 395, 395, 395, 396, 396, 396, 397, 397, 397, + 398, 398, 398, 398, 399, 399, 399, 400, 400, 400, + 401, 401, 401, 402, 402, 402, 402, 403, 403, 403, + 404, 404, 404, 405, 405, 405, 405, 406, 406, 406, + 407, 407, 407, 408, 408, 408, 408, 409, 409, 409, + 410, 410, 410, 411, 411, 411, 411, 412, 412, 412, + 413, 413, 413, 414, 414, 414, 414, 415, 415, 415, + 416, 416, 416, 417, 417, 417, 417, 418, 418, 418, + 419, 419, 419, 420, 420, 420, 420, 421, 421, 421, + 422, 422, 422, 423, 423, 423, 423, 424, 424, 424, + 425, 425, 425, 426, 426, 426, 426, 427, 427, 427, + 428, 428, 428, 429, 429, 429, 429, 430, 430, 430, + 431, 431, 431, 432, 432, 432, 433, 433, 433, 433, + 434, 434, 434, 435, 435, 435, 436, 436, 436, 436, + 437, 437, 437, 438, 438, 438, 439, 439, 439, 439, + 440, 440, 440, 441, 441, 441, 442, 442, 442, 442, + 443, 443, 443, 444, 444, 444, 445, 445, 445, 445, + 446, 446, 446, 447, 447, 447, 448, 448, 448, 448, + 449, 449, 449, 450, 450, 450, 451, 451, 451, 451, + 452, 452, 452, 453, 453, 453, 454, 454, 454, 454, + 455, 455, 455, 456, 456, 456, 457, 457, 457, 457, + 458, 458, 458, 459, 459, 459, 460, 460, 460, 461, + 461, 461, 461, 462, 462, 462, 463, 463, 463, 464, + 464, 464, 464, 465, 465, 465, 466, 466, 466, 467, + 467, 467, 467, 468, 468, 468, 469, 469, 469, 470, + 470, 470, 470, 471, 471, 471, 472, 472, 472, 473, + 473, 473, 473, 474, 474, 474, 475, 475, 475, 476, + 476, 476, 476, 477, 477, 477, 478, 478, 478, 479, + 479, 479, 479, 480, 480, 480, 481, 481, 481, 482, + 482, 482, 482, 483, 483, 483, 484, 484, 484, 485, + 485, 485, 485, 486, 486, 486, 487, 487, 487, 488, + 488, 488, 488, 489, 489, 489, 490, 490, 490, 491, + 491, 491, 492, 492, 492, 492, 493, 493, 493, 494, + 494, 494, 495, 495, 495, 495, 496, 496, 496, 497, + 497, 497, 498, 498, 498, 498, 499, 499, 499, 500, + 500, 500, 501, 501, 501, 501, 502, 502, 502, 503, + 503, 503, 504, 504, 504, 504, 505, 505, 505, 506, + 506, 506, 507, 507, 507, 507, 508, 508, 508, 509, + 509, 509, 510, 510, 510, 510, 511, 511, 511, 512, + 512, 512, 513, 513, 513, 513, 514, 514, 514, 515, + 515, 515, 516, 516, 516, 516, 517, 517, 517, 518, + 518, 518, 519, 519, 519, 520, 520, 520, 520, 521, + 521, 521, 522, 522, 522, 523, 523, 523, 523, 524, + 524, 524, 525, 525, 525, 526, 526, 526, 526, 527, + 527, 527, 528, 528, 528, 529, 529, 529, 529, 530, + 530, 530, 531, 531, 531, 532, 532, 532, 532, 533, + 533, 533, 534, 534, 534, 535, 535, 535, 535, 536, + 536, 536, 537, 537, 537, 538, 538, 538, 538, 539, + 539, 539, 540, 540, 540, 541, 541, 541, 541, 542, + 542, 542, 543, 543, 543, 544, 544, 544, 544, 545, + 545, 545, 546, 546, 546, 547, 547, 547, 548, 548, + 548, 548, 549, 549, 549, 550, 550, 550, 551, 551, + 551, 551, 552, 552, 552, 553, 553, 553, 554, 554, + 554, 554, 555, 555, 555, 556, 556, 556, 557, 557, + 557, 557, 558, 558, 558, 559, 559, 559, 560, 560, + 560, 560, 561, 561, 561, 562, 562, 562, 563, 563, + 563, 563, 564, 564, 564, 565, 565, 565, 566, 566, + 566, 566, 567, 567, 567, 568, 568, 568, 569, 569, + 569, 569, 570, 570, 570, 571, 571, 571, 572, 572, + 572, 572, 573, 573, 573, 574, 574, 574, 575, 575, + 575, 575, 576, 576, 576, 577, 577, 577, 578, 578, + 578, 579, 579, 579, 579, 580, 580, 580, 581, 581, + 581, 582, 582, 582, 582, 583, 583, 583, 584, 584, + 584, 585, 585, 585, 585, 586, 586, 586, 587, 587, + 587, 588, 588, 588, 588, 589, 589, 589, 590, 590, + 590, 591, 591, 591, 591, 592, 592, 592, 593, 593, + 593, 594, 594, 594, 594, 595, 595, 595, 596, 596, + 596, 597, 597, 597, 597, 598, 598, 598, 599, 599, + 599, 600, 600, 600, 600, 601, 601, 601, 602, 602, + 602, 603, 603, 603, 603, 604, 604, 604, 605, 605, + 605, 606, 606, 606, 607, 607, 607, 607, 608, 608, + 608, 609, 609, 609, 610, 610, 610, 610, 611, 611, + 611, 612, 612, 612, 613, 613, 613, 613, 614, 614, + 614, 615, 615, 615, 616, 616, 616, 616, 617, 617, + 617, 618, 618, 618, 619, 619, 619, 619, 620, 620, + 620, 621, 621, 621, 622, 622, 622, 622, 623, 623, + 623, 624, 624, 624, 625, 625, 625, 625, 626, 626, + 626, 627, 627, 627, 628, 628, 628, 628, 629, 629, + 629, 630, 630, 630, 631, 631, 631, 631, 632, 632, + 632, 633, 633, 633, 634, 634, 634, 634, 635, 635, + 635, 636, 636, 636, 637, 637, 637, 638, 638, 638, + 638, 639, 639, 639, 640, 640, 640, 641, 641, 641, + 641, 642, 642, 642, 643, 643, 643, 644, 644, 644, + 644, 645, 645, 645, 646, 646, 646, 647, 647, 647, + 647, 648, 648, 648, 649, 649, 649, 650, 650 }; + static ULLong pfive[27] = { + 5ll, + 25ll, + 125ll, + 625ll, + 3125ll, + 15625ll, + 78125ll, + 390625ll, + 1953125ll, + 9765625ll, + 48828125ll, + 244140625ll, + 1220703125ll, + 6103515625ll, + 30517578125ll, + 152587890625ll, + 762939453125ll, + 3814697265625ll, + 19073486328125ll, + 95367431640625ll, + 476837158203125ll, + 2384185791015625ll, + 11920928955078125ll, + 59604644775390625ll, + 298023223876953125ll, + 1490116119384765625ll, + 7450580596923828125ll + }; + + static int pfivebits[25] = {3, 5, 7, 10, 12, 14, 17, 19, 21, 24, 26, 28, 31, + 33, 35, 38, 40, 42, 45, 47, 49, 52, 54, 56, 59}; +#endif /*}*/ +#endif /*}} NO_LONG_LONG */ + +typedef union { double d; ULong L[2]; +#ifdef USE_BF96 + ULLong LL; +#endif + } U; + +#ifdef IEEE_8087 +#define word0(x) (x)->L[1] +#define word1(x) (x)->L[0] +#else +#define word0(x) (x)->L[0] +#define word1(x) (x)->L[1] +#endif +#define dval(x) (x)->d +#define LLval(x) (x)->LL + +#ifndef STRTOD_DIGLIM +#define STRTOD_DIGLIM 40 +#endif + +#ifdef DIGLIM_DEBUG +extern int strtod_diglim; +#else +#define strtod_diglim STRTOD_DIGLIM +#endif + +/* The following definition of Storeinc is appropriate for MIPS processors. + * An alternative that might be better on some machines is + * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) + */ +#if defined(IEEE_8087) + defined(VAX) +#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ +((unsigned short *)a)[0] = (unsigned short)c, a++) +#else +#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ +((unsigned short *)a)[1] = (unsigned short)c, a++) +#endif + +/* #define P DBL_MANT_DIG */ +/* Ten_pmax = floor(P*log(2)/log(5)) */ +/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ +/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ +/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ + +#ifdef IEEE_Arith +#define Exp_shift 20 +#define Exp_shift1 20 +#define Exp_msk1 0x100000 +#define Exp_msk11 0x100000 +#define Exp_mask 0x7ff00000 +#define P 53 +#define Nbits 53 +#define Bias 1023 +#define Emax 1023 +#define Emin (-1022) +#define Exp_1 0x3ff00000 +#define Exp_11 0x3ff00000 +#define Ebits 11 +#define Frac_mask 0xfffff +#define Frac_mask1 0xfffff +#define Ten_pmax 22 +#define Bletch 0x10 +#define Bndry_mask 0xfffff +#define Bndry_mask1 0xfffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 1 +#define Tiny0 0 +#define Tiny1 1 +#define Quick_max 14 +#define Int_max 14 +#ifndef NO_IEEE_Scale +#define Avoid_Underflow +#ifdef Flush_Denorm /* debugging option */ +#undef Sudden_Underflow +#endif +#endif + +#ifndef Flt_Rounds +#ifdef FLT_ROUNDS +#define Flt_Rounds FLT_ROUNDS +#else +#define Flt_Rounds 1 +#endif +#endif /*Flt_Rounds*/ + +#ifdef Honor_FLT_ROUNDS +#undef Check_FLT_ROUNDS +#define Check_FLT_ROUNDS +#else +#define Rounding Flt_Rounds +#endif + +#else /* ifndef IEEE_Arith */ +#undef Check_FLT_ROUNDS +#undef Honor_FLT_ROUNDS +#undef SET_INEXACT +#undef Sudden_Underflow +#define Sudden_Underflow +#ifdef IBM +#undef Flt_Rounds +#define Flt_Rounds 0 +#define Exp_shift 24 +#define Exp_shift1 24 +#define Exp_msk1 0x1000000 +#define Exp_msk11 0x1000000 +#define Exp_mask 0x7f000000 +#define P 14 +#define Nbits 56 +#define Bias 65 +#define Emax 248 +#define Emin (-260) +#define Exp_1 0x41000000 +#define Exp_11 0x41000000 +#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ +#define Frac_mask 0xffffff +#define Frac_mask1 0xffffff +#define Bletch 4 +#define Ten_pmax 22 +#define Bndry_mask 0xefffff +#define Bndry_mask1 0xffffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 4 +#define Tiny0 0x100000 +#define Tiny1 0 +#define Quick_max 14 +#define Int_max 15 +#else /* VAX */ +#undef Flt_Rounds +#define Flt_Rounds 1 +#define Exp_shift 23 +#define Exp_shift1 7 +#define Exp_msk1 0x80 +#define Exp_msk11 0x800000 +#define Exp_mask 0x7f80 +#define P 56 +#define Nbits 56 +#define Bias 129 +#define Emax 126 +#define Emin (-129) +#define Exp_1 0x40800000 +#define Exp_11 0x4080 +#define Ebits 8 +#define Frac_mask 0x7fffff +#define Frac_mask1 0xffff007f +#define Ten_pmax 24 +#define Bletch 2 +#define Bndry_mask 0xffff007f +#define Bndry_mask1 0xffff007f +#define LSB 0x10000 +#define Sign_bit 0x8000 +#define Log2P 1 +#define Tiny0 0x80 +#define Tiny1 0 +#define Quick_max 15 +#define Int_max 15 +#endif /* IBM, VAX */ +#endif /* IEEE_Arith */ + +#ifndef IEEE_Arith +#define ROUND_BIASED +#else +#ifdef ROUND_BIASED_without_Round_Up +#undef ROUND_BIASED +#define ROUND_BIASED +#endif +#endif + +#ifdef RND_PRODQUOT +#define rounded_product(a,b) a = rnd_prod(a, b) +#define rounded_quotient(a,b) a = rnd_quot(a, b) +extern double rnd_prod(double, double), rnd_quot(double, double); +#else +#define rounded_product(a,b) a *= b +#define rounded_quotient(a,b) a /= b +#endif + +#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) +#define Big1 0xffffffff + +#ifndef Pack_32 +#define Pack_32 +#endif + +typedef struct BCinfo BCinfo; + struct +BCinfo { int dp0, dp1, dplen, dsign, e0, inexact, nd, nd0, rounding, scale, uflchk; }; + +#define FFFFFFFF 0xffffffffUL + +#ifdef MULTIPLE_THREADS +#define MTa , PTI +#define MTb , &TI +#define MTd , ThInfo **PTI +static unsigned int maxthreads = 0; +#else +#define MTa /*nothing*/ +#define MTb /*nothing*/ +#define MTd /*nothing*/ +#endif + +#define Kmax 7 + +#ifdef __cplusplus +extern "C" double (strtod)(const char *s00, char **se); +extern "C" char *dtoa(double d, int mode, int ndigits, + int *decpt, int *sign, char **rve); +#endif + + struct +Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; + }; + + typedef struct Bigint Bigint; + typedef struct +ThInfo { + Bigint *Freelist[Kmax+1]; + Bigint *P5s; + } ThInfo; + + static ThInfo TI0; + +#ifdef MULTIPLE_THREADS + static ThInfo *TI1; + static int TI0_used; + + void +set_max_dtoa_threads(unsigned int n) +{ + size_t L; + + if (n > maxthreads) { + L = n*sizeof(ThInfo); + if (TI1) { + TI1 = (ThInfo*)REALLOC(TI1, L); + memset(TI1 + maxthreads, 0, (n-maxthreads)*sizeof(ThInfo)); + } + else { + TI1 = (ThInfo*)MALLOC(L); + if (TI0_used) { + memcpy(TI1, &TI0, sizeof(ThInfo)); + if (n > 1) + memset(TI1 + 1, 0, L - sizeof(ThInfo)); + memset(&TI0, 0, sizeof(ThInfo)); + } + else + memset(TI1, 0, L); + } + maxthreads = n; + } + } + + static ThInfo* +get_TI(void) +{ + unsigned int thno = dtoa_get_threadno(); + if (thno < maxthreads) + return TI1 + thno; + if (thno == 0) + TI0_used = 1; + return &TI0; + } +#define freelist TI->Freelist +#define p5s TI->P5s +#else +#define freelist TI0.Freelist +#define p5s TI0.P5s +#endif + + static Bigint * +Balloc(int k MTd) +{ + int x; + Bigint *rv; +#ifndef Omit_Private_Memory + unsigned int len; +#endif +#ifdef MULTIPLE_THREADS + ThInfo *TI; + + if (!(TI = *PTI)) + *PTI = TI = get_TI(); + if (TI == &TI0) + ACQUIRE_DTOA_LOCK(0); +#endif + /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ + /* but this case seems very unlikely. */ + if (k <= Kmax && (rv = freelist[k])) + freelist[k] = rv->next; + else { + x = 1u << k; +#ifdef Omit_Private_Memory + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); +#else + len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) + /sizeof(double); + if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem +#ifdef MULTIPLE_THREADS + && TI == TI1 +#endif + ) { + rv = (Bigint*)pmem_next; + pmem_next += len; + } + else + rv = (Bigint*)MALLOC(len*sizeof(double)); +#endif + rv->k = k; + rv->maxwds = x; + } +#ifdef MULTIPLE_THREADS + if (TI == &TI0) + FREE_DTOA_LOCK(0); +#endif + rv->sign = rv->wds = 0; + return rv; + } + + static void +Bfree(Bigint *v MTd) +{ +#ifdef MULTIPLE_THREADS + ThInfo *TI; +#endif + if (v) { + if (v->k > Kmax) + FREE((void*)v); + else { +#ifdef MULTIPLE_THREADS + if (!(TI = *PTI)) + *PTI = TI = get_TI(); + if (TI == &TI0) + ACQUIRE_DTOA_LOCK(0); +#endif + v->next = freelist[v->k]; + freelist[v->k] = v; +#ifdef MULTIPLE_THREADS + if (TI == &TI0) + FREE_DTOA_LOCK(0); +#endif + } + } + } + +#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ +y->wds*sizeof(Long) + 2*sizeof(int)) + + static Bigint * +multadd(Bigint *b, int m, int a MTd) /* multiply by m and add a */ +{ + int i, wds; +#ifdef ULLong + ULong *x; + ULLong carry, y; +#else + ULong carry, *x, y; +#ifdef Pack_32 + ULong xi, z; +#endif +#endif + Bigint *b1; + + wds = b->wds; + x = b->x; + i = 0; + carry = a; + do { +#ifdef ULLong + y = *x * (ULLong)m + carry; + carry = y >> 32; + *x++ = y & FFFFFFFF; +#else +#ifdef Pack_32 + xi = *x; + y = (xi & 0xffff) * m + carry; + z = (xi >> 16) * m + (y >> 16); + carry = z >> 16; + *x++ = (z << 16) + (y & 0xffff); +#else + y = *x * m + carry; + carry = y >> 16; + *x++ = y & 0xffff; +#endif +#endif + } + while(++i < wds); + if (carry) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1 MTa); + Bcopy(b1, b); + Bfree(b MTa); + b = b1; + } + b->x[wds++] = carry; + b->wds = wds; + } + return b; + } + + static Bigint * +s2b(const char *s, int nd0, int nd, ULong y9, int dplen MTd) +{ + Bigint *b; + int i, k; + Long x, y; + + x = (nd + 8) / 9; + for(k = 0, y = 1; x > y; y <<= 1, k++) ; +#ifdef Pack_32 + b = Balloc(k MTa); + b->x[0] = y9; + b->wds = 1; +#else + b = Balloc(k+1 MTa); + b->x[0] = y9 & 0xffff; + b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; +#endif + + i = 9; + if (9 < nd0) { + s += 9; + do b = multadd(b, 10, *s++ - '0' MTa); + while(++i < nd0); + s += dplen; + } + else + s += dplen + 9; + for(; i < nd; i++) + b = multadd(b, 10, *s++ - '0' MTa); + return b; + } + + static int +hi0bits(ULong x) +{ + int k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) + return 32; + } + return k; + } + + static int +lo0bits(ULong *y) +{ + int k; + ULong x = *y; + + if (x & 7) { + if (x & 1) + return 0; + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x) + return 32; + } + *y = x; + return k; + } + + static Bigint * +i2b(int i MTd) +{ + Bigint *b; + + b = Balloc(1 MTa); + b->x[0] = i; + b->wds = 1; + return b; + } + + static Bigint * +mult(Bigint *a, Bigint *b MTd) +{ + Bigint *c; + int k, wa, wb, wc; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; + ULong y; +#ifdef ULLong + ULLong carry, z; +#else + ULong carry, z; +#ifdef Pack_32 + ULong z2; +#endif +#endif + + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + k++; + c = Balloc(k MTa); + for(x = c->x, xa = x + wc; x < xa; x++) + *x = 0; + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; +#ifdef ULLong + for(; xb < xbe; xc0++) { + if ((y = *xb++)) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * (ULLong)y + *xc + carry; + carry = z >> 32; + *xc++ = z & FFFFFFFF; + } + while(x < xae); + *xc = carry; + } + } +#else +#ifdef Pack_32 + for(; xb < xbe; xb++, xc0++) { + if (y = *xb & 0xffff) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } + while(x < xae); + *xc = carry; + } + if (y = *xb >> 16) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } + while(x < xae); + *xc = z2; + } + } +#else + for(; xb < xbe; xc0++) { + if (y = *xb++) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * y + *xc + carry; + carry = z >> 16; + *xc++ = z & 0xffff; + } + while(x < xae); + *xc = carry; + } + } +#endif +#endif + for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; + } + + static Bigint * +pow5mult(Bigint *b, int k MTd) +{ + Bigint *b1, *p5, *p51; +#ifdef MULTIPLE_THREADS + ThInfo *TI; +#endif + int i; + static int p05[3] = { 5, 25, 125 }; + + if ((i = k & 3)) + b = multadd(b, p05[i-1], 0 MTa); + + if (!(k >>= 2)) + return b; +#ifdef MULTIPLE_THREADS + if (!(TI = *PTI)) + *PTI = TI = get_TI(); +#endif + if (!(p5 = p5s)) { + /* first time */ +#ifdef MULTIPLE_THREADS + if (!(TI = *PTI)) + *PTI = TI = get_TI(); + if (TI == &TI0) + ACQUIRE_DTOA_LOCK(1); + if (!(p5 = p5s)) { + p5 = p5s = i2b(625 MTa); + p5->next = 0; + } + if (TI == &TI0) + FREE_DTOA_LOCK(1); +#else + p5 = p5s = i2b(625 MTa); + p5->next = 0; +#endif + } + for(;;) { + if (k & 1) { + b1 = mult(b, p5 MTa); + Bfree(b MTa); + b = b1; + } + if (!(k >>= 1)) + break; + if (!(p51 = p5->next)) { +#ifdef MULTIPLE_THREADS + if (!TI && !(TI = *PTI)) + *PTI = TI = get_TI(); + if (TI == &TI0) + ACQUIRE_DTOA_LOCK(1); + if (!(p51 = p5->next)) { + p51 = p5->next = mult(p5,p5 MTa); + p51->next = 0; + } + if (TI == &TI0) + FREE_DTOA_LOCK(1); +#else + p51 = p5->next = mult(p5,p5); + p51->next = 0; +#endif + } + p5 = p51; + } + return b; + } + + static Bigint * +lshift(Bigint *b, int k MTd) +{ + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; + +#ifdef Pack_32 + n = k >> 5; +#else + n = k >> 4; +#endif + k1 = b->k; + n1 = n + b->wds + 1; + for(i = b->maxwds; n1 > i; i <<= 1) + k1++; + b1 = Balloc(k1 MTa); + x1 = b1->x; + for(i = 0; i < n; i++) + *x1++ = 0; + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + if (k &= 0x1f) { + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } + while(x < xe); + if ((*x1 = z)) + ++n1; + } +#else + if (k &= 0xf) { + k1 = 16 - k; + z = 0; + do { + *x1++ = *x << k & 0xffff | z; + z = *x++ >> k1; + } + while(x < xe); + if (*x1 = z) + ++n1; + } +#endif + else do + *x1++ = *x++; + while(x < xe); + b1->wds = n1 - 1; + Bfree(b MTa); + return b1; + } + + static int +cmp(Bigint *a, Bigint *b) +{ + ULong *xa, *xa0, *xb, *xb0; + int i, j; + + i = a->wds; + j = b->wds; +#ifdef DEBUG + if (i > 1 && !a->x[i-1]) + Bug("cmp called with a->x[a->wds-1] == 0"); + if (j > 1 && !b->x[j-1]) + Bug("cmp called with b->x[b->wds-1] == 0"); +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for(;;) { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; + } + + static Bigint * +diff(Bigint *a, Bigint *b MTd) +{ + Bigint *c; + int i, wa, wb; + ULong *xa, *xae, *xb, *xbe, *xc; +#ifdef ULLong + ULLong borrow, y; +#else + ULong borrow, y; +#ifdef Pack_32 + ULong z; +#endif +#endif + + i = cmp(a,b); + if (!i) { + c = Balloc(0 MTa); + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k MTa); + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; +#ifdef ULLong + do { + y = (ULLong)*xa++ - *xb++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = y & FFFFFFFF; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = y & FFFFFFFF; + } +#else +#ifdef Pack_32 + do { + y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } + while(xb < xbe); + while(xa < xae) { + y = (*xa & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ - *xb++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } +#endif +#endif + while(!*--xc) + wa--; + c->wds = wa; + return c; + } + + static double +ulp(U *x) +{ + Long L; + U u; + + L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; +#ifndef Avoid_Underflow +#ifndef Sudden_Underflow + if (L > 0) { +#endif +#endif +#ifdef IBM + L |= Exp_msk1 >> 4; +#endif + word0(&u) = L; + word1(&u) = 0; +#ifndef Avoid_Underflow +#ifndef Sudden_Underflow + } + else { + L = -L >> Exp_shift; + if (L < Exp_shift) { + word0(&u) = 0x80000 >> L; + word1(&u) = 0; + } + else { + word0(&u) = 0; + L -= Exp_shift; + word1(&u) = L >= 31 ? 1 : 1 << 31 - L; + } + } +#endif +#endif + return dval(&u); + } + + static double +b2d(Bigint *a, int *e) +{ + ULong *xa, *xa0, w, y, z; + int k; + U d; +#ifdef VAX + ULong d0, d1; +#else +#define d0 word0(&d) +#define d1 word1(&d) +#endif + + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; +#ifdef DEBUG + if (!y) Bug("zero y in b2d"); +#endif + k = hi0bits(y); + *e = 32 - k; +#ifdef Pack_32 + if (k < Ebits) { + d0 = Exp_1 | y >> (Ebits - k); + w = xa > xa0 ? *--xa : 0; + d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + d0 = Exp_1 | y << k | z >> (32 - k); + y = xa > xa0 ? *--xa : 0; + d1 = z << k | y >> (32 - k); + } + else { + d0 = Exp_1 | y; + d1 = z; + } +#else + if (k < Ebits + 16) { + z = xa > xa0 ? *--xa : 0; + d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; + w = xa > xa0 ? *--xa : 0; + y = xa > xa0 ? *--xa : 0; + d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + w = xa > xa0 ? *--xa : 0; + k -= Ebits + 16; + d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; + y = xa > xa0 ? *--xa : 0; + d1 = w << k + 16 | y << k; +#endif + ret_d: +#ifdef VAX + word0(&d) = d0 >> 16 | d0 << 16; + word1(&d) = d1 >> 16 | d1 << 16; +#else +#undef d0 +#undef d1 +#endif + return dval(&d); + } + + static Bigint * +d2b(U *d, int *e, int *bits MTd) +{ + Bigint *b; + int de, k; + ULong *x, y, z; +#ifndef Sudden_Underflow + int i; +#endif +#ifdef VAX + ULong d0, d1; + d0 = word0(d) >> 16 | word0(d) << 16; + d1 = word1(d) >> 16 | word1(d) << 16; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + +#ifdef Pack_32 + b = Balloc(1 MTa); +#else + b = Balloc(2 MTa); +#endif + x = b->x; + + z = d0 & Frac_mask; + d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ +#ifdef Sudden_Underflow + de = (int)(d0 >> Exp_shift); +#ifndef IBM + z |= Exp_msk11; +#endif +#else + if ((de = (int)(d0 >> Exp_shift))) + z |= Exp_msk1; +#endif +#ifdef Pack_32 + if ((y = d1)) { + if ((k = lo0bits(&y))) { + x[0] = y | z << (32 - k); + z >>= k; + } + else + x[0] = y; +#ifndef Sudden_Underflow + i = +#endif + b->wds = (x[1] = z) ? 2 : 1; + } + else { + k = lo0bits(&z); + x[0] = z; +#ifndef Sudden_Underflow + i = +#endif + b->wds = 1; + k += 32; + } +#else + if (y = d1) { + if (k = lo0bits(&y)) + if (k >= 16) { + x[0] = y | z << 32 - k & 0xffff; + x[1] = z >> k - 16 & 0xffff; + x[2] = z >> k; + i = 2; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16 | z << 16 - k & 0xffff; + x[2] = z >> k & 0xffff; + x[3] = z >> k+16; + i = 3; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16; + x[2] = z & 0xffff; + x[3] = z >> 16; + i = 3; + } + } + else { +#ifdef DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + if (k >= 16) { + x[0] = z; + i = 0; + } + else { + x[0] = z & 0xffff; + x[1] = z >> 16; + i = 1; + } + k += 32; + } + while(!x[i]) + --i; + b->wds = i + 1; +#endif +#ifndef Sudden_Underflow + if (de) { +#endif +#ifdef IBM + *e = (de - Bias - (P-1) << 2) + k; + *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); +#else + *e = de - Bias - (P-1) + k; + *bits = P - k; +#endif +#ifndef Sudden_Underflow + } + else { + *e = de - Bias - (P-1) + 1 + k; +#ifdef Pack_32 + *bits = 32*i - hi0bits(x[i-1]); +#else + *bits = (i+2)*16 - hi0bits(x[i]); +#endif + } +#endif + return b; + } +#undef d0 +#undef d1 + + static double +ratio(Bigint *a, Bigint *b) +{ + U da, db; + int k, ka, kb; + + dval(&da) = b2d(a, &ka); + dval(&db) = b2d(b, &kb); +#ifdef Pack_32 + k = ka - kb + 32*(a->wds - b->wds); +#else + k = ka - kb + 16*(a->wds - b->wds); +#endif +#ifdef IBM + if (k > 0) { + word0(&da) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(&da) *= 1u << k; + } + else { + k = -k; + word0(&db) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(&db) *= 1u << k; + } +#else + if (k > 0) + word0(&da) += k*Exp_msk1; + else { + k = -k; + word0(&db) += k*Exp_msk1; + } +#endif + return dval(&da) / dval(&db); + } + + static const double +tens[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +#ifdef VAX + , 1e23, 1e24 +#endif + }; + + static const double +#ifdef IEEE_Arith +bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; +static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, +#ifdef Avoid_Underflow + 9007199254740992.*9007199254740992.e-256 + /* = 2^106 * 1e-256 */ +#else + 1e-256 +#endif + }; +/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ +/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ +#define Scale_Bit 0x10 +#define n_bigtens 5 +#else +#ifdef IBM +bigtens[] = { 1e16, 1e32, 1e64 }; +static const double tinytens[] = { 1e-16, 1e-32, 1e-64 }; +#define n_bigtens 3 +#else +bigtens[] = { 1e16, 1e32 }; +static const double tinytens[] = { 1e-16, 1e-32 }; +#define n_bigtens 2 +#endif +#endif + +#undef Need_Hexdig +#ifdef INFNAN_CHECK +#ifndef No_Hex_NaN +#define Need_Hexdig +#endif +#endif + +#ifndef Need_Hexdig +#ifndef NO_HEX_FP +#define Need_Hexdig +#endif +#endif + +#ifdef Need_Hexdig /*{*/ +#if 0 +static unsigned char hexdig[256]; + + static void +htinit(unsigned char *h, unsigned char *s, int inc) +{ + int i, j; + for(i = 0; (j = s[i]) !=0; i++) + h[j] = i + inc; + } + + static void +hexdig_init(void) /* Use of hexdig_init omitted 20121220 to avoid a */ + /* race condition when multiple threads are used. */ +{ +#define USC (unsigned char *) + htinit(hexdig, USC "0123456789", 0x10); + htinit(hexdig, USC "abcdef", 0x10 + 10); + htinit(hexdig, USC "ABCDEF", 0x10 + 10); + } +#else +static unsigned char hexdig[256] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 16,17,18,19,20,21,22,23,24,25,0,0,0,0,0,0, + 0,26,27,28,29,30,31,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,26,27,28,29,30,31,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + }; +#endif +#endif /* } Need_Hexdig */ + +#ifdef INFNAN_CHECK + +#ifndef NAN_WORD0 +#define NAN_WORD0 0x7ff80000 +#endif + +#ifndef NAN_WORD1 +#define NAN_WORD1 0 +#endif + + static int +match(const char **sp, const char *t) +{ + int c, d; + const char *s = *sp; + + while((d = *t++)) { + if ((c = *++s) >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if (c != d) + return 0; + } + *sp = s + 1; + return 1; + } + +#ifndef No_Hex_NaN + static void +hexnan(U *rvp, const char **sp) +{ + ULong c, x[2]; + const char *s; + int c1, havedig, udx0, xshift; + + /**** if (!hexdig['0']) hexdig_init(); ****/ + x[0] = x[1] = 0; + havedig = xshift = 0; + udx0 = 1; + s = *sp; + /* allow optional initial 0x or 0X */ + while((c = *(const unsigned char*)(s+1)) && c <= ' ') + ++s; + if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')) + s += 2; + while((c = *(const unsigned char*)++s)) { + if ((c1 = hexdig[c])) + c = c1 & 0xf; + else if (c <= ' ') { + if (udx0 && havedig) { + udx0 = 0; + xshift = 1; + } + continue; + } +#ifdef GDTOA_NON_PEDANTIC_NANCHECK + else if (/*(*/ c == ')' && havedig) { + *sp = s + 1; + break; + } + else + return; /* invalid form: don't change *sp */ +#else + else { + do { + if (/*(*/ c == ')') { + *sp = s + 1; + break; + } + } while((c = *++s)); + break; + } +#endif + havedig = 1; + if (xshift) { + xshift = 0; + x[0] = x[1]; + x[1] = 0; + } + if (udx0) + x[0] = (x[0] << 4) | (x[1] >> 28); + x[1] = (x[1] << 4) | c; + } + if ((x[0] &= 0xfffff) || x[1]) { + word0(rvp) = Exp_mask | x[0]; + word1(rvp) = x[1]; + } + } +#endif /*No_Hex_NaN*/ +#endif /* INFNAN_CHECK */ + +#ifdef Pack_32 +#define ULbits 32 +#define kshift 5 +#define kmask 31 +#else +#define ULbits 16 +#define kshift 4 +#define kmask 15 +#endif + +#if !defined(NO_HEX_FP) || defined(Honor_FLT_ROUNDS) /*{*/ + static Bigint * +increment(Bigint *b MTd) +{ + ULong *x, *xe; + Bigint *b1; + + x = b->x; + xe = x + b->wds; + do { + if (*x < (ULong)0xffffffffL) { + ++*x; + return b; + } + *x++ = 0; + } while(x < xe); + { + if (b->wds >= b->maxwds) { + b1 = Balloc(b->k+1 MTa); + Bcopy(b1,b); + Bfree(b MTa); + b = b1; + } + b->x[b->wds++] = 1; + } + return b; + } + +#endif /*}*/ + +#ifndef NO_HEX_FP /*{*/ + + static void +rshift(Bigint *b, int k) +{ + ULong *x, *x1, *xe, y; + int n; + + x = x1 = b->x; + n = k >> kshift; + if (n < b->wds) { + xe = x + b->wds; + x += n; + if (k &= kmask) { + n = 32 - k; + y = *x++ >> k; + while(x < xe) { + *x1++ = (y | (*x << n)) & 0xffffffff; + y = *x++ >> k; + } + if ((*x1 = y) !=0) + x1++; + } + else + while(x < xe) + *x1++ = *x++; + } + if ((b->wds = x1 - b->x) == 0) + b->x[0] = 0; + } + + static ULong +any_on(Bigint *b, int k) +{ + int n, nwds; + ULong *x, *x0, x1, x2; + + x = b->x; + nwds = b->wds; + n = k >> kshift; + if (n > nwds) + n = nwds; + else if (n < nwds && (k &= kmask)) { + x1 = x2 = x[n]; + x1 >>= k; + x1 <<= k; + if (x1 != x2) + return 1; + } + x0 = x; + x += n; + while(x > x0) + if (*--x) + return 1; + return 0; + } + +enum { /* rounding values: same as FLT_ROUNDS */ + Round_zero = 0, + Round_near = 1, + Round_up = 2, + Round_down = 3 + }; + +static void +gethex( const char **sp, U *rvp, int rounding, int sign MTd) +{ + Bigint *b; + const unsigned char *decpt, *s0, *s, *s1; + Long e, e1; + ULong L, lostbits, *x; + int big, denorm, esign, havedig, k, n, nbits, up, zret; +#ifdef IBM + int j; +#endif + enum { +#ifdef IEEE_Arith /*{{*/ + emax = 0x7fe - Bias - P + 1, + emin = Emin - P + 1 +#else /*}{*/ + emin = Emin - P, +#ifdef VAX + emax = 0x7ff - Bias - P + 1 +#endif +#ifdef IBM + emax = 0x7f - Bias - P +#endif +#endif /*}}*/ + }; +#ifdef USE_LOCALE + int i; +#ifdef NO_LOCALE_CACHE + const unsigned char *decimalpoint = (unsigned char*) + localeconv()->decimal_point; +#else + const unsigned char *decimalpoint; + static unsigned char *decimalpoint_cache; + if (!(s0 = decimalpoint_cache)) { + s0 = (unsigned char*)localeconv()->decimal_point; + if ((decimalpoint_cache = (unsigned char*) + MALLOC(strlen((const char*)s0) + 1))) { + strcpy((char*)decimalpoint_cache, (const char*)s0); + s0 = decimalpoint_cache; + } + } + decimalpoint = s0; +#endif +#endif + + /**** if (!hexdig['0']) hexdig_init(); ****/ + havedig = 0; + s0 = *(const unsigned char **)sp + 2; + while(s0[havedig] == '0') + havedig++; + s0 += havedig; + s = s0; + decpt = 0; + zret = 0; + e = 0; + if (hexdig[*s]) + havedig++; + else { + zret = 1; +#ifdef USE_LOCALE + for(i = 0; decimalpoint[i]; ++i) { + if (s[i] != decimalpoint[i]) + goto pcheck; + } + decpt = s += i; +#else + if (*s != '.') + goto pcheck; + decpt = ++s; +#endif + if (!hexdig[*s]) + goto pcheck; + while(*s == '0') + s++; + if (hexdig[*s]) + zret = 0; + havedig = 1; + s0 = s; + } + while(hexdig[*s]) + s++; +#ifdef USE_LOCALE + if (*s == *decimalpoint && !decpt) { + for(i = 1; decimalpoint[i]; ++i) { + if (s[i] != decimalpoint[i]) + goto pcheck; + } + decpt = s += i; +#else + if (*s == '.' && !decpt) { + decpt = ++s; +#endif + while(hexdig[*s]) + s++; + }/*}*/ + if (decpt) + e = -(((Long)(s-decpt)) << 2); + pcheck: + s1 = s; + big = esign = 0; + switch(*s) { + case 'p': + case 'P': + switch(*++s) { + case '-': + esign = 1; + /* no break */ + case '+': + s++; + } + if ((n = hexdig[*s]) == 0 || n > 0x19) { + s = s1; + break; + } + e1 = n - 0x10; + while((n = hexdig[*++s]) !=0 && n <= 0x19) { + if (e1 & 0xf8000000) + big = 1; + e1 = 10*e1 + n - 0x10; + } + if (esign) + e1 = -e1; + e += e1; + } + *sp = (char*)s; + if (!havedig) + *sp = (char*)s0 - 1; + if (zret) + goto retz1; + if (big) { + if (esign) { +#ifdef IEEE_Arith + switch(rounding) { + case Round_up: + if (sign) + break; + goto ret_tiny; + case Round_down: + if (!sign) + break; + goto ret_tiny; + } +#endif + goto retz; +#ifdef IEEE_Arith + ret_tinyf: + Bfree(b MTa); + ret_tiny: + Set_errno(erange); + word0(rvp) = 0; + word1(rvp) = 1; + return; +#endif /* IEEE_Arith */ + } + switch(rounding) { + case Round_near: + goto ovfl1; + case Round_up: + if (!sign) + goto ovfl1; + goto ret_big; + case Round_down: + if (sign) + goto ovfl1; + goto ret_big; + } + ret_big: + word0(rvp) = Big0; + word1(rvp) = Big1; + return; + } + n = s1 - s0 - 1; + for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1) + k++; + b = Balloc(k MTa); + x = b->x; + n = 0; + L = 0; +#ifdef USE_LOCALE + for(i = 0; decimalpoint[i+1]; ++i); +#endif + while(s1 > s0) { +#ifdef USE_LOCALE + if (*--s1 == decimalpoint[i]) { + s1 -= i; + continue; + } +#else + if (*--s1 == '.') + continue; +#endif + if (n == ULbits) { + *x++ = L; + L = 0; + n = 0; + } + L |= (hexdig[*s1] & 0x0f) << n; + n += 4; + } + *x++ = L; + b->wds = n = x - b->x; + n = ULbits*n - hi0bits(L); + nbits = Nbits; + lostbits = 0; + x = b->x; + if (n > nbits) { + n -= nbits; + if (any_on(b,n)) { + lostbits = 1; + k = n - 1; + if (x[k>>kshift] & 1 << (k & kmask)) { + lostbits = 2; + if (k > 0 && any_on(b,k)) + lostbits = 3; + } + } + rshift(b, n); + e += n; + } + else if (n < nbits) { + n = nbits - n; + b = lshift(b, n MTa); + e -= n; + x = b->x; + } + if (e > emax) { + ovfl: + Bfree(b MTa); + ovfl1: + Set_errno(erange); +#ifdef Honor_FLT_ROUNDS + switch (rounding) { + case Round_zero: + goto ret_big; + case Round_down: + if (!sign) + goto ret_big; + break; + case Round_up: + if (sign) + goto ret_big; + } +#endif + word0(rvp) = Exp_mask; + word1(rvp) = 0; + return; + } + denorm = 0; + if (e < emin) { + denorm = 1; + n = emin - e; + if (n >= nbits) { +#ifdef IEEE_Arith /*{*/ + switch (rounding) { + case Round_near: + if (n == nbits && (n < 2 || lostbits || any_on(b,n-1))) + goto ret_tinyf; + break; + case Round_up: + if (!sign) + goto ret_tinyf; + break; + case Round_down: + if (sign) + goto ret_tinyf; + } +#endif /* } IEEE_Arith */ + Bfree(b MTa); + retz: + Set_errno(erange); + retz1: + rvp->d = 0.; + return; + } + k = n - 1; + if (lostbits) + lostbits = 1; + else if (k > 0) + lostbits = any_on(b,k); + if (x[k>>kshift] & 1 << (k & kmask)) + lostbits |= 2; + nbits -= n; + rshift(b,n); + e = emin; + } + if (lostbits) { + up = 0; + switch(rounding) { + case Round_zero: + break; + case Round_near: + if (lostbits & 2 + && (lostbits & 1) | (x[0] & 1)) + up = 1; + break; + case Round_up: + up = 1 - sign; + break; + case Round_down: + up = sign; + } + if (up) { + k = b->wds; + b = increment(b MTa); + x = b->x; + if (denorm) { +#if 0 + if (nbits == Nbits - 1 + && x[nbits >> kshift] & 1 << (nbits & kmask)) + denorm = 0; /* not currently used */ +#endif + } + else if (b->wds > k + || ((n = nbits & kmask) !=0 + && hi0bits(x[k-1]) < 32-n)) { + rshift(b,1); + if (++e > Emax) + goto ovfl; + } + } + } +#ifdef IEEE_Arith + if (denorm) + word0(rvp) = b->wds > 1 ? b->x[1] & ~0x100000 : 0; + else + word0(rvp) = (b->x[1] & ~0x100000) | ((e + 0x3ff + 52) << 20); + word1(rvp) = b->x[0]; +#endif +#ifdef IBM + if ((j = e & 3)) { + k = b->x[0] & ((1u << j) - 1); + rshift(b,j); + if (k) { + switch(rounding) { + case Round_up: + if (!sign) + increment(b); + break; + case Round_down: + if (sign) + increment(b); + break; + case Round_near: + j = 1 << (j-1); + if (k & j && ((k & (j-1)) | lostbits)) + increment(b); + } + } + } + e >>= 2; + word0(rvp) = b->x[1] | ((e + 65 + 13) << 24); + word1(rvp) = b->x[0]; +#endif +#ifdef VAX + /* The next two lines ignore swap of low- and high-order 2 bytes. */ + /* word0(rvp) = (b->x[1] & ~0x800000) | ((e + 129 + 55) << 23); */ + /* word1(rvp) = b->x[0]; */ + word0(rvp) = ((b->x[1] & ~0x800000) >> 16) | ((e + 129 + 55) << 7) | (b->x[1] << 16); + word1(rvp) = (b->x[0] >> 16) | (b->x[0] << 16); +#endif + Bfree(b MTa); + } +#endif /*!NO_HEX_FP}*/ + + static int +dshift(Bigint *b, int p2) +{ + int rv = hi0bits(b->x[b->wds-1]) - 4; + if (p2 > 0) + rv -= p2; + return rv & kmask; + } + + static int +quorem(Bigint *b, Bigint *S) +{ + int n; + ULong *bx, *bxe, q, *sx, *sxe; +#ifdef ULLong + ULLong borrow, carry, y, ys; +#else + ULong borrow, carry, y, ys; +#ifdef Pack_32 + ULong si, z, zs; +#endif +#endif + + n = S->wds; +#ifdef DEBUG + /*debug*/ if (b->wds > n) + /*debug*/ Bug("oversize b in quorem"); +#endif + if (b->wds < n) + return 0; + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ +#ifdef DEBUG +#ifdef NO_STRTOD_BIGCOMP + /*debug*/ if (q > 9) +#else + /* An oversized q is possible when quorem is called from bigcomp and */ + /* the input is near, e.g., twice the smallest denormalized number. */ + /*debug*/ if (q > 15) +#endif + /*debug*/ Bug("oversized quotient in quorem"); +#endif + if (q) { + borrow = 0; + carry = 0; + do { +#ifdef ULLong + ys = *sx++ * (ULLong)q + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = y & FFFFFFFF; +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + if (!*bxe) { + bx = b->x; + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { +#ifdef ULLong + ys = *sx++ + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = y & FFFFFFFF; +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return q; + } + +#if defined(Avoid_Underflow) || !defined(NO_STRTOD_BIGCOMP) /*{*/ + static double +sulp(U *x, BCinfo *bc) +{ + U u; + double rv; + int i; + + rv = ulp(x); + if (!bc->scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0) + return rv; /* Is there an example where i <= 0 ? */ + word0(&u) = Exp_1 + (i << Exp_shift); + word1(&u) = 0; + return rv * u.d; + } +#endif /*}*/ + +#ifndef NO_STRTOD_BIGCOMP + static void +bigcomp(U *rv, const char *s0, BCinfo *bc MTd) +{ + Bigint *b, *d; + int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase; + dd = 0; /* TODO(jart): Why does compiler complain? */ + + dsign = bc->dsign; + nd = bc->nd; + nd0 = bc->nd0; + p5 = nd + bc->e0 - 1; + speccase = 0; +#ifndef Sudden_Underflow + if (rv->d == 0.) { /* special case: value near underflow-to-zero */ + /* threshold was rounded to zero */ + b = i2b(1 MTa); + p2 = Emin - P + 1; + bbits = 1; +#ifdef Avoid_Underflow + word0(rv) = (P+2) << Exp_shift; +#else + word1(rv) = 1; +#endif + i = 0; +#ifdef Honor_FLT_ROUNDS + if (bc->rounding == 1) +#endif + { + speccase = 1; + --p2; + dsign = 0; + goto have_i; + } + } + else +#endif + b = d2b(rv, &p2, &bbits MTa); +#ifdef Avoid_Underflow + p2 -= bc->scale; +#endif + /* floor(log2(rv)) == bbits - 1 + p2 */ + /* Check for denormal case. */ + i = P - bbits; + if (i > (j = P - Emin - 1 + p2)) { +#ifdef Sudden_Underflow + Bfree(b MTa); + b = i2b(1 MTa); + p2 = Emin; + i = P - 1; +#ifdef Avoid_Underflow + word0(rv) = (1 + bc->scale) << Exp_shift; +#else + word0(rv) = Exp_msk1; +#endif + word1(rv) = 0; +#else + i = j; +#endif + } +#ifdef Honor_FLT_ROUNDS + if (bc->rounding != 1) { + if (i > 0) + b = lshift(b, i MTa); + if (dsign) + b = increment(b MTa); + } + else +#endif + { + b = lshift(b, ++i MTa); + b->x[0] |= 1; + } +#ifndef Sudden_Underflow + have_i: +#endif + p2 -= p5 + i; + d = i2b(1 MTa); + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + */ + if (p5 > 0) + d = pow5mult(d, p5 MTa); + else if (p5 < 0) + b = pow5mult(b, -p5 MTa); + if (p2 > 0) { + b2 = p2; + d2 = 0; + } + else { + b2 = 0; + d2 = -p2; + } + i = dshift(d, d2); + if ((b2 += i) > 0) + b = lshift(b, b2 MTa); + if ((d2 += i) > 0) + d = lshift(d, d2 MTa); + + /* Now b/d = exactly half-way between the two floating-point values */ + /* on either side of the input string. Compute first digit of b/d. */ + + if (!(dig = quorem(b,d))) { + b = multadd(b, 10, 0 MTa); /* very unlikely */ + dig = quorem(b,d); + } + + /* Compare b/d with s0 */ + + for(i = 0; i < nd0; ) { + if ((dd = s0[i++] - '0' - dig)) + goto ret; + if (!b->x[0] && b->wds == 1) { + if (i < nd) + dd = 1; + goto ret; + } + b = multadd(b, 10, 0 MTa); + dig = quorem(b,d); + } + for(j = bc->dp1; i++ < nd;) { + if ((dd = s0[j++] - '0' - dig)) + goto ret; + if (!b->x[0] && b->wds == 1) { + if (i < nd) + dd = 1; + goto ret; + } + b = multadd(b, 10, 0 MTa); + dig = quorem(b,d); + } + if (dig > 0 || b->x[0] || b->wds > 1) + dd = -1; + ret: + Bfree(b MTa); + Bfree(d MTa); +#ifdef Honor_FLT_ROUNDS + if (bc->rounding != 1) { + if (dd < 0) { + if (bc->rounding == 0) { + if (!dsign) + goto retlow1; + } + else if (dsign) + goto rethi1; + } + else if (dd > 0) { + if (bc->rounding == 0) { + if (dsign) + goto rethi1; + goto ret1; + } + if (!dsign) + goto rethi1; + dval(rv) += 2.*sulp(rv,bc); + } + else { + bc->inexact = 0; + if (dsign) + goto rethi1; + } + } + else +#endif + if (speccase) { + if (dd <= 0) + rv->d = 0.; + } + else if (dd < 0) { + if (!dsign) /* does not happen for round-near */ +retlow1: + dval(rv) -= sulp(rv,bc); + } + else if (dd > 0) { + if (dsign) { + rethi1: + dval(rv) += sulp(rv,bc); + } + } + else { + /* Exact half-way case: apply round-even rule. */ + if ((j = ((word0(rv) & Exp_mask) >> Exp_shift) - bc->scale) <= 0) { + i = 1 - j; + if (i <= 31) { + if (word1(rv) & (0x1 << i)) + goto odd; + } + else if (word0(rv) & (0x1 << (i-32))) + goto odd; + } + else if (word1(rv) & 1) { + odd: + if (dsign) + goto rethi1; + goto retlow1; + } + } + +#ifdef Honor_FLT_ROUNDS + ret1: +#endif + return; + } +#endif /* NO_STRTOD_BIGCOMP */ + + double +(strtod)(const char *s00, char **se) +{ + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1; + int esign, i, j, k, nd, nd0, nf, nz, nz0, nz1, sign; + const char *s, *s0, *s1; + double aadj, aadj1; + Long L; + U aadj2, adj, rv, rv0; + ULong y, z; + BCinfo bc; + Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; +#ifdef USE_BF96 + ULLong bhi, blo, brv, t00, t01, t02, t10, t11, terv, tg, tlo, yz; + const BF96 *p10; + int bexact, erv; +#endif +#ifdef Avoid_Underflow + ULong Lsb, Lsb1; +#endif +#ifdef SET_INEXACT + int oldinexact; +#endif +#ifndef NO_STRTOD_BIGCOMP + int req_bigcomp = 0; +#endif +#ifdef MULTIPLE_THREADS + ThInfo *TI = 0; +#endif +#ifdef Honor_FLT_ROUNDS /*{*/ +#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ + bc.rounding = Flt_Rounds; +#else /*}{*/ + bc.rounding = 1; + switch(fegetround()) { + case FE_TOWARDZERO: bc.rounding = 0; break; + case FE_UPWARD: bc.rounding = 2; break; + case FE_DOWNWARD: bc.rounding = 3; + } +#endif /*}}*/ +#endif /*}*/ +#ifdef USE_LOCALE + const char *s2; +#endif + + sign = nz0 = nz1 = nz = bc.dplen = bc.uflchk = 0; + dval(&rv) = 0.; + for(s = s00;;s++) switch(*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + goto ret0; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } + break2: + if (*s == '0') { +#ifndef NO_HEX_FP /*{*/ + switch(s[1]) { + case 'x': + case 'X': +#ifdef Honor_FLT_ROUNDS + gethex(&s, &rv, bc.rounding, sign MTb); +#else + gethex(&s, &rv, 1, sign MTb); +#endif + goto ret; + } +#endif /*}*/ + nz0 = 1; + while(*++s == '0') ; + if (!*s) + goto ret; + } + s0 = s; + nd = nf = 0; +#ifdef USE_BF96 + yz = 0; + for(; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 19) + yz = 10*yz + c - '0'; +#else + y = z = 0; + for(; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < DBL_DIG + 2) + z = 10*z + c - '0'; +#endif + nd0 = nd; + bc.dp0 = bc.dp1 = s - s0; + for(s1 = s; s1 > s0 && *--s1 == '0'; ) + ++nz1; +#ifdef USE_LOCALE + s1 = localeconv()->decimal_point; + if (c == *s1) { + c = '.'; + if (*++s1) { + s2 = s; + for(;;) { + if (*++s2 != *s1) { + c = 0; + break; + } + if (!*++s1) { + s = s2; + break; + } + } + } + } +#endif + if (c == '.') { + c = *++s; + bc.dp1 = s - s0; + bc.dplen = bc.dp1 - bc.dp0; + if (!nd) { + for(; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + bc.dp0 = s0 - s; + bc.dp1 = bc.dp0 + bc.dplen; + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { + have_dig: + nz++; + if (c -= '0') { + nf += nz; + i = 1; +#ifdef USE_BF96 + for(; i < nz; ++i) { + if (++nd <= 19) + yz *= 10; + } + if (++nd <= 19) + yz = 10*yz + c; +#else + for(; i < nz; ++i) { + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 2) + z *= 10; + } + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 2) + z = 10*z + c; +#endif + nz = nz1 = 0; + } + } + } + dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + goto ret0; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) { +#ifdef INFNAN_CHECK /*{*/ + /* Check for Nan and Infinity */ + if (!bc.dplen) + switch(c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) + ++s; + word0(&rv) = 0x7ff00000; + word1(&rv) = 0; + goto ret; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { + word0(&rv) = NAN_WORD0; + word1(&rv) = NAN_WORD1; +#ifndef No_Hex_NaN + if (*s == '(') /*)*/ + hexnan(&rv, &s); +#endif + goto ret; + } + } +#endif /*} INFNAN_CHECK */ + ret0: + s = s00; + sign = 0; + } + goto ret; + } + bc.e0 = e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; +#ifndef USE_BF96 + k = nd < DBL_DIG + 2 ? nd : DBL_DIG + 2; + dval(&rv) = y; + if (k > 9) { +#ifdef SET_INEXACT + if (k > DBL_DIG) + oldinexact = get_inexact(); +#endif + dval(&rv) = tens[k - 9] * dval(&rv) + z; + } +#endif + bd0 = 0; + if (nd <= DBL_DIG +#ifndef RND_PRODQUOT +#ifndef Honor_FLT_ROUNDS + && Flt_Rounds == 1 +#endif +#endif + ) { +#ifdef USE_BF96 + dval(&rv) = yz; +#endif + if (!e) + goto ret; +#ifndef ROUND_BIASED_without_Round_Up + if (e > 0) { + if (e <= Ten_pmax) { +#ifdef SET_INEXACT + bc.inexact = 0; + oldinexact = 1; +#endif +#ifdef VAX + goto vax_ovfl_check; +#else +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv.d = -rv.d; + sign = 0; + } +#endif + /* rv = */ rounded_product(dval(&rv), tens[e]); + goto ret; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ +#ifdef SET_INEXACT + bc.inexact = 0; + oldinexact = 1; +#endif +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv.d = -rv.d; + sign = 0; + } +#endif + e -= i; + dval(&rv) *= tens[i]; +#ifdef VAX + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ + vax_ovfl_check: + word0(&rv) -= P*Exp_msk1; + /* rv = */ rounded_product(dval(&rv), tens[e]); + if ((word0(&rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) + goto ovfl; + word0(&rv) += P*Exp_msk1; +#else + /* rv = */ rounded_product(dval(&rv), tens[e]); +#endif + goto ret; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) { +#ifdef SET_INEXACT + bc.inexact = 0; + oldinexact = 1; +#endif +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv.d = -rv.d; + sign = 0; + } +#endif + /* rv = */ rounded_quotient(dval(&rv), tens[-e]); + goto ret; + } +#endif +#endif /* ROUND_BIASED_without_Round_Up */ + } +#ifdef USE_BF96 + k = nd < 19 ? nd : 19; +#endif + e1 += nd - k; /* scale factor = 10^e1 */ + +#ifdef IEEE_Arith +#ifdef SET_INEXACT + bc.inexact = 1; +#ifndef USE_BF96 + if (k <= DBL_DIG) +#endif + oldinexact = get_inexact(); +#endif +#ifdef Honor_FLT_ROUNDS + if (bc.rounding >= 2) { + if (sign) + bc.rounding = bc.rounding == 2 ? 0 : 2; + else + if (bc.rounding != 2) + bc.rounding = 0; + } +#endif +#endif /*IEEE_Arith*/ + +#ifdef USE_BF96 /*{*/ + Debug(++dtoa_stats[0]); + i = e1 + 342; + if (i < 0) + goto undfl; + if (i > 650) + goto ovfl; + p10 = &pten[i]; + brv = yz; + /* shift brv left, with i = number of bits shifted */ + i = 0; + if (!(brv & 0xffffffff00000000ull)) { + i = 32; + brv <<= 32; + } + if (!(brv & 0xffff000000000000ull)) { + i += 16; + brv <<= 16; + } + if (!(brv & 0xff00000000000000ull)) { + i += 8; + brv <<= 8; + } + if (!(brv & 0xf000000000000000ull)) { + i += 4; + brv <<= 4; + } + if (!(brv & 0xc000000000000000ull)) { + i += 2; + brv <<= 2; + } + if (!(brv & 0x8000000000000000ull)) { + i += 1; + brv <<= 1; + } + erv = (64 + 0x3fe) + p10->e - i; + if (erv <= 0 && nd > 19) + goto many_digits; /* denormal: may need to look at all digits */ + bhi = brv >> 32; + blo = brv & 0xffffffffull; + /* Unsigned 32-bit ints lie in [0,2^32-1] and */ + /* unsigned 64-bit ints lie in [0, 2^64-1]. The product of two unsigned */ + /* 32-bit ints is <= 2^64 - 2*2^32-1 + 1 = 2^64 - 1 - 2*(2^32 - 1), so */ + /* we can add two unsigned 32-bit ints to the product of two such ints, */ + /* and 64 bits suffice to contain the result. */ + t01 = bhi * p10->b1; + t10 = blo * p10->b0 + (t01 & 0xffffffffull); + t00 = bhi * p10->b0 + (t01 >> 32) + (t10 >> 32); + if (t00 & 0x8000000000000000ull) { + if ((t00 & 0x3ff) && (~t00 & 0x3fe)) { /* unambiguous result? */ + if (nd > 19 && ((t00 + (1< 19 && ((t00 + (1<b2; + t11 = blo * p10->b1 + (t02 & 0xffffffffull); + bexact = 1; + if (e1 < 0 || e1 > 41 || (t10 | t11) & 0xffffffffull || nd > 19) + bexact = 0; + tlo = (t10 & 0xffffffffull) + (t02 >> 32) + (t11 >> 32); + if (!bexact && (tlo + 0x10) >> 32 > tlo >> 32) + goto many_digits; + t00 += tlo >> 32; + if (t00 & 0x8000000000000000ull) { + if (erv <= 0) { /* denormal result */ + if (nd >= 20 || !((tlo & 0xfffffff0) | (t00 & 0x3ff))) + goto many_digits; + denormal: + if (erv <= -52) { +#ifdef Honor_FLT_ROUNDS + switch(bc.rounding) { + case 0: goto undfl; + case 2: goto tiniest; + } +#endif + if (erv < -52 || !(t00 & 0x7fffffffffffffffull)) + goto undfl; + goto tiniest; + } + tg = 1ull << (11 - erv); + t00 &= ~(tg - 1); /* clear low bits */ +#ifdef Honor_FLT_ROUNDS + switch(bc.rounding) { + case 0: goto noround_den; + case 2: goto roundup_den; + } +#endif + if (t00 & tg) { +#ifdef Honor_FLT_ROUNDS + roundup_den: +#endif + t00 += tg << 1; + if (!(t00 & 0x8000000000000000ull)) { + if (++erv > 0) + goto smallest_normal; + t00 = 0x8000000000000000ull; + } + } +#ifdef Honor_FLT_ROUNDS + noround_den: +#endif + LLval(&rv) = t00 >> (12 - erv); + Set_errno(erange); + goto ret; + } + if (bexact) { +#ifdef SET_INEXACT + if (!(t00 & 0x7ff) && !(tlo & 0xffffffffull)) { + bc.inexact = 0; + goto noround; + } +#endif +#ifdef Honor_FLT_ROUNDS + switch(bc.rounding) { + case 2: + if (t00 & 0x7ff) + goto roundup; + case 0: goto noround; + } +#endif + if (t00 & 0x400 && (tlo & 0xffffffff) | (t00 & 0xbff)) + goto roundup; + goto noround; + } + if ((tlo & 0xfffffff0) | (t00 & 0x3ff) + && (nd <= 19 || ((t00 + (1ull << i)) & 0xfffffffffffffc00ull) + == (t00 & 0xfffffffffffffc00ull))) { + /* Unambiguous result. */ + /* If nd > 19, then incrementing the 19th digit */ + /* does not affect rv. */ +#ifdef Honor_FLT_ROUNDS + switch(bc.rounding) { + case 0: goto noround; + case 2: goto roundup; + } +#endif + if (t00 & 0x400) { /* round up */ + roundup: + t00 += 0x800; + if (!(t00 & 0x8000000000000000ull)) { + /* rounded up to a power of 2 */ + if (erv >= 0x7fe) + goto ovfl; + terv = erv + 1; + LLval(&rv) = terv << 52; + goto ret; + } + } + noround: + if (erv >= 0x7ff) + goto ovfl; + terv = erv; + LLval(&rv) = (terv << 52) | ((t00 & 0x7ffffffffffff800ull) >> 11); + goto ret; + } + } + else { + if (erv <= 1) { /* denormal result */ + if (nd >= 20 || !((tlo & 0xfffffff0) | (t00 & 0x1ff))) + goto many_digits; + denormal1: + if (erv <= -51) { +#ifdef Honor_FLT_ROUNDS + switch(bc.rounding) { + case 0: goto undfl; + case 2: goto tiniest; + } +#endif + if (erv < -51 || !(t00 & 0x3fffffffffffffffull)) + goto undfl; + tiniest: + LLval(&rv) = 1; + Set_errno(erange); + goto ret; + } + tg = 1ull << (11 - erv); +#ifdef Honor_FLT_ROUNDS + switch(bc.rounding) { + case 0: goto noround1_den; + case 2: goto roundup1_den; + } +#endif + if (t00 & tg) { +#ifdef Honor_FLT_ROUNDS + roundup1_den: +#endif + if (0x8000000000000000ull & (t00 += (tg<<1)) && erv == 1) { + + smallest_normal: + LLval(&rv) = 0x0010000000000000ull; + goto ret; + } + } +#ifdef Honor_FLT_ROUNDS + noround1_den: +#endif + if (erv <= -52) + goto undfl; + LLval(&rv) = t00 >> (12 - erv); + Set_errno(erange); + goto ret; + } + if (bexact) { +#ifdef SET_INEXACT + if (!(t00 & 0x3ff) && !(tlo & 0xffffffffull)) { + bc.inexact = 0; + goto noround1; + } +#endif +#ifdef Honor_FLT_ROUNDS + switch(bc.rounding) { + case 2: + if (t00 & 0x3ff) + goto roundup1; + case 0: goto noround1; + } +#endif + if (t00 & 0x200 && (t00 & 0x5ff || tlo)) + goto roundup1; + goto noround1; + } + if ((tlo & 0xfffffff0) | (t00 & 0x1ff) + && (nd <= 19 || ((t00 + (1ull << i)) & 0x7ffffffffffffe00ull) + == (t00 & 0x7ffffffffffffe00ull))) { + /* Unambiguous result. */ +#ifdef Honor_FLT_ROUNDS + switch(bc.rounding) { + case 0: goto noround1; + case 2: goto roundup1; + } +#endif + if (t00 & 0x200) { /* round up */ + roundup1: + t00 += 0x400; + if (!(t00 & 0x4000000000000000ull)) { + /* rounded up to a power of 2 */ + if (erv >= 0x7ff) + goto ovfl; + terv = erv; + LLval(&rv) = terv << 52; + goto ret; + } + } + noround1: + if (erv >= 0x800) + goto ovfl; + terv = erv - 1; + LLval(&rv) = (terv << 52) | ((t00 & 0x3ffffffffffffc00ull) >> 10); + goto ret; + } + } + many_digits: + Debug(++dtoa_stats[2]); + if (nd > 17) { + if (nd > 18) { + yz /= 100; + e1 += 2; + } + else { + yz /= 10; + e1 += 1; + } + y = yz / 100000000; + } + else if (nd > 9) { + i = nd - 9; + y = (yz >> i) / pfive[i-1]; + } + else + y = yz; + dval(&rv) = yz; +#endif /*}*/ + +#ifdef IEEE_Arith +#ifdef Avoid_Underflow + bc.scale = 0; +#endif +#endif /*IEEE_Arith*/ + + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { + if ((i = e1 & 15)) + dval(&rv) *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { + ovfl: + /* Can't trust HUGE_VAL */ +#ifdef IEEE_Arith +#ifdef Honor_FLT_ROUNDS + switch(bc.rounding) { + case 0: /* toward 0 */ + case 3: /* toward -infinity */ + word0(&rv) = Big0; + word1(&rv) = Big1; + break; + default: + word0(&rv) = Exp_mask; + word1(&rv) = 0; + } +#else /*Honor_FLT_ROUNDS*/ + word0(&rv) = Exp_mask; + word1(&rv) = 0; +#endif /*Honor_FLT_ROUNDS*/ +#ifdef SET_INEXACT + /* set overflow bit */ + dval(&rv0) = 1e300; + dval(&rv0) *= dval(&rv0); +#endif +#else /*IEEE_Arith*/ + word0(&rv) = Big0; + word1(&rv) = Big1; +#endif /*IEEE_Arith*/ + range_err: + if (bd0) { + Bfree(bb MTb); + Bfree(bd MTb); + Bfree(bs MTb); + Bfree(bd0 MTb); + Bfree(delta MTb); + } + Set_errno(erange); + goto ret; + } + e1 >>= 4; + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(&rv) *= bigtens[j]; + /* The last multiplication could overflow. */ + word0(&rv) -= P*Exp_msk1; + dval(&rv) *= bigtens[j]; + if ((z = word0(&rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-P)) + goto ovfl; + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + word0(&rv) = Big0; + word1(&rv) = Big1; + } + else + word0(&rv) += P*Exp_msk1; + } + } + else if (e1 < 0) { + e1 = -e1; + if ((i = e1 & 15)) + dval(&rv) /= tens[i]; + if (e1 >>= 4) { + if (e1 >= 1u << n_bigtens) + goto undfl; +#ifdef Avoid_Underflow + if (e1 & Scale_Bit) + bc.scale = 2*P; + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(&rv) *= tinytens[j]; + if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) + >> Exp_shift)) > 0) { + /* scaled rv is denormal; clear j low bits */ + if (j >= 32) { + if (j > 54) + goto undfl; + word1(&rv) = 0; + if (j >= 53) + word0(&rv) = (P+2)*Exp_msk1; + else + word0(&rv) &= 0xffffffff << (j-32); + } + else + word1(&rv) &= 0xffffffff << j; + } +#else + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(&rv) *= tinytens[j]; + /* The last multiplication could underflow. */ + dval(&rv0) = dval(&rv); + dval(&rv) *= tinytens[j]; + if (!dval(&rv)) { + dval(&rv) = 2.*dval(&rv0); + dval(&rv) *= tinytens[j]; +#endif + if (!dval(&rv)) { + undfl: + dval(&rv) = 0.; +#ifdef Honor_FLT_ROUNDS + if (bc.rounding == 2) + word1(&rv) = 1; +#endif + goto range_err; + } +#ifndef Avoid_Underflow + word0(&rv) = Tiny0; + word1(&rv) = Tiny1; + /* The refinement below will clean + * this approximation up. + */ + } +#endif + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bc.nd = nd - nz1; +#ifndef NO_STRTOD_BIGCOMP + bc.nd0 = nd0; /* Only needed if nd > strtod_diglim, but done here */ + /* to silence an erroneous warning about bc.nd0 */ + /* possibly not being initialized. */ + if (nd > strtod_diglim) { + /* ASSERT(strtod_diglim >= 18); 18 == one more than the */ + /* minimum number of decimal digits to distinguish double values */ + /* in IEEE arithmetic. */ + i = j = 18; + if (i > nd0) + j += bc.dplen; + for(;;) { + if (--j < bc.dp1 && j >= bc.dp0) + j = bc.dp0 - 1; + if (s0[j] != '0') + break; + --i; + } + e += nd - i; + nd = i; + if (nd0 > nd) + nd0 = nd; + if (nd < 9) { /* must recompute y */ + y = 0; + for(i = 0; i < nd0; ++i) + y = 10*y + s0[i] - '0'; + for(j = bc.dp1; i < nd; ++i) + y = 10*y + s0[j++] - '0'; + } + } +#endif + bd0 = s2b(s0, nd0, nd, y, bc.dplen MTb); + + for(;;) { + bd = Balloc(bd0->k MTb); + Bcopy(bd, bd0); + bb = d2b(&rv, &bbe, &bbbits MTb); /* rv = bb * 2^bbe */ + bs = i2b(1 MTb); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; +#ifdef Honor_FLT_ROUNDS + if (bc.rounding != 1) + bs2++; +#endif +#ifdef Avoid_Underflow + Lsb = LSB; + Lsb1 = 0; + j = bbe - bc.scale; + i = j + bbbits - 1; /* logb(rv) */ + j = P + 1 - bbbits; + if (i < Emin) { /* denormal */ + i = Emin - i; + j -= i; + if (i < 32) + Lsb <<= i; + else if (i < 52) + Lsb1 = Lsb << (i-32); + else + Lsb1 = Exp_mask; + } +#else /*Avoid_Underflow*/ +#ifdef Sudden_Underflow +#ifdef IBM + j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); +#else + j = P + 1 - bbbits; +#endif +#else /*Sudden_Underflow*/ + j = bbe; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + bb2 += j; + bd2 += j; +#ifdef Avoid_Underflow + bd2 += bc.scale; +#endif + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5 MTb); + bb1 = mult(bs, bb MTb); + Bfree(bb MTb); + bb = bb1; + } + if (bb2 > 0) + bb = lshift(bb, bb2 MTb); + if (bd5 > 0) + bd = pow5mult(bd, bd5 MTb); + if (bd2 > 0) + bd = lshift(bd, bd2 MTb); + if (bs2 > 0) + bs = lshift(bs, bs2 MTb); + delta = diff(bb, bd MTb); + bc.dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); +#ifndef NO_STRTOD_BIGCOMP /*{*/ + if (bc.nd > nd && i <= 0) { + if (bc.dsign) { + /* Must use bigcomp(). */ + req_bigcomp = 1; + break; + } +#ifdef Honor_FLT_ROUNDS + if (bc.rounding != 1) { + if (i < 0) { + req_bigcomp = 1; + break; + } + } + else +#endif + i = -1; /* Discarded digits make delta smaller. */ + } +#endif /*}*/ +#ifdef Honor_FLT_ROUNDS /*{*/ + if (bc.rounding != 1) { + if (i < 0) { + /* Error is less than an ulp */ + if (!delta->x[0] && delta->wds <= 1) { + /* exact */ +#ifdef SET_INEXACT + bc.inexact = 0; +#endif + break; + } + if (bc.rounding) { + if (bc.dsign) { + adj.d = 1.; + goto apply_adj; + } + } + else if (!bc.dsign) { + adj.d = -1.; + if (!word1(&rv) + && !(word0(&rv) & Frac_mask)) { + y = word0(&rv) & Exp_mask; +#ifdef Avoid_Underflow + if (!bc.scale || y > 2*P*Exp_msk1) +#else + if (y) +#endif + { + delta = lshift(delta,Log2P MTb); + if (cmp(delta, bs) <= 0) + adj.d = -0.5; + } + } + apply_adj: +#ifdef Avoid_Underflow /*{*/ + if (bc.scale && (y = word0(&rv) & Exp_mask) + <= 2*P*Exp_msk1) + word0(&adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(&rv) & Exp_mask) <= + P*Exp_msk1) { + word0(&rv) += P*Exp_msk1; + dval(&rv) += adj.d*ulp(dval(&rv)); + word0(&rv) -= P*Exp_msk1; + } + else +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow}*/ + dval(&rv) += adj.d*ulp(&rv); + } + break; + } + adj.d = ratio(delta, bs); + if (adj.d < 1.) + adj.d = 1.; + if (adj.d <= 0x7ffffffe) { + /* adj = rounding ? ceil(adj) : floor(adj); */ + y = adj.d; + if (y != adj.d) { + if (!((bc.rounding>>1) ^ bc.dsign)) + y++; + adj.d = y; + } + } +#ifdef Avoid_Underflow /*{*/ + if (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) + word0(&adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { + word0(&rv) += P*Exp_msk1; + adj.d *= ulp(dval(&rv)); + if (bc.dsign) + dval(&rv) += adj.d; + else + dval(&rv) -= adj.d; + word0(&rv) -= P*Exp_msk1; + goto cont; + } +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow}*/ + adj.d *= ulp(&rv); + if (bc.dsign) { + if (word0(&rv) == Big0 && word1(&rv) == Big1) + goto ovfl; + dval(&rv) += adj.d; + } + else + dval(&rv) -= adj.d; + goto cont; + } +#endif /*}Honor_FLT_ROUNDS*/ + + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask +#ifdef IEEE_Arith /*{*/ +#ifdef Avoid_Underflow + || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 +#else + || (word0(&rv) & Exp_mask) <= Exp_msk1 +#endif +#endif /*}*/ + ) { +#ifdef SET_INEXACT + if (!delta->x[0] && delta->wds <= 1) + bc.inexact = 0; +#endif + break; + } + if (!delta->x[0] && delta->wds <= 1) { + /* exact result */ +#ifdef SET_INEXACT + bc.inexact = 0; +#endif + break; + } + delta = lshift(delta,Log2P MTb); + if (cmp(delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) { + /* exactly half-way between */ + if (bc.dsign) { + if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 + && word1(&rv) == ( +#ifdef Avoid_Underflow + (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) + ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : +#endif + 0xffffffff)) { + /*boundary case -- increment exponent*/ + if (word0(&rv) == Big0 && word1(&rv) == Big1) + goto ovfl; + word0(&rv) = (word0(&rv) & Exp_mask) + + Exp_msk1 +#ifdef IBM + | Exp_msk1 >> 4 +#endif + ; + word1(&rv) = 0; +#ifdef Avoid_Underflow + bc.dsign = 0; +#endif + break; + } + } + else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { + drop_down: + /* boundary case -- decrement exponent */ +#ifdef Sudden_Underflow /*{{*/ + L = word0(&rv) & Exp_mask; +#ifdef IBM + if (L < Exp_msk1) +#else +#ifdef Avoid_Underflow + if (L <= (bc.scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) +#else + if (L <= Exp_msk1) +#endif /*Avoid_Underflow*/ +#endif /*IBM*/ + { + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } + L -= Exp_msk1; +#else /*Sudden_Underflow}{*/ +#ifdef Avoid_Underflow + if (bc.scale) { + L = word0(&rv) & Exp_mask; + if (L <= (2*P+1)*Exp_msk1) { + if (L > (P+2)*Exp_msk1) + /* round even ==> */ + /* accept rv */ + break; + /* rv = smallest denormal */ + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } + } +#endif /*Avoid_Underflow*/ + L = (word0(&rv) & Exp_mask) - Exp_msk1; +#endif /*Sudden_Underflow}}*/ + word0(&rv) = L | Bndry_mask1; + word1(&rv) = 0xffffffff; +#ifdef IBM + goto cont; +#else +#ifndef NO_STRTOD_BIGCOMP + if (bc.nd > nd) + goto cont; +#endif + break; +#endif + } +#ifndef ROUND_BIASED +#ifdef Avoid_Underflow + if (Lsb1) { + if (!(word0(&rv) & Lsb1)) + break; + } + else if (!(word1(&rv) & Lsb)) + break; +#else + if (!(word1(&rv) & LSB)) + break; +#endif +#endif + if (bc.dsign) +#ifdef Avoid_Underflow + dval(&rv) += sulp(&rv, &bc); +#else + dval(&rv) += ulp(&rv); +#endif +#ifndef ROUND_BIASED + else { +#ifdef Avoid_Underflow + dval(&rv) -= sulp(&rv, &bc); +#else + dval(&rv) -= ulp(&rv); +#endif +#ifndef Sudden_Underflow + if (!dval(&rv)) { + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } +#endif + } +#ifdef Avoid_Underflow + bc.dsign = 1 - bc.dsign; +#endif +#endif + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (bc.dsign) + aadj = aadj1 = 1.; + else if (word1(&rv) || word0(&rv) & Bndry_mask) { +#ifndef Sudden_Underflow + if (word1(&rv) == Tiny1 && !word0(&rv)) { + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } +#endif + aadj = 1.; + aadj1 = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) + aadj = 1./FLT_RADIX; + else + aadj *= 0.5; + aadj1 = -aadj; + } + } + else { + aadj *= 0.5; + aadj1 = bc.dsign ? aadj : -aadj; +#ifdef Check_FLT_ROUNDS + switch(bc.rounding) { + case 2: /* towards +infinity */ + aadj1 -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + aadj1 += 0.5; + } +#else + if (Flt_Rounds == 0) + aadj1 += 0.5; +#endif /*Check_FLT_ROUNDS*/ + } + y = word0(&rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + dval(&rv0) = dval(&rv); + word0(&rv) -= P*Exp_msk1; + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + if ((word0(&rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (word0(&rv0) == Big0 && word1(&rv0) == Big1) + goto ovfl; + word0(&rv) = Big0; + word1(&rv) = Big1; + goto cont; + } + else + word0(&rv) += P*Exp_msk1; + } + else { +#ifdef Avoid_Underflow + if (bc.scale && y <= 2*P*Exp_msk1) { + if (aadj <= 0x7fffffff) { + if ((z = aadj) <= 0) + z = 1; + aadj = z; + aadj1 = bc.dsign ? aadj : -aadj; + } + dval(&aadj2) = aadj1; + word0(&aadj2) += (2*P+1)*Exp_msk1 - y; + aadj1 = dval(&aadj2); + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + if (rv.d == 0.) +#ifdef NO_STRTOD_BIGCOMP + goto undfl; +#else + { + req_bigcomp = 1; + break; + } +#endif + } + else { + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + } +#else +#ifdef Sudden_Underflow + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { + dval(&rv0) = dval(&rv); + word0(&rv) += P*Exp_msk1; + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; +#ifdef IBM + if ((word0(&rv) & Exp_mask) < P*Exp_msk1) +#else + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) +#endif + { + if (word0(&rv0) == Tiny0 + && word1(&rv0) == Tiny1) { + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } + word0(&rv) = Tiny0; + word1(&rv) = Tiny1; + goto cont; + } + else + word0(&rv) -= P*Exp_msk1; + } + else { + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + } +#else /*Sudden_Underflow*/ + /* Compute adj so that the IEEE rounding rules will + * correctly round rv + adj in some half-way cases. + * If rv * ulp(rv) is denormalized (i.e., + * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid + * trouble from bits lost to denormalization; + * example: 1.2e-307 . + */ + if (y <= (P-1)*Exp_msk1 && aadj > 1.) { + aadj1 = (double)(int)(aadj + 0.5); + if (!bc.dsign) + aadj1 = -aadj1; + } + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + } + z = word0(&rv) & Exp_mask; +#ifndef SET_INEXACT + if (bc.nd == nd) { +#ifdef Avoid_Underflow + if (!bc.scale) +#endif + if (y == z) { + /* Can we stop now? */ + L = (Long)aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999/FLT_RADIX) + break; + } + } +#endif + cont: + Bfree(bb MTb); + Bfree(bd MTb); + Bfree(bs MTb); + Bfree(delta MTb); + } + Bfree(bb MTb); + Bfree(bd MTb); + Bfree(bs MTb); + Bfree(bd0 MTb); + Bfree(delta MTb); +#ifndef NO_STRTOD_BIGCOMP + if (req_bigcomp) { + bd0 = 0; + bc.e0 += nz1; + bigcomp(&rv, s0, &bc MTb); + y = word0(&rv) & Exp_mask; + if (y == Exp_mask) + goto ovfl; + if (y == 0 && rv.d == 0.) + goto undfl; + } +#endif +#ifdef Avoid_Underflow + if (bc.scale) { + word0(&rv0) = Exp_1 - 2*P*Exp_msk1; + word1(&rv0) = 0; + dval(&rv) *= dval(&rv0); +#ifndef NO_ERRNO + /* try to avoid the bug of testing an 8087 register value */ +#ifdef IEEE_Arith + if (!(word0(&rv) & Exp_mask)) +#else + if (word0(&rv) == 0 && word1(&rv) == 0) +#endif + Set_errno(erange); +#endif + } +#endif /* Avoid_Underflow */ + ret: +#ifdef SET_INEXACT + if (bc.inexact) { + if (!(word0(&rv) & Exp_mask)) { + /* set underflow and inexact bits */ + dval(&rv0) = 1e-300; + dval(&rv0) *= dval(&rv0); + } + else if (!oldinexact) { + word0(&rv0) = Exp_1 + (70 << Exp_shift); + word1(&rv0) = 0; + dval(&rv0) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif + if (se) + *se = (char *)s; + if (sign) { + return -dval(&rv); + } else { + return dval(&rv); + } + } + +#ifndef MULTIPLE_THREADS + static char *dtoa_result; +#endif + + static char * +rv_alloc(int i MTd) +{ + int j, k, *r; + + j = sizeof(ULong); + for(k = 0; + sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; + j <<= 1) + k++; + r = (int*)Balloc(k MTa); + *r = k; + return +#ifndef MULTIPLE_THREADS + dtoa_result = +#endif + (char *)(r+1); + } + + static char * +nrv_alloc(const char *s, char *s0, size_t s0len, char **rve, int n MTd) +{ + char *rv, *t; + + if (!s0) + s0 = rv_alloc(n MTa); + else if (s0len <= n) { + rv = 0; + t = rv + n; + goto rve_chk; + } + t = rv = s0; + while((*t = *s++)) + ++t; + rve_chk: + if (rve) + *rve = t; + return rv; + } + +/* freedtoa(s) must be used to free values s returned by dtoa + * when MULTIPLE_THREADS is #defined. It should be used in all cases, + * but for consistency with earlier versions of dtoa, it is optional + * when MULTIPLE_THREADS is not defined. + */ + + void +freedtoa(char *s) +{ +#ifdef MULTIPLE_THREADS + ThInfo *TI = 0; +#endif + Bigint *b = (Bigint *)((int *)s - 1); + b->maxwds = 1 << (b->k = *(int*)b); + Bfree(b MTb); +#ifndef MULTIPLE_THREADS + if (s == dtoa_result) + dtoa_result = 0; +#endif + } + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + + char * +dtoa_r(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve, char *buf, size_t blen) +{ + /* Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4,5 ==> similar to 2 and 3, respectively, but (in + round-nearest mode) with the tests of mode 0 to + possibly return a shorter string that rounds to d. + With IEEE arithmetic and compilation with + -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same + as modes 2 and 3 when FLT_ROUNDS != 1. + 6-9 ==> Debugging modes similar to mode - 4: don't try + fast floating-point estimate (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + When not NULL, buf is an output buffer of length blen, which must + be large enough to accommodate suppressed trailing zeros and a trailing + null byte. If blen is too small, rv = NULL is returned, in which case + if rve is not NULL, a subsequent call with blen >= (*rve - rv) + 1 + should succeed in returning buf. + + When buf is NULL, sufficient space is allocated for the return value, + which, when done using, the caller should pass to freedtoa(). + + USE_BF is automatically defined when neither NO_LONG_LONG nor NO_BF96 + is defined. + */ + +#ifdef MULTIPLE_THREADS + ThInfo *TI = 0; +#endif + int bbits, b2, b5, be, dig, i, ilim, ilim1, + j, j1, k, leftright, m2, m5, s2, s5, spec_case; +#if !defined(Sudden_Underflow) || defined(USE_BF96) + int denorm; +#endif + Bigint *b, *b1, *delta, *mlo, *mhi, *S; + U u; + char *s; +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif +#ifdef USE_BF96 /*{{*/ + BF96 *p10; + ULLong dbhi, dbits, dblo, den, hb, rb, rblo, res, res0, res3, reslo, sres, + sulp, tv0, tv1, tv2, tv3, ulp, ulplo, ulpmask, ures, ureslo, zb; + int eulp, k1, n2, ulpadj, ulpshift; +#else /*}{*/ +#ifndef Sudden_Underflow + ULong x; +#endif + Long L; + U d2, eps; + double ds; + int ieps, ilim0, k0, k_check, try_quick; +#ifndef No_leftright +#ifdef IEEE_Arith + U eps1; +#endif +#endif +#endif /*}}*/ +#ifdef Honor_FLT_ROUNDS /*{*/ + int Rounding; +#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ + Rounding = Flt_Rounds; +#else /*}{*/ + Rounding = 1; + switch(fegetround()) { + case FE_TOWARDZERO: Rounding = 0; break; + case FE_UPWARD: Rounding = 2; break; + case FE_DOWNWARD: Rounding = 3; + } +#endif /*}}*/ +#endif /*}*/ + + u.d = dd; + if (word0(&u) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(&u) &= ~Sign_bit; /* clear sign bit */ + } + else + *sign = 0; + +#if defined(IEEE_Arith) + defined(VAX) +#ifdef IEEE_Arith + if ((word0(&u) & Exp_mask) == Exp_mask) +#else + if (word0(&u) == 0x8000) +#endif + { + /* Infinity or NaN */ + *decpt = 9999; +#ifdef IEEE_Arith + if (!word1(&u) && !(word0(&u) & 0xfffff)) + return nrv_alloc("INFINITY", buf, blen, rve, 8 MTb); +#endif + return nrv_alloc("NAN", buf, blen, rve, 3 MTb); + } +#endif +#ifdef IBM + dval(&u) += 0; /* normalize */ +#endif + if (!dval(&u)) { + *decpt = 1; + return nrv_alloc("0", buf, blen, rve, 1 MTb); + } + +#ifdef SET_INEXACT +#ifndef USE_BF96 + try_quick = +#endif + oldinexact = get_inexact(); + inexact = 1; +#endif +#ifdef Honor_FLT_ROUNDS + if (Rounding >= 2) { + if (*sign) + Rounding = Rounding == 2 ? 0 : 2; + else + if (Rounding != 2) + Rounding = 0; + } +#endif +#ifdef USE_BF96 /*{{*/ + dbits = (u.LL & 0xfffffffffffffull) << 11; /* fraction bits */ + if ((be = u.LL >> 52)) /* biased exponent; nonzero ==> normal */ { + dbits |= 0x8000000000000000ull; + denorm = ulpadj = 0; + } + else { + denorm = 1; + ulpadj = be + 1; + dbits <<= 1; + if (!(dbits & 0xffffffff00000000ull)) { + dbits <<= 32; + be -= 32; + } + if (!(dbits & 0xffff000000000000ull)) { + dbits <<= 16; + be -= 16; + } + if (!(dbits & 0xff00000000000000ull)) { + dbits <<= 8; + be -= 8; + } + if (!(dbits & 0xf000000000000000ull)) { + dbits <<= 4; + be -= 4; + } + if (!(dbits & 0xc000000000000000ull)) { + dbits <<= 2; + be -= 2; + } + if (!(dbits & 0x8000000000000000ull)) { + dbits <<= 1; + be -= 1; + } + assert(be >= -51); + ulpadj -= be; + } + j = Lhint[be + 51]; + p10 = &pten[j]; + dbhi = dbits >> 32; + dblo = dbits & 0xffffffffull; + i = be - 0x3fe; + if (i < p10->e + || (i == p10->e && (dbhi < p10->b0 || (dbhi == p10->b0 && dblo < p10->b1)))) + --j; + k = j - 342; + + /* now 10^k <= dd < 10^(k+1) */ + +#else /*}{*/ + + b = d2b(&u, &be, &bbits MTb); +#ifdef Sudden_Underflow + i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); +#else + if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { +#endif + dval(&d2) = dval(&u); + word0(&d2) &= Frac_mask1; + word0(&d2) |= Exp_11; +#ifdef IBM + if (j = 11 - hi0bits(word0(&d2) & Frac_mask)) + dval(&d2) /= 1u << j; +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; +#ifdef IBM + i <<= 2; + i += j; +#endif +#ifndef Sudden_Underflow + denorm = 0; + } + else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32) + : word1(&u) << (32 - i); + dval(&d2) = x; + word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; + } +#endif + ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; + if (k >= 0 && k <= Ten_pmax) { + if (dval(&u) < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } +#endif /*}}*/ + if (mode < 0 || mode > 9) + mode = 0; + +#ifndef USE_BF96 +#ifndef SET_INEXACT +#ifdef Check_FLT_ROUNDS + try_quick = Rounding == 1; +#endif +#endif /*SET_INEXACT*/ +#endif + + if (mode > 5) { + mode -= 4; +#ifndef USE_BF96 + try_quick = 0; +#endif + } + leftright = 1; + ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ + /* silence erroneous "gcc -Wall" warning. */ + switch(mode) { + case 0: + case 1: + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + if (!buf) { + buf = rv_alloc(i MTb); + blen = sizeof(Bigint) + ((1 << ((int*)buf)[-1]) - 1)*sizeof(ULong) - sizeof(int); + } + else if (blen <= i) { + buf = 0; + if (rve) + *rve = buf + i; + return buf; + } + s = buf; + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if (mode < 2 || (leftright +#ifdef Honor_FLT_ROUNDS + && Rounding == 1 +#endif + )) { + if (!word1(&u) && !(word0(&u) & Bndry_mask) +#ifndef Sudden_Underflow + && word0(&u) & (Exp_mask & ~Exp_msk1) +#endif + ) { + /* The special case */ + spec_case = 1; + } + } + +#ifdef USE_BF96 /*{*/ + b = 0; + if (ilim < 0 && (mode == 3 || mode == 5)) { + S = mhi = 0; + goto no_digits; + } + i = 1; + j = 52 + 0x3ff - be; + ulpshift = 0; + ulplo = 0; + /* Can we do an exact computation with 64-bit integer arithmetic? */ + if (k < 0) { + if (k < -25) + goto toobig; + res = dbits >> 11; + n2 = pfivebits[k1 = -(k + 1)] + 53; + j1 = j; + if (n2 > 61) { + ulpshift = n2 - 61; + if (res & (ulpmask = (1ull << ulpshift) - 1)) + goto toobig; + j -= ulpshift; + res >>= ulpshift; + } + /* Yes. */ + res *= ulp = pfive[k1]; + if (ulpshift) { + ulplo = ulp; + ulp >>= ulpshift; + } + j += k; + if (ilim == 0) { + S = mhi = 0; + if (res > (5ull << j)) + goto one_digit; + goto no_digits; + } + goto no_div; + } + if (ilim == 0 && j + k >= 0) { + S = mhi = 0; + if ((dbits >> 11) > (pfive[k-1] << j)) + goto one_digit; + goto no_digits; + } + if (k <= dtoa_divmax && j + k >= 0) { + /* Another "yes" case -- we will use exact integer arithmetic. */ + use_exact: + Debug(++dtoa_stats[3]); + res = dbits >> 11; /* residual */ + ulp = 1; + if (k <= 0) + goto no_div; + j1 = j + k + 1; + den = pfive[k-i] << (j1 - i); + for(;;) { + dig = res / den; + *s++ = '0' + dig; + if (!(res -= dig*den)) { +#ifdef SET_INEXACT + inexact = 0; + oldinexact = 1; +#endif + goto retc; + } + if (ilim < 0) { + ures = den - res; + if (2*res <= ulp + && (spec_case ? 4*res <= ulp : (2*res < ulp || dig & 1))) + goto ulp_reached; + if (2*ures < ulp) + goto Roundup; + } + else if (i == ilim) { + switch(Rounding) { + case 0: goto retc; + case 2: goto Roundup; + default: (void)0; /* added by jart */ + } + ures = 2*res; + if (ures > den + || (ures == den && dig & 1) + || (spec_case && res <= ulp && 2*res >= ulp)) + goto Roundup; + goto retc; + } + if (j1 < ++i) { + res *= 10; + ulp *= 10; + } + else { + if (i > k) + break; + den = pfive[k-i] << (j1 - i); + } + } + no_div: + for(;;) { + dig = den = res >> j; + *s++ = '0' + dig; + if (!(res -= den << j)) { +#ifdef SET_INEXACT + inexact = 0; + oldinexact = 1; +#endif + goto retc; + } + if (ilim < 0) { + ures = (1ull << j) - res; + if (2*res <= ulp + && (spec_case ? 4*res <= ulp : (2*res < ulp || dig & 1))) { + ulp_reached: + if (ures < res + || (ures == res && dig & 1)) + goto Roundup; + goto retc; + } + if (2*ures < ulp) + goto Roundup; + } + --j; + if (i == ilim) { +#ifdef Honor_FLT_ROUNDS + switch(Rounding) { + case 0: goto retc; + case 2: goto Roundup; + } +#endif + hb = 1ull << j; + if (res & hb && (dig & 1 || res & (hb-1))) + goto Roundup; + if (spec_case && res <= ulp && 2*res >= ulp) { + Roundup: + while(*--s == '9') + if (s == buf) { + ++k; + *s++ = '1'; + goto ret1; + } + ++*s++; + goto ret1; + } + goto retc; + } + ++i; + res *= 5; + if (ulpshift) { + ulplo = 5*(ulplo & ulpmask); + ulp = 5*ulp + (ulplo >> ulpshift); + } + else + ulp *= 5; + } + } + toobig: + if (ilim > 28) + goto Fast_failed1; + /* Scale by 10^-k */ + p10 = &pten[342-k]; + tv0 = p10->b2 * dblo; /* rarely matters, but does, e.g., for 9.862818194192001e18 */ + tv1 = p10->b1 * dblo + (tv0 >> 32); + tv2 = p10->b2 * dbhi + (tv1 & 0xffffffffull); + tv3 = p10->b0 * dblo + (tv1>>32) + (tv2>>32); + res3 = p10->b1 * dbhi + (tv3 & 0xffffffffull); + res = p10->b0 * dbhi + (tv3>>32) + (res3>>32); + be += p10->e - 0x3fe; + eulp = j1 = be - 54 + ulpadj; + if (!(res & 0x8000000000000000ull)) { + --be; + res3 <<= 1; + res = (res << 1) | ((res3 & 0x100000000ull) >> 32); + } + res0 = res; /* save for Fast_failed */ +#if !defined(SET_INEXACT) && !defined(NO_DTOA_64) /*{*/ + if (ilim > 19) + goto Fast_failed; + Debug(++dtoa_stats[4]); + assert(be >= 0 && be <= 4); /* be = 0 is rare, but possible, e.g., for 1e20 */ + res >>= 4 - be; + ulp = p10->b0; /* ulp */ + ulp = (ulp << 29) | (p10->b1 >> 3); + /* scaled ulp = ulp * 2^(eulp - 60) */ + /* We maintain 61 bits of the scaled ulp. */ + if (ilim == 0) { + if (!(res & 0x7fffffffffffffeull) + || !((~res) & 0x7fffffffffffffeull)) + goto Fast_failed1; + S = mhi = 0; + if (res >= 0x5000000000000000ull) + goto one_digit; + goto no_digits; + } + rb = 1; /* upper bound on rounding error */ + for(;;++i) { + dig = res >> 60; + *s++ = '0' + dig; + res &= 0xfffffffffffffffull; + if (ilim < 0) { + ures = 0x1000000000000000ull - res; + if (eulp > 0) { + assert(eulp <= 4); + sulp = ulp << (eulp - 1); + if (res <= ures) { + if (res + rb > ures - rb) + goto Fast_failed; + if (res < sulp) + goto retc; + } + else { + if (res - rb <= ures + rb) + goto Fast_failed; + if (ures < sulp) + goto Roundup; + } + } + else { + zb = -(1ull << (eulp + 63)); + if (!(zb & res)) { + sres = res << (1 - eulp); + if (sres < ulp && (!spec_case || 2*sres < ulp)) { + if ((res+rb) << (1 - eulp) >= ulp) + goto Fast_failed; + if (ures < res) { + if (ures + rb >= res - rb) + goto Fast_failed; + goto Roundup; + } + if (ures - rb < res + rb) + goto Fast_failed; + goto retc; + } + } + if (!(zb & ures) && ures << -eulp < ulp) { + if (ures << (1 - eulp) < ulp) + goto Roundup; + goto Fast_failed; + } + } + } + else if (i == ilim) { + ures = 0x1000000000000000ull - res; + if (ures < res) { + if (ures <= rb || res - rb <= ures + rb) { + if (j + k >= 0 && k >= 0 && k <= 27) + goto use_exact1; + goto Fast_failed; + } +#ifdef Honor_FLT_ROUNDS + if (Rounding == 0) + goto retc; +#endif + goto Roundup; + } + if (res <= rb || ures - rb <= res + rb) { + if (j + k >= 0 && k >= 0 && k <= 27) { + use_exact1: + s = buf; + i = 1; + goto use_exact; + } + goto Fast_failed; + } +#ifdef Honor_FLT_ROUNDS + if (Rounding == 2) + goto Roundup; +#endif + goto retc; + } + rb *= 10; + if (rb >= 0x1000000000000000ull) + goto Fast_failed; + res *= 10; + ulp *= 5; + if (ulp & 0x8000000000000000ull) { + eulp += 4; + ulp >>= 3; + } + else { + eulp += 3; + ulp >>= 2; + } + } +#endif /*}*/ +#ifndef NO_BF96 + Fast_failed: +#endif + Debug(++dtoa_stats[5]); + s = buf; + i = 4 - be; + res = res0 >> i; + reslo = 0xffffffffull & res3; + if (i) + reslo = (res0 << (64 - i)) >> 32 | (reslo >> i); + rb = 0; + rblo = 4; /* roundoff bound */ + ulp = p10->b0; /* ulp */ + ulp = (ulp << 29) | (p10->b1 >> 3); + eulp = j1; + for(i = 1;;++i) { + dig = res >> 60; + *s++ = '0' + dig; + res &= 0xfffffffffffffffull; +#ifdef SET_INEXACT + if (!res && !reslo) { + if (!(res3 & 0xffffffffull)) { + inexact = 0; + oldinexact = 1; + } + goto retc; + } +#endif + if (ilim < 0) { + ures = 0x1000000000000000ull - res; + ureslo = 0; + if (reslo) { + ureslo = 0x100000000ull - reslo; + --ures; + } + if (eulp > 0) { + assert(eulp <= 4); + sulp = (ulp << (eulp - 1)) - rb; + if (res <= ures) { + if (res < sulp) { + if (res+rb < ures-rb) + goto retc; + } + } + else if (ures < sulp) { + if (res-rb > ures+rb) + goto Roundup; + } + goto Fast_failed1; + } + else { + zb = -(1ull << (eulp + 60)); + if (!(zb & (res + rb))) { + sres = (res - rb) << (1 - eulp); + if (sres < ulp && (!spec_case || 2*sres < ulp)) { + sres = res << (1 - eulp); + if ((j = eulp + 31) > 0) + sres += (rblo + reslo) >> j; + else + sres += (rblo + reslo) << -j; + if (sres + (rb << (1 - eulp)) >= ulp) + goto Fast_failed1; + if (sres >= ulp) + goto more96; + if (ures < res + || (ures == res && ureslo < reslo)) { + if (ures + rb >= res - rb) + goto Fast_failed1; + goto Roundup; + } + if (ures - rb <= res + rb) + goto Fast_failed1; + goto retc; + } + } + if (!(zb & ures) && (ures-rb) << (1 - eulp) < ulp) { + if ((ures + rb) << (1 - eulp) < ulp) + goto Roundup; + goto Fast_failed1; + } + } + } + else if (i == ilim) { + ures = 0x1000000000000000ull - res; + sres = ureslo = 0; + if (reslo) { + ureslo = 0x100000000ull - reslo; + --ures; + sres = (reslo + rblo) >> 31; + } + sres += 2*rb; + if (ures <= res) { + if (ures <=sres || res - ures <= sres) + goto Fast_failed1; +#ifdef Honor_FLT_ROUNDS + if (Rounding == 0) + goto retc; +#endif + goto Roundup; + } + if (res <= sres || ures - res <= sres) + goto Fast_failed1; +#ifdef Honor_FLT_ROUNDS + if (Rounding == 2) + goto Roundup; +#endif + goto retc; + } + more96: + rblo *= 10; + rb = 10*rb + (rblo >> 32); + rblo &= 0xffffffffull; + if (rb >= 0x1000000000000000ull) + goto Fast_failed1; + reslo *= 10; + res = 10*res + (reslo >> 32); + reslo &= 0xffffffffull; + ulp *= 5; + if (ulp & 0x8000000000000000ull) { + eulp += 4; + ulp >>= 3; + } + else { + eulp += 3; + ulp >>= 2; + } + } + Fast_failed1: + Debug(++dtoa_stats[6]); + S = mhi = mlo = 0; +#ifdef USE_BF96 + b = d2b(&u, &be, &bbits MTb); +#endif + s = buf; + i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); + i -= Bias; + if (ulpadj) + i -= ulpadj - 1; + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } +#endif /*}*/ + +#ifdef Honor_FLT_ROUNDS + if (mode > 1 && Rounding != 1) + leftright = 0; +#endif + +#ifndef USE_BF96 /*{*/ + if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + dval(&d2) = dval(&u); + j1 = -(k0 = k); + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(&u) /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + dval(&u) /= ds; + } + else if (j1 > 0) { + dval(&u) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(&u) *= bigtens[i]; + } + } + if (k_check && dval(&u) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(&u) *= 10.; + ieps++; + } + dval(&eps) = ieps*dval(&u) + 7.; + word0(&eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(&u) -= 5.; + if (dval(&u) > dval(&eps)) + goto one_digit; + if (dval(&u) < -dval(&eps)) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(&eps) = 0.5/tens[ilim-1] - dval(&eps); +#ifdef IEEE_Arith + if (j1 >= 307) { + eps1.d = 1.01e256; /* 1.01 allows roundoff in the next few lines */ + word0(&eps1) -= Exp_msk1 * (Bias+P-1); + dval(&eps1) *= tens[j1 & 0xf]; + for(i = 0, j = (j1-256) >> 4; j; j >>= 1, i++) + if (j & 1) + dval(&eps1) *= bigtens[i]; + if (eps.d < eps1.d) + eps.d = eps1.d; + if (10. - u.d < 10.*eps.d && eps.d < 1.) { + /* eps.d < 1. excludes trouble with the tiniest denormal */ + *s++ = '1'; + ++k; + goto ret1; + } + } +#endif + for(i = 0;;) { + L = dval(&u); + dval(&u) -= L; + *s++ = '0' + (int)L; + if (1. - dval(&u) < dval(&eps)) + goto bump_up; + if (dval(&u) < dval(&eps)) + goto retc; + if (++i >= ilim) + break; + dval(&eps) *= 10.; + dval(&u) *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + dval(&eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(&u) *= 10.) { + L = (Long)(dval(&u)); + if (!(dval(&u) -= L)) + ilim = i; + *s++ = '0' + (int)L; + if (i == ilim) { + if (dval(&u) > 0.5 + dval(&eps)) + goto bump_up; + else if (dval(&u) < 0.5 - dval(&eps)) + goto retc; + break; + } + } +#ifndef No_leftright + } +#endif + fast_failed: + s = buf; + dval(&u) = dval(&d2); + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(&u) <= 5*ds) + goto no_digits; + goto one_digit; + } + for(i = 1;; i++, dval(&u) *= 10.) { + L = (Long)(dval(&u) / ds); + dval(&u) -= L*ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(&u) < 0) { + L--; + dval(&u) += ds; + } +#endif + *s++ = '0' + (int)L; + if (!dval(&u)) { +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (i == ilim) { +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch(Rounding) { + case 0: goto retc; + case 2: goto bump_up; + } +#endif + dval(&u) += dval(&u); +#ifdef ROUND_BIASED + if (dval(&u) >= ds) +#else + if (dval(&u) > ds || (dval(&u) == ds && L & 1)) +#endif + { + bump_up: + while(*--s == '9') + if (s == buf) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + } + goto retc; + } + +#endif /*}*/ + m2 = b2; + m5 = b5; + mhi = mlo = 0; + if (leftright) { + i = +#ifndef Sudden_Underflow + denorm ? be + (Bias + (P-1) - 1 + 1) : +#endif +#ifdef IBM + 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); +#else + 1 + P - bbits; +#endif + b2 += i; + s2 += i; + mhi = i2b(1 MTb); + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5 MTb); + b1 = mult(mhi, b MTb); + Bfree(b MTb); + b = b1; + } + if ((j = b5 - m5)) + b = pow5mult(b, j MTb); + } + else + b = pow5mult(b, b5 MTb); + } + S = i2b(1 MTb); + if (s5 > 0) + S = pow5mult(S, s5 MTb); + + if (spec_case) { + b2 += Log2P; + s2 += Log2P; + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ + i = dshift(S, s2); + b2 += i; + m2 += i; + s2 += i; + if (b2 > 0) + b = lshift(b, b2 MTb); + if (s2 > 0) + S = lshift(S, s2 MTb); +#ifndef USE_BF96 + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0 MTb); /* we botched the k estimate */ + if (leftright) + mhi = multadd(mhi, 10, 0 MTb); + ilim = ilim1; + } + } +#endif + if (ilim <= 0 && (mode == 3 || mode == 5)) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0 MTb)) <= 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + goto ret; + } + one_digit: + *s++ = '1'; + ++k; + goto ret; + } + if (leftright) { + if (m2 > 0) + mhi = lshift(mhi, m2 MTb); + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k MTb); + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P MTb); + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi MTb); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta MTb); +#ifndef ROUND_BIASED + if (j1 == 0 && mode != 1 && !(word1(&u) & 1) +#ifdef Honor_FLT_ROUNDS + && (mode <= 1 || Rounding >= 1) +#endif + ) { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; +#ifdef SET_INEXACT + else if (!b->x[0] && b->wds <= 1) + inexact = 0; +#endif + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || (j == 0 && mode != 1 +#ifndef ROUND_BIASED + && !(word1(&u) & 1) +#endif + )) { + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto accept_dig; + } +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch(Rounding) { + case 0: goto accept_dig; + case 2: goto keep_dig; + } +#endif /*Honor_FLT_ROUNDS*/ + if (j1 > 0) { + b = lshift(b, 1 MTb); + j1 = cmp(b, S); +#ifdef ROUND_BIASED + if (j1 >= 0 /*)*/ +#else + if ((j1 > 0 || (j1 == 0 && dig & 1)) +#endif + && dig++ == '9') + goto round_9_up; + } + accept_dig: + *s++ = dig; + goto ret; + } + if (j1 > 0) { +#ifdef Honor_FLT_ROUNDS + if (!Rounding && mode > 1) + goto accept_dig; +#endif + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } +#ifdef Honor_FLT_ROUNDS + keep_dig: +#endif + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0 MTb); + if (mlo == mhi) + mlo = mhi = multadd(mhi, 10, 0 MTb); + else { + mlo = multadd(mlo, 10, 0 MTb); + mhi = multadd(mhi, 10, 0 MTb); + } + } + } + else + for(i = 1;; i++) { + dig = quorem(b,S) + '0'; + *s++ = dig; + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto ret; + } + if (i >= ilim) + break; + b = multadd(b, 10, 0 MTb); + } + + /* Round off last digit */ + +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch(Rounding) { + case 0: goto ret; + case 2: goto roundoff; + } +#endif + b = lshift(b, 1 MTb); + j = cmp(b, S); +#ifdef ROUND_BIASED + if (j >= 0) +#else + if (j > 0 || (j == 0 && dig & 1)) +#endif + { + roundoff: + while(*--s == '9') + if (s == buf) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + ret: + Bfree(S MTb); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo MTb); + Bfree(mhi MTb); + } + retc: + while(s > buf && s[-1] == '0') + --s; + ret1: + if (b) + Bfree(b MTb); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(&u) = Exp_1 + (70 << Exp_shift); + word1(&u) = 0; + dval(&u) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif + return buf; + } + + char * +dtoa(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) +{ + /* Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + See dtoa_r() above for details on the other arguments. + */ +#ifndef MULTIPLE_THREADS + if (dtoa_result) + freedtoa(dtoa_result); +#endif + return dtoa_r(dd, mode, ndigits, decpt, sign, rve, 0, 0); + } + +#ifdef __cplusplus +} +#endif diff --git a/third_party/dtoa/dtoa.h b/third_party/dtoa/dtoa.h new file mode 100644 index 00000000..398ba73a --- /dev/null +++ b/third_party/dtoa/dtoa.h @@ -0,0 +1,23 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_DTOA_DTOA_H_ +#define COSMOPOLITAN_THIRD_PARTY_DTOA_DTOA_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +/* see also xdtoa() in //libc/x */ +double strtod(const char *s00, char **se); +char *g_fmt(char *buf /*[32]*/, double x); + +char *dtoa(double d, int mode, int ndigits, int *decpt, int *sign, + char **rve) nodiscard; +void freedtoa(char *s); +char *dtoa_r(double dd, int mode, int ndigits, int *decpt, int *sign, + char **rve, char *buf, size_t blen); +double plan9_strtod(const char *as, char **aas); + +/* #if defined(TINY) || defined(TINY_STRTOD) */ +/* #define strtod(X, Y) plan9_strtod(X, Y) */ +/* #endif */ + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_DTOA_DTOA_H_ */ diff --git a/third_party/dtoa/dtoa.mk b/third_party/dtoa/dtoa.mk new file mode 100644 index 00000000..281e2b49 --- /dev/null +++ b/third_party/dtoa/dtoa.mk @@ -0,0 +1,63 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += THIRD_PARTY_DTOA + +THIRD_PARTY_DTOA_ARTIFACTS += THIRD_PARTY_DTOA_A +THIRD_PARTY_DTOA = $(THIRD_PARTY_DTOA_A_DEPS) $(THIRD_PARTY_DTOA_A) +THIRD_PARTY_DTOA_A = o/$(MODE)/third_party/dtoa/dtoa.a +THIRD_PARTY_DTOA_A_FILES := $(wildcard third_party/dtoa/*) +THIRD_PARTY_DTOA_A_HDRS = $(filter %.h,$(THIRD_PARTY_DTOA_A_FILES)) +THIRD_PARTY_DTOA_A_SRCS_S = $(filter %.S,$(THIRD_PARTY_DTOA_A_FILES)) +THIRD_PARTY_DTOA_A_SRCS_C = $(filter %.c,$(THIRD_PARTY_DTOA_A_FILES)) + +THIRD_PARTY_DTOA_A_SRCS = \ + $(THIRD_PARTY_DTOA_A_SRCS_S) \ + $(THIRD_PARTY_DTOA_A_SRCS_C) + +THIRD_PARTY_DTOA_A_OBJS = \ + $(THIRD_PARTY_DTOA_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(THIRD_PARTY_DTOA_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(THIRD_PARTY_DTOA_A_SRCS_C:%.c=o/$(MODE)/%.o) + +THIRD_PARTY_DTOA_A_CHECKS = \ + $(THIRD_PARTY_DTOA_A).pkg \ + $(THIRD_PARTY_DTOA_A_HDRS:%=o/$(MODE)/%.ok) + +THIRD_PARTY_DTOA_A_DIRECTDEPS = \ + LIBC_TINYMATH \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_SYSV + +THIRD_PARTY_DTOA_A_DEPS := \ + $(call uniq,$(foreach x,$(THIRD_PARTY_DTOA_A_DIRECTDEPS),$($(x)))) + +$(THIRD_PARTY_DTOA_A): \ + third_party/dtoa/ \ + $(THIRD_PARTY_DTOA_A).pkg \ + $(THIRD_PARTY_DTOA_A_OBJS) + +$(THIRD_PARTY_DTOA_A).pkg: \ + $(THIRD_PARTY_DTOA_A_OBJS) \ + $(foreach x,$(THIRD_PARTY_DTOA_A_DIRECTDEPS),$($(x)_A).pkg) + +$(THIRD_PARTY_DTOA_A_OBJS): \ + OVERRIDE_CFLAGS += \ + -ansi \ + $(OLD_CODE) \ + $(IEEE_MATH) \ + -ffunction-sections \ + -fdata-sections + +THIRD_PARTY_DTOA_LIBS = $(foreach x,$(THIRD_PARTY_DTOA_ARTIFACTS),$($(x))) +THIRD_PARTY_DTOA_SRCS = $(foreach x,$(THIRD_PARTY_DTOA_ARTIFACTS),$($(x)_SRCS)) +THIRD_PARTY_DTOA_HDRS = $(foreach x,$(THIRD_PARTY_DTOA_ARTIFACTS),$($(x)_HDRS)) +THIRD_PARTY_DTOA_CHECKS = $(foreach x,$(THIRD_PARTY_DTOA_ARTIFACTS),$($(x)_CHECKS)) +THIRD_PARTY_DTOA_OBJS = $(foreach x,$(THIRD_PARTY_DTOA_ARTIFACTS),$($(x)_OBJS)) +$(THIRD_PARTY_DTOA_OBJS): $(BUILD_FILES) third_party/dtoa/dtoa.mk + +.PHONY: o/$(MODE)/third_party/dtoa +o/$(MODE)/third_party/dtoa: $(THIRD_PARTY_DTOA_CHECKS) diff --git a/third_party/dtoa/g_fmt.c b/third_party/dtoa/g_fmt.c new file mode 100644 index 00000000..e263ab5b --- /dev/null +++ b/third_party/dtoa/g_fmt.c @@ -0,0 +1,114 @@ +#pragma GCC diagnostic ignored "-Wparentheses" +#pragma GCC diagnostic ignored "-Wunused-label" + +asm(".ident\t\"\\n\\n\ +dtoa (MIT License)\\n\ +The author of this software is David M. Gay.\\n\ +Copyright (c) 1991, 2000, 2001 by Lucent Technologies.\""); +asm(".include \"libc/disclaimer.inc\""); + +/* clang-format off */ +/**************************************************************** + * + * The author of this software is David M. Gay. + * + * Copyright (c) 1991, 1996 by Lucent Technologies. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + * + ***************************************************************/ + +/* g_fmt(buf,x) stores the closest decimal approximation to x in buf; + * it suffices to declare buf + * char buf[32]; + */ + +#ifdef __cplusplus +extern "C" { +#endif + extern char *dtoa(double, int, int, int *, int *, char **); + extern char *g_fmt(char *, double); + extern void freedtoa(char*); +#ifdef __cplusplus + } +#endif + + char * +g_fmt(register char *b, double x) +{ + register int i, k; + register char *s; + int decpt, j, sign; + char *b0, *s0, *se; + + b0 = b; +#ifdef IGNORE_ZERO_SIGN + if (!x) { + *b++ = '0'; + *b = 0; + goto done; + } +#endif + s = s0 = dtoa(x, 0, 0, &decpt, &sign, &se); + if (sign) + *b++ = '-'; + if (decpt == 9999) /* Infinity or Nan */ { + while(*b++ = *s++); + goto done0; + } + if (decpt <= -4 || decpt > se - s + 5) { + *b++ = *s++; + if (*s) { + *b++ = '.'; + while(*b = *s++) + b++; + } + *b++ = 'e'; + /* sprintf(b, "%+.2d", decpt - 1); */ + if (--decpt < 0) { + *b++ = '-'; + decpt = -decpt; + } + else + *b++ = '+'; + for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10); + for(;;) { + i = decpt / k; + *b++ = i + '0'; + if (--j <= 0) + break; + decpt -= i*k; + decpt *= 10; + } + *b = 0; + } + else if (decpt <= 0) { + *b++ = '.'; + for(; decpt < 0; decpt++) + *b++ = '0'; + while(*b++ = *s++); + } + else { + while(*b = *s++) { + b++; + if (--decpt == 0 && *s) + *b++ = '.'; + } + for(; decpt > 0; decpt--) + *b++ = '0'; + *b = 0; + } + done0: + freedtoa(s0); + done: + return b0; + } diff --git a/third_party/dtoa/strtod.c b/third_party/dtoa/strtod.c new file mode 100644 index 00000000..6c94799d --- /dev/null +++ b/third_party/dtoa/strtod.c @@ -0,0 +1,532 @@ +#include "libc/macros.h" +#include "libc/str/str.h" +#include "third_party/dtoa/dtoa.h" + +/** + * @fileoverview Plan 9 strtod(). + * It's like dtoa but smaller. + */ + +asm(".ident\t\"\\n\\n\ +Plan 9 » strtod (MIT)\\n\ +The authors of this software are Rob Pike and Ken Thompson.\\n\ +Copyright (c) 2002 by Lucent Technologies.\""); +asm(".include \"libc/disclaimer.inc\""); + +#define nelem(a) ARRAYLEN(a) +#define ulong unsigned long +#define nil NULL +#define __NaN() __builtin_nanf("") + +/* clang-format off */ +/* The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ + +#include "libc/str/str.h" +#include "libc/math.h" +#include "libc/sysv/errfuns.h" + +static ulong +umuldiv(ulong a, ulong b, ulong c) +{ + double d; + + d = ((double)a * (double)b) / (double)c; + if(d >= 4294967295.) + d = 4294967295.; + return (ulong)d; +} + +/* + * This routine will convert to arbitrary precision + * floating point entirely in multi-precision fixed. + * The answer is the closest floating point number to + * the given decimal number. Exactly half way are + * rounded ala ieee rules. + * Method is to scale input decimal between .500 and .999... + * with external power of 2, then binary search for the + * closest mantissa to this decimal number. + * Nmant is is the required precision. (53 for ieee dp) + * Nbits is the max number of bits/word. (must be <= 28) + * Prec is calculated - the number of words of fixed mantissa. + */ +enum +{ + Nbits = 28, /* bits safely represented in a ulong */ + Nmant = 53, /* bits of precision required */ + Prec = (Nmant+Nbits+1)/Nbits, /* words of Nbits each to represent mantissa */ + Sigbit = 1<<(Prec*Nbits-Nmant), /* first significant bit of Prec-th word */ + Ndig = 1500, + One = (ulong)(1<>1), + Maxe = 310, + + Fsign = 1<<0, /* found - */ + Fesign = 1<<1, /* found e- */ + Fdpoint = 1<<2, /* found . */ + + S0 = 0, /* _ _S0 +S1 #S2 .S3 */ + S1, /* _+ #S2 .S3 */ + S2, /* _+# #S2 .S4 eS5 */ + S3, /* _+. #S4 */ + S4, /* _+#.# #S4 eS5 */ + S5, /* _+#.#e +S6 #S7 */ + S6, /* _+#.#e+ #S7 */ + S7 /* _+#.#e+# #S7 */ +}; + +static int xcmp(char*, char*); +static int fpcmp(char*, ulong*); +static void frnorm(ulong*); +static void divascii(char*, int*, int*, int*); +static void mulascii(char*, int*, int*, int*); + +typedef struct Tab Tab; +struct Tab +{ + int bp; + int siz; + char* cmp; +}; + +double +plan9_strtod(const char *as, char **aas) +{ + int na, ex, dp, bp, c, i, flag, state; + ulong low[Prec], hig[Prec], mid[Prec]; + double d; + char *s, a[Ndig]; + + flag = 0; /* Fsign, Fesign, Fdpoint */ + na = 0; /* number of digits of a[] */ + dp = 0; /* na of decimal point */ + ex = 0; /* exonent */ + + state = S0; + for(s=(char*)as;; s++) { + c = *s; + if(c >= '0' && c <= '9') { + switch(state) { + case S0: + case S1: + case S2: + state = S2; + break; + case S3: + case S4: + state = S4; + break; + + case S5: + case S6: + case S7: + state = S7; + ex = ex*10 + (c-'0'); + continue; + } + if(na == 0 && c == '0') { + dp--; + continue; + } + if(na < Ndig-50) + a[na++] = c; + continue; + } + switch(c) { + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + if(state == S0) + continue; + break; + case '-': + if(state == S0) + flag |= Fsign; + else + flag |= Fesign; + case '+': + if(state == S0) + state = S1; + else + if(state == S5) + state = S6; + else + break; /* syntax */ + continue; + case '.': + flag |= Fdpoint; + dp = na; + if(state == S0 || state == S1) { + state = S3; + continue; + } + if(state == S2) { + state = S4; + continue; + } + break; + case 'e': + case 'E': + if(state == S2 || state == S4) { + state = S5; + continue; + } + break; + } + break; + } + + /* + * clean up return char-pointer + */ + switch(state) { + case S0: + if(strcasecmp(s, "nan") == 0) { + if(aas != nil) + *aas = s+3; + goto retnan; + } + case S1: + if(strcasecmp(s, "infinity") == 0) { + if(aas != nil) + *aas = s+8; + goto retinf; + } + if(strcasecmp(s, "inf") == 0) { + if(aas != nil) + *aas = s+3; + goto retinf; + } + case S3: + if(aas != nil) + *aas = (char*)as; + goto ret0; /* no digits found */ + case S6: + s--; /* back over +- */ + case S5: + s--; /* back over e */ + break; + } + if(aas != nil) + *aas = s; + + if(flag & Fdpoint) + while(na > 0 && a[na-1] == '0') + na--; + if(na == 0) + goto ret0; /* zero */ + a[na] = 0; + if(!(flag & Fdpoint)) + dp = na; + if(flag & Fesign) + ex = -ex; + dp += ex; + if(dp < -Maxe){ + erange(); + goto ret0; /* underflow by exp */ + } else + if(dp > +Maxe) + goto retinf; /* overflow by exp */ + + /* + * normalize the decimal ascii number + * to range .[5-9][0-9]* e0 + */ + bp = 0; /* binary exponent */ + while(dp > 0) + divascii(a, &na, &dp, &bp); + while(dp < 0 || a[0] < '5') + mulascii(a, &na, &dp, &bp); + + /* close approx by naïve conversion */ + mid[0] = 0; + mid[1] = 1; + for(i=0; (c=a[i]) != '\0'; i++) { + mid[0] = mid[0]*10 + (c-'0'); + mid[1] = mid[1]*10; + if(i >= 8) + break; + } + low[0] = umuldiv(mid[0], One, mid[1]); + hig[0] = umuldiv(mid[0]+1, One, mid[1]); + for(i=1; i>= 1; + } + frnorm(mid); + + /* compare */ + c = fpcmp(a, mid); + if(c > 0) { + c = 1; + for(i=0; i= Sigbit/2) { + mid[Prec-1] += Sigbit; + frnorm(mid); + } + goto out; + +ret0: + return 0; + +retnan: + return __NaN(); + +retinf: + /* + * Unix strtod requires these. Plan 9 would return Inf(0) or Inf(-1). */ + erange(); + if(flag & Fsign) + return -HUGE_VAL; + return HUGE_VAL; + +out: + d = 0; + for(i=0; i0; i--) { + f[i] += c; + c = f[i] >> Nbits; + f[i] &= One-1; + } + f[0] += c; +} + +static int +fpcmp(char *a, ulong* f) +{ + ulong tf[Prec]; + int i, d, c; + + for(i=0; i> Nbits) + '0'; + tf[0] &= One-1; + + /* compare next digit */ + c = *a; + if(c == 0) { + if('0' < d) + return -1; + if(tf[0] != 0) + goto cont; + for(i=1; i d) + return +1; + if(c < d) + return -1; + a++; + cont:; + } +} + +static void +divby(char *a, int *na, int b) +{ + int n, c; + char *p; + + p = a; + n = 0; + while(n>>b == 0) { + c = *a++; + if(c == 0) { + while(n) { + c = n*10; + if(c>>b) + break; + n = c; + } + goto xx; + } + n = n*10 + c-'0'; + (*na)--; + } + for(;;) { + c = n>>b; + n -= c<>b; + n -= c<= (int)(nelem(tab1))) + d = (int)(nelem(tab1))-1; + t = tab1 + d; + b = t->bp; + if(memcmp(a, t->cmp, t->siz) > 0) + d--; + *dp -= d; + *bp += b; + divby(a, na, b); +} + +static void +mulby(char *a, char *p, char *q, int b) +{ + int n, c; + + n = 0; + *p = 0; + for(;;) { + q--; + if(q < a) + break; + c = *q - '0'; + c = (c<= (int)(nelem(tab2))) + d = (int)(nelem(tab2))-1; + t = tab2 + d; + b = t->bp; + if(memcmp(a, t->cmp, t->siz) < 0) + d--; + p = a + *na; + *bp -= b; + *dp += d; + *na += d; + mulby(a, p+d, p, b); +} diff --git a/third_party/duktape/LICENSE.txt b/third_party/duktape/LICENSE.txt new file mode 100644 index 00000000..aad07536 --- /dev/null +++ b/third_party/duktape/LICENSE.txt @@ -0,0 +1,25 @@ +=============== +Duktape license +=============== + +(http://opensource.org/licenses/MIT) + +Copyright (c) 2013-2019 by Duktape authors (see AUTHORS.rst) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/third_party/duktape/authors.rst b/third_party/duktape/authors.rst new file mode 100644 index 00000000..a01daa9c --- /dev/null +++ b/third_party/duktape/authors.rst @@ -0,0 +1,110 @@ +=============== +Duktape authors +=============== + +Copyright +========= + +Duktape copyrights are held by its authors. Each author has a copyright +to their contribution, and agrees to irrevocably license the contribution +under the Duktape ``LICENSE.txt``. + +Authors +======= + +Please include an e-mail address, a link to your GitHub profile, or something +similar to allow your contribution to be identified accurately. + +The following people have contributed code, website contents, or Wiki contents, +and agreed to irrevocably license their contributions under the Duktape +``LICENSE.txt`` (in order of appearance): + +* Sami Vaarala +* Niki Dobrev +* Andreas Öman +* László Langó +* Legimet +* Karl Skomski +* Bruce Pascoe +* René Hollander +* Julien Hamaide (https://github.com/crazyjul) +* Sebastian Götte (https://github.com/jaseg) +* Tomasz Magulski (https://github.com/magul) +* \D. Bohdan (https://github.com/dbohdan) +* Ondřej Jirman (https://github.com/megous) +* Saúl Ibarra Corretgé +* Jeremy HU +* Ole André Vadla Ravnås (https://github.com/oleavr) +* Harold Brenes (https://github.com/harold-b) +* Oliver Crow (https://github.com/ocrow) +* Jakub Chłapiński (https://github.com/jchlapinski) +* Brett Vickers (https://github.com/beevik) +* Dominik Okwieka (https://github.com/okitec) +* Remko Tronçon (https://el-tramo.be) +* Romero Malaquias (rbsm@ic.ufal.br) +* Michael Drake +* Steven Don (https://github.com/shdon) +* Simon Stone (https://github.com/sstone1) +* \J. McC. (https://github.com/jmhmccr) +* Jakub Nowakowski (https://github.com/jimvonmoon) +* Tommy Nguyen (https://github.com/tn0502) +* Fabrice Fontaine (https://github.com/ffontaine) +* Christopher Hiller (https://github.com/boneskull) +* Gonzalo Diethelm (https://github.com/gonzus) +* Michal Kasperek (https://github.com/michalkas) +* Andrew Janke (https://github.com/apjanke) +* Steve Fan (https://github.com/stevefan1999) +* Edward Betts (https://github.com/edwardbetts) +* Ozhan Duz (https://github.com/webfolderio) +* Akos Kiss (https://github.com/akosthekiss) +* TheBrokenRail (https://github.com/TheBrokenRail) +* Jesse Doyle (https://github.com/jessedoyle) +* Gero Kuehn (https://github.com/dc6jgk) +* James Swift (https://github.com/phraemer) +* Luis de Bethencourt (https://github.com/luisbg) +* Ian Whyman (https://github.com/v00d00) + +Other contributions +=================== + +The following people have contributed something other than code (e.g. reported +bugs, provided ideas, etc; roughly in order of appearance): + +* Greg Burns +* Anthony Rabine +* Carlos Costa +* Aurélien Bouilland +* Preet Desai (Pris Matic) +* judofyr (http://www.reddit.com/user/judofyr) +* Jason Woofenden +* Michał Przybyś +* Anthony Howe +* Conrad Pankoff +* Jim Schimpf +* Rajaran Gaunker (https://github.com/zimbabao) +* Andreas Öman +* Doug Sanden +* Josh Engebretson (https://github.com/JoshEngebretson) +* Remo Eichenberger (https://github.com/remoe) +* Mamod Mehyar (https://github.com/mamod) +* David Demelier (https://github.com/markand) +* Tim Caswell (https://github.com/creationix) +* Mitchell Blank Jr (https://github.com/mitchblank) +* https://github.com/yushli +* Seo Sanghyeon (https://github.com/sanxiyn) +* Han ChoongWoo (https://github.com/tunz) +* Joshua Peek (https://github.com/josh) +* Bruce E. Pascoe (https://github.com/fatcerberus) +* https://github.com/Kelledin +* https://github.com/sstruchtrup +* Michael Drake (https://github.com/tlsa) +* https://github.com/chris-y +* Laurent Zubiaur (https://github.com/lzubiaur) +* Neil Kolban (https://github.com/nkolban) +* Wilhelm Wanecek (https://github.com/wanecek) +* Andrew Janke (https://github.com/apjanke) +* Unamer (https://github.com/unamer) +* Karl Dahlke (eklhad@gmail.com) + +If you are accidentally missing from this list, send me an e-mail +(``sami.vaarala@iki.fi``) and I'll fix the omission. diff --git a/third_party/duktape/duk_alloc_default.c b/third_party/duktape/duk_alloc_default.c new file mode 100644 index 00000000..a882a82c --- /dev/null +++ b/third_party/duktape/duk_alloc_default.c @@ -0,0 +1,34 @@ +/* + * Default allocation functions. + * + * Assumes behavior such as malloc allowing zero size, yielding + * a NULL or a unique pointer which is a no-op for free. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS) +DUK_INTERNAL void *duk_default_alloc_function(void *udata, duk_size_t size) { + void *res; + DUK_UNREF(udata); + res = DUK_ANSI_MALLOC(size); + DUK_DDD(DUK_DDDPRINT("default alloc function: %lu -> %p", + (unsigned long) size, (void *) res)); + return res; +} + +DUK_INTERNAL void *duk_default_realloc_function(void *udata, void *ptr, duk_size_t newsize) { + void *res; + DUK_UNREF(udata); + res = DUK_ANSI_REALLOC(ptr, newsize); + DUK_DDD(DUK_DDDPRINT("default realloc function: %p %lu -> %p", + (void *) ptr, (unsigned long) newsize, (void *) res)); + return res; +} + +DUK_INTERNAL void duk_default_free_function(void *udata, void *ptr) { + DUK_DDD(DUK_DDDPRINT("default free function: %p", (void *) ptr)); + DUK_UNREF(udata); + DUK_ANSI_FREE(ptr); +} +#endif /* DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS */ diff --git a/third_party/duktape/duk_api_buffer.c b/third_party/duktape/duk_api_buffer.c new file mode 100644 index 00000000..9f241591 --- /dev/null +++ b/third_party/duktape/duk_api_buffer.c @@ -0,0 +1,73 @@ +/* + * Buffer + */ + +#include "third_party/duktape/duk_internal.h" + +DUK_EXTERNAL void *duk_resize_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t new_size) { + duk_hbuffer_dynamic *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = (duk_hbuffer_dynamic *) duk_require_hbuffer(thr, idx); + DUK_ASSERT(h != NULL); + + if (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) { + DUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE); + DUK_WO_NORETURN(return NULL;); + } + + /* Maximum size check is handled by callee. */ + duk_hbuffer_resize(thr, h, new_size); + + return DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h); +} + +DUK_EXTERNAL void *duk_steal_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) { + duk_hbuffer_dynamic *h; + void *ptr; + duk_size_t sz; + + DUK_ASSERT_API_ENTRY(thr); + + h = (duk_hbuffer_dynamic *) duk_require_hbuffer(thr, idx); + DUK_ASSERT(h != NULL); + + if (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) { + DUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE); + DUK_WO_NORETURN(return NULL;); + } + + /* Forget the previous allocation, setting size to 0 and alloc to + * NULL. Caller is responsible for freeing the previous allocation. + * Getting the allocation and clearing it is done in the same API + * call to avoid any chance of a realloc. + */ + ptr = DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h); + sz = DUK_HBUFFER_DYNAMIC_GET_SIZE(h); + if (out_size) { + *out_size = sz; + } + DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(thr->heap, h); + DUK_HBUFFER_DYNAMIC_SET_SIZE(h, 0); + + return ptr; +} + +DUK_EXTERNAL void duk_config_buffer(duk_hthread *thr, duk_idx_t idx, void *ptr, duk_size_t len) { + duk_hbuffer_external *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = (duk_hbuffer_external *) duk_require_hbuffer(thr, idx); + DUK_ASSERT(h != NULL); + + if (!DUK_HBUFFER_HAS_EXTERNAL(h)) { + DUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE); + DUK_WO_NORETURN(return;); + } + DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h)); + + DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(thr->heap, h, ptr); + DUK_HBUFFER_EXTERNAL_SET_SIZE(h, len); +} diff --git a/third_party/duktape/duk_api_bytecode.c b/third_party/duktape/duk_api_bytecode.c new file mode 100644 index 00000000..3b7a8417 --- /dev/null +++ b/third_party/duktape/duk_api_bytecode.c @@ -0,0 +1,760 @@ +/* + * Bytecode dump/load + * + * The bytecode load primitive is more important performance-wise than the + * dump primitive. + * + * Unlike most Duktape API calls, bytecode dump/load is not guaranteed to be + * memory safe for invalid arguments - caller beware! There's little point + * in trying to achieve memory safety unless bytecode instructions are also + * validated which is not easy to do with indirect register references etc. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_BYTECODE_DUMP_SUPPORT) + +#define DUK__SER_MARKER 0xbf +#define DUK__SER_STRING 0x00 +#define DUK__SER_NUMBER 0x01 +#define DUK__BYTECODE_INITIAL_ALLOC 256 +#define DUK__NO_FORMALS 0xffffffffUL + +/* + * Dump/load helpers, xxx_raw() helpers do no buffer checks + */ + +DUK_LOCAL const duk_uint8_t *duk__load_string_raw(duk_hthread *thr, const duk_uint8_t *p) { + duk_uint32_t len; + + len = DUK_RAW_READINC_U32_BE(p); + duk_push_lstring(thr, (const char *) p, len); + p += len; + return p; +} + +DUK_LOCAL const duk_uint8_t *duk__load_buffer_raw(duk_hthread *thr, const duk_uint8_t *p) { + duk_uint32_t len; + duk_uint8_t *buf; + + len = DUK_RAW_READINC_U32_BE(p); + buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) len); + DUK_ASSERT(buf != NULL); + duk_memcpy((void *) buf, (const void *) p, (size_t) len); + p += len; + return p; +} + +DUK_LOCAL duk_uint8_t *duk__dump_hstring_raw(duk_uint8_t *p, duk_hstring *h) { + duk_size_t len; + duk_uint32_t tmp32; + + DUK_ASSERT(h != NULL); + + len = DUK_HSTRING_GET_BYTELEN(h); + DUK_ASSERT(len <= 0xffffffffUL); /* string limits */ + tmp32 = (duk_uint32_t) len; + DUK_RAW_WRITEINC_U32_BE(p, tmp32); + duk_memcpy((void *) p, + (const void *) DUK_HSTRING_GET_DATA(h), + len); + p += len; + return p; +} + +DUK_LOCAL duk_uint8_t *duk__dump_hbuffer_raw(duk_hthread *thr, duk_uint8_t *p, duk_hbuffer *h) { + duk_size_t len; + duk_uint32_t tmp32; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(h != NULL); + DUK_UNREF(thr); + + len = DUK_HBUFFER_GET_SIZE(h); + DUK_ASSERT(len <= 0xffffffffUL); /* buffer limits */ + tmp32 = (duk_uint32_t) len; + DUK_RAW_WRITEINC_U32_BE(p, tmp32); + /* When len == 0, buffer data pointer may be NULL. */ + duk_memcpy_unsafe((void *) p, + (const void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h), + len); + p += len; + return p; +} + +DUK_LOCAL duk_uint8_t *duk__dump_string_prop(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func, duk_small_uint_t stridx) { + duk_hstring *h_str; + duk_tval *tv; + + tv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx); + if (tv != NULL && DUK_TVAL_IS_STRING(tv)) { + h_str = DUK_TVAL_GET_STRING(tv); + DUK_ASSERT(h_str != NULL); + } else { + h_str = DUK_HTHREAD_STRING_EMPTY_STRING(thr); + DUK_ASSERT(h_str != NULL); + } + DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL); /* ensures no overflow */ + p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(h_str), p); + p = duk__dump_hstring_raw(p, h_str); + return p; +} + +DUK_LOCAL duk_uint8_t *duk__dump_buffer_prop(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func, duk_small_uint_t stridx) { + duk_tval *tv; + + tv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx); + if (tv != NULL && DUK_TVAL_IS_BUFFER(tv)) { + duk_hbuffer *h_buf; + h_buf = DUK_TVAL_GET_BUFFER(tv); + DUK_ASSERT(h_buf != NULL); + DUK_ASSERT(DUK_HBUFFER_MAX_BYTELEN <= 0x7fffffffUL); /* ensures no overflow */ + p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HBUFFER_GET_SIZE(h_buf), p); + p = duk__dump_hbuffer_raw(thr, p, h_buf); + } else { + p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p); + DUK_RAW_WRITEINC_U32_BE(p, 0); + } + return p; +} + +DUK_LOCAL duk_uint8_t *duk__dump_uint32_prop(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func, duk_small_uint_t stridx, duk_uint32_t def_value) { + duk_tval *tv; + duk_uint32_t val; + + tv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx); + if (tv != NULL && DUK_TVAL_IS_NUMBER(tv)) { + val = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv); + } else { + val = def_value; + } + p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p); + DUK_RAW_WRITEINC_U32_BE(p, val); + return p; +} + +DUK_LOCAL duk_uint8_t *duk__dump_varmap(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func) { + duk_hobject *h; + + h = duk_hobject_get_varmap(thr, (duk_hobject *) func); + if (h != NULL) { + duk_uint_fast32_t i; + + /* We know _Varmap only has own properties so walk property + * table directly. We also know _Varmap is dense and all + * values are numbers; assert for these. GC and finalizers + * shouldn't affect _Varmap so side effects should be fine. + */ + for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) { + duk_hstring *key; + duk_tval *tv_val; + duk_uint32_t val; + + key = DUK_HOBJECT_E_GET_KEY(thr->heap, h, i); + DUK_ASSERT(key != NULL); /* _Varmap is dense */ + DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, h, i)); + tv_val = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, h, i); + DUK_ASSERT(tv_val != NULL); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_val)); /* known to be number; in fact an integer */ +#if defined(DUK_USE_FASTINT) + DUK_ASSERT(DUK_TVAL_IS_FASTINT(tv_val)); + DUK_ASSERT(DUK_TVAL_GET_FASTINT(tv_val) == (duk_int64_t) DUK_TVAL_GET_FASTINT_U32(tv_val)); /* known to be 32-bit */ + val = DUK_TVAL_GET_FASTINT_U32(tv_val); +#else + val = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv_val); +#endif + + DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL); /* ensures no overflow */ + p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(key) + 4U, p); + p = duk__dump_hstring_raw(p, key); + DUK_RAW_WRITEINC_U32_BE(p, val); + } + } + p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p); + DUK_RAW_WRITEINC_U32_BE(p, 0); /* end of _Varmap */ + return p; +} + +DUK_LOCAL duk_uint8_t *duk__dump_formals(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func) { + duk_harray *h; + + h = duk_hobject_get_formals(thr, (duk_hobject *) func); + if (h != NULL) { + duk_uint32_t i; + + /* Here we rely on _Formals being a dense array containing + * strings. This should be the case unless _Formals has been + * tweaked by the application (which we don't support right + * now). + */ + + p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p); + DUK_ASSERT(h->length != DUK__NO_FORMALS); /* limits */ + DUK_RAW_WRITEINC_U32_BE(p, h->length); + + for (i = 0; i < h->length; i++) { + duk_tval *tv_val; + duk_hstring *varname; + + tv_val = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, (duk_hobject *) h, i); + DUK_ASSERT(tv_val != NULL); + DUK_ASSERT(DUK_TVAL_IS_STRING(tv_val)); + + varname = DUK_TVAL_GET_STRING(tv_val); + DUK_ASSERT(varname != NULL); + DUK_ASSERT(DUK_HSTRING_GET_BYTELEN(varname) >= 1); + + DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL); /* ensures no overflow */ + p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(varname), p); + p = duk__dump_hstring_raw(p, varname); + } + } else { + DUK_DD(DUK_DDPRINT("dumping function without _Formals, emit marker to indicate missing _Formals")); + p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p); + DUK_RAW_WRITEINC_U32_BE(p, DUK__NO_FORMALS); /* marker: no formals */ + } + return p; +} + +static duk_uint8_t *duk__dump_func(duk_hthread *thr, duk_hcompfunc *func, duk_bufwriter_ctx *bw_ctx, duk_uint8_t *p) { + duk_tval *tv, *tv_end; + duk_instr_t *ins, *ins_end; + duk_hobject **fn, **fn_end; + duk_hstring *h_str; + duk_uint32_t count_instr; + duk_uint32_t tmp32; + duk_uint16_t tmp16; + duk_double_t d; + + DUK_DD(DUK_DDPRINT("dumping function %p to %p: " + "consts=[%p,%p[ (%ld bytes, %ld items), " + "funcs=[%p,%p[ (%ld bytes, %ld items), " + "code=[%p,%p[ (%ld bytes, %ld items)", + (void *) func, + (void *) p, + (void *) DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, func), + (void *) DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, func), + (long) DUK_HCOMPFUNC_GET_CONSTS_SIZE(thr->heap, func), + (long) DUK_HCOMPFUNC_GET_CONSTS_COUNT(thr->heap, func), + (void *) DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, func), + (void *) DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, func), + (long) DUK_HCOMPFUNC_GET_FUNCS_SIZE(thr->heap, func), + (long) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, func), + (void *) DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, func), + (void *) DUK_HCOMPFUNC_GET_CODE_END(thr->heap, func), + (long) DUK_HCOMPFUNC_GET_CODE_SIZE(thr->heap, func), + (long) DUK_HCOMPFUNC_GET_CODE_COUNT(thr->heap, func))); + + DUK_ASSERT(DUK_USE_ESBC_MAX_BYTES <= 0x7fffffffUL); /* ensures no overflow */ + count_instr = (duk_uint32_t) DUK_HCOMPFUNC_GET_CODE_COUNT(thr->heap, func); + p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 3U * 4U + 2U * 2U + 3U * 4U + count_instr * 4U, p); + + /* Fixed header info. */ + tmp32 = count_instr; + DUK_RAW_WRITEINC_U32_BE(p, tmp32); + tmp32 = (duk_uint32_t) DUK_HCOMPFUNC_GET_CONSTS_COUNT(thr->heap, func); + DUK_RAW_WRITEINC_U32_BE(p, tmp32); + tmp32 = (duk_uint32_t) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, func); + DUK_RAW_WRITEINC_U32_BE(p, tmp32); + tmp16 = func->nregs; + DUK_RAW_WRITEINC_U16_BE(p, tmp16); + tmp16 = func->nargs; + DUK_RAW_WRITEINC_U16_BE(p, tmp16); +#if defined(DUK_USE_DEBUGGER_SUPPORT) + tmp32 = func->start_line; + DUK_RAW_WRITEINC_U32_BE(p, tmp32); + tmp32 = func->end_line; + DUK_RAW_WRITEINC_U32_BE(p, tmp32); +#else + DUK_RAW_WRITEINC_U32_BE(p, 0); + DUK_RAW_WRITEINC_U32_BE(p, 0); +#endif + tmp32 = DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) func); /* masks flags, only duk_hobject flags */ + tmp32 &= ~(DUK_HOBJECT_FLAG_HAVE_FINALIZER); /* finalizer flag is lost */ + DUK_RAW_WRITEINC_U32_BE(p, tmp32); + + /* Bytecode instructions: endian conversion needed unless + * platform is big endian. + */ + ins = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, func); + ins_end = DUK_HCOMPFUNC_GET_CODE_END(thr->heap, func); + DUK_ASSERT((duk_size_t) (ins_end - ins) == (duk_size_t) count_instr); +#if defined(DUK_USE_INTEGER_BE) + duk_memcpy_unsafe((void *) p, (const void *) ins, (size_t) (ins_end - ins)); + p += (size_t) (ins_end - ins); +#else + while (ins != ins_end) { + tmp32 = (duk_uint32_t) (*ins); + DUK_RAW_WRITEINC_U32_BE(p, tmp32); + ins++; + } +#endif + + /* Constants: variable size encoding. */ + tv = DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, func); + tv_end = DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, func); + while (tv != tv_end) { + /* constants are strings or numbers now */ + DUK_ASSERT(DUK_TVAL_IS_STRING(tv) || + DUK_TVAL_IS_NUMBER(tv)); + + if (DUK_TVAL_IS_STRING(tv)) { + h_str = DUK_TVAL_GET_STRING(tv); + DUK_ASSERT(h_str != NULL); + DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL); /* ensures no overflow */ + p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 1U + 4U + DUK_HSTRING_GET_BYTELEN(h_str), p); + *p++ = DUK__SER_STRING; + p = duk__dump_hstring_raw(p, h_str); + } else { + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); + p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 1U + 8U, p); + *p++ = DUK__SER_NUMBER; + d = DUK_TVAL_GET_NUMBER(tv); + DUK_RAW_WRITEINC_DOUBLE_BE(p, d); + } + tv++; + } + + /* Inner functions recursively. */ + fn = (duk_hobject **) DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, func); + fn_end = (duk_hobject **) DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, func); + while (fn != fn_end) { + /* XXX: This causes recursion up to inner function depth + * which is normally not an issue, e.g. mark-and-sweep uses + * a recursion limiter to avoid C stack issues. Avoiding + * this would mean some sort of a work list or just refusing + * to serialize deep functions. + */ + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(*fn)); + p = duk__dump_func(thr, (duk_hcompfunc *) *fn, bw_ctx, p); + fn++; + } + + /* Lexenv and varenv are not dumped. */ + + /* Object extra properties. + * + * There are some difference between function templates and functions. + * For example, function templates don't have .length and nargs is + * normally used to instantiate the functions. + */ + + p = duk__dump_uint32_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_LENGTH, (duk_uint32_t) func->nargs); +#if defined(DUK_USE_FUNC_NAME_PROPERTY) + p = duk__dump_string_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_NAME); +#endif +#if defined(DUK_USE_FUNC_FILENAME_PROPERTY) + p = duk__dump_string_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_FILE_NAME); +#endif +#if defined(DUK_USE_PC2LINE) + p = duk__dump_buffer_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_INT_PC2LINE); +#endif + p = duk__dump_varmap(thr, p, bw_ctx, (duk_hobject *) func); + p = duk__dump_formals(thr, p, bw_ctx, (duk_hobject *) func); + + DUK_DD(DUK_DDPRINT("serialized function %p -> final pointer %p", (void *) func, (void *) p)); + + return p; +} + +/* Load a function from bytecode. The function object returned here must + * match what is created by duk_js_push_closure() with respect to its flags, + * properties, etc. + * + * NOTE: there are intentionally no input buffer length / bound checks. + * Adding them would be easy but wouldn't ensure memory safety as untrusted + * or broken bytecode is unsafe during execution unless the opcodes themselves + * are validated (which is quite complex, especially for indirect opcodes). + */ + +#define DUK__ASSERT_LEFT(n) do { \ + DUK_ASSERT((duk_size_t) (p_end - p) >= (duk_size_t) (n)); \ + } while (0) + +static const duk_uint8_t *duk__load_func(duk_hthread *thr, const duk_uint8_t *p, const duk_uint8_t *p_end) { + duk_hcompfunc *h_fun; + duk_hbuffer *h_data; + duk_size_t data_size; + duk_uint32_t count_instr, count_const, count_funcs; + duk_uint32_t n; + duk_uint32_t tmp32; + duk_small_uint_t const_type; + duk_uint8_t *fun_data; + duk_uint8_t *q; + duk_idx_t idx_base; + duk_tval *tv1; + duk_uarridx_t arr_idx; + duk_uarridx_t arr_limit; + duk_hobject *func_env; + duk_bool_t need_pop; + + /* XXX: There's some overlap with duk_js_closure() here, but + * seems difficult to share code. Ensure that the final function + * looks the same as created by duk_js_closure(). + */ + + DUK_ASSERT(thr != NULL); + + DUK_DD(DUK_DDPRINT("loading function, p=%p, p_end=%p", (void *) p, (void *) p_end)); + + DUK__ASSERT_LEFT(3 * 4); + count_instr = DUK_RAW_READINC_U32_BE(p); + count_const = DUK_RAW_READINC_U32_BE(p); + count_funcs = DUK_RAW_READINC_U32_BE(p); + + data_size = sizeof(duk_tval) * count_const + + sizeof(duk_hobject *) * count_funcs + + sizeof(duk_instr_t) * count_instr; + + DUK_DD(DUK_DDPRINT("instr=%ld, const=%ld, funcs=%ld, data_size=%ld", + (long) count_instr, (long) count_const, + (long) count_const, (long) data_size)); + + /* Value stack is used to ensure reachability of constants and + * inner functions being loaded. Require enough space to handle + * large functions correctly. + */ + duk_require_stack(thr, (duk_idx_t) (2 + count_const + count_funcs)); + idx_base = duk_get_top(thr); + + /* Push function object, init flags etc. This must match + * duk_js_push_closure() quite carefully. + */ + h_fun = duk_push_hcompfunc(thr); + DUK_ASSERT(h_fun != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) h_fun)); + DUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, h_fun) == NULL); + DUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, h_fun) == NULL); + DUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, h_fun) == NULL); + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_fun) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]); + + h_fun->nregs = DUK_RAW_READINC_U16_BE(p); + h_fun->nargs = DUK_RAW_READINC_U16_BE(p); +#if defined(DUK_USE_DEBUGGER_SUPPORT) + h_fun->start_line = DUK_RAW_READINC_U32_BE(p); + h_fun->end_line = DUK_RAW_READINC_U32_BE(p); +#else + p += 8; /* skip line info */ +#endif + + /* duk_hcompfunc flags; quite version specific */ + tmp32 = DUK_RAW_READINC_U32_BE(p); + DUK_HEAPHDR_SET_FLAGS((duk_heaphdr *) h_fun, tmp32); /* masks flags to only change duk_hobject flags */ + + /* standard prototype (no need to set here, already set) */ + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_fun) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]); +#if 0 + DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, &h_fun->obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]); +#endif + + /* assert just a few critical flags */ + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h_fun) == DUK_HTYPE_OBJECT); + DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&h_fun->obj)); + DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(&h_fun->obj)); + DUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(&h_fun->obj)); + DUK_ASSERT(!DUK_HOBJECT_IS_THREAD(&h_fun->obj)); + DUK_ASSERT(!DUK_HOBJECT_IS_PROXY(&h_fun->obj)); + DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(&h_fun->obj)); + DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(&h_fun->obj)); + DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(&h_fun->obj)); + + /* Create function 'data' buffer but don't attach it yet. */ + fun_data = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, data_size); + DUK_ASSERT(fun_data != NULL); + + /* Load bytecode instructions. */ + DUK_ASSERT(sizeof(duk_instr_t) == 4); + DUK__ASSERT_LEFT(count_instr * sizeof(duk_instr_t)); +#if defined(DUK_USE_INTEGER_BE) + q = fun_data + sizeof(duk_tval) * count_const + sizeof(duk_hobject *) * count_funcs; + duk_memcpy((void *) q, + (const void *) p, + sizeof(duk_instr_t) * count_instr); + p += sizeof(duk_instr_t) * count_instr; +#else + q = fun_data + sizeof(duk_tval) * count_const + sizeof(duk_hobject *) * count_funcs; + for (n = count_instr; n > 0; n--) { + *((duk_instr_t *) (void *) q) = DUK_RAW_READINC_U32_BE(p); + q += sizeof(duk_instr_t); + } +#endif + + /* Load constants onto value stack but don't yet copy to buffer. */ + for (n = count_const; n > 0; n--) { + DUK__ASSERT_LEFT(1); + const_type = DUK_RAW_READINC_U8(p); + switch (const_type) { + case DUK__SER_STRING: { + p = duk__load_string_raw(thr, p); + break; + } + case DUK__SER_NUMBER: { + /* Important to do a fastint check so that constants are + * properly read back as fastints. + */ + duk_tval tv_tmp; + duk_double_t val; + DUK__ASSERT_LEFT(8); + val = DUK_RAW_READINC_DOUBLE_BE(p); + DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(&tv_tmp, val); + duk_push_tval(thr, &tv_tmp); + break; + } + default: { + goto format_error; + } + } + } + + /* Load inner functions to value stack, but don't yet copy to buffer. */ + for (n = count_funcs; n > 0; n--) { + p = duk__load_func(thr, p, p_end); + if (p == NULL) { + goto format_error; + } + } + + /* With constants and inner functions on value stack, we can now + * atomically finish the function 'data' buffer, bump refcounts, + * etc. + * + * Here we take advantage of the value stack being just a duk_tval + * array: we can just memcpy() the constants as long as we incref + * them afterwards. + */ + + h_data = (duk_hbuffer *) duk_known_hbuffer(thr, idx_base + 1); + DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC(h_data)); + DUK_HCOMPFUNC_SET_DATA(thr->heap, h_fun, h_data); + DUK_HBUFFER_INCREF(thr, h_data); + + tv1 = duk_get_tval(thr, idx_base + 2); /* may be NULL if no constants or inner funcs */ + DUK_ASSERT((count_const == 0 && count_funcs == 0) || tv1 != NULL); + + q = fun_data; + duk_memcpy_unsafe((void *) q, (const void *) tv1, sizeof(duk_tval) * count_const); + for (n = count_const; n > 0; n--) { + DUK_TVAL_INCREF_FAST(thr, (duk_tval *) (void *) q); /* no side effects */ + q += sizeof(duk_tval); + } + tv1 += count_const; + + DUK_HCOMPFUNC_SET_FUNCS(thr->heap, h_fun, (duk_hobject **) (void *) q); + for (n = count_funcs; n > 0; n--) { + duk_hobject *h_obj; + + DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv1)); + h_obj = DUK_TVAL_GET_OBJECT(tv1); + DUK_ASSERT(h_obj != NULL); + tv1++; + DUK_HOBJECT_INCREF(thr, h_obj); + + *((duk_hobject **) (void *) q) = h_obj; + q += sizeof(duk_hobject *); + } + + DUK_HCOMPFUNC_SET_BYTECODE(thr->heap, h_fun, (duk_instr_t *) (void *) q); + + /* The function object is now reachable and refcounts are fine, + * so we can pop off all the temporaries. + */ + DUK_DDD(DUK_DDDPRINT("function is reachable, reset top; func: %!iT", duk_get_tval(thr, idx_base))); + duk_set_top(thr, idx_base + 1); + + /* Setup function properties. */ + tmp32 = DUK_RAW_READINC_U32_BE(p); + duk_push_u32(thr, tmp32); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C); + +#if defined(DUK_USE_FUNC_NAME_PROPERTY) + p = duk__load_string_raw(thr, p); /* -> [ func funcname ] */ + func_env = thr->builtins[DUK_BIDX_GLOBAL_ENV]; + DUK_ASSERT(func_env != NULL); + need_pop = 0; + if (DUK_HOBJECT_HAS_NAMEBINDING((duk_hobject *) h_fun)) { + /* Original function instance/template had NAMEBINDING. + * Must create a lexical environment on loading to allow + * recursive functions like 'function foo() { foo(); }'. + */ + duk_hdecenv *new_env; + + new_env = duk_hdecenv_alloc(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV)); + DUK_ASSERT(new_env != NULL); + DUK_ASSERT(new_env->thread == NULL); /* Closed. */ + DUK_ASSERT(new_env->varmap == NULL); + DUK_ASSERT(new_env->regbase_byteoff == 0); + DUK_HDECENV_ASSERT_VALID(new_env); + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL); + DUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, func_env); + DUK_HOBJECT_INCREF(thr, func_env); + + func_env = (duk_hobject *) new_env; + + duk_push_hobject(thr, (duk_hobject *) new_env); + + duk_dup_m2(thr); /* -> [ func funcname env funcname ] */ + duk_dup(thr, idx_base); /* -> [ func funcname env funcname func ] */ + duk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_NONE); /* -> [ func funcname env ] */ + + need_pop = 1; /* Need to pop env, but -after- updating h_fun and increfs. */ + } + DUK_ASSERT(func_env != NULL); + DUK_HCOMPFUNC_SET_LEXENV(thr->heap, h_fun, func_env); + DUK_HCOMPFUNC_SET_VARENV(thr->heap, h_fun, func_env); + DUK_HOBJECT_INCREF(thr, func_env); + DUK_HOBJECT_INCREF(thr, func_env); + if (need_pop) { + duk_pop(thr); + } + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C); +#endif /* DUK_USE_FUNC_NAME_PROPERTY */ + +#if defined(DUK_USE_FUNC_FILENAME_PROPERTY) + p = duk__load_string_raw(thr, p); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C); +#endif /* DUK_USE_FUNC_FILENAME_PROPERTY */ + + if (DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) h_fun)) { + /* Restore empty external .prototype only for constructable + * functions. The prototype object should inherit from + * Object.prototype. + */ + duk_push_object(thr); + DUK_ASSERT(!duk_is_bare_object(thr, -1)); + duk_dup_m2(thr); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC); /* func.prototype.constructor = func */ + duk_compact_m1(thr); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_W); + } + +#if defined(DUK_USE_PC2LINE) + p = duk__load_buffer_raw(thr, p); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_PC2LINE, DUK_PROPDESC_FLAGS_WC); +#endif /* DUK_USE_PC2LINE */ + + duk_push_bare_object(thr); /* _Varmap */ + for (;;) { + /* XXX: awkward */ + p = duk__load_string_raw(thr, p); + if (duk_get_length(thr, -1) == 0) { + duk_pop(thr); + break; + } + tmp32 = DUK_RAW_READINC_U32_BE(p); + duk_push_u32(thr, tmp32); + duk_put_prop(thr, -3); + } + duk_compact_m1(thr); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VARMAP, DUK_PROPDESC_FLAGS_NONE); + + /* _Formals may have been missing in the original function, which is + * handled using a marker length. + */ + arr_limit = DUK_RAW_READINC_U32_BE(p); + if (arr_limit != DUK__NO_FORMALS) { + duk_push_bare_array(thr); /* _Formals */ + for (arr_idx = 0; arr_idx < arr_limit; arr_idx++) { + p = duk__load_string_raw(thr, p); + duk_put_prop_index(thr, -2, arr_idx); + } + duk_compact_m1(thr); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_FORMALS, DUK_PROPDESC_FLAGS_NONE); + } else { + DUK_DD(DUK_DDPRINT("no _Formals in dumped function")); + } + + /* Return with final function pushed on stack top. */ + DUK_DD(DUK_DDPRINT("final loaded function: %!iT", duk_get_tval(thr, -1))); + DUK_ASSERT_TOP(thr, idx_base + 1); + return p; + + format_error: + return NULL; +} + +DUK_EXTERNAL void duk_dump_function(duk_hthread *thr) { + duk_hcompfunc *func; + duk_bufwriter_ctx bw_ctx_alloc; + duk_bufwriter_ctx *bw_ctx = &bw_ctx_alloc; + duk_uint8_t *p; + + DUK_ASSERT_API_ENTRY(thr); + + /* Bound functions don't have all properties so we'd either need to + * lookup the non-bound target function or reject bound functions. + * For now, bound functions are rejected with TypeError. + */ + func = duk_require_hcompfunc(thr, -1); + DUK_ASSERT(func != NULL); + DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&func->obj)); + + /* Estimating the result size beforehand would be costly, so + * start with a reasonable size and extend as needed. + */ + DUK_BW_INIT_PUSHBUF(thr, bw_ctx, DUK__BYTECODE_INITIAL_ALLOC); + p = DUK_BW_GET_PTR(thr, bw_ctx); + *p++ = DUK__SER_MARKER; + p = duk__dump_func(thr, func, bw_ctx, p); + DUK_BW_SET_PTR(thr, bw_ctx, p); + DUK_BW_COMPACT(thr, bw_ctx); + + DUK_DD(DUK_DDPRINT("serialized result: %!T", duk_get_tval(thr, -1))); + + duk_remove_m2(thr); /* [ ... func buf ] -> [ ... buf ] */ +} + +DUK_EXTERNAL void duk_load_function(duk_hthread *thr) { + const duk_uint8_t *p_buf, *p, *p_end; + duk_size_t sz; + + DUK_ASSERT_API_ENTRY(thr); + + p_buf = (duk_uint8_t *) duk_require_buffer(thr, -1, &sz); + DUK_ASSERT(p_buf != NULL); + + /* The caller is responsible for being sure that bytecode being loaded + * is valid and trusted. Invalid bytecode can cause memory unsafe + * behavior directly during loading or later during bytecode execution + * (instruction validation would be quite complex to implement). + * + * This signature check is the only sanity check for detecting + * accidental invalid inputs. The initial byte ensures no ordinary + * string or Symbol will be accepted by accident. + */ + p = p_buf; + p_end = p_buf + sz; + if (sz < 1 || p[0] != DUK__SER_MARKER) { + goto format_error; + } + p++; + + p = duk__load_func(thr, p, p_end); + if (p == NULL) { + goto format_error; + } + + duk_remove_m2(thr); /* [ ... buf func ] -> [ ... func ] */ + return; + + format_error: + DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BYTECODE); + DUK_WO_NORETURN(return;); +} + +#else /* DUK_USE_BYTECODE_DUMP_SUPPORT */ + +DUK_EXTERNAL void duk_dump_function(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return;); +} + +DUK_EXTERNAL void duk_load_function(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return;); +} + +#endif /* DUK_USE_BYTECODE_DUMP_SUPPORT */ diff --git a/third_party/duktape/duk_api_call.c b/third_party/duktape/duk_api_call.c new file mode 100644 index 00000000..2448f0b4 --- /dev/null +++ b/third_party/duktape/duk_api_call.c @@ -0,0 +1,516 @@ +/* + * Calls. + * + * Protected variants should avoid ever throwing an error. Must be careful + * to catch errors related to value stack manipulation and property lookup, + * not just the call itself. + * + * The only exception is when arguments are insane, e.g. nargs/nrets are out + * of bounds; in such cases an error is thrown for two reasons. First, we + * can't always respect the value stack input/output guarantees in such cases + * so the caller would end up with the value stack in an unexpected state. + * Second, an attempt to create an error might itself fail (although this + * could be avoided by pushing a preallocated object/string or a primitive + * value). + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Helpers + */ + +struct duk__pcall_prop_args { + duk_idx_t obj_idx; + duk_idx_t nargs; + duk_small_uint_t call_flags; +}; +typedef struct duk__pcall_prop_args duk__pcall_prop_args; + +struct duk__pcall_method_args { + duk_idx_t nargs; + duk_small_uint_t call_flags; +}; +typedef struct duk__pcall_method_args duk__pcall_method_args; + +struct duk__pcall_args { + duk_idx_t nargs; + duk_small_uint_t call_flags; +}; +typedef struct duk__pcall_args duk__pcall_args; + +/* Compute and validate idx_func for a certain 'nargs' and 'other' + * parameter count (1 or 2, depending on whether 'this' binding is + * present). + */ +DUK_LOCAL duk_idx_t duk__call_get_idx_func(duk_hthread *thr, duk_idx_t nargs, duk_idx_t other) { + duk_idx_t idx_func; + + /* XXX: byte arithmetic? */ + + DUK_ASSERT(other >= 0); + + idx_func = duk_get_top(thr) - nargs - other; + if (DUK_UNLIKELY((idx_func | nargs) < 0)) { /* idx_func < 0 || nargs < 0; OR sign bits */ + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return 0;); + } + DUK_ASSERT(duk_is_valid_index(thr, idx_func)); + return idx_func; +} + +/* Compute idx_func, assume index will be valid. This is a valid assumption + * for protected calls: nargs < 0 is checked explicitly and duk_safe_call() + * validates the argument count. + */ +DUK_LOCAL duk_idx_t duk__call_get_idx_func_unvalidated(duk_hthread *thr, duk_idx_t nargs, duk_idx_t other) { + duk_idx_t idx_func; + + /* XXX: byte arithmetic? */ + + DUK_ASSERT(nargs >= 0); + DUK_ASSERT(other >= 0); + + idx_func = duk_get_top(thr) - nargs - other; + DUK_ASSERT(idx_func >= 0); + DUK_ASSERT(duk_is_valid_index(thr, idx_func)); + return idx_func; +} + +/* Prepare value stack for a method call through an object property. + * May currently throw an error e.g. when getting the property. + */ +DUK_LOCAL void duk__call_prop_prep_stack(duk_hthread *thr, duk_idx_t normalized_obj_idx, duk_idx_t nargs) { + DUK_CTX_ASSERT_VALID(thr); + DUK_ASSERT(nargs >= 0); + + DUK_DDD(DUK_DDDPRINT("duk__call_prop_prep_stack, normalized_obj_idx=%ld, nargs=%ld, stacktop=%ld", + (long) normalized_obj_idx, (long) nargs, (long) duk_get_top(thr))); + + /* [... key arg1 ... argN] */ + + /* duplicate key */ + duk_dup(thr, -nargs - 1); /* Note: -nargs alone would fail for nargs == 0, this is OK */ + (void) duk_get_prop(thr, normalized_obj_idx); + + DUK_DDD(DUK_DDDPRINT("func: %!T", (duk_tval *) duk_get_tval(thr, -1))); + +#if defined(DUK_USE_VERBOSE_ERRORS) + if (DUK_UNLIKELY(!duk_is_callable(thr, -1))) { + duk_tval *tv_base; + duk_tval *tv_key; + + /* tv_targ is passed on stack top (at index -1). */ + tv_base = DUK_GET_TVAL_POSIDX(thr, normalized_obj_idx); + tv_key = DUK_GET_TVAL_NEGIDX(thr, -nargs - 2); + DUK_ASSERT(tv_base >= thr->valstack_bottom && tv_base < thr->valstack_top); + DUK_ASSERT(tv_key >= thr->valstack_bottom && tv_key < thr->valstack_top); + + duk_call_setup_propcall_error(thr, tv_base, tv_key); + } +#endif + + /* [... key arg1 ... argN func] */ + + duk_replace(thr, -nargs - 2); + + /* [... func arg1 ... argN] */ + + duk_dup(thr, normalized_obj_idx); + duk_insert(thr, -nargs - 1); + + /* [... func this arg1 ... argN] */ +} + +DUK_EXTERNAL void duk_call(duk_hthread *thr, duk_idx_t nargs) { + duk_small_uint_t call_flags; + duk_idx_t idx_func; + + DUK_ASSERT_API_ENTRY(thr); + + idx_func = duk__call_get_idx_func(thr, nargs, 1); + DUK_ASSERT(duk_is_valid_index(thr, idx_func)); + + duk_insert_undefined(thr, idx_func + 1); + + call_flags = 0; /* not protected, respect reclimit, not constructor */ + duk_handle_call_unprotected(thr, idx_func, call_flags); +} + +DUK_EXTERNAL void duk_call_method(duk_hthread *thr, duk_idx_t nargs) { + duk_small_uint_t call_flags; + duk_idx_t idx_func; + + DUK_ASSERT_API_ENTRY(thr); + + idx_func = duk__call_get_idx_func(thr, nargs, 2); + DUK_ASSERT(duk_is_valid_index(thr, idx_func)); + + call_flags = 0; /* not protected, respect reclimit, not constructor */ + duk_handle_call_unprotected(thr, idx_func, call_flags); +} + +DUK_EXTERNAL void duk_call_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t nargs) { + /* + * XXX: if duk_handle_call() took values through indices, this could be + * made much more sensible. However, duk_handle_call() needs to fudge + * the 'this' and 'func' values to handle bound functions, which is now + * done "in-place", so this is not a trivial change. + */ + + DUK_ASSERT_API_ENTRY(thr); + + obj_idx = duk_require_normalize_index(thr, obj_idx); /* make absolute */ + if (DUK_UNLIKELY(nargs < 0)) { + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return;); + } + + duk__call_prop_prep_stack(thr, obj_idx, nargs); + + duk_call_method(thr, nargs); +} + +DUK_LOCAL duk_ret_t duk__pcall_raw(duk_hthread *thr, void *udata) { + duk__pcall_args *args; + duk_idx_t idx_func; + duk_int_t ret; + + DUK_CTX_ASSERT_VALID(thr); + DUK_ASSERT(udata != NULL); + + args = (duk__pcall_args *) udata; + idx_func = duk__call_get_idx_func_unvalidated(thr, args->nargs, 1); + DUK_ASSERT(duk_is_valid_index(thr, idx_func)); + + duk_insert_undefined(thr, idx_func + 1); + + ret = duk_handle_call_unprotected(thr, idx_func, args->call_flags); + DUK_ASSERT(ret == 0); + DUK_UNREF(ret); + + return 1; +} + +DUK_EXTERNAL duk_int_t duk_pcall(duk_hthread *thr, duk_idx_t nargs) { + duk__pcall_args args; + + DUK_ASSERT_API_ENTRY(thr); + + args.nargs = nargs; + if (DUK_UNLIKELY(nargs < 0)) { + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return DUK_EXEC_ERROR;); + } + args.call_flags = 0; + + return duk_safe_call(thr, duk__pcall_raw, (void *) &args /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/); +} + +DUK_LOCAL duk_ret_t duk__pcall_method_raw(duk_hthread *thr, void *udata) { + duk__pcall_method_args *args; + duk_idx_t idx_func; + duk_int_t ret; + + DUK_CTX_ASSERT_VALID(thr); + DUK_ASSERT(udata != NULL); + + args = (duk__pcall_method_args *) udata; + + idx_func = duk__call_get_idx_func_unvalidated(thr, args->nargs, 2); + DUK_ASSERT(duk_is_valid_index(thr, idx_func)); + + ret = duk_handle_call_unprotected(thr, idx_func, args->call_flags); + DUK_ASSERT(ret == 0); + DUK_UNREF(ret); + + return 1; +} + +DUK_INTERNAL duk_int_t duk_pcall_method_flags(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags) { + duk__pcall_method_args args; + + DUK_ASSERT_API_ENTRY(thr); + + args.nargs = nargs; + if (DUK_UNLIKELY(nargs < 0)) { + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return DUK_EXEC_ERROR;); + } + args.call_flags = call_flags; + + return duk_safe_call(thr, duk__pcall_method_raw, (void *) &args /*udata*/, nargs + 2 /*nargs*/, 1 /*nrets*/); +} + +DUK_EXTERNAL duk_int_t duk_pcall_method(duk_hthread *thr, duk_idx_t nargs) { + DUK_ASSERT_API_ENTRY(thr); + + return duk_pcall_method_flags(thr, nargs, 0); +} + +DUK_LOCAL duk_ret_t duk__pcall_prop_raw(duk_hthread *thr, void *udata) { + duk__pcall_prop_args *args; + duk_idx_t obj_idx; + duk_int_t ret; + + DUK_CTX_ASSERT_VALID(thr); + DUK_ASSERT(udata != NULL); + + args = (duk__pcall_prop_args *) udata; + + obj_idx = duk_require_normalize_index(thr, args->obj_idx); /* make absolute */ + duk__call_prop_prep_stack(thr, obj_idx, args->nargs); + + ret = duk_handle_call_unprotected_nargs(thr, args->nargs, args->call_flags); + DUK_ASSERT(ret == 0); + DUK_UNREF(ret); + return 1; +} + +DUK_EXTERNAL duk_int_t duk_pcall_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t nargs) { + duk__pcall_prop_args args; + + DUK_ASSERT_API_ENTRY(thr); + + args.obj_idx = obj_idx; + args.nargs = nargs; + if (DUK_UNLIKELY(nargs < 0)) { + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return DUK_EXEC_ERROR;); + } + args.call_flags = 0; + + return duk_safe_call(thr, duk__pcall_prop_raw, (void *) &args /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/); +} + +DUK_EXTERNAL duk_int_t duk_safe_call(duk_hthread *thr, duk_safe_call_function func, void *udata, duk_idx_t nargs, duk_idx_t nrets) { + duk_int_t rc; + + DUK_ASSERT_API_ENTRY(thr); + + /* nargs condition; fail if: top - bottom < nargs + * <=> top < bottom + nargs + * nrets condition; fail if: end - (top - nargs) < nrets + * <=> end - top + nargs < nrets + * <=> end + nargs < top + nrets + */ + /* XXX: check for any reserve? */ + + if (DUK_UNLIKELY((nargs | nrets) < 0 || /* nargs < 0 || nrets < 0; OR sign bits */ + thr->valstack_top < thr->valstack_bottom + nargs || /* nargs too large compared to top */ + thr->valstack_end + nargs < thr->valstack_top + nrets)) { /* nrets too large compared to reserve */ + DUK_D(DUK_DPRINT("not enough stack reserve for safe call or invalid arguments: " + "nargs=%ld < 0 (?), nrets=%ld < 0 (?), top=%ld < bottom=%ld + nargs=%ld (?), " + "end=%ld + nargs=%ld < top=%ld + nrets=%ld (?)", + (long) nargs, + (long) nrets, + (long) (thr->valstack_top - thr->valstack), + (long) (thr->valstack_bottom - thr->valstack), + (long) nargs, + (long) (thr->valstack_end - thr->valstack), + (long) nargs, + (long) (thr->valstack_top - thr->valstack), + (long) nrets)); + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return DUK_EXEC_ERROR;); + } + + rc = duk_handle_safe_call(thr, /* thread */ + func, /* func */ + udata, /* udata */ + nargs, /* num_stack_args */ + nrets); /* num_stack_res */ + + return rc; +} + +DUK_EXTERNAL void duk_new(duk_hthread *thr, duk_idx_t nargs) { + duk_idx_t idx_func; + + DUK_ASSERT_API_ENTRY(thr); + + idx_func = duk__call_get_idx_func(thr, nargs, 1); + DUK_ASSERT(duk_is_valid_index(thr, idx_func)); + + duk_push_object(thr); /* default instance; internal proto updated by call handling */ + duk_insert(thr, idx_func + 1); + + duk_handle_call_unprotected(thr, idx_func, DUK_CALL_FLAG_CONSTRUCT); +} + +DUK_LOCAL duk_ret_t duk__pnew_helper(duk_hthread *thr, void *udata) { + duk_idx_t nargs; + + DUK_ASSERT(udata != NULL); + nargs = *((duk_idx_t *) udata); + + duk_new(thr, nargs); + return 1; +} + +DUK_EXTERNAL duk_int_t duk_pnew(duk_hthread *thr, duk_idx_t nargs) { + duk_int_t rc; + + DUK_ASSERT_API_ENTRY(thr); + + /* For now, just use duk_safe_call() to wrap duk_new(). We can't + * simply use a protected duk_handle_call() because pushing the + * default instance might throw. + */ + + if (DUK_UNLIKELY(nargs < 0)) { + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return DUK_EXEC_ERROR;); + } + + rc = duk_safe_call(thr, duk__pnew_helper, (void *) &nargs /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/); + return rc; +} + +DUK_EXTERNAL duk_bool_t duk_is_constructor_call(duk_hthread *thr) { + duk_activation *act; + + DUK_ASSERT_API_ENTRY(thr); + + act = thr->callstack_curr; + if (act != NULL) { + return ((act->flags & DUK_ACT_FLAG_CONSTRUCT) != 0 ? 1 : 0); + } + return 0; +} + +DUK_EXTERNAL void duk_require_constructor_call(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + + if (!duk_is_constructor_call(thr)) { + DUK_ERROR_TYPE(thr, DUK_STR_CONSTRUCT_ONLY); + DUK_WO_NORETURN(return;); + } +} + +DUK_EXTERNAL duk_bool_t duk_is_strict_call(duk_hthread *thr) { + duk_activation *act; + + /* For user code this could just return 1 (strict) always + * because all Duktape/C functions are considered strict, + * and strict is also the default when nothing is running. + * However, Duktape may call this function internally when + * the current activation is an ECMAScript function, so + * this cannot be replaced by a 'return 1' without fixing + * the internal call sites. + */ + + DUK_ASSERT_API_ENTRY(thr); + + act = thr->callstack_curr; + if (act != NULL) { + return ((act->flags & DUK_ACT_FLAG_STRICT) != 0 ? 1 : 0); + } else { + /* Strict by default. */ + return 1; + } +} + +/* + * Duktape/C function magic + */ + +DUK_EXTERNAL duk_int_t duk_get_current_magic(duk_hthread *thr) { + duk_activation *act; + duk_hobject *func; + + DUK_ASSERT_API_ENTRY(thr); + + act = thr->callstack_curr; + if (act) { + func = DUK_ACT_GET_FUNC(act); + if (!func) { + duk_tval *tv = &act->tv_func; + duk_small_uint_t lf_flags; + lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv); + return (duk_int_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags); + } + DUK_ASSERT(func != NULL); + + if (DUK_HOBJECT_IS_NATFUNC(func)) { + duk_hnatfunc *nf = (duk_hnatfunc *) func; + return (duk_int_t) nf->magic; + } + } + return 0; +} + +DUK_EXTERNAL duk_int_t duk_get_magic(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + duk_hobject *h; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_require_tval(thr, idx); + if (DUK_TVAL_IS_OBJECT(tv)) { + h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + if (!DUK_HOBJECT_HAS_NATFUNC(h)) { + goto type_error; + } + return (duk_int_t) ((duk_hnatfunc *) h)->magic; + } else if (DUK_TVAL_IS_LIGHTFUNC(tv)) { + duk_small_uint_t lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv); + return (duk_int_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags); + } + + /* fall through */ + type_error: + DUK_ERROR_TYPE(thr, DUK_STR_UNEXPECTED_TYPE); + DUK_WO_NORETURN(return 0;); +} + +DUK_EXTERNAL void duk_set_magic(duk_hthread *thr, duk_idx_t idx, duk_int_t magic) { + duk_hnatfunc *nf; + + DUK_ASSERT_API_ENTRY(thr); + + nf = duk_require_hnatfunc(thr, idx); + DUK_ASSERT(nf != NULL); + nf->magic = (duk_int16_t) magic; +} + +/* + * Misc helpers + */ + +/* Resolve a bound function on value stack top to a non-bound target + * (leave other values as is). + */ +DUK_INTERNAL void duk_resolve_nonbound_function(duk_hthread *thr) { + duk_tval *tv; + + DUK_HTHREAD_ASSERT_VALID(thr); + + tv = DUK_GET_TVAL_NEGIDX(thr, -1); + if (DUK_TVAL_IS_OBJECT(tv)) { + duk_hobject *h; + + h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + if (DUK_HOBJECT_HAS_BOUNDFUNC(h)) { + duk_push_tval(thr, &((duk_hboundfunc *) (void *) h)->target); + duk_replace(thr, -2); +#if 0 + DUK_TVAL_SET_TVAL(tv, &((duk_hboundfunc *) h)->target); + DUK_TVAL_INCREF(thr, tv); + DUK_HOBJECT_DECREF_NORZ(thr, h); +#endif + /* Rely on Function.prototype.bind() on never creating a bound + * function whose target is not proper. This is now safe + * because the target is not even an internal property but a + * struct member. + */ + DUK_ASSERT(duk_is_lightfunc(thr, -1) || duk_is_callable(thr, -1)); + } + } + + /* Lightfuncs cannot be bound but are always callable and + * constructable. + */ +} diff --git a/third_party/duktape/duk_api_codec.c b/third_party/duktape/duk_api_codec.c new file mode 100644 index 00000000..c601c1be --- /dev/null +++ b/third_party/duktape/duk_api_codec.c @@ -0,0 +1,926 @@ +/* + * Encoding and decoding basic formats: hex, base64. + * + * These are in-place operations which may allow an optimized implementation. + * + * Base-64: https://tools.ietf.org/html/rfc4648#section-4 + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Misc helpers + */ + +/* Shared handling for encode/decode argument. Fast path handling for + * buffer and string values because they're the most common. In particular, + * avoid creating a temporary string or buffer when possible. Return value + * is guaranteed to be non-NULL, even for zero length input. + */ +DUK_LOCAL const duk_uint8_t *duk__prep_codec_arg(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) { + const void *def_ptr = (const void *) out_len; /* Any non-NULL pointer will do. */ + const void *ptr; + duk_bool_t isbuffer; + + DUK_ASSERT(out_len != NULL); + DUK_ASSERT(def_ptr != NULL); + DUK_ASSERT(duk_is_valid_index(thr, idx)); /* checked by caller */ + + ptr = (const void *) duk_get_buffer_data_raw(thr, idx, out_len, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/, &isbuffer); + if (isbuffer) { + DUK_ASSERT(ptr != NULL || *out_len == 0U); + if (DUK_UNLIKELY(ptr == NULL)) { + ptr = def_ptr; + } + DUK_ASSERT(ptr != NULL); + } else { + /* For strings a non-NULL pointer is always guaranteed because + * at least a NUL will be present. + */ + ptr = (const void *) duk_to_lstring(thr, idx, out_len); + DUK_ASSERT(ptr != NULL); + } + DUK_ASSERT(ptr != NULL); + return (const duk_uint8_t *) ptr; +} + +/* + * Base64 + */ + +#if defined(DUK_USE_BASE64_SUPPORT) +/* Bytes emitted for number of padding characters in range [0,4]. */ +DUK_LOCAL const duk_int8_t duk__base64_decode_nequal_step[5] = { + 3, /* #### -> 24 bits, emit 3 bytes */ + 2, /* ###= -> 18 bits, emit 2 bytes */ + 1, /* ##== -> 12 bits, emit 1 byte */ + -1, /* #=== -> 6 bits, error */ + 0, /* ==== -> 0 bits, emit 0 bytes */ +}; + +#if defined(DUK_USE_BASE64_FASTPATH) +DUK_LOCAL const duk_uint8_t duk__base64_enctab_fast[64] = { + 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, 0x50U, /* A...P */ + 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, 0x58U, 0x59U, 0x5aU, 0x61U, 0x62U, 0x63U, 0x64U, 0x65U, 0x66U, /* Q...f */ + 0x67U, 0x68U, 0x69U, 0x6aU, 0x6bU, 0x6cU, 0x6dU, 0x6eU, 0x6fU, 0x70U, 0x71U, 0x72U, 0x73U, 0x74U, 0x75U, 0x76U, /* g...v */ + 0x77U, 0x78U, 0x79U, 0x7aU, 0x30U, 0x31U, 0x32U, 0x33U, 0x34U, 0x35U, 0x36U, 0x37U, 0x38U, 0x39U, 0x2bU, 0x2fU /* w.../ */ +}; +#endif /* DUK_USE_BASE64_FASTPATH */ + +#if defined(DUK_USE_BASE64_FASTPATH) +/* Decode table for one byte of input: + * -1 = allowed whitespace + * -2 = padding + * -3 = error + * 0...63 decoded bytes + */ +DUK_LOCAL const duk_int8_t duk__base64_dectab_fast[256] = { + -3, -3, -3, -3, -3, -3, -3, -3, -3, -1, -1, -3, -3, -1, -3, -3, /* 0x00...0x0f */ + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, /* 0x10...0x1f */ + -1, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, 62, -3, -3, -3, 63, /* 0x20...0x2f */ + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -3, -3, -3, -2, -3, -3, /* 0x30...0x3f */ + -3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40...0x4f */ + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -3, -3, -3, -3, -3, /* 0x50...0x5f */ + -3, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60...0x6f */ + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -3, -3, -3, -3, -3, /* 0x70...0x7f */ + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, /* 0x80...0x8f */ + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, /* 0x90...0x9f */ + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, /* 0xa0...0xaf */ + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, /* 0xb0...0xbf */ + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, /* 0xc0...0xcf */ + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, /* 0xd0...0xdf */ + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, /* 0xe0...0xef */ + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3 /* 0xf0...0xff */ +}; +#endif /* DUK_USE_BASE64_FASTPATH */ + +#if defined(DUK_USE_BASE64_FASTPATH) +DUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_3(const duk_uint8_t *src, duk_uint8_t *dst) { + duk_uint_t t; + + t = (duk_uint_t) src[0]; + t = (t << 8) + (duk_uint_t) src[1]; + t = (t << 8) + (duk_uint_t) src[2]; + + dst[0] = duk__base64_enctab_fast[t >> 18]; + dst[1] = duk__base64_enctab_fast[(t >> 12) & 0x3fU]; + dst[2] = duk__base64_enctab_fast[(t >> 6) & 0x3fU]; + dst[3] = duk__base64_enctab_fast[t & 0x3fU]; + +#if 0 + /* Tested: not faster on x64, most likely due to aliasing between + * output and input index computation. + */ + /* aaaaaabb bbbbcccc ccdddddd */ + dst[0] = duk__base64_enctab_fast[(src[0] >> 2) & 0x3fU]; + dst[1] = duk__base64_enctab_fast[((src[0] << 4) & 0x30U) | ((src[1] >> 4) & 0x0fU)]; + dst[2] = duk__base64_enctab_fast[((src[1] << 2) & 0x3fU) | ((src[2] >> 6) & 0x03U)]; + dst[3] = duk__base64_enctab_fast[src[2] & 0x3fU]; +#endif +} + +DUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_2(const duk_uint8_t *src, duk_uint8_t *dst) { + duk_uint_t t; + + t = (duk_uint_t) src[0]; + t = (t << 8) + (duk_uint_t) src[1]; + dst[0] = duk__base64_enctab_fast[t >> 10]; /* XXXXXX-- -------- */ + dst[1] = duk__base64_enctab_fast[(t >> 4) & 0x3fU]; /* ------XX XXXX---- */ + dst[2] = duk__base64_enctab_fast[(t << 2) & 0x3fU]; /* -------- ----XXXX */ + dst[3] = DUK_ASC_EQUALS; +} + +DUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_1(const duk_uint8_t *src, duk_uint8_t *dst) { + duk_uint_t t; + + t = (duk_uint_t) src[0]; + dst[0] = duk__base64_enctab_fast[t >> 2]; /* XXXXXX-- */ + dst[1] = duk__base64_enctab_fast[(t << 4) & 0x3fU]; /* ------XX */ + dst[2] = DUK_ASC_EQUALS; + dst[3] = DUK_ASC_EQUALS; +} + +DUK_LOCAL void duk__base64_encode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst) { + duk_size_t n; + const duk_uint8_t *p; + duk_uint8_t *q; + + n = srclen; + p = src; + q = dst; + + if (n >= 16U) { + /* Fast path, unrolled by 4, allows interleaving. Process + * 12-byte input chunks which encode to 16-char output chunks. + * Only enter when at least one block is emitted (avoids div+mul + * for short inputs too). + */ + const duk_uint8_t *p_end_fast; + + p_end_fast = p + ((n / 12U) * 12U); + DUK_ASSERT(p_end_fast >= p + 12); + do { + duk__base64_encode_fast_3(p, q); + duk__base64_encode_fast_3(p + 3, q + 4); + duk__base64_encode_fast_3(p + 6, q + 8); + duk__base64_encode_fast_3(p + 9, q + 12); + p += 12; + q += 16; + } while (DUK_LIKELY(p != p_end_fast)); + + DUK_ASSERT(src + srclen >= p); + n = (duk_size_t) (src + srclen - p); + DUK_ASSERT(n < 12U); + } + + /* Remainder. */ + while (n >= 3U) { + duk__base64_encode_fast_3(p, q); + p += 3; + q += 4; + n -= 3U; + } + DUK_ASSERT(n == 0U || n == 1U || n == 2U); + if (n == 1U) { + duk__base64_encode_fast_1(p, q); +#if 0 /* Unnecessary. */ + p += 1; + q += 4; + n -= 1U; +#endif + } else if (n == 2U) { + duk__base64_encode_fast_2(p, q); +#if 0 /* Unnecessary. */ + p += 2; + q += 4; + n -= 2U; +#endif + } else { + DUK_ASSERT(n == 0U); /* nothing to do */ + ; + } +} +#else /* DUK_USE_BASE64_FASTPATH */ +DUK_LOCAL void duk__base64_encode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst) { + duk_small_uint_t i, npad; + duk_uint_t t, x, y; + const duk_uint8_t *p; + const duk_uint8_t *p_end; + duk_uint8_t *q; + + p = src; + p_end = src + srclen; + q = dst; + npad = 0U; + + while (p < p_end) { + /* Read 3 bytes into 't', padded by zero. */ + t = 0; + for (i = 0; i < 3; i++) { + t = t << 8; + if (p < p_end) { + t += (duk_uint_t) (*p++); + } else { + /* This only happens on the last loop and we're + * guaranteed to exit on the next loop. + */ + npad++; + } + } + DUK_ASSERT(npad <= 2U); + + /* Emit 4 encoded characters. If npad > 0, some of the + * chars will be incorrect (zero bits) but we fix up the + * padding after the loop. A straightforward 64-byte + * lookup would be faster and cleaner, but this is shorter. + */ + for (i = 0; i < 4; i++) { + x = ((t >> 18) & 0x3fU); + t = t << 6; + + if (x <= 51U) { + if (x <= 25) { + y = x + DUK_ASC_UC_A; + } else { + y = x - 26 + DUK_ASC_LC_A; + } + } else { + if (x <= 61U) { + y = x - 52 + DUK_ASC_0; + } else if (x == 62) { + y = DUK_ASC_PLUS; + } else { + DUK_ASSERT(x == 63); + y = DUK_ASC_SLASH; + } + } + + *q++ = (duk_uint8_t) y; + } + } + + /* Handle padding by rewriting 0-2 bogus characters at the end. + * + * Missing bytes npad base64 example + * 0 0 #### + * 1 1 ###= + * 2 2 ##== + */ + DUK_ASSERT(npad <= 2U); + while (npad > 0U) { + *(q - npad) = DUK_ASC_EQUALS; + npad--; + } +} +#endif /* DUK_USE_BASE64_FASTPATH */ + +#if defined(DUK_USE_BASE64_FASTPATH) +DUK_LOCAL duk_bool_t duk__base64_decode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst, duk_uint8_t **out_dst_final) { + duk_int_t x; + duk_uint_t t; + duk_small_uint_t n_equal; + duk_int8_t step; + const duk_uint8_t *p; + const duk_uint8_t *p_end; + const duk_uint8_t *p_end_safe; + duk_uint8_t *q; + + DUK_ASSERT(src != NULL); /* Required by pointer arithmetic below, which fails for NULL. */ + + p = src; + p_end = src + srclen; + p_end_safe = p_end - 8; /* If 'src <= src_end_safe', safe to read 8 bytes. */ + q = dst; + + /* Alternate between a fast path which processes clean groups with no + * padding or whitespace, and a slow path which processes one arbitrary + * group and then re-enters the fast path. This handles e.g. base64 + * with newlines reasonably well because the majority of a line is in + * the fast path. + */ + for (;;) { + /* Fast path, on each loop handle two 4-char input groups. + * If both are clean, emit 6 bytes and continue. If first + * is clean, emit 3 bytes and drop out; otherwise emit + * nothing and drop out. This approach could be extended to + * more groups per loop, but for inputs with e.g. periodic + * newlines (which are common) it might not be an improvement. + */ + while (DUK_LIKELY(p <= p_end_safe)) { + duk_int_t t1, t2; + + /* The lookup byte is intentionally sign extended to + * (at least) 32 bits and then ORed. This ensures + * that is at least 1 byte is negative, the highest + * bit of the accumulator will be set at the end and + * we don't need to check every byte. + * + * Read all input bytes first before writing output + * bytes to minimize aliasing. + */ + DUK_DDD(DUK_DDDPRINT("fast loop: p=%p, p_end_safe=%p, p_end=%p", + (const void *) p, (const void *) p_end_safe, (const void *) p_end)); + + t1 = (duk_int_t) duk__base64_dectab_fast[p[0]]; + t1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[1]]; + t1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[2]]; + t1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[3]]; + + t2 = (duk_int_t) duk__base64_dectab_fast[p[4]]; + t2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[5]]; + t2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[6]]; + t2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[7]]; + + q[0] = (duk_uint8_t) (((duk_uint_t) t1 >> 16) & 0xffU); + q[1] = (duk_uint8_t) (((duk_uint_t) t1 >> 8) & 0xffU); + q[2] = (duk_uint8_t) ((duk_uint_t) t1 & 0xffU); + + q[3] = (duk_uint8_t) (((duk_uint_t) t2 >> 16) & 0xffU); + q[4] = (duk_uint8_t) (((duk_uint_t) t2 >> 8) & 0xffU); + q[5] = (duk_uint8_t) ((duk_uint_t) t2 & 0xffU); + + /* Optimistic check using one branch. */ + if (DUK_LIKELY((t1 | t2) >= 0)) { + p += 8; + q += 6; + } else if (t1 >= 0) { + DUK_DDD(DUK_DDDPRINT("fast loop first group was clean, second was not, process one slow path group")); + DUK_ASSERT(t2 < 0); + p += 4; + q += 3; + break; + } else { + DUK_DDD(DUK_DDDPRINT("fast loop first group was not clean, second does not matter, process one slow path group")); + DUK_ASSERT(t1 < 0); + break; + } + } /* fast path */ + + /* Slow path step 1: try to scan a 4-character encoded group, + * end-of-input, or start-of-padding. We exit with: + * 1. n_chars == 4: full group, no padding, no end-of-input. + * 2. n_chars < 4: partial group (may also be 0), encountered + * padding or end of input. + * + * The accumulator is initialized to 1; this allows us to detect + * a full group by comparing >= 0x1000000 without an extra + * counter variable. + */ + t = 1UL; + for (;;) { + DUK_DDD(DUK_DDDPRINT("slow loop: p=%p, p_end=%p, t=%lu", + (const void *) p, (const void *) p_end, (unsigned long) t)); + + if (DUK_LIKELY(p < p_end)) { + x = duk__base64_dectab_fast[*p++]; + if (DUK_LIKELY(x >= 0)) { + DUK_ASSERT(x >= 0 && x <= 63); + t = (t << 6) + (duk_uint_t) x; + if (t >= 0x1000000UL) { + break; + } + } else if (x == -1) { + continue; /* allowed ascii whitespace */ + } else if (x == -2) { + p--; + break; /* start of padding */ + } else { + DUK_ASSERT(x == -3); + goto decode_error; + } + } else { + break; /* end of input */ + } + } /* slow path step 1 */ + + /* Complete the padding by simulating pad characters, + * regardless of actual input padding chars. + */ + n_equal = 0; + while (t < 0x1000000UL) { + t = (t << 6) + 0U; + n_equal++; + } + + /* Slow path step 2: deal with full/partial group, padding, + * etc. Note that for num chars in [0,3] we intentionally emit + * 3 bytes but don't step forward that much, buffer space is + * guaranteed in setup. + * + * num chars: + * 0 #### no output (= step 0) + * 1 #=== reject, 6 bits of data + * 2 ##== 12 bits of data, output 1 byte (= step 1) + * 3 ###= 18 bits of data, output 2 bytes (= step 2) + * 4 #### 24 bits of data, output 3 bytes (= step 3) + */ + q[0] = (duk_uint8_t) ((t >> 16) & 0xffU); + q[1] = (duk_uint8_t) ((t >> 8) & 0xffU); + q[2] = (duk_uint8_t) (t & 0xffU); + + DUK_ASSERT(n_equal <= 4); + step = duk__base64_decode_nequal_step[n_equal]; + if (DUK_UNLIKELY(step < 0)) { + goto decode_error; + } + q += step; + + /* Slow path step 3: read and ignore padding and whitespace + * until (a) next non-padding and non-whitespace character + * after which we resume the fast path, or (b) end of input. + * This allows us to accept missing, partial, full, and extra + * padding cases uniformly. We also support concatenated + * base-64 documents because we resume scanning afterwards. + * + * Note that to support concatenated documents well, the '=' + * padding found inside the input must also allow for 'extra' + * padding. For example, 'Zm===' decodes to 'f' and has one + * extra padding char. So, 'Zm===Zm' should decode 'ff', even + * though the standard break-up would be 'Zm==' + '=Zm' which + * doesn't make sense. + * + * We also accept prepended padding like '==Zm9', because it + * is equivalent to an empty document with extra padding ('==') + * followed by a valid document. + */ + + for (;;) { + if (DUK_UNLIKELY(p >= p_end)) { + goto done; + } + x = duk__base64_dectab_fast[*p++]; + if (x == -1 || x == -2) { + ; /* padding or whitespace, keep eating */ + } else { + p--; + break; /* backtrack and go back to fast path, even for -1 */ + } + } /* slow path step 3 */ + } /* outer fast+slow path loop */ + + done: + DUK_DDD(DUK_DDDPRINT("done; p=%p, p_end=%p", + (const void *) p, (const void *) p_end)); + + DUK_ASSERT(p == p_end); + + *out_dst_final = q; + return 1; + + decode_error: + return 0; +} +#else /* DUK_USE_BASE64_FASTPATH */ +DUK_LOCAL duk_bool_t duk__base64_decode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst, duk_uint8_t **out_dst_final) { + duk_uint_t t, x; + duk_int_t y; + duk_int8_t step; + const duk_uint8_t *p; + const duk_uint8_t *p_end; + duk_uint8_t *q; + /* 0x09, 0x0a, or 0x0d */ + duk_uint32_t mask_white = (1U << 9) | (1U << 10) | (1U << 13); + + /* 't' tracks progress of the decoded group: + * + * t == 1 no valid chars yet + * t >= 0x40 1x6 = 6 bits shifted in + * t >= 0x1000 2x6 = 12 bits shifted in + * t >= 0x40000 3x6 = 18 bits shifted in + * t >= 0x1000000 4x6 = 24 bits shifted in + * + * By initializing t=1 there's no need for a separate counter for + * the number of characters found so far. + */ + p = src; + p_end = src + srclen; + q = dst; + t = 1UL; + + for (;;) { + duk_small_uint_t n_equal; + + DUK_ASSERT(t >= 1U); + if (p >= p_end) { + /* End of input: if input exists, treat like + * start of padding, finish the block, then + * re-enter here to see we're done. + */ + if (t == 1U) { + break; + } else { + goto simulate_padding; + } + } + + x = *p++; + + if (x >= 0x41U) { + /* Valid: a-z and A-Z. */ + DUK_ASSERT(x >= 0x41U && x <= 0xffU); + if (x >= 0x61U && x <= 0x7aU) { + y = (duk_int_t) x - 0x61 + 26; + } else if (x <= 0x5aU) { + y = (duk_int_t) x - 0x41; + } else { + goto decode_error; + } + } else if (x >= 0x30U) { + /* Valid: 0-9 and =. */ + DUK_ASSERT(x >= 0x30U && x <= 0x40U); + if (x <= 0x39U) { + y = (duk_int_t) x - 0x30 + 52; + } else if (x == 0x3dU) { + /* Skip padding and whitespace unless we're in the + * middle of a block. Otherwise complete group by + * simulating shifting in the correct padding. + */ + if (t == 1U) { + continue; + } + goto simulate_padding; + } else { + goto decode_error; + } + } else if (x >= 0x20U) { + /* Valid: +, /, and 0x20 whitespace. */ + DUK_ASSERT(x >= 0x20U && x <= 0x2fU); + if (x == 0x2bU) { + y = 62; + } else if (x == 0x2fU) { + y = 63; + } else if (x == 0x20U) { + continue; + } else { + goto decode_error; + } + } else { + /* Valid: whitespace. */ + duk_uint32_t m; + DUK_ASSERT(x < 0x20U); /* 0x00 to 0x1f */ + m = (1U << x); + if (mask_white & m) { + /* Allow basic ASCII whitespace. */ + continue; + } else { + goto decode_error; + } + } + + DUK_ASSERT(y >= 0 && y <= 63); + t = (t << 6) + (duk_uint_t) y; + if (t < 0x1000000UL) { + continue; + } + /* fall through; no padding will be added */ + + simulate_padding: + n_equal = 0; + while (t < 0x1000000UL) { + t = (t << 6) + 0U; + n_equal++; + } + + /* Output 3 bytes from 't' and advance as needed. */ + q[0] = (duk_uint8_t) ((t >> 16) & 0xffU); + q[1] = (duk_uint8_t) ((t >> 8) & 0xffU); + q[2] = (duk_uint8_t) (t & 0xffU); + + DUK_ASSERT(n_equal <= 4U); + step = duk__base64_decode_nequal_step[n_equal]; + if (step < 0) { + goto decode_error; + } + q += step; + + /* Re-enter loop. The actual padding characters are skipped + * by the main loop. This handles cases like missing, partial, + * full, and extra padding, and allows parsing of concatenated + * documents (with extra padding) like: Zm===Zm. Also extra + * prepended padding is accepted: ===Zm9v. + */ + t = 1U; + } + DUK_ASSERT(t == 1UL); + + *out_dst_final = q; + return 1; + + decode_error: + return 0; +} +#endif /* DUK_USE_BASE64_FASTPATH */ + +DUK_EXTERNAL const char *duk_base64_encode(duk_hthread *thr, duk_idx_t idx) { + const duk_uint8_t *src; + duk_size_t srclen; + duk_size_t dstlen; + duk_uint8_t *dst; + const char *ret; + + DUK_ASSERT_API_ENTRY(thr); + + idx = duk_require_normalize_index(thr, idx); + src = duk__prep_codec_arg(thr, idx, &srclen); + DUK_ASSERT(src != NULL); + + /* Compute exact output length. Computation must not wrap; this + * limit works for 32-bit size_t: + * >>> srclen = 3221225469 + * >>> '%x' % ((srclen + 2) / 3 * 4) + * 'fffffffc' + */ + if (srclen > 3221225469UL) { + goto type_error; + } + dstlen = (srclen + 2U) / 3U * 4U; + dst = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, dstlen); + + duk__base64_encode_helper((const duk_uint8_t *) src, srclen, dst); + + ret = duk_buffer_to_string(thr, -1); /* Safe, result is ASCII. */ + duk_replace(thr, idx); + return ret; + + type_error: + DUK_ERROR_TYPE(thr, DUK_STR_BASE64_ENCODE_FAILED); + DUK_WO_NORETURN(return NULL;); +} + +DUK_EXTERNAL void duk_base64_decode(duk_hthread *thr, duk_idx_t idx) { + const duk_uint8_t *src; + duk_size_t srclen; + duk_size_t dstlen; + duk_uint8_t *dst; + duk_uint8_t *dst_final; + + DUK_ASSERT_API_ENTRY(thr); + + idx = duk_require_normalize_index(thr, idx); + src = duk__prep_codec_arg(thr, idx, &srclen); + DUK_ASSERT(src != NULL); + + /* Round up and add safety margin. Avoid addition before division to + * avoid possibility of wrapping. Margin includes +3 for rounding up, + * and +3 for one extra group: the decoder may emit and then backtrack + * a full group (3 bytes) from zero-sized input for technical reasons. + * Similarly, 'xx' may ecause 1+3 = bytes to be emitted and then + * backtracked. + */ + dstlen = (srclen / 4) * 3 + 6; /* upper limit, assuming no whitespace etc */ + dst = (duk_uint8_t *) duk_push_dynamic_buffer(thr, dstlen); + /* Note: for dstlen=0, dst may be NULL */ + + if (!duk__base64_decode_helper((const duk_uint8_t *) src, srclen, dst, &dst_final)) { + goto type_error; + } + + /* XXX: convert to fixed buffer? */ + (void) duk_resize_buffer(thr, -1, (duk_size_t) (dst_final - dst)); + duk_replace(thr, idx); + return; + + type_error: + DUK_ERROR_TYPE(thr, DUK_STR_BASE64_DECODE_FAILED); + DUK_WO_NORETURN(return;); +} +#else /* DUK_USE_BASE64_SUPPORT */ +DUK_EXTERNAL const char *duk_base64_encode(duk_hthread *thr, duk_idx_t idx) { + DUK_UNREF(idx); + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return NULL;); +} + +DUK_EXTERNAL void duk_base64_decode(duk_hthread *thr, duk_idx_t idx) { + DUK_UNREF(idx); + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return;); +} +#endif /* DUK_USE_BASE64_SUPPORT */ + +/* + * Hex + */ + +#if defined(DUK_USE_HEX_SUPPORT) +DUK_EXTERNAL const char *duk_hex_encode(duk_hthread *thr, duk_idx_t idx) { + const duk_uint8_t *inp; + duk_size_t len; + duk_size_t i; + duk_uint8_t *buf; + const char *ret; +#if defined(DUK_USE_HEX_FASTPATH) + duk_size_t len_safe; + duk_uint16_t *p16; +#endif + + DUK_ASSERT_API_ENTRY(thr); + + idx = duk_require_normalize_index(thr, idx); + inp = duk__prep_codec_arg(thr, idx, &len); + DUK_ASSERT(inp != NULL); + + /* Fixed buffer, no zeroing because we'll fill all the data. */ + buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len * 2); + DUK_ASSERT(buf != NULL); + +#if defined(DUK_USE_HEX_FASTPATH) + DUK_ASSERT((((duk_size_t) buf) & 0x01U) == 0); /* pointer is aligned, guaranteed for fixed buffer */ + p16 = (duk_uint16_t *) (void *) buf; + len_safe = len & ~0x03U; + for (i = 0; i < len_safe; i += 4) { + p16[0] = duk_hex_enctab[inp[i]]; + p16[1] = duk_hex_enctab[inp[i + 1]]; + p16[2] = duk_hex_enctab[inp[i + 2]]; + p16[3] = duk_hex_enctab[inp[i + 3]]; + p16 += 4; + } + for (; i < len; i++) { + *p16++ = duk_hex_enctab[inp[i]]; + } +#else /* DUK_USE_HEX_FASTPATH */ + for (i = 0; i < len; i++) { + duk_small_uint_t t; + t = (duk_small_uint_t) inp[i]; + buf[i*2 + 0] = duk_lc_digits[t >> 4]; + buf[i*2 + 1] = duk_lc_digits[t & 0x0f]; + } +#endif /* DUK_USE_HEX_FASTPATH */ + + /* XXX: Using a string return value forces a string intern which is + * not always necessary. As a rough performance measure, hex encode + * time for tests/perf/test-hex-encode.js dropped from ~35s to ~15s + * without string coercion. Change to returning a buffer and let the + * caller coerce to string if necessary? + */ + + ret = duk_buffer_to_string(thr, -1); /* Safe, result is ASCII. */ + duk_replace(thr, idx); + return ret; +} + +DUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) { + const duk_uint8_t *inp; + duk_size_t len; + duk_size_t i; + duk_int_t t; + duk_uint8_t *buf; +#if defined(DUK_USE_HEX_FASTPATH) + duk_int_t chk; + duk_uint8_t *p; + duk_size_t len_safe; +#endif + + DUK_ASSERT_API_ENTRY(thr); + + idx = duk_require_normalize_index(thr, idx); + inp = duk__prep_codec_arg(thr, idx, &len); + DUK_ASSERT(inp != NULL); + + if (len & 0x01) { + goto type_error; + } + + /* Fixed buffer, no zeroing because we'll fill all the data. */ + buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len / 2); + DUK_ASSERT(buf != NULL); + +#if defined(DUK_USE_HEX_FASTPATH) + p = buf; + len_safe = len & ~0x07U; + for (i = 0; i < len_safe; i += 8) { + t = ((duk_int_t) duk_hex_dectab_shift4[inp[i]]) | + ((duk_int_t) duk_hex_dectab[inp[i + 1]]); + chk = t; + p[0] = (duk_uint8_t) t; + t = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 2]]) | + ((duk_int_t) duk_hex_dectab[inp[i + 3]]); + chk |= t; + p[1] = (duk_uint8_t) t; + t = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 4]]) | + ((duk_int_t) duk_hex_dectab[inp[i + 5]]); + chk |= t; + p[2] = (duk_uint8_t) t; + t = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 6]]) | + ((duk_int_t) duk_hex_dectab[inp[i + 7]]); + chk |= t; + p[3] = (duk_uint8_t) t; + p += 4; + + /* Check if any lookup above had a negative result. */ + if (DUK_UNLIKELY(chk < 0)) { + goto type_error; + } + } + for (; i < len; i += 2) { + /* First cast to duk_int_t to sign extend, second cast to + * duk_uint_t to avoid signed left shift, and final cast to + * duk_int_t result type. + */ + t = (duk_int_t) ((((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i]]) << 4U) | + ((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i + 1]])); + if (DUK_UNLIKELY(t < 0)) { + goto type_error; + } + *p++ = (duk_uint8_t) t; + } +#else /* DUK_USE_HEX_FASTPATH */ + for (i = 0; i < len; i += 2) { + /* For invalid characters the value -1 gets extended to + * at least 16 bits. If either nybble is invalid, the + * resulting 't' will be < 0. + */ + t = (duk_int_t) ((((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i]]) << 4U) | + ((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i + 1]])); + if (DUK_UNLIKELY(t < 0)) { + goto type_error; + } + buf[i >> 1] = (duk_uint8_t) t; + } +#endif /* DUK_USE_HEX_FASTPATH */ + + duk_replace(thr, idx); + return; + + type_error: + DUK_ERROR_TYPE(thr, DUK_STR_HEX_DECODE_FAILED); + DUK_WO_NORETURN(return;); +} +#else /* DUK_USE_HEX_SUPPORT */ +DUK_EXTERNAL const char *duk_hex_encode(duk_hthread *thr, duk_idx_t idx) { + DUK_UNREF(idx); + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return NULL;); +} +DUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) { + DUK_UNREF(idx); + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return;); +} +#endif /* DUK_USE_HEX_SUPPORT */ + +/* + * JSON + */ + +#if defined(DUK_USE_JSON_SUPPORT) +DUK_EXTERNAL const char *duk_json_encode(duk_hthread *thr, duk_idx_t idx) { +#if defined(DUK_USE_ASSERTIONS) + duk_idx_t top_at_entry; +#endif + const char *ret; + + DUK_ASSERT_API_ENTRY(thr); +#if defined(DUK_USE_ASSERTIONS) + top_at_entry = duk_get_top(thr); +#endif + + idx = duk_require_normalize_index(thr, idx); + duk_bi_json_stringify_helper(thr, + idx /*idx_value*/, + DUK_INVALID_INDEX /*idx_replacer*/, + DUK_INVALID_INDEX /*idx_space*/, + 0 /*flags*/); + DUK_ASSERT(duk_is_string(thr, -1)); + duk_replace(thr, idx); + ret = duk_get_string(thr, idx); + + DUK_ASSERT(duk_get_top(thr) == top_at_entry); + + return ret; +} + +DUK_EXTERNAL void duk_json_decode(duk_hthread *thr, duk_idx_t idx) { +#if defined(DUK_USE_ASSERTIONS) + duk_idx_t top_at_entry; +#endif + + DUK_ASSERT_API_ENTRY(thr); +#if defined(DUK_USE_ASSERTIONS) + top_at_entry = duk_get_top(thr); +#endif + + idx = duk_require_normalize_index(thr, idx); + duk_bi_json_parse_helper(thr, + idx /*idx_value*/, + DUK_INVALID_INDEX /*idx_reviver*/, + 0 /*flags*/); + duk_replace(thr, idx); + + DUK_ASSERT(duk_get_top(thr) == top_at_entry); +} +#else /* DUK_USE_JSON_SUPPORT */ +DUK_EXTERNAL const char *duk_json_encode(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_UNREF(idx); + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return NULL;); +} + +DUK_EXTERNAL void duk_json_decode(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_UNREF(idx); + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return;); +} +#endif /* DUK_USE_JSON_SUPPORT */ diff --git a/third_party/duktape/duk_api_compile.c b/third_party/duktape/duk_api_compile.c new file mode 100644 index 00000000..2f07d3e6 --- /dev/null +++ b/third_party/duktape/duk_api_compile.c @@ -0,0 +1,172 @@ +/* + * Compilation and evaluation + */ + +#include "third_party/duktape/duk_internal.h" + +typedef struct duk__compile_raw_args duk__compile_raw_args; +struct duk__compile_raw_args { + duk_size_t src_length; /* should be first on 64-bit platforms */ + const duk_uint8_t *src_buffer; + duk_uint_t flags; +}; + +/* Eval is just a wrapper now. */ +DUK_EXTERNAL duk_int_t duk_eval_raw(duk_hthread *thr, const char *src_buffer, duk_size_t src_length, duk_uint_t flags) { + duk_int_t rc; + + DUK_ASSERT_API_ENTRY(thr); + + /* Note: strictness is *not* inherited from the current Duktape/C. + * This would be confusing because the current strictness state + * depends on whether we're running inside a Duktape/C activation + * (= strict mode) or outside of any activation (= non-strict mode). + * See tests/api/test-eval-strictness.c for more discussion. + */ + + /* [ ... source? filename? ] (depends on flags) */ + + rc = duk_compile_raw(thr, src_buffer, src_length, flags | DUK_COMPILE_EVAL); /* may be safe, or non-safe depending on flags */ + + /* [ ... closure/error ] */ + + if (rc != DUK_EXEC_SUCCESS) { + rc = DUK_EXEC_ERROR; + goto got_rc; + } + + duk_push_global_object(thr); /* explicit 'this' binding, see GH-164 */ + + if (flags & DUK_COMPILE_SAFE) { + rc = duk_pcall_method(thr, 0); + } else { + duk_call_method(thr, 0); + rc = DUK_EXEC_SUCCESS; + } + + /* [ ... result/error ] */ + + got_rc: + if (flags & DUK_COMPILE_NORESULT) { + duk_pop(thr); + } + + return rc; +} + +/* Helper which can be called both directly and with duk_safe_call(). */ +DUK_LOCAL duk_ret_t duk__do_compile(duk_hthread *thr, void *udata) { + duk__compile_raw_args *comp_args; + duk_uint_t flags; + duk_hcompfunc *h_templ; + + DUK_CTX_ASSERT_VALID(thr); + DUK_ASSERT(udata != NULL); + + /* Note: strictness is not inherited from the current Duktape/C + * context. Otherwise it would not be possible to compile + * non-strict code inside a Duktape/C activation (which is + * always strict now). See tests/api/test-eval-strictness.c + * for discussion. + */ + + /* [ ... source? filename? ] (depends on flags) */ + + comp_args = (duk__compile_raw_args *) udata; + flags = comp_args->flags; + + if (flags & DUK_COMPILE_NOFILENAME) { + /* Automatic filename: 'eval' or 'input'. */ + duk_push_hstring_stridx(thr, (flags & DUK_COMPILE_EVAL) ? DUK_STRIDX_EVAL : DUK_STRIDX_INPUT); + } + + /* [ ... source? filename ] */ + + if (!comp_args->src_buffer) { + duk_hstring *h_sourcecode; + + h_sourcecode = duk_get_hstring(thr, -2); + if ((flags & DUK_COMPILE_NOSOURCE) || /* args incorrect */ + (h_sourcecode == NULL)) { /* e.g. duk_push_string_file_raw() pushed undefined */ + DUK_ERROR_TYPE(thr, DUK_STR_NO_SOURCECODE); + DUK_WO_NORETURN(return 0;); + } + DUK_ASSERT(h_sourcecode != NULL); + comp_args->src_buffer = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_sourcecode); + comp_args->src_length = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sourcecode); + } + DUK_ASSERT(comp_args->src_buffer != NULL); + + if (flags & DUK_COMPILE_FUNCTION) { + flags |= DUK_COMPILE_EVAL | DUK_COMPILE_FUNCEXPR; + } + + /* [ ... source? filename ] */ + + duk_js_compile(thr, comp_args->src_buffer, comp_args->src_length, flags); + + /* [ ... source? func_template ] */ + + if (flags & DUK_COMPILE_NOSOURCE) { + ; + } else { + duk_remove_m2(thr); + } + + /* [ ... func_template ] */ + + h_templ = (duk_hcompfunc *) duk_known_hobject(thr, -1); + duk_js_push_closure(thr, + h_templ, + thr->builtins[DUK_BIDX_GLOBAL_ENV], + thr->builtins[DUK_BIDX_GLOBAL_ENV], + 1 /*add_auto_proto*/); + duk_remove_m2(thr); /* -> [ ... closure ] */ + + /* [ ... closure ] */ + + return 1; +} + +DUK_EXTERNAL duk_int_t duk_compile_raw(duk_hthread *thr, const char *src_buffer, duk_size_t src_length, duk_uint_t flags) { + duk__compile_raw_args comp_args_alloc; + duk__compile_raw_args *comp_args = &comp_args_alloc; + + DUK_ASSERT_API_ENTRY(thr); + + if ((flags & DUK_COMPILE_STRLEN) && (src_buffer != NULL)) { + /* String length is computed here to avoid multiple evaluation + * of a macro argument in the calling side. + */ + src_length = DUK_STRLEN(src_buffer); + } + + comp_args->src_buffer = (const duk_uint8_t *) src_buffer; + comp_args->src_length = src_length; + comp_args->flags = flags; + + /* [ ... source? filename? ] (depends on flags) */ + + if (flags & DUK_COMPILE_SAFE) { + duk_int_t rc; + duk_int_t nargs; + duk_int_t nrets = 1; + + /* Arguments can be: [ source? filename? &comp_args] so that + * nargs is 1 to 3. Call site encodes the correct nargs count + * directly into flags. + */ + nargs = flags & 0x07; + DUK_ASSERT(nargs == ((flags & DUK_COMPILE_NOSOURCE) ? 0 : 1) + + ((flags & DUK_COMPILE_NOFILENAME) ? 0 : 1)); + rc = duk_safe_call(thr, duk__do_compile, (void *) comp_args, nargs, nrets); + + /* [ ... closure ] */ + return rc; + } + + (void) duk__do_compile(thr, (void *) comp_args); + + /* [ ... closure ] */ + return DUK_EXEC_SUCCESS; +} diff --git a/third_party/duktape/duk_api_debug.c b/third_party/duktape/duk_api_debug.c new file mode 100644 index 00000000..54ea563b --- /dev/null +++ b/third_party/duktape/duk_api_debug.c @@ -0,0 +1,261 @@ +/* + * Debugging related API calls + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_JSON_SUPPORT) +DUK_EXTERNAL void duk_push_context_dump(duk_hthread *thr) { + duk_idx_t idx; + duk_idx_t top; + + DUK_ASSERT_API_ENTRY(thr); + + /* We don't duk_require_stack() here now, but rely on the caller having + * enough space. + */ + + top = duk_get_top(thr); + duk_push_bare_array(thr); + for (idx = 0; idx < top; idx++) { + duk_dup(thr, idx); + duk_put_prop_index(thr, -2, (duk_uarridx_t) idx); + } + + /* XXX: conversion errors should not propagate outwards. + * Perhaps values need to be coerced individually? + */ + duk_bi_json_stringify_helper(thr, + duk_get_top_index(thr), /*idx_value*/ + DUK_INVALID_INDEX, /*idx_replacer*/ + DUK_INVALID_INDEX, /*idx_space*/ + DUK_JSON_FLAG_EXT_CUSTOM | + DUK_JSON_FLAG_ASCII_ONLY | + DUK_JSON_FLAG_AVOID_KEY_QUOTES /*flags*/); + + duk_push_sprintf(thr, "ctx: top=%ld, stack=%s", (long) top, (const char *) duk_safe_to_string(thr, -1)); + duk_replace(thr, -3); /* [ ... arr jsonx(arr) res ] -> [ ... res jsonx(arr) ] */ + duk_pop(thr); + DUK_ASSERT(duk_is_string(thr, -1)); +} +#else /* DUK_USE_JSON_SUPPORT */ +DUK_EXTERNAL void duk_push_context_dump(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return;); +} +#endif /* DUK_USE_JSON_SUPPORT */ + +#if defined(DUK_USE_DEBUGGER_SUPPORT) + +DUK_EXTERNAL void duk_debugger_attach(duk_hthread *thr, + duk_debug_read_function read_cb, + duk_debug_write_function write_cb, + duk_debug_peek_function peek_cb, + duk_debug_read_flush_function read_flush_cb, + duk_debug_write_flush_function write_flush_cb, + duk_debug_request_function request_cb, + duk_debug_detached_function detached_cb, + void *udata) { + duk_heap *heap; + const char *str; + duk_size_t len; + + /* XXX: should there be an error or an automatic detach if + * already attached? + */ + + DUK_D(DUK_DPRINT("application called duk_debugger_attach()")); + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(read_cb != NULL); + DUK_ASSERT(write_cb != NULL); + /* Other callbacks are optional. */ + + heap = thr->heap; + heap->dbg_read_cb = read_cb; + heap->dbg_write_cb = write_cb; + heap->dbg_peek_cb = peek_cb; + heap->dbg_read_flush_cb = read_flush_cb; + heap->dbg_write_flush_cb = write_flush_cb; + heap->dbg_request_cb = request_cb; + heap->dbg_detached_cb = detached_cb; + heap->dbg_udata = udata; + heap->dbg_have_next_byte = 0; + + /* Start in paused state. */ + heap->dbg_processing = 0; + heap->dbg_state_dirty = 0; + heap->dbg_force_restart = 0; + heap->dbg_pause_flags = 0; + heap->dbg_pause_act = NULL; + heap->dbg_pause_startline = 0; + heap->dbg_exec_counter = 0; + heap->dbg_last_counter = 0; + heap->dbg_last_time = 0.0; + duk_debug_set_paused(heap); /* XXX: overlap with fields above */ + + /* Send version identification and flush right afterwards. Note that + * we must write raw, unframed bytes here. + */ + duk_push_sprintf(thr, "%ld %ld %s %s\n", + (long) DUK_DEBUG_PROTOCOL_VERSION, + (long) DUK_VERSION, + (const char *) DUK_GIT_DESCRIBE, + (const char *) DUK_USE_TARGET_INFO); + str = duk_get_lstring(thr, -1, &len); + DUK_ASSERT(str != NULL); + duk_debug_write_bytes(thr, (const duk_uint8_t *) str, len); + duk_debug_write_flush(thr); + duk_pop(thr); +} + +DUK_EXTERNAL void duk_debugger_detach(duk_hthread *thr) { + DUK_D(DUK_DPRINT("application called duk_debugger_detach()")); + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->heap != NULL); + + /* Can be called multiple times with no harm. */ + duk_debug_do_detach(thr->heap); +} + +DUK_EXTERNAL void duk_debugger_cooperate(duk_hthread *thr) { + duk_bool_t processed_messages; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->heap != NULL); + + if (!duk_debug_is_attached(thr->heap)) { + return; + } + if (thr->callstack_curr != NULL || thr->heap->dbg_processing) { + /* Calling duk_debugger_cooperate() while Duktape is being + * called into is not supported. This is not a 100% check + * but prevents any damage in most cases. + */ + return; + } + + processed_messages = duk_debug_process_messages(thr, 1 /*no_block*/); + DUK_UNREF(processed_messages); +} + +DUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_hthread *thr, duk_idx_t nvalues) { + duk_idx_t top; + duk_idx_t idx; + duk_bool_t ret = 0; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->heap != NULL); + + DUK_D(DUK_DPRINT("application called duk_debugger_notify() with nvalues=%ld", (long) nvalues)); + + top = duk_get_top(thr); + if (top < nvalues) { + DUK_ERROR_RANGE(thr, "not enough stack values for notify"); + DUK_WO_NORETURN(return 0;); + } + if (duk_debug_is_attached(thr->heap)) { + duk_debug_write_notify(thr, DUK_DBG_CMD_APPNOTIFY); + for (idx = top - nvalues; idx < top; idx++) { + duk_tval *tv = DUK_GET_TVAL_POSIDX(thr, idx); + duk_debug_write_tval(thr, tv); + } + duk_debug_write_eom(thr); + + /* Return non-zero (true) if we have a good reason to believe + * the notify was delivered; if we're still attached at least + * a transport error was not indicated by the transport write + * callback. This is not a 100% guarantee of course. + */ + if (duk_debug_is_attached(thr->heap)) { + ret = 1; + } + } + duk_pop_n(thr, nvalues); + return ret; +} + +DUK_EXTERNAL void duk_debugger_pause(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->heap != NULL); + + DUK_D(DUK_DPRINT("application called duk_debugger_pause()")); + + /* Treat like a debugger statement: ignore when not attached. */ + if (duk_debug_is_attached(thr->heap)) { + if (duk_debug_is_paused(thr->heap)) { + DUK_D(DUK_DPRINT("duk_debugger_pause() called when already paused; ignoring")); + } else { + duk_debug_set_paused(thr->heap); + + /* Pause on the next opcode executed. This is always safe to do even + * inside the debugger message loop: the interrupt counter will be reset + * to its proper value when the message loop exits. + */ + thr->interrupt_init = 1; + thr->interrupt_counter = 0; + } + } +} + +#else /* DUK_USE_DEBUGGER_SUPPORT */ + +DUK_EXTERNAL void duk_debugger_attach(duk_hthread *thr, + duk_debug_read_function read_cb, + duk_debug_write_function write_cb, + duk_debug_peek_function peek_cb, + duk_debug_read_flush_function read_flush_cb, + duk_debug_write_flush_function write_flush_cb, + duk_debug_request_function request_cb, + duk_debug_detached_function detached_cb, + void *udata) { + DUK_ASSERT_API_ENTRY(thr); + DUK_UNREF(read_cb); + DUK_UNREF(write_cb); + DUK_UNREF(peek_cb); + DUK_UNREF(read_flush_cb); + DUK_UNREF(write_flush_cb); + DUK_UNREF(request_cb); + DUK_UNREF(detached_cb); + DUK_UNREF(udata); + DUK_ERROR_TYPE(thr, "no debugger support"); + DUK_WO_NORETURN(return;); +} + +DUK_EXTERNAL void duk_debugger_detach(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ERROR_TYPE(thr, "no debugger support"); + DUK_WO_NORETURN(return;); +} + +DUK_EXTERNAL void duk_debugger_cooperate(duk_hthread *thr) { + /* nop */ + DUK_ASSERT_API_ENTRY(thr); + DUK_UNREF(thr); +} + +DUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_hthread *thr, duk_idx_t nvalues) { + duk_idx_t top; + + DUK_ASSERT_API_ENTRY(thr); + + top = duk_get_top(thr); + if (top < nvalues) { + DUK_ERROR_RANGE_INVALID_COUNT(thr); + DUK_WO_NORETURN(return 0;); + } + + /* No debugger support, just pop values. */ + duk_pop_n(thr, nvalues); + return 0; +} + +DUK_EXTERNAL void duk_debugger_pause(duk_hthread *thr) { + /* Treat like debugger statement: nop */ + DUK_ASSERT_API_ENTRY(thr); + DUK_UNREF(thr); +} + +#endif /* DUK_USE_DEBUGGER_SUPPORT */ diff --git a/third_party/duktape/duk_api_heap.c b/third_party/duktape/duk_api_heap.c new file mode 100644 index 00000000..13525ee4 --- /dev/null +++ b/third_party/duktape/duk_api_heap.c @@ -0,0 +1,205 @@ +/* + * Heap creation and destruction + */ + +#include "third_party/duktape/duk_internal.h" + +typedef struct duk_internal_thread_state duk_internal_thread_state; + +struct duk_internal_thread_state { + duk_ljstate lj; + duk_bool_t creating_error; + duk_hthread *curr_thread; + duk_int_t call_recursion_depth; +}; + +DUK_EXTERNAL duk_hthread *duk_create_heap(duk_alloc_function alloc_func, + duk_realloc_function realloc_func, + duk_free_function free_func, + void *heap_udata, + duk_fatal_function fatal_handler) { + duk_heap *heap = NULL; + duk_hthread *thr; + + /* Assume that either all memory funcs are NULL or non-NULL, mixed + * cases will now be unsafe. + */ + + /* XXX: just assert non-NULL values here and make caller arguments + * do the defaulting to the default implementations (smaller code)? + */ + + if (!alloc_func) { + DUK_ASSERT(realloc_func == NULL); + DUK_ASSERT(free_func == NULL); +#if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS) + alloc_func = duk_default_alloc_function; + realloc_func = duk_default_realloc_function; + free_func = duk_default_free_function; +#else + DUK_D(DUK_DPRINT("no allocation functions given and no default providers")); + return NULL; +#endif + } else { + DUK_ASSERT(realloc_func != NULL); + DUK_ASSERT(free_func != NULL); + } + + if (!fatal_handler) { + fatal_handler = duk_default_fatal_handler; + } + + DUK_ASSERT(alloc_func != NULL); + DUK_ASSERT(realloc_func != NULL); + DUK_ASSERT(free_func != NULL); + DUK_ASSERT(fatal_handler != NULL); + + heap = duk_heap_alloc(alloc_func, realloc_func, free_func, heap_udata, fatal_handler); + if (!heap) { + return NULL; + } + thr = heap->heap_thread; + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + return thr; +} + +DUK_EXTERNAL void duk_destroy_heap(duk_hthread *thr) { + duk_heap *heap; + + if (!thr) { + return; + } + DUK_ASSERT_API_ENTRY(thr); + heap = thr->heap; + DUK_ASSERT(heap != NULL); + + duk_heap_free(heap); +} + +DUK_EXTERNAL void duk_suspend(duk_hthread *thr, duk_thread_state *state) { + duk_internal_thread_state *snapshot = (duk_internal_thread_state *) (void *) state; + duk_heap *heap; + duk_ljstate *lj; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(state != NULL); /* unvalidated */ + + /* Currently not supported when called from within a finalizer. + * If that is done, the finalizer will remain running indefinitely, + * preventing other finalizers from executing. The assert is a bit + * wider, checking that it would be OK to run pending finalizers. + */ + DUK_ASSERT(thr->heap->pf_prevent_count == 0); + + /* Currently not supported to duk_suspend() from an errCreate() + * call. + */ + DUK_ASSERT(thr->heap->creating_error == 0); + + heap = thr->heap; + lj = &heap->lj; + + duk_push_tval(thr, &lj->value1); + duk_push_tval(thr, &lj->value2); + + /* XXX: creating_error == 0 is asserted above, so no need to store. */ + duk_memcpy((void *) &snapshot->lj, (const void *) lj, sizeof(duk_ljstate)); + snapshot->creating_error = heap->creating_error; + snapshot->curr_thread = heap->curr_thread; + snapshot->call_recursion_depth = heap->call_recursion_depth; + + lj->jmpbuf_ptr = NULL; + lj->type = DUK_LJ_TYPE_UNKNOWN; + DUK_TVAL_SET_UNDEFINED(&lj->value1); + DUK_TVAL_SET_UNDEFINED(&lj->value2); + heap->creating_error = 0; + heap->curr_thread = NULL; + heap->call_recursion_depth = 0; +} + +DUK_EXTERNAL void duk_resume(duk_hthread *thr, const duk_thread_state *state) { + const duk_internal_thread_state *snapshot = (const duk_internal_thread_state *) (const void *) state; + duk_heap *heap; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(state != NULL); /* unvalidated */ + + /* Shouldn't be necessary if duk_suspend() is called before + * duk_resume(), but assert in case API sequence is incorrect. + */ + DUK_ASSERT(thr->heap->pf_prevent_count == 0); + DUK_ASSERT(thr->heap->creating_error == 0); + + heap = thr->heap; + + duk_memcpy((void *) &heap->lj, (const void *) &snapshot->lj, sizeof(duk_ljstate)); + heap->creating_error = snapshot->creating_error; + heap->curr_thread = snapshot->curr_thread; + heap->call_recursion_depth = snapshot->call_recursion_depth; + + duk_pop_2(thr); +} + +/* XXX: better place for this */ +DUK_EXTERNAL void duk_set_global_object(duk_hthread *thr) { + duk_hobject *h_glob; + duk_hobject *h_prev_glob; + duk_hobjenv *h_env; + duk_hobject *h_prev_env; + + DUK_ASSERT_API_ENTRY(thr); + + DUK_D(DUK_DPRINT("replace global object with: %!T", duk_get_tval(thr, -1))); + + h_glob = duk_require_hobject(thr, -1); + DUK_ASSERT(h_glob != NULL); + + /* + * Replace global object. + */ + + h_prev_glob = thr->builtins[DUK_BIDX_GLOBAL]; + DUK_UNREF(h_prev_glob); + thr->builtins[DUK_BIDX_GLOBAL] = h_glob; + DUK_HOBJECT_INCREF(thr, h_glob); + DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_prev_glob); /* side effects, in theory (referenced by global env) */ + + /* + * Replace lexical environment for global scope + * + * Create a new object environment for the global lexical scope. + * We can't just reset the _Target property of the current one, + * because the lexical scope is shared by other threads with the + * same (initial) built-ins. + */ + + h_env = duk_hobjenv_alloc(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV)); + DUK_ASSERT(h_env != NULL); + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_env) == NULL); + + DUK_ASSERT(h_env->target == NULL); + DUK_ASSERT(h_glob != NULL); + h_env->target = h_glob; + DUK_HOBJECT_INCREF(thr, h_glob); + DUK_ASSERT(h_env->has_this == 0); + + /* [ ... new_glob ] */ + + h_prev_env = thr->builtins[DUK_BIDX_GLOBAL_ENV]; + thr->builtins[DUK_BIDX_GLOBAL_ENV] = (duk_hobject *) h_env; + DUK_HOBJECT_INCREF(thr, (duk_hobject *) h_env); + DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_prev_env); /* side effects */ + DUK_UNREF(h_env); /* without refcounts */ + DUK_UNREF(h_prev_env); + + /* [ ... new_glob ] */ + + duk_pop(thr); + + /* [ ... ] */ +} diff --git a/third_party/duktape/duk_api_inspect.c b/third_party/duktape/duk_api_inspect.c new file mode 100644 index 00000000..f5750b0a --- /dev/null +++ b/third_party/duktape/duk_api_inspect.c @@ -0,0 +1,229 @@ +/* + * Inspection + */ + +#include "third_party/duktape/duk_internal.h" + +/* For footprint efficient multiple value setting: arrays are much better than + * varargs, format string with parsing is often better than string pointer arrays. + */ +DUK_LOCAL void duk__inspect_multiple_uint(duk_hthread *thr, const char *fmt, duk_int_t *vals) { + duk_int_t val; + const char *p; + const char *p_curr; + duk_size_t len; + + for (p = fmt;;) { + len = DUK_STRLEN(p); + p_curr = p; + p += len + 1; + if (len == 0) { + /* Double NUL (= empty key) terminates. */ + break; + } + val = *vals++; + if (val >= 0) { + /* Negative values are markers to skip key. */ + duk_push_string(thr, p_curr); + duk_push_int(thr, val); + duk_put_prop(thr, -3); + } + } +} + +/* Raw helper to extract internal information / statistics about a value. + * The return value is an object with properties that are version specific. + * The properties must not expose anything that would lead to security + * issues (e.g. exposing compiled function 'data' buffer might be an issue). + * Currently only counts and sizes and such are given so there shouldn't + * be security implications. + */ + +#define DUK__IDX_TYPE 0 +#define DUK__IDX_ITAG 1 +#define DUK__IDX_REFC 2 +#define DUK__IDX_HBYTES 3 +#define DUK__IDX_CLASS 4 +#define DUK__IDX_PBYTES 5 +#define DUK__IDX_ESIZE 6 +#define DUK__IDX_ENEXT 7 +#define DUK__IDX_ASIZE 8 +#define DUK__IDX_HSIZE 9 +#define DUK__IDX_BCBYTES 10 +#define DUK__IDX_DBYTES 11 +#define DUK__IDX_TSTATE 12 +#define DUK__IDX_VARIANT 13 + +DUK_EXTERNAL void duk_inspect_value(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + duk_heaphdr *h; + /* The temporary values should be in an array rather than individual + * variables which (in practice) ensures that the compiler won't map + * them to registers and emit a lot of unnecessary shuffling code. + */ + duk_int_t vals[14]; + + DUK_ASSERT_API_ENTRY(thr); + + /* Assume two's complement and set everything to -1. */ + duk_memset((void *) &vals, (int) 0xff, sizeof(vals)); + DUK_ASSERT(vals[DUK__IDX_TYPE] == -1); /* spot check one */ + + tv = duk_get_tval_or_unused(thr, idx); + h = (DUK_TVAL_IS_HEAP_ALLOCATED(tv) ? DUK_TVAL_GET_HEAPHDR(tv) : NULL); + + vals[DUK__IDX_TYPE] = duk_get_type_tval(tv); + vals[DUK__IDX_ITAG] = (duk_int_t) DUK_TVAL_GET_TAG(tv); + + duk_push_bare_object(thr); /* Invalidates 'tv'. */ + tv = NULL; + + if (h == NULL) { + goto finish; + } + duk_push_pointer(thr, (void *) h); + duk_put_prop_literal(thr, -2, "hptr"); + +#if 0 + /* Covers a lot of information, e.g. buffer and string variants. */ + duk_push_uint(thr, (duk_uint_t) DUK_HEAPHDR_GET_FLAGS(h)); + duk_put_prop_literal(thr, -2, "hflags"); +#endif + +#if defined(DUK_USE_REFERENCE_COUNTING) + vals[DUK__IDX_REFC] = (duk_int_t) DUK_HEAPHDR_GET_REFCOUNT(h); +#endif + vals[DUK__IDX_VARIANT] = 0; + + /* Heaphdr size and additional allocation size, followed by + * type specific stuff (with varying value count). + */ + switch ((duk_small_int_t) DUK_HEAPHDR_GET_TYPE(h)) { + case DUK_HTYPE_STRING: { + duk_hstring *h_str = (duk_hstring *) h; + vals[DUK__IDX_HBYTES] = (duk_int_t) (sizeof(duk_hstring) + DUK_HSTRING_GET_BYTELEN(h_str) + 1); +#if defined(DUK_USE_HSTRING_EXTDATA) + if (DUK_HSTRING_HAS_EXTDATA(h_str)) { + vals[DUK__IDX_VARIANT] = 1; + } +#endif + break; + } + case DUK_HTYPE_OBJECT: { + duk_hobject *h_obj = (duk_hobject *) h; + + /* XXX: variants here are maybe pointless; class is enough? */ + if (DUK_HOBJECT_IS_ARRAY(h_obj)) { + vals[DUK__IDX_HBYTES] = sizeof(duk_harray); + } else if (DUK_HOBJECT_IS_COMPFUNC(h_obj)) { + vals[DUK__IDX_HBYTES] = sizeof(duk_hcompfunc); + } else if (DUK_HOBJECT_IS_NATFUNC(h_obj)) { + vals[DUK__IDX_HBYTES] = sizeof(duk_hnatfunc); + } else if (DUK_HOBJECT_IS_THREAD(h_obj)) { + vals[DUK__IDX_HBYTES] = sizeof(duk_hthread); + vals[DUK__IDX_TSTATE] = ((duk_hthread *) h_obj)->state; +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + } else if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) { + vals[DUK__IDX_HBYTES] = sizeof(duk_hbufobj); + /* XXX: some size information */ +#endif + } else { + vals[DUK__IDX_HBYTES] = (duk_small_uint_t) sizeof(duk_hobject); + } + + vals[DUK__IDX_CLASS] = (duk_int_t) DUK_HOBJECT_GET_CLASS_NUMBER(h_obj); + vals[DUK__IDX_PBYTES] = (duk_int_t) DUK_HOBJECT_P_ALLOC_SIZE(h_obj); + vals[DUK__IDX_ESIZE] = (duk_int_t) DUK_HOBJECT_GET_ESIZE(h_obj); + vals[DUK__IDX_ENEXT] = (duk_int_t) DUK_HOBJECT_GET_ENEXT(h_obj); + vals[DUK__IDX_ASIZE] = (duk_int_t) DUK_HOBJECT_GET_ASIZE(h_obj); + vals[DUK__IDX_HSIZE] = (duk_int_t) DUK_HOBJECT_GET_HSIZE(h_obj); + + /* Note: e_next indicates the number of gc-reachable entries + * in the entry part, and also indicates the index where the + * next new property would be inserted. It does *not* indicate + * the number of non-NULL keys present in the object. That + * value could be counted separately but requires a pass through + * the key list. + */ + + if (DUK_HOBJECT_IS_COMPFUNC(h_obj)) { + duk_hbuffer *h_data = (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(thr->heap, (duk_hcompfunc *) h_obj); + vals[DUK__IDX_BCBYTES] = (duk_int_t) (h_data ? DUK_HBUFFER_GET_SIZE(h_data) : 0); + } + break; + } + case DUK_HTYPE_BUFFER: { + duk_hbuffer *h_buf = (duk_hbuffer *) h; + + if (DUK_HBUFFER_HAS_DYNAMIC(h_buf)) { + if (DUK_HBUFFER_HAS_EXTERNAL(h_buf)) { + vals[DUK__IDX_VARIANT] = 2; /* buffer variant 2: external */ + vals[DUK__IDX_HBYTES] = (duk_uint_t) (sizeof(duk_hbuffer_external)); + } else { + /* When alloc_size == 0 the second allocation may not + * actually exist. + */ + vals[DUK__IDX_VARIANT] = 1; /* buffer variant 1: dynamic */ + vals[DUK__IDX_HBYTES] = (duk_uint_t) (sizeof(duk_hbuffer_dynamic)); + } + vals[DUK__IDX_DBYTES] = (duk_int_t) (DUK_HBUFFER_GET_SIZE(h_buf)); + } else { + DUK_ASSERT(vals[DUK__IDX_VARIANT] == 0); /* buffer variant 0: fixed */ + vals[DUK__IDX_HBYTES] = (duk_int_t) (sizeof(duk_hbuffer_fixed) + DUK_HBUFFER_GET_SIZE(h_buf)); + } + break; + } + } + + finish: + duk__inspect_multiple_uint(thr, + "type" "\x00" "itag" "\x00" "refc" "\x00" "hbytes" "\x00" "class" "\x00" + "pbytes" "\x00" "esize" "\x00" "enext" "\x00" "asize" "\x00" "hsize" "\x00" + "bcbytes" "\x00" "dbytes" "\x00" "tstate" "\x00" "variant" "\x00" "\x00", + (duk_int_t *) &vals); +} + +DUK_EXTERNAL void duk_inspect_callstack_entry(duk_hthread *thr, duk_int_t level) { + duk_activation *act; + duk_uint_fast32_t pc; + duk_uint_fast32_t line; + + DUK_ASSERT_API_ENTRY(thr); + + /* -1 = top callstack entry + * -2 = caller of level -1 + * etc + */ + act = duk_hthread_get_activation_for_level(thr, level); + if (act == NULL) { + duk_push_undefined(thr); + return; + } + duk_push_bare_object(thr); + + /* Relevant PC is just before current one because PC is + * post-incremented. This should match what error augment + * code does. + */ + pc = duk_hthread_get_act_prev_pc(thr, act); + + duk_push_tval(thr, &act->tv_func); + + duk_push_uint(thr, (duk_uint_t) pc); + duk_put_prop_stridx_short(thr, -3, DUK_STRIDX_PC); + +#if defined(DUK_USE_PC2LINE) + line = duk_hobject_pc2line_query(thr, -1, pc); +#else + line = 0; +#endif + duk_push_uint(thr, (duk_uint_t) line); + duk_put_prop_stridx_short(thr, -3, DUK_STRIDX_LINE_NUMBER); + + duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_LC_FUNCTION); + /* Providing access to e.g. act->lex_env would be dangerous: these + * internal structures must never be accessible to the application. + * Duktape relies on them having consistent data, and this consistency + * is only asserted for, not checked for. + */ +} diff --git a/third_party/duktape/duk_api_internal.h b/third_party/duktape/duk_api_internal.h new file mode 100644 index 00000000..cf9c0f6b --- /dev/null +++ b/third_party/duktape/duk_api_internal.h @@ -0,0 +1,386 @@ +/* + * Internal API calls which have (stack and other) semantics similar + * to the public API. + */ + +#if !defined(DUK_API_INTERNAL_H_INCLUDED) +#define DUK_API_INTERNAL_H_INCLUDED + +/* Inline macro helpers. */ +#if defined(DUK_USE_PREFER_SIZE) +#define DUK_INLINE_PERF +#define DUK_ALWAYS_INLINE_PERF +#define DUK_NOINLINE_PERF +#else +#define DUK_INLINE_PERF DUK_INLINE +#define DUK_ALWAYS_INLINE_PERF DUK_ALWAYS_INLINE +#define DUK_NOINLINE_PERF DUK_NOINLINE +#endif + +/* Inline macro helpers, for bytecode executor. */ +#if defined(DUK_USE_EXEC_PREFER_SIZE) +#define DUK_EXEC_INLINE_PERF +#define DUK_EXEC_ALWAYS_INLINE_PERF +#define DUK_EXEC_NOINLINE_PERF +#else +#define DUK_EXEC_INLINE_PERF DUK_INLINE +#define DUK_EXEC_ALWAYS_INLINE_PERF DUK_ALWAYS_INLINE +#define DUK_EXEC_NOINLINE_PERF DUK_NOINLINE +#endif + +/* duk_push_sprintf constants */ +#define DUK_PUSH_SPRINTF_INITIAL_SIZE 256L +#define DUK_PUSH_SPRINTF_SANITY_LIMIT (1L * 1024L * 1024L * 1024L) + +/* Flag ORed to err_code to indicate __FILE__ / __LINE__ is not + * blamed as source of error for error fileName / lineNumber. + */ +#define DUK_ERRCODE_FLAG_NOBLAME_FILELINE (1L << 24) + +/* Current convention is to use duk_size_t for value stack sizes and global indices, + * and duk_idx_t for local frame indices. + */ +DUK_INTERNAL_DECL void duk_valstack_grow_check_throw(duk_hthread *thr, duk_size_t min_bytes); +DUK_INTERNAL_DECL duk_bool_t duk_valstack_grow_check_nothrow(duk_hthread *thr, duk_size_t min_bytes); +DUK_INTERNAL_DECL void duk_valstack_shrink_check_nothrow(duk_hthread *thr, duk_bool_t snug); + +DUK_INTERNAL_DECL void duk_copy_tvals_incref(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_size_t count); + +DUK_INTERNAL_DECL duk_tval *duk_reserve_gap(duk_hthread *thr, duk_idx_t idx_base, duk_idx_t count); + +DUK_INTERNAL_DECL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL void duk_set_top_and_wipe(duk_hthread *thr, duk_idx_t top, duk_idx_t idx_wipe_start); + +DUK_INTERNAL_DECL void duk_dup_0(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_dup_1(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_dup_2(duk_hthread *thr); +/* duk_dup_m1() would be same as duk_dup_top() */ +DUK_INTERNAL_DECL void duk_dup_m2(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_dup_m3(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_dup_m4(duk_hthread *thr); + +DUK_INTERNAL_DECL void duk_remove_unsafe(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL void duk_remove_m2(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_remove_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count); +DUK_INTERNAL_DECL void duk_remove_n_unsafe(duk_hthread *thr, duk_idx_t idx, duk_idx_t count); + +DUK_INTERNAL_DECL duk_int_t duk_get_type_tval(duk_tval *tv); +DUK_INTERNAL_DECL duk_uint_t duk_get_type_mask_tval(duk_tval *tv); + +#if defined(DUK_USE_VERBOSE_ERRORS) && defined(DUK_USE_PARANOID_ERRORS) +DUK_INTERNAL_DECL const char *duk_get_type_name(duk_hthread *thr, duk_idx_t idx); +#endif +DUK_INTERNAL_DECL duk_small_uint_t duk_get_class_number(duk_hthread *thr, duk_idx_t idx); + +DUK_INTERNAL_DECL duk_tval *duk_get_tval(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_tval *duk_get_tval_or_unused(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_tval *duk_require_tval(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL void duk_push_tval(duk_hthread *thr, duk_tval *tv); + +/* Push the current 'this' binding; throw TypeError if binding is not object + * coercible (CheckObjectCoercible). + */ +DUK_INTERNAL_DECL void duk_push_this_check_object_coercible(duk_hthread *thr); + +/* duk_push_this() + CheckObjectCoercible() + duk_to_object() */ +DUK_INTERNAL_DECL duk_hobject *duk_push_this_coercible_to_object(duk_hthread *thr); + +/* duk_push_this() + CheckObjectCoercible() + duk_to_string() */ +DUK_INTERNAL_DECL duk_hstring *duk_push_this_coercible_to_string(duk_hthread *thr); + +DUK_INTERNAL_DECL duk_hstring *duk_push_uint_to_hstring(duk_hthread *thr, duk_uint_t i); + +/* Get a borrowed duk_tval pointer to the current 'this' binding. Caller must + * make sure there's an active callstack entry. Note that the returned pointer + * is unstable with regards to side effects. + */ +DUK_INTERNAL_DECL duk_tval *duk_get_borrowed_this_tval(duk_hthread *thr); + +/* XXX: add fastint support? */ +#define duk_push_u64(thr,val) \ + duk_push_number((thr), (duk_double_t) (val)) +#define duk_push_i64(thr,val) \ + duk_push_number((thr), (duk_double_t) (val)) + +/* duk_push_(u)int() is guaranteed to support at least (un)signed 32-bit range */ +#define duk_push_u32(thr,val) \ + duk_push_uint((thr), (duk_uint_t) (val)) +#define duk_push_i32(thr,val) \ + duk_push_int((thr), (duk_int_t) (val)) + +/* sometimes stack and array indices need to go on the stack */ +#define duk_push_idx(thr,val) \ + duk_push_int((thr), (duk_int_t) (val)) +#define duk_push_uarridx(thr,val) \ + duk_push_uint((thr), (duk_uint_t) (val)) +#define duk_push_size_t(thr,val) \ + duk_push_uint((thr), (duk_uint_t) (val)) /* XXX: assumed to fit for now */ + +DUK_INTERNAL_DECL duk_bool_t duk_is_string_notsymbol(duk_hthread *thr, duk_idx_t idx); + +DUK_INTERNAL_DECL duk_bool_t duk_is_callable_tval(duk_hthread *thr, duk_tval *tv); + +DUK_INTERNAL_DECL duk_bool_t duk_is_bare_object(duk_hthread *thr, duk_idx_t idx); + +DUK_INTERNAL_DECL duk_hstring *duk_get_hstring(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hstring *duk_get_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL const char *duk_get_string_notsymbol(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hobject *duk_get_hobject(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hbuffer *duk_get_hbuffer(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hthread *duk_get_hthread(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hcompfunc *duk_get_hcompfunc(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hnatfunc *duk_get_hnatfunc(duk_hthread *thr, duk_idx_t idx); + +DUK_INTERNAL_DECL void *duk_get_buffer_data_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len, duk_bool_t throw_flag, duk_bool_t *out_isbuffer); + +DUK_INTERNAL_DECL duk_hobject *duk_get_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum); + +DUK_INTERNAL_DECL duk_hobject *duk_get_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask); +DUK_INTERNAL_DECL duk_hobject *duk_require_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask); +DUK_INTERNAL_DECL duk_hobject *duk_require_hobject_accept_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask); +#define duk_require_hobject_promote_lfunc(thr,idx) \ + duk_require_hobject_promote_mask((thr), (idx), DUK_TYPE_MASK_LIGHTFUNC) +#define duk_get_hobject_promote_lfunc(thr,idx) \ + duk_get_hobject_promote_mask((thr), (idx), DUK_TYPE_MASK_LIGHTFUNC) + +#if 0 /*unused*/ +DUK_INTERNAL_DECL void *duk_get_voidptr(duk_hthread *thr, duk_idx_t idx); +#endif + +DUK_INTERNAL_DECL duk_hstring *duk_known_hstring(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hobject *duk_known_hobject(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hbuffer *duk_known_hbuffer(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hcompfunc *duk_known_hcompfunc(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hnatfunc *duk_known_hnatfunc(duk_hthread *thr, duk_idx_t idx); + +DUK_INTERNAL_DECL duk_double_t duk_to_number_tval(duk_hthread *thr, duk_tval *tv); + +DUK_INTERNAL_DECL duk_hstring *duk_to_hstring(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hstring *duk_to_hstring_m1(duk_hthread *thr); +DUK_INTERNAL_DECL duk_hstring *duk_to_hstring_acceptsymbol(duk_hthread *thr, duk_idx_t idx); + +DUK_INTERNAL_DECL duk_hobject *duk_to_hobject(duk_hthread *thr, duk_idx_t idx); + +DUK_INTERNAL_DECL duk_double_t duk_to_number_m1(duk_hthread *thr); +DUK_INTERNAL_DECL duk_double_t duk_to_number_m2(duk_hthread *thr); + +DUK_INTERNAL_DECL duk_bool_t duk_to_boolean_top_pop(duk_hthread *thr); + +#if defined(DUK_USE_DEBUGGER_SUPPORT) /* only needed by debugger for now */ +DUK_INTERNAL_DECL duk_hstring *duk_safe_to_hstring(duk_hthread *thr, duk_idx_t idx); +#endif +DUK_INTERNAL_DECL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv, duk_bool_t avoid_side_effects); + +DUK_INTERNAL_DECL duk_int_t duk_to_int_clamped_raw(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped); /* out_clamped=NULL, RangeError if outside range */ +DUK_INTERNAL_DECL duk_int_t duk_to_int_clamped(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval); +DUK_INTERNAL_DECL duk_int_t duk_to_int_check_range(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval); +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL_DECL duk_uint8_t duk_to_uint8clamped(duk_hthread *thr, duk_idx_t idx); +#endif +DUK_INTERNAL_DECL duk_hstring *duk_to_property_key_hstring(duk_hthread *thr, duk_idx_t idx); + +DUK_INTERNAL_DECL duk_hstring *duk_require_hstring(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hstring *duk_require_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL const char *duk_require_lstring_notsymbol(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len); +DUK_INTERNAL_DECL const char *duk_require_string_notsymbol(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hobject *duk_require_hobject(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hbuffer *duk_require_hbuffer(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hthread *duk_require_hthread(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hcompfunc *duk_require_hcompfunc(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL duk_hnatfunc *duk_require_hnatfunc(duk_hthread *thr, duk_idx_t idx); + +DUK_INTERNAL_DECL duk_hobject *duk_require_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum); + +DUK_INTERNAL_DECL void duk_push_hstring(duk_hthread *thr, duk_hstring *h); +DUK_INTERNAL_DECL void duk_push_hstring_stridx(duk_hthread *thr, duk_small_uint_t stridx); +DUK_INTERNAL_DECL void duk_push_hstring_empty(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_push_hobject(duk_hthread *thr, duk_hobject *h); +DUK_INTERNAL_DECL void duk_push_hbuffer(duk_hthread *thr, duk_hbuffer *h); +#define duk_push_hthread(thr,h) \ + duk_push_hobject((thr), (duk_hobject *) (h)) +#define duk_push_hnatfunc(thr,h) \ + duk_push_hobject((thr), (duk_hobject *) (h)) +DUK_INTERNAL_DECL void duk_push_hobject_bidx(duk_hthread *thr, duk_small_int_t builtin_idx); +DUK_INTERNAL_DECL duk_hobject *duk_push_object_helper(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx); +DUK_INTERNAL_DECL duk_hobject *duk_push_object_helper_proto(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_hobject *proto); +DUK_INTERNAL_DECL duk_hcompfunc *duk_push_hcompfunc(duk_hthread *thr); +DUK_INTERNAL_DECL duk_hboundfunc *duk_push_hboundfunc(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_push_c_function_builtin(duk_hthread *thr, duk_c_function func, duk_int_t nargs); +DUK_INTERNAL_DECL void duk_push_c_function_builtin_noconstruct(duk_hthread *thr, duk_c_function func, duk_int_t nargs); + +/* XXX: duk_push_harray() and duk_push_hcompfunc() are inconsistent with + * duk_push_hobject() etc which don't create a new value. + */ +DUK_INTERNAL_DECL duk_harray *duk_push_harray(duk_hthread *thr); +DUK_INTERNAL_DECL duk_harray *duk_push_harray_with_size(duk_hthread *thr, duk_uint32_t size); +DUK_INTERNAL_DECL duk_tval *duk_push_harray_with_size_outptr(duk_hthread *thr, duk_uint32_t size); + +DUK_INTERNAL_DECL void duk_push_string_funcptr(duk_hthread *thr, duk_uint8_t *ptr, duk_size_t sz); +DUK_INTERNAL_DECL void duk_push_lightfunc_name_raw(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags); +DUK_INTERNAL_DECL void duk_push_lightfunc_name(duk_hthread *thr, duk_tval *tv); +DUK_INTERNAL_DECL void duk_push_lightfunc_tostring(duk_hthread *thr, duk_tval *tv); +#if 0 /* not used yet */ +DUK_INTERNAL_DECL void duk_push_hnatfunc_name(duk_hthread *thr, duk_hnatfunc *h); +#endif +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL_DECL duk_hbufobj *duk_push_bufobj_raw(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx); +#endif + +DUK_INTERNAL_DECL void *duk_push_fixed_buffer_nozero(duk_hthread *thr, duk_size_t len); +DUK_INTERNAL_DECL void *duk_push_fixed_buffer_zero(duk_hthread *thr, duk_size_t len); + +DUK_INTERNAL_DECL const char *duk_push_string_readable(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL const char *duk_push_string_tval_readable(duk_hthread *thr, duk_tval *tv); +DUK_INTERNAL_DECL const char *duk_push_string_tval_readable_error(duk_hthread *thr, duk_tval *tv); + +/* The duk_xxx_prop_stridx_short() variants expect their arguments to be short + * enough to be packed into a single 32-bit integer argument. Argument limits + * vary per call; typically 16 bits are assigned to the signed value stack index + * and the stridx. In practice these work well for footprint with constant + * arguments and such call sites are also easiest to verify to be correct. + */ + +DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [val] */ +DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args); +#define duk_get_prop_stridx_short(thr,obj_idx,stridx) \ + (DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \ + DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \ + duk_get_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx)))) +DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_boolean(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_bool_t *out_has_prop); /* [] -> [] */ + +DUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop(duk_hthread *thr, duk_idx_t obj_idx); +DUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx); +DUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args); +#define duk_xget_owndataprop_stridx_short(thr,obj_idx,stridx) \ + (DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \ + DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \ + duk_xget_owndataprop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx)))) + +DUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [val] -> [] */ +DUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args); +#define duk_put_prop_stridx_short(thr,obj_idx,stridx) \ + (DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \ + DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \ + duk_put_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx)))) + +DUK_INTERNAL_DECL duk_bool_t duk_del_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [] */ +#if 0 /* Too few call sites to be useful. */ +DUK_INTERNAL_DECL duk_bool_t duk_del_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args); +#define duk_del_prop_stridx_short(thr,obj_idx,stridx) \ + (DUK_ASSERT_EXPR((obj_idx) >= -0x8000L && (obj_idx) <= 0x7fffL), \ + DUK_ASSERT_EXPR((stridx) >= 0 && (stridx) <= 0xffffL), \ + duk_del_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx)))) +#endif +#define duk_del_prop_stridx_short(thr,obj_idx,stridx) \ + duk_del_prop_stridx((thr), (obj_idx), (stridx)) + +DUK_INTERNAL_DECL duk_bool_t duk_has_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [] */ +#if 0 /* Too few call sites to be useful. */ +DUK_INTERNAL_DECL duk_bool_t duk_has_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args); +#define duk_has_prop_stridx_short(thr,obj_idx,stridx) \ + (DUK_ASSERT_EXPR((obj_idx) >= -0x8000L && (obj_idx) <= 0x7fffL), \ + DUK_ASSERT_EXPR((stridx) >= 0 && (stridx) <= 0xffffL), \ + duk_has_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx)))) +#endif +#define duk_has_prop_stridx_short(thr,obj_idx,stridx) \ + duk_has_prop_stridx((thr), (obj_idx), (stridx)) + +DUK_INTERNAL_DECL void duk_xdef_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t desc_flags); /* [key val] -> [] */ + +DUK_INTERNAL_DECL void duk_xdef_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx, duk_small_uint_t desc_flags); /* [val] -> [] */ + +/* XXX: Because stridx and desc_flags have a limited range, this call could + * always pack stridx and desc_flags into a single argument. + */ +DUK_INTERNAL_DECL void duk_xdef_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_uint_t desc_flags); /* [val] -> [] */ +DUK_INTERNAL_DECL void duk_xdef_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args); +#define duk_xdef_prop_stridx_short(thr,obj_idx,stridx,desc_flags) \ + (DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x80L && (duk_int_t) (obj_idx) <= 0x7fL), \ + DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \ + DUK_ASSERT_EXPR((duk_int_t) (desc_flags) >= 0 && (duk_int_t) (desc_flags) <= 0xffL), \ + duk_xdef_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 24) + (((duk_uint_t) (stridx)) << 8) + (duk_uint_t) (desc_flags))) + +#define duk_xdef_prop_wec(thr,obj_idx) \ + duk_xdef_prop((thr), (obj_idx), DUK_PROPDESC_FLAGS_WEC) +#define duk_xdef_prop_index_wec(thr,obj_idx,arr_idx) \ + duk_xdef_prop_index((thr), (obj_idx), (arr_idx), DUK_PROPDESC_FLAGS_WEC) +#define duk_xdef_prop_stridx_wec(thr,obj_idx,stridx) \ + duk_xdef_prop_stridx((thr), (obj_idx), (stridx), DUK_PROPDESC_FLAGS_WEC) +#define duk_xdef_prop_stridx_short_wec(thr,obj_idx,stridx) \ + duk_xdef_prop_stridx_short((thr), (obj_idx), (stridx), DUK_PROPDESC_FLAGS_WEC) + +#if 0 /*unused*/ +DUK_INTERNAL_DECL void duk_xdef_prop_stridx_builtin(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags); /* [] -> [] */ +#endif + +DUK_INTERNAL_DECL void duk_xdef_prop_stridx_thrower(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [] */ + +DUK_INTERNAL_DECL duk_bool_t duk_get_method_stridx(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t stridx); + +DUK_INTERNAL_DECL void duk_pack(duk_hthread *thr, duk_idx_t count); +DUK_INTERNAL_DECL duk_idx_t duk_unpack_array_like(duk_hthread *thr, duk_idx_t idx); +#if 0 +DUK_INTERNAL_DECL void duk_unpack(duk_hthread *thr); +#endif + +DUK_INTERNAL_DECL void duk_push_symbol_descriptive_string(duk_hthread *thr, duk_hstring *h); + +DUK_INTERNAL_DECL void duk_resolve_nonbound_function(duk_hthread *thr); + +DUK_INTERNAL_DECL duk_idx_t duk_get_top_require_min(duk_hthread *thr, duk_idx_t min_top); +DUK_INTERNAL_DECL duk_idx_t duk_get_top_index_unsafe(duk_hthread *thr); + +DUK_INTERNAL_DECL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count); +DUK_INTERNAL_DECL void duk_pop_unsafe(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_pop_2_unsafe(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_pop_3_unsafe(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count); +DUK_INTERNAL_DECL void duk_pop_nodecref_unsafe(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_pop_2_nodecref_unsafe(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_pop_3_nodecref_unsafe(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_pop_undefined(duk_hthread *thr); + +DUK_INTERNAL_DECL void duk_compact_m1(duk_hthread *thr); + +DUK_INTERNAL_DECL void duk_seal_freeze_raw(duk_hthread *thr, duk_idx_t obj_idx, duk_bool_t is_freeze); + +DUK_INTERNAL_DECL void duk_insert_undefined(duk_hthread *thr, duk_idx_t idx); +DUK_INTERNAL_DECL void duk_insert_undefined_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count); + +DUK_INTERNAL_DECL void duk_concat_2(duk_hthread *thr); + +DUK_INTERNAL_DECL duk_int_t duk_pcall_method_flags(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags); + +#if defined(DUK_USE_SYMBOL_BUILTIN) +DUK_INTERNAL_DECL void duk_to_primitive_ordinary(duk_hthread *thr, duk_idx_t idx, duk_int_t hint); +#endif + +DUK_INTERNAL_DECL void duk_clear_prototype(duk_hthread *thr, duk_idx_t idx); + +/* Raw internal valstack access macros: access is unsafe so call site + * must have a guarantee that the index is valid. When that is the case, + * using these macro results in faster and smaller code than duk_get_tval(). + * Both 'ctx' and 'idx' are evaluted multiple times, but only for asserts. + */ +#define DUK_ASSERT_VALID_NEGIDX(thr,idx) \ + (DUK_ASSERT_EXPR((duk_int_t) (idx) < 0), DUK_ASSERT_EXPR(duk_is_valid_index((thr), (idx)))) +#define DUK_ASSERT_VALID_POSIDX(thr,idx) \ + (DUK_ASSERT_EXPR((duk_int_t) (idx) >= 0), DUK_ASSERT_EXPR(duk_is_valid_index((thr), (idx)))) +#define DUK_GET_TVAL_NEGIDX(thr,idx) \ + (DUK_ASSERT_VALID_NEGIDX((thr),(idx)), ((duk_hthread *) (thr))->valstack_top + (idx)) +#define DUK_GET_TVAL_POSIDX(thr,idx) \ + (DUK_ASSERT_VALID_POSIDX((thr),(idx)), ((duk_hthread *) (thr))->valstack_bottom + (idx)) +#define DUK_GET_HOBJECT_NEGIDX(thr,idx) \ + (DUK_ASSERT_VALID_NEGIDX((thr),(idx)), DUK_TVAL_GET_OBJECT(((duk_hthread *) (thr))->valstack_top + (idx))) +#define DUK_GET_HOBJECT_POSIDX(thr,idx) \ + (DUK_ASSERT_VALID_POSIDX((thr),(idx)), DUK_TVAL_GET_OBJECT(((duk_hthread *) (thr))->valstack_bottom + (idx))) + +#define DUK_GET_THIS_TVAL_PTR(thr) \ + (DUK_ASSERT_EXPR((thr)->valstack_bottom > (thr)->valstack), \ + (thr)->valstack_bottom - 1) + +DUK_INTERNAL_DECL duk_double_t duk_time_get_ecmascript_time(duk_hthread *thr); +DUK_INTERNAL_DECL duk_double_t duk_time_get_ecmascript_time_nofrac(duk_hthread *thr); +DUK_INTERNAL_DECL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr); + +#endif /* DUK_API_INTERNAL_H_INCLUDED */ diff --git a/third_party/duktape/duk_api_memory.c b/third_party/duktape/duk_api_memory.c new file mode 100644 index 00000000..a0c9040f --- /dev/null +++ b/third_party/duktape/duk_api_memory.c @@ -0,0 +1,80 @@ +/* + * Memory calls. + */ + +#include "third_party/duktape/duk_internal.h" + +DUK_EXTERNAL void *duk_alloc_raw(duk_hthread *thr, duk_size_t size) { + DUK_ASSERT_API_ENTRY(thr); + + return DUK_ALLOC_RAW(thr->heap, size); +} + +DUK_EXTERNAL void duk_free_raw(duk_hthread *thr, void *ptr) { + DUK_ASSERT_API_ENTRY(thr); + + DUK_FREE_RAW(thr->heap, ptr); +} + +DUK_EXTERNAL void *duk_realloc_raw(duk_hthread *thr, void *ptr, duk_size_t size) { + DUK_ASSERT_API_ENTRY(thr); + + return DUK_REALLOC_RAW(thr->heap, ptr, size); +} + +DUK_EXTERNAL void *duk_alloc(duk_hthread *thr, duk_size_t size) { + DUK_ASSERT_API_ENTRY(thr); + + return DUK_ALLOC(thr->heap, size); +} + +DUK_EXTERNAL void duk_free(duk_hthread *thr, void *ptr) { + DUK_ASSERT_API_ENTRY(thr); + + DUK_FREE_CHECKED(thr, ptr); +} + +DUK_EXTERNAL void *duk_realloc(duk_hthread *thr, void *ptr, duk_size_t size) { + DUK_ASSERT_API_ENTRY(thr); + + /* + * Note: since this is an exposed API call, there should be + * no way a mark-and-sweep could have a side effect on the + * memory allocation behind 'ptr'; the pointer should never + * be something that Duktape wants to change. + * + * Thus, no need to use DUK_REALLOC_INDIRECT (and we don't + * have the storage location here anyway). + */ + + return DUK_REALLOC(thr->heap, ptr, size); +} + +DUK_EXTERNAL void duk_get_memory_functions(duk_hthread *thr, duk_memory_functions *out_funcs) { + duk_heap *heap; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(out_funcs != NULL); + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + + heap = thr->heap; + out_funcs->alloc_func = heap->alloc_func; + out_funcs->realloc_func = heap->realloc_func; + out_funcs->free_func = heap->free_func; + out_funcs->udata = heap->heap_udata; +} + +DUK_EXTERNAL void duk_gc(duk_hthread *thr, duk_uint_t flags) { + duk_heap *heap; + duk_small_uint_t ms_flags; + + DUK_ASSERT_API_ENTRY(thr); + heap = thr->heap; + DUK_ASSERT(heap != NULL); + + DUK_D(DUK_DPRINT("mark-and-sweep requested by application")); + DUK_ASSERT(DUK_GC_COMPACT == DUK_MS_FLAG_EMERGENCY); /* Compact flag is 1:1 with emergency flag which forces compaction. */ + ms_flags = (duk_small_uint_t) flags; + duk_heap_mark_and_sweep(heap, ms_flags); +} diff --git a/third_party/duktape/duk_api_object.c b/third_party/duktape/duk_api_object.c new file mode 100644 index 00000000..3ae7865a --- /dev/null +++ b/third_party/duktape/duk_api_object.c @@ -0,0 +1,1050 @@ +/* + * Object handling: property access and other support functions. + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Property handling + * + * The API exposes only the most common property handling functions. + * The caller can invoke ECMAScript built-ins for full control (e.g. + * defineProperty, getOwnPropertyDescriptor). + */ + +DUK_EXTERNAL duk_bool_t duk_get_prop(duk_hthread *thr, duk_idx_t obj_idx) { + duk_tval *tv_obj; + duk_tval *tv_key; + duk_bool_t rc; + + DUK_ASSERT_API_ENTRY(thr); + + /* Note: copying tv_obj and tv_key to locals to shield against a valstack + * resize is not necessary for a property get right now. + */ + + tv_obj = duk_require_tval(thr, obj_idx); + tv_key = duk_require_tval(thr, -1); + + rc = duk_hobject_getprop(thr, tv_obj, tv_key); + DUK_ASSERT(rc == 0 || rc == 1); + /* a value is left on stack regardless of rc */ + + duk_remove_m2(thr); /* remove key */ + DUK_ASSERT(duk_is_undefined(thr, -1) || rc == 1); + return rc; /* 1 if property found, 0 otherwise */ +} + +DUK_EXTERNAL duk_bool_t duk_get_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(key != NULL); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + (void) duk_push_string(thr, key); + return duk_get_prop(thr, obj_idx); +} + +DUK_EXTERNAL duk_bool_t duk_get_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(key != NULL); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + (void) duk_push_lstring(thr, key, key_len); + return duk_get_prop(thr, obj_idx); +} + +#if !defined(DUK_USE_PREFER_SIZE) +DUK_EXTERNAL duk_bool_t duk_get_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(key != NULL); + DUK_ASSERT(key[key_len] == (char) 0); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + (void) duk_push_literal_raw(thr, key, key_len); + return duk_get_prop(thr, obj_idx); +} +#endif + +DUK_EXTERNAL duk_bool_t duk_get_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) { + DUK_ASSERT_API_ENTRY(thr); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + duk_push_uarridx(thr, arr_idx); + return duk_get_prop(thr, obj_idx); +} + +DUK_EXTERNAL duk_bool_t duk_get_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) { + DUK_ASSERT_API_ENTRY(thr); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + (void) duk_push_heapptr(thr, ptr); /* NULL -> 'undefined' */ + return duk_get_prop(thr, obj_idx); +} + +DUK_INTERNAL duk_bool_t duk_get_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT_STRIDX_VALID(stridx); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + (void) duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx)); + return duk_get_prop(thr, obj_idx); +} + +DUK_INTERNAL duk_bool_t duk_get_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) { + return duk_get_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16), + (duk_small_uint_t) (packed_args & 0xffffUL)); +} + +DUK_INTERNAL duk_bool_t duk_get_prop_stridx_boolean(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_bool_t *out_has_prop) { + duk_bool_t rc; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT_STRIDX_VALID(stridx); + + rc = duk_get_prop_stridx(thr, obj_idx, stridx); + if (out_has_prop) { + *out_has_prop = rc; + } + return duk_to_boolean_top_pop(thr); +} + +/* This get variant is for internal use, it differs from standard + * duk_get_prop() in that: + * - Object argument must be an object (primitive values not supported). + * - Key argument must be a string (no coercion). + * - Only own properties are checked (no inheritance). Only "entry part" + * properties are checked (not array index properties). + * - Property must be a plain data property, not a getter. + * - Proxy traps are not triggered. + */ +DUK_INTERNAL duk_bool_t duk_xget_owndataprop(duk_hthread *thr, duk_idx_t obj_idx) { + duk_hobject *h_obj; + duk_hstring *h_key; + duk_tval *tv_val; + + DUK_ASSERT_API_ENTRY(thr); + + /* Note: copying tv_obj and tv_key to locals to shield against a valstack + * resize is not necessary for a property get right now. + */ + + h_obj = duk_get_hobject(thr, obj_idx); + if (h_obj == NULL) { + return 0; + } + h_key = duk_require_hstring(thr, -1); + + tv_val = duk_hobject_find_entry_tval_ptr(thr->heap, h_obj, h_key); + if (tv_val == NULL) { + return 0; + } + + duk_push_tval(thr, tv_val); + duk_remove_m2(thr); /* remove key */ + + return 1; +} + +DUK_INTERNAL duk_bool_t duk_xget_owndataprop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT_STRIDX_VALID(stridx); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + (void) duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx)); + return duk_xget_owndataprop(thr, obj_idx); +} + +DUK_INTERNAL duk_bool_t duk_xget_owndataprop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) { + return duk_xget_owndataprop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16), + (duk_small_uint_t) (packed_args & 0xffffUL)); +} + +DUK_LOCAL duk_bool_t duk__put_prop_shared(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t idx_key) { + duk_tval *tv_obj; + duk_tval *tv_key; + duk_tval *tv_val; + duk_bool_t throw_flag; + duk_bool_t rc; + + /* Note: copying tv_obj and tv_key to locals to shield against a valstack + * resize is not necessary for a property put right now (putprop protects + * against it internally). + */ + + /* Key and value indices are either (-2, -1) or (-1, -2). Given idx_key, + * idx_val is always (idx_key ^ 0x01). + */ + DUK_ASSERT((idx_key == -2 && (idx_key ^ 1) == -1) || + (idx_key == -1 && (idx_key ^ 1) == -2)); + /* XXX: Direct access; faster validation. */ + tv_obj = duk_require_tval(thr, obj_idx); + tv_key = duk_require_tval(thr, idx_key); + tv_val = duk_require_tval(thr, idx_key ^ 1); + throw_flag = duk_is_strict_call(thr); + + rc = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, throw_flag); + DUK_ASSERT(rc == 0 || rc == 1); + + duk_pop_2(thr); /* remove key and value */ + return rc; /* 1 if property found, 0 otherwise */ +} + +DUK_EXTERNAL duk_bool_t duk_put_prop(duk_hthread *thr, duk_idx_t obj_idx) { + DUK_ASSERT_API_ENTRY(thr); + return duk__put_prop_shared(thr, obj_idx, -2); +} + +DUK_EXTERNAL duk_bool_t duk_put_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(key != NULL); + + /* Careful here and with other duk_put_prop_xxx() helpers: the + * target object and the property value may be in the same value + * stack slot (unusual, but still conceptually clear). + */ + obj_idx = duk_normalize_index(thr, obj_idx); + (void) duk_push_string(thr, key); + return duk__put_prop_shared(thr, obj_idx, -1); +} + +DUK_EXTERNAL duk_bool_t duk_put_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(key != NULL); + + obj_idx = duk_normalize_index(thr, obj_idx); + (void) duk_push_lstring(thr, key, key_len); + return duk__put_prop_shared(thr, obj_idx, -1); +} + +#if !defined(DUK_USE_PREFER_SIZE) +DUK_EXTERNAL duk_bool_t duk_put_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(key != NULL); + DUK_ASSERT(key[key_len] == (char) 0); + + obj_idx = duk_normalize_index(thr, obj_idx); + (void) duk_push_literal_raw(thr, key, key_len); + return duk__put_prop_shared(thr, obj_idx, -1); +} +#endif + +DUK_EXTERNAL duk_bool_t duk_put_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) { + DUK_ASSERT_API_ENTRY(thr); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + duk_push_uarridx(thr, arr_idx); + return duk__put_prop_shared(thr, obj_idx, -1); +} + +DUK_EXTERNAL duk_bool_t duk_put_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) { + DUK_ASSERT_API_ENTRY(thr); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + (void) duk_push_heapptr(thr, ptr); /* NULL -> 'undefined' */ + return duk__put_prop_shared(thr, obj_idx, -1); +} + + +DUK_INTERNAL duk_bool_t duk_put_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT_STRIDX_VALID(stridx); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx)); + return duk__put_prop_shared(thr, obj_idx, -1); +} + +DUK_INTERNAL duk_bool_t duk_put_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) { + return duk_put_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16), + (duk_small_uint_t) (packed_args & 0xffffUL)); +} + +DUK_EXTERNAL duk_bool_t duk_del_prop(duk_hthread *thr, duk_idx_t obj_idx) { + duk_tval *tv_obj; + duk_tval *tv_key; + duk_bool_t throw_flag; + duk_bool_t rc; + + DUK_ASSERT_API_ENTRY(thr); + + /* Note: copying tv_obj and tv_key to locals to shield against a valstack + * resize is not necessary for a property delete right now. + */ + + tv_obj = duk_require_tval(thr, obj_idx); + tv_key = duk_require_tval(thr, -1); + throw_flag = duk_is_strict_call(thr); + + rc = duk_hobject_delprop(thr, tv_obj, tv_key, throw_flag); + DUK_ASSERT(rc == 0 || rc == 1); + + duk_pop(thr); /* remove key */ + return rc; +} + +DUK_EXTERNAL duk_bool_t duk_del_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(key != NULL); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + (void) duk_push_string(thr, key); + return duk_del_prop(thr, obj_idx); +} + +DUK_EXTERNAL duk_bool_t duk_del_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(key != NULL); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + (void) duk_push_lstring(thr, key, key_len); + return duk_del_prop(thr, obj_idx); +} + +#if !defined(DUK_USE_PREFER_SIZE) +DUK_EXTERNAL duk_bool_t duk_del_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(key != NULL); + DUK_ASSERT(key[key_len] == (char) 0); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + (void) duk_push_literal_raw(thr, key, key_len); + return duk_del_prop(thr, obj_idx); +} +#endif + +DUK_EXTERNAL duk_bool_t duk_del_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) { + DUK_ASSERT_API_ENTRY(thr); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + duk_push_uarridx(thr, arr_idx); + return duk_del_prop(thr, obj_idx); +} + +DUK_EXTERNAL duk_bool_t duk_del_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) { + DUK_ASSERT_API_ENTRY(thr); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + (void) duk_push_heapptr(thr, ptr); /* NULL -> 'undefined' */ + return duk_del_prop(thr, obj_idx); +} + +DUK_INTERNAL duk_bool_t duk_del_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT_STRIDX_VALID(stridx); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx)); + return duk_del_prop(thr, obj_idx); +} + +#if 0 +DUK_INTERNAL duk_bool_t duk_del_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) { + return duk_del_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16), + (duk_small_uint_t) (packed_args & 0xffffUL)); +} +#endif + +DUK_EXTERNAL duk_bool_t duk_has_prop(duk_hthread *thr, duk_idx_t obj_idx) { + duk_tval *tv_obj; + duk_tval *tv_key; + duk_bool_t rc; + + DUK_ASSERT_API_ENTRY(thr); + + /* Note: copying tv_obj and tv_key to locals to shield against a valstack + * resize is not necessary for a property existence check right now. + */ + + tv_obj = duk_require_tval(thr, obj_idx); + tv_key = duk_require_tval(thr, -1); + + rc = duk_hobject_hasprop(thr, tv_obj, tv_key); + DUK_ASSERT(rc == 0 || rc == 1); + + duk_pop(thr); /* remove key */ + return rc; /* 1 if property found, 0 otherwise */ +} + +DUK_EXTERNAL duk_bool_t duk_has_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(key != NULL); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + (void) duk_push_string(thr, key); + return duk_has_prop(thr, obj_idx); +} + +DUK_EXTERNAL duk_bool_t duk_has_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(key != NULL); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + (void) duk_push_lstring(thr, key, key_len); + return duk_has_prop(thr, obj_idx); +} + +#if !defined(DUK_USE_PREFER_SIZE) +DUK_EXTERNAL duk_bool_t duk_has_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(key != NULL); + DUK_ASSERT(key[key_len] == (char) 0); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + (void) duk_push_literal_raw(thr, key, key_len); + return duk_has_prop(thr, obj_idx); +} +#endif + +DUK_EXTERNAL duk_bool_t duk_has_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) { + DUK_ASSERT_API_ENTRY(thr); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + duk_push_uarridx(thr, arr_idx); + return duk_has_prop(thr, obj_idx); +} + +DUK_EXTERNAL duk_bool_t duk_has_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) { + DUK_ASSERT_API_ENTRY(thr); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + (void) duk_push_heapptr(thr, ptr); /* NULL -> 'undefined' */ + return duk_has_prop(thr, obj_idx); +} + +DUK_INTERNAL duk_bool_t duk_has_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT_STRIDX_VALID(stridx); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx)); + return duk_has_prop(thr, obj_idx); +} + +#if 0 +DUK_INTERNAL duk_bool_t duk_has_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) { + return duk_has_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16), + (duk_small_uint_t) (packed_args & 0xffffUL)); +} +#endif + +/* Define own property without inheritance lookups and such. This differs from + * [[DefineOwnProperty]] because special behaviors (like Array 'length') are + * not invoked by this method. The caller must be careful to invoke any such + * behaviors if necessary. + */ +DUK_INTERNAL void duk_xdef_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t desc_flags) { + duk_hobject *obj; + duk_hstring *key; + + DUK_ASSERT_API_ENTRY(thr); + + obj = duk_require_hobject(thr, obj_idx); + DUK_ASSERT(obj != NULL); + key = duk_to_property_key_hstring(thr, -2); + DUK_ASSERT(key != NULL); + DUK_ASSERT(duk_require_tval(thr, -1) != NULL); + + duk_hobject_define_property_internal(thr, obj, key, desc_flags); + + duk_pop(thr); /* pop key */ +} + +DUK_INTERNAL void duk_xdef_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx, duk_small_uint_t desc_flags) { + duk_hobject *obj; + + DUK_ASSERT_API_ENTRY(thr); + + obj = duk_require_hobject(thr, obj_idx); + DUK_ASSERT(obj != NULL); + + duk_hobject_define_property_internal_arridx(thr, obj, arr_idx, desc_flags); + /* value popped by call */ +} + +DUK_INTERNAL void duk_xdef_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_uint_t desc_flags) { + duk_hobject *obj; + duk_hstring *key; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT_STRIDX_VALID(stridx); + + obj = duk_require_hobject(thr, obj_idx); + DUK_ASSERT(obj != NULL); + key = DUK_HTHREAD_GET_STRING(thr, stridx); + DUK_ASSERT(key != NULL); + DUK_ASSERT(duk_require_tval(thr, -1) != NULL); + + duk_hobject_define_property_internal(thr, obj, key, desc_flags); + /* value popped by call */ +} + +DUK_INTERNAL void duk_xdef_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) { + duk_xdef_prop_stridx(thr, (duk_idx_t) (duk_int8_t) (packed_args >> 24), + (duk_small_uint_t) (packed_args >> 8) & 0xffffUL, + (duk_small_uint_t) (packed_args & 0xffL)); +} + +#if 0 /*unused*/ +DUK_INTERNAL void duk_xdef_prop_stridx_builtin(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags) { + duk_hobject *obj; + duk_hstring *key; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT_STRIDX_VALID(stridx); + DUK_ASSERT_BIDX_VALID(builtin_idx); + + obj = duk_require_hobject(thr, obj_idx); + DUK_ASSERT(obj != NULL); + key = DUK_HTHREAD_GET_STRING(thr, stridx); + DUK_ASSERT(key != NULL); + + duk_push_hobject(thr, thr->builtins[builtin_idx]); + duk_hobject_define_property_internal(thr, obj, key, desc_flags); + /* value popped by call */ +} +#endif + +/* This is a rare property helper; it sets the global thrower (E5 Section 13.2.3) + * setter/getter into an object property. This is needed by the 'arguments' + * object creation code, function instance creation code, and Function.prototype.bind(). + */ + +DUK_INTERNAL void duk_xdef_prop_stridx_thrower(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) { + DUK_ASSERT_API_ENTRY(thr); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + duk_push_hstring_stridx(thr, stridx); + duk_push_hobject_bidx(thr, DUK_BIDX_TYPE_ERROR_THROWER); + duk_dup_top(thr); + duk_def_prop(thr, obj_idx, DUK_DEFPROP_HAVE_SETTER | DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_FORCE); /* attributes always 0 */ +} + +/* Object.getOwnPropertyDescriptor() equivalent C binding. */ +DUK_EXTERNAL void duk_get_prop_desc(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t flags) { + DUK_ASSERT_API_ENTRY(thr); + DUK_UNREF(flags); /* no flags defined yet */ + + duk_hobject_object_get_own_property_descriptor(thr, obj_idx); /* [ ... key ] -> [ ... desc ] */ +} + +/* Object.defineProperty() equivalent C binding. */ +DUK_EXTERNAL void duk_def_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t flags) { + duk_idx_t idx_base; + duk_hobject *obj; + duk_hstring *key; + duk_idx_t idx_value; + duk_hobject *get; + duk_hobject *set; + duk_uint_t is_data_desc; + duk_uint_t is_acc_desc; + + DUK_ASSERT_API_ENTRY(thr); + + obj = duk_require_hobject(thr, obj_idx); + + is_data_desc = flags & (DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE); + is_acc_desc = flags & (DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER); + if (is_data_desc && is_acc_desc) { + /* "Have" flags must not be conflicting so that they would + * apply to both a plain property and an accessor at the same + * time. + */ + goto fail_invalid_desc; + } + + idx_base = duk_get_top_index(thr); + if (flags & DUK_DEFPROP_HAVE_SETTER) { + duk_require_type_mask(thr, idx_base, DUK_TYPE_MASK_UNDEFINED | + DUK_TYPE_MASK_OBJECT | + DUK_TYPE_MASK_LIGHTFUNC); + set = duk_get_hobject_promote_lfunc(thr, idx_base); + if (set != NULL && !DUK_HOBJECT_IS_CALLABLE(set)) { + goto fail_not_callable; + } + idx_base--; + } else { + set = NULL; + } + if (flags & DUK_DEFPROP_HAVE_GETTER) { + duk_require_type_mask(thr, idx_base, DUK_TYPE_MASK_UNDEFINED | + DUK_TYPE_MASK_OBJECT | + DUK_TYPE_MASK_LIGHTFUNC); + get = duk_get_hobject_promote_lfunc(thr, idx_base); + if (get != NULL && !DUK_HOBJECT_IS_CALLABLE(get)) { + goto fail_not_callable; + } + idx_base--; + } else { + get = NULL; + } + if (flags & DUK_DEFPROP_HAVE_VALUE) { + idx_value = idx_base; + idx_base--; + } else { + idx_value = (duk_idx_t) -1; + } + key = duk_to_property_key_hstring(thr, idx_base); + DUK_ASSERT(key != NULL); + + duk_require_valid_index(thr, idx_base); + + duk_hobject_define_property_helper(thr, + flags /*defprop_flags*/, + obj, + key, + idx_value, + get, + set, + 1 /*throw_flag*/); + + /* Clean up stack */ + + duk_set_top(thr, idx_base); + + /* [ ... obj ... ] */ + + return; + + fail_invalid_desc: + DUK_ERROR_TYPE(thr, DUK_STR_INVALID_DESCRIPTOR); + DUK_WO_NORETURN(return;); + + fail_not_callable: + DUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE); + DUK_WO_NORETURN(return;); +} + +/* + * Object related + */ + +DUK_EXTERNAL void duk_compact(duk_hthread *thr, duk_idx_t obj_idx) { + duk_hobject *obj; + + DUK_ASSERT_API_ENTRY(thr); + + obj = duk_get_hobject(thr, obj_idx); + if (obj) { + /* Note: this may fail, caller should protect the call if necessary */ + duk_hobject_compact_props(thr, obj); + } +} + +DUK_INTERNAL void duk_compact_m1(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + + duk_compact(thr, -1); +} + +/* XXX: the duk_hobject_enum.c stack APIs should be reworked */ + +DUK_EXTERNAL void duk_enum(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t enum_flags) { + DUK_ASSERT_API_ENTRY(thr); + + duk_dup(thr, obj_idx); + duk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER); + duk_hobject_enumerator_create(thr, enum_flags); /* [target] -> [enum] */ +} + +DUK_EXTERNAL duk_bool_t duk_next(duk_hthread *thr, duk_idx_t enum_index, duk_bool_t get_value) { + DUK_ASSERT_API_ENTRY(thr); + + duk_require_hobject(thr, enum_index); + duk_dup(thr, enum_index); + return duk_hobject_enumerator_next(thr, get_value); +} + +DUK_INTERNAL void duk_seal_freeze_raw(duk_hthread *thr, duk_idx_t obj_idx, duk_bool_t is_freeze) { + duk_tval *tv; + duk_hobject *h; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_require_tval(thr, obj_idx); + DUK_ASSERT(tv != NULL); + + /* Seal/freeze are quite rare in practice so it'd be nice to get the + * correct behavior simply via automatic promotion (at the cost of some + * memory churn). However, the promoted objects don't behave the same, + * e.g. promoted lightfuncs are extensible. + */ + + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_BUFFER: + /* Plain buffer: already sealed, but not frozen (and can't be frozen + * because index properties can't be made non-writable. + */ + if (is_freeze) { + goto fail_cannot_freeze; + } + break; + case DUK_TAG_LIGHTFUNC: + /* Lightfunc: already sealed and frozen, success. */ + break; + case DUK_TAG_OBJECT: + h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + if (is_freeze && DUK_HOBJECT_IS_BUFOBJ(h)) { + /* Buffer objects cannot be frozen because there's no internal + * support for making virtual array indices non-writable. + */ + DUK_DD(DUK_DDPRINT("cannot freeze a buffer object")); + goto fail_cannot_freeze; + } + duk_hobject_object_seal_freeze_helper(thr, h, is_freeze); + + /* Sealed and frozen objects cannot gain any more properties, + * so this is a good time to compact them. + */ + duk_hobject_compact_props(thr, h); + break; + default: + /* ES2015 Sections 19.1.2.5, 19.1.2.17 */ + break; + } + return; + + fail_cannot_freeze: + DUK_ERROR_TYPE_INVALID_ARGS(thr); /* XXX: proper error message */ + DUK_WO_NORETURN(return;); +} + +DUK_EXTERNAL void duk_seal(duk_hthread *thr, duk_idx_t obj_idx) { + DUK_ASSERT_API_ENTRY(thr); + + duk_seal_freeze_raw(thr, obj_idx, 0 /*is_freeze*/); +} + +DUK_EXTERNAL void duk_freeze(duk_hthread *thr, duk_idx_t obj_idx) { + DUK_ASSERT_API_ENTRY(thr); + + duk_seal_freeze_raw(thr, obj_idx, 1 /*is_freeze*/); +} + +/* + * Helpers for writing multiple properties + */ + +DUK_EXTERNAL void duk_put_function_list(duk_hthread *thr, duk_idx_t obj_idx, const duk_function_list_entry *funcs) { + const duk_function_list_entry *ent = funcs; + + DUK_ASSERT_API_ENTRY(thr); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + if (ent != NULL) { + while (ent->key != NULL) { + duk_push_c_function(thr, ent->value, ent->nargs); + duk_put_prop_string(thr, obj_idx, ent->key); + ent++; + } + } +} + +DUK_EXTERNAL void duk_put_number_list(duk_hthread *thr, duk_idx_t obj_idx, const duk_number_list_entry *numbers) { + const duk_number_list_entry *ent = numbers; + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + obj_idx = duk_require_normalize_index(thr, obj_idx); + if (ent != NULL) { + while (ent->key != NULL) { + tv = thr->valstack_top++; + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv)); /* value stack init policy */ + DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv, ent->value); /* no need for decref/incref */ + duk_put_prop_string(thr, obj_idx, ent->key); + ent++; + } + } +} + +/* + * Shortcut for accessing global object properties + */ + +DUK_EXTERNAL duk_bool_t duk_get_global_string(duk_hthread *thr, const char *key) { + duk_bool_t ret; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL); + + /* XXX: direct implementation */ + + duk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]); + ret = duk_get_prop_string(thr, -1, key); + duk_remove_m2(thr); + return ret; +} + +DUK_EXTERNAL duk_bool_t duk_get_global_lstring(duk_hthread *thr, const char *key, duk_size_t key_len) { + duk_bool_t ret; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL); + + /* XXX: direct implementation */ + + duk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]); + ret = duk_get_prop_lstring(thr, -1, key, key_len); + duk_remove_m2(thr); + return ret; +} + +#if !defined(DUK_USE_PREFER_SIZE) +DUK_EXTERNAL duk_bool_t duk_get_global_literal_raw(duk_hthread *thr, const char *key, duk_size_t key_len) { + duk_bool_t ret; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL); + DUK_ASSERT(key[key_len] == (char) 0); + + /* XXX: direct implementation */ + + duk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]); + ret = duk_get_prop_literal_raw(thr, -1, key, key_len); + duk_remove_m2(thr); + return ret; +} +#endif + +DUK_EXTERNAL duk_bool_t duk_get_global_heapptr(duk_hthread *thr, void *ptr) { + duk_bool_t ret; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL); + + /* XXX: direct implementation */ + + duk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]); + ret = duk_get_prop_heapptr(thr, -1, ptr); + duk_remove_m2(thr); + return ret; +} + + +DUK_EXTERNAL duk_bool_t duk_put_global_string(duk_hthread *thr, const char *key) { + duk_bool_t ret; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL); + + /* XXX: direct implementation */ + + duk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]); + duk_insert(thr, -2); + ret = duk_put_prop_string(thr, -2, key); /* [ ... global val ] -> [ ... global ] */ + duk_pop(thr); + return ret; +} + +DUK_EXTERNAL duk_bool_t duk_put_global_lstring(duk_hthread *thr, const char *key, duk_size_t key_len) { + duk_bool_t ret; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL); + + /* XXX: direct implementation */ + + duk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]); + duk_insert(thr, -2); + ret = duk_put_prop_lstring(thr, -2, key, key_len); /* [ ... global val ] -> [ ... global ] */ + duk_pop(thr); + return ret; +} + +#if !defined(DUK_USE_PREFER_SIZE) +DUK_EXTERNAL duk_bool_t duk_put_global_literal_raw(duk_hthread *thr, const char *key, duk_size_t key_len) { + duk_bool_t ret; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL); + DUK_ASSERT(key[key_len] == (char) 0); + + /* XXX: direct implementation */ + + duk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]); + duk_insert(thr, -2); + ret = duk_put_prop_literal_raw(thr, -2, key, key_len); /* [ ... global val ] -> [ ... global ] */ + duk_pop(thr); + return ret; +} +#endif + +DUK_EXTERNAL duk_bool_t duk_put_global_heapptr(duk_hthread *thr, void *ptr) { + duk_bool_t ret; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL); + + /* XXX: direct implementation */ + + duk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]); + duk_insert(thr, -2); + ret = duk_put_prop_heapptr(thr, -2, ptr); /* [ ... global val ] -> [ ... global ] */ + duk_pop(thr); + return ret; +} + +/* + * ES2015 GetMethod() + */ + +DUK_INTERNAL duk_bool_t duk_get_method_stridx(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t stridx) { + (void) duk_get_prop_stridx(thr, idx, stridx); + if (duk_is_null_or_undefined(thr, -1)) { + duk_pop_nodecref_unsafe(thr); + return 0; + } + if (!duk_is_callable(thr, -1)) { + DUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE); + DUK_WO_NORETURN(return 0;); + } + return 1; +} + +/* + * Object prototype + */ + +DUK_EXTERNAL void duk_get_prototype(duk_hthread *thr, duk_idx_t idx) { + duk_hobject *obj; + duk_hobject *proto; + + DUK_ASSERT_API_ENTRY(thr); + + obj = duk_require_hobject(thr, idx); + DUK_ASSERT(obj != NULL); + + /* XXX: shared helper for duk_push_hobject_or_undefined()? */ + proto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, obj); + if (proto) { + duk_push_hobject(thr, proto); + } else { + duk_push_undefined(thr); + } +} + +DUK_EXTERNAL void duk_set_prototype(duk_hthread *thr, duk_idx_t idx) { + duk_hobject *obj; + duk_hobject *proto; + + DUK_ASSERT_API_ENTRY(thr); + + obj = duk_require_hobject(thr, idx); + DUK_ASSERT(obj != NULL); + duk_require_type_mask(thr, -1, DUK_TYPE_MASK_UNDEFINED | + DUK_TYPE_MASK_OBJECT); + proto = duk_get_hobject(thr, -1); + /* proto can also be NULL here (allowed explicitly) */ + +#if defined(DUK_USE_ROM_OBJECTS) + if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) { + DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE); /* XXX: "read only object"? */ + DUK_WO_NORETURN(return;); + } +#endif + + DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, obj, proto); + + duk_pop(thr); +} + +DUK_INTERNAL void duk_clear_prototype(duk_hthread *thr, duk_idx_t idx) { + duk_hobject *obj; + + DUK_ASSERT_API_ENTRY(thr); + + obj = duk_require_hobject(thr, idx); + DUK_ASSERT(obj != NULL); + +#if defined(DUK_USE_ROM_OBJECTS) + if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) { + DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE); /* XXX: "read only object"? */ + DUK_WO_NORETURN(return;); + } +#endif + + DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, obj, NULL); +} + +DUK_INTERNAL duk_bool_t duk_is_bare_object(duk_hthread *thr, duk_idx_t idx) { + duk_hobject *obj; + duk_hobject *proto; + + DUK_ASSERT_API_ENTRY(thr); + + obj = duk_require_hobject(thr, idx); + DUK_ASSERT(obj != NULL); + + proto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, obj); + return (proto == NULL); +} + +/* + * Object finalizer + */ + +#if defined(DUK_USE_FINALIZER_SUPPORT) +/* XXX: these could be implemented as macros calling an internal function + * directly. + * XXX: same issue as with Duktape.fin: there's no way to delete the property + * now (just set it to undefined). + */ +DUK_EXTERNAL void duk_get_finalizer(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + + /* This get intentionally walks the inheritance chain at present, + * which matches how the effective finalizer property is also + * looked up in GC. + */ + duk_get_prop_stridx(thr, idx, DUK_STRIDX_INT_FINALIZER); +} + +DUK_EXTERNAL void duk_set_finalizer(duk_hthread *thr, duk_idx_t idx) { + duk_hobject *h; + duk_bool_t callable; + + DUK_ASSERT_API_ENTRY(thr); + + h = duk_require_hobject(thr, idx); /* Get before 'put' so that 'idx' is correct. */ + callable = duk_is_callable(thr, -1); + + /* At present finalizer is stored as a hidden Symbol, with normal + * inheritance and access control. As a result, finalizer cannot + * currently be set on a non-extensible (sealed or frozen) object. + * It might be useful to allow it. + */ + duk_put_prop_stridx(thr, idx, DUK_STRIDX_INT_FINALIZER); + + /* In addition to setting the finalizer property, keep a "have + * finalizer" flag in duk_hobject in sync so that refzero can do + * a very quick finalizer check by walking the prototype chain + * and checking the flag alone. (Note that this means that just + * setting _Finalizer on an object won't affect finalizer checks.) + * + * NOTE: if the argument is a Proxy object, this flag will be set + * on the Proxy, not the target. As a result, the target won't get + * a finalizer flag and the Proxy also won't be finalized as there's + * an explicit Proxy check in finalization now. + */ + if (callable) { + DUK_HOBJECT_SET_HAVE_FINALIZER(h); + } else { + DUK_HOBJECT_CLEAR_HAVE_FINALIZER(h); + } +} +#else /* DUK_USE_FINALIZER_SUPPORT */ +DUK_EXTERNAL void duk_get_finalizer(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_UNREF(idx); + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return;); +} + +DUK_EXTERNAL void duk_set_finalizer(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_UNREF(idx); + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return;); +} +#endif /* DUK_USE_FINALIZER_SUPPORT */ diff --git a/third_party/duktape/duk_api_random.c b/third_party/duktape/duk_api_random.c new file mode 100644 index 00000000..3b541cf1 --- /dev/null +++ b/third_party/duktape/duk_api_random.c @@ -0,0 +1,9 @@ +/* + * Random numbers + */ + +#include "third_party/duktape/duk_internal.h" + +DUK_EXTERNAL duk_double_t duk_random(duk_hthread *thr) { + return (duk_double_t) DUK_UTIL_GET_RANDOM_DOUBLE(thr); +} diff --git a/third_party/duktape/duk_api_stack.c b/third_party/duktape/duk_api_stack.c new file mode 100644 index 00000000..562d2bf8 --- /dev/null +++ b/third_party/duktape/duk_api_stack.c @@ -0,0 +1,6822 @@ +/* + * API calls related to general value stack manipulation: resizing the value + * stack, pushing and popping values, type checking and reading values, + * coercing values, etc. + * + * Also contains internal functions (such as duk_get_tval()), defined + * in duk_api_internal.h, with semantics similar to the public API. + */ + +/* XXX: repetition of stack pre-checks -> helper or macro or inline */ +/* XXX: shared api error strings, and perhaps even throw code for rare cases? */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Forward declarations + */ + +DUK_LOCAL_DECL duk_idx_t duk__push_c_function_raw(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_uint_t flags, duk_small_uint_t proto_bidx); + +/* + * Global state for working around missing variadic macros + */ + +#if !defined(DUK_USE_VARIADIC_MACROS) +DUK_EXTERNAL const char *duk_api_global_filename = NULL; +DUK_EXTERNAL duk_int_t duk_api_global_line = 0; +#endif + +/* + * Misc helpers + */ + +DUK_LOCAL const char * const duk__symbol_type_strings[4] = { + "hidden", "global", "local", "wellknown" +}; + +#if !defined(DUK_USE_PACKED_TVAL) +DUK_LOCAL const duk_uint_t duk__type_from_tag[] = { + DUK_TYPE_NUMBER, + DUK_TYPE_NUMBER, /* fastint */ + DUK_TYPE_UNDEFINED, + DUK_TYPE_NULL, + DUK_TYPE_BOOLEAN, + DUK_TYPE_POINTER, + DUK_TYPE_LIGHTFUNC, + DUK_TYPE_NONE, + DUK_TYPE_STRING, + DUK_TYPE_OBJECT, + DUK_TYPE_BUFFER, +}; +DUK_LOCAL const duk_uint_t duk__type_mask_from_tag[] = { + DUK_TYPE_MASK_NUMBER, + DUK_TYPE_MASK_NUMBER, /* fastint */ + DUK_TYPE_MASK_UNDEFINED, + DUK_TYPE_MASK_NULL, + DUK_TYPE_MASK_BOOLEAN, + DUK_TYPE_MASK_POINTER, + DUK_TYPE_MASK_LIGHTFUNC, + DUK_TYPE_MASK_NONE, + DUK_TYPE_MASK_STRING, + DUK_TYPE_MASK_OBJECT, + DUK_TYPE_MASK_BUFFER, +}; +#endif /* !DUK_USE_PACKED_TVAL */ + +/* Assert that there's room for one value. */ +#define DUK__ASSERT_SPACE() do { \ + DUK_ASSERT(!(thr->valstack_top >= thr->valstack_end)); \ + } while (0) + +/* Check that there's room to push one value. */ +#if defined(DUK_USE_VALSTACK_UNSAFE) +/* Faster but value stack overruns are memory unsafe. */ +#define DUK__CHECK_SPACE() DUK__ASSERT_SPACE() +#else +#define DUK__CHECK_SPACE() do { \ + if (DUK_UNLIKELY(thr->valstack_top >= thr->valstack_end)) { \ + DUK_ERROR_RANGE_PUSH_BEYOND(thr); \ + } \ + } while (0) +#endif + +DUK_LOCAL duk_small_uint_t duk__get_symbol_type(duk_hstring *h) { + const duk_uint8_t *data; + duk_size_t len; + + DUK_ASSERT(h != NULL); + DUK_ASSERT(DUK_HSTRING_HAS_SYMBOL(h)); + DUK_ASSERT(DUK_HSTRING_GET_BYTELEN(h) >= 1); /* always true, symbol prefix */ + + data = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h); + len = DUK_HSTRING_GET_BYTELEN(h); + DUK_ASSERT(len >= 1); + + /* XXX: differentiate between 0x82 and 0xff (hidden vs. internal?)? */ + + if (data[0] == 0xffU) { + return DUK_SYMBOL_TYPE_HIDDEN; + } else if (data[0] == 0x82U) { + return DUK_SYMBOL_TYPE_HIDDEN; + } else if (data[0] == 0x80U) { + return DUK_SYMBOL_TYPE_GLOBAL; + } else if (data[len - 1] != 0xffU) { + return DUK_SYMBOL_TYPE_LOCAL; + } else { + return DUK_SYMBOL_TYPE_WELLKNOWN; + } +} + +DUK_LOCAL const char *duk__get_symbol_type_string(duk_hstring *h) { + duk_small_uint_t idx; + idx = duk__get_symbol_type(h); + DUK_ASSERT(idx < sizeof(duk__symbol_type_strings)); + return duk__symbol_type_strings[idx]; +} + +DUK_LOCAL_DECL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t tag); + +DUK_LOCAL duk_int_t duk__api_coerce_d2i(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value, duk_bool_t require) { + duk_tval *tv; + duk_small_int_t c; + duk_double_t d; + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + + /* + * Special cases like NaN and +/- Infinity are handled explicitly + * because a plain C coercion from double to int handles these cases + * in undesirable ways. For instance, NaN may coerce to INT_MIN + * (not zero), and INT_MAX + 1 may coerce to INT_MIN (not INT_MAX). + * + * This double-to-int coercion differs from ToInteger() because it + * has a finite range (ToInteger() allows e.g. +/- Infinity). It + * also differs from ToInt32() because the INT_MIN/INT_MAX clamping + * depends on the size of the int type on the platform. In particular, + * on platforms with a 64-bit int type, the full range is allowed. + */ + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv)) { + duk_int64_t t = DUK_TVAL_GET_FASTINT(tv); +#if (DUK_INT_MAX <= 0x7fffffffL) + /* Clamping only necessary for 32-bit ints. */ + if (t < DUK_INT_MIN) { + t = DUK_INT_MIN; + } else if (t > DUK_INT_MAX) { + t = DUK_INT_MAX; + } +#endif + return (duk_int_t) t; + } +#endif + + if (DUK_TVAL_IS_NUMBER(tv)) { + d = DUK_TVAL_GET_NUMBER(tv); + c = (duk_small_int_t) DUK_FPCLASSIFY(d); + if (c == DUK_FP_NAN) { + return 0; + } else if (d < (duk_double_t) DUK_INT_MIN) { + /* covers -Infinity */ + return DUK_INT_MIN; + } else if (d > (duk_double_t) DUK_INT_MAX) { + /* covers +Infinity */ + return DUK_INT_MAX; + } else { + /* coerce towards zero */ + return (duk_int_t) d; + } + } + + if (require) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "number", DUK_STR_NOT_NUMBER); + DUK_WO_NORETURN(return 0;); + } + + return def_value; +} + +DUK_LOCAL duk_uint_t duk__api_coerce_d2ui(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value, duk_bool_t require) { + duk_tval *tv; + duk_small_int_t c; + duk_double_t d; + + /* Same as above but for unsigned int range. */ + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv)) { + duk_int64_t t = DUK_TVAL_GET_FASTINT(tv); + if (t < 0) { + t = 0; + } +#if (DUK_UINT_MAX <= 0xffffffffUL) + /* Clamping only necessary for 32-bit ints. */ + else if (t > DUK_UINT_MAX) { + t = DUK_UINT_MAX; + } +#endif + return (duk_uint_t) t; + } +#endif + + if (DUK_TVAL_IS_NUMBER(tv)) { + d = DUK_TVAL_GET_NUMBER(tv); + c = (duk_small_int_t) DUK_FPCLASSIFY(d); + if (c == DUK_FP_NAN) { + return 0; + } else if (d < 0.0) { + /* covers -Infinity */ + return (duk_uint_t) 0; + } else if (d > (duk_double_t) DUK_UINT_MAX) { + /* covers +Infinity */ + return (duk_uint_t) DUK_UINT_MAX; + } else { + /* coerce towards zero */ + return (duk_uint_t) d; + } + } + + if (require) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "number", DUK_STR_NOT_NUMBER); + DUK_WO_NORETURN(return 0;); + } + + return def_value; +} + +/* + * Stack index validation/normalization and getting a stack duk_tval ptr. + * + * These are called by many API entrypoints so the implementations must be + * fast and "inlined". + * + * There's some repetition because of this; keep the functions in sync. + */ + +DUK_EXTERNAL duk_idx_t duk_normalize_index(duk_hthread *thr, duk_idx_t idx) { + duk_uidx_t vs_size; + duk_uidx_t uidx; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(DUK_INVALID_INDEX < 0); + + /* Care must be taken to avoid pointer wrapping in the index + * validation. For instance, on a 32-bit platform with 8-byte + * duk_tval the index 0x20000000UL would wrap the memory space + * once. + */ + + /* Assume value stack sizes (in elements) fits into duk_idx_t. */ + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + vs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom); + DUK_ASSERT_DISABLE(vs_size >= 0); /* unsigned */ + + if (idx < 0) { + uidx = vs_size + (duk_uidx_t) idx; + } else { + /* since index non-negative */ + DUK_ASSERT(idx != DUK_INVALID_INDEX); + uidx = (duk_uidx_t) idx; + } + + /* DUK_INVALID_INDEX won't be accepted as a valid index. */ + DUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size); + + if (DUK_LIKELY(uidx < vs_size)) { + return (duk_idx_t) uidx; + } + return DUK_INVALID_INDEX; +} + +DUK_EXTERNAL duk_idx_t duk_require_normalize_index(duk_hthread *thr, duk_idx_t idx) { + duk_uidx_t vs_size; + duk_uidx_t uidx; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(DUK_INVALID_INDEX < 0); + + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + vs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom); + DUK_ASSERT_DISABLE(vs_size >= 0); /* unsigned */ + + if (idx < 0) { + uidx = vs_size + (duk_uidx_t) idx; + } else { + DUK_ASSERT(idx != DUK_INVALID_INDEX); + uidx = (duk_uidx_t) idx; + } + + /* DUK_INVALID_INDEX won't be accepted as a valid index. */ + DUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size); + + if (DUK_LIKELY(uidx < vs_size)) { + return (duk_idx_t) uidx; + } + DUK_ERROR_RANGE_INDEX(thr, idx); + DUK_WO_NORETURN(return 0;); +} + +DUK_INTERNAL duk_tval *duk_get_tval(duk_hthread *thr, duk_idx_t idx) { + duk_uidx_t vs_size; + duk_uidx_t uidx; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(DUK_INVALID_INDEX < 0); + + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + vs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom); + DUK_ASSERT_DISABLE(vs_size >= 0); /* unsigned */ + + if (idx < 0) { + uidx = vs_size + (duk_uidx_t) idx; + } else { + DUK_ASSERT(idx != DUK_INVALID_INDEX); + uidx = (duk_uidx_t) idx; + } + + /* DUK_INVALID_INDEX won't be accepted as a valid index. */ + DUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size); + + if (DUK_LIKELY(uidx < vs_size)) { + return thr->valstack_bottom + uidx; + } + return NULL; +} + +/* Variant of duk_get_tval() which is guaranteed to return a valid duk_tval + * pointer. When duk_get_tval() would return NULL, this variant returns a + * pointer to a duk_tval with tag DUK_TAG_UNUSED. This allows the call site + * to avoid an unnecessary NULL check which sometimes leads to better code. + * The return duk_tval is read only (at least for the UNUSED value). + */ +DUK_LOCAL const duk_tval_unused duk__const_tval_unused = DUK_TVAL_UNUSED_INITIALIZER(); + +DUK_INTERNAL duk_tval *duk_get_tval_or_unused(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval(thr, idx); + if (tv != NULL) { + return tv; + } + return (duk_tval *) DUK_LOSE_CONST(&duk__const_tval_unused); +} + +DUK_INTERNAL duk_tval *duk_require_tval(duk_hthread *thr, duk_idx_t idx) { + duk_uidx_t vs_size; + duk_uidx_t uidx; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(DUK_INVALID_INDEX < 0); + + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + vs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom); + DUK_ASSERT_DISABLE(vs_size >= 0); /* unsigned */ + + /* Use unsigned arithmetic to optimize comparison. */ + if (idx < 0) { + uidx = vs_size + (duk_uidx_t) idx; + } else { + DUK_ASSERT(idx != DUK_INVALID_INDEX); + uidx = (duk_uidx_t) idx; + } + + /* DUK_INVALID_INDEX won't be accepted as a valid index. */ + DUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size); + + if (DUK_LIKELY(uidx < vs_size)) { + return thr->valstack_bottom + uidx; + } + DUK_ERROR_RANGE_INDEX(thr, idx); + DUK_WO_NORETURN(return NULL;); +} + +/* Non-critical. */ +DUK_EXTERNAL duk_bool_t duk_is_valid_index(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(DUK_INVALID_INDEX < 0); + + return (duk_normalize_index(thr, idx) >= 0); +} + +/* Non-critical. */ +DUK_EXTERNAL void duk_require_valid_index(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(DUK_INVALID_INDEX < 0); + + if (DUK_UNLIKELY(duk_normalize_index(thr, idx) < 0)) { + DUK_ERROR_RANGE_INDEX(thr, idx); + DUK_WO_NORETURN(return;); + } +} + +/* + * Value stack top handling + */ + +DUK_EXTERNAL duk_idx_t duk_get_top(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + + return (duk_idx_t) (thr->valstack_top - thr->valstack_bottom); +} + +/* Internal helper to get current top but to require a minimum top value + * (TypeError if not met). + */ +DUK_INTERNAL duk_idx_t duk_get_top_require_min(duk_hthread *thr, duk_idx_t min_top) { + duk_idx_t ret; + + DUK_ASSERT_API_ENTRY(thr); + + ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom); + if (DUK_UNLIKELY(ret < min_top)) { + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return 0;); + } + return ret; +} + +/* Set stack top within currently allocated range, but don't reallocate. + * This is performance critical especially for call handling, so whenever + * changing, profile and look at generated code. + */ +DUK_EXTERNAL void duk_set_top(duk_hthread *thr, duk_idx_t idx) { + duk_uidx_t vs_size; + duk_uidx_t vs_limit; + duk_uidx_t uidx; + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(DUK_INVALID_INDEX < 0); + + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + DUK_ASSERT(thr->valstack_end >= thr->valstack_bottom); + vs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom); + vs_limit = (duk_uidx_t) (thr->valstack_end - thr->valstack_bottom); + + if (idx < 0) { + /* Negative indices are always within allocated stack but + * must not go below zero index. + */ + uidx = vs_size + (duk_uidx_t) idx; + } else { + /* Positive index can be higher than valstack top but must + * not go above allocated stack (equality is OK). + */ + uidx = (duk_uidx_t) idx; + } + + /* DUK_INVALID_INDEX won't be accepted as a valid index. */ + DUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size); + DUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_limit); + +#if defined(DUK_USE_VALSTACK_UNSAFE) + DUK_ASSERT(uidx <= vs_limit); + DUK_UNREF(vs_limit); +#else + if (DUK_UNLIKELY(uidx > vs_limit)) { + DUK_ERROR_RANGE_INDEX(thr, idx); + DUK_WO_NORETURN(return;); + } +#endif + DUK_ASSERT(uidx <= vs_limit); + + /* Handle change in value stack top. Respect value stack + * initialization policy: 'undefined' above top. Note that + * DECREF may cause a side effect that reallocates valstack, + * so must relookup after DECREF. + */ + + if (uidx >= vs_size) { + /* Stack size increases or stays the same. */ +#if defined(DUK_USE_ASSERTIONS) + duk_uidx_t count; + + count = uidx - vs_size; + while (count != 0) { + count--; + tv = thr->valstack_top + count; + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv)); + } +#endif + thr->valstack_top = thr->valstack_bottom + uidx; + } else { + /* Stack size decreases. */ +#if defined(DUK_USE_REFERENCE_COUNTING) + duk_uidx_t count; + duk_tval *tv_end; + + count = vs_size - uidx; + DUK_ASSERT(count > 0); + tv = thr->valstack_top; + tv_end = tv - count; + DUK_ASSERT(tv > tv_end); /* Because count > 0. */ + do { + tv--; + DUK_ASSERT(tv >= thr->valstack_bottom); + DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv); + } while (tv != tv_end); + thr->valstack_top = tv_end; + DUK_REFZERO_CHECK_FAST(thr); +#else /* DUK_USE_REFERENCE_COUNTING */ + duk_uidx_t count; + duk_tval *tv_end; + + count = vs_size - uidx; + tv = thr->valstack_top; + tv_end = tv - count; + DUK_ASSERT(tv > tv_end); + do { + tv--; + DUK_TVAL_SET_UNDEFINED(tv); + } while (tv != tv_end); + thr->valstack_top = tv_end; +#endif /* DUK_USE_REFERENCE_COUNTING */ + } +} + +/* Internal variant with a non-negative index and no runtime size checks. */ +#if defined(DUK_USE_PREFER_SIZE) +DUK_INTERNAL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + + duk_set_top(thr, idx); +} +#else /* DUK_USE_PREFER_SIZE */ +DUK_INTERNAL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx) { + duk_uidx_t uidx; + duk_uidx_t vs_size; + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + DUK_ASSERT(thr->valstack_end >= thr->valstack_bottom); + DUK_ASSERT(idx >= 0); + DUK_ASSERT(idx <= (duk_idx_t) (thr->valstack_end - thr->valstack_bottom)); + + /* XXX: byte arithmetic */ + uidx = (duk_uidx_t) idx; + vs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom); + + if (uidx >= vs_size) { + /* Stack size increases or stays the same. */ +#if defined(DUK_USE_ASSERTIONS) + duk_uidx_t count; + + count = uidx - vs_size; + while (count != 0) { + count--; + tv = thr->valstack_top + count; + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv)); + } +#endif + thr->valstack_top = thr->valstack_bottom + uidx; + } else { + /* Stack size decreases. */ +#if defined(DUK_USE_REFERENCE_COUNTING) + duk_uidx_t count; + duk_tval *tv_end; + + count = vs_size - uidx; + DUK_ASSERT(count > 0); + tv = thr->valstack_top; + tv_end = tv - count; + DUK_ASSERT(tv > tv_end); /* Because count > 0. */ + do { + tv--; + DUK_ASSERT(tv >= thr->valstack_bottom); + DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv); + } while (tv != tv_end); + thr->valstack_top = tv_end; + DUK_REFZERO_CHECK_FAST(thr); +#else /* DUK_USE_REFERENCE_COUNTING */ + duk_uidx_t count; + duk_tval *tv_end; + + count = vs_size - uidx; + tv = thr->valstack_top; + tv_end = tv - count; + DUK_ASSERT(tv > tv_end); + do { + tv--; + DUK_TVAL_SET_UNDEFINED(tv); + } while (tv != tv_end); + thr->valstack_top = tv_end; +#endif /* DUK_USE_REFERENCE_COUNTING */ + } +} +#endif /* DUK_USE_PREFER_SIZE */ + +/* Internal helper: set top to 'top', and set [idx_wipe_start,top[ to + * 'undefined' (doing nothing if idx_wipe_start == top). Indices are + * positive and within value stack reserve. This is used by call handling. + */ +DUK_INTERNAL void duk_set_top_and_wipe(duk_hthread *thr, duk_idx_t top, duk_idx_t idx_wipe_start) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(top >= 0); + DUK_ASSERT(idx_wipe_start >= 0); + DUK_ASSERT(idx_wipe_start <= top); + DUK_ASSERT(thr->valstack_bottom + top <= thr->valstack_end); + DUK_ASSERT(thr->valstack_bottom + idx_wipe_start <= thr->valstack_end); + + duk_set_top_unsafe(thr, idx_wipe_start); + duk_set_top_unsafe(thr, top); +} + +DUK_EXTERNAL duk_idx_t duk_get_top_index(duk_hthread *thr) { + duk_idx_t ret; + + DUK_ASSERT_API_ENTRY(thr); + + ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1; + if (DUK_UNLIKELY(ret < 0)) { + /* Return invalid index; if caller uses this without checking + * in another API call, the index won't map to a valid stack + * entry. + */ + return DUK_INVALID_INDEX; + } + return ret; +} + +/* Internal variant: call assumes there is at least one element on the value + * stack frame; this is only asserted for. + */ +DUK_INTERNAL duk_idx_t duk_get_top_index_unsafe(duk_hthread *thr) { + duk_idx_t ret; + + DUK_ASSERT_API_ENTRY(thr); + + ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1; + return ret; +} + +DUK_EXTERNAL duk_idx_t duk_require_top_index(duk_hthread *thr) { + duk_idx_t ret; + + DUK_ASSERT_API_ENTRY(thr); + + ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1; + if (DUK_UNLIKELY(ret < 0)) { + DUK_ERROR_RANGE_INDEX(thr, -1); + DUK_WO_NORETURN(return 0;); + } + return ret; +} + +/* + * Value stack resizing. + * + * This resizing happens above the current "top": the value stack can be + * grown or shrunk, but the "top" is not affected. The value stack cannot + * be resized to a size below the current reserve. + * + * The low level reallocation primitive must carefully recompute all value + * stack pointers, and must also work if ALL pointers are NULL. The resize + * is quite tricky because the valstack realloc may cause a mark-and-sweep, + * which may run finalizers. Running finalizers may resize the valstack + * recursively (the same value stack we're working on). So, after realloc + * returns, we know that the valstack bottom, top, and reserve should still + * be the same (there should not be live values above the "top"), but its + * underlying size, alloc_end, and base pointer may have changed. + * + * 'new_size' is known to be <= DUK_USE_VALSTACK_LIMIT, which ensures that + * size_t and pointer arithmetic won't wrap in duk__resize_valstack(). + */ + +/* Low level valstack resize primitive, used for both grow and shrink. All + * adjustments for slack etc have already been done. Doesn't throw but does + * have allocation side effects. + */ +DUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__resize_valstack(duk_hthread *thr, duk_size_t new_size) { + duk_tval *pre_valstack; + duk_tval *pre_bottom; + duk_tval *pre_top; + duk_tval *pre_end; + duk_tval *pre_alloc_end; + duk_ptrdiff_t ptr_diff; + duk_tval *new_valstack; + duk_size_t new_alloc_size; + duk_tval *tv_prev_alloc_end; + duk_tval *p; + + DUK_HTHREAD_ASSERT_VALID(thr); + DUK_ASSERT(thr->valstack_bottom >= thr->valstack); + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + DUK_ASSERT(thr->valstack_end >= thr->valstack_top); + DUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end); + DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack) <= new_size); /* can't resize below 'top' */ + DUK_ASSERT(new_size <= DUK_USE_VALSTACK_LIMIT); /* valstack limit caller has check, prevents wrapping */ + DUK_ASSERT(new_size <= DUK_SIZE_MAX / sizeof(duk_tval)); /* specific assert for wrapping */ + + /* Pre-realloc pointer copies for asserts and debug logs. */ + pre_valstack = thr->valstack; + pre_bottom = thr->valstack_bottom; + pre_top = thr->valstack_top; + pre_end = thr->valstack_end; + pre_alloc_end = thr->valstack_alloc_end; + + DUK_UNREF(pre_valstack); + DUK_UNREF(pre_bottom); + DUK_UNREF(pre_top); + DUK_UNREF(pre_end); + DUK_UNREF(pre_alloc_end); + + /* If finalizer torture enabled, force base pointer change every time + * when it would be allowed. + */ +#if defined(DUK_USE_FINALIZER_TORTURE) + if (thr->heap->pf_prevent_count == 0) { + duk_hthread_valstack_torture_realloc(thr); + } +#endif + + /* Allocate a new valstack using DUK_REALLOC_DIRECT() to deal with + * a side effect changing the base pointer. + */ + new_alloc_size = sizeof(duk_tval) * new_size; + new_valstack = (duk_tval *) DUK_REALLOC_INDIRECT(thr->heap, duk_hthread_get_valstack_ptr, (void *) thr, new_alloc_size); + if (DUK_UNLIKELY(new_valstack == NULL)) { + /* Because new_size != 0, if condition doesn't need to be + * (new_valstack != NULL || new_size == 0). + */ + DUK_ASSERT(new_size != 0); + DUK_D(DUK_DPRINT("failed to resize valstack to %lu entries (%lu bytes)", + (unsigned long) new_size, (unsigned long) new_alloc_size)); + return 0; + } + + /* Debug log any changes in pointer(s) by side effects. These don't + * necessarily imply any incorrect behavior, but should be rare in + * practice. + */ +#if defined(DUK_USE_DEBUG) + if (thr->valstack != pre_valstack) { + DUK_D(DUK_DPRINT("valstack base pointer changed during valstack resize: %p -> %p", + (void *) pre_valstack, (void *) thr->valstack)); + } + if (thr->valstack_bottom != pre_bottom) { + DUK_D(DUK_DPRINT("valstack bottom pointer changed during valstack resize: %p -> %p", + (void *) pre_bottom, (void *) thr->valstack_bottom)); + } + if (thr->valstack_top != pre_top) { + DUK_D(DUK_DPRINT("valstack top pointer changed during valstack resize: %p -> %p", + (void *) pre_top, (void *) thr->valstack_top)); + } + if (thr->valstack_end != pre_end) { + DUK_D(DUK_DPRINT("valstack end pointer changed during valstack resize: %p -> %p", + (void *) pre_end, (void *) thr->valstack_end)); + } + if (thr->valstack_alloc_end != pre_alloc_end) { + DUK_D(DUK_DPRINT("valstack alloc_end pointer changed during valstack resize: %p -> %p", + (void *) pre_alloc_end, (void *) thr->valstack_alloc_end)); + } +#endif + + /* Assertions: offsets for bottom, top, and end (reserve) must not + * have changed even with side effects because they are always + * restored in unwind. For alloc_end there's no guarantee: it may + * have grown or shrunk (but remain above 'end'). + */ + DUK_ASSERT(thr->valstack_bottom - thr->valstack == pre_bottom - pre_valstack); + DUK_ASSERT(thr->valstack_top - thr->valstack == pre_top - pre_valstack); + DUK_ASSERT(thr->valstack_end - thr->valstack == pre_end - pre_valstack); + DUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end); + + /* Write new pointers. Most pointers can be handled as a pointer + * difference. + */ + ptr_diff = (duk_ptrdiff_t) ((duk_uint8_t *) new_valstack - (duk_uint8_t *) thr->valstack); + tv_prev_alloc_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_alloc_end + ptr_diff); + thr->valstack = new_valstack; + thr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + ptr_diff); + thr->valstack_top = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_top + ptr_diff); + thr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_end + ptr_diff); + thr->valstack_alloc_end = (duk_tval *) (void *) ((duk_uint8_t *) new_valstack + new_alloc_size); + + /* Assertions: pointer sanity after pointer updates. */ + DUK_ASSERT(thr->valstack_bottom >= thr->valstack); + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + DUK_ASSERT(thr->valstack_end >= thr->valstack_top); + DUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end); + + DUK_D(DUK_DPRINT("resized valstack %lu -> %lu elements (%lu -> %lu bytes): " + "base=%p -> %p, bottom=%p -> %p (%ld), top=%p -> %p (%ld), " + "end=%p -> %p (%ld), alloc_end=%p -> %p (%ld);" + " tv_prev_alloc_end=%p (-> %ld inits; <0 means shrink)", + (unsigned long) (pre_alloc_end - pre_valstack), + (unsigned long) new_size, + (unsigned long) ((duk_uint8_t *) pre_alloc_end - (duk_uint8_t *) pre_valstack), + (unsigned long) new_alloc_size, + (void *) pre_valstack, (void *) thr->valstack, + (void *) pre_bottom, (void *) thr->valstack_bottom, (long) (thr->valstack_bottom - thr->valstack), + (void *) pre_top, (void *) thr->valstack_top, (long) (thr->valstack_top - thr->valstack), + (void *) pre_end, (void *) thr->valstack_end, (long) (thr->valstack_end - thr->valstack), + (void *) pre_alloc_end, (void *) thr->valstack_alloc_end, (long) (thr->valstack_alloc_end - thr->valstack), + (void *) tv_prev_alloc_end, (long) (thr->valstack_alloc_end - tv_prev_alloc_end))); + + /* If allocation grew, init any new slots to 'undefined'. */ + p = tv_prev_alloc_end; + while (p < thr->valstack_alloc_end) { + /* Never executed if new size is smaller. */ + DUK_TVAL_SET_UNDEFINED(p); + p++; + } + + /* Assert for value stack initialization policy. */ +#if defined(DUK_USE_ASSERTIONS) + p = thr->valstack_top; + while (p < thr->valstack_alloc_end) { + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(p)); + p++; + } +#endif + + return 1; +} + +DUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__valstack_grow(duk_hthread *thr, duk_size_t min_bytes, duk_bool_t throw_on_error) { + duk_size_t min_size; + duk_size_t new_size; + + DUK_ASSERT(min_bytes / sizeof(duk_tval) * sizeof(duk_tval) == min_bytes); + min_size = min_bytes / sizeof(duk_tval); /* from bytes to slots */ + +#if defined(DUK_USE_VALSTACK_GROW_SHIFT) + /* New size is minimum size plus a proportional slack, e.g. shift of + * 2 means a 25% slack. + */ + new_size = min_size + (min_size >> DUK_USE_VALSTACK_GROW_SHIFT); +#else + /* New size is tight with no slack. This is sometimes preferred in + * low memory environments. + */ + new_size = min_size; +#endif + + if (DUK_UNLIKELY(new_size > DUK_USE_VALSTACK_LIMIT || new_size < min_size /*wrap*/)) { + /* Note: may be triggered even if minimal new_size would not reach the limit, + * plan limit accordingly. + */ + if (throw_on_error) { + DUK_ERROR_RANGE(thr, DUK_STR_VALSTACK_LIMIT); + DUK_WO_NORETURN(return 0;); + } + return 0; + } + + if (duk__resize_valstack(thr, new_size) == 0) { + if (throw_on_error) { + DUK_ERROR_ALLOC_FAILED(thr); + DUK_WO_NORETURN(return 0;); + } + return 0; + } + + thr->valstack_end = thr->valstack + min_size; + DUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end); + + return 1; +} + +/* Hot, inlined value stack grow check. Because value stack almost never + * grows, the actual resize call is in a NOINLINE helper. + */ +DUK_INTERNAL DUK_INLINE void duk_valstack_grow_check_throw(duk_hthread *thr, duk_size_t min_bytes) { + duk_tval *tv; + + tv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + min_bytes); + if (DUK_LIKELY(thr->valstack_end >= tv)) { + return; + } + if (DUK_LIKELY(thr->valstack_alloc_end >= tv)) { + /* Values in [valstack_top,valstack_alloc_end[ are initialized + * to 'undefined' so we can just move the end pointer. + */ + thr->valstack_end = tv; + return; + } + (void) duk__valstack_grow(thr, min_bytes, 1 /*throw_on_error*/); +} + +/* Hot, inlined value stack grow check which doesn't throw. */ +DUK_INTERNAL DUK_INLINE duk_bool_t duk_valstack_grow_check_nothrow(duk_hthread *thr, duk_size_t min_bytes) { + duk_tval *tv; + + tv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + min_bytes); + if (DUK_LIKELY(thr->valstack_end >= tv)) { + return 1; + } + if (DUK_LIKELY(thr->valstack_alloc_end >= tv)) { + thr->valstack_end = tv; + return 1; + } + return duk__valstack_grow(thr, min_bytes, 0 /*throw_on_error*/); +} + +/* Value stack shrink check, called from mark-and-sweep. */ +DUK_INTERNAL void duk_valstack_shrink_check_nothrow(duk_hthread *thr, duk_bool_t snug) { + duk_size_t alloc_bytes; + duk_size_t reserve_bytes; + duk_size_t shrink_bytes; + + alloc_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_alloc_end - (duk_uint8_t *) thr->valstack); + reserve_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack); + DUK_ASSERT(alloc_bytes >= reserve_bytes); + + /* We're free to shrink the value stack allocation down to + * reserve_bytes but not more. If 'snug' (emergency GC) + * shrink whatever we can. Otherwise only shrink if the new + * size would be considerably smaller. + */ + +#if defined(DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT) + if (snug) { + shrink_bytes = reserve_bytes; + } else { + duk_size_t proportion, slack; + + /* Require that value stack shrinks by at least X% of its + * current size. For example, shift of 2 means at least + * 25%. The proportion is computed as bytes and may not + * be a multiple of sizeof(duk_tval); that's OK here. + */ + proportion = alloc_bytes >> DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT; + if (alloc_bytes - reserve_bytes < proportion) { + /* Too little would be freed, do nothing. */ + return; + } + + /* Keep a slack after shrinking. The slack is again a + * proportion of the current size (the proportion should + * of course be smaller than the check proportion above). + */ +#if defined(DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT) + DUK_ASSERT(DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT > DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT); + slack = alloc_bytes >> DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT; +#else + slack = 0; +#endif + shrink_bytes = reserve_bytes + + slack / sizeof(duk_tval) * sizeof(duk_tval); /* multiple of duk_tval */ + } +#else /* DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT */ + /* Always snug, useful in some low memory environments. */ + DUK_UNREF(snug); + shrink_bytes = reserve_bytes; +#endif /* DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT */ + + DUK_D(DUK_DPRINT("valstack shrink check: alloc_bytes=%ld, reserve_bytes=%ld, shrink_bytes=%ld (unvalidated)", + (long) alloc_bytes, (long) reserve_bytes, (long) shrink_bytes)); + DUK_ASSERT(shrink_bytes >= reserve_bytes); + if (shrink_bytes >= alloc_bytes) { + /* Skip if shrink target is same as current one (or higher, + * though that shouldn't happen in practice). + */ + return; + } + DUK_ASSERT(shrink_bytes / sizeof(duk_tval) * sizeof(duk_tval) == shrink_bytes); + + DUK_D(DUK_DPRINT("valstack shrink check: decided to shrink, snug: %ld", (long) snug)); + + duk__resize_valstack(thr, shrink_bytes / sizeof(duk_tval)); +} + +DUK_EXTERNAL duk_bool_t duk_check_stack(duk_hthread *thr, duk_idx_t extra) { + duk_size_t min_new_bytes; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr != NULL); + + if (DUK_UNLIKELY(extra < 0 || extra > DUK_USE_VALSTACK_LIMIT)) { + if (extra < 0) { + /* Clamping to zero makes the API more robust to calling code + * calculation errors. + */ + extra = 0; + } else { + /* Cause grow check to fail without wrapping arithmetic. */ + extra = DUK_USE_VALSTACK_LIMIT; + } + } + + min_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack) + + sizeof(duk_tval) * ((duk_size_t) extra + DUK_VALSTACK_INTERNAL_EXTRA); + return duk_valstack_grow_check_nothrow(thr, min_new_bytes); +} + +DUK_EXTERNAL void duk_require_stack(duk_hthread *thr, duk_idx_t extra) { + duk_size_t min_new_bytes; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr != NULL); + + if (DUK_UNLIKELY(extra < 0 || extra > DUK_USE_VALSTACK_LIMIT)) { + if (extra < 0) { + /* Clamping to zero makes the API more robust to calling code + * calculation errors. + */ + extra = 0; + } else { + /* Cause grow check to fail without wrapping arithmetic. */ + extra = DUK_USE_VALSTACK_LIMIT; + } + } + + min_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack) + + sizeof(duk_tval) * ((duk_size_t) extra + DUK_VALSTACK_INTERNAL_EXTRA); + duk_valstack_grow_check_throw(thr, min_new_bytes); +} + +DUK_EXTERNAL duk_bool_t duk_check_stack_top(duk_hthread *thr, duk_idx_t top) { + duk_size_t min_new_bytes; + + DUK_ASSERT_API_ENTRY(thr); + + if (DUK_UNLIKELY(top < 0 || top > DUK_USE_VALSTACK_LIMIT)) { + if (top < 0) { + /* Clamping to zero makes the API more robust to calling code + * calculation errors. + */ + top = 0; + } else { + /* Cause grow check to fail without wrapping arithmetic. */ + top = DUK_USE_VALSTACK_LIMIT; + } + } + + DUK_ASSERT(top >= 0); + min_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) + + sizeof(duk_tval) * ((duk_size_t) top + DUK_VALSTACK_INTERNAL_EXTRA); + return duk_valstack_grow_check_nothrow(thr, min_new_bytes); +} + +DUK_EXTERNAL void duk_require_stack_top(duk_hthread *thr, duk_idx_t top) { + duk_size_t min_new_bytes; + + DUK_ASSERT_API_ENTRY(thr); + + if (DUK_UNLIKELY(top < 0 || top > DUK_USE_VALSTACK_LIMIT)) { + if (top < 0) { + /* Clamping to zero makes the API more robust to calling code + * calculation errors. + */ + top = 0; + } else { + /* Cause grow check to fail without wrapping arithmetic. */ + top = DUK_USE_VALSTACK_LIMIT; + } + } + + DUK_ASSERT(top >= 0); + min_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) + + sizeof(duk_tval) * ((duk_size_t) top + DUK_VALSTACK_INTERNAL_EXTRA); + duk_valstack_grow_check_throw(thr, min_new_bytes); +} + +/* + * Basic stack manipulation: swap, dup, insert, replace, etc + */ + +DUK_EXTERNAL void duk_swap(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) { + duk_tval *tv1; + duk_tval *tv2; + duk_tval tv_tmp; + + DUK_ASSERT_API_ENTRY(thr); + + tv1 = duk_require_tval(thr, idx1); + DUK_ASSERT(tv1 != NULL); + tv2 = duk_require_tval(thr, idx2); + DUK_ASSERT(tv2 != NULL); + + /* If tv1==tv2 this is a NOP, no check is needed */ + DUK_TVAL_SET_TVAL(&tv_tmp, tv1); + DUK_TVAL_SET_TVAL(tv1, tv2); + DUK_TVAL_SET_TVAL(tv2, &tv_tmp); +} + +DUK_EXTERNAL void duk_swap_top(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + + duk_swap(thr, idx, -1); +} + +DUK_EXTERNAL void duk_dup(duk_hthread *thr, duk_idx_t from_idx) { + duk_tval *tv_from; + duk_tval *tv_to; + + DUK_ASSERT_API_ENTRY(thr); + DUK__CHECK_SPACE(); + + tv_from = duk_require_tval(thr, from_idx); + tv_to = thr->valstack_top++; + DUK_ASSERT(tv_from != NULL); + DUK_ASSERT(tv_to != NULL); + DUK_TVAL_SET_TVAL(tv_to, tv_from); + DUK_TVAL_INCREF(thr, tv_to); /* no side effects */ +} + +DUK_EXTERNAL void duk_dup_top(duk_hthread *thr) { +#if defined(DUK_USE_PREFER_SIZE) + duk_dup(thr, -1); +#else + duk_tval *tv_from; + duk_tval *tv_to; + + DUK_ASSERT_API_ENTRY(thr); + DUK__CHECK_SPACE(); + + if (DUK_UNLIKELY(thr->valstack_top - thr->valstack_bottom <= 0)) { + DUK_ERROR_RANGE_INDEX(thr, -1); + DUK_WO_NORETURN(return;); + } + tv_from = thr->valstack_top - 1; + tv_to = thr->valstack_top++; + DUK_ASSERT(tv_from != NULL); + DUK_ASSERT(tv_to != NULL); + DUK_TVAL_SET_TVAL(tv_to, tv_from); + DUK_TVAL_INCREF(thr, tv_to); /* no side effects */ +#endif +} + +DUK_INTERNAL void duk_dup_0(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_dup(thr, 0); +} +DUK_INTERNAL void duk_dup_1(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_dup(thr, 1); +} +DUK_INTERNAL void duk_dup_2(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_dup(thr, 2); +} +DUK_INTERNAL void duk_dup_m2(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_dup(thr, -2); +} +DUK_INTERNAL void duk_dup_m3(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_dup(thr, -3); +} +DUK_INTERNAL void duk_dup_m4(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_dup(thr, -4); +} + +DUK_EXTERNAL void duk_insert(duk_hthread *thr, duk_idx_t to_idx) { + duk_tval *p; + duk_tval *q; + duk_tval tv_tmp; + duk_size_t nbytes; + + DUK_ASSERT_API_ENTRY(thr); + + p = duk_require_tval(thr, to_idx); + DUK_ASSERT(p != NULL); + q = duk_require_tval(thr, -1); + DUK_ASSERT(q != NULL); + + DUK_ASSERT(q >= p); + + /* nbytes + * <---------> + * [ ... | p | x | x | q ] + * => [ ... | q | p | x | x ] + */ + + nbytes = (duk_size_t) (((duk_uint8_t *) q) - ((duk_uint8_t *) p)); /* Note: 'q' is top-1 */ + + DUK_DDD(DUK_DDDPRINT("duk_insert: to_idx=%ld, p=%p, q=%p, nbytes=%lu", + (long) to_idx, (void *) p, (void *) q, (unsigned long) nbytes)); + + /* No net refcount changes. No need to special case nbytes == 0 + * (p == q). + */ + DUK_TVAL_SET_TVAL(&tv_tmp, q); + duk_memmove((void *) (p + 1), (const void *) p, (size_t) nbytes); + DUK_TVAL_SET_TVAL(p, &tv_tmp); +} + +DUK_INTERNAL void duk_insert_undefined(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(idx >= 0); /* Doesn't support negative indices. */ + + duk_push_undefined(thr); + duk_insert(thr, idx); +} + +DUK_INTERNAL void duk_insert_undefined_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) { + duk_tval *tv, *tv_end; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(idx >= 0); /* Doesn't support negative indices or count. */ + DUK_ASSERT(count >= 0); + + tv = duk_reserve_gap(thr, idx, count); + tv_end = tv + count; + while (tv != tv_end) { + DUK_TVAL_SET_UNDEFINED(tv); + tv++; + } +} + +DUK_EXTERNAL void duk_replace(duk_hthread *thr, duk_idx_t to_idx) { + duk_tval *tv1; + duk_tval *tv2; + duk_tval tv_tmp; + + DUK_ASSERT_API_ENTRY(thr); + + tv1 = duk_require_tval(thr, -1); + DUK_ASSERT(tv1 != NULL); + tv2 = duk_require_tval(thr, to_idx); + DUK_ASSERT(tv2 != NULL); + + /* For tv1 == tv2, both pointing to stack top, the end result + * is same as duk_pop(thr). + */ + DUK_TVAL_SET_TVAL(&tv_tmp, tv2); + DUK_TVAL_SET_TVAL(tv2, tv1); + DUK_TVAL_SET_UNDEFINED(tv1); + thr->valstack_top--; + DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */ +} + +DUK_EXTERNAL void duk_copy(duk_hthread *thr, duk_idx_t from_idx, duk_idx_t to_idx) { + duk_tval *tv1; + duk_tval *tv2; + + DUK_ASSERT_API_ENTRY(thr); + + tv1 = duk_require_tval(thr, from_idx); + DUK_ASSERT(tv1 != NULL); + tv2 = duk_require_tval(thr, to_idx); + DUK_ASSERT(tv2 != NULL); + + /* For tv1 == tv2, this is a no-op (no explicit check needed). */ + DUK_TVAL_SET_TVAL_UPDREF(thr, tv2, tv1); /* side effects */ +} + +DUK_EXTERNAL void duk_remove(duk_hthread *thr, duk_idx_t idx) { + duk_tval *p; + duk_tval *q; +#if defined(DUK_USE_REFERENCE_COUNTING) + duk_tval tv_tmp; +#endif + duk_size_t nbytes; + + DUK_ASSERT_API_ENTRY(thr); + + p = duk_require_tval(thr, idx); + DUK_ASSERT(p != NULL); + q = duk_require_tval(thr, -1); + DUK_ASSERT(q != NULL); + + DUK_ASSERT(q >= p); + + /* nbytes zero size case + * <---------> + * [ ... | p | x | x | q ] [ ... | p==q ] + * => [ ... | x | x | q ] [ ... ] + */ + +#if defined(DUK_USE_REFERENCE_COUNTING) + /* use a temp: decref only when valstack reachable values are correct */ + DUK_TVAL_SET_TVAL(&tv_tmp, p); +#endif + + nbytes = (duk_size_t) (((duk_uint8_t *) q) - ((duk_uint8_t *) p)); /* Note: 'q' is top-1 */ + duk_memmove((void *) p, (const void *) (p + 1), (size_t) nbytes); + + DUK_TVAL_SET_UNDEFINED(q); + thr->valstack_top--; + +#if defined(DUK_USE_REFERENCE_COUNTING) + DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */ +#endif +} + +DUK_INTERNAL void duk_remove_unsafe(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + + duk_remove(thr, idx); /* XXX: no optimization for now */ +} + +DUK_INTERNAL void duk_remove_m2(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + + duk_remove(thr, -2); +} + +DUK_INTERNAL void duk_remove_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) { +#if defined(DUK_USE_PREFER_SIZE) + /* XXX: maybe too slow even when preferring size? */ + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(count >= 0); + DUK_ASSERT(idx >= 0); + + while (count-- > 0) { + duk_remove(thr, idx); + } +#else /* DUK_USE_PREFER_SIZE */ + duk_tval *tv_src; + duk_tval *tv_dst; + duk_tval *tv_newtop; + duk_tval *tv; + duk_size_t bytes; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(count >= 0); + DUK_ASSERT(idx >= 0); + + tv_dst = thr->valstack_bottom + idx; + DUK_ASSERT(tv_dst <= thr->valstack_top); + tv_src = tv_dst + count; + DUK_ASSERT(tv_src <= thr->valstack_top); + bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) tv_src); + + for (tv = tv_dst; tv < tv_src; tv++) { + DUK_TVAL_DECREF_NORZ(thr, tv); + } + + duk_memmove((void *) tv_dst, (const void *) tv_src, bytes); + + tv_newtop = thr->valstack_top - count; + for (tv = tv_newtop; tv < thr->valstack_top; tv++) { + DUK_TVAL_SET_UNDEFINED(tv); + } + thr->valstack_top = tv_newtop; + + /* When not preferring size, only NORZ macros are used; caller + * is expected to DUK_REFZERO_CHECK(). + */ +#endif /* DUK_USE_PREFER_SIZE */ +} + +DUK_INTERNAL void duk_remove_n_unsafe(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) { + DUK_ASSERT_API_ENTRY(thr); + + duk_remove_n(thr, idx, count); /* XXX: no optimization for now */ +} + +/* + * Stack slice primitives + */ + +DUK_EXTERNAL void duk_xcopymove_raw(duk_hthread *to_thr, duk_hthread *from_thr, duk_idx_t count, duk_bool_t is_copy) { + void *src; + duk_size_t nbytes; + duk_tval *p; + duk_tval *q; + + /* XXX: several pointer comparison issues here */ + + DUK_ASSERT_API_ENTRY(to_thr); + DUK_CTX_ASSERT_VALID(to_thr); + DUK_CTX_ASSERT_VALID(from_thr); + DUK_ASSERT(to_thr->heap == from_thr->heap); + + if (DUK_UNLIKELY(to_thr == from_thr)) { + DUK_ERROR_TYPE(to_thr, DUK_STR_INVALID_CONTEXT); + DUK_WO_NORETURN(return;); + } + if (DUK_UNLIKELY((duk_uidx_t) count > (duk_uidx_t) DUK_USE_VALSTACK_LIMIT)) { + /* Maximum value check ensures 'nbytes' won't wrap below. + * Also handles negative count. + */ + DUK_ERROR_RANGE_INVALID_COUNT(to_thr); + DUK_WO_NORETURN(return;); + } + DUK_ASSERT(count >= 0); + + nbytes = sizeof(duk_tval) * (duk_size_t) count; + if (DUK_UNLIKELY(nbytes == 0)) { + return; + } + DUK_ASSERT(to_thr->valstack_top <= to_thr->valstack_end); + if (DUK_UNLIKELY((duk_size_t) ((duk_uint8_t *) to_thr->valstack_end - (duk_uint8_t *) to_thr->valstack_top) < nbytes)) { + DUK_ERROR_RANGE_PUSH_BEYOND(to_thr); + DUK_WO_NORETURN(return;); + } + src = (void *) ((duk_uint8_t *) from_thr->valstack_top - nbytes); + if (DUK_UNLIKELY(src < (void *) from_thr->valstack_bottom)) { + DUK_ERROR_RANGE_INVALID_COUNT(to_thr); + DUK_WO_NORETURN(return;); + } + + /* Copy values (no overlap even if to_thr == from_thr; that's not + * allowed now anyway). + */ + DUK_ASSERT(nbytes > 0); + duk_memcpy((void *) to_thr->valstack_top, (const void *) src, (size_t) nbytes); + + p = to_thr->valstack_top; + to_thr->valstack_top = (duk_tval *) (void *) (((duk_uint8_t *) p) + nbytes); + + if (is_copy) { + /* Incref copies, keep originals. */ + q = to_thr->valstack_top; + while (p < q) { + DUK_TVAL_INCREF(to_thr, p); /* no side effects */ + p++; + } + } else { + /* No net refcount change. */ + p = from_thr->valstack_top; + q = (duk_tval *) (void *) (((duk_uint8_t *) p) - nbytes); + from_thr->valstack_top = q; + + while (p > q) { + p--; + DUK_TVAL_SET_UNDEFINED(p); + /* XXX: fast primitive to set a bunch of values to UNDEFINED */ + } + } +} + +/* Internal helper: reserve a gap of 'count' elements at 'idx_base' and return a + * pointer to the gap. Values in the gap are garbage and MUST be initialized by + * the caller before any side effects may occur. The caller must ensure there's + * enough stack reserve for 'count' values. + */ +DUK_INTERNAL duk_tval *duk_reserve_gap(duk_hthread *thr, duk_idx_t idx_base, duk_idx_t count) { + duk_tval *tv_src; + duk_tval *tv_dst; + duk_size_t gap_bytes; + duk_size_t copy_bytes; + + /* Caller is responsible for ensuring there's enough preallocated + * value stack. + */ + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(count >= 0); + DUK_ASSERT((duk_size_t) (thr->valstack_end - thr->valstack_top) >= (duk_size_t) count); + + tv_src = thr->valstack_bottom + idx_base; + gap_bytes = (duk_size_t) count * sizeof(duk_tval); + tv_dst = (duk_tval *) (void *) ((duk_uint8_t *) tv_src + gap_bytes); + copy_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) tv_src); + thr->valstack_top = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_top + gap_bytes); + duk_memmove((void *) tv_dst, (const void *) tv_src, copy_bytes); + + /* Values in the gap are left as garbage: caller must fill them in + * and INCREF them before any side effects. + */ + return tv_src; +} + +/* + * Get/opt/require + */ + +DUK_EXTERNAL void duk_require_undefined(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (DUK_UNLIKELY(!DUK_TVAL_IS_UNDEFINED(tv))) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "undefined", DUK_STR_NOT_UNDEFINED); + DUK_WO_NORETURN(return;); + } +} + +DUK_EXTERNAL void duk_require_null(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (DUK_UNLIKELY(!DUK_TVAL_IS_NULL(tv))) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "null", DUK_STR_NOT_NULL); + DUK_WO_NORETURN(return;); + } +} + +DUK_LOCAL DUK_ALWAYS_INLINE duk_bool_t duk__get_boolean_raw(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) { + duk_bool_t ret; + duk_tval *tv; + + DUK_CTX_ASSERT_VALID(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (DUK_TVAL_IS_BOOLEAN(tv)) { + ret = DUK_TVAL_GET_BOOLEAN(tv); + DUK_ASSERT(ret == 0 || ret == 1); + } else { + ret = def_value; + /* Not guaranteed to be 0 or 1. */ + } + + return ret; +} + +DUK_EXTERNAL duk_bool_t duk_get_boolean(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + + return duk__get_boolean_raw(thr, idx, 0); /* default: false */ +} + +DUK_EXTERNAL duk_bool_t duk_get_boolean_default(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) { + DUK_ASSERT_API_ENTRY(thr); + + return duk__get_boolean_raw(thr, idx, def_value); +} + +DUK_EXTERNAL duk_bool_t duk_require_boolean(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + duk_bool_t ret; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (DUK_LIKELY(DUK_TVAL_IS_BOOLEAN(tv))) { + ret = DUK_TVAL_GET_BOOLEAN(tv); + DUK_ASSERT(ret == 0 || ret == 1); + return ret; + } else { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "boolean", DUK_STR_NOT_BOOLEAN); + DUK_WO_NORETURN(return 0;); + } +} + +DUK_EXTERNAL duk_bool_t duk_opt_boolean(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) { + DUK_ASSERT_API_ENTRY(thr); + + if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) { + return def_value; + } + return duk_require_boolean(thr, idx); +} + +DUK_LOCAL DUK_ALWAYS_INLINE duk_double_t duk__get_number_raw(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) { + duk_double_union ret; + duk_tval *tv; + + DUK_CTX_ASSERT_VALID(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv)) { + ret.d = (duk_double_t) DUK_TVAL_GET_FASTINT(tv); /* XXX: cast trick */ + } + else +#endif + if (DUK_TVAL_IS_DOUBLE(tv)) { + /* When using packed duk_tval, number must be in NaN-normalized form + * for it to be a duk_tval, so no need to normalize. NOP for unpacked + * duk_tval. + */ + ret.d = DUK_TVAL_GET_DOUBLE(tv); + DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&ret)); + } else { + ret.d = def_value; + /* Default value (including NaN) may not be normalized. */ + } + + return ret.d; +} + +DUK_EXTERNAL duk_double_t duk_get_number(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return duk__get_number_raw(thr, idx, DUK_DOUBLE_NAN); /* default: NaN */ +} + +DUK_EXTERNAL duk_double_t duk_get_number_default(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) { + DUK_ASSERT_API_ENTRY(thr); + return duk__get_number_raw(thr, idx, def_value); +} + +DUK_EXTERNAL duk_double_t duk_require_number(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + duk_double_union ret; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (DUK_UNLIKELY(!DUK_TVAL_IS_NUMBER(tv))) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "number", DUK_STR_NOT_NUMBER); + DUK_WO_NORETURN(return 0.0;); + } + + ret.d = DUK_TVAL_GET_NUMBER(tv); + + /* When using packed duk_tval, number must be in NaN-normalized form + * for it to be a duk_tval, so no need to normalize. NOP for unpacked + * duk_tval. + */ + DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&ret)); + return ret.d; +} + +DUK_EXTERNAL duk_double_t duk_opt_number(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) { + DUK_ASSERT_API_ENTRY(thr); + + if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) { + /* User provided default is not NaN normalized. */ + return def_value; + } + return duk_require_number(thr, idx); +} + +DUK_EXTERNAL duk_int_t duk_get_int(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + + return (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 0 /*require*/); +} + +DUK_EXTERNAL duk_uint_t duk_get_uint(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + + return (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 0 /*require*/); +} + +DUK_EXTERNAL duk_int_t duk_get_int_default(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value) { + DUK_ASSERT_API_ENTRY(thr); + + return (duk_int_t) duk__api_coerce_d2i(thr, idx, def_value, 0 /*require*/); +} + +DUK_EXTERNAL duk_uint_t duk_get_uint_default(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value) { + DUK_ASSERT_API_ENTRY(thr); + + return (duk_uint_t) duk__api_coerce_d2ui(thr, idx, def_value, 0 /*require*/); +} + +DUK_EXTERNAL duk_int_t duk_require_int(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + + return (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 1 /*require*/); +} + +DUK_EXTERNAL duk_uint_t duk_require_uint(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + + return (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 1 /*require*/); +} + +DUK_EXTERNAL duk_int_t duk_opt_int(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value) { + DUK_ASSERT_API_ENTRY(thr); + + if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) { + return def_value; + } + return duk_require_int(thr, idx); +} + +DUK_EXTERNAL duk_uint_t duk_opt_uint(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value) { + DUK_ASSERT_API_ENTRY(thr); + + if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) { + return def_value; + } + return duk_require_uint(thr, idx); +} + +DUK_EXTERNAL const char *duk_get_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) { + duk_hstring *h; + const char *ret; + duk_size_t len; + + DUK_ASSERT_API_ENTRY(thr); + + h = duk_get_hstring(thr, idx); + if (h != NULL) { + len = DUK_HSTRING_GET_BYTELEN(h); + ret = (const char *) DUK_HSTRING_GET_DATA(h); + } else { + len = 0; + ret = NULL; + } + + if (out_len != NULL) { + *out_len = len; + } + return ret; +} + +DUK_EXTERNAL const char *duk_require_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) { + duk_hstring *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = duk_require_hstring(thr, idx); + DUK_ASSERT(h != NULL); + if (out_len) { + *out_len = DUK_HSTRING_GET_BYTELEN(h); + } + return (const char *) DUK_HSTRING_GET_DATA(h); +} + +DUK_INTERNAL const char *duk_require_lstring_notsymbol(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) { + duk_hstring *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = duk_require_hstring_notsymbol(thr, idx); + DUK_ASSERT(h != NULL); + if (out_len) { + *out_len = DUK_HSTRING_GET_BYTELEN(h); + } + return (const char *) DUK_HSTRING_GET_DATA(h); +} + +DUK_EXTERNAL const char *duk_get_string(duk_hthread *thr, duk_idx_t idx) { + duk_hstring *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = duk_get_hstring(thr, idx); + if (h != NULL) { + return (const char *) DUK_HSTRING_GET_DATA(h); + } else { + return NULL; + } +} + +DUK_EXTERNAL const char *duk_opt_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len) { + DUK_ASSERT_API_ENTRY(thr); + + if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) { + if (out_len != NULL) { + *out_len = def_len; + } + return def_ptr; + } + return duk_require_lstring(thr, idx, out_len); +} + +DUK_EXTERNAL const char *duk_opt_string(duk_hthread *thr, duk_idx_t idx, const char *def_ptr) { + DUK_ASSERT_API_ENTRY(thr); + + if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) { + return def_ptr; + } + return duk_require_string(thr, idx); +} + +DUK_EXTERNAL const char *duk_get_lstring_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len) { + duk_hstring *h; + const char *ret; + duk_size_t len; + + DUK_ASSERT_API_ENTRY(thr); + + h = duk_get_hstring(thr, idx); + if (h != NULL) { + len = DUK_HSTRING_GET_BYTELEN(h); + ret = (const char *) DUK_HSTRING_GET_DATA(h); + } else { + len = def_len; + ret = def_ptr; + } + + if (out_len != NULL) { + *out_len = len; + } + return ret; +} + +DUK_EXTERNAL const char *duk_get_string_default(duk_hthread *thr, duk_idx_t idx, const char *def_value) { + duk_hstring *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = duk_get_hstring(thr, idx); + if (h != NULL) { + return (const char *) DUK_HSTRING_GET_DATA(h); + } else { + return def_value; + } +} + +DUK_INTERNAL const char *duk_get_string_notsymbol(duk_hthread *thr, duk_idx_t idx) { + duk_hstring *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = duk_get_hstring_notsymbol(thr, idx); + if (h) { + return (const char *) DUK_HSTRING_GET_DATA(h); + } else { + return NULL; + } +} + +DUK_EXTERNAL const char *duk_require_string(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + + return duk_require_lstring(thr, idx, NULL); +} + +DUK_INTERNAL const char *duk_require_string_notsymbol(duk_hthread *thr, duk_idx_t idx) { + duk_hstring *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = duk_require_hstring_notsymbol(thr, idx); + DUK_ASSERT(h != NULL); + return (const char *) DUK_HSTRING_GET_DATA(h); +} + +DUK_EXTERNAL void duk_require_object(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (DUK_UNLIKELY(!DUK_TVAL_IS_OBJECT(tv))) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "object", DUK_STR_NOT_OBJECT); + DUK_WO_NORETURN(return;); + } +} + +DUK_LOCAL void *duk__get_pointer_raw(duk_hthread *thr, duk_idx_t idx, void *def_value) { + duk_tval *tv; + void *p; + + DUK_CTX_ASSERT_VALID(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (!DUK_TVAL_IS_POINTER(tv)) { + return def_value; + } + + p = DUK_TVAL_GET_POINTER(tv); /* may be NULL */ + return p; +} + +DUK_EXTERNAL void *duk_get_pointer(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return duk__get_pointer_raw(thr, idx, NULL /*def_value*/); +} + +DUK_EXTERNAL void *duk_opt_pointer(duk_hthread *thr, duk_idx_t idx, void *def_value) { + DUK_ASSERT_API_ENTRY(thr); + + if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) { + return def_value; + } + return duk_require_pointer(thr, idx); +} + +DUK_EXTERNAL void *duk_get_pointer_default(duk_hthread *thr, duk_idx_t idx, void *def_value) { + DUK_ASSERT_API_ENTRY(thr); + return duk__get_pointer_raw(thr, idx, def_value); +} + +DUK_EXTERNAL void *duk_require_pointer(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + void *p; + + DUK_ASSERT_API_ENTRY(thr); + + /* Note: here we must be wary of the fact that a pointer may be + * valid and be a NULL. + */ + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (DUK_UNLIKELY(!DUK_TVAL_IS_POINTER(tv))) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "pointer", DUK_STR_NOT_POINTER); + DUK_WO_NORETURN(return NULL;); + } + p = DUK_TVAL_GET_POINTER(tv); /* may be NULL */ + return p; +} + +#if 0 /*unused*/ +DUK_INTERNAL void *duk_get_voidptr(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + duk_heaphdr *h; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (!DUK_TVAL_IS_HEAP_ALLOCATED(tv)) { + return NULL; + } + + h = DUK_TVAL_GET_HEAPHDR(tv); + DUK_ASSERT(h != NULL); + return (void *) h; +} +#endif + +DUK_LOCAL void *duk__get_buffer_helper(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size, duk_bool_t throw_flag) { + duk_hbuffer *h; + void *ret; + duk_size_t len; + duk_tval *tv; + + DUK_CTX_ASSERT_VALID(thr); + + if (out_size != NULL) { + *out_size = 0; + } + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (DUK_LIKELY(DUK_TVAL_IS_BUFFER(tv))) { + h = DUK_TVAL_GET_BUFFER(tv); + DUK_ASSERT(h != NULL); + + len = DUK_HBUFFER_GET_SIZE(h); + ret = DUK_HBUFFER_GET_DATA_PTR(thr->heap, h); + } else { + if (throw_flag) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "buffer", DUK_STR_NOT_BUFFER); + DUK_WO_NORETURN(return NULL;); + } + len = def_size; + ret = def_ptr; + } + + if (out_size != NULL) { + *out_size = len; + } + return ret; +} + +DUK_EXTERNAL void *duk_get_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) { + DUK_ASSERT_API_ENTRY(thr); + + return duk__get_buffer_helper(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/); +} + +DUK_EXTERNAL void *duk_opt_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) { + DUK_ASSERT_API_ENTRY(thr); + + if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) { + if (out_size != NULL) { + *out_size = def_size; + } + return def_ptr; + } + return duk_require_buffer(thr, idx, out_size); +} + +DUK_EXTERNAL void *duk_get_buffer_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len) { + DUK_ASSERT_API_ENTRY(thr); + + return duk__get_buffer_helper(thr, idx, out_size, def_ptr, def_len, 0 /*throw_flag*/); +} + +DUK_EXTERNAL void *duk_require_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) { + DUK_ASSERT_API_ENTRY(thr); + + return duk__get_buffer_helper(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 1 /*throw_flag*/); +} + +/* Get the active buffer data area for a plain buffer or a buffer object. + * Return NULL if the the value is not a buffer. Note that a buffer may + * have a NULL data pointer when its size is zero, the optional 'out_isbuffer' + * argument allows caller to detect this reliably. + */ +DUK_INTERNAL void *duk_get_buffer_data_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size, duk_bool_t throw_flag, duk_bool_t *out_isbuffer) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + if (out_isbuffer != NULL) { + *out_isbuffer = 0; + } + if (out_size != NULL) { + *out_size = def_size; + } + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + + if (DUK_TVAL_IS_BUFFER(tv)) { + duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv); + DUK_ASSERT(h != NULL); + if (out_size != NULL) { + *out_size = DUK_HBUFFER_GET_SIZE(h); + } + if (out_isbuffer != NULL) { + *out_isbuffer = 1; + } + return (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h); /* may be NULL (but only if size is 0) */ + } +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + else if (DUK_TVAL_IS_OBJECT(tv)) { + duk_hobject *h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + if (DUK_HOBJECT_IS_BUFOBJ(h)) { + /* XXX: this is probably a useful shared helper: for a + * duk_hbufobj, get a validated buffer pointer/length. + */ + duk_hbufobj *h_bufobj = (duk_hbufobj *) h; + DUK_HBUFOBJ_ASSERT_VALID(h_bufobj); + + if (h_bufobj->buf != NULL && + DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) { + duk_uint8_t *p; + + p = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf); + if (out_size != NULL) { + *out_size = (duk_size_t) h_bufobj->length; + } + if (out_isbuffer != NULL) { + *out_isbuffer = 1; + } + return (void *) (p + h_bufobj->offset); + } + /* if slice not fully valid, treat as error */ + } + } +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + + if (throw_flag) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "buffer", DUK_STR_NOT_BUFFER); + DUK_WO_NORETURN(return NULL;); + } + return def_ptr; +} + +DUK_EXTERNAL void *duk_get_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) { + DUK_ASSERT_API_ENTRY(thr); + return duk_get_buffer_data_raw(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/, NULL); +} + +DUK_EXTERNAL void *duk_get_buffer_data_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) { + DUK_ASSERT_API_ENTRY(thr); + return duk_get_buffer_data_raw(thr, idx, out_size, def_ptr, def_size, 0 /*throw_flag*/, NULL); +} + +DUK_EXTERNAL void *duk_opt_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) { + DUK_ASSERT_API_ENTRY(thr); + + if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) { + if (out_size != NULL) { + *out_size = def_size; + } + return def_ptr; + } + return duk_require_buffer_data(thr, idx, out_size); +} + +DUK_EXTERNAL void *duk_require_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) { + DUK_ASSERT_API_ENTRY(thr); + return duk_get_buffer_data_raw(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 1 /*throw_flag*/, NULL); +} + +/* Raw helper for getting a value from the stack, checking its tag. + * The tag cannot be a number because numbers don't have an internal + * tag in the packed representation. + */ + +DUK_LOCAL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t tag) { + duk_tval *tv; + duk_heaphdr *ret; + + DUK_CTX_ASSERT_VALID(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (DUK_TVAL_GET_TAG(tv) != tag) { + return (duk_heaphdr *) NULL; + } + + ret = DUK_TVAL_GET_HEAPHDR(tv); + DUK_ASSERT(ret != NULL); /* tagged null pointers should never occur */ + return ret; + +} + +DUK_INTERNAL duk_hstring *duk_get_hstring(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING); +} + +DUK_INTERNAL duk_hstring *duk_get_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx) { + duk_hstring *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING); + if (DUK_UNLIKELY(h && DUK_HSTRING_HAS_SYMBOL(h))) { + return NULL; + } + return h; +} + +DUK_INTERNAL duk_hstring *duk_require_hstring(duk_hthread *thr, duk_idx_t idx) { + duk_hstring *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING); + if (DUK_UNLIKELY(h == NULL)) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "string", DUK_STR_NOT_STRING); + DUK_WO_NORETURN(return NULL;); + } + return h; +} + +DUK_INTERNAL duk_hstring *duk_require_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx) { + duk_hstring *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING); + if (DUK_UNLIKELY(h == NULL || DUK_HSTRING_HAS_SYMBOL(h))) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "string", DUK_STR_NOT_STRING); + DUK_WO_NORETURN(return NULL;); + } + return h; +} + +DUK_INTERNAL duk_hobject *duk_get_hobject(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT); +} + +DUK_INTERNAL duk_hobject *duk_require_hobject(duk_hthread *thr, duk_idx_t idx) { + duk_hobject *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT); + if (DUK_UNLIKELY(h == NULL)) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "object", DUK_STR_NOT_OBJECT); + DUK_WO_NORETURN(return NULL;); + } + return h; +} + +DUK_INTERNAL duk_hbuffer *duk_get_hbuffer(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return (duk_hbuffer *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_BUFFER); +} + +DUK_INTERNAL duk_hbuffer *duk_require_hbuffer(duk_hthread *thr, duk_idx_t idx) { + duk_hbuffer *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = (duk_hbuffer *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_BUFFER); + if (DUK_UNLIKELY(h == NULL)) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "buffer", DUK_STR_NOT_BUFFER); + DUK_WO_NORETURN(return NULL;); + } + return h; +} + +DUK_INTERNAL duk_hthread *duk_get_hthread(duk_hthread *thr, duk_idx_t idx) { + duk_hobject *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT); + if (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_THREAD(h))) { + h = NULL; + } + return (duk_hthread *) h; +} + +DUK_INTERNAL duk_hthread *duk_require_hthread(duk_hthread *thr, duk_idx_t idx) { + duk_hobject *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT); + if (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_THREAD(h)))) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "thread", DUK_STR_NOT_THREAD); + DUK_WO_NORETURN(return NULL;); + } + return (duk_hthread *) h; +} + +DUK_INTERNAL duk_hcompfunc *duk_get_hcompfunc(duk_hthread *thr, duk_idx_t idx) { + duk_hobject *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT); + if (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_COMPFUNC(h))) { + h = NULL; + } + return (duk_hcompfunc *) h; +} + +DUK_INTERNAL duk_hcompfunc *duk_require_hcompfunc(duk_hthread *thr, duk_idx_t idx) { + duk_hobject *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT); + if (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_COMPFUNC(h)))) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "compiledfunction", DUK_STR_NOT_COMPFUNC); + DUK_WO_NORETURN(return NULL;); + } + return (duk_hcompfunc *) h; +} + +DUK_INTERNAL duk_hnatfunc *duk_get_hnatfunc(duk_hthread *thr, duk_idx_t idx) { + duk_hobject *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT); + if (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_NATFUNC(h))) { + h = NULL; + } + return (duk_hnatfunc *) h; +} + +DUK_INTERNAL duk_hnatfunc *duk_require_hnatfunc(duk_hthread *thr, duk_idx_t idx) { + duk_hobject *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT); + if (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_NATFUNC(h)))) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "nativefunction", DUK_STR_NOT_NATFUNC); + DUK_WO_NORETURN(return NULL;); + } + return (duk_hnatfunc *) h; +} + +DUK_EXTERNAL duk_c_function duk_get_c_function(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + duk_hobject *h; + duk_hnatfunc *f; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (DUK_UNLIKELY(!DUK_TVAL_IS_OBJECT(tv))) { + return NULL; + } + h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + + if (DUK_UNLIKELY(!DUK_HOBJECT_IS_NATFUNC(h))) { + return NULL; + } + DUK_ASSERT(DUK_HOBJECT_HAS_NATFUNC(h)); + f = (duk_hnatfunc *) h; + + return f->func; +} + +DUK_EXTERNAL duk_c_function duk_opt_c_function(duk_hthread *thr, duk_idx_t idx, duk_c_function def_value) { + DUK_ASSERT_API_ENTRY(thr); + + if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) { + return def_value; + } + return duk_require_c_function(thr, idx); +} + +DUK_EXTERNAL duk_c_function duk_get_c_function_default(duk_hthread *thr, duk_idx_t idx, duk_c_function def_value) { + duk_c_function ret; + + DUK_ASSERT_API_ENTRY(thr); + + ret = duk_get_c_function(thr, idx); + if (ret != NULL) { + return ret; + } + + return def_value; +} + +DUK_EXTERNAL duk_c_function duk_require_c_function(duk_hthread *thr, duk_idx_t idx) { + duk_c_function ret; + + DUK_ASSERT_API_ENTRY(thr); + + ret = duk_get_c_function(thr, idx); + if (DUK_UNLIKELY(!ret)) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "nativefunction", DUK_STR_NOT_NATFUNC); + DUK_WO_NORETURN(return ret;); + } + return ret; +} + +DUK_EXTERNAL void duk_require_function(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + if (DUK_UNLIKELY(!duk_is_function(thr, idx))) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "function", DUK_STR_NOT_FUNCTION); + DUK_WO_NORETURN(return;); + } +} + +DUK_EXTERNAL void duk_require_constructable(duk_hthread *thr, duk_idx_t idx) { + duk_hobject *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = duk_require_hobject_accept_mask(thr, idx, DUK_TYPE_MASK_LIGHTFUNC); + if (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_HAS_CONSTRUCTABLE(h))) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "constructable", DUK_STR_NOT_CONSTRUCTABLE); + DUK_WO_NORETURN(return;); + } + /* Lightfuncs (h == NULL) are constructable. */ +} + +DUK_EXTERNAL duk_hthread *duk_get_context(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + + return duk_get_hthread(thr, idx); +} + +DUK_EXTERNAL duk_hthread *duk_require_context(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + + return duk_require_hthread(thr, idx); +} + +DUK_EXTERNAL duk_hthread *duk_opt_context(duk_hthread *thr, duk_idx_t idx, duk_hthread *def_value) { + DUK_ASSERT_API_ENTRY(thr); + + if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) { + return def_value; + } + return duk_require_context(thr, idx); +} + +DUK_EXTERNAL duk_hthread *duk_get_context_default(duk_hthread *thr, duk_idx_t idx, duk_hthread *def_value) { + duk_hthread *ret; + + DUK_ASSERT_API_ENTRY(thr); + + ret = duk_get_context(thr, idx); + if (ret != NULL) { + return ret; + } + + return def_value; +} + +DUK_EXTERNAL void *duk_get_heapptr(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + void *ret; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (DUK_UNLIKELY(!DUK_TVAL_IS_HEAP_ALLOCATED(tv))) { + return (void *) NULL; + } + + ret = (void *) DUK_TVAL_GET_HEAPHDR(tv); + DUK_ASSERT(ret != NULL); + return ret; +} + +DUK_EXTERNAL void *duk_opt_heapptr(duk_hthread *thr, duk_idx_t idx, void *def_value) { + DUK_ASSERT_API_ENTRY(thr); + + if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) { + return def_value; + } + return duk_require_heapptr(thr, idx); +} + +DUK_EXTERNAL void *duk_get_heapptr_default(duk_hthread *thr, duk_idx_t idx, void *def_value) { + void *ret; + + DUK_ASSERT_API_ENTRY(thr); + + ret = duk_get_heapptr(thr, idx); + if (ret != NULL) { + return ret; + } + + return def_value; +} + +DUK_EXTERNAL void *duk_require_heapptr(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + void *ret; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (DUK_UNLIKELY(!DUK_TVAL_IS_HEAP_ALLOCATED(tv))) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "heapobject", DUK_STR_UNEXPECTED_TYPE); + DUK_WO_NORETURN(return NULL;); + } + + ret = (void *) DUK_TVAL_GET_HEAPHDR(tv); + DUK_ASSERT(ret != NULL); + return ret; +} + +/* Internal helper for getting/requiring a duk_hobject with possible promotion. */ +DUK_LOCAL duk_hobject *duk__get_hobject_promote_mask_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) { + duk_uint_t val_mask; + duk_hobject *res; + + DUK_CTX_ASSERT_VALID(thr); + + res = duk_get_hobject(thr, idx); /* common case, not promoted */ + if (DUK_LIKELY(res != NULL)) { + DUK_ASSERT(res != NULL); + return res; + } + + val_mask = duk_get_type_mask(thr, idx); + if (val_mask & type_mask) { + if (type_mask & DUK_TYPE_MASK_PROMOTE) { + res = duk_to_hobject(thr, idx); + DUK_ASSERT(res != NULL); + return res; + } else { + return NULL; /* accept without promoting */ + } + } + + if (type_mask & DUK_TYPE_MASK_THROW) { + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "object", DUK_STR_NOT_OBJECT); + DUK_WO_NORETURN(return NULL;); + } + return NULL; +} + +/* Get a duk_hobject * at 'idx'; if the value is not an object but matches the + * supplied 'type_mask', promote it to an object and return the duk_hobject *. + * This is useful for call sites which want an object but also accept a plain + * buffer and/or a lightfunc which gets automatically promoted to an object. + * Return value is NULL if value is neither an object nor a plain type allowed + * by the mask. + */ +DUK_INTERNAL duk_hobject *duk_get_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) { + DUK_ASSERT_API_ENTRY(thr); + return duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_PROMOTE); +} + +/* Like duk_get_hobject_promote_mask() but throw a TypeError instead of + * returning a NULL. + */ +DUK_INTERNAL duk_hobject *duk_require_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) { + DUK_ASSERT_API_ENTRY(thr); + return duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_THROW | DUK_TYPE_MASK_PROMOTE); +} + +/* Require a duk_hobject * at 'idx'; if the value is not an object but matches the + * supplied 'type_mask', return a NULL instead. Otherwise throw a TypeError. + */ +DUK_INTERNAL duk_hobject *duk_require_hobject_accept_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) { + DUK_ASSERT_API_ENTRY(thr); + return duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_THROW); +} + +DUK_INTERNAL duk_hobject *duk_get_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum) { + duk_hobject *h; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT_DISABLE(classnum >= 0); /* unsigned */ + DUK_ASSERT(classnum <= DUK_HOBJECT_CLASS_MAX); + + h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT); + if (DUK_UNLIKELY(h != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h) != classnum)) { + h = NULL; + } + return h; +} + +DUK_INTERNAL duk_hobject *duk_require_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum) { + duk_hobject *h; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT_DISABLE(classnum >= 0); /* unsigned */ + DUK_ASSERT(classnum <= DUK_HOBJECT_CLASS_MAX); + + h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT); + if (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h) == classnum))) { + duk_hstring *h_class; + h_class = DUK_HTHREAD_GET_STRING(thr, DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum)); + DUK_UNREF(h_class); + + DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, (const char *) DUK_HSTRING_GET_DATA(h_class), DUK_STR_UNEXPECTED_TYPE); + DUK_WO_NORETURN(return NULL;); + } + return h; +} + +DUK_EXTERNAL duk_size_t duk_get_length(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_UNDEFINED: + case DUK_TAG_NULL: + case DUK_TAG_BOOLEAN: + case DUK_TAG_POINTER: + return 0; +#if defined(DUK_USE_PREFER_SIZE) + /* String and buffer have a virtual non-configurable .length property + * which is within size_t range so it can be looked up without specific + * type checks. Lightfuncs inherit from %NativeFunctionPrototype% + * which provides an inherited .length accessor; it could be overwritten + * to produce unexpected types or values, but just number convert and + * duk_size_t cast for now. + */ + case DUK_TAG_STRING: + case DUK_TAG_BUFFER: + case DUK_TAG_LIGHTFUNC: { + duk_size_t ret; + duk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH); + ret = (duk_size_t) duk_to_number_m1(thr); + duk_pop_unsafe(thr); + return ret; + } +#else /* DUK_USE_PREFER_SIZE */ + case DUK_TAG_STRING: { + duk_hstring *h = DUK_TVAL_GET_STRING(tv); + DUK_ASSERT(h != NULL); + if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) { + return 0; + } + return (duk_size_t) DUK_HSTRING_GET_CHARLEN(h); + } + case DUK_TAG_BUFFER: { + duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv); + DUK_ASSERT(h != NULL); + return (duk_size_t) DUK_HBUFFER_GET_SIZE(h); + } + case DUK_TAG_LIGHTFUNC: { + /* We could look up the length from the lightfunc duk_tval, + * but since Duktape 2.2 lightfunc .length comes from + * %NativeFunctionPrototype% which can be overridden, so + * look up the property explicitly. + */ + duk_size_t ret; + duk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH); + ret = (duk_size_t) duk_to_number_m1(thr); + duk_pop_unsafe(thr); + return ret; + } +#endif /* DUK_USE_PREFER_SIZE */ + case DUK_TAG_OBJECT: { + duk_hobject *h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + return (duk_size_t) duk_hobject_get_length(thr, h); + } +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: +#endif + default: + /* number or 'unused' */ + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv) || DUK_TVAL_IS_UNUSED(tv)); + return 0; + } + + DUK_UNREACHABLE(); +} + +/* + * duk_known_xxx() helpers + * + * Used internally when we're 100% sure that a certain index is valid and + * contains an object of a certain type. For example, if we duk_push_object() + * we can then safely duk_known_hobject(thr, -1). These helpers just assert + * for the index and type, and if the assumptions are not valid, memory unsafe + * behavior happens. + */ + +DUK_LOCAL duk_heaphdr *duk__known_heaphdr(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + duk_heaphdr *h; + + DUK_CTX_ASSERT_VALID(thr); + if (idx < 0) { + tv = thr->valstack_top + idx; + } else { + tv = thr->valstack_bottom + idx; + } + DUK_ASSERT(tv >= thr->valstack_bottom); + DUK_ASSERT(tv < thr->valstack_top); + h = DUK_TVAL_GET_HEAPHDR(tv); + DUK_ASSERT(h != NULL); + return h; +} + +DUK_INTERNAL duk_hstring *duk_known_hstring(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(duk_get_hstring(thr, idx) != NULL); + return (duk_hstring *) duk__known_heaphdr(thr, idx); +} + +DUK_INTERNAL duk_hobject *duk_known_hobject(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(duk_get_hobject(thr, idx) != NULL); + return (duk_hobject *) duk__known_heaphdr(thr, idx); +} + +DUK_INTERNAL duk_hbuffer *duk_known_hbuffer(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(duk_get_hbuffer(thr, idx) != NULL); + return (duk_hbuffer *) duk__known_heaphdr(thr, idx); +} + +DUK_INTERNAL duk_hcompfunc *duk_known_hcompfunc(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(duk_get_hcompfunc(thr, idx) != NULL); + return (duk_hcompfunc *) duk__known_heaphdr(thr, idx); +} + +DUK_INTERNAL duk_hnatfunc *duk_known_hnatfunc(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(duk_get_hnatfunc(thr, idx) != NULL); + return (duk_hnatfunc *) duk__known_heaphdr(thr, idx); +} + +DUK_EXTERNAL void duk_set_length(duk_hthread *thr, duk_idx_t idx, duk_size_t len) { + DUK_ASSERT_API_ENTRY(thr); + + idx = duk_normalize_index(thr, idx); + duk_push_uint(thr, (duk_uint_t) len); + duk_put_prop_stridx(thr, idx, DUK_STRIDX_LENGTH); +} + +/* + * Conversions and coercions + * + * The conversion/coercions are in-place operations on the value stack. + * Some operations are implemented here directly, while others call a + * helper in duk_js_ops.c after validating arguments. + */ + +/* E5 Section 8.12.8 */ + +DUK_LOCAL duk_bool_t duk__defaultvalue_coerce_attempt(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t func_stridx) { + if (duk_get_prop_stridx(thr, idx, func_stridx)) { + /* [ ... func ] */ + if (duk_is_callable(thr, -1)) { + duk_dup(thr, idx); /* -> [ ... func this ] */ + duk_call_method(thr, 0); /* -> [ ... retval ] */ + if (duk_is_primitive(thr, -1)) { + duk_replace(thr, idx); + return 1; + } + /* [ ... retval ]; popped below */ + } + } + duk_pop_unsafe(thr); /* [ ... func/retval ] -> [ ... ] */ + return 0; +} + +DUK_EXTERNAL void duk_to_undefined(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_require_tval(thr, idx); + DUK_ASSERT(tv != NULL); + DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv); /* side effects */ +} + +DUK_EXTERNAL void duk_to_null(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_require_tval(thr, idx); + DUK_ASSERT(tv != NULL); + DUK_TVAL_SET_NULL_UPDREF(thr, tv); /* side effects */ +} + +/* E5 Section 9.1 */ +DUK_LOCAL const char * const duk__toprim_hint_strings[3] = { + "default", "string", "number" +}; +DUK_LOCAL void duk__to_primitive_helper(duk_hthread *thr, duk_idx_t idx, duk_int_t hint, duk_bool_t check_symbol) { + /* Inline initializer for coercers[] is not allowed by old compilers like BCC. */ + duk_small_uint_t coercers[2]; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(hint == DUK_HINT_NONE || hint == DUK_HINT_NUMBER || hint == DUK_HINT_STRING); + + idx = duk_require_normalize_index(thr, idx); + + /* If already primitive, return as is. */ + if (!duk_check_type_mask(thr, idx, DUK_TYPE_MASK_OBJECT | + DUK_TYPE_MASK_LIGHTFUNC | + DUK_TYPE_MASK_BUFFER)) { + DUK_ASSERT(!duk_is_buffer(thr, idx)); /* duk_to_string() relies on this behavior */ + return; + } + + /* @@toPrimitive lookup. Also do for plain buffers and lightfuncs + * which mimic objects. + */ + if (check_symbol && duk_get_method_stridx(thr, idx, DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE)) { + DUK_ASSERT(hint >= 0 && (duk_size_t) hint < sizeof(duk__toprim_hint_strings) / sizeof(const char *)); + duk_dup(thr, idx); + duk_push_string(thr, duk__toprim_hint_strings[hint]); + duk_call_method(thr, 1); /* [ ... method value hint ] -> [ ... res] */ + if (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT | + DUK_TYPE_MASK_LIGHTFUNC | + DUK_TYPE_MASK_BUFFER)) { + goto fail; + } + duk_replace(thr, idx); + return; + } + + /* Objects are coerced based on E5 specification. + * Lightfuncs are coerced because they behave like + * objects even if they're internally a primitive + * type. Same applies to plain buffers, which behave + * like ArrayBuffer objects since Duktape 2.x. + */ + + /* Hint magic for Date is unnecessary in ES2015 because of + * Date.prototype[@@toPrimitive]. However, it is needed if + * symbol support is not enabled. + */ +#if defined(DUK_USE_SYMBOL_BUILTIN) + if (hint == DUK_HINT_NONE) { + hint = DUK_HINT_NUMBER; + } +#else /* DUK_USE_SYMBOL_BUILTIN */ + if (hint == DUK_HINT_NONE) { + duk_small_uint_t class_number; + + class_number = duk_get_class_number(thr, idx); + if (class_number == DUK_HOBJECT_CLASS_DATE) { + hint = DUK_HINT_STRING; + } else { + hint = DUK_HINT_NUMBER; + } + } +#endif /* DUK_USE_SYMBOL_BUILTIN */ + + coercers[0] = DUK_STRIDX_VALUE_OF; + coercers[1] = DUK_STRIDX_TO_STRING; + if (hint == DUK_HINT_STRING) { + coercers[0] = DUK_STRIDX_TO_STRING; + coercers[1] = DUK_STRIDX_VALUE_OF; + } + + if (duk__defaultvalue_coerce_attempt(thr, idx, coercers[0])) { + DUK_ASSERT(!duk_is_buffer(thr, idx)); /* duk_to_string() relies on this behavior */ + return; + } + + if (duk__defaultvalue_coerce_attempt(thr, idx, coercers[1])) { + DUK_ASSERT(!duk_is_buffer(thr, idx)); /* duk_to_string() relies on this behavior */ + return; + } + + fail: + DUK_ERROR_TYPE(thr, DUK_STR_TOPRIMITIVE_FAILED); + DUK_WO_NORETURN(return;); +} + +DUK_EXTERNAL void duk_to_primitive(duk_hthread *thr, duk_idx_t idx, duk_int_t hint) { + duk__to_primitive_helper(thr, idx, hint, 1 /*check_symbol*/); +} + +#if defined(DUK_USE_SYMBOL_BUILTIN) +DUK_INTERNAL void duk_to_primitive_ordinary(duk_hthread *thr, duk_idx_t idx, duk_int_t hint) { + duk__to_primitive_helper(thr, idx, hint, 0 /*check_symbol*/); +} +#endif + +/* E5 Section 9.2 */ +DUK_EXTERNAL duk_bool_t duk_to_boolean(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + duk_bool_t val; + + DUK_ASSERT_API_ENTRY(thr); + + idx = duk_require_normalize_index(thr, idx); + tv = DUK_GET_TVAL_POSIDX(thr, idx); + DUK_ASSERT(tv != NULL); + + val = duk_js_toboolean(tv); + DUK_ASSERT(val == 0 || val == 1); + + /* Note: no need to re-lookup tv, conversion is side effect free. */ + DUK_ASSERT(tv != NULL); + DUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv, val); /* side effects */ + return val; +} + +DUK_INTERNAL duk_bool_t duk_to_boolean_top_pop(duk_hthread *thr) { + duk_tval *tv; + duk_bool_t val; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_require_tval(thr, -1); + DUK_ASSERT(tv != NULL); + + val = duk_js_toboolean(tv); + DUK_ASSERT(val == 0 || val == 1); + + duk_pop_unsafe(thr); + return val; +} + +DUK_EXTERNAL duk_double_t duk_to_number(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + duk_double_t d; + + DUK_ASSERT_API_ENTRY(thr); + + /* XXX: No need to normalize; the whole operation could be inlined here to + * avoid 'tv' re-lookup. + */ + idx = duk_require_normalize_index(thr, idx); + tv = DUK_GET_TVAL_POSIDX(thr, idx); + DUK_ASSERT(tv != NULL); + d = duk_js_tonumber(thr, tv); /* XXX: fastint coercion? now result will always be a non-fastint */ + + /* ToNumber() may have side effects so must relookup 'tv'. */ + tv = DUK_GET_TVAL_POSIDX(thr, idx); + DUK_TVAL_SET_NUMBER_UPDREF(thr, tv, d); /* side effects */ + return d; +} + +DUK_INTERNAL duk_double_t duk_to_number_m1(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + return duk_to_number(thr, -1); +} +DUK_INTERNAL duk_double_t duk_to_number_m2(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + return duk_to_number(thr, -2); +} + +DUK_INTERNAL duk_double_t duk_to_number_tval(duk_hthread *thr, duk_tval *tv) { +#if defined(DUK_USE_PREFER_SIZE) + duk_double_t res; + + DUK_ASSERT_API_ENTRY(thr); + + duk_push_tval(thr, tv); + res = duk_to_number_m1(thr); + duk_pop_unsafe(thr); + return res; +#else + duk_double_t res; + duk_tval *tv_dst; + + DUK_ASSERT_API_ENTRY(thr); + DUK__ASSERT_SPACE(); + + tv_dst = thr->valstack_top++; + DUK_TVAL_SET_TVAL(tv_dst, tv); + DUK_TVAL_INCREF(thr, tv_dst); /* decref not necessary */ + res = duk_to_number_m1(thr); /* invalidates tv_dst */ + + tv_dst = --thr->valstack_top; + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_dst)); + DUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv_dst)); /* plain number */ + DUK_TVAL_SET_UNDEFINED(tv_dst); /* valstack init policy */ + + return res; +#endif +} + +/* XXX: combine all the integer conversions: they share everything + * but the helper function for coercion. + */ + +typedef duk_double_t (*duk__toint_coercer)(duk_hthread *thr, duk_tval *tv); + +DUK_LOCAL duk_double_t duk__to_int_uint_helper(duk_hthread *thr, duk_idx_t idx, duk__toint_coercer coerce_func) { + duk_tval *tv; + duk_double_t d; + + DUK_CTX_ASSERT_VALID(thr); + + tv = duk_require_tval(thr, idx); + DUK_ASSERT(tv != NULL); + +#if defined(DUK_USE_FASTINT) + /* If argument is a fastint, guarantee that it remains one. + * There's no downgrade check for other cases. + */ + if (DUK_TVAL_IS_FASTINT(tv)) { + /* XXX: Unnecessary conversion back and forth. */ + return (duk_double_t) DUK_TVAL_GET_FASTINT(tv); + } +#endif + d = coerce_func(thr, tv); + + /* XXX: fastint? */ + + /* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */ + tv = duk_require_tval(thr, idx); + DUK_TVAL_SET_NUMBER_UPDREF(thr, tv, d); /* side effects */ + return d; +} + +DUK_EXTERNAL duk_int_t duk_to_int(duk_hthread *thr, duk_idx_t idx) { + /* Value coercion (in stack): ToInteger(), E5 Section 9.4, + * API return value coercion: custom. + */ + DUK_ASSERT_API_ENTRY(thr); + (void) duk__to_int_uint_helper(thr, idx, duk_js_tointeger); + return (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 0 /*require*/); +} + +DUK_EXTERNAL duk_uint_t duk_to_uint(duk_hthread *thr, duk_idx_t idx) { + /* Value coercion (in stack): ToInteger(), E5 Section 9.4, + * API return value coercion: custom. + */ + DUK_ASSERT_API_ENTRY(thr); + (void) duk__to_int_uint_helper(thr, idx, duk_js_tointeger); + return (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 0 /*require*/); +} + +DUK_EXTERNAL duk_int32_t duk_to_int32(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + duk_int32_t ret; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_require_tval(thr, idx); + DUK_ASSERT(tv != NULL); + ret = duk_js_toint32(thr, tv); + + /* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */ + tv = duk_require_tval(thr, idx); + DUK_TVAL_SET_I32_UPDREF(thr, tv, ret); /* side effects */ + return ret; +} + +DUK_EXTERNAL duk_uint32_t duk_to_uint32(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + duk_uint32_t ret; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_require_tval(thr, idx); + DUK_ASSERT(tv != NULL); + ret = duk_js_touint32(thr, tv); + + /* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */ + tv = duk_require_tval(thr, idx); + DUK_TVAL_SET_U32_UPDREF(thr, tv, ret); /* side effects */ + return ret; +} + +DUK_EXTERNAL duk_uint16_t duk_to_uint16(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + duk_uint16_t ret; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_require_tval(thr, idx); + DUK_ASSERT(tv != NULL); + ret = duk_js_touint16(thr, tv); + + /* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */ + tv = duk_require_tval(thr, idx); + DUK_TVAL_SET_U32_UPDREF(thr, tv, ret); /* side effects */ + return ret; +} + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +/* Special coercion for Uint8ClampedArray. */ +DUK_INTERNAL duk_uint8_t duk_to_uint8clamped(duk_hthread *thr, duk_idx_t idx) { + duk_double_t d; + duk_double_t t; + duk_uint8_t ret; + + DUK_ASSERT_API_ENTRY(thr); + + /* XXX: Simplify this algorithm, should be possible to come up with + * a shorter and faster algorithm by inspecting IEEE representation + * directly. + */ + + d = duk_to_number(thr, idx); + if (d <= 0.0) { + return 0; + } else if (d >= 255) { + return 255; + } else if (DUK_ISNAN(d)) { + /* Avoid NaN-to-integer coercion as it is compiler specific. */ + return 0; + } + + t = d - DUK_FLOOR(d); + if (duk_double_equals(t, 0.5)) { + /* Exact halfway, round to even. */ + ret = (duk_uint8_t) d; + ret = (ret + 1) & 0xfe; /* Example: d=3.5, t=0.5 -> ret = (3 + 1) & 0xfe = 4 & 0xfe = 4 + * Example: d=4.5, t=0.5 -> ret = (4 + 1) & 0xfe = 5 & 0xfe = 4 + */ + } else { + /* Not halfway, round to nearest. */ + ret = (duk_uint8_t) (d + 0.5); + } + return ret; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +DUK_EXTERNAL const char *duk_to_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) { + DUK_ASSERT_API_ENTRY(thr); + + (void) duk_to_string(thr, idx); + DUK_ASSERT(duk_is_string(thr, idx)); + return duk_require_lstring(thr, idx, out_len); +} + +DUK_LOCAL duk_ret_t duk__safe_to_string_raw(duk_hthread *thr, void *udata) { + DUK_CTX_ASSERT_VALID(thr); + DUK_UNREF(udata); + + (void) duk_to_string(thr, -1); + return 1; +} + +DUK_EXTERNAL const char *duk_safe_to_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) { + DUK_ASSERT_API_ENTRY(thr); + + idx = duk_require_normalize_index(thr, idx); + + /* We intentionally ignore the duk_safe_call() return value and only + * check the output type. This way we don't also need to check that + * the returned value is indeed a string in the success case. + */ + + duk_dup(thr, idx); + (void) duk_safe_call(thr, duk__safe_to_string_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/); + if (!duk_is_string(thr, -1)) { + /* Error: try coercing error to string once. */ + (void) duk_safe_call(thr, duk__safe_to_string_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/); + if (!duk_is_string(thr, -1)) { + /* Double error */ + duk_pop_unsafe(thr); + duk_push_hstring_stridx(thr, DUK_STRIDX_UC_ERROR); + } else { + ; + } + } else { + /* String; may be a symbol, accepted. */ + ; + } + DUK_ASSERT(duk_is_string(thr, -1)); + + duk_replace(thr, idx); + DUK_ASSERT(duk_get_string(thr, idx) != NULL); + return duk_get_lstring(thr, idx, out_len); +} + +DUK_EXTERNAL const char *duk_to_stacktrace(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + idx = duk_require_normalize_index(thr, idx); + + /* The expected argument to the call is an Error object. The stack + * trace is extracted without an inheritance-based instanceof check + * so that one can also extract the stack trace of a foreign error + * created in another Realm. Accept only a string .stack property. + */ + if (duk_is_object(thr, idx)) { + (void) duk_get_prop_string(thr, idx, "stack"); + if (duk_is_string(thr, -1)) { + duk_replace(thr, idx); + } else { + duk_pop(thr); + } + } + + return duk_to_string(thr, idx); +} + +DUK_LOCAL duk_ret_t duk__safe_to_stacktrace_raw(duk_hthread *thr, void *udata) { + DUK_CTX_ASSERT_VALID(thr); + DUK_UNREF(udata); + + (void) duk_to_stacktrace(thr, -1); + + return 1; +} + +DUK_EXTERNAL const char *duk_safe_to_stacktrace(duk_hthread *thr, duk_idx_t idx) { + duk_int_t rc; + + DUK_ASSERT_API_ENTRY(thr); + idx = duk_require_normalize_index(thr, idx); + + duk_dup(thr, idx); + rc = duk_safe_call(thr, duk__safe_to_stacktrace_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/); + if (rc != 0) { + /* Coercion failed. Try to coerce the coercion itself error + * to a stack trace once. If that also fails, return a fixed, + * preallocated 'Error' string to avoid potential infinite loop. + */ + rc = duk_safe_call(thr, duk__safe_to_stacktrace_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/); + if (rc != 0) { + duk_pop_unsafe(thr); + duk_push_hstring_stridx(thr, DUK_STRIDX_UC_ERROR); + } + } + duk_replace(thr, idx); + + return duk_get_string(thr, idx); +} + +DUK_INTERNAL duk_hstring *duk_to_property_key_hstring(duk_hthread *thr, duk_idx_t idx) { + duk_hstring *h; + + DUK_ASSERT_API_ENTRY(thr); + + duk_to_primitive(thr, idx, DUK_HINT_STRING); /* needed for e.g. Symbol objects */ + h = duk_get_hstring(thr, idx); + if (h == NULL) { + /* The "is string?" check may seem unnecessary, but as things + * are duk_to_hstring() invokes ToString() which fails for + * symbols. But since symbols are already strings for Duktape + * C API, we check for that before doing the coercion. + */ + h = duk_to_hstring(thr, idx); + } + DUK_ASSERT(h != NULL); + return h; +} + +#if defined(DUK_USE_DEBUGGER_SUPPORT) /* only needed by debugger for now */ +DUK_INTERNAL duk_hstring *duk_safe_to_hstring(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + + (void) duk_safe_to_string(thr, idx); + DUK_ASSERT(duk_is_string(thr, idx)); + DUK_ASSERT(duk_get_hstring(thr, idx) != NULL); + return duk_known_hstring(thr, idx); +} +#endif + +/* Push Object.prototype.toString() output for 'tv'. */ +DUK_INTERNAL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv, duk_bool_t avoid_side_effects) { + duk_hobject *h_obj; + duk_small_uint_t classnum; + duk_small_uint_t stridx; + duk_tval tv_tmp; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(tv != NULL); + + /* Stabilize 'tv', duk_push_literal() may trigger side effects. */ + DUK_TVAL_SET_TVAL(&tv_tmp, tv); + tv = &tv_tmp; + + /* Conceptually for any non-undefined/null value we should do a + * ToObject() coercion and look up @@toStringTag (from the object + * prototype) to see if a custom result should be used, with the + * exception of Arrays which are handled specially first. + * + * We'd like to avoid the actual conversion, but even for primitive + * types the prototype may have @@toStringTag. What's worse, the + * @@toStringTag property may be a getter that must get the object + * coerced value (not the prototype) as its 'this' binding. + * + * For now, do an actual object coercion. This could be avoided by + * doing a side effect free lookup to see if a getter would be invoked. + * If not, the value can be read directly and the object coercion could + * be avoided. This may not be worth it in practice, because + * Object.prototype.toString() is usually not performance critical. + */ + + duk_push_literal(thr, "[object "); /* -> [ ... "[object" ] */ + + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_UNUSED: /* Treat like 'undefined', shouldn't happen. */ + case DUK_TAG_UNDEFINED: { + duk_push_hstring_stridx(thr, DUK_STRIDX_UC_UNDEFINED); + goto finish; + } + case DUK_TAG_NULL: { + duk_push_hstring_stridx(thr, DUK_STRIDX_UC_NULL); + goto finish; + } + } + + duk_push_tval(thr, tv); + tv = NULL; /* Invalidated by ToObject(). */ + h_obj = duk_to_hobject(thr, -1); + DUK_ASSERT(h_obj != NULL); + if (duk_js_isarray_hobject(h_obj)) { + stridx = DUK_STRIDX_UC_ARRAY; + } else { + /* [ ... "[object" obj ] */ + +#if defined(DUK_USE_SYMBOL_BUILTIN) + /* XXX: better handling with avoid_side_effects == 1; lookup tval + * without Proxy or getter side effects, and use it in sanitized + * form if it's a string. + */ + if (!avoid_side_effects) { + (void) duk_get_prop_stridx(thr, -1, DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG); + if (duk_is_string_notsymbol(thr, -1)) { + duk_remove_m2(thr); + goto finish; + } + duk_pop_unsafe(thr); + } +#else + DUK_UNREF(avoid_side_effects); +#endif + + classnum = DUK_HOBJECT_GET_CLASS_NUMBER(h_obj); + stridx = DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum); + } + duk_pop_unsafe(thr); + duk_push_hstring_stridx(thr, stridx); + + finish: + /* [ ... "[object" tag ] */ + duk_push_literal(thr, "]"); + duk_concat(thr, 3); /* [ ... "[object" tag "]" ] -> [ ... res ] */ +} + +/* XXX: other variants like uint, u32 etc */ +DUK_INTERNAL duk_int_t duk_to_int_clamped_raw(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped) { + duk_tval *tv; + duk_tval tv_tmp; + duk_double_t d, dmin, dmax; + duk_int_t res; + duk_bool_t clamped = 0; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_require_tval(thr, idx); + DUK_ASSERT(tv != NULL); + d = duk_js_tointeger(thr, tv); /* E5 Section 9.4, ToInteger() */ + + dmin = (duk_double_t) minval; + dmax = (duk_double_t) maxval; + + if (d < dmin) { + clamped = 1; + res = minval; + d = dmin; + } else if (d > dmax) { + clamped = 1; + res = maxval; + d = dmax; + } else { + res = (duk_int_t) d; + } + DUK_UNREF(d); /* SCANBUILD: with suitable dmin/dmax limits 'd' is unused */ + /* 'd' and 'res' agree here */ + + /* Relookup in case duk_js_tointeger() ends up e.g. coercing an object. */ + tv = duk_get_tval(thr, idx); + DUK_ASSERT(tv != NULL); /* not popped by side effect */ + DUK_TVAL_SET_TVAL(&tv_tmp, tv); +#if defined(DUK_USE_FASTINT) +#if (DUK_INT_MAX <= 0x7fffffffL) + DUK_TVAL_SET_I32(tv, res); +#else + /* Clamping needed if duk_int_t is 64 bits. */ + if (res >= DUK_FASTINT_MIN && res <= DUK_FASTINT_MAX) { + DUK_TVAL_SET_FASTINT(tv, res); + } else { + DUK_TVAL_SET_NUMBER(tv, d); + } +#endif +#else + DUK_TVAL_SET_NUMBER(tv, d); /* no need to incref */ +#endif + DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */ + + if (out_clamped) { + *out_clamped = clamped; + } else { + /* coerced value is updated to value stack even when RangeError thrown */ + if (clamped) { + DUK_ERROR_RANGE(thr, DUK_STR_NUMBER_OUTSIDE_RANGE); + DUK_WO_NORETURN(return 0;); + } + } + + return res; +} + +DUK_INTERNAL duk_int_t duk_to_int_clamped(duk_hthread *thr, duk_idx_t idx, duk_idx_t minval, duk_idx_t maxval) { + duk_bool_t dummy; + + DUK_ASSERT_API_ENTRY(thr); + + return duk_to_int_clamped_raw(thr, idx, minval, maxval, &dummy); +} + +DUK_INTERNAL duk_int_t duk_to_int_check_range(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval) { + DUK_ASSERT_API_ENTRY(thr); + return duk_to_int_clamped_raw(thr, idx, minval, maxval, NULL); /* out_clamped==NULL -> RangeError if outside range */ +} + +DUK_EXTERNAL const char *duk_to_string(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + idx = duk_require_normalize_index(thr, idx); + tv = DUK_GET_TVAL_POSIDX(thr, idx); + DUK_ASSERT(tv != NULL); + + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_UNDEFINED: { + duk_push_hstring_stridx(thr, DUK_STRIDX_LC_UNDEFINED); + break; + } + case DUK_TAG_NULL: { + duk_push_hstring_stridx(thr, DUK_STRIDX_LC_NULL); + break; + } + case DUK_TAG_BOOLEAN: { + if (DUK_TVAL_GET_BOOLEAN(tv)) { + duk_push_hstring_stridx(thr, DUK_STRIDX_TRUE); + } else { + duk_push_hstring_stridx(thr, DUK_STRIDX_FALSE); + } + break; + } + case DUK_TAG_STRING: { + /* Nop for actual strings, TypeError for Symbols. + * Because various internals rely on ToString() coercion of + * internal strings, -allow- (NOP) string coercion for hidden + * symbols. + */ +#if 1 + duk_hstring *h; + h = DUK_TVAL_GET_STRING(tv); + DUK_ASSERT(h != NULL); + if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) { + DUK_ERROR_TYPE(thr, DUK_STR_CANNOT_STRING_COERCE_SYMBOL); + DUK_WO_NORETURN(goto skip_replace;); + } else { + goto skip_replace; + } +#else + goto skip_replace; +#endif + break; + } + case DUK_TAG_BUFFER: /* Go through Uint8Array.prototype.toString() for coercion. */ + case DUK_TAG_OBJECT: { + /* Plain buffers: go through ArrayBuffer.prototype.toString() + * for coercion. + * + * Symbol objects: duk_to_primitive() results in a plain symbol + * value, and duk_to_string() then causes a TypeError. + */ + duk_to_primitive(thr, idx, DUK_HINT_STRING); + DUK_ASSERT(!duk_is_buffer(thr, idx)); /* ToPrimitive() must guarantee */ + DUK_ASSERT(!duk_is_object(thr, idx)); + return duk_to_string(thr, idx); /* Note: recursive call */ + } + case DUK_TAG_POINTER: { + void *ptr = DUK_TVAL_GET_POINTER(tv); + if (ptr != NULL) { + duk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) ptr); + } else { + /* Represent a null pointer as 'null' to be consistent with + * the JX format variant. Native '%p' format for a NULL + * pointer may be e.g. '(nil)'. + */ + duk_push_hstring_stridx(thr, DUK_STRIDX_LC_NULL); + } + break; + } + case DUK_TAG_LIGHTFUNC: { + /* Should match Function.prototype.toString() */ + duk_push_lightfunc_tostring(thr, tv); + break; + } +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: +#endif + default: { + /* number */ + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv)); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); + duk_push_tval(thr, tv); + duk_numconv_stringify(thr, + 10 /*radix*/, + 0 /*precision:shortest*/, + 0 /*force_exponential*/); + break; + } + } + + duk_replace(thr, idx); + + skip_replace: + DUK_ASSERT(duk_is_string(thr, idx)); + return duk_require_string(thr, idx); +} + +DUK_INTERNAL duk_hstring *duk_to_hstring(duk_hthread *thr, duk_idx_t idx) { + duk_hstring *ret; + + DUK_ASSERT_API_ENTRY(thr); + + duk_to_string(thr, idx); + ret = duk_get_hstring(thr, idx); + DUK_ASSERT(ret != NULL); + return ret; +} + +DUK_INTERNAL duk_hstring *duk_to_hstring_m1(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + return duk_to_hstring(thr, -1); +} + +DUK_INTERNAL duk_hstring *duk_to_hstring_acceptsymbol(duk_hthread *thr, duk_idx_t idx) { + duk_hstring *ret; + + DUK_ASSERT_API_ENTRY(thr); + + ret = duk_get_hstring(thr, idx); + if (DUK_UNLIKELY(ret && DUK_HSTRING_HAS_SYMBOL(ret))) { + return ret; + } + return duk_to_hstring(thr, idx); +} + +/* Convert a plain buffer or any buffer object into a string, using the buffer + * bytes 1:1 in the internal string representation. For views the active byte + * slice (not element slice interpreted as an initializer) is used. This is + * necessary in Duktape 2.x because ToString(plainBuffer) no longer creates a + * string with the same bytes as in the buffer but rather (usually) + * '[object ArrayBuffer]'. + */ +DUK_EXTERNAL const char *duk_buffer_to_string(duk_hthread *thr, duk_idx_t idx) { + void *ptr_src; + duk_size_t len; + const char *res; + + DUK_ASSERT_API_ENTRY(thr); + + idx = duk_require_normalize_index(thr, idx); + + ptr_src = duk_require_buffer_data(thr, idx, &len); + DUK_ASSERT(ptr_src != NULL || len == 0); + + res = duk_push_lstring(thr, (const char *) ptr_src, len); + duk_replace(thr, idx); + return res; +} + +DUK_EXTERNAL void *duk_to_buffer_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, duk_uint_t mode) { + duk_hbuffer *h_buf; + const duk_uint8_t *src_data; + duk_size_t src_size; + duk_uint8_t *dst_data; + + DUK_ASSERT_API_ENTRY(thr); + + idx = duk_require_normalize_index(thr, idx); + + h_buf = duk_get_hbuffer(thr, idx); + if (h_buf != NULL) { + /* Buffer is kept as is, with the fixed/dynamic nature of the + * buffer only changed if requested. An external buffer + * is converted into a non-external dynamic buffer in a + * duk_to_dynamic_buffer() call. + */ + duk_uint_t tmp; + duk_uint8_t *tmp_ptr; + + tmp_ptr = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_buf); + src_data = (const duk_uint8_t *) tmp_ptr; + src_size = DUK_HBUFFER_GET_SIZE(h_buf); + + tmp = (DUK_HBUFFER_HAS_DYNAMIC(h_buf) ? DUK_BUF_MODE_DYNAMIC : DUK_BUF_MODE_FIXED); + if ((tmp == mode && !DUK_HBUFFER_HAS_EXTERNAL(h_buf)) || + mode == DUK_BUF_MODE_DONTCARE) { + /* Note: src_data may be NULL if input is a zero-size + * dynamic buffer. + */ + dst_data = tmp_ptr; + goto skip_copy; + } + } else { + /* Non-buffer value is first ToString() coerced, then converted + * to a buffer (fixed buffer is used unless a dynamic buffer is + * explicitly requested). Symbols are rejected with a TypeError. + * XXX: C API could maybe allow symbol-to-buffer coercion? + */ + src_data = (const duk_uint8_t *) duk_to_lstring(thr, idx, &src_size); + } + + dst_data = (duk_uint8_t *) duk_push_buffer(thr, src_size, (mode == DUK_BUF_MODE_DYNAMIC) /*dynamic*/); + /* dst_data may be NULL if size is zero. */ + duk_memcpy_unsafe((void *) dst_data, (const void *) src_data, (size_t) src_size); + + duk_replace(thr, idx); + skip_copy: + + if (out_size) { + *out_size = src_size; + } + return dst_data; +} + +DUK_EXTERNAL void *duk_to_pointer(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + void *res; + + DUK_ASSERT_API_ENTRY(thr); + + idx = duk_require_normalize_index(thr, idx); + tv = DUK_GET_TVAL_POSIDX(thr, idx); + DUK_ASSERT(tv != NULL); + + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_UNDEFINED: + case DUK_TAG_NULL: + case DUK_TAG_BOOLEAN: + res = NULL; + break; + case DUK_TAG_POINTER: + res = DUK_TVAL_GET_POINTER(tv); + break; + case DUK_TAG_STRING: + case DUK_TAG_OBJECT: + case DUK_TAG_BUFFER: + /* Heap allocated: return heap pointer which is NOT useful + * for the caller, except for debugging. + */ + res = (void *) DUK_TVAL_GET_HEAPHDR(tv); + break; + case DUK_TAG_LIGHTFUNC: + /* Function pointers do not always cast correctly to void * + * (depends on memory and segmentation model for instance), + * so they coerce to NULL. + */ + res = NULL; + break; +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: +#endif + default: + /* number */ + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv)); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); + res = NULL; + break; + } + + duk_push_pointer(thr, res); + duk_replace(thr, idx); + return res; +} + +DUK_LOCAL void duk__push_func_from_lightfunc(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags) { + duk_idx_t nargs; + duk_uint_t flags = 0; /* shared flags for a subset of types */ + duk_small_uint_t lf_len; + duk_hnatfunc *nf; + + nargs = (duk_idx_t) DUK_LFUNC_FLAGS_GET_NARGS(lf_flags); + if (nargs == DUK_LFUNC_NARGS_VARARGS) { + nargs = (duk_idx_t) DUK_VARARGS; + } + + flags = DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_CONSTRUCTABLE | + DUK_HOBJECT_FLAG_CALLABLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_FLAG_NATFUNC | + DUK_HOBJECT_FLAG_NEWENV | + DUK_HOBJECT_FLAG_STRICT | + DUK_HOBJECT_FLAG_NOTAIL | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION); + (void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE); + + lf_len = DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags); + if ((duk_idx_t) lf_len != nargs) { + /* Explicit length is only needed if it differs from 'nargs'. */ + duk_push_int(thr, (duk_int_t) lf_len); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_NONE); + } + +#if defined(DUK_USE_FUNC_NAME_PROPERTY) + duk_push_lightfunc_name_raw(thr, func, lf_flags); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C); +#endif + + nf = duk_known_hnatfunc(thr, -1); + nf->magic = (duk_int16_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags); +} + +DUK_EXTERNAL void duk_to_object(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + duk_uint_t flags = 0; /* shared flags for a subset of types */ + duk_small_int_t proto = 0; + + DUK_ASSERT_API_ENTRY(thr); + + idx = duk_require_normalize_index(thr, idx); + tv = DUK_GET_TVAL_POSIDX(thr, idx); + DUK_ASSERT(tv != NULL); + + switch (DUK_TVAL_GET_TAG(tv)) { +#if !defined(DUK_USE_BUFFEROBJECT_SUPPORT) + case DUK_TAG_BUFFER: /* With no bufferobject support, don't object coerce. */ +#endif + case DUK_TAG_UNDEFINED: + case DUK_TAG_NULL: { + DUK_ERROR_TYPE(thr, DUK_STR_NOT_OBJECT_COERCIBLE); + DUK_WO_NORETURN(return;); + break; + } + case DUK_TAG_BOOLEAN: { + flags = DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_BOOLEAN); + proto = DUK_BIDX_BOOLEAN_PROTOTYPE; + goto create_object; + } + case DUK_TAG_STRING: { + duk_hstring *h; + h = DUK_TVAL_GET_STRING(tv); + DUK_ASSERT(h != NULL); + if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) { + flags = DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_SYMBOL); + proto = DUK_BIDX_SYMBOL_PROTOTYPE; + } else { + flags = DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_STRING); + proto = DUK_BIDX_STRING_PROTOTYPE; + } + goto create_object; + } + case DUK_TAG_OBJECT: { + /* nop */ + break; + } +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + case DUK_TAG_BUFFER: { + /* A plain buffer object coerces to a full ArrayBuffer which + * is not fully transparent behavior (ToObject() should be a + * nop for an object). This behavior matches lightfuncs which + * also coerce to an equivalent Function object. There are + * also downsides to defining ToObject(plainBuffer) as a no-op; + * for example duk_to_hobject() could result in a NULL pointer. + */ + duk_hbuffer *h_buf; + + h_buf = DUK_TVAL_GET_BUFFER(tv); + DUK_ASSERT(h_buf != NULL); + duk_hbufobj_push_uint8array_from_plain(thr, h_buf); + goto replace_value; + } +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + case DUK_TAG_POINTER: { + flags = DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_POINTER); + proto = DUK_BIDX_POINTER_PROTOTYPE; + goto create_object; + } + case DUK_TAG_LIGHTFUNC: { + /* Lightfunc coerces to a Function instance with concrete + * properties. Since 'length' is virtual for Duktape/C + * functions, don't need to define that. The result is made + * extensible to mimic what happens to strings in object + * coercion: + * + * > Object.isExtensible(Object('foo')) + * true + */ + duk_small_uint_t lf_flags; + duk_c_function func; + + DUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags); + duk__push_func_from_lightfunc(thr, func, lf_flags); + goto replace_value; + } +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: +#endif + default: { + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv)); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); + flags = DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_NUMBER); + proto = DUK_BIDX_NUMBER_PROTOTYPE; + goto create_object; + } + } + DUK_ASSERT(duk_is_object(thr, idx)); + return; + + create_object: + (void) duk_push_object_helper(thr, flags, proto); + + /* Note: Boolean prototype's internal value property is not writable, + * but duk_xdef_prop_stridx() disregards the write protection. Boolean + * instances are immutable. + * + * String and buffer special behaviors are already enabled which is not + * ideal, but a write to the internal value is not affected by them. + */ + duk_dup(thr, idx); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); + + replace_value: + duk_replace(thr, idx); + DUK_ASSERT(duk_is_object(thr, idx)); +} + +DUK_INTERNAL duk_hobject *duk_to_hobject(duk_hthread *thr, duk_idx_t idx) { + duk_hobject *ret; + + DUK_ASSERT_API_ENTRY(thr); + + duk_to_object(thr, idx); + ret = duk_known_hobject(thr, idx); + return ret; +} + +/* + * Type checking + */ + +DUK_LOCAL duk_bool_t duk__tag_check(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t tag) { + duk_tval *tv; + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + return (DUK_TVAL_GET_TAG(tv) == tag); +} + +DUK_LOCAL duk_bool_t duk__obj_flag_any_default_false(duk_hthread *thr, duk_idx_t idx, duk_uint_t flag_mask) { + duk_hobject *obj; + + DUK_ASSERT_API_ENTRY(thr); + + obj = duk_get_hobject(thr, idx); + if (obj) { + return (DUK_HEAPHDR_CHECK_FLAG_BITS((duk_heaphdr *) obj, flag_mask) ? 1 : 0); + } + return 0; +} + +DUK_INTERNAL duk_int_t duk_get_type_tval(duk_tval *tv) { + DUK_ASSERT(tv != NULL); + +#if defined(DUK_USE_PACKED_TVAL) + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_UNUSED: + return DUK_TYPE_NONE; + case DUK_TAG_UNDEFINED: + return DUK_TYPE_UNDEFINED; + case DUK_TAG_NULL: + return DUK_TYPE_NULL; + case DUK_TAG_BOOLEAN: + return DUK_TYPE_BOOLEAN; + case DUK_TAG_STRING: + return DUK_TYPE_STRING; + case DUK_TAG_OBJECT: + return DUK_TYPE_OBJECT; + case DUK_TAG_BUFFER: + return DUK_TYPE_BUFFER; + case DUK_TAG_POINTER: + return DUK_TYPE_POINTER; + case DUK_TAG_LIGHTFUNC: + return DUK_TYPE_LIGHTFUNC; +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: +#endif + default: + /* Note: number has no explicit tag (in 8-byte representation) */ + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv)); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); + return DUK_TYPE_NUMBER; + } +#else /* DUK_USE_PACKED_TVAL */ + DUK_ASSERT(DUK_TVAL_IS_VALID_TAG(tv)); + DUK_ASSERT(sizeof(duk__type_from_tag) / sizeof(duk_uint_t) == DUK_TAG_MAX - DUK_TAG_MIN + 1); + return (duk_int_t) duk__type_from_tag[DUK_TVAL_GET_TAG(tv) - DUK_TAG_MIN]; +#endif /* DUK_USE_PACKED_TVAL */ +} + +DUK_EXTERNAL duk_int_t duk_get_type(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + + return duk_get_type_tval(tv); +} + +#if defined(DUK_USE_VERBOSE_ERRORS) && defined(DUK_USE_PARANOID_ERRORS) +DUK_LOCAL const char * const duk__type_names[] = { + "none", + "undefined", + "null", + "boolean", + "number", + "string", + "object", + "buffer", + "pointer", + "lightfunc" +}; + +DUK_INTERNAL const char *duk_get_type_name(duk_hthread *thr, duk_idx_t idx) { + duk_int_t type_tag; + + DUK_ASSERT_API_ENTRY(thr); + + type_tag = duk_get_type(thr, idx); + DUK_ASSERT(type_tag >= DUK_TYPE_MIN && type_tag <= DUK_TYPE_MAX); + DUK_ASSERT(DUK_TYPE_MIN == 0 && sizeof(duk__type_names) / sizeof(const char *) == DUK_TYPE_MAX + 1); + + return duk__type_names[type_tag]; +} +#endif /* DUK_USE_VERBOSE_ERRORS && DUK_USE_PARANOID_ERRORS */ + +DUK_INTERNAL duk_small_uint_t duk_get_class_number(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + duk_hobject *obj; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_OBJECT: + obj = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(obj != NULL); + return DUK_HOBJECT_GET_CLASS_NUMBER(obj); + case DUK_TAG_BUFFER: + /* Buffers behave like Uint8Array objects. */ + return DUK_HOBJECT_CLASS_UINT8ARRAY; + case DUK_TAG_LIGHTFUNC: + /* Lightfuncs behave like Function objects. */ + return DUK_HOBJECT_CLASS_FUNCTION; + default: + /* Primitive or UNUSED, no class number. */ + return DUK_HOBJECT_CLASS_NONE; + } +} + +DUK_EXTERNAL duk_bool_t duk_check_type(duk_hthread *thr, duk_idx_t idx, duk_int_t type) { + DUK_ASSERT_API_ENTRY(thr); + + return (duk_get_type(thr, idx) == type) ? 1 : 0; +} + +DUK_INTERNAL duk_uint_t duk_get_type_mask_tval(duk_tval *tv) { + DUK_ASSERT(tv != NULL); + +#if defined(DUK_USE_PACKED_TVAL) + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_UNUSED: + return DUK_TYPE_MASK_NONE; + case DUK_TAG_UNDEFINED: + return DUK_TYPE_MASK_UNDEFINED; + case DUK_TAG_NULL: + return DUK_TYPE_MASK_NULL; + case DUK_TAG_BOOLEAN: + return DUK_TYPE_MASK_BOOLEAN; + case DUK_TAG_STRING: + return DUK_TYPE_MASK_STRING; + case DUK_TAG_OBJECT: + return DUK_TYPE_MASK_OBJECT; + case DUK_TAG_BUFFER: + return DUK_TYPE_MASK_BUFFER; + case DUK_TAG_POINTER: + return DUK_TYPE_MASK_POINTER; + case DUK_TAG_LIGHTFUNC: + return DUK_TYPE_MASK_LIGHTFUNC; +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: +#endif + default: + /* Note: number has no explicit tag (in 8-byte representation) */ + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv)); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); + return DUK_TYPE_MASK_NUMBER; + } +#else /* DUK_USE_PACKED_TVAL */ + DUK_ASSERT(DUK_TVAL_IS_VALID_TAG(tv)); + DUK_ASSERT(sizeof(duk__type_mask_from_tag) / sizeof(duk_uint_t) == DUK_TAG_MAX - DUK_TAG_MIN + 1); + return duk__type_mask_from_tag[DUK_TVAL_GET_TAG(tv) - DUK_TAG_MIN]; +#endif /* DUK_USE_PACKED_TVAL */ +} + +DUK_EXTERNAL duk_uint_t duk_get_type_mask(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + + return duk_get_type_mask_tval(tv); +} + +DUK_EXTERNAL duk_bool_t duk_check_type_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t mask) { + DUK_ASSERT_API_ENTRY(thr); + + if (DUK_LIKELY((duk_get_type_mask(thr, idx) & mask) != 0U)) { + return 1; + } + if (mask & DUK_TYPE_MASK_THROW) { + DUK_ERROR_TYPE(thr, DUK_STR_UNEXPECTED_TYPE); + DUK_WO_NORETURN(return 0;); + } + return 0; +} + +DUK_EXTERNAL duk_bool_t duk_is_undefined(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return duk__tag_check(thr, idx, DUK_TAG_UNDEFINED); +} + +DUK_EXTERNAL duk_bool_t duk_is_null(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return duk__tag_check(thr, idx, DUK_TAG_NULL); +} + +DUK_EXTERNAL duk_bool_t duk_is_boolean(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return duk__tag_check(thr, idx, DUK_TAG_BOOLEAN); +} + +DUK_EXTERNAL duk_bool_t duk_is_number(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + /* + * Number is special because it doesn't have a specific + * tag in the 8-byte representation. + */ + + /* XXX: shorter version for unpacked representation? */ + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + return DUK_TVAL_IS_NUMBER(tv); +} + +DUK_EXTERNAL duk_bool_t duk_is_nan(duk_hthread *thr, duk_idx_t idx) { + /* XXX: This will now return false for non-numbers, even though they would + * coerce to NaN (as a general rule). In particular, duk_get_number() + * returns a NaN for non-numbers, so should this function also return + * true for non-numbers? + */ + + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + + /* XXX: for packed duk_tval an explicit "is number" check is unnecessary */ + if (!DUK_TVAL_IS_NUMBER(tv)) { + return 0; + } + return (duk_bool_t) DUK_ISNAN(DUK_TVAL_GET_NUMBER(tv)); +} + +DUK_EXTERNAL duk_bool_t duk_is_string(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return duk__tag_check(thr, idx, DUK_TAG_STRING); +} + +DUK_INTERNAL duk_bool_t duk_is_string_notsymbol(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return duk_get_hstring_notsymbol(thr, idx) != NULL; +} + +DUK_EXTERNAL duk_bool_t duk_is_object(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return duk__tag_check(thr, idx, DUK_TAG_OBJECT); +} + +DUK_EXTERNAL duk_bool_t duk_is_buffer(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return duk__tag_check(thr, idx, DUK_TAG_BUFFER); +} + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_EXTERNAL duk_bool_t duk_is_buffer_data(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (DUK_TVAL_IS_BUFFER(tv)) { + return 1; + } else if (DUK_TVAL_IS_OBJECT(tv)) { + duk_hobject *h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + if (DUK_HOBJECT_IS_BUFOBJ(h)) { + return 1; + } + } + return 0; +} +#else /* DUK_USE_BUFFEROBJECT_SUPPORT */ +DUK_EXTERNAL duk_bool_t duk_is_buffer_data(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + + return duk_is_buffer(thr, idx); +} + +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +DUK_EXTERNAL duk_bool_t duk_is_pointer(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return duk__tag_check(thr, idx, DUK_TAG_POINTER); +} + +DUK_EXTERNAL duk_bool_t duk_is_lightfunc(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return duk__tag_check(thr, idx, DUK_TAG_LIGHTFUNC); +} + +DUK_EXTERNAL duk_bool_t duk_is_symbol(duk_hthread *thr, duk_idx_t idx) { + duk_hstring *h; + + DUK_ASSERT_API_ENTRY(thr); + h = duk_get_hstring(thr, idx); + /* Use DUK_LIKELY() here because caller may be more likely to type + * check an expected symbol than not. + */ + if (DUK_LIKELY(h != NULL && DUK_HSTRING_HAS_SYMBOL(h))) { + return 1; + } + return 0; +} + +/* IsArray(), returns true for Array instance or Proxy of Array instance. */ +DUK_EXTERNAL duk_bool_t duk_is_array(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval(thr, idx); + if (tv) { + return duk_js_isarray(tv); + } + return 0; +} + +DUK_EXTERNAL duk_bool_t duk_is_function(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + if (DUK_TVAL_IS_OBJECT(tv)) { + duk_hobject *h; + h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + return DUK_HOBJECT_HAS_CALLABLE(h) ? 1 : 0; + } + if (DUK_TVAL_IS_LIGHTFUNC(tv)) { + return 1; + } + return 0; +} + +DUK_INTERNAL duk_bool_t duk_is_callable_tval(duk_hthread *thr, duk_tval *tv) { + DUK_ASSERT_API_ENTRY(thr); + + DUK_UNREF(thr); + + if (DUK_TVAL_IS_OBJECT(tv)) { + duk_hobject *h; + h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + return DUK_HOBJECT_HAS_CALLABLE(h) ? 1 : 0; + } + if (DUK_TVAL_IS_LIGHTFUNC(tv)) { + return 1; + } + return 0; +} + +DUK_EXTERNAL duk_bool_t duk_is_constructable(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + if (DUK_TVAL_IS_OBJECT(tv)) { + duk_hobject *h; + h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + return DUK_HOBJECT_HAS_CONSTRUCTABLE(h) ? 1 : 0; + } + if (DUK_TVAL_IS_LIGHTFUNC(tv)) { + return 1; + } + return 0; +} + +DUK_EXTERNAL duk_bool_t duk_is_c_function(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return duk__obj_flag_any_default_false(thr, + idx, + DUK_HOBJECT_FLAG_NATFUNC); +} + +DUK_EXTERNAL duk_bool_t duk_is_ecmascript_function(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return duk__obj_flag_any_default_false(thr, + idx, + DUK_HOBJECT_FLAG_COMPFUNC); +} + +DUK_EXTERNAL duk_bool_t duk_is_bound_function(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return duk__obj_flag_any_default_false(thr, + idx, + DUK_HOBJECT_FLAG_BOUNDFUNC); +} + +DUK_EXTERNAL duk_bool_t duk_is_thread(duk_hthread *thr, duk_idx_t idx) { + duk_hobject *obj; + + DUK_ASSERT_API_ENTRY(thr); + + obj = duk_get_hobject(thr, idx); + if (obj) { + return (DUK_HOBJECT_GET_CLASS_NUMBER(obj) == DUK_HOBJECT_CLASS_THREAD ? 1 : 0); + } + return 0; +} + +DUK_EXTERNAL duk_bool_t duk_is_fixed_buffer(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (DUK_TVAL_IS_BUFFER(tv)) { + duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv); + DUK_ASSERT(h != NULL); + return (DUK_HBUFFER_HAS_DYNAMIC(h) ? 0 : 1); + } + return 0; +} + +DUK_EXTERNAL duk_bool_t duk_is_dynamic_buffer(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (DUK_TVAL_IS_BUFFER(tv)) { + duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv); + DUK_ASSERT(h != NULL); + return (DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h) ? 1 : 0); + } + return 0; +} + +DUK_EXTERNAL duk_bool_t duk_is_external_buffer(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_get_tval_or_unused(thr, idx); + DUK_ASSERT(tv != NULL); + if (DUK_TVAL_IS_BUFFER(tv)) { + duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv); + DUK_ASSERT(h != NULL); + return (DUK_HBUFFER_HAS_DYNAMIC(h) && DUK_HBUFFER_HAS_EXTERNAL(h) ? 1 : 0); + } + return 0; +} + +DUK_EXTERNAL duk_errcode_t duk_get_error_code(duk_hthread *thr, duk_idx_t idx) { + duk_hobject *h; + duk_uint_t sanity; + + DUK_ASSERT_API_ENTRY(thr); + + h = duk_get_hobject(thr, idx); + + sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY; + do { + if (!h) { + return DUK_ERR_NONE; + } + + /* XXX: something more convenient? */ + + if (h == thr->builtins[DUK_BIDX_EVAL_ERROR_PROTOTYPE]) { + return DUK_ERR_EVAL_ERROR; + } + if (h == thr->builtins[DUK_BIDX_RANGE_ERROR_PROTOTYPE]) { + return DUK_ERR_RANGE_ERROR; + } + if (h == thr->builtins[DUK_BIDX_REFERENCE_ERROR_PROTOTYPE]) { + return DUK_ERR_REFERENCE_ERROR; + } + if (h == thr->builtins[DUK_BIDX_SYNTAX_ERROR_PROTOTYPE]) { + return DUK_ERR_SYNTAX_ERROR; + } + if (h == thr->builtins[DUK_BIDX_TYPE_ERROR_PROTOTYPE]) { + return DUK_ERR_TYPE_ERROR; + } + if (h == thr->builtins[DUK_BIDX_URI_ERROR_PROTOTYPE]) { + return DUK_ERR_URI_ERROR; + } + if (h == thr->builtins[DUK_BIDX_ERROR_PROTOTYPE]) { + return DUK_ERR_ERROR; + } + + h = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h); + } while (--sanity > 0); + + return DUK_ERR_NONE; +} + +/* + * Pushers + */ + +DUK_INTERNAL void duk_push_tval(duk_hthread *thr, duk_tval *tv) { + duk_tval *tv_slot; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(tv != NULL); + + DUK__CHECK_SPACE(); + tv_slot = thr->valstack_top++; + DUK_TVAL_SET_TVAL(tv_slot, tv); + DUK_TVAL_INCREF(thr, tv); /* no side effects */ +} + +DUK_EXTERNAL void duk_push_undefined(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + + DUK__CHECK_SPACE(); + + /* Because value stack init policy is 'undefined above top', + * we don't need to write, just assert. + */ + thr->valstack_top++; + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1)); +} + +DUK_EXTERNAL void duk_push_null(duk_hthread *thr) { + duk_tval *tv_slot; + + DUK_ASSERT_API_ENTRY(thr); + DUK__CHECK_SPACE(); + tv_slot = thr->valstack_top++; + DUK_TVAL_SET_NULL(tv_slot); +} + +DUK_EXTERNAL void duk_push_boolean(duk_hthread *thr, duk_bool_t val) { + duk_tval *tv_slot; + duk_small_int_t b; + + DUK_ASSERT_API_ENTRY(thr); + DUK__CHECK_SPACE(); + b = (val ? 1 : 0); /* ensure value is 1 or 0 (not other non-zero) */ + tv_slot = thr->valstack_top++; + DUK_TVAL_SET_BOOLEAN(tv_slot, b); +} + +DUK_EXTERNAL void duk_push_true(duk_hthread *thr) { + duk_tval *tv_slot; + + DUK_ASSERT_API_ENTRY(thr); + DUK__CHECK_SPACE(); + tv_slot = thr->valstack_top++; + DUK_TVAL_SET_BOOLEAN_TRUE(tv_slot); +} + +DUK_EXTERNAL void duk_push_false(duk_hthread *thr) { + duk_tval *tv_slot; + + DUK_ASSERT_API_ENTRY(thr); + DUK__CHECK_SPACE(); + tv_slot = thr->valstack_top++; + DUK_TVAL_SET_BOOLEAN_FALSE(tv_slot); +} + +/* normalize NaN which may not match our canonical internal NaN */ +DUK_EXTERNAL void duk_push_number(duk_hthread *thr, duk_double_t val) { + duk_tval *tv_slot; + duk_double_union du; + + DUK_ASSERT_API_ENTRY(thr); + DUK__CHECK_SPACE(); + du.d = val; + DUK_DBLUNION_NORMALIZE_NAN_CHECK(&du); + tv_slot = thr->valstack_top++; + DUK_TVAL_SET_NUMBER(tv_slot, du.d); +} + +DUK_EXTERNAL void duk_push_int(duk_hthread *thr, duk_int_t val) { +#if defined(DUK_USE_FASTINT) + duk_tval *tv_slot; + + DUK_ASSERT_API_ENTRY(thr); + DUK__CHECK_SPACE(); + tv_slot = thr->valstack_top++; +#if DUK_INT_MAX <= 0x7fffffffL + DUK_TVAL_SET_I32(tv_slot, (duk_int32_t) val); +#else + if (val >= DUK_FASTINT_MIN && val <= DUK_FASTINT_MAX) { + DUK_TVAL_SET_FASTINT(tv_slot, (duk_int64_t) val); + } else { + duk_double_t = (duk_double_t) val; + DUK_TVAL_SET_NUMBER(tv_slot, d); + } +#endif +#else /* DUK_USE_FASTINT */ + duk_tval *tv_slot; + duk_double_t d; + + DUK_ASSERT_API_ENTRY(thr); + DUK__CHECK_SPACE(); + d = (duk_double_t) val; + tv_slot = thr->valstack_top++; + DUK_TVAL_SET_NUMBER(tv_slot, d); +#endif /* DUK_USE_FASTINT */ +} + +DUK_EXTERNAL void duk_push_uint(duk_hthread *thr, duk_uint_t val) { +#if defined(DUK_USE_FASTINT) + duk_tval *tv_slot; + + DUK_ASSERT_API_ENTRY(thr); + DUK__CHECK_SPACE(); + tv_slot = thr->valstack_top++; +#if DUK_UINT_MAX <= 0xffffffffUL + DUK_TVAL_SET_U32(tv_slot, (duk_uint32_t) val); +#else + if (val <= DUK_FASTINT_MAX) { /* val is unsigned so >= 0 */ + /* XXX: take advantage of val being unsigned, no need to mask */ + DUK_TVAL_SET_FASTINT(tv_slot, (duk_int64_t) val); + } else { + duk_double_t = (duk_double_t) val; + DUK_TVAL_SET_NUMBER(tv_slot, d); + } +#endif +#else /* DUK_USE_FASTINT */ + duk_tval *tv_slot; + duk_double_t d; + + DUK_ASSERT_API_ENTRY(thr); + DUK__CHECK_SPACE(); + d = (duk_double_t) val; + tv_slot = thr->valstack_top++; + DUK_TVAL_SET_NUMBER(tv_slot, d); +#endif /* DUK_USE_FASTINT */ +} + +DUK_EXTERNAL void duk_push_nan(duk_hthread *thr) { + duk_tval *tv_slot; + duk_double_union du; + + DUK_ASSERT_API_ENTRY(thr); + DUK__CHECK_SPACE(); + DUK_DBLUNION_SET_NAN(&du); + DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du)); + tv_slot = thr->valstack_top++; + DUK_TVAL_SET_NUMBER(tv_slot, du.d); +} + +DUK_EXTERNAL const char *duk_push_lstring(duk_hthread *thr, const char *str, duk_size_t len) { + duk_hstring *h; + duk_tval *tv_slot; + + DUK_ASSERT_API_ENTRY(thr); + + /* Check stack before interning (avoid hanging temp). */ + DUK__CHECK_SPACE(); + + /* NULL with zero length represents an empty string; NULL with higher + * length is also now treated like an empty string although it is + * a bit dubious. This is unlike duk_push_string() which pushes a + * 'null' if the input string is a NULL. + */ + if (DUK_UNLIKELY(str == NULL)) { + len = 0U; + } + + /* Check for maximum string length. */ + if (DUK_UNLIKELY(len > DUK_HSTRING_MAX_BYTELEN)) { + DUK_ERROR_RANGE(thr, DUK_STR_STRING_TOO_LONG); + DUK_WO_NORETURN(return NULL;); + } + + h = duk_heap_strtable_intern_checked(thr, (const duk_uint8_t *) str, (duk_uint32_t) len); + DUK_ASSERT(h != NULL); + + tv_slot = thr->valstack_top++; + DUK_TVAL_SET_STRING(tv_slot, h); + DUK_HSTRING_INCREF(thr, h); /* no side effects */ + + return (const char *) DUK_HSTRING_GET_DATA(h); +} + +DUK_EXTERNAL const char *duk_push_string(duk_hthread *thr, const char *str) { + DUK_ASSERT_API_ENTRY(thr); + + if (str) { + return duk_push_lstring(thr, str, DUK_STRLEN(str)); + } else { + duk_push_null(thr); + return NULL; + } +} + +#if !defined(DUK_USE_PREFER_SIZE) +#if defined(DUK_USE_LITCACHE_SIZE) +DUK_EXTERNAL const char *duk_push_literal_raw(duk_hthread *thr, const char *str, duk_size_t len) { + duk_hstring *h; + duk_tval *tv_slot; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(str != NULL); + DUK_ASSERT(str[len] == (char) 0); + + /* Check for maximum string length. */ + if (DUK_UNLIKELY(len > DUK_HSTRING_MAX_BYTELEN)) { + DUK_ERROR_RANGE(thr, DUK_STR_STRING_TOO_LONG); + DUK_WO_NORETURN(return NULL;); + } + + h = duk_heap_strtable_intern_literal_checked(thr, (const duk_uint8_t *) str, (duk_uint32_t) len); + DUK_ASSERT(h != NULL); + + tv_slot = thr->valstack_top++; + DUK_TVAL_SET_STRING(tv_slot, h); + DUK_HSTRING_INCREF(thr, h); /* no side effects */ + + return (const char *) DUK_HSTRING_GET_DATA(h); +} +#else /* DUK_USE_LITCACHE_SIZE */ +DUK_EXTERNAL const char *duk_push_literal_raw(duk_hthread *thr, const char *str, duk_size_t len) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(str != NULL); + DUK_ASSERT(str[len] == (char) 0); + + return duk_push_lstring(thr, str, len); +} +#endif /* DUK_USE_LITCACHE_SIZE */ +#endif /* !DUK_USE_PREFER_SIZE */ + +DUK_EXTERNAL void duk_push_pointer(duk_hthread *thr, void *val) { + duk_tval *tv_slot; + + DUK_ASSERT_API_ENTRY(thr); + DUK__CHECK_SPACE(); + tv_slot = thr->valstack_top++; + DUK_TVAL_SET_POINTER(tv_slot, val); +} + +DUK_INTERNAL duk_hstring *duk_push_uint_to_hstring(duk_hthread *thr, duk_uint_t i) { + duk_hstring *h_tmp; + + DUK_ASSERT_API_ENTRY(thr); + + /* XXX: this could be a direct DUK_SPRINTF to a buffer followed by duk_push_string() */ + duk_push_uint(thr, (duk_uint_t) i); + h_tmp = duk_to_hstring_m1(thr); + DUK_ASSERT(h_tmp != NULL); + return h_tmp; +} + +DUK_LOCAL void duk__push_this_helper(duk_hthread *thr, duk_small_uint_t check_object_coercible) { + duk_tval *tv_slot; + + DUK__CHECK_SPACE(); + + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top)); /* because of valstack init policy */ + tv_slot = thr->valstack_top++; + + if (DUK_UNLIKELY(thr->callstack_curr == NULL)) { + if (check_object_coercible) { + goto type_error; + } + /* 'undefined' already on stack top */ + } else { + duk_tval *tv; + + /* 'this' binding is just before current activation's bottom */ + DUK_ASSERT(thr->valstack_bottom > thr->valstack); + tv = thr->valstack_bottom - 1; + if (check_object_coercible && + (DUK_TVAL_IS_UNDEFINED(tv) || DUK_TVAL_IS_NULL(tv))) { + /* XXX: better macro for DUK_TVAL_IS_UNDEFINED_OR_NULL(tv) */ + goto type_error; + } + + DUK_TVAL_SET_TVAL(tv_slot, tv); + DUK_TVAL_INCREF(thr, tv); + } + return; + + type_error: + DUK_ERROR_TYPE(thr, DUK_STR_NOT_OBJECT_COERCIBLE); + DUK_WO_NORETURN(return;); +} + +DUK_EXTERNAL void duk_push_this(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + + duk__push_this_helper(thr, 0 /*check_object_coercible*/); +} + +DUK_INTERNAL void duk_push_this_check_object_coercible(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + + duk__push_this_helper(thr, 1 /*check_object_coercible*/); +} + +DUK_INTERNAL duk_hobject *duk_push_this_coercible_to_object(duk_hthread *thr) { + duk_hobject *h; + + DUK_ASSERT_API_ENTRY(thr); + + duk__push_this_helper(thr, 1 /*check_object_coercible*/); + h = duk_to_hobject(thr, -1); + DUK_ASSERT(h != NULL); + return h; +} + +DUK_INTERNAL duk_hstring *duk_push_this_coercible_to_string(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + + duk__push_this_helper(thr, 1 /*check_object_coercible*/); + return duk_to_hstring_m1(thr); /* This will reject all Symbol values; accepts Symbol objects. */ +} + +DUK_INTERNAL duk_tval *duk_get_borrowed_this_tval(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + + DUK_ASSERT(thr->callstack_top > 0); /* caller required to know */ + DUK_ASSERT(thr->callstack_curr != NULL); /* caller required to know */ + DUK_ASSERT(thr->valstack_bottom > thr->valstack); /* consequence of above */ + DUK_ASSERT(thr->valstack_bottom - 1 >= thr->valstack); /* 'this' binding exists */ + + return thr->valstack_bottom - 1; +} + +DUK_EXTERNAL void duk_push_new_target(duk_hthread *thr) { + duk_activation *act; + + DUK_ASSERT_API_ENTRY(thr); + + /* https://www.ecma-international.org/ecma-262/6.0/#sec-meta-properties-runtime-semantics-evaluation + * https://www.ecma-international.org/ecma-262/6.0/#sec-getnewtarget + * + * No newTarget support now, so as a first approximation + * use the resolved (non-bound) target function. + * + * Check CONSTRUCT flag from current function, or if running + * direct eval, from a non-direct-eval parent (with possibly + * more than one nested direct eval). An alternative to this + * would be to store [[NewTarget]] as a hidden symbol of the + * lexical scope, and then just look up that variable. + * + * Calls from the application will either be for an empty + * call stack, or a Duktape/C function as the top activation. + */ + + act = thr->callstack_curr; + for (;;) { + if (act == NULL) { + break; + } + + if (act->flags & DUK_ACT_FLAG_CONSTRUCT) { + duk_push_tval(thr, &act->tv_func); + return; + } else if (act->flags & DUK_ACT_FLAG_DIRECT_EVAL) { + act = act->parent; + } else { + break; + } + } + + duk_push_undefined(thr); +} + +DUK_EXTERNAL void duk_push_current_function(duk_hthread *thr) { + duk_activation *act; + + DUK_ASSERT_API_ENTRY(thr); + + act = thr->callstack_curr; + if (act != NULL) { + duk_push_tval(thr, &act->tv_func); + } else { + duk_push_undefined(thr); + } +} + +DUK_EXTERNAL void duk_push_current_thread(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + + if (thr->heap->curr_thread) { + duk_push_hobject(thr, (duk_hobject *) thr->heap->curr_thread); + } else { + duk_push_undefined(thr); + } +} + +DUK_EXTERNAL void duk_push_global_object(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + + duk_push_hobject_bidx(thr, DUK_BIDX_GLOBAL); +} + +/* XXX: size optimize */ +DUK_LOCAL void duk__push_stash(duk_hthread *thr) { + if (!duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE)) { + DUK_DDD(DUK_DDDPRINT("creating heap/global/thread stash on first use")); + duk_pop_unsafe(thr); + duk_push_bare_object(thr); + duk_dup_top(thr); + duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_C); /* [ ... parent stash stash ] -> [ ... parent stash ] */ + } + duk_remove_m2(thr); +} + +DUK_EXTERNAL void duk_push_heap_stash(duk_hthread *thr) { + duk_heap *heap; + DUK_ASSERT_API_ENTRY(thr); + heap = thr->heap; + DUK_ASSERT(heap->heap_object != NULL); + duk_push_hobject(thr, heap->heap_object); + duk__push_stash(thr); +} + +DUK_EXTERNAL void duk_push_global_stash(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_push_global_object(thr); + duk__push_stash(thr); +} + +DUK_EXTERNAL void duk_push_thread_stash(duk_hthread *thr, duk_hthread *target_thr) { + DUK_ASSERT_API_ENTRY(thr); + if (DUK_UNLIKELY(target_thr == NULL)) { + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return;); + } + duk_push_hobject(thr, (duk_hobject *) target_thr); + duk__push_stash(thr); +} + +/* XXX: duk_ssize_t would be useful here */ +DUK_LOCAL duk_int_t duk__try_push_vsprintf(duk_hthread *thr, void *buf, duk_size_t sz, const char *fmt, va_list ap) { + duk_int_t len; + + DUK_CTX_ASSERT_VALID(thr); + DUK_UNREF(thr); + + /* NUL terminator handling doesn't matter here */ + len = DUK_VSNPRINTF((char *) buf, sz, fmt, ap); + if (len < (duk_int_t) sz) { + /* Return value of 'sz' or more indicates output was (potentially) + * truncated. + */ + return (duk_int_t) len; + } + return -1; +} + +DUK_EXTERNAL const char *duk_push_vsprintf(duk_hthread *thr, const char *fmt, va_list ap) { + duk_uint8_t stack_buf[DUK_PUSH_SPRINTF_INITIAL_SIZE]; + duk_size_t sz = DUK_PUSH_SPRINTF_INITIAL_SIZE; + duk_bool_t pushed_buf = 0; + void *buf; + duk_int_t len; /* XXX: duk_ssize_t */ + const char *res; + + DUK_ASSERT_API_ENTRY(thr); + + /* special handling of fmt==NULL */ + if (!fmt) { + duk_hstring *h_str; + duk_push_hstring_empty(thr); + h_str = duk_known_hstring(thr, -1); + return (const char *) DUK_HSTRING_GET_DATA(h_str); + } + + /* initial estimate based on format string */ + sz = DUK_STRLEN(fmt) + 16; /* format plus something to avoid just missing */ + if (sz < DUK_PUSH_SPRINTF_INITIAL_SIZE) { + sz = DUK_PUSH_SPRINTF_INITIAL_SIZE; + } + DUK_ASSERT(sz > 0); + + /* Try to make do with a stack buffer to avoid allocating a temporary buffer. + * This works 99% of the time which is quite nice. + */ + for (;;) { + va_list ap_copy; /* copied so that 'ap' can be reused */ + + if (sz <= sizeof(stack_buf)) { + buf = stack_buf; + } else if (!pushed_buf) { + pushed_buf = 1; + buf = duk_push_dynamic_buffer(thr, sz); + } else { + buf = duk_resize_buffer(thr, -1, sz); + } + DUK_ASSERT(buf != NULL); + + DUK_VA_COPY(ap_copy, ap); + len = duk__try_push_vsprintf(thr, buf, sz, fmt, ap_copy); + va_end(ap_copy); + if (len >= 0) { + break; + } + + /* failed, resize and try again */ + sz = sz * 2; + if (DUK_UNLIKELY(sz >= DUK_PUSH_SPRINTF_SANITY_LIMIT)) { + DUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG); + DUK_WO_NORETURN(return NULL;); + } + } + + /* Cannot use duk_buffer_to_string() on the buffer because it is + * usually larger than 'len'; 'buf' is also usually a stack buffer. + */ + res = duk_push_lstring(thr, (const char *) buf, (duk_size_t) len); /* [ buf? res ] */ + if (pushed_buf) { + duk_remove_m2(thr); + } + return res; +} + +DUK_EXTERNAL const char *duk_push_sprintf(duk_hthread *thr, const char *fmt, ...) { + va_list ap; + const char *ret; + + DUK_ASSERT_API_ENTRY(thr); + + /* allow fmt==NULL */ + va_start(ap, fmt); + ret = duk_push_vsprintf(thr, fmt, ap); + va_end(ap); + + return ret; +} + +DUK_INTERNAL duk_hobject *duk_push_object_helper(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx) { + duk_tval *tv_slot; + duk_hobject *h; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(prototype_bidx == -1 || + (prototype_bidx >= 0 && prototype_bidx < DUK_NUM_BUILTINS)); + + DUK__CHECK_SPACE(); + + h = duk_hobject_alloc(thr, hobject_flags_and_class); + DUK_ASSERT(h != NULL); + + DUK_DDD(DUK_DDDPRINT("created object with flags: 0x%08lx", (unsigned long) h->hdr.h_flags)); + + tv_slot = thr->valstack_top; + DUK_TVAL_SET_OBJECT(tv_slot, h); + DUK_HOBJECT_INCREF(thr, h); /* no side effects */ + thr->valstack_top++; + + /* object is now reachable */ + + if (prototype_bidx >= 0) { + DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, h, thr->builtins[prototype_bidx]); + } else { + DUK_ASSERT(prototype_bidx == -1); + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h) == NULL); + } + + return h; +} + +DUK_INTERNAL duk_hobject *duk_push_object_helper_proto(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_hobject *proto) { + duk_hobject *h; + + DUK_ASSERT_API_ENTRY(thr); + + h = duk_push_object_helper(thr, hobject_flags_and_class, -1); + DUK_ASSERT(h != NULL); + DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, h, proto); + return h; +} + +DUK_EXTERNAL duk_idx_t duk_push_object(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + + (void) duk_push_object_helper(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT), + DUK_BIDX_OBJECT_PROTOTYPE); + return duk_get_top_index_unsafe(thr); +} + +DUK_EXTERNAL duk_idx_t duk_push_array(duk_hthread *thr) { + duk_uint_t flags; + duk_harray *obj; + duk_idx_t ret; + duk_tval *tv_slot; + + DUK_ASSERT_API_ENTRY(thr); + + flags = DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_FLAG_ARRAY_PART | + DUK_HOBJECT_FLAG_EXOTIC_ARRAY | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAY); + + obj = duk_harray_alloc(thr, flags); + DUK_ASSERT(obj != NULL); + + DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[DUK_BIDX_ARRAY_PROTOTYPE]); + + tv_slot = thr->valstack_top; + DUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj); + DUK_HOBJECT_INCREF(thr, obj); /* XXX: could preallocate with refcount = 1 */ + ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom); + thr->valstack_top++; + + DUK_ASSERT(obj->length == 0); /* Array .length starts at zero. */ + return ret; +} + +DUK_EXTERNAL duk_idx_t duk_push_bare_array(duk_hthread *thr) { + duk_uint_t flags; + duk_harray *obj; + duk_idx_t ret; + duk_tval *tv_slot; + + DUK_ASSERT_API_ENTRY(thr); + + flags = DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_FLAG_ARRAY_PART | + DUK_HOBJECT_FLAG_EXOTIC_ARRAY | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAY); + + obj = duk_harray_alloc(thr, flags); + DUK_ASSERT(obj != NULL); + + tv_slot = thr->valstack_top; + DUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj); + DUK_HOBJECT_INCREF(thr, obj); /* XXX: could preallocate with refcount = 1 */ + ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom); + thr->valstack_top++; + + DUK_ASSERT(obj->length == 0); /* Array .length starts at zero. */ + return ret; +} + +DUK_INTERNAL duk_harray *duk_push_harray(duk_hthread *thr) { + /* XXX: API call could do this directly, cast to void in API macro. */ + duk_harray *a; + + DUK_ASSERT_API_ENTRY(thr); + + (void) duk_push_array(thr); + DUK_ASSERT(DUK_TVAL_IS_OBJECT(thr->valstack_top - 1)); + a = (duk_harray *) DUK_TVAL_GET_OBJECT(thr->valstack_top - 1); + DUK_ASSERT(a != NULL); + return a; +} + +/* Push a duk_harray with preallocated size (.length also set to match size). + * Caller may then populate array part of the duk_harray directly. + */ +DUK_INTERNAL duk_harray *duk_push_harray_with_size(duk_hthread *thr, duk_uint32_t size) { + duk_harray *a; + + DUK_ASSERT_API_ENTRY(thr); + + a = duk_push_harray(thr); + + duk_hobject_realloc_props(thr, + (duk_hobject *) a, + 0, + size, + 0, + 0); + a->length = size; + return a; +} + +DUK_INTERNAL duk_tval *duk_push_harray_with_size_outptr(duk_hthread *thr, duk_uint32_t size) { + duk_harray *a; + + DUK_ASSERT_API_ENTRY(thr); + + a = duk_push_harray_with_size(thr, size); + DUK_ASSERT(a != NULL); + return DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a); +} + +DUK_EXTERNAL duk_idx_t duk_push_thread_raw(duk_hthread *thr, duk_uint_t flags) { + duk_hthread *obj; + duk_idx_t ret; + duk_tval *tv_slot; + + DUK_ASSERT_API_ENTRY(thr); + + DUK__CHECK_SPACE(); + + obj = duk_hthread_alloc(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_THREAD)); + DUK_ASSERT(obj != NULL); + obj->state = DUK_HTHREAD_STATE_INACTIVE; +#if defined(DUK_USE_ROM_STRINGS) + /* Nothing to initialize, strs[] is in ROM. */ +#else +#if defined(DUK_USE_HEAPPTR16) + obj->strs16 = thr->strs16; +#else + obj->strs = thr->strs; +#endif +#endif + DUK_DDD(DUK_DDDPRINT("created thread object with flags: 0x%08lx", (unsigned long) obj->obj.hdr.h_flags)); + + /* make the new thread reachable */ + tv_slot = thr->valstack_top; + DUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj); + DUK_HTHREAD_INCREF(thr, obj); + ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom); + thr->valstack_top++; + + /* important to do this *after* pushing, to make the thread reachable for gc */ + if (DUK_UNLIKELY(!duk_hthread_init_stacks(thr->heap, obj))) { + DUK_ERROR_ALLOC_FAILED(thr); + DUK_WO_NORETURN(return 0;); + } + + /* initialize built-ins - either by copying or creating new ones */ + if (flags & DUK_THREAD_NEW_GLOBAL_ENV) { + duk_hthread_create_builtin_objects(obj); + } else { + duk_hthread_copy_builtin_objects(thr, obj); + } + + /* default prototype */ + DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, obj->builtins[DUK_BIDX_THREAD_PROTOTYPE]); + + /* Initial stack size satisfies the stack slack constraints so there + * is no need to require stack here. + */ + DUK_ASSERT(DUK_VALSTACK_INITIAL_SIZE >= + DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA); + + return ret; +} + +DUK_INTERNAL duk_hcompfunc *duk_push_hcompfunc(duk_hthread *thr) { + duk_hcompfunc *obj; + duk_tval *tv_slot; + + DUK_ASSERT_API_ENTRY(thr); + + DUK__CHECK_SPACE(); + + /* Template functions are not strictly constructable (they don't + * have a "prototype" property for instance), so leave the + * DUK_HOBJECT_FLAG_CONSRUCTABLE flag cleared here. + */ + + obj = duk_hcompfunc_alloc(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_CALLABLE | + DUK_HOBJECT_FLAG_COMPFUNC | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION)); + if (DUK_UNLIKELY(obj == NULL)) { + DUK_ERROR_ALLOC_FAILED(thr); + DUK_WO_NORETURN(return NULL;); + } + + DUK_DDD(DUK_DDDPRINT("created compiled function object with flags: 0x%08lx", (unsigned long) obj->obj.hdr.h_flags)); + + tv_slot = thr->valstack_top; + DUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj); + DUK_HOBJECT_INCREF(thr, obj); + thr->valstack_top++; + + /* default prototype */ + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) obj) == NULL); + DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]); + + return obj; +} + +DUK_INTERNAL duk_hboundfunc *duk_push_hboundfunc(duk_hthread *thr) { + duk_hboundfunc *obj; + duk_tval *tv_slot; + + DUK_ASSERT_API_ENTRY(thr); + + DUK__CHECK_SPACE(); + obj = duk_hboundfunc_alloc(thr->heap, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_BOUNDFUNC | + DUK_HOBJECT_FLAG_CONSTRUCTABLE | + DUK_HOBJECT_FLAG_CALLABLE | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION)); + if (!obj) { + DUK_ERROR_ALLOC_FAILED(thr); + DUK_WO_NORETURN(return NULL;); + } + + tv_slot = thr->valstack_top++; + DUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj); + DUK_HOBJECT_INCREF(thr, obj); + + /* Prototype is left as NULL because the caller always sets it (and + * it depends on the target function). + */ + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) obj) == NULL); + + return obj; +} + +DUK_LOCAL duk_idx_t duk__push_c_function_raw(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_uint_t flags, duk_small_uint_t proto_bidx) { + duk_hnatfunc *obj; + duk_idx_t ret; + duk_tval *tv_slot; + duk_int16_t func_nargs; + + DUK_CTX_ASSERT_VALID(thr); + + DUK__CHECK_SPACE(); + + if (DUK_UNLIKELY(func == NULL)) { + goto api_error; + } + if (nargs >= 0 && nargs < DUK_HNATFUNC_NARGS_MAX) { + func_nargs = (duk_int16_t) nargs; + } else if (nargs == DUK_VARARGS) { + func_nargs = DUK_HNATFUNC_NARGS_VARARGS; + } else { + goto api_error; + } + + obj = duk_hnatfunc_alloc(thr, flags); + DUK_ASSERT(obj != NULL); + + obj->func = func; + obj->nargs = func_nargs; + + DUK_DDD(DUK_DDDPRINT("created native function object with flags: 0x%08lx, nargs=%ld", + (unsigned long) obj->obj.hdr.h_flags, (long) obj->nargs)); + + tv_slot = thr->valstack_top; + DUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj); + DUK_HOBJECT_INCREF(thr, obj); + ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom); + thr->valstack_top++; + + DUK_ASSERT_BIDX_VALID(proto_bidx); + DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[proto_bidx]); + return ret; + + api_error: + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return 0;); +} + +DUK_EXTERNAL duk_idx_t duk_push_c_function(duk_hthread *thr, duk_c_function func, duk_int_t nargs) { + duk_uint_t flags; + + DUK_ASSERT_API_ENTRY(thr); + + flags = DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_CONSTRUCTABLE | + DUK_HOBJECT_FLAG_CALLABLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_FLAG_NATFUNC | + DUK_HOBJECT_FLAG_NEWENV | + DUK_HOBJECT_FLAG_STRICT | + DUK_HOBJECT_FLAG_NOTAIL | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION); + + /* Default prototype is a Duktape specific %NativeFunctionPrototype% + * which provides .length and .name getters. + */ + return duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE); +} + +DUK_INTERNAL void duk_push_c_function_builtin(duk_hthread *thr, duk_c_function func, duk_int_t nargs) { + duk_uint_t flags; + + DUK_ASSERT_API_ENTRY(thr); + + flags = DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_CONSTRUCTABLE | + DUK_HOBJECT_FLAG_CALLABLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_FLAG_NATFUNC | + DUK_HOBJECT_FLAG_NEWENV | + DUK_HOBJECT_FLAG_STRICT | + DUK_HOBJECT_FLAG_NOTAIL | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION); + + /* Must use Function.prototype for standard built-in functions. */ + (void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_FUNCTION_PROTOTYPE); +} + +DUK_INTERNAL void duk_push_c_function_builtin_noconstruct(duk_hthread *thr, duk_c_function func, duk_int_t nargs) { + duk_uint_t flags; + + DUK_ASSERT_API_ENTRY(thr); + + flags = DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_CALLABLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_FLAG_NATFUNC | + DUK_HOBJECT_FLAG_NEWENV | + DUK_HOBJECT_FLAG_STRICT | + DUK_HOBJECT_FLAG_NOTAIL | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION); + + /* Must use Function.prototype for standard built-in functions. */ + (void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_FUNCTION_PROTOTYPE); +} + +DUK_EXTERNAL duk_idx_t duk_push_c_lightfunc(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_idx_t length, duk_int_t magic) { + duk_small_uint_t lf_flags; + duk_tval *tv_slot; + + DUK_ASSERT_API_ENTRY(thr); + + DUK__CHECK_SPACE(); + + if (nargs >= DUK_LFUNC_NARGS_MIN && nargs <= DUK_LFUNC_NARGS_MAX) { + /* as is */ + } else if (nargs == DUK_VARARGS) { + nargs = DUK_LFUNC_NARGS_VARARGS; + } else { + goto api_error; + } + if (DUK_UNLIKELY(!(length >= DUK_LFUNC_LENGTH_MIN && length <= DUK_LFUNC_LENGTH_MAX))) { + goto api_error; + } + if (DUK_UNLIKELY(!(magic >= DUK_LFUNC_MAGIC_MIN && magic <= DUK_LFUNC_MAGIC_MAX))) { + goto api_error; + } + + lf_flags = DUK_LFUNC_FLAGS_PACK((duk_small_int_t) magic, (duk_small_uint_t) length, (duk_small_uint_t) nargs); + tv_slot = thr->valstack_top++; + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_slot)); + DUK_TVAL_SET_LIGHTFUNC(tv_slot, func, lf_flags); + DUK_ASSERT(tv_slot >= thr->valstack_bottom); + return (duk_idx_t) (tv_slot - thr->valstack_bottom); + + api_error: + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return 0;); +} + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_hbufobj *duk_push_bufobj_raw(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx) { + duk_hbufobj *obj; + duk_tval *tv_slot; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(prototype_bidx >= 0); + + DUK__CHECK_SPACE(); + + obj = duk_hbufobj_alloc(thr, hobject_flags_and_class); + DUK_ASSERT(obj != NULL); + + DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[prototype_bidx]); + DUK_HBUFOBJ_ASSERT_VALID(obj); + + tv_slot = thr->valstack_top; + DUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj); + DUK_HOBJECT_INCREF(thr, obj); + thr->valstack_top++; + + return obj; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* XXX: There's quite a bit of overlap with buffer creation handling in + * duk_bi_buffer.c. Look for overlap and refactor. + */ +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +#define DUK__PACK_ARGS(classnum,protobidx,elemtype,elemshift,istypedarray) \ + (((classnum) << 24) | ((protobidx) << 16) | ((elemtype) << 8) | ((elemshift) << 4) | (istypedarray)) + +static const duk_uint32_t duk__bufobj_flags_lookup[] = { + /* Node.js Buffers are Uint8Array instances which inherit from Buffer.prototype. */ + DUK__PACK_ARGS(DUK_HOBJECT_CLASS_ARRAYBUFFER, DUK_BIDX_ARRAYBUFFER_PROTOTYPE, DUK_HBUFOBJ_ELEM_UINT8, 0, 0), /* DUK_BUFOBJ_ARRAYBUFFER */ + DUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT8ARRAY, DUK_BIDX_NODEJS_BUFFER_PROTOTYPE, DUK_HBUFOBJ_ELEM_UINT8, 0, 1), /* DUK_BUFOBJ_NODEJS_BUFFER */ + DUK__PACK_ARGS(DUK_HOBJECT_CLASS_DATAVIEW, DUK_BIDX_DATAVIEW_PROTOTYPE, DUK_HBUFOBJ_ELEM_UINT8, 0, 0), /* DUK_BUFOBJ_DATAVIEW */ + DUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT8ARRAY, DUK_BIDX_INT8ARRAY_PROTOTYPE, DUK_HBUFOBJ_ELEM_INT8, 0, 1), /* DUK_BUFOBJ_INT8ARRAY */ + DUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT8ARRAY, DUK_BIDX_UINT8ARRAY_PROTOTYPE, DUK_HBUFOBJ_ELEM_UINT8, 0, 1), /* DUK_BUFOBJ_UINT8ARRAY */ + DUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY, DUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE, DUK_HBUFOBJ_ELEM_UINT8CLAMPED, 0, 1), /* DUK_BUFOBJ_UINT8CLAMPEDARRAY */ + DUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT16ARRAY, DUK_BIDX_INT16ARRAY_PROTOTYPE, DUK_HBUFOBJ_ELEM_INT16, 1, 1), /* DUK_BUFOBJ_INT16ARRAY */ + DUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT16ARRAY, DUK_BIDX_UINT16ARRAY_PROTOTYPE, DUK_HBUFOBJ_ELEM_UINT16, 1, 1), /* DUK_BUFOBJ_UINT16ARRAY */ + DUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT32ARRAY, DUK_BIDX_INT32ARRAY_PROTOTYPE, DUK_HBUFOBJ_ELEM_INT32, 2, 1), /* DUK_BUFOBJ_INT32ARRAY */ + DUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT32ARRAY, DUK_BIDX_UINT32ARRAY_PROTOTYPE, DUK_HBUFOBJ_ELEM_UINT32, 2, 1), /* DUK_BUFOBJ_UINT32ARRAY */ + DUK__PACK_ARGS(DUK_HOBJECT_CLASS_FLOAT32ARRAY, DUK_BIDX_FLOAT32ARRAY_PROTOTYPE, DUK_HBUFOBJ_ELEM_FLOAT32, 2, 1), /* DUK_BUFOBJ_FLOAT32ARRAY */ + DUK__PACK_ARGS(DUK_HOBJECT_CLASS_FLOAT64ARRAY, DUK_BIDX_FLOAT64ARRAY_PROTOTYPE, DUK_HBUFOBJ_ELEM_FLOAT64, 3, 1) /* DUK_BUFOBJ_FLOAT64ARRAY */ +}; +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_EXTERNAL void duk_push_buffer_object(duk_hthread *thr, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags) { + duk_hbufobj *h_bufobj; + duk_hbuffer *h_val; + duk_hobject *h_arraybuf; + duk_uint32_t tmp; + duk_uint_t classnum; + duk_uint_t protobidx; + duk_uint_t lookupidx; + duk_uint_t uint_offset, uint_length, uint_added; + + DUK_ASSERT_API_ENTRY(thr); + + /* The underlying types for offset/length in duk_hbufobj is + * duk_uint_t; make sure argument values fit. + */ + uint_offset = (duk_uint_t) byte_offset; + uint_length = (duk_uint_t) byte_length; + if (sizeof(duk_size_t) != sizeof(duk_uint_t)) { + if (DUK_UNLIKELY((duk_size_t) uint_offset != byte_offset || (duk_size_t) uint_length != byte_length)) { + goto range_error; + } + } + + DUK_ASSERT_DISABLE(flags >= 0); /* flags is unsigned */ + lookupidx = flags; + if (DUK_UNLIKELY(lookupidx >= sizeof(duk__bufobj_flags_lookup) / sizeof(duk_uint32_t))) { + goto arg_error; + } + tmp = duk__bufobj_flags_lookup[lookupidx]; + classnum = tmp >> 24; + protobidx = (tmp >> 16) & 0xff; + + h_arraybuf = duk_get_hobject(thr, idx_buffer); + if (h_arraybuf != NULL && /* argument is an object */ + flags != DUK_BUFOBJ_ARRAYBUFFER && /* creating a view */ + DUK_HOBJECT_GET_CLASS_NUMBER(h_arraybuf) == DUK_HOBJECT_CLASS_ARRAYBUFFER /* argument is ArrayBuffer */) { + duk_uint_t tmp_offset; + + DUK_HBUFOBJ_ASSERT_VALID((duk_hbufobj *) h_arraybuf); + h_val = ((duk_hbufobj *) h_arraybuf)->buf; + if (DUK_UNLIKELY(h_val == NULL)) { + goto arg_error; + } + + tmp_offset = uint_offset + ((duk_hbufobj *) h_arraybuf)->offset; + if (DUK_UNLIKELY(tmp_offset < uint_offset)) { + goto range_error; + } + uint_offset = tmp_offset; + + /* Note intentional difference to new TypedArray(): we allow + * caller to create an uncovered typed array (which is memory + * safe); new TypedArray() rejects it. + */ + } else { + /* Handle unexpected object arguments here too, for nice error + * messages. + */ + h_arraybuf = NULL; + h_val = duk_require_hbuffer(thr, idx_buffer); + } + + /* Wrap check for offset+length. */ + uint_added = uint_offset + uint_length; + if (DUK_UNLIKELY(uint_added < uint_offset)) { + goto range_error; + } + DUK_ASSERT(uint_added >= uint_offset && uint_added >= uint_length); + + DUK_ASSERT(h_val != NULL); + + h_bufobj = duk_push_bufobj_raw(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_BUFOBJ | + DUK_HOBJECT_CLASS_AS_FLAGS(classnum), + (duk_small_int_t) protobidx); + DUK_ASSERT(h_bufobj != NULL); + + h_bufobj->buf = h_val; + DUK_HBUFFER_INCREF(thr, h_val); + h_bufobj->buf_prop = h_arraybuf; + DUK_HOBJECT_INCREF_ALLOWNULL(thr, h_arraybuf); + h_bufobj->offset = uint_offset; + h_bufobj->length = uint_length; + h_bufobj->shift = (tmp >> 4) & 0x0f; + h_bufobj->elem_type = (tmp >> 8) & 0xff; + h_bufobj->is_typedarray = tmp & 0x0f; + DUK_HBUFOBJ_ASSERT_VALID(h_bufobj); + + /* TypedArray views need an automatic ArrayBuffer which must be + * provided as .buffer property of the view. The ArrayBuffer is + * referenced via duk_hbufobj->buf_prop and an inherited .buffer + * accessor returns it. The ArrayBuffer is created lazily on first + * access if necessary so we don't need to do anything more here. + */ + return; + + range_error: + DUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARGS); + DUK_WO_NORETURN(return;); + + arg_error: + DUK_ERROR_TYPE(thr, DUK_STR_INVALID_ARGS); + DUK_WO_NORETURN(return;); +} +#else /* DUK_USE_BUFFEROBJECT_SUPPORT */ +DUK_EXTERNAL void duk_push_buffer_object(duk_hthread *thr, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags) { + DUK_ASSERT_API_ENTRY(thr); + DUK_UNREF(idx_buffer); + DUK_UNREF(byte_offset); + DUK_UNREF(byte_length); + DUK_UNREF(flags); + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return;); +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +DUK_EXTERNAL duk_idx_t duk_push_error_object_va_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap) { + duk_hobject *proto; +#if defined(DUK_USE_AUGMENT_ERROR_CREATE) + duk_small_uint_t augment_flags; +#endif + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr != NULL); + DUK_UNREF(filename); + DUK_UNREF(line); + + /* Error code also packs a tracedata related flag. */ +#if defined(DUK_USE_AUGMENT_ERROR_CREATE) + augment_flags = 0; + if (err_code & DUK_ERRCODE_FLAG_NOBLAME_FILELINE) { + augment_flags = DUK_AUGMENT_FLAG_NOBLAME_FILELINE; + } +#endif + err_code = err_code & (~DUK_ERRCODE_FLAG_NOBLAME_FILELINE); + + /* error gets its 'name' from the prototype */ + proto = duk_error_prototype_from_code(thr, err_code); + (void) duk_push_object_helper_proto(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ERROR), + proto); + + /* ... and its 'message' from an instance property */ + if (fmt) { + duk_push_vsprintf(thr, fmt, ap); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC); + } else { + /* If no explicit message given, put error code into message field + * (as a number). This is not fully in keeping with the ECMAScript + * error model because messages are supposed to be strings (Error + * constructors use ToString() on their argument). However, it's + * probably more useful than having a separate 'code' property. + */ + duk_push_int(thr, err_code); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC); + } + + /* XXX: .code = err_code disabled, not sure if useful */ + + /* Creation time error augmentation */ +#if defined(DUK_USE_AUGMENT_ERROR_CREATE) + /* filename may be NULL in which case file/line is not recorded */ + duk_err_augment_error_create(thr, thr, filename, line, augment_flags); /* may throw an error */ +#endif + + return duk_get_top_index_unsafe(thr); +} + +DUK_EXTERNAL duk_idx_t duk_push_error_object_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...) { + va_list ap; + duk_idx_t ret; + + DUK_ASSERT_API_ENTRY(thr); + + va_start(ap, fmt); + ret = duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap); + va_end(ap); + return ret; +} + +#if !defined(DUK_USE_VARIADIC_MACROS) +DUK_EXTERNAL duk_idx_t duk_push_error_object_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, ...) { + const char *filename = duk_api_global_filename; + duk_int_t line = duk_api_global_line; + va_list ap; + duk_idx_t ret; + + DUK_ASSERT_API_ENTRY(thr); + + duk_api_global_filename = NULL; + duk_api_global_line = 0; + va_start(ap, fmt); + ret = duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap); + va_end(ap); + return ret; +} +#endif /* DUK_USE_VARIADIC_MACROS */ + +DUK_EXTERNAL void *duk_push_buffer_raw(duk_hthread *thr, duk_size_t size, duk_small_uint_t flags) { + duk_tval *tv_slot; + duk_hbuffer *h; + void *buf_data; + + DUK_ASSERT_API_ENTRY(thr); + + DUK__CHECK_SPACE(); + + /* Check for maximum buffer length. */ + if (DUK_UNLIKELY(size > DUK_HBUFFER_MAX_BYTELEN)) { + DUK_ERROR_RANGE(thr, DUK_STR_BUFFER_TOO_LONG); + DUK_WO_NORETURN(return NULL;); + } + + h = duk_hbuffer_alloc(thr->heap, size, flags, &buf_data); + if (DUK_UNLIKELY(h == NULL)) { + DUK_ERROR_ALLOC_FAILED(thr); + DUK_WO_NORETURN(return NULL;); + } + + tv_slot = thr->valstack_top; + DUK_TVAL_SET_BUFFER(tv_slot, h); + DUK_HBUFFER_INCREF(thr, h); + thr->valstack_top++; + + return (void *) buf_data; +} + +DUK_INTERNAL void *duk_push_fixed_buffer_nozero(duk_hthread *thr, duk_size_t len) { + DUK_ASSERT_API_ENTRY(thr); + return duk_push_buffer_raw(thr, len, DUK_BUF_FLAG_NOZERO); +} + +DUK_INTERNAL void *duk_push_fixed_buffer_zero(duk_hthread *thr, duk_size_t len) { + void *ptr; + + DUK_ASSERT_API_ENTRY(thr); + + ptr = duk_push_buffer_raw(thr, len, 0); + DUK_ASSERT(ptr != NULL); +#if !defined(DUK_USE_ZERO_BUFFER_DATA) + /* ES2015 requires zeroing even when DUK_USE_ZERO_BUFFER_DATA + * is not set. + */ + duk_memzero((void *) ptr, (size_t) len); +#endif + return ptr; +} + +#if defined(DUK_USE_ES6_PROXY) +DUK_EXTERNAL duk_idx_t duk_push_proxy(duk_hthread *thr, duk_uint_t proxy_flags) { + duk_hobject *h_target; + duk_hobject *h_handler; + duk_hproxy *h_proxy; + duk_tval *tv_slot; + duk_uint_t flags; + + DUK_ASSERT_API_ENTRY(thr); + DUK_UNREF(proxy_flags); + + /* DUK__CHECK_SPACE() unnecessary because the Proxy is written to + * value stack in-place. + */ +#if 0 + DUK__CHECK_SPACE(); +#endif + + /* Reject a proxy object as the target because it would need + * special handling in property lookups. (ES2015 has no such + * restriction.) + */ + h_target = duk_require_hobject_promote_mask(thr, -2, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER); + DUK_ASSERT(h_target != NULL); + if (DUK_HOBJECT_IS_PROXY(h_target)) { + goto fail_args; + } + + /* Reject a proxy object as the handler because it would cause + * potentially unbounded recursion. (ES2015 has no such + * restriction.) + * + * There's little practical reason to use a lightfunc or a plain + * buffer as the handler table: one could only provide traps via + * their prototype objects (Function.prototype and ArrayBuffer.prototype). + * Even so, as lightfuncs and plain buffers mimic their object + * counterparts, they're promoted and accepted here. + */ + h_handler = duk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER); + DUK_ASSERT(h_handler != NULL); + if (DUK_HOBJECT_IS_PROXY(h_handler)) { + goto fail_args; + } + + /* XXX: Proxy object currently has no prototype, so ToPrimitive() + * coercion fails which is a bit confusing. + */ + + /* CALLABLE and CONSTRUCTABLE flags are copied from the (initial) + * target, see ES2015 Sections 9.5.15 and 9.5.13. + */ + flags = DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h_target) & + (DUK_HOBJECT_FLAG_CALLABLE | DUK_HOBJECT_FLAG_CONSTRUCTABLE); + flags |= DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ; + if (flags & DUK_HOBJECT_FLAG_CALLABLE) { + flags |= DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION) | + DUK_HOBJECT_FLAG_SPECIAL_CALL; + } else { + flags |= DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT); + } + + h_proxy = duk_hproxy_alloc(thr, flags); + DUK_ASSERT(h_proxy != NULL); + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_proxy) == NULL); + + /* Initialize Proxy target and handler references; avoid INCREF + * by stealing the value stack refcounts via direct value stack + * manipulation. INCREF is needed for the Proxy itself however. + */ + DUK_ASSERT(h_target != NULL); + h_proxy->target = h_target; + DUK_ASSERT(h_handler != NULL); + h_proxy->handler = h_handler; + DUK_HPROXY_ASSERT_VALID(h_proxy); + + DUK_ASSERT(duk_get_hobject(thr, -2) == h_target); + DUK_ASSERT(duk_get_hobject(thr, -1) == h_handler); + tv_slot = thr->valstack_top - 2; + DUK_ASSERT(tv_slot >= thr->valstack_bottom); + DUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) h_proxy); + DUK_HOBJECT_INCREF(thr, (duk_hobject *) h_proxy); + tv_slot++; + DUK_TVAL_SET_UNDEFINED(tv_slot); /* [ ... target handler ] -> [ ... proxy undefined ] */ + thr->valstack_top = tv_slot; /* -> [ ... proxy ] */ + + DUK_DD(DUK_DDPRINT("created Proxy: %!iT", duk_get_tval(thr, -1))); + + return (duk_idx_t) (thr->valstack_top - thr->valstack_bottom - 1); + + fail_args: + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return 0;); +} +#else /* DUK_USE_ES6_PROXY */ +DUK_EXTERNAL duk_idx_t duk_push_proxy(duk_hthread *thr, duk_uint_t proxy_flags) { + DUK_ASSERT_API_ENTRY(thr); + DUK_UNREF(proxy_flags); + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return 0;); +} +#endif /* DUK_USE_ES6_PROXY */ + +#if defined(DUK_USE_ASSERTIONS) +DUK_LOCAL void duk__validate_push_heapptr(duk_hthread *thr, void *ptr) { + duk_heaphdr *h; + duk_heaphdr *curr; + duk_bool_t found = 0; + + h = (duk_heaphdr *) ptr; + if (h == NULL) { + /* Allowed. */ + return; + } + DUK_ASSERT(h != NULL); + DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h)); + + /* One particular problem case is where an object has been + * queued for finalization but the finalizer hasn't yet been + * executed. + * + * Corner case: we're running in a finalizer for object X, and + * user code calls duk_push_heapptr() for X itself. In this + * case X will be in finalize_list, and we can detect the case + * by seeing that X's FINALIZED flag is set (which is done before + * the finalizer starts executing). + */ +#if defined(DUK_USE_FINALIZER_SUPPORT) + for (curr = thr->heap->finalize_list; + curr != NULL; + curr = DUK_HEAPHDR_GET_NEXT(thr->heap, curr)) { + /* FINALIZABLE is set for all objects on finalize_list + * except for an object being finalized right now. So + * can't assert here. + */ +#if 0 + DUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZABLE(curr)); +#endif + + if (curr == h) { + if (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) h)) { + /* Object is currently being finalized. */ + DUK_ASSERT(found == 0); /* Would indicate corrupted lists. */ + found = 1; + } else { + /* Not being finalized but on finalize_list, + * allowed since Duktape 2.1. + */ + DUK_ASSERT(found == 0); /* Would indicate corrupted lists. */ + found = 1; + } + } + } +#endif /* DUK_USE_FINALIZER_SUPPORT */ + +#if defined(DUK_USE_REFERENCE_COUNTING) + /* Because refzero_list is now processed to completion inline with + * no side effects, it's always empty here. + */ + DUK_ASSERT(thr->heap->refzero_list == NULL); +#endif + + /* If not present in finalize_list (or refzero_list), it + * must be either in heap_allocated or the string table. + */ + if (DUK_HEAPHDR_IS_STRING(h)) { + duk_uint32_t i; + duk_hstring *str; + duk_heap *heap = thr->heap; + + DUK_ASSERT(found == 0); + for (i = 0; i < heap->st_size; i++) { +#if defined(DUK_USE_STRTAB_PTRCOMP) + str = DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, heap->strtable16[i]); +#else + str = heap->strtable[i]; +#endif + while (str != NULL) { + if (str == (duk_hstring *) h) { + DUK_ASSERT(found == 0); /* Would indicate corrupted lists. */ + found = 1; + break; + } + str = str->hdr.h_next; + } + } + DUK_ASSERT(found != 0); + } else { + for (curr = thr->heap->heap_allocated; + curr != NULL; + curr = DUK_HEAPHDR_GET_NEXT(thr->heap, curr)) { + if (curr == h) { + DUK_ASSERT(found == 0); /* Would indicate corrupted lists. */ + found = 1; + } + } + DUK_ASSERT(found != 0); + } +} +#endif /* DUK_USE_ASSERTIONS */ + +DUK_EXTERNAL duk_idx_t duk_push_heapptr(duk_hthread *thr, void *ptr) { + duk_idx_t ret; + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + /* Reviving an object using a heap pointer is a dangerous API + * operation: if the application doesn't guarantee that the + * pointer target is always reachable, difficult-to-diagnose + * problems may ensue. Try to validate the 'ptr' argument to + * the extent possible. + */ + +#if defined(DUK_USE_ASSERTIONS) + duk__validate_push_heapptr(thr, ptr); +#endif + + DUK__CHECK_SPACE(); + + ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom); + tv = thr->valstack_top++; + + if (ptr == NULL) { + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv)); + return ret; + } + + DUK_HEAPHDR_ASSERT_VALID((duk_heaphdr *) ptr); + + /* If the argument is on finalize_list it has technically been + * unreachable before duk_push_heapptr() but it's still safe to + * push it. Starting from Duktape 2.1 allow application code to + * do so. There are two main cases: + * + * (1) The object is on the finalize_list and we're called by + * the finalizer for the object being finalized. In this + * case do nothing: finalize_list handling will deal with + * the object queueing. This is detected by the object not + * having a FINALIZABLE flag despite being on the finalize_list; + * the flag is cleared for the object being finalized only. + * + * (2) The object is on the finalize_list but is not currently + * being processed. In this case the object can be queued + * back to heap_allocated with a few flags cleared, in effect + * cancelling the finalizer. + */ + if (DUK_UNLIKELY(DUK_HEAPHDR_HAS_FINALIZABLE((duk_heaphdr *) ptr))) { + duk_heaphdr *curr; + + DUK_D(DUK_DPRINT("duk_push_heapptr() with a pointer on finalize_list, autorescue")); + + curr = (duk_heaphdr *) ptr; + DUK_HEAPHDR_CLEAR_FINALIZABLE(curr); + + /* Because FINALIZED is set prior to finalizer call, it will + * be set for the object being currently finalized, but not + * for other objects on finalize_list. + */ + DUK_HEAPHDR_CLEAR_FINALIZED(curr); + + /* Dequeue object from finalize_list and queue it back to + * heap_allocated. + */ +#if defined(DUK_USE_REFERENCE_COUNTING) + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) >= 1); /* Preincremented on finalize_list insert. */ + DUK_HEAPHDR_PREDEC_REFCOUNT(curr); +#endif + DUK_HEAP_REMOVE_FROM_FINALIZE_LIST(thr->heap, curr); + DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(thr->heap, curr); + + /* Continue with the rest. */ + } + + switch (DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) ptr)) { + case DUK_HTYPE_STRING: + DUK_TVAL_SET_STRING(tv, (duk_hstring *) ptr); + break; + case DUK_HTYPE_OBJECT: + DUK_TVAL_SET_OBJECT(tv, (duk_hobject *) ptr); + break; + default: + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) ptr) == DUK_HTYPE_BUFFER); + DUK_TVAL_SET_BUFFER(tv, (duk_hbuffer *) ptr); + break; + } + + DUK_HEAPHDR_INCREF(thr, (duk_heaphdr *) ptr); + + return ret; +} + +/* Push object with no prototype, i.e. a "bare" object. */ +DUK_EXTERNAL duk_idx_t duk_push_bare_object(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + + (void) duk_push_object_helper(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT), + -1); /* no prototype */ + return duk_get_top_index_unsafe(thr); +} + +DUK_INTERNAL void duk_push_hstring(duk_hthread *thr, duk_hstring *h) { + duk_tval tv; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(h != NULL); + + DUK_TVAL_SET_STRING(&tv, h); + duk_push_tval(thr, &tv); +} + +DUK_INTERNAL void duk_push_hstring_stridx(duk_hthread *thr, duk_small_uint_t stridx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT_STRIDX_VALID(stridx); + duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx)); +} + +DUK_INTERNAL void duk_push_hstring_empty(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, DUK_STRIDX_EMPTY_STRING)); +} + +DUK_INTERNAL void duk_push_hobject(duk_hthread *thr, duk_hobject *h) { + duk_tval tv; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(h != NULL); + + DUK_TVAL_SET_OBJECT(&tv, h); + duk_push_tval(thr, &tv); +} + +DUK_INTERNAL void duk_push_hbuffer(duk_hthread *thr, duk_hbuffer *h) { + duk_tval tv; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(h != NULL); + + DUK_TVAL_SET_BUFFER(&tv, h); + duk_push_tval(thr, &tv); +} + +DUK_INTERNAL void duk_push_hobject_bidx(duk_hthread *thr, duk_small_int_t builtin_idx) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(builtin_idx >= 0 && builtin_idx < DUK_NUM_BUILTINS); + DUK_ASSERT(thr->builtins[builtin_idx] != NULL); + + duk_push_hobject(thr, thr->builtins[builtin_idx]); +} + +/* + * Poppers + */ + +DUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_n_unsafe_raw(duk_hthread *thr, duk_idx_t count) { + duk_tval *tv; +#if defined(DUK_USE_REFERENCE_COUNTING) + duk_tval *tv_end; +#endif + + DUK_CTX_ASSERT_VALID(thr); + DUK_ASSERT(count >= 0); + DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) count); + +#if defined(DUK_USE_REFERENCE_COUNTING) + tv = thr->valstack_top; + tv_end = tv - count; + while (tv != tv_end) { + tv--; + DUK_ASSERT(tv >= thr->valstack_bottom); + DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv); + } + thr->valstack_top = tv; + DUK_REFZERO_CHECK_FAST(thr); +#else + tv = thr->valstack_top; + while (count > 0) { + count--; + tv--; + DUK_ASSERT(tv >= thr->valstack_bottom); + DUK_TVAL_SET_UNDEFINED(tv); + } + thr->valstack_top = tv; +#endif + + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); +} + +DUK_EXTERNAL void duk_pop_n(duk_hthread *thr, duk_idx_t count) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + + if (DUK_UNLIKELY((duk_uidx_t) (thr->valstack_top - thr->valstack_bottom) < (duk_uidx_t) count)) { + DUK_ERROR_RANGE_INVALID_COUNT(thr); + DUK_WO_NORETURN(return;); + } + DUK_ASSERT(count >= 0); + + duk__pop_n_unsafe_raw(thr, count); +} + +#if defined(DUK_USE_PREFER_SIZE) +DUK_INTERNAL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count) { + DUK_ASSERT_API_ENTRY(thr); + duk_pop_n(thr, count); +} +#else /* DUK_USE_PREFER_SIZE */ +DUK_INTERNAL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count) { + DUK_ASSERT_API_ENTRY(thr); + duk__pop_n_unsafe_raw(thr, count); +} +#endif /* DUK_USE_PREFER_SIZE */ + +/* Pop N elements without DECREF (in effect "stealing" any actual refcounts). */ +#if defined(DUK_USE_REFERENCE_COUNTING) +DUK_INTERNAL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(count >= 0); + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) count); + + tv = thr->valstack_top; + while (count > 0) { + count--; + tv--; + DUK_ASSERT(tv >= thr->valstack_bottom); + DUK_TVAL_SET_UNDEFINED(tv); + } + thr->valstack_top = tv; + + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); +} +#else /* DUK_USE_REFERENCE_COUNTING */ +DUK_INTERNAL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count) { + DUK_ASSERT_API_ENTRY(thr); + duk_pop_n_unsafe(thr, count); +} +#endif /* DUK_USE_REFERENCE_COUNTING */ + +/* Popping one element is called so often that when footprint is not an issue, + * compile a specialized function for it. + */ +#if defined(DUK_USE_PREFER_SIZE) +DUK_EXTERNAL void duk_pop(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_pop_n(thr, 1); +} +DUK_INTERNAL void duk_pop_unsafe(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_pop_n_unsafe(thr, 1); +} +DUK_INTERNAL void duk_pop_nodecref_unsafe(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_pop_n_nodecref_unsafe(thr, 1); +} +#else /* DUK_USE_PREFER_SIZE */ +DUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_unsafe_raw(duk_hthread *thr) { + duk_tval *tv; + + DUK_CTX_ASSERT_VALID(thr); + DUK_ASSERT(thr->valstack_top != thr->valstack_bottom); + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1); + + tv = --thr->valstack_top; + DUK_ASSERT(tv >= thr->valstack_bottom); +#if defined(DUK_USE_REFERENCE_COUNTING) + DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv); /* side effects */ +#else + DUK_TVAL_SET_UNDEFINED(tv); +#endif + + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); +} +DUK_EXTERNAL void duk_pop(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + if (DUK_UNLIKELY(thr->valstack_top == thr->valstack_bottom)) { + DUK_ERROR_RANGE_INVALID_COUNT(thr); + DUK_WO_NORETURN(return;); + } + + duk__pop_unsafe_raw(thr); +} +DUK_INTERNAL void duk_pop_unsafe(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk__pop_unsafe_raw(thr); +} +DUK_INTERNAL void duk_pop_nodecref_unsafe(duk_hthread *thr) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->valstack_top != thr->valstack_bottom); + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1); + + tv = --thr->valstack_top; + DUK_ASSERT(tv >= thr->valstack_bottom); + DUK_TVAL_SET_UNDEFINED(tv); + + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); +} +#endif /* !DUK_USE_PREFER_SIZE */ + +#if defined(DUK_USE_PREFER_SIZE) +DUK_INTERNAL void duk_pop_undefined(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_pop_nodecref_unsafe(thr); +} +#else /* DUK_USE_PREFER_SIZE */ +DUK_INTERNAL void duk_pop_undefined(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->valstack_top != thr->valstack_bottom); + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1); + + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1)); + thr->valstack_top--; + + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); +} +#endif /* !DUK_USE_PREFER_SIZE */ + +#if defined(DUK_USE_PREFER_SIZE) +DUK_EXTERNAL void duk_pop_2(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_pop_n(thr, 2); +} +DUK_INTERNAL void duk_pop_2_unsafe(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_pop_n_unsafe(thr, 2); +} +DUK_INTERNAL void duk_pop_2_nodecref_unsafe(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_pop_n_nodecref_unsafe(thr, 2); +} +#else +DUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_2_unsafe_raw(duk_hthread *thr) { + duk_tval *tv; + + DUK_CTX_ASSERT_VALID(thr); + DUK_ASSERT(thr->valstack_top != thr->valstack_bottom); + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 2); + + tv = --thr->valstack_top; + DUK_ASSERT(tv >= thr->valstack_bottom); +#if defined(DUK_USE_REFERENCE_COUNTING) + DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv); /* side effects */ +#else + DUK_TVAL_SET_UNDEFINED(tv); +#endif + tv = --thr->valstack_top; + DUK_ASSERT(tv >= thr->valstack_bottom); +#if defined(DUK_USE_REFERENCE_COUNTING) + DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv); /* side effects */ +#else + DUK_TVAL_SET_UNDEFINED(tv); +#endif + + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); +} +DUK_EXTERNAL void duk_pop_2(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + if (DUK_UNLIKELY(thr->valstack_top - 2 < thr->valstack_bottom)) { + DUK_ERROR_RANGE_INVALID_COUNT(thr); + DUK_WO_NORETURN(return;); + } + + duk__pop_2_unsafe_raw(thr); +} +DUK_INTERNAL void duk_pop_2_unsafe(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk__pop_2_unsafe_raw(thr); +} +DUK_INTERNAL void duk_pop_2_nodecref_unsafe(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->valstack_top != thr->valstack_bottom); + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 2); + + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1)); + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 2)); + thr->valstack_top -= 2; + + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); +} +#endif /* !DUK_USE_PREFER_SIZE */ + +DUK_EXTERNAL void duk_pop_3(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_pop_n(thr, 3); +} + +DUK_INTERNAL void duk_pop_3_unsafe(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_pop_n_unsafe(thr, 3); +} + +DUK_INTERNAL void duk_pop_3_nodecref_unsafe(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_pop_n_nodecref_unsafe(thr, 3); +} + +/* + * Pack and unpack (pack value stack entries into an array and vice versa) + */ + +/* XXX: pack index range? array index offset? */ +/* XXX: need ability to pack into a bare array? */ +DUK_INTERNAL void duk_pack(duk_hthread *thr, duk_idx_t count) { + duk_tval *tv_src; + duk_tval *tv_dst; + duk_tval *tv_curr; + duk_tval *tv_limit; + duk_idx_t top; + + DUK_ASSERT_API_ENTRY(thr); + + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + top = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom); + DUK_ASSERT(top >= 0); + if (DUK_UNLIKELY((duk_uidx_t) count > (duk_uidx_t) top)) { + /* Also handles negative count. */ + DUK_ERROR_RANGE_INVALID_COUNT(thr); + DUK_WO_NORETURN(return;); + } + DUK_ASSERT(count >= 0); + + /* Wrapping is controlled by the check above: value stack top can be + * at most DUK_USE_VALSTACK_LIMIT which is low enough so that + * multiplying with sizeof(duk_tval) won't wrap. + */ + DUK_ASSERT(count >= 0 && count <= (duk_idx_t) DUK_USE_VALSTACK_LIMIT); + DUK_ASSERT((duk_size_t) count <= DUK_SIZE_MAX / sizeof(duk_tval)); /* no wrapping */ + + tv_dst = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) count); /* XXX: uninitialized would be OK */ + DUK_ASSERT(count == 0 || tv_dst != NULL); + DUK_ASSERT(!duk_is_bare_object(thr, -1)); + + /* Copy value stack values directly to the array part without + * any refcount updates: net refcount changes are zero. + */ + tv_src = thr->valstack_top - count - 1; + duk_memcpy_unsafe((void *) tv_dst, (const void *) tv_src, (size_t) count * sizeof(duk_tval)); + + /* Overwrite result array to final value stack location and wipe + * the rest; no refcount operations needed. + */ + + tv_dst = tv_src; /* when count == 0, same as tv_src (OK) */ + tv_src = thr->valstack_top - 1; + DUK_TVAL_SET_TVAL(tv_dst, tv_src); + + /* XXX: internal helper to wipe a value stack segment? */ + tv_curr = tv_dst + 1; + tv_limit = thr->valstack_top; + while (tv_curr != tv_limit) { + /* Wipe policy: keep as 'undefined'. */ + DUK_TVAL_SET_UNDEFINED(tv_curr); + tv_curr++; + } + thr->valstack_top = tv_dst + 1; +} + +DUK_INTERNAL duk_idx_t duk_unpack_array_like(duk_hthread *thr, duk_idx_t idx) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + + tv = duk_require_tval(thr, idx); + if (DUK_LIKELY(DUK_TVAL_IS_OBJECT(tv))) { + duk_hobject *h; + duk_uint32_t len; + duk_uint32_t i; + + h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + DUK_UNREF(h); + +#if defined(DUK_USE_ARRAY_FASTPATH) /* close enough */ + if (DUK_LIKELY(DUK_HOBJECT_IS_ARRAY(h) && + ((duk_harray *) h)->length <= DUK_HOBJECT_GET_ASIZE(h))) { + duk_harray *h_arr; + duk_tval *tv_src; + duk_tval *tv_dst; + + h_arr = (duk_harray *) h; + len = h_arr->length; + if (DUK_UNLIKELY(len >= 0x80000000UL)) { + goto fail_over_2g; + } + duk_require_stack(thr, (duk_idx_t) len); + + /* The potential allocation in duk_require_stack() may + * run a finalizer which modifies the argArray so that + * e.g. becomes sparse. So, we need to recheck that the + * array didn't change size and that there's still a + * valid backing array part. + * + * XXX: alternatively, could prevent finalizers for the + * duration. + */ + if (DUK_UNLIKELY(len != h_arr->length || + h_arr->length > DUK_HOBJECT_GET_ASIZE((duk_hobject *) h_arr))) { + goto skip_fast; + } + + /* Main fast path: arguments array is almost always + * an actual array (though it might also be an arguments + * object). + */ + + DUK_DDD(DUK_DDDPRINT("fast path for %ld elements", (long) h_arr->length)); + tv_src = DUK_HOBJECT_A_GET_BASE(thr->heap, h); + tv_dst = thr->valstack_top; + while (len-- > 0) { + DUK_ASSERT(tv_dst < thr->valstack_end); + if (DUK_UNLIKELY(DUK_TVAL_IS_UNUSED(tv_src))) { + /* Gaps are very unlikely. Skip over them, + * without an ancestor lookup (technically + * not compliant). + */ + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_dst)); /* valstack policy */ + } else { + DUK_TVAL_SET_TVAL(tv_dst, tv_src); + DUK_TVAL_INCREF(thr, tv_dst); + } + tv_src++; + tv_dst++; + } + DUK_ASSERT(tv_dst <= thr->valstack_end); + thr->valstack_top = tv_dst; + return (duk_idx_t) h_arr->length; + } + skip_fast: +#endif /* DUK_USE_ARRAY_FASTPATH */ + + /* Slow path: actual lookups. The initial 'length' lookup + * decides the output length, regardless of side effects that + * may resize or change the argArray while we read the + * indices. + */ + idx = duk_normalize_index(thr, idx); + duk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH); + len = duk_to_uint32(thr, -1); /* ToUint32() coercion required */ + if (DUK_UNLIKELY(len >= 0x80000000UL)) { + goto fail_over_2g; + } + duk_pop_unsafe(thr); + DUK_DDD(DUK_DDDPRINT("slow path for %ld elements", (long) len)); + + duk_require_stack(thr, (duk_idx_t) len); + for (i = 0; i < len; i++) { + duk_get_prop_index(thr, idx, (duk_uarridx_t) i); + } + return (duk_idx_t) len; + } else if (DUK_TVAL_IS_UNDEFINED(tv) || DUK_TVAL_IS_NULL(tv)) { + return 0; + } + + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return 0;); + + fail_over_2g: + DUK_ERROR_RANGE_INVALID_LENGTH(thr); + DUK_WO_NORETURN(return 0;); +} + +/* + * Error throwing + */ + +DUK_EXTERNAL void duk_throw_raw(duk_hthread *thr) { + duk_tval *tv_val; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr->valstack_bottom >= thr->valstack); + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + DUK_ASSERT(thr->valstack_end >= thr->valstack_top); + + if (DUK_UNLIKELY(thr->valstack_top == thr->valstack_bottom)) { + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return;); + } + + /* Errors are augmented when they are created, not when they are + * thrown or re-thrown. The current error handler, however, runs + * just before an error is thrown. + */ + + /* Sync so that augmentation sees up-to-date activations, NULL + * thr->ptr_curr_pc so that it's not used if side effects occur + * in augmentation or longjmp handling. + */ + duk_hthread_sync_and_null_currpc(thr); + +#if defined(DUK_USE_AUGMENT_ERROR_THROW) + DUK_DDD(DUK_DDDPRINT("THROW ERROR (API): %!dT (before throw augment)", (duk_tval *) duk_get_tval(thr, -1))); + duk_err_augment_error_throw(thr); +#endif + DUK_DDD(DUK_DDDPRINT("THROW ERROR (API): %!dT (after throw augment)", (duk_tval *) duk_get_tval(thr, -1))); + + tv_val = DUK_GET_TVAL_NEGIDX(thr, -1); + duk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, tv_val); +#if defined(DUK_USE_DEBUGGER_SUPPORT) + duk_err_check_debugger_integration(thr); +#endif + + /* thr->heap->lj.jmpbuf_ptr is checked by duk_err_longjmp() so we don't + * need to check that here. If the value is NULL, a fatal error occurs + * because we can't return. + */ + + duk_err_longjmp(thr); + DUK_UNREACHABLE(); +} + +DUK_EXTERNAL void duk_fatal_raw(duk_hthread *thr, const char *err_msg) { + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(thr->heap->fatal_func != NULL); + + DUK_D(DUK_DPRINT("fatal error occurred: %s", err_msg ? err_msg : "NULL")); + + /* fatal_func should be noreturn, but noreturn declarations on function + * pointers has a very spotty support apparently so it's not currently + * done. + */ + thr->heap->fatal_func(thr->heap->heap_udata, err_msg); + + /* If the fatal handler returns, all bets are off. It'd be nice to + * print something here but since we don't want to depend on stdio, + * there's no way to do so portably. + */ + DUK_D(DUK_DPRINT("fatal error handler returned, all bets are off!")); + for (;;) { + /* loop forever, don't return (function marked noreturn) */ + } +} + +DUK_EXTERNAL void duk_error_va_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap) { + DUK_ASSERT_API_ENTRY(thr); + + duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap); + (void) duk_throw(thr); + DUK_WO_NORETURN(return;); +} + +DUK_EXTERNAL void duk_error_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...) { + va_list ap; + + DUK_ASSERT_API_ENTRY(thr); + + va_start(ap, fmt); + duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap); + va_end(ap); + (void) duk_throw(thr); + DUK_WO_NORETURN(return;); +} + +#if !defined(DUK_USE_VARIADIC_MACROS) +DUK_NORETURN(DUK_LOCAL_DECL void duk__throw_error_from_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, va_list ap)); + +DUK_LOCAL void duk__throw_error_from_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, va_list ap) { + const char *filename; + duk_int_t line; + + DUK_CTX_ASSERT_VALID(thr); + + filename = duk_api_global_filename; + line = duk_api_global_line; + duk_api_global_filename = NULL; + duk_api_global_line = 0; + + duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap); + (void) duk_throw(thr); + DUK_WO_NORETURN(return;); +} + +#define DUK__ERROR_STASH_SHARED(code) do { \ + va_list ap; \ + va_start(ap, fmt); \ + duk__throw_error_from_stash(thr, (code), fmt, ap); \ + va_end(ap); \ + DUK_WO_NORETURN(return 0;); \ + } while (0) + +DUK_EXTERNAL duk_ret_t duk_error_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, ...) { + DUK_ASSERT_API_ENTRY(thr); + DUK__ERROR_STASH_SHARED(err_code); +} +DUK_EXTERNAL duk_ret_t duk_generic_error_stash(duk_hthread *thr, const char *fmt, ...) { + DUK_ASSERT_API_ENTRY(thr); + DUK__ERROR_STASH_SHARED(DUK_ERR_ERROR); +} +DUK_EXTERNAL duk_ret_t duk_eval_error_stash(duk_hthread *thr, const char *fmt, ...) { + DUK_ASSERT_API_ENTRY(thr); + DUK__ERROR_STASH_SHARED(DUK_ERR_EVAL_ERROR); +} +DUK_EXTERNAL duk_ret_t duk_range_error_stash(duk_hthread *thr, const char *fmt, ...) { + DUK_ASSERT_API_ENTRY(thr); + DUK__ERROR_STASH_SHARED(DUK_ERR_RANGE_ERROR); +} +DUK_EXTERNAL duk_ret_t duk_reference_error_stash(duk_hthread *thr, const char *fmt, ...) { + DUK_ASSERT_API_ENTRY(thr); + DUK__ERROR_STASH_SHARED(DUK_ERR_REFERENCE_ERROR); +} +DUK_EXTERNAL duk_ret_t duk_syntax_error_stash(duk_hthread *thr, const char *fmt, ...) { + DUK_ASSERT_API_ENTRY(thr); + DUK__ERROR_STASH_SHARED(DUK_ERR_SYNTAX_ERROR); +} +DUK_EXTERNAL duk_ret_t duk_type_error_stash(duk_hthread *thr, const char *fmt, ...) { + DUK_ASSERT_API_ENTRY(thr); + DUK__ERROR_STASH_SHARED(DUK_ERR_TYPE_ERROR); +} +DUK_EXTERNAL duk_ret_t duk_uri_error_stash(duk_hthread *thr, const char *fmt, ...) { + DUK_ASSERT_API_ENTRY(thr); + DUK__ERROR_STASH_SHARED(DUK_ERR_URI_ERROR); +} +#endif /* DUK_USE_VARIADIC_MACROS */ + +/* + * Comparison + */ + +DUK_EXTERNAL duk_bool_t duk_equals(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) { + duk_tval *tv1, *tv2; + + DUK_ASSERT_API_ENTRY(thr); + + tv1 = duk_get_tval(thr, idx1); + tv2 = duk_get_tval(thr, idx2); + if ((tv1 == NULL) || (tv2 == NULL)) { + return 0; + } + + /* Coercion may be needed, the helper handles that by pushing the + * tagged values to the stack. + */ + return duk_js_equals(thr, tv1, tv2); +} + +DUK_EXTERNAL duk_bool_t duk_strict_equals(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) { + duk_tval *tv1, *tv2; + + DUK_ASSERT_API_ENTRY(thr); + + tv1 = duk_get_tval(thr, idx1); + tv2 = duk_get_tval(thr, idx2); + if ((tv1 == NULL) || (tv2 == NULL)) { + return 0; + } + + /* No coercions or other side effects, so safe */ + return duk_js_strict_equals(tv1, tv2); +} + +DUK_EXTERNAL duk_bool_t duk_samevalue(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) { + duk_tval *tv1, *tv2; + + DUK_ASSERT_API_ENTRY(thr); + + tv1 = duk_get_tval(thr, idx1); + tv2 = duk_get_tval(thr, idx2); + if ((tv1 == NULL) || (tv2 == NULL)) { + return 0; + } + + /* No coercions or other side effects, so safe */ + return duk_js_samevalue(tv1, tv2); +} + +/* + * instanceof + */ + +DUK_EXTERNAL duk_bool_t duk_instanceof(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) { + duk_tval *tv1, *tv2; + + DUK_ASSERT_API_ENTRY(thr); + + /* Index validation is strict, which differs from duk_equals(). + * The strict behavior mimics how instanceof itself works, e.g. + * it is a TypeError if rval is not a -callable- object. It would + * be somewhat inconsistent if rval would be allowed to be + * non-existent without a TypeError. + */ + tv1 = duk_require_tval(thr, idx1); + DUK_ASSERT(tv1 != NULL); + tv2 = duk_require_tval(thr, idx2); + DUK_ASSERT(tv2 != NULL); + + return duk_js_instanceof(thr, tv1, tv2); +} + +/* + * Lightfunc + */ + +DUK_INTERNAL void duk_push_lightfunc_name_raw(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags) { + /* Lightfunc name, includes Duktape/C native function pointer, which + * can often be used to locate the function from a symbol table. + * The name also includes the 16-bit duk_tval flags field because it + * includes the magic value. Because a single native function often + * provides different functionality depending on the magic value, it + * seems reasonably to include it in the name. + * + * On the other hand, a complicated name increases string table + * pressure in low memory environments (but only when function name + * is accessed). + */ + + DUK_ASSERT_API_ENTRY(thr); + + duk_push_literal(thr, "light_"); + duk_push_string_funcptr(thr, (duk_uint8_t *) &func, sizeof(func)); + duk_push_sprintf(thr, "_%04x", (unsigned int) lf_flags); + duk_concat(thr, 3); +} + +DUK_INTERNAL void duk_push_lightfunc_name(duk_hthread *thr, duk_tval *tv) { + duk_c_function func; + duk_small_uint_t lf_flags; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv)); + + DUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags); + duk_push_lightfunc_name_raw(thr, func, lf_flags); +} + +DUK_INTERNAL void duk_push_lightfunc_tostring(duk_hthread *thr, duk_tval *tv) { + duk_c_function func; + duk_small_uint_t lf_flags; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv)); + + DUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags); /* read before 'tv' potentially invalidated */ + duk_push_literal(thr, "function "); + duk_push_lightfunc_name_raw(thr, func, lf_flags); + duk_push_literal(thr, "() { [lightfunc code] }"); + duk_concat(thr, 3); +} + +/* + * Function pointers + * + * Printing function pointers is non-portable, so we do that by hex printing + * bytes from memory. + */ + +DUK_INTERNAL void duk_push_string_funcptr(duk_hthread *thr, duk_uint8_t *ptr, duk_size_t sz) { + duk_uint8_t buf[32 * 2]; + duk_uint8_t *p, *q; + duk_small_uint_t i; + duk_small_uint_t t; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(sz <= 32); /* sanity limit for function pointer size */ + + p = buf; +#if defined(DUK_USE_INTEGER_LE) + q = ptr + sz; +#else + q = ptr; +#endif + for (i = 0; i < sz; i++) { +#if defined(DUK_USE_INTEGER_LE) + t = *(--q); +#else + t = *(q++); +#endif + *p++ = duk_lc_digits[t >> 4]; + *p++ = duk_lc_digits[t & 0x0f]; + } + + duk_push_lstring(thr, (const char *) buf, sz * 2); +} + +/* + * Push readable string summarizing duk_tval. The operation is side effect + * free and will only throw from internal errors (e.g. out of memory). + * This is used by e.g. property access code to summarize a key/base safely, + * and is not intended to be fast (but small and safe). + */ + +/* String limits for summary strings. */ +#define DUK__READABLE_SUMMARY_MAXCHARS 96 /* maximum supported by helper */ +#define DUK__READABLE_STRING_MAXCHARS 32 /* for strings/symbols */ +#define DUK__READABLE_ERRMSG_MAXCHARS 96 /* for error messages */ + +/* String sanitizer which escapes ASCII control characters and a few other + * ASCII characters, passes Unicode as is, and replaces invalid UTF-8 with + * question marks. No errors are thrown for any input string, except in out + * of memory situations. + */ +DUK_LOCAL void duk__push_hstring_readable_unicode(duk_hthread *thr, duk_hstring *h_input, duk_small_uint_t maxchars) { + const duk_uint8_t *p, *p_start, *p_end; + duk_uint8_t buf[DUK_UNICODE_MAX_XUTF8_LENGTH * DUK__READABLE_SUMMARY_MAXCHARS + + 2 /*quotes*/ + 3 /*periods*/]; + duk_uint8_t *q; + duk_ucodepoint_t cp; + duk_small_uint_t nchars; + + DUK_CTX_ASSERT_VALID(thr); + DUK_ASSERT(h_input != NULL); + DUK_ASSERT(maxchars <= DUK__READABLE_SUMMARY_MAXCHARS); + + p_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input); + p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input); + p = p_start; + q = buf; + + nchars = 0; + *q++ = (duk_uint8_t) DUK_ASC_SINGLEQUOTE; + for (;;) { + if (p >= p_end) { + break; + } + if (nchars == maxchars) { + *q++ = (duk_uint8_t) DUK_ASC_PERIOD; + *q++ = (duk_uint8_t) DUK_ASC_PERIOD; + *q++ = (duk_uint8_t) DUK_ASC_PERIOD; + break; + } + if (duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp)) { + if (cp < 0x20 || cp == 0x7f || cp == DUK_ASC_SINGLEQUOTE || cp == DUK_ASC_BACKSLASH) { + DUK_ASSERT(DUK_UNICODE_MAX_XUTF8_LENGTH >= 4); /* estimate is valid */ + DUK_ASSERT((cp >> 4) <= 0x0f); + *q++ = (duk_uint8_t) DUK_ASC_BACKSLASH; + *q++ = (duk_uint8_t) DUK_ASC_LC_X; + *q++ = (duk_uint8_t) duk_lc_digits[cp >> 4]; + *q++ = (duk_uint8_t) duk_lc_digits[cp & 0x0f]; + } else { + q += duk_unicode_encode_xutf8(cp, q); + } + } else { + p++; /* advance manually */ + *q++ = (duk_uint8_t) DUK_ASC_QUESTION; + } + nchars++; + } + *q++ = (duk_uint8_t) DUK_ASC_SINGLEQUOTE; + + duk_push_lstring(thr, (const char *) buf, (duk_size_t) (q - buf)); +} + +DUK_LOCAL const char *duk__push_string_tval_readable(duk_hthread *thr, duk_tval *tv, duk_bool_t error_aware) { + DUK_CTX_ASSERT_VALID(thr); + /* 'tv' may be NULL */ + + if (tv == NULL) { + duk_push_literal(thr, "none"); + } else { + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_STRING: { + duk_hstring *h = DUK_TVAL_GET_STRING(tv); + if (DUK_HSTRING_HAS_SYMBOL(h)) { + /* XXX: string summary produces question marks + * so this is not very ideal. + */ + duk_push_literal(thr, "[Symbol "); + duk_push_string(thr, duk__get_symbol_type_string(h)); + duk_push_literal(thr, " "); + duk__push_hstring_readable_unicode(thr, h, DUK__READABLE_STRING_MAXCHARS); + duk_push_literal(thr, "]"); + duk_concat(thr, 5); + break; + } + duk__push_hstring_readable_unicode(thr, h, DUK__READABLE_STRING_MAXCHARS); + break; + } + case DUK_TAG_OBJECT: { + duk_hobject *h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + + if (error_aware && + duk_hobject_prototype_chain_contains(thr, h, thr->builtins[DUK_BIDX_ERROR_PROTOTYPE], 1 /*ignore_loop*/)) { + /* Get error message in a side effect free way if + * possible; if not, summarize as a generic object. + * Error message currently gets quoted. + */ + /* XXX: better internal getprop call; get without side effects + * but traverse inheritance chain. + */ + duk_tval *tv_msg; + tv_msg = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, h, DUK_STRIDX_MESSAGE); + if (tv_msg != NULL && DUK_TVAL_IS_STRING(tv_msg)) { + /* It's critical to avoid recursion so + * only summarize a string .message. + */ + duk__push_hstring_readable_unicode(thr, DUK_TVAL_GET_STRING(tv_msg), DUK__READABLE_ERRMSG_MAXCHARS); + break; + } + } + duk_push_class_string_tval(thr, tv, 1 /*avoid_side_effects*/); + break; + } + case DUK_TAG_BUFFER: { + /* While plain buffers mimic Uint8Arrays, they summarize differently. + * This is useful so that the summarized string accurately reflects the + * internal type which may matter for figuring out bugs etc. + */ + /* XXX: Hex encoded, length limited buffer summary here? */ + duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv); + DUK_ASSERT(h != NULL); + duk_push_sprintf(thr, "[buffer:%ld]", (long) DUK_HBUFFER_GET_SIZE(h)); + break; + } + case DUK_TAG_POINTER: { + /* Surround with parentheses like in JX, ensures NULL pointer + * is distinguishable from null value ("(null)" vs "null"). + */ + duk_push_tval(thr, tv); + duk_push_sprintf(thr, "(%s)", duk_to_string(thr, -1)); + duk_remove_m2(thr); + break; + } + default: { + duk_push_tval(thr, tv); + break; + } + } + } + + return duk_to_string(thr, -1); +} +DUK_INTERNAL const char *duk_push_string_tval_readable(duk_hthread *thr, duk_tval *tv) { + DUK_ASSERT_API_ENTRY(thr); + return duk__push_string_tval_readable(thr, tv, 0 /*error_aware*/); +} + +DUK_INTERNAL const char *duk_push_string_readable(duk_hthread *thr, duk_idx_t idx) { + DUK_ASSERT_API_ENTRY(thr); + return duk_push_string_tval_readable(thr, duk_get_tval(thr, idx)); +} + +DUK_INTERNAL const char *duk_push_string_tval_readable_error(duk_hthread *thr, duk_tval *tv) { + DUK_ASSERT_API_ENTRY(thr); + return duk__push_string_tval_readable(thr, tv, 1 /*error_aware*/); +} + +DUK_INTERNAL void duk_push_symbol_descriptive_string(duk_hthread *thr, duk_hstring *h) { + const duk_uint8_t *p; + const duk_uint8_t *p_end; + const duk_uint8_t *q; + + DUK_ASSERT_API_ENTRY(thr); + + /* .toString() */ + duk_push_literal(thr, "Symbol("); + p = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h); + p_end = p + DUK_HSTRING_GET_BYTELEN(h); + DUK_ASSERT(p[0] == 0xff || (p[0] & 0xc0) == 0x80); + p++; + for (q = p; q < p_end; q++) { + if (*q == 0xffU) { + /* Terminate either at end-of-string (but NUL MUST + * be accepted without terminating description) or + * 0xFF, which is used to mark start of unique trailer + * (and cannot occur in CESU-8 / extended UTF-8). + */ + break; + } + } + duk_push_lstring(thr, (const char *) p, (duk_size_t) (q - p)); + duk_push_literal(thr, ")"); + duk_concat(thr, 3); +} + +/* + * Functions + */ + +#if 0 /* not used yet */ +DUK_INTERNAL void duk_push_hnatfunc_name(duk_hthread *thr, duk_hnatfunc *h) { + duk_c_function func; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(h != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h)); + + duk_push_sprintf(thr, "native_"); + func = h->func; + duk_push_string_funcptr(thr, (duk_uint8_t *) &func, sizeof(func)); + duk_push_sprintf(thr, "_%04x_%04x", + (unsigned int) (duk_uint16_t) h->nargs, + (unsigned int) (duk_uint16_t) h->magic); + duk_concat(thr, 3); +} +#endif + +/* + * duk_tval slice copy + */ + +DUK_INTERNAL void duk_copy_tvals_incref(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_size_t count) { + duk_tval *tv; + + DUK_ASSERT_API_ENTRY(thr); + DUK_UNREF(thr); + DUK_ASSERT(count * sizeof(duk_tval) >= count); /* no wrap */ + + duk_memcpy_unsafe((void *) tv_dst, (const void *) tv_src, count * sizeof(duk_tval)); + + tv = tv_dst; + while (count-- > 0) { + DUK_TVAL_INCREF(thr, tv); + tv++; + } +} diff --git a/third_party/duktape/duk_api_string.c b/third_party/duktape/duk_api_string.c new file mode 100644 index 00000000..b6b465af --- /dev/null +++ b/third_party/duktape/duk_api_string.c @@ -0,0 +1,378 @@ +/* + * String manipulation + */ + +#include "third_party/duktape/duk_internal.h" + +DUK_LOCAL void duk__concat_and_join_helper(duk_hthread *thr, duk_idx_t count_in, duk_bool_t is_join) { + duk_uint_t count; + duk_uint_t i; + duk_size_t idx; + duk_size_t len; + duk_hstring *h; + duk_uint8_t *buf; + + DUK_CTX_ASSERT_VALID(thr); + + if (DUK_UNLIKELY(count_in <= 0)) { + if (count_in < 0) { + DUK_ERROR_RANGE_INVALID_COUNT(thr); + DUK_WO_NORETURN(return;); + } + DUK_ASSERT(count_in == 0); + duk_push_hstring_empty(thr); + return; + } + count = (duk_uint_t) count_in; + + if (is_join) { + duk_size_t t1, t2, limit; + h = duk_to_hstring(thr, -((duk_idx_t) count) - 1); + DUK_ASSERT(h != NULL); + + /* A bit tricky overflow test, see doc/code-issues.rst. */ + t1 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h); + t2 = (duk_size_t) (count - 1); + limit = (duk_size_t) DUK_HSTRING_MAX_BYTELEN; + if (DUK_UNLIKELY(t2 != 0 && t1 > limit / t2)) { + /* Combined size of separators already overflows. */ + goto error_overflow; + } + len = (duk_size_t) (t1 * t2); + } else { + len = (duk_size_t) 0; + } + + for (i = count; i >= 1; i--) { + duk_size_t new_len; + h = duk_to_hstring(thr, -((duk_idx_t) i)); + new_len = len + (duk_size_t) DUK_HSTRING_GET_BYTELEN(h); + + /* Impose a string maximum length, need to handle overflow + * correctly. + */ + if (new_len < len || /* wrapped */ + new_len > (duk_size_t) DUK_HSTRING_MAX_BYTELEN) { + goto error_overflow; + } + len = new_len; + } + + DUK_DDD(DUK_DDDPRINT("join/concat %lu strings, total length %lu bytes", + (unsigned long) count, (unsigned long) len)); + + /* Use stack allocated buffer to ensure reachability in errors + * (e.g. intern error). + */ + buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len); + DUK_ASSERT(buf != NULL); + + /* [ ... (sep) str1 str2 ... strN buf ] */ + + idx = 0; + for (i = count; i >= 1; i--) { + if (is_join && i != count) { + h = duk_require_hstring(thr, -((duk_idx_t) count) - 2); /* extra -1 for buffer */ + duk_memcpy(buf + idx, DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h)); + idx += DUK_HSTRING_GET_BYTELEN(h); + } + h = duk_require_hstring(thr, -((duk_idx_t) i) - 1); /* extra -1 for buffer */ + duk_memcpy(buf + idx, DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h)); + idx += DUK_HSTRING_GET_BYTELEN(h); + } + + DUK_ASSERT(idx == len); + + /* [ ... (sep) str1 str2 ... strN buf ] */ + + /* Get rid of the strings early to minimize memory use before intern. */ + + if (is_join) { + duk_replace(thr, -((duk_idx_t) count) - 2); /* overwrite sep */ + duk_pop_n(thr, (duk_idx_t) count); + } else { + duk_replace(thr, -((duk_idx_t) count) - 1); /* overwrite str1 */ + duk_pop_n(thr, (duk_idx_t) (count - 1)); + } + + /* [ ... buf ] */ + + (void) duk_buffer_to_string(thr, -1); /* Safe if inputs are safe. */ + + /* [ ... res ] */ + return; + + error_overflow: + DUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG); + DUK_WO_NORETURN(return;); +} + +DUK_EXTERNAL void duk_concat(duk_hthread *thr, duk_idx_t count) { + DUK_ASSERT_API_ENTRY(thr); + + duk__concat_and_join_helper(thr, count, 0 /*is_join*/); +} + +#if defined(DUK_USE_PREFER_SIZE) +DUK_INTERNAL void duk_concat_2(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + duk_concat(thr, 2); +} +#else /* DUK_USE_PREFER_SIZE */ +DUK_INTERNAL void duk_concat_2(duk_hthread *thr) { + duk_hstring *h1; + duk_hstring *h2; + duk_uint8_t *buf; + duk_size_t len1; + duk_size_t len2; + duk_size_t len; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(duk_get_top(thr) >= 2); /* Trusted caller. */ + + h1 = duk_to_hstring(thr, -2); + h2 = duk_to_hstring(thr, -1); + len1 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h1); + len2 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h2); + len = len1 + len2; + if (DUK_UNLIKELY(len < len1 || /* wrapped */ + len > (duk_size_t) DUK_HSTRING_MAX_BYTELEN)) { + goto error_overflow; + } + buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len); + DUK_ASSERT(buf != NULL); + + duk_memcpy((void *) buf, (const void *) DUK_HSTRING_GET_DATA(h1), (size_t) len1); + duk_memcpy((void *) (buf + len1), (const void *) DUK_HSTRING_GET_DATA(h2), (size_t) len2); + (void) duk_buffer_to_string(thr, -1); /* Safe if inputs are safe. */ + + /* [ ... str1 str2 buf ] */ + + duk_replace(thr, -3); + duk_pop_unsafe(thr); + return; + + error_overflow: + DUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG); + DUK_WO_NORETURN(return;); +} +#endif /* DUK_USE_PREFER_SIZE */ + +DUK_EXTERNAL void duk_join(duk_hthread *thr, duk_idx_t count) { + DUK_ASSERT_API_ENTRY(thr); + + duk__concat_and_join_helper(thr, count, 1 /*is_join*/); +} + +/* XXX: could map/decode be unified with duk_unicode_support.c code? + * Case conversion needs also the character surroundings though. + */ + +DUK_EXTERNAL void duk_decode_string(duk_hthread *thr, duk_idx_t idx, duk_decode_char_function callback, void *udata) { + duk_hstring *h_input; + const duk_uint8_t *p, *p_start, *p_end; + duk_codepoint_t cp; + + DUK_ASSERT_API_ENTRY(thr); + + h_input = duk_require_hstring(thr, idx); /* Accept symbols. */ + DUK_ASSERT(h_input != NULL); + + p_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input); + p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input); + p = p_start; + + for (;;) { + if (p >= p_end) { + break; + } + cp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end); + callback(udata, cp); + } +} + +DUK_EXTERNAL void duk_map_string(duk_hthread *thr, duk_idx_t idx, duk_map_char_function callback, void *udata) { + duk_hstring *h_input; + duk_bufwriter_ctx bw_alloc; + duk_bufwriter_ctx *bw; + const duk_uint8_t *p, *p_start, *p_end; + duk_codepoint_t cp; + + DUK_ASSERT_API_ENTRY(thr); + + idx = duk_normalize_index(thr, idx); + + h_input = duk_require_hstring(thr, idx); /* Accept symbols. */ + DUK_ASSERT(h_input != NULL); + + bw = &bw_alloc; + DUK_BW_INIT_PUSHBUF(thr, bw, DUK_HSTRING_GET_BYTELEN(h_input)); /* Reasonable output estimate. */ + + p_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input); + p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input); + p = p_start; + + for (;;) { + /* XXX: could write output in chunks with fewer ensure calls, + * but relative benefit would be small here. + */ + + if (p >= p_end) { + break; + } + cp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end); + cp = callback(udata, cp); + + DUK_BW_WRITE_ENSURE_XUTF8(thr, bw, cp); + } + + DUK_BW_COMPACT(thr, bw); + (void) duk_buffer_to_string(thr, -1); /* Safe, extended UTF-8 encoded. */ + duk_replace(thr, idx); +} + +DUK_EXTERNAL void duk_substring(duk_hthread *thr, duk_idx_t idx, duk_size_t start_offset, duk_size_t end_offset) { + duk_hstring *h; + duk_hstring *res; + duk_size_t start_byte_offset; + duk_size_t end_byte_offset; + duk_size_t charlen; + + DUK_ASSERT_API_ENTRY(thr); + + idx = duk_require_normalize_index(thr, idx); /* Accept symbols. */ + h = duk_require_hstring(thr, idx); + DUK_ASSERT(h != NULL); + + charlen = DUK_HSTRING_GET_CHARLEN(h); + if (end_offset >= charlen) { + end_offset = charlen; + } + if (start_offset > end_offset) { + start_offset = end_offset; + } + + DUK_ASSERT_DISABLE(start_offset >= 0); + DUK_ASSERT(start_offset <= end_offset && start_offset <= DUK_HSTRING_GET_CHARLEN(h)); + DUK_ASSERT_DISABLE(end_offset >= 0); + DUK_ASSERT(end_offset >= start_offset && end_offset <= DUK_HSTRING_GET_CHARLEN(h)); + + /* Guaranteed by string limits. */ + DUK_ASSERT(start_offset <= DUK_UINT32_MAX); + DUK_ASSERT(end_offset <= DUK_UINT32_MAX); + + start_byte_offset = (duk_size_t) duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t) start_offset); + end_byte_offset = (duk_size_t) duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t) end_offset); + + DUK_ASSERT(end_byte_offset >= start_byte_offset); + DUK_ASSERT(end_byte_offset - start_byte_offset <= DUK_UINT32_MAX); /* Guaranteed by string limits. */ + + /* No size check is necessary. */ + res = duk_heap_strtable_intern_checked(thr, + DUK_HSTRING_GET_DATA(h) + start_byte_offset, + (duk_uint32_t) (end_byte_offset - start_byte_offset)); + + duk_push_hstring(thr, res); + duk_replace(thr, idx); +} + +/* XXX: this is quite clunky. Add Unicode helpers to scan backwards and + * forwards with a callback to process codepoints? + */ +DUK_EXTERNAL void duk_trim(duk_hthread *thr, duk_idx_t idx) { + duk_hstring *h; + const duk_uint8_t *p, *p_start, *p_end, *p_tmp1, *p_tmp2; /* pointers for scanning */ + const duk_uint8_t *q_start, *q_end; /* start (incl) and end (excl) of trimmed part */ + duk_codepoint_t cp; + + DUK_ASSERT_API_ENTRY(thr); + + idx = duk_require_normalize_index(thr, idx); /* Accept symbols. */ + h = duk_require_hstring(thr, idx); + DUK_ASSERT(h != NULL); + + p_start = DUK_HSTRING_GET_DATA(h); + p_end = p_start + DUK_HSTRING_GET_BYTELEN(h); + + p = p_start; + while (p < p_end) { + p_tmp1 = p; + cp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p_tmp1, p_start, p_end); + if (!(duk_unicode_is_whitespace(cp) || duk_unicode_is_line_terminator(cp))) { + break; + } + p = p_tmp1; + } + q_start = p; + if (p == p_end) { + /* Entire string is whitespace. */ + q_end = p; + goto scan_done; + } + + p = p_end; + while (p > p_start) { + p_tmp1 = p; + while (p > p_start) { + p--; + if (((*p) & 0xc0) != 0x80) { + break; + } + } + p_tmp2 = p; + + cp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p_tmp2, p_start, p_end); + if (!(duk_unicode_is_whitespace(cp) || duk_unicode_is_line_terminator(cp))) { + p = p_tmp1; + break; + } + } + q_end = p; + + scan_done: + /* This may happen when forward and backward scanning disagree + * (possible for non-extended-UTF-8 strings). + */ + if (q_end < q_start) { + q_end = q_start; + } + + DUK_ASSERT(q_start >= p_start && q_start <= p_end); + DUK_ASSERT(q_end >= p_start && q_end <= p_end); + DUK_ASSERT(q_end >= q_start); + + DUK_DDD(DUK_DDDPRINT("trim: p_start=%p, p_end=%p, q_start=%p, q_end=%p", + (const void *) p_start, (const void *) p_end, + (const void *) q_start, (const void *) q_end)); + + if (q_start == p_start && q_end == p_end) { + DUK_DDD(DUK_DDDPRINT("nothing was trimmed: avoid interning (hashing etc)")); + return; + } + + duk_push_lstring(thr, (const char *) q_start, (duk_size_t) (q_end - q_start)); + duk_replace(thr, idx); +} + +DUK_EXTERNAL duk_codepoint_t duk_char_code_at(duk_hthread *thr, duk_idx_t idx, duk_size_t char_offset) { + duk_hstring *h; + duk_ucodepoint_t cp; + + DUK_ASSERT_API_ENTRY(thr); + + /* XXX: Share code with String.prototype.charCodeAt? Main difference + * is handling of clamped offsets. + */ + + h = duk_require_hstring(thr, idx); /* Accept symbols. */ + DUK_ASSERT(h != NULL); + + DUK_ASSERT_DISABLE(char_offset >= 0); /* Always true, arg is unsigned. */ + if (char_offset >= DUK_HSTRING_GET_CHARLEN(h)) { + return 0; + } + + DUK_ASSERT(char_offset <= DUK_UINT_MAX); /* Guaranteed by string limits. */ + cp = duk_hstring_char_code_at_raw(thr, h, (duk_uint_t) char_offset, 0 /*surrogate_aware*/); + return (duk_codepoint_t) cp; +} diff --git a/third_party/duktape/duk_api_time.c b/third_party/duktape/duk_api_time.c new file mode 100644 index 00000000..57625037 --- /dev/null +++ b/third_party/duktape/duk_api_time.c @@ -0,0 +1,110 @@ +/* + * Date/time. + */ + +#include "third_party/duktape/duk_internal.h" + +DUK_INTERNAL duk_double_t duk_time_get_ecmascript_time(duk_hthread *thr) { + /* ECMAScript time, with millisecond fractions. Exposed via + * duk_get_now() for example. + */ + DUK_UNREF(thr); + return (duk_double_t) DUK_USE_DATE_GET_NOW(thr); +} + +DUK_INTERNAL duk_double_t duk_time_get_ecmascript_time_nofrac(duk_hthread *thr) { + /* ECMAScript time without millisecond fractions. Exposed via + * the Date built-in which doesn't allow fractions. + */ + DUK_UNREF(thr); + return (duk_double_t) DUK_FLOOR(DUK_USE_DATE_GET_NOW(thr)); +} + +DUK_INTERNAL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr) { + DUK_UNREF(thr); +#if defined(DUK_USE_GET_MONOTONIC_TIME) + return (duk_double_t) DUK_USE_GET_MONOTONIC_TIME(thr); +#else + return (duk_double_t) DUK_USE_DATE_GET_NOW(thr); +#endif +} + +DUK_EXTERNAL duk_double_t duk_get_now(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + DUK_UNREF(thr); + + /* This API intentionally allows millisecond fractions. */ + return duk_time_get_ecmascript_time(thr); +} + +#if 0 /* XXX: worth exposing? */ +DUK_EXTERNAL duk_double_t duk_get_monotonic_time(duk_hthread *thr) { + DUK_ASSERT_API_ENTRY(thr); + DUK_UNREF(thr); + + return duk_time_get_monotonic_time(thr); +} +#endif + +DUK_EXTERNAL void duk_time_to_components(duk_hthread *thr, duk_double_t timeval, duk_time_components *comp) { + duk_int_t parts[DUK_DATE_IDX_NUM_PARTS]; + duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS]; + duk_uint_t flags; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(comp != NULL); /* XXX: or check? */ + DUK_UNREF(thr); + + /* Convert as one-based, but change month to zero-based to match the + * ECMAScript Date built-in behavior 1:1. + */ + flags = DUK_DATE_FLAG_ONEBASED | DUK_DATE_FLAG_NAN_TO_ZERO; + + duk_bi_date_timeval_to_parts(timeval, parts, dparts, flags); + + /* XXX: sub-millisecond accuracy for the API */ + + DUK_ASSERT(dparts[DUK_DATE_IDX_MONTH] >= 1.0 && dparts[DUK_DATE_IDX_MONTH] <= 12.0); + comp->year = dparts[DUK_DATE_IDX_YEAR]; + comp->month = dparts[DUK_DATE_IDX_MONTH] - 1.0; + comp->day = dparts[DUK_DATE_IDX_DAY]; + comp->hours = dparts[DUK_DATE_IDX_HOUR]; + comp->minutes = dparts[DUK_DATE_IDX_MINUTE]; + comp->seconds = dparts[DUK_DATE_IDX_SECOND]; + comp->milliseconds = dparts[DUK_DATE_IDX_MILLISECOND]; + comp->weekday = dparts[DUK_DATE_IDX_WEEKDAY]; +} + +DUK_EXTERNAL duk_double_t duk_components_to_time(duk_hthread *thr, duk_time_components *comp) { + duk_double_t d; + duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS]; + duk_uint_t flags; + + DUK_ASSERT_API_ENTRY(thr); + DUK_ASSERT(comp != NULL); /* XXX: or check? */ + DUK_UNREF(thr); + + /* Match Date constructor behavior (with UTC time). Month is given + * as zero-based. Day-of-month is given as one-based so normalize + * it to zero-based as the internal conversion helpers expects all + * components to be zero-based. + */ + flags = 0; + + /* XXX: expensive conversion; use array format in API instead, or unify + * time provider and time API to use same struct? + */ + + dparts[DUK_DATE_IDX_YEAR] = comp->year; + dparts[DUK_DATE_IDX_MONTH] = comp->month; + dparts[DUK_DATE_IDX_DAY] = comp->day - 1.0; + dparts[DUK_DATE_IDX_HOUR] = comp->hours; + dparts[DUK_DATE_IDX_MINUTE] = comp->minutes; + dparts[DUK_DATE_IDX_SECOND] = comp->seconds; + dparts[DUK_DATE_IDX_MILLISECOND] = comp->milliseconds; + dparts[DUK_DATE_IDX_WEEKDAY] = 0; /* ignored */ + + d = duk_bi_date_get_timeval_from_dparts(dparts, flags); + + return d; +} diff --git a/third_party/duktape/duk_bi_array.c b/third_party/duktape/duk_bi_array.c new file mode 100644 index 00000000..b1ed5bd9 --- /dev/null +++ b/third_party/duktape/duk_bi_array.c @@ -0,0 +1,1647 @@ +/* + * Array built-ins + * + * Most Array built-ins are intentionally generic in ECMAScript, and are + * intended to work even when the 'this' binding is not an Array instance. + * This ECMAScript feature is also used by much real world code. For this + * reason the implementations here don't assume exotic Array behavior or + * e.g. presence of a .length property. However, some algorithms have a + * fast path for duk_harray backed actual Array instances, enabled when + * footprint is not a concern. + * + * XXX: the "Throw" flag should be set for (almost?) all [[Put]] and + * [[Delete]] operations, but it's currently false throughout. Go through + * all put/delete cases and check throw flag use. Need a new API primitive + * which allows throws flag to be specified. + * + * XXX: array lengths above 2G won't work reliably. There are many places + * where one needs a full signed 32-bit range ([-0xffffffff, 0xffffffff], + * i.e. -33- bits). Although array 'length' cannot be written to be outside + * the unsigned 32-bit range (E5.1 Section 15.4.5.1 throws a RangeError if so) + * some intermediate values may be above 0xffffffff and this may not be always + * correctly handled now (duk_uint32_t is not enough for all algorithms). + * For instance, push() can legitimately write entries beyond length 0xffffffff + * and cause a RangeError only at the end. To do this properly, the current + * push() implementation tracks the array index using a 'double' instead of a + * duk_uint32_t (which is somewhat awkward). See test-bi-array-push-maxlen.js. + * + * On using "put" vs. "def" prop + * ============================= + * + * Code below must be careful to use the appropriate primitive as it matters + * for compliance. When using "put" there may be inherited properties in + * Array.prototype which cause side effects when values are written. When + * using "define" there are no such side effects, and many test262 test cases + * check for this (for real world code, such side effects are very rare). + * Both "put" and "define" are used in the E5.1 specification; as a rule, + * "put" is used when modifying an existing array (or a non-array 'this' + * binding) and "define" for setting values into a fresh result array. + */ + +#include "third_party/duktape/duk_internal.h" + +/* Perform an intermediate join when this many elements have been pushed + * on the value stack. + */ +#define DUK__ARRAY_MID_JOIN_LIMIT 4096 + +#if defined(DUK_USE_ARRAY_BUILTIN) + +/* + * Shared helpers. + */ + +/* Shared entry code for many Array built-ins: the 'this' binding is pushed + * on the value stack and object coerced, and the current .length is returned. + * Note that length is left on stack (it could be popped, but that's not + * usually necessary because call handling will clean it up automatically). + */ +DUK_LOCAL duk_uint32_t duk__push_this_obj_len_u32(duk_hthread *thr) { + duk_uint32_t len; + + /* XXX: push more directly? */ + (void) duk_push_this_coercible_to_object(thr); + DUK_HOBJECT_ASSERT_VALID(duk_get_hobject(thr, -1)); + duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_LENGTH); + len = duk_to_uint32(thr, -1); + + /* -> [ ... ToObject(this) ToUint32(length) ] */ + return len; +} + +DUK_LOCAL duk_uint32_t duk__push_this_obj_len_u32_limited(duk_hthread *thr) { + /* Range limited to [0, 0x7fffffff] range, i.e. range that can be + * represented with duk_int32_t. Use this when the method doesn't + * handle the full 32-bit unsigned range correctly. + */ + duk_uint32_t ret = duk__push_this_obj_len_u32(thr); + if (DUK_UNLIKELY(ret >= 0x80000000UL)) { + DUK_ERROR_RANGE_INVALID_LENGTH(thr); + DUK_WO_NORETURN(return 0U;); + } + return ret; +} + +#if defined(DUK_USE_ARRAY_FASTPATH) +/* Check if 'this' binding is an Array instance (duk_harray) which satisfies + * a few other guarantees for fast path operation. The fast path doesn't + * need to handle all operations, even for duk_harrays, but must handle a + * significant fraction to improve performance. Return a non-NULL duk_harray + * pointer when all fast path criteria are met, NULL otherwise. + */ +DUK_LOCAL duk_harray *duk__arraypart_fastpath_this(duk_hthread *thr) { + duk_tval *tv; + duk_hobject *h; + duk_uint_t flags_mask, flags_bits, flags_value; + + DUK_ASSERT(thr->valstack_bottom > thr->valstack); /* because call in progress */ + tv = DUK_GET_THIS_TVAL_PTR(thr); + + /* Fast path requires that 'this' is a duk_harray. Read only arrays + * (ROM backed) are also rejected for simplicity. + */ + if (!DUK_TVAL_IS_OBJECT(tv)) { + DUK_DD(DUK_DDPRINT("reject array fast path: not an object")); + return NULL; + } + h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + flags_mask = DUK_HOBJECT_FLAG_ARRAY_PART | \ + DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \ + DUK_HEAPHDR_FLAG_READONLY; + flags_bits = DUK_HOBJECT_FLAG_ARRAY_PART | \ + DUK_HOBJECT_FLAG_EXOTIC_ARRAY; + flags_value = DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) h); + if ((flags_value & flags_mask) != flags_bits) { + DUK_DD(DUK_DDPRINT("reject array fast path: object flag check failed")); + return NULL; + } + + /* In some cases a duk_harray's 'length' may be larger than the + * current array part allocation. Avoid the fast path in these + * cases, so that all fast path code can safely assume that all + * items in the range [0,length[ are backed by the current array + * part allocation. + */ + if (((duk_harray *) h)->length > DUK_HOBJECT_GET_ASIZE(h)) { + DUK_DD(DUK_DDPRINT("reject array fast path: length > array part size")); + return NULL; + } + + /* Guarantees for fast path. */ + DUK_ASSERT(h != NULL); + DUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0 || DUK_HOBJECT_A_GET_BASE(thr->heap, h) != NULL); + DUK_ASSERT(((duk_harray *) h)->length <= DUK_HOBJECT_GET_ASIZE(h)); + + DUK_DD(DUK_DDPRINT("array fast path allowed for: %!O", (duk_heaphdr *) h)); + return (duk_harray *) h; +} +#endif /* DUK_USE_ARRAY_FASTPATH */ + +/* + * Constructor + */ + +DUK_INTERNAL duk_ret_t duk_bi_array_constructor(duk_hthread *thr) { + duk_idx_t nargs; + duk_harray *a; + duk_double_t d; + duk_uint32_t len; + duk_uint32_t len_prealloc; + + nargs = duk_get_top(thr); + + if (nargs == 1 && duk_is_number(thr, 0)) { + /* XXX: expensive check (also shared elsewhere - so add a shared internal API call?) */ + d = duk_get_number(thr, 0); + len = duk_to_uint32(thr, 0); + if (!duk_double_equals((duk_double_t) len, d)) { + DUK_DCERROR_RANGE_INVALID_LENGTH(thr); + } + + /* For small lengths create a dense preallocated array. + * For large arrays preallocate an initial part. + */ + len_prealloc = len < 64 ? len : 64; + a = duk_push_harray_with_size(thr, len_prealloc); + DUK_ASSERT(a != NULL); + DUK_ASSERT(!duk_is_bare_object(thr, -1)); + a->length = len; + return 1; + } + + duk_pack(thr, nargs); + return 1; +} + +/* + * isArray() + */ + +DUK_INTERNAL duk_ret_t duk_bi_array_constructor_is_array(duk_hthread *thr) { + DUK_ASSERT_TOP(thr, 1); + duk_push_boolean(thr, duk_js_isarray(DUK_GET_TVAL_POSIDX(thr, 0))); + return 1; +} + +/* + * toString() + */ + +DUK_INTERNAL duk_ret_t duk_bi_array_prototype_to_string(duk_hthread *thr) { + (void) duk_push_this_coercible_to_object(thr); + duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_JOIN); + + /* [ ... this func ] */ + if (!duk_is_callable(thr, -1)) { + /* Fall back to the initial (original) Object.toString(). We don't + * currently have pointers to the built-in functions, only the top + * level global objects (like "Array") so this is now done in a bit + * of a hacky manner. It would be cleaner to push the (original) + * function and use duk_call_method(). + */ + + /* XXX: 'this' will be ToObject() coerced twice, which is incorrect + * but should have no visible side effects. + */ + DUK_DDD(DUK_DDDPRINT("this.join is not callable, fall back to (original) Object.toString")); + duk_set_top(thr, 0); + return duk_bi_object_prototype_to_string(thr); /* has access to 'this' binding */ + } + + /* [ ... this func ] */ + + duk_insert(thr, -2); + + /* [ ... func this ] */ + + DUK_DDD(DUK_DDDPRINT("calling: func=%!iT, this=%!iT", + (duk_tval *) duk_get_tval(thr, -2), + (duk_tval *) duk_get_tval(thr, -1))); + duk_call_method(thr, 0); + + return 1; +} + +/* + * concat() + */ + +DUK_INTERNAL duk_ret_t duk_bi_array_prototype_concat(duk_hthread *thr) { + duk_idx_t i, n; + duk_uint32_t j, idx, len; + duk_hobject *h; + duk_size_t tmp_len; + + /* XXX: In ES2015 Array .length can be up to 2^53-1. The current + * implementation is limited to 2^32-1. + */ + + /* XXX: Fast path for array 'this' and array element. */ + + /* XXX: The insert here is a bit expensive if there are a lot of items. + * It could also be special cased in the outermost for loop quite easily + * (as the element is dup()'d anyway). + */ + + (void) duk_push_this_coercible_to_object(thr); + duk_insert(thr, 0); + n = duk_get_top(thr); + duk_push_array(thr); /* -> [ ToObject(this) item1 ... itemN arr ] */ + + /* NOTE: The Array special behaviors are NOT invoked by duk_xdef_prop_index() + * (which differs from the official algorithm). If no error is thrown, this + * doesn't matter as the length is updated at the end. However, if an error + * is thrown, the length will be unset. That shouldn't matter because the + * caller won't get a reference to the intermediate value. + */ + + idx = 0; + for (i = 0; i < n; i++) { + duk_bool_t spreadable; + duk_bool_t need_has_check; + + DUK_ASSERT_TOP(thr, n + 1); + + /* [ ToObject(this) item1 ... itemN arr ] */ + + h = duk_get_hobject(thr, i); + + if (h == NULL) { + spreadable = 0; + } else { +#if defined(DUK_USE_SYMBOL_BUILTIN) + duk_get_prop_stridx(thr, i, DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE); + if (duk_is_undefined(thr, -1)) { + spreadable = duk_js_isarray_hobject(h); + } else { + spreadable = duk_to_boolean(thr, -1); + } + duk_pop_nodecref_unsafe(thr); +#else + spreadable = duk_js_isarray_hobject(h); +#endif + } + + if (!spreadable) { + duk_dup(thr, i); + duk_xdef_prop_index_wec(thr, -2, idx); + idx++; + if (DUK_UNLIKELY(idx == 0U)) { + /* Index after update is 0, and index written + * was 0xffffffffUL which is no longer a valid + * array index. + */ + goto fail_wrap; + } + continue; + } + + DUK_ASSERT(duk_is_object(thr, i)); + need_has_check = (DUK_HOBJECT_IS_PROXY(h) != 0); /* Always 0 w/o Proxy support. */ + + /* [ ToObject(this) item1 ... itemN arr ] */ + + tmp_len = duk_get_length(thr, i); + len = (duk_uint32_t) tmp_len; + if (DUK_UNLIKELY(tmp_len != (duk_size_t) len)) { + goto fail_wrap; + } + if (DUK_UNLIKELY(idx + len < idx)) { + /* Result length must be at most 0xffffffffUL to be + * a valid 32-bit array index. + */ + goto fail_wrap; + } + for (j = 0; j < len; j++) { + /* For a Proxy element, an explicit 'has' check is + * needed to allow the Proxy to present gaps. + */ + if (need_has_check) { + if (duk_has_prop_index(thr, i, j)) { + duk_get_prop_index(thr, i, j); + duk_xdef_prop_index_wec(thr, -2, idx); + } + } else { + if (duk_get_prop_index(thr, i, j)) { + duk_xdef_prop_index_wec(thr, -2, idx); + } else { + duk_pop_undefined(thr); + } + } + idx++; + DUK_ASSERT(idx != 0U); /* Wrap check above. */ + } + } + + /* ES5.1 has a specification "bug" in that nonexistent trailing + * elements don't affect the result .length. Test262 and other + * engines disagree, and the specification bug was fixed in ES2015 + * (see NOTE 1 in https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.concat). + */ + duk_push_uarridx(thr, idx); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W); + + DUK_ASSERT_TOP(thr, n + 1); + return 1; + + fail_wrap: + DUK_ERROR_RANGE_INVALID_LENGTH(thr); + DUK_WO_NORETURN(return 0;); +} + +/* + * join(), toLocaleString() + * + * Note: checking valstack is necessary, but only in the per-element loop. + * + * Note: the trivial approach of pushing all the elements on the value stack + * and then calling duk_join() fails when the array contains a large number + * of elements. This problem can't be offloaded to duk_join() because the + * elements to join must be handled here and have special handling. Current + * approach is to do intermediate joins with very large number of elements. + * There is no fancy handling; the prefix gets re-joined multiple times. + */ + +DUK_INTERNAL duk_ret_t duk_bi_array_prototype_join_shared(duk_hthread *thr) { + duk_uint32_t len, count; + duk_uint32_t idx; + duk_small_int_t to_locale_string = duk_get_current_magic(thr); + duk_idx_t valstack_required; + + /* For join(), nargs is 1. For toLocaleString(), nargs is 0 and + * setting the top essentially pushes an undefined to the stack, + * thus defaulting to a comma separator. + */ + duk_set_top(thr, 1); + if (duk_is_undefined(thr, 0)) { + duk_pop_undefined(thr); + duk_push_hstring_stridx(thr, DUK_STRIDX_COMMA); + } else { + duk_to_string(thr, 0); + } + + len = duk__push_this_obj_len_u32(thr); + + /* [ sep ToObject(this) len ] */ + + DUK_DDD(DUK_DDDPRINT("sep=%!T, this=%!T, len=%lu", + (duk_tval *) duk_get_tval(thr, 0), + (duk_tval *) duk_get_tval(thr, 1), + (unsigned long) len)); + + /* The extra (+4) is tight. */ + valstack_required = (duk_idx_t) ((len >= DUK__ARRAY_MID_JOIN_LIMIT ? + DUK__ARRAY_MID_JOIN_LIMIT : len) + 4); + duk_require_stack(thr, valstack_required); + + duk_dup_0(thr); + + /* [ sep ToObject(this) len sep ] */ + + count = 0; + idx = 0; + for (;;) { + DUK_DDD(DUK_DDDPRINT("join idx=%ld", (long) idx)); + if (count >= DUK__ARRAY_MID_JOIN_LIMIT || /* intermediate join to avoid valstack overflow */ + idx >= len) { /* end of loop (careful with len==0) */ + /* [ sep ToObject(this) len sep str0 ... str(count-1) ] */ + DUK_DDD(DUK_DDDPRINT("mid/final join, count=%ld, idx=%ld, len=%ld", + (long) count, (long) idx, (long) len)); + duk_join(thr, (duk_idx_t) count); /* -> [ sep ToObject(this) len str ] */ + duk_dup_0(thr); /* -> [ sep ToObject(this) len str sep ] */ + duk_insert(thr, -2); /* -> [ sep ToObject(this) len sep str ] */ + count = 1; + } + if (idx >= len) { + /* if true, the stack already contains the final result */ + break; + } + + duk_get_prop_index(thr, 1, (duk_uarridx_t) idx); + if (duk_is_null_or_undefined(thr, -1)) { + duk_pop_nodecref_unsafe(thr); + duk_push_hstring_empty(thr); + } else { + if (to_locale_string) { + duk_to_object(thr, -1); + duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_LOCALE_STRING); + duk_insert(thr, -2); /* -> [ ... toLocaleString ToObject(val) ] */ + duk_call_method(thr, 0); + } + duk_to_string(thr, -1); + } + + count++; + idx++; + } + + /* [ sep ToObject(this) len sep result ] */ + + return 1; +} + +/* + * pop(), push() + */ + +#if defined(DUK_USE_ARRAY_FASTPATH) +DUK_LOCAL duk_ret_t duk__array_pop_fastpath(duk_hthread *thr, duk_harray *h_arr) { + duk_tval *tv_arraypart; + duk_tval *tv_val; + duk_uint32_t len; + + tv_arraypart = DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) h_arr); + len = h_arr->length; + if (len <= 0) { + /* nop, return undefined */ + return 0; + } + + len--; + h_arr->length = len; + + /* Fast path doesn't check for an index property inherited from + * Array.prototype. This is quite often acceptable; if not, + * disable fast path. + */ + DUK_ASSERT_VS_SPACE(thr); + tv_val = tv_arraypart + len; + if (DUK_TVAL_IS_UNUSED(tv_val)) { + /* No net refcount change. Value stack already has + * 'undefined' based on value stack init policy. + */ + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top)); + DUK_ASSERT(DUK_TVAL_IS_UNUSED(tv_val)); + } else { + /* No net refcount change. */ + DUK_TVAL_SET_TVAL(thr->valstack_top, tv_val); + DUK_TVAL_SET_UNUSED(tv_val); + } + thr->valstack_top++; + + /* XXX: there's no shrink check in the fast path now */ + + return 1; +} +#endif /* DUK_USE_ARRAY_FASTPATH */ + +DUK_INTERNAL duk_ret_t duk_bi_array_prototype_pop(duk_hthread *thr) { + duk_uint32_t len; + duk_uint32_t idx; +#if defined(DUK_USE_ARRAY_FASTPATH) + duk_harray *h_arr; +#endif + + DUK_ASSERT_TOP(thr, 0); + +#if defined(DUK_USE_ARRAY_FASTPATH) + h_arr = duk__arraypart_fastpath_this(thr); + if (h_arr) { + return duk__array_pop_fastpath(thr, h_arr); + } +#endif + + /* XXX: Merge fastpath check into a related call (push this, coerce length, etc)? */ + + len = duk__push_this_obj_len_u32(thr); + if (len == 0) { + duk_push_int(thr, 0); + duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH); + return 0; + } + idx = len - 1; + + duk_get_prop_index(thr, 0, (duk_uarridx_t) idx); + duk_del_prop_index(thr, 0, (duk_uarridx_t) idx); + duk_push_u32(thr, idx); + duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH); + return 1; +} + +#if defined(DUK_USE_ARRAY_FASTPATH) +DUK_LOCAL duk_ret_t duk__array_push_fastpath(duk_hthread *thr, duk_harray *h_arr) { + duk_tval *tv_arraypart; + duk_tval *tv_src; + duk_tval *tv_dst; + duk_uint32_t len; + duk_idx_t i, n; + + len = h_arr->length; + tv_arraypart = DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) h_arr); + + n = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom); + DUK_ASSERT(n >= 0); + DUK_ASSERT((duk_uint32_t) n <= DUK_UINT32_MAX); + if (DUK_UNLIKELY(len + (duk_uint32_t) n < len)) { + DUK_D(DUK_DPRINT("Array.prototype.push() would go beyond 32-bit length, throw")); + DUK_DCERROR_RANGE_INVALID_LENGTH(thr); /* != 0 return value returned as is by caller */ + } + if (len + (duk_uint32_t) n > DUK_HOBJECT_GET_ASIZE((duk_hobject *) h_arr)) { + /* Array part would need to be extended. Rely on slow path + * for now. + * + * XXX: Rework hobject code a bit and add extend support. + */ + return 0; + } + + tv_src = thr->valstack_bottom; + tv_dst = tv_arraypart + len; + for (i = 0; i < n; i++) { + /* No net refcount change; reset value stack values to + * undefined to satisfy value stack init policy. + */ + DUK_TVAL_SET_TVAL(tv_dst, tv_src); + DUK_TVAL_SET_UNDEFINED(tv_src); + tv_src++; + tv_dst++; + } + thr->valstack_top = thr->valstack_bottom; + len += (duk_uint32_t) n; + h_arr->length = len; + + DUK_ASSERT((duk_uint_t) len == len); + duk_push_uint(thr, (duk_uint_t) len); + return 1; +} +#endif /* DUK_USE_ARRAY_FASTPATH */ + +DUK_INTERNAL duk_ret_t duk_bi_array_prototype_push(duk_hthread *thr) { + /* Note: 'this' is not necessarily an Array object. The push() + * algorithm is supposed to work for other kinds of objects too, + * so the algorithm has e.g. an explicit update for the 'length' + * property which is normally "magical" in arrays. + */ + + duk_uint32_t len; + duk_idx_t i, n; +#if defined(DUK_USE_ARRAY_FASTPATH) + duk_harray *h_arr; +#endif + +#if defined(DUK_USE_ARRAY_FASTPATH) + h_arr = duk__arraypart_fastpath_this(thr); + if (h_arr) { + duk_ret_t rc; + rc = duk__array_push_fastpath(thr, h_arr); + if (rc != 0) { + return rc; + } + DUK_DD(DUK_DDPRINT("array push() fast path exited, resize case")); + } +#endif + + n = duk_get_top(thr); + len = duk__push_this_obj_len_u32(thr); + + /* [ arg1 ... argN obj length ] */ + + /* Technically Array.prototype.push() can create an Array with length + * longer than 2^32-1, i.e. outside the 32-bit range. The final length + * is *not* wrapped to 32 bits in the specification. + * + * This implementation tracks length with a uint32 because it's much + * more practical. + * + * See: test-bi-array-push-maxlen.js. + */ + + if (len + (duk_uint32_t) n < len) { + DUK_D(DUK_DPRINT("Array.prototype.push() would go beyond 32-bit length, throw")); + DUK_DCERROR_RANGE_INVALID_LENGTH(thr); + } + + for (i = 0; i < n; i++) { + duk_dup(thr, i); + duk_put_prop_index(thr, -3, (duk_uarridx_t) (len + (duk_uint32_t) i)); + } + len += (duk_uint32_t) n; + + duk_push_u32(thr, len); + duk_dup_top(thr); + duk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH); + + /* [ arg1 ... argN obj length new_length ] */ + return 1; +} + +/* + * sort() + * + * Currently qsort with random pivot. This is now really, really slow, + * because there is no fast path for array parts. + * + * Signed indices are used because qsort() leaves and degenerate cases + * may use a negative offset. + */ + +DUK_LOCAL duk_small_int_t duk__array_sort_compare(duk_hthread *thr, duk_int_t idx1, duk_int_t idx2) { + duk_bool_t have1, have2; + duk_bool_t undef1, undef2; + duk_small_int_t ret; + duk_idx_t idx_obj = 1; /* fixed offsets in valstack */ + duk_idx_t idx_fn = 0; + duk_hstring *h1, *h2; + + /* Fast exit if indices are identical. This is valid for a non-existent property, + * for an undefined value, and almost always for ToString() coerced comparison of + * arbitrary values (corner cases where this is not the case include e.g. a an + * object with varying ToString() coercion). + * + * The specification does not prohibit "caching" of values read from the array, so + * assuming equality for comparing an index with itself falls into the category of + * "caching". + * + * Also, compareFn may be inconsistent, so skipping a call to compareFn here may + * have an effect on the final result. The specification does not require any + * specific behavior for inconsistent compare functions, so again, this fast path + * is OK. + */ + + if (idx1 == idx2) { + DUK_DDD(DUK_DDDPRINT("duk__array_sort_compare: idx1=%ld, idx2=%ld -> indices identical, quick exit", + (long) idx1, (long) idx2)); + return 0; + } + + have1 = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) idx1); + have2 = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) idx2); + + DUK_DDD(DUK_DDDPRINT("duk__array_sort_compare: idx1=%ld, idx2=%ld, have1=%ld, have2=%ld, val1=%!T, val2=%!T", + (long) idx1, (long) idx2, (long) have1, (long) have2, + (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1))); + + if (have1) { + if (have2) { + ; + } else { + ret = -1; + goto pop_ret; + } + } else { + if (have2) { + ret = 1; + goto pop_ret; + } else { + ret = 0; + goto pop_ret; + } + } + + undef1 = duk_is_undefined(thr, -2); + undef2 = duk_is_undefined(thr, -1); + if (undef1) { + if (undef2) { + ret = 0; + goto pop_ret; + } else { + ret = 1; + goto pop_ret; + } + } else { + if (undef2) { + ret = -1; + goto pop_ret; + } else { + ; + } + } + + if (!duk_is_undefined(thr, idx_fn)) { + duk_double_t d; + + /* No need to check callable; duk_call() will do that. */ + duk_dup(thr, idx_fn); /* -> [ ... x y fn ] */ + duk_insert(thr, -3); /* -> [ ... fn x y ] */ + duk_call(thr, 2); /* -> [ ... res ] */ + + /* ES5 is a bit vague about what to do if the return value is + * not a number. ES2015 provides a concrete description: + * http://www.ecma-international.org/ecma-262/6.0/#sec-sortcompare. + */ + + d = duk_to_number_m1(thr); + if (d < 0.0) { + ret = -1; + } else if (d > 0.0) { + ret = 1; + } else { + /* Because NaN compares to false, NaN is handled here + * without an explicit check above. + */ + ret = 0; + } + + duk_pop_nodecref_unsafe(thr); + DUK_DDD(DUK_DDDPRINT("-> result %ld (from comparefn, after coercion)", (long) ret)); + return ret; + } + + /* string compare is the default (a bit oddly) */ + + /* XXX: any special handling for plain array; causes repeated coercion now? */ + h1 = duk_to_hstring(thr, -2); + h2 = duk_to_hstring_m1(thr); + DUK_ASSERT(h1 != NULL); + DUK_ASSERT(h2 != NULL); + + ret = duk_js_string_compare(h1, h2); /* retval is directly usable */ + goto pop_ret; + + pop_ret: + duk_pop_2_unsafe(thr); + DUK_DDD(DUK_DDDPRINT("-> result %ld", (long) ret)); + return ret; +} + +DUK_LOCAL void duk__array_sort_swap(duk_hthread *thr, duk_int_t l, duk_int_t r) { + duk_bool_t have_l, have_r; + duk_idx_t idx_obj = 1; /* fixed offset in valstack */ + + if (l == r) { + return; + } + + /* swap elements; deal with non-existent elements correctly */ + have_l = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) l); + have_r = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) r); + + if (have_r) { + /* right exists, [[Put]] regardless whether or not left exists */ + duk_put_prop_index(thr, idx_obj, (duk_uarridx_t) l); + } else { + duk_del_prop_index(thr, idx_obj, (duk_uarridx_t) l); + duk_pop_undefined(thr); + } + + if (have_l) { + duk_put_prop_index(thr, idx_obj, (duk_uarridx_t) r); + } else { + duk_del_prop_index(thr, idx_obj, (duk_uarridx_t) r); + duk_pop_undefined(thr); + } +} + +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2) +/* Debug print which visualizes the qsort partitioning process. */ +DUK_LOCAL void duk__debuglog_qsort_state(duk_hthread *thr, duk_int_t lo, duk_int_t hi, duk_int_t pivot) { + char buf[4096]; + char *ptr = buf; + duk_int_t i, n; + n = (duk_int_t) duk_get_length(thr, 1); + if (n > 4000) { + n = 4000; + } + *ptr++ = '['; + for (i = 0; i < n; i++) { + if (i == pivot) { + *ptr++ = '|'; + } else if (i == lo) { + *ptr++ = '<'; + } else if (i == hi) { + *ptr++ = '>'; + } else if (i >= lo && i <= hi) { + *ptr++ = '-'; + } else { + *ptr++ = ' '; + } + } + *ptr++ = ']'; + *ptr++ = '\0'; + + DUK_DDD(DUK_DDDPRINT("%s (lo=%ld, hi=%ld, pivot=%ld)", + (const char *) buf, (long) lo, (long) hi, (long) pivot)); +} +#endif + +DUK_LOCAL void duk__array_qsort(duk_hthread *thr, duk_int_t lo, duk_int_t hi) { + duk_int_t p, l, r; + + /* The lo/hi indices may be crossed and hi < 0 is possible at entry. */ + + DUK_DDD(DUK_DDDPRINT("duk__array_qsort: lo=%ld, hi=%ld, obj=%!T", + (long) lo, (long) hi, (duk_tval *) duk_get_tval(thr, 1))); + + DUK_ASSERT_TOP(thr, 3); + + /* In some cases it may be that lo > hi, or hi < 0; these + * degenerate cases happen e.g. for empty arrays, and in + * recursion leaves. + */ + + /* trivial cases */ + if (hi - lo < 1) { + DUK_DDD(DUK_DDDPRINT("degenerate case, return immediately")); + return; + } + DUK_ASSERT(hi > lo); + DUK_ASSERT(hi - lo + 1 >= 2); + + /* randomized pivot selection */ + p = lo + (duk_int_t) (DUK_UTIL_GET_RANDOM_DOUBLE(thr) * (duk_double_t) (hi - lo + 1)); + DUK_ASSERT(p >= lo && p <= hi); + DUK_DDD(DUK_DDDPRINT("lo=%ld, hi=%ld, chose pivot p=%ld", (long) lo, (long) hi, (long) p)); + + /* move pivot out of the way */ + duk__array_sort_swap(thr, p, lo); + p = lo; + DUK_DDD(DUK_DDDPRINT("pivot moved out of the way: %!T", (duk_tval *) duk_get_tval(thr, 1))); + + l = lo + 1; + r = hi; + for (;;) { + /* find elements to swap */ + for (;;) { + DUK_DDD(DUK_DDDPRINT("left scan: l=%ld, r=%ld, p=%ld", + (long) l, (long) r, (long) p)); + if (l >= hi) { + break; + } + if (duk__array_sort_compare(thr, l, p) >= 0) { /* !(l < p) */ + break; + } + l++; + } + for (;;) { + DUK_DDD(DUK_DDDPRINT("right scan: l=%ld, r=%ld, p=%ld", + (long) l, (long) r, (long) p)); + if (r <= lo) { + break; + } + if (duk__array_sort_compare(thr, p, r) >= 0) { /* !(p < r) */ + break; + } + r--; + } + if (l >= r) { + goto done; + } + DUK_ASSERT(l < r); + + DUK_DDD(DUK_DDDPRINT("swap %ld and %ld", (long) l, (long) r)); + + duk__array_sort_swap(thr, l, r); + + DUK_DDD(DUK_DDDPRINT("after swap: %!T", (duk_tval *) duk_get_tval(thr, 1))); + l++; + r--; + } + done: + /* Note that 'l' and 'r' may cross, i.e. r < l */ + DUK_ASSERT(l >= lo && l <= hi); + DUK_ASSERT(r >= lo && r <= hi); + + /* XXX: there's no explicit recursion bound here now. For the average + * qsort recursion depth O(log n) that's not really necessary: e.g. for + * 2**32 recursion depth would be about 32 which is OK. However, qsort + * worst case recursion depth is O(n) which may be a problem. + */ + + /* move pivot to its final place */ + DUK_DDD(DUK_DDDPRINT("before final pivot swap: %!T", (duk_tval *) duk_get_tval(thr, 1))); + duk__array_sort_swap(thr, lo, r); + +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2) + duk__debuglog_qsort_state(thr, lo, hi, r); +#endif + + DUK_DDD(DUK_DDDPRINT("recurse: pivot=%ld, obj=%!T", (long) r, (duk_tval *) duk_get_tval(thr, 1))); + duk__array_qsort(thr, lo, r - 1); + duk__array_qsort(thr, r + 1, hi); +} + +DUK_INTERNAL duk_ret_t duk_bi_array_prototype_sort(duk_hthread *thr) { + duk_uint32_t len; + + /* XXX: len >= 0x80000000 won't work below because a signed type + * is needed by qsort. + */ + len = duk__push_this_obj_len_u32_limited(thr); + + /* stack[0] = compareFn + * stack[1] = ToObject(this) + * stack[2] = ToUint32(length) + */ + + if (len > 0) { + /* avoid degenerate cases, so that (len - 1) won't underflow */ + duk__array_qsort(thr, (duk_int_t) 0, (duk_int_t) (len - 1)); + } + + DUK_ASSERT_TOP(thr, 3); + duk_pop_nodecref_unsafe(thr); + return 1; /* return ToObject(this) */ +} + +/* + * splice() + */ + +/* XXX: this compiles to over 500 bytes now, even without special handling + * for an array part. Uses signed ints so does not handle full array range correctly. + */ + +/* XXX: can shift() / unshift() use the same helper? + * shift() is (close to?) <--> splice(0, 1) + * unshift is (close to?) <--> splice(0, 0, [items])? + */ + +DUK_INTERNAL duk_ret_t duk_bi_array_prototype_splice(duk_hthread *thr) { + duk_idx_t nargs; + duk_uint32_t len_u32; + duk_int_t len; + duk_bool_t have_delcount; + duk_int_t item_count; + duk_int_t act_start; + duk_int_t del_count; + duk_int_t i, n; + + DUK_UNREF(have_delcount); + + nargs = duk_get_top(thr); + if (nargs < 2) { + duk_set_top(thr, 2); + nargs = 2; + have_delcount = 0; + } else { + have_delcount = 1; + } + + /* XXX: len >= 0x80000000 won't work below because we need to be + * able to represent -len. + */ + len_u32 = duk__push_this_obj_len_u32_limited(thr); + len = (duk_int_t) len_u32; + DUK_ASSERT(len >= 0); + + act_start = duk_to_int_clamped(thr, 0, -len, len); + if (act_start < 0) { + act_start = len + act_start; + } + DUK_ASSERT(act_start >= 0 && act_start <= len); + +#if defined(DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT) + if (have_delcount) { +#endif + del_count = duk_to_int_clamped(thr, 1, 0, len - act_start); +#if defined(DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT) + } else { + /* E5.1 standard behavior when deleteCount is not given would be + * to treat it just like if 'undefined' was given, which coerces + * ultimately to 0. Real world behavior is to splice to the end + * of array, see test-bi-array-proto-splice-no-delcount.js. + */ + del_count = len - act_start; + } +#endif + + DUK_ASSERT(nargs >= 2); + item_count = (duk_int_t) (nargs - 2); + + DUK_ASSERT(del_count >= 0 && del_count <= len - act_start); + DUK_ASSERT(del_count + act_start <= len); + + /* For now, restrict result array into 32-bit length range. */ + if (((duk_double_t) len) - ((duk_double_t) del_count) + ((duk_double_t) item_count) > (duk_double_t) DUK_UINT32_MAX) { + DUK_D(DUK_DPRINT("Array.prototype.splice() would go beyond 32-bit length, throw")); + DUK_DCERROR_RANGE_INVALID_LENGTH(thr); + } + + duk_push_array(thr); + + /* stack[0] = start + * stack[1] = deleteCount + * stack[2...nargs-1] = items + * stack[nargs] = ToObject(this) -3 + * stack[nargs+1] = ToUint32(length) -2 + * stack[nargs+2] = result array -1 + */ + + DUK_ASSERT_TOP(thr, nargs + 3); + + /* Step 9: copy elements-to-be-deleted into the result array */ + + for (i = 0; i < del_count; i++) { + if (duk_get_prop_index(thr, -3, (duk_uarridx_t) (act_start + i))) { + duk_xdef_prop_index_wec(thr, -2, (duk_uarridx_t) i); /* throw flag irrelevant (false in std alg) */ + } else { + duk_pop_undefined(thr); + } + } + duk_push_u32(thr, (duk_uint32_t) del_count); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W); + + /* Steps 12 and 13: reorganize elements to make room for itemCount elements */ + + if (item_count < del_count) { + /* [ A B C D E F G H ] rel_index = 2, del_count 3, item count 1 + * -> [ A B F G H ] (conceptual intermediate step) + * -> [ A B . F G H ] (placeholder marked) + * [ A B C F G H ] (actual result at this point, C will be replaced) + */ + + DUK_ASSERT_TOP(thr, nargs + 3); + + n = len - del_count; + for (i = act_start; i < n; i++) { + if (duk_get_prop_index(thr, -3, (duk_uarridx_t) (i + del_count))) { + duk_put_prop_index(thr, -4, (duk_uarridx_t) (i + item_count)); + } else { + duk_pop_undefined(thr); + duk_del_prop_index(thr, -3, (duk_uarridx_t) (i + item_count)); + } + } + + DUK_ASSERT_TOP(thr, nargs + 3); + + /* loop iterator init and limit changed from standard algorithm */ + n = len - del_count + item_count; + for (i = len - 1; i >= n; i--) { + duk_del_prop_index(thr, -3, (duk_uarridx_t) i); + } + + DUK_ASSERT_TOP(thr, nargs + 3); + } else if (item_count > del_count) { + /* [ A B C D E F G H ] rel_index = 2, del_count 3, item count 4 + * -> [ A B F G H ] (conceptual intermediate step) + * -> [ A B . . . . F G H ] (placeholder marked) + * [ A B C D E F F G H ] (actual result at this point) + */ + + DUK_ASSERT_TOP(thr, nargs + 3); + + /* loop iterator init and limit changed from standard algorithm */ + for (i = len - del_count - 1; i >= act_start; i--) { + if (duk_get_prop_index(thr, -3, (duk_uarridx_t) (i + del_count))) { + duk_put_prop_index(thr, -4, (duk_uarridx_t) (i + item_count)); + } else { + duk_pop_undefined(thr); + duk_del_prop_index(thr, -3, (duk_uarridx_t) (i + item_count)); + } + } + + DUK_ASSERT_TOP(thr, nargs + 3); + } else { + /* [ A B C D E F G H ] rel_index = 2, del_count 3, item count 3 + * -> [ A B F G H ] (conceptual intermediate step) + * -> [ A B . . . F G H ] (placeholder marked) + * [ A B C D E F G H ] (actual result at this point) + */ + } + DUK_ASSERT_TOP(thr, nargs + 3); + + /* Step 15: insert itemCount elements into the hole made above */ + + for (i = 0; i < item_count; i++) { + duk_dup(thr, i + 2); /* args start at index 2 */ + duk_put_prop_index(thr, -4, (duk_uarridx_t) (act_start + i)); + } + + /* Step 16: update length; note that the final length may be above 32 bit range + * (but we checked above that this isn't the case here) + */ + + duk_push_u32(thr, (duk_uint32_t) (len - del_count + item_count)); + duk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH); + + /* result array is already at the top of stack */ + DUK_ASSERT_TOP(thr, nargs + 3); + return 1; +} + +/* + * reverse() + */ + +DUK_INTERNAL duk_ret_t duk_bi_array_prototype_reverse(duk_hthread *thr) { + duk_uint32_t len; + duk_uint32_t middle; + duk_uint32_t lower, upper; + duk_bool_t have_lower, have_upper; + + len = duk__push_this_obj_len_u32(thr); + middle = len / 2; + + /* If len <= 1, middle will be 0 and for-loop bails out + * immediately (0 < 0 -> false). + */ + + for (lower = 0; lower < middle; lower++) { + DUK_ASSERT(len >= 2); + DUK_ASSERT_TOP(thr, 2); + + DUK_ASSERT(len >= lower + 1); + upper = len - lower - 1; + + have_lower = duk_get_prop_index(thr, -2, (duk_uarridx_t) lower); + have_upper = duk_get_prop_index(thr, -3, (duk_uarridx_t) upper); + + /* [ ToObject(this) ToUint32(length) lowerValue upperValue ] */ + + if (have_upper) { + duk_put_prop_index(thr, -4, (duk_uarridx_t) lower); + } else { + duk_del_prop_index(thr, -4, (duk_uarridx_t) lower); + duk_pop_undefined(thr); + } + + if (have_lower) { + duk_put_prop_index(thr, -3, (duk_uarridx_t) upper); + } else { + duk_del_prop_index(thr, -3, (duk_uarridx_t) upper); + duk_pop_undefined(thr); + } + + DUK_ASSERT_TOP(thr, 2); + } + + DUK_ASSERT_TOP(thr, 2); + duk_pop_unsafe(thr); /* -> [ ToObject(this) ] */ + return 1; +} + +/* + * slice() + */ + +DUK_INTERNAL duk_ret_t duk_bi_array_prototype_slice(duk_hthread *thr) { + duk_uint32_t len_u32; + duk_int_t len; + duk_int_t start, end; + duk_int_t i; + duk_uarridx_t idx; + duk_uint32_t res_length = 0; + + /* XXX: len >= 0x80000000 won't work below because we need to be + * able to represent -len. + */ + len_u32 = duk__push_this_obj_len_u32_limited(thr); + len = (duk_int_t) len_u32; + DUK_ASSERT(len >= 0); + + duk_push_array(thr); + + /* stack[0] = start + * stack[1] = end + * stack[2] = ToObject(this) + * stack[3] = ToUint32(length) + * stack[4] = result array + */ + + start = duk_to_int_clamped(thr, 0, -len, len); + if (start < 0) { + start = len + start; + } + /* XXX: could duk_is_undefined() provide defaulting undefined to 'len' + * (the upper limit)? + */ + if (duk_is_undefined(thr, 1)) { + end = len; + } else { + end = duk_to_int_clamped(thr, 1, -len, len); + if (end < 0) { + end = len + end; + } + } + DUK_ASSERT(start >= 0 && start <= len); + DUK_ASSERT(end >= 0 && end <= len); + + idx = 0; + for (i = start; i < end; i++) { + DUK_ASSERT_TOP(thr, 5); + if (duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) { + duk_xdef_prop_index_wec(thr, 4, idx); + res_length = idx + 1; + } else { + duk_pop_undefined(thr); + } + idx++; + DUK_ASSERT_TOP(thr, 5); + } + + duk_push_u32(thr, res_length); + duk_xdef_prop_stridx_short(thr, 4, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W); + + DUK_ASSERT_TOP(thr, 5); + return 1; +} + +/* + * shift() + */ + +DUK_INTERNAL duk_ret_t duk_bi_array_prototype_shift(duk_hthread *thr) { + duk_uint32_t len; + duk_uint32_t i; + + len = duk__push_this_obj_len_u32(thr); + if (len == 0) { + duk_push_int(thr, 0); + duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH); + return 0; + } + + duk_get_prop_index(thr, 0, 0); + + /* stack[0] = object (this) + * stack[1] = ToUint32(length) + * stack[2] = elem at index 0 (retval) + */ + + for (i = 1; i < len; i++) { + DUK_ASSERT_TOP(thr, 3); + if (duk_get_prop_index(thr, 0, (duk_uarridx_t) i)) { + /* fromPresent = true */ + duk_put_prop_index(thr, 0, (duk_uarridx_t) (i - 1)); + } else { + /* fromPresent = false */ + duk_del_prop_index(thr, 0, (duk_uarridx_t) (i - 1)); + duk_pop_undefined(thr); + } + } + duk_del_prop_index(thr, 0, (duk_uarridx_t) (len - 1)); + + duk_push_u32(thr, (duk_uint32_t) (len - 1)); + duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH); + + DUK_ASSERT_TOP(thr, 3); + return 1; +} + +/* + * unshift() + */ + +DUK_INTERNAL duk_ret_t duk_bi_array_prototype_unshift(duk_hthread *thr) { + duk_idx_t nargs; + duk_uint32_t len; + duk_uint32_t i; + + nargs = duk_get_top(thr); + len = duk__push_this_obj_len_u32(thr); + + /* stack[0...nargs-1] = unshift args (vararg) + * stack[nargs] = ToObject(this) + * stack[nargs+1] = ToUint32(length) + */ + + DUK_ASSERT_TOP(thr, nargs + 2); + + /* Note: unshift() may operate on indices above unsigned 32-bit range + * and the final length may be >= 2**32. However, we restrict the + * final result to 32-bit range for practicality. + */ + + if (len + (duk_uint32_t) nargs < len) { + DUK_D(DUK_DPRINT("Array.prototype.unshift() would go beyond 32-bit length, throw")); + DUK_DCERROR_RANGE_INVALID_LENGTH(thr); + } + + i = len; + while (i > 0) { + DUK_ASSERT_TOP(thr, nargs + 2); + i--; + /* k+argCount-1; note that may be above 32-bit range */ + + if (duk_get_prop_index(thr, -2, (duk_uarridx_t) i)) { + /* fromPresent = true */ + /* [ ... ToObject(this) ToUint32(length) val ] */ + duk_put_prop_index(thr, -3, (duk_uarridx_t) (i + (duk_uint32_t) nargs)); /* -> [ ... ToObject(this) ToUint32(length) ] */ + } else { + /* fromPresent = false */ + /* [ ... ToObject(this) ToUint32(length) val ] */ + duk_pop_undefined(thr); + duk_del_prop_index(thr, -2, (duk_uarridx_t) (i + (duk_uint32_t) nargs)); /* -> [ ... ToObject(this) ToUint32(length) ] */ + } + DUK_ASSERT_TOP(thr, nargs + 2); + } + + for (i = 0; i < (duk_uint32_t) nargs; i++) { + DUK_ASSERT_TOP(thr, nargs + 2); + duk_dup(thr, (duk_idx_t) i); /* -> [ ... ToObject(this) ToUint32(length) arg[i] ] */ + duk_put_prop_index(thr, -3, (duk_uarridx_t) i); + DUK_ASSERT_TOP(thr, nargs + 2); + } + + DUK_ASSERT_TOP(thr, nargs + 2); + duk_push_u32(thr, len + (duk_uint32_t) nargs); + duk_dup_top(thr); /* -> [ ... ToObject(this) ToUint32(length) final_len final_len ] */ + duk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH); + return 1; +} + +/* + * indexOf(), lastIndexOf() + */ + +DUK_INTERNAL duk_ret_t duk_bi_array_prototype_indexof_shared(duk_hthread *thr) { + duk_idx_t nargs; + duk_int_t i, len; + duk_int_t from_idx; + duk_small_int_t idx_step = duk_get_current_magic(thr); /* idx_step is +1 for indexOf, -1 for lastIndexOf */ + + /* lastIndexOf() needs to be a vararg function because we must distinguish + * between an undefined fromIndex and a "not given" fromIndex; indexOf() is + * made vararg for symmetry although it doesn't strictly need to be. + */ + + nargs = duk_get_top(thr); + duk_set_top(thr, 2); + + /* XXX: must be able to represent -len */ + len = (duk_int_t) duk__push_this_obj_len_u32_limited(thr); + if (len == 0) { + goto not_found; + } + + /* Index clamping is a bit tricky, we must ensure that we'll only iterate + * through elements that exist and that the specific requirements from E5.1 + * Sections 15.4.4.14 and 15.4.4.15 are fulfilled; especially: + * + * - indexOf: clamp to [-len,len], negative handling -> [0,len], + * if clamped result is len, for-loop bails out immediately + * + * - lastIndexOf: clamp to [-len-1, len-1], negative handling -> [-1, len-1], + * if clamped result is -1, for-loop bails out immediately + * + * If fromIndex is not given, ToInteger(undefined) = 0, which is correct + * for indexOf() but incorrect for lastIndexOf(). Hence special handling, + * and why lastIndexOf() needs to be a vararg function. + */ + + if (nargs >= 2) { + /* indexOf: clamp fromIndex to [-len, len] + * (if fromIndex == len, for-loop terminates directly) + * + * lastIndexOf: clamp fromIndex to [-len - 1, len - 1] + * (if clamped to -len-1 -> fromIndex becomes -1, terminates for-loop directly) + */ + from_idx = duk_to_int_clamped(thr, + 1, + (idx_step > 0 ? -len : -len - 1), + (idx_step > 0 ? len : len - 1)); + if (from_idx < 0) { + /* for lastIndexOf, result may be -1 (mark immediate termination) */ + from_idx = len + from_idx; + } + } else { + /* for indexOf, ToInteger(undefined) would be 0, i.e. correct, but + * handle both indexOf and lastIndexOf specially here. + */ + if (idx_step > 0) { + from_idx = 0; + } else { + from_idx = len - 1; + } + } + + /* stack[0] = searchElement + * stack[1] = fromIndex + * stack[2] = object + * stack[3] = length (not needed, but not popped above) + */ + + for (i = from_idx; i >= 0 && i < len; i += idx_step) { + DUK_ASSERT_TOP(thr, 4); + + if (duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) { + DUK_ASSERT_TOP(thr, 5); + if (duk_strict_equals(thr, 0, 4)) { + duk_push_int(thr, i); + return 1; + } + } + + duk_pop_unsafe(thr); + } + + not_found: + duk_push_int(thr, -1); + return 1; +} + +/* + * every(), some(), forEach(), map(), filter() + */ + +#define DUK__ITER_EVERY 0 +#define DUK__ITER_SOME 1 +#define DUK__ITER_FOREACH 2 +#define DUK__ITER_MAP 3 +#define DUK__ITER_FILTER 4 + +/* XXX: This helper is a bit awkward because the handling for the different iteration + * callers is quite different. This now compiles to a bit less than 500 bytes, so with + * 5 callers the net result is about 100 bytes / caller. + */ + +DUK_INTERNAL duk_ret_t duk_bi_array_prototype_iter_shared(duk_hthread *thr) { + duk_uint32_t len; + duk_uint32_t i; + duk_uarridx_t k; + duk_bool_t bval; + duk_small_int_t iter_type = duk_get_current_magic(thr); + duk_uint32_t res_length = 0; + + /* each call this helper serves has nargs==2 */ + DUK_ASSERT_TOP(thr, 2); + + len = duk__push_this_obj_len_u32(thr); + duk_require_callable(thr, 0); + /* if thisArg not supplied, behave as if undefined was supplied */ + + if (iter_type == DUK__ITER_MAP || iter_type == DUK__ITER_FILTER) { + duk_push_array(thr); + } else { + duk_push_undefined(thr); + } + + /* stack[0] = callback + * stack[1] = thisArg + * stack[2] = object + * stack[3] = ToUint32(length) (unused, but avoid unnecessary pop) + * stack[4] = result array (or undefined) + */ + + k = 0; /* result index for filter() */ + for (i = 0; i < len; i++) { + DUK_ASSERT_TOP(thr, 5); + + if (!duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) { + /* For 'map' trailing missing elements don't invoke the + * callback but count towards the result length. + */ + if (iter_type == DUK__ITER_MAP) { + res_length = i + 1; + } + duk_pop_undefined(thr); + continue; + } + + /* The original value needs to be preserved for filter(), hence + * this funny order. We can't re-get the value because of side + * effects. + */ + + duk_dup_0(thr); + duk_dup_1(thr); + duk_dup_m3(thr); + duk_push_u32(thr, i); + duk_dup_2(thr); /* [ ... val callback thisArg val i obj ] */ + duk_call_method(thr, 3); /* -> [ ... val retval ] */ + + switch (iter_type) { + case DUK__ITER_EVERY: + bval = duk_to_boolean(thr, -1); + if (!bval) { + /* stack top contains 'false' */ + return 1; + } + break; + case DUK__ITER_SOME: + bval = duk_to_boolean(thr, -1); + if (bval) { + /* stack top contains 'true' */ + return 1; + } + break; + case DUK__ITER_FOREACH: + /* nop */ + break; + case DUK__ITER_MAP: + duk_dup_top(thr); + duk_xdef_prop_index_wec(thr, 4, (duk_uarridx_t) i); /* retval to result[i] */ + res_length = i + 1; + break; + case DUK__ITER_FILTER: + bval = duk_to_boolean(thr, -1); + if (bval) { + duk_dup_m2(thr); /* orig value */ + duk_xdef_prop_index_wec(thr, 4, (duk_uarridx_t) k); + k++; + res_length = k; + } + break; + default: + DUK_UNREACHABLE(); + break; + } + duk_pop_2_unsafe(thr); + + DUK_ASSERT_TOP(thr, 5); + } + + switch (iter_type) { + case DUK__ITER_EVERY: + duk_push_true(thr); + break; + case DUK__ITER_SOME: + duk_push_false(thr); + break; + case DUK__ITER_FOREACH: + duk_push_undefined(thr); + break; + case DUK__ITER_MAP: + case DUK__ITER_FILTER: + DUK_ASSERT_TOP(thr, 5); + DUK_ASSERT(duk_is_array(thr, -1)); /* topmost element is the result array already */ + duk_push_u32(thr, res_length); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W); + break; + default: + DUK_UNREACHABLE(); + break; + } + + return 1; +} + +/* + * reduce(), reduceRight() + */ + +DUK_INTERNAL duk_ret_t duk_bi_array_prototype_reduce_shared(duk_hthread *thr) { + duk_idx_t nargs; + duk_bool_t have_acc; + duk_uint32_t i, len; + duk_small_int_t idx_step = duk_get_current_magic(thr); /* idx_step is +1 for reduce, -1 for reduceRight */ + + /* We're a varargs function because we need to detect whether + * initialValue was given or not. + */ + nargs = duk_get_top(thr); + DUK_DDD(DUK_DDDPRINT("nargs=%ld", (long) nargs)); + + duk_set_top(thr, 2); + len = duk__push_this_obj_len_u32(thr); + duk_require_callable(thr, 0); + + /* stack[0] = callback fn + * stack[1] = initialValue + * stack[2] = object (coerced this) + * stack[3] = length (not needed, but not popped above) + * stack[4] = accumulator + */ + + have_acc = 0; + if (nargs >= 2) { + duk_dup_1(thr); + have_acc = 1; + } + DUK_DDD(DUK_DDDPRINT("have_acc=%ld, acc=%!T", + (long) have_acc, (duk_tval *) duk_get_tval(thr, 3))); + + /* For len == 0, i is initialized to len - 1 which underflows. + * The condition (i < len) will then exit the for-loop on the + * first round which is correct. Similarly, loop termination + * happens by i underflowing. + */ + + for (i = (idx_step >= 0 ? 0 : len - 1); + i < len; /* i >= 0 would always be true */ + i += (duk_uint32_t) idx_step) { + DUK_DDD(DUK_DDDPRINT("i=%ld, len=%ld, have_acc=%ld, top=%ld, acc=%!T", + (long) i, (long) len, (long) have_acc, + (long) duk_get_top(thr), + (duk_tval *) duk_get_tval(thr, 4))); + + DUK_ASSERT((have_acc && duk_get_top(thr) == 5) || + (!have_acc && duk_get_top(thr) == 4)); + + if (!duk_has_prop_index(thr, 2, (duk_uarridx_t) i)) { + continue; + } + + if (!have_acc) { + DUK_ASSERT_TOP(thr, 4); + duk_get_prop_index(thr, 2, (duk_uarridx_t) i); + have_acc = 1; + DUK_ASSERT_TOP(thr, 5); + } else { + DUK_ASSERT_TOP(thr, 5); + duk_dup_0(thr); + duk_dup(thr, 4); + duk_get_prop_index(thr, 2, (duk_uarridx_t) i); + duk_push_u32(thr, i); + duk_dup_2(thr); + DUK_DDD(DUK_DDDPRINT("calling reduce function: func=%!T, prev=%!T, curr=%!T, idx=%!T, obj=%!T", + (duk_tval *) duk_get_tval(thr, -5), (duk_tval *) duk_get_tval(thr, -4), + (duk_tval *) duk_get_tval(thr, -3), (duk_tval *) duk_get_tval(thr, -2), + (duk_tval *) duk_get_tval(thr, -1))); + duk_call(thr, 4); + DUK_DDD(DUK_DDDPRINT("-> result: %!T", (duk_tval *) duk_get_tval(thr, -1))); + duk_replace(thr, 4); + DUK_ASSERT_TOP(thr, 5); + } + } + + if (!have_acc) { + DUK_DCERROR_TYPE_INVALID_ARGS(thr); + } + + DUK_ASSERT_TOP(thr, 5); + return 1; +} + +#endif /* DUK_USE_ARRAY_BUILTIN */ diff --git a/third_party/duktape/duk_bi_boolean.c b/third_party/duktape/duk_bi_boolean.c new file mode 100644 index 00000000..407d0348 --- /dev/null +++ b/third_party/duktape/duk_bi_boolean.c @@ -0,0 +1,69 @@ +/* + * Boolean built-ins + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_BOOLEAN_BUILTIN) + +/* Shared helper to provide toString() and valueOf(). Checks 'this', gets + * the primitive value to stack top, and optionally coerces with ToString(). + */ +DUK_INTERNAL duk_ret_t duk_bi_boolean_prototype_tostring_shared(duk_hthread *thr) { + duk_tval *tv; + duk_hobject *h; + duk_small_int_t coerce_tostring = duk_get_current_magic(thr); + + /* XXX: there is room to use a shared helper here, many built-ins + * check the 'this' type, and if it's an object, check its class, + * then get its internal value, etc. + */ + + duk_push_this(thr); + tv = duk_get_tval(thr, -1); + DUK_ASSERT(tv != NULL); + + if (DUK_TVAL_IS_BOOLEAN(tv)) { + goto type_ok; + } else if (DUK_TVAL_IS_OBJECT(tv)) { + h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + + if (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_BOOLEAN) { + duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE); + DUK_ASSERT(duk_is_boolean(thr, -1)); + goto type_ok; + } + } + + DUK_DCERROR_TYPE_INVALID_ARGS(thr); + /* never here */ + + type_ok: + if (coerce_tostring) { + duk_to_string(thr, -1); + } + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_boolean_constructor(duk_hthread *thr) { + duk_hobject *h_this; + + duk_to_boolean(thr, 0); + + if (duk_is_constructor_call(thr)) { + /* XXX: helper; rely on Boolean.prototype as being non-writable, non-configurable */ + duk_push_this(thr); + h_this = duk_known_hobject(thr, -1); + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_this) == thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE]); + + DUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_BOOLEAN); + + duk_dup_0(thr); /* -> [ val obj val ] */ + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); /* XXX: proper flags? */ + } /* unbalanced stack */ + + return 1; +} + +#endif /* DUK_USE_BOOLEAN_BUILTIN */ diff --git a/third_party/duktape/duk_bi_buffer.c b/third_party/duktape/duk_bi_buffer.c new file mode 100644 index 00000000..13cf9be0 --- /dev/null +++ b/third_party/duktape/duk_bi_buffer.c @@ -0,0 +1,2982 @@ +/* + * ES2015 TypedArray and Node.js Buffer built-ins + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Helpers for buffer handling, enabled with DUK_USE_BUFFEROBJECT_SUPPORT. + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +/* Map class number (minus DUK_HOBJECT_CLASS_BUFOBJ_MIN) to a bidx for the + * default internal prototype. + */ +static const duk_uint8_t duk__buffer_proto_from_classnum[] = { + DUK_BIDX_ARRAYBUFFER_PROTOTYPE, DUK_BIDX_DATAVIEW_PROTOTYPE, + DUK_BIDX_INT8ARRAY_PROTOTYPE, DUK_BIDX_UINT8ARRAY_PROTOTYPE, + DUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE, DUK_BIDX_INT16ARRAY_PROTOTYPE, + DUK_BIDX_UINT16ARRAY_PROTOTYPE, DUK_BIDX_INT32ARRAY_PROTOTYPE, + DUK_BIDX_UINT32ARRAY_PROTOTYPE, DUK_BIDX_FLOAT32ARRAY_PROTOTYPE, + DUK_BIDX_FLOAT64ARRAY_PROTOTYPE}; + +/* Map DUK_HBUFOBJ_ELEM_xxx to duk_hobject class number. + * Sync with duk_hbufobj.h and duk_hobject.h. + */ +static const duk_uint8_t duk__buffer_class_from_elemtype[9] = { + DUK_HOBJECT_CLASS_UINT8ARRAY, DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY, + DUK_HOBJECT_CLASS_INT8ARRAY, DUK_HOBJECT_CLASS_UINT16ARRAY, + DUK_HOBJECT_CLASS_INT16ARRAY, DUK_HOBJECT_CLASS_UINT32ARRAY, + DUK_HOBJECT_CLASS_INT32ARRAY, DUK_HOBJECT_CLASS_FLOAT32ARRAY, + DUK_HOBJECT_CLASS_FLOAT64ARRAY}; + +/* Map DUK_HBUFOBJ_ELEM_xxx to prototype object built-in index. + * Sync with duk_hbufobj.h. + */ +static const duk_uint8_t duk__buffer_proto_from_elemtype[9] = { + DUK_BIDX_UINT8ARRAY_PROTOTYPE, DUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE, + DUK_BIDX_INT8ARRAY_PROTOTYPE, DUK_BIDX_UINT16ARRAY_PROTOTYPE, + DUK_BIDX_INT16ARRAY_PROTOTYPE, DUK_BIDX_UINT32ARRAY_PROTOTYPE, + DUK_BIDX_INT32ARRAY_PROTOTYPE, DUK_BIDX_FLOAT32ARRAY_PROTOTYPE, + DUK_BIDX_FLOAT64ARRAY_PROTOTYPE}; + +/* Map DUK__FLD_xxx to byte size. */ +static const duk_uint8_t duk__buffer_nbytes_from_fldtype[6] = { + 1, /* DUK__FLD_8BIT */ + 2, /* DUK__FLD_16BIT */ + 4, /* DUK__FLD_32BIT */ + 4, /* DUK__FLD_FLOAT */ + 8, /* DUK__FLD_DOUBLE */ + 0 /* DUK__FLD_VARINT; not relevant here */ +}; + +/* Bitfield for each DUK_HBUFOBJ_ELEM_xxx indicating which element types + * are compatible with a blind byte copy for the TypedArray set() method (also + * used for TypedArray constructor). Array index is target buffer elem type, + * bitfield indicates compatible source types. The types must have same byte + * size and they must be coercion compatible. + */ +#if !defined(DUK_USE_PREFER_SIZE) +static duk_uint16_t duk__buffer_elemtype_copy_compatible[9] = { + /* xxx -> DUK_HBUFOBJ_ELEM_UINT8 */ + (1U << DUK_HBUFOBJ_ELEM_UINT8) | (1U << DUK_HBUFOBJ_ELEM_UINT8CLAMPED) | + (1U << DUK_HBUFOBJ_ELEM_INT8), + + /* xxx -> DUK_HBUFOBJ_ELEM_UINT8CLAMPED + * Note: INT8 is -not- copy compatible, e.g. -1 would coerce to 0x00. + */ + (1U << DUK_HBUFOBJ_ELEM_UINT8) | (1U << DUK_HBUFOBJ_ELEM_UINT8CLAMPED), + + /* xxx -> DUK_HBUFOBJ_ELEM_INT8 */ + (1U << DUK_HBUFOBJ_ELEM_UINT8) | (1U << DUK_HBUFOBJ_ELEM_UINT8CLAMPED) | + (1U << DUK_HBUFOBJ_ELEM_INT8), + + /* xxx -> DUK_HBUFOBJ_ELEM_UINT16 */ + (1U << DUK_HBUFOBJ_ELEM_UINT16) | (1U << DUK_HBUFOBJ_ELEM_INT16), + + /* xxx -> DUK_HBUFOBJ_ELEM_INT16 */ + (1U << DUK_HBUFOBJ_ELEM_UINT16) | (1U << DUK_HBUFOBJ_ELEM_INT16), + + /* xxx -> DUK_HBUFOBJ_ELEM_UINT32 */ + (1U << DUK_HBUFOBJ_ELEM_UINT32) | (1U << DUK_HBUFOBJ_ELEM_INT32), + + /* xxx -> DUK_HBUFOBJ_ELEM_INT32 */ + (1U << DUK_HBUFOBJ_ELEM_UINT32) | (1U << DUK_HBUFOBJ_ELEM_INT32), + + /* xxx -> DUK_HBUFOBJ_ELEM_FLOAT32 */ + (1U << DUK_HBUFOBJ_ELEM_FLOAT32), + + /* xxx -> DUK_HBUFOBJ_ELEM_FLOAT64 */ + (1U << DUK_HBUFOBJ_ELEM_FLOAT64)}; +#endif /* !DUK_USE_PREFER_SIZE */ + +DUK_LOCAL duk_hbufobj *duk__hbufobj_promote_this(duk_hthread *thr) { + duk_tval *tv_dst; + duk_hbufobj *res; + + duk_push_this(thr); + DUK_ASSERT(duk_is_buffer(thr, -1)); + res = (duk_hbufobj *)duk_to_hobject(thr, -1); + DUK_HBUFOBJ_ASSERT_VALID(res); + DUK_DD(DUK_DDPRINT("promoted 'this' automatically to an ArrayBuffer: %!iT", + duk_get_tval(thr, -1))); + + tv_dst = duk_get_borrowed_this_tval(thr); + DUK_TVAL_SET_OBJECT_UPDREF(thr, tv_dst, (duk_hobject *)res); + duk_pop(thr); + + return res; +} + +#define DUK__BUFOBJ_FLAG_THROW (1 << 0) +#define DUK__BUFOBJ_FLAG_PROMOTE (1 << 1) + +/* Shared helper. When DUK__BUFOBJ_FLAG_PROMOTE is given, the return value is + * always a duk_hbufobj *. Without the flag the return value can also be a + * plain buffer, and the caller must check for it using DUK_HEAPHDR_IS_BUFFER(). + */ +DUK_LOCAL duk_heaphdr *duk__getrequire_bufobj_this(duk_hthread *thr, + duk_small_uint_t flags) { + duk_tval *tv; + duk_hbufobj *h_this; + + DUK_ASSERT(thr != NULL); + + tv = duk_get_borrowed_this_tval(thr); + DUK_ASSERT(tv != NULL); + + if (DUK_TVAL_IS_OBJECT(tv)) { + h_this = (duk_hbufobj *)DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h_this != NULL); + if (DUK_HOBJECT_IS_BUFOBJ((duk_hobject *)h_this)) { + DUK_HBUFOBJ_ASSERT_VALID(h_this); + return (duk_heaphdr *)h_this; + } + } else if (DUK_TVAL_IS_BUFFER(tv)) { + if (flags & DUK__BUFOBJ_FLAG_PROMOTE) { + /* Promote a plain buffer to a Uint8Array. This is very + * inefficient but allows plain buffer to be used wherever an + * Uint8Array is used with very small cost; hot path functions + * like index read/write calls should provide direct buffer + * support to avoid promotion. + */ + /* XXX: make this conditional to a flag if call sites need it? */ + h_this = duk__hbufobj_promote_this(thr); + DUK_ASSERT(h_this != NULL); + DUK_HBUFOBJ_ASSERT_VALID(h_this); + return (duk_heaphdr *)h_this; + } else { + /* XXX: ugly, share return pointer for duk_hbuffer. */ + return (duk_heaphdr *)DUK_TVAL_GET_BUFFER(tv); + } + } + + if (flags & DUK__BUFOBJ_FLAG_THROW) { + DUK_ERROR_TYPE(thr, DUK_STR_NOT_BUFFER); + DUK_WO_NORETURN(return NULL;); + } + return NULL; +} + +/* Check that 'this' is a duk_hbufobj and return a pointer to it. */ +DUK_LOCAL duk_hbufobj *duk__get_bufobj_this(duk_hthread *thr) { + return (duk_hbufobj *)duk__getrequire_bufobj_this(thr, + DUK__BUFOBJ_FLAG_PROMOTE); +} + +/* Check that 'this' is a duk_hbufobj and return a pointer to it + * (NULL if not). + */ +DUK_LOCAL duk_hbufobj *duk__require_bufobj_this(duk_hthread *thr) { + return (duk_hbufobj *)duk__getrequire_bufobj_this( + thr, DUK__BUFOBJ_FLAG_THROW | DUK__BUFOBJ_FLAG_PROMOTE); +} + +/* Check that value is a duk_hbufobj and return a pointer to it. */ +DUK_LOCAL duk_hbufobj *duk__require_bufobj_value(duk_hthread *thr, + duk_idx_t idx) { + duk_tval *tv; + duk_hbufobj *h_obj; + + /* Don't accept relative indices now. */ + DUK_ASSERT(idx >= 0); + + tv = duk_require_tval(thr, idx); + DUK_ASSERT(tv != NULL); + if (DUK_TVAL_IS_OBJECT(tv)) { + h_obj = (duk_hbufobj *)DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h_obj != NULL); + if (DUK_HOBJECT_IS_BUFOBJ((duk_hobject *)h_obj)) { + DUK_HBUFOBJ_ASSERT_VALID(h_obj); + return h_obj; + } + } else if (DUK_TVAL_IS_BUFFER(tv)) { + h_obj = (duk_hbufobj *)duk_to_hobject(thr, idx); + DUK_ASSERT(h_obj != NULL); + DUK_HBUFOBJ_ASSERT_VALID(h_obj); + return h_obj; + } + + DUK_ERROR_TYPE(thr, DUK_STR_NOT_BUFFER); + DUK_WO_NORETURN(return NULL;); +} + +DUK_LOCAL void duk__set_bufobj_buffer(duk_hthread *thr, duk_hbufobj *h_bufobj, + duk_hbuffer *h_val) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(h_bufobj != NULL); + DUK_ASSERT(h_bufobj->buf == NULL); /* no need to decref */ + DUK_ASSERT(h_val != NULL); + DUK_HBUFOBJ_ASSERT_VALID(h_bufobj); + DUK_UNREF(thr); + + h_bufobj->buf = h_val; + DUK_HBUFFER_INCREF(thr, h_val); + h_bufobj->length = (duk_uint_t)DUK_HBUFFER_GET_SIZE(h_val); + DUK_ASSERT(h_bufobj->shift == 0); + DUK_ASSERT(h_bufobj->elem_type == DUK_HBUFOBJ_ELEM_UINT8); + DUK_ASSERT(h_bufobj->is_typedarray == 0); + + DUK_HBUFOBJ_ASSERT_VALID(h_bufobj); +} + +/* Shared offset/length coercion helper. */ +DUK_LOCAL void duk__resolve_offset_opt_length( + duk_hthread *thr, duk_hbufobj *h_bufarg, duk_idx_t idx_offset, + duk_idx_t idx_length, duk_uint_t *out_offset, duk_uint_t *out_length, + duk_bool_t throw_flag) { + duk_int_t offset_signed; + duk_int_t length_signed; + duk_uint_t offset; + duk_uint_t length; + + offset_signed = duk_to_int(thr, idx_offset); + if (offset_signed < 0) { + goto fail_range; + } + offset = (duk_uint_t)offset_signed; + if (offset > h_bufarg->length) { + goto fail_range; + } + DUK_ASSERT_DISABLE(offset >= 0); /* unsigned */ + DUK_ASSERT(offset <= h_bufarg->length); + + if (duk_is_undefined(thr, idx_length)) { + DUK_ASSERT(h_bufarg->length >= offset); + length = h_bufarg->length - offset; /* >= 0 */ + } else { + length_signed = duk_to_int(thr, idx_length); + if (length_signed < 0) { + goto fail_range; + } + length = (duk_uint_t)length_signed; + DUK_ASSERT(h_bufarg->length >= offset); + if (length > h_bufarg->length - offset) { + /* Unlike for negative arguments, some call sites + * want length to be clamped if it's positive. + */ + if (throw_flag) { + goto fail_range; + } else { + length = h_bufarg->length - offset; + } + } + } + DUK_ASSERT_DISABLE(length >= 0); /* unsigned */ + DUK_ASSERT(offset + length <= h_bufarg->length); + + *out_offset = offset; + *out_length = length; + return; + +fail_range: + DUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARGS); + DUK_WO_NORETURN(return;); +} + +/* Shared lenient buffer length clamping helper. No negative indices, no + * element/byte shifting. + */ +DUK_LOCAL void duk__clamp_startend_nonegidx_noshift( + duk_hthread *thr, duk_int_t buffer_length, duk_idx_t idx_start, + duk_idx_t idx_end, duk_int_t *out_start_offset, duk_int_t *out_end_offset) { + duk_int_t start_offset; + duk_int_t end_offset; + + DUK_ASSERT(out_start_offset != NULL); + DUK_ASSERT(out_end_offset != NULL); + + /* undefined coerces to zero which is correct */ + start_offset = duk_to_int_clamped(thr, idx_start, 0, buffer_length); + if (duk_is_undefined(thr, idx_end)) { + end_offset = buffer_length; + } else { + end_offset = duk_to_int_clamped(thr, idx_end, start_offset, buffer_length); + } + + DUK_ASSERT(start_offset >= 0); + DUK_ASSERT(start_offset <= buffer_length); + DUK_ASSERT(end_offset >= 0); + DUK_ASSERT(end_offset <= buffer_length); + DUK_ASSERT(start_offset <= end_offset); + + *out_start_offset = start_offset; + *out_end_offset = end_offset; +} + +/* Shared lenient buffer length clamping helper. Indices are treated as + * element indices (though output values are byte offsets) which only + * really matters for TypedArray views as other buffer object have a zero + * shift. Negative indices are counted from end of input slice; crossed + * indices are clamped to zero length; and final indices are clamped + * against input slice. Used for e.g. ArrayBuffer slice(). + */ +DUK_LOCAL void duk__clamp_startend_negidx_shifted( + duk_hthread *thr, duk_int_t buffer_length, duk_uint8_t buffer_shift, + duk_idx_t idx_start, duk_idx_t idx_end, duk_int_t *out_start_offset, + duk_int_t *out_end_offset) { + duk_int_t start_offset; + duk_int_t end_offset; + + DUK_ASSERT(out_start_offset != NULL); + DUK_ASSERT(out_end_offset != NULL); + + buffer_length >>= buffer_shift; /* as (full) elements */ + + /* Resolve start/end offset as element indices first; arguments + * at idx_start/idx_end are element offsets. Working with element + * indices first also avoids potential for wrapping. + */ + + start_offset = duk_to_int(thr, idx_start); + if (start_offset < 0) { + start_offset = buffer_length + start_offset; + } + if (duk_is_undefined(thr, idx_end)) { + end_offset = buffer_length; + } else { + end_offset = duk_to_int(thr, idx_end); + if (end_offset < 0) { + end_offset = buffer_length + end_offset; + } + } + /* Note: start_offset/end_offset can still be < 0 here. */ + + if (start_offset < 0) { + start_offset = 0; + } else if (start_offset > buffer_length) { + start_offset = buffer_length; + } + if (end_offset < start_offset) { + end_offset = start_offset; + } else if (end_offset > buffer_length) { + end_offset = buffer_length; + } + DUK_ASSERT(start_offset >= 0); + DUK_ASSERT(start_offset <= buffer_length); + DUK_ASSERT(end_offset >= 0); + DUK_ASSERT(end_offset <= buffer_length); + DUK_ASSERT(start_offset <= end_offset); + + /* Convert indices to byte offsets. */ + start_offset <<= buffer_shift; + end_offset <<= buffer_shift; + + *out_start_offset = start_offset; + *out_end_offset = end_offset; +} + +DUK_INTERNAL void duk_hbufobj_promote_plain(duk_hthread *thr, duk_idx_t idx) { + if (duk_is_buffer(thr, idx)) { + duk_to_object(thr, idx); + } +} + +DUK_INTERNAL void duk_hbufobj_push_uint8array_from_plain(duk_hthread *thr, + duk_hbuffer *h_buf) { + /* Push Uint8Array which will share the same underlying buffer as + * the plain buffer argument. Also create an ArrayBuffer with the + * same backing for the result .buffer property. + */ + + duk_push_hbuffer(thr, h_buf); + duk_push_buffer_object(thr, -1, 0, (duk_size_t)DUK_HBUFFER_GET_SIZE(h_buf), + DUK_BUFOBJ_UINT8ARRAY); + duk_remove_m2(thr); + +#if 0 + /* More verbose equivalent; maybe useful if e.g. .buffer is omitted. */ + h_bufobj = duk_push_bufobj_raw(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_BUFOBJ | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_UINT8ARRAY), + DUK_BIDX_UINT8ARRAY_PROTOTYPE); + DUK_ASSERT(h_bufobj != NULL); + duk__set_bufobj_buffer(thr, h_bufobj, h_buf); + h_bufobj->is_typedarray = 1; + DUK_HBUFOBJ_ASSERT_VALID(h_bufobj); + + h_arrbuf = duk_push_bufobj_raw(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_BUFOBJ | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER), + DUK_BIDX_ARRAYBUFFER_PROTOTYPE); + DUK_ASSERT(h_arrbuf != NULL); + duk__set_bufobj_buffer(thr, h_arrbuf, h_buf); + DUK_ASSERT(h_arrbuf->is_typedarray == 0); + DUK_HBUFOBJ_ASSERT_VALID(h_arrbuf); + + DUK_ASSERT(h_bufobj->buf_prop == NULL); + h_bufobj->buf_prop = (duk_hobject *) h_arrbuf; + DUK_ASSERT(h_arrbuf != NULL); + DUK_HBUFOBJ_INCREF(thr, h_arrbuf); + duk_pop(thr); +#endif +} + +/* Indexed read helper for buffer objects, also called from outside this file. + */ +DUK_INTERNAL void duk_hbufobj_push_validated_read(duk_hthread *thr, + duk_hbufobj *h_bufobj, + duk_uint8_t *p, + duk_small_uint_t elem_size) { + duk_double_union du; + + DUK_ASSERT(elem_size > 0); + duk_memcpy((void *)du.uc, (const void *)p, (size_t)elem_size); + + switch (h_bufobj->elem_type) { + case DUK_HBUFOBJ_ELEM_UINT8: + case DUK_HBUFOBJ_ELEM_UINT8CLAMPED: + duk_push_uint(thr, (duk_uint_t)du.uc[0]); + break; + case DUK_HBUFOBJ_ELEM_INT8: + duk_push_int(thr, (duk_int_t)(duk_int8_t)du.uc[0]); + break; + case DUK_HBUFOBJ_ELEM_UINT16: + duk_push_uint(thr, (duk_uint_t)du.us[0]); + break; + case DUK_HBUFOBJ_ELEM_INT16: + duk_push_int(thr, (duk_int_t)(duk_int16_t)du.us[0]); + break; + case DUK_HBUFOBJ_ELEM_UINT32: + duk_push_uint(thr, (duk_uint_t)du.ui[0]); + break; + case DUK_HBUFOBJ_ELEM_INT32: + duk_push_int(thr, (duk_int_t)(duk_int32_t)du.ui[0]); + break; + case DUK_HBUFOBJ_ELEM_FLOAT32: + duk_push_number(thr, (duk_double_t)du.f[0]); + break; + case DUK_HBUFOBJ_ELEM_FLOAT64: + duk_push_number(thr, (duk_double_t)du.d); + break; + default: + DUK_UNREACHABLE(); + } +} + +/* Indexed write helper for buffer objects, also called from outside this file. + */ +DUK_INTERNAL void duk_hbufobj_validated_write(duk_hthread *thr, + duk_hbufobj *h_bufobj, + duk_uint8_t *p, + duk_small_uint_t elem_size) { + duk_double_union du; + + /* NOTE! Caller must ensure that any side effects from the + * coercions below are safe. If that cannot be guaranteed + * (which is normally the case), caller must coerce the + * argument using duk_to_number() before any pointer + * validations; the result of duk_to_number() always coerces + * without side effects here. + */ + + switch (h_bufobj->elem_type) { + case DUK_HBUFOBJ_ELEM_UINT8: + du.uc[0] = (duk_uint8_t)duk_to_uint32(thr, -1); + break; + case DUK_HBUFOBJ_ELEM_UINT8CLAMPED: + du.uc[0] = (duk_uint8_t)duk_to_uint8clamped(thr, -1); + break; + case DUK_HBUFOBJ_ELEM_INT8: + du.uc[0] = (duk_uint8_t)duk_to_int32(thr, -1); + break; + case DUK_HBUFOBJ_ELEM_UINT16: + du.us[0] = (duk_uint16_t)duk_to_uint32(thr, -1); + break; + case DUK_HBUFOBJ_ELEM_INT16: + du.us[0] = (duk_uint16_t)duk_to_int32(thr, -1); + break; + case DUK_HBUFOBJ_ELEM_UINT32: + du.ui[0] = (duk_uint32_t)duk_to_uint32(thr, -1); + break; + case DUK_HBUFOBJ_ELEM_INT32: + du.ui[0] = (duk_uint32_t)duk_to_int32(thr, -1); + break; + case DUK_HBUFOBJ_ELEM_FLOAT32: + /* A double-to-float cast is undefined behavior in C99 if + * the cast is out-of-range, so use a helper. Example: + * runtime error: value -1e+100 is outside the range of representable + * values of type 'float' + */ + du.f[0] = duk_double_to_float_t(duk_to_number_m1(thr)); + break; + case DUK_HBUFOBJ_ELEM_FLOAT64: + du.d = (duk_double_t)duk_to_number_m1(thr); + break; + default: + DUK_UNREACHABLE(); + } + + DUK_ASSERT(elem_size > 0); + duk_memcpy((void *)p, (const void *)du.uc, (size_t)elem_size); +} + +/* Helper to create a fixed buffer from argument value at index 0. + * Node.js and allocPlain() compatible. + */ +DUK_LOCAL duk_hbuffer *duk__hbufobj_fixed_from_argvalue(duk_hthread *thr) { + duk_int_t len; + duk_int_t i; + duk_size_t buf_size; + duk_uint8_t *buf; + + switch (duk_get_type(thr, 0)) { + case DUK_TYPE_NUMBER: { + len = duk_to_int_clamped(thr, 0, 0, DUK_INT_MAX); + (void)duk_push_fixed_buffer_zero(thr, (duk_size_t)len); + break; + } + case DUK_TYPE_BUFFER: { /* Treat like Uint8Array. */ + goto slow_copy; + } + case DUK_TYPE_OBJECT: { + duk_hobject *h; + duk_hbufobj *h_bufobj; + + /* For Node.js Buffers "Passing an ArrayBuffer returns a Buffer + * that shares allocated memory with the given ArrayBuffer." + * https://nodejs.org/api/buffer.html#buffer_buffer_from_buffer_alloc_and_buffer_allocunsafe + */ + + h = duk_known_hobject(thr, 0); + if (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAYBUFFER) { + DUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ(h)); + h_bufobj = (duk_hbufobj *)h; + if (DUK_UNLIKELY(h_bufobj->buf == NULL)) { + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return NULL;); + } + if (DUK_UNLIKELY(h_bufobj->offset != 0 || + h_bufobj->length != + DUK_HBUFFER_GET_SIZE(h_bufobj->buf))) { + /* No support for ArrayBuffers with slice + * offset/length. + */ + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return NULL;); + } + duk_push_hbuffer(thr, h_bufobj->buf); + return h_bufobj->buf; + } + goto slow_copy; + } + case DUK_TYPE_STRING: { + /* ignore encoding for now */ + duk_require_hstring_notsymbol(thr, 0); + duk_dup_0(thr); + (void)duk_to_buffer(thr, -1, &buf_size); + break; + } + default: + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return NULL;); + } + +done: + DUK_ASSERT(duk_is_buffer(thr, -1)); + return duk_known_hbuffer(thr, -1); + +slow_copy: + /* XXX: fast path for typed arrays and other buffer objects? */ + + (void)duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH); + len = duk_to_int_clamped(thr, -1, 0, DUK_INT_MAX); + duk_pop(thr); + buf = (duk_uint8_t *)duk_push_fixed_buffer_nozero( + thr, (duk_size_t)len); /* no zeroing, all indices get initialized */ + for (i = 0; i < len; i++) { + /* XXX: fast path for array or buffer arguments? */ + duk_get_prop_index(thr, 0, (duk_uarridx_t)i); + buf[i] = (duk_uint8_t)(duk_to_uint32(thr, -1) & 0xffU); + duk_pop(thr); + } + goto done; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * Node.js Buffer constructor + * + * Node.js Buffers are just Uint8Arrays with internal prototype set to + * Buffer.prototype so they're handled otherwise the same as Uint8Array. + * However, the constructor arguments are very different so a separate + * constructor entry point is used. + */ +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_constructor(duk_hthread *thr) { + duk_hbuffer *h_buf; + + h_buf = duk__hbufobj_fixed_from_argvalue(thr); + DUK_ASSERT(h_buf != NULL); + + duk_push_buffer_object( + thr, -1, 0, + DUK_HBUFFER_FIXED_GET_SIZE((duk_hbuffer_fixed *)(void *)h_buf), + DUK_BUFOBJ_UINT8ARRAY); + duk_push_hobject_bidx(thr, DUK_BIDX_NODEJS_BUFFER_PROTOTYPE); + duk_set_prototype(thr, -2); + + /* XXX: a more direct implementation */ + + return 1; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * ArrayBuffer, DataView, and TypedArray constructors + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_arraybuffer_constructor(duk_hthread *thr) { + duk_hbufobj *h_bufobj; + duk_hbuffer *h_val; + duk_int_t len; + + DUK_CTX_ASSERT_VALID(thr); + + duk_require_constructor_call(thr); + + len = duk_to_int(thr, 0); + if (len < 0) { + goto fail_length; + } + (void)duk_push_fixed_buffer_zero(thr, (duk_size_t)len); + h_val = (duk_hbuffer *)duk_known_hbuffer(thr, -1); + + h_bufobj = duk_push_bufobj_raw( + thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_FLAG_BUFOBJ | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER), + DUK_BIDX_ARRAYBUFFER_PROTOTYPE); + DUK_ASSERT(h_bufobj != NULL); + + duk__set_bufobj_buffer(thr, h_bufobj, h_val); + DUK_HBUFOBJ_ASSERT_VALID(h_bufobj); + + return 1; + +fail_length: + DUK_DCERROR_RANGE_INVALID_LENGTH(thr); +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* Format of magic, bits: + * 0...1: elem size shift (0-3) + * 2...5: elem type (DUK_HBUFOBJ_ELEM_xxx) + * + * XXX: add prototype bidx explicitly to magic instead of using a mapping? + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_hthread *thr) { + duk_tval *tv; + duk_hobject *h_obj; + duk_hbufobj *h_bufobj = NULL; + duk_hbufobj *h_bufarg = NULL; + duk_hbuffer *h_val; + duk_small_uint_t magic; + duk_small_uint_t shift; + duk_small_uint_t elem_type; + duk_small_uint_t elem_size; + duk_small_uint_t class_num; + duk_small_uint_t proto_bidx; + duk_uint_t align_mask; + duk_uint_t elem_length; + duk_int_t elem_length_signed; + duk_uint_t byte_length; + duk_small_uint_t copy_mode; + + /* XXX: The same copy helpers could be shared with at least some + * buffer functions. + */ + + duk_require_constructor_call(thr); + + /* We could fit built-in index into magic but that'd make the magic + * number dependent on built-in numbering (genbuiltins.py doesn't + * handle that yet). So map both class and prototype from the + * element type. + */ + magic = (duk_small_uint_t)duk_get_current_magic(thr); + shift = magic & 0x03U; /* bits 0...1: shift */ + elem_type = (magic >> 2) & 0x0fU; /* bits 2...5: type */ + elem_size = 1U << shift; + align_mask = elem_size - 1; + DUK_ASSERT(elem_type < + sizeof(duk__buffer_proto_from_elemtype) / sizeof(duk_uint8_t)); + proto_bidx = duk__buffer_proto_from_elemtype[elem_type]; + DUK_ASSERT(proto_bidx < DUK_NUM_BUILTINS); + DUK_ASSERT(elem_type < + sizeof(duk__buffer_class_from_elemtype) / sizeof(duk_uint8_t)); + class_num = duk__buffer_class_from_elemtype[elem_type]; + + DUK_DD( + DUK_DDPRINT("typedarray constructor, magic=%d, shift=%d, elem_type=%d, " + "elem_size=%d, proto_bidx=%d, class_num=%d", + (int)magic, (int)shift, (int)elem_type, (int)elem_size, + (int)proto_bidx, (int)class_num)); + + /* Argument variants. When the argument is an ArrayBuffer a view to + * the same buffer is created; otherwise a new ArrayBuffer is always + * created. + */ + + /* XXX: initial iteration to treat a plain buffer like an ArrayBuffer: + * coerce to an ArrayBuffer object and use that as .buffer. The underlying + * buffer will be the same but result .buffer !== inputPlainBuffer. + */ + duk_hbufobj_promote_plain(thr, 0); + + tv = duk_get_tval(thr, 0); + DUK_ASSERT(tv != NULL); /* arg count */ + if (DUK_TVAL_IS_OBJECT(tv)) { + h_obj = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h_obj != NULL); + + if (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_ARRAYBUFFER) { + /* ArrayBuffer: unlike any other argument variant, create + * a view into the existing buffer. + */ + + duk_int_t byte_offset_signed; + duk_uint_t byte_offset; + + h_bufarg = (duk_hbufobj *)h_obj; + + byte_offset_signed = duk_to_int(thr, 1); + if (byte_offset_signed < 0) { + goto fail_arguments; + } + byte_offset = (duk_uint_t)byte_offset_signed; + if (byte_offset > h_bufarg->length || (byte_offset & align_mask) != 0) { + /* Must be >= 0 and multiple of element size. */ + goto fail_arguments; + } + if (duk_is_undefined(thr, 2)) { + DUK_ASSERT(h_bufarg->length >= byte_offset); + byte_length = h_bufarg->length - byte_offset; + if ((byte_length & align_mask) != 0) { + /* Must be element size multiple from + * start offset to end of buffer. + */ + goto fail_arguments; + } + elem_length = (byte_length >> shift); + } else { + elem_length_signed = duk_to_int(thr, 2); + if (elem_length_signed < 0) { + goto fail_arguments; + } + elem_length = (duk_uint_t)elem_length_signed; + byte_length = elem_length << shift; + if ((byte_length >> shift) != elem_length) { + /* Byte length would overflow. */ + /* XXX: easier check with less code? */ + goto fail_arguments; + } + DUK_ASSERT(h_bufarg->length >= byte_offset); + if (byte_length > h_bufarg->length - byte_offset) { + /* Not enough data. */ + goto fail_arguments; + } + } + DUK_UNREF(elem_length); + DUK_ASSERT_DISABLE(byte_offset >= 0); + DUK_ASSERT(byte_offset <= h_bufarg->length); + DUK_ASSERT_DISABLE(byte_length >= 0); + DUK_ASSERT(byte_offset + byte_length <= h_bufarg->length); + DUK_ASSERT((elem_length << shift) == byte_length); + + h_bufobj = duk_push_bufobj_raw(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_BUFOBJ | + DUK_HOBJECT_CLASS_AS_FLAGS(class_num), + (duk_small_int_t)proto_bidx); + h_val = h_bufarg->buf; + if (h_val == NULL) { + DUK_DCERROR_TYPE_INVALID_ARGS(thr); + } + h_bufobj->buf = h_val; + DUK_HBUFFER_INCREF(thr, h_val); + h_bufobj->offset = h_bufarg->offset + byte_offset; + h_bufobj->length = byte_length; + h_bufobj->shift = (duk_uint8_t)shift; + h_bufobj->elem_type = (duk_uint8_t)elem_type; + h_bufobj->is_typedarray = 1; + DUK_HBUFOBJ_ASSERT_VALID(h_bufobj); + + /* Set .buffer to the argument ArrayBuffer. */ + DUK_ASSERT(h_bufobj->buf_prop == NULL); + h_bufobj->buf_prop = (duk_hobject *)h_bufarg; + DUK_ASSERT(h_bufarg != NULL); + DUK_HBUFOBJ_INCREF(thr, h_bufarg); + return 1; + } else if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) { + /* TypedArray (or other non-ArrayBuffer duk_hbufobj). + * Conceptually same behavior as for an Array-like argument, + * with a few fast paths. + */ + + h_bufarg = (duk_hbufobj *)h_obj; + DUK_HBUFOBJ_ASSERT_VALID(h_bufarg); + elem_length_signed = (duk_int_t)(h_bufarg->length >> h_bufarg->shift); + if (h_bufarg->buf == NULL) { + DUK_DCERROR_TYPE_INVALID_ARGS(thr); + } + + /* Select copy mode. Must take into account element + * compatibility and validity of the underlying source + * buffer. + */ + + DUK_DDD(DUK_DDDPRINT("selecting copy mode for bufobj arg, " + "src byte_length=%ld, src shift=%d, " + "src/dst elem_length=%ld; " + "dst shift=%d -> dst byte_length=%ld", + (long)h_bufarg->length, (int)h_bufarg->shift, + (long)elem_length_signed, (int)shift, + (long)(elem_length_signed << shift))); + + copy_mode = 2; /* default is explicit index read/write copy */ +#if !defined(DUK_USE_PREFER_SIZE) + /* With a size optimized build copy_mode 2 is enough. + * Modes 0 and 1 are faster but conceptually the same. + */ + DUK_ASSERT(elem_type < sizeof(duk__buffer_elemtype_copy_compatible) / + sizeof(duk_uint16_t)); + if (DUK_HBUFOBJ_VALID_SLICE(h_bufarg)) { + if ((duk__buffer_elemtype_copy_compatible[elem_type] & + (1u << h_bufarg->elem_type)) != 0) { + DUK_DDD(DUK_DDDPRINT("source/target are copy compatible, memcpy")); + DUK_ASSERT(shift == h_bufarg->shift); /* byte sizes will match */ + copy_mode = 0; + } else { + DUK_DDD(DUK_DDDPRINT( + "source/target not copy compatible but valid, fast copy")); + copy_mode = 1; + } + } +#endif /* !DUK_USE_PREFER_SIZE */ + } else { + /* Array or Array-like */ + elem_length_signed = (duk_int_t)duk_get_length(thr, 0); + copy_mode = 2; + } + } else { + /* Non-object argument is simply int coerced, matches + * V8 behavior (except for "null", which we coerce to + * 0 but V8 TypeErrors). + */ + elem_length_signed = duk_to_int(thr, 0); + copy_mode = 3; + } + if (elem_length_signed < 0) { + goto fail_arguments; + } + elem_length = (duk_uint_t)elem_length_signed; + byte_length = (duk_uint_t)(elem_length << shift); + if ((byte_length >> shift) != elem_length) { + /* Byte length would overflow. */ + /* XXX: easier check with less code? */ + goto fail_arguments; + } + + DUK_DDD(DUK_DDDPRINT("elem_length=%ld, byte_length=%ld", (long)elem_length, + (long)byte_length)); + + /* ArrayBuffer argument is handled specially above; the rest of the + * argument variants are handled by shared code below. + * + * ArrayBuffer in h_bufobj->buf_prop is intentionally left unset. + * It will be automatically created by the .buffer accessor on + * first access. + */ + + /* Push the resulting view object on top of a plain fixed buffer. */ + (void)duk_push_fixed_buffer(thr, byte_length); + h_val = duk_known_hbuffer(thr, -1); + DUK_ASSERT(h_val != NULL); + + h_bufobj = duk_push_bufobj_raw(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_BUFOBJ | + DUK_HOBJECT_CLASS_AS_FLAGS(class_num), + (duk_small_int_t)proto_bidx); + + h_bufobj->buf = h_val; + DUK_HBUFFER_INCREF(thr, h_val); + DUK_ASSERT(h_bufobj->offset == 0); + h_bufobj->length = byte_length; + h_bufobj->shift = (duk_uint8_t)shift; + h_bufobj->elem_type = (duk_uint8_t)elem_type; + h_bufobj->is_typedarray = 1; + DUK_HBUFOBJ_ASSERT_VALID(h_bufobj); + + /* Copy values, the copy method depends on the arguments. + * + * Copy mode decision may depend on the validity of the underlying + * buffer of the source argument; there must be no harmful side effects + * from there to here for copy_mode to still be valid. + */ + DUK_DDD(DUK_DDDPRINT("copy mode: %d", (int)copy_mode)); + switch (copy_mode) { + /* Copy modes 0 and 1 can be omitted in size optimized build, + * copy mode 2 handles them (but more slowly). + */ +#if !defined(DUK_USE_PREFER_SIZE) + case 0: { + /* Use byte copy. */ + + duk_uint8_t *p_src; + duk_uint8_t *p_dst; + + DUK_ASSERT(h_bufobj != NULL); + DUK_ASSERT(h_bufobj->buf != NULL); + DUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufobj)); + DUK_ASSERT(h_bufarg != NULL); + DUK_ASSERT(h_bufarg->buf != NULL); + DUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufarg)); + + p_dst = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufobj); + p_src = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg); + + DUK_DDD(DUK_DDDPRINT("using memcpy: p_src=%p, p_dst=%p, byte_length=%ld", + (void *)p_src, (void *)p_dst, (long)byte_length)); + + duk_memcpy_unsafe((void *)p_dst, (const void *)p_src, + (size_t)byte_length); + break; + } + case 1: { + /* Copy values through direct validated reads and writes. */ + + duk_small_uint_t src_elem_size; + duk_small_uint_t dst_elem_size; + duk_uint8_t *p_src; + duk_uint8_t *p_src_end; + duk_uint8_t *p_dst; + + DUK_ASSERT(h_bufobj != NULL); + DUK_ASSERT(h_bufobj->buf != NULL); + DUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufobj)); + DUK_ASSERT(h_bufarg != NULL); + DUK_ASSERT(h_bufarg->buf != NULL); + DUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufarg)); + + src_elem_size = (duk_small_uint_t)(1U << h_bufarg->shift); + dst_elem_size = elem_size; + + p_src = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg); + p_dst = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufobj); + p_src_end = p_src + h_bufarg->length; + + DUK_DDD(DUK_DDDPRINT("using fast copy: p_src=%p, p_src_end=%p, p_dst=%p, " + "src_elem_size=%d, dst_elem_size=%d", + (void *)p_src, (void *)p_src_end, (void *)p_dst, + (int)src_elem_size, (int)dst_elem_size)); + + while (p_src != p_src_end) { + DUK_DDD(DUK_DDDPRINT("fast path per element copy loop: " + "p_src=%p, p_src_end=%p, p_dst=%p", + (void *)p_src, (void *)p_src_end, (void *)p_dst)); + /* A validated read() is always a number, so it's write coercion + * is always side effect free an won't invalidate pointers etc. + */ + duk_hbufobj_push_validated_read(thr, h_bufarg, p_src, src_elem_size); + duk_hbufobj_validated_write(thr, h_bufobj, p_dst, dst_elem_size); + duk_pop(thr); + p_src += src_elem_size; + p_dst += dst_elem_size; + } + break; + } +#endif /* !DUK_USE_PREFER_SIZE */ + case 2: { + /* Copy values by index reads and writes. Let virtual + * property handling take care of coercion. + */ + duk_uint_t i; + + DUK_DDD(DUK_DDDPRINT("using slow copy")); + + for (i = 0; i < elem_length; i++) { + duk_get_prop_index(thr, 0, (duk_uarridx_t)i); + duk_put_prop_index(thr, -2, (duk_uarridx_t)i); + } + break; + } + default: + case 3: { + /* No copy, leave zero bytes in the buffer. There's no + * ambiguity with Float32/Float64 because zero bytes also + * represent 0.0. + */ + + DUK_DDD(DUK_DDDPRINT("using no copy")); + break; + } + } + + return 1; + +fail_arguments: + DUK_DCERROR_RANGE_INVALID_ARGS(thr); +} +#else /* DUK_USE_BUFFEROBJECT_SUPPORT */ +/* When bufferobject support is disabled, new Uint8Array() could still be + * supported to create a plain fixed buffer. Disabled for now. + */ +#if 0 +DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_hthread *thr) { + duk_int_t elem_length_signed; + duk_uint_t byte_length; + + /* XXX: The same copy helpers could be shared with at least some + * buffer functions. + */ + + duk_require_constructor_call(thr); + + elem_length_signed = duk_require_int(thr, 0); + if (elem_length_signed < 0) { + goto fail_arguments; + } + byte_length = (duk_uint_t) elem_length_signed; + + (void) duk_push_fixed_buffer_zero(thr, (duk_size_t) byte_length); + return 1; + + fail_arguments: + DUK_DCERROR_RANGE_INVALID_ARGS(thr); +} +#endif /* 0 */ +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_dataview_constructor(duk_hthread *thr) { + duk_hbufobj *h_bufarg; + duk_hbufobj *h_bufobj; + duk_hbuffer *h_val; + duk_uint_t offset; + duk_uint_t length; + + length = 0; + offset = 0; + + duk_require_constructor_call(thr); + + h_bufarg = duk__require_bufobj_value(thr, 0); + DUK_ASSERT(h_bufarg != NULL); + if (DUK_HOBJECT_GET_CLASS_NUMBER((duk_hobject *)h_bufarg) != + DUK_HOBJECT_CLASS_ARRAYBUFFER) { + DUK_DCERROR_TYPE_INVALID_ARGS(thr); + } + + duk__resolve_offset_opt_length(thr, h_bufarg, 1, 2, &offset, &length, + 1 /*throw_flag*/); + DUK_ASSERT(offset <= h_bufarg->length); + DUK_ASSERT(offset + length <= h_bufarg->length); + + h_bufobj = duk_push_bufobj_raw( + thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_FLAG_BUFOBJ | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DATAVIEW), + DUK_BIDX_DATAVIEW_PROTOTYPE); + + h_val = h_bufarg->buf; + if (h_val == NULL) { + DUK_DCERROR_TYPE_INVALID_ARGS(thr); + } + h_bufobj->buf = h_val; + DUK_HBUFFER_INCREF(thr, h_val); + h_bufobj->offset = h_bufarg->offset + offset; + h_bufobj->length = length; + DUK_ASSERT(h_bufobj->shift == 0); + DUK_ASSERT(h_bufobj->elem_type == DUK_HBUFOBJ_ELEM_UINT8); + DUK_ASSERT(h_bufobj->is_typedarray == 0); + + DUK_ASSERT(h_bufobj->buf_prop == NULL); + h_bufobj->buf_prop = (duk_hobject *)h_bufarg; + DUK_ASSERT(h_bufarg != NULL); + DUK_HBUFOBJ_INCREF(thr, h_bufarg); + + DUK_HBUFOBJ_ASSERT_VALID(h_bufobj); + return 1; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * ArrayBuffer.isView() + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_arraybuffer_isview(duk_hthread *thr) { + duk_hobject *h_obj; + duk_bool_t ret = 0; + + if (duk_is_buffer(thr, 0)) { + ret = 1; + } else { + h_obj = duk_get_hobject(thr, 0); + if (h_obj != NULL && DUK_HOBJECT_IS_BUFOBJ(h_obj)) { + /* DataView needs special casing: ArrayBuffer.isView() is + * true, but ->is_typedarray is 0. + */ + ret = ((duk_hbufobj *)h_obj)->is_typedarray || + (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_DATAVIEW); + } + } + duk_push_boolean(thr, ret); + return 1; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * Uint8Array.allocPlain() + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_uint8array_allocplain(duk_hthread *thr) { + duk__hbufobj_fixed_from_argvalue(thr); + return 1; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * Uint8Array.plainOf() + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_uint8array_plainof(duk_hthread *thr) { + duk_hbufobj *h_bufobj; + +#if !defined(DUK_USE_PREFER_SIZE) + /* Avoid churn if argument is already a plain buffer. */ + if (duk_is_buffer(thr, 0)) { + return 1; + } +#endif + + /* Promotes plain buffers to ArrayBuffers, so for a plain buffer + * argument we'll create a pointless temporary (but still work + * correctly). + */ + h_bufobj = duk__require_bufobj_value(thr, 0); + if (h_bufobj->buf == NULL) { + duk_push_undefined(thr); + } else { + duk_push_hbuffer(thr, h_bufobj->buf); + } + return 1; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * Node.js Buffer: toString([encoding], [start], [end]) + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_hthread *thr) { + duk_hbufobj *h_this; + duk_int_t start_offset, end_offset; + duk_uint8_t *buf_slice; + duk_size_t slice_length; + + h_this = duk__get_bufobj_this(thr); + if (h_this == NULL) { + /* XXX: happens e.g. when evaluating: String(Buffer.prototype). */ + duk_push_literal(thr, "[object Object]"); + return 1; + } + DUK_HBUFOBJ_ASSERT_VALID(h_this); + + /* Ignore encoding for now. */ + + duk__clamp_startend_nonegidx_noshift(thr, (duk_int_t)h_this->length, + 1 /*idx_start*/, 2 /*idx_end*/, + &start_offset, &end_offset); + + slice_length = (duk_size_t)(end_offset - start_offset); + buf_slice = (duk_uint8_t *)duk_push_fixed_buffer_nozero( + thr, slice_length); /* all bytes initialized below */ + DUK_ASSERT(buf_slice != NULL); + + /* Neutered or uncovered, TypeError. */ + if (h_this->buf == NULL || + !DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL( + h_this, (duk_size_t)start_offset + slice_length)) { + DUK_DCERROR_TYPE_INVALID_ARGS(thr); + } + + /* XXX: ideally we wouldn't make a copy but a view into the buffer for the + * decoding process. Or the decoding helper could be changed to accept + * the slice info (a buffer pointer is NOT a good approach because + * guaranteeing its stability is difficult). + */ + + DUK_ASSERT(DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL( + h_this, (duk_size_t)start_offset + slice_length)); + duk_memcpy_unsafe( + (void *)buf_slice, + (const void *)(DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + + start_offset), + (size_t)slice_length); + + /* Use the equivalent of: new TextEncoder().encode(this) to convert the + * string. Result will be valid UTF-8; non-CESU-8 inputs are currently + * interpreted loosely. Value stack convention is a bit odd for now. + */ + duk_replace(thr, 0); + duk_set_top(thr, 1); + return duk_textdecoder_decode_utf8_nodejs(thr); +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * Node.js Buffer.prototype: toJSON() + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_hthread *thr) { + duk_hbufobj *h_this; + duk_uint8_t *buf; + duk_uint_t i, n; + duk_tval *tv; + + h_this = duk__require_bufobj_this(thr); + DUK_ASSERT(h_this != NULL); + + if (h_this->buf == NULL || !DUK_HBUFOBJ_VALID_SLICE(h_this)) { + /* Serialize uncovered backing buffer as a null; doesn't + * really matter as long we're memory safe. + */ + duk_push_null(thr); + return 1; + } + + duk_push_object(thr); + duk_push_hstring_stridx(thr, DUK_STRIDX_UC_BUFFER); + duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_TYPE); + + /* XXX: uninitialized would be OK */ + DUK_ASSERT_DISABLE((duk_size_t)h_this->length <= (duk_size_t)DUK_UINT32_MAX); + tv = duk_push_harray_with_size_outptr( + thr, + (duk_uint32_t)h_this->length); /* XXX: needs revision with >4G buffers */ + DUK_ASSERT(!duk_is_bare_object(thr, -1)); + + DUK_ASSERT(h_this->buf != NULL); + buf = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this); + for (i = 0, n = h_this->length; i < n; i++) { + DUK_TVAL_SET_U32(tv + i, + (duk_uint32_t)buf[i]); /* no need for decref or incref */ + } + duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_DATA); + + return 1; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * Node.js Buffer.prototype.equals() + * Node.js Buffer.prototype.compare() + * Node.js Buffer.compare() + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_buffer_compare_shared(duk_hthread *thr) { + duk_small_uint_t magic; + duk_hbufobj *h_bufarg1; + duk_hbufobj *h_bufarg2; + duk_small_int_t comp_res; + + /* XXX: keep support for plain buffers and non-Node.js buffers? */ + + magic = (duk_small_uint_t)duk_get_current_magic(thr); + if (magic & 0x02U) { + /* Static call style. */ + h_bufarg1 = duk__require_bufobj_value(thr, 0); + h_bufarg2 = duk__require_bufobj_value(thr, 1); + } else { + h_bufarg1 = duk__require_bufobj_this(thr); + h_bufarg2 = duk__require_bufobj_value(thr, 0); + } + DUK_ASSERT(h_bufarg1 != NULL); + DUK_ASSERT(h_bufarg2 != NULL); + + /* We want to compare the slice/view areas of the arguments. + * If either slice/view is invalid (underlying buffer is shorter) + * ensure equals() is false, but otherwise the only thing that + * matters is to be memory safe. + */ + + if (DUK_HBUFOBJ_VALID_SLICE(h_bufarg1) && + DUK_HBUFOBJ_VALID_SLICE(h_bufarg2)) { + comp_res = duk_js_data_compare( + (const duk_uint8_t *)DUK_HBUFFER_GET_DATA_PTR(thr->heap, + h_bufarg1->buf) + + h_bufarg1->offset, + (const duk_uint8_t *)DUK_HBUFFER_GET_DATA_PTR(thr->heap, + h_bufarg2->buf) + + h_bufarg2->offset, + (duk_size_t)h_bufarg1->length, (duk_size_t)h_bufarg2->length); + } else { + comp_res = -1; /* either nonzero value is ok */ + } + + if (magic & 0x01U) { + /* compare: similar to string comparison but for buffer data. */ + duk_push_int(thr, comp_res); + } else { + /* equals */ + duk_push_boolean(thr, (comp_res == 0)); + } + + return 1; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * Node.js Buffer.prototype.fill() + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_fill(duk_hthread *thr) { + duk_hbufobj *h_this; + const duk_uint8_t *fill_str_ptr; + duk_size_t fill_str_len; + duk_uint8_t fill_value; + duk_int_t fill_offset; + duk_int_t fill_end; + duk_size_t fill_length; + duk_uint8_t *p; + + h_this = duk__require_bufobj_this(thr); + DUK_ASSERT(h_this != NULL); + if (h_this->buf == NULL) { + DUK_DCERROR_TYPE_INVALID_ARGS(thr); + } + + /* [ value offset end ] */ + + if (duk_is_string_notsymbol(thr, 0)) { + fill_str_ptr = (const duk_uint8_t *)duk_get_lstring(thr, 0, &fill_str_len); + DUK_ASSERT(fill_str_ptr != NULL); + } else { + /* Symbols get ToNumber() coerced and cause TypeError. */ + fill_value = (duk_uint8_t)duk_to_uint32(thr, 0); + fill_str_ptr = (const duk_uint8_t *)&fill_value; + fill_str_len = 1; + } + + /* Fill offset handling is more lenient than in Node.js. */ + + duk__clamp_startend_nonegidx_noshift(thr, (duk_int_t)h_this->length, + 1 /*idx_start*/, 2 /*idx_end*/, + &fill_offset, &fill_end); + + DUK_DDD(DUK_DDDPRINT( + "fill: fill_value=%02x, fill_offset=%ld, fill_end=%ld, view length=%ld", + (unsigned int)fill_value, (long)fill_offset, (long)fill_end, + (long)h_this->length)); + + DUK_ASSERT(fill_end - fill_offset >= 0); + DUK_ASSERT(h_this->buf != NULL); + + p = (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + fill_offset); + fill_length = (duk_size_t)(fill_end - fill_offset); + if (fill_str_len == 1) { + /* Handle single character fills as memset() even when + * the fill data comes from a one-char argument. + */ + duk_memset_unsafe((void *)p, (int)fill_str_ptr[0], (size_t)fill_length); + } else if (fill_str_len > 1) { + duk_size_t i, n, t; + + for (i = 0, n = (duk_size_t)(fill_end - fill_offset), t = 0; i < n; i++) { + p[i] = fill_str_ptr[t++]; + if (t >= fill_str_len) { + t = 0; + } + } + } else { + DUK_DDD(DUK_DDDPRINT("zero size fill pattern, ignore silently")); + } + + /* Return the Buffer to allow chaining: b.fill(0x11).fill(0x22, 3, + * 5).toString() */ + duk_push_this(thr); + return 1; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * Node.js Buffer.prototype.write(string, [offset], [length], [encoding]) + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_write(duk_hthread *thr) { + duk_hbufobj *h_this; + duk_uint_t offset; + duk_uint_t length; + const duk_uint8_t *str_data; + duk_size_t str_len; + + length = 0; + offset = 0; + + /* XXX: very inefficient support for plain buffers */ + h_this = duk__require_bufobj_this(thr); + DUK_ASSERT(h_this != NULL); + + /* Argument must be a string, e.g. a buffer is not allowed. */ + str_data = + (const duk_uint8_t *)duk_require_lstring_notsymbol(thr, 0, &str_len); + + duk__resolve_offset_opt_length(thr, h_this, 1, 2, &offset, &length, + 0 /*throw_flag*/); + DUK_ASSERT(offset <= h_this->length); + DUK_ASSERT(offset + length <= h_this->length); + + /* XXX: encoding is ignored now. */ + + if (length > str_len) { + length = (duk_uint_t)str_len; + } + + if (DUK_HBUFOBJ_VALID_SLICE(h_this)) { + /* Cannot overlap. */ + duk_memcpy_unsafe( + (void *)(DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + offset), + (const void *)str_data, (size_t)length); + } else { + DUK_DDD( + DUK_DDDPRINT("write() target buffer is not covered, silent ignore")); + } + + duk_push_uint(thr, length); + return 1; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * Node.js Buffer.prototype.copy() + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_copy(duk_hthread *thr) { + duk_hbufobj *h_this; + duk_hbufobj *h_bufarg; + duk_int_t source_length; + duk_int_t target_length; + duk_int_t target_start, source_start, source_end; + duk_uint_t target_ustart, source_ustart, source_uend; + duk_uint_t copy_size = 0; + + /* [ targetBuffer targetStart sourceStart sourceEnd ] */ + + h_this = duk__require_bufobj_this(thr); + h_bufarg = duk__require_bufobj_value(thr, 0); + DUK_ASSERT(h_this != NULL); + DUK_ASSERT(h_bufarg != NULL); + source_length = (duk_int_t)h_this->length; + target_length = (duk_int_t)h_bufarg->length; + + target_start = duk_to_int(thr, 1); + source_start = duk_to_int(thr, 2); + if (duk_is_undefined(thr, 3)) { + source_end = source_length; + } else { + source_end = duk_to_int(thr, 3); + } + + DUK_DDD( + DUK_DDDPRINT("checking copy args: target_start=%ld, target_length=%ld, " + "source_start=%ld, source_end=%ld, source_length=%ld", + (long)target_start, (long)h_bufarg->length, + (long)source_start, (long)source_end, (long)source_length)); + + /* This behavior mostly mimics Node.js now. */ + + if (source_start < 0 || source_end < 0 || target_start < 0) { + /* Negative offsets cause a RangeError. */ + goto fail_bounds; + } + source_ustart = (duk_uint_t)source_start; + source_uend = (duk_uint_t)source_end; + target_ustart = (duk_uint_t)target_start; + if (source_ustart >= source_uend || /* crossed offsets or zero size */ + source_ustart >= + (duk_uint_t)source_length || /* source out-of-bounds (but positive) */ + target_ustart >= + (duk_uint_t)target_length) { /* target out-of-bounds (but positive) */ + goto silent_ignore; + } + if (source_uend >= (duk_uint_t)source_length) { + /* Source end clamped silently to available length. */ + source_uend = (duk_uint_t)source_length; + } + copy_size = source_uend - source_ustart; + if (target_ustart + copy_size > (duk_uint_t)target_length) { + /* Clamp to target's end if too long. + * + * NOTE: there's no overflow possibility in the comparison; + * both target_ustart and copy_size are >= 0 and based on + * values in duk_int_t range. Adding them as duk_uint_t + * values is then guaranteed not to overflow. + */ + DUK_ASSERT(target_ustart + copy_size >= target_ustart); /* no overflow */ + DUK_ASSERT(target_ustart + copy_size >= copy_size); /* no overflow */ + copy_size = (duk_uint_t)target_length - target_ustart; + } + + DUK_DDD(DUK_DDDPRINT( + "making copy: target_ustart=%lu source_ustart=%lu copy_size=%lu", + (unsigned long)target_ustart, (unsigned long)source_ustart, + (unsigned long)copy_size)); + + DUK_ASSERT(copy_size >= 1); + DUK_ASSERT(source_ustart <= (duk_uint_t)source_length); + DUK_ASSERT(source_ustart + copy_size <= (duk_uint_t)source_length); + DUK_ASSERT(target_ustart <= (duk_uint_t)target_length); + DUK_ASSERT(target_ustart + copy_size <= (duk_uint_t)target_length); + + /* Ensure copy is covered by underlying buffers. */ + DUK_ASSERT(h_bufarg->buf != NULL); /* length check */ + DUK_ASSERT(h_this->buf != NULL); /* length check */ + if (DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufarg, target_ustart + copy_size) && + DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, source_ustart + copy_size)) { + /* Must use memmove() because copy area may overlap (source and target + * buffer may be the same, or from different slices. + */ + duk_memmove_unsafe( + (void *)(DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg) + + target_ustart), + (const void *)(DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + + source_ustart), + (size_t)copy_size); + } else { + DUK_DDD(DUK_DDDPRINT( + "buffer copy not covered by underlying buffer(s), ignoring")); + } + +silent_ignore: + /* Return value is like write(), number of bytes written. + * The return value matters because of code like: + * "off += buf.copy(...)". + */ + duk_push_uint(thr, copy_size); + return 1; + +fail_bounds: + DUK_DCERROR_RANGE_INVALID_ARGS(thr); +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * TypedArray.prototype.set() + * + * TypedArray set() is pretty interesting to implement because: + * + * - The source argument may be a plain array or a typedarray. If the + * source is a TypedArray, values are decoded and re-encoded into the + * target (not as a plain byte copy). This may happen even when the + * element byte size is the same, e.g. integer values may be re-encoded + * into floats. + * + * - Source and target may refer to the same underlying buffer, so that + * the set() operation may overlap. The specification requires that this + * must work as if a copy was made before the operation. Note that this + * is NOT a simple memmove() situation because the source and target + * byte sizes may be different -- e.g. a 4-byte source (Int8Array) may + * expand to a 16-byte target (Uint32Array) so that the target overlaps + * the source both from beginning and the end (unlike in typical memmove). + * + * - Even if 'buf' pointers of the source and target differ, there's no + * guarantee that their memory areas don't overlap. This may be the + * case with external buffers. + * + * Even so, it is nice to optimize for the common case: + * + * - Source and target separate buffers or non-overlapping. + * + * - Source and target have a compatible type so that a plain byte copy + * is possible. Note that while e.g. uint8 and int8 are compatible + * (coercion one way or another doesn't change the byte representation), + * e.g. int8 and uint8clamped are NOT compatible when writing int8 + * values into uint8clamped typedarray (-1 would clamp to 0 for instance). + * + * See test-bi-typedarray-proto-set.js. + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_hthread *thr) { + duk_hbufobj *h_this; + duk_hobject *h_obj; + duk_uarridx_t i, n; + duk_int_t offset_signed; + duk_uint_t offset_elems; + duk_uint_t offset_bytes; + + h_this = duk__require_bufobj_this(thr); + DUK_ASSERT(h_this != NULL); + DUK_HBUFOBJ_ASSERT_VALID(h_this); + + if (h_this->buf == NULL) { + DUK_DDD(DUK_DDDPRINT("source neutered, skip copy")); + return 0; + } + + duk_hbufobj_promote_plain(thr, 0); + h_obj = duk_require_hobject(thr, 0); + + /* XXX: V8 throws a TypeError for negative values. Would it + * be more useful to interpret negative offsets here from the + * end of the buffer too? + */ + offset_signed = duk_to_int(thr, 1); + if (offset_signed < 0) { + /* For some reason this is a TypeError (at least in V8). */ + DUK_DCERROR_TYPE_INVALID_ARGS(thr); + } + offset_elems = (duk_uint_t)offset_signed; + offset_bytes = offset_elems << h_this->shift; + if ((offset_bytes >> h_this->shift) != offset_elems) { + /* Byte length would overflow. */ + /* XXX: easier check with less code? */ + goto fail_args; + } + if (offset_bytes > h_this->length) { + /* Equality may be OK but >length not. Checking + * this explicitly avoids some overflow cases + * below. + */ + goto fail_args; + } + DUK_ASSERT(offset_bytes <= h_this->length); + + /* Fast path: source is a TypedArray (or any bufobj). */ + + if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) { + duk_hbufobj *h_bufarg; +#if !defined(DUK_USE_PREFER_SIZE) + duk_uint16_t comp_mask; +#endif + duk_small_int_t no_overlap = 0; + duk_uint_t src_length; + duk_uint_t dst_length; + duk_uint_t dst_length_elems; + duk_uint8_t *p_src_base; + duk_uint8_t *p_src_end; + duk_uint8_t *p_src; + duk_uint8_t *p_dst_base; + duk_uint8_t *p_dst; + duk_small_uint_t src_elem_size; + duk_small_uint_t dst_elem_size; + + h_bufarg = (duk_hbufobj *)h_obj; + DUK_HBUFOBJ_ASSERT_VALID(h_bufarg); + + if (h_bufarg->buf == NULL) { + DUK_DDD(DUK_DDDPRINT("target neutered, skip copy")); + return 0; + } + + /* Nominal size check. */ + src_length = h_bufarg->length; /* bytes in source */ + dst_length_elems = + (src_length >> h_bufarg->shift); /* elems in source and dest */ + dst_length = dst_length_elems << h_this->shift; /* bytes in dest */ + if ((dst_length >> h_this->shift) != dst_length_elems) { + /* Byte length would overflow. */ + /* XXX: easier check with less code? */ + goto fail_args; + } + DUK_DDD(DUK_DDDPRINT("nominal size check: src_length=%ld, dst_length=%ld", + (long)src_length, (long)dst_length)); + DUK_ASSERT(offset_bytes <= h_this->length); + if (dst_length > h_this->length - offset_bytes) { + /* Overflow not an issue because subtraction is used on the right + * side and guaranteed to be >= 0. + */ + DUK_DDD(DUK_DDDPRINT("copy exceeds target buffer nominal length")); + goto fail_args; + } + if (!DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, offset_bytes + dst_length)) { + DUK_DDD( + DUK_DDDPRINT("copy not covered by underlying target buffer, ignore")); + return 0; + } + + p_src_base = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg); + p_dst_base = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + offset_bytes; + + /* Check actual underlying buffers for validity and that they + * cover the copy. No side effects are allowed after the check + * so that the validity status doesn't change. + */ + if (!DUK_HBUFOBJ_VALID_SLICE(h_this) || + !DUK_HBUFOBJ_VALID_SLICE(h_bufarg)) { + /* The condition could be more narrow and check for the + * copy area only, but there's no need for fine grained + * behavior when the underlying buffer is misconfigured. + */ + DUK_DDD(DUK_DDDPRINT( + "source and/or target not covered by underlying buffer, skip copy")); + return 0; + } + + /* We want to do a straight memory copy if possible: this is + * an important operation because .set() is the TypedArray + * way to copy chunks of memory. However, because set() + * conceptually works in terms of elements, not all views are + * compatible with direct byte copying. + * + * If we do manage a direct copy, the "overlap issue" handled + * below can just be solved using memmove() because the source + * and destination element sizes are necessarily equal. + */ + +#if !defined(DUK_USE_PREFER_SIZE) + DUK_ASSERT(h_this->elem_type < + sizeof(duk__buffer_elemtype_copy_compatible) / + sizeof(duk_uint16_t)); + comp_mask = duk__buffer_elemtype_copy_compatible[h_this->elem_type]; + if (comp_mask & (1u << h_bufarg->elem_type)) { + DUK_ASSERT(src_length == dst_length); + + DUK_DDD(DUK_DDDPRINT( + "fast path: able to use memmove() because views are compatible")); + duk_memmove_unsafe((void *)p_dst_base, (const void *)p_src_base, + (size_t)dst_length); + return 0; + } + DUK_DDD(DUK_DDDPRINT( + "fast path: views are not compatible with a byte copy, copy by item")); +#endif /* !DUK_USE_PREFER_SIZE */ + + /* We want to avoid making a copy to process set() but that's + * not always possible: the source and the target may overlap + * and because element sizes are different, the overlap cannot + * always be handled with a memmove() or choosing the copy + * direction in a certain way. For example, if source type is + * uint8 and target type is uint32, the target area may exceed + * the source area from both ends! + * + * Note that because external buffers may point to the same + * memory areas, we must ultimately make this check using + * pointers. + * + * NOTE: careful with side effects: any side effect may cause + * a buffer resize (or external buffer pointer/length update)! + */ + + DUK_DDD(DUK_DDDPRINT("overlap check: p_src_base=%p, src_length=%ld, " + "p_dst_base=%p, dst_length=%ld", + (void *)p_src_base, (long)src_length, + (void *)p_dst_base, (long)dst_length)); + + if (p_src_base >= + p_dst_base + dst_length || /* source starts after dest ends */ + p_src_base + src_length <= + p_dst_base) { /* source ends before dest starts */ + no_overlap = 1; + } + + if (!no_overlap) { + /* There's overlap: the desired end result is that + * conceptually a copy is made to avoid "trampling" + * of source data by destination writes. We make + * an actual temporary copy to handle this case. + */ + duk_uint8_t *p_src_copy; + + DUK_DDD(DUK_DDDPRINT("there is overlap, make a copy of the source")); + p_src_copy = (duk_uint8_t *)duk_push_fixed_buffer_nozero(thr, src_length); + DUK_ASSERT(p_src_copy != NULL); + duk_memcpy_unsafe((void *)p_src_copy, (const void *)p_src_base, + (size_t)src_length); + + p_src_base = p_src_copy; /* use p_src_base from now on */ + } + /* Value stack intentionally mixed size here. */ + + DUK_DDD(DUK_DDDPRINT("after overlap check: p_src_base=%p, src_length=%ld, " + "p_dst_base=%p, dst_length=%ld, valstack top=%ld", + (void *)p_src_base, (long)src_length, + (void *)p_dst_base, (long)dst_length, + (long)duk_get_top(thr))); + + /* Ready to make the copy. We must proceed element by element + * and must avoid any side effects that might cause the buffer + * validity check above to become invalid. + * + * Although we work through the value stack here, only plain + * numbers are handled which should be side effect safe. + */ + + src_elem_size = (duk_small_uint_t)(1U << h_bufarg->shift); + dst_elem_size = (duk_small_uint_t)(1U << h_this->shift); + p_src = p_src_base; + p_dst = p_dst_base; + p_src_end = p_src_base + src_length; + + while (p_src != p_src_end) { + DUK_DDD(DUK_DDDPRINT("fast path per element copy loop: " + "p_src=%p, p_src_end=%p, p_dst=%p", + (void *)p_src, (void *)p_src_end, (void *)p_dst)); + /* A validated read() is always a number, so it's write coercion + * is always side effect free an won't invalidate pointers etc. + */ + duk_hbufobj_push_validated_read(thr, h_bufarg, p_src, src_elem_size); + duk_hbufobj_validated_write(thr, h_this, p_dst, dst_elem_size); + duk_pop(thr); + p_src += src_elem_size; + p_dst += dst_elem_size; + } + + return 0; + } else { + /* Slow path: quite slow, but we save space by using the property code + * to write coerce target values. We don't need to worry about overlap + * here because the source is not a TypedArray. + * + * We could use the bufobj write coercion helper but since the + * property read may have arbitrary side effects, full validity checks + * would be needed for every element anyway. + */ + + n = (duk_uarridx_t)duk_get_length(thr, 0); + DUK_ASSERT(offset_bytes <= h_this->length); + if ((n << h_this->shift) > h_this->length - offset_bytes) { + /* Overflow not an issue because subtraction is used on the right + * side and guaranteed to be >= 0. + */ + DUK_DDD(DUK_DDDPRINT("copy exceeds target buffer nominal length")); + goto fail_args; + } + + /* There's no need to check for buffer validity status for the + * target here: the property access code will do that for each + * element. Moreover, if we did check the validity here, side + * effects from reading the source argument might invalidate + * the results anyway. + */ + + DUK_ASSERT_TOP(thr, 2); + duk_push_this(thr); + + for (i = 0; i < n; i++) { + duk_get_prop_index(thr, 0, i); + duk_put_prop_index(thr, 2, offset_elems + i); + } + } + + return 0; + +fail_args: + DUK_DCERROR_RANGE_INVALID_ARGS(thr); +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * Node.js Buffer.prototype.slice([start], [end]) + * ArrayBuffer.prototype.slice(begin, [end]) + * TypedArray.prototype.subarray(begin, [end]) + * + * The API calls are almost identical; negative indices are counted from end + * of buffer, and final indices are clamped (allowing crossed indices). Main + * differences: + * + * - Copy/view behavior; Node.js .slice() and TypedArray .subarray() create + * views, ArrayBuffer .slice() creates a copy + * + * - Resulting object has a different class and prototype depending on the + * call (or 'this' argument) + * + * - TypedArray .subarray() arguments are element indices, not byte offsets + * + * - Plain buffer argument creates a plain buffer slice + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_LOCAL void duk__arraybuffer_plain_slice(duk_hthread *thr, + duk_hbuffer *h_val) { + duk_int_t start_offset, end_offset; + duk_uint_t slice_length; + duk_uint8_t *p_copy; + duk_size_t copy_length; + + duk__clamp_startend_negidx_shifted( + thr, (duk_int_t)DUK_HBUFFER_GET_SIZE(h_val), 0 /*buffer_shift*/, + 0 /*idx_start*/, 1 /*idx_end*/, &start_offset, &end_offset); + DUK_ASSERT(end_offset <= (duk_int_t)DUK_HBUFFER_GET_SIZE(h_val)); + DUK_ASSERT(start_offset >= 0); + DUK_ASSERT(end_offset >= start_offset); + slice_length = (duk_uint_t)(end_offset - start_offset); + + p_copy = (duk_uint8_t *)duk_push_fixed_buffer_nozero( + thr, (duk_size_t)slice_length); + DUK_ASSERT(p_copy != NULL); + copy_length = slice_length; + + duk_memcpy_unsafe( + (void *)p_copy, + (const void *)((duk_uint8_t *)DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_val) + + start_offset), + copy_length); +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +/* Shared helper for slice/subarray operation. + * Magic: 0x01=isView, 0x02=copy, 0x04=Node.js Buffer special handling. + */ +DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_hthread *thr) { + duk_small_int_t magic; + duk_small_uint_t res_class_num; + duk_small_int_t res_proto_bidx; + duk_hbufobj *h_this; + duk_hbufobj *h_bufobj; + duk_hbuffer *h_val; + duk_int_t start_offset, end_offset; + duk_uint_t slice_length; + duk_tval *tv; + + /* [ start end ] */ + + magic = duk_get_current_magic(thr); + + tv = duk_get_borrowed_this_tval(thr); + DUK_ASSERT(tv != NULL); + + if (DUK_TVAL_IS_BUFFER(tv)) { + /* For plain buffers return a plain buffer slice. */ + h_val = DUK_TVAL_GET_BUFFER(tv); + DUK_ASSERT(h_val != NULL); + + if (magic & 0x02) { + /* Make copy: ArrayBuffer.prototype.slice() uses this. */ + duk__arraybuffer_plain_slice(thr, h_val); + return 1; + } else { + /* View into existing buffer: cannot be done if the + * result is a plain buffer because there's no slice + * info. So return an ArrayBuffer instance; coerce + * the 'this' binding into an object and behave as if + * the original call was for an Object-coerced plain + * buffer (handled automatically by duk__require_bufobj_this()). + */ + + DUK_DDD( + DUK_DDDPRINT("slice() doesn't handle view into plain buffer, coerce " + "'this' to ArrayBuffer object")); + /* fall through */ + } + } + tv = NULL; /* No longer valid nor needed. */ + + h_this = duk__require_bufobj_this(thr); + + /* Slice offsets are element (not byte) offsets, which only matters + * for TypedArray views, Node.js Buffer and ArrayBuffer have shift + * zero so byte and element offsets are the same. Negative indices + * are counted from end of slice, crossed indices are allowed (and + * result in zero length result), and final values are clamped + * against the current slice. There's intentionally no check + * against the underlying buffer here. + */ + + duk__clamp_startend_negidx_shifted( + thr, (duk_int_t)h_this->length, (duk_uint8_t)h_this->shift, + 0 /*idx_start*/, 1 /*idx_end*/, &start_offset, &end_offset); + DUK_ASSERT(end_offset >= start_offset); + DUK_ASSERT(start_offset >= 0); + DUK_ASSERT(end_offset >= 0); + slice_length = (duk_uint_t)(end_offset - start_offset); + + /* The resulting buffer object gets the same class and prototype as + * the buffer in 'this', e.g. if the input is a Uint8Array the + * result is a Uint8Array; if the input is a Float32Array, the + * result is a Float32Array. The result internal prototype should + * be the default prototype for the class (e.g. initial value of + * Uint8Array.prototype), not copied from the argument (Duktape 1.x + * did that). + * + * Node.js Buffers have special handling: they're Uint8Arrays as far + * as the internal class is concerned, so the new Buffer should also + * be an Uint8Array but inherit from Buffer.prototype. + */ + res_class_num = DUK_HOBJECT_GET_CLASS_NUMBER((duk_hobject *)h_this); + DUK_ASSERT(res_class_num >= + DUK_HOBJECT_CLASS_BUFOBJ_MIN); /* type check guarantees */ + DUK_ASSERT(res_class_num <= DUK_HOBJECT_CLASS_BUFOBJ_MAX); + res_proto_bidx = + duk__buffer_proto_from_classnum[res_class_num - + DUK_HOBJECT_CLASS_BUFOBJ_MIN]; + if (magic & 0x04) { + res_proto_bidx = DUK_BIDX_NODEJS_BUFFER_PROTOTYPE; + } + h_bufobj = duk_push_bufobj_raw(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_BUFOBJ | + DUK_HOBJECT_CLASS_AS_FLAGS(res_class_num), + res_proto_bidx); + DUK_ASSERT(h_bufobj != NULL); + + DUK_ASSERT(h_bufobj->length == 0); + h_bufobj->shift = h_this->shift; /* inherit */ + h_bufobj->elem_type = h_this->elem_type; /* inherit */ + h_bufobj->is_typedarray = magic & 0x01; + DUK_ASSERT(h_bufobj->is_typedarray == 0 || h_bufobj->is_typedarray == 1); + + h_val = h_this->buf; + if (h_val == NULL) { + DUK_DCERROR_TYPE_INVALID_ARGS(thr); + } + + if (magic & 0x02) { + /* non-zero: make copy */ + duk_uint8_t *p_copy; + duk_size_t copy_length; + + p_copy = (duk_uint8_t *)duk_push_fixed_buffer_zero( + thr, + (duk_size_t) + slice_length); /* must be zeroed, not all bytes always copied */ + DUK_ASSERT(p_copy != NULL); + + /* Copy slice, respecting underlying buffer limits; remainder + * is left as zero. + */ + copy_length = DUK_HBUFOBJ_CLAMP_BYTELENGTH(h_this, slice_length); + duk_memcpy_unsafe( + (void *)p_copy, + (const void *)(DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + + start_offset), + copy_length); + + h_val = duk_known_hbuffer(thr, -1); + + h_bufobj->buf = h_val; + DUK_HBUFFER_INCREF(thr, h_val); + h_bufobj->length = slice_length; + DUK_ASSERT(h_bufobj->offset == 0); + + duk_pop(thr); /* reachable so pop OK */ + } else { + h_bufobj->buf = h_val; + DUK_HBUFFER_INCREF(thr, h_val); + h_bufobj->length = slice_length; + h_bufobj->offset = h_this->offset + (duk_uint_t)start_offset; + + /* Copy the .buffer property, needed for TypedArray.prototype.subarray(). + * + * XXX: limit copy only for TypedArray classes specifically? + */ + + DUK_ASSERT(h_bufobj->buf_prop == NULL); + h_bufobj->buf_prop = h_this->buf_prop; /* may be NULL */ + DUK_HOBJECT_INCREF_ALLOWNULL(thr, (duk_hobject *)h_bufobj->buf_prop); + } + /* unbalanced stack on purpose */ + + DUK_HBUFOBJ_ASSERT_VALID(h_bufobj); + return 1; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * Node.js Buffer.isEncoding() + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_encoding(duk_hthread *thr) { + const char *encoding; + + /* only accept lowercase 'utf8' now. */ + + encoding = duk_to_string(thr, 0); + DUK_ASSERT(duk_is_string(thr, 0)); /* guaranteed by duk_to_string() */ + duk_push_boolean(thr, DUK_STRCMP(encoding, "utf8") == 0); + return 1; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * Node.js Buffer.isBuffer() + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_buffer(duk_hthread *thr) { + duk_hobject *h; + duk_hobject *h_proto; + duk_bool_t ret = 0; + + DUK_ASSERT(duk_get_top(thr) >= 1); /* nargs */ + h = duk_get_hobject(thr, 0); + if (h != NULL) { + h_proto = thr->builtins[DUK_BIDX_NODEJS_BUFFER_PROTOTYPE]; + DUK_ASSERT(h_proto != NULL); + + h = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h); + if (h != NULL) { + ret = duk_hobject_prototype_chain_contains(thr, h, h_proto, + 0 /*ignore_loop*/); + } + } + + duk_push_boolean(thr, ret); + return 1; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * Node.js Buffer.byteLength() + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_byte_length(duk_hthread *thr) { + const char *str; + duk_size_t len; + + /* At the moment Buffer() will just use the string bytes as + * is (ignoring encoding), so we return the string length here + * unconditionally. + */ + + /* XXX: to be revised; Old Node.js behavior just coerces any buffer + * values to string: + * $ node + * > Buffer.byteLength(new Uint32Array(10)) + * 20 + * > Buffer.byteLength(new Uint32Array(100)) + * 20 + * (The 20 comes from '[object Uint32Array]'.length + */ + + str = duk_to_lstring(thr, 0, &len); + DUK_UNREF(str); + duk_push_size_t(thr, len); + return 1; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * Node.js Buffer.concat() + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_concat(duk_hthread *thr) { + duk_hobject *h_arg; + duk_uint_t total_length; + duk_hbufobj *h_bufobj; + duk_hbufobj *h_bufres; + duk_hbuffer *h_val; + duk_uint_t i, n; + duk_uint8_t *p; + duk_size_t space_left; + duk_size_t copy_size; + + /* Node.js accepts only actual Arrays. */ + h_arg = duk_require_hobject(thr, 0); + if (DUK_HOBJECT_GET_CLASS_NUMBER(h_arg) != DUK_HOBJECT_CLASS_ARRAY) { + DUK_DCERROR_TYPE_INVALID_ARGS(thr); + } + + /* Compute result length and validate argument buffers. */ + n = (duk_uint_t)duk_get_length(thr, 0); + total_length = 0; + for (i = 0; i < n; i++) { + /* Neutered checks not necessary here: neutered buffers have + * zero 'length' so we'll effectively skip them. + */ + DUK_ASSERT_TOP(thr, 2); /* [ array totalLength ] */ + duk_get_prop_index(thr, 0, + (duk_uarridx_t)i); /* -> [ array totalLength buf ] */ + h_bufobj = duk__require_bufobj_value(thr, 2); + DUK_ASSERT(h_bufobj != NULL); + total_length += h_bufobj->length; + if (DUK_UNLIKELY(total_length < h_bufobj->length)) { + DUK_DCERROR_RANGE_INVALID_ARGS(thr); /* Wrapped. */ + } + duk_pop(thr); + } + /* In Node.js v0.12.1 a 1-element array is special and won't create a + * copy, this was fixed later so an explicit check no longer needed. + */ + + /* User totalLength overrides a computed length, but we'll check + * every copy in the copy loop. Note that duk_to_int() can + * technically have arbitrary side effects so we need to recheck + * the buffers in the copy loop. + */ + if (!duk_is_undefined(thr, 1) && n > 0) { + /* For n == 0, Node.js ignores totalLength argument and + * returns a zero length buffer. + */ + duk_int_t total_length_signed; + total_length_signed = duk_to_int(thr, 1); + if (total_length_signed < 0) { + DUK_DCERROR_RANGE_INVALID_ARGS(thr); + } + total_length = (duk_uint_t)total_length_signed; + } + + h_bufres = duk_push_bufobj_raw( + thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_FLAG_BUFOBJ | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_UINT8ARRAY), + DUK_BIDX_NODEJS_BUFFER_PROTOTYPE); + DUK_ASSERT(h_bufres != NULL); + + p = (duk_uint8_t *)duk_push_fixed_buffer_zero( + thr, total_length); /* must be zeroed, all bytes not necessarily written + over */ + DUK_ASSERT(p != NULL); + space_left = (duk_size_t)total_length; + + for (i = 0; i < n; i++) { + DUK_ASSERT_TOP(thr, 4); /* [ array totalLength bufres buf ] */ + + duk_get_prop_index(thr, 0, (duk_uarridx_t)i); + h_bufobj = duk__require_bufobj_value(thr, 4); + DUK_ASSERT(h_bufobj != NULL); + + copy_size = h_bufobj->length; + if (copy_size > space_left) { + copy_size = space_left; + } + + if (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) { + duk_memcpy_unsafe( + (void *)p, + (const void *)DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufobj), + copy_size); + } else { + /* Just skip, leaving zeroes in the result. */ + ; + } + p += copy_size; + space_left -= copy_size; + + duk_pop(thr); + } + + h_val = duk_known_hbuffer(thr, -1); + + duk__set_bufobj_buffer(thr, h_bufres, h_val); + h_bufres->is_typedarray = 1; + DUK_HBUFOBJ_ASSERT_VALID(h_bufres); + + duk_pop(thr); /* pop plain buffer, now reachable through h_bufres */ + + return 1; /* return h_bufres */ +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * Shared readfield and writefield methods + * + * The readfield/writefield methods need support for endianness and field + * types. All offsets are byte based so no offset shifting is needed. + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +/* Format of magic, bits: + * 0...1: field type; 0=uint8, 1=uint16, 2=uint32, 3=float, 4=double, + * 5=unused, 6=unused, 7=unused 3: endianness: 0=little, 1=big 4: signed: 1=yes, + * 0=no 5: typedarray: 1=yes, 0=no + */ +#define DUK__FLD_8BIT 0 +#define DUK__FLD_16BIT 1 +#define DUK__FLD_32BIT 2 +#define DUK__FLD_FLOAT 3 +#define DUK__FLD_DOUBLE 4 +#define DUK__FLD_VARINT 5 +#define DUK__FLD_BIGENDIAN (1 << 3) +#define DUK__FLD_SIGNED (1 << 4) +#define DUK__FLD_TYPEDARRAY (1 << 5) + +/* XXX: split into separate functions for each field type? */ +DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_hthread *thr) { + duk_small_int_t magic = (duk_small_int_t)duk_get_current_magic(thr); + duk_small_int_t magic_ftype; + duk_small_int_t magic_bigendian; + duk_small_int_t magic_signed; + duk_small_int_t magic_typedarray; + duk_small_uint_t endswap; + duk_hbufobj *h_this; + duk_bool_t no_assert; + duk_int_t offset_signed; + duk_uint_t offset; + duk_uint_t buffer_length; + duk_uint_t check_length; + duk_uint8_t *buf; + duk_double_union du; + + magic_ftype = magic & 0x0007; + magic_bigendian = magic & 0x0008; + magic_signed = magic & 0x0010; + magic_typedarray = magic & 0x0020; + + h_this = duk__require_bufobj_this( + thr); /* XXX: very inefficient for plain buffers */ + DUK_ASSERT(h_this != NULL); + buffer_length = h_this->length; + + /* [ offset noAssert ], when ftype != DUK__FLD_VARINT */ + /* [ offset fieldByteLength noAssert ], when ftype == DUK__FLD_VARINT */ + /* [ offset littleEndian ], when DUK__FLD_TYPEDARRAY (regardless + * of ftype) */ + + /* Handle TypedArray vs. Node.js Buffer arg differences */ + if (magic_typedarray) { + no_assert = 0; +#if defined(DUK_USE_INTEGER_LE) + endswap = !duk_to_boolean(thr, 1); /* 1=little endian */ +#else + endswap = duk_to_boolean(thr, 1); /* 1=little endian */ +#endif + } else { + no_assert = duk_to_boolean(thr, (magic_ftype == DUK__FLD_VARINT) ? 2 : 1); +#if defined(DUK_USE_INTEGER_LE) + endswap = magic_bigendian; +#else + endswap = !magic_bigendian; +#endif + } + + /* Offset is coerced first to signed integer range and then to unsigned. + * This ensures we can add a small byte length (1-8) to the offset in + * bound checks and not wrap. + */ + offset_signed = duk_to_int(thr, 0); + offset = (duk_uint_t)offset_signed; + if (offset_signed < 0) { + goto fail_bounds; + } + + DUK_DDD(DUK_DDDPRINT( + "readfield, buffer_length=%ld, offset=%ld, no_assert=%d, " + "magic=%04x, magic_fieldtype=%d, magic_bigendian=%d, magic_signed=%d, " + "endswap=%u", + (long)buffer_length, (long)offset, (int)no_assert, (unsigned int)magic, + (int)magic_ftype, (int)(magic_bigendian >> 3), (int)(magic_signed >> 4), + (int)endswap)); + + /* Update 'buffer_length' to be the effective, safe limit which + * takes into account the underlying buffer. This value will be + * potentially invalidated by any side effect. + */ + check_length = DUK_HBUFOBJ_CLAMP_BYTELENGTH(h_this, buffer_length); + DUK_DDD(DUK_DDDPRINT("buffer_length=%ld, check_length=%ld", + (long)buffer_length, (long)check_length)); + + if (h_this->buf) { + buf = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this); + } else { + /* Neutered. We could go into the switch-case safely with + * buf == NULL because check_length == 0. To avoid scanbuild + * warnings, fail directly instead. + */ + DUK_ASSERT(check_length == 0); + goto fail_neutered; + } + DUK_ASSERT(buf != NULL); + + switch (magic_ftype) { + case DUK__FLD_8BIT: { + duk_uint8_t tmp; + if (offset + 1U > check_length) { + goto fail_bounds; + } + tmp = buf[offset]; + if (magic_signed) { + duk_push_int(thr, (duk_int_t)((duk_int8_t)tmp)); + } else { + duk_push_uint(thr, (duk_uint_t)tmp); + } + break; + } + case DUK__FLD_16BIT: { + duk_uint16_t tmp; + if (offset + 2U > check_length) { + goto fail_bounds; + } + duk_memcpy((void *)du.uc, (const void *)(buf + offset), 2); + tmp = du.us[0]; + if (endswap) { + tmp = DUK_BSWAP16(tmp); + } + if (magic_signed) { + duk_push_int(thr, (duk_int_t)((duk_int16_t)tmp)); + } else { + duk_push_uint(thr, (duk_uint_t)tmp); + } + break; + } + case DUK__FLD_32BIT: { + duk_uint32_t tmp; + if (offset + 4U > check_length) { + goto fail_bounds; + } + duk_memcpy((void *)du.uc, (const void *)(buf + offset), 4); + tmp = du.ui[0]; + if (endswap) { + tmp = DUK_BSWAP32(tmp); + } + if (magic_signed) { + duk_push_int(thr, (duk_int_t)((duk_int32_t)tmp)); + } else { + duk_push_uint(thr, (duk_uint_t)tmp); + } + break; + } + case DUK__FLD_FLOAT: { + duk_uint32_t tmp; + if (offset + 4U > check_length) { + goto fail_bounds; + } + duk_memcpy((void *)du.uc, (const void *)(buf + offset), 4); + if (endswap) { + tmp = du.ui[0]; + tmp = DUK_BSWAP32(tmp); + du.ui[0] = tmp; + } + duk_push_number(thr, (duk_double_t)du.f[0]); + break; + } + case DUK__FLD_DOUBLE: { + if (offset + 8U > check_length) { + goto fail_bounds; + } + duk_memcpy((void *)du.uc, (const void *)(buf + offset), 8); + if (endswap) { + DUK_DBLUNION_BSWAP64(&du); + } + duk_push_number(thr, (duk_double_t)du.d); + break; + } + case DUK__FLD_VARINT: { + /* Node.js Buffer variable width integer field. We don't really + * care about speed here, so aim for shortest algorithm. + */ + duk_int_t field_bytelen; + duk_int_t i, i_step, i_end; +#if defined(DUK_USE_64BIT_OPS) + duk_int64_t tmp; + duk_small_uint_t shift_tmp; +#else + duk_double_t tmp; + duk_small_int_t highbyte; +#endif + const duk_uint8_t *p; + + field_bytelen = duk_get_int(thr, 1); /* avoid side effects! */ + if (field_bytelen < 1 || field_bytelen > 6) { + goto fail_field_length; + } + if (offset + (duk_uint_t)field_bytelen > check_length) { + goto fail_bounds; + } + p = (const duk_uint8_t *)(buf + offset); + + /* Slow gathering of value using either 64-bit arithmetic + * or IEEE doubles if 64-bit types not available. Handling + * of negative numbers is a bit non-obvious in both cases. + */ + + if (magic_bigendian) { + /* Gather in big endian */ + i = 0; + i_step = 1; + i_end = field_bytelen; /* one i_step over */ + } else { + /* Gather in little endian */ + i = field_bytelen - 1; + i_step = -1; + i_end = -1; /* one i_step over */ + } + +#if defined(DUK_USE_64BIT_OPS) + tmp = 0; + do { + DUK_ASSERT(i >= 0 && i < field_bytelen); + tmp = (tmp << 8) + (duk_int64_t)p[i]; + i += i_step; + } while (i != i_end); + + if (magic_signed) { + /* Shift to sign extend. Left shift must be unsigned + * to avoid undefined behavior; right shift must be + * signed to sign extend properly. + */ + shift_tmp = + (duk_small_uint_t)(64U - (duk_small_uint_t)field_bytelen * 8U); + tmp = (duk_int64_t)((duk_uint64_t)tmp << shift_tmp) >> shift_tmp; + } + + duk_push_i64(thr, tmp); +#else + highbyte = p[i]; + if (magic_signed && (highbyte & 0x80) != 0) { + /* 0xff => 255 - 256 = -1; 0x80 => 128 - 256 = -128 */ + tmp = (duk_double_t)(highbyte - 256); + } else { + tmp = (duk_double_t)highbyte; + } + for (;;) { + i += i_step; + if (i == i_end) { + break; + } + DUK_ASSERT(i >= 0 && i < field_bytelen); + tmp = (tmp * 256.0) + (duk_double_t)p[i]; + } + + duk_push_number(thr, tmp); +#endif + break; + } + default: { /* should never happen but default here */ + goto fail_bounds; + } + } + + return 1; + +fail_neutered: +fail_field_length: +fail_bounds: + if (no_assert) { + /* Node.js return value for noAssert out-of-bounds reads is + * usually (but not always) NaN. Return NaN consistently. + */ + duk_push_nan(thr); + return 1; + } + DUK_DCERROR_RANGE_INVALID_ARGS(thr); +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +/* XXX: split into separate functions for each field type? */ +DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_hthread *thr) { + duk_small_int_t magic = (duk_small_int_t)duk_get_current_magic(thr); + duk_small_int_t magic_ftype; + duk_small_int_t magic_bigendian; + duk_small_int_t magic_signed; + duk_small_int_t magic_typedarray; + duk_small_uint_t endswap; + duk_hbufobj *h_this; + duk_bool_t no_assert; + duk_int_t offset_signed; + duk_uint_t offset; + duk_uint_t buffer_length; + duk_uint_t check_length; + duk_uint8_t *buf; + duk_double_union du; + duk_int_t nbytes = 0; + + magic_ftype = magic & 0x0007; + magic_bigendian = magic & 0x0008; + magic_signed = magic & 0x0010; + magic_typedarray = magic & 0x0020; + DUK_UNREF(magic_signed); + + h_this = duk__require_bufobj_this( + thr); /* XXX: very inefficient for plain buffers */ + DUK_ASSERT(h_this != NULL); + buffer_length = h_this->length; + + /* [ value offset noAssert ], when ftype != DUK__FLD_VARINT + */ + /* [ value offset fieldByteLength noAssert ], when ftype == DUK__FLD_VARINT + */ + /* [ offset value littleEndian ], when DUK__FLD_TYPEDARRAY + * (regardless of ftype) */ + + /* Handle TypedArray vs. Node.js Buffer arg differences */ + if (magic_typedarray) { + no_assert = 0; +#if defined(DUK_USE_INTEGER_LE) + endswap = !duk_to_boolean(thr, 2); /* 1=little endian */ +#else + endswap = duk_to_boolean(thr, 2); /* 1=little endian */ +#endif + duk_swap(thr, 0, 1); /* offset/value order different from Node.js */ + } else { + no_assert = duk_to_boolean(thr, (magic_ftype == DUK__FLD_VARINT) ? 3 : 2); +#if defined(DUK_USE_INTEGER_LE) + endswap = magic_bigendian; +#else + endswap = !magic_bigendian; +#endif + } + + /* Offset is coerced first to signed integer range and then to unsigned. + * This ensures we can add a small byte length (1-8) to the offset in + * bound checks and not wrap. + */ + offset_signed = duk_to_int(thr, 1); + offset = (duk_uint_t)offset_signed; + + /* We need 'nbytes' even for a failed offset; return value must be + * (offset + nbytes) even when write fails due to invalid offset. + */ + if (magic_ftype != DUK__FLD_VARINT) { + DUK_ASSERT(magic_ftype >= 0 && + magic_ftype < + (duk_small_int_t)(sizeof(duk__buffer_nbytes_from_fldtype) / + sizeof(duk_uint8_t))); + nbytes = duk__buffer_nbytes_from_fldtype[magic_ftype]; + } else { + nbytes = duk_get_int(thr, 2); + if (nbytes < 1 || nbytes > 6) { + goto fail_field_length; + } + } + DUK_ASSERT(nbytes >= 1 && nbytes <= 8); + + /* Now we can check offset validity. */ + if (offset_signed < 0) { + goto fail_bounds; + } + + DUK_DDD(DUK_DDDPRINT( + "writefield, value=%!T, buffer_length=%ld, offset=%ld, no_assert=%d, " + "magic=%04x, magic_fieldtype=%d, magic_bigendian=%d, magic_signed=%d, " + "endswap=%u", + duk_get_tval(thr, 0), (long)buffer_length, (long)offset, (int)no_assert, + (unsigned int)magic, (int)magic_ftype, (int)(magic_bigendian >> 3), + (int)(magic_signed >> 4), (int)endswap)); + + /* Coerce value to a number before computing check_length, so that + * the field type specific coercion below can't have side effects + * that would invalidate check_length. + */ + duk_to_number(thr, 0); + + /* Update 'buffer_length' to be the effective, safe limit which + * takes into account the underlying buffer. This value will be + * potentially invalidated by any side effect. + */ + check_length = DUK_HBUFOBJ_CLAMP_BYTELENGTH(h_this, buffer_length); + DUK_DDD(DUK_DDDPRINT("buffer_length=%ld, check_length=%ld", + (long)buffer_length, (long)check_length)); + + if (h_this->buf) { + buf = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this); + } else { + /* Neutered. We could go into the switch-case safely with + * buf == NULL because check_length == 0. To avoid scanbuild + * warnings, fail directly instead. + */ + DUK_ASSERT(check_length == 0); + goto fail_neutered; + } + DUK_ASSERT(buf != NULL); + + switch (magic_ftype) { + case DUK__FLD_8BIT: { + if (offset + 1U > check_length) { + goto fail_bounds; + } + /* sign doesn't matter when writing */ + buf[offset] = (duk_uint8_t)duk_to_uint32(thr, 0); + break; + } + case DUK__FLD_16BIT: { + duk_uint16_t tmp; + if (offset + 2U > check_length) { + goto fail_bounds; + } + tmp = (duk_uint16_t)duk_to_uint32(thr, 0); + if (endswap) { + tmp = DUK_BSWAP16(tmp); + } + du.us[0] = tmp; + /* sign doesn't matter when writing */ + duk_memcpy((void *)(buf + offset), (const void *)du.uc, 2); + break; + } + case DUK__FLD_32BIT: { + duk_uint32_t tmp; + if (offset + 4U > check_length) { + goto fail_bounds; + } + tmp = (duk_uint32_t)duk_to_uint32(thr, 0); + if (endswap) { + tmp = DUK_BSWAP32(tmp); + } + du.ui[0] = tmp; + /* sign doesn't matter when writing */ + duk_memcpy((void *)(buf + offset), (const void *)du.uc, 4); + break; + } + case DUK__FLD_FLOAT: { + duk_uint32_t tmp; + if (offset + 4U > check_length) { + goto fail_bounds; + } + du.f[0] = (duk_float_t)duk_to_number(thr, 0); + if (endswap) { + tmp = du.ui[0]; + tmp = DUK_BSWAP32(tmp); + du.ui[0] = tmp; + } + /* sign doesn't matter when writing */ + duk_memcpy((void *)(buf + offset), (const void *)du.uc, 4); + break; + } + case DUK__FLD_DOUBLE: { + if (offset + 8U > check_length) { + goto fail_bounds; + } + du.d = (duk_double_t)duk_to_number(thr, 0); + if (endswap) { + DUK_DBLUNION_BSWAP64(&du); + } + /* sign doesn't matter when writing */ + duk_memcpy((void *)(buf + offset), (const void *)du.uc, 8); + break; + } + case DUK__FLD_VARINT: { + /* Node.js Buffer variable width integer field. We don't really + * care about speed here, so aim for shortest algorithm. + */ + duk_int_t field_bytelen; + duk_int_t i, i_step, i_end; +#if defined(DUK_USE_64BIT_OPS) + duk_int64_t tmp; +#else + duk_double_t tmp; +#endif + duk_uint8_t *p; + + field_bytelen = (duk_int_t)nbytes; + if (offset + (duk_uint_t)field_bytelen > check_length) { + goto fail_bounds; + } + + /* Slow writing of value using either 64-bit arithmetic + * or IEEE doubles if 64-bit types not available. There's + * no special sign handling when writing varints. + */ + + if (magic_bigendian) { + /* Write in big endian */ + i = field_bytelen; /* one i_step added at top of loop */ + i_step = -1; + i_end = 0; + } else { + /* Write in little endian */ + i = -1; /* one i_step added at top of loop */ + i_step = 1; + i_end = field_bytelen - 1; + } + + /* XXX: The duk_to_number() cast followed by integer coercion + * is platform specific so NaN, +/- Infinity, and out-of-bounds + * values result in platform specific output now. + * See: test-bi-nodejs-buffer-proto-varint-special.js + */ + +#if defined(DUK_USE_64BIT_OPS) + tmp = (duk_int64_t)duk_to_number(thr, 0); + p = (duk_uint8_t *)(buf + offset); + do { + i += i_step; + DUK_ASSERT(i >= 0 && i < field_bytelen); + p[i] = (duk_uint8_t)(tmp & 0xff); + tmp = tmp >> 8; /* unnecessary shift for last byte */ + } while (i != i_end); +#else + tmp = duk_to_number(thr, 0); + p = (duk_uint8_t *)(buf + offset); + do { + i += i_step; + tmp = DUK_FLOOR(tmp); + DUK_ASSERT(i >= 0 && i < field_bytelen); + p[i] = (duk_uint8_t)(DUK_FMOD(tmp, 256.0)); + tmp = tmp / 256.0; /* unnecessary div for last byte */ + } while (i != i_end); +#endif + break; + } + default: { /* should never happen but default here */ + goto fail_bounds; + } + } + + /* Node.js Buffer: return offset + #bytes written (i.e. next + * write offset). + */ + if (magic_typedarray) { + /* For TypedArrays 'undefined' return value is specified + * by ES2015 (matches V8). + */ + return 0; + } + duk_push_uint(thr, offset + (duk_uint_t)nbytes); + return 1; + +fail_neutered: +fail_field_length: +fail_bounds: + if (no_assert) { + /* Node.js return value for failed writes is offset + #bytes + * that would have been written. + */ + /* XXX: for negative input offsets, 'offset' will be a large + * positive value so the result here is confusing. + */ + if (magic_typedarray) { + return 0; + } + duk_push_uint(thr, offset + (duk_uint_t)nbytes); + return 1; + } + DUK_DCERROR_RANGE_INVALID_ARGS(thr); +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * Accessors for .buffer, .byteLength, .byteOffset + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_LOCAL duk_hbufobj *duk__autospawn_arraybuffer(duk_hthread *thr, + duk_hbuffer *h_buf) { + duk_hbufobj *h_res; + + h_res = duk_push_bufobj_raw( + thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_FLAG_BUFOBJ | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER), + DUK_BIDX_ARRAYBUFFER_PROTOTYPE); + DUK_ASSERT(h_res != NULL); + DUK_UNREF(h_res); + + duk__set_bufobj_buffer(thr, h_res, h_buf); + DUK_HBUFOBJ_ASSERT_VALID(h_res); + DUK_ASSERT(h_res->buf_prop == NULL); + return h_res; +} + +DUK_INTERNAL duk_ret_t duk_bi_typedarray_buffer_getter(duk_hthread *thr) { + duk_hbufobj *h_bufobj; + + h_bufobj = (duk_hbufobj *)duk__getrequire_bufobj_this( + thr, DUK__BUFOBJ_FLAG_THROW /*flags*/); + DUK_ASSERT(h_bufobj != NULL); + if (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *)h_bufobj)) { + DUK_DD(DUK_DDPRINT("autospawn ArrayBuffer for plain buffer")); + (void)duk__autospawn_arraybuffer(thr, (duk_hbuffer *)h_bufobj); + return 1; + } else { + if (h_bufobj->buf_prop == NULL && + DUK_HOBJECT_GET_CLASS_NUMBER((duk_hobject *)h_bufobj) != + DUK_HOBJECT_CLASS_ARRAYBUFFER && + h_bufobj->buf != NULL) { + duk_hbufobj *h_arrbuf; + + DUK_DD(DUK_DDPRINT("autospawn ArrayBuffer for typed array or DataView")); + h_arrbuf = duk__autospawn_arraybuffer(thr, h_bufobj->buf); + + if (h_bufobj->buf_prop == NULL) { + /* Must recheck buf_prop, in case ArrayBuffer + * alloc had a side effect which already filled + * it! + */ + + /* Set ArrayBuffer's .byteOffset and .byteLength based + * on the view so that Arraybuffer[view.byteOffset] + * matches view[0]. + */ + h_arrbuf->offset = 0; + DUK_ASSERT(h_bufobj->offset + h_bufobj->length >= + h_bufobj->offset); /* Wrap check on creation. */ + h_arrbuf->length = h_bufobj->offset + h_bufobj->length; + DUK_ASSERT(h_arrbuf->buf_prop == NULL); + + DUK_ASSERT(h_bufobj->buf_prop == NULL); + h_bufobj->buf_prop = (duk_hobject *)h_arrbuf; + DUK_HBUFOBJ_INCREF(thr, + h_arrbuf); /* Now reachable and accounted for. */ + } + + /* Left on stack; pushed for the second time below (OK). */ + } + if (h_bufobj->buf_prop) { + duk_push_hobject(thr, h_bufobj->buf_prop); + return 1; + } + } + return 0; +} + +DUK_INTERNAL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_hthread *thr) { + duk_hbufobj *h_bufobj; + + h_bufobj = (duk_hbufobj *)duk__getrequire_bufobj_this( + thr, DUK__BUFOBJ_FLAG_THROW /*flags*/); + DUK_ASSERT(h_bufobj != NULL); + if (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *)h_bufobj)) { + duk_push_uint(thr, 0); + } else { + /* If neutered must return 0; offset is zeroed during + * neutering. + */ + duk_push_uint(thr, h_bufobj->offset); + } + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_hthread *thr) { + duk_hbufobj *h_bufobj; + + h_bufobj = (duk_hbufobj *)duk__getrequire_bufobj_this( + thr, DUK__BUFOBJ_FLAG_THROW /*flags*/); + DUK_ASSERT(h_bufobj != NULL); + if (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *)h_bufobj)) { + duk_hbuffer *h_buf; + + h_buf = (duk_hbuffer *)h_bufobj; + DUK_ASSERT(DUK_HBUFFER_GET_SIZE(h_buf) <= + DUK_UINT_MAX); /* Buffer limits. */ + duk_push_uint(thr, (duk_uint_t)DUK_HBUFFER_GET_SIZE(h_buf)); + } else { + /* If neutered must return 0; length is zeroed during + * neutering. + */ + duk_push_uint(thr, h_bufobj->length); + } + return 1; +} +#else /* DUK_USE_BUFFEROBJECT_SUPPORT */ +/* No .buffer getter without ArrayBuffer support. */ +#if 0 +DUK_INTERNAL duk_ret_t duk_bi_typedarray_buffer_getter(duk_hthread *thr) { + return 0; +} +#endif + +DUK_INTERNAL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_hthread *thr) { + duk_push_uint(thr, 0); + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_hthread *thr) { + duk_hbuffer *h_buf; + + /* XXX: helper? */ + duk_push_this(thr); + h_buf = duk_require_hbuffer(thr, -1); + duk_push_uint(thr, DUK_HBUFFER_GET_SIZE(h_buf)); + return 1; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ diff --git a/third_party/duktape/duk_bi_cbor.c b/third_party/duktape/duk_bi_cbor.c new file mode 100644 index 00000000..303d07e8 --- /dev/null +++ b/third_party/duktape/duk_bi_cbor.c @@ -0,0 +1,1662 @@ +/* + * CBOR bindings. + * + * http://cbor.io/ + * https://tools.ietf.org/html/rfc7049 + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_CBOR_SUPPORT) + +/* #define DUK_CBOR_STRESS */ + +/* Default behavior for encoding strings: use CBOR text string if string + * is UTF-8 compatible, otherwise use CBOR byte string. These defines + * can be used to force either type for all strings. Using text strings + * for non-UTF-8 data is technically invalid CBOR. + */ +/* #define DUK_CBOR_TEXT_STRINGS */ +/* #define DUK_CBOR_BYTE_STRINGS */ + +/* Misc. defines. */ +/* #define DUK_CBOR_PREFER_SIZE */ +/* #define DUK_CBOR_DOUBLE_AS_IS */ +/* #define DUK_CBOR_DECODE_FASTPATH */ + +typedef struct { + duk_hthread *thr; + duk_uint8_t *ptr; + duk_uint8_t *buf; + duk_uint8_t *buf_end; + duk_size_t len; + duk_idx_t idx_buf; +} duk_cbor_encode_context; + +typedef struct { + duk_hthread *thr; + const duk_uint8_t *buf; + duk_size_t off; + duk_size_t len; +} duk_cbor_decode_context; + +DUK_LOCAL void duk__cbor_encode_value(duk_cbor_encode_context *enc_ctx); +DUK_LOCAL void duk__cbor_decode_value(duk_cbor_decode_context *dec_ctx); + +/* + * Misc + */ + +DUK_LOCAL duk_uint32_t duk__cbor_double_to_uint32(double d) { + /* Out of range casts are undefined behavior, so caller must avoid. */ + DUK_ASSERT(d >= 0.0 && d <= 4294967295.0); + return (duk_uint32_t) d; +} + +/* + * Encoding + */ + +DUK_LOCAL void duk__cbor_encode_error(duk_cbor_encode_context *enc_ctx) { + (void) duk_type_error(enc_ctx->thr, "cbor encode error"); +} + +/* Check that a size_t is in uint32 range to avoid out-of-range casts. */ +DUK_LOCAL void duk__cbor_encode_sizet_uint32_check(duk_cbor_encode_context *enc_ctx, duk_size_t len) { + if (DUK_UNLIKELY(sizeof(duk_size_t) > sizeof(duk_uint32_t) && len > (duk_size_t) DUK_UINT32_MAX)) { + duk__cbor_encode_error(enc_ctx); + } +} + +DUK_LOCAL DUK_NOINLINE void duk__cbor_encode_ensure_slowpath(duk_cbor_encode_context *enc_ctx, duk_size_t len) { + duk_size_t oldlen; + duk_size_t minlen; + duk_size_t newlen; + duk_uint8_t *p_new; + duk_size_t old_data_len; + + DUK_ASSERT(enc_ctx->ptr >= enc_ctx->buf); + DUK_ASSERT(enc_ctx->buf_end >= enc_ctx->ptr); + DUK_ASSERT(enc_ctx->buf_end >= enc_ctx->buf); + + /* Overflow check. + * + * Limit example: 0xffffffffUL / 2U = 0x7fffffffUL, we reject >= 0x80000000UL. + */ + oldlen = enc_ctx->len; + minlen = oldlen + len; + if (DUK_UNLIKELY(oldlen > DUK_SIZE_MAX / 2U || minlen < oldlen)) { + duk__cbor_encode_error(enc_ctx); + } + +#if defined(DUK_CBOR_STRESS) + newlen = oldlen + 1U; +#else + newlen = oldlen * 2U; +#endif + DUK_ASSERT(newlen >= oldlen); + + if (minlen > newlen) { + newlen = minlen; + } + DUK_ASSERT(newlen >= oldlen); + DUK_ASSERT(newlen >= minlen); + DUK_ASSERT(newlen > 0U); + + DUK_DD(DUK_DDPRINT("cbor encode buffer resized to %ld", (long) newlen)); + + p_new = (duk_uint8_t *) duk_resize_buffer(enc_ctx->thr, enc_ctx->idx_buf, newlen); + DUK_ASSERT(p_new != NULL); + old_data_len = (duk_size_t) (enc_ctx->ptr - enc_ctx->buf); + enc_ctx->buf = p_new; + enc_ctx->buf_end = p_new + newlen; + enc_ctx->ptr = p_new + old_data_len; + enc_ctx->len = newlen; +} + +DUK_LOCAL DUK_INLINE void duk__cbor_encode_ensure(duk_cbor_encode_context *enc_ctx, duk_size_t len) { + if (DUK_LIKELY((duk_size_t) (enc_ctx->buf_end - enc_ctx->ptr) >= len)) { + return; + } + duk__cbor_encode_ensure_slowpath(enc_ctx, len); +} + +DUK_LOCAL duk_size_t duk__cbor_get_reserve(duk_cbor_encode_context *enc_ctx) { + DUK_ASSERT(enc_ctx->ptr >= enc_ctx->buf); + DUK_ASSERT(enc_ctx->ptr <= enc_ctx->buf_end); + return (duk_size_t) (enc_ctx->buf_end - enc_ctx->ptr); +} + +DUK_LOCAL void duk__cbor_encode_uint32(duk_cbor_encode_context *enc_ctx, duk_uint32_t u, duk_uint8_t base) { + duk_uint8_t *p; + + /* Caller must ensure space. */ + DUK_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 4); + + p = enc_ctx->ptr; + if (DUK_LIKELY(u <= 23U)) { + *p++ = (duk_uint8_t) (base + (duk_uint8_t) u); + } else if (u <= 0xffUL) { + *p++ = base + 0x18U; + *p++ = (duk_uint8_t) u; + } else if (u <= 0xffffUL) { + *p++ = base + 0x19U; + DUK_RAW_WRITEINC_U16_BE(p, (duk_uint16_t) u); + } else { + *p++ = base + 0x1aU; + DUK_RAW_WRITEINC_U32_BE(p, u); + } + enc_ctx->ptr = p; +} + +#if defined(DUK_CBOR_DOUBLE_AS_IS) +DUK_LOCAL void duk__cbor_encode_double(duk_cbor_encode_context *enc_ctx, double d) { + duk_uint8_t *p; + + /* Caller must ensure space. */ + DUK_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 8); + + p = enc_ctx->ptr; + *p++ = 0xfbU; + DUK_RAW_WRITEINC_DOUBLE_BE(p, d); + p += 8; + enc_ctx->ptr = p; +} +#else /* DUK_CBOR_DOUBLE_AS_IS */ +DUK_LOCAL void duk__cbor_encode_double_fp(duk_cbor_encode_context *enc_ctx, double d) { + duk_double_union u; + duk_uint16_t u16; + duk_int16_t expt; + duk_uint8_t *p; + + DUK_ASSERT(DUK_FPCLASSIFY(d) != DUK_FP_ZERO); + + /* Caller must ensure space. */ + DUK_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 8); + + /* Organize into little endian (no-op if platform is little endian). */ + u.d = d; + duk_dblunion_host_to_little(&u); + + /* Check if 'd' can represented as a normal half-float. + * Denormal half-floats could also be used, but that check + * isn't done now (denormal half-floats are decoded of course). + * So just check exponent range and that at most 10 significant + * bits (excluding implicit leading 1) are used in 'd'. + */ + u16 = (((duk_uint16_t) u.uc[7]) << 8) | ((duk_uint16_t) u.uc[6]); + expt = (duk_int16_t) ((u16 & 0x7ff0U) >> 4) - 1023; + + if (expt >= -14 && expt <= 15) { + /* Half-float normal exponents (excl. denormals). + * + * 7 6 5 4 3 2 1 0 (LE index) + * double: seeeeeee eeeemmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm + * half: seeeee mmmm mmmmmm00 00000000 00000000 00000000 00000000 00000000 + */ + duk_bool_t use_half_float; + + use_half_float = + (u.uc[0] == 0 && u.uc[1] == 0 && u.uc[2] == 0 && u.uc[3] == 0 && + u.uc[4] == 0 && (u.uc[5] & 0x03U) == 0); + + if (use_half_float) { + duk_uint32_t t; + + expt += 15; + t = (duk_uint32_t) (u.uc[7] & 0x80U) << 8; + t += (duk_uint32_t) expt << 10; + t += ((duk_uint32_t) u.uc[6] & 0x0fU) << 6; + t += ((duk_uint32_t) u.uc[5]) >> 2; + + /* seeeeemm mmmmmmmm */ + p = enc_ctx->ptr; + *p++ = 0xf9U; + DUK_RAW_WRITEINC_U16_BE(p, (duk_uint16_t) t); + enc_ctx->ptr = p; + return; + } + } + + /* Same check for plain float. Also no denormal support here. */ + if (expt >= -126 && expt <= 127) { + /* Float normal exponents (excl. denormals). + * + * double: seeeeeee eeeemmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm + * float: seeee eeeemmmm mmmmmmmm mmmmmmmm mmm00000 00000000 00000000 00000000 + */ + duk_bool_t use_float; + duk_float_t d_float; + + /* We could do this explicit mantissa check, but doing + * a double-float-double cast is fine because we've + * already verified that the exponent is in range so + * that the narrower cast is not undefined behavior. + */ +#if 0 + use_float = + (u.uc[0] == 0 && u.uc[1] == 0 && u.uc[2] == 0 && (u.uc[3] & 0xe0U) == 0); +#endif + d_float = (duk_float_t) d; + use_float = duk_double_equals((duk_double_t) d_float, d); + if (use_float) { + p = enc_ctx->ptr; + *p++ = 0xfaU; + DUK_RAW_WRITEINC_FLOAT_BE(p, d_float); + enc_ctx->ptr = p; + return; + } + } + + /* Special handling for NaN and Inf which we want to encode as + * half-floats. They share the same (maximum) exponent. + */ + if (expt == 1024) { + DUK_ASSERT(DUK_ISNAN(d) || DUK_ISINF(d)); + p = enc_ctx->ptr; + *p++ = 0xf9U; + if (DUK_ISNAN(d)) { + /* Shortest NaN encoding is using a half-float. Lose the + * exact NaN bits in the process. IEEE double would be + * 7ff8 0000 0000 0000, i.e. a quiet NaN in most architectures + * (https://en.wikipedia.org/wiki/NaN#Encoding). The + * equivalent half float is 7e00. + */ + *p++ = 0x7eU; + } else { + /* Shortest +/- Infinity encoding is using a half-float. */ + if (DUK_SIGNBIT(d)) { + *p++ = 0xfcU; + } else { + *p++ = 0x7cU; + } + } + *p++ = 0x00U; + enc_ctx->ptr = p; + return; + } + + /* Cannot use half-float or float, encode as full IEEE double. */ + p = enc_ctx->ptr; + *p++ = 0xfbU; + DUK_RAW_WRITEINC_DOUBLE_BE(p, d); + enc_ctx->ptr = p; +} + +DUK_LOCAL void duk__cbor_encode_double(duk_cbor_encode_context *enc_ctx, double d) { + duk_uint8_t *p; + double d_floor; + + /* Integers and floating point values of all types are conceptually + * equivalent in CBOR. Try to always choose the shortest encoding + * which is not always immediately obvious. For example, NaN and Inf + * can be most compactly represented as a half-float (assuming NaN + * bits are not preserved), and 0x1'0000'0000 as a single precision + * float. Shortest forms in preference order (prefer integer over + * float when equal length): + * + * uint 1 byte [0,23] (not -0) + * sint 1 byte [-24,-1] + * uint+1 2 bytes [24,255] + * sint+1 2 bytes [-256,-25] + * uint+2 3 bytes [256,65535] + * sint+2 3 bytes [-65536,-257] + * half-float 3 bytes -0, NaN, +/- Infinity, range [-65504,65504] + * uint+4 5 bytes [65536,4294967295] + * sint+4 5 bytes [-4294967296,-258] + * float 5 bytes range [-(1 - 2^(-24)) * 2^128, (1 - 2^(-24)) * 2^128] + * uint+8 9 bytes [4294967296,18446744073709551615] + * sint+8 9 bytes [-18446744073709551616,-4294967297] + * double 9 bytes + * + * For whole numbers (compatible with integers): + * - 1-byte or 2-byte uint/sint representation is preferred for + * [-256,255]. + * - 3-byte uint/sint is preferred for [-65536,65535]. Half floats + * are never preferred because they have the same length. + * - 5-byte uint/sint is preferred for [-4294967296,4294967295]. + * Single precision floats are never preferred, and half-floats + * don't reach above the 3-byte uint/sint range so they're never + * preferred. + * - So, for all integers up to signed/unsigned 32-bit range the + * preferred encoding is always an integer uint/sint. + * - For integers above 32 bits the situation is more complicated. + * Half-floats are never useful for them because of their limited + * range, but IEEE single precision floats (5 bytes encoded) can + * represent some integers between the 32-bit and 64-bit ranges + * which require 9 bytes as a uint/sint. + * + * For floating point values not compatible with integers, the + * preferred encoding is quite clear: + * - For +Inf/-Inf use half-float. + * - For NaN use a half-float, assuming NaN bits ("payload") is + * not worth preserving. Duktape doesn't in general guarantee + * preservation of the NaN payload so using a half-float seems + * consistent with that. + * - For remaining values, prefer the shortest form which doesn't + * lose any precision. For normal half-floats and single precision + * floats this is simple: just check exponent and mantissa bits + * using a fixed mask. For denormal half-floats and single + * precision floats the check is a bit more complicated: a normal + * IEEE double can sometimes be represented as a denormal + * half-float or single precision float. + * + * https://en.wikipedia.org/wiki/Half-precision_floating-point_format#IEEE_754_half-precision_binary_floating-point_format:_binary16 + */ + + /* Caller must ensure space. */ + DUK_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 8); + + /* Most important path is integers. The floor() test will be true + * for Inf too (but not NaN). + */ + d_floor = DUK_FLOOR(d); /* identity if d is +/- 0.0, NaN, or +/- Infinity */ + if (DUK_LIKELY(duk_double_equals(d_floor, d) != 0)) { + DUK_ASSERT(!DUK_ISNAN(d)); /* NaN == NaN compares false. */ + if (DUK_SIGNBIT(d)) { + if (d >= -4294967296.0) { + d = -1.0 - d; + if (d >= 0.0) { + DUK_ASSERT(d >= 0.0); + duk__cbor_encode_uint32(enc_ctx, duk__cbor_double_to_uint32(d), 0x20U); + return; + } + + /* Input was negative zero, d == -1.0 < 0.0. + * Shortest -0 is using half-float. + */ + p = enc_ctx->ptr; + *p++ = 0xf9U; + *p++ = 0x80U; + *p++ = 0x00U; + enc_ctx->ptr = p; + return; + } + } else { + if (d <= 4294967295.0) { + /* Positive zero needs no special handling. */ + DUK_ASSERT(d >= 0.0); + duk__cbor_encode_uint32(enc_ctx, duk__cbor_double_to_uint32(d), 0x00U); + return; + } + } + } + + /* 64-bit integers are not supported at present. So + * we also don't need to deal with choosing between a + * 64-bit uint/sint representation vs. IEEE double or + * float. + */ + + DUK_ASSERT(DUK_FPCLASSIFY(d) != DUK_FP_ZERO); + duk__cbor_encode_double_fp(enc_ctx, d); +} +#endif /* DUK_CBOR_DOUBLE_AS_IS */ + +DUK_LOCAL void duk__cbor_encode_string_top(duk_cbor_encode_context *enc_ctx) { + const duk_uint8_t *str; + duk_size_t len; + duk_uint8_t *p; + + /* CBOR differentiates between UTF-8 text strings and byte strings. + * Text strings MUST be valid UTF-8, so not all Duktape strings can + * be encoded as valid CBOR text strings. Possible behaviors: + * + * 1. Use text string when input is valid UTF-8, otherwise use + * byte string (maybe tagged to indicate it was an extended + * UTF-8 string). + * 2. Always use text strings, but sanitize input string so that + * invalid UTF-8 is replaced with U+FFFD for example. Combine + * surrogates whenever possible. + * 3. Always use byte strings. This is simple and produces valid + * CBOR, but isn't ideal for interoperability. + * 4. Always use text strings, even for invalid UTF-8 such as + * codepoints in the surrogate pair range. This is simple but + * produces technically invalid CBOR for non-UTF-8 strings which + * may affect interoperability. + * + * Current default is 1; can be changed with defines. + */ + + /* Caller must ensure space. */ + DUK_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 8); + + str = (const duk_uint8_t *) duk_require_lstring(enc_ctx->thr, -1, &len); + if (duk_is_symbol(enc_ctx->thr, -1)) { + /* Symbols, encode as an empty table for now. This matches + * the behavior of cbor-js. + * + * XXX: Maybe encode String() coercion with a tag? + * XXX: Option to keep enough information to recover + * Symbols when decoding (this is not always desirable). + */ + p = enc_ctx->ptr; + *p++ = 0xa0U; + enc_ctx->ptr = p; + return; + } + + duk__cbor_encode_sizet_uint32_check(enc_ctx, len); +#if defined(DUK_CBOR_TEXT_STRINGS) + duk__cbor_encode_uint32(enc_ctx, (duk_uint32_t) len, 0x60U); +#elif defined(DUK_CBOR_BYTE_STRINGS) + duk__cbor_encode_uint32(enc_ctx, (duk_uint32_t) len, 0x40U); +#else + duk__cbor_encode_uint32(enc_ctx, (duk_uint32_t) len, + (DUK_LIKELY(duk_unicode_is_utf8_compatible(str, len) != 0) ? 0x60U : 0x40U)); +#endif + duk__cbor_encode_ensure(enc_ctx, len); + p = enc_ctx->ptr; + duk_memcpy((void *) p, (const void *) str, len); + p += len; + enc_ctx->ptr = p; +} + +DUK_LOCAL void duk__cbor_encode_object(duk_cbor_encode_context *enc_ctx) { + duk_uint8_t *buf; + duk_size_t len; + duk_uint8_t *p; + duk_size_t i; + duk_size_t off_ib; + duk_uint32_t count; + + /* Caller must ensure space. */ + DUK_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 8); + + /* XXX: Support for specific built-ins like Date and RegExp. */ + if (duk_is_array(enc_ctx->thr, -1)) { + /* Shortest encoding for arrays >= 256 in length is actually + * the indefinite length one (3 or more bytes vs. 2 bytes). + * We still use the definite length version because it is + * more decoding friendly. + */ + len = duk_get_length(enc_ctx->thr, -1); + duk__cbor_encode_sizet_uint32_check(enc_ctx, len); + duk__cbor_encode_uint32(enc_ctx, (duk_uint32_t) len, 0x80U); + for (i = 0; i < len; i++) { + duk_get_prop_index(enc_ctx->thr, -1, (duk_uarridx_t) i); + duk__cbor_encode_value(enc_ctx); + } + } else if (duk_is_buffer_data(enc_ctx->thr, -1)) { + /* XXX: Tag buffer data? + * XXX: Encode typed arrays as integer arrays rather + * than buffer data as is? + */ + buf = (duk_uint8_t *) duk_require_buffer_data(enc_ctx->thr, -1, &len); + duk__cbor_encode_sizet_uint32_check(enc_ctx, len); + duk__cbor_encode_uint32(enc_ctx, (duk_uint32_t) len, 0x40U); + duk__cbor_encode_ensure(enc_ctx, len); + p = enc_ctx->ptr; + duk_memcpy((void *) p, (const void *) buf, len); + p += len; + enc_ctx->ptr = p; + } else { + /* We don't know the number of properties in advance + * but would still like to encode at least small + * objects without indefinite length. Emit an + * indefinite length byte initially, and if the final + * property count is small enough to also fit in one + * byte, backpatch it later. Otherwise keep the + * indefinite length. This works well up to 23 + * properties which is practical and good enough. + */ + off_ib = (duk_size_t) (enc_ctx->ptr - enc_ctx->buf); /* XXX: get_offset? */ + count = 0U; + p = enc_ctx->ptr; + *p++ = 0xa0U + 0x1fU; /* indefinite length */ + enc_ctx->ptr = p; + duk_enum(enc_ctx->thr, -1, DUK_ENUM_OWN_PROPERTIES_ONLY); + while (duk_next(enc_ctx->thr, -1, 1 /*get_value*/)) { + duk_insert(enc_ctx->thr, -2); /* [ ... key value ] -> [ ... value key ] */ + duk__cbor_encode_value(enc_ctx); + duk__cbor_encode_value(enc_ctx); + count++; + if (count == 0U) { + duk__cbor_encode_error(enc_ctx); + } + } + duk_pop(enc_ctx->thr); + if (count <= 0x17U) { + DUK_ASSERT(off_ib < enc_ctx->len); + enc_ctx->buf[off_ib] = 0xa0U + (duk_uint8_t) count; + } else { + duk__cbor_encode_ensure(enc_ctx, 1); + p = enc_ctx->ptr; + *p++ = 0xffU; /* break */ + enc_ctx->ptr = p; + } + } +} + +DUK_LOCAL void duk__cbor_encode_buffer(duk_cbor_encode_context *enc_ctx) { + duk_uint8_t *buf; + duk_size_t len; + duk_uint8_t *p; + + /* Caller must ensure space. */ + DUK_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 8); + + /* Tag buffer data? */ + buf = (duk_uint8_t *) duk_require_buffer(enc_ctx->thr, -1, &len); + duk__cbor_encode_sizet_uint32_check(enc_ctx, len); + duk__cbor_encode_uint32(enc_ctx, (duk_uint32_t) len, 0x40U); + duk__cbor_encode_ensure(enc_ctx, len); + p = enc_ctx->ptr; + duk_memcpy((void *) p, (const void *) buf, len); + p += len; + enc_ctx->ptr = p; +} + +DUK_LOCAL void duk__cbor_encode_pointer(duk_cbor_encode_context *enc_ctx) { + /* Pointers (void *) are challenging to encode. They can't + * be relied to be even 64-bit integer compatible (there are + * pointer models larger than that), nor can floats encode + * them. They could be encoded as strings (%p format) but + * that's not portable. They could be encoded as direct memory + * representations. Recovering pointers is non-portable in any + * case but it would be nice to be able to detect and recover + * compatible pointers. + * + * For now, encode as "(%p)" string, matching JX. There doesn't + * seem to be an appropriate tag, so pointers don't currently + * survive a CBOR encode/decode roundtrip intact. + */ + const char *ptr; + + ptr = duk_to_string(enc_ctx->thr, -1); + DUK_ASSERT(ptr != NULL); + duk_push_sprintf(enc_ctx->thr, "(%s)", ptr); + duk_remove(enc_ctx->thr, -2); + duk__cbor_encode_string_top(enc_ctx); +} + +DUK_LOCAL void duk__cbor_encode_lightfunc(duk_cbor_encode_context *enc_ctx) { + duk_uint8_t *p; + + /* Caller must ensure space. */ + DUK_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 8); + + /* For now encode as an empty object. */ + p = enc_ctx->ptr; + *p++ = 0xa0U; + enc_ctx->ptr = p; +} + +DUK_LOCAL void duk__cbor_encode_value(duk_cbor_encode_context *enc_ctx) { + duk_uint8_t *p; + + /* Encode/decode cycle currently loses some type information. + * This can be improved by registering custom tags with IANA. + */ + + /* When working with deeply recursive structures, this is important + * to ensure there's no effective depth limit. + */ + duk_require_stack(enc_ctx->thr, 4); + + /* Reserve space for up to 64-bit types (1 initial byte + 8 + * followup bytes). This allows encoding of integers, floats, + * string/buffer length fields, etc without separate checks + * in each code path. + */ + duk__cbor_encode_ensure(enc_ctx, 1 + 8); + + switch (duk_get_type(enc_ctx->thr, -1)) { + case DUK_TYPE_UNDEFINED: { + p = enc_ctx->ptr; + *p++ = 0xf7; + enc_ctx->ptr = p; + break; + } + case DUK_TYPE_NULL: { + p = enc_ctx->ptr; + *p++ = 0xf6; + enc_ctx->ptr = p; + break; + } + case DUK_TYPE_BOOLEAN: { + duk_uint8_t u8 = duk_get_boolean(enc_ctx->thr, -1) ? 0xf5U : 0xf4U; + p = enc_ctx->ptr; + *p++ = u8; + enc_ctx->ptr = p; + break; + } + case DUK_TYPE_NUMBER: { + duk__cbor_encode_double(enc_ctx, duk_get_number(enc_ctx->thr, -1)); + break; + } + case DUK_TYPE_STRING: { + duk__cbor_encode_string_top(enc_ctx); + break; + } + case DUK_TYPE_OBJECT: { + duk__cbor_encode_object(enc_ctx); + break; + } + case DUK_TYPE_BUFFER: { + duk__cbor_encode_buffer(enc_ctx); + break; + } + case DUK_TYPE_POINTER: { + duk__cbor_encode_pointer(enc_ctx); + break; + } + case DUK_TYPE_LIGHTFUNC: { + duk__cbor_encode_lightfunc(enc_ctx); + break; + } + case DUK_TYPE_NONE: + default: + goto fail; + } + + duk_pop(enc_ctx->thr); + return; + + fail: + duk__cbor_encode_error(enc_ctx); +} + +/* + * Decoding + */ + +DUK_LOCAL void duk__cbor_req_stack(duk_cbor_decode_context *dec_ctx) { + duk_require_stack(dec_ctx->thr, 4); +} + +DUK_LOCAL void duk__cbor_decode_error(duk_cbor_decode_context *dec_ctx) { + (void) duk_type_error(dec_ctx->thr, "cbor decode error"); +} + +DUK_LOCAL duk_uint8_t duk__cbor_decode_readbyte(duk_cbor_decode_context *dec_ctx) { + DUK_ASSERT(dec_ctx->off <= dec_ctx->len); + if (DUK_UNLIKELY(dec_ctx->len - dec_ctx->off < 1U)) { + duk__cbor_decode_error(dec_ctx); + } + return dec_ctx->buf[dec_ctx->off++]; +} + +DUK_LOCAL duk_uint16_t duk__cbor_decode_read_u16(duk_cbor_decode_context *dec_ctx) { + duk_uint16_t res; + + DUK_ASSERT(dec_ctx->off <= dec_ctx->len); + if (DUK_UNLIKELY(dec_ctx->len - dec_ctx->off < 2U)) { + duk__cbor_decode_error(dec_ctx); + } + res = DUK_RAW_READ_U16_BE(dec_ctx->buf + dec_ctx->off); + dec_ctx->off += 2; + return res; +} + +DUK_LOCAL duk_uint32_t duk__cbor_decode_read_u32(duk_cbor_decode_context *dec_ctx) { + duk_uint32_t res; + + DUK_ASSERT(dec_ctx->off <= dec_ctx->len); + if (DUK_UNLIKELY(dec_ctx->len - dec_ctx->off < 4U)) { + duk__cbor_decode_error(dec_ctx); + } + res = DUK_RAW_READ_U32_BE(dec_ctx->buf + dec_ctx->off); + dec_ctx->off += 4; + return res; +} + +DUK_LOCAL duk_uint8_t duk__cbor_decode_peekbyte(duk_cbor_decode_context *dec_ctx) { + if (DUK_UNLIKELY(dec_ctx->off >= dec_ctx->len)) { + duk__cbor_decode_error(dec_ctx); + } + return dec_ctx->buf[dec_ctx->off]; +} + +DUK_LOCAL void duk__cbor_decode_rewind(duk_cbor_decode_context *dec_ctx, duk_size_t len) { + DUK_ASSERT(len <= dec_ctx->off); /* Caller must ensure. */ + dec_ctx->off -= len; +} + +#if 0 +DUK_LOCAL void duk__cbor_decode_ensure(duk_cbor_decode_context *dec_ctx, duk_size_t len) { + if (dec_ctx->off + len > dec_ctx->len) { + duk__cbor_decode_error(dec_ctx); + } +} +#endif + +DUK_LOCAL const duk_uint8_t *duk__cbor_decode_consume(duk_cbor_decode_context *dec_ctx, duk_size_t len) { + DUK_ASSERT(dec_ctx->off <= dec_ctx->len); + if (DUK_LIKELY(dec_ctx->len - dec_ctx->off >= len)) { + const duk_uint8_t *res = dec_ctx->buf + dec_ctx->off; + dec_ctx->off += len; + return res; + } + + duk__cbor_decode_error(dec_ctx); /* Not enough input. */ + return NULL; +} + +DUK_LOCAL int duk__cbor_decode_checkbreak(duk_cbor_decode_context *dec_ctx) { + if (duk__cbor_decode_peekbyte(dec_ctx) == 0xffU) { + DUK_ASSERT(dec_ctx->off < dec_ctx->len); + dec_ctx->off++; +#if 0 + (void) duk__cbor_decode_readbyte(dec_ctx); +#endif + return 1; + } + return 0; +} + +DUK_LOCAL void duk__cbor_decode_push_aival_int(duk_cbor_decode_context *dec_ctx, duk_uint8_t ib, duk_bool_t negative) { + duk_uint8_t ai; + duk_uint32_t t, t1, t2; +#if 0 + duk_uint64_t t3; +#endif + duk_double_t d1, d2; + duk_double_t d; + + ai = ib & 0x1fU; + if (ai <= 0x17U) { + t = ai; + goto shared_exit; + } + + switch (ai) { + case 0x18U: /* 1 byte */ + t = (duk_uint32_t) duk__cbor_decode_readbyte(dec_ctx); + goto shared_exit; + case 0x19U: /* 2 byte */ + t = (duk_uint32_t) duk__cbor_decode_read_u16(dec_ctx); + goto shared_exit; + case 0x1aU: /* 4 byte */ + t = (duk_uint32_t) duk__cbor_decode_read_u32(dec_ctx); + goto shared_exit; + case 0x1bU: /* 8 byte */ + /* For uint64 it's important to handle the -1.0 part before + * casting to double: otherwise the adjustment might be lost + * in the cast. Uses: -1.0 - d <=> -(d + 1.0). + */ + t = (duk_uint32_t) duk__cbor_decode_read_u32(dec_ctx); + t2 = t; + t = (duk_uint32_t) duk__cbor_decode_read_u32(dec_ctx); + t1 = t; +#if 0 + t3 = (duk_uint64_t) t2 * DUK_U64_CONSTANT(0x100000000) + (duk_uint64_t) t1; + if (negative) { + if (t3 == DUK_UINT64_MAX) { + /* -(0xffff'ffff'ffff'ffffULL + 1) = + * -0x1'0000'0000'0000'0000 + * + * >>> -0x10000000000000000 + * -18446744073709551616L + */ + return -18446744073709551616.0; + } else { + return -((duk_double_t) (t3 + DUK_U64_CONSTANT(1))); + } + } else { + return (duk_double_t) t3; /* XXX: cast helper */ + } +#endif +#if 0 + t3 = (duk_uint64_t) t2 * DUK_U64_CONSTANT(0x100000000) + (duk_uint64_t) t1; + if (negative) { + /* Simpler version: take advantage of the fact that + * 0xffff'ffff'ffff'ffff and 0x1'0000'0000'0000'0000 + * both round to 0x1'0000'0000'0000'0000: + * > (0xffffffffffffffff).toString(16) + * '10000000000000000' + * > (0x10000000000000000).toString(16) + * '10000000000000000' + * + * For the DUK_UINT64_MAX case we just skip the +1 + * increment to avoid wrapping; the result still + * comes out right for an IEEE double cast. + */ + if (t3 != DUK_UINT64_MAX) { + t3++; + } + return -((duk_double_t) t3); + } else { + return (duk_double_t) t3; /* XXX: cast helper */ + } +#endif +#if 1 + /* Use two double parts, avoids dependency on 64-bit type. + * Avoid precision loss carefully, especially when dealing + * with the required +1 for negative values. + * + * No fastint check for this path at present. + */ + d1 = (duk_double_t) t1; /* XXX: cast helpers */ + d2 = (duk_double_t) t2 * 4294967296.0; + if (negative) { + d1 += 1.0; + } + d = d2 + d1; + if (negative) { + d = -d; + } +#endif + /* XXX: a push and check for fastint API would be nice */ + duk_push_number(dec_ctx->thr, d); + return; + } + + duk__cbor_decode_error(dec_ctx); + return; + + shared_exit: + if (negative) { + /* XXX: a push and check for fastint API would be nice */ + if ((duk_uint_t) t <= (duk_uint_t) -(DUK_INT_MIN + 1)) { + duk_push_int(dec_ctx->thr, -1 - ((duk_int_t) t)); + } else { + duk_push_number(dec_ctx->thr, -1.0 - (duk_double_t) t); + } + } else { + duk_push_uint(dec_ctx->thr, (duk_uint_t) t); + } +} + +DUK_LOCAL void duk__cbor_decode_skip_aival_int(duk_cbor_decode_context *dec_ctx, duk_uint8_t ib) { + const duk_int8_t skips[32] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 8, -1, -1, -1, -1 + }; + duk_uint8_t ai; + duk_int8_t skip; + + ai = ib & 0x1fU; + skip = skips[ai]; + if (DUK_UNLIKELY(skip < 0)) { + duk__cbor_decode_error(dec_ctx); + } + duk__cbor_decode_consume(dec_ctx, (duk_size_t) skip); + return; +} + +DUK_LOCAL duk_uint32_t duk__cbor_decode_aival_uint32(duk_cbor_decode_context *dec_ctx, duk_uint8_t ib) { + duk_uint8_t ai; + duk_uint32_t t; + + ai = ib & 0x1fU; + if (ai <= 0x17U) { + return (duk_uint32_t) ai; + } + + switch (ai) { + case 0x18U: /* 1 byte */ + t = (duk_uint32_t) duk__cbor_decode_readbyte(dec_ctx); + return t; + case 0x19U: /* 2 byte */ + t = (duk_uint32_t) duk__cbor_decode_read_u16(dec_ctx); + return t; + case 0x1aU: /* 4 byte */ + t = (duk_uint32_t) duk__cbor_decode_read_u32(dec_ctx); + return t; + case 0x1bU: /* 8 byte */ + t = (duk_uint32_t) duk__cbor_decode_read_u32(dec_ctx); + if (t != 0U) { + break; + } + t = (duk_uint32_t) duk__cbor_decode_read_u32(dec_ctx); + return t; + } + + duk__cbor_decode_error(dec_ctx); + return 0U; +} + +DUK_LOCAL void duk__cbor_decode_buffer(duk_cbor_decode_context *dec_ctx, duk_uint8_t expected_base) { + duk_uint32_t len; + duk_uint8_t *buf; + const duk_uint8_t *inp; + duk_uint8_t ib; + + ib = duk__cbor_decode_readbyte(dec_ctx); + if ((ib & 0xe0U) != expected_base) { + duk__cbor_decode_error(dec_ctx); + } + /* Indefinite format is rejected by the following on purpose. */ + len = duk__cbor_decode_aival_uint32(dec_ctx, ib); + inp = duk__cbor_decode_consume(dec_ctx, len); + /* XXX: duk_push_fixed_buffer_with_data() would be a nice API addition. */ + buf = (duk_uint8_t *) duk_push_fixed_buffer(dec_ctx->thr, (duk_size_t) len); + duk_memcpy((void *) buf, (const void *) inp, (size_t) len); +} + +DUK_LOCAL void duk__cbor_decode_join_buffers(duk_cbor_decode_context *dec_ctx, duk_idx_t count) { + duk_size_t total_size = 0; + duk_idx_t top = duk_get_top(dec_ctx->thr); + duk_idx_t base = top - count; /* count is >= 1 */ + duk_idx_t idx; + duk_uint8_t *p = NULL; + + DUK_ASSERT(count >= 1); + DUK_ASSERT(top >= count); + + for (;;) { + /* First round: compute total size. + * Second round: copy into place. + */ + for (idx = base; idx < top; idx++) { + duk_uint8_t *buf_data; + duk_size_t buf_size; + + buf_data = (duk_uint8_t *) duk_require_buffer(dec_ctx->thr, idx, &buf_size); + if (p != NULL) { + if (buf_size > 0U) { + duk_memcpy((void *) p, (const void *) buf_data, buf_size); + } + p += buf_size; + } else { + total_size += buf_size; + if (DUK_UNLIKELY(total_size < buf_size)) { /* Wrap check. */ + duk__cbor_decode_error(dec_ctx); + } + } + } + + if (p != NULL) { + break; + } else { + p = (duk_uint8_t *) duk_push_fixed_buffer(dec_ctx->thr, total_size); + DUK_ASSERT(p != NULL); + } + } + + duk_replace(dec_ctx->thr, base); + duk_pop_n(dec_ctx->thr, count - 1); +} + +DUK_LOCAL void duk__cbor_decode_and_join_strbuf(duk_cbor_decode_context *dec_ctx, duk_uint8_t expected_base) { + duk_idx_t count = 0; + for (;;) { + if (duk__cbor_decode_checkbreak(dec_ctx)) { + break; + } + duk_require_stack(dec_ctx->thr, 1); + duk__cbor_decode_buffer(dec_ctx, expected_base); + count++; + if (DUK_UNLIKELY(count <= 0)) { /* Wrap check. */ + duk__cbor_decode_error(dec_ctx); + } + } + if (count == 0) { + (void) duk_push_fixed_buffer(dec_ctx->thr, 0); + } else if (count > 1) { + duk__cbor_decode_join_buffers(dec_ctx, count); + } +} + +DUK_LOCAL duk_double_t duk__cbor_decode_half_float(duk_cbor_decode_context *dec_ctx) { + duk_double_union u; + const duk_uint8_t *inp; + duk_int_t expt; + duk_uint_t u16; + duk_uint_t tmp; + duk_double_t res; + + inp = duk__cbor_decode_consume(dec_ctx, 2); + u16 = ((duk_uint_t) inp[0] << 8) + (duk_uint_t) inp[1]; + expt = (duk_int_t) ((u16 >> 10) & 0x1fU) - 15; + + /* Reconstruct IEEE double into little endian order first, then convert + * to host order. + */ + + duk_memzero((void *) &u, sizeof(u)); + + if (expt == -15) { + /* Zero or denormal; but note that half float + * denormals become double normals. + */ + if ((u16 & 0x03ffU) == 0) { + u.uc[7] = inp[0] & 0x80U; + } else { + /* Create denormal by first creating a double that + * contains the denormal bits and a leading implicit + * 1-bit. Then subtract away the implicit 1-bit. + * + * 0.mmmmmmmmmm * 2^-14 + * 1.mmmmmmmmmm 0.... * 2^-14 + * -1.0000000000 0.... * 2^-14 + * + * Double exponent: -14 + 1023 = 0x3f1 + */ + u.uc[7] = 0x3fU; + u.uc[6] = 0x10U + (duk_uint8_t) ((u16 >> 6) & 0x0fU); + u.uc[5] = (duk_uint8_t) ((u16 << 2) & 0xffU); /* Mask is really 0xfcU */ + + duk_dblunion_little_to_host(&u); + res = u.d - 0.00006103515625; /* 2^(-14) */ + if (u16 & 0x8000U) { + res = -res; + } + return res; + } + } else if (expt == 16) { + /* +/- Inf or NaN. */ + if ((u16 & 0x03ffU) == 0) { + u.uc[7] = (inp[0] & 0x80U) + 0x7fU; + u.uc[6] = 0xf0U; + } else { + /* Create a 'quiet NaN' with highest + * bit set (there are some platforms + * where the NaN payload convention is + * the opposite). Keep sign. + */ + u.uc[7] = (inp[0] & 0x80U) + 0x7fU; + u.uc[6] = 0xf8U; + } + } else { + /* Normal. */ + tmp = (inp[0] & 0x80U) ? 0x80000000UL : 0UL; + tmp += (duk_uint_t) (expt + 1023) << 20; + tmp += (duk_uint_t) (inp[0] & 0x03U) << 18; + tmp += (duk_uint_t) (inp[1] & 0xffU) << 10; + u.uc[7] = (tmp >> 24) & 0xffU; + u.uc[6] = (tmp >> 16) & 0xffU; + u.uc[5] = (tmp >> 8) & 0xffU; + u.uc[4] = (tmp >> 0) & 0xffU; + } + + duk_dblunion_little_to_host(&u); + return u.d; +} + +DUK_LOCAL void duk__cbor_decode_string(duk_cbor_decode_context *dec_ctx, duk_uint8_t ib, duk_uint8_t ai) { + /* If the CBOR string data is not valid UTF-8 it is technically + * invalid CBOR. Possible behaviors at least: + * + * 1. Reject the input, i.e. throw TypeError. + * + * 2. Accept the input, but sanitize non-UTF-8 data into UTF-8 + * using U+FFFD replacements. Also it might make sense to + * decode non-BMP codepoints into surrogates for better + * ECMAScript compatibility. + * + * 3. Accept the input as a Duktape string (which are not always + * valid UTF-8), but reject any input that would create a + * Symbol representation. + * + * Current behavior is 3. + */ + + if (ai == 0x1fU) { + duk_uint8_t *buf_data; + duk_size_t buf_size; + + duk__cbor_decode_and_join_strbuf(dec_ctx, 0x60U); + buf_data = (duk_uint8_t *) duk_require_buffer(dec_ctx->thr, -1, &buf_size); + (void) duk_push_lstring(dec_ctx->thr, (const char *) buf_data, buf_size); + duk_remove(dec_ctx->thr, -2); + } else { + duk_uint32_t len; + const duk_uint8_t *inp; + + len = duk__cbor_decode_aival_uint32(dec_ctx, ib); + inp = duk__cbor_decode_consume(dec_ctx, len); + (void) duk_push_lstring(dec_ctx->thr, (const char *) inp, (duk_size_t) len); + } + if (duk_is_symbol(dec_ctx->thr, -1)) { + /* Refuse to create Symbols when decoding. */ + duk__cbor_decode_error(dec_ctx); + } + + /* XXX: Here a Duktape API call to convert input -> utf-8 with + * replacements would be nice. + */ +} + +DUK_LOCAL duk_bool_t duk__cbor_decode_array(duk_cbor_decode_context *dec_ctx, duk_uint8_t ib, duk_uint8_t ai) { + duk_uint32_t idx, len; + + duk__cbor_req_stack(dec_ctx); + + /* Support arrays up to 0xfffffffeU in length. 0xffffffff is + * used as an indefinite length marker. + */ + if (ai == 0x1fU) { + len = 0xffffffffUL; + } else { + len = duk__cbor_decode_aival_uint32(dec_ctx, ib); + if (len == 0xffffffffUL) { + return 0; + } + } + + /* XXX: use bare array? */ + duk_push_array(dec_ctx->thr); + for (idx = 0U; ;) { + if (len == 0xffffffffUL && duk__cbor_decode_checkbreak(dec_ctx)) { + break; + } + if (idx == len) { + if (ai == 0x1fU) { + return 0; + } + break; + } + duk__cbor_decode_value(dec_ctx); + duk_put_prop_index(dec_ctx->thr, -2, (duk_uarridx_t) idx); + idx++; + if (idx == 0U) { + return 0; /* wrapped */ + } + } + + return 1; +} + +DUK_LOCAL duk_bool_t duk__cbor_decode_map(duk_cbor_decode_context *dec_ctx, duk_uint8_t ib, duk_uint8_t ai) { + duk_uint32_t count; + + duk__cbor_req_stack(dec_ctx); + + if (ai == 0x1fU) { + count = 0xffffffffUL; + } else { + count = duk__cbor_decode_aival_uint32(dec_ctx, ib); + if (count == 0xffffffffUL) { + return 0; + } + } + + /* XXX: use bare object? */ + duk_push_object(dec_ctx->thr); + for (;;) { + if (count == 0xffffffffUL) { + if (duk__cbor_decode_checkbreak(dec_ctx)) { + break; + } + } else { + if (count == 0UL) { + break; + } + count--; + } + + /* Non-string keys are coerced to strings, + * possibly leading to overwriting previous + * keys. Last key of a certain coerced name + * wins. If key is an object, it will coerce + * to '[object Object]' which is consistent + * but potentially misleading. One alternative + * would be to skip non-string keys. + */ + duk__cbor_decode_value(dec_ctx); + duk__cbor_decode_value(dec_ctx); + duk_put_prop(dec_ctx->thr, -3); + } + + return 1; +} + +DUK_LOCAL duk_double_t duk__cbor_decode_float(duk_cbor_decode_context *dec_ctx) { + duk_float_union u; + const duk_uint8_t *inp; + inp = duk__cbor_decode_consume(dec_ctx, 4); + duk_memcpy((void *) u.uc, (const void *) inp, 4); + duk_fltunion_big_to_host(&u); + return (duk_double_t) u.f; +} + +DUK_LOCAL duk_double_t duk__cbor_decode_double(duk_cbor_decode_context *dec_ctx) { + duk_double_union u; + const duk_uint8_t *inp; + inp = duk__cbor_decode_consume(dec_ctx, 8); + duk_memcpy((void *) u.uc, (const void *) inp, 8); + duk_dblunion_big_to_host(&u); + return u.d; +} + +#if defined(DUK_CBOR_DECODE_FASTPATH) +#define DUK__CBOR_AI (ib & 0x1fU) + +DUK_LOCAL void duk__cbor_decode_value(duk_cbor_decode_context *dec_ctx) { + duk_uint8_t ib; + + /* Any paths potentially recursing back to duk__cbor_decode_value() + * must perform a Duktape value stack growth check. Avoid the check + * here for simple paths like primitive values. + */ + + reread_initial_byte: + DUK_DDD(DUK_DDDPRINT("cbor decode off=%ld len=%ld", (long) dec_ctx->off, (long) dec_ctx->len)); + + ib = duk__cbor_decode_readbyte(dec_ctx); + + /* Full initial byte switch, footprint cost over baseline is ~+1kB. */ + /* XXX: Force full switch with no range check. */ + + switch (ib) { + case 0x00U: case 0x01U: case 0x02U: case 0x03U: case 0x04U: case 0x05U: case 0x06U: case 0x07U: + case 0x08U: case 0x09U: case 0x0aU: case 0x0bU: case 0x0cU: case 0x0dU: case 0x0eU: case 0x0fU: + case 0x10U: case 0x11U: case 0x12U: case 0x13U: case 0x14U: case 0x15U: case 0x16U: case 0x17U: + duk_push_uint(dec_ctx->thr, ib); + break; + case 0x18U: case 0x19U: case 0x1aU: case 0x1bU: + duk__cbor_decode_push_aival_int(dec_ctx, ib, 0 /*negative*/); + break; + case 0x1cU: case 0x1dU: case 0x1eU: case 0x1fU: + goto format_error; + case 0x20U: case 0x21U: case 0x22U: case 0x23U: case 0x24U: case 0x25U: case 0x26U: case 0x27U: + case 0x28U: case 0x29U: case 0x2aU: case 0x2bU: case 0x2cU: case 0x2dU: case 0x2eU: case 0x2fU: + case 0x30U: case 0x31U: case 0x32U: case 0x33U: case 0x34U: case 0x35U: case 0x36U: case 0x37U: + duk_push_int(dec_ctx->thr, -((duk_int_t) ((ib - 0x20U) + 1U))); + break; + case 0x38U: case 0x39U: case 0x3aU: case 0x3bU: + duk__cbor_decode_push_aival_int(dec_ctx, ib, 1 /*negative*/); + break; + case 0x3cU: case 0x3dU: case 0x3eU: case 0x3fU: + goto format_error; + case 0x40U: case 0x41U: case 0x42U: case 0x43U: case 0x44U: case 0x45U: case 0x46U: case 0x47U: + case 0x48U: case 0x49U: case 0x4aU: case 0x4bU: case 0x4cU: case 0x4dU: case 0x4eU: case 0x4fU: + case 0x50U: case 0x51U: case 0x52U: case 0x53U: case 0x54U: case 0x55U: case 0x56U: case 0x57U: + /* XXX: Avoid rewind, we know the length already. */ + DUK_ASSERT(dec_ctx->off > 0U); + dec_ctx->off--; + duk__cbor_decode_buffer(dec_ctx, 0x40U); + break; + case 0x58U: case 0x59U: case 0x5aU: case 0x5bU: + /* XXX: Avoid rewind, decode length inline. */ + DUK_ASSERT(dec_ctx->off > 0U); + dec_ctx->off--; + duk__cbor_decode_buffer(dec_ctx, 0x40U); + break; + case 0x5cU: case 0x5dU: case 0x5eU: + goto format_error; + case 0x5fU: + duk__cbor_decode_and_join_strbuf(dec_ctx, 0x40U); + break; + case 0x60U: case 0x61U: case 0x62U: case 0x63U: case 0x64U: case 0x65U: case 0x66U: case 0x67U: + case 0x68U: case 0x69U: case 0x6aU: case 0x6bU: case 0x6cU: case 0x6dU: case 0x6eU: case 0x6fU: + case 0x70U: case 0x71U: case 0x72U: case 0x73U: case 0x74U: case 0x75U: case 0x76U: case 0x77U: + /* XXX: Avoid double decode of length. */ + duk__cbor_decode_string(dec_ctx, ib, DUK__CBOR_AI); + break; + case 0x78U: case 0x79U: case 0x7aU: case 0x7bU: + /* XXX: Avoid double decode of length. */ + duk__cbor_decode_string(dec_ctx, ib, DUK__CBOR_AI); + break; + case 0x7cU: case 0x7dU: case 0x7eU: + goto format_error; + case 0x7fU: + duk__cbor_decode_string(dec_ctx, ib, DUK__CBOR_AI); + break; + case 0x80U: case 0x81U: case 0x82U: case 0x83U: case 0x84U: case 0x85U: case 0x86U: case 0x87U: + case 0x88U: case 0x89U: case 0x8aU: case 0x8bU: case 0x8cU: case 0x8dU: case 0x8eU: case 0x8fU: + case 0x90U: case 0x91U: case 0x92U: case 0x93U: case 0x94U: case 0x95U: case 0x96U: case 0x97U: + if (DUK_UNLIKELY(duk__cbor_decode_array(dec_ctx, ib, DUK__CBOR_AI) == 0)) { + goto format_error; + } + break; + case 0x98U: case 0x99U: case 0x9aU: case 0x9bU: + if (DUK_UNLIKELY(duk__cbor_decode_array(dec_ctx, ib, DUK__CBOR_AI) == 0)) { + goto format_error; + } + break; + case 0x9cU: case 0x9dU: case 0x9eU: + goto format_error; + case 0x9fU: + if (DUK_UNLIKELY(duk__cbor_decode_array(dec_ctx, ib, DUK__CBOR_AI) == 0)) { + goto format_error; + } + break; + case 0xa0U: case 0xa1U: case 0xa2U: case 0xa3U: case 0xa4U: case 0xa5U: case 0xa6U: case 0xa7U: + case 0xa8U: case 0xa9U: case 0xaaU: case 0xabU: case 0xacU: case 0xadU: case 0xaeU: case 0xafU: + case 0xb0U: case 0xb1U: case 0xb2U: case 0xb3U: case 0xb4U: case 0xb5U: case 0xb6U: case 0xb7U: + if (DUK_UNLIKELY(duk__cbor_decode_map(dec_ctx, ib, DUK__CBOR_AI) == 0)) { + goto format_error; + } + break; + case 0xb8U: case 0xb9U: case 0xbaU: case 0xbbU: + if (DUK_UNLIKELY(duk__cbor_decode_map(dec_ctx, ib, DUK__CBOR_AI) == 0)) { + goto format_error; + } + break; + case 0xbcU: case 0xbdU: case 0xbeU: + goto format_error; + case 0xbfU: + if (DUK_UNLIKELY(duk__cbor_decode_map(dec_ctx, ib, DUK__CBOR_AI) == 0)) { + goto format_error; + } + break; + case 0xc0U: case 0xc1U: case 0xc2U: case 0xc3U: case 0xc4U: case 0xc5U: case 0xc6U: case 0xc7U: + case 0xc8U: case 0xc9U: case 0xcaU: case 0xcbU: case 0xccU: case 0xcdU: case 0xceU: case 0xcfU: + case 0xd0U: case 0xd1U: case 0xd2U: case 0xd3U: case 0xd4U: case 0xd5U: case 0xd6U: case 0xd7U: + /* Tag 0-23: drop. */ + goto reread_initial_byte; + case 0xd8U: case 0xd9U: case 0xdaU: case 0xdbU: + duk__cbor_decode_skip_aival_int(dec_ctx, ib); + goto reread_initial_byte; + case 0xdcU: case 0xddU: case 0xdeU: case 0xdfU: + goto format_error; + case 0xe0U: + goto format_error; + case 0xe1U: + goto format_error; + case 0xe2U: + goto format_error; + case 0xe3U: + goto format_error; + case 0xe4U: + goto format_error; + case 0xe5U: + goto format_error; + case 0xe6U: + goto format_error; + case 0xe7U: + goto format_error; + case 0xe8U: + goto format_error; + case 0xe9U: + goto format_error; + case 0xeaU: + goto format_error; + case 0xebU: + goto format_error; + case 0xecU: + goto format_error; + case 0xedU: + goto format_error; + case 0xeeU: + goto format_error; + case 0xefU: + goto format_error; + case 0xf0U: + goto format_error; + case 0xf1U: + goto format_error; + case 0xf2U: + goto format_error; + case 0xf3U: + goto format_error; + case 0xf4U: + duk_push_false(dec_ctx->thr); + break; + case 0xf5U: + duk_push_true(dec_ctx->thr); + break; + case 0xf6U: + duk_push_null(dec_ctx->thr); + break; + case 0xf7U: + duk_push_undefined(dec_ctx->thr); + break; + case 0xf8U: + /* Simple value 32-255, nothing defined yet, so reject. */ + goto format_error; + case 0xf9U: { + duk_double_t d; + d = duk__cbor_decode_half_float(dec_ctx); + duk_push_number(dec_ctx->thr, d); + break; + } + case 0xfaU: { + duk_double_t d; + d = duk__cbor_decode_float(dec_ctx); + duk_push_number(dec_ctx->thr, d); + break; + } + case 0xfbU: { + duk_double_t d; + d = duk__cbor_decode_double(dec_ctx); + duk_push_number(dec_ctx->thr, d); + break; + } + case 0xfcU: + case 0xfdU: + case 0xfeU: + case 0xffU: + goto format_error; + } /* end switch */ + + return; + + format_error: + duk__cbor_decode_error(dec_ctx); +} +#else /* DUK_CBOR_DECODE_FASTPATH */ +DUK_LOCAL void duk__cbor_decode_value(duk_cbor_decode_context *dec_ctx) { + duk_uint8_t ib, mt, ai; + + /* Any paths potentially recursing back to duk__cbor_decode_value() + * must perform a Duktape value stack growth check. Avoid the check + * here for simple paths like primitive values. + */ + + reread_initial_byte: + DUK_DDD(DUK_DDDPRINT("cbor decode off=%ld len=%ld", (long) dec_ctx->off, (long) dec_ctx->len)); + + ib = duk__cbor_decode_readbyte(dec_ctx); + mt = ib >> 5U; + ai = ib & 0x1fU; + + /* Additional information in [24,27] = [0x18,0x1b] has relatively + * uniform handling for all major types: read 1/2/4/8 additional + * bytes. For major type 7 the 1-byte value is a 'simple type', and + * 2/4/8-byte values are floats. For other major types the 1/2/4/8 + * byte values are integers. The lengths are uniform, but the typing + * is not. + */ + + switch (mt) { + case 0U: { /* unsigned integer */ + duk__cbor_decode_push_aival_int(dec_ctx, ib, 0 /*negative*/); + break; + } + case 1U: { /* negative integer */ + duk__cbor_decode_push_aival_int(dec_ctx, ib, 1 /*negative*/); + break; + } + case 2U: { /* byte string */ + if (ai == 0x1fU) { + duk__cbor_decode_and_join_strbuf(dec_ctx, 0x40U); + } else { + duk__cbor_decode_rewind(dec_ctx, 1U); + duk__cbor_decode_buffer(dec_ctx, 0x40U); + } + break; + } + case 3U: { /* text string */ + duk__cbor_decode_string(dec_ctx, ib, ai); + break; + } + case 4U: { /* array of data items */ + if (DUK_UNLIKELY(duk__cbor_decode_array(dec_ctx, ib, ai) == 0)) { + goto format_error; + } + break; + } + case 5U: { /* map of pairs of data items */ + if (DUK_UNLIKELY(duk__cbor_decode_map(dec_ctx, ib, ai) == 0)) { + goto format_error; + } + break; + } + case 6U: { /* semantic tagging */ + /* Tags are ignored now, re-read initial byte. A tagged + * value may itself be tagged (an unlimited number of times) + * so keep on peeling away tags. + */ + duk__cbor_decode_skip_aival_int(dec_ctx, ib); + goto reread_initial_byte; + } + case 7U: { /* floating point numbers, simple data types, break; other */ + switch (ai) { + case 0x14U: { + duk_push_false(dec_ctx->thr); + break; + } + case 0x15U: { + duk_push_true(dec_ctx->thr); + break; + } + case 0x16U: { + duk_push_null(dec_ctx->thr); + break; + } + case 0x17U: { + duk_push_undefined(dec_ctx->thr); + break; + } + case 0x18U: { /* more simple values (1 byte) */ + /* Simple value encoded in additional byte (none + * are defined so far). RFC 7049 states that the + * follow-up byte must be 32-255 to minimize + * confusion. So, a non-shortest encoding like + * f815 (= true, shortest encoding f5) must be + * rejected. cbor.me tester rejects f815, but + * e.g. Python CBOR binding decodes it as true. + */ + goto format_error; + } + case 0x19U: { /* half-float (2 bytes) */ + duk_double_t d; + d = duk__cbor_decode_half_float(dec_ctx); + duk_push_number(dec_ctx->thr, d); + break; + } + case 0x1aU: { /* float (4 bytes) */ + duk_double_t d; + d = duk__cbor_decode_float(dec_ctx); + duk_push_number(dec_ctx->thr, d); + break; + } + case 0x1bU: { /* double (8 bytes) */ + duk_double_t d; + d = duk__cbor_decode_double(dec_ctx); + duk_push_number(dec_ctx->thr, d); + break; + } + case 0xffU: /* unexpected break */ + default: { + goto format_error; + } + } /* end switch */ + break; + } + default: { + goto format_error; /* will never actually occur */ + } + } /* end switch */ + + return; + + format_error: + duk__cbor_decode_error(dec_ctx); +} +#endif /* DUK_CBOR_DECODE_FASTPATH */ + +DUK_LOCAL void duk__cbor_encode(duk_hthread *thr, duk_idx_t idx, duk_uint_t encode_flags) { + duk_cbor_encode_context enc_ctx; + duk_uint8_t *buf; + + DUK_UNREF(encode_flags); + + idx = duk_require_normalize_index(thr, idx); + + enc_ctx.thr = thr; + enc_ctx.idx_buf = duk_get_top(thr); + + enc_ctx.len = 64; + buf = (duk_uint8_t *) duk_push_dynamic_buffer(thr, enc_ctx.len); + enc_ctx.ptr = buf; + enc_ctx.buf = buf; + enc_ctx.buf_end = buf + enc_ctx.len; + + duk_dup(thr, idx); + duk__cbor_encode_value(&enc_ctx); + duk_resize_buffer(enc_ctx.thr, enc_ctx.idx_buf, (duk_size_t) (enc_ctx.ptr - enc_ctx.buf)); + duk_replace(thr, idx); +} + +DUK_LOCAL void duk__cbor_decode(duk_hthread *thr, duk_idx_t idx, duk_uint_t decode_flags) { + duk_cbor_decode_context dec_ctx; + + DUK_UNREF(decode_flags); + + /* Suppress compile warnings for functions only needed with e.g. + * asserts enabled. + */ + DUK_UNREF(duk__cbor_get_reserve); + + idx = duk_require_normalize_index(thr, idx); + + dec_ctx.thr = thr; + dec_ctx.buf = (const duk_uint8_t *) duk_require_buffer_data(thr, idx, &dec_ctx.len); + dec_ctx.off = 0; + /* dec_ctx.len: set above */ + + duk__cbor_req_stack(&dec_ctx); + duk__cbor_decode_value(&dec_ctx); + if (dec_ctx.off != dec_ctx.len) { + (void) duk_type_error(thr, "trailing garbage"); + } + + duk_replace(thr, idx); +} + +#else /* DUK_USE_CBOR_SUPPORT */ + +DUK_LOCAL void duk__cbor_encode(duk_hthread *thr, duk_idx_t idx, duk_uint_t encode_flags) { + DUK_UNREF(idx); + DUK_UNREF(encode_flags); + DUK_ERROR_UNSUPPORTED(thr); +} + +DUK_LOCAL void duk__cbor_decode(duk_hthread *thr, duk_idx_t idx, duk_uint_t decode_flags) { + DUK_UNREF(idx); + DUK_UNREF(decode_flags); + DUK_ERROR_UNSUPPORTED(thr); +} + +#endif /* DUK_USE_CBOR_SUPPORT */ + +/* + * Public APIs + */ + +DUK_EXTERNAL void duk_cbor_encode(duk_hthread *thr, duk_idx_t idx, duk_uint_t encode_flags) { + DUK_ASSERT_API_ENTRY(thr); + duk__cbor_encode(thr, idx, encode_flags); +} +DUK_EXTERNAL void duk_cbor_decode(duk_hthread *thr, duk_idx_t idx, duk_uint_t decode_flags) { + DUK_ASSERT_API_ENTRY(thr); + duk__cbor_decode(thr, idx, decode_flags); +} + +#if defined(DUK_USE_CBOR_BUILTIN) +#if defined(DUK_USE_CBOR_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_cbor_encode(duk_hthread *thr) { + DUK_ASSERT_TOP(thr, 1); + + duk__cbor_encode(thr, -1, 0 /*flags*/); + + /* Produce an ArrayBuffer by first decoding into a plain buffer which + * mimics a Uint8Array and gettings its .buffer property. + */ + /* XXX: shortcut */ + (void) duk_get_prop_stridx(thr, -1, DUK_STRIDX_LC_BUFFER); + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_cbor_decode(duk_hthread *thr) { + DUK_ASSERT_TOP(thr, 1); + + duk__cbor_decode(thr, -1, 0 /*flags*/); + return 1; +} +#else /* DUK_USE_CBOR_SUPPORT */ +DUK_INTERNAL duk_ret_t duk_bi_cbor_encode(duk_hthread *thr) { + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return 0;); +} +DUK_INTERNAL duk_ret_t duk_bi_cbor_decode(duk_hthread *thr) { + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return 0;); +} +#endif /* DUK_USE_CBOR_SUPPORT */ +#endif /* DUK_USE_CBOR_BUILTIN */ diff --git a/third_party/duktape/duk_bi_date.c b/third_party/duktape/duk_bi_date.c new file mode 100644 index 00000000..bd7f0822 --- /dev/null +++ b/third_party/duktape/duk_bi_date.c @@ -0,0 +1,1771 @@ +/* clang-format off */ +/* + * Date built-ins + * + * Unlike most built-ins, Date has some platform dependencies for getting + * UTC time, converting between UTC and local time, and parsing and + * formatting time values. These are all abstracted behind DUK_USE_xxx + * config options. There are built-in platform specific providers for + * POSIX and Windows, but external providers can also be used. + * + * See doc/datetime.rst. + * + */ + +#include "third_party/duktape/duk_internal.h" + +/* XXX: currently defines unnecessary symbols when DUK_USE_DATE_BUILTIN is disabled. */ + +/* + * Forward declarations + */ + +DUK_LOCAL_DECL duk_double_t duk__push_this_get_timeval_tzoffset(duk_hthread *thr, duk_small_uint_t flags, duk_int_t *out_tzoffset); +DUK_LOCAL_DECL duk_double_t duk__push_this_get_timeval(duk_hthread *thr, duk_small_uint_t flags); +DUK_LOCAL_DECL void duk__twodigit_year_fixup(duk_hthread *thr, duk_idx_t idx_val); +DUK_LOCAL_DECL duk_ret_t duk__set_this_timeval_from_dparts(duk_hthread *thr, duk_double_t *dparts, duk_small_uint_t flags); + +/* + * Other file level defines + */ + +/* Debug macro to print all parts and dparts (used manually because of debug level). */ +#define DUK__DPRINT_PARTS_AND_DPARTS(parts,dparts) do { \ + DUK_D(DUK_DPRINT("parts: %ld %ld %ld %ld %ld %ld %ld %ld, dparts: %lf %lf %lf %lf %lf %lf %lf %lf", \ + (long) (parts)[0], (long) (parts)[1], \ + (long) (parts)[2], (long) (parts)[3], \ + (long) (parts)[4], (long) (parts)[5], \ + (long) (parts)[6], (long) (parts)[7], \ + (double) (dparts)[0], (double) (dparts)[1], \ + (double) (dparts)[2], (double) (dparts)[3], \ + (double) (dparts)[4], (double) (dparts)[5], \ + (double) (dparts)[6], (double) (dparts)[7])); \ + } while (0) +#define DUK__DPRINT_PARTS(parts) do { \ + DUK_D(DUK_DPRINT("parts: %ld %ld %ld %ld %ld %ld %ld %ld", \ + (long) (parts)[0], (long) (parts)[1], \ + (long) (parts)[2], (long) (parts)[3], \ + (long) (parts)[4], (long) (parts)[5], \ + (long) (parts)[6], (long) (parts)[7])); \ + } while (0) +#define DUK__DPRINT_DPARTS(dparts) do { \ + DUK_D(DUK_DPRINT("dparts: %lf %lf %lf %lf %lf %lf %lf %lf", \ + (double) (dparts)[0], (double) (dparts)[1], \ + (double) (dparts)[2], (double) (dparts)[3], \ + (double) (dparts)[4], (double) (dparts)[5], \ + (double) (dparts)[6], (double) (dparts)[7])); \ + } while (0) + +/* Equivalent year for DST calculations outside [1970,2038[ range, see + * E5 Section 15.9.1.8. Equivalent year has the same leap-year-ness and + * starts with the same weekday on Jan 1. + * https://bugzilla.mozilla.org/show_bug.cgi?id=351066 + */ +#define DUK__YEAR(x) ((duk_uint8_t) ((x) - 1970)) +DUK_LOCAL duk_uint8_t duk__date_equivyear[14] = { +#if 1 + /* This is based on V8 EquivalentYear() algorithm (see util/genequivyear.py): + * http://code.google.com/p/v8/source/browse/trunk/src/date.h#146 + */ + + /* non-leap year: sunday, monday, ... */ + DUK__YEAR(2023), DUK__YEAR(2035), DUK__YEAR(2019), DUK__YEAR(2031), + DUK__YEAR(2015), DUK__YEAR(2027), DUK__YEAR(2011), + + /* leap year: sunday, monday, ... */ + DUK__YEAR(2012), DUK__YEAR(2024), DUK__YEAR(2008), DUK__YEAR(2020), + DUK__YEAR(2032), DUK__YEAR(2016), DUK__YEAR(2028) +#endif + +#if 0 + /* This is based on Rhino EquivalentYear() algorithm: + * https://github.com/mozilla/rhino/blob/f99cc11d616f0cdda2c42bde72b3484df6182947/src/org/mozilla/javascript/NativeDate.java + */ + + /* non-leap year: sunday, monday, ... */ + DUK__YEAR(1978), DUK__YEAR(1973), DUK__YEAR(1985), DUK__YEAR(1986), + DUK__YEAR(1981), DUK__YEAR(1971), DUK__YEAR(1977), + + /* leap year: sunday, monday, ... */ + DUK__YEAR(1984), DUK__YEAR(1996), DUK__YEAR(1980), DUK__YEAR(1992), + DUK__YEAR(1976), DUK__YEAR(1988), DUK__YEAR(1972) +#endif +}; + +/* + * ISO 8601 subset parser. + */ + +/* Parser part count. */ +#define DUK__NUM_ISO8601_PARSER_PARTS 9 + +/* Parser part indices. */ +#define DUK__PI_YEAR 0 +#define DUK__PI_MONTH 1 +#define DUK__PI_DAY 2 +#define DUK__PI_HOUR 3 +#define DUK__PI_MINUTE 4 +#define DUK__PI_SECOND 5 +#define DUK__PI_MILLISECOND 6 +#define DUK__PI_TZHOUR 7 +#define DUK__PI_TZMINUTE 8 + +/* Parser part masks. */ +#define DUK__PM_YEAR (1 << DUK__PI_YEAR) +#define DUK__PM_MONTH (1 << DUK__PI_MONTH) +#define DUK__PM_DAY (1 << DUK__PI_DAY) +#define DUK__PM_HOUR (1 << DUK__PI_HOUR) +#define DUK__PM_MINUTE (1 << DUK__PI_MINUTE) +#define DUK__PM_SECOND (1 << DUK__PI_SECOND) +#define DUK__PM_MILLISECOND (1 << DUK__PI_MILLISECOND) +#define DUK__PM_TZHOUR (1 << DUK__PI_TZHOUR) +#define DUK__PM_TZMINUTE (1 << DUK__PI_TZMINUTE) + +/* Parser separator indices. */ +#define DUK__SI_PLUS 0 +#define DUK__SI_MINUS 1 +#define DUK__SI_T 2 +#define DUK__SI_SPACE 3 +#define DUK__SI_COLON 4 +#define DUK__SI_PERIOD 5 +#define DUK__SI_Z 6 +#define DUK__SI_NUL 7 + +/* Parser separator masks. */ +#define DUK__SM_PLUS (1 << DUK__SI_PLUS) +#define DUK__SM_MINUS (1 << DUK__SI_MINUS) +#define DUK__SM_T (1 << DUK__SI_T) +#define DUK__SM_SPACE (1 << DUK__SI_SPACE) +#define DUK__SM_COLON (1 << DUK__SI_COLON) +#define DUK__SM_PERIOD (1 << DUK__SI_PERIOD) +#define DUK__SM_Z (1 << DUK__SI_Z) +#define DUK__SM_NUL (1 << DUK__SI_NUL) + +/* Rule control flags. */ +#define DUK__CF_NEG (1 << 0) /* continue matching, set neg_tzoffset flag */ +#define DUK__CF_ACCEPT (1 << 1) /* accept string */ +#define DUK__CF_ACCEPT_NUL (1 << 2) /* accept string if next char is NUL (otherwise reject) */ + +#define DUK__PACK_RULE(partmask,sepmask,nextpart,flags) \ + ((duk_uint32_t) (partmask) + \ + (((duk_uint32_t) (sepmask)) << 9) + \ + (((duk_uint32_t) (nextpart)) << 17) + \ + (((duk_uint32_t) (flags)) << 21)) + +#define DUK__UNPACK_RULE(rule,var_nextidx,var_flags) do { \ + (var_nextidx) = (duk_small_uint_t) (((rule) >> 17) & 0x0f); \ + (var_flags) = (duk_small_uint_t) ((rule) >> 21); \ + } while (0) + +#define DUK__RULE_MASK_PART_SEP 0x1ffffUL + +/* Matching separator index is used in the control table */ +DUK_LOCAL const duk_uint8_t duk__parse_iso8601_seps[] = { + DUK_ASC_PLUS /*0*/, DUK_ASC_MINUS /*1*/, DUK_ASC_UC_T /*2*/, DUK_ASC_SPACE /*3*/, + DUK_ASC_COLON /*4*/, DUK_ASC_PERIOD /*5*/, DUK_ASC_UC_Z /*6*/, DUK_ASC_NUL /*7*/ +}; + +/* Rule table: first matching rule is used to determine what to do next. */ +DUK_LOCAL const duk_uint32_t duk__parse_iso8601_control[] = { + DUK__PACK_RULE(DUK__PM_YEAR, DUK__SM_MINUS, DUK__PI_MONTH, 0), + DUK__PACK_RULE(DUK__PM_MONTH, DUK__SM_MINUS, DUK__PI_DAY, 0), + DUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY, DUK__SM_T | DUK__SM_SPACE, DUK__PI_HOUR, 0), + DUK__PACK_RULE(DUK__PM_HOUR, DUK__SM_COLON, DUK__PI_MINUTE, 0), + DUK__PACK_RULE(DUK__PM_MINUTE, DUK__SM_COLON, DUK__PI_SECOND, 0), + DUK__PACK_RULE(DUK__PM_SECOND, DUK__SM_PERIOD, DUK__PI_MILLISECOND, 0), + DUK__PACK_RULE(DUK__PM_TZHOUR, DUK__SM_COLON, DUK__PI_TZMINUTE, 0), + DUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_PLUS, DUK__PI_TZHOUR, 0), + DUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_MINUS, DUK__PI_TZHOUR, DUK__CF_NEG), + DUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_Z, 0, DUK__CF_ACCEPT_NUL), + DUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND | DUK__PM_TZHOUR /*Note2*/ | DUK__PM_TZMINUTE, DUK__SM_NUL, 0, DUK__CF_ACCEPT) + + /* Note1: the specification doesn't require matching a time form with + * just hours ("HH"), but we accept it here, e.g. "2012-01-02T12Z". + * + * Note2: the specification doesn't require matching a timezone offset + * with just hours ("HH"), but accept it here, e.g. "2012-01-02T03:04:05+02" + */ +}; + +DUK_LOCAL duk_bool_t duk__parse_string_iso8601_subset(duk_hthread *thr, const char *str) { + duk_int_t parts[DUK__NUM_ISO8601_PARSER_PARTS]; + duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS]; + duk_double_t d; + const duk_uint8_t *p; + duk_small_uint_t part_idx = 0; + duk_int_t accum = 0; + duk_small_uint_t ndigits = 0; + duk_bool_t neg_year = 0; + duk_bool_t neg_tzoffset = 0; + duk_uint_fast8_t ch; + duk_small_uint_t i; + + /* During parsing, month and day are one-based; set defaults here. */ + duk_memzero(parts, sizeof(parts)); + DUK_ASSERT(parts[DUK_DATE_IDX_YEAR] == 0); /* don't care value, year is mandatory */ + parts[DUK_DATE_IDX_MONTH] = 1; + parts[DUK_DATE_IDX_DAY] = 1; + + /* Special handling for year sign. */ + p = (const duk_uint8_t *) str; + ch = p[0]; + if (ch == DUK_ASC_PLUS) { + p++; + } else if (ch == DUK_ASC_MINUS) { + neg_year = 1; + p++; + } + + for (;;) { + ch = *p++; + DUK_DDD(DUK_DDDPRINT("parsing, part_idx=%ld, char=%ld ('%c')", + (long) part_idx, (long) ch, + (int) ((ch >= 0x20 && ch <= 0x7e) ? ch : DUK_ASC_QUESTION))); + + if (ch >= DUK_ASC_0 && ch <= DUK_ASC_9) { + if (ndigits >= 9) { + DUK_DDD(DUK_DDDPRINT("too many digits -> reject")); + goto reject; + } + if (part_idx == DUK__PI_MILLISECOND && ndigits >= 3) { + /* ignore millisecond fractions after 3 */ + } else { + accum = accum * 10 + ((duk_int_t) ch) - ((duk_int_t) DUK_ASC_0) + 0x00; + ndigits++; + } + } else { + duk_uint_fast32_t match_val; + duk_small_uint_t sep_idx; + + if (ndigits <= 0) { + goto reject; + } + if (part_idx == DUK__PI_MILLISECOND) { + /* complete the millisecond field */ + while (ndigits < 3) { + accum *= 10; + ndigits++; + } + } + parts[part_idx] = accum; + DUK_DDD(DUK_DDDPRINT("wrote part %ld -> value %ld", (long) part_idx, (long) accum)); + + accum = 0; + ndigits = 0; + + for (i = 0; i < (duk_small_uint_t) (sizeof(duk__parse_iso8601_seps) / sizeof(duk_uint8_t)); i++) { + if (duk__parse_iso8601_seps[i] == ch) { + break; + } + } + if (i == (duk_small_uint_t) (sizeof(duk__parse_iso8601_seps) / sizeof(duk_uint8_t))) { + DUK_DDD(DUK_DDDPRINT("separator character doesn't match -> reject")); + goto reject; + } + + sep_idx = i; + match_val = (1UL << part_idx) + (1UL << (sep_idx + 9)); /* match against rule part/sep bits */ + + for (i = 0; i < (duk_small_uint_t) (sizeof(duk__parse_iso8601_control) / sizeof(duk_uint32_t)); i++) { + duk_uint_fast32_t rule = duk__parse_iso8601_control[i]; + duk_small_uint_t nextpart; + duk_small_uint_t cflags; + + DUK_DDD(DUK_DDDPRINT("part_idx=%ld, sep_idx=%ld, match_val=0x%08lx, considering rule=0x%08lx", + (long) part_idx, (long) sep_idx, + (unsigned long) match_val, (unsigned long) rule)); + + if ((rule & match_val) != match_val) { + continue; + } + + DUK__UNPACK_RULE(rule, nextpart, cflags); + + DUK_DDD(DUK_DDDPRINT("rule match -> part_idx=%ld, sep_idx=%ld, match_val=0x%08lx, " + "rule=0x%08lx -> nextpart=%ld, cflags=0x%02lx", + (long) part_idx, (long) sep_idx, + (unsigned long) match_val, (unsigned long) rule, + (long) nextpart, (unsigned long) cflags)); + + if (cflags & DUK__CF_NEG) { + neg_tzoffset = 1; + } + + if (cflags & DUK__CF_ACCEPT) { + goto accept; + } + + if (cflags & DUK__CF_ACCEPT_NUL) { + DUK_ASSERT(*(p - 1) != (char) 0); + if (*p == DUK_ASC_NUL) { + goto accept; + } + goto reject; + } + + part_idx = nextpart; + break; + } /* rule match */ + + if (i == (duk_small_uint_t) (sizeof(duk__parse_iso8601_control) / sizeof(duk_uint32_t))) { + DUK_DDD(DUK_DDDPRINT("no rule matches -> reject")); + goto reject; + } + + if (ch == 0) { + /* This shouldn't be necessary, but check just in case + * to avoid any chance of overruns. + */ + DUK_DDD(DUK_DDDPRINT("NUL after rule matching (should not happen) -> reject")); + goto reject; + } + } /* if-digit-else-ctrl */ + } /* char loop */ + + /* We should never exit the loop above. */ + DUK_UNREACHABLE(); + + reject: + DUK_DDD(DUK_DDDPRINT("reject")); + return 0; + + accept: + DUK_DDD(DUK_DDDPRINT("accept")); + + /* Apply timezone offset to get the main parts in UTC */ + if (neg_year) { + parts[DUK__PI_YEAR] = -parts[DUK__PI_YEAR]; + } + if (neg_tzoffset) { + parts[DUK__PI_HOUR] += parts[DUK__PI_TZHOUR]; + parts[DUK__PI_MINUTE] += parts[DUK__PI_TZMINUTE]; + } else { + parts[DUK__PI_HOUR] -= parts[DUK__PI_TZHOUR]; + parts[DUK__PI_MINUTE] -= parts[DUK__PI_TZMINUTE]; + } + parts[DUK__PI_MONTH] -= 1; /* zero-based month */ + parts[DUK__PI_DAY] -= 1; /* zero-based day */ + + /* Use double parts, they tolerate unnormalized time. + * + * Note: DUK_DATE_IDX_WEEKDAY is initialized with a bogus value (DUK__PI_TZHOUR) + * on purpose. It won't be actually used by duk_bi_date_get_timeval_from_dparts(), + * but will make the value initialized just in case, and avoid any + * potential for Valgrind issues. + */ + for (i = 0; i < DUK_DATE_IDX_NUM_PARTS; i++) { + DUK_DDD(DUK_DDDPRINT("part[%ld] = %ld", (long) i, (long) parts[i])); + dparts[i] = parts[i]; + } + + d = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/); + duk_push_number(thr, d); + return 1; +} + +/* + * Date/time parsing helper. + * + * Parse a datetime string into a time value. We must first try to parse + * the input according to the standard format in E5.1 Section 15.9.1.15. + * If that fails, we can try to parse using custom parsing, which can + * either be platform neutral (custom code) or platform specific (using + * existing platform API calls). + * + * Note in particular that we must parse whatever toString(), toUTCString(), + * and toISOString() can produce; see E5.1 Section 15.9.4.2. + * + * Returns 1 to allow tail calling. + * + * There is much room for improvement here with respect to supporting + * alternative datetime formats. For instance, V8 parses '2012-01-01' as + * UTC and '2012/01/01' as local time. + */ + +DUK_LOCAL duk_ret_t duk__parse_string(duk_hthread *thr, const char *str) { + /* XXX: there is a small risk here: because the ISO 8601 parser is + * very loose, it may end up parsing some datetime values which + * would be better parsed with a platform specific parser. + */ + + DUK_ASSERT(str != NULL); + DUK_DDD(DUK_DDDPRINT("parse datetime from string '%s'", (const char *) str)); + + if (duk__parse_string_iso8601_subset(thr, str) != 0) { + return 1; + } + +#if defined(DUK_USE_DATE_PARSE_STRING) + /* Contract, either: + * - Push value on stack and return 1 + * - Don't push anything on stack and return 0 + */ + + if (DUK_USE_DATE_PARSE_STRING(thr, str) != 0) { + return 1; + } +#else + /* No platform-specific parsing, this is not an error. */ +#endif + + duk_push_nan(thr); + return 1; +} + +/* + * Calendar helpers + * + * Some helpers are used for getters and can operate on normalized values + * which can be represented with 32-bit signed integers. Other helpers are + * needed by setters and operate on un-normalized double values, must watch + * out for non-finite numbers etc. + */ + +DUK_LOCAL duk_uint8_t duk__days_in_month[12] = { + (duk_uint8_t) 31, (duk_uint8_t) 28, (duk_uint8_t) 31, (duk_uint8_t) 30, + (duk_uint8_t) 31, (duk_uint8_t) 30, (duk_uint8_t) 31, (duk_uint8_t) 31, + (duk_uint8_t) 30, (duk_uint8_t) 31, (duk_uint8_t) 30, (duk_uint8_t) 31 +}; + +/* Maximum iteration count for computing UTC-to-local time offset when + * creating an ECMAScript time value from local parts. + */ +#define DUK__LOCAL_TZOFFSET_MAXITER 4 + +/* Because 'day since epoch' can be negative and is used to compute weekday + * using a modulo operation, add this multiple of 7 to avoid negative values + * when year is below 1970 epoch. ECMAScript time values are restricted to + * +/- 100 million days from epoch, so this adder fits nicely into 32 bits. + * Round to a multiple of 7 (= floor(100000000 / 7) * 7) and add margin. + */ +#define DUK__WEEKDAY_MOD_ADDER (20000000 * 7) /* 0x08583b00 */ + +DUK_INTERNAL duk_bool_t duk_bi_date_is_leap_year(duk_int_t year) { + if ((year % 4) != 0) { + return 0; + } + if ((year % 100) != 0) { + return 1; + } + if ((year % 400) != 0) { + return 0; + } + return 1; +} + +DUK_INTERNAL duk_bool_t duk_bi_date_timeval_in_valid_range(duk_double_t x) { + return (x >= -DUK_DATE_MSEC_100M_DAYS && x <= DUK_DATE_MSEC_100M_DAYS); +} + +DUK_INTERNAL duk_bool_t duk_bi_date_timeval_in_leeway_range(duk_double_t x) { + return (x >= -DUK_DATE_MSEC_100M_DAYS_LEEWAY && x <= DUK_DATE_MSEC_100M_DAYS_LEEWAY); +} + +DUK_INTERNAL duk_bool_t duk_bi_date_year_in_valid_range(duk_double_t x) { + return (x >= DUK_DATE_MIN_ECMA_YEAR && x <= DUK_DATE_MAX_ECMA_YEAR); +} + +DUK_LOCAL duk_double_t duk__timeclip(duk_double_t x) { + if (!DUK_ISFINITE(x)) { + return DUK_DOUBLE_NAN; + } + + if (!duk_bi_date_timeval_in_valid_range(x)) { + return DUK_DOUBLE_NAN; + } + + x = duk_js_tointeger_number(x); + + /* Here we'd have the option to normalize -0 to +0. */ + return x; +} + +/* Integer division which floors also negative values correctly. */ +DUK_LOCAL duk_int_t duk__div_floor(duk_int_t a, duk_int_t b) { + DUK_ASSERT(b > 0); + if (a >= 0) { + return a / b; + } else { + /* e.g. a = -4, b = 5 --> -4 - 5 + 1 / 5 --> -8 / 5 --> -1 + * a = -5, b = 5 --> -5 - 5 + 1 / 5 --> -9 / 5 --> -1 + * a = -6, b = 5 --> -6 - 5 + 1 / 5 --> -10 / 5 --> -2 + */ + return (a - b + 1) / b; + } +} + +/* Compute day number of the first day of a given year. */ +DUK_LOCAL duk_int_t duk__day_from_year(duk_int_t year) { + /* Note: in integer arithmetic, (x / 4) is same as floor(x / 4) for non-negative + * values, but is incorrect for negative ones. + */ + return 365 * (year - 1970) + + duk__div_floor(year - 1969, 4) + - duk__div_floor(year - 1901, 100) + + duk__div_floor(year - 1601, 400); +} + +/* Given a day number, determine year and day-within-year. */ +DUK_LOCAL duk_int_t duk__year_from_day(duk_int_t day, duk_small_int_t *out_day_within_year) { + duk_int_t year; + duk_int_t diff_days; + + /* estimate year upwards (towards positive infinity), then back down; + * two iterations should be enough + */ + + if (day >= 0) { + year = 1970 + day / 365; + } else { + year = 1970 + day / 366; + } + + for (;;) { + diff_days = duk__day_from_year(year) - day; + DUK_DDD(DUK_DDDPRINT("year=%ld day=%ld, diff_days=%ld", (long) year, (long) day, (long) diff_days)); + if (diff_days <= 0) { + DUK_ASSERT(-diff_days < 366); /* fits into duk_small_int_t */ + *out_day_within_year = -diff_days; + DUK_DDD(DUK_DDDPRINT("--> year=%ld, day-within-year=%ld", + (long) year, (long) *out_day_within_year)); + DUK_ASSERT(*out_day_within_year >= 0); + DUK_ASSERT(*out_day_within_year < (duk_bi_date_is_leap_year(year) ? 366 : 365)); + return year; + } + + /* Note: this is very tricky; we must never 'overshoot' the + * correction downwards. + */ + year -= 1 + (diff_days - 1) / 366; /* conservative */ + } +} + +/* Given a (year, month, day-within-month) triple, compute day number. + * The input triple is un-normalized and may contain non-finite values. + */ +DUK_LOCAL duk_double_t duk__make_day(duk_double_t year, duk_double_t month, duk_double_t day) { + duk_int_t day_num; + duk_bool_t is_leap; + duk_small_int_t i, n; + + /* Assume that year, month, day are all coerced to whole numbers. + * They may also be NaN or infinity, in which case this function + * must return NaN or infinity to ensure time value becomes NaN. + * If 'day' is NaN, the final return will end up returning a NaN, + * so it doesn't need to be checked here. + */ + + if (!DUK_ISFINITE(year) || !DUK_ISFINITE(month)) { + return DUK_DOUBLE_NAN; + } + + year += DUK_FLOOR(month / 12.0); + + month = DUK_FMOD(month, 12.0); + if (month < 0.0) { + /* handle negative values */ + month += 12.0; + } + + /* The algorithm in E5.1 Section 15.9.1.12 normalizes month, but + * does not normalize the day-of-month (nor check whether or not + * it is finite) because it's not necessary for finding the day + * number which matches the (year,month) pair. + * + * We assume that duk__day_from_year() is exact here. + * + * Without an explicit infinity / NaN check in the beginning, + * day_num would be a bogus integer here. + * + * It's possible for 'year' to be out of integer range here. + * If so, we need to return NaN without integer overflow. + * This fixes test-bug-setyear-overflow.js. + */ + + if (!duk_bi_date_year_in_valid_range(year)) { + DUK_DD(DUK_DDPRINT("year not in ecmascript valid range, avoid integer overflow: %lf", (double) year)); + return DUK_DOUBLE_NAN; + } + day_num = duk__day_from_year((duk_int_t) year); + is_leap = duk_bi_date_is_leap_year((duk_int_t) year); + + n = (duk_small_int_t) month; + for (i = 0; i < n; i++) { + day_num += duk__days_in_month[i]; + if (i == 1 && is_leap) { + day_num++; + } + } + + /* If 'day' is NaN, returns NaN. */ + return (duk_double_t) day_num + day; +} + +/* Split time value into parts. The time value may contain fractions (it may + * come from duk_time_to_components() API call) which are truncated. Possible + * local time adjustment has already been applied when reading the time value. + */ +DUK_INTERNAL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts, duk_double_t *dparts, duk_small_uint_t flags) { + duk_double_t d1, d2; + duk_int_t t1, t2; + duk_int_t day_since_epoch; + duk_int_t year; /* does not fit into 16 bits */ + duk_small_int_t day_in_year; + duk_small_int_t month; + duk_small_int_t day; + duk_small_int_t dim; + duk_int_t jan1_since_epoch; + duk_small_int_t jan1_weekday; + duk_int_t equiv_year; + duk_small_uint_t i; + duk_bool_t is_leap; + duk_small_int_t arridx; + + DUK_ASSERT(DUK_ISFINITE(d)); /* caller checks */ + d = DUK_FLOOR(d); /* remove fractions if present */ + DUK_ASSERT(duk_double_equals(DUK_FLOOR(d), d)); + + /* The timevalue must be in valid ECMAScript range, but since a local + * time offset can be applied, we need to allow a +/- 24h leeway to + * the value. In other words, although the UTC time is within the + * ECMAScript range, the local part values can be just outside of it. + */ + DUK_UNREF(duk_bi_date_timeval_in_leeway_range); + DUK_ASSERT(duk_bi_date_timeval_in_leeway_range(d)); + + /* These computations are guaranteed to be exact for the valid + * E5 time value range, assuming milliseconds without fractions. + */ + d1 = (duk_double_t) DUK_FMOD(d, (double) DUK_DATE_MSEC_DAY); + if (d1 < 0.0) { + /* deal with negative values */ + d1 += (duk_double_t) DUK_DATE_MSEC_DAY; + } + d2 = DUK_FLOOR((double) (d / (duk_double_t) DUK_DATE_MSEC_DAY)); + DUK_ASSERT(duk_double_equals(d2 * ((duk_double_t) DUK_DATE_MSEC_DAY) + d1, d)); + /* now expected to fit into a 32-bit integer */ + t1 = (duk_int_t) d1; + t2 = (duk_int_t) d2; + day_since_epoch = t2; + DUK_ASSERT(duk_double_equals((duk_double_t) t1, d1)); + DUK_ASSERT(duk_double_equals((duk_double_t) t2, d2)); + + /* t1 = milliseconds within day (fits 32 bit) + * t2 = day number from epoch (fits 32 bit, may be negative) + */ + + parts[DUK_DATE_IDX_MILLISECOND] = t1 % 1000; t1 /= 1000; + parts[DUK_DATE_IDX_SECOND] = t1 % 60; t1 /= 60; + parts[DUK_DATE_IDX_MINUTE] = t1 % 60; t1 /= 60; + parts[DUK_DATE_IDX_HOUR] = t1; + DUK_ASSERT(parts[DUK_DATE_IDX_MILLISECOND] >= 0 && parts[DUK_DATE_IDX_MILLISECOND] <= 999); + DUK_ASSERT(parts[DUK_DATE_IDX_SECOND] >= 0 && parts[DUK_DATE_IDX_SECOND] <= 59); + DUK_ASSERT(parts[DUK_DATE_IDX_MINUTE] >= 0 && parts[DUK_DATE_IDX_MINUTE] <= 59); + DUK_ASSERT(parts[DUK_DATE_IDX_HOUR] >= 0 && parts[DUK_DATE_IDX_HOUR] <= 23); + + DUK_DDD(DUK_DDDPRINT("d=%lf, d1=%lf, d2=%lf, t1=%ld, t2=%ld, parts: hour=%ld min=%ld sec=%ld msec=%ld", + (double) d, (double) d1, (double) d2, (long) t1, (long) t2, + (long) parts[DUK_DATE_IDX_HOUR], + (long) parts[DUK_DATE_IDX_MINUTE], + (long) parts[DUK_DATE_IDX_SECOND], + (long) parts[DUK_DATE_IDX_MILLISECOND])); + + /* This assert depends on the input parts representing time inside + * the ECMAScript range. + */ + DUK_ASSERT(t2 + DUK__WEEKDAY_MOD_ADDER >= 0); + parts[DUK_DATE_IDX_WEEKDAY] = (t2 + 4 + DUK__WEEKDAY_MOD_ADDER) % 7; /* E5.1 Section 15.9.1.6 */ + DUK_ASSERT(parts[DUK_DATE_IDX_WEEKDAY] >= 0 && parts[DUK_DATE_IDX_WEEKDAY] <= 6); + + year = duk__year_from_day(t2, &day_in_year); + day = day_in_year; + is_leap = duk_bi_date_is_leap_year(year); + for (month = 0; month < 12; month++) { + dim = duk__days_in_month[month]; + if (month == 1 && is_leap) { + dim++; + } + DUK_DDD(DUK_DDDPRINT("month=%ld, dim=%ld, day=%ld", + (long) month, (long) dim, (long) day)); + if (day < dim) { + break; + } + day -= dim; + } + DUK_DDD(DUK_DDDPRINT("final month=%ld", (long) month)); + DUK_ASSERT(month >= 0 && month <= 11); + DUK_ASSERT(day >= 0 && day <= 31); + + /* Equivalent year mapping, used to avoid DST trouble when platform + * may fail to provide reasonable DST answers for dates outside the + * ordinary range (e.g. 1970-2038). An equivalent year has the same + * leap-year-ness as the original year and begins on the same weekday + * (Jan 1). + * + * The year 2038 is avoided because there seem to be problems with it + * on some platforms. The year 1970 is also avoided as there were + * practical problems with it; an equivalent year is used for it too, + * which breaks some DST computations for 1970 right now, see e.g. + * test-bi-date-tzoffset-brute-fi.js. + */ + if ((flags & DUK_DATE_FLAG_EQUIVYEAR) && (year < 1971 || year > 2037)) { + DUK_ASSERT(is_leap == 0 || is_leap == 1); + + jan1_since_epoch = day_since_epoch - day_in_year; /* day number for Jan 1 since epoch */ + DUK_ASSERT(jan1_since_epoch + DUK__WEEKDAY_MOD_ADDER >= 0); + jan1_weekday = (jan1_since_epoch + 4 + DUK__WEEKDAY_MOD_ADDER) % 7; /* E5.1 Section 15.9.1.6 */ + DUK_ASSERT(jan1_weekday >= 0 && jan1_weekday <= 6); + arridx = jan1_weekday; + if (is_leap) { + arridx += 7; + } + DUK_ASSERT(arridx >= 0 && arridx < (duk_small_int_t) (sizeof(duk__date_equivyear) / sizeof(duk_uint8_t))); + + equiv_year = (duk_int_t) duk__date_equivyear[arridx] + 1970; + year = equiv_year; + DUK_DDD(DUK_DDDPRINT("equiv year mapping, year=%ld, day_in_year=%ld, day_since_epoch=%ld, " + "jan1_since_epoch=%ld, jan1_weekday=%ld -> equiv year %ld", + (long) year, (long) day_in_year, (long) day_since_epoch, + (long) jan1_since_epoch, (long) jan1_weekday, (long) equiv_year)); + } + + parts[DUK_DATE_IDX_YEAR] = year; + parts[DUK_DATE_IDX_MONTH] = month; + parts[DUK_DATE_IDX_DAY] = day; + + if (flags & DUK_DATE_FLAG_ONEBASED) { + parts[DUK_DATE_IDX_MONTH]++; /* zero-based -> one-based */ + parts[DUK_DATE_IDX_DAY]++; /* -""- */ + } + + if (dparts != NULL) { + for (i = 0; i < DUK_DATE_IDX_NUM_PARTS; i++) { + dparts[i] = (duk_double_t) parts[i]; + } + } +} + +/* Compute time value from (double) parts. The parts can be either UTC + * or local time; if local, they need to be (conceptually) converted into + * UTC time. The parts may represent valid or invalid time, and may be + * wildly out of range (but may cancel each other and still come out in + * the valid Date range). + */ +DUK_INTERNAL duk_double_t duk_bi_date_get_timeval_from_dparts(duk_double_t *dparts, duk_small_uint_t flags) { +#if defined(DUK_USE_PARANOID_DATE_COMPUTATION) + /* See comments below on MakeTime why these are volatile. */ + volatile duk_double_t tmp_time; + volatile duk_double_t tmp_day; + volatile duk_double_t d; +#else + duk_double_t tmp_time; + duk_double_t tmp_day; + duk_double_t d; +#endif + duk_small_uint_t i; + duk_int_t tzoff, tzoffprev1, tzoffprev2; + + /* Expects 'this' at top of stack on entry. */ + + /* Coerce all finite parts with ToInteger(). ToInteger() must not + * be called for NaN/Infinity because it will convert e.g. NaN to + * zero. If ToInteger() has already been called, this has no side + * effects and is idempotent. + * + * Don't read dparts[DUK_DATE_IDX_WEEKDAY]; it will cause Valgrind + * issues if the value is uninitialized. + */ + for (i = 0; i <= DUK_DATE_IDX_MILLISECOND; i++) { + /* SCANBUILD: scan-build complains here about assigned value + * being garbage or undefined. This is correct but operating + * on undefined values has no ill effect and is ignored by the + * caller in the case where this happens. + */ + d = dparts[i]; + if (DUK_ISFINITE(d)) { + dparts[i] = duk_js_tointeger_number(d); + } + } + + /* Use explicit steps in computation to try to ensure that + * computation happens with intermediate results coerced to + * double values (instead of using something more accurate). + * E.g. E5.1 Section 15.9.1.11 requires use of IEEE 754 + * rules (= ECMAScript '+' and '*' operators). + * + * Without 'volatile' even this approach fails on some platform + * and compiler combinations. For instance, gcc 4.8.1 on Ubuntu + * 64-bit, with -m32 and without -std=c99, test-bi-date-canceling.js + * would fail because of some optimizations when computing tmp_time + * (MakeTime below). Adding 'volatile' to tmp_time solved this + * particular problem (annoyingly, also adding debug prints or + * running the executable under valgrind hides it). + */ + + /* MakeTime */ + tmp_time = 0.0; + tmp_time += dparts[DUK_DATE_IDX_HOUR] * ((duk_double_t) DUK_DATE_MSEC_HOUR); + tmp_time += dparts[DUK_DATE_IDX_MINUTE] * ((duk_double_t) DUK_DATE_MSEC_MINUTE); + tmp_time += dparts[DUK_DATE_IDX_SECOND] * ((duk_double_t) DUK_DATE_MSEC_SECOND); + tmp_time += dparts[DUK_DATE_IDX_MILLISECOND]; + + /* MakeDay */ + tmp_day = duk__make_day(dparts[DUK_DATE_IDX_YEAR], dparts[DUK_DATE_IDX_MONTH], dparts[DUK_DATE_IDX_DAY]); + + /* MakeDate */ + d = tmp_day * ((duk_double_t) DUK_DATE_MSEC_DAY) + tmp_time; + + DUK_DDD(DUK_DDDPRINT("time=%lf day=%lf --> timeval=%lf", + (double) tmp_time, (double) tmp_day, (double) d)); + + /* Optional UTC conversion. */ + if (flags & DUK_DATE_FLAG_LOCALTIME) { + /* DUK_USE_DATE_GET_LOCAL_TZOFFSET() needs to be called with a + * time value computed from UTC parts. At this point we only + * have 'd' which is a time value computed from local parts, so + * it is off by the UTC-to-local time offset which we don't know + * yet. The current solution for computing the UTC-to-local + * time offset is to iterate a few times and detect a fixed + * point or a two-cycle loop (or a sanity iteration limit), + * see test-bi-date-local-parts.js and test-bi-date-tzoffset-basic-fi.js. + * + * E5.1 Section 15.9.1.9: + * UTC(t) = t - LocalTZA - DaylightSavingTA(t - LocalTZA) + * + * For NaN/inf, DUK_USE_DATE_GET_LOCAL_TZOFFSET() returns 0. + */ + +#if 0 + /* Old solution: don't iterate, incorrect */ + tzoff = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d); + DUK_DDD(DUK_DDDPRINT("tzoffset w/o iteration, tzoff=%ld", (long) tzoff)); + d -= tzoff * 1000L; + DUK_UNREF(tzoffprev1); + DUK_UNREF(tzoffprev2); +#endif + + /* Iteration solution */ + tzoff = 0; + tzoffprev1 = 999999999L; /* invalid value which never matches */ + for (i = 0; i < DUK__LOCAL_TZOFFSET_MAXITER; i++) { + tzoffprev2 = tzoffprev1; + tzoffprev1 = tzoff; + tzoff = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d - tzoff * 1000L); + DUK_DDD(DUK_DDDPRINT("tzoffset iteration, i=%d, tzoff=%ld, tzoffprev1=%ld tzoffprev2=%ld", + (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2)); + if (tzoff == tzoffprev1) { + DUK_DDD(DUK_DDDPRINT("tzoffset iteration finished, i=%d, tzoff=%ld, tzoffprev1=%ld, tzoffprev2=%ld", + (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2)); + break; + } else if (tzoff == tzoffprev2) { + /* Two value cycle, see e.g. test-bi-date-tzoffset-basic-fi.js. + * In these cases, favor a higher tzoffset to get a consistent + * result which is independent of iteration count. Not sure if + * this is a generically correct solution. + */ + DUK_DDD(DUK_DDDPRINT("tzoffset iteration two-value cycle, i=%d, tzoff=%ld, tzoffprev1=%ld, tzoffprev2=%ld", + (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2)); + if (tzoffprev1 > tzoff) { + tzoff = tzoffprev1; + } + break; + } + } + DUK_DDD(DUK_DDDPRINT("tzoffset iteration, tzoff=%ld", (long) tzoff)); + d -= tzoff * 1000L; + } + + /* TimeClip(), which also handles Infinity -> NaN conversion */ + d = duk__timeclip(d); + + return d; +} + +/* + * API oriented helpers + */ + +/* Push 'this' binding, check that it is a Date object; then push the + * internal time value. At the end, stack is: [ ... this timeval ]. + * Returns the time value. Local time adjustment is done if requested. + */ +DUK_LOCAL duk_double_t duk__push_this_get_timeval_tzoffset(duk_hthread *thr, duk_small_uint_t flags, duk_int_t *out_tzoffset) { + duk_hobject *h; + duk_double_t d; + duk_int_t tzoffset = 0; + + duk_push_this(thr); + h = duk_get_hobject(thr, -1); /* XXX: getter with class check, useful in built-ins */ + if (h == NULL || DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_DATE) { + DUK_ERROR_TYPE(thr, "expected Date"); + DUK_WO_NORETURN(return 0.0;); + } + + duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE); + d = duk_to_number_m1(thr); + duk_pop(thr); + + if (DUK_ISNAN(d)) { + if (flags & DUK_DATE_FLAG_NAN_TO_ZERO) { + d = 0.0; + } + if (flags & DUK_DATE_FLAG_NAN_TO_RANGE_ERROR) { + DUK_ERROR_RANGE(thr, "Invalid Date"); + DUK_WO_NORETURN(return 0.0;); + } + } + /* if no NaN handling flag, may still be NaN here, but not Inf */ + DUK_ASSERT(!DUK_ISINF(d)); + + if (flags & DUK_DATE_FLAG_LOCALTIME) { + /* Note: DST adjustment is determined using UTC time. + * If 'd' is NaN, tzoffset will be 0. + */ + tzoffset = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d); /* seconds */ + d += tzoffset * 1000L; + } + if (out_tzoffset) { + *out_tzoffset = tzoffset; + } + + /* [ ... this ] */ + return d; +} + +DUK_LOCAL duk_double_t duk__push_this_get_timeval(duk_hthread *thr, duk_small_uint_t flags) { + return duk__push_this_get_timeval_tzoffset(thr, flags, NULL); +} + +/* Set timeval to 'this' from dparts, push the new time value onto the + * value stack and return 1 (caller can then tail call us). Expects + * the value stack to contain 'this' on the stack top. + */ +DUK_LOCAL duk_ret_t duk__set_this_timeval_from_dparts(duk_hthread *thr, duk_double_t *dparts, duk_small_uint_t flags) { + duk_double_t d; + + /* [ ... this ] */ + + d = duk_bi_date_get_timeval_from_dparts(dparts, flags); + duk_push_number(thr, d); /* -> [ ... this timeval_new ] */ + duk_dup_top(thr); /* -> [ ... this timeval_new timeval_new ] */ + + /* Must force write because e.g. .setYear() must work even when + * the Date instance is frozen. + */ + duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W); + + /* Stack top: new time value, return 1 to allow tail calls. */ + return 1; +} + +/* 'out_buf' must be at least DUK_BI_DATE_ISO8601_BUFSIZE long. */ +DUK_LOCAL void duk__format_parts_iso8601(duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags, duk_uint8_t *out_buf) { + char yearstr[8]; /* "-123456\0" */ + char tzstr[8]; /* "+11:22\0" */ + char sep = (flags & DUK_DATE_FLAG_SEP_T) ? DUK_ASC_UC_T : DUK_ASC_SPACE; + + DUK_ASSERT(parts[DUK_DATE_IDX_MONTH] >= 1 && parts[DUK_DATE_IDX_MONTH] <= 12); + DUK_ASSERT(parts[DUK_DATE_IDX_DAY] >= 1 && parts[DUK_DATE_IDX_DAY] <= 31); + DUK_ASSERT(parts[DUK_DATE_IDX_YEAR] >= -999999 && parts[DUK_DATE_IDX_YEAR] <= 999999); + + /* Note: %06d for positive value, %07d for negative value to include + * sign and 6 digits. + */ + DUK_SNPRINTF(yearstr, + sizeof(yearstr), + (parts[DUK_DATE_IDX_YEAR] >= 0 && parts[DUK_DATE_IDX_YEAR] <= 9999) ? "%04ld" : + ((parts[DUK_DATE_IDX_YEAR] >= 0) ? "+%06ld" : "%07ld"), + (long) parts[DUK_DATE_IDX_YEAR]); + yearstr[sizeof(yearstr) - 1] = (char) 0; + + if (flags & DUK_DATE_FLAG_LOCALTIME) { + /* tzoffset seconds are dropped; 16 bits suffice for + * time offset in minutes + */ + const char *fmt; + duk_small_int_t tmp, arg_hours, arg_minutes; + + if (tzoffset >= 0) { + tmp = tzoffset; + fmt = "+%02d:%02d"; + } else { + tmp = -tzoffset; + fmt = "-%02d:%02d"; + } + tmp = tmp / 60; + arg_hours = tmp / 60; + arg_minutes = tmp % 60; + DUK_ASSERT(arg_hours <= 24); /* Even less is actually guaranteed for a valid tzoffset. */ + arg_hours = arg_hours & 0x3f; /* For [0,24] this is a no-op, but fixes GCC 7 warning, see https://github.com/svaarala/duktape/issues/1602. */ + + DUK_SNPRINTF(tzstr, sizeof(tzstr), fmt, (int) arg_hours, (int) arg_minutes); + tzstr[sizeof(tzstr) - 1] = (char) 0; + } else { + tzstr[0] = DUK_ASC_UC_Z; + tzstr[1] = (char) 0; + } + + /* Unlike year, the other parts fit into 16 bits so %d format + * is portable. + */ + if ((flags & DUK_DATE_FLAG_TOSTRING_DATE) && (flags & DUK_DATE_FLAG_TOSTRING_TIME)) { + DUK_SPRINTF((char *) out_buf, "%s-%02d-%02d%c%02d:%02d:%02d.%03d%s", + (const char *) yearstr, (int) parts[DUK_DATE_IDX_MONTH], (int) parts[DUK_DATE_IDX_DAY], (int) sep, + (int) parts[DUK_DATE_IDX_HOUR], (int) parts[DUK_DATE_IDX_MINUTE], + (int) parts[DUK_DATE_IDX_SECOND], (int) parts[DUK_DATE_IDX_MILLISECOND], (const char *) tzstr); + } else if (flags & DUK_DATE_FLAG_TOSTRING_DATE) { + DUK_SPRINTF((char *) out_buf, "%s-%02d-%02d", + (const char *) yearstr, (int) parts[DUK_DATE_IDX_MONTH], (int) parts[DUK_DATE_IDX_DAY]); + } else { + DUK_ASSERT(flags & DUK_DATE_FLAG_TOSTRING_TIME); + DUK_SPRINTF((char *) out_buf, "%02d:%02d:%02d.%03d%s", + (int) parts[DUK_DATE_IDX_HOUR], (int) parts[DUK_DATE_IDX_MINUTE], + (int) parts[DUK_DATE_IDX_SECOND], (int) parts[DUK_DATE_IDX_MILLISECOND], + (const char *) tzstr); + } +} + +/* Helper for string conversion calls: check 'this' binding, get the + * internal time value, and format date and/or time in a few formats. + * Return value allows tail calls. + */ +DUK_LOCAL duk_ret_t duk__to_string_helper(duk_hthread *thr, duk_small_uint_t flags) { + duk_double_t d; + duk_int_t parts[DUK_DATE_IDX_NUM_PARTS]; + duk_int_t tzoffset; /* seconds, doesn't fit into 16 bits */ + duk_bool_t rc; + duk_uint8_t buf[DUK_BI_DATE_ISO8601_BUFSIZE]; + + tzoffset = 0; /* ffs guys */ + DUK_UNREF(rc); /* unreferenced with some options */ + + d = duk__push_this_get_timeval_tzoffset(thr, flags, &tzoffset); + if (DUK_ISNAN(d)) { + duk_push_hstring_stridx(thr, DUK_STRIDX_INVALID_DATE); + return 1; + } + DUK_ASSERT(DUK_ISFINITE(d)); + + /* formatters always get one-based month/day-of-month */ + duk_bi_date_timeval_to_parts(d, parts, NULL, DUK_DATE_FLAG_ONEBASED); + DUK_ASSERT(parts[DUK_DATE_IDX_MONTH] >= 1 && parts[DUK_DATE_IDX_MONTH] <= 12); + DUK_ASSERT(parts[DUK_DATE_IDX_DAY] >= 1 && parts[DUK_DATE_IDX_DAY] <= 31); + + if (flags & DUK_DATE_FLAG_TOSTRING_LOCALE) { + /* try locale specific formatter; if it refuses to format the + * string, fall back to an ISO 8601 formatted value in local + * time. + */ +#if defined(DUK_USE_DATE_FORMAT_STRING) + /* Contract, either: + * - Push string to value stack and return 1 + * - Don't push anything and return 0 + */ + + rc = DUK_USE_DATE_FORMAT_STRING(thr, parts, tzoffset, flags); + if (rc != 0) { + return 1; + } +#else + /* No locale specific formatter; this is OK, we fall back + * to ISO 8601. + */ +#endif + } + + /* Different calling convention than above used because the helper + * is shared. + */ + duk__format_parts_iso8601(parts, tzoffset, flags, buf); + duk_push_string(thr, (const char *) buf); + return 1; +} + +/* Helper for component getter calls: check 'this' binding, get the + * internal time value, split it into parts (either as UTC time or + * local time), push a specified component as a return value to the + * value stack and return 1 (caller can then tail call us). + */ +DUK_LOCAL duk_ret_t duk__get_part_helper(duk_hthread *thr, duk_small_uint_t flags_and_idx) { + duk_double_t d; + duk_int_t parts[DUK_DATE_IDX_NUM_PARTS]; + duk_small_uint_t idx_part = (duk_small_uint_t) (flags_and_idx >> DUK_DATE_FLAG_VALUE_SHIFT); /* unpack args */ + + DUK_ASSERT_DISABLE(idx_part >= 0); /* unsigned */ + DUK_ASSERT(idx_part < DUK_DATE_IDX_NUM_PARTS); + + d = duk__push_this_get_timeval(thr, flags_and_idx); + if (DUK_ISNAN(d)) { + duk_push_nan(thr); + return 1; + } + DUK_ASSERT(DUK_ISFINITE(d)); + + duk_bi_date_timeval_to_parts(d, parts, NULL, flags_and_idx); /* no need to mask idx portion */ + + /* Setter APIs detect special year numbers (0...99) and apply a +1900 + * only in certain cases. The legacy getYear() getter applies -1900 + * unconditionally. + */ + duk_push_int(thr, (flags_and_idx & DUK_DATE_FLAG_SUB1900) ? parts[idx_part] - 1900 : parts[idx_part]); + return 1; +} + +/* Helper for component setter calls: check 'this' binding, get the + * internal time value, split it into parts (either as UTC time or + * local time), modify one or more components as specified, recompute + * the time value, set it as the internal value. Finally, push the + * new time value as a return value to the value stack and return 1 + * (caller can then tail call us). + */ +DUK_LOCAL duk_ret_t duk__set_part_helper(duk_hthread *thr, duk_small_uint_t flags_and_maxnargs) { + duk_double_t d; + duk_int_t parts[DUK_DATE_IDX_NUM_PARTS]; + duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS]; + duk_idx_t nargs; + duk_small_uint_t maxnargs = (duk_small_uint_t) (flags_and_maxnargs >> DUK_DATE_FLAG_VALUE_SHIFT); /* unpack args */ + duk_small_uint_t idx_first, idx; + duk_small_uint_t i; + + nargs = duk_get_top(thr); + d = duk__push_this_get_timeval(thr, flags_and_maxnargs); + DUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d)); + + if (DUK_ISFINITE(d)) { + duk_bi_date_timeval_to_parts(d, parts, dparts, flags_and_maxnargs); + } else { + /* NaN timevalue: we need to coerce the arguments, but + * the resulting internal timestamp needs to remain NaN. + * This works but is not pretty: parts and dparts will + * be partially uninitialized, but we only write to them. + */ + } + + /* + * Determining which datetime components to overwrite based on + * stack arguments is a bit complicated, but important to factor + * out from setters themselves for compactness. + * + * If DUK_DATE_FLAG_TIMESETTER, maxnargs indicates setter type: + * + * 1 -> millisecond + * 2 -> second, [millisecond] + * 3 -> minute, [second], [millisecond] + * 4 -> hour, [minute], [second], [millisecond] + * + * Else: + * + * 1 -> date + * 2 -> month, [date] + * 3 -> year, [month], [date] + * + * By comparing nargs and maxnargs (and flags) we know which + * components to override. We rely on part index ordering. + */ + + if (flags_and_maxnargs & DUK_DATE_FLAG_TIMESETTER) { + DUK_ASSERT(maxnargs >= 1 && maxnargs <= 4); + idx_first = DUK_DATE_IDX_MILLISECOND - (maxnargs - 1); + } else { + DUK_ASSERT(maxnargs >= 1 && maxnargs <= 3); + idx_first = DUK_DATE_IDX_DAY - (maxnargs - 1); + } + DUK_ASSERT_DISABLE(idx_first >= 0); /* unsigned */ + DUK_ASSERT(idx_first < DUK_DATE_IDX_NUM_PARTS); + + for (i = 0; i < maxnargs; i++) { + if ((duk_idx_t) i >= nargs) { + /* no argument given -> leave components untouched */ + break; + } + idx = idx_first + i; + DUK_ASSERT_DISABLE(idx >= 0); /* unsigned */ + DUK_ASSERT(idx < DUK_DATE_IDX_NUM_PARTS); + + if (idx == DUK_DATE_IDX_YEAR && (flags_and_maxnargs & DUK_DATE_FLAG_YEAR_FIXUP)) { + duk__twodigit_year_fixup(thr, (duk_idx_t) i); + } + + dparts[idx] = duk_to_number(thr, (duk_idx_t) i); + + if (idx == DUK_DATE_IDX_DAY) { + /* Day-of-month is one-based in the API, but zero-based + * internally, so fix here. Note that month is zero-based + * both in the API and internally. + */ + /* SCANBUILD: complains about use of uninitialized values. + * The complaint is correct, but operating in undefined + * values here is intentional in some cases and the caller + * ignores the results. + */ + dparts[idx] -= 1.0; + } + } + + /* Leaves new timevalue on stack top and returns 1, which is correct + * for part setters. + */ + if (DUK_ISFINITE(d)) { + return duk__set_this_timeval_from_dparts(thr, dparts, flags_and_maxnargs); + } else { + /* Internal timevalue is already NaN, so don't touch it. */ + duk_push_nan(thr); + return 1; + } +} + +/* Apply ToNumber() to specified index; if ToInteger(val) in [0,99], add + * 1900 and replace value at idx_val. + */ +DUK_LOCAL void duk__twodigit_year_fixup(duk_hthread *thr, duk_idx_t idx_val) { + duk_double_t d; + + /* XXX: idx_val would fit into 16 bits, but using duk_small_uint_t + * might not generate better code due to casting. + */ + + /* E5 Sections 15.9.3.1, B.2.4, B.2.5 */ + duk_to_number(thr, idx_val); + if (duk_is_nan(thr, idx_val)) { + return; + } + duk_dup(thr, idx_val); + duk_to_int(thr, -1); + d = duk_get_number(thr, -1); /* get as double to handle huge numbers correctly */ + if (d >= 0.0 && d <= 99.0) { + d += 1900.0; + duk_push_number(thr, d); + duk_replace(thr, idx_val); + } + duk_pop(thr); +} + +/* Set datetime parts from stack arguments, defaulting any missing values. + * Day-of-week is not set; it is not required when setting the time value. + */ +DUK_LOCAL void duk__set_parts_from_args(duk_hthread *thr, duk_double_t *dparts, duk_idx_t nargs) { + duk_double_t d; + duk_small_uint_t i; + duk_small_uint_t idx; + + /* Causes a ToNumber() coercion, but doesn't break coercion order since + * year is coerced first anyway. + */ + duk__twodigit_year_fixup(thr, 0); + + /* There are at most 7 args, but we use 8 here so that also + * DUK_DATE_IDX_WEEKDAY gets initialized (to zero) to avoid the potential + * for any Valgrind gripes later. + */ + for (i = 0; i < 8; i++) { + /* Note: rely on index ordering */ + idx = DUK_DATE_IDX_YEAR + i; + if ((duk_idx_t) i < nargs) { + d = duk_to_number(thr, (duk_idx_t) i); + if (idx == DUK_DATE_IDX_DAY) { + /* Convert day from one-based to zero-based (internal). This may + * cause the day part to be negative, which is OK. + */ + d -= 1.0; + } + } else { + /* All components default to 0 except day-of-month which defaults + * to 1. However, because our internal day-of-month is zero-based, + * it also defaults to zero here. + */ + d = 0.0; + } + dparts[idx] = d; + } + + DUK_DDD(DUK_DDDPRINT("parts from args -> %lf %lf %lf %lf %lf %lf %lf %lf", + (double) dparts[0], (double) dparts[1], + (double) dparts[2], (double) dparts[3], + (double) dparts[4], (double) dparts[5], + (double) dparts[6], (double) dparts[7])); +} + +/* + * Indirect magic value lookup for Date methods. + * + * Date methods don't put their control flags into the function magic value + * because they wouldn't fit into a LIGHTFUNC's magic field. Instead, the + * magic value is set to an index pointing to the array of control flags + * below. + * + * This must be kept in strict sync with genbuiltins.py! + */ + +static duk_uint16_t duk__date_magics[] = { + /* 0: toString */ + DUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_LOCALTIME, + + /* 1: toDateString */ + DUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_LOCALTIME, + + /* 2: toTimeString */ + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_LOCALTIME, + + /* 3: toLocaleString */ + DUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME, + + /* 4: toLocaleDateString */ + DUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME, + + /* 5: toLocaleTimeString */ + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME, + + /* 6: toUTCString */ + DUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME, + + /* 7: toISOString */ + DUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_NAN_TO_RANGE_ERROR + DUK_DATE_FLAG_SEP_T, + + /* 8: getFullYear */ + DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 9: getUTCFullYear */ + 0 + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 10: getMonth */ + DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MONTH << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 11: getUTCMonth */ + 0 + (DUK_DATE_IDX_MONTH << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 12: getDate */ + DUK_DATE_FLAG_ONEBASED + DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_DAY << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 13: getUTCDate */ + DUK_DATE_FLAG_ONEBASED + (DUK_DATE_IDX_DAY << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 14: getDay */ + DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_WEEKDAY << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 15: getUTCDay */ + 0 + (DUK_DATE_IDX_WEEKDAY << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 16: getHours */ + DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_HOUR << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 17: getUTCHours */ + 0 + (DUK_DATE_IDX_HOUR << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 18: getMinutes */ + DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MINUTE << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 19: getUTCMinutes */ + 0 + (DUK_DATE_IDX_MINUTE << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 20: getSeconds */ + DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_SECOND << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 21: getUTCSeconds */ + 0 + (DUK_DATE_IDX_SECOND << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 22: getMilliseconds */ + DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MILLISECOND << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 23: getUTCMilliseconds */ + 0 + (DUK_DATE_IDX_MILLISECOND << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 24: setMilliseconds */ + DUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (1 << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 25: setUTCMilliseconds */ + DUK_DATE_FLAG_TIMESETTER + (1 << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 26: setSeconds */ + DUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (2 << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 27: setUTCSeconds */ + DUK_DATE_FLAG_TIMESETTER + (2 << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 28: setMinutes */ + DUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (3 << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 29: setUTCMinutes */ + DUK_DATE_FLAG_TIMESETTER + (3 << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 30: setHours */ + DUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (4 << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 31: setUTCHours */ + DUK_DATE_FLAG_TIMESETTER + (4 << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 32: setDate */ + DUK_DATE_FLAG_LOCALTIME + (1 << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 33: setUTCDate */ + 0 + (1 << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 34: setMonth */ + DUK_DATE_FLAG_LOCALTIME + (2 << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 35: setUTCMonth */ + 0 + (2 << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 36: setFullYear */ + DUK_DATE_FLAG_NAN_TO_ZERO + DUK_DATE_FLAG_LOCALTIME + (3 << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 37: setUTCFullYear */ + DUK_DATE_FLAG_NAN_TO_ZERO + (3 << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 38: getYear */ + DUK_DATE_FLAG_LOCALTIME + DUK_DATE_FLAG_SUB1900 + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT), + + /* 39: setYear */ + DUK_DATE_FLAG_NAN_TO_ZERO + DUK_DATE_FLAG_YEAR_FIXUP + (3 << DUK_DATE_FLAG_VALUE_SHIFT), +}; + +DUK_LOCAL duk_small_uint_t duk__date_get_indirect_magic(duk_hthread *thr) { + duk_small_uint_t magicidx = (duk_small_uint_t) duk_get_current_magic(thr); + DUK_ASSERT(magicidx < (duk_small_int_t) (sizeof(duk__date_magics) / sizeof(duk_uint16_t))); + return (duk_small_uint_t) duk__date_magics[magicidx]; +} + +#if defined(DUK_USE_DATE_BUILTIN) +/* + * Constructor calls + */ + +DUK_INTERNAL duk_ret_t duk_bi_date_constructor(duk_hthread *thr) { + duk_idx_t nargs = duk_get_top(thr); + duk_bool_t is_cons = duk_is_constructor_call(thr); + duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS]; + duk_double_t d; + + DUK_DDD(DUK_DDDPRINT("Date constructor, nargs=%ld, is_cons=%ld", (long) nargs, (long) is_cons)); + + (void) duk_push_object_helper(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DATE), + DUK_BIDX_DATE_PROTOTYPE); + + /* Unlike most built-ins, the internal [[PrimitiveValue]] of a Date + * is mutable. + */ + + if (nargs == 0 || !is_cons) { + d = duk__timeclip(duk_time_get_ecmascript_time_nofrac(thr)); + duk_push_number(thr, d); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W); + if (!is_cons) { + /* called as a normal function: return new Date().toString() */ + duk_to_string(thr, -1); + } + return 1; + } else if (nargs == 1) { + const char *str; + duk_to_primitive(thr, 0, DUK_HINT_NONE); + str = duk_get_string_notsymbol(thr, 0); + if (str) { + duk__parse_string(thr, str); + duk_replace(thr, 0); /* may be NaN */ + } + d = duk__timeclip(duk_to_number(thr, 0)); /* symbols fail here */ + duk_push_number(thr, d); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W); + return 1; + } + + duk__set_parts_from_args(thr, dparts, nargs); + + /* Parts are in local time, convert when setting. */ + + (void) duk__set_this_timeval_from_dparts(thr, dparts, DUK_DATE_FLAG_LOCALTIME /*flags*/); /* -> [ ... this timeval ] */ + duk_pop(thr); /* -> [ ... this ] */ + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_date_constructor_parse(duk_hthread *thr) { + return duk__parse_string(thr, duk_to_string(thr, 0)); +} + +DUK_INTERNAL duk_ret_t duk_bi_date_constructor_utc(duk_hthread *thr) { + duk_idx_t nargs = duk_get_top(thr); + duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS]; + duk_double_t d; + + /* Behavior for nargs < 2 is implementation dependent: currently we'll + * set a NaN time value (matching V8 behavior) in this case. + */ + + if (nargs < 2) { + duk_push_nan(thr); + } else { + duk__set_parts_from_args(thr, dparts, nargs); + d = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/); + duk_push_number(thr, d); + } + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_date_constructor_now(duk_hthread *thr) { + duk_double_t d; + + d = duk_time_get_ecmascript_time_nofrac(thr); + DUK_ASSERT(duk_double_equals(duk__timeclip(d), d)); /* TimeClip() should never be necessary */ + duk_push_number(thr, d); + return 1; +} + +/* + * String/JSON conversions + * + * Human readable conversions are now basically ISO 8601 with a space + * (instead of 'T') as the date/time separator. This is a good baseline + * and is platform independent. + * + * A shared native helper to provide many conversions. Magic value contains + * a set of flags. The helper provides: + * + * toString() + * toDateString() + * toTimeString() + * toLocaleString() + * toLocaleDateString() + * toLocaleTimeString() + * toUTCString() + * toISOString() + * + * Notes: + * + * - Date.prototype.toGMTString() and Date.prototype.toUTCString() are + * required to be the same ECMAScript function object (!), so it is + * omitted from here. + * + * - Date.prototype.toUTCString(): E5.1 specification does not require a + * specific format, but result should be human readable. The + * specification suggests using ISO 8601 format with a space (instead + * of 'T') separator if a more human readable format is not available. + * + * - Date.prototype.toISOString(): unlike other conversion functions, + * toISOString() requires a RangeError for invalid date values. + */ + +DUK_INTERNAL duk_ret_t duk_bi_date_prototype_tostring_shared(duk_hthread *thr) { + duk_small_uint_t flags = duk__date_get_indirect_magic(thr); + return duk__to_string_helper(thr, flags); +} + +DUK_INTERNAL duk_ret_t duk_bi_date_prototype_value_of(duk_hthread *thr) { + /* This native function is also used for Date.prototype.getTime() + * as their behavior is identical. + */ + + duk_double_t d = duk__push_this_get_timeval(thr, 0 /*flags*/); /* -> [ this ] */ + DUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d)); + duk_push_number(thr, d); + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_date_prototype_to_json(duk_hthread *thr) { + /* Note: toJSON() is a generic function which works even if 'this' + * is not a Date. The sole argument is ignored. + */ + + duk_push_this(thr); + duk_to_object(thr, -1); + + duk_dup_top(thr); + duk_to_primitive(thr, -1, DUK_HINT_NUMBER); + if (duk_is_number(thr, -1)) { + duk_double_t d = duk_get_number(thr, -1); + if (!DUK_ISFINITE(d)) { + duk_push_null(thr); + return 1; + } + } + duk_pop(thr); + + duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_ISO_STRING); + duk_dup_m2(thr); /* -> [ O toIsoString O ] */ + duk_call_method(thr, 0); + return 1; +} + +/* + * Getters. + * + * Implementing getters is quite easy. The internal time value is either + * NaN, or represents milliseconds (without fractions) from Jan 1, 1970. + * The internal time value can be converted to integer parts, and each + * part will be normalized and will fit into a 32-bit signed integer. + * + * A shared native helper to provide all getters. Magic value contains + * a set of flags and also packs the date component index argument. The + * helper provides: + * + * getFullYear() + * getUTCFullYear() + * getMonth() + * getUTCMonth() + * getDate() + * getUTCDate() + * getDay() + * getUTCDay() + * getHours() + * getUTCHours() + * getMinutes() + * getUTCMinutes() + * getSeconds() + * getUTCSeconds() + * getMilliseconds() + * getUTCMilliseconds() + * getYear() + * + * Notes: + * + * - Date.prototype.getDate(): 'date' means day-of-month, and is + * zero-based in internal calculations but public API expects it to + * be one-based. + * + * - Date.prototype.getTime() and Date.prototype.valueOf() have identical + * behavior. They have separate function objects, but share the same C + * function (duk_bi_date_prototype_value_of). + */ + +DUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_shared(duk_hthread *thr) { + duk_small_uint_t flags_and_idx = duk__date_get_indirect_magic(thr); + return duk__get_part_helper(thr, flags_and_idx); +} + +DUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_timezone_offset(duk_hthread *thr) { + /* + * Return (t - LocalTime(t)) in minutes: + * + * t - LocalTime(t) = t - (t + LocalTZA + DaylightSavingTA(t)) + * = -(LocalTZA + DaylightSavingTA(t)) + * + * where DaylightSavingTA() is checked for time 't'. + * + * Note that the sign of the result is opposite to common usage, + * e.g. for EE(S)T which normally is +2h or +3h from UTC, this + * function returns -120 or -180. + * + */ + + duk_double_t d; + duk_int_t tzoffset; + + /* Note: DST adjustment is determined using UTC time. */ + d = duk__push_this_get_timeval(thr, 0 /*flags*/); + DUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d)); + if (DUK_ISNAN(d)) { + duk_push_nan(thr); + } else { + DUK_ASSERT(DUK_ISFINITE(d)); + tzoffset = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d); + duk_push_int(thr, -tzoffset / 60); + } + return 1; +} + +/* + * Setters. + * + * Setters are a bit more complicated than getters. Component setters + * break down the current time value into its (normalized) component + * parts, replace one or more components with -unnormalized- new values, + * and the components are then converted back into a time value. As an + * example of using unnormalized values: + * + * var d = new Date(1234567890); + * + * is equivalent to: + * + * var d = new Date(0); + * d.setUTCMilliseconds(1234567890); + * + * A shared native helper to provide almost all setters. Magic value + * contains a set of flags and also packs the "maxnargs" argument. The + * helper provides: + * + * setMilliseconds() + * setUTCMilliseconds() + * setSeconds() + * setUTCSeconds() + * setMinutes() + * setUTCMinutes() + * setHours() + * setUTCHours() + * setDate() + * setUTCDate() + * setMonth() + * setUTCMonth() + * setFullYear() + * setUTCFullYear() + * setYear() + * + * Notes: + * + * - Date.prototype.setYear() (Section B addition): special year check + * is omitted. NaN / Infinity will just flow through and ultimately + * result in a NaN internal time value. + * + * - Date.prototype.setYear() does not have optional arguments for + * setting month and day-in-month (like setFullYear()), but we indicate + * 'maxnargs' to be 3 to get the year written to the correct component + * index in duk__set_part_helper(). The function has nargs == 1, so only + * the year will be set regardless of actual argument count. + */ + +DUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_shared(duk_hthread *thr) { + duk_small_uint_t flags_and_maxnargs = duk__date_get_indirect_magic(thr); + return duk__set_part_helper(thr, flags_and_maxnargs); +} + +DUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_time(duk_hthread *thr) { + duk_double_t d; + + (void) duk__push_this_get_timeval(thr, 0 /*flags*/); /* -> [ timeval this ] */ + d = duk__timeclip(duk_to_number(thr, 0)); + duk_push_number(thr, d); + duk_dup_top(thr); + /* Must force write because .setTime() must work even when + * the Date instance is frozen. + */ + duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W); + /* -> [ timeval this timeval ] */ + + return 1; +} + +/* + * Misc. + */ + +#if defined(DUK_USE_SYMBOL_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_date_prototype_toprimitive(duk_hthread *thr) { + duk_size_t hintlen; + const char *hintstr; + duk_int_t hint; + + /* Invokes OrdinaryToPrimitive() with suitable hint. Note that the + * method is generic, and works on non-Date arguments too. + * + * https://www.ecma-international.org/ecma-262/6.0/#sec-date.prototype-@@toprimitive + */ + + duk_push_this(thr); + duk_require_object(thr, -1); + DUK_ASSERT_TOP(thr, 2); + + hintstr = duk_require_lstring(thr, 0, &hintlen); + if ((hintlen == 6 && DUK_STRCMP(hintstr, "string") == 0) || + (hintlen == 7 && DUK_STRCMP(hintstr, "default") == 0)) { + hint = DUK_HINT_STRING; + } else if (hintlen == 6 && DUK_STRCMP(hintstr, "number") == 0) { + hint = DUK_HINT_NUMBER; + } else { + DUK_DCERROR_TYPE_INVALID_ARGS(thr); + } + + duk_to_primitive_ordinary(thr, -1, hint); + return 1; +} +#endif /* DUK_USE_SYMBOL_BUILTIN */ + +#endif /* DUK_USE_DATE_BUILTIN */ diff --git a/third_party/duktape/duk_bi_date_unix.c b/third_party/duktape/duk_bi_date_unix.c new file mode 100644 index 00000000..e69dbcfc --- /dev/null +++ b/third_party/duktape/duk_bi_date_unix.c @@ -0,0 +1,325 @@ +/* + * Unix-like Date providers + * + * Generally useful Unix / POSIX / ANSI Date providers. + */ + +#include "third_party/duktape/duk_internal.h" + +/* The necessary #includes are in place in duk_config.h. */ + +/* Buffer sizes for some UNIX calls. Larger than strictly necessary + * to avoid Valgrind errors. + */ +#define DUK__STRPTIME_BUF_SIZE 64 +#define DUK__STRFTIME_BUF_SIZE 64 + +#if defined(DUK_USE_DATE_NOW_GETTIMEOFDAY) +/* Get current ECMAScript time (= UNIX/Posix time, but in milliseconds). */ +DUK_INTERNAL duk_double_t duk_bi_date_get_now_gettimeofday(void) { + struct timeval tv; + duk_double_t d; + + if (gettimeofday(&tv, NULL) != 0) { + DUK_D(DUK_DPRINT("gettimeofday() failed")); + return 0.0; + } + + /* As of Duktape 2.2.0 allow fractions. */ + d = ((duk_double_t) tv.tv_sec) * 1000.0 + + ((duk_double_t) tv.tv_usec) / 1000.0; + + return d; +} +#endif /* DUK_USE_DATE_NOW_GETTIMEOFDAY */ + +#if defined(DUK_USE_DATE_NOW_TIME) +/* Not a very good provider: only full seconds are available. */ +DUK_INTERNAL duk_double_t duk_bi_date_get_now_time(void) { + time_t t; + + t = time(NULL); + if (t == (time_t) -1) { + DUK_D(DUK_DPRINT("time() failed")); + return 0.0; + } + return ((duk_double_t) t) * 1000.0; +} +#endif /* DUK_USE_DATE_NOW_TIME */ + +#if defined(DUK_USE_DATE_TZO_GMTIME) || defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME_S) +/* Get local time offset (in seconds) for a certain (UTC) instant 'd'. */ +DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d) { + time_t t, t1, t2; + duk_int_t parts[DUK_DATE_IDX_NUM_PARTS]; + duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS]; + struct tm tms[2]; +#if defined(DUK_USE_DATE_TZO_GMTIME) + struct tm *tm_ptr; +#endif + + /* For NaN/inf, the return value doesn't matter. */ + if (!DUK_ISFINITE(d)) { + return 0; + } + + /* If not within ECMAScript range, some integer time calculations + * won't work correctly (and some asserts will fail), so bail out + * if so. This fixes test-bug-date-insane-setyear.js. There is + * a +/- 24h leeway in this range check to avoid a test262 corner + * case documented in test-bug-date-timeval-edges.js. + */ + if (!duk_bi_date_timeval_in_leeway_range(d)) { + DUK_DD(DUK_DDPRINT("timeval not within valid range, skip tzoffset computation to avoid integer overflows")); + return 0; + } + + /* + * This is a bit tricky to implement portably. The result depends + * on the timestamp (specifically, DST depends on the timestamp). + * If e.g. UNIX APIs are used, they'll have portability issues with + * very small and very large years. + * + * Current approach: + * + * - Stay within portable UNIX limits by using equivalent year mapping. + * Avoid year 1970 and 2038 as some conversions start to fail, at + * least on some platforms. Avoiding 1970 means that there are + * currently DST discrepancies for 1970. + * + * - Create a UTC and local time breakdowns from 't'. Then create + * a time_t using gmtime() and localtime() and compute the time + * difference between the two. + * + * Equivalent year mapping (E5 Section 15.9.1.8): + * + * If the host environment provides functionality for determining + * daylight saving time, the implementation of ECMAScript is free + * to map the year in question to an equivalent year (same + * leap-year-ness and same starting week day for the year) for which + * the host environment provides daylight saving time information. + * The only restriction is that all equivalent years should produce + * the same result. + * + * This approach is quite reasonable but not entirely correct, e.g. + * the specification also states (E5 Section 15.9.1.8): + * + * The implementation of ECMAScript should not try to determine + * whether the exact time was subject to daylight saving time, but + * just whether daylight saving time would have been in effect if + * the _current daylight saving time algorithm_ had been used at the + * time. This avoids complications such as taking into account the + * years that the locale observed daylight saving time year round. + * + * Since we rely on the platform APIs for conversions between local + * time and UTC, we can't guarantee the above. Rather, if the platform + * has historical DST rules they will be applied. This seems to be the + * general preferred direction in ECMAScript standardization (or at least + * implementations) anyway, and even the equivalent year mapping should + * be disabled if the platform is known to handle DST properly for the + * full ECMAScript range. + * + * The following has useful discussion and links: + * + * https://bugzilla.mozilla.org/show_bug.cgi?id=351066 + */ + + duk_bi_date_timeval_to_parts(d, parts, dparts, DUK_DATE_FLAG_EQUIVYEAR /*flags*/); + DUK_ASSERT(parts[DUK_DATE_IDX_YEAR] >= 1970 && parts[DUK_DATE_IDX_YEAR] <= 2038); + + d = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/); + DUK_ASSERT(d >= 0 && d < 2147483648.0 * 1000.0); /* unsigned 31-bit range */ + t = (time_t) (d / 1000.0); + DUK_DDD(DUK_DDDPRINT("timeval: %lf -> time_t %ld", (double) d, (long) t)); + + duk_memzero((void *) tms, sizeof(struct tm) * 2); + +#if defined(DUK_USE_DATE_TZO_GMTIME_R) + (void) gmtime_r(&t, &tms[0]); + (void) localtime_r(&t, &tms[1]); +#elif defined(DUK_USE_DATE_TZO_GMTIME_S) + (void) gmtime_s(&t, &tms[0]); + (void) localtime_s(&t, &tms[1]); +#elif defined(DUK_USE_DATE_TZO_GMTIME) + tm_ptr = gmtime(&t); + duk_memcpy((void *) &tms[0], tm_ptr, sizeof(struct tm)); + tm_ptr = localtime(&t); + duk_memcpy((void *) &tms[1], tm_ptr, sizeof(struct tm)); +#else +#error internal error +#endif + DUK_DDD(DUK_DDDPRINT("gmtime result: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld," + "wday:%ld,yday:%ld,isdst:%ld}", + (long) tms[0].tm_sec, (long) tms[0].tm_min, (long) tms[0].tm_hour, + (long) tms[0].tm_mday, (long) tms[0].tm_mon, (long) tms[0].tm_year, + (long) tms[0].tm_wday, (long) tms[0].tm_yday, (long) tms[0].tm_isdst)); + DUK_DDD(DUK_DDDPRINT("localtime result: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld," + "wday:%ld,yday:%ld,isdst:%ld}", + (long) tms[1].tm_sec, (long) tms[1].tm_min, (long) tms[1].tm_hour, + (long) tms[1].tm_mday, (long) tms[1].tm_mon, (long) tms[1].tm_year, + (long) tms[1].tm_wday, (long) tms[1].tm_yday, (long) tms[1].tm_isdst)); + + /* tm_isdst is both an input and an output to mktime(), use 0 to + * avoid DST handling in mktime(): + * - https://github.com/svaarala/duktape/issues/406 + * - http://stackoverflow.com/questions/8558919/mktime-and-tm-isdst + */ + tms[0].tm_isdst = 0; + tms[1].tm_isdst = 0; + t1 = mktime(&tms[0]); /* UTC */ + t2 = mktime(&tms[1]); /* local */ + if (t1 == (time_t) -1 || t2 == (time_t) -1) { + /* This check used to be for (t < 0) but on some platforms + * time_t is unsigned and apparently the proper way to detect + * an mktime() error return is the cast above. See e.g.: + * http://pubs.opengroup.org/onlinepubs/009695299/functions/mktime.html + */ + goto mktime_error; + } + DUK_DDD(DUK_DDDPRINT("t1=%ld (utc), t2=%ld (local)", (long) t1, (long) t2)); + + /* Compute final offset in seconds, positive if local time ahead of + * UTC (returned value is UTC-to-local offset). + * + * difftime() returns a double, so coercion to int generates quite + * a lot of code. Direct subtraction is not portable, however. + * XXX: allow direct subtraction on known platforms. + */ +#if 0 + return (duk_int_t) (t2 - t1); +#endif + return (duk_int_t) difftime(t2, t1); + + mktime_error: + /* XXX: return something more useful, so that caller can throw? */ + DUK_D(DUK_DPRINT("mktime() failed, d=%lf", (double) d)); + return 0; +} +#endif /* DUK_USE_DATE_TZO_GMTIME */ + +#if defined(DUK_USE_DATE_PRS_STRPTIME) +DUK_INTERNAL duk_bool_t duk_bi_date_parse_string_strptime(duk_hthread *thr, const char *str) { + struct tm tm; + time_t t; + char buf[DUK__STRPTIME_BUF_SIZE]; + + /* Copy to buffer with slack to avoid Valgrind gripes from strptime. */ + DUK_ASSERT(str != NULL); + duk_memzero(buf, sizeof(buf)); /* valgrind whine without this */ + DUK_SNPRINTF(buf, sizeof(buf), "%s", (const char *) str); + buf[sizeof(buf) - 1] = (char) 0; + + DUK_DDD(DUK_DDDPRINT("parsing: '%s'", (const char *) buf)); + + duk_memzero(&tm, sizeof(tm)); + if (strptime((const char *) buf, "%c", &tm) != NULL) { + DUK_DDD(DUK_DDDPRINT("before mktime: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld," + "wday:%ld,yday:%ld,isdst:%ld}", + (long) tm.tm_sec, (long) tm.tm_min, (long) tm.tm_hour, + (long) tm.tm_mday, (long) tm.tm_mon, (long) tm.tm_year, + (long) tm.tm_wday, (long) tm.tm_yday, (long) tm.tm_isdst)); + tm.tm_isdst = -1; /* negative: dst info not available */ + + t = mktime(&tm); + DUK_DDD(DUK_DDDPRINT("mktime() -> %ld", (long) t)); + if (t >= 0) { + duk_push_number(thr, ((duk_double_t) t) * 1000.0); + return 1; + } + } + + return 0; +} +#endif /* DUK_USE_DATE_PRS_STRPTIME */ + +#if defined(DUK_USE_DATE_PRS_GETDATE) +DUK_INTERNAL duk_bool_t duk_bi_date_parse_string_getdate(duk_hthread *thr, const char *str) { + struct tm tm; + duk_small_int_t rc; + time_t t; + + /* For this to work, DATEMSK must be set, so this is not very + * convenient for an embeddable interpreter. + */ + + duk_memzero(&tm, sizeof(struct tm)); + rc = (duk_small_int_t) getdate_r(str, &tm); + DUK_DDD(DUK_DDDPRINT("getdate_r() -> %ld", (long) rc)); + + if (rc == 0) { + t = mktime(&tm); + DUK_DDD(DUK_DDDPRINT("mktime() -> %ld", (long) t)); + if (t >= 0) { + duk_push_number(thr, (duk_double_t) t); + return 1; + } + } + + return 0; +} +#endif /* DUK_USE_DATE_PRS_GETDATE */ + +#if defined(DUK_USE_DATE_FMT_STRFTIME) +DUK_INTERNAL duk_bool_t duk_bi_date_format_parts_strftime(duk_hthread *thr, duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags) { + char buf[DUK__STRFTIME_BUF_SIZE]; + struct tm tm; + const char *fmt; + + DUK_UNREF(tzoffset); + + /* If the platform doesn't support the entire ECMAScript range, we need + * to return 0 so that the caller can fall back to the default formatter. + * + * For now, assume that if time_t is 8 bytes or more, the whole ECMAScript + * range is supported. For smaller time_t values (4 bytes in practice), + * assumes that the signed 32-bit range is supported. + * + * XXX: detect this more correctly per platform. The size of time_t is + * probably not an accurate guarantee of strftime() supporting or not + * supporting a large time range (the full ECMAScript range). + */ + if (sizeof(time_t) < 8 && + (parts[DUK_DATE_IDX_YEAR] < 1970 || parts[DUK_DATE_IDX_YEAR] > 2037)) { + /* be paranoid for 32-bit time values (even avoiding negative ones) */ + return 0; + } + + duk_memzero(&tm, sizeof(tm)); + tm.tm_sec = parts[DUK_DATE_IDX_SECOND]; + tm.tm_min = parts[DUK_DATE_IDX_MINUTE]; + tm.tm_hour = parts[DUK_DATE_IDX_HOUR]; + tm.tm_mday = parts[DUK_DATE_IDX_DAY]; /* already one-based */ + tm.tm_mon = parts[DUK_DATE_IDX_MONTH] - 1; /* one-based -> zero-based */ + tm.tm_year = parts[DUK_DATE_IDX_YEAR] - 1900; + tm.tm_wday = parts[DUK_DATE_IDX_WEEKDAY]; + tm.tm_isdst = 0; + + duk_memzero(buf, sizeof(buf)); + if ((flags & DUK_DATE_FLAG_TOSTRING_DATE) && (flags & DUK_DATE_FLAG_TOSTRING_TIME)) { + fmt = "%c"; + } else if (flags & DUK_DATE_FLAG_TOSTRING_DATE) { + fmt = "%x"; + } else { + DUK_ASSERT(flags & DUK_DATE_FLAG_TOSTRING_TIME); + fmt = "%X"; + } + (void) strftime(buf, sizeof(buf) - 1, fmt, &tm); + DUK_ASSERT(buf[sizeof(buf) - 1] == 0); + + duk_push_string(thr, buf); + return 1; +} +#endif /* DUK_USE_DATE_FMT_STRFTIME */ + +#if defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME) +DUK_INTERNAL duk_double_t duk_bi_date_get_monotonic_time_clock_gettime(void) { + struct timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { + return (duk_double_t) ts.tv_sec * 1000.0 + (duk_double_t) ts.tv_nsec / 1000000.0; + } else { + DUK_D(DUK_DPRINT("clock_gettime(CLOCK_MONOTONIC) failed")); + return 0.0; + } +} +#endif diff --git a/third_party/duktape/duk_bi_date_windows.c b/third_party/duktape/duk_bi_date_windows.c new file mode 100644 index 00000000..df13a330 --- /dev/null +++ b/third_party/duktape/duk_bi_date_windows.c @@ -0,0 +1,193 @@ +/* + * Windows Date providers + * + * Platform specific links: + * + * - http://msdn.microsoft.com/en-us/library/windows/desktop/ms725473(v=vs.85).aspx + */ + +#include "third_party/duktape/duk_internal.h" + +/* The necessary #includes are in place in duk_config.h. */ + +#if defined(DUK_USE_DATE_NOW_WINDOWS) || defined(DUK_USE_DATE_TZO_WINDOWS) +/* Shared Windows helpers. */ +DUK_LOCAL void duk__convert_systime_to_ularge(const SYSTEMTIME *st, ULARGE_INTEGER *res) { + FILETIME ft; + if (SystemTimeToFileTime(st, &ft) == 0) { + DUK_D(DUK_DPRINT("SystemTimeToFileTime() failed, returning 0")); + res->QuadPart = 0; + } else { + res->LowPart = ft.dwLowDateTime; + res->HighPart = ft.dwHighDateTime; + } +} + +#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS) +DUK_LOCAL void duk__convert_filetime_to_ularge(const FILETIME *ft, ULARGE_INTEGER *res) { + res->LowPart = ft->dwLowDateTime; + res->HighPart = ft->dwHighDateTime; +} +#endif /* DUK_USE_DATE_NOW_WINDOWS_SUBMS */ + +DUK_LOCAL void duk__set_systime_jan1970(SYSTEMTIME *st) { + duk_memzero((void *) st, sizeof(*st)); + st->wYear = 1970; + st->wMonth = 1; + st->wDayOfWeek = 4; /* not sure whether or not needed; Thursday */ + st->wDay = 1; + DUK_ASSERT(st->wHour == 0); + DUK_ASSERT(st->wMinute == 0); + DUK_ASSERT(st->wSecond == 0); + DUK_ASSERT(st->wMilliseconds == 0); +} +#endif /* defined(DUK_USE_DATE_NOW_WINDOWS) || defined(DUK_USE_DATE_TZO_WINDOWS) */ + +#if defined(DUK_USE_DATE_NOW_WINDOWS) +DUK_INTERNAL duk_double_t duk_bi_date_get_now_windows(void) { + /* Suggested step-by-step method from documentation of RtlTimeToSecondsSince1970: + * http://msdn.microsoft.com/en-us/library/windows/desktop/ms724928(v=vs.85).aspx + */ + SYSTEMTIME st1, st2; + ULARGE_INTEGER tmp1, tmp2; + + GetSystemTime(&st1); + duk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1); + + duk__set_systime_jan1970(&st2); + duk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2); + + /* Difference is in 100ns units, convert to milliseconds, keeping + * fractions since Duktape 2.2.0. This is only theoretical because + * SYSTEMTIME is limited to milliseconds. + */ + return (duk_double_t) ((LONGLONG) tmp1.QuadPart - (LONGLONG) tmp2.QuadPart) / 10000.0; +} +#endif /* DUK_USE_DATE_NOW_WINDOWS */ + +#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS) +DUK_INTERNAL duk_double_t duk_bi_date_get_now_windows_subms(void) { + /* Variant of the basic algorithm using GetSystemTimePreciseAsFileTime() + * for more accuracy. + */ + FILETIME ft1; + SYSTEMTIME st2; + ULARGE_INTEGER tmp1, tmp2; + + GetSystemTimePreciseAsFileTime(&ft1); + duk__convert_filetime_to_ularge((const FILETIME *) &ft1, &tmp1); + + duk__set_systime_jan1970(&st2); + duk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2); + + /* Difference is in 100ns units, convert to milliseconds, keeping + * fractions since Duktape 2.2.0. + */ + return (duk_double_t) ((LONGLONG) tmp1.QuadPart - (LONGLONG) tmp2.QuadPart) / 10000.0; +} +#endif /* DUK_USE_DATE_NOW_WINDOWS */ + +#if defined(DUK_USE_DATE_TZO_WINDOWS) +DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d) { + SYSTEMTIME st1; + SYSTEMTIME st2; + SYSTEMTIME st3; + ULARGE_INTEGER tmp1; + ULARGE_INTEGER tmp2; + ULARGE_INTEGER tmp3; + FILETIME ft1; + + /* XXX: handling of timestamps outside Windows supported range. + * How does Windows deal with dates before 1600? Does windows + * support all ECMAScript years (like -200000 and +200000)? + * Should equivalent year mapping be used here too? If so, use + * a shared helper (currently integrated into timeval-to-parts). + */ + + /* Use the approach described in "Remarks" of FileTimeToLocalFileTime: + * http://msdn.microsoft.com/en-us/library/windows/desktop/ms724277(v=vs.85).aspx + */ + + duk__set_systime_jan1970(&st1); + duk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1); + tmp2.QuadPart = (ULONGLONG) (d * 10000.0); /* millisec -> 100ns units since jan 1, 1970 */ + tmp2.QuadPart += tmp1.QuadPart; /* input 'd' in Windows UTC, 100ns units */ + + ft1.dwLowDateTime = tmp2.LowPart; + ft1.dwHighDateTime = tmp2.HighPart; + if (FileTimeToSystemTime((const FILETIME *) &ft1, &st2) == 0) { + DUK_D(DUK_DPRINT("FileTimeToSystemTime() failed, return tzoffset 0")); + return 0; + } + if (SystemTimeToTzSpecificLocalTime((LPTIME_ZONE_INFORMATION) NULL, &st2, &st3) == 0) { + DUK_D(DUK_DPRINT("SystemTimeToTzSpecificLocalTime() failed, return tzoffset 0")); + return 0; + } + duk__convert_systime_to_ularge((const SYSTEMTIME *) &st3, &tmp3); + + /* Positive if local time ahead of UTC. */ + return (duk_int_t) (((LONGLONG) tmp3.QuadPart - (LONGLONG) tmp2.QuadPart) / DUK_I64_CONSTANT(10000000)); /* seconds */ +} +#endif /* DUK_USE_DATE_TZO_WINDOWS */ + +#if defined(DUK_USE_DATE_TZO_WINDOWS_NO_DST) +DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_double_t d) { + SYSTEMTIME st1; + SYSTEMTIME st2; + FILETIME ft1; + FILETIME ft2; + ULARGE_INTEGER tmp1; + ULARGE_INTEGER tmp2; + + /* Do a similar computation to duk_bi_date_get_local_tzoffset_windows + * but without accounting for daylight savings time. Use this on + * Windows platforms (like Durango) that don't support the + * SystemTimeToTzSpecificLocalTime() call. + */ + + /* current time not needed for this computation */ + DUK_UNREF(d); + + duk__set_systime_jan1970(&st1); + duk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1); + + ft1.dwLowDateTime = tmp1.LowPart; + ft1.dwHighDateTime = tmp1.HighPart; + if (FileTimeToLocalFileTime((const FILETIME *) &ft1, &ft2) == 0) { + DUK_D(DUK_DPRINT("FileTimeToLocalFileTime() failed, return tzoffset 0")); + return 0; + } + if (FileTimeToSystemTime((const FILETIME *) &ft2, &st2) == 0) { + DUK_D(DUK_DPRINT("FileTimeToSystemTime() failed, return tzoffset 0")); + return 0; + } + duk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2); + + return (duk_int_t) (((LONGLONG) tmp2.QuadPart - (LONGLONG) tmp1.QuadPart) / DUK_I64_CONSTANT(10000000)); /* seconds */ +} +#endif /* DUK_USE_DATE_TZO_WINDOWS_NO_DST */ + +#if defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC) +DUK_INTERNAL duk_double_t duk_bi_date_get_monotonic_time_windows_qpc(void) { + LARGE_INTEGER count, freq; + + /* There are legacy issues with QueryPerformanceCounter(): + * - Potential jumps: https://support.microsoft.com/en-us/help/274323/performance-counter-value-may-unexpectedly-leap-forward + * - Differences between cores (XP): https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx#qpc_support_in_windows_versions + * + * We avoid these by enabling QPC by default only for Vista or later. + */ + + if (QueryPerformanceCounter(&count) && QueryPerformanceFrequency(&freq)) { + /* XXX: QueryPerformanceFrequency() can be cached */ + return (duk_double_t) count.QuadPart / (duk_double_t) freq.QuadPart * 1000.0; + } else { + /* MSDN: "On systems that run Windows XP or later, the function + * will always succeed and will thus never return zero." + * Provide minimal error path just in case user enables this + * feature in pre-XP Windows. + */ + return 0.0; + } +} +#endif /* DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC */ diff --git a/third_party/duktape/duk_bi_duktape.c b/third_party/duktape/duk_bi_duktape.c new file mode 100644 index 00000000..443f3293 --- /dev/null +++ b/third_party/duktape/duk_bi_duktape.c @@ -0,0 +1,158 @@ +/* + * Duktape built-ins + * + * Size optimization note: it might seem that vararg multipurpose functions + * like fin(), enc(), and dec() are not very size optimal, but using a single + * user-visible ECMAScript function saves a lot of run-time footprint; each + * Function instance takes >100 bytes. Using a shared native helper and a + * 'magic' value won't save much if there are multiple Function instances + * anyway. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_DUKTAPE_BUILTIN) + +DUK_INTERNAL duk_ret_t duk_bi_duktape_object_info(duk_hthread *thr) { + duk_inspect_value(thr, -1); + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_duktape_object_act(duk_hthread *thr) { + duk_int_t level; + + level = duk_to_int(thr, 0); + duk_inspect_callstack_entry(thr, level); + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_duktape_object_gc(duk_hthread *thr) { + duk_small_uint_t flags; + + flags = (duk_small_uint_t) duk_get_uint(thr, 0); + duk_heap_mark_and_sweep(thr->heap, flags); + + /* XXX: Not sure what the best return value would be in the API. + * Return true for now. + */ + duk_push_true(thr); + return 1; +} + +#if defined(DUK_USE_FINALIZER_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_duktape_object_fin(duk_hthread *thr) { + (void) duk_require_hobject(thr, 0); + if (duk_get_top(thr) >= 2) { + /* Set: currently a finalizer is disabled by setting it to + * undefined; this does not remove the property at the moment. + * The value could be type checked to be either a function + * or something else; if something else, the property could + * be deleted. Must use duk_set_finalizer() to keep + * DUK_HOBJECT_FLAG_HAVE_FINALIZER in sync. + */ + duk_set_top(thr, 2); + duk_set_finalizer(thr, 0); + return 0; + } else { + /* Get. */ + DUK_ASSERT(duk_get_top(thr) == 1); + duk_get_finalizer(thr, 0); + return 1; + } +} +#endif /* DUK_USE_FINALIZER_SUPPORT */ + +DUK_INTERNAL duk_ret_t duk_bi_duktape_object_enc(duk_hthread *thr) { + duk_hstring *h_str; + + /* Vararg function: must be careful to check/require arguments. + * The JSON helpers accept invalid indices and treat them like + * non-existent optional parameters. + */ + + h_str = duk_require_hstring(thr, 0); /* Could reject symbols, but no point: won't match comparisons. */ + duk_require_valid_index(thr, 1); + + if (h_str == DUK_HTHREAD_STRING_HEX(thr)) { + duk_set_top(thr, 2); + duk_hex_encode(thr, 1); + DUK_ASSERT_TOP(thr, 2); + } else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) { + duk_set_top(thr, 2); + duk_base64_encode(thr, 1); + DUK_ASSERT_TOP(thr, 2); +#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JX) + } else if (h_str == DUK_HTHREAD_STRING_JX(thr)) { + duk_bi_json_stringify_helper(thr, + 1 /*idx_value*/, + 2 /*idx_replacer*/, + 3 /*idx_space*/, + DUK_JSON_FLAG_EXT_CUSTOM | + DUK_JSON_FLAG_ASCII_ONLY | + DUK_JSON_FLAG_AVOID_KEY_QUOTES /*flags*/); +#endif +#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JC) + } else if (h_str == DUK_HTHREAD_STRING_JC(thr)) { + duk_bi_json_stringify_helper(thr, + 1 /*idx_value*/, + 2 /*idx_replacer*/, + 3 /*idx_space*/, + DUK_JSON_FLAG_EXT_COMPATIBLE | + DUK_JSON_FLAG_ASCII_ONLY /*flags*/); +#endif + } else { + DUK_DCERROR_TYPE_INVALID_ARGS(thr); + } + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_duktape_object_dec(duk_hthread *thr) { + duk_hstring *h_str; + + /* Vararg function: must be careful to check/require arguments. + * The JSON helpers accept invalid indices and treat them like + * non-existent optional parameters. + */ + + h_str = duk_require_hstring(thr, 0); /* Could reject symbols, but no point: won't match comparisons */ + duk_require_valid_index(thr, 1); + + if (h_str == DUK_HTHREAD_STRING_HEX(thr)) { + duk_set_top(thr, 2); + duk_hex_decode(thr, 1); + DUK_ASSERT_TOP(thr, 2); + } else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) { + duk_set_top(thr, 2); + duk_base64_decode(thr, 1); + DUK_ASSERT_TOP(thr, 2); +#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JX) + } else if (h_str == DUK_HTHREAD_STRING_JX(thr)) { + duk_bi_json_parse_helper(thr, + 1 /*idx_value*/, + 2 /*idx_replacer*/, + DUK_JSON_FLAG_EXT_CUSTOM /*flags*/); +#endif +#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JC) + } else if (h_str == DUK_HTHREAD_STRING_JC(thr)) { + duk_bi_json_parse_helper(thr, + 1 /*idx_value*/, + 2 /*idx_replacer*/, + DUK_JSON_FLAG_EXT_COMPATIBLE /*flags*/); +#endif + } else { + DUK_DCERROR_TYPE_INVALID_ARGS(thr); + } + return 1; +} + +/* + * Compact an object + */ + +DUK_INTERNAL duk_ret_t duk_bi_duktape_object_compact(duk_hthread *thr) { + DUK_ASSERT_TOP(thr, 1); + duk_compact(thr, 0); + return 1; /* return the argument object */ +} + +#endif /* DUK_USE_DUKTAPE_BUILTIN */ diff --git a/third_party/duktape/duk_bi_encoding.c b/third_party/duktape/duk_bi_encoding.c new file mode 100644 index 00000000..f06a1579 --- /dev/null +++ b/third_party/duktape/duk_bi_encoding.c @@ -0,0 +1,533 @@ +/* + * WHATWG Encoding API built-ins + * + * API specification: https://encoding.spec.whatwg.org/#api + * Web IDL: https://www.w3.org/TR/WebIDL/ + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Data structures for encoding/decoding + */ + +typedef struct { + duk_uint8_t *out; /* where to write next byte(s) */ + duk_codepoint_t lead; /* lead surrogate */ +} duk__encode_context; + +typedef struct { + /* UTF-8 decoding state */ + duk_codepoint_t codepoint; /* built up incrementally */ + duk_uint8_t upper; /* max value of next byte (decode error otherwise) */ + duk_uint8_t lower; /* min value of next byte (ditto) */ + duk_uint8_t needed; /* how many more bytes we need */ + duk_uint8_t bom_handled; /* BOM seen or no longer expected */ + + /* Decoder configuration */ + duk_uint8_t fatal; + duk_uint8_t ignore_bom; +} duk__decode_context; + +/* The signed duk_codepoint_t type is used to signal a decoded codepoint + * (>= 0) or various other states using negative values. + */ +#define DUK__CP_CONTINUE (-1) /* continue to next byte, no completed codepoint */ +#define DUK__CP_ERROR (-2) /* decoding error */ +#define DUK__CP_RETRY (-3) /* decoding error; retry last byte */ + +/* + * Raw helpers for encoding/decoding + */ + +/* Emit UTF-8 (= CESU-8) encoded U+FFFD (replacement char), i.e. ef bf bd. */ +DUK_LOCAL duk_uint8_t *duk__utf8_emit_repl(duk_uint8_t *ptr) { + *ptr++ = 0xef; + *ptr++ = 0xbf; + *ptr++ = 0xbd; + return ptr; +} + +DUK_LOCAL void duk__utf8_decode_init(duk__decode_context *dec_ctx) { + /* (Re)init the decoding state of 'dec_ctx' but leave decoder + * configuration fields untouched. + */ + dec_ctx->codepoint = 0x0000L; + dec_ctx->upper = 0xbf; + dec_ctx->lower = 0x80; + dec_ctx->needed = 0; + dec_ctx->bom_handled = 0; +} + +DUK_LOCAL duk_codepoint_t duk__utf8_decode_next(duk__decode_context *dec_ctx, duk_uint8_t x) { + /* + * UTF-8 algorithm based on the Encoding specification: + * https://encoding.spec.whatwg.org/#utf-8-decoder + * + * Two main states: decoding initial byte vs. decoding continuation + * bytes. Shortest length encoding is validated by restricting the + * allowed range of first continuation byte using 'lower' and 'upper'. + */ + + if (dec_ctx->needed == 0) { + /* process initial byte */ + if (x <= 0x7f) { + /* U+0000-U+007F, 1 byte (ASCII) */ + return (duk_codepoint_t) x; + } else if (x >= 0xc2 && x <= 0xdf) { + /* U+0080-U+07FF, 2 bytes */ + dec_ctx->needed = 1; + dec_ctx->codepoint = x & 0x1f; + DUK_ASSERT(dec_ctx->lower == 0x80); + DUK_ASSERT(dec_ctx->upper == 0xbf); + return DUK__CP_CONTINUE; + } else if (x >= 0xe0 && x <= 0xef) { + /* U+0800-U+FFFF, 3 bytes */ + if (x == 0xe0) { + dec_ctx->lower = 0xa0; + DUK_ASSERT(dec_ctx->upper == 0xbf); + } else if (x == 0xed) { + DUK_ASSERT(dec_ctx->lower == 0x80); + dec_ctx->upper = 0x9f; + } + dec_ctx->needed = 2; + dec_ctx->codepoint = x & 0x0f; + return DUK__CP_CONTINUE; + } else if (x >= 0xf0 && x <= 0xf4) { + /* U+010000-U+10FFFF, 4 bytes */ + if (x == 0xf0) { + dec_ctx->lower = 0x90; + DUK_ASSERT(dec_ctx->upper == 0xbf); + } else if (x == 0xf4) { + DUK_ASSERT(dec_ctx->lower == 0x80); + dec_ctx->upper = 0x8f; + } + dec_ctx->needed = 3; + dec_ctx->codepoint = x & 0x07; + return DUK__CP_CONTINUE; + } else { + /* not a legal initial byte */ + return DUK__CP_ERROR; + } + } else { + /* process continuation byte */ + if (x >= dec_ctx->lower && x <= dec_ctx->upper) { + dec_ctx->lower = 0x80; + dec_ctx->upper = 0xbf; + dec_ctx->codepoint = (dec_ctx->codepoint << 6) | (x & 0x3f); + if (--dec_ctx->needed > 0) { + /* need more bytes */ + return DUK__CP_CONTINUE; + } else { + /* got a codepoint */ + duk_codepoint_t ret; + DUK_ASSERT(dec_ctx->codepoint <= 0x10ffffL); /* Decoding rules guarantee. */ + ret = dec_ctx->codepoint; + dec_ctx->codepoint = 0x0000L; + dec_ctx->needed = 0; + return ret; + } + } else { + /* We just encountered an illegal UTF-8 continuation byte. This might + * be the initial byte of the next character; if we return a plain + * error status and the decoder is in replacement mode, the character + * will be masked. We still need to alert the caller to the error + * though. + */ + dec_ctx->codepoint = 0x0000L; + dec_ctx->needed = 0; + dec_ctx->lower = 0x80; + dec_ctx->upper = 0xbf; + return DUK__CP_RETRY; + } + } +} + +#if defined(DUK_USE_ENCODING_BUILTINS) +DUK_LOCAL void duk__utf8_encode_char(void *udata, duk_codepoint_t codepoint) { + duk__encode_context *enc_ctx; + + DUK_ASSERT(codepoint >= 0); + enc_ctx = (duk__encode_context *) udata; + DUK_ASSERT(enc_ctx != NULL); + +#if !defined(DUK_USE_PREFER_SIZE) + if (codepoint <= 0x7f && enc_ctx->lead == 0x0000L) { + /* Fast path for ASCII. */ + *enc_ctx->out++ = (duk_uint8_t) codepoint; + return; + } +#endif + + if (DUK_UNLIKELY(codepoint > 0x10ffffL)) { + /* cannot legally encode in UTF-8 */ + codepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER; + } else if (codepoint >= 0xd800L && codepoint <= 0xdfffL) { + if (codepoint <= 0xdbffL) { + /* high surrogate */ + duk_codepoint_t prev_lead = enc_ctx->lead; + enc_ctx->lead = codepoint; + if (prev_lead == 0x0000L) { + /* high surrogate, no output */ + return; + } else { + /* consecutive high surrogates, consider first one unpaired */ + codepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER; + } + } else { + /* low surrogate */ + if (enc_ctx->lead != 0x0000L) { + codepoint = (duk_codepoint_t) (0x010000L + ((enc_ctx->lead - 0xd800L) << 10) + (codepoint - 0xdc00L)); + enc_ctx->lead = 0x0000L; + } else { + /* unpaired low surrogate */ + DUK_ASSERT(enc_ctx->lead == 0x0000L); + codepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER; + } + } + } else { + if (enc_ctx->lead != 0x0000L) { + /* unpaired high surrogate: emit replacement character and the input codepoint */ + enc_ctx->lead = 0x0000L; + enc_ctx->out = duk__utf8_emit_repl(enc_ctx->out); + } + } + + /* Codepoint may be original input, a decoded surrogate pair, or may + * have been replaced with U+FFFD. + */ + enc_ctx->out += duk_unicode_encode_xutf8((duk_ucodepoint_t) codepoint, enc_ctx->out); +} +#endif /* DUK_USE_ENCODING_BUILTINS */ + +/* Shared helper for buffer-to-string using a TextDecoder() compatible UTF-8 + * decoder. + */ +DUK_LOCAL duk_ret_t duk__decode_helper(duk_hthread *thr, duk__decode_context *dec_ctx) { + const duk_uint8_t *input; + duk_size_t len = 0; + duk_size_t len_tmp; + duk_bool_t stream = 0; + duk_codepoint_t codepoint; + duk_uint8_t *output; + const duk_uint8_t *in; + duk_uint8_t *out; + + DUK_ASSERT(dec_ctx != NULL); + + /* Careful with input buffer pointer: any side effects involving + * code execution (e.g. getters, coercion calls, and finalizers) + * may cause a resize and invalidate a pointer we've read. This + * is why the pointer is actually looked up at the last minute. + * Argument validation must still happen first to match WHATWG + * required side effect order. + */ + + if (duk_is_undefined(thr, 0)) { + duk_push_fixed_buffer_nozero(thr, 0); + duk_replace(thr, 0); + } + (void) duk_require_buffer_data(thr, 0, &len); /* Need 'len', avoid pointer. */ + + if (duk_check_type_mask(thr, 1, DUK_TYPE_MASK_UNDEFINED | + DUK_TYPE_MASK_NULL | + DUK_TYPE_MASK_NONE)) { + /* Use defaults, treat missing value like undefined. */ + } else { + duk_require_type_mask(thr, 1, DUK_TYPE_MASK_UNDEFINED | + DUK_TYPE_MASK_NULL | + DUK_TYPE_MASK_LIGHTFUNC | + DUK_TYPE_MASK_BUFFER | + DUK_TYPE_MASK_OBJECT); + if (duk_get_prop_literal(thr, 1, "stream")) { + stream = duk_to_boolean(thr, -1); + } + } + + /* Allowance is 3*len in the general case because all bytes may potentially + * become U+FFFD. If the first byte completes a non-BMP codepoint it will + * decode to a CESU-8 surrogate pair (6 bytes) so we allow 3 extra bytes to + * compensate: (1*3)+3 = 6. Non-BMP codepoints are safe otherwise because + * the 4->6 expansion is well under the 3x allowance. + * + * XXX: As with TextEncoder, need a better buffer allocation strategy here. + */ + if (len >= (DUK_HBUFFER_MAX_BYTELEN / 3) - 3) { + DUK_ERROR_TYPE(thr, DUK_STR_RESULT_TOO_LONG); + DUK_WO_NORETURN(return 0;); + } + output = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, 3 + (3 * len)); /* used parts will be always manually written over */ + + input = (const duk_uint8_t *) duk_get_buffer_data(thr, 0, &len_tmp); + DUK_ASSERT(input != NULL || len == 0); + if (DUK_UNLIKELY(len != len_tmp)) { + /* Very unlikely but possible: source buffer was resized by + * a side effect when fixed buffer was pushed. Output buffer + * may not be large enough to hold output, so just fail if + * length has changed. + */ + DUK_D(DUK_DPRINT("input buffer resized by side effect, fail")); + goto fail_type; + } + + /* From this point onwards it's critical that no side effect occur + * which may disturb 'input': finalizer execution, property accesses, + * active coercions, etc. Even an allocation related mark-and-sweep + * may affect the pointer because it may trigger a pending finalizer. + */ + + in = input; + out = output; + while (in < input + len) { + codepoint = duk__utf8_decode_next(dec_ctx, *in++); + if (codepoint < 0) { + if (codepoint == DUK__CP_CONTINUE) { + continue; + } + + /* Decoding error with or without retry. */ + DUK_ASSERT(codepoint == DUK__CP_ERROR || codepoint == DUK__CP_RETRY); + if (codepoint == DUK__CP_RETRY) { + --in; /* retry last byte */ + } + /* replacement mode: replace with U+FFFD */ + codepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER; + if (dec_ctx->fatal) { + /* fatal mode: throw a TypeError */ + goto fail_type; + } + /* Continue with 'codepoint', Unicode replacement. */ + } + DUK_ASSERT(codepoint >= 0x0000L && codepoint <= 0x10ffffL); + + if (!dec_ctx->bom_handled) { + dec_ctx->bom_handled = 1; + if (codepoint == 0xfeffL && !dec_ctx->ignore_bom) { + continue; + } + } + + out += duk_unicode_encode_cesu8((duk_ucodepoint_t) codepoint, out); + DUK_ASSERT(out <= output + (3 + (3 * len))); + } + + if (!stream) { + if (dec_ctx->needed != 0) { + /* truncated sequence at end of buffer */ + if (dec_ctx->fatal) { + goto fail_type; + } else { + out += duk_unicode_encode_cesu8(DUK_UNICODE_CP_REPLACEMENT_CHARACTER, out); + DUK_ASSERT(out <= output + (3 + (3 * len))); + } + } + duk__utf8_decode_init(dec_ctx); /* Initialize decoding state for potential reuse. */ + } + + /* Output buffer is fixed and thus stable even if there had been + * side effects (which there shouldn't be). + */ + duk_push_lstring(thr, (const char *) output, (duk_size_t) (out - output)); + return 1; + + fail_type: + DUK_ERROR_TYPE(thr, DUK_STR_UTF8_DECODE_FAILED); + DUK_WO_NORETURN(return 0;); +} + +/* + * Built-in bindings + */ + +#if defined(DUK_USE_ENCODING_BUILTINS) +DUK_INTERNAL duk_ret_t duk_bi_textencoder_constructor(duk_hthread *thr) { + /* TextEncoder currently requires no persistent state, so the constructor + * does nothing on purpose. + */ + + duk_require_constructor_call(thr); + return 0; +} + +DUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encoding_getter(duk_hthread *thr) { + duk_push_literal(thr, "utf-8"); + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encode(duk_hthread *thr) { + duk__encode_context enc_ctx; + duk_size_t len; + duk_size_t final_len; + duk_uint8_t *output; + + DUK_ASSERT_TOP(thr, 1); + if (duk_is_undefined(thr, 0)) { + len = 0; + } else { + duk_hstring *h_input; + + h_input = duk_to_hstring(thr, 0); + DUK_ASSERT(h_input != NULL); + + len = (duk_size_t) DUK_HSTRING_GET_CHARLEN(h_input); + if (len >= DUK_HBUFFER_MAX_BYTELEN / 3) { + DUK_ERROR_TYPE(thr, DUK_STR_RESULT_TOO_LONG); + DUK_WO_NORETURN(return 0;); + } + } + + /* Allowance is 3*len because all bytes can potentially be replaced with + * U+FFFD -- which rather inconveniently encodes to 3 bytes in UTF-8. + * Rely on dynamic buffer data pointer stability: no other code has + * access to the data pointer. + * + * XXX: The buffer allocation strategy used here is rather inefficient. + * Maybe switch to a chunk-based strategy, or preprocess the string to + * figure out the space needed ahead of time? + */ + DUK_ASSERT(3 * len >= len); + output = (duk_uint8_t *) duk_push_dynamic_buffer(thr, 3 * len); + + if (len > 0) { + DUK_ASSERT(duk_is_string(thr, 0)); /* True if len > 0. */ + + /* XXX: duk_decode_string() is used to process the input + * string. For standard ECMAScript strings, represented + * internally as CESU-8, this is fine. However, behavior + * beyond CESU-8 is not very strict: codepoints using an + * extended form of UTF-8 are also accepted, and invalid + * codepoint sequences (which are allowed in Duktape strings) + * are not handled as well as they could (e.g. invalid + * continuation bytes may mask following codepoints). + * This is how ECMAScript code would also see such strings. + * Maybe replace duk_decode_string() with an explicit strict + * CESU-8 decoder here? + */ + enc_ctx.lead = 0x0000L; + enc_ctx.out = output; + duk_decode_string(thr, 0, duk__utf8_encode_char, (void *) &enc_ctx); + if (enc_ctx.lead != 0x0000L) { + /* unpaired high surrogate at end of string */ + enc_ctx.out = duk__utf8_emit_repl(enc_ctx.out); + DUK_ASSERT(enc_ctx.out <= output + (3 * len)); + } + + /* The output buffer is usually very much oversized, so shrink it to + * actually needed size. Pointer stability assumed up to this point. + */ + DUK_ASSERT_TOP(thr, 2); + DUK_ASSERT(output == (duk_uint8_t *) duk_get_buffer_data(thr, -1, NULL)); + + final_len = (duk_size_t) (enc_ctx.out - output); + duk_resize_buffer(thr, -1, final_len); + /* 'output' and 'enc_ctx.out' are potentially invalidated by the resize. */ + } else { + final_len = 0; + } + + /* Standard WHATWG output is a Uint8Array. Here the Uint8Array will + * be backed by a dynamic buffer which differs from e.g. Uint8Arrays + * created as 'new Uint8Array(N)'. ECMAScript code won't see the + * difference but C code will. When bufferobjects are not supported, + * returns a plain dynamic buffer. + */ +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + duk_push_buffer_object(thr, -1, 0, final_len, DUK_BUFOBJ_UINT8ARRAY); +#endif + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_textdecoder_constructor(duk_hthread *thr) { + duk__decode_context *dec_ctx; + duk_bool_t fatal = 0; + duk_bool_t ignore_bom = 0; + + DUK_ASSERT_TOP(thr, 2); + duk_require_constructor_call(thr); + if (!duk_is_undefined(thr, 0)) { + /* XXX: For now ignore 'label' (encoding identifier). */ + duk_to_string(thr, 0); + } + if (!duk_is_null_or_undefined(thr, 1)) { + if (duk_get_prop_literal(thr, 1, "fatal")) { + fatal = duk_to_boolean(thr, -1); + } + if (duk_get_prop_literal(thr, 1, "ignoreBOM")) { + ignore_bom = duk_to_boolean(thr, -1); + } + } + + duk_push_this(thr); + + /* The decode context is not assumed to be zeroed; all fields are + * initialized explicitly. + */ + dec_ctx = (duk__decode_context *) duk_push_fixed_buffer(thr, sizeof(duk__decode_context)); + dec_ctx->fatal = (duk_uint8_t) fatal; + dec_ctx->ignore_bom = (duk_uint8_t) ignore_bom; + duk__utf8_decode_init(dec_ctx); /* Initializes remaining fields. */ + + duk_put_prop_literal(thr, -2, DUK_INTERNAL_SYMBOL("Context")); + return 0; +} + +/* Get TextDecoder context from 'this'; leaves garbage on stack. */ +DUK_LOCAL duk__decode_context *duk__get_textdecoder_context(duk_hthread *thr) { + duk__decode_context *dec_ctx; + duk_push_this(thr); + duk_get_prop_literal(thr, -1, DUK_INTERNAL_SYMBOL("Context")); + dec_ctx = (duk__decode_context *) duk_require_buffer(thr, -1, NULL); + DUK_ASSERT(dec_ctx != NULL); + return dec_ctx; +} + +DUK_INTERNAL duk_ret_t duk_bi_textdecoder_prototype_shared_getter(duk_hthread *thr) { + duk__decode_context *dec_ctx; + duk_int_t magic; + + dec_ctx = duk__get_textdecoder_context(thr); + magic = duk_get_current_magic(thr); + switch (magic) { + case 0: + /* Encoding is now fixed, so _Context lookup is only needed to + * validate the 'this' binding (TypeError if not TextDecoder-like). + */ + duk_push_literal(thr, "utf-8"); + break; + case 1: + duk_push_boolean(thr, dec_ctx->fatal); + break; + default: + duk_push_boolean(thr, dec_ctx->ignore_bom); + break; + } + + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_textdecoder_prototype_decode(duk_hthread *thr) { + duk__decode_context *dec_ctx; + + dec_ctx = duk__get_textdecoder_context(thr); + return duk__decode_helper(thr, dec_ctx); +} +#endif /* DUK_USE_ENCODING_BUILTINS */ + +/* + * Internal helper for Node.js Buffer + */ + +/* Internal helper used for Node.js Buffer .toString(). Value stack convention + * is currently odd: it mimics TextDecoder .decode() so that argument must be at + * index 0, and decode options (not present for Buffer) at index 1. Return value + * is a Duktape/C function return value. + */ +DUK_INTERNAL duk_ret_t duk_textdecoder_decode_utf8_nodejs(duk_hthread *thr) { + duk__decode_context dec_ctx; + + dec_ctx.fatal = 0; /* use replacement chars */ + dec_ctx.ignore_bom = 1; /* ignore BOMs (matches Node.js Buffer .toString()) */ + duk__utf8_decode_init(&dec_ctx); + + return duk__decode_helper(thr, &dec_ctx); +} diff --git a/third_party/duktape/duk_bi_error.c b/third_party/duktape/duk_bi_error.c new file mode 100644 index 00000000..6ca49f83 --- /dev/null +++ b/third_party/duktape/duk_bi_error.c @@ -0,0 +1,387 @@ +/* + * Error built-ins + */ + +#include "third_party/duktape/duk_internal.h" + +DUK_INTERNAL duk_ret_t duk_bi_error_constructor_shared(duk_hthread *thr) { + /* Behavior for constructor and non-constructor call is + * the same except for augmenting the created error. When + * called as a constructor, the caller (duk_new()) will handle + * augmentation; when called as normal function, we need to do + * it here. + */ + + duk_small_int_t bidx_prototype = duk_get_current_magic(thr); + + /* same for both error and each subclass like TypeError */ + duk_uint_t flags_and_class = DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ERROR); + + (void) duk_push_object_helper(thr, flags_and_class, bidx_prototype); + + /* If message is undefined, the own property 'message' is not set at + * all to save property space. An empty message is inherited anyway. + */ + if (!duk_is_undefined(thr, 0)) { + duk_to_string(thr, 0); + duk_dup_0(thr); /* [ message error message ] */ + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC); + } + + /* Augment the error if called as a normal function. __FILE__ and __LINE__ + * are not desirable in this case. + */ + +#if defined(DUK_USE_AUGMENT_ERROR_CREATE) + if (!duk_is_constructor_call(thr)) { + duk_err_augment_error_create(thr, thr, NULL, 0, DUK_AUGMENT_FLAG_NOBLAME_FILELINE); + } +#endif + + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_error_prototype_to_string(duk_hthread *thr) { + /* XXX: optimize with more direct internal access */ + + duk_push_this(thr); + (void) duk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER); + + /* [ ... this ] */ + + duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME); + if (duk_is_undefined(thr, -1)) { + duk_pop(thr); + duk_push_literal(thr, "Error"); + } else { + duk_to_string(thr, -1); + } + + /* [ ... this name ] */ + + /* XXX: Are steps 6 and 7 in E5 Section 15.11.4.4 duplicated by + * accident or are they actually needed? The first ToString() + * could conceivably return 'undefined'. + */ + duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE); + if (duk_is_undefined(thr, -1)) { + duk_pop(thr); + duk_push_hstring_empty(thr); + } else { + duk_to_string(thr, -1); + } + + /* [ ... this name message ] */ + + if (duk_get_length(thr, -2) == 0) { + /* name is empty -> return message */ + return 1; + } + if (duk_get_length(thr, -1) == 0) { + /* message is empty -> return name */ + duk_pop(thr); + return 1; + } + duk_push_literal(thr, ": "); + duk_insert(thr, -2); /* ... name ': ' message */ + duk_concat(thr, 3); + + return 1; +} + +#if defined(DUK_USE_TRACEBACKS) + +/* + * Traceback handling + * + * The unified helper decodes the traceback and produces various requested + * outputs. It should be optimized for size, and may leave garbage on stack, + * only the topmost return value matters. For instance, traceback separator + * and decoded strings are pushed even when looking for filename only. + * + * NOTE: although _Tracedata is an internal property, user code can currently + * write to the array (or replace it with something other than an array). + * The code below must tolerate arbitrary _Tracedata. It can throw errors + * etc, but cannot cause a segfault or memory unsafe behavior. + */ + +/* constants arbitrary, chosen for small loads */ +#define DUK__OUTPUT_TYPE_TRACEBACK (-1) +#define DUK__OUTPUT_TYPE_FILENAME 0 +#define DUK__OUTPUT_TYPE_LINENUMBER 1 + +DUK_LOCAL duk_ret_t duk__error_getter_helper(duk_hthread *thr, duk_small_int_t output_type) { + duk_idx_t idx_td; + duk_small_int_t i; /* traceback depth fits into 16 bits */ + duk_small_int_t t; /* stack type fits into 16 bits */ + duk_small_int_t count_func = 0; /* traceback depth ensures fits into 16 bits */ + const char *str_tailcall = " tailcall"; + const char *str_strict = " strict"; + const char *str_construct = " construct"; + const char *str_prevyield = " preventsyield"; + const char *str_directeval = " directeval"; + const char *str_empty = ""; + + DUK_ASSERT_TOP(thr, 0); /* fixed arg count */ + + duk_push_this(thr); + duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_TRACEDATA); + idx_td = duk_get_top_index(thr); + + duk_push_hstring_stridx(thr, DUK_STRIDX_NEWLINE_4SPACE); + duk_push_this(thr); + + /* [ ... this tracedata sep this ] */ + + /* XXX: skip null filename? */ + + if (duk_check_type(thr, idx_td, DUK_TYPE_OBJECT)) { + /* Current tracedata contains 2 entries per callstack entry. */ + for (i = 0; ; i += 2) { + duk_int_t pc; + duk_uint_t line; + duk_uint_t flags; + duk_double_t d; + const char *funcname; + const char *filename; + duk_hobject *h_func; + duk_hstring *h_name; + + duk_require_stack(thr, 5); + duk_get_prop_index(thr, idx_td, (duk_uarridx_t) i); + duk_get_prop_index(thr, idx_td, (duk_uarridx_t) (i + 1)); + d = duk_to_number_m1(thr); + pc = duk_double_to_int_t(DUK_FMOD(d, DUK_DOUBLE_2TO32)); + flags = duk_double_to_uint_t(DUK_FLOOR(d / DUK_DOUBLE_2TO32)); + t = (duk_small_int_t) duk_get_type(thr, -2); + + if (t == DUK_TYPE_OBJECT || t == DUK_TYPE_LIGHTFUNC) { + /* + * ECMAScript/native function call or lightfunc call + */ + + count_func++; + + /* [ ... v1(func) v2(pc+flags) ] */ + + /* These may be systematically omitted by Duktape + * with certain config options, but allow user to + * set them on a case-by-case basis. + */ + duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME); + duk_get_prop_stridx_short(thr, -3, DUK_STRIDX_FILE_NAME); + +#if defined(DUK_USE_PC2LINE) + line = (duk_uint_t) duk_hobject_pc2line_query(thr, -4, (duk_uint_fast32_t) pc); +#else + line = 0; +#endif + + /* [ ... v1 v2 name filename ] */ + + /* When looking for .fileName/.lineNumber, blame first + * function which has a .fileName. + */ + if (duk_is_string_notsymbol(thr, -1)) { + if (output_type == DUK__OUTPUT_TYPE_FILENAME) { + return 1; + } else if (output_type == DUK__OUTPUT_TYPE_LINENUMBER) { + duk_push_uint(thr, line); + return 1; + } + } + + /* XXX: Change 'anon' handling here too, to use empty string for anonymous functions? */ + /* XXX: Could be improved by coercing to a readable duk_tval (especially string escaping) */ + h_name = duk_get_hstring_notsymbol(thr, -2); /* may be NULL */ + funcname = (h_name == NULL || h_name == DUK_HTHREAD_STRING_EMPTY_STRING(thr)) ? + "[anon]" : (const char *) DUK_HSTRING_GET_DATA(h_name); + filename = duk_get_string_notsymbol(thr, -1); + filename = filename ? filename : ""; + DUK_ASSERT(funcname != NULL); + DUK_ASSERT(filename != NULL); + + h_func = duk_get_hobject(thr, -4); /* NULL for lightfunc */ + + if (h_func == NULL) { + duk_push_sprintf(thr, "at %s light%s%s%s%s%s", + (const char *) funcname, + (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty), + (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty), + (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty), + (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty), + (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty)); + } else if (DUK_HOBJECT_HAS_NATFUNC(h_func)) { + duk_push_sprintf(thr, "at %s (%s) native%s%s%s%s%s", + (const char *) funcname, + (const char *) filename, + (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty), + (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty), + (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty), + (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty), + (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty)); + } else { + duk_push_sprintf(thr, "at %s (%s:%lu)%s%s%s%s%s", + (const char *) funcname, + (const char *) filename, + (unsigned long) line, + (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty), + (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty), + (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty), + (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty), + (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty)); + } + duk_replace(thr, -5); /* [ ... v1 v2 name filename str ] -> [ ... str v2 name filename ] */ + duk_pop_3(thr); /* -> [ ... str ] */ + } else if (t == DUK_TYPE_STRING) { + const char *str_file; + + /* + * __FILE__ / __LINE__ entry, here 'pc' is line number directly. + * Sometimes __FILE__ / __LINE__ is reported as the source for + * the error (fileName, lineNumber), sometimes not. + */ + + /* [ ... v1(filename) v2(line+flags) ] */ + + /* When looking for .fileName/.lineNumber, blame compilation + * or C call site unless flagged not to do so. + */ + if (!(flags & DUK_TB_FLAG_NOBLAME_FILELINE)) { + if (output_type == DUK__OUTPUT_TYPE_FILENAME) { + duk_pop(thr); + return 1; + } else if (output_type == DUK__OUTPUT_TYPE_LINENUMBER) { + duk_push_int(thr, pc); + return 1; + } + } + + /* Tracedata is trusted but avoid any risk of using a NULL + * for %s format because it has undefined behavior. Symbols + * don't need to be explicitly rejected as they pose no memory + * safety issues. + */ + str_file = (const char *) duk_get_string(thr, -2); + duk_push_sprintf(thr, "at [anon] (%s:%ld) internal", + (const char *) (str_file ? str_file : "null"), (long) pc); + duk_replace(thr, -3); /* [ ... v1 v2 str ] -> [ ... str v2 ] */ + duk_pop(thr); /* -> [ ... str ] */ + } else { + /* unknown, ignore */ + duk_pop_2(thr); + break; + } + } + + if (count_func >= DUK_USE_TRACEBACK_DEPTH) { + /* Possibly truncated; there is no explicit truncation + * marker so this is the best we can do. + */ + + duk_push_hstring_stridx(thr, DUK_STRIDX_BRACKETED_ELLIPSIS); + } + } + + /* [ ... this tracedata sep this str1 ... strN ] */ + + if (output_type != DUK__OUTPUT_TYPE_TRACEBACK) { + return 0; + } else { + /* The 'this' after 'sep' will get ToString() coerced by + * duk_join() automatically. We don't want to do that + * coercion when providing .fileName or .lineNumber (GH-254). + */ + duk_join(thr, duk_get_top(thr) - (idx_td + 2) /*count, not including sep*/); + return 1; + } +} + +/* XXX: Output type could be encoded into native function 'magic' value to + * save space. For setters the stridx could be encoded into 'magic'. + */ + +DUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_getter(duk_hthread *thr) { + return duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_TRACEBACK); +} + +DUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_getter(duk_hthread *thr) { + return duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_FILENAME); +} + +DUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_hthread *thr) { + return duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_LINENUMBER); +} + +#else /* DUK_USE_TRACEBACKS */ + +/* + * Traceback handling when tracebacks disabled. + * + * The fileName / lineNumber stubs are now necessary because built-in + * data will include the accessor properties in Error.prototype. If those + * are removed for builds without tracebacks, these can also be removed. + * 'stack' should still be present and produce a ToString() equivalent: + * this is useful for user code which prints a stacktrace and expects to + * see something useful. A normal stacktrace also begins with a ToString() + * of the error so this makes sense. + */ + +DUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_getter(duk_hthread *thr) { + /* XXX: remove this native function and map 'stack' accessor + * to the toString() implementation directly. + */ + return duk_bi_error_prototype_to_string(thr); +} + +DUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_getter(duk_hthread *thr) { + DUK_UNREF(thr); + return 0; +} + +DUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_hthread *thr) { + DUK_UNREF(thr); + return 0; +} + +#endif /* DUK_USE_TRACEBACKS */ + +DUK_LOCAL duk_ret_t duk__error_setter_helper(duk_hthread *thr, duk_small_uint_t stridx_key) { + /* Attempt to write 'stack', 'fileName', 'lineNumber' works as if + * user code called Object.defineProperty() to create an overriding + * own property. This allows user code to overwrite .fileName etc + * intuitively as e.g. "err.fileName = 'dummy'" as one might expect. + * See https://github.com/svaarala/duktape/issues/387. + */ + + DUK_ASSERT_TOP(thr, 1); /* fixed arg count: value */ + + duk_push_this(thr); + duk_push_hstring_stridx(thr, stridx_key); + duk_dup_0(thr); + + /* [ ... obj key value ] */ + + DUK_DD(DUK_DDPRINT("error setter: %!T %!T %!T", + duk_get_tval(thr, -3), duk_get_tval(thr, -2), duk_get_tval(thr, -1))); + + duk_def_prop(thr, -3, DUK_DEFPROP_HAVE_VALUE | + DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE | + DUK_DEFPROP_HAVE_ENUMERABLE | /*not enumerable*/ + DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE); + return 0; +} + +DUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_setter(duk_hthread *thr) { + return duk__error_setter_helper(thr, DUK_STRIDX_STACK); +} + +DUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_setter(duk_hthread *thr) { + return duk__error_setter_helper(thr, DUK_STRIDX_FILE_NAME); +} + +DUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_setter(duk_hthread *thr) { + return duk__error_setter_helper(thr, DUK_STRIDX_LINE_NUMBER); +} diff --git a/third_party/duktape/duk_bi_function.c b/third_party/duktape/duk_bi_function.c new file mode 100644 index 00000000..ac6125e6 --- /dev/null +++ b/third_party/duktape/duk_bi_function.c @@ -0,0 +1,453 @@ +/* + * Function built-ins + */ + +#include "third_party/duktape/duk_internal.h" + +/* Needed even when Function built-in is disabled. */ +DUK_INTERNAL duk_ret_t duk_bi_function_prototype(duk_hthread *thr) { + /* ignore arguments, return undefined (E5 Section 15.3.4) */ + DUK_UNREF(thr); + return 0; +} + +#if defined(DUK_USE_FUNCTION_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_function_constructor(duk_hthread *thr) { + duk_hstring *h_sourcecode; + duk_idx_t nargs; + duk_idx_t i; + duk_small_uint_t comp_flags; + duk_hcompfunc *func; + duk_hobject *outer_lex_env; + duk_hobject *outer_var_env; + + /* normal and constructor calls have identical semantics */ + + nargs = duk_get_top(thr); + for (i = 0; i < nargs; i++) { + duk_to_string(thr, i); /* Rejects Symbols during coercion. */ + } + + if (nargs == 0) { + duk_push_hstring_empty(thr); + duk_push_hstring_empty(thr); + } else if (nargs == 1) { + /* XXX: cover this with the generic >1 case? */ + duk_push_hstring_empty(thr); + } else { + duk_insert(thr, 0); /* [ arg1 ... argN-1 body] -> [body arg1 ... argN-1] */ + duk_push_literal(thr, ","); + duk_insert(thr, 1); + duk_join(thr, nargs - 1); + } + + /* [ body formals ], formals is comma separated list that needs to be parsed */ + + DUK_ASSERT_TOP(thr, 2); + + /* XXX: this placeholder is not always correct, but use for now. + * It will fail in corner cases; see test-dev-func-cons-args.js. + */ + duk_push_literal(thr, "function("); + duk_dup_1(thr); + duk_push_literal(thr, "){"); + duk_dup_0(thr); + duk_push_literal(thr, "\n}"); /* Newline is important to handle trailing // comment. */ + duk_concat(thr, 5); + + /* [ body formals source ] */ + + DUK_ASSERT_TOP(thr, 3); + + /* strictness is not inherited, intentional */ + comp_flags = DUK_COMPILE_FUNCEXPR; + + duk_push_hstring_stridx(thr, DUK_STRIDX_COMPILE); /* XXX: copy from caller? */ /* XXX: ignored now */ + h_sourcecode = duk_require_hstring(thr, -2); /* no symbol check needed; -2 is concat'd code */ + duk_js_compile(thr, + (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_sourcecode), + (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sourcecode), + comp_flags); + + /* Force .name to 'anonymous' (ES2015). */ + duk_push_literal(thr, "anonymous"); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C); + + func = (duk_hcompfunc *) duk_known_hobject(thr, -1); + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) func)); + DUK_ASSERT(DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) func)); + + /* [ body formals source template ] */ + + /* only outer_lex_env matters, as functions always get a new + * variable declaration environment. + */ + + outer_lex_env = thr->builtins[DUK_BIDX_GLOBAL_ENV]; + outer_var_env = thr->builtins[DUK_BIDX_GLOBAL_ENV]; + + duk_js_push_closure(thr, func, outer_var_env, outer_lex_env, 1 /*add_auto_proto*/); + + /* [ body formals source template closure ] */ + + return 1; +} +#endif /* DUK_USE_FUNCTION_BUILTIN */ + +#if defined(DUK_USE_FUNCTION_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_function_prototype_to_string(duk_hthread *thr) { + duk_tval *tv; + + /* + * E5 Section 15.3.4.2 places few requirements on the output of + * this function: the result is implementation dependent, must + * follow FunctionDeclaration syntax (in particular, must have a + * name even for anonymous functions or functions with empty name). + * The output does NOT need to compile into anything useful. + * + * E6 Section 19.2.3.5 changes the requirements completely: the + * result must either eval() to a functionally equivalent object + * OR eval() to a SyntaxError. + * + * We opt for the SyntaxError approach for now, with a syntax that + * mimics V8's native function syntax: + * + * 'function cos() { [native code] }' + * + * but extended with [ecmascript code], [bound code], and + * [lightfunc code]. + */ + + duk_push_this(thr); + tv = DUK_GET_TVAL_NEGIDX(thr, -1); + DUK_ASSERT(tv != NULL); + + if (DUK_TVAL_IS_OBJECT(tv)) { + duk_hobject *obj = DUK_TVAL_GET_OBJECT(tv); + const char *func_name; + + /* Function name: missing/undefined is mapped to empty string, + * otherwise coerce to string. No handling for invalid identifier + * characters or e.g. '{' in the function name. This doesn't + * really matter as long as a SyntaxError results. Technically + * if the name contained a suitable prefix followed by '//' it + * might cause the result to parse without error. + */ + duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME); + if (duk_is_undefined(thr, -1)) { + func_name = ""; + } else { + func_name = duk_to_string(thr, -1); + DUK_ASSERT(func_name != NULL); + } + + if (DUK_HOBJECT_IS_COMPFUNC(obj)) { + duk_push_sprintf(thr, "function %s() { [ecmascript code] }", (const char *) func_name); + } else if (DUK_HOBJECT_IS_NATFUNC(obj)) { + duk_push_sprintf(thr, "function %s() { [native code] }", (const char *) func_name); + } else if (DUK_HOBJECT_IS_BOUNDFUNC(obj)) { + duk_push_sprintf(thr, "function %s() { [bound code] }", (const char *) func_name); + } else { + goto type_error; + } + } else if (DUK_TVAL_IS_LIGHTFUNC(tv)) { + duk_push_lightfunc_tostring(thr, tv); + } else { + goto type_error; + } + + return 1; + + type_error: + DUK_DCERROR_TYPE_INVALID_ARGS(thr); +} +#endif + +/* Always present because the native function pointer is needed in call + * handling. + */ +DUK_INTERNAL duk_ret_t duk_bi_function_prototype_call(duk_hthread *thr) { + /* .call() is dealt with in call handling by simulating its + * effects so this function is actually never called. + */ + DUK_UNREF(thr); + return DUK_RET_TYPE_ERROR; +} + +DUK_INTERNAL duk_ret_t duk_bi_function_prototype_apply(duk_hthread *thr) { + /* Like .call(), never actually called. */ + DUK_UNREF(thr); + return DUK_RET_TYPE_ERROR; +} + +DUK_INTERNAL duk_ret_t duk_bi_reflect_apply(duk_hthread *thr) { + /* Like .call(), never actually called. */ + DUK_UNREF(thr); + return DUK_RET_TYPE_ERROR; +} + +DUK_INTERNAL duk_ret_t duk_bi_reflect_construct(duk_hthread *thr) { + /* Like .call(), never actually called. */ + DUK_UNREF(thr); + return DUK_RET_TYPE_ERROR; +} + +#if defined(DUK_USE_FUNCTION_BUILTIN) +/* Create a bound function which points to a target function which may + * be bound or non-bound. If the target is bound, the argument lists + * and 'this' binding of the functions are merged and the resulting + * function points directly to the non-bound target. + */ +DUK_INTERNAL duk_ret_t duk_bi_function_prototype_bind(duk_hthread *thr) { + duk_hboundfunc *h_bound; + duk_idx_t nargs; /* bound args, not counting 'this' binding */ + duk_idx_t bound_nargs; + duk_int_t bound_len; + duk_tval *tv_prevbound; + duk_idx_t n_prevbound; + duk_tval *tv_res; + duk_tval *tv_tmp; + + /* XXX: C API call, e.g. duk_push_bound_function(thr, target_idx, nargs); */ + + /* Vararg function, careful arg handling, e.g. thisArg may not + * be present. + */ + nargs = duk_get_top(thr) - 1; /* actual args, not counting 'this' binding */ + if (nargs < 0) { + nargs++; + duk_push_undefined(thr); + } + DUK_ASSERT(nargs >= 0); + + /* Limit 'nargs' for bound functions to guarantee arithmetic + * below will never wrap. + */ + if (nargs > (duk_idx_t) DUK_HBOUNDFUNC_MAX_ARGS) { + DUK_DCERROR_RANGE_INVALID_COUNT(thr); + } + + duk_push_this(thr); + duk_require_callable(thr, -1); + + /* [ thisArg arg1 ... argN func ] (thisArg+args == nargs+1 total) */ + DUK_ASSERT_TOP(thr, nargs + 2); + + /* Create bound function object. */ + h_bound = duk_push_hboundfunc(thr); + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&h_bound->target)); + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&h_bound->this_binding)); + DUK_ASSERT(h_bound->args == NULL); + DUK_ASSERT(h_bound->nargs == 0); + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_bound) == NULL); + + /* [ thisArg arg1 ... argN func boundFunc ] */ + + /* If the target is a bound function, argument lists must be + * merged. The 'this' binding closest to the target function + * wins because in call handling the 'this' gets replaced over + * and over again until we call the non-bound function. + */ + tv_prevbound = NULL; + n_prevbound = 0; + tv_tmp = DUK_GET_TVAL_POSIDX(thr, 0); + DUK_TVAL_SET_TVAL(&h_bound->this_binding, tv_tmp); + tv_tmp = DUK_GET_TVAL_NEGIDX(thr, -2); + DUK_TVAL_SET_TVAL(&h_bound->target, tv_tmp); + + if (DUK_TVAL_IS_OBJECT(tv_tmp)) { + duk_hobject *h_target; + duk_hobject *bound_proto; + + h_target = DUK_TVAL_GET_OBJECT(tv_tmp); + DUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(h_target)); + + /* Internal prototype must be copied from the target. + * For lightfuncs Function.prototype is used and is already + * in place. + */ + bound_proto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_target); + DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) h_bound, bound_proto); + + /* The 'strict' flag is copied to get the special [[Get]] of E5.1 + * Section 15.3.5.4 to apply when a 'caller' value is a strict bound + * function. Not sure if this is correct, because the specification + * is a bit ambiguous on this point but it would make sense. + */ + /* Strictness is inherited from target. */ + if (DUK_HOBJECT_HAS_STRICT(h_target)) { + DUK_HOBJECT_SET_STRICT((duk_hobject *) h_bound); + } + + if (DUK_HOBJECT_HAS_BOUNDFUNC(h_target)) { + duk_hboundfunc *h_boundtarget; + + h_boundtarget = (duk_hboundfunc *) (void *) h_target; + + /* The final function should always be non-bound, unless + * there's a bug in the internals. Assert for it. + */ + DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(&h_boundtarget->target) || + (DUK_TVAL_IS_OBJECT(&h_boundtarget->target) && + DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(&h_boundtarget->target)) && + !DUK_HOBJECT_IS_BOUNDFUNC(DUK_TVAL_GET_OBJECT(&h_boundtarget->target)))); + + DUK_TVAL_SET_TVAL(&h_bound->target, &h_boundtarget->target); + DUK_TVAL_SET_TVAL(&h_bound->this_binding, &h_boundtarget->this_binding); + + tv_prevbound = h_boundtarget->args; + n_prevbound = h_boundtarget->nargs; + } + } else { + /* Lightfuncs are always strict. */ + duk_hobject *bound_proto; + + DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_tmp)); + DUK_HOBJECT_SET_STRICT((duk_hobject *) h_bound); + bound_proto = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]; + DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) h_bound, bound_proto); + } + + DUK_TVAL_INCREF(thr, &h_bound->target); /* old values undefined, no decref needed */ + DUK_TVAL_INCREF(thr, &h_bound->this_binding); + + bound_nargs = n_prevbound + nargs; + if (bound_nargs > (duk_idx_t) DUK_HBOUNDFUNC_MAX_ARGS) { + DUK_DCERROR_RANGE_INVALID_COUNT(thr); + } + tv_res = (duk_tval *) DUK_ALLOC_CHECKED(thr, ((duk_size_t) bound_nargs) * sizeof(duk_tval)); + DUK_ASSERT(tv_res != NULL || bound_nargs == 0); + DUK_ASSERT(h_bound->args == NULL); + DUK_ASSERT(h_bound->nargs == 0); + h_bound->args = tv_res; + h_bound->nargs = bound_nargs; + + DUK_ASSERT(n_prevbound >= 0); + duk_copy_tvals_incref(thr, tv_res, tv_prevbound, (duk_size_t) n_prevbound); + DUK_ASSERT(nargs >= 0); + duk_copy_tvals_incref(thr, tv_res + n_prevbound, DUK_GET_TVAL_POSIDX(thr, 1), (duk_size_t) nargs); + + /* [ thisArg arg1 ... argN func boundFunc ] */ + + /* Bound function 'length' property is interesting. + * For lightfuncs, simply read the virtual property. + */ + duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH); + bound_len = duk_get_int(thr, -1); /* ES2015: no coercion */ + if (bound_len < nargs) { + bound_len = 0; + } else { + bound_len -= nargs; + } + if (sizeof(duk_int_t) > 4 && bound_len > (duk_int_t) DUK_UINT32_MAX) { + bound_len = (duk_int_t) DUK_UINT32_MAX; + } + duk_pop(thr); + DUK_ASSERT(bound_len >= 0); + tv_tmp = thr->valstack_top++; + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_tmp)); + DUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv_tmp)); + DUK_TVAL_SET_U32(tv_tmp, (duk_uint32_t) bound_len); /* in-place update, fastint */ + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C); /* attrs in E6 Section 9.2.4 */ + + /* XXX: could these be virtual? */ + /* Caller and arguments must use the same thrower, [[ThrowTypeError]]. */ + duk_xdef_prop_stridx_thrower(thr, -1, DUK_STRIDX_CALLER); + duk_xdef_prop_stridx_thrower(thr, -1, DUK_STRIDX_LC_ARGUMENTS); + + /* Function name and fileName (non-standard). */ + duk_push_literal(thr, "bound "); /* ES2015 19.2.3.2. */ + duk_get_prop_stridx(thr, -3, DUK_STRIDX_NAME); + if (!duk_is_string_notsymbol(thr, -1)) { + /* ES2015 has requirement to check that .name of target is a string + * (also must check for Symbol); if not, targetName should be the + * empty string. ES2015 19.2.3.2. + */ + duk_pop(thr); + duk_push_hstring_empty(thr); + } + duk_concat(thr, 2); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C); +#if defined(DUK_USE_FUNC_FILENAME_PROPERTY) + duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C); +#endif + + DUK_DDD(DUK_DDDPRINT("created bound function: %!iT", (duk_tval *) duk_get_tval(thr, -1))); + + return 1; +} +#endif /* DUK_USE_FUNCTION_BUILTIN */ + +/* %NativeFunctionPrototype% .length getter. */ +DUK_INTERNAL duk_ret_t duk_bi_native_function_length(duk_hthread *thr) { + duk_tval *tv; + duk_hnatfunc *h; + duk_int16_t func_nargs; + + tv = duk_get_borrowed_this_tval(thr); + DUK_ASSERT(tv != NULL); + + if (DUK_TVAL_IS_OBJECT(tv)) { + h = (duk_hnatfunc *) DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + if (!DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h)) { + goto fail_type; + } + func_nargs = h->nargs; + duk_push_int(thr, func_nargs == DUK_HNATFUNC_NARGS_VARARGS ? 0 : func_nargs); + } else if (DUK_TVAL_IS_LIGHTFUNC(tv)) { + duk_small_uint_t lf_flags; + duk_small_uint_t lf_len; + + lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv); + lf_len = DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags); + duk_push_uint(thr, lf_len); + } else { + goto fail_type; + } + return 1; + + fail_type: + DUK_DCERROR_TYPE_INVALID_ARGS(thr); +} + +/* %NativeFunctionPrototype% .name getter. */ +DUK_INTERNAL duk_ret_t duk_bi_native_function_name(duk_hthread *thr) { + duk_tval *tv; + duk_hnatfunc *h; + + tv = duk_get_borrowed_this_tval(thr); + DUK_ASSERT(tv != NULL); + + if (DUK_TVAL_IS_OBJECT(tv)) { + h = (duk_hnatfunc *) DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + if (!DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h)) { + goto fail_type; + } +#if 0 + duk_push_hnatfunc_name(thr, h); +#endif + duk_push_hstring_empty(thr); + } else if (DUK_TVAL_IS_LIGHTFUNC(tv)) { + duk_push_lightfunc_name(thr, tv); + } else { + goto fail_type; + } + return 1; + + fail_type: + DUK_DCERROR_TYPE_INVALID_ARGS(thr); +} + +#if defined(DUK_USE_SYMBOL_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_function_prototype_hasinstance(duk_hthread *thr) { + /* This binding: RHS, stack index 0: LHS. */ + duk_bool_t ret; + + ret = duk_js_instanceof_ordinary(thr, DUK_GET_TVAL_POSIDX(thr, 0), DUK_GET_THIS_TVAL_PTR(thr)); + duk_push_boolean(thr, ret); + return 1; +} +#endif /* DUK_USE_SYMBOL_BUILTIN */ diff --git a/third_party/duktape/duk_bi_global.c b/third_party/duktape/duk_bi_global.c new file mode 100644 index 00000000..a370f5cd --- /dev/null +++ b/third_party/duktape/duk_bi_global.c @@ -0,0 +1,785 @@ +/* + * Global object built-ins + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Encoding/decoding helpers + */ + +/* XXX: Could add fast path (for each transform callback) with direct byte + * lookups (no shifting) and no explicit check for x < 0x80 before table + * lookup. + */ + +/* Macros for creating and checking bitmasks for character encoding. + * Bit number is a bit counterintuitive, but minimizes code size. + */ +#define DUK__MKBITS(a, b, c, d, e, f, g, h) \ + ((duk_uint8_t)(((a) << 0) | ((b) << 1) | ((c) << 2) | ((d) << 3) | \ + ((e) << 4) | ((f) << 5) | ((g) << 6) | ((h) << 7))) +#define DUK__CHECK_BITMASK(table, cp) ((table)[(cp) >> 3] & (1u << ((cp)&0x07))) + +/* E5.1 Section 15.1.3.3: uriReserved + uriUnescaped + '#' */ +DUK_LOCAL const duk_uint8_t duk__encode_uriunescaped_table[16] = { + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x00-0x0f */ + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x10-0x1f */ + DUK__MKBITS(0, 1, 0, 1, 1, 0, 1, 1), + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), /* 0x20-0x2f */ + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), + DUK__MKBITS(1, 1, 1, 1, 0, 1, 0, 1), /* 0x30-0x3f */ + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), /* 0x40-0x4f */ + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), + DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 1), /* 0x50-0x5f */ + DUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), /* 0x60-0x6f */ + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), + DUK__MKBITS(1, 1, 1, 0, 0, 0, 1, 0), /* 0x70-0x7f */ +}; + +/* E5.1 Section 15.1.3.4: uriUnescaped */ +DUK_LOCAL const duk_uint8_t duk__encode_uricomponent_unescaped_table[16] = { + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x00-0x0f */ + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x10-0x1f */ + DUK__MKBITS(0, 1, 0, 0, 0, 0, 0, 1), + DUK__MKBITS(1, 1, 1, 0, 0, 1, 1, 0), /* 0x20-0x2f */ + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), + DUK__MKBITS(1, 1, 0, 0, 0, 0, 0, 0), /* 0x30-0x3f */ + DUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), /* 0x40-0x4f */ + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), + DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 1), /* 0x50-0x5f */ + DUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), /* 0x60-0x6f */ + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), + DUK__MKBITS(1, 1, 1, 0, 0, 0, 1, 0), /* 0x70-0x7f */ +}; + +/* E5.1 Section 15.1.3.1: uriReserved + '#' */ +DUK_LOCAL const duk_uint8_t duk__decode_uri_reserved_table[16] = { + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x00-0x0f */ + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x10-0x1f */ + DUK__MKBITS(0, 0, 0, 1, 1, 0, 1, 0), + DUK__MKBITS(0, 0, 0, 1, 1, 0, 0, 1), /* 0x20-0x2f */ + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 1, 1, 0, 1, 0, 1), /* 0x30-0x3f */ + DUK__MKBITS(1, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x40-0x4f */ + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x50-0x5f */ + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x60-0x6f */ + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x70-0x7f */ +}; + +/* E5.1 Section 15.1.3.2: empty */ +DUK_LOCAL const duk_uint8_t duk__decode_uri_component_reserved_table[16] = { + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x00-0x0f */ + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x10-0x1f */ + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x20-0x2f */ + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x30-0x3f */ + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x40-0x4f */ + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x50-0x5f */ + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x60-0x6f */ + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x70-0x7f */ +}; + +#if defined(DUK_USE_SECTION_B) +/* E5.1 Section B.2.2, step 7. */ +DUK_LOCAL const duk_uint8_t duk__escape_unescaped_table[16] = { + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x00-0x0f */ + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x10-0x1f */ + DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), + DUK__MKBITS(0, 0, 1, 1, 0, 1, 1, 1), /* 0x20-0x2f */ + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), + DUK__MKBITS(1, 1, 0, 0, 0, 0, 0, 0), /* 0x30-0x3f */ + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), /* 0x40-0x4f */ + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), + DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 1), /* 0x50-0x5f */ + DUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), /* 0x60-0x6f */ + DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), + DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 0) /* 0x70-0x7f */ +}; +#endif /* DUK_USE_SECTION_B */ + +typedef struct { + duk_hthread *thr; + duk_hstring *h_str; + duk_bufwriter_ctx bw; + const duk_uint8_t *p; + const duk_uint8_t *p_start; + const duk_uint8_t *p_end; +} duk__transform_context; + +typedef void (*duk__transform_callback)(duk__transform_context *tfm_ctx, + const void *udata, duk_codepoint_t cp); + +/* XXX: refactor and share with other code */ +DUK_LOCAL duk_small_int_t duk__decode_hex_escape(const duk_uint8_t *p, + duk_small_int_t n) { + duk_small_int_t ch; + duk_small_int_t t = 0; + + while (n > 0) { + t = t * 16; + ch = (duk_small_int_t)duk_hex_dectab[*p++]; + if (DUK_LIKELY(ch >= 0)) { + t += ch; + } else { + return -1; + } + n--; + } + return t; +} + +DUK_LOCAL int duk__transform_helper(duk_hthread *thr, + duk__transform_callback callback, + const void *udata) { + duk__transform_context tfm_ctx_alloc; + duk__transform_context *tfm_ctx = &tfm_ctx_alloc; + duk_codepoint_t cp; + + tfm_ctx->thr = thr; + + tfm_ctx->h_str = duk_to_hstring(thr, 0); + DUK_ASSERT(tfm_ctx->h_str != NULL); + + DUK_BW_INIT_PUSHBUF( + thr, &tfm_ctx->bw, + DUK_HSTRING_GET_BYTELEN(tfm_ctx->h_str)); /* initial size guess */ + + tfm_ctx->p_start = DUK_HSTRING_GET_DATA(tfm_ctx->h_str); + tfm_ctx->p_end = tfm_ctx->p_start + DUK_HSTRING_GET_BYTELEN(tfm_ctx->h_str); + tfm_ctx->p = tfm_ctx->p_start; + + while (tfm_ctx->p < tfm_ctx->p_end) { + cp = (duk_codepoint_t)duk_unicode_decode_xutf8_checked( + thr, &tfm_ctx->p, tfm_ctx->p_start, tfm_ctx->p_end); + callback(tfm_ctx, udata, cp); + } + + DUK_BW_COMPACT(thr, &tfm_ctx->bw); + + (void)duk_buffer_to_string(thr, -1); /* Safe if transform is safe. */ + return 1; +} + +DUK_LOCAL void duk__transform_callback_encode_uri( + duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) { + duk_uint8_t xutf8_buf[DUK_UNICODE_MAX_XUTF8_LENGTH]; + duk_small_int_t len; + duk_codepoint_t cp1, cp2; + duk_small_int_t i, t; + const duk_uint8_t *unescaped_table = (const duk_uint8_t *)udata; + + /* UTF-8 encoded bytes escaped as %xx%xx%xx... -> 3 * nbytes. + * Codepoint range is restricted so this is a slightly too large + * but doesn't matter. + */ + DUK_BW_ENSURE(tfm_ctx->thr, &tfm_ctx->bw, 3 * DUK_UNICODE_MAX_XUTF8_LENGTH); + + if (cp < 0) { + goto uri_error; + } else if ((cp < 0x80L) && DUK__CHECK_BITMASK(unescaped_table, cp)) { + DUK_BW_WRITE_RAW_U8(tfm_ctx->thr, &tfm_ctx->bw, (duk_uint8_t)cp); + return; + } else if (cp >= 0xdc00L && cp <= 0xdfffL) { + goto uri_error; + } else if (cp >= 0xd800L && cp <= 0xdbffL) { + /* Needs lookahead */ + if (duk_unicode_decode_xutf8(tfm_ctx->thr, &tfm_ctx->p, tfm_ctx->p_start, + tfm_ctx->p_end, + (duk_ucodepoint_t *)&cp2) == 0) { + goto uri_error; + } + if (!(cp2 >= 0xdc00L && cp2 <= 0xdfffL)) { + goto uri_error; + } + cp1 = cp; + cp = + (duk_codepoint_t)(((cp1 - 0xd800L) << 10) + (cp2 - 0xdc00L) + 0x10000L); + } else if (cp > 0x10ffffL) { + /* Although we can allow non-BMP characters (they'll decode + * back into surrogate pairs), we don't allow extended UTF-8 + * characters; they would encode to URIs which won't decode + * back because of strict UTF-8 checks in URI decoding. + * (However, we could just as well allow them here.) + */ + goto uri_error; + } else { + /* Non-BMP characters within valid UTF-8 range: encode as is. + * They'll decode back into surrogate pairs if the escaped + * output is decoded. + */ + ; + } + + len = duk_unicode_encode_xutf8((duk_ucodepoint_t)cp, xutf8_buf); + for (i = 0; i < len; i++) { + t = (duk_small_int_t)xutf8_buf[i]; + DUK_BW_WRITE_RAW_U8_3(tfm_ctx->thr, &tfm_ctx->bw, DUK_ASC_PERCENT, + (duk_uint8_t)duk_uc_nybbles[t >> 4], + (duk_uint8_t)duk_uc_nybbles[t & 0x0f]); + } + + return; + +uri_error: + DUK_ERROR_URI(tfm_ctx->thr, DUK_STR_INVALID_INPUT); + DUK_WO_NORETURN(return;); +} + +DUK_LOCAL void duk__transform_callback_decode_uri( + duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) { + const duk_uint8_t *reserved_table = (const duk_uint8_t *)udata; + duk_small_uint_t utf8_blen; + duk_codepoint_t min_cp; + duk_small_int_t t; /* must be signed */ + duk_small_uint_t i; + + /* Maximum write size: XUTF8 path writes max DUK_UNICODE_MAX_XUTF8_LENGTH, + * percent escape path writes max two times CESU-8 encoded BMP length. + */ + DUK_BW_ENSURE( + tfm_ctx->thr, &tfm_ctx->bw, + (DUK_UNICODE_MAX_XUTF8_LENGTH >= 2 * DUK_UNICODE_MAX_CESU8_BMP_LENGTH + ? DUK_UNICODE_MAX_XUTF8_LENGTH + : DUK_UNICODE_MAX_CESU8_BMP_LENGTH)); + + if (cp == (duk_codepoint_t)'%') { + const duk_uint8_t *p = tfm_ctx->p; + duk_size_t left = (duk_size_t)(tfm_ctx->p_end - p); /* bytes left */ + + DUK_DDD(DUK_DDDPRINT("percent encoding, left=%ld", (long)left)); + + if (left < 2) { + goto uri_error; + } + + t = duk__decode_hex_escape(p, 2); + DUK_DDD(DUK_DDDPRINT("first byte: %ld", (long)t)); + if (t < 0) { + goto uri_error; + } + + if (t < 0x80) { + if (DUK__CHECK_BITMASK(reserved_table, t)) { + /* decode '%xx' to '%xx' if decoded char in reserved set */ + DUK_ASSERT(tfm_ctx->p - 1 >= tfm_ctx->p_start); + DUK_BW_WRITE_RAW_U8_3(tfm_ctx->thr, &tfm_ctx->bw, DUK_ASC_PERCENT, p[0], + p[1]); + } else { + DUK_BW_WRITE_RAW_U8(tfm_ctx->thr, &tfm_ctx->bw, (duk_uint8_t)t); + } + tfm_ctx->p += 2; + return; + } + + /* Decode UTF-8 codepoint from a sequence of hex escapes. The + * first byte of the sequence has been decoded to 't'. + * + * Note that UTF-8 validation must be strict according to the + * specification: E5.1 Section 15.1.3, decode algorithm step + * 4.d.vii.8. URIError from non-shortest encodings is also + * specifically noted in the spec. + */ + + DUK_ASSERT(t >= 0x80); + if (t < 0xc0) { + /* continuation byte */ + goto uri_error; + } else if (t < 0xe0) { + /* 110x xxxx; 2 bytes */ + utf8_blen = 2; + min_cp = 0x80L; + cp = t & 0x1f; + } else if (t < 0xf0) { + /* 1110 xxxx; 3 bytes */ + utf8_blen = 3; + min_cp = 0x800L; + cp = t & 0x0f; + } else if (t < 0xf8) { + /* 1111 0xxx; 4 bytes */ + utf8_blen = 4; + min_cp = 0x10000L; + cp = t & 0x07; + } else { + /* extended utf-8 not allowed for URIs */ + goto uri_error; + } + + if (left < utf8_blen * 3 - 1) { + /* '%xx%xx...%xx', p points to char after first '%' */ + goto uri_error; + } + + p += 3; + for (i = 1; i < utf8_blen; i++) { + /* p points to digit part ('%xy', p points to 'x') */ + t = duk__decode_hex_escape(p, 2); + DUK_DDD(DUK_DDDPRINT("i=%ld utf8_blen=%ld cp=%ld t=0x%02lx", (long)i, + (long)utf8_blen, (long)cp, (unsigned long)t)); + if (t < 0) { + goto uri_error; + } + if ((t & 0xc0) != 0x80) { + goto uri_error; + } + cp = (cp << 6) + (t & 0x3f); + p += 3; + } + p--; /* p overshoots */ + tfm_ctx->p = p; + + DUK_DDD(DUK_DDDPRINT("final cp=%ld, min_cp=%ld", (long)cp, (long)min_cp)); + + if (cp < min_cp || cp > 0x10ffffL || (cp >= 0xd800L && cp <= 0xdfffL)) { + goto uri_error; + } + + /* The E5.1 algorithm checks whether or not a decoded codepoint + * is below 0x80 and perhaps may be in the "reserved" set. + * This seems pointless because the single byte UTF-8 case is + * handled separately, and non-shortest encodings are rejected. + * So, 'cp' cannot be below 0x80 here, and thus cannot be in + * the reserved set. + */ + + /* utf-8 validation ensures these */ + DUK_ASSERT(cp >= 0x80L && cp <= 0x10ffffL); + + if (cp >= 0x10000L) { + cp -= 0x10000L; + DUK_ASSERT(cp < 0x100000L); + + DUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, + ((cp >> 10) + 0xd800L)); + DUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, + ((cp & 0x03ffL) + 0xdc00L)); + } else { + DUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, cp); + } + } else { + DUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, cp); + } + return; + +uri_error: + DUK_ERROR_URI(tfm_ctx->thr, DUK_STR_INVALID_INPUT); + DUK_WO_NORETURN(return;); +} + +#if defined(DUK_USE_SECTION_B) +DUK_LOCAL void duk__transform_callback_escape(duk__transform_context *tfm_ctx, + const void *udata, + duk_codepoint_t cp) { + DUK_UNREF(udata); + + DUK_BW_ENSURE(tfm_ctx->thr, &tfm_ctx->bw, 6); + + if (cp < 0) { + goto esc_error; + } else if ((cp < 0x80L) && + DUK__CHECK_BITMASK(duk__escape_unescaped_table, cp)) { + DUK_BW_WRITE_RAW_U8(tfm_ctx->thr, &tfm_ctx->bw, (duk_uint8_t)cp); + } else if (cp < 0x100L) { + DUK_BW_WRITE_RAW_U8_3(tfm_ctx->thr, &tfm_ctx->bw, + (duk_uint8_t)DUK_ASC_PERCENT, + (duk_uint8_t)duk_uc_nybbles[cp >> 4], + (duk_uint8_t)duk_uc_nybbles[cp & 0x0f]); + } else if (cp < 0x10000L) { + DUK_BW_WRITE_RAW_U8_6( + tfm_ctx->thr, &tfm_ctx->bw, (duk_uint8_t)DUK_ASC_PERCENT, + (duk_uint8_t)DUK_ASC_LC_U, (duk_uint8_t)duk_uc_nybbles[cp >> 12], + (duk_uint8_t)duk_uc_nybbles[(cp >> 8) & 0x0f], + (duk_uint8_t)duk_uc_nybbles[(cp >> 4) & 0x0f], + (duk_uint8_t)duk_uc_nybbles[cp & 0x0f]); + } else { + /* Characters outside BMP cannot be escape()'d. We could + * encode them as surrogate pairs (for codepoints inside + * valid UTF-8 range, but not extended UTF-8). Because + * escape() and unescape() are legacy functions, we don't. + */ + goto esc_error; + } + + return; + +esc_error: + DUK_ERROR_TYPE(tfm_ctx->thr, DUK_STR_INVALID_INPUT); + DUK_WO_NORETURN(return;); +} + +DUK_LOCAL void duk__transform_callback_unescape(duk__transform_context *tfm_ctx, + const void *udata, + duk_codepoint_t cp) { + duk_small_int_t t; + + DUK_UNREF(udata); + + if (cp == (duk_codepoint_t)'%') { + const duk_uint8_t *p = tfm_ctx->p; + duk_size_t left = (duk_size_t)(tfm_ctx->p_end - p); /* bytes left */ + + if (left >= 5 && p[0] == 'u' && + ((t = duk__decode_hex_escape(p + 1, 4)) >= 0)) { + cp = (duk_codepoint_t)t; + tfm_ctx->p += 5; + } else if (left >= 2 && ((t = duk__decode_hex_escape(p, 2)) >= 0)) { + cp = (duk_codepoint_t)t; + tfm_ctx->p += 2; + } + } + + DUK_BW_WRITE_ENSURE_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, cp); +} +#endif /* DUK_USE_SECTION_B */ + +/* + * Eval + * + * Eval needs to handle both a "direct eval" and an "indirect eval". + * Direct eval handling needs access to the caller's activation so that its + * lexical environment can be accessed. A direct eval is only possible from + * ECMAScript code; an indirect eval call is possible also from C code. + * When an indirect eval call is made from C code, there may not be a + * calling activation at all which needs careful handling. + */ + +DUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_hthread *thr) { + duk_hstring *h; + duk_activation *act_caller; + duk_activation *act_eval; + duk_hcompfunc *func; + duk_hobject *outer_lex_env; + duk_hobject *outer_var_env; + duk_bool_t this_to_global = 1; + duk_small_uint_t comp_flags; + duk_int_t level = -2; + duk_small_uint_t call_flags; + + DUK_ASSERT(duk_get_top(thr) == 1 || + duk_get_top(thr) == 2); /* 2 when called by debugger */ + DUK_ASSERT(thr->callstack_top >= 1); /* at least this function exists */ + DUK_ASSERT(thr->callstack_curr != NULL); + DUK_ASSERT((thr->callstack_curr->flags & DUK_ACT_FLAG_DIRECT_EVAL) == + 0 || /* indirect eval */ + (thr->callstack_top >= + 2)); /* if direct eval, calling activation must exist */ + + /* + * callstack_top - 1 --> this function + * callstack_top - 2 --> caller (may not exist) + * + * If called directly from C, callstack_top might be 1. If calling + * activation doesn't exist, call must be indirect. + */ + + h = duk_get_hstring_notsymbol(thr, 0); + if (!h) { + /* Symbol must be returned as is, like any non-string values. */ + return 1; /* return arg as-is */ + } + +#if defined(DUK_USE_DEBUGGER_SUPPORT) + /* NOTE: level is used only by the debugger and should never be present + * for an ECMAScript eval(). + */ + DUK_ASSERT(level == -2); /* by default, use caller's environment */ + if (duk_get_top(thr) >= 2 && duk_is_number(thr, 1)) { + level = duk_get_int(thr, 1); + } + DUK_ASSERT(level <= -2); /* This is guaranteed by debugger code. */ +#endif + + /* [ source ] */ + + comp_flags = DUK_COMPILE_EVAL; + act_eval = thr->callstack_curr; /* this function */ + DUK_ASSERT(act_eval != NULL); + act_caller = duk_hthread_get_activation_for_level(thr, level); + if (act_caller != NULL) { + /* Have a calling activation, check for direct eval (otherwise + * assume indirect eval. + */ + if ((act_caller->flags & DUK_ACT_FLAG_STRICT) && + (act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL)) { + /* Only direct eval inherits strictness from calling code + * (E5.1 Section 10.1.1). + */ + comp_flags |= DUK_COMPILE_STRICT; + } + } else { + DUK_ASSERT((act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) == 0); + } + + duk_push_hstring_stridx(thr, DUK_STRIDX_INPUT); /* XXX: copy from caller? */ + duk_js_compile(thr, (const duk_uint8_t *)DUK_HSTRING_GET_DATA(h), + (duk_size_t)DUK_HSTRING_GET_BYTELEN(h), comp_flags); + func = (duk_hcompfunc *)duk_known_hobject(thr, -1); + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *)func)); + + /* [ source template ] */ + + /* E5 Section 10.4.2 */ + + if (act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) { + DUK_ASSERT(thr->callstack_top >= 2); + DUK_ASSERT(act_caller != NULL); + if (act_caller->lex_env == NULL) { + DUK_ASSERT(act_caller->var_env == NULL); + DUK_DDD(DUK_DDDPRINT("delayed environment initialization")); + + /* this may have side effects, so re-lookup act */ + duk_js_init_activation_environment_records_delayed(thr, act_caller); + } + DUK_ASSERT(act_caller->lex_env != NULL); + DUK_ASSERT(act_caller->var_env != NULL); + + this_to_global = 0; + + if (DUK_HOBJECT_HAS_STRICT((duk_hobject *)func)) { + duk_hdecenv *new_env; + duk_hobject *act_lex_env; + + DUK_DDD(DUK_DDDPRINT("direct eval call to a strict function -> " + "var_env and lex_env to a fresh env, " + "this_binding to caller's this_binding")); + + act_lex_env = act_caller->lex_env; + + new_env = duk_hdecenv_alloc( + thr, DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV)); + DUK_ASSERT(new_env != NULL); + duk_push_hobject(thr, (duk_hobject *)new_env); + + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *)new_env) == + NULL); + DUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *)new_env, act_lex_env); + DUK_HOBJECT_INCREF_ALLOWNULL(thr, act_lex_env); + DUK_DDD(DUK_DDDPRINT("new_env allocated: %!iO", (duk_heaphdr *)new_env)); + + outer_lex_env = (duk_hobject *)new_env; + outer_var_env = (duk_hobject *)new_env; + + duk_insert(thr, 0); /* stash to bottom of value stack to keep new_env + reachable for duration of eval */ + + /* compiler's responsibility */ + DUK_ASSERT(DUK_HOBJECT_HAS_NEWENV((duk_hobject *)func)); + } else { + DUK_DDD(DUK_DDDPRINT("direct eval call to a non-strict function -> " + "var_env and lex_env to caller's envs, " + "this_binding to caller's this_binding")); + + outer_lex_env = act_caller->lex_env; + outer_var_env = act_caller->var_env; + + /* compiler's responsibility */ + DUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV((duk_hobject *)func)); + } + } else { + DUK_DDD(DUK_DDDPRINT("indirect eval call -> var_env and lex_env to " + "global object, this_binding to global object")); + + this_to_global = 1; + outer_lex_env = thr->builtins[DUK_BIDX_GLOBAL_ENV]; + outer_var_env = thr->builtins[DUK_BIDX_GLOBAL_ENV]; + } + + /* Eval code doesn't need an automatic .prototype object. */ + duk_js_push_closure(thr, func, outer_var_env, outer_lex_env, + 0 /*add_auto_proto*/); + + /* [ env? source template closure ] */ + + if (this_to_global) { + DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL); + duk_push_hobject_bidx(thr, DUK_BIDX_GLOBAL); + } else { + duk_tval *tv; + DUK_ASSERT(thr->callstack_top >= 2); + DUK_ASSERT(act_caller != NULL); + tv = (duk_tval *)(void *)((duk_uint8_t *)thr->valstack + + act_caller->bottom_byteoff - + sizeof( + duk_tval)); /* this is just beneath bottom */ + DUK_ASSERT(tv >= thr->valstack); + duk_push_tval(thr, tv); + } + + DUK_DDD(DUK_DDDPRINT("eval -> lex_env=%!iO, var_env=%!iO, this_binding=%!T", + (duk_heaphdr *)outer_lex_env, + (duk_heaphdr *)outer_var_env, duk_get_tval(thr, -1))); + + /* [ env? source template closure this ] */ + + call_flags = 0; + if (act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) { + /* Set DIRECT_EVAL flag for the call; it's not strictly + * needed for the 'inner' eval call (the eval body) but + * current new.target implementation expects to find it + * so it can traverse direct eval chains up to the real + * calling function. + */ + call_flags |= DUK_CALL_FLAG_DIRECT_EVAL; + } + duk_handle_call_unprotected_nargs(thr, 0, call_flags); + + /* [ env? source template result ] */ + + return 1; +} + +/* + * Parsing of ints and floats + */ + +#if defined(DUK_USE_GLOBAL_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_global_object_parse_int(duk_hthread *thr) { + duk_int32_t radix; + duk_small_uint_t s2n_flags; + + DUK_ASSERT_TOP(thr, 2); + duk_to_string(thr, 0); /* Reject symbols. */ + + radix = duk_to_int32(thr, 1); + + /* While parseInt() recognizes 0xdeadbeef, it doesn't recognize + * ES2015 0o123 or 0b10001. + */ + s2n_flags = DUK_S2N_FLAG_TRIM_WHITE | DUK_S2N_FLAG_ALLOW_GARBAGE | + DUK_S2N_FLAG_ALLOW_PLUS | DUK_S2N_FLAG_ALLOW_MINUS | + DUK_S2N_FLAG_ALLOW_LEADING_ZERO | DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT; + + /* Specification stripPrefix maps to DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT. + * + * Don't autodetect octals (from leading zeroes), require user code to + * provide an explicit radix 8 for parsing octal. See write-up from Mozilla: + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt#ECMAScript_5_Removes_Octal_Interpretation + */ + + if (radix != 0) { + if (radix < 2 || radix > 36) { + goto ret_nan; + } + if (radix != 16) { + s2n_flags &= ~DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT; + } + } else { + radix = 10; + } + + duk_dup_0(thr); + duk_numconv_parse(thr, (duk_small_int_t)radix, s2n_flags); + return 1; + +ret_nan: + duk_push_nan(thr); + return 1; +} +#endif /* DUK_USE_GLOBAL_BUILTIN */ + +#if defined(DUK_USE_GLOBAL_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_global_object_parse_float(duk_hthread *thr) { + duk_small_uint_t s2n_flags; + + DUK_ASSERT_TOP(thr, 1); + duk_to_string(thr, 0); /* Reject symbols. */ + + /* XXX: check flags */ + s2n_flags = DUK_S2N_FLAG_TRIM_WHITE | DUK_S2N_FLAG_ALLOW_EXP | + DUK_S2N_FLAG_ALLOW_GARBAGE | DUK_S2N_FLAG_ALLOW_PLUS | + DUK_S2N_FLAG_ALLOW_MINUS | DUK_S2N_FLAG_ALLOW_INF | + DUK_S2N_FLAG_ALLOW_FRAC | DUK_S2N_FLAG_ALLOW_NAKED_FRAC | + DUK_S2N_FLAG_ALLOW_EMPTY_FRAC | DUK_S2N_FLAG_ALLOW_LEADING_ZERO; + + duk_numconv_parse(thr, 10 /*radix*/, s2n_flags); + return 1; +} +#endif /* DUK_USE_GLOBAL_BUILTIN */ + +/* + * Number checkers + */ + +#if defined(DUK_USE_GLOBAL_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_global_object_is_nan(duk_hthread *thr) { + duk_double_t d = duk_to_number(thr, 0); + duk_push_boolean(thr, (duk_bool_t)DUK_ISNAN(d)); + return 1; +} +#endif /* DUK_USE_GLOBAL_BUILTIN */ + +#if defined(DUK_USE_GLOBAL_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_global_object_is_finite(duk_hthread *thr) { + duk_double_t d = duk_to_number(thr, 0); + duk_push_boolean(thr, (duk_bool_t)DUK_ISFINITE(d)); + return 1; +} +#endif /* DUK_USE_GLOBAL_BUILTIN */ + +/* + * URI handling + */ + +#if defined(DUK_USE_GLOBAL_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_global_object_decode_uri(duk_hthread *thr) { + return duk__transform_helper(thr, duk__transform_callback_decode_uri, + (const void *)duk__decode_uri_reserved_table); +} + +DUK_INTERNAL duk_ret_t +duk_bi_global_object_decode_uri_component(duk_hthread *thr) { + return duk__transform_helper( + thr, duk__transform_callback_decode_uri, + (const void *)duk__decode_uri_component_reserved_table); +} + +DUK_INTERNAL duk_ret_t duk_bi_global_object_encode_uri(duk_hthread *thr) { + return duk__transform_helper(thr, duk__transform_callback_encode_uri, + (const void *)duk__encode_uriunescaped_table); +} + +DUK_INTERNAL duk_ret_t +duk_bi_global_object_encode_uri_component(duk_hthread *thr) { + return duk__transform_helper( + thr, duk__transform_callback_encode_uri, + (const void *)duk__encode_uricomponent_unescaped_table); +} + +#if defined(DUK_USE_SECTION_B) +DUK_INTERNAL duk_ret_t duk_bi_global_object_escape(duk_hthread *thr) { + return duk__transform_helper(thr, duk__transform_callback_escape, + (const void *)NULL); +} + +DUK_INTERNAL duk_ret_t duk_bi_global_object_unescape(duk_hthread *thr) { + return duk__transform_helper(thr, duk__transform_callback_unescape, + (const void *)NULL); +} +#endif /* DUK_USE_SECTION_B */ +#endif /* DUK_USE_GLOBAL_BUILTIN */ diff --git a/third_party/duktape/duk_bi_json.c b/third_party/duktape/duk_bi_json.c new file mode 100644 index 00000000..6aa4df72 --- /dev/null +++ b/third_party/duktape/duk_bi_json.c @@ -0,0 +1,3255 @@ +/* + * JSON built-ins. + * + * See doc/json.rst. + * + * Codepoints are handled as duk_uint_fast32_t to ensure that the full + * unsigned 32-bit range is supported. This matters to e.g. JX. + * + * Input parsing doesn't do an explicit end-of-input check at all. This is + * safe: input string data is always NUL-terminated (0x00) and valid JSON + * inputs never contain plain NUL characters, so that as long as syntax checks + * are correct, we'll never read past the NUL. This approach reduces code size + * and improves parsing performance, but it's critical that syntax checks are + * indeed correct! + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_JSON_SUPPORT) + +/* + * Local defines and forward declarations. + */ + +#define DUK__JSON_DECSTR_BUFSIZE 128 +#define DUK__JSON_DECSTR_CHUNKSIZE 64 +#define DUK__JSON_ENCSTR_CHUNKSIZE 64 +#define DUK__JSON_STRINGIFY_BUFSIZE 128 +#define DUK__JSON_MAX_ESC_LEN 10 /* '\Udeadbeef' */ + +DUK_LOCAL_DECL void duk__dec_syntax_error(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__dec_eat_white(duk_json_dec_ctx *js_ctx); +#if defined(DUK_USE_JX) +DUK_LOCAL_DECL duk_uint8_t duk__dec_peek(duk_json_dec_ctx *js_ctx); +#endif +DUK_LOCAL_DECL duk_uint8_t duk__dec_get(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL duk_uint8_t duk__dec_get_nonwhite(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n); +DUK_LOCAL_DECL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx); +DUK_LOCAL_DECL void duk__dec_string(duk_json_dec_ctx *js_ctx); +#if defined(DUK_USE_JX) +DUK_LOCAL_DECL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__dec_pointer(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__dec_buffer(duk_json_dec_ctx *js_ctx); +#endif +DUK_LOCAL_DECL void duk__dec_number(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__dec_objarr_entry(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__dec_objarr_exit(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__dec_object(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__dec_array(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__dec_value(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx); + +DUK_LOCAL_DECL void duk__emit_1(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch); +DUK_LOCAL_DECL void duk__emit_2(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch1, duk_uint_fast8_t ch2); +DUK_LOCAL_DECL void duk__unemit_1(duk_json_enc_ctx *js_ctx); +DUK_LOCAL_DECL void duk__emit_hstring(duk_json_enc_ctx *js_ctx, duk_hstring *h); +#if defined(DUK_USE_FASTINT) +DUK_LOCAL_DECL void duk__emit_cstring(duk_json_enc_ctx *js_ctx, const char *p); +#endif +DUK_LOCAL_DECL void duk__emit_stridx(duk_json_enc_ctx *js_ctx, duk_small_uint_t stridx); +DUK_LOCAL_DECL duk_uint8_t *duk__emit_esc_auto_fast(duk_json_enc_ctx *js_ctx, duk_uint_fast32_t cp, duk_uint8_t *q); +DUK_LOCAL_DECL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k); +DUK_LOCAL_DECL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str); +DUK_LOCAL_DECL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top); +DUK_LOCAL_DECL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top); +DUK_LOCAL_DECL void duk__enc_object(duk_json_enc_ctx *js_ctx); +DUK_LOCAL_DECL void duk__enc_array(duk_json_enc_ctx *js_ctx); +DUK_LOCAL_DECL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder); +DUK_LOCAL_DECL duk_bool_t duk__enc_allow_into_proplist(duk_tval *tv); +DUK_LOCAL_DECL void duk__enc_double(duk_json_enc_ctx *js_ctx); +#if defined(DUK_USE_FASTINT) +DUK_LOCAL_DECL void duk__enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv); +#endif +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) +DUK_LOCAL_DECL void duk__enc_buffer_jx_jc(duk_json_enc_ctx *js_ctx, duk_hbuffer *h); +DUK_LOCAL_DECL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr); +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_LOCAL_DECL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj); +#endif +#endif +#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH) +DUK_LOCAL_DECL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h); +#endif +DUK_LOCAL_DECL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth); + +/* + * Helper tables + */ + +#if defined(DUK_USE_JSON_QUOTESTRING_FASTPATH) +DUK_LOCAL const duk_uint8_t duk__json_quotestr_lookup[256] = { + /* 0x00 ... 0x7f: as is + * 0x80: escape generically + * 0x81: slow path + * 0xa0 ... 0xff: backslash + one char + */ + + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xe2, 0xf4, 0xee, 0x80, 0xe6, 0xf2, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x20, 0x21, 0xa2, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0xdc, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81 +}; +#else /* DUK_USE_JSON_QUOTESTRING_FASTPATH */ +DUK_LOCAL const duk_uint8_t duk__json_quotestr_esc[14] = { + DUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL, + DUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL, + DUK_ASC_LC_B, DUK_ASC_LC_T, DUK_ASC_LC_N, DUK_ASC_NUL, + DUK_ASC_LC_F, DUK_ASC_LC_R +}; +#endif /* DUK_USE_JSON_QUOTESTRING_FASTPATH */ + +#if defined(DUK_USE_JSON_DECSTRING_FASTPATH) +DUK_LOCAL const duk_uint8_t duk__json_decstr_lookup[256] = { + /* 0x00: slow path + * other: as is + */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x21, 0x00, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x00, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; +#endif /* DUK_USE_JSON_DECSTRING_FASTPATH */ + +#if defined(DUK_USE_JSON_EATWHITE_FASTPATH) +DUK_LOCAL const duk_uint8_t duk__json_eatwhite_lookup[256] = { + /* 0x00: finish (non-white) + * 0x01: continue + */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +#endif /* DUK_USE_JSON_EATWHITE_FASTPATH */ + +#if defined(DUK_USE_JSON_DECNUMBER_FASTPATH) +DUK_LOCAL const duk_uint8_t duk__json_decnumber_lookup[256] = { + /* 0x00: finish (not part of number) + * 0x01: continue + */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +#endif /* DUK_USE_JSON_DECNUMBER_FASTPATH */ + +/* + * Parsing implementation. + * + * JSON lexer is now separate from duk_lexer.c because there are numerous + * small differences making it difficult to share the lexer. + * + * The parser here works with raw bytes directly; this works because all + * JSON delimiters are ASCII characters. Invalid xUTF-8 encoded values + * inside strings will be passed on without normalization; this is not a + * compliance concern because compliant inputs will always be valid + * CESU-8 encodings. + */ + +DUK_LOCAL void duk__dec_syntax_error(duk_json_dec_ctx *js_ctx) { + /* Shared handler to minimize parser size. Cause will be + * hidden, unfortunately, but we'll have an offset which + * is often quite enough. + */ + DUK_ERROR_FMT1(js_ctx->thr, DUK_ERR_SYNTAX_ERROR, DUK_STR_FMT_INVALID_JSON, + (long) (js_ctx->p - js_ctx->p_start)); + DUK_WO_NORETURN(return;); +} + +DUK_LOCAL void duk__dec_eat_white(duk_json_dec_ctx *js_ctx) { + const duk_uint8_t *p; + duk_uint8_t t; + + p = js_ctx->p; + for (;;) { + DUK_ASSERT(p <= js_ctx->p_end); + t = *p; + +#if defined(DUK_USE_JSON_EATWHITE_FASTPATH) + /* This fast path is pretty marginal in practice. + * XXX: candidate for removal. + */ + DUK_ASSERT(duk__json_eatwhite_lookup[0x00] == 0x00); /* end-of-input breaks */ + if (duk__json_eatwhite_lookup[t] == 0) { + break; + } +#else /* DUK_USE_JSON_EATWHITE_FASTPATH */ + if (!(t == 0x20 || t == 0x0a || t == 0x0d || t == 0x09)) { + /* NUL also comes here. Comparison order matters, 0x20 + * is most common whitespace. + */ + break; + } +#endif /* DUK_USE_JSON_EATWHITE_FASTPATH */ + p++; + } + js_ctx->p = p; +} + +#if defined(DUK_USE_JX) +DUK_LOCAL duk_uint8_t duk__dec_peek(duk_json_dec_ctx *js_ctx) { + DUK_ASSERT(js_ctx->p <= js_ctx->p_end); + return *js_ctx->p; +} +#endif + +DUK_LOCAL duk_uint8_t duk__dec_get(duk_json_dec_ctx *js_ctx) { + DUK_ASSERT(js_ctx->p <= js_ctx->p_end); + return *js_ctx->p++; +} + +DUK_LOCAL duk_uint8_t duk__dec_get_nonwhite(duk_json_dec_ctx *js_ctx) { + duk__dec_eat_white(js_ctx); + return duk__dec_get(js_ctx); +} + +/* For JX, expressing the whole unsigned 32-bit range matters. */ +DUK_LOCAL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n) { + duk_small_uint_t i; + duk_uint_fast32_t res = 0; + duk_uint8_t x; + duk_small_int_t t; + + for (i = 0; i < n; i++) { + /* XXX: share helper from lexer; duk_lexer.c / hexval(). */ + + x = duk__dec_get(js_ctx); + DUK_DDD(DUK_DDDPRINT("decode_hex_escape: i=%ld, n=%ld, res=%ld, x=%ld", + (long) i, (long) n, (long) res, (long) x)); + + /* x == 0x00 (EOF) causes syntax_error */ + DUK_ASSERT(duk_hex_dectab[0] == -1); + t = duk_hex_dectab[x & 0xff]; + if (DUK_LIKELY(t >= 0)) { + res = (res * 16) + (duk_uint_fast32_t) t; + } else { + /* catches EOF and invalid digits */ + goto syntax_error; + } + } + + DUK_DDD(DUK_DDDPRINT("final hex decoded value: %ld", (long) res)); + return res; + + syntax_error: + duk__dec_syntax_error(js_ctx); + DUK_UNREACHABLE(); + return 0; +} + +DUK_LOCAL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx) { + duk_hstring *h; + const duk_uint8_t *p; + duk_uint8_t x, y; + + /* First character has already been eaten and checked by the caller. + * We can scan until a NUL in stridx string because no built-in strings + * have internal NULs. + */ + + DUK_ASSERT_STRIDX_VALID(stridx); + h = DUK_HTHREAD_GET_STRING(js_ctx->thr, stridx); + DUK_ASSERT(h != NULL); + + p = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h) + 1; + DUK_ASSERT(*(js_ctx->p - 1) == *(p - 1)); /* first character has been matched */ + + for (;;) { + x = *p; + if (x == 0) { + break; + } + y = duk__dec_get(js_ctx); + if (x != y) { + /* Catches EOF of JSON input. */ + goto syntax_error; + } + p++; + } + + return; + + syntax_error: + duk__dec_syntax_error(js_ctx); + DUK_UNREACHABLE(); +} + +DUK_LOCAL duk_small_int_t duk__dec_string_escape(duk_json_dec_ctx *js_ctx, duk_uint8_t **ext_p) { + duk_uint_fast32_t cp; + + /* EOF (-1) will be cast to an unsigned value first + * and then re-cast for the switch. In any case, it + * will match the default case (syntax error). + */ + cp = (duk_uint_fast32_t) duk__dec_get(js_ctx); + switch (cp) { + case DUK_ASC_BACKSLASH: break; + case DUK_ASC_DOUBLEQUOTE: break; + case DUK_ASC_SLASH: break; + case DUK_ASC_LC_T: cp = 0x09; break; + case DUK_ASC_LC_N: cp = 0x0a; break; + case DUK_ASC_LC_R: cp = 0x0d; break; + case DUK_ASC_LC_F: cp = 0x0c; break; + case DUK_ASC_LC_B: cp = 0x08; break; + case DUK_ASC_LC_U: { + cp = duk__dec_decode_hex_escape(js_ctx, 4); + break; + } +#if defined(DUK_USE_JX) + case DUK_ASC_UC_U: { + if (js_ctx->flag_ext_custom) { + cp = duk__dec_decode_hex_escape(js_ctx, 8); + } else { + return 1; /* syntax error */ + } + break; + } + case DUK_ASC_LC_X: { + if (js_ctx->flag_ext_custom) { + cp = duk__dec_decode_hex_escape(js_ctx, 2); + } else { + return 1; /* syntax error */ + } + break; + } +#endif /* DUK_USE_JX */ + default: + /* catches EOF (0x00) */ + return 1; /* syntax error */ + } + + DUK_RAW_WRITEINC_XUTF8(*ext_p, cp); + + return 0; +} + +DUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) { + duk_hthread *thr = js_ctx->thr; + duk_bufwriter_ctx bw_alloc; + duk_bufwriter_ctx *bw; + duk_uint8_t *q; + + /* '"' was eaten by caller */ + + /* Note that we currently parse -bytes-, not codepoints. + * All non-ASCII extended UTF-8 will encode to bytes >= 0x80, + * so they'll simply pass through (valid UTF-8 or not). + */ + + bw = &bw_alloc; + DUK_BW_INIT_PUSHBUF(js_ctx->thr, bw, DUK__JSON_DECSTR_BUFSIZE); + q = DUK_BW_GET_PTR(js_ctx->thr, bw); + +#if defined(DUK_USE_JSON_DECSTRING_FASTPATH) + for (;;) { + duk_small_uint_t safe; + duk_uint8_t b, x; + const duk_uint8_t *p; + + /* Select a safe loop count where no output checks are + * needed assuming we won't encounter escapes. Input + * bound checks are not necessary as a NUL (guaranteed) + * will cause a SyntaxError before we read out of bounds. + */ + + safe = DUK__JSON_DECSTR_CHUNKSIZE; + + /* Ensure space for 1:1 output plus one escape. */ + q = DUK_BW_ENSURE_RAW(js_ctx->thr, bw, safe + DUK_UNICODE_MAX_XUTF8_LENGTH, q); + + p = js_ctx->p; /* temp copy, write back for next loop */ + for (;;) { + if (safe == 0) { + js_ctx->p = p; + break; + } + safe--; + + /* End of input (NUL) goes through slow path and causes SyntaxError. */ + DUK_ASSERT(duk__json_decstr_lookup[0] == 0x00); + + b = *p++; + x = (duk_small_int_t) duk__json_decstr_lookup[b]; + if (DUK_LIKELY(x != 0)) { + /* Fast path, decode as is. */ + *q++ = b; + } else if (b == DUK_ASC_DOUBLEQUOTE) { + js_ctx->p = p; + goto found_quote; + } else if (b == DUK_ASC_BACKSLASH) { + /* We've ensured space for one escaped input; then + * bail out and recheck (this makes escape handling + * quite slow but it's uncommon). + */ + js_ctx->p = p; + if (duk__dec_string_escape(js_ctx, &q) != 0) { + goto syntax_error; + } + break; + } else { + js_ctx->p = p; + goto syntax_error; + } + } + } + found_quote: +#else /* DUK_USE_JSON_DECSTRING_FASTPATH */ + for (;;) { + duk_uint8_t x; + + q = DUK_BW_ENSURE_RAW(js_ctx->thr, bw, DUK_UNICODE_MAX_XUTF8_LENGTH, q); + + x = duk__dec_get(js_ctx); + + if (x == DUK_ASC_DOUBLEQUOTE) { + break; + } else if (x == DUK_ASC_BACKSLASH) { + if (duk__dec_string_escape(js_ctx, &q) != 0) { + goto syntax_error; + } + } else if (x < 0x20) { + /* catches EOF (NUL) */ + goto syntax_error; + } else { + *q++ = (duk_uint8_t) x; + } + } +#endif /* DUK_USE_JSON_DECSTRING_FASTPATH */ + + DUK_BW_SETPTR_AND_COMPACT(js_ctx->thr, bw, q); + (void) duk_buffer_to_string(thr, -1); /* Safe if input string is safe. */ + + /* [ ... str ] */ + + return; + + syntax_error: + duk__dec_syntax_error(js_ctx); + DUK_UNREACHABLE(); +} + +#if defined(DUK_USE_JX) +/* Decode a plain string consisting entirely of identifier characters. + * Used to parse plain keys (e.g. "foo: 123"). + */ +DUK_LOCAL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx) { + duk_hthread *thr = js_ctx->thr; + const duk_uint8_t *p; + duk_small_int_t x; + + /* Caller has already eaten the first char so backtrack one byte. */ + + js_ctx->p--; /* safe */ + p = js_ctx->p; + + /* Here again we parse bytes, and non-ASCII UTF-8 will cause end of + * parsing (which is correct except if there are non-shortest encodings). + * There is also no need to check explicitly for end of input buffer as + * the input is NUL padded and NUL will exit the parsing loop. + * + * Because no unescaping takes place, we can just scan to the end of the + * plain string and intern from the input buffer. + */ + + for (;;) { + x = *p; + + /* There is no need to check the first character specially here + * (i.e. reject digits): the caller only accepts valid initial + * characters and won't call us if the first character is a digit. + * This also ensures that the plain string won't be empty. + */ + + if (!duk_unicode_is_identifier_part((duk_codepoint_t) x)) { + break; + } + p++; + } + + duk_push_lstring(thr, (const char *) js_ctx->p, (duk_size_t) (p - js_ctx->p)); + js_ctx->p = p; + + /* [ ... str ] */ +} +#endif /* DUK_USE_JX */ + +#if defined(DUK_USE_JX) +DUK_LOCAL void duk__dec_pointer(duk_json_dec_ctx *js_ctx) { + duk_hthread *thr = js_ctx->thr; + const duk_uint8_t *p; + duk_small_int_t x; + void *voidptr; + + /* Caller has already eaten the first character ('(') which we don't need. */ + + p = js_ctx->p; + + for (;;) { + x = *p; + + /* Assume that the native representation never contains a closing + * parenthesis. + */ + + if (x == DUK_ASC_RPAREN) { + break; + } else if (x <= 0) { + /* NUL term or -1 (EOF), NUL check would suffice */ + goto syntax_error; + } + p++; + } + + /* There is no need to NUL delimit the sscanf() call: trailing garbage is + * ignored and there is always a NUL terminator which will force an error + * if no error is encountered before it. It's possible that the scan + * would scan further than between [js_ctx->p,p[ though and we'd advance + * by less than the scanned value. + * + * Because pointers are platform specific, a failure to scan a pointer + * results in a null pointer which is a better placeholder than a missing + * value or an error. + */ + + voidptr = NULL; + (void) DUK_SSCANF((const char *) js_ctx->p, DUK_STR_FMT_PTR, &voidptr); + duk_push_pointer(thr, voidptr); + js_ctx->p = p + 1; /* skip ')' */ + + /* [ ... ptr ] */ + + return; + + syntax_error: + duk__dec_syntax_error(js_ctx); + DUK_UNREACHABLE(); +} +#endif /* DUK_USE_JX */ + +#if defined(DUK_USE_JX) +DUK_LOCAL void duk__dec_buffer(duk_json_dec_ctx *js_ctx) { + duk_hthread *thr = js_ctx->thr; + const duk_uint8_t *p; + duk_uint8_t *buf; + duk_size_t src_len; + duk_small_int_t x; + + /* Caller has already eaten the first character ('|') which we don't need. */ + + p = js_ctx->p; + + /* XXX: Would be nice to share the fast path loop from duk_hex_decode() + * and avoid creating a temporary buffer. However, there are some + * differences which prevent trivial sharing: + * + * - Pipe char detection + * - EOF detection + * - Unknown length of input and output + * + * The best approach here would be a bufwriter and a reasonaly sized + * safe inner loop (e.g. 64 output bytes at a time). + */ + + for (;;) { + x = *p; + + /* This loop intentionally does not ensure characters are valid + * ([0-9a-fA-F]) because the hex decode call below will do that. + */ + if (x == DUK_ASC_PIPE) { + break; + } else if (x <= 0) { + /* NUL term or -1 (EOF), NUL check would suffice */ + goto syntax_error; + } + p++; + } + + /* XXX: this is not very nice; unnecessary copy is made. */ + src_len = (duk_size_t) (p - js_ctx->p); + buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, src_len); + DUK_ASSERT(buf != NULL); + duk_memcpy((void *) buf, (const void *) js_ctx->p, src_len); + duk_hex_decode(thr, -1); + + js_ctx->p = p + 1; /* skip '|' */ + + /* [ ... buf ] */ + + return; + + syntax_error: + duk__dec_syntax_error(js_ctx); + DUK_UNREACHABLE(); +} +#endif /* DUK_USE_JX */ + +/* Parse a number, other than NaN or +/- Infinity */ +DUK_LOCAL void duk__dec_number(duk_json_dec_ctx *js_ctx) { + duk_hthread *thr = js_ctx->thr; + const duk_uint8_t *p_start; + const duk_uint8_t *p; + duk_uint8_t x; + duk_small_uint_t s2n_flags; + + DUK_DDD(DUK_DDDPRINT("parse_number")); + + p_start = js_ctx->p; + + /* First pass parse is very lenient (e.g. allows '1.2.3') and extracts a + * string for strict number parsing. + */ + + p = js_ctx->p; + for (;;) { + x = *p; + + DUK_DDD(DUK_DDDPRINT("parse_number: p_start=%p, p=%p, p_end=%p, x=%ld", + (const void *) p_start, (const void *) p, + (const void *) js_ctx->p_end, (long) x)); + +#if defined(DUK_USE_JSON_DECNUMBER_FASTPATH) + /* This fast path is pretty marginal in practice. + * XXX: candidate for removal. + */ + DUK_ASSERT(duk__json_decnumber_lookup[0x00] == 0x00); /* end-of-input breaks */ + if (duk__json_decnumber_lookup[x] == 0) { + break; + } +#else /* DUK_USE_JSON_DECNUMBER_FASTPATH */ + if (!((x >= DUK_ASC_0 && x <= DUK_ASC_9) || + (x == DUK_ASC_PERIOD || x == DUK_ASC_LC_E || + x == DUK_ASC_UC_E || x == DUK_ASC_MINUS || x == DUK_ASC_PLUS))) { + /* Plus sign must be accepted for positive exponents + * (e.g. '1.5e+2'). This clause catches NULs. + */ + break; + } +#endif /* DUK_USE_JSON_DECNUMBER_FASTPATH */ + p++; /* safe, because matched (NUL causes a break) */ + } + js_ctx->p = p; + + DUK_ASSERT(js_ctx->p > p_start); + duk_push_lstring(thr, (const char *) p_start, (duk_size_t) (p - p_start)); + + s2n_flags = DUK_S2N_FLAG_ALLOW_EXP | + DUK_S2N_FLAG_ALLOW_MINUS | /* but don't allow leading plus */ + DUK_S2N_FLAG_ALLOW_FRAC; + + DUK_DDD(DUK_DDDPRINT("parse_number: string before parsing: %!T", + (duk_tval *) duk_get_tval(thr, -1))); + duk_numconv_parse(thr, 10 /*radix*/, s2n_flags); + if (duk_is_nan(thr, -1)) { + duk__dec_syntax_error(js_ctx); + } + DUK_ASSERT(duk_is_number(thr, -1)); + DUK_DDD(DUK_DDDPRINT("parse_number: final number: %!T", + (duk_tval *) duk_get_tval(thr, -1))); + + /* [ ... num ] */ +} + +DUK_LOCAL void duk__dec_objarr_entry(duk_json_dec_ctx *js_ctx) { + duk_hthread *thr = js_ctx->thr; + duk_require_stack(thr, DUK_JSON_DEC_REQSTACK); + + /* c recursion check */ + + DUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0); /* unsigned */ + DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit); + if (js_ctx->recursion_depth >= js_ctx->recursion_limit) { + DUK_ERROR_RANGE(thr, DUK_STR_JSONDEC_RECLIMIT); + DUK_WO_NORETURN(return;); + } + js_ctx->recursion_depth++; +} + +DUK_LOCAL void duk__dec_objarr_exit(duk_json_dec_ctx *js_ctx) { + /* c recursion check */ + + DUK_ASSERT(js_ctx->recursion_depth > 0); + DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit); + js_ctx->recursion_depth--; +} + +DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) { + duk_hthread *thr = js_ctx->thr; + duk_int_t key_count; /* XXX: a "first" flag would suffice */ + duk_uint8_t x; + + DUK_DDD(DUK_DDDPRINT("parse_object")); + + duk__dec_objarr_entry(js_ctx); + + duk_push_object(thr); + + /* Initial '{' has been checked and eaten by caller. */ + + key_count = 0; + for (;;) { + x = duk__dec_get_nonwhite(js_ctx); + + DUK_DDD(DUK_DDDPRINT("parse_object: obj=%!T, x=%ld, key_count=%ld", + (duk_tval *) duk_get_tval(thr, -1), + (long) x, (long) key_count)); + + /* handle comma and closing brace */ + + if (x == DUK_ASC_COMMA && key_count > 0) { + /* accept comma, expect new value */ + x = duk__dec_get_nonwhite(js_ctx); + } else if (x == DUK_ASC_RCURLY) { + /* eat closing brace */ + break; + } else if (key_count == 0) { + /* accept anything, expect first value (EOF will be + * caught by key parsing below. + */ + ; + } else { + /* catches EOF (NUL) and initial comma */ + goto syntax_error; + } + + /* parse key and value */ + + if (x == DUK_ASC_DOUBLEQUOTE) { + duk__dec_string(js_ctx); +#if defined(DUK_USE_JX) + } else if (js_ctx->flag_ext_custom && + duk_unicode_is_identifier_start((duk_codepoint_t) x)) { + duk__dec_plain_string(js_ctx); +#endif + } else { + goto syntax_error; + } + + /* [ ... obj key ] */ + + x = duk__dec_get_nonwhite(js_ctx); + if (x != DUK_ASC_COLON) { + goto syntax_error; + } + + duk__dec_value(js_ctx); + + /* [ ... obj key val ] */ + + duk_xdef_prop_wec(thr, -3); + + /* [ ... obj ] */ + + key_count++; + } + + /* [ ... obj ] */ + + DUK_DDD(DUK_DDDPRINT("parse_object: final object is %!T", + (duk_tval *) duk_get_tval(thr, -1))); + + duk__dec_objarr_exit(js_ctx); + return; + + syntax_error: + duk__dec_syntax_error(js_ctx); + DUK_UNREACHABLE(); +} + +DUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) { + duk_hthread *thr = js_ctx->thr; + duk_uarridx_t arr_idx; + duk_uint8_t x; + + DUK_DDD(DUK_DDDPRINT("parse_array")); + + duk__dec_objarr_entry(js_ctx); + + duk_push_array(thr); + + /* Initial '[' has been checked and eaten by caller. */ + + arr_idx = 0; + for (;;) { + x = duk__dec_get_nonwhite(js_ctx); + + DUK_DDD(DUK_DDDPRINT("parse_array: arr=%!T, x=%ld, arr_idx=%ld", + (duk_tval *) duk_get_tval(thr, -1), + (long) x, (long) arr_idx)); + + /* handle comma and closing bracket */ + + if ((x == DUK_ASC_COMMA) && (arr_idx != 0)) { + /* accept comma, expect new value */ + ; + } else if (x == DUK_ASC_RBRACKET) { + /* eat closing bracket */ + break; + } else if (arr_idx == 0) { + /* accept anything, expect first value (EOF will be + * caught by duk__dec_value() below. + */ + js_ctx->p--; /* backtrack (safe) */ + } else { + /* catches EOF (NUL) and initial comma */ + goto syntax_error; + } + + /* parse value */ + + duk__dec_value(js_ctx); + + /* [ ... arr val ] */ + + duk_xdef_prop_index_wec(thr, -2, arr_idx); + arr_idx++; + } + + /* Must set 'length' explicitly when using duk_xdef_prop_xxx() to + * set the values. + */ + + duk_set_length(thr, -1, arr_idx); + + /* [ ... arr ] */ + + DUK_DDD(DUK_DDDPRINT("parse_array: final array is %!T", + (duk_tval *) duk_get_tval(thr, -1))); + + duk__dec_objarr_exit(js_ctx); + return; + + syntax_error: + duk__dec_syntax_error(js_ctx); + DUK_UNREACHABLE(); +} + +DUK_LOCAL void duk__dec_value(duk_json_dec_ctx *js_ctx) { + duk_hthread *thr = js_ctx->thr; + duk_uint8_t x; + + x = duk__dec_get_nonwhite(js_ctx); + + DUK_DDD(DUK_DDDPRINT("parse_value: initial x=%ld", (long) x)); + + /* Note: duk__dec_req_stridx() backtracks one char */ + + if (x == DUK_ASC_DOUBLEQUOTE) { + duk__dec_string(js_ctx); + } else if ((x >= DUK_ASC_0 && x <= DUK_ASC_9) || (x == DUK_ASC_MINUS)) { +#if defined(DUK_USE_JX) + if (js_ctx->flag_ext_custom && x == DUK_ASC_MINUS && duk__dec_peek(js_ctx) == DUK_ASC_UC_I) { + duk__dec_req_stridx(js_ctx, DUK_STRIDX_MINUS_INFINITY); /* "-Infinity", '-' has been eaten */ + duk_push_number(thr, -DUK_DOUBLE_INFINITY); + } else { +#else + { /* unconditional block */ +#endif + /* We already ate 'x', so backup one byte. */ + js_ctx->p--; /* safe */ + duk__dec_number(js_ctx); + } + } else if (x == DUK_ASC_LC_T) { + duk__dec_req_stridx(js_ctx, DUK_STRIDX_TRUE); + duk_push_true(thr); + } else if (x == DUK_ASC_LC_F) { + duk__dec_req_stridx(js_ctx, DUK_STRIDX_FALSE); + duk_push_false(thr); + } else if (x == DUK_ASC_LC_N) { + duk__dec_req_stridx(js_ctx, DUK_STRIDX_LC_NULL); + duk_push_null(thr); +#if defined(DUK_USE_JX) + } else if (js_ctx->flag_ext_custom && x == DUK_ASC_LC_U) { + duk__dec_req_stridx(js_ctx, DUK_STRIDX_LC_UNDEFINED); + duk_push_undefined(thr); + } else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_N) { + duk__dec_req_stridx(js_ctx, DUK_STRIDX_NAN); + duk_push_nan(thr); + } else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_I) { + duk__dec_req_stridx(js_ctx, DUK_STRIDX_INFINITY); + duk_push_number(thr, DUK_DOUBLE_INFINITY); + } else if (js_ctx->flag_ext_custom && x == DUK_ASC_LPAREN) { + duk__dec_pointer(js_ctx); + } else if (js_ctx->flag_ext_custom && x == DUK_ASC_PIPE) { + duk__dec_buffer(js_ctx); +#endif + } else if (x == DUK_ASC_LCURLY) { + duk__dec_object(js_ctx); + } else if (x == DUK_ASC_LBRACKET) { + duk__dec_array(js_ctx); + } else { + /* catches EOF (NUL) */ + goto syntax_error; + } + + duk__dec_eat_white(js_ctx); + + /* [ ... val ] */ + return; + + syntax_error: + duk__dec_syntax_error(js_ctx); + DUK_UNREACHABLE(); +} + +/* Recursive value reviver, implements the Walk() algorithm. No C recursion + * check is done here because the initial parsing step will already ensure + * there is a reasonable limit on C recursion depth and hence object depth. + */ +DUK_LOCAL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx) { + duk_hthread *thr = js_ctx->thr; + duk_hobject *h; + duk_uarridx_t i, arr_len; + + DUK_DDD(DUK_DDDPRINT("walk: top=%ld, holder=%!T, name=%!T", + (long) duk_get_top(thr), + (duk_tval *) duk_get_tval(thr, -2), + (duk_tval *) duk_get_tval(thr, -1))); + + duk_dup_top(thr); + duk_get_prop(thr, -3); /* -> [ ... holder name val ] */ + + h = duk_get_hobject(thr, -1); + if (h != NULL) { + if (duk_js_isarray_hobject(h)) { + arr_len = (duk_uarridx_t) duk_get_length(thr, -1); + for (i = 0; i < arr_len; i++) { + /* [ ... holder name val ] */ + + DUK_DDD(DUK_DDDPRINT("walk: array, top=%ld, i=%ld, arr_len=%ld, holder=%!T, name=%!T, val=%!T", + (long) duk_get_top(thr), (long) i, (long) arr_len, + (duk_tval *) duk_get_tval(thr, -3), (duk_tval *) duk_get_tval(thr, -2), + (duk_tval *) duk_get_tval(thr, -1))); + + duk_dup_top(thr); + (void) duk_push_uint_to_hstring(thr, (duk_uint_t) i); /* -> [ ... holder name val val ToString(i) ] */ + duk__dec_reviver_walk(js_ctx); /* -> [ ... holder name val new_elem ] */ + + if (duk_is_undefined(thr, -1)) { + duk_pop(thr); + duk_del_prop_index(thr, -1, i); + } else { + /* XXX: duk_xdef_prop_index_wec() would be more appropriate + * here but it currently makes some assumptions that might + * not hold (e.g. that previous property is not an accessor). + */ + duk_put_prop_index(thr, -2, i); + } + } + } else { + /* [ ... holder name val ] */ + duk_enum(thr, -1, DUK_ENUM_OWN_PROPERTIES_ONLY /*flags*/); + while (duk_next(thr, -1 /*enum_index*/, 0 /*get_value*/)) { + DUK_DDD(DUK_DDDPRINT("walk: object, top=%ld, holder=%!T, name=%!T, val=%!T, enum=%!iT, obj_key=%!T", + (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, -5), + (duk_tval *) duk_get_tval(thr, -4), (duk_tval *) duk_get_tval(thr, -3), + (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1))); + + /* [ ... holder name val enum obj_key ] */ + duk_dup_m3(thr); + duk_dup_m2(thr); + + /* [ ... holder name val enum obj_key val obj_key ] */ + duk__dec_reviver_walk(js_ctx); + + /* [ ... holder name val enum obj_key new_elem ] */ + if (duk_is_undefined(thr, -1)) { + duk_pop(thr); + duk_del_prop(thr, -3); + } else { + /* XXX: duk_xdef_prop_index_wec() would be more appropriate + * here but it currently makes some assumptions that might + * not hold (e.g. that previous property is not an accessor). + * + * Using duk_put_prop() works incorrectly with '__proto__' + * if the own property with that name has been deleted. This + * does not happen normally, but a clever reviver can trigger + * that, see complex reviver case in: test-bug-json-parse-__proto__.js. + */ + duk_put_prop(thr, -4); + } + } + duk_pop(thr); /* pop enum */ + } + } + + /* [ ... holder name val ] */ + + duk_dup(thr, js_ctx->idx_reviver); + duk_insert(thr, -4); /* -> [ ... reviver holder name val ] */ + duk_call_method(thr, 2); /* -> [ ... res ] */ + + DUK_DDD(DUK_DDDPRINT("walk: top=%ld, result=%!T", + (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, -1))); +} + +/* + * Stringify implementation. + */ + +#define DUK__EMIT_1(js_ctx,ch) duk__emit_1((js_ctx), (duk_uint_fast8_t) (ch)) +#define DUK__EMIT_2(js_ctx,ch1,ch2) duk__emit_2((js_ctx), (duk_uint_fast8_t) (ch1), (duk_uint_fast8_t) (ch2)) +#define DUK__EMIT_HSTR(js_ctx,h) duk__emit_hstring((js_ctx), (h)) +#if defined(DUK_USE_FASTINT) || defined(DUK_USE_JX) || defined(DUK_USE_JC) +#define DUK__EMIT_CSTR(js_ctx,p) duk__emit_cstring((js_ctx), (p)) +#endif +#define DUK__EMIT_STRIDX(js_ctx,i) duk__emit_stridx((js_ctx), (i)) +#define DUK__UNEMIT_1(js_ctx) duk__unemit_1((js_ctx)) + +DUK_LOCAL void duk__emit_1(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch) { + DUK_BW_WRITE_ENSURE_U8(js_ctx->thr, &js_ctx->bw, ch); +} + +DUK_LOCAL void duk__emit_2(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch1, duk_uint_fast8_t ch2) { + DUK_BW_WRITE_ENSURE_U8_2(js_ctx->thr, &js_ctx->bw, ch1, ch2); +} + +DUK_LOCAL void duk__emit_hstring(duk_json_enc_ctx *js_ctx, duk_hstring *h) { + DUK_BW_WRITE_ENSURE_HSTRING(js_ctx->thr, &js_ctx->bw, h); +} + +#if defined(DUK_USE_FASTINT) || defined(DUK_USE_JX) || defined(DUK_USE_JC) +DUK_LOCAL void duk__emit_cstring(duk_json_enc_ctx *js_ctx, const char *str) { + DUK_BW_WRITE_ENSURE_CSTRING(js_ctx->thr, &js_ctx->bw, str); +} +#endif + +DUK_LOCAL void duk__emit_stridx(duk_json_enc_ctx *js_ctx, duk_small_uint_t stridx) { + duk_hstring *h; + + DUK_ASSERT_STRIDX_VALID(stridx); + h = DUK_HTHREAD_GET_STRING(js_ctx->thr, stridx); + DUK_ASSERT(h != NULL); + + DUK_BW_WRITE_ENSURE_HSTRING(js_ctx->thr, &js_ctx->bw, h); +} + +DUK_LOCAL void duk__unemit_1(duk_json_enc_ctx *js_ctx) { + DUK_ASSERT(DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw) >= 1); + DUK_BW_ADD_PTR(js_ctx->thr, &js_ctx->bw, -1); +} + +#define DUK__MKESC(nybbles,esc1,esc2) \ + (((duk_uint_fast32_t) (nybbles)) << 16) | \ + (((duk_uint_fast32_t) (esc1)) << 8) | \ + ((duk_uint_fast32_t) (esc2)) + +DUK_LOCAL duk_uint8_t *duk__emit_esc_auto_fast(duk_json_enc_ctx *js_ctx, duk_uint_fast32_t cp, duk_uint8_t *q) { + duk_uint_fast32_t tmp; + duk_small_uint_t dig; + + DUK_UNREF(js_ctx); + + /* Caller ensures space for at least DUK__JSON_MAX_ESC_LEN. */ + + /* Select appropriate escape format automatically, and set 'tmp' to a + * value encoding both the escape format character and the nybble count: + * + * (nybble_count << 16) | (escape_char1) | (escape_char2) + */ + +#if defined(DUK_USE_JX) + if (DUK_LIKELY(cp < 0x100UL)) { + if (DUK_UNLIKELY(js_ctx->flag_ext_custom != 0U)) { + tmp = DUK__MKESC(2, DUK_ASC_BACKSLASH, DUK_ASC_LC_X); + } else { + tmp = DUK__MKESC(4, DUK_ASC_BACKSLASH, DUK_ASC_LC_U); + } + } else +#endif + if (DUK_LIKELY(cp < 0x10000UL)) { + tmp = DUK__MKESC(4, DUK_ASC_BACKSLASH, DUK_ASC_LC_U); + } else { +#if defined(DUK_USE_JX) + if (DUK_LIKELY(js_ctx->flag_ext_custom != 0U)) { + tmp = DUK__MKESC(8, DUK_ASC_BACKSLASH, DUK_ASC_UC_U); + } else +#endif + { + /* In compatible mode and standard JSON mode, output + * something useful for non-BMP characters. This won't + * roundtrip but will still be more or less readable and + * more useful than an error. + */ + tmp = DUK__MKESC(8, DUK_ASC_UC_U, DUK_ASC_PLUS); + } + } + + *q++ = (duk_uint8_t) ((tmp >> 8) & 0xff); + *q++ = (duk_uint8_t) (tmp & 0xff); + + tmp = tmp >> 16; + while (tmp > 0) { + tmp--; + dig = (duk_small_uint_t) ((cp >> (4 * tmp)) & 0x0f); + *q++ = duk_lc_digits[dig]; + } + + return q; +} + +DUK_LOCAL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k) { + const duk_int8_t *p, *p_start, *p_end; /* Note: intentionally signed. */ + duk_size_t k_len; + duk_codepoint_t cp; + + DUK_ASSERT(k != NULL); + + /* Accept ASCII strings which conform to identifier requirements + * as being emitted without key quotes. Since we only accept ASCII + * there's no need for actual decoding: 'p' is intentionally signed + * so that bytes >= 0x80 extend to negative values and are rejected + * as invalid identifier codepoints. + */ + + if (js_ctx->flag_avoid_key_quotes) { + k_len = DUK_HSTRING_GET_BYTELEN(k); + p_start = (const duk_int8_t *) DUK_HSTRING_GET_DATA(k); + p_end = p_start + k_len; + p = p_start; + + if (p == p_end) { + /* Zero length string is not accepted without quotes */ + goto quote_normally; + } + cp = (duk_codepoint_t) (*p++); + if (DUK_UNLIKELY(!duk_unicode_is_identifier_start(cp))) { + goto quote_normally; + } + while (p < p_end) { + cp = (duk_codepoint_t) (*p++); + if (DUK_UNLIKELY(!duk_unicode_is_identifier_part(cp))) { + goto quote_normally; + } + } + + /* This seems faster than emitting bytes one at a time and + * then potentially rewinding. + */ + DUK__EMIT_HSTR(js_ctx, k); + return; + } + + quote_normally: + duk__enc_quote_string(js_ctx, k); +} + +/* The Quote(value) operation: quote a string. + * + * Stack policy: [ ] -> [ ]. + */ + +DUK_LOCAL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str) { + duk_hthread *thr = js_ctx->thr; + const duk_uint8_t *p, *p_start, *p_end, *p_now, *p_tmp; + duk_uint8_t *q; + duk_ucodepoint_t cp; /* typed for duk_unicode_decode_xutf8() */ + + DUK_DDD(DUK_DDDPRINT("duk__enc_quote_string: h_str=%!O", (duk_heaphdr *) h_str)); + + DUK_ASSERT(h_str != NULL); + p_start = DUK_HSTRING_GET_DATA(h_str); + p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_str); + p = p_start; + + DUK__EMIT_1(js_ctx, DUK_ASC_DOUBLEQUOTE); + + /* Encode string in small chunks, estimating the maximum expansion so that + * there's no need to ensure space while processing the chunk. + */ + + while (p < p_end) { + duk_size_t left, now, space; + + left = (duk_size_t) (p_end - p); + now = (left > DUK__JSON_ENCSTR_CHUNKSIZE ? + DUK__JSON_ENCSTR_CHUNKSIZE : left); + + /* Maximum expansion per input byte is 6: + * - invalid UTF-8 byte causes "\uXXXX" to be emitted (6/1 = 6). + * - 2-byte UTF-8 encodes as "\uXXXX" (6/2 = 3). + * - 4-byte UTF-8 encodes as "\Uxxxxxxxx" (10/4 = 2.5). + */ + space = now * 6; + q = DUK_BW_ENSURE_GETPTR(thr, &js_ctx->bw, space); + + p_now = p + now; + + while (p < p_now) { +#if defined(DUK_USE_JSON_QUOTESTRING_FASTPATH) + duk_uint8_t b; + + b = duk__json_quotestr_lookup[*p++]; + if (DUK_LIKELY(b < 0x80)) { + /* Most input bytes go through here. */ + *q++ = b; + } else if (b >= 0xa0) { + *q++ = DUK_ASC_BACKSLASH; + *q++ = (duk_uint8_t) (b - 0x80); + } else if (b == 0x80) { + cp = (duk_ucodepoint_t) (*(p - 1)); + q = duk__emit_esc_auto_fast(js_ctx, cp, q); + } else if (b == 0x7f && js_ctx->flag_ascii_only) { + /* 0x7F is special */ + DUK_ASSERT(b == 0x81); + cp = (duk_ucodepoint_t) 0x7f; + q = duk__emit_esc_auto_fast(js_ctx, cp, q); + } else { + DUK_ASSERT(b == 0x81); + p--; + + /* slow path is shared */ +#else /* DUK_USE_JSON_QUOTESTRING_FASTPATH */ + cp = *p; + + if (DUK_LIKELY(cp <= 0x7f)) { + /* ascii fast path: avoid decoding utf-8 */ + p++; + if (cp == 0x22 || cp == 0x5c) { + /* double quote or backslash */ + *q++ = DUK_ASC_BACKSLASH; + *q++ = (duk_uint8_t) cp; + } else if (cp < 0x20) { + duk_uint_fast8_t esc_char; + + /* This approach is a bit shorter than a straight + * if-else-ladder and also a bit faster. + */ + if (cp < (sizeof(duk__json_quotestr_esc) / sizeof(duk_uint8_t)) && + (esc_char = duk__json_quotestr_esc[cp]) != 0) { + *q++ = DUK_ASC_BACKSLASH; + *q++ = (duk_uint8_t) esc_char; + } else { + q = duk__emit_esc_auto_fast(js_ctx, cp, q); + } + } else if (cp == 0x7f && js_ctx->flag_ascii_only) { + q = duk__emit_esc_auto_fast(js_ctx, cp, q); + } else { + /* any other printable -> as is */ + *q++ = (duk_uint8_t) cp; + } + } else { + /* slow path is shared */ +#endif /* DUK_USE_JSON_QUOTESTRING_FASTPATH */ + + /* slow path decode */ + + /* If XUTF-8 decoding fails, treat the offending byte as a codepoint directly + * and go forward one byte. This is of course very lossy, but allows some kind + * of output to be produced even for internal strings which don't conform to + * XUTF-8. All standard ECMAScript strings are always CESU-8, so this behavior + * does not violate the ECMAScript specification. The behavior is applied to + * all modes, including ECMAScript standard JSON. Because the current XUTF-8 + * decoding is not very strict, this behavior only really affects initial bytes + * and truncated codepoints. + * + * Another alternative would be to scan forwards to start of next codepoint + * (or end of input) and emit just one replacement codepoint. + */ + + p_tmp = p; + if (!duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp)) { + /* Decode failed. */ + cp = *p_tmp; + p = p_tmp + 1; + } + +#if defined(DUK_USE_NONSTD_JSON_ESC_U2028_U2029) + if (js_ctx->flag_ascii_only || cp == 0x2028 || cp == 0x2029) { +#else + if (js_ctx->flag_ascii_only) { +#endif + q = duk__emit_esc_auto_fast(js_ctx, cp, q); + } else { + /* as is */ + DUK_RAW_WRITEINC_XUTF8(q, cp); + } + } + } + + DUK_BW_SET_PTR(thr, &js_ctx->bw, q); + } + + DUK__EMIT_1(js_ctx, DUK_ASC_DOUBLEQUOTE); +} + +/* Encode a double (checked by caller) from stack top. Stack top may be + * replaced by serialized string but is not popped (caller does that). + */ +DUK_LOCAL void duk__enc_double(duk_json_enc_ctx *js_ctx) { + duk_hthread *thr; + duk_tval *tv; + duk_double_t d; + duk_small_int_t c; + duk_small_int_t s; + duk_small_uint_t stridx; + duk_small_uint_t n2s_flags; + duk_hstring *h_str; + + DUK_ASSERT(js_ctx != NULL); + thr = js_ctx->thr; + DUK_ASSERT(thr != NULL); + + /* Caller must ensure 'tv' is indeed a double and not a fastint! */ + tv = DUK_GET_TVAL_NEGIDX(thr, -1); + DUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv)); + d = DUK_TVAL_GET_DOUBLE(tv); + + c = (duk_small_int_t) DUK_FPCLASSIFY(d); + s = (duk_small_int_t) DUK_SIGNBIT(d); + DUK_UNREF(s); + + if (DUK_LIKELY(!(c == DUK_FP_INFINITE || c == DUK_FP_NAN))) { + DUK_ASSERT(DUK_ISFINITE(d)); + +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + /* Negative zero needs special handling in JX/JC because + * it would otherwise serialize to '0', not '-0'. + */ + if (DUK_UNLIKELY(c == DUK_FP_ZERO && s != 0 && + (js_ctx->flag_ext_custom_or_compatible))) { + duk_push_hstring_stridx(thr, DUK_STRIDX_MINUS_ZERO); /* '-0' */ + } else +#endif /* DUK_USE_JX || DUK_USE_JC */ + { + n2s_flags = 0; + /* [ ... number ] -> [ ... string ] */ + duk_numconv_stringify(thr, 10 /*radix*/, 0 /*digits*/, n2s_flags); + } + h_str = duk_known_hstring(thr, -1); + DUK__EMIT_HSTR(js_ctx, h_str); + return; + } + +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + if (!(js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM | + DUK_JSON_FLAG_EXT_COMPATIBLE))) { + stridx = DUK_STRIDX_LC_NULL; + } else if (c == DUK_FP_NAN) { + stridx = js_ctx->stridx_custom_nan; + } else if (s == 0) { + stridx = js_ctx->stridx_custom_posinf; + } else { + stridx = js_ctx->stridx_custom_neginf; + } +#else + stridx = DUK_STRIDX_LC_NULL; +#endif + DUK__EMIT_STRIDX(js_ctx, stridx); +} + +#if defined(DUK_USE_FASTINT) +/* Encode a fastint from duk_tval ptr, no value stack effects. */ +DUK_LOCAL void duk__enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv) { + duk_int64_t v; + + /* Fastint range is signed 48-bit so longest value is -2^47 = -140737488355328 + * (16 chars long), longest signed 64-bit value is -2^63 = -9223372036854775808 + * (20 chars long). Alloc space for 64-bit range to be safe. + */ + duk_uint8_t buf[20 + 1]; + + /* Caller must ensure 'tv' is indeed a fastint! */ + DUK_ASSERT(DUK_TVAL_IS_FASTINT(tv)); + v = DUK_TVAL_GET_FASTINT(tv); + + /* XXX: There are no format strings in duk_config.h yet, could add + * one for formatting duk_int64_t. For now, assumes "%lld" and that + * "long long" type exists. Could also rely on C99 directly but that + * won't work for older MSVC. + */ + DUK_SPRINTF((char *) buf, "%lld", (long long) v); + DUK__EMIT_CSTR(js_ctx, (const char *) buf); +} +#endif + +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) +#if defined(DUK_USE_HEX_FASTPATH) +DUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst) { + duk_uint8_t *q; + duk_uint16_t *q16; + duk_small_uint_t x; + duk_size_t i, len_safe; +#if !defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE) + duk_bool_t shift_dst; +#endif + + /* Unlike in duk_hex_encode() 'dst' is not necessarily aligned by 2. + * For platforms where unaligned accesses are not allowed, shift 'dst' + * ahead by 1 byte to get alignment and then duk_memmove() the result + * in place. The faster encoding loop makes up the difference. + * There's always space for one extra byte because a terminator always + * follows the hex data and that's been accounted for by the caller. + */ + +#if defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE) + q16 = (duk_uint16_t *) (void *) dst; +#else + shift_dst = (duk_bool_t) (((duk_size_t) dst) & 0x01U); + if (shift_dst) { + DUK_DD(DUK_DDPRINT("unaligned accesses not possible, dst not aligned -> step to dst + 1")); + q16 = (duk_uint16_t *) (void *) (dst + 1); + } else { + DUK_DD(DUK_DDPRINT("unaligned accesses not possible, dst is aligned")); + q16 = (duk_uint16_t *) (void *) dst; + } + DUK_ASSERT((((duk_size_t) q16) & 0x01U) == 0); +#endif + + len_safe = src_len & ~0x03U; + for (i = 0; i < len_safe; i += 4) { + q16[0] = duk_hex_enctab[src[i]]; + q16[1] = duk_hex_enctab[src[i + 1]]; + q16[2] = duk_hex_enctab[src[i + 2]]; + q16[3] = duk_hex_enctab[src[i + 3]]; + q16 += 4; + } + q = (duk_uint8_t *) q16; + +#if !defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE) + if (shift_dst) { + q--; + duk_memmove((void *) dst, (const void *) (dst + 1), 2 * len_safe); + DUK_ASSERT(dst + 2 * len_safe == q); + } +#endif + + for (; i < src_len; i++) { + x = src[i]; + *q++ = duk_lc_digits[x >> 4]; + *q++ = duk_lc_digits[x & 0x0f]; + } + + return q; +} +#else /* DUK_USE_HEX_FASTPATH */ +DUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst) { + const duk_uint8_t *p; + const duk_uint8_t *p_end; + duk_uint8_t *q; + duk_small_uint_t x; + + p = src; + p_end = src + src_len; + q = dst; + while (p != p_end) { + x = *p++; + *q++ = duk_lc_digits[x >> 4]; + *q++ = duk_lc_digits[x & 0x0f]; + } + + return q; +} +#endif /* DUK_USE_HEX_FASTPATH */ + +DUK_LOCAL void duk__enc_buffer_data(duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_data, duk_size_t buf_len) { + duk_hthread *thr; + duk_uint8_t *q; + duk_size_t space; + + thr = js_ctx->thr; + + DUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible); /* caller checks */ + DUK_ASSERT(js_ctx->flag_ext_custom_or_compatible); + + /* Buffer values are encoded in (lowercase) hex to make the + * binary data readable. Base64 or similar would be more + * compact but less readable, and the point of JX/JC + * variants is to be as useful to a programmer as possible. + */ + + /* The #if defined() clutter here needs to handle the three + * cases: (1) JX+JC, (2) JX only, (3) JC only. + */ + + /* Note: space must cater for both JX and JC. */ + space = 9 + buf_len * 2 + 2; + DUK_ASSERT(DUK_HBUFFER_MAX_BYTELEN <= 0x7ffffffeUL); + DUK_ASSERT((space - 2) / 2 >= buf_len); /* overflow not possible, buffer limits */ + q = DUK_BW_ENSURE_GETPTR(thr, &js_ctx->bw, space); + +#if defined(DUK_USE_JX) && defined(DUK_USE_JC) + if (js_ctx->flag_ext_custom) +#endif +#if defined(DUK_USE_JX) + { + *q++ = DUK_ASC_PIPE; + q = duk__enc_buffer_data_hex(buf_data, buf_len, q); + *q++ = DUK_ASC_PIPE; + + } +#endif +#if defined(DUK_USE_JX) && defined(DUK_USE_JC) + else +#endif +#if defined(DUK_USE_JC) + { + DUK_ASSERT(js_ctx->flag_ext_compatible); + duk_memcpy((void *) q, (const void *) "{\"_buf\":\"", 9); /* len: 9 */ + q += 9; + q = duk__enc_buffer_data_hex(buf_data, buf_len, q); + *q++ = DUK_ASC_DOUBLEQUOTE; + *q++ = DUK_ASC_RCURLY; + } +#endif + + DUK_BW_SET_PTR(thr, &js_ctx->bw, q); +} + +DUK_LOCAL void duk__enc_buffer_jx_jc(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) { + duk__enc_buffer_data(js_ctx, + (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(js_ctx->thr->heap, h), + (duk_size_t) DUK_HBUFFER_GET_SIZE(h)); +} +#endif /* DUK_USE_JX || DUK_USE_JC */ + +#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH) +DUK_LOCAL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) { + duk_size_t i, n; + const duk_uint8_t *buf; + duk_uint8_t *q; + + n = DUK_HBUFFER_GET_SIZE(h); + if (n == 0) { + DUK__EMIT_2(js_ctx, DUK_ASC_LCURLY, DUK_ASC_RCURLY); + return; + } + + DUK__EMIT_1(js_ctx, DUK_ASC_LCURLY); + + /* Maximum encoded length with 32-bit index: 1 + 10 + 2 + 3 + 1 + 1 = 18, + * with 64-bit index: 1 + 20 + 2 + 3 + 1 + 1 = 28. 32 has some slack. + * + * Note that because the output buffer is reallocated from time to time, + * side effects (such as finalizers) affecting the buffer 'h' must be + * disabled. This is the case in the JSON.stringify() fast path. + */ + + buf = (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(js_ctx->thr->heap, h); + if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { + for (i = 0; i < n; i++) { + duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth + 1); + q = DUK_BW_ENSURE_GETPTR(js_ctx->thr, &js_ctx->bw, 32); + q += DUK_SPRINTF((char *) q, "\"%lu\": %u,", (unsigned long) i, (unsigned int) buf[i]); + DUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, q); + } + } else { + q = DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw); + for (i = 0; i < n; i++) { + q = DUK_BW_ENSURE_RAW(js_ctx->thr, &js_ctx->bw, 32, q); + q += DUK_SPRINTF((char *) q, "\"%lu\":%u,", (unsigned long) i, (unsigned int) buf[i]); + } + DUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, q); + } + DUK__UNEMIT_1(js_ctx); /* eat trailing comma */ + + if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { + duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth); + } + DUK__EMIT_1(js_ctx, DUK_ASC_RCURLY); +} +#endif /* DUK_USE_JSON_STRINGIFY_FASTPATH */ + +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) +DUK_LOCAL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr) { + char buf[64]; /* XXX: how to figure correct size? */ + const char *fmt; + + DUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible); /* caller checks */ + DUK_ASSERT(js_ctx->flag_ext_custom_or_compatible); + + duk_memzero(buf, sizeof(buf)); + + /* The #if defined() clutter here needs to handle the three + * cases: (1) JX+JC, (2) JX only, (3) JC only. + */ +#if defined(DUK_USE_JX) && defined(DUK_USE_JC) + if (js_ctx->flag_ext_custom) +#endif +#if defined(DUK_USE_JX) + { + fmt = ptr ? "(%p)" : "(null)"; + } +#endif +#if defined(DUK_USE_JX) && defined(DUK_USE_JC) + else +#endif +#if defined(DUK_USE_JC) + { + DUK_ASSERT(js_ctx->flag_ext_compatible); + fmt = ptr ? "{\"_ptr\":\"%p\"}" : "{\"_ptr\":\"null\"}"; + } +#endif + + /* When ptr == NULL, the format argument is unused. */ + DUK_SNPRINTF(buf, sizeof(buf) - 1, fmt, ptr); /* must not truncate */ + DUK__EMIT_CSTR(js_ctx, buf); +} +#endif /* DUK_USE_JX || DUK_USE_JC */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) +DUK_LOCAL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj) { + DUK_HBUFOBJ_ASSERT_VALID(h_bufobj); + + if (h_bufobj->buf == NULL || !DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) { + DUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL); + } else { + /* Handle both full and partial slice (as long as covered). */ + duk__enc_buffer_data(js_ctx, + (duk_uint8_t *) DUK_HBUFOBJ_GET_SLICE_BASE(js_ctx->thr->heap, h_bufobj), + (duk_size_t) h_bufobj->length); + } +} +#endif /* DUK_USE_JX || DUK_USE_JC */ +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* Indent helper. Calling code relies on js_ctx->recursion_depth also being + * directly related to indent depth. + */ +#if defined(DUK_USE_PREFER_SIZE) +DUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) { + DUK_ASSERT(js_ctx->h_gap != NULL); + DUK_ASSERT(DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) > 0); /* caller guarantees */ + + DUK__EMIT_1(js_ctx, 0x0a); + while (depth-- > 0) { + DUK__EMIT_HSTR(js_ctx, js_ctx->h_gap); + } +} +#else /* DUK_USE_PREFER_SIZE */ +DUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) { + const duk_uint8_t *gap_data; + duk_size_t gap_len; + duk_size_t avail_bytes; /* bytes of indent available for copying */ + duk_size_t need_bytes; /* bytes of indent still needed */ + duk_uint8_t *p_start; + duk_uint8_t *p; + + DUK_ASSERT(js_ctx->h_gap != NULL); + DUK_ASSERT(DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) > 0); /* caller guarantees */ + + DUK__EMIT_1(js_ctx, 0x0a); + if (DUK_UNLIKELY(depth == 0)) { + return; + } + + /* To handle deeper indents efficiently, make use of copies we've + * already emitted. In effect we can emit a sequence of 1, 2, 4, + * 8, etc copies, and then finish the last run. Byte counters + * avoid multiply with gap_len on every loop. + */ + + gap_data = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(js_ctx->h_gap); + gap_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap); + DUK_ASSERT(gap_len > 0); + + need_bytes = gap_len * depth; + p = DUK_BW_ENSURE_GETPTR(js_ctx->thr, &js_ctx->bw, need_bytes); + p_start = p; + + duk_memcpy((void *) p, (const void *) gap_data, (size_t) gap_len); + p += gap_len; + avail_bytes = gap_len; + DUK_ASSERT(need_bytes >= gap_len); + need_bytes -= gap_len; + + while (need_bytes >= avail_bytes) { + duk_memcpy((void *) p, (const void *) p_start, (size_t) avail_bytes); + p += avail_bytes; + need_bytes -= avail_bytes; + avail_bytes <<= 1; + } + + DUK_ASSERT(need_bytes < avail_bytes); /* need_bytes may be zero */ + duk_memcpy((void *) p, (const void *) p_start, (size_t) need_bytes); + p += need_bytes; + /*avail_bytes += need_bytes*/ + + DUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, p); +} +#endif /* DUK_USE_PREFER_SIZE */ + +/* Shared entry handling for object/array serialization. */ +DUK_LOCAL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) { + duk_hthread *thr = js_ctx->thr; + duk_hobject *h_target; + duk_uint_fast32_t i, n; + + *entry_top = duk_get_top(thr); + + duk_require_stack(thr, DUK_JSON_ENC_REQSTACK); + + /* Loop check using a hybrid approach: a fixed-size visited[] array + * with overflow in a loop check object. + */ + + h_target = duk_known_hobject(thr, -1); /* object or array */ + + n = js_ctx->recursion_depth; + if (DUK_UNLIKELY(n > DUK_JSON_ENC_LOOPARRAY)) { + n = DUK_JSON_ENC_LOOPARRAY; + } + for (i = 0; i < n; i++) { + if (DUK_UNLIKELY(js_ctx->visiting[i] == h_target)) { + DUK_DD(DUK_DDPRINT("slow path loop detect")); + DUK_ERROR_TYPE(thr, DUK_STR_CYCLIC_INPUT); + DUK_WO_NORETURN(return;); + } + } + if (js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY) { + js_ctx->visiting[js_ctx->recursion_depth] = h_target; + } else { + duk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) h_target); + duk_dup_top(thr); /* -> [ ... voidp voidp ] */ + if (duk_has_prop(thr, js_ctx->idx_loop)) { + DUK_ERROR_TYPE(thr, DUK_STR_CYCLIC_INPUT); + DUK_WO_NORETURN(return;); + } + duk_push_true(thr); /* -> [ ... voidp true ] */ + duk_put_prop(thr, js_ctx->idx_loop); /* -> [ ... ] */ + } + + /* C recursion check. */ + + DUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0); /* unsigned */ + DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit); + if (js_ctx->recursion_depth >= js_ctx->recursion_limit) { + DUK_ERROR_RANGE(thr, DUK_STR_JSONENC_RECLIMIT); + DUK_WO_NORETURN(return;); + } + js_ctx->recursion_depth++; + + DUK_DDD(DUK_DDDPRINT("shared entry finished: top=%ld, loop=%!T", + (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop))); +} + +/* Shared exit handling for object/array serialization. */ +DUK_LOCAL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) { + duk_hthread *thr = js_ctx->thr; + duk_hobject *h_target; + + /* C recursion check. */ + + DUK_ASSERT(js_ctx->recursion_depth > 0); + DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit); + js_ctx->recursion_depth--; + + /* Loop check. */ + + h_target = duk_known_hobject(thr, *entry_top - 1); /* original target at entry_top - 1 */ + + if (js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY) { + /* Previous entry was inside visited[], nothing to do. */ + } else { + duk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) h_target); + duk_del_prop(thr, js_ctx->idx_loop); /* -> [ ... ] */ + } + + /* Restore stack top after unbalanced code paths. */ + duk_set_top(thr, *entry_top); + + DUK_DDD(DUK_DDDPRINT("shared entry finished: top=%ld, loop=%!T", + (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop))); +} + +/* The JO(value) operation: encode object. + * + * Stack policy: [ object ] -> [ object ]. + */ +DUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) { + duk_hthread *thr = js_ctx->thr; + duk_hstring *h_key; + duk_idx_t entry_top; + duk_idx_t idx_obj; + duk_idx_t idx_keys; + duk_bool_t emitted; + duk_uarridx_t arr_len, i; + duk_size_t prev_size; + + DUK_DDD(DUK_DDDPRINT("duk__enc_object: obj=%!T", (duk_tval *) duk_get_tval(thr, -1))); + + duk__enc_objarr_entry(js_ctx, &entry_top); + + idx_obj = entry_top - 1; + + if (js_ctx->idx_proplist >= 0) { + idx_keys = js_ctx->idx_proplist; + } else { + /* XXX: would be nice to enumerate an object at specified index */ + duk_dup(thr, idx_obj); + (void) duk_hobject_get_enumerated_keys(thr, DUK_ENUM_OWN_PROPERTIES_ONLY /*flags*/); /* [ ... target ] -> [ ... target keys ] */ + idx_keys = duk_require_normalize_index(thr, -1); + /* leave stack unbalanced on purpose */ + } + + DUK_DDD(DUK_DDDPRINT("idx_keys=%ld, h_keys=%!T", + (long) idx_keys, (duk_tval *) duk_get_tval(thr, idx_keys))); + + /* Steps 8-10 have been merged to avoid a "partial" variable. */ + + DUK__EMIT_1(js_ctx, DUK_ASC_LCURLY); + + /* XXX: keys is an internal object with all keys to be processed + * in its (gapless) array part. Because nobody can touch the keys + * object, we could iterate its array part directly (keeping in mind + * that it can be reallocated). + */ + + arr_len = (duk_uarridx_t) duk_get_length(thr, idx_keys); + emitted = 0; + for (i = 0; i < arr_len; i++) { + duk_get_prop_index(thr, idx_keys, i); /* -> [ ... key ] */ + + DUK_DDD(DUK_DDDPRINT("object property loop: holder=%!T, key=%!T", + (duk_tval *) duk_get_tval(thr, idx_obj), + (duk_tval *) duk_get_tval(thr, -1))); + + h_key = duk_known_hstring(thr, -1); + DUK_ASSERT(h_key != NULL); + DUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(h_key)); /* proplist filtering; enum options */ + + prev_size = DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw); + if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { + duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth); + duk__enc_key_autoquote(js_ctx, h_key); + DUK__EMIT_2(js_ctx, DUK_ASC_COLON, DUK_ASC_SPACE); + } else { + duk__enc_key_autoquote(js_ctx, h_key); + DUK__EMIT_1(js_ctx, DUK_ASC_COLON); + } + + /* [ ... key ] */ + + if (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_obj) == 0)) { + /* Value would yield 'undefined', so skip key altogether. + * Side effects have already happened. + */ + DUK_BW_SET_SIZE(js_ctx->thr, &js_ctx->bw, prev_size); + } else { + DUK__EMIT_1(js_ctx, DUK_ASC_COMMA); + emitted = 1; + } + + /* [ ... ] */ + } + + if (emitted) { + DUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA); + DUK__UNEMIT_1(js_ctx); /* eat trailing comma */ + if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { + DUK_ASSERT(js_ctx->recursion_depth >= 1); + duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U); + } + } + DUK__EMIT_1(js_ctx, DUK_ASC_RCURLY); + + duk__enc_objarr_exit(js_ctx, &entry_top); + + DUK_ASSERT_TOP(thr, entry_top); +} + +/* The JA(value) operation: encode array. + * + * Stack policy: [ array ] -> [ array ]. + */ +DUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) { + duk_hthread *thr = js_ctx->thr; + duk_idx_t entry_top; + duk_idx_t idx_arr; + duk_bool_t emitted; + duk_uarridx_t i, arr_len; + + DUK_DDD(DUK_DDDPRINT("duk__enc_array: array=%!T", + (duk_tval *) duk_get_tval(thr, -1))); + + duk__enc_objarr_entry(js_ctx, &entry_top); + + idx_arr = entry_top - 1; + + /* Steps 8-10 have been merged to avoid a "partial" variable. */ + + DUK__EMIT_1(js_ctx, DUK_ASC_LBRACKET); + + arr_len = (duk_uarridx_t) duk_get_length(thr, idx_arr); + emitted = 0; + for (i = 0; i < arr_len; i++) { + DUK_DDD(DUK_DDDPRINT("array entry loop: array=%!T, index=%ld, arr_len=%ld", + (duk_tval *) duk_get_tval(thr, idx_arr), + (long) i, (long) arr_len)); + + if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { + DUK_ASSERT(js_ctx->recursion_depth >= 1); + duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth); + } + + (void) duk_push_uint_to_hstring(thr, (duk_uint_t) i); /* -> [ ... key ] */ + + /* [ ... key ] */ + + if (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_arr) == 0)) { + /* Value would normally be omitted, replace with 'null'. */ + DUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL); + } else { + ; + } + + /* [ ... ] */ + + DUK__EMIT_1(js_ctx, DUK_ASC_COMMA); + emitted = 1; + } + + if (emitted) { + DUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA); + DUK__UNEMIT_1(js_ctx); /* eat trailing comma */ + if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { + DUK_ASSERT(js_ctx->recursion_depth >= 1); + duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U); + } + } + DUK__EMIT_1(js_ctx, DUK_ASC_RBRACKET); + + duk__enc_objarr_exit(js_ctx, &entry_top); + + DUK_ASSERT_TOP(thr, entry_top); +} + +/* The Str(key, holder) operation. + * + * Stack policy: [ ... key ] -> [ ... ] + */ +DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder) { + duk_hthread *thr = js_ctx->thr; + duk_tval *tv; + duk_tval *tv_holder; + duk_tval *tv_key; + duk_small_int_t c; + + DUK_DDD(DUK_DDDPRINT("duk__enc_value: idx_holder=%ld, holder=%!T, key=%!T", + (long) idx_holder, (duk_tval *) duk_get_tval(thr, idx_holder), + (duk_tval *) duk_get_tval(thr, -1))); + + tv_holder = DUK_GET_TVAL_POSIDX(thr, idx_holder); + DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_holder)); + tv_key = DUK_GET_TVAL_NEGIDX(thr, -1); + DUK_ASSERT(DUK_TVAL_IS_STRING(tv_key)); + DUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(DUK_TVAL_GET_STRING(tv_key))); /* Caller responsible. */ + (void) duk_hobject_getprop(thr, tv_holder, tv_key); + + /* -> [ ... key val ] */ + + DUK_DDD(DUK_DDDPRINT("value=%!T", (duk_tval *) duk_get_tval(thr, -1))); + + /* Standard JSON checks for .toJSON() only for actual objects; for + * example, setting Number.prototype.toJSON and then serializing a + * number won't invoke the .toJSON() method. However, lightfuncs and + * plain buffers mimic objects so we check for their .toJSON() method. + */ + if (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT | + DUK_TYPE_MASK_LIGHTFUNC | + DUK_TYPE_MASK_BUFFER)) { + duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_JSON); + if (duk_is_callable(thr, -1)) { /* toJSON() can also be a lightfunc */ + DUK_DDD(DUK_DDDPRINT("value is object, has callable toJSON() -> call it")); + /* XXX: duk_dup_unvalidated(thr, -2) etc. */ + duk_dup_m2(thr); /* -> [ ... key val toJSON val ] */ + duk_dup_m4(thr); /* -> [ ... key val toJSON val key ] */ + duk_call_method(thr, 1); /* -> [ ... key val val' ] */ + duk_remove_m2(thr); /* -> [ ... key val' ] */ + } else { + duk_pop(thr); /* -> [ ... key val ] */ + } + } + + /* [ ... key val ] */ + + DUK_DDD(DUK_DDDPRINT("value=%!T", (duk_tval *) duk_get_tval(thr, -1))); + + if (js_ctx->h_replacer) { + /* XXX: Here a "slice copy" would be useful. */ + DUK_DDD(DUK_DDDPRINT("replacer is set, call replacer")); + duk_push_hobject(thr, js_ctx->h_replacer); /* -> [ ... key val replacer ] */ + duk_dup(thr, idx_holder); /* -> [ ... key val replacer holder ] */ + duk_dup_m4(thr); /* -> [ ... key val replacer holder key ] */ + duk_dup_m4(thr); /* -> [ ... key val replacer holder key val ] */ + duk_call_method(thr, 2); /* -> [ ... key val val' ] */ + duk_remove_m2(thr); /* -> [ ... key val' ] */ + } + + /* [ ... key val ] */ + + DUK_DDD(DUK_DDDPRINT("value=%!T", (duk_tval *) duk_get_tval(thr, -1))); + + tv = DUK_GET_TVAL_NEGIDX(thr, -1); + if (DUK_TVAL_IS_OBJECT(tv)) { + duk_hobject *h; + + h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + if (DUK_HOBJECT_IS_BUFOBJ(h) && + js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM | DUK_JSON_FLAG_EXT_COMPATIBLE)) { + /* With JX/JC a bufferobject gets serialized specially. */ + duk_hbufobj *h_bufobj; + h_bufobj = (duk_hbufobj *) h; + DUK_HBUFOBJ_ASSERT_VALID(h_bufobj); + duk__enc_bufobj(js_ctx, h_bufobj); + goto pop2_emitted; + } + /* Otherwise bufferobjects get serialized as normal objects. */ +#endif /* JX || JC */ +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + c = (duk_small_int_t) DUK_HOBJECT_GET_CLASS_NUMBER(h); + switch (c) { + case DUK_HOBJECT_CLASS_NUMBER: { + DUK_DDD(DUK_DDDPRINT("value is a Number object -> coerce with ToNumber()")); + duk_to_number_m1(thr); + /* The coercion potentially invokes user .valueOf() and .toString() + * but can't result in a function value because ToPrimitive() would + * reject such a result: test-dev-json-stringify-coercion-1.js. + */ + DUK_ASSERT(!duk_is_callable(thr, -1)); + break; + } + case DUK_HOBJECT_CLASS_STRING: { + DUK_DDD(DUK_DDDPRINT("value is a String object -> coerce with ToString()")); + duk_to_string(thr, -1); + /* Same coercion behavior as for Number. */ + DUK_ASSERT(!duk_is_callable(thr, -1)); + break; + } +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + case DUK_HOBJECT_CLASS_POINTER: +#endif + case DUK_HOBJECT_CLASS_BOOLEAN: { + DUK_DDD(DUK_DDDPRINT("value is a Boolean/Buffer/Pointer object -> get internal value")); + duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE); + duk_remove_m2(thr); + break; + } + default: { + /* Normal object which doesn't get automatically coerced to a + * primitive value. Functions are checked for specially. The + * primitive value coercions for Number, String, Pointer, and + * Boolean can't result in functions so suffices to check here. + * Symbol objects are handled like plain objects (their primitive + * value is NOT looked up like for e.g. String objects). + */ + DUK_ASSERT(h != NULL); + if (DUK_HOBJECT_IS_CALLABLE(h)) { +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + if (js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM | + DUK_JSON_FLAG_EXT_COMPATIBLE)) { + /* We only get here when doing non-standard JSON encoding */ + DUK_DDD(DUK_DDDPRINT("-> function allowed, serialize to custom format")); + DUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible); + DUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_function); + goto pop2_emitted; + } else { + DUK_DDD(DUK_DDDPRINT("-> will result in undefined (function)")); + goto pop2_undef; + } +#else /* DUK_USE_JX || DUK_USE_JC */ + DUK_DDD(DUK_DDDPRINT("-> will result in undefined (function)")); + goto pop2_undef; +#endif /* DUK_USE_JX || DUK_USE_JC */ + } + } + } /* end switch */ + } + + /* [ ... key val ] */ + + DUK_DDD(DUK_DDDPRINT("value=%!T", (duk_tval *) duk_get_tval(thr, -1))); + + if (duk_check_type_mask(thr, -1, js_ctx->mask_for_undefined)) { + /* will result in undefined */ + DUK_DDD(DUK_DDDPRINT("-> will result in undefined (type mask check)")); + goto pop2_undef; + } + tv = DUK_GET_TVAL_NEGIDX(thr, -1); + + switch (DUK_TVAL_GET_TAG(tv)) { +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + /* When JX/JC not in use, the type mask above will avoid this case if needed. */ + case DUK_TAG_UNDEFINED: { + DUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_undefined); + break; + } +#endif + case DUK_TAG_NULL: { + DUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL); + break; + } + case DUK_TAG_BOOLEAN: { + DUK__EMIT_STRIDX(js_ctx, DUK_TVAL_GET_BOOLEAN(tv) ? + DUK_STRIDX_TRUE : DUK_STRIDX_FALSE); + break; + } +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + /* When JX/JC not in use, the type mask above will avoid this case if needed. */ + case DUK_TAG_POINTER: { + duk__enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv)); + break; + } +#endif /* DUK_USE_JX || DUK_USE_JC */ + case DUK_TAG_STRING: { + duk_hstring *h = DUK_TVAL_GET_STRING(tv); + DUK_ASSERT(h != NULL); + if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) { + goto pop2_undef; + } + duk__enc_quote_string(js_ctx, h); + break; + } + case DUK_TAG_OBJECT: { + duk_hobject *h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + + /* Function values are handled completely above (including + * coercion results): + */ + DUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE(h)); + + if (duk_js_isarray_hobject(h)) { + duk__enc_array(js_ctx); + } else { + duk__enc_object(js_ctx); + } + break; + } + /* Because plain buffers mimics Uint8Array, they have enumerable + * index properties [0,byteLength[. Because JSON only serializes + * enumerable own properties, no properties can be serialized for + * plain buffers (all virtual properties are non-enumerable). However, + * there may be a .toJSON() method which was already handled above. + */ + case DUK_TAG_BUFFER: { +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + if (js_ctx->flag_ext_custom_or_compatible) { + duk__enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv)); + break; + } +#endif + + /* Could implement a fastpath, but the fast path would need + * to handle realloc side effects correctly. + */ + duk_to_object(thr, -1); + duk__enc_object(js_ctx); + break; + } + case DUK_TAG_LIGHTFUNC: { +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + /* We only get here when doing non-standard JSON encoding */ + DUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible); + DUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_function); +#else + /* Standard JSON omits functions */ + DUK_UNREACHABLE(); +#endif + break; + } +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: + /* Number serialization has a significant impact relative to + * other fast path code, so careful fast path for fastints. + */ + duk__enc_fastint_tval(js_ctx, tv); + break; +#endif + default: { + /* number */ + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv)); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); + /* XXX: A fast path for usual integers would be useful when + * fastint support is not enabled. + */ + duk__enc_double(js_ctx); + break; + } + } + +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + pop2_emitted: +#endif + duk_pop_2(thr); /* [ ... key val ] -> [ ... ] */ + return 1; /* emitted */ + + pop2_undef: + duk_pop_2(thr); /* [ ... key val ] -> [ ... ] */ + return 0; /* not emitted */ +} + +/* E5 Section 15.12.3, main algorithm, step 4.b.ii steps 1-4. */ +DUK_LOCAL duk_bool_t duk__enc_allow_into_proplist(duk_tval *tv) { + duk_small_int_t c; + + /* XXX: some kind of external internal type checker? + * - type mask; symbol flag; class mask + */ + DUK_ASSERT(tv != NULL); + if (DUK_TVAL_IS_STRING(tv)) { + duk_hstring *h; + h = DUK_TVAL_GET_STRING(tv); + DUK_ASSERT(h != NULL); + if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) { + return 0; + } + return 1; + } else if (DUK_TVAL_IS_NUMBER(tv)) { + return 1; + } else if (DUK_TVAL_IS_OBJECT(tv)) { + duk_hobject *h; + h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + c = (duk_small_int_t) DUK_HOBJECT_GET_CLASS_NUMBER(h); + if (c == DUK_HOBJECT_CLASS_STRING || c == DUK_HOBJECT_CLASS_NUMBER) { + return 1; + } + } + + return 0; +} + +/* + * JSON.stringify() fast path + * + * Otherwise supports full JSON, JX, and JC features, but bails out on any + * possible side effect which might change the value being serialized. The + * fast path can take advantage of the fact that the value being serialized + * is unchanged so that we can walk directly through property tables etc. + */ + +#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH) +DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, duk_tval *tv) { + duk_uint_fast32_t i, n; + + DUK_DDD(DUK_DDDPRINT("stringify fast: %!T", tv)); + + DUK_ASSERT(js_ctx != NULL); + DUK_ASSERT(js_ctx->thr != NULL); + +#if 0 /* disabled for now */ + restart_match: +#endif + + DUK_ASSERT(tv != NULL); + + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_UNDEFINED: { +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + if (js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible) { + DUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_undefined); + break; + } else { + goto emit_undefined; + } +#else + goto emit_undefined; +#endif + } + case DUK_TAG_NULL: { + DUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL); + break; + } + case DUK_TAG_BOOLEAN: { + DUK__EMIT_STRIDX(js_ctx, DUK_TVAL_GET_BOOLEAN(tv) ? + DUK_STRIDX_TRUE : DUK_STRIDX_FALSE); + break; + } + case DUK_TAG_STRING: { + duk_hstring *h; + h = DUK_TVAL_GET_STRING(tv); + DUK_ASSERT(h != NULL); + if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) { + goto emit_undefined; + } + duk__enc_quote_string(js_ctx, h); + break; + } + case DUK_TAG_OBJECT: { + duk_hobject *obj; + duk_tval *tv_val; + duk_bool_t emitted = 0; + duk_uint32_t c_bit, c_all, c_array, c_unbox, c_undef, + c_func, c_bufobj, c_object, c_abort; + + /* For objects JSON.stringify() only looks for own, enumerable + * properties which is nice for the fast path here. + * + * For arrays JSON.stringify() uses [[Get]] so it will actually + * inherit properties during serialization! This fast path + * supports gappy arrays as long as there's no actual inherited + * property (which might be a getter etc). + * + * Since recursion only happens for objects, we can have both + * recursion and loop checks here. We use a simple, depth-limited + * loop check in the fast path because the object-based tracking + * is very slow (when tested, it accounted for 50% of fast path + * execution time for input data with a lot of small objects!). + */ + + /* XXX: for real world code, could just ignore array inheritance + * and only look at array own properties. + */ + + /* We rely on a few object flag / class number relationships here, + * assert for them. + */ + + obj = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(obj != NULL); + DUK_HOBJECT_ASSERT_VALID(obj); + + /* Once recursion depth is increased, exit path must decrease + * it (though it's OK to abort the fast path). + */ + + DUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0); /* unsigned */ + DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit); + if (js_ctx->recursion_depth >= js_ctx->recursion_limit) { + DUK_DD(DUK_DDPRINT("fast path recursion limit")); + DUK_ERROR_RANGE(js_ctx->thr, DUK_STR_JSONDEC_RECLIMIT); + DUK_WO_NORETURN(return 0;); + } + + for (i = 0, n = (duk_uint_fast32_t) js_ctx->recursion_depth; i < n; i++) { + if (DUK_UNLIKELY(js_ctx->visiting[i] == obj)) { + DUK_DD(DUK_DDPRINT("fast path loop detect")); + DUK_ERROR_TYPE(js_ctx->thr, DUK_STR_CYCLIC_INPUT); + DUK_WO_NORETURN(return 0;); + } + } + + /* Guaranteed by recursion_limit setup so we don't have to + * check twice. + */ + DUK_ASSERT(js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY); + js_ctx->visiting[js_ctx->recursion_depth] = obj; + js_ctx->recursion_depth++; + + /* If object has a .toJSON() property, we can't be certain + * that it wouldn't mutate any value arbitrarily, so bail + * out of the fast path. + * + * If an object is a Proxy we also can't avoid side effects + * so abandon. + */ + /* XXX: non-callable .toJSON() doesn't need to cause an abort + * but does at the moment, probably not worth fixing. + */ + if (duk_hobject_hasprop_raw(js_ctx->thr, obj, DUK_HTHREAD_STRING_TO_JSON(js_ctx->thr)) || + DUK_HOBJECT_IS_PROXY(obj)) { + DUK_DD(DUK_DDPRINT("object has a .toJSON property or object is a Proxy, abort fast path")); + goto abort_fastpath; + } + + /* We could use a switch-case for the class number but it turns out + * a small if-else ladder on class masks is better. The if-ladder + * should be in order of relevancy. + */ + + /* XXX: move masks to js_ctx? they don't change during one + * fast path invocation. + */ + DUK_ASSERT(DUK_HOBJECT_CLASS_MAX <= 31); +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + if (js_ctx->flag_ext_custom_or_compatible) { + c_all = DUK_HOBJECT_CMASK_ALL; + c_array = DUK_HOBJECT_CMASK_ARRAY; + c_unbox = DUK_HOBJECT_CMASK_NUMBER | + DUK_HOBJECT_CMASK_STRING | + DUK_HOBJECT_CMASK_BOOLEAN | + DUK_HOBJECT_CMASK_POINTER; /* Symbols are not unboxed. */ + c_func = DUK_HOBJECT_CMASK_FUNCTION; + c_bufobj = DUK_HOBJECT_CMASK_ALL_BUFOBJS; + c_undef = 0; + c_abort = 0; + c_object = c_all & ~(c_array | c_unbox | c_func | c_bufobj | c_undef | c_abort); + } + else +#endif + { + c_all = DUK_HOBJECT_CMASK_ALL; + c_array = DUK_HOBJECT_CMASK_ARRAY; + c_unbox = DUK_HOBJECT_CMASK_NUMBER | + DUK_HOBJECT_CMASK_STRING | + DUK_HOBJECT_CMASK_BOOLEAN; /* Symbols are not unboxed. */ + c_func = 0; + c_bufobj = 0; + c_undef = DUK_HOBJECT_CMASK_FUNCTION | + DUK_HOBJECT_CMASK_POINTER; + /* As the fast path doesn't currently properly support + * duk_hbufobj virtual properties, abort fast path if + * we encounter them in plain JSON mode. + */ + c_abort = DUK_HOBJECT_CMASK_ALL_BUFOBJS; + c_object = c_all & ~(c_array | c_unbox | c_func | c_bufobj | c_undef | c_abort); + } + + c_bit = (duk_uint32_t) DUK_HOBJECT_GET_CLASS_MASK(obj); + if (c_bit & c_object) { + /* All other object types. */ + DUK__EMIT_1(js_ctx, DUK_ASC_LCURLY); + + /* A non-Array object should not have an array part in practice. + * But since it is supported internally (and perhaps used at some + * point), check and abandon if that's the case. + */ + if (DUK_HOBJECT_HAS_ARRAY_PART(obj)) { + DUK_DD(DUK_DDPRINT("non-Array object has array part, abort fast path")); + goto abort_fastpath; + } + + for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(obj); i++) { + duk_hstring *k; + duk_size_t prev_size; + + k = DUK_HOBJECT_E_GET_KEY(js_ctx->thr->heap, obj, i); + if (!k) { + continue; + } + if (DUK_HSTRING_HAS_ARRIDX(k)) { + /* If an object has array index keys we would need + * to sort them into the ES2015 enumeration order to + * be consistent with the slow path. Abort the fast + * path and handle in the slow path for now. + */ + DUK_DD(DUK_DDPRINT("property key is an array index, abort fast path")); + goto abort_fastpath; + } + if (!DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(js_ctx->thr->heap, obj, i)) { + continue; + } + if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(js_ctx->thr->heap, obj, i)) { + /* Getter might have arbitrary side effects, + * so bail out. + */ + DUK_DD(DUK_DDPRINT("property is an accessor, abort fast path")); + goto abort_fastpath; + } + if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(k))) { + continue; + } + + tv_val = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(js_ctx->thr->heap, obj, i); + + prev_size = DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw); + if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { + duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth); + duk__enc_key_autoquote(js_ctx, k); + DUK__EMIT_2(js_ctx, DUK_ASC_COLON, DUK_ASC_SPACE); + } else { + duk__enc_key_autoquote(js_ctx, k); + DUK__EMIT_1(js_ctx, DUK_ASC_COLON); + } + + if (duk__json_stringify_fast_value(js_ctx, tv_val) == 0) { + DUK_DD(DUK_DDPRINT("prop value not supported, rewind key and colon")); + DUK_BW_SET_SIZE(js_ctx->thr, &js_ctx->bw, prev_size); + } else { + DUK__EMIT_1(js_ctx, DUK_ASC_COMMA); + emitted = 1; + } + } + + /* If any non-Array value had enumerable virtual own + * properties, they should be serialized here (actually, + * before the explicit properties). Standard types don't. + */ + + if (emitted) { + DUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA); + DUK__UNEMIT_1(js_ctx); /* eat trailing comma */ + if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { + DUK_ASSERT(js_ctx->recursion_depth >= 1); + duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U); + } + } + DUK__EMIT_1(js_ctx, DUK_ASC_RCURLY); + } else if (c_bit & c_array) { + duk_uint_fast32_t arr_len; + duk_uint_fast32_t asize; + + DUK__EMIT_1(js_ctx, DUK_ASC_LBRACKET); + + /* Assume arrays are dense in the fast path. */ + if (!DUK_HOBJECT_HAS_ARRAY_PART(obj)) { + DUK_DD(DUK_DDPRINT("Array object is sparse, abort fast path")); + goto abort_fastpath; + } + + arr_len = (duk_uint_fast32_t) ((duk_harray *) obj)->length; + asize = (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(obj); + /* Array part may be larger than 'length'; if so, iterate + * only up to array 'length'. Array part may also be smaller + * than 'length' in some cases. + */ + for (i = 0; i < arr_len; i++) { + duk_tval *tv_arrval; + duk_hstring *h_tmp; + duk_bool_t has_inherited; + + if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { + duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth); + } + + if (DUK_LIKELY(i < asize)) { + tv_arrval = DUK_HOBJECT_A_GET_VALUE_PTR(js_ctx->thr->heap, obj, i); + if (DUK_LIKELY(!DUK_TVAL_IS_UNUSED(tv_arrval))) { + /* Expected case: element is present. */ + if (duk__json_stringify_fast_value(js_ctx, tv_arrval) == 0) { + DUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL); + } + goto elem_done; + } + } + + /* Gap in array; check for inherited property, + * bail out if one exists. This should be enough + * to support gappy arrays for all practical code. + */ + + h_tmp = duk_push_uint_to_hstring(js_ctx->thr, (duk_uint_t) i); + has_inherited = duk_hobject_hasprop_raw(js_ctx->thr, obj, h_tmp); + duk_pop(js_ctx->thr); + if (has_inherited) { + DUK_D(DUK_DPRINT("gap in array, conflicting inherited property, abort fast path")); + goto abort_fastpath; + } + + /* Ordinary gap, undefined encodes to 'null' in + * standard JSON, but JX/JC use their form for + * undefined to better preserve the typing. + */ + DUK_D(DUK_DPRINT("gap in array, no conflicting inherited property, remain on fast path")); +#if defined(DUK_USE_JX) + DUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_undefined); +#else + DUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL); +#endif + /* fall through */ + + elem_done: + DUK__EMIT_1(js_ctx, DUK_ASC_COMMA); + emitted = 1; + } + + if (emitted) { + DUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA); + DUK__UNEMIT_1(js_ctx); /* eat trailing comma */ + if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { + DUK_ASSERT(js_ctx->recursion_depth >= 1); + duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U); + } + } + DUK__EMIT_1(js_ctx, DUK_ASC_RBRACKET); + } else if (c_bit & c_unbox) { + /* Certain boxed types are required to go through + * automatic unboxing. Rely on internal value being + * sane (to avoid infinite recursion). + */ + DUK_ASSERT((c_bit & DUK_HOBJECT_CMASK_SYMBOL) == 0); /* Symbols are not unboxed. */ + +#if 1 + /* The code below is incorrect if .toString() or .valueOf() have + * have been overridden. The correct approach would be to look up + * the method(s) and if they resolve to the built-in function we + * can safely bypass it and look up the internal value directly. + * Unimplemented for now, abort fast path for boxed values. + */ + goto abort_fastpath; +#else /* disabled */ + /* Disabled until fixed, see above. */ + duk_tval *tv_internal; + + DUK_DD(DUK_DDPRINT("auto unboxing in fast path")); + + tv_internal = duk_hobject_get_internal_value_tval_ptr(js_ctx->thr->heap, obj); + DUK_ASSERT(tv_internal != NULL); + DUK_ASSERT(DUK_TVAL_IS_STRING(tv_internal) || + DUK_TVAL_IS_NUMBER(tv_internal) || + DUK_TVAL_IS_BOOLEAN(tv_internal) || + DUK_TVAL_IS_POINTER(tv_internal)); + + tv = tv_internal; + DUK_ASSERT(js_ctx->recursion_depth > 0); + js_ctx->recursion_depth--; /* required to keep recursion depth correct */ + goto restart_match; +#endif /* disabled */ +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + } else if (c_bit & c_func) { + DUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_function); +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + } else if (c_bit & c_bufobj) { + duk__enc_bufobj(js_ctx, (duk_hbufobj *) obj); +#endif +#endif + } else if (c_bit & c_abort) { + DUK_DD(DUK_DDPRINT("abort fast path for unsupported type")); + goto abort_fastpath; + } else { + DUK_ASSERT((c_bit & c_undef) != 0); + + /* Must decrease recursion depth before returning. */ + DUK_ASSERT(js_ctx->recursion_depth > 0); + DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit); + js_ctx->recursion_depth--; + goto emit_undefined; + } + + DUK_ASSERT(js_ctx->recursion_depth > 0); + DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit); + js_ctx->recursion_depth--; + break; + } + case DUK_TAG_BUFFER: { + /* Plain buffers are treated like Uint8Arrays: they have + * enumerable indices. Other virtual properties are not + * enumerable, and inherited properties are not serialized. + * However, there can be a replacer (not relevant here) or + * a .toJSON() method (which we need to check for explicitly). + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + if (duk_hobject_hasprop_raw(js_ctx->thr, + js_ctx->thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE], + DUK_HTHREAD_STRING_TO_JSON(js_ctx->thr))) { + DUK_DD(DUK_DDPRINT("value is a plain buffer and there's an inherited .toJSON, abort fast path")); + goto abort_fastpath; + } +#endif + +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + if (js_ctx->flag_ext_custom_or_compatible) { + duk__enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv)); + break; + } +#endif + + /* Plain buffers mimic Uint8Arrays, and have enumerable index + * properties. + */ + duk__enc_buffer_json_fastpath(js_ctx, DUK_TVAL_GET_BUFFER(tv)); + break; + } + case DUK_TAG_POINTER: { +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + if (js_ctx->flag_ext_custom_or_compatible) { + duk__enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv)); + break; + } else { + goto emit_undefined; + } +#else + goto emit_undefined; +#endif + } + case DUK_TAG_LIGHTFUNC: { + /* A lightfunc might also inherit a .toJSON() so just bail out. */ + /* XXX: Could just lookup .toJSON() and continue in fast path, + * as it would almost never be defined. + */ + DUK_DD(DUK_DDPRINT("value is a lightfunc, abort fast path")); + goto abort_fastpath; + } +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: { + /* Number serialization has a significant impact relative to + * other fast path code, so careful fast path for fastints. + */ + duk__enc_fastint_tval(js_ctx, tv); + break; + } +#endif + default: { + /* XXX: A fast path for usual integers would be useful when + * fastint support is not enabled. + */ + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv)); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); + + /* XXX: Stack discipline is annoying, could be changed in numconv. */ + duk_push_tval(js_ctx->thr, tv); + duk__enc_double(js_ctx); + duk_pop(js_ctx->thr); + +#if 0 + /* Could also rely on native sprintf(), but it will handle + * values like NaN, Infinity, -0, exponent notation etc in + * a JSON-incompatible way. + */ + duk_double_t d; + char buf[64]; + + DUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv)); + d = DUK_TVAL_GET_DOUBLE(tv); + DUK_SPRINTF(buf, "%lg", d); + DUK__EMIT_CSTR(js_ctx, buf); +#endif + } + } + return 1; /* not undefined */ + + emit_undefined: + return 0; /* value was undefined/unsupported */ + + abort_fastpath: + /* Error message doesn't matter: the error is ignored anyway. */ + DUK_DD(DUK_DDPRINT("aborting fast path")); + DUK_ERROR_INTERNAL(js_ctx->thr); + DUK_WO_NORETURN(return 0;); +} + +DUK_LOCAL duk_ret_t duk__json_stringify_fast(duk_hthread *thr, void *udata) { + duk_json_enc_ctx *js_ctx; + duk_tval *tv; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(udata != NULL); + + js_ctx = (duk_json_enc_ctx *) udata; + DUK_ASSERT(js_ctx != NULL); + + tv = DUK_GET_TVAL_NEGIDX(thr, -1); + if (duk__json_stringify_fast_value(js_ctx, tv) == 0) { + DUK_DD(DUK_DDPRINT("top level value not supported, fail fast path")); + DUK_DCERROR_TYPE_INVALID_ARGS(thr); /* Error message is ignored, so doesn't matter. */ + } + + return 0; +} +#endif /* DUK_USE_JSON_STRINGIFY_FASTPATH */ + +/* + * Top level wrappers + */ + +DUK_INTERNAL +void duk_bi_json_parse_helper(duk_hthread *thr, + duk_idx_t idx_value, + duk_idx_t idx_reviver, + duk_small_uint_t flags) { + duk_json_dec_ctx js_ctx_alloc; + duk_json_dec_ctx *js_ctx = &js_ctx_alloc; + duk_hstring *h_text; +#if defined(DUK_USE_ASSERTIONS) + duk_idx_t entry_top = duk_get_top(thr); +#endif + + /* negative top-relative indices not allowed now */ + DUK_ASSERT(idx_value == DUK_INVALID_INDEX || idx_value >= 0); + DUK_ASSERT(idx_reviver == DUK_INVALID_INDEX || idx_reviver >= 0); + + DUK_DDD(DUK_DDDPRINT("JSON parse start: text=%!T, reviver=%!T, flags=0x%08lx, stack_top=%ld", + (duk_tval *) duk_get_tval(thr, idx_value), + (duk_tval *) duk_get_tval(thr, idx_reviver), + (unsigned long) flags, + (long) duk_get_top(thr))); + + duk_memzero(&js_ctx_alloc, sizeof(js_ctx_alloc)); + js_ctx->thr = thr; +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + /* nothing now */ +#endif + js_ctx->recursion_limit = DUK_USE_JSON_DEC_RECLIMIT; + DUK_ASSERT(js_ctx->recursion_depth == 0); + + /* Flag handling currently assumes that flags are consistent. This is OK + * because the call sites are now strictly controlled. + */ + + js_ctx->flags = flags; +#if defined(DUK_USE_JX) + js_ctx->flag_ext_custom = flags & DUK_JSON_FLAG_EXT_CUSTOM; +#endif +#if defined(DUK_USE_JC) + js_ctx->flag_ext_compatible = flags & DUK_JSON_FLAG_EXT_COMPATIBLE; +#endif +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + js_ctx->flag_ext_custom_or_compatible = flags & (DUK_JSON_FLAG_EXT_CUSTOM | DUK_JSON_FLAG_EXT_COMPATIBLE); +#endif + + h_text = duk_to_hstring(thr, idx_value); /* coerce in-place; rejects Symbols */ + DUK_ASSERT(h_text != NULL); + + /* JSON parsing code is allowed to read [p_start,p_end]: p_end is + * valid and points to the string NUL terminator (which is always + * guaranteed for duk_hstrings. + */ + js_ctx->p_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_text); + js_ctx->p = js_ctx->p_start; + js_ctx->p_end = ((const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_text)) + + DUK_HSTRING_GET_BYTELEN(h_text); + DUK_ASSERT(*(js_ctx->p_end) == 0x00); + + duk__dec_value(js_ctx); /* -> [ ... value ] */ + + /* Trailing whitespace has been eaten by duk__dec_value(), so if + * we're not at end of input here, it's a SyntaxError. + */ + + if (js_ctx->p != js_ctx->p_end) { + duk__dec_syntax_error(js_ctx); + } + + if (duk_is_callable(thr, idx_reviver)) { + DUK_DDD(DUK_DDDPRINT("applying reviver: %!T", + (duk_tval *) duk_get_tval(thr, idx_reviver))); + + js_ctx->idx_reviver = idx_reviver; + + duk_push_object(thr); + duk_dup_m2(thr); /* -> [ ... val root val ] */ + duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_EMPTY_STRING); /* default attrs ok */ + duk_push_hstring_stridx(thr, DUK_STRIDX_EMPTY_STRING); /* -> [ ... val root "" ] */ + + DUK_DDD(DUK_DDDPRINT("start reviver walk, root=%!T, name=%!T", + (duk_tval *) duk_get_tval(thr, -2), + (duk_tval *) duk_get_tval(thr, -1))); + + duk__dec_reviver_walk(js_ctx); /* [ ... val root "" ] -> [ ... val val' ] */ + duk_remove_m2(thr); /* -> [ ... val' ] */ + } else { + DUK_DDD(DUK_DDDPRINT("reviver does not exist or is not callable: %!T", + (duk_tval *) duk_get_tval(thr, idx_reviver))); + } + + /* Final result is at stack top. */ + + DUK_DDD(DUK_DDDPRINT("JSON parse end: text=%!T, reviver=%!T, flags=0x%08lx, result=%!T, stack_top=%ld", + (duk_tval *) duk_get_tval(thr, idx_value), + (duk_tval *) duk_get_tval(thr, idx_reviver), + (unsigned long) flags, + (duk_tval *) duk_get_tval(thr, -1), + (long) duk_get_top(thr))); + + DUK_ASSERT(duk_get_top(thr) == entry_top + 1); +} + +DUK_INTERNAL +void duk_bi_json_stringify_helper(duk_hthread *thr, + duk_idx_t idx_value, + duk_idx_t idx_replacer, + duk_idx_t idx_space, + duk_small_uint_t flags) { + duk_json_enc_ctx js_ctx_alloc; + duk_json_enc_ctx *js_ctx = &js_ctx_alloc; + duk_hobject *h; + duk_idx_t idx_holder; + duk_idx_t entry_top; + + /* negative top-relative indices not allowed now */ + DUK_ASSERT(idx_value == DUK_INVALID_INDEX || idx_value >= 0); + DUK_ASSERT(idx_replacer == DUK_INVALID_INDEX || idx_replacer >= 0); + DUK_ASSERT(idx_space == DUK_INVALID_INDEX || idx_space >= 0); + + DUK_DDD(DUK_DDDPRINT("JSON stringify start: value=%!T, replacer=%!T, space=%!T, flags=0x%08lx, stack_top=%ld", + (duk_tval *) duk_get_tval(thr, idx_value), + (duk_tval *) duk_get_tval(thr, idx_replacer), + (duk_tval *) duk_get_tval(thr, idx_space), + (unsigned long) flags, + (long) duk_get_top(thr))); + + entry_top = duk_get_top(thr); + + /* + * Context init + */ + + duk_memzero(&js_ctx_alloc, sizeof(js_ctx_alloc)); + js_ctx->thr = thr; +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + js_ctx->h_replacer = NULL; + js_ctx->h_gap = NULL; +#endif + js_ctx->idx_proplist = -1; + + /* Flag handling currently assumes that flags are consistent. This is OK + * because the call sites are now strictly controlled. + */ + + js_ctx->flags = flags; + js_ctx->flag_ascii_only = flags & DUK_JSON_FLAG_ASCII_ONLY; + js_ctx->flag_avoid_key_quotes = flags & DUK_JSON_FLAG_AVOID_KEY_QUOTES; +#if defined(DUK_USE_JX) + js_ctx->flag_ext_custom = flags & DUK_JSON_FLAG_EXT_CUSTOM; +#endif +#if defined(DUK_USE_JC) + js_ctx->flag_ext_compatible = flags & DUK_JSON_FLAG_EXT_COMPATIBLE; +#endif +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + js_ctx->flag_ext_custom_or_compatible = flags & (DUK_JSON_FLAG_EXT_CUSTOM | DUK_JSON_FLAG_EXT_COMPATIBLE); +#endif + + /* The #if defined() clutter here handles the JX/JC enable/disable + * combinations properly. + */ +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + js_ctx->stridx_custom_undefined = DUK_STRIDX_LC_NULL; /* standard JSON; array gaps */ +#if defined(DUK_USE_JX) + if (flags & DUK_JSON_FLAG_EXT_CUSTOM) { + js_ctx->stridx_custom_undefined = DUK_STRIDX_LC_UNDEFINED; + js_ctx->stridx_custom_nan = DUK_STRIDX_NAN; + js_ctx->stridx_custom_neginf = DUK_STRIDX_MINUS_INFINITY; + js_ctx->stridx_custom_posinf = DUK_STRIDX_INFINITY; + js_ctx->stridx_custom_function = + (flags & DUK_JSON_FLAG_AVOID_KEY_QUOTES) ? + DUK_STRIDX_JSON_EXT_FUNCTION2 : + DUK_STRIDX_JSON_EXT_FUNCTION1; + } +#endif /* DUK_USE_JX */ +#if defined(DUK_USE_JX) && defined(DUK_USE_JC) + else +#endif /* DUK_USE_JX && DUK_USE_JC */ +#if defined(DUK_USE_JC) + if (js_ctx->flags & DUK_JSON_FLAG_EXT_COMPATIBLE) { + js_ctx->stridx_custom_undefined = DUK_STRIDX_JSON_EXT_UNDEFINED; + js_ctx->stridx_custom_nan = DUK_STRIDX_JSON_EXT_NAN; + js_ctx->stridx_custom_neginf = DUK_STRIDX_JSON_EXT_NEGINF; + js_ctx->stridx_custom_posinf = DUK_STRIDX_JSON_EXT_POSINF; + js_ctx->stridx_custom_function = DUK_STRIDX_JSON_EXT_FUNCTION1; + } +#endif /* DUK_USE_JC */ +#endif /* DUK_USE_JX || DUK_USE_JC */ + +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + if (js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM | + DUK_JSON_FLAG_EXT_COMPATIBLE)) { + DUK_ASSERT(js_ctx->mask_for_undefined == 0); /* already zero */ + } + else +#endif /* DUK_USE_JX || DUK_USE_JC */ + { + /* Plain buffer is treated like ArrayBuffer and serialized. + * Lightfuncs are treated like objects, but JSON explicitly + * skips serializing Function objects so we can just reject + * lightfuncs here. + */ + js_ctx->mask_for_undefined = DUK_TYPE_MASK_UNDEFINED | + DUK_TYPE_MASK_POINTER | + DUK_TYPE_MASK_LIGHTFUNC; + } + + DUK_BW_INIT_PUSHBUF(thr, &js_ctx->bw, DUK__JSON_STRINGIFY_BUFSIZE); + + js_ctx->idx_loop = duk_push_bare_object(thr); + DUK_ASSERT(js_ctx->idx_loop >= 0); + + /* [ ... buf loop ] */ + + /* + * Process replacer/proplist (2nd argument to JSON.stringify) + */ + + h = duk_get_hobject(thr, idx_replacer); + if (h != NULL) { + if (DUK_HOBJECT_IS_CALLABLE(h)) { + js_ctx->h_replacer = h; + } else if (duk_js_isarray_hobject(h)) { + /* Here the specification requires correct array index enumeration + * which is a bit tricky for sparse arrays (it is handled by the + * enum setup code). We now enumerate ancestors too, although the + * specification is not very clear on whether that is required. + */ + + duk_uarridx_t plist_idx = 0; + duk_small_uint_t enum_flags; + + js_ctx->idx_proplist = duk_push_array(thr); /* XXX: array internal? */ + + enum_flags = DUK_ENUM_ARRAY_INDICES_ONLY | + DUK_ENUM_SORT_ARRAY_INDICES; /* expensive flag */ + duk_enum(thr, idx_replacer, enum_flags); + while (duk_next(thr, -1 /*enum_index*/, 1 /*get_value*/)) { + /* [ ... proplist enum_obj key val ] */ + if (duk__enc_allow_into_proplist(duk_get_tval(thr, -1))) { + /* XXX: duplicates should be eliminated here */ + DUK_DDD(DUK_DDDPRINT("proplist enum: key=%!T, val=%!T --> accept", + (duk_tval *) duk_get_tval(thr, -2), + (duk_tval *) duk_get_tval(thr, -1))); + duk_to_string(thr, -1); /* extra coercion of strings is OK */ + duk_put_prop_index(thr, -4, plist_idx); /* -> [ ... proplist enum_obj key ] */ + plist_idx++; + duk_pop(thr); + } else { + DUK_DDD(DUK_DDDPRINT("proplist enum: key=%!T, val=%!T --> reject", + (duk_tval *) duk_get_tval(thr, -2), + (duk_tval *) duk_get_tval(thr, -1))); + duk_pop_2(thr); + } + } + duk_pop(thr); /* pop enum */ + + /* [ ... proplist ] */ + } + } + + /* [ ... buf loop (proplist) ] */ + + /* + * Process space (3rd argument to JSON.stringify) + */ + + h = duk_get_hobject(thr, idx_space); + if (h != NULL) { + duk_small_uint_t c = DUK_HOBJECT_GET_CLASS_NUMBER(h); + if (c == DUK_HOBJECT_CLASS_NUMBER) { + duk_to_number(thr, idx_space); + } else if (c == DUK_HOBJECT_CLASS_STRING) { + duk_to_string(thr, idx_space); + } + } + + if (duk_is_number(thr, idx_space)) { + duk_small_int_t nspace; + /* spaces[] must be static to allow initializer with old compilers like BCC */ + static const char spaces[10] = { + DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE, + DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE, + DUK_ASC_SPACE, DUK_ASC_SPACE + }; /* XXX: helper */ + + /* ToInteger() coercion; NaN -> 0, infinities are clamped to 0 and 10 */ + nspace = (duk_small_int_t) duk_to_int_clamped(thr, idx_space, 0 /*minval*/, 10 /*maxval*/); + DUK_ASSERT(nspace >= 0 && nspace <= 10); + + duk_push_lstring(thr, spaces, (duk_size_t) nspace); + js_ctx->h_gap = duk_known_hstring(thr, -1); + DUK_ASSERT(js_ctx->h_gap != NULL); + } else if (duk_is_string_notsymbol(thr, idx_space)) { + duk_dup(thr, idx_space); + duk_substring(thr, -1, 0, 10); /* clamp to 10 chars */ + js_ctx->h_gap = duk_known_hstring(thr, -1); + } else { + /* nop */ + } + + if (js_ctx->h_gap != NULL) { + /* If gap is empty, behave as if not given at all. Check + * against byte length because character length is more + * expensive. + */ + if (DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) == 0) { + js_ctx->h_gap = NULL; + } + } + + /* [ ... buf loop (proplist) (gap) ] */ + + /* + * Fast path: assume no mutation, iterate object property tables + * directly; bail out if that assumption doesn't hold. + */ + +#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH) + if (js_ctx->h_replacer == NULL && /* replacer is a mutation risk */ + js_ctx->idx_proplist == -1) { /* proplist is very rare */ + duk_int_t pcall_rc; + duk_small_uint_t prev_ms_base_flags; + + DUK_DD(DUK_DDPRINT("try JSON.stringify() fast path")); + + /* Use recursion_limit to ensure we don't overwrite js_ctx->visiting[] + * array so we don't need two counter checks in the fast path. The + * slow path has a much larger recursion limit which we'll use if + * necessary. + */ + DUK_ASSERT(DUK_USE_JSON_ENC_RECLIMIT >= DUK_JSON_ENC_LOOPARRAY); + js_ctx->recursion_limit = DUK_JSON_ENC_LOOPARRAY; + DUK_ASSERT(js_ctx->recursion_depth == 0); + + /* Execute the fast path in a protected call. If any error is thrown, + * fall back to the slow path. This includes e.g. recursion limit + * because the fast path has a smaller recursion limit (and simpler, + * limited loop detection). + */ + + duk_dup(thr, idx_value); + + /* Must prevent finalizers which may have arbitrary side effects. */ + prev_ms_base_flags = thr->heap->ms_base_flags; + thr->heap->ms_base_flags |= + DUK_MS_FLAG_NO_OBJECT_COMPACTION; /* Avoid attempt to compact any objects. */ + thr->heap->pf_prevent_count++; /* Prevent finalizers. */ + DUK_ASSERT(thr->heap->pf_prevent_count != 0); /* Wrap. */ + + pcall_rc = duk_safe_call(thr, duk__json_stringify_fast, (void *) js_ctx /*udata*/, 1 /*nargs*/, 0 /*nret*/); + + DUK_ASSERT(thr->heap->pf_prevent_count > 0); + thr->heap->pf_prevent_count--; + thr->heap->ms_base_flags = prev_ms_base_flags; + + if (pcall_rc == DUK_EXEC_SUCCESS) { + DUK_DD(DUK_DDPRINT("fast path successful")); + DUK_BW_PUSH_AS_STRING(thr, &js_ctx->bw); + goto replace_finished; + } + + /* We come here for actual aborts (like encountering .toJSON()) + * but also for recursion/loop errors. Bufwriter size can be + * kept because we'll probably need at least as much as we've + * allocated so far. + */ + DUK_D(DUK_DPRINT("fast path failed, serialize using slow path instead")); + DUK_BW_RESET_SIZE(thr, &js_ctx->bw); + js_ctx->recursion_depth = 0; + } +#endif + + /* + * Create wrapper object and serialize + */ + + idx_holder = duk_push_object(thr); + duk_dup(thr, idx_value); + duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_EMPTY_STRING); + + DUK_DDD(DUK_DDDPRINT("before: flags=0x%08lx, loop=%!T, replacer=%!O, " + "proplist=%!T, gap=%!O, holder=%!T", + (unsigned long) js_ctx->flags, + (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop), + (duk_heaphdr *) js_ctx->h_replacer, + (duk_tval *) (js_ctx->idx_proplist >= 0 ? duk_get_tval(thr, js_ctx->idx_proplist) : NULL), + (duk_heaphdr *) js_ctx->h_gap, + (duk_tval *) duk_get_tval(thr, -1))); + + /* serialize the wrapper with empty string key */ + + duk_push_hstring_empty(thr); + + /* [ ... buf loop (proplist) (gap) holder "" ] */ + + js_ctx->recursion_limit = DUK_USE_JSON_ENC_RECLIMIT; + DUK_ASSERT(js_ctx->recursion_depth == 0); + + if (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_holder) == 0)) { /* [ ... holder key ] -> [ ... holder ] */ + /* Result is undefined. */ + duk_push_undefined(thr); + } else { + /* Convert buffer to result string. */ + DUK_BW_PUSH_AS_STRING(thr, &js_ctx->bw); + } + + DUK_DDD(DUK_DDDPRINT("after: flags=0x%08lx, loop=%!T, replacer=%!O, " + "proplist=%!T, gap=%!O, holder=%!T", + (unsigned long) js_ctx->flags, + (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop), + (duk_heaphdr *) js_ctx->h_replacer, + (duk_tval *) (js_ctx->idx_proplist >= 0 ? duk_get_tval(thr, js_ctx->idx_proplist) : NULL), + (duk_heaphdr *) js_ctx->h_gap, + (duk_tval *) duk_get_tval(thr, idx_holder))); + + /* The stack has a variable shape here, so force it to the + * desired one explicitly. + */ + +#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH) + replace_finished: +#endif + duk_replace(thr, entry_top); + duk_set_top(thr, entry_top + 1); + + DUK_DDD(DUK_DDDPRINT("JSON stringify end: value=%!T, replacer=%!T, space=%!T, " + "flags=0x%08lx, result=%!T, stack_top=%ld", + (duk_tval *) duk_get_tval(thr, idx_value), + (duk_tval *) duk_get_tval(thr, idx_replacer), + (duk_tval *) duk_get_tval(thr, idx_space), + (unsigned long) flags, + (duk_tval *) duk_get_tval(thr, -1), + (long) duk_get_top(thr))); + + DUK_ASSERT(duk_get_top(thr) == entry_top + 1); +} + +#if defined(DUK_USE_JSON_BUILTIN) + +/* + * Entry points + */ + +DUK_INTERNAL duk_ret_t duk_bi_json_object_parse(duk_hthread *thr) { + duk_bi_json_parse_helper(thr, + 0 /*idx_value*/, + 1 /*idx_replacer*/, + 0 /*flags*/); + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_json_object_stringify(duk_hthread *thr) { + duk_bi_json_stringify_helper(thr, + 0 /*idx_value*/, + 1 /*idx_replacer*/, + 2 /*idx_space*/, + 0 /*flags*/); + return 1; +} + +#endif /* DUK_USE_JSON_BUILTIN */ + +#endif /* DUK_USE_JSON_SUPPORT */ diff --git a/third_party/duktape/duk_bi_math.c b/third_party/duktape/duk_bi_math.c new file mode 100644 index 00000000..d7587375 --- /dev/null +++ b/third_party/duktape/duk_bi_math.c @@ -0,0 +1,519 @@ +/* + * Math built-ins + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_MATH_BUILTIN) + +/* + * Use static helpers which can work with math.h functions matching + * the following signatures. This is not portable if any of these math + * functions is actually a macro. + * + * Typing here is intentionally 'double' wherever values interact with + * the standard library APIs. + */ + +typedef double (*duk__one_arg_func)(double); +typedef double (*duk__two_arg_func)(double, double); + +DUK_LOCAL duk_ret_t duk__math_minmax(duk_hthread *thr, duk_double_t initial, duk__two_arg_func min_max) { + duk_idx_t n = duk_get_top(thr); + duk_idx_t i; + duk_double_t res = initial; + duk_double_t t; + + /* + * Note: fmax() does not match the E5 semantics. E5 requires + * that if -any- input to Math.max() is a NaN, the result is a + * NaN. fmax() will return a NaN only if -both- inputs are NaN. + * Same applies to fmin(). + * + * Note: every input value must be coerced with ToNumber(), even + * if we know the result will be a NaN anyway: ToNumber() may have + * side effects for which even order of evaluation matters. + */ + + for (i = 0; i < n; i++) { + t = duk_to_number(thr, i); + if (DUK_FPCLASSIFY(t) == DUK_FP_NAN || DUK_FPCLASSIFY(res) == DUK_FP_NAN) { + /* Note: not normalized, but duk_push_number() will normalize */ + res = (duk_double_t) DUK_DOUBLE_NAN; + } else { + res = (duk_double_t) min_max(res, (double) t); + } + } + + duk_push_number(thr, res); + return 1; +} + +DUK_LOCAL double duk__fmin_fixed(double x, double y) { + /* fmin() with args -0 and +0 is not guaranteed to return + * -0 as ECMAScript requires. + */ + if (duk_double_equals(x, 0.0) && duk_double_equals(y, 0.0)) { + duk_double_union du1, du2; + du1.d = x; + du2.d = y; + + /* Already checked to be zero so these must hold, and allow us + * to check for "x is -0 or y is -0" by ORing the high parts + * for comparison. + */ + DUK_ASSERT(du1.ui[DUK_DBL_IDX_UI0] == 0 || du1.ui[DUK_DBL_IDX_UI0] == 0x80000000UL); + DUK_ASSERT(du2.ui[DUK_DBL_IDX_UI0] == 0 || du2.ui[DUK_DBL_IDX_UI0] == 0x80000000UL); + + /* XXX: what's the safest way of creating a negative zero? */ + if ((du1.ui[DUK_DBL_IDX_UI0] | du2.ui[DUK_DBL_IDX_UI0]) != 0) { + /* Enter here if either x or y (or both) is -0. */ + return -0.0; + } else { + return +0.0; + } + } + return duk_double_fmin(x, y); +} + +DUK_LOCAL double duk__fmax_fixed(double x, double y) { + /* fmax() with args -0 and +0 is not guaranteed to return + * +0 as ECMAScript requires. + */ + if (duk_double_equals(x, 0.0) && duk_double_equals(y, 0.0)) { + if (DUK_SIGNBIT(x) == 0 || DUK_SIGNBIT(y) == 0) { + return +0.0; + } else { + return -0.0; + } + } + return duk_double_fmax(x, y); +} + +#if defined(DUK_USE_ES6) +DUK_LOCAL double duk__cbrt(double x) { + /* cbrt() is C99. To avoid hassling embedders with the need to provide a + * cube root function, we can get by with pow(). The result is not + * identical, but that's OK: ES2015 says it's implementation-dependent. + */ + +#if defined(DUK_CBRT) + /* cbrt() matches ES2015 requirements. */ + return DUK_CBRT(x); +#else + duk_small_int_t c = (duk_small_int_t) DUK_FPCLASSIFY(x); + + /* pow() does not, however. */ + if (c == DUK_FP_NAN || c == DUK_FP_INFINITE || c == DUK_FP_ZERO) { + return x; + } + if (DUK_SIGNBIT(x)) { + return -DUK_POW(-x, 1.0 / 3.0); + } else { + return DUK_POW(x, 1.0 / 3.0); + } +#endif +} + +DUK_LOCAL double duk__log2(double x) { +#if defined(DUK_LOG2) + return DUK_LOG2(x); +#else + return DUK_LOG(x) * DUK_DOUBLE_LOG2E; +#endif +} + +DUK_LOCAL double duk__log10(double x) { +#if defined(DUK_LOG10) + return DUK_LOG10(x); +#else + return DUK_LOG(x) * DUK_DOUBLE_LOG10E; +#endif +} + +DUK_LOCAL double duk__trunc(double x) { +#if defined(DUK_TRUNC) + return DUK_TRUNC(x); +#else + /* Handles -0 correctly: -0.0 matches 'x >= 0.0' but floor() + * is required to return -0 when the argument is -0. + */ + return x >= 0.0 ? DUK_FLOOR(x) : DUK_CEIL(x); +#endif +} +#endif /* DUK_USE_ES6 */ + +DUK_LOCAL double duk__round_fixed(double x) { + /* Numbers half-way between integers must be rounded towards +Infinity, + * e.g. -3.5 must be rounded to -3 (not -4). When rounded to zero, zero + * sign must be set appropriately. E5.1 Section 15.8.2.15. + * + * Note that ANSI C round() is "round to nearest integer, away from zero", + * which is incorrect for negative values. Here we make do with floor(). + */ + + duk_small_int_t c = (duk_small_int_t) DUK_FPCLASSIFY(x); + if (c == DUK_FP_NAN || c == DUK_FP_INFINITE || c == DUK_FP_ZERO) { + return x; + } + + /* + * x is finite and non-zero + * + * -1.6 -> floor(-1.1) -> -2 + * -1.5 -> floor(-1.0) -> -1 (towards +Inf) + * -1.4 -> floor(-0.9) -> -1 + * -0.5 -> -0.0 (special case) + * -0.1 -> -0.0 (special case) + * +0.1 -> +0.0 (special case) + * +0.5 -> floor(+1.0) -> 1 (towards +Inf) + * +1.4 -> floor(+1.9) -> 1 + * +1.5 -> floor(+2.0) -> 2 (towards +Inf) + * +1.6 -> floor(+2.1) -> 2 + */ + + if (x >= -0.5 && x < 0.5) { + /* +0.5 is handled by floor, this is on purpose */ + if (x < 0.0) { + return -0.0; + } else { + return +0.0; + } + } + + return DUK_FLOOR(x + 0.5); +} + +/* Wrappers for calling standard math library methods. These may be required + * on platforms where one or more of the math built-ins are defined as macros + * or inline functions and are thus not suitable to be used as function pointers. + */ +#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS) +DUK_LOCAL double duk__fabs(double x) { + return DUK_FABS(x); +} +DUK_LOCAL double duk__acos(double x) { + return DUK_ACOS(x); +} +DUK_LOCAL double duk__asin(double x) { + return DUK_ASIN(x); +} +DUK_LOCAL double duk__atan(double x) { + return DUK_ATAN(x); +} +DUK_LOCAL double duk__ceil(double x) { + return DUK_CEIL(x); +} +DUK_LOCAL double duk__cos(double x) { + return DUK_COS(x); +} +DUK_LOCAL double duk__exp(double x) { + return DUK_EXP(x); +} +DUK_LOCAL double duk__floor(double x) { + return DUK_FLOOR(x); +} +DUK_LOCAL double duk__log(double x) { + return DUK_LOG(x); +} +DUK_LOCAL double duk__sin(double x) { + return DUK_SIN(x); +} +DUK_LOCAL double duk__sqrt(double x) { + return DUK_SQRT(x); +} +DUK_LOCAL double duk__tan(double x) { + return DUK_TAN(x); +} +DUK_LOCAL double duk__atan2_fixed(double x, double y) { +#if defined(DUK_USE_ATAN2_WORKAROUNDS) + /* Specific fixes to common atan2() implementation issues: + * - test-bug-mingw-math-issues.js + */ + if (DUK_ISINF(x) && DUK_ISINF(y)) { + if (DUK_SIGNBIT(x)) { + if (DUK_SIGNBIT(y)) { + return -2.356194490192345; + } else { + return -0.7853981633974483; + } + } else { + if (DUK_SIGNBIT(y)) { + return 2.356194490192345; + } else { + return 0.7853981633974483; + } + } + } +#else + /* Some ISO C assumptions. */ + + DUK_ASSERT(duk_double_equals(DUK_ATAN2(DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY), 0.7853981633974483)); + DUK_ASSERT(duk_double_equals(DUK_ATAN2(-DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY), -0.7853981633974483)); + DUK_ASSERT(duk_double_equals(DUK_ATAN2(DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY), 2.356194490192345)); + DUK_ASSERT(duk_double_equals(DUK_ATAN2(-DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY), -2.356194490192345)); +#endif + + return DUK_ATAN2(x, y); +} +#endif /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */ + +/* order must match constants in genbuiltins.py */ +DUK_LOCAL const duk__one_arg_func duk__one_arg_funcs[] = { +#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS) + duk__fabs, + duk__acos, + duk__asin, + duk__atan, + duk__ceil, + duk__cos, + duk__exp, + duk__floor, + duk__log, + duk__round_fixed, + duk__sin, + duk__sqrt, + duk__tan, +#if defined(DUK_USE_ES6) + duk__cbrt, + duk__log2, + duk__log10, + duk__trunc +#endif +#else /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */ + DUK_FABS, + DUK_ACOS, + DUK_ASIN, + DUK_ATAN, + DUK_CEIL, + DUK_COS, + DUK_EXP, + DUK_FLOOR, + DUK_LOG, + duk__round_fixed, + DUK_SIN, + DUK_SQRT, + DUK_TAN, +#if defined(DUK_USE_ES6) + duk__cbrt, + duk__log2, + duk__log10, + duk__trunc +#endif +#endif /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */ +}; + +/* order must match constants in genbuiltins.py */ +DUK_LOCAL const duk__two_arg_func duk__two_arg_funcs[] = { +#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS) + duk__atan2_fixed, + duk_js_arith_pow +#else + duk__atan2_fixed, + duk_js_arith_pow +#endif +}; + +DUK_INTERNAL duk_ret_t duk_bi_math_object_onearg_shared(duk_hthread *thr) { + duk_small_int_t fun_idx = duk_get_current_magic(thr); + duk__one_arg_func fun; + duk_double_t arg1; + + DUK_ASSERT(fun_idx >= 0); + DUK_ASSERT(fun_idx < (duk_small_int_t) (sizeof(duk__one_arg_funcs) / sizeof(duk__one_arg_func))); + arg1 = duk_to_number(thr, 0); + fun = duk__one_arg_funcs[fun_idx]; + duk_push_number(thr, (duk_double_t) fun((double) arg1)); + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_math_object_twoarg_shared(duk_hthread *thr) { + duk_small_int_t fun_idx = duk_get_current_magic(thr); + duk__two_arg_func fun; + duk_double_t arg1; + duk_double_t arg2; + + DUK_ASSERT(fun_idx >= 0); + DUK_ASSERT(fun_idx < (duk_small_int_t) (sizeof(duk__two_arg_funcs) / sizeof(duk__two_arg_func))); + arg1 = duk_to_number(thr, 0); /* explicit ordered evaluation to match coercion semantics */ + arg2 = duk_to_number(thr, 1); + fun = duk__two_arg_funcs[fun_idx]; + duk_push_number(thr, (duk_double_t) fun((double) arg1, (double) arg2)); + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_math_object_max(duk_hthread *thr) { + return duk__math_minmax(thr, -DUK_DOUBLE_INFINITY, duk__fmax_fixed); +} + +DUK_INTERNAL duk_ret_t duk_bi_math_object_min(duk_hthread *thr) { + return duk__math_minmax(thr, DUK_DOUBLE_INFINITY, duk__fmin_fixed); +} + +DUK_INTERNAL duk_ret_t duk_bi_math_object_random(duk_hthread *thr) { + duk_push_number(thr, (duk_double_t) DUK_UTIL_GET_RANDOM_DOUBLE(thr)); + return 1; +} + +#if defined(DUK_USE_ES6) +DUK_INTERNAL duk_ret_t duk_bi_math_object_hypot(duk_hthread *thr) { + /* + * E6 Section 20.2.2.18: Math.hypot + * + * - If no arguments are passed, the result is +0. + * - If any argument is +inf, the result is +inf. + * - If any argument is -inf, the result is +inf. + * - If no argument is +inf or -inf, and any argument is NaN, the result is + * NaN. + * - If all arguments are either +0 or -0, the result is +0. + */ + + duk_idx_t nargs; + duk_idx_t i; + duk_bool_t found_nan; + duk_double_t max; + duk_double_t sum, summand; + duk_double_t comp, prelim; + duk_double_t t; + + nargs = duk_get_top(thr); + + /* Find the highest value. Also ToNumber() coerces. */ + max = 0.0; + found_nan = 0; + for (i = 0; i < nargs; i++) { + t = DUK_FABS(duk_to_number(thr, i)); + if (DUK_FPCLASSIFY(t) == DUK_FP_NAN) { + found_nan = 1; + } else { + max = duk_double_fmax(max, t); + } + } + + /* Early return cases. */ + if (duk_double_equals(max, DUK_DOUBLE_INFINITY)) { + duk_push_number(thr, DUK_DOUBLE_INFINITY); + return 1; + } else if (found_nan) { + duk_push_number(thr, DUK_DOUBLE_NAN); + return 1; + } else if (duk_double_equals(max, 0.0)) { + duk_push_number(thr, 0.0); + /* Otherwise we'd divide by zero. */ + return 1; + } + + /* Use Kahan summation and normalize to the highest value to minimize + * floating point rounding error and avoid overflow. + * + * https://en.wikipedia.org/wiki/Kahan_summation_algorithm + */ + sum = 0.0; + comp = 0.0; + for (i = 0; i < nargs; i++) { + t = DUK_FABS(duk_get_number(thr, i)) / max; + summand = (t * t) - comp; + prelim = sum + summand; + comp = (prelim - sum) - summand; + sum = prelim; + } + + duk_push_number(thr, (duk_double_t) DUK_SQRT(sum) * max); + return 1; +} +#endif /* DUK_USE_ES6 */ + +#if defined(DUK_USE_ES6) +DUK_INTERNAL duk_ret_t duk_bi_math_object_sign(duk_hthread *thr) { + duk_double_t d; + + d = duk_to_number(thr, 0); + if (duk_double_is_nan(d)) { + DUK_ASSERT(duk_is_nan(thr, -1)); + return 1; /* NaN input -> return NaN */ + } + if (duk_double_equals(d, 0.0)) { + /* Zero sign kept, i.e. -0 -> -0, +0 -> +0. */ + return 1; + } + duk_push_int(thr, (d > 0.0 ? 1 : -1)); + return 1; +} +#endif /* DUK_USE_ES6 */ + +#if defined(DUK_USE_ES6) +DUK_INTERNAL duk_ret_t duk_bi_math_object_clz32(duk_hthread *thr) { + duk_uint32_t x; + duk_small_uint_t i; + +#if defined(DUK_USE_PREFER_SIZE) + duk_uint32_t mask; + + x = duk_to_uint32(thr, 0); + for (i = 0, mask = 0x80000000UL; mask != 0; mask >>= 1) { + if (x & mask) { + break; + } + i++; + } + DUK_ASSERT(i <= 32); + duk_push_uint(thr, i); + return 1; +#else /* DUK_USE_PREFER_SIZE */ + i = 0; + x = duk_to_uint32(thr, 0); + if (x & 0xffff0000UL) { + x >>= 16; + } else { + i += 16; + } + if (x & 0x0000ff00UL) { + x >>= 8; + } else { + i += 8; + } + if (x & 0x000000f0UL) { + x >>= 4; + } else { + i += 4; + } + if (x & 0x0000000cUL) { + x >>= 2; + } else { + i += 2; + } + if (x & 0x00000002UL) { + x >>= 1; + } else { + i += 1; + } + if (x & 0x00000001UL) { + ; + } else { + i += 1; + } + DUK_ASSERT(i <= 32); + duk_push_uint(thr, i); + return 1; +#endif /* DUK_USE_PREFER_SIZE */ +} +#endif /* DUK_USE_ES6 */ + +#if defined(DUK_USE_ES6) +DUK_INTERNAL duk_ret_t duk_bi_math_object_imul(duk_hthread *thr) { + duk_uint32_t x, y, z; + + x = duk_to_uint32(thr, 0); + y = duk_to_uint32(thr, 1); + z = x * y; + + /* While arguments are ToUint32() coerced and the multiplication + * is unsigned as such, the final result is curiously interpreted + * as a signed 32-bit value. + */ + duk_push_i32(thr, (duk_int32_t) z); + return 1; +} +#endif /* DUK_USE_ES6 */ + +#endif /* DUK_USE_MATH_BUILTIN */ diff --git a/third_party/duktape/duk_bi_number.c b/third_party/duktape/duk_bi_number.c new file mode 100644 index 00000000..a56e09ee --- /dev/null +++ b/third_party/duktape/duk_bi_number.c @@ -0,0 +1,280 @@ +/* + * Number built-ins + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_NUMBER_BUILTIN) + +DUK_LOCAL duk_double_t duk__push_this_number_plain(duk_hthread *thr) { + duk_hobject *h; + + /* Number built-in accepts a plain number or a Number object (whose + * internal value is operated on). Other types cause TypeError. + */ + + duk_push_this(thr); + if (duk_is_number(thr, -1)) { + DUK_DDD(DUK_DDDPRINT("plain number value: %!T", (duk_tval *) duk_get_tval(thr, -1))); + goto done; + } + h = duk_get_hobject(thr, -1); + if (!h || + (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_NUMBER)) { + DUK_DDD(DUK_DDDPRINT("unacceptable this value: %!T", (duk_tval *) duk_get_tval(thr, -1))); + DUK_ERROR_TYPE(thr, "number expected"); + DUK_WO_NORETURN(return 0.0;); + } + duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE); + DUK_ASSERT(duk_is_number(thr, -1)); + DUK_DDD(DUK_DDDPRINT("number object: %!T, internal value: %!T", + (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1))); + duk_remove_m2(thr); + + done: + return duk_get_number(thr, -1); +} + +DUK_INTERNAL duk_ret_t duk_bi_number_constructor(duk_hthread *thr) { + duk_idx_t nargs; + duk_hobject *h_this; + + /* + * The Number constructor uses ToNumber(arg) for number coercion + * (coercing an undefined argument to NaN). However, if the + * argument is not given at all, +0 must be used instead. To do + * this, a vararg function is used. + */ + + nargs = duk_get_top(thr); + if (nargs == 0) { + duk_push_int(thr, 0); + } + duk_to_number(thr, 0); + duk_set_top(thr, 1); + DUK_ASSERT_TOP(thr, 1); + + if (!duk_is_constructor_call(thr)) { + return 1; + } + + /* + * E5 Section 15.7.2.1 requires that the constructed object + * must have the original Number.prototype as its internal + * prototype. However, since Number.prototype is non-writable + * and non-configurable, this doesn't have to be enforced here: + * The default object (bound to 'this') is OK, though we have + * to change its class. + * + * Internal value set to ToNumber(arg) or +0; if no arg given, + * ToNumber(undefined) = NaN, so special treatment is needed + * (above). String internal value is immutable. + */ + + /* XXX: helper */ + duk_push_this(thr); + h_this = duk_known_hobject(thr, -1); + DUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_NUMBER); + + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_this) == thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE]); + DUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_this) == DUK_HOBJECT_CLASS_NUMBER); + DUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h_this)); + + duk_dup_0(thr); /* -> [ val obj val ] */ + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); + return 0; /* no return value -> don't replace created value */ +} + +DUK_INTERNAL duk_ret_t duk_bi_number_prototype_value_of(duk_hthread *thr) { + (void) duk__push_this_number_plain(thr); + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_string(duk_hthread *thr) { + duk_small_int_t radix; + duk_small_uint_t n2s_flags; + + (void) duk__push_this_number_plain(thr); + if (duk_is_undefined(thr, 0)) { + radix = 10; + } else { + radix = (duk_small_int_t) duk_to_int_check_range(thr, 0, 2, 36); + } + DUK_DDD(DUK_DDDPRINT("radix=%ld", (long) radix)); + + n2s_flags = 0; + + duk_numconv_stringify(thr, + radix /*radix*/, + 0 /*digits*/, + n2s_flags /*flags*/); + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_locale_string(duk_hthread *thr) { + /* XXX: just use toString() for now; permitted although not recommended. + * nargs==1, so radix is passed to toString(). + */ + return duk_bi_number_prototype_to_string(thr); +} + +/* + * toFixed(), toExponential(), toPrecision() + */ + +/* XXX: shared helper for toFixed(), toExponential(), toPrecision()? */ + +DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_fixed(duk_hthread *thr) { + duk_small_int_t frac_digits; + duk_double_t d; + duk_small_int_t c; + duk_small_uint_t n2s_flags; + + /* In ES5.1 frac_digits is coerced first; in ES2015 the 'this number + * value' check is done first. + */ + d = duk__push_this_number_plain(thr); + frac_digits = (duk_small_int_t) duk_to_int_check_range(thr, 0, 0, 20); + + c = (duk_small_int_t) DUK_FPCLASSIFY(d); + if (c == DUK_FP_NAN || c == DUK_FP_INFINITE) { + goto use_to_string; + } + + if (d >= 1.0e21 || d <= -1.0e21) { + goto use_to_string; + } + + n2s_flags = DUK_N2S_FLAG_FIXED_FORMAT | + DUK_N2S_FLAG_FRACTION_DIGITS; + + duk_numconv_stringify(thr, + 10 /*radix*/, + frac_digits /*digits*/, + n2s_flags /*flags*/); + return 1; + + use_to_string: + DUK_ASSERT_TOP(thr, 2); + duk_to_string(thr, -1); + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_exponential(duk_hthread *thr) { + duk_bool_t frac_undefined; + duk_small_int_t frac_digits; + duk_double_t d; + duk_small_int_t c; + duk_small_uint_t n2s_flags; + + d = duk__push_this_number_plain(thr); + + frac_undefined = duk_is_undefined(thr, 0); + duk_to_int(thr, 0); /* for side effects */ + + c = (duk_small_int_t) DUK_FPCLASSIFY(d); + if (c == DUK_FP_NAN || c == DUK_FP_INFINITE) { + goto use_to_string; + } + + frac_digits = (duk_small_int_t) duk_to_int_check_range(thr, 0, 0, 20); + + n2s_flags = DUK_N2S_FLAG_FORCE_EXP | + (frac_undefined ? 0 : DUK_N2S_FLAG_FIXED_FORMAT); + + duk_numconv_stringify(thr, + 10 /*radix*/, + frac_digits + 1 /*leading digit + fractions*/, + n2s_flags /*flags*/); + return 1; + + use_to_string: + DUK_ASSERT_TOP(thr, 2); + duk_to_string(thr, -1); + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_precision(duk_hthread *thr) { + /* The specification has quite awkward order of coercion and + * checks for toPrecision(). The operations below are a bit + * reordered, within constraints of observable side effects. + */ + + duk_double_t d; + duk_small_int_t prec; + duk_small_int_t c; + duk_small_uint_t n2s_flags; + + DUK_ASSERT_TOP(thr, 1); + + d = duk__push_this_number_plain(thr); + if (duk_is_undefined(thr, 0)) { + goto use_to_string; + } + DUK_ASSERT_TOP(thr, 2); + + duk_to_int(thr, 0); /* for side effects */ + + c = (duk_small_int_t) DUK_FPCLASSIFY(d); + if (c == DUK_FP_NAN || c == DUK_FP_INFINITE) { + goto use_to_string; + } + + prec = (duk_small_int_t) duk_to_int_check_range(thr, 0, 1, 21); + + n2s_flags = DUK_N2S_FLAG_FIXED_FORMAT | + DUK_N2S_FLAG_NO_ZERO_PAD; + + duk_numconv_stringify(thr, + 10 /*radix*/, + prec /*digits*/, + n2s_flags /*flags*/); + return 1; + + use_to_string: + /* Used when precision is undefined; also used for NaN (-> "NaN"), + * and +/- infinity (-> "Infinity", "-Infinity"). + */ + + DUK_ASSERT_TOP(thr, 2); + duk_to_string(thr, -1); + return 1; +} + +/* + * ES2015 isFinite() etc + */ + +#if defined(DUK_USE_ES6) +DUK_INTERNAL duk_ret_t duk_bi_number_check_shared(duk_hthread *thr) { + duk_int_t magic; + duk_bool_t ret = 0; + + if (duk_is_number(thr, 0)) { + duk_double_t d; + + magic = duk_get_current_magic(thr); + d = duk_get_number(thr, 0); + + switch (magic) { + case 0: /* isFinite() */ + ret = duk_double_is_finite(d); + break; + case 1: /* isInteger() */ + ret = duk_double_is_integer(d); + break; + case 2: /* isNaN() */ + ret = duk_double_is_nan(d); + break; + default: /* isSafeInteger() */ + DUK_ASSERT(magic == 3); + ret = duk_double_is_safe_integer(d); + } + } + + duk_push_boolean(thr, ret); + return 1; +} +#endif /* DUK_USE_ES6 */ + +#endif /* DUK_USE_NUMBER_BUILTIN */ diff --git a/third_party/duktape/duk_bi_object.c b/third_party/duktape/duk_bi_object.c new file mode 100644 index 00000000..4033cc8f --- /dev/null +++ b/third_party/duktape/duk_bi_object.c @@ -0,0 +1,803 @@ +/* + * Object built-ins + */ + +#include "third_party/duktape/duk_internal.h" + +/* Needed even when Object built-in disabled. */ +DUK_INTERNAL duk_ret_t duk_bi_object_prototype_to_string(duk_hthread *thr) { + duk_tval *tv; + + tv = DUK_HTHREAD_THIS_PTR(thr); + duk_push_class_string_tval(thr, tv, 0 /*avoid_side_effects*/); + return 1; +} + +#if defined(DUK_USE_OBJECT_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_object_constructor(duk_hthread *thr) { + duk_uint_t arg_mask; + + arg_mask = duk_get_type_mask(thr, 0); + + if (!duk_is_constructor_call(thr) && /* not a constructor call */ + ((arg_mask & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED)) == 0)) { /* and argument not null or undefined */ + duk_to_object(thr, 0); + return 1; + } + + /* Pointer and buffer primitive values are treated like other + * primitives values which have a fully fledged object counterpart: + * promote to an object value. Lightfuncs and plain buffers are + * coerced with ToObject() even they could also be returned as is. + */ + if (arg_mask & (DUK_TYPE_MASK_OBJECT | + DUK_TYPE_MASK_STRING | + DUK_TYPE_MASK_BOOLEAN | + DUK_TYPE_MASK_NUMBER | + DUK_TYPE_MASK_POINTER | + DUK_TYPE_MASK_BUFFER | + DUK_TYPE_MASK_LIGHTFUNC)) { + /* For DUK_TYPE_OBJECT the coercion is a no-op and could + * be checked for explicitly, but Object(obj) calls are + * not very common so opt for minimal footprint. + */ + duk_to_object(thr, 0); + return 1; + } + + (void) duk_push_object_helper(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT), + DUK_BIDX_OBJECT_PROTOTYPE); + return 1; +} +#endif /* DUK_USE_OBJECT_BUILTIN */ + +#if defined(DUK_USE_OBJECT_BUILTIN) && defined(DUK_USE_ES6) +DUK_INTERNAL duk_ret_t duk_bi_object_constructor_assign(duk_hthread *thr) { + duk_idx_t nargs; + duk_int_t idx; + + nargs = duk_get_top_require_min(thr, 1 /*min_top*/); + + duk_to_object(thr, 0); + for (idx = 1; idx < nargs; idx++) { + /* E7 19.1.2.1 (step 4a) */ + if (duk_is_null_or_undefined(thr, idx)) { + continue; + } + + /* duk_enum() respects ES2015+ [[OwnPropertyKeys]] ordering, which is + * convenient here. + */ + duk_to_object(thr, idx); + duk_enum(thr, idx, DUK_ENUM_OWN_PROPERTIES_ONLY); + while (duk_next(thr, -1, 1 /*get_value*/)) { + /* [ target ... enum key value ] */ + duk_put_prop(thr, 0); + /* [ target ... enum ] */ + } + /* Could pop enumerator, but unnecessary because of duk_set_top() + * below. + */ + } + + duk_set_top(thr, 1); + return 1; +} +#endif + +#if defined(DUK_USE_OBJECT_BUILTIN) && defined(DUK_USE_ES6) +DUK_INTERNAL duk_ret_t duk_bi_object_constructor_is(duk_hthread *thr) { + DUK_ASSERT_TOP(thr, 2); + duk_push_boolean(thr, duk_samevalue(thr, 0, 1)); + return 1; +} +#endif + +#if defined(DUK_USE_OBJECT_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_object_constructor_create(duk_hthread *thr) { + duk_hobject *proto; + + DUK_ASSERT_TOP(thr, 2); + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + duk_hbufobj_promote_plain(thr, 0); +#endif + proto = duk_require_hobject_accept_mask(thr, 0, DUK_TYPE_MASK_NULL); + DUK_ASSERT(proto != NULL || duk_is_null(thr, 0)); + + (void) duk_push_object_helper_proto(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT), + proto); + + if (!duk_is_undefined(thr, 1)) { + /* [ O Properties obj ] */ + + duk_replace(thr, 0); + + /* [ obj Properties ] */ + + /* Just call the "original" Object.defineProperties() to + * finish up. + */ + + return duk_bi_object_constructor_define_properties(thr); + } + + /* [ O Properties obj ] */ + + return 1; +} +#endif /* DUK_USE_OBJECT_BUILTIN */ + +#if defined(DUK_USE_OBJECT_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_properties(duk_hthread *thr) { + duk_small_uint_t pass_; + duk_uint_t defprop_flags; + duk_hobject *obj; + duk_idx_t idx_value; + duk_hobject *get; + duk_hobject *set; + + /* Lightfunc and plain buffer handling by ToObject() coercion. */ + obj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER); + DUK_ASSERT(obj != NULL); + + duk_to_object(thr, 1); /* properties object */ + + DUK_DDD(DUK_DDDPRINT("target=%!iT, properties=%!iT", + (duk_tval *) duk_get_tval(thr, 0), + (duk_tval *) duk_get_tval(thr, 1))); + + /* + * Two pass_ approach to processing the property descriptors. + * On first pass_ validate and normalize all descriptors before + * any changes are made to the target object. On second pass_ + * make the actual modifications to the target object. + * + * Right now we'll just use the same normalize/validate helper + * on both passes, ignoring its outputs on the first pass_. + */ + + for (pass_ = 0; pass_ < 2; pass_++) { + duk_set_top(thr, 2); /* -> [ hobject props ] */ + duk_enum(thr, 1, DUK_ENUM_OWN_PROPERTIES_ONLY | DUK_ENUM_INCLUDE_SYMBOLS /*enum_flags*/); + + for (;;) { + duk_hstring *key; + + /* [ hobject props enum(props) ] */ + + duk_set_top(thr, 3); + + if (!duk_next(thr, 2, 1 /*get_value*/)) { + break; + } + + DUK_DDD(DUK_DDDPRINT("-> key=%!iT, desc=%!iT", + (duk_tval *) duk_get_tval(thr, -2), + (duk_tval *) duk_get_tval(thr, -1))); + + /* [ hobject props enum(props) key desc ] */ + + duk_hobject_prepare_property_descriptor(thr, + 4 /*idx_desc*/, + &defprop_flags, + &idx_value, + &get, + &set); + + /* [ hobject props enum(props) key desc [multiple values] ] */ + + if (pass_ == 0) { + continue; + } + + /* This allows symbols on purpose. */ + key = duk_known_hstring(thr, 3); + DUK_ASSERT(key != NULL); + + duk_hobject_define_property_helper(thr, + defprop_flags, + obj, + key, + idx_value, + get, + set, + 1 /*throw_flag*/); + } + } + + /* + * Return target object + */ + + duk_dup_0(thr); + return 1; +} +#endif /* DUK_USE_OBJECT_BUILTIN */ + +#if defined(DUK_USE_OBJECT_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_object_constructor_seal_freeze_shared(duk_hthread *thr) { + DUK_ASSERT_TOP(thr, 1); + + duk_seal_freeze_raw(thr, 0, (duk_bool_t) duk_get_current_magic(thr) /*is_freeze*/); + return 1; +} +#endif /* DUK_USE_OBJECT_BUILTIN */ + +#if defined(DUK_USE_OBJECT_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_sealed_frozen_shared(duk_hthread *thr) { + duk_hobject *h; + duk_bool_t is_frozen; + duk_uint_t mask; + + is_frozen = (duk_bool_t) duk_get_current_magic(thr); + mask = duk_get_type_mask(thr, 0); + if (mask & (DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER)) { + DUK_ASSERT(is_frozen == 0 || is_frozen == 1); + duk_push_boolean(thr, (mask & DUK_TYPE_MASK_LIGHTFUNC) ? + 1 : /* lightfunc always frozen and sealed */ + (is_frozen ^ 1)); /* buffer sealed but not frozen (index props writable) */ + } else { + /* ES2015 Sections 19.1.2.12, 19.1.2.13: anything other than an object + * is considered to be already sealed and frozen. + */ + h = duk_get_hobject(thr, 0); + duk_push_boolean(thr, (h == NULL) || + duk_hobject_object_is_sealed_frozen_helper(thr, h, is_frozen /*is_frozen*/)); + } + return 1; +} +#endif /* DUK_USE_OBJECT_BUILTIN */ + +#if defined(DUK_USE_OBJECT_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_object_prototype_to_locale_string(duk_hthread *thr) { + DUK_ASSERT_TOP(thr, 0); + (void) duk_push_this_coercible_to_object(thr); + duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_TO_STRING); +#if 0 /* This is mentioned explicitly in the E5.1 spec, but duk_call_method() checks for it in practice. */ + duk_require_callable(thr, 1); +#endif + duk_dup_0(thr); /* -> [ O toString O ] */ + duk_call_method(thr, 0); /* XXX: call method tail call? */ + return 1; +} +#endif /* DUK_USE_OBJECT_BUILTIN */ + +#if defined(DUK_USE_OBJECT_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_object_prototype_value_of(duk_hthread *thr) { + /* For lightfuncs and plain buffers, returns Object() coerced. */ + (void) duk_push_this_coercible_to_object(thr); + return 1; +} +#endif /* DUK_USE_OBJECT_BUILTIN */ + +#if defined(DUK_USE_OBJECT_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_object_prototype_is_prototype_of(duk_hthread *thr) { + duk_hobject *h_v; + duk_hobject *h_obj; + + DUK_ASSERT_TOP(thr, 1); + + h_v = duk_get_hobject(thr, 0); + if (!h_v) { + duk_push_false(thr); /* XXX: tail call: return duk_push_false(thr) */ + return 1; + } + + h_obj = duk_push_this_coercible_to_object(thr); + DUK_ASSERT(h_obj != NULL); + + /* E5.1 Section 15.2.4.6, step 3.a, lookup proto once before compare. + * Prototype loops should cause an error to be thrown. + */ + duk_push_boolean(thr, duk_hobject_prototype_chain_contains(thr, DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_v), h_obj, 0 /*ignore_loop*/)); + return 1; +} +#endif /* DUK_USE_OBJECT_BUILTIN */ + +#if defined(DUK_USE_OBJECT_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_object_prototype_has_own_property(duk_hthread *thr) { + return (duk_ret_t) duk_hobject_object_ownprop_helper(thr, 0 /*required_desc_flags*/); +} +#endif /* DUK_USE_OBJECT_BUILTIN */ + +#if defined(DUK_USE_OBJECT_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_object_prototype_property_is_enumerable(duk_hthread *thr) { + return (duk_ret_t) duk_hobject_object_ownprop_helper(thr, DUK_PROPDESC_FLAG_ENUMERABLE /*required_desc_flags*/); +} +#endif /* DUK_USE_OBJECT_BUILTIN */ + +#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN) +/* Shared helper to implement Object.getPrototypeOf, + * Object.prototype.__proto__ getter, and Reflect.getPrototypeOf. + * + * http://www.ecma-international.org/ecma-262/6.0/index.html#sec-get-object.prototype.__proto__ + */ +DUK_INTERNAL duk_ret_t duk_bi_object_getprototype_shared(duk_hthread *thr) { + /* + * magic = 0: __proto__ getter + * magic = 1: Object.getPrototypeOf() + * magic = 2: Reflect.getPrototypeOf() + */ + + duk_hobject *h; + duk_hobject *proto; + duk_tval *tv; + duk_int_t magic; + + magic = duk_get_current_magic(thr); + + if (magic == 0) { + DUK_ASSERT_TOP(thr, 0); + duk_push_this_coercible_to_object(thr); + } + DUK_ASSERT(duk_get_top(thr) >= 1); + if (magic < 2) { + /* ES2015 Section 19.1.2.9, step 1 */ + duk_to_object(thr, 0); + } + tv = DUK_GET_TVAL_POSIDX(thr, 0); + + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_BUFFER: + proto = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE]; + break; + case DUK_TAG_LIGHTFUNC: + proto = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]; + break; + case DUK_TAG_OBJECT: + h = DUK_TVAL_GET_OBJECT(tv); + proto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h); + break; + default: + /* This implicitly handles CheckObjectCoercible() caused + * TypeError. + */ + DUK_DCERROR_TYPE_INVALID_ARGS(thr); + } + if (proto != NULL) { + duk_push_hobject(thr, proto); + } else { + duk_push_null(thr); + } + return 1; +} +#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */ + +#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN) +/* Shared helper to implement ES2015 Object.setPrototypeOf, + * Object.prototype.__proto__ setter, and Reflect.setPrototypeOf. + * + * http://www.ecma-international.org/ecma-262/6.0/index.html#sec-get-object.prototype.__proto__ + * http://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.setprototypeof + */ +DUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_hthread *thr) { + /* + * magic = 0: __proto__ setter + * magic = 1: Object.setPrototypeOf() + * magic = 2: Reflect.setPrototypeOf() + */ + + duk_hobject *h_obj; + duk_hobject *h_new_proto; + duk_hobject *h_curr; + duk_ret_t ret_success = 1; /* retval for success path */ + duk_uint_t mask; + duk_int_t magic; + + /* Preliminaries for __proto__ and setPrototypeOf (E6 19.1.2.18 steps 1-4). */ + magic = duk_get_current_magic(thr); + if (magic == 0) { + duk_push_this_check_object_coercible(thr); + duk_insert(thr, 0); + if (!duk_check_type_mask(thr, 1, DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_OBJECT)) { + return 0; + } + + /* __proto__ setter returns 'undefined' on success unlike the + * setPrototypeOf() call which returns the target object. + */ + ret_success = 0; + } else { + if (magic == 1) { + duk_require_object_coercible(thr, 0); + } else { + duk_require_hobject_accept_mask(thr, 0, + DUK_TYPE_MASK_LIGHTFUNC | + DUK_TYPE_MASK_BUFFER); + } + duk_require_type_mask(thr, 1, DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_OBJECT); + } + + h_new_proto = duk_get_hobject(thr, 1); + /* h_new_proto may be NULL */ + + mask = duk_get_type_mask(thr, 0); + if (mask & (DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER)) { + duk_hobject *curr_proto; + curr_proto = thr->builtins[(mask & DUK_TYPE_MASK_LIGHTFUNC) ? + DUK_BIDX_FUNCTION_PROTOTYPE : + DUK_BIDX_UINT8ARRAY_PROTOTYPE]; + if (h_new_proto == curr_proto) { + goto skip; + } + goto fail_nonextensible; + } + h_obj = duk_get_hobject(thr, 0); + if (h_obj == NULL) { + goto skip; + } + DUK_ASSERT(h_obj != NULL); + + /* [[SetPrototypeOf]] standard behavior, E6 9.1.2. */ + /* TODO: implement Proxy object support here */ + + if (h_new_proto == DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_obj)) { + goto skip; + } + if (!DUK_HOBJECT_HAS_EXTENSIBLE(h_obj)) { + goto fail_nonextensible; + } + for (h_curr = h_new_proto; h_curr != NULL; h_curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_curr)) { + /* Loop prevention. */ + if (h_curr == h_obj) { + goto fail_loop; + } + } + DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h_obj, h_new_proto); + /* fall thru */ + + skip: + duk_set_top(thr, 1); + if (magic == 2) { + duk_push_true(thr); + } + return ret_success; + + fail_nonextensible: + fail_loop: + if (magic != 2) { + DUK_DCERROR_TYPE_INVALID_ARGS(thr); + } else { + duk_push_false(thr); + return 1; + } +} +#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */ + +#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_property(duk_hthread *thr) { + /* + * magic = 0: Object.defineProperty() + * magic = 1: Reflect.defineProperty() + */ + + duk_hobject *obj; + duk_hstring *key; + duk_hobject *get; + duk_hobject *set; + duk_idx_t idx_value; + duk_uint_t defprop_flags; + duk_small_uint_t magic; + duk_bool_t throw_flag; + duk_bool_t ret; + + DUK_ASSERT(thr != NULL); + + DUK_DDD(DUK_DDDPRINT("Object.defineProperty(): ctx=%p obj=%!T key=%!T desc=%!T", + (void *) thr, + (duk_tval *) duk_get_tval(thr, 0), + (duk_tval *) duk_get_tval(thr, 1), + (duk_tval *) duk_get_tval(thr, 2))); + + /* [ obj key desc ] */ + + magic = (duk_small_uint_t) duk_get_current_magic(thr); + + /* Lightfuncs are currently supported by coercing to a temporary + * Function object; changes will be allowed (the coerced value is + * extensible) but will be lost. Same for plain buffers. + */ + obj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER); + DUK_ASSERT(obj != NULL); + key = duk_to_property_key_hstring(thr, 1); + (void) duk_require_hobject(thr, 2); + + DUK_ASSERT(obj != NULL); + DUK_ASSERT(key != NULL); + DUK_ASSERT(duk_get_hobject(thr, 2) != NULL); + + /* + * Validate and convert argument property descriptor (an ECMAScript + * object) into a set of defprop_flags and possibly property value, + * getter, and/or setter values on the value stack. + * + * Lightfunc set/get values are coerced to full Functions. + */ + + duk_hobject_prepare_property_descriptor(thr, + 2 /*idx_desc*/, + &defprop_flags, + &idx_value, + &get, + &set); + + /* + * Use Object.defineProperty() helper for the actual operation. + */ + + DUK_ASSERT(magic == 0U || magic == 1U); + throw_flag = magic ^ 1U; + ret = duk_hobject_define_property_helper(thr, + defprop_flags, + obj, + key, + idx_value, + get, + set, + throw_flag); + + /* Ignore the normalize/validate helper outputs on the value stack, + * they're popped automatically. + */ + + if (magic == 0U) { + /* Object.defineProperty(): return target object. */ + duk_push_hobject(thr, obj); + } else { + /* Reflect.defineProperty(): return success/fail. */ + duk_push_boolean(thr, ret); + } + return 1; +} +#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */ + +#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_object_constructor_get_own_property_descriptor(duk_hthread *thr) { + DUK_ASSERT_TOP(thr, 2); + + /* ES2015 Section 19.1.2.6, step 1 */ + if (duk_get_current_magic(thr) == 0) { + duk_to_object(thr, 0); + } + + /* [ obj key ] */ + + duk_hobject_object_get_own_property_descriptor(thr, -2); + return 1; +} +#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */ + +#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_extensible(duk_hthread *thr) { + /* + * magic = 0: Object.isExtensible() + * magic = 1: Reflect.isExtensible() + */ + + duk_hobject *h; + + if (duk_get_current_magic(thr) == 0) { + h = duk_get_hobject(thr, 0); + } else { + /* Reflect.isExtensible(): throw if non-object, but we accept lightfuncs + * and plain buffers here because they pretend to be objects. + */ + h = duk_require_hobject_accept_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER); + } + + duk_push_boolean(thr, (h != NULL) && DUK_HOBJECT_HAS_EXTENSIBLE(h)); + return 1; +} +#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */ + +#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN) +/* Shared helper for various key/symbol listings, magic: + * 0=Object.keys() + * 1=Object.getOwnPropertyNames(), + * 2=Object.getOwnPropertySymbols(), + * 3=Reflect.ownKeys() + */ +DUK_LOCAL const duk_small_uint_t duk__object_keys_enum_flags[4] = { + /* Object.keys() */ + DUK_ENUM_OWN_PROPERTIES_ONLY | + DUK_ENUM_NO_PROXY_BEHAVIOR, + + /* Object.getOwnPropertyNames() */ + DUK_ENUM_INCLUDE_NONENUMERABLE | + DUK_ENUM_OWN_PROPERTIES_ONLY | + DUK_ENUM_NO_PROXY_BEHAVIOR, + + /* Object.getOwnPropertySymbols() */ + DUK_ENUM_INCLUDE_SYMBOLS | + DUK_ENUM_OWN_PROPERTIES_ONLY | + DUK_ENUM_EXCLUDE_STRINGS | + DUK_ENUM_INCLUDE_NONENUMERABLE | + DUK_ENUM_NO_PROXY_BEHAVIOR, + + /* Reflect.ownKeys() */ + DUK_ENUM_INCLUDE_SYMBOLS | + DUK_ENUM_OWN_PROPERTIES_ONLY | + DUK_ENUM_INCLUDE_NONENUMERABLE | + DUK_ENUM_NO_PROXY_BEHAVIOR +}; + +DUK_INTERNAL duk_ret_t duk_bi_object_constructor_keys_shared(duk_hthread *thr) { + duk_hobject *obj; +#if defined(DUK_USE_ES6_PROXY) + duk_hobject *h_proxy_target; + duk_hobject *h_proxy_handler; + duk_hobject *h_trap_result; +#endif + duk_small_uint_t enum_flags; + duk_int_t magic; + + DUK_ASSERT_TOP(thr, 1); + + magic = duk_get_current_magic(thr); + if (magic == 3) { + /* ES2015 Section 26.1.11 requires a TypeError for non-objects. Lightfuncs + * and plain buffers pretend to be objects, so accept those too. + */ + obj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER); + } else { + /* ES2015: ToObject coerce. */ + obj = duk_to_hobject(thr, 0); + } + DUK_ASSERT(obj != NULL); + DUK_UNREF(obj); + + /* XXX: proxy chains */ + +#if defined(DUK_USE_ES6_PROXY) + /* XXX: better sharing of code between proxy target call sites */ + if (DUK_LIKELY(!duk_hobject_proxy_check(obj, + &h_proxy_target, + &h_proxy_handler))) { + goto skip_proxy; + } + + duk_push_hobject(thr, h_proxy_handler); + if (!duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_OWN_KEYS)) { + /* Careful with reachability here: don't pop 'obj' before pushing + * proxy target. + */ + DUK_DDD(DUK_DDDPRINT("no ownKeys trap, get keys of target instead")); + duk_pop_2(thr); + duk_push_hobject(thr, h_proxy_target); + duk_replace(thr, 0); + DUK_ASSERT_TOP(thr, 1); + goto skip_proxy; + } + + /* [ obj handler trap ] */ + duk_insert(thr, -2); + duk_push_hobject(thr, h_proxy_target); /* -> [ obj trap handler target ] */ + duk_call_method(thr, 1 /*nargs*/); /* -> [ obj trap_result ] */ + h_trap_result = duk_require_hobject(thr, -1); + DUK_UNREF(h_trap_result); + + magic = duk_get_current_magic(thr); + DUK_ASSERT(magic >= 0 && magic < (duk_int_t) (sizeof(duk__object_keys_enum_flags) / sizeof(duk_small_uint_t))); + enum_flags = duk__object_keys_enum_flags[magic]; + + duk_proxy_ownkeys_postprocess(thr, h_proxy_target, enum_flags); + return 1; + + skip_proxy: +#endif /* DUK_USE_ES6_PROXY */ + + DUK_ASSERT_TOP(thr, 1); + magic = duk_get_current_magic(thr); + DUK_ASSERT(magic >= 0 && magic < (duk_int_t) (sizeof(duk__object_keys_enum_flags) / sizeof(duk_small_uint_t))); + enum_flags = duk__object_keys_enum_flags[magic]; + return duk_hobject_get_enumerated_keys(thr, enum_flags); +} +#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */ + +#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_hthread *thr) { + /* + * magic = 0: Object.preventExtensions() + * magic = 1: Reflect.preventExtensions() + */ + + duk_hobject *h; + duk_uint_t mask; + duk_int_t magic; + + magic = duk_get_current_magic(thr); + + /* Silent success for lightfuncs and plain buffers always. */ + mask = DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER; + + /* Object.preventExtensions() silent success for non-object. */ + if (magic == 0) { + mask |= DUK_TYPE_MASK_UNDEFINED | + DUK_TYPE_MASK_NULL | + DUK_TYPE_MASK_BOOLEAN | + DUK_TYPE_MASK_NUMBER | + DUK_TYPE_MASK_STRING | + DUK_TYPE_MASK_POINTER; + } + + if (duk_check_type_mask(thr, 0, mask)) { + /* Not an object, already non-extensible so always success. */ + goto done; + } + h = duk_require_hobject(thr, 0); + DUK_ASSERT(h != NULL); + + DUK_HOBJECT_CLEAR_EXTENSIBLE(h); + + /* A non-extensible object cannot gain any more properties, + * so this is a good time to compact. + */ + duk_hobject_compact_props(thr, h); + + done: + if (magic == 1) { + duk_push_true(thr); + } + return 1; +} +#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */ + +/* + * __defineGetter__, __defineSetter__, __lookupGetter__, __lookupSetter__ + */ + +#if defined(DUK_USE_ES8) +DUK_INTERNAL duk_ret_t duk_bi_object_prototype_defineaccessor(duk_hthread *thr) { + duk_push_this(thr); + duk_insert(thr, 0); + duk_to_object(thr, 0); + duk_require_callable(thr, 2); + + /* [ ToObject(this) key getter/setter ] */ + + /* ToPropertyKey() coercion is not needed, duk_def_prop() does it. */ + duk_def_prop(thr, 0, DUK_DEFPROP_SET_ENUMERABLE | + DUK_DEFPROP_SET_CONFIGURABLE | + (duk_get_current_magic(thr) ? DUK_DEFPROP_HAVE_SETTER : DUK_DEFPROP_HAVE_GETTER)); + return 0; +} +DUK_INTERNAL duk_ret_t duk_bi_object_prototype_lookupaccessor(duk_hthread *thr) { + duk_uint_t sanity; + + duk_push_this(thr); + duk_to_object(thr, -1); + + /* XXX: Prototype walk (with sanity) should be a core property + * operation, could add a flag to e.g. duk_get_prop_desc(). + */ + + /* ToPropertyKey() coercion is not needed, duk_get_prop_desc() does it. */ + sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY; + while (!duk_is_undefined(thr, -1)) { + /* [ key obj ] */ + duk_dup(thr, 0); + duk_get_prop_desc(thr, 1, 0 /*flags*/); + if (!duk_is_undefined(thr, -1)) { + duk_get_prop_stridx(thr, -1, (duk_get_current_magic(thr) != 0 ? DUK_STRIDX_SET : DUK_STRIDX_GET)); + return 1; + } + duk_pop(thr); + + if (DUK_UNLIKELY(sanity-- == 0)) { + DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT); + DUK_WO_NORETURN(return 0;); + } + + duk_get_prototype(thr, -1); + duk_remove(thr, -2); + } + return 1; +} +#endif /* DUK_USE_ES8 */ diff --git a/third_party/duktape/duk_bi_performance.c b/third_party/duktape/duk_bi_performance.c new file mode 100644 index 00000000..77dc24d1 --- /dev/null +++ b/third_party/duktape/duk_bi_performance.c @@ -0,0 +1,31 @@ +/* + * High resolution time API (performance.now() et al) + * + * API specification: https://encoding.spec.whatwg.org/#ap://www.w3.org/TR/hr-time/ + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_PERFORMANCE_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_performance_now(duk_hthread *thr) { + /* From API spec: + * The DOMHighResTimeStamp type is used to store a time value in + * milliseconds, measured relative from the time origin, global + * monotonic clock, or a time value that represents a duration + * between two DOMHighResTimeStamp's. + */ + duk_push_number(thr, duk_time_get_monotonic_time(thr)); + return 1; +} + +#if 0 /* Missing until semantics decided. */ +DUK_INTERNAL duk_ret_t duk_bi_performance_timeorigin_getter(duk_hthread *thr) { + /* No decision yet how to handle timeOrigins, e.g. should one be + * initialized per heap, or per global object set. See + * https://www.w3.org/TR/hr-time/#time-origin. + */ + duk_push_uint(thr, 0); + return 1; +} +#endif /* 0 */ +#endif /* DUK_USE_PERFORMANCE_BUILTIN */ diff --git a/third_party/duktape/duk_bi_pointer.c b/third_party/duktape/duk_bi_pointer.c new file mode 100644 index 00000000..9e799ac4 --- /dev/null +++ b/third_party/duktape/duk_bi_pointer.c @@ -0,0 +1,75 @@ +/* + * Pointer built-ins + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Constructor + */ + +DUK_INTERNAL duk_ret_t duk_bi_pointer_constructor(duk_hthread *thr) { + /* XXX: this behavior is quite useless now; it would be nice to be able + * to create pointer values from e.g. numbers or strings. Numbers are + * problematic on 64-bit platforms though. Hex encoded strings? + */ + if (duk_get_top(thr) == 0) { + duk_push_pointer(thr, NULL); + } else { + duk_to_pointer(thr, 0); + } + DUK_ASSERT(duk_is_pointer(thr, 0)); + duk_set_top(thr, 1); + + if (duk_is_constructor_call(thr)) { + (void) duk_push_object_helper(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_POINTER), + DUK_BIDX_POINTER_PROTOTYPE); + + /* Pointer object internal value is immutable. */ + duk_dup_0(thr); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); + } + /* Note: unbalanced stack on purpose */ + + return 1; +} + +/* + * toString(), valueOf() + */ + +DUK_INTERNAL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_hthread *thr) { + duk_tval *tv; + duk_small_int_t to_string = duk_get_current_magic(thr); + + duk_push_this(thr); + tv = duk_require_tval(thr, -1); + DUK_ASSERT(tv != NULL); + + if (DUK_TVAL_IS_POINTER(tv)) { + /* nop */ + } else if (DUK_TVAL_IS_OBJECT(tv)) { + duk_hobject *h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + + /* Must be a "pointer object", i.e. class "Pointer" */ + if (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_POINTER) { + goto type_error; + } + + duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE); + } else { + goto type_error; + } + + if (to_string) { + duk_to_string(thr, -1); + } + return 1; + + type_error: + DUK_DCERROR_TYPE_INVALID_ARGS(thr); +} diff --git a/third_party/duktape/duk_bi_promise.c b/third_party/duktape/duk_bi_promise.c new file mode 100644 index 00000000..ed4d0938 --- /dev/null +++ b/third_party/duktape/duk_bi_promise.c @@ -0,0 +1,44 @@ +/* + * Promise built-in + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_PROMISE_BUILTIN) + +DUK_INTERNAL duk_ret_t duk_bi_promise_constructor(duk_hthread *thr) { + DUK_ERROR_TYPE(thr, "unimplemented"); + DUK_WO_NORETURN(return 0;); +} + +DUK_INTERNAL duk_ret_t duk_bi_promise_all(duk_hthread *thr) { + DUK_ERROR_TYPE(thr, "unimplemented"); + DUK_WO_NORETURN(return 0;); +} + +DUK_INTERNAL duk_ret_t duk_bi_promise_race(duk_hthread *thr) { + DUK_ERROR_TYPE(thr, "unimplemented"); + DUK_WO_NORETURN(return 0;); +} + +DUK_INTERNAL duk_ret_t duk_bi_promise_reject(duk_hthread *thr) { + DUK_ERROR_TYPE(thr, "unimplemented"); + DUK_WO_NORETURN(return 0;); +} + +DUK_INTERNAL duk_ret_t duk_bi_promise_resolve(duk_hthread *thr) { + DUK_ERROR_TYPE(thr, "unimplemented"); + DUK_WO_NORETURN(return 0;); +} + +DUK_INTERNAL duk_ret_t duk_bi_promise_catch(duk_hthread *thr) { + DUK_ERROR_TYPE(thr, "unimplemented"); + DUK_WO_NORETURN(return 0;); +} + +DUK_INTERNAL duk_ret_t duk_bi_promise_then(duk_hthread *thr) { + DUK_ERROR_TYPE(thr, "unimplemented"); + DUK_WO_NORETURN(return 0;); +} + +#endif /* DUK_USE_PROMISE_BUILTIN */ diff --git a/third_party/duktape/duk_bi_protos.h b/third_party/duktape/duk_bi_protos.h new file mode 100644 index 00000000..7c1488d4 --- /dev/null +++ b/third_party/duktape/duk_bi_protos.h @@ -0,0 +1,81 @@ +/* + * Prototypes for built-in functions not automatically covered by the + * header declarations emitted by genbuiltins.py. + */ + +#if !defined(DUK_BUILTIN_PROTOS_H_INCLUDED) +#define DUK_BUILTIN_PROTOS_H_INCLUDED + +/* Buffer size needed for ISO 8601 formatting. + * Accurate value is 32 + 1 for NUL termination: + * >>> len('+123456-01-23T12:34:56.123+12:34') + * 32 + * Include additional space to be safe. + */ +#define DUK_BI_DATE_ISO8601_BUFSIZE 40 + +/* Helpers exposed for internal use */ +DUK_INTERNAL_DECL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts, duk_double_t *dparts, duk_small_uint_t flags); +DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_timeval_from_dparts(duk_double_t *dparts, duk_small_uint_t flags); +DUK_INTERNAL_DECL duk_bool_t duk_bi_date_is_leap_year(duk_int_t year); +DUK_INTERNAL_DECL duk_bool_t duk_bi_date_timeval_in_valid_range(duk_double_t x); +DUK_INTERNAL_DECL duk_bool_t duk_bi_date_year_in_valid_range(duk_double_t year); +DUK_INTERNAL_DECL duk_bool_t duk_bi_date_timeval_in_leeway_range(duk_double_t x); +/* Built-in providers */ +#if defined(DUK_USE_DATE_NOW_GETTIMEOFDAY) +DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_gettimeofday(void); +#endif +#if defined(DUK_USE_DATE_NOW_TIME) +DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_time(void); +#endif +#if defined(DUK_USE_DATE_NOW_WINDOWS) +DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_windows(void); +#endif +#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS) +DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_windows_subms(void); +#endif +#if defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME_S) || defined(DUK_USE_DATE_TZO_GMTIME) +DUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d); +#endif +#if defined(DUK_USE_DATE_TZO_WINDOWS) +DUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d); +#endif +#if defined(DUK_USE_DATE_TZO_WINDOWS_NO_DST) +DUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_double_t d); +#endif +#if defined(DUK_USE_DATE_PRS_STRPTIME) +DUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_strptime(duk_hthread *thr, const char *str); +#endif +#if defined(DUK_USE_DATE_PRS_GETDATE) +DUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_getdate(duk_hthread *thr, const char *str); +#endif +#if defined(DUK_USE_DATE_FMT_STRFTIME) +DUK_INTERNAL_DECL duk_bool_t duk_bi_date_format_parts_strftime(duk_hthread *thr, duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags); +#endif + +#if defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME) +DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_monotonic_time_clock_gettime(void); +#endif +#if defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC) +DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_monotonic_time_windows_qpc(void); +#endif + +DUK_INTERNAL_DECL +void duk_bi_json_parse_helper(duk_hthread *thr, + duk_idx_t idx_value, + duk_idx_t idx_reviver, + duk_small_uint_t flags); +DUK_INTERNAL_DECL +void duk_bi_json_stringify_helper(duk_hthread *thr, + duk_idx_t idx_value, + duk_idx_t idx_replacer, + duk_idx_t idx_space, + duk_small_uint_t flags); + +DUK_INTERNAL_DECL duk_ret_t duk_textdecoder_decode_utf8_nodejs(duk_hthread *thr); + +#if defined(DUK_USE_ES6_PROXY) +DUK_INTERNAL_DECL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h_proxy_target, duk_uint_t flags); +#endif + +#endif /* DUK_BUILTIN_PROTOS_H_INCLUDED */ diff --git a/third_party/duktape/duk_bi_proxy.c b/third_party/duktape/duk_bi_proxy.c new file mode 100644 index 00000000..349d4de0 --- /dev/null +++ b/third_party/duktape/duk_bi_proxy.c @@ -0,0 +1,96 @@ +/* + * Proxy built-in (ES2015) + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_ES6_PROXY) +/* Post-process a Proxy ownKeys() result at stack top. Push a cleaned up + * array of valid result keys (strings or symbols). TypeError for invalid + * values. Flags are shared with duk_enum(). + */ +DUK_INTERNAL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h_proxy_target, duk_uint_t flags) { + duk_uarridx_t i, len, idx; + duk_propdesc desc; + + DUK_CTX_ASSERT_VALID(thr); + DUK_ASSERT(h_proxy_target != NULL); + + len = (duk_uarridx_t) duk_get_length(thr, -1); + idx = 0; + duk_push_array(thr); + /* XXX: preallocated dense array, fill in directly */ + for (i = 0; i < len; i++) { + duk_hstring *h; + + /* [ obj trap_result res_arr ] */ + (void) duk_get_prop_index(thr, -2, i); + h = duk_get_hstring(thr, -1); + if (h == NULL) { + DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr); + DUK_WO_NORETURN(return;); + } + + if (!(flags & DUK_ENUM_INCLUDE_NONENUMERABLE)) { + /* No support for 'getOwnPropertyDescriptor' trap yet, + * so check enumerability always from target object + * descriptor. + */ + if (duk_hobject_get_own_propdesc(thr, h_proxy_target, duk_known_hstring(thr, -1), &desc, 0 /*flags*/)) { + if ((desc.flags & DUK_PROPDESC_FLAG_ENUMERABLE) == 0) { + DUK_DDD(DUK_DDDPRINT("ignore non-enumerable property: %!T", duk_get_tval(thr, -1))); + goto skip_key; + } + } else { + DUK_DDD(DUK_DDDPRINT("ignore non-existent property: %!T", duk_get_tval(thr, -1))); + goto skip_key; + } + } + if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) { + if (!(flags & DUK_ENUM_INCLUDE_SYMBOLS)) { + DUK_DDD(DUK_DDDPRINT("ignore symbol property: %!T", duk_get_tval(thr, -1))); + goto skip_key; + } + if (DUK_HSTRING_HAS_HIDDEN(h) && !(flags & DUK_ENUM_INCLUDE_HIDDEN)) { + DUK_DDD(DUK_DDDPRINT("ignore hidden symbol property: %!T", duk_get_tval(thr, -1))); + goto skip_key; + } + } else { + if (flags & DUK_ENUM_EXCLUDE_STRINGS) { + DUK_DDD(DUK_DDDPRINT("ignore string property: %!T", duk_get_tval(thr, -1))); + goto skip_key; + } + } + + /* [ obj trap_result res_arr propname ] */ + duk_put_prop_index(thr, -2, idx++); + continue; + + skip_key: + duk_pop(thr); + continue; + } + + /* XXX: Missing trap result validation for non-configurable target keys + * (must be present), for non-extensible target all target keys must be + * present and no extra keys can be present. + * http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys + */ + + /* XXX: The key enumerability check should trigger the "getOwnPropertyDescriptor" + * trap which has not yet been implemented. In the absence of such a trap, + * the enumerability should be checked from the target object; this is + * handled above. + */ +} +#endif /* DUK_USE_ES6_PROXY */ + +#if defined(DUK_USE_ES6_PROXY) +DUK_INTERNAL duk_ret_t duk_bi_proxy_constructor(duk_hthread *thr) { + DUK_ASSERT_TOP(thr, 2); /* [ target handler ] */ + + duk_require_constructor_call(thr); + duk_push_proxy(thr, 0 /*flags*/); /* [ target handler ] -> [ proxy ] */ + return 1; /* replacement */ +} +#endif /* DUK_USE_ES6_PROXY */ diff --git a/third_party/duktape/duk_bi_reflect.c b/third_party/duktape/duk_bi_reflect.c new file mode 100644 index 00000000..c398712e --- /dev/null +++ b/third_party/duktape/duk_bi_reflect.c @@ -0,0 +1,99 @@ +/* + * 'Reflect' built-in (ES2016 Section 26.1) + * http://www.ecma-international.org/ecma-262/7.0/#sec-reflect-object + * + * Many Reflect built-in functions are provided by shared helpers in + * duk_bi_object.c or duk_bi_function.c. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_REFLECT_BUILTIN) +DUK_INTERNAL duk_ret_t duk_bi_reflect_object_delete_property(duk_hthread *thr) { + duk_tval *tv_obj; + duk_tval *tv_key; + duk_bool_t ret; + + DUK_ASSERT_TOP(thr, 2); + (void) duk_require_hobject(thr, 0); + (void) duk_to_string(thr, 1); + + /* [ target key ] */ + + DUK_ASSERT(thr != NULL); + tv_obj = DUK_GET_TVAL_POSIDX(thr, 0); + tv_key = DUK_GET_TVAL_POSIDX(thr, 1); + ret = duk_hobject_delprop(thr, tv_obj, tv_key, 0 /*throw_flag*/); + duk_push_boolean(thr, ret); + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_reflect_object_get(duk_hthread *thr) { + duk_tval *tv_obj; + duk_tval *tv_key; + duk_idx_t nargs; + + DUK_ASSERT(thr != NULL); + nargs = duk_get_top_require_min(thr, 2 /*min_top*/); + (void) duk_require_hobject(thr, 0); + (void) duk_to_string(thr, 1); + if (nargs >= 3 && !duk_strict_equals(thr, 0, 2)) { + /* XXX: [[Get]] receiver currently unsupported */ + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return 0;); + } + + /* [ target key receiver? ...? ] */ + + tv_obj = DUK_GET_TVAL_POSIDX(thr, 0); + tv_key = DUK_GET_TVAL_POSIDX(thr, 1); + (void) duk_hobject_getprop(thr, tv_obj, tv_key); /* This could also be a duk_get_prop(). */ + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_reflect_object_has(duk_hthread *thr) { + duk_tval *tv_obj; + duk_tval *tv_key; + duk_bool_t ret; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT_TOP(thr, 2); + (void) duk_require_hobject(thr, 0); + (void) duk_to_string(thr, 1); + + /* [ target key ] */ + + tv_obj = DUK_GET_TVAL_POSIDX(thr, 0); + tv_key = DUK_GET_TVAL_POSIDX(thr, 1); + ret = duk_hobject_hasprop(thr, tv_obj, tv_key); + duk_push_boolean(thr, ret); + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_reflect_object_set(duk_hthread *thr) { + duk_tval *tv_obj; + duk_tval *tv_key; + duk_tval *tv_val; + duk_idx_t nargs; + duk_bool_t ret; + + DUK_ASSERT(thr != NULL); + nargs = duk_get_top_require_min(thr, 3 /*min_top*/); + (void) duk_require_hobject(thr, 0); + (void) duk_to_string(thr, 1); + if (nargs >= 4 && !duk_strict_equals(thr, 0, 3)) { + /* XXX: [[Set]] receiver currently unsupported */ + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return 0;); + } + + /* [ target key value receiver? ...? ] */ + + tv_obj = DUK_GET_TVAL_POSIDX(thr, 0); + tv_key = DUK_GET_TVAL_POSIDX(thr, 1); + tv_val = DUK_GET_TVAL_POSIDX(thr, 2); + ret = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, 0 /*throw_flag*/); + duk_push_boolean(thr, ret); + return 1; +} +#endif /* DUK_USE_REFLECT_BUILTIN */ diff --git a/third_party/duktape/duk_bi_regexp.c b/third_party/duktape/duk_bi_regexp.c new file mode 100644 index 00000000..81db7556 --- /dev/null +++ b/third_party/duktape/duk_bi_regexp.c @@ -0,0 +1,226 @@ +/* + * RegExp built-ins + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_REGEXP_SUPPORT) + +DUK_LOCAL void duk__get_this_regexp(duk_hthread *thr) { + duk_hobject *h; + + duk_push_this(thr); + h = duk_require_hobject_with_class(thr, -1, DUK_HOBJECT_CLASS_REGEXP); + DUK_ASSERT(h != NULL); + DUK_UNREF(h); + duk_insert(thr, 0); /* prepend regexp to valstack 0 index */ +} + +/* XXX: much to improve (code size) */ +DUK_INTERNAL duk_ret_t duk_bi_regexp_constructor(duk_hthread *thr) { + duk_hobject *h_pattern; + + DUK_ASSERT_TOP(thr, 2); + h_pattern = duk_get_hobject(thr, 0); + + if (!duk_is_constructor_call(thr) && + h_pattern != NULL && + DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP && + duk_is_undefined(thr, 1)) { + /* Called as a function, pattern has [[Class]] "RegExp" and + * flags is undefined -> return object as is. + */ + /* XXX: ES2015 has a NewTarget SameValue() check which is not + * yet implemented. + */ + duk_dup_0(thr); + return 1; + } + + /* Else functionality is identical for function call and constructor + * call. + */ + + if (h_pattern != NULL && + DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP) { + duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_SOURCE); + if (duk_is_undefined(thr, 1)) { + /* In ES5 one would need to read the flags individually; + * in ES2015 just read .flags. + */ + duk_get_prop_stridx(thr, 0, DUK_STRIDX_FLAGS); + } else { + /* In ES2015 allowed; overrides argument RegExp flags. */ + duk_dup_1(thr); + } + } else { + if (duk_is_undefined(thr, 0)) { + duk_push_hstring_empty(thr); + } else { + duk_dup_0(thr); + duk_to_string(thr, -1); /* Rejects Symbols. */ + } + if (duk_is_undefined(thr, 1)) { + duk_push_hstring_empty(thr); + } else { + duk_dup_1(thr); + duk_to_string(thr, -1); /* Rejects Symbols. */ + } + + /* [ ... pattern flags ] */ + } + + DUK_DDD(DUK_DDDPRINT("RegExp constructor/function call, pattern=%!T, flags=%!T", + (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1))); + + /* [ ... pattern flags ] (both uncoerced) */ + + duk_to_string(thr, -2); + duk_to_string(thr, -1); + duk_regexp_compile(thr); + + /* [ ... bytecode escaped_source ] */ + + duk_regexp_create_instance(thr); + + /* [ ... RegExp ] */ + + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_exec(duk_hthread *thr) { + duk__get_this_regexp(thr); + + /* [ regexp input ] */ + + duk_regexp_match(thr); + + /* [ result ] */ + + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_test(duk_hthread *thr) { + duk__get_this_regexp(thr); + + /* [ regexp input ] */ + + /* result object is created and discarded; wasteful but saves code space */ + duk_regexp_match(thr); + + /* [ result ] */ + + duk_push_boolean(thr, (duk_is_null(thr, -1) ? 0 : 1)); + + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_tostring(duk_hthread *thr) { + /* This must be generic in ES2015 and later. */ + DUK_ASSERT_TOP(thr, 0); + duk_push_this(thr); + duk_push_literal(thr, "/"); + duk_get_prop_stridx(thr, 0, DUK_STRIDX_SOURCE); + duk_dup_m2(thr); /* another "/" */ + duk_get_prop_stridx(thr, 0, DUK_STRIDX_FLAGS); + duk_concat(thr, 4); + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_flags(duk_hthread *thr) { + /* .flags is ES2015 but present even when ES2015 bindings are + * disabled because the constructor relies on it. + */ + duk_uint8_t buf[8]; /* enough for all flags + NUL */ + duk_uint8_t *p = buf; + + /* .flags is generic and works on any object. */ + duk_push_this(thr); + (void) duk_require_hobject(thr, -1); + if (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL)) { + *p++ = DUK_ASC_LC_G; + } + if (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_IGNORE_CASE, NULL)) { + *p++ = DUK_ASC_LC_I; + } + if (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_MULTILINE, NULL)) { + *p++ = DUK_ASC_LC_M; + } + /* .unicode: to be added */ + /* .sticky: to be added */ + *p++ = DUK_ASC_NUL; + DUK_ASSERT((duk_size_t) (p - buf) <= sizeof(buf)); + + duk_push_string(thr, (const char *) buf); + return 1; +} + +/* Shared helper for providing .source, .global, .multiline, etc getters. */ +DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_hthread *thr) { + duk_hstring *h_bc; + duk_small_uint_t re_flags; + duk_hobject *h; + duk_int_t magic; + + DUK_ASSERT_TOP(thr, 0); + + duk_push_this(thr); + h = duk_require_hobject(thr, -1); + magic = duk_get_current_magic(thr); + + if (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_REGEXP) { + duk_xget_owndataprop_stridx_short(thr, 0, DUK_STRIDX_INT_SOURCE); + duk_xget_owndataprop_stridx_short(thr, 0, DUK_STRIDX_INT_BYTECODE); + h_bc = duk_require_hstring(thr, -1); + re_flags = (duk_small_uint_t) DUK_HSTRING_GET_DATA(h_bc)[0]; /* Safe even if h_bc length is 0 (= NUL) */ + duk_pop(thr); + } else if (h == thr->builtins[DUK_BIDX_REGEXP_PROTOTYPE]) { + /* In ES2015 and ES2016 a TypeError would be thrown here. + * However, this had real world issues so ES2017 draft + * allows RegExp.prototype specifically, returning '(?:)' + * for .source and undefined for all flags. + */ + if (magic != 16 /* .source */) { + return 0; + } + duk_push_literal(thr, "(?:)"); /* .source handled by switch-case */ + re_flags = 0; + } else { + DUK_DCERROR_TYPE_INVALID_ARGS(thr); + } + + /* [ regexp source ] */ + + switch (magic) { + case 0: { /* global */ + duk_push_boolean(thr, (re_flags & DUK_RE_FLAG_GLOBAL)); + break; + } + case 1: { /* ignoreCase */ + duk_push_boolean(thr, (re_flags & DUK_RE_FLAG_IGNORE_CASE)); + break; + } + case 2: { /* multiline */ + duk_push_boolean(thr, (re_flags & DUK_RE_FLAG_MULTILINE)); + break; + } +#if 0 + /* Don't provide until implemented to avoid interfering with feature + * detection in user code. + */ + case 3: /* sticky */ + case 4: { /* unicode */ + duk_push_false(thr); + break; + } +#endif + default: { /* source */ + /* leave 'source' on top */ + break; + } + } + + return 1; +} + +#endif /* DUK_USE_REGEXP_SUPPORT */ diff --git a/third_party/duktape/duk_bi_string.c b/third_party/duktape/duk_bi_string.c new file mode 100644 index 00000000..6ec621d9 --- /dev/null +++ b/third_party/duktape/duk_bi_string.c @@ -0,0 +1,1634 @@ +/* + * String built-ins + * + * Most String built-ins must only accept strings (or String objects). + * Symbols, represented internally as strings, must be generally rejected. + * The duk_push_this_coercible_to_string() helper does this automatically. + */ + +/* XXX: There are several limitations in the current implementation for + * strings with >= 0x80000000UL characters. In some cases one would need + * to be able to represent the range [-0xffffffff,0xffffffff] and so on. + * Generally character and byte length are assumed to fit into signed 32 + * bits (< 0x80000000UL). Places with issues are not marked explicitly + * below in all cases, look for signed type usage (duk_int_t etc) for + * offsets/lengths. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_STRING_BUILTIN) + +/* + * Helpers + */ + +DUK_LOCAL duk_hstring *duk__str_tostring_notregexp(duk_hthread *thr, + duk_idx_t idx) { + duk_hstring *h; + + if (duk_get_class_number(thr, idx) == DUK_HOBJECT_CLASS_REGEXP) { + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return NULL;); + } + h = duk_to_hstring(thr, idx); + DUK_ASSERT(h != NULL); + + return h; +} + +DUK_LOCAL duk_int_t duk__str_search_shared(duk_hthread *thr, + duk_hstring *h_this, + duk_hstring *h_search, + duk_int_t start_cpos, + duk_bool_t backwards) { + duk_int_t cpos; + duk_int_t bpos; + const duk_uint8_t *p_start, *p_end, *p; + const duk_uint8_t *q_start; + duk_int_t q_blen; + duk_uint8_t firstbyte; + duk_uint8_t t; + + cpos = start_cpos; + + /* Empty searchstring always matches; cpos must be clamped here. + * (If q_blen were < 0 due to clamped coercion, it would also be + * caught here.) + */ + q_start = DUK_HSTRING_GET_DATA(h_search); + q_blen = (duk_int_t)DUK_HSTRING_GET_BYTELEN(h_search); + if (q_blen <= 0) { + return cpos; + } + DUK_ASSERT(q_blen > 0); + + bpos = (duk_int_t)duk_heap_strcache_offset_char2byte(thr, h_this, + (duk_uint32_t)cpos); + + p_start = DUK_HSTRING_GET_DATA(h_this); + p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_this); + p = p_start + bpos; + + /* This loop is optimized for size. For speed, there should be + * two separate loops, and we should ensure that memcmp() can be + * used without an extra "will searchstring fit" check. Doing + * the preconditioning for 'p' and 'p_end' is easy but cpos + * must be updated if 'p' is wound back (backward scanning). + */ + + firstbyte = q_start[0]; /* leading byte of match string */ + while (p <= p_end && p >= p_start) { + t = *p; + + /* For ECMAScript strings, this check can only match for + * initial UTF-8 bytes (not continuation bytes). For other + * strings all bets are off. + */ + + if ((t == firstbyte) && ((duk_size_t)(p_end - p) >= (duk_size_t)q_blen)) { + DUK_ASSERT(q_blen > 0); + if (duk_memcmp((const void *)p, (const void *)q_start, (size_t)q_blen) == + 0) { + return cpos; + } + } + + /* track cpos while scanning */ + if (backwards) { + /* when going backwards, we decrement cpos 'early'; + * 'p' may point to a continuation byte of the char + * at offset 'cpos', but that's OK because we'll + * backtrack all the way to the initial byte. + */ + if ((t & 0xc0) != 0x80) { + cpos--; + } + p--; + } else { + if ((t & 0xc0) != 0x80) { + cpos++; + } + p++; + } + } + + /* Not found. Empty string case is handled specially above. */ + return -1; +} + +/* + * Constructor + */ + +DUK_INTERNAL duk_ret_t duk_bi_string_constructor(duk_hthread *thr) { + duk_hstring *h; + duk_uint_t flags; + + /* String constructor needs to distinguish between an argument not given at + * all vs. given as 'undefined'. We're a vararg function to handle this + * properly. + */ + + /* XXX: copy current activation flags to thr, including current magic, + * is_constructor_call etc. This takes a few bytes in duk_hthread but + * makes call sites smaller (there are >30 is_constructor_call and get + * current magic call sites. + */ + + if (duk_get_top(thr) == 0) { + duk_push_hstring_empty(thr); + } else { + h = duk_to_hstring_acceptsymbol(thr, 0); + if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h) && + !duk_is_constructor_call(thr))) { + duk_push_symbol_descriptive_string(thr, h); + duk_replace(thr, 0); + } + } + duk_to_string(thr, 0); /* catches symbol argument for constructor call */ + DUK_ASSERT(duk_is_string(thr, 0)); + duk_set_top(thr, 1); /* Top may be 1 or larger. */ + + if (duk_is_constructor_call(thr)) { + /* String object internal value is immutable */ + flags = DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_STRING); + duk_push_object_helper(thr, flags, DUK_BIDX_STRING_PROTOTYPE); + duk_dup_0(thr); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, + DUK_PROPDESC_FLAGS_NONE); + } + /* Note: unbalanced stack on purpose */ + + return 1; +} + +DUK_LOCAL duk_ret_t duk__construct_from_codepoints(duk_hthread *thr, + duk_bool_t nonbmp) { + duk_bufwriter_ctx bw_alloc; + duk_bufwriter_ctx *bw; + duk_idx_t i, n; + duk_ucodepoint_t cp; + + /* XXX: It would be nice to build the string directly but ToUint16() + * coercion is needed so a generic helper would not be very + * helpful (perhaps coerce the value stack first here and then + * build a string from a duk_tval number sequence in one go?). + */ + + n = duk_get_top(thr); + + bw = &bw_alloc; + DUK_BW_INIT_PUSHBUF( + thr, bw, (duk_size_t)n); /* initial estimate for ASCII only codepoints */ + + for (i = 0; i < n; i++) { + /* XXX: could improve bufwriter handling to write multiple codepoints + * with one ensure call but the relative benefit would be quite small. + */ + + if (nonbmp) { + /* ES2015 requires that (1) SameValue(cp, ToInteger(cp)) and + * (2) cp >= 0 and cp <= 0x10ffff. This check does not + * implement the steps exactly but the outcome should be + * the same. + */ + duk_int32_t i32 = 0; + if (!duk_is_whole_get_int32(duk_to_number(thr, i), &i32) || i32 < 0 || + i32 > 0x10ffffL) { + DUK_DCERROR_RANGE_INVALID_ARGS(thr); + } + DUK_ASSERT(i32 >= 0 && i32 <= 0x10ffffL); + cp = (duk_ucodepoint_t)i32; + DUK_BW_WRITE_ENSURE_CESU8(thr, bw, cp); + } else { +#if defined(DUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT) + /* ToUint16() coercion is mandatory in the E5.1 specification, but + * this non-compliant behavior makes more sense because we support + * non-BMP codepoints. Don't use CESU-8 because that'd create + * surrogate pairs. + */ + cp = (duk_ucodepoint_t)duk_to_uint32(thr, i); + DUK_BW_WRITE_ENSURE_XUTF8(thr, bw, cp); +#else + cp = (duk_ucodepoint_t)duk_to_uint16(thr, i); + DUK_ASSERT(cp >= 0 && cp <= 0x10ffffL); + DUK_BW_WRITE_ENSURE_CESU8(thr, bw, cp); +#endif + } + } + + DUK_BW_COMPACT(thr, bw); + (void)duk_buffer_to_string(thr, + -1); /* Safe, extended UTF-8 or CESU-8 encoded. */ + return 1; +} + +DUK_INTERNAL duk_ret_t +duk_bi_string_constructor_from_char_code(duk_hthread *thr) { + return duk__construct_from_codepoints(thr, 0 /*nonbmp*/); +} + +#if defined(DUK_USE_ES6) +DUK_INTERNAL duk_ret_t +duk_bi_string_constructor_from_code_point(duk_hthread *thr) { + return duk__construct_from_codepoints(thr, 1 /*nonbmp*/); +} +#endif + +/* + * toString(), valueOf() + */ + +DUK_INTERNAL duk_ret_t duk_bi_string_prototype_to_string(duk_hthread *thr) { + duk_tval *tv; + + duk_push_this(thr); + tv = duk_require_tval(thr, -1); + DUK_ASSERT(tv != NULL); + + if (DUK_TVAL_IS_STRING(tv)) { + /* return as is */ + } else if (DUK_TVAL_IS_OBJECT(tv)) { + duk_hobject *h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + + /* Must be a "string object", i.e. class "String" */ + if (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_STRING) { + goto type_error; + } + + duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE); + DUK_ASSERT(duk_is_string(thr, -1)); + } else { + goto type_error; + } + + (void)duk_require_hstring_notsymbol( + thr, -1); /* Reject symbols (and wrapped symbols). */ + return 1; + +type_error: + DUK_DCERROR_TYPE_INVALID_ARGS(thr); +} + +/* + * Character and charcode access + */ + +DUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_at(duk_hthread *thr) { + duk_hstring *h; + duk_int_t pos; + + /* XXX: faster implementation */ + + h = duk_push_this_coercible_to_string(thr); + DUK_ASSERT(h != NULL); + + pos = duk_to_int(thr, 0); + + if (sizeof(duk_size_t) >= sizeof(duk_uint_t)) { + /* Cast to duk_size_t works in this case: + * - If pos < 0, (duk_size_t) pos will always be + * >= max_charlen, and result will be the empty string + * (see duk_substring()). + * - If pos >= 0, pos + 1 cannot wrap. + */ + DUK_ASSERT((duk_size_t)DUK_INT_MIN >= DUK_HSTRING_MAX_BYTELEN); + DUK_ASSERT((duk_size_t)DUK_INT_MAX + 1U > (duk_size_t)DUK_INT_MAX); + duk_substring(thr, -1, (duk_size_t)pos, (duk_size_t)pos + 1U); + } else { + /* If size_t is smaller than int, explicit bounds checks + * are needed because an int may wrap multiple times. + */ + if (DUK_UNLIKELY(pos < 0 || (duk_uint_t)pos >= + (duk_uint_t)DUK_HSTRING_GET_CHARLEN(h))) { + duk_push_hstring_empty(thr); + } else { + duk_substring(thr, -1, (duk_size_t)pos, (duk_size_t)pos + 1U); + } + } + + return 1; +} + +/* Magic: 0=charCodeAt, 1=codePointAt */ +DUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_code_at(duk_hthread *thr) { + duk_int_t pos; + duk_hstring *h; + duk_bool_t clamped; + duk_uint32_t cp; + duk_int_t magic; + + /* XXX: faster implementation */ + + DUK_DDD(DUK_DDDPRINT("arg=%!T", (duk_tval *)duk_get_tval(thr, 0))); + + h = duk_push_this_coercible_to_string(thr); + DUK_ASSERT(h != NULL); + + pos = duk_to_int_clamped_raw( + thr, 0 /*index*/, 0 /*min(incl)*/, + (duk_int_t)DUK_HSTRING_GET_CHARLEN(h) - 1 /*max(incl)*/, + &clamped /*out_clamped*/); +#if defined(DUK_USE_ES6) + magic = duk_get_current_magic(thr); +#else + DUK_ASSERT(duk_get_current_magic(thr) == 0); + magic = 0; +#endif + if (clamped) { + /* For out-of-bounds indices .charCodeAt() returns NaN and + * .codePointAt() returns undefined. + */ + if (magic != 0) { + return 0; + } + duk_push_nan(thr); + } else { + DUK_ASSERT(pos >= 0); + cp = (duk_uint32_t)duk_hstring_char_code_at_raw( + thr, h, (duk_uint_t)pos, (duk_bool_t)magic /*surrogate_aware*/); + duk_push_u32(thr, cp); + } + return 1; +} + +/* + * substring(), substr(), slice() + */ + +/* XXX: any chance of merging these three similar but still slightly + * different algorithms so that footprint would be reduced? + */ + +DUK_INTERNAL duk_ret_t duk_bi_string_prototype_substring(duk_hthread *thr) { + duk_hstring *h; + duk_int_t start_pos, end_pos; + duk_int_t len; + + h = duk_push_this_coercible_to_string(thr); + DUK_ASSERT(h != NULL); + len = (duk_int_t)DUK_HSTRING_GET_CHARLEN(h); + + /* [ start end str ] */ + + start_pos = duk_to_int_clamped(thr, 0, 0, len); + if (duk_is_undefined(thr, 1)) { + end_pos = len; + } else { + end_pos = duk_to_int_clamped(thr, 1, 0, len); + } + DUK_ASSERT(start_pos >= 0 && start_pos <= len); + DUK_ASSERT(end_pos >= 0 && end_pos <= len); + + if (start_pos > end_pos) { + duk_int_t tmp = start_pos; + start_pos = end_pos; + end_pos = tmp; + } + + DUK_ASSERT(end_pos >= start_pos); + + duk_substring(thr, -1, (duk_size_t)start_pos, (duk_size_t)end_pos); + return 1; +} + +#if defined(DUK_USE_SECTION_B) +DUK_INTERNAL duk_ret_t duk_bi_string_prototype_substr(duk_hthread *thr) { + duk_hstring *h; + duk_int_t start_pos, end_pos; + duk_int_t len; + + /* Unlike non-obsolete String calls, substr() algorithm in E5.1 + * specification will happily coerce undefined and null to strings + * ("undefined" and "null"). + */ + duk_push_this(thr); + h = duk_to_hstring_m1(thr); /* Reject Symbols. */ + DUK_ASSERT(h != NULL); + len = (duk_int_t)DUK_HSTRING_GET_CHARLEN(h); + + /* [ start length str ] */ + + /* The implementation for computing of start_pos and end_pos differs + * from the standard algorithm, but is intended to result in the exactly + * same behavior. This is not always obvious. + */ + + /* combines steps 2 and 5; -len ensures max() not needed for step 5 */ + start_pos = duk_to_int_clamped(thr, 0, -len, len); + if (start_pos < 0) { + start_pos = len + start_pos; + } + DUK_ASSERT(start_pos >= 0 && start_pos <= len); + + /* combines steps 3, 6; step 7 is not needed */ + if (duk_is_undefined(thr, 1)) { + end_pos = len; + } else { + DUK_ASSERT(start_pos <= len); + end_pos = start_pos + duk_to_int_clamped(thr, 1, 0, len - start_pos); + } + DUK_ASSERT(start_pos >= 0 && start_pos <= len); + DUK_ASSERT(end_pos >= 0 && end_pos <= len); + DUK_ASSERT(end_pos >= start_pos); + + duk_substring(thr, -1, (duk_size_t)start_pos, (duk_size_t)end_pos); + return 1; +} +#endif /* DUK_USE_SECTION_B */ + +DUK_INTERNAL duk_ret_t duk_bi_string_prototype_slice(duk_hthread *thr) { + duk_hstring *h; + duk_int_t start_pos, end_pos; + duk_int_t len; + + h = duk_push_this_coercible_to_string(thr); + DUK_ASSERT(h != NULL); + len = (duk_int_t)DUK_HSTRING_GET_CHARLEN(h); + + /* [ start end str ] */ + + start_pos = duk_to_int_clamped(thr, 0, -len, len); + if (start_pos < 0) { + start_pos = len + start_pos; + } + if (duk_is_undefined(thr, 1)) { + end_pos = len; + } else { + end_pos = duk_to_int_clamped(thr, 1, -len, len); + if (end_pos < 0) { + end_pos = len + end_pos; + } + } + DUK_ASSERT(start_pos >= 0 && start_pos <= len); + DUK_ASSERT(end_pos >= 0 && end_pos <= len); + + if (end_pos < start_pos) { + end_pos = start_pos; + } + + DUK_ASSERT(end_pos >= start_pos); + + duk_substring(thr, -1, (duk_size_t)start_pos, (duk_size_t)end_pos); + return 1; +} + +/* + * Case conversion + */ + +DUK_INTERNAL duk_ret_t +duk_bi_string_prototype_caseconv_shared(duk_hthread *thr) { + duk_small_int_t uppercase = duk_get_current_magic(thr); + + (void)duk_push_this_coercible_to_string(thr); + duk_unicode_case_convert_string(thr, (duk_bool_t)uppercase); + return 1; +} + +/* + * indexOf() and lastIndexOf() + */ + +DUK_INTERNAL duk_ret_t +duk_bi_string_prototype_indexof_shared(duk_hthread *thr) { + duk_hstring *h_this; + duk_hstring *h_search; + duk_int_t clen_this; + duk_int_t cpos; + duk_small_uint_t is_lastindexof = (duk_small_uint_t)duk_get_current_magic( + thr); /* 0=indexOf, 1=lastIndexOf */ + + h_this = duk_push_this_coercible_to_string(thr); + DUK_ASSERT(h_this != NULL); + clen_this = (duk_int_t)DUK_HSTRING_GET_CHARLEN(h_this); + + h_search = duk_to_hstring(thr, 0); + DUK_ASSERT(h_search != NULL); + + duk_to_number(thr, 1); + if (duk_is_nan(thr, 1) && is_lastindexof) { + /* indexOf: NaN should cause pos to be zero. + * lastIndexOf: NaN should cause pos to be +Infinity + * (and later be clamped to len). + */ + cpos = clen_this; + } else { + cpos = duk_to_int_clamped(thr, 1, 0, clen_this); + } + + cpos = duk__str_search_shared(thr, h_this, h_search, cpos, + is_lastindexof /*backwards*/); + duk_push_int(thr, cpos); + return 1; +} + +/* + * replace() + */ + +/* XXX: the current implementation works but is quite clunky; it compiles + * to almost 1,4kB of x86 code so it needs to be simplified (better approach, + * shared helpers, etc). Some ideas for refactoring: + * + * - a primitive to convert a string into a regexp matcher (reduces matching + * code at the cost of making matching much slower) + * - use replace() as a basic helper for match() and split(), which are both + * much simpler + * - API call to get_prop and to_boolean + */ + +DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) { + duk_hstring *h_input; + duk_hstring *h_match; + duk_hstring *h_search; + duk_hobject *h_re; + duk_bufwriter_ctx bw_alloc; + duk_bufwriter_ctx *bw; +#if defined(DUK_USE_REGEXP_SUPPORT) + duk_bool_t is_regexp; + duk_bool_t is_global; +#endif + duk_bool_t is_repl_func; + duk_uint32_t match_start_coff, match_start_boff; +#if defined(DUK_USE_REGEXP_SUPPORT) + duk_int_t match_caps; +#endif + duk_uint32_t prev_match_end_boff; + const duk_uint8_t *r_start, *r_end, *r; /* repl string scan */ + duk_size_t tmp_sz; + + DUK_ASSERT_TOP(thr, 2); + h_input = duk_push_this_coercible_to_string(thr); + DUK_ASSERT(h_input != NULL); + + bw = &bw_alloc; + DUK_BW_INIT_PUSHBUF( + thr, bw, + DUK_HSTRING_GET_BYTELEN( + h_input)); /* input size is good output starting point */ + + DUK_ASSERT_TOP(thr, 4); + + /* stack[0] = search value + * stack[1] = replace value + * stack[2] = input string + * stack[3] = result buffer + */ + + h_re = duk_get_hobject_with_class(thr, 0, DUK_HOBJECT_CLASS_REGEXP); + if (h_re) { +#if defined(DUK_USE_REGEXP_SUPPORT) + is_regexp = 1; + is_global = duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL); + + if (is_global) { + /* start match from beginning */ + duk_push_int(thr, 0); + duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX); + } +#else /* DUK_USE_REGEXP_SUPPORT */ + DUK_DCERROR_UNSUPPORTED(thr); +#endif /* DUK_USE_REGEXP_SUPPORT */ + } else { + duk_to_string(thr, 0); /* rejects symbols */ +#if defined(DUK_USE_REGEXP_SUPPORT) + is_regexp = 0; + is_global = 0; +#endif + } + + if (duk_is_function(thr, 1)) { + is_repl_func = 1; + r_start = NULL; + r_end = NULL; + } else { + duk_hstring *h_repl; + + is_repl_func = 0; + h_repl = duk_to_hstring(thr, 1); /* reject symbols */ + DUK_ASSERT(h_repl != NULL); + r_start = DUK_HSTRING_GET_DATA(h_repl); + r_end = r_start + DUK_HSTRING_GET_BYTELEN(h_repl); + } + + prev_match_end_boff = 0; + + for (;;) { + /* + * If matching with a regexp: + * - non-global RegExp: lastIndex not touched on a match, zeroed + * on a non-match + * - global RegExp: on match, lastIndex will be updated by regexp + * executor to point to next char after the matching part (so that + * characters in the matching part are not matched again) + * + * If matching with a string: + * - always non-global match, find first occurrence + * + * We need: + * - The character offset of start-of-match for the replacer function + * - The byte offsets for start-of-match and end-of-match to implement + * the replacement values $&, $`, and $', and to copy non-matching + * input string portions (including header and trailer) verbatim. + * + * NOTE: the E5.1 specification is a bit vague how the RegExp should + * behave in the replacement process; e.g. is matching done first for + * all matches (in the global RegExp case) before any replacer calls + * are made? See: test-bi-string-proto-replace.js for discussion. + */ + + DUK_ASSERT_TOP(thr, 4); + +#if defined(DUK_USE_REGEXP_SUPPORT) + if (is_regexp) { + duk_dup_0(thr); + duk_dup_2(thr); + duk_regexp_match(thr); /* [ ... regexp input ] -> [ res_obj ] */ + if (!duk_is_object(thr, -1)) { + duk_pop(thr); + break; + } + + duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX); + DUK_ASSERT(duk_is_number(thr, -1)); + match_start_coff = duk_get_uint(thr, -1); + duk_pop(thr); + + duk_get_prop_index(thr, -1, 0); + DUK_ASSERT(duk_is_string(thr, -1)); + h_match = duk_known_hstring(thr, -1); + duk_pop( + thr); /* h_match is borrowed, remains reachable through match_obj */ + + if (DUK_HSTRING_GET_BYTELEN(h_match) == 0) { + /* This should be equivalent to match() algorithm step 8.f.iii.2: + * detect an empty match and allow it, but don't allow it twice. + */ + duk_uint32_t last_index; + + duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX); + last_index = (duk_uint32_t)duk_get_uint(thr, -1); + DUK_DDD(DUK_DDDPRINT("empty match, bump lastIndex: %ld -> %ld", + (long)last_index, (long)(last_index + 1))); + duk_pop(thr); + duk_push_uint(thr, (duk_uint_t)(last_index + 1)); + duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX); + } + + DUK_ASSERT(duk_get_length(thr, -1) <= DUK_INT_MAX); /* string limits */ + match_caps = (duk_int_t)duk_get_length(thr, -1); + } else { +#else /* DUK_USE_REGEXP_SUPPORT */ + { /* unconditionally */ +#endif /* DUK_USE_REGEXP_SUPPORT */ + const duk_uint8_t *p_start, *p_end, *p; /* input string scan */ + const duk_uint8_t *q_start; /* match string */ + duk_size_t q_blen; + +#if defined(DUK_USE_REGEXP_SUPPORT) + DUK_ASSERT(!is_global); /* single match always */ +#endif + + p_start = DUK_HSTRING_GET_DATA(h_input); + p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input); + p = p_start; + + h_search = duk_known_hstring(thr, 0); + q_start = DUK_HSTRING_GET_DATA(h_search); + q_blen = (duk_size_t)DUK_HSTRING_GET_BYTELEN(h_search); + + p_end -= q_blen; /* ensure full memcmp() fits in while */ + + match_start_coff = 0; + + while (p <= p_end) { + DUK_ASSERT(p + q_blen <= DUK_HSTRING_GET_DATA(h_input) + + DUK_HSTRING_GET_BYTELEN(h_input)); + if (duk_memcmp((const void *)p, (const void *)q_start, + (size_t)q_blen) == 0) { + duk_dup_0(thr); + h_match = duk_known_hstring(thr, -1); +#if defined(DUK_USE_REGEXP_SUPPORT) + match_caps = 0; +#endif + goto found; + } + + /* track utf-8 non-continuation bytes */ + if ((p[0] & 0xc0) != 0x80) { + match_start_coff++; + } + p++; + } + + /* not found */ + break; + } + found: + + /* stack[0] = search value + * stack[1] = replace value + * stack[2] = input string + * stack[3] = result buffer + * stack[4] = regexp match OR match string + */ + + match_start_boff = (duk_uint32_t)duk_heap_strcache_offset_char2byte( + thr, h_input, match_start_coff); + + tmp_sz = (duk_size_t)(match_start_boff - prev_match_end_boff); + DUK_BW_WRITE_ENSURE_BYTES( + thr, bw, DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff, tmp_sz); + + prev_match_end_boff = match_start_boff + DUK_HSTRING_GET_BYTELEN(h_match); + + if (is_repl_func) { + duk_idx_t idx_args; + duk_hstring *h_repl; + + /* regexp res_obj is at index 4 */ + + duk_dup_1(thr); + idx_args = duk_get_top(thr); + +#if defined(DUK_USE_REGEXP_SUPPORT) + if (is_regexp) { + duk_int_t idx; + duk_require_stack(thr, match_caps + 2); + for (idx = 0; idx < match_caps; idx++) { + /* match followed by capture(s) */ + duk_get_prop_index(thr, 4, (duk_uarridx_t)idx); + } + } else { +#else /* DUK_USE_REGEXP_SUPPORT */ + { /* unconditionally */ +#endif /* DUK_USE_REGEXP_SUPPORT */ + /* match == search string, by definition */ + duk_dup_0(thr); + } + duk_push_uint(thr, (duk_uint_t)match_start_coff); + duk_dup_2(thr); + + /* [ ... replacer match [captures] match_char_offset input ] */ + + duk_call(thr, duk_get_top(thr) - idx_args); + h_repl = duk_to_hstring_m1(thr); /* -> [ ... repl_value ] */ + DUK_ASSERT(h_repl != NULL); + + DUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_repl); + + duk_pop(thr); /* repl_value */ + } else { + r = r_start; + + while (r < r_end) { + duk_int_t ch1; + duk_int_t ch2; +#if defined(DUK_USE_REGEXP_SUPPORT) + duk_int_t ch3; +#endif + duk_size_t left; + + ch1 = *r++; + if (ch1 != DUK_ASC_DOLLAR) { + goto repl_write; + } + DUK_ASSERT(r <= r_end); + left = (duk_size_t)(r_end - r); + + if (left <= 0) { + goto repl_write; + } + + ch2 = r[0]; + switch (ch2) { + case DUK_ASC_DOLLAR: { + ch1 = (1u << 8) + DUK_ASC_DOLLAR; + goto repl_write; + } + case DUK_ASC_AMP: { + DUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_match); + r++; + continue; + } + case DUK_ASC_GRAVE: { + tmp_sz = (duk_size_t)match_start_boff; + DUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input), + tmp_sz); + r++; + continue; + } + case DUK_ASC_SINGLEQUOTE: { + duk_uint32_t match_end_boff; + + /* Use match charlen instead of bytelen, just in case the input and + * match codepoint encodings would have different lengths. + */ + /* XXX: charlen computed here, and also in char2byte helper. */ + match_end_boff = (duk_uint32_t)duk_heap_strcache_offset_char2byte( + thr, h_input, + match_start_coff + + (duk_uint_fast32_t)DUK_HSTRING_GET_CHARLEN(h_match)); + + tmp_sz = + (duk_size_t)(DUK_HSTRING_GET_BYTELEN(h_input) - match_end_boff); + DUK_BW_WRITE_ENSURE_BYTES( + thr, bw, DUK_HSTRING_GET_DATA(h_input) + match_end_boff, + tmp_sz); + r++; + continue; + } + default: { +#if defined(DUK_USE_REGEXP_SUPPORT) + duk_int_t capnum, captmp, capadv; + /* XXX: optional check, match_caps is zero if no regexp, + * so dollar will be interpreted literally anyway. + */ + + if (!is_regexp) { + goto repl_write; + } + + if (!(ch2 >= DUK_ASC_0 && ch2 <= DUK_ASC_9)) { + goto repl_write; + } + capnum = ch2 - DUK_ASC_0; + capadv = 1; + + if (left >= 2) { + ch3 = r[1]; + if (ch3 >= DUK_ASC_0 && ch3 <= DUK_ASC_9) { + captmp = capnum * 10 + (ch3 - DUK_ASC_0); + if (captmp < match_caps) { + capnum = captmp; + capadv = 2; + } + } + } + + if (capnum > 0 && capnum < match_caps) { + DUK_ASSERT(is_regexp != 0); /* match_caps == 0 without regexps */ + + /* regexp res_obj is at offset 4 */ + duk_get_prop_index(thr, 4, (duk_uarridx_t)capnum); + if (duk_is_string(thr, -1)) { + duk_hstring *h_tmp_str; + + h_tmp_str = duk_known_hstring(thr, -1); + + DUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_tmp_str); + } else { + /* undefined -> skip (replaced with empty) */ + } + duk_pop(thr); + r += capadv; + continue; + } else { + goto repl_write; + } +#else /* DUK_USE_REGEXP_SUPPORT */ + goto repl_write; /* unconditionally */ +#endif /* DUK_USE_REGEXP_SUPPORT */ + } /* default case */ + } /* switch (ch2) */ + + repl_write: + /* ch1 = (r_increment << 8) + byte */ + + DUK_BW_WRITE_ENSURE_U8(thr, bw, (duk_uint8_t)(ch1 & 0xff)); + r += ch1 >> 8; + } /* while repl */ + } /* if (is_repl_func) */ + + duk_pop(thr); /* pop regexp res_obj or match string */ + +#if defined(DUK_USE_REGEXP_SUPPORT) + if (!is_global) { +#else + { /* unconditionally; is_global==0 */ +#endif + break; + } + } + + /* trailer */ + tmp_sz = (duk_size_t)(DUK_HSTRING_GET_BYTELEN(h_input) - prev_match_end_boff); + DUK_BW_WRITE_ENSURE_BYTES( + thr, bw, DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff, tmp_sz); + + DUK_ASSERT_TOP(thr, 4); + DUK_BW_COMPACT(thr, bw); + (void)duk_buffer_to_string(thr, -1); /* Safe if inputs are safe. */ + return 1; +} + +/* + * split() + */ + +/* XXX: very messy now, but works; clean up, remove unused variables (nomimally + * used so compiler doesn't complain). + */ + +DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) { + duk_hstring *h_input; + duk_hstring *h_sep; + duk_uint32_t limit; + duk_uint32_t arr_idx; +#if defined(DUK_USE_REGEXP_SUPPORT) + duk_bool_t is_regexp; +#endif + duk_bool_t matched; /* set to 1 if any match exists (needed for empty input + special case) */ + duk_uint32_t prev_match_end_coff, prev_match_end_boff; + duk_uint32_t match_start_boff, match_start_coff; + duk_uint32_t match_end_boff, match_end_coff; + + h_input = duk_push_this_coercible_to_string(thr); + DUK_ASSERT(h_input != NULL); + + duk_push_array(thr); + + if (duk_is_undefined(thr, 1)) { + limit = 0xffffffffUL; + } else { + limit = duk_to_uint32(thr, 1); + } + + if (limit == 0) { + return 1; + } + + /* If the separator is a RegExp, make a "clone" of it. The specification + * algorithm calls [[Match]] directly for specific indices; we emulate this + * by tweaking lastIndex and using a "force global" variant of + * duk_regexp_match() which will use global-style matching even when the + * RegExp itself is non-global. + */ + + if (duk_is_undefined(thr, 0)) { + /* The spec algorithm first does "R = ToString(separator)" before checking + * whether separator is undefined. Since this is side effect free, we can + * skip the ToString() here. + */ + duk_dup_2(thr); + duk_put_prop_index(thr, 3, 0); + return 1; + } else if (duk_get_hobject_with_class(thr, 0, DUK_HOBJECT_CLASS_REGEXP) != + NULL) { +#if defined(DUK_USE_REGEXP_SUPPORT) + duk_push_hobject_bidx(thr, DUK_BIDX_REGEXP_CONSTRUCTOR); + duk_dup_0(thr); + duk_new(thr, 1); /* [ ... RegExp val ] -> [ ... res ] */ + duk_replace(thr, 0); + /* lastIndex is initialized to zero by new RegExp() */ + is_regexp = 1; +#else + DUK_DCERROR_UNSUPPORTED(thr); +#endif + } else { + duk_to_string(thr, 0); +#if defined(DUK_USE_REGEXP_SUPPORT) + is_regexp = 0; +#endif + } + + /* stack[0] = separator (string or regexp) + * stack[1] = limit + * stack[2] = input string + * stack[3] = result array + */ + + prev_match_end_boff = 0; + prev_match_end_coff = 0; + arr_idx = 0; + matched = 0; + + for (;;) { + /* + * The specification uses RegExp [[Match]] to attempt match at specific + * offsets. We don't have such a primitive, so we use an actual RegExp + * and tweak lastIndex. Since the RegExp may be non-global, we use a + * special variant which forces global-like behavior for matching. + */ + + DUK_ASSERT_TOP(thr, 4); + +#if defined(DUK_USE_REGEXP_SUPPORT) + if (is_regexp) { + duk_dup_0(thr); + duk_dup_2(thr); + duk_regexp_match_force_global( + thr); /* [ ... regexp input ] -> [ res_obj ] */ + if (!duk_is_object(thr, -1)) { + duk_pop(thr); + break; + } + matched = 1; + + duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX); + DUK_ASSERT(duk_is_number(thr, -1)); + match_start_coff = duk_get_uint(thr, -1); + match_start_boff = (duk_uint32_t)duk_heap_strcache_offset_char2byte( + thr, h_input, match_start_coff); + duk_pop(thr); + + if (match_start_coff == DUK_HSTRING_GET_CHARLEN(h_input)) { + /* don't allow an empty match at the end of the string */ + duk_pop(thr); + break; + } + + duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX); + DUK_ASSERT(duk_is_number(thr, -1)); + match_end_coff = duk_get_uint(thr, -1); + match_end_boff = (duk_uint32_t)duk_heap_strcache_offset_char2byte( + thr, h_input, match_end_coff); + duk_pop(thr); + + /* empty match -> bump and continue */ + if (prev_match_end_boff == match_end_boff) { + duk_push_uint(thr, (duk_uint_t)(match_end_coff + 1)); + duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX); + duk_pop(thr); + continue; + } + } else { +#else /* DUK_USE_REGEXP_SUPPORT */ + { /* unconditionally */ +#endif /* DUK_USE_REGEXP_SUPPORT */ + const duk_uint8_t *p_start, *p_end, *p; /* input string scan */ + const duk_uint8_t *q_start; /* match string */ + duk_size_t q_blen, q_clen; + + p_start = DUK_HSTRING_GET_DATA(h_input); + p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input); + p = p_start + prev_match_end_boff; + + h_sep = duk_known_hstring(thr, 0); /* symbol already rejected above */ + q_start = DUK_HSTRING_GET_DATA(h_sep); + q_blen = (duk_size_t)DUK_HSTRING_GET_BYTELEN(h_sep); + q_clen = (duk_size_t)DUK_HSTRING_GET_CHARLEN(h_sep); + + p_end -= q_blen; /* ensure full memcmp() fits in while */ + + match_start_coff = prev_match_end_coff; + + if (q_blen == 0) { + /* Handle empty separator case: it will always match, and always + * triggers the check in step 13.c.iii initially. Note that we + * must skip to either end of string or start of first codepoint, + * skipping over any continuation bytes! + * + * Don't allow an empty string to match at the end of the input. + */ + + matched = 1; /* empty separator can always match */ + + match_start_coff++; + p++; + while (p < p_end) { + if ((p[0] & 0xc0) != 0x80) { + goto found; + } + p++; + } + goto not_found; + } + + DUK_ASSERT(q_blen > 0 && q_clen > 0); + while (p <= p_end) { + DUK_ASSERT(p + q_blen <= DUK_HSTRING_GET_DATA(h_input) + + DUK_HSTRING_GET_BYTELEN(h_input)); + DUK_ASSERT(q_blen > 0); /* no issues with empty memcmp() */ + if (duk_memcmp((const void *)p, (const void *)q_start, + (size_t)q_blen) == 0) { + /* never an empty match, so step 13.c.iii can't be triggered */ + goto found; + } + + /* track utf-8 non-continuation bytes */ + if ((p[0] & 0xc0) != 0x80) { + match_start_coff++; + } + p++; + } + + not_found: + /* not found */ + break; + + found: + matched = 1; + match_start_boff = (duk_uint32_t)(p - p_start); + match_end_coff = (duk_uint32_t)( + match_start_coff + q_clen); /* constrained by string length */ + match_end_boff = (duk_uint32_t)(match_start_boff + q_blen); /* ditto */ + + /* empty match (may happen with empty separator) -> bump and continue */ + if (prev_match_end_boff == match_end_boff) { + prev_match_end_boff++; + prev_match_end_coff++; + continue; + } + } /* if (is_regexp) */ + + /* stack[0] = separator (string or regexp) + * stack[1] = limit + * stack[2] = input string + * stack[3] = result array + * stack[4] = regexp res_obj (if is_regexp) + */ + + DUK_DDD(DUK_DDDPRINT("split; match_start b=%ld,c=%ld, match_end " + "b=%ld,c=%ld, prev_end b=%ld,c=%ld", + (long)match_start_boff, (long)match_start_coff, + (long)match_end_boff, (long)match_end_coff, + (long)prev_match_end_boff, (long)prev_match_end_coff)); + + duk_push_lstring( + thr, + (const char *)(DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff), + (duk_size_t)(match_start_boff - prev_match_end_boff)); + duk_put_prop_index(thr, 3, arr_idx); + arr_idx++; + if (arr_idx >= limit) { + goto hit_limit; + } + +#if defined(DUK_USE_REGEXP_SUPPORT) + if (is_regexp) { + duk_size_t i, len; + + len = duk_get_length(thr, 4); + for (i = 1; i < len; i++) { + DUK_ASSERT(i <= DUK_UARRIDX_MAX); /* cannot have >4G captures */ + duk_get_prop_index(thr, 4, (duk_uarridx_t)i); + duk_put_prop_index(thr, 3, arr_idx); + arr_idx++; + if (arr_idx >= limit) { + goto hit_limit; + } + } + + duk_pop(thr); + /* lastIndex already set up for next match */ + } else { +#else /* DUK_USE_REGEXP_SUPPORT */ + { + /* unconditionally */ +#endif /* DUK_USE_REGEXP_SUPPORT */ + /* no action */ + } + + prev_match_end_boff = match_end_boff; + prev_match_end_coff = match_end_coff; + continue; + } /* for */ + + /* Combined step 11 (empty string special case) and 14-15. */ + + DUK_DDD(DUK_DDDPRINT("split trailer; prev_end b=%ld,c=%ld", + (long)prev_match_end_boff, (long)prev_match_end_coff)); + + if (DUK_HSTRING_GET_BYTELEN(h_input) > 0 || !matched) { + /* Add trailer if: + * a) non-empty input + * b) empty input and no (zero size) match found (step 11) + */ + + duk_push_lstring( + thr, (const char *)DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff, + (duk_size_t)(DUK_HSTRING_GET_BYTELEN(h_input) - prev_match_end_boff)); + duk_put_prop_index(thr, 3, arr_idx); + /* No arr_idx update or limit check */ + } + + return 1; + +hit_limit: +#if defined(DUK_USE_REGEXP_SUPPORT) + if (is_regexp) { + duk_pop(thr); + } +#endif + + return 1; +} + +/* + * Various + */ + +#if defined(DUK_USE_REGEXP_SUPPORT) +DUK_LOCAL void duk__to_regexp_helper(duk_hthread *thr, duk_idx_t idx, + duk_bool_t force_new) { + duk_hobject *h; + + /* Shared helper for match() steps 3-4, search() steps 3-4. */ + + DUK_ASSERT(idx >= 0); + + if (force_new) { + goto do_new; + } + + h = duk_get_hobject_with_class(thr, idx, DUK_HOBJECT_CLASS_REGEXP); + if (!h) { + goto do_new; + } + return; + +do_new: + duk_push_hobject_bidx(thr, DUK_BIDX_REGEXP_CONSTRUCTOR); + duk_dup(thr, idx); + duk_new(thr, 1); /* [ ... RegExp val ] -> [ ... res ] */ + duk_replace(thr, idx); +} +#endif /* DUK_USE_REGEXP_SUPPORT */ + +#if defined(DUK_USE_REGEXP_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_string_prototype_search(duk_hthread *thr) { + /* Easiest way to implement the search required by the specification + * is to do a RegExp test() with lastIndex forced to zero. To avoid + * side effects on the argument, "clone" the RegExp if a RegExp was + * given as input. + * + * The global flag of the RegExp should be ignored; setting lastIndex + * to zero (which happens when "cloning" the RegExp) should have an + * equivalent effect. + */ + + DUK_ASSERT_TOP(thr, 1); + (void)duk_push_this_coercible_to_string(thr); /* at index 1 */ + duk__to_regexp_helper(thr, 0 /*index*/, 1 /*force_new*/); + + /* stack[0] = regexp + * stack[1] = string + */ + + /* Avoid using RegExp.prototype methods, as they're writable and + * configurable and may have been changed. + */ + + duk_dup_0(thr); + duk_dup_1(thr); /* [ ... re_obj input ] */ + duk_regexp_match(thr); /* -> [ ... res_obj ] */ + + if (!duk_is_object(thr, -1)) { + duk_push_int(thr, -1); + return 1; + } + + duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX); + DUK_ASSERT(duk_is_number(thr, -1)); + return 1; +} +#endif /* DUK_USE_REGEXP_SUPPORT */ + +#if defined(DUK_USE_REGEXP_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_string_prototype_match(duk_hthread *thr) { + duk_bool_t global; + duk_int_t prev_last_index; + duk_int_t this_index; + duk_int_t arr_idx; + + DUK_ASSERT_TOP(thr, 1); + (void)duk_push_this_coercible_to_string(thr); + duk__to_regexp_helper(thr, 0 /*index*/, 0 /*force_new*/); + global = duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL); + DUK_ASSERT_TOP(thr, 2); + + /* stack[0] = regexp + * stack[1] = string + */ + + if (!global) { + duk_regexp_match(thr); /* -> [ res_obj ] */ + return 1; /* return 'res_obj' */ + } + + /* Global case is more complex. */ + + /* [ regexp string ] */ + + duk_push_int(thr, 0); + duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX); + duk_push_array(thr); + + /* [ regexp string res_arr ] */ + + prev_last_index = 0; + arr_idx = 0; + + for (;;) { + DUK_ASSERT_TOP(thr, 3); + + duk_dup_0(thr); + duk_dup_1(thr); + duk_regexp_match(thr); /* -> [ ... regexp string ] -> [ ... res_obj ] */ + + if (!duk_is_object(thr, -1)) { + duk_pop(thr); + break; + } + + duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX); + DUK_ASSERT(duk_is_number(thr, -1)); + this_index = duk_get_int(thr, -1); + duk_pop(thr); + + if (this_index == prev_last_index) { + this_index++; + duk_push_int(thr, this_index); + duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX); + } + prev_last_index = this_index; + + duk_get_prop_index(thr, -1, 0); /* match string */ + duk_put_prop_index(thr, 2, (duk_uarridx_t)arr_idx); + arr_idx++; + duk_pop(thr); /* res_obj */ + } + + if (arr_idx == 0) { + duk_push_null(thr); + } + + return 1; /* return 'res_arr' or 'null' */ +} +#endif /* DUK_USE_REGEXP_SUPPORT */ + +DUK_INTERNAL duk_ret_t duk_bi_string_prototype_concat(duk_hthread *thr) { + /* duk_concat() coerces arguments with ToString() in correct order */ + (void)duk_push_this_coercible_to_string(thr); + duk_insert(thr, 0); /* this is relatively expensive */ + duk_concat(thr, duk_get_top(thr)); + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_string_prototype_trim(duk_hthread *thr) { + DUK_ASSERT_TOP(thr, 0); + (void)duk_push_this_coercible_to_string(thr); + duk_trim(thr, 0); + DUK_ASSERT_TOP(thr, 1); + return 1; +} + +#if defined(DUK_USE_ES6) +DUK_INTERNAL duk_ret_t duk_bi_string_prototype_repeat(duk_hthread *thr) { + duk_hstring *h_input; + duk_size_t input_blen; + duk_size_t result_len; + duk_int_t count_signed; + duk_uint_t count; + const duk_uint8_t *src; + duk_uint8_t *buf; + duk_uint8_t *p; + duk_double_t d; +#if !defined(DUK_USE_PREFER_SIZE) + duk_size_t copy_size; + duk_uint8_t *p_end; +#endif + + DUK_ASSERT_TOP(thr, 1); + h_input = duk_push_this_coercible_to_string(thr); + DUK_ASSERT(h_input != NULL); + input_blen = DUK_HSTRING_GET_BYTELEN(h_input); + + /* Count is ToNumber() coerced; +Infinity must be always rejected + * (even if input string is zero length), as well as negative values + * and -Infinity. -Infinity doesn't require an explicit check + * because duk_get_int() clamps it to DUK_INT_MIN which gets rejected + * as a negative value (regardless of input string length). + */ + d = duk_to_number(thr, 0); + if (duk_double_is_posinf(d)) { + goto fail_range; + } + count_signed = duk_get_int(thr, 0); + if (count_signed < 0) { + goto fail_range; + } + count = (duk_uint_t)count_signed; + + /* Overflow check for result length. */ + result_len = count * input_blen; + if (count != 0 && result_len / count != input_blen) { + goto fail_range; + } + + /* Temporary fixed buffer, later converted to string. */ + buf = (duk_uint8_t *)duk_push_fixed_buffer_nozero(thr, result_len); + DUK_ASSERT(buf != NULL); + src = (const duk_uint8_t *)DUK_HSTRING_GET_DATA(h_input); + DUK_ASSERT(src != NULL); + +#if defined(DUK_USE_PREFER_SIZE) + p = buf; + while (count-- > 0) { + duk_memcpy((void *)p, (const void *)src, + input_blen); /* copy size may be zero, but pointers are valid */ + p += input_blen; + } +#else /* DUK_USE_PREFER_SIZE */ + /* Take advantage of already copied pieces to speed up the process + * especially for small repeated strings. + */ + p = buf; + p_end = p + result_len; + copy_size = input_blen; + for (;;) { + duk_size_t remain = (duk_size_t)(p_end - p); + DUK_DDD(DUK_DDDPRINT( + "remain=%ld, copy_size=%ld, input_blen=%ld, result_len=%ld", + (long)remain, (long)copy_size, (long)input_blen, (long)result_len)); + if (remain <= copy_size) { + /* If result_len is zero, this case is taken and does + * a zero size copy (with valid pointers). + */ + duk_memcpy((void *)p, (const void *)src, remain); + break; + } else { + duk_memcpy((void *)p, (const void *)src, copy_size); + p += copy_size; + } + + src = (const duk_uint8_t *)buf; /* Use buf as source for larger copies. */ + copy_size = (duk_size_t)(p - buf); + } +#endif /* DUK_USE_PREFER_SIZE */ + + /* XXX: It would be useful to be able to create a duk_hstring with + * a certain byte size whose data area wasn't initialized and which + * wasn't in the string table yet. This would allow a string to be + * constructed directly without a buffer temporary and when it was + * finished, it could be injected into the string table. Currently + * this isn't possible because duk_hstrings are only tracked by the + * intern table (they are not in heap_allocated). + */ + + duk_buffer_to_string(thr, -1); /* Safe if input is safe. */ + return 1; + +fail_range: + DUK_DCERROR_RANGE_INVALID_ARGS(thr); +} +#endif /* DUK_USE_ES6 */ + +DUK_INTERNAL duk_ret_t +duk_bi_string_prototype_locale_compare(duk_hthread *thr) { + duk_hstring *h1; + duk_hstring *h2; + duk_size_t h1_len, h2_len, prefix_len; + duk_small_int_t ret = 0; + duk_small_int_t rc; + + /* The current implementation of localeCompare() is simply a codepoint + * by codepoint comparison, implemented with a simple string compare + * because UTF-8 should preserve codepoint ordering (assuming valid + * shortest UTF-8 encoding). + * + * The specification requires that the return value must be related + * to the sort order: e.g. negative means that 'this' comes before + * 'that' in sort order. We assume an ascending sort order. + */ + + /* XXX: could share code with duk_js_ops.c, duk_js_compare_helper */ + + h1 = duk_push_this_coercible_to_string(thr); + DUK_ASSERT(h1 != NULL); + + h2 = duk_to_hstring(thr, 0); + DUK_ASSERT(h2 != NULL); + + h1_len = (duk_size_t)DUK_HSTRING_GET_BYTELEN(h1); + h2_len = (duk_size_t)DUK_HSTRING_GET_BYTELEN(h2); + prefix_len = (h1_len <= h2_len ? h1_len : h2_len); + + rc = (duk_small_int_t)duk_memcmp((const void *)DUK_HSTRING_GET_DATA(h1), + (const void *)DUK_HSTRING_GET_DATA(h2), + (size_t)prefix_len); + + if (rc < 0) { + ret = -1; + goto done; + } else if (rc > 0) { + ret = 1; + goto done; + } + + /* prefix matches, lengths matter now */ + if (h1_len > h2_len) { + ret = 1; + goto done; + } else if (h1_len == h2_len) { + DUK_ASSERT(ret == 0); + goto done; + } + ret = -1; + goto done; + +done: + duk_push_int(thr, (duk_int_t)ret); + return 1; +} + +#if defined(DUK_USE_ES6) +DUK_INTERNAL duk_ret_t +duk_bi_string_prototype_startswith_endswith(duk_hthread *thr) { + duk_int_t magic; + duk_hstring *h; + duk_hstring *h_search; + duk_size_t blen_search; + const duk_uint8_t *p_cmp_start; + duk_bool_t result; + + h = duk_push_this_coercible_to_string(thr); + DUK_ASSERT(h != NULL); + + h_search = duk__str_tostring_notregexp(thr, 0); + DUK_ASSERT(h_search != NULL); + + magic = duk_get_current_magic(thr); + + p_cmp_start = (const duk_uint8_t *)DUK_HSTRING_GET_DATA(h); + blen_search = DUK_HSTRING_GET_BYTELEN(h_search); + + if (duk_is_undefined(thr, 1)) { + if (magic) { + p_cmp_start = p_cmp_start + DUK_HSTRING_GET_BYTELEN(h) - blen_search; + } else { + /* p_cmp_start already OK */ + } + } else { + duk_int_t len; + duk_int_t pos; + + DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= DUK_INT_MAX); + len = (duk_int_t)DUK_HSTRING_GET_CHARLEN(h); + pos = duk_to_int_clamped(thr, 1, 0, len); + DUK_ASSERT(pos >= 0 && pos <= len); + + if (magic) { + p_cmp_start -= + blen_search; /* Conceptually subtracted last, but do already here. */ + } + DUK_ASSERT(pos >= 0 && pos <= len); + + p_cmp_start += + duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t)pos); + } + + /* The main comparison can be done using a memcmp() rather than + * doing codepoint comparisons: for CESU-8 strings there is a + * canonical representation for every codepoint. But we do need + * to deal with the char/byte offset translation to find the + * comparison range. + */ + + result = 0; + if (p_cmp_start >= DUK_HSTRING_GET_DATA(h) && + (duk_size_t)(p_cmp_start - (const duk_uint8_t *)DUK_HSTRING_GET_DATA(h)) + + blen_search <= + DUK_HSTRING_GET_BYTELEN(h)) { + if (duk_memcmp((const void *)p_cmp_start, + (const void *)DUK_HSTRING_GET_DATA(h_search), + (size_t)blen_search) == 0) { + result = 1; + } + } + + duk_push_boolean(thr, result); + return 1; +} +#endif /* DUK_USE_ES6 */ + +#if defined(DUK_USE_ES6) +DUK_INTERNAL duk_ret_t duk_bi_string_prototype_includes(duk_hthread *thr) { + duk_hstring *h; + duk_hstring *h_search; + duk_int_t len; + duk_int_t pos; + + h = duk_push_this_coercible_to_string(thr); + DUK_ASSERT(h != NULL); + + h_search = duk__str_tostring_notregexp(thr, 0); + DUK_ASSERT(h_search != NULL); + + len = (duk_int_t)DUK_HSTRING_GET_CHARLEN(h); + pos = duk_to_int_clamped(thr, 1, 0, len); + DUK_ASSERT(pos >= 0 && pos <= len); + + pos = duk__str_search_shared(thr, h, h_search, pos, 0 /*backwards*/); + duk_push_boolean(thr, pos >= 0); + return 1; +} +#endif /* DUK_USE_ES6 */ +#endif /* DUK_USE_STRING_BUILTIN */ diff --git a/third_party/duktape/duk_bi_symbol.c b/third_party/duktape/duk_bi_symbol.c new file mode 100644 index 00000000..262fa8a3 --- /dev/null +++ b/third_party/duktape/duk_bi_symbol.c @@ -0,0 +1,170 @@ +/* + * Symbol built-in + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_SYMBOL_BUILTIN) + +/* + * Constructor + */ + +DUK_INTERNAL duk_ret_t duk_bi_symbol_constructor_shared(duk_hthread *thr) { + const duk_uint8_t *desc; + duk_size_t len; + duk_uint8_t *buf; + duk_uint8_t *p; + duk_int_t magic; + + magic = duk_get_current_magic(thr); + if (duk_is_undefined(thr, 0) && (magic == 0)) { + /* Symbol() accepts undefined and empty string, but they are + * treated differently. + */ + desc = NULL; + len = 0; + } else { + /* Symbol.for() coerces undefined to 'undefined' */ + desc = (const duk_uint8_t *) duk_to_lstring(thr, 0, &len); + } + + /* Maximum symbol data length: + * +1 initial byte (0x80 or 0x81) + * +len description + * +1 0xff after description, before unique suffix + * +17 autogenerated unique suffix: 'ffffffff-ffffffff' is longest + * +1 0xff after unique suffix for symbols with undefined description + */ + buf = (duk_uint8_t *) duk_push_fixed_buffer(thr, 1 + len + 1 + 17 + 1); + DUK_ASSERT(buf != NULL); + p = buf + 1; + DUK_ASSERT(desc != NULL || len == 0); /* may be NULL if len is 0 */ + duk_memcpy_unsafe((void *) p, (const void *) desc, len); + p += len; + if (magic == 0) { + /* Symbol(): create unique symbol. Use two 32-bit values + * to avoid dependency on 64-bit types and 64-bit integer + * formatting (at least for now). + */ + if (++thr->heap->sym_counter[0] == 0) { + thr->heap->sym_counter[1]++; + } + p += DUK_SPRINTF((char *) p, "\xFF" "%lx-%lx", + (unsigned long) thr->heap->sym_counter[1], + (unsigned long) thr->heap->sym_counter[0]); + if (desc == NULL) { + /* Special case for 'undefined' description, trailing + * 0xff distinguishes from empty string description, + * but needs minimal special case handling elsewhere. + */ + *p++ = 0xff; + } + buf[0] = 0x81; + } else { + /* Symbol.for(): create a global symbol */ + buf[0] = 0x80; + } + + duk_push_lstring(thr, (const char *) buf, (duk_size_t) (p - buf)); + DUK_DDD(DUK_DDDPRINT("created symbol: %!T", duk_get_tval(thr, -1))); + return 1; +} + +DUK_LOCAL duk_hstring *duk__auto_unbox_symbol(duk_hthread *thr, duk_tval *tv_arg) { + duk_tval *tv; + duk_hobject *h_obj; + duk_hstring *h_str; + + DUK_ASSERT(tv_arg != NULL); + + /* XXX: add internal helper: duk_auto_unbox_tval(thr, tv, mask); */ + /* XXX: add internal helper: duk_auto_unbox(thr, tv, idx); */ + + tv = tv_arg; + if (DUK_TVAL_IS_OBJECT(tv)) { + h_obj = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h_obj != NULL); + if (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_SYMBOL) { + tv = duk_hobject_get_internal_value_tval_ptr(thr->heap, h_obj); + if (tv == NULL) { + return NULL; + } + } else { + return NULL; + } + } + + if (!DUK_TVAL_IS_STRING(tv)) { + return NULL; + } + h_str = DUK_TVAL_GET_STRING(tv); + DUK_ASSERT(h_str != NULL); + + /* Here symbol is more expected than not. */ + if (DUK_UNLIKELY(!DUK_HSTRING_HAS_SYMBOL(h_str))) { + return NULL; + } + + return h_str; +} + +DUK_INTERNAL duk_ret_t duk_bi_symbol_tostring_shared(duk_hthread *thr) { + duk_hstring *h_str; + + h_str = duk__auto_unbox_symbol(thr, DUK_HTHREAD_THIS_PTR(thr)); + if (h_str == NULL) { + return DUK_RET_TYPE_ERROR; + } + + if (duk_get_current_magic(thr) == 0) { + /* .toString() */ + duk_push_symbol_descriptive_string(thr, h_str); + } else { + /* .valueOf() */ + duk_push_hstring(thr, h_str); + } + return 1; +} + +DUK_INTERNAL duk_ret_t duk_bi_symbol_key_for(duk_hthread *thr) { + duk_hstring *h; + const duk_uint8_t *p; + + /* Argument must be a symbol but not checked here. The initial byte + * check will catch non-symbol strings. + */ + h = duk_require_hstring(thr, 0); + DUK_ASSERT(h != NULL); + + p = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h); + DUK_ASSERT(p != NULL); + + /* Even for zero length strings there's at least one NUL byte so + * we can safely check the initial byte. + */ + if (p[0] == 0x80) { + /* Global symbol, return its key (bytes just after the initial byte). */ + duk_push_lstring(thr, (const char *) (p + 1), (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h) - 1)); + return 1; + } else if (p[0] == 0x81 || p[0] == 0x82 || p[0] == 0xff) { + /* Local symbol or hidden symbol, return undefined. */ + return 0; + } + + /* Covers normal strings and unknown initial bytes. */ + return DUK_RET_TYPE_ERROR; +} + +DUK_INTERNAL duk_ret_t duk_bi_symbol_toprimitive(duk_hthread *thr) { + duk_hstring *h_str; + + h_str = duk__auto_unbox_symbol(thr, DUK_HTHREAD_THIS_PTR(thr)); + if (h_str == NULL) { + return DUK_RET_TYPE_ERROR; + } + duk_push_hstring(thr, h_str); + return 1; +} + +#endif /* DUK_USE_SYMBOL_BUILTIN */ diff --git a/third_party/duktape/duk_bi_thread.c b/third_party/duktape/duk_bi_thread.c new file mode 100644 index 00000000..37dda74c --- /dev/null +++ b/third_party/duktape/duk_bi_thread.c @@ -0,0 +1,326 @@ +/* + * Thread builtins + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Constructor + */ + +#if defined(DUK_USE_COROUTINE_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_thread_constructor(duk_hthread *thr) { + duk_hthread *new_thr; + duk_hobject *func; + + /* Check that the argument is callable; this is not 100% because we + * don't allow native functions to be a thread's initial function. + * Resume will reject such functions in any case. + */ + /* XXX: need a duk_require_func_promote_lfunc() */ + func = duk_require_hobject_promote_lfunc(thr, 0); + DUK_ASSERT(func != NULL); + duk_require_callable(thr, 0); + + duk_push_thread(thr); + new_thr = (duk_hthread *) duk_known_hobject(thr, -1); + new_thr->state = DUK_HTHREAD_STATE_INACTIVE; + + /* push initial function call to new thread stack; this is + * picked up by resume(). + */ + duk_push_hobject(new_thr, func); + + return 1; /* return thread */ +} +#endif + +/* + * Resume a thread. + * + * The thread must be in resumable state, either (a) new thread which hasn't + * yet started, or (b) a thread which has previously yielded. This method + * must be called from an ECMAScript function. + * + * Args: + * - thread + * - value + * - isError (defaults to false) + * + * Note: yield and resume handling is currently asymmetric. + */ + +#if defined(DUK_USE_COROUTINE_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_hthread *ctx) { + duk_hthread *thr = (duk_hthread *) ctx; + duk_hthread *thr_resume; + duk_hobject *caller_func; + duk_small_uint_t is_error; + + DUK_DDD(DUK_DDDPRINT("Duktape.Thread.resume(): thread=%!T, value=%!T, is_error=%!T", + (duk_tval *) duk_get_tval(thr, 0), + (duk_tval *) duk_get_tval(thr, 1), + (duk_tval *) duk_get_tval(thr, 2))); + + DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING); + DUK_ASSERT(thr->heap->curr_thread == thr); + + thr_resume = duk_require_hthread(thr, 0); + DUK_ASSERT(duk_get_top(thr) == 3); + is_error = (duk_small_uint_t) duk_to_boolean_top_pop(thr); + DUK_ASSERT(duk_get_top(thr) == 2); + + /* [ thread value ] */ + + /* + * Thread state and calling context checks + */ + + if (thr->callstack_top < 2) { + DUK_DD(DUK_DDPRINT("resume state invalid: callstack should contain at least 2 entries (caller and Duktape.Thread.resume)")); + goto state_error; + } + DUK_ASSERT(thr->callstack_curr != NULL); + DUK_ASSERT(thr->callstack_curr->parent != NULL); + DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL); /* us */ + DUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr))); + DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL); /* caller */ + + caller_func = DUK_ACT_GET_FUNC(thr->callstack_curr->parent); + if (!DUK_HOBJECT_IS_COMPFUNC(caller_func)) { + DUK_DD(DUK_DDPRINT("resume state invalid: caller must be ECMAScript code")); + goto state_error; + } + + /* Note: there is no requirement that: 'thr->callstack_preventcount == 1' + * like for yield. + */ + + if (thr_resume->state != DUK_HTHREAD_STATE_INACTIVE && + thr_resume->state != DUK_HTHREAD_STATE_YIELDED) { + DUK_DD(DUK_DDPRINT("resume state invalid: target thread must be INACTIVE or YIELDED")); + goto state_error; + } + + DUK_ASSERT(thr_resume->state == DUK_HTHREAD_STATE_INACTIVE || + thr_resume->state == DUK_HTHREAD_STATE_YIELDED); + + /* Further state-dependent pre-checks */ + + if (thr_resume->state == DUK_HTHREAD_STATE_YIELDED) { + /* no pre-checks now, assume a previous yield() has left things in + * tip-top shape (longjmp handler will assert for these). + */ + } else { + duk_hobject *h_fun; + + DUK_ASSERT(thr_resume->state == DUK_HTHREAD_STATE_INACTIVE); + + /* The initial function must be an ECMAScript function (but + * can be bound). We must make sure of that before we longjmp + * because an error in the RESUME handler call processing will + * not be handled very cleanly. + */ + if ((thr_resume->callstack_top != 0) || + (thr_resume->valstack_top - thr_resume->valstack != 1)) { + goto state_error; + } + + duk_push_tval(thr, DUK_GET_TVAL_NEGIDX(thr_resume, -1)); + duk_resolve_nonbound_function(thr); + h_fun = duk_require_hobject(thr, -1); /* reject lightfuncs on purpose */ + if (!DUK_HOBJECT_IS_CALLABLE(h_fun) || !DUK_HOBJECT_IS_COMPFUNC(h_fun)) { + goto state_error; + } + duk_pop(thr); + } + +#if 0 + /* This check would prevent a heap destruction time finalizer from + * launching a coroutine, which would ensure that during finalization + * 'thr' would always equal heap_thread. Normal runtime finalizers + * run with ms_running == 0, i.e. outside mark-and-sweep. See GH-2030. + */ + if (thr->heap->ms_running) { + DUK_D(DUK_DPRINT("refuse Duktape.Thread.resume() when ms_running != 0")); + goto state_error; + } +#endif + + /* + * The error object has been augmented with a traceback and other + * info from its creation point -- usually another thread. The + * error handler is called here right before throwing, but it also + * runs in the resumer's thread. It might be nice to get a traceback + * from the resumee but this is not the case now. + */ + +#if defined(DUK_USE_AUGMENT_ERROR_THROW) + if (is_error) { + DUK_ASSERT_TOP(thr, 2); /* value (error) is at stack top */ + duk_err_augment_error_throw(thr); /* in resumer's context */ + } +#endif + +#if defined(DUK_USE_DEBUG) + if (is_error) { + DUK_DDD(DUK_DDDPRINT("RESUME ERROR: thread=%!T, value=%!T", + (duk_tval *) duk_get_tval(thr, 0), + (duk_tval *) duk_get_tval(thr, 1))); + } else if (thr_resume->state == DUK_HTHREAD_STATE_YIELDED) { + DUK_DDD(DUK_DDDPRINT("RESUME NORMAL: thread=%!T, value=%!T", + (duk_tval *) duk_get_tval(thr, 0), + (duk_tval *) duk_get_tval(thr, 1))); + } else { + DUK_DDD(DUK_DDDPRINT("RESUME INITIAL: thread=%!T, value=%!T", + (duk_tval *) duk_get_tval(thr, 0), + (duk_tval *) duk_get_tval(thr, 1))); + } +#endif + + thr->heap->lj.type = DUK_LJ_TYPE_RESUME; + + /* lj value2: thread */ + DUK_ASSERT(thr->valstack_bottom < thr->valstack_top); + DUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value2, &thr->valstack_bottom[0]); /* side effects */ + + /* lj value1: value */ + DUK_ASSERT(thr->valstack_bottom + 1 < thr->valstack_top); + DUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1, &thr->valstack_bottom[1]); /* side effects */ + DUK_TVAL_CHKFAST_INPLACE_SLOW(&thr->heap->lj.value1); + + thr->heap->lj.iserror = is_error; + + DUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL); /* call is from executor, so we know we have a jmpbuf */ + duk_err_longjmp(thr); /* execution resumes in bytecode executor */ + DUK_UNREACHABLE(); + /* Never here, fall through to error (from compiler point of view). */ + + state_error: + DUK_DCERROR_TYPE_INVALID_STATE(thr); +} +#endif + +/* + * Yield the current thread. + * + * The thread must be in yieldable state: it must have a resumer, and there + * must not be any yield-preventing calls (native calls and constructor calls, + * currently) in the thread's call stack (otherwise a resume would not be + * possible later). This method must be called from an ECMAScript function. + * + * Args: + * - value + * - isError (defaults to false) + * + * Note: yield and resume handling is currently asymmetric. + */ + +#if defined(DUK_USE_COROUTINE_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_hthread *thr) { + duk_hobject *caller_func; + duk_small_uint_t is_error; + + DUK_DDD(DUK_DDDPRINT("Duktape.Thread.yield(): value=%!T, is_error=%!T", + (duk_tval *) duk_get_tval(thr, 0), + (duk_tval *) duk_get_tval(thr, 1))); + + DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING); + DUK_ASSERT(thr->heap->curr_thread == thr); + + DUK_ASSERT(duk_get_top(thr) == 2); + is_error = (duk_small_uint_t) duk_to_boolean_top_pop(thr); + DUK_ASSERT(duk_get_top(thr) == 1); + + /* [ value ] */ + + /* + * Thread state and calling context checks + */ + + if (!thr->resumer) { + DUK_DD(DUK_DDPRINT("yield state invalid: current thread must have a resumer")); + goto state_error; + } + DUK_ASSERT(thr->resumer->state == DUK_HTHREAD_STATE_RESUMED); + + if (thr->callstack_top < 2) { + DUK_DD(DUK_DDPRINT("yield state invalid: callstack should contain at least 2 entries (caller and Duktape.Thread.yield)")); + goto state_error; + } + DUK_ASSERT(thr->callstack_curr != NULL); + DUK_ASSERT(thr->callstack_curr->parent != NULL); + DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL); /* us */ + DUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr))); + DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL); /* caller */ + + caller_func = DUK_ACT_GET_FUNC(thr->callstack_curr->parent); + if (!DUK_HOBJECT_IS_COMPFUNC(caller_func)) { + DUK_DD(DUK_DDPRINT("yield state invalid: caller must be ECMAScript code")); + goto state_error; + } + + DUK_ASSERT(thr->callstack_preventcount >= 1); /* should never be zero, because we (Duktape.Thread.yield) are on the stack */ + if (thr->callstack_preventcount != 1) { + /* Note: the only yield-preventing call is Duktape.Thread.yield(), hence check for 1, not 0 */ + DUK_DD(DUK_DDPRINT("yield state invalid: there must be no yield-preventing calls in current thread callstack (preventcount is %ld)", + (long) thr->callstack_preventcount)); + goto state_error; + } + + /* + * The error object has been augmented with a traceback and other + * info from its creation point -- usually the current thread. + * The error handler, however, is called right before throwing + * and runs in the yielder's thread. + */ + +#if defined(DUK_USE_AUGMENT_ERROR_THROW) + if (is_error) { + DUK_ASSERT_TOP(thr, 1); /* value (error) is at stack top */ + duk_err_augment_error_throw(thr); /* in yielder's context */ + } +#endif + +#if defined(DUK_USE_DEBUG) + if (is_error) { + DUK_DDD(DUK_DDDPRINT("YIELD ERROR: value=%!T", + (duk_tval *) duk_get_tval(thr, 0))); + } else { + DUK_DDD(DUK_DDDPRINT("YIELD NORMAL: value=%!T", + (duk_tval *) duk_get_tval(thr, 0))); + } +#endif + + /* + * Process yield + * + * After longjmp(), processing continues in bytecode executor longjmp + * handler, which will e.g. update thr->resumer to NULL. + */ + + thr->heap->lj.type = DUK_LJ_TYPE_YIELD; + + /* lj value1: value */ + DUK_ASSERT(thr->valstack_bottom < thr->valstack_top); + DUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1, &thr->valstack_bottom[0]); /* side effects */ + DUK_TVAL_CHKFAST_INPLACE_SLOW(&thr->heap->lj.value1); + + thr->heap->lj.iserror = is_error; + + DUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL); /* call is from executor, so we know we have a jmpbuf */ + duk_err_longjmp(thr); /* execution resumes in bytecode executor */ + DUK_UNREACHABLE(); + /* Never here, fall through to error (from compiler point of view). */ + + state_error: + DUK_DCERROR_TYPE_INVALID_STATE(thr); +} +#endif + +#if defined(DUK_USE_COROUTINE_SUPPORT) +DUK_INTERNAL duk_ret_t duk_bi_thread_current(duk_hthread *thr) { + duk_push_current_thread(thr); + return 1; +} +#endif diff --git a/third_party/duktape/duk_bi_thrower.c b/third_party/duktape/duk_bi_thrower.c new file mode 100644 index 00000000..a97c1731 --- /dev/null +++ b/third_party/duktape/duk_bi_thrower.c @@ -0,0 +1,9 @@ +/* + * Type error thrower, E5 Section 13.2.3. + */ + +#include "third_party/duktape/duk_internal.h" + +DUK_INTERNAL duk_ret_t duk_bi_type_error_thrower(duk_hthread *thr) { + DUK_DCERROR_TYPE_INVALID_ARGS(thr); +} diff --git a/third_party/duktape/duk_builtins.c b/third_party/duktape/duk_builtins.c new file mode 100644 index 00000000..4340d4ff --- /dev/null +++ b/third_party/duktape/duk_builtins.c @@ -0,0 +1,861 @@ +/* + * Automatically generated by genbuiltins.py, do not edit! + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_ASSERTIONS) +#define DUK__REFCINIT(refc) 0 /*h_assert_refcount*/, (refc) /*actual*/ +#else +#define DUK__REFCINIT(refc) (refc) /*actual*/ +#endif + +#if defined(DUK_USE_ROM_STRINGS) +#error ROM support not enabled, rerun configure.py with --rom-support +#else /* DUK_USE_ROM_STRINGS */ +DUK_INTERNAL const duk_uint8_t duk_strings_data[972] = { +79,40,209,144,168,105,6,78,54,139,89,185,44,48,46,90,120,8,154,140,35,103, +35,113,193,73,5,52,112,180,104,166,135,52,188,4,98,12,27,146,156,80,211,31, +129,115,150,64,52,220,109,24,18,68,156,24,38,67,114,36,55,9,119,151,132, +140,93,18,113,128,153,201,212,201,205,2,248,8,196,24,224,104,82,146,40,224, +193,48,114,168,37,147,196,54,123,28,4,98,12,43,148,67,103,177,192,70,32, +196,121,68,54,123,28,18,192,199,144,124,4,98,12,43,136,108,244,117,184,8, +196,24,95,40,134,207,71,91,128,140,65,133,113,13,158,158,151,1,24,131,11, +229,16,217,233,233,112,17,136,48,206,21,110,4,244,244,184,8,196,24,103,10, +183,2,122,218,156,4,98,12,24,203,112,64,179,113,193,79,8,218,155,131,32, +184,70,212,220,13,10,82,68,252,123,144,217,146,38,228,207,18,0,100,37,64, +178,212,11,161,17,104,162,96,10,200,193,57,165,65,169,16,5,100,81,27,70,18, +32,10,200,68,185,13,116,221,197,184,64,89,57,41,197,13,49,234,5,208,156, +113,87,55,118,147,20,187,56,161,166,92,221,212,73,210,236,226,134,153,115, +119,76,201,203,179,138,26,99,73,212,136,136,164,25,174,137,56,32,72,137, +101,23,52,45,13,34,86,9,79,136,104,201,114,149,96,52,138,134,140,151,75, +226,233,186,120,121,22,39,54,83,141,5,55,68,236,36,164,3,16,225,115,150,64, +52,205,163,2,72,154,83,138,26,99,75,12,11,150,103,5,36,20,211,70,140,133, +67,72,49,241,160,227,81,196,52,168,106,39,132,252,183,136,105,80,212,79,2, +249,110,128,126,88,95,133,109,237,237,237,151,235,127,46,249,119,203,190, +186,206,33,181,2,208,61,190,12,19,34,65,19,81,132,108,228,97,1,107,33,12, +32,45,100,137,64,247,175,9,19,155,41,198,130,155,134,69,146,100,227,226, +231,146,51,192,204,73,140,224,145,221,102,241,68,196,169,248,30,75,12,11, +151,242,233,187,143,138,24,137,162,164,255,253,63,3,201,97,129,114,254,92, +112,75,136,108,166,6,136,159,255,167,224,121,44,48,46,95,203,166,238,74, +113,67,77,201,128,223,255,223,224,121,44,48,46,95,203,145,46,9,205,16,39, +201,62,36,0,192,21,147,255,238,145,39,199,197,211,116,240,242,113,197,78, +214,211,226,233,187,107,105,19,119,37,56,161,166,52,221,212,201,205,36,240, +242,16,96,152,12,26,20,164,137,150,70,154,103,28,137,50,202,96,18,132,241, +41,104,105,56,218,48,36,138,183,57,56,128,68,24,38,2,52,12,34,10,133,147, +141,3,8,119,185,13,153,34,125,206,76,17,49,38,93,206,52,151,154,119,56,28, +76,130,112,200,141,206,21,209,96,23,35,238,114,160,139,0,243,238,114,78, +164,68,68,110,113,226,210,90,26,66,110,113,128,121,247,57,80,68,141,170, +183,56,84,52,11,70,73,19,110,114,160,93,8,113,57,143,66,200,84,53,244,154, +73,24,240,81,32,38,68,18,49,228,207,23,88,100,109,70,114,92,193,4,137,173, +168,36,220,73,19,247,247,182,168,209,144,187,223,58,156,104,79,190,183,127, +123,105,160,110,247,206,167,26,19,239,173,223,222,218,67,75,189,243,169, +198,132,251,235,183,247,182,154,134,151,123,231,83,141,9,247,215,111,239, +109,22,141,22,247,206,167,26,19,239,172,223,218,45,26,47,157,78,52,39,223, +74,24,144,10,32,129,34,20,64,152,142,129,57,179,67,104,68,12,129,161,140, +72,156,100,40,40,185,152,100,89,38,65,13,196,34,228,67,149,13,2,215,129, +149,209,65,104,209,77,14,104,144,81,33,170,67,101,48,52,68,113,70,210,88, +209,36,233,22,154,86,68,196,114,76,232,145,102,120,186,195,156,112,105,225, +228,113,71,80,68,162,115,101,50,85,200,25,108,116,44,132,178,38,114,137,96, +148,136,70,209,134,37,222,232,204,228,188,200,209,200,200,99,221,25,150,84, +121,34,70,209,107,36,227,66,20,160,92,136,164,49,235,35,8,217,201,40,108, +201,18,128,68,26,201,51,188,2,80,12,67,190,40,168,38,68,190,46,153,5,50,12, +207,160,86,129,26,83,4,208,34,225,4,88,192, +}; +#endif /* DUK_USE_ROM_STRINGS */ + +#if defined(DUK_USE_ROM_OBJECTS) +#error ROM support not enabled, rerun configure.py with --rom-support +#else /* DUK_USE_ROM_OBJECTS */ +/* native functions: 185 */ +DUK_INTERNAL const duk_c_function duk_bi_native_functions[185] = { + NULL, + duk_bi_array_constructor, + duk_bi_array_constructor_is_array, + duk_bi_array_prototype_concat, + duk_bi_array_prototype_indexof_shared, + duk_bi_array_prototype_iter_shared, + duk_bi_array_prototype_join_shared, + duk_bi_array_prototype_pop, + duk_bi_array_prototype_push, + duk_bi_array_prototype_reduce_shared, + duk_bi_array_prototype_reverse, + duk_bi_array_prototype_shift, + duk_bi_array_prototype_slice, + duk_bi_array_prototype_sort, + duk_bi_array_prototype_splice, + duk_bi_array_prototype_to_string, + duk_bi_array_prototype_unshift, + duk_bi_arraybuffer_constructor, + duk_bi_arraybuffer_isview, + duk_bi_boolean_constructor, + duk_bi_boolean_prototype_tostring_shared, + duk_bi_buffer_compare_shared, + duk_bi_buffer_readfield, + duk_bi_buffer_slice_shared, + duk_bi_buffer_writefield, + duk_bi_cbor_decode, + duk_bi_cbor_encode, + duk_bi_dataview_constructor, + duk_bi_date_constructor, + duk_bi_date_constructor_now, + duk_bi_date_constructor_parse, + duk_bi_date_constructor_utc, + duk_bi_date_prototype_get_shared, + duk_bi_date_prototype_get_timezone_offset, + duk_bi_date_prototype_set_shared, + duk_bi_date_prototype_set_time, + duk_bi_date_prototype_to_json, + duk_bi_date_prototype_toprimitive, + duk_bi_date_prototype_tostring_shared, + duk_bi_date_prototype_value_of, + duk_bi_duktape_object_act, + duk_bi_duktape_object_compact, + duk_bi_duktape_object_dec, + duk_bi_duktape_object_enc, + duk_bi_duktape_object_fin, + duk_bi_duktape_object_gc, + duk_bi_duktape_object_info, + duk_bi_error_constructor_shared, + duk_bi_error_prototype_filename_getter, + duk_bi_error_prototype_filename_setter, + duk_bi_error_prototype_linenumber_getter, + duk_bi_error_prototype_linenumber_setter, + duk_bi_error_prototype_stack_getter, + duk_bi_error_prototype_stack_setter, + duk_bi_error_prototype_to_string, + duk_bi_function_constructor, + duk_bi_function_prototype, + duk_bi_function_prototype_apply, + duk_bi_function_prototype_bind, + duk_bi_function_prototype_call, + duk_bi_function_prototype_hasinstance, + duk_bi_function_prototype_to_string, + duk_bi_global_object_decode_uri, + duk_bi_global_object_decode_uri_component, + duk_bi_global_object_encode_uri, + duk_bi_global_object_encode_uri_component, + duk_bi_global_object_escape, + duk_bi_global_object_eval, + duk_bi_global_object_is_finite, + duk_bi_global_object_is_nan, + duk_bi_global_object_parse_float, + duk_bi_global_object_parse_int, + duk_bi_global_object_unescape, + duk_bi_json_object_parse, + duk_bi_json_object_stringify, + duk_bi_math_object_clz32, + duk_bi_math_object_hypot, + duk_bi_math_object_imul, + duk_bi_math_object_max, + duk_bi_math_object_min, + duk_bi_math_object_onearg_shared, + duk_bi_math_object_random, + duk_bi_math_object_sign, + duk_bi_math_object_twoarg_shared, + duk_bi_native_function_length, + duk_bi_native_function_name, + duk_bi_nodejs_buffer_byte_length, + duk_bi_nodejs_buffer_concat, + duk_bi_nodejs_buffer_constructor, + duk_bi_nodejs_buffer_copy, + duk_bi_nodejs_buffer_fill, + duk_bi_nodejs_buffer_is_buffer, + duk_bi_nodejs_buffer_is_encoding, + duk_bi_nodejs_buffer_tojson, + duk_bi_nodejs_buffer_tostring, + duk_bi_nodejs_buffer_write, + duk_bi_number_check_shared, + duk_bi_number_constructor, + duk_bi_number_prototype_to_exponential, + duk_bi_number_prototype_to_fixed, + duk_bi_number_prototype_to_locale_string, + duk_bi_number_prototype_to_precision, + duk_bi_number_prototype_to_string, + duk_bi_number_prototype_value_of, + duk_bi_object_constructor, + duk_bi_object_constructor_assign, + duk_bi_object_constructor_create, + duk_bi_object_constructor_define_properties, + duk_bi_object_constructor_define_property, + duk_bi_object_constructor_get_own_property_descriptor, + duk_bi_object_constructor_is, + duk_bi_object_constructor_is_extensible, + duk_bi_object_constructor_is_sealed_frozen_shared, + duk_bi_object_constructor_keys_shared, + duk_bi_object_constructor_prevent_extensions, + duk_bi_object_constructor_seal_freeze_shared, + duk_bi_object_getprototype_shared, + duk_bi_object_prototype_defineaccessor, + duk_bi_object_prototype_has_own_property, + duk_bi_object_prototype_is_prototype_of, + duk_bi_object_prototype_lookupaccessor, + duk_bi_object_prototype_property_is_enumerable, + duk_bi_object_prototype_to_locale_string, + duk_bi_object_prototype_to_string, + duk_bi_object_prototype_value_of, + duk_bi_object_setprototype_shared, + duk_bi_performance_now, + duk_bi_pointer_constructor, + duk_bi_pointer_prototype_tostring_shared, + duk_bi_proxy_constructor, + duk_bi_reflect_apply, + duk_bi_reflect_construct, + duk_bi_reflect_object_delete_property, + duk_bi_reflect_object_get, + duk_bi_reflect_object_has, + duk_bi_reflect_object_set, + duk_bi_regexp_constructor, + duk_bi_regexp_prototype_exec, + duk_bi_regexp_prototype_flags, + duk_bi_regexp_prototype_shared_getter, + duk_bi_regexp_prototype_test, + duk_bi_regexp_prototype_tostring, + duk_bi_string_constructor, + duk_bi_string_constructor_from_char_code, + duk_bi_string_constructor_from_code_point, + duk_bi_string_prototype_caseconv_shared, + duk_bi_string_prototype_char_at, + duk_bi_string_prototype_char_code_at, + duk_bi_string_prototype_concat, + duk_bi_string_prototype_includes, + duk_bi_string_prototype_indexof_shared, + duk_bi_string_prototype_locale_compare, + duk_bi_string_prototype_match, + duk_bi_string_prototype_repeat, + duk_bi_string_prototype_replace, + duk_bi_string_prototype_search, + duk_bi_string_prototype_slice, + duk_bi_string_prototype_split, + duk_bi_string_prototype_startswith_endswith, + duk_bi_string_prototype_substr, + duk_bi_string_prototype_substring, + duk_bi_string_prototype_to_string, + duk_bi_string_prototype_trim, + duk_bi_symbol_constructor_shared, + duk_bi_symbol_key_for, + duk_bi_symbol_toprimitive, + duk_bi_symbol_tostring_shared, + duk_bi_textdecoder_constructor, + duk_bi_textdecoder_prototype_decode, + duk_bi_textdecoder_prototype_shared_getter, + duk_bi_textencoder_constructor, + duk_bi_textencoder_prototype_encode, + duk_bi_textencoder_prototype_encoding_getter, + duk_bi_thread_constructor, + duk_bi_thread_current, + duk_bi_thread_resume, + duk_bi_thread_yield, + duk_bi_type_error_thrower, + duk_bi_typedarray_buffer_getter, + duk_bi_typedarray_bytelength_getter, + duk_bi_typedarray_byteoffset_getter, + duk_bi_typedarray_constructor, + duk_bi_typedarray_set, + duk_bi_uint8array_allocplain, + duk_bi_uint8array_plainof, +}; +#if defined(DUK_USE_DOUBLE_LE) +DUK_INTERNAL const duk_uint8_t duk_builtins_data[4281] = { +144,148,105,226,32,68,52,228,254,12,104,202,37,132,52,167,194,138,105,245, +124,57,28,211,57,18,64,52,239,126,44,138,111,175,241,164,19,87,145,30,33, +167,22,145,159,8,211,139,9,225,42,5,240,145,139,163,163,8,211,139,10,228, +64,211,19,132,140,93,29,56,70,156,88,119,34,66,146,36,104,137,194,70,46, +142,172,35,78,44,47,146,195,102,11,240,145,139,163,175,8,211,139,9,228,240, +242,112,145,139,163,179,8,211,139,8,237,34,130,118,49,116,118,225,26,48,0, +1,98,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132, +33,8,66,26,180,105,97,167,68,150,34,33,154,112,0,1,91,247,35,79,111,237, +198,174,232,47,31,23,95,17,13,31,249,96,211,49,50,53,214,77,141,24,0,0,181, +10,228,240,242,15,128,140,65,128,134,188,0,0,90,167,97,181,224,0,2,213,62, +53,224,0,2,213,66,237,120,0,0,181,81,204,107,192,0,5,170,150,67,94,0,0,45, +84,245,90,240,0,1,106,169,162,215,128,0,11,85,93,150,188,0,0,90,171,111,53, +109,22,162,26,48,0,1,84,23,201,146,243,225,26,39,12,145,136,104,192,0,5,61, +11,228,201,121,240,100,19,134,72,196,33,195,14,40,203,112,64,190,76,232, +145,153,136,0,0,0,0,0,0,31,15,249,152,0,0,0,0,0,0,30,15,249,120,144,13,96, +155,194,56,80,206,36,67,141,20,228,70,57,81,206,100,131,156,39,132,168,23, +194,70,46,137,208,21,200,129,166,39,9,24,186,39,72,119,34,66,146,36,104, +137,194,70,46,137,212,23,201,97,179,5,248,72,197,209,58,194,121,60,60,156, +36,98,232,157,129,29,164,80,78,198,46,137,218,146,121,25,71,146,9,209,5, +209,61,48,126,14,138,152,30,67,186,23,143,139,175,131,202,135,228,72,85, +144,83,60,179,30,94,209,233,102,30,98,105,230,103,30,114,121,231,104,30, +122,137,231,233,30,130,153,232,106,30,138,169,232,235,30,144,67,193,25,19, +136,108,207,30,41,224,140,137,194,173,192,153,228,5,242,100,188,248,70,137, +195,36,79,78,47,147,37,231,193,144,78,25,34,122,145,111,36,74,232,176,13, +17,61,234,226,93,207,148,160,84,75,141,7,27,161,32,33,18,225,80,212,76,154, +2,2,70,65,56,100,237,34,140,209,2,67,32,156,50,118,145,64,186,230,61,205, +35,103,155,32,36,141,19,134,78,210,40,206,16,36,70,137,195,39,105,20,11, +174,99,220,210,54,121,210,1,137,33,1,228,207,16,17,70,146,66,3,201,164,32, +0,65,112,152,56,196,159,31,23,77,211,195,201,199,23,160,72,214,246,81,6,12, +73,241,214,111,31,23,60,145,158,56,50,72,81,67,230,232,242,80,19,49,39,199, +89,188,124,92,242,70,120,227,64,194,75,154,72,12,9,73,6,111,21,120,12,40, +144,19,39,25,0,225,144,168,105,56,248,185,228,140,241,200,96,64,100,42,26, +78,62,46,121,35,52,18,92,116,1,36,64,47,158,64,49,98,66,100,156,242,65,23, +196,149,35,103,194,94,100,108,144,230,203,156,64,66,37,201,16,11,32,249, +132,4,34,92,44,93,146,55,152,72,24,137,112,151,153,27,36,5,100,229,144,8, +162,98,92,210,5,76,73,241,214,111,31,23,60,145,158,57,44,48,46,92,185,164, +160,72,151,41,0,50,107,179,244,59,36,93,127,92,6,19,172,3,11,216,0,56,224, +151,29,102,241,241,115,201,25,227,164,64,106,37,199,197,211,116,240,242, +113,197,233,144,40,248,185,228,140,241,196,75,132,109,24,72,128,43,39,84, +129,13,173,161,144,168,105,56,98,78,100,142,214,215,69,1,13,173,161,144, +168,105,57,34,78,100,142,214,215,69,16,67,107,105,110,114,168,254,24,147, +153,35,181,181,212,32,67,107,105,110,114,168,254,72,147,153,35,181,181,212, +36,65,130,3,144,8,26,252,200,13,30,85,16,16,64,90,242,231,192,64,161,163, +203,31,26,172,193,17,4,23,105,159,96,27,172,251,16,32,196,4,14,137,112,17, +136,48,164,28,134,80,215,202,1,132,130,8,12,39,52,64,155,31,24,56,36,1,189, +207,132,0,35,233,35,195,62,3,196,149,36,100,72,160,2,200,232,44,227,0,11, +37,160,68,142,128,36,157,25,200,32,26,79,90,4,73,43,192,122,54,71,65,103, +44,248,14,134,140,151,227,138,231,208,45,96,148,248,134,140,151,227,138, +231,240,1,255,254,10,74,146,56,128,104,4,147,152,72,6,144,28,174,143,8,1, +30,1,165,3,96,31,0,211,3,21,11,153,35,0,211,131,68,131,160,137,16,250,5, +196,131,160,137,200,160,199,156,67,248,0,255,255,65,140,10,48,177,115,56, +35,130,60,19,134,79,89,240,52,177,115,56,39,12,156,123,144,217,251,15,135, +34,167,30,20,170,154,255,232,12,47,244,0,97,28,17,224,39,238,32,40,71,4, +120,39,12,156,4,253,228,5,137,195,39,30,228,54,124,4,253,228,128,194,115, +68,9,252,15,128,232,104,201,126,56,191,35,64,90,193,41,241,13,25,47,199,23, +228,105,3,86,225,1,100,224,156,199,130,36,249,144,10,192,76,71,250,16,15, +18,61,96,17,62,200,3,72,128,136,143,247,32,22,75,64,137,248,64,22,79,90,39, +249,64,38,84,12,167,20,52,223,196,2,230,238,45,214,36,120,32,72,158,208,4, +102,238,45,194,2,201,197,186,196,143,4,9,19,218,0,92,221,202,61,228,143,4, +9,19,218,8,35,55,113,110,16,22,78,81,239,36,120,32,72,158,208,64,73,197,12, +255,0,13,18,60,128,159,212,128,169,76,17,156,185,100,76,255,163,64,65,26, +57,114,200,153,255,70,144,33,13,18,232,50,75,226,104,6,149,3,41,199,246, +130,12,128,28,142,156,120,203,175,158,8,194,207,1,6,81,20,79,88,11,237,84, +11,161,32,127,255,255,255,255,255,247,191,137,235,16,221,170,129,116,36,0, +16,0,0,0,0,0,0,12,196,0,0,0,0,0,0,15,135,242,61,123,164,137,162,164,218,67, +74,134,162,120,128,0,0,0,0,0,1,224,254,71,173,33,129,52,84,155,72,105,80, +212,79,16,0,0,0,0,0,0,60,63,195,244,143,146,22,230,192,0,0,0,0,0,0,176,60, +33,214,2,251,82,1,73,180,134,204,134,36,96,127,255,255,255,255,255,159,161, +144,235,16,221,169,0,164,218,67,102,67,18,48,63,255,255,255,255,255,207, +240,196,60,17,145,56,134,204,241,226,158,8,200,156,42,220,9,158,65,196,34, +92,42,26,137,147,120,64,74,37,196,54,100,49,35,188,36,5,68,184,208,113,187, +194,80,212,75,146,1,73,196,54,100,49,35,188,38,57,37,56,240,0,0,0,0,0,0,0, +0,32,235,248,68,48,156,2,24,94,24,0,243,119,10,139,144,123,242,3,102,238, +18,239,115,72,217,160,11,223,16,23,55,113,241,32,145,36,57,188,18,16,102,3, +5,120,35,34,89,32,15,180,152,173,127,0,218,235,88,0,228,180,227,200,0,0,0, +0,0,0,248,127,197,107,240,64,6,77,220,24,38,78,74,113,67,77,130,4,12,155, +185,52,48,156,148,226,134,155,4,10,194,96,129,132,166,238,45,194,2,201,193, +130,100,228,167,20,52,216,32,113,41,187,139,112,128,178,114,104,97,57,41, +197,13,54,8,32,48,216,32,130,195,224,130,19,97,124,134,23,6,0,57,137,62,77, +12,38,12,0,179,18,124,45,22,190,96,128,141,176,134,28,98,79,180,152,139, +218,45,124,193,1,27,97,16,32,196,159,24,230,204,246,194,40,89,137,62,210, +98,103,92,217,158,216,70,7,49,39,193,130,100,182,17,194,140,73,246,147,16, +250,9,146,216,72,6,49,39,193,131,22,194,72,73,137,62,210,98,31,65,139,97, +40,32,196,159,14,234,70,86,194,88,89,137,62,210,98,63,93,72,202,216,76,10, +49,39,198,33,180,153,37,108,38,134,152,147,237,38,38,117,13,164,201,43,97, +56,40,196,159,36,65,57,163,149,176,158,26,98,79,180,152,165,210,9,205,28, +173,133,0,243,18,124,98,22,180,72,130,115,71,43,97,68,72,196,159,105,49,51, +168,90,209,34,9,205,28,173,133,33,19,18,124,154,24,76,185,164,227,138,89, +18,119,0,7,145,39,201,161,132,188,64,124,137,62,49,11,90,36,65,57,163,149, +210,166,37,34,79,180,152,153,212,45,104,145,4,230,142,87,74,160,84,137,62, +72,130,115,71,43,171,234,134,200,147,237,38,41,116,130,115,71,43,171,235,5, +72,147,227,16,218,76,146,186,254,184,108,137,62,210,98,103,80,218,76,146, +186,254,192,68,137,62,29,212,140,174,207,178,23,34,79,180,152,143,215,82, +50,187,62,208,60,137,62,12,19,37,210,182,21,34,79,180,152,135,208,76,151, +74,224,68,137,62,49,205,153,238,175,186,23,34,79,180,152,153,215,54,103, +186,190,240,92,137,62,22,139,95,48,64,70,235,251,225,210,36,251,73,136,189, +162,215,204,16,17,186,255,2,14,98,79,152,32,35,108,48,64,242,36,249,130,2, +55,75,6,212,224,72,200,51,128,114,108,28,100,128,0,0,0,0,0,0,0,12,110,127, +48,98,115,249,201,117,243,249,195,21,159,206,38,47,63,156,86,8,75,144,94, +82,1,38,73,79,208,67,95,233,1,6,128,14,79,129,186,40,249,18,149,182,207, +144,200,155,188,248,204,105,184,207,142,199,137,175,201,0,159,72,10,5,21, +221,10,120,74,129,124,36,98,232,228,74,81,62,160,20,10,107,186,21,114,32, +105,137,194,70,46,142,68,165,19,235,1,64,170,187,161,119,34,66,146,36,104, +137,194,70,46,142,68,165,19,236,1,64,174,187,161,95,37,134,204,23,225,35, +23,71,34,82,137,246,128,160,89,93,208,167,147,195,201,194,70,46,142,68,165, +19,238,1,64,182,187,161,71,105,20,19,177,139,163,145,41,68,16,7,6,15,82,70, +72,115,96,0,0,0,0,96,2,106,32,91,60,165,195,201,194,8,134,149,216,162,0, +192,41,225,8,2,48,177,36,1,149,13,196,15,0,200,209,97,199,128,99,32,176, +195,192,113,57,143,0,167,133,32,230,80,28,202,139,175,238,2,48,189,192,20, +1,119,80,87,193,186,129,89,56,72,197,209,200,193,185,35,23,71,109,13,219, +36,98,232,237,156,13,26,208,211,14,102,19,87,137,91,95,128,0,10,96,24,92,0, +0,83,2,53,56,0,0,165,3,28,204,160,160,226,100,226,200,211,76,241,240,0,1, +102,8,22,75,64,137,73,20,230,105,133,7,19,39,22,70,154,103,143,128,0,11,48, +20,28,76,156,113,75,34,78,62,0,0,45,3,103,31,0,0,22,65,44,57,137,62,33,179, +216,162,152,192,131,18,124,162,27,61,138,41,108,32,196,159,16,217,232,235, +81,76,104,73,137,62,81,13,158,142,181,20,184,16,98,79,136,108,244,244,168, +166,56,36,196,159,40,134,207,79,74,138,93,10,49,39,194,173,192,158,158,149, +20,188,20,98,79,133,91,129,61,109,74,41,124,30,68,159,16,217,236,83,108,96, +68,137,62,81,13,158,197,54,182,17,34,79,136,108,244,117,169,182,52,38,68, +159,40,134,207,71,90,155,92,8,145,39,196,54,122,122,84,219,28,19,34,79,148, +67,103,167,165,77,174,133,72,147,225,86,224,79,79,74,155,94,10,145,39,194, +173,192,158,182,165,54,190,206,25,212,35,208,226,100,150,211,201,29,162,44, +140,35,103,0,0,0,0,0,0,3,192,252,206,25,228,35,208,226,100,150,211,201,29, +162,44,140,35,103,0,0,0,0,0,0,3,192,252,206,25,244,35,208,226,100,150,211, +201,29,162,44,140,35,103,0,0,0,0,0,0,3,192,252,206,26,4,35,208,226,100,150, +211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,1,0,206,26,20,35,208,226,100, +150,211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,1,0,206,26,36,35,208,226, +100,150,211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,65,0,206,26,52,35,208, +226,100,150,211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,65,0,206,26,68,35, +208,226,100,150,211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,65,0,206,26,84, +35,208,226,100,150,211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,129,0,195, +154,99,16,38,36,0,251,68,117,179,216,162,128,68,72,1,241,13,158,197,20,150, +25,18,0,125,162,58,217,232,235,117,100,162,136,25,18,0,125,162,58,217,232, +235,116,36,162,145,2,226,64,15,136,108,244,117,186,178,81,73,129,113,32,7, +196,54,122,58,221,9,40,165,64,200,144,3,237,17,214,207,79,75,171,37,20,80, +200,144,3,237,17,214,207,79,75,161,37,20,138,23,18,0,124,67,103,167,165, +213,146,138,77,11,137,0,62,33,179,211,210,232,73,69,42,133,196,128,31,10, +183,2,125,89,40,163,5,196,128,31,10,183,2,125,9,40,164,96,200,144,3,224, +221,64,172,157,89,40,163,134,68,128,31,6,234,5,100,232,73,69,35,133,68,128, +31,104,142,182,125,89,40,180,0,168,144,3,237,17,214,207,161,37,22,144,19, +18,0,124,67,103,213,146,139,80,9,137,0,62,33,179,232,73,69,172,5,90,40,153, +59,68,117,179,216,166,192,77,162,137,147,136,108,246,41,180,176,219,69,19, +39,104,142,182,122,58,221,89,41,178,6,218,40,153,59,68,117,179,209,214,232, +73,77,162,6,90,40,153,56,134,207,71,91,171,37,54,152,25,104,162,100,226,27, +61,29,110,132,148,218,160,109,162,137,147,180,71,91,61,61,46,172,148,217, +67,109,20,76,157,162,58,217,233,233,116,36,166,209,67,45,20,76,156,67,103, +167,165,213,146,155,77,12,180,81,50,113,13,158,158,151,66,74,109,84,50,209, +68,201,194,173,192,159,86,74,108,193,150,138,38,78,21,110,4,250,18,83,104, +193,182,138,38,78,13,212,10,201,213,146,155,56,109,162,137,147,131,117,2, +178,116,36,166,209,194,237,20,76,157,162,58,217,245,100,167,16,2,237,20,76, +157,162,58,217,244,36,167,18,2,173,20,76,156,67,103,213,146,156,80,10,180, +81,50,113,13,159,66,74,113,97,175,221,48,216,110,64,4,42,22,189,179,0,196, +133,0,185,80,32,28,78,99,193,18,80,36,4,19,159,141,172,0,178,90,4,74,73,0, +22,209,68,201,187,129,4,2,8,3,132,64,60,36,6,149,113,72,176,171,240,84,0, +157,91,116,116,32,11,42,218,221,216,181,129,32,3,234,219,165,3,188,231,235, +249,8,187,152,252,47,86,227,105,18,7,244,17,91,42,56,175,185,248,110,173, +198,209,208,36,0,238,82,97,87,188,189,179,240,93,122,32,12,22,162,42,125, +144,132,160,7,236,161,25,232,237,105,64,205,59,127,102,158,160,230,63,11, +217,66,51,210,129,154,118,254,205,61,65,236,127,171,197,34,168,48,6,90,194, +1,0,39,75,88,72,8,9,33,186,194,80,64,76,13,214,19,2,130,96,110,150,189,0, +65,6,51,214,20,128,65,17,11,214,19,130,137,121,211,210,211,144,6,39,75,88, +80,0,201,119,235,10,8,41,86,231,71,88,80,129,79,135,186,122,133,224,34,25, +69,234,80,3,91,141,172,40,96,139,113,180,181,133,36,21,110,54,142,134,176, +165,1,176,23,213,47,0,216,134,234,215,128,111,117,181,232,128,209,3,70,230, +107,64,5,139,168,209,235,10,32,36,144,102,235,136,3,146,27,172,40,160,146, +132,103,172,40,192,115,3,117,133,28,22,113,163,69,172,41,103,1,66,188,17, +145,52,168,4,202,113,67,76,130,227,76,194,13,240,108,0,0,83,224,0,2,193,0, +104,146,84,97,48,0,1,94,192,56,169,24,145,179,192,0,5,112,8,56,16,32,128, +56,18,52,125,230,86,147,190,140,28,50,21,13,39,31,23,60,145,158,57,12,141, +47,129,6,155,194,188,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69, +15,155,163,201,68,14,49,39,199,197,211,116,240,242,113,197,232,18,180,254, +36,3,17,46,18,243,35,100,128,172,156,178,70,163,154,76,34,248,146,164,108, +248,75,204,141,146,28,217,115,137,27,95,27,241,173,236,162,160,224,200,2, +206,9,113,13,148,192,209,18,22,164,146,37,193,57,162,4,249,39,196,128,24,2, +178,66,213,136,68,201,16,77,209,131,31,192,242,88,96,92,191,151,34,100,136, +38,232,255,252,92,221,199,197,12,68,209,82,66,212,11,155,185,41,197,13,55, +38,3,66,213,47,135,254,72,12,162,99,133,116,112,0,1,72,66,14,16,16,50,37, +202,160,150,154,66,14,20,8,57,192,28,24,80,113,50,113,100,105,166,120,248, +0,0,179,1,65,196,201,199,20,178,36,227,224,0,2,208,54,113,240,0,1,100,11, +181,192,0,5,178,1,18,160,65,24,131,20,145,25,188,48,132,122,28,76,146,218, +121,35,180,69,145,132,108,224,0,0,0,0,0,0,120,31,153,188,56,132,122,28,76, +146,218,121,35,180,69,145,132,108,224,0,0,0,0,0,0,120,31,168,160,45,110,23, +30,176,33,184,0,0,183,32,29,235,2,27,199,23,0,0,23,4,51,120,129,8,244,56, +153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,240,63,51,120,145,8,244, +56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,0,64,51,120,161,8, +244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,0,64,51,120,177, +8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,120, +193,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51, +120,209,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64, +51,120,225,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,32, +64,32,227,194,0,97,57,162,4,246,104,5,34,92,35,68,225,161,166,220,16,16, +137,112,52,41,73,29,185,1,65,196,201,197,145,166,153,246,72,3,137,204,120, +34,74,8,199,1,67,17,162,112,201,84,128,97,144,78,25,42,16,131,169,1,205,66, +8,35,68,225,161,166,239,128,0,10,192,64,196,104,156,50,96,0,2,172,73,240, +117,96,57,170,97,4,104,156,52,52,221,240,0,1,82,1,74,9,129,125,240,0,1,82, +32,148,25,174,137,58,23,51,190,0,0,42,69,64,195,32,156,50,96,0,2,160,81, +238,2,3,107,173,218,3,192, +}; +#elif defined(DUK_USE_DOUBLE_BE) +DUK_INTERNAL const duk_uint8_t duk_builtins_data[4281] = { +144,148,105,226,32,68,52,228,254,12,104,202,37,132,52,167,194,138,105,245, +124,57,28,211,57,18,64,52,239,126,44,138,111,175,241,164,19,87,145,30,33, +167,22,145,159,8,211,139,9,225,42,5,240,145,139,163,163,8,211,139,10,228, +64,211,19,132,140,93,29,56,70,156,88,119,34,66,146,36,104,137,194,70,46, +142,172,35,78,44,47,146,195,102,11,240,145,139,163,175,8,211,139,9,228,240, +242,112,145,139,163,179,8,211,139,8,237,34,130,118,49,116,118,225,26,48,0, +1,98,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132, +33,8,66,26,180,105,97,167,68,150,34,33,154,112,0,1,91,247,35,79,111,237, +198,174,232,47,31,23,95,17,13,31,249,96,211,49,50,53,214,77,141,24,0,0,181, +10,228,240,242,15,128,140,65,128,134,188,0,0,90,167,97,181,224,0,2,213,62, +53,224,0,2,213,66,237,120,0,0,181,81,204,107,192,0,5,170,150,67,94,0,0,45, +84,245,90,240,0,1,106,169,162,215,128,0,11,85,93,150,188,0,0,90,171,111,53, +109,22,162,26,48,0,1,84,23,201,146,243,225,26,39,12,145,136,104,192,0,5,61, +11,228,201,121,240,100,19,134,72,196,33,195,14,40,203,112,64,190,76,232, +145,153,136,15,255,0,0,0,0,0,0,25,152,15,254,0,0,0,0,0,0,25,120,144,13,96, +155,194,56,80,206,36,67,141,20,228,70,57,81,206,100,131,156,39,132,168,23, +194,70,46,137,208,21,200,129,166,39,9,24,186,39,72,119,34,66,146,36,104, +137,194,70,46,137,212,23,201,97,179,5,248,72,197,209,58,194,121,60,60,156, +36,98,232,157,129,29,164,80,78,198,46,137,218,146,121,25,71,146,9,209,5, +209,61,48,126,14,138,152,30,67,186,23,143,139,175,131,202,135,228,72,85, +144,83,60,179,30,94,209,233,102,30,98,105,230,103,30,114,121,231,104,30, +122,137,231,233,30,130,153,232,106,30,138,169,232,235,30,144,67,193,25,19, +136,108,207,30,41,224,140,137,194,173,192,153,228,5,242,100,188,248,70,137, +195,36,79,78,47,147,37,231,193,144,78,25,34,122,145,111,36,74,232,176,13, +17,61,234,226,93,207,148,160,84,75,141,7,27,161,32,33,18,225,80,212,76,154, +2,2,70,65,56,100,237,34,140,209,2,67,32,156,50,118,145,64,186,230,61,205, +35,103,155,32,36,141,19,134,78,210,40,206,16,36,70,137,195,39,105,20,11, +174,99,220,210,54,121,210,1,137,33,1,228,207,16,17,70,146,66,3,201,164,32, +0,65,112,152,56,196,159,31,23,77,211,195,201,199,23,160,72,214,246,81,6,12, +73,241,214,111,31,23,60,145,158,56,50,72,81,67,230,232,242,80,19,49,39,199, +89,188,124,92,242,70,120,227,64,194,75,154,72,12,9,73,6,111,21,120,12,40, +144,19,39,25,0,225,144,168,105,56,248,185,228,140,241,200,96,64,100,42,26, +78,62,46,121,35,52,18,92,116,1,36,64,47,158,64,49,98,66,100,156,242,65,23, +196,149,35,103,194,94,100,108,144,230,203,156,64,66,37,201,16,11,32,249, +132,4,34,92,44,93,146,55,152,72,24,137,112,151,153,27,36,5,100,229,144,8, +162,98,92,210,5,76,73,241,214,111,31,23,60,145,158,57,44,48,46,92,185,164, +160,72,151,41,0,50,107,179,244,59,36,93,127,92,6,19,172,3,11,216,0,56,224, +151,29,102,241,241,115,201,25,227,164,64,106,37,199,197,211,116,240,242, +113,197,233,144,40,248,185,228,140,241,196,75,132,109,24,72,128,43,39,84, +129,13,173,161,144,168,105,56,98,78,100,142,214,215,69,1,13,173,161,144, +168,105,57,34,78,100,142,214,215,69,16,67,107,105,110,114,168,254,24,147, +153,35,181,181,212,32,67,107,105,110,114,168,254,72,147,153,35,181,181,212, +36,65,130,3,144,8,26,252,200,13,30,85,16,16,64,90,242,231,192,64,161,163, +203,31,26,172,193,17,4,23,105,159,96,27,172,251,16,32,196,4,14,137,112,17, +136,48,164,28,134,80,215,202,1,132,130,8,12,39,52,64,155,31,24,56,36,1,189, +207,132,0,35,233,35,195,62,3,196,149,36,100,72,160,2,200,232,44,227,0,11, +37,160,68,142,128,36,157,25,200,32,26,79,90,4,73,43,192,122,54,71,65,103, +44,248,14,134,140,151,227,138,231,208,45,96,148,248,134,140,151,227,138, +231,240,1,255,254,10,74,146,56,128,104,4,147,152,72,6,144,28,174,143,8,1, +30,1,165,3,96,31,0,211,3,21,11,153,35,0,211,131,68,131,160,137,16,250,5, +196,131,160,137,200,160,199,156,67,248,0,255,255,65,140,10,48,177,115,56, +35,130,60,19,134,79,89,240,52,177,115,56,39,12,156,123,144,217,251,15,135, +34,167,30,20,170,154,255,232,12,47,244,0,97,28,17,224,39,238,32,40,71,4, +120,39,12,156,4,253,228,5,137,195,39,30,228,54,124,4,253,228,128,194,115, +68,9,252,15,128,232,104,201,126,56,191,35,64,90,193,41,241,13,25,47,199,23, +228,105,3,86,225,1,100,224,156,199,130,36,249,144,10,192,76,71,250,16,15, +18,61,96,17,62,200,3,72,128,136,143,247,32,22,75,64,137,248,64,22,79,90,39, +249,64,38,84,12,167,20,52,223,196,2,230,238,45,214,36,120,32,72,158,208,4, +102,238,45,194,2,201,197,186,196,143,4,9,19,218,0,92,221,202,61,228,143,4, +9,19,218,8,35,55,113,110,16,22,78,81,239,36,120,32,72,158,208,64,73,197,12, +255,0,13,18,60,128,159,212,128,169,76,17,156,185,100,76,255,163,64,65,26, +57,114,200,153,255,70,144,33,13,18,232,50,75,226,104,6,149,3,41,199,246, +130,12,128,28,142,156,120,203,175,158,8,194,207,1,6,81,20,79,88,11,237,84, +11,161,32,63,247,255,255,255,255,255,255,137,235,16,221,170,129,116,36,0,0, +0,0,0,0,0,0,28,196,7,255,128,0,0,0,0,0,2,61,123,164,137,162,164,218,67,74, +134,162,120,128,255,224,0,0,0,0,0,0,71,173,33,129,52,84,155,72,105,80,212, +79,16,63,252,0,0,0,0,0,0,3,244,143,146,22,230,192,60,176,0,0,0,0,0,0,33, +214,2,251,82,1,73,180,134,204,134,36,96,33,159,255,255,255,255,255,255,144, +235,16,221,169,0,164,218,67,102,67,18,48,48,207,255,255,255,255,255,255, +196,60,17,145,56,134,204,241,226,158,8,200,156,42,220,9,158,65,196,34,92, +42,26,137,147,120,64,74,37,196,54,100,49,35,188,36,5,68,184,208,113,187, +194,80,212,75,146,1,73,196,54,100,49,35,188,38,57,37,56,240,0,0,0,0,0,0,0, +0,32,235,248,68,48,156,2,24,94,24,0,243,119,10,139,144,123,242,3,102,238, +18,239,115,72,217,160,11,223,16,23,55,113,241,32,145,36,57,188,18,16,102,3, +5,120,35,34,89,32,15,180,152,173,127,0,218,235,88,0,228,180,227,200,127, +248,0,0,0,0,0,0,197,107,240,64,6,77,220,24,38,78,74,113,67,77,130,4,12,155, +185,52,48,156,148,226,134,155,4,10,194,96,129,132,166,238,45,194,2,201,193, +130,100,228,167,20,52,216,32,113,41,187,139,112,128,178,114,104,97,57,41, +197,13,54,8,32,48,216,32,130,195,224,130,19,97,124,134,23,6,0,57,137,62,77, +12,38,12,0,179,18,124,45,22,190,96,128,141,176,134,28,98,79,180,152,139, +218,45,124,193,1,27,97,16,32,196,159,24,230,204,246,194,40,89,137,62,210, +98,103,92,217,158,216,70,7,49,39,193,130,100,182,17,194,140,73,246,147,16, +250,9,146,216,72,6,49,39,193,131,22,194,72,73,137,62,210,98,31,65,139,97, +40,32,196,159,14,234,70,86,194,88,89,137,62,210,98,63,93,72,202,216,76,10, +49,39,198,33,180,153,37,108,38,134,152,147,237,38,38,117,13,164,201,43,97, +56,40,196,159,36,65,57,163,149,176,158,26,98,79,180,152,165,210,9,205,28, +173,133,0,243,18,124,98,22,180,72,130,115,71,43,97,68,72,196,159,105,49,51, +168,90,209,34,9,205,28,173,133,33,19,18,124,154,24,76,185,164,227,138,89, +18,119,0,7,145,39,201,161,132,188,64,124,137,62,49,11,90,36,65,57,163,149, +210,166,37,34,79,180,152,153,212,45,104,145,4,230,142,87,74,160,84,137,62, +72,130,115,71,43,171,234,134,200,147,237,38,41,116,130,115,71,43,171,235,5, +72,147,227,16,218,76,146,186,254,184,108,137,62,210,98,103,80,218,76,146, +186,254,192,68,137,62,29,212,140,174,207,178,23,34,79,180,152,143,215,82, +50,187,62,208,60,137,62,12,19,37,210,182,21,34,79,180,152,135,208,76,151, +74,224,68,137,62,49,205,153,238,175,186,23,34,79,180,152,153,215,54,103, +186,190,240,92,137,62,22,139,95,48,64,70,235,251,225,210,36,251,73,136,189, +162,215,204,16,17,186,255,2,14,98,79,152,32,35,108,48,64,242,36,249,130,2, +55,75,6,212,224,72,200,51,128,114,108,28,100,128,0,0,0,0,0,0,0,12,110,127, +48,98,115,249,201,117,243,249,195,21,159,206,38,47,63,156,86,8,75,144,94, +82,1,38,73,79,208,67,95,233,1,6,128,14,79,129,186,40,249,18,149,182,207, +144,200,155,188,248,204,105,184,207,142,199,137,175,201,0,159,72,10,5,21, +221,10,120,74,129,124,36,98,232,228,74,81,62,160,20,10,107,186,21,114,32, +105,137,194,70,46,142,68,165,19,235,1,64,170,187,161,119,34,66,146,36,104, +137,194,70,46,142,68,165,19,236,1,64,174,187,161,95,37,134,204,23,225,35, +23,71,34,82,137,246,128,160,89,93,208,167,147,195,201,194,70,46,142,68,165, +19,238,1,64,182,187,161,71,105,20,19,177,139,163,145,41,68,16,7,6,15,82,70, +72,115,96,32,106,2,96,0,0,0,0,91,60,165,195,201,194,8,134,149,216,162,0, +192,41,225,8,2,48,177,36,1,149,13,196,15,0,200,209,97,199,128,99,32,176, +195,192,113,57,143,0,167,133,32,230,80,28,202,139,175,238,2,48,189,192,20, +1,119,80,87,193,186,129,89,56,72,197,209,200,193,185,35,23,71,109,13,219, +36,98,232,237,156,13,26,208,211,14,102,19,87,137,91,95,128,0,10,96,24,92,0, +0,83,2,53,56,0,0,165,3,28,204,160,160,226,100,226,200,211,76,241,240,0,1, +102,8,22,75,64,137,73,20,230,105,133,7,19,39,22,70,154,103,143,128,0,11,48, +20,28,76,156,113,75,34,78,62,0,0,45,3,103,31,0,0,22,65,44,57,137,62,33,179, +216,162,152,192,131,18,124,162,27,61,138,41,108,32,196,159,16,217,232,235, +81,76,104,73,137,62,81,13,158,142,181,20,184,16,98,79,136,108,244,244,168, +166,56,36,196,159,40,134,207,79,74,138,93,10,49,39,194,173,192,158,158,149, +20,188,20,98,79,133,91,129,61,109,74,41,124,30,68,159,16,217,236,83,108,96, +68,137,62,81,13,158,197,54,182,17,34,79,136,108,244,117,169,182,52,38,68, +159,40,134,207,71,90,155,92,8,145,39,196,54,122,122,84,219,28,19,34,79,148, +67,103,167,165,77,174,133,72,147,225,86,224,79,79,74,155,94,10,145,39,194, +173,192,158,182,165,54,190,206,25,212,35,208,226,100,150,211,201,29,162,44, +140,35,103,0,255,192,0,0,0,0,0,0,206,25,228,35,208,226,100,150,211,201,29, +162,44,140,35,103,0,255,192,0,0,0,0,0,0,206,25,244,35,208,226,100,150,211, +201,29,162,44,140,35,103,0,255,192,0,0,0,0,0,0,206,26,4,35,208,226,100,150, +211,201,29,162,44,140,35,103,1,0,0,0,0,0,0,0,0,206,26,20,35,208,226,100, +150,211,201,29,162,44,140,35,103,1,0,0,0,0,0,0,0,0,206,26,36,35,208,226, +100,150,211,201,29,162,44,140,35,103,1,0,64,0,0,0,0,0,0,206,26,52,35,208, +226,100,150,211,201,29,162,44,140,35,103,1,0,64,0,0,0,0,0,0,206,26,68,35, +208,226,100,150,211,201,29,162,44,140,35,103,1,0,64,0,0,0,0,0,0,206,26,84, +35,208,226,100,150,211,201,29,162,44,140,35,103,1,0,128,0,0,0,0,0,0,195, +154,99,16,38,36,0,251,68,117,179,216,162,128,68,72,1,241,13,158,197,20,150, +25,18,0,125,162,58,217,232,235,117,100,162,136,25,18,0,125,162,58,217,232, +235,116,36,162,145,2,226,64,15,136,108,244,117,186,178,81,73,129,113,32,7, +196,54,122,58,221,9,40,165,64,200,144,3,237,17,214,207,79,75,171,37,20,80, +200,144,3,237,17,214,207,79,75,161,37,20,138,23,18,0,124,67,103,167,165, +213,146,138,77,11,137,0,62,33,179,211,210,232,73,69,42,133,196,128,31,10, +183,2,125,89,40,163,5,196,128,31,10,183,2,125,9,40,164,96,200,144,3,224, +221,64,172,157,89,40,163,134,68,128,31,6,234,5,100,232,73,69,35,133,68,128, +31,104,142,182,125,89,40,180,0,168,144,3,237,17,214,207,161,37,22,144,19, +18,0,124,67,103,213,146,139,80,9,137,0,62,33,179,232,73,69,172,5,90,40,153, +59,68,117,179,216,166,192,77,162,137,147,136,108,246,41,180,176,219,69,19, +39,104,142,182,122,58,221,89,41,178,6,218,40,153,59,68,117,179,209,214,232, +73,77,162,6,90,40,153,56,134,207,71,91,171,37,54,152,25,104,162,100,226,27, +61,29,110,132,148,218,160,109,162,137,147,180,71,91,61,61,46,172,148,217, +67,109,20,76,157,162,58,217,233,233,116,36,166,209,67,45,20,76,156,67,103, +167,165,213,146,155,77,12,180,81,50,113,13,158,158,151,66,74,109,84,50,209, +68,201,194,173,192,159,86,74,108,193,150,138,38,78,21,110,4,250,18,83,104, +193,182,138,38,78,13,212,10,201,213,146,155,56,109,162,137,147,131,117,2, +178,116,36,166,209,194,237,20,76,157,162,58,217,245,100,167,16,2,237,20,76, +157,162,58,217,244,36,167,18,2,173,20,76,156,67,103,213,146,156,80,10,180, +81,50,113,13,159,66,74,113,97,175,221,48,216,110,64,4,42,22,189,179,0,196, +133,0,185,80,32,28,78,99,193,18,80,36,4,19,159,141,172,0,178,90,4,74,73,0, +22,209,68,201,187,129,4,2,8,3,132,64,60,36,4,0,91,240,168,177,69,118,144, +157,91,116,116,32,32,1,53,216,221,218,170,139,3,234,219,165,0,255,152,185, +11,251,232,231,188,47,86,227,105,18,1,255,184,170,59,41,92,23,240,110,173, +198,209,208,36,3,253,188,183,177,82,110,80,224,93,122,32,32,4,144,253,170, +34,22,140,7,236,161,25,232,237,105,64,63,230,160,158,102,127,59,205,11,217, +66,51,210,128,127,237,65,60,204,254,119,155,171,197,34,168,48,6,90,194,1,0, +39,75,88,72,8,9,33,186,194,80,64,76,13,214,19,2,130,96,110,150,189,0,65,6, +51,214,20,128,65,17,11,214,19,130,137,121,211,210,211,144,6,39,75,88,80,0, +201,119,235,10,8,41,86,231,71,88,80,129,79,135,186,122,133,224,34,25,69, +234,80,3,91,141,172,40,96,139,113,180,181,133,36,21,110,54,142,134,176,165, +1,176,23,213,47,0,216,134,234,215,128,111,117,181,232,128,209,3,70,230,107, +64,5,139,168,209,235,10,32,36,144,102,235,136,3,146,27,172,40,160,146,132, +103,172,40,192,115,3,117,133,28,22,113,163,69,172,41,103,1,66,188,17,145, +52,168,4,202,113,67,76,130,227,76,194,13,240,108,0,0,83,224,0,2,193,0,104, +146,84,97,48,0,1,94,192,56,169,24,145,179,192,0,5,112,8,56,16,32,128,56,18, +52,125,230,86,147,190,140,28,50,21,13,39,31,23,60,145,158,57,12,141,47,129, +6,155,194,188,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155, +163,201,68,14,49,39,199,197,211,116,240,242,113,197,232,18,180,254,36,3,17, +46,18,243,35,100,128,172,156,178,70,163,154,76,34,248,146,164,108,248,75, +204,141,146,28,217,115,137,27,95,27,241,173,236,162,160,224,200,2,206,9, +113,13,148,192,209,18,22,164,146,37,193,57,162,4,249,39,196,128,24,2,178, +66,213,136,68,201,16,77,209,131,31,192,242,88,96,92,191,151,34,100,136,38, +232,255,252,92,221,199,197,12,68,209,82,66,212,11,155,185,41,197,13,55,38, +3,66,213,47,135,254,72,12,162,99,133,116,112,0,1,72,66,14,16,16,50,37,202, +160,150,154,66,14,20,8,57,192,28,24,80,113,50,113,100,105,166,120,248,0,0, +179,1,65,196,201,199,20,178,36,227,224,0,2,208,54,113,240,0,1,100,11,181, +192,0,5,178,1,18,160,65,24,131,20,145,25,188,48,132,122,28,76,146,218,121, +35,180,69,145,132,108,224,31,248,0,0,0,0,0,0,25,188,56,132,122,28,76,146, +218,121,35,180,69,145,132,108,224,31,248,0,0,0,0,0,0,40,160,45,110,23,30, +176,33,184,0,0,183,32,29,235,2,27,199,23,0,0,23,4,51,120,129,8,244,56,153, +37,180,242,71,104,139,35,8,217,192,63,240,0,0,0,0,0,0,51,120,145,8,244,56, +153,37,180,242,71,104,139,35,8,217,192,64,0,0,0,0,0,0,0,51,120,161,8,244, +56,153,37,180,242,71,104,139,35,8,217,192,64,0,0,0,0,0,0,0,51,120,177,8, +244,56,153,37,180,242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,120,193, +8,244,56,153,37,180,242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,120, +209,8,244,56,153,37,180,242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51, +120,225,8,244,56,153,37,180,242,71,104,139,35,8,217,192,64,32,0,0,0,0,0,0, +32,227,194,0,97,57,162,4,246,104,5,34,92,35,68,225,161,166,220,16,16,137, +112,52,41,73,29,185,1,65,196,201,197,145,166,153,246,72,3,137,204,120,34, +74,8,199,1,67,17,162,112,201,84,128,97,144,78,25,42,16,131,169,1,205,66,8, +35,68,225,161,166,239,128,0,10,192,64,196,104,156,50,96,0,2,172,73,240,117, +96,57,170,97,4,104,156,52,52,221,240,0,1,82,1,74,9,129,125,240,0,1,82,32, +148,25,174,137,58,23,51,190,0,0,42,69,64,195,32,156,50,96,0,2,160,81,238,2, +3,107,173,218,3,192, +}; +#elif defined(DUK_USE_DOUBLE_ME) +DUK_INTERNAL const duk_uint8_t duk_builtins_data[4281] = { +144,148,105,226,32,68,52,228,254,12,104,202,37,132,52,167,194,138,105,245, +124,57,28,211,57,18,64,52,239,126,44,138,111,175,241,164,19,87,145,30,33, +167,22,145,159,8,211,139,9,225,42,5,240,145,139,163,163,8,211,139,10,228, +64,211,19,132,140,93,29,56,70,156,88,119,34,66,146,36,104,137,194,70,46, +142,172,35,78,44,47,146,195,102,11,240,145,139,163,175,8,211,139,9,228,240, +242,112,145,139,163,179,8,211,139,8,237,34,130,118,49,116,118,225,26,48,0, +1,98,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132, +33,8,66,26,180,105,97,167,68,150,34,33,154,112,0,1,91,247,35,79,111,237, +198,174,232,47,31,23,95,17,13,31,249,96,211,49,50,53,214,77,141,24,0,0,181, +10,228,240,242,15,128,140,65,128,134,188,0,0,90,167,97,181,224,0,2,213,62, +53,224,0,2,213,66,237,120,0,0,181,81,204,107,192,0,5,170,150,67,94,0,0,45, +84,245,90,240,0,1,106,169,162,215,128,0,11,85,93,150,188,0,0,90,171,111,53, +109,22,162,26,48,0,1,84,23,201,146,243,225,26,39,12,145,136,104,192,0,5,61, +11,228,201,121,240,100,19,134,72,196,33,195,14,40,203,112,64,190,76,232, +145,153,136,0,0,31,15,224,0,0,0,25,152,0,0,30,15,224,0,0,0,25,120,144,13, +96,155,194,56,80,206,36,67,141,20,228,70,57,81,206,100,131,156,39,132,168, +23,194,70,46,137,208,21,200,129,166,39,9,24,186,39,72,119,34,66,146,36,104, +137,194,70,46,137,212,23,201,97,179,5,248,72,197,209,58,194,121,60,60,156, +36,98,232,157,129,29,164,80,78,198,46,137,218,146,121,25,71,146,9,209,5, +209,61,48,126,14,138,152,30,67,186,23,143,139,175,131,202,135,228,72,85, +144,83,60,179,30,94,209,233,102,30,98,105,230,103,30,114,121,231,104,30, +122,137,231,233,30,130,153,232,106,30,138,169,232,235,30,144,67,193,25,19, +136,108,207,30,41,224,140,137,194,173,192,153,228,5,242,100,188,248,70,137, +195,36,79,78,47,147,37,231,193,144,78,25,34,122,145,111,36,74,232,176,13, +17,61,234,226,93,207,148,160,84,75,141,7,27,161,32,33,18,225,80,212,76,154, +2,2,70,65,56,100,237,34,140,209,2,67,32,156,50,118,145,64,186,230,61,205, +35,103,155,32,36,141,19,134,78,210,40,206,16,36,70,137,195,39,105,20,11, +174,99,220,210,54,121,210,1,137,33,1,228,207,16,17,70,146,66,3,201,164,32, +0,65,112,152,56,196,159,31,23,77,211,195,201,199,23,160,72,214,246,81,6,12, +73,241,214,111,31,23,60,145,158,56,50,72,81,67,230,232,242,80,19,49,39,199, +89,188,124,92,242,70,120,227,64,194,75,154,72,12,9,73,6,111,21,120,12,40, +144,19,39,25,0,225,144,168,105,56,248,185,228,140,241,200,96,64,100,42,26, +78,62,46,121,35,52,18,92,116,1,36,64,47,158,64,49,98,66,100,156,242,65,23, +196,149,35,103,194,94,100,108,144,230,203,156,64,66,37,201,16,11,32,249, +132,4,34,92,44,93,146,55,152,72,24,137,112,151,153,27,36,5,100,229,144,8, +162,98,92,210,5,76,73,241,214,111,31,23,60,145,158,57,44,48,46,92,185,164, +160,72,151,41,0,50,107,179,244,59,36,93,127,92,6,19,172,3,11,216,0,56,224, +151,29,102,241,241,115,201,25,227,164,64,106,37,199,197,211,116,240,242, +113,197,233,144,40,248,185,228,140,241,196,75,132,109,24,72,128,43,39,84, +129,13,173,161,144,168,105,56,98,78,100,142,214,215,69,1,13,173,161,144, +168,105,57,34,78,100,142,214,215,69,16,67,107,105,110,114,168,254,24,147, +153,35,181,181,212,32,67,107,105,110,114,168,254,72,147,153,35,181,181,212, +36,65,130,3,144,8,26,252,200,13,30,85,16,16,64,90,242,231,192,64,161,163, +203,31,26,172,193,17,4,23,105,159,96,27,172,251,16,32,196,4,14,137,112,17, +136,48,164,28,134,80,215,202,1,132,130,8,12,39,52,64,155,31,24,56,36,1,189, +207,132,0,35,233,35,195,62,3,196,149,36,100,72,160,2,200,232,44,227,0,11, +37,160,68,142,128,36,157,25,200,32,26,79,90,4,73,43,192,122,54,71,65,103, +44,248,14,134,140,151,227,138,231,208,45,96,148,248,134,140,151,227,138, +231,240,1,255,254,10,74,146,56,128,104,4,147,152,72,6,144,28,174,143,8,1, +30,1,165,3,96,31,0,211,3,21,11,153,35,0,211,131,68,131,160,137,16,250,5, +196,131,160,137,200,160,199,156,67,248,0,255,255,65,140,10,48,177,115,56, +35,130,60,19,134,79,89,240,52,177,115,56,39,12,156,123,144,217,251,15,135, +34,167,30,20,170,154,255,232,12,47,244,0,97,28,17,224,39,238,32,40,71,4, +120,39,12,156,4,253,228,5,137,195,39,30,228,54,124,4,253,228,128,194,115, +68,9,252,15,128,232,104,201,126,56,191,35,64,90,193,41,241,13,25,47,199,23, +228,105,3,86,225,1,100,224,156,199,130,36,249,144,10,192,76,71,250,16,15, +18,61,96,17,62,200,3,72,128,136,143,247,32,22,75,64,137,248,64,22,79,90,39, +249,64,38,84,12,167,20,52,223,196,2,230,238,45,214,36,120,32,72,158,208,4, +102,238,45,194,2,201,197,186,196,143,4,9,19,218,0,92,221,202,61,228,143,4, +9,19,218,8,35,55,113,110,16,22,78,81,239,36,120,32,72,158,208,64,73,197,12, +255,0,13,18,60,128,159,212,128,169,76,17,156,185,100,76,255,163,64,65,26, +57,114,200,153,255,70,144,33,13,18,232,50,75,226,104,6,149,3,41,199,246, +130,12,128,28,142,156,120,203,175,158,8,194,207,1,6,81,20,79,88,11,237,84, +11,161,32,127,255,247,191,255,255,255,255,137,235,16,221,170,129,116,36,0, +0,0,0,0,16,0,0,12,196,0,0,15,135,240,0,0,0,2,61,123,164,137,162,164,218,67, +74,134,162,120,128,0,1,224,254,0,0,0,0,71,173,33,129,52,84,155,72,105,80, +212,79,16,0,0,60,63,192,0,0,0,3,244,143,146,22,230,192,0,0,176,60,0,0,0,0, +33,214,2,251,82,1,73,180,134,204,134,36,96,127,255,159,161,255,255,255,255, +144,235,16,221,169,0,164,218,67,102,67,18,48,63,255,207,240,255,255,255, +255,196,60,17,145,56,134,204,241,226,158,8,200,156,42,220,9,158,65,196,34, +92,42,26,137,147,120,64,74,37,196,54,100,49,35,188,36,5,68,184,208,113,187, +194,80,212,75,146,1,73,196,54,100,49,35,188,38,57,37,56,240,0,0,0,0,0,0,0, +0,32,235,248,68,48,156,2,24,94,24,0,243,119,10,139,144,123,242,3,102,238, +18,239,115,72,217,160,11,223,16,23,55,113,241,32,145,36,57,188,18,16,102,3, +5,120,35,34,89,32,15,180,152,173,127,0,218,235,88,0,228,180,227,200,0,0, +248,127,0,0,0,0,197,107,240,64,6,77,220,24,38,78,74,113,67,77,130,4,12,155, +185,52,48,156,148,226,134,155,4,10,194,96,129,132,166,238,45,194,2,201,193, +130,100,228,167,20,52,216,32,113,41,187,139,112,128,178,114,104,97,57,41, +197,13,54,8,32,48,216,32,130,195,224,130,19,97,124,134,23,6,0,57,137,62,77, +12,38,12,0,179,18,124,45,22,190,96,128,141,176,134,28,98,79,180,152,139, +218,45,124,193,1,27,97,16,32,196,159,24,230,204,246,194,40,89,137,62,210, +98,103,92,217,158,216,70,7,49,39,193,130,100,182,17,194,140,73,246,147,16, +250,9,146,216,72,6,49,39,193,131,22,194,72,73,137,62,210,98,31,65,139,97, +40,32,196,159,14,234,70,86,194,88,89,137,62,210,98,63,93,72,202,216,76,10, +49,39,198,33,180,153,37,108,38,134,152,147,237,38,38,117,13,164,201,43,97, +56,40,196,159,36,65,57,163,149,176,158,26,98,79,180,152,165,210,9,205,28, +173,133,0,243,18,124,98,22,180,72,130,115,71,43,97,68,72,196,159,105,49,51, +168,90,209,34,9,205,28,173,133,33,19,18,124,154,24,76,185,164,227,138,89, +18,119,0,7,145,39,201,161,132,188,64,124,137,62,49,11,90,36,65,57,163,149, +210,166,37,34,79,180,152,153,212,45,104,145,4,230,142,87,74,160,84,137,62, +72,130,115,71,43,171,234,134,200,147,237,38,41,116,130,115,71,43,171,235,5, +72,147,227,16,218,76,146,186,254,184,108,137,62,210,98,103,80,218,76,146, +186,254,192,68,137,62,29,212,140,174,207,178,23,34,79,180,152,143,215,82, +50,187,62,208,60,137,62,12,19,37,210,182,21,34,79,180,152,135,208,76,151, +74,224,68,137,62,49,205,153,238,175,186,23,34,79,180,152,153,215,54,103, +186,190,240,92,137,62,22,139,95,48,64,70,235,251,225,210,36,251,73,136,189, +162,215,204,16,17,186,255,2,14,98,79,152,32,35,108,48,64,242,36,249,130,2, +55,75,6,212,224,72,200,51,128,114,108,28,100,128,0,0,0,0,0,0,0,12,110,127, +48,98,115,249,201,117,243,249,195,21,159,206,38,47,63,156,86,8,75,144,94, +82,1,38,73,79,208,67,95,233,1,6,128,14,79,129,186,40,249,18,149,182,207, +144,200,155,188,248,204,105,184,207,142,199,137,175,201,0,159,72,10,5,21, +221,10,120,74,129,124,36,98,232,228,74,81,62,160,20,10,107,186,21,114,32, +105,137,194,70,46,142,68,165,19,235,1,64,170,187,161,119,34,66,146,36,104, +137,194,70,46,142,68,165,19,236,1,64,174,187,161,95,37,134,204,23,225,35, +23,71,34,82,137,246,128,160,89,93,208,167,147,195,201,194,70,46,142,68,165, +19,238,1,64,182,187,161,71,105,20,19,177,139,163,145,41,68,16,7,6,15,82,70, +72,115,96,96,2,106,32,0,0,0,0,91,60,165,195,201,194,8,134,149,216,162,0, +192,41,225,8,2,48,177,36,1,149,13,196,15,0,200,209,97,199,128,99,32,176, +195,192,113,57,143,0,167,133,32,230,80,28,202,139,175,238,2,48,189,192,20, +1,119,80,87,193,186,129,89,56,72,197,209,200,193,185,35,23,71,109,13,219, +36,98,232,237,156,13,26,208,211,14,102,19,87,137,91,95,128,0,10,96,24,92,0, +0,83,2,53,56,0,0,165,3,28,204,160,160,226,100,226,200,211,76,241,240,0,1, +102,8,22,75,64,137,73,20,230,105,133,7,19,39,22,70,154,103,143,128,0,11,48, +20,28,76,156,113,75,34,78,62,0,0,45,3,103,31,0,0,22,65,44,57,137,62,33,179, +216,162,152,192,131,18,124,162,27,61,138,41,108,32,196,159,16,217,232,235, +81,76,104,73,137,62,81,13,158,142,181,20,184,16,98,79,136,108,244,244,168, +166,56,36,196,159,40,134,207,79,74,138,93,10,49,39,194,173,192,158,158,149, +20,188,20,98,79,133,91,129,61,109,74,41,124,30,68,159,16,217,236,83,108,96, +68,137,62,81,13,158,197,54,182,17,34,79,136,108,244,117,169,182,52,38,68, +159,40,134,207,71,90,155,92,8,145,39,196,54,122,122,84,219,28,19,34,79,148, +67,103,167,165,77,174,133,72,147,225,86,224,79,79,74,155,94,10,145,39,194, +173,192,158,182,165,54,190,206,25,212,35,208,226,100,150,211,201,29,162,44, +140,35,103,0,0,3,192,252,0,0,0,0,206,25,228,35,208,226,100,150,211,201,29, +162,44,140,35,103,0,0,3,192,252,0,0,0,0,206,25,244,35,208,226,100,150,211, +201,29,162,44,140,35,103,0,0,3,192,252,0,0,0,0,206,26,4,35,208,226,100,150, +211,201,29,162,44,140,35,103,0,0,0,1,0,0,0,0,0,206,26,20,35,208,226,100, +150,211,201,29,162,44,140,35,103,0,0,0,1,0,0,0,0,0,206,26,36,35,208,226, +100,150,211,201,29,162,44,140,35,103,0,0,0,65,0,0,0,0,0,206,26,52,35,208, +226,100,150,211,201,29,162,44,140,35,103,0,0,0,65,0,0,0,0,0,206,26,68,35, +208,226,100,150,211,201,29,162,44,140,35,103,0,0,0,65,0,0,0,0,0,206,26,84, +35,208,226,100,150,211,201,29,162,44,140,35,103,0,0,0,129,0,0,0,0,0,195, +154,99,16,38,36,0,251,68,117,179,216,162,128,68,72,1,241,13,158,197,20,150, +25,18,0,125,162,58,217,232,235,117,100,162,136,25,18,0,125,162,58,217,232, +235,116,36,162,145,2,226,64,15,136,108,244,117,186,178,81,73,129,113,32,7, +196,54,122,58,221,9,40,165,64,200,144,3,237,17,214,207,79,75,171,37,20,80, +200,144,3,237,17,214,207,79,75,161,37,20,138,23,18,0,124,67,103,167,165, +213,146,138,77,11,137,0,62,33,179,211,210,232,73,69,42,133,196,128,31,10, +183,2,125,89,40,163,5,196,128,31,10,183,2,125,9,40,164,96,200,144,3,224, +221,64,172,157,89,40,163,134,68,128,31,6,234,5,100,232,73,69,35,133,68,128, +31,104,142,182,125,89,40,180,0,168,144,3,237,17,214,207,161,37,22,144,19, +18,0,124,67,103,213,146,139,80,9,137,0,62,33,179,232,73,69,172,5,90,40,153, +59,68,117,179,216,166,192,77,162,137,147,136,108,246,41,180,176,219,69,19, +39,104,142,182,122,58,221,89,41,178,6,218,40,153,59,68,117,179,209,214,232, +73,77,162,6,90,40,153,56,134,207,71,91,171,37,54,152,25,104,162,100,226,27, +61,29,110,132,148,218,160,109,162,137,147,180,71,91,61,61,46,172,148,217, +67,109,20,76,157,162,58,217,233,233,116,36,166,209,67,45,20,76,156,67,103, +167,165,213,146,155,77,12,180,81,50,113,13,158,158,151,66,74,109,84,50,209, +68,201,194,173,192,159,86,74,108,193,150,138,38,78,21,110,4,250,18,83,104, +193,182,138,38,78,13,212,10,201,213,146,155,56,109,162,137,147,131,117,2, +178,116,36,166,209,194,237,20,76,157,162,58,217,245,100,167,16,2,237,20,76, +157,162,58,217,244,36,167,18,2,173,20,76,156,67,103,213,146,156,80,10,180, +81,50,113,13,159,66,74,113,97,175,221,48,216,110,64,4,42,22,189,179,0,196, +133,0,185,80,32,28,78,99,193,18,80,36,4,19,159,141,172,0,178,90,4,74,73,0, +22,209,68,201,187,129,4,2,8,3,132,64,60,36,0,171,240,84,6,149,113,72,176, +157,91,116,116,32,88,181,129,32,11,42,218,221,131,234,219,165,1,8,187,152, +255,188,231,235,248,47,86,227,105,18,2,56,175,185,255,244,17,91,40,110,173, +198,209,208,36,7,188,189,179,240,238,82,97,80,93,122,32,125,144,132,160,12, +22,162,42,7,236,161,25,232,237,105,64,158,160,230,63,205,59,127,102,11,217, +66,51,210,129,61,65,236,127,154,118,254,205,171,197,34,168,48,6,90,194,1,0, +39,75,88,72,8,9,33,186,194,80,64,76,13,214,19,2,130,96,110,150,189,0,65,6, +51,214,20,128,65,17,11,214,19,130,137,121,211,210,211,144,6,39,75,88,80,0, +201,119,235,10,8,41,86,231,71,88,80,129,79,135,186,122,133,224,34,25,69, +234,80,3,91,141,172,40,96,139,113,180,181,133,36,21,110,54,142,134,176,165, +1,176,23,213,47,0,216,134,234,215,128,111,117,181,232,128,209,3,70,230,107, +64,5,139,168,209,235,10,32,36,144,102,235,136,3,146,27,172,40,160,146,132, +103,172,40,192,115,3,117,133,28,22,113,163,69,172,41,103,1,66,188,17,145, +52,168,4,202,113,67,76,130,227,76,194,13,240,108,0,0,83,224,0,2,193,0,104, +146,84,97,48,0,1,94,192,56,169,24,145,179,192,0,5,112,8,56,16,32,128,56,18, +52,125,230,86,147,190,140,28,50,21,13,39,31,23,60,145,158,57,12,141,47,129, +6,155,194,188,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155, +163,201,68,14,49,39,199,197,211,116,240,242,113,197,232,18,180,254,36,3,17, +46,18,243,35,100,128,172,156,178,70,163,154,76,34,248,146,164,108,248,75, +204,141,146,28,217,115,137,27,95,27,241,173,236,162,160,224,200,2,206,9, +113,13,148,192,209,18,22,164,146,37,193,57,162,4,249,39,196,128,24,2,178, +66,213,136,68,201,16,77,209,131,31,192,242,88,96,92,191,151,34,100,136,38, +232,255,252,92,221,199,197,12,68,209,82,66,212,11,155,185,41,197,13,55,38, +3,66,213,47,135,254,72,12,162,99,133,116,112,0,1,72,66,14,16,16,50,37,202, +160,150,154,66,14,20,8,57,192,28,24,80,113,50,113,100,105,166,120,248,0,0, +179,1,65,196,201,199,20,178,36,227,224,0,2,208,54,113,240,0,1,100,11,181, +192,0,5,178,1,18,160,65,24,131,20,145,25,188,48,132,122,28,76,146,218,121, +35,180,69,145,132,108,224,0,0,120,31,128,0,0,0,25,188,56,132,122,28,76,146, +218,121,35,180,69,145,132,108,224,0,0,120,31,128,0,0,0,40,160,45,110,23,30, +176,33,184,0,0,183,32,29,235,2,27,199,23,0,0,23,4,51,120,129,8,244,56,153, +37,180,242,71,104,139,35,8,217,192,0,0,240,63,0,0,0,0,51,120,145,8,244,56, +153,37,180,242,71,104,139,35,8,217,192,0,0,0,64,0,0,0,0,51,120,161,8,244, +56,153,37,180,242,71,104,139,35,8,217,192,0,0,0,64,0,0,0,0,51,120,177,8, +244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,120,193, +8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,120, +209,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51, +120,225,8,244,56,153,37,180,242,71,104,139,35,8,217,192,0,0,32,64,0,0,0,0, +32,227,194,0,97,57,162,4,246,104,5,34,92,35,68,225,161,166,220,16,16,137, +112,52,41,73,29,185,1,65,196,201,197,145,166,153,246,72,3,137,204,120,34, +74,8,199,1,67,17,162,112,201,84,128,97,144,78,25,42,16,131,169,1,205,66,8, +35,68,225,161,166,239,128,0,10,192,64,196,104,156,50,96,0,2,172,73,240,117, +96,57,170,97,4,104,156,52,52,221,240,0,1,82,1,74,9,129,125,240,0,1,82,32, +148,25,174,137,58,23,51,190,0,0,42,69,64,195,32,156,50,96,0,2,160,81,238,2, +3,107,173,218,3,192, +}; +#else +#error invalid endianness defines +#endif +#endif /* DUK_USE_ROM_OBJECTS */ diff --git a/third_party/duktape/duk_builtins.h b/third_party/duktape/duk_builtins.h new file mode 100644 index 00000000..e60902b4 --- /dev/null +++ b/third_party/duktape/duk_builtins.h @@ -0,0 +1,791 @@ +/* + * Automatically generated by genbuiltins.py, do not edit! + */ + +#if !defined(DUK_BUILTINS_H_INCLUDED) +#define DUK_BUILTINS_H_INCLUDED + +#if defined(DUK_USE_ROM_STRINGS) +#error ROM support not enabled, rerun configure.py with --rom-support +#else /* DUK_USE_ROM_STRINGS */ +#define DUK_STRIDX_UC_UNDEFINED 0 /* 'Undefined' */ +#define DUK_HEAP_STRING_UC_UNDEFINED(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_UNDEFINED) +#define DUK_HTHREAD_STRING_UC_UNDEFINED(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_UNDEFINED) +#define DUK_STRIDX_UC_NULL 1 /* 'Null' */ +#define DUK_HEAP_STRING_UC_NULL(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_NULL) +#define DUK_HTHREAD_STRING_UC_NULL(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_NULL) +#define DUK_STRIDX_UC_SYMBOL 2 /* 'Symbol' */ +#define DUK_HEAP_STRING_UC_SYMBOL(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_SYMBOL) +#define DUK_HTHREAD_STRING_UC_SYMBOL(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_SYMBOL) +#define DUK_STRIDX_UC_ARGUMENTS 3 /* 'Arguments' */ +#define DUK_HEAP_STRING_UC_ARGUMENTS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_ARGUMENTS) +#define DUK_HTHREAD_STRING_UC_ARGUMENTS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_ARGUMENTS) +#define DUK_STRIDX_UC_OBJECT 4 /* 'Object' */ +#define DUK_HEAP_STRING_UC_OBJECT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_OBJECT) +#define DUK_HTHREAD_STRING_UC_OBJECT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_OBJECT) +#define DUK_STRIDX_UC_FUNCTION 5 /* 'Function' */ +#define DUK_HEAP_STRING_UC_FUNCTION(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_FUNCTION) +#define DUK_HTHREAD_STRING_UC_FUNCTION(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_FUNCTION) +#define DUK_STRIDX_UC_ARRAY 6 /* 'Array' */ +#define DUK_HEAP_STRING_UC_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_ARRAY) +#define DUK_HTHREAD_STRING_UC_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_ARRAY) +#define DUK_STRIDX_UC_STRING 7 /* 'String' */ +#define DUK_HEAP_STRING_UC_STRING(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_STRING) +#define DUK_HTHREAD_STRING_UC_STRING(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_STRING) +#define DUK_STRIDX_UC_BOOLEAN 8 /* 'Boolean' */ +#define DUK_HEAP_STRING_UC_BOOLEAN(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_BOOLEAN) +#define DUK_HTHREAD_STRING_UC_BOOLEAN(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_BOOLEAN) +#define DUK_STRIDX_UC_NUMBER 9 /* 'Number' */ +#define DUK_HEAP_STRING_UC_NUMBER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_NUMBER) +#define DUK_HTHREAD_STRING_UC_NUMBER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_NUMBER) +#define DUK_STRIDX_UC_DATE 10 /* 'Date' */ +#define DUK_HEAP_STRING_UC_DATE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_DATE) +#define DUK_HTHREAD_STRING_UC_DATE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_DATE) +#define DUK_STRIDX_REG_EXP 11 /* 'RegExp' */ +#define DUK_HEAP_STRING_REG_EXP(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_REG_EXP) +#define DUK_HTHREAD_STRING_REG_EXP(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_REG_EXP) +#define DUK_STRIDX_UC_ERROR 12 /* 'Error' */ +#define DUK_HEAP_STRING_UC_ERROR(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_ERROR) +#define DUK_HTHREAD_STRING_UC_ERROR(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_ERROR) +#define DUK_STRIDX_MATH 13 /* 'Math' */ +#define DUK_HEAP_STRING_MATH(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MATH) +#define DUK_HTHREAD_STRING_MATH(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MATH) +#define DUK_STRIDX_JSON 14 /* 'JSON' */ +#define DUK_HEAP_STRING_JSON(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON) +#define DUK_HTHREAD_STRING_JSON(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON) +#define DUK_STRIDX_EMPTY_STRING 15 /* '' */ +#define DUK_HEAP_STRING_EMPTY_STRING(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EMPTY_STRING) +#define DUK_HTHREAD_STRING_EMPTY_STRING(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EMPTY_STRING) +#define DUK_STRIDX_ARRAY_BUFFER 16 /* 'ArrayBuffer' */ +#define DUK_HEAP_STRING_ARRAY_BUFFER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ARRAY_BUFFER) +#define DUK_HTHREAD_STRING_ARRAY_BUFFER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ARRAY_BUFFER) +#define DUK_STRIDX_DATA_VIEW 17 /* 'DataView' */ +#define DUK_HEAP_STRING_DATA_VIEW(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DATA_VIEW) +#define DUK_HTHREAD_STRING_DATA_VIEW(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DATA_VIEW) +#define DUK_STRIDX_INT8_ARRAY 18 /* 'Int8Array' */ +#define DUK_HEAP_STRING_INT8_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT8_ARRAY) +#define DUK_HTHREAD_STRING_INT8_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT8_ARRAY) +#define DUK_STRIDX_UINT8_ARRAY 19 /* 'Uint8Array' */ +#define DUK_HEAP_STRING_UINT8_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT8_ARRAY) +#define DUK_HTHREAD_STRING_UINT8_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT8_ARRAY) +#define DUK_STRIDX_UINT8_CLAMPED_ARRAY 20 /* 'Uint8ClampedArray' */ +#define DUK_HEAP_STRING_UINT8_CLAMPED_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT8_CLAMPED_ARRAY) +#define DUK_HTHREAD_STRING_UINT8_CLAMPED_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT8_CLAMPED_ARRAY) +#define DUK_STRIDX_INT16_ARRAY 21 /* 'Int16Array' */ +#define DUK_HEAP_STRING_INT16_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT16_ARRAY) +#define DUK_HTHREAD_STRING_INT16_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT16_ARRAY) +#define DUK_STRIDX_UINT16_ARRAY 22 /* 'Uint16Array' */ +#define DUK_HEAP_STRING_UINT16_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT16_ARRAY) +#define DUK_HTHREAD_STRING_UINT16_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT16_ARRAY) +#define DUK_STRIDX_INT32_ARRAY 23 /* 'Int32Array' */ +#define DUK_HEAP_STRING_INT32_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT32_ARRAY) +#define DUK_HTHREAD_STRING_INT32_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT32_ARRAY) +#define DUK_STRIDX_UINT32_ARRAY 24 /* 'Uint32Array' */ +#define DUK_HEAP_STRING_UINT32_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT32_ARRAY) +#define DUK_HTHREAD_STRING_UINT32_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT32_ARRAY) +#define DUK_STRIDX_FLOAT32_ARRAY 25 /* 'Float32Array' */ +#define DUK_HEAP_STRING_FLOAT32_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FLOAT32_ARRAY) +#define DUK_HTHREAD_STRING_FLOAT32_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FLOAT32_ARRAY) +#define DUK_STRIDX_FLOAT64_ARRAY 26 /* 'Float64Array' */ +#define DUK_HEAP_STRING_FLOAT64_ARRAY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FLOAT64_ARRAY) +#define DUK_HTHREAD_STRING_FLOAT64_ARRAY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FLOAT64_ARRAY) +#define DUK_STRIDX_GLOBAL 27 /* 'global' */ +#define DUK_HEAP_STRING_GLOBAL(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_GLOBAL) +#define DUK_HTHREAD_STRING_GLOBAL(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_GLOBAL) +#define DUK_STRIDX_OBJ_ENV 28 /* 'ObjEnv' */ +#define DUK_HEAP_STRING_OBJ_ENV(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_OBJ_ENV) +#define DUK_HTHREAD_STRING_OBJ_ENV(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_OBJ_ENV) +#define DUK_STRIDX_DEC_ENV 29 /* 'DecEnv' */ +#define DUK_HEAP_STRING_DEC_ENV(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEC_ENV) +#define DUK_HTHREAD_STRING_DEC_ENV(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEC_ENV) +#define DUK_STRIDX_UC_BUFFER 30 /* 'Buffer' */ +#define DUK_HEAP_STRING_UC_BUFFER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_BUFFER) +#define DUK_HTHREAD_STRING_UC_BUFFER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_BUFFER) +#define DUK_STRIDX_UC_POINTER 31 /* 'Pointer' */ +#define DUK_HEAP_STRING_UC_POINTER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_POINTER) +#define DUK_HTHREAD_STRING_UC_POINTER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_POINTER) +#define DUK_STRIDX_UC_THREAD 32 /* 'Thread' */ +#define DUK_HEAP_STRING_UC_THREAD(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_THREAD) +#define DUK_HTHREAD_STRING_UC_THREAD(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_THREAD) +#define DUK_STRIDX_EVAL 33 /* 'eval' */ +#define DUK_HEAP_STRING_EVAL(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EVAL) +#define DUK_HTHREAD_STRING_EVAL(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EVAL) +#define DUK_STRIDX_VALUE 34 /* 'value' */ +#define DUK_HEAP_STRING_VALUE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VALUE) +#define DUK_HTHREAD_STRING_VALUE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VALUE) +#define DUK_STRIDX_WRITABLE 35 /* 'writable' */ +#define DUK_HEAP_STRING_WRITABLE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WRITABLE) +#define DUK_HTHREAD_STRING_WRITABLE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WRITABLE) +#define DUK_STRIDX_CONFIGURABLE 36 /* 'configurable' */ +#define DUK_HEAP_STRING_CONFIGURABLE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONFIGURABLE) +#define DUK_HTHREAD_STRING_CONFIGURABLE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONFIGURABLE) +#define DUK_STRIDX_ENUMERABLE 37 /* 'enumerable' */ +#define DUK_HEAP_STRING_ENUMERABLE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ENUMERABLE) +#define DUK_HTHREAD_STRING_ENUMERABLE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ENUMERABLE) +#define DUK_STRIDX_JOIN 38 /* 'join' */ +#define DUK_HEAP_STRING_JOIN(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JOIN) +#define DUK_HTHREAD_STRING_JOIN(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JOIN) +#define DUK_STRIDX_TO_LOCALE_STRING 39 /* 'toLocaleString' */ +#define DUK_HEAP_STRING_TO_LOCALE_STRING(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_LOCALE_STRING) +#define DUK_HTHREAD_STRING_TO_LOCALE_STRING(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_LOCALE_STRING) +#define DUK_STRIDX_VALUE_OF 40 /* 'valueOf' */ +#define DUK_HEAP_STRING_VALUE_OF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VALUE_OF) +#define DUK_HTHREAD_STRING_VALUE_OF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VALUE_OF) +#define DUK_STRIDX_TO_UTC_STRING 41 /* 'toUTCString' */ +#define DUK_HEAP_STRING_TO_UTC_STRING(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_UTC_STRING) +#define DUK_HTHREAD_STRING_TO_UTC_STRING(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_UTC_STRING) +#define DUK_STRIDX_TO_ISO_STRING 42 /* 'toISOString' */ +#define DUK_HEAP_STRING_TO_ISO_STRING(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_ISO_STRING) +#define DUK_HTHREAD_STRING_TO_ISO_STRING(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_ISO_STRING) +#define DUK_STRIDX_TO_GMT_STRING 43 /* 'toGMTString' */ +#define DUK_HEAP_STRING_TO_GMT_STRING(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_GMT_STRING) +#define DUK_HTHREAD_STRING_TO_GMT_STRING(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_GMT_STRING) +#define DUK_STRIDX_SOURCE 44 /* 'source' */ +#define DUK_HEAP_STRING_SOURCE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SOURCE) +#define DUK_HTHREAD_STRING_SOURCE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SOURCE) +#define DUK_STRIDX_IGNORE_CASE 45 /* 'ignoreCase' */ +#define DUK_HEAP_STRING_IGNORE_CASE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IGNORE_CASE) +#define DUK_HTHREAD_STRING_IGNORE_CASE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IGNORE_CASE) +#define DUK_STRIDX_MULTILINE 46 /* 'multiline' */ +#define DUK_HEAP_STRING_MULTILINE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MULTILINE) +#define DUK_HTHREAD_STRING_MULTILINE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MULTILINE) +#define DUK_STRIDX_LAST_INDEX 47 /* 'lastIndex' */ +#define DUK_HEAP_STRING_LAST_INDEX(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LAST_INDEX) +#define DUK_HTHREAD_STRING_LAST_INDEX(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LAST_INDEX) +#define DUK_STRIDX_FLAGS 48 /* 'flags' */ +#define DUK_HEAP_STRING_FLAGS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FLAGS) +#define DUK_HTHREAD_STRING_FLAGS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FLAGS) +#define DUK_STRIDX_INDEX 49 /* 'index' */ +#define DUK_HEAP_STRING_INDEX(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INDEX) +#define DUK_HTHREAD_STRING_INDEX(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INDEX) +#define DUK_STRIDX_PROTOTYPE 50 /* 'prototype' */ +#define DUK_HEAP_STRING_PROTOTYPE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PROTOTYPE) +#define DUK_HTHREAD_STRING_PROTOTYPE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PROTOTYPE) +#define DUK_STRIDX_CONSTRUCTOR 51 /* 'constructor' */ +#define DUK_HEAP_STRING_CONSTRUCTOR(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONSTRUCTOR) +#define DUK_HTHREAD_STRING_CONSTRUCTOR(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONSTRUCTOR) +#define DUK_STRIDX_MESSAGE 52 /* 'message' */ +#define DUK_HEAP_STRING_MESSAGE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MESSAGE) +#define DUK_HTHREAD_STRING_MESSAGE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MESSAGE) +#define DUK_STRIDX_LC_BOOLEAN 53 /* 'boolean' */ +#define DUK_HEAP_STRING_LC_BOOLEAN(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_BOOLEAN) +#define DUK_HTHREAD_STRING_LC_BOOLEAN(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_BOOLEAN) +#define DUK_STRIDX_LC_NUMBER 54 /* 'number' */ +#define DUK_HEAP_STRING_LC_NUMBER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_NUMBER) +#define DUK_HTHREAD_STRING_LC_NUMBER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_NUMBER) +#define DUK_STRIDX_LC_STRING 55 /* 'string' */ +#define DUK_HEAP_STRING_LC_STRING(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_STRING) +#define DUK_HTHREAD_STRING_LC_STRING(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_STRING) +#define DUK_STRIDX_LC_SYMBOL 56 /* 'symbol' */ +#define DUK_HEAP_STRING_LC_SYMBOL(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_SYMBOL) +#define DUK_HTHREAD_STRING_LC_SYMBOL(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_SYMBOL) +#define DUK_STRIDX_LC_OBJECT 57 /* 'object' */ +#define DUK_HEAP_STRING_LC_OBJECT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_OBJECT) +#define DUK_HTHREAD_STRING_LC_OBJECT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_OBJECT) +#define DUK_STRIDX_LC_UNDEFINED 58 /* 'undefined' */ +#define DUK_HEAP_STRING_LC_UNDEFINED(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_UNDEFINED) +#define DUK_HTHREAD_STRING_LC_UNDEFINED(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_UNDEFINED) +#define DUK_STRIDX_NAN 59 /* 'NaN' */ +#define DUK_HEAP_STRING_NAN(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NAN) +#define DUK_HTHREAD_STRING_NAN(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NAN) +#define DUK_STRIDX_INFINITY 60 /* 'Infinity' */ +#define DUK_HEAP_STRING_INFINITY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INFINITY) +#define DUK_HTHREAD_STRING_INFINITY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INFINITY) +#define DUK_STRIDX_MINUS_INFINITY 61 /* '-Infinity' */ +#define DUK_HEAP_STRING_MINUS_INFINITY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MINUS_INFINITY) +#define DUK_HTHREAD_STRING_MINUS_INFINITY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MINUS_INFINITY) +#define DUK_STRIDX_MINUS_ZERO 62 /* '-0' */ +#define DUK_HEAP_STRING_MINUS_ZERO(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MINUS_ZERO) +#define DUK_HTHREAD_STRING_MINUS_ZERO(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MINUS_ZERO) +#define DUK_STRIDX_COMMA 63 /* ',' */ +#define DUK_HEAP_STRING_COMMA(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_COMMA) +#define DUK_HTHREAD_STRING_COMMA(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_COMMA) +#define DUK_STRIDX_NEWLINE_4SPACE 64 /* '\n ' */ +#define DUK_HEAP_STRING_NEWLINE_4SPACE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NEWLINE_4SPACE) +#define DUK_HTHREAD_STRING_NEWLINE_4SPACE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NEWLINE_4SPACE) +#define DUK_STRIDX_BRACKETED_ELLIPSIS 65 /* '[...]' */ +#define DUK_HEAP_STRING_BRACKETED_ELLIPSIS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BRACKETED_ELLIPSIS) +#define DUK_HTHREAD_STRING_BRACKETED_ELLIPSIS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BRACKETED_ELLIPSIS) +#define DUK_STRIDX_INVALID_DATE 66 /* 'Invalid Date' */ +#define DUK_HEAP_STRING_INVALID_DATE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INVALID_DATE) +#define DUK_HTHREAD_STRING_INVALID_DATE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INVALID_DATE) +#define DUK_STRIDX_LC_ARGUMENTS 67 /* 'arguments' */ +#define DUK_HEAP_STRING_LC_ARGUMENTS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_ARGUMENTS) +#define DUK_HTHREAD_STRING_LC_ARGUMENTS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_ARGUMENTS) +#define DUK_STRIDX_CALLEE 68 /* 'callee' */ +#define DUK_HEAP_STRING_CALLEE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CALLEE) +#define DUK_HTHREAD_STRING_CALLEE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CALLEE) +#define DUK_STRIDX_CALLER 69 /* 'caller' */ +#define DUK_HEAP_STRING_CALLER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CALLER) +#define DUK_HTHREAD_STRING_CALLER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CALLER) +#define DUK_STRIDX_APPLY 70 /* 'apply' */ +#define DUK_HEAP_STRING_APPLY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_APPLY) +#define DUK_HTHREAD_STRING_APPLY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_APPLY) +#define DUK_STRIDX_CONSTRUCT 71 /* 'construct' */ +#define DUK_HEAP_STRING_CONSTRUCT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONSTRUCT) +#define DUK_HTHREAD_STRING_CONSTRUCT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONSTRUCT) +#define DUK_STRIDX_DELETE_PROPERTY 72 /* 'deleteProperty' */ +#define DUK_HEAP_STRING_DELETE_PROPERTY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DELETE_PROPERTY) +#define DUK_HTHREAD_STRING_DELETE_PROPERTY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DELETE_PROPERTY) +#define DUK_STRIDX_GET 73 /* 'get' */ +#define DUK_HEAP_STRING_GET(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_GET) +#define DUK_HTHREAD_STRING_GET(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_GET) +#define DUK_STRIDX_HAS 74 /* 'has' */ +#define DUK_HEAP_STRING_HAS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_HAS) +#define DUK_HTHREAD_STRING_HAS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_HAS) +#define DUK_STRIDX_OWN_KEYS 75 /* 'ownKeys' */ +#define DUK_HEAP_STRING_OWN_KEYS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_OWN_KEYS) +#define DUK_HTHREAD_STRING_OWN_KEYS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_OWN_KEYS) +#define DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE 76 /* '\x81Symbol.toPrimitive\xff' */ +#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_TO_PRIMITIVE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE) +#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_TO_PRIMITIVE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE) +#define DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE 77 /* '\x81Symbol.hasInstance\xff' */ +#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_HAS_INSTANCE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE) +#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_HAS_INSTANCE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE) +#define DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG 78 /* '\x81Symbol.toStringTag\xff' */ +#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_TO_STRING_TAG(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG) +#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_TO_STRING_TAG(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG) +#define DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE 79 /* '\x81Symbol.isConcatSpreadable\xff' */ +#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE) +#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE) +#define DUK_STRIDX_SET_PROTOTYPE_OF 80 /* 'setPrototypeOf' */ +#define DUK_HEAP_STRING_SET_PROTOTYPE_OF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SET_PROTOTYPE_OF) +#define DUK_HTHREAD_STRING_SET_PROTOTYPE_OF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SET_PROTOTYPE_OF) +#define DUK_STRIDX___PROTO__ 81 /* '__proto__' */ +#define DUK_HEAP_STRING___PROTO__(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX___PROTO__) +#define DUK_HTHREAD_STRING___PROTO__(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX___PROTO__) +#define DUK_STRIDX_TO_STRING 82 /* 'toString' */ +#define DUK_HEAP_STRING_TO_STRING(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_STRING) +#define DUK_HTHREAD_STRING_TO_STRING(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_STRING) +#define DUK_STRIDX_TO_JSON 83 /* 'toJSON' */ +#define DUK_HEAP_STRING_TO_JSON(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_JSON) +#define DUK_HTHREAD_STRING_TO_JSON(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_JSON) +#define DUK_STRIDX_TYPE 84 /* 'type' */ +#define DUK_HEAP_STRING_TYPE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TYPE) +#define DUK_HTHREAD_STRING_TYPE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TYPE) +#define DUK_STRIDX_DATA 85 /* 'data' */ +#define DUK_HEAP_STRING_DATA(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DATA) +#define DUK_HTHREAD_STRING_DATA(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DATA) +#define DUK_STRIDX_LC_BUFFER 86 /* 'buffer' */ +#define DUK_HEAP_STRING_LC_BUFFER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_BUFFER) +#define DUK_HTHREAD_STRING_LC_BUFFER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_BUFFER) +#define DUK_STRIDX_LENGTH 87 /* 'length' */ +#define DUK_HEAP_STRING_LENGTH(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LENGTH) +#define DUK_HTHREAD_STRING_LENGTH(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LENGTH) +#define DUK_STRIDX_SET 88 /* 'set' */ +#define DUK_HEAP_STRING_SET(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SET) +#define DUK_HTHREAD_STRING_SET(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SET) +#define DUK_STRIDX_STACK 89 /* 'stack' */ +#define DUK_HEAP_STRING_STACK(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_STACK) +#define DUK_HTHREAD_STRING_STACK(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_STACK) +#define DUK_STRIDX_PC 90 /* 'pc' */ +#define DUK_HEAP_STRING_PC(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PC) +#define DUK_HTHREAD_STRING_PC(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PC) +#define DUK_STRIDX_LINE_NUMBER 91 /* 'lineNumber' */ +#define DUK_HEAP_STRING_LINE_NUMBER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LINE_NUMBER) +#define DUK_HTHREAD_STRING_LINE_NUMBER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LINE_NUMBER) +#define DUK_STRIDX_INT_TRACEDATA 92 /* '\x82Tracedata' */ +#define DUK_HEAP_STRING_INT_TRACEDATA(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_TRACEDATA) +#define DUK_HTHREAD_STRING_INT_TRACEDATA(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_TRACEDATA) +#define DUK_STRIDX_NAME 93 /* 'name' */ +#define DUK_HEAP_STRING_NAME(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NAME) +#define DUK_HTHREAD_STRING_NAME(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NAME) +#define DUK_STRIDX_FILE_NAME 94 /* 'fileName' */ +#define DUK_HEAP_STRING_FILE_NAME(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FILE_NAME) +#define DUK_HTHREAD_STRING_FILE_NAME(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FILE_NAME) +#define DUK_STRIDX_LC_POINTER 95 /* 'pointer' */ +#define DUK_HEAP_STRING_LC_POINTER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_POINTER) +#define DUK_HTHREAD_STRING_LC_POINTER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_POINTER) +#define DUK_STRIDX_INT_TARGET 96 /* '\x82Target' */ +#define DUK_HEAP_STRING_INT_TARGET(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_TARGET) +#define DUK_HTHREAD_STRING_INT_TARGET(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_TARGET) +#define DUK_STRIDX_INT_NEXT 97 /* '\x82Next' */ +#define DUK_HEAP_STRING_INT_NEXT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_NEXT) +#define DUK_HTHREAD_STRING_INT_NEXT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_NEXT) +#define DUK_STRIDX_INT_BYTECODE 98 /* '\x82Bytecode' */ +#define DUK_HEAP_STRING_INT_BYTECODE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_BYTECODE) +#define DUK_HTHREAD_STRING_INT_BYTECODE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_BYTECODE) +#define DUK_STRIDX_INT_FORMALS 99 /* '\x82Formals' */ +#define DUK_HEAP_STRING_INT_FORMALS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_FORMALS) +#define DUK_HTHREAD_STRING_INT_FORMALS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_FORMALS) +#define DUK_STRIDX_INT_VARMAP 100 /* '\x82Varmap' */ +#define DUK_HEAP_STRING_INT_VARMAP(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VARMAP) +#define DUK_HTHREAD_STRING_INT_VARMAP(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VARMAP) +#define DUK_STRIDX_INT_SOURCE 101 /* '\x82Source' */ +#define DUK_HEAP_STRING_INT_SOURCE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_SOURCE) +#define DUK_HTHREAD_STRING_INT_SOURCE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_SOURCE) +#define DUK_STRIDX_INT_PC2LINE 102 /* '\x82Pc2line' */ +#define DUK_HEAP_STRING_INT_PC2LINE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_PC2LINE) +#define DUK_HTHREAD_STRING_INT_PC2LINE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_PC2LINE) +#define DUK_STRIDX_INT_MAP 103 /* '\x82Map' */ +#define DUK_HEAP_STRING_INT_MAP(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_MAP) +#define DUK_HTHREAD_STRING_INT_MAP(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_MAP) +#define DUK_STRIDX_INT_VARENV 104 /* '\x82Varenv' */ +#define DUK_HEAP_STRING_INT_VARENV(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VARENV) +#define DUK_HTHREAD_STRING_INT_VARENV(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VARENV) +#define DUK_STRIDX_INT_FINALIZER 105 /* '\x82Finalizer' */ +#define DUK_HEAP_STRING_INT_FINALIZER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_FINALIZER) +#define DUK_HTHREAD_STRING_INT_FINALIZER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_FINALIZER) +#define DUK_STRIDX_INT_VALUE 106 /* '\x82Value' */ +#define DUK_HEAP_STRING_INT_VALUE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VALUE) +#define DUK_HTHREAD_STRING_INT_VALUE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VALUE) +#define DUK_STRIDX_COMPILE 107 /* 'compile' */ +#define DUK_HEAP_STRING_COMPILE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_COMPILE) +#define DUK_HTHREAD_STRING_COMPILE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_COMPILE) +#define DUK_STRIDX_INPUT 108 /* 'input' */ +#define DUK_HEAP_STRING_INPUT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INPUT) +#define DUK_HTHREAD_STRING_INPUT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INPUT) +#define DUK_STRIDX_ERR_CREATE 109 /* 'errCreate' */ +#define DUK_HEAP_STRING_ERR_CREATE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ERR_CREATE) +#define DUK_HTHREAD_STRING_ERR_CREATE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ERR_CREATE) +#define DUK_STRIDX_ERR_THROW 110 /* 'errThrow' */ +#define DUK_HEAP_STRING_ERR_THROW(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ERR_THROW) +#define DUK_HTHREAD_STRING_ERR_THROW(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ERR_THROW) +#define DUK_STRIDX_ENV 111 /* 'env' */ +#define DUK_HEAP_STRING_ENV(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ENV) +#define DUK_HTHREAD_STRING_ENV(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ENV) +#define DUK_STRIDX_HEX 112 /* 'hex' */ +#define DUK_HEAP_STRING_HEX(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_HEX) +#define DUK_HTHREAD_STRING_HEX(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_HEX) +#define DUK_STRIDX_BASE64 113 /* 'base64' */ +#define DUK_HEAP_STRING_BASE64(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BASE64) +#define DUK_HTHREAD_STRING_BASE64(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BASE64) +#define DUK_STRIDX_JX 114 /* 'jx' */ +#define DUK_HEAP_STRING_JX(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JX) +#define DUK_HTHREAD_STRING_JX(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JX) +#define DUK_STRIDX_JC 115 /* 'jc' */ +#define DUK_HEAP_STRING_JC(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JC) +#define DUK_HTHREAD_STRING_JC(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JC) +#define DUK_STRIDX_JSON_EXT_UNDEFINED 116 /* '{"_undef":true}' */ +#define DUK_HEAP_STRING_JSON_EXT_UNDEFINED(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_UNDEFINED) +#define DUK_HTHREAD_STRING_JSON_EXT_UNDEFINED(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_UNDEFINED) +#define DUK_STRIDX_JSON_EXT_NAN 117 /* '{"_nan":true}' */ +#define DUK_HEAP_STRING_JSON_EXT_NAN(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_NAN) +#define DUK_HTHREAD_STRING_JSON_EXT_NAN(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_NAN) +#define DUK_STRIDX_JSON_EXT_POSINF 118 /* '{"_inf":true}' */ +#define DUK_HEAP_STRING_JSON_EXT_POSINF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_POSINF) +#define DUK_HTHREAD_STRING_JSON_EXT_POSINF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_POSINF) +#define DUK_STRIDX_JSON_EXT_NEGINF 119 /* '{"_ninf":true}' */ +#define DUK_HEAP_STRING_JSON_EXT_NEGINF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_NEGINF) +#define DUK_HTHREAD_STRING_JSON_EXT_NEGINF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_NEGINF) +#define DUK_STRIDX_JSON_EXT_FUNCTION1 120 /* '{"_func":true}' */ +#define DUK_HEAP_STRING_JSON_EXT_FUNCTION1(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_FUNCTION1) +#define DUK_HTHREAD_STRING_JSON_EXT_FUNCTION1(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_FUNCTION1) +#define DUK_STRIDX_JSON_EXT_FUNCTION2 121 /* '{_func:true}' */ +#define DUK_HEAP_STRING_JSON_EXT_FUNCTION2(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_FUNCTION2) +#define DUK_HTHREAD_STRING_JSON_EXT_FUNCTION2(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_FUNCTION2) +#define DUK_STRIDX_BREAK 122 /* 'break' */ +#define DUK_HEAP_STRING_BREAK(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BREAK) +#define DUK_HTHREAD_STRING_BREAK(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BREAK) +#define DUK_STRIDX_CASE 123 /* 'case' */ +#define DUK_HEAP_STRING_CASE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CASE) +#define DUK_HTHREAD_STRING_CASE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CASE) +#define DUK_STRIDX_CATCH 124 /* 'catch' */ +#define DUK_HEAP_STRING_CATCH(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CATCH) +#define DUK_HTHREAD_STRING_CATCH(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CATCH) +#define DUK_STRIDX_CONTINUE 125 /* 'continue' */ +#define DUK_HEAP_STRING_CONTINUE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONTINUE) +#define DUK_HTHREAD_STRING_CONTINUE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONTINUE) +#define DUK_STRIDX_DEBUGGER 126 /* 'debugger' */ +#define DUK_HEAP_STRING_DEBUGGER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEBUGGER) +#define DUK_HTHREAD_STRING_DEBUGGER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEBUGGER) +#define DUK_STRIDX_DEFAULT 127 /* 'default' */ +#define DUK_HEAP_STRING_DEFAULT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEFAULT) +#define DUK_HTHREAD_STRING_DEFAULT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEFAULT) +#define DUK_STRIDX_DELETE 128 /* 'delete' */ +#define DUK_HEAP_STRING_DELETE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DELETE) +#define DUK_HTHREAD_STRING_DELETE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DELETE) +#define DUK_STRIDX_DO 129 /* 'do' */ +#define DUK_HEAP_STRING_DO(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DO) +#define DUK_HTHREAD_STRING_DO(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DO) +#define DUK_STRIDX_ELSE 130 /* 'else' */ +#define DUK_HEAP_STRING_ELSE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ELSE) +#define DUK_HTHREAD_STRING_ELSE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ELSE) +#define DUK_STRIDX_FINALLY 131 /* 'finally' */ +#define DUK_HEAP_STRING_FINALLY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FINALLY) +#define DUK_HTHREAD_STRING_FINALLY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FINALLY) +#define DUK_STRIDX_FOR 132 /* 'for' */ +#define DUK_HEAP_STRING_FOR(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FOR) +#define DUK_HTHREAD_STRING_FOR(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FOR) +#define DUK_STRIDX_LC_FUNCTION 133 /* 'function' */ +#define DUK_HEAP_STRING_LC_FUNCTION(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_FUNCTION) +#define DUK_HTHREAD_STRING_LC_FUNCTION(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_FUNCTION) +#define DUK_STRIDX_IF 134 /* 'if' */ +#define DUK_HEAP_STRING_IF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IF) +#define DUK_HTHREAD_STRING_IF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IF) +#define DUK_STRIDX_IN 135 /* 'in' */ +#define DUK_HEAP_STRING_IN(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IN) +#define DUK_HTHREAD_STRING_IN(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IN) +#define DUK_STRIDX_INSTANCEOF 136 /* 'instanceof' */ +#define DUK_HEAP_STRING_INSTANCEOF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INSTANCEOF) +#define DUK_HTHREAD_STRING_INSTANCEOF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INSTANCEOF) +#define DUK_STRIDX_NEW 137 /* 'new' */ +#define DUK_HEAP_STRING_NEW(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NEW) +#define DUK_HTHREAD_STRING_NEW(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NEW) +#define DUK_STRIDX_RETURN 138 /* 'return' */ +#define DUK_HEAP_STRING_RETURN(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_RETURN) +#define DUK_HTHREAD_STRING_RETURN(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_RETURN) +#define DUK_STRIDX_SWITCH 139 /* 'switch' */ +#define DUK_HEAP_STRING_SWITCH(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SWITCH) +#define DUK_HTHREAD_STRING_SWITCH(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SWITCH) +#define DUK_STRIDX_THIS 140 /* 'this' */ +#define DUK_HEAP_STRING_THIS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_THIS) +#define DUK_HTHREAD_STRING_THIS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_THIS) +#define DUK_STRIDX_THROW 141 /* 'throw' */ +#define DUK_HEAP_STRING_THROW(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_THROW) +#define DUK_HTHREAD_STRING_THROW(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_THROW) +#define DUK_STRIDX_TRY 142 /* 'try' */ +#define DUK_HEAP_STRING_TRY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TRY) +#define DUK_HTHREAD_STRING_TRY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TRY) +#define DUK_STRIDX_TYPEOF 143 /* 'typeof' */ +#define DUK_HEAP_STRING_TYPEOF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TYPEOF) +#define DUK_HTHREAD_STRING_TYPEOF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TYPEOF) +#define DUK_STRIDX_VAR 144 /* 'var' */ +#define DUK_HEAP_STRING_VAR(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VAR) +#define DUK_HTHREAD_STRING_VAR(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VAR) +#define DUK_STRIDX_CONST 145 /* 'const' */ +#define DUK_HEAP_STRING_CONST(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONST) +#define DUK_HTHREAD_STRING_CONST(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONST) +#define DUK_STRIDX_VOID 146 /* 'void' */ +#define DUK_HEAP_STRING_VOID(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VOID) +#define DUK_HTHREAD_STRING_VOID(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VOID) +#define DUK_STRIDX_WHILE 147 /* 'while' */ +#define DUK_HEAP_STRING_WHILE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WHILE) +#define DUK_HTHREAD_STRING_WHILE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WHILE) +#define DUK_STRIDX_WITH 148 /* 'with' */ +#define DUK_HEAP_STRING_WITH(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WITH) +#define DUK_HTHREAD_STRING_WITH(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WITH) +#define DUK_STRIDX_CLASS 149 /* 'class' */ +#define DUK_HEAP_STRING_CLASS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CLASS) +#define DUK_HTHREAD_STRING_CLASS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CLASS) +#define DUK_STRIDX_ENUM 150 /* 'enum' */ +#define DUK_HEAP_STRING_ENUM(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ENUM) +#define DUK_HTHREAD_STRING_ENUM(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ENUM) +#define DUK_STRIDX_EXPORT 151 /* 'export' */ +#define DUK_HEAP_STRING_EXPORT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EXPORT) +#define DUK_HTHREAD_STRING_EXPORT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EXPORT) +#define DUK_STRIDX_EXTENDS 152 /* 'extends' */ +#define DUK_HEAP_STRING_EXTENDS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EXTENDS) +#define DUK_HTHREAD_STRING_EXTENDS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EXTENDS) +#define DUK_STRIDX_IMPORT 153 /* 'import' */ +#define DUK_HEAP_STRING_IMPORT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IMPORT) +#define DUK_HTHREAD_STRING_IMPORT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IMPORT) +#define DUK_STRIDX_SUPER 154 /* 'super' */ +#define DUK_HEAP_STRING_SUPER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SUPER) +#define DUK_HTHREAD_STRING_SUPER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SUPER) +#define DUK_STRIDX_LC_NULL 155 /* 'null' */ +#define DUK_HEAP_STRING_LC_NULL(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_NULL) +#define DUK_HTHREAD_STRING_LC_NULL(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_NULL) +#define DUK_STRIDX_TRUE 156 /* 'true' */ +#define DUK_HEAP_STRING_TRUE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TRUE) +#define DUK_HTHREAD_STRING_TRUE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TRUE) +#define DUK_STRIDX_FALSE 157 /* 'false' */ +#define DUK_HEAP_STRING_FALSE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FALSE) +#define DUK_HTHREAD_STRING_FALSE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FALSE) +#define DUK_STRIDX_IMPLEMENTS 158 /* 'implements' */ +#define DUK_HEAP_STRING_IMPLEMENTS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IMPLEMENTS) +#define DUK_HTHREAD_STRING_IMPLEMENTS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IMPLEMENTS) +#define DUK_STRIDX_INTERFACE 159 /* 'interface' */ +#define DUK_HEAP_STRING_INTERFACE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INTERFACE) +#define DUK_HTHREAD_STRING_INTERFACE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INTERFACE) +#define DUK_STRIDX_LET 160 /* 'let' */ +#define DUK_HEAP_STRING_LET(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LET) +#define DUK_HTHREAD_STRING_LET(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LET) +#define DUK_STRIDX_PACKAGE 161 /* 'package' */ +#define DUK_HEAP_STRING_PACKAGE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PACKAGE) +#define DUK_HTHREAD_STRING_PACKAGE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PACKAGE) +#define DUK_STRIDX_PRIVATE 162 /* 'private' */ +#define DUK_HEAP_STRING_PRIVATE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PRIVATE) +#define DUK_HTHREAD_STRING_PRIVATE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PRIVATE) +#define DUK_STRIDX_PROTECTED 163 /* 'protected' */ +#define DUK_HEAP_STRING_PROTECTED(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PROTECTED) +#define DUK_HTHREAD_STRING_PROTECTED(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PROTECTED) +#define DUK_STRIDX_PUBLIC 164 /* 'public' */ +#define DUK_HEAP_STRING_PUBLIC(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PUBLIC) +#define DUK_HTHREAD_STRING_PUBLIC(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PUBLIC) +#define DUK_STRIDX_STATIC 165 /* 'static' */ +#define DUK_HEAP_STRING_STATIC(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_STATIC) +#define DUK_HTHREAD_STRING_STATIC(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_STATIC) +#define DUK_STRIDX_YIELD 166 /* 'yield' */ +#define DUK_HEAP_STRING_YIELD(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_YIELD) +#define DUK_HTHREAD_STRING_YIELD(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_YIELD) + +#define DUK_HEAP_NUM_STRINGS 167 +#define DUK_STRIDX_START_RESERVED 122 +#define DUK_STRIDX_START_STRICT_RESERVED 158 +#define DUK_STRIDX_END_RESERVED 167 /* exclusive endpoint */ + +/* To convert a heap stridx to a token number, subtract + * DUK_STRIDX_START_RESERVED and add DUK_TOK_START_RESERVED. + */ +#if !defined(DUK_SINGLE_FILE) +DUK_INTERNAL_DECL const duk_uint8_t duk_strings_data[972]; +#endif /* !DUK_SINGLE_FILE */ +#define DUK_STRDATA_MAX_STRLEN 27 +#define DUK_STRDATA_DATA_LENGTH 972 +#endif /* DUK_USE_ROM_STRINGS */ + +#if defined(DUK_USE_ROM_OBJECTS) +#error RAM support not enabled, rerun configure.py with --ram-support +#else /* DUK_USE_ROM_OBJECTS */ +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_function_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_array_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_boolean_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_number_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_date_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_error_constructor_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_type_error_thrower(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_parse_int(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_parse_float(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_thread_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_pointer_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_proxy_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_constructor_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_arraybuffer_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_dataview_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_textencoder_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_constructor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_eval(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_is_nan(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_is_finite(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_decode_uri(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_decode_uri_component(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_encode_uri(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_encode_uri_component(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_escape(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_unescape(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_getprototype_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_setprototype_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_get_own_property_descriptor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_keys_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_assign(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_create(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_define_property(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_define_properties(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_seal_freeze_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_is_sealed_frozen_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_is_extensible(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_is(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_string(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_locale_string(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_value_of(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_has_own_property(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_is_prototype_of(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_property_is_enumerable(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_defineaccessor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_lookupaccessor(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_to_string(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_apply(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_call(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_bind(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_hasinstance(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_native_function_length(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_native_function_name(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_array_constructor_is_array(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_to_string(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_join_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_concat(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_pop(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_push(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_reverse(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_shift(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_slice(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_sort(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_splice(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_unshift(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_indexof_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_iter_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_reduce_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_constructor_from_char_code(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_constructor_from_code_point(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_to_string(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_char_at(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_char_code_at(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_concat(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_indexof_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_locale_compare(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_match(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_search(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_slice(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_split(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_substring(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_caseconv_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_trim(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_repeat(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_includes(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_substr(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_boolean_prototype_tostring_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_number_check_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_string(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_locale_string(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_value_of(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_fixed(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_exponential(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_precision(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_date_constructor_parse(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_date_constructor_utc(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_date_constructor_now(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_tostring_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_to_json(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_value_of(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_get_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_get_timezone_offset(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_set_time(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_set_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_toprimitive(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_exec(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_test(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_tostring(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_flags(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_stack_getter(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_stack_setter(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_filename_getter(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_filename_setter(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_linenumber_setter(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_to_string(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_onearg_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_twoarg_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_clz32(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_hypot(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_imul(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_max(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_min(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_random(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_sign(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_json_object_parse(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_json_object_stringify(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_info(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_act(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_gc(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_fin(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_enc(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_dec(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_compact(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_thread_yield(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_thread_resume(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_thread_current(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_apply(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_construct(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_delete_property(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_get(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_has(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_set(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_key_for(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_tostring_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_toprimitive(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_arraybuffer_isview(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_buffer_getter(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_set(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_uint8array_allocplain(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_uint8array_plainof(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_concat(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_is_encoding(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_is_buffer(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_byte_length(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_compare_shared(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_fill(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_copy(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_write(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_cbor_encode(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_cbor_decode(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_textencoder_prototype_encoding_getter(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_textencoder_prototype_encode(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_prototype_shared_getter(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_prototype_decode(duk_context *ctx); +DUK_INTERNAL_DECL duk_ret_t duk_bi_performance_now(duk_context *ctx); +#if !defined(DUK_SINGLE_FILE) +DUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[185]; +#endif /* !DUK_SINGLE_FILE */ +#define DUK_BIDX_GLOBAL 0 +#define DUK_BIDX_GLOBAL_ENV 1 +#define DUK_BIDX_OBJECT_CONSTRUCTOR 2 +#define DUK_BIDX_OBJECT_PROTOTYPE 3 +#define DUK_BIDX_FUNCTION_CONSTRUCTOR 4 +#define DUK_BIDX_FUNCTION_PROTOTYPE 5 +#define DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE 6 +#define DUK_BIDX_ARRAY_CONSTRUCTOR 7 +#define DUK_BIDX_ARRAY_PROTOTYPE 8 +#define DUK_BIDX_STRING_CONSTRUCTOR 9 +#define DUK_BIDX_STRING_PROTOTYPE 10 +#define DUK_BIDX_BOOLEAN_CONSTRUCTOR 11 +#define DUK_BIDX_BOOLEAN_PROTOTYPE 12 +#define DUK_BIDX_NUMBER_CONSTRUCTOR 13 +#define DUK_BIDX_NUMBER_PROTOTYPE 14 +#define DUK_BIDX_DATE_CONSTRUCTOR 15 +#define DUK_BIDX_DATE_PROTOTYPE 16 +#define DUK_BIDX_REGEXP_CONSTRUCTOR 17 +#define DUK_BIDX_REGEXP_PROTOTYPE 18 +#define DUK_BIDX_ERROR_CONSTRUCTOR 19 +#define DUK_BIDX_ERROR_PROTOTYPE 20 +#define DUK_BIDX_EVAL_ERROR_CONSTRUCTOR 21 +#define DUK_BIDX_EVAL_ERROR_PROTOTYPE 22 +#define DUK_BIDX_RANGE_ERROR_CONSTRUCTOR 23 +#define DUK_BIDX_RANGE_ERROR_PROTOTYPE 24 +#define DUK_BIDX_REFERENCE_ERROR_CONSTRUCTOR 25 +#define DUK_BIDX_REFERENCE_ERROR_PROTOTYPE 26 +#define DUK_BIDX_SYNTAX_ERROR_CONSTRUCTOR 27 +#define DUK_BIDX_SYNTAX_ERROR_PROTOTYPE 28 +#define DUK_BIDX_TYPE_ERROR_CONSTRUCTOR 29 +#define DUK_BIDX_TYPE_ERROR_PROTOTYPE 30 +#define DUK_BIDX_URI_ERROR_CONSTRUCTOR 31 +#define DUK_BIDX_URI_ERROR_PROTOTYPE 32 +#define DUK_BIDX_TYPE_ERROR_THROWER 33 +#define DUK_BIDX_DUKTAPE 34 +#define DUK_BIDX_THREAD_PROTOTYPE 35 +#define DUK_BIDX_POINTER_PROTOTYPE 36 +#define DUK_BIDX_DOUBLE_ERROR 37 +#define DUK_BIDX_SYMBOL_PROTOTYPE 38 +#define DUK_BIDX_ARRAYBUFFER_PROTOTYPE 39 +#define DUK_BIDX_DATAVIEW_PROTOTYPE 40 +#define DUK_BIDX_INT8ARRAY_PROTOTYPE 41 +#define DUK_BIDX_UINT8ARRAY_PROTOTYPE 42 +#define DUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE 43 +#define DUK_BIDX_INT16ARRAY_PROTOTYPE 44 +#define DUK_BIDX_UINT16ARRAY_PROTOTYPE 45 +#define DUK_BIDX_INT32ARRAY_PROTOTYPE 46 +#define DUK_BIDX_UINT32ARRAY_PROTOTYPE 47 +#define DUK_BIDX_FLOAT32ARRAY_PROTOTYPE 48 +#define DUK_BIDX_FLOAT64ARRAY_PROTOTYPE 49 +#define DUK_BIDX_NODEJS_BUFFER_PROTOTYPE 50 +#define DUK_NUM_BUILTINS 51 +#define DUK_NUM_BIDX_BUILTINS 51 +#define DUK_NUM_ALL_BUILTINS 80 +#if defined(DUK_USE_DOUBLE_LE) +#if !defined(DUK_SINGLE_FILE) +DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4281]; +#endif /* !DUK_SINGLE_FILE */ +#define DUK_BUILTINS_DATA_LENGTH 4281 +#elif defined(DUK_USE_DOUBLE_BE) +#if !defined(DUK_SINGLE_FILE) +DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4281]; +#endif /* !DUK_SINGLE_FILE */ +#define DUK_BUILTINS_DATA_LENGTH 4281 +#elif defined(DUK_USE_DOUBLE_ME) +#if !defined(DUK_SINGLE_FILE) +DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4281]; +#endif /* !DUK_SINGLE_FILE */ +#define DUK_BUILTINS_DATA_LENGTH 4281 +#else +#error invalid endianness defines +#endif +#endif /* DUK_USE_ROM_OBJECTS */ +#endif /* DUK_BUILTINS_H_INCLUDED */ diff --git a/third_party/duktape/duk_config.h b/third_party/duktape/duk_config.h new file mode 100644 index 00000000..441c0dfc --- /dev/null +++ b/third_party/duktape/duk_config.h @@ -0,0 +1,2181 @@ +/* + * duk_config.h configuration header generated by genconfig.py. + * + * Git commit: 0dce8a3ba7eeb3fa3bec7e258b35edab1443ae60 + * Git describe: v2.4.0-55-g0dce8a3b-dirty + * Git branch: master + * + * Supported platforms: + * - Mac OSX, iPhone, Darwin + * - Orbis + * - OpenBSD + * - Generic BSD + * - Atari ST TOS + * - AmigaOS + * - Durango (XboxOne) + * - Windows + * - Flashplayer (Crossbridge) + * - QNX + * - TI-Nspire + * - Emscripten + * - Android + * - Linux + * - Solaris + * - AIX + * - HPUX + * - Generic POSIX + * - Cygwin + * - Generic UNIX + * - Generic fallback + * + * Architecture: x64 + * + * Compiler: gcc + * + */ + +#if !defined(DUK_CONFIG_H_INCLUDED) +#define DUK_CONFIG_H_INCLUDED +#include "libc/assert.h" +#include "libc/calls/calls.h" +#include "libc/calls/struct/dirent.h" +#include "libc/calls/struct/stat.h" +#include "libc/calls/struct/timeval.h" +#include "libc/calls/termios.h" +#include "libc/calls/typedef/sighandler_t.h" +#include "libc/calls/weirdtypes.h" +#include "libc/conv/conv.h" +#include "libc/errno.h" +#include "libc/fmt/fmt.h" +#include "libc/inttypes.h" +#include "libc/limits.h" +#include "libc/math.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/sysconf.h" +#include "libc/sock/sock.h" +#include "libc/stdio/stdio.h" +#include "libc/stdio/temp.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/clock.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/termios.h" +#include "libc/sysv/consts/w.h" +#include "libc/time/struct/tm.h" +#include "libc/time/time.h" +#pragma GCC diagnostic ignored "-Wunused-function" + +/* + * Intermediate helper defines + */ + +/* DLL build detection */ +/* not configured for DLL build */ +#undef DUK_F_DLL_BUILD + +/* Apple OSX, iOS */ +#if defined(__APPLE__) +#define DUK_F_APPLE +#endif + +/* FreeBSD */ +#if defined(__FreeBSD__) || defined(__FreeBSD) +#define DUK_F_FREEBSD +#endif + +/* Orbis (PS4) variant */ +#if defined(DUK_F_FREEBSD) && defined(__ORBIS__) +#define DUK_F_ORBIS +#endif + +/* OpenBSD */ +#if defined(__OpenBSD__) || defined(__OpenBSD) +#define DUK_F_OPENBSD +#endif + +/* NetBSD */ +#if defined(__NetBSD__) || defined(__NetBSD) +#define DUK_F_NETBSD +#endif + +/* BSD variant */ +#if defined(DUK_F_FREEBSD) || defined(DUK_F_NETBSD) || \ + defined(DUK_F_OPENBSD) || defined(__bsdi__) || defined(__DragonFly__) +#define DUK_F_BSD +#endif + +/* Atari ST TOS. __TOS__ defined by PureC. No platform define in VBCC + * apparently, so to use with VBCC user must define __TOS__ manually. + */ +#if defined(__TOS__) +#define DUK_F_TOS +#endif + +/* Motorola 68K. Not defined by VBCC, so user must define one of these + * manually when using VBCC. + */ +#if defined(__m68k__) || defined(M68000) || defined(__MC68K__) +#define DUK_F_M68K +#endif + +/* AmigaOS. Neither AMIGA nor __amigaos__ is defined on VBCC, so user must + * define 'AMIGA' manually when using VBCC. + */ +#if defined(AMIGA) || defined(__amigaos__) +#define DUK_F_AMIGAOS +#endif + +/* PowerPC */ +#if defined(__powerpc) || defined(__powerpc__) || defined(__PPC__) +#define DUK_F_PPC +#if defined(__PPC64__) || defined(__LP64__) || defined(_LP64) +#define DUK_F_PPC64 +#else +#define DUK_F_PPC32 +#endif +#endif + +/* Durango (Xbox One) */ +#if defined(_DURANGO) || defined(_XBOX_ONE) +#define DUK_F_DURANGO +#endif + +/* Windows, both 32-bit and 64-bit */ +#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64) || \ + defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) +#define DUK_F_WINDOWS +#if defined(_WIN64) || defined(WIN64) +#define DUK_F_WIN64 +#else +#define DUK_F_WIN32 +#endif +#endif + +/* Flash player (e.g. Crossbridge) */ +#if defined(__FLASHPLAYER__) +#define DUK_F_FLASHPLAYER +#endif + +/* QNX */ +#if defined(__QNX__) +#define DUK_F_QNX +#endif + +/* TI-Nspire (using Ndless) */ +#if defined(_TINSPIRE) +#define DUK_F_TINSPIRE +#endif + +/* Emscripten (provided explicitly by user), improve if possible */ +#if defined(EMSCRIPTEN) +#define DUK_F_EMSCRIPTEN +#endif + +/* BCC (Bruce's C compiler): this is a "torture target" for compilation */ +#if defined(__BCC__) || defined(__BCC_VERSION__) +#define DUK_F_BCC +#endif + +#if defined(ANDROID) || defined(__ANDROID__) +#define DUK_F_ANDROID +#endif + +/* Linux */ +#if defined(__linux) || defined(__linux__) || defined(linux) +#define DUK_F_LINUX +#endif + +/* illumos / Solaris */ +#if defined(__sun) && defined(__SVR4) +#define DUK_F_SUN +#if defined(__SUNPRO_C) && (__SUNPRO_C < 0x550) +#define DUK_F_OLD_SOLARIS +/* Defines _ILP32 / _LP64 required by DUK_F_X86/DUK_F_X64. Platforms + * are processed before architectures, so this happens before the + * DUK_F_X86/DUK_F_X64 detection is emitted. + */ +#endif +#endif + +/* AIX */ +#if defined(_AIX) +/* defined(__xlc__) || defined(__IBMC__): works but too wide */ +#define DUK_F_AIX +#endif + +/* HPUX */ +#if defined(__hpux) +#define DUK_F_HPUX +#if defined(__ia64) +#define DUK_F_HPUX_ITANIUM +#endif +#endif + +/* POSIX */ +#if defined(__posix) +#define DUK_F_POSIX +#endif + +/* Cygwin */ +#if defined(__CYGWIN__) +#define DUK_F_CYGWIN +#endif + +/* Generic Unix (includes Cygwin) */ +#if defined(__unix) || defined(__unix__) || defined(unix) || \ + defined(DUK_F_LINUX) || defined(DUK_F_BSD) +#define DUK_F_UNIX +#endif + +/* MinGW. Also GCC flags (DUK_F_GCC) are enabled now. */ +#if defined(__MINGW32__) || defined(__MINGW64__) +#define DUK_F_MINGW +#endif + +/* Clang */ +#if defined(__clang__) +#define DUK_F_CLANG +#endif + +/* C++ */ +#undef DUK_F_CPP +#if defined(__cplusplus) +#define DUK_F_CPP +#endif + +/* C99 or above */ +#undef DUK_F_C99 +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#define DUK_F_C99 +#endif + +/* C++11 or above */ +#undef DUK_F_CPP11 +#if defined(__cplusplus) && (__cplusplus >= 201103L) +#define DUK_F_CPP11 +#endif + +/* GCC. Clang also defines __GNUC__ so don't detect GCC if using Clang. */ +#if defined(__GNUC__) && !defined(__clang__) && !defined(DUK_F_CLANG) +#define DUK_F_GCC +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +/* Convenience, e.g. gcc 4.5.1 == 40501; + * http://stackoverflow.com/questions/6031819/emulating-gccs-builtin-unreachable + */ +#define DUK_F_GCC_VERSION \ + (__GNUC__ * 10000L + __GNUC_MINOR__ * 100L + __GNUC_PATCHLEVEL__) +#else +#error cannot figure out gcc version +#endif +#endif + +/* ARM */ +#if defined(__arm__) || defined(__thumb__) || defined(_ARM) || \ + defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) +#define DUK_F_ARM +#if defined(__LP64__) || defined(_LP64) || defined(__arm64) || \ + defined(__arm64__) || defined(_M_ARM64) || defined(__aarch64__) +#define DUK_F_ARM64 +#else +#define DUK_F_ARM32 +#endif +#endif + +/* VBCC */ +#if defined(__VBCC__) +#define DUK_F_VBCC +#endif + +/* Intel x86 (32-bit), x64 (64-bit) or x32 (64-bit but 32-bit pointers), + * define only one of DUK_F_X86, DUK_F_X64, DUK_F_X32. + * https://sites.google.com/site/x32abi/ + * + * With DUK_F_OLD_SOLARIS the header must be included + * before this. + */ +#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || \ + defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) +#if defined(__ILP32__) || defined(_ILP32) +#define DUK_F_X32 +#else +#define DUK_F_X64 +#endif +#elif defined(i386) || defined(__i386) || defined(__i386__) || \ + defined(__i486__) || defined(__i586__) || defined(__i686__) || \ + defined(__IA32__) || defined(_M_IX86) || defined(__X86__) || \ + defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__) +#if defined(__LP64__) || defined(_LP64) +/* This should not really happen, but would indicate x64. */ +#define DUK_F_X64 +#else +#define DUK_F_X86 +#endif +#endif + +/* MSVC */ +#if defined(_MSC_VER) +/* MSVC preprocessor defines: + * http://msdn.microsoft.com/en-us/library/b0084kay.aspx _MSC_FULL_VER includes + * the build number, but it has at least two formats, see e.g. + * BOOST_MSVC_FULL_VER in + * http://www.boost.org/doc/libs/1_52_0/boost/config/compiler/visualc.hpp + */ +#define DUK_F_MSVC +#if defined(_MSC_FULL_VER) +#if (_MSC_FULL_VER > 100000000) +#define DUK_F_MSVC_FULL_VER _MSC_FULL_VER +#else +#define DUK_F_MSCV_FULL_VER (_MSC_FULL_VER * 10) +#endif +#endif +#endif /* _MSC_VER */ + +/* Atari Mint */ +#if defined(__MINT__) +#define DUK_F_MINT +#endif + +/* + * Platform autodetection + */ + +/* Workaround for older C++ compilers before including , + * see e.g.: https://sourceware.org/bugzilla/show_bug.cgi?id=15366 + */ +#if defined(__cplusplus) && !defined(__STDC_LIMIT_MACROS) +#define __STDC_LIMIT_MACROS +#endif +#if defined(__cplusplus) && !defined(__STDC_CONSTANT_MACROS) +#define __STDC_CONSTANT_MACROS +#endif + +#if defined(DUK_F_APPLE) +/* --- Mac OSX, iPhone, Darwin --- */ +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME +#define DUK_USE_DATE_FMT_STRFTIME + +/* http://stackoverflow.com/questions/5919996/how-to-detect-reliably-mac-os-x-ios-linux-windows-in-c-preprocessor + */ +#if TARGET_IPHONE_SIMULATOR +#define DUK_USE_OS_STRING "iphone-sim" +#elif TARGET_OS_IPHONE +#define DUK_USE_OS_STRING "iphone" +#elif TARGET_OS_MAC +#define DUK_USE_OS_STRING "osx" +#else +#define DUK_USE_OS_STRING "osx-unknown" +#endif + +/* Use _setjmp() on Apple by default, see GH-55. */ +#define DUK_JMPBUF_TYPE jmp_buf +#define DUK_SETJMP(jb) _setjmp((jb)) +#define DUK_LONGJMP(jb) _longjmp((jb), 1) +#elif defined(DUK_F_ORBIS) +/* --- Orbis --- */ +/* Orbis = PS4 */ +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_S +/* no parsing (not an error) */ +#define DUK_USE_DATE_FMT_STRFTIME + +#define DUK_USE_OS_STRING "orbis" +#elif defined(DUK_F_OPENBSD) +/* --- OpenBSD --- */ +/* http://www.monkey.org/openbsd/archive/ports/0401/msg00089.html */ +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME +#define DUK_USE_DATE_FMT_STRFTIME + +#define DUK_USE_OS_STRING "openbsd" +#elif defined(DUK_F_BSD) +/* --- Generic BSD --- */ +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME +#define DUK_USE_DATE_FMT_STRFTIME + +#define DUK_USE_OS_STRING "bsd" +#elif defined(DUK_F_TOS) +/* --- Atari ST TOS --- */ +#define DUK_USE_DATE_NOW_TIME +#define DUK_USE_DATE_TZO_GMTIME +/* no parsing (not an error) */ +#define DUK_USE_DATE_FMT_STRFTIME + +#define DUK_USE_OS_STRING "tos" + +/* TOS on M68K is always big endian. */ +#if !defined(DUK_USE_BYTEORDER) && defined(DUK_F_M68K) +#define DUK_USE_BYTEORDER 3 +#endif +#elif defined(DUK_F_AMIGAOS) +/* --- AmigaOS --- */ +#if defined(DUK_F_M68K) +/* AmigaOS on M68k */ +#define DUK_USE_DATE_NOW_TIME +#define DUK_USE_DATE_TZO_GMTIME +/* no parsing (not an error) */ +#define DUK_USE_DATE_FMT_STRFTIME +#elif defined(DUK_F_PPC) +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME +#define DUK_USE_DATE_FMT_STRFTIME +#if !defined(UINTPTR_MAX) +#define UINTPTR_MAX UINT_MAX +#endif +#else +#error AmigaOS but not M68K/PPC, not supported now +#endif + +#define DUK_USE_OS_STRING "amigaos" + +/* AmigaOS on M68K or PPC is always big endian. */ +#if !defined(DUK_USE_BYTEORDER) && (defined(DUK_F_M68K) || defined(DUK_F_PPC)) +#define DUK_USE_BYTEORDER 3 +#endif +#elif defined(DUK_F_DURANGO) +/* --- Durango (XboxOne) --- */ +/* Durango = XboxOne + * Configuration is nearly identical to Windows, except for + * DUK_USE_DATE_TZO_WINDOWS. + */ + +/* Initial fix: disable secure CRT related warnings when compiling Duktape + * itself (must be defined before including Windows headers). Don't define + * for user code including duktape.h. + */ +#if defined(DUK_COMPILING_DUKTAPE) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +/* MSVC does not have sys/param.h */ +#define DUK_USE_DATE_NOW_WINDOWS +#define DUK_USE_DATE_TZO_WINDOWS_NO_DST +/* Note: PRS and FMT are intentionally left undefined for now. This means + * there is no platform specific date parsing/formatting but there is still + * the ISO 8601 standard format. + */ +#if defined(DUK_COMPILING_DUKTAPE) +/* Only include when compiling Duktape to avoid polluting application build + * with a lot of unnecessary defines. + */ +#endif + +#define DUK_USE_OS_STRING "durango" + +#if !defined(DUK_USE_BYTEORDER) +#define DUK_USE_BYTEORDER 1 +#endif +#elif defined(DUK_F_WINDOWS) +/* --- Windows --- */ +/* Windows version can't obviously be determined at compile time, + * but _WIN32_WINNT indicates the minimum version targeted: + * - https://msdn.microsoft.com/en-us/library/6sehtctf.aspx + */ + +/* Initial fix: disable secure CRT related warnings when compiling Duktape + * itself (must be defined before including Windows headers). Don't define + * for user code including duktape.h. + */ +#if defined(DUK_COMPILING_DUKTAPE) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +/* Windows 32-bit and 64-bit are currently the same. */ +/* MSVC does not have sys/param.h */ + +#if defined(DUK_COMPILING_DUKTAPE) +/* Only include when compiling Duktape to avoid polluting application build + * with a lot of unnecessary defines. + */ +#endif + +/* GetSystemTimePreciseAsFileTime() available from Windows 8: + * https://msdn.microsoft.com/en-us/library/windows/desktop/hh706895(v=vs.85).aspx + */ +#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS) || defined(DUK_USE_DATE_NOW_WINDOWS) +/* User forced provider. */ +#else +#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602) +#define DUK_USE_DATE_NOW_WINDOWS_SUBMS +#else +#define DUK_USE_DATE_NOW_WINDOWS +#endif +#endif + +#define DUK_USE_DATE_TZO_WINDOWS + +/* Note: PRS and FMT are intentionally left undefined for now. This means + * there is no platform specific date parsing/formatting but there is still + * the ISO 8601 standard format. + */ + +/* QueryPerformanceCounter() may go backwards in Windows XP, so enable for + * Vista and later: + * https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx#qpc_support_in_windows_versions + */ +#if !defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC) && \ + defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600) +#define DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC +#endif + +#define DUK_USE_OS_STRING "windows" + +/* On Windows, assume we're little endian. Even Itanium which has a + * configurable endianness runs little endian in Windows. + */ +#if !defined(DUK_USE_BYTEORDER) +#define DUK_USE_BYTEORDER 1 +#endif +#elif defined(DUK_F_FLASHPLAYER) +/* --- Flashplayer (Crossbridge) --- */ +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME +#define DUK_USE_DATE_FMT_STRFTIME + +#define DUK_USE_OS_STRING "flashplayer" + +#if !defined(DUK_USE_BYTEORDER) && defined(DUK_F_FLASHPLAYER) +#define DUK_USE_BYTEORDER 1 +#endif +#elif defined(DUK_F_QNX) +/* --- QNX --- */ +#if defined(DUK_F_QNX) && defined(DUK_COMPILING_DUKTAPE) +/* See: /opt/qnx650/target/qnx6/usr/include/sys/platform.h */ +#define _XOPEN_SOURCE 600 +#define _POSIX_C_SOURCE 200112L +#endif + +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME +#define DUK_USE_DATE_FMT_STRFTIME + +#define DUK_USE_OS_STRING "qnx" +#elif defined(DUK_F_TINSPIRE) +/* --- TI-Nspire --- */ +#if defined(DUK_COMPILING_DUKTAPE) && !defined(_XOPEN_SOURCE) +#define _XOPEN_SOURCE /* e.g. strptime */ +#endif + +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME +#define DUK_USE_DATE_FMT_STRFTIME + +#define DUK_USE_OS_STRING "tinspire" +#elif defined(DUK_F_EMSCRIPTEN) +/* --- Emscripten --- */ +#if defined(DUK_COMPILING_DUKTAPE) +#if !defined(_POSIX_C_SOURCE) +#define _POSIX_C_SOURCE 200809L +#endif +#if !defined(_GNU_SOURCE) +#define _GNU_SOURCE /* e.g. getdate_r */ +#endif +#if !defined(_XOPEN_SOURCE) +#define _XOPEN_SOURCE /* e.g. strptime */ +#endif +#endif /* DUK_COMPILING_DUKTAPE */ + +#if defined(DUK_F_BCC) +/* no endian.h */ +#else +#endif /* DUK_F_BCC */ + +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME +#define DUK_USE_DATE_FMT_STRFTIME + +#define DUK_USE_OS_STRING "emscripten" +#elif defined(DUK_F_ANDROID) +/* --- Android --- */ +#if defined(DUK_COMPILING_DUKTAPE) +#if !defined(_POSIX_C_SOURCE) +#define _POSIX_C_SOURCE 200809L +#endif +#if !defined(_GNU_SOURCE) +#define _GNU_SOURCE /* e.g. getdate_r */ +#endif +#if !defined(_XOPEN_SOURCE) +#define _XOPEN_SOURCE /* e.g. strptime */ +#endif +#endif /* DUK_COMPILING_DUKTAPE */ + +#if defined(DUK_F_BCC) +/* no endian.h or stdint.h */ +#else +#endif /* DUK_F_BCC */ + +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME +#define DUK_USE_DATE_FMT_STRFTIME + +#if 0 /* XXX: safe condition? */ +#define DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME +#endif + +#define DUK_USE_OS_STRING "android" +#elif defined(DUK_F_LINUX) +/* --- Linux --- */ +#if defined(DUK_COMPILING_DUKTAPE) +#if !defined(_POSIX_C_SOURCE) +#define _POSIX_C_SOURCE 200809L +#endif +#if !defined(_GNU_SOURCE) +#define _GNU_SOURCE /* e.g. getdate_r */ +#endif +#if !defined(_XOPEN_SOURCE) +#define _XOPEN_SOURCE /* e.g. strptime */ +#endif +#endif /* DUK_COMPILING_DUKTAPE */ + +#if defined(DUK_F_BCC) +/* no endian.h or stdint.h */ +#else +#endif /* DUK_F_BCC */ + +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME +#define DUK_USE_DATE_FMT_STRFTIME + +#if 0 /* XXX: safe condition? */ +#define DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME +#endif + +#define DUK_USE_OS_STRING "linux" +#elif defined(DUK_F_SUN) +/* --- Solaris --- */ +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME +#define DUK_USE_DATE_FMT_STRFTIME + +#if defined(DUK_F_OLD_SOLARIS) +/* Old Solaris with no endian.h, stdint.h */ +#define DUK_F_NO_STDINT_H +#if !defined(DUK_USE_BYTEORDER) +#define DUK_USE_BYTEORDER 3 +#endif +#else /* DUK_F_OLD_SOLARIS */ +#endif /* DUK_F_OLD_SOLARIS */ + +#define DUK_USE_OS_STRING "solaris" +#elif defined(DUK_F_AIX) +/* --- AIX --- */ +#if !defined(DUK_USE_BYTEORDER) +#define DUK_USE_BYTEORDER 3 +#endif +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME +#define DUK_USE_DATE_FMT_STRFTIME + +#define DUK_USE_OS_STRING "aix" +#elif defined(DUK_F_HPUX) +/* --- HPUX --- */ +#define DUK_F_NO_STDINT_H +#if !defined(DUK_USE_BYTEORDER) +#define DUK_USE_BYTEORDER 3 +#endif +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME +#define DUK_USE_DATE_FMT_STRFTIME + +#define DUK_USE_OS_STRING "hpux" +#elif defined(DUK_F_POSIX) +/* --- Generic POSIX --- */ +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME +#define DUK_USE_DATE_FMT_STRFTIME + +#define DUK_USE_OS_STRING "posix" +#elif defined(DUK_F_CYGWIN) +/* --- Cygwin --- */ +/* don't use strptime() for now */ +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_FMT_STRFTIME + +#define DUK_JMPBUF_TYPE jmp_buf +#define DUK_SETJMP(jb) _setjmp((jb)) +#define DUK_LONGJMP(jb) _longjmp((jb), 1) + +#define DUK_USE_OS_STRING "windows" +#elif defined(DUK_F_UNIX) +/* --- Generic UNIX --- */ +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME +#define DUK_USE_DATE_FMT_STRFTIME +#define DUK_USE_OS_STRING "unknown" +#else +/* --- Generic fallback --- */ +/* The most portable current time provider is time(), but it only has a + * one second resolution. + */ +#define DUK_USE_DATE_NOW_TIME + +/* The most portable way to figure out local time offset is gmtime(), + * but it's not thread safe so use with caution. + */ +#define DUK_USE_DATE_TZO_GMTIME + +/* Avoid custom date parsing and formatting for portability. */ +#undef DUK_USE_DATE_PRS_STRPTIME +#undef DUK_USE_DATE_FMT_STRFTIME + +/* Rely on C89 headers only; time.h must be here. */ + +#define DUK_USE_OS_STRING "unknown" +#endif /* autodetect platform */ + +/* Shared includes: C89 */ + +/* date.h is omitted, and included per platform */ + +/* Shared includes: stdint.h is C99 */ +#if defined(DUK_F_NO_STDINT_H) +/* stdint.h not available */ +#else +/* Technically C99 (C++11) but found in many systems. On some systems + * __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS must be defined before + * including stdint.h (see above). + */ +#endif + +/* is only included if needed, based on DUK_USE_xxx flags. */ + +/* + * Architecture: x64 + */ + +#define DUK_USE_ARCH_STRING "x64" +#if !defined(DUK_USE_BYTEORDER) +#define DUK_USE_BYTEORDER 1 +#endif +#undef DUK_USE_PACKED_TVAL +#define DUK_F_PACKED_TVAL_PROVIDED + +/* + * Compiler: gcc + */ + +#if defined(DUK_F_C99) || defined(DUK_F_CPP11) +/* C99 / C++11 and above: rely on va_copy() which is required. */ +#define DUK_VA_COPY(dest, src) va_copy(dest, src) +#else +/* GCC: assume we have __va_copy() in non-C99 mode. */ +#define DUK_VA_COPY(dest, src) __va_copy(dest, src) +#endif + +#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 20500L) && \ + (DUK_F_GCC_VERSION < 50000L) +/* Since gcc-2.5. + * + * Disabled temporarily in GCC 5+ because of an unresolved noreturn-related + * issue: https://github.com/svaarala/duktape/issues/2155. + */ +#define DUK_NORETURN(decl) decl noreturn +#endif + +#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500L) +/* Since gcc-4.5. */ +#define DUK_UNREACHABLE() unreachable +#endif + +#define DUK_USE_BRANCH_HINTS +#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500L) +/* GCC: test not very accurate; enable only in relatively recent builds + * because of bugs in gcc-4.4 + * (http://lists.debian.org/debian-gcc/2010/04/msg00000.html) + */ +#define DUK_LIKELY(x) likely(x) +#define DUK_UNLIKELY(x) unlikely(x) +#endif +/* XXX: equivalent of clang __builtin_unpredictable? */ + +#if (defined(DUK_F_C99) || defined(DUK_F_CPP11)) && \ + defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 30101) +#define DUK_NOINLINE noinline +#define DUK_INLINE inline +#define DUK_ALWAYS_INLINE inline __attribute__((__always_inline__)) +#endif + +#if (defined(DUK_F_C99) || defined(DUK_F_CPP11)) && \ + defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40300) +#define DUK_HOT firstclass +#define DUK_COLD relegated +#endif + +#if defined(DUK_F_DLL_BUILD) && defined(DUK_F_WINDOWS) +/* MSVC dllexport/dllimport: appropriate __declspec depends on whether we're + * compiling Duktape or the application. + */ +#if defined(DUK_COMPILING_DUKTAPE) +#define DUK_EXTERNAL_DECL extern __declspec(dllexport) +#define DUK_EXTERNAL __declspec(dllexport) +#else +#define DUK_EXTERNAL_DECL extern __declspec(dllimport) +#define DUK_EXTERNAL should_not_happen +#endif +#if defined(DUK_SINGLE_FILE) +#define DUK_INTERNAL_DECL static +#define DUK_INTERNAL static +#else +#define DUK_INTERNAL_DECL extern +#define DUK_INTERNAL /*empty*/ +#endif +#define DUK_LOCAL_DECL static +#define DUK_LOCAL static +#elif defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40000) +#define DUK_EXTERNAL_DECL __attribute__((visibility("default"))) extern +#define DUK_EXTERNAL __attribute__((visibility("default"))) +#if defined(DUK_SINGLE_FILE) +#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || \ + defined(DUK_F_CLANG) +/* Minimize warnings for unused internal functions with GCC >= 3.1.1 and + * Clang. Based on documentation it should suffice to have the attribute + * in the declaration only, but in practice some warnings are generated unless + * the attribute is also applied to the definition. + */ +#define DUK_INTERNAL_DECL static __attribute__((unused)) +#define DUK_INTERNAL static __attribute__((unused)) +#else +#define DUK_INTERNAL_DECL static +#define DUK_INTERNAL static +#endif +#else +#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || \ + defined(DUK_F_CLANG) +#define DUK_INTERNAL_DECL \ + __attribute__((visibility("hidden"))) __attribute__((unused)) extern +#define DUK_INTERNAL \ + __attribute__((visibility("hidden"))) __attribute__((unused)) +#else +#define DUK_INTERNAL_DECL __attribute__((visibility("hidden"))) extern +#define DUK_INTERNAL __attribute__((visibility("hidden"))) +#endif +#endif +#define DUK_LOCAL_DECL static +#define DUK_LOCAL static +#endif + +#if defined(DUK_F_MINGW) +#if defined(DUK_F_CPP) +#define DUK_USE_COMPILER_STRING "mingw++" +#else +#define DUK_USE_COMPILER_STRING "mingw" +#endif +#else +#if defined(DUK_F_CPP) +#define DUK_USE_COMPILER_STRING "g++" +#else +#define DUK_USE_COMPILER_STRING "gcc" +#endif +#endif + +#undef DUK_USE_VARIADIC_MACROS +#if defined(DUK_F_C99) || (defined(DUK_F_CPP11) && defined(__GNUC__)) +#define DUK_USE_VARIADIC_MACROS +#endif + +#define DUK_USE_UNION_INITIALIZERS + +#undef DUK_USE_FLEX_C99 +#undef DUK_USE_FLEX_ZEROSIZE +#undef DUK_USE_FLEX_ONESIZE +#if defined(DUK_F_C99) +#define DUK_USE_FLEX_C99 +#else +#define DUK_USE_FLEX_ZEROSIZE +#endif + +/* Since 4.6 one can '#pragma GCC diagnostic push/pop'. */ +#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40600) +#define DUK_USE_GCC_PRAGMAS +#else +#undef DUK_USE_GCC_PRAGMAS +#endif + +#define DUK_USE_PACK_GCC_ATTR + +/* Availability varies based on platform (between GCC 4.4 and 4.8), and there + * are apparently some bugs in GCC 4.x. Check for GCC 5.0 before enabling + * these to be safe. + */ +#define DUK_BSWAP64(x) bswap_64(x) +#define DUK_BSWAP32(x) bswap_32(x) +#define DUK_BSWAP16(x) bswap_16(x) + +/* uclibc */ +#if defined(__UCLIBC__) +#define DUK_F_UCLIBC +#endif + +/* + * Wrapper typedefs and constants for integer types, also sanity check types. + * + * C99 typedefs are quite good but not always available, and we want to avoid + * forcibly redefining the C99 typedefs. So, there are Duktape wrappers for + * all C99 typedefs and Duktape code should only use these typedefs. Type + * detection when C99 is not supported is best effort and may end up detecting + * some types incorrectly. + * + * Pointer sizes are a portability problem: pointers to different types may + * have a different size and function pointers are very difficult to manage + * portably. + * + * http://en.wikipedia.org/wiki/C_data_types#Fixed-width_integer_types + * + * Note: there's an interesting corner case when trying to define minimum + * signed integer value constants which leads to the current workaround of + * defining e.g. -0x80000000 as (-0x7fffffffL - 1L). See doc/code-issues.txt + * for a longer discussion. + * + * Note: avoid typecasts and computations in macro integer constants as they + * can then no longer be used in macro relational expressions (such as + * #if DUK_SIZE_MAX < 0xffffffffUL). There is internal code which relies on + * being able to compare DUK_SIZE_MAX against a limit. + */ + +/* XXX: add feature options to force basic types from outside? */ + +#if !defined(INT_MAX) +#error INT_MAX not defined +#endif + +/* Check that architecture is two's complement, standard C allows e.g. + * INT_MIN to be -2**31+1 (instead of -2**31). + */ +#if defined(INT_MAX) && defined(INT_MIN) +#if INT_MAX != -(INT_MIN + 1) +#error platform does not seem complement of two +#endif +#else +#error cannot check complement of two +#endif + +/* Pointer size determination based on __WORDSIZE or architecture when + * that's not available. + */ +#if defined(DUK_F_X86) || defined(DUK_F_X32) || defined(DUK_F_M68K) || \ + defined(DUK_F_PPC32) || defined(DUK_F_BCC) || \ + (defined(__WORDSIZE) && (__WORDSIZE == 32)) || \ + ((defined(DUK_F_OLD_SOLARIS) || defined(DUK_F_AIX) || \ + defined(DUK_F_HPUX)) && \ + defined(_ILP32)) || \ + defined(DUK_F_ARM32) +#define DUK_F_32BIT_PTRS +#elif defined(DUK_F_X64) || (defined(__WORDSIZE) && (__WORDSIZE == 64)) || \ + ((defined(DUK_F_OLD_SOLARIS) || defined(DUK_F_AIX) || \ + defined(DUK_F_HPUX)) && \ + defined(_LP64)) || \ + defined(DUK_F_ARM64) +#define DUK_F_64BIT_PTRS +#else +/* not sure, not needed with C99 anyway */ +#endif + +/* Intermediate define for 'have inttypes.h' */ +#undef DUK_F_HAVE_INTTYPES +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ + !(defined(DUK_F_AMIGAOS) && defined(DUK_F_VBCC)) +/* vbcc + AmigaOS has C99 but no inttypes.h */ +#define DUK_F_HAVE_INTTYPES +#elif defined(__cplusplus) && (__cplusplus >= 201103L) +/* C++11 apparently ratified stdint.h */ +#define DUK_F_HAVE_INTTYPES +#endif + +/* Basic integer typedefs and limits, preferably from inttypes.h, otherwise + * through automatic detection. + */ +/* C99 types assumed */ +#define DUK_F_HAVE_64BIT + +typedef uint8_t duk_uint8_t; +typedef int8_t duk_int8_t; +typedef uint16_t duk_uint16_t; +typedef int16_t duk_int16_t; +typedef uint32_t duk_uint32_t; +typedef int32_t duk_int32_t; +typedef uint64_t duk_uint64_t; +typedef int64_t duk_int64_t; +typedef uint_least8_t duk_uint_least8_t; +typedef int_least8_t duk_int_least8_t; +typedef uint_least16_t duk_uint_least16_t; +typedef int_least16_t duk_int_least16_t; +typedef uint_least32_t duk_uint_least32_t; +typedef int_least32_t duk_int_least32_t; +typedef uint_least64_t duk_uint_least64_t; +typedef int_least64_t duk_int_least64_t; +typedef uint_fast8_t duk_uint_fast8_t; +typedef int_fast8_t duk_int_fast8_t; +typedef uint_fast16_t duk_uint_fast16_t; +typedef int_fast16_t duk_int_fast16_t; +typedef uint_fast32_t duk_uint_fast32_t; +typedef int_fast32_t duk_int_fast32_t; +typedef uint_fast64_t duk_uint_fast64_t; +typedef int_fast64_t duk_int_fast64_t; +typedef uintptr_t duk_uintptr_t; +typedef intptr_t duk_intptr_t; +typedef uintmax_t duk_uintmax_t; +typedef intmax_t duk_intmax_t; + +#define DUK_UINT8_MIN 0 +#define DUK_UINT8_MAX UINT8_MAX +#define DUK_INT8_MIN INT8_MIN +#define DUK_INT8_MAX INT8_MAX +#define DUK_UINT_LEAST8_MIN 0 +#define DUK_UINT_LEAST8_MAX UINT_LEAST8_MAX +#define DUK_INT_LEAST8_MIN INT_LEAST8_MIN +#define DUK_INT_LEAST8_MAX INT_LEAST8_MAX +#define DUK_UINT_FAST8_MIN 0 +#define DUK_UINT_FAST8_MAX UINT_FAST8_MAX +#define DUK_INT_FAST8_MIN INT_FAST8_MIN +#define DUK_INT_FAST8_MAX INT_FAST8_MAX +#define DUK_UINT16_MIN 0 +#define DUK_UINT16_MAX UINT16_MAX +#define DUK_INT16_MIN INT16_MIN +#define DUK_INT16_MAX INT16_MAX +#define DUK_UINT_LEAST16_MIN 0 +#define DUK_UINT_LEAST16_MAX UINT_LEAST16_MAX +#define DUK_INT_LEAST16_MIN INT_LEAST16_MIN +#define DUK_INT_LEAST16_MAX INT_LEAST16_MAX +#define DUK_UINT_FAST16_MIN 0 +#define DUK_UINT_FAST16_MAX UINT_FAST16_MAX +#define DUK_INT_FAST16_MIN INT_FAST16_MIN +#define DUK_INT_FAST16_MAX INT_FAST16_MAX +#define DUK_UINT32_MIN 0 +#define DUK_UINT32_MAX UINT32_MAX +#define DUK_INT32_MIN INT32_MIN +#define DUK_INT32_MAX INT32_MAX +#define DUK_UINT_LEAST32_MIN 0 +#define DUK_UINT_LEAST32_MAX UINT_LEAST32_MAX +#define DUK_INT_LEAST32_MIN INT_LEAST32_MIN +#define DUK_INT_LEAST32_MAX INT_LEAST32_MAX +#define DUK_UINT_FAST32_MIN 0 +#define DUK_UINT_FAST32_MAX UINT_FAST32_MAX +#define DUK_INT_FAST32_MIN INT_FAST32_MIN +#define DUK_INT_FAST32_MAX INT_FAST32_MAX +#define DUK_UINT64_MIN 0 +#define DUK_UINT64_MAX UINT64_MAX +#define DUK_INT64_MIN INT64_MIN +#define DUK_INT64_MAX INT64_MAX +#define DUK_UINT_LEAST64_MIN 0 +#define DUK_UINT_LEAST64_MAX UINT_LEAST64_MAX +#define DUK_INT_LEAST64_MIN INT_LEAST64_MIN +#define DUK_INT_LEAST64_MAX INT_LEAST64_MAX +#define DUK_UINT_FAST64_MIN 0 +#define DUK_UINT_FAST64_MAX UINT_FAST64_MAX +#define DUK_INT_FAST64_MIN INT_FAST64_MIN +#define DUK_INT_FAST64_MAX INT_FAST64_MAX + +#define DUK_UINTPTR_MIN 0 +#define DUK_UINTPTR_MAX UINTPTR_MAX +#define DUK_INTPTR_MIN INTPTR_MIN +#define DUK_INTPTR_MAX INTPTR_MAX + +#define DUK_UINTMAX_MIN 0 +#define DUK_UINTMAX_MAX UINTMAX_MAX +#define DUK_INTMAX_MIN INTMAX_MIN +#define DUK_INTMAX_MAX INTMAX_MAX + +#define DUK_SIZE_MIN 0 +#define DUK_SIZE_MAX SIZE_MAX +#undef DUK_SIZE_MAX_COMPUTED + +/* A few types are assumed to always exist. */ +typedef size_t duk_size_t; +typedef ptrdiff_t duk_ptrdiff_t; + +/* The best type for an "all around int" in Duktape internals is "at least + * 32 bit signed integer" which is most convenient. Same for unsigned type. + * Prefer 'int' when large enough, as it is almost always a convenient type. + */ +#if defined(UINT_MAX) && (UINT_MAX >= 0xffffffffUL) +typedef int duk_int_t; +typedef unsigned int duk_uint_t; +#define DUK_INT_MIN INT_MIN +#define DUK_INT_MAX INT_MAX +#define DUK_UINT_MIN 0 +#define DUK_UINT_MAX UINT_MAX +#else +typedef duk_int_fast32_t duk_int_t; +typedef duk_uint_fast32_t duk_uint_t; +#define DUK_INT_MIN DUK_INT_FAST32_MIN +#define DUK_INT_MAX DUK_INT_FAST32_MAX +#define DUK_UINT_MIN DUK_UINT_FAST32_MIN +#define DUK_UINT_MAX DUK_UINT_FAST32_MAX +#endif + +/* Same as 'duk_int_t' but guaranteed to be a 'fast' variant if this + * distinction matters for the CPU. These types are used mainly in the + * executor where it might really matter. + */ +typedef duk_int_fast32_t duk_int_fast_t; +typedef duk_uint_fast32_t duk_uint_fast_t; +#define DUK_INT_FAST_MIN DUK_INT_FAST32_MIN +#define DUK_INT_FAST_MAX DUK_INT_FAST32_MAX +#define DUK_UINT_FAST_MIN DUK_UINT_FAST32_MIN +#define DUK_UINT_FAST_MAX DUK_UINT_FAST32_MAX + +/* Small integers (16 bits or more) can fall back to the 'int' type, but + * have a typedef so they are marked "small" explicitly. + */ +typedef int duk_small_int_t; +typedef unsigned int duk_small_uint_t; +#define DUK_SMALL_INT_MIN INT_MIN +#define DUK_SMALL_INT_MAX INT_MAX +#define DUK_SMALL_UINT_MIN 0 +#define DUK_SMALL_UINT_MAX UINT_MAX + +/* Fast variants of small integers, again for really fast paths like the + * executor. + */ +typedef duk_int_fast16_t duk_small_int_fast_t; +typedef duk_uint_fast16_t duk_small_uint_fast_t; +#define DUK_SMALL_INT_FAST_MIN DUK_INT_FAST16_MIN +#define DUK_SMALL_INT_FAST_MAX DUK_INT_FAST16_MAX +#define DUK_SMALL_UINT_FAST_MIN DUK_UINT_FAST16_MIN +#define DUK_SMALL_UINT_FAST_MAX DUK_UINT_FAST16_MAX + +/* Boolean values are represented with the platform 'unsigned int'. */ +typedef duk_small_uint_t duk_bool_t; +#define DUK_BOOL_MIN DUK_SMALL_UINT_MIN +#define DUK_BOOL_MAX DUK_SMALL_UINT_MAX + +/* Index values must have at least 32-bit signed range. */ +typedef duk_int_t duk_idx_t; +#define DUK_IDX_MIN DUK_INT_MIN +#define DUK_IDX_MAX DUK_INT_MAX + +/* Unsigned index variant. */ +typedef duk_uint_t duk_uidx_t; +#define DUK_UIDX_MIN DUK_UINT_MIN +#define DUK_UIDX_MAX DUK_UINT_MAX + +/* Array index values, could be exact 32 bits. + * Currently no need for signed duk_arridx_t. + */ +typedef duk_uint_t duk_uarridx_t; +#define DUK_UARRIDX_MIN DUK_UINT_MIN +#define DUK_UARRIDX_MAX DUK_UINT_MAX + +/* Duktape/C function return value, platform int is enough for now to + * represent 0, 1, or negative error code. Must be compatible with + * assigning truth values (e.g. duk_ret_t rc = (foo == bar);). + */ +typedef duk_small_int_t duk_ret_t; +#define DUK_RET_MIN DUK_SMALL_INT_MIN +#define DUK_RET_MAX DUK_SMALL_INT_MAX + +/* Error codes are represented with platform int. High bits are used + * for flags and such, so 32 bits are needed. + */ +typedef duk_int_t duk_errcode_t; +#define DUK_ERRCODE_MIN DUK_INT_MIN +#define DUK_ERRCODE_MAX DUK_INT_MAX + +/* Codepoint type. Must be 32 bits or more because it is used also for + * internal codepoints. The type is signed because negative codepoints + * are used as internal markers (e.g. to mark EOF or missing argument). + * (X)UTF-8/CESU-8 encode/decode take and return an unsigned variant to + * ensure duk_uint32_t casts back and forth nicely. Almost everything + * else uses the signed one. + */ +typedef duk_int_t duk_codepoint_t; +typedef duk_uint_t duk_ucodepoint_t; +#define DUK_CODEPOINT_MIN DUK_INT_MIN +#define DUK_CODEPOINT_MAX DUK_INT_MAX +#define DUK_UCODEPOINT_MIN DUK_UINT_MIN +#define DUK_UCODEPOINT_MAX DUK_UINT_MAX + +/* IEEE float/double typedef. */ +typedef float duk_float_t; +typedef double duk_double_t; + +/* We're generally assuming that we're working on a platform with a 32-bit + * address space. If DUK_SIZE_MAX is a typecast value (which is necessary + * if SIZE_MAX is missing), the check must be avoided because the + * preprocessor can't do a comparison. + */ +#if !defined(DUK_SIZE_MAX) +#error DUK_SIZE_MAX is undefined, probably missing SIZE_MAX +#elif !defined(DUK_SIZE_MAX_COMPUTED) +#if DUK_SIZE_MAX < 0xffffffffUL +/* On some systems SIZE_MAX can be smaller than max unsigned 32-bit value + * which seems incorrect if size_t is (at least) an unsigned 32-bit type. + * However, it doesn't seem useful to error out compilation if this is the + * case. + */ +#endif +#endif + +/* Type used in public API declarations and user code. Typedef maps to + * 'struct duk_hthread' like the 'duk_hthread' typedef which is used + * exclusively in internals. + */ +typedef struct duk_hthread duk_context; + +/* Check whether we should use 64-bit integers or not. + * + * Quite incomplete now. Use 64-bit types if detected (C99 or other detection) + * unless they are known to be unreliable. For instance, 64-bit types are + * available on VBCC but seem to misbehave. + */ +#if defined(DUK_F_HAVE_64BIT) && !defined(DUK_F_VBCC) +#define DUK_USE_64BIT_OPS +#else +#undef DUK_USE_64BIT_OPS +#endif + +/* + * Fill-ins for platform, architecture, and compiler + */ + +/* An abort()-like primitive is needed by the default fatal error handler. */ +#if !defined(DUK_ABORT) +#define DUK_ABORT abort +#endif + +#if !defined(DUK_SETJMP) +#define DUK_JMPBUF_TYPE jmp_buf +#define DUK_SETJMP(jb) setjmp((jb)) +#define DUK_LONGJMP(jb) longjmp((jb), 1) +#endif + +#if 0 +/* sigsetjmp() alternative */ +#define DUK_JMPBUF_TYPE sigjmp_buf +#define DUK_SETJMP(jb) sigsetjmp((jb)) +#define DUK_LONGJMP(jb) siglongjmp((jb), 1) +#endif + +/* Special naming to avoid conflict with e.g. DUK_FREE() in duk_heap.h + * (which is unfortunately named). May sometimes need replacement, e.g. + * some compilers don't handle zero length or NULL correctly in realloc(). + */ +#if !defined(DUK_ANSI_MALLOC) +#define DUK_ANSI_MALLOC malloc +#endif +#if !defined(DUK_ANSI_REALLOC) +#define DUK_ANSI_REALLOC realloc +#endif +#if !defined(DUK_ANSI_CALLOC) +#define DUK_ANSI_CALLOC calloc +#endif +#if !defined(DUK_ANSI_FREE) +#define DUK_ANSI_FREE free +#endif + +/* ANSI C (various versions) and some implementations require that the + * pointer arguments to memset(), memcpy(), and memmove() be valid values + * even when byte size is 0 (even a NULL pointer is considered invalid in + * this context). Zero-size operations as such are allowed, as long as their + * pointer arguments point to a valid memory area. The DUK_MEMSET(), + * DUK_MEMCPY(), and DUK_MEMMOVE() macros require this same behavior, i.e.: + * (1) pointers must be valid and non-NULL, (2) zero size must otherwise be + * allowed. If these are not fulfilled, a macro wrapper is needed. + * + * http://stackoverflow.com/questions/5243012/is-it-guaranteed-to-be-safe-to-perform-memcpy0-0-0 + * http://lists.cs.uiuc.edu/pipermail/llvmdev/2007-October/011065.html + * + * Not sure what's the required behavior when a pointer points just past the + * end of a buffer, which often happens in practice (e.g. zero size memmoves). + * For example, if allocation size is 3, the following pointer would not + * technically point to a valid memory byte: + * + * <-- alloc --> + * | 0 | 1 | 2 | ..... + * ^-- p=3, points after last valid byte (2) + */ +#if !defined(DUK_MEMCPY) +#if defined(DUK_F_UCLIBC) +/* Old uclibcs have a broken memcpy so use memmove instead (this is overly wide + * now on purpose): + * http://lists.uclibc.org/pipermail/uclibc-cvs/2008-October/025511.html + */ +#define DUK_MEMCPY memmove +#else +#define DUK_MEMCPY memcpy +#endif +#endif +#if !defined(DUK_MEMMOVE) +#define DUK_MEMMOVE memmove +#endif +#if !defined(DUK_MEMCMP) +#define DUK_MEMCMP memcmp +#endif +#if !defined(DUK_MEMSET) +#define DUK_MEMSET memset +#endif +#if !defined(DUK_STRLEN) +#define DUK_STRLEN strlen +#endif +#if !defined(DUK_STRCMP) +#define DUK_STRCMP strcmp +#endif +#if !defined(DUK_STRNCMP) +#define DUK_STRNCMP strncmp +#endif +#if !defined(DUK_SPRINTF) +#define DUK_SPRINTF sprintf +#endif +#if !defined(DUK_SNPRINTF) +/* snprintf() is technically not part of C89 but usually available. */ +#define DUK_SNPRINTF snprintf +#endif +#if !defined(DUK_VSPRINTF) +#define DUK_VSPRINTF vsprintf +#endif +#if !defined(DUK_VSNPRINTF) +/* vsnprintf() is technically not part of C89 but usually available. */ +#define DUK_VSNPRINTF vsnprintf +#endif +#if !defined(DUK_SSCANF) +#define DUK_SSCANF sscanf +#endif +#if !defined(DUK_VSSCANF) +#define DUK_VSSCANF vsscanf +#endif +#if !defined(DUK_MEMZERO) +#define DUK_MEMZERO(p, n) DUK_MEMSET((p), 0, (n)) +#endif + +#if !defined(DUK_DOUBLE_INFINITY) +#undef DUK_USE_COMPUTED_INFINITY +#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION < 40600) +/* GCC older than 4.6: avoid overflow warnings related to using INFINITY */ +#define DUK_DOUBLE_INFINITY (__builtin_inf()) +#elif defined(INFINITY) +#define DUK_DOUBLE_INFINITY ((double)INFINITY) +#elif !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC) && !defined(DUK_F_BCC) && \ + !defined(DUK_F_OLD_SOLARIS) && !defined(DUK_F_AIX) +#define DUK_DOUBLE_INFINITY (1.0 / 0.0) +#else +/* In VBCC (1.0 / 0.0) results in a warning and 0.0 instead of infinity. + * Use a computed infinity (initialized when a heap is created at the + * latest). + */ +#define DUK_USE_COMPUTED_INFINITY +#define DUK_DOUBLE_INFINITY duk_computed_infinity +#endif +#endif + +#if !defined(DUK_DOUBLE_NAN) +#undef DUK_USE_COMPUTED_NAN +#if defined(NAN) +#define DUK_DOUBLE_NAN NAN +#elif !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC) && !defined(DUK_F_BCC) && \ + !defined(DUK_F_OLD_SOLARIS) && !defined(DUK_F_AIX) +#define DUK_DOUBLE_NAN (0.0 / 0.0) +#else +/* In VBCC (0.0 / 0.0) results in a warning and 0.0 instead of NaN. + * In MSVC (VS2010 Express) (0.0 / 0.0) results in a compile error. + * Use a computed NaN (initialized when a heap is created at the + * latest). + */ +#define DUK_USE_COMPUTED_NAN +#define DUK_DOUBLE_NAN duk_computed_nan +#endif +#endif + +/* Many platforms are missing fpclassify() and friends, so use replacements + * if necessary. The replacement constants (FP_NAN etc) can be anything but + * match Linux constants now. + */ +#undef DUK_USE_REPL_FPCLASSIFY +#undef DUK_USE_REPL_SIGNBIT +#undef DUK_USE_REPL_ISFINITE +#undef DUK_USE_REPL_ISNAN +#undef DUK_USE_REPL_ISINF + +/* Complex condition broken into separate parts. */ +#undef DUK_F_USE_REPL_ALL +#if !(defined(FP_NAN) && defined(FP_INFINITE) && defined(FP_ZERO) && \ + defined(FP_SUBNORMAL) && defined(FP_NORMAL)) +/* Missing some obvious constants. */ +#define DUK_F_USE_REPL_ALL +#elif defined(DUK_F_AMIGAOS) && defined(DUK_F_VBCC) +/* VBCC is missing the built-ins even in C99 mode (perhaps a header issue). */ +#define DUK_F_USE_REPL_ALL +#elif defined(DUK_F_AMIGAOS) && defined(DUK_F_M68K) +/* AmigaOS + M68K seems to have math issues even when using GCC cross + * compilation. Use replacements for all AmigaOS versions on M68K + * regardless of compiler. + */ +#define DUK_F_USE_REPL_ALL +#elif defined(DUK_F_FREEBSD) && defined(DUK_F_CLANG) +/* Placeholder fix for (detection is wider than necessary): + * http://llvm.org/bugs/show_bug.cgi?id=17788 + */ +#define DUK_F_USE_REPL_ALL +#elif defined(DUK_F_UCLIBC) +/* At least some uclibc versions have broken floating point math. For + * example, fpclassify() can incorrectly classify certain NaN formats. + * To be safe, use replacements. + */ +#define DUK_F_USE_REPL_ALL +#elif defined(DUK_F_AIX) +/* Older versions may be missing isnan(), etc. */ +#define DUK_F_USE_REPL_ALL +#endif + +#if defined(DUK_F_USE_REPL_ALL) +#define DUK_USE_REPL_FPCLASSIFY +#define DUK_USE_REPL_SIGNBIT +#define DUK_USE_REPL_ISFINITE +#define DUK_USE_REPL_ISNAN +#define DUK_USE_REPL_ISINF +#define DUK_FPCLASSIFY duk_repl_fpclassify +#define DUK_SIGNBIT duk_repl_signbit +#define DUK_ISFINITE duk_repl_isfinite +#define DUK_ISNAN duk_repl_isnan +#define DUK_ISINF duk_repl_isinf +#define DUK_FP_NAN 0 +#define DUK_FP_INFINITE 1 +#define DUK_FP_ZERO 2 +#define DUK_FP_SUBNORMAL 3 +#define DUK_FP_NORMAL 4 +#else +#define DUK_FPCLASSIFY fpclassify +#define DUK_SIGNBIT signbit +#define DUK_ISFINITE isfinite +#define DUK_ISNAN isnan +#define DUK_ISINF isinf +#define DUK_FP_NAN FP_NAN +#define DUK_FP_INFINITE FP_INFINITE +#define DUK_FP_ZERO FP_ZERO +#define DUK_FP_SUBNORMAL FP_SUBNORMAL +#define DUK_FP_NORMAL FP_NORMAL +#endif + +#if defined(DUK_F_USE_REPL_ALL) +#undef DUK_F_USE_REPL_ALL +#endif + +/* These functions don't currently need replacement but are wrapped for + * completeness. Because these are used as function pointers, they need + * to be defined as concrete C functions (not macros). + */ +#if !defined(DUK_FABS) +#define DUK_FABS fabs +#endif +#if !defined(DUK_FLOOR) +#define DUK_FLOOR floor +#endif +#if !defined(DUK_CEIL) +#define DUK_CEIL ceil +#endif +#if !defined(DUK_FMOD) +#define DUK_FMOD fmod +#endif +#if !defined(DUK_POW) +#define DUK_POW pow +#endif +#if !defined(DUK_ACOS) +#define DUK_ACOS acos +#endif +#if !defined(DUK_ASIN) +#define DUK_ASIN asin +#endif +#if !defined(DUK_ATAN) +#define DUK_ATAN atan +#endif +#if !defined(DUK_ATAN2) +#define DUK_ATAN2 atan2 +#endif +#if !defined(DUK_SIN) +#define DUK_SIN sin +#endif +#if !defined(DUK_COS) +#define DUK_COS cos +#endif +#if !defined(DUK_TAN) +#define DUK_TAN tan +#endif +#if !defined(DUK_EXP) +#define DUK_EXP exp +#endif +#if !defined(DUK_LOG) +#define DUK_LOG log +#endif +#if !defined(DUK_SQRT) +#define DUK_SQRT sqrt +#endif + +/* The functions below exist only in C99/C++11 or later and need a workaround + * for platforms that don't include them. MSVC isn't detected as C99, but + * these functions also exist in MSVC 2013 and later so include a clause for + * that too. Android doesn't have log2; disable all of these for Android. + */ +#if (defined(DUK_F_C99) || defined(DUK_F_CPP11) || \ + (defined(_MSC_VER) && (_MSC_VER >= 1800))) && \ + !defined(DUK_F_ANDROID) && !defined(DUK_F_MINT) +#if !defined(DUK_CBRT) +#define DUK_CBRT cbrt +#endif +#if !defined(DUK_LOG2) +#define DUK_LOG2 log2 +#endif +#if !defined(DUK_LOG10) +#define DUK_LOG10 log10 +#endif +#if !defined(DUK_TRUNC) +#define DUK_TRUNC trunc +#endif +#endif /* DUK_F_C99 etc */ + +/* NetBSD 6.0 x86 (at least) has a few problems with pow() semantics, + * see test-bug-netbsd-math-pow.js. MinGW has similar (but different) + * issues, see test-bug-mingw-math-issues.js. Enable pow() workarounds + * for these targets. + */ +#undef DUK_USE_POW_WORKAROUNDS +#if defined(DUK_F_NETBSD) || defined(DUK_F_MINGW) +#define DUK_USE_POW_WORKAROUNDS +#endif + +/* Similar workarounds for atan2() semantics issues. MinGW issues are + * documented in test-bug-mingw-math-issues.js. + */ +#undef DUK_USE_ATAN2_WORKAROUNDS +#if defined(DUK_F_MINGW) +#define DUK_USE_ATAN2_WORKAROUNDS +#endif + +/* Rely as little as possible on compiler behavior for NaN comparison, + * signed zero handling, etc. Currently never activated but may be needed + * for broken compilers. + */ +#undef DUK_USE_PARANOID_MATH + +/* There was a curious bug where test-bi-date-canceling.js would fail e.g. + * on 64-bit Ubuntu, gcc-4.8.1, -m32, and no -std=c99. Some date computations + * using doubles would be optimized which then broke some corner case tests. + * The problem goes away by adding 'volatile' to the datetime computations. + * Not sure what the actual triggering conditions are, but using this on + * non-C99 systems solves the known issues and has relatively little cost + * on other platforms. + */ +#undef DUK_USE_PARANOID_DATE_COMPUTATION +#if !defined(DUK_F_C99) +#define DUK_USE_PARANOID_DATE_COMPUTATION +#endif + +/* + * Alignment requirement and support for unaligned accesses + * + * Assume unaligned accesses are not supported unless specifically allowed + * in the target platform. Some platforms may support unaligned accesses + * but alignment to 4 or 8 may still be desirable. Note that unaligned + * accesses (and even pointers) relative to natural alignment (regardless + * of target alignment) are technically undefined behavior and thus + * compiler/architecture specific. + */ + +/* If not forced, use safe default for alignment. */ +#if !defined(DUK_USE_ALIGN_BY) +#define DUK_USE_ALIGN_BY 8 +#endif + +/* Compiler specific hackery needed to force struct size to match alignment, + * see e.g. duk_hbuffer.h. + * + * http://stackoverflow.com/questions/11130109/c-struct-size-alignment + * http://stackoverflow.com/questions/10951039/specifying-64-bit-alignment + */ +#if !(defined(DUK_USE_PACK_MSVC_PRAGMA) || defined(DUK_USE_PACK_GCC_ATTR) || \ + defined(DUK_USE_PACK_CLANG_ATTR) || defined(DUK_USE_PACK_DUMMY_MEMBER)) +#define DUK_USE_PACK_DUMMY_MEMBER +#endif + +#if !defined(DUK_U64_CONSTANT) +#define DUK_U64_CONSTANT(x) x##ULL +#endif +#if !defined(DUK_I64_CONSTANT) +#define DUK_I64_CONSTANT(x) x##LL +#endif + +#if !defined(DUK_VA_COPY) +/* We need va_copy() which is defined in C99 / C++11, so an awkward + * replacement is needed for pre-C99 / pre-C++11 environments. This + * will quite likely need portability hacks for some non-C99 + * environments. + */ +#if defined(DUK_F_C99) || defined(DUK_F_CPP11) +/* C99 / C++11 and above: rely on va_copy() which is required. + * Omit parenthesis on macro right side on purpose to minimize differences + * to direct use. + */ +#define DUK_VA_COPY(dest, src) va_copy(dest, src) +#else +/* Pre-C99: va_list type is implementation dependent. This replacement + * assumes it is a plain value so that a simple assignment will work. + * This is not the case on all platforms (it may be a single-array element, + * for instance). + */ +#define DUK_VA_COPY(dest, src) \ + do { \ + (dest) = (src); \ + } while (0) +#endif +#endif + +#if !defined(DUK_MACRO_STRINGIFY) +/* Macro hackery to convert e.g. __LINE__ to a string without formatting, + * see: + * http://stackoverflow.com/questions/240353/convert-a-preprocessor-token-to-a-string + */ +#define DUK_MACRO_STRINGIFY_HELPER(x) #x +#define DUK_MACRO_STRINGIFY(x) DUK_MACRO_STRINGIFY_HELPER(x) +#endif + +#if !defined(DUK_CAUSE_SEGFAULT) +/* This can be used for testing; valgrind will then indicate the C call stack + * leading to the call site. + */ +#define DUK_CAUSE_SEGFAULT() \ + do { \ + *((volatile duk_uint32_t *)NULL) = (duk_uint32_t)0xdeadbeefUL; \ + } while (0) +#endif + +#if !defined(DUK_UNREF) +/* Macro for suppressing warnings for potentially unreferenced variables. + * The variables can be actually unreferenced or unreferenced in some + * specific cases only; for instance, if a variable is only debug printed, + * it is unreferenced when debug printing is disabled. May cause warnings + * for volatile arguments. + */ +#define DUK_UNREF(x) \ + do { \ + (void)(x); \ + } while (0) +#endif + +/* Fillin for DUK_NORETURN; DUK_WO_NORETURN() is used to insert dummy + * dummy statements after noreturn calls to silence harmless compiler + * warnings, e.g.: + * + * DUK_ERROR_TYPE(thr, "aiee"); + * DUK_WO_NORETURN(return 0;); + * + * Statements inside DUK_WO_NORETURN() must NEVER be actually reachable, + * and they're only included to satisfy the compiler. + */ +#if defined(DUK_NORETURN) +#define DUK_WO_NORETURN(stmt) \ + do { \ + } while (0) +#else +#define DUK_NORETURN(decl) decl +#define DUK_WO_NORETURN(stmt) \ + do { \ + stmt \ + } while (0) +#endif + +#if defined(DUK_UNREACHABLE) +#define DUK_WO_UNREACHABLE(stmt) \ + do { \ + } while (0) +#else +/* Don't know how to declare unreachable point, so don't do it; this + * may cause some spurious compilation warnings (e.g. "variable used + * uninitialized"). + */ +#define DUK_UNREACHABLE() \ + do { \ + } while (0) +#define DUK_WO_UNREACHABLE(stmt) \ + do { \ + stmt \ + } while (0) +#endif + +#if !defined(DUK_LOSE_CONST) +/* Convert any input pointer into a "void *", losing a const qualifier. + * This is not fully portable because casting through duk_uintptr_t may + * not work on all architectures (e.g. those with long, segmented pointers). + */ +#define DUK_LOSE_CONST(src) ((void *)(duk_uintptr_t)(src)) +#endif + +#if !defined(DUK_LIKELY) +#define DUK_LIKELY(x) (x) +#endif +#if !defined(DUK_UNLIKELY) +#define DUK_UNLIKELY(x) (x) +#endif +#if !defined(DUK_UNPREDICTABLE) +#define DUK_UNPREDICTABLE(x) (x) +#endif + +#if !defined(DUK_NOINLINE) +#define DUK_NOINLINE /*nop*/ +#endif +#if !defined(DUK_INLINE) +#define DUK_INLINE /*nop*/ +#endif +#if !defined(DUK_ALWAYS_INLINE) +#define DUK_ALWAYS_INLINE /*nop*/ +#endif + +#if !defined(DUK_HOT) +#define DUK_HOT /*nop*/ +#endif +#if !defined(DUK_COLD) +#define DUK_COLD /*nop*/ +#endif + +#if !defined(DUK_EXTERNAL_DECL) +#define DUK_EXTERNAL_DECL extern +#endif +#if !defined(DUK_EXTERNAL) +#define DUK_EXTERNAL /*empty*/ +#endif +#if !defined(DUK_INTERNAL_DECL) +#if defined(DUK_SINGLE_FILE) +#define DUK_INTERNAL_DECL static +#else +#define DUK_INTERNAL_DECL extern +#endif +#endif +#if !defined(DUK_INTERNAL) +#if defined(DUK_SINGLE_FILE) +#define DUK_INTERNAL static +#else +#define DUK_INTERNAL /*empty*/ +#endif +#endif +#if !defined(DUK_LOCAL_DECL) +#define DUK_LOCAL_DECL static +#endif +#if !defined(DUK_LOCAL) +#define DUK_LOCAL static +#endif + +#if !defined(DUK_FILE_MACRO) +#define DUK_FILE_MACRO __FILE__ +#endif +#if !defined(DUK_LINE_MACRO) +#define DUK_LINE_MACRO __LINE__ +#endif +#if !defined(DUK_FUNC_MACRO) +#if defined(DUK_F_C99) || defined(DUK_F_CPP11) +#define DUK_FUNC_MACRO __func__ +#elif defined(__FUNCTION__) +#define DUK_FUNC_MACRO __FUNCTION__ +#else +#define DUK_FUNC_MACRO "unknown" +#endif +#endif + +#if defined(DUK_F_HAVE_64BIT) +#if !defined(DUK_BSWAP64) +#define DUK_BSWAP64(x) \ + ((((duk_uint64_t)(x)) >> 56U) | \ + ((((duk_uint64_t)(x)) >> 40U) & DUK_U64_CONSTANT(0xff00)) | \ + ((((duk_uint64_t)(x)) >> 24U) & DUK_U64_CONSTANT(0xff0000)) | \ + ((((duk_uint64_t)(x)) >> 8U) & DUK_U64_CONSTANT(0xff000000)) | \ + ((((duk_uint64_t)(x)) << 8U) & DUK_U64_CONSTANT(0xff00000000)) | \ + ((((duk_uint64_t)(x)) << 24U) & DUK_U64_CONSTANT(0xff0000000000)) | \ + ((((duk_uint64_t)(x)) << 40U) & DUK_U64_CONSTANT(0xff000000000000)) | \ + (((duk_uint64_t)(x)) << 56U)) +#endif +#endif +#if !defined(DUK_BSWAP32) +#define DUK_BSWAP32(x) \ + ((((duk_uint32_t)(x)) >> 24U) | ((((duk_uint32_t)(x)) >> 8U) & 0xff00UL) | \ + ((((duk_uint32_t)(x)) << 8U) & 0xff0000UL) | (((duk_uint32_t)(x)) << 24U)) +#endif +#if !defined(DUK_BSWAP16) +#define DUK_BSWAP16(x) ((duk_uint16_t)(x) >> 8U) | ((duk_uint16_t)(x) << 8U) +#endif + +/* DUK_USE_VARIADIC_MACROS: required from compilers, so no fill-in. */ +/* DUK_USE_UNION_INITIALIZERS: required from compilers, so no fill-in. */ + +#if !(defined(DUK_USE_FLEX_C99) || defined(DUK_USE_FLEX_ZEROSIZE) || \ + defined(DUK_USE_FLEX_ONESIZE)) +#if defined(DUK_F_C99) +#define DUK_USE_FLEX_C99 +#else +#define DUK_USE_FLEX_ZEROSIZE /* Not standard but common enough */ +#endif +#endif + +#if !(defined(DUK_USE_PACK_GCC_ATTR) || defined(DUK_USE_PACK_CLANG_ATTR) || \ + defined(DUK_USE_PACK_MSVC_PRAGMA) || defined(DUK_USE_PACK_DUMMY_MEMBER)) +#define DUK_USE_PACK_DUMMY_MEMBER +#endif + +#if 0 /* not defined by default */ +#undef DUK_USE_GCC_PRAGMAS +#endif + +/* Workaround for GH-323: avoid inlining control when compiling from + * multiple sources, as it causes compiler portability trouble. + */ +#if !defined(DUK_SINGLE_FILE) +#undef DUK_NOINLINE +#undef DUK_INLINE +#undef DUK_ALWAYS_INLINE +#define DUK_NOINLINE /*nop*/ +#define DUK_INLINE /*nop*/ +#define DUK_ALWAYS_INLINE /*nop*/ +#endif + +/* Object property allocation layout has implications for memory and code + * footprint and generated code size/speed. The best layout also depends + * on whether the platform has alignment requirements or benefits from + * having mostly aligned accesses. + */ +#undef DUK_USE_HOBJECT_LAYOUT_1 +#undef DUK_USE_HOBJECT_LAYOUT_2 +#undef DUK_USE_HOBJECT_LAYOUT_3 +#if (DUK_USE_ALIGN_BY == 1) +/* On platforms without any alignment issues, layout 1 is preferable + * because it compiles to slightly less code and provides direct access + * to property keys. + */ +#define DUK_USE_HOBJECT_LAYOUT_1 +#else +/* On other platforms use layout 2, which requires some padding but + * is a bit more natural than layout 3 in ordering the entries. Layout + * 3 is currently not used. + */ +#define DUK_USE_HOBJECT_LAYOUT_2 +#endif + +/* GCC/clang inaccurate math would break compliance and probably duk_tval, + * so refuse to compile. Relax this if -ffast-math is tested to work. + */ +#if defined(__FAST_MATH__) +#error __FAST_MATH__ defined, refusing to compile +#endif + +/* + * Autogenerated defaults + */ + +#undef DUK_USE_ALLOW_UNDEFINED_BEHAVIOR +#define DUK_USE_ARRAY_BUILTIN +#define DUK_USE_ARRAY_FASTPATH +#define DUK_USE_ARRAY_PROP_FASTPATH +#undef DUK_USE_ASSERTIONS +#define DUK_USE_AUGMENT_ERROR_CREATE +#define DUK_USE_AUGMENT_ERROR_THROW +#define DUK_USE_AVOID_PLATFORM_FUNCPTRS +#define DUK_USE_BASE64_FASTPATH +#define DUK_USE_BASE64_SUPPORT +#define DUK_USE_BOOLEAN_BUILTIN +#define DUK_USE_BUFFEROBJECT_SUPPORT +#undef DUK_USE_BUFLEN16 +#define DUK_USE_BYTECODE_DUMP_SUPPORT +#define DUK_USE_CACHE_ACTIVATION +#define DUK_USE_CACHE_CATCHER +#define DUK_USE_CALLSTACK_LIMIT 10000 +#define DUK_USE_CBOR_BUILTIN +#define DUK_USE_CBOR_SUPPORT +#undef DUK_USE_CLANG_PRAGMAS +#define DUK_USE_COMPILER_RECLIMIT 2500 +#define DUK_USE_COROUTINE_SUPPORT +#undef DUK_USE_CPP_EXCEPTIONS +#undef DUK_USE_DATAPTR16 +#undef DUK_USE_DATAPTR_DEC16 +#undef DUK_USE_DATAPTR_ENC16 +#define DUK_USE_DATE_BUILTIN +#undef DUK_USE_DATE_FORMAT_STRING +#undef DUK_USE_DATE_GET_LOCAL_TZOFFSET +#undef DUK_USE_DATE_GET_NOW +#undef DUK_USE_DATE_PARSE_STRING +#undef DUK_USE_DATE_PRS_GETDATE +#undef DUK_USE_DEBUG +#undef DUK_USE_DEBUGGER_DUMPHEAP +#undef DUK_USE_DEBUGGER_INSPECT +#undef DUK_USE_DEBUGGER_PAUSE_UNCAUGHT +#undef DUK_USE_DEBUGGER_SUPPORT +#define DUK_USE_DEBUGGER_THROW_NOTIFY +#undef DUK_USE_DEBUGGER_TRANSPORT_TORTURE +#define DUK_USE_DEBUG_BUFSIZE 65536L +#define DUK_USE_DEBUG_LEVEL 0 +#undef DUK_USE_DEBUG_WRITE +#define DUK_USE_DOUBLE_LINKED_HEAP +#define DUK_USE_DUKTAPE_BUILTIN +#define DUK_USE_ENCODING_BUILTINS +#define DUK_USE_ERRCREATE +#define DUK_USE_ERRTHROW +#define DUK_USE_ES6 +#define DUK_USE_ES6_OBJECT_PROTO_PROPERTY +#define DUK_USE_ES6_OBJECT_SETPROTOTYPEOF +#define DUK_USE_ES6_PROXY +#define DUK_USE_ES6_REGEXP_SYNTAX +#define DUK_USE_ES6_UNICODE_ESCAPE +#define DUK_USE_ES7 +#define DUK_USE_ES7_EXP_OPERATOR +#define DUK_USE_ES8 +#define DUK_USE_ES9 +#define DUK_USE_ESBC_LIMITS +#define DUK_USE_ESBC_MAX_BYTES 2147418112L +#define DUK_USE_ESBC_MAX_LINENUMBER 2147418112L +#undef DUK_USE_EXEC_FUN_LOCAL +#undef DUK_USE_EXEC_INDIRECT_BOUND_CHECK +#undef DUK_USE_EXEC_PREFER_SIZE +#define DUK_USE_EXEC_REGCONST_OPTIMIZE +#undef DUK_USE_EXEC_TIMEOUT_CHECK +#undef DUK_USE_EXPLICIT_NULL_INIT +#undef DUK_USE_EXTSTR_FREE +#undef DUK_USE_EXTSTR_INTERN_CHECK +#undef DUK_USE_FASTINT +#define DUK_USE_FAST_REFCOUNT_DEFAULT +#undef DUK_USE_FATAL_HANDLER +#define DUK_USE_FATAL_MAXLEN 128 +#define DUK_USE_FINALIZER_SUPPORT +#undef DUK_USE_FINALIZER_TORTURE +#undef DUK_USE_FUNCPTR16 +#undef DUK_USE_FUNCPTR_DEC16 +#undef DUK_USE_FUNCPTR_ENC16 +#define DUK_USE_FUNCTION_BUILTIN +#define DUK_USE_FUNC_FILENAME_PROPERTY +#define DUK_USE_FUNC_NAME_PROPERTY +#undef DUK_USE_GC_TORTURE +#undef DUK_USE_GET_MONOTONIC_TIME +#undef DUK_USE_GET_RANDOM_DOUBLE +#define DUK_USE_GLOBAL_BINDING +#define DUK_USE_GLOBAL_BUILTIN +#undef DUK_USE_HEAPPTR16 +#undef DUK_USE_HEAPPTR_DEC16 +#undef DUK_USE_HEAPPTR_ENC16 +#define DUK_USE_HEX_FASTPATH +#define DUK_USE_HEX_SUPPORT +#define DUK_USE_HOBJECT_ARRAY_ABANDON_LIMIT 2 +#define DUK_USE_HOBJECT_ARRAY_ABANDON_MINSIZE 257 +#define DUK_USE_HOBJECT_ARRAY_FAST_RESIZE_LIMIT 9 +#define DUK_USE_HOBJECT_ARRAY_MINGROW_ADD 16 +#define DUK_USE_HOBJECT_ARRAY_MINGROW_DIVISOR 8 +#define DUK_USE_HOBJECT_ENTRY_MINGROW_ADD 16 +#define DUK_USE_HOBJECT_ENTRY_MINGROW_DIVISOR 8 +#define DUK_USE_HOBJECT_HASH_PART +#define DUK_USE_HOBJECT_HASH_PROP_LIMIT 8 +#define DUK_USE_HSTRING_ARRIDX +#define DUK_USE_HSTRING_CLEN +#undef DUK_USE_HSTRING_EXTDATA +#define DUK_USE_HSTRING_LAZY_CLEN +#define DUK_USE_HTML_COMMENTS +#define DUK_USE_IDCHAR_FASTPATH +#undef DUK_USE_INJECT_HEAP_ALLOC_ERROR +#undef DUK_USE_INTERRUPT_COUNTER +#undef DUK_USE_INTERRUPT_DEBUG_FIXUP +#define DUK_USE_JC +#define DUK_USE_JSON_BUILTIN +#define DUK_USE_JSON_DECNUMBER_FASTPATH +#define DUK_USE_JSON_DECSTRING_FASTPATH +#define DUK_USE_JSON_DEC_RECLIMIT 1000 +#define DUK_USE_JSON_EATWHITE_FASTPATH +#define DUK_USE_JSON_ENC_RECLIMIT 1000 +#define DUK_USE_JSON_QUOTESTRING_FASTPATH +#undef DUK_USE_JSON_STRINGIFY_FASTPATH +#define DUK_USE_JSON_SUPPORT +#define DUK_USE_JX +#define DUK_USE_LEXER_SLIDING_WINDOW +#undef DUK_USE_LIGHTFUNC_BUILTINS +#define DUK_USE_LITCACHE_SIZE 256 +#define DUK_USE_MARK_AND_SWEEP_RECLIMIT 256 +#define DUK_USE_MATH_BUILTIN +#define DUK_USE_NATIVE_CALL_RECLIMIT 1000 +#undef DUK_USE_NATIVE_STACK_CHECK +#define DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT +#undef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY +#undef DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY +#define DUK_USE_NONSTD_FUNC_STMT +#define DUK_USE_NONSTD_GETTER_KEY_ARGUMENT +#define DUK_USE_NONSTD_JSON_ESC_U2028_U2029 +#define DUK_USE_NONSTD_SETTER_KEY_ARGUMENT +#define DUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT +#define DUK_USE_NUMBER_BUILTIN +#define DUK_USE_OBJECT_BUILTIN +#undef DUK_USE_OBJSIZES16 +#undef DUK_USE_PACK_CLANG_ATTR +#undef DUK_USE_PACK_MSVC_PRAGMA +#undef DUK_USE_PARANOID_ERRORS +#define DUK_USE_PC2LINE +#define DUK_USE_PERFORMANCE_BUILTIN +#undef DUK_USE_PREFER_SIZE +#undef DUK_USE_PROMISE_BUILTIN +#define DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS +#undef DUK_USE_REFCOUNT16 +#define DUK_USE_REFCOUNT32 +#define DUK_USE_REFERENCE_COUNTING +#define DUK_USE_REFLECT_BUILTIN +#define DUK_USE_REGEXP_CANON_BITMAP +#undef DUK_USE_REGEXP_CANON_WORKAROUND +#define DUK_USE_REGEXP_COMPILER_RECLIMIT 10000 +#define DUK_USE_REGEXP_EXECUTOR_RECLIMIT 10000 +#define DUK_USE_REGEXP_SUPPORT +#undef DUK_USE_ROM_GLOBAL_CLONE +#undef DUK_USE_ROM_GLOBAL_INHERIT +#undef DUK_USE_ROM_OBJECTS +#define DUK_USE_ROM_PTRCOMP_FIRST 63488L +#undef DUK_USE_ROM_STRINGS +#define DUK_USE_SECTION_B +#undef DUK_USE_SELF_TESTS +#define DUK_USE_SHEBANG_COMMENTS +#undef DUK_USE_SHUFFLE_TORTURE +#define DUK_USE_SOURCE_NONBMP +#undef DUK_USE_STRHASH16 +#undef DUK_USE_STRHASH_DENSE +#define DUK_USE_STRHASH_SKIP_SHIFT 5 +#define DUK_USE_STRICT_DECL +#undef DUK_USE_STRICT_UTF8_SOURCE +#define DUK_USE_STRING_BUILTIN +#undef DUK_USE_STRLEN16 +#define DUK_USE_STRTAB_GROW_LIMIT 17 +#define DUK_USE_STRTAB_MAXSIZE 268435456L +#define DUK_USE_STRTAB_MINSIZE 1024 +#undef DUK_USE_STRTAB_PTRCOMP +#define DUK_USE_STRTAB_RESIZE_CHECK_MASK 255 +#define DUK_USE_STRTAB_SHRINK_LIMIT 6 +#undef DUK_USE_STRTAB_TORTURE +#define DUK_USE_SYMBOL_BUILTIN +#define DUK_USE_TAILCALL +#define DUK_USE_TARGET_INFO "unknown" +#define DUK_USE_TRACEBACKS +#define DUK_USE_TRACEBACK_DEPTH 10 +#define DUK_USE_VALSTACK_GROW_SHIFT 2 +#define DUK_USE_VALSTACK_LIMIT 1000000L +#define DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT 2 +#define DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT 4 +#undef DUK_USE_VALSTACK_UNSAFE +#define DUK_USE_VERBOSE_ERRORS +#define DUK_USE_VERBOSE_EXECUTOR_ERRORS +#define DUK_USE_VOLUNTARY_GC +#define DUK_USE_ZERO_BUFFER_DATA + +/* + * You may add overriding #define/#undef directives below for + * customization. You of course cannot un-#include or un-typedef + * anything; these require direct changes above. + */ + +/* __OVERRIDE_DEFINES__ */ + +/* + * Conditional includes + */ + +#if defined(DUK_F_CPP) && defined(DUK_USE_CPP_EXCEPTIONS) +#endif + +/* + * Date provider selection + * + * User may define DUK_USE_DATE_GET_NOW() etc directly, in which case we'll + * rely on an external provider. If this is not done, revert to previous + * behavior and use Unix/Windows built-in provider. + */ + +#if defined(DUK_COMPILING_DUKTAPE) + +#if defined(DUK_USE_DATE_GET_NOW) +/* External provider already defined. */ +#elif defined(DUK_USE_DATE_NOW_GETTIMEOFDAY) +#define DUK_USE_DATE_GET_NOW(ctx) duk_bi_date_get_now_gettimeofday() +#elif defined(DUK_USE_DATE_NOW_TIME) +#define DUK_USE_DATE_GET_NOW(ctx) duk_bi_date_get_now_time() +#elif defined(DUK_USE_DATE_NOW_WINDOWS) +#define DUK_USE_DATE_GET_NOW(ctx) duk_bi_date_get_now_windows() +#elif defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS) +#define DUK_USE_DATE_GET_NOW(ctx) duk_bi_date_get_now_windows_subms() +#else +#error no provider for DUK_USE_DATE_GET_NOW() +#endif + +#if defined(DUK_USE_DATE_GET_LOCAL_TZOFFSET) +/* External provider already defined. */ +#elif defined(DUK_USE_DATE_TZO_GMTIME_R) || \ + defined(DUK_USE_DATE_TZO_GMTIME_S) || defined(DUK_USE_DATE_TZO_GMTIME) +#define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d) \ + duk_bi_date_get_local_tzoffset_gmtime((d)) +#elif defined(DUK_USE_DATE_TZO_WINDOWS) +#define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d) \ + duk_bi_date_get_local_tzoffset_windows((d)) +#elif defined(DUK_USE_DATE_TZO_WINDOWS_NO_DST) +#define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d) \ + duk_bi_date_get_local_tzoffset_windows_no_dst((d)) +#else +#error no provider for DUK_USE_DATE_GET_LOCAL_TZOFFSET() +#endif + +#if defined(DUK_USE_DATE_PARSE_STRING) +/* External provider already defined. */ +#elif defined(DUK_USE_DATE_PRS_STRPTIME) +#define DUK_USE_DATE_PARSE_STRING(ctx, str) \ + duk_bi_date_parse_string_strptime((ctx), (str)) +#elif defined(DUK_USE_DATE_PRS_GETDATE) +#define DUK_USE_DATE_PARSE_STRING(ctx, str) \ + duk_bi_date_parse_string_getdate((ctx), (str)) +#else +/* No provider for DUK_USE_DATE_PARSE_STRING(), fall back to ISO 8601 only. */ +#endif + +#if defined(DUK_USE_DATE_FORMAT_STRING) +/* External provider already defined. */ +#elif defined(DUK_USE_DATE_FMT_STRFTIME) +#define DUK_USE_DATE_FORMAT_STRING(ctx, parts, tzoffset, flags) \ + duk_bi_date_format_parts_strftime((ctx), (parts), (tzoffset), (flags)) +#else +/* No provider for DUK_USE_DATE_FORMAT_STRING(), fall back to ISO 8601 only. */ +#endif + +#if defined(DUK_USE_GET_MONOTONIC_TIME) +/* External provider already defined. */ +#elif defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME) +#define DUK_USE_GET_MONOTONIC_TIME(ctx) \ + duk_bi_date_get_monotonic_time_clock_gettime() +#elif defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC) +#define DUK_USE_GET_MONOTONIC_TIME(ctx) \ + duk_bi_date_get_monotonic_time_windows_qpc() +#else +/* No provider for DUK_USE_GET_MONOTONIC_TIME(), fall back to + * DUK_USE_DATE_GET_NOW(). */ +#endif + +#endif /* DUK_COMPILING_DUKTAPE */ + +/* + * Convert DUK_USE_BYTEORDER, from whatever source, into currently used + * internal defines. If detection failed, #error out. + */ + +#if defined(DUK_USE_BYTEORDER) +#if (DUK_USE_BYTEORDER == 1) +#define DUK_USE_INTEGER_LE +#define DUK_USE_DOUBLE_LE +#elif (DUK_USE_BYTEORDER == 2) +#define DUK_USE_INTEGER_LE /* integer endianness is little on purpose */ +#define DUK_USE_DOUBLE_ME +#elif (DUK_USE_BYTEORDER == 3) +#define DUK_USE_INTEGER_BE +#define DUK_USE_DOUBLE_BE +#else +#error unsupported: byte order invalid +#endif /* byte order */ +#else +#error unsupported: byte order detection failed +#endif /* defined(DUK_USE_BYTEORDER) */ + +#endif /* DUK_CONFIG_H_INCLUDED */ diff --git a/third_party/duktape/duk_dblunion.h b/third_party/duktape/duk_dblunion.h new file mode 100644 index 00000000..a779653b --- /dev/null +++ b/third_party/duktape/duk_dblunion.h @@ -0,0 +1,424 @@ +/* + * Union to access IEEE double memory representation, indexes for double + * memory representation, and some macros for double manipulation. + * + * Also used by packed duk_tval. Use a union for bit manipulation to + * minimize aliasing issues in practice. The C99 standard does not + * guarantee that this should work, but it's a very widely supported + * practice for low level manipulation. + * + * IEEE double format summary: + * + * seeeeeee eeeeffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff + * A B C D E F G H + * + * s sign bit + * eee... exponent field + * fff... fraction + * + * See http://en.wikipedia.org/wiki/Double_precision_floating-point_format. + * + * NaNs are represented as exponent 0x7ff and mantissa != 0. The NaN is a + * signaling NaN when the highest bit of the mantissa is zero, and a quiet + * NaN when the highest bit is set. + * + * At least three memory layouts are relevant here: + * + * A B C D E F G H Big endian (e.g. 68k) DUK_USE_DOUBLE_BE + * H G F E D C B A Little endian (e.g. x86) DUK_USE_DOUBLE_LE + * D C B A H G F E Mixed endian (e.g. ARM FPA) DUK_USE_DOUBLE_ME + * + * Legacy ARM (FPA) is a special case: ARM double values are in mixed + * endian format while ARM duk_uint64_t values are in standard little endian + * format (H G F E D C B A). When a double is read as a duk_uint64_t + * from memory, the register will contain the (logical) value + * E F G H A B C D. This requires some special handling below. + * See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0056d/Bcfhgcgd.html. + * + * Indexes of various types (8-bit, 16-bit, 32-bit) in memory relative to + * the logical (big endian) order: + * + * byte order duk_uint8_t duk_uint16_t duk_uint32_t + * BE 01234567 0123 01 + * LE 76543210 3210 10 + * ME (ARM) 32107654 1032 01 + * + * Some processors may alter NaN values in a floating point load+store. + * For instance, on X86 a FLD + FSTP may convert a signaling NaN to a + * quiet one. This is catastrophic when NaN space is used in packed + * duk_tval values. See: misc/clang_aliasing.c. + */ + +#if !defined(DUK_DBLUNION_H_INCLUDED) +#define DUK_DBLUNION_H_INCLUDED + +/* + * Union for accessing double parts, also serves as packed duk_tval + */ + +union duk_double_union { + double d; + float f[2]; +#if defined(DUK_USE_64BIT_OPS) + duk_uint64_t ull[1]; +#endif + duk_uint32_t ui[2]; + duk_uint16_t us[4]; + duk_uint8_t uc[8]; +#if defined(DUK_USE_PACKED_TVAL) + void *vp[2]; /* used by packed duk_tval, assumes sizeof(void *) == 4 */ +#endif +}; + +typedef union duk_double_union duk_double_union; + +/* + * Indexes of various types with respect to big endian (logical) layout + */ + +#if defined(DUK_USE_DOUBLE_LE) +#if defined(DUK_USE_64BIT_OPS) +#define DUK_DBL_IDX_ULL0 0 +#endif +#define DUK_DBL_IDX_UI0 1 +#define DUK_DBL_IDX_UI1 0 +#define DUK_DBL_IDX_US0 3 +#define DUK_DBL_IDX_US1 2 +#define DUK_DBL_IDX_US2 1 +#define DUK_DBL_IDX_US3 0 +#define DUK_DBL_IDX_UC0 7 +#define DUK_DBL_IDX_UC1 6 +#define DUK_DBL_IDX_UC2 5 +#define DUK_DBL_IDX_UC3 4 +#define DUK_DBL_IDX_UC4 3 +#define DUK_DBL_IDX_UC5 2 +#define DUK_DBL_IDX_UC6 1 +#define DUK_DBL_IDX_UC7 0 +#define DUK_DBL_IDX_VP0 DUK_DBL_IDX_UI0 /* packed tval */ +#define DUK_DBL_IDX_VP1 DUK_DBL_IDX_UI1 /* packed tval */ +#elif defined(DUK_USE_DOUBLE_BE) +#if defined(DUK_USE_64BIT_OPS) +#define DUK_DBL_IDX_ULL0 0 +#endif +#define DUK_DBL_IDX_UI0 0 +#define DUK_DBL_IDX_UI1 1 +#define DUK_DBL_IDX_US0 0 +#define DUK_DBL_IDX_US1 1 +#define DUK_DBL_IDX_US2 2 +#define DUK_DBL_IDX_US3 3 +#define DUK_DBL_IDX_UC0 0 +#define DUK_DBL_IDX_UC1 1 +#define DUK_DBL_IDX_UC2 2 +#define DUK_DBL_IDX_UC3 3 +#define DUK_DBL_IDX_UC4 4 +#define DUK_DBL_IDX_UC5 5 +#define DUK_DBL_IDX_UC6 6 +#define DUK_DBL_IDX_UC7 7 +#define DUK_DBL_IDX_VP0 DUK_DBL_IDX_UI0 /* packed tval */ +#define DUK_DBL_IDX_VP1 DUK_DBL_IDX_UI1 /* packed tval */ +#elif defined(DUK_USE_DOUBLE_ME) +#if defined(DUK_USE_64BIT_OPS) +#define DUK_DBL_IDX_ULL0 0 /* not directly applicable, byte order differs from a double */ +#endif +#define DUK_DBL_IDX_UI0 0 +#define DUK_DBL_IDX_UI1 1 +#define DUK_DBL_IDX_US0 1 +#define DUK_DBL_IDX_US1 0 +#define DUK_DBL_IDX_US2 3 +#define DUK_DBL_IDX_US3 2 +#define DUK_DBL_IDX_UC0 3 +#define DUK_DBL_IDX_UC1 2 +#define DUK_DBL_IDX_UC2 1 +#define DUK_DBL_IDX_UC3 0 +#define DUK_DBL_IDX_UC4 7 +#define DUK_DBL_IDX_UC5 6 +#define DUK_DBL_IDX_UC6 5 +#define DUK_DBL_IDX_UC7 4 +#define DUK_DBL_IDX_VP0 DUK_DBL_IDX_UI0 /* packed tval */ +#define DUK_DBL_IDX_VP1 DUK_DBL_IDX_UI1 /* packed tval */ +#else +#error internal error +#endif + +/* + * Helper macros for reading/writing memory representation parts, used + * by duk_numconv.c and duk_tval.h. + */ + +#define DUK_DBLUNION_SET_DOUBLE(u,v) do { \ + (u)->d = (v); \ + } while (0) + +#define DUK_DBLUNION_SET_HIGH32(u,v) do { \ + (u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) (v); \ + } while (0) + +#if defined(DUK_USE_64BIT_OPS) +#if defined(DUK_USE_DOUBLE_ME) +#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v) do { \ + (u)->ull[DUK_DBL_IDX_ULL0] = (duk_uint64_t) (v); \ + } while (0) +#else +#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v) do { \ + (u)->ull[DUK_DBL_IDX_ULL0] = ((duk_uint64_t) (v)) << 32; \ + } while (0) +#endif +#else /* DUK_USE_64BIT_OPS */ +#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v) do { \ + (u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) (v); \ + (u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) 0; \ + } while (0) +#endif /* DUK_USE_64BIT_OPS */ + +#define DUK_DBLUNION_SET_LOW32(u,v) do { \ + (u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (v); \ + } while (0) + +#define DUK_DBLUNION_GET_DOUBLE(u) ((u)->d) +#define DUK_DBLUNION_GET_HIGH32(u) ((u)->ui[DUK_DBL_IDX_UI0]) +#define DUK_DBLUNION_GET_LOW32(u) ((u)->ui[DUK_DBL_IDX_UI1]) + +#if defined(DUK_USE_64BIT_OPS) +#if defined(DUK_USE_DOUBLE_ME) +#define DUK_DBLUNION_SET_UINT64(u,v) do { \ + (u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) ((v) >> 32); \ + (u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (v); \ + } while (0) +#define DUK_DBLUNION_GET_UINT64(u) \ + ((((duk_uint64_t) (u)->ui[DUK_DBL_IDX_UI0]) << 32) | \ + ((duk_uint64_t) (u)->ui[DUK_DBL_IDX_UI1])) +#else +#define DUK_DBLUNION_SET_UINT64(u,v) do { \ + (u)->ull[DUK_DBL_IDX_ULL0] = (duk_uint64_t) (v); \ + } while (0) +#define DUK_DBLUNION_GET_UINT64(u) ((u)->ull[DUK_DBL_IDX_ULL0]) +#endif +#define DUK_DBLUNION_SET_INT64(u,v) DUK_DBLUNION_SET_UINT64((u), (duk_uint64_t) (v)) +#define DUK_DBLUNION_GET_INT64(u) ((duk_int64_t) DUK_DBLUNION_GET_UINT64((u))) +#endif /* DUK_USE_64BIT_OPS */ + +/* + * Double NaN manipulation macros related to NaN normalization needed when + * using the packed duk_tval representation. NaN normalization is necessary + * to keep double values compatible with the duk_tval format. + * + * When packed duk_tval is used, the NaN space is used to store pointers + * and other tagged values in addition to NaNs. Actual NaNs are normalized + * to a specific quiet NaN. The macros below are used by the implementation + * to check and normalize NaN values when they might be created. The macros + * are essentially NOPs when the non-packed duk_tval representation is used. + * + * A FULL check is exact and checks all bits. A NOTFULL check is used by + * the packed duk_tval and works correctly for all NaNs except those that + * begin with 0x7ff0. Since the 'normalized NaN' values used with packed + * duk_tval begin with 0x7ff8, the partial check is reliable when packed + * duk_tval is used. The 0x7ff8 prefix means the normalized NaN will be a + * quiet NaN regardless of its remaining lower bits. + * + * The ME variant below is specifically for ARM byte order, which has the + * feature that while doubles have a mixed byte order (32107654), unsigned + * long long values has a little endian byte order (76543210). When writing + * a logical double value through a ULL pointer, the 32-bit words need to be + * swapped; hence the #if defined()s below for ULL writes with DUK_USE_DOUBLE_ME. + * This is not full ARM support but suffices for some environments. + */ + +#if defined(DUK_USE_64BIT_OPS) +#if defined(DUK_USE_DOUBLE_ME) +/* Macros for 64-bit ops + mixed endian doubles. */ +#define DUK__DBLUNION_SET_NAN_FULL(u) do { \ + (u)->ull[DUK_DBL_IDX_ULL0] = DUK_U64_CONSTANT(0x000000007ff80000); \ + } while (0) +#define DUK__DBLUNION_IS_NAN_FULL(u) \ + ((((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000)) == DUK_U64_CONSTANT(0x000000007ff00000)) && \ + ((((u)->ull[DUK_DBL_IDX_ULL0]) & DUK_U64_CONSTANT(0xffffffff000fffff)) != 0)) +#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \ + ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff80000)) +#define DUK__DBLUNION_IS_ANYINF(u) \ + (((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0xffffffff7fffffff)) == DUK_U64_CONSTANT(0x000000007ff00000)) +#define DUK__DBLUNION_IS_POSINF(u) \ + ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff00000)) +#define DUK__DBLUNION_IS_NEGINF(u) \ + ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x00000000fff00000)) +#define DUK__DBLUNION_IS_ANYZERO(u) \ + (((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0xffffffff7fffffff)) == DUK_U64_CONSTANT(0x0000000000000000)) +#define DUK__DBLUNION_IS_POSZERO(u) \ + ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000)) +#define DUK__DBLUNION_IS_NEGZERO(u) \ + ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000080000000)) +#else +/* Macros for 64-bit ops + big/little endian doubles. */ +#define DUK__DBLUNION_SET_NAN_FULL(u) do { \ + (u)->ull[DUK_DBL_IDX_ULL0] = DUK_U64_CONSTANT(0x7ff8000000000000); \ + } while (0) +#define DUK__DBLUNION_IS_NAN_FULL(u) \ + ((((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000)) == DUK_U64_CONSTANT(0x7ff0000000000000)) && \ + ((((u)->ull[DUK_DBL_IDX_ULL0]) & DUK_U64_CONSTANT(0x000fffffffffffff)) != 0)) +#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \ + ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff8000000000000)) +#define DUK__DBLUNION_IS_ANYINF(u) \ + (((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7fffffffffffffff)) == DUK_U64_CONSTANT(0x7ff0000000000000)) +#define DUK__DBLUNION_IS_POSINF(u) \ + ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff0000000000000)) +#define DUK__DBLUNION_IS_NEGINF(u) \ + ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0xfff0000000000000)) +#define DUK__DBLUNION_IS_ANYZERO(u) \ + (((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7fffffffffffffff)) == DUK_U64_CONSTANT(0x0000000000000000)) +#define DUK__DBLUNION_IS_POSZERO(u) \ + ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000)) +#define DUK__DBLUNION_IS_NEGZERO(u) \ + ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x8000000000000000)) +#endif +#else /* DUK_USE_64BIT_OPS */ +/* Macros for no 64-bit ops, any endianness. */ +#define DUK__DBLUNION_SET_NAN_FULL(u) do { \ + (u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) 0x7ff80000UL; \ + (u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) 0x00000000UL; \ + } while (0) +#define DUK__DBLUNION_IS_NAN_FULL(u) \ + ((((u)->ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL) && \ + (((u)->ui[DUK_DBL_IDX_UI0] & 0x000fffffUL) != 0 || \ + (u)->ui[DUK_DBL_IDX_UI1] != 0)) +#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \ + (((u)->ui[DUK_DBL_IDX_UI0] == 0x7ff80000UL) && \ + ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL)) +#define DUK__DBLUNION_IS_ANYINF(u) \ + ((((u)->ui[DUK_DBL_IDX_UI0] & 0x7fffffffUL) == 0x7ff00000UL) && \ + ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL)) +#define DUK__DBLUNION_IS_POSINF(u) \ + (((u)->ui[DUK_DBL_IDX_UI0] == 0x7ff00000UL) && \ + ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL)) +#define DUK__DBLUNION_IS_NEGINF(u) \ + (((u)->ui[DUK_DBL_IDX_UI0] == 0xfff00000UL) && \ + ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL)) +#define DUK__DBLUNION_IS_ANYZERO(u) \ + ((((u)->ui[DUK_DBL_IDX_UI0] & 0x7fffffffUL) == 0x00000000UL) && \ + ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL)) +#define DUK__DBLUNION_IS_POSZERO(u) \ + (((u)->ui[DUK_DBL_IDX_UI0] == 0x00000000UL) && \ + ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL)) +#define DUK__DBLUNION_IS_NEGZERO(u) \ + (((u)->ui[DUK_DBL_IDX_UI0] == 0x80000000UL) && \ + ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL)) +#endif /* DUK_USE_64BIT_OPS */ + +#define DUK__DBLUNION_SET_NAN_NOTFULL(u) do { \ + (u)->us[DUK_DBL_IDX_US0] = 0x7ff8UL; \ + } while (0) + +#define DUK__DBLUNION_IS_NAN_NOTFULL(u) \ + /* E == 0x7ff, topmost four bits of F != 0 => assume NaN */ \ + ((((u)->us[DUK_DBL_IDX_US0] & 0x7ff0UL) == 0x7ff0UL) && \ + (((u)->us[DUK_DBL_IDX_US0] & 0x000fUL) != 0x0000UL)) + +#define DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL(u) \ + /* E == 0x7ff, F == 8 => normalized NaN */ \ + ((u)->us[DUK_DBL_IDX_US0] == 0x7ff8UL) + +#define DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL(u) do { \ + if (DUK__DBLUNION_IS_NAN_FULL((u))) { \ + DUK__DBLUNION_SET_NAN_FULL((u)); \ + } \ + } while (0) + +#define DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL(u) do { \ + if (DUK__DBLUNION_IS_NAN_NOTFULL((u))) { \ + DUK__DBLUNION_SET_NAN_NOTFULL((u)); \ + } \ + } while (0) + +/* Concrete macros for NaN handling used by the implementation internals. + * Chosen so that they match the duk_tval representation: with a packed + * duk_tval, ensure NaNs are properly normalized; with a non-packed duk_tval + * these are essentially NOPs. + */ + +#if defined(DUK_USE_PACKED_TVAL) +#if defined(DUK_USE_FULL_TVAL) +#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL((u)) +#define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_FULL((u)) +#define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NORMALIZED_NAN_FULL((u)) +#define DUK_DBLUNION_SET_NAN(d) DUK__DBLUNION_SET_NAN_FULL((d)) +#else +#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL((u)) +#define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_NOTFULL((u)) +#define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL((u)) +#define DUK_DBLUNION_SET_NAN(d) DUK__DBLUNION_SET_NAN_NOTFULL((d)) +#endif +#define DUK_DBLUNION_IS_NORMALIZED(u) \ + (!DUK_DBLUNION_IS_NAN((u)) || /* either not a NaN */ \ + DUK_DBLUNION_IS_NORMALIZED_NAN((u))) /* or is a normalized NaN */ +#else /* DUK_USE_PACKED_TVAL */ +#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) /* nop: no need to normalize */ +#define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_FULL((u)) /* (DUK_ISNAN((u)->d)) */ +#define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NAN_FULL((u)) /* (DUK_ISNAN((u)->d)) */ +#define DUK_DBLUNION_IS_NORMALIZED(u) 1 /* all doubles are considered normalized */ +#define DUK_DBLUNION_SET_NAN(u) do { \ + /* in non-packed representation we don't care about which NaN is used */ \ + (u)->d = DUK_DOUBLE_NAN; \ + } while (0) +#endif /* DUK_USE_PACKED_TVAL */ + +#define DUK_DBLUNION_IS_ANYINF(u) DUK__DBLUNION_IS_ANYINF((u)) +#define DUK_DBLUNION_IS_POSINF(u) DUK__DBLUNION_IS_POSINF((u)) +#define DUK_DBLUNION_IS_NEGINF(u) DUK__DBLUNION_IS_NEGINF((u)) + +#define DUK_DBLUNION_IS_ANYZERO(u) DUK__DBLUNION_IS_ANYZERO((u)) +#define DUK_DBLUNION_IS_POSZERO(u) DUK__DBLUNION_IS_POSZERO((u)) +#define DUK_DBLUNION_IS_NEGZERO(u) DUK__DBLUNION_IS_NEGZERO((u)) + +/* XXX: native 64-bit byteswaps when available */ + +/* 64-bit byteswap, same operation independent of target endianness. */ +#define DUK_DBLUNION_BSWAP64(u) do { \ + duk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \ + duk__bswaptmp1 = (u)->ui[0]; \ + duk__bswaptmp2 = (u)->ui[1]; \ + duk__bswaptmp1 = DUK_BSWAP32(duk__bswaptmp1); \ + duk__bswaptmp2 = DUK_BSWAP32(duk__bswaptmp2); \ + (u)->ui[0] = duk__bswaptmp2; \ + (u)->ui[1] = duk__bswaptmp1; \ + } while (0) + +/* Byteswap an IEEE double in the duk_double_union from host to network + * order. For a big endian target this is a no-op. + */ +#if defined(DUK_USE_DOUBLE_LE) +#define DUK_DBLUNION_DOUBLE_HTON(u) do { \ + duk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \ + duk__bswaptmp1 = (u)->ui[0]; \ + duk__bswaptmp2 = (u)->ui[1]; \ + duk__bswaptmp1 = DUK_BSWAP32(duk__bswaptmp1); \ + duk__bswaptmp2 = DUK_BSWAP32(duk__bswaptmp2); \ + (u)->ui[0] = duk__bswaptmp2; \ + (u)->ui[1] = duk__bswaptmp1; \ + } while (0) +#elif defined(DUK_USE_DOUBLE_ME) +#define DUK_DBLUNION_DOUBLE_HTON(u) do { \ + duk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \ + duk__bswaptmp1 = (u)->ui[0]; \ + duk__bswaptmp2 = (u)->ui[1]; \ + duk__bswaptmp1 = DUK_BSWAP32(duk__bswaptmp1); \ + duk__bswaptmp2 = DUK_BSWAP32(duk__bswaptmp2); \ + (u)->ui[0] = duk__bswaptmp1; \ + (u)->ui[1] = duk__bswaptmp2; \ + } while (0) +#elif defined(DUK_USE_DOUBLE_BE) +#define DUK_DBLUNION_DOUBLE_HTON(u) do { } while (0) +#else +#error internal error, double endianness insane +#endif + +/* Reverse operation is the same. */ +#define DUK_DBLUNION_DOUBLE_NTOH(u) DUK_DBLUNION_DOUBLE_HTON((u)) + +/* Some sign bit helpers. */ +#if defined(DUK_USE_64BIT_OPS) +#define DUK_DBLUNION_HAS_SIGNBIT(u) (((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x8000000000000000)) != 0) +#define DUK_DBLUNION_GET_SIGNBIT(u) (((u)->ull[DUK_DBL_IDX_ULL0] >> 63U)) +#else +#define DUK_DBLUNION_HAS_SIGNBIT(u) (((u)->ui[DUK_DBL_IDX_UI0] & 0x80000000UL) != 0) +#define DUK_DBLUNION_GET_SIGNBIT(u) (((u)->ui[DUK_DBL_IDX_UI0] >> 31U)) +#endif + +#endif /* DUK_DBLUNION_H_INCLUDED */ diff --git a/third_party/duktape/duk_debug.h b/third_party/duktape/duk_debug.h new file mode 100644 index 00000000..0b496c48 --- /dev/null +++ b/third_party/duktape/duk_debug.h @@ -0,0 +1,184 @@ +/* + * Debugging macros, DUK_DPRINT() and its variants in particular. + * + * DUK_DPRINT() allows formatted debug prints, and supports standard + * and Duktape specific formatters. See duk_debug_vsnprintf.c for details. + * + * DUK_D(x), DUK_DD(x), and DUK_DDD(x) are used together with log macros + * for technical reasons. They are concretely used to hide 'x' from the + * compiler when the corresponding log level is disabled. This allows + * clean builds on non-C99 compilers, at the cost of more verbose code. + * Examples: + * + * DUK_D(DUK_DPRINT("foo")); + * DUK_DD(DUK_DDPRINT("foo")); + * DUK_DDD(DUK_DDDPRINT("foo")); + * + * This approach is preferable to the old "double parentheses" hack because + * double parentheses make the C99 solution worse: __FILE__ and __LINE__ can + * no longer be added transparently without going through globals, which + * works poorly with threading. + */ + +#if !defined(DUK_DEBUG_H_INCLUDED) +#define DUK_DEBUG_H_INCLUDED + +#if defined(DUK_USE_DEBUG) + +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0) +#define DUK_D(x) x +#else +#define DUK_D(x) do { } while (0) /* omit */ +#endif + +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1) +#define DUK_DD(x) x +#else +#define DUK_DD(x) do { } while (0) /* omit */ +#endif + +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2) +#define DUK_DDD(x) x +#else +#define DUK_DDD(x) do { } while (0) /* omit */ +#endif + +/* + * Exposed debug macros: debugging enabled + */ + +#if defined(DUK_USE_VARIADIC_MACROS) + +/* Note: combining __FILE__, __LINE__, and __func__ into fmt would be + * possible compile time, but waste some space with shared function names. + */ +#define DUK__DEBUG_LOG(lev,...) duk_debug_log((duk_int_t) (lev), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, DUK_FUNC_MACRO, __VA_ARGS__); + +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0) +#define DUK_DPRINT(...) DUK__DEBUG_LOG(DUK_LEVEL_DEBUG, __VA_ARGS__) +#else +#define DUK_DPRINT(...) +#endif + +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1) +#define DUK_DDPRINT(...) DUK__DEBUG_LOG(DUK_LEVEL_DDEBUG, __VA_ARGS__) +#else +#define DUK_DDPRINT(...) +#endif + +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2) +#define DUK_DDDPRINT(...) DUK__DEBUG_LOG(DUK_LEVEL_DDDEBUG, __VA_ARGS__) +#else +#define DUK_DDDPRINT(...) +#endif + +#else /* DUK_USE_VARIADIC_MACROS */ + +#define DUK__DEBUG_STASH(lev) \ + (void) DUK_SNPRINTF(duk_debug_file_stash, DUK_DEBUG_STASH_SIZE, "%s", (const char *) DUK_FILE_MACRO), \ + (void) (duk_debug_file_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0), \ + (void) (duk_debug_line_stash = (duk_int_t) DUK_LINE_MACRO), \ + (void) DUK_SNPRINTF(duk_debug_func_stash, DUK_DEBUG_STASH_SIZE, "%s", (const char *) DUK_FUNC_MACRO), \ + (void) (duk_debug_func_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0), \ + (void) (duk_debug_level_stash = (lev)) + +/* Without variadic macros resort to comma expression trickery to handle debug + * prints. This generates a lot of harmless warnings. These hacks are not + * needed normally because DUK_D() and friends will hide the entire debug log + * statement from the compiler. + */ + +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0) +#define DUK_DPRINT DUK__DEBUG_STASH(DUK_LEVEL_DEBUG), (void) duk_debug_log /* args go here in parens */ +#else +#define DUK_DPRINT 0 && /* args go here as a comma expression in parens */ +#endif + +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1) +#define DUK_DDPRINT DUK__DEBUG_STASH(DUK_LEVEL_DDEBUG), (void) duk_debug_log /* args go here in parens */ +#else +#define DUK_DDPRINT 0 && /* args */ +#endif + +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2) +#define DUK_DDDPRINT DUK__DEBUG_STASH(DUK_LEVEL_DDDEBUG), (void) duk_debug_log /* args go here in parens */ +#else +#define DUK_DDDPRINT 0 && /* args */ +#endif + +#endif /* DUK_USE_VARIADIC_MACROS */ + +#else /* DUK_USE_DEBUG */ + +/* + * Exposed debug macros: debugging disabled + */ + +#define DUK_D(x) do { } while (0) /* omit */ +#define DUK_DD(x) do { } while (0) /* omit */ +#define DUK_DDD(x) do { } while (0) /* omit */ + +#if defined(DUK_USE_VARIADIC_MACROS) + +#define DUK_DPRINT(...) +#define DUK_DDPRINT(...) +#define DUK_DDDPRINT(...) + +#else /* DUK_USE_VARIADIC_MACROS */ + +#define DUK_DPRINT 0 && /* args go here as a comma expression in parens */ +#define DUK_DDPRINT 0 && /* args */ +#define DUK_DDDPRINT 0 && /* args */ + +#endif /* DUK_USE_VARIADIC_MACROS */ + +#endif /* DUK_USE_DEBUG */ + +/* + * Structs + */ + +#if defined(DUK_USE_DEBUG) +struct duk_fixedbuffer { + duk_uint8_t *buffer; + duk_size_t length; + duk_size_t offset; + duk_bool_t truncated; +}; +#endif + +/* + * Prototypes + */ + +#if defined(DUK_USE_DEBUG) +DUK_INTERNAL_DECL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const char *format, va_list ap); +#if 0 /*unused*/ +DUK_INTERNAL_DECL duk_int_t duk_debug_snprintf(char *str, duk_size_t size, const char *format, ...); +#endif +DUK_INTERNAL_DECL void duk_debug_format_funcptr(char *buf, duk_size_t buf_size, duk_uint8_t *fptr, duk_size_t fptr_size); + +#if defined(DUK_USE_VARIADIC_MACROS) +DUK_INTERNAL_DECL void duk_debug_log(duk_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...); +#else /* DUK_USE_VARIADIC_MACROS */ +/* parameter passing, not thread safe */ +#define DUK_DEBUG_STASH_SIZE 128 +#if !defined(DUK_SINGLE_FILE) +DUK_INTERNAL_DECL char duk_debug_file_stash[DUK_DEBUG_STASH_SIZE]; +DUK_INTERNAL_DECL duk_int_t duk_debug_line_stash; +DUK_INTERNAL_DECL char duk_debug_func_stash[DUK_DEBUG_STASH_SIZE]; +DUK_INTERNAL_DECL duk_int_t duk_debug_level_stash; +#endif +DUK_INTERNAL_DECL void duk_debug_log(const char *fmt, ...); +#endif /* DUK_USE_VARIADIC_MACROS */ + +DUK_INTERNAL_DECL void duk_fb_put_bytes(duk_fixedbuffer *fb, const duk_uint8_t *buffer, duk_size_t length); +DUK_INTERNAL_DECL void duk_fb_put_byte(duk_fixedbuffer *fb, duk_uint8_t x); +DUK_INTERNAL_DECL void duk_fb_put_cstring(duk_fixedbuffer *fb, const char *x); +DUK_INTERNAL_DECL void duk_fb_sprintf(duk_fixedbuffer *fb, const char *fmt, ...); +DUK_INTERNAL_DECL void duk_fb_put_funcptr(duk_fixedbuffer *fb, duk_uint8_t *fptr, duk_size_t fptr_size); +DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb); + +#endif /* DUK_USE_DEBUG */ + +#endif /* DUK_DEBUG_H_INCLUDED */ diff --git a/third_party/duktape/duk_debug_fixedbuffer.c b/third_party/duktape/duk_debug_fixedbuffer.c new file mode 100644 index 00000000..de2036e5 --- /dev/null +++ b/third_party/duktape/duk_debug_fixedbuffer.c @@ -0,0 +1,69 @@ +/* + * Fixed buffer helper useful for debugging, requires no allocation + * which is critical for debugging. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_DEBUG) + +DUK_INTERNAL void duk_fb_put_bytes(duk_fixedbuffer *fb, const duk_uint8_t *buffer, duk_size_t length) { + duk_size_t avail; + duk_size_t copylen; + + avail = (fb->offset >= fb->length ? (duk_size_t) 0 : (duk_size_t) (fb->length - fb->offset)); + if (length > avail) { + copylen = avail; + fb->truncated = 1; + } else { + copylen = length; + } + duk_memcpy_unsafe(fb->buffer + fb->offset, buffer, copylen); + fb->offset += copylen; +} + +DUK_INTERNAL void duk_fb_put_byte(duk_fixedbuffer *fb, duk_uint8_t x) { + duk_fb_put_bytes(fb, (const duk_uint8_t *) &x, 1); +} + +DUK_INTERNAL void duk_fb_put_cstring(duk_fixedbuffer *fb, const char *x) { + duk_fb_put_bytes(fb, (const duk_uint8_t *) x, (duk_size_t) DUK_STRLEN(x)); +} + +DUK_INTERNAL void duk_fb_sprintf(duk_fixedbuffer *fb, const char *fmt, ...) { + duk_size_t avail; + va_list ap; + + va_start(ap, fmt); + avail = (fb->offset >= fb->length ? (duk_size_t) 0 : (duk_size_t) (fb->length - fb->offset)); + if (avail > 0) { + duk_int_t res = (duk_int_t) DUK_VSNPRINTF((char *) (fb->buffer + fb->offset), avail, fmt, ap); + if (res < 0) { + /* error */ + } else if ((duk_size_t) res >= avail) { + /* (maybe) truncated */ + fb->offset += avail; + if ((duk_size_t) res > avail) { + /* actual chars dropped (not just NUL term) */ + fb->truncated = 1; + } + } else { + /* normal */ + fb->offset += (duk_size_t) res; + } + } + va_end(ap); +} + +DUK_INTERNAL void duk_fb_put_funcptr(duk_fixedbuffer *fb, duk_uint8_t *fptr, duk_size_t fptr_size) { + char buf[64+1]; + duk_debug_format_funcptr(buf, sizeof(buf), fptr, fptr_size); + buf[sizeof(buf) - 1] = (char) 0; + duk_fb_put_cstring(fb, buf); +} + +DUK_INTERNAL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb) { + return (fb->offset >= fb->length); +} + +#endif /* DUK_USE_DEBUG */ diff --git a/third_party/duktape/duk_debug_macros.c b/third_party/duktape/duk_debug_macros.c new file mode 100644 index 00000000..c112a36e --- /dev/null +++ b/third_party/duktape/duk_debug_macros.c @@ -0,0 +1,85 @@ +/* + * Debugging macro calls. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_DEBUG) + +/* + * Debugging enabled + */ + + +#if !defined(DUK_USE_DEBUG_WRITE) +#error debugging enabled (DUK_USE_DEBUG) but DUK_USE_DEBUG_WRITE not defined +#endif + +#define DUK__DEBUG_BUFSIZE DUK_USE_DEBUG_BUFSIZE + +#if defined(DUK_USE_VARIADIC_MACROS) + +DUK_INTERNAL void duk_debug_log(duk_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...) { + va_list ap; + long arg_level; + const char *arg_file; + long arg_line; + const char *arg_func; + const char *arg_msg; + char buf[DUK__DEBUG_BUFSIZE]; + + va_start(ap, fmt); + + duk_memzero((void *) buf, (size_t) DUK__DEBUG_BUFSIZE); + duk_debug_vsnprintf(buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap); + + arg_level = (long) level; + arg_file = (const char *) file; + arg_line = (long) line; + arg_func = (const char *) func; + arg_msg = (const char *) buf; + DUK_USE_DEBUG_WRITE(arg_level, arg_file, arg_line, arg_func, arg_msg); + + va_end(ap); +} + +#else /* DUK_USE_VARIADIC_MACROS */ + +DUK_INTERNAL char duk_debug_file_stash[DUK_DEBUG_STASH_SIZE]; +DUK_INTERNAL duk_int_t duk_debug_line_stash; +DUK_INTERNAL char duk_debug_func_stash[DUK_DEBUG_STASH_SIZE]; +DUK_INTERNAL duk_int_t duk_debug_level_stash; + +DUK_INTERNAL void duk_debug_log(const char *fmt, ...) { + va_list ap; + long arg_level; + const char *arg_file; + long arg_line; + const char *arg_func; + const char *arg_msg; + char buf[DUK__DEBUG_BUFSIZE]; + + va_start(ap, fmt); + + duk_memzero((void *) buf, (size_t) DUK__DEBUG_BUFSIZE); + duk_debug_vsnprintf(buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap); + + arg_level = (long) duk_debug_level_stash; + arg_file = (const char *) duk_debug_file_stash; + arg_line = (long) duk_debug_line_stash; + arg_func = (const char *) duk_debug_func_stash; + arg_msg = (const char *) buf; + DUK_USE_DEBUG_WRITE(arg_level, arg_file, arg_line, arg_func, arg_msg); + + va_end(ap); +} + +#endif /* DUK_USE_VARIADIC_MACROS */ + +#else /* DUK_USE_DEBUG */ + +/* + * Debugging disabled + */ + +#endif /* DUK_USE_DEBUG */ diff --git a/third_party/duktape/duk_debug_vsnprintf.c b/third_party/duktape/duk_debug_vsnprintf.c new file mode 100644 index 00000000..63a226f2 --- /dev/null +++ b/third_party/duktape/duk_debug_vsnprintf.c @@ -0,0 +1,1090 @@ +/* + * Custom formatter for debug printing, allowing Duktape specific data + * structures (such as tagged values and heap objects) to be printed with + * a nice format string. Because debug printing should not affect execution + * state, formatting here must be independent of execution (see implications + * below) and must not allocate memory. + * + * Custom format tags begin with a '%!' to safely distinguish them from + * standard format tags. The following conversions are supported: + * + * %!T tagged value (duk_tval *) + * %!O heap object (duk_heaphdr *) + * %!I decoded bytecode instruction + * %!X bytecode instruction opcode name (arg is long) + * %!C catcher (duk_catcher *) + * %!A activation (duk_activation *) + * + * Everything is serialized in a JSON-like manner. The default depth is one + * level, internal prototype is not followed, and internal properties are not + * serialized. The following modifiers change this behavior: + * + * @ print pointers + * # print binary representations (where applicable) + * d deep traversal of own properties (not prototype) + * p follow prototype chain (useless without 'd') + * i include internal properties (other than prototype) + * x hexdump buffers + * h heavy formatting + * + * For instance, the following serializes objects recursively, but does not + * follow the prototype chain nor print internal properties: "%!dO". + * + * Notes: + * + * * Standard snprintf return value semantics seem to vary. This + * implementation returns the number of bytes it actually wrote + * (excluding the null terminator). If retval == buffer size, + * output was truncated (except for corner cases). + * + * * Output format is intentionally different from ECMAScript + * formatting requirements, as formatting here serves debugging + * of internals. + * + * * Depth checking (and updating) is done in each type printer + * separately, to allow them to call each other freely. + * + * * Some pathological structures might take ages to print (e.g. + * self recursion with 100 properties pointing to the object + * itself). To guard against these, each printer also checks + * whether the output buffer is full; if so, early exit. + * + * * Reference loops are detected using a loop stack. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_DEBUG) + + +/* list of conversion specifiers that terminate a format tag; + * this is unfortunately guesswork. + */ +#define DUK__ALLOWED_STANDARD_SPECIFIERS "diouxXeEfFgGaAcsCSpnm" + +/* maximum length of standard format tag that we support */ +#define DUK__MAX_FORMAT_TAG_LENGTH 32 + +/* heapobj recursion depth when deep printing is selected */ +#define DUK__DEEP_DEPTH_LIMIT 8 + +/* maximum recursion depth for loop detection stacks */ +#define DUK__LOOP_STACK_DEPTH 256 + +/* must match bytecode defines now; build autogenerate? */ +DUK_LOCAL const char * const duk__bc_optab[256] = { + "LDREG", "STREG", "JUMP", "LDCONST", "LDINT", "LDINTX", "LDTHIS", "LDUNDEF", + "LDNULL", "LDTRUE", "LDFALSE", "GETVAR", "BNOT", "LNOT", "UNM", "UNP", + "EQ_RR", "EQ_CR", "EQ_RC", "EQ_CC", "NEQ_RR", "NEQ_CR", "NEQ_RC", "NEQ_CC", + "SEQ_RR", "SEQ_CR", "SEQ_RC", "SEQ_CC", "SNEQ_RR", "SNEQ_CR", "SNEQ_RC", "SNEQ_CC", + + "GT_RR", "GT_CR", "GT_RC", "GT_CC", "GE_RR", "GE_CR", "GE_RC", "GE_CC", + "LT_RR", "LT_CR", "LT_RC", "LT_CC", "LE_RR", "LE_CR", "LE_RC", "LE_CC", + "IFTRUE_R", "IFTRUE_C", "IFFALSE_R", "IFFALSE_C", "ADD_RR", "ADD_CR", "ADD_RC", "ADD_CC", + "SUB_RR", "SUB_CR", "SUB_RC", "SUB_CC", "MUL_RR", "MUL_CR", "MUL_RC", "MUL_CC", + + "DIV_RR", "DIV_CR", "DIV_RC", "DIV_CC", "MOD_RR", "MOD_CR", "MOD_RC", "MOD_CC", + "EXP_RR", "EXP_CR", "EXP_RC", "EXP_CC", "BAND_RR", "BAND_CR", "BAND_RC", "BAND_CC", + "BOR_RR", "BOR_CR", "BOR_RC", "BOR_CC", "BXOR_RR", "BXOR_CR", "BXOR_RC", "BXOR_CC", + "BASL_RR", "BASL_CR", "BASL_RC", "BASL_CC", "BLSR_RR", "BLSR_CR", "BLSR_RC", "BLSR_CC", + + "BASR_RR", "BASR_CR", "BASR_RC", "BASR_CC", "INSTOF_RR", "INSTOF_CR", "INSTOF_RC", "INSTOF_CC", + "IN_RR", "IN_CR", "IN_RC", "IN_CC", "GETPROP_RR", "GETPROP_CR", "GETPROP_RC", "GETPROP_CC", + "PUTPROP_RR", "PUTPROP_CR", "PUTPROP_RC", "PUTPROP_CC", "DELPROP_RR", "DELPROP_CR", "DELPROP_RC", "DELPROP_CC", + "PREINCR", "PREDECR", "POSTINCR", "POSTDECR", "PREINCV", "PREDECV", "POSTINCV", "POSTDECV", + + "PREINCP_RR", "PREINCP_CR", "PREINCP_RC", "PREINCP_CC", "PREDECP_RR", "PREDECP_CR", "PREDECP_RC", "PREDECP_CC", + "POSTINCP_RR", "POSTINCP_CR", "POSTINCP_RC", "POSTINCP_CC", "POSTDECP_RR", "POSTDECP_CR", "POSTDECP_RC", "POSTDECP_CC", + "DECLVAR_RR", "DECLVAR_CR", "DECLVAR_RC", "DECLVAR_CC", "REGEXP_RR", "REGEXP_RC", "REGEXP_CR", "REGEXP_CC", + "CLOSURE", "TYPEOF", "TYPEOFID", "PUTVAR", "DELVAR", "RETREG", "RETUNDEF", "RETCONST", + + "RETCONSTN", "LABEL", "ENDLABEL", "BREAK", "CONTINUE", "TRYCATCH", "ENDTRY", "ENDCATCH", + "ENDFIN", "THROW", "INVLHS", "CSREG", "CSVAR_RR", "CSVAR_CR", "CSVAR_RC", "CSVAR_CC", + "CALL0", "CALL1", "CALL2", "CALL3", "CALL4", "CALL5", "CALL6", "CALL7", + "CALL8", "CALL9", "CALL10", "CALL11", "CALL12", "CALL13", "CALL14", "CALL15", + + "NEWOBJ", "NEWARR", "MPUTOBJ", "MPUTOBJI", "INITSET", "INITGET", "MPUTARR", "MPUTARRI", + "SETALEN", "INITENUM", "NEXTENUM", "NEWTARGET", "DEBUGGER", "NOP", "INVALID", "UNUSED207", + "GETPROPC_RR", "GETPROPC_CR", "GETPROPC_RC", "GETPROPC_CC", "UNUSED212", "UNUSED213", "UNUSED214", "UNUSED215", + "UNUSED216", "UNUSED217", "UNUSED218", "UNUSED219", "UNUSED220", "UNUSED221", "UNUSED222", "UNUSED223", + + "UNUSED224", "UNUSED225", "UNUSED226", "UNUSED227", "UNUSED228", "UNUSED229", "UNUSED230", "UNUSED231", + "UNUSED232", "UNUSED233", "UNUSED234", "UNUSED235", "UNUSED236", "UNUSED237", "UNUSED238", "UNUSED239", + "UNUSED240", "UNUSED241", "UNUSED242", "UNUSED243", "UNUSED244", "UNUSED245", "UNUSED246", "UNUSED247", + "UNUSED248", "UNUSED249", "UNUSED250", "UNUSED251", "UNUSED252", "UNUSED253", "UNUSED254", "UNUSED255" +}; + +typedef struct duk__dprint_state duk__dprint_state; +struct duk__dprint_state { + duk_fixedbuffer *fb; + + /* loop_stack_index could be perhaps be replaced by 'depth', but it's nice + * to not couple these two mechanisms unnecessarily. + */ + duk_hobject *loop_stack[DUK__LOOP_STACK_DEPTH]; + duk_int_t loop_stack_index; + duk_int_t loop_stack_limit; + + duk_int_t depth; + duk_int_t depth_limit; + + duk_bool_t pointer; + duk_bool_t heavy; + duk_bool_t binary; + duk_bool_t follow_proto; + duk_bool_t internal; + duk_bool_t hexdump; +}; + +/* helpers */ +DUK_LOCAL_DECL void duk__print_hstring(duk__dprint_state *st, duk_hstring *k, duk_bool_t quotes); +DUK_LOCAL_DECL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h); +DUK_LOCAL_DECL void duk__print_hbuffer(duk__dprint_state *st, duk_hbuffer *h); +DUK_LOCAL_DECL void duk__print_tval(duk__dprint_state *st, duk_tval *tv); +DUK_LOCAL_DECL void duk__print_instr(duk__dprint_state *st, duk_instr_t ins); +DUK_LOCAL_DECL void duk__print_heaphdr(duk__dprint_state *st, duk_heaphdr *h); +DUK_LOCAL_DECL void duk__print_shared_heaphdr(duk__dprint_state *st, duk_heaphdr *h); +DUK_LOCAL_DECL void duk__print_shared_heaphdr_string(duk__dprint_state *st, duk_heaphdr_string *h); + +DUK_LOCAL void duk__print_shared_heaphdr(duk__dprint_state *st, duk_heaphdr *h) { + duk_fixedbuffer *fb = st->fb; + + if (st->heavy) { + duk_fb_sprintf(fb, "(%p)", (void *) h); + } + + if (!h) { + return; + } + + if (st->binary) { + duk_size_t i; + duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET); + for (i = 0; i < (duk_size_t) sizeof(*h); i++) { + duk_fb_sprintf(fb, "%02lx", (unsigned long) ((duk_uint8_t *)h)[i]); + } + duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET); + } + +#if defined(DUK_USE_REFERENCE_COUNTING) /* currently implicitly also DUK_USE_DOUBLE_LINKED_HEAP */ + if (st->heavy) { + duk_fb_sprintf(fb, "[h_next=%p,h_prev=%p,h_refcount=%lu,h_flags=%08lx,type=%ld," + "reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]", + (void *) DUK_HEAPHDR_GET_NEXT(NULL, h), + (void *) DUK_HEAPHDR_GET_PREV(NULL, h), + (unsigned long) DUK_HEAPHDR_GET_REFCOUNT(h), + (unsigned long) DUK_HEAPHDR_GET_FLAGS(h), + (long) DUK_HEAPHDR_GET_TYPE(h), + (long) (DUK_HEAPHDR_HAS_REACHABLE(h) ? 1 : 0), + (long) (DUK_HEAPHDR_HAS_TEMPROOT(h) ? 1 : 0), + (long) (DUK_HEAPHDR_HAS_FINALIZABLE(h) ? 1 : 0), + (long) (DUK_HEAPHDR_HAS_FINALIZED(h) ? 1 : 0)); + } +#else + if (st->heavy) { + duk_fb_sprintf(fb, "[h_next=%p,h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]", + (void *) DUK_HEAPHDR_GET_NEXT(NULL, h), + (unsigned long) DUK_HEAPHDR_GET_FLAGS(h), + (long) DUK_HEAPHDR_GET_TYPE(h), + (long) (DUK_HEAPHDR_HAS_REACHABLE(h) ? 1 : 0), + (long) (DUK_HEAPHDR_HAS_TEMPROOT(h) ? 1 : 0), + (long) (DUK_HEAPHDR_HAS_FINALIZABLE(h) ? 1 : 0), + (long) (DUK_HEAPHDR_HAS_FINALIZED(h) ? 1 : 0)); + } +#endif +} + +DUK_LOCAL void duk__print_shared_heaphdr_string(duk__dprint_state *st, duk_heaphdr_string *h) { + duk_fixedbuffer *fb = st->fb; + + if (st->heavy) { + duk_fb_sprintf(fb, "(%p)", (void *) h); + } + + if (!h) { + return; + } + + if (st->binary) { + duk_size_t i; + duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET); + for (i = 0; i < (duk_size_t) sizeof(*h); i++) { + duk_fb_sprintf(fb, "%02lx", (unsigned long) ((duk_uint8_t *)h)[i]); + } + duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET); + } + +#if defined(DUK_USE_REFERENCE_COUNTING) + if (st->heavy) { + duk_fb_sprintf(fb, "[h_refcount=%lu,h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]", + (unsigned long) DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h), + (unsigned long) DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h), + (long) DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h), + (long) (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h) ? 1 : 0), + (long) (DUK_HEAPHDR_HAS_TEMPROOT((duk_heaphdr *) h) ? 1 : 0), + (long) (DUK_HEAPHDR_HAS_FINALIZABLE((duk_heaphdr *) h) ? 1 : 0), + (long) (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) h) ? 1 : 0)); + } +#else + if (st->heavy) { + duk_fb_sprintf(fb, "[h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]", + (unsigned long) DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h), + (long) DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h), + (long) (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h) ? 1 : 0), + (long) (DUK_HEAPHDR_HAS_TEMPROOT((duk_heaphdr *) h) ? 1 : 0), + (long) (DUK_HEAPHDR_HAS_FINALIZABLE((duk_heaphdr *) h) ? 1 : 0), + (long) (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) h) ? 1 : 0)); + } +#endif +} + +DUK_LOCAL void duk__print_hstring(duk__dprint_state *st, duk_hstring *h, duk_bool_t quotes) { + duk_fixedbuffer *fb = st->fb; + const duk_uint8_t *p; + const duk_uint8_t *p_end; + + /* terminal type: no depth check */ + + if (duk_fb_is_full(fb)) { + return; + } + + duk__print_shared_heaphdr_string(st, &h->hdr); + + if (!h) { + duk_fb_put_cstring(fb, "NULL"); + return; + } + + p = DUK_HSTRING_GET_DATA(h); + p_end = p + DUK_HSTRING_GET_BYTELEN(h); + + if (p_end > p && p[0] == DUK_ASC_UNDERSCORE) { + /* If property key begins with underscore, encode it with + * forced quotes (e.g. "_Foo") to distinguish it from encoded + * internal properties (e.g. \x82Bar -> _Bar). + */ + quotes = 1; + } + + if (quotes) { + duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_DOUBLEQUOTE); + } + while (p < p_end) { + duk_uint8_t ch = *p++; + + /* two special escapes: '\' and '"', other printables as is */ + if (ch == '\\') { + duk_fb_sprintf(fb, "\\\\"); + } else if (ch == '"') { + duk_fb_sprintf(fb, "\\\""); + } else if (ch >= 0x20 && ch <= 0x7e) { + duk_fb_put_byte(fb, ch); + } else if (ch == 0x82 && !quotes) { + /* encode \x82Bar as _Bar if no quotes are + * applied, this is for readable internal keys. + */ + duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_UNDERSCORE); + } else { + duk_fb_sprintf(fb, "\\x%02lx", (unsigned long) ch); + } + } + if (quotes) { + duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_DOUBLEQUOTE); + } +#if defined(DUK_USE_REFERENCE_COUNTING) + /* XXX: limit to quoted strings only, to save keys from being cluttered? */ + duk_fb_sprintf(fb, "/%lu", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT(&h->hdr)); +#endif +} + +#define DUK__COMMA() do { \ + if (first) { \ + first = 0; \ + } else { \ + duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COMMA); \ + } \ + } while (0) + +DUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) { + duk_fixedbuffer *fb = st->fb; + duk_uint_fast32_t i; + duk_tval *tv; + duk_hstring *key; + duk_bool_t first = 1; + const char *brace1 = "{"; + const char *brace2 = "}"; + duk_bool_t pushed_loopstack = 0; + + if (duk_fb_is_full(fb)) { + return; + } + + duk__print_shared_heaphdr(st, &h->hdr); + + if (h && DUK_HOBJECT_HAS_ARRAY_PART(h)) { + brace1 = "["; + brace2 = "]"; + } + + if (!h) { + duk_fb_put_cstring(fb, "NULL"); + goto finished; + } + + if (st->depth >= st->depth_limit) { + const char *subtype = "generic"; + + if (DUK_HOBJECT_IS_COMPFUNC(h)) { + subtype = "compfunc"; + } else if (DUK_HOBJECT_IS_NATFUNC(h)) { + subtype = "natfunc"; + } else if (DUK_HOBJECT_IS_THREAD(h)) { + subtype = "thread"; + } else if (DUK_HOBJECT_IS_BUFOBJ(h)) { + subtype = "bufobj"; + } else if (DUK_HOBJECT_IS_ARRAY(h)) { + subtype = "array"; + } + duk_fb_sprintf(fb, "%sobject/%s %p%s", (const char *) brace1, subtype, (void *) h, (const char *) brace2); + return; + } + + for (i = 0; i < (duk_uint_fast32_t) st->loop_stack_index; i++) { + if (st->loop_stack[i] == h) { + duk_fb_sprintf(fb, "%sLOOP:%p%s", (const char *) brace1, (void *) h, (const char *) brace2); + return; + } + } + + /* after this, return paths should 'goto finished' for decrement */ + st->depth++; + + if (st->loop_stack_index >= st->loop_stack_limit) { + duk_fb_sprintf(fb, "%sOUT-OF-LOOP-STACK%s", (const char *) brace1, (const char *) brace2); + goto finished; + } + st->loop_stack[st->loop_stack_index++] = h; + pushed_loopstack = 1; + + /* + * Notation: double underscore used for internal properties which are not + * stored in the property allocation (e.g. '__valstack'). + */ + + duk_fb_put_cstring(fb, brace1); + + if (DUK_HOBJECT_GET_PROPS(NULL, h)) { + duk_uint32_t a_limit; + + a_limit = DUK_HOBJECT_GET_ASIZE(h); + if (st->internal) { + /* dump all allocated entries, unused entries print as 'unused', + * note that these may extend beyond current 'length' and look + * a bit funny. + */ + } else { + /* leave out trailing 'unused' elements */ + while (a_limit > 0) { + tv = DUK_HOBJECT_A_GET_VALUE_PTR(NULL, h, a_limit - 1); + if (!DUK_TVAL_IS_UNUSED(tv)) { + break; + } + a_limit--; + } + } + + for (i = 0; i < a_limit; i++) { + tv = DUK_HOBJECT_A_GET_VALUE_PTR(NULL, h, i); + DUK__COMMA(); + duk__print_tval(st, tv); + } + for (i = 0; i < DUK_HOBJECT_GET_ENEXT(h); i++) { + key = DUK_HOBJECT_E_GET_KEY(NULL, h, i); + if (!key) { + continue; + } + if (!st->internal && DUK_HSTRING_HAS_HIDDEN(key)) { + continue; + } + DUK__COMMA(); + duk__print_hstring(st, key, 0); + duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COLON); + if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(NULL, h, i)) { + duk_fb_sprintf(fb, "[get:%p,set:%p]", + (void *) DUK_HOBJECT_E_GET_VALUE(NULL, h, i).a.get, + (void *) DUK_HOBJECT_E_GET_VALUE(NULL, h, i).a.set); + } else { + tv = &DUK_HOBJECT_E_GET_VALUE(NULL, h, i).v; + duk__print_tval(st, tv); + } + if (st->heavy) { + duk_fb_sprintf(fb, "<%02lx>", (unsigned long) DUK_HOBJECT_E_GET_FLAGS(NULL, h, i)); + } + } + } + if (st->internal) { + if (DUK_HOBJECT_IS_ARRAY(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__array:true"); + } + if (DUK_HOBJECT_HAS_EXTENSIBLE(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__extensible:true"); + } + if (DUK_HOBJECT_HAS_CONSTRUCTABLE(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__constructable:true"); + } + if (DUK_HOBJECT_HAS_BOUNDFUNC(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__boundfunc:true"); + } + if (DUK_HOBJECT_HAS_COMPFUNC(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__compfunc:true"); + } + if (DUK_HOBJECT_HAS_NATFUNC(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__natfunc:true"); + } + if (DUK_HOBJECT_HAS_BUFOBJ(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__bufobj:true"); + } + if (DUK_HOBJECT_IS_THREAD(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__thread:true"); + } + if (DUK_HOBJECT_HAS_ARRAY_PART(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__array_part:true"); + } + if (DUK_HOBJECT_HAS_STRICT(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__strict:true"); + } + if (DUK_HOBJECT_HAS_NOTAIL(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__notail:true"); + } + if (DUK_HOBJECT_HAS_NEWENV(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__newenv:true"); + } + if (DUK_HOBJECT_HAS_NAMEBINDING(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__namebinding:true"); + } + if (DUK_HOBJECT_HAS_CREATEARGS(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__createargs:true"); + } + if (DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__exotic_array:true"); + } + if (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__exotic_stringobj:true"); + } + if (DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__exotic_arguments:true"); + } + if (DUK_HOBJECT_IS_BUFOBJ(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__exotic_bufobj:true"); + } + if (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h)) { + DUK__COMMA(); duk_fb_sprintf(fb, "__exotic_proxyobj:true"); + } + } + + if (st->internal && DUK_HOBJECT_IS_ARRAY(h)) { + duk_harray *a = (duk_harray *) h; + DUK__COMMA(); duk_fb_sprintf(fb, "__length:%ld", (long) a->length); + DUK__COMMA(); duk_fb_sprintf(fb, "__length_nonwritable:%ld", (long) a->length_nonwritable); + } else if (st->internal && DUK_HOBJECT_IS_COMPFUNC(h)) { + duk_hcompfunc *f = (duk_hcompfunc *) h; + DUK__COMMA(); duk_fb_put_cstring(fb, "__data:"); + duk__print_hbuffer(st, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(NULL, f)); + DUK__COMMA(); duk_fb_put_cstring(fb, "__lexenv:"); duk__print_hobject(st, DUK_HCOMPFUNC_GET_LEXENV(NULL, f)); + DUK__COMMA(); duk_fb_put_cstring(fb, "__varenv:"); duk__print_hobject(st, DUK_HCOMPFUNC_GET_VARENV(NULL, f)); + DUK__COMMA(); duk_fb_sprintf(fb, "__nregs:%ld", (long) f->nregs); + DUK__COMMA(); duk_fb_sprintf(fb, "__nargs:%ld", (long) f->nargs); +#if defined(DUK_USE_DEBUGGER_SUPPORT) + DUK__COMMA(); duk_fb_sprintf(fb, "__start_line:%ld", (long) f->start_line); + DUK__COMMA(); duk_fb_sprintf(fb, "__end_line:%ld", (long) f->end_line); +#endif + DUK__COMMA(); duk_fb_put_cstring(fb, "__data:"); + duk__print_hbuffer(st, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(NULL, f)); + } else if (st->internal && DUK_HOBJECT_IS_NATFUNC(h)) { + duk_hnatfunc *f = (duk_hnatfunc *) h; + DUK__COMMA(); duk_fb_sprintf(fb, "__func:"); + duk_fb_put_funcptr(fb, (duk_uint8_t *) &f->func, sizeof(f->func)); + DUK__COMMA(); duk_fb_sprintf(fb, "__nargs:%ld", (long) f->nargs); + DUK__COMMA(); duk_fb_sprintf(fb, "__magic:%ld", (long) f->magic); + } else if (st->internal && DUK_HOBJECT_IS_DECENV(h)) { + duk_hdecenv *e = (duk_hdecenv *) h; + DUK__COMMA(); duk_fb_sprintf(fb, "__thread:"); duk__print_hobject(st, (duk_hobject *) e->thread); + DUK__COMMA(); duk_fb_sprintf(fb, "__varmap:"); duk__print_hobject(st, (duk_hobject *) e->varmap); + DUK__COMMA(); duk_fb_sprintf(fb, "__regbase_byteoff:%ld", (long) e->regbase_byteoff); + } else if (st->internal && DUK_HOBJECT_IS_OBJENV(h)) { + duk_hobjenv *e = (duk_hobjenv *) h; + DUK__COMMA(); duk_fb_sprintf(fb, "__target:"); duk__print_hobject(st, (duk_hobject *) e->target); + DUK__COMMA(); duk_fb_sprintf(fb, "__has_this:%ld", (long) e->has_this); +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + } else if (st->internal && DUK_HOBJECT_IS_BUFOBJ(h)) { + duk_hbufobj *b = (duk_hbufobj *) h; + DUK__COMMA(); duk_fb_sprintf(fb, "__buf:"); + duk__print_hbuffer(st, (duk_hbuffer *) b->buf); + DUK__COMMA(); duk_fb_sprintf(fb, "__buf_prop:"); + duk__print_hobject(st, (duk_hobject *) b->buf_prop); + DUK__COMMA(); duk_fb_sprintf(fb, "__offset:%ld", (long) b->offset); + DUK__COMMA(); duk_fb_sprintf(fb, "__length:%ld", (long) b->length); + DUK__COMMA(); duk_fb_sprintf(fb, "__shift:%ld", (long) b->shift); + DUK__COMMA(); duk_fb_sprintf(fb, "__elemtype:%ld", (long) b->elem_type); +#endif + } else if (st->internal && DUK_HOBJECT_IS_PROXY(h)) { + duk_hproxy *p = (duk_hproxy *) h; + DUK__COMMA(); duk_fb_sprintf(fb, "__target:"); + duk__print_hobject(st, p->target); + DUK__COMMA(); duk_fb_sprintf(fb, "__handler:"); + duk__print_hobject(st, p->handler); + } else if (st->internal && DUK_HOBJECT_IS_THREAD(h)) { + duk_hthread *t = (duk_hthread *) h; + DUK__COMMA(); duk_fb_sprintf(fb, "__ptr_curr_pc:%p", (void *) t->ptr_curr_pc); + DUK__COMMA(); duk_fb_sprintf(fb, "__heap:%p", (void *) t->heap); + DUK__COMMA(); duk_fb_sprintf(fb, "__strict:%ld", (long) t->strict); + DUK__COMMA(); duk_fb_sprintf(fb, "__state:%ld", (long) t->state); + DUK__COMMA(); duk_fb_sprintf(fb, "__unused1:%ld", (long) t->unused1); + DUK__COMMA(); duk_fb_sprintf(fb, "__unused2:%ld", (long) t->unused2); + DUK__COMMA(); duk_fb_sprintf(fb, "__valstack:%p", (void *) t->valstack); + DUK__COMMA(); duk_fb_sprintf(fb, "__valstack_end:%p/%ld", (void *) t->valstack_end, (long) (t->valstack_end - t->valstack)); + DUK__COMMA(); duk_fb_sprintf(fb, "__valstack_alloc_end:%p/%ld", (void *) t->valstack_alloc_end, (long) (t->valstack_alloc_end - t->valstack)); + DUK__COMMA(); duk_fb_sprintf(fb, "__valstack_bottom:%p/%ld", (void *) t->valstack_bottom, (long) (t->valstack_bottom - t->valstack)); + DUK__COMMA(); duk_fb_sprintf(fb, "__valstack_top:%p/%ld", (void *) t->valstack_top, (long) (t->valstack_top - t->valstack)); + DUK__COMMA(); duk_fb_sprintf(fb, "__callstack_curr:%p", (void *) t->callstack_curr); + DUK__COMMA(); duk_fb_sprintf(fb, "__callstack_top:%ld", (long) t->callstack_top); + DUK__COMMA(); duk_fb_sprintf(fb, "__callstack_preventcount:%ld", (long) t->callstack_preventcount); + DUK__COMMA(); duk_fb_sprintf(fb, "__resumer:"); duk__print_hobject(st, (duk_hobject *) t->resumer); + DUK__COMMA(); duk_fb_sprintf(fb, "__compile_ctx:%p", (void *) t->compile_ctx); +#if defined(DUK_USE_INTERRUPT_COUNTER) + DUK__COMMA(); duk_fb_sprintf(fb, "__interrupt_counter:%ld", (long) t->interrupt_counter); + DUK__COMMA(); duk_fb_sprintf(fb, "__interrupt_init:%ld", (long) t->interrupt_init); +#endif + + /* XXX: print built-ins array? */ + + } +#if defined(DUK_USE_REFERENCE_COUNTING) + if (st->internal) { + DUK__COMMA(); duk_fb_sprintf(fb, "__refcount:%lu", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h)); + } +#endif + if (st->internal) { + DUK__COMMA(); duk_fb_sprintf(fb, "__class:%ld", (long) DUK_HOBJECT_GET_CLASS_NUMBER(h)); + } + + DUK__COMMA(); duk_fb_sprintf(fb, "__heapptr:%p", (void *) h); /* own pointer */ + + /* prototype should be last, for readability */ + if (DUK_HOBJECT_GET_PROTOTYPE(NULL, h)) { + if (st->follow_proto) { + DUK__COMMA(); duk_fb_put_cstring(fb, "__prototype:"); duk__print_hobject(st, DUK_HOBJECT_GET_PROTOTYPE(NULL, h)); + } else { + DUK__COMMA(); duk_fb_sprintf(fb, "__prototype:%p", (void *) DUK_HOBJECT_GET_PROTOTYPE(NULL, h)); + } + } + + duk_fb_put_cstring(fb, brace2); + +#if defined(DUK_USE_HOBJECT_HASH_PART) + if (st->heavy && DUK_HOBJECT_GET_HSIZE(h) > 0) { + duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LANGLE); + for (i = 0; i < DUK_HOBJECT_GET_HSIZE(h); i++) { + duk_uint_t h_idx = DUK_HOBJECT_H_GET_INDEX(NULL, h, i); + if (i > 0) { + duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COMMA); + } + if (h_idx == DUK_HOBJECT_HASHIDX_UNUSED) { + duk_fb_sprintf(fb, "u"); + } else if (h_idx == DUK_HOBJECT_HASHIDX_DELETED) { + duk_fb_sprintf(fb, "d"); + } else { + duk_fb_sprintf(fb, "%ld", (long) h_idx); + } + } + duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RANGLE); + } +#endif + + finished: + st->depth--; + if (pushed_loopstack) { + st->loop_stack_index--; + st->loop_stack[st->loop_stack_index] = NULL; + } +} + +DUK_LOCAL void duk__print_hbuffer(duk__dprint_state *st, duk_hbuffer *h) { + duk_fixedbuffer *fb = st->fb; + duk_size_t i, n; + duk_uint8_t *p; + + if (duk_fb_is_full(fb)) { + return; + } + + /* terminal type: no depth check */ + + if (!h) { + duk_fb_put_cstring(fb, "NULL"); + return; + } + + if (DUK_HBUFFER_HAS_DYNAMIC(h)) { + if (DUK_HBUFFER_HAS_EXTERNAL(h)) { + duk_hbuffer_external *g = (duk_hbuffer_external *) h; + duk_fb_sprintf(fb, "buffer:external:%p:%ld", + (void *) DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(NULL, g), + (long) DUK_HBUFFER_EXTERNAL_GET_SIZE(g)); + } else { + duk_hbuffer_dynamic *g = (duk_hbuffer_dynamic *) h; + duk_fb_sprintf(fb, "buffer:dynamic:%p:%ld", + (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(NULL, g), + (long) DUK_HBUFFER_DYNAMIC_GET_SIZE(g)); + } + } else { + duk_fb_sprintf(fb, "buffer:fixed:%ld", (long) DUK_HBUFFER_GET_SIZE(h)); + } + +#if defined(DUK_USE_REFERENCE_COUNTING) + duk_fb_sprintf(fb, "/%lu", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT(&h->hdr)); +#endif + + if (st->hexdump) { + duk_fb_sprintf(fb, "=["); + n = DUK_HBUFFER_GET_SIZE(h); + p = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(NULL, h); + for (i = 0; i < n; i++) { + duk_fb_sprintf(fb, "%02lx", (unsigned long) p[i]); + } + duk_fb_sprintf(fb, "]"); + } +} + +DUK_LOCAL void duk__print_heaphdr(duk__dprint_state *st, duk_heaphdr *h) { + duk_fixedbuffer *fb = st->fb; + + if (duk_fb_is_full(fb)) { + return; + } + + if (!h) { + duk_fb_put_cstring(fb, "NULL"); + return; + } + + switch (DUK_HEAPHDR_GET_TYPE(h)) { + case DUK_HTYPE_STRING: + duk__print_hstring(st, (duk_hstring *) h, 1); + break; + case DUK_HTYPE_OBJECT: + duk__print_hobject(st, (duk_hobject *) h); + break; + case DUK_HTYPE_BUFFER: + duk__print_hbuffer(st, (duk_hbuffer *) h); + break; + default: + duk_fb_sprintf(fb, "[unknown htype %ld]", (long) DUK_HEAPHDR_GET_TYPE(h)); + break; + } +} + +DUK_LOCAL void duk__print_tval(duk__dprint_state *st, duk_tval *tv) { + duk_fixedbuffer *fb = st->fb; + + if (duk_fb_is_full(fb)) { + return; + } + + /* depth check is done when printing an actual type */ + + if (st->heavy) { + duk_fb_sprintf(fb, "(%p)", (void *) tv); + } + + if (!tv) { + duk_fb_put_cstring(fb, "NULL"); + return; + } + + if (st->binary) { + duk_size_t i; + duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET); + for (i = 0; i < (duk_size_t) sizeof(*tv); i++) { + duk_fb_sprintf(fb, "%02lx", (unsigned long) ((duk_uint8_t *)tv)[i]); + } + duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET); + } + + if (st->heavy) { + duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LANGLE); + } + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_UNDEFINED: { + duk_fb_put_cstring(fb, "undefined"); + break; + } + case DUK_TAG_UNUSED: { + duk_fb_put_cstring(fb, "unused"); + break; + } + case DUK_TAG_NULL: { + duk_fb_put_cstring(fb, "null"); + break; + } + case DUK_TAG_BOOLEAN: { + duk_fb_put_cstring(fb, DUK_TVAL_GET_BOOLEAN(tv) ? "true" : "false"); + break; + } + case DUK_TAG_STRING: { + /* Note: string is a terminal heap object, so no depth check here */ + duk__print_hstring(st, DUK_TVAL_GET_STRING(tv), 1); + break; + } + case DUK_TAG_OBJECT: { + duk__print_hobject(st, DUK_TVAL_GET_OBJECT(tv)); + break; + } + case DUK_TAG_BUFFER: { + duk__print_hbuffer(st, DUK_TVAL_GET_BUFFER(tv)); + break; + } + case DUK_TAG_POINTER: { + duk_fb_sprintf(fb, "pointer:%p", (void *) DUK_TVAL_GET_POINTER(tv)); + break; + } + case DUK_TAG_LIGHTFUNC: { + duk_c_function func; + duk_small_uint_t lf_flags; + + DUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags); + duk_fb_sprintf(fb, "lightfunc:"); + duk_fb_put_funcptr(fb, (duk_uint8_t *) &func, sizeof(func)); + duk_fb_sprintf(fb, ":%04lx", (long) lf_flags); + break; + } +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv)); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); + duk_fb_sprintf(fb, "%.18g_F", (double) DUK_TVAL_GET_NUMBER(tv)); + break; +#endif + default: { + /* IEEE double is approximately 16 decimal digits; print a couple extra */ + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv)); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); + duk_fb_sprintf(fb, "%.18g", (double) DUK_TVAL_GET_NUMBER(tv)); + break; + } + } + if (st->heavy) { + duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RANGLE); + } +} + +DUK_LOCAL void duk__print_instr(duk__dprint_state *st, duk_instr_t ins) { + duk_fixedbuffer *fb = st->fb; + duk_small_int_t op; + const char *op_name; + + op = (duk_small_int_t) DUK_DEC_OP(ins); + op_name = duk__bc_optab[op]; + + /* XXX: option to fix opcode length so it lines up nicely */ + + if (op == DUK_OP_JUMP) { + duk_int_t diff1 = (duk_int_t) (DUK_DEC_ABC(ins) - DUK_BC_JUMP_BIAS); /* from next pc */ + duk_int_t diff2 = diff1 + 1; /* from curr pc */ + + duk_fb_sprintf(fb, "%s %ld (to pc%c%ld)", + (const char *) op_name, (long) diff1, + (int) (diff2 >= 0 ? '+' : '-'), /* char format: use int */ + (long) (diff2 >= 0 ? diff2 : -diff2)); + } else { + duk_fb_sprintf(fb, "%s %ld, %ld, %ld", + (const char *) op_name, (long) DUK_DEC_A(ins), + (long) DUK_DEC_B(ins), (long) DUK_DEC_C(ins)); + } +} + +DUK_LOCAL void duk__print_opcode(duk__dprint_state *st, duk_small_int_t opcode) { + duk_fixedbuffer *fb = st->fb; + + if (opcode < DUK_BC_OP_MIN || opcode > DUK_BC_OP_MAX) { + duk_fb_sprintf(fb, "?(%ld)", (long) opcode); + } else { + duk_fb_sprintf(fb, "%s", (const char *) duk__bc_optab[opcode]); + } +} + +DUK_LOCAL void duk__print_catcher(duk__dprint_state *st, duk_catcher *cat) { + duk_fixedbuffer *fb = st->fb; + + if (duk_fb_is_full(fb)) { + return; + } + + if (!cat) { + duk_fb_put_cstring(fb, "NULL"); + return; + } + + duk_fb_sprintf(fb, "[catcher ptr=%p parent=%p varname=%p pc_base=%p, idx_base=%ld, flags=0x%08lx]", + (void *) cat, + (void *) cat->parent, (void *) cat->h_varname, (void *) cat->pc_base, + (long) cat->idx_base, (unsigned long) cat->flags); +} + + +DUK_LOCAL void duk__print_activation(duk__dprint_state *st, duk_activation *act) { + duk_fixedbuffer *fb = st->fb; + + if (duk_fb_is_full(fb)) { + return; + } + + if (!act) { + duk_fb_put_cstring(fb, "NULL"); + return; + } + + /* prev_caller: conditional, omitted on purpose, it's rarely used. */ + /* prev_line: conditional, omitted on purpose (but would be nice). */ + duk_fb_sprintf(fb, "[activation ptr=%p tv_func= func=%p parent=%p var_env=%p lex_env=%p cat=%p curr_pc=%p bottom_byteoff=%ld retval_byteoff=%ld reserve_byteoff=%ld flags=%ld]", + (void *) act, + (void *) act->func, (void *) act->parent, (void *) act->var_env, + (void *) act->lex_env, (void *) act->cat, (void *) act->curr_pc, + (long) act->bottom_byteoff, (long) act->retval_byteoff, (long) act->reserve_byteoff, + (long) act->flags); +} + +DUK_INTERNAL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const char *format, va_list ap) { + duk_fixedbuffer fb; + const char *p = format; + const char *p_end = p + DUK_STRLEN(format); + duk_int_t retval; + + duk_memzero(&fb, sizeof(fb)); + fb.buffer = (duk_uint8_t *) str; + fb.length = size; + fb.offset = 0; + fb.truncated = 0; + + while (p < p_end) { + char ch = *p++; + const char *p_begfmt = NULL; + duk_bool_t got_exclamation = 0; + duk_bool_t got_long = 0; /* %lf, %ld etc */ + duk__dprint_state st; + + if (ch != DUK_ASC_PERCENT) { + duk_fb_put_byte(&fb, (duk_uint8_t) ch); + continue; + } + + /* + * Format tag parsing. Since we don't understand all the + * possible format tags allowed, we just scan for a terminating + * specifier and keep track of relevant modifiers that we do + * understand. See man 3 printf. + */ + + duk_memzero(&st, sizeof(st)); + st.fb = &fb; + st.depth = 0; + st.depth_limit = 1; + st.loop_stack_index = 0; + st.loop_stack_limit = DUK__LOOP_STACK_DEPTH; + + p_begfmt = p - 1; + while (p < p_end) { + ch = *p++; + + if (ch == DUK_ASC_STAR) { + /* unsupported: would consume multiple args */ + goto format_error; + } else if (ch == DUK_ASC_PERCENT) { + duk_fb_put_byte(&fb, (duk_uint8_t) DUK_ASC_PERCENT); + break; + } else if (ch == DUK_ASC_EXCLAMATION) { + got_exclamation = 1; + } else if (!got_exclamation && ch == DUK_ASC_LC_L) { + got_long = 1; + } else if (got_exclamation && ch == DUK_ASC_LC_D) { + st.depth_limit = DUK__DEEP_DEPTH_LIMIT; + } else if (got_exclamation && ch == DUK_ASC_LC_P) { + st.follow_proto = 1; + } else if (got_exclamation && ch == DUK_ASC_LC_I) { + st.internal = 1; + } else if (got_exclamation && ch == DUK_ASC_LC_X) { + st.hexdump = 1; + } else if (got_exclamation && ch == DUK_ASC_LC_H) { + st.heavy = 1; + } else if (got_exclamation && ch == DUK_ASC_ATSIGN) { + st.pointer = 1; + } else if (got_exclamation && ch == DUK_ASC_HASH) { + st.binary = 1; + } else if (got_exclamation && ch == DUK_ASC_UC_T) { + duk_tval *t = va_arg(ap, duk_tval *); + if (st.pointer && !st.heavy) { + duk_fb_sprintf(&fb, "(%p)", (void *) t); + } + duk__print_tval(&st, t); + break; + } else if (got_exclamation && ch == DUK_ASC_UC_O) { + duk_heaphdr *t = va_arg(ap, duk_heaphdr *); + if (st.pointer && !st.heavy) { + duk_fb_sprintf(&fb, "(%p)", (void *) t); + } + duk__print_heaphdr(&st, t); + break; + } else if (got_exclamation && ch == DUK_ASC_UC_I) { + duk_instr_t t = va_arg(ap, duk_instr_t); + duk__print_instr(&st, t); + break; + } else if (got_exclamation && ch == DUK_ASC_UC_X) { + long t = va_arg(ap, long); + duk__print_opcode(&st, (duk_small_int_t) t); + break; + } else if (got_exclamation && ch == DUK_ASC_UC_C) { + duk_catcher *t = va_arg(ap, duk_catcher *); + duk__print_catcher(&st, t); + break; + } else if (got_exclamation && ch == DUK_ASC_UC_A) { + duk_activation *t = va_arg(ap, duk_activation *); + duk__print_activation(&st, t); + break; + } else if (!got_exclamation && strchr(DUK__ALLOWED_STANDARD_SPECIFIERS, (int) ch)) { + char fmtbuf[DUK__MAX_FORMAT_TAG_LENGTH]; + duk_size_t fmtlen; + + DUK_ASSERT(p >= p_begfmt); + fmtlen = (duk_size_t) (p - p_begfmt); + if (fmtlen >= sizeof(fmtbuf)) { + /* format is too large, abort */ + goto format_error; + } + duk_memzero(fmtbuf, sizeof(fmtbuf)); + duk_memcpy(fmtbuf, p_begfmt, fmtlen); + + /* assume exactly 1 arg, which is why '*' is forbidden; arg size still + * depends on type though. + */ + + if (ch == DUK_ASC_LC_F || ch == DUK_ASC_LC_G || ch == DUK_ASC_LC_E) { + /* %f and %lf both consume a 'long' */ + double arg = va_arg(ap, double); + duk_fb_sprintf(&fb, fmtbuf, arg); + } else if (ch == DUK_ASC_LC_D && got_long) { + /* %ld */ + long arg = va_arg(ap, long); + duk_fb_sprintf(&fb, fmtbuf, arg); + } else if (ch == DUK_ASC_LC_D) { + /* %d; only 16 bits are guaranteed */ + int arg = va_arg(ap, int); + duk_fb_sprintf(&fb, fmtbuf, arg); + } else if (ch == DUK_ASC_LC_U && got_long) { + /* %lu */ + unsigned long arg = va_arg(ap, unsigned long); + duk_fb_sprintf(&fb, fmtbuf, arg); + } else if (ch == DUK_ASC_LC_U) { + /* %u; only 16 bits are guaranteed */ + unsigned int arg = va_arg(ap, unsigned int); + duk_fb_sprintf(&fb, fmtbuf, arg); + } else if (ch == DUK_ASC_LC_X && got_long) { + /* %lx */ + unsigned long arg = va_arg(ap, unsigned long); + duk_fb_sprintf(&fb, fmtbuf, arg); + } else if (ch == DUK_ASC_LC_X) { + /* %x; only 16 bits are guaranteed */ + unsigned int arg = va_arg(ap, unsigned int); + duk_fb_sprintf(&fb, fmtbuf, arg); + } else if (ch == DUK_ASC_LC_S) { + /* %s */ + const char *arg = va_arg(ap, const char *); + if (arg == NULL) { + /* '%s' and NULL is not portable, so special case + * it for debug printing. + */ + duk_fb_sprintf(&fb, "NULL"); + } else { + duk_fb_sprintf(&fb, fmtbuf, arg); + } + } else if (ch == DUK_ASC_LC_P) { + /* %p */ + void *arg = va_arg(ap, void *); + if (arg == NULL) { + /* '%p' and NULL is portable, but special case it + * anyway to get a standard NULL marker in logs. + */ + duk_fb_sprintf(&fb, "NULL"); + } else { + duk_fb_sprintf(&fb, fmtbuf, arg); + } + } else if (ch == DUK_ASC_LC_C) { + /* '%c', passed concretely as int */ + int arg = va_arg(ap, int); + duk_fb_sprintf(&fb, fmtbuf, arg); + } else { + /* Should not happen. */ + duk_fb_sprintf(&fb, "INVALID-FORMAT(%s)", (const char *) fmtbuf); + } + break; + } else { + /* ignore */ + } + } + } + goto done; + + format_error: + duk_fb_put_cstring(&fb, "FMTERR"); + /* fall through */ + + done: + retval = (duk_int_t) fb.offset; + duk_fb_put_byte(&fb, (duk_uint8_t) 0); + + /* return total chars written excluding terminator */ + return retval; +} + +#if 0 /*unused*/ +DUK_INTERNAL duk_int_t duk_debug_snprintf(char *str, duk_size_t size, const char *format, ...) { + duk_int_t retval; + va_list ap; + va_start(ap, format); + retval = duk_debug_vsnprintf(str, size, format, ap); + va_end(ap); + return retval; +} +#endif + +/* Formatting function pointers is tricky: there is no standard pointer for + * function pointers and the size of a function pointer may depend on the + * specific pointer type. This helper formats a function pointer based on + * its memory layout to get something useful on most platforms. + */ +DUK_INTERNAL void duk_debug_format_funcptr(char *buf, duk_size_t buf_size, duk_uint8_t *fptr, duk_size_t fptr_size) { + duk_size_t i; + duk_uint8_t *p = (duk_uint8_t *) buf; + duk_uint8_t *p_end = (duk_uint8_t *) (buf + buf_size - 1); + + DUK_ASSERT(buf != NULL); + duk_memzero(buf, buf_size); + + for (i = 0; i < fptr_size; i++) { + duk_int_t left = (duk_int_t) (p_end - p); + duk_uint8_t ch; + if (left <= 0) { + break; + } + + /* Quite approximate but should be useful for little and big endian. */ +#if defined(DUK_USE_INTEGER_BE) + ch = fptr[i]; +#else + ch = fptr[fptr_size - 1 - i]; +#endif + p += DUK_SNPRINTF((char *) p, (duk_size_t) left, "%02lx", (unsigned long) ch); + } +} + +#endif /* DUK_USE_DEBUG */ diff --git a/third_party/duktape/duk_debugger.c b/third_party/duktape/duk_debugger.c new file mode 100644 index 00000000..5a594820 --- /dev/null +++ b/third_party/duktape/duk_debugger.c @@ -0,0 +1,2909 @@ +/* + * Duktape debugger + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_DEBUGGER_SUPPORT) + +/* + * Assert helpers + */ + +#if defined(DUK_USE_ASSERTIONS) +#define DUK__DBG_TPORT_ENTER() do { \ + DUK_ASSERT(heap->dbg_calling_transport == 0); \ + heap->dbg_calling_transport = 1; \ + } while (0) +#define DUK__DBG_TPORT_EXIT() do { \ + DUK_ASSERT(heap->dbg_calling_transport == 1); \ + heap->dbg_calling_transport = 0; \ + } while (0) +#else +#define DUK__DBG_TPORT_ENTER() do {} while (0) +#define DUK__DBG_TPORT_EXIT() do {} while (0) +#endif + +/* + * Helper structs + */ + +typedef union { + void *p; + duk_uint_t b[1]; + /* Use b[] to access the size of the union, which is strictly not + * correct. Can't use fixed size unless there's feature detection + * for pointer byte size. + */ +} duk__ptr_union; + +/* + * Detach handling + */ + +#define DUK__SET_CONN_BROKEN(thr,reason) do { \ + /* For now shared handler is fine. */ \ + duk__debug_do_detach1((thr)->heap, (reason)); \ + } while (0) + +DUK_LOCAL void duk__debug_do_detach1(duk_heap *heap, duk_int_t reason) { + /* Can be called multiple times with no harm. Mark the transport + * bad (dbg_read_cb == NULL) and clear state except for the detached + * callback and the udata field. The detached callback is delayed + * to the message loop so that it can be called between messages; + * this avoids corner cases related to immediate debugger reattach + * inside the detached callback. + */ + + if (heap->dbg_detaching) { + DUK_D(DUK_DPRINT("debugger already detaching, ignore detach1")); + return; + } + + DUK_D(DUK_DPRINT("debugger transport detaching, marking transport broken")); + + heap->dbg_detaching = 1; /* prevent multiple in-progress detaches */ + + if (heap->dbg_write_cb != NULL) { + duk_hthread *thr; + + thr = heap->heap_thread; + DUK_ASSERT(thr != NULL); + + duk_debug_write_notify(thr, DUK_DBG_CMD_DETACHING); + duk_debug_write_int(thr, reason); + duk_debug_write_eom(thr); + } + + heap->dbg_read_cb = NULL; + heap->dbg_write_cb = NULL; + heap->dbg_peek_cb = NULL; + heap->dbg_read_flush_cb = NULL; + heap->dbg_write_flush_cb = NULL; + heap->dbg_request_cb = NULL; + /* heap->dbg_detached_cb: keep */ + /* heap->dbg_udata: keep */ + /* heap->dbg_processing: keep on purpose to avoid debugger re-entry in detaching state */ + heap->dbg_state_dirty = 0; + heap->dbg_force_restart = 0; + heap->dbg_pause_flags = 0; + heap->dbg_pause_act = NULL; + heap->dbg_pause_startline = 0; + heap->dbg_have_next_byte = 0; + duk_debug_clear_paused(heap); /* XXX: some overlap with field inits above */ + heap->dbg_state_dirty = 0; /* XXX: clear_paused sets dirty; rework? */ + + /* Ensure there are no stale active breakpoint pointers. + * Breakpoint list is currently kept - we could empty it + * here but we'd need to handle refcounts correctly, and + * we'd need a 'thr' reference for that. + * + * XXX: clear breakpoint on either attach or detach? + */ + heap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL; +} + +DUK_LOCAL void duk__debug_do_detach2(duk_heap *heap) { + duk_debug_detached_function detached_cb; + void *detached_udata; + duk_hthread *thr; + + thr = heap->heap_thread; + if (thr == NULL) { + DUK_ASSERT(heap->dbg_detached_cb == NULL); + return; + } + + /* Safe to call multiple times. */ + + detached_cb = heap->dbg_detached_cb; + detached_udata = heap->dbg_udata; + heap->dbg_detached_cb = NULL; + heap->dbg_udata = NULL; + + if (detached_cb) { + /* Careful here: state must be wiped before the call + * so that we can cleanly handle a re-attach from + * inside the callback. + */ + DUK_D(DUK_DPRINT("detached during message loop, delayed call to detached_cb")); + detached_cb(thr, detached_udata); + } + + heap->dbg_detaching = 0; +} + +DUK_INTERNAL void duk_debug_do_detach(duk_heap *heap) { + duk__debug_do_detach1(heap, 0); + duk__debug_do_detach2(heap); +} + +/* Called on a read/write error: NULL all callbacks except the detached + * callback so that we never accidentally call them after a read/write + * error has been indicated. This is especially important for the transport + * I/O callbacks to fulfill guaranteed callback semantics. + */ +DUK_LOCAL void duk__debug_null_most_callbacks(duk_hthread *thr) { + duk_heap *heap; + + DUK_ASSERT(thr != NULL); + + heap = thr->heap; + DUK_D(DUK_DPRINT("transport read/write error, NULL all callbacks expected detached")); + heap->dbg_read_cb = NULL; + heap->dbg_write_cb = NULL; /* this is especially critical to avoid another write call in detach1() */ + heap->dbg_peek_cb = NULL; + heap->dbg_read_flush_cb = NULL; + heap->dbg_write_flush_cb = NULL; + heap->dbg_request_cb = NULL; + /* keep heap->dbg_detached_cb */ +} + +/* + * Pause handling + */ + +DUK_LOCAL void duk__debug_set_pause_state(duk_hthread *thr, duk_heap *heap, duk_small_uint_t pause_flags) { + duk_uint_fast32_t line; + + line = duk_debug_curr_line(thr); + if (line == 0) { + /* No line info for current function. */ + duk_small_uint_t updated_flags; + + updated_flags = pause_flags & ~(DUK_PAUSE_FLAG_LINE_CHANGE); + DUK_D(DUK_DPRINT("no line info for current activation, disable line-based pause flags: 0x%08lx -> 0x%08lx", + (long) pause_flags, (long) updated_flags)); + pause_flags = updated_flags; + } + + heap->dbg_pause_flags = pause_flags; + heap->dbg_pause_act = thr->callstack_curr; + heap->dbg_pause_startline = (duk_uint32_t) line; + heap->dbg_state_dirty = 1; + + DUK_D(DUK_DPRINT("set state for automatic pause triggers, flags=0x%08lx, act=%p, startline=%ld", + (long) heap->dbg_pause_flags, (void *) heap->dbg_pause_act, + (long) heap->dbg_pause_startline)); +} + +/* + * Debug connection peek and flush primitives + */ + +DUK_INTERNAL duk_bool_t duk_debug_read_peek(duk_hthread *thr) { + duk_heap *heap; + duk_bool_t ret; + + DUK_ASSERT(thr != NULL); + heap = thr->heap; + DUK_ASSERT(heap != NULL); + + if (heap->dbg_read_cb == NULL) { + DUK_D(DUK_DPRINT("attempt to peek in detached state, return zero (= no data)")); + return 0; + } + if (heap->dbg_peek_cb == NULL) { + DUK_DD(DUK_DDPRINT("no peek callback, return zero (= no data)")); + return 0; + } + + DUK__DBG_TPORT_ENTER(); + ret = (duk_bool_t) (heap->dbg_peek_cb(heap->dbg_udata) > 0); + DUK__DBG_TPORT_EXIT(); + return ret; +} + +DUK_INTERNAL void duk_debug_read_flush(duk_hthread *thr) { + duk_heap *heap; + + DUK_ASSERT(thr != NULL); + heap = thr->heap; + DUK_ASSERT(heap != NULL); + + if (heap->dbg_read_cb == NULL) { + DUK_D(DUK_DPRINT("attempt to read flush in detached state, ignore")); + return; + } + if (heap->dbg_read_flush_cb == NULL) { + DUK_DD(DUK_DDPRINT("no read flush callback, ignore")); + return; + } + + DUK__DBG_TPORT_ENTER(); + heap->dbg_read_flush_cb(heap->dbg_udata); + DUK__DBG_TPORT_EXIT(); +} + +DUK_INTERNAL void duk_debug_write_flush(duk_hthread *thr) { + duk_heap *heap; + + DUK_ASSERT(thr != NULL); + heap = thr->heap; + DUK_ASSERT(heap != NULL); + + if (heap->dbg_read_cb == NULL) { + DUK_D(DUK_DPRINT("attempt to write flush in detached state, ignore")); + return; + } + if (heap->dbg_write_flush_cb == NULL) { + DUK_DD(DUK_DDPRINT("no write flush callback, ignore")); + return; + } + + DUK__DBG_TPORT_ENTER(); + heap->dbg_write_flush_cb(heap->dbg_udata); + DUK__DBG_TPORT_EXIT(); +} + +/* + * Debug connection skip primitives + */ + +/* Skip fully. */ +DUK_INTERNAL void duk_debug_skip_bytes(duk_hthread *thr, duk_size_t length) { + duk_uint8_t dummy[64]; + duk_size_t now; + + DUK_ASSERT(thr != NULL); + + while (length > 0) { + now = (length > sizeof(dummy) ? sizeof(dummy) : length); + duk_debug_read_bytes(thr, dummy, now); + length -= now; + } +} + +DUK_INTERNAL void duk_debug_skip_byte(duk_hthread *thr) { + DUK_ASSERT(thr != NULL); + + (void) duk_debug_read_byte(thr); +} + +/* + * Debug connection read primitives + */ + +/* Peek ahead in the stream one byte. */ +DUK_INTERNAL uint8_t duk_debug_peek_byte(duk_hthread *thr) { + /* It is important not to call this if the last byte read was an EOM. + * Reading ahead in this scenario would cause unnecessary blocking if + * another message is not available. + */ + + duk_uint8_t x; + + x = duk_debug_read_byte(thr); + thr->heap->dbg_have_next_byte = 1; + thr->heap->dbg_next_byte = x; + return x; +} + +/* Read fully. */ +DUK_INTERNAL void duk_debug_read_bytes(duk_hthread *thr, duk_uint8_t *data, duk_size_t length) { + duk_heap *heap; + duk_uint8_t *p; + duk_size_t left; + duk_size_t got; + + DUK_ASSERT(thr != NULL); + heap = thr->heap; + DUK_ASSERT(heap != NULL); + DUK_ASSERT(data != NULL); + + if (heap->dbg_read_cb == NULL) { + DUK_D(DUK_DPRINT("attempt to read %ld bytes in detached state, return zero data", (long) length)); + goto fail; + } + + /* NOTE: length may be zero */ + p = data; + if (length >= 1 && heap->dbg_have_next_byte) { + heap->dbg_have_next_byte = 0; + *p++ = heap->dbg_next_byte; + } + for (;;) { + left = (duk_size_t) ((data + length) - p); + if (left == 0) { + break; + } + DUK_ASSERT(heap->dbg_read_cb != NULL); + DUK_ASSERT(left >= 1); +#if defined(DUK_USE_DEBUGGER_TRANSPORT_TORTURE) + left = 1; +#endif + DUK__DBG_TPORT_ENTER(); + got = heap->dbg_read_cb(heap->dbg_udata, (char *) p, left); + DUK__DBG_TPORT_EXIT(); + + if (got == 0 || got > left) { + DUK_D(DUK_DPRINT("connection error during read, return zero data")); + duk__debug_null_most_callbacks(thr); /* avoid calling write callback in detach1() */ + DUK__SET_CONN_BROKEN(thr, 1); + goto fail; + } + p += got; + } + return; + + fail: + duk_memzero((void *) data, (size_t) length); +} + +DUK_INTERNAL duk_uint8_t duk_debug_read_byte(duk_hthread *thr) { + duk_uint8_t x; + + x = 0; /* just in case callback is broken and won't write 'x' */ + duk_debug_read_bytes(thr, &x, 1); + return x; +} + +DUK_LOCAL duk_uint32_t duk__debug_read_uint32_raw(duk_hthread *thr) { + duk_uint8_t buf[4]; + + DUK_ASSERT(thr != NULL); + + duk_debug_read_bytes(thr, buf, 4); + return ((duk_uint32_t) buf[0] << 24) | + ((duk_uint32_t) buf[1] << 16) | + ((duk_uint32_t) buf[2] << 8) | + (duk_uint32_t) buf[3]; +} + +DUK_LOCAL duk_int32_t duk__debug_read_int32_raw(duk_hthread *thr) { + return (duk_int32_t) duk__debug_read_uint32_raw(thr); +} + +DUK_LOCAL duk_uint16_t duk__debug_read_uint16_raw(duk_hthread *thr) { + duk_uint8_t buf[2]; + + DUK_ASSERT(thr != NULL); + + duk_debug_read_bytes(thr, buf, 2); + return ((duk_uint16_t) buf[0] << 8) | + (duk_uint16_t) buf[1]; +} + +DUK_INTERNAL duk_int32_t duk_debug_read_int(duk_hthread *thr) { + duk_small_uint_t x; + duk_small_uint_t t; + + DUK_ASSERT(thr != NULL); + + x = duk_debug_read_byte(thr); + if (x >= 0xc0) { + t = duk_debug_read_byte(thr); + return (duk_int32_t) (((x - 0xc0) << 8) + t); + } else if (x >= 0x80) { + return (duk_int32_t) (x - 0x80); + } else if (x == DUK_DBG_IB_INT4) { + return (duk_int32_t) duk__debug_read_uint32_raw(thr); + } + + DUK_D(DUK_DPRINT("debug connection error: failed to decode int")); + DUK__SET_CONN_BROKEN(thr, 1); + return 0; +} + +DUK_LOCAL duk_hstring *duk__debug_read_hstring_raw(duk_hthread *thr, duk_uint32_t len) { + duk_uint8_t buf[31]; + duk_uint8_t *p; + + if (len <= sizeof(buf)) { + duk_debug_read_bytes(thr, buf, (duk_size_t) len); + duk_push_lstring(thr, (const char *) buf, (duk_size_t) len); + } else { + p = (duk_uint8_t *) duk_push_fixed_buffer(thr, (duk_size_t) len); /* zero for paranoia */ + DUK_ASSERT(p != NULL); + duk_debug_read_bytes(thr, p, (duk_size_t) len); + (void) duk_buffer_to_string(thr, -1); /* Safety relies on debug client, which is OK. */ + } + + return duk_require_hstring(thr, -1); +} + +DUK_INTERNAL duk_hstring *duk_debug_read_hstring(duk_hthread *thr) { + duk_small_uint_t x; + duk_uint32_t len; + + DUK_ASSERT(thr != NULL); + + x = duk_debug_read_byte(thr); + if (x >= 0x60 && x <= 0x7f) { + /* For short strings, use a fixed temp buffer. */ + len = (duk_uint32_t) (x - 0x60); + } else if (x == DUK_DBG_IB_STR2) { + len = (duk_uint32_t) duk__debug_read_uint16_raw(thr); + } else if (x == DUK_DBG_IB_STR4) { + len = (duk_uint32_t) duk__debug_read_uint32_raw(thr); + } else { + goto fail; + } + + return duk__debug_read_hstring_raw(thr, len); + + fail: + DUK_D(DUK_DPRINT("debug connection error: failed to decode int")); + DUK__SET_CONN_BROKEN(thr, 1); + duk_push_hstring_empty(thr); /* always push some string */ + return duk_require_hstring(thr, -1); +} + +DUK_LOCAL duk_hbuffer *duk__debug_read_hbuffer_raw(duk_hthread *thr, duk_uint32_t len) { + duk_uint8_t *p; + + p = (duk_uint8_t *) duk_push_fixed_buffer(thr, (duk_size_t) len); /* zero for paranoia */ + DUK_ASSERT(p != NULL); + duk_debug_read_bytes(thr, p, (duk_size_t) len); + + return duk_require_hbuffer(thr, -1); +} + +DUK_LOCAL void *duk__debug_read_pointer_raw(duk_hthread *thr) { + duk_small_uint_t x; + duk__ptr_union pu; + + DUK_ASSERT(thr != NULL); + + x = duk_debug_read_byte(thr); + if (x != sizeof(pu)) { + goto fail; + } + duk_debug_read_bytes(thr, (duk_uint8_t *) &pu.p, sizeof(pu)); +#if defined(DUK_USE_INTEGER_LE) + duk_byteswap_bytes((duk_uint8_t *) pu.b, sizeof(pu)); +#endif + return (void *) pu.p; + + fail: + DUK_D(DUK_DPRINT("debug connection error: failed to decode pointer")); + DUK__SET_CONN_BROKEN(thr, 1); + return (void *) NULL; +} + +DUK_LOCAL duk_double_t duk__debug_read_double_raw(duk_hthread *thr) { + duk_double_union du; + + DUK_ASSERT(sizeof(du.uc) == 8); + duk_debug_read_bytes(thr, (duk_uint8_t *) du.uc, sizeof(du.uc)); + DUK_DBLUNION_DOUBLE_NTOH(&du); + return du.d; +} + +#if 0 +DUK_INTERNAL duk_heaphdr *duk_debug_read_heapptr(duk_hthread *thr) { + duk_small_uint_t x; + + DUK_ASSERT(thr != NULL); + + x = duk_debug_read_byte(thr); + if (x != DUK_DBG_IB_HEAPPTR) { + goto fail; + } + + return (duk_heaphdr *) duk__debug_read_pointer_raw(thr); + + fail: + DUK_D(DUK_DPRINT("debug connection error: failed to decode heapptr")); + DUK__SET_CONN_BROKEN(thr, 1); + return NULL; +} +#endif + +DUK_INTERNAL duk_heaphdr *duk_debug_read_any_ptr(duk_hthread *thr) { + duk_small_uint_t x; + + DUK_ASSERT(thr != NULL); + + x = duk_debug_read_byte(thr); + switch (x) { + case DUK_DBG_IB_OBJECT: + case DUK_DBG_IB_POINTER: + case DUK_DBG_IB_HEAPPTR: + /* Accept any pointer-like value; for 'object' dvalue, read + * and ignore the class number. + */ + if (x == DUK_DBG_IB_OBJECT) { + duk_debug_skip_byte(thr); + } + break; + default: + goto fail; + } + + return (duk_heaphdr *) duk__debug_read_pointer_raw(thr); + + fail: + DUK_D(DUK_DPRINT("debug connection error: failed to decode any pointer (object, pointer, heapptr)")); + DUK__SET_CONN_BROKEN(thr, 1); + return NULL; +} + +DUK_INTERNAL duk_tval *duk_debug_read_tval(duk_hthread *thr) { + duk_uint8_t x; + duk_uint_t t; + duk_uint32_t len; + + DUK_ASSERT(thr != NULL); + + x = duk_debug_read_byte(thr); + + if (x >= 0xc0) { + t = (duk_uint_t) (x - 0xc0); + t = (t << 8) + duk_debug_read_byte(thr); + duk_push_uint(thr, (duk_uint_t) t); + goto return_ptr; + } + if (x >= 0x80) { + duk_push_uint(thr, (duk_uint_t) (x - 0x80)); + goto return_ptr; + } + if (x >= 0x60) { + len = (duk_uint32_t) (x - 0x60); + duk__debug_read_hstring_raw(thr, len); + goto return_ptr; + } + + switch (x) { + case DUK_DBG_IB_INT4: { + duk_int32_t i = duk__debug_read_int32_raw(thr); + duk_push_i32(thr, i); + break; + } + case DUK_DBG_IB_STR4: { + len = duk__debug_read_uint32_raw(thr); + duk__debug_read_hstring_raw(thr, len); + break; + } + case DUK_DBG_IB_STR2: { + len = duk__debug_read_uint16_raw(thr); + duk__debug_read_hstring_raw(thr, len); + break; + } + case DUK_DBG_IB_BUF4: { + len = duk__debug_read_uint32_raw(thr); + duk__debug_read_hbuffer_raw(thr, len); + break; + } + case DUK_DBG_IB_BUF2: { + len = duk__debug_read_uint16_raw(thr); + duk__debug_read_hbuffer_raw(thr, len); + break; + } + case DUK_DBG_IB_UNDEFINED: { + duk_push_undefined(thr); + break; + } + case DUK_DBG_IB_NULL: { + duk_push_null(thr); + break; + } + case DUK_DBG_IB_TRUE: { + duk_push_true(thr); + break; + } + case DUK_DBG_IB_FALSE: { + duk_push_false(thr); + break; + } + case DUK_DBG_IB_NUMBER: { + duk_double_t d; + d = duk__debug_read_double_raw(thr); + duk_push_number(thr, d); + break; + } + case DUK_DBG_IB_OBJECT: { + duk_heaphdr *h; + duk_debug_skip_byte(thr); + h = (duk_heaphdr *) duk__debug_read_pointer_raw(thr); + duk_push_heapptr(thr, (void *) h); + break; + } + case DUK_DBG_IB_POINTER: { + void *ptr; + ptr = duk__debug_read_pointer_raw(thr); + duk_push_pointer(thr, ptr); + break; + } + case DUK_DBG_IB_LIGHTFUNC: { + /* XXX: Not needed for now, so not implemented. Note that + * function pointers may have different size/layout than + * a void pointer. + */ + DUK_D(DUK_DPRINT("reading lightfunc values unimplemented")); + goto fail; + } + case DUK_DBG_IB_HEAPPTR: { + duk_heaphdr *h; + h = (duk_heaphdr *) duk__debug_read_pointer_raw(thr); + duk_push_heapptr(thr, (void *) h); + break; + } + case DUK_DBG_IB_UNUSED: /* unused: not accepted in inbound messages */ + default: + goto fail; + } + + return_ptr: + return DUK_GET_TVAL_NEGIDX(thr, -1); + + fail: + DUK_D(DUK_DPRINT("debug connection error: failed to decode tval")); + DUK__SET_CONN_BROKEN(thr, 1); + return NULL; +} + +/* + * Debug connection write primitives + */ + +/* Write fully. */ +DUK_INTERNAL void duk_debug_write_bytes(duk_hthread *thr, const duk_uint8_t *data, duk_size_t length) { + duk_heap *heap; + const duk_uint8_t *p; + duk_size_t left; + duk_size_t got; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(length == 0 || data != NULL); + heap = thr->heap; + DUK_ASSERT(heap != NULL); + + if (heap->dbg_write_cb == NULL) { + DUK_D(DUK_DPRINT("attempt to write %ld bytes in detached state, ignore", (long) length)); + return; + } + if (length == 0) { + /* Avoid doing an actual write callback with length == 0, + * because that's reserved for a write flush. + */ + return; + } + DUK_ASSERT(data != NULL); + + p = data; + for (;;) { + left = (duk_size_t) ((data + length) - p); + if (left == 0) { + break; + } + DUK_ASSERT(heap->dbg_write_cb != NULL); + DUK_ASSERT(left >= 1); +#if defined(DUK_USE_DEBUGGER_TRANSPORT_TORTURE) + left = 1; +#endif + DUK__DBG_TPORT_ENTER(); + got = heap->dbg_write_cb(heap->dbg_udata, (const char *) p, left); + DUK__DBG_TPORT_EXIT(); + + if (got == 0 || got > left) { + duk__debug_null_most_callbacks(thr); /* avoid calling write callback in detach1() */ + DUK_D(DUK_DPRINT("connection error during write")); + DUK__SET_CONN_BROKEN(thr, 1); + return; + } + p += got; + } +} + +DUK_INTERNAL void duk_debug_write_byte(duk_hthread *thr, duk_uint8_t x) { + duk_debug_write_bytes(thr, (const duk_uint8_t *) &x, 1); +} + +DUK_INTERNAL void duk_debug_write_unused(duk_hthread *thr) { + duk_debug_write_byte(thr, DUK_DBG_IB_UNUSED); +} + +DUK_INTERNAL void duk_debug_write_undefined(duk_hthread *thr) { + duk_debug_write_byte(thr, DUK_DBG_IB_UNDEFINED); +} + +#if defined(DUK_USE_DEBUGGER_INSPECT) +DUK_INTERNAL void duk_debug_write_null(duk_hthread *thr) { + duk_debug_write_byte(thr, DUK_DBG_IB_NULL); +} +#endif + +DUK_INTERNAL void duk_debug_write_boolean(duk_hthread *thr, duk_uint_t val) { + duk_debug_write_byte(thr, val ? DUK_DBG_IB_TRUE : DUK_DBG_IB_FALSE); +} + +/* Write signed 32-bit integer. */ +DUK_INTERNAL void duk_debug_write_int(duk_hthread *thr, duk_int32_t x) { + duk_uint8_t buf[5]; + duk_size_t len; + + DUK_ASSERT(thr != NULL); + + if (x >= 0 && x <= 0x3fL) { + buf[0] = (duk_uint8_t) (0x80 + x); + len = 1; + } else if (x >= 0 && x <= 0x3fffL) { + buf[0] = (duk_uint8_t) (0xc0 + (x >> 8)); + buf[1] = (duk_uint8_t) (x & 0xff); + len = 2; + } else { + /* Signed integers always map to 4 bytes now. */ + buf[0] = (duk_uint8_t) DUK_DBG_IB_INT4; + buf[1] = (duk_uint8_t) ((x >> 24) & 0xff); + buf[2] = (duk_uint8_t) ((x >> 16) & 0xff); + buf[3] = (duk_uint8_t) ((x >> 8) & 0xff); + buf[4] = (duk_uint8_t) (x & 0xff); + len = 5; + } + duk_debug_write_bytes(thr, buf, len); +} + +/* Write unsigned 32-bit integer. */ +DUK_INTERNAL void duk_debug_write_uint(duk_hthread *thr, duk_uint32_t x) { + /* The debugger protocol doesn't support a plain integer encoding for + * the full 32-bit unsigned range (only 32-bit signed). For now, + * unsigned 32-bit values simply written as signed ones. This is not + * a concrete issue except for 32-bit heaphdr fields. Proper solutions + * would be to (a) write such integers as IEEE doubles or (b) add an + * unsigned 32-bit dvalue. + */ + if (x >= 0x80000000UL) { + DUK_D(DUK_DPRINT("writing unsigned integer 0x%08lx as signed integer", + (long) x)); + } + duk_debug_write_int(thr, (duk_int32_t) x); +} + +DUK_INTERNAL void duk_debug_write_strbuf(duk_hthread *thr, const char *data, duk_size_t length, duk_uint8_t marker_base) { + duk_uint8_t buf[5]; + duk_size_t buflen; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(length == 0 || data != NULL); + + if (length <= 0x1fUL && marker_base == DUK_DBG_IB_STR4) { + /* For strings, special form for short lengths. */ + buf[0] = (duk_uint8_t) (0x60 + length); + buflen = 1; + } else if (length <= 0xffffUL) { + buf[0] = (duk_uint8_t) (marker_base + 1); + buf[1] = (duk_uint8_t) (length >> 8); + buf[2] = (duk_uint8_t) (length & 0xff); + buflen = 3; + } else { + buf[0] = (duk_uint8_t) marker_base; + buf[1] = (duk_uint8_t) (length >> 24); + buf[2] = (duk_uint8_t) ((length >> 16) & 0xff); + buf[3] = (duk_uint8_t) ((length >> 8) & 0xff); + buf[4] = (duk_uint8_t) (length & 0xff); + buflen = 5; + } + + duk_debug_write_bytes(thr, (const duk_uint8_t *) buf, buflen); + duk_debug_write_bytes(thr, (const duk_uint8_t *) data, length); +} + +DUK_INTERNAL void duk_debug_write_string(duk_hthread *thr, const char *data, duk_size_t length) { + duk_debug_write_strbuf(thr, data, length, DUK_DBG_IB_STR4); +} + +DUK_INTERNAL void duk_debug_write_cstring(duk_hthread *thr, const char *data) { + DUK_ASSERT(thr != NULL); + + duk_debug_write_string(thr, + data, + data ? DUK_STRLEN(data) : 0); +} + +DUK_INTERNAL void duk_debug_write_hstring(duk_hthread *thr, duk_hstring *h) { + DUK_ASSERT(thr != NULL); + + /* XXX: differentiate null pointer from empty string? */ + duk_debug_write_string(thr, + (h != NULL ? (const char *) DUK_HSTRING_GET_DATA(h) : NULL), + (h != NULL ? (duk_size_t) DUK_HSTRING_GET_BYTELEN(h) : 0)); +} + +DUK_LOCAL void duk__debug_write_hstring_safe_top(duk_hthread *thr) { + duk_debug_write_hstring(thr, duk_safe_to_hstring(thr, -1)); +} + +DUK_INTERNAL void duk_debug_write_buffer(duk_hthread *thr, const char *data, duk_size_t length) { + duk_debug_write_strbuf(thr, data, length, DUK_DBG_IB_BUF4); +} + +DUK_INTERNAL void duk_debug_write_hbuffer(duk_hthread *thr, duk_hbuffer *h) { + DUK_ASSERT(thr != NULL); + + duk_debug_write_buffer(thr, + (h != NULL ? (const char *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h) : NULL), + (h != NULL ? (duk_size_t) DUK_HBUFFER_GET_SIZE(h) : 0)); +} + +DUK_LOCAL void duk__debug_write_pointer_raw(duk_hthread *thr, void *ptr, duk_uint8_t ibyte) { + duk_uint8_t buf[2]; + duk__ptr_union pu; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(sizeof(ptr) >= 1 && sizeof(ptr) <= 16); + /* ptr may be NULL */ + + buf[0] = ibyte; + buf[1] = sizeof(pu); + duk_debug_write_bytes(thr, buf, 2); + pu.p = (void *) ptr; +#if defined(DUK_USE_INTEGER_LE) + duk_byteswap_bytes((duk_uint8_t *) pu.b, sizeof(pu)); +#endif + duk_debug_write_bytes(thr, (const duk_uint8_t *) &pu.p, (duk_size_t) sizeof(pu)); +} + +DUK_INTERNAL void duk_debug_write_pointer(duk_hthread *thr, void *ptr) { + duk__debug_write_pointer_raw(thr, ptr, DUK_DBG_IB_POINTER); +} + +#if defined(DUK_USE_DEBUGGER_DUMPHEAP) || defined(DUK_USE_DEBUGGER_INSPECT) +DUK_INTERNAL void duk_debug_write_heapptr(duk_hthread *thr, duk_heaphdr *h) { + duk__debug_write_pointer_raw(thr, (void *) h, DUK_DBG_IB_HEAPPTR); +} +#endif /* DUK_USE_DEBUGGER_DUMPHEAP || DUK_USE_DEBUGGER_INSPECT */ + +DUK_INTERNAL void duk_debug_write_hobject(duk_hthread *thr, duk_hobject *obj) { + duk_uint8_t buf[3]; + duk__ptr_union pu; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(sizeof(obj) >= 1 && sizeof(obj) <= 16); + DUK_ASSERT(obj != NULL); + + buf[0] = DUK_DBG_IB_OBJECT; + buf[1] = (duk_uint8_t) DUK_HOBJECT_GET_CLASS_NUMBER(obj); + buf[2] = sizeof(pu); + duk_debug_write_bytes(thr, buf, 3); + pu.p = (void *) obj; +#if defined(DUK_USE_INTEGER_LE) + duk_byteswap_bytes((duk_uint8_t *) pu.b, sizeof(pu)); +#endif + duk_debug_write_bytes(thr, (const duk_uint8_t *) &pu.p, (duk_size_t) sizeof(pu)); +} + +DUK_INTERNAL void duk_debug_write_tval(duk_hthread *thr, duk_tval *tv) { + duk_c_function lf_func; + duk_small_uint_t lf_flags; + duk_uint8_t buf[4]; + duk_double_union du1; + duk_double_union du2; + duk_int32_t i32; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(tv != NULL); + + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_UNDEFINED: + duk_debug_write_byte(thr, DUK_DBG_IB_UNDEFINED); + break; + case DUK_TAG_UNUSED: + duk_debug_write_byte(thr, DUK_DBG_IB_UNUSED); + break; + case DUK_TAG_NULL: + duk_debug_write_byte(thr, DUK_DBG_IB_NULL); + break; + case DUK_TAG_BOOLEAN: + DUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv) == 0 || + DUK_TVAL_GET_BOOLEAN(tv) == 1); + duk_debug_write_boolean(thr, DUK_TVAL_GET_BOOLEAN(tv)); + break; + case DUK_TAG_POINTER: + duk_debug_write_pointer(thr, (void *) DUK_TVAL_GET_POINTER(tv)); + break; + case DUK_TAG_LIGHTFUNC: + DUK_TVAL_GET_LIGHTFUNC(tv, lf_func, lf_flags); + buf[0] = DUK_DBG_IB_LIGHTFUNC; + buf[1] = (duk_uint8_t) (lf_flags >> 8); + buf[2] = (duk_uint8_t) (lf_flags & 0xff); + buf[3] = sizeof(lf_func); + duk_debug_write_bytes(thr, buf, 4); + duk_debug_write_bytes(thr, (const duk_uint8_t *) &lf_func, sizeof(lf_func)); + break; + case DUK_TAG_STRING: + duk_debug_write_hstring(thr, DUK_TVAL_GET_STRING(tv)); + break; + case DUK_TAG_OBJECT: + duk_debug_write_hobject(thr, DUK_TVAL_GET_OBJECT(tv)); + break; + case DUK_TAG_BUFFER: + duk_debug_write_hbuffer(thr, DUK_TVAL_GET_BUFFER(tv)); + break; +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: +#endif + default: + /* Numbers are normalized to big (network) endian. We can + * (but are not required) to use integer dvalues when there's + * no loss of precision. + * + * XXX: share check with other code; this check is slow but + * reliable and doesn't require careful exponent/mantissa + * mask tricks as in the fastint downgrade code. + */ + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv)); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); + du1.d = DUK_TVAL_GET_NUMBER(tv); + i32 = (duk_int32_t) du1.d; + du2.d = (duk_double_t) i32; + + DUK_DD(DUK_DDPRINT("i32=%ld du1=%02x%02x%02x%02x%02x%02x%02x%02x " + "du2=%02x%02x%02x%02x%02x%02x%02x%02x", + (long) i32, + (unsigned int) du1.uc[0], (unsigned int) du1.uc[1], + (unsigned int) du1.uc[2], (unsigned int) du1.uc[3], + (unsigned int) du1.uc[4], (unsigned int) du1.uc[5], + (unsigned int) du1.uc[6], (unsigned int) du1.uc[7], + (unsigned int) du2.uc[0], (unsigned int) du2.uc[1], + (unsigned int) du2.uc[2], (unsigned int) du2.uc[3], + (unsigned int) du2.uc[4], (unsigned int) du2.uc[5], + (unsigned int) du2.uc[6], (unsigned int) du2.uc[7])); + + if (duk_memcmp((const void *) du1.uc, (const void *) du2.uc, sizeof(du1.uc)) == 0) { + duk_debug_write_int(thr, i32); + } else { + DUK_DBLUNION_DOUBLE_HTON(&du1); + duk_debug_write_byte(thr, DUK_DBG_IB_NUMBER); + duk_debug_write_bytes(thr, (const duk_uint8_t *) du1.uc, sizeof(du1.uc)); + } + } +} + +#if defined(DUK_USE_DEBUGGER_DUMPHEAP) +/* Variant for writing duk_tvals so that any heap allocated values are + * written out as tagged heap pointers. + */ +DUK_LOCAL void duk__debug_write_tval_heapptr(duk_hthread *thr, duk_tval *tv) { + if (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) { + duk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv); + duk_debug_write_heapptr(thr, h); + } else { + duk_debug_write_tval(thr, tv); + } +} +#endif /* DUK_USE_DEBUGGER_DUMPHEAP */ + +/* + * Debug connection message write helpers + */ + +#if 0 /* unused */ +DUK_INTERNAL void duk_debug_write_request(duk_hthread *thr, duk_small_uint_t command) { + duk_debug_write_byte(thr, DUK_DBG_IB_REQUEST); + duk_debug_write_int(thr, command); +} +#endif + +DUK_INTERNAL void duk_debug_write_reply(duk_hthread *thr) { + duk_debug_write_byte(thr, DUK_DBG_IB_REPLY); +} + +DUK_INTERNAL void duk_debug_write_error_eom(duk_hthread *thr, duk_small_uint_t err_code, const char *msg) { + /* Allow NULL 'msg' */ + duk_debug_write_byte(thr, DUK_DBG_IB_ERROR); + duk_debug_write_int(thr, (duk_int32_t) err_code); + duk_debug_write_cstring(thr, msg); + duk_debug_write_eom(thr); +} + +DUK_INTERNAL void duk_debug_write_notify(duk_hthread *thr, duk_small_uint_t command) { + duk_debug_write_byte(thr, DUK_DBG_IB_NOTIFY); + duk_debug_write_int(thr, (duk_int32_t) command); +} + +DUK_INTERNAL void duk_debug_write_eom(duk_hthread *thr) { + duk_debug_write_byte(thr, DUK_DBG_IB_EOM); + + /* As an initial implementation, write flush after every EOM (and the + * version identifier). A better implementation would flush only when + * Duktape is finished processing messages so that a flush only happens + * after all outbound messages are finished on that occasion. + */ + duk_debug_write_flush(thr); +} + +/* + * Status message and helpers + */ + +DUK_INTERNAL duk_uint_fast32_t duk_debug_curr_line(duk_hthread *thr) { + duk_activation *act; + duk_uint_fast32_t line; + duk_uint_fast32_t pc; + + act = thr->callstack_curr; + if (act == NULL) { + return 0; + } + + /* We're conceptually between two opcodes; act->pc indicates the next + * instruction to be executed. This is usually the correct pc/line to + * indicate in Status. (For the 'debugger' statement this now reports + * the pc/line after the debugger statement because the debugger opcode + * has already been executed.) + */ + + pc = duk_hthread_get_act_curr_pc(thr, act); + + /* XXX: this should be optimized to be a raw query and avoid valstack + * operations if possible. + */ + duk_push_tval(thr, &act->tv_func); + line = duk_hobject_pc2line_query(thr, -1, pc); + duk_pop(thr); + return line; +} + +DUK_INTERNAL void duk_debug_send_status(duk_hthread *thr) { + duk_activation *act; + + duk_debug_write_notify(thr, DUK_DBG_CMD_STATUS); + duk_debug_write_int(thr, (DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) ? 1 : 0)); + + act = thr->callstack_curr; + if (act == NULL) { + duk_debug_write_undefined(thr); + duk_debug_write_undefined(thr); + duk_debug_write_int(thr, 0); + duk_debug_write_int(thr, 0); + } else { + duk_push_tval(thr, &act->tv_func); + duk_get_prop_literal(thr, -1, "fileName"); + duk__debug_write_hstring_safe_top(thr); + duk_get_prop_literal(thr, -2, "name"); + duk__debug_write_hstring_safe_top(thr); + duk_pop_3(thr); + /* Report next pc/line to be executed. */ + duk_debug_write_uint(thr, (duk_uint32_t) duk_debug_curr_line(thr)); + duk_debug_write_uint(thr, (duk_uint32_t) duk_hthread_get_act_curr_pc(thr, act)); + } + + duk_debug_write_eom(thr); +} + +#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY) +DUK_INTERNAL void duk_debug_send_throw(duk_hthread *thr, duk_bool_t fatal) { + /* + * NFY EOM + */ + + duk_activation *act; + duk_uint32_t pc; + + DUK_ASSERT(thr->valstack_top > thr->valstack); /* At least: ... [err] */ + + duk_debug_write_notify(thr, DUK_DBG_CMD_THROW); + duk_debug_write_int(thr, (duk_int32_t) fatal); + + /* Report thrown value to client coerced to string */ + duk_dup_top(thr); + duk__debug_write_hstring_safe_top(thr); + duk_pop(thr); + + if (duk_is_error(thr, -1)) { + /* Error instance, use augmented error data directly */ + duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME); + duk__debug_write_hstring_safe_top(thr); + duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_LINE_NUMBER); + duk_debug_write_uint(thr, duk_get_uint(thr, -1)); + duk_pop_2(thr); + } else { + /* For anything other than an Error instance, we calculate the + * error location directly from the current activation if one + * exists. + */ + act = thr->callstack_curr; + if (act != NULL) { + duk_push_tval(thr, &act->tv_func); + duk_get_prop_literal(thr, -1, "fileName"); + duk__debug_write_hstring_safe_top(thr); + pc = (duk_uint32_t) duk_hthread_get_act_prev_pc(thr, act); + duk_debug_write_uint(thr, (duk_uint32_t) duk_hobject_pc2line_query(thr, -2, pc)); + duk_pop_2(thr); + } else { + /* Can happen if duk_throw() is called on an empty + * callstack. + */ + duk_debug_write_cstring(thr, ""); + duk_debug_write_uint(thr, 0); + } + } + + duk_debug_write_eom(thr); +} +#endif /* DUK_USE_DEBUGGER_THROW_NOTIFY */ + +/* + * Debug message processing + */ + +/* Skip dvalue. */ +DUK_LOCAL duk_bool_t duk__debug_skip_dvalue(duk_hthread *thr) { + duk_uint8_t x; + duk_uint32_t len; + + x = duk_debug_read_byte(thr); + + if (x >= 0xc0) { + duk_debug_skip_byte(thr); + return 0; + } + if (x >= 0x80) { + return 0; + } + if (x >= 0x60) { + duk_debug_skip_bytes(thr, (duk_size_t) (x - 0x60)); + return 0; + } + switch(x) { + case DUK_DBG_IB_EOM: + return 1; /* Return 1: got EOM */ + case DUK_DBG_IB_REQUEST: + case DUK_DBG_IB_REPLY: + case DUK_DBG_IB_ERROR: + case DUK_DBG_IB_NOTIFY: + break; + case DUK_DBG_IB_INT4: + (void) duk__debug_read_uint32_raw(thr); + break; + case DUK_DBG_IB_STR4: + case DUK_DBG_IB_BUF4: + len = duk__debug_read_uint32_raw(thr); + duk_debug_skip_bytes(thr, len); + break; + case DUK_DBG_IB_STR2: + case DUK_DBG_IB_BUF2: + len = duk__debug_read_uint16_raw(thr); + duk_debug_skip_bytes(thr, len); + break; + case DUK_DBG_IB_UNUSED: + case DUK_DBG_IB_UNDEFINED: + case DUK_DBG_IB_NULL: + case DUK_DBG_IB_TRUE: + case DUK_DBG_IB_FALSE: + break; + case DUK_DBG_IB_NUMBER: + duk_debug_skip_bytes(thr, 8); + break; + case DUK_DBG_IB_OBJECT: + duk_debug_skip_byte(thr); + len = duk_debug_read_byte(thr); + duk_debug_skip_bytes(thr, len); + break; + case DUK_DBG_IB_POINTER: + case DUK_DBG_IB_HEAPPTR: + len = duk_debug_read_byte(thr); + duk_debug_skip_bytes(thr, len); + break; + case DUK_DBG_IB_LIGHTFUNC: + duk_debug_skip_bytes(thr, 2); + len = duk_debug_read_byte(thr); + duk_debug_skip_bytes(thr, len); + break; + default: + goto fail; + } + + return 0; + + fail: + DUK__SET_CONN_BROKEN(thr, 1); + return 1; /* Pretend like we got EOM */ +} + +/* Skip dvalues to EOM. */ +DUK_LOCAL void duk__debug_skip_to_eom(duk_hthread *thr) { + for (;;) { + if (duk__debug_skip_dvalue(thr)) { + break; + } + } +} + +/* Read and validate a call stack index. If index is invalid, write out an + * error message and return zero. + */ +DUK_LOCAL duk_int32_t duk__debug_read_validate_csindex(duk_hthread *thr) { + duk_int32_t level; + level = duk_debug_read_int(thr); + if (level >= 0 || -level > (duk_int32_t) thr->callstack_top) { + duk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, "invalid callstack index"); + return 0; /* zero indicates failure */ + } + return level; +} + +/* Read a call stack index and lookup the corresponding duk_activation. + * If index is invalid, write out an error message and return NULL. + */ +DUK_LOCAL duk_activation *duk__debug_read_level_get_activation(duk_hthread *thr) { + duk_activation *act; + duk_int32_t level; + + level = duk_debug_read_int(thr); + act = duk_hthread_get_activation_for_level(thr, level); + if (act == NULL) { + duk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, "invalid callstack index"); + } + return act; +} + +/* + * Simple commands + */ + +DUK_LOCAL void duk__debug_handle_basic_info(duk_hthread *thr, duk_heap *heap) { + DUK_UNREF(heap); + DUK_D(DUK_DPRINT("debug command Version")); + + duk_debug_write_reply(thr); + duk_debug_write_int(thr, DUK_VERSION); + duk_debug_write_cstring(thr, DUK_GIT_DESCRIBE); + duk_debug_write_cstring(thr, DUK_USE_TARGET_INFO); +#if defined(DUK_USE_DOUBLE_LE) + duk_debug_write_int(thr, 1); +#elif defined(DUK_USE_DOUBLE_ME) + duk_debug_write_int(thr, 2); +#elif defined(DUK_USE_DOUBLE_BE) + duk_debug_write_int(thr, 3); +#else + duk_debug_write_int(thr, 0); +#endif + duk_debug_write_int(thr, (duk_int_t) sizeof(void *)); + duk_debug_write_eom(thr); +} + +DUK_LOCAL void duk__debug_handle_trigger_status(duk_hthread *thr, duk_heap *heap) { + DUK_UNREF(heap); + DUK_D(DUK_DPRINT("debug command TriggerStatus")); + + duk_debug_write_reply(thr); + duk_debug_write_eom(thr); + heap->dbg_state_dirty = 1; +} + +DUK_LOCAL void duk__debug_handle_pause(duk_hthread *thr, duk_heap *heap) { + DUK_D(DUK_DPRINT("debug command Pause")); + duk_debug_set_paused(heap); + duk_debug_write_reply(thr); + duk_debug_write_eom(thr); +} + +DUK_LOCAL void duk__debug_handle_resume(duk_hthread *thr, duk_heap *heap) { + duk_small_uint_t pause_flags; + + DUK_D(DUK_DPRINT("debug command Resume")); + + duk_debug_clear_paused(heap); + + pause_flags = 0; +#if 0 /* manual testing */ + pause_flags |= DUK_PAUSE_FLAG_ONE_OPCODE; + pause_flags |= DUK_PAUSE_FLAG_CAUGHT_ERROR; + pause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR; +#endif +#if defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT) + pause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR; +#endif + + duk__debug_set_pause_state(thr, heap, pause_flags); + + duk_debug_write_reply(thr); + duk_debug_write_eom(thr); +} + +DUK_LOCAL void duk__debug_handle_step(duk_hthread *thr, duk_heap *heap, duk_int32_t cmd) { + duk_small_uint_t pause_flags; + + DUK_D(DUK_DPRINT("debug command StepInto/StepOver/StepOut: %d", (int) cmd)); + + if (cmd == DUK_DBG_CMD_STEPINTO) { + pause_flags = DUK_PAUSE_FLAG_LINE_CHANGE | + DUK_PAUSE_FLAG_FUNC_ENTRY | + DUK_PAUSE_FLAG_FUNC_EXIT; + } else if (cmd == DUK_DBG_CMD_STEPOVER) { + pause_flags = DUK_PAUSE_FLAG_LINE_CHANGE | + DUK_PAUSE_FLAG_FUNC_EXIT; + } else { + DUK_ASSERT(cmd == DUK_DBG_CMD_STEPOUT); + pause_flags = DUK_PAUSE_FLAG_FUNC_EXIT; + } +#if defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT) + pause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR; +#endif + + /* If current activation doesn't have line information, line-based + * pause flags are automatically disabled. As a result, e.g. + * StepInto will then pause on (native) function entry or exit. + */ + duk_debug_clear_paused(heap); + duk__debug_set_pause_state(thr, heap, pause_flags); + + duk_debug_write_reply(thr); + duk_debug_write_eom(thr); +} + +DUK_LOCAL void duk__debug_handle_list_break(duk_hthread *thr, duk_heap *heap) { + duk_small_int_t i; + + DUK_D(DUK_DPRINT("debug command ListBreak")); + duk_debug_write_reply(thr); + for (i = 0; i < (duk_small_int_t) heap->dbg_breakpoint_count; i++) { + duk_debug_write_hstring(thr, heap->dbg_breakpoints[i].filename); + duk_debug_write_uint(thr, (duk_uint32_t) heap->dbg_breakpoints[i].line); + } + duk_debug_write_eom(thr); +} + +DUK_LOCAL void duk__debug_handle_add_break(duk_hthread *thr, duk_heap *heap) { + duk_hstring *filename; + duk_uint32_t linenumber; + duk_small_int_t idx; + + DUK_UNREF(heap); + + filename = duk_debug_read_hstring(thr); + linenumber = (duk_uint32_t) duk_debug_read_int(thr); + DUK_D(DUK_DPRINT("debug command AddBreak: %!O:%ld", (duk_hobject *) filename, (long) linenumber)); + idx = duk_debug_add_breakpoint(thr, filename, linenumber); + if (idx >= 0) { + duk_debug_write_reply(thr); + duk_debug_write_int(thr, (duk_int32_t) idx); + duk_debug_write_eom(thr); + } else { + duk_debug_write_error_eom(thr, DUK_DBG_ERR_TOOMANY, "no space for breakpoint"); + } +} + +DUK_LOCAL void duk__debug_handle_del_break(duk_hthread *thr, duk_heap *heap) { + duk_small_uint_t idx; + + DUK_UNREF(heap); + + DUK_D(DUK_DPRINT("debug command DelBreak")); + idx = (duk_small_uint_t) duk_debug_read_int(thr); + if (duk_debug_remove_breakpoint(thr, idx)) { + duk_debug_write_reply(thr); + duk_debug_write_eom(thr); + } else { + duk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, "invalid breakpoint index"); + } +} + +DUK_LOCAL void duk__debug_handle_get_var(duk_hthread *thr, duk_heap *heap) { + duk_activation *act; + duk_hstring *str; + duk_bool_t rc; + + DUK_UNREF(heap); + DUK_D(DUK_DPRINT("debug command GetVar")); + + act = duk__debug_read_level_get_activation(thr); + if (act == NULL) { + return; + } + str = duk_debug_read_hstring(thr); /* push to stack */ + DUK_ASSERT(str != NULL); + + rc = duk_js_getvar_activation(thr, act, str, 0); + + duk_debug_write_reply(thr); + if (rc) { + duk_debug_write_int(thr, 1); + DUK_ASSERT(duk_get_tval(thr, -2) != NULL); + duk_debug_write_tval(thr, duk_get_tval(thr, -2)); + } else { + duk_debug_write_int(thr, 0); + duk_debug_write_unused(thr); + } + duk_debug_write_eom(thr); +} + +DUK_LOCAL void duk__debug_handle_put_var(duk_hthread *thr, duk_heap *heap) { + duk_activation *act; + duk_hstring *str; + duk_tval *tv; + + DUK_UNREF(heap); + DUK_D(DUK_DPRINT("debug command PutVar")); + + act = duk__debug_read_level_get_activation(thr); + if (act == NULL) { + return; + } + str = duk_debug_read_hstring(thr); /* push to stack */ + DUK_ASSERT(str != NULL); + tv = duk_debug_read_tval(thr); + if (tv == NULL) { + /* detached */ + return; + } + + duk_js_putvar_activation(thr, act, str, tv, 0); + + /* XXX: Current putvar implementation doesn't have a success flag, + * add one and send to debug client? + */ + duk_debug_write_reply(thr); + duk_debug_write_eom(thr); +} + +DUK_LOCAL void duk__debug_handle_get_call_stack(duk_hthread *thr, duk_heap *heap) { + duk_hthread *curr_thr = thr; + duk_activation *curr_act; + duk_uint_fast32_t pc; + duk_uint_fast32_t line; + + DUK_ASSERT(thr != NULL); + DUK_UNREF(heap); + + duk_debug_write_reply(thr); + while (curr_thr != NULL) { + for (curr_act = curr_thr->callstack_curr; curr_act != NULL; curr_act = curr_act->parent) { + /* PC/line semantics here are: + * - For callstack top we're conceptually between two + * opcodes and current PC indicates next line to + * execute, so report that (matches Status). + * - For other activations we're conceptually still + * executing the instruction at PC-1, so report that + * (matches error stacktrace behavior). + * - See: https://github.com/svaarala/duktape/issues/281 + */ + + /* XXX: optimize to use direct reads, i.e. avoid + * value stack operations. + */ + duk_push_tval(thr, &curr_act->tv_func); + duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME); + duk__debug_write_hstring_safe_top(thr); + duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME); + duk__debug_write_hstring_safe_top(thr); + pc = duk_hthread_get_act_curr_pc(thr, curr_act); + if (curr_act != curr_thr->callstack_curr && pc > 0) { + pc--; + } + line = duk_hobject_pc2line_query(thr, -3, pc); + duk_debug_write_uint(thr, (duk_uint32_t) line); + duk_debug_write_uint(thr, (duk_uint32_t) pc); + duk_pop_3(thr); + } + curr_thr = curr_thr->resumer; + } + /* SCANBUILD: warning about 'thr' potentially being NULL here, + * warning is incorrect because thr != NULL always here. + */ + duk_debug_write_eom(thr); +} + +DUK_LOCAL void duk__debug_handle_get_locals(duk_hthread *thr, duk_heap *heap) { + duk_activation *act; + duk_hstring *varname; + + DUK_UNREF(heap); + + act = duk__debug_read_level_get_activation(thr); + if (act == NULL) { + return; + } + + duk_debug_write_reply(thr); + + /* XXX: several nice-to-have improvements here: + * - Use direct reads avoiding value stack operations + * - Avoid triggering getters, indicate getter values to debug client + * - If side effects are possible, add error catching + */ + + if (DUK_TVAL_IS_OBJECT(&act->tv_func)) { + duk_hobject *h_func = DUK_TVAL_GET_OBJECT(&act->tv_func); + duk_hobject *h_varmap; + + h_varmap = duk_hobject_get_varmap(thr, h_func); + if (h_varmap != NULL) { + duk_push_hobject(thr, h_varmap); + duk_enum(thr, -1, 0 /*enum_flags*/); + while (duk_next(thr, -1 /*enum_index*/, 0 /*get_value*/)) { + varname = duk_known_hstring(thr, -1); + + duk_js_getvar_activation(thr, act, varname, 0 /*throw_flag*/); + /* [ ... func varmap enum key value this ] */ + duk_debug_write_hstring(thr, duk_get_hstring(thr, -3)); + duk_debug_write_tval(thr, duk_get_tval(thr, -2)); + duk_pop_3(thr); /* -> [ ... func varmap enum ] */ + } + } else { + DUK_D(DUK_DPRINT("varmap missing in GetLocals, ignore")); + } + } else { + DUK_D(DUK_DPRINT("varmap is not an object in GetLocals, ignore")); + } + + duk_debug_write_eom(thr); +} + +DUK_LOCAL void duk__debug_handle_eval(duk_hthread *thr, duk_heap *heap) { + duk_small_uint_t call_flags; + duk_int_t call_ret; + duk_small_int_t eval_err; + duk_bool_t direct_eval; + duk_int32_t level; + duk_idx_t idx_func; + + DUK_UNREF(heap); + + DUK_D(DUK_DPRINT("debug command Eval")); + + /* The eval code is executed within the lexical environment of a specified + * activation. For now, use global object eval() function, with the eval + * considered a 'direct call to eval'. + * + * Callstack index for debug commands only affects scope -- the callstack + * as seen by, e.g. Duktape.act() will be the same regardless. + */ + + /* nargs == 2 so we can pass a callstack index to eval(). */ + idx_func = duk_get_top(thr); + duk_push_c_function(thr, duk_bi_global_object_eval, 2 /*nargs*/); + duk_push_undefined(thr); /* 'this' binding shouldn't matter here */ + + /* Read callstack index, if non-null. */ + if (duk_debug_peek_byte(thr) == DUK_DBG_IB_NULL) { + direct_eval = 0; + level = -1; /* Not needed, but silences warning. */ + (void) duk_debug_read_byte(thr); + } else { + direct_eval = 1; + level = duk__debug_read_validate_csindex(thr); + if (level == 0) { + return; + } + } + + DUK_ASSERT(!direct_eval || + (level < 0 && -level <= (duk_int32_t) thr->callstack_top)); + + (void) duk_debug_read_hstring(thr); + if (direct_eval) { + duk_push_int(thr, level - 1); /* compensate for eval() call */ + } + + /* [ ... eval "eval" eval_input level? ] */ + + call_flags = 0; + if (direct_eval) { + duk_activation *act; + duk_hobject *fun; + + act = duk_hthread_get_activation_for_level(thr, level); + if (act != NULL) { + fun = DUK_ACT_GET_FUNC(act); + if (fun != NULL && DUK_HOBJECT_IS_COMPFUNC(fun)) { + /* Direct eval requires that there's a current + * activation and it is an ECMAScript function. + * When Eval is executed from e.g. cooperate API + * call we'll need to do an indirect eval instead. + */ + call_flags |= DUK_CALL_FLAG_DIRECT_EVAL; + } + } + } + + call_ret = duk_pcall_method_flags(thr, duk_get_top(thr) - (idx_func + 2), call_flags); + + if (call_ret == DUK_EXEC_SUCCESS) { + eval_err = 0; + /* Use result value as is. */ + } else { + /* For errors a string coerced result is most informative + * right now, as the debug client doesn't have the capability + * to traverse the error object. + */ + eval_err = 1; + duk_safe_to_string(thr, -1); + } + + /* [ ... result ] */ + + duk_debug_write_reply(thr); + duk_debug_write_int(thr, (duk_int32_t) eval_err); + DUK_ASSERT(duk_get_tval(thr, -1) != NULL); + duk_debug_write_tval(thr, duk_get_tval(thr, -1)); + duk_debug_write_eom(thr); +} + +DUK_LOCAL void duk__debug_handle_detach(duk_hthread *thr, duk_heap *heap) { + DUK_UNREF(heap); + DUK_D(DUK_DPRINT("debug command Detach")); + + duk_debug_write_reply(thr); + duk_debug_write_eom(thr); + + DUK_D(DUK_DPRINT("debug connection detached, mark broken")); + DUK__SET_CONN_BROKEN(thr, 0); /* not an error */ +} + +DUK_LOCAL void duk__debug_handle_apprequest(duk_hthread *thr, duk_heap *heap) { + duk_idx_t old_top; + + DUK_D(DUK_DPRINT("debug command AppRequest")); + + old_top = duk_get_top(thr); /* save stack top */ + + if (heap->dbg_request_cb != NULL) { + duk_idx_t nrets; + duk_idx_t nvalues = 0; + duk_idx_t top, idx; + + /* Read tvals from the message and push them onto the valstack, + * then call the request callback to process the request. + */ + while (duk_debug_peek_byte(thr) != DUK_DBG_IB_EOM) { + duk_tval *tv; + if (!duk_check_stack(thr, 1)) { + DUK_D(DUK_DPRINT("failed to allocate space for request dvalue(s)")); + goto fail; + } + tv = duk_debug_read_tval(thr); /* push to stack */ + if (tv == NULL) { + /* detached */ + return; + } + nvalues++; + } + DUK_ASSERT(duk_get_top(thr) == old_top + nvalues); + + /* Request callback should push values for reply to client onto valstack */ + DUK_D(DUK_DPRINT("calling into AppRequest request_cb with nvalues=%ld, old_top=%ld, top=%ld", + (long) nvalues, (long) old_top, (long) duk_get_top(thr))); + nrets = heap->dbg_request_cb(thr, heap->dbg_udata, nvalues); + DUK_D(DUK_DPRINT("returned from AppRequest request_cb; nvalues=%ld -> nrets=%ld, old_top=%ld, top=%ld", + (long) nvalues, (long) nrets, (long) old_top, (long) duk_get_top(thr))); + if (nrets >= 0) { + DUK_ASSERT(duk_get_top(thr) >= old_top + nrets); + if (duk_get_top(thr) < old_top + nrets) { + DUK_D(DUK_DPRINT("AppRequest callback doesn't match value stack configuration, " + "top=%ld < old_top=%ld + nrets=%ld; " + "this might mean it's unsafe to continue!", + (long) duk_get_top(thr), (long) old_top, (long) nrets)); + goto fail; + } + + /* Reply with tvals pushed by request callback */ + duk_debug_write_byte(thr, DUK_DBG_IB_REPLY); + top = duk_get_top(thr); + for (idx = top - nrets; idx < top; idx++) { + duk_debug_write_tval(thr, DUK_GET_TVAL_POSIDX(thr, idx)); + } + duk_debug_write_eom(thr); + } else { + DUK_ASSERT(duk_get_top(thr) >= old_top + 1); + if (duk_get_top(thr) < old_top + 1) { + DUK_D(DUK_DPRINT("request callback return value doesn't match value stack configuration")); + goto fail; + } + duk_debug_write_error_eom(thr, DUK_DBG_ERR_APPLICATION, duk_get_string(thr, -1)); + } + + duk_set_top(thr, old_top); /* restore stack top */ + } else { + DUK_D(DUK_DPRINT("no request callback, treat AppRequest as unsupported")); + duk_debug_write_error_eom(thr, DUK_DBG_ERR_UNSUPPORTED, "AppRequest unsupported by target"); + } + + return; + + fail: + duk_set_top(thr, old_top); /* restore stack top */ + DUK__SET_CONN_BROKEN(thr, 1); +} + +/* + * DumpHeap command + */ + +#if defined(DUK_USE_DEBUGGER_DUMPHEAP) +/* XXX: this has some overlap with object inspection; remove this and make + * DumpHeap return lists of heapptrs instead? + */ +DUK_LOCAL void duk__debug_dump_heaphdr(duk_hthread *thr, duk_heap *heap, duk_heaphdr *hdr) { + DUK_UNREF(heap); + + duk_debug_write_heapptr(thr, hdr); + duk_debug_write_uint(thr, (duk_uint32_t) DUK_HEAPHDR_GET_TYPE(hdr)); + duk_debug_write_uint(thr, (duk_uint32_t) DUK_HEAPHDR_GET_FLAGS_RAW(hdr)); +#if defined(DUK_USE_REFERENCE_COUNTING) + duk_debug_write_uint(thr, (duk_uint32_t) DUK_HEAPHDR_GET_REFCOUNT(hdr)); +#else + duk_debug_write_int(thr, (duk_int32_t) -1); +#endif + + switch (DUK_HEAPHDR_GET_TYPE(hdr)) { + case DUK_HTYPE_STRING: { + duk_hstring *h = (duk_hstring *) hdr; + + duk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_BYTELEN(h)); + duk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_CHARLEN(h)); + duk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_HASH(h)); + duk_debug_write_hstring(thr, h); + break; + } + case DUK_HTYPE_OBJECT: { + duk_hobject *h = (duk_hobject *) hdr; + duk_hstring *k; + duk_uint_fast32_t i; + + duk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_CLASS_NUMBER(h)); + duk_debug_write_heapptr(thr, (duk_heaphdr *) DUK_HOBJECT_GET_PROTOTYPE(heap, h)); + duk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_ESIZE(h)); + duk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_ENEXT(h)); + duk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_ASIZE(h)); + duk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_HSIZE(h)); + + for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) { + duk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_E_GET_FLAGS(heap, h, i)); + k = DUK_HOBJECT_E_GET_KEY(heap, h, i); + duk_debug_write_heapptr(thr, (duk_heaphdr *) k); + if (k == NULL) { + duk_debug_write_int(thr, 0); /* isAccessor */ + duk_debug_write_unused(thr); + continue; + } + if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, h, i)) { + duk_debug_write_int(thr, 1); /* isAccessor */ + duk_debug_write_heapptr(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.get); + duk_debug_write_heapptr(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.set); + } else { + duk_debug_write_int(thr, 0); /* isAccessor */ + + duk__debug_write_tval_heapptr(thr, &DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->v); + } + } + + for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(h); i++) { + /* Note: array dump will include elements beyond + * 'length'. + */ + duk__debug_write_tval_heapptr(thr, DUK_HOBJECT_A_GET_VALUE_PTR(heap, h, i)); + } + break; + } + case DUK_HTYPE_BUFFER: { + duk_hbuffer *h = (duk_hbuffer *) hdr; + + duk_debug_write_uint(thr, (duk_uint32_t) DUK_HBUFFER_GET_SIZE(h)); + duk_debug_write_buffer(thr, (const char *) DUK_HBUFFER_GET_DATA_PTR(heap, h), (duk_size_t) DUK_HBUFFER_GET_SIZE(h)); + break; + } + default: { + DUK_D(DUK_DPRINT("invalid htype: %d", (int) DUK_HEAPHDR_GET_TYPE(hdr))); + } + } +} + +DUK_LOCAL void duk__debug_dump_heap_allocated(duk_hthread *thr, duk_heap *heap) { + duk_heaphdr *hdr; + + hdr = heap->heap_allocated; + while (hdr != NULL) { + duk__debug_dump_heaphdr(thr, heap, hdr); + hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr); + } +} + +DUK_LOCAL void duk__debug_dump_strtab(duk_hthread *thr, duk_heap *heap) { + duk_uint32_t i; + duk_hstring *h; + + for (i = 0; i < heap->st_size; i++) { +#if defined(DUK_USE_STRTAB_PTRCOMP) + h = DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, heap->strtable16[i]); +#else + h = heap->strtable[i]; +#endif + while (h != NULL) { + duk__debug_dump_heaphdr(thr, heap, (duk_heaphdr *) h); + h = h->hdr.h_next; + } + } +} + +DUK_LOCAL void duk__debug_handle_dump_heap(duk_hthread *thr, duk_heap *heap) { + DUK_D(DUK_DPRINT("debug command DumpHeap")); + + duk_debug_write_reply(thr); + duk__debug_dump_heap_allocated(thr, heap); + duk__debug_dump_strtab(thr, heap); + duk_debug_write_eom(thr); +} +#endif /* DUK_USE_DEBUGGER_DUMPHEAP */ + +DUK_LOCAL void duk__debug_handle_get_bytecode(duk_hthread *thr, duk_heap *heap) { + duk_activation *act; + duk_hcompfunc *fun = NULL; + duk_size_t i, n; + duk_tval *tv; + duk_hobject **fn; + duk_int32_t level = -1; + duk_uint8_t ibyte; + + DUK_UNREF(heap); + + DUK_D(DUK_DPRINT("debug command GetBytecode")); + + ibyte = duk_debug_peek_byte(thr); + if (ibyte != DUK_DBG_IB_EOM) { + tv = duk_debug_read_tval(thr); + if (tv == NULL) { + /* detached */ + return; + } + if (DUK_TVAL_IS_OBJECT(tv)) { + /* tentative, checked later */ + fun = (duk_hcompfunc *) DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(fun != NULL); + } else if (DUK_TVAL_IS_NUMBER(tv)) { + level = (duk_int32_t) DUK_TVAL_GET_NUMBER(tv); + } else { + DUK_D(DUK_DPRINT("invalid argument to GetBytecode: %!T", tv)); + goto fail_args; + } + } + + if (fun == NULL) { + act = duk_hthread_get_activation_for_level(thr, level); + if (act == NULL) { + goto fail_index; + } + fun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act); + } + + if (fun == NULL || !DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun)) { + DUK_D(DUK_DPRINT("invalid argument to GetBytecode: %!O", fun)); + goto fail_args; + } + DUK_ASSERT(fun != NULL && DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun)); + + duk_debug_write_reply(thr); + n = DUK_HCOMPFUNC_GET_CONSTS_COUNT(heap, fun); + duk_debug_write_int(thr, (duk_int32_t) n); + tv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, fun); + for (i = 0; i < n; i++) { + duk_debug_write_tval(thr, tv); + tv++; + } + n = DUK_HCOMPFUNC_GET_FUNCS_COUNT(heap, fun); + duk_debug_write_int(thr, (duk_int32_t) n); + fn = DUK_HCOMPFUNC_GET_FUNCS_BASE(heap, fun); + for (i = 0; i < n; i++) { + duk_debug_write_hobject(thr, *fn); + fn++; + } + duk_debug_write_string(thr, + (const char *) DUK_HCOMPFUNC_GET_CODE_BASE(heap, fun), + (duk_size_t) DUK_HCOMPFUNC_GET_CODE_SIZE(heap, fun)); + duk_debug_write_eom(thr); + return; + + fail_args: + duk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, "invalid argument"); + return; + + fail_index: + duk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, "invalid callstack index"); + return; +} + +/* + * Object inspection commands: GetHeapObjInfo, GetObjPropDesc, + * GetObjPropDescRange + */ + +#if defined(DUK_USE_DEBUGGER_INSPECT) + +#if 0 /* pruned */ +DUK_LOCAL const char * const duk__debug_getinfo_heaphdr_keys[] = { + "reachable", + "temproot", + "finalizable", + "finalized", + "readonly" + /* NULL not needed here */ +}; +DUK_LOCAL duk_uint_t duk__debug_getinfo_heaphdr_masks[] = { + DUK_HEAPHDR_FLAG_REACHABLE, + DUK_HEAPHDR_FLAG_TEMPROOT, + DUK_HEAPHDR_FLAG_FINALIZABLE, + DUK_HEAPHDR_FLAG_FINALIZED, + DUK_HEAPHDR_FLAG_READONLY, + 0 /* terminator */ +}; +#endif +DUK_LOCAL const char * const duk__debug_getinfo_hstring_keys[] = { +#if 0 + "arridx", + "symbol", + "hidden", + "reserved_word", + "strict_reserved_word", + "eval_or_arguments", +#endif + "extdata" + /* NULL not needed here */ +}; +DUK_LOCAL duk_uint_t duk__debug_getinfo_hstring_masks[] = { +#if 0 + DUK_HSTRING_FLAG_ARRIDX, + DUK_HSTRING_FLAG_SYMBOL, + DUK_HSTRING_FLAG_HIDDEN, + DUK_HSTRING_FLAG_RESERVED_WORD, + DUK_HSTRING_FLAG_STRICT_RESERVED_WORD, + DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS, +#endif + DUK_HSTRING_FLAG_EXTDATA, + 0 /* terminator */ +}; +DUK_LOCAL const char * const duk__debug_getinfo_hobject_keys[] = { + "extensible", + "constructable", + "callable", + "boundfunc", + "compfunc", + "natfunc", + "bufobj", + "fastrefs", + "array_part", + "strict", + "notail", + "newenv", + "namebinding", + "createargs", + "have_finalizer", + "exotic_array", + "exotic_stringobj", + "exotic_arguments", + "exotic_proxyobj", + "special_call" + /* NULL not needed here */ +}; +DUK_LOCAL duk_uint_t duk__debug_getinfo_hobject_masks[] = { + DUK_HOBJECT_FLAG_EXTENSIBLE, + DUK_HOBJECT_FLAG_CONSTRUCTABLE, + DUK_HOBJECT_FLAG_CALLABLE, + DUK_HOBJECT_FLAG_BOUNDFUNC, + DUK_HOBJECT_FLAG_COMPFUNC, + DUK_HOBJECT_FLAG_NATFUNC, + DUK_HOBJECT_FLAG_BUFOBJ, + DUK_HOBJECT_FLAG_FASTREFS, + DUK_HOBJECT_FLAG_ARRAY_PART, + DUK_HOBJECT_FLAG_STRICT, + DUK_HOBJECT_FLAG_NOTAIL, + DUK_HOBJECT_FLAG_NEWENV, + DUK_HOBJECT_FLAG_NAMEBINDING, + DUK_HOBJECT_FLAG_CREATEARGS, + DUK_HOBJECT_FLAG_HAVE_FINALIZER, + DUK_HOBJECT_FLAG_EXOTIC_ARRAY, + DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ, + DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS, + DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ, + DUK_HOBJECT_FLAG_SPECIAL_CALL, + 0 /* terminator */ +}; +DUK_LOCAL const char * const duk__debug_getinfo_hbuffer_keys[] = { + "dynamic", + "external" + /* NULL not needed here */ +}; +DUK_LOCAL duk_uint_t duk__debug_getinfo_hbuffer_masks[] = { + DUK_HBUFFER_FLAG_DYNAMIC, + DUK_HBUFFER_FLAG_EXTERNAL, + 0 /* terminator */ +}; + +DUK_LOCAL void duk__debug_getinfo_flags_key(duk_hthread *thr, const char *key) { + duk_debug_write_uint(thr, 0); + duk_debug_write_cstring(thr, key); +} + +DUK_LOCAL void duk__debug_getinfo_prop_uint(duk_hthread *thr, const char *key, duk_uint_t val) { + duk_debug_write_uint(thr, 0); + duk_debug_write_cstring(thr, key); + duk_debug_write_uint(thr, val); +} + +DUK_LOCAL void duk__debug_getinfo_prop_int(duk_hthread *thr, const char *key, duk_int_t val) { + duk_debug_write_uint(thr, 0); + duk_debug_write_cstring(thr, key); + duk_debug_write_int(thr, val); +} + +DUK_LOCAL void duk__debug_getinfo_prop_bool(duk_hthread *thr, const char *key, duk_bool_t val) { + duk_debug_write_uint(thr, 0); + duk_debug_write_cstring(thr, key); + duk_debug_write_boolean(thr, val); +} + +DUK_LOCAL void duk__debug_getinfo_bitmask(duk_hthread *thr, const char * const * keys, duk_uint_t *masks, duk_uint_t flags) { + const char *key; + duk_uint_t mask; + + for (;;) { + mask = *masks++; + if (mask == 0) { + break; + } + key = *keys++; + DUK_ASSERT(key != NULL); + + DUK_DD(DUK_DDPRINT("inspect bitmask: key=%s, mask=0x%08lx, flags=0x%08lx", key, (unsigned long) mask, (unsigned long) flags)); + duk__debug_getinfo_prop_bool(thr, key, flags & mask); + } +} + +/* Inspect a property using a virtual index into a conceptual property list + * consisting of (1) all array part items from [0,a_size[ (even when above + * .length) and (2) all entry part items from [0,e_next[. Unused slots are + * indicated using dvalue 'unused'. + */ +DUK_LOCAL duk_bool_t duk__debug_getprop_index(duk_hthread *thr, duk_heap *heap, duk_hobject *h_obj, duk_uint_t idx) { + duk_uint_t a_size; + duk_tval *tv; + duk_hstring *h_key; + duk_hobject *h_getset; + duk_uint_t flags; + + DUK_UNREF(heap); + + a_size = DUK_HOBJECT_GET_ASIZE(h_obj); + if (idx < a_size) { + duk_debug_write_uint(thr, DUK_PROPDESC_FLAGS_WEC); + duk_debug_write_uint(thr, idx); + tv = DUK_HOBJECT_A_GET_VALUE_PTR(heap, h_obj, idx); + duk_debug_write_tval(thr, tv); + return 1; + } + + idx -= a_size; + if (idx >= DUK_HOBJECT_GET_ENEXT(h_obj)) { + return 0; + } + + h_key = DUK_HOBJECT_E_GET_KEY(heap, h_obj, idx); + if (h_key == NULL) { + duk_debug_write_uint(thr, 0); + duk_debug_write_null(thr); + duk_debug_write_unused(thr); + return 1; + } + + flags = DUK_HOBJECT_E_GET_FLAGS(heap, h_obj, idx); + if (DUK_HSTRING_HAS_SYMBOL(h_key)) { + flags |= DUK_DBG_PROPFLAG_SYMBOL; + } + if (DUK_HSTRING_HAS_HIDDEN(h_key)) { + flags |= DUK_DBG_PROPFLAG_HIDDEN; + } + duk_debug_write_uint(thr, flags); + duk_debug_write_hstring(thr, h_key); + if (flags & DUK_PROPDESC_FLAG_ACCESSOR) { + h_getset = DUK_HOBJECT_E_GET_VALUE_GETTER(heap, h_obj, idx); + if (h_getset) { + duk_debug_write_hobject(thr, h_getset); + } else { + duk_debug_write_null(thr); + } + h_getset = DUK_HOBJECT_E_GET_VALUE_SETTER(heap, h_obj, idx); + if (h_getset) { + duk_debug_write_hobject(thr, h_getset); + } else { + duk_debug_write_null(thr); + } + } else { + tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, h_obj, idx); + duk_debug_write_tval(thr, tv); + } + return 1; +} + +DUK_LOCAL void duk__debug_handle_get_heap_obj_info(duk_hthread *thr, duk_heap *heap) { + duk_heaphdr *h; + + DUK_D(DUK_DPRINT("debug command GetHeapObjInfo")); + DUK_UNREF(heap); + + DUK_ASSERT(sizeof(duk__debug_getinfo_hstring_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hstring_masks) / sizeof(duk_uint_t) - 1); + DUK_ASSERT(sizeof(duk__debug_getinfo_hobject_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hobject_masks) / sizeof(duk_uint_t) - 1); + DUK_ASSERT(sizeof(duk__debug_getinfo_hbuffer_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hbuffer_masks) / sizeof(duk_uint_t) - 1); + + h = duk_debug_read_any_ptr(thr); + if (!h) { + duk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, "invalid target"); + return; + } + + duk_debug_write_reply(thr); + + /* As with all inspection code, we rely on the debug client providing + * a valid, non-stale pointer: there's no portable way to safely + * validate the pointer here. + */ + + duk__debug_getinfo_flags_key(thr, "heapptr"); + duk_debug_write_heapptr(thr, h); + + /* XXX: comes out as signed now */ + duk__debug_getinfo_prop_uint(thr, "heaphdr_flags", (duk_uint_t) DUK_HEAPHDR_GET_FLAGS(h)); + duk__debug_getinfo_prop_uint(thr, "heaphdr_type", (duk_uint_t) DUK_HEAPHDR_GET_TYPE(h)); +#if defined(DUK_USE_REFERENCE_COUNTING) + duk__debug_getinfo_prop_uint(thr, "refcount", (duk_uint_t) DUK_HEAPHDR_GET_REFCOUNT(h)); +#endif +#if 0 /* pruned */ + duk__debug_getinfo_bitmask(thr, + duk__debug_getinfo_heaphdr_keys, + duk__debug_getinfo_heaphdr_masks, + DUK_HEAPHDR_GET_FLAGS_RAW(h)); +#endif + + switch (DUK_HEAPHDR_GET_TYPE(h)) { + case DUK_HTYPE_STRING: { + duk_hstring *h_str; + + h_str = (duk_hstring *) h; + duk__debug_getinfo_bitmask(thr, + duk__debug_getinfo_hstring_keys, + duk__debug_getinfo_hstring_masks, + DUK_HEAPHDR_GET_FLAGS_RAW(h)); + duk__debug_getinfo_prop_uint(thr, "bytelen", (duk_uint_t) DUK_HSTRING_GET_BYTELEN(h_str)); + duk__debug_getinfo_prop_uint(thr, "charlen", (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h_str)); + duk__debug_getinfo_prop_uint(thr, "hash", (duk_uint_t) DUK_HSTRING_GET_HASH(h_str)); + duk__debug_getinfo_flags_key(thr, "data"); + duk_debug_write_hstring(thr, h_str); + break; + } + case DUK_HTYPE_OBJECT: { + duk_hobject *h_obj; + duk_hobject *h_proto; + + h_obj = (duk_hobject *) h; + h_proto = DUK_HOBJECT_GET_PROTOTYPE(heap, h_obj); + + /* duk_hobject specific fields. */ + duk__debug_getinfo_bitmask(thr, + duk__debug_getinfo_hobject_keys, + duk__debug_getinfo_hobject_masks, + DUK_HEAPHDR_GET_FLAGS_RAW(h)); + duk__debug_getinfo_prop_uint(thr, "class_number", DUK_HOBJECT_GET_CLASS_NUMBER(h_obj)); + duk__debug_getinfo_flags_key(thr, "class_name"); + duk_debug_write_hstring(thr, DUK_HOBJECT_GET_CLASS_STRING(heap, h_obj)); + duk__debug_getinfo_flags_key(thr, "prototype"); + if (h_proto != NULL) { + duk_debug_write_hobject(thr, h_proto); + } else { + duk_debug_write_null(thr); + } + duk__debug_getinfo_flags_key(thr, "props"); + duk_debug_write_pointer(thr, (void *) DUK_HOBJECT_GET_PROPS(heap, h_obj)); + duk__debug_getinfo_prop_uint(thr, "e_size", (duk_uint_t) DUK_HOBJECT_GET_ESIZE(h_obj)); + duk__debug_getinfo_prop_uint(thr, "e_next", (duk_uint_t) DUK_HOBJECT_GET_ENEXT(h_obj)); + duk__debug_getinfo_prop_uint(thr, "a_size", (duk_uint_t) DUK_HOBJECT_GET_ASIZE(h_obj)); + duk__debug_getinfo_prop_uint(thr, "h_size", (duk_uint_t) DUK_HOBJECT_GET_HSIZE(h_obj)); + + if (DUK_HOBJECT_IS_ARRAY(h_obj)) { + duk_harray *h_arr; + h_arr = (duk_harray *) h_obj; + + duk__debug_getinfo_prop_uint(thr, "length", (duk_uint_t) h_arr->length); + duk__debug_getinfo_prop_bool(thr, "length_nonwritable", h_arr->length_nonwritable); + } + + if (DUK_HOBJECT_IS_NATFUNC(h_obj)) { + duk_hnatfunc *h_fun; + h_fun = (duk_hnatfunc *) h_obj; + + duk__debug_getinfo_prop_int(thr, "nargs", h_fun->nargs); + duk__debug_getinfo_prop_int(thr, "magic", h_fun->magic); + duk__debug_getinfo_prop_bool(thr, "varargs", h_fun->magic == DUK_HNATFUNC_NARGS_VARARGS); + /* Native function pointer may be different from a void pointer, + * and we serialize it from memory directly now (no byte swapping etc). + */ + duk__debug_getinfo_flags_key(thr, "funcptr"); + duk_debug_write_buffer(thr, (const char *) &h_fun->func, sizeof(h_fun->func)); + } + + if (DUK_HOBJECT_IS_COMPFUNC(h_obj)) { + duk_hcompfunc *h_fun; + duk_hbuffer *h_buf; + duk_hobject *h_lexenv; + duk_hobject *h_varenv; + h_fun = (duk_hcompfunc *) h_obj; + + duk__debug_getinfo_prop_int(thr, "nregs", h_fun->nregs); + duk__debug_getinfo_prop_int(thr, "nargs", h_fun->nargs); + + duk__debug_getinfo_flags_key(thr, "lex_env"); + h_lexenv = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, h_fun); + if (h_lexenv != NULL) { + duk_debug_write_hobject(thr, h_lexenv); + } else { + duk_debug_write_null(thr); + } + duk__debug_getinfo_flags_key(thr, "var_env"); + h_varenv = DUK_HCOMPFUNC_GET_VARENV(thr->heap, h_fun); + if (h_varenv != NULL) { + duk_debug_write_hobject(thr, h_varenv); + } else { + duk_debug_write_null(thr); + } + + duk__debug_getinfo_prop_uint(thr, "start_line", h_fun->start_line); + duk__debug_getinfo_prop_uint(thr, "end_line", h_fun->end_line); + h_buf = (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(thr->heap, h_fun); + if (h_buf != NULL) { + duk__debug_getinfo_flags_key(thr, "data"); + duk_debug_write_heapptr(thr, (duk_heaphdr *) h_buf); + } + } + + if (DUK_HOBJECT_IS_BOUNDFUNC(h_obj)) { + duk_hboundfunc *h_bfun; + h_bfun = (duk_hboundfunc *) (void *) h_obj; + + duk__debug_getinfo_flags_key(thr, "target"); + duk_debug_write_tval(thr, &h_bfun->target); + duk__debug_getinfo_flags_key(thr, "this_binding"); + duk_debug_write_tval(thr, &h_bfun->this_binding); + duk__debug_getinfo_flags_key(thr, "nargs"); + duk_debug_write_int(thr, h_bfun->nargs); + /* h_bfun->args not exposed now */ + } + + if (DUK_HOBJECT_IS_THREAD(h_obj)) { + /* XXX: Currently no inspection of threads, e.g. value stack, call + * stack, catch stack, etc. + */ + duk_hthread *h_thr; + h_thr = (duk_hthread *) h_obj; + DUK_UNREF(h_thr); + } + + if (DUK_HOBJECT_IS_DECENV(h_obj)) { + duk_hdecenv *h_env; + h_env = (duk_hdecenv *) h_obj; + + duk__debug_getinfo_flags_key(thr, "thread"); + duk_debug_write_heapptr(thr, (duk_heaphdr *) (h_env->thread)); + duk__debug_getinfo_flags_key(thr, "varmap"); + duk_debug_write_heapptr(thr, (duk_heaphdr *) (h_env->varmap)); + duk__debug_getinfo_prop_uint(thr, "regbase", (duk_uint_t) h_env->regbase_byteoff); + } + + if (DUK_HOBJECT_IS_OBJENV(h_obj)) { + duk_hobjenv *h_env; + h_env = (duk_hobjenv *) h_obj; + + duk__debug_getinfo_flags_key(thr, "target"); + duk_debug_write_heapptr(thr, (duk_heaphdr *) (h_env->target)); + duk__debug_getinfo_prop_bool(thr, "has_this", h_env->has_this); + } + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) { + duk_hbufobj *h_bufobj; + h_bufobj = (duk_hbufobj *) h_obj; + + duk__debug_getinfo_prop_uint(thr, "slice_offset", h_bufobj->offset); + duk__debug_getinfo_prop_uint(thr, "slice_length", h_bufobj->length); + duk__debug_getinfo_prop_uint(thr, "elem_shift", (duk_uint_t) h_bufobj->shift); + duk__debug_getinfo_prop_uint(thr, "elem_type", (duk_uint_t) h_bufobj->elem_type); + duk__debug_getinfo_prop_bool(thr, "is_typedarray", (duk_uint_t) h_bufobj->is_typedarray); + if (h_bufobj->buf != NULL) { + duk__debug_getinfo_flags_key(thr, "buffer"); + duk_debug_write_heapptr(thr, (duk_heaphdr *) h_bufobj->buf); + } + } +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + break; + } + case DUK_HTYPE_BUFFER: { + duk_hbuffer *h_buf; + + h_buf = (duk_hbuffer *) h; + duk__debug_getinfo_bitmask(thr, + duk__debug_getinfo_hbuffer_keys, + duk__debug_getinfo_hbuffer_masks, + DUK_HEAPHDR_GET_FLAGS_RAW(h)); + duk__debug_getinfo_prop_uint(thr, "size", (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_buf)); + duk__debug_getinfo_flags_key(thr, "dataptr"); + duk_debug_write_pointer(thr, (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_buf)); + duk__debug_getinfo_flags_key(thr, "data"); + duk_debug_write_hbuffer(thr, h_buf); /* tolerates NULL h_buf */ + break; + } + default: { + /* Since we already started writing the reply, just emit nothing. */ + DUK_D(DUK_DPRINT("inspect target pointer has invalid heaphdr type")); + } + } + + duk_debug_write_eom(thr); +} + +DUK_LOCAL void duk__debug_handle_get_obj_prop_desc(duk_hthread *thr, duk_heap *heap) { + duk_heaphdr *h; + duk_hobject *h_obj; + duk_hstring *h_key; + duk_propdesc desc; + + DUK_D(DUK_DPRINT("debug command GetObjPropDesc")); + DUK_UNREF(heap); + + h = duk_debug_read_any_ptr(thr); + if (!h) { + duk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, "invalid target"); + return; + } + h_key = duk_debug_read_hstring(thr); + if (h == NULL || DUK_HEAPHDR_GET_TYPE(h) != DUK_HTYPE_OBJECT || h_key == NULL) { + goto fail_args; + } + h_obj = (duk_hobject *) h; + + if (duk_hobject_get_own_propdesc(thr, h_obj, h_key, &desc, 0 /*flags*/)) { + duk_int_t virtual_idx; + duk_bool_t rc; + + /* To use the shared helper need the virtual index. */ + DUK_ASSERT(desc.e_idx >= 0 || desc.a_idx >= 0); + virtual_idx = (desc.a_idx >= 0 ? desc.a_idx : + (duk_int_t) DUK_HOBJECT_GET_ASIZE(h_obj) + desc.e_idx); + + duk_debug_write_reply(thr); + rc = duk__debug_getprop_index(thr, heap, h_obj, (duk_uint_t) virtual_idx); + DUK_ASSERT(rc == 1); + DUK_UNREF(rc); + duk_debug_write_eom(thr); + } else { + duk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, "not found"); + } + return; + + fail_args: + duk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, "invalid args"); +} + +DUK_LOCAL void duk__debug_handle_get_obj_prop_desc_range(duk_hthread *thr, duk_heap *heap) { + duk_heaphdr *h; + duk_hobject *h_obj; + duk_uint_t idx, idx_start, idx_end; + + DUK_D(DUK_DPRINT("debug command GetObjPropDescRange")); + DUK_UNREF(heap); + + h = duk_debug_read_any_ptr(thr); + idx_start = (duk_uint_t) duk_debug_read_int(thr); + idx_end = (duk_uint_t) duk_debug_read_int(thr); + if (h == NULL || DUK_HEAPHDR_GET_TYPE(h) != DUK_HTYPE_OBJECT) { + goto fail_args; + } + h_obj = (duk_hobject *) h; + + /* The index range space is conceptually the array part followed by the + * entry part. Unlike normal enumeration all slots are exposed here as + * is and return 'unused' if the slots are not in active use. In particular + * the array part is included for the full a_size regardless of what the + * array .length is. + */ + + duk_debug_write_reply(thr); + for (idx = idx_start; idx < idx_end; idx++) { + if (!duk__debug_getprop_index(thr, heap, h_obj, idx)) { + break; + } + } + duk_debug_write_eom(thr); + return; + + fail_args: + duk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, "invalid args"); +} + +#endif /* DUK_USE_DEBUGGER_INSPECT */ + +/* + * Process incoming debug requests + * + * Individual request handlers can push temporaries on the value stack and + * rely on duk__debug_process_message() to restore the value stack top + * automatically. + */ + +/* Process one debug message. Automatically restore value stack top to its + * entry value, so that individual message handlers don't need exact value + * stack handling which is convenient. + */ +DUK_LOCAL void duk__debug_process_message(duk_hthread *thr) { + duk_heap *heap; + duk_uint8_t x; + duk_int32_t cmd; + duk_idx_t entry_top; + + DUK_ASSERT(thr != NULL); + heap = thr->heap; + DUK_ASSERT(heap != NULL); + + entry_top = duk_get_top(thr); + + x = duk_debug_read_byte(thr); + switch (x) { + case DUK_DBG_IB_REQUEST: { + cmd = duk_debug_read_int(thr); + switch (cmd) { + case DUK_DBG_CMD_BASICINFO: { + duk__debug_handle_basic_info(thr, heap); + break; + } + case DUK_DBG_CMD_TRIGGERSTATUS: { + duk__debug_handle_trigger_status(thr, heap); + break; + } + case DUK_DBG_CMD_PAUSE: { + duk__debug_handle_pause(thr, heap); + break; + } + case DUK_DBG_CMD_RESUME: { + duk__debug_handle_resume(thr, heap); + break; + } + case DUK_DBG_CMD_STEPINTO: + case DUK_DBG_CMD_STEPOVER: + case DUK_DBG_CMD_STEPOUT: { + duk__debug_handle_step(thr, heap, cmd); + break; + } + case DUK_DBG_CMD_LISTBREAK: { + duk__debug_handle_list_break(thr, heap); + break; + } + case DUK_DBG_CMD_ADDBREAK: { + duk__debug_handle_add_break(thr, heap); + break; + } + case DUK_DBG_CMD_DELBREAK: { + duk__debug_handle_del_break(thr, heap); + break; + } + case DUK_DBG_CMD_GETVAR: { + duk__debug_handle_get_var(thr, heap); + break; + } + case DUK_DBG_CMD_PUTVAR: { + duk__debug_handle_put_var(thr, heap); + break; + } + case DUK_DBG_CMD_GETCALLSTACK: { + duk__debug_handle_get_call_stack(thr, heap); + break; + } + case DUK_DBG_CMD_GETLOCALS: { + duk__debug_handle_get_locals(thr, heap); + break; + } + case DUK_DBG_CMD_EVAL: { + duk__debug_handle_eval(thr, heap); + break; + } + case DUK_DBG_CMD_DETACH: { + /* The actual detached_cb call is postponed to message loop so + * we don't need any special precautions here (just skip to EOM + * on the already closed connection). + */ + duk__debug_handle_detach(thr, heap); + break; + } +#if defined(DUK_USE_DEBUGGER_DUMPHEAP) + case DUK_DBG_CMD_DUMPHEAP: { + duk__debug_handle_dump_heap(thr, heap); + break; + } +#endif /* DUK_USE_DEBUGGER_DUMPHEAP */ + case DUK_DBG_CMD_GETBYTECODE: { + duk__debug_handle_get_bytecode(thr, heap); + break; + } + case DUK_DBG_CMD_APPREQUEST: { + duk__debug_handle_apprequest(thr, heap); + break; + } +#if defined(DUK_USE_DEBUGGER_INSPECT) + case DUK_DBG_CMD_GETHEAPOBJINFO: { + duk__debug_handle_get_heap_obj_info(thr, heap); + break; + } + case DUK_DBG_CMD_GETOBJPROPDESC: { + duk__debug_handle_get_obj_prop_desc(thr, heap); + break; + } + case DUK_DBG_CMD_GETOBJPROPDESCRANGE: { + duk__debug_handle_get_obj_prop_desc_range(thr, heap); + break; + } +#endif /* DUK_USE_DEBUGGER_INSPECT */ + default: { + DUK_D(DUK_DPRINT("debug command unsupported: %d", (int) cmd)); + duk_debug_write_error_eom(thr, DUK_DBG_ERR_UNSUPPORTED, "unsupported command"); + } + } /* switch cmd */ + break; + } + case DUK_DBG_IB_REPLY: { + DUK_D(DUK_DPRINT("debug reply, skipping")); + break; + } + case DUK_DBG_IB_ERROR: { + DUK_D(DUK_DPRINT("debug error, skipping")); + break; + } + case DUK_DBG_IB_NOTIFY: { + DUK_D(DUK_DPRINT("debug notify, skipping")); + break; + } + default: { + DUK_D(DUK_DPRINT("invalid initial byte, drop connection: %d", (int) x)); + goto fail; + } + } /* switch initial byte */ + + DUK_ASSERT(duk_get_top(thr) >= entry_top); + duk_set_top(thr, entry_top); + duk__debug_skip_to_eom(thr); + return; + + fail: + DUK_ASSERT(duk_get_top(thr) >= entry_top); + duk_set_top(thr, entry_top); + DUK__SET_CONN_BROKEN(thr, 1); + return; +} + +DUK_LOCAL void duk__check_resend_status(duk_hthread *thr) { + if (thr->heap->dbg_read_cb != NULL && thr->heap->dbg_state_dirty) { + duk_debug_send_status(thr); + thr->heap->dbg_state_dirty = 0; + } +} + +DUK_INTERNAL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t no_block) { +#if defined(DUK_USE_ASSERTIONS) + duk_idx_t entry_top; +#endif + duk_bool_t retval = 0; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); +#if defined(DUK_USE_ASSERTIONS) + entry_top = duk_get_top(thr); +#endif + + DUK_D(DUK_DPRINT("process debug messages: read_cb=%s, no_block=%ld, detaching=%ld, processing=%ld", + thr->heap->dbg_read_cb ? "not NULL" : "NULL", (long) no_block, + (long) thr->heap->dbg_detaching, (long) thr->heap->dbg_processing)); + DUK_DD(DUK_DDPRINT("top at entry: %ld", (long) duk_get_top(thr))); + + /* thr->heap->dbg_detaching may be != 0 if a debugger write outside + * the message loop caused a transport error and detach1() to run. + */ + DUK_ASSERT(thr->heap->dbg_detaching == 0 || thr->heap->dbg_detaching == 1); + DUK_ASSERT(thr->heap->dbg_processing == 0); + thr->heap->dbg_processing = 1; + + /* Ensure dirty state causes a Status even if never process any + * messages. This is expected by the bytecode executor when in + * the running state. + */ + duk__check_resend_status(thr); + + for (;;) { + /* Process messages until we're no longer paused or we peek + * and see there's nothing to read right now. + */ + DUK_DD(DUK_DDPRINT("top at loop top: %ld", (long) duk_get_top(thr))); + DUK_ASSERT(thr->heap->dbg_processing == 1); + + while (thr->heap->dbg_read_cb == NULL && thr->heap->dbg_detaching) { + /* Detach is pending; can be triggered from outside the + * debugger loop (e.g. Status notify write error) or by + * previous message handling. Call detached callback + * here, in a controlled state, to ensure a possible + * reattach inside the detached_cb is handled correctly. + * + * Recheck for detach in a while loop: an immediate + * reattach involves a call to duk_debugger_attach() + * which writes a debugger handshake line immediately + * inside the API call. If the transport write fails + * for that handshake, we can immediately end up in a + * "transport broken, detaching" case several times here. + * Loop back until we're either cleanly attached or + * fully detached. + * + * NOTE: Reset dbg_processing = 1 forcibly, in case we + * re-attached; duk_debugger_attach() sets dbg_processing + * to 0 at the moment. + */ + + DUK_D(DUK_DPRINT("detach pending (dbg_read_cb == NULL, dbg_detaching != 0), call detach2")); + + duk__debug_do_detach2(thr->heap); + thr->heap->dbg_processing = 1; /* may be set to 0 by duk_debugger_attach() inside callback */ + + DUK_D(DUK_DPRINT("after detach2 (and possible reattach): dbg_read_cb=%s, dbg_detaching=%ld", + thr->heap->dbg_read_cb ? "not NULL" : "NULL", (long) thr->heap->dbg_detaching)); + } + DUK_ASSERT(thr->heap->dbg_detaching == 0); /* true even with reattach */ + DUK_ASSERT(thr->heap->dbg_processing == 1); /* even after a detach and possible reattach */ + + if (thr->heap->dbg_read_cb == NULL) { + DUK_D(DUK_DPRINT("debug connection broken (and not detaching), stop processing messages")); + break; + } + + if (!DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) || no_block) { + if (!duk_debug_read_peek(thr)) { + /* Note: peek cannot currently trigger a detach + * so the dbg_detaching == 0 assert outside the + * loop is correct. + */ + DUK_D(DUK_DPRINT("processing debug message, peek indicated no data, stop processing messages")); + break; + } + DUK_D(DUK_DPRINT("processing debug message, peek indicated there is data, handle it")); + } else { + DUK_D(DUK_DPRINT("paused, process debug message, blocking if necessary")); + } + + duk__check_resend_status(thr); + duk__debug_process_message(thr); + duk__check_resend_status(thr); + + retval = 1; /* processed one or more messages */ + } + + DUK_ASSERT(thr->heap->dbg_detaching == 0); + DUK_ASSERT(thr->heap->dbg_processing == 1); + thr->heap->dbg_processing = 0; + + /* As an initial implementation, read flush after exiting the message + * loop. If transport is broken, this is a no-op (with debug logs). + */ + duk_debug_read_flush(thr); /* this cannot initiate a detach */ + DUK_ASSERT(thr->heap->dbg_detaching == 0); + + DUK_DD(DUK_DDPRINT("top at exit: %ld", (long) duk_get_top(thr))); + +#if defined(DUK_USE_ASSERTIONS) + /* Easy to get wrong, so assert for it. */ + DUK_ASSERT(entry_top == duk_get_top(thr)); +#endif + + return retval; +} + +/* + * Halt execution helper + */ + +/* Halt execution and enter a debugger message loop until execution is resumed + * by the client. PC for the current activation may be temporarily decremented + * so that the "current" instruction will be shown by the client. This helper + * is callable from anywhere, also outside bytecode executor. + */ + +DUK_INTERNAL void duk_debug_halt_execution(duk_hthread *thr, duk_bool_t use_prev_pc) { + duk_activation *act; + duk_hcompfunc *fun; + duk_instr_t *old_pc = NULL; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(duk_debug_is_attached(thr->heap)); + DUK_ASSERT(thr->heap->dbg_processing == 0); + DUK_ASSERT(!duk_debug_is_paused(thr->heap)); + + duk_debug_set_paused(thr->heap); + + act = thr->callstack_curr; + + /* NOTE: act may be NULL if an error is thrown outside of any activation, + * which may happen in the case of, e.g. syntax errors. + */ + + /* Decrement PC if that was requested, this requires a PC sync. */ + if (act != NULL) { + duk_hthread_sync_currpc(thr); + old_pc = act->curr_pc; + fun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act); + + /* Short circuit if is safe: if act->curr_pc != NULL, 'fun' is + * guaranteed to be a non-NULL ECMAScript function. + */ + DUK_ASSERT(act->curr_pc == NULL || + (fun != NULL && DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun))); + if (use_prev_pc && + act->curr_pc != NULL && + act->curr_pc > DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, fun)) { + act->curr_pc--; + } + } + + /* Process debug messages until we are no longer paused. */ + + /* NOTE: This is a bit fragile. It's important to ensure that + * duk_debug_process_messages() never throws an error or + * act->curr_pc will never be reset. + */ + + thr->heap->dbg_state_dirty = 1; + while (DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap)) { + DUK_ASSERT(duk_debug_is_attached(thr->heap)); + DUK_ASSERT(thr->heap->dbg_processing == 0); + duk_debug_process_messages(thr, 0 /*no_block*/); + } + + /* XXX: Decrementing and restoring act->curr_pc works now, but if the + * debugger message loop gains the ability to adjust the current PC + * (e.g. a forced jump) restoring the PC here will break. Another + * approach would be to use a state flag for the "decrement 1 from + * topmost activation's PC" and take it into account whenever dealing + * with PC values. + */ + if (act != NULL) { + act->curr_pc = old_pc; /* restore PC */ + } +} + +/* + * Breakpoint management + */ + +DUK_INTERNAL duk_small_int_t duk_debug_add_breakpoint(duk_hthread *thr, duk_hstring *filename, duk_uint32_t line) { + duk_heap *heap; + duk_breakpoint *b; + + /* Caller must trigger recomputation of active breakpoint list. To + * ensure stale values are not used if that doesn't happen, clear the + * active breakpoint list here. + */ + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(filename != NULL); + heap = thr->heap; + DUK_ASSERT(heap != NULL); + + if (heap->dbg_breakpoint_count >= DUK_HEAP_MAX_BREAKPOINTS) { + DUK_D(DUK_DPRINT("failed to add breakpoint for %O:%ld, all breakpoint slots used", + (duk_heaphdr *) filename, (long) line)); + return -1; + } + heap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL; + b = heap->dbg_breakpoints + (heap->dbg_breakpoint_count++); + b->filename = filename; + b->line = line; + DUK_HSTRING_INCREF(thr, filename); + + return (duk_small_int_t) (heap->dbg_breakpoint_count - 1); /* index */ +} + +DUK_INTERNAL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_small_uint_t breakpoint_index) { + duk_heap *heap; + duk_hstring *h; + duk_breakpoint *b; + duk_size_t move_size; + + /* Caller must trigger recomputation of active breakpoint list. To + * ensure stale values are not used if that doesn't happen, clear the + * active breakpoint list here. + */ + + DUK_ASSERT(thr != NULL); + heap = thr->heap; + DUK_ASSERT(heap != NULL); + DUK_ASSERT(duk_debug_is_attached(thr->heap)); + DUK_ASSERT_DISABLE(breakpoint_index >= 0); /* unsigned */ + + if (breakpoint_index >= heap->dbg_breakpoint_count) { + DUK_D(DUK_DPRINT("invalid breakpoint index: %ld", (long) breakpoint_index)); + return 0; + } + b = heap->dbg_breakpoints + breakpoint_index; + + h = b->filename; + DUK_ASSERT(h != NULL); + + move_size = sizeof(duk_breakpoint) * (heap->dbg_breakpoint_count - breakpoint_index - 1); + duk_memmove((void *) b, + (const void *) (b + 1), + (size_t) move_size); + + heap->dbg_breakpoint_count--; + heap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL; + + DUK_HSTRING_DECREF(thr, h); /* side effects */ + DUK_UNREF(h); /* w/o refcounting */ + + /* Breakpoint entries above the used area are left as garbage. */ + + return 1; +} + +/* + * Misc state management + */ + +DUK_INTERNAL duk_bool_t duk_debug_is_attached(duk_heap *heap) { + return (heap->dbg_read_cb != NULL); +} + +DUK_INTERNAL duk_bool_t duk_debug_is_paused(duk_heap *heap) { + return (DUK_HEAP_HAS_DEBUGGER_PAUSED(heap) != 0); +} + +DUK_INTERNAL void duk_debug_set_paused(duk_heap *heap) { + if (duk_debug_is_paused(heap)) { + DUK_D(DUK_DPRINT("trying to set paused state when already paused, ignoring")); + } else { + DUK_HEAP_SET_DEBUGGER_PAUSED(heap); + heap->dbg_state_dirty = 1; + duk_debug_clear_pause_state(heap); + DUK_ASSERT(heap->ms_running == 0); /* debugger can't be triggered within mark-and-sweep */ + heap->ms_running = 2; /* prevent mark-and-sweep, prevent refzero queueing */ + heap->ms_prevent_count++; + DUK_ASSERT(heap->ms_prevent_count != 0); /* Wrap. */ + DUK_ASSERT(heap->heap_thread != NULL); + } +} + +DUK_INTERNAL void duk_debug_clear_paused(duk_heap *heap) { + if (duk_debug_is_paused(heap)) { + DUK_HEAP_CLEAR_DEBUGGER_PAUSED(heap); + heap->dbg_state_dirty = 1; + duk_debug_clear_pause_state(heap); + DUK_ASSERT(heap->ms_running == 2); + DUK_ASSERT(heap->ms_prevent_count > 0); + heap->ms_prevent_count--; + heap->ms_running = 0; + DUK_ASSERT(heap->heap_thread != NULL); + } else { + DUK_D(DUK_DPRINT("trying to clear paused state when not paused, ignoring")); + } +} + +DUK_INTERNAL void duk_debug_clear_pause_state(duk_heap *heap) { + heap->dbg_pause_flags = 0; + heap->dbg_pause_act = NULL; + heap->dbg_pause_startline = 0; +} + +#else /* DUK_USE_DEBUGGER_SUPPORT */ + +/* No debugger support. */ + +#endif /* DUK_USE_DEBUGGER_SUPPORT */ diff --git a/third_party/duktape/duk_debugger.h b/third_party/duktape/duk_debugger.h new file mode 100644 index 00000000..ea62b022 --- /dev/null +++ b/third_party/duktape/duk_debugger.h @@ -0,0 +1,151 @@ +#if !defined(DUK_DEBUGGER_H_INCLUDED) +#define DUK_DEBUGGER_H_INCLUDED + +/* Debugger protocol version is defined in the public API header. */ + +/* Initial bytes for markers. */ +#define DUK_DBG_IB_EOM 0x00 +#define DUK_DBG_IB_REQUEST 0x01 +#define DUK_DBG_IB_REPLY 0x02 +#define DUK_DBG_IB_ERROR 0x03 +#define DUK_DBG_IB_NOTIFY 0x04 + +/* Other initial bytes. */ +#define DUK_DBG_IB_INT4 0x10 +#define DUK_DBG_IB_STR4 0x11 +#define DUK_DBG_IB_STR2 0x12 +#define DUK_DBG_IB_BUF4 0x13 +#define DUK_DBG_IB_BUF2 0x14 +#define DUK_DBG_IB_UNUSED 0x15 +#define DUK_DBG_IB_UNDEFINED 0x16 +#define DUK_DBG_IB_NULL 0x17 +#define DUK_DBG_IB_TRUE 0x18 +#define DUK_DBG_IB_FALSE 0x19 +#define DUK_DBG_IB_NUMBER 0x1a +#define DUK_DBG_IB_OBJECT 0x1b +#define DUK_DBG_IB_POINTER 0x1c +#define DUK_DBG_IB_LIGHTFUNC 0x1d +#define DUK_DBG_IB_HEAPPTR 0x1e +/* The short string/integer initial bytes starting from 0x60 don't have + * defines now. + */ + +/* Error codes. */ +#define DUK_DBG_ERR_UNKNOWN 0x00 +#define DUK_DBG_ERR_UNSUPPORTED 0x01 +#define DUK_DBG_ERR_TOOMANY 0x02 +#define DUK_DBG_ERR_NOTFOUND 0x03 +#define DUK_DBG_ERR_APPLICATION 0x04 + +/* Commands and notifys initiated by Duktape. */ +#define DUK_DBG_CMD_STATUS 0x01 +#define DUK_DBG_CMD_UNUSED_2 0x02 /* Duktape 1.x: print notify */ +#define DUK_DBG_CMD_UNUSED_3 0x03 /* Duktape 1.x: alert notify */ +#define DUK_DBG_CMD_UNUSED_4 0x04 /* Duktape 1.x: log notify */ +#define DUK_DBG_CMD_THROW 0x05 +#define DUK_DBG_CMD_DETACHING 0x06 +#define DUK_DBG_CMD_APPNOTIFY 0x07 + +/* Commands initiated by debug client. */ +#define DUK_DBG_CMD_BASICINFO 0x10 +#define DUK_DBG_CMD_TRIGGERSTATUS 0x11 +#define DUK_DBG_CMD_PAUSE 0x12 +#define DUK_DBG_CMD_RESUME 0x13 +#define DUK_DBG_CMD_STEPINTO 0x14 +#define DUK_DBG_CMD_STEPOVER 0x15 +#define DUK_DBG_CMD_STEPOUT 0x16 +#define DUK_DBG_CMD_LISTBREAK 0x17 +#define DUK_DBG_CMD_ADDBREAK 0x18 +#define DUK_DBG_CMD_DELBREAK 0x19 +#define DUK_DBG_CMD_GETVAR 0x1a +#define DUK_DBG_CMD_PUTVAR 0x1b +#define DUK_DBG_CMD_GETCALLSTACK 0x1c +#define DUK_DBG_CMD_GETLOCALS 0x1d +#define DUK_DBG_CMD_EVAL 0x1e +#define DUK_DBG_CMD_DETACH 0x1f +#define DUK_DBG_CMD_DUMPHEAP 0x20 +#define DUK_DBG_CMD_GETBYTECODE 0x21 +#define DUK_DBG_CMD_APPREQUEST 0x22 +#define DUK_DBG_CMD_GETHEAPOBJINFO 0x23 +#define DUK_DBG_CMD_GETOBJPROPDESC 0x24 +#define DUK_DBG_CMD_GETOBJPROPDESCRANGE 0x25 + +/* The low 8 bits map directly to duk_hobject.h DUK_PROPDESC_FLAG_xxx. + * The remaining flags are specific to the debugger. + */ +#define DUK_DBG_PROPFLAG_SYMBOL (1U << 8) +#define DUK_DBG_PROPFLAG_HIDDEN (1U << 9) + +#if defined(DUK_USE_DEBUGGER_SUPPORT) +DUK_INTERNAL_DECL void duk_debug_do_detach(duk_heap *heap); + +DUK_INTERNAL_DECL duk_bool_t duk_debug_read_peek(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_debug_write_flush(duk_hthread *thr); + +DUK_INTERNAL_DECL void duk_debug_skip_bytes(duk_hthread *thr, duk_size_t length); +DUK_INTERNAL_DECL void duk_debug_skip_byte(duk_hthread *thr); + +DUK_INTERNAL_DECL void duk_debug_read_bytes(duk_hthread *thr, duk_uint8_t *data, duk_size_t length); +DUK_INTERNAL_DECL duk_uint8_t duk_debug_read_byte(duk_hthread *thr); +DUK_INTERNAL_DECL duk_int32_t duk_debug_read_int(duk_hthread *thr); +DUK_INTERNAL_DECL duk_hstring *duk_debug_read_hstring(duk_hthread *thr); +/* XXX: exposed duk_debug_read_pointer */ +/* XXX: exposed duk_debug_read_buffer */ +/* XXX: exposed duk_debug_read_hbuffer */ +#if 0 +DUK_INTERNAL_DECL duk_heaphdr *duk_debug_read_heapptr(duk_hthread *thr); +#endif +#if defined(DUK_USE_DEBUGGER_INSPECT) +DUK_INTERNAL_DECL duk_heaphdr *duk_debug_read_any_ptr(duk_hthread *thr); +#endif +DUK_INTERNAL_DECL duk_tval *duk_debug_read_tval(duk_hthread *thr); + +DUK_INTERNAL_DECL void duk_debug_write_bytes(duk_hthread *thr, const duk_uint8_t *data, duk_size_t length); +DUK_INTERNAL_DECL void duk_debug_write_byte(duk_hthread *thr, duk_uint8_t x); +DUK_INTERNAL_DECL void duk_debug_write_unused(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_debug_write_undefined(duk_hthread *thr); +#if defined(DUK_USE_DEBUGGER_INSPECT) +DUK_INTERNAL_DECL void duk_debug_write_null(duk_hthread *thr); +#endif +DUK_INTERNAL_DECL void duk_debug_write_boolean(duk_hthread *thr, duk_uint_t val); +DUK_INTERNAL_DECL void duk_debug_write_int(duk_hthread *thr, duk_int32_t x); +DUK_INTERNAL_DECL void duk_debug_write_uint(duk_hthread *thr, duk_uint32_t x); +DUK_INTERNAL_DECL void duk_debug_write_string(duk_hthread *thr, const char *data, duk_size_t length); +DUK_INTERNAL_DECL void duk_debug_write_cstring(duk_hthread *thr, const char *data); +DUK_INTERNAL_DECL void duk_debug_write_hstring(duk_hthread *thr, duk_hstring *h); +DUK_INTERNAL_DECL void duk_debug_write_buffer(duk_hthread *thr, const char *data, duk_size_t length); +DUK_INTERNAL_DECL void duk_debug_write_hbuffer(duk_hthread *thr, duk_hbuffer *h); +DUK_INTERNAL_DECL void duk_debug_write_pointer(duk_hthread *thr, void *ptr); +#if defined(DUK_USE_DEBUGGER_DUMPHEAP) || defined(DUK_USE_DEBUGGER_INSPECT) +DUK_INTERNAL_DECL void duk_debug_write_heapptr(duk_hthread *thr, duk_heaphdr *h); +#endif +DUK_INTERNAL_DECL void duk_debug_write_hobject(duk_hthread *thr, duk_hobject *obj); +DUK_INTERNAL_DECL void duk_debug_write_tval(duk_hthread *thr, duk_tval *tv); +#if 0 /* unused */ +DUK_INTERNAL_DECL void duk_debug_write_request(duk_hthread *thr, duk_small_uint_t command); +#endif +DUK_INTERNAL_DECL void duk_debug_write_reply(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_debug_write_error_eom(duk_hthread *thr, duk_small_uint_t err_code, const char *msg); +DUK_INTERNAL_DECL void duk_debug_write_notify(duk_hthread *thr, duk_small_uint_t command); +DUK_INTERNAL_DECL void duk_debug_write_eom(duk_hthread *thr); + +DUK_INTERNAL_DECL duk_uint_fast32_t duk_debug_curr_line(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_debug_send_status(duk_hthread *thr); +#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY) +DUK_INTERNAL_DECL void duk_debug_send_throw(duk_hthread *thr, duk_bool_t fatal); +#endif + +DUK_INTERNAL_DECL void duk_debug_halt_execution(duk_hthread *thr, duk_bool_t use_prev_pc); +DUK_INTERNAL_DECL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t no_block); + +DUK_INTERNAL_DECL duk_small_int_t duk_debug_add_breakpoint(duk_hthread *thr, duk_hstring *filename, duk_uint32_t line); +DUK_INTERNAL_DECL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_small_uint_t breakpoint_index); + +DUK_INTERNAL_DECL duk_bool_t duk_debug_is_attached(duk_heap *heap); +DUK_INTERNAL_DECL duk_bool_t duk_debug_is_paused(duk_heap *heap); +DUK_INTERNAL_DECL void duk_debug_set_paused(duk_heap *heap); +DUK_INTERNAL_DECL void duk_debug_clear_paused(duk_heap *heap); +DUK_INTERNAL_DECL void duk_debug_clear_pause_state(duk_heap *heap); +#endif /* DUK_USE_DEBUGGER_SUPPORT */ + +#endif /* DUK_DEBUGGER_H_INCLUDED */ diff --git a/third_party/duktape/duk_error.h b/third_party/duktape/duk_error.h new file mode 100644 index 00000000..dcfd618e --- /dev/null +++ b/third_party/duktape/duk_error.h @@ -0,0 +1,525 @@ +/* + * Error handling macros, assertion macro, error codes. + * + * There are three types of 'errors': + * + * 1. Ordinary errors relative to a thread, cause a longjmp, catchable. + * 2. Fatal errors relative to a heap, cause fatal handler to be called. + * 3. Fatal errors without context, cause the default (not heap specific) + * fatal handler to be called. + * + * Fatal errors without context are used by debug code such as assertions. + * By providing a fatal error handler for a Duktape heap, user code can + * avoid fatal errors without context in non-debug builds. + */ + +#if !defined(DUK_ERROR_H_INCLUDED) +#define DUK_ERROR_H_INCLUDED + +/* + * Error codes: defined in duktape.h + * + * Error codes are used as a shorthand to throw exceptions from inside + * the implementation. The appropriate ECMAScript object is constructed + * based on the code. ECMAScript code throws objects directly. The error + * codes are defined in the public API header because they are also used + * by calling code. + */ + +/* + * Normal error + * + * Normal error is thrown with a longjmp() through the current setjmp() + * catchpoint record in the duk_heap. The 'curr_thread' of the duk_heap + * identifies the throwing thread. + * + * Error formatting is usually unnecessary. The error macros provide a + * zero argument version (no formatting) and separate macros for small + * argument counts. Variadic macros are not used to avoid portability + * issues and avoid the need for stash-based workarounds when they're not + * available. Vararg calls are avoided for non-formatted error calls + * because vararg call sites are larger than normal, and there are a lot + * of call sites with no formatting. + * + * Note that special formatting provided by debug macros is NOT available. + * + * The _RAW variants allow the caller to specify file and line. This makes + * it easier to write checked calls which want to use the call site of the + * checked function, not the error macro call inside the checked function. + */ + +#if defined(DUK_USE_VERBOSE_ERRORS) + +/* Because there are quite many call sites, pack error code (require at most + * 8-bit) into a single argument. + */ +#define DUK_ERROR(thr,err,msg) do { \ + duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \ + DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ + duk_err_handle_error((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (msg)); \ + } while (0) +#define DUK_ERROR_RAW(thr,file,line,err,msg) do { \ + duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \ + DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ + duk_err_handle_error((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (msg)); \ + } while (0) + +#define DUK_ERROR_FMT1(thr,err,fmt,arg1) do { \ + duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \ + DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ + duk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1)); \ + } while (0) +#define DUK_ERROR_RAW_FMT1(thr,file,line,err,fmt,arg1) do { \ + duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \ + DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ + duk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1)); \ + } while (0) + +#define DUK_ERROR_FMT2(thr,err,fmt,arg1,arg2) do { \ + duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \ + DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ + duk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2)); \ + } while (0) +#define DUK_ERROR_RAW_FMT2(thr,file,line,err,fmt,arg1,arg2) do { \ + duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \ + DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ + duk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2)); \ + } while (0) + +#define DUK_ERROR_FMT3(thr,err,fmt,arg1,arg2,arg3) do { \ + duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \ + DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ + duk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3)); \ + } while (0) +#define DUK_ERROR_RAW_FMT3(thr,file,line,err,fmt,arg1,arg2,arg3) do { \ + duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \ + DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ + duk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3)); \ + } while (0) + +#define DUK_ERROR_FMT4(thr,err,fmt,arg1,arg2,arg3,arg4) do { \ + duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \ + DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ + duk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3), (arg4)); \ + } while (0) +#define DUK_ERROR_RAW_FMT4(thr,file,line,err,fmt,arg1,arg2,arg3,arg4) do { \ + duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \ + DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ + duk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3), (arg4)); \ + } while (0) + +#else /* DUK_USE_VERBOSE_ERRORS */ + +#define DUK_ERROR(thr,err,msg) duk_err_handle_error((thr), (err)) +#define DUK_ERROR_RAW(thr,file,line,err,msg) duk_err_handle_error((thr), (err)) + +#define DUK_ERROR_FMT1(thr,err,fmt,arg1) DUK_ERROR((thr),(err),(fmt)) +#define DUK_ERROR_RAW_FMT1(thr,file,line,err,fmt,arg1) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt)) + +#define DUK_ERROR_FMT2(thr,err,fmt,arg1,arg2) DUK_ERROR((thr),(err),(fmt)) +#define DUK_ERROR_RAW_FMT2(thr,file,line,err,fmt,arg1,arg2) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt)) + +#define DUK_ERROR_FMT3(thr,err,fmt,arg1,arg2,arg3) DUK_ERROR((thr),(err),(fmt)) +#define DUK_ERROR_RAW_FMT3(thr,file,line,err,fmt,arg1,arg2,arg3) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt)) + +#define DUK_ERROR_FMT4(thr,err,fmt,arg1,arg2,arg3,arg4) DUK_ERROR((thr),(err),(fmt)) +#define DUK_ERROR_RAW_FMT4(thr,file,line,err,fmt,arg1,arg2,arg3,arg4) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt)) + +#endif /* DUK_USE_VERBOSE_ERRORS */ + +/* + * Fatal error without context + * + * The macro is an expression to make it compatible with DUK_ASSERT_EXPR(). + */ + +#define DUK_FATAL_WITHOUT_CONTEXT(msg) \ + duk_default_fatal_handler(NULL, (msg)) + +/* + * Error throwing helpers + * + * The goal is to provide verbose and configurable error messages. Call + * sites should be clean in source code and compile to a small footprint. + * Small footprint is also useful for performance because small cold paths + * reduce code cache pressure. Adding macros here only makes sense if there + * are enough call sites to get concrete benefits. + * + * DUK_ERROR_xxx() macros are generic and can be used anywhere. + * + * DUK_DCERROR_xxx() macros can only be used in Duktape/C functions where + * the "return DUK_RET_xxx;" shorthand is available for low memory targets. + * The DUK_DCERROR_xxx() macros always either throw or perform a + * 'return DUK_RET_xxx' from the calling function. + */ + +#if defined(DUK_USE_VERBOSE_ERRORS) +/* Verbose errors with key/value summaries (non-paranoid) or without key/value + * summaries (paranoid, for some security sensitive environments), the paranoid + * vs. non-paranoid distinction affects only a few specific errors. + */ +#if defined(DUK_USE_PARANOID_ERRORS) +#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \ + duk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx), (expectname)); \ + } while (0) +#else /* DUK_USE_PARANOID_ERRORS */ +#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \ + duk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx), (expectname)); \ + } while (0) +#endif /* DUK_USE_PARANOID_ERRORS */ + +#define DUK_ERROR_INTERNAL(thr) do { \ + duk_err_error_internal((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ + } while (0) +#define DUK_DCERROR_INTERNAL(thr) do { \ + DUK_ERROR_INTERNAL((thr)); \ + return 0; \ + } while (0) +#define DUK_ERROR_ALLOC_FAILED(thr) do { \ + duk_err_error_alloc_failed((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ + } while (0) +#define DUK_ERROR_UNSUPPORTED(thr) do { \ + DUK_ERROR((thr), DUK_ERR_ERROR, DUK_STR_UNSUPPORTED); \ + } while (0) +#define DUK_DCERROR_UNSUPPORTED(thr) do { \ + DUK_ERROR_UNSUPPORTED((thr)); \ + return 0; \ + } while (0) +#define DUK_ERROR_ERROR(thr,msg) do { \ + duk_err_error((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \ + } while (0) +#define DUK_ERROR_RANGE_INDEX(thr,idx) do { \ + duk_err_range_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx)); \ + } while (0) +#define DUK_ERROR_RANGE_PUSH_BEYOND(thr) do { \ + duk_err_range_push_beyond((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ + } while (0) +#define DUK_ERROR_RANGE_INVALID_ARGS(thr) do { \ + DUK_ERROR_RANGE((thr), DUK_STR_INVALID_ARGS); \ + } while (0) +#define DUK_DCERROR_RANGE_INVALID_ARGS(thr) do { \ + DUK_ERROR_RANGE_INVALID_ARGS((thr)); \ + return 0; \ + } while (0) +#define DUK_ERROR_RANGE_INVALID_COUNT(thr) do { \ + DUK_ERROR_RANGE((thr), DUK_STR_INVALID_COUNT); \ + } while (0) +#define DUK_DCERROR_RANGE_INVALID_COUNT(thr) do { \ + DUK_ERROR_RANGE_INVALID_COUNT((thr)); \ + return 0; \ + } while (0) +#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) do { \ + DUK_ERROR_RANGE((thr), DUK_STR_INVALID_LENGTH); \ + } while (0) +#define DUK_DCERROR_RANGE_INVALID_LENGTH(thr) do { \ + DUK_ERROR_RANGE_INVALID_LENGTH((thr)); \ + return 0; \ + } while (0) +#define DUK_ERROR_RANGE(thr,msg) do { \ + duk_err_range((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \ + } while (0) +#define DUK_ERROR_EVAL(thr,msg) do { \ + DUK_ERROR((thr), DUK_ERR_EVAL_ERROR, (msg)); \ + } while (0) +#define DUK_ERROR_REFERENCE(thr,msg) do { \ + DUK_ERROR((thr), DUK_ERR_REFERENCE_ERROR, (msg)); \ + } while (0) +#define DUK_ERROR_SYNTAX(thr,msg) do { \ + DUK_ERROR((thr), DUK_ERR_SYNTAX_ERROR, (msg)); \ + } while (0) +#define DUK_ERROR_TYPE_INVALID_ARGS(thr) do { \ + duk_err_type_invalid_args((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ + } while (0) +#define DUK_DCERROR_TYPE_INVALID_ARGS(thr) do { \ + DUK_ERROR_TYPE_INVALID_ARGS((thr)); \ + return 0; \ + } while (0) +#define DUK_ERROR_TYPE_INVALID_STATE(thr) do { \ + duk_err_type_invalid_state((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ + } while (0) +#define DUK_DCERROR_TYPE_INVALID_STATE(thr) do { \ + DUK_ERROR_TYPE_INVALID_STATE((thr)); \ + return 0; \ + } while (0) +#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \ + duk_err_type_invalid_trap_result((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ + } while (0) +#define DUK_DCERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \ + DUK_ERROR_TYPE((thr), DUK_STR_INVALID_TRAP_RESULT); \ + } while (0) +#define DUK_ERROR_TYPE(thr,msg) do { \ + DUK_ERROR((thr), DUK_ERR_TYPE_ERROR, (msg)); \ + } while (0) +#define DUK_ERROR_URI(thr,msg) do { \ + DUK_ERROR((thr), DUK_ERR_URI_ERROR, (msg)); \ + } while (0) +#else /* DUK_USE_VERBOSE_ERRORS */ +/* Non-verbose errors for low memory targets: no file, line, or message. */ + +#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \ + duk_err_type((thr)); \ + } while (0) + +#define DUK_ERROR_INTERNAL(thr) do { \ + duk_err_error((thr)); \ + } while (0) +#define DUK_DCERROR_INTERNAL(thr) do { \ + DUK_UNREF((thr)); \ + return DUK_RET_ERROR; \ + } while (0) +#define DUK_ERROR_ALLOC_FAILED(thr) do { \ + duk_err_error((thr)); \ + } while (0) +#define DUK_ERROR_UNSUPPORTED(thr) do { \ + duk_err_error((thr)); \ + } while (0) +#define DUK_DCERROR_UNSUPPORTED(thr) do { \ + DUK_UNREF((thr)); \ + return DUK_RET_ERROR; \ + } while (0) +#define DUK_ERROR_ERROR(thr,msg) do { \ + duk_err_error((thr)); \ + } while (0) +#define DUK_ERROR_RANGE_INDEX(thr,idx) do { \ + duk_err_range((thr)); \ + } while (0) +#define DUK_ERROR_RANGE_PUSH_BEYOND(thr) do { \ + duk_err_range((thr)); \ + } while (0) +#define DUK_ERROR_RANGE_INVALID_ARGS(thr) do { \ + duk_err_range((thr)); \ + } while (0) +#define DUK_DCERROR_RANGE_INVALID_ARGS(thr) do { \ + DUK_UNREF((thr)); \ + return DUK_RET_RANGE_ERROR; \ + } while (0) +#define DUK_ERROR_RANGE_INVALID_COUNT(thr) do { \ + duk_err_range((thr)); \ + } while (0) +#define DUK_DCERROR_RANGE_INVALID_COUNT(thr) do { \ + DUK_UNREF((thr)); \ + return DUK_RET_RANGE_ERROR; \ + } while (0) +#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) do { \ + duk_err_range((thr)); \ + } while (0) +#define DUK_DCERROR_RANGE_INVALID_LENGTH(thr) do { \ + DUK_UNREF((thr)); \ + return DUK_RET_RANGE_ERROR; \ + } while (0) +#define DUK_ERROR_RANGE(thr,msg) do { \ + duk_err_range((thr)); \ + } while (0) +#define DUK_ERROR_EVAL(thr,msg) do { \ + duk_err_eval((thr)); \ + } while (0) +#define DUK_ERROR_REFERENCE(thr,msg) do { \ + duk_err_reference((thr)); \ + } while (0) +#define DUK_ERROR_SYNTAX(thr,msg) do { \ + duk_err_syntax((thr)); \ + } while (0) +#define DUK_ERROR_TYPE_INVALID_ARGS(thr) do { \ + duk_err_type((thr)); \ + } while (0) +#define DUK_DCERROR_TYPE_INVALID_ARGS(thr) do { \ + DUK_UNREF((thr)); \ + return DUK_RET_TYPE_ERROR; \ + } while (0) +#define DUK_ERROR_TYPE_INVALID_STATE(thr) do { \ + duk_err_type((thr)); \ + } while (0) +#define DUK_DCERROR_TYPE_INVALID_STATE(thr) do { \ + duk_err_type((thr)); \ + } while (0) +#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \ + duk_err_type((thr)); \ + } while (0) +#define DUK_DCERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \ + DUK_UNREF((thr)); \ + return DUK_RET_TYPE_ERROR; \ + } while (0) +#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \ + duk_err_type((thr)); \ + } while (0) +#define DUK_ERROR_TYPE(thr,msg) do { \ + duk_err_type((thr)); \ + } while (0) +#define DUK_ERROR_URI(thr,msg) do { \ + duk_err_uri((thr)); \ + } while (0) +#endif /* DUK_USE_VERBOSE_ERRORS */ + +/* + * Assert macro: failure causes a fatal error. + * + * NOTE: since the assert macro doesn't take a heap/context argument, there's + * no way to look up a heap/context specific fatal error handler which may have + * been given by the application. Instead, assertion failures always use the + * internal default fatal error handler; it can be replaced via duk_config.h + * and then applies to all Duktape heaps. + */ + +#if defined(DUK_USE_ASSERTIONS) + +/* The message should be a compile time constant without formatting (less risk); + * we don't care about assertion text size because they're not used in production + * builds. + */ +#define DUK_ASSERT(x) do { \ + if (!(x)) { \ + DUK_FATAL_WITHOUT_CONTEXT("assertion failed: " #x \ + " (" DUK_FILE_MACRO ":" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) ")"); \ + } \ + } while (0) + +/* Assertion compatible inside a comma expression, evaluates to void. */ +#define DUK_ASSERT_EXPR(x) \ + ((void) ((x) ? 0 : (DUK_FATAL_WITHOUT_CONTEXT("assertion failed: " #x \ + " (" DUK_FILE_MACRO ":" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) ")"), 0))) + +#else /* DUK_USE_ASSERTIONS */ + +#define DUK_ASSERT(x) do { /* assertion omitted */ } while (0) + +#define DUK_ASSERT_EXPR(x) ((void) 0) + +#endif /* DUK_USE_ASSERTIONS */ + +/* this variant is used when an assert would generate a compile warning by + * being always true (e.g. >= 0 comparison for an unsigned value + */ +#define DUK_ASSERT_DISABLE(x) do { /* assertion disabled */ } while (0) + +/* + * Assertion helpers + */ + +#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING) +#define DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(h) do { \ + DUK_ASSERT((h) == NULL || DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) (h)) > 0); \ + } while (0) +#define DUK_ASSERT_REFCOUNT_NONZERO_TVAL(tv) do { \ + if ((tv) != NULL && DUK_TVAL_IS_HEAP_ALLOCATED((tv))) { \ + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(DUK_TVAL_GET_HEAPHDR((tv))) > 0); \ + } \ + } while (0) +#else +#define DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(h) /* no refcount check */ +#define DUK_ASSERT_REFCOUNT_NONZERO_TVAL(tv) /* no refcount check */ +#endif + +#define DUK_ASSERT_TOP(ctx,n) DUK_ASSERT((duk_idx_t) duk_get_top((ctx)) == (duk_idx_t) (n)) + +#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_PACKED_TVAL) +#define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval) do { \ + duk_double_union duk__assert_tmp_du; \ + duk__assert_tmp_du.d = (dval); \ + DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&duk__assert_tmp_du)); \ + } while (0) +#else +#define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval) /* nop */ +#endif + +#define DUK_ASSERT_VS_SPACE(thr) \ + DUK_ASSERT(thr->valstack_top < thr->valstack_end) + +/* + * Helper to initialize a memory area (e.g. struct) with garbage when + * assertions enabled. + */ + +#if defined(DUK_USE_ASSERTIONS) +#define DUK_ASSERT_SET_GARBAGE(ptr,size) do { \ + duk_memset_unsafe((void *) (ptr), 0x5a, size); \ + } while (0) +#else +#define DUK_ASSERT_SET_GARBAGE(ptr,size) do {} while (0) +#endif + +/* + * Helper for valstack space + * + * Caller of DUK_ASSERT_VALSTACK_SPACE() estimates the number of free stack entries + * required for its own use, and any child calls which are not (a) Duktape API calls + * or (b) Duktape calls which involve extending the valstack (e.g. getter call). + */ + +#define DUK_VALSTACK_ASSERT_EXTRA 5 /* this is added to checks to allow for Duktape + * API calls in addition to function's own use + */ +#if defined(DUK_USE_ASSERTIONS) +#define DUK_ASSERT_VALSTACK_SPACE(thr,n) do { \ + DUK_ASSERT((thr) != NULL); \ + DUK_ASSERT((thr)->valstack_end - (thr)->valstack_top >= (n) + DUK_VALSTACK_ASSERT_EXTRA); \ + } while (0) +#else +#define DUK_ASSERT_VALSTACK_SPACE(thr,n) /* no valstack space check */ +#endif + +/* + * Prototypes + */ + +#if defined(DUK_USE_VERBOSE_ERRORS) +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *msg)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error_fmt(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *fmt, ...)); +#else /* DUK_USE_VERBOSE_ERRORS */ +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error(duk_hthread *thr, duk_errcode_t code)); +#endif /* DUK_USE_VERBOSE_ERRORS */ + +#if defined(DUK_USE_VERBOSE_ERRORS) +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code, const char *msg, const char *filename, duk_int_t line)); +#else +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code)); +#endif + +DUK_NORETURN(DUK_INTERNAL_DECL void duk_error_throw_from_negative_rc(duk_hthread *thr, duk_ret_t rc)); + +#define DUK_AUGMENT_FLAG_NOBLAME_FILELINE (1U << 0) /* if set, don't blame C file/line for .fileName and .lineNumber */ +#define DUK_AUGMENT_FLAG_SKIP_ONE (1U << 1) /* if set, skip topmost activation in traceback construction */ + +#if defined(DUK_USE_AUGMENT_ERROR_CREATE) +DUK_INTERNAL_DECL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *filename, duk_int_t line, duk_small_uint_t flags); +#endif +#if defined(DUK_USE_AUGMENT_ERROR_THROW) +DUK_INTERNAL_DECL void duk_err_augment_error_throw(duk_hthread *thr); +#endif + +#if defined(DUK_USE_VERBOSE_ERRORS) +#if defined(DUK_USE_PARANOID_ERRORS) +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name)); +#else +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name)); +#endif +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error_alloc_failed(duk_hthread *thr, const char *filename, duk_int_t linenumber)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range_push_beyond(duk_hthread *thr, const char *filename, duk_int_t linenumber)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_args(duk_hthread *thr, const char *filename, duk_int_t linenumber)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_state(duk_hthread *thr, const char *filename, duk_int_t linenumber)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_trap_result(duk_hthread *thr, const char *filename, duk_int_t linenumber)); +#else /* DUK_VERBOSE_ERRORS */ +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error(duk_hthread *thr)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_eval(duk_hthread *thr)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_reference(duk_hthread *thr)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_syntax(duk_hthread *thr)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type(duk_hthread *thr)); +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_uri(duk_hthread *thr)); +#endif /* DUK_VERBOSE_ERRORS */ + +DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_longjmp(duk_hthread *thr)); + +DUK_NORETURN(DUK_INTERNAL_DECL void duk_default_fatal_handler(void *udata, const char *msg)); + +DUK_INTERNAL_DECL void duk_err_setup_ljstate1(duk_hthread *thr, duk_small_uint_t lj_type, duk_tval *tv_val); +#if defined(DUK_USE_DEBUGGER_SUPPORT) +DUK_INTERNAL_DECL void duk_err_check_debugger_integration(duk_hthread *thr); +#endif + +DUK_INTERNAL_DECL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, duk_errcode_t err_code); + +#endif /* DUK_ERROR_H_INCLUDED */ diff --git a/third_party/duktape/duk_error_augment.c b/third_party/duktape/duk_error_augment.c new file mode 100644 index 00000000..564e66ce --- /dev/null +++ b/third_party/duktape/duk_error_augment.c @@ -0,0 +1,588 @@ +/* + * Augmenting errors at their creation site and their throw site. + * + * When errors are created, traceback data is added by built-in code + * and a user error handler (if defined) can process or replace the + * error. Similarly, when errors are thrown, a user error handler + * (if defined) can process or replace the error. + * + * Augmentation and other processing at error creation time is nice + * because an error is only created once, but it may be thrown and + * rethrown multiple times. User error handler registered for processing + * an error at its throw site must be careful to handle rethrowing in + * a useful manner. + * + * Error augmentation may throw an internal error (e.g. alloc error). + * + * ECMAScript allows throwing any values, so all values cannot be + * augmented. Currently, the built-in augmentation at error creation + * only augments error values which are Error instances (= have the + * built-in Error.prototype in their prototype chain) and are also + * extensible. User error handlers have no limitations in this respect. + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Helper for calling a user error handler. + * + * 'thr' must be the currently active thread; the error handler is called + * in its context. The valstack of 'thr' must have the error value on + * top, and will be replaced by another error value based on the return + * value of the error handler. + * + * The helper calls duk_handle_call() recursively in protected mode. + * Before that call happens, no longjmps should happen; as a consequence, + * we must assume that the valstack contains enough temporary space for + * arguments and such. + * + * While the error handler runs, any errors thrown will not trigger a + * recursive error handler call (this is implemented using a heap level + * flag which will "follow" through any coroutines resumed inside the + * error handler). If the error handler is not callable or throws an + * error, the resulting error replaces the original error (for Duktape + * internal errors, duk_error_throw.c further substitutes this error with + * a DoubleError which is not ideal). This would be easy to change and + * even signal to the caller. + * + * The user error handler is stored in 'Duktape.errCreate' or + * 'Duktape.errThrow' depending on whether we're augmenting the error at + * creation or throw time. There are several alternatives to this approach, + * see doc/error-objects.rst for discussion. + * + * Note: since further longjmp()s may occur while calling the error handler + * (for many reasons, e.g. a labeled 'break' inside the handler), the + * caller can make no assumptions on the thr->heap->lj state after the + * call (this affects especially duk_error_throw.c). This is not an issue + * as long as the caller writes to the lj state only after the error handler + * finishes. + */ + +#if defined(DUK_USE_ERRTHROW) || defined(DUK_USE_ERRCREATE) +DUK_LOCAL void duk__err_augment_user(duk_hthread *thr, duk_small_uint_t stridx_cb) { + duk_tval *tv_hnd; + duk_int_t rc; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT_STRIDX_VALID(stridx_cb); + + if (thr->heap->augmenting_error) { + DUK_D(DUK_DPRINT("recursive call to error augmentation, ignore")); + return; + } + + /* + * Check whether or not we have an error handler. + * + * We must be careful of not triggering an error when looking up the + * property. For instance, if the property is a getter, we don't want + * to call it, only plain values are allowed. The value, if it exists, + * is not checked. If the value is not a function, a TypeError happens + * when it is called and that error replaces the original one. + */ + + DUK_ASSERT_VALSTACK_SPACE(thr, 4); /* 3 entries actually needed below */ + + /* [ ... errval ] */ + + if (thr->builtins[DUK_BIDX_DUKTAPE] == NULL) { + /* When creating built-ins, some of the built-ins may not be set + * and we want to tolerate that when throwing errors. + */ + DUK_DD(DUK_DDPRINT("error occurred when DUK_BIDX_DUKTAPE is NULL, ignoring")); + return; + } + tv_hnd = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, + thr->builtins[DUK_BIDX_DUKTAPE], + stridx_cb); + if (tv_hnd == NULL) { + DUK_DD(DUK_DDPRINT("error handler does not exist or is not a plain value: %!T", + (duk_tval *) tv_hnd)); + return; + } + DUK_DDD(DUK_DDDPRINT("error handler dump (callability not checked): %!T", + (duk_tval *) tv_hnd)); + duk_push_tval(thr, tv_hnd); + + /* [ ... errval errhandler ] */ + + duk_insert(thr, -2); /* -> [ ... errhandler errval ] */ + duk_push_undefined(thr); + duk_insert(thr, -2); /* -> [ ... errhandler undefined(= this) errval ] */ + + /* [ ... errhandler undefined errval ] */ + + /* + * heap->augmenting_error prevents recursive re-entry and also causes + * call handling to use a larger (but not unbounded) call stack limit + * for the duration of error augmentation. + * + * We ignore errors now: a success return and an error value both + * replace the original error value. (This would be easy to change.) + */ + + DUK_ASSERT(thr->heap->augmenting_error == 0); + thr->heap->augmenting_error = 1; + + rc = duk_pcall_method(thr, 1); + DUK_UNREF(rc); /* no need to check now: both success and error are OK */ + + DUK_ASSERT(thr->heap->augmenting_error == 1); + thr->heap->augmenting_error = 0; + + /* [ ... errval ] */ +} +#endif /* DUK_USE_ERRTHROW || DUK_USE_ERRCREATE */ + +/* + * Add ._Tracedata to an error on the stack top. + */ + +#if defined(DUK_USE_TRACEBACKS) +DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) { + duk_activation *act; + duk_int_t depth; + duk_int_t arr_size; + duk_tval *tv; + duk_hstring *s; + duk_uint32_t u32; + duk_double_t d; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr_callstack != NULL); + + /* [ ... error ] */ + + /* + * The traceback format is pretty arcane in an attempt to keep it compact + * and cheap to create. It may change arbitrarily from version to version. + * It should be decoded/accessed through version specific accessors only. + * + * See doc/error-objects.rst. + */ + + DUK_DDD(DUK_DDDPRINT("adding traceback to object: %!T", + (duk_tval *) duk_get_tval(thr, -1))); + + /* Preallocate array to correct size, so that we can just write out + * the _Tracedata values into the array part. + */ + act = thr->callstack_curr; + depth = DUK_USE_TRACEBACK_DEPTH; + DUK_ASSERT(thr_callstack->callstack_top <= DUK_INT_MAX); /* callstack limits */ + if (depth > (duk_int_t) thr_callstack->callstack_top) { + depth = (duk_int_t) thr_callstack->callstack_top; + } + if (depth > 0) { + if (flags & DUK_AUGMENT_FLAG_SKIP_ONE) { + DUK_ASSERT(act != NULL); + act = act->parent; + depth--; + } + } + arr_size = depth * 2; + if (thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL) { + arr_size += 2; + } + if (c_filename) { + /* We need the C filename to be interned before getting the + * array part pointer to avoid any GC interference while the + * array part is populated. + */ + duk_push_string(thr, c_filename); + arr_size += 2; + } + + /* XXX: Uninitialized would be OK. Maybe add internal primitive to + * push bare duk_harray with size? + */ + DUK_D(DUK_DPRINT("preallocated _Tracedata to %ld items", (long) arr_size)); + tv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) arr_size); + duk_clear_prototype(thr, -1); + DUK_ASSERT(duk_is_bare_object(thr, -1)); + DUK_ASSERT(arr_size == 0 || tv != NULL); + + /* Compiler SyntaxErrors (and other errors) come first, and are + * blamed by default (not flagged "noblame"). + */ + if (thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL) { + s = thr->compile_ctx->h_filename; + DUK_TVAL_SET_STRING(tv, s); + DUK_HSTRING_INCREF(thr, s); + tv++; + + u32 = (duk_uint32_t) thr->compile_ctx->curr_token.start_line; /* (flags<<32) + (line), flags = 0 */ + DUK_TVAL_SET_U32(tv, u32); + tv++; + } + + /* Filename/line from C macros (__FILE__, __LINE__) are added as an + * entry with a special format: (string, number). The number contains + * the line and flags. + */ + + /* [ ... error c_filename? arr ] */ + + if (c_filename) { + DUK_ASSERT(DUK_TVAL_IS_STRING(thr->valstack_top - 2)); + s = DUK_TVAL_GET_STRING(thr->valstack_top - 2); /* interned c_filename */ + DUK_ASSERT(s != NULL); + DUK_TVAL_SET_STRING(tv, s); + DUK_HSTRING_INCREF(thr, s); + tv++; + + d = ((flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE) ? ((duk_double_t) DUK_TB_FLAG_NOBLAME_FILELINE) * DUK_DOUBLE_2TO32 : 0.0) + + (duk_double_t) c_line; + DUK_TVAL_SET_DOUBLE(tv, d); + tv++; + } + + /* Traceback depth doesn't take into account the filename/line + * special handling above (intentional). + */ + for (; depth-- > 0; act = act->parent) { + duk_uint32_t pc; + duk_tval *tv_src; + + /* [... arr] */ + + DUK_ASSERT(act != NULL); /* depth check above, assumes book-keeping is correct */ + DUK_ASSERT_DISABLE(act->pc >= 0); /* unsigned */ + + /* Add function object. */ + tv_src = &act->tv_func; /* object (function) or lightfunc */ + DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_src) || DUK_TVAL_IS_LIGHTFUNC(tv_src)); + DUK_TVAL_SET_TVAL(tv, tv_src); + DUK_TVAL_INCREF(thr, tv); + tv++; + + /* Add a number containing: pc, activation flags. + * + * PC points to next instruction, find offending PC. Note that + * PC == 0 for native code. + */ + pc = (duk_uint32_t) duk_hthread_get_act_prev_pc(thr_callstack, act); + DUK_ASSERT_DISABLE(pc >= 0); /* unsigned */ + DUK_ASSERT((duk_double_t) pc < DUK_DOUBLE_2TO32); /* assume PC is at most 32 bits and non-negative */ + d = ((duk_double_t) act->flags) * DUK_DOUBLE_2TO32 + (duk_double_t) pc; + DUK_TVAL_SET_DOUBLE(tv, d); + tv++; + } + +#if defined(DUK_USE_ASSERTIONS) + { + duk_harray *a; + a = (duk_harray *) duk_known_hobject(thr, -1); + DUK_ASSERT(a != NULL); + DUK_ASSERT((duk_uint32_t) (tv - DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a)) == a->length); + DUK_ASSERT(a->length == (duk_uint32_t) arr_size); + DUK_ASSERT(duk_is_bare_object(thr, -1)); + } +#endif + + /* [ ... error c_filename? arr ] */ + + if (c_filename) { + duk_remove_m2(thr); + } + + /* [ ... error arr ] */ + + duk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INT_TRACEDATA); /* -> [ ... error ] */ +} +#endif /* DUK_USE_TRACEBACKS */ + +/* + * Add .fileName and .lineNumber to an error on the stack top. + */ + +#if defined(DUK_USE_AUGMENT_ERROR_CREATE) && !defined(DUK_USE_TRACEBACKS) +DUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) { +#if defined(DUK_USE_ASSERTIONS) + duk_int_t entry_top; +#endif + +#if defined(DUK_USE_ASSERTIONS) + entry_top = duk_get_top(thr); +#endif + + /* + * If tracebacks are disabled, 'fileName' and 'lineNumber' are added + * as plain own properties. Since Error.prototype has accessors of + * the same name, we need to define own properties directly (cannot + * just use e.g. duk_put_prop_stridx). Existing properties are not + * overwritten in case they already exist. + */ + + if (thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL) { + /* Compiler SyntaxError (or other error) gets the primary blame. + * Currently no flag to prevent blaming. + */ + duk_push_uint(thr, (duk_uint_t) thr->compile_ctx->curr_token.start_line); + duk_push_hstring(thr, thr->compile_ctx->h_filename); + } else if (c_filename && (flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE) == 0) { + /* C call site gets blamed next, unless flagged not to do so. + * XXX: file/line is disabled in minimal builds, so disable this + * too when appropriate. + */ + duk_push_int(thr, c_line); + duk_push_string(thr, c_filename); + } else { + /* Finally, blame the innermost callstack entry which has a + * .fileName property. + */ + duk_small_uint_t depth; + duk_uint32_t ecma_line; + duk_activation *act; + + DUK_ASSERT(thr_callstack->callstack_top <= DUK_INT_MAX); /* callstack limits */ + depth = DUK_USE_TRACEBACK_DEPTH; + if (depth > thr_callstack->callstack_top) { + depth = thr_callstack->callstack_top; + } + for (act = thr_callstack->callstack_curr; depth-- > 0; act = act->parent) { + duk_hobject *func; + duk_uint32_t pc; + + DUK_ASSERT(act != NULL); + func = DUK_ACT_GET_FUNC(act); + if (func == NULL) { + /* Lightfunc, not blamed now. */ + continue; + } + + /* PC points to next instruction, find offending PC, + * PC == 0 for native code. + */ + pc = duk_hthread_get_act_prev_pc(thr, act); /* thr argument only used for thr->heap, so specific thread doesn't matter */ + DUK_UNREF(pc); + DUK_ASSERT_DISABLE(pc >= 0); /* unsigned */ + DUK_ASSERT((duk_double_t) pc < DUK_DOUBLE_2TO32); /* assume PC is at most 32 bits and non-negative */ + + duk_push_hobject(thr, func); + + /* [ ... error func ] */ + + duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME); + if (!duk_is_string_notsymbol(thr, -1)) { + duk_pop_2(thr); + continue; + } + + /* [ ... error func fileName ] */ + + ecma_line = 0; +#if defined(DUK_USE_PC2LINE) + if (DUK_HOBJECT_IS_COMPFUNC(func)) { + ecma_line = duk_hobject_pc2line_query(thr, -2, (duk_uint_fast32_t) pc); + } else { + /* Native function, no relevant lineNumber. */ + } +#endif /* DUK_USE_PC2LINE */ + duk_push_u32(thr, ecma_line); + + /* [ ... error func fileName lineNumber ] */ + + duk_replace(thr, -3); + + /* [ ... error lineNumber fileName ] */ + goto define_props; + } + + /* No activation matches, use undefined for both .fileName and + * .lineNumber (matches what we do with a _Tracedata based + * no-match lookup. + */ + duk_push_undefined(thr); + duk_push_undefined(thr); + } + + define_props: + /* [ ... error lineNumber fileName ] */ +#if defined(DUK_USE_ASSERTIONS) + DUK_ASSERT(duk_get_top(thr) == entry_top + 2); +#endif + duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C | DUK_PROPDESC_FLAG_NO_OVERWRITE); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LINE_NUMBER, DUK_PROPDESC_FLAGS_C | DUK_PROPDESC_FLAG_NO_OVERWRITE); +} +#endif /* DUK_USE_AUGMENT_ERROR_CREATE && !DUK_USE_TRACEBACKS */ + +/* + * Add line number to a compiler error. + */ + +#if defined(DUK_USE_AUGMENT_ERROR_CREATE) +DUK_LOCAL void duk__add_compiler_error_line(duk_hthread *thr) { + + /* Append a "(line NNN)" to the "message" property of any error + * thrown during compilation. Usually compilation errors are + * SyntaxErrors but they can also be out-of-memory errors and + * the like. + */ + + /* [ ... error ] */ + + DUK_ASSERT(duk_is_object(thr, -1)); + + if (!(thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL)) { + return; + } + + DUK_DDD(DUK_DDDPRINT("compile error, before adding line info: %!T", + (duk_tval *) duk_get_tval(thr, -1))); + + if (duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_MESSAGE)) { + duk_bool_t at_end; + + /* Best guesstimate that error occurred at end of input, token + * truncated by end of input, etc. + */ +#if 0 + at_end = (thr->compile_ctx->curr_token.start_offset + 1 >= thr->compile_ctx->lex.input_length); + at_end = (thr->compile_ctx->lex.window[0].codepoint < 0 || thr->compile_ctx->lex.window[1].codepoint < 0); +#endif + at_end = (thr->compile_ctx->lex.window[0].codepoint < 0); + + DUK_D(DUK_DPRINT("syntax error, determined at_end=%ld; curr_token.start_offset=%ld, " + "lex.input_length=%ld, window[0].codepoint=%ld, window[1].codepoint=%ld", + (long) at_end, + (long) thr->compile_ctx->curr_token.start_offset, + (long) thr->compile_ctx->lex.input_length, + (long) thr->compile_ctx->lex.window[0].codepoint, + (long) thr->compile_ctx->lex.window[1].codepoint)); + + duk_push_sprintf(thr, " (line %ld%s)", + (long) thr->compile_ctx->curr_token.start_line, + at_end ? ", end of input" : ""); + duk_concat(thr, 2); + duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE); + } else { + duk_pop(thr); + } + + DUK_DDD(DUK_DDDPRINT("compile error, after adding line info: %!T", + (duk_tval *) duk_get_tval(thr, -1))); +} +#endif /* DUK_USE_AUGMENT_ERROR_CREATE */ + +/* + * Augment an error being created using Duktape specific properties + * like _Tracedata or .fileName/.lineNumber. + */ + +#if defined(DUK_USE_AUGMENT_ERROR_CREATE) +DUK_LOCAL void duk__err_augment_builtin_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_hobject *obj, duk_small_uint_t flags) { +#if defined(DUK_USE_ASSERTIONS) + duk_int_t entry_top; +#endif + +#if defined(DUK_USE_ASSERTIONS) + entry_top = duk_get_top(thr); +#endif + DUK_ASSERT(obj != NULL); + + DUK_UNREF(obj); /* unreferenced w/o tracebacks */ + + duk__add_compiler_error_line(thr); + +#if defined(DUK_USE_TRACEBACKS) + /* If tracebacks are enabled, the '_Tracedata' property is the only + * thing we need: 'fileName' and 'lineNumber' are virtual properties + * which use '_Tracedata'. (Check _Tracedata only as own property.) + */ + if (duk_hobject_find_entry_tval_ptr_stridx(thr->heap, obj, DUK_STRIDX_INT_TRACEDATA) != NULL) { + DUK_DDD(DUK_DDDPRINT("error value already has a '_Tracedata' property, not modifying it")); + } else { + duk__add_traceback(thr, thr_callstack, c_filename, c_line, flags); + } +#else + /* Without tracebacks the concrete .fileName and .lineNumber need + * to be added directly. + */ + duk__add_fileline(thr, thr_callstack, c_filename, c_line, flags); +#endif + +#if defined(DUK_USE_ASSERTIONS) + DUK_ASSERT(duk_get_top(thr) == entry_top); +#endif +} +#endif /* DUK_USE_AUGMENT_ERROR_CREATE */ + +/* + * Augment an error at creation time with _Tracedata/fileName/lineNumber + * and allow a user error handler (if defined) to process/replace the error. + * The error to be augmented is at the stack top. + * + * thr: thread containing the error value + * thr_callstack: thread which should be used for generating callstack etc. + * c_filename: C __FILE__ related to the error + * c_line: C __LINE__ related to the error + * flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE: + * if true, don't fileName/line as error source, otherwise use traceback + * (needed because user code filename/line are reported but internal ones + * are not) + */ + +#if defined(DUK_USE_AUGMENT_ERROR_CREATE) +DUK_INTERNAL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) { + duk_hobject *obj; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr_callstack != NULL); + + /* [ ... error ] */ + + /* + * Criteria for augmenting: + * + * - augmentation enabled in build (naturally) + * - error value internal prototype chain contains the built-in + * Error prototype object (i.e. 'val instanceof Error') + * + * Additional criteria for built-in augmenting: + * + * - error value is an extensible object + */ + + obj = duk_get_hobject(thr, -1); + if (!obj) { + DUK_DDD(DUK_DDDPRINT("value is not an object, skip both built-in and user augment")); + return; + } + if (!duk_hobject_prototype_chain_contains(thr, obj, thr->builtins[DUK_BIDX_ERROR_PROTOTYPE], 1 /*ignore_loop*/)) { + /* If the value has a prototype loop, it's critical not to + * throw here. Instead, assume the value is not to be + * augmented. + */ + DUK_DDD(DUK_DDDPRINT("value is not an error instance, skip both built-in and user augment")); + return; + } + if (DUK_HOBJECT_HAS_EXTENSIBLE(obj)) { + DUK_DDD(DUK_DDDPRINT("error meets criteria, built-in augment")); + duk__err_augment_builtin_create(thr, thr_callstack, c_filename, c_line, obj, flags); + } else { + DUK_DDD(DUK_DDDPRINT("error does not meet criteria, no built-in augment")); + } + + /* [ ... error ] */ + +#if defined(DUK_USE_ERRCREATE) + duk__err_augment_user(thr, DUK_STRIDX_ERR_CREATE); +#endif +} +#endif /* DUK_USE_AUGMENT_ERROR_CREATE */ + +/* + * Augment an error at throw time; allow a user error handler (if defined) + * to process/replace the error. The error to be augmented is at the + * stack top. + */ + +#if defined(DUK_USE_AUGMENT_ERROR_THROW) +DUK_INTERNAL void duk_err_augment_error_throw(duk_hthread *thr) { +#if defined(DUK_USE_ERRTHROW) + duk__err_augment_user(thr, DUK_STRIDX_ERR_THROW); +#endif /* DUK_USE_ERRTHROW */ +} +#endif /* DUK_USE_AUGMENT_ERROR_THROW */ diff --git a/third_party/duktape/duk_error_longjmp.c b/third_party/duktape/duk_error_longjmp.c new file mode 100644 index 00000000..0a06b23a --- /dev/null +++ b/third_party/duktape/duk_error_longjmp.c @@ -0,0 +1,103 @@ +/* + * Do a longjmp call, calling the fatal error handler if no + * catchpoint exists. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_PREFER_SIZE) +DUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_minimal(duk_hthread *thr)); +DUK_LOCAL void duk__uncaught_minimal(duk_hthread *thr) { + (void) duk_fatal(thr, "uncaught error"); + DUK_WO_NORETURN(return;); +} +#endif + +#if 0 +DUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_readable(duk_hthread *thr)); +DUK_LOCAL void duk__uncaught_readable(duk_hthread *thr) { + const char *summary; + char buf[DUK_USE_FATAL_MAXLEN]; + + summary = duk_push_string_tval_readable(thr, &thr->heap->lj.value1); + DUK_SNPRINTF(buf, sizeof(buf), "uncaught: %s", summary); + buf[sizeof(buf) - 1] = (char) 0; + (void) duk_fatal(thr, (const char *) buf); + DUK_WO_NORETURN(return;); +} +#endif + +#if !defined(DUK_USE_PREFER_SIZE) +DUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_error_aware(duk_hthread *thr)); +DUK_LOCAL void duk__uncaught_error_aware(duk_hthread *thr) { + const char *summary; + char buf[DUK_USE_FATAL_MAXLEN]; + + summary = duk_push_string_tval_readable_error(thr, &thr->heap->lj.value1); + DUK_ASSERT(summary != NULL); + DUK_SNPRINTF(buf, sizeof(buf), "uncaught: %s", summary); + buf[sizeof(buf) - 1] = (char) 0; + (void) duk_fatal(thr, (const char *) buf); + DUK_WO_NORETURN(return;); +} +#endif + +DUK_INTERNAL void duk_err_longjmp(duk_hthread *thr) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + + DUK_DD(DUK_DDPRINT("longjmp error: type=%d iserror=%d value1=%!T value2=%!T", + (int) thr->heap->lj.type, (int) thr->heap->lj.iserror, + &thr->heap->lj.value1, &thr->heap->lj.value2)); + + /* Prevent finalizer execution during error handling. All error + * handling sites will process pending finalizers once error handling + * is complete and we're ready for the side effects. Does not prevent + * refzero freeing or mark-and-sweep during error handling. + * + * NOTE: when we come here some calling code may have used DECREF + * NORZ macros without an explicit DUK_REFZERO_CHECK_xxx() call. + * We don't want to do it here because it would just check for + * pending finalizers and we prevent that explicitly. Instead, + * the error catcher will run the finalizers once error handling + * is complete. + */ + + DUK_ASSERT_LJSTATE_SET(thr->heap); + + thr->heap->pf_prevent_count++; + DUK_ASSERT(thr->heap->pf_prevent_count != 0); /* Wrap. */ + +#if defined(DUK_USE_ASSERTIONS) + /* XXX: set this immediately when longjmp state is set */ + DUK_ASSERT(thr->heap->error_not_allowed == 0); /* Detect error within critical section. */ + thr->heap->error_not_allowed = 1; +#endif + + DUK_DD(DUK_DDPRINT("about to longjmp, pf_prevent_count=%ld", (long) thr->heap->pf_prevent_count)); + + /* If we don't have a jmpbuf_ptr, there is little we can do except + * cause a fatal error. The caller's expectation is that we never + * return. + */ + if (!thr->heap->lj.jmpbuf_ptr) { + DUK_D(DUK_DPRINT("uncaught error: type=%d iserror=%d value1=%!T value2=%!T", + (int) thr->heap->lj.type, (int) thr->heap->lj.iserror, + &thr->heap->lj.value1, &thr->heap->lj.value2)); + +#if defined(DUK_USE_PREFER_SIZE) + duk__uncaught_minimal(thr); +#else + duk__uncaught_error_aware(thr); +#endif + DUK_UNREACHABLE(); + } + +#if defined(DUK_USE_CPP_EXCEPTIONS) + throw duk_internal_exception(); /* dummy */ +#else + DUK_LONGJMP(thr->heap->lj.jmpbuf_ptr->jb); +#endif + + DUK_UNREACHABLE(); +} diff --git a/third_party/duktape/duk_error_macros.c b/third_party/duktape/duk_error_macros.c new file mode 100644 index 00000000..e65bf40a --- /dev/null +++ b/third_party/duktape/duk_error_macros.c @@ -0,0 +1,152 @@ +/* + * Error and fatal handling. + */ + +#include "third_party/duktape/duk_internal.h" + +#define DUK__ERRFMT_BUFSIZE 256 /* size for formatting buffers */ + +#if defined(DUK_USE_VERBOSE_ERRORS) + +DUK_INTERNAL DUK_COLD void duk_err_handle_error_fmt(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *fmt, ...) { + va_list ap; + char msg[DUK__ERRFMT_BUFSIZE]; + va_start(ap, fmt); + (void) DUK_VSNPRINTF(msg, sizeof(msg), fmt, ap); + msg[sizeof(msg) - 1] = (char) 0; + duk_err_create_and_throw(thr, (duk_errcode_t) (line_and_code >> 24), msg, filename, (duk_int_t) (line_and_code & 0x00ffffffL)); + va_end(ap); /* dead code, but ensures portability (see Linux man page notes) */ +} + +DUK_INTERNAL DUK_COLD void duk_err_handle_error(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *msg) { + duk_err_create_and_throw(thr, (duk_errcode_t) (line_and_code >> 24), msg, filename, (duk_int_t) (line_and_code & 0x00ffffffL)); +} + +#else /* DUK_USE_VERBOSE_ERRORS */ + +DUK_INTERNAL DUK_COLD void duk_err_handle_error(duk_hthread *thr, duk_errcode_t code) { + duk_err_create_and_throw(thr, code); +} + +#endif /* DUK_USE_VERBOSE_ERRORS */ + +/* + * Error throwing helpers + */ + +#if defined(DUK_USE_VERBOSE_ERRORS) +#if defined(DUK_USE_PARANOID_ERRORS) +DUK_INTERNAL DUK_COLD void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name) { + DUK_ERROR_RAW_FMT3(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, "%s required, found %s (stack index %ld)", + expect_name, duk_get_type_name(thr, idx), (long) idx); +} +#else +DUK_INTERNAL DUK_COLD void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name) { + DUK_ERROR_RAW_FMT3(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, "%s required, found %s (stack index %ld)", + expect_name, duk_push_string_readable(thr, idx), (long) idx); +} +#endif +DUK_INTERNAL DUK_COLD void duk_err_error_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber) { + DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, DUK_STR_INTERNAL_ERROR); +} +DUK_INTERNAL DUK_COLD void duk_err_error_alloc_failed(duk_hthread *thr, const char *filename, duk_int_t linenumber) { + DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, DUK_STR_ALLOC_FAILED); +} +DUK_INTERNAL DUK_COLD void duk_err_error(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message) { + DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, message); +} +DUK_INTERNAL DUK_COLD void duk_err_range(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message) { + DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, message); +} +DUK_INTERNAL DUK_COLD void duk_err_range_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx) { + DUK_ERROR_RAW_FMT1(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, "invalid stack index %ld", (long) (idx)); +} +DUK_INTERNAL DUK_COLD void duk_err_range_push_beyond(duk_hthread *thr, const char *filename, duk_int_t linenumber) { + DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, DUK_STR_PUSH_BEYOND_ALLOC_STACK); +} +DUK_INTERNAL DUK_COLD void duk_err_type_invalid_args(duk_hthread *thr, const char *filename, duk_int_t linenumber) { + DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_ARGS); +} +DUK_INTERNAL DUK_COLD void duk_err_type_invalid_state(duk_hthread *thr, const char *filename, duk_int_t linenumber) { + DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_STATE); +} +DUK_INTERNAL DUK_COLD void duk_err_type_invalid_trap_result(duk_hthread *thr, const char *filename, duk_int_t linenumber) { + DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_TRAP_RESULT); +} +#else +/* The file/line arguments are NULL and 0, they're ignored by DUK_ERROR_RAW() + * when non-verbose errors are used. + */ + +DUK_NORETURN(DUK_LOCAL_DECL void duk__err_shared(duk_hthread *thr, duk_errcode_t code)); +DUK_LOCAL void duk__err_shared(duk_hthread *thr, duk_errcode_t code) { + DUK_ERROR_RAW(thr, NULL, 0, code, NULL); +} +DUK_INTERNAL DUK_COLD void duk_err_error(duk_hthread *thr) { + duk__err_shared(thr, DUK_ERR_ERROR); +} +DUK_INTERNAL DUK_COLD void duk_err_range(duk_hthread *thr) { + duk__err_shared(thr, DUK_ERR_RANGE_ERROR); +} +DUK_INTERNAL DUK_COLD void duk_err_eval(duk_hthread *thr) { + duk__err_shared(thr, DUK_ERR_EVAL_ERROR); +} +DUK_INTERNAL DUK_COLD void duk_err_reference(duk_hthread *thr) { + duk__err_shared(thr, DUK_ERR_REFERENCE_ERROR); +} +DUK_INTERNAL DUK_COLD void duk_err_syntax(duk_hthread *thr) { + duk__err_shared(thr, DUK_ERR_SYNTAX_ERROR); +} +DUK_INTERNAL DUK_COLD void duk_err_type(duk_hthread *thr) { + duk__err_shared(thr, DUK_ERR_TYPE_ERROR); +} +DUK_INTERNAL DUK_COLD void duk_err_uri(duk_hthread *thr) { + duk__err_shared(thr, DUK_ERR_URI_ERROR); +} +#endif + +/* + * Default fatal error handler + */ + +DUK_INTERNAL DUK_COLD void duk_default_fatal_handler(void *udata, const char *msg) { + DUK_UNREF(udata); + DUK_UNREF(msg); + + msg = msg ? msg : "NULL"; + +#if defined(DUK_USE_FATAL_HANDLER) + /* duk_config.h provided a custom default fatal handler. */ + DUK_D(DUK_DPRINT("custom default fatal error handler called: %s", msg)); + DUK_USE_FATAL_HANDLER(udata, msg); +#elif defined(DUK_USE_CPP_EXCEPTIONS) + /* With C++ use a duk_fatal_exception which user code can catch in + * a natural way. + */ + DUK_D(DUK_DPRINT("built-in default C++ fatal error handler called: %s", msg)); + throw duk_fatal_exception(msg); +#else + /* Default behavior is to abort() on error. There's no printout + * which makes this awkward, so it's always recommended to use an + * explicit fatal error handler. + * + * ==================================================================== + * NOTE: If you are seeing this, you are most likely dealing with an + * uncaught error. You should provide a fatal error handler in Duktape + * heap creation, and should consider using a protected call as your + * first call into an empty Duktape context to properly handle errors. + * See: + * - http://duktape.org/guide.html#error-handling + * - http://wiki.duktape.org/HowtoFatalErrors.html + * - http://duktape.org/api.html#taglist-protected + * ==================================================================== + */ + DUK_D(DUK_DPRINT("built-in default fatal error handler called: %s", msg)); + DUK_ABORT(); +#endif + + DUK_D(DUK_DPRINT("fatal error handler returned, enter forever loop")); + for (;;) { + /* Loop forever to ensure we don't return. */ + } +} diff --git a/third_party/duktape/duk_error_misc.c b/third_party/duktape/duk_error_misc.c new file mode 100644 index 00000000..9bc668fa --- /dev/null +++ b/third_party/duktape/duk_error_misc.c @@ -0,0 +1,174 @@ +/* + * Error helpers + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Helper to walk the thread chain and see if there is an active error + * catcher. Protected calls or finally blocks aren't considered catching. + */ + +#if defined(DUK_USE_DEBUGGER_SUPPORT) +DUK_LOCAL duk_bool_t duk__have_active_catcher(duk_hthread *thr) { + /* As noted above, a protected API call won't be counted as a + * catcher. This is usually convenient, e.g. in the case of a top- + * level duk_pcall(), but may not always be desirable. Perhaps add + * an argument to treat them as catchers? + */ + + duk_activation *act; + duk_catcher *cat; + + DUK_ASSERT(thr != NULL); + + for (; thr != NULL; thr = thr->resumer) { + for (act = thr->callstack_curr; act != NULL; act = act->parent) { + for (cat = act->cat; cat != NULL; cat = cat->parent) { + if (DUK_CAT_HAS_CATCH_ENABLED(cat)) { + return 1; /* all we need to know */ + } + } + } + } + return 0; +} +#endif /* DUK_USE_DEBUGGER_SUPPORT */ + +/* + * Get prototype object for an integer error code. + */ + +DUK_INTERNAL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, duk_errcode_t code) { + switch (code) { + case DUK_ERR_EVAL_ERROR: + return thr->builtins[DUK_BIDX_EVAL_ERROR_PROTOTYPE]; + case DUK_ERR_RANGE_ERROR: + return thr->builtins[DUK_BIDX_RANGE_ERROR_PROTOTYPE]; + case DUK_ERR_REFERENCE_ERROR: + return thr->builtins[DUK_BIDX_REFERENCE_ERROR_PROTOTYPE]; + case DUK_ERR_SYNTAX_ERROR: + return thr->builtins[DUK_BIDX_SYNTAX_ERROR_PROTOTYPE]; + case DUK_ERR_TYPE_ERROR: + return thr->builtins[DUK_BIDX_TYPE_ERROR_PROTOTYPE]; + case DUK_ERR_URI_ERROR: + return thr->builtins[DUK_BIDX_URI_ERROR_PROTOTYPE]; + case DUK_ERR_ERROR: + default: + return thr->builtins[DUK_BIDX_ERROR_PROTOTYPE]; + } +} + +/* + * Helper for debugger throw notify and pause-on-uncaught integration. + */ + +#if defined(DUK_USE_DEBUGGER_SUPPORT) +DUK_INTERNAL void duk_err_check_debugger_integration(duk_hthread *thr) { + duk_bool_t uncaught; + duk_tval *tv_obj; + + /* If something is thrown with the debugger attached and nobody will + * catch it, execution is paused before the longjmp, turning over + * control to the debug client. This allows local state to be examined + * before the stack is unwound. Errors are not intercepted when debug + * message loop is active (e.g. for Eval). + */ + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + + /* XXX: Allow customizing the pause and notify behavior at runtime + * using debugger runtime flags. For now the behavior is fixed using + * config options. + */ + + if (!duk_debug_is_attached(thr->heap) || + thr->heap->dbg_processing || + thr->heap->lj.type != DUK_LJ_TYPE_THROW || + thr->heap->creating_error) { + DUK_D(DUK_DPRINT("skip debugger error integration; not attached, debugger processing, not THROW, or error thrown while creating error")); + return; + } + + /* Don't intercept a DoubleError, we may have caused the initial double + * fault and attempting to intercept it will cause us to be called + * recursively and exhaust the C stack. (This should no longer happen + * for the initial throw because DoubleError path doesn't do a debugger + * integration check, but it might happen for rethrows.) + */ + tv_obj = &thr->heap->lj.value1; + if (DUK_TVAL_IS_OBJECT(tv_obj) && DUK_TVAL_GET_OBJECT(tv_obj) == thr->builtins[DUK_BIDX_DOUBLE_ERROR]) { + DUK_D(DUK_DPRINT("built-in DoubleError instance (re)thrown, not intercepting")); + return; + } + + uncaught = !duk__have_active_catcher(thr); + + /* Debugger code expects the value at stack top. This also serves + * as a backup: we need to store/restore the longjmp state because + * when the debugger is paused Eval commands may be executed and + * they can arbitrarily clobber the longjmp state. + */ + duk_push_tval(thr, tv_obj); + + /* Store and reset longjmp state. */ + DUK_ASSERT_LJSTATE_SET(thr->heap); + DUK_TVAL_DECREF_NORZ(thr, tv_obj); + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value2)); /* Always for THROW type. */ + DUK_TVAL_SET_UNDEFINED(tv_obj); + thr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN; + DUK_ASSERT_LJSTATE_UNSET(thr->heap); + +#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY) + /* Report it to the debug client */ + DUK_D(DUK_DPRINT("throw with debugger attached, report to client")); + duk_debug_send_throw(thr, uncaught); +#endif + + if (uncaught) { + if (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_UNCAUGHT_ERROR) { + DUK_D(DUK_DPRINT("PAUSE TRIGGERED by uncaught error")); + duk_debug_halt_execution(thr, 1 /*use_prev_pc*/); + } + } else { + if (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_CAUGHT_ERROR) { + DUK_D(DUK_DPRINT("PAUSE TRIGGERED by caught error")); + duk_debug_halt_execution(thr, 1 /*use_prev_pc*/); + } + } + + /* Restore longjmp state. */ + DUK_ASSERT_LJSTATE_UNSET(thr->heap); + thr->heap->lj.type = DUK_LJ_TYPE_THROW; + tv_obj = DUK_GET_TVAL_NEGIDX(thr, -1); + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value1)); + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value2)); + DUK_TVAL_SET_TVAL(&thr->heap->lj.value1, tv_obj); + DUK_TVAL_INCREF(thr, tv_obj); + DUK_ASSERT_LJSTATE_SET(thr->heap); + + duk_pop(thr); +} +#endif /* DUK_USE_DEBUGGER_SUPPORT */ + +/* + * Helpers for setting up heap longjmp state. + */ + +DUK_INTERNAL void duk_err_setup_ljstate1(duk_hthread *thr, duk_small_uint_t lj_type, duk_tval *tv_val) { + duk_heap *heap; + + DUK_ASSERT(thr != NULL); + heap = thr->heap; + DUK_ASSERT(heap != NULL); + DUK_ASSERT(tv_val != NULL); + + DUK_ASSERT_LJSTATE_UNSET(heap); + + heap->lj.type = lj_type; + DUK_TVAL_SET_TVAL(&heap->lj.value1, tv_val); + DUK_TVAL_INCREF(thr, tv_val); + + DUK_ASSERT_LJSTATE_SET(heap); +} diff --git a/third_party/duktape/duk_error_throw.c b/third_party/duktape/duk_error_throw.c new file mode 100644 index 00000000..743c79b0 --- /dev/null +++ b/third_party/duktape/duk_error_throw.c @@ -0,0 +1,162 @@ +/* + * Create and throw an ECMAScript error object based on a code and a message. + * + * Used when we throw errors internally. ECMAScript generated error objects + * are created by ECMAScript code, and the throwing is handled by the bytecode + * executor. + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Create and throw an error (originating from Duktape internally) + * + * Push an error object on top of the stack, possibly throw augmenting + * the error, and finally longjmp. + * + * If an error occurs while we're dealing with the current error, we might + * enter an infinite recursion loop. This is prevented by detecting a + * "double fault" through the heap->creating_error flag; the recursion + * then stops at the second level. + */ + +#if defined(DUK_USE_VERBOSE_ERRORS) +DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code, const char *msg, const char *filename, duk_int_t line) { +#else +DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code) { +#endif +#if defined(DUK_USE_VERBOSE_ERRORS) + DUK_DD(DUK_DDPRINT("duk_err_create_and_throw(): code=%ld, msg=%s, filename=%s, line=%ld", + (long) code, (const char *) msg, + (const char *) filename, (long) line)); +#else + DUK_DD(DUK_DDPRINT("duk_err_create_and_throw(): code=%ld", (long) code)); +#endif + + DUK_ASSERT(thr != NULL); + + /* Even though nested call is possible because we throw an error when + * trying to create an error, the potential errors must happen before + * the longjmp state is configured. + */ + DUK_ASSERT_LJSTATE_UNSET(thr->heap); + + /* Sync so that augmentation sees up-to-date activations, NULL + * thr->ptr_curr_pc so that it's not used if side effects occur + * in augmentation or longjmp handling. + */ + duk_hthread_sync_and_null_currpc(thr); + + /* + * Create and push an error object onto the top of stack. + * The error is potentially augmented before throwing. + * + * If a "double error" occurs, use a fixed error instance + * to avoid further trouble. + */ + + if (thr->heap->creating_error) { + duk_tval tv_val; + duk_hobject *h_err; + + thr->heap->creating_error = 0; + + h_err = thr->builtins[DUK_BIDX_DOUBLE_ERROR]; + if (h_err != NULL) { + DUK_D(DUK_DPRINT("double fault detected -> use built-in fixed 'double error' instance")); + DUK_TVAL_SET_OBJECT(&tv_val, h_err); + } else { + DUK_D(DUK_DPRINT("double fault detected; there is no built-in fixed 'double error' instance " + "-> use the error code as a number")); + DUK_TVAL_SET_I32(&tv_val, (duk_int32_t) code); + } + + duk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, &tv_val); + + /* No augmentation to avoid any allocations or side effects. */ + } else { + /* Prevent infinite recursion. Extra call stack and C + * recursion headroom (see GH-191) is added for augmentation. + * That is now signalled by heap->augmenting error and taken + * into account in call handling without an explicit limit bump. + */ + thr->heap->creating_error = 1; + + duk_require_stack(thr, 1); + + /* XXX: usually unnecessary '%s' formatting here, but cannot + * use 'msg' as a format string directly. + */ +#if defined(DUK_USE_VERBOSE_ERRORS) + duk_push_error_object_raw(thr, + code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE, + filename, + line, + "%s", + (const char *) msg); +#else + duk_push_error_object_raw(thr, + code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE, + NULL, + 0, + NULL); +#endif + + /* Note that an alloc error may happen during error augmentation. + * This may happen both when the original error is an alloc error + * and when it's something else. Because any error in augmentation + * must be handled correctly anyway, there's no special check for + * avoiding it for alloc errors (this differs from Duktape 1.x). + */ +#if defined(DUK_USE_AUGMENT_ERROR_THROW) + DUK_DDD(DUK_DDDPRINT("THROW ERROR (INTERNAL): %!iT (before throw augment)", + (duk_tval *) duk_get_tval(thr, -1))); + duk_err_augment_error_throw(thr); +#endif + + duk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, DUK_GET_TVAL_NEGIDX(thr, -1)); + thr->heap->creating_error = 0; + + /* Error is now created and we assume no errors can occur any + * more. Check for debugger Throw integration only when the + * error is complete. If we enter debugger message loop, + * creating_error must be 0 so that errors can be thrown in + * the paused state, e.g. in Eval commands. + */ +#if defined(DUK_USE_DEBUGGER_SUPPORT) + duk_err_check_debugger_integration(thr); +#endif + } + + /* + * Finally, longjmp + */ + + DUK_DDD(DUK_DDDPRINT("THROW ERROR (INTERNAL): %!iT, %!iT (after throw augment)", + (duk_tval *) &thr->heap->lj.value1, (duk_tval *) &thr->heap->lj.value2)); + + duk_err_longjmp(thr); + DUK_UNREACHABLE(); +} + +/* + * Helper for C function call negative return values. + */ + +DUK_INTERNAL void duk_error_throw_from_negative_rc(duk_hthread *thr, duk_ret_t rc) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(rc < 0); + + /* + * The __FILE__ and __LINE__ information is intentionally not used in the + * creation of the error object, as it isn't useful in the tracedata. The + * tracedata still contains the function which returned the negative return + * code, and having the file/line of this function isn't very useful. + * + * The error messages for DUK_RET_xxx shorthand are intentionally very + * minimal: they're only really useful for low memory targets. + */ + + duk_error_raw(thr, -rc, NULL, 0, "error (rc %ld)", (long) rc); + DUK_WO_NORETURN(return;); +} diff --git a/third_party/duktape/duk_exception.h b/third_party/duktape/duk_exception.h new file mode 100644 index 00000000..580e9d7e --- /dev/null +++ b/third_party/duktape/duk_exception.h @@ -0,0 +1,30 @@ +/* + * Exceptions for Duktape internal throws when C++ exceptions are used + * for long control transfers. + */ + +#if !defined(DUK_EXCEPTION_H_INCLUDED) +#define DUK_EXCEPTION_H_INCLUDED + +#if defined(DUK_USE_CPP_EXCEPTIONS) +/* Internal exception used as a setjmp-longjmp replacement. User code should + * NEVER see or catch this exception, so it doesn't inherit from any base + * class which should minimize the chance of user code accidentally catching + * the exception. + */ +class duk_internal_exception { + /* intentionally empty */ +}; + +/* Fatal error, thrown as a specific C++ exception with C++ exceptions + * enabled. It is unsafe to continue; doing so may cause crashes or memory + * leaks. This is intended to be either uncaught, or caught by user code + * aware of the "unsafe to continue" semantics. + */ +class duk_fatal_exception : public virtual std::runtime_error { + public: + duk_fatal_exception(const char *message) : std::runtime_error(message) {} +}; +#endif + +#endif /* DUK_EXCEPTION_H_INCLUDED */ diff --git a/third_party/duktape/duk_fltunion.h b/third_party/duktape/duk_fltunion.h new file mode 100644 index 00000000..57533b31 --- /dev/null +++ b/third_party/duktape/duk_fltunion.h @@ -0,0 +1,39 @@ +/* + * Union to access IEEE float memory representation. + */ + +#if !defined(DUK_FLTUNION_H_INCLUDED) +#define DUK_FLTUNION_H_INCLUDED + +#include "third_party/duktape/duk_internal.h" + +union duk_float_union { + float f; + duk_uint32_t ui[1]; + duk_uint16_t us[2]; + duk_uint8_t uc[4]; +}; + +typedef union duk_float_union duk_float_union; + +#if defined(DUK_USE_DOUBLE_LE) || defined(DUK_USE_DOUBLE_ME) +#define DUK_FLT_IDX_UI0 0 +#define DUK_FLT_IDX_US0 1 +#define DUK_FLT_IDX_US1 0 +#define DUK_FLT_IDX_UC0 3 +#define DUK_FLT_IDX_UC1 2 +#define DUK_FLT_IDX_UC2 1 +#define DUK_FLT_IDX_UC3 0 +#elif defined(DUK_USE_DOUBLE_BE) +#define DUK_FLT_IDX_UI0 0 +#define DUK_FLT_IDX_US0 0 +#define DUK_FLT_IDX_US1 1 +#define DUK_FLT_IDX_UC0 0 +#define DUK_FLT_IDX_UC1 1 +#define DUK_FLT_IDX_UC2 2 +#define DUK_FLT_IDX_UC3 3 +#else +#error internal error +#endif + +#endif /* DUK_FLTUNION_H_INCLUDED */ diff --git a/third_party/duktape/duk_forwdecl.h b/third_party/duktape/duk_forwdecl.h new file mode 100644 index 00000000..6bfe3e1f --- /dev/null +++ b/third_party/duktape/duk_forwdecl.h @@ -0,0 +1,134 @@ +/* + * Forward declarations for all Duktape structures. + */ + +#if !defined(DUK_FORWDECL_H_INCLUDED) +#define DUK_FORWDECL_H_INCLUDED + +/* + * Forward declarations + */ + +#if defined(DUK_USE_CPP_EXCEPTIONS) +class duk_internal_exception; +#else +struct duk_jmpbuf; +#endif + +/* duk_tval intentionally skipped */ +struct duk_heaphdr; +struct duk_heaphdr_string; +struct duk_harray; +struct duk_hstring; +struct duk_hstring_external; +struct duk_hobject; +struct duk_hcompfunc; +struct duk_hnatfunc; +struct duk_hboundfunc; +struct duk_hthread; +struct duk_hbufobj; +struct duk_hdecenv; +struct duk_hobjenv; +struct duk_hproxy; +struct duk_hbuffer; +struct duk_hbuffer_fixed; +struct duk_hbuffer_dynamic; +struct duk_hbuffer_external; + +struct duk_propaccessor; +union duk_propvalue; +struct duk_propdesc; + +struct duk_heap; +struct duk_breakpoint; + +struct duk_activation; +struct duk_catcher; +struct duk_ljstate; +struct duk_strcache_entry; +struct duk_litcache_entry; +struct duk_strtab_entry; + +#if defined(DUK_USE_DEBUG) +struct duk_fixedbuffer; +#endif + +struct duk_bitdecoder_ctx; +struct duk_bitencoder_ctx; +struct duk_bufwriter_ctx; + +struct duk_token; +struct duk_re_token; +struct duk_lexer_point; +struct duk_lexer_ctx; +struct duk_lexer_codepoint; + +struct duk_compiler_instr; +struct duk_compiler_func; +struct duk_compiler_ctx; + +struct duk_re_matcher_ctx; +struct duk_re_compiler_ctx; + +#if defined(DUK_USE_CPP_EXCEPTIONS) +/* no typedef */ +#else +typedef struct duk_jmpbuf duk_jmpbuf; +#endif + +/* duk_tval intentionally skipped */ +typedef struct duk_heaphdr duk_heaphdr; +typedef struct duk_heaphdr_string duk_heaphdr_string; +typedef struct duk_harray duk_harray; +typedef struct duk_hstring duk_hstring; +typedef struct duk_hstring_external duk_hstring_external; +typedef struct duk_hobject duk_hobject; +typedef struct duk_hcompfunc duk_hcompfunc; +typedef struct duk_hnatfunc duk_hnatfunc; +typedef struct duk_hboundfunc duk_hboundfunc; +typedef struct duk_hthread duk_hthread; +typedef struct duk_hbufobj duk_hbufobj; +typedef struct duk_hdecenv duk_hdecenv; +typedef struct duk_hobjenv duk_hobjenv; +typedef struct duk_hproxy duk_hproxy; +typedef struct duk_hbuffer duk_hbuffer; +typedef struct duk_hbuffer_fixed duk_hbuffer_fixed; +typedef struct duk_hbuffer_dynamic duk_hbuffer_dynamic; +typedef struct duk_hbuffer_external duk_hbuffer_external; + +typedef struct duk_propaccessor duk_propaccessor; +typedef union duk_propvalue duk_propvalue; +typedef struct duk_propdesc duk_propdesc; + +typedef struct duk_heap duk_heap; +typedef struct duk_breakpoint duk_breakpoint; + +typedef struct duk_activation duk_activation; +typedef struct duk_catcher duk_catcher; +typedef struct duk_ljstate duk_ljstate; +typedef struct duk_strcache_entry duk_strcache_entry; +typedef struct duk_litcache_entry duk_litcache_entry; +typedef struct duk_strtab_entry duk_strtab_entry; + +#if defined(DUK_USE_DEBUG) +typedef struct duk_fixedbuffer duk_fixedbuffer; +#endif + +typedef struct duk_bitdecoder_ctx duk_bitdecoder_ctx; +typedef struct duk_bitencoder_ctx duk_bitencoder_ctx; +typedef struct duk_bufwriter_ctx duk_bufwriter_ctx; + +typedef struct duk_token duk_token; +typedef struct duk_re_token duk_re_token; +typedef struct duk_lexer_point duk_lexer_point; +typedef struct duk_lexer_ctx duk_lexer_ctx; +typedef struct duk_lexer_codepoint duk_lexer_codepoint; + +typedef struct duk_compiler_instr duk_compiler_instr; +typedef struct duk_compiler_func duk_compiler_func; +typedef struct duk_compiler_ctx duk_compiler_ctx; + +typedef struct duk_re_matcher_ctx duk_re_matcher_ctx; +typedef struct duk_re_compiler_ctx duk_re_compiler_ctx; + +#endif /* DUK_FORWDECL_H_INCLUDED */ diff --git a/third_party/duktape/duk_harray.h b/third_party/duktape/duk_harray.h new file mode 100644 index 00000000..853814f0 --- /dev/null +++ b/third_party/duktape/duk_harray.h @@ -0,0 +1,48 @@ +/* + * Array object representation, used for actual Array instances. + * + * All objects with the exotic array behavior (which must coincide with having + * internal class array) MUST be duk_harrays. No other object can be a + * duk_harray. However, duk_harrays may not always have an array part. + */ + +#if !defined(DUK_HARRAY_H_INCLUDED) +#define DUK_HARRAY_H_INCLUDED + +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL_DECL void duk_harray_assert_valid(duk_harray *h); +#define DUK_HARRAY_ASSERT_VALID(h) do { duk_harray_assert_valid((h)); } while (0) +#else +#define DUK_HARRAY_ASSERT_VALID(h) do {} while (0) +#endif + +#define DUK_HARRAY_LENGTH_WRITABLE(h) (!(h)->length_nonwritable) +#define DUK_HARRAY_LENGTH_NONWRITABLE(h) ((h)->length_nonwritable) +#define DUK_HARRAY_SET_LENGTH_WRITABLE(h) do { (h)->length_nonwritable = 0; } while (0) +#define DUK_HARRAY_SET_LENGTH_NONWRITABLE(h) do { (h)->length_nonwritable = 1; } while (0) + +struct duk_harray { + /* Shared object part. */ + duk_hobject obj; + + /* Array .length. + * + * At present Array .length may be smaller, equal, or even larger + * than the allocated underlying array part. Fast path code must + * always take this into account carefully. + */ + duk_uint32_t length; + + /* Array .length property attributes. The property is always + * non-enumerable and non-configurable. It's initially writable + * but per Object.defineProperty() rules it can be made non-writable + * even if it is non-configurable. Thus we need to track the + * writability explicitly. + * + * XXX: this field to be eliminated and moved into duk_hobject + * flags field to save space. + */ + duk_bool_t length_nonwritable; +}; + +#endif /* DUK_HARRAY_H_INCLUDED */ diff --git a/third_party/duktape/duk_hboundfunc.h b/third_party/duktape/duk_hboundfunc.h new file mode 100644 index 00000000..72cadb1b --- /dev/null +++ b/third_party/duktape/duk_hboundfunc.h @@ -0,0 +1,37 @@ +/* + * Bound function representation. + */ + +#if !defined(DUK_HBOUNDFUNC_H_INCLUDED) +#define DUK_HBOUNDFUNC_H_INCLUDED + +/* Artificial limit for args length. Ensures arithmetic won't overflow + * 32 bits when combining bound functions. + */ +#define DUK_HBOUNDFUNC_MAX_ARGS 0x20000000UL + +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL_DECL void duk_hboundfunc_assert_valid(duk_hboundfunc *h); +#define DUK_HBOUNDFUNC_ASSERT_VALID(h) do { duk_hboundfunc_assert_valid((h)); } while (0) +#else +#define DUK_HBOUNDFUNC_ASSERT_VALID(h) do {} while (0) +#endif + +struct duk_hboundfunc { + /* Shared object part. */ + duk_hobject obj; + + /* Final target function, stored as duk_tval so that lightfunc can be + * represented too. + */ + duk_tval target; + + /* This binding. */ + duk_tval this_binding; + + /* Arguments to prepend. */ + duk_tval *args; /* Separate allocation. */ + duk_idx_t nargs; +}; + +#endif /* DUK_HBOUNDFUNC_H_INCLUDED */ diff --git a/third_party/duktape/duk_hbuffer.h b/third_party/duktape/duk_hbuffer.h new file mode 100644 index 00000000..283900e2 --- /dev/null +++ b/third_party/duktape/duk_hbuffer.h @@ -0,0 +1,336 @@ +/* + * Heap buffer representation. + * + * Heap allocated user data buffer which is either: + * + * 1. A fixed size buffer (data follows header statically) + * 2. A dynamic size buffer (data pointer follows header) + * + * The data pointer for a variable size buffer of zero size may be NULL. + */ + +#if !defined(DUK_HBUFFER_H_INCLUDED) +#define DUK_HBUFFER_H_INCLUDED + +/* + * Flags + * + * Fixed buffer: 0 + * Dynamic buffer: DUK_HBUFFER_FLAG_DYNAMIC + * External buffer: DUK_HBUFFER_FLAG_DYNAMIC | DUK_HBUFFER_FLAG_EXTERNAL + */ + +#define DUK_HBUFFER_FLAG_DYNAMIC DUK_HEAPHDR_USER_FLAG(0) /* buffer is behind a pointer, dynamic or external */ +#define DUK_HBUFFER_FLAG_EXTERNAL DUK_HEAPHDR_USER_FLAG(1) /* buffer pointer is to an externally allocated buffer */ + +#define DUK_HBUFFER_HAS_DYNAMIC(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC) +#define DUK_HBUFFER_HAS_EXTERNAL(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL) + +#define DUK_HBUFFER_SET_DYNAMIC(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC) +#define DUK_HBUFFER_SET_EXTERNAL(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL) + +#define DUK_HBUFFER_CLEAR_DYNAMIC(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC) +#define DUK_HBUFFER_CLEAR_EXTERNAL(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL) + +/* + * Misc defines + */ + +/* Impose a maximum buffer length for now. Restricted artificially to + * ensure resize computations or adding a heap header length won't + * overflow size_t and that a signed duk_int_t can hold a buffer + * length. The limit should be synchronized with DUK_HSTRING_MAX_BYTELEN. + */ + +#if defined(DUK_USE_BUFLEN16) +#define DUK_HBUFFER_MAX_BYTELEN (0x0000ffffUL) +#else +/* Intentionally not 0x7fffffffUL; at least JSON code expects that + * 2*len + 2 fits in 32 bits. + */ +#define DUK_HBUFFER_MAX_BYTELEN (0x7ffffffeUL) +#endif + +/* + * Field access + */ + +#if defined(DUK_USE_BUFLEN16) +/* size stored in duk_heaphdr unused flag bits */ +#define DUK_HBUFFER_GET_SIZE(x) ((x)->hdr.h_flags >> 16) +#define DUK_HBUFFER_SET_SIZE(x,v) do { \ + duk_size_t duk__v; \ + duk__v = (v); \ + DUK_ASSERT(duk__v <= 0xffffUL); \ + (x)->hdr.h_flags = ((x)->hdr.h_flags & 0x0000ffffUL) | (((duk_uint32_t) duk__v) << 16); \ + } while (0) +#define DUK_HBUFFER_ADD_SIZE(x,dv) do { \ + (x)->hdr.h_flags += ((dv) << 16); \ + } while (0) +#define DUK_HBUFFER_SUB_SIZE(x,dv) do { \ + (x)->hdr.h_flags -= ((dv) << 16); \ + } while (0) +#else +#define DUK_HBUFFER_GET_SIZE(x) (((duk_hbuffer *) (x))->size) +#define DUK_HBUFFER_SET_SIZE(x,v) do { \ + ((duk_hbuffer *) (x))->size = (v); \ + } while (0) +#define DUK_HBUFFER_ADD_SIZE(x,dv) do { \ + (x)->size += (dv); \ + } while (0) +#define DUK_HBUFFER_SUB_SIZE(x,dv) do { \ + (x)->size -= (dv); \ + } while (0) +#endif + +#define DUK_HBUFFER_FIXED_GET_SIZE(x) DUK_HBUFFER_GET_SIZE((duk_hbuffer *) (x)) +#define DUK_HBUFFER_FIXED_SET_SIZE(x,v) DUK_HBUFFER_SET_SIZE((duk_hbuffer *) (x)) + +#define DUK_HBUFFER_DYNAMIC_GET_SIZE(x) DUK_HBUFFER_GET_SIZE((duk_hbuffer *) (x)) +#define DUK_HBUFFER_DYNAMIC_SET_SIZE(x,v) DUK_HBUFFER_SET_SIZE((duk_hbuffer *) (x), (v)) +#define DUK_HBUFFER_DYNAMIC_ADD_SIZE(x,dv) DUK_HBUFFER_ADD_SIZE((duk_hbuffer *) (x), (dv)) +#define DUK_HBUFFER_DYNAMIC_SUB_SIZE(x,dv) DUK_HBUFFER_SUB_SIZE((duk_hbuffer *) (x), (dv)) + +#define DUK_HBUFFER_EXTERNAL_GET_SIZE(x) DUK_HBUFFER_GET_SIZE((duk_hbuffer *) (x)) +#define DUK_HBUFFER_EXTERNAL_SET_SIZE(x,v) DUK_HBUFFER_SET_SIZE((duk_hbuffer *) (x), (v)) + +#define DUK_HBUFFER_FIXED_GET_DATA_PTR(heap,x) ((duk_uint8_t *) (((duk_hbuffer_fixed *) (void *) (x)) + 1)) + +#if defined(DUK_USE_HEAPPTR16) +#define DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap,x) \ + ((void *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, ((duk_heaphdr *) (x))->h_extra16)) +#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap,x,v) do { \ + ((duk_heaphdr *) (x))->h_extra16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \ + } while (0) +#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(heap,x) do { \ + ((duk_heaphdr *) (x))->h_extra16 = 0; /* assume 0 <=> NULL */ \ + } while (0) +#else +#define DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap,x) ((x)->curr_alloc) +#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap,x,v) do { \ + (x)->curr_alloc = (void *) (v); \ + } while (0) +#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(heap,x) do { \ + (x)->curr_alloc = (void *) NULL; \ + } while (0) +#endif + +/* No pointer compression because pointer is potentially outside of + * Duktape heap. + */ +#if defined(DUK_USE_HEAPPTR16) +#define DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap,x) \ + ((void *) (x)->curr_alloc) +#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap,x,v) do { \ + (x)->curr_alloc = (void *) (v); \ + } while (0) +#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR_NULL(heap,x) do { \ + (x)->curr_alloc = (void *) NULL; \ + } while (0) +#else +#define DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap,x) \ + ((void *) (x)->curr_alloc) +#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap,x,v) do { \ + (x)->curr_alloc = (void *) (v); \ + } while (0) +#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR_NULL(heap,x) do { \ + (x)->curr_alloc = (void *) NULL; \ + } while (0) +#endif + +/* Get a pointer to the current buffer contents (matching current allocation + * size). May be NULL for zero size dynamic/external buffer. + */ +#if defined(DUK_USE_HEAPPTR16) +#define DUK_HBUFFER_GET_DATA_PTR(heap,x) ( \ + DUK_HBUFFER_HAS_DYNAMIC((x)) ? \ + ( \ + DUK_HBUFFER_HAS_EXTERNAL((x)) ? \ + DUK_HBUFFER_EXTERNAL_GET_DATA_PTR((heap), (duk_hbuffer_external *) (x)) : \ + DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((heap), (duk_hbuffer_dynamic *) (x)) \ + ) : \ + DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), (duk_hbuffer_fixed *) (void *) (x)) \ + ) +#else +/* Without heap pointer compression duk_hbuffer_dynamic and duk_hbuffer_external + * have the same layout so checking for fixed vs. dynamic (or external) is enough. + */ +#define DUK_HBUFFER_GET_DATA_PTR(heap,x) ( \ + DUK_HBUFFER_HAS_DYNAMIC((x)) ? \ + DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((heap), (duk_hbuffer_dynamic *) (x)) : \ + DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), (duk_hbuffer_fixed *) (void *) (x)) \ + ) +#endif + +/* Validity assert. */ +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL_DECL void duk_hbuffer_assert_valid(duk_hbuffer *h); +#define DUK_HBUFFER_ASSERT_VALID(h) do { duk_hbuffer_assert_valid((h)); } while (0) +#else +#define DUK_HBUFFER_ASSERT_VALID(h) do {} while (0) +#endif + +/* + * Structs + */ + +/* Shared prefix for all buffer types. */ +struct duk_hbuffer { + duk_heaphdr hdr; + + /* It's not strictly necessary to track the current size, but + * it is useful for writing robust native code. + */ + + /* Current size. */ +#if defined(DUK_USE_BUFLEN16) + /* Stored in duk_heaphdr unused flags. */ +#else + duk_size_t size; +#endif + + /* + * Data following the header depends on the DUK_HBUFFER_FLAG_DYNAMIC + * flag. + * + * If the flag is clear (the buffer is a fixed size one), the buffer + * data follows the header directly, consisting of 'size' bytes. + * + * If the flag is set, the actual buffer is allocated separately, and + * a few control fields follow the header. Specifically: + * + * - a "void *" pointing to the current allocation + * - a duk_size_t indicating the full allocated size (always >= 'size') + * + * If DUK_HBUFFER_FLAG_EXTERNAL is set, the buffer has been allocated + * by user code, so that Duktape won't be able to resize it and won't + * free it. This allows buffers to point to e.g. an externally + * allocated structure such as a frame buffer. + * + * Unlike strings, no terminator byte (NUL) is guaranteed after the + * data. This would be convenient, but would pad aligned user buffers + * unnecessarily upwards in size. For instance, if user code requested + * a 64-byte dynamic buffer, 65 bytes would actually be allocated which + * would then potentially round upwards to perhaps 68 or 72 bytes. + */ +}; + +/* Fixed buffer; data follows struct, with proper alignment guaranteed by + * struct size. + */ +#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA) +#pragma pack(push, 8) +#endif +struct duk_hbuffer_fixed { + /* A union is used here as a portable struct size / alignment trick: + * by adding a 32-bit or a 64-bit (unused) union member, the size of + * the struct is effectively forced to be a multiple of 4 or 8 bytes + * (respectively) without increasing the size of the struct unless + * necessary. + */ + union { + struct { + duk_heaphdr hdr; +#if defined(DUK_USE_BUFLEN16) + /* Stored in duk_heaphdr unused flags. */ +#else + duk_size_t size; +#endif + } s; +#if (DUK_USE_ALIGN_BY == 4) + duk_uint32_t dummy_for_align4; +#elif (DUK_USE_ALIGN_BY == 8) + duk_double_t dummy_for_align8_1; +#if defined(DUK_USE_64BIT_OPS) + duk_uint64_t dummy_for_align8_2; +#endif +#elif (DUK_USE_ALIGN_BY == 1) + /* no extra padding */ +#else +#error invalid DUK_USE_ALIGN_BY +#endif + } u; + + /* + * Data follows the struct header. The struct size is padded by the + * compiler based on the struct members. This guarantees that the + * buffer data will be aligned-by-4 but not necessarily aligned-by-8. + * + * On platforms where alignment does not matter, the struct padding + * could be removed (if there is any). On platforms where alignment + * by 8 is required, the struct size must be forced to be a multiple + * of 8 by some means. Without it, some user code may break, and also + * Duktape itself breaks (e.g. the compiler stores duk_tvals in a + * dynamic buffer). + */ +} +#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_GCC_ATTR) +__attribute__ ((__aligned__ (8))) +#elif (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_CLANG_ATTR) +__attribute__ ((__aligned__ (8))) +#endif +; +#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA) +#pragma pack(pop) +#endif + +/* Dynamic buffer with 'curr_alloc' pointing to a dynamic area allocated using + * heap allocation primitives. Also used for external buffers when low memory + * options are not used. + */ +struct duk_hbuffer_dynamic { + duk_heaphdr hdr; + +#if defined(DUK_USE_BUFLEN16) + /* Stored in duk_heaphdr unused flags. */ +#else + duk_size_t size; +#endif + +#if defined(DUK_USE_HEAPPTR16) + /* Stored in duk_heaphdr h_extra16. */ +#else + void *curr_alloc; /* may be NULL if alloc_size == 0 */ +#endif + + /* + * Allocation size for 'curr_alloc' is alloc_size. There is no + * automatic NUL terminator for buffers (see above for rationale). + * + * 'curr_alloc' is explicitly allocated with heap allocation + * primitives and will thus always have alignment suitable for + * e.g. duk_tval and an IEEE double. + */ +}; + +/* External buffer with 'curr_alloc' managed by user code and pointing to an + * arbitrary address. When heap pointer compression is not used, this struct + * has the same layout as duk_hbuffer_dynamic. + */ +struct duk_hbuffer_external { + duk_heaphdr hdr; + +#if defined(DUK_USE_BUFLEN16) + /* Stored in duk_heaphdr unused flags. */ +#else + duk_size_t size; +#endif + + /* Cannot be compressed as a heap pointer because may point to + * an arbitrary address. + */ + void *curr_alloc; /* may be NULL if alloc_size == 0 */ +}; + +/* + * Prototypes + */ + +DUK_INTERNAL_DECL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk_small_uint_t flags, void **out_bufdata); +DUK_INTERNAL_DECL void *duk_hbuffer_get_dynalloc_ptr(duk_heap *heap, void *ud); /* indirect allocs */ + +/* dynamic buffer ops */ +DUK_INTERNAL_DECL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf, duk_size_t new_size); +DUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *buf); + +#endif /* DUK_HBUFFER_H_INCLUDED */ diff --git a/third_party/duktape/duk_hbuffer_alloc.c b/third_party/duktape/duk_hbuffer_alloc.c new file mode 100644 index 00000000..c4f99d60 --- /dev/null +++ b/third_party/duktape/duk_hbuffer_alloc.c @@ -0,0 +1,132 @@ +/* + * duk_hbuffer allocation and freeing. + */ + +#include "third_party/duktape/duk_internal.h" + +/* Allocate a new duk_hbuffer of a certain type and return a pointer to it + * (NULL on error). Write buffer data pointer to 'out_bufdata' (only if + * allocation successful). + */ +DUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk_small_uint_t flags, void **out_bufdata) { + duk_hbuffer *res = NULL; + duk_size_t header_size; + duk_size_t alloc_size; + + DUK_ASSERT(heap != NULL); + DUK_ASSERT(out_bufdata != NULL); + + DUK_DDD(DUK_DDDPRINT("allocate hbuffer")); + + /* Size sanity check. Should not be necessary because caller is + * required to check this, but we don't want to cause a segfault + * if the size wraps either in duk_size_t computation or when + * storing the size in a 16-bit field. + */ + if (size > DUK_HBUFFER_MAX_BYTELEN) { + DUK_D(DUK_DPRINT("hbuffer alloc failed: size too large: %ld", (long) size)); + return NULL; /* no need to write 'out_bufdata' */ + } + + if (flags & DUK_BUF_FLAG_EXTERNAL) { + header_size = sizeof(duk_hbuffer_external); + alloc_size = sizeof(duk_hbuffer_external); + } else if (flags & DUK_BUF_FLAG_DYNAMIC) { + header_size = sizeof(duk_hbuffer_dynamic); + alloc_size = sizeof(duk_hbuffer_dynamic); + } else { + header_size = sizeof(duk_hbuffer_fixed); + alloc_size = sizeof(duk_hbuffer_fixed) + size; + DUK_ASSERT(alloc_size >= sizeof(duk_hbuffer_fixed)); /* no wrapping */ + } + + res = (duk_hbuffer *) DUK_ALLOC(heap, alloc_size); + if (DUK_UNLIKELY(res == NULL)) { + goto alloc_error; + } + + /* zero everything unless requested not to do so */ +#if defined(DUK_USE_ZERO_BUFFER_DATA) + duk_memzero((void *) res, + (flags & DUK_BUF_FLAG_NOZERO) ? header_size : alloc_size); +#else + duk_memzero((void *) res, header_size); +#endif + + if (flags & DUK_BUF_FLAG_EXTERNAL) { + duk_hbuffer_external *h; + h = (duk_hbuffer_external *) res; + DUK_UNREF(h); + *out_bufdata = NULL; +#if defined(DUK_USE_EXPLICIT_NULL_INIT) +#if defined(DUK_USE_HEAPPTR16) +/* the compressed pointer is zeroed which maps to NULL, so nothing to do. */ +#else + DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap, h, NULL); +#endif +#endif + DUK_ASSERT(DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap, h) == NULL); + } else if (flags & DUK_BUF_FLAG_DYNAMIC) { + duk_hbuffer_dynamic *h = (duk_hbuffer_dynamic *) res; + void *ptr; + + if (size > 0) { + DUK_ASSERT(!(flags & DUK_BUF_FLAG_EXTERNAL)); /* alloc external with size zero */ + DUK_DDD(DUK_DDDPRINT("dynamic buffer with nonzero size, alloc actual buffer")); +#if defined(DUK_USE_ZERO_BUFFER_DATA) + ptr = DUK_ALLOC_ZEROED(heap, size); +#else + ptr = DUK_ALLOC(heap, size); +#endif + if (DUK_UNLIKELY(ptr == NULL)) { + /* Because size > 0, NULL check is correct */ + goto alloc_error; + } + *out_bufdata = ptr; + + DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, ptr); + } else { + *out_bufdata = NULL; +#if defined(DUK_USE_EXPLICIT_NULL_INIT) +#if defined(DUK_USE_HEAPPTR16) +/* the compressed pointer is zeroed which maps to NULL, so nothing to do. */ +#else + DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, NULL); +#endif +#endif + DUK_ASSERT(DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, h) == NULL); + } + } else { + *out_bufdata = (void *) ((duk_hbuffer_fixed *) (void *) res + 1); + } + + DUK_HBUFFER_SET_SIZE(res, size); + + DUK_HEAPHDR_SET_TYPE(&res->hdr, DUK_HTYPE_BUFFER); + if (flags & DUK_BUF_FLAG_DYNAMIC) { + DUK_HBUFFER_SET_DYNAMIC(res); + if (flags & DUK_BUF_FLAG_EXTERNAL) { + DUK_HBUFFER_SET_EXTERNAL(res); + } + } else { + DUK_ASSERT(!(flags & DUK_BUF_FLAG_EXTERNAL)); + } + DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, &res->hdr); + + DUK_DDD(DUK_DDDPRINT("allocated hbuffer: %p", (void *) res)); + return res; + + alloc_error: + DUK_DD(DUK_DDPRINT("hbuffer allocation failed")); + + DUK_FREE(heap, res); + return NULL; /* no need to write 'out_bufdata' */ +} + +/* For indirect allocs. */ + +DUK_INTERNAL void *duk_hbuffer_get_dynalloc_ptr(duk_heap *heap, void *ud) { + duk_hbuffer_dynamic *buf = (duk_hbuffer_dynamic *) ud; + DUK_UNREF(heap); + return (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, buf); +} diff --git a/third_party/duktape/duk_hbuffer_assert.c b/third_party/duktape/duk_hbuffer_assert.c new file mode 100644 index 00000000..9733945c --- /dev/null +++ b/third_party/duktape/duk_hbuffer_assert.c @@ -0,0 +1,13 @@ +/* + * duk_hbuffer assertion helpers + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_ASSERTIONS) + +DUK_INTERNAL void duk_hbuffer_assert_valid(duk_hbuffer *h) { + DUK_ASSERT(h != NULL); +} + +#endif /* DUK_USE_ASSERTIONS */ diff --git a/third_party/duktape/duk_hbuffer_ops.c b/third_party/duktape/duk_hbuffer_ops.c new file mode 100644 index 00000000..878b7c27 --- /dev/null +++ b/third_party/duktape/duk_hbuffer_ops.c @@ -0,0 +1,78 @@ +/* + * duk_hbuffer operations such as resizing and inserting/appending data to + * a dynamic buffer. + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Resizing + */ + +DUK_INTERNAL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf, duk_size_t new_size) { + void *res; + duk_size_t prev_size; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(buf != NULL); + DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf)); + DUK_ASSERT(!DUK_HBUFFER_HAS_EXTERNAL(buf)); + + /* + * Maximum size check + */ + + if (new_size > DUK_HBUFFER_MAX_BYTELEN) { + DUK_ERROR_RANGE(thr, "buffer too long"); + DUK_WO_NORETURN(return;); + } + + /* + * Note: use indirect realloc variant just in case mark-and-sweep + * (finalizers) might resize this same buffer during garbage + * collection. + */ + + res = DUK_REALLOC_INDIRECT(thr->heap, duk_hbuffer_get_dynalloc_ptr, (void *) buf, new_size); + if (DUK_LIKELY(res != NULL || new_size == 0)) { + /* 'res' may be NULL if new allocation size is 0. */ + + DUK_DDD(DUK_DDDPRINT("resized dynamic buffer %p:%ld -> %p:%ld", + (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, buf), + (long) DUK_HBUFFER_DYNAMIC_GET_SIZE(buf), + (void *) res, + (long) new_size)); + + /* + * The entire allocated buffer area, regardless of actual used + * size, is kept zeroed in resizes for simplicity. If the buffer + * is grown, zero the new part. + */ + + prev_size = DUK_HBUFFER_DYNAMIC_GET_SIZE(buf); + if (new_size > prev_size) { + DUK_ASSERT(new_size - prev_size > 0); +#if defined(DUK_USE_ZERO_BUFFER_DATA) + duk_memzero((void *) ((char *) res + prev_size), + (duk_size_t) (new_size - prev_size)); +#endif + } + + DUK_HBUFFER_DYNAMIC_SET_SIZE(buf, new_size); + DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(thr->heap, buf, res); + } else { + DUK_ERROR_ALLOC_FAILED(thr); + DUK_WO_NORETURN(return;); + } + + DUK_ASSERT(res != NULL || new_size == 0); +} + +DUK_INTERNAL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *buf) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(buf != NULL); + DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf)); + DUK_ASSERT(!DUK_HBUFFER_HAS_EXTERNAL(buf)); + + duk_hbuffer_resize(thr, buf, 0); +} diff --git a/third_party/duktape/duk_hbufobj.h b/third_party/duktape/duk_hbufobj.h new file mode 100644 index 00000000..15587c6a --- /dev/null +++ b/third_party/duktape/duk_hbufobj.h @@ -0,0 +1,127 @@ +/* + * Heap Buffer object representation. Used for all Buffer variants. + */ + +#if !defined(DUK_HBUFOBJ_H_INCLUDED) +#define DUK_HBUFOBJ_H_INCLUDED + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + +/* All element accessors are host endian now (driven by TypedArray spec). */ +#define DUK_HBUFOBJ_ELEM_UINT8 0 +#define DUK_HBUFOBJ_ELEM_UINT8CLAMPED 1 +#define DUK_HBUFOBJ_ELEM_INT8 2 +#define DUK_HBUFOBJ_ELEM_UINT16 3 +#define DUK_HBUFOBJ_ELEM_INT16 4 +#define DUK_HBUFOBJ_ELEM_UINT32 5 +#define DUK_HBUFOBJ_ELEM_INT32 6 +#define DUK_HBUFOBJ_ELEM_FLOAT32 7 +#define DUK_HBUFOBJ_ELEM_FLOAT64 8 +#define DUK_HBUFOBJ_ELEM_MAX 8 + +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL_DECL void duk_hbufobj_assert_valid(duk_hbufobj *h); +#define DUK_HBUFOBJ_ASSERT_VALID(h) do { duk_hbufobj_assert_valid((h)); } while (0) +#else +#define DUK_HBUFOBJ_ASSERT_VALID(h) do {} while (0) +#endif + +/* Get the current data pointer (caller must ensure buf != NULL) as a + * duk_uint8_t ptr. Note that the result may be NULL if the underlying + * buffer has zero size and is not a fixed buffer. + */ +#define DUK_HBUFOBJ_GET_SLICE_BASE(heap,h) \ + (DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \ + (((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR((heap), (h)->buf)) + (h)->offset)) + +/* True if slice is full, i.e. offset is zero and length covers the entire + * buffer. This status may change independently of the duk_hbufobj if + * the underlying buffer is dynamic and changes without the hbufobj + * being changed. + */ +#define DUK_HBUFOBJ_FULL_SLICE(h) \ + (DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \ + ((h)->offset == 0 && (h)->length == DUK_HBUFFER_GET_SIZE((h)->buf))) + +/* Validate that the whole slice [0,length[ is contained in the underlying + * buffer. Caller must ensure 'buf' != NULL. + */ +#define DUK_HBUFOBJ_VALID_SLICE(h) \ + (DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \ + ((h)->offset + (h)->length <= DUK_HBUFFER_GET_SIZE((h)->buf))) + +/* Validate byte read/write for virtual 'offset', i.e. check that the + * offset, taking into account h->offset, is within the underlying + * buffer size. This is a safety check which is needed to ensure + * that even a misconfigured duk_hbufobj never causes memory unsafe + * behavior (e.g. if an underlying dynamic buffer changes after being + * setup). Caller must ensure 'buf' != NULL. + */ +#define DUK_HBUFOBJ_VALID_BYTEOFFSET_INCL(h,off) \ + (DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \ + ((h)->offset + (off) < DUK_HBUFFER_GET_SIZE((h)->buf))) + +#define DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h,off) \ + (DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \ + ((h)->offset + (off) <= DUK_HBUFFER_GET_SIZE((h)->buf))) + +/* Clamp an input byte length (already assumed to be within the nominal + * duk_hbufobj 'length') to the current dynamic buffer limits to yield + * a byte length limit that's safe for memory accesses. This value can + * be invalidated by any side effect because it may trigger a user + * callback that resizes the underlying buffer. + */ +#define DUK_HBUFOBJ_CLAMP_BYTELENGTH(h,len) \ + (DUK_ASSERT_EXPR((h) != NULL), \ + duk_hbufobj_clamp_bytelength((h), (len))) + +/* Typed arrays have virtual indices, ArrayBuffer and DataView do not. */ +#define DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h) ((h)->is_typedarray) + +struct duk_hbufobj { + /* Shared object part. */ + duk_hobject obj; + + /* Underlying buffer (refcounted), may be NULL. */ + duk_hbuffer *buf; + + /* .buffer reference to an ArrayBuffer, may be NULL. */ + duk_hobject *buf_prop; + + /* Slice and accessor information. + * + * Because the underlying buffer may be dynamic, these may be + * invalidated by the buffer being modified so that both offset + * and length should be validated before every access. Behavior + * when the underlying buffer has changed doesn't need to be clean: + * virtual 'length' doesn't need to be affected, reads can return + * zero/NaN, and writes can be ignored. + * + * Note that a data pointer cannot be precomputed because 'buf' may + * be dynamic and its pointer unstable. + */ + + duk_uint_t offset; /* byte offset to buf */ + duk_uint_t length; /* byte index limit for element access, exclusive */ + duk_uint8_t shift; /* element size shift: + * 0 = u8/i8 + * 1 = u16/i16 + * 2 = u32/i32/float + * 3 = double + */ + duk_uint8_t elem_type; /* element type */ + duk_uint8_t is_typedarray; +}; + +DUK_INTERNAL_DECL duk_uint_t duk_hbufobj_clamp_bytelength(duk_hbufobj *h_bufobj, duk_uint_t len); +DUK_INTERNAL_DECL void duk_hbufobj_push_uint8array_from_plain(duk_hthread *thr, duk_hbuffer *h_buf); +DUK_INTERNAL_DECL void duk_hbufobj_push_validated_read(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size); +DUK_INTERNAL_DECL void duk_hbufobj_validated_write(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size); +DUK_INTERNAL_DECL void duk_hbufobj_promote_plain(duk_hthread *thr, duk_idx_t idx); + +#else /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* nothing */ + +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ +#endif /* DUK_HBUFOBJ_H_INCLUDED */ diff --git a/third_party/duktape/duk_hbufobj_misc.c b/third_party/duktape/duk_hbufobj_misc.c new file mode 100644 index 00000000..5d7d01fe --- /dev/null +++ b/third_party/duktape/duk_hbufobj_misc.c @@ -0,0 +1,20 @@ +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_uint_t duk_hbufobj_clamp_bytelength(duk_hbufobj *h_bufobj, duk_uint_t len) { + duk_uint_t buf_size; + duk_uint_t buf_avail; + + DUK_ASSERT(h_bufobj != NULL); + DUK_ASSERT(h_bufobj->buf != NULL); + + buf_size = (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_bufobj->buf); + if (h_bufobj->offset > buf_size) { + /* Slice starting point is beyond current length. */ + return 0; + } + buf_avail = buf_size - h_bufobj->offset; + + return buf_avail >= len ? len : buf_avail; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ diff --git a/third_party/duktape/duk_hcompfunc.h b/third_party/duktape/duk_hcompfunc.h new file mode 100644 index 00000000..8f168ae9 --- /dev/null +++ b/third_party/duktape/duk_hcompfunc.h @@ -0,0 +1,273 @@ +/* + * Heap compiled function (ECMAScript function) representation. + * + * There is a single data buffer containing the ECMAScript function's + * bytecode, constants, and inner functions. + */ + +#if !defined(DUK_HCOMPFUNC_H_INCLUDED) +#define DUK_HCOMPFUNC_H_INCLUDED + +/* + * Field accessor macros + */ + +/* XXX: casts could be improved, especially for GET/SET DATA */ + +#if defined(DUK_USE_HEAPPTR16) +#define DUK_HCOMPFUNC_GET_DATA(heap,h) \ + ((duk_hbuffer_fixed *) (void *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->data16)) +#define DUK_HCOMPFUNC_SET_DATA(heap,h,v) do { \ + (h)->data16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \ + } while (0) +#define DUK_HCOMPFUNC_GET_FUNCS(heap,h) \ + ((duk_hobject **) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->funcs16))) +#define DUK_HCOMPFUNC_SET_FUNCS(heap,h,v) do { \ + (h)->funcs16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \ + } while (0) +#define DUK_HCOMPFUNC_GET_BYTECODE(heap,h) \ + ((duk_instr_t *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->bytecode16))) +#define DUK_HCOMPFUNC_SET_BYTECODE(heap,h,v) do { \ + (h)->bytecode16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \ + } while (0) +#define DUK_HCOMPFUNC_GET_LEXENV(heap,h) \ + ((duk_hobject *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->lex_env16))) +#define DUK_HCOMPFUNC_SET_LEXENV(heap,h,v) do { \ + (h)->lex_env16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \ + } while (0) +#define DUK_HCOMPFUNC_GET_VARENV(heap,h) \ + ((duk_hobject *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->var_env16))) +#define DUK_HCOMPFUNC_SET_VARENV(heap,h,v) do { \ + (h)->var_env16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \ + } while (0) +#else +#define DUK_HCOMPFUNC_GET_DATA(heap,h) ((duk_hbuffer_fixed *) (void *) (h)->data) +#define DUK_HCOMPFUNC_SET_DATA(heap,h,v) do { \ + (h)->data = (duk_hbuffer *) (v); \ + } while (0) +#define DUK_HCOMPFUNC_GET_FUNCS(heap,h) ((h)->funcs) +#define DUK_HCOMPFUNC_SET_FUNCS(heap,h,v) do { \ + (h)->funcs = (v); \ + } while (0) +#define DUK_HCOMPFUNC_GET_BYTECODE(heap,h) ((h)->bytecode) +#define DUK_HCOMPFUNC_SET_BYTECODE(heap,h,v) do { \ + (h)->bytecode = (v); \ + } while (0) +#define DUK_HCOMPFUNC_GET_LEXENV(heap,h) ((h)->lex_env) +#define DUK_HCOMPFUNC_SET_LEXENV(heap,h,v) do { \ + (h)->lex_env = (v); \ + } while (0) +#define DUK_HCOMPFUNC_GET_VARENV(heap,h) ((h)->var_env) +#define DUK_HCOMPFUNC_SET_VARENV(heap,h,v) do { \ + (h)->var_env = (v); \ + } while (0) +#endif + +/* + * Accessor macros for function specific data areas + */ + +/* Note: assumes 'data' is always a fixed buffer */ +#define DUK_HCOMPFUNC_GET_BUFFER_BASE(heap,h) \ + DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPFUNC_GET_DATA((heap), (h))) + +#define DUK_HCOMPFUNC_GET_CONSTS_BASE(heap,h) \ + ((duk_tval *) (void *) DUK_HCOMPFUNC_GET_BUFFER_BASE((heap), (h))) + +#define DUK_HCOMPFUNC_GET_FUNCS_BASE(heap,h) \ + DUK_HCOMPFUNC_GET_FUNCS((heap), (h)) + +#define DUK_HCOMPFUNC_GET_CODE_BASE(heap,h) \ + DUK_HCOMPFUNC_GET_BYTECODE((heap), (h)) + +#define DUK_HCOMPFUNC_GET_CONSTS_END(heap,h) \ + ((duk_tval *) (void *) DUK_HCOMPFUNC_GET_FUNCS((heap), (h))) + +#define DUK_HCOMPFUNC_GET_FUNCS_END(heap,h) \ + ((duk_hobject **) (void *) DUK_HCOMPFUNC_GET_BYTECODE((heap), (h))) + +/* XXX: double evaluation of DUK_HCOMPFUNC_GET_DATA() */ +#define DUK_HCOMPFUNC_GET_CODE_END(heap,h) \ + ((duk_instr_t *) (void *) (DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPFUNC_GET_DATA((heap), (h))) + \ + DUK_HBUFFER_GET_SIZE((duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA((heap), h)))) + +#define DUK_HCOMPFUNC_GET_CONSTS_SIZE(heap,h) \ + ( \ + (duk_size_t) \ + ( \ + ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CONSTS_END((heap), (h))) - \ + ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CONSTS_BASE((heap), (h))) \ + ) \ + ) + +#define DUK_HCOMPFUNC_GET_FUNCS_SIZE(heap,h) \ + ( \ + (duk_size_t) \ + ( \ + ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_FUNCS_END((heap), (h))) - \ + ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_FUNCS_BASE((heap), (h))) \ + ) \ + ) + +#define DUK_HCOMPFUNC_GET_CODE_SIZE(heap,h) \ + ( \ + (duk_size_t) \ + ( \ + ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CODE_END((heap),(h))) - \ + ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CODE_BASE((heap),(h))) \ + ) \ + ) + +#define DUK_HCOMPFUNC_GET_CONSTS_COUNT(heap,h) \ + ((duk_size_t) (DUK_HCOMPFUNC_GET_CONSTS_SIZE((heap), (h)) / sizeof(duk_tval))) + +#define DUK_HCOMPFUNC_GET_FUNCS_COUNT(heap,h) \ + ((duk_size_t) (DUK_HCOMPFUNC_GET_FUNCS_SIZE((heap), (h)) / sizeof(duk_hobject *))) + +#define DUK_HCOMPFUNC_GET_CODE_COUNT(heap,h) \ + ((duk_size_t) (DUK_HCOMPFUNC_GET_CODE_SIZE((heap), (h)) / sizeof(duk_instr_t))) + +/* + * Validity assert + */ + +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL_DECL void duk_hcompfunc_assert_valid(duk_hcompfunc *h); +#define DUK_HCOMPFUNC_ASSERT_VALID(h) do { duk_hcompfunc_assert_valid((h)); } while (0) +#else +#define DUK_HCOMPFUNC_ASSERT_VALID(h) do {} while (0) +#endif + +/* + * Main struct + */ + +struct duk_hcompfunc { + /* shared object part */ + duk_hobject obj; + + /* + * Pointers to function data area for faster access. Function + * data is a buffer shared between all closures of the same + * "template" function. The data buffer is always fixed (non- + * dynamic, hence stable), with a layout as follows: + * + * constants (duk_tval) + * inner functions (duk_hobject *) + * bytecode (duk_instr_t) + * + * Note: bytecode end address can be computed from 'data' buffer + * size. It is not strictly necessary functionally, assuming + * bytecode never jumps outside its allocated area. However, + * it's a safety/robustness feature for avoiding the chance of + * executing random data as bytecode due to a compiler error. + * + * Note: values in the data buffer must be incref'd (they will + * be decref'd on release) for every compiledfunction referring + * to the 'data' element. + */ + + /* Data area, fixed allocation, stable data ptrs. */ +#if defined(DUK_USE_HEAPPTR16) + duk_uint16_t data16; +#else + duk_hbuffer *data; +#endif + + /* No need for constants pointer (= same as data). + * + * When using 16-bit packing alignment to 4 is nice. 'funcs' will be + * 4-byte aligned because 'constants' are duk_tvals. For now the + * inner function pointers are not compressed, so that 'bytecode' will + * also be 4-byte aligned. + */ +#if defined(DUK_USE_HEAPPTR16) + duk_uint16_t funcs16; + duk_uint16_t bytecode16; +#else + duk_hobject **funcs; + duk_instr_t *bytecode; +#endif + + /* Lexenv: lexical environment of closure, NULL for templates. + * Varenv: variable environment of closure, NULL for templates. + */ +#if defined(DUK_USE_HEAPPTR16) + duk_uint16_t lex_env16; + duk_uint16_t var_env16; +#else + duk_hobject *lex_env; + duk_hobject *var_env; +#endif + + /* + * 'nregs' registers are allocated on function entry, at most 'nargs' + * are initialized to arguments, and the rest to undefined. Arguments + * above 'nregs' are not mapped to registers. All registers in the + * active stack range must be initialized because they are GC reachable. + * 'nargs' is needed so that if the function is given more than 'nargs' + * arguments, the additional arguments do not 'clobber' registers + * beyond 'nregs' which must be consistently initialized to undefined. + * + * Usually there is no need to know which registers are mapped to + * local variables. Registers may be allocated to variable in any + * way (even including gaps). However, a register-variable mapping + * must be the same for the duration of the function execution and + * the register cannot be used for anything else. + * + * When looking up variables by name, the '_Varmap' map is used. + * When an activation closes, registers mapped to arguments are + * copied into the environment record based on the same map. The + * reverse map (from register to variable) is not currently needed + * at run time, except for debugging, so it is not maintained. + */ + + duk_uint16_t nregs; /* regs to allocate */ + duk_uint16_t nargs; /* number of arguments allocated to regs */ + + /* + * Additional control information is placed into the object itself + * as internal properties to avoid unnecessary fields for the + * majority of functions. The compiler tries to omit internal + * control fields when possible. + * + * Function templates: + * + * { + * name: "func", // declaration, named function expressions + * fileName: + * _Varmap: { "arg1": 0, "arg2": 1, "varname": 2 }, + * _Formals: [ "arg1", "arg2" ], + * _Source: "function func(arg1, arg2) { ... }", + * _Pc2line: , + * } + * + * Function instances: + * + * { + * length: 2, + * prototype: { constructor: }, + * caller: , + * arguments: , + * name: "func", // declaration, named function expressions + * fileName: + * _Varmap: { "arg1": 0, "arg2": 1, "varname": 2 }, + * _Formals: [ "arg1", "arg2" ], + * _Source: "function func(arg1, arg2) { ... }", + * _Pc2line: , + * } + * + * More detailed description of these properties can be found + * in the documentation. + */ + +#if defined(DUK_USE_DEBUGGER_SUPPORT) + /* Line number range for function. Needed during debugging to + * determine active breakpoints. + */ + duk_uint32_t start_line; + duk_uint32_t end_line; +#endif +}; + +#endif /* DUK_HCOMPFUNC_H_INCLUDED */ diff --git a/third_party/duktape/duk_heap.h b/third_party/duktape/duk_heap.h new file mode 100644 index 00000000..5c3f9b0d --- /dev/null +++ b/third_party/duktape/duk_heap.h @@ -0,0 +1,723 @@ +/* + * Heap structure. + * + * Heap contains allocated heap objects, interned strings, and built-in + * strings for one or more threads. + */ + +#if !defined(DUK_HEAP_H_INCLUDED) +#define DUK_HEAP_H_INCLUDED + +/* alloc function typedefs in duktape.h */ + +/* + * Heap flags + */ + +#define DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED (1U << 0) /* mark-and-sweep marking reached a recursion limit and must use multi-pass marking */ +#define DUK_HEAP_FLAG_INTERRUPT_RUNNING (1U << 1) /* executor interrupt running (used to avoid nested interrupts) */ +#define DUK_HEAP_FLAG_FINALIZER_NORESCUE (1U << 2) /* heap destruction ongoing, finalizer rescue no longer possible */ +#define DUK_HEAP_FLAG_DEBUGGER_PAUSED (1U << 3) /* debugger is paused: talk with debug client until step/resume */ + +#define DUK__HEAP_HAS_FLAGS(heap,bits) ((heap)->flags & (bits)) +#define DUK__HEAP_SET_FLAGS(heap,bits) do { \ + (heap)->flags |= (bits); \ + } while (0) +#define DUK__HEAP_CLEAR_FLAGS(heap,bits) do { \ + (heap)->flags &= ~(bits); \ + } while (0) + +#define DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED) +#define DUK_HEAP_HAS_INTERRUPT_RUNNING(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING) +#define DUK_HEAP_HAS_FINALIZER_NORESCUE(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE) +#define DUK_HEAP_HAS_DEBUGGER_PAUSED(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED) + +#define DUK_HEAP_SET_MARKANDSWEEP_RECLIMIT_REACHED(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED) +#define DUK_HEAP_SET_INTERRUPT_RUNNING(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING) +#define DUK_HEAP_SET_FINALIZER_NORESCUE(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE) +#define DUK_HEAP_SET_DEBUGGER_PAUSED(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED) + +#define DUK_HEAP_CLEAR_MARKANDSWEEP_RECLIMIT_REACHED(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED) +#define DUK_HEAP_CLEAR_INTERRUPT_RUNNING(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING) +#define DUK_HEAP_CLEAR_FINALIZER_NORESCUE(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE) +#define DUK_HEAP_CLEAR_DEBUGGER_PAUSED(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED) + +/* + * Longjmp types, also double as identifying continuation type for a rethrow (in 'finally') + */ + +#define DUK_LJ_TYPE_UNKNOWN 0 /* unused */ +#define DUK_LJ_TYPE_THROW 1 /* value1 -> error object */ +#define DUK_LJ_TYPE_YIELD 2 /* value1 -> yield value, iserror -> error / normal */ +#define DUK_LJ_TYPE_RESUME 3 /* value1 -> resume value, value2 -> resumee thread, iserror -> error/normal */ +#define DUK_LJ_TYPE_BREAK 4 /* value1 -> label number, pseudo-type to indicate a break continuation (for ENDFIN) */ +#define DUK_LJ_TYPE_CONTINUE 5 /* value1 -> label number, pseudo-type to indicate a continue continuation (for ENDFIN) */ +#define DUK_LJ_TYPE_RETURN 6 /* value1 -> return value, pseudo-type to indicate a return continuation (for ENDFIN) */ +#define DUK_LJ_TYPE_NORMAL 7 /* no value, pseudo-type to indicate a normal continuation (for ENDFIN) */ + +/* + * Mark-and-sweep flags + * + * These are separate from heap level flags now but could be merged. + * The heap structure only contains a 'base mark-and-sweep flags' + * field and the GC caller can impose further flags. + */ + +/* Emergency mark-and-sweep: try extra hard, even at the cost of + * performance. + */ +#define DUK_MS_FLAG_EMERGENCY (1U << 0) + +/* Postpone rescue decisions for reachable objects with FINALIZED set. + * Used during finalize_list processing to avoid incorrect rescue + * decisions due to finalize_list being a reachability root. + */ +#define DUK_MS_FLAG_POSTPONE_RESCUE (1U << 1) + +/* Don't compact objects; needed during object property table resize + * to prevent a recursive resize. It would suffice to protect only the + * current object being resized, but this is not yet implemented. + */ +#define DUK_MS_FLAG_NO_OBJECT_COMPACTION (1U << 2) + +/* + * Thread switching + * + * To switch heap->curr_thread, use the macro below so that interrupt counters + * get updated correctly. The macro allows a NULL target thread because that + * happens e.g. in call handling. + */ + +#if defined(DUK_USE_INTERRUPT_COUNTER) +#define DUK_HEAP_SWITCH_THREAD(heap,newthr) duk_heap_switch_thread((heap), (newthr)) +#else +#define DUK_HEAP_SWITCH_THREAD(heap,newthr) do { \ + (heap)->curr_thread = (newthr); \ + } while (0) +#endif + +/* + * Stats + */ + +#if defined(DUK_USE_DEBUG) +#define DUK_STATS_INC(heap,fieldname) do { \ + (heap)->fieldname += 1; \ + } while (0) +#else +#define DUK_STATS_INC(heap,fieldname) do {} while (0) +#endif + +/* + * Other heap related defines + */ + +/* Mark-and-sweep interval is relative to combined count of objects and + * strings kept in the heap during the latest mark-and-sweep pass. + * Fixed point .8 multiplier and .0 adder. Trigger count (interval) is + * decreased by each (re)allocation attempt (regardless of size), and each + * refzero processed object. + * + * 'SKIP' indicates how many (re)allocations to wait until a retry if + * GC is skipped because there is no thread do it with yet (happens + * only during init phases). + */ +#if defined(DUK_USE_REFERENCE_COUNTING) +#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT 12800L /* 50x heap size */ +#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD 1024L +#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_SKIP 256L +#else +#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT 256L /* 1x heap size */ +#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD 1024L +#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_SKIP 256L +#endif + +/* GC torture. */ +#if defined(DUK_USE_GC_TORTURE) +#define DUK_GC_TORTURE(heap) do { duk_heap_mark_and_sweep((heap), 0); } while (0) +#else +#define DUK_GC_TORTURE(heap) do { } while (0) +#endif + +/* Stringcache is used for speeding up char-offset-to-byte-offset + * translations for non-ASCII strings. + */ +#define DUK_HEAP_STRCACHE_SIZE 4 +#define DUK_HEAP_STRINGCACHE_NOCACHE_LIMIT 16 /* strings up to the this length are not cached */ + +/* Some list management macros. */ +#define DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap,hdr) duk_heap_insert_into_heap_allocated((heap), (hdr)) +#if defined(DUK_USE_REFERENCE_COUNTING) +#define DUK_HEAP_REMOVE_FROM_HEAP_ALLOCATED(heap,hdr) duk_heap_remove_from_heap_allocated((heap), (hdr)) +#endif +#if defined(DUK_USE_FINALIZER_SUPPORT) +#define DUK_HEAP_INSERT_INTO_FINALIZE_LIST(heap,hdr) duk_heap_insert_into_finalize_list((heap), (hdr)) +#define DUK_HEAP_REMOVE_FROM_FINALIZE_LIST(heap,hdr) duk_heap_remove_from_finalize_list((heap), (hdr)) +#endif + +/* + * Built-in strings + */ + +/* heap string indices are autogenerated in duk_strings.h */ +#if defined(DUK_USE_ROM_STRINGS) +#define DUK_HEAP_GET_STRING(heap,idx) \ + ((duk_hstring *) DUK_LOSE_CONST(duk_rom_strings_stridx[(idx)])) +#else /* DUK_USE_ROM_STRINGS */ +#if defined(DUK_USE_HEAPPTR16) +#define DUK_HEAP_GET_STRING(heap,idx) \ + ((duk_hstring *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (heap)->strs16[(idx)])) +#else +#define DUK_HEAP_GET_STRING(heap,idx) \ + ((heap)->strs[(idx)]) +#endif +#endif /* DUK_USE_ROM_STRINGS */ + +/* + * Raw memory calls: relative to heap, but no GC interaction + */ + +#define DUK_ALLOC_RAW(heap,size) \ + ((heap)->alloc_func((heap)->heap_udata, (size))) + +#define DUK_REALLOC_RAW(heap,ptr,newsize) \ + ((heap)->realloc_func((heap)->heap_udata, (void *) (ptr), (newsize))) + +#define DUK_FREE_RAW(heap,ptr) \ + ((heap)->free_func((heap)->heap_udata, (void *) (ptr))) + +/* + * Memory calls: relative to heap, GC interaction, but no error throwing. + * + * XXX: Currently a mark-and-sweep triggered by memory allocation will run + * using the heap->heap_thread. This thread is also used for running + * mark-and-sweep finalization; this is not ideal because it breaks the + * isolation between multiple global environments. + * + * Notes: + * + * - DUK_FREE() is required to ignore NULL and any other possible return + * value of a zero-sized alloc/realloc (same as ANSI C free()). + * + * - There is no DUK_REALLOC_ZEROED because we don't assume to know the + * old size. Caller must zero the reallocated memory. + * + * - DUK_REALLOC_INDIRECT() must be used when a mark-and-sweep triggered + * by an allocation failure might invalidate the original 'ptr', thus + * causing a realloc retry to use an invalid pointer. Example: we're + * reallocating the value stack and a finalizer resizes the same value + * stack during mark-and-sweep. The indirect variant requests for the + * current location of the pointer being reallocated using a callback + * right before every realloc attempt; this circuitous approach is used + * to avoid strict aliasing issues in a more straightforward indirect + * pointer (void **) approach. Note: the pointer in the storage + * location is read but is NOT updated; the caller must do that. + */ + +/* callback for indirect reallocs, request for current pointer */ +typedef void *(*duk_mem_getptr)(duk_heap *heap, void *ud); + +#define DUK_ALLOC(heap,size) duk_heap_mem_alloc((heap), (size)) +#define DUK_ALLOC_ZEROED(heap,size) duk_heap_mem_alloc_zeroed((heap), (size)) +#define DUK_REALLOC(heap,ptr,newsize) duk_heap_mem_realloc((heap), (ptr), (newsize)) +#define DUK_REALLOC_INDIRECT(heap,cb,ud,newsize) duk_heap_mem_realloc_indirect((heap), (cb), (ud), (newsize)) +#define DUK_FREE(heap,ptr) duk_heap_mem_free((heap), (ptr)) + +/* + * Checked allocation, relative to a thread + * + * DUK_FREE_CHECKED() doesn't actually throw, but accepts a 'thr' argument + * for convenience. + */ + +#define DUK_ALLOC_CHECKED(thr,size) duk_heap_mem_alloc_checked((thr), (size)) +#define DUK_ALLOC_CHECKED_ZEROED(thr,size) duk_heap_mem_alloc_checked_zeroed((thr), (size)) +#define DUK_FREE_CHECKED(thr,ptr) duk_heap_mem_free((thr)->heap, (ptr)) + +/* + * Memory constants + */ + +#define DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT 10 /* Retry allocation after mark-and-sweep for this + * many times. A single mark-and-sweep round is + * not guaranteed to free all unreferenced memory + * because of finalization (in fact, ANY number of + * rounds is strictly not enough). + */ + +#define DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT 3 /* Starting from this round, use emergency mode + * for mark-and-sweep. + */ + +/* + * Debugger support + */ + +/* Maximum number of breakpoints. Only breakpoints that are set are + * consulted so increasing this has no performance impact. + */ +#define DUK_HEAP_MAX_BREAKPOINTS 16 + +/* Opcode interval for a Date-based status/peek rate limit check. Only + * relevant when debugger is attached. Requesting a timestamp may be a + * slow operation on some platforms so this shouldn't be too low. On the + * other hand a high value makes Duktape react to a pause request slowly. + */ +#define DUK_HEAP_DBG_RATELIMIT_OPCODES 4000 + +/* Milliseconds between status notify and transport peeks. */ +#define DUK_HEAP_DBG_RATELIMIT_MILLISECS 200 + +/* Debugger pause flags. */ +#define DUK_PAUSE_FLAG_ONE_OPCODE (1U << 0) /* pause when a single opcode has been executed */ +#define DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE (1U << 1) /* one opcode pause actually active; artifact of current implementation */ +#define DUK_PAUSE_FLAG_LINE_CHANGE (1U << 2) /* pause when current line number changes */ +#define DUK_PAUSE_FLAG_FUNC_ENTRY (1U << 3) /* pause when entering a function */ +#define DUK_PAUSE_FLAG_FUNC_EXIT (1U << 4) /* pause when exiting current function */ +#define DUK_PAUSE_FLAG_CAUGHT_ERROR (1U << 5) /* pause when about to throw an error that is caught */ +#define DUK_PAUSE_FLAG_UNCAUGHT_ERROR (1U << 6) /* pause when about to throw an error that won't be caught */ + +struct duk_breakpoint { + duk_hstring *filename; + duk_uint32_t line; +}; + +/* + * String cache should ideally be at duk_hthread level, but that would + * cause string finalization to slow down relative to the number of + * threads; string finalization must check the string cache for "weak" + * references to the string being finalized to avoid dead pointers. + * + * Thus, string caches are now at the heap level now. + */ + +struct duk_strcache_entry { + duk_hstring *h; + duk_uint32_t bidx; + duk_uint32_t cidx; +}; + +/* + * Longjmp state, contains the information needed to perform a longjmp. + * Longjmp related values are written to value1, value2, and iserror. + */ + +struct duk_ljstate { + duk_jmpbuf *jmpbuf_ptr; /* current setjmp() catchpoint */ + duk_small_uint_t type; /* longjmp type */ + duk_bool_t iserror; /* isError flag for yield */ + duk_tval value1; /* 1st related value (type specific) */ + duk_tval value2; /* 2nd related value (type specific) */ +}; + +#define DUK_ASSERT_LJSTATE_UNSET(heap) do { \ + DUK_ASSERT(heap != NULL); \ + DUK_ASSERT(heap->lj.type == DUK_LJ_TYPE_UNKNOWN); \ + DUK_ASSERT(heap->lj.iserror == 0); \ + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&heap->lj.value1)); \ + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&heap->lj.value2)); \ + } while (0) +#define DUK_ASSERT_LJSTATE_SET(heap) do { \ + DUK_ASSERT(heap != NULL); \ + DUK_ASSERT(heap->lj.type != DUK_LJ_TYPE_UNKNOWN); \ + } while (0) + +/* + * Literal intern cache + */ + +struct duk_litcache_entry { + const duk_uint8_t *addr; + duk_hstring *h; +}; + +/* + * Main heap structure + */ + +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL_DECL void duk_heap_assert_valid(duk_heap *heap); +#define DUK_HEAP_ASSERT_VALID(heap) do { duk_heap_assert_valid((heap)); } while (0) +#else +#define DUK_HEAP_ASSERT_VALID(heap) do {} while (0) +#endif + +struct duk_heap { + duk_small_uint_t flags; + + /* Allocator functions. */ + duk_alloc_function alloc_func; + duk_realloc_function realloc_func; + duk_free_function free_func; + + /* Heap udata, used for allocator functions but also for other heap + * level callbacks like fatal function, pointer compression, etc. + */ + void *heap_udata; + + /* Fatal error handling, called e.g. when a longjmp() is needed but + * lj.jmpbuf_ptr is NULL. fatal_func must never return; it's not + * declared as "noreturn" because doing that for typedefs is a bit + * challenging portability-wise. + */ + duk_fatal_function fatal_func; + + /* Main list of allocated heap objects. Objects are either here, + * in finalize_list waiting for processing, or in refzero_list + * temporarily while a DECREF refzero cascade finishes. + */ + duk_heaphdr *heap_allocated; + + /* Temporary work list for freeing a cascade of objects when a DECREF + * (or DECREF_NORZ) encounters a zero refcount. Using a work list + * allows fixed C stack size when refcounts go to zero for a chain of + * objects. Outside of DECREF this is always a NULL because DECREF is + * processed without side effects (only memory free calls). + */ +#if defined(DUK_USE_REFERENCE_COUNTING) + duk_heaphdr *refzero_list; +#endif + +#if defined(DUK_USE_FINALIZER_SUPPORT) + /* Work list for objects to be finalized. */ + duk_heaphdr *finalize_list; +#if defined(DUK_USE_ASSERTIONS) + /* Object whose finalizer is executing right now (no nesting). */ + duk_heaphdr *currently_finalizing; +#endif +#endif + + /* Freelist for duk_activations and duk_catchers. */ +#if defined(DUK_USE_CACHE_ACTIVATION) + duk_activation *activation_free; +#endif +#if defined(DUK_USE_CACHE_CATCHER) + duk_catcher *catcher_free; +#endif + + /* Voluntary mark-and-sweep trigger counter. Intentionally signed + * because we continue decreasing the value when voluntary GC cannot + * run. + */ +#if defined(DUK_USE_VOLUNTARY_GC) + duk_int_t ms_trigger_counter; +#endif + + /* Mark-and-sweep recursion control: too deep recursion causes + * multi-pass processing to avoid growing C stack without bound. + */ + duk_uint_t ms_recursion_depth; + + /* Mark-and-sweep flags automatically active (used for critical sections). */ + duk_small_uint_t ms_base_flags; + + /* Mark-and-sweep running flag. Prevents re-entry, and also causes + * refzero events to be ignored (= objects won't be queued to refzero_list). + * + * 0: mark-and-sweep not running + * 1: mark-and-sweep is running + * 2: heap destruction active or debugger active, prevent mark-and-sweep + * and refzero processing (but mark-and-sweep not itself running) + */ + duk_uint_t ms_running; + + /* Mark-and-sweep prevent count, stacking. Used to avoid M&S side + * effects (besides finalizers which are controlled separately) such + * as compacting the string table or object property tables. This + * is also bumped when ms_running is set to prevent recursive re-entry. + * Can also be bumped when mark-and-sweep is not running. + */ + duk_uint_t ms_prevent_count; + + /* Finalizer processing prevent count, stacking. Bumped when finalizers + * are processed to prevent recursive finalizer processing (first call site + * processing finalizers handles all finalizers until the list is empty). + * Can also be bumped explicitly to prevent finalizer execution. + */ + duk_uint_t pf_prevent_count; + + /* When processing finalize_list, don't actually run finalizers but + * queue finalizable objects back to heap_allocated as is. This is + * used during heap destruction to deal with finalizers that keep + * on creating more finalizable garbage. + */ + duk_uint_t pf_skip_finalizers; + +#if defined(DUK_USE_ASSERTIONS) + /* Set when we're in a critical path where an error throw would cause + * e.g. sandboxing/protected call violations or state corruption. This + * is just used for asserts. + */ + duk_bool_t error_not_allowed; +#endif + +#if defined(DUK_USE_ASSERTIONS) + /* Set when heap is still being initialized, helps with writing + * some assertions. + */ + duk_bool_t heap_initializing; +#endif + + /* Marker for detecting internal "double faults", errors thrown when + * we're trying to create an error object, see duk_error_throw.c. + */ + duk_bool_t creating_error; + + /* Marker for indicating we're calling a user error augmentation + * (errCreate/errThrow) function. Errors created/thrown during + * such a call are not augmented. + */ +#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE) + duk_bool_t augmenting_error; +#endif + + /* Longjmp state. */ + duk_ljstate lj; + + /* Heap thread, used internally and for finalization. */ + duk_hthread *heap_thread; + + /* Current running thread. */ + duk_hthread *curr_thread; + + /* Heap level "stash" object (e.g., various reachability roots). */ + duk_hobject *heap_object; + + /* duk_handle_call / duk_handle_safe_call recursion depth limiting */ + duk_int_t call_recursion_depth; + duk_int_t call_recursion_limit; + + /* Mix-in value for computing string hashes; should be reasonably unpredictable. */ + duk_uint32_t hash_seed; + + /* Random number state for duk_util_tinyrandom.c. */ +#if !defined(DUK_USE_GET_RANDOM_DOUBLE) +#if defined(DUK_USE_PREFER_SIZE) || !defined(DUK_USE_64BIT_OPS) + duk_uint32_t rnd_state; /* State for Shamir's three-op algorithm */ +#else + duk_uint64_t rnd_state[2]; /* State for xoroshiro128+ */ +#endif +#endif + + /* Counter for unique local symbol creation. */ + /* XXX: When 64-bit types are available, it would be more efficient to + * use a duk_uint64_t at least for incrementing but maybe also for + * string formatting in the Symbol constructor. + */ + duk_uint32_t sym_counter[2]; + + /* For manual debugging: instruction count based on executor and + * interrupt counter book-keeping. Inspect debug logs to see how + * they match up. + */ +#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG) + duk_int_t inst_count_exec; + duk_int_t inst_count_interrupt; +#endif + + /* Debugger state. */ +#if defined(DUK_USE_DEBUGGER_SUPPORT) + /* Callbacks and udata; dbg_read_cb != NULL is used to indicate attached state. */ + duk_debug_read_function dbg_read_cb; /* required, NULL implies detached */ + duk_debug_write_function dbg_write_cb; /* required */ + duk_debug_peek_function dbg_peek_cb; + duk_debug_read_flush_function dbg_read_flush_cb; + duk_debug_write_flush_function dbg_write_flush_cb; + duk_debug_request_function dbg_request_cb; + duk_debug_detached_function dbg_detached_cb; + void *dbg_udata; + + /* The following are only relevant when debugger is attached. */ + duk_bool_t dbg_processing; /* currently processing messages or breakpoints: don't enter message processing recursively (e.g. no breakpoints when processing debugger eval) */ + duk_bool_t dbg_state_dirty; /* resend state next time executor is about to run */ + duk_bool_t dbg_force_restart; /* force executor restart to recheck breakpoints; used to handle function returns (see GH-303) */ + duk_bool_t dbg_detaching; /* debugger detaching; used to avoid calling detach handler recursively */ + duk_small_uint_t dbg_pause_flags; /* flags for automatic pause behavior */ + duk_activation *dbg_pause_act; /* activation related to pause behavior (pause on line change, function entry/exit) */ + duk_uint32_t dbg_pause_startline; /* starting line number for line change related pause behavior */ + duk_breakpoint dbg_breakpoints[DUK_HEAP_MAX_BREAKPOINTS]; /* breakpoints: [0,breakpoint_count[ gc reachable */ + duk_small_uint_t dbg_breakpoint_count; + duk_breakpoint *dbg_breakpoints_active[DUK_HEAP_MAX_BREAKPOINTS + 1]; /* currently active breakpoints: NULL term, borrowed pointers */ + /* XXX: make active breakpoints actual copies instead of pointers? */ + + /* These are for rate limiting Status notifications and transport peeking. */ + duk_uint_t dbg_exec_counter; /* cumulative opcode execution count (overflows are OK) */ + duk_uint_t dbg_last_counter; /* value of dbg_exec_counter when we last did a Date-based check */ + duk_double_t dbg_last_time; /* time when status/peek was last done (Date-based rate limit) */ + + /* Used to support single-byte stream lookahead. */ + duk_bool_t dbg_have_next_byte; + duk_uint8_t dbg_next_byte; +#endif /* DUK_USE_DEBUGGER_SUPPORT */ +#if defined(DUK_USE_ASSERTIONS) + duk_bool_t dbg_calling_transport; /* transport call in progress, calling into Duktape forbidden */ +#endif + + /* String intern table (weak refs). */ +#if defined(DUK_USE_STRTAB_PTRCOMP) + duk_uint16_t *strtable16; +#else + duk_hstring **strtable; +#endif + duk_uint32_t st_mask; /* mask for lookup, st_size - 1 */ + duk_uint32_t st_size; /* stringtable size */ +#if (DUK_USE_STRTAB_MINSIZE != DUK_USE_STRTAB_MAXSIZE) + duk_uint32_t st_count; /* string count for resize load factor checks */ +#endif + duk_bool_t st_resizing; /* string table is being resized; avoid recursive resize */ + + /* String access cache (codepoint offset -> byte offset) for fast string + * character looping; 'weak' reference which needs special handling in GC. + */ + duk_strcache_entry strcache[DUK_HEAP_STRCACHE_SIZE]; + +#if defined(DUK_USE_LITCACHE_SIZE) + /* Literal intern cache. When enabled, strings interned as literals + * (e.g. duk_push_literal()) will be pinned and cached for the lifetime + * of the heap. + */ + duk_litcache_entry litcache[DUK_USE_LITCACHE_SIZE]; +#endif + + /* Built-in strings. */ +#if defined(DUK_USE_ROM_STRINGS) + /* No field needed when strings are in ROM. */ +#else +#if defined(DUK_USE_HEAPPTR16) + duk_uint16_t strs16[DUK_HEAP_NUM_STRINGS]; +#else + duk_hstring *strs[DUK_HEAP_NUM_STRINGS]; +#endif +#endif + + /* Stats. */ +#if defined(DUK_USE_DEBUG) + duk_int_t stats_exec_opcodes; + duk_int_t stats_exec_interrupt; + duk_int_t stats_exec_throw; + duk_int_t stats_call_all; + duk_int_t stats_call_tailcall; + duk_int_t stats_call_ecmatoecma; + duk_int_t stats_safecall_all; + duk_int_t stats_safecall_nothrow; + duk_int_t stats_safecall_throw; + duk_int_t stats_ms_try_count; + duk_int_t stats_ms_skip_count; + duk_int_t stats_ms_emergency_count; + duk_int_t stats_strtab_intern_hit; + duk_int_t stats_strtab_intern_miss; + duk_int_t stats_strtab_resize_check; + duk_int_t stats_strtab_resize_grow; + duk_int_t stats_strtab_resize_shrink; + duk_int_t stats_strtab_litcache_hit; + duk_int_t stats_strtab_litcache_miss; + duk_int_t stats_strtab_litcache_pin; + duk_int_t stats_object_realloc_props; + duk_int_t stats_object_abandon_array; + duk_int_t stats_getownpropdesc_count; + duk_int_t stats_getownpropdesc_hit; + duk_int_t stats_getownpropdesc_miss; + duk_int_t stats_getpropdesc_count; + duk_int_t stats_getpropdesc_hit; + duk_int_t stats_getpropdesc_miss; + duk_int_t stats_getprop_all; + duk_int_t stats_getprop_arrayidx; + duk_int_t stats_getprop_bufobjidx; + duk_int_t stats_getprop_bufferidx; + duk_int_t stats_getprop_bufferlen; + duk_int_t stats_getprop_stringidx; + duk_int_t stats_getprop_stringlen; + duk_int_t stats_getprop_proxy; + duk_int_t stats_getprop_arguments; + duk_int_t stats_putprop_all; + duk_int_t stats_putprop_arrayidx; + duk_int_t stats_putprop_bufobjidx; + duk_int_t stats_putprop_bufferidx; + duk_int_t stats_putprop_proxy; + duk_int_t stats_getvar_all; + duk_int_t stats_putvar_all; + duk_int_t stats_envrec_delayedcreate; + duk_int_t stats_envrec_create; + duk_int_t stats_envrec_newenv; + duk_int_t stats_envrec_oldenv; + duk_int_t stats_envrec_pushclosure; +#endif +}; + +/* + * Prototypes + */ + +DUK_INTERNAL_DECL +duk_heap *duk_heap_alloc(duk_alloc_function alloc_func, + duk_realloc_function realloc_func, + duk_free_function free_func, + void *heap_udata, + duk_fatal_function fatal_func); +DUK_INTERNAL_DECL void duk_heap_free(duk_heap *heap); +DUK_INTERNAL_DECL void duk_free_hobject(duk_heap *heap, duk_hobject *h); +DUK_INTERNAL_DECL void duk_free_hbuffer(duk_heap *heap, duk_hbuffer *h); +DUK_INTERNAL_DECL void duk_free_hstring(duk_heap *heap, duk_hstring *h); +DUK_INTERNAL_DECL void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr); + +DUK_INTERNAL_DECL void duk_heap_insert_into_heap_allocated(duk_heap *heap, duk_heaphdr *hdr); +#if defined(DUK_USE_REFERENCE_COUNTING) +DUK_INTERNAL_DECL void duk_heap_remove_from_heap_allocated(duk_heap *heap, duk_heaphdr *hdr); +#endif +#if defined(DUK_USE_FINALIZER_SUPPORT) +DUK_INTERNAL_DECL void duk_heap_insert_into_finalize_list(duk_heap *heap, duk_heaphdr *hdr); +DUK_INTERNAL_DECL void duk_heap_remove_from_finalize_list(duk_heap *heap, duk_heaphdr *hdr); +#endif +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL_DECL duk_bool_t duk_heap_in_heap_allocated(duk_heap *heap, duk_heaphdr *ptr); +#endif +#if defined(DUK_USE_INTERRUPT_COUNTER) +DUK_INTERNAL_DECL void duk_heap_switch_thread(duk_heap *heap, duk_hthread *new_thr); +#endif + +DUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen); +DUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t len); +#if defined(DUK_USE_LITCACHE_SIZE) +DUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_literal_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t blen); +#endif +DUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_u32(duk_heap *heap, duk_uint32_t val); +DUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_u32_checked(duk_hthread *thr, duk_uint32_t val); +#if defined(DUK_USE_REFERENCE_COUNTING) +DUK_INTERNAL_DECL void duk_heap_strtable_unlink(duk_heap *heap, duk_hstring *h); +#endif +DUK_INTERNAL_DECL void duk_heap_strtable_unlink_prev(duk_heap *heap, duk_hstring *h, duk_hstring *prev); +DUK_INTERNAL_DECL void duk_heap_strtable_force_resize(duk_heap *heap); +DUK_INTERNAL void duk_heap_strtable_free(duk_heap *heap); +#if defined(DUK_USE_DEBUG) +DUK_INTERNAL void duk_heap_strtable_dump(duk_heap *heap); +#endif + +DUK_INTERNAL_DECL void duk_heap_strcache_string_remove(duk_heap *heap, duk_hstring *h); +DUK_INTERNAL_DECL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *thr, duk_hstring *h, duk_uint_fast32_t char_offset); + +#if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS) +DUK_INTERNAL_DECL void *duk_default_alloc_function(void *udata, duk_size_t size); +DUK_INTERNAL_DECL void *duk_default_realloc_function(void *udata, void *ptr, duk_size_t newsize); +DUK_INTERNAL_DECL void duk_default_free_function(void *udata, void *ptr); +#endif + +DUK_INTERNAL_DECL void *duk_heap_mem_alloc(duk_heap *heap, duk_size_t size); +DUK_INTERNAL_DECL void *duk_heap_mem_alloc_zeroed(duk_heap *heap, duk_size_t size); +DUK_INTERNAL_DECL void *duk_heap_mem_alloc_checked(duk_hthread *thr, duk_size_t size); +DUK_INTERNAL_DECL void *duk_heap_mem_alloc_checked_zeroed(duk_hthread *thr, duk_size_t size); +DUK_INTERNAL_DECL void *duk_heap_mem_realloc(duk_heap *heap, void *ptr, duk_size_t newsize); +DUK_INTERNAL_DECL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr cb, void *ud, duk_size_t newsize); +DUK_INTERNAL_DECL void duk_heap_mem_free(duk_heap *heap, void *ptr); + +DUK_INTERNAL_DECL void duk_heap_free_freelists(duk_heap *heap); + +#if defined(DUK_USE_FINALIZER_SUPPORT) +DUK_INTERNAL_DECL void duk_heap_run_finalizer(duk_heap *heap, duk_hobject *obj); +DUK_INTERNAL_DECL void duk_heap_process_finalize_list(duk_heap *heap); +#endif /* DUK_USE_FINALIZER_SUPPORT */ + +DUK_INTERNAL_DECL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags); + +DUK_INTERNAL_DECL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len); + +#endif /* DUK_HEAP_H_INCLUDED */ diff --git a/third_party/duktape/duk_heap_alloc.c b/third_party/duktape/duk_heap_alloc.c new file mode 100644 index 00000000..2a9844c5 --- /dev/null +++ b/third_party/duktape/duk_heap_alloc.c @@ -0,0 +1,1217 @@ +/* + * duk_heap allocation and freeing. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_ROM_STRINGS) +/* Fixed seed value used with ROM strings. */ +#define DUK__FIXED_HASH_SEED 0xabcd1234 +#endif + +/* + * Free a heap object. + * + * Free heap object and its internal (non-heap) pointers. Assumes that + * caller has removed the object from heap allocated list or the string + * intern table, and any weak references (which strings may have) have + * been already dealt with. + */ + +DUK_INTERNAL void duk_free_hobject(duk_heap *heap, duk_hobject *h) { + DUK_ASSERT(heap != NULL); + DUK_ASSERT(h != NULL); + + DUK_FREE(heap, DUK_HOBJECT_GET_PROPS(heap, h)); + + if (DUK_HOBJECT_IS_COMPFUNC(h)) { + duk_hcompfunc *f = (duk_hcompfunc *) h; + DUK_UNREF(f); + /* Currently nothing to free; 'data' is a heap object */ + } else if (DUK_HOBJECT_IS_NATFUNC(h)) { + duk_hnatfunc *f = (duk_hnatfunc *) h; + DUK_UNREF(f); + /* Currently nothing to free */ + } else if (DUK_HOBJECT_IS_THREAD(h)) { + duk_hthread *t = (duk_hthread *) h; + duk_activation *act; + + DUK_FREE(heap, t->valstack); + + /* Don't free h->resumer because it exists in the heap. + * Callstack entries also contain function pointers which + * are not freed for the same reason. They are decref + * finalized and the targets are freed if necessary based + * on their refcount (or reachability). + */ + for (act = t->callstack_curr; act != NULL;) { + duk_activation *act_next; + duk_catcher *cat; + + for (cat = act->cat; cat != NULL;) { + duk_catcher *cat_next; + + cat_next = cat->parent; + DUK_FREE(heap, (void *) cat); + cat = cat_next; + } + + act_next = act->parent; + DUK_FREE(heap, (void *) act); + act = act_next; + } + + /* XXX: with 'caller' property the callstack would need + * to be unwound to update the 'caller' properties of + * functions in the callstack. + */ + } else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) { + duk_hboundfunc *f = (duk_hboundfunc *) (void *) h; + + DUK_FREE(heap, f->args); + } + + DUK_FREE(heap, (void *) h); +} + +DUK_INTERNAL void duk_free_hbuffer(duk_heap *heap, duk_hbuffer *h) { + DUK_ASSERT(heap != NULL); + DUK_ASSERT(h != NULL); + + if (DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h)) { + duk_hbuffer_dynamic *g = (duk_hbuffer_dynamic *) h; + DUK_DDD(DUK_DDDPRINT("free dynamic buffer %p", (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, g))); + DUK_FREE(heap, DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, g)); + } + DUK_FREE(heap, (void *) h); +} + +DUK_INTERNAL void duk_free_hstring(duk_heap *heap, duk_hstring *h) { + DUK_ASSERT(heap != NULL); + DUK_ASSERT(h != NULL); + + DUK_UNREF(heap); + DUK_UNREF(h); + +#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_FREE) + if (DUK_HSTRING_HAS_EXTDATA(h)) { + DUK_DDD(DUK_DDDPRINT("free extstr: hstring %!O, extdata: %p", + h, DUK_HSTRING_GET_EXTDATA((duk_hstring_external *) h))); + DUK_USE_EXTSTR_FREE(heap->heap_udata, (const void *) DUK_HSTRING_GET_EXTDATA((duk_hstring_external *) h)); + } +#endif + DUK_FREE(heap, (void *) h); +} + +DUK_INTERNAL void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr) { + DUK_ASSERT(heap); + DUK_ASSERT(hdr); + + DUK_DDD(DUK_DDDPRINT("free heaphdr %p, htype %ld", (void *) hdr, (long) DUK_HEAPHDR_GET_TYPE(hdr))); + + switch (DUK_HEAPHDR_GET_TYPE(hdr)) { + case DUK_HTYPE_STRING: + duk_free_hstring(heap, (duk_hstring *) hdr); + break; + case DUK_HTYPE_OBJECT: + duk_free_hobject(heap, (duk_hobject *) hdr); + break; + default: + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) == DUK_HTYPE_BUFFER); + duk_free_hbuffer(heap, (duk_hbuffer *) hdr); + } + +} + +/* + * Free the heap. + * + * Frees heap-related non-heap-tracked allocations such as the + * string intern table; then frees the heap allocated objects; + * and finally frees the heap structure itself. Reference counts + * and GC markers are ignored (and not updated) in this process, + * and finalizers won't be called. + * + * The heap pointer and heap object pointers must not be used + * after this call. + */ + +#if defined(DUK_USE_CACHE_ACTIVATION) +DUK_LOCAL duk_size_t duk__heap_free_activation_freelist(duk_heap *heap) { + duk_activation *act; + duk_activation *act_next; + duk_size_t count_act = 0; + + for (act = heap->activation_free; act != NULL;) { + act_next = act->parent; + DUK_FREE(heap, (void *) act); + act = act_next; +#if defined(DUK_USE_DEBUG) + count_act++; +#endif + } + heap->activation_free = NULL; /* needed when called from mark-and-sweep */ + return count_act; +} +#endif /* DUK_USE_CACHE_ACTIVATION */ + +#if defined(DUK_USE_CACHE_CATCHER) +DUK_LOCAL duk_size_t duk__heap_free_catcher_freelist(duk_heap *heap) { + duk_catcher *cat; + duk_catcher *cat_next; + duk_size_t count_cat = 0; + + for (cat = heap->catcher_free; cat != NULL;) { + cat_next = cat->parent; + DUK_FREE(heap, (void *) cat); + cat = cat_next; +#if defined(DUK_USE_DEBUG) + count_cat++; +#endif + } + heap->catcher_free = NULL; /* needed when called from mark-and-sweep */ + + return count_cat; +} +#endif /* DUK_USE_CACHE_CATCHER */ + +DUK_INTERNAL void duk_heap_free_freelists(duk_heap *heap) { + duk_size_t count_act = 0; + duk_size_t count_cat = 0; + +#if defined(DUK_USE_CACHE_ACTIVATION) + count_act = duk__heap_free_activation_freelist(heap); +#endif +#if defined(DUK_USE_CACHE_CATCHER) + count_cat = duk__heap_free_catcher_freelist(heap); +#endif + DUK_UNREF(heap); + DUK_UNREF(count_act); + DUK_UNREF(count_cat); + + DUK_D(DUK_DPRINT("freed %ld activation freelist entries, %ld catcher freelist entries", + (long) count_act, (long) count_cat)); +} + +DUK_LOCAL void duk__free_allocated(duk_heap *heap) { + duk_heaphdr *curr; + duk_heaphdr *next; + + curr = heap->heap_allocated; + while (curr) { + /* We don't log or warn about freeing zero refcount objects + * because they may happen with finalizer processing. + */ + + DUK_DDD(DUK_DDDPRINT("FINALFREE (allocated): %!iO", + (duk_heaphdr *) curr)); + next = DUK_HEAPHDR_GET_NEXT(heap, curr); + duk_heap_free_heaphdr_raw(heap, curr); + curr = next; + } +} + +#if defined(DUK_USE_FINALIZER_SUPPORT) +DUK_LOCAL void duk__free_finalize_list(duk_heap *heap) { + duk_heaphdr *curr; + duk_heaphdr *next; + + curr = heap->finalize_list; + while (curr) { + DUK_DDD(DUK_DDDPRINT("FINALFREE (finalize_list): %!iO", + (duk_heaphdr *) curr)); + next = DUK_HEAPHDR_GET_NEXT(heap, curr); + duk_heap_free_heaphdr_raw(heap, curr); + curr = next; + } +} +#endif /* DUK_USE_FINALIZER_SUPPORT */ + +DUK_LOCAL void duk__free_stringtable(duk_heap *heap) { + /* strings are only tracked by stringtable */ + duk_heap_strtable_free(heap); +} + +#if defined(DUK_USE_FINALIZER_SUPPORT) +DUK_LOCAL void duk__free_run_finalizers(duk_heap *heap) { + duk_heaphdr *curr; + duk_uint_t round_no; + duk_size_t count_all; + duk_size_t count_finalized; + duk_size_t curr_limit; + + DUK_ASSERT(heap != NULL); + +#if defined(DUK_USE_REFERENCE_COUNTING) + DUK_ASSERT(heap->refzero_list == NULL); /* refzero not running -> must be empty */ +#endif + DUK_ASSERT(heap->finalize_list == NULL); /* mark-and-sweep last pass */ + + if (heap->heap_thread == NULL) { + /* May happen when heap allocation fails right off. There + * cannot be any finalizable objects in this case. + */ + DUK_D(DUK_DPRINT("no heap_thread in heap destruct, assume no finalizable objects")); + return; + } + + /* Prevent finalize_list processing and mark-and-sweep entirely. + * Setting ms_running != 0 also prevents refzero handling from moving + * objects away from the heap_allocated list. The flag name is a bit + * misleading here. + * + * Use a distinct value for ms_running here (== 2) so that assertions + * can detect this situation separate from the normal runtime + * mark-and-sweep case. This allows better assertions (GH-2030). + */ + DUK_ASSERT(heap->pf_prevent_count == 0); + DUK_ASSERT(heap->ms_running == 0); + DUK_ASSERT(heap->ms_prevent_count == 0); + heap->pf_prevent_count = 1; + heap->ms_running = 2; /* Use distinguishable value. */ + heap->ms_prevent_count = 1; /* Bump, because mark-and-sweep assumes it's bumped when ms_running is set. */ + + curr_limit = 0; /* suppress warning, not used */ + for (round_no = 0; ; round_no++) { + curr = heap->heap_allocated; + count_all = 0; + count_finalized = 0; + while (curr) { + count_all++; + if (DUK_HEAPHDR_IS_OBJECT(curr)) { + /* Only objects in heap_allocated may have finalizers. Check that + * the object itself has a _Finalizer property (own or inherited) + * so that we don't execute finalizers for e.g. Proxy objects. + */ + DUK_ASSERT(curr != NULL); + + if (DUK_HOBJECT_HAS_FINALIZER_FAST(heap, (duk_hobject *) curr)) { + if (!DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) curr)) { + DUK_ASSERT(DUK_HEAP_HAS_FINALIZER_NORESCUE(heap)); /* maps to finalizer 2nd argument */ + duk_heap_run_finalizer(heap, (duk_hobject *) curr); + count_finalized++; + } + } + } + curr = DUK_HEAPHDR_GET_NEXT(heap, curr); + } + + /* Each round of finalizer execution may spawn new finalizable objects + * which is normal behavior for some applications. Allow multiple + * rounds of finalization, but use a shrinking limit based on the + * first round to detect the case where a runaway finalizer creates + * an unbounded amount of new finalizable objects. Finalizer rescue + * is not supported: the semantics are unclear because most of the + * objects being finalized here are already reachable. The finalizer + * is given a boolean to indicate that rescue is not possible. + * + * See discussion in: https://github.com/svaarala/duktape/pull/473 + */ + + if (round_no == 0) { + /* Cannot wrap: each object is at least 8 bytes so count is + * at most 1/8 of that. + */ + curr_limit = count_all * 2; + } else { + curr_limit = (curr_limit * 3) / 4; /* Decrease by 25% every round */ + } + DUK_D(DUK_DPRINT("finalizer round %ld complete, %ld objects, tried to execute %ld finalizers, current limit is %ld", + (long) round_no, (long) count_all, (long) count_finalized, (long) curr_limit)); + + if (count_finalized == 0) { + DUK_D(DUK_DPRINT("no more finalizable objects, forced finalization finished")); + break; + } + if (count_finalized >= curr_limit) { + DUK_D(DUK_DPRINT("finalizer count above limit, potentially runaway finalizer; skip remaining finalizers")); + break; + } + } + + DUK_ASSERT(heap->ms_running == 2); + DUK_ASSERT(heap->pf_prevent_count == 1); + heap->ms_running = 0; + heap->pf_prevent_count = 0; +} +#endif /* DUK_USE_FINALIZER_SUPPORT */ + +DUK_INTERNAL void duk_heap_free(duk_heap *heap) { + DUK_D(DUK_DPRINT("free heap: %p", (void *) heap)); + +#if defined(DUK_USE_DEBUG) + duk_heap_strtable_dump(heap); +#endif + +#if defined(DUK_USE_DEBUGGER_SUPPORT) + /* Detach a debugger if attached (can be called multiple times) + * safely. + */ + /* XXX: Add a flag to reject an attempt to re-attach? Otherwise + * the detached callback may immediately reattach. + */ + duk_debug_do_detach(heap); +#endif + + /* Execute finalizers before freeing the heap, even for reachable + * objects. This gives finalizers the chance to free any native + * resources like file handles, allocations made outside Duktape, + * etc. This is quite tricky to get right, so that all finalizer + * guarantees are honored. + * + * Run mark-and-sweep a few times just in case (unreachable object + * finalizers run already here). The last round must rescue objects + * from the previous round without running any more finalizers. This + * ensures rescued objects get their FINALIZED flag cleared so that + * their finalizer is called once more in forced finalization to + * satisfy finalizer guarantees. However, we don't want to run any + * more finalizers because that'd required one more loop, and so on. + * + * XXX: this perhaps requires an execution time limit. + */ + DUK_D(DUK_DPRINT("execute finalizers before freeing heap")); + DUK_ASSERT(heap->pf_skip_finalizers == 0); + DUK_D(DUK_DPRINT("forced gc #1 in heap destruction")); + duk_heap_mark_and_sweep(heap, 0); + DUK_D(DUK_DPRINT("forced gc #2 in heap destruction")); + duk_heap_mark_and_sweep(heap, 0); + DUK_D(DUK_DPRINT("forced gc #3 in heap destruction (don't run finalizers)")); + heap->pf_skip_finalizers = 1; + duk_heap_mark_and_sweep(heap, 0); /* Skip finalizers; queue finalizable objects to heap_allocated. */ + + /* There are never objects in refzero_list at this point, or at any + * point beyond a DECREF (even a DECREF_NORZ). Since Duktape 2.1 + * refzero_list processing is side effect free, so it is always + * processed to completion by a DECREF initially triggering a zero + * refcount. + */ +#if defined(DUK_USE_REFERENCE_COUNTING) + DUK_ASSERT(heap->refzero_list == NULL); /* Always processed to completion inline. */ +#endif +#if defined(DUK_USE_FINALIZER_SUPPORT) + DUK_ASSERT(heap->finalize_list == NULL); /* Last mark-and-sweep with skip_finalizers. */ +#endif + +#if defined(DUK_USE_FINALIZER_SUPPORT) + DUK_D(DUK_DPRINT("run finalizers for remaining finalizable objects")); + DUK_HEAP_SET_FINALIZER_NORESCUE(heap); /* Rescue no longer supported. */ + duk__free_run_finalizers(heap); +#endif /* DUK_USE_FINALIZER_SUPPORT */ + + /* Note: heap->heap_thread, heap->curr_thread, and heap->heap_object + * are on the heap allocated list. + */ + + DUK_D(DUK_DPRINT("freeing temporary freelists")); + duk_heap_free_freelists(heap); + + DUK_D(DUK_DPRINT("freeing heap_allocated of heap: %p", (void *) heap)); + duk__free_allocated(heap); + +#if defined(DUK_USE_REFERENCE_COUNTING) + DUK_ASSERT(heap->refzero_list == NULL); /* Always processed to completion inline. */ +#endif + +#if defined(DUK_USE_FINALIZER_SUPPORT) + DUK_D(DUK_DPRINT("freeing finalize_list of heap: %p", (void *) heap)); + duk__free_finalize_list(heap); +#endif + + DUK_D(DUK_DPRINT("freeing string table of heap: %p", (void *) heap)); + duk__free_stringtable(heap); + + DUK_D(DUK_DPRINT("freeing heap structure: %p", (void *) heap)); + heap->free_func(heap->heap_udata, heap); +} + +/* + * Allocate a heap. + * + * String table is initialized with built-in strings from genbuiltins.py, + * either by dynamically creating the strings or by referring to ROM strings. + */ + +#if defined(DUK_USE_ROM_STRINGS) +DUK_LOCAL duk_bool_t duk__init_heap_strings(duk_heap *heap) { +#if defined(DUK_USE_ASSERTIONS) + duk_small_uint_t i; +#endif + + DUK_UNREF(heap); + + /* With ROM-based strings, heap->strs[] and thr->strs[] are omitted + * so nothing to initialize for strs[]. + */ + +#if defined(DUK_USE_ASSERTIONS) + for (i = 0; i < sizeof(duk_rom_strings_lookup) / sizeof(const duk_hstring *); i++) { + const duk_hstring *h; + duk_uint32_t hash; + + h = duk_rom_strings_lookup[i]; + while (h != NULL) { + hash = duk_heap_hashstring(heap, (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h)); + DUK_DD(DUK_DDPRINT("duk_rom_strings_lookup[%d] -> hash 0x%08lx, computed 0x%08lx", + (int) i, (unsigned long) DUK_HSTRING_GET_HASH(h), (unsigned long) hash)); + DUK_ASSERT(hash == (duk_uint32_t) DUK_HSTRING_GET_HASH(h)); + + h = (const duk_hstring *) h->hdr.h_next; + } + } +#endif + return 1; +} +#else /* DUK_USE_ROM_STRINGS */ + +DUK_LOCAL duk_bool_t duk__init_heap_strings(duk_heap *heap) { + duk_bitdecoder_ctx bd_ctx; + duk_bitdecoder_ctx *bd = &bd_ctx; /* convenience */ + duk_small_uint_t i; + + duk_memzero(&bd_ctx, sizeof(bd_ctx)); + bd->data = (const duk_uint8_t *) duk_strings_data; + bd->length = (duk_size_t) DUK_STRDATA_DATA_LENGTH; + + for (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) { + duk_uint8_t tmp[DUK_STRDATA_MAX_STRLEN]; + duk_small_uint_t len; + duk_hstring *h; + + len = duk_bd_decode_bitpacked_string(bd, tmp); + + /* No need to length check string: it will never exceed even + * the 16-bit length maximum. + */ + DUK_ASSERT(len <= 0xffffUL); + DUK_DDD(DUK_DDDPRINT("intern built-in string %ld", (long) i)); + h = duk_heap_strtable_intern(heap, tmp, len); + if (!h) { + goto failed; + } + DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)); + + /* Special flags checks. Since these strings are always + * reachable and a string cannot appear twice in the string + * table, there's no need to check/set these flags elsewhere. + * The 'internal' flag is set by string intern code. + */ + if (i == DUK_STRIDX_EVAL || i == DUK_STRIDX_LC_ARGUMENTS) { + DUK_HSTRING_SET_EVAL_OR_ARGUMENTS(h); + } + if (i >= DUK_STRIDX_START_RESERVED && i < DUK_STRIDX_END_RESERVED) { + DUK_HSTRING_SET_RESERVED_WORD(h); + if (i >= DUK_STRIDX_START_STRICT_RESERVED) { + DUK_HSTRING_SET_STRICT_RESERVED_WORD(h); + } + } + + DUK_DDD(DUK_DDDPRINT("interned: %!O", (duk_heaphdr *) h)); + + /* XXX: The incref macro takes a thread pointer but doesn't + * use it right now. + */ + DUK_HSTRING_INCREF(_never_referenced_, h); + +#if defined(DUK_USE_HEAPPTR16) + heap->strs16[i] = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) h); +#else + heap->strs[i] = h; +#endif + } + + return 1; + + failed: + return 0; +} +#endif /* DUK_USE_ROM_STRINGS */ + +DUK_LOCAL duk_bool_t duk__init_heap_thread(duk_heap *heap) { + duk_hthread *thr; + + DUK_D(DUK_DPRINT("heap init: alloc heap thread")); + thr = duk_hthread_alloc_unchecked(heap, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_THREAD)); + if (thr == NULL) { + DUK_D(DUK_DPRINT("failed to alloc heap_thread")); + return 0; + } + thr->state = DUK_HTHREAD_STATE_INACTIVE; +#if defined(DUK_USE_ROM_STRINGS) + /* No strs[] pointer. */ +#else /* DUK_USE_ROM_STRINGS */ +#if defined(DUK_USE_HEAPPTR16) + thr->strs16 = heap->strs16; +#else + thr->strs = heap->strs; +#endif +#endif /* DUK_USE_ROM_STRINGS */ + + heap->heap_thread = thr; + DUK_HTHREAD_INCREF(thr, thr); /* Note: first argument not really used */ + + /* 'thr' is now reachable */ + + DUK_D(DUK_DPRINT("heap init: init heap thread stacks")); + if (!duk_hthread_init_stacks(heap, thr)) { + return 0; + } + + /* XXX: this may now fail, and is not handled correctly */ + duk_hthread_create_builtin_objects(thr); + + /* default prototype */ + DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) thr, thr->builtins[DUK_BIDX_THREAD_PROTOTYPE]); + + return 1; +} + +#if defined(DUK_USE_DEBUG) +#define DUK__DUMPSZ(t) do { \ + DUK_D(DUK_DPRINT("" #t "=%ld", (long) sizeof(t))); \ + } while (0) + +/* These is not 100% because format would need to be non-portable "long long". + * Also print out as doubles to catch cases where the "long" type is not wide + * enough; the limits will then not be printed accurately but the magnitude + * will be correct. + */ +#define DUK__DUMPLM_SIGNED_RAW(t,a,b) do { \ + DUK_D(DUK_DPRINT(t "=[%ld,%ld]=[%lf,%lf]", \ + (long) (a), (long) (b), \ + (double) (a), (double) (b))); \ + } while (0) +#define DUK__DUMPLM_UNSIGNED_RAW(t,a,b) do { \ + DUK_D(DUK_DPRINT(t "=[%lu,%lu]=[%lf,%lf]", \ + (unsigned long) (a), (unsigned long) (b), \ + (double) (a), (double) (b))); \ + } while (0) +#define DUK__DUMPLM_SIGNED(t) do { \ + DUK__DUMPLM_SIGNED_RAW("DUK_" #t "_{MIN,MAX}", DUK_##t##_MIN, DUK_##t##_MAX); \ + } while (0) +#define DUK__DUMPLM_UNSIGNED(t) do { \ + DUK__DUMPLM_UNSIGNED_RAW("DUK_" #t "_{MIN,MAX}", DUK_##t##_MIN, DUK_##t##_MAX); \ + } while (0) + +DUK_LOCAL void duk__dump_type_sizes(void) { + DUK_D(DUK_DPRINT("sizeof()")); + + /* basic platform types */ + DUK__DUMPSZ(char); + DUK__DUMPSZ(short); + DUK__DUMPSZ(int); + DUK__DUMPSZ(long); + DUK__DUMPSZ(double); + DUK__DUMPSZ(void *); + DUK__DUMPSZ(size_t); + + /* basic types from duk_features.h */ + DUK__DUMPSZ(duk_uint8_t); + DUK__DUMPSZ(duk_int8_t); + DUK__DUMPSZ(duk_uint16_t); + DUK__DUMPSZ(duk_int16_t); + DUK__DUMPSZ(duk_uint32_t); + DUK__DUMPSZ(duk_int32_t); + DUK__DUMPSZ(duk_uint64_t); + DUK__DUMPSZ(duk_int64_t); + DUK__DUMPSZ(duk_uint_least8_t); + DUK__DUMPSZ(duk_int_least8_t); + DUK__DUMPSZ(duk_uint_least16_t); + DUK__DUMPSZ(duk_int_least16_t); + DUK__DUMPSZ(duk_uint_least32_t); + DUK__DUMPSZ(duk_int_least32_t); +#if defined(DUK_USE_64BIT_OPS) + DUK__DUMPSZ(duk_uint_least64_t); + DUK__DUMPSZ(duk_int_least64_t); +#endif + DUK__DUMPSZ(duk_uint_fast8_t); + DUK__DUMPSZ(duk_int_fast8_t); + DUK__DUMPSZ(duk_uint_fast16_t); + DUK__DUMPSZ(duk_int_fast16_t); + DUK__DUMPSZ(duk_uint_fast32_t); + DUK__DUMPSZ(duk_int_fast32_t); +#if defined(DUK_USE_64BIT_OPS) + DUK__DUMPSZ(duk_uint_fast64_t); + DUK__DUMPSZ(duk_int_fast64_t); +#endif + DUK__DUMPSZ(duk_uintptr_t); + DUK__DUMPSZ(duk_intptr_t); + DUK__DUMPSZ(duk_uintmax_t); + DUK__DUMPSZ(duk_intmax_t); + DUK__DUMPSZ(duk_double_t); + + /* important chosen base types */ + DUK__DUMPSZ(duk_int_t); + DUK__DUMPSZ(duk_uint_t); + DUK__DUMPSZ(duk_int_fast_t); + DUK__DUMPSZ(duk_uint_fast_t); + DUK__DUMPSZ(duk_small_int_t); + DUK__DUMPSZ(duk_small_uint_t); + DUK__DUMPSZ(duk_small_int_fast_t); + DUK__DUMPSZ(duk_small_uint_fast_t); + + /* some derived types */ + DUK__DUMPSZ(duk_codepoint_t); + DUK__DUMPSZ(duk_ucodepoint_t); + DUK__DUMPSZ(duk_idx_t); + DUK__DUMPSZ(duk_errcode_t); + DUK__DUMPSZ(duk_uarridx_t); + + /* tval */ + DUK__DUMPSZ(duk_double_union); + DUK__DUMPSZ(duk_tval); + + /* structs from duk_forwdecl.h */ + DUK__DUMPSZ(duk_jmpbuf); /* just one 'int' for C++ exceptions */ + DUK__DUMPSZ(duk_heaphdr); + DUK__DUMPSZ(duk_heaphdr_string); + DUK__DUMPSZ(duk_hstring); + DUK__DUMPSZ(duk_hstring_external); + DUK__DUMPSZ(duk_hobject); + DUK__DUMPSZ(duk_harray); + DUK__DUMPSZ(duk_hcompfunc); + DUK__DUMPSZ(duk_hnatfunc); + DUK__DUMPSZ(duk_hdecenv); + DUK__DUMPSZ(duk_hobjenv); + DUK__DUMPSZ(duk_hthread); +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + DUK__DUMPSZ(duk_hbufobj); +#endif + DUK__DUMPSZ(duk_hproxy); + DUK__DUMPSZ(duk_hbuffer); + DUK__DUMPSZ(duk_hbuffer_fixed); + DUK__DUMPSZ(duk_hbuffer_dynamic); + DUK__DUMPSZ(duk_hbuffer_external); + DUK__DUMPSZ(duk_propaccessor); + DUK__DUMPSZ(duk_propvalue); + DUK__DUMPSZ(duk_propdesc); + DUK__DUMPSZ(duk_heap); + DUK__DUMPSZ(duk_activation); + DUK__DUMPSZ(duk_catcher); + DUK__DUMPSZ(duk_strcache_entry); + DUK__DUMPSZ(duk_litcache_entry); + DUK__DUMPSZ(duk_ljstate); + DUK__DUMPSZ(duk_fixedbuffer); + DUK__DUMPSZ(duk_bitdecoder_ctx); + DUK__DUMPSZ(duk_bitencoder_ctx); + DUK__DUMPSZ(duk_token); + DUK__DUMPSZ(duk_re_token); + DUK__DUMPSZ(duk_lexer_point); + DUK__DUMPSZ(duk_lexer_ctx); + DUK__DUMPSZ(duk_compiler_instr); + DUK__DUMPSZ(duk_compiler_func); + DUK__DUMPSZ(duk_compiler_ctx); + DUK__DUMPSZ(duk_re_matcher_ctx); + DUK__DUMPSZ(duk_re_compiler_ctx); +} +DUK_LOCAL void duk__dump_type_limits(void) { + DUK_D(DUK_DPRINT("limits")); + + /* basic types */ + DUK__DUMPLM_SIGNED(INT8); + DUK__DUMPLM_UNSIGNED(UINT8); + DUK__DUMPLM_SIGNED(INT_FAST8); + DUK__DUMPLM_UNSIGNED(UINT_FAST8); + DUK__DUMPLM_SIGNED(INT_LEAST8); + DUK__DUMPLM_UNSIGNED(UINT_LEAST8); + DUK__DUMPLM_SIGNED(INT16); + DUK__DUMPLM_UNSIGNED(UINT16); + DUK__DUMPLM_SIGNED(INT_FAST16); + DUK__DUMPLM_UNSIGNED(UINT_FAST16); + DUK__DUMPLM_SIGNED(INT_LEAST16); + DUK__DUMPLM_UNSIGNED(UINT_LEAST16); + DUK__DUMPLM_SIGNED(INT32); + DUK__DUMPLM_UNSIGNED(UINT32); + DUK__DUMPLM_SIGNED(INT_FAST32); + DUK__DUMPLM_UNSIGNED(UINT_FAST32); + DUK__DUMPLM_SIGNED(INT_LEAST32); + DUK__DUMPLM_UNSIGNED(UINT_LEAST32); +#if defined(DUK_USE_64BIT_OPS) + DUK__DUMPLM_SIGNED(INT64); + DUK__DUMPLM_UNSIGNED(UINT64); + DUK__DUMPLM_SIGNED(INT_FAST64); + DUK__DUMPLM_UNSIGNED(UINT_FAST64); + DUK__DUMPLM_SIGNED(INT_LEAST64); + DUK__DUMPLM_UNSIGNED(UINT_LEAST64); +#endif + DUK__DUMPLM_SIGNED(INTPTR); + DUK__DUMPLM_UNSIGNED(UINTPTR); + DUK__DUMPLM_SIGNED(INTMAX); + DUK__DUMPLM_UNSIGNED(UINTMAX); + + /* derived types */ + DUK__DUMPLM_SIGNED(INT); + DUK__DUMPLM_UNSIGNED(UINT); + DUK__DUMPLM_SIGNED(INT_FAST); + DUK__DUMPLM_UNSIGNED(UINT_FAST); + DUK__DUMPLM_SIGNED(SMALL_INT); + DUK__DUMPLM_UNSIGNED(SMALL_UINT); + DUK__DUMPLM_SIGNED(SMALL_INT_FAST); + DUK__DUMPLM_UNSIGNED(SMALL_UINT_FAST); +} + +DUK_LOCAL void duk__dump_misc_options(void) { + DUK_D(DUK_DPRINT("DUK_VERSION: %ld", (long) DUK_VERSION)); + DUK_D(DUK_DPRINT("DUK_GIT_DESCRIBE: %s", DUK_GIT_DESCRIBE)); + DUK_D(DUK_DPRINT("OS string: %s", DUK_USE_OS_STRING)); + DUK_D(DUK_DPRINT("architecture string: %s", DUK_USE_ARCH_STRING)); + DUK_D(DUK_DPRINT("compiler string: %s", DUK_USE_COMPILER_STRING)); + DUK_D(DUK_DPRINT("debug level: %ld", (long) DUK_USE_DEBUG_LEVEL)); +#if defined(DUK_USE_PACKED_TVAL) + DUK_D(DUK_DPRINT("DUK_USE_PACKED_TVAL: yes")); +#else + DUK_D(DUK_DPRINT("DUK_USE_PACKED_TVAL: no")); +#endif +#if defined(DUK_USE_VARIADIC_MACROS) + DUK_D(DUK_DPRINT("DUK_USE_VARIADIC_MACROS: yes")); +#else + DUK_D(DUK_DPRINT("DUK_USE_VARIADIC_MACROS: no")); +#endif +#if defined(DUK_USE_INTEGER_LE) + DUK_D(DUK_DPRINT("integer endianness: little")); +#elif defined(DUK_USE_INTEGER_ME) + DUK_D(DUK_DPRINT("integer endianness: mixed")); +#elif defined(DUK_USE_INTEGER_BE) + DUK_D(DUK_DPRINT("integer endianness: big")); +#else + DUK_D(DUK_DPRINT("integer endianness: ???")); +#endif +#if defined(DUK_USE_DOUBLE_LE) + DUK_D(DUK_DPRINT("IEEE double endianness: little")); +#elif defined(DUK_USE_DOUBLE_ME) + DUK_D(DUK_DPRINT("IEEE double endianness: mixed")); +#elif defined(DUK_USE_DOUBLE_BE) + DUK_D(DUK_DPRINT("IEEE double endianness: big")); +#else + DUK_D(DUK_DPRINT("IEEE double endianness: ???")); +#endif +} +#endif /* DUK_USE_DEBUG */ + +DUK_INTERNAL +duk_heap *duk_heap_alloc(duk_alloc_function alloc_func, + duk_realloc_function realloc_func, + duk_free_function free_func, + void *heap_udata, + duk_fatal_function fatal_func) { + duk_heap *res = NULL; + duk_uint32_t st_initsize; + + DUK_D(DUK_DPRINT("allocate heap")); + + /* + * Random config sanity asserts + */ + + DUK_ASSERT(DUK_USE_STRTAB_MINSIZE >= 64); + + DUK_ASSERT((DUK_HTYPE_STRING & 0x01U) == 0); + DUK_ASSERT((DUK_HTYPE_BUFFER & 0x01U) == 0); + DUK_ASSERT((DUK_HTYPE_OBJECT & 0x01U) == 1); /* DUK_HEAPHDR_IS_OBJECT() relies ont his. */ + + /* + * Debug dump type sizes + */ + +#if defined(DUK_USE_DEBUG) + duk__dump_misc_options(); + duk__dump_type_sizes(); + duk__dump_type_limits(); +#endif + + /* + * If selftests enabled, run them as early as possible. + */ + +#if defined(DUK_USE_SELF_TESTS) + DUK_D(DUK_DPRINT("run self tests")); + if (duk_selftest_run_tests(alloc_func, realloc_func, free_func, heap_udata) > 0) { + fatal_func(heap_udata, "self test(s) failed"); + } + DUK_D(DUK_DPRINT("self tests passed")); +#endif + + /* + * Important assert-like checks that should be enabled even + * when assertions are otherwise not enabled. + */ + +#if defined(DUK_USE_EXEC_REGCONST_OPTIMIZE) + /* Can't check sizeof() using preprocessor so explicit check. + * This will be optimized away in practice; unfortunately a + * warning is generated on some compilers as a result. + */ +#if defined(DUK_USE_PACKED_TVAL) + if (sizeof(duk_tval) != 8) { +#else + if (sizeof(duk_tval) != 16) { +#endif + fatal_func(heap_udata, "sizeof(duk_tval) not 8 or 16, cannot use DUK_USE_EXEC_REGCONST_OPTIMIZE option"); + } +#endif /* DUK_USE_EXEC_REGCONST_OPTIMIZE */ + + /* + * Computed values (e.g. INFINITY) + */ + +#if defined(DUK_USE_COMPUTED_NAN) + do { + /* Workaround for some exotic platforms where NAN is missing + * and the expression (0.0 / 0.0) does NOT result in a NaN. + * Such platforms use the global 'duk_computed_nan' which must + * be initialized at runtime. Use 'volatile' to ensure that + * the compiler will actually do the computation and not try + * to do constant folding which might result in the original + * problem. + */ + volatile double dbl1 = 0.0; + volatile double dbl2 = 0.0; + duk_computed_nan = dbl1 / dbl2; + } while (0); +#endif + +#if defined(DUK_USE_COMPUTED_INFINITY) + do { + /* Similar workaround for INFINITY. */ + volatile double dbl1 = 1.0; + volatile double dbl2 = 0.0; + duk_computed_infinity = dbl1 / dbl2; + } while (0); +#endif + + /* + * Allocate heap struct + * + * Use a raw call, all macros expect the heap to be initialized + */ + +#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 1) + goto failed; +#endif + DUK_D(DUK_DPRINT("alloc duk_heap object")); + res = (duk_heap *) alloc_func(heap_udata, sizeof(duk_heap)); + if (!res) { + goto failed; + } + + /* + * Zero the struct, and start initializing roughly in order + */ + + duk_memzero(res, sizeof(*res)); +#if defined(DUK_USE_ASSERTIONS) + res->heap_initializing = 1; +#endif + + /* explicit NULL inits */ +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + res->heap_udata = NULL; + res->heap_allocated = NULL; +#if defined(DUK_USE_REFERENCE_COUNTING) + res->refzero_list = NULL; +#endif +#if defined(DUK_USE_FINALIZER_SUPPORT) + res->finalize_list = NULL; +#if defined(DUK_USE_ASSERTIONS) + res->currently_finalizing = NULL; +#endif +#endif +#if defined(DUK_USE_CACHE_ACTIVATION) + res->activation_free = NULL; +#endif +#if defined(DUK_USE_CACHE_CATCHER) + res->catcher_free = NULL; +#endif + res->heap_thread = NULL; + res->curr_thread = NULL; + res->heap_object = NULL; +#if defined(DUK_USE_STRTAB_PTRCOMP) + res->strtable16 = NULL; +#else + res->strtable = NULL; +#endif +#if defined(DUK_USE_ROM_STRINGS) + /* no res->strs[] */ +#else /* DUK_USE_ROM_STRINGS */ +#if defined(DUK_USE_HEAPPTR16) + /* res->strs16[] is zeroed and zero decodes to NULL, so no NULL inits. */ +#else + { + duk_small_uint_t i; + for (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) { + res->strs[i] = NULL; + } + } +#endif +#endif /* DUK_USE_ROM_STRINGS */ +#if defined(DUK_USE_DEBUGGER_SUPPORT) + res->dbg_read_cb = NULL; + res->dbg_write_cb = NULL; + res->dbg_peek_cb = NULL; + res->dbg_read_flush_cb = NULL; + res->dbg_write_flush_cb = NULL; + res->dbg_request_cb = NULL; + res->dbg_udata = NULL; + res->dbg_pause_act = NULL; +#endif +#endif /* DUK_USE_EXPLICIT_NULL_INIT */ + + res->alloc_func = alloc_func; + res->realloc_func = realloc_func; + res->free_func = free_func; + res->heap_udata = heap_udata; + res->fatal_func = fatal_func; + + /* XXX: for now there's a pointer packing zero assumption, i.e. + * NULL <=> compressed pointer 0. If this is removed, may need + * to precompute e.g. null16 here. + */ + + /* res->ms_trigger_counter == 0 -> now causes immediate GC; which is OK */ + + /* Prevent mark-and-sweep and finalizer execution until heap is completely + * initialized. + */ + DUK_ASSERT(res->ms_prevent_count == 0); + DUK_ASSERT(res->pf_prevent_count == 0); + res->ms_prevent_count = 1; + res->pf_prevent_count = 1; + DUK_ASSERT(res->ms_running == 0); + + res->call_recursion_depth = 0; + res->call_recursion_limit = DUK_USE_NATIVE_CALL_RECLIMIT; + + /* XXX: use the pointer as a seed for now: mix in time at least */ + + /* The casts through duk_uintptr_t is to avoid the following GCC warning: + * + * warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] + * + * This still generates a /Wp64 warning on VS2010 when compiling for x86. + */ +#if defined(DUK_USE_ROM_STRINGS) + /* XXX: make a common DUK_USE_ option, and allow custom fixed seed? */ + DUK_D(DUK_DPRINT("using rom strings, force heap hash_seed to fixed value 0x%08lx", (long) DUK__FIXED_HASH_SEED)); + res->hash_seed = (duk_uint32_t) DUK__FIXED_HASH_SEED; +#else /* DUK_USE_ROM_STRINGS */ + res->hash_seed = (duk_uint32_t) (duk_uintptr_t) res; +#if !defined(DUK_USE_STRHASH_DENSE) + res->hash_seed ^= 5381; /* Bernstein hash init value is normally 5381; XOR it in in case pointer low bits are 0 */ +#endif +#endif /* DUK_USE_ROM_STRINGS */ + +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + res->lj.jmpbuf_ptr = NULL; +#endif + DUK_ASSERT(res->lj.type == DUK_LJ_TYPE_UNKNOWN); /* zero */ + DUK_ASSERT(res->lj.iserror == 0); + DUK_TVAL_SET_UNDEFINED(&res->lj.value1); + DUK_TVAL_SET_UNDEFINED(&res->lj.value2); + + DUK_ASSERT_LJSTATE_UNSET(res); + + /* + * Init stringtable: fixed variant + */ + + st_initsize = DUK_USE_STRTAB_MINSIZE; +#if defined(DUK_USE_STRTAB_PTRCOMP) + res->strtable16 = (duk_uint16_t *) alloc_func(heap_udata, sizeof(duk_uint16_t) * st_initsize); + if (res->strtable16 == NULL) { + goto failed; + } +#else + res->strtable = (duk_hstring **) alloc_func(heap_udata, sizeof(duk_hstring *) * st_initsize); + if (res->strtable == NULL) { + goto failed; + } +#endif + res->st_size = st_initsize; + res->st_mask = st_initsize - 1; +#if (DUK_USE_STRTAB_MINSIZE != DUK_USE_STRTAB_MAXSIZE) + DUK_ASSERT(res->st_count == 0); +#endif + +#if defined(DUK_USE_STRTAB_PTRCOMP) + /* zero assumption */ + duk_memzero(res->strtable16, sizeof(duk_uint16_t) * st_initsize); +#else +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + { + duk_uint32_t i; + for (i = 0; i < st_initsize; i++) { + res->strtable[i] = NULL; + } + } +#else + duk_memzero(res->strtable, sizeof(duk_hstring *) * st_initsize); +#endif /* DUK_USE_EXPLICIT_NULL_INIT */ +#endif /* DUK_USE_STRTAB_PTRCOMP */ + + /* + * Init stringcache + */ + +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + { + duk_uint_t i; + for (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) { + res->strcache[i].h = NULL; + } + } +#endif + + /* + * Init litcache + */ +#if defined(DUK_USE_LITCACHE_SIZE) + DUK_ASSERT(DUK_USE_LITCACHE_SIZE > 0); + DUK_ASSERT(DUK_IS_POWER_OF_TWO((duk_uint_t) DUK_USE_LITCACHE_SIZE)); +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + { + duk_uint_t i; + for (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) { + res->litcache[i].addr = NULL; + res->litcache[i].h = NULL; + } + } +#endif +#endif /* DUK_USE_LITCACHE_SIZE */ + + /* XXX: error handling is incomplete. It would be cleanest if + * there was a setjmp catchpoint, so that all init code could + * freely throw errors. If that were the case, the return code + * passing here could be removed. + */ + + /* + * Init built-in strings + */ + +#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 2) + goto failed; +#endif + DUK_D(DUK_DPRINT("heap init: initialize heap strings")); + if (!duk__init_heap_strings(res)) { + goto failed; + } + + /* + * Init the heap thread + */ + +#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 3) + goto failed; +#endif + DUK_D(DUK_DPRINT("heap init: initialize heap thread")); + if (!duk__init_heap_thread(res)) { + goto failed; + } + + /* + * Init the heap object + */ + +#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 4) + goto failed; +#endif + DUK_D(DUK_DPRINT("heap init: initialize heap object")); + DUK_ASSERT(res->heap_thread != NULL); + res->heap_object = duk_hobject_alloc_unchecked(res, DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT)); + if (res->heap_object == NULL) { + goto failed; + } + DUK_HOBJECT_INCREF(res->heap_thread, res->heap_object); + + /* + * Odds and ends depending on the heap thread + */ + +#if !defined(DUK_USE_GET_RANDOM_DOUBLE) +#if defined(DUK_USE_PREFER_SIZE) || !defined(DUK_USE_64BIT_OPS) + res->rnd_state = (duk_uint32_t) duk_time_get_ecmascript_time(res->heap_thread); + duk_util_tinyrandom_prepare_seed(res->heap_thread); +#else + res->rnd_state[0] = (duk_uint64_t) duk_time_get_ecmascript_time(res->heap_thread); + DUK_ASSERT(res->rnd_state[1] == 0); /* Not filled here, filled in by seed preparation. */ +#if 0 /* Manual test values matching misc/xoroshiro128plus_test.c. */ + res->rnd_state[0] = DUK_U64_CONSTANT(0xdeadbeef12345678); + res->rnd_state[1] = DUK_U64_CONSTANT(0xcafed00d12345678); +#endif + duk_util_tinyrandom_prepare_seed(res->heap_thread); + /* Mix in heap pointer: this ensures that if two Duktape heaps are + * created on the same millisecond, they get a different PRNG + * sequence (unless e.g. virtual memory addresses cause also the + * heap object pointer to be the same). + */ + { + duk_uint64_t tmp_u64; + tmp_u64 = 0; + duk_memcpy((void *) &tmp_u64, + (const void *) &res, + (size_t) (sizeof(void *) >= sizeof(duk_uint64_t) ? sizeof(duk_uint64_t) : sizeof(void *))); + res->rnd_state[1] ^= tmp_u64; + } + do { + duk_small_uint_t i; + for (i = 0; i < 10; i++) { + /* Throw away a few initial random numbers just in + * case. Probably unnecessary due to SplitMix64 + * preparation. + */ + (void) duk_util_tinyrandom_get_double(res->heap_thread); + } + } while (0); +#endif +#endif + + /* + * Allow finalizer and mark-and-sweep processing. + */ + + DUK_D(DUK_DPRINT("heap init: allow finalizer/mark-and-sweep processing")); + DUK_ASSERT(res->ms_prevent_count == 1); + DUK_ASSERT(res->pf_prevent_count == 1); + res->ms_prevent_count = 0; + res->pf_prevent_count = 0; + DUK_ASSERT(res->ms_running == 0); +#if defined(DUK_USE_ASSERTIONS) + res->heap_initializing = 0; +#endif + + /* + * All done. + */ + + DUK_D(DUK_DPRINT("allocated heap: %p", (void *) res)); + return res; + + failed: + DUK_D(DUK_DPRINT("heap allocation failed")); + + if (res != NULL) { + /* Assumes that allocated pointers and alloc funcs are valid + * if res exists. + */ + DUK_ASSERT(res->ms_prevent_count == 1); + DUK_ASSERT(res->pf_prevent_count == 1); + DUK_ASSERT(res->ms_running == 0); + if (res->heap_thread != NULL) { + res->ms_prevent_count = 0; + res->pf_prevent_count = 0; + } +#if defined(DUK_USE_ASSERTIONS) + res->heap_initializing = 0; +#endif + + DUK_ASSERT(res->alloc_func != NULL); + DUK_ASSERT(res->realloc_func != NULL); + DUK_ASSERT(res->free_func != NULL); + duk_heap_free(res); + } + + return NULL; +} diff --git a/third_party/duktape/duk_heap_finalize.c b/third_party/duktape/duk_heap_finalize.c new file mode 100644 index 00000000..65c6e4e9 --- /dev/null +++ b/third_party/duktape/duk_heap_finalize.c @@ -0,0 +1,445 @@ +/* + * Finalizer handling. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_FINALIZER_SUPPORT) + +/* + * Fake torture finalizer. + */ + +#if defined(DUK_USE_FINALIZER_TORTURE) +DUK_LOCAL duk_ret_t duk__fake_global_finalizer(duk_hthread *thr) { + DUK_DD(DUK_DDPRINT("fake global torture finalizer executed")); + + /* Require a lot of stack to force a value stack grow/shrink. */ + duk_require_stack(thr, 100000); + + /* Force a reallocation with pointer change for value stack + * to maximize side effects. + */ + duk_hthread_valstack_torture_realloc(thr); + + /* Inner function call, error throw. */ + duk_eval_string_noresult(thr, + "(function dummy() {\n" + " dummy.prototype = null; /* break reference loop */\n" + " try {\n" + " throw 'fake-finalizer-dummy-error';\n" + " } catch (e) {\n" + " void e;\n" + " }\n" + "})()"); + + /* The above creates garbage (e.g. a function instance). Because + * the function/prototype reference loop is broken, it gets collected + * immediately by DECREF. If Function.prototype has a _Finalizer + * property (happens in some test cases), the garbage gets queued to + * finalize_list. This still won't cause an infinite loop because + * the torture finalizer is called once per finalize_list run and + * the garbage gets handled in the same run. (If the garbage needs + * mark-and-sweep collection, an infinite loop might ensue.) + */ + return 0; +} + +DUK_LOCAL void duk__run_global_torture_finalizer(duk_hthread *thr) { + DUK_ASSERT(thr != NULL); + + /* Avoid fake finalization when callstack limit is near. Otherwise + * a callstack limit error will be created, then refzero'ed. The + * +5 headroom is conservative. + */ + if (thr->heap->call_recursion_depth + 5 >= thr->heap->call_recursion_limit || + thr->callstack_top + 5 >= DUK_USE_CALLSTACK_LIMIT) { + DUK_D(DUK_DPRINT("skip global torture finalizer, too little headroom for call recursion or call stack size")); + return; + } + + /* Run fake finalizer. Avoid creating unnecessary garbage. */ + duk_push_c_function(thr, duk__fake_global_finalizer, 0 /*nargs*/); + (void) duk_pcall(thr, 0 /*nargs*/); + duk_pop(thr); +} +#endif /* DUK_USE_FINALIZER_TORTURE */ + +/* + * Process the finalize_list to completion. + * + * An object may be placed on finalize_list by either refcounting or + * mark-and-sweep. The refcount of objects placed by refcounting will be + * zero; the refcount of objects placed by mark-and-sweep is > 0. In both + * cases the refcount is bumped by 1 artificially so that a REFZERO event + * can never happen while an object is waiting for finalization. Without + * this bump a REFZERO could now happen because user code may call + * duk_push_heapptr() and then pop a value even when it's on finalize_list. + * + * List processing assumes refcounts are kept up-to-date at all times, so + * that once the finalizer returns, a zero refcount is a reliable reason to + * free the object immediately rather than place it back to the heap. This + * is the case because we run outside of refzero_list processing so that + * DECREF cascades are handled fully inline. + * + * For mark-and-sweep queued objects (had_zero_refcount false) the object + * may be freed immediately if its refcount is zero after the finalizer call + * (i.e. finalizer removed the reference loop for the object). If not, the + * next mark-and-sweep will collect the object unless it has become reachable + * (i.e. rescued) by that time and its refcount hasn't fallen to zero before + * that. Mark-and-sweep detects these objects because their FINALIZED flag + * is set. + * + * There's an inherent limitation for mark-and-sweep finalizer rescuing: an + * object won't get refinalized if (1) it's rescued, but (2) becomes + * unreachable before mark-and-sweep has had time to notice it. The next + * mark-and-sweep round simply doesn't have any information of whether the + * object has been unreachable the whole time or not (the only way to get + * that information would be a mark-and-sweep pass for *every finalized + * object*). This is awkward for the application because the mark-and-sweep + * round is not generally visible or under full application control. + * + * For refcount queued objects (had_zero_refcount true) the object is either + * immediately freed or rescued, and waiting for a mark-and-sweep round is not + * necessary (or desirable); FINALIZED is cleared when a rescued object is + * queued back to heap_allocated. The object is eligible for finalization + * again (either via refcounting or mark-and-sweep) immediately after being + * rescued. If a refcount finalized object is placed into an unreachable + * reference loop by its finalizer, it will get collected by mark-and-sweep + * and currently the finalizer will execute again. + * + * There's a special case where: + * + * - Mark-and-sweep queues an object to finalize_list for finalization. + * - The finalizer is executed, FINALIZED is set, and object is queued + * back to heap_allocated, waiting for a new mark-and-sweep round. + * - The object's refcount drops to zero before mark-and-sweep has a + * chance to run another round and make a rescue/free decision. + * + * This is now handled by refzero code: if an object has a finalizer but + * FINALIZED is already set, the object is freed without finalizer processing. + * The outcome is the same as if mark-and-sweep was executed at that point; + * mark-and-sweep would also free the object without another finalizer run. + * This could also be changed so that the refzero-triggered finalizer *IS* + * executed: being refzero collected implies someone has operated on the + * object so it hasn't been totally unreachable the whole time. This would + * risk a finalizer loop however. + */ + +DUK_INTERNAL void duk_heap_process_finalize_list(duk_heap *heap) { + duk_heaphdr *curr; +#if defined(DUK_USE_DEBUG) + duk_size_t count = 0; +#endif + + DUK_DDD(DUK_DDDPRINT("duk_heap_process_finalize_list: %p", (void *) heap)); + + if (heap->pf_prevent_count != 0) { + DUK_DDD(DUK_DDDPRINT("skip finalize_list processing: pf_prevent_count != 0")); + return; + } + + /* Heap alloc prevents mark-and-sweep before heap_thread is ready. */ + DUK_ASSERT(heap != NULL); + DUK_ASSERT(heap->heap_thread != NULL); + DUK_ASSERT(heap->heap_thread->valstack != NULL); +#if defined(DUK_USE_REFERENCE_COUNTING) + DUK_ASSERT(heap->refzero_list == NULL); +#endif + + DUK_ASSERT(heap->pf_prevent_count == 0); + heap->pf_prevent_count = 1; + + /* Mark-and-sweep no longer needs to be prevented when running + * finalizers: mark-and-sweep skips any rescue decisions if there + * are any objects in finalize_list when mark-and-sweep is entered. + * This protects finalized objects from incorrect rescue decisions + * caused by finalize_list being a reachability root and only + * partially processed. Freeing decisions are not postponed. + */ + + /* When finalizer torture is enabled, make a fake finalizer call with + * maximum side effects regardless of whether finalize_list is empty. + */ +#if defined(DUK_USE_FINALIZER_TORTURE) + duk__run_global_torture_finalizer(heap->heap_thread); +#endif + + /* Process finalize_list until it becomes empty. There's currently no + * protection against a finalizer always creating more garbage. + */ + while ((curr = heap->finalize_list) != NULL) { +#if defined(DUK_USE_REFERENCE_COUNTING) + duk_bool_t queue_back; +#endif + + DUK_DD(DUK_DDPRINT("processing finalize_list entry: %p -> %!iO", (void *) curr, curr)); + + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT); /* Only objects have finalizers. */ + DUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(curr)); + DUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(curr)); + DUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZABLE(curr)); /* All objects on finalize_list will have this flag (except object being finalized right now). */ + DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr)); /* Queueing code ensures. */ + DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(curr)); /* ROM objects never get freed (or finalized). */ + +#if defined(DUK_USE_ASSERTIONS) + DUK_ASSERT(heap->currently_finalizing == NULL); + heap->currently_finalizing = curr; +#endif + + /* Clear FINALIZABLE for object being finalized, so that + * duk_push_heapptr() can properly ignore the object. + */ + DUK_HEAPHDR_CLEAR_FINALIZABLE(curr); + + if (DUK_LIKELY(!heap->pf_skip_finalizers)) { + /* Run the finalizer, duk_heap_run_finalizer() sets + * and checks for FINALIZED to prevent the finalizer + * from executing multiple times per finalization cycle. + * (This safeguard shouldn't be actually needed anymore). + */ + +#if defined(DUK_USE_REFERENCE_COUNTING) + duk_bool_t had_zero_refcount; +#endif + + /* The object's refcount is >0 throughout so it won't be + * refzero processed prematurely. + */ +#if defined(DUK_USE_REFERENCE_COUNTING) + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) >= 1); + had_zero_refcount = (DUK_HEAPHDR_GET_REFCOUNT(curr) == 1); /* Preincremented on finalize_list insert. */ +#endif + + DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr)); + duk_heap_run_finalizer(heap, (duk_hobject *) curr); /* must never longjmp */ + DUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZED(curr)); + /* XXX: assert that object is still in finalize_list + * when duk_push_heapptr() allows automatic rescue. + */ + +#if defined(DUK_USE_REFERENCE_COUNTING) + DUK_DD(DUK_DDPRINT("refcount after finalizer (includes bump): %ld", (long) DUK_HEAPHDR_GET_REFCOUNT(curr))); + if (DUK_HEAPHDR_GET_REFCOUNT(curr) == 1) { /* Only artificial bump in refcount? */ +#if defined(DUK_USE_DEBUG) + if (had_zero_refcount) { + DUK_DD(DUK_DDPRINT("finalized object's refcount is zero -> free immediately (refcount queued)")); + } else { + DUK_DD(DUK_DDPRINT("finalized object's refcount is zero -> free immediately (mark-and-sweep queued)")); + } +#endif + queue_back = 0; + } else +#endif + { +#if defined(DUK_USE_REFERENCE_COUNTING) + queue_back = 1; + if (had_zero_refcount) { + /* When finalization is triggered + * by refzero and we queue the object + * back, clear FINALIZED right away + * so that the object can be refinalized + * immediately if necessary. + */ + DUK_HEAPHDR_CLEAR_FINALIZED(curr); + } +#endif + } + } else { + /* Used during heap destruction: don't actually run finalizers + * because we're heading into forced finalization. Instead, + * queue finalizable objects back to the heap_allocated list. + */ + DUK_D(DUK_DPRINT("skip finalizers flag set, queue object to heap_allocated without finalizing")); + DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr)); +#if defined(DUK_USE_REFERENCE_COUNTING) + queue_back = 1; +#endif + } + + /* Dequeue object from finalize_list. Note that 'curr' may no + * longer be finalize_list head because new objects may have + * been queued to the list. As a result we can't optimize for + * the single-linked heap case and must scan the list for + * removal, typically the scan is very short however. + */ + DUK_HEAP_REMOVE_FROM_FINALIZE_LIST(heap, curr); + + /* Queue back to heap_allocated or free immediately. */ +#if defined(DUK_USE_REFERENCE_COUNTING) + if (queue_back) { + /* FINALIZED is only cleared if object originally + * queued for finalization by refcounting. For + * mark-and-sweep FINALIZED is left set, so that + * next mark-and-sweep round can make a rescue/free + * decision. + */ + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) >= 1); + DUK_HEAPHDR_PREDEC_REFCOUNT(curr); /* Remove artificial refcount bump. */ + DUK_HEAPHDR_CLEAR_FINALIZABLE(curr); + DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, curr); + } else { + /* No need to remove the refcount bump here. */ + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT); /* currently, always the case */ + DUK_DD(DUK_DDPRINT("refcount finalize after finalizer call: %!O", curr)); + duk_hobject_refcount_finalize_norz(heap, (duk_hobject *) curr); + duk_free_hobject(heap, (duk_hobject *) curr); + DUK_DD(DUK_DDPRINT("freed hobject after finalization: %p", (void *) curr)); + } +#else /* DUK_USE_REFERENCE_COUNTING */ + DUK_HEAPHDR_CLEAR_FINALIZABLE(curr); + DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, curr); +#endif /* DUK_USE_REFERENCE_COUNTING */ + +#if defined(DUK_USE_DEBUG) + count++; +#endif + +#if defined(DUK_USE_ASSERTIONS) + DUK_ASSERT(heap->currently_finalizing != NULL); + heap->currently_finalizing = NULL; +#endif + } + + /* finalize_list will always be processed completely. */ + DUK_ASSERT(heap->finalize_list == NULL); + +#if 0 + /* While NORZ macros are used above, this is unnecessary because the + * only pending side effects are now finalizers, and finalize_list is + * empty. + */ + DUK_REFZERO_CHECK_SLOW(heap->heap_thread); +#endif + + /* Prevent count may be bumped while finalizers run, but should always + * be reliably unbumped by the time we get here. + */ + DUK_ASSERT(heap->pf_prevent_count == 1); + heap->pf_prevent_count = 0; + +#if defined(DUK_USE_DEBUG) + DUK_DD(DUK_DDPRINT("duk_heap_process_finalize_list: %ld finalizers called", (long) count)); +#endif +} + +/* + * Run an duk_hobject finalizer. Must never throw an uncaught error + * (but may throw caught errors). + * + * There is no return value. Any return value or error thrown by + * the finalizer is ignored (although errors are debug logged). + * + * Notes: + * + * - The finalizer thread 'top' assertions are there because it is + * critical that strict stack policy is observed (i.e. no cruft + * left on the finalizer stack). + */ + +DUK_LOCAL duk_ret_t duk__finalize_helper(duk_hthread *thr, void *udata) { + DUK_ASSERT(thr != NULL); + DUK_UNREF(udata); + + DUK_DDD(DUK_DDDPRINT("protected finalization helper running")); + + /* [... obj] */ + + /* _Finalizer property is read without checking if the value is + * callable or even exists. This is intentional, and handled + * by throwing an error which is caught by the safe call wrapper. + * + * XXX: Finalizer lookup should traverse the prototype chain (to allow + * inherited finalizers) but should not invoke accessors or proxy object + * behavior. At the moment this lookup will invoke proxy behavior, so + * caller must ensure that this function is not called if the target is + * a Proxy. + */ + duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_FINALIZER); /* -> [... obj finalizer] */ + duk_dup_m2(thr); + duk_push_boolean(thr, DUK_HEAP_HAS_FINALIZER_NORESCUE(thr->heap)); + DUK_DDD(DUK_DDDPRINT("calling finalizer")); + duk_call(thr, 2); /* [ ... obj finalizer obj heapDestruct ] -> [ ... obj retval ] */ + DUK_DDD(DUK_DDDPRINT("finalizer returned successfully")); + return 0; + + /* Note: we rely on duk_safe_call() to fix up the stack for the caller, + * so we don't need to pop stuff here. There is no return value; + * caller determines rescued status based on object refcount. + */ +} + +DUK_INTERNAL void duk_heap_run_finalizer(duk_heap *heap, duk_hobject *obj) { + duk_hthread *thr; + duk_ret_t rc; +#if defined(DUK_USE_ASSERTIONS) + duk_idx_t entry_top; +#endif + + DUK_DD(DUK_DDPRINT("running duk_hobject finalizer for object: %p", (void *) obj)); + + DUK_ASSERT(heap != NULL); + DUK_ASSERT(heap->heap_thread != NULL); + thr = heap->heap_thread; + DUK_ASSERT(obj != NULL); + DUK_ASSERT_VALSTACK_SPACE(heap->heap_thread, 1); + +#if defined(DUK_USE_ASSERTIONS) + entry_top = duk_get_top(thr); +#endif + /* + * Get and call the finalizer. All of this must be wrapped + * in a protected call, because even getting the finalizer + * may trigger an error (getter may throw one, for instance). + */ + + /* ROM objects could inherit a finalizer, but they are never deemed + * unreachable by mark-and-sweep, and their refcount never falls to 0. + */ + DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)); + + /* Duktape 2.1: finalize_list never contains objects with FINALIZED + * set, so no need to check here. + */ + DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) obj)); +#if 0 + if (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) obj)) { + DUK_D(DUK_DPRINT("object already finalized, avoid running finalizer twice: %!O", obj)); + return; + } +#endif + DUK_HEAPHDR_SET_FINALIZED((duk_heaphdr *) obj); /* ensure never re-entered until rescue cycle complete */ + +#if defined(DUK_USE_ES6_PROXY) + if (DUK_HOBJECT_IS_PROXY(obj)) { + /* This may happen if duk_set_finalizer() or Duktape.fin() is + * called for a Proxy object. In such cases the fast finalizer + * flag will be set on the Proxy, not the target, and neither + * will be finalized. + */ + DUK_D(DUK_DPRINT("object is a Proxy, skip finalizer call")); + return; + } +#endif /* DUK_USE_ES6_PROXY */ + + duk_push_hobject(thr, obj); /* this also increases refcount by one */ + rc = duk_safe_call(thr, duk__finalize_helper, NULL /*udata*/, 0 /*nargs*/, 1 /*nrets*/); /* -> [... obj retval/error] */ + DUK_ASSERT_TOP(thr, entry_top + 2); /* duk_safe_call discipline */ + + if (rc != DUK_EXEC_SUCCESS) { + /* Note: we ask for one return value from duk_safe_call to get this + * error debugging here. + */ + DUK_D(DUK_DPRINT("wrapped finalizer call failed for object %p (ignored); error: %!T", + (void *) obj, (duk_tval *) duk_get_tval(thr, -1))); + } + duk_pop_2(thr); /* -> [...] */ + + DUK_ASSERT_TOP(thr, entry_top); +} + +#else /* DUK_USE_FINALIZER_SUPPORT */ + +/* nothing */ + +#endif /* DUK_USE_FINALIZER_SUPPORT */ diff --git a/third_party/duktape/duk_heap_hashstring.c b/third_party/duktape/duk_heap_hashstring.c new file mode 100644 index 00000000..fee7b46c --- /dev/null +++ b/third_party/duktape/duk_heap_hashstring.c @@ -0,0 +1,116 @@ +/* + * String hash computation (interning). + * + * String hashing is performance critical because a string hash is computed + * for all new strings which are candidates to be added to the string table. + * However, strings actually added to the string table go through a codepoint + * length calculation which dominates performance because it goes through + * every byte of the input string (but only for strings added). + * + * The string hash algorithm should be fast, but on the other hand provide + * good enough hashes to ensure both string table and object property table + * hash tables work reasonably well (i.e., there aren't too many collisions + * with real world inputs). Unless the hash is cryptographic, it's always + * possible to craft inputs with maximal hash collisions. + * + * NOTE: The hash algorithms must match tools/dukutil.py:duk_heap_hashstring() + * for ROM string support! + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_STRHASH_DENSE) +/* Constants for duk_hashstring(). */ +#define DUK__STRHASH_SHORTSTRING 4096L +#define DUK__STRHASH_MEDIUMSTRING (256L * 1024L) +#define DUK__STRHASH_BLOCKSIZE 256L + +DUK_INTERNAL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len) { + duk_uint32_t hash; + + /* Use Murmurhash2 directly for short strings, and use "block skipping" + * for long strings: hash an initial part and then sample the rest of + * the string with reasonably sized chunks. An initial offset for the + * sampling is computed based on a hash of the initial part of the string; + * this is done to (usually) avoid the case where all long strings have + * certain offset ranges which are never sampled. + * + * Skip should depend on length and bound the total time to roughly + * logarithmic. With current values: + * + * 1M string => 256 * 241 = 61696 bytes (0.06M) of hashing + * 1G string => 256 * 16321 = 4178176 bytes (3.98M) of hashing + * + * XXX: It would be better to compute the skip offset more "smoothly" + * instead of having a few boundary values. + */ + + /* note: mixing len into seed improves hashing when skipping */ + duk_uint32_t str_seed = heap->hash_seed ^ ((duk_uint32_t) len); + + if (len <= DUK__STRHASH_SHORTSTRING) { + hash = duk_util_hashbytes(str, len, str_seed); + } else { + duk_size_t off; + duk_size_t skip; + + if (len <= DUK__STRHASH_MEDIUMSTRING) { + skip = (duk_size_t) (16 * DUK__STRHASH_BLOCKSIZE + DUK__STRHASH_BLOCKSIZE); + } else { + skip = (duk_size_t) (256 * DUK__STRHASH_BLOCKSIZE + DUK__STRHASH_BLOCKSIZE); + } + + hash = duk_util_hashbytes(str, (duk_size_t) DUK__STRHASH_SHORTSTRING, str_seed); + off = DUK__STRHASH_SHORTSTRING + (skip * (hash % 256)) / 256; + + /* XXX: inefficient loop */ + while (off < len) { + duk_size_t left = len - off; + duk_size_t now = (duk_size_t) (left > DUK__STRHASH_BLOCKSIZE ? DUK__STRHASH_BLOCKSIZE : left); + hash ^= duk_util_hashbytes(str + off, now, str_seed); + off += skip; + } + } + +#if defined(DUK_USE_STRHASH16) + /* Truncate to 16 bits here, so that a computed hash can be compared + * against a hash stored in a 16-bit field. + */ + hash &= 0x0000ffffUL; +#endif + return hash; +} +#else /* DUK_USE_STRHASH_DENSE */ +DUK_INTERNAL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len) { + duk_uint32_t hash; + duk_size_t step; + duk_size_t off; + + /* Slightly modified "Bernstein hash" from: + * + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx + * + * Modifications: string skipping and reverse direction similar to + * Lua 5.1.5, and different hash initializer. + * + * The reverse direction ensures last byte it always included in the + * hash which is a good default as changing parts of the string are + * more often in the suffix than in the prefix. + */ + + hash = heap->hash_seed ^ ((duk_uint32_t) len); /* Bernstein hash init value is normally 5381 */ + step = (len >> DUK_USE_STRHASH_SKIP_SHIFT) + 1; + for (off = len; off >= step; off -= step) { + DUK_ASSERT(off >= 1); /* off >= step, and step >= 1 */ + hash = (hash * 33) + str[off - 1]; + } + +#if defined(DUK_USE_STRHASH16) + /* Truncate to 16 bits here, so that a computed hash can be compared + * against a hash stored in a 16-bit field. + */ + hash &= 0x0000ffffUL; +#endif + return hash; +} +#endif /* DUK_USE_STRHASH_DENSE */ diff --git a/third_party/duktape/duk_heap_markandsweep.c b/third_party/duktape/duk_heap_markandsweep.c new file mode 100644 index 00000000..50b762a2 --- /dev/null +++ b/third_party/duktape/duk_heap_markandsweep.c @@ -0,0 +1,1482 @@ +/* + * Mark-and-sweep garbage collection. + */ + +#include "third_party/duktape/duk_internal.h" + +DUK_LOCAL_DECL void duk__mark_heaphdr(duk_heap *heap, duk_heaphdr *h); +DUK_LOCAL_DECL void duk__mark_heaphdr_nonnull(duk_heap *heap, duk_heaphdr *h); +DUK_LOCAL_DECL void duk__mark_tval(duk_heap *heap, duk_tval *tv); +DUK_LOCAL_DECL void duk__mark_tvals(duk_heap *heap, duk_tval *tv, duk_idx_t count); + +/* + * Marking functions for heap types: mark children recursively. + */ + +DUK_LOCAL void duk__mark_hstring(duk_heap *heap, duk_hstring *h) { + DUK_UNREF(heap); + DUK_UNREF(h); + + DUK_DDD(DUK_DDDPRINT("duk__mark_hstring: %p", (void *) h)); + DUK_ASSERT(h); + DUK_HSTRING_ASSERT_VALID(h); + + /* nothing to process */ +} + +DUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) { + duk_uint_fast32_t i; + + DUK_DDD(DUK_DDDPRINT("duk__mark_hobject: %p", (void *) h)); + + DUK_ASSERT(h); + DUK_HOBJECT_ASSERT_VALID(h); + + /* XXX: use advancing pointers instead of index macros -> faster and smaller? */ + + for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) { + duk_hstring *key = DUK_HOBJECT_E_GET_KEY(heap, h, i); + if (key == NULL) { + continue; + } + duk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) key); + if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, h, i)) { + duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.get); + duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.set); + } else { + duk__mark_tval(heap, &DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->v); + } + } + + for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(h); i++) { + duk__mark_tval(heap, DUK_HOBJECT_A_GET_VALUE_PTR(heap, h, i)); + } + + /* Hash part is a 'weak reference' and does not contribute. */ + + duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_GET_PROTOTYPE(heap, h)); + + /* Fast path for objects which don't have a subclass struct, or have a + * subclass struct but nothing that needs marking in the subclass struct. + */ + if (DUK_HOBJECT_HAS_FASTREFS(h)) { + DUK_ASSERT(DUK_HOBJECT_ALLOWS_FASTREFS(h)); + return; + } + DUK_ASSERT(DUK_HOBJECT_PROHIBITS_FASTREFS(h)); + + /* XXX: reorg, more common first */ + if (DUK_HOBJECT_IS_COMPFUNC(h)) { + duk_hcompfunc *f = (duk_hcompfunc *) h; + duk_tval *tv, *tv_end; + duk_hobject **fn, **fn_end; + + DUK_HCOMPFUNC_ASSERT_VALID(f); + + /* 'data' is reachable through every compiled function which + * contains a reference. + */ + + duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_DATA(heap, f)); + duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_LEXENV(heap, f)); + duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_VARENV(heap, f)); + + if (DUK_HCOMPFUNC_GET_DATA(heap, f) != NULL) { + tv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, f); + tv_end = DUK_HCOMPFUNC_GET_CONSTS_END(heap, f); + while (tv < tv_end) { + duk__mark_tval(heap, tv); + tv++; + } + + fn = DUK_HCOMPFUNC_GET_FUNCS_BASE(heap, f); + fn_end = DUK_HCOMPFUNC_GET_FUNCS_END(heap, f); + while (fn < fn_end) { + duk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) *fn); + fn++; + } + } else { + /* May happen in some out-of-memory corner cases. */ + DUK_D(DUK_DPRINT("duk_hcompfunc 'data' is NULL, skipping marking")); + } + } else if (DUK_HOBJECT_IS_DECENV(h)) { + duk_hdecenv *e = (duk_hdecenv *) h; + DUK_HDECENV_ASSERT_VALID(e); + duk__mark_heaphdr(heap, (duk_heaphdr *) e->thread); + duk__mark_heaphdr(heap, (duk_heaphdr *) e->varmap); + } else if (DUK_HOBJECT_IS_OBJENV(h)) { + duk_hobjenv *e = (duk_hobjenv *) h; + DUK_HOBJENV_ASSERT_VALID(e); + duk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) e->target); +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + } else if (DUK_HOBJECT_IS_BUFOBJ(h)) { + duk_hbufobj *b = (duk_hbufobj *) h; + DUK_HBUFOBJ_ASSERT_VALID(b); + duk__mark_heaphdr(heap, (duk_heaphdr *) b->buf); + duk__mark_heaphdr(heap, (duk_heaphdr *) b->buf_prop); +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + } else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) { + duk_hboundfunc *f = (duk_hboundfunc *) (void *) h; + DUK_HBOUNDFUNC_ASSERT_VALID(f); + duk__mark_tval(heap, &f->target); + duk__mark_tval(heap, &f->this_binding); + duk__mark_tvals(heap, f->args, f->nargs); +#if defined(DUK_USE_ES6_PROXY) + } else if (DUK_HOBJECT_IS_PROXY(h)) { + duk_hproxy *p = (duk_hproxy *) h; + DUK_HPROXY_ASSERT_VALID(p); + duk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) p->target); + duk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) p->handler); +#endif /* DUK_USE_ES6_PROXY */ + } else if (DUK_HOBJECT_IS_THREAD(h)) { + duk_hthread *t = (duk_hthread *) h; + duk_activation *act; + duk_tval *tv; + + DUK_HTHREAD_ASSERT_VALID(t); + + tv = t->valstack; + while (tv < t->valstack_top) { + duk__mark_tval(heap, tv); + tv++; + } + + for (act = t->callstack_curr; act != NULL; act = act->parent) { + duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_ACT_GET_FUNC(act)); + duk__mark_heaphdr(heap, (duk_heaphdr *) act->var_env); + duk__mark_heaphdr(heap, (duk_heaphdr *) act->lex_env); +#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY) + duk__mark_heaphdr(heap, (duk_heaphdr *) act->prev_caller); +#endif +#if 0 /* nothing now */ + for (cat = act->cat; cat != NULL; cat = cat->parent) { + } +#endif + } + + duk__mark_heaphdr(heap, (duk_heaphdr *) t->resumer); + + for (i = 0; i < DUK_NUM_BUILTINS; i++) { + duk__mark_heaphdr(heap, (duk_heaphdr *) t->builtins[i]); + } + } else { + /* We may come here if the object should have a FASTREFS flag + * but it's missing for some reason. Assert for never getting + * here; however, other than performance, this is harmless. + */ + DUK_D(DUK_DPRINT("missing FASTREFS flag for: %!iO", h)); + DUK_ASSERT(0); + } +} + +/* Mark any duk_heaphdr type. Recursion tracking happens only here. */ +DUK_LOCAL void duk__mark_heaphdr(duk_heap *heap, duk_heaphdr *h) { + DUK_DDD(DUK_DDDPRINT("duk__mark_heaphdr %p, type %ld", + (void *) h, + (h != NULL ? (long) DUK_HEAPHDR_GET_TYPE(h) : (long) -1))); + + /* XXX: add non-null variant? */ + if (h == NULL) { + return; + } + + DUK_HEAPHDR_ASSERT_VALID(h); + DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(h) || DUK_HEAPHDR_HAS_REACHABLE(h)); + +#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING) + if (!DUK_HEAPHDR_HAS_READONLY(h)) { + h->h_assert_refcount++; /* Comparison refcount: bump even if already reachable. */ + } +#endif + if (DUK_HEAPHDR_HAS_REACHABLE(h)) { + DUK_DDD(DUK_DDDPRINT("already marked reachable, skip")); + return; + } +#if defined(DUK_USE_ROM_OBJECTS) + /* READONLY objects always have REACHABLE set, so the check above + * will prevent READONLY objects from being marked here. + */ + DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(h)); +#endif + + DUK_HEAPHDR_SET_REACHABLE(h); + + if (heap->ms_recursion_depth >= DUK_USE_MARK_AND_SWEEP_RECLIMIT) { + DUK_D(DUK_DPRINT("mark-and-sweep recursion limit reached, marking as temproot: %p", (void *) h)); + DUK_HEAP_SET_MARKANDSWEEP_RECLIMIT_REACHED(heap); + DUK_HEAPHDR_SET_TEMPROOT(h); + return; + } + + heap->ms_recursion_depth++; + DUK_ASSERT(heap->ms_recursion_depth != 0); /* Wrap. */ + + switch (DUK_HEAPHDR_GET_TYPE(h)) { + case DUK_HTYPE_STRING: + duk__mark_hstring(heap, (duk_hstring *) h); + break; + case DUK_HTYPE_OBJECT: + duk__mark_hobject(heap, (duk_hobject *) h); + break; + case DUK_HTYPE_BUFFER: + /* nothing to mark */ + break; + default: + DUK_D(DUK_DPRINT("attempt to mark heaphdr %p with invalid htype %ld", (void *) h, (long) DUK_HEAPHDR_GET_TYPE(h))); + DUK_UNREACHABLE(); + } + + DUK_ASSERT(heap->ms_recursion_depth > 0); + heap->ms_recursion_depth--; +} + +DUK_LOCAL void duk__mark_tval(duk_heap *heap, duk_tval *tv) { + DUK_DDD(DUK_DDDPRINT("duk__mark_tval %p", (void *) tv)); + if (tv == NULL) { + return; + } + DUK_TVAL_ASSERT_VALID(tv); + if (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) { + duk_heaphdr *h; + h = DUK_TVAL_GET_HEAPHDR(tv); + DUK_ASSERT(h != NULL); + duk__mark_heaphdr_nonnull(heap, h); + } +} + +DUK_LOCAL void duk__mark_tvals(duk_heap *heap, duk_tval *tv, duk_idx_t count) { + DUK_ASSERT(count == 0 || tv != NULL); + + while (count-- > 0) { + DUK_TVAL_ASSERT_VALID(tv); + if (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) { + duk_heaphdr *h; + h = DUK_TVAL_GET_HEAPHDR(tv); + DUK_ASSERT(h != NULL); + duk__mark_heaphdr_nonnull(heap, h); + } + tv++; + } +} + +/* Mark any duk_heaphdr type, caller guarantees a non-NULL pointer. */ +DUK_LOCAL void duk__mark_heaphdr_nonnull(duk_heap *heap, duk_heaphdr *h) { + /* For now, just call the generic handler. Change when call sites + * are changed too. + */ + duk__mark_heaphdr(heap, h); +} + +/* + * Mark the heap. + */ + +DUK_LOCAL void duk__mark_roots_heap(duk_heap *heap) { + duk_small_uint_t i; + + DUK_DD(DUK_DDPRINT("duk__mark_roots_heap: %p", (void *) heap)); + + duk__mark_heaphdr(heap, (duk_heaphdr *) heap->heap_thread); + duk__mark_heaphdr(heap, (duk_heaphdr *) heap->heap_object); + + for (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) { + duk_hstring *h = DUK_HEAP_GET_STRING(heap, i); + duk__mark_heaphdr(heap, (duk_heaphdr *) h); + } + + duk__mark_tval(heap, &heap->lj.value1); + duk__mark_tval(heap, &heap->lj.value2); + +#if defined(DUK_USE_DEBUGGER_SUPPORT) + for (i = 0; i < heap->dbg_breakpoint_count; i++) { + duk__mark_heaphdr(heap, (duk_heaphdr *) heap->dbg_breakpoints[i].filename); + } +#endif +} + +/* + * Mark unreachable, finalizable objects. + * + * Such objects will be moved aside and their finalizers run later. They + * have to be treated as reachability roots for their properties etc to + * remain allocated. This marking is only done for unreachable values which + * would be swept later. + * + * Objects are first marked FINALIZABLE and only then marked as reachability + * roots; otherwise circular references might be handled inconsistently. + */ + +#if defined(DUK_USE_FINALIZER_SUPPORT) +DUK_LOCAL void duk__mark_finalizable(duk_heap *heap) { + duk_heaphdr *hdr; + duk_size_t count_finalizable = 0; + + DUK_DD(DUK_DDPRINT("duk__mark_finalizable: %p", (void *) heap)); + + DUK_ASSERT(heap->heap_thread != NULL); + + hdr = heap->heap_allocated; + while (hdr != NULL) { + /* A finalizer is looked up from the object and up its + * prototype chain (which allows inherited finalizers). + * The finalizer is checked for using a duk_hobject flag + * which is kept in sync with the presence and callability + * of a _Finalizer hidden symbol. + */ + + if (!DUK_HEAPHDR_HAS_REACHABLE(hdr) && + DUK_HEAPHDR_IS_OBJECT(hdr) && + !DUK_HEAPHDR_HAS_FINALIZED(hdr) && + DUK_HOBJECT_HAS_FINALIZER_FAST(heap, (duk_hobject *) hdr)) { + /* heaphdr: + * - is not reachable + * - is an object + * - is not a finalized object waiting for rescue/keep decision + * - has a finalizer + */ + + DUK_DD(DUK_DDPRINT("unreachable heap object will be " + "finalized -> mark as finalizable " + "and treat as a reachability root: %p", + (void *) hdr)); + DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(hdr)); + DUK_HEAPHDR_SET_FINALIZABLE(hdr); + count_finalizable++; + } + + hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr); + } + + if (count_finalizable == 0) { + return; + } + + DUK_DD(DUK_DDPRINT("marked %ld heap objects as finalizable, now mark them reachable", + (long) count_finalizable)); + + hdr = heap->heap_allocated; + while (hdr != NULL) { + if (DUK_HEAPHDR_HAS_FINALIZABLE(hdr)) { + duk__mark_heaphdr_nonnull(heap, hdr); + } + + hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr); + } + + /* Caller will finish the marking process if we hit a recursion limit. */ +} +#endif /* DUK_USE_FINALIZER_SUPPORT */ + +/* + * Mark objects on finalize_list. + */ + +#if defined(DUK_USE_FINALIZER_SUPPORT) +DUK_LOCAL void duk__mark_finalize_list(duk_heap *heap) { + duk_heaphdr *hdr; +#if defined(DUK_USE_DEBUG) + duk_size_t count_finalize_list = 0; +#endif + + DUK_DD(DUK_DDPRINT("duk__mark_finalize_list: %p", (void *) heap)); + + hdr = heap->finalize_list; + while (hdr != NULL) { + duk__mark_heaphdr_nonnull(heap, hdr); + hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr); +#if defined(DUK_USE_DEBUG) + count_finalize_list++; +#endif + } + +#if defined(DUK_USE_DEBUG) + if (count_finalize_list > 0) { + DUK_D(DUK_DPRINT("marked %ld objects on the finalize_list as reachable (previous finalizer run skipped)", + (long) count_finalize_list)); + } +#endif +} +#endif /* DUK_USE_FINALIZER_SUPPORT */ + +/* + * Fallback marking handler if recursion limit is reached. + * + * Iterates 'temproots' until recursion limit is no longer hit. Temproots + * can be in heap_allocated or finalize_list; refzero_list is now always + * empty for mark-and-sweep. A temproot may occur in finalize_list now if + * there are objects on the finalize_list and user code creates a reference + * from an object in heap_allocated to the object in finalize_list (which is + * now allowed), and it happened to coincide with the recursion depth limit. + * + * This is a slow scan, but guarantees that we finish with a bounded C stack. + * + * Note that nodes may have been marked as temproots before this scan begun, + * OR they may have been marked during the scan (as we process nodes + * recursively also during the scan). This is intended behavior. + */ + +#if defined(DUK_USE_DEBUG) +DUK_LOCAL void duk__handle_temproot(duk_heap *heap, duk_heaphdr *hdr, duk_size_t *count) { +#else +DUK_LOCAL void duk__handle_temproot(duk_heap *heap, duk_heaphdr *hdr) { +#endif + DUK_ASSERT(hdr != NULL); + + if (!DUK_HEAPHDR_HAS_TEMPROOT(hdr)) { + DUK_DDD(DUK_DDDPRINT("not a temp root: %p", (void *) hdr)); + return; + } + + DUK_DDD(DUK_DDDPRINT("found a temp root: %p", (void *) hdr)); + DUK_HEAPHDR_CLEAR_TEMPROOT(hdr); + DUK_HEAPHDR_CLEAR_REACHABLE(hdr); /* Done so that duk__mark_heaphdr() works correctly. */ +#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING) + hdr->h_assert_refcount--; /* Same node visited twice. */ +#endif + duk__mark_heaphdr_nonnull(heap, hdr); + +#if defined(DUK_USE_DEBUG) + (*count)++; +#endif +} + +DUK_LOCAL void duk__mark_temproots_by_heap_scan(duk_heap *heap) { + duk_heaphdr *hdr; +#if defined(DUK_USE_DEBUG) + duk_size_t count; +#endif + + DUK_DD(DUK_DDPRINT("duk__mark_temproots_by_heap_scan: %p", (void *) heap)); + + while (DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap)) { + DUK_DD(DUK_DDPRINT("recursion limit reached, doing heap scan to continue from temproots")); + +#if defined(DUK_USE_DEBUG) + count = 0; +#endif + DUK_HEAP_CLEAR_MARKANDSWEEP_RECLIMIT_REACHED(heap); + + hdr = heap->heap_allocated; + while (hdr) { +#if defined(DUK_USE_DEBUG) + duk__handle_temproot(heap, hdr, &count); +#else + duk__handle_temproot(heap, hdr); +#endif + hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr); + } + +#if defined(DUK_USE_FINALIZER_SUPPORT) + hdr = heap->finalize_list; + while (hdr) { +#if defined(DUK_USE_DEBUG) + duk__handle_temproot(heap, hdr, &count); +#else + duk__handle_temproot(heap, hdr); +#endif + hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr); + } +#endif + +#if defined(DUK_USE_DEBUG) + DUK_DD(DUK_DDPRINT("temproot mark heap scan processed %ld temp roots", (long) count)); +#endif + } +} + +/* + * Finalize refcounts for heap elements just about to be freed. + * This must be done for all objects before freeing to avoid any + * stale pointer dereferences. + * + * Note that this must deduce the set of objects to be freed + * identically to duk__sweep_heap(). + */ + +#if defined(DUK_USE_REFERENCE_COUNTING) +DUK_LOCAL void duk__finalize_refcounts(duk_heap *heap) { + duk_heaphdr *hdr; + + DUK_ASSERT(heap->heap_thread != NULL); + + DUK_DD(DUK_DDPRINT("duk__finalize_refcounts: heap=%p", (void *) heap)); + + hdr = heap->heap_allocated; + while (hdr) { + if (!DUK_HEAPHDR_HAS_REACHABLE(hdr)) { + /* + * Unreachable object about to be swept. Finalize target refcounts + * (objects which the unreachable object points to) without doing + * refzero processing. Recursive decrefs are also prevented when + * refzero processing is disabled. + * + * Value cannot be a finalizable object, as they have been made + * temporarily reachable for this round. + */ + + DUK_DDD(DUK_DDDPRINT("unreachable object, refcount finalize before sweeping: %p", (void *) hdr)); + + /* Finalize using heap->heap_thread; DECREF has a + * suppress check for mark-and-sweep which is based + * on heap->ms_running. + */ + duk_heaphdr_refcount_finalize_norz(heap, hdr); + } + + hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr); + } +} +#endif /* DUK_USE_REFERENCE_COUNTING */ + +/* + * Clear (reachable) flags of finalize_list. + * + * We could mostly do in the sweep phase when we move objects from the + * heap into the finalize_list. However, if a finalizer run is skipped + * during a mark-and-sweep, the objects on the finalize_list will be marked + * reachable during the next mark-and-sweep. Since they're already on the + * finalize_list, no-one will be clearing their REACHABLE flag so we do it + * here. (This now overlaps with the sweep handling in a harmless way.) + */ + +#if defined(DUK_USE_FINALIZER_SUPPORT) +DUK_LOCAL void duk__clear_finalize_list_flags(duk_heap *heap) { + duk_heaphdr *hdr; + + DUK_DD(DUK_DDPRINT("duk__clear_finalize_list_flags: %p", (void *) heap)); + + hdr = heap->finalize_list; + while (hdr) { + DUK_HEAPHDR_CLEAR_REACHABLE(hdr); +#if defined(DUK_USE_ASSERTIONS) + DUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZABLE(hdr) || \ + (heap->currently_finalizing == hdr)); +#endif + /* DUK_HEAPHDR_FLAG_FINALIZED may be set. */ + DUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(hdr)); + hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr); + } +} +#endif /* DUK_USE_FINALIZER_SUPPORT */ + +/* + * Sweep stringtable. + */ + +DUK_LOCAL void duk__sweep_stringtable(duk_heap *heap, duk_size_t *out_count_keep) { + duk_hstring *h; + duk_hstring *prev; + duk_uint32_t i; +#if defined(DUK_USE_DEBUG) + duk_size_t count_free = 0; +#endif + duk_size_t count_keep = 0; + + DUK_DD(DUK_DDPRINT("duk__sweep_stringtable: %p", (void *) heap)); + +#if defined(DUK_USE_STRTAB_PTRCOMP) + if (heap->strtable16 == NULL) { +#else + if (heap->strtable == NULL) { +#endif + goto done; + } + + for (i = 0; i < heap->st_size; i++) { +#if defined(DUK_USE_STRTAB_PTRCOMP) + h = DUK_USE_HEAPPTR_DEC16(heap->heap_udata, heap->strtable16[i]); +#else + h = heap->strtable[i]; +#endif + prev = NULL; + while (h != NULL) { + duk_hstring *next; + next = h->hdr.h_next; + + if (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h)) + { + DUK_HEAPHDR_CLEAR_REACHABLE((duk_heaphdr *) h); + count_keep++; + prev = h; + } else { +#if defined(DUK_USE_DEBUG) + count_free++; +#endif + + /* For pinned strings the refcount has been + * bumped. We could unbump it here before + * freeing, but that's actually not necessary + * except for assertions. + */ +#if 0 + if (DUK_HSTRING_HAS_PINNED_LITERAL(h)) { + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) > 0U); + DUK_HSTRING_DECREF_NORZ(heap->heap_thread, h); + DUK_HSTRING_CLEAR_PINNED_LITERAL(h); + } +#endif +#if defined(DUK_USE_REFERENCE_COUNTING) + /* Non-zero refcounts should not happen for unreachable strings, + * because we refcount finalize all unreachable objects which + * should have decreased unreachable string refcounts to zero + * (even for cycles). However, pinned strings have a +1 bump. + */ + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) == + DUK_HSTRING_HAS_PINNED_LITERAL(h) ? 1U : 0U); +#endif + + /* Deal with weak references first. */ + duk_heap_strcache_string_remove(heap, (duk_hstring *) h); + + /* Remove the string from the string table. */ + duk_heap_strtable_unlink_prev(heap, (duk_hstring *) h, (duk_hstring *) prev); + + /* Free inner references (these exist e.g. when external + * strings are enabled) and the struct itself. + */ + duk_free_hstring(heap, (duk_hstring *) h); + + /* Don't update 'prev'; it should be last string kept. */ + } + + h = next; + } + } + + done: +#if defined(DUK_USE_DEBUG) + DUK_D(DUK_DPRINT("mark-and-sweep sweep stringtable: %ld freed, %ld kept", + (long) count_free, (long) count_keep)); +#endif + *out_count_keep = count_keep; +} + +/* + * Sweep heap. + */ + +DUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_small_uint_t flags, duk_size_t *out_count_keep) { + duk_heaphdr *prev; /* last element that was left in the heap */ + duk_heaphdr *curr; + duk_heaphdr *next; +#if defined(DUK_USE_DEBUG) + duk_size_t count_free = 0; + duk_size_t count_finalize = 0; + duk_size_t count_rescue = 0; +#endif + duk_size_t count_keep = 0; + + DUK_DD(DUK_DDPRINT("duk__sweep_heap: %p", (void *) heap)); + + prev = NULL; + curr = heap->heap_allocated; + heap->heap_allocated = NULL; + while (curr) { + /* Strings and ROM objects are never placed on the heap allocated list. */ + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) != DUK_HTYPE_STRING); + DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(curr)); + + next = DUK_HEAPHDR_GET_NEXT(heap, curr); + + if (DUK_HEAPHDR_HAS_REACHABLE(curr)) { + /* + * Reachable object: + * - If FINALIZABLE -> actually unreachable (but marked + * artificially reachable), queue to finalize_list. + * - If !FINALIZABLE but FINALIZED -> rescued after + * finalizer execution. + * - Otherwise just a normal, reachable object. + * + * Objects which are kept are queued to heap_allocated + * tail (we're essentially filtering heap_allocated in + * practice). + */ + +#if defined(DUK_USE_FINALIZER_SUPPORT) + if (DUK_UNLIKELY(DUK_HEAPHDR_HAS_FINALIZABLE(curr))) { + DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr)); + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT); + DUK_DD(DUK_DDPRINT("sweep; reachable, finalizable --> move to finalize_list: %p", (void *) curr)); + +#if defined(DUK_USE_REFERENCE_COUNTING) + DUK_HEAPHDR_PREINC_REFCOUNT(curr); /* Bump refcount so that refzero never occurs when pending a finalizer call. */ +#endif + DUK_HEAP_INSERT_INTO_FINALIZE_LIST(heap, curr); +#if defined(DUK_USE_DEBUG) + count_finalize++; +#endif + } + else +#endif /* DUK_USE_FINALIZER_SUPPORT */ + { + if (DUK_UNLIKELY(DUK_HEAPHDR_HAS_FINALIZED(curr))) { + DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(curr)); + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT); + + if (flags & DUK_MS_FLAG_POSTPONE_RESCUE) { + DUK_DD(DUK_DDPRINT("sweep; reachable, finalized, but postponing rescue decisions --> keep object (with FINALIZED set): %!iO", curr)); + count_keep++; + } else { + DUK_DD(DUK_DDPRINT("sweep; reachable, finalized --> rescued after finalization: %p", (void *) curr)); +#if defined(DUK_USE_FINALIZER_SUPPORT) + DUK_HEAPHDR_CLEAR_FINALIZED(curr); +#endif +#if defined(DUK_USE_DEBUG) + count_rescue++; +#endif + } + } else { + DUK_DD(DUK_DDPRINT("sweep; reachable --> keep: %!iO", curr)); + count_keep++; + } + + if (prev != NULL) { + DUK_ASSERT(heap->heap_allocated != NULL); + DUK_HEAPHDR_SET_NEXT(heap, prev, curr); + } else { + DUK_ASSERT(heap->heap_allocated == NULL); + heap->heap_allocated = curr; + } +#if defined(DUK_USE_DOUBLE_LINKED_HEAP) + DUK_HEAPHDR_SET_PREV(heap, curr, prev); +#endif + DUK_HEAPHDR_ASSERT_LINKS(heap, prev); + DUK_HEAPHDR_ASSERT_LINKS(heap, curr); + prev = curr; + } + + /* + * Shrink check for value stacks here. We're inside + * ms_prevent_count protection which prevents recursive + * mark-and-sweep and refzero finalizers, so there are + * no side effects that would affect the heap lists. + */ + if (DUK_HEAPHDR_IS_OBJECT(curr) && DUK_HOBJECT_IS_THREAD((duk_hobject *) curr)) { + duk_hthread *thr_curr = (duk_hthread *) curr; + DUK_DD(DUK_DDPRINT("value stack shrink check for thread: %!O", curr)); + duk_valstack_shrink_check_nothrow(thr_curr, flags & DUK_MS_FLAG_EMERGENCY /*snug*/); + } + + DUK_HEAPHDR_CLEAR_REACHABLE(curr); + /* Keep FINALIZED if set, used if rescue decisions are postponed. */ + /* Keep FINALIZABLE for objects on finalize_list. */ + DUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(curr)); + } else { + /* + * Unreachable object: + * - If FINALIZED, object was finalized but not + * rescued. This doesn't affect freeing. + * - Otherwise normal unreachable object. + * + * There's no guard preventing a FINALIZED object + * from being freed while finalizers execute: the + * artificial finalize_list reachability roots can't + * cause an incorrect free decision (but can cause + * an incorrect rescue decision). + */ + +#if defined(DUK_USE_REFERENCE_COUNTING) + /* Non-zero refcounts should not happen because we refcount + * finalize all unreachable objects which should cancel out + * refcounts (even for cycles). + */ + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) == 0); +#endif + DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(curr)); + +#if defined(DUK_USE_DEBUG) + if (DUK_HEAPHDR_HAS_FINALIZED(curr)) { + DUK_DD(DUK_DDPRINT("sweep; unreachable, finalized --> finalized object not rescued: %p", (void *) curr)); + } else { + DUK_DD(DUK_DDPRINT("sweep; not reachable --> free: %p", (void *) curr)); + } + +#endif + + /* Note: object cannot be a finalizable unreachable object, as + * they have been marked temporarily reachable for this round, + * and are handled above. + */ + +#if defined(DUK_USE_DEBUG) + count_free++; +#endif + + /* Weak refs should be handled here, but no weak refs for + * any non-string objects exist right now. + */ + + /* Free object and all auxiliary (non-heap) allocs. */ + duk_heap_free_heaphdr_raw(heap, curr); + } + + curr = next; + } + + if (prev != NULL) { + DUK_HEAPHDR_SET_NEXT(heap, prev, NULL); + } + DUK_HEAPHDR_ASSERT_LINKS(heap, prev); + +#if defined(DUK_USE_DEBUG) + DUK_D(DUK_DPRINT("mark-and-sweep sweep objects (non-string): %ld freed, %ld kept, %ld rescued, %ld queued for finalization", + (long) count_free, (long) count_keep, (long) count_rescue, (long) count_finalize)); +#endif + *out_count_keep = count_keep; +} + +/* + * Litcache helpers. + */ + +#if defined(DUK_USE_LITCACHE_SIZE) +DUK_LOCAL void duk__wipe_litcache(duk_heap *heap) { + duk_uint_t i; + duk_litcache_entry *e; + + e = heap->litcache; + for (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) { + e->addr = NULL; + /* e->h does not need to be invalidated: when e->addr is + * NULL, e->h is considered garbage. + */ + e++; + } +} +#endif /* DUK_USE_LITCACHE_SIZE */ + +/* + * Object compaction. + * + * Compaction is assumed to never throw an error. + */ + +DUK_LOCAL int duk__protected_compact_object(duk_hthread *thr, void *udata) { + duk_hobject *obj; + /* XXX: for threads, compact stacks? */ + + DUK_UNREF(udata); + obj = duk_known_hobject(thr, -1); + duk_hobject_compact_props(thr, obj); + return 0; +} + +#if defined(DUK_USE_DEBUG) +DUK_LOCAL void duk__compact_object_list(duk_heap *heap, duk_hthread *thr, duk_heaphdr *start, duk_size_t *p_count_check, duk_size_t *p_count_compact, duk_size_t *p_count_bytes_saved) { +#else +DUK_LOCAL void duk__compact_object_list(duk_heap *heap, duk_hthread *thr, duk_heaphdr *start) { +#endif + duk_heaphdr *curr; +#if defined(DUK_USE_DEBUG) + duk_size_t old_size, new_size; +#endif + duk_hobject *obj; + + DUK_UNREF(heap); + + curr = start; + while (curr) { + DUK_DDD(DUK_DDDPRINT("mark-and-sweep compact: %p", (void *) curr)); + + if (DUK_HEAPHDR_GET_TYPE(curr) != DUK_HTYPE_OBJECT) { + goto next; + } + obj = (duk_hobject *) curr; + +#if defined(DUK_USE_DEBUG) + old_size = DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj), + DUK_HOBJECT_GET_ASIZE(obj), + DUK_HOBJECT_GET_HSIZE(obj)); +#endif + + DUK_DD(DUK_DDPRINT("compact object: %p", (void *) obj)); + duk_push_hobject(thr, obj); + /* XXX: disable error handlers for duration of compaction? */ + duk_safe_call(thr, duk__protected_compact_object, NULL, 1, 0); + +#if defined(DUK_USE_DEBUG) + new_size = DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj), + DUK_HOBJECT_GET_ASIZE(obj), + DUK_HOBJECT_GET_HSIZE(obj)); +#endif + +#if defined(DUK_USE_DEBUG) + (*p_count_compact)++; + (*p_count_bytes_saved) += (duk_size_t) (old_size - new_size); +#endif + + next: + curr = DUK_HEAPHDR_GET_NEXT(heap, curr); +#if defined(DUK_USE_DEBUG) + (*p_count_check)++; +#endif + } +} + +DUK_LOCAL void duk__compact_objects(duk_heap *heap) { + /* XXX: which lists should participate? to be finalized? */ +#if defined(DUK_USE_DEBUG) + duk_size_t count_check = 0; + duk_size_t count_compact = 0; + duk_size_t count_bytes_saved = 0; +#endif + + DUK_DD(DUK_DDPRINT("duk__compact_objects: %p", (void *) heap)); + + DUK_ASSERT(heap->heap_thread != NULL); + +#if defined(DUK_USE_DEBUG) + duk__compact_object_list(heap, heap->heap_thread, heap->heap_allocated, &count_check, &count_compact, &count_bytes_saved); +#if defined(DUK_USE_FINALIZER_SUPPORT) + duk__compact_object_list(heap, heap->heap_thread, heap->finalize_list, &count_check, &count_compact, &count_bytes_saved); +#endif +#else + duk__compact_object_list(heap, heap->heap_thread, heap->heap_allocated); +#if defined(DUK_USE_FINALIZER_SUPPORT) + duk__compact_object_list(heap, heap->heap_thread, heap->finalize_list); +#endif +#endif +#if defined(DUK_USE_REFERENCE_COUNTING) + DUK_ASSERT(heap->refzero_list == NULL); /* Always handled to completion inline in DECREF. */ +#endif + +#if defined(DUK_USE_DEBUG) + DUK_D(DUK_DPRINT("mark-and-sweep compact objects: %ld checked, %ld compaction attempts, %ld bytes saved by compaction", + (long) count_check, (long) count_compact, (long) count_bytes_saved)); +#endif +} + +/* + * Assertion helpers. + */ + +#if defined(DUK_USE_ASSERTIONS) +typedef void (*duk__gc_heaphdr_assert)(duk_heap *heap, duk_heaphdr *h); +typedef void (*duk__gc_hstring_assert)(duk_heap *heap, duk_hstring *h); + +DUK_LOCAL void duk__assert_walk_list(duk_heap *heap, duk_heaphdr *start, duk__gc_heaphdr_assert func) { + duk_heaphdr *curr; + for (curr = start; curr != NULL; curr = DUK_HEAPHDR_GET_NEXT(heap, curr)) { + func(heap, curr); + } +} + +DUK_LOCAL void duk__assert_walk_strtable(duk_heap *heap, duk__gc_hstring_assert func) { + duk_uint32_t i; + + for (i = 0; i < heap->st_size; i++) { + duk_hstring *h; + +#if defined(DUK_USE_STRTAB_PTRCOMP) + h = DUK_USE_HEAPPTR_DEC16(heap->heap_udata, heap->strtable16[i]); +#else + h = heap->strtable[i]; +#endif + while (h != NULL) { + func(heap, h); + h = h->hdr.h_next; + } + } +} + +DUK_LOCAL void duk__assert_heaphdr_flags_cb(duk_heap *heap, duk_heaphdr *h) { + DUK_UNREF(heap); + DUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(h)); + DUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(h)); + DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(h)); + /* may have FINALIZED */ +} +DUK_LOCAL void duk__assert_heaphdr_flags(duk_heap *heap) { + duk__assert_walk_list(heap, heap->heap_allocated, duk__assert_heaphdr_flags_cb); +#if defined(DUK_USE_REFERENCE_COUNTING) + DUK_ASSERT(heap->refzero_list == NULL); /* Always handled to completion inline in DECREF. */ +#endif + /* XXX: Assertions for finalize_list? */ +} + +DUK_LOCAL void duk__assert_validity_cb1(duk_heap *heap, duk_heaphdr *h) { + DUK_UNREF(heap); + DUK_ASSERT(DUK_HEAPHDR_IS_OBJECT(h) || DUK_HEAPHDR_IS_BUFFER(h)); + duk_heaphdr_assert_valid_subclassed(h); +} +DUK_LOCAL void duk__assert_validity_cb2(duk_heap *heap, duk_hstring *h) { + DUK_UNREF(heap); + DUK_ASSERT(DUK_HEAPHDR_IS_STRING((duk_heaphdr *) h)); + duk_heaphdr_assert_valid_subclassed((duk_heaphdr *) h); +} +DUK_LOCAL void duk__assert_validity(duk_heap *heap) { + duk__assert_walk_list(heap, heap->heap_allocated, duk__assert_validity_cb1); +#if defined(DUK_USE_FINALIZER_SUPPORT) + duk__assert_walk_list(heap, heap->finalize_list, duk__assert_validity_cb1); +#endif +#if defined(DUK_USE_REFERENCE_COUNTING) + duk__assert_walk_list(heap, heap->refzero_list, duk__assert_validity_cb1); +#endif + duk__assert_walk_strtable(heap, duk__assert_validity_cb2); +} + +#if defined(DUK_USE_REFERENCE_COUNTING) +DUK_LOCAL void duk__assert_valid_refcounts_cb(duk_heap *heap, duk_heaphdr *h) { + /* Cannot really assert much w.r.t. refcounts now. */ + + DUK_UNREF(heap); + if (DUK_HEAPHDR_GET_REFCOUNT(h) == 0 && + DUK_HEAPHDR_HAS_FINALIZED(h)) { + /* An object may be in heap_allocated list with a zero + * refcount if it has just been finalized and is waiting + * to be collected by the next cycle. + * (This doesn't currently happen however.) + */ + } else if (DUK_HEAPHDR_GET_REFCOUNT(h) == 0) { + /* An object may be in heap_allocated list with a zero + * refcount also if it is a temporary object created + * during debugger paused state. It will get collected + * by mark-and-sweep based on its reachability status + * (presumably not reachable because refcount is 0). + */ + } + DUK_ASSERT_DISABLE(DUK_HEAPHDR_GET_REFCOUNT(h) >= 0); /* Unsigned. */ +} +DUK_LOCAL void duk__assert_valid_refcounts(duk_heap *heap) { + duk__assert_walk_list(heap, heap->heap_allocated, duk__assert_valid_refcounts_cb); +} + +DUK_LOCAL void duk__clear_assert_refcounts_cb1(duk_heap *heap, duk_heaphdr *h) { + DUK_UNREF(heap); + h->h_assert_refcount = 0; +} +DUK_LOCAL void duk__clear_assert_refcounts_cb2(duk_heap *heap, duk_hstring *h) { + DUK_UNREF(heap); + ((duk_heaphdr *) h)->h_assert_refcount = 0; +} +DUK_LOCAL void duk__clear_assert_refcounts(duk_heap *heap) { + duk__assert_walk_list(heap, heap->heap_allocated, duk__clear_assert_refcounts_cb1); +#if defined(DUK_USE_FINALIZER_SUPPORT) + duk__assert_walk_list(heap, heap->finalize_list, duk__clear_assert_refcounts_cb1); +#endif +#if defined(DUK_USE_REFERENCE_COUNTING) + duk__assert_walk_list(heap, heap->refzero_list, duk__clear_assert_refcounts_cb1); +#endif + duk__assert_walk_strtable(heap, duk__clear_assert_refcounts_cb2); +} + +DUK_LOCAL void duk__check_refcount_heaphdr(duk_heaphdr *hdr) { + duk_bool_t count_ok; + duk_size_t expect_refc; + + /* The refcount check only makes sense for reachable objects on + * heap_allocated or string table, after the sweep phase. Prior to + * sweep phase refcounts will include references that are not visible + * via reachability roots. + * + * Because we're called after the sweep phase, all heap objects on + * heap_allocated are reachable. REACHABLE flags have already been + * cleared so we can't check them. + */ + + /* ROM objects have intentionally incorrect refcount (1), but we won't + * check them. + */ + DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(hdr)); + + expect_refc = hdr->h_assert_refcount; + if (DUK_HEAPHDR_IS_STRING(hdr) && DUK_HSTRING_HAS_PINNED_LITERAL((duk_hstring *) hdr)) { + expect_refc++; + } + count_ok = ((duk_size_t) DUK_HEAPHDR_GET_REFCOUNT(hdr) == expect_refc); + if (!count_ok) { + DUK_D(DUK_DPRINT("refcount mismatch for: %p: header=%ld counted=%ld --> %!iO", + (void *) hdr, (long) DUK_HEAPHDR_GET_REFCOUNT(hdr), + (long) hdr->h_assert_refcount, hdr)); + DUK_ASSERT(0); + } +} + +DUK_LOCAL void duk__check_assert_refcounts_cb1(duk_heap *heap, duk_heaphdr *h) { + DUK_UNREF(heap); + duk__check_refcount_heaphdr(h); +} +DUK_LOCAL void duk__check_assert_refcounts_cb2(duk_heap *heap, duk_hstring *h) { + DUK_UNREF(heap); + duk__check_refcount_heaphdr((duk_heaphdr *) h); +} +DUK_LOCAL void duk__check_assert_refcounts(duk_heap *heap) { + duk__assert_walk_list(heap, heap->heap_allocated, duk__check_assert_refcounts_cb1); +#if defined(DUK_USE_FINALIZER_SUPPORT) + duk__assert_walk_list(heap, heap->finalize_list, duk__check_assert_refcounts_cb1); +#endif + /* XXX: Assert anything for refzero_list? */ + duk__assert_walk_strtable(heap, duk__check_assert_refcounts_cb2); +} +#endif /* DUK_USE_REFERENCE_COUNTING */ + +#if defined(DUK_USE_LITCACHE_SIZE) +DUK_LOCAL void duk__assert_litcache_nulls(duk_heap *heap) { + duk_uint_t i; + duk_litcache_entry *e; + + e = heap->litcache; + for (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) { + /* Entry addresses were NULLed before mark-and-sweep, check + * that they're still NULL afterwards to ensure no pointers + * were recorded through any side effects. + */ + DUK_ASSERT(e->addr == NULL); + } +} +#endif /* DUK_USE_LITCACHE_SIZE */ +#endif /* DUK_USE_ASSERTIONS */ + +/* + * Stats dump. + */ + +#if defined(DUK_USE_DEBUG) +DUK_LOCAL void duk__dump_stats(duk_heap *heap) { + DUK_D(DUK_DPRINT("stats executor: opcodes=%ld, interrupt=%ld, throw=%ld", + (long) heap->stats_exec_opcodes, (long) heap->stats_exec_interrupt, + (long) heap->stats_exec_throw)); + DUK_D(DUK_DPRINT("stats call: all=%ld, tailcall=%ld, ecmatoecma=%ld", + (long) heap->stats_call_all, (long) heap->stats_call_tailcall, + (long) heap->stats_call_ecmatoecma)); + DUK_D(DUK_DPRINT("stats safecall: all=%ld, nothrow=%ld, throw=%ld", + (long) heap->stats_safecall_all, (long) heap->stats_safecall_nothrow, + (long) heap->stats_safecall_throw)); + DUK_D(DUK_DPRINT("stats mark-and-sweep: try_count=%ld, skip_count=%ld, emergency_count=%ld", + (long) heap->stats_ms_try_count, (long) heap->stats_ms_skip_count, + (long) heap->stats_ms_emergency_count)); + DUK_D(DUK_DPRINT("stats stringtable: intern_hit=%ld, intern_miss=%ld, " + "resize_check=%ld, resize_grow=%ld, resize_shrink=%ld, " + "litcache_hit=%ld, litcache_miss=%ld, litcache_pin=%ld", + (long) heap->stats_strtab_intern_hit, (long) heap->stats_strtab_intern_miss, + (long) heap->stats_strtab_resize_check, (long) heap->stats_strtab_resize_grow, + (long) heap->stats_strtab_resize_shrink, (long) heap->stats_strtab_litcache_hit, + (long) heap->stats_strtab_litcache_miss, (long) heap->stats_strtab_litcache_pin)); + DUK_D(DUK_DPRINT("stats object: realloc_props=%ld, abandon_array=%ld", + (long) heap->stats_object_realloc_props, (long) heap->stats_object_abandon_array)); + DUK_D(DUK_DPRINT("stats getownpropdesc: count=%ld, hit=%ld, miss=%ld", + (long) heap->stats_getownpropdesc_count, (long) heap->stats_getownpropdesc_hit, + (long) heap->stats_getownpropdesc_miss)); + DUK_D(DUK_DPRINT("stats getpropdesc: count=%ld, hit=%ld, miss=%ld", + (long) heap->stats_getpropdesc_count, (long) heap->stats_getpropdesc_hit, + (long) heap->stats_getpropdesc_miss)); + DUK_D(DUK_DPRINT("stats getprop: all=%ld, arrayidx=%ld, bufobjidx=%ld, " + "bufferidx=%ld, bufferlen=%ld, stringidx=%ld, stringlen=%ld, " + "proxy=%ld, arguments=%ld", + (long) heap->stats_getprop_all, (long) heap->stats_getprop_arrayidx, + (long) heap->stats_getprop_bufobjidx, (long) heap->stats_getprop_bufferidx, + (long) heap->stats_getprop_bufferlen, (long) heap->stats_getprop_stringidx, + (long) heap->stats_getprop_stringlen, (long) heap->stats_getprop_proxy, + (long) heap->stats_getprop_arguments)); + DUK_D(DUK_DPRINT("stats putprop: all=%ld, arrayidx=%ld, bufobjidx=%ld, " + "bufferidx=%ld, proxy=%ld", + (long) heap->stats_putprop_all, (long) heap->stats_putprop_arrayidx, + (long) heap->stats_putprop_bufobjidx, (long) heap->stats_putprop_bufferidx, + (long) heap->stats_putprop_proxy)); + DUK_D(DUK_DPRINT("stats getvar: all=%ld", + (long) heap->stats_getvar_all)); + DUK_D(DUK_DPRINT("stats putvar: all=%ld", + (long) heap->stats_putvar_all)); + DUK_D(DUK_DPRINT("stats envrec: delayedcreate=%ld, create=%ld, newenv=%ld, oldenv=%ld, pushclosure=%ld", + (long) heap->stats_envrec_delayedcreate, + (long) heap->stats_envrec_create, + (long) heap->stats_envrec_newenv, + (long) heap->stats_envrec_oldenv, + (long) heap->stats_envrec_pushclosure)); +} +#endif /* DUK_USE_DEBUG */ + +/* + * Main mark-and-sweep function. + * + * 'flags' represents the features requested by the caller. The current + * heap->ms_base_flags is ORed automatically into the flags; the base flags + * mask typically prevents certain mark-and-sweep operation to avoid trouble. + */ + +DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags) { + duk_size_t count_keep_obj; + duk_size_t count_keep_str; +#if defined(DUK_USE_VOLUNTARY_GC) + duk_size_t tmp; +#endif + + DUK_STATS_INC(heap, stats_ms_try_count); +#if defined(DUK_USE_DEBUG) + if (flags & DUK_MS_FLAG_EMERGENCY) { + DUK_STATS_INC(heap, stats_ms_emergency_count); + } +#endif + + /* If debugger is paused, garbage collection is disabled by default. + * This is achieved by bumping ms_prevent_count when becoming paused. + */ + DUK_ASSERT(!DUK_HEAP_HAS_DEBUGGER_PAUSED(heap) || heap->ms_prevent_count > 0); + + /* Prevention/recursion check as soon as possible because we may + * be called a number of times when voluntary mark-and-sweep is + * pending. + */ + if (heap->ms_prevent_count != 0) { + DUK_DD(DUK_DDPRINT("reject recursive mark-and-sweep")); + DUK_STATS_INC(heap, stats_ms_skip_count); + return; + } + DUK_ASSERT(heap->ms_running == 0); /* ms_prevent_count is bumped when ms_running is set */ + + /* Heap_thread is used during mark-and-sweep for refcount finalization + * (it's also used for finalizer execution once mark-and-sweep is + * complete). Heap allocation code ensures heap_thread is set and + * properly initialized before setting ms_prevent_count to 0. + */ + DUK_ASSERT(heap->heap_thread != NULL); + DUK_ASSERT(heap->heap_thread->valstack != NULL); + + DUK_D(DUK_DPRINT("garbage collect (mark-and-sweep) starting, requested flags: 0x%08lx, effective flags: 0x%08lx", + (unsigned long) flags, (unsigned long) (flags | heap->ms_base_flags))); + + flags |= heap->ms_base_flags; +#if defined(DUK_USE_FINALIZER_SUPPORT) + if (heap->finalize_list != NULL) { + flags |= DUK_MS_FLAG_POSTPONE_RESCUE; + } +#endif + + /* + * Assertions before + */ + +#if defined(DUK_USE_ASSERTIONS) + DUK_ASSERT(heap->ms_prevent_count == 0); + DUK_ASSERT(heap->ms_running == 0); + DUK_ASSERT(!DUK_HEAP_HAS_DEBUGGER_PAUSED(heap)); + DUK_ASSERT(!DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap)); + DUK_ASSERT(heap->ms_recursion_depth == 0); + duk__assert_heaphdr_flags(heap); + duk__assert_validity(heap); +#if defined(DUK_USE_REFERENCE_COUNTING) + /* Note: heap->refzero_free_running may be true; a refcount + * finalizer may trigger a mark-and-sweep. + */ + duk__assert_valid_refcounts(heap); +#endif /* DUK_USE_REFERENCE_COUNTING */ +#endif /* DUK_USE_ASSERTIONS */ + + /* + * Begin + */ + + DUK_ASSERT(heap->ms_prevent_count == 0); + DUK_ASSERT(heap->ms_running == 0); + heap->ms_prevent_count = 1; + heap->ms_running = 1; + + /* + * Free activation/catcher freelists on every mark-and-sweep for now. + * This is an initial rough draft; ideally we'd keep count of the + * freelist size and free only excess entries. + */ + + DUK_D(DUK_DPRINT("freeing temporary freelists")); + duk_heap_free_freelists(heap); + + /* + * Mark roots, hoping that recursion limit is not normally hit. + * If recursion limit is hit, run additional reachability rounds + * starting from "temproots" until marking is complete. + * + * Marking happens in two phases: first we mark actual reachability + * roots (and run "temproots" to complete the process). Then we + * check which objects are unreachable and are finalizable; such + * objects are marked as FINALIZABLE and marked as reachability + * (and "temproots" is run again to complete the process). + * + * The heap finalize_list must also be marked as a reachability root. + * There may be objects on the list from a previous round if the + * previous run had finalizer skip flag. + */ + +#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING) + duk__clear_assert_refcounts(heap); +#endif +#if defined(DUK_USE_LITCACHE_SIZE) + duk__wipe_litcache(heap); +#endif + duk__mark_roots_heap(heap); /* Mark main reachability roots. */ +#if defined(DUK_USE_REFERENCE_COUNTING) + DUK_ASSERT(heap->refzero_list == NULL); /* Always handled to completion inline in DECREF. */ +#endif + duk__mark_temproots_by_heap_scan(heap); /* Temproots. */ + +#if defined(DUK_USE_FINALIZER_SUPPORT) + duk__mark_finalizable(heap); /* Mark finalizable as reachability roots. */ + duk__mark_finalize_list(heap); /* Mark finalizer work list as reachability roots. */ +#endif + duk__mark_temproots_by_heap_scan(heap); /* Temproots. */ + + /* + * Sweep garbage and remove marking flags, and move objects with + * finalizers to the finalizer work list. + * + * Objects to be swept need to get their refcounts finalized before + * they are swept. In other words, their target object refcounts + * need to be decreased. This has to be done before freeing any + * objects to avoid decref'ing dangling pointers (which may happen + * even without bugs, e.g. with reference loops) + * + * Because strings don't point to other heap objects, similar + * finalization is not necessary for strings. + */ + + /* XXX: more emergency behavior, e.g. find smaller hash sizes etc */ + +#if defined(DUK_USE_REFERENCE_COUNTING) + duk__finalize_refcounts(heap); +#endif + duk__sweep_heap(heap, flags, &count_keep_obj); + duk__sweep_stringtable(heap, &count_keep_str); +#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING) + duk__check_assert_refcounts(heap); +#endif +#if defined(DUK_USE_REFERENCE_COUNTING) + DUK_ASSERT(heap->refzero_list == NULL); /* Always handled to completion inline in DECREF. */ +#endif +#if defined(DUK_USE_FINALIZER_SUPPORT) + duk__clear_finalize_list_flags(heap); +#endif + + /* + * Object compaction (emergency only). + * + * Object compaction is a separate step after sweeping, as there is + * more free memory for it to work with. Also, currently compaction + * may insert new objects into the heap allocated list and the string + * table which we don't want to do during a sweep (the reachability + * flags of such objects would be incorrect). The objects inserted + * are currently: + * + * - a temporary duk_hbuffer for a new properties allocation + * - if array part is abandoned, string keys are interned + * + * The object insertions go to the front of the list, so they do not + * cause an infinite loop (they are not compacted). + * + * At present compaction is not allowed when mark-and-sweep runs + * during error handling because it involves a duk_safe_call() + * interfering with error state. + */ + + if ((flags & DUK_MS_FLAG_EMERGENCY) && + !(flags & DUK_MS_FLAG_NO_OBJECT_COMPACTION)) { + if (heap->lj.type != DUK_LJ_TYPE_UNKNOWN) { + DUK_D(DUK_DPRINT("lj.type (%ld) not DUK_LJ_TYPE_UNKNOWN, skip object compaction", (long) heap->lj.type)); + } else { + DUK_D(DUK_DPRINT("object compaction")); + duk__compact_objects(heap); + } + } + + /* + * String table resize check. + * + * This is mainly useful in emergency GC: if the string table load + * factor is really low for some reason, we can shrink the string + * table to a smaller size and free some memory in the process. + * Only execute in emergency GC. String table has internal flags + * to protect against recursive resizing if this mark-and-sweep pass + * was triggered by a string table resize. + */ + + if (flags & DUK_MS_FLAG_EMERGENCY) { + DUK_D(DUK_DPRINT("stringtable resize check in emergency gc")); + duk_heap_strtable_force_resize(heap); + } + + /* + * Finish + */ + + DUK_ASSERT(heap->ms_prevent_count == 1); + DUK_ASSERT(heap->ms_running == 1); + heap->ms_prevent_count = 0; + heap->ms_running = 0; + + /* + * Assertions after + */ + +#if defined(DUK_USE_ASSERTIONS) + DUK_ASSERT(heap->ms_prevent_count == 0); + DUK_ASSERT(!DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap)); + DUK_ASSERT(heap->ms_recursion_depth == 0); + duk__assert_heaphdr_flags(heap); + duk__assert_validity(heap); +#if defined(DUK_USE_REFERENCE_COUNTING) + /* Note: heap->refzero_free_running may be true; a refcount + * finalizer may trigger a mark-and-sweep. + */ + duk__assert_valid_refcounts(heap); +#endif /* DUK_USE_REFERENCE_COUNTING */ +#if defined(DUK_USE_LITCACHE_SIZE) + duk__assert_litcache_nulls(heap); +#endif /* DUK_USE_LITCACHE_SIZE */ +#endif /* DUK_USE_ASSERTIONS */ + + /* + * Reset trigger counter + */ + +#if defined(DUK_USE_VOLUNTARY_GC) + tmp = (count_keep_obj + count_keep_str) / 256; + heap->ms_trigger_counter = (duk_int_t) ( + (tmp * DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT) + + DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD); + DUK_D(DUK_DPRINT("garbage collect (mark-and-sweep) finished: %ld objects kept, %ld strings kept, trigger reset to %ld", + (long) count_keep_obj, (long) count_keep_str, (long) heap->ms_trigger_counter)); +#else + DUK_D(DUK_DPRINT("garbage collect (mark-and-sweep) finished: %ld objects kept, %ld strings kept, no voluntary trigger", + (long) count_keep_obj, (long) count_keep_str)); +#endif + + /* + * Stats dump + */ + +#if defined(DUK_USE_DEBUG) + duk__dump_stats(heap); +#endif + + /* + * Finalize objects in the finalization work list. Finalized + * objects are queued back to heap_allocated with FINALIZED set. + * + * Since finalizers may cause arbitrary side effects, they are + * prevented e.g. during string table and object property allocation + * resizing using heap->pf_prevent_count. In this case the objects + * remain in the finalization work list after mark-and-sweep exits + * and they may be finalized on the next pass or any DECREF checking + * for finalize_list. + * + * As of Duktape 2.1 finalization happens outside mark-and-sweep + * protection. Mark-and-sweep is allowed while the finalize_list + * is being processed, but no rescue decisions are done while the + * process is on-going. This avoids incorrect rescue decisions + * if an object is considered reachable (and thus rescued) because + * of a reference via finalize_list (which is considered a reachability + * root). When finalize_list is being processed, reachable objects + * with FINALIZED set will just keep their FINALIZED flag for later + * mark-and-sweep processing. + * + * This could also be handled (a bit better) by having a more refined + * notion of reachability for rescue/free decisions. + * + * XXX: avoid finalizer execution when doing emergency GC? + */ + +#if defined(DUK_USE_FINALIZER_SUPPORT) + /* Attempt to process finalize_list, pf_prevent_count check + * is inside the target. + */ + duk_heap_process_finalize_list(heap); +#endif /* DUK_USE_FINALIZER_SUPPORT */ +} diff --git a/third_party/duktape/duk_heap_memory.c b/third_party/duktape/duk_heap_memory.c new file mode 100644 index 00000000..01f9d9ed --- /dev/null +++ b/third_party/duktape/duk_heap_memory.c @@ -0,0 +1,412 @@ +/* + * Memory allocation handling. + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Allocate memory with garbage collection. + */ + +/* Slow path: voluntary GC triggered, first alloc attempt failed, or zero size. */ +DUK_LOCAL DUK_NOINLINE_PERF DUK_COLD void *duk__heap_mem_alloc_slowpath(duk_heap *heap, duk_size_t size) { + void *res; + duk_small_int_t i; + + DUK_ASSERT(heap != NULL); + DUK_ASSERT(heap->alloc_func != NULL); + DUK_ASSERT_DISABLE(size >= 0); + + if (size == 0) { + DUK_D(DUK_DPRINT("zero size alloc in slow path, return NULL")); + return NULL; + } + + DUK_D(DUK_DPRINT("first alloc attempt failed or voluntary GC limit reached, attempt to gc and retry")); + +#if 0 + /* + * If GC is already running there is no point in attempting a GC + * because it will be skipped. This could be checked for explicitly, + * but it isn't actually needed: the loop below will eventually + * fail resulting in a NULL. + */ + + if (heap->ms_prevent_count != 0) { + DUK_D(DUK_DPRINT("duk_heap_mem_alloc() failed, gc in progress (gc skipped), alloc size %ld", (long) size)); + return NULL; + } +#endif + + /* + * Retry with several GC attempts. Initial attempts are made without + * emergency mode; later attempts use emergency mode which minimizes + * memory allocations forcibly. + */ + + for (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) { + duk_small_uint_t flags; + + flags = 0; + if (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) { + flags |= DUK_MS_FLAG_EMERGENCY; + } + + duk_heap_mark_and_sweep(heap, flags); + + DUK_ASSERT(size > 0); + res = heap->alloc_func(heap->heap_udata, size); + if (res != NULL) { + DUK_D(DUK_DPRINT("duk_heap_mem_alloc() succeeded after gc (pass %ld), alloc size %ld", + (long) (i + 1), (long) size)); + return res; + } + } + + DUK_D(DUK_DPRINT("duk_heap_mem_alloc() failed even after gc, alloc size %ld", (long) size)); + return NULL; +} + +DUK_INTERNAL DUK_INLINE_PERF DUK_HOT void *duk_heap_mem_alloc(duk_heap *heap, duk_size_t size) { + void *res; + + DUK_ASSERT(heap != NULL); + DUK_ASSERT(heap->alloc_func != NULL); + DUK_ASSERT_DISABLE(size >= 0); + +#if defined(DUK_USE_VOLUNTARY_GC) + /* Voluntary periodic GC (if enabled). */ + if (DUK_UNLIKELY(--(heap)->ms_trigger_counter < 0)) { + goto slowpath; + } +#endif + +#if defined(DUK_USE_GC_TORTURE) + /* Simulate alloc failure on every alloc, except when mark-and-sweep + * is running. + */ + if (heap->ms_prevent_count == 0) { + DUK_DDD(DUK_DDDPRINT("gc torture enabled, pretend that first alloc attempt fails")); + res = NULL; + DUK_UNREF(res); + goto slowpath; + } +#endif + + /* Zero-size allocation should happen very rarely (if at all), so + * don't check zero size on NULL; handle it in the slow path + * instead. This reduces size of inlined code. + */ + res = heap->alloc_func(heap->heap_udata, size); + if (DUK_LIKELY(res != NULL)) { + return res; + } + + slowpath: + + if (size == 0) { + DUK_D(DUK_DPRINT("first alloc attempt returned NULL for zero size alloc, use slow path to deal with it")); + } else { + DUK_D(DUK_DPRINT("first alloc attempt failed, attempt to gc and retry")); + } + return duk__heap_mem_alloc_slowpath(heap, size); +} + +DUK_INTERNAL DUK_INLINE_PERF DUK_HOT void *duk_heap_mem_alloc_zeroed(duk_heap *heap, duk_size_t size) { + void *res; + + DUK_ASSERT(heap != NULL); + DUK_ASSERT(heap->alloc_func != NULL); + DUK_ASSERT_DISABLE(size >= 0); + + res = DUK_ALLOC(heap, size); + if (DUK_LIKELY(res != NULL)) { + duk_memzero(res, size); + } + return res; +} + +DUK_INTERNAL DUK_INLINE_PERF DUK_HOT void *duk_heap_mem_alloc_checked(duk_hthread *thr, duk_size_t size) { + void *res; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(thr->heap->alloc_func != NULL); + + res = duk_heap_mem_alloc(thr->heap, size); + if (DUK_LIKELY(res != NULL)) { + return res; + } else if (size == 0) { + DUK_ASSERT(res == NULL); + return res; + } + DUK_ERROR_ALLOC_FAILED(thr); + DUK_WO_NORETURN(return NULL;); +} + +DUK_INTERNAL DUK_INLINE_PERF DUK_HOT void *duk_heap_mem_alloc_checked_zeroed(duk_hthread *thr, duk_size_t size) { + void *res; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(thr->heap->alloc_func != NULL); + + res = duk_heap_mem_alloc(thr->heap, size); + if (DUK_LIKELY(res != NULL)) { + duk_memzero(res, size); + return res; + } else if (size == 0) { + DUK_ASSERT(res == NULL); + return res; + } + DUK_ERROR_ALLOC_FAILED(thr); + DUK_WO_NORETURN(return NULL;); +} + +/* + * Reallocate memory with garbage collection. + */ + +/* Slow path: voluntary GC triggered, first realloc attempt failed, or zero size. */ +DUK_LOCAL DUK_NOINLINE_PERF DUK_COLD void *duk__heap_mem_realloc_slowpath(duk_heap *heap, void *ptr, duk_size_t newsize) { + void *res; + duk_small_int_t i; + + DUK_ASSERT(heap != NULL); + DUK_ASSERT(heap->realloc_func != NULL); + /* ptr may be NULL */ + DUK_ASSERT_DISABLE(newsize >= 0); + + /* Newsize was 0 and realloc() returned NULL, this has the semantics + * of free(oldptr), i.e. memory was successfully freed. + */ + if (newsize == 0) { + DUK_D(DUK_DPRINT("zero size realloc in slow path, return NULL")); + return NULL; + } + + DUK_D(DUK_DPRINT("first realloc attempt failed, attempt to gc and retry")); + +#if 0 + /* + * Avoid a GC if GC is already running. See duk_heap_mem_alloc(). + */ + + if (heap->ms_prevent_count != 0) { + DUK_D(DUK_DPRINT("duk_heap_mem_realloc() failed, gc in progress (gc skipped), alloc size %ld", (long) newsize)); + return NULL; + } +#endif + + /* + * Retry with several GC attempts. Initial attempts are made without + * emergency mode; later attempts use emergency mode which minimizes + * memory allocations forcibly. + */ + + for (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) { + duk_small_uint_t flags; + + flags = 0; + if (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) { + flags |= DUK_MS_FLAG_EMERGENCY; + } + + duk_heap_mark_and_sweep(heap, flags); + + DUK_ASSERT(newsize > 0); + res = heap->realloc_func(heap->heap_udata, ptr, newsize); + if (res || newsize == 0) { + DUK_D(DUK_DPRINT("duk_heap_mem_realloc() succeeded after gc (pass %ld), alloc size %ld", + (long) (i + 1), (long) newsize)); + return res; + } + } + + DUK_D(DUK_DPRINT("duk_heap_mem_realloc() failed even after gc, alloc size %ld", (long) newsize)); + return NULL; +} + +DUK_INTERNAL DUK_INLINE_PERF DUK_HOT void *duk_heap_mem_realloc(duk_heap *heap, void *ptr, duk_size_t newsize) { + void *res; + + DUK_ASSERT(heap != NULL); + DUK_ASSERT(heap->realloc_func != NULL); + /* ptr may be NULL */ + DUK_ASSERT_DISABLE(newsize >= 0); + +#if defined(DUK_USE_VOLUNTARY_GC) + /* Voluntary periodic GC (if enabled). */ + if (DUK_UNLIKELY(--(heap)->ms_trigger_counter < 0)) { + goto slowpath; + } +#endif + +#if defined(DUK_USE_GC_TORTURE) + /* Simulate alloc failure on every realloc, except when mark-and-sweep + * is running. + */ + if (heap->ms_prevent_count == 0) { + DUK_DDD(DUK_DDDPRINT("gc torture enabled, pretend that first realloc attempt fails")); + res = NULL; + DUK_UNREF(res); + goto slowpath; + } +#endif + + res = heap->realloc_func(heap->heap_udata, ptr, newsize); + if (DUK_LIKELY(res != NULL)) { + return res; + } + + slowpath: + + if (newsize == 0) { + DUK_D(DUK_DPRINT("first realloc attempt returned NULL for zero size realloc, use slow path to deal with it")); + } else { + DUK_D(DUK_DPRINT("first realloc attempt failed, attempt to gc and retry")); + } + return duk__heap_mem_realloc_slowpath(heap, ptr, newsize); +} + +/* + * Reallocate memory with garbage collection, using a callback to provide + * the current allocated pointer. This variant is used when a mark-and-sweep + * (e.g. finalizers) might change the original pointer. + */ + +/* Slow path: voluntary GC triggered, first realloc attempt failed, or zero size. */ +DUK_LOCAL DUK_NOINLINE_PERF DUK_COLD void *duk__heap_mem_realloc_indirect_slowpath(duk_heap *heap, duk_mem_getptr cb, void *ud, duk_size_t newsize) { + void *res; + duk_small_int_t i; + + DUK_ASSERT(heap != NULL); + DUK_ASSERT(heap->realloc_func != NULL); + DUK_ASSERT_DISABLE(newsize >= 0); + + if (newsize == 0) { + DUK_D(DUK_DPRINT("zero size indirect realloc in slow path, return NULL")); + return NULL; + } + + DUK_D(DUK_DPRINT("first indirect realloc attempt failed, attempt to gc and retry")); + +#if 0 + /* + * Avoid a GC if GC is already running. See duk_heap_mem_alloc(). + */ + + if (heap->ms_prevent_count != 0) { + DUK_D(DUK_DPRINT("duk_heap_mem_realloc_indirect() failed, gc in progress (gc skipped), alloc size %ld", (long) newsize)); + return NULL; + } +#endif + + /* + * Retry with several GC attempts. Initial attempts are made without + * emergency mode; later attempts use emergency mode which minimizes + * memory allocations forcibly. + */ + + for (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) { + duk_small_uint_t flags; + +#if defined(DUK_USE_DEBUG) + void *ptr_pre; + void *ptr_post; +#endif + +#if defined(DUK_USE_DEBUG) + ptr_pre = cb(heap, ud); +#endif + flags = 0; + if (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) { + flags |= DUK_MS_FLAG_EMERGENCY; + } + + duk_heap_mark_and_sweep(heap, flags); +#if defined(DUK_USE_DEBUG) + ptr_post = cb(heap, ud); + if (ptr_pre != ptr_post) { + DUK_DD(DUK_DDPRINT("realloc base pointer changed by mark-and-sweep: %p -> %p", + (void *) ptr_pre, (void *) ptr_post)); + } +#endif + + /* Note: key issue here is to re-lookup the base pointer on every attempt. + * The pointer being reallocated may change after every mark-and-sweep. + */ + + DUK_ASSERT(newsize > 0); + res = heap->realloc_func(heap->heap_udata, cb(heap, ud), newsize); + if (res || newsize == 0) { + DUK_D(DUK_DPRINT("duk_heap_mem_realloc_indirect() succeeded after gc (pass %ld), alloc size %ld", + (long) (i + 1), (long) newsize)); + return res; + } + } + + DUK_D(DUK_DPRINT("duk_heap_mem_realloc_indirect() failed even after gc, alloc size %ld", (long) newsize)); + return NULL; +} + +DUK_INTERNAL DUK_INLINE_PERF DUK_HOT void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr cb, void *ud, duk_size_t newsize) { + void *res; + + DUK_ASSERT(heap != NULL); + DUK_ASSERT(heap->realloc_func != NULL); + DUK_ASSERT_DISABLE(newsize >= 0); + +#if defined(DUK_USE_VOLUNTARY_GC) + /* Voluntary periodic GC (if enabled). */ + if (DUK_UNLIKELY(--(heap)->ms_trigger_counter < 0)) { + goto slowpath; + } +#endif + +#if defined(DUK_USE_GC_TORTURE) + /* Simulate alloc failure on every realloc, except when mark-and-sweep + * is running. + */ + if (heap->ms_prevent_count == 0) { + DUK_DDD(DUK_DDDPRINT("gc torture enabled, pretend that first indirect realloc attempt fails")); + res = NULL; + DUK_UNREF(res); + goto slowpath; + } +#endif + + res = heap->realloc_func(heap->heap_udata, cb(heap, ud), newsize); + if (DUK_LIKELY(res != NULL)) { + return res; + } + + slowpath: + + if (newsize == 0) { + DUK_D(DUK_DPRINT("first indirect realloc attempt returned NULL for zero size realloc, use slow path to deal with it")); + } else { + DUK_D(DUK_DPRINT("first indirect realloc attempt failed, attempt to gc and retry")); + } + return duk__heap_mem_realloc_indirect_slowpath(heap, cb, ud, newsize); +} + +/* + * Free memory + */ + +DUK_INTERNAL DUK_INLINE_PERF DUK_HOT void duk_heap_mem_free(duk_heap *heap, void *ptr) { + DUK_ASSERT(heap != NULL); + DUK_ASSERT(heap->free_func != NULL); + /* ptr may be NULL */ + + /* Must behave like a no-op with NULL and any pointer returned from + * malloc/realloc with zero size. + */ + heap->free_func(heap->heap_udata, ptr); + + /* Never perform a GC (even voluntary) in a memory free, otherwise + * all call sites doing frees would need to deal with the side effects. + * No need to update voluntary GC counter either. + */ +} diff --git a/third_party/duktape/duk_heap_misc.c b/third_party/duktape/duk_heap_misc.c new file mode 100644 index 00000000..d9c1def7 --- /dev/null +++ b/third_party/duktape/duk_heap_misc.c @@ -0,0 +1,187 @@ +/* + * Support functions for duk_heap. + */ + +#include "third_party/duktape/duk_internal.h" + +DUK_INTERNAL void duk_heap_insert_into_heap_allocated(duk_heap *heap, duk_heaphdr *hdr) { + duk_heaphdr *root; + + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) != DUK_HTYPE_STRING); + + root = heap->heap_allocated; +#if defined(DUK_USE_DOUBLE_LINKED_HEAP) + if (root != NULL) { + DUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, root) == NULL); + DUK_HEAPHDR_SET_PREV(heap, root, hdr); + } + DUK_HEAPHDR_SET_PREV(heap, hdr, NULL); +#endif + DUK_HEAPHDR_SET_NEXT(heap, hdr, root); + DUK_HEAPHDR_ASSERT_LINKS(heap, hdr); + DUK_HEAPHDR_ASSERT_LINKS(heap, root); + heap->heap_allocated = hdr; +} + +#if defined(DUK_USE_REFERENCE_COUNTING) +DUK_INTERNAL void duk_heap_remove_from_heap_allocated(duk_heap *heap, duk_heaphdr *hdr) { + duk_heaphdr *prev; + duk_heaphdr *next; + + /* Strings are in string table. */ + DUK_ASSERT(hdr != NULL); + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) != DUK_HTYPE_STRING); + + /* Target 'hdr' must be in heap_allocated (not e.g. finalize_list). + * If not, heap lists will become corrupted so assert early for it. + */ +#if defined(DUK_USE_ASSERTIONS) + { + duk_heaphdr *tmp; + for (tmp = heap->heap_allocated; tmp != NULL; tmp = DUK_HEAPHDR_GET_NEXT(heap, tmp)) { + if (tmp == hdr) { + break; + } + } + DUK_ASSERT(tmp == hdr); + } +#endif + + /* Read/write only once to minimize pointer compression calls. */ + prev = DUK_HEAPHDR_GET_PREV(heap, hdr); + next = DUK_HEAPHDR_GET_NEXT(heap, hdr); + + if (prev != NULL) { + DUK_ASSERT(heap->heap_allocated != hdr); + DUK_HEAPHDR_SET_NEXT(heap, prev, next); + } else { + DUK_ASSERT(heap->heap_allocated == hdr); + heap->heap_allocated = next; + } + if (next != NULL) { + DUK_HEAPHDR_SET_PREV(heap, next, prev); + } else { + ; + } +} +#endif /* DUK_USE_REFERENCE_COUNTING */ + +#if defined(DUK_USE_FINALIZER_SUPPORT) +DUK_INTERNAL void duk_heap_insert_into_finalize_list(duk_heap *heap, duk_heaphdr *hdr) { + duk_heaphdr *root; + + root = heap->finalize_list; +#if defined(DUK_USE_DOUBLE_LINKED_HEAP) + DUK_HEAPHDR_SET_PREV(heap, hdr, NULL); + if (root != NULL) { + DUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, root) == NULL); + DUK_HEAPHDR_SET_PREV(heap, root, hdr); + } +#endif + DUK_HEAPHDR_SET_NEXT(heap, hdr, root); + DUK_HEAPHDR_ASSERT_LINKS(heap, hdr); + DUK_HEAPHDR_ASSERT_LINKS(heap, root); + heap->finalize_list = hdr; +} +#endif /* DUK_USE_FINALIZER_SUPPORT */ + +#if defined(DUK_USE_FINALIZER_SUPPORT) +DUK_INTERNAL void duk_heap_remove_from_finalize_list(duk_heap *heap, duk_heaphdr *hdr) { +#if defined(DUK_USE_DOUBLE_LINKED_HEAP) + duk_heaphdr *next; + duk_heaphdr *prev; + + next = DUK_HEAPHDR_GET_NEXT(heap, hdr); + prev = DUK_HEAPHDR_GET_PREV(heap, hdr); + if (next != NULL) { + DUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, next) == hdr); + DUK_HEAPHDR_SET_PREV(heap, next, prev); + } + if (prev == NULL) { + DUK_ASSERT(hdr == heap->finalize_list); + heap->finalize_list = next; + } else { + DUK_ASSERT(hdr != heap->finalize_list); + DUK_HEAPHDR_SET_NEXT(heap, prev, next); + } +#else + duk_heaphdr *next; + duk_heaphdr *curr; + + /* Random removal is expensive: we need to locate the previous element + * because we don't have a 'prev' pointer. + */ + curr = heap->finalize_list; + if (curr == hdr) { + heap->finalize_list = DUK_HEAPHDR_GET_NEXT(heap, curr); + } else { + DUK_ASSERT(hdr != heap->finalize_list); + for (;;) { + DUK_ASSERT(curr != NULL); /* Caller responsibility. */ + + next = DUK_HEAPHDR_GET_NEXT(heap, curr); + if (next == hdr) { + next = DUK_HEAPHDR_GET_NEXT(heap, hdr); + DUK_HEAPHDR_SET_NEXT(heap, curr, next); + break; + } + } + } +#endif +} +#endif /* DUK_USE_FINALIZER_SUPPORT */ + +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL duk_bool_t duk_heap_in_heap_allocated(duk_heap *heap, duk_heaphdr *ptr) { + duk_heaphdr *curr; + DUK_ASSERT(heap != NULL); + + for (curr = heap->heap_allocated; curr != NULL; curr = DUK_HEAPHDR_GET_NEXT(heap, curr)) { + if (curr == ptr) { + return 1; + } + } + return 0; +} +#endif /* DUK_USE_ASSERTIONS */ + +#if defined(DUK_USE_INTERRUPT_COUNTER) +DUK_INTERNAL void duk_heap_switch_thread(duk_heap *heap, duk_hthread *new_thr) { + duk_hthread *curr_thr; + + DUK_ASSERT(heap != NULL); + + if (new_thr != NULL) { + curr_thr = heap->curr_thread; + if (curr_thr == NULL) { + /* For initial entry use default value; zero forces an + * interrupt before executing the first insturction. + */ + DUK_DD(DUK_DDPRINT("switch thread, initial entry, init default interrupt counter")); + new_thr->interrupt_counter = 0; + new_thr->interrupt_init = 0; + } else { + /* Copy interrupt counter/init value state to new thread (if any). + * It's OK for new_thr to be the same as curr_thr. + */ +#if defined(DUK_USE_DEBUG) + if (new_thr != curr_thr) { + DUK_DD(DUK_DDPRINT("switch thread, not initial entry, copy interrupt counter")); + } +#endif + new_thr->interrupt_counter = curr_thr->interrupt_counter; + new_thr->interrupt_init = curr_thr->interrupt_init; + } + } else { + DUK_DD(DUK_DDPRINT("switch thread, new thread is NULL, no interrupt counter changes")); + } + + heap->curr_thread = new_thr; /* may be NULL */ +} +#endif /* DUK_USE_INTERRUPT_COUNTER */ + +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL void duk_heap_assert_valid(duk_heap *heap) { + DUK_ASSERT(heap != NULL); +} +#endif diff --git a/third_party/duktape/duk_heap_refcount.c b/third_party/duktape/duk_heap_refcount.c new file mode 100644 index 00000000..529c4ed9 --- /dev/null +++ b/third_party/duktape/duk_heap_refcount.c @@ -0,0 +1,833 @@ +/* + * Reference counting implementation. + * + * INCREF/DECREF, finalization and freeing of objects whose refcount reaches + * zero (refzero). These operations are very performance sensitive, so + * various small tricks are used in an attempt to maximize speed. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_REFERENCE_COUNTING) + +#if !defined(DUK_USE_DOUBLE_LINKED_HEAP) +#error internal error, reference counting requires a double linked heap +#endif + +/* + * Heap object refcount finalization. + * + * When an object is about to be freed, all other objects it refers to must + * be decref'd. Refcount finalization does NOT free the object or its inner + * allocations (mark-and-sweep shares these helpers), it just manipulates + * the refcounts. + * + * Note that any of the DECREFs may cause a refcount to drop to zero. If so, + * the object won't be refzero processed inline, but will just be queued to + * refzero_list and processed by an earlier caller working on refzero_list, + * eliminating C recursion from even long refzero cascades. If refzero + * finalization is triggered by mark-and-sweep, refzero conditions are ignored + * (objects are not even queued to refzero_list) because mark-and-sweep deals + * with them; refcounts are still updated so that they remain in sync with + * actual references. + */ + +DUK_LOCAL void duk__decref_tvals_norz(duk_hthread *thr, duk_tval *tv, duk_idx_t count) { + DUK_ASSERT(count == 0 || tv != NULL); + + while (count-- > 0) { + DUK_TVAL_DECREF_NORZ(thr, tv); + tv++; + } +} + +DUK_INTERNAL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject *h) { + duk_hthread *thr; + duk_uint_fast32_t i; + duk_uint_fast32_t n; + duk_propvalue *p_val; + duk_tval *p_tv; + duk_hstring **p_key; + duk_uint8_t *p_flag; + duk_hobject *h_proto; + + DUK_ASSERT(heap != NULL); + DUK_ASSERT(heap->heap_thread != NULL); + DUK_ASSERT(h); + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h) == DUK_HTYPE_OBJECT); + + thr = heap->heap_thread; + DUK_ASSERT(thr != NULL); + + p_key = DUK_HOBJECT_E_GET_KEY_BASE(heap, h); + p_val = DUK_HOBJECT_E_GET_VALUE_BASE(heap, h); + p_flag = DUK_HOBJECT_E_GET_FLAGS_BASE(heap, h); + n = DUK_HOBJECT_GET_ENEXT(h); + while (n-- > 0) { + duk_hstring *key; + + key = p_key[n]; + if (DUK_UNLIKELY(key == NULL)) { + continue; + } + DUK_HSTRING_DECREF_NORZ(thr, key); + if (DUK_UNLIKELY(p_flag[n] & DUK_PROPDESC_FLAG_ACCESSOR)) { + duk_hobject *h_getset; + h_getset = p_val[n].a.get; + DUK_ASSERT(h_getset == NULL || DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_getset)); + DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h_getset); + h_getset = p_val[n].a.set; + DUK_ASSERT(h_getset == NULL || DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_getset)); + DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h_getset); + } else { + duk_tval *tv_val; + tv_val = &p_val[n].v; + DUK_TVAL_DECREF_NORZ(thr, tv_val); + } + } + + p_tv = DUK_HOBJECT_A_GET_BASE(heap, h); + n = DUK_HOBJECT_GET_ASIZE(h); + while (n-- > 0) { + duk_tval *tv_val; + tv_val = p_tv + n; + DUK_TVAL_DECREF_NORZ(thr, tv_val); + } + + /* Hash part is a 'weak reference' and doesn't contribute to refcounts. */ + + h_proto = (duk_hobject *) DUK_HOBJECT_GET_PROTOTYPE(heap, h); + DUK_ASSERT(h_proto == NULL || DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_proto)); + DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h_proto); + + /* XXX: Object subclass tests are quite awkward at present, ideally + * we should be able to switch-case here with a dense index (subtype + * number or something). For now, fast path plain objects and arrays + * and bit test the rest individually. + */ + + if (DUK_HOBJECT_HAS_FASTREFS(h)) { + /* Plain object or array, nothing more to do. While a + * duk_harray has additional fields, none of them need + * DECREF updates. + */ + DUK_ASSERT(DUK_HOBJECT_ALLOWS_FASTREFS(h)); + return; + } + DUK_ASSERT(DUK_HOBJECT_PROHIBITS_FASTREFS(h)); + + /* Slow path: special object, start bit checks from most likely. */ + + /* XXX: reorg, more common first */ + if (DUK_HOBJECT_IS_COMPFUNC(h)) { + duk_hcompfunc *f = (duk_hcompfunc *) h; + duk_tval *tv, *tv_end; + duk_hobject **funcs, **funcs_end; + + DUK_HCOMPFUNC_ASSERT_VALID(f); + + if (DUK_LIKELY(DUK_HCOMPFUNC_GET_DATA(heap, f) != NULL)) { + tv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, f); + tv_end = DUK_HCOMPFUNC_GET_CONSTS_END(heap, f); + while (tv < tv_end) { + DUK_TVAL_DECREF_NORZ(thr, tv); + tv++; + } + + funcs = DUK_HCOMPFUNC_GET_FUNCS_BASE(heap, f); + funcs_end = DUK_HCOMPFUNC_GET_FUNCS_END(heap, f); + while (funcs < funcs_end) { + duk_hobject *h_func; + h_func = *funcs; + DUK_ASSERT(h_func != NULL); + DUK_ASSERT(DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_func)); + DUK_HCOMPFUNC_DECREF_NORZ(thr, (duk_hcompfunc *) h_func); + funcs++; + } + } else { + /* May happen in some out-of-memory corner cases. */ + DUK_D(DUK_DPRINT("duk_hcompfunc 'data' is NULL, skipping decref")); + } + + DUK_HEAPHDR_DECREF_ALLOWNULL(thr, (duk_heaphdr *) DUK_HCOMPFUNC_GET_LEXENV(heap, f)); + DUK_HEAPHDR_DECREF_ALLOWNULL(thr, (duk_heaphdr *) DUK_HCOMPFUNC_GET_VARENV(heap, f)); + DUK_HEAPHDR_DECREF_ALLOWNULL(thr, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(heap, f)); + } else if (DUK_HOBJECT_IS_DECENV(h)) { + duk_hdecenv *e = (duk_hdecenv *) h; + DUK_HDECENV_ASSERT_VALID(e); + DUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr, e->thread); + DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, e->varmap); + } else if (DUK_HOBJECT_IS_OBJENV(h)) { + duk_hobjenv *e = (duk_hobjenv *) h; + DUK_HOBJENV_ASSERT_VALID(e); + DUK_ASSERT(e->target != NULL); /* Required for object environments. */ + DUK_HOBJECT_DECREF_NORZ(thr, e->target); +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + } else if (DUK_HOBJECT_IS_BUFOBJ(h)) { + duk_hbufobj *b = (duk_hbufobj *) h; + DUK_HBUFOBJ_ASSERT_VALID(b); + DUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr, (duk_hbuffer *) b->buf); + DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) b->buf_prop); +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + } else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) { + duk_hboundfunc *f = (duk_hboundfunc *) (void *) h; + DUK_HBOUNDFUNC_ASSERT_VALID(f); + DUK_TVAL_DECREF_NORZ(thr, &f->target); + DUK_TVAL_DECREF_NORZ(thr, &f->this_binding); + duk__decref_tvals_norz(thr, f->args, f->nargs); +#if defined(DUK_USE_ES6_PROXY) + } else if (DUK_HOBJECT_IS_PROXY(h)) { + duk_hproxy *p = (duk_hproxy *) h; + DUK_HPROXY_ASSERT_VALID(p); + DUK_HOBJECT_DECREF_NORZ(thr, p->target); + DUK_HOBJECT_DECREF_NORZ(thr, p->handler); +#endif /* DUK_USE_ES6_PROXY */ + } else if (DUK_HOBJECT_IS_THREAD(h)) { + duk_hthread *t = (duk_hthread *) h; + duk_activation *act; + duk_tval *tv; + + DUK_HTHREAD_ASSERT_VALID(t); + + tv = t->valstack; + while (tv < t->valstack_top) { + DUK_TVAL_DECREF_NORZ(thr, tv); + tv++; + } + + for (act = t->callstack_curr; act != NULL; act = act->parent) { + DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) DUK_ACT_GET_FUNC(act)); + DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->var_env); + DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->lex_env); +#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY) + DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->prev_caller); +#endif +#if 0 /* nothing now */ + for (cat = act->cat; cat != NULL; cat = cat->parent) { + } +#endif + } + + + for (i = 0; i < DUK_NUM_BUILTINS; i++) { + DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) t->builtins[i]); + } + + DUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr, (duk_hthread *) t->resumer); + } else { + /* We may come here if the object should have a FASTREFS flag + * but it's missing for some reason. Assert for never getting + * here; however, other than performance, this is harmless. + */ + DUK_D(DUK_DPRINT("missing FASTREFS flag for: %!iO", h)); + DUK_ASSERT(0); + } +} + +DUK_INTERNAL void duk_heaphdr_refcount_finalize_norz(duk_heap *heap, duk_heaphdr *hdr) { + DUK_ASSERT(heap != NULL); + DUK_ASSERT(heap->heap_thread != NULL); + DUK_ASSERT(hdr != NULL); + + if (DUK_HEAPHDR_IS_OBJECT(hdr)) { + duk_hobject_refcount_finalize_norz(heap, (duk_hobject *) hdr); + } + /* DUK_HTYPE_BUFFER: nothing to finalize */ + /* DUK_HTYPE_STRING: nothing to finalize */ +} + +/* + * Refzero processing for duk_hobject: queue a refzero'ed object to either + * finalize_list or refzero_list and process the relevent list(s) if + * necessary. + * + * Refzero_list is single linked, with only 'prev' pointers set and valid. + * All 'next' pointers are intentionally left as garbage. This doesn't + * matter because refzero_list is processed to completion before any other + * code (like mark-and-sweep) might walk the list. + * + * In more detail: + * + * - On first insert refzero_list is NULL and the new object becomes the + * first and only element on the list; duk__refcount_free_pending() is + * called and it starts processing the list from the initial element, + * i.e. the list tail. + * + * - As each object is refcount finalized, new objects may be queued to + * refzero_list head. Their 'next' pointers are left as garbage, but + * 'prev' points are set correctly, with the element at refzero_list + * having a NULL 'prev' pointer. The fact that refzero_list is non-NULL + * is used to reject (1) recursive duk__refcount_free_pending() and + * (2) finalize_list processing calls. + * + * - When we're done with the current object, read its 'prev' pointer and + * free the object. If 'prev' is NULL, we've reached head of list and are + * done: set refzero_list to NULL and process pending finalizers. Otherwise + * continue processing the list. + * + * A refzero cascade is free of side effects because it only involves + * queueing more objects and freeing memory; finalizer execution is blocked + * in the code path queueing objects to finalize_list. As a result the + * initial refzero call (which triggers duk__refcount_free_pending()) must + * check finalize_list so that finalizers are executed snappily. + * + * If finalize_list processing starts first, refzero may occur while we're + * processing finalizers. That's fine: that particular refzero cascade is + * handled to completion without side effects. Once the cascade is complete, + * we'll run pending finalizers but notice that we're already doing that and + * return. + * + * This could be expanded to allow incremental freeing: just bail out + * early and resume at a future alloc/decref/refzero. However, if that + * were done, the list structure would need to be kept consistent at all + * times, mark-and-sweep would need to handle refzero_list, etc. + */ + +DUK_LOCAL void duk__refcount_free_pending(duk_heap *heap) { + duk_heaphdr *curr; +#if defined(DUK_USE_DEBUG) + duk_int_t count = 0; +#endif + + DUK_ASSERT(heap != NULL); + + curr = heap->refzero_list; + DUK_ASSERT(curr != NULL); + DUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, curr) == NULL); /* We're called on initial insert only. */ + /* curr->next is GARBAGE. */ + + do { + duk_heaphdr *prev; + + DUK_DDD(DUK_DDDPRINT("refzero processing %p: %!O", (void *) curr, (duk_heaphdr *) curr)); + +#if defined(DUK_USE_DEBUG) + count++; +#endif + + DUK_ASSERT(curr != NULL); + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT); /* currently, always the case */ + /* FINALIZED may be set; don't care about flags here. */ + + /* Refcount finalize 'curr'. Refzero_list must be non-NULL + * here to prevent recursive entry to duk__refcount_free_pending(). + */ + DUK_ASSERT(heap->refzero_list != NULL); + duk_hobject_refcount_finalize_norz(heap, (duk_hobject *) curr); + + prev = DUK_HEAPHDR_GET_PREV(heap, curr); + DUK_ASSERT((prev == NULL && heap->refzero_list == curr) || \ + (prev != NULL && heap->refzero_list != curr)); + /* prev->next is intentionally not updated and is garbage. */ + + duk_free_hobject(heap, (duk_hobject *) curr); /* Invalidates 'curr'. */ + + curr = prev; + } while (curr != NULL); + + heap->refzero_list = NULL; + + DUK_DD(DUK_DDPRINT("refzero processed %ld objects", (long) count)); +} + +DUK_LOCAL DUK_INLINE void duk__refcount_refzero_hobject(duk_heap *heap, duk_hobject *obj, duk_bool_t skip_free_pending) { + duk_heaphdr *hdr; + duk_heaphdr *root; + + DUK_ASSERT(heap != NULL); + DUK_ASSERT(heap->heap_thread != NULL); + DUK_ASSERT(obj != NULL); + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) obj) == DUK_HTYPE_OBJECT); + + hdr = (duk_heaphdr *) obj; + + /* Refzero'd objects must be in heap_allocated. They can't be in + * finalize_list because all objects on finalize_list have an + * artificial +1 refcount bump. + */ +#if defined(DUK_USE_ASSERTIONS) + DUK_ASSERT(duk_heap_in_heap_allocated(heap, (duk_heaphdr *) obj)); +#endif + + DUK_HEAP_REMOVE_FROM_HEAP_ALLOCATED(heap, hdr); + +#if defined(DUK_USE_FINALIZER_SUPPORT) + /* This finalizer check MUST BE side effect free. It should also be + * as fast as possible because it's applied to every object freed. + */ + if (DUK_UNLIKELY(DUK_HOBJECT_HAS_FINALIZER_FAST(heap, (duk_hobject *) hdr) != 0U)) { + /* Special case: FINALIZED may be set if mark-and-sweep queued + * object for finalization, the finalizer was executed (and + * FINALIZED set), mark-and-sweep hasn't yet processed the + * object again, but its refcount drops to zero. Free without + * running the finalizer again. + */ + if (DUK_HEAPHDR_HAS_FINALIZED(hdr)) { + DUK_D(DUK_DPRINT("refzero'd object has finalizer and FINALIZED is set -> free")); + } else { + /* Set FINALIZABLE flag so that all objects on finalize_list + * will have it set and are thus detectable based on the + * flag alone. + */ + DUK_HEAPHDR_SET_FINALIZABLE(hdr); + DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(hdr)); + +#if defined(DUK_USE_REFERENCE_COUNTING) + /* Bump refcount on finalize_list insert so that a + * refzero can never occur when an object is waiting + * for its finalizer call. Refzero might otherwise + * now happen because we allow duk_push_heapptr() for + * objects pending finalization. + */ + DUK_HEAPHDR_PREINC_REFCOUNT(hdr); +#endif + DUK_HEAP_INSERT_INTO_FINALIZE_LIST(heap, hdr); + + /* Process finalizers unless skipping is explicitly + * requested (NORZ) or refzero_list is being processed + * (avoids side effects during a refzero cascade). + * If refzero_list is processed, the initial refzero + * call will run pending finalizers when refzero_list + * is done. + */ + if (!skip_free_pending && heap->refzero_list == NULL) { + duk_heap_process_finalize_list(heap); + } + return; + } + } +#endif /* DUK_USE_FINALIZER_SUPPORT */ + + /* No need to finalize, free object via refzero_list. */ + + root = heap->refzero_list; + + DUK_HEAPHDR_SET_PREV(heap, hdr, NULL); + /* 'next' is left as GARBAGE. */ + heap->refzero_list = hdr; + + if (root == NULL) { + /* Object is now queued. Refzero_list was NULL so + * no-one is currently processing it; do it here. + * With refzero processing just doing a cascade of + * free calls, we can process it directly even when + * NORZ macros are used: there are no side effects. + */ + duk__refcount_free_pending(heap); + DUK_ASSERT(heap->refzero_list == NULL); + + /* Process finalizers only after the entire cascade + * is finished. In most cases there's nothing to + * finalize, so fast path check to avoid a call. + */ +#if defined(DUK_USE_FINALIZER_SUPPORT) + if (!skip_free_pending && DUK_UNLIKELY(heap->finalize_list != NULL)) { + duk_heap_process_finalize_list(heap); + } +#endif + } else { + DUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, root) == NULL); + DUK_HEAPHDR_SET_PREV(heap, root, hdr); + + /* Object is now queued. Because refzero_list was + * non-NULL, it's already being processed by someone + * in the C call stack, so we're done. + */ + } +} + +#if defined(DUK_USE_FINALIZER_SUPPORT) +DUK_INTERNAL DUK_ALWAYS_INLINE void duk_refzero_check_fast(duk_hthread *thr) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(thr->heap->refzero_list == NULL); /* Processed to completion inline. */ + + if (DUK_UNLIKELY(thr->heap->finalize_list != NULL)) { + duk_heap_process_finalize_list(thr->heap); + } +} + +DUK_INTERNAL void duk_refzero_check_slow(duk_hthread *thr) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(thr->heap->refzero_list == NULL); /* Processed to completion inline. */ + + if (DUK_UNLIKELY(thr->heap->finalize_list != NULL)) { + duk_heap_process_finalize_list(thr->heap); + } +} +#endif /* DUK_USE_FINALIZER_SUPPORT */ + +/* + * Refzero processing for duk_hstring. + */ + +DUK_LOCAL DUK_INLINE void duk__refcount_refzero_hstring(duk_heap *heap, duk_hstring *str) { + DUK_ASSERT(heap != NULL); + DUK_ASSERT(heap->heap_thread != NULL); + DUK_ASSERT(str != NULL); + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) str) == DUK_HTYPE_STRING); + + duk_heap_strcache_string_remove(heap, str); + duk_heap_strtable_unlink(heap, str); + duk_free_hstring(heap, str); +} + +/* + * Refzero processing for duk_hbuffer. + */ + +DUK_LOCAL DUK_INLINE void duk__refcount_refzero_hbuffer(duk_heap *heap, duk_hbuffer *buf) { + DUK_ASSERT(heap != NULL); + DUK_ASSERT(heap->heap_thread != NULL); + DUK_ASSERT(buf != NULL); + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) buf) == DUK_HTYPE_BUFFER); + + DUK_HEAP_REMOVE_FROM_HEAP_ALLOCATED(heap, (duk_heaphdr *) buf); + duk_free_hbuffer(heap, buf); +} + +/* + * Incref and decref functions. + * + * Decref may trigger immediate refzero handling, which may free and finalize + * an arbitrary number of objects (a "DECREF cascade"). + * + * Refzero handling is skipped entirely if (1) mark-and-sweep is running or + * (2) execution is paused in the debugger. The objects are left in the heap, + * and will be freed by mark-and-sweep or eventual heap destruction. + * + * This is necessary during mark-and-sweep because refcounts are also updated + * during the sweep phase (otherwise objects referenced by a swept object + * would have incorrect refcounts) which then calls here. This could be + * avoided by using separate decref macros in mark-and-sweep; however, + * mark-and-sweep also calls finalizers which would use the ordinary decref + * macros anyway. + * + * We can't process refzeros (= free objects) when the debugger is running + * as the debugger might make an object unreachable but still continue + * inspecting it (or even cause it to be pushed back). So we must rely on + * mark-and-sweep to collect them. + * + * The DUK__RZ_SUPPRESS_CHECK() condition is also used in heap destruction + * when running finalizers for remaining objects: the flag prevents objects + * from being moved around in heap linked lists while that's being done. + * + * The suppress condition is important to performance. + */ + +#define DUK__RZ_SUPPRESS_ASSERT1() do { \ + DUK_ASSERT(thr != NULL); \ + DUK_ASSERT(thr->heap != NULL); \ + /* When mark-and-sweep runs, heap_thread must exist. */ \ + DUK_ASSERT(thr->heap->ms_running == 0 || thr->heap->heap_thread != NULL); \ + /* In normal operation finalizers are executed with ms_running == 0 \ + * so we should never see ms_running == 1 and thr != heap_thread. \ + * In heap destruction finalizers are executed with ms_running != 0 \ + * to e.g. prevent refzero; a special value ms_running == 2 is used \ + * in that case so it can be distinguished from the normal runtime \ + * case, and allows a stronger assertion here (GH-2030). \ + */ \ + DUK_ASSERT(!(thr->heap->ms_running == 1 && thr != thr->heap->heap_thread)); \ + /* We may be called when the heap is initializing and we process \ + * refzeros normally, but mark-and-sweep and finalizers are prevented \ + * if that's the case. \ + */ \ + DUK_ASSERT(thr->heap->heap_initializing == 0 || thr->heap->ms_prevent_count > 0); \ + DUK_ASSERT(thr->heap->heap_initializing == 0 || thr->heap->pf_prevent_count > 0); \ + } while (0) + +#if defined(DUK_USE_DEBUGGER_SUPPORT) +#define DUK__RZ_SUPPRESS_ASSERT2() do { \ + /* When debugger is paused, ms_running is set. */ \ + DUK_ASSERT(!DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) || thr->heap->ms_running != 0); \ + } while (0) +#define DUK__RZ_SUPPRESS_COND() (heap->ms_running != 0) +#else +#define DUK__RZ_SUPPRESS_ASSERT2() do { } while (0) +#define DUK__RZ_SUPPRESS_COND() (heap->ms_running != 0) +#endif /* DUK_USE_DEBUGGER_SUPPORT */ + +#define DUK__RZ_SUPPRESS_CHECK() do { \ + DUK__RZ_SUPPRESS_ASSERT1(); \ + DUK__RZ_SUPPRESS_ASSERT2(); \ + if (DUK_UNLIKELY(DUK__RZ_SUPPRESS_COND())) { \ + DUK_DDD(DUK_DDDPRINT("refzero handling suppressed (not even queued) when mark-and-sweep running, object: %p", (void *) h)); \ + return; \ + } \ + } while (0) + +#define DUK__RZ_STRING() do { \ + duk__refcount_refzero_hstring(heap, (duk_hstring *) h); \ + } while (0) +#define DUK__RZ_BUFFER() do { \ + duk__refcount_refzero_hbuffer(heap, (duk_hbuffer *) h); \ + } while (0) +#define DUK__RZ_OBJECT() do { \ + duk__refcount_refzero_hobject(heap, (duk_hobject *) h, skip_free_pending); \ + } while (0) + +/* XXX: test the effect of inlining here vs. NOINLINE in refzero helpers */ +#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT) +#define DUK__RZ_INLINE DUK_ALWAYS_INLINE +#else +#define DUK__RZ_INLINE /*nop*/ +#endif + +DUK_LOCAL DUK__RZ_INLINE void duk__hstring_refzero_helper(duk_hthread *thr, duk_hstring *h) { + duk_heap *heap; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(h != NULL); + heap = thr->heap; + + DUK__RZ_SUPPRESS_CHECK(); + DUK__RZ_STRING(); +} + +DUK_LOCAL DUK__RZ_INLINE void duk__hbuffer_refzero_helper(duk_hthread *thr, duk_hbuffer *h) { + duk_heap *heap; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(h != NULL); + heap = thr->heap; + + DUK__RZ_SUPPRESS_CHECK(); + DUK__RZ_BUFFER(); +} + +DUK_LOCAL DUK__RZ_INLINE void duk__hobject_refzero_helper(duk_hthread *thr, duk_hobject *h, duk_bool_t skip_free_pending) { + duk_heap *heap; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(h != NULL); + heap = thr->heap; + + DUK__RZ_SUPPRESS_CHECK(); + DUK__RZ_OBJECT(); +} + +DUK_LOCAL DUK__RZ_INLINE void duk__heaphdr_refzero_helper(duk_hthread *thr, duk_heaphdr *h, duk_bool_t skip_free_pending) { + duk_heap *heap; + duk_small_uint_t htype; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(h != NULL); + heap = thr->heap; + + htype = (duk_small_uint_t) DUK_HEAPHDR_GET_TYPE(h); + DUK_DDD(DUK_DDDPRINT("ms_running=%ld, heap_thread=%p", (long) thr->heap->ms_running, thr->heap->heap_thread)); + DUK__RZ_SUPPRESS_CHECK(); + + switch (htype) { + case DUK_HTYPE_STRING: + /* Strings have no internal references but do have "weak" + * references in the string cache. Also note that strings + * are not on the heap_allocated list like other heap + * elements. + */ + + DUK__RZ_STRING(); + break; + + case DUK_HTYPE_OBJECT: + /* Objects have internal references. Must finalize through + * the "refzero" work list. + */ + + DUK__RZ_OBJECT(); + break; + + default: + /* Buffers have no internal references. However, a dynamic + * buffer has a separate allocation for the buffer. This is + * freed by duk_heap_free_heaphdr_raw(). + */ + + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(h) == DUK_HTYPE_BUFFER); + DUK__RZ_BUFFER(); + break; + } +} + +DUK_INTERNAL DUK_NOINLINE void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h) { + duk__heaphdr_refzero_helper(thr, h, 0 /*skip_free_pending*/); +} + +DUK_INTERNAL DUK_NOINLINE void duk_heaphdr_refzero_norz(duk_hthread *thr, duk_heaphdr *h) { + duk__heaphdr_refzero_helper(thr, h, 1 /*skip_free_pending*/); +} + +DUK_INTERNAL DUK_NOINLINE void duk_hstring_refzero(duk_hthread *thr, duk_hstring *h) { + duk__hstring_refzero_helper(thr, h); +} + +DUK_INTERNAL DUK_NOINLINE void duk_hbuffer_refzero(duk_hthread *thr, duk_hbuffer *h) { + duk__hbuffer_refzero_helper(thr, h); +} + +DUK_INTERNAL DUK_NOINLINE void duk_hobject_refzero(duk_hthread *thr, duk_hobject *h) { + duk__hobject_refzero_helper(thr, h, 0 /*skip_free_pending*/); +} + +DUK_INTERNAL DUK_NOINLINE void duk_hobject_refzero_norz(duk_hthread *thr, duk_hobject *h) { + duk__hobject_refzero_helper(thr, h, 1 /*skip_free_pending*/); +} + +#if !defined(DUK_USE_FAST_REFCOUNT_DEFAULT) +DUK_INTERNAL void duk_tval_incref(duk_tval *tv) { + DUK_ASSERT(tv != NULL); + + if (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)) { + duk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv); + DUK_ASSERT(h != NULL); + DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h)); + DUK_ASSERT_DISABLE(h->h_refcount >= 0); + DUK_HEAPHDR_PREINC_REFCOUNT(h); + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h) != 0); /* No wrapping. */ + } +} + +DUK_INTERNAL void duk_tval_decref(duk_hthread *thr, duk_tval *tv) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(tv != NULL); + + if (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)) { + duk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv); + DUK_ASSERT(h != NULL); + DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h)); + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h) >= 1); +#if 0 + if (DUK_HEAPHDR_PREDEC_REFCOUNT(h) != 0) { + return; + } + duk_heaphdr_refzero(thr, h); +#else + duk_heaphdr_decref(thr, h); +#endif + } +} + +DUK_INTERNAL void duk_tval_decref_norz(duk_hthread *thr, duk_tval *tv) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(tv != NULL); + + if (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)) { + duk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv); + DUK_ASSERT(h != NULL); + DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h)); + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h) >= 1); +#if 0 + if (DUK_HEAPHDR_PREDEC_REFCOUNT(h) != 0) { + return; + } + duk_heaphdr_refzero_norz(thr, h); +#else + duk_heaphdr_decref_norz(thr, h); +#endif + } +} +#endif /* !DUK_USE_FAST_REFCOUNT_DEFAULT */ + +#define DUK__DECREF_ASSERTS() do { \ + DUK_ASSERT(thr != NULL); \ + DUK_ASSERT(thr->heap != NULL); \ + DUK_ASSERT(h != NULL); \ + DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID((duk_heaphdr *) h)); \ + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) >= 1); \ + } while (0) +#if defined(DUK_USE_ROM_OBJECTS) +#define DUK__INCREF_SHARED() do { \ + if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) { \ + return; \ + } \ + DUK_HEAPHDR_PREINC_REFCOUNT((duk_heaphdr *) h); \ + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) != 0); /* No wrapping. */ \ + } while (0) +#define DUK__DECREF_SHARED() do { \ + if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) { \ + return; \ + } \ + if (DUK_HEAPHDR_PREDEC_REFCOUNT((duk_heaphdr *) h) != 0) { \ + return; \ + } \ + } while (0) +#else +#define DUK__INCREF_SHARED() do { \ + DUK_HEAPHDR_PREINC_REFCOUNT((duk_heaphdr *) h); \ + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) != 0); /* No wrapping. */ \ + } while (0) +#define DUK__DECREF_SHARED() do { \ + if (DUK_HEAPHDR_PREDEC_REFCOUNT((duk_heaphdr *) h) != 0) { \ + return; \ + } \ + } while (0) +#endif + +#if !defined(DUK_USE_FAST_REFCOUNT_DEFAULT) +/* This will in practice be inlined because it's just an INC instructions + * and a bit test + INC when ROM objects are enabled. + */ +DUK_INTERNAL void duk_heaphdr_incref(duk_heaphdr *h) { + DUK_ASSERT(h != NULL); + DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h)); + DUK_ASSERT_DISABLE(DUK_HEAPHDR_GET_REFCOUNT(h) >= 0); + + DUK__INCREF_SHARED(); +} + +DUK_INTERNAL void duk_heaphdr_decref(duk_hthread *thr, duk_heaphdr *h) { + DUK__DECREF_ASSERTS(); + DUK__DECREF_SHARED(); + duk_heaphdr_refzero(thr, h); + + /* Forced mark-and-sweep when GC torture enabled; this could happen + * on any DECREF (but not DECREF_NORZ). + */ + DUK_GC_TORTURE(thr->heap); +} +DUK_INTERNAL void duk_heaphdr_decref_norz(duk_hthread *thr, duk_heaphdr *h) { + DUK__DECREF_ASSERTS(); + DUK__DECREF_SHARED(); + duk_heaphdr_refzero_norz(thr, h); +} +#endif /* !DUK_USE_FAST_REFCOUNT_DEFAULT */ + +#if 0 /* Not needed. */ +DUK_INTERNAL void duk_hstring_decref(duk_hthread *thr, duk_hstring *h) { + DUK__DECREF_ASSERTS(); + DUK__DECREF_SHARED(); + duk_hstring_refzero(thr, h); +} +DUK_INTERNAL void duk_hstring_decref_norz(duk_hthread *thr, duk_hstring *h) { + DUK__DECREF_ASSERTS(); + DUK__DECREF_SHARED(); + duk_hstring_refzero_norz(thr, h); +} +DUK_INTERNAL void duk_hbuffer_decref(duk_hthread *thr, duk_hbuffer *h) { + DUK__DECREF_ASSERTS(); + DUK__DECREF_SHARED(); + duk_hbuffer_refzero(thr, h); +} +DUK_INTERNAL void duk_hbuffer_decref_norz(duk_hthread *thr, duk_hbuffer *h) { + DUK__DECREF_ASSERTS(); + DUK__DECREF_SHARED(); + duk_hbuffer_refzero_norz(thr, h); +} +DUK_INTERNAL void duk_hobject_decref(duk_hthread *thr, duk_hobject *h) { + DUK__DECREF_ASSERTS(); + DUK__DECREF_SHARED(); + duk_hobject_refzero(thr, h); +} +DUK_INTERNAL void duk_hobject_decref_norz(duk_hthread *thr, duk_hobject *h) { + DUK__DECREF_ASSERTS(); + DUK__DECREF_SHARED(); + duk_hobject_refzero_norz(thr, h); +} +#endif + +#else /* DUK_USE_REFERENCE_COUNTING */ + +/* no refcounting */ + +#endif /* DUK_USE_REFERENCE_COUNTING */ diff --git a/third_party/duktape/duk_heap_stringcache.c b/third_party/duktape/duk_heap_stringcache.c new file mode 100644 index 00000000..c17639c6 --- /dev/null +++ b/third_party/duktape/duk_heap_stringcache.c @@ -0,0 +1,309 @@ +/* + * String cache. + * + * Provides a cache to optimize indexed string lookups. The cache keeps + * track of (byte offset, char offset) states for a fixed number of strings. + * Otherwise we'd need to scan from either end of the string, as we store + * strings in (extended) UTF-8. + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Delete references to given hstring from the heap string cache. + * + * String cache references are 'weak': they are not counted towards + * reference counts, nor serve as roots for mark-and-sweep. When an + * object is about to be freed, such references need to be removed. + */ + +DUK_INTERNAL void duk_heap_strcache_string_remove(duk_heap *heap, duk_hstring *h) { + duk_uint_t i; + for (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) { + duk_strcache_entry *c = heap->strcache + i; + if (c->h == h) { + DUK_DD(DUK_DDPRINT("deleting weak strcache reference to hstring %p from heap %p", + (void *) h, (void *) heap)); + c->h = NULL; + + /* XXX: the string shouldn't appear twice, but we now loop to the + * end anyway; if fixed, add a looping assertion to ensure there + * is no duplicate. + */ + } + } +} + +/* + * String scanning helpers + * + * All bytes other than UTF-8 continuation bytes ([0x80,0xbf]) are + * considered to contribute a character. This must match how string + * character length is computed. + */ + +DUK_LOCAL const duk_uint8_t *duk__scan_forwards(const duk_uint8_t *p, const duk_uint8_t *q, duk_uint_fast32_t n) { + while (n > 0) { + for (;;) { + p++; + if (p >= q) { + return NULL; + } + if ((*p & 0xc0) != 0x80) { + break; + } + } + n--; + } + return p; +} + +DUK_LOCAL const duk_uint8_t *duk__scan_backwards(const duk_uint8_t *p, const duk_uint8_t *q, duk_uint_fast32_t n) { + while (n > 0) { + for (;;) { + p--; + if (p < q) { + return NULL; + } + if ((*p & 0xc0) != 0x80) { + break; + } + } + n--; + } + return p; +} + +/* + * Convert char offset to byte offset + * + * Avoid using the string cache if possible: for ASCII strings byte and + * char offsets are equal and for short strings direct scanning may be + * better than using the string cache (which may evict a more important + * entry). + * + * Typing now assumes 32-bit string byte/char offsets (duk_uint_fast32_t). + * Better typing might be to use duk_size_t. + * + * Caller should ensure 'char_offset' is within the string bounds [0,charlen] + * (endpoint is inclusive). If this is not the case, no memory unsafe + * behavior will happen but an error will be thrown. + */ + +DUK_INTERNAL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *thr, duk_hstring *h, duk_uint_fast32_t char_offset) { + duk_heap *heap; + duk_strcache_entry *sce; + duk_uint_fast32_t byte_offset; + duk_uint_t i; + duk_bool_t use_cache; + duk_uint_fast32_t dist_start, dist_end, dist_sce; + duk_uint_fast32_t char_length; + const duk_uint8_t *p_start; + const duk_uint8_t *p_end; + const duk_uint8_t *p_found; + + /* + * For ASCII strings, the answer is simple. + */ + + if (DUK_LIKELY(DUK_HSTRING_IS_ASCII(h))) { + return char_offset; + } + + char_length = (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h); + DUK_ASSERT(char_offset <= char_length); + + if (DUK_LIKELY(DUK_HSTRING_IS_ASCII(h))) { + /* Must recheck because the 'is ascii' flag may be set + * lazily. Alternatively, we could just compare charlen + * to bytelen. + */ + return char_offset; + } + + /* + * For non-ASCII strings, we need to scan forwards or backwards + * from some starting point. The starting point may be the start + * or end of the string, or some cached midpoint in the string + * cache. + * + * For "short" strings we simply scan without checking or updating + * the cache. For longer strings we check and update the cache as + * necessary, inserting a new cache entry if none exists. + */ + + DUK_DDD(DUK_DDDPRINT("non-ascii string %p, char_offset=%ld, clen=%ld, blen=%ld", + (void *) h, (long) char_offset, + (long) DUK_HSTRING_GET_CHARLEN(h), + (long) DUK_HSTRING_GET_BYTELEN(h))); + + heap = thr->heap; + sce = NULL; + use_cache = (char_length > DUK_HEAP_STRINGCACHE_NOCACHE_LIMIT); + + if (use_cache) { +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2) + DUK_DDD(DUK_DDDPRINT("stringcache before char2byte (using cache):")); + for (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) { + duk_strcache_entry *c = heap->strcache + i; + DUK_DDD(DUK_DDDPRINT(" [%ld] -> h=%p, cidx=%ld, bidx=%ld", + (long) i, (void *) c->h, (long) c->cidx, (long) c->bidx)); + } +#endif + + for (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) { + duk_strcache_entry *c = heap->strcache + i; + + if (c->h == h) { + sce = c; + break; + } + } + } + + /* + * Scan from shortest distance: + * - start of string + * - end of string + * - cache entry (if exists) + */ + + DUK_ASSERT(DUK_HSTRING_GET_CHARLEN(h) >= char_offset); + dist_start = char_offset; + dist_end = char_length - char_offset; + dist_sce = 0; DUK_UNREF(dist_sce); /* initialize for debug prints, needed if sce==NULL */ + + p_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h); + p_end = (const duk_uint8_t *) (p_start + DUK_HSTRING_GET_BYTELEN(h)); + p_found = NULL; + + if (sce) { + if (char_offset >= sce->cidx) { + dist_sce = char_offset - sce->cidx; + if ((dist_sce <= dist_start) && (dist_sce <= dist_end)) { + DUK_DDD(DUK_DDDPRINT("non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, " + "dist_start=%ld, dist_end=%ld, dist_sce=%ld => " + "scan forwards from sce", + (long) use_cache, (void *) (sce ? sce->h : NULL), + (sce ? (long) sce->cidx : (long) -1), + (sce ? (long) sce->bidx : (long) -1), + (long) dist_start, (long) dist_end, (long) dist_sce)); + + p_found = duk__scan_forwards(p_start + sce->bidx, + p_end, + dist_sce); + goto scan_done; + } + } else { + dist_sce = sce->cidx - char_offset; + if ((dist_sce <= dist_start) && (dist_sce <= dist_end)) { + DUK_DDD(DUK_DDDPRINT("non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, " + "dist_start=%ld, dist_end=%ld, dist_sce=%ld => " + "scan backwards from sce", + (long) use_cache, (void *) (sce ? sce->h : NULL), + (sce ? (long) sce->cidx : (long) -1), + (sce ? (long) sce->bidx : (long) -1), + (long) dist_start, (long) dist_end, (long) dist_sce)); + + p_found = duk__scan_backwards(p_start + sce->bidx, + p_start, + dist_sce); + goto scan_done; + } + } + } + + /* no sce, or sce scan not best */ + + if (dist_start <= dist_end) { + DUK_DDD(DUK_DDDPRINT("non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, " + "dist_start=%ld, dist_end=%ld, dist_sce=%ld => " + "scan forwards from string start", + (long) use_cache, (void *) (sce ? sce->h : NULL), + (sce ? (long) sce->cidx : (long) -1), + (sce ? (long) sce->bidx : (long) -1), + (long) dist_start, (long) dist_end, (long) dist_sce)); + + p_found = duk__scan_forwards(p_start, + p_end, + dist_start); + } else { + DUK_DDD(DUK_DDDPRINT("non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, " + "dist_start=%ld, dist_end=%ld, dist_sce=%ld => " + "scan backwards from string end", + (long) use_cache, (void *) (sce ? sce->h : NULL), + (sce ? (long) sce->cidx : (long) -1), + (sce ? (long) sce->bidx : (long) -1), + (long) dist_start, (long) dist_end, (long) dist_sce)); + + p_found = duk__scan_backwards(p_end, + p_start, + dist_end); + } + + scan_done: + + if (DUK_UNLIKELY(p_found == NULL)) { + /* Scan error: this shouldn't normally happen; it could happen if + * string is not valid UTF-8 data, and clen/blen are not consistent + * with the scanning algorithm. + */ + goto scan_error; + } + + DUK_ASSERT(p_found >= p_start); + DUK_ASSERT(p_found <= p_end); /* may be equal */ + byte_offset = (duk_uint32_t) (p_found - p_start); + + DUK_DDD(DUK_DDDPRINT("-> string %p, cidx %ld -> bidx %ld", + (void *) h, (long) char_offset, (long) byte_offset)); + + /* + * Update cache entry (allocating if necessary), and move the + * cache entry to the first place (in an "LRU" policy). + */ + + if (use_cache) { + /* update entry, allocating if necessary */ + if (!sce) { + sce = heap->strcache + DUK_HEAP_STRCACHE_SIZE - 1; /* take last entry */ + sce->h = h; + } + DUK_ASSERT(sce != NULL); + sce->bidx = (duk_uint32_t) (p_found - p_start); + sce->cidx = (duk_uint32_t) char_offset; + + /* LRU: move our entry to first */ + if (sce > &heap->strcache[0]) { + /* + * A C + * B A + * C <- sce ==> B + * D D + */ + duk_strcache_entry tmp; + + tmp = *sce; + duk_memmove((void *) (&heap->strcache[1]), + (const void *) (&heap->strcache[0]), + (size_t) (((char *) sce) - ((char *) &heap->strcache[0]))); + heap->strcache[0] = tmp; + + /* 'sce' points to the wrong entry here, but is no longer used */ + } +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2) + DUK_DDD(DUK_DDDPRINT("stringcache after char2byte (using cache):")); + for (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) { + duk_strcache_entry *c = heap->strcache + i; + DUK_DDD(DUK_DDDPRINT(" [%ld] -> h=%p, cidx=%ld, bidx=%ld", + (long) i, (void *) c->h, (long) c->cidx, (long) c->bidx)); + } +#endif + } + + return byte_offset; + + scan_error: + DUK_ERROR_INTERNAL(thr); + DUK_WO_NORETURN(return 0;); +} diff --git a/third_party/duktape/duk_heap_stringtable.c b/third_party/duktape/duk_heap_stringtable.c new file mode 100644 index 00000000..b8941e91 --- /dev/null +++ b/third_party/duktape/duk_heap_stringtable.c @@ -0,0 +1,1043 @@ +/* + * Heap string table handling, string interning. + */ + +#include "third_party/duktape/duk_internal.h" + +/* Resize checks not needed if minsize == maxsize, typical for low memory + * targets. + */ +#define DUK__STRTAB_RESIZE_CHECK +#if (DUK_USE_STRTAB_MINSIZE == DUK_USE_STRTAB_MAXSIZE) +#undef DUK__STRTAB_RESIZE_CHECK +#endif + +#if defined(DUK_USE_STRTAB_PTRCOMP) +#define DUK__HEAPPTR_ENC16(heap,ptr) DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (ptr)) +#define DUK__HEAPPTR_DEC16(heap,val) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (val)) +#define DUK__GET_STRTABLE(heap) ((heap)->strtable16) +#else +#define DUK__HEAPPTR_ENC16(heap,ptr) (ptr) +#define DUK__HEAPPTR_DEC16(heap,val) (val) +#define DUK__GET_STRTABLE(heap) ((heap)->strtable) +#endif + +#define DUK__STRTAB_U32_MAX_STRLEN 10 /* 4'294'967'295 */ + +/* + * Debug dump stringtable. + */ + +#if defined(DUK_USE_DEBUG) +DUK_INTERNAL void duk_heap_strtable_dump(duk_heap *heap) { +#if defined(DUK_USE_STRTAB_PTRCOMP) + duk_uint16_t *strtable; +#else + duk_hstring **strtable; +#endif + duk_uint32_t i; + duk_hstring *h; + duk_size_t count_total = 0; + duk_size_t count_chain; + duk_size_t count_chain_min = DUK_SIZE_MAX; + duk_size_t count_chain_max = 0; + duk_size_t count_len[8]; /* chain lengths from 0 to 7 */ + + if (heap == NULL) { + DUK_D(DUK_DPRINT("string table, heap=NULL")); + return; + } + + strtable = DUK__GET_STRTABLE(heap); + if (strtable == NULL) { + DUK_D(DUK_DPRINT("string table, strtab=NULL")); + return; + } + + duk_memzero((void *) count_len, sizeof(count_len)); + for (i = 0; i < heap->st_size; i++) { + h = DUK__HEAPPTR_DEC16(heap, strtable[i]); + count_chain = 0; + while (h != NULL) { + count_chain++; + h = h->hdr.h_next; + } + if (count_chain < sizeof(count_len) / sizeof(duk_size_t)) { + count_len[count_chain]++; + } + count_chain_max = (count_chain > count_chain_max ? count_chain : count_chain_max); + count_chain_min = (count_chain < count_chain_min ? count_chain : count_chain_min); + count_total += count_chain; + } + + DUK_D(DUK_DPRINT("string table, strtab=%p, count=%lu, chain min=%lu max=%lu avg=%lf: " + "counts: %lu %lu %lu %lu %lu %lu %lu %lu ...", + (void *) heap->strtable, (unsigned long) count_total, + (unsigned long) count_chain_min, (unsigned long) count_chain_max, + (double) count_total / (double) heap->st_size, + (unsigned long) count_len[0], (unsigned long) count_len[1], + (unsigned long) count_len[2], (unsigned long) count_len[3], + (unsigned long) count_len[4], (unsigned long) count_len[5], + (unsigned long) count_len[6], (unsigned long) count_len[7])); +} +#endif /* DUK_USE_DEBUG */ + +/* + * Assertion helper to ensure strtable is populated correctly. + */ + +#if defined(DUK_USE_ASSERTIONS) +DUK_LOCAL void duk__strtable_assert_checks(duk_heap *heap) { +#if defined(DUK_USE_STRTAB_PTRCOMP) + duk_uint16_t *strtable; +#else + duk_hstring **strtable; +#endif + duk_uint32_t i; + duk_hstring *h; + duk_size_t count = 0; + + DUK_ASSERT(heap != NULL); + + strtable = DUK__GET_STRTABLE(heap); + if (strtable != NULL) { + DUK_ASSERT(heap->st_size != 0); + DUK_ASSERT(heap->st_mask == heap->st_size - 1); + + for (i = 0; i < heap->st_size; i++) { + h = DUK__HEAPPTR_DEC16(heap, strtable[i]); + while (h != NULL) { + DUK_ASSERT((DUK_HSTRING_GET_HASH(h) & heap->st_mask) == i); + count++; + h = h->hdr.h_next; + } + } + } else { + DUK_ASSERT(heap->st_size == 0); + DUK_ASSERT(heap->st_mask == 0); + } + +#if defined(DUK__STRTAB_RESIZE_CHECK) + DUK_ASSERT(count == (duk_size_t) heap->st_count); +#endif +} +#endif /* DUK_USE_ASSERTIONS */ + +/* + * Allocate and initialize a duk_hstring. + * + * Returns a NULL if allocation or initialization fails for some reason. + * + * The string won't be inserted into the string table and isn't tracked in + * any way (link pointers will be NULL). The caller must place the string + * into the string table without any risk of a longjmp, otherwise the string + * is leaked. + */ + +DUK_LOCAL duk_hstring *duk__strtable_alloc_hstring(duk_heap *heap, + const duk_uint8_t *str, + duk_uint32_t blen, + duk_uint32_t strhash, + const duk_uint8_t *extdata) { + duk_hstring *res; + const duk_uint8_t *data; +#if !defined(DUK_USE_HSTRING_ARRIDX) + duk_uarridx_t dummy; +#endif + + DUK_ASSERT(heap != NULL); + DUK_UNREF(extdata); + +#if defined(DUK_USE_STRLEN16) + /* If blen <= 0xffffUL, clen is also guaranteed to be <= 0xffffUL. */ + if (blen > 0xffffUL) { + DUK_D(DUK_DPRINT("16-bit string blen/clen active and blen over 16 bits, reject intern")); + goto alloc_error; + } +#endif + + /* XXX: Memzeroing the allocated structure is not really necessary + * because we could just initialize all fields explicitly (almost + * all fields are initialized explicitly anyway). + */ +#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_INTERN_CHECK) + if (extdata) { + res = (duk_hstring *) DUK_ALLOC(heap, sizeof(duk_hstring_external)); + if (DUK_UNLIKELY(res == NULL)) { + goto alloc_error; + } + duk_memzero(res, sizeof(duk_hstring_external)); +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + DUK_HEAPHDR_STRING_INIT_NULLS(&res->hdr); +#endif + DUK_HEAPHDR_SET_TYPE_AND_FLAGS(&res->hdr, DUK_HTYPE_STRING, DUK_HSTRING_FLAG_EXTDATA); + + DUK_ASSERT(extdata[blen] == 0); /* Application responsibility. */ + data = extdata; + ((duk_hstring_external *) res)->extdata = extdata; + } else +#endif /* DUK_USE_HSTRING_EXTDATA && DUK_USE_EXTSTR_INTERN_CHECK */ + { + duk_uint8_t *data_tmp; + + /* NUL terminate for convenient C access */ + DUK_ASSERT(sizeof(duk_hstring) + blen + 1 > blen); /* No wrap, limits ensure. */ + res = (duk_hstring *) DUK_ALLOC(heap, sizeof(duk_hstring) + blen + 1); + if (DUK_UNLIKELY(res == NULL)) { + goto alloc_error; + } + duk_memzero(res, sizeof(duk_hstring)); +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + DUK_HEAPHDR_STRING_INIT_NULLS(&res->hdr); +#endif + DUK_HEAPHDR_SET_TYPE_AND_FLAGS(&res->hdr, DUK_HTYPE_STRING, 0); + + data_tmp = (duk_uint8_t *) (res + 1); + duk_memcpy(data_tmp, str, blen); + data_tmp[blen] = (duk_uint8_t) 0; + data = (const duk_uint8_t *) data_tmp; + } + + DUK_HSTRING_SET_BYTELEN(res, blen); + DUK_HSTRING_SET_HASH(res, strhash); + + DUK_ASSERT(!DUK_HSTRING_HAS_ARRIDX(res)); +#if defined(DUK_USE_HSTRING_ARRIDX) + res->arridx = duk_js_to_arrayindex_string(data, blen); + if (res->arridx != DUK_HSTRING_NO_ARRAY_INDEX) { +#else + dummy = duk_js_to_arrayindex_string(data, blen); + if (dummy != DUK_HSTRING_NO_ARRAY_INDEX) { +#endif + /* Array index strings cannot be symbol strings, + * and they're always pure ASCII so blen == clen. + */ + DUK_HSTRING_SET_ARRIDX(res); + DUK_HSTRING_SET_ASCII(res); + DUK_ASSERT(duk_unicode_unvalidated_utf8_length(data, (duk_size_t) blen) == blen); + } else { + /* Because 'data' is NUL-terminated, we don't need a + * blen > 0 check here. For NUL (0x00) the symbol + * checks will be false. + */ + if (DUK_UNLIKELY(data[0] >= 0x80U)) { + if (data[0] <= 0x81) { + DUK_HSTRING_SET_SYMBOL(res); + } else if (data[0] == 0x82U || data[0] == 0xffU) { + DUK_HSTRING_SET_HIDDEN(res); + DUK_HSTRING_SET_SYMBOL(res); + } + } + + /* Using an explicit 'ASCII' flag has larger footprint (one call site + * only) but is quite useful for the case when there's no explicit + * 'clen' in duk_hstring. + * + * The flag is set lazily for RAM strings. + */ + DUK_ASSERT(!DUK_HSTRING_HAS_ASCII(res)); + +#if defined(DUK_USE_HSTRING_LAZY_CLEN) + /* Charlen initialized to 0, updated on-the-fly. */ +#else + duk_hstring_init_charlen(res); /* Also sets ASCII flag. */ +#endif + } + + DUK_DDD(DUK_DDDPRINT("interned string, hash=0x%08lx, blen=%ld, has_arridx=%ld, has_extdata=%ld", + (unsigned long) DUK_HSTRING_GET_HASH(res), + (long) DUK_HSTRING_GET_BYTELEN(res), + (long) (DUK_HSTRING_HAS_ARRIDX(res) ? 1 : 0), + (long) (DUK_HSTRING_HAS_EXTDATA(res) ? 1 : 0))); + + DUK_ASSERT(res != NULL); + return res; + + alloc_error: + return NULL; +} + +/* + * Grow strtable allocation in-place. + */ + +#if defined(DUK__STRTAB_RESIZE_CHECK) +DUK_LOCAL void duk__strtable_grow_inplace(duk_heap *heap) { + duk_uint32_t new_st_size; + duk_uint32_t old_st_size; + duk_uint32_t i; + duk_hstring *h; + duk_hstring *next; + duk_hstring *prev; +#if defined(DUK_USE_STRTAB_PTRCOMP) + duk_uint16_t *new_ptr; + duk_uint16_t *new_ptr_high; +#else + duk_hstring **new_ptr; + duk_hstring **new_ptr_high; +#endif + + DUK_DD(DUK_DDPRINT("grow in-place: %lu -> %lu", (unsigned long) heap->st_size, (unsigned long) heap->st_size * 2)); + + DUK_ASSERT(heap != NULL); + DUK_ASSERT(heap->st_resizing == 1); + DUK_ASSERT(heap->st_size >= 2); + DUK_ASSERT((heap->st_size & (heap->st_size - 1)) == 0); /* 2^N */ + DUK_ASSERT(DUK__GET_STRTABLE(heap) != NULL); + + DUK_STATS_INC(heap, stats_strtab_resize_grow); + + new_st_size = heap->st_size << 1U; + DUK_ASSERT(new_st_size > heap->st_size); /* No overflow. */ + + /* Reallocate the strtable first and then work in-place to rehash + * strings. We don't need an indirect allocation here: even if GC + * is triggered to satisfy the allocation, recursive strtable resize + * is prevented by flags. This is also why we don't need to use + * DUK_REALLOC_INDIRECT(). + */ + +#if defined(DUK_USE_STRTAB_PTRCOMP) + new_ptr = (duk_uint16_t *) DUK_REALLOC(heap, heap->strtable16, sizeof(duk_uint16_t) * new_st_size); +#else + new_ptr = (duk_hstring **) DUK_REALLOC(heap, heap->strtable, sizeof(duk_hstring *) * new_st_size); +#endif + if (DUK_UNLIKELY(new_ptr == NULL)) { + /* If realloc fails we can continue normally: the string table + * won't "fill up" although chains will gradually get longer. + * When string insertions continue, we'll quite soon try again + * with no special handling. + */ + DUK_D(DUK_DPRINT("string table grow failed, ignoring")); + return; + } +#if defined(DUK_USE_STRTAB_PTRCOMP) + heap->strtable16 = new_ptr; +#else + heap->strtable = new_ptr; +#endif + + /* Rehash a single bucket into two separate ones. When we grow + * by x2 the highest 'new' bit determines whether a string remains + * in its old position (bit is 0) or goes to a new one (bit is 1). + */ + + old_st_size = heap->st_size; + new_ptr_high = new_ptr + old_st_size; + for (i = 0; i < old_st_size; i++) { + duk_hstring *new_root; + duk_hstring *new_root_high; + + h = DUK__HEAPPTR_DEC16(heap, new_ptr[i]); + new_root = h; + new_root_high = NULL; + + prev = NULL; + while (h != NULL) { + duk_uint32_t mask; + + DUK_ASSERT((DUK_HSTRING_GET_HASH(h) & heap->st_mask) == i); + next = h->hdr.h_next; + + /* Example: if previous size was 256, previous mask is 0xFF + * and size is 0x100 which corresponds to the new bit that + * comes into play. + */ + DUK_ASSERT(heap->st_mask == old_st_size - 1); + mask = old_st_size; + if (DUK_HSTRING_GET_HASH(h) & mask) { + if (prev != NULL) { + prev->hdr.h_next = h->hdr.h_next; + } else { + DUK_ASSERT(h == new_root); + new_root = h->hdr.h_next; + } + + h->hdr.h_next = new_root_high; + new_root_high = h; + } else { + prev = h; + } + h = next; + } + + new_ptr[i] = DUK__HEAPPTR_ENC16(heap, new_root); + new_ptr_high[i] = DUK__HEAPPTR_ENC16(heap, new_root_high); + } + + heap->st_size = new_st_size; + heap->st_mask = new_st_size - 1; + +#if defined(DUK_USE_ASSERTIONS) + duk__strtable_assert_checks(heap); +#endif +} +#endif /* DUK__STRTAB_RESIZE_CHECK */ + +/* + * Shrink strtable allocation in-place. + */ + +#if defined(DUK__STRTAB_RESIZE_CHECK) +DUK_LOCAL void duk__strtable_shrink_inplace(duk_heap *heap) { + duk_uint32_t new_st_size; + duk_uint32_t i; + duk_hstring *h; + duk_hstring *other; + duk_hstring *root; +#if defined(DUK_USE_STRTAB_PTRCOMP) + duk_uint16_t *old_ptr; + duk_uint16_t *old_ptr_high; + duk_uint16_t *new_ptr; +#else + duk_hstring **old_ptr; + duk_hstring **old_ptr_high; + duk_hstring **new_ptr; +#endif + + DUK_DD(DUK_DDPRINT("shrink in-place: %lu -> %lu", (unsigned long) heap->st_size, (unsigned long) heap->st_size / 2)); + + DUK_ASSERT(heap != NULL); + DUK_ASSERT(heap->st_resizing == 1); + DUK_ASSERT(heap->st_size >= 2); + DUK_ASSERT((heap->st_size & (heap->st_size - 1)) == 0); /* 2^N */ + DUK_ASSERT(DUK__GET_STRTABLE(heap) != NULL); + + DUK_STATS_INC(heap, stats_strtab_resize_shrink); + + new_st_size = heap->st_size >> 1U; + + /* Combine two buckets into a single one. When we shrink, one hash + * bit (highest) disappears. + */ + old_ptr = DUK__GET_STRTABLE(heap); + old_ptr_high = old_ptr + new_st_size; + for (i = 0; i < new_st_size; i++) { + h = DUK__HEAPPTR_DEC16(heap, old_ptr[i]); + other = DUK__HEAPPTR_DEC16(heap, old_ptr_high[i]); + + if (h == NULL) { + /* First chain is empty, so use second one as is. */ + root = other; + } else { + /* Find end of first chain, and link in the second. */ + root = h; + while (h->hdr.h_next != NULL) { + h = h->hdr.h_next; + } + h->hdr.h_next = other; + } + + old_ptr[i] = DUK__HEAPPTR_ENC16(heap, root); + } + + heap->st_size = new_st_size; + heap->st_mask = new_st_size - 1; + + /* The strtable is now consistent and we can realloc safely. Even + * if side effects cause string interning or removal the strtable + * updates are safe. Recursive resize has been prevented by caller. + * This is also why we don't need to use DUK_REALLOC_INDIRECT(). + * + * We assume a realloc() to a smaller size is guaranteed to succeed. + * It would be relatively straightforward to handle the error by + * essentially performing a "grow" step to recover. + */ + +#if defined(DUK_USE_STRTAB_PTRCOMP) + new_ptr = (duk_uint16_t *) DUK_REALLOC(heap, heap->strtable16, sizeof(duk_uint16_t) * new_st_size); + DUK_ASSERT(new_ptr != NULL); + heap->strtable16 = new_ptr; +#else + new_ptr = (duk_hstring **) DUK_REALLOC(heap, heap->strtable, sizeof(duk_hstring *) * new_st_size); + DUK_ASSERT(new_ptr != NULL); + heap->strtable = new_ptr; +#endif + +#if defined(DUK_USE_ASSERTIONS) + duk__strtable_assert_checks(heap); +#endif +} +#endif /* DUK__STRTAB_RESIZE_CHECK */ + +/* + * Grow/shrink check. + */ + +#if defined(DUK__STRTAB_RESIZE_CHECK) +DUK_LOCAL DUK_COLD DUK_NOINLINE void duk__strtable_resize_check(duk_heap *heap) { + duk_uint32_t load_factor; /* fixed point */ + + DUK_ASSERT(heap != NULL); +#if defined(DUK_USE_STRTAB_PTRCOMP) + DUK_ASSERT(heap->strtable16 != NULL); +#else + DUK_ASSERT(heap->strtable != NULL); +#endif + + DUK_STATS_INC(heap, stats_strtab_resize_check); + + /* Prevent recursive resizing. */ + if (DUK_UNLIKELY(heap->st_resizing != 0U)) { + DUK_D(DUK_DPRINT("prevent recursive strtable resize")); + return; + } + + heap->st_resizing = 1; + + DUK_ASSERT(heap->st_size >= 16U); + DUK_ASSERT((heap->st_size >> 4U) >= 1); + load_factor = heap->st_count / (heap->st_size >> 4U); + + DUK_DD(DUK_DDPRINT("resize check string table: size=%lu, count=%lu, load_factor=%lu (fixed point .4; float %lf)", + (unsigned long) heap->st_size, (unsigned long) heap->st_count, + (unsigned long) load_factor, + (double) heap->st_count / (double) heap->st_size)); + + if (load_factor >= DUK_USE_STRTAB_GROW_LIMIT) { + if (heap->st_size >= DUK_USE_STRTAB_MAXSIZE) { + DUK_DD(DUK_DDPRINT("want to grow strtable (based on load factor) but already maximum size")); + } else { + DUK_D(DUK_DPRINT("grow string table: %lu -> %lu", (unsigned long) heap->st_size, (unsigned long) heap->st_size * 2)); +#if defined(DUK_USE_DEBUG) + duk_heap_strtable_dump(heap); +#endif + duk__strtable_grow_inplace(heap); + } + } else if (load_factor <= DUK_USE_STRTAB_SHRINK_LIMIT) { + if (heap->st_size <= DUK_USE_STRTAB_MINSIZE) { + DUK_DD(DUK_DDPRINT("want to shrink strtable (based on load factor) but already minimum size")); + } else { + DUK_D(DUK_DPRINT("shrink string table: %lu -> %lu", (unsigned long) heap->st_size, (unsigned long) heap->st_size / 2)); +#if defined(DUK_USE_DEBUG) + duk_heap_strtable_dump(heap); +#endif + duk__strtable_shrink_inplace(heap); + } + } else { + DUK_DD(DUK_DDPRINT("no need for strtable resize")); + } + + heap->st_resizing = 0; +} +#endif /* DUK__STRTAB_RESIZE_CHECK */ + +/* + * Torture grow/shrink: unconditionally grow and shrink back. + */ + +#if defined(DUK_USE_STRTAB_TORTURE) && defined(DUK__STRTAB_RESIZE_CHECK) +DUK_LOCAL void duk__strtable_resize_torture(duk_heap *heap) { + duk_uint32_t old_st_size; + + DUK_ASSERT(heap != NULL); + + old_st_size = heap->st_size; + if (old_st_size >= DUK_USE_STRTAB_MAXSIZE) { + return; + } + + heap->st_resizing = 1; + duk__strtable_grow_inplace(heap); + if (heap->st_size > old_st_size) { + duk__strtable_shrink_inplace(heap); + } + heap->st_resizing = 0; +} +#endif /* DUK_USE_STRTAB_TORTURE && DUK__STRTAB_RESIZE_CHECK */ + +/* + * Raw intern; string already checked not to be present. + */ + +DUK_LOCAL duk_hstring *duk__strtable_do_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen, duk_uint32_t strhash) { + duk_hstring *res; + const duk_uint8_t *extdata; +#if defined(DUK_USE_STRTAB_PTRCOMP) + duk_uint16_t *slot; +#else + duk_hstring **slot; +#endif + + DUK_DDD(DUK_DDDPRINT("do_intern: heap=%p, str=%p, blen=%lu, strhash=%lx, st_size=%lu, st_count=%lu, load=%lf", + (void *) heap, (const void *) str, (unsigned long) blen, (unsigned long) strhash, + (unsigned long) heap->st_size, (unsigned long) heap->st_count, + (double) heap->st_count / (double) heap->st_size)); + + DUK_ASSERT(heap != NULL); + + /* Prevent any side effects on the string table and the caller provided + * str/blen arguments while interning is in progress. For example, if + * the caller provided str/blen from a dynamic buffer, a finalizer + * might resize or modify that dynamic buffer, invalidating the call + * arguments. + * + * While finalizers must be prevented, mark-and-sweep itself is fine. + * Recursive string table resize is prevented explicitly here. + */ + + heap->pf_prevent_count++; + DUK_ASSERT(heap->pf_prevent_count != 0); /* Wrap. */ + +#if defined(DUK_USE_STRTAB_TORTURE) && defined(DUK__STRTAB_RESIZE_CHECK) + duk__strtable_resize_torture(heap); +#endif + + /* String table grow/shrink check. Because of chaining (and no + * accumulation issues as with hash probe chains and DELETED + * markers) there's never a mandatory need to resize right now. + * Check for the resize only periodically, based on st_count + * bit pattern. Because string table removal doesn't do a shrink + * check, we do that also here. + * + * Do the resize and possible grow/shrink before the new duk_hstring + * has been allocated. Otherwise we may trigger a GC when the result + * duk_hstring is not yet strongly referenced. + */ + +#if defined(DUK__STRTAB_RESIZE_CHECK) + if (DUK_UNLIKELY((heap->st_count & DUK_USE_STRTAB_RESIZE_CHECK_MASK) == 0)) { + duk__strtable_resize_check(heap); + } +#endif + + /* External string check (low memory optimization). */ + +#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_INTERN_CHECK) + extdata = (const duk_uint8_t *) DUK_USE_EXTSTR_INTERN_CHECK(heap->heap_udata, (void *) DUK_LOSE_CONST(str), (duk_size_t) blen); +#else + extdata = (const duk_uint8_t *) NULL; +#endif + + /* Allocate and initialize string, not yet linked. This may cause a + * GC which may cause other strings to be interned and inserted into + * the string table before we insert our string. Finalizer execution + * is disabled intentionally to avoid a finalizer from e.g. resizing + * a buffer used as a data area for 'str'. + */ + + res = duk__strtable_alloc_hstring(heap, str, blen, strhash, extdata); + + /* Allow side effects again: GC must be avoided until duk_hstring + * result (if successful) has been INCREF'd. + */ + DUK_ASSERT(heap->pf_prevent_count > 0); + heap->pf_prevent_count--; + + /* Alloc error handling. */ + + if (DUK_UNLIKELY(res == NULL)) { +#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_INTERN_CHECK) + if (extdata != NULL) { + DUK_USE_EXTSTR_FREE(heap->heap_udata, (const void *) extdata); + } +#endif + return NULL; + } + + /* Insert into string table. */ + +#if defined(DUK_USE_STRTAB_PTRCOMP) + slot = heap->strtable16 + (strhash & heap->st_mask); +#else + slot = heap->strtable + (strhash & heap->st_mask); +#endif + DUK_ASSERT(res->hdr.h_next == NULL); /* This is the case now, but unnecessary zeroing/NULLing. */ + res->hdr.h_next = DUK__HEAPPTR_DEC16(heap, *slot); + *slot = DUK__HEAPPTR_ENC16(heap, res); + + /* Update string count only for successful inserts. */ + +#if defined(DUK__STRTAB_RESIZE_CHECK) + heap->st_count++; +#endif + + /* The duk_hstring is in the string table but is not yet strongly + * reachable. Calling code MUST NOT make any allocations or other + * side effects before the duk_hstring has been INCREF'd and made + * reachable. + */ + + return res; +} + +/* + * Intern a string from str/blen, returning either an existing duk_hstring + * or adding a new one into the string table. The input string does -not- + * need to be NUL terminated. + * + * The input 'str' argument may point to a Duktape managed data area such as + * the data area of a dynamic buffer. It's crucial to avoid any side effects + * that might affect the data area (e.g. resize the dynamic buffer, or write + * to the buffer) before the string is fully interned. + */ + +#if defined(DUK_USE_ROM_STRINGS) +DUK_LOCAL duk_hstring *duk__strtab_romstring_lookup(duk_heap *heap, const duk_uint8_t *str, duk_size_t blen, duk_uint32_t strhash) { + duk_size_t lookup_hash; + duk_hstring *curr; + + DUK_ASSERT(heap != NULL); + DUK_UNREF(heap); + + lookup_hash = (blen << 4); + if (blen > 0) { + lookup_hash += str[0]; + } + lookup_hash &= 0xff; + + curr = (duk_hstring *) DUK_LOSE_CONST(duk_rom_strings_lookup[lookup_hash]); + while (curr != NULL) { + /* Unsafe memcmp() because for zero blen, str may be NULL. */ + if (strhash == DUK_HSTRING_GET_HASH(curr) && + blen == DUK_HSTRING_GET_BYTELEN(curr) && + duk_memcmp_unsafe((const void *) str, (const void *) DUK_HSTRING_GET_DATA(curr), blen) == 0) { + DUK_DDD(DUK_DDDPRINT("intern check: rom string: %!O, computed hash 0x%08lx, rom hash 0x%08lx", + curr, (unsigned long) strhash, (unsigned long) DUK_HSTRING_GET_HASH(curr))); + return curr; + } + curr = curr->hdr.h_next; + } + + return NULL; +} +#endif /* DUK_USE_ROM_STRINGS */ + +DUK_INTERNAL duk_hstring *duk_heap_strtable_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen) { + duk_uint32_t strhash; + duk_hstring *h; + + DUK_DDD(DUK_DDDPRINT("intern check: heap=%p, str=%p, blen=%lu", (void *) heap, (const void *) str, (unsigned long) blen)); + + /* Preliminaries. */ + + /* XXX: maybe just require 'str != NULL' even for zero size? */ + DUK_ASSERT(heap != NULL); + DUK_ASSERT(blen == 0 || str != NULL); + DUK_ASSERT(blen <= DUK_HSTRING_MAX_BYTELEN); /* Caller is responsible for ensuring this. */ + strhash = duk_heap_hashstring(heap, str, (duk_size_t) blen); + + /* String table lookup. */ + + DUK_ASSERT(DUK__GET_STRTABLE(heap) != NULL); + DUK_ASSERT(heap->st_size > 0); + DUK_ASSERT(heap->st_size == heap->st_mask + 1); +#if defined(DUK_USE_STRTAB_PTRCOMP) + h = DUK__HEAPPTR_DEC16(heap, heap->strtable16[strhash & heap->st_mask]); +#else + h = heap->strtable[strhash & heap->st_mask]; +#endif + while (h != NULL) { + if (DUK_HSTRING_GET_HASH(h) == strhash && + DUK_HSTRING_GET_BYTELEN(h) == blen && + duk_memcmp_unsafe((const void *) str, (const void *) DUK_HSTRING_GET_DATA(h), (size_t) blen) == 0) { + /* Found existing entry. */ + DUK_STATS_INC(heap, stats_strtab_intern_hit); + return h; + } + h = h->hdr.h_next; + } + + /* ROM table lookup. Because this lookup is slower, do it only after + * RAM lookup. This works because no ROM string is ever interned into + * the RAM string table. + */ + +#if defined(DUK_USE_ROM_STRINGS) + h = duk__strtab_romstring_lookup(heap, str, blen, strhash); + if (h != NULL) { + DUK_STATS_INC(heap, stats_strtab_intern_hit); + return h; + } +#endif + + /* Not found in string table; insert. */ + + DUK_STATS_INC(heap, stats_strtab_intern_miss); + h = duk__strtable_do_intern(heap, str, blen, strhash); + return h; /* may be NULL */ +} + +/* + * Intern a string from u32. + */ + +/* XXX: Could arrange some special handling because we know that the result + * will have an arridx flag and an ASCII flag, won't need a clen check, etc. + */ + +DUK_INTERNAL duk_hstring *duk_heap_strtable_intern_u32(duk_heap *heap, duk_uint32_t val) { + duk_uint8_t buf[DUK__STRTAB_U32_MAX_STRLEN]; + duk_uint8_t *p; + + DUK_ASSERT(heap != NULL); + + /* This is smaller and faster than a %lu sprintf. */ + p = buf + sizeof(buf); + do { + p--; + *p = duk_lc_digits[val % 10]; + val = val / 10; + } while (val != 0); /* For val == 0, emit exactly one '0'. */ + DUK_ASSERT(p >= buf); + + return duk_heap_strtable_intern(heap, (const duk_uint8_t *) p, (duk_uint32_t) ((buf + sizeof(buf)) - p)); +} + +/* + * Checked convenience variants. + * + * XXX: Because the main use case is for the checked variants, make them the + * main functionality and provide a safe variant separately (it is only needed + * during heap init). The problem with that is that longjmp state and error + * creation must already be possible to throw. + */ + +DUK_INTERNAL duk_hstring *duk_heap_strtable_intern_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t blen) { + duk_hstring *res; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(blen == 0 || str != NULL); + + res = duk_heap_strtable_intern(thr->heap, str, blen); + if (DUK_UNLIKELY(res == NULL)) { + DUK_ERROR_ALLOC_FAILED(thr); + DUK_WO_NORETURN(return NULL;); + } + return res; +} + +#if defined(DUK_USE_LITCACHE_SIZE) +DUK_LOCAL duk_uint_t duk__strtable_litcache_key(const duk_uint8_t *str, duk_uint32_t blen) { + duk_uintptr_t key; + + DUK_ASSERT(DUK_USE_LITCACHE_SIZE > 0); + DUK_ASSERT(DUK_IS_POWER_OF_TWO((duk_uint_t) DUK_USE_LITCACHE_SIZE)); + + key = (duk_uintptr_t) blen ^ (duk_uintptr_t) str; + key &= (duk_uintptr_t) (DUK_USE_LITCACHE_SIZE - 1); /* Assumes size is power of 2. */ + /* Due to masking, cast is in 32-bit range. */ + DUK_ASSERT(key <= DUK_UINT_MAX); + return (duk_uint_t) key; +} + +DUK_INTERNAL duk_hstring *duk_heap_strtable_intern_literal_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t blen) { + duk_uint_t key; + duk_litcache_entry *ent; + duk_hstring *h; + + /* Fast path check: literal exists in literal cache. */ + key = duk__strtable_litcache_key(str, blen); + ent = thr->heap->litcache + key; + if (ent->addr == str) { + DUK_DD(DUK_DDPRINT("intern check for cached, pinned literal: str=%p, blen=%ld -> duk_hstring %!O", + (const void *) str, (long) blen, (duk_heaphdr *) ent->h)); + DUK_ASSERT(ent->h != NULL); + DUK_ASSERT(DUK_HSTRING_HAS_PINNED_LITERAL(ent->h)); + DUK_STATS_INC(thr->heap, stats_strtab_litcache_hit); + return ent->h; + } + + /* Intern and update (overwrite) cache entry. */ + h = duk_heap_strtable_intern_checked(thr, str, blen); + ent->addr = str; + ent->h = h; + DUK_STATS_INC(thr->heap, stats_strtab_litcache_miss); + + /* Pin the duk_hstring until the next mark-and-sweep. This means + * litcache entries don't need to be invalidated until the next + * mark-and-sweep as their target duk_hstring is not freed before + * the mark-and-sweep happens. The pin remains even if the literal + * cache entry is overwritten, and is still useful to avoid string + * table traffic. + */ + if (!DUK_HSTRING_HAS_PINNED_LITERAL(h)) { + DUK_DD(DUK_DDPRINT("pin duk_hstring because it is a literal: %!O", (duk_heaphdr *) h)); + DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)); + DUK_HSTRING_INCREF(thr, h); + DUK_HSTRING_SET_PINNED_LITERAL(h); + DUK_STATS_INC(thr->heap, stats_strtab_litcache_pin); + } + + return h; +} +#endif /* DUK_USE_LITCACHE_SIZE */ + +DUK_INTERNAL duk_hstring *duk_heap_strtable_intern_u32_checked(duk_hthread *thr, duk_uint32_t val) { + duk_hstring *res; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + + res = duk_heap_strtable_intern_u32(thr->heap, val); + if (DUK_UNLIKELY(res == NULL)) { + DUK_ERROR_ALLOC_FAILED(thr); + DUK_WO_NORETURN(return NULL;); + } + return res; +} + +/* + * Remove (unlink) a string from the string table. + * + * Just unlinks the duk_hstring, leaving link pointers as garbage. + * Caller must free the string itself. + */ + +#if defined(DUK_USE_REFERENCE_COUNTING) +/* Unlink without a 'prev' pointer. */ +DUK_INTERNAL void duk_heap_strtable_unlink(duk_heap *heap, duk_hstring *h) { +#if defined(DUK_USE_STRTAB_PTRCOMP) + duk_uint16_t *slot; +#else + duk_hstring **slot; +#endif + duk_hstring *other; + duk_hstring *prev; + + DUK_DDD(DUK_DDDPRINT("remove: heap=%p, h=%p, blen=%lu, strhash=%lx", + (void *) heap, (void *) h, + (unsigned long) (h != NULL ? DUK_HSTRING_GET_BYTELEN(h) : 0), + (unsigned long) (h != NULL ? DUK_HSTRING_GET_HASH(h) : 0))); + + DUK_ASSERT(heap != NULL); + DUK_ASSERT(h != NULL); + +#if defined(DUK__STRTAB_RESIZE_CHECK) + DUK_ASSERT(heap->st_count > 0); + heap->st_count--; +#endif + +#if defined(DUK_USE_STRTAB_PTRCOMP) + slot = heap->strtable16 + (DUK_HSTRING_GET_HASH(h) & heap->st_mask); +#else + slot = heap->strtable + (DUK_HSTRING_GET_HASH(h) & heap->st_mask); +#endif + other = DUK__HEAPPTR_DEC16(heap, *slot); + DUK_ASSERT(other != NULL); /* At least argument string is in the chain. */ + + prev = NULL; + while (other != h) { + prev = other; + other = other->hdr.h_next; + DUK_ASSERT(other != NULL); /* We'll eventually find 'h'. */ + } + if (prev != NULL) { + /* Middle of list. */ + prev->hdr.h_next = h->hdr.h_next; + } else { + /* Head of list. */ + *slot = DUK__HEAPPTR_ENC16(heap, h->hdr.h_next); + } + + /* There's no resize check on a string free. The next string + * intern will do one. + */ +} +#endif /* DUK_USE_REFERENCE_COUNTING */ + +/* Unlink with a 'prev' pointer. */ +DUK_INTERNAL void duk_heap_strtable_unlink_prev(duk_heap *heap, duk_hstring *h, duk_hstring *prev) { +#if defined(DUK_USE_STRTAB_PTRCOMP) + duk_uint16_t *slot; +#else + duk_hstring **slot; +#endif + + DUK_DDD(DUK_DDDPRINT("remove: heap=%p, prev=%p, h=%p, blen=%lu, strhash=%lx", + (void *) heap, (void *) prev, (void *) h, + (unsigned long) (h != NULL ? DUK_HSTRING_GET_BYTELEN(h) : 0), + (unsigned long) (h != NULL ? DUK_HSTRING_GET_HASH(h) : 0))); + + DUK_ASSERT(heap != NULL); + DUK_ASSERT(h != NULL); + DUK_ASSERT(prev == NULL || prev->hdr.h_next == h); + +#if defined(DUK__STRTAB_RESIZE_CHECK) + DUK_ASSERT(heap->st_count > 0); + heap->st_count--; +#endif + + if (prev != NULL) { + /* Middle of list. */ + prev->hdr.h_next = h->hdr.h_next; + } else { + /* Head of list. */ +#if defined(DUK_USE_STRTAB_PTRCOMP) + slot = heap->strtable16 + (DUK_HSTRING_GET_HASH(h) & heap->st_mask); +#else + slot = heap->strtable + (DUK_HSTRING_GET_HASH(h) & heap->st_mask); +#endif + DUK_ASSERT(DUK__HEAPPTR_DEC16(heap, *slot) == h); + *slot = DUK__HEAPPTR_ENC16(heap, h->hdr.h_next); + } +} + +/* + * Force string table resize check in mark-and-sweep. + */ + +DUK_INTERNAL void duk_heap_strtable_force_resize(duk_heap *heap) { + /* Does only one grow/shrink step if needed. The heap->st_resizing + * flag protects against recursive resizing. + */ + + DUK_ASSERT(heap != NULL); + DUK_UNREF(heap); + +#if defined(DUK__STRTAB_RESIZE_CHECK) +#if defined(DUK_USE_STRTAB_PTRCOMP) + if (heap->strtable16 != NULL) { +#else + if (heap->strtable != NULL) { +#endif + duk__strtable_resize_check(heap); + } +#endif +} + +/* + * Free strings in the string table and the string table itself. + */ + +DUK_INTERNAL void duk_heap_strtable_free(duk_heap *heap) { +#if defined(DUK_USE_STRTAB_PTRCOMP) + duk_uint16_t *strtable; + duk_uint16_t *st; +#else + duk_hstring **strtable; + duk_hstring **st; +#endif + duk_hstring *h; + + DUK_ASSERT(heap != NULL); + +#if defined(DUK_USE_ASSERTIONS) + duk__strtable_assert_checks(heap); +#endif + + /* Strtable can be NULL if heap init fails. However, in that case + * heap->st_size is 0, so strtable == strtable_end and we skip the + * loop without a special check. + */ + strtable = DUK__GET_STRTABLE(heap); + st = strtable + heap->st_size; + DUK_ASSERT(strtable != NULL || heap->st_size == 0); + + while (strtable != st) { + --st; + h = DUK__HEAPPTR_DEC16(heap, *st); + while (h) { + duk_hstring *h_next; + h_next = h->hdr.h_next; + + /* Strings may have inner refs (extdata) in some cases. */ + duk_free_hstring(heap, h); + + h = h_next; + } + } + + DUK_FREE(heap, strtable); +} diff --git a/third_party/duktape/duk_heaphdr.h b/third_party/duktape/duk_heaphdr.h new file mode 100644 index 00000000..72c0c82b --- /dev/null +++ b/third_party/duktape/duk_heaphdr.h @@ -0,0 +1,297 @@ +/* + * Heap header definition and assorted macros, including ref counting. + * Access all fields through the accessor macros. + */ + +#if !defined(DUK_HEAPHDR_H_INCLUDED) +#define DUK_HEAPHDR_H_INCLUDED + +/* + * Common heap header + * + * All heap objects share the same flags and refcount fields. Objects other + * than strings also need to have a single or double linked list pointers + * for insertion into the "heap allocated" list. Strings have single linked + * list pointers for string table chaining. + * + * Technically, 'h_refcount' must be wide enough to guarantee that it cannot + * wrap; otherwise objects might be freed incorrectly after wrapping. The + * default refcount field is 32 bits even on 64-bit systems: while that's in + * theory incorrect, the Duktape heap needs to be larger than 64GB for the + * count to actually wrap (assuming 16-byte duk_tvals). This is very unlikely + * to ever be an issue, but if it is, disabling DUK_USE_REFCOUNT32 causes + * Duktape to use size_t for refcounts which should always be safe. + * + * Heap header size on 32-bit platforms: 8 bytes without reference counting, + * 16 bytes with reference counting. + * + * Note that 'raw' macros such as DUK_HEAPHDR_GET_REFCOUNT() are not + * defined without DUK_USE_REFERENCE_COUNTING, so caller must #if defined() + * around them. + */ + +/* XXX: macro for shared header fields (avoids some padding issues) */ + +struct duk_heaphdr { + duk_uint32_t h_flags; + +#if defined(DUK_USE_REFERENCE_COUNTING) +#if defined(DUK_USE_ASSERTIONS) + /* When assertions enabled, used by mark-and-sweep for refcount + * validation. Largest reasonable type; also detects overflows. + */ + duk_size_t h_assert_refcount; +#endif +#if defined(DUK_USE_REFCOUNT16) + duk_uint16_t h_refcount; +#elif defined(DUK_USE_REFCOUNT32) + duk_uint32_t h_refcount; +#else + duk_size_t h_refcount; +#endif +#endif /* DUK_USE_REFERENCE_COUNTING */ + +#if defined(DUK_USE_HEAPPTR16) + duk_uint16_t h_next16; +#else + duk_heaphdr *h_next; +#endif + +#if defined(DUK_USE_DOUBLE_LINKED_HEAP) + /* refcounting requires direct heap frees, which in turn requires a dual linked heap */ +#if defined(DUK_USE_HEAPPTR16) + duk_uint16_t h_prev16; +#else + duk_heaphdr *h_prev; +#endif +#endif + + /* When DUK_USE_HEAPPTR16 (and DUK_USE_REFCOUNT16) is in use, the + * struct won't align nicely to 4 bytes. This 16-bit extra field + * is added to make the alignment clean; the field can be used by + * heap objects when 16-bit packing is used. This field is now + * conditional to DUK_USE_HEAPPTR16 only, but it is intended to be + * used with DUK_USE_REFCOUNT16 and DUK_USE_DOUBLE_LINKED_HEAP; + * this only matter to low memory environments anyway. + */ +#if defined(DUK_USE_HEAPPTR16) + duk_uint16_t h_extra16; +#endif +}; + +struct duk_heaphdr_string { + /* 16 bits would be enough for shared heaphdr flags and duk_hstring + * flags. The initial parts of duk_heaphdr_string and duk_heaphdr + * must match so changing the flags field size here would be quite + * awkward. However, to minimize struct size, we can pack at least + * 16 bits of duk_hstring data into the flags field. + */ + duk_uint32_t h_flags; + +#if defined(DUK_USE_REFERENCE_COUNTING) +#if defined(DUK_USE_ASSERTIONS) + /* When assertions enabled, used by mark-and-sweep for refcount + * validation. Largest reasonable type; also detects overflows. + */ + duk_size_t h_assert_refcount; +#endif +#if defined(DUK_USE_REFCOUNT16) + duk_uint16_t h_refcount; + duk_uint16_t h_strextra16; /* round out to 8 bytes */ +#elif defined(DUK_USE_REFCOUNT32) + duk_uint32_t h_refcount; +#else + duk_size_t h_refcount; +#endif +#else + duk_uint16_t h_strextra16; +#endif /* DUK_USE_REFERENCE_COUNTING */ + + duk_hstring *h_next; + /* No 'h_prev' pointer for strings. */ +}; + +#define DUK_HEAPHDR_FLAGS_TYPE_MASK 0x00000003UL +#define DUK_HEAPHDR_FLAGS_FLAG_MASK (~DUK_HEAPHDR_FLAGS_TYPE_MASK) + + /* 2 bits for heap type */ +#define DUK_HEAPHDR_FLAGS_HEAP_START 2 /* 5 heap flags */ +#define DUK_HEAPHDR_FLAGS_USER_START 7 /* 25 user flags */ + +#define DUK_HEAPHDR_HEAP_FLAG_NUMBER(n) (DUK_HEAPHDR_FLAGS_HEAP_START + (n)) +#define DUK_HEAPHDR_USER_FLAG_NUMBER(n) (DUK_HEAPHDR_FLAGS_USER_START + (n)) +#define DUK_HEAPHDR_HEAP_FLAG(n) (1UL << (DUK_HEAPHDR_FLAGS_HEAP_START + (n))) +#define DUK_HEAPHDR_USER_FLAG(n) (1UL << (DUK_HEAPHDR_FLAGS_USER_START + (n))) + +#define DUK_HEAPHDR_FLAG_REACHABLE DUK_HEAPHDR_HEAP_FLAG(0) /* mark-and-sweep: reachable */ +#define DUK_HEAPHDR_FLAG_TEMPROOT DUK_HEAPHDR_HEAP_FLAG(1) /* mark-and-sweep: children not processed */ +#define DUK_HEAPHDR_FLAG_FINALIZABLE DUK_HEAPHDR_HEAP_FLAG(2) /* mark-and-sweep: finalizable (on current pass) */ +#define DUK_HEAPHDR_FLAG_FINALIZED DUK_HEAPHDR_HEAP_FLAG(3) /* mark-and-sweep: finalized (on previous pass) */ +#define DUK_HEAPHDR_FLAG_READONLY DUK_HEAPHDR_HEAP_FLAG(4) /* read-only object, in code section */ + +#define DUK_HTYPE_MIN 0 +#define DUK_HTYPE_STRING 0 +#define DUK_HTYPE_OBJECT 1 +#define DUK_HTYPE_BUFFER 2 +#define DUK_HTYPE_MAX 2 + +#if defined(DUK_USE_HEAPPTR16) +#define DUK_HEAPHDR_GET_NEXT(heap,h) \ + ((duk_heaphdr *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->h_next16)) +#define DUK_HEAPHDR_SET_NEXT(heap,h,val) do { \ + (h)->h_next16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) val); \ + } while (0) +#else +#define DUK_HEAPHDR_GET_NEXT(heap,h) ((h)->h_next) +#define DUK_HEAPHDR_SET_NEXT(heap,h,val) do { \ + (h)->h_next = (val); \ + } while (0) +#endif + +#if defined(DUK_USE_DOUBLE_LINKED_HEAP) +#if defined(DUK_USE_HEAPPTR16) +#define DUK_HEAPHDR_GET_PREV(heap,h) \ + ((duk_heaphdr *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->h_prev16)) +#define DUK_HEAPHDR_SET_PREV(heap,h,val) do { \ + (h)->h_prev16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (val)); \ + } while (0) +#else +#define DUK_HEAPHDR_GET_PREV(heap,h) ((h)->h_prev) +#define DUK_HEAPHDR_SET_PREV(heap,h,val) do { \ + (h)->h_prev = (val); \ + } while (0) +#endif +#endif + +#if defined(DUK_USE_REFERENCE_COUNTING) +#define DUK_HEAPHDR_GET_REFCOUNT(h) ((h)->h_refcount) +#define DUK_HEAPHDR_SET_REFCOUNT(h,val) do { \ + (h)->h_refcount = (val); \ + DUK_ASSERT((h)->h_refcount == (val)); /* No truncation. */ \ + } while (0) +#define DUK_HEAPHDR_PREINC_REFCOUNT(h) (++(h)->h_refcount) /* result: updated refcount */ +#define DUK_HEAPHDR_PREDEC_REFCOUNT(h) (--(h)->h_refcount) /* result: updated refcount */ +#else +/* refcount macros not defined without refcounting, caller must #if defined() now */ +#endif /* DUK_USE_REFERENCE_COUNTING */ + +/* + * Note: type is treated as a field separate from flags, so some masking is + * involved in the macros below. + */ + +#define DUK_HEAPHDR_GET_FLAGS_RAW(h) ((h)->h_flags) +#define DUK_HEAPHDR_SET_FLAGS_RAW(h,val) do { \ + (h)->h_flags = (val); } \ + } +#define DUK_HEAPHDR_GET_FLAGS(h) ((h)->h_flags & DUK_HEAPHDR_FLAGS_FLAG_MASK) +#define DUK_HEAPHDR_SET_FLAGS(h,val) do { \ + (h)->h_flags = ((h)->h_flags & ~(DUK_HEAPHDR_FLAGS_FLAG_MASK)) | (val); \ + } while (0) +#define DUK_HEAPHDR_GET_TYPE(h) ((h)->h_flags & DUK_HEAPHDR_FLAGS_TYPE_MASK) +#define DUK_HEAPHDR_SET_TYPE(h,val) do { \ + (h)->h_flags = ((h)->h_flags & ~(DUK_HEAPHDR_FLAGS_TYPE_MASK)) | (val); \ + } while (0) + +/* Comparison for type >= DUK_HTYPE_MIN skipped; because DUK_HTYPE_MIN is zero + * and the comparison is unsigned, it's always true and generates warnings. + */ +#define DUK_HEAPHDR_HTYPE_VALID(h) ( \ + DUK_HEAPHDR_GET_TYPE((h)) <= DUK_HTYPE_MAX \ + ) + +#define DUK_HEAPHDR_SET_TYPE_AND_FLAGS(h,tval,fval) do { \ + (h)->h_flags = ((tval) & DUK_HEAPHDR_FLAGS_TYPE_MASK) | \ + ((fval) & DUK_HEAPHDR_FLAGS_FLAG_MASK); \ + } while (0) + +#define DUK_HEAPHDR_SET_FLAG_BITS(h,bits) do { \ + DUK_ASSERT(((bits) & ~(DUK_HEAPHDR_FLAGS_FLAG_MASK)) == 0); \ + (h)->h_flags |= (bits); \ + } while (0) + +#define DUK_HEAPHDR_CLEAR_FLAG_BITS(h,bits) do { \ + DUK_ASSERT(((bits) & ~(DUK_HEAPHDR_FLAGS_FLAG_MASK)) == 0); \ + (h)->h_flags &= ~((bits)); \ + } while (0) + +#define DUK_HEAPHDR_CHECK_FLAG_BITS(h,bits) (((h)->h_flags & (bits)) != 0) + +#define DUK_HEAPHDR_SET_REACHABLE(h) DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_REACHABLE) +#define DUK_HEAPHDR_CLEAR_REACHABLE(h) DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_REACHABLE) +#define DUK_HEAPHDR_HAS_REACHABLE(h) DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_REACHABLE) + +#define DUK_HEAPHDR_SET_TEMPROOT(h) DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_TEMPROOT) +#define DUK_HEAPHDR_CLEAR_TEMPROOT(h) DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_TEMPROOT) +#define DUK_HEAPHDR_HAS_TEMPROOT(h) DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_TEMPROOT) + +#define DUK_HEAPHDR_SET_FINALIZABLE(h) DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZABLE) +#define DUK_HEAPHDR_CLEAR_FINALIZABLE(h) DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZABLE) +#define DUK_HEAPHDR_HAS_FINALIZABLE(h) DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZABLE) + +#define DUK_HEAPHDR_SET_FINALIZED(h) DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZED) +#define DUK_HEAPHDR_CLEAR_FINALIZED(h) DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZED) +#define DUK_HEAPHDR_HAS_FINALIZED(h) DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZED) + +#define DUK_HEAPHDR_SET_READONLY(h) DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_READONLY) +#define DUK_HEAPHDR_CLEAR_READONLY(h) DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_READONLY) +#define DUK_HEAPHDR_HAS_READONLY(h) DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_READONLY) + +/* get or set a range of flags; m=first bit number, n=number of bits */ +#define DUK_HEAPHDR_GET_FLAG_RANGE(h,m,n) (((h)->h_flags >> (m)) & ((1UL << (n)) - 1UL)) + +#define DUK_HEAPHDR_SET_FLAG_RANGE(h,m,n,v) do { \ + (h)->h_flags = \ + ((h)->h_flags & (~(((1UL << (n)) - 1UL) << (m)))) \ + | ((v) << (m)); \ + } while (0) + +/* init pointer fields to null */ +#if defined(DUK_USE_DOUBLE_LINKED_HEAP) +#define DUK_HEAPHDR_INIT_NULLS(h) do { \ + DUK_HEAPHDR_SET_NEXT((h), (void *) NULL); \ + DUK_HEAPHDR_SET_PREV((h), (void *) NULL); \ + } while (0) +#else +#define DUK_HEAPHDR_INIT_NULLS(h) do { \ + DUK_HEAPHDR_SET_NEXT((h), (void *) NULL); \ + } while (0) +#endif + +#define DUK_HEAPHDR_STRING_INIT_NULLS(h) do { \ + (h)->h_next = NULL; \ + } while (0) + +/* + * Type tests + */ + +/* Take advantage of the fact that for DUK_HTYPE_xxx numbers the lowest bit + * is only set for DUK_HTYPE_OBJECT (= 1). + */ +#if 0 +#define DUK_HEAPHDR_IS_OBJECT(h) (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_OBJECT) +#endif +#define DUK_HEAPHDR_IS_OBJECT(h) ((h)->h_flags & 0x01UL) +#define DUK_HEAPHDR_IS_STRING(h) (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_STRING) +#define DUK_HEAPHDR_IS_BUFFER(h) (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_BUFFER) + +/* + * Assert helpers + */ + +/* Check that prev/next links are consistent: if e.g. h->prev is != NULL, + * h->prev->next should point back to h. + */ +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL_DECL void duk_heaphdr_assert_valid_subclassed(duk_heaphdr *h); +DUK_INTERNAL_DECL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h); +DUK_INTERNAL_DECL void duk_heaphdr_assert_valid(duk_heaphdr *h); +#define DUK_HEAPHDR_ASSERT_LINKS(heap,h) do { duk_heaphdr_assert_links((heap), (h)); } while (0) +#define DUK_HEAPHDR_ASSERT_VALID(h) do { duk_heaphdr_assert_valid((h)); } while (0) +#else +#define DUK_HEAPHDR_ASSERT_LINKS(heap,h) do {} while (0) +#define DUK_HEAPHDR_ASSERT_VALID(h) do {} while (0) +#endif + +#endif /* DUK_HEAPHDR_H_INCLUDED */ diff --git a/third_party/duktape/duk_heaphdr_assert.c b/third_party/duktape/duk_heaphdr_assert.c new file mode 100644 index 00000000..f478c483 --- /dev/null +++ b/third_party/duktape/duk_heaphdr_assert.c @@ -0,0 +1,78 @@ +/* + * duk_heaphdr assertion helpers + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_ASSERTIONS) + +#if defined(DUK_USE_DOUBLE_LINKED_HEAP) +DUK_INTERNAL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h) { + DUK_UNREF(heap); + if (h != NULL) { + duk_heaphdr *h_prev, *h_next; + h_prev = DUK_HEAPHDR_GET_PREV(heap, h); + h_next = DUK_HEAPHDR_GET_NEXT(heap, h); + DUK_ASSERT(h_prev == NULL || (DUK_HEAPHDR_GET_NEXT(heap, h_prev) == h)); + DUK_ASSERT(h_next == NULL || (DUK_HEAPHDR_GET_PREV(heap, h_next) == h)); + } +} +#else +DUK_INTERNAL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h) { + DUK_UNREF(heap); + DUK_UNREF(h); +} +#endif + +DUK_INTERNAL void duk_heaphdr_assert_valid(duk_heaphdr *h) { + DUK_ASSERT(h != NULL); + DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h)); +} + +/* Assert validity of a heaphdr, including all subclasses. */ +DUK_INTERNAL void duk_heaphdr_assert_valid_subclassed(duk_heaphdr *h) { + switch (DUK_HEAPHDR_GET_TYPE(h)) { + case DUK_HTYPE_OBJECT: { + duk_hobject *h_obj = (duk_hobject *) h; + DUK_HOBJECT_ASSERT_VALID(h_obj); + if (DUK_HOBJECT_IS_COMPFUNC(h_obj)) { + DUK_HCOMPFUNC_ASSERT_VALID((duk_hcompfunc *) h_obj); + } else if (DUK_HOBJECT_IS_NATFUNC(h_obj)) { + DUK_HNATFUNC_ASSERT_VALID((duk_hnatfunc *) h_obj); + } else if (DUK_HOBJECT_IS_DECENV(h_obj)) { + DUK_HDECENV_ASSERT_VALID((duk_hdecenv *) h_obj); + } else if (DUK_HOBJECT_IS_OBJENV(h_obj)) { + DUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) h_obj); + } else if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) { +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + DUK_HBUFOBJ_ASSERT_VALID((duk_hbufobj *) h_obj); +#endif + } else if (DUK_HOBJECT_IS_BOUNDFUNC(h_obj)) { + DUK_HBOUNDFUNC_ASSERT_VALID((duk_hboundfunc *) h_obj); + } else if (DUK_HOBJECT_IS_PROXY(h_obj)) { + DUK_HPROXY_ASSERT_VALID((duk_hproxy *) h_obj); + } else if (DUK_HOBJECT_IS_THREAD(h_obj)) { + DUK_HTHREAD_ASSERT_VALID((duk_hthread *) h_obj); + } else { + /* Just a plain object. */ + ; + } + break; + } + case DUK_HTYPE_STRING: { + duk_hstring *h_str = (duk_hstring *) h; + DUK_HSTRING_ASSERT_VALID(h_str); + break; + } + case DUK_HTYPE_BUFFER: { + duk_hbuffer *h_buf = (duk_hbuffer *) h; + DUK_HBUFFER_ASSERT_VALID(h_buf); + break; + } + default: { + DUK_ASSERT(0); + } + } +} + +#endif /* DUK_USE_ASSERTIONS */ diff --git a/third_party/duktape/duk_henv.h b/third_party/duktape/duk_henv.h new file mode 100644 index 00000000..0fdd2c5f --- /dev/null +++ b/third_party/duktape/duk_henv.h @@ -0,0 +1,45 @@ +/* + * Environment object representation. + */ + +#if !defined(DUK_HENV_H_INCLUDED) +#define DUK_HENV_H_INCLUDED + +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL_DECL void duk_hdecenv_assert_valid(duk_hdecenv *h); +DUK_INTERNAL_DECL void duk_hobjenv_assert_valid(duk_hobjenv *h); +#define DUK_HDECENV_ASSERT_VALID(h) do { duk_hdecenv_assert_valid((h)); } while (0) +#define DUK_HOBJENV_ASSERT_VALID(h) do { duk_hobjenv_assert_valid((h)); } while (0) +#else +#define DUK_HDECENV_ASSERT_VALID(h) do {} while (0) +#define DUK_HOBJENV_ASSERT_VALID(h) do {} while (0) +#endif + +struct duk_hdecenv { + /* Shared object part. */ + duk_hobject obj; + + /* These control variables provide enough information to access live + * variables for a closure that is still open. If thread == NULL, + * the record is closed and the identifiers are in the property table. + */ + duk_hthread *thread; + duk_hobject *varmap; + duk_size_t regbase_byteoff; +}; + +struct duk_hobjenv { + /* Shared object part. */ + duk_hobject obj; + + /* Target object and 'this' binding for object binding. */ + duk_hobject *target; + + /* The 'target' object is used as a this binding in only some object + * environments. For example, the global environment does not provide + * a this binding, but a with statement does. + */ + duk_bool_t has_this; +}; + +#endif /* DUK_HENV_H_INCLUDED */ diff --git a/third_party/duktape/duk_hnatfunc.h b/third_party/duktape/duk_hnatfunc.h new file mode 100644 index 00000000..420dffbf --- /dev/null +++ b/third_party/duktape/duk_hnatfunc.h @@ -0,0 +1,39 @@ +/* + * Heap native function representation. + */ + +#if !defined(DUK_HNATFUNC_H_INCLUDED) +#define DUK_HNATFUNC_H_INCLUDED + +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL_DECL void duk_hnatfunc_assert_valid(duk_hnatfunc *h); +#define DUK_HNATFUNC_ASSERT_VALID(h) do { duk_hnatfunc_assert_valid((h)); } while (0) +#else +#define DUK_HNATFUNC_ASSERT_VALID(h) do {} while (0) +#endif + +#define DUK_HNATFUNC_NARGS_VARARGS ((duk_int16_t) -1) +#define DUK_HNATFUNC_NARGS_MAX ((duk_int16_t) 0x7fff) + +struct duk_hnatfunc { + /* shared object part */ + duk_hobject obj; + + duk_c_function func; + duk_int16_t nargs; + duk_int16_t magic; + + /* The 'magic' field allows an opaque 16-bit field to be accessed by the + * Duktape/C function. This allows, for instance, the same native function + * to be used for a set of very similar functions, with the 'magic' field + * providing the necessary non-argument flags / values to guide the behavior + * of the native function. The value is signed on purpose: it is easier to + * convert a signed value to unsigned (simply AND with 0xffff) than vice + * versa. + * + * Note: cannot place nargs/magic into the heaphdr flags, because + * duk_hobject takes almost all flags already. + */ +}; + +#endif /* DUK_HNATFUNC_H_INCLUDED */ diff --git a/third_party/duktape/duk_hobject.h b/third_party/duktape/duk_hobject.h new file mode 100644 index 00000000..17f44d31 --- /dev/null +++ b/third_party/duktape/duk_hobject.h @@ -0,0 +1,981 @@ +/* + * Heap object representation. + * + * Heap objects are used for ECMAScript objects, arrays, and functions, + * but also for internal control like declarative and object environment + * records. Compiled functions, native functions, and threads are also + * objects but with an extended C struct. + * + * Objects provide the required ECMAScript semantics and exotic behaviors + * especially for property access. + * + * Properties are stored in three conceptual parts: + * + * 1. A linear 'entry part' contains ordered key-value-attributes triples + * and is the main method of string properties. + * + * 2. An optional linear 'array part' is used for array objects to store a + * (dense) range of [0,N[ array indexed entries with default attributes + * (writable, enumerable, configurable). If the array part would become + * sparse or non-default attributes are required, the array part is + * abandoned and moved to the 'entry part'. + * + * 3. An optional 'hash part' is used to optimize lookups of the entry + * part; it is used only for objects with sufficiently many properties + * and can be abandoned without loss of information. + * + * These three conceptual parts are stored in a single memory allocated area. + * This minimizes memory allocation overhead but also means that all three + * parts are resized together, and makes property access a bit complicated. + */ + +#if !defined(DUK_HOBJECT_H_INCLUDED) +#define DUK_HOBJECT_H_INCLUDED + +/* Object flags. Make sure this stays in sync with debugger object + * inspection code. + */ + +/* XXX: some flags are object subtype specific (e.g. common to all function + * subtypes, duk_harray, etc) and could be reused for different subtypes. + */ +#define DUK_HOBJECT_FLAG_EXTENSIBLE DUK_HEAPHDR_USER_FLAG(0) /* object is extensible */ +#define DUK_HOBJECT_FLAG_CONSTRUCTABLE DUK_HEAPHDR_USER_FLAG(1) /* object is constructable */ +#define DUK_HOBJECT_FLAG_CALLABLE DUK_HEAPHDR_USER_FLAG(2) /* object is callable */ +#define DUK_HOBJECT_FLAG_BOUNDFUNC DUK_HEAPHDR_USER_FLAG(3) /* object established using Function.prototype.bind() */ +#define DUK_HOBJECT_FLAG_COMPFUNC DUK_HEAPHDR_USER_FLAG(4) /* object is a compiled function (duk_hcompfunc) */ +#define DUK_HOBJECT_FLAG_NATFUNC DUK_HEAPHDR_USER_FLAG(5) /* object is a native function (duk_hnatfunc) */ +#define DUK_HOBJECT_FLAG_BUFOBJ DUK_HEAPHDR_USER_FLAG(6) /* object is a buffer object (duk_hbufobj) (always exotic) */ +#define DUK_HOBJECT_FLAG_FASTREFS DUK_HEAPHDR_USER_FLAG(7) /* object has no fields needing DECREF/marking beyond base duk_hobject header */ +#define DUK_HOBJECT_FLAG_ARRAY_PART DUK_HEAPHDR_USER_FLAG(8) /* object has an array part (a_size may still be 0) */ +#define DUK_HOBJECT_FLAG_STRICT DUK_HEAPHDR_USER_FLAG(9) /* function: function object is strict */ +#define DUK_HOBJECT_FLAG_NOTAIL DUK_HEAPHDR_USER_FLAG(10) /* function: function must not be tail called */ +#define DUK_HOBJECT_FLAG_NEWENV DUK_HEAPHDR_USER_FLAG(11) /* function: create new environment when called (see duk_hcompfunc) */ +#define DUK_HOBJECT_FLAG_NAMEBINDING DUK_HEAPHDR_USER_FLAG(12) /* function: create binding for func name (function templates only, used for named function expressions) */ +#define DUK_HOBJECT_FLAG_CREATEARGS DUK_HEAPHDR_USER_FLAG(13) /* function: create an arguments object on function call */ +#define DUK_HOBJECT_FLAG_HAVE_FINALIZER DUK_HEAPHDR_USER_FLAG(14) /* object has a callable (own) finalizer property */ +#define DUK_HOBJECT_FLAG_EXOTIC_ARRAY DUK_HEAPHDR_USER_FLAG(15) /* 'Array' object, array length and index exotic behavior */ +#define DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ DUK_HEAPHDR_USER_FLAG(16) /* 'String' object, array index exotic behavior */ +#define DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS DUK_HEAPHDR_USER_FLAG(17) /* 'Arguments' object and has arguments exotic behavior (non-strict callee) */ +#define DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ DUK_HEAPHDR_USER_FLAG(18) /* 'Proxy' object */ +#define DUK_HOBJECT_FLAG_SPECIAL_CALL DUK_HEAPHDR_USER_FLAG(19) /* special casing in call behavior, for .call(), .apply(), etc. */ + +#define DUK_HOBJECT_FLAG_CLASS_BASE DUK_HEAPHDR_USER_FLAG_NUMBER(20) +#define DUK_HOBJECT_FLAG_CLASS_BITS 5 + +#define DUK_HOBJECT_GET_CLASS_NUMBER(h) \ + DUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS) +#define DUK_HOBJECT_SET_CLASS_NUMBER(h,v) \ + DUK_HEAPHDR_SET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS, (v)) + +#define DUK_HOBJECT_GET_CLASS_MASK(h) \ + (1UL << DUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS)) + +/* Macro for creating flag initializer from a class number. + * Unsigned type cast is needed to avoid warnings about coercing + * a signed integer to an unsigned one; the largest class values + * have the highest bit (bit 31) set which causes this. + */ +#define DUK_HOBJECT_CLASS_AS_FLAGS(v) (((duk_uint_t) (v)) << DUK_HOBJECT_FLAG_CLASS_BASE) + +/* E5 Section 8.6.2 + custom classes */ +#define DUK_HOBJECT_CLASS_NONE 0 +#define DUK_HOBJECT_CLASS_OBJECT 1 +#define DUK_HOBJECT_CLASS_ARRAY 2 +#define DUK_HOBJECT_CLASS_FUNCTION 3 +#define DUK_HOBJECT_CLASS_ARGUMENTS 4 +#define DUK_HOBJECT_CLASS_BOOLEAN 5 +#define DUK_HOBJECT_CLASS_DATE 6 +#define DUK_HOBJECT_CLASS_ERROR 7 +#define DUK_HOBJECT_CLASS_JSON 8 +#define DUK_HOBJECT_CLASS_MATH 9 +#define DUK_HOBJECT_CLASS_NUMBER 10 +#define DUK_HOBJECT_CLASS_REGEXP 11 +#define DUK_HOBJECT_CLASS_STRING 12 +#define DUK_HOBJECT_CLASS_GLOBAL 13 +#define DUK_HOBJECT_CLASS_SYMBOL 14 +#define DUK_HOBJECT_CLASS_OBJENV 15 /* custom */ +#define DUK_HOBJECT_CLASS_DECENV 16 /* custom */ +#define DUK_HOBJECT_CLASS_POINTER 17 /* custom */ +#define DUK_HOBJECT_CLASS_THREAD 18 /* custom; implies DUK_HOBJECT_IS_THREAD */ +#define DUK_HOBJECT_CLASS_BUFOBJ_MIN 19 +#define DUK_HOBJECT_CLASS_ARRAYBUFFER 19 /* implies DUK_HOBJECT_IS_BUFOBJ */ +#define DUK_HOBJECT_CLASS_DATAVIEW 20 +#define DUK_HOBJECT_CLASS_INT8ARRAY 21 +#define DUK_HOBJECT_CLASS_UINT8ARRAY 22 +#define DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY 23 +#define DUK_HOBJECT_CLASS_INT16ARRAY 24 +#define DUK_HOBJECT_CLASS_UINT16ARRAY 25 +#define DUK_HOBJECT_CLASS_INT32ARRAY 26 +#define DUK_HOBJECT_CLASS_UINT32ARRAY 27 +#define DUK_HOBJECT_CLASS_FLOAT32ARRAY 28 +#define DUK_HOBJECT_CLASS_FLOAT64ARRAY 29 +#define DUK_HOBJECT_CLASS_BUFOBJ_MAX 29 +#define DUK_HOBJECT_CLASS_MAX 29 + +/* Class masks. */ +#define DUK_HOBJECT_CMASK_ALL ((1UL << (DUK_HOBJECT_CLASS_MAX + 1)) - 1UL) +#define DUK_HOBJECT_CMASK_NONE (1UL << DUK_HOBJECT_CLASS_NONE) +#define DUK_HOBJECT_CMASK_ARGUMENTS (1UL << DUK_HOBJECT_CLASS_ARGUMENTS) +#define DUK_HOBJECT_CMASK_ARRAY (1UL << DUK_HOBJECT_CLASS_ARRAY) +#define DUK_HOBJECT_CMASK_BOOLEAN (1UL << DUK_HOBJECT_CLASS_BOOLEAN) +#define DUK_HOBJECT_CMASK_DATE (1UL << DUK_HOBJECT_CLASS_DATE) +#define DUK_HOBJECT_CMASK_ERROR (1UL << DUK_HOBJECT_CLASS_ERROR) +#define DUK_HOBJECT_CMASK_FUNCTION (1UL << DUK_HOBJECT_CLASS_FUNCTION) +#define DUK_HOBJECT_CMASK_JSON (1UL << DUK_HOBJECT_CLASS_JSON) +#define DUK_HOBJECT_CMASK_MATH (1UL << DUK_HOBJECT_CLASS_MATH) +#define DUK_HOBJECT_CMASK_NUMBER (1UL << DUK_HOBJECT_CLASS_NUMBER) +#define DUK_HOBJECT_CMASK_OBJECT (1UL << DUK_HOBJECT_CLASS_OBJECT) +#define DUK_HOBJECT_CMASK_REGEXP (1UL << DUK_HOBJECT_CLASS_REGEXP) +#define DUK_HOBJECT_CMASK_STRING (1UL << DUK_HOBJECT_CLASS_STRING) +#define DUK_HOBJECT_CMASK_GLOBAL (1UL << DUK_HOBJECT_CLASS_GLOBAL) +#define DUK_HOBJECT_CMASK_SYMBOL (1UL << DUK_HOBJECT_CLASS_SYMBOL) +#define DUK_HOBJECT_CMASK_OBJENV (1UL << DUK_HOBJECT_CLASS_OBJENV) +#define DUK_HOBJECT_CMASK_DECENV (1UL << DUK_HOBJECT_CLASS_DECENV) +#define DUK_HOBJECT_CMASK_POINTER (1UL << DUK_HOBJECT_CLASS_POINTER) +#define DUK_HOBJECT_CMASK_ARRAYBUFFER (1UL << DUK_HOBJECT_CLASS_ARRAYBUFFER) +#define DUK_HOBJECT_CMASK_DATAVIEW (1UL << DUK_HOBJECT_CLASS_DATAVIEW) +#define DUK_HOBJECT_CMASK_INT8ARRAY (1UL << DUK_HOBJECT_CLASS_INT8ARRAY) +#define DUK_HOBJECT_CMASK_UINT8ARRAY (1UL << DUK_HOBJECT_CLASS_UINT8ARRAY) +#define DUK_HOBJECT_CMASK_UINT8CLAMPEDARRAY (1UL << DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY) +#define DUK_HOBJECT_CMASK_INT16ARRAY (1UL << DUK_HOBJECT_CLASS_INT16ARRAY) +#define DUK_HOBJECT_CMASK_UINT16ARRAY (1UL << DUK_HOBJECT_CLASS_UINT16ARRAY) +#define DUK_HOBJECT_CMASK_INT32ARRAY (1UL << DUK_HOBJECT_CLASS_INT32ARRAY) +#define DUK_HOBJECT_CMASK_UINT32ARRAY (1UL << DUK_HOBJECT_CLASS_UINT32ARRAY) +#define DUK_HOBJECT_CMASK_FLOAT32ARRAY (1UL << DUK_HOBJECT_CLASS_FLOAT32ARRAY) +#define DUK_HOBJECT_CMASK_FLOAT64ARRAY (1UL << DUK_HOBJECT_CLASS_FLOAT64ARRAY) + +#define DUK_HOBJECT_CMASK_ALL_BUFOBJS \ + (DUK_HOBJECT_CMASK_ARRAYBUFFER | \ + DUK_HOBJECT_CMASK_DATAVIEW | \ + DUK_HOBJECT_CMASK_INT8ARRAY | \ + DUK_HOBJECT_CMASK_UINT8ARRAY | \ + DUK_HOBJECT_CMASK_UINT8CLAMPEDARRAY | \ + DUK_HOBJECT_CMASK_INT16ARRAY | \ + DUK_HOBJECT_CMASK_UINT16ARRAY | \ + DUK_HOBJECT_CMASK_INT32ARRAY | \ + DUK_HOBJECT_CMASK_UINT32ARRAY | \ + DUK_HOBJECT_CMASK_FLOAT32ARRAY | \ + DUK_HOBJECT_CMASK_FLOAT64ARRAY) + +#define DUK_HOBJECT_IS_OBJENV(h) (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_OBJENV) +#define DUK_HOBJECT_IS_DECENV(h) (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_DECENV) +#define DUK_HOBJECT_IS_ENV(h) (DUK_HOBJECT_IS_OBJENV((h)) || DUK_HOBJECT_IS_DECENV((h))) +#define DUK_HOBJECT_IS_ARRAY(h) DUK_HOBJECT_HAS_EXOTIC_ARRAY((h)) /* Rely on class Array <=> exotic Array */ +#define DUK_HOBJECT_IS_BOUNDFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC) +#define DUK_HOBJECT_IS_COMPFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC) +#define DUK_HOBJECT_IS_NATFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC) +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +#define DUK_HOBJECT_IS_BUFOBJ(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ) +#else +#define DUK_HOBJECT_IS_BUFOBJ(h) 0 +#endif +#define DUK_HOBJECT_IS_THREAD(h) (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_THREAD) +#if defined(DUK_USE_ES6_PROXY) +#define DUK_HOBJECT_IS_PROXY(h) DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ((h)) +#else +#define DUK_HOBJECT_IS_PROXY(h) 0 +#endif + +#define DUK_HOBJECT_IS_NONBOUND_FUNCTION(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \ + DUK_HOBJECT_FLAG_COMPFUNC | \ + DUK_HOBJECT_FLAG_NATFUNC) + +#define DUK_HOBJECT_IS_FUNCTION(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \ + DUK_HOBJECT_FLAG_BOUNDFUNC | \ + DUK_HOBJECT_FLAG_COMPFUNC | \ + DUK_HOBJECT_FLAG_NATFUNC) + +#define DUK_HOBJECT_IS_CALLABLE(h) DUK_HOBJECT_HAS_CALLABLE((h)) + +/* Object has any exotic behavior(s). */ +#define DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS (DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \ + DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS | \ + DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | \ + DUK_HOBJECT_FLAG_BUFOBJ | \ + DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ) +#define DUK_HOBJECT_HAS_EXOTIC_BEHAVIOR(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS) + +/* Object has any virtual properties (not counting Proxy behavior). */ +#define DUK_HOBJECT_VIRTUAL_PROPERTY_FLAGS (DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \ + DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | \ + DUK_HOBJECT_FLAG_BUFOBJ) +#define DUK_HOBJECT_HAS_VIRTUAL_PROPERTIES(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_VIRTUAL_PROPERTY_FLAGS) + +#define DUK_HOBJECT_HAS_EXTENSIBLE(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE) +#define DUK_HOBJECT_HAS_CONSTRUCTABLE(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE) +#define DUK_HOBJECT_HAS_CALLABLE(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE) +#define DUK_HOBJECT_HAS_BOUNDFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC) +#define DUK_HOBJECT_HAS_COMPFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC) +#define DUK_HOBJECT_HAS_NATFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC) +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +#define DUK_HOBJECT_HAS_BUFOBJ(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ) +#else +#define DUK_HOBJECT_HAS_BUFOBJ(h) 0 +#endif +#define DUK_HOBJECT_HAS_FASTREFS(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS) +#define DUK_HOBJECT_HAS_ARRAY_PART(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART) +#define DUK_HOBJECT_HAS_STRICT(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT) +#define DUK_HOBJECT_HAS_NOTAIL(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL) +#define DUK_HOBJECT_HAS_NEWENV(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV) +#define DUK_HOBJECT_HAS_NAMEBINDING(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING) +#define DUK_HOBJECT_HAS_CREATEARGS(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS) +#define DUK_HOBJECT_HAS_HAVE_FINALIZER(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_HAVE_FINALIZER) +#define DUK_HOBJECT_HAS_EXOTIC_ARRAY(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY) +#define DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ) +#define DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS) +#if defined(DUK_USE_ES6_PROXY) +#define DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ) +#else +#define DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h) 0 +#endif +#define DUK_HOBJECT_HAS_SPECIAL_CALL(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL) + +#define DUK_HOBJECT_SET_EXTENSIBLE(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE) +#define DUK_HOBJECT_SET_CONSTRUCTABLE(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE) +#define DUK_HOBJECT_SET_CALLABLE(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE) +#define DUK_HOBJECT_SET_BOUNDFUNC(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC) +#define DUK_HOBJECT_SET_COMPFUNC(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC) +#define DUK_HOBJECT_SET_NATFUNC(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC) +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +#define DUK_HOBJECT_SET_BUFOBJ(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ) +#endif +#define DUK_HOBJECT_SET_FASTREFS(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS) +#define DUK_HOBJECT_SET_ARRAY_PART(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART) +#define DUK_HOBJECT_SET_STRICT(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT) +#define DUK_HOBJECT_SET_NOTAIL(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL) +#define DUK_HOBJECT_SET_NEWENV(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV) +#define DUK_HOBJECT_SET_NAMEBINDING(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING) +#define DUK_HOBJECT_SET_CREATEARGS(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS) +#define DUK_HOBJECT_SET_HAVE_FINALIZER(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_HAVE_FINALIZER) +#define DUK_HOBJECT_SET_EXOTIC_ARRAY(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY) +#define DUK_HOBJECT_SET_EXOTIC_STRINGOBJ(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ) +#define DUK_HOBJECT_SET_EXOTIC_ARGUMENTS(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS) +#if defined(DUK_USE_ES6_PROXY) +#define DUK_HOBJECT_SET_EXOTIC_PROXYOBJ(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ) +#endif +#define DUK_HOBJECT_SET_SPECIAL_CALL(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL) + +#define DUK_HOBJECT_CLEAR_EXTENSIBLE(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE) +#define DUK_HOBJECT_CLEAR_CONSTRUCTABLE(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE) +#define DUK_HOBJECT_CLEAR_CALLABLE(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE) +#define DUK_HOBJECT_CLEAR_BOUNDFUNC(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC) +#define DUK_HOBJECT_CLEAR_COMPFUNC(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC) +#define DUK_HOBJECT_CLEAR_NATFUNC(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC) +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +#define DUK_HOBJECT_CLEAR_BUFOBJ(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ) +#endif +#define DUK_HOBJECT_CLEAR_FASTREFS(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS) +#define DUK_HOBJECT_CLEAR_ARRAY_PART(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART) +#define DUK_HOBJECT_CLEAR_STRICT(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT) +#define DUK_HOBJECT_CLEAR_NOTAIL(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL) +#define DUK_HOBJECT_CLEAR_NEWENV(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV) +#define DUK_HOBJECT_CLEAR_NAMEBINDING(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING) +#define DUK_HOBJECT_CLEAR_CREATEARGS(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS) +#define DUK_HOBJECT_CLEAR_HAVE_FINALIZER(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_HAVE_FINALIZER) +#define DUK_HOBJECT_CLEAR_EXOTIC_ARRAY(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY) +#define DUK_HOBJECT_CLEAR_EXOTIC_STRINGOBJ(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ) +#define DUK_HOBJECT_CLEAR_EXOTIC_ARGUMENTS(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS) +#if defined(DUK_USE_ES6_PROXY) +#define DUK_HOBJECT_CLEAR_EXOTIC_PROXYOBJ(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ) +#endif +#define DUK_HOBJECT_CLEAR_SPECIAL_CALL(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL) + +/* Object can/cannot use FASTREFS, i.e. has no strong reference fields beyond + * duk_hobject base header. This is used just for asserts so doesn't need to + * be optimized. + */ +#define DUK_HOBJECT_PROHIBITS_FASTREFS(h) \ + (DUK_HOBJECT_IS_COMPFUNC((h)) || DUK_HOBJECT_IS_DECENV((h)) || DUK_HOBJECT_IS_OBJENV((h)) || \ + DUK_HOBJECT_IS_BUFOBJ((h)) || DUK_HOBJECT_IS_THREAD((h)) || DUK_HOBJECT_IS_PROXY((h)) || \ + DUK_HOBJECT_IS_BOUNDFUNC((h))) +#define DUK_HOBJECT_ALLOWS_FASTREFS(h) (!DUK_HOBJECT_PROHIBITS_FASTREFS((h))) + +/* Flags used for property attributes in duk_propdesc and packed flags. + * Must fit into 8 bits. + */ +#define DUK_PROPDESC_FLAG_WRITABLE (1U << 0) /* E5 Section 8.6.1 */ +#define DUK_PROPDESC_FLAG_ENUMERABLE (1U << 1) /* E5 Section 8.6.1 */ +#define DUK_PROPDESC_FLAG_CONFIGURABLE (1U << 2) /* E5 Section 8.6.1 */ +#define DUK_PROPDESC_FLAG_ACCESSOR (1U << 3) /* accessor */ +#define DUK_PROPDESC_FLAG_VIRTUAL (1U << 4) /* property is virtual: used in duk_propdesc, never stored + * (used by e.g. buffer virtual properties) + */ +#define DUK_PROPDESC_FLAGS_MASK (DUK_PROPDESC_FLAG_WRITABLE | \ + DUK_PROPDESC_FLAG_ENUMERABLE | \ + DUK_PROPDESC_FLAG_CONFIGURABLE | \ + DUK_PROPDESC_FLAG_ACCESSOR) + +/* Additional flags which are passed in the same flags argument as property + * flags but are not stored in object properties. + */ +#define DUK_PROPDESC_FLAG_NO_OVERWRITE (1U << 4) /* internal define property: skip write silently if exists */ + +/* Convenience defines for property attributes. */ +#define DUK_PROPDESC_FLAGS_NONE 0 +#define DUK_PROPDESC_FLAGS_W (DUK_PROPDESC_FLAG_WRITABLE) +#define DUK_PROPDESC_FLAGS_E (DUK_PROPDESC_FLAG_ENUMERABLE) +#define DUK_PROPDESC_FLAGS_C (DUK_PROPDESC_FLAG_CONFIGURABLE) +#define DUK_PROPDESC_FLAGS_WE (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_ENUMERABLE) +#define DUK_PROPDESC_FLAGS_WC (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_CONFIGURABLE) +#define DUK_PROPDESC_FLAGS_EC (DUK_PROPDESC_FLAG_ENUMERABLE | DUK_PROPDESC_FLAG_CONFIGURABLE) +#define DUK_PROPDESC_FLAGS_WEC (DUK_PROPDESC_FLAG_WRITABLE | \ + DUK_PROPDESC_FLAG_ENUMERABLE | \ + DUK_PROPDESC_FLAG_CONFIGURABLE) + +/* Flags for duk_hobject_get_own_propdesc() and variants. */ +#define DUK_GETDESC_FLAG_PUSH_VALUE (1U << 0) /* push value to stack */ +#define DUK_GETDESC_FLAG_IGNORE_PROTOLOOP (1U << 1) /* don't throw for prototype loop */ + +/* + * Macro for object validity check + * + * Assert for currently guaranteed relations between flags, for instance. + */ + +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL_DECL void duk_hobject_assert_valid(duk_hobject *h); +#define DUK_HOBJECT_ASSERT_VALID(h) do { duk_hobject_assert_valid((h)); } while (0) +#else +#define DUK_HOBJECT_ASSERT_VALID(h) do {} while (0) +#endif + +/* + * Macros to access the 'props' allocation. + */ + +#if defined(DUK_USE_HEAPPTR16) +#define DUK_HOBJECT_GET_PROPS(heap,h) \ + ((duk_uint8_t *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, ((duk_heaphdr *) (h))->h_extra16)) +#define DUK_HOBJECT_SET_PROPS(heap,h,x) do { \ + ((duk_heaphdr *) (h))->h_extra16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (x)); \ + } while (0) +#else +#define DUK_HOBJECT_GET_PROPS(heap,h) \ + ((h)->props) +#define DUK_HOBJECT_SET_PROPS(heap,h,x) do { \ + (h)->props = (duk_uint8_t *) (x); \ + } while (0) +#endif + +#if defined(DUK_USE_HOBJECT_LAYOUT_1) +/* LAYOUT 1 */ +#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \ + ((duk_hstring **) (void *) ( \ + DUK_HOBJECT_GET_PROPS((heap), (h)) \ + )) +#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \ + ((duk_propvalue *) (void *) ( \ + DUK_HOBJECT_GET_PROPS((heap), (h)) + \ + DUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_hstring *) \ + )) +#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \ + ((duk_uint8_t *) (void *) ( \ + DUK_HOBJECT_GET_PROPS((heap), (h)) + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue)) \ + )) +#define DUK_HOBJECT_A_GET_BASE(heap,h) \ + ((duk_tval *) (void *) ( \ + DUK_HOBJECT_GET_PROPS((heap), (h)) + \ + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) \ + )) +#define DUK_HOBJECT_H_GET_BASE(heap,h) \ + ((duk_uint32_t *) (void *) ( \ + DUK_HOBJECT_GET_PROPS((heap), (h)) + \ + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \ + DUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \ + )) +#define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \ + ( \ + (n_ent) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \ + (n_arr) * sizeof(duk_tval) + \ + (n_hash) * sizeof(duk_uint32_t) \ + ) +#define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash) do { \ + (set_e_k) = (duk_hstring **) (void *) (p_base); \ + (set_e_pv) = (duk_propvalue *) (void *) ((set_e_k) + (n_ent)); \ + (set_e_f) = (duk_uint8_t *) (void *) ((set_e_pv) + (n_ent)); \ + (set_a) = (duk_tval *) (void *) ((set_e_f) + (n_ent)); \ + (set_h) = (duk_uint32_t *) (void *) ((set_a) + (n_arr)); \ + } while (0) +#elif defined(DUK_USE_HOBJECT_LAYOUT_2) +/* LAYOUT 2 */ +#if (DUK_USE_ALIGN_BY == 4) +#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) ((4 - (e_sz)) & 0x03) +#elif (DUK_USE_ALIGN_BY == 8) +#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) ((8 - (e_sz)) & 0x07) +#elif (DUK_USE_ALIGN_BY == 1) +#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) 0 +#else +#error invalid DUK_USE_ALIGN_BY +#endif +#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \ + ((duk_hstring **) (void *) ( \ + DUK_HOBJECT_GET_PROPS((heap), (h)) + \ + DUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) \ + )) +#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \ + ((duk_propvalue *) (void *) ( \ + DUK_HOBJECT_GET_PROPS((heap), (h)) \ + )) +#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \ + ((duk_uint8_t *) (void *) ( \ + DUK_HOBJECT_GET_PROPS((heap), (h)) + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue)) \ + )) +#define DUK_HOBJECT_A_GET_BASE(heap,h) \ + ((duk_tval *) (void *) ( \ + DUK_HOBJECT_GET_PROPS((heap), (h)) + \ + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \ + DUK_HOBJECT_E_FLAG_PADDING(DUK_HOBJECT_GET_ESIZE((h))) \ + )) +#define DUK_HOBJECT_H_GET_BASE(heap,h) \ + ((duk_uint32_t *) (void *) ( \ + DUK_HOBJECT_GET_PROPS((heap), (h)) + \ + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \ + DUK_HOBJECT_E_FLAG_PADDING(DUK_HOBJECT_GET_ESIZE((h))) + \ + DUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \ + )) +#define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \ + ( \ + (n_ent) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \ + DUK_HOBJECT_E_FLAG_PADDING((n_ent)) + \ + (n_arr) * sizeof(duk_tval) + \ + (n_hash) * sizeof(duk_uint32_t) \ + ) +#define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash) do { \ + (set_e_pv) = (duk_propvalue *) (void *) (p_base); \ + (set_e_k) = (duk_hstring **) (void *) ((set_e_pv) + (n_ent)); \ + (set_e_f) = (duk_uint8_t *) (void *) ((set_e_k) + (n_ent)); \ + (set_a) = (duk_tval *) (void *) (((duk_uint8_t *) (set_e_f)) + \ + sizeof(duk_uint8_t) * (n_ent) + \ + DUK_HOBJECT_E_FLAG_PADDING((n_ent))); \ + (set_h) = (duk_uint32_t *) (void *) ((set_a) + (n_arr)); \ + } while (0) +#elif defined(DUK_USE_HOBJECT_LAYOUT_3) +/* LAYOUT 3 */ +#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \ + ((duk_hstring **) (void *) ( \ + DUK_HOBJECT_GET_PROPS((heap), (h)) + \ + DUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) + \ + DUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \ + )) +#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \ + ((duk_propvalue *) (void *) ( \ + DUK_HOBJECT_GET_PROPS((heap), (h)) \ + )) +#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \ + ((duk_uint8_t *) (void *) ( \ + DUK_HOBJECT_GET_PROPS((heap), (h)) + \ + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_propvalue) + sizeof(duk_hstring *)) + \ + DUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) + \ + DUK_HOBJECT_GET_HSIZE((h)) * sizeof(duk_uint32_t) \ + )) +#define DUK_HOBJECT_A_GET_BASE(heap,h) \ + ((duk_tval *) (void *) ( \ + DUK_HOBJECT_GET_PROPS((heap), (h)) + \ + DUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) \ + )) +#define DUK_HOBJECT_H_GET_BASE(heap,h) \ + ((duk_uint32_t *) (void *) ( \ + DUK_HOBJECT_GET_PROPS((heap), (h)) + \ + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_propvalue) + sizeof(duk_hstring *)) + \ + DUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \ + )) +#define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \ + ( \ + (n_ent) * (sizeof(duk_propvalue) + sizeof(duk_hstring *) + sizeof(duk_uint8_t)) + \ + (n_arr) * sizeof(duk_tval) + \ + (n_hash) * sizeof(duk_uint32_t) \ + ) +#define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash) do { \ + (set_e_pv) = (duk_propvalue *) (void *) (p_base); \ + (set_a) = (duk_tval *) (void *) ((set_e_pv) + (n_ent)); \ + (set_e_k) = (duk_hstring **) (void *) ((set_a) + (n_arr)); \ + (set_h) = (duk_uint32_t *) (void *) ((set_e_k) + (n_ent)); \ + (set_e_f) = (duk_uint8_t *) (void *) ((set_h) + (n_hash)); \ + } while (0) +#else +#error invalid hobject layout defines +#endif /* hobject property layout */ + +#define DUK_HOBJECT_P_ALLOC_SIZE(h) \ + DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE((h)), DUK_HOBJECT_GET_ASIZE((h)), DUK_HOBJECT_GET_HSIZE((h))) + +#define DUK_HOBJECT_E_GET_KEY(heap,h,i) (DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)]) +#define DUK_HOBJECT_E_GET_KEY_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)]) +#define DUK_HOBJECT_E_GET_VALUE(heap,h,i) (DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)]) +#define DUK_HOBJECT_E_GET_VALUE_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)]) +#define DUK_HOBJECT_E_GET_VALUE_TVAL(heap,h,i) (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v) +#define DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v) +#define DUK_HOBJECT_E_GET_VALUE_GETTER(heap,h,i) (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get) +#define DUK_HOBJECT_E_GET_VALUE_GETTER_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get) +#define DUK_HOBJECT_E_GET_VALUE_SETTER(heap,h,i) (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set) +#define DUK_HOBJECT_E_GET_VALUE_SETTER_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set) +#define DUK_HOBJECT_E_GET_FLAGS(heap,h,i) (DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)]) +#define DUK_HOBJECT_E_GET_FLAGS_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)]) +#define DUK_HOBJECT_A_GET_VALUE(heap,h,i) (DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)]) +#define DUK_HOBJECT_A_GET_VALUE_PTR(heap,h,i) (&DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)]) +#define DUK_HOBJECT_H_GET_INDEX(heap,h,i) (DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)]) +#define DUK_HOBJECT_H_GET_INDEX_PTR(heap,h,i) (&DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)]) + +#define DUK_HOBJECT_E_SET_KEY(heap,h,i,k) do { \ + DUK_HOBJECT_E_GET_KEY((heap), (h), (i)) = (k); \ + } while (0) +#define DUK_HOBJECT_E_SET_VALUE(heap,h,i,v) do { \ + DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)) = (v); \ + } while (0) +#define DUK_HOBJECT_E_SET_VALUE_TVAL(heap,h,i,v) do { \ + DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v = (v); \ + } while (0) +#define DUK_HOBJECT_E_SET_VALUE_GETTER(heap,h,i,v) do { \ + DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get = (v); \ + } while (0) +#define DUK_HOBJECT_E_SET_VALUE_SETTER(heap,h,i,v) do { \ + DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set = (v); \ + } while (0) +#define DUK_HOBJECT_E_SET_FLAGS(heap,h,i,f) do { \ + DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) = (duk_uint8_t) (f); \ + } while (0) +#define DUK_HOBJECT_A_SET_VALUE(heap,h,i,v) do { \ + DUK_HOBJECT_A_GET_VALUE((heap), (h), (i)) = (v); \ + } while (0) +#define DUK_HOBJECT_A_SET_VALUE_TVAL(heap,h,i,v) \ + DUK_HOBJECT_A_SET_VALUE((heap), (h), (i), (v)) /* alias for above */ +#define DUK_HOBJECT_H_SET_INDEX(heap,h,i,v) do { \ + DUK_HOBJECT_H_GET_INDEX((heap), (h), (i)) = (v); \ + } while (0) + +#define DUK_HOBJECT_E_SET_FLAG_BITS(heap,h,i,mask) do { \ + DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] |= (mask); \ + } while (0) + +#define DUK_HOBJECT_E_CLEAR_FLAG_BITS(heap,h,i,mask) do { \ + DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] &= ~(mask); \ + } while (0) + +#define DUK_HOBJECT_E_SLOT_IS_WRITABLE(heap,h,i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_WRITABLE) != 0) +#define DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(heap,h,i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ENUMERABLE) != 0) +#define DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(heap,h,i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0) +#define DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap,h,i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ACCESSOR) != 0) + +#define DUK_HOBJECT_E_SLOT_SET_WRITABLE(heap,h,i) DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE) +#define DUK_HOBJECT_E_SLOT_SET_ENUMERABLE(heap,h,i) DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE) +#define DUK_HOBJECT_E_SLOT_SET_CONFIGURABLE(heap,h,i) DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE) +#define DUK_HOBJECT_E_SLOT_SET_ACCESSOR(heap,h,i) DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR) + +#define DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(heap,h,i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE) +#define DUK_HOBJECT_E_SLOT_CLEAR_ENUMERABLE(heap,h,i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE) +#define DUK_HOBJECT_E_SLOT_CLEAR_CONFIGURABLE(heap,h,i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE) +#define DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(heap,h,i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR) + +#define DUK_PROPDESC_IS_WRITABLE(p) (((p)->flags & DUK_PROPDESC_FLAG_WRITABLE) != 0) +#define DUK_PROPDESC_IS_ENUMERABLE(p) (((p)->flags & DUK_PROPDESC_FLAG_ENUMERABLE) != 0) +#define DUK_PROPDESC_IS_CONFIGURABLE(p) (((p)->flags & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0) +#define DUK_PROPDESC_IS_ACCESSOR(p) (((p)->flags & DUK_PROPDESC_FLAG_ACCESSOR) != 0) + +#define DUK_HOBJECT_HASHIDX_UNUSED 0xffffffffUL +#define DUK_HOBJECT_HASHIDX_DELETED 0xfffffffeUL + +/* + * Macros for accessing size fields + */ + +#if defined(DUK_USE_OBJSIZES16) +#define DUK_HOBJECT_GET_ESIZE(h) ((h)->e_size16) +#define DUK_HOBJECT_SET_ESIZE(h,v) do { (h)->e_size16 = (v); } while (0) +#define DUK_HOBJECT_GET_ENEXT(h) ((h)->e_next16) +#define DUK_HOBJECT_SET_ENEXT(h,v) do { (h)->e_next16 = (v); } while (0) +#define DUK_HOBJECT_POSTINC_ENEXT(h) ((h)->e_next16++) +#define DUK_HOBJECT_GET_ASIZE(h) ((h)->a_size16) +#define DUK_HOBJECT_SET_ASIZE(h,v) do { (h)->a_size16 = (v); } while (0) +#if defined(DUK_USE_HOBJECT_HASH_PART) +#define DUK_HOBJECT_GET_HSIZE(h) ((h)->h_size16) +#define DUK_HOBJECT_SET_HSIZE(h,v) do { (h)->h_size16 = (v); } while (0) +#else +#define DUK_HOBJECT_GET_HSIZE(h) 0 +#define DUK_HOBJECT_SET_HSIZE(h,v) do { DUK_ASSERT((v) == 0); } while (0) +#endif +#else +#define DUK_HOBJECT_GET_ESIZE(h) ((h)->e_size) +#define DUK_HOBJECT_SET_ESIZE(h,v) do { (h)->e_size = (v); } while (0) +#define DUK_HOBJECT_GET_ENEXT(h) ((h)->e_next) +#define DUK_HOBJECT_SET_ENEXT(h,v) do { (h)->e_next = (v); } while (0) +#define DUK_HOBJECT_POSTINC_ENEXT(h) ((h)->e_next++) +#define DUK_HOBJECT_GET_ASIZE(h) ((h)->a_size) +#define DUK_HOBJECT_SET_ASIZE(h,v) do { (h)->a_size = (v); } while (0) +#if defined(DUK_USE_HOBJECT_HASH_PART) +#define DUK_HOBJECT_GET_HSIZE(h) ((h)->h_size) +#define DUK_HOBJECT_SET_HSIZE(h,v) do { (h)->h_size = (v); } while (0) +#else +#define DUK_HOBJECT_GET_HSIZE(h) 0 +#define DUK_HOBJECT_SET_HSIZE(h,v) do { DUK_ASSERT((v) == 0); } while (0) +#endif +#endif + +/* + * Misc + */ + +/* Maximum prototype traversal depth. Sanity limit which handles e.g. + * prototype loops (even complex ones like 1->2->3->4->2->3->4->2->3->4). + */ +#define DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY 10000L + +/* + * ECMAScript [[Class]] + */ + +/* range check not necessary because all 4-bit values are mapped */ +#define DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(n) duk_class_number_to_stridx[(n)] + +#define DUK_HOBJECT_GET_CLASS_STRING(heap,h) \ + DUK_HEAP_GET_STRING( \ + (heap), \ + DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(DUK_HOBJECT_GET_CLASS_NUMBER((h))) \ + ) + +/* + * Macros for property handling + */ + +#if defined(DUK_USE_HEAPPTR16) +#define DUK_HOBJECT_GET_PROTOTYPE(heap,h) \ + ((duk_hobject *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->prototype16)) +#define DUK_HOBJECT_SET_PROTOTYPE(heap,h,x) do { \ + (h)->prototype16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (x)); \ + } while (0) +#else +#define DUK_HOBJECT_GET_PROTOTYPE(heap,h) \ + ((h)->prototype) +#define DUK_HOBJECT_SET_PROTOTYPE(heap,h,x) do { \ + (h)->prototype = (x); \ + } while (0) +#endif + +/* Set prototype, DECREF earlier value, INCREF new value (tolerating NULLs). */ +#define DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr,h,p) duk_hobject_set_prototype_updref((thr), (h), (p)) + +/* Set initial prototype, assume NULL previous prototype, INCREF new value, + * tolerate NULL. + */ +#define DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr,h,proto) do { \ + duk_hthread *duk__thr = (thr); \ + duk_hobject *duk__obj = (h); \ + duk_hobject *duk__proto = (proto); \ + DUK_UNREF(duk__thr); \ + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(duk__thr->heap, duk__obj) == NULL); \ + DUK_HOBJECT_SET_PROTOTYPE(duk__thr->heap, duk__obj, duk__proto); \ + DUK_HOBJECT_INCREF_ALLOWNULL(duk__thr, duk__proto); \ + } while (0) + +/* + * Finalizer check + */ + +#if defined(DUK_USE_HEAPPTR16) +#define DUK_HOBJECT_HAS_FINALIZER_FAST(heap,h) duk_hobject_has_finalizer_fast_raw((heap), (h)) +#else +#define DUK_HOBJECT_HAS_FINALIZER_FAST(heap,h) duk_hobject_has_finalizer_fast_raw((h)) +#endif + +/* + * Resizing and hash behavior + */ + +/* Sanity limit on max number of properties (allocated, not necessarily used). + * This is somewhat arbitrary, but if we're close to 2**32 properties some + * algorithms will fail (e.g. hash size selection, next prime selection). + * Also, we use negative array/entry table indices to indicate 'not found', + * so anything above 0x80000000 will cause trouble now. + */ +#if defined(DUK_USE_OBJSIZES16) +#define DUK_HOBJECT_MAX_PROPERTIES 0x0000ffffUL +#else +#define DUK_HOBJECT_MAX_PROPERTIES 0x3fffffffUL /* 2**30-1 ~= 1G properties */ +#endif + +/* internal align target for props allocation, must be 2*n for some n */ +#if (DUK_USE_ALIGN_BY == 4) +#define DUK_HOBJECT_ALIGN_TARGET 4 +#elif (DUK_USE_ALIGN_BY == 8) +#define DUK_HOBJECT_ALIGN_TARGET 8 +#elif (DUK_USE_ALIGN_BY == 1) +#define DUK_HOBJECT_ALIGN_TARGET 1 +#else +#error invalid DUK_USE_ALIGN_BY +#endif + +/* + * PC-to-line constants + */ + +#define DUK_PC2LINE_SKIP 64 + +/* maximum length for a SKIP-1 diffstream: 35 bits per entry, rounded up to bytes */ +#define DUK_PC2LINE_MAX_DIFF_LENGTH (((DUK_PC2LINE_SKIP - 1) * 35 + 7) / 8) + +/* + * Struct defs + */ + +struct duk_propaccessor { + duk_hobject *get; + duk_hobject *set; +}; + +union duk_propvalue { + /* The get/set pointers could be 16-bit pointer compressed but it + * would make no difference on 32-bit platforms because duk_tval is + * 8 bytes or more anyway. + */ + duk_tval v; + duk_propaccessor a; +}; + +struct duk_propdesc { + /* read-only values 'lifted' for ease of use */ + duk_small_uint_t flags; + duk_hobject *get; + duk_hobject *set; + + /* for updating (all are set to < 0 for virtual properties) */ + duk_int_t e_idx; /* prop index in 'entry part', < 0 if not there */ + duk_int_t h_idx; /* prop index in 'hash part', < 0 if not there */ + duk_int_t a_idx; /* prop index in 'array part', < 0 if not there */ +}; + +struct duk_hobject { + duk_heaphdr hdr; + + /* + * 'props' contains {key,value,flags} entries, optional array entries, and + * an optional hash lookup table for non-array entries in a single 'sliced' + * allocation. There are several layout options, which differ slightly in + * generated code size/speed and alignment/padding; duk_features.h selects + * the layout used. + * + * Layout 1 (DUK_USE_HOBJECT_LAYOUT_1): + * + * e_size * sizeof(duk_hstring *) bytes of entry keys (e_next gc reachable) + * e_size * sizeof(duk_propvalue) bytes of entry values (e_next gc reachable) + * e_size * sizeof(duk_uint8_t) bytes of entry flags (e_next gc reachable) + * a_size * sizeof(duk_tval) bytes of (opt) array values (plain only) (all gc reachable) + * h_size * sizeof(duk_uint32_t) bytes of (opt) hash indexes to entries (e_size), + * 0xffffffffUL = unused, 0xfffffffeUL = deleted + * + * Layout 2 (DUK_USE_HOBJECT_LAYOUT_2): + * + * e_size * sizeof(duk_propvalue) bytes of entry values (e_next gc reachable) + * e_size * sizeof(duk_hstring *) bytes of entry keys (e_next gc reachable) + * e_size * sizeof(duk_uint8_t) + pad bytes of entry flags (e_next gc reachable) + * a_size * sizeof(duk_tval) bytes of (opt) array values (plain only) (all gc reachable) + * h_size * sizeof(duk_uint32_t) bytes of (opt) hash indexes to entries (e_size), + * 0xffffffffUL = unused, 0xfffffffeUL = deleted + * + * Layout 3 (DUK_USE_HOBJECT_LAYOUT_3): + * + * e_size * sizeof(duk_propvalue) bytes of entry values (e_next gc reachable) + * a_size * sizeof(duk_tval) bytes of (opt) array values (plain only) (all gc reachable) + * e_size * sizeof(duk_hstring *) bytes of entry keys (e_next gc reachable) + * h_size * sizeof(duk_uint32_t) bytes of (opt) hash indexes to entries (e_size), + * 0xffffffffUL = unused, 0xfffffffeUL = deleted + * e_size * sizeof(duk_uint8_t) bytes of entry flags (e_next gc reachable) + * + * In layout 1, the 'e_next' count is rounded to 4 or 8 on platforms + * requiring 4 or 8 byte alignment. This ensures proper alignment + * for the entries, at the cost of memory footprint. However, it's + * probably preferable to use another layout on such platforms instead. + * + * In layout 2, the key and value parts are swapped to avoid padding + * the key array on platforms requiring alignment by 8. The flags part + * is padded to get alignment for array entries. The 'e_next' count does + * not need to be rounded as in layout 1. + * + * In layout 3, entry values and array values are always aligned properly, + * and assuming pointers are at most 8 bytes, so are the entry keys. Hash + * indices will be properly aligned (assuming pointers are at least 4 bytes). + * Finally, flags don't need additional alignment. This layout provides + * compact allocations without padding (even on platforms with alignment + * requirements) at the cost of a bit slower lookups. + * + * Objects with few keys don't have a hash index; keys are looked up linearly, + * which is cache efficient because the keys are consecutive. Larger objects + * have a hash index part which contains integer indexes to the entries part. + * + * A single allocation reduces memory allocation overhead but requires more + * work when any part needs to be resized. A sliced allocation for entries + * makes linear key matching faster on most platforms (more locality) and + * skimps on flags size (which would be followed by 3 bytes of padding in + * most architectures if entries were placed in a struct). + * + * 'props' also contains internal properties distinguished with a non-BMP + * prefix. Often used properties should be placed early in 'props' whenever + * possible to make accessing them as fast a possible. + */ + +#if defined(DUK_USE_HEAPPTR16) + /* Located in duk_heaphdr h_extra16. Subclasses of duk_hobject (like + * duk_hcompfunc) are not free to use h_extra16 for this reason. + */ +#else + duk_uint8_t *props; +#endif + + /* prototype: the only internal property lifted outside 'e' as it is so central */ +#if defined(DUK_USE_HEAPPTR16) + duk_uint16_t prototype16; +#else + duk_hobject *prototype; +#endif + +#if defined(DUK_USE_OBJSIZES16) + duk_uint16_t e_size16; + duk_uint16_t e_next16; + duk_uint16_t a_size16; +#if defined(DUK_USE_HOBJECT_HASH_PART) + duk_uint16_t h_size16; +#endif +#else + duk_uint32_t e_size; /* entry part size */ + duk_uint32_t e_next; /* index for next new key ([0,e_next[ are gc reachable) */ + duk_uint32_t a_size; /* array part size (entirely gc reachable) */ +#if defined(DUK_USE_HOBJECT_HASH_PART) + duk_uint32_t h_size; /* hash part size or 0 if unused */ +#endif +#endif +}; + +/* + * Exposed data + */ + +#if !defined(DUK_SINGLE_FILE) +DUK_INTERNAL_DECL duk_uint8_t duk_class_number_to_stridx[32]; +#endif /* !DUK_SINGLE_FILE */ + +/* + * Prototypes + */ + +/* alloc and init */ +DUK_INTERNAL_DECL duk_hobject *duk_hobject_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags); +DUK_INTERNAL_DECL duk_hobject *duk_hobject_alloc(duk_hthread *thr, duk_uint_t hobject_flags); +DUK_INTERNAL_DECL duk_harray *duk_harray_alloc(duk_hthread *thr, duk_uint_t hobject_flags); +DUK_INTERNAL_DECL duk_hcompfunc *duk_hcompfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags); +DUK_INTERNAL_DECL duk_hnatfunc *duk_hnatfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags); +DUK_INTERNAL_DECL duk_hboundfunc *duk_hboundfunc_alloc(duk_heap *heap, duk_uint_t hobject_flags); +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL_DECL duk_hbufobj *duk_hbufobj_alloc(duk_hthread *thr, duk_uint_t hobject_flags); +#endif +DUK_INTERNAL_DECL duk_hthread *duk_hthread_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags); +DUK_INTERNAL_DECL duk_hthread *duk_hthread_alloc(duk_hthread *thr, duk_uint_t hobject_flags); +DUK_INTERNAL_DECL duk_hdecenv *duk_hdecenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags); +DUK_INTERNAL_DECL duk_hobjenv *duk_hobjenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags); +DUK_INTERNAL_DECL duk_hproxy *duk_hproxy_alloc(duk_hthread *thr, duk_uint_t hobject_flags); + +/* resize */ +DUK_INTERNAL_DECL void duk_hobject_realloc_props(duk_hthread *thr, + duk_hobject *obj, + duk_uint32_t new_e_size, + duk_uint32_t new_a_size, + duk_uint32_t new_h_size, + duk_bool_t abandon_array); +DUK_INTERNAL_DECL void duk_hobject_resize_entrypart(duk_hthread *thr, + duk_hobject *obj, + duk_uint32_t new_e_size); +#if 0 /*unused*/ +DUK_INTERNAL_DECL void duk_hobject_resize_arraypart(duk_hthread *thr, + duk_hobject *obj, + duk_uint32_t new_a_size); +#endif + +/* low-level property functions */ +DUK_INTERNAL_DECL duk_bool_t duk_hobject_find_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx); +DUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key); +DUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx); +DUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_uint_t *out_attrs); +DUK_INTERNAL_DECL duk_tval *duk_hobject_find_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i); +DUK_INTERNAL_DECL duk_bool_t duk_hobject_get_own_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags); + +/* core property functions */ +DUK_INTERNAL_DECL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key); +DUK_INTERNAL_DECL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_tval *tv_val, duk_bool_t throw_flag); +DUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_bool_t throw_flag); +DUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key); + +/* internal property functions */ +#define DUK_DELPROP_FLAG_THROW (1U << 0) +#define DUK_DELPROP_FLAG_FORCE (1U << 1) +DUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags); +DUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key); +DUK_INTERNAL_DECL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags); +DUK_INTERNAL_DECL void duk_hobject_define_property_internal_arridx(duk_hthread *thr, duk_hobject *obj, duk_uarridx_t arr_idx, duk_small_uint_t flags); +DUK_INTERNAL_DECL duk_size_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj); +#if defined(DUK_USE_HEAPPTR16) +DUK_INTERNAL_DECL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_heap *heap, duk_hobject *obj); +#else +DUK_INTERNAL_DECL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_hobject *obj); +#endif + +/* helpers for defineProperty() and defineProperties() */ +DUK_INTERNAL_DECL void duk_hobject_prepare_property_descriptor(duk_hthread *thr, + duk_idx_t idx_in, + duk_uint_t *out_defprop_flags, + duk_idx_t *out_idx_value, + duk_hobject **out_getter, + duk_hobject **out_setter); +DUK_INTERNAL_DECL duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr, + duk_uint_t defprop_flags, + duk_hobject *obj, + duk_hstring *key, + duk_idx_t idx_value, + duk_hobject *get, + duk_hobject *set, + duk_bool_t throw_flag); + +/* Object built-in methods */ +DUK_INTERNAL_DECL void duk_hobject_object_get_own_property_descriptor(duk_hthread *thr, duk_idx_t obj_idx); +DUK_INTERNAL_DECL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_freeze); +DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_frozen); +DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_ownprop_helper(duk_hthread *thr, duk_small_uint_t required_desc_flags); + +/* internal properties */ +DUK_INTERNAL_DECL duk_tval *duk_hobject_get_internal_value_tval_ptr(duk_heap *heap, duk_hobject *obj); +DUK_INTERNAL_DECL duk_hstring *duk_hobject_get_internal_value_string(duk_heap *heap, duk_hobject *obj); +DUK_INTERNAL_DECL duk_harray *duk_hobject_get_formals(duk_hthread *thr, duk_hobject *obj); +DUK_INTERNAL_DECL duk_hobject *duk_hobject_get_varmap(duk_hthread *thr, duk_hobject *obj); + +/* hobject management functions */ +DUK_INTERNAL_DECL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj); + +/* ES2015 proxy */ +#if defined(DUK_USE_ES6_PROXY) +DUK_INTERNAL_DECL duk_bool_t duk_hobject_proxy_check(duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler); +DUK_INTERNAL_DECL duk_hobject *duk_hobject_resolve_proxy_target(duk_hobject *obj); +#endif + +/* enumeration */ +DUK_INTERNAL_DECL void duk_hobject_enumerator_create(duk_hthread *thr, duk_small_uint_t enum_flags); +DUK_INTERNAL_DECL duk_ret_t duk_hobject_get_enumerated_keys(duk_hthread *thr, duk_small_uint_t enum_flags); +DUK_INTERNAL_DECL duk_bool_t duk_hobject_enumerator_next(duk_hthread *thr, duk_bool_t get_value); + +/* macros */ +DUK_INTERNAL_DECL void duk_hobject_set_prototype_updref(duk_hthread *thr, duk_hobject *h, duk_hobject *p); + +/* pc2line */ +#if defined(DUK_USE_PC2LINE) +DUK_INTERNAL_DECL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr *instrs, duk_uint_fast32_t length); +DUK_INTERNAL_DECL duk_uint_fast32_t duk_hobject_pc2line_query(duk_hthread *thr, duk_idx_t idx_func, duk_uint_fast32_t pc); +#endif + +/* misc */ +DUK_INTERNAL_DECL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *thr, duk_hobject *h, duk_hobject *p, duk_bool_t ignore_loop); + +#if !defined(DUK_USE_OBJECT_BUILTIN) +/* These declarations are needed when related built-in is disabled and + * genbuiltins.py won't automatically emit the declerations. + */ +DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_string(duk_hthread *thr); +DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype(duk_hthread *thr); +#endif + +#endif /* DUK_HOBJECT_H_INCLUDED */ diff --git a/third_party/duktape/duk_hobject_alloc.c b/third_party/duktape/duk_hobject_alloc.c new file mode 100644 index 00000000..fd76486a --- /dev/null +++ b/third_party/duktape/duk_hobject_alloc.c @@ -0,0 +1,271 @@ +/* + * Hobject allocation. + * + * Provides primitive allocation functions for all object types (plain object, + * compiled function, native function, thread). The object return is not yet + * in "heap allocated" list and has a refcount of zero, so caller must careful. + */ + +/* XXX: In most cases there's no need for plain allocation without pushing + * to the value stack. Maybe rework contract? + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Helpers. + */ + +DUK_LOCAL void duk__init_object_parts(duk_heap *heap, duk_uint_t hobject_flags, duk_hobject *obj) { + DUK_ASSERT(obj != NULL); + /* Zeroed by caller. */ + + obj->hdr.h_flags = hobject_flags | DUK_HTYPE_OBJECT; + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(&obj->hdr) == DUK_HTYPE_OBJECT); /* Assume zero shift. */ + +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + DUK_HOBJECT_SET_PROTOTYPE(heap, obj, NULL); + DUK_HOBJECT_SET_PROPS(heap, obj, NULL); +#endif +#if defined(DUK_USE_HEAPPTR16) + /* Zero encoded pointer is required to match NULL. */ + DUK_HEAPHDR_SET_NEXT(heap, &obj->hdr, NULL); +#if defined(DUK_USE_DOUBLE_LINKED_HEAP) + DUK_HEAPHDR_SET_PREV(heap, &obj->hdr, NULL); +#endif +#endif + DUK_HEAPHDR_ASSERT_LINKS(heap, &obj->hdr); + DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, &obj->hdr); + + /* obj->props is intentionally left as NULL, and duk_hobject_props.c must deal + * with this properly. This is intentional: empty objects consume a minimum + * amount of memory. Further, an initial allocation might fail and cause + * 'obj' to "leak" (require a mark-and-sweep) since it is not reachable yet. + */ +} + +DUK_LOCAL void *duk__hobject_alloc_init(duk_hthread *thr, duk_uint_t hobject_flags, duk_size_t size) { + void *res; + + res = (void *) DUK_ALLOC_CHECKED_ZEROED(thr, size); + DUK_ASSERT(res != NULL); + duk__init_object_parts(thr->heap, hobject_flags, (duk_hobject *) res); + return res; +} + +/* + * Allocate an duk_hobject. + * + * The allocated object has no allocation for properties; the caller may + * want to force a resize if a desired size is known. + * + * The allocated object has zero reference count and is not reachable. + * The caller MUST make the object reachable and increase its reference + * count before invoking any operation that might require memory allocation. + */ + +DUK_INTERNAL duk_hobject *duk_hobject_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags) { + duk_hobject *res; + + DUK_ASSERT(heap != NULL); + + /* different memory layout, alloc size, and init */ + DUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_COMPFUNC) == 0); + DUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_NATFUNC) == 0); + DUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_BOUNDFUNC) == 0); + + res = (duk_hobject *) DUK_ALLOC_ZEROED(heap, sizeof(duk_hobject)); + if (DUK_UNLIKELY(res == NULL)) { + return NULL; + } + DUK_ASSERT(!DUK_HOBJECT_IS_THREAD(res)); + + duk__init_object_parts(heap, hobject_flags, res); + + DUK_ASSERT(!DUK_HOBJECT_IS_THREAD(res)); + return res; +} + +DUK_INTERNAL duk_hobject *duk_hobject_alloc(duk_hthread *thr, duk_uint_t hobject_flags) { + duk_hobject *res; + + res = (duk_hobject *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hobject)); + return res; +} + +DUK_INTERNAL duk_hcompfunc *duk_hcompfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags) { + duk_hcompfunc *res; + + res = (duk_hcompfunc *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hcompfunc)); +#if defined(DUK_USE_EXPLICIT_NULL_INIT) +#if defined(DUK_USE_HEAPPTR16) + /* NULL pointer is required to encode to zero, so memset is enough. */ +#else + res->data = NULL; + res->funcs = NULL; + res->bytecode = NULL; +#endif + res->lex_env = NULL; + res->var_env = NULL; +#endif + + return res; +} + +DUK_INTERNAL duk_hnatfunc *duk_hnatfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags) { + duk_hnatfunc *res; + + res = (duk_hnatfunc *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hnatfunc)); +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + res->func = NULL; +#endif + + return res; +} + +DUK_INTERNAL duk_hboundfunc *duk_hboundfunc_alloc(duk_heap *heap, duk_uint_t hobject_flags) { + duk_hboundfunc *res; + + res = (duk_hboundfunc *) DUK_ALLOC(heap, sizeof(duk_hboundfunc)); + if (!res) { + return NULL; + } + duk_memzero(res, sizeof(duk_hboundfunc)); + + duk__init_object_parts(heap, hobject_flags, &res->obj); + + DUK_TVAL_SET_UNDEFINED(&res->target); + DUK_TVAL_SET_UNDEFINED(&res->this_binding); + +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + res->args = NULL; +#endif + + return res; +} + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL duk_hbufobj *duk_hbufobj_alloc(duk_hthread *thr, duk_uint_t hobject_flags) { + duk_hbufobj *res; + + res = (duk_hbufobj *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hbufobj)); +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + res->buf = NULL; + res->buf_prop = NULL; +#endif + + DUK_HBUFOBJ_ASSERT_VALID(res); + return res; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* Allocate a new thread. + * + * Leaves the built-ins array uninitialized. The caller must either + * initialize a new global context or share existing built-ins from + * another thread. + */ +DUK_INTERNAL duk_hthread *duk_hthread_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags) { + duk_hthread *res; + + res = (duk_hthread *) DUK_ALLOC(heap, sizeof(duk_hthread)); + if (DUK_UNLIKELY(res == NULL)) { + return NULL; + } + duk_memzero(res, sizeof(duk_hthread)); + + duk__init_object_parts(heap, hobject_flags, &res->obj); + +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + res->ptr_curr_pc = NULL; + res->heap = NULL; + res->valstack = NULL; + res->valstack_end = NULL; + res->valstack_alloc_end = NULL; + res->valstack_bottom = NULL; + res->valstack_top = NULL; + res->callstack_curr = NULL; + res->resumer = NULL; + res->compile_ctx = NULL, +#if defined(DUK_USE_HEAPPTR16) + res->strs16 = NULL; +#else + res->strs = NULL; +#endif + { + duk_small_uint_t i; + for (i = 0; i < DUK_NUM_BUILTINS; i++) { + res->builtins[i] = NULL; + } + } +#endif + /* When nothing is running, API calls are in non-strict mode. */ + DUK_ASSERT(res->strict == 0); + + res->heap = heap; + + /* XXX: Any reason not to merge duk_hthread_alloc.c here? */ + return res; +} + +DUK_INTERNAL duk_hthread *duk_hthread_alloc(duk_hthread *thr, duk_uint_t hobject_flags) { + duk_hthread *res; + + res = duk_hthread_alloc_unchecked(thr->heap, hobject_flags); + if (res == NULL) { + DUK_ERROR_ALLOC_FAILED(thr); + DUK_WO_NORETURN(return NULL;); + } + return res; +} + +DUK_INTERNAL duk_harray *duk_harray_alloc(duk_hthread *thr, duk_uint_t hobject_flags) { + duk_harray *res; + + res = (duk_harray *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_harray)); + + DUK_ASSERT(res->length == 0); + + return res; +} + +DUK_INTERNAL duk_hdecenv *duk_hdecenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags) { + duk_hdecenv *res; + + res = (duk_hdecenv *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hdecenv)); +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + res->thread = NULL; + res->varmap = NULL; +#endif + + DUK_ASSERT(res->thread == NULL); + DUK_ASSERT(res->varmap == NULL); + DUK_ASSERT(res->regbase_byteoff == 0); + + return res; +} + +DUK_INTERNAL duk_hobjenv *duk_hobjenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags) { + duk_hobjenv *res; + + res = (duk_hobjenv *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hobjenv)); +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + res->target = NULL; +#endif + + DUK_ASSERT(res->target == NULL); + + return res; +} + +DUK_INTERNAL duk_hproxy *duk_hproxy_alloc(duk_hthread *thr, duk_uint_t hobject_flags) { + duk_hproxy *res; + + res = (duk_hproxy *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hproxy)); + + /* Leave ->target and ->handler uninitialized, as caller will always + * explicitly initialize them before any side effects are possible. + */ + + return res; +} diff --git a/third_party/duktape/duk_hobject_assert.c b/third_party/duktape/duk_hobject_assert.c new file mode 100644 index 00000000..5bb62a62 --- /dev/null +++ b/third_party/duktape/duk_hobject_assert.c @@ -0,0 +1,127 @@ +/* + * duk_hobject and subclass assertion helpers + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_ASSERTIONS) + +DUK_INTERNAL void duk_hobject_assert_valid(duk_hobject *h) { + DUK_ASSERT(h != NULL); + DUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE(h) || + DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FUNCTION); + DUK_ASSERT(!DUK_HOBJECT_IS_BUFOBJ(h) || + (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAYBUFFER || + DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_DATAVIEW || + DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT8ARRAY || + DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT8ARRAY || + DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY || + DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT16ARRAY || + DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT16ARRAY || + DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT32ARRAY || + DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT32ARRAY || + DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FLOAT32ARRAY || + DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FLOAT64ARRAY)); + /* Object is an Array <=> object has exotic array behavior */ + DUK_ASSERT((DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY && DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)) || + (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_ARRAY && !DUK_HOBJECT_HAS_EXOTIC_ARRAY(h))); +} + +DUK_INTERNAL void duk_harray_assert_valid(duk_harray *h) { + DUK_ASSERT(h != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_ARRAY((duk_hobject *) h)); + DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY((duk_hobject *) h)); +} + +DUK_INTERNAL void duk_hboundfunc_assert_valid(duk_hboundfunc *h) { + DUK_ASSERT(h != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_BOUNDFUNC((duk_hobject *) h)); + DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(&h->target) || + (DUK_TVAL_IS_OBJECT(&h->target) && + DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(&h->target)))); + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(&h->this_binding)); + DUK_ASSERT(h->nargs == 0 || h->args != NULL); +} + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_INTERNAL void duk_hbufobj_assert_valid(duk_hbufobj *h) { + DUK_ASSERT(h != NULL); + DUK_ASSERT(h->shift <= 3); + DUK_ASSERT(h->elem_type <= DUK_HBUFOBJ_ELEM_MAX); + DUK_ASSERT((h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT8) || + (h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT8CLAMPED) || + (h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_INT8) || + (h->shift == 1 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT16) || + (h->shift == 1 && h->elem_type == DUK_HBUFOBJ_ELEM_INT16) || + (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT32) || + (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_INT32) || + (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_FLOAT32) || + (h->shift == 3 && h->elem_type == DUK_HBUFOBJ_ELEM_FLOAT64)); + DUK_ASSERT(h->is_typedarray == 0 || h->is_typedarray == 1); + DUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) h)); + if (h->buf == NULL) { + DUK_ASSERT(h->offset == 0); + DUK_ASSERT(h->length == 0); + } else { + /* No assertions for offset or length; in particular, + * it's OK for length to be longer than underlying + * buffer. Just ensure they don't wrap when added. + */ + DUK_ASSERT(h->offset + h->length >= h->offset); + } +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +DUK_INTERNAL void duk_hcompfunc_assert_valid(duk_hcompfunc *h) { + DUK_ASSERT(h != NULL); +} + +DUK_INTERNAL void duk_hnatfunc_assert_valid(duk_hnatfunc *h) { + DUK_ASSERT(h != NULL); +} + +DUK_INTERNAL void duk_hdecenv_assert_valid(duk_hdecenv *h) { + DUK_ASSERT(h != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_DECENV((duk_hobject *) h)); + DUK_ASSERT(h->thread == NULL || h->varmap != NULL); +} + +DUK_INTERNAL void duk_hobjenv_assert_valid(duk_hobjenv *h) { + DUK_ASSERT(h != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_OBJENV((duk_hobject *) h)); + DUK_ASSERT(h->target != NULL); + DUK_ASSERT(h->has_this == 0 || h->has_this == 1); +} + +DUK_INTERNAL void duk_hproxy_assert_valid(duk_hproxy *h) { + DUK_ASSERT(h != NULL); + DUK_ASSERT(h->target != NULL); + DUK_ASSERT(h->handler != NULL); + DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ((duk_hobject *) h)); +} + +DUK_INTERNAL void duk_hthread_assert_valid(duk_hthread *thr) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) thr) == DUK_HTYPE_OBJECT); + DUK_ASSERT(DUK_HOBJECT_IS_THREAD((duk_hobject *) thr)); + DUK_ASSERT(thr->unused1 == 0); + DUK_ASSERT(thr->unused2 == 0); +} + +DUK_INTERNAL void duk_ctx_assert_valid(duk_hthread *thr) { + DUK_ASSERT(thr != NULL); + DUK_HTHREAD_ASSERT_VALID(thr); + DUK_ASSERT(thr->valstack != NULL); + DUK_ASSERT(thr->valstack_bottom != NULL); + DUK_ASSERT(thr->valstack_top != NULL); + DUK_ASSERT(thr->valstack_end != NULL); + DUK_ASSERT(thr->valstack_alloc_end != NULL); + DUK_ASSERT(thr->valstack_alloc_end >= thr->valstack); + DUK_ASSERT(thr->valstack_end >= thr->valstack); + DUK_ASSERT(thr->valstack_top >= thr->valstack); + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + DUK_ASSERT(thr->valstack_end >= thr->valstack_top); + DUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end); +} + +#endif /* DUK_USE_ASSERTIONS */ diff --git a/third_party/duktape/duk_hobject_class.c b/third_party/duktape/duk_hobject_class.c new file mode 100644 index 00000000..ba2834d7 --- /dev/null +++ b/third_party/duktape/duk_hobject_class.c @@ -0,0 +1,129 @@ +/* + * Hobject ECMAScript [[Class]]. + */ + +#include "third_party/duktape/duk_internal.h" + +#if (DUK_STRIDX_UC_ARGUMENTS > 255) +#error constant too large +#endif +#if (DUK_STRIDX_UC_ARRAY > 255) +#error constant too large +#endif +#if (DUK_STRIDX_UC_BOOLEAN > 255) +#error constant too large +#endif +#if (DUK_STRIDX_UC_DATE > 255) +#error constant too large +#endif +#if (DUK_STRIDX_UC_ERROR > 255) +#error constant too large +#endif +#if (DUK_STRIDX_UC_FUNCTION > 255) +#error constant too large +#endif +#if (DUK_STRIDX_JSON > 255) +#error constant too large +#endif +#if (DUK_STRIDX_MATH > 255) +#error constant too large +#endif +#if (DUK_STRIDX_UC_NUMBER > 255) +#error constant too large +#endif +#if (DUK_STRIDX_UC_OBJECT > 255) +#error constant too large +#endif +#if (DUK_STRIDX_REG_EXP > 255) +#error constant too large +#endif +#if (DUK_STRIDX_UC_STRING > 255) +#error constant too large +#endif +#if (DUK_STRIDX_GLOBAL > 255) +#error constant too large +#endif +#if (DUK_STRIDX_OBJ_ENV > 255) +#error constant too large +#endif +#if (DUK_STRIDX_DEC_ENV > 255) +#error constant too large +#endif +#if (DUK_STRIDX_UC_POINTER > 255) +#error constant too large +#endif +#if (DUK_STRIDX_UC_THREAD > 255) +#error constant too large +#endif +#if (DUK_STRIDX_ARRAY_BUFFER > 255) +#error constant too large +#endif +#if (DUK_STRIDX_DATA_VIEW > 255) +#error constant too large +#endif +#if (DUK_STRIDX_INT8_ARRAY > 255) +#error constant too large +#endif +#if (DUK_STRIDX_UINT8_ARRAY > 255) +#error constant too large +#endif +#if (DUK_STRIDX_UINT8_CLAMPED_ARRAY > 255) +#error constant too large +#endif +#if (DUK_STRIDX_INT16_ARRAY > 255) +#error constant too large +#endif +#if (DUK_STRIDX_UINT16_ARRAY > 255) +#error constant too large +#endif +#if (DUK_STRIDX_INT32_ARRAY > 255) +#error constant too large +#endif +#if (DUK_STRIDX_UINT32_ARRAY > 255) +#error constant too large +#endif +#if (DUK_STRIDX_FLOAT32_ARRAY > 255) +#error constant too large +#endif +#if (DUK_STRIDX_FLOAT64_ARRAY > 255) +#error constant too large +#endif +#if (DUK_STRIDX_EMPTY_STRING > 255) +#error constant too large +#endif + +/* Note: assumes that these string indexes are 8-bit, genstrings.py must ensure that */ +DUK_INTERNAL duk_uint8_t duk_class_number_to_stridx[32] = { + DUK_STRIDX_EMPTY_STRING, /* NONE, intentionally empty */ + DUK_STRIDX_UC_OBJECT, + DUK_STRIDX_UC_ARRAY, + DUK_STRIDX_UC_FUNCTION, + DUK_STRIDX_UC_ARGUMENTS, + DUK_STRIDX_UC_BOOLEAN, + DUK_STRIDX_UC_DATE, + DUK_STRIDX_UC_ERROR, + DUK_STRIDX_JSON, + DUK_STRIDX_MATH, + DUK_STRIDX_UC_NUMBER, + DUK_STRIDX_REG_EXP, + DUK_STRIDX_UC_STRING, + DUK_STRIDX_GLOBAL, + DUK_STRIDX_UC_SYMBOL, + DUK_STRIDX_OBJ_ENV, + DUK_STRIDX_DEC_ENV, + DUK_STRIDX_UC_POINTER, + DUK_STRIDX_UC_THREAD, + DUK_STRIDX_ARRAY_BUFFER, + DUK_STRIDX_DATA_VIEW, + DUK_STRIDX_INT8_ARRAY, + DUK_STRIDX_UINT8_ARRAY, + DUK_STRIDX_UINT8_CLAMPED_ARRAY, + DUK_STRIDX_INT16_ARRAY, + DUK_STRIDX_UINT16_ARRAY, + DUK_STRIDX_INT32_ARRAY, + DUK_STRIDX_UINT32_ARRAY, + DUK_STRIDX_FLOAT32_ARRAY, + DUK_STRIDX_FLOAT64_ARRAY, + DUK_STRIDX_EMPTY_STRING, /* UNUSED, intentionally empty */ + DUK_STRIDX_EMPTY_STRING, /* UNUSED, intentionally empty */ +}; diff --git a/third_party/duktape/duk_hobject_enum.c b/third_party/duktape/duk_hobject_enum.c new file mode 100644 index 00000000..19a2f9dc --- /dev/null +++ b/third_party/duktape/duk_hobject_enum.c @@ -0,0 +1,706 @@ +/* + * Object enumeration support. + * + * Creates an internal enumeration state object to be used e.g. with for-in + * enumeration. The state object contains a snapshot of target object keys + * and internal control state for enumeration. Enumerator flags allow caller + * to e.g. request internal/non-enumerable properties, and to enumerate only + * "own" properties. + * + * Also creates the result value for e.g. Object.keys() based on the same + * internal structure. + * + * This snapshot-based enumeration approach is used to simplify enumeration: + * non-snapshot-based approaches are difficult to reconcile with mutating + * the enumeration target, running multiple long-lived enumerators at the + * same time, garbage collection details, etc. The downside is that the + * enumerator object is memory inefficient especially for iterating arrays. + */ + +#include "third_party/duktape/duk_internal.h" + +/* XXX: identify enumeration target with an object index (not top of stack) */ + +/* First enumerated key index in enumerator object, must match exactly the + * number of control properties inserted to the enumerator. + */ +#define DUK__ENUM_START_INDEX 2 + +/* Current implementation suffices for ES2015 for now because there's no symbol + * sorting, so commented out for now. + */ + +/* + * Helper to sort enumeration keys using a callback for pairwise duk_hstring + * comparisons. The keys are in the enumeration object entry part, starting + * from DUK__ENUM_START_INDEX, and the entry part is dense. Entry part values + * are all "true", e.g. "1" -> true, "3" -> true, "foo" -> true, "2" -> true, + * so it suffices to just switch keys without switching values. + * + * ES2015 [[OwnPropertyKeys]] enumeration order for ordinary objects: + * (1) array indices in ascending order, + * (2) non-array-index keys in insertion order, and + * (3) symbols in insertion order. + * http://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys. + * + * This rule is applied to "own properties" at each inheritance level; + * non-duplicate parent keys always follow child keys. For example, + * an inherited array index will enumerate -after- a symbol in the + * child. + * + * Insertion sort is used because (1) it's simple and compact, (2) works + * in-place, (3) minimizes operations if data is already nearly sorted, + * (4) doesn't reorder elements considered equal. + * http://en.wikipedia.org/wiki/Insertion_sort + */ + +/* Sort key, must hold array indices, "not array index" marker, and one more + * higher value for symbols. + */ +#if !defined(DUK_USE_SYMBOL_BUILTIN) +typedef duk_uint32_t duk__sort_key_t; +#elif defined(DUK_USE_64BIT_OPS) +typedef duk_uint64_t duk__sort_key_t; +#else +typedef duk_double_t duk__sort_key_t; +#endif + +/* Get sort key for a duk_hstring. */ +DUK_LOCAL duk__sort_key_t duk__hstring_sort_key(duk_hstring *x) { + duk__sort_key_t val; + + /* For array indices [0,0xfffffffe] use the array index as is. + * For strings, use 0xffffffff, the marker 'arridx' already in + * duk_hstring. For symbols, any value above 0xffffffff works, + * as long as it is the same for all symbols; currently just add + * the masked flag field into the arridx temporary. + */ + DUK_ASSERT(x != NULL); + DUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(x) || DUK_HSTRING_GET_ARRIDX_FAST(x) == DUK_HSTRING_NO_ARRAY_INDEX); + + val = (duk__sort_key_t) DUK_HSTRING_GET_ARRIDX_FAST(x); + +#if defined(DUK_USE_SYMBOL_BUILTIN) + val = val + (duk__sort_key_t) (DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) x) & DUK_HSTRING_FLAG_SYMBOL); +#endif + + return (duk__sort_key_t) val; +} + +/* Insert element 'b' after element 'a'? */ +DUK_LOCAL duk_bool_t duk__sort_compare_es6(duk_hstring *a, duk_hstring *b, duk__sort_key_t val_b) { + duk__sort_key_t val_a; + + DUK_ASSERT(a != NULL); + DUK_ASSERT(b != NULL); + DUK_UNREF(b); /* Not actually needed now, val_b suffices. */ + + val_a = duk__hstring_sort_key(a); + + if (val_a > val_b) { + return 0; + } else { + return 1; + } +} + +DUK_LOCAL void duk__sort_enum_keys_es6(duk_hthread *thr, duk_hobject *h_obj, duk_int_fast32_t idx_start, duk_int_fast32_t idx_end) { + duk_hstring **keys; + duk_int_fast32_t idx; + + DUK_ASSERT(h_obj != NULL); + DUK_ASSERT(idx_start >= DUK__ENUM_START_INDEX); + DUK_ASSERT(idx_end >= idx_start); + DUK_UNREF(thr); + + if (idx_end <= idx_start + 1) { + return; /* Zero or one element(s). */ + } + + keys = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, h_obj); + + for (idx = idx_start + 1; idx < idx_end; idx++) { + duk_hstring *h_curr; + duk_int_fast32_t idx_insert; + duk__sort_key_t val_curr; + + h_curr = keys[idx]; + DUK_ASSERT(h_curr != NULL); + + /* Scan backwards for insertion place. This works very well + * when the elements are nearly in order which is the common + * (and optimized for) case. + */ + + val_curr = duk__hstring_sort_key(h_curr); /* Remains same during scanning. */ + for (idx_insert = idx - 1; idx_insert >= idx_start; idx_insert--) { + duk_hstring *h_insert; + h_insert = keys[idx_insert]; + DUK_ASSERT(h_insert != NULL); + + if (duk__sort_compare_es6(h_insert, h_curr, val_curr)) { + break; + } + } + /* If we're out of indices, idx_insert == idx_start - 1 and idx_insert++ + * brings us back to idx_start. + */ + idx_insert++; + DUK_ASSERT(idx_insert >= 0 && idx_insert <= idx); + + /* .-- p_insert .-- p_curr + * v v + * | ... | insert | ... | curr + */ + + /* This could also done when the keys are in order, i.e. + * idx_insert == idx. The result would be an unnecessary + * memmove() but we use an explicit check because the keys + * are very often in order already. + */ + if (idx != idx_insert) { + duk_memmove((void *) (keys + idx_insert + 1), + (const void *) (keys + idx_insert), + ((size_t) (idx - idx_insert) * sizeof(duk_hstring *))); + keys[idx_insert] = h_curr; + } + } +} + +/* + * Create an internal enumerator object E, which has its keys ordered + * to match desired enumeration ordering. Also initialize internal control + * properties for enumeration. + * + * Note: if an array was used to hold enumeration keys instead, an array + * scan would be needed to eliminate duplicates found in the prototype chain. + */ + +DUK_LOCAL void duk__add_enum_key(duk_hthread *thr, duk_hstring *k) { + /* 'k' may be unreachable on entry so must push without any + * potential for GC. + */ + duk_push_hstring(thr, k); + duk_push_true(thr); + duk_put_prop(thr, -3); +} + +DUK_LOCAL void duk__add_enum_key_stridx(duk_hthread *thr, duk_small_uint_t stridx) { + duk__add_enum_key(thr, DUK_HTHREAD_GET_STRING(thr, stridx)); +} + +DUK_INTERNAL void duk_hobject_enumerator_create(duk_hthread *thr, duk_small_uint_t enum_flags) { + duk_hobject *enum_target; + duk_hobject *curr; + duk_hobject *res; +#if defined(DUK_USE_ES6_PROXY) + duk_hobject *h_proxy_target; + duk_hobject *h_proxy_handler; + duk_hobject *h_trap_result; +#endif + duk_uint_fast32_t i, len; /* used for array, stack, and entry indices */ + duk_uint_fast32_t sort_start_index; + + DUK_ASSERT(thr != NULL); + + enum_target = duk_require_hobject(thr, -1); + DUK_ASSERT(enum_target != NULL); + + duk_push_bare_object(thr); + res = duk_known_hobject(thr, -1); + + /* [enum_target res] */ + + /* Target must be stored so that we can recheck whether or not + * keys still exist when we enumerate. This is not done if the + * enumeration result comes from a proxy trap as there is no + * real object to check against. + */ + duk_push_hobject(thr, enum_target); + duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_TARGET); /* Target is bare, plain put OK. */ + + /* Initialize index so that we skip internal control keys. */ + duk_push_int(thr, DUK__ENUM_START_INDEX); + duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_NEXT); /* Target is bare, plain put OK. */ + + /* + * Proxy object handling + */ + +#if defined(DUK_USE_ES6_PROXY) + if (DUK_LIKELY((enum_flags & DUK_ENUM_NO_PROXY_BEHAVIOR) != 0)) { + goto skip_proxy; + } + if (DUK_LIKELY(!duk_hobject_proxy_check(enum_target, + &h_proxy_target, + &h_proxy_handler))) { + goto skip_proxy; + } + + /* XXX: share code with Object.keys() Proxy handling */ + + /* In ES2015 for-in invoked the "enumerate" trap; in ES2016 "enumerate" + * has been obsoleted and "ownKeys" is used instead. + */ + DUK_DDD(DUK_DDDPRINT("proxy enumeration")); + duk_push_hobject(thr, h_proxy_handler); + if (!duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_OWN_KEYS)) { + /* No need to replace the 'enum_target' value in stack, only the + * enum_target reference. This also ensures that the original + * enum target is reachable, which keeps the proxy and the proxy + * target reachable. We do need to replace the internal _Target. + */ + DUK_DDD(DUK_DDDPRINT("no ownKeys trap, enumerate proxy target instead")); + DUK_DDD(DUK_DDDPRINT("h_proxy_target=%!O", (duk_heaphdr *) h_proxy_target)); + enum_target = h_proxy_target; + + duk_push_hobject(thr, enum_target); /* -> [ ... enum_target res handler undefined target ] */ + duk_put_prop_stridx_short(thr, -4, DUK_STRIDX_INT_TARGET); /* Target is bare, plain put OK. */ + + duk_pop_2(thr); /* -> [ ... enum_target res ] */ + goto skip_proxy; + } + + /* [ ... enum_target res handler trap ] */ + duk_insert(thr, -2); + duk_push_hobject(thr, h_proxy_target); /* -> [ ... enum_target res trap handler target ] */ + duk_call_method(thr, 1 /*nargs*/); /* -> [ ... enum_target res trap_result ] */ + h_trap_result = duk_require_hobject(thr, -1); + DUK_UNREF(h_trap_result); + + duk_proxy_ownkeys_postprocess(thr, h_proxy_target, enum_flags); + /* -> [ ... enum_target res trap_result keys_array ] */ + + /* Copy cleaned up trap result keys into the enumerator object. */ + /* XXX: result is a dense array; could make use of that. */ + DUK_ASSERT(duk_is_array(thr, -1)); + len = (duk_uint_fast32_t) duk_get_length(thr, -1); + for (i = 0; i < len; i++) { + (void) duk_get_prop_index(thr, -1, (duk_uarridx_t) i); + DUK_ASSERT(duk_is_string(thr, -1)); /* postprocess cleaned up */ + /* [ ... enum_target res trap_result keys_array val ] */ + duk_push_true(thr); + /* [ ... enum_target res trap_result keys_array val true ] */ + duk_put_prop(thr, -5); + } + /* [ ... enum_target res trap_result keys_array ] */ + duk_pop_2(thr); + duk_remove_m2(thr); + + /* [ ... res ] */ + + /* The internal _Target property is kept pointing to the original + * enumeration target (the proxy object), so that the enumerator + * 'next' operation can read property values if so requested. The + * fact that the _Target is a proxy disables key existence check + * during enumeration. + */ + DUK_DDD(DUK_DDDPRINT("proxy enumeration, final res: %!O", (duk_heaphdr *) res)); + goto compact_and_return; + + skip_proxy: +#endif /* DUK_USE_ES6_PROXY */ + + curr = enum_target; + sort_start_index = DUK__ENUM_START_INDEX; + DUK_ASSERT(DUK_HOBJECT_GET_ENEXT(res) == DUK__ENUM_START_INDEX); + while (curr) { + duk_uint_fast32_t sort_end_index; +#if !defined(DUK_USE_PREFER_SIZE) + duk_bool_t need_sort = 0; +#endif + duk_bool_t cond; + + /* Enumeration proceeds by inheritance level. Virtual + * properties need to be handled specially, followed by + * array part, and finally entry part. + * + * If there are array index keys in the entry part or any + * other risk of the ES2015 [[OwnPropertyKeys]] order being + * violated, need_sort is set and an explicit ES2015 sort is + * done for the inheritance level. + */ + + /* XXX: inheriting from proxy */ + + /* + * Virtual properties. + * + * String and buffer indices are virtual and always enumerable, + * 'length' is virtual and non-enumerable. Array and arguments + * object props have special behavior but are concrete. + * + * String and buffer objects don't have an array part so as long + * as virtual array index keys are enumerated first, we don't + * need to set need_sort. + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + cond = DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr) || DUK_HOBJECT_IS_BUFOBJ(curr); +#else + cond = DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr); +#endif + cond = cond && !(enum_flags & DUK_ENUM_EXCLUDE_STRINGS); + if (cond) { + duk_bool_t have_length = 1; + + /* String and buffer enumeration behavior is identical now, + * so use shared handler. + */ + if (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr)) { + duk_hstring *h_val; + h_val = duk_hobject_get_internal_value_string(thr->heap, curr); + DUK_ASSERT(h_val != NULL); /* string objects must not created without internal value */ + len = (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h_val); + } +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + else { + duk_hbufobj *h_bufobj; + DUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ(curr)); + h_bufobj = (duk_hbufobj *) curr; + + if (h_bufobj == NULL || !h_bufobj->is_typedarray) { + /* Zero length seems like a good behavior for neutered buffers. + * ArrayBuffer (non-view) and DataView don't have index properties + * or .length property. + */ + len = 0; + have_length = 0; + } else { + /* There's intentionally no check for + * current underlying buffer length. + */ + len = (duk_uint_fast32_t) (h_bufobj->length >> h_bufobj->shift); + } + } +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + + for (i = 0; i < len; i++) { + duk_hstring *k; + + /* This is a bit fragile: the string is not + * reachable until it is pushed by the helper. + */ + k = duk_heap_strtable_intern_u32_checked(thr, (duk_uint32_t) i); + DUK_ASSERT(k); + + duk__add_enum_key(thr, k); + + /* [enum_target res] */ + } + + /* 'length' and other virtual properties are not + * enumerable, but are included if non-enumerable + * properties are requested. + */ + + if (have_length && (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE)) { + duk__add_enum_key_stridx(thr, DUK_STRIDX_LENGTH); + } + } + + /* + * Array part + */ + + cond = !(enum_flags & DUK_ENUM_EXCLUDE_STRINGS); + if (cond) { + for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(curr); i++) { + duk_hstring *k; + duk_tval *tv; + + tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, curr, i); + if (DUK_TVAL_IS_UNUSED(tv)) { + continue; + } + k = duk_heap_strtable_intern_u32_checked(thr, (duk_uint32_t) i); /* Fragile reachability. */ + DUK_ASSERT(k); + + duk__add_enum_key(thr, k); + + /* [enum_target res] */ + } + + if (DUK_HOBJECT_HAS_EXOTIC_ARRAY(curr)) { + /* Array .length comes after numeric indices. */ + if (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) { + duk__add_enum_key_stridx(thr, DUK_STRIDX_LENGTH); + } + } + } + + /* + * Entries part + */ + + for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(curr); i++) { + duk_hstring *k; + + k = DUK_HOBJECT_E_GET_KEY(thr->heap, curr, i); + if (!k) { + continue; + } + if (!(enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) && + !DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(thr->heap, curr, i)) { + continue; + } + if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(k))) { + if (!(enum_flags & DUK_ENUM_INCLUDE_HIDDEN) && + DUK_HSTRING_HAS_HIDDEN(k)) { + continue; + } + if (!(enum_flags & DUK_ENUM_INCLUDE_SYMBOLS)) { + continue; + } +#if !defined(DUK_USE_PREFER_SIZE) + need_sort = 1; +#endif + } else { + DUK_ASSERT(!DUK_HSTRING_HAS_HIDDEN(k)); /* would also have symbol flag */ + if (enum_flags & DUK_ENUM_EXCLUDE_STRINGS) { + continue; + } + } + if (DUK_HSTRING_HAS_ARRIDX(k)) { + /* This in currently only possible if the + * object has no array part: the array part + * is exhaustive when it is present. + */ +#if !defined(DUK_USE_PREFER_SIZE) + need_sort = 1; +#endif + } else { + if (enum_flags & DUK_ENUM_ARRAY_INDICES_ONLY) { + continue; + } + } + + DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, curr, i) || + !DUK_TVAL_IS_UNUSED(&DUK_HOBJECT_E_GET_VALUE_PTR(thr->heap, curr, i)->v)); + + duk__add_enum_key(thr, k); + + /* [enum_target res] */ + } + + /* Sort enumerated keys according to ES2015 requirements for + * the "inheritance level" just processed. This is far from + * optimal, ES2015 semantics could be achieved more efficiently + * by handling array index string keys (and symbol keys) + * specially above in effect doing the sort inline. + * + * Skip the sort if array index sorting is requested because + * we must consider all keys, also inherited, so an explicit + * sort is done for the whole result after we're done with the + * prototype chain. + * + * Also skip the sort if need_sort == 0, i.e. we know for + * certain that the enumerated order is already correct. + */ + sort_end_index = DUK_HOBJECT_GET_ENEXT(res); + + if (!(enum_flags & DUK_ENUM_SORT_ARRAY_INDICES)) { +#if defined(DUK_USE_PREFER_SIZE) + duk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) sort_start_index, (duk_int_fast32_t) sort_end_index); +#else + if (need_sort) { + DUK_DDD(DUK_DDDPRINT("need to sort")); + duk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) sort_start_index, (duk_int_fast32_t) sort_end_index); + } else { + DUK_DDD(DUK_DDDPRINT("no need to sort")); + } +#endif + } + + sort_start_index = sort_end_index; + + if (enum_flags & DUK_ENUM_OWN_PROPERTIES_ONLY) { + break; + } + + curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr); + } + + /* [enum_target res] */ + + duk_remove_m2(thr); + + /* [res] */ + + if (enum_flags & DUK_ENUM_SORT_ARRAY_INDICES) { + /* Some E5/E5.1 algorithms require that array indices are iterated + * in a strictly ascending order. This is the case for e.g. + * Array.prototype.forEach() and JSON.stringify() PropertyList + * handling. The caller can request an explicit sort in these + * cases. + */ + + /* Sort to ES2015 order which works for pure array incides but + * also for mixed keys. + */ + duk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) DUK__ENUM_START_INDEX, (duk_int_fast32_t) DUK_HOBJECT_GET_ENEXT(res)); + } + +#if defined(DUK_USE_ES6_PROXY) + compact_and_return: +#endif + /* compact; no need to seal because object is internal */ + duk_hobject_compact_props(thr, res); + + DUK_DDD(DUK_DDDPRINT("created enumerator object: %!iT", (duk_tval *) duk_get_tval(thr, -1))); +} + +/* + * Returns non-zero if a key and/or value was enumerated, and: + * + * [enum] -> [key] (get_value == 0) + * [enum] -> [key value] (get_value == 1) + * + * Returns zero without pushing anything on the stack otherwise. + */ +DUK_INTERNAL duk_bool_t duk_hobject_enumerator_next(duk_hthread *thr, duk_bool_t get_value) { + duk_hobject *e; + duk_hobject *enum_target; + duk_hstring *res = NULL; + duk_uint_fast32_t idx; + duk_bool_t check_existence; + + DUK_ASSERT(thr != NULL); + + /* [... enum] */ + + e = duk_require_hobject(thr, -1); + + /* XXX use get tval ptr, more efficient */ + duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_NEXT); + idx = (duk_uint_fast32_t) duk_require_uint(thr, -1); + duk_pop(thr); + DUK_DDD(DUK_DDDPRINT("enumeration: index is: %ld", (long) idx)); + + /* Enumeration keys are checked against the enumeration target (to see + * that they still exist). In the proxy enumeration case _Target will + * be the proxy, and checking key existence against the proxy is not + * required (or sensible, as the keys may be fully virtual). + */ + duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_TARGET); + enum_target = duk_require_hobject(thr, -1); + DUK_ASSERT(enum_target != NULL); +#if defined(DUK_USE_ES6_PROXY) + check_existence = (!DUK_HOBJECT_IS_PROXY(enum_target)); +#else + check_existence = 1; +#endif + duk_pop(thr); /* still reachable */ + + DUK_DDD(DUK_DDDPRINT("getting next enum value, enum_target=%!iO, enumerator=%!iT", + (duk_heaphdr *) enum_target, (duk_tval *) duk_get_tval(thr, -1))); + + /* no array part */ + for (;;) { + duk_hstring *k; + + if (idx >= DUK_HOBJECT_GET_ENEXT(e)) { + DUK_DDD(DUK_DDDPRINT("enumeration: ran out of elements")); + break; + } + + /* we know these because enum objects are internally created */ + k = DUK_HOBJECT_E_GET_KEY(thr->heap, e, idx); + DUK_ASSERT(k != NULL); + DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, e, idx)); + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(&DUK_HOBJECT_E_GET_VALUE(thr->heap, e, idx).v)); + + idx++; + + /* recheck that the property still exists */ + if (check_existence && !duk_hobject_hasprop_raw(thr, enum_target, k)) { + DUK_DDD(DUK_DDDPRINT("property deleted during enumeration, skip")); + continue; + } + + DUK_DDD(DUK_DDDPRINT("enumeration: found element, key: %!O", (duk_heaphdr *) k)); + res = k; + break; + } + + DUK_DDD(DUK_DDDPRINT("enumeration: updating next index to %ld", (long) idx)); + + duk_push_u32(thr, (duk_uint32_t) idx); + duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_NEXT); + + /* [... enum] */ + + if (res) { + duk_push_hstring(thr, res); + if (get_value) { + duk_push_hobject(thr, enum_target); + duk_dup_m2(thr); /* -> [... enum key enum_target key] */ + duk_get_prop(thr, -2); /* -> [... enum key enum_target val] */ + duk_remove_m2(thr); /* -> [... enum key val] */ + duk_remove(thr, -3); /* -> [... key val] */ + } else { + duk_remove_m2(thr); /* -> [... key] */ + } + return 1; + } else { + duk_pop(thr); /* -> [...] */ + return 0; + } +} + +/* + * Get enumerated keys in an ECMAScript array. Matches Object.keys() behavior + * described in E5 Section 15.2.3.14. + */ + +DUK_INTERNAL duk_ret_t duk_hobject_get_enumerated_keys(duk_hthread *thr, duk_small_uint_t enum_flags) { + duk_hobject *e; + duk_hstring **keys; + duk_tval *tv; + duk_uint_fast32_t count; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(duk_get_hobject(thr, -1) != NULL); + + /* Create a temporary enumerator to get the (non-duplicated) key list; + * the enumerator state is initialized without being needed, but that + * has little impact. + */ + + duk_hobject_enumerator_create(thr, enum_flags); + e = duk_known_hobject(thr, -1); + + /* [enum_target enum res] */ + + /* Create dense result array to exact size. */ + DUK_ASSERT(DUK_HOBJECT_GET_ENEXT(e) >= DUK__ENUM_START_INDEX); + count = (duk_uint32_t) (DUK_HOBJECT_GET_ENEXT(e) - DUK__ENUM_START_INDEX); + + /* XXX: uninit would be OK */ + tv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) count); + DUK_ASSERT(count == 0 || tv != NULL); + DUK_ASSERT(!duk_is_bare_object(thr, -1)); + + /* Fill result array, no side effects. */ + + keys = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, e); + keys += DUK__ENUM_START_INDEX; + + while (count-- > 0) { + duk_hstring *k; + + k = *keys++; + DUK_ASSERT(k != NULL); /* enumerator must have no keys deleted */ + + DUK_TVAL_SET_STRING(tv, k); + tv++; + DUK_HSTRING_INCREF(thr, k); + } + + /* [enum_target enum res] */ + duk_remove_m2(thr); + + /* [enum_target res] */ + + return 1; /* return 1 to allow callers to tail call */ +} diff --git a/third_party/duktape/duk_hobject_misc.c b/third_party/duktape/duk_hobject_misc.c new file mode 100644 index 00000000..5db8e40c --- /dev/null +++ b/third_party/duktape/duk_hobject_misc.c @@ -0,0 +1,53 @@ +/* + * Misc support functions + */ + +#include "third_party/duktape/duk_internal.h" + +DUK_INTERNAL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *thr, duk_hobject *h, duk_hobject *p, duk_bool_t ignore_loop) { + duk_uint_t sanity; + + DUK_ASSERT(thr != NULL); + + /* False if the object is NULL or the prototype 'p' is NULL. + * In particular, false if both are NULL (don't compare equal). + */ + if (h == NULL || p == NULL) { + return 0; + } + + sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY; + do { + if (h == p) { + return 1; + } + + if (sanity-- == 0) { + if (ignore_loop) { + break; + } else { + DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT); + DUK_WO_NORETURN(return 0;); + } + } + h = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h); + } while (h); + + return 0; +} + +DUK_INTERNAL void duk_hobject_set_prototype_updref(duk_hthread *thr, duk_hobject *h, duk_hobject *p) { +#if defined(DUK_USE_REFERENCE_COUNTING) + duk_hobject *tmp; + + DUK_ASSERT(h); + tmp = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h); + DUK_HOBJECT_SET_PROTOTYPE(thr->heap, h, p); + DUK_HOBJECT_INCREF_ALLOWNULL(thr, p); /* avoid problems if p == h->prototype */ + DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); +#else + DUK_ASSERT(h); + DUK_UNREF(thr); + DUK_HOBJECT_SET_PROTOTYPE(thr->heap, h, p); +#endif +} diff --git a/third_party/duktape/duk_hobject_pc2line.c b/third_party/duktape/duk_hobject_pc2line.c new file mode 100644 index 00000000..159120a1 --- /dev/null +++ b/third_party/duktape/duk_hobject_pc2line.c @@ -0,0 +1,244 @@ +/* + * Helpers for creating and querying pc2line debug data, which + * converts a bytecode program counter to a source line number. + * + * The run-time pc2line data is bit-packed, and documented in: + * + * doc/function-objects.rst + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_PC2LINE) + +/* Generate pc2line data for an instruction sequence, leaving a buffer on stack top. */ +DUK_INTERNAL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr *instrs, duk_uint_fast32_t length) { + duk_hbuffer_dynamic *h_buf; + duk_bitencoder_ctx be_ctx_alloc; + duk_bitencoder_ctx *be_ctx = &be_ctx_alloc; + duk_uint32_t *hdr; + duk_size_t new_size; + duk_uint_fast32_t num_header_entries; + duk_uint_fast32_t curr_offset; + duk_int_fast32_t curr_line, next_line, diff_line; + duk_uint_fast32_t curr_pc; + duk_uint_fast32_t hdr_index; + + DUK_ASSERT(length <= DUK_COMPILER_MAX_BYTECODE_LENGTH); + + num_header_entries = (length + DUK_PC2LINE_SKIP - 1) / DUK_PC2LINE_SKIP; + curr_offset = (duk_uint_fast32_t) (sizeof(duk_uint32_t) + num_header_entries * sizeof(duk_uint32_t) * 2); + + duk_push_dynamic_buffer(thr, (duk_size_t) curr_offset); + h_buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, -1); + DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h_buf) && !DUK_HBUFFER_HAS_EXTERNAL(h_buf)); + + hdr = (duk_uint32_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h_buf); + DUK_ASSERT(hdr != NULL); + hdr[0] = (duk_uint32_t) length; /* valid pc range is [0, length[ */ + + curr_pc = 0U; + while (curr_pc < length) { + new_size = (duk_size_t) (curr_offset + DUK_PC2LINE_MAX_DIFF_LENGTH); + duk_hbuffer_resize(thr, h_buf, new_size); + + hdr = (duk_uint32_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h_buf); + DUK_ASSERT(hdr != NULL); + DUK_ASSERT(curr_pc < length); + hdr_index = 1 + (curr_pc / DUK_PC2LINE_SKIP) * 2; + curr_line = (duk_int_fast32_t) instrs[curr_pc].line; + hdr[hdr_index + 0] = (duk_uint32_t) curr_line; + hdr[hdr_index + 1] = (duk_uint32_t) curr_offset; + +#if 0 + DUK_DDD(DUK_DDDPRINT("hdr[%ld]: pc=%ld line=%ld offset=%ld", + (long) (curr_pc / DUK_PC2LINE_SKIP), + (long) curr_pc, + (long) hdr[hdr_index + 0], + (long) hdr[hdr_index + 1])); +#endif + + duk_memzero(be_ctx, sizeof(*be_ctx)); + be_ctx->data = ((duk_uint8_t *) hdr) + curr_offset; + be_ctx->length = (duk_size_t) DUK_PC2LINE_MAX_DIFF_LENGTH; + + for (;;) { + curr_pc++; + if ( ((curr_pc % DUK_PC2LINE_SKIP) == 0) || /* end of diff run */ + (curr_pc >= length) ) { /* end of bytecode */ + break; + } + DUK_ASSERT(curr_pc < length); + next_line = (duk_int32_t) instrs[curr_pc].line; + diff_line = next_line - curr_line; + +#if 0 + DUK_DDD(DUK_DDDPRINT("curr_line=%ld, next_line=%ld -> diff_line=%ld", + (long) curr_line, (long) next_line, (long) diff_line)); +#endif + + if (diff_line == 0) { + /* 0 */ + duk_be_encode(be_ctx, 0, 1); + } else if (diff_line >= 1 && diff_line <= 4) { + /* 1 0 <2 bits> */ + duk_be_encode(be_ctx, (duk_uint32_t) ((0x02 << 2) + (diff_line - 1)), 4); + } else if (diff_line >= -0x80 && diff_line <= 0x7f) { + /* 1 1 0 <8 bits> */ + DUK_ASSERT(diff_line + 0x80 >= 0 && diff_line + 0x80 <= 0xff); + duk_be_encode(be_ctx, (duk_uint32_t) ((0x06 << 8) + (diff_line + 0x80)), 11); + } else { + /* 1 1 1 <32 bits> + * Encode in two parts to avoid bitencode 24-bit limitation + */ + duk_be_encode(be_ctx, (duk_uint32_t) ((0x07 << 16) + ((next_line >> 16) & 0xffff)), 19); + duk_be_encode(be_ctx, (duk_uint32_t) (next_line & 0xffff), 16); + } + + curr_line = next_line; + } + + duk_be_finish(be_ctx); + DUK_ASSERT(!be_ctx->truncated); + + /* be_ctx->offset == length of encoded bitstream */ + curr_offset += (duk_uint_fast32_t) be_ctx->offset; + } + + /* compact */ + new_size = (duk_size_t) curr_offset; + duk_hbuffer_resize(thr, h_buf, new_size); + + (void) duk_to_fixed_buffer(thr, -1, NULL); + + DUK_DDD(DUK_DDDPRINT("final pc2line data: pc_limit=%ld, length=%ld, %lf bits/opcode --> %!ixT", + (long) length, (long) new_size, (double) new_size * 8.0 / (double) length, + (duk_tval *) duk_get_tval(thr, -1))); +} + +/* PC is unsigned. If caller does PC arithmetic and gets a negative result, + * it will map to a large PC which is out of bounds and causes a zero to be + * returned. + */ +DUK_LOCAL duk_uint_fast32_t duk__hobject_pc2line_query_raw(duk_hthread *thr, duk_hbuffer_fixed *buf, duk_uint_fast32_t pc) { + duk_bitdecoder_ctx bd_ctx_alloc; + duk_bitdecoder_ctx *bd_ctx = &bd_ctx_alloc; + duk_uint32_t *hdr; + duk_uint_fast32_t start_offset; + duk_uint_fast32_t pc_limit; + duk_uint_fast32_t hdr_index; + duk_uint_fast32_t pc_base; + duk_uint_fast32_t n; + duk_uint_fast32_t curr_line; + + DUK_ASSERT(buf != NULL); + DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) buf) && !DUK_HBUFFER_HAS_EXTERNAL((duk_hbuffer *) buf)); + DUK_UNREF(thr); + + /* + * Use the index in the header to find the right starting point + */ + + hdr_index = pc / DUK_PC2LINE_SKIP; + pc_base = hdr_index * DUK_PC2LINE_SKIP; + n = pc - pc_base; + + if (DUK_HBUFFER_FIXED_GET_SIZE(buf) <= sizeof(duk_uint32_t)) { + DUK_DD(DUK_DDPRINT("pc2line lookup failed: buffer is smaller than minimal header")); + goto pc2line_error; + } + + hdr = (duk_uint32_t *) (void *) DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, buf); + pc_limit = hdr[0]; + if (pc >= pc_limit) { + /* Note: pc is unsigned and cannot be negative */ + DUK_DD(DUK_DDPRINT("pc2line lookup failed: pc out of bounds (pc=%ld, limit=%ld)", + (long) pc, (long) pc_limit)); + goto pc2line_error; + } + + curr_line = hdr[1 + hdr_index * 2]; + start_offset = hdr[1 + hdr_index * 2 + 1]; + if ((duk_size_t) start_offset > DUK_HBUFFER_FIXED_GET_SIZE(buf)) { + DUK_DD(DUK_DDPRINT("pc2line lookup failed: start_offset out of bounds (start_offset=%ld, buffer_size=%ld)", + (long) start_offset, (long) DUK_HBUFFER_GET_SIZE((duk_hbuffer *) buf))); + goto pc2line_error; + } + + /* + * Iterate the bitstream (line diffs) until PC is reached + */ + + duk_memzero(bd_ctx, sizeof(*bd_ctx)); + bd_ctx->data = ((duk_uint8_t *) hdr) + start_offset; + bd_ctx->length = (duk_size_t) (DUK_HBUFFER_FIXED_GET_SIZE(buf) - start_offset); + +#if 0 + DUK_DDD(DUK_DDDPRINT("pc2line lookup: pc=%ld -> hdr_index=%ld, pc_base=%ld, n=%ld, start_offset=%ld", + (long) pc, (long) hdr_index, (long) pc_base, (long) n, (long) start_offset)); +#endif + + while (n > 0) { +#if 0 + DUK_DDD(DUK_DDDPRINT("lookup: n=%ld, curr_line=%ld", (long) n, (long) curr_line)); +#endif + + if (duk_bd_decode_flag(bd_ctx)) { + if (duk_bd_decode_flag(bd_ctx)) { + if (duk_bd_decode_flag(bd_ctx)) { + /* 1 1 1 <32 bits> */ + duk_uint_fast32_t t; + t = duk_bd_decode(bd_ctx, 16); /* workaround: max nbits = 24 now */ + t = (t << 16) + duk_bd_decode(bd_ctx, 16); + curr_line = t; + } else { + /* 1 1 0 <8 bits> */ + duk_uint_fast32_t t; + t = duk_bd_decode(bd_ctx, 8); + curr_line = curr_line + t - 0x80; + } + } else { + /* 1 0 <2 bits> */ + duk_uint_fast32_t t; + t = duk_bd_decode(bd_ctx, 2); + curr_line = curr_line + t + 1; + } + } else { + /* 0: no change */ + } + + n--; + } + + DUK_DDD(DUK_DDDPRINT("pc2line lookup result: pc %ld -> line %ld", (long) pc, (long) curr_line)); + return curr_line; + + pc2line_error: + DUK_D(DUK_DPRINT("pc2line conversion failed for pc=%ld", (long) pc)); + return 0; +} + +DUK_INTERNAL duk_uint_fast32_t duk_hobject_pc2line_query(duk_hthread *thr, duk_idx_t idx_func, duk_uint_fast32_t pc) { + duk_hbuffer_fixed *pc2line; + duk_uint_fast32_t line; + + /* XXX: now that pc2line is used by the debugger quite heavily in + * checked execution, this should be optimized to avoid value stack + * and perhaps also implement some form of pc2line caching (see + * future work in debugger.rst). + */ + + duk_xget_owndataprop_stridx_short(thr, idx_func, DUK_STRIDX_INT_PC2LINE); + pc2line = (duk_hbuffer_fixed *) (void *) duk_get_hbuffer(thr, -1); + if (pc2line != NULL) { + DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) pc2line) && !DUK_HBUFFER_HAS_EXTERNAL((duk_hbuffer *) pc2line)); + line = duk__hobject_pc2line_query_raw(thr, pc2line, (duk_uint_fast32_t) pc); + } else { + line = 0; + } + duk_pop(thr); + + return line; +} + +#endif /* DUK_USE_PC2LINE */ diff --git a/third_party/duktape/duk_hobject_props.c b/third_party/duktape/duk_hobject_props.c new file mode 100644 index 00000000..07c850a5 --- /dev/null +++ b/third_party/duktape/duk_hobject_props.c @@ -0,0 +1,6208 @@ +/* + * duk_hobject property access functionality. + * + * This is very central functionality for size, performance, and compliance. + * It is also rather intricate; see hobject-algorithms.rst for discussion on + * the algorithms and memory-management.rst for discussion on refcounts and + * side effect issues. + * + * Notes: + * + * - It might be tempting to assert "refcount nonzero" for objects + * being operated on, but that's not always correct: objects with + * a zero refcount may be operated on by the refcount implementation + * (finalization) for instance. Hence, no refcount assertions are made. + * + * - Many operations (memory allocation, identifier operations, etc) + * may cause arbitrary side effects (e.g. through GC and finalization). + * These side effects may invalidate duk_tval pointers which point to + * areas subject to reallocation (like value stack). Heap objects + * themselves have stable pointers. Holding heap object pointers or + * duk_tval copies is not problematic with respect to side effects; + * care must be taken when holding and using argument duk_tval pointers. + * + * - If a finalizer is executed, it may operate on the the same object + * we're currently dealing with. For instance, the finalizer might + * delete a certain property which has already been looked up and + * confirmed to exist. Ideally finalizers would be disabled if GC + * happens during property access. At the moment property table realloc + * disables finalizers, and all DECREFs may cause arbitrary changes so + * handle DECREF carefully. + * + * - The order of operations for a DECREF matters. When DECREF is executed, + * the entire object graph must be consistent; note that a refzero may + * lead to a mark-and-sweep through a refcount finalizer. Use NORZ macros + * and an explicit DUK_REFZERO_CHECK_xxx() if achieving correct order is hard. + */ + +/* + * XXX: array indices are mostly typed as duk_uint32_t here; duk_uarridx_t + * might be more appropriate. + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Local defines + */ + +#define DUK__NO_ARRAY_INDEX DUK_HSTRING_NO_ARRAY_INDEX + +/* Marker values for hash part. */ +#define DUK__HASH_UNUSED DUK_HOBJECT_HASHIDX_UNUSED +#define DUK__HASH_DELETED DUK_HOBJECT_HASHIDX_DELETED + +/* Valstack space that suffices for all local calls, excluding any recursion + * into ECMAScript or Duktape/C calls (Proxy, getters, etc). + */ +#define DUK__VALSTACK_SPACE 10 + +/* Valstack space allocated especially for proxy lookup which does a + * recursive property lookup. + */ +#define DUK__VALSTACK_PROXY_LOOKUP 20 + +/* + * Local prototypes + */ + +DUK_LOCAL_DECL duk_bool_t duk__check_arguments_map_for_get(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc); +DUK_LOCAL_DECL void duk__check_arguments_map_for_put(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc, duk_bool_t throw_flag); +DUK_LOCAL_DECL void duk__check_arguments_map_for_delete(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc); + +DUK_LOCAL_DECL duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr, duk_hobject *obj, duk_uint32_t old_len, duk_uint32_t new_len, duk_bool_t force_flag, duk_uint32_t *out_result_len); +DUK_LOCAL_DECL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject *obj); + +DUK_LOCAL_DECL duk_bool_t duk__get_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags); +DUK_LOCAL_DECL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_uint32_t arr_idx, duk_propdesc *out_desc, duk_small_uint_t flags); + +DUK_LOCAL_DECL void duk__abandon_array_part(duk_hthread *thr, duk_hobject *obj); +DUK_LOCAL_DECL void duk__grow_props_for_array_item(duk_hthread *thr, duk_hobject *obj, duk_uint32_t highest_arr_idx); + +/* + * Misc helpers + */ + +/* Convert a duk_tval number (caller checks) to a 32-bit index. Returns + * DUK__NO_ARRAY_INDEX if the number is not whole or not a valid array + * index. + */ +/* XXX: for fastints, could use a variant which assumes a double duk_tval + * (and doesn't need to check for fastint again). + */ +DUK_LOCAL duk_uint32_t duk__tval_number_to_arr_idx(duk_tval *tv) { + duk_double_t dbl; + duk_uint32_t idx; + + DUK_ASSERT(tv != NULL); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); + + /* -0 is accepted here as index 0 because ToString(-0) == "0" which is + * in canonical form and thus an array index. + */ + dbl = DUK_TVAL_GET_NUMBER(tv); + idx = (duk_uint32_t) dbl; + if (duk_double_equals((duk_double_t) idx, dbl)) { + /* Is whole and within 32 bit range. If the value happens to be 0xFFFFFFFF, + * it's not a valid array index but will then match DUK__NO_ARRAY_INDEX. + */ + return idx; + } + return DUK__NO_ARRAY_INDEX; +} + +#if defined(DUK_USE_FASTINT) +/* Convert a duk_tval fastint (caller checks) to a 32-bit index. */ +DUK_LOCAL duk_uint32_t duk__tval_fastint_to_arr_idx(duk_tval *tv) { + duk_int64_t t; + + DUK_ASSERT(tv != NULL); + DUK_ASSERT(DUK_TVAL_IS_FASTINT(tv)); + + t = DUK_TVAL_GET_FASTINT(tv); + if (((duk_uint64_t) t & ~DUK_U64_CONSTANT(0xffffffff)) != 0) { + /* Catches >0x100000000 and negative values. */ + return DUK__NO_ARRAY_INDEX; + } + + /* If the value happens to be 0xFFFFFFFF, it's not a valid array index + * but will then match DUK__NO_ARRAY_INDEX. + */ + return (duk_uint32_t) t; +} +#endif /* DUK_USE_FASTINT */ + +/* Convert a duk_tval on the value stack (in a trusted index we don't validate) + * to a string or symbol using ES2015 ToPropertyKey(): + * http://www.ecma-international.org/ecma-262/6.0/#sec-topropertykey. + * + * Also check if it's a valid array index and return that (or DUK__NO_ARRAY_INDEX + * if not). + */ +DUK_LOCAL duk_uint32_t duk__to_property_key(duk_hthread *thr, duk_idx_t idx, duk_hstring **out_h) { + duk_uint32_t arr_idx; + duk_hstring *h; + duk_tval *tv_dst; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(out_h != NULL); + DUK_ASSERT(duk_is_valid_index(thr, idx)); + DUK_ASSERT(idx < 0); + + /* XXX: The revised ES2015 ToPropertyKey() handling (ES5.1 was just + * ToString()) involves a ToPrimitive(), a symbol check, and finally + * a ToString(). Figure out the best way to have a good fast path + * but still be compliant and share code. + */ + + tv_dst = DUK_GET_TVAL_NEGIDX(thr, idx); /* intentionally unvalidated */ + if (DUK_TVAL_IS_STRING(tv_dst)) { + /* Most important path: strings and plain symbols are used as + * is. For symbols the array index check below is unnecessary + * (they're never valid array indices) but checking that the + * string is a symbol would make the plain string path slower + * unnecessarily. + */ + h = DUK_TVAL_GET_STRING(tv_dst); + } else { + h = duk_to_property_key_hstring(thr, idx); + } + DUK_ASSERT(h != NULL); + *out_h = h; + + arr_idx = DUK_HSTRING_GET_ARRIDX_FAST(h); + return arr_idx; +} + +DUK_LOCAL duk_uint32_t duk__push_tval_to_property_key(duk_hthread *thr, duk_tval *tv_key, duk_hstring **out_h) { + duk_push_tval(thr, tv_key); /* XXX: could use an unsafe push here */ + return duk__to_property_key(thr, -1, out_h); +} + +/* String is an own (virtual) property of a plain buffer. */ +DUK_LOCAL duk_bool_t duk__key_is_plain_buf_ownprop(duk_hthread *thr, duk_hbuffer *buf, duk_hstring *key, duk_uint32_t arr_idx) { + DUK_UNREF(thr); + + /* Virtual index properties. Checking explicitly for + * 'arr_idx != DUK__NO_ARRAY_INDEX' is not necessary + * because DUK__NO_ARRAY_INDEXi is always larger than + * maximum allowed buffer size. + */ + DUK_ASSERT(DUK__NO_ARRAY_INDEX >= DUK_HBUFFER_GET_SIZE(buf)); + if (arr_idx < DUK_HBUFFER_GET_SIZE(buf)) { + return 1; + } + + /* Other virtual properties. */ + return (key == DUK_HTHREAD_STRING_LENGTH(thr)); +} + +/* + * Helpers for managing property storage size + */ + +/* Get default hash part size for a certain entry part size. */ +#if defined(DUK_USE_HOBJECT_HASH_PART) +DUK_LOCAL duk_uint32_t duk__get_default_h_size(duk_uint32_t e_size) { + DUK_ASSERT(e_size <= DUK_HOBJECT_MAX_PROPERTIES); + + if (e_size >= DUK_USE_HOBJECT_HASH_PROP_LIMIT) { + duk_uint32_t res; + duk_uint32_t tmp; + + /* Hash size should be 2^N where N is chosen so that 2^N is + * larger than e_size. Extra shifting is used to ensure hash + * is relatively sparse. + */ + tmp = e_size; + res = 2; /* Result will be 2 ** (N + 1). */ + while (tmp >= 0x40) { + tmp >>= 6; + res <<= 6; + } + while (tmp != 0) { + tmp >>= 1; + res <<= 1; + } + DUK_ASSERT((DUK_HOBJECT_MAX_PROPERTIES << 2U) > DUK_HOBJECT_MAX_PROPERTIES); /* Won't wrap, even shifted by 2. */ + DUK_ASSERT(res > e_size); + return res; + } else { + return 0; + } +} +#endif /* USE_PROP_HASH_PART */ + +/* Get minimum entry part growth for a certain size. */ +DUK_LOCAL duk_uint32_t duk__get_min_grow_e(duk_uint32_t e_size) { + duk_uint32_t res; + + res = (e_size + DUK_USE_HOBJECT_ENTRY_MINGROW_ADD) / DUK_USE_HOBJECT_ENTRY_MINGROW_DIVISOR; + DUK_ASSERT(res >= 1); /* important for callers */ + return res; +} + +/* Get minimum array part growth for a certain size. */ +DUK_LOCAL duk_uint32_t duk__get_min_grow_a(duk_uint32_t a_size) { + duk_uint32_t res; + + res = (a_size + DUK_USE_HOBJECT_ARRAY_MINGROW_ADD) / DUK_USE_HOBJECT_ARRAY_MINGROW_DIVISOR; + DUK_ASSERT(res >= 1); /* important for callers */ + return res; +} + +/* Count actually used entry part entries (non-NULL keys). */ +DUK_LOCAL duk_uint32_t duk__count_used_e_keys(duk_hthread *thr, duk_hobject *obj) { + duk_uint_fast32_t i; + duk_uint_fast32_t n = 0; + duk_hstring **e; + + DUK_ASSERT(obj != NULL); + DUK_UNREF(thr); + + e = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, obj); + for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) { + if (*e++) { + n++; + } + } + return (duk_uint32_t) n; +} + +/* Count actually used array part entries and array minimum size. + * NOTE: 'out_min_size' can be computed much faster by starting from the + * end and breaking out early when finding first used entry, but this is + * not needed now. + */ +DUK_LOCAL void duk__compute_a_stats(duk_hthread *thr, duk_hobject *obj, duk_uint32_t *out_used, duk_uint32_t *out_min_size) { + duk_uint_fast32_t i; + duk_uint_fast32_t used = 0; + duk_uint_fast32_t highest_idx = (duk_uint_fast32_t) -1; /* see below */ + duk_tval *a; + + DUK_ASSERT(obj != NULL); + DUK_ASSERT(out_used != NULL); + DUK_ASSERT(out_min_size != NULL); + DUK_UNREF(thr); + + a = DUK_HOBJECT_A_GET_BASE(thr->heap, obj); + for (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) { + duk_tval *tv = a++; + if (!DUK_TVAL_IS_UNUSED(tv)) { + used++; + highest_idx = i; + } + } + + /* Initial value for highest_idx is -1 coerced to unsigned. This + * is a bit odd, but (highest_idx + 1) will then wrap to 0 below + * for out_min_size as intended. + */ + + *out_used = (duk_uint32_t) used; + *out_min_size = (duk_uint32_t) (highest_idx + 1); /* 0 if no used entries */ +} + +/* Check array density and indicate whether or not the array part should be abandoned. */ +DUK_LOCAL duk_bool_t duk__abandon_array_density_check(duk_uint32_t a_used, duk_uint32_t a_size) { + /* + * Array abandon check; abandon if: + * + * new_used / new_size < limit + * new_used < limit * new_size || limit is 3 bits fixed point + * new_used < limit' / 8 * new_size || *8 + * 8*new_used < limit' * new_size || :8 + * new_used < limit' * (new_size / 8) + * + * Here, new_used = a_used, new_size = a_size. + * + * Note: some callers use approximate values for a_used and/or a_size + * (e.g. dropping a '+1' term). This doesn't affect the usefulness + * of the check, but may confuse debugging. + */ + + return (a_used < DUK_USE_HOBJECT_ARRAY_ABANDON_LIMIT * (a_size >> 3)); +} + +/* Fast check for extending array: check whether or not a slow density check is required. */ +DUK_LOCAL duk_bool_t duk__abandon_array_slow_check_required(duk_uint32_t arr_idx, duk_uint32_t old_size) { + duk_uint32_t new_size_min; + + /* + * In a fast check we assume old_size equals old_used (i.e., existing + * array is fully dense). + * + * Slow check if: + * + * (new_size - old_size) / old_size > limit + * new_size - old_size > limit * old_size + * new_size > (1 + limit) * old_size || limit' is 3 bits fixed point + * new_size > (1 + (limit' / 8)) * old_size || * 8 + * 8 * new_size > (8 + limit') * old_size || : 8 + * new_size > (8 + limit') * (old_size / 8) + * new_size > limit'' * (old_size / 8) || limit'' = 9 -> max 25% increase + * arr_idx + 1 > limit'' * (old_size / 8) + * + * This check doesn't work well for small values, so old_size is rounded + * up for the check (and the '+ 1' of arr_idx can be ignored in practice): + * + * arr_idx > limit'' * ((old_size + 7) / 8) + */ + + new_size_min = arr_idx + 1; + return (new_size_min >= DUK_USE_HOBJECT_ARRAY_ABANDON_MINSIZE) && + (arr_idx > DUK_USE_HOBJECT_ARRAY_FAST_RESIZE_LIMIT * ((old_size + 7) >> 3)); +} + +DUK_LOCAL duk_bool_t duk__abandon_array_check(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) { + duk_uint32_t min_size; + duk_uint32_t old_used; + duk_uint32_t old_size; + + if (!duk__abandon_array_slow_check_required(arr_idx, DUK_HOBJECT_GET_ASIZE(obj))) { + DUK_DDD(DUK_DDDPRINT("=> fast resize is OK")); + return 0; + } + + duk__compute_a_stats(thr, obj, &old_used, &old_size); + + DUK_DDD(DUK_DDDPRINT("abandon check, array stats: old_used=%ld, old_size=%ld, arr_idx=%ld", + (long) old_used, (long) old_size, (long) arr_idx)); + + min_size = arr_idx + 1; +#if defined(DUK_USE_OBJSIZES16) + if (min_size > DUK_UINT16_MAX) { + goto do_abandon; + } +#endif + DUK_UNREF(min_size); + + /* Note: intentionally use approximations to shave a few instructions: + * a_used = old_used (accurate: old_used + 1) + * a_size = arr_idx (accurate: arr_idx + 1) + */ + if (duk__abandon_array_density_check(old_used, arr_idx)) { + DUK_DD(DUK_DDPRINT("write to new array entry beyond current length, " + "decided to abandon array part (would become too sparse)")); + + /* Abandoning requires a props allocation resize and + * 'rechecks' the valstack, invalidating any existing + * valstack value pointers. + */ + goto do_abandon; + } + + DUK_DDD(DUK_DDDPRINT("=> decided to keep array part")); + return 0; + + do_abandon: + duk__abandon_array_part(thr, obj); + DUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj)); + return 1; +} + +DUK_LOCAL duk_tval *duk__obtain_arridx_slot_slowpath(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) { + /* + * Array needs to grow, but we don't want it becoming too sparse. + * If it were to become sparse, abandon array part, moving all + * array entries into the entries part (for good). + * + * Since we don't keep track of actual density (used vs. size) of + * the array part, we need to estimate somehow. The check is made + * in two parts: + * + * - Check whether the resize need is small compared to the + * current size (relatively); if so, resize without further + * checking (essentially we assume that the original part is + * "dense" so that the result would be dense enough). + * + * - Otherwise, compute the resize using an actual density + * measurement based on counting the used array entries. + */ + + DUK_DDD(DUK_DDDPRINT("write to new array requires array resize, decide whether to do a " + "fast resize without abandon check (arr_idx=%ld, old_size=%ld)", + (long) arr_idx, (long) DUK_HOBJECT_GET_ASIZE(obj))); + + if (DUK_UNLIKELY(duk__abandon_array_check(thr, arr_idx, obj) != 0)) { + DUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj)); + return NULL; + } + + DUK_DD(DUK_DDPRINT("write to new array entry beyond current length, " + "decided to extend current allocation")); + + /* In principle it's possible to run out of memory extending the + * array but with the allocation going through if we were to abandon + * the array part and try again. In practice this should be rare + * because abandoned arrays have a higher per-entry footprint. + */ + + duk__grow_props_for_array_item(thr, obj, arr_idx); + + DUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(obj)); + DUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(obj)); + return DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx); +} + +DUK_LOCAL DUK_INLINE duk_tval *duk__obtain_arridx_slot(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) { + if (DUK_LIKELY(arr_idx < DUK_HOBJECT_GET_ASIZE(obj))) { + return DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx); + } else { + return duk__obtain_arridx_slot_slowpath(thr, arr_idx, obj); + } +} + +/* + * Proxy helpers + */ + +#if defined(DUK_USE_ES6_PROXY) +DUK_INTERNAL duk_bool_t duk_hobject_proxy_check(duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler) { + duk_hproxy *h_proxy; + + DUK_ASSERT(obj != NULL); + DUK_ASSERT(out_target != NULL); + DUK_ASSERT(out_handler != NULL); + + /* Caller doesn't need to check exotic proxy behavior (but does so for + * some fast paths). + */ + if (DUK_LIKELY(!DUK_HOBJECT_IS_PROXY(obj))) { + return 0; + } + h_proxy = (duk_hproxy *) obj; + DUK_HPROXY_ASSERT_VALID(h_proxy); + + DUK_ASSERT(h_proxy->handler != NULL); + DUK_ASSERT(h_proxy->target != NULL); + *out_handler = h_proxy->handler; + *out_target = h_proxy->target; + + return 1; +} +#endif /* DUK_USE_ES6_PROXY */ + +/* Get Proxy target object. If the argument is not a Proxy, return it as is. + * If a Proxy is revoked, an error is thrown. + */ +#if defined(DUK_USE_ES6_PROXY) +DUK_INTERNAL duk_hobject *duk_hobject_resolve_proxy_target(duk_hobject *obj) { + DUK_ASSERT(obj != NULL); + + /* Resolve Proxy targets until Proxy chain ends. No explicit check for + * a Proxy loop: user code cannot create such a loop (it would only be + * possible by editing duk_hproxy references directly). + */ + + while (DUK_HOBJECT_IS_PROXY(obj)) { + duk_hproxy *h_proxy; + + h_proxy = (duk_hproxy *) obj; + DUK_HPROXY_ASSERT_VALID(h_proxy); + obj = h_proxy->target; + DUK_ASSERT(obj != NULL); + } + + DUK_ASSERT(obj != NULL); + return obj; +} +#endif /* DUK_USE_ES6_PROXY */ + +#if defined(DUK_USE_ES6_PROXY) +DUK_LOCAL duk_bool_t duk__proxy_check_prop(duk_hthread *thr, duk_hobject *obj, duk_small_uint_t stridx_trap, duk_tval *tv_key, duk_hobject **out_target) { + duk_hobject *h_handler; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(obj != NULL); + DUK_ASSERT(tv_key != NULL); + DUK_ASSERT(out_target != NULL); + + if (!duk_hobject_proxy_check(obj, out_target, &h_handler)) { + return 0; + } + DUK_ASSERT(*out_target != NULL); + DUK_ASSERT(h_handler != NULL); + + /* XXX: At the moment Duktape accesses internal keys like _Finalizer using a + * normal property set/get which would allow a proxy handler to interfere with + * such behavior and to get access to internal key strings. This is not a problem + * as such because internal key strings can be created in other ways too (e.g. + * through buffers). The best fix is to change Duktape internal lookups to + * skip proxy behavior. Until that, internal property accesses bypass the + * proxy and are applied to the target (as if the handler did not exist). + * This has some side effects, see test-bi-proxy-internal-keys.js. + */ + + if (DUK_TVAL_IS_STRING(tv_key)) { + duk_hstring *h_key = (duk_hstring *) DUK_TVAL_GET_STRING(tv_key); + DUK_ASSERT(h_key != NULL); + if (DUK_HSTRING_HAS_HIDDEN(h_key)) { + /* Symbol accesses must go through proxy lookup in ES2015. + * Hidden symbols behave like Duktape 1.x internal keys + * and currently won't. + */ + DUK_DDD(DUK_DDDPRINT("hidden key, skip proxy handler and apply to target")); + return 0; + } + } + + /* The handler is looked up with a normal property lookup; it may be an + * accessor or the handler object itself may be a proxy object. If the + * handler is a proxy, we need to extend the valstack as we make a + * recursive proxy check without a function call in between (in fact + * there is no limit to the potential recursion here). + * + * (For sanity, proxy creation rejects another proxy object as either + * the handler or the target at the moment so recursive proxy cases + * are not realized now.) + */ + + /* XXX: C recursion limit if proxies are allowed as handler/target values */ + + duk_require_stack(thr, DUK__VALSTACK_PROXY_LOOKUP); + duk_push_hobject(thr, h_handler); + if (duk_get_prop_stridx_short(thr, -1, stridx_trap)) { + /* -> [ ... handler trap ] */ + duk_insert(thr, -2); /* -> [ ... trap handler ] */ + + /* stack prepped for func call: [ ... trap handler ] */ + return 1; + } else { + duk_pop_2_unsafe(thr); + return 0; + } +} +#endif /* DUK_USE_ES6_PROXY */ + +/* + * Reallocate property allocation, moving properties to the new allocation. + * + * Includes key compaction, rehashing, and can also optionally abandon + * the array part, 'migrating' array entries into the beginning of the + * new entry part. + * + * There is no support for in-place reallocation or just compacting keys + * without resizing the property allocation. This is intentional to keep + * code size minimal, but would be useful future work. + * + * The implementation is relatively straightforward, except for the array + * abandonment process. Array abandonment requires that new string keys + * are interned, which may trigger GC. All keys interned so far must be + * reachable for GC at all times and correctly refcounted for; valstack is + * used for that now. + * + * Also, a GC triggered during this reallocation process must not interfere + * with the object being resized. This is currently controlled by preventing + * finalizers (as they may affect ANY object) and object compaction in + * mark-and-sweep. It would suffice to protect only this particular object + * from compaction, however. DECREF refzero cascades are side effect free + * and OK. + * + * Note: because we need to potentially resize the valstack (as part + * of abandoning the array part), any tval pointers to the valstack + * will become invalid after this call. + */ + +DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr, + duk_hobject *obj, + duk_uint32_t new_e_size, + duk_uint32_t new_a_size, + duk_uint32_t new_h_size, + duk_bool_t abandon_array) { + duk_small_uint_t prev_ms_base_flags; + duk_uint32_t new_alloc_size; + duk_uint32_t new_e_size_adjusted; + duk_uint8_t *new_p; + duk_hstring **new_e_k; + duk_propvalue *new_e_pv; + duk_uint8_t *new_e_f; + duk_tval *new_a; + duk_uint32_t *new_h; + duk_uint32_t new_e_next; + duk_uint_fast32_t i; + duk_size_t array_copy_size; +#if defined(DUK_USE_ASSERTIONS) + duk_bool_t prev_error_not_allowed; +#endif + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(obj != NULL); + DUK_ASSERT(!abandon_array || new_a_size == 0); /* if abandon_array, new_a_size must be 0 */ + DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL || (DUK_HOBJECT_GET_ESIZE(obj) == 0 && DUK_HOBJECT_GET_ASIZE(obj) == 0)); + DUK_ASSERT(new_h_size == 0 || new_h_size >= new_e_size); /* required to guarantee success of rehashing, + * intentionally use unadjusted new_e_size + */ + DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)); + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + DUK_STATS_INC(thr->heap, stats_object_realloc_props); + + /* + * Pre resize assertions. + */ + +#if defined(DUK_USE_ASSERTIONS) + /* XXX: pre-checks (such as no duplicate keys) */ +#endif + + /* + * For property layout 1, tweak e_size to ensure that the whole entry + * part (key + val + flags) is a suitable multiple for alignment + * (platform specific). + * + * Property layout 2 does not require this tweaking and is preferred + * on low RAM platforms requiring alignment. + */ + +#if defined(DUK_USE_HOBJECT_LAYOUT_2) || defined(DUK_USE_HOBJECT_LAYOUT_3) + DUK_DDD(DUK_DDDPRINT("using layout 2 or 3, no need to pad e_size: %ld", (long) new_e_size)); + new_e_size_adjusted = new_e_size; +#elif defined(DUK_USE_HOBJECT_LAYOUT_1) && (DUK_HOBJECT_ALIGN_TARGET == 1) + DUK_DDD(DUK_DDDPRINT("using layout 1, but no need to pad e_size: %ld", (long) new_e_size)); + new_e_size_adjusted = new_e_size; +#elif defined(DUK_USE_HOBJECT_LAYOUT_1) && ((DUK_HOBJECT_ALIGN_TARGET == 4) || (DUK_HOBJECT_ALIGN_TARGET == 8)) + new_e_size_adjusted = (new_e_size + (duk_uint32_t) DUK_HOBJECT_ALIGN_TARGET - 1U) & + (~((duk_uint32_t) DUK_HOBJECT_ALIGN_TARGET - 1U)); + DUK_DDD(DUK_DDDPRINT("using layout 1, and alignment target is %ld, adjusted e_size: %ld -> %ld", + (long) DUK_HOBJECT_ALIGN_TARGET, (long) new_e_size, (long) new_e_size_adjusted)); + DUK_ASSERT(new_e_size_adjusted >= new_e_size); +#else +#error invalid hobject layout defines +#endif + + /* + * Debug logging after adjustment. + */ + + DUK_DDD(DUK_DDDPRINT("attempt to resize hobject %p props (%ld -> %ld bytes), from {p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld} to " + "{e_size=%ld,a_size=%ld,h_size=%ld}, abandon_array=%ld, unadjusted new_e_size=%ld", + (void *) obj, + (long) DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj), + DUK_HOBJECT_GET_ASIZE(obj), + DUK_HOBJECT_GET_HSIZE(obj)), + (long) DUK_HOBJECT_P_COMPUTE_SIZE(new_e_size_adjusted, new_a_size, new_h_size), + (void *) DUK_HOBJECT_GET_PROPS(thr->heap, obj), + (long) DUK_HOBJECT_GET_ESIZE(obj), + (long) DUK_HOBJECT_GET_ENEXT(obj), + (long) DUK_HOBJECT_GET_ASIZE(obj), + (long) DUK_HOBJECT_GET_HSIZE(obj), + (long) new_e_size_adjusted, + (long) new_a_size, + (long) new_h_size, + (long) abandon_array, + (long) new_e_size)); + + /* + * Property count check. This is the only point where we ensure that + * we don't get more (allocated) property space that we can handle. + * There aren't hard limits as such, but some algorithms may fail + * if we get too close to the 4G property limit. + * + * Since this works based on allocation size (not actually used size), + * the limit is a bit approximate but good enough in practice. + */ + + if (new_e_size_adjusted + new_a_size > DUK_HOBJECT_MAX_PROPERTIES) { + DUK_ERROR_ALLOC_FAILED(thr); + DUK_WO_NORETURN(return;); + } +#if defined(DUK_USE_OBJSIZES16) + if (new_e_size_adjusted > DUK_UINT16_MAX || new_a_size > DUK_UINT16_MAX) { + /* If caller gave us sizes larger than what we can store, + * fail memory safely with an internal error rather than + * truncating the sizes. + */ + DUK_ERROR_INTERNAL(thr); + DUK_WO_NORETURN(return;); + } +#endif + + /* + * Compute new alloc size and alloc new area. + * + * The new area is not tracked in the heap at all, so it's critical + * we get to free/keep it in a controlled manner. + */ + +#if defined(DUK_USE_ASSERTIONS) + /* Whole path must be error throw free, but we may be called from + * within error handling so can't assert for error_not_allowed == 0. + */ + prev_error_not_allowed = thr->heap->error_not_allowed; + thr->heap->error_not_allowed = 1; +#endif + prev_ms_base_flags = thr->heap->ms_base_flags; + thr->heap->ms_base_flags |= + DUK_MS_FLAG_NO_OBJECT_COMPACTION; /* Avoid attempt to compact the current object (all objects really). */ + thr->heap->pf_prevent_count++; /* Avoid finalizers. */ + DUK_ASSERT(thr->heap->pf_prevent_count != 0); /* Wrap. */ + + new_alloc_size = DUK_HOBJECT_P_COMPUTE_SIZE(new_e_size_adjusted, new_a_size, new_h_size); + DUK_DDD(DUK_DDDPRINT("new hobject allocation size is %ld", (long) new_alloc_size)); + if (new_alloc_size == 0) { + DUK_ASSERT(new_e_size_adjusted == 0); + DUK_ASSERT(new_a_size == 0); + DUK_ASSERT(new_h_size == 0); + new_p = NULL; + } else { + /* Alloc may trigger mark-and-sweep but no compaction, and + * cannot throw. + */ +#if 0 /* XXX: inject test */ + if (1) { + new_p = NULL; + goto alloc_failed; + } +#endif + new_p = (duk_uint8_t *) DUK_ALLOC(thr->heap, new_alloc_size); + if (new_p == NULL) { + /* NULL always indicates alloc failure because + * new_alloc_size > 0. + */ + goto alloc_failed; + } + } + + /* Set up pointers to the new property area: this is hidden behind a macro + * because it is memory layout specific. + */ + DUK_HOBJECT_P_SET_REALLOC_PTRS(new_p, new_e_k, new_e_pv, new_e_f, new_a, new_h, + new_e_size_adjusted, new_a_size, new_h_size); + DUK_UNREF(new_h); /* happens when hash part dropped */ + new_e_next = 0; + + /* if new_p == NULL, all of these pointers are NULL */ + DUK_ASSERT((new_p != NULL) || + (new_e_k == NULL && new_e_pv == NULL && new_e_f == NULL && + new_a == NULL && new_h == NULL)); + + DUK_DDD(DUK_DDDPRINT("new alloc size %ld, new_e_k=%p, new_e_pv=%p, new_e_f=%p, new_a=%p, new_h=%p", + (long) new_alloc_size, (void *) new_e_k, (void *) new_e_pv, (void *) new_e_f, + (void *) new_a, (void *) new_h)); + + /* + * Migrate array part to start of entries if requested. + * + * Note: from an enumeration perspective the order of entry keys matters. + * Array keys should appear wherever they appeared before the array abandon + * operation. (This no longer matters much because keys are ES2015 sorted.) + */ + + if (abandon_array) { + /* Assuming new_a_size == 0, and that entry part contains + * no conflicting keys, refcounts do not need to be adjusted for + * the values, as they remain exactly the same. + * + * The keys, however, need to be interned, incref'd, and be + * reachable for GC. Any intern attempt may trigger a GC and + * claim any non-reachable strings, so every key must be reachable + * at all times. Refcounts must be correct to satisfy refcount + * assertions. + * + * A longjmp must not occur here, as the new_p allocation would + * leak. Refcounts would come out correctly as the interned + * strings are valstack tracked. + */ + DUK_ASSERT(new_a_size == 0); + + DUK_STATS_INC(thr->heap, stats_object_abandon_array); + + for (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) { + duk_tval *tv1; + duk_tval *tv2; + duk_hstring *key; + + DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL); + + tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i); + if (DUK_TVAL_IS_UNUSED(tv1)) { + continue; + } + + DUK_ASSERT(new_p != NULL && new_e_k != NULL && + new_e_pv != NULL && new_e_f != NULL); + + /* + * Intern key via the valstack to ensure reachability behaves + * properly. We must avoid longjmp's here so use non-checked + * primitives. + * + * Note: duk_check_stack() potentially reallocs the valstack, + * invalidating any duk_tval pointers to valstack. Callers + * must be careful. + */ + +#if 0 /* XXX: inject test */ + if (1) { + goto abandon_error; + } +#endif + /* Never shrinks; auto-adds DUK_VALSTACK_INTERNAL_EXTRA, which + * is generous. + */ + if (!duk_check_stack(thr, 1)) { + goto abandon_error; + } + DUK_ASSERT_VALSTACK_SPACE(thr, 1); + key = duk_heap_strtable_intern_u32(thr->heap, (duk_uint32_t) i); + if (key == NULL) { + goto abandon_error; + } + duk_push_hstring(thr, key); /* keep key reachable for GC etc; guaranteed not to fail */ + + /* Key is now reachable in the valstack, don't INCREF + * the new allocation yet (we'll steal the refcounts + * from the value stack once all keys are done). + */ + + new_e_k[new_e_next] = key; + tv2 = &new_e_pv[new_e_next].v; /* array entries are all plain values */ + DUK_TVAL_SET_TVAL(tv2, tv1); + new_e_f[new_e_next] = DUK_PROPDESC_FLAG_WRITABLE | + DUK_PROPDESC_FLAG_ENUMERABLE | + DUK_PROPDESC_FLAG_CONFIGURABLE; + new_e_next++; + + /* Note: new_e_next matches pushed temp key count, and nothing can + * fail above between the push and this point. + */ + } + + /* Steal refcounts from value stack. */ + DUK_DDD(DUK_DDDPRINT("abandon array: pop %ld key temps from valstack", (long) new_e_next)); + duk_pop_n_nodecref_unsafe(thr, (duk_idx_t) new_e_next); + } + + /* + * Copy keys and values in the entry part (compacting them at the same time). + */ + + for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) { + duk_hstring *key; + + DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL); + + key = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i); + if (key == NULL) { + continue; + } + + DUK_ASSERT(new_p != NULL && new_e_k != NULL && + new_e_pv != NULL && new_e_f != NULL); + + new_e_k[new_e_next] = key; + new_e_pv[new_e_next] = DUK_HOBJECT_E_GET_VALUE(thr->heap, obj, i); + new_e_f[new_e_next] = DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, i); + new_e_next++; + } + /* the entries [new_e_next, new_e_size_adjusted[ are left uninitialized on purpose (ok, not gc reachable) */ + + /* + * Copy array elements to new array part. If the new array part is + * larger, initialize the unused entries as UNUSED because they are + * GC reachable. + */ + +#if defined(DUK_USE_ASSERTIONS) + /* Caller must have decref'd values above new_a_size (if that is necessary). */ + if (!abandon_array) { + for (i = new_a_size; i < DUK_HOBJECT_GET_ASIZE(obj); i++) { + duk_tval *tv; + tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i); + DUK_ASSERT(DUK_TVAL_IS_UNUSED(tv)); + } + } +#endif + if (new_a_size > DUK_HOBJECT_GET_ASIZE(obj)) { + array_copy_size = sizeof(duk_tval) * DUK_HOBJECT_GET_ASIZE(obj); + } else { + array_copy_size = sizeof(duk_tval) * new_a_size; + } + + DUK_ASSERT(new_a != NULL || array_copy_size == 0U); + DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL || array_copy_size == 0U); + DUK_ASSERT(DUK_HOBJECT_GET_ASIZE(obj) > 0 || array_copy_size == 0U); + duk_memcpy_unsafe((void *) new_a, + (const void *) DUK_HOBJECT_A_GET_BASE(thr->heap, obj), + array_copy_size); + + for (i = DUK_HOBJECT_GET_ASIZE(obj); i < new_a_size; i++) { + duk_tval *tv = &new_a[i]; + DUK_TVAL_SET_UNUSED(tv); + } + + /* + * Rebuild the hash part always from scratch (guaranteed to finish + * as long as caller gave consistent parameters). + * + * Any resize of hash part requires rehashing. In addition, by rehashing + * get rid of any elements marked deleted (DUK__HASH_DELETED) which is critical + * to ensuring the hash part never fills up. + */ + +#if defined(DUK_USE_HOBJECT_HASH_PART) + if (new_h_size == 0) { + DUK_DDD(DUK_DDDPRINT("no hash part, no rehash")); + } else { + duk_uint32_t mask; + + DUK_ASSERT(new_h != NULL); + + /* fill new_h with u32 0xff = UNUSED */ + DUK_ASSERT(new_h_size > 0); + duk_memset(new_h, 0xff, sizeof(duk_uint32_t) * new_h_size); + + DUK_ASSERT(new_e_next <= new_h_size); /* equality not actually possible */ + + mask = new_h_size - 1; + for (i = 0; i < new_e_next; i++) { + duk_hstring *key = new_e_k[i]; + duk_uint32_t j, step; + + DUK_ASSERT(key != NULL); + j = DUK_HSTRING_GET_HASH(key) & mask; + step = 1; /* Cache friendly but clustering prone. */ + + for (;;) { + DUK_ASSERT(new_h[j] != DUK__HASH_DELETED); /* should never happen */ + if (new_h[j] == DUK__HASH_UNUSED) { + DUK_DDD(DUK_DDDPRINT("rebuild hit %ld -> %ld", (long) j, (long) i)); + new_h[j] = (duk_uint32_t) i; + break; + } + DUK_DDD(DUK_DDDPRINT("rebuild miss %ld, step %ld", (long) j, (long) step)); + j = (j + step) & mask; + + /* Guaranteed to finish (hash is larger than #props). */ + } + } + } +#endif /* DUK_USE_HOBJECT_HASH_PART */ + + /* + * Nice debug log. + */ + + DUK_DD(DUK_DDPRINT("resized hobject %p props (%ld -> %ld bytes), from {p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld} to " + "{p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld}, abandon_array=%ld, unadjusted new_e_size=%ld", + (void *) obj, + (long) DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj), + DUK_HOBJECT_GET_ASIZE(obj), + DUK_HOBJECT_GET_HSIZE(obj)), + (long) new_alloc_size, + (void *) DUK_HOBJECT_GET_PROPS(thr->heap, obj), + (long) DUK_HOBJECT_GET_ESIZE(obj), + (long) DUK_HOBJECT_GET_ENEXT(obj), + (long) DUK_HOBJECT_GET_ASIZE(obj), + (long) DUK_HOBJECT_GET_HSIZE(obj), + (void *) new_p, + (long) new_e_size_adjusted, + (long) new_e_next, + (long) new_a_size, + (long) new_h_size, + (long) abandon_array, + (long) new_e_size)); + + /* + * All done, switch properties ('p') allocation to new one. + */ + + DUK_FREE_CHECKED(thr, DUK_HOBJECT_GET_PROPS(thr->heap, obj)); /* NULL obj->p is OK */ + DUK_HOBJECT_SET_PROPS(thr->heap, obj, new_p); + DUK_HOBJECT_SET_ESIZE(obj, new_e_size_adjusted); + DUK_HOBJECT_SET_ENEXT(obj, new_e_next); + DUK_HOBJECT_SET_ASIZE(obj, new_a_size); + DUK_HOBJECT_SET_HSIZE(obj, new_h_size); + + /* Clear array part flag only after switching. */ + if (abandon_array) { + DUK_HOBJECT_CLEAR_ARRAY_PART(obj); + } + + DUK_DDD(DUK_DDDPRINT("resize result: %!O", (duk_heaphdr *) obj)); + + DUK_ASSERT(thr->heap->pf_prevent_count > 0); + thr->heap->pf_prevent_count--; + thr->heap->ms_base_flags = prev_ms_base_flags; +#if defined(DUK_USE_ASSERTIONS) + DUK_ASSERT(thr->heap->error_not_allowed == 1); + thr->heap->error_not_allowed = prev_error_not_allowed; +#endif + + /* + * Post resize assertions. + */ + +#if defined(DUK_USE_ASSERTIONS) + /* XXX: post-checks (such as no duplicate keys) */ +#endif + return; + + /* + * Abandon array failed. We don't need to DECREF anything + * because the references in the new allocation are not + * INCREF'd until abandon is complete. The string interned + * keys are on the value stack and are handled normally by + * unwind. + */ + + abandon_error: + alloc_failed: + DUK_D(DUK_DPRINT("object property table resize failed")); + + DUK_FREE_CHECKED(thr, new_p); /* OK for NULL. */ + + thr->heap->pf_prevent_count--; + thr->heap->ms_base_flags = prev_ms_base_flags; +#if defined(DUK_USE_ASSERTIONS) + DUK_ASSERT(thr->heap->error_not_allowed == 1); + thr->heap->error_not_allowed = prev_error_not_allowed; +#endif + + DUK_ERROR_ALLOC_FAILED(thr); + DUK_WO_NORETURN(return;); +} + +/* + * Helpers to resize properties allocation on specific needs. + */ + +DUK_INTERNAL void duk_hobject_resize_entrypart(duk_hthread *thr, + duk_hobject *obj, + duk_uint32_t new_e_size) { + duk_uint32_t old_e_size; + duk_uint32_t new_a_size; + duk_uint32_t new_h_size; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(obj != NULL); + + old_e_size = DUK_HOBJECT_GET_ESIZE(obj); + if (old_e_size > new_e_size) { + new_e_size = old_e_size; + } +#if defined(DUK_USE_HOBJECT_HASH_PART) + new_h_size = duk__get_default_h_size(new_e_size); +#else + new_h_size = 0; +#endif + new_a_size = DUK_HOBJECT_GET_ASIZE(obj); + + duk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0); +} + +/* Grow entry part allocation for one additional entry. */ +DUK_LOCAL void duk__grow_props_for_new_entry_item(duk_hthread *thr, duk_hobject *obj) { + duk_uint32_t old_e_used; /* actually used, non-NULL entries */ + duk_uint32_t new_e_size_minimum; + duk_uint32_t new_e_size; + duk_uint32_t new_a_size; + duk_uint32_t new_h_size; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(obj != NULL); + + /* Duktape 0.11.0 and prior tried to optimize the resize by not + * counting the number of actually used keys prior to the resize. + * This worked mostly well but also caused weird leak-like behavior + * as in: test-bug-object-prop-alloc-unbounded.js. So, now we count + * the keys explicitly to compute the new entry part size. + */ + + old_e_used = duk__count_used_e_keys(thr, obj); + new_e_size_minimum = old_e_used + 1; + new_e_size = old_e_used + duk__get_min_grow_e(old_e_used); +#if defined(DUK_USE_HOBJECT_HASH_PART) + new_h_size = duk__get_default_h_size(new_e_size); +#else + new_h_size = 0; +#endif + new_a_size = DUK_HOBJECT_GET_ASIZE(obj); + +#if defined(DUK_USE_OBJSIZES16) + if (new_e_size > DUK_UINT16_MAX) { + new_e_size = DUK_UINT16_MAX; + } + if (new_h_size > DUK_UINT16_MAX) { + new_h_size = DUK_UINT16_MAX; + } + if (new_a_size > DUK_UINT16_MAX) { + new_a_size = DUK_UINT16_MAX; + } +#endif + DUK_ASSERT(new_h_size == 0 || new_h_size >= new_e_size); + + if (!(new_e_size >= new_e_size_minimum)) { + DUK_ERROR_ALLOC_FAILED(thr); + DUK_WO_NORETURN(return;); + } + + duk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0); +} + +/* Grow array part for a new highest array index. */ +DUK_LOCAL void duk__grow_props_for_array_item(duk_hthread *thr, duk_hobject *obj, duk_uint32_t highest_arr_idx) { + duk_uint32_t new_e_size; + duk_uint32_t new_a_size; + duk_uint32_t new_a_size_minimum; + duk_uint32_t new_h_size; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(obj != NULL); + DUK_ASSERT(highest_arr_idx >= DUK_HOBJECT_GET_ASIZE(obj)); + + new_e_size = DUK_HOBJECT_GET_ESIZE(obj); + new_h_size = DUK_HOBJECT_GET_HSIZE(obj); + new_a_size_minimum = highest_arr_idx + 1; + new_a_size = highest_arr_idx + duk__get_min_grow_a(highest_arr_idx); + DUK_ASSERT(new_a_size >= highest_arr_idx + 1); /* duk__get_min_grow_a() is always >= 1 */ + +#if defined(DUK_USE_OBJSIZES16) + if (new_e_size > DUK_UINT16_MAX) { + new_e_size = DUK_UINT16_MAX; + } + if (new_h_size > DUK_UINT16_MAX) { + new_h_size = DUK_UINT16_MAX; + } + if (new_a_size > DUK_UINT16_MAX) { + new_a_size = DUK_UINT16_MAX; + } +#endif + + if (!(new_a_size >= new_a_size_minimum)) { + DUK_ERROR_ALLOC_FAILED(thr); + DUK_WO_NORETURN(return;); + } + + duk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0); +} + +/* Abandon array part, moving array entries into entries part. + * This requires a props resize, which is a heavy operation. + * We also compact the entries part while we're at it, although + * this is not strictly required. + */ +DUK_LOCAL void duk__abandon_array_part(duk_hthread *thr, duk_hobject *obj) { + duk_uint32_t new_e_size_minimum; + duk_uint32_t new_e_size; + duk_uint32_t new_a_size; + duk_uint32_t new_h_size; + duk_uint32_t e_used; /* actually used, non-NULL keys */ + duk_uint32_t a_used; + duk_uint32_t a_size; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(obj != NULL); + + e_used = duk__count_used_e_keys(thr, obj); + duk__compute_a_stats(thr, obj, &a_used, &a_size); + + /* + * Must guarantee all actually used array entries will fit into + * new entry part. Add one growth step to ensure we don't run out + * of space right away. + */ + + new_e_size_minimum = e_used + a_used; + new_e_size = new_e_size_minimum + duk__get_min_grow_e(new_e_size_minimum); + new_a_size = 0; +#if defined(DUK_USE_HOBJECT_HASH_PART) + new_h_size = duk__get_default_h_size(new_e_size); +#else + new_h_size = 0; +#endif + +#if defined(DUK_USE_OBJSIZES16) + if (new_e_size > DUK_UINT16_MAX) { + new_e_size = DUK_UINT16_MAX; + } + if (new_h_size > DUK_UINT16_MAX) { + new_h_size = DUK_UINT16_MAX; + } + if (new_a_size > DUK_UINT16_MAX) { + new_a_size = DUK_UINT16_MAX; + } +#endif + + if (!(new_e_size >= new_e_size_minimum)) { + DUK_ERROR_ALLOC_FAILED(thr); + DUK_WO_NORETURN(return;); + } + + DUK_DD(DUK_DDPRINT("abandon array part for hobject %p, " + "array stats before: e_used=%ld, a_used=%ld, a_size=%ld; " + "resize to e_size=%ld, a_size=%ld, h_size=%ld", + (void *) obj, (long) e_used, (long) a_used, (long) a_size, + (long) new_e_size, (long) new_a_size, (long) new_h_size)); + + duk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 1); +} + +/* + * Compact an object. Minimizes allocation size for objects which are + * not likely to be extended. This is useful for internal and non- + * extensible objects, but can also be called for non-extensible objects. + * May abandon the array part if it is computed to be too sparse. + * + * This call is relatively expensive, as it needs to scan both the + * entries and the array part. + * + * The call may fail due to allocation error. + */ + +DUK_INTERNAL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj) { + duk_uint32_t e_size; /* currently used -> new size */ + duk_uint32_t a_size; /* currently required */ + duk_uint32_t a_used; /* actually used */ + duk_uint32_t h_size; + duk_bool_t abandon_array; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(obj != NULL); + +#if defined(DUK_USE_ROM_OBJECTS) + if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) { + DUK_DD(DUK_DDPRINT("ignore attempt to compact a rom object")); + return; + } +#endif + + e_size = duk__count_used_e_keys(thr, obj); + duk__compute_a_stats(thr, obj, &a_used, &a_size); + + DUK_DD(DUK_DDPRINT("compacting hobject, used e keys %ld, used a keys %ld, min a size %ld, " + "resized array density would be: %ld/%ld = %lf", + (long) e_size, (long) a_used, (long) a_size, + (long) a_used, (long) a_size, + (double) a_used / (double) a_size)); + + if (duk__abandon_array_density_check(a_used, a_size)) { + DUK_DD(DUK_DDPRINT("decided to abandon array during compaction, a_used=%ld, a_size=%ld", + (long) a_used, (long) a_size)); + abandon_array = 1; + e_size += a_used; + a_size = 0; + } else { + DUK_DD(DUK_DDPRINT("decided to keep array during compaction")); + abandon_array = 0; + } + +#if defined(DUK_USE_HOBJECT_HASH_PART) + if (e_size >= DUK_USE_HOBJECT_HASH_PROP_LIMIT) { + h_size = duk__get_default_h_size(e_size); + } else { + h_size = 0; + } +#else + h_size = 0; +#endif + + DUK_DD(DUK_DDPRINT("compacting hobject -> new e_size %ld, new a_size=%ld, new h_size=%ld, abandon_array=%ld", + (long) e_size, (long) a_size, (long) h_size, (long) abandon_array)); + + duk_hobject_realloc_props(thr, obj, e_size, a_size, h_size, abandon_array); +} + +/* + * Find an existing key from entry part either by linear scan or by + * using the hash index (if it exists). + * + * Sets entry index (and possibly the hash index) to output variables, + * which allows the caller to update the entry and hash entries in-place. + * If entry is not found, both values are set to -1. If entry is found + * but there is no hash part, h_idx is set to -1. + */ + +DUK_INTERNAL duk_bool_t duk_hobject_find_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx) { + DUK_ASSERT(obj != NULL); + DUK_ASSERT(key != NULL); + DUK_ASSERT(e_idx != NULL); + DUK_ASSERT(h_idx != NULL); + DUK_UNREF(heap); + + if (DUK_LIKELY(DUK_HOBJECT_GET_HSIZE(obj) == 0)) + { + /* Linear scan: more likely because most objects are small. + * This is an important fast path. + * + * XXX: this might be worth inlining for property lookups. + */ + duk_uint_fast32_t i; + duk_uint_fast32_t n; + duk_hstring **h_keys_base; + DUK_DDD(DUK_DDDPRINT("duk_hobject_find_entry() using linear scan for lookup")); + + h_keys_base = DUK_HOBJECT_E_GET_KEY_BASE(heap, obj); + n = DUK_HOBJECT_GET_ENEXT(obj); + for (i = 0; i < n; i++) { + if (h_keys_base[i] == key) { + *e_idx = (duk_int_t) i; + *h_idx = -1; + return 1; + } + } + } +#if defined(DUK_USE_HOBJECT_HASH_PART) + else + { + /* hash lookup */ + duk_uint32_t n; + duk_uint32_t i, step; + duk_uint32_t *h_base; + duk_uint32_t mask; + + DUK_DDD(DUK_DDDPRINT("duk_hobject_find_entry() using hash part for lookup")); + + h_base = DUK_HOBJECT_H_GET_BASE(heap, obj); + n = DUK_HOBJECT_GET_HSIZE(obj); + mask = n - 1; + i = DUK_HSTRING_GET_HASH(key) & mask; + step = 1; /* Cache friendly but clustering prone. */ + + for (;;) { + duk_uint32_t t; + + DUK_ASSERT_DISABLE(i >= 0); /* unsigned */ + DUK_ASSERT(i < DUK_HOBJECT_GET_HSIZE(obj)); + t = h_base[i]; + DUK_ASSERT(t == DUK__HASH_UNUSED || t == DUK__HASH_DELETED || + (t < DUK_HOBJECT_GET_ESIZE(obj))); /* t >= 0 always true, unsigned */ + + if (t == DUK__HASH_UNUSED) { + break; + } else if (t == DUK__HASH_DELETED) { + DUK_DDD(DUK_DDDPRINT("lookup miss (deleted) i=%ld, t=%ld", + (long) i, (long) t)); + } else { + DUK_ASSERT(t < DUK_HOBJECT_GET_ESIZE(obj)); + if (DUK_HOBJECT_E_GET_KEY(heap, obj, t) == key) { + DUK_DDD(DUK_DDDPRINT("lookup hit i=%ld, t=%ld -> key %p", + (long) i, (long) t, (void *) key)); + *e_idx = (duk_int_t) t; + *h_idx = (duk_int_t) i; + return 1; + } + DUK_DDD(DUK_DDDPRINT("lookup miss i=%ld, t=%ld", + (long) i, (long) t)); + } + i = (i + step) & mask; + + /* Guaranteed to finish (hash is larger than #props). */ + } + } +#endif /* DUK_USE_HOBJECT_HASH_PART */ + + /* Not found, leave e_idx and h_idx unset. */ + return 0; +} + +/* For internal use: get non-accessor entry value */ +DUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key) { + duk_int_t e_idx; + duk_int_t h_idx; + + DUK_ASSERT(obj != NULL); + DUK_ASSERT(key != NULL); + DUK_UNREF(heap); + + if (duk_hobject_find_entry(heap, obj, key, &e_idx, &h_idx)) { + DUK_ASSERT(e_idx >= 0); + if (!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) { + return DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx); + } + } + return NULL; +} + +DUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx) { + return duk_hobject_find_entry_tval_ptr(heap, obj, DUK_HEAP_GET_STRING(heap, stridx)); +} + +/* For internal use: get non-accessor entry value and attributes */ +DUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_uint_t *out_attrs) { + duk_int_t e_idx; + duk_int_t h_idx; + + DUK_ASSERT(obj != NULL); + DUK_ASSERT(key != NULL); + DUK_ASSERT(out_attrs != NULL); + DUK_UNREF(heap); + + if (duk_hobject_find_entry(heap, obj, key, &e_idx, &h_idx)) { + DUK_ASSERT(e_idx >= 0); + if (!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) { + *out_attrs = DUK_HOBJECT_E_GET_FLAGS(heap, obj, e_idx); + return DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx); + } + } + /* If not found, out_attrs is left unset. */ + return NULL; +} + +/* For internal use: get array part value */ +DUK_INTERNAL duk_tval *duk_hobject_find_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i) { + duk_tval *tv; + + DUK_ASSERT(obj != NULL); + DUK_UNREF(heap); + + if (!DUK_HOBJECT_HAS_ARRAY_PART(obj)) { + return NULL; + } + if (i >= DUK_HOBJECT_GET_ASIZE(obj)) { + return NULL; + } + tv = DUK_HOBJECT_A_GET_VALUE_PTR(heap, obj, i); + return tv; +} + +/* + * Allocate and initialize a new entry, resizing the properties allocation + * if necessary. Returns entry index (e_idx) or throws an error if alloc fails. + * + * Sets the key of the entry (increasing the key's refcount), and updates + * the hash part if it exists. Caller must set value and flags, and update + * the entry value refcount. A decref for the previous value is not necessary. + */ + +DUK_LOCAL duk_int_t duk__hobject_alloc_entry_checked(duk_hthread *thr, duk_hobject *obj, duk_hstring *key) { + duk_uint32_t idx; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(obj != NULL); + DUK_ASSERT(key != NULL); + DUK_ASSERT(DUK_HOBJECT_GET_ENEXT(obj) <= DUK_HOBJECT_GET_ESIZE(obj)); + +#if defined(DUK_USE_ASSERTIONS) + /* key must not already exist in entry part */ + { + duk_uint_fast32_t i; + for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) { + DUK_ASSERT(DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i) != key); + } + } +#endif + + if (DUK_HOBJECT_GET_ENEXT(obj) >= DUK_HOBJECT_GET_ESIZE(obj)) { + /* only need to guarantee 1 more slot, but allocation growth is in chunks */ + DUK_DDD(DUK_DDDPRINT("entry part full, allocate space for one more entry")); + duk__grow_props_for_new_entry_item(thr, obj); + } + DUK_ASSERT(DUK_HOBJECT_GET_ENEXT(obj) < DUK_HOBJECT_GET_ESIZE(obj)); + idx = DUK_HOBJECT_POSTINC_ENEXT(obj); + + /* previous value is assumed to be garbage, so don't touch it */ + DUK_HOBJECT_E_SET_KEY(thr->heap, obj, idx, key); + DUK_HSTRING_INCREF(thr, key); + +#if defined(DUK_USE_HOBJECT_HASH_PART) + if (DUK_UNLIKELY(DUK_HOBJECT_GET_HSIZE(obj) > 0)) { + duk_uint32_t n, mask; + duk_uint32_t i, step; + duk_uint32_t *h_base = DUK_HOBJECT_H_GET_BASE(thr->heap, obj); + + n = DUK_HOBJECT_GET_HSIZE(obj); + mask = n - 1; + i = DUK_HSTRING_GET_HASH(key) & mask; + step = 1; /* Cache friendly but clustering prone. */ + + for (;;) { + duk_uint32_t t = h_base[i]; + if (t == DUK__HASH_UNUSED || t == DUK__HASH_DELETED) { + DUK_DDD(DUK_DDDPRINT("duk__hobject_alloc_entry_checked() inserted key into hash part, %ld -> %ld", + (long) i, (long) idx)); + DUK_ASSERT_DISABLE(i >= 0); /* unsigned */ + DUK_ASSERT(i < DUK_HOBJECT_GET_HSIZE(obj)); + DUK_ASSERT_DISABLE(idx >= 0); + DUK_ASSERT(idx < DUK_HOBJECT_GET_ESIZE(obj)); + h_base[i] = idx; + break; + } + DUK_DDD(DUK_DDDPRINT("duk__hobject_alloc_entry_checked() miss %ld", (long) i)); + i = (i + step) & mask; + + /* Guaranteed to finish (hash is larger than #props). */ + } + } +#endif /* DUK_USE_HOBJECT_HASH_PART */ + + /* Note: we could return the hash index here too, but it's not + * needed right now. + */ + + DUK_ASSERT_DISABLE(idx >= 0); + DUK_ASSERT(idx < DUK_HOBJECT_GET_ESIZE(obj)); + DUK_ASSERT(idx < DUK_HOBJECT_GET_ENEXT(obj)); + return (duk_int_t) idx; +} + +/* + * Object internal value + * + * Returned value is guaranteed to be reachable / incref'd, caller does not need + * to incref OR decref. No proxies or accessors are invoked, no prototype walk. + */ + +DUK_INTERNAL duk_tval *duk_hobject_get_internal_value_tval_ptr(duk_heap *heap, duk_hobject *obj) { + return duk_hobject_find_entry_tval_ptr_stridx(heap, obj, DUK_STRIDX_INT_VALUE); +} + +DUK_LOCAL duk_heaphdr *duk_hobject_get_internal_value_heaphdr(duk_heap *heap, duk_hobject *obj) { + duk_tval *tv; + + DUK_ASSERT(heap != NULL); + DUK_ASSERT(obj != NULL); + + tv = duk_hobject_get_internal_value_tval_ptr(heap, obj); + if (tv != NULL) { + duk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv); + DUK_ASSERT(h != NULL); + return h; + } + + return NULL; +} + +DUK_INTERNAL duk_hstring *duk_hobject_get_internal_value_string(duk_heap *heap, duk_hobject *obj) { + duk_hstring *h; + + h = (duk_hstring *) duk_hobject_get_internal_value_heaphdr(heap, obj); + if (h != NULL) { + DUK_ASSERT(DUK_HEAPHDR_IS_STRING((duk_heaphdr *) h)); + } + return h; +} + +DUK_LOCAL duk_hobject *duk__hobject_get_entry_object_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx) { + duk_tval *tv; + duk_hobject *h; + + tv = duk_hobject_find_entry_tval_ptr_stridx(heap, obj, stridx); + if (tv != NULL && DUK_TVAL_IS_OBJECT(tv)) { + h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + return h; + } + return NULL; +} + +DUK_INTERNAL duk_harray *duk_hobject_get_formals(duk_hthread *thr, duk_hobject *obj) { + duk_harray *h; + + h = (duk_harray *) duk__hobject_get_entry_object_stridx(thr->heap, obj, DUK_STRIDX_INT_FORMALS); + if (h != NULL) { + DUK_ASSERT(DUK_HOBJECT_IS_ARRAY((duk_hobject *) h)); + DUK_ASSERT(h->length <= DUK_HOBJECT_GET_ASIZE((duk_hobject *) h)); + } + return h; +} + +DUK_INTERNAL duk_hobject *duk_hobject_get_varmap(duk_hthread *thr, duk_hobject *obj) { + duk_hobject *h; + + h = duk__hobject_get_entry_object_stridx(thr->heap, obj, DUK_STRIDX_INT_VARMAP); + return h; +} + +/* + * Arguments handling helpers (argument map mainly). + * + * An arguments object has exotic behavior for some numeric indices. + * Accesses may translate to identifier operations which may have + * arbitrary side effects (potentially invalidating any duk_tval + * pointers). + */ + +/* Lookup 'key' from arguments internal 'map', perform a variable lookup + * if mapped, and leave the result on top of stack (and return non-zero). + * Used in E5 Section 10.6 algorithms [[Get]] and [[GetOwnProperty]]. + */ +DUK_LOCAL +duk_bool_t duk__lookup_arguments_map(duk_hthread *thr, + duk_hobject *obj, + duk_hstring *key, + duk_propdesc *temp_desc, + duk_hobject **out_map, + duk_hobject **out_varenv) { + duk_hobject *map; + duk_hobject *varenv; + duk_bool_t rc; + + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + DUK_DDD(DUK_DDDPRINT("arguments map lookup: thr=%p, obj=%p, key=%p, temp_desc=%p " + "(obj -> %!O, key -> %!O)", + (void *) thr, (void *) obj, (void *) key, (void *) temp_desc, + (duk_heaphdr *) obj, (duk_heaphdr *) key)); + + if (!duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_MAP(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) { + DUK_DDD(DUK_DDDPRINT("-> no 'map'")); + return 0; + } + + map = duk_require_hobject(thr, -1); + DUK_ASSERT(map != NULL); + duk_pop_unsafe(thr); /* map is reachable through obj */ + + if (!duk_hobject_get_own_propdesc(thr, map, key, temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) { + DUK_DDD(DUK_DDDPRINT("-> 'map' exists, but key not in map")); + return 0; + } + + /* [... varname] */ + DUK_DDD(DUK_DDDPRINT("-> 'map' exists, and contains key, key is mapped to argument/variable binding %!T", + (duk_tval *) duk_get_tval(thr, -1))); + DUK_ASSERT(duk_is_string(thr, -1)); /* guaranteed when building arguments */ + + /* get varenv for varname (callee's declarative lexical environment) */ + rc = duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_VARENV(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE); + DUK_UNREF(rc); + DUK_ASSERT(rc != 0); /* arguments MUST have an initialized lexical environment reference */ + varenv = duk_require_hobject(thr, -1); + DUK_ASSERT(varenv != NULL); + duk_pop_unsafe(thr); /* varenv remains reachable through 'obj' */ + + DUK_DDD(DUK_DDDPRINT("arguments varenv is: %!dO", (duk_heaphdr *) varenv)); + + /* success: leave varname in stack */ + *out_map = map; + *out_varenv = varenv; + return 1; /* [... varname] */ +} + +/* Lookup 'key' from arguments internal 'map', and leave replacement value + * on stack top if mapped (and return non-zero). + * Used in E5 Section 10.6 algorithm for [[GetOwnProperty]] (used by [[Get]]). + */ +DUK_LOCAL duk_bool_t duk__check_arguments_map_for_get(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc) { + duk_hobject *map; + duk_hobject *varenv; + duk_hstring *varname; + + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + if (!duk__lookup_arguments_map(thr, obj, key, temp_desc, &map, &varenv)) { + DUK_DDD(DUK_DDDPRINT("arguments: key not mapped, no exotic get behavior")); + return 0; + } + + /* [... varname] */ + + varname = duk_require_hstring(thr, -1); + DUK_ASSERT(varname != NULL); + duk_pop_unsafe(thr); /* varname is still reachable */ + + DUK_DDD(DUK_DDDPRINT("arguments object automatic getvar for a bound variable; " + "key=%!O, varname=%!O", + (duk_heaphdr *) key, + (duk_heaphdr *) varname)); + + (void) duk_js_getvar_envrec(thr, varenv, varname, 1 /*throw*/); + + /* [... value this_binding] */ + + duk_pop_unsafe(thr); + + /* leave result on stack top */ + return 1; +} + +/* Lookup 'key' from arguments internal 'map', perform a variable write if mapped. + * Used in E5 Section 10.6 algorithm for [[DefineOwnProperty]] (used by [[Put]]). + * Assumes stack top contains 'put' value (which is NOT popped). + */ +DUK_LOCAL void duk__check_arguments_map_for_put(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc, duk_bool_t throw_flag) { + duk_hobject *map; + duk_hobject *varenv; + duk_hstring *varname; + + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + if (!duk__lookup_arguments_map(thr, obj, key, temp_desc, &map, &varenv)) { + DUK_DDD(DUK_DDDPRINT("arguments: key not mapped, no exotic put behavior")); + return; + } + + /* [... put_value varname] */ + + varname = duk_require_hstring(thr, -1); + DUK_ASSERT(varname != NULL); + duk_pop_unsafe(thr); /* varname is still reachable */ + + DUK_DDD(DUK_DDDPRINT("arguments object automatic putvar for a bound variable; " + "key=%!O, varname=%!O, value=%!T", + (duk_heaphdr *) key, + (duk_heaphdr *) varname, + (duk_tval *) duk_require_tval(thr, -1))); + + /* [... put_value] */ + + /* + * Note: although arguments object variable mappings are only established + * for non-strict functions (and a call to a non-strict function created + * the arguments object in question), an inner strict function may be doing + * the actual property write. Hence the throw_flag applied here comes from + * the property write call. + */ + + duk_js_putvar_envrec(thr, varenv, varname, duk_require_tval(thr, -1), throw_flag); + + /* [... put_value] */ +} + +/* Lookup 'key' from arguments internal 'map', delete mapping if found. + * Used in E5 Section 10.6 algorithm for [[Delete]]. Note that the + * variable/argument itself (where the map points) is not deleted. + */ +DUK_LOCAL void duk__check_arguments_map_for_delete(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc) { + duk_hobject *map; + + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + if (!duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_MAP(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) { + DUK_DDD(DUK_DDDPRINT("arguments: key not mapped, no exotic delete behavior")); + return; + } + + map = duk_require_hobject(thr, -1); + DUK_ASSERT(map != NULL); + duk_pop_unsafe(thr); /* map is reachable through obj */ + + DUK_DDD(DUK_DDDPRINT("-> have 'map', delete key %!O from map (if exists)); ignore result", + (duk_heaphdr *) key)); + + /* Note: no recursion issue, we can trust 'map' to behave */ + DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_BEHAVIOR(map)); + DUK_DDD(DUK_DDDPRINT("map before deletion: %!O", (duk_heaphdr *) map)); + (void) duk_hobject_delprop_raw(thr, map, key, 0); /* ignore result */ + DUK_DDD(DUK_DDDPRINT("map after deletion: %!O", (duk_heaphdr *) map)); +} + +/* + * ECMAScript compliant [[GetOwnProperty]](P), for internal use only. + * + * If property is found: + * - Fills descriptor fields to 'out_desc' + * - If DUK_GETDESC_FLAG_PUSH_VALUE is set, pushes a value related to the + * property onto the stack ('undefined' for accessor properties). + * - Returns non-zero + * + * If property is not found: + * - 'out_desc' is left in untouched state (possibly garbage) + * - Nothing is pushed onto the stack (not even with DUK_GETDESC_FLAG_PUSH_VALUE + * set) + * - Returns zero + * + * Notes: + * + * - Getting a property descriptor may cause an allocation (and hence + * GC) to take place, hence reachability and refcount of all related + * values matter. Reallocation of value stack, properties, etc may + * invalidate many duk_tval pointers (concretely, those which reside + * in memory areas subject to reallocation). However, heap object + * pointers are never affected (heap objects have stable pointers). + * + * - The value of a plain property is always reachable and has a non-zero + * reference count. + * + * - The value of a virtual property is not necessarily reachable from + * elsewhere and may have a refcount of zero. Hence we push it onto + * the valstack for the caller, which ensures it remains reachable + * while it is needed. + * + * - There are no virtual accessor properties. Hence, all getters and + * setters are always related to concretely stored properties, which + * ensures that the get/set functions in the resulting descriptor are + * reachable and have non-zero refcounts. Should there be virtual + * accessor properties later, this would need to change. + */ + +DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_uint32_t arr_idx, duk_propdesc *out_desc, duk_small_uint_t flags) { + duk_tval *tv; + + DUK_DDD(DUK_DDDPRINT("duk_hobject_get_own_propdesc: thr=%p, obj=%p, key=%p, out_desc=%p, flags=%lx, " + "arr_idx=%ld (obj -> %!O, key -> %!O)", + (void *) thr, (void *) obj, (void *) key, (void *) out_desc, + (long) flags, (long) arr_idx, + (duk_heaphdr *) obj, (duk_heaphdr *) key)); + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(obj != NULL); + DUK_ASSERT(key != NULL); + DUK_ASSERT(out_desc != NULL); + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + DUK_STATS_INC(thr->heap, stats_getownpropdesc_count); + + /* Each code path returning 1 (= found) must fill in all the output + * descriptor fields. We don't do it beforehand because it'd be + * unnecessary work if the property isn't found and would happen + * multiple times for an inheritance chain. + */ + DUK_ASSERT_SET_GARBAGE(out_desc, sizeof(*out_desc)); +#if 0 + out_desc->flags = 0; + out_desc->get = NULL; + out_desc->set = NULL; + out_desc->e_idx = -1; + out_desc->h_idx = -1; + out_desc->a_idx = -1; +#endif + + /* + * Try entries part first because it's the common case. + * + * Array part lookups are usually handled by the array fast path, and + * are not usually inherited. Array and entry parts never contain the + * same keys so the entry part vs. array part order doesn't matter. + */ + + if (duk_hobject_find_entry(thr->heap, obj, key, &out_desc->e_idx, &out_desc->h_idx)) { + duk_int_t e_idx = out_desc->e_idx; + DUK_ASSERT(out_desc->e_idx >= 0); + out_desc->a_idx = -1; + out_desc->flags = DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, e_idx); + out_desc->get = NULL; + out_desc->set = NULL; + if (DUK_UNLIKELY(out_desc->flags & DUK_PROPDESC_FLAG_ACCESSOR)) { + DUK_DDD(DUK_DDDPRINT("-> found accessor property in entry part")); + out_desc->get = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, e_idx); + out_desc->set = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, e_idx); + if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) { + /* a dummy undefined value is pushed to make valstack + * behavior uniform for caller + */ + duk_push_undefined(thr); + } + } else { + DUK_DDD(DUK_DDDPRINT("-> found plain property in entry part")); + tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx); + if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) { + duk_push_tval(thr, tv); + } + } + goto prop_found; + } + + /* + * Try array part. + */ + + if (DUK_HOBJECT_HAS_ARRAY_PART(obj) && arr_idx != DUK__NO_ARRAY_INDEX) { + if (arr_idx < DUK_HOBJECT_GET_ASIZE(obj)) { + tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx); + if (!DUK_TVAL_IS_UNUSED(tv)) { + DUK_DDD(DUK_DDDPRINT("-> found in array part")); + if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) { + duk_push_tval(thr, tv); + } + /* implicit attributes */ + out_desc->flags = DUK_PROPDESC_FLAG_WRITABLE | + DUK_PROPDESC_FLAG_CONFIGURABLE | + DUK_PROPDESC_FLAG_ENUMERABLE; + out_desc->get = NULL; + out_desc->set = NULL; + out_desc->e_idx = -1; + out_desc->h_idx = -1; + out_desc->a_idx = (duk_int_t) arr_idx; /* XXX: limit 2G due to being signed */ + goto prop_found; + } + } + } + + DUK_DDD(DUK_DDDPRINT("-> not found as a concrete property")); + + /* + * Not found as a concrete property, check for virtual properties. + */ + + if (!DUK_HOBJECT_HAS_VIRTUAL_PROPERTIES(obj)) { + /* Quick skip. */ + goto prop_not_found; + } + + if (DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) { + duk_harray *a; + + DUK_DDD(DUK_DDDPRINT("array object exotic property get for key: %!O, arr_idx: %ld", + (duk_heaphdr *) key, (long) arr_idx)); + + a = (duk_harray *) obj; + DUK_HARRAY_ASSERT_VALID(a); + + if (key == DUK_HTHREAD_STRING_LENGTH(thr)) { + DUK_DDD(DUK_DDDPRINT("-> found, key is 'length', length exotic behavior")); + + if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) { + duk_push_uint(thr, (duk_uint_t) a->length); + } + out_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL; + if (DUK_HARRAY_LENGTH_WRITABLE(a)) { + out_desc->flags |= DUK_PROPDESC_FLAG_WRITABLE; + } + out_desc->get = NULL; + out_desc->set = NULL; + out_desc->e_idx = -1; + out_desc->h_idx = -1; + out_desc->a_idx = -1; + + DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)); + goto prop_found_noexotic; /* cannot be arguments exotic */ + } + } else if (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(obj)) { + DUK_DDD(DUK_DDDPRINT("string object exotic property get for key: %!O, arr_idx: %ld", + (duk_heaphdr *) key, (long) arr_idx)); + + /* XXX: charlen; avoid multiple lookups? */ + + if (arr_idx != DUK__NO_ARRAY_INDEX) { + duk_hstring *h_val; + + DUK_DDD(DUK_DDDPRINT("array index exists")); + + h_val = duk_hobject_get_internal_value_string(thr->heap, obj); + DUK_ASSERT(h_val); + if (arr_idx < DUK_HSTRING_GET_CHARLEN(h_val)) { + DUK_DDD(DUK_DDDPRINT("-> found, array index inside string")); + if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) { + duk_push_hstring(thr, h_val); + duk_substring(thr, -1, arr_idx, arr_idx + 1); /* [str] -> [substr] */ + } + out_desc->flags = DUK_PROPDESC_FLAG_ENUMERABLE | /* E5 Section 15.5.5.2 */ + DUK_PROPDESC_FLAG_VIRTUAL; + out_desc->get = NULL; + out_desc->set = NULL; + out_desc->e_idx = -1; + out_desc->h_idx = -1; + out_desc->a_idx = -1; + + DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)); + goto prop_found_noexotic; /* cannot be arguments exotic */ + } else { + /* index is above internal string length -> property is fully normal */ + DUK_DDD(DUK_DDDPRINT("array index outside string -> normal property")); + } + } else if (key == DUK_HTHREAD_STRING_LENGTH(thr)) { + duk_hstring *h_val; + + DUK_DDD(DUK_DDDPRINT("-> found, key is 'length', length exotic behavior")); + + h_val = duk_hobject_get_internal_value_string(thr->heap, obj); + DUK_ASSERT(h_val != NULL); + if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) { + duk_push_uint(thr, (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h_val)); + } + out_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL; /* E5 Section 15.5.5.1 */ + out_desc->get = NULL; + out_desc->set = NULL; + out_desc->e_idx = -1; + out_desc->h_idx = -1; + out_desc->a_idx = -1; + + DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)); + goto prop_found_noexotic; /* cannot be arguments exotic */ + } + } +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + else if (DUK_HOBJECT_IS_BUFOBJ(obj)) { + duk_hbufobj *h_bufobj; + duk_uint_t byte_off; + duk_small_uint_t elem_size; + + h_bufobj = (duk_hbufobj *) obj; + DUK_HBUFOBJ_ASSERT_VALID(h_bufobj); + DUK_DDD(DUK_DDDPRINT("bufobj property get for key: %!O, arr_idx: %ld", + (duk_heaphdr *) key, (long) arr_idx)); + + if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) { + DUK_DDD(DUK_DDDPRINT("array index exists")); + + /* Careful with wrapping: arr_idx upshift may easily wrap, whereas + * length downshift won't. + */ + if (arr_idx < (h_bufobj->length >> h_bufobj->shift)) { + byte_off = arr_idx << h_bufobj->shift; /* no wrap assuming h_bufobj->length is valid */ + elem_size = (duk_small_uint_t) (1U << h_bufobj->shift); + if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) { + duk_uint8_t *data; + + if (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) { + data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off; + duk_hbufobj_push_validated_read(thr, h_bufobj, data, elem_size); + } else { + DUK_D(DUK_DPRINT("bufobj access out of underlying buffer, ignoring (read zero)")); + duk_push_uint(thr, 0); + } + } + out_desc->flags = DUK_PROPDESC_FLAG_WRITABLE | + DUK_PROPDESC_FLAG_VIRTUAL; + if (DUK_HOBJECT_GET_CLASS_NUMBER(obj) != DUK_HOBJECT_CLASS_ARRAYBUFFER) { + /* ArrayBuffer indices are non-standard and are + * non-enumerable to avoid their serialization. + */ + out_desc->flags |= DUK_PROPDESC_FLAG_ENUMERABLE; + } + out_desc->get = NULL; + out_desc->set = NULL; + out_desc->e_idx = -1; + out_desc->h_idx = -1; + out_desc->a_idx = -1; + + DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)); + goto prop_found_noexotic; /* cannot be e.g. arguments exotic, since exotic 'traits' are mutually exclusive */ + } else { + /* index is above internal buffer length -> property is fully normal */ + DUK_DDD(DUK_DDDPRINT("array index outside buffer -> normal property")); + } + } else if (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) { + DUK_DDD(DUK_DDDPRINT("-> found, key is 'length', length exotic behavior")); + + if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) { + /* Length in elements: take into account shift, but + * intentionally don't check the underlying buffer here. + */ + duk_push_uint(thr, h_bufobj->length >> h_bufobj->shift); + } + out_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL; + out_desc->get = NULL; + out_desc->set = NULL; + out_desc->e_idx = -1; + out_desc->h_idx = -1; + out_desc->a_idx = -1; + + DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)); + goto prop_found_noexotic; /* cannot be arguments exotic */ + } + } +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + + /* Array properties have exotic behavior but they are concrete, + * so no special handling here. + * + * Arguments exotic behavior (E5 Section 10.6, [[GetOwnProperty]] + * is only relevant as a post-check implemented below; hence no + * check here. + */ + + /* + * Not found as concrete or virtual. + */ + + prop_not_found: + DUK_DDD(DUK_DDDPRINT("-> not found (virtual, entry part, or array part)")); + DUK_STATS_INC(thr->heap, stats_getownpropdesc_miss); + return 0; + + /* + * Found. + * + * Arguments object has exotic post-processing, see E5 Section 10.6, + * description of [[GetOwnProperty]] variant for arguments. + */ + + prop_found: + DUK_DDD(DUK_DDDPRINT("-> property found, checking for arguments exotic post-behavior")); + + /* Notes: + * - Only numbered indices are relevant, so arr_idx fast reject is good + * (this is valid unless there are more than 4**32-1 arguments). + * - Since variable lookup has no side effects, this can be skipped if + * DUK_GETDESC_FLAG_PUSH_VALUE is not set. + */ + + if (DUK_UNLIKELY(DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj) && + arr_idx != DUK__NO_ARRAY_INDEX && + (flags & DUK_GETDESC_FLAG_PUSH_VALUE))) { + duk_propdesc temp_desc; + + /* Magically bound variable cannot be an accessor. However, + * there may be an accessor property (or a plain property) in + * place with magic behavior removed. This happens e.g. when + * a magic property is redefined with defineProperty(). + * Cannot assert for "not accessor" here. + */ + + /* replaces top of stack with new value if necessary */ + DUK_ASSERT((flags & DUK_GETDESC_FLAG_PUSH_VALUE) != 0); + + /* This can perform a variable lookup but only into a declarative + * environment which has no side effects. + */ + if (duk__check_arguments_map_for_get(thr, obj, key, &temp_desc)) { + DUK_DDD(DUK_DDDPRINT("-> arguments exotic behavior overrides result: %!T -> %!T", + (duk_tval *) duk_get_tval(thr, -2), + (duk_tval *) duk_get_tval(thr, -1))); + /* [... old_result result] -> [... result] */ + duk_remove_m2(thr); + } + } + + prop_found_noexotic: + DUK_STATS_INC(thr->heap, stats_getownpropdesc_hit); + return 1; +} + +DUK_INTERNAL duk_bool_t duk_hobject_get_own_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(obj != NULL); + DUK_ASSERT(key != NULL); + DUK_ASSERT(out_desc != NULL); + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + return duk__get_own_propdesc_raw(thr, obj, key, DUK_HSTRING_GET_ARRIDX_SLOW(key), out_desc, flags); +} + +/* + * ECMAScript compliant [[GetProperty]](P), for internal use only. + * + * If property is found: + * - Fills descriptor fields to 'out_desc' + * - If DUK_GETDESC_FLAG_PUSH_VALUE is set, pushes a value related to the + * property onto the stack ('undefined' for accessor properties). + * - Returns non-zero + * + * If property is not found: + * - 'out_desc' is left in untouched state (possibly garbage) + * - Nothing is pushed onto the stack (not even with DUK_GETDESC_FLAG_PUSH_VALUE + * set) + * - Returns zero + * + * May cause arbitrary side effects and invalidate (most) duk_tval + * pointers. + */ + +DUK_LOCAL duk_bool_t duk__get_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags) { + duk_hobject *curr; + duk_uint32_t arr_idx; + duk_uint_t sanity; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(obj != NULL); + DUK_ASSERT(key != NULL); + DUK_ASSERT(out_desc != NULL); + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + DUK_STATS_INC(thr->heap, stats_getpropdesc_count); + + arr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key); + + DUK_DDD(DUK_DDDPRINT("duk__get_propdesc: thr=%p, obj=%p, key=%p, out_desc=%p, flags=%lx, " + "arr_idx=%ld (obj -> %!O, key -> %!O)", + (void *) thr, (void *) obj, (void *) key, (void *) out_desc, + (long) flags, (long) arr_idx, + (duk_heaphdr *) obj, (duk_heaphdr *) key)); + + curr = obj; + DUK_ASSERT(curr != NULL); + sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY; + do { + if (duk__get_own_propdesc_raw(thr, curr, key, arr_idx, out_desc, flags)) { + /* stack contains value (if requested), 'out_desc' is set */ + DUK_STATS_INC(thr->heap, stats_getpropdesc_hit); + return 1; + } + + /* not found in 'curr', next in prototype chain; impose max depth */ + if (DUK_UNLIKELY(sanity-- == 0)) { + if (flags & DUK_GETDESC_FLAG_IGNORE_PROTOLOOP) { + /* treat like property not found */ + break; + } else { + DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT); + DUK_WO_NORETURN(return 0;); + } + } + curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr); + } while (curr != NULL); + + /* out_desc is left untouched (possibly garbage), caller must use return + * value to determine whether out_desc can be looked up + */ + + DUK_STATS_INC(thr->heap, stats_getpropdesc_miss); + return 0; +} + +/* + * Shallow fast path checks for accessing array elements with numeric + * indices. The goal is to try to avoid coercing an array index to an + * (interned) string for the most common lookups, in particular, for + * standard Array objects. + * + * Interning is avoided but only for a very narrow set of cases: + * - Object has array part, index is within array allocation, and + * value is not unused (= key exists) + * - Object has no interfering exotic behavior (e.g. arguments or + * string object exotic behaviors interfere, array exotic + * behavior does not). + * + * Current shortcoming: if key does not exist (even if it is within + * the array allocation range) a slow path lookup with interning is + * always required. This can probably be fixed so that there is a + * quick fast path for non-existent elements as well, at least for + * standard Array objects. + */ + +#if defined(DUK_USE_ARRAY_PROP_FASTPATH) +DUK_LOCAL duk_tval *duk__getprop_shallow_fastpath_array_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key) { + duk_tval *tv; + duk_uint32_t idx; + + DUK_UNREF(thr); + + if (!(DUK_HOBJECT_HAS_ARRAY_PART(obj) && + !DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj) && + !DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(obj) && + !DUK_HOBJECT_IS_BUFOBJ(obj) && + !DUK_HOBJECT_IS_PROXY(obj))) { + /* Must have array part and no conflicting exotic behaviors. + * Doesn't need to have array special behavior, e.g. Arguments + * object has array part. + */ + return NULL; + } + + /* Arrays never have other exotic behaviors. */ + + DUK_DDD(DUK_DDDPRINT("fast path attempt (no exotic string/arguments/buffer " + "behavior, object has array part)")); + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv_key)) { + idx = duk__tval_fastint_to_arr_idx(tv_key); + } else +#endif + if (DUK_TVAL_IS_DOUBLE(tv_key)) { + idx = duk__tval_number_to_arr_idx(tv_key); + } else { + DUK_DDD(DUK_DDDPRINT("key is not a number")); + return NULL; + } + + /* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which + * is 0xffffffffUL. We don't need to check for that explicitly + * because 0xffffffffUL will never be inside object 'a_size'. + */ + + if (idx >= DUK_HOBJECT_GET_ASIZE(obj)) { + DUK_DDD(DUK_DDDPRINT("key is not an array index or outside array part")); + return NULL; + } + DUK_ASSERT(idx != 0xffffffffUL); + DUK_ASSERT(idx != DUK__NO_ARRAY_INDEX); + + /* XXX: for array instances we could take a shortcut here and assume + * Array.prototype doesn't contain an array index property. + */ + + DUK_DDD(DUK_DDDPRINT("key is a valid array index and inside array part")); + tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, idx); + if (!DUK_TVAL_IS_UNUSED(tv)) { + DUK_DDD(DUK_DDDPRINT("-> fast path successful")); + return tv; + } + + DUK_DDD(DUK_DDDPRINT("fast path attempt failed, fall back to slow path")); + return NULL; +} + +DUK_LOCAL duk_bool_t duk__putprop_shallow_fastpath_array_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key, duk_tval *tv_val) { + duk_tval *tv; + duk_harray *a; + duk_uint32_t idx; + duk_uint32_t old_len, new_len; + + if (!(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj) && + DUK_HOBJECT_HAS_ARRAY_PART(obj) && + DUK_HOBJECT_HAS_EXTENSIBLE(obj))) { + return 0; + } + DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)); /* caller ensures */ + + a = (duk_harray *) obj; + DUK_HARRAY_ASSERT_VALID(a); + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv_key)) { + idx = duk__tval_fastint_to_arr_idx(tv_key); + } else +#endif + if (DUK_TVAL_IS_DOUBLE(tv_key)) { + idx = duk__tval_number_to_arr_idx(tv_key); + } else { + DUK_DDD(DUK_DDDPRINT("key is not a number")); + return 0; + } + + /* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which + * is 0xffffffffUL. We don't need to check for that explicitly + * because 0xffffffffUL will never be inside object 'a_size'. + */ + + if (idx >= DUK_HOBJECT_GET_ASIZE(obj)) { /* for resizing of array part, use slow path */ + return 0; + } + DUK_ASSERT(idx != 0xffffffffUL); + DUK_ASSERT(idx != DUK__NO_ARRAY_INDEX); + + old_len = a->length; + + if (idx >= old_len) { + DUK_DDD(DUK_DDDPRINT("write new array entry requires length update " + "(arr_idx=%ld, old_len=%ld)", + (long) idx, (long) old_len)); + if (DUK_HARRAY_LENGTH_NONWRITABLE(a)) { + /* The correct behavior here is either a silent error + * or a TypeError, depending on strictness. Fall back + * to the slow path to handle the situation. + */ + return 0; + } + new_len = idx + 1; + + ((duk_harray *) obj)->length = new_len; + } + + tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, idx); + DUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val); /* side effects */ + + DUK_DDD(DUK_DDDPRINT("array fast path success for index %ld", (long) idx)); + return 1; +} +#endif /* DUK_USE_ARRAY_PROP_FASTPATH */ + +/* + * Fast path for bufobj getprop/putprop + */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_LOCAL duk_bool_t duk__getprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key) { + duk_uint32_t idx; + duk_hbufobj *h_bufobj; + duk_uint_t byte_off; + duk_small_uint_t elem_size; + duk_uint8_t *data; + + if (!DUK_HOBJECT_IS_BUFOBJ(obj)) { + return 0; + } + h_bufobj = (duk_hbufobj *) obj; + if (!DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) { + return 0; + } + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv_key)) { + idx = duk__tval_fastint_to_arr_idx(tv_key); + } else +#endif + if (DUK_TVAL_IS_DOUBLE(tv_key)) { + idx = duk__tval_number_to_arr_idx(tv_key); + } else { + return 0; + } + + /* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which + * is 0xffffffffUL. We don't need to check for that explicitly + * because 0xffffffffUL will never be inside bufobj length. + */ + + /* Careful with wrapping (left shifting idx would be unsafe). */ + if (idx >= (h_bufobj->length >> h_bufobj->shift)) { + return 0; + } + DUK_ASSERT(idx != DUK__NO_ARRAY_INDEX); + + byte_off = idx << h_bufobj->shift; /* no wrap assuming h_bufobj->length is valid */ + elem_size = (duk_small_uint_t) (1U << h_bufobj->shift); + + if (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) { + data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off; + duk_hbufobj_push_validated_read(thr, h_bufobj, data, elem_size); + } else { + DUK_D(DUK_DPRINT("bufobj access out of underlying buffer, ignoring (read zero)")); + duk_push_uint(thr, 0); + } + + return 1; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) +DUK_LOCAL duk_bool_t duk__putprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key, duk_tval *tv_val) { + duk_uint32_t idx; + duk_hbufobj *h_bufobj; + duk_uint_t byte_off; + duk_small_uint_t elem_size; + duk_uint8_t *data; + + if (!(DUK_HOBJECT_IS_BUFOBJ(obj) && + DUK_TVAL_IS_NUMBER(tv_val))) { + return 0; + } + DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)); /* caller ensures; rom objects are never bufobjs now */ + + h_bufobj = (duk_hbufobj *) obj; + if (!DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) { + return 0; + } + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv_key)) { + idx = duk__tval_fastint_to_arr_idx(tv_key); + } else +#endif + if (DUK_TVAL_IS_DOUBLE(tv_key)) { + idx = duk__tval_number_to_arr_idx(tv_key); + } else { + return 0; + } + + /* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which + * is 0xffffffffUL. We don't need to check for that explicitly + * because 0xffffffffUL will never be inside bufobj length. + */ + + /* Careful with wrapping (left shifting idx would be unsafe). */ + if (idx >= (h_bufobj->length >> h_bufobj->shift)) { + return 0; + } + DUK_ASSERT(idx != DUK__NO_ARRAY_INDEX); + + byte_off = idx << h_bufobj->shift; /* no wrap assuming h_bufobj->length is valid */ + elem_size = (duk_small_uint_t) (1U << h_bufobj->shift); + + /* Value is required to be a number in the fast path so there + * are no side effects in write coercion. + */ + duk_push_tval(thr, tv_val); + DUK_ASSERT(duk_is_number(thr, -1)); + + if (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) { + data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off; + duk_hbufobj_validated_write(thr, h_bufobj, data, elem_size); + } else { + DUK_D(DUK_DPRINT("bufobj access out of underlying buffer, ignoring (write skipped)")); + } + + duk_pop_unsafe(thr); + return 1; +} +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + +/* + * GETPROP: ECMAScript property read. + */ + +DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key) { + duk_tval tv_obj_copy; + duk_tval tv_key_copy; + duk_hobject *curr = NULL; + duk_hstring *key = NULL; + duk_uint32_t arr_idx = DUK__NO_ARRAY_INDEX; + duk_propdesc desc; + duk_uint_t sanity; + + DUK_DDD(DUK_DDDPRINT("getprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)", + (void *) thr, (void *) tv_obj, (void *) tv_key, + (duk_tval *) tv_obj, (duk_tval *) tv_key)); + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(tv_obj != NULL); + DUK_ASSERT(tv_key != NULL); + + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + DUK_STATS_INC(thr->heap, stats_getprop_all); + + /* + * Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of + * them being invalidated by a valstack resize. + * + * XXX: this is now an overkill for many fast paths. Rework this + * to be faster (although switching to a valstack discipline might + * be a better solution overall). + */ + + DUK_TVAL_SET_TVAL(&tv_obj_copy, tv_obj); + DUK_TVAL_SET_TVAL(&tv_key_copy, tv_key); + tv_obj = &tv_obj_copy; + tv_key = &tv_key_copy; + + /* + * Coercion and fast path processing + */ + + switch (DUK_TVAL_GET_TAG(tv_obj)) { + case DUK_TAG_UNDEFINED: + case DUK_TAG_NULL: { + /* Note: unconditional throw */ + DUK_DDD(DUK_DDDPRINT("base object is undefined or null -> reject")); +#if defined(DUK_USE_PARANOID_ERRORS) + DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE); +#else + DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot read property %s of %s", + duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj)); +#endif + DUK_WO_NORETURN(return 0;); + break; + } + + case DUK_TAG_BOOLEAN: { + DUK_DDD(DUK_DDDPRINT("base object is a boolean, start lookup from boolean prototype")); + curr = thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE]; + break; + } + + case DUK_TAG_STRING: { + duk_hstring *h = DUK_TVAL_GET_STRING(tv_obj); + duk_int_t pop_count; + + if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) { + /* Symbols (ES2015 or hidden) don't have virtual properties. */ + DUK_DDD(DUK_DDDPRINT("base object is a symbol, start lookup from symbol prototype")); + curr = thr->builtins[DUK_BIDX_SYMBOL_PROTOTYPE]; + break; + } + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv_key)) { + arr_idx = duk__tval_fastint_to_arr_idx(tv_key); + DUK_DDD(DUK_DDDPRINT("base object string, key is a fast-path fastint; arr_idx %ld", (long) arr_idx)); + pop_count = 0; + } else +#endif + if (DUK_TVAL_IS_NUMBER(tv_key)) { + arr_idx = duk__tval_number_to_arr_idx(tv_key); + DUK_DDD(DUK_DDDPRINT("base object string, key is a fast-path number; arr_idx %ld", (long) arr_idx)); + pop_count = 0; + } else { + arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key); + DUK_ASSERT(key != NULL); + DUK_DDD(DUK_DDDPRINT("base object string, key is a non-fast-path number; after " + "coercion key is %!T, arr_idx %ld", + (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx)); + pop_count = 1; + } + + if (arr_idx != DUK__NO_ARRAY_INDEX && + arr_idx < DUK_HSTRING_GET_CHARLEN(h)) { + duk_pop_n_unsafe(thr, pop_count); + duk_push_hstring(thr, h); + duk_substring(thr, -1, arr_idx, arr_idx + 1); /* [str] -> [substr] */ + + DUK_STATS_INC(thr->heap, stats_getprop_stringidx); + DUK_DDD(DUK_DDDPRINT("-> %!T (base is string, key is an index inside string length " + "after coercion -> return char)", + (duk_tval *) duk_get_tval(thr, -1))); + return 1; + } + + if (pop_count == 0) { + /* This is a pretty awkward control flow, but we need to recheck the + * key coercion here. + */ + arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key); + DUK_ASSERT(key != NULL); + DUK_DDD(DUK_DDDPRINT("base object string, key is a non-fast-path number; after " + "coercion key is %!T, arr_idx %ld", + (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx)); + } + + if (key == DUK_HTHREAD_STRING_LENGTH(thr)) { + duk_pop_unsafe(thr); /* [key] -> [] */ + duk_push_uint(thr, (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h)); /* [] -> [res] */ + + DUK_STATS_INC(thr->heap, stats_getprop_stringlen); + DUK_DDD(DUK_DDDPRINT("-> %!T (base is string, key is 'length' after coercion -> " + "return string length)", + (duk_tval *) duk_get_tval(thr, -1))); + return 1; + } + + DUK_DDD(DUK_DDDPRINT("base object is a string, start lookup from string prototype")); + curr = thr->builtins[DUK_BIDX_STRING_PROTOTYPE]; + goto lookup; /* avoid double coercion */ + } + + case DUK_TAG_OBJECT: { +#if defined(DUK_USE_ARRAY_PROP_FASTPATH) + duk_tval *tmp; +#endif + + curr = DUK_TVAL_GET_OBJECT(tv_obj); + DUK_ASSERT(curr != NULL); + + /* XXX: array .length fast path (important in e.g. loops)? */ + +#if defined(DUK_USE_ARRAY_PROP_FASTPATH) + tmp = duk__getprop_shallow_fastpath_array_tval(thr, curr, tv_key); + if (tmp) { + duk_push_tval(thr, tmp); + + DUK_DDD(DUK_DDDPRINT("-> %!T (base is object, key is a number, array part " + "fast path)", + (duk_tval *) duk_get_tval(thr, -1))); + DUK_STATS_INC(thr->heap, stats_getprop_arrayidx); + return 1; + } +#endif + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + if (duk__getprop_fastpath_bufobj_tval(thr, curr, tv_key) != 0) { + /* Read value pushed on stack. */ + DUK_DDD(DUK_DDDPRINT("-> %!T (base is bufobj, key is a number, bufobj " + "fast path)", + (duk_tval *) duk_get_tval(thr, -1))); + DUK_STATS_INC(thr->heap, stats_getprop_bufobjidx); + return 1; + } +#endif + +#if defined(DUK_USE_ES6_PROXY) + if (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(curr))) { + duk_hobject *h_target; + + if (duk__proxy_check_prop(thr, curr, DUK_STRIDX_GET, tv_key, &h_target)) { + /* -> [ ... trap handler ] */ + DUK_DDD(DUK_DDDPRINT("-> proxy object 'get' for key %!T", (duk_tval *) tv_key)); + DUK_STATS_INC(thr->heap, stats_getprop_proxy); + duk_push_hobject(thr, h_target); /* target */ + duk_push_tval(thr, tv_key); /* P */ + duk_push_tval(thr, tv_obj); /* Receiver: Proxy object */ + duk_call_method(thr, 3 /*nargs*/); + + /* Target object must be checked for a conflicting + * non-configurable property. + */ + arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key); + DUK_ASSERT(key != NULL); + + if (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) { + duk_tval *tv_hook = duk_require_tval(thr, -3); /* value from hook */ + duk_tval *tv_targ = duk_require_tval(thr, -1); /* value from target */ + duk_bool_t datadesc_reject; + duk_bool_t accdesc_reject; + + DUK_DDD(DUK_DDDPRINT("proxy 'get': target has matching property %!O, check for " + "conflicting property; tv_hook=%!T, tv_targ=%!T, desc.flags=0x%08lx, " + "desc.get=%p, desc.set=%p", + (duk_heaphdr *) key, (duk_tval *) tv_hook, (duk_tval *) tv_targ, + (unsigned long) desc.flags, + (void *) desc.get, (void *) desc.set)); + + datadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) && + !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && + !(desc.flags & DUK_PROPDESC_FLAG_WRITABLE) && + !duk_js_samevalue(tv_hook, tv_targ); + accdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) && + !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && + (desc.get == NULL) && + !DUK_TVAL_IS_UNDEFINED(tv_hook); + if (datadesc_reject || accdesc_reject) { + DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED); + DUK_WO_NORETURN(return 0;); + } + + duk_pop_2_unsafe(thr); + } else { + duk_pop_unsafe(thr); + } + return 1; /* return value */ + } + + curr = h_target; /* resume lookup from target */ + DUK_TVAL_SET_OBJECT(tv_obj, curr); + } +#endif /* DUK_USE_ES6_PROXY */ + + if (DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(curr)) { + arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key); + DUK_ASSERT(key != NULL); + + DUK_STATS_INC(thr->heap, stats_getprop_arguments); + if (duk__check_arguments_map_for_get(thr, curr, key, &desc)) { + DUK_DDD(DUK_DDDPRINT("-> %!T (base is object with arguments exotic behavior, " + "key matches magically bound property -> skip standard " + "Get with replacement value)", + (duk_tval *) duk_get_tval(thr, -1))); + + /* no need for 'caller' post-check, because 'key' must be an array index */ + + duk_remove_m2(thr); /* [key result] -> [result] */ + return 1; + } + + goto lookup; /* avoid double coercion */ + } + break; + } + + /* Buffer has virtual properties similar to string, but indexed values + * are numbers, not 1-byte buffers/strings which would perform badly. + */ + case DUK_TAG_BUFFER: { + duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj); + duk_int_t pop_count; + + /* + * Because buffer values are often looped over, a number fast path + * is important. + */ + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv_key)) { + arr_idx = duk__tval_fastint_to_arr_idx(tv_key); + DUK_DDD(DUK_DDDPRINT("base object buffer, key is a fast-path fastint; arr_idx %ld", (long) arr_idx)); + pop_count = 0; + } + else +#endif + if (DUK_TVAL_IS_NUMBER(tv_key)) { + arr_idx = duk__tval_number_to_arr_idx(tv_key); + DUK_DDD(DUK_DDDPRINT("base object buffer, key is a fast-path number; arr_idx %ld", (long) arr_idx)); + pop_count = 0; + } else { + arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key); + DUK_ASSERT(key != NULL); + DUK_DDD(DUK_DDDPRINT("base object buffer, key is a non-fast-path number; after " + "coercion key is %!T, arr_idx %ld", + (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx)); + pop_count = 1; + } + + if (arr_idx != DUK__NO_ARRAY_INDEX && + arr_idx < DUK_HBUFFER_GET_SIZE(h)) { + duk_pop_n_unsafe(thr, pop_count); + duk_push_uint(thr, ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h))[arr_idx]); + DUK_STATS_INC(thr->heap, stats_getprop_bufferidx); + DUK_DDD(DUK_DDDPRINT("-> %!T (base is buffer, key is an index inside buffer length " + "after coercion -> return byte as number)", + (duk_tval *) duk_get_tval(thr, -1))); + return 1; + } + + if (pop_count == 0) { + /* This is a pretty awkward control flow, but we need to recheck the + * key coercion here. + */ + arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key); + DUK_ASSERT(key != NULL); + DUK_DDD(DUK_DDDPRINT("base object buffer, key is a non-fast-path number; after " + "coercion key is %!T, arr_idx %ld", + (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx)); + } + + if (key == DUK_HTHREAD_STRING_LENGTH(thr)) { + duk_pop_unsafe(thr); /* [key] -> [] */ + duk_push_uint(thr, (duk_uint_t) DUK_HBUFFER_GET_SIZE(h)); /* [] -> [res] */ + DUK_STATS_INC(thr->heap, stats_getprop_bufferlen); + + DUK_DDD(DUK_DDDPRINT("-> %!T (base is buffer, key is 'length' " + "after coercion -> return buffer length)", + (duk_tval *) duk_get_tval(thr, -1))); + return 1; + } + + DUK_DDD(DUK_DDDPRINT("base object is a buffer, start lookup from Uint8Array prototype")); + curr = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE]; + goto lookup; /* avoid double coercion */ + } + + case DUK_TAG_POINTER: { + DUK_DDD(DUK_DDDPRINT("base object is a pointer, start lookup from pointer prototype")); + curr = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE]; + break; + } + + case DUK_TAG_LIGHTFUNC: { + /* Lightfuncs inherit getter .name and .length from %NativeFunctionPrototype%. */ + DUK_DDD(DUK_DDDPRINT("base object is a lightfunc, start lookup from function prototype")); + curr = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE]; + break; + } + +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: +#endif + default: { + /* number */ + DUK_DDD(DUK_DDDPRINT("base object is a number, start lookup from number prototype")); + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_obj)); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_obj)); + curr = thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE]; + break; + } + } + + /* key coercion (unless already coerced above) */ + DUK_ASSERT(key == NULL); + arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key); + DUK_ASSERT(key != NULL); + /* + * Property lookup + */ + + lookup: + /* [key] (coerced) */ + DUK_ASSERT(curr != NULL); + DUK_ASSERT(key != NULL); + + sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY; + do { + if (!duk__get_own_propdesc_raw(thr, curr, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) { + goto next_in_chain; + } + + if (desc.get != NULL) { + /* accessor with defined getter */ + DUK_ASSERT((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) != 0); + + duk_pop_unsafe(thr); /* [key undefined] -> [key] */ + duk_push_hobject(thr, desc.get); + duk_push_tval(thr, tv_obj); /* note: original, uncoerced base */ +#if defined(DUK_USE_NONSTD_GETTER_KEY_ARGUMENT) + duk_dup_m3(thr); + duk_call_method(thr, 1); /* [key getter this key] -> [key retval] */ +#else + duk_call_method(thr, 0); /* [key getter this] -> [key retval] */ +#endif + } else { + /* [key value] or [key undefined] */ + + /* data property or accessor without getter */ + DUK_ASSERT(((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) == 0) || + (desc.get == NULL)); + + /* if accessor without getter, return value is undefined */ + DUK_ASSERT(((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) == 0) || + duk_is_undefined(thr, -1)); + + /* Note: for an accessor without getter, falling through to + * check for "caller" exotic behavior is unnecessary as + * "undefined" will never activate the behavior. But it does + * no harm, so we'll do it anyway. + */ + } + + goto found; /* [key result] */ + + next_in_chain: + /* XXX: option to pretend property doesn't exist if sanity limit is + * hit might be useful. + */ + if (DUK_UNLIKELY(sanity-- == 0)) { + DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT); + DUK_WO_NORETURN(return 0;); + } + curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr); + } while (curr != NULL); + + /* + * Not found + */ + + duk_to_undefined(thr, -1); /* [key] -> [undefined] (default value) */ + + DUK_DDD(DUK_DDDPRINT("-> %!T (not found)", (duk_tval *) duk_get_tval(thr, -1))); + return 0; + + /* + * Found; post-processing (Function and arguments objects) + */ + + found: + /* [key result] */ + +#if !defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY) + /* Special behavior for 'caller' property of (non-bound) function objects + * and non-strict Arguments objects: if 'caller' -value- (!) is a strict + * mode function, throw a TypeError (E5 Sections 15.3.5.4, 10.6). + * Quite interestingly, a non-strict function with no formal arguments + * will get an arguments object -without- special 'caller' behavior! + * + * The E5.1 spec is a bit ambiguous if this special behavior applies when + * a bound function is the base value (not the 'caller' value): Section + * 15.3.4.5 (describing bind()) states that [[Get]] for bound functions + * matches that of Section 15.3.5.4 ([[Get]] for Function instances). + * However, Section 13.3.5.4 has "NOTE: Function objects created using + * Function.prototype.bind use the default [[Get]] internal method." + * The current implementation assumes this means that bound functions + * should not have the special [[Get]] behavior. + * + * The E5.1 spec is also a bit unclear if the TypeError throwing is + * applied if the 'caller' value is a strict bound function. The + * current implementation will throw even for both strict non-bound + * and strict bound functions. + * + * See test-dev-strict-func-as-caller-prop-value.js for quite extensive + * tests. + * + * This exotic behavior is disabled when the non-standard 'caller' property + * is enabled, as it conflicts with the free use of 'caller'. + */ + if (key == DUK_HTHREAD_STRING_CALLER(thr) && + DUK_TVAL_IS_OBJECT(tv_obj)) { + duk_hobject *orig = DUK_TVAL_GET_OBJECT(tv_obj); + DUK_ASSERT(orig != NULL); + + if (DUK_HOBJECT_IS_NONBOUND_FUNCTION(orig) || + DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(orig)) { + duk_hobject *h; + + /* XXX: The TypeError is currently not applied to bound + * functions because the 'strict' flag is not copied by + * bind(). This may or may not be correct, the specification + * only refers to the value being a "strict mode Function + * object" which is ambiguous. + */ + DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(orig)); + + h = duk_get_hobject(thr, -1); /* NULL if not an object */ + if (h && + DUK_HOBJECT_IS_FUNCTION(h) && + DUK_HOBJECT_HAS_STRICT(h)) { + /* XXX: sufficient to check 'strict', assert for 'is function' */ + DUK_ERROR_TYPE(thr, DUK_STR_STRICT_CALLER_READ); + DUK_WO_NORETURN(return 0;); + } + } + } +#endif /* !DUK_USE_NONSTD_FUNC_CALLER_PROPERTY */ + + duk_remove_m2(thr); /* [key result] -> [result] */ + + DUK_DDD(DUK_DDDPRINT("-> %!T (found)", (duk_tval *) duk_get_tval(thr, -1))); + return 1; +} + +/* + * HASPROP: ECMAScript property existence check ("in" operator). + * + * Interestingly, the 'in' operator does not do any coercion of + * the target object. + */ + +DUK_INTERNAL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key) { + duk_tval tv_key_copy; + duk_hobject *obj; + duk_hstring *key; + duk_uint32_t arr_idx; + duk_bool_t rc; + duk_propdesc desc; + + DUK_DDD(DUK_DDDPRINT("hasprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)", + (void *) thr, (void *) tv_obj, (void *) tv_key, + (duk_tval *) tv_obj, (duk_tval *) tv_key)); + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(tv_obj != NULL); + DUK_ASSERT(tv_key != NULL); + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + DUK_TVAL_SET_TVAL(&tv_key_copy, tv_key); + tv_key = &tv_key_copy; + + /* + * The 'in' operator requires an object as its right hand side, + * throwing a TypeError unconditionally if this is not the case. + * + * However, lightfuncs need to behave like fully fledged objects + * here to be maximally transparent, so we need to handle them + * here. Same goes for plain buffers which behave like ArrayBuffers. + */ + + /* XXX: Refactor key coercion so that it's only called once. It can't + * be trivially lifted here because the object must be type checked + * first. + */ + + if (DUK_TVAL_IS_OBJECT(tv_obj)) { + obj = DUK_TVAL_GET_OBJECT(tv_obj); + DUK_ASSERT(obj != NULL); + + arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key); + } else if (DUK_TVAL_IS_BUFFER(tv_obj)) { + arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key); + if (duk__key_is_plain_buf_ownprop(thr, DUK_TVAL_GET_BUFFER(tv_obj), key, arr_idx)) { + rc = 1; + goto pop_and_return; + } + obj = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE]; + } else if (DUK_TVAL_IS_LIGHTFUNC(tv_obj)) { + arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key); + + /* If not found, resume existence check from %NativeFunctionPrototype%. + * We can just substitute the value in this case; nothing will + * need the original base value (as would be the case with e.g. + * setters/getters. + */ + obj = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE]; + } else { + /* Note: unconditional throw */ + DUK_DDD(DUK_DDDPRINT("base object is not an object -> reject")); + DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE); + DUK_WO_NORETURN(return 0;); + } + + /* XXX: fast path for arrays? */ + + DUK_ASSERT(key != NULL); + DUK_ASSERT(obj != NULL); + DUK_UNREF(arr_idx); + +#if defined(DUK_USE_ES6_PROXY) + if (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(obj))) { + duk_hobject *h_target; + duk_bool_t tmp_bool; + + /* XXX: the key in 'key in obj' is string coerced before we're called + * (which is the required behavior in E5/E5.1/E6) so the key is a string + * here already. + */ + + if (duk__proxy_check_prop(thr, obj, DUK_STRIDX_HAS, tv_key, &h_target)) { + /* [ ... key trap handler ] */ + DUK_DDD(DUK_DDDPRINT("-> proxy object 'has' for key %!T", (duk_tval *) tv_key)); + duk_push_hobject(thr, h_target); /* target */ + duk_push_tval(thr, tv_key); /* P */ + duk_call_method(thr, 2 /*nargs*/); + tmp_bool = duk_to_boolean_top_pop(thr); + if (!tmp_bool) { + /* Target object must be checked for a conflicting + * non-configurable property. + */ + + if (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, 0 /*flags*/)) { /* don't push value */ + DUK_DDD(DUK_DDDPRINT("proxy 'has': target has matching property %!O, check for " + "conflicting property; desc.flags=0x%08lx, " + "desc.get=%p, desc.set=%p", + (duk_heaphdr *) key, (unsigned long) desc.flags, + (void *) desc.get, (void *) desc.set)); + /* XXX: Extensibility check for target uses IsExtensible(). If we + * implemented the isExtensible trap and didn't reject proxies as + * proxy targets, it should be respected here. + */ + if (!((desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && /* property is configurable and */ + DUK_HOBJECT_HAS_EXTENSIBLE(h_target))) { /* ... target is extensible */ + DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED); + DUK_WO_NORETURN(return 0;); + } + } + } + + duk_pop_unsafe(thr); /* [ key ] -> [] */ + return tmp_bool; + } + + obj = h_target; /* resume check from proxy target */ + } +#endif /* DUK_USE_ES6_PROXY */ + + /* XXX: inline into a prototype walking loop? */ + + rc = duk__get_propdesc(thr, obj, key, &desc, 0 /*flags*/); /* don't push value */ + /* fall through */ + + pop_and_return: + duk_pop_unsafe(thr); /* [ key ] -> [] */ + return rc; +} + +/* + * HASPROP variant used internally. + * + * This primitive must never throw an error, callers rely on this. + * In particular, don't throw an error for prototype loops; instead, + * pretend like the property doesn't exist if a prototype sanity limit + * is reached. + * + * Does not implement proxy behavior: if applied to a proxy object, + * returns key existence on the proxy object itself. + */ + +DUK_INTERNAL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key) { + duk_propdesc dummy; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(obj != NULL); + DUK_ASSERT(key != NULL); + + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + return duk__get_propdesc(thr, obj, key, &dummy, DUK_GETDESC_FLAG_IGNORE_PROTOLOOP); /* don't push value */ +} + +/* + * Helper: handle Array object 'length' write which automatically + * deletes properties, see E5 Section 15.4.5.1, step 3. This is + * quite tricky to get right. + * + * Used by duk_hobject_putprop(). + */ + +/* Coerce a new .length candidate to a number and check that it's a valid + * .length. + */ +DUK_LOCAL duk_uint32_t duk__to_new_array_length_checked(duk_hthread *thr, duk_tval *tv) { + duk_uint32_t res; + duk_double_t d; + +#if !defined(DUK_USE_PREFER_SIZE) +#if defined(DUK_USE_FASTINT) + /* When fastints are enabled, the most interesting case is assigning + * a fastint to .length (e.g. arr.length = 0). + */ + if (DUK_TVAL_IS_FASTINT(tv)) { + /* Very common case. */ + duk_int64_t fi; + fi = DUK_TVAL_GET_FASTINT(tv); + if (fi < 0 || fi > DUK_I64_CONSTANT(0xffffffff)) { + goto fail_range; + } + return (duk_uint32_t) fi; + } +#else /* DUK_USE_FASTINT */ + /* When fastints are not enabled, the most interesting case is any + * number. + */ + if (DUK_TVAL_IS_DOUBLE(tv)) { + d = DUK_TVAL_GET_NUMBER(tv); + } +#endif /* DUK_USE_FASTINT */ + else +#endif /* !DUK_USE_PREFER_SIZE */ + { + /* In all other cases, and when doing a size optimized build, + * fall back to the comprehensive handler. + */ + d = duk_js_tonumber(thr, tv); + } + + /* Refuse to update an Array's 'length' to a value outside the + * 32-bit range. Negative zero is accepted as zero. + */ + res = duk_double_to_uint32_t(d); + if (!duk_double_equals((duk_double_t) res, d)) { + goto fail_range; + } + + return res; + + fail_range: + DUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARRAY_LENGTH); + DUK_WO_NORETURN(return 0;); +} + +/* Delete elements required by a smaller length, taking into account + * potentially non-configurable elements. Returns non-zero if all + * elements could be deleted, and zero if all or some elements could + * not be deleted. Also writes final "target length" to 'out_result_len'. + * This is the length value that should go into the 'length' property + * (must be set by the caller). Never throws an error. + */ +DUK_LOCAL +duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr, + duk_hobject *obj, + duk_uint32_t old_len, + duk_uint32_t new_len, + duk_bool_t force_flag, + duk_uint32_t *out_result_len) { + duk_uint32_t target_len; + duk_uint_fast32_t i; + duk_uint32_t arr_idx; + duk_hstring *key; + duk_tval *tv; + duk_bool_t rc; + + DUK_DDD(DUK_DDDPRINT("new array length smaller than old (%ld -> %ld), " + "probably need to remove elements", + (long) old_len, (long) new_len)); + + /* + * New length is smaller than old length, need to delete properties above + * the new length. + * + * If array part exists, this is straightforward: array entries cannot + * be non-configurable so this is guaranteed to work. + * + * If array part does not exist, array-indexed values are scattered + * in the entry part, and some may not be configurable (preventing length + * from becoming lower than their index + 1). To handle the algorithm + * in E5 Section 15.4.5.1, step l correctly, we scan the entire property + * set twice. + */ + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(obj != NULL); + DUK_ASSERT(new_len < old_len); + DUK_ASSERT(out_result_len != NULL); + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)); + DUK_ASSERT(DUK_HOBJECT_IS_ARRAY(obj)); + + if (DUK_HOBJECT_HAS_ARRAY_PART(obj)) { + /* + * All defined array-indexed properties are in the array part + * (we assume the array part is comprehensive), and all array + * entries are writable, configurable, and enumerable. Thus, + * nothing can prevent array entries from being deleted. + */ + + DUK_DDD(DUK_DDDPRINT("have array part, easy case")); + + if (old_len < DUK_HOBJECT_GET_ASIZE(obj)) { + /* XXX: assertion that entries >= old_len are already unused */ + i = old_len; + } else { + i = DUK_HOBJECT_GET_ASIZE(obj); + } + DUK_ASSERT(i <= DUK_HOBJECT_GET_ASIZE(obj)); + + while (i > new_len) { + i--; + tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i); + DUK_TVAL_SET_UNUSED_UPDREF(thr, tv); /* side effects */ + } + + *out_result_len = new_len; + return 1; + } else { + /* + * Entries part is a bit more complex. + */ + + /* Stage 1: find highest preventing non-configurable entry (if any). + * When forcing, ignore non-configurability. + */ + + DUK_DDD(DUK_DDDPRINT("no array part, slow case")); + + DUK_DDD(DUK_DDDPRINT("array length write, no array part, stage 1: find target_len " + "(highest preventing non-configurable entry (if any))")); + + target_len = new_len; + if (force_flag) { + DUK_DDD(DUK_DDDPRINT("array length write, no array part; force flag -> skip stage 1")); + goto skip_stage1; + } + for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) { + key = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i); + if (!key) { + DUK_DDD(DUK_DDDPRINT("skip entry index %ld: null key", (long) i)); + continue; + } + if (!DUK_HSTRING_HAS_ARRIDX(key)) { + DUK_DDD(DUK_DDDPRINT("skip entry index %ld: key not an array index", (long) i)); + continue; + } + + DUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(key)); /* XXX: macro checks for array index flag, which is unnecessary here */ + arr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key); + DUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX); + DUK_ASSERT(arr_idx < old_len); /* consistency requires this */ + + if (arr_idx < new_len) { + DUK_DDD(DUK_DDDPRINT("skip entry index %ld: key is array index %ld, below new_len", + (long) i, (long) arr_idx)); + continue; + } + if (DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(thr->heap, obj, i)) { + DUK_DDD(DUK_DDDPRINT("skip entry index %ld: key is a relevant array index %ld, but configurable", + (long) i, (long) arr_idx)); + continue; + } + + /* relevant array index is non-configurable, blocks write */ + if (arr_idx >= target_len) { + DUK_DDD(DUK_DDDPRINT("entry at index %ld has arr_idx %ld, is not configurable, " + "update target_len %ld -> %ld", + (long) i, (long) arr_idx, (long) target_len, + (long) (arr_idx + 1))); + target_len = arr_idx + 1; + } + } + skip_stage1: + + /* stage 2: delete configurable entries above target length */ + + DUK_DDD(DUK_DDDPRINT("old_len=%ld, new_len=%ld, target_len=%ld", + (long) old_len, (long) new_len, (long) target_len)); + + DUK_DDD(DUK_DDDPRINT("array length write, no array part, stage 2: remove " + "entries >= target_len")); + + for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) { + key = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i); + if (!key) { + DUK_DDD(DUK_DDDPRINT("skip entry index %ld: null key", (long) i)); + continue; + } + if (!DUK_HSTRING_HAS_ARRIDX(key)) { + DUK_DDD(DUK_DDDPRINT("skip entry index %ld: key not an array index", (long) i)); + continue; + } + + DUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(key)); /* XXX: macro checks for array index flag, which is unnecessary here */ + arr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key); + DUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX); + DUK_ASSERT(arr_idx < old_len); /* consistency requires this */ + + if (arr_idx < target_len) { + DUK_DDD(DUK_DDDPRINT("skip entry index %ld: key is array index %ld, below target_len", + (long) i, (long) arr_idx)); + continue; + } + DUK_ASSERT(force_flag || DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(thr->heap, obj, i)); /* stage 1 guarantees */ + + DUK_DDD(DUK_DDDPRINT("delete entry index %ld: key is array index %ld", + (long) i, (long) arr_idx)); + + /* + * Slow delete, but we don't care as we're already in a very slow path. + * The delete always succeeds: key has no exotic behavior, property + * is configurable, and no resize occurs. + */ + rc = duk_hobject_delprop_raw(thr, obj, key, force_flag ? DUK_DELPROP_FLAG_FORCE : 0); + DUK_UNREF(rc); + DUK_ASSERT(rc != 0); + } + + /* stage 3: update length (done by caller), decide return code */ + + DUK_DDD(DUK_DDDPRINT("array length write, no array part, stage 3: update length (done by caller)")); + + *out_result_len = target_len; + + if (target_len == new_len) { + DUK_DDD(DUK_DDDPRINT("target_len matches new_len, return success")); + return 1; + } + DUK_DDD(DUK_DDDPRINT("target_len does not match new_len (some entry prevented " + "full length adjustment), return error")); + return 0; + } + + DUK_UNREACHABLE(); +} + +/* XXX: is valstack top best place for argument? */ +DUK_LOCAL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject *obj) { + duk_harray *a; + duk_uint32_t old_len; + duk_uint32_t new_len; + duk_uint32_t result_len; + duk_bool_t rc; + + DUK_DDD(DUK_DDDPRINT("handling a put operation to array 'length' exotic property, " + "new val: %!T", + (duk_tval *) duk_get_tval(thr, -1))); + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(obj != NULL); + + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)); + DUK_ASSERT(DUK_HOBJECT_IS_ARRAY(obj)); + a = (duk_harray *) obj; + DUK_HARRAY_ASSERT_VALID(a); + + DUK_ASSERT(duk_is_valid_index(thr, -1)); + + /* + * Get old and new length + */ + + old_len = a->length; + new_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_NEGIDX(thr, -1)); + DUK_DDD(DUK_DDDPRINT("old_len=%ld, new_len=%ld", (long) old_len, (long) new_len)); + + /* + * Writability check + */ + + if (DUK_HARRAY_LENGTH_NONWRITABLE(a)) { + DUK_DDD(DUK_DDDPRINT("length is not writable, fail")); + return 0; + } + + /* + * New length not lower than old length => no changes needed + * (not even array allocation). + */ + + if (new_len >= old_len) { + DUK_DDD(DUK_DDDPRINT("new length is same or higher than old length, just update length, no deletions")); + a->length = new_len; + return 1; + } + + DUK_DDD(DUK_DDDPRINT("new length is lower than old length, probably must delete entries")); + + /* + * New length lower than old length => delete elements, then + * update length. + * + * Note: even though a bunch of elements have been deleted, the 'desc' is + * still valid as properties haven't been resized (and entries compacted). + */ + + rc = duk__handle_put_array_length_smaller(thr, obj, old_len, new_len, 0 /*force_flag*/, &result_len); + DUK_ASSERT(result_len >= new_len && result_len <= old_len); + + a->length = result_len; + + /* XXX: shrink array allocation or entries compaction here? */ + + return rc; +} + +/* + * PUTPROP: ECMAScript property write. + * + * Unlike ECMAScript primitive which returns nothing, returns 1 to indicate + * success and 0 to indicate failure (assuming throw is not set). + * + * This is an extremely tricky function. Some examples: + * + * * Currently a decref may trigger a GC, which may compact an object's + * property allocation. Consequently, any entry indices (e_idx) will + * be potentially invalidated by a decref. + * + * * Exotic behaviors (strings, arrays, arguments object) require, + * among other things: + * + * - Preprocessing before and postprocessing after an actual property + * write. For example, array index write requires pre-checking the + * array 'length' property for access control, and may require an + * array 'length' update after the actual write has succeeded (but + * not if it fails). + * + * - Deletion of multiple entries, as a result of array 'length' write. + * + * * Input values are taken as pointers which may point to the valstack. + * If valstack is resized because of the put (this may happen at least + * when the array part is abandoned), the pointers can be invalidated. + * (We currently make a copy of all of the input values to avoid issues.) + */ + +DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_tval *tv_val, duk_bool_t throw_flag) { + duk_tval tv_obj_copy; + duk_tval tv_key_copy; + duk_tval tv_val_copy; + duk_hobject *orig = NULL; /* NULL if tv_obj is primitive */ + duk_hobject *curr; + duk_hstring *key = NULL; + duk_propdesc desc; + duk_tval *tv; + duk_uint32_t arr_idx; + duk_bool_t rc; + duk_int_t e_idx; + duk_uint_t sanity; + duk_uint32_t new_array_length = 0; /* 0 = no update */ + + DUK_DDD(DUK_DDDPRINT("putprop: thr=%p, obj=%p, key=%p, val=%p, throw=%ld " + "(obj -> %!T, key -> %!T, val -> %!T)", + (void *) thr, (void *) tv_obj, (void *) tv_key, (void *) tv_val, + (long) throw_flag, (duk_tval *) tv_obj, (duk_tval *) tv_key, (duk_tval *) tv_val)); + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(tv_obj != NULL); + DUK_ASSERT(tv_key != NULL); + DUK_ASSERT(tv_val != NULL); + + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + DUK_STATS_INC(thr->heap, stats_putprop_all); + + /* + * Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of + * them being invalidated by a valstack resize. + * + * XXX: this is an overkill for some paths, so optimize this later + * (or maybe switch to a stack arguments model entirely). + */ + + DUK_TVAL_SET_TVAL(&tv_obj_copy, tv_obj); + DUK_TVAL_SET_TVAL(&tv_key_copy, tv_key); + DUK_TVAL_SET_TVAL(&tv_val_copy, tv_val); + tv_obj = &tv_obj_copy; + tv_key = &tv_key_copy; + tv_val = &tv_val_copy; + + /* + * Coercion and fast path processing. + */ + + switch (DUK_TVAL_GET_TAG(tv_obj)) { + case DUK_TAG_UNDEFINED: + case DUK_TAG_NULL: { + /* Note: unconditional throw */ + DUK_DDD(DUK_DDDPRINT("base object is undefined or null -> reject (object=%!iT)", + (duk_tval *) tv_obj)); +#if defined(DUK_USE_PARANOID_ERRORS) + DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE); +#else + DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot write property %s of %s", + duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj)); +#endif + DUK_WO_NORETURN(return 0;); + break; + } + + case DUK_TAG_BOOLEAN: { + DUK_DDD(DUK_DDDPRINT("base object is a boolean, start lookup from boolean prototype")); + curr = thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE]; + break; + } + + case DUK_TAG_STRING: { + duk_hstring *h = DUK_TVAL_GET_STRING(tv_obj); + + /* + * Note: currently no fast path for array index writes. + * They won't be possible anyway as strings are immutable. + */ + + DUK_ASSERT(key == NULL); + arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key); + DUK_ASSERT(key != NULL); + + if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) { + /* Symbols (ES2015 or hidden) don't have virtual properties. */ + curr = thr->builtins[DUK_BIDX_SYMBOL_PROTOTYPE]; + goto lookup; + } + + if (key == DUK_HTHREAD_STRING_LENGTH(thr)) { + goto fail_not_writable; + } + + if (arr_idx != DUK__NO_ARRAY_INDEX && + arr_idx < DUK_HSTRING_GET_CHARLEN(h)) { + goto fail_not_writable; + } + + DUK_DDD(DUK_DDDPRINT("base object is a string, start lookup from string prototype")); + curr = thr->builtins[DUK_BIDX_STRING_PROTOTYPE]; + goto lookup; /* avoid double coercion */ + } + + case DUK_TAG_OBJECT: { + orig = DUK_TVAL_GET_OBJECT(tv_obj); + DUK_ASSERT(orig != NULL); + +#if defined(DUK_USE_ROM_OBJECTS) + /* With this check in place fast paths won't need read-only + * object checks. This is technically incorrect if there are + * setters that cause no writes to ROM objects, but current + * built-ins don't have such setters. + */ + if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) { + DUK_DD(DUK_DDPRINT("attempt to putprop on read-only target object")); + goto fail_not_writable_no_pop; /* Must avoid duk_pop() in exit path */ + } +#endif + + /* The fast path for array property put is not fully compliant: + * If one places conflicting number-indexed properties into + * Array.prototype (for example, a non-writable Array.prototype[7]) + * the fast path will incorrectly ignore them. + * + * This fast path could be made compliant by falling through + * to the slow path if the previous value was UNUSED. This would + * also remove the need to check for extensibility. Right now a + * non-extensible array is slower than an extensible one as far + * as writes are concerned. + * + * The fast path behavior is documented in more detail here: + * tests/ecmascript/test-misc-array-fast-write.js + */ + + /* XXX: array .length? */ + +#if defined(DUK_USE_ARRAY_PROP_FASTPATH) + if (duk__putprop_shallow_fastpath_array_tval(thr, orig, tv_key, tv_val) != 0) { + DUK_DDD(DUK_DDDPRINT("array fast path success")); + DUK_STATS_INC(thr->heap, stats_putprop_arrayidx); + return 1; + } +#endif + +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + if (duk__putprop_fastpath_bufobj_tval(thr, orig, tv_key, tv_val) != 0) { + DUK_DDD(DUK_DDDPRINT("base is bufobj, key is a number, bufobj fast path")); + DUK_STATS_INC(thr->heap, stats_putprop_bufobjidx); + return 1; + } +#endif + +#if defined(DUK_USE_ES6_PROXY) + if (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(orig))) { + duk_hobject *h_target; + duk_bool_t tmp_bool; + + if (duk__proxy_check_prop(thr, orig, DUK_STRIDX_SET, tv_key, &h_target)) { + /* -> [ ... trap handler ] */ + DUK_DDD(DUK_DDDPRINT("-> proxy object 'set' for key %!T", (duk_tval *) tv_key)); + DUK_STATS_INC(thr->heap, stats_putprop_proxy); + duk_push_hobject(thr, h_target); /* target */ + duk_push_tval(thr, tv_key); /* P */ + duk_push_tval(thr, tv_val); /* V */ + duk_push_tval(thr, tv_obj); /* Receiver: Proxy object */ + duk_call_method(thr, 4 /*nargs*/); + tmp_bool = duk_to_boolean_top_pop(thr); + if (!tmp_bool) { + goto fail_proxy_rejected; + } + + /* Target object must be checked for a conflicting + * non-configurable property. + */ + arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key); + DUK_ASSERT(key != NULL); + + if (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) { + duk_tval *tv_targ = duk_require_tval(thr, -1); + duk_bool_t datadesc_reject; + duk_bool_t accdesc_reject; + + DUK_DDD(DUK_DDDPRINT("proxy 'set': target has matching property %!O, check for " + "conflicting property; tv_val=%!T, tv_targ=%!T, desc.flags=0x%08lx, " + "desc.get=%p, desc.set=%p", + (duk_heaphdr *) key, (duk_tval *) tv_val, (duk_tval *) tv_targ, + (unsigned long) desc.flags, + (void *) desc.get, (void *) desc.set)); + + datadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) && + !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && + !(desc.flags & DUK_PROPDESC_FLAG_WRITABLE) && + !duk_js_samevalue(tv_val, tv_targ); + accdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) && + !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && + (desc.set == NULL); + if (datadesc_reject || accdesc_reject) { + DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED); + DUK_WO_NORETURN(return 0;); + } + + duk_pop_2_unsafe(thr); + } else { + duk_pop_unsafe(thr); + } + return 1; /* success */ + } + + orig = h_target; /* resume write to target */ + DUK_TVAL_SET_OBJECT(tv_obj, orig); + } +#endif /* DUK_USE_ES6_PROXY */ + + curr = orig; + break; + } + + case DUK_TAG_BUFFER: { + duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj); + duk_int_t pop_count = 0; + + /* + * Because buffer values may be looped over and read/written + * from, an array index fast path is important. + */ + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv_key)) { + arr_idx = duk__tval_fastint_to_arr_idx(tv_key); + DUK_DDD(DUK_DDDPRINT("base object buffer, key is a fast-path fastint; arr_idx %ld", (long) arr_idx)); + pop_count = 0; + } else +#endif + if (DUK_TVAL_IS_NUMBER(tv_key)) { + arr_idx = duk__tval_number_to_arr_idx(tv_key); + DUK_DDD(DUK_DDDPRINT("base object buffer, key is a fast-path number; arr_idx %ld", (long) arr_idx)); + pop_count = 0; + } else { + arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key); + DUK_ASSERT(key != NULL); + DUK_DDD(DUK_DDDPRINT("base object buffer, key is a non-fast-path number; after " + "coercion key is %!T, arr_idx %ld", + (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx)); + pop_count = 1; + } + + if (arr_idx != DUK__NO_ARRAY_INDEX && + arr_idx < DUK_HBUFFER_GET_SIZE(h)) { + duk_uint8_t *data; + DUK_DDD(DUK_DDDPRINT("writing to buffer data at index %ld", (long) arr_idx)); + data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h); + + /* XXX: duk_to_int() ensures we'll get 8 lowest bits as + * as input is within duk_int_t range (capped outside it). + */ +#if defined(DUK_USE_FASTINT) + /* Buffer writes are often integers. */ + if (DUK_TVAL_IS_FASTINT(tv_val)) { + data[arr_idx] = (duk_uint8_t) DUK_TVAL_GET_FASTINT_U32(tv_val); + } + else +#endif + { + duk_push_tval(thr, tv_val); + data[arr_idx] = (duk_uint8_t) duk_to_uint32(thr, -1); + pop_count++; + } + + duk_pop_n_unsafe(thr, pop_count); + DUK_DDD(DUK_DDDPRINT("result: success (buffer data write)")); + DUK_STATS_INC(thr->heap, stats_putprop_bufferidx); + return 1; + } + + if (pop_count == 0) { + /* This is a pretty awkward control flow, but we need to recheck the + * key coercion here. + */ + arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key); + DUK_ASSERT(key != NULL); + DUK_DDD(DUK_DDDPRINT("base object buffer, key is a non-fast-path number; after " + "coercion key is %!T, arr_idx %ld", + (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx)); + } + + if (key == DUK_HTHREAD_STRING_LENGTH(thr)) { + goto fail_not_writable; + } + + DUK_DDD(DUK_DDDPRINT("base object is a buffer, start lookup from Uint8Array prototype")); + curr = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE]; + goto lookup; /* avoid double coercion */ + } + + case DUK_TAG_POINTER: { + DUK_DDD(DUK_DDDPRINT("base object is a pointer, start lookup from pointer prototype")); + curr = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE]; + break; + } + + case DUK_TAG_LIGHTFUNC: { + /* Lightfuncs have no own properties and are considered non-extensible. + * However, the write may be captured by an inherited setter which + * means we can't stop the lookup here. + */ + DUK_DDD(DUK_DDDPRINT("base object is a lightfunc, start lookup from function prototype")); + curr = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE]; + break; + } + +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: +#endif + default: { + /* number */ + DUK_DDD(DUK_DDDPRINT("base object is a number, start lookup from number prototype")); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_obj)); + curr = thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE]; + break; + } + } + + DUK_ASSERT(key == NULL); + arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key); + DUK_ASSERT(key != NULL); + + lookup: + + /* + * Check whether the property already exists in the prototype chain. + * Note that the actual write goes into the original base object + * (except if an accessor property captures the write). + */ + + /* [key] */ + + DUK_ASSERT(curr != NULL); + sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY; + do { + if (!duk__get_own_propdesc_raw(thr, curr, key, arr_idx, &desc, 0 /*flags*/)) { /* don't push value */ + goto next_in_chain; + } + + if (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) { + /* + * Found existing accessor property (own or inherited). + * Call setter with 'this' set to orig, and value as the only argument. + * Setter calls are OK even for ROM objects. + * + * Note: no exotic arguments object behavior, because [[Put]] never + * calls [[DefineOwnProperty]] (E5 Section 8.12.5, step 5.b). + */ + + duk_hobject *setter; + + DUK_DD(DUK_DDPRINT("put to an own or inherited accessor, calling setter")); + + setter = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, curr, desc.e_idx); + if (!setter) { + goto fail_no_setter; + } + duk_push_hobject(thr, setter); + duk_push_tval(thr, tv_obj); /* note: original, uncoerced base */ + duk_push_tval(thr, tv_val); /* [key setter this val] */ +#if defined(DUK_USE_NONSTD_SETTER_KEY_ARGUMENT) + duk_dup_m4(thr); + duk_call_method(thr, 2); /* [key setter this val key] -> [key retval] */ +#else + duk_call_method(thr, 1); /* [key setter this val] -> [key retval] */ +#endif + duk_pop_unsafe(thr); /* ignore retval -> [key] */ + goto success_no_arguments_exotic; + } + + if (orig == NULL) { + /* + * Found existing own or inherited plain property, but original + * base is a primitive value. + */ + DUK_DD(DUK_DDPRINT("attempt to create a new property in a primitive base object")); + goto fail_base_primitive; + } + + if (curr != orig) { + /* + * Found existing inherited plain property. + * Do an access control check, and if OK, write + * new property to 'orig'. + */ + if (!DUK_HOBJECT_HAS_EXTENSIBLE(orig)) { + DUK_DD(DUK_DDPRINT("found existing inherited plain property, but original object is not extensible")); + goto fail_not_extensible; + } + if (!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE)) { + DUK_DD(DUK_DDPRINT("found existing inherited plain property, original object is extensible, but inherited property is not writable")); + goto fail_not_writable; + } + DUK_DD(DUK_DDPRINT("put to new property, object extensible, inherited property found and is writable")); + goto create_new; + } else { + /* + * Found existing own (non-inherited) plain property. + * Do an access control check and update in place. + */ + + if (!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE)) { + DUK_DD(DUK_DDPRINT("found existing own (non-inherited) plain property, but property is not writable")); + goto fail_not_writable; + } + if (desc.flags & DUK_PROPDESC_FLAG_VIRTUAL) { + DUK_DD(DUK_DDPRINT("found existing own (non-inherited) virtual property, property is writable")); + + if (DUK_HOBJECT_IS_ARRAY(curr)) { + /* + * Write to 'length' of an array is a very complex case + * handled in a helper which updates both the array elements + * and writes the new 'length'. The write may result in an + * unconditional RangeError or a partial write (indicated + * by a return code). + * + * Note: the helper has an unnecessary writability check + * for 'length', we already know it is writable. + */ + DUK_ASSERT(key == DUK_HTHREAD_STRING_LENGTH(thr)); /* only virtual array property */ + + DUK_DDD(DUK_DDDPRINT("writing existing 'length' property to array exotic, invoke complex helper")); + + /* XXX: the helper currently assumes stack top contains new + * 'length' value and the whole calling convention is not very + * compatible with what we need. + */ + + duk_push_tval(thr, tv_val); /* [key val] */ + rc = duk__handle_put_array_length(thr, orig); + duk_pop_unsafe(thr); /* [key val] -> [key] */ + if (!rc) { + goto fail_array_length_partial; + } + + /* key is 'length', cannot match argument exotic behavior */ + goto success_no_arguments_exotic; + } +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + else if (DUK_HOBJECT_IS_BUFOBJ(curr)) { + duk_hbufobj *h_bufobj; + duk_uint_t byte_off; + duk_small_uint_t elem_size; + + h_bufobj = (duk_hbufobj *) curr; + DUK_HBUFOBJ_ASSERT_VALID(h_bufobj); + + DUK_DD(DUK_DDPRINT("writable virtual property is in buffer object")); + + /* Careful with wrapping: arr_idx upshift may easily wrap, whereas + * length downshift won't. + */ + if (arr_idx < (h_bufobj->length >> h_bufobj->shift) && DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) { + duk_uint8_t *data; + DUK_DDD(DUK_DDDPRINT("writing to buffer data at index %ld", (long) arr_idx)); + + DUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX); /* index/length check guarantees */ + byte_off = arr_idx << h_bufobj->shift; /* no wrap assuming h_bufobj->length is valid */ + elem_size = (duk_small_uint_t) (1U << h_bufobj->shift); + + /* Coerce to number before validating pointers etc so that the + * number coercions in duk_hbufobj_validated_write() are + * guaranteed to be side effect free and not invalidate the + * pointer checks we do here. + */ + duk_push_tval(thr, tv_val); + (void) duk_to_number_m1(thr); + + if (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) { + data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off; + duk_hbufobj_validated_write(thr, h_bufobj, data, elem_size); + } else { + DUK_D(DUK_DPRINT("bufobj access out of underlying buffer, ignoring (write skipped)")); + } + duk_pop_unsafe(thr); + goto success_no_arguments_exotic; + } + } +#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ + + DUK_D(DUK_DPRINT("should not happen, key %!O", key)); + goto fail_internal; /* should not happen */ + } + DUK_DD(DUK_DDPRINT("put to existing own plain property, property is writable")); + goto update_old; + } + DUK_UNREACHABLE(); + + next_in_chain: + /* XXX: option to pretend property doesn't exist if sanity limit is + * hit might be useful. + */ + if (DUK_UNLIKELY(sanity-- == 0)) { + DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT); + DUK_WO_NORETURN(return 0;); + } + curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr); + } while (curr != NULL); + + /* + * Property not found in prototype chain. + */ + + DUK_DDD(DUK_DDDPRINT("property not found in prototype chain")); + + if (orig == NULL) { + DUK_DD(DUK_DDPRINT("attempt to create a new property in a primitive base object")); + goto fail_base_primitive; + } + + if (!DUK_HOBJECT_HAS_EXTENSIBLE(orig)) { + DUK_DD(DUK_DDPRINT("put to a new property (not found in prototype chain), but original object not extensible")); + goto fail_not_extensible; + } + + goto create_new; + + update_old: + + /* + * Update an existing property of the base object. + */ + + /* [key] */ + + DUK_DDD(DUK_DDDPRINT("update an existing property of the original object")); + + DUK_ASSERT(orig != NULL); +#if defined(DUK_USE_ROM_OBJECTS) + /* This should not happen because DUK_TAG_OBJECT case checks + * for this already, but check just in case. + */ + if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) { + goto fail_not_writable; + } +#endif + + /* Although there are writable virtual properties (e.g. plain buffer + * and buffer object number indices), they are handled before we come + * here. + */ + DUK_ASSERT((desc.flags & DUK_PROPDESC_FLAG_VIRTUAL) == 0); + DUK_ASSERT(desc.a_idx >= 0 || desc.e_idx >= 0); + + /* Array own property .length is handled above. */ + DUK_ASSERT(!(DUK_HOBJECT_IS_ARRAY(orig) && key == DUK_HTHREAD_STRING_LENGTH(thr))); + + if (desc.e_idx >= 0) { + tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, desc.e_idx); + DUK_DDD(DUK_DDDPRINT("previous entry value: %!iT", (duk_tval *) tv)); + DUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val); /* side effects; e_idx may be invalidated */ + /* don't touch property attributes or hash part */ + DUK_DD(DUK_DDPRINT("put to an existing entry at index %ld -> new value %!iT", + (long) desc.e_idx, (duk_tval *) tv)); + } else { + /* Note: array entries are always writable, so the writability check + * above is pointless for them. The check could be avoided with some + * refactoring but is probably not worth it. + */ + + DUK_ASSERT(desc.a_idx >= 0); + tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, orig, desc.a_idx); + DUK_DDD(DUK_DDDPRINT("previous array value: %!iT", (duk_tval *) tv)); + DUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val); /* side effects; a_idx may be invalidated */ + DUK_DD(DUK_DDPRINT("put to an existing array entry at index %ld -> new value %!iT", + (long) desc.a_idx, (duk_tval *) tv)); + } + + /* Regardless of whether property is found in entry or array part, + * it may have arguments exotic behavior (array indices may reside + * in entry part for abandoned / non-existent array parts). + */ + goto success_with_arguments_exotic; + + create_new: + + /* + * Create a new property in the original object. + * + * Exotic properties need to be reconsidered here from a write + * perspective (not just property attributes perspective). + * However, the property does not exist in the object already, + * so this limits the kind of exotic properties that apply. + */ + + /* [key] */ + + DUK_DDD(DUK_DDDPRINT("create new property to original object")); + + DUK_ASSERT(orig != NULL); + + /* Array own property .length is handled above. */ + DUK_ASSERT(!(DUK_HOBJECT_IS_ARRAY(orig) && key == DUK_HTHREAD_STRING_LENGTH(thr))); + +#if defined(DUK_USE_ROM_OBJECTS) + /* This should not happen because DUK_TAG_OBJECT case checks + * for this already, but check just in case. + */ + if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) { + goto fail_not_writable; + } +#endif + + /* Not possible because array object 'length' is present + * from its creation and cannot be deleted, and is thus + * caught as an existing property above. + */ + DUK_ASSERT(!(DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig) && + key == DUK_HTHREAD_STRING_LENGTH(thr))); + + if (DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig) && + arr_idx != DUK__NO_ARRAY_INDEX) { + /* automatic length update */ + duk_uint32_t old_len; + duk_harray *a; + + a = (duk_harray *) orig; + DUK_HARRAY_ASSERT_VALID(a); + + old_len = a->length; + + if (arr_idx >= old_len) { + DUK_DDD(DUK_DDDPRINT("write new array entry requires length update " + "(arr_idx=%ld, old_len=%ld)", + (long) arr_idx, (long) old_len)); + + if (DUK_HARRAY_LENGTH_NONWRITABLE(a)) { + DUK_DD(DUK_DDPRINT("attempt to extend array, but array 'length' is not writable")); + goto fail_not_writable; + } + + /* Note: actual update happens once write has been completed + * without error below. The write should always succeed + * from a specification viewpoint, but we may e.g. run out + * of memory. It's safer in this order. + */ + + DUK_ASSERT(arr_idx != 0xffffffffUL); + new_array_length = arr_idx + 1; /* flag for later write */ + } else { + DUK_DDD(DUK_DDDPRINT("write new array entry does not require length update " + "(arr_idx=%ld, old_len=%ld)", + (long) arr_idx, (long) old_len)); + } + } + + /* write_to_array_part: */ + + /* + * Write to array part? + * + * Note: array abandonding requires a property resize which uses + * 'rechecks' valstack for temporaries and may cause any existing + * valstack pointers to be invalidated. To protect against this, + * tv_obj, tv_key, and tv_val are copies of the original inputs. + */ + + if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(orig)) { + tv = duk__obtain_arridx_slot(thr, arr_idx, orig); + if (tv == NULL) { + DUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(orig)); + goto write_to_entry_part; + } + + /* prev value must be unused, no decref */ + DUK_ASSERT(DUK_TVAL_IS_UNUSED(tv)); + DUK_TVAL_SET_TVAL(tv, tv_val); + DUK_TVAL_INCREF(thr, tv); + DUK_DD(DUK_DDPRINT("put to new array entry: %ld -> %!T", + (long) arr_idx, (duk_tval *) tv)); + + /* Note: array part values are [[Writable]], [[Enumerable]], + * and [[Configurable]] which matches the required attributes + * here. + */ + goto entry_updated; + } + + write_to_entry_part: + + /* + * Write to entry part + */ + + /* entry allocation updates hash part and increases the key + * refcount; may need a props allocation resize but doesn't + * 'recheck' the valstack. + */ + e_idx = duk__hobject_alloc_entry_checked(thr, orig, key); + DUK_ASSERT(e_idx >= 0); + + tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, e_idx); + /* prev value can be garbage, no decref */ + DUK_TVAL_SET_TVAL(tv, tv_val); + DUK_TVAL_INCREF(thr, tv); + DUK_HOBJECT_E_SET_FLAGS(thr->heap, orig, e_idx, DUK_PROPDESC_FLAGS_WEC); + goto entry_updated; + + entry_updated: + + /* + * Possible pending array length update, which must only be done + * if the actual entry write succeeded. + */ + + if (new_array_length > 0) { + /* Note: zero works as a "no update" marker because the new length + * can never be zero after a new property is written. + */ + + DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig)); + + DUK_DDD(DUK_DDDPRINT("write successful, pending array length update to: %ld", + (long) new_array_length)); + + ((duk_harray *) orig)->length = new_array_length; + } + + /* + * Arguments exotic behavior not possible for new properties: all + * magically bound properties are initially present in the arguments + * object, and if they are deleted, the binding is also removed from + * parameter map. + */ + + goto success_no_arguments_exotic; + + success_with_arguments_exotic: + + /* + * Arguments objects have exotic [[DefineOwnProperty]] which updates + * the internal 'map' of arguments for writes to currently mapped + * arguments. More conretely, writes to mapped arguments generate + * a write to a bound variable. + * + * The [[Put]] algorithm invokes [[DefineOwnProperty]] for existing + * data properties and new properties, but not for existing accessors. + * Hence, in E5 Section 10.6 ([[DefinedOwnProperty]] algorithm), we + * have a Desc with 'Value' (and possibly other properties too), and + * we end up in step 5.b.i. + */ + + if (arr_idx != DUK__NO_ARRAY_INDEX && + DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(orig)) { + /* Note: only numbered indices are relevant, so arr_idx fast reject + * is good (this is valid unless there are more than 4**32-1 arguments). + */ + + DUK_DDD(DUK_DDDPRINT("putprop successful, arguments exotic behavior needed")); + + /* Note: we can reuse 'desc' here */ + + /* XXX: top of stack must contain value, which helper doesn't touch, + * rework to use tv_val directly? + */ + + duk_push_tval(thr, tv_val); + (void) duk__check_arguments_map_for_put(thr, orig, key, &desc, throw_flag); + duk_pop_unsafe(thr); + } + /* fall thru */ + + success_no_arguments_exotic: + /* shared exit path now */ + DUK_DDD(DUK_DDDPRINT("result: success")); + duk_pop_unsafe(thr); /* remove key */ + return 1; + +#if defined(DUK_USE_ES6_PROXY) + fail_proxy_rejected: + DUK_DDD(DUK_DDDPRINT("result: error, proxy rejects")); + if (throw_flag) { + DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED); + DUK_WO_NORETURN(return 0;); + } + /* Note: no key on stack */ + return 0; +#endif + + fail_base_primitive: + DUK_DDD(DUK_DDDPRINT("result: error, base primitive")); + if (throw_flag) { +#if defined(DUK_USE_PARANOID_ERRORS) + DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE); +#else + DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot write property %s of %s", + duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj)); +#endif + DUK_WO_NORETURN(return 0;); + } + duk_pop_unsafe(thr); /* remove key */ + return 0; + + fail_not_extensible: + DUK_DDD(DUK_DDDPRINT("result: error, not extensible")); + if (throw_flag) { + DUK_ERROR_TYPE(thr, DUK_STR_NOT_EXTENSIBLE); + DUK_WO_NORETURN(return 0;); + } + duk_pop_unsafe(thr); /* remove key */ + return 0; + + fail_not_writable: + DUK_DDD(DUK_DDDPRINT("result: error, not writable")); + if (throw_flag) { + DUK_ERROR_TYPE(thr, DUK_STR_NOT_WRITABLE); + DUK_WO_NORETURN(return 0;); + } + duk_pop_unsafe(thr); /* remove key */ + return 0; + +#if defined(DUK_USE_ROM_OBJECTS) + fail_not_writable_no_pop: + DUK_DDD(DUK_DDDPRINT("result: error, not writable")); + if (throw_flag) { + DUK_ERROR_TYPE(thr, DUK_STR_NOT_WRITABLE); + DUK_WO_NORETURN(return 0;); + } + return 0; +#endif + + fail_array_length_partial: + DUK_DD(DUK_DDPRINT("result: error, array length write only partially successful")); + if (throw_flag) { + DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE); + DUK_WO_NORETURN(return 0;); + } + duk_pop_unsafe(thr); /* remove key */ + return 0; + + fail_no_setter: + DUK_DDD(DUK_DDDPRINT("result: error, accessor property without setter")); + if (throw_flag) { + DUK_ERROR_TYPE(thr, DUK_STR_SETTER_UNDEFINED); + DUK_WO_NORETURN(return 0;); + } + duk_pop_unsafe(thr); /* remove key */ + return 0; + + fail_internal: + DUK_DDD(DUK_DDDPRINT("result: error, internal")); + if (throw_flag) { + DUK_ERROR_INTERNAL(thr); + DUK_WO_NORETURN(return 0;); + } + duk_pop_unsafe(thr); /* remove key */ + return 0; +} + +/* + * ECMAScript compliant [[Delete]](P, Throw). + */ + +DUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags) { + duk_propdesc desc; + duk_tval *tv; + duk_uint32_t arr_idx; + duk_bool_t throw_flag; + duk_bool_t force_flag; + + throw_flag = (flags & DUK_DELPROP_FLAG_THROW); + force_flag = (flags & DUK_DELPROP_FLAG_FORCE); + + DUK_DDD(DUK_DDDPRINT("delprop_raw: thr=%p, obj=%p, key=%p, throw=%ld, force=%ld (obj -> %!O, key -> %!O)", + (void *) thr, (void *) obj, (void *) key, (long) throw_flag, (long) force_flag, + (duk_heaphdr *) obj, (duk_heaphdr *) key)); + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(obj != NULL); + DUK_ASSERT(key != NULL); + + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + arr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key); + + /* 0 = don't push current value */ + if (!duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &desc, 0 /*flags*/)) { /* don't push value */ + DUK_DDD(DUK_DDDPRINT("property not found, succeed always")); + goto success; + } + +#if defined(DUK_USE_ROM_OBJECTS) + if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) { + DUK_DD(DUK_DDPRINT("attempt to delprop on read-only target object")); + goto fail_not_configurable; + } +#endif + + if ((desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) == 0 && !force_flag) { + goto fail_not_configurable; + } + if (desc.a_idx < 0 && desc.e_idx < 0) { + /* Currently there are no deletable virtual properties, but + * with force_flag we might attempt to delete one. + */ + DUK_DD(DUK_DDPRINT("delete failed: property found, force flag, but virtual (and implicitly non-configurable)")); + goto fail_virtual; + } + + if (desc.a_idx >= 0) { + DUK_ASSERT(desc.e_idx < 0); + + tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, desc.a_idx); + DUK_TVAL_SET_UNUSED_UPDREF(thr, tv); /* side effects */ + goto success; + } else { + DUK_ASSERT(desc.a_idx < 0); + + /* remove hash entry (no decref) */ +#if defined(DUK_USE_HOBJECT_HASH_PART) + if (desc.h_idx >= 0) { + duk_uint32_t *h_base = DUK_HOBJECT_H_GET_BASE(thr->heap, obj); + + DUK_DDD(DUK_DDDPRINT("removing hash entry at h_idx %ld", (long) desc.h_idx)); + DUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) > 0); + DUK_ASSERT((duk_uint32_t) desc.h_idx < DUK_HOBJECT_GET_HSIZE(obj)); + h_base[desc.h_idx] = DUK__HASH_DELETED; + } else { + DUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) == 0); + } +#else + DUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) == 0); +#endif + + /* Remove value. This requires multiple writes so avoid side + * effects via no-refzero macros so that e_idx is not + * invalidated. + */ + DUK_DDD(DUK_DDDPRINT("before removing value, e_idx %ld, key %p, key at slot %p", + (long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx))); + DUK_DDD(DUK_DDDPRINT("removing value at e_idx %ld", (long) desc.e_idx)); + if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx)) { + duk_hobject *tmp; + + tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, desc.e_idx); + DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, desc.e_idx, NULL); + DUK_UNREF(tmp); + DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp); + + tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, desc.e_idx); + DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, desc.e_idx, NULL); + DUK_UNREF(tmp); + DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp); + } else { + tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx); + DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv); + } +#if 0 + /* Not strictly necessary because if key == NULL, flag MUST be ignored. */ + DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, desc.e_idx, 0); +#endif + + /* Remove key. */ + DUK_DDD(DUK_DDDPRINT("before removing key, e_idx %ld, key %p, key at slot %p", + (long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx))); + DUK_DDD(DUK_DDDPRINT("removing key at e_idx %ld", (long) desc.e_idx)); + DUK_ASSERT(key == DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx)); + DUK_HOBJECT_E_SET_KEY(thr->heap, obj, desc.e_idx, NULL); + DUK_HSTRING_DECREF_NORZ(thr, key); + + /* Trigger refzero side effects only when we're done as a + * finalizer might operate on the object and affect the + * e_idx we're supposed to use. + */ + DUK_REFZERO_CHECK_SLOW(thr); + goto success; + } + + DUK_UNREACHABLE(); + + success: + /* + * Argument exotic [[Delete]] behavior (E5 Section 10.6) is + * a post-check, keeping arguments internal 'map' in sync with + * any successful deletes (note that property does not need to + * exist for delete to 'succeed'). + * + * Delete key from 'map'. Since 'map' only contains array index + * keys, we can use arr_idx for a fast skip. + */ + + DUK_DDD(DUK_DDDPRINT("delete successful, check for arguments exotic behavior")); + + if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)) { + /* Note: only numbered indices are relevant, so arr_idx fast reject + * is good (this is valid unless there are more than 4**32-1 arguments). + */ + + DUK_DDD(DUK_DDDPRINT("delete successful, arguments exotic behavior needed")); + + /* Note: we can reuse 'desc' here */ + (void) duk__check_arguments_map_for_delete(thr, obj, key, &desc); + } + + DUK_DDD(DUK_DDDPRINT("delete successful")); + return 1; + + fail_virtual: /* just use the same "not configurable" error message */ + fail_not_configurable: + DUK_DDD(DUK_DDDPRINT("delete failed: property found, not configurable")); + + if (throw_flag) { + DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE); + DUK_WO_NORETURN(return 0;); + } + return 0; +} + +/* + * DELPROP: ECMAScript property deletion. + */ + +DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_bool_t throw_flag) { + duk_hstring *key = NULL; +#if defined(DUK_USE_ES6_PROXY) + duk_propdesc desc; +#endif + duk_int_t entry_top; + duk_uint32_t arr_idx = DUK__NO_ARRAY_INDEX; + duk_bool_t rc; + + DUK_DDD(DUK_DDDPRINT("delprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)", + (void *) thr, (void *) tv_obj, (void *) tv_key, + (duk_tval *) tv_obj, (duk_tval *) tv_key)); + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(tv_obj != NULL); + DUK_ASSERT(tv_key != NULL); + + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + /* Storing the entry top is cheaper here to ensure stack is correct at exit, + * as there are several paths out. + */ + entry_top = duk_get_top(thr); + + if (DUK_TVAL_IS_UNDEFINED(tv_obj) || + DUK_TVAL_IS_NULL(tv_obj)) { + DUK_DDD(DUK_DDDPRINT("base object is undefined or null -> reject")); + goto fail_invalid_base_uncond; + } + + duk_push_tval(thr, tv_obj); + duk_push_tval(thr, tv_key); + + tv_obj = DUK_GET_TVAL_NEGIDX(thr, -2); + if (DUK_TVAL_IS_OBJECT(tv_obj)) { + duk_hobject *obj = DUK_TVAL_GET_OBJECT(tv_obj); + DUK_ASSERT(obj != NULL); + +#if defined(DUK_USE_ES6_PROXY) + if (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(obj))) { + duk_hobject *h_target; + duk_bool_t tmp_bool; + + /* Note: proxy handling must happen before key is string coerced. */ + + if (duk__proxy_check_prop(thr, obj, DUK_STRIDX_DELETE_PROPERTY, tv_key, &h_target)) { + /* -> [ ... obj key trap handler ] */ + DUK_DDD(DUK_DDDPRINT("-> proxy object 'deleteProperty' for key %!T", (duk_tval *) tv_key)); + duk_push_hobject(thr, h_target); /* target */ + duk_dup_m4(thr); /* P */ + duk_call_method(thr, 2 /*nargs*/); + tmp_bool = duk_to_boolean_top_pop(thr); + if (!tmp_bool) { + goto fail_proxy_rejected; /* retval indicates delete failed */ + } + + /* Target object must be checked for a conflicting + * non-configurable property. + */ + tv_key = DUK_GET_TVAL_NEGIDX(thr, -1); + arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key); + DUK_ASSERT(key != NULL); + + if (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, 0 /*flags*/)) { /* don't push value */ + duk_small_int_t desc_reject; + + DUK_DDD(DUK_DDDPRINT("proxy 'deleteProperty': target has matching property %!O, check for " + "conflicting property; desc.flags=0x%08lx, " + "desc.get=%p, desc.set=%p", + (duk_heaphdr *) key, (unsigned long) desc.flags, + (void *) desc.get, (void *) desc.set)); + + desc_reject = !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE); + if (desc_reject) { + /* unconditional */ + DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED); + DUK_WO_NORETURN(return 0;); + } + } + rc = 1; /* success */ + goto done_rc; + } + + obj = h_target; /* resume delete to target */ + } +#endif /* DUK_USE_ES6_PROXY */ + + arr_idx = duk__to_property_key(thr, -1, &key); + DUK_ASSERT(key != NULL); + + rc = duk_hobject_delprop_raw(thr, obj, key, throw_flag ? DUK_DELPROP_FLAG_THROW : 0); + goto done_rc; + } else if (DUK_TVAL_IS_STRING(tv_obj)) { + /* String has .length and array index virtual properties + * which can't be deleted. No need for a symbol check; + * no offending virtual symbols exist. + */ + /* XXX: unnecessary string coercion for array indices, + * intentional to keep small. + */ + duk_hstring *h = DUK_TVAL_GET_STRING(tv_obj); + DUK_ASSERT(h != NULL); + + arr_idx = duk__to_property_key(thr, -1, &key); + DUK_ASSERT(key != NULL); + + if (key == DUK_HTHREAD_STRING_LENGTH(thr)) { + goto fail_not_configurable; + } + + if (arr_idx != DUK__NO_ARRAY_INDEX && + arr_idx < DUK_HSTRING_GET_CHARLEN(h)) { + goto fail_not_configurable; + } + } else if (DUK_TVAL_IS_BUFFER(tv_obj)) { + /* XXX: unnecessary string coercion for array indices, + * intentional to keep small; some overlap with string + * handling. + */ + duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj); + DUK_ASSERT(h != NULL); + + arr_idx = duk__to_property_key(thr, -1, &key); + DUK_ASSERT(key != NULL); + + if (key == DUK_HTHREAD_STRING_LENGTH(thr)) { + goto fail_not_configurable; + } + + if (arr_idx != DUK__NO_ARRAY_INDEX && + arr_idx < DUK_HBUFFER_GET_SIZE(h)) { + goto fail_not_configurable; + } + } else if (DUK_TVAL_IS_LIGHTFUNC(tv_obj)) { + /* Lightfunc has no virtual properties since Duktape 2.2 + * so success. Still must coerce key for side effects. + */ + + arr_idx = duk__to_property_key(thr, -1, &key); + DUK_ASSERT(key != NULL); + DUK_UNREF(key); + } + + /* non-object base, no offending virtual property */ + rc = 1; + goto done_rc; + + done_rc: + duk_set_top_unsafe(thr, entry_top); + return rc; + + fail_invalid_base_uncond: + /* Note: unconditional throw */ + DUK_ASSERT(duk_get_top(thr) == entry_top); +#if defined(DUK_USE_PARANOID_ERRORS) + DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE); +#else + DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot delete property %s of %s", + duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj)); +#endif + DUK_WO_NORETURN(return 0;); + +#if defined(DUK_USE_ES6_PROXY) + fail_proxy_rejected: + if (throw_flag) { + DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED); + DUK_WO_NORETURN(return 0;); + } + duk_set_top_unsafe(thr, entry_top); + return 0; +#endif + + fail_not_configurable: + if (throw_flag) { + DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE); + DUK_WO_NORETURN(return 0;); + } + duk_set_top_unsafe(thr, entry_top); + return 0; +} + +/* + * Internal helper to define a property with specific flags, ignoring + * normal semantics such as extensibility, write protection etc. + * Overwrites any existing value and attributes unless caller requests + * that value only be updated if it doesn't already exists. + * + * Does not support: + * - virtual properties (error if write attempted) + * - getter/setter properties (error if write attempted) + * - non-default (!= WEC) attributes for array entries (error if attempted) + * - array abandoning: if array part exists, it is always extended + * - array 'length' updating + * + * Stack: [... in_val] -> [] + * + * Used for e.g. built-in initialization and environment record + * operations. + */ + +DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags) { + duk_propdesc desc; + duk_uint32_t arr_idx; + duk_int_t e_idx; + duk_tval *tv1 = NULL; + duk_tval *tv2 = NULL; + duk_small_uint_t propflags = flags & DUK_PROPDESC_FLAGS_MASK; /* mask out flags not actually stored */ + + DUK_DDD(DUK_DDDPRINT("define new property (internal): thr=%p, obj=%!O, key=%!O, flags=0x%02lx, val=%!T", + (void *) thr, (duk_heaphdr *) obj, (duk_heaphdr *) key, + (unsigned long) flags, (duk_tval *) duk_get_tval(thr, -1))); + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(obj != NULL); + DUK_ASSERT(key != NULL); + DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)); + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + DUK_ASSERT(duk_is_valid_index(thr, -1)); /* contains value */ + + arr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key); + + if (duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &desc, 0 /*flags*/)) { /* don't push value */ + if (desc.e_idx >= 0) { + if (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) { + DUK_DDD(DUK_DDDPRINT("property already exists in the entry part -> skip as requested")); + goto pop_exit; + } + DUK_DDD(DUK_DDDPRINT("property already exists in the entry part -> update value and attributes")); + if (DUK_UNLIKELY(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx))) { + DUK_D(DUK_DPRINT("existing property is an accessor, not supported")); + goto error_internal; + } + + DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, desc.e_idx, propflags); + tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx); + } else if (desc.a_idx >= 0) { + if (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) { + DUK_DDD(DUK_DDDPRINT("property already exists in the array part -> skip as requested")); + goto pop_exit; + } + DUK_DDD(DUK_DDDPRINT("property already exists in the array part -> update value (assert attributes)")); + if (propflags != DUK_PROPDESC_FLAGS_WEC) { + DUK_D(DUK_DPRINT("existing property in array part, but propflags not WEC (0x%02lx)", + (unsigned long) propflags)); + goto error_internal; + } + + tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, desc.a_idx); + } else { + if (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) { + DUK_DDD(DUK_DDDPRINT("property already exists but is virtual -> skip as requested")); + goto pop_exit; + } + if (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) { + duk_uint32_t new_len; +#if defined(DUK_USE_DEBUG) + duk_uint32_t prev_len; + prev_len = ((duk_harray *) obj)->length; +#endif + new_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_NEGIDX(thr, -1)); + ((duk_harray *) obj)->length = new_len; + DUK_DD(DUK_DDPRINT("internal define property for array .length: %ld -> %ld", + (long) prev_len, (long) ((duk_harray *) obj)->length)); + goto pop_exit; + } + DUK_DD(DUK_DDPRINT("property already exists but is virtual -> failure")); + goto error_virtual; + } + + goto write_value; + } + + if (DUK_HOBJECT_HAS_ARRAY_PART(obj)) { + if (arr_idx != DUK__NO_ARRAY_INDEX) { + DUK_DDD(DUK_DDDPRINT("property does not exist, object has array part -> possibly extend array part and write value (assert attributes)")); + DUK_ASSERT(propflags == DUK_PROPDESC_FLAGS_WEC); + + tv1 = duk__obtain_arridx_slot(thr, arr_idx, obj); + if (tv1 == NULL) { + DUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj)); + goto write_to_entry_part; + } + + tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx); + goto write_value; + } + } + + write_to_entry_part: + DUK_DDD(DUK_DDDPRINT("property does not exist, object belongs in entry part -> allocate new entry and write value and attributes")); + e_idx = duk__hobject_alloc_entry_checked(thr, obj, key); /* increases key refcount */ + DUK_ASSERT(e_idx >= 0); + DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, propflags); + tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx); + /* new entry: previous value is garbage; set to undefined to share write_value */ + DUK_TVAL_SET_UNDEFINED(tv1); + goto write_value; + + write_value: + /* tv1 points to value storage */ + + tv2 = duk_require_tval(thr, -1); /* late lookup, avoid side effects */ + DUK_DDD(DUK_DDDPRINT("writing/updating value: %!T -> %!T", + (duk_tval *) tv1, (duk_tval *) tv2)); + + DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects */ + goto pop_exit; + + pop_exit: + duk_pop_unsafe(thr); /* remove in_val */ + return; + + error_virtual: /* share error message */ + error_internal: + DUK_ERROR_INTERNAL(thr); + DUK_WO_NORETURN(return;); +} + +/* + * Fast path for defining array indexed values without interning the key. + * This is used by e.g. code for Array prototype and traceback creation so + * must avoid interning. + */ + +DUK_INTERNAL void duk_hobject_define_property_internal_arridx(duk_hthread *thr, duk_hobject *obj, duk_uarridx_t arr_idx, duk_small_uint_t flags) { + duk_hstring *key; + duk_tval *tv1, *tv2; + + DUK_DDD(DUK_DDDPRINT("define new property (internal) arr_idx fast path: thr=%p, obj=%!O, " + "arr_idx=%ld, flags=0x%02lx, val=%!T", + (void *) thr, obj, (long) arr_idx, (unsigned long) flags, + (duk_tval *) duk_get_tval(thr, -1))); + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(obj != NULL); + DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)); + + if (DUK_HOBJECT_HAS_ARRAY_PART(obj) && + arr_idx != DUK__NO_ARRAY_INDEX && + flags == DUK_PROPDESC_FLAGS_WEC) { + DUK_ASSERT((flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) == 0); /* covered by comparison */ + + DUK_DDD(DUK_DDDPRINT("define property to array part (property may or may not exist yet)")); + + tv1 = duk__obtain_arridx_slot(thr, arr_idx, obj); + if (tv1 == NULL) { + DUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj)); + goto write_slow; + } + tv2 = duk_require_tval(thr, -1); + + DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects */ + + duk_pop_unsafe(thr); /* [ ...val ] -> [ ... ] */ + return; + } + + write_slow: + DUK_DDD(DUK_DDDPRINT("define property fast path didn't work, use slow path")); + + key = duk_push_uint_to_hstring(thr, (duk_uint_t) arr_idx); + DUK_ASSERT(key != NULL); + duk_insert(thr, -2); /* [ ... val key ] -> [ ... key val ] */ + + duk_hobject_define_property_internal(thr, obj, key, flags); + + duk_pop_unsafe(thr); /* [ ... key ] -> [ ... ] */ +} + +/* + * Internal helpers for managing object 'length' + */ + +DUK_INTERNAL duk_size_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj) { + duk_double_t val; + + DUK_CTX_ASSERT_VALID(thr); + DUK_ASSERT(obj != NULL); + + /* Fast path for Arrays. */ + if (DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) { + return ((duk_harray *) obj)->length; + } + + /* Slow path, .length can be e.g. accessor, obj can be a Proxy, etc. */ + duk_push_hobject(thr, obj); + duk_push_hstring_stridx(thr, DUK_STRIDX_LENGTH); + (void) duk_hobject_getprop(thr, + DUK_GET_TVAL_NEGIDX(thr, -2), + DUK_GET_TVAL_NEGIDX(thr, -1)); + val = duk_to_number_m1(thr); + duk_pop_3_unsafe(thr); + + /* This isn't part of ECMAScript semantics; return a value within + * duk_size_t range, or 0 otherwise. + */ + if (val >= 0.0 && val <= (duk_double_t) DUK_SIZE_MAX) { + return (duk_size_t) val; + } + return 0; +} + +/* + * Fast finalizer check for an object. Walks the prototype chain, checking + * for finalizer presence using DUK_HOBJECT_FLAG_HAVE_FINALIZER which is kept + * in sync with the actual property when setting/removing the finalizer. + */ + +#if defined(DUK_USE_HEAPPTR16) +DUK_INTERNAL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_heap *heap, duk_hobject *obj) { +#else +DUK_INTERNAL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_hobject *obj) { +#endif + duk_uint_t sanity; + + DUK_ASSERT(obj != NULL); + + sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY; + do { + if (DUK_UNLIKELY(DUK_HOBJECT_HAS_HAVE_FINALIZER(obj))) { + return 1; + } + if (DUK_UNLIKELY(sanity-- == 0)) { + DUK_D(DUK_DPRINT("prototype loop when checking for finalizer existence; returning false")); + return 0; + } +#if defined(DUK_USE_HEAPPTR16) + DUK_ASSERT(heap != NULL); + obj = DUK_HOBJECT_GET_PROTOTYPE(heap, obj); +#else + obj = DUK_HOBJECT_GET_PROTOTYPE(NULL, obj); /* 'heap' arg ignored */ +#endif + } while (obj != NULL); + + return 0; +} + +/* + * Object.getOwnPropertyDescriptor() (E5 Sections 15.2.3.3, 8.10.4) + * + * [ ... key ] -> [ ... desc/undefined ] + */ + +DUK_INTERNAL void duk_hobject_object_get_own_property_descriptor(duk_hthread *thr, duk_idx_t obj_idx) { + duk_hobject *obj; + duk_hstring *key; + duk_propdesc pd; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + + obj = duk_require_hobject_promote_mask(thr, obj_idx, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER); + key = duk_to_property_key_hstring(thr, -1); + DUK_ASSERT(key != NULL); + + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + if (!duk_hobject_get_own_propdesc(thr, obj, key, &pd, DUK_GETDESC_FLAG_PUSH_VALUE)) { + duk_push_undefined(thr); + duk_remove_m2(thr); + return; + } + + duk_push_object(thr); + + /* [ ... key value desc ] */ + + if (DUK_PROPDESC_IS_ACCESSOR(&pd)) { + /* If a setter/getter is missing (undefined), the descriptor must + * still have the property present with the value 'undefined'. + */ + if (pd.get) { + duk_push_hobject(thr, pd.get); + } else { + duk_push_undefined(thr); + } + duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_GET); + if (pd.set) { + duk_push_hobject(thr, pd.set); + } else { + duk_push_undefined(thr); + } + duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_SET); + } else { + duk_dup_m2(thr); + duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_VALUE); + duk_push_boolean(thr, DUK_PROPDESC_IS_WRITABLE(&pd)); + duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_WRITABLE); + } + duk_push_boolean(thr, DUK_PROPDESC_IS_ENUMERABLE(&pd)); + duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_ENUMERABLE); + duk_push_boolean(thr, DUK_PROPDESC_IS_CONFIGURABLE(&pd)); + duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_CONFIGURABLE); + + /* [ ... key value desc ] */ + + duk_replace(thr, -3); + duk_pop_unsafe(thr); /* -> [ ... desc ] */ +} + +/* + * NormalizePropertyDescriptor() related helper. + * + * Internal helper which validates and normalizes a property descriptor + * represented as an ECMAScript object (e.g. argument to defineProperty()). + * The output of this conversion is a set of defprop_flags and possibly + * some values pushed on the value stack to (1) ensure borrowed pointers + * remain valid, and (2) avoid unnecessary pops for footprint reasons. + * Caller must manage stack top carefully because the number of values + * pushed depends on the input property descriptor. + * + * The original descriptor object must not be altered in the process. + */ + +/* XXX: very basic optimization -> duk_get_prop_stridx_top */ + +DUK_INTERNAL +void duk_hobject_prepare_property_descriptor(duk_hthread *thr, + duk_idx_t idx_in, + duk_uint_t *out_defprop_flags, + duk_idx_t *out_idx_value, + duk_hobject **out_getter, + duk_hobject **out_setter) { + duk_idx_t idx_value = -1; + duk_hobject *getter = NULL; + duk_hobject *setter = NULL; + duk_bool_t is_data_desc = 0; + duk_bool_t is_acc_desc = 0; + duk_uint_t defprop_flags = 0; + + DUK_ASSERT(out_defprop_flags != NULL); + DUK_ASSERT(out_idx_value != NULL); + DUK_ASSERT(out_getter != NULL); + DUK_ASSERT(out_setter != NULL); + DUK_ASSERT(idx_in <= 0x7fffL); /* short variants would be OK, but not used to avoid shifts */ + + /* Must be an object, otherwise TypeError (E5.1 Section 8.10.5, step 1). */ + idx_in = duk_require_normalize_index(thr, idx_in); + (void) duk_require_hobject(thr, idx_in); + + /* The coercion order must match the ToPropertyDescriptor() algorithm + * so that side effects in coercion happen in the correct order. + * (This order also happens to be compatible with duk_def_prop(), + * although it doesn't matter in practice.) + */ + + if (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_VALUE)) { + is_data_desc = 1; + defprop_flags |= DUK_DEFPROP_HAVE_VALUE; + idx_value = duk_get_top_index(thr); + } + + if (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_WRITABLE)) { + is_data_desc = 1; + if (duk_to_boolean_top_pop(thr)) { + defprop_flags |= DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE; + } else { + defprop_flags |= DUK_DEFPROP_HAVE_WRITABLE; + } + } + + if (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_GET)) { + duk_tval *tv = duk_require_tval(thr, -1); + duk_hobject *h_get; + + if (DUK_TVAL_IS_UNDEFINED(tv)) { + /* undefined is accepted */ + DUK_ASSERT(getter == NULL); + } else { + /* NOTE: lightfuncs are coerced to full functions because + * lightfuncs don't fit into a property value slot. This + * has some side effects, see test-dev-lightfunc-accessor.js. + */ + h_get = duk_get_hobject_promote_lfunc(thr, -1); + if (h_get == NULL || !DUK_HOBJECT_IS_CALLABLE(h_get)) { + goto type_error; + } + getter = h_get; + } + is_acc_desc = 1; + defprop_flags |= DUK_DEFPROP_HAVE_GETTER; + } + + if (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_SET)) { + duk_tval *tv = duk_require_tval(thr, -1); + duk_hobject *h_set; + + if (DUK_TVAL_IS_UNDEFINED(tv)) { + /* undefined is accepted */ + DUK_ASSERT(setter == NULL); + } else { + /* NOTE: lightfuncs are coerced to full functions because + * lightfuncs don't fit into a property value slot. This + * has some side effects, see test-dev-lightfunc-accessor.js. + */ + h_set = duk_get_hobject_promote_lfunc(thr, -1); + if (h_set == NULL || !DUK_HOBJECT_IS_CALLABLE(h_set)) { + goto type_error; + } + setter = h_set; + } + is_acc_desc = 1; + defprop_flags |= DUK_DEFPROP_HAVE_SETTER; + } + + if (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_ENUMERABLE)) { + if (duk_to_boolean_top_pop(thr)) { + defprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE; + } else { + defprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE; + } + } + + if (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_CONFIGURABLE)) { + if (duk_to_boolean_top_pop(thr)) { + defprop_flags |= DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE; + } else { + defprop_flags |= DUK_DEFPROP_HAVE_CONFIGURABLE; + } + } + + if (is_data_desc && is_acc_desc) { + goto type_error; + } + + *out_defprop_flags = defprop_flags; + *out_idx_value = idx_value; + *out_getter = getter; + *out_setter = setter; + + /* [ ... [multiple values] ] */ + return; + + type_error: + DUK_ERROR_TYPE(thr, DUK_STR_INVALID_DESCRIPTOR); + DUK_WO_NORETURN(return;); +} + +/* + * Object.defineProperty() related helper (E5 Section 15.2.3.6). + * Also handles ES2015 Reflect.defineProperty(). + * + * Inlines all [[DefineOwnProperty]] exotic behaviors. + * + * Note: ECMAScript compliant [[DefineOwnProperty]](P, Desc, Throw) is not + * implemented directly, but Object.defineProperty() serves its purpose. + * We don't need the [[DefineOwnProperty]] internally and we don't have a + * property descriptor with 'missing values' so it's easier to avoid it + * entirely. + * + * Note: this is only called for actual objects, not primitive values. + * This must support virtual properties for full objects (e.g. Strings) + * but not for plain values (e.g. strings). Lightfuncs, even though + * primitive in a sense, are treated like objects and accepted as target + * values. + */ + +/* XXX: this is a major target for size optimization */ +DUK_INTERNAL +duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr, + duk_uint_t defprop_flags, + duk_hobject *obj, + duk_hstring *key, + duk_idx_t idx_value, + duk_hobject *get, + duk_hobject *set, + duk_bool_t throw_flag) { + duk_uint32_t arr_idx; + duk_tval tv; + duk_bool_t has_enumerable; + duk_bool_t has_configurable; + duk_bool_t has_writable; + duk_bool_t has_value; + duk_bool_t has_get; + duk_bool_t has_set; + duk_bool_t is_enumerable; + duk_bool_t is_configurable; + duk_bool_t is_writable; + duk_bool_t force_flag; + duk_small_uint_t new_flags; + duk_propdesc curr; + duk_uint32_t arridx_new_array_length; /* != 0 => post-update for array 'length' (used when key is an array index) */ + duk_uint32_t arrlen_old_len; + duk_uint32_t arrlen_new_len; + duk_bool_t pending_write_protect; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(obj != NULL); + DUK_ASSERT(key != NULL); + /* idx_value may be < 0 (no value), set and get may be NULL */ + + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + + /* All the flags fit in 16 bits, so will fit into duk_bool_t. */ + + has_writable = (defprop_flags & DUK_DEFPROP_HAVE_WRITABLE); + has_enumerable = (defprop_flags & DUK_DEFPROP_HAVE_ENUMERABLE); + has_configurable = (defprop_flags & DUK_DEFPROP_HAVE_CONFIGURABLE); + has_value = (defprop_flags & DUK_DEFPROP_HAVE_VALUE); + has_get = (defprop_flags & DUK_DEFPROP_HAVE_GETTER); + has_set = (defprop_flags & DUK_DEFPROP_HAVE_SETTER); + is_writable = (defprop_flags & DUK_DEFPROP_WRITABLE); + is_enumerable = (defprop_flags & DUK_DEFPROP_ENUMERABLE); + is_configurable = (defprop_flags & DUK_DEFPROP_CONFIGURABLE); + force_flag = (defprop_flags & DUK_DEFPROP_FORCE); + + arr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key); + + arridx_new_array_length = 0; + pending_write_protect = 0; + arrlen_old_len = 0; + arrlen_new_len = 0; + + DUK_DDD(DUK_DDDPRINT("has_enumerable=%ld is_enumerable=%ld " + "has_configurable=%ld is_configurable=%ld " + "has_writable=%ld is_writable=%ld " + "has_value=%ld value=%!T " + "has_get=%ld get=%p=%!O " + "has_set=%ld set=%p=%!O " + "arr_idx=%ld throw_flag=!%ld", + (long) has_enumerable, (long) is_enumerable, + (long) has_configurable, (long) is_configurable, + (long) has_writable, (long) is_writable, + (long) has_value, (duk_tval *) (idx_value >= 0 ? duk_get_tval(thr, idx_value) : NULL), + (long) has_get, (void *) get, (duk_heaphdr *) get, + (long) has_set, (void *) set, (duk_heaphdr *) set, + (long) arr_idx, (long) throw_flag)); + + /* + * Array exotic behaviors can be implemented at this point. The local variables + * are essentially a 'value copy' of the input descriptor (Desc), which is modified + * by the Array [[DefineOwnProperty]] (E5 Section 15.4.5.1). + */ + + if (!DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) { + goto skip_array_exotic; + } + + if (key == DUK_HTHREAD_STRING_LENGTH(thr)) { + duk_harray *a; + + /* E5 Section 15.4.5.1, step 3, steps a - i are implemented here, j - n at the end */ + if (!has_value) { + DUK_DDD(DUK_DDDPRINT("exotic array behavior for 'length', but no value in descriptor -> normal behavior")); + goto skip_array_exotic; + } + + DUK_DDD(DUK_DDDPRINT("exotic array behavior for 'length', value present in descriptor -> exotic behavior")); + + /* + * Get old and new length + */ + + a = (duk_harray *) obj; + DUK_HARRAY_ASSERT_VALID(a); + arrlen_old_len = a->length; + + DUK_ASSERT(idx_value >= 0); + arrlen_new_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_POSIDX(thr, idx_value)); + duk_push_u32(thr, arrlen_new_len); + duk_replace(thr, idx_value); /* step 3.e: replace 'Desc.[[Value]]' */ + + DUK_DDD(DUK_DDDPRINT("old_len=%ld, new_len=%ld", (long) arrlen_old_len, (long) arrlen_new_len)); + + if (arrlen_new_len >= arrlen_old_len) { + /* standard behavior, step 3.f.i */ + DUK_DDD(DUK_DDDPRINT("new length is same or higher as previous => standard behavior")); + goto skip_array_exotic; + } + DUK_DDD(DUK_DDDPRINT("new length is smaller than previous => exotic post behavior")); + + /* XXX: consolidated algorithm step 15.f -> redundant? */ + if (DUK_HARRAY_LENGTH_NONWRITABLE(a) && !force_flag) { + /* Array .length is always non-configurable; if it's also + * non-writable, don't allow it to be written. + */ + goto fail_not_configurable; + } + + /* steps 3.h and 3.i */ + if (has_writable && !is_writable) { + DUK_DDD(DUK_DDDPRINT("desc writable is false, force it back to true, and flag pending write protect")); + is_writable = 1; + pending_write_protect = 1; + } + + /* remaining actual steps are carried out if standard DefineOwnProperty succeeds */ + } else if (arr_idx != DUK__NO_ARRAY_INDEX) { + /* XXX: any chance of unifying this with the 'length' key handling? */ + + /* E5 Section 15.4.5.1, step 4 */ + duk_uint32_t old_len; + duk_harray *a; + + a = (duk_harray *) obj; + DUK_HARRAY_ASSERT_VALID(a); + + old_len = a->length; + + if (arr_idx >= old_len) { + DUK_DDD(DUK_DDDPRINT("defineProperty requires array length update " + "(arr_idx=%ld, old_len=%ld)", + (long) arr_idx, (long) old_len)); + + if (DUK_HARRAY_LENGTH_NONWRITABLE(a) && !force_flag) { + /* Array .length is always non-configurable, so + * if it's also non-writable, don't allow a value + * write. With force flag allow writing. + */ + goto fail_not_configurable; + } + + /* actual update happens once write has been completed without + * error below. + */ + DUK_ASSERT(arr_idx != 0xffffffffUL); + arridx_new_array_length = arr_idx + 1; + } else { + DUK_DDD(DUK_DDDPRINT("defineProperty does not require length update " + "(arr_idx=%ld, old_len=%ld) -> standard behavior", + (long) arr_idx, (long) old_len)); + } + } + skip_array_exotic: + + /* XXX: There is currently no support for writing buffer object + * indexed elements here. Attempt to do so will succeed and + * write a concrete property into the buffer object. This should + * be fixed at some point but because buffers are a custom feature + * anyway, this is relatively unimportant. + */ + + /* + * Actual Object.defineProperty() default algorithm. + */ + + /* + * First check whether property exists; if not, simple case. This covers + * steps 1-4. + */ + + if (!duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE)) { + DUK_DDD(DUK_DDDPRINT("property does not exist")); + + if (!DUK_HOBJECT_HAS_EXTENSIBLE(obj) && !force_flag) { + goto fail_not_extensible; + } + +#if defined(DUK_USE_ROM_OBJECTS) + /* ROM objects are never extensible but force flag may + * allow us to come here anyway. + */ + DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj) || !DUK_HOBJECT_HAS_EXTENSIBLE(obj)); + if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) { + DUK_D(DUK_DPRINT("attempt to define property on a read-only target object")); + goto fail_not_configurable; + } +#endif + + /* XXX: share final setting code for value and flags? difficult because + * refcount code is different. Share entry allocation? But can't allocate + * until array index checked. + */ + + /* steps 4.a and 4.b are tricky */ + if (has_set || has_get) { + duk_int_t e_idx; + + DUK_DDD(DUK_DDDPRINT("create new accessor property")); + + DUK_ASSERT(has_set || set == NULL); + DUK_ASSERT(has_get || get == NULL); + DUK_ASSERT(!has_value); + DUK_ASSERT(!has_writable); + + new_flags = DUK_PROPDESC_FLAG_ACCESSOR; /* defaults, E5 Section 8.6.1, Table 7 */ + if (has_enumerable && is_enumerable) { + new_flags |= DUK_PROPDESC_FLAG_ENUMERABLE; + } + if (has_configurable && is_configurable) { + new_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE; + } + + if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(obj)) { + DUK_DDD(DUK_DDDPRINT("accessor cannot go to array part, abandon array")); + duk__abandon_array_part(thr, obj); + } + + /* write to entry part */ + e_idx = duk__hobject_alloc_entry_checked(thr, obj, key); + DUK_ASSERT(e_idx >= 0); + + DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, e_idx, get); + DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, e_idx, set); + DUK_HOBJECT_INCREF_ALLOWNULL(thr, get); + DUK_HOBJECT_INCREF_ALLOWNULL(thr, set); + + DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, new_flags); + goto success_exotics; + } else { + duk_int_t e_idx; + duk_tval *tv2; + + DUK_DDD(DUK_DDDPRINT("create new data property")); + + DUK_ASSERT(!has_set); + DUK_ASSERT(!has_get); + + new_flags = 0; /* defaults, E5 Section 8.6.1, Table 7 */ + if (has_writable && is_writable) { + new_flags |= DUK_PROPDESC_FLAG_WRITABLE; + } + if (has_enumerable && is_enumerable) { + new_flags |= DUK_PROPDESC_FLAG_ENUMERABLE; + } + if (has_configurable && is_configurable) { + new_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE; + } + if (has_value) { + duk_tval *tv_tmp = duk_require_tval(thr, idx_value); + DUK_TVAL_SET_TVAL(&tv, tv_tmp); + } else { + DUK_TVAL_SET_UNDEFINED(&tv); /* default value */ + } + + if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(obj)) { + if (new_flags == DUK_PROPDESC_FLAGS_WEC) { + DUK_DDD(DUK_DDDPRINT("new data property attributes match array defaults, attempt to write to array part")); + tv2 = duk__obtain_arridx_slot(thr, arr_idx, obj); + if (tv2 == NULL) { + DUK_DDD(DUK_DDDPRINT("failed writing to array part, abandoned array")); + } else { + DUK_DDD(DUK_DDDPRINT("success in writing to array part")); + DUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(obj)); + DUK_ASSERT(DUK_TVAL_IS_UNUSED(tv2)); + DUK_TVAL_SET_TVAL(tv2, &tv); + DUK_TVAL_INCREF(thr, tv2); + goto success_exotics; + } + } else { + DUK_DDD(DUK_DDDPRINT("new data property cannot go to array part, abandon array")); + duk__abandon_array_part(thr, obj); + } + /* fall through */ + } + + /* write to entry part */ + e_idx = duk__hobject_alloc_entry_checked(thr, obj, key); + DUK_ASSERT(e_idx >= 0); + tv2 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx); + DUK_TVAL_SET_TVAL(tv2, &tv); + DUK_TVAL_INCREF(thr, tv2); + + DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, new_flags); + goto success_exotics; + } + DUK_UNREACHABLE(); + } + + /* we currently assume virtual properties are not configurable (as none of them are) */ + DUK_ASSERT((curr.e_idx >= 0 || curr.a_idx >= 0) || !(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE)); + + /* [obj key desc value get set curr_value] */ + + /* + * Property already exists. Steps 5-6 detect whether any changes need + * to be made. + */ + + if (has_enumerable) { + if (is_enumerable) { + if (!(curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE)) { + goto need_check; + } + } else { + if (curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE) { + goto need_check; + } + } + } + if (has_configurable) { + if (is_configurable) { + if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE)) { + goto need_check; + } + } else { + if (curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) { + goto need_check; + } + } + } + if (has_value) { + duk_tval *tmp1; + duk_tval *tmp2; + + /* attempt to change from accessor to data property */ + if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) { + goto need_check; + } + + tmp1 = duk_require_tval(thr, -1); /* curr value */ + tmp2 = duk_require_tval(thr, idx_value); /* new value */ + if (!duk_js_samevalue(tmp1, tmp2)) { + goto need_check; + } + } + if (has_writable) { + /* attempt to change from accessor to data property */ + if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) { + goto need_check; + } + + if (is_writable) { + if (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE)) { + goto need_check; + } + } else { + if (curr.flags & DUK_PROPDESC_FLAG_WRITABLE) { + goto need_check; + } + } + } + if (has_set) { + if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) { + if (set != curr.set) { + goto need_check; + } + } else { + goto need_check; + } + } + if (has_get) { + if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) { + if (get != curr.get) { + goto need_check; + } + } else { + goto need_check; + } + } + + /* property exists, either 'desc' is empty, or all values + * match (SameValue) + */ + goto success_no_exotics; + + need_check: + + /* + * Some change(s) need to be made. Steps 7-11. + */ + + /* shared checks for all descriptor types */ + if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) { + if (has_configurable && is_configurable) { + goto fail_not_configurable; + } + if (has_enumerable) { + if (curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE) { + if (!is_enumerable) { + goto fail_not_configurable; + } + } else { + if (is_enumerable) { + goto fail_not_configurable; + } + } + } + } + + /* Virtual properties don't have backing so they can't mostly be + * edited. Some virtual properties are, however, writable: for + * example, virtual index properties of buffer objects and Array + * instance .length. These are not configurable so the checks + * above mostly cover attempts to change them, except when the + * duk_def_prop() call is used with DUK_DEFPROP_FORCE; even in + * that case we can't forcibly change the property attributes + * because they don't have concrete backing. + */ + + /* XXX: for ROM objects too it'd be best if value modify was + * allowed if the value matches SameValue. + */ + /* Reject attempt to change a read-only object. */ +#if defined(DUK_USE_ROM_OBJECTS) + if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) { + DUK_DD(DUK_DDPRINT("attempt to define property on read-only target object")); + goto fail_not_configurable; + } +#endif + + /* descriptor type specific checks */ + if (has_set || has_get) { + /* IsAccessorDescriptor(desc) == true */ + DUK_ASSERT(!has_writable); + DUK_ASSERT(!has_value); + + if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) { + /* curr and desc are accessors */ + if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) { + if (has_set && set != curr.set) { + goto fail_not_configurable; + } + if (has_get && get != curr.get) { + goto fail_not_configurable; + } + } + } else { + duk_bool_t rc; + duk_tval *tv1; + + /* curr is data, desc is accessor */ + if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) { + goto fail_not_configurable; + } + + DUK_DDD(DUK_DDDPRINT("convert property to accessor property")); + if (curr.a_idx >= 0) { + DUK_DDD(DUK_DDDPRINT("property to convert is stored in an array entry, abandon array and re-lookup")); + duk__abandon_array_part(thr, obj); + duk_pop_unsafe(thr); /* remove old value */ + rc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE); + DUK_UNREF(rc); + DUK_ASSERT(rc != 0); + DUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0); + } + if (curr.e_idx < 0) { + DUK_ASSERT(curr.a_idx < 0 && curr.e_idx < 0); + goto fail_virtual; /* safeguard for virtual property */ + } + + DUK_ASSERT(curr.e_idx >= 0); + DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx)); + + tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx); + DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv1); /* XXX: just decref */ + + DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL); + DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL); + DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx); + DUK_HOBJECT_E_SLOT_SET_ACCESSOR(thr->heap, obj, curr.e_idx); + + DUK_DDD(DUK_DDDPRINT("flags after data->accessor conversion: 0x%02lx", + (unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx))); + /* Update curr.flags; faster than a re-lookup. */ + curr.flags &= ~DUK_PROPDESC_FLAG_WRITABLE; + curr.flags |= DUK_PROPDESC_FLAG_ACCESSOR; + } + } else if (has_value || has_writable) { + /* IsDataDescriptor(desc) == true */ + DUK_ASSERT(!has_set); + DUK_ASSERT(!has_get); + + if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) { + duk_hobject *tmp; + + /* curr is accessor, desc is data */ + if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) { + goto fail_not_configurable; + } + + /* curr is accessor -> cannot be in array part. */ + DUK_ASSERT(curr.a_idx < 0); + if (curr.e_idx < 0) { + goto fail_virtual; /* safeguard; no virtual accessors now */ + } + + DUK_DDD(DUK_DDDPRINT("convert property to data property")); + + DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx)); + tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx); + DUK_UNREF(tmp); + DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL); + DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp); + tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx); + DUK_UNREF(tmp); + DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL); + DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp); + + DUK_TVAL_SET_UNDEFINED(DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx)); + DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx); + DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(thr->heap, obj, curr.e_idx); + + DUK_DDD(DUK_DDDPRINT("flags after accessor->data conversion: 0x%02lx", + (unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx))); + + /* Update curr.flags; faster than a re-lookup. */ + curr.flags &= ~(DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_ACCESSOR); + } else { + /* curr and desc are data */ + if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) { + if (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE) && has_writable && is_writable) { + goto fail_not_configurable; + } + /* Note: changing from writable to non-writable is OK */ + if (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE) && has_value) { + duk_tval *tmp1 = duk_require_tval(thr, -1); /* curr value */ + duk_tval *tmp2 = duk_require_tval(thr, idx_value); /* new value */ + if (!duk_js_samevalue(tmp1, tmp2)) { + goto fail_not_configurable; + } + } + } + } + } else { + /* IsGenericDescriptor(desc) == true; this means in practice that 'desc' + * only has [[Enumerable]] or [[Configurable]] flag updates, which are + * allowed at this point. + */ + + DUK_ASSERT(!has_value && !has_writable && !has_get && !has_set); + } + + /* + * Start doing property attributes updates. Steps 12-13. + * + * Start by computing new attribute flags without writing yet. + * Property type conversion is done above if necessary. + */ + + new_flags = curr.flags; + + if (has_enumerable) { + if (is_enumerable) { + new_flags |= DUK_PROPDESC_FLAG_ENUMERABLE; + } else { + new_flags &= ~DUK_PROPDESC_FLAG_ENUMERABLE; + } + } + if (has_configurable) { + if (is_configurable) { + new_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE; + } else { + new_flags &= ~DUK_PROPDESC_FLAG_CONFIGURABLE; + } + } + if (has_writable) { + if (is_writable) { + new_flags |= DUK_PROPDESC_FLAG_WRITABLE; + } else { + new_flags &= ~DUK_PROPDESC_FLAG_WRITABLE; + } + } + + /* XXX: write protect after flag? -> any chance of handling it here? */ + + DUK_DDD(DUK_DDDPRINT("new flags that we want to write: 0x%02lx", + (unsigned long) new_flags)); + + /* + * Check whether we need to abandon an array part (if it exists) + */ + + if (curr.a_idx >= 0) { + duk_bool_t rc; + + DUK_ASSERT(curr.e_idx < 0); + + if (new_flags == DUK_PROPDESC_FLAGS_WEC) { + duk_tval *tv1, *tv2; + + DUK_DDD(DUK_DDDPRINT("array index, new property attributes match array defaults, update in-place")); + + DUK_ASSERT(curr.flags == DUK_PROPDESC_FLAGS_WEC); /* must have been, since in array part */ + DUK_ASSERT(!has_set); + DUK_ASSERT(!has_get); + DUK_ASSERT(idx_value >= 0); /* must be: if attributes match and we get here the value must differ (otherwise no change) */ + + tv2 = duk_require_tval(thr, idx_value); + tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, curr.a_idx); + DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects; may invalidate a_idx */ + goto success_exotics; + } + + DUK_DDD(DUK_DDDPRINT("array index, new property attributes do not match array defaults, abandon array and re-lookup")); + duk__abandon_array_part(thr, obj); + duk_pop_unsafe(thr); /* remove old value */ + rc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE); + DUK_UNREF(rc); + DUK_ASSERT(rc != 0); + DUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0); + } + + DUK_DDD(DUK_DDDPRINT("updating existing property in entry part")); + + /* Array case is handled comprehensively above: either in entry + * part or a virtual property. + */ + DUK_ASSERT(curr.a_idx < 0); + + DUK_DDD(DUK_DDDPRINT("update existing property attributes")); + if (curr.e_idx >= 0) { + DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, curr.e_idx, new_flags); + } else { + /* For Array .length the only allowed transition is for .length + * to become non-writable. + */ + if (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) { + duk_harray *a; + a = (duk_harray *) obj; + DUK_DD(DUK_DDPRINT("Object.defineProperty() attribute update for duk_harray .length -> %02lx", (unsigned long) new_flags)); + DUK_HARRAY_ASSERT_VALID(a); + if ((new_flags & DUK_PROPDESC_FLAGS_EC) != (curr.flags & DUK_PROPDESC_FLAGS_EC)) { + DUK_D(DUK_DPRINT("Object.defineProperty() attempt to change virtual array .length enumerable or configurable attribute, fail")); + goto fail_virtual; + } + if (new_flags & DUK_PROPDESC_FLAG_WRITABLE) { + DUK_HARRAY_SET_LENGTH_WRITABLE(a); + } else { + DUK_HARRAY_SET_LENGTH_NONWRITABLE(a); + } + } + } + + if (has_set) { + duk_hobject *tmp; + + /* Virtual properties are non-configurable but with a 'force' + * flag we might come here so check explicitly for virtual. + */ + if (curr.e_idx < 0) { + goto fail_virtual; + } + + DUK_DDD(DUK_DDDPRINT("update existing property setter")); + DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx)); + + tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx); + DUK_UNREF(tmp); + DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, set); + DUK_HOBJECT_INCREF_ALLOWNULL(thr, set); + DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); /* side effects; may invalidate e_idx */ + } + if (has_get) { + duk_hobject *tmp; + + if (curr.e_idx < 0) { + goto fail_virtual; + } + + DUK_DDD(DUK_DDDPRINT("update existing property getter")); + DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx)); + + tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx); + DUK_UNREF(tmp); + DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, get); + DUK_HOBJECT_INCREF_ALLOWNULL(thr, get); + DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); /* side effects; may invalidate e_idx */ + } + if (has_value) { + duk_tval *tv1, *tv2; + + DUK_DDD(DUK_DDDPRINT("update existing property value")); + + if (curr.e_idx >= 0) { + DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx)); + tv2 = duk_require_tval(thr, idx_value); + tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx); + DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects; may invalidate e_idx */ + } else { + DUK_ASSERT(curr.a_idx < 0); /* array part case handled comprehensively previously */ + + DUK_DD(DUK_DDPRINT("Object.defineProperty(), value update for virtual property")); + /* XXX: Uint8Array and other typed array virtual writes not currently + * handled. + */ + if (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) { + duk_harray *a; + a = (duk_harray *) obj; + DUK_DD(DUK_DDPRINT("Object.defineProperty() value update for duk_harray .length -> %ld", (long) arrlen_new_len)); + DUK_HARRAY_ASSERT_VALID(a); + a->length = arrlen_new_len; + } else { + goto fail_virtual; /* should not happen */ + } + } + } + + /* + * Standard algorithm succeeded without errors, check for exotic post-behaviors. + * + * Arguments exotic behavior in E5 Section 10.6 occurs after the standard + * [[DefineOwnProperty]] has completed successfully. + * + * Array exotic behavior in E5 Section 15.4.5.1 is implemented partly + * prior to the default [[DefineOwnProperty]], but: + * - for an array index key (e.g. "10") the final 'length' update occurs here + * - for 'length' key the element deletion and 'length' update occurs here + */ + + success_exotics: + + /* curr.a_idx or curr.e_idx may have been invalidated by side effects + * above. + */ + + /* [obj key desc value get set curr_value] */ + + if (DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) { + duk_harray *a; + + a = (duk_harray *) obj; + DUK_HARRAY_ASSERT_VALID(a); + + if (arridx_new_array_length > 0) { + /* + * Note: zero works as a "no update" marker because the new length + * can never be zero after a new property is written. + */ + + /* E5 Section 15.4.5.1, steps 4.e.i - 4.e.ii */ + + DUK_DDD(DUK_DDDPRINT("defineProperty successful, pending array length update to: %ld", + (long) arridx_new_array_length)); + + a->length = arridx_new_array_length; + } + + if (key == DUK_HTHREAD_STRING_LENGTH(thr) && arrlen_new_len < arrlen_old_len) { + /* + * E5 Section 15.4.5.1, steps 3.k - 3.n. The order at the end combines + * the error case 3.l.iii and the success case 3.m-3.n. + */ + + /* XXX: investigate whether write protect can be handled above, if we + * just update length here while ignoring its protected status + */ + + duk_uint32_t result_len; + duk_bool_t rc; + + DUK_DDD(DUK_DDDPRINT("defineProperty successful, key is 'length', exotic array behavior, " + "doing array element deletion and length update")); + + rc = duk__handle_put_array_length_smaller(thr, obj, arrlen_old_len, arrlen_new_len, force_flag, &result_len); + + /* update length (curr points to length, and we assume it's still valid) */ + DUK_ASSERT(result_len >= arrlen_new_len && result_len <= arrlen_old_len); + + a->length = result_len; + + if (pending_write_protect) { + DUK_DDD(DUK_DDDPRINT("setting array length non-writable (pending writability update)")); + DUK_HARRAY_SET_LENGTH_NONWRITABLE(a); + } + + /* XXX: shrink array allocation or entries compaction here? */ + if (!rc) { + DUK_DD(DUK_DDPRINT("array length write only partially successful")); + goto fail_not_configurable; + } + } + } else if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)) { + duk_hobject *map; + duk_hobject *varenv; + + DUK_ASSERT(arridx_new_array_length == 0); + DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)); /* traits are separate; in particular, arguments not an array */ + + map = NULL; + varenv = NULL; + if (!duk__lookup_arguments_map(thr, obj, key, &curr, &map, &varenv)) { + goto success_no_exotics; + } + DUK_ASSERT(map != NULL); + DUK_ASSERT(varenv != NULL); + + /* [obj key desc value get set curr_value varname] */ + + if (has_set || has_get) { + /* = IsAccessorDescriptor(Desc) */ + DUK_DDD(DUK_DDDPRINT("defineProperty successful, key mapped to arguments 'map' " + "changed to an accessor, delete arguments binding")); + + (void) duk_hobject_delprop_raw(thr, map, key, 0); /* ignore result */ + } else { + /* Note: this order matters (final value before deleting map entry must be done) */ + DUK_DDD(DUK_DDDPRINT("defineProperty successful, key mapped to arguments 'map', " + "check for value update / binding deletion")); + + if (has_value) { + duk_hstring *varname; + + DUK_DDD(DUK_DDDPRINT("defineProperty successful, key mapped to arguments 'map', " + "update bound value (variable/argument)")); + + varname = duk_require_hstring(thr, -1); + DUK_ASSERT(varname != NULL); + + DUK_DDD(DUK_DDDPRINT("arguments object automatic putvar for a bound variable; " + "key=%!O, varname=%!O, value=%!T", + (duk_heaphdr *) key, + (duk_heaphdr *) varname, + (duk_tval *) duk_require_tval(thr, idx_value))); + + /* strict flag for putvar comes from our caller (currently: fixed) */ + duk_js_putvar_envrec(thr, varenv, varname, duk_require_tval(thr, idx_value), 1 /*throw_flag*/); + } + if (has_writable && !is_writable) { + DUK_DDD(DUK_DDDPRINT("defineProperty successful, key mapped to arguments 'map', " + "changed to non-writable, delete arguments binding")); + + (void) duk_hobject_delprop_raw(thr, map, key, 0); /* ignore result */ + } + } + + /* 'varname' is in stack in this else branch, leaving an unbalanced stack below, + * but this doesn't matter now. + */ + } + + success_no_exotics: + /* Some code paths use NORZ macros for simplicity, ensure refzero + * handling is completed. + */ + DUK_REFZERO_CHECK_SLOW(thr); + return 1; + + fail_not_extensible: + if (throw_flag) { + DUK_ERROR_TYPE(thr, DUK_STR_NOT_EXTENSIBLE); + DUK_WO_NORETURN(return 0;); + } + return 0; + + fail_virtual: /* just use the same "not configurable" error message" */ + fail_not_configurable: + if (throw_flag) { + DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE); + DUK_WO_NORETURN(return 0;); + } + return 0; +} + +/* + * Object.prototype.hasOwnProperty() and Object.prototype.propertyIsEnumerable(). + */ + +DUK_INTERNAL duk_bool_t duk_hobject_object_ownprop_helper(duk_hthread *thr, duk_small_uint_t required_desc_flags) { + duk_hstring *h_v; + duk_hobject *h_obj; + duk_propdesc desc; + duk_bool_t ret; + + /* coercion order matters */ + h_v = duk_to_hstring_acceptsymbol(thr, 0); + DUK_ASSERT(h_v != NULL); + + h_obj = duk_push_this_coercible_to_object(thr); + DUK_ASSERT(h_obj != NULL); + + ret = duk_hobject_get_own_propdesc(thr, h_obj, h_v, &desc, 0 /*flags*/); /* don't push value */ + + duk_push_boolean(thr, ret && ((desc.flags & required_desc_flags) == required_desc_flags)); + return 1; +} + +/* + * Object.seal() and Object.freeze() (E5 Sections 15.2.3.8 and 15.2.3.9) + * + * Since the algorithms are similar, a helper provides both functions. + * Freezing is essentially sealing + making plain properties non-writable. + * + * Note: virtual (non-concrete) properties which are non-configurable but + * writable would pose some problems, but such properties do not currently + * exist (all virtual properties are non-configurable and non-writable). + * If they did exist, the non-configurability does NOT prevent them from + * becoming non-writable. However, this change should be recorded somehow + * so that it would turn up (e.g. when getting the property descriptor), + * requiring some additional flags in the object. + */ + +DUK_INTERNAL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_freeze) { + duk_uint_fast32_t i; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(obj != NULL); + + DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE); + +#if defined(DUK_USE_ROM_OBJECTS) + if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) { + DUK_DD(DUK_DDPRINT("attempt to seal/freeze a readonly object, reject")); + DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE); + DUK_WO_NORETURN(return;); + } +#endif + + /* + * Abandon array part because all properties must become non-configurable. + * Note that this is now done regardless of whether this is always the case + * (skips check, but performance problem if caller would do this many times + * for the same object; not likely). + */ + + duk__abandon_array_part(thr, obj); + DUK_ASSERT(DUK_HOBJECT_GET_ASIZE(obj) == 0); + + for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) { + duk_uint8_t *fp; + + /* since duk__abandon_array_part() causes a resize, there should be no gaps in keys */ + DUK_ASSERT(DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i) != NULL); + + /* avoid multiple computations of flags address; bypasses macros */ + fp = DUK_HOBJECT_E_GET_FLAGS_PTR(thr->heap, obj, i); + if (is_freeze && !((*fp) & DUK_PROPDESC_FLAG_ACCESSOR)) { + *fp &= ~(DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_CONFIGURABLE); + } else { + *fp &= ~DUK_PROPDESC_FLAG_CONFIGURABLE; + } + } + + DUK_HOBJECT_CLEAR_EXTENSIBLE(obj); + + /* no need to compact since we already did that in duk__abandon_array_part() + * (regardless of whether an array part existed or not. + */ + + return; +} + +/* + * Object.isSealed() and Object.isFrozen() (E5 Sections 15.2.3.11, 15.2.3.13) + * + * Since the algorithms are similar, a helper provides both functions. + * Freezing is essentially sealing + making plain properties non-writable. + * + * Note: all virtual (non-concrete) properties are currently non-configurable + * and non-writable (and there are no accessor virtual properties), so they don't + * need to be considered here now. + */ + +DUK_INTERNAL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_frozen) { + duk_uint_fast32_t i; + + DUK_ASSERT(obj != NULL); + DUK_UNREF(thr); + + /* Note: no allocation pressure, no need to check refcounts etc */ + + /* must not be extensible */ + if (DUK_HOBJECT_HAS_EXTENSIBLE(obj)) { + return 0; + } + + /* all virtual properties are non-configurable and non-writable */ + + /* entry part must not contain any configurable properties, or + * writable properties (if is_frozen). + */ + for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) { + duk_small_uint_t flags; + + if (!DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i)) { + continue; + } + + /* avoid multiple computations of flags address; bypasses macros */ + flags = (duk_small_uint_t) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, i); + + if (flags & DUK_PROPDESC_FLAG_CONFIGURABLE) { + return 0; + } + if (is_frozen && + !(flags & DUK_PROPDESC_FLAG_ACCESSOR) && + (flags & DUK_PROPDESC_FLAG_WRITABLE)) { + return 0; + } + } + + /* array part must not contain any non-unused properties, as they would + * be configurable and writable. + */ + for (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) { + duk_tval *tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i); + if (!DUK_TVAL_IS_UNUSED(tv)) { + return 0; + } + } + + return 1; +} + +/* + * Object.preventExtensions() and Object.isExtensible() (E5 Sections 15.2.3.10, 15.2.3.13) + * + * Not needed, implemented by macros DUK_HOBJECT_{HAS,CLEAR,SET}_EXTENSIBLE + * and the Object built-in bindings. + */ diff --git a/third_party/duktape/duk_hproxy.h b/third_party/duktape/duk_hproxy.h new file mode 100644 index 00000000..eca8f582 --- /dev/null +++ b/third_party/duktape/duk_hproxy.h @@ -0,0 +1,26 @@ +/* + * Proxy object representation. + */ + +#if !defined(DUK_HPROXY_H_INCLUDED) +#define DUK_HPROXY_H_INCLUDED + +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL_DECL void duk_hproxy_assert_valid(duk_hproxy *h); +#define DUK_HPROXY_ASSERT_VALID(h) do { duk_hproxy_assert_valid((h)); } while (0) +#else +#define DUK_HPROXY_ASSERT_VALID(h) do {} while (0) +#endif + +struct duk_hproxy { + /* Shared object part. */ + duk_hobject obj; + + /* Proxy target object. */ + duk_hobject *target; + + /* Proxy handlers (traps). */ + duk_hobject *handler; +}; + +#endif /* DUK_HPROXY_H_INCLUDED */ diff --git a/third_party/duktape/duk_hstring.h b/third_party/duktape/duk_hstring.h new file mode 100644 index 00000000..f7caab9f --- /dev/null +++ b/third_party/duktape/duk_hstring.h @@ -0,0 +1,253 @@ +/* + * Heap string representation. + * + * Strings are byte sequences ordinarily stored in extended UTF-8 format, + * allowing values larger than the official UTF-8 range (used internally) + * and also allowing UTF-8 encoding of surrogate pairs (CESU-8 format). + * Strings may also be invalid UTF-8 altogether which is the case e.g. with + * strings used as internal property names and raw buffers converted to + * strings. In such cases the 'clen' field contains an inaccurate value. + * + * ECMAScript requires support for 32-bit long strings. However, since each + * 16-bit codepoint can take 3 bytes in CESU-8, this representation can only + * support about 1.4G codepoint long strings in extreme cases. This is not + * really a practical issue. + */ + +#if !defined(DUK_HSTRING_H_INCLUDED) +#define DUK_HSTRING_H_INCLUDED + +/* Impose a maximum string length for now. Restricted artificially to + * ensure adding a heap header length won't overflow size_t. The limit + * should be synchronized with DUK_HBUFFER_MAX_BYTELEN. + * + * E5.1 makes provisions to support strings longer than 4G characters. + * This limit should be eliminated on 64-bit platforms (and increased + * closer to maximum support on 32-bit platforms). + */ + +#if defined(DUK_USE_STRLEN16) +#define DUK_HSTRING_MAX_BYTELEN (0x0000ffffUL) +#else +#define DUK_HSTRING_MAX_BYTELEN (0x7fffffffUL) +#endif + +/* XXX: could add flags for "is valid CESU-8" (ECMAScript compatible strings), + * "is valid UTF-8", "is valid extended UTF-8" (internal strings are not, + * regexp bytecode is), and "contains non-BMP characters". These are not + * needed right now. + */ + +/* With lowmem builds the high 16 bits of duk_heaphdr are used for other + * purposes, so this leaves 7 duk_heaphdr flags and 9 duk_hstring flags. + */ +#define DUK_HSTRING_FLAG_ASCII DUK_HEAPHDR_USER_FLAG(0) /* string is ASCII, clen == blen */ +#define DUK_HSTRING_FLAG_ARRIDX DUK_HEAPHDR_USER_FLAG(1) /* string is a valid array index */ +#define DUK_HSTRING_FLAG_SYMBOL DUK_HEAPHDR_USER_FLAG(2) /* string is a symbol (invalid utf-8) */ +#define DUK_HSTRING_FLAG_HIDDEN DUK_HEAPHDR_USER_FLAG(3) /* string is a hidden symbol (implies symbol, Duktape 1.x internal string) */ +#define DUK_HSTRING_FLAG_RESERVED_WORD DUK_HEAPHDR_USER_FLAG(4) /* string is a reserved word (non-strict) */ +#define DUK_HSTRING_FLAG_STRICT_RESERVED_WORD DUK_HEAPHDR_USER_FLAG(5) /* string is a reserved word (strict) */ +#define DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS DUK_HEAPHDR_USER_FLAG(6) /* string is 'eval' or 'arguments' */ +#define DUK_HSTRING_FLAG_EXTDATA DUK_HEAPHDR_USER_FLAG(7) /* string data is external (duk_hstring_external) */ +#define DUK_HSTRING_FLAG_PINNED_LITERAL DUK_HEAPHDR_USER_FLAG(8) /* string is a literal, and pinned */ + +#define DUK_HSTRING_HAS_ASCII(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII) +#define DUK_HSTRING_HAS_ARRIDX(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX) +#define DUK_HSTRING_HAS_SYMBOL(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL) +#define DUK_HSTRING_HAS_HIDDEN(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN) +#define DUK_HSTRING_HAS_RESERVED_WORD(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD) +#define DUK_HSTRING_HAS_STRICT_RESERVED_WORD(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD) +#define DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS) +#define DUK_HSTRING_HAS_EXTDATA(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA) +#define DUK_HSTRING_HAS_PINNED_LITERAL(x) DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL) + +#define DUK_HSTRING_SET_ASCII(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII) +#define DUK_HSTRING_SET_ARRIDX(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX) +#define DUK_HSTRING_SET_SYMBOL(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL) +#define DUK_HSTRING_SET_HIDDEN(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN) +#define DUK_HSTRING_SET_RESERVED_WORD(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD) +#define DUK_HSTRING_SET_STRICT_RESERVED_WORD(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD) +#define DUK_HSTRING_SET_EVAL_OR_ARGUMENTS(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS) +#define DUK_HSTRING_SET_EXTDATA(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA) +#define DUK_HSTRING_SET_PINNED_LITERAL(x) DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL) + +#define DUK_HSTRING_CLEAR_ASCII(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII) +#define DUK_HSTRING_CLEAR_ARRIDX(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX) +#define DUK_HSTRING_CLEAR_SYMBOL(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL) +#define DUK_HSTRING_CLEAR_HIDDEN(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN) +#define DUK_HSTRING_CLEAR_RESERVED_WORD(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD) +#define DUK_HSTRING_CLEAR_STRICT_RESERVED_WORD(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD) +#define DUK_HSTRING_CLEAR_EVAL_OR_ARGUMENTS(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS) +#define DUK_HSTRING_CLEAR_EXTDATA(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA) +#define DUK_HSTRING_CLEAR_PINNED_LITERAL(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL) + +#if 0 /* Slightly smaller code without explicit flag, but explicit flag + * is very useful when 'clen' is dropped. + */ +#define DUK_HSTRING_IS_ASCII(x) (DUK_HSTRING_GET_BYTELEN((x)) == DUK_HSTRING_GET_CHARLEN((x))) +#endif +#define DUK_HSTRING_IS_ASCII(x) DUK_HSTRING_HAS_ASCII((x)) /* lazily set! */ +#define DUK_HSTRING_IS_EMPTY(x) (DUK_HSTRING_GET_BYTELEN((x)) == 0) + +#if defined(DUK_USE_STRHASH16) +#define DUK_HSTRING_GET_HASH(x) ((x)->hdr.h_flags >> 16) +#define DUK_HSTRING_SET_HASH(x,v) do { \ + (x)->hdr.h_flags = ((x)->hdr.h_flags & 0x0000ffffUL) | ((v) << 16); \ + } while (0) +#else +#define DUK_HSTRING_GET_HASH(x) ((x)->hash) +#define DUK_HSTRING_SET_HASH(x,v) do { \ + (x)->hash = (v); \ + } while (0) +#endif + +#if defined(DUK_USE_STRLEN16) +#define DUK_HSTRING_GET_BYTELEN(x) ((x)->hdr.h_strextra16) +#define DUK_HSTRING_SET_BYTELEN(x,v) do { \ + (x)->hdr.h_strextra16 = (v); \ + } while (0) +#if defined(DUK_USE_HSTRING_CLEN) +#define DUK_HSTRING_GET_CHARLEN(x) duk_hstring_get_charlen((x)) +#define DUK_HSTRING_SET_CHARLEN(x,v) do { \ + (x)->clen16 = (v); \ + } while (0) +#else +#define DUK_HSTRING_GET_CHARLEN(x) duk_hstring_get_charlen((x)) +#define DUK_HSTRING_SET_CHARLEN(x,v) do { \ + DUK_ASSERT(0); /* should never be called */ \ + } while (0) +#endif +#else +#define DUK_HSTRING_GET_BYTELEN(x) ((x)->blen) +#define DUK_HSTRING_SET_BYTELEN(x,v) do { \ + (x)->blen = (v); \ + } while (0) +#define DUK_HSTRING_GET_CHARLEN(x) duk_hstring_get_charlen((x)) +#define DUK_HSTRING_SET_CHARLEN(x,v) do { \ + (x)->clen = (v); \ + } while (0) +#endif + +#if defined(DUK_USE_HSTRING_EXTDATA) +#define DUK_HSTRING_GET_EXTDATA(x) \ + ((x)->extdata) +#define DUK_HSTRING_GET_DATA(x) \ + (DUK_HSTRING_HAS_EXTDATA((x)) ? \ + DUK_HSTRING_GET_EXTDATA((const duk_hstring_external *) (x)) : ((const duk_uint8_t *) ((x) + 1))) +#else +#define DUK_HSTRING_GET_DATA(x) \ + ((const duk_uint8_t *) ((x) + 1)) +#endif + +#define DUK_HSTRING_GET_DATA_END(x) \ + (DUK_HSTRING_GET_DATA((x)) + (x)->blen) + +/* Marker value; in E5 2^32-1 is not a valid array index (2^32-2 is highest + * valid). + */ +#define DUK_HSTRING_NO_ARRAY_INDEX (0xffffffffUL) + +#if defined(DUK_USE_HSTRING_ARRIDX) +#define DUK_HSTRING_GET_ARRIDX_FAST(h) ((h)->arridx) +#define DUK_HSTRING_GET_ARRIDX_SLOW(h) ((h)->arridx) +#else +/* Get array index related to string (or return DUK_HSTRING_NO_ARRAY_INDEX); + * avoids helper call if string has no array index value. + */ +#define DUK_HSTRING_GET_ARRIDX_FAST(h) \ + (DUK_HSTRING_HAS_ARRIDX((h)) ? duk_js_to_arrayindex_hstring_fast_known((h)) : DUK_HSTRING_NO_ARRAY_INDEX) + +/* Slower but more compact variant. */ +#define DUK_HSTRING_GET_ARRIDX_SLOW(h) \ + (duk_js_to_arrayindex_hstring_fast((h))) +#endif + +/* XXX: these actually fit into duk_hstring */ +#define DUK_SYMBOL_TYPE_HIDDEN 0 +#define DUK_SYMBOL_TYPE_GLOBAL 1 +#define DUK_SYMBOL_TYPE_LOCAL 2 +#define DUK_SYMBOL_TYPE_WELLKNOWN 3 + +/* Assertion for duk_hstring validity. */ +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL_DECL void duk_hstring_assert_valid(duk_hstring *h); +#define DUK_HSTRING_ASSERT_VALID(h) do { duk_hstring_assert_valid((h)); } while (0) +#else +#define DUK_HSTRING_ASSERT_VALID(h) do {} while (0) +#endif + +/* + * Misc + */ + +struct duk_hstring { + /* Smaller heaphdr than for other objects, because strings are held + * in string intern table which requires no link pointers. Much of + * the 32-bit flags field is unused by flags, so we can stuff a 16-bit + * field in there. + */ + duk_heaphdr_string hdr; + + /* String hash. */ +#if defined(DUK_USE_STRHASH16) + /* If 16-bit hash is in use, stuff it into duk_heaphdr_string flags. */ +#else + duk_uint32_t hash; +#endif + + /* Precomputed array index (or DUK_HSTRING_NO_ARRAY_INDEX). */ +#if defined(DUK_USE_HSTRING_ARRIDX) + duk_uarridx_t arridx; +#endif + + /* Length in bytes (not counting NUL term). */ +#if defined(DUK_USE_STRLEN16) + /* placed in duk_heaphdr_string */ +#else + duk_uint32_t blen; +#endif + + /* Length in codepoints (must be E5 compatible). */ +#if defined(DUK_USE_STRLEN16) +#if defined(DUK_USE_HSTRING_CLEN) + duk_uint16_t clen16; +#else + /* computed live */ +#endif +#else + duk_uint32_t clen; +#endif + + /* + * String data of 'blen+1' bytes follows (+1 for NUL termination + * convenience for C API). No alignment needs to be guaranteed + * for strings, but fields above should guarantee alignment-by-4 + * (but not alignment-by-8). + */ +}; + +/* The external string struct is defined even when the feature is inactive. */ +struct duk_hstring_external { + duk_hstring str; + + /* + * For an external string, the NUL-terminated string data is stored + * externally. The user must guarantee that data behind this pointer + * doesn't change while it's used. + */ + + const duk_uint8_t *extdata; +}; + +/* + * Prototypes + */ + +DUK_INTERNAL_DECL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk_hstring *h, duk_uint_t pos, duk_bool_t surrogate_aware); +DUK_INTERNAL_DECL duk_bool_t duk_hstring_equals_ascii_cstring(duk_hstring *h, const char *cstr); +DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h); +#if !defined(DUK_USE_HSTRING_LAZY_CLEN) +DUK_INTERNAL_DECL void duk_hstring_init_charlen(duk_hstring *h); +#endif + +#endif /* DUK_HSTRING_H_INCLUDED */ diff --git a/third_party/duktape/duk_hstring_assert.c b/third_party/duktape/duk_hstring_assert.c new file mode 100644 index 00000000..553018d5 --- /dev/null +++ b/third_party/duktape/duk_hstring_assert.c @@ -0,0 +1,13 @@ +/* + * duk_hstring assertion helpers. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_ASSERTIONS) + +DUK_INTERNAL void duk_hstring_assert_valid(duk_hstring *h) { + DUK_ASSERT(h != NULL); +} + +#endif /* DUK_USE_ASSERTIONS */ diff --git a/third_party/duktape/duk_hstring_misc.c b/third_party/duktape/duk_hstring_misc.c new file mode 100644 index 00000000..23744c25 --- /dev/null +++ b/third_party/duktape/duk_hstring_misc.c @@ -0,0 +1,196 @@ +/* + * Misc support functions + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * duk_hstring charCodeAt, with and without surrogate awareness + */ + +DUK_INTERNAL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk_hstring *h, duk_uint_t pos, duk_bool_t surrogate_aware) { + duk_uint32_t boff; + const duk_uint8_t *p, *p_start, *p_end; + duk_ucodepoint_t cp1; + duk_ucodepoint_t cp2; + + /* Caller must check character offset to be inside the string. */ + DUK_ASSERT(thr != NULL); + DUK_ASSERT(h != NULL); + DUK_ASSERT_DISABLE(pos >= 0); /* unsigned */ + DUK_ASSERT(pos < (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h)); + + boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h, (duk_uint32_t) pos); + DUK_DDD(DUK_DDDPRINT("charCodeAt: pos=%ld -> boff=%ld, str=%!O", + (long) pos, (long) boff, (duk_heaphdr *) h)); + DUK_ASSERT_DISABLE(boff >= 0); + DUK_ASSERT(boff < DUK_HSTRING_GET_BYTELEN(h)); + + p_start = DUK_HSTRING_GET_DATA(h); + p_end = p_start + DUK_HSTRING_GET_BYTELEN(h); + p = p_start + boff; + DUK_DDD(DUK_DDDPRINT("p_start=%p, p_end=%p, p=%p", + (const void *) p_start, (const void *) p_end, + (const void *) p)); + + /* For invalid UTF-8 (never happens for standard ECMAScript strings) + * return U+FFFD replacement character. + */ + if (duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp1)) { + if (surrogate_aware && cp1 >= 0xd800UL && cp1 <= 0xdbffUL) { + /* The decode helper is memory safe even if 'cp1' was + * decoded at the end of the string and 'p' is no longer + * within string memory range. + */ + cp2 = 0; /* If call fails, this is left untouched and won't match cp2 check. */ + (void) duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp2); + if (cp2 >= 0xdc00UL && cp2 <= 0xdfffUL) { + cp1 = (duk_ucodepoint_t) (((cp1 - 0xd800UL) << 10) + (cp2 - 0xdc00UL) + 0x10000UL); + } + } + } else { + cp1 = DUK_UNICODE_CP_REPLACEMENT_CHARACTER; + } + + return cp1; +} + +/* + * duk_hstring charlen, when lazy charlen disabled + */ + +#if !defined(DUK_USE_HSTRING_LAZY_CLEN) +#if !defined(DUK_USE_HSTRING_CLEN) +#error non-lazy duk_hstring charlen but DUK_USE_HSTRING_CLEN not set +#endif +DUK_INTERNAL void duk_hstring_init_charlen(duk_hstring *h) { + duk_uint32_t clen; + + DUK_ASSERT(h != NULL); + DUK_ASSERT(!DUK_HSTRING_HAS_ASCII(h)); + DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)); + + clen = duk_unicode_unvalidated_utf8_length(DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h)); +#if defined(DUK_USE_STRLEN16) + DUK_ASSERT(clen <= 0xffffUL); /* Bytelength checked during interning. */ + h->clen16 = (duk_uint16_t) clen; +#else + h->clen = (duk_uint32_t) clen; +#endif + if (DUK_LIKELY(clen == DUK_HSTRING_GET_BYTELEN(h))) { + DUK_HSTRING_SET_ASCII(h); + } +} + +DUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) { +#if defined(DUK_USE_STRLEN16) + return h->clen16; +#else + return h->clen; +#endif +} +#endif /* !DUK_USE_HSTRING_LAZY_CLEN */ + +/* + * duk_hstring charlen, when lazy charlen enabled + */ + +#if defined(DUK_USE_HSTRING_LAZY_CLEN) +#if defined(DUK_USE_HSTRING_CLEN) +DUK_LOCAL DUK_COLD duk_size_t duk__hstring_get_charlen_slowpath(duk_hstring *h) { + duk_size_t res; + + DUK_ASSERT(h->clen == 0); /* Checked by caller. */ + +#if defined(DUK_USE_ROM_STRINGS) + /* ROM strings have precomputed clen, but if the computed clen is zero + * we can still come here and can't write anything. + */ + if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) { + return 0; + } +#endif + + res = duk_unicode_unvalidated_utf8_length(DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h)); +#if defined(DUK_USE_STRLEN16) + DUK_ASSERT(res <= 0xffffUL); /* Bytelength checked during interning. */ + h->clen16 = (duk_uint16_t) res; +#else + h->clen = (duk_uint32_t) res; +#endif + if (DUK_LIKELY(res == DUK_HSTRING_GET_BYTELEN(h))) { + DUK_HSTRING_SET_ASCII(h); + } + return res; +} +#else /* DUK_USE_HSTRING_CLEN */ +DUK_LOCAL duk_size_t duk__hstring_get_charlen_slowpath(duk_hstring *h) { + if (DUK_LIKELY(DUK_HSTRING_HAS_ASCII(h))) { + /* Most practical strings will go here. */ + return DUK_HSTRING_GET_BYTELEN(h); + } else { + /* ASCII flag is lazy, so set it here. */ + duk_size_t res; + + /* XXX: here we could use the strcache to speed up the + * computation (matters for 'i < str.length' loops). + */ + + res = duk_unicode_unvalidated_utf8_length(DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h)); + +#if defined(DUK_USE_ROM_STRINGS) + if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) { + /* For ROM strings, can't write anything; ASCII flag + * is preset so we don't need to update it. + */ + return res; + } +#endif + if (DUK_LIKELY(res == DUK_HSTRING_GET_BYTELEN(h))) { + DUK_HSTRING_SET_ASCII(h); + } + return res; + } +} +#endif /* DUK_USE_HSTRING_CLEN */ + +#if defined(DUK_USE_HSTRING_CLEN) +DUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) { +#if defined(DUK_USE_STRLEN16) + if (DUK_LIKELY(h->clen16 != 0)) { + return h->clen16; + } +#else + if (DUK_LIKELY(h->clen != 0)) { + return h->clen; + } +#endif + return duk__hstring_get_charlen_slowpath(h); +} +#else /* DUK_USE_HSTRING_CLEN */ +DUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) { + /* Always use slow path. */ + return duk__hstring_get_charlen_slowpath(h); +} +#endif /* DUK_USE_HSTRING_CLEN */ +#endif /* DUK_USE_HSTRING_LAZY_CLEN */ + +/* + * Compare duk_hstring to an ASCII cstring. + */ + +DUK_INTERNAL duk_bool_t duk_hstring_equals_ascii_cstring(duk_hstring *h, const char *cstr) { + duk_size_t len; + + DUK_ASSERT(h != NULL); + DUK_ASSERT(cstr != NULL); + + len = DUK_STRLEN(cstr); + if (len != DUK_HSTRING_GET_BYTELEN(h)) { + return 0; + } + if (duk_memcmp((const void *) cstr, (const void *) DUK_HSTRING_GET_DATA(h), len) == 0) { + return 1; + } + return 0; +} diff --git a/third_party/duktape/duk_hthread.h b/third_party/duktape/duk_hthread.h new file mode 100644 index 00000000..65b89bbf --- /dev/null +++ b/third_party/duktape/duk_hthread.h @@ -0,0 +1,408 @@ +/* + * Heap thread object representation. + * + * duk_hthread is also the 'context' for public API functions via a + * different typedef. Most API calls operate on the topmost frame + * of the value stack only. + */ + +#if !defined(DUK_HTHREAD_H_INCLUDED) +#define DUK_HTHREAD_H_INCLUDED + +/* + * Stack constants + */ + +/* Initial valstack size, roughly 0.7kiB. */ +#define DUK_VALSTACK_INITIAL_SIZE 96U + +/* Internal extra elements assumed on function entry, always added to + * user-defined 'extra' for e.g. the duk_check_stack() call. + */ +#define DUK_VALSTACK_INTERNAL_EXTRA 32U + +/* Number of elements guaranteed to be user accessible (in addition to call + * arguments) on Duktape/C function entry. This is the major public API + * commitment. + */ +#define DUK_VALSTACK_API_ENTRY_MINIMUM DUK_API_ENTRY_STACK + +/* + * Activation defines + */ + +#define DUK_ACT_FLAG_STRICT (1U << 0) /* function executes in strict mode */ +#define DUK_ACT_FLAG_TAILCALLED (1U << 1) /* activation has tail called one or more times */ +#define DUK_ACT_FLAG_CONSTRUCT (1U << 2) /* function executes as a constructor (called via "new") */ +#define DUK_ACT_FLAG_PREVENT_YIELD (1U << 3) /* activation prevents yield (native call or "new") */ +#define DUK_ACT_FLAG_DIRECT_EVAL (1U << 4) /* activation is a direct eval call */ +#define DUK_ACT_FLAG_CONSTRUCT_PROXY (1U << 5) /* activation is for Proxy 'construct' call, special return value handling */ +#define DUK_ACT_FLAG_BREAKPOINT_ACTIVE (1U << 6) /* activation has active breakpoint(s) */ + +#define DUK_ACT_GET_FUNC(act) ((act)->func) + +/* + * Flags for __FILE__ / __LINE__ registered into tracedata + */ + +#define DUK_TB_FLAG_NOBLAME_FILELINE (1U << 0) /* don't report __FILE__ / __LINE__ as fileName/lineNumber */ + +/* + * Catcher defines + */ + +/* XXX: remove catcher type entirely */ + +/* flags field: LLLLLLFT, L = label (24 bits), F = flags (4 bits), T = type (4 bits) */ +#define DUK_CAT_TYPE_MASK 0x0000000fUL +#define DUK_CAT_TYPE_BITS 4 +#define DUK_CAT_LABEL_MASK 0xffffff00UL +#define DUK_CAT_LABEL_BITS 24 +#define DUK_CAT_LABEL_SHIFT 8 + +#define DUK_CAT_FLAG_CATCH_ENABLED (1U << 4) /* catch part will catch */ +#define DUK_CAT_FLAG_FINALLY_ENABLED (1U << 5) /* finally part will catch */ +#define DUK_CAT_FLAG_CATCH_BINDING_ENABLED (1U << 6) /* request to create catch binding */ +#define DUK_CAT_FLAG_LEXENV_ACTIVE (1U << 7) /* catch or with binding is currently active */ + +#define DUK_CAT_TYPE_UNKNOWN 0 +#define DUK_CAT_TYPE_TCF 1 +#define DUK_CAT_TYPE_LABEL 2 + +#define DUK_CAT_GET_TYPE(c) ((c)->flags & DUK_CAT_TYPE_MASK) +#define DUK_CAT_GET_LABEL(c) (((c)->flags & DUK_CAT_LABEL_MASK) >> DUK_CAT_LABEL_SHIFT) + +#define DUK_CAT_HAS_CATCH_ENABLED(c) ((c)->flags & DUK_CAT_FLAG_CATCH_ENABLED) +#define DUK_CAT_HAS_FINALLY_ENABLED(c) ((c)->flags & DUK_CAT_FLAG_FINALLY_ENABLED) +#define DUK_CAT_HAS_CATCH_BINDING_ENABLED(c) ((c)->flags & DUK_CAT_FLAG_CATCH_BINDING_ENABLED) +#define DUK_CAT_HAS_LEXENV_ACTIVE(c) ((c)->flags & DUK_CAT_FLAG_LEXENV_ACTIVE) + +#define DUK_CAT_SET_CATCH_ENABLED(c) do { \ + (c)->flags |= DUK_CAT_FLAG_CATCH_ENABLED; \ + } while (0) +#define DUK_CAT_SET_FINALLY_ENABLED(c) do { \ + (c)->flags |= DUK_CAT_FLAG_FINALLY_ENABLED; \ + } while (0) +#define DUK_CAT_SET_CATCH_BINDING_ENABLED(c) do { \ + (c)->flags |= DUK_CAT_FLAG_CATCH_BINDING_ENABLED; \ + } while (0) +#define DUK_CAT_SET_LEXENV_ACTIVE(c) do { \ + (c)->flags |= DUK_CAT_FLAG_LEXENV_ACTIVE; \ + } while (0) + +#define DUK_CAT_CLEAR_CATCH_ENABLED(c) do { \ + (c)->flags &= ~DUK_CAT_FLAG_CATCH_ENABLED; \ + } while (0) +#define DUK_CAT_CLEAR_FINALLY_ENABLED(c) do { \ + (c)->flags &= ~DUK_CAT_FLAG_FINALLY_ENABLED; \ + } while (0) +#define DUK_CAT_CLEAR_CATCH_BINDING_ENABLED(c) do { \ + (c)->flags &= ~DUK_CAT_FLAG_CATCH_BINDING_ENABLED; \ + } while (0) +#define DUK_CAT_CLEAR_LEXENV_ACTIVE(c) do { \ + (c)->flags &= ~DUK_CAT_FLAG_LEXENV_ACTIVE; \ + } while (0) + +/* + * Thread defines + */ + +#if defined(DUK_USE_ROM_STRINGS) +#define DUK_HTHREAD_GET_STRING(thr,idx) \ + ((duk_hstring *) DUK_LOSE_CONST(duk_rom_strings_stridx[(idx)])) +#else /* DUK_USE_ROM_STRINGS */ +#if defined(DUK_USE_HEAPPTR16) +#define DUK_HTHREAD_GET_STRING(thr,idx) \ + ((duk_hstring *) DUK_USE_HEAPPTR_DEC16((thr)->heap->heap_udata, (thr)->strs16[(idx)])) +#else +#define DUK_HTHREAD_GET_STRING(thr,idx) \ + ((thr)->strs[(idx)]) +#endif +#endif /* DUK_USE_ROM_STRINGS */ + +/* values for the state field */ +#define DUK_HTHREAD_STATE_INACTIVE 1 /* thread not currently running */ +#define DUK_HTHREAD_STATE_RUNNING 2 /* thread currently running (only one at a time) */ +#define DUK_HTHREAD_STATE_RESUMED 3 /* thread resumed another thread (active but not running) */ +#define DUK_HTHREAD_STATE_YIELDED 4 /* thread has yielded */ +#define DUK_HTHREAD_STATE_TERMINATED 5 /* thread has terminated */ + +/* Executor interrupt default interval when nothing else requires a + * smaller value. The default interval must be small enough to allow + * for reasonable execution timeout checking but large enough to keep + * impact on execution performance low. + */ +#if defined(DUK_USE_INTERRUPT_COUNTER) +#define DUK_HTHREAD_INTCTR_DEFAULT (256L * 1024L) +#endif + +/* + * Assert context is valid: non-NULL pointer, fields look sane. + * + * This is used by public API call entrypoints to catch invalid 'ctx' pointers + * as early as possible; invalid 'ctx' pointers cause very odd and difficult to + * diagnose behavior so it's worth checking even when the check is not 100%. + */ + +#if defined(DUK_USE_ASSERTIONS) +/* Assertions for internals. */ +DUK_INTERNAL_DECL void duk_hthread_assert_valid(duk_hthread *thr); +#define DUK_HTHREAD_ASSERT_VALID(thr) do { duk_hthread_assert_valid((thr)); } while (0) + +/* Assertions for public API calls; a bit stronger. */ +DUK_INTERNAL_DECL void duk_ctx_assert_valid(duk_hthread *thr); +#define DUK_CTX_ASSERT_VALID(thr) do { duk_ctx_assert_valid((thr)); } while (0) +#else +#define DUK_HTHREAD_ASSERT_VALID(thr) do {} while (0) +#define DUK_CTX_ASSERT_VALID(thr) do {} while (0) +#endif + +/* Assertions for API call entry specifically. Checks 'ctx' but also may + * check internal state (e.g. not in a debugger transport callback). + */ +#define DUK_ASSERT_API_ENTRY(thr) do { \ + DUK_CTX_ASSERT_VALID((thr)); \ + DUK_ASSERT((thr)->heap != NULL); \ + DUK_ASSERT((thr)->heap->dbg_calling_transport == 0); \ + } while (0) + +/* + * Assertion helpers. + */ + +#define DUK_ASSERT_STRIDX_VALID(val) \ + DUK_ASSERT((duk_uint_t) (val) < DUK_HEAP_NUM_STRINGS) + +#define DUK_ASSERT_BIDX_VALID(val) \ + DUK_ASSERT((duk_uint_t) (val) < DUK_NUM_BUILTINS) + +/* + * Misc + */ + +/* Fast access to 'this' binding. Assumes there's a call in progress. */ +#define DUK_HTHREAD_THIS_PTR(thr) \ + (DUK_ASSERT_EXPR((thr) != NULL), \ + DUK_ASSERT_EXPR((thr)->valstack_bottom > (thr)->valstack), \ + (thr)->valstack_bottom - 1) + +/* + * Struct defines + */ + +/* Fields are ordered for alignment/packing. */ +struct duk_activation { + duk_tval tv_func; /* borrowed: full duk_tval for function being executed; for lightfuncs */ + duk_hobject *func; /* borrowed: function being executed; for bound function calls, this is the final, real function, NULL for lightfuncs */ + duk_activation *parent; /* previous (parent) activation (or NULL if none) */ + duk_hobject *var_env; /* current variable environment (may be NULL if delayed) */ + duk_hobject *lex_env; /* current lexical environment (may be NULL if delayed) */ + duk_catcher *cat; /* current catcher (or NULL) */ + +#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY) + /* Previous value of 'func' caller, restored when unwound. Only in use + * when 'func' is non-strict. + */ + duk_hobject *prev_caller; +#endif + + duk_instr_t *curr_pc; /* next instruction to execute (points to 'func' bytecode, stable pointer), NULL for native calls */ + + /* bottom_byteoff and retval_byteoff are only used for book-keeping + * of ECMAScript-initiated calls, to allow returning to an ECMAScript + * function properly. + */ + + /* Bottom of valstack for this activation, used to reset + * valstack_bottom on return; offset is absolute. There's + * no need to track 'top' because native call handling deals + * with that using locals, and for ECMAScript returns 'nregs' + * indicates the necessary top. + */ + duk_size_t bottom_byteoff; + + /* Return value when returning to this activation (points to caller + * reg, not callee reg); offset is absolute (only set if activation is + * not topmost). + * + * Note: bottom_byteoff is always set, while retval_byteoff is only + * applicable for activations below the topmost one. Currently + * retval_byteoff for the topmost activation is considered garbage + * (and it not initialized on entry or cleared on return; may contain + * previous or garbage values). + */ + duk_size_t retval_byteoff; + + /* Current 'this' binding is the value just below bottom. + * Previously, 'this' binding was handled with an index to the + * (calling) valstack. This works for everything except tail + * calls, which must not "accumulate" valstack temps. + */ + + /* Value stack reserve (valstack_end) byte offset to be restored + * when returning to this activation. Only used by the bytecode + * executor. + */ + duk_size_t reserve_byteoff; + +#if defined(DUK_USE_DEBUGGER_SUPPORT) + duk_uint32_t prev_line; /* needed for stepping */ +#endif + + duk_small_uint_t flags; +}; + +struct duk_catcher { + duk_catcher *parent; /* previous (parent) catcher (or NULL if none) */ + duk_hstring *h_varname; /* borrowed reference to catch variable name (or NULL if none) */ + /* (reference is valid as long activation exists) */ + duk_instr_t *pc_base; /* resume execution from pc_base or pc_base+1 (points to 'func' bytecode, stable pointer) */ + duk_size_t idx_base; /* idx_base and idx_base+1 get completion value and type */ + duk_uint32_t flags; /* type and control flags, label number */ + /* XXX: could pack 'flags' and 'idx_base' to same value in practice, + * on 32-bit targets this would make duk_catcher 16 bytes. + */ +}; + +struct duk_hthread { + /* Shared object part */ + duk_hobject obj; + + /* Pointer to bytecode executor's 'curr_pc' variable. Used to copy + * the current PC back into the topmost activation when activation + * state is about to change (or "syncing" is otherwise needed). This + * is rather awkward but important for performance, see execution.rst. + */ + duk_instr_t **ptr_curr_pc; + + /* Backpointers. */ + duk_heap *heap; + + /* Current strictness flag: affects API calls. */ + duk_uint8_t strict; + + /* Thread state. */ + duk_uint8_t state; + duk_uint8_t unused1; + duk_uint8_t unused2; + + /* XXX: Valstack and callstack are currently assumed to have non-NULL + * pointers. Relaxing this would not lead to big benefits (except + * perhaps for terminated threads). + */ + + /* Value stack: these are expressed as pointers for faster stack + * manipulation. [valstack,valstack_top[ is GC-reachable, + * [valstack_top,valstack_alloc_end[ is not GC-reachable but kept + * initialized as 'undefined'. [valstack,valstack_end[ is the + * guaranteed/reserved space and the valstack cannot be resized to + * a smaller size. [valstack_end,valstack_alloc_end[ is currently + * allocated slack that can be used to grow the current guaranteed + * space but may be shrunk away without notice. + * + * + * <----------------------- guaranteed ---> + * <---- slack ---> + * <--- frame ---> + * .-------------+=============+----------+--------------. + * |xxxxxxxxxxxxx|yyyyyyyyyyyyy|uuuuuuuuuu|uuuuuuuuuuuuuu| + * `-------------+=============+----------+--------------' + * + * ^ ^ ^ ^ ^ + * | | | | | + * valstack bottom top end alloc_end + * + * xxx = arbitrary values, below current frame + * yyy = arbitrary values, inside current frame + * uuu = outside active value stack, initialized to 'undefined' + */ + duk_tval *valstack; /* start of valstack allocation */ + duk_tval *valstack_end; /* end of valstack reservation/guarantee (exclusive) */ + duk_tval *valstack_alloc_end; /* end of valstack allocation */ + duk_tval *valstack_bottom; /* bottom of current frame */ + duk_tval *valstack_top; /* top of current frame (exclusive) */ + + /* Call stack, represented as a linked list starting from the current + * activation (or NULL if nothing is active). + */ + duk_activation *callstack_curr; /* current activation (or NULL if none) */ + duk_size_t callstack_top; /* number of activation records in callstack (0 if none) */ + duk_size_t callstack_preventcount; /* number of activation records in callstack preventing a yield */ + + /* Yield/resume book-keeping. */ + duk_hthread *resumer; /* who resumed us (if any) */ + + /* Current compiler state (if any), used for augmenting SyntaxErrors. */ + duk_compiler_ctx *compile_ctx; + +#if defined(DUK_USE_INTERRUPT_COUNTER) + /* Interrupt counter for triggering a slow path check for execution + * timeout, debugger interaction such as breakpoints, etc. The value + * is valid for the current running thread, and both the init and + * counter values are copied whenever a thread switch occurs. It's + * important for the counter to be conveniently accessible for the + * bytecode executor inner loop for performance reasons. + */ + duk_int_t interrupt_counter; /* countdown state */ + duk_int_t interrupt_init; /* start value for current countdown */ +#endif + + /* Builtin-objects; may or may not be shared with other threads, + * threads existing in different "compartments" will have different + * built-ins. Must be stored on a per-thread basis because there + * is no intermediate structure for a thread group / compartment. + * This takes quite a lot of space, currently 43x4 = 172 bytes on + * 32-bit platforms. + * + * In some cases the builtins array could be ROM based, but it's + * sometimes edited (e.g. for sandboxing) so it's better to keep + * this array in RAM. + */ + duk_hobject *builtins[DUK_NUM_BUILTINS]; + + /* Convenience copies from heap/vm for faster access. */ +#if defined(DUK_USE_ROM_STRINGS) + /* No field needed when strings are in ROM. */ +#else +#if defined(DUK_USE_HEAPPTR16) + duk_uint16_t *strs16; +#else + duk_hstring **strs; +#endif +#endif +}; + +/* + * Prototypes + */ + +DUK_INTERNAL_DECL void duk_hthread_copy_builtin_objects(duk_hthread *thr_from, duk_hthread *thr_to); +DUK_INTERNAL_DECL void duk_hthread_create_builtin_objects(duk_hthread *thr); +DUK_INTERNAL_DECL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr); +DUK_INTERNAL_DECL void duk_hthread_terminate(duk_hthread *thr); + +DUK_INTERNAL_DECL duk_activation *duk_hthread_activation_alloc(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_hthread_activation_free(duk_hthread *thr, duk_activation *act); +DUK_INTERNAL_DECL void duk_hthread_activation_unwind_norz(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_hthread_activation_unwind_reuse_norz(duk_hthread *thr); +DUK_INTERNAL_DECL duk_activation *duk_hthread_get_activation_for_level(duk_hthread *thr, duk_int_t level); + +DUK_INTERNAL_DECL duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_hthread_catcher_free(duk_hthread *thr, duk_catcher *cat); +DUK_INTERNAL_DECL void duk_hthread_catcher_unwind_norz(duk_hthread *thr, duk_activation *act); +DUK_INTERNAL_DECL void duk_hthread_catcher_unwind_nolexenv_norz(duk_hthread *thr, duk_activation *act); + +#if defined(DUK_USE_FINALIZER_TORTURE) +DUK_INTERNAL_DECL void duk_hthread_valstack_torture_realloc(duk_hthread *thr); +#endif + +DUK_INTERNAL_DECL void *duk_hthread_get_valstack_ptr(duk_heap *heap, void *ud); /* indirect allocs */ + +#if defined(DUK_USE_DEBUGGER_SUPPORT) +DUK_INTERNAL_DECL duk_uint_fast32_t duk_hthread_get_act_curr_pc(duk_hthread *thr, duk_activation *act); +#endif +DUK_INTERNAL_DECL duk_uint_fast32_t duk_hthread_get_act_prev_pc(duk_hthread *thr, duk_activation *act); +DUK_INTERNAL_DECL void duk_hthread_sync_currpc(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_hthread_sync_and_null_currpc(duk_hthread *thr); + +#endif /* DUK_HTHREAD_H_INCLUDED */ diff --git a/third_party/duktape/duk_hthread_alloc.c b/third_party/duktape/duk_hthread_alloc.c new file mode 100644 index 00000000..506fb652 --- /dev/null +++ b/third_party/duktape/duk_hthread_alloc.c @@ -0,0 +1,59 @@ +/* + * duk_hthread allocation and freeing. + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Allocate initial stacks for a thread. Note that 'thr' must be reachable + * as a garbage collection may be triggered by the allocation attempts. + * Returns zero (without leaking memory) if init fails. + */ + +DUK_INTERNAL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr) { + duk_size_t alloc_size; + duk_size_t i; + + DUK_ASSERT(heap != NULL); + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->valstack == NULL); + DUK_ASSERT(thr->valstack_end == NULL); + DUK_ASSERT(thr->valstack_alloc_end == NULL); + DUK_ASSERT(thr->valstack_bottom == NULL); + DUK_ASSERT(thr->valstack_top == NULL); + DUK_ASSERT(thr->callstack_curr == NULL); + + /* valstack */ + DUK_ASSERT(DUK_VALSTACK_API_ENTRY_MINIMUM <= DUK_VALSTACK_INITIAL_SIZE); + alloc_size = sizeof(duk_tval) * DUK_VALSTACK_INITIAL_SIZE; + thr->valstack = (duk_tval *) DUK_ALLOC(heap, alloc_size); + if (!thr->valstack) { + goto fail; + } + duk_memzero(thr->valstack, alloc_size); + thr->valstack_end = thr->valstack + DUK_VALSTACK_API_ENTRY_MINIMUM; + thr->valstack_alloc_end = thr->valstack + DUK_VALSTACK_INITIAL_SIZE; + thr->valstack_bottom = thr->valstack; + thr->valstack_top = thr->valstack; + + for (i = 0; i < DUK_VALSTACK_INITIAL_SIZE; i++) { + DUK_TVAL_SET_UNDEFINED(&thr->valstack[i]); + } + + return 1; + + fail: + DUK_FREE(heap, thr->valstack); + DUK_ASSERT(thr->callstack_curr == NULL); + + thr->valstack = NULL; + return 0; +} + +/* For indirect allocs. */ + +DUK_INTERNAL void *duk_hthread_get_valstack_ptr(duk_heap *heap, void *ud) { + duk_hthread *thr = (duk_hthread *) ud; + DUK_UNREF(heap); + return (void *) thr->valstack; +} diff --git a/third_party/duktape/duk_hthread_builtins.c b/third_party/duktape/duk_hthread_builtins.c new file mode 100644 index 00000000..c7cff74b --- /dev/null +++ b/third_party/duktape/duk_hthread_builtins.c @@ -0,0 +1,871 @@ +/* + * Initialize built-in objects. Current thread must have a valstack + * and initialization errors may longjmp, so a setjmp() catch point + * must exist. + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Encoding constants, must match genbuiltins.py + */ + +#define DUK__PROP_FLAGS_BITS 3 +#define DUK__LENGTH_PROP_BITS 3 +#define DUK__NARGS_BITS 3 +#define DUK__PROP_TYPE_BITS 3 + +#define DUK__NARGS_VARARGS_MARKER 0x07 + +#define DUK__PROP_TYPE_DOUBLE 0 +#define DUK__PROP_TYPE_STRING 1 +#define DUK__PROP_TYPE_STRIDX 2 +#define DUK__PROP_TYPE_BUILTIN 3 +#define DUK__PROP_TYPE_UNDEFINED 4 +#define DUK__PROP_TYPE_BOOLEAN_TRUE 5 +#define DUK__PROP_TYPE_BOOLEAN_FALSE 6 +#define DUK__PROP_TYPE_ACCESSOR 7 + +/* + * Create built-in objects by parsing an init bitstream generated + * by genbuiltins.py. + */ + +#if defined(DUK_USE_ROM_OBJECTS) +#if defined(DUK_USE_ROM_GLOBAL_CLONE) || defined(DUK_USE_ROM_GLOBAL_INHERIT) +DUK_LOCAL void duk__duplicate_ram_global_object(duk_hthread *thr) { + duk_hobject *h_global; +#if defined(DUK_USE_ROM_GLOBAL_CLONE) + duk_hobject *h_oldglobal; + duk_uint8_t *props; + duk_size_t alloc_size; +#endif + duk_hobject *h_objenv; + + /* XXX: refactor into internal helper, duk_clone_hobject() */ + +#if defined(DUK_USE_ROM_GLOBAL_INHERIT) + /* Inherit from ROM-based global object: less RAM usage, less transparent. */ + h_global = duk_push_object_helper(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_GLOBAL), + DUK_BIDX_GLOBAL); + DUK_ASSERT(h_global != NULL); +#elif defined(DUK_USE_ROM_GLOBAL_CLONE) + /* Clone the properties of the ROM-based global object to create a + * fully RAM-based global object. Uses more memory than the inherit + * model but more compliant. + */ + h_global = duk_push_object_helper(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_GLOBAL), + DUK_BIDX_OBJECT_PROTOTYPE); + DUK_ASSERT(h_global != NULL); + h_oldglobal = thr->builtins[DUK_BIDX_GLOBAL]; + DUK_ASSERT(h_oldglobal != NULL); + + /* Copy the property table verbatim; this handles attributes etc. + * For ROM objects it's not necessary (or possible) to update + * refcounts so leave them as is. + */ + alloc_size = DUK_HOBJECT_P_ALLOC_SIZE(h_oldglobal); + DUK_ASSERT(alloc_size > 0); + props = DUK_ALLOC_CHECKED(thr, alloc_size); + DUK_ASSERT(props != NULL); + DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, h_oldglobal) != NULL); + duk_memcpy((void *) props, (const void *) DUK_HOBJECT_GET_PROPS(thr->heap, h_oldglobal), alloc_size); + + /* XXX: keep property attributes or tweak them here? + * Properties will now be non-configurable even when they're + * normally configurable for the global object. + */ + + DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, h_global) == NULL); + DUK_HOBJECT_SET_PROPS(thr->heap, h_global, props); + DUK_HOBJECT_SET_ESIZE(h_global, DUK_HOBJECT_GET_ESIZE(h_oldglobal)); + DUK_HOBJECT_SET_ENEXT(h_global, DUK_HOBJECT_GET_ENEXT(h_oldglobal)); + DUK_HOBJECT_SET_ASIZE(h_global, DUK_HOBJECT_GET_ASIZE(h_oldglobal)); + DUK_HOBJECT_SET_HSIZE(h_global, DUK_HOBJECT_GET_HSIZE(h_oldglobal)); +#else +#error internal error in config defines +#endif + + duk_hobject_compact_props(thr, h_global); + DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL); + DUK_ASSERT(!DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE((duk_heaphdr *) thr->builtins[DUK_BIDX_GLOBAL])); /* no need to decref: ROM object */ + thr->builtins[DUK_BIDX_GLOBAL] = h_global; + DUK_HOBJECT_INCREF(thr, h_global); + DUK_D(DUK_DPRINT("duplicated global object: %!O", h_global)); + + /* Create a fresh object environment for the global scope. This is + * needed so that the global scope points to the newly created RAM-based + * global object. + */ + h_objenv = (duk_hobject *) duk_hobjenv_alloc(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV)); + DUK_ASSERT(h_objenv != NULL); + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_objenv) == NULL); + duk_push_hobject(thr, h_objenv); + + DUK_ASSERT(h_global != NULL); + ((duk_hobjenv *) h_objenv)->target = h_global; + DUK_HOBJECT_INCREF(thr, h_global); + DUK_ASSERT(((duk_hobjenv *) h_objenv)->has_this == 0); + + DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL_ENV] != NULL); + DUK_ASSERT(!DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE((duk_heaphdr *) thr->builtins[DUK_BIDX_GLOBAL_ENV])); /* no need to decref: ROM object */ + thr->builtins[DUK_BIDX_GLOBAL_ENV] = h_objenv; + DUK_HOBJECT_INCREF(thr, h_objenv); + DUK_D(DUK_DPRINT("duplicated global env: %!O", h_objenv)); + + DUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) h_objenv); + + duk_pop_2(thr); /* Pop global object and global env. */ +} +#endif /* DUK_USE_ROM_GLOBAL_CLONE || DUK_USE_ROM_GLOBAL_INHERIT */ + +DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) { + /* Setup builtins from ROM objects. All heaps/threads will share + * the same readonly objects. + */ + duk_small_uint_t i; + + for (i = 0; i < DUK_NUM_BUILTINS; i++) { + duk_hobject *h; + h = (duk_hobject *) DUK_LOSE_CONST(duk_rom_builtins_bidx[i]); + DUK_ASSERT(h != NULL); + thr->builtins[i] = h; + } + +#if defined(DUK_USE_ROM_GLOBAL_CLONE) || defined(DUK_USE_ROM_GLOBAL_INHERIT) + /* By default the global object is read-only which is often much + * more of an issue than having read-only built-in objects (like + * RegExp, Date, etc). Use a RAM-based copy of the global object + * and the global environment object for convenience. + */ + duk__duplicate_ram_global_object(thr); +#endif +} +#else /* DUK_USE_ROM_OBJECTS */ +DUK_LOCAL void duk__push_stridx(duk_hthread *thr, duk_bitdecoder_ctx *bd) { + duk_small_uint_t n; + + n = (duk_small_uint_t) duk_bd_decode_varuint(bd); + DUK_ASSERT_DISABLE(n >= 0); /* unsigned */ + DUK_ASSERT(n < DUK_HEAP_NUM_STRINGS); + duk_push_hstring_stridx(thr, n); +} +DUK_LOCAL void duk__push_string(duk_hthread *thr, duk_bitdecoder_ctx *bd) { + /* XXX: built-ins data could provide a maximum length that is + * actually needed; bitpacked max length is now 256 bytes. + */ + duk_uint8_t tmp[DUK_BD_BITPACKED_STRING_MAXLEN]; + duk_small_uint_t len; + + len = duk_bd_decode_bitpacked_string(bd, tmp); + duk_push_lstring(thr, (const char *) tmp, (duk_size_t) len); +} +DUK_LOCAL void duk__push_stridx_or_string(duk_hthread *thr, duk_bitdecoder_ctx *bd) { + duk_small_uint_t n; + + n = (duk_small_uint_t) duk_bd_decode_varuint(bd); + if (n == 0) { + duk__push_string(thr, bd); + } else { + n--; + DUK_ASSERT(n < DUK_HEAP_NUM_STRINGS); + duk_push_hstring_stridx(thr, n); + } +} +DUK_LOCAL void duk__push_double(duk_hthread *thr, duk_bitdecoder_ctx *bd) { + duk_double_union du; + duk_small_uint_t i; + + for (i = 0; i < 8; i++) { + /* Encoding endianness must match target memory layout, + * build scripts and genbuiltins.py must ensure this. + */ + du.uc[i] = (duk_uint8_t) duk_bd_decode(bd, 8); + } + + duk_push_number(thr, du.d); /* push operation normalizes NaNs */ +} + +DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) { + duk_bitdecoder_ctx bd_ctx; + duk_bitdecoder_ctx *bd = &bd_ctx; /* convenience */ + duk_hobject *h; + duk_small_uint_t i, j; + + DUK_D(DUK_DPRINT("INITBUILTINS BEGIN: DUK_NUM_BUILTINS=%d, DUK_NUM_BUILTINS_ALL=%d", (int) DUK_NUM_BUILTINS, (int) DUK_NUM_ALL_BUILTINS)); + + duk_memzero(&bd_ctx, sizeof(bd_ctx)); + bd->data = (const duk_uint8_t *) duk_builtins_data; + bd->length = (duk_size_t) DUK_BUILTINS_DATA_LENGTH; + + /* + * First create all built-in bare objects on the empty valstack. + * + * Built-ins in the index range [0,DUK_NUM_BUILTINS-1] have value + * stack indices matching their eventual thr->builtins[] index. + * + * Built-ins in the index range [DUK_NUM_BUILTINS,DUK_NUM_ALL_BUILTINS] + * will exist on the value stack during init but won't be placed + * into thr->builtins[]. These are objects referenced in some way + * from thr->builtins[] roots but which don't need to be indexed by + * Duktape through thr->builtins[] (e.g. user custom objects). + * + * Internal prototypes will be incorrect (NULL) at this stage. + */ + + duk_require_stack(thr, DUK_NUM_ALL_BUILTINS); + + DUK_DD(DUK_DDPRINT("create empty built-ins")); + DUK_ASSERT_TOP(thr, 0); + for (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) { + duk_small_uint_t class_num; + duk_small_int_t len = -1; /* must be signed */ + + class_num = (duk_small_uint_t) duk_bd_decode_varuint(bd); + len = (duk_small_int_t) duk_bd_decode_flagged_signed(bd, DUK__LENGTH_PROP_BITS, (duk_int32_t) -1 /*def_value*/); + + if (class_num == DUK_HOBJECT_CLASS_FUNCTION) { + duk_small_uint_t natidx; + duk_small_int_t c_nargs; /* must hold DUK_VARARGS */ + duk_c_function c_func; + duk_int16_t magic; + + DUK_DDD(DUK_DDDPRINT("len=%ld", (long) len)); + DUK_ASSERT(len >= 0); + + natidx = (duk_small_uint_t) duk_bd_decode_varuint(bd); + DUK_ASSERT(natidx != 0); + c_func = duk_bi_native_functions[natidx]; + DUK_ASSERT(c_func != NULL); + + c_nargs = (duk_small_int_t) duk_bd_decode_flagged_signed(bd, DUK__NARGS_BITS, len /*def_value*/); + if (c_nargs == DUK__NARGS_VARARGS_MARKER) { + c_nargs = DUK_VARARGS; + } + + /* XXX: set magic directly here? (it could share the c_nargs arg) */ + (void) duk_push_c_function_builtin(thr, c_func, c_nargs); + h = duk_known_hobject(thr, -1); + + /* Currently all built-in native functions are strict. + * duk_push_c_function() now sets strict flag, so + * assert for it. + */ + DUK_ASSERT(DUK_HOBJECT_HAS_STRICT(h)); + + /* XXX: function properties */ + + duk__push_stridx_or_string(thr, bd); +#if defined(DUK_USE_FUNC_NAME_PROPERTY) + duk_xdef_prop_stridx_short(thr, + -2, + DUK_STRIDX_NAME, + DUK_PROPDESC_FLAGS_C); +#else + duk_pop(thr); /* Not very ideal but good enough for now. */ +#endif + + /* Almost all global level Function objects are constructable + * but not all: Function.prototype is a non-constructable, + * callable Function. + */ + if (duk_bd_decode_flag(bd)) { + DUK_ASSERT(DUK_HOBJECT_HAS_CONSTRUCTABLE(h)); + } else { + DUK_HOBJECT_CLEAR_CONSTRUCTABLE(h); + } + + /* Cast converts magic to 16-bit signed value */ + magic = (duk_int16_t) duk_bd_decode_varuint(bd); + ((duk_hnatfunc *) h)->magic = magic; + } else if (class_num == DUK_HOBJECT_CLASS_ARRAY) { + duk_push_array(thr); + } else if (class_num == DUK_HOBJECT_CLASS_OBJENV) { + duk_hobjenv *env; + duk_hobject *global; + + DUK_ASSERT(i == DUK_BIDX_GLOBAL_ENV); + DUK_ASSERT(DUK_BIDX_GLOBAL_ENV > DUK_BIDX_GLOBAL); + + env = duk_hobjenv_alloc(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV)); + DUK_ASSERT(env->target == NULL); + duk_push_hobject(thr, (duk_hobject *) env); + + global = duk_known_hobject(thr, DUK_BIDX_GLOBAL); + DUK_ASSERT(global != NULL); + env->target = global; + DUK_HOBJECT_INCREF(thr, global); + DUK_ASSERT(env->has_this == 0); + + DUK_HOBJENV_ASSERT_VALID(env); + } else { + DUK_ASSERT(class_num != DUK_HOBJECT_CLASS_DECENV); + + (void) duk_push_object_helper(thr, + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_FLAG_EXTENSIBLE, + -1); /* no prototype or class yet */ + + } + + h = duk_known_hobject(thr, -1); + DUK_HOBJECT_SET_CLASS_NUMBER(h, class_num); + + if (i < DUK_NUM_BUILTINS) { + thr->builtins[i] = h; + DUK_HOBJECT_INCREF(thr, &h->hdr); + } + + if (len >= 0) { + /* In ES2015+ built-in function object .length property + * has property attributes C (configurable only): + * http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-standard-built-in-objects + * + * Array.prototype remains an Array instance in ES2015+ + * and its length has attributes W (writable only). + * Because .length is now virtual for duk_harray, it is + * not encoded explicitly in init data. + */ + + DUK_ASSERT(class_num != DUK_HOBJECT_CLASS_ARRAY); /* .length is virtual */ + duk_push_int(thr, len); + duk_xdef_prop_stridx_short(thr, + -2, + DUK_STRIDX_LENGTH, + DUK_PROPDESC_FLAGS_C); + } + + /* enable exotic behaviors last */ + + if (class_num == DUK_HOBJECT_CLASS_ARRAY) { + DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)); /* set by duk_push_array() */ + } + if (class_num == DUK_HOBJECT_CLASS_STRING) { + DUK_HOBJECT_SET_EXOTIC_STRINGOBJ(h); + } + + /* some assertions */ + + DUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h)); + /* DUK_HOBJECT_FLAG_CONSTRUCTABLE varies */ + DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(h)); + DUK_ASSERT(!DUK_HOBJECT_HAS_COMPFUNC(h)); + /* DUK_HOBJECT_FLAG_NATFUNC varies */ + DUK_ASSERT(!DUK_HOBJECT_IS_THREAD(h)); + DUK_ASSERT(!DUK_HOBJECT_IS_PROXY(h)); + DUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(h) || class_num == DUK_HOBJECT_CLASS_ARRAY); + /* DUK_HOBJECT_FLAG_STRICT varies */ + DUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(h) || /* all native functions have NEWENV */ + DUK_HOBJECT_HAS_NEWENV(h)); + DUK_ASSERT(!DUK_HOBJECT_HAS_NAMEBINDING(h)); + DUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(h)); + /* DUK_HOBJECT_FLAG_EXOTIC_ARRAY varies */ + /* DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ varies */ + DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h)); + + DUK_DDD(DUK_DDDPRINT("created built-in %ld, class=%ld, length=%ld", (long) i, (long) class_num, (long) len)); + } + + /* + * Then decode the builtins init data (see genbuiltins.py) to + * init objects. Internal prototypes are set at this stage, + * with thr->builtins[] populated. + */ + + DUK_DD(DUK_DDPRINT("initialize built-in object properties")); + for (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) { + duk_small_uint_t t; + duk_small_uint_t num; + + DUK_DDD(DUK_DDDPRINT("initializing built-in object at index %ld", (long) i)); + h = duk_known_hobject(thr, (duk_idx_t) i); + + t = (duk_small_uint_t) duk_bd_decode_varuint(bd); + if (t > 0) { + t--; + DUK_DDD(DUK_DDDPRINT("set internal prototype: built-in %ld", (long) t)); + DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, duk_known_hobject(thr, (duk_idx_t) t)); + } else if (DUK_HOBJECT_IS_NATFUNC(h)) { + /* Standard native built-ins cannot inherit from + * %NativeFunctionPrototype%, they are required to + * inherit from Function.prototype directly. + */ + DUK_ASSERT(thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE] != NULL); + DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]); + } + + t = (duk_small_uint_t) duk_bd_decode_varuint(bd); + if (t > 0) { + /* 'prototype' property for all built-in objects (which have it) has attributes: + * [[Writable]] = false, + * [[Enumerable]] = false, + * [[Configurable]] = false + */ + t--; + DUK_DDD(DUK_DDDPRINT("set external prototype: built-in %ld", (long) t)); + duk_dup(thr, (duk_idx_t) t); + duk_xdef_prop_stridx(thr, (duk_idx_t) i, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_NONE); + } + + t = (duk_small_uint_t) duk_bd_decode_varuint(bd); + if (t > 0) { + /* 'constructor' property for all built-in objects (which have it) has attributes: + * [[Writable]] = true, + * [[Enumerable]] = false, + * [[Configurable]] = true + */ + t--; + DUK_DDD(DUK_DDDPRINT("set external constructor: built-in %ld", (long) t)); + duk_dup(thr, (duk_idx_t) t); + duk_xdef_prop_stridx(thr, (duk_idx_t) i, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC); + } + + /* normal valued properties */ + num = (duk_small_uint_t) duk_bd_decode_varuint(bd); + DUK_DDD(DUK_DDDPRINT("built-in object %ld, %ld normal valued properties", (long) i, (long) num)); + for (j = 0; j < num; j++) { + duk_small_uint_t defprop_flags; + + duk__push_stridx_or_string(thr, bd); + + /* + * Property attribute defaults are defined in E5 Section 15 (first + * few pages); there is a default for all properties and a special + * default for 'length' properties. Variation from the defaults is + * signaled using a single flag bit in the bitstream. + */ + + defprop_flags = (duk_small_uint_t) duk_bd_decode_flagged(bd, + DUK__PROP_FLAGS_BITS, + (duk_uint32_t) DUK_PROPDESC_FLAGS_WC); + defprop_flags |= DUK_DEFPROP_FORCE | + DUK_DEFPROP_HAVE_VALUE | + DUK_DEFPROP_HAVE_WRITABLE | + DUK_DEFPROP_HAVE_ENUMERABLE | + DUK_DEFPROP_HAVE_CONFIGURABLE; /* Defaults for data properties. */ + + /* The writable, enumerable, configurable flags in prop_flags + * match both duk_def_prop() and internal property flags. + */ + DUK_ASSERT(DUK_PROPDESC_FLAG_WRITABLE == DUK_DEFPROP_WRITABLE); + DUK_ASSERT(DUK_PROPDESC_FLAG_ENUMERABLE == DUK_DEFPROP_ENUMERABLE); + DUK_ASSERT(DUK_PROPDESC_FLAG_CONFIGURABLE == DUK_DEFPROP_CONFIGURABLE); + + t = (duk_small_uint_t) duk_bd_decode(bd, DUK__PROP_TYPE_BITS); + + DUK_DDD(DUK_DDDPRINT("built-in %ld, normal-valued property %ld, key %!T, flags 0x%02lx, type %ld", + (long) i, (long) j, duk_get_tval(thr, -1), (unsigned long) defprop_flags, (long) t)); + + switch (t) { + case DUK__PROP_TYPE_DOUBLE: { + duk__push_double(thr, bd); + break; + } + case DUK__PROP_TYPE_STRING: { + duk__push_string(thr, bd); + break; + } + case DUK__PROP_TYPE_STRIDX: { + duk__push_stridx(thr, bd); + break; + } + case DUK__PROP_TYPE_BUILTIN: { + duk_small_uint_t bidx; + + bidx = (duk_small_uint_t) duk_bd_decode_varuint(bd); + duk_dup(thr, (duk_idx_t) bidx); + break; + } + case DUK__PROP_TYPE_UNDEFINED: { + duk_push_undefined(thr); + break; + } + case DUK__PROP_TYPE_BOOLEAN_TRUE: { + duk_push_true(thr); + break; + } + case DUK__PROP_TYPE_BOOLEAN_FALSE: { + duk_push_false(thr); + break; + } + case DUK__PROP_TYPE_ACCESSOR: { + duk_small_uint_t natidx_getter = (duk_small_uint_t) duk_bd_decode_varuint(bd); + duk_small_uint_t natidx_setter = (duk_small_uint_t) duk_bd_decode_varuint(bd); + duk_small_uint_t accessor_magic = (duk_small_uint_t) duk_bd_decode_varuint(bd); + duk_c_function c_func_getter; + duk_c_function c_func_setter; + + DUK_DDD(DUK_DDDPRINT("built-in accessor property: objidx=%ld, key=%!T, getteridx=%ld, setteridx=%ld, flags=0x%04lx", + (long) i, duk_get_tval(thr, -1), (long) natidx_getter, (long) natidx_setter, (unsigned long) defprop_flags)); + + c_func_getter = duk_bi_native_functions[natidx_getter]; + if (c_func_getter != NULL) { + duk_push_c_function_builtin_noconstruct(thr, c_func_getter, 0); /* always 0 args */ + duk_set_magic(thr, -1, (duk_int_t) accessor_magic); + defprop_flags |= DUK_DEFPROP_HAVE_GETTER; + } + c_func_setter = duk_bi_native_functions[natidx_setter]; + if (c_func_setter != NULL) { + duk_push_c_function_builtin_noconstruct(thr, c_func_setter, 1); /* always 1 arg */ + duk_set_magic(thr, -1, (duk_int_t) accessor_magic); + defprop_flags |= DUK_DEFPROP_HAVE_SETTER; + } + + /* Writable flag doesn't make sense for an accessor. */ + DUK_ASSERT((defprop_flags & DUK_PROPDESC_FLAG_WRITABLE) == 0); /* genbuiltins.py ensures */ + + defprop_flags &= ~(DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE); + defprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE; + break; + } + default: { + /* exhaustive */ + DUK_UNREACHABLE(); + } + } + + duk_def_prop(thr, (duk_idx_t) i, defprop_flags); + DUK_ASSERT_TOP(thr, DUK_NUM_ALL_BUILTINS); + } + + /* native function properties */ + num = (duk_small_uint_t) duk_bd_decode_varuint(bd); + DUK_DDD(DUK_DDDPRINT("built-in object %ld, %ld function valued properties", (long) i, (long) num)); + for (j = 0; j < num; j++) { + duk_hstring *h_key; + duk_small_uint_t natidx; + duk_int_t c_nargs; /* must hold DUK_VARARGS */ + duk_small_uint_t c_length; + duk_int16_t magic; + duk_c_function c_func; + duk_hnatfunc *h_func; +#if defined(DUK_USE_LIGHTFUNC_BUILTINS) + duk_small_int_t lightfunc_eligible; +#endif + duk_small_uint_t defprop_flags; + + duk__push_stridx_or_string(thr, bd); + h_key = duk_known_hstring(thr, -1); + DUK_UNREF(h_key); + natidx = (duk_small_uint_t) duk_bd_decode_varuint(bd); + + c_length = (duk_small_uint_t) duk_bd_decode(bd, DUK__LENGTH_PROP_BITS); + c_nargs = (duk_int_t) duk_bd_decode_flagged(bd, DUK__NARGS_BITS, (duk_uint32_t) c_length /*def_value*/); + if (c_nargs == DUK__NARGS_VARARGS_MARKER) { + c_nargs = DUK_VARARGS; + } + + c_func = duk_bi_native_functions[natidx]; + + DUK_DDD(DUK_DDDPRINT("built-in %ld, function-valued property %ld, key %!O, natidx %ld, length %ld, nargs %ld", + (long) i, (long) j, (duk_heaphdr *) h_key, (long) natidx, (long) c_length, + (c_nargs == DUK_VARARGS ? (long) -1 : (long) c_nargs))); + + /* Cast converts magic to 16-bit signed value */ + magic = (duk_int16_t) duk_bd_decode_varuint(bd); + +#if defined(DUK_USE_LIGHTFUNC_BUILTINS) + lightfunc_eligible = + ((c_nargs >= DUK_LFUNC_NARGS_MIN && c_nargs <= DUK_LFUNC_NARGS_MAX) || (c_nargs == DUK_VARARGS)) && + (c_length <= DUK_LFUNC_LENGTH_MAX) && + (magic >= DUK_LFUNC_MAGIC_MIN && magic <= DUK_LFUNC_MAGIC_MAX); + + /* These functions have trouble working as lightfuncs. + * Some of them have specific asserts and some may have + * additional properties (e.g. 'require.id' may be written). + */ + if (c_func == duk_bi_global_object_eval) { + lightfunc_eligible = 0; + } +#if defined(DUK_USE_COROUTINE_SUPPORT) + if (c_func == duk_bi_thread_yield || + c_func == duk_bi_thread_resume) { + lightfunc_eligible = 0; + } +#endif + if (c_func == duk_bi_function_prototype_call || + c_func == duk_bi_function_prototype_apply || + c_func == duk_bi_reflect_apply || + c_func == duk_bi_reflect_construct) { + lightfunc_eligible = 0; + } + + if (lightfunc_eligible) { + duk_tval tv_lfunc; + duk_small_uint_t lf_nargs = (duk_small_uint_t) (c_nargs == DUK_VARARGS ? DUK_LFUNC_NARGS_VARARGS : c_nargs); + duk_small_uint_t lf_flags = DUK_LFUNC_FLAGS_PACK(magic, c_length, lf_nargs); + DUK_TVAL_SET_LIGHTFUNC(&tv_lfunc, c_func, lf_flags); + duk_push_tval(thr, &tv_lfunc); + DUK_D(DUK_DPRINT("built-in function eligible as light function: i=%d, j=%d c_length=%ld, c_nargs=%ld, magic=%ld -> %!iT", (int) i, (int) j, (long) c_length, (long) c_nargs, (long) magic, duk_get_tval(thr, -1))); + goto lightfunc_skip; + } + + DUK_D(DUK_DPRINT("built-in function NOT ELIGIBLE as light function: i=%d, j=%d c_length=%ld, c_nargs=%ld, magic=%ld", (int) i, (int) j, (long) c_length, (long) c_nargs, (long) magic)); +#endif /* DUK_USE_LIGHTFUNC_BUILTINS */ + + /* [ (builtin objects) name ] */ + + duk_push_c_function_builtin_noconstruct(thr, c_func, c_nargs); + h_func = duk_known_hnatfunc(thr, -1); + DUK_UNREF(h_func); + + /* XXX: add into init data? */ + + /* Special call handling, not described in init data. */ + if (c_func == duk_bi_global_object_eval || + c_func == duk_bi_function_prototype_call || + c_func == duk_bi_function_prototype_apply || + c_func == duk_bi_reflect_apply || + c_func == duk_bi_reflect_construct) { + DUK_HOBJECT_SET_SPECIAL_CALL((duk_hobject *) h_func); + } + + /* Currently all built-in native functions are strict. + * This doesn't matter for many functions, but e.g. + * String.prototype.charAt (and other string functions) + * rely on being strict so that their 'this' binding is + * not automatically coerced. + */ + DUK_HOBJECT_SET_STRICT((duk_hobject *) h_func); + + /* No built-in functions are constructable except the top + * level ones (Number, etc). + */ + DUK_ASSERT(!DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) h_func)); + + /* XXX: any way to avoid decoding magic bit; there are quite + * many function properties and relatively few with magic values. + */ + h_func->magic = magic; + + /* [ (builtin objects) name func ] */ + + duk_push_uint(thr, c_length); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C); + + duk_dup_m2(thr); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C); + + /* XXX: other properties of function instances; 'arguments', 'caller'. */ + + DUK_DD(DUK_DDPRINT("built-in object %ld, function property %ld -> %!T", + (long) i, (long) j, (duk_tval *) duk_get_tval(thr, -1))); + + /* [ (builtin objects) name func ] */ + + /* + * The default property attributes are correct for all + * function valued properties of built-in objects now. + */ + +#if defined(DUK_USE_LIGHTFUNC_BUILTINS) + lightfunc_skip: +#endif + + defprop_flags = (duk_small_uint_t) duk_bd_decode_flagged(bd, + DUK__PROP_FLAGS_BITS, + (duk_uint32_t) DUK_PROPDESC_FLAGS_WC); + defprop_flags |= DUK_DEFPROP_FORCE | + DUK_DEFPROP_HAVE_VALUE | + DUK_DEFPROP_HAVE_WRITABLE | + DUK_DEFPROP_HAVE_ENUMERABLE | + DUK_DEFPROP_HAVE_CONFIGURABLE; + DUK_ASSERT(DUK_PROPDESC_FLAG_WRITABLE == DUK_DEFPROP_WRITABLE); + DUK_ASSERT(DUK_PROPDESC_FLAG_ENUMERABLE == DUK_DEFPROP_ENUMERABLE); + DUK_ASSERT(DUK_PROPDESC_FLAG_CONFIGURABLE == DUK_DEFPROP_CONFIGURABLE); + + duk_def_prop(thr, (duk_idx_t) i, defprop_flags); + + /* [ (builtin objects) ] */ + } + } + + /* + * Special post-tweaks, for cases not covered by the init data format. + * + * - Set Date.prototype.toGMTString to Date.prototype.toUTCString. + * toGMTString is required to have the same Function object as + * toUTCString in E5 Section B.2.6. Note that while Smjs respects + * this, V8 does not (the Function objects are distinct). + * + * - Make DoubleError non-extensible. + * + * - Add info about most important effective compile options to Duktape. + * + * - Possibly remove some properties (values or methods) which are not + * desirable with current feature options but are not currently + * conditional in init data. + */ + +#if defined(DUK_USE_DATE_BUILTIN) + duk_get_prop_stridx_short(thr, DUK_BIDX_DATE_PROTOTYPE, DUK_STRIDX_TO_UTC_STRING); + duk_xdef_prop_stridx_short(thr, DUK_BIDX_DATE_PROTOTYPE, DUK_STRIDX_TO_GMT_STRING, DUK_PROPDESC_FLAGS_WC); +#endif + + h = duk_known_hobject(thr, DUK_BIDX_DOUBLE_ERROR); + DUK_HOBJECT_CLEAR_EXTENSIBLE(h); + +#if !defined(DUK_USE_ES6_OBJECT_PROTO_PROPERTY) + DUK_DD(DUK_DDPRINT("delete Object.prototype.__proto__ built-in which is not enabled in features")); + (void) duk_hobject_delprop_raw(thr, thr->builtins[DUK_BIDX_OBJECT_PROTOTYPE], DUK_HTHREAD_STRING___PROTO__(thr), DUK_DELPROP_FLAG_THROW); +#endif + +#if !defined(DUK_USE_ES6_OBJECT_SETPROTOTYPEOF) + DUK_DD(DUK_DDPRINT("delete Object.setPrototypeOf built-in which is not enabled in features")); + (void) duk_hobject_delprop_raw(thr, thr->builtins[DUK_BIDX_OBJECT_CONSTRUCTOR], DUK_HTHREAD_STRING_SET_PROTOTYPE_OF(thr), DUK_DELPROP_FLAG_THROW); +#endif + + /* XXX: relocate */ + duk_push_string(thr, + /* Endianness indicator */ +#if defined(DUK_USE_INTEGER_LE) + "l" +#elif defined(DUK_USE_INTEGER_BE) + "b" +#elif defined(DUK_USE_INTEGER_ME) /* integer mixed endian not really used now */ + "m" +#else + "?" +#endif +#if defined(DUK_USE_DOUBLE_LE) + "l" +#elif defined(DUK_USE_DOUBLE_BE) + "b" +#elif defined(DUK_USE_DOUBLE_ME) + "m" +#else + "?" +#endif + " " + /* Packed or unpacked tval */ +#if defined(DUK_USE_PACKED_TVAL) + "p" +#else + "u" +#endif +#if defined(DUK_USE_FASTINT) + "f" +#endif + " " + /* Low memory/performance options */ +#if defined(DUK_USE_STRTAB_PTRCOMP) + "s" +#endif +#if !defined(DUK_USE_HEAPPTR16) && !defined(DUK_DATAPTR16) && !defined(DUK_FUNCPTR16) + "n" +#endif +#if defined(DUK_USE_HEAPPTR16) + "h" +#endif +#if defined(DUK_USE_DATAPTR16) + "d" +#endif +#if defined(DUK_USE_FUNCPTR16) + "f" +#endif +#if defined(DUK_USE_REFCOUNT16) + "R" +#endif +#if defined(DUK_USE_STRHASH16) + "H" +#endif +#if defined(DUK_USE_STRLEN16) + "S" +#endif +#if defined(DUK_USE_BUFLEN16) + "B" +#endif +#if defined(DUK_USE_OBJSIZES16) + "O" +#endif +#if defined(DUK_USE_LIGHTFUNC_BUILTINS) + "L" +#endif +#if defined(DUK_USE_ROM_STRINGS) || defined(DUK_USE_ROM_OBJECTS) + /* XXX: This won't be shown in practice now + * because this code is not run when builtins + * are in ROM. + */ + "Z" +#endif +#if defined(DUK_USE_LITCACHE_SIZE) + "l" +#endif + " " + /* Object property allocation layout */ +#if defined(DUK_USE_HOBJECT_LAYOUT_1) + "p1" +#elif defined(DUK_USE_HOBJECT_LAYOUT_2) + "p2" +#elif defined(DUK_USE_HOBJECT_LAYOUT_3) + "p3" +#else + "p?" +#endif + " " + /* Alignment guarantee */ +#if (DUK_USE_ALIGN_BY == 4) + "a4" +#elif (DUK_USE_ALIGN_BY == 8) + "a8" +#elif (DUK_USE_ALIGN_BY == 1) + "a1" +#else +#error invalid DUK_USE_ALIGN_BY +#endif + " " + /* Architecture, OS, and compiler strings */ + DUK_USE_ARCH_STRING + " " + DUK_USE_OS_STRING + " " + DUK_USE_COMPILER_STRING); + duk_xdef_prop_stridx_short(thr, DUK_BIDX_DUKTAPE, DUK_STRIDX_ENV, DUK_PROPDESC_FLAGS_WC); + + /* + * Since built-ins are not often extended, compact them. + */ + + DUK_DD(DUK_DDPRINT("compact built-ins")); + for (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) { + duk_hobject_compact_props(thr, duk_known_hobject(thr, (duk_idx_t) i)); + } + + DUK_D(DUK_DPRINT("INITBUILTINS END")); + +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1) + for (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) { + DUK_DD(DUK_DDPRINT("built-in object %ld after initialization and compacting: %!@iO", + (long) i, (duk_heaphdr *) duk_require_hobject(thr, (duk_idx_t) i))); + } +#endif + + /* + * Pop built-ins from stack: they are now INCREF'd and + * reachable from the builtins[] array or indirectly + * through builtins[]. + */ + + duk_set_top(thr, 0); + DUK_ASSERT_TOP(thr, 0); +} +#endif /* DUK_USE_ROM_OBJECTS */ + +DUK_INTERNAL void duk_hthread_copy_builtin_objects(duk_hthread *thr_from, duk_hthread *thr_to) { + duk_small_uint_t i; + + for (i = 0; i < DUK_NUM_BUILTINS; i++) { + thr_to->builtins[i] = thr_from->builtins[i]; + DUK_HOBJECT_INCREF_ALLOWNULL(thr_to, thr_to->builtins[i]); /* side effect free */ + } +} diff --git a/third_party/duktape/duk_hthread_misc.c b/third_party/duktape/duk_hthread_misc.c new file mode 100644 index 00000000..f6e0f535 --- /dev/null +++ b/third_party/duktape/duk_hthread_misc.c @@ -0,0 +1,97 @@ +/* + * Thread support. + */ + +#include "third_party/duktape/duk_internal.h" + +DUK_INTERNAL void duk_hthread_terminate(duk_hthread *thr) { + DUK_ASSERT(thr != NULL); + + while (thr->callstack_curr != NULL) { + duk_hthread_activation_unwind_norz(thr); + } + + thr->valstack_bottom = thr->valstack; + duk_set_top(thr, 0); /* unwinds valstack, updating refcounts */ + + thr->state = DUK_HTHREAD_STATE_TERMINATED; + + /* Here we could remove references to built-ins, but it may not be + * worth the effort because built-ins are quite likely to be shared + * with another (unterminated) thread, and terminated threads are also + * usually garbage collected quite quickly. + * + * We could also shrink the value stack here, but that also may not + * be worth the effort for the same reason. + */ + + DUK_REFZERO_CHECK_SLOW(thr); +} + +#if defined(DUK_USE_DEBUGGER_SUPPORT) +DUK_INTERNAL duk_uint_fast32_t duk_hthread_get_act_curr_pc(duk_hthread *thr, duk_activation *act) { + duk_instr_t *bcode; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(act != NULL); + DUK_UNREF(thr); + + /* XXX: store 'bcode' pointer to activation for faster lookup? */ + if (act->func && DUK_HOBJECT_IS_COMPFUNC(act->func)) { + bcode = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) (act->func)); + return (duk_uint_fast32_t) (act->curr_pc - bcode); + } + return 0; +} +#endif /* DUK_USE_DEBUGGER_SUPPORT */ + +DUK_INTERNAL duk_uint_fast32_t duk_hthread_get_act_prev_pc(duk_hthread *thr, duk_activation *act) { + duk_instr_t *bcode; + duk_uint_fast32_t ret; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(act != NULL); + DUK_UNREF(thr); + + if (act->func && DUK_HOBJECT_IS_COMPFUNC(act->func)) { + bcode = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) (act->func)); + ret = (duk_uint_fast32_t) (act->curr_pc - bcode); + if (ret > 0) { + ret--; + } + return ret; + } + return 0; +} + +/* Write bytecode executor's curr_pc back to topmost activation (if any). */ +DUK_INTERNAL void duk_hthread_sync_currpc(duk_hthread *thr) { + duk_activation *act; + + DUK_ASSERT(thr != NULL); + + if (thr->ptr_curr_pc != NULL) { + /* ptr_curr_pc != NULL only when bytecode executor is active. */ + DUK_ASSERT(thr->callstack_top > 0); + DUK_ASSERT(thr->callstack_curr != NULL); + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + act->curr_pc = *thr->ptr_curr_pc; + } +} + +DUK_INTERNAL void duk_hthread_sync_and_null_currpc(duk_hthread *thr) { + duk_activation *act; + + DUK_ASSERT(thr != NULL); + + if (thr->ptr_curr_pc != NULL) { + /* ptr_curr_pc != NULL only when bytecode executor is active. */ + DUK_ASSERT(thr->callstack_top > 0); + DUK_ASSERT(thr->callstack_curr != NULL); + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + act->curr_pc = *thr->ptr_curr_pc; + thr->ptr_curr_pc = NULL; + } +} diff --git a/third_party/duktape/duk_hthread_stacks.c b/third_party/duktape/duk_hthread_stacks.c new file mode 100644 index 00000000..17e38fc0 --- /dev/null +++ b/third_party/duktape/duk_hthread_stacks.c @@ -0,0 +1,407 @@ +/* + * Thread stack (mainly call stack) primitives: allocation of activations, + * unwinding catchers and activations, etc. + * + * Value stack handling is a part of the API implementation. + */ + +#include "third_party/duktape/duk_internal.h" + +/* Unwind the topmost catcher of the current activation (caller must check that + * both exist) without side effects. + */ +DUK_INTERNAL void duk_hthread_catcher_unwind_norz(duk_hthread *thr, duk_activation *act) { + duk_catcher *cat; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(act != NULL); + DUK_ASSERT(act->cat != NULL); /* caller must check */ + cat = act->cat; + DUK_ASSERT(cat != NULL); + + DUK_DDD(DUK_DDDPRINT("unwinding catch stack entry %p (lexenv check is done)", (void *) cat)); + + if (DUK_CAT_HAS_LEXENV_ACTIVE(cat)) { + duk_hobject *env; + + env = act->lex_env; /* current lex_env of the activation (created for catcher) */ + DUK_ASSERT(env != NULL); /* must be, since env was created when catcher was created */ + act->lex_env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, env); /* prototype is lex_env before catcher created */ + DUK_HOBJECT_INCREF(thr, act->lex_env); + DUK_HOBJECT_DECREF_NORZ(thr, env); + + /* There is no need to decref anything else than 'env': if 'env' + * becomes unreachable, refzero will handle decref'ing its prototype. + */ + } + + act->cat = cat->parent; + duk_hthread_catcher_free(thr, cat); +} + +/* Same as above, but caller is certain no catcher-related lexenv may exist. */ +DUK_INTERNAL void duk_hthread_catcher_unwind_nolexenv_norz(duk_hthread *thr, duk_activation *act) { + duk_catcher *cat; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(act != NULL); + DUK_ASSERT(act->cat != NULL); /* caller must check */ + cat = act->cat; + DUK_ASSERT(cat != NULL); + + DUK_DDD(DUK_DDDPRINT("unwinding catch stack entry %p (lexenv check is not done)", (void *) cat)); + + DUK_ASSERT(!DUK_CAT_HAS_LEXENV_ACTIVE(cat)); + + act->cat = cat->parent; + duk_hthread_catcher_free(thr, cat); +} + +DUK_LOCAL +#if defined(DUK_USE_CACHE_CATCHER) +DUK_NOINLINE +#endif +duk_catcher *duk__hthread_catcher_alloc_slow(duk_hthread *thr) { + duk_catcher *cat; + + cat = (duk_catcher *) DUK_ALLOC_CHECKED(thr, sizeof(duk_catcher)); + DUK_ASSERT(cat != NULL); + return cat; +} + +#if defined(DUK_USE_CACHE_CATCHER) +DUK_INTERNAL DUK_INLINE duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr) { + duk_catcher *cat; + + DUK_ASSERT(thr != NULL); + + cat = thr->heap->catcher_free; + if (DUK_LIKELY(cat != NULL)) { + thr->heap->catcher_free = cat->parent; + return cat; + } + + return duk__hthread_catcher_alloc_slow(thr); +} +#else /* DUK_USE_CACHE_CATCHER */ +DUK_INTERNAL duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr) { + return duk__hthread_catcher_alloc_slow(thr); +} +#endif /* DUK_USE_CACHE_CATCHER */ + +DUK_INTERNAL void duk_hthread_catcher_free(duk_hthread *thr, duk_catcher *cat) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(cat != NULL); + +#if defined(DUK_USE_CACHE_CATCHER) + /* Unconditional caching for now; freed in mark-and-sweep. */ + cat->parent = thr->heap->catcher_free; + thr->heap->catcher_free = cat; +#else + DUK_FREE_CHECKED(thr, (void *) cat); +#endif +} + +DUK_LOCAL +#if defined(DUK_USE_CACHE_ACTIVATION) +DUK_NOINLINE +#endif +duk_activation *duk__hthread_activation_alloc_slow(duk_hthread *thr) { + duk_activation *act; + + act = (duk_activation *) DUK_ALLOC_CHECKED(thr, sizeof(duk_activation)); + DUK_ASSERT(act != NULL); + return act; +} + +#if defined(DUK_USE_CACHE_ACTIVATION) +DUK_INTERNAL DUK_INLINE duk_activation *duk_hthread_activation_alloc(duk_hthread *thr) { + duk_activation *act; + + DUK_ASSERT(thr != NULL); + + act = thr->heap->activation_free; + if (DUK_LIKELY(act != NULL)) { + thr->heap->activation_free = act->parent; + return act; + } + + return duk__hthread_activation_alloc_slow(thr); +} +#else /* DUK_USE_CACHE_ACTIVATION */ +DUK_INTERNAL duk_activation *duk_hthread_activation_alloc(duk_hthread *thr) { + return duk__hthread_activation_alloc_slow(thr); +} +#endif /* DUK_USE_CACHE_ACTIVATION */ + + +DUK_INTERNAL void duk_hthread_activation_free(duk_hthread *thr, duk_activation *act) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(act != NULL); + +#if defined(DUK_USE_CACHE_ACTIVATION) + /* Unconditional caching for now; freed in mark-and-sweep. */ + act->parent = thr->heap->activation_free; + thr->heap->activation_free = act; +#else + DUK_FREE_CHECKED(thr, (void *) act); +#endif +} + +/* Internal helper: process the unwind for the topmost activation of a thread, + * but leave the duk_activation in place for possible tailcall reuse. + */ +DUK_LOCAL void duk__activation_unwind_nofree_norz(duk_hthread *thr) { +#if defined(DUK_USE_DEBUGGER_SUPPORT) + duk_heap *heap; +#endif + duk_activation *act; + duk_hobject *func; + duk_hobject *tmp; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->callstack_curr != NULL); /* caller must check */ + DUK_ASSERT(thr->callstack_top > 0); + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + /* With lightfuncs, act 'func' may be NULL. */ + + /* With duk_activation records allocated separately, 'act' is a stable + * pointer and not affected by side effects. + */ + +#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY) + /* + * Restore 'caller' property for non-strict callee functions. + */ + + func = DUK_ACT_GET_FUNC(act); + if (func != NULL && !DUK_HOBJECT_HAS_STRICT(func)) { + duk_tval *tv_caller; + duk_tval tv_tmp; + duk_hobject *h_tmp; + + tv_caller = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, func, DUK_STRIDX_CALLER); + + /* The act->prev_caller should only be set if the entry for 'caller' + * exists (as it is only set in that case, and the property is not + * configurable), but handle all the cases anyway. + */ + + if (tv_caller) { + DUK_TVAL_SET_TVAL(&tv_tmp, tv_caller); + if (act->prev_caller) { + /* Just transfer the refcount from act->prev_caller to tv_caller, + * so no need for a refcount update. This is the expected case. + */ + DUK_TVAL_SET_OBJECT(tv_caller, act->prev_caller); + act->prev_caller = NULL; + } else { + DUK_TVAL_SET_NULL(tv_caller); /* no incref needed */ + DUK_ASSERT(act->prev_caller == NULL); + } + DUK_TVAL_DECREF_NORZ(thr, &tv_tmp); + } else { + h_tmp = act->prev_caller; + if (h_tmp) { + act->prev_caller = NULL; + DUK_HOBJECT_DECREF_NORZ(thr, h_tmp); + } + } + DUK_ASSERT(act->prev_caller == NULL); + } +#endif + + /* + * Unwind debugger state. If we unwind while stepping + * (for any step type), pause execution. This is the + * only place explicitly handling a step out. + */ + +#if defined(DUK_USE_DEBUGGER_SUPPORT) + heap = thr->heap; + if (heap->dbg_pause_act == thr->callstack_curr) { + if (heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_EXIT) { + DUK_D(DUK_DPRINT("PAUSE TRIGGERED by function exit")); + duk_debug_set_paused(heap); + } else { + DUK_D(DUK_DPRINT("unwound past dbg_pause_act, set to NULL")); + heap->dbg_pause_act = NULL; /* avoid stale pointers */ + } + DUK_ASSERT(heap->dbg_pause_act == NULL); + } +#endif + + /* + * Unwind catchers. + * + * Since there are no references in the catcher structure, + * unwinding is quite simple. The only thing we need to + * look out for is popping a possible lexical environment + * established for an active catch clause. + */ + + while (act->cat != NULL) { + duk_hthread_catcher_unwind_norz(thr, act); + } + + /* + * Close environment record(s) if they exist. + * + * Only variable environments are closed. If lex_env != var_env, it + * cannot currently contain any register bound declarations. + * + * Only environments created for a NEWENV function are closed. If an + * environment is created for e.g. an eval call, it must not be closed. + */ + + func = DUK_ACT_GET_FUNC(act); + if (func != NULL && !DUK_HOBJECT_HAS_NEWENV(func)) { + DUK_DDD(DUK_DDDPRINT("skip closing environments, envs not owned by this activation")); + goto skip_env_close; + } + /* func is NULL for lightfunc */ + + /* Catch sites are required to clean up their environments + * in FINALLY part before propagating, so this should + * always hold here. + */ + DUK_ASSERT(act->lex_env == act->var_env); + + /* XXX: Closing the environment record copies values from registers + * into the scope object. It's side effect free as such, but may + * currently run out of memory which causes an error throw. This is + * an actual sandboxing problem for error unwinds, and needs to be + * fixed e.g. by preallocating the scope property slots. + */ + if (act->var_env != NULL) { + DUK_DDD(DUK_DDDPRINT("closing var_env record %p -> %!O", + (void *) act->var_env, (duk_heaphdr *) act->var_env)); + duk_js_close_environment_record(thr, act->var_env); + } + + skip_env_close: + + /* + * Update preventcount + */ + + if (act->flags & DUK_ACT_FLAG_PREVENT_YIELD) { + DUK_ASSERT(thr->callstack_preventcount >= 1); + thr->callstack_preventcount--; + } + + /* + * Reference count updates, using NORZ macros so we don't + * need to handle side effects. + * + * duk_activation pointers like act->var_env are intentionally + * left as garbage and not NULLed. Without side effects they + * can't be used when the values are dangling/garbage. + */ + + DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, act->var_env); + DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, act->lex_env); + tmp = DUK_ACT_GET_FUNC(act); + DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp); + DUK_UNREF(tmp); +} + +/* Unwind topmost duk_activation of a thread, caller must ensure that an + * activation exists. The call is side effect free, except that scope + * closure may currently throw an out-of-memory error. + */ +DUK_INTERNAL void duk_hthread_activation_unwind_norz(duk_hthread *thr) { + duk_activation *act; + + duk__activation_unwind_nofree_norz(thr); + + DUK_ASSERT(thr->callstack_curr != NULL); + DUK_ASSERT(thr->callstack_top > 0); + act = thr->callstack_curr; + thr->callstack_curr = act->parent; + thr->callstack_top--; + + /* Ideally we'd restore value stack reserve here to caller's value. + * This doesn't work for current unwind call sites however, because + * the current (unwound) value stack top may be above the reserve. + * Thus value stack reserve is restored by the call sites. + */ + + /* XXX: inline for performance builds? */ + duk_hthread_activation_free(thr, act); + + /* We could clear the book-keeping variables like retval_byteoff for + * the topmost activation, but don't do so now as it's not necessary. + */ +} + +DUK_INTERNAL void duk_hthread_activation_unwind_reuse_norz(duk_hthread *thr) { + duk__activation_unwind_nofree_norz(thr); +} + +/* Get duk_activation for given callstack level or NULL if level is invalid + * or deeper than the call stack. Level -1 refers to current activation, -2 + * to its caller, etc. Starting from Duktape 2.2 finding the activation is + * a linked list scan which gets more expensive the deeper the lookup is. + */ +DUK_INTERNAL duk_activation *duk_hthread_get_activation_for_level(duk_hthread *thr, duk_int_t level) { + duk_activation *act; + + if (level >= 0) { + return NULL; + } + act = thr->callstack_curr; + for (;;) { + if (act == NULL) { + return act; + } + if (level == -1) { + return act; + } + level++; + act = act->parent; + } + /* never here */ +} + +#if defined(DUK_USE_FINALIZER_TORTURE) +DUK_INTERNAL void duk_hthread_valstack_torture_realloc(duk_hthread *thr) { + duk_size_t alloc_size; + duk_tval *new_ptr; + duk_ptrdiff_t alloc_end_off; + duk_ptrdiff_t end_off; + duk_ptrdiff_t bottom_off; + duk_ptrdiff_t top_off; + + if (thr->valstack == NULL) { + DUK_D(DUK_DPRINT("skip valstack torture realloc, valstack is NULL")); + return; + } + + alloc_end_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_alloc_end - (duk_uint8_t *) thr->valstack); + end_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack); + bottom_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack); + top_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack); + alloc_size = (duk_size_t) alloc_end_off; + if (alloc_size == 0) { + DUK_D(DUK_DPRINT("skip valstack torture realloc, alloc_size is zero")); + return; + } + + /* Use DUK_ALLOC_RAW() to avoid side effects. */ + new_ptr = (duk_tval *) DUK_ALLOC_RAW(thr->heap, alloc_size); + if (new_ptr != NULL) { + duk_memcpy((void *) new_ptr, (const void *) thr->valstack, alloc_size); + duk_memset((void *) thr->valstack, 0x55, alloc_size); + DUK_FREE_CHECKED(thr, (void *) thr->valstack); + thr->valstack = new_ptr; + thr->valstack_alloc_end = (duk_tval *) ((duk_uint8_t *) new_ptr + alloc_end_off); + thr->valstack_end = (duk_tval *) ((duk_uint8_t *) new_ptr + end_off); + thr->valstack_bottom = (duk_tval *) ((duk_uint8_t *) new_ptr + bottom_off); + thr->valstack_top = (duk_tval *) ((duk_uint8_t *) new_ptr + top_off); + } else { + DUK_D(DUK_DPRINT("failed to realloc valstack for torture, ignore")); + } +} +#endif /* DUK_USE_FINALIZER_TORTURE */ diff --git a/third_party/duktape/duk_internal.h b/third_party/duktape/duk_internal.h new file mode 100644 index 00000000..13e0a849 --- /dev/null +++ b/third_party/duktape/duk_internal.h @@ -0,0 +1,77 @@ +/* + * Top-level include file to be used for all (internal) source files. + * + * Source files should not include individual header files, as they + * have not been designed to be individually included. + */ + +#if !defined(DUK_INTERNAL_H_INCLUDED) +#define DUK_INTERNAL_H_INCLUDED + +/* + * The 'duktape.h' header provides the public API, but also handles all + * compiler and platform specific feature detection, Duktape feature + * resolution, inclusion of system headers, etc. These have been merged + * because the public API is also dependent on e.g. detecting appropriate + * C types which is quite platform/compiler specific especially for a non-C99 + * build. The public API is also dependent on the resolved feature set. + * + * Some actions taken by the merged header (such as including system headers) + * are not appropriate for building a user application. The define + * DUK_COMPILING_DUKTAPE allows the merged header to skip/include some + * sections depending on what is being built. + */ + +#define DUK_COMPILING_DUKTAPE +#include "third_party/duktape/duktape.h" + +/* + * Duktape includes (other than duk_features.h) + * + * The header files expect to be included in an order which satisfies header + * dependencies correctly (the headers themselves don't include any other + * includes). Forward declarations are used to break circular struct/typedef + * dependencies. + */ + +#include "third_party/duktape/duk_dblunion.h" +#include "third_party/duktape/duk_fltunion.h" +#include "third_party/duktape/duk_replacements.h" +#include "third_party/duktape/duk_jmpbuf.h" +#include "third_party/duktape/duk_exception.h" +#include "third_party/duktape/duk_forwdecl.h" +#include "third_party/duktape/duk_tval.h" /* builtins need e.g. duk_tval tag definitions */ +#include "third_party/duktape/duk_builtins.h" /* autogenerated: strings and built-in object init data */ + +#include "third_party/duktape/duk_util.h" +#include "third_party/duktape/duk_strings.h" +#include "third_party/duktape/duk_js_bytecode.h" +#include "third_party/duktape/duk_lexer.h" +#include "third_party/duktape/duk_js_compiler.h" +#include "third_party/duktape/duk_regexp.h" +#include "third_party/duktape/duk_heaphdr.h" +#include "third_party/duktape/duk_refcount.h" +#include "third_party/duktape/duk_api_internal.h" +#include "third_party/duktape/duk_hstring.h" +#include "third_party/duktape/duk_hobject.h" +#include "third_party/duktape/duk_hcompfunc.h" +#include "third_party/duktape/duk_hnatfunc.h" +#include "third_party/duktape/duk_hboundfunc.h" +#include "third_party/duktape/duk_hbufobj.h" +#include "third_party/duktape/duk_hthread.h" +#include "third_party/duktape/duk_harray.h" +#include "third_party/duktape/duk_henv.h" +#include "third_party/duktape/duk_hbuffer.h" +#include "third_party/duktape/duk_hproxy.h" +#include "third_party/duktape/duk_heap.h" +#include "third_party/duktape/duk_debugger.h" +#include "third_party/duktape/duk_debug.h" +#include "third_party/duktape/duk_error.h" +#include "third_party/duktape/duk_unicode.h" +#include "third_party/duktape/duk_json.h" +#include "third_party/duktape/duk_js.h" +#include "third_party/duktape/duk_numconv.h" +#include "third_party/duktape/duk_bi_protos.h" +#include "third_party/duktape/duk_selftest.h" + +#endif /* DUK_INTERNAL_H_INCLUDED */ diff --git a/third_party/duktape/duk_jmpbuf.h b/third_party/duktape/duk_jmpbuf.h new file mode 100644 index 00000000..a52119ad --- /dev/null +++ b/third_party/duktape/duk_jmpbuf.h @@ -0,0 +1,24 @@ +/* + * Wrapper for jmp_buf. + * + * This is used because jmp_buf is an array type for backward compatibility. + * Wrapping jmp_buf in a struct makes pointer references, sizeof, etc, + * behave more intuitively. + * + * http://en.wikipedia.org/wiki/Setjmp.h#Member_types + */ + +#if !defined(DUK_JMPBUF_H_INCLUDED) +#define DUK_JMPBUF_H_INCLUDED + +#if defined(DUK_USE_CPP_EXCEPTIONS) +struct duk_jmpbuf { + duk_small_int_t dummy; /* unused */ +}; +#else +struct duk_jmpbuf { + DUK_JMPBUF_TYPE jb; +}; +#endif + +#endif /* DUK_JMPBUF_H_INCLUDED */ diff --git a/third_party/duktape/duk_js.h b/third_party/duktape/duk_js.h new file mode 100644 index 00000000..92af2540 --- /dev/null +++ b/third_party/duktape/duk_js.h @@ -0,0 +1,116 @@ +/* + * ECMAScript execution, support primitives. + */ + +#if !defined(DUK_JS_H_INCLUDED) +#define DUK_JS_H_INCLUDED + +/* Flags for call handling. Lowest flags must match bytecode DUK_BC_CALL_FLAG_xxx 1:1. */ +#define DUK_CALL_FLAG_TAILCALL (1U << 0) /* setup for a tail call */ +#define DUK_CALL_FLAG_CONSTRUCT (1U << 1) /* constructor call (i.e. called as 'new Foo()') */ +#define DUK_CALL_FLAG_CALLED_AS_EVAL (1U << 2) /* call was made using the identifier 'eval' */ +#define DUK_CALL_FLAG_ALLOW_ECMATOECMA (1U << 3) /* ecma-to-ecma call with executor reuse is possible */ +#define DUK_CALL_FLAG_DIRECT_EVAL (1U << 4) /* call is a direct eval call */ +#define DUK_CALL_FLAG_CONSTRUCT_PROXY (1U << 5) /* handled via 'construct' proxy trap, check return value invariant(s) */ +#define DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED (1U << 6) /* prototype of 'default instance' updated, temporary flag in call handling */ + +/* Flags for duk_js_equals_helper(). */ +#define DUK_EQUALS_FLAG_SAMEVALUE (1U << 0) /* use SameValue instead of non-strict equality */ +#define DUK_EQUALS_FLAG_STRICT (1U << 1) /* use strict equality instead of non-strict equality */ + +/* Flags for duk_js_compare_helper(). */ +#define DUK_COMPARE_FLAG_NEGATE (1U << 0) /* negate result */ +#define DUK_COMPARE_FLAG_EVAL_LEFT_FIRST (1U << 1) /* eval left argument first */ + +/* conversions, coercions, comparison, etc */ +DUK_INTERNAL_DECL duk_bool_t duk_js_toboolean(duk_tval *tv); +DUK_INTERNAL_DECL duk_double_t duk_js_tonumber(duk_hthread *thr, duk_tval *tv); +DUK_INTERNAL_DECL duk_double_t duk_js_tointeger_number(duk_double_t x); +DUK_INTERNAL_DECL duk_double_t duk_js_tointeger(duk_hthread *thr, duk_tval *tv); +DUK_INTERNAL_DECL duk_uint32_t duk_js_touint32(duk_hthread *thr, duk_tval *tv); +DUK_INTERNAL_DECL duk_int32_t duk_js_toint32(duk_hthread *thr, duk_tval *tv); +DUK_INTERNAL_DECL duk_uint16_t duk_js_touint16(duk_hthread *thr, duk_tval *tv); +DUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_string(const duk_uint8_t *str, duk_uint32_t blen); +#if !defined(DUK_USE_HSTRING_ARRIDX) +DUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_hstring_fast_known(duk_hstring *h); +DUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_hstring_fast(duk_hstring *h); +#endif +DUK_INTERNAL_DECL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags); +DUK_INTERNAL_DECL duk_small_int_t duk_js_data_compare(const duk_uint8_t *buf1, const duk_uint8_t *buf2, duk_size_t len1, duk_size_t len2); +DUK_INTERNAL_DECL duk_small_int_t duk_js_string_compare(duk_hstring *h1, duk_hstring *h2); +#if 0 /* unused */ +DUK_INTERNAL_DECL duk_small_int_t duk_js_buffer_compare(duk_heap *heap, duk_hbuffer *h1, duk_hbuffer *h2); +#endif +DUK_INTERNAL_DECL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags); +DUK_INTERNAL_DECL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y); +#if defined(DUK_USE_SYMBOL_BUILTIN) +DUK_INTERNAL_DECL duk_bool_t duk_js_instanceof_ordinary(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y); +#endif +DUK_INTERNAL_DECL duk_bool_t duk_js_in(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y); +DUK_INTERNAL_DECL duk_small_uint_t duk_js_typeof_stridx(duk_tval *tv_x); +DUK_INTERNAL_DECL duk_bool_t duk_js_isarray_hobject(duk_hobject *h); +DUK_INTERNAL_DECL duk_bool_t duk_js_isarray(duk_tval *tv); + +/* arithmetic */ +DUK_INTERNAL_DECL double duk_js_arith_pow(double x, double y); +DUK_INTERNAL_DECL double duk_js_arith_mod(double x, double y); + +#define duk_js_equals(thr,tv_x,tv_y) \ + duk_js_equals_helper((thr), (tv_x), (tv_y), 0) +#define duk_js_strict_equals(tv_x,tv_y) \ + duk_js_equals_helper(NULL, (tv_x), (tv_y), DUK_EQUALS_FLAG_STRICT) +#define duk_js_samevalue(tv_x,tv_y) \ + duk_js_equals_helper(NULL, (tv_x), (tv_y), DUK_EQUALS_FLAG_SAMEVALUE) + +/* E5 Sections 11.8.1, 11.8.5; x < y */ +#define duk_js_lessthan(thr,tv_x,tv_y) \ + duk_js_compare_helper((thr), (tv_x), (tv_Y), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST) + +/* E5 Sections 11.8.2, 11.8.5; x > y --> y < x */ +#define duk_js_greaterthan(thr,tv_x,tv_y) \ + duk_js_compare_helper((thr), (tv_y), (tv_x), 0) + +/* E5 Sections 11.8.3, 11.8.5; x <= y --> not (x > y) --> not (y < x) */ +#define duk_js_lessthanorequal(thr,tv_x,tv_y) \ + duk_js_compare_helper((thr), (tv_y), (tv_x), DUK_COMPARE_FLAG_NEGATE) + +/* E5 Sections 11.8.4, 11.8.5; x >= y --> not (x < y) */ +#define duk_js_greaterthanorequal(thr,tv_x,tv_y) \ + duk_js_compare_helper((thr), (tv_x), (tv_y), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST | DUK_COMPARE_FLAG_NEGATE) + +/* identifiers and environment handling */ +#if 0 /*unused*/ +DUK_INTERNAL duk_bool_t duk_js_hasvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name); +#endif +DUK_INTERNAL_DECL duk_bool_t duk_js_getvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name, duk_bool_t throw_flag); +DUK_INTERNAL_DECL duk_bool_t duk_js_getvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name, duk_bool_t throw_flag); +DUK_INTERNAL_DECL void duk_js_putvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name, duk_tval *val, duk_bool_t strict); +DUK_INTERNAL_DECL void duk_js_putvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name, duk_tval *val, duk_bool_t strict); +#if 0 /*unused*/ +DUK_INTERNAL_DECL duk_bool_t duk_js_delvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name); +#endif +DUK_INTERNAL_DECL duk_bool_t duk_js_delvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name); +DUK_INTERNAL_DECL duk_bool_t duk_js_declvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name, duk_tval *val, duk_small_uint_t prop_flags, duk_bool_t is_func_decl); +DUK_INTERNAL_DECL void duk_js_init_activation_environment_records_delayed(duk_hthread *thr, duk_activation *act); +DUK_INTERNAL_DECL void duk_js_close_environment_record(duk_hthread *thr, duk_hobject *env); +DUK_INTERNAL_DECL duk_hobject *duk_create_activation_environment_record(duk_hthread *thr, duk_hobject *func, duk_size_t bottom_byteoff); +DUK_INTERNAL_DECL void duk_js_push_closure(duk_hthread *thr, + duk_hcompfunc *fun_temp, + duk_hobject *outer_var_env, + duk_hobject *outer_lex_env, + duk_bool_t add_auto_proto); + +/* call handling */ +DUK_INTERNAL_DECL void duk_native_stack_check(duk_hthread *thr); +DUK_INTERNAL_DECL duk_int_t duk_handle_call_unprotected(duk_hthread *thr, duk_idx_t idx_func, duk_small_uint_t call_flags); +DUK_INTERNAL_DECL duk_int_t duk_handle_call_unprotected_nargs(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags); +DUK_INTERNAL_DECL duk_int_t duk_handle_safe_call(duk_hthread *thr, duk_safe_call_function func, void *udata, duk_idx_t num_stack_args, duk_idx_t num_stack_res); +DUK_INTERNAL_DECL void duk_call_construct_postprocess(duk_hthread *thr, duk_small_uint_t proxy_invariant); +#if defined(DUK_USE_VERBOSE_ERRORS) +DUK_INTERNAL_DECL void duk_call_setup_propcall_error(duk_hthread *thr, duk_tval *tv_base, duk_tval *tv_key); +#endif + +/* bytecode execution */ +DUK_INTERNAL_DECL void duk_js_execute_bytecode(duk_hthread *exec_thr); + +#endif /* DUK_JS_H_INCLUDED */ diff --git a/third_party/duktape/duk_js_arith.c b/third_party/duktape/duk_js_arith.c new file mode 100644 index 00000000..e14a9806 --- /dev/null +++ b/third_party/duktape/duk_js_arith.c @@ -0,0 +1,137 @@ +/* + * Shared helpers for arithmetic operations + */ + +#include "third_party/duktape/duk_internal.h" + +/* ECMAScript modulus ('%') does not match IEEE 754 "remainder" operation + * (implemented by remainder() in C99) but does seem to match ANSI C fmod(). + * Compare E5 Section 11.5.3 and "man fmod". + */ +DUK_INTERNAL double duk_js_arith_mod(double d1, double d2) { +#if defined(DUK_USE_POW_WORKAROUNDS) + /* Specific fixes to common fmod() implementation issues: + * - test-bug-mingw-math-issues.js + */ + if (DUK_ISINF(d2)) { + if (DUK_ISINF(d1)) { + return DUK_DOUBLE_NAN; + } else { + return d1; + } + } else if (duk_double_equals(d1, 0.0)) { + /* d1 +/-0 is returned as is (preserving sign) except when + * d2 is zero or NaN. + */ + if (duk_double_equals(d2, 0.0) || DUK_ISNAN(d2)) { + return DUK_DOUBLE_NAN; + } else { + return d1; + } + } +#else + /* Some ISO C assumptions. */ + DUK_ASSERT(duk_double_equals(DUK_FMOD(1.0, DUK_DOUBLE_INFINITY), 1.0)); + DUK_ASSERT(duk_double_equals(DUK_FMOD(-1.0, DUK_DOUBLE_INFINITY), -1.0)); + DUK_ASSERT(duk_double_equals(DUK_FMOD(1.0, -DUK_DOUBLE_INFINITY), 1.0)); + DUK_ASSERT(duk_double_equals(DUK_FMOD(-1.0, -DUK_DOUBLE_INFINITY), -1.0)); + DUK_ASSERT(DUK_ISNAN(DUK_FMOD(DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY))); + DUK_ASSERT(DUK_ISNAN(DUK_FMOD(DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY))); + DUK_ASSERT(DUK_ISNAN(DUK_FMOD(-DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY))); + DUK_ASSERT(DUK_ISNAN(DUK_FMOD(-DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY))); + DUK_ASSERT(duk_double_equals(DUK_FMOD(0.0, 1.0), 0.0) && DUK_SIGNBIT(DUK_FMOD(0.0, 1.0)) == 0); + DUK_ASSERT(duk_double_equals(DUK_FMOD(-0.0, 1.0), 0.0) && DUK_SIGNBIT(DUK_FMOD(-0.0, 1.0)) != 0); + DUK_ASSERT(duk_double_equals(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY), 0.0) && DUK_SIGNBIT(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY)) == 0); + DUK_ASSERT(duk_double_equals(DUK_FMOD(-0.0, DUK_DOUBLE_INFINITY), 0.0) && DUK_SIGNBIT(DUK_FMOD(-0.0, DUK_DOUBLE_INFINITY)) != 0); + DUK_ASSERT(duk_double_equals(DUK_FMOD(0.0, -DUK_DOUBLE_INFINITY), 0.0) && DUK_SIGNBIT(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY)) == 0); + DUK_ASSERT(duk_double_equals(DUK_FMOD(-0.0, -DUK_DOUBLE_INFINITY), 0.0) && DUK_SIGNBIT(DUK_FMOD(-0.0, -DUK_DOUBLE_INFINITY)) != 0); + DUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, 0.0))); + DUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, 0.0))); + DUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, -0.0))); + DUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, -0.0))); + DUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, DUK_DOUBLE_NAN))); + DUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, DUK_DOUBLE_NAN))); +#endif + + return (duk_double_t) DUK_FMOD((double) d1, (double) d2); +} + +/* Shared helper for Math.pow() and exponentiation operator. */ +DUK_INTERNAL double duk_js_arith_pow(double x, double y) { + /* The ANSI C pow() semantics differ from ECMAScript. + * + * E.g. when x==1 and y is +/- infinite, the ECMAScript required + * result is NaN, while at least Linux pow() returns 1. + */ + + duk_small_int_t cx, cy, sx; + + DUK_UNREF(cx); + DUK_UNREF(sx); + cy = (duk_small_int_t) DUK_FPCLASSIFY(y); + + if (cy == DUK_FP_NAN) { + goto ret_nan; + } + if (duk_double_equals(DUK_FABS(x), 1.0) && cy == DUK_FP_INFINITE) { + goto ret_nan; + } + +#if defined(DUK_USE_POW_WORKAROUNDS) + /* Specific fixes to common pow() implementation issues: + * - test-bug-netbsd-math-pow.js: NetBSD 6.0 on x86 (at least) + * - test-bug-mingw-math-issues.js + */ + cx = (duk_small_int_t) DUK_FPCLASSIFY(x); + if (cx == DUK_FP_ZERO && y < 0.0) { + sx = (duk_small_int_t) DUK_SIGNBIT(x); + if (sx == 0) { + /* Math.pow(+0,y) should be Infinity when y<0. NetBSD pow() + * returns -Infinity instead when y is <0 and finite. The + * if-clause also catches y == -Infinity (which works even + * without the fix). + */ + return DUK_DOUBLE_INFINITY; + } else { + /* Math.pow(-0,y) where y<0 should be: + * - -Infinity if y<0 and an odd integer + * - Infinity if y<0 but not an odd integer + * NetBSD pow() returns -Infinity for all finite y<0. The + * if-clause also catches y == -Infinity (which works even + * without the fix). + */ + + /* fmod() return value has same sign as input (negative) so + * the result here will be in the range ]-2,0], -1 indicates + * odd. If x is -Infinity, NaN is returned and the odd check + * always concludes "not odd" which results in desired outcome. + */ + double tmp = DUK_FMOD(y, 2); + if (tmp == -1.0) { + return -DUK_DOUBLE_INFINITY; + } else { + /* Not odd, or y == -Infinity */ + return DUK_DOUBLE_INFINITY; + } + } + } else if (cx == DUK_FP_NAN) { + if (duk_double_equals(y, 0.0)) { + /* NaN ** +/- 0 should always be 1, but is NaN on + * at least some Cygwin/MinGW versions. + */ + return 1.0; + } + } +#else + /* Some ISO C assumptions. */ + DUK_ASSERT(duk_double_equals(DUK_POW(DUK_DOUBLE_NAN, 0.0), 1.0)); + DUK_ASSERT(DUK_ISINF(DUK_POW(0.0, -1.0)) && DUK_SIGNBIT(DUK_POW(0.0, -1.0)) == 0); + DUK_ASSERT(DUK_ISINF(DUK_POW(-0.0, -2.0)) && DUK_SIGNBIT(DUK_POW(-0.0, -2.0)) == 0); + DUK_ASSERT(DUK_ISINF(DUK_POW(-0.0, -3.0)) && DUK_SIGNBIT(DUK_POW(-0.0, -3.0)) != 0); +#endif + + return DUK_POW(x, y); + + ret_nan: + return DUK_DOUBLE_NAN; +} diff --git a/third_party/duktape/duk_js_bytecode.h b/third_party/duktape/duk_js_bytecode.h new file mode 100644 index 00000000..b564b64a --- /dev/null +++ b/third_party/duktape/duk_js_bytecode.h @@ -0,0 +1,482 @@ +/* + * ECMAScript bytecode + */ + +#if !defined(DUK_JS_BYTECODE_H_INCLUDED) +#define DUK_JS_BYTECODE_H_INCLUDED + +/* + * Bytecode instruction layout + * =========================== + * + * Instructions are unsigned 32-bit integers divided as follows: + * + * !3!3!2!2!2!2!2!2!2!2!2!2!1!1!1!1!1!1!1!1!1!1! ! ! ! ! ! ! ! ! ! ! + * !1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0! + * +-----------------------------------------------+---------------+ + * ! C ! B ! A ! OP ! + * +-----------------------------------------------+---------------+ + * + * OP (8 bits): opcode (DUK_OP_*), access should be fastest + * consecutive opcodes allocated when opcode needs flags + * A (8 bits): typically a target register number + * B (8 bits): typically first source register/constant number + * C (8 bits): typically second source register/constant number + * + * Some instructions combine BC or ABC together for larger parameter values. + * Signed integers (e.g. jump offsets) are encoded as unsigned, with an + * opcode specific bias. + * + * Some opcodes have flags which are handled by allocating consecutive + * opcodes to make space for 1-N flags. Flags can also be e.g. in the 'A' + * field when there's room for the specific opcode. + * + * For example, if three flags were needed, they could be allocated from + * the opcode field as follows: + * + * !3!3!2!2!2!2!2!2!2!2!2!2!1!1!1!1!1!1!1!1!1!1! ! ! ! ! ! ! ! ! ! ! + * !1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0! + * +-----------------------------------------------+---------------+ + * ! C ! B ! A ! OP !Z!Y!X! + * +-----------------------------------------------+---------------+ + * + * Some opcodes accept a reg/const argument which is handled by allocating + * flags in the OP field, see DUK_BC_ISREG() and DUK_BC_ISCONST(). The + * following convention is shared by most opcodes, so that the compiler + * can handle reg/const flagging without opcode specific code paths: + * + * !3!3!2!2!2!2!2!2!2!2!2!2!1!1!1!1!1!1!1!1!1!1! ! ! ! ! ! ! ! ! ! ! + * !1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0! + * +-----------------------------------------------+---------------+ + * ! C ! B ! A ! OP !Y!X! + * +-----------------------------------------------+---------------+ + * + * X 1=B is const, 0=B is reg + * Y 1=C is const, 0=C is reg + * + * In effect OP, OP + 1, OP + 2, and OP + 3 are allocated from the + * 8-bit opcode space for a single logical opcode. The base opcode + * number should be divisible by 4. If the opcode is called 'FOO' + * the following opcode constants would be defined: + * + * DUK_OP_FOO 100 // base opcode number + * DUK_OP_FOO_RR 100 // FOO, B=reg, C=reg + * DUK_OP_FOO_CR 101 // FOO, B=const, C=reg + * DUK_OP_FOO_RC 102 // FOO, B=reg, C=const + * DUK_OP_FOO_CC 103 // FOO, B=const, C=const + * + * If only B or C is a reg/const, the unused opcode combinations can be + * used for other opcodes (which take no reg/const argument). However, + * such opcode values are initially reserved, at least while opcode space + * is available. For example, if 'BAR' uses B for a register field and + * C is a reg/const: + * + * DUK_OP_BAR 116 // base opcode number + * DUK_OP_BAR_RR 116 // BAR, B=reg, C=reg + * DUK_OP_BAR_CR_UNUSED 117 // unused, could be repurposed + * DUK_OP_BAR_RC 118 // BAR, B=reg, C=const + * DUK_OP_BAR_CC_UNUSED 119 // unused, could be repurposed + * + * Macro naming is a bit misleading, e.g. "ABC" in macro name but the + * field layout is concretely "CBA" in the register. + */ + +typedef duk_uint32_t duk_instr_t; + +#define DUK_BC_SHIFT_OP 0 +#define DUK_BC_SHIFT_A 8 +#define DUK_BC_SHIFT_B 16 +#define DUK_BC_SHIFT_C 24 +#define DUK_BC_SHIFT_BC DUK_BC_SHIFT_B +#define DUK_BC_SHIFT_ABC DUK_BC_SHIFT_A + +#define DUK_BC_UNSHIFTED_MASK_OP 0xffUL +#define DUK_BC_UNSHIFTED_MASK_A 0xffUL +#define DUK_BC_UNSHIFTED_MASK_B 0xffUL +#define DUK_BC_UNSHIFTED_MASK_C 0xffUL +#define DUK_BC_UNSHIFTED_MASK_BC 0xffffUL +#define DUK_BC_UNSHIFTED_MASK_ABC 0xffffffUL + +#define DUK_BC_SHIFTED_MASK_OP (DUK_BC_UNSHIFTED_MASK_OP << DUK_BC_SHIFT_OP) +#define DUK_BC_SHIFTED_MASK_A (DUK_BC_UNSHIFTED_MASK_A << DUK_BC_SHIFT_A) +#define DUK_BC_SHIFTED_MASK_B (DUK_BC_UNSHIFTED_MASK_B << DUK_BC_SHIFT_B) +#define DUK_BC_SHIFTED_MASK_C (DUK_BC_UNSHIFTED_MASK_C << DUK_BC_SHIFT_C) +#define DUK_BC_SHIFTED_MASK_BC (DUK_BC_UNSHIFTED_MASK_BC << DUK_BC_SHIFT_BC) +#define DUK_BC_SHIFTED_MASK_ABC (DUK_BC_UNSHIFTED_MASK_ABC << DUK_BC_SHIFT_ABC) + +#define DUK_DEC_OP(x) ((x) & 0xffUL) +#define DUK_DEC_A(x) (((x) >> 8) & 0xffUL) +#define DUK_DEC_B(x) (((x) >> 16) & 0xffUL) +#define DUK_DEC_C(x) (((x) >> 24) & 0xffUL) +#define DUK_DEC_BC(x) (((x) >> 16) & 0xffffUL) +#define DUK_DEC_ABC(x) (((x) >> 8) & 0xffffffUL) + +#define DUK_ENC_OP(op) ((duk_instr_t) (op)) +#define DUK_ENC_OP_ABC(op,abc) ((duk_instr_t) ( \ + (((duk_instr_t) (abc)) << 8) | \ + ((duk_instr_t) (op)) \ + )) +#define DUK_ENC_OP_A_BC(op,a,bc) ((duk_instr_t) ( \ + (((duk_instr_t) (bc)) << 16) | \ + (((duk_instr_t) (a)) << 8) | \ + ((duk_instr_t) (op)) \ + )) +#define DUK_ENC_OP_A_B_C(op,a,b,c) ((duk_instr_t) ( \ + (((duk_instr_t) (c)) << 24) | \ + (((duk_instr_t) (b)) << 16) | \ + (((duk_instr_t) (a)) << 8) | \ + ((duk_instr_t) (op)) \ + )) +#define DUK_ENC_OP_A_B(op,a,b) DUK_ENC_OP_A_B_C((op),(a),(b),0) +#define DUK_ENC_OP_A(op,a) DUK_ENC_OP_A_B_C((op),(a),0,0) +#define DUK_ENC_OP_BC(op,bc) DUK_ENC_OP_A_BC((op),0,(bc)) + +/* Get opcode base value with B/C reg/const flags cleared. */ +#define DUK_BC_NOREGCONST_OP(op) ((op) & 0xfc) + +/* Constants should be signed so that signed arithmetic involving them + * won't cause values to be coerced accidentally to unsigned. + */ +#define DUK_BC_OP_MIN 0 +#define DUK_BC_OP_MAX 0xffL +#define DUK_BC_A_MIN 0 +#define DUK_BC_A_MAX 0xffL +#define DUK_BC_B_MIN 0 +#define DUK_BC_B_MAX 0xffL +#define DUK_BC_C_MIN 0 +#define DUK_BC_C_MAX 0xffL +#define DUK_BC_BC_MIN 0 +#define DUK_BC_BC_MAX 0xffffL +#define DUK_BC_ABC_MIN 0 +#define DUK_BC_ABC_MAX 0xffffffL + +/* Masks for B/C reg/const indicator in opcode field. */ +#define DUK_BC_REGCONST_B (0x01UL) +#define DUK_BC_REGCONST_C (0x02UL) + +/* Misc. masks for opcode field. */ +#define DUK_BC_INCDECP_FLAG_DEC (0x04UL) +#define DUK_BC_INCDECP_FLAG_POST (0x08UL) + +/* Opcodes. */ +#define DUK_OP_LDREG 0 +#define DUK_OP_STREG 1 +#define DUK_OP_JUMP 2 +#define DUK_OP_LDCONST 3 +#define DUK_OP_LDINT 4 +#define DUK_OP_LDINTX 5 +#define DUK_OP_LDTHIS 6 +#define DUK_OP_LDUNDEF 7 +#define DUK_OP_LDNULL 8 +#define DUK_OP_LDTRUE 9 +#define DUK_OP_LDFALSE 10 +#define DUK_OP_GETVAR 11 +#define DUK_OP_BNOT 12 +#define DUK_OP_LNOT 13 +#define DUK_OP_UNM 14 +#define DUK_OP_UNP 15 +#define DUK_OP_EQ 16 +#define DUK_OP_EQ_RR 16 +#define DUK_OP_EQ_CR 17 +#define DUK_OP_EQ_RC 18 +#define DUK_OP_EQ_CC 19 +#define DUK_OP_NEQ 20 +#define DUK_OP_NEQ_RR 20 +#define DUK_OP_NEQ_CR 21 +#define DUK_OP_NEQ_RC 22 +#define DUK_OP_NEQ_CC 23 +#define DUK_OP_SEQ 24 +#define DUK_OP_SEQ_RR 24 +#define DUK_OP_SEQ_CR 25 +#define DUK_OP_SEQ_RC 26 +#define DUK_OP_SEQ_CC 27 +#define DUK_OP_SNEQ 28 +#define DUK_OP_SNEQ_RR 28 +#define DUK_OP_SNEQ_CR 29 +#define DUK_OP_SNEQ_RC 30 +#define DUK_OP_SNEQ_CC 31 +#define DUK_OP_GT 32 +#define DUK_OP_GT_RR 32 +#define DUK_OP_GT_CR 33 +#define DUK_OP_GT_RC 34 +#define DUK_OP_GT_CC 35 +#define DUK_OP_GE 36 +#define DUK_OP_GE_RR 36 +#define DUK_OP_GE_CR 37 +#define DUK_OP_GE_RC 38 +#define DUK_OP_GE_CC 39 +#define DUK_OP_LT 40 +#define DUK_OP_LT_RR 40 +#define DUK_OP_LT_CR 41 +#define DUK_OP_LT_RC 42 +#define DUK_OP_LT_CC 43 +#define DUK_OP_LE 44 +#define DUK_OP_LE_RR 44 +#define DUK_OP_LE_CR 45 +#define DUK_OP_LE_RC 46 +#define DUK_OP_LE_CC 47 +#define DUK_OP_IFTRUE 48 +#define DUK_OP_IFTRUE_R 48 +#define DUK_OP_IFTRUE_C 49 +#define DUK_OP_IFFALSE 50 +#define DUK_OP_IFFALSE_R 50 +#define DUK_OP_IFFALSE_C 51 +#define DUK_OP_ADD 52 +#define DUK_OP_ADD_RR 52 +#define DUK_OP_ADD_CR 53 +#define DUK_OP_ADD_RC 54 +#define DUK_OP_ADD_CC 55 +#define DUK_OP_SUB 56 +#define DUK_OP_SUB_RR 56 +#define DUK_OP_SUB_CR 57 +#define DUK_OP_SUB_RC 58 +#define DUK_OP_SUB_CC 59 +#define DUK_OP_MUL 60 +#define DUK_OP_MUL_RR 60 +#define DUK_OP_MUL_CR 61 +#define DUK_OP_MUL_RC 62 +#define DUK_OP_MUL_CC 63 +#define DUK_OP_DIV 64 +#define DUK_OP_DIV_RR 64 +#define DUK_OP_DIV_CR 65 +#define DUK_OP_DIV_RC 66 +#define DUK_OP_DIV_CC 67 +#define DUK_OP_MOD 68 +#define DUK_OP_MOD_RR 68 +#define DUK_OP_MOD_CR 69 +#define DUK_OP_MOD_RC 70 +#define DUK_OP_MOD_CC 71 +#define DUK_OP_EXP 72 +#define DUK_OP_EXP_RR 72 +#define DUK_OP_EXP_CR 73 +#define DUK_OP_EXP_RC 74 +#define DUK_OP_EXP_CC 75 +#define DUK_OP_BAND 76 +#define DUK_OP_BAND_RR 76 +#define DUK_OP_BAND_CR 77 +#define DUK_OP_BAND_RC 78 +#define DUK_OP_BAND_CC 79 +#define DUK_OP_BOR 80 +#define DUK_OP_BOR_RR 80 +#define DUK_OP_BOR_CR 81 +#define DUK_OP_BOR_RC 82 +#define DUK_OP_BOR_CC 83 +#define DUK_OP_BXOR 84 +#define DUK_OP_BXOR_RR 84 +#define DUK_OP_BXOR_CR 85 +#define DUK_OP_BXOR_RC 86 +#define DUK_OP_BXOR_CC 87 +#define DUK_OP_BASL 88 +#define DUK_OP_BASL_RR 88 +#define DUK_OP_BASL_CR 89 +#define DUK_OP_BASL_RC 90 +#define DUK_OP_BASL_CC 91 +#define DUK_OP_BLSR 92 +#define DUK_OP_BLSR_RR 92 +#define DUK_OP_BLSR_CR 93 +#define DUK_OP_BLSR_RC 94 +#define DUK_OP_BLSR_CC 95 +#define DUK_OP_BASR 96 +#define DUK_OP_BASR_RR 96 +#define DUK_OP_BASR_CR 97 +#define DUK_OP_BASR_RC 98 +#define DUK_OP_BASR_CC 99 +#define DUK_OP_INSTOF 100 +#define DUK_OP_INSTOF_RR 100 +#define DUK_OP_INSTOF_CR 101 +#define DUK_OP_INSTOF_RC 102 +#define DUK_OP_INSTOF_CC 103 +#define DUK_OP_IN 104 +#define DUK_OP_IN_RR 104 +#define DUK_OP_IN_CR 105 +#define DUK_OP_IN_RC 106 +#define DUK_OP_IN_CC 107 +#define DUK_OP_GETPROP 108 +#define DUK_OP_GETPROP_RR 108 +#define DUK_OP_GETPROP_CR 109 +#define DUK_OP_GETPROP_RC 110 +#define DUK_OP_GETPROP_CC 111 +#define DUK_OP_PUTPROP 112 +#define DUK_OP_PUTPROP_RR 112 +#define DUK_OP_PUTPROP_CR 113 +#define DUK_OP_PUTPROP_RC 114 +#define DUK_OP_PUTPROP_CC 115 +#define DUK_OP_DELPROP 116 +#define DUK_OP_DELPROP_RR 116 +#define DUK_OP_DELPROP_CR_UNUSED 117 /* unused now */ +#define DUK_OP_DELPROP_RC 118 +#define DUK_OP_DELPROP_CC_UNUSED 119 /* unused now */ +#define DUK_OP_PREINCR 120 /* pre/post opcode values have constraints, */ +#define DUK_OP_PREDECR 121 /* see duk_js_executor.c and duk_js_compiler.c. */ +#define DUK_OP_POSTINCR 122 +#define DUK_OP_POSTDECR 123 +#define DUK_OP_PREINCV 124 +#define DUK_OP_PREDECV 125 +#define DUK_OP_POSTINCV 126 +#define DUK_OP_POSTDECV 127 +#define DUK_OP_PREINCP 128 /* pre/post inc/dec prop opcodes have constraints */ +#define DUK_OP_PREINCP_RR 128 +#define DUK_OP_PREINCP_CR 129 +#define DUK_OP_PREINCP_RC 130 +#define DUK_OP_PREINCP_CC 131 +#define DUK_OP_PREDECP 132 +#define DUK_OP_PREDECP_RR 132 +#define DUK_OP_PREDECP_CR 133 +#define DUK_OP_PREDECP_RC 134 +#define DUK_OP_PREDECP_CC 135 +#define DUK_OP_POSTINCP 136 +#define DUK_OP_POSTINCP_RR 136 +#define DUK_OP_POSTINCP_CR 137 +#define DUK_OP_POSTINCP_RC 138 +#define DUK_OP_POSTINCP_CC 139 +#define DUK_OP_POSTDECP 140 +#define DUK_OP_POSTDECP_RR 140 +#define DUK_OP_POSTDECP_CR 141 +#define DUK_OP_POSTDECP_RC 142 +#define DUK_OP_POSTDECP_CC 143 +#define DUK_OP_DECLVAR 144 +#define DUK_OP_DECLVAR_RR 144 +#define DUK_OP_DECLVAR_CR 145 +#define DUK_OP_DECLVAR_RC 146 +#define DUK_OP_DECLVAR_CC 147 +#define DUK_OP_REGEXP 148 +#define DUK_OP_REGEXP_RR 148 +#define DUK_OP_REGEXP_CR 149 +#define DUK_OP_REGEXP_RC 150 +#define DUK_OP_REGEXP_CC 151 +#define DUK_OP_CLOSURE 152 +#define DUK_OP_TYPEOF 153 +#define DUK_OP_TYPEOFID 154 +#define DUK_OP_PUTVAR 155 +#define DUK_OP_DELVAR 156 +#define DUK_OP_RETREG 157 +#define DUK_OP_RETUNDEF 158 +#define DUK_OP_RETCONST 159 +#define DUK_OP_RETCONSTN 160 /* return const without incref (e.g. number) */ +#define DUK_OP_LABEL 161 +#define DUK_OP_ENDLABEL 162 +#define DUK_OP_BREAK 163 +#define DUK_OP_CONTINUE 164 +#define DUK_OP_TRYCATCH 165 +#define DUK_OP_ENDTRY 166 +#define DUK_OP_ENDCATCH 167 +#define DUK_OP_ENDFIN 168 +#define DUK_OP_THROW 169 +#define DUK_OP_INVLHS 170 +#define DUK_OP_CSREG 171 +#define DUK_OP_CSVAR 172 +#define DUK_OP_CSVAR_RR 172 +#define DUK_OP_CSVAR_CR 173 +#define DUK_OP_CSVAR_RC 174 +#define DUK_OP_CSVAR_CC 175 +#define DUK_OP_CALL0 176 /* DUK_OP_CALL0 & 0x0F must be zero. */ +#define DUK_OP_CALL1 177 +#define DUK_OP_CALL2 178 +#define DUK_OP_CALL3 179 +#define DUK_OP_CALL4 180 +#define DUK_OP_CALL5 181 +#define DUK_OP_CALL6 182 +#define DUK_OP_CALL7 183 +#define DUK_OP_CALL8 184 +#define DUK_OP_CALL9 185 +#define DUK_OP_CALL10 186 +#define DUK_OP_CALL11 187 +#define DUK_OP_CALL12 188 +#define DUK_OP_CALL13 189 +#define DUK_OP_CALL14 190 +#define DUK_OP_CALL15 191 +#define DUK_OP_NEWOBJ 192 +#define DUK_OP_NEWARR 193 +#define DUK_OP_MPUTOBJ 194 +#define DUK_OP_MPUTOBJI 195 +#define DUK_OP_INITSET 196 +#define DUK_OP_INITGET 197 +#define DUK_OP_MPUTARR 198 +#define DUK_OP_MPUTARRI 199 +#define DUK_OP_SETALEN 200 +#define DUK_OP_INITENUM 201 +#define DUK_OP_NEXTENUM 202 +#define DUK_OP_NEWTARGET 203 +#define DUK_OP_DEBUGGER 204 +#define DUK_OP_NOP 205 +#define DUK_OP_INVALID 206 +#define DUK_OP_UNUSED207 207 +#define DUK_OP_GETPROPC 208 +#define DUK_OP_GETPROPC_RR 208 +#define DUK_OP_GETPROPC_CR 209 +#define DUK_OP_GETPROPC_RC 210 +#define DUK_OP_GETPROPC_CC 211 +#define DUK_OP_UNUSED212 212 +#define DUK_OP_UNUSED213 213 +#define DUK_OP_UNUSED214 214 +#define DUK_OP_UNUSED215 215 +#define DUK_OP_UNUSED216 216 +#define DUK_OP_UNUSED217 217 +#define DUK_OP_UNUSED218 218 +#define DUK_OP_UNUSED219 219 +#define DUK_OP_UNUSED220 220 +#define DUK_OP_UNUSED221 221 +#define DUK_OP_UNUSED222 222 +#define DUK_OP_UNUSED223 223 +#define DUK_OP_UNUSED224 224 +#define DUK_OP_UNUSED225 225 +#define DUK_OP_UNUSED226 226 +#define DUK_OP_UNUSED227 227 +#define DUK_OP_UNUSED228 228 +#define DUK_OP_UNUSED229 229 +#define DUK_OP_UNUSED230 230 +#define DUK_OP_UNUSED231 231 +#define DUK_OP_UNUSED232 232 +#define DUK_OP_UNUSED233 233 +#define DUK_OP_UNUSED234 234 +#define DUK_OP_UNUSED235 235 +#define DUK_OP_UNUSED236 236 +#define DUK_OP_UNUSED237 237 +#define DUK_OP_UNUSED238 238 +#define DUK_OP_UNUSED239 239 +#define DUK_OP_UNUSED240 240 +#define DUK_OP_UNUSED241 241 +#define DUK_OP_UNUSED242 242 +#define DUK_OP_UNUSED243 243 +#define DUK_OP_UNUSED244 244 +#define DUK_OP_UNUSED245 245 +#define DUK_OP_UNUSED246 246 +#define DUK_OP_UNUSED247 247 +#define DUK_OP_UNUSED248 248 +#define DUK_OP_UNUSED249 249 +#define DUK_OP_UNUSED250 250 +#define DUK_OP_UNUSED251 251 +#define DUK_OP_UNUSED252 252 +#define DUK_OP_UNUSED253 253 +#define DUK_OP_UNUSED254 254 +#define DUK_OP_UNUSED255 255 +#define DUK_OP_NONE 256 /* dummy value used as marker (doesn't fit in 8-bit field) */ + +/* XXX: Allocate flags from opcode field? Would take 16 opcode slots + * but avoids shuffling in more cases. Maybe not worth it. + */ +/* DUK_OP_TRYCATCH flags in A. */ +#define DUK_BC_TRYCATCH_FLAG_HAVE_CATCH (1U << 0) +#define DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY (1U << 1) +#define DUK_BC_TRYCATCH_FLAG_CATCH_BINDING (1U << 2) +#define DUK_BC_TRYCATCH_FLAG_WITH_BINDING (1U << 3) + +/* DUK_OP_DECLVAR flags in A; bottom bits are reserved for propdesc flags + * (DUK_PROPDESC_FLAG_XXX). + */ +#define DUK_BC_DECLVAR_FLAG_FUNC_DECL (1U << 4) /* function declaration */ + +/* DUK_OP_CALLn flags, part of opcode field. Three lowest bits must match + * DUK_CALL_FLAG_xxx directly. + */ +#define DUK_BC_CALL_FLAG_TAILCALL (1U << 0) +#define DUK_BC_CALL_FLAG_CONSTRUCT (1U << 1) +#define DUK_BC_CALL_FLAG_CALLED_AS_EVAL (1U << 2) +#define DUK_BC_CALL_FLAG_INDIRECT (1U << 3) + +/* Misc constants and helper macros. */ +#define DUK_BC_LDINT_BIAS (1L << 15) +#define DUK_BC_LDINTX_SHIFT 16 +#define DUK_BC_JUMP_BIAS (1L << 23) + +#endif /* DUK_JS_BYTECODE_H_INCLUDED */ diff --git a/third_party/duktape/duk_js_call.c b/third_party/duktape/duk_js_call.c new file mode 100644 index 00000000..001fb41c --- /dev/null +++ b/third_party/duktape/duk_js_call.c @@ -0,0 +1,2933 @@ +/* + * Call handling. + * + * duk_handle_call_unprotected(): + * + * - Unprotected call to ECMAScript or Duktape/C function, from native + * code or bytecode executor. + * + * - Also handles Ecma-to-Ecma calls which reuses a currently running + * executor instance to avoid native recursion. Call setup is done + * normally, but just before calling the bytecode executor a special + * return code is used to indicate that a calling executor is reused. + * + * - Also handles tailcalls, i.e. reuse of current duk_activation. + * + * - Also handles setup for initial Duktape.Thread.resume(). + * + * duk_handle_safe_call(): + * + * - Protected C call within current activation. + * + * setjmp() and local variables have a nasty interaction, see execution.rst; + * non-volatile locals modified after setjmp() call are not guaranteed to + * keep their value and can cause compiler or compiler version specific + * difficult to replicate issues. + * + * See 'execution.rst'. + */ + +#include "third_party/duktape/duk_internal.h" + +/* XXX: heap->error_not_allowed for success path too? */ + +/* + * Limit check helpers. + */ + +/* Check native stack space if DUK_USE_NATIVE_STACK_CHECK() defined. */ +DUK_INTERNAL void duk_native_stack_check(duk_hthread *thr) { +#if defined(DUK_USE_NATIVE_STACK_CHECK) + if (DUK_USE_NATIVE_STACK_CHECK() != 0) { + DUK_ERROR_RANGE(thr, DUK_STR_NATIVE_STACK_LIMIT); + } +#else + DUK_UNREF(thr); +#endif +} + +/* Allow headroom for calls during error augmentation (see GH-191). + * We allow space for 10 additional recursions, with one extra + * for, e.g. a print() call at the deepest level, and an extra + * +1 for protected call wrapping. + */ +#define DUK__AUGMENT_CALL_RELAX_COUNT (10 + 2) + +/* Stack space required by call handling entry. */ +#define DUK__CALL_HANDLING_REQUIRE_STACK 8 + +DUK_LOCAL DUK_NOINLINE void duk__call_c_recursion_limit_check_slowpath(duk_hthread *thr) { + /* When augmenting an error, the effective limit is a bit higher. + * Check for it only if the fast path check fails. + */ +#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE) + if (thr->heap->augmenting_error) { + if (thr->heap->call_recursion_depth < thr->heap->call_recursion_limit + DUK__AUGMENT_CALL_RELAX_COUNT) { + DUK_D(DUK_DPRINT("C recursion limit reached but augmenting error and within relaxed limit")); + return; + } + } +#endif + + DUK_D(DUK_DPRINT("call prevented because C recursion limit reached")); + DUK_ERROR_RANGE(thr, DUK_STR_NATIVE_STACK_LIMIT); + DUK_WO_NORETURN(return;); +} + +DUK_LOCAL DUK_ALWAYS_INLINE void duk__call_c_recursion_limit_check(duk_hthread *thr) { + DUK_ASSERT(thr->heap->call_recursion_depth >= 0); + DUK_ASSERT(thr->heap->call_recursion_depth <= thr->heap->call_recursion_limit); + + duk_native_stack_check(thr); + + /* This check is forcibly inlined because it's very cheap and almost + * always passes. The slow path is forcibly noinline. + */ + if (DUK_LIKELY(thr->heap->call_recursion_depth < thr->heap->call_recursion_limit)) { + return; + } + + duk__call_c_recursion_limit_check_slowpath(thr); +} + +DUK_LOCAL DUK_NOINLINE void duk__call_callstack_limit_check_slowpath(duk_hthread *thr) { + /* When augmenting an error, the effective limit is a bit higher. + * Check for it only if the fast path check fails. + */ +#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE) + if (thr->heap->augmenting_error) { + if (thr->callstack_top < DUK_USE_CALLSTACK_LIMIT + DUK__AUGMENT_CALL_RELAX_COUNT) { + DUK_D(DUK_DPRINT("call stack limit reached but augmenting error and within relaxed limit")); + return; + } + } +#endif + + /* XXX: error message is a bit misleading: we reached a recursion + * limit which is also essentially the same as a C callstack limit + * (except perhaps with some relaxed threading assumptions). + */ + DUK_D(DUK_DPRINT("call prevented because call stack limit reached")); + DUK_ERROR_RANGE(thr, DUK_STR_CALLSTACK_LIMIT); + DUK_WO_NORETURN(return;); +} + +DUK_LOCAL DUK_ALWAYS_INLINE void duk__call_callstack_limit_check(duk_hthread *thr) { + /* This check is forcibly inlined because it's very cheap and almost + * always passes. The slow path is forcibly noinline. + */ + if (DUK_LIKELY(thr->callstack_top < DUK_USE_CALLSTACK_LIMIT)) { + return; + } + + duk__call_callstack_limit_check_slowpath(thr); +} + +/* + * Interrupt counter fixup (for development only). + */ + +#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG) +DUK_LOCAL void duk__interrupt_fixup(duk_hthread *thr, duk_hthread *entry_curr_thread) { + /* Currently the bytecode executor and executor interrupt + * instruction counts are off because we don't execute the + * interrupt handler when we're about to exit from the initial + * user call into Duktape. + * + * If we were to execute the interrupt handler here, the counts + * would match. You can enable this block manually to check + * that this is the case. + */ + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + +#if defined(DUK_USE_INTERRUPT_DEBUG_FIXUP) + if (entry_curr_thread == NULL) { + thr->interrupt_init = thr->interrupt_init - thr->interrupt_counter; + thr->heap->inst_count_interrupt += thr->interrupt_init; + DUK_DD(DUK_DDPRINT("debug test: updated interrupt count on exit to " + "user code, instruction counts: executor=%ld, interrupt=%ld", + (long) thr->heap->inst_count_exec, (long) thr->heap->inst_count_interrupt)); + DUK_ASSERT(thr->heap->inst_count_exec == thr->heap->inst_count_interrupt); + } +#else + DUK_UNREF(thr); + DUK_UNREF(entry_curr_thread); +#endif +} +#endif + +/* + * Arguments object creation. + * + * Creating arguments objects involves many small details, see E5 Section + * 10.6 for the specific requirements. Much of the arguments object exotic + * behavior is implemented in duk_hobject_props.c, and is enabled by the + * object flag DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS. + */ + +DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr, + duk_hobject *func, + duk_hobject *varenv, + duk_idx_t idx_args) { + duk_hobject *arg; /* 'arguments' */ + duk_hobject *formals; /* formals for 'func' (may be NULL if func is a C function) */ + duk_idx_t i_arg; + duk_idx_t i_map; + duk_idx_t i_mappednames; + duk_idx_t i_formals; + duk_idx_t i_argbase; + duk_idx_t n_formals; + duk_idx_t idx; + duk_idx_t num_stack_args; + duk_bool_t need_map; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(func != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_NONBOUND_FUNCTION(func)); + DUK_ASSERT(varenv != NULL); + + /* [ ... func this arg1(@idx_args) ... argN envobj ] + * [ arg1(@idx_args) ... argN envobj ] (for tailcalls) + */ + + need_map = 0; + + i_argbase = idx_args; + num_stack_args = duk_get_top(thr) - i_argbase - 1; + DUK_ASSERT(i_argbase >= 0); + DUK_ASSERT(num_stack_args >= 0); + + formals = (duk_hobject *) duk_hobject_get_formals(thr, (duk_hobject *) func); + if (formals) { + n_formals = (duk_idx_t) ((duk_harray *) formals)->length; + duk_push_hobject(thr, formals); + } else { + /* This shouldn't happen without tampering of internal + * properties: if a function accesses 'arguments', _Formals + * is kept. Check for the case anyway in case internal + * properties have been modified manually. + */ + DUK_D(DUK_DPRINT("_Formals is undefined when creating arguments, use n_formals == 0")); + n_formals = 0; + duk_push_undefined(thr); + } + i_formals = duk_require_top_index(thr); + + DUK_ASSERT(n_formals >= 0); + DUK_ASSERT(formals != NULL || n_formals == 0); + + DUK_DDD(DUK_DDDPRINT("func=%!O, formals=%!O, n_formals=%ld", + (duk_heaphdr *) func, (duk_heaphdr *) formals, + (long) n_formals)); + + /* [ ... formals ] */ + + /* + * Create required objects: + * - 'arguments' object: array-like, but not an array + * - 'map' object: internal object, tied to 'arguments' (bare) + * - 'mappedNames' object: temporary value used during construction (bare) + */ + + arg = duk_push_object_helper(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_FLAG_ARRAY_PART | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARGUMENTS), + DUK_BIDX_OBJECT_PROTOTYPE); + DUK_ASSERT(arg != NULL); + (void) duk_push_object_helper(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT), + -1); /* no prototype */ + (void) duk_push_object_helper(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_FLAG_FASTREFS | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT), + -1); /* no prototype */ + i_arg = duk_get_top(thr) - 3; + i_map = i_arg + 1; + i_mappednames = i_arg + 2; + DUK_ASSERT(!duk_is_bare_object(thr, -3)); /* arguments */ + DUK_ASSERT(duk_is_bare_object(thr, -2)); /* map */ + DUK_ASSERT(duk_is_bare_object(thr, -1)); /* mappedNames */ + + /* [ ... formals arguments map mappedNames ] */ + + DUK_DDD(DUK_DDDPRINT("created arguments related objects: " + "arguments at index %ld -> %!O " + "map at index %ld -> %!O " + "mappednames at index %ld -> %!O", + (long) i_arg, (duk_heaphdr *) duk_get_hobject(thr, i_arg), + (long) i_map, (duk_heaphdr *) duk_get_hobject(thr, i_map), + (long) i_mappednames, (duk_heaphdr *) duk_get_hobject(thr, i_mappednames))); + + /* + * Init arguments properties, map, etc. + */ + + duk_push_int(thr, num_stack_args); + duk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_WC); + + /* + * Init argument related properties. + */ + + /* step 11 */ + idx = num_stack_args - 1; + while (idx >= 0) { + DUK_DDD(DUK_DDDPRINT("arg idx %ld, argbase=%ld, argidx=%ld", + (long) idx, (long) i_argbase, (long) (i_argbase + idx))); + + DUK_DDD(DUK_DDDPRINT("define arguments[%ld]=arg", (long) idx)); + duk_dup(thr, i_argbase + idx); + duk_xdef_prop_index_wec(thr, i_arg, (duk_uarridx_t) idx); + DUK_DDD(DUK_DDDPRINT("defined arguments[%ld]=arg", (long) idx)); + + /* step 11.c is relevant only if non-strict (checked in 11.c.ii) */ + if (!DUK_HOBJECT_HAS_STRICT(func) && idx < n_formals) { + DUK_ASSERT(formals != NULL); + + DUK_DDD(DUK_DDDPRINT("strict function, index within formals (%ld < %ld)", + (long) idx, (long) n_formals)); + + duk_get_prop_index(thr, i_formals, (duk_uarridx_t) idx); + DUK_ASSERT(duk_is_string(thr, -1)); + + duk_dup_top(thr); /* [ ... name name ] */ + + if (!duk_has_prop(thr, i_mappednames)) { + /* steps 11.c.ii.1 - 11.c.ii.4, but our internal book-keeping + * differs from the reference model + */ + + /* [ ... name ] */ + + need_map = 1; + + DUK_DDD(DUK_DDDPRINT("set mappednames[%s]=%ld", + (const char *) duk_get_string(thr, -1), + (long) idx)); + duk_dup_top(thr); /* name */ + (void) duk_push_uint_to_hstring(thr, (duk_uint_t) idx); /* index */ + duk_xdef_prop_wec(thr, i_mappednames); /* out of spec, must be configurable */ + + DUK_DDD(DUK_DDDPRINT("set map[%ld]=%s", + (long) idx, + duk_get_string(thr, -1))); + duk_dup_top(thr); /* name */ + duk_xdef_prop_index_wec(thr, i_map, (duk_uarridx_t) idx); /* out of spec, must be configurable */ + } else { + /* duk_has_prop() popped the second 'name' */ + } + + /* [ ... name ] */ + duk_pop(thr); /* pop 'name' */ + } + + idx--; + } + + DUK_DDD(DUK_DDDPRINT("actual arguments processed")); + + /* step 12 */ + if (need_map) { + DUK_DDD(DUK_DDDPRINT("adding 'map' and 'varenv' to arguments object")); + + /* should never happen for a strict callee */ + DUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(func)); + + duk_dup(thr, i_map); + duk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_INT_MAP, DUK_PROPDESC_FLAGS_NONE); /* out of spec, don't care */ + + /* The variable environment for magic variable bindings needs to be + * given by the caller and recorded in the arguments object. + * + * See E5 Section 10.6, the creation of setters/getters. + * + * The variable environment also provides access to the callee, so + * an explicit (internal) callee property is not needed. + */ + + duk_push_hobject(thr, varenv); + duk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_INT_VARENV, DUK_PROPDESC_FLAGS_NONE); /* out of spec, don't care */ + } + + /* steps 13-14 */ + if (DUK_HOBJECT_HAS_STRICT(func)) { + /* Callee/caller are throwers and are not deletable etc. They + * could be implemented as virtual properties, but currently + * there is no support for virtual properties which are accessors + * (only plain virtual properties). This would not be difficult + * to change in duk_hobject_props, but we can make the throwers + * normal, concrete properties just as easily. + * + * Note that the specification requires that the *same* thrower + * built-in object is used here! See E5 Section 10.6 main + * algoritm, step 14, and Section 13.2.3 which describes the + * thrower. See test case test-arguments-throwers.js. + */ + + DUK_DDD(DUK_DDDPRINT("strict function, setting caller/callee to throwers")); + + /* In ES2017 .caller is no longer set at all. */ + duk_xdef_prop_stridx_thrower(thr, i_arg, DUK_STRIDX_CALLEE); + } else { + DUK_DDD(DUK_DDDPRINT("non-strict function, setting callee to actual value")); + duk_push_hobject(thr, func); + duk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_CALLEE, DUK_PROPDESC_FLAGS_WC); + } + + /* set exotic behavior only after we're done */ + if (need_map) { + /* Exotic behaviors are only enabled for arguments objects + * which have a parameter map (see E5 Section 10.6 main + * algorithm, step 12). + * + * In particular, a non-strict arguments object with no + * mapped formals does *NOT* get exotic behavior, even + * for e.g. "caller" property. This seems counterintuitive + * but seems to be the case. + */ + + /* cannot be strict (never mapped variables) */ + DUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(func)); + + DUK_DDD(DUK_DDDPRINT("enabling exotic behavior for arguments object")); + DUK_HOBJECT_SET_EXOTIC_ARGUMENTS(arg); + } else { + DUK_DDD(DUK_DDDPRINT("not enabling exotic behavior for arguments object")); + } + + DUK_DDD(DUK_DDDPRINT("final arguments related objects: " + "arguments at index %ld -> %!O " + "map at index %ld -> %!O " + "mappednames at index %ld -> %!O", + (long) i_arg, (duk_heaphdr *) duk_get_hobject(thr, i_arg), + (long) i_map, (duk_heaphdr *) duk_get_hobject(thr, i_map), + (long) i_mappednames, (duk_heaphdr *) duk_get_hobject(thr, i_mappednames))); + + /* [ args(n) envobj formals arguments map mappednames ] */ + + duk_pop_2(thr); + duk_remove_m2(thr); + + /* [ args(n) envobj arguments ] */ +} + +/* Helper for creating the arguments object and adding it to the env record + * on top of the value stack. + */ +DUK_LOCAL void duk__handle_createargs_for_call(duk_hthread *thr, + duk_hobject *func, + duk_hobject *env, + duk_idx_t idx_args) { + DUK_DDD(DUK_DDDPRINT("creating arguments object for function call")); + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(func != NULL); + DUK_ASSERT(env != NULL); + DUK_ASSERT(DUK_HOBJECT_HAS_CREATEARGS(func)); + + /* [ ... arg1 ... argN envobj ] */ + + duk__create_arguments_object(thr, + func, + env, + idx_args); + + /* [ ... arg1 ... argN envobj argobj ] */ + + duk_xdef_prop_stridx_short(thr, + -2, + DUK_STRIDX_LC_ARGUMENTS, + DUK_HOBJECT_HAS_STRICT(func) ? DUK_PROPDESC_FLAGS_E : /* strict: non-deletable, non-writable */ + DUK_PROPDESC_FLAGS_WE); /* non-strict: non-deletable, writable */ + /* [ ... arg1 ... argN envobj ] */ +} + +/* + * Helpers for constructor call handling. + * + * There are two [[Construct]] operations in the specification: + * + * - E5 Section 13.2.2: for Function objects + * - E5 Section 15.3.4.5.2: for "bound" Function objects + * + * The chain of bound functions is resolved in Section 15.3.4.5.2, + * with arguments "piling up" until the [[Construct]] internal + * method is called on the final, actual Function object. Note + * that the "prototype" property is looked up *only* from the + * final object, *before* calling the constructor. + * + * Since Duktape 2.2 bound functions are represented with the + * duk_hboundfunc internal type, and bound function chains are + * collapsed when a bound function is created. As a result, the + * direct target of a duk_hboundfunc is always non-bound and the + * this/argument lists have been resolved. + * + * When constructing new Array instances, an unnecessary object is + * created and discarded now: the standard [[Construct]] creates an + * object, and calls the Array constructor. The Array constructor + * returns an Array instance, which is used as the result value for + * the "new" operation; the object created before the Array constructor + * call is discarded. + * + * This would be easy to fix, e.g. by knowing that the Array constructor + * will always create a replacement object and skip creating the fallback + * object in that case. + */ + +/* Update default instance prototype for constructor call. */ +DUK_LOCAL void duk__update_default_instance_proto(duk_hthread *thr, duk_idx_t idx_func) { + duk_hobject *proto; + duk_hobject *fallback; + + DUK_ASSERT(duk_is_constructable(thr, idx_func)); + + duk_get_prop_stridx_short(thr, idx_func, DUK_STRIDX_PROTOTYPE); + proto = duk_get_hobject(thr, -1); + if (proto == NULL) { + DUK_DDD(DUK_DDDPRINT("constructor has no 'prototype' property, or value not an object " + "-> leave standard Object prototype as fallback prototype")); + } else { + DUK_DDD(DUK_DDDPRINT("constructor has 'prototype' property with object value " + "-> set fallback prototype to that value: %!iO", (duk_heaphdr *) proto)); + /* Original fallback (default instance) is untouched when + * resolving bound functions etc. + */ + fallback = duk_known_hobject(thr, idx_func + 1); + DUK_ASSERT(fallback != NULL); + DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, fallback, proto); + } + duk_pop(thr); +} + +/* Postprocess: return value special handling, error augmentation. */ +DUK_INTERNAL void duk_call_construct_postprocess(duk_hthread *thr, duk_small_uint_t proxy_invariant) { + /* Use either fallback (default instance) or retval depending + * on retval type. Needs to be called before unwind because + * the default instance is read from the current (immutable) + * 'this' binding. + * + * For Proxy 'construct' calls the return value must be an + * Object (we accept object-like values like buffers and + * lightfuncs too). If not, TypeError. + */ + if (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT | + DUK_TYPE_MASK_BUFFER | + DUK_TYPE_MASK_LIGHTFUNC)) { + DUK_DDD(DUK_DDDPRINT("replacement value")); + } else { + if (DUK_UNLIKELY(proxy_invariant != 0U)) { + /* Proxy 'construct' return value invariant violated. */ + DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr); + DUK_WO_NORETURN(return;); + } + /* XXX: direct value stack access */ + duk_pop(thr); + duk_push_this(thr); + } + +#if defined(DUK_USE_AUGMENT_ERROR_CREATE) + /* Augment created errors upon creation, not when they are thrown or + * rethrown. __FILE__ and __LINE__ are not desirable here; the call + * stack reflects the caller which is correct. Skip topmost, unwound + * activation when creating a traceback. If thr->ptr_curr_pc was != + * NULL we'd need to sync the current PC so that the traceback comes + * out right; however it is always synced here so just assert for it. + */ + DUK_ASSERT(thr->ptr_curr_pc == NULL); + duk_err_augment_error_create(thr, thr, NULL, 0, DUK_AUGMENT_FLAG_NOBLAME_FILELINE | + DUK_AUGMENT_FLAG_SKIP_ONE); +#endif +} + +/* + * Helper for handling a bound function when a call is being made. + * + * Assumes that bound function chains have been "collapsed" so that either + * the target is non-bound or there is one bound function that points to a + * nonbound target. + * + * Prepends the bound arguments to the value stack (at idx_func + 2). + * The 'this' binding is also updated if necessary (at idx_func + 1). + * Note that for constructor calls the 'this' binding is never updated by + * [[BoundThis]]. + */ + +DUK_LOCAL void duk__handle_bound_chain_for_call(duk_hthread *thr, + duk_idx_t idx_func, + duk_bool_t is_constructor_call) { + duk_tval *tv_func; + duk_hobject *func; + duk_idx_t len; + + DUK_ASSERT(thr != NULL); + + /* On entry, item at idx_func is a bound, non-lightweight function, + * but we don't rely on that below. + */ + + DUK_ASSERT(duk_get_top(thr) >= idx_func + 2); + + tv_func = duk_require_tval(thr, idx_func); + DUK_ASSERT(tv_func != NULL); + + if (DUK_TVAL_IS_OBJECT(tv_func)) { + func = DUK_TVAL_GET_OBJECT(tv_func); + + /* XXX: separate helper function, out of fast path? */ + if (DUK_HOBJECT_HAS_BOUNDFUNC(func)) { + duk_hboundfunc *h_bound; + duk_tval *tv_args; + duk_tval *tv_gap; + + h_bound = (duk_hboundfunc *) (void *) func; + tv_args = h_bound->args; + len = h_bound->nargs; + DUK_ASSERT(len == 0 || tv_args != NULL); + + DUK_DDD(DUK_DDDPRINT("bound function encountered, ptr=%p: %!T", + (void *) DUK_TVAL_GET_OBJECT(tv_func), tv_func)); + + /* [ ... func this arg1 ... argN ] */ + + if (is_constructor_call) { + /* See: tests/ecmascript/test-spec-bound-constructor.js */ + DUK_DDD(DUK_DDDPRINT("constructor call: don't update this binding")); + } else { + /* XXX: duk_replace_tval */ + duk_push_tval(thr, &h_bound->this_binding); + duk_replace(thr, idx_func + 1); /* idx_this = idx_func + 1 */ + } + + /* [ ... func this arg1 ... argN ] */ + + duk_require_stack(thr, len); + + tv_gap = duk_reserve_gap(thr, idx_func + 2, len); + duk_copy_tvals_incref(thr, tv_gap, tv_args, (duk_size_t) len); + + /* [ ... func this arg1 ... argN ] */ + + duk_push_tval(thr, &h_bound->target); + duk_replace(thr, idx_func); /* replace in stack */ + + DUK_DDD(DUK_DDDPRINT("bound function handled, idx_func=%ld, curr func=%!T", + (long) idx_func, duk_get_tval(thr, idx_func))); + } + } else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) { + /* Lightweight function: never bound, so terminate. */ + ; + } else { + /* Shouldn't happen, so ugly error is enough. */ + DUK_ERROR_INTERNAL(thr); + DUK_WO_NORETURN(return;); + } + + DUK_ASSERT(duk_get_top(thr) >= idx_func + 2); + + DUK_DDD(DUK_DDDPRINT("final non-bound function is: %!T", duk_get_tval(thr, idx_func))); + +#if defined(DUK_USE_ASSERTIONS) + tv_func = duk_require_tval(thr, idx_func); + DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func) || DUK_TVAL_IS_OBJECT(tv_func)); + if (DUK_TVAL_IS_OBJECT(tv_func)) { + func = DUK_TVAL_GET_OBJECT(tv_func); + DUK_ASSERT(func != NULL); + DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func)); + DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func) || + DUK_HOBJECT_HAS_NATFUNC(func) || + DUK_HOBJECT_IS_PROXY(func)); + } +#endif +} + +/* + * Helper for inline handling of .call(), .apply(), and .construct(). + */ + +DUK_LOCAL duk_bool_t duk__handle_specialfuncs_for_call(duk_hthread *thr, duk_idx_t idx_func, duk_hobject *func, duk_small_uint_t *call_flags, duk_bool_t first) { +#if defined(DUK_USE_ASSERTIONS) + duk_c_function natfunc; +#endif + duk_tval *tv_args; + + DUK_ASSERT(func != NULL); + DUK_ASSERT((*call_flags & DUK_CALL_FLAG_CONSTRUCT) == 0); /* Caller. */ + +#if defined(DUK_USE_ASSERTIONS) + natfunc = ((duk_hnatfunc *) func)->func; + DUK_ASSERT(natfunc != NULL); +#endif + + /* On every round of function resolution at least target function and + * 'this' binding are set. We can assume that here, and must guarantee + * it on exit. Value stack reserve is extended for bound function and + * .apply() unpacking so we don't need to extend it here when we need a + * few slots. + */ + DUK_ASSERT(duk_get_top(thr) >= idx_func + 2); + + /* Handle native 'eval' specially. A direct eval check is only made + * for the first resolution attempt; e.g. a bound eval call is -not- + * a direct eval call. + */ + if (DUK_UNLIKELY(((duk_hnatfunc *) func)->magic == 15)) { + /* For now no special handling except for direct eval + * detection. + */ + DUK_ASSERT(((duk_hnatfunc *) func)->func == duk_bi_global_object_eval); + if (first && (*call_flags & DUK_CALL_FLAG_CALLED_AS_EVAL)) { + *call_flags = (*call_flags & ~DUK_CALL_FLAG_CALLED_AS_EVAL) | DUK_CALL_FLAG_DIRECT_EVAL; + } + DUK_ASSERT(duk_get_top(thr) >= idx_func + 2); + return 1; /* stop resolving */ + } + + /* Handle special functions based on the DUK_HOBJECT_FLAG_SPECIAL_CALL + * flag; their magic value is used for switch-case. + * + * NOTE: duk_unpack_array_like() reserves value stack space + * for the result values (unlike most other value stack calls). + */ + switch (((duk_hnatfunc *) func)->magic) { + case 0: { /* 0=Function.prototype.call() */ + /* Value stack: + * idx_func + 0: Function.prototype.call() [removed] + * idx_func + 1: this binding for .call (target function) + * idx_func + 2: 1st argument to .call, desired 'this' binding + * idx_func + 3: 2nd argument to .call, desired 1st argument for ultimate target + * ... + * + * Remove idx_func + 0 to get: + * idx_func + 0: target function + * idx_func + 1: this binding + * idx_func + 2: call arguments + * ... + */ + DUK_ASSERT(natfunc == duk_bi_function_prototype_call); + duk_remove_unsafe(thr, idx_func); + tv_args = thr->valstack_bottom + idx_func + 2; + if (thr->valstack_top < tv_args) { + DUK_ASSERT(tv_args <= thr->valstack_end); + thr->valstack_top = tv_args; /* at least target function and 'this' binding present */ + } + break; + } + case 1: { /* 1=Function.prototype.apply() */ + /* Value stack: + * idx_func + 0: Function.prototype.apply() [removed] + * idx_func + 1: this binding for .apply (target function) + * idx_func + 2: 1st argument to .apply, desired 'this' binding + * idx_func + 3: 2nd argument to .apply, argArray + * [anything after this MUST be ignored] + * + * Remove idx_func + 0 and unpack the argArray to get: + * idx_func + 0: target function + * idx_func + 1: this binding + * idx_func + 2: call arguments + * ... + */ + DUK_ASSERT(natfunc == duk_bi_function_prototype_apply); + duk_remove_unsafe(thr, idx_func); + goto apply_shared; + } +#if defined(DUK_USE_REFLECT_BUILTIN) + case 2: { /* 2=Reflect.apply() */ + /* Value stack: + * idx_func + 0: Reflect.apply() [removed] + * idx_func + 1: this binding for .apply (ignored, usually Reflect) [removed] + * idx_func + 2: 1st argument to .apply, target function + * idx_func + 3: 2nd argument to .apply, desired 'this' binding + * idx_func + 4: 3rd argument to .apply, argArray + * [anything after this MUST be ignored] + * + * Remove idx_func + 0 and idx_func + 1, and unpack the argArray to get: + * idx_func + 0: target function + * idx_func + 1: this binding + * idx_func + 2: call arguments + * ... + */ + DUK_ASSERT(natfunc == duk_bi_reflect_apply); + duk_remove_n_unsafe(thr, idx_func, 2); + goto apply_shared; + } + case 3: { /* 3=Reflect.construct() */ + /* Value stack: + * idx_func + 0: Reflect.construct() [removed] + * idx_func + 1: this binding for .construct (ignored, usually Reflect) [removed] + * idx_func + 2: 1st argument to .construct, target function + * idx_func + 3: 2nd argument to .construct, argArray + * idx_func + 4: 3rd argument to .construct, newTarget + * [anything after this MUST be ignored] + * + * Remove idx_func + 0 and idx_func + 1, unpack the argArray, + * and insert default instance (prototype not yet updated), to get: + * idx_func + 0: target function + * idx_func + 1: this binding (default instance) + * idx_func + 2: constructor call arguments + * ... + * + * Call flags must be updated to reflect the fact that we're + * now dealing with a constructor call, and e.g. the 'this' + * binding cannot be overwritten if the target is bound. + * + * newTarget is checked but not yet passed onwards. + */ + + duk_idx_t top; + + DUK_ASSERT(natfunc == duk_bi_reflect_construct); + *call_flags |= DUK_CALL_FLAG_CONSTRUCT; + duk_remove_n_unsafe(thr, idx_func, 2); + top = duk_get_top(thr); + if (!duk_is_constructable(thr, idx_func)) { + /* Target constructability must be checked before + * unpacking argArray (which may cause side effects). + * Just return; caller will throw the error. + */ + duk_set_top_unsafe(thr, idx_func + 2); /* satisfy asserts */ + break; + } + duk_push_object(thr); + duk_insert(thr, idx_func + 1); /* default instance */ + + /* [ ... func default_instance argArray newTarget? ] */ + + top = duk_get_top(thr); + if (top < idx_func + 3) { + /* argArray is a mandatory argument for Reflect.construct(). */ + DUK_ERROR_TYPE_INVALID_ARGS(thr); + DUK_WO_NORETURN(return 0;); + } + if (top > idx_func + 3) { + if (!duk_strict_equals(thr, idx_func, idx_func + 3)) { + /* XXX: [[Construct]] newTarget currently unsupported */ + DUK_ERROR_UNSUPPORTED(thr); + DUK_WO_NORETURN(return 0;); + } + duk_set_top_unsafe(thr, idx_func + 3); /* remove any args beyond argArray */ + } + DUK_ASSERT(duk_get_top(thr) == idx_func + 3); + DUK_ASSERT(duk_is_valid_index(thr, idx_func + 2)); + (void) duk_unpack_array_like(thr, idx_func + 2); /* XXX: should also remove target to be symmetric with duk_pack()? */ + duk_remove(thr, idx_func + 2); + DUK_ASSERT(duk_get_top(thr) >= idx_func + 2); + break; + } +#endif /* DUK_USE_REFLECT_BUILTIN */ + default: { + DUK_ASSERT(0); + DUK_UNREACHABLE(); + } + } + + DUK_ASSERT(duk_get_top(thr) >= idx_func + 2); + return 0; /* keep resolving */ + + apply_shared: + tv_args = thr->valstack_bottom + idx_func + 2; + if (thr->valstack_top <= tv_args) { + DUK_ASSERT(tv_args <= thr->valstack_end); + thr->valstack_top = tv_args; /* at least target func and 'this' binding present */ + /* No need to check for argArray. */ + } else { + DUK_ASSERT(duk_get_top(thr) >= idx_func + 3); /* idx_func + 2 covered above */ + if (thr->valstack_top > tv_args + 1) { + duk_set_top_unsafe(thr, idx_func + 3); /* remove any args beyond argArray */ + } + DUK_ASSERT(duk_is_valid_index(thr, idx_func + 2)); + if (!duk_is_callable(thr, idx_func)) { + /* Avoid unpack side effects if the target isn't callable. + * Calling code will throw the actual error. + */ + } else { + (void) duk_unpack_array_like(thr, idx_func + 2); + duk_remove(thr, idx_func + 2); + } + } + DUK_ASSERT(duk_get_top(thr) >= idx_func + 2); + return 0; /* keep resolving */ +} + +/* + * Helper for Proxy handling. + */ + +#if defined(DUK_USE_ES6_PROXY) +DUK_LOCAL void duk__handle_proxy_for_call(duk_hthread *thr, duk_idx_t idx_func, duk_hproxy *h_proxy, duk_small_uint_t *call_flags) { + duk_bool_t rc; + + /* Value stack: + * idx_func + 0: Proxy object + * idx_func + 1: this binding for call + * idx_func + 2: 1st argument for call + * idx_func + 3: 2nd argument for call + * ... + * + * If Proxy doesn't have a trap for the call ('apply' or 'construct'), + * replace Proxy object with target object. + * + * If we're dealing with a normal call and the Proxy has an 'apply' + * trap, manipulate value stack to: + * + * idx_func + 0: trap + * idx_func + 1: Proxy's handler + * idx_func + 2: Proxy's target + * idx_func + 3: this binding for call (from idx_func + 1) + * idx_func + 4: call arguments packed to an array + * + * If we're dealing with a constructor call and the Proxy has a + * 'construct' trap, manipulate value stack to: + * + * idx_func + 0: trap + * idx_func + 1: Proxy's handler + * idx_func + 2: Proxy's target + * idx_func + 3: call arguments packed to an array + * idx_func + 4: newTarget == Proxy object here + * + * As we don't yet have proper newTarget support, the newTarget at + * idx_func + 3 is just the original constructor being called, i.e. + * the Proxy object (not the target). Note that the default instance + * (original 'this' binding) is dropped and ignored. + */ + + duk_push_hobject(thr, h_proxy->handler); + rc = duk_get_prop_stridx_short(thr, -1, (*call_flags & DUK_CALL_FLAG_CONSTRUCT) ? DUK_STRIDX_CONSTRUCT : DUK_STRIDX_APPLY); + if (rc == 0) { + /* Not found, continue to target. If this is a construct + * call, update default instance prototype using the Proxy, + * not the target. + */ + if (*call_flags & DUK_CALL_FLAG_CONSTRUCT) { + if (!(*call_flags & DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED)) { + *call_flags |= DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED; + duk__update_default_instance_proto(thr, idx_func); + } + } + duk_pop_2(thr); + duk_push_hobject(thr, h_proxy->target); + duk_replace(thr, idx_func); + return; + } + + /* Here we must be careful not to replace idx_func while + * h_proxy is still needed, otherwise h_proxy may become + * dangling. This could be improved e.g. using a + * duk_pack_slice() with a freeform slice. + */ + + /* Here: + * idx_func + 0: Proxy object + * idx_func + 1: this binding for call + * idx_func + 2: 1st argument for call + * idx_func + 3: 2nd argument for call + * ... + * idx_func + N: handler + * idx_func + N + 1: trap + */ + + duk_insert(thr, idx_func + 1); + duk_insert(thr, idx_func + 2); + duk_push_hobject(thr, h_proxy->target); + duk_insert(thr, idx_func + 3); + duk_pack(thr, duk_get_top(thr) - (idx_func + 5)); + DUK_ASSERT(!duk_is_bare_object(thr, -1)); + + /* Here: + * idx_func + 0: Proxy object + * idx_func + 1: trap + * idx_func + 2: Proxy's handler + * idx_func + 3: Proxy's target + * idx_func + 4: this binding for call + * idx_func + 5: arguments array + */ + DUK_ASSERT(duk_get_top(thr) == idx_func + 6); + + if (*call_flags & DUK_CALL_FLAG_CONSTRUCT) { + *call_flags |= DUK_CALL_FLAG_CONSTRUCT_PROXY; /* Enable 'construct' trap return invariant check. */ + *call_flags &= ~(DUK_CALL_FLAG_CONSTRUCT); /* Resume as non-constructor call to the trap. */ + + /* 'apply' args: target, thisArg, argArray + * 'construct' args: target, argArray, newTarget + */ + duk_remove(thr, idx_func + 4); + duk_push_hobject(thr, (duk_hobject *) h_proxy); + } + + /* Finalize value stack layout by removing Proxy reference. */ + duk_remove(thr, idx_func); + h_proxy = NULL; /* invalidated */ + DUK_ASSERT(duk_get_top(thr) == idx_func + 5); +} +#endif /* DUK_USE_ES6_PROXY */ + +/* + * Helper for setting up var_env and lex_env of an activation, + * assuming it does NOT have the DUK_HOBJECT_FLAG_NEWENV flag. + */ + +DUK_LOCAL void duk__handle_oldenv_for_call(duk_hthread *thr, + duk_hobject *func, + duk_activation *act) { + duk_hcompfunc *f; + duk_hobject *h_lex; + duk_hobject *h_var; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(func != NULL); + DUK_ASSERT(act != NULL); + DUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV(func)); + DUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(func)); + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(func)); + DUK_UNREF(thr); + + f = (duk_hcompfunc *) func; + h_lex = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, f); + h_var = DUK_HCOMPFUNC_GET_VARENV(thr->heap, f); + DUK_ASSERT(h_lex != NULL); /* Always true for closures (not for templates) */ + DUK_ASSERT(h_var != NULL); + act->lex_env = h_lex; + act->var_env = h_var; + DUK_HOBJECT_INCREF(thr, h_lex); + DUK_HOBJECT_INCREF(thr, h_var); +} + +/* + * Helper for updating callee 'caller' property. + */ + +#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY) +DUK_LOCAL void duk__update_func_caller_prop(duk_hthread *thr, duk_hobject *func) { + duk_tval *tv_caller; + duk_hobject *h_tmp; + duk_activation *act_callee; + duk_activation *act_caller; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(func != NULL); + DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func)); /* bound chain resolved */ + DUK_ASSERT(thr->callstack_top >= 1); + + if (DUK_HOBJECT_HAS_STRICT(func)) { + /* Strict functions don't get their 'caller' updated. */ + return; + } + + DUK_ASSERT(thr->callstack_top > 0); + act_callee = thr->callstack_curr; + DUK_ASSERT(act_callee != NULL); + act_caller = (thr->callstack_top >= 2 ? act_callee->parent : NULL); + + /* XXX: check .caller writability? */ + + /* Backup 'caller' property and update its value. */ + tv_caller = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, func, DUK_STRIDX_CALLER); + if (tv_caller) { + /* If caller is global/eval code, 'caller' should be set to + * 'null'. + * + * XXX: there is no exotic flag to infer this correctly now. + * The NEWENV flag is used now which works as intended for + * everything (global code, non-strict eval code, and functions) + * except strict eval code. Bound functions are never an issue + * because 'func' has been resolved to a non-bound function. + */ + + if (act_caller != NULL) { + /* act_caller->func may be NULL in some finalization cases, + * just treat like we don't know the caller. + */ + if (act_caller->func && !DUK_HOBJECT_HAS_NEWENV(act_caller->func)) { + /* Setting to NULL causes 'caller' to be set to + * 'null' as desired. + */ + act_caller = NULL; + } + } + + if (DUK_TVAL_IS_OBJECT(tv_caller)) { + h_tmp = DUK_TVAL_GET_OBJECT(tv_caller); + DUK_ASSERT(h_tmp != NULL); + act_callee->prev_caller = h_tmp; + + /* Previous value doesn't need refcount changes because its ownership + * is transferred to prev_caller. + */ + + if (act_caller != NULL) { + DUK_ASSERT(act_caller->func != NULL); + DUK_TVAL_SET_OBJECT(tv_caller, act_caller->func); + DUK_TVAL_INCREF(thr, tv_caller); + } else { + DUK_TVAL_SET_NULL(tv_caller); /* no incref */ + } + } else { + /* 'caller' must only take on 'null' or function value */ + DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_caller)); + DUK_ASSERT(act_callee->prev_caller == NULL); + if (act_caller != NULL && act_caller->func) { + /* Tolerate act_caller->func == NULL which happens in + * some finalization cases; treat like unknown caller. + */ + DUK_TVAL_SET_OBJECT(tv_caller, act_caller->func); + DUK_TVAL_INCREF(thr, tv_caller); + } else { + DUK_TVAL_SET_NULL(tv_caller); /* no incref */ + } + } + } +} +#endif /* DUK_USE_NONSTD_FUNC_CALLER_PROPERTY */ + +/* + * Shared helpers for resolving the final, non-bound target function of the + * call and the effective 'this' binding. Resolves bound functions and + * applies .call(), .apply(), and .construct() inline. + * + * Proxy traps are also handled inline so that if the target is a Proxy with + * a 'call' or 'construct' trap, the trap handler is called with a modified + * argument list. + * + * Once the bound function / .call() / .apply() / .construct() sequence has + * been resolved, the value at idx_func + 1 may need coercion described in + * E5 Section 10.4.3. + * + * A call that begins as a non-constructor call may be converted into a + * constructor call during the resolution process if Reflect.construct() + * is invoked. This is handled by updating the caller's call_flags. + * + * For global and eval code (E5 Sections 10.4.1 and 10.4.2), we assume + * that the caller has provided the correct 'this' binding explicitly + * when calling, i.e.: + * + * - global code: this=global object + * - direct eval: this=copy from eval() caller's this binding + * - other eval: this=global object + * + * The 'this' coercion may cause a recursive function call with arbitrary + * side effects, because ToObject() may be called. + */ + +DUK_LOCAL DUK_INLINE void duk__coerce_nonstrict_this_binding(duk_hthread *thr, duk_idx_t idx_this) { + duk_tval *tv_this; + duk_hobject *obj_global; + + tv_this = thr->valstack_bottom + idx_this; + switch (DUK_TVAL_GET_TAG(tv_this)) { + case DUK_TAG_OBJECT: + DUK_DDD(DUK_DDDPRINT("this binding: non-strict, object -> use directly")); + break; + case DUK_TAG_UNDEFINED: + case DUK_TAG_NULL: + DUK_DDD(DUK_DDDPRINT("this binding: non-strict, undefined/null -> use global object")); + obj_global = thr->builtins[DUK_BIDX_GLOBAL]; + /* XXX: avoid this check somehow */ + if (DUK_LIKELY(obj_global != NULL)) { + DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_this)); /* no need to decref previous value */ + DUK_TVAL_SET_OBJECT(tv_this, obj_global); + DUK_HOBJECT_INCREF(thr, obj_global); + } else { + /* This may only happen if built-ins are being "torn down". + * This behavior is out of specification scope. + */ + DUK_D(DUK_DPRINT("this binding: wanted to use global object, but it is NULL -> using undefined instead")); + DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_this)); /* no need to decref previous value */ + DUK_TVAL_SET_UNDEFINED(tv_this); /* nothing to incref */ + } + break; + default: + /* Plain buffers and lightfuncs are object coerced. Lightfuncs + * very rarely come here however, because the call target would + * need to be a non-strict non-lightfunc (lightfuncs are considered + * strict) with an explicit lightfunc 'this' binding. + */ + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_this)); + DUK_DDD(DUK_DDDPRINT("this binding: non-strict, not object/undefined/null -> use ToObject(value)")); + duk_to_object(thr, idx_this); /* may have side effects */ + break; + } +} + +DUK_LOCAL DUK_ALWAYS_INLINE duk_bool_t duk__resolve_target_fastpath_check(duk_hthread *thr, duk_idx_t idx_func, duk_hobject **out_func, duk_small_uint_t call_flags) { +#if defined(DUK_USE_PREFER_SIZE) + DUK_UNREF(thr); + DUK_UNREF(idx_func); + DUK_UNREF(out_func); + DUK_UNREF(call_flags); +#else /* DUK_USE_PREFER_SIZE */ + duk_tval *tv_func; + duk_hobject *func; + + if (DUK_UNLIKELY(call_flags & DUK_CALL_FLAG_CONSTRUCT)) { + return 0; + } + + tv_func = DUK_GET_TVAL_POSIDX(thr, idx_func); + DUK_ASSERT(tv_func != NULL); + + if (DUK_LIKELY(DUK_TVAL_IS_OBJECT(tv_func))) { + func = DUK_TVAL_GET_OBJECT(tv_func); + if (DUK_HOBJECT_IS_CALLABLE(func) && + !DUK_HOBJECT_HAS_BOUNDFUNC(func) && + !DUK_HOBJECT_HAS_SPECIAL_CALL(func)) { + *out_func = func; + + if (DUK_HOBJECT_HAS_STRICT(func)) { + /* Strict function: no 'this' coercion. */ + return 1; + } + + duk__coerce_nonstrict_this_binding(thr, idx_func + 1); + return 1; + } + } else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) { + *out_func = NULL; + + /* Lightfuncs are considered strict, so 'this' binding is + * used as is. They're never bound, always constructable, + * and never special functions. + */ + return 1; + } +#endif /* DUK_USE_PREFER_SIZE */ + return 0; /* let slow path deal with it */ +} + +DUK_LOCAL duk_hobject *duk__resolve_target_func_and_this_binding(duk_hthread *thr, + duk_idx_t idx_func, + duk_small_uint_t *call_flags) { + duk_tval *tv_func; + duk_hobject *func; + duk_bool_t first; + + DUK_ASSERT(duk_get_top(thr) >= idx_func + 2); + + for (first = 1;; first = 0) { + DUK_ASSERT(duk_get_top(thr) >= idx_func + 2); + + tv_func = DUK_GET_TVAL_POSIDX(thr, idx_func); + DUK_ASSERT(tv_func != NULL); + + DUK_DD(DUK_DDPRINT("target func: %!iT", tv_func)); + + if (DUK_TVAL_IS_OBJECT(tv_func)) { + func = DUK_TVAL_GET_OBJECT(tv_func); + + if (*call_flags & DUK_CALL_FLAG_CONSTRUCT) { + if (DUK_UNLIKELY(!DUK_HOBJECT_HAS_CONSTRUCTABLE(func))) { + goto not_constructable; + } + } else { + if (DUK_UNLIKELY(!DUK_HOBJECT_IS_CALLABLE(func))) { + goto not_callable; + } + } + + if (DUK_LIKELY(!DUK_HOBJECT_HAS_BOUNDFUNC(func) && + !DUK_HOBJECT_HAS_SPECIAL_CALL(func) && + !DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(func))) { + /* Common case, so test for using a single bitfield test. + * Break out to handle this coercion etc. + */ + break; + } + + /* XXX: could set specialcall for boundfuncs too, simplify check above */ + + if (DUK_HOBJECT_HAS_BOUNDFUNC(func)) { + DUK_ASSERT(!DUK_HOBJECT_HAS_SPECIAL_CALL(func)); + DUK_ASSERT(!DUK_HOBJECT_IS_NATFUNC(func)); + + /* Callable/constructable flags are the same + * for the bound function and its target, so + * we don't need to check them here, we can + * check them from the target only. + */ + duk__handle_bound_chain_for_call(thr, idx_func, *call_flags & DUK_CALL_FLAG_CONSTRUCT); + + DUK_ASSERT(DUK_TVAL_IS_OBJECT(duk_require_tval(thr, idx_func)) || + DUK_TVAL_IS_LIGHTFUNC(duk_require_tval(thr, idx_func))); + } else { + DUK_ASSERT(DUK_HOBJECT_HAS_SPECIAL_CALL(func)); + +#if defined(DUK_USE_ES6_PROXY) + if (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(func)) { + /* If no trap, resume processing from Proxy trap. + * If trap exists, helper converts call into a trap + * call; this may change a constructor call into a + * normal (non-constructor) trap call. We must + * continue processing even when a trap is found as + * the trap may be bound. + */ + duk__handle_proxy_for_call(thr, idx_func, (duk_hproxy *) func, call_flags); + } + else +#endif + { + DUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(func)); + DUK_ASSERT(DUK_HOBJECT_HAS_CALLABLE(func)); + DUK_ASSERT(!DUK_HOBJECT_HAS_CONSTRUCTABLE(func)); + /* Constructable check already done above. */ + + if (duk__handle_specialfuncs_for_call(thr, idx_func, func, call_flags, first) != 0) { + /* Encountered native eval call, normal call + * context. Break out, handle this coercion etc. + */ + break; + } + } + } + /* Retry loop. */ + } else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) { + /* Lightfuncs are: + * - Always strict, so no 'this' coercion. + * - Always callable. + * - Always constructable. + * - Never specialfuncs. + */ + func = NULL; + goto finished; + } else { + goto not_callable; + } + } + + DUK_ASSERT(func != NULL); + + if (!DUK_HOBJECT_HAS_STRICT(func)) { + /* Non-strict target needs 'this' coercion. + * This has potential side effects invalidating + * 'tv_func'. + */ + duk__coerce_nonstrict_this_binding(thr, idx_func + 1); + } + if (*call_flags & DUK_CALL_FLAG_CONSTRUCT) { + if (!(*call_flags & DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED)) { + *call_flags |= DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED; + duk__update_default_instance_proto(thr, idx_func); + } + } + + finished: + +#if defined(DUK_USE_ASSERTIONS) + { + duk_tval *tv_tmp; + + tv_tmp = duk_get_tval(thr, idx_func); + DUK_ASSERT(tv_tmp != NULL); + + DUK_ASSERT((DUK_TVAL_IS_OBJECT(tv_tmp) && DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(tv_tmp))) || + DUK_TVAL_IS_LIGHTFUNC(tv_tmp)); + DUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func)); + DUK_ASSERT(func == NULL || (DUK_HOBJECT_IS_COMPFUNC(func) || + DUK_HOBJECT_IS_NATFUNC(func))); + DUK_ASSERT(func == NULL || (DUK_HOBJECT_HAS_CONSTRUCTABLE(func) || + (*call_flags & DUK_CALL_FLAG_CONSTRUCT) == 0)); + } +#endif + + return func; + + not_callable: + DUK_ASSERT(tv_func != NULL); + +#if defined(DUK_USE_VERBOSE_ERRORS) + /* GETPROPC delayed error handling: when target is not callable, + * GETPROPC replaces idx_func+0 with a non-callable wrapper object + * with a hidden Symbol to signify it's to be handled here. If + * found, unwrap the original Error and throw it as is here. The + * hidden Symbol is only checked as an own property, not inherited + * (which would be dangerous). + */ + if (DUK_TVAL_IS_OBJECT(tv_func)) { + duk_tval *tv_wrap = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, DUK_TVAL_GET_OBJECT(tv_func), DUK_STRIDX_INT_TARGET); + if (tv_wrap != NULL) { + DUK_DD(DUK_DDPRINT("delayed error from GETPROPC: %!T", tv_wrap)); + duk_push_tval(thr, tv_wrap); + (void) duk_throw(thr); + DUK_WO_NORETURN(return NULL;); + } + } +#endif + +#if defined(DUK_USE_VERBOSE_ERRORS) +#if defined(DUK_USE_PARANOID_ERRORS) + DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "%s not callable", duk_get_type_name(thr, idx_func)); +#else + DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "%s not callable", duk_push_string_tval_readable(thr, tv_func)); +#endif +#else + DUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE); +#endif + DUK_WO_NORETURN(return NULL;); + + not_constructable: + /* For now GETPROPC delayed error not needed for constructor calls. */ +#if defined(DUK_USE_VERBOSE_ERRORS) +#if defined(DUK_USE_PARANOID_ERRORS) + DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "%s not constructable", duk_get_type_name(thr, idx_func)); +#else + DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "%s not constructable", duk_push_string_tval_readable(thr, tv_func)); +#endif +#else + DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONSTRUCTABLE); +#endif + DUK_WO_NORETURN(return NULL;); +} + +/* + * Manipulate value stack so that exactly 'num_stack_rets' return + * values are at 'idx_retbase' in every case, assuming there are + * 'rc' return values on top of stack. + * + * This is a bit tricky, because the called C function operates in + * the same activation record and may have e.g. popped the stack + * empty (below idx_retbase). + */ + +DUK_LOCAL void duk__safe_call_adjust_valstack(duk_hthread *thr, duk_idx_t idx_retbase, duk_idx_t num_stack_rets, duk_idx_t num_actual_rets) { + duk_idx_t idx_rcbase; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(idx_retbase >= 0); + DUK_ASSERT(num_stack_rets >= 0); + DUK_ASSERT(num_actual_rets >= 0); + + idx_rcbase = duk_get_top(thr) - num_actual_rets; /* base of known return values */ + if (DUK_UNLIKELY(idx_rcbase < 0)) { + DUK_ERROR_TYPE(thr, DUK_STR_INVALID_CFUNC_RC); + DUK_WO_NORETURN(return;); + } + + DUK_DDD(DUK_DDDPRINT("adjust valstack after func call: " + "num_stack_rets=%ld, num_actual_rets=%ld, stack_top=%ld, idx_retbase=%ld, idx_rcbase=%ld", + (long) num_stack_rets, (long) num_actual_rets, (long) duk_get_top(thr), + (long) idx_retbase, (long) idx_rcbase)); + + DUK_ASSERT(idx_rcbase >= 0); /* caller must check */ + + /* Space for num_stack_rets was reserved before the safe call. + * Because value stack reserve cannot shrink except in call returns, + * the reserve is still in place. Adjust valstack, carefully + * ensuring we don't overstep the reserve. + */ + + /* Match idx_rcbase with idx_retbase so that the return values + * start at the correct index. + */ + if (idx_rcbase > idx_retbase) { + duk_idx_t count = idx_rcbase - idx_retbase; + + DUK_DDD(DUK_DDDPRINT("elements at/after idx_retbase have enough to cover func retvals " + "(idx_retbase=%ld, idx_rcbase=%ld)", (long) idx_retbase, (long) idx_rcbase)); + + /* Remove values between irc_rcbase (start of intended return + * values) and idx_retbase to lower return values to idx_retbase. + */ + DUK_ASSERT(count > 0); + duk_remove_n(thr, idx_retbase, count); /* may be NORZ */ + } else { + duk_idx_t count = idx_retbase - idx_rcbase; + + DUK_DDD(DUK_DDDPRINT("not enough elements at/after idx_retbase to cover func retvals " + "(idx_retbase=%ld, idx_rcbase=%ld)", (long) idx_retbase, (long) idx_rcbase)); + + /* Insert 'undefined' at idx_rcbase (start of intended return + * values) to lift return values to idx_retbase. + */ + DUK_ASSERT(count >= 0); + DUK_ASSERT(thr->valstack_end - thr->valstack_top >= count); /* reserve cannot shrink */ + duk_insert_undefined_n(thr, idx_rcbase, count); + } + + /* Chop extra retvals away / extend with undefined. */ + duk_set_top_unsafe(thr, idx_retbase + num_stack_rets); +} + +/* + * Activation setup for tailcalls and non-tailcalls. + */ + +#if defined(DUK_USE_TAILCALL) +DUK_LOCAL duk_small_uint_t duk__call_setup_act_attempt_tailcall(duk_hthread *thr, + duk_small_uint_t call_flags, + duk_idx_t idx_func, + duk_hobject *func, + duk_size_t entry_valstack_bottom_byteoff, + duk_size_t entry_valstack_end_byteoff, + duk_idx_t *out_nargs, + duk_idx_t *out_nregs, + duk_size_t *out_vs_min_bytes, + duk_activation **out_act) { + duk_activation *act; + duk_tval *tv1, *tv2; + duk_idx_t idx_args; + duk_small_uint_t flags1, flags2; +#if defined(DUK_USE_DEBUGGER_SUPPORT) + duk_activation *prev_pause_act; +#endif + + DUK_UNREF(entry_valstack_end_byteoff); + + /* Tailcall cannot be flagged to resume calls, and a + * previous frame must exist. + */ + DUK_ASSERT(thr->callstack_top >= 1); + + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + *out_act = act; + + if (func == NULL || !DUK_HOBJECT_IS_COMPFUNC(func)) { + DUK_DDD(DUK_DDDPRINT("tail call prevented by target not being ecma function")); + return 0; + } + if (act->flags & DUK_ACT_FLAG_PREVENT_YIELD) { + DUK_DDD(DUK_DDDPRINT("tail call prevented by current activation having DUK_ACT_FLAG_PREVENT_YIELD")); + return 0; + } + /* Tailcall is only allowed if current and candidate + * function have identical return value handling. There + * are three possible return value handling cases: + * 1. Normal function call, no special return value handling. + * 2. Constructor call, return value replacement object check. + * 3. Proxy 'construct' trap call, return value invariant check. + */ + flags1 = (duk_small_uint_t) ((act->flags & DUK_ACT_FLAG_CONSTRUCT) ? 1 : 0) +#if defined(DUK_USE_ES6_PROXY) + | (duk_small_uint_t) ((act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) ? 2 : 0) +#endif + ; + flags2 = (duk_small_uint_t) ((call_flags & DUK_CALL_FLAG_CONSTRUCT) ? 1 : 0) +#if defined(DUK_USE_ES6_PROXY) + | (duk_small_uint_t) ((call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) ? 2 : 0); +#endif + ; + if (flags1 != flags2) { + DUK_DDD(DUK_DDDPRINT("tail call prevented by incompatible return value handling")); + return 0; + } + DUK_ASSERT(((act->flags & DUK_ACT_FLAG_CONSTRUCT) && (call_flags & DUK_CALL_FLAG_CONSTRUCT)) || + (!(act->flags & DUK_ACT_FLAG_CONSTRUCT) && !(call_flags & DUK_CALL_FLAG_CONSTRUCT))); + DUK_ASSERT(((act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) && (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY)) || + (!(act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) && !(call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY))); + if (DUK_HOBJECT_HAS_NOTAIL(func)) { + /* See: test-bug-tailcall-preventyield-assert.c. */ + DUK_DDD(DUK_DDDPRINT("tail call prevented by function having a notail flag")); + return 0; + } + + /* + * Tailcall handling + * + * Although the callstack entry is reused, we need to explicitly unwind + * the current activation (or simulate an unwind). In particular, the + * current activation must be closed, otherwise something like + * test-bug-reduce-judofyr.js results. Also catchers need to be unwound + * because there may be non-error-catching label entries in valid tail calls. + * + * Special attention is needed for debugger and pause behavior when + * reusing an activation. + * - Disable StepOut processing for the activation unwind because + * we reuse the activation, see: + * https://github.com/svaarala/duktape/issues/1684. + * - Disable line change pause flag permanently if act == dbg_pause_act + * (if set) because it would no longer be relevant, see: + * https://github.com/svaarala/duktape/issues/1726, + * https://github.com/svaarala/duktape/issues/1786. + * - Check for function entry (e.g. StepInto) pause flag here, because + * the executor pause check won't trigger due to shared activation, see: + * https://github.com/svaarala/duktape/issues/1726. + */ + + DUK_DDD(DUK_DDDPRINT("is tail call, reusing activation at callstack top, at index %ld", + (long) (thr->callstack_top - 1))); + + DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func)); + DUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(func)); + DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func)); + DUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0); + DUK_ASSERT(call_flags & DUK_CALL_FLAG_ALLOW_ECMATOECMA); + + /* Unwind the topmost callstack entry before reusing it. This + * also unwinds the catchers related to the topmost entry. + */ + DUK_ASSERT(thr->callstack_top > 0); + DUK_ASSERT(thr->callstack_curr != NULL); +#if defined(DUK_USE_DEBUGGER_SUPPORT) + if (act == thr->heap->dbg_pause_act) { + thr->heap->dbg_pause_flags &= ~DUK_PAUSE_FLAG_LINE_CHANGE; + } + + prev_pause_act = thr->heap->dbg_pause_act; + thr->heap->dbg_pause_act = NULL; + if (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_ENTRY) { + DUK_D(DUK_DPRINT("PAUSE TRIGGERED by function entry (tailcall)")); + duk_debug_set_paused(thr->heap); + } +#endif + duk_hthread_activation_unwind_reuse_norz(thr); +#if defined(DUK_USE_DEBUGGER_SUPPORT) + thr->heap->dbg_pause_act = prev_pause_act; +#endif + DUK_ASSERT(act == thr->callstack_curr); + + /* XXX: We could restore the caller's value stack reserve + * here, as if we did an actual unwind-and-call. Without + * the restoration, value stack reserve may remain higher + * than would otherwise be possible until we return to a + * non-tailcall. + */ + + /* Then reuse the unwound activation. */ + act->cat = NULL; + act->var_env = NULL; + act->lex_env = NULL; + DUK_ASSERT(func != NULL); + DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func)); + act->func = func; /* don't want an intermediate exposed state with func == NULL */ +#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY) + act->prev_caller = NULL; +#endif + /* don't want an intermediate exposed state with invalid pc */ + act->curr_pc = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) func); +#if defined(DUK_USE_DEBUGGER_SUPPORT) + act->prev_line = 0; +#endif + DUK_TVAL_SET_OBJECT(&act->tv_func, func); /* borrowed, no refcount */ + DUK_HOBJECT_INCREF(thr, func); + + act->flags = DUK_ACT_FLAG_TAILCALLED; + if (DUK_HOBJECT_HAS_STRICT(func)) { + act->flags |= DUK_ACT_FLAG_STRICT; + } + if (call_flags & DUK_CALL_FLAG_CONSTRUCT) { + act->flags |= DUK_ACT_FLAG_CONSTRUCT; + } +#if defined(DUK_USE_ES6_PROXY) + if (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) { + act->flags |= DUK_ACT_FLAG_CONSTRUCT_PROXY; + } +#endif + + DUK_ASSERT(DUK_ACT_GET_FUNC(act) == func); /* already updated */ + DUK_ASSERT(act->var_env == NULL); + DUK_ASSERT(act->lex_env == NULL); + act->bottom_byteoff = entry_valstack_bottom_byteoff; /* tail call -> reuse current "frame" */ +#if 0 + /* Topmost activation retval_byteoff is considered garbage, no need to init. */ + act->retval_byteoff = 0; +#endif + /* Filled in when final reserve is known, dummy value doesn't matter + * even in error unwind because reserve_byteoff is only used when + * returning to -this- activation. + */ + act->reserve_byteoff = 0; + + /* + * Manipulate valstack so that args are on the current bottom and the + * previous caller's 'this' binding (which is the value preceding the + * current bottom) is replaced with the new 'this' binding: + * + * [ ... this_old | (crud) func this_new arg1 ... argN ] + * --> [ ... this_new | arg1 ... argN ] + * + * For tail calling to work properly, the valstack bottom must not grow + * here; otherwise crud would accumulate on the valstack. + */ + + tv1 = thr->valstack_bottom - 1; + tv2 = thr->valstack_bottom + idx_func + 1; + DUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top); /* tv1 is -below- valstack_bottom */ + DUK_ASSERT(tv2 >= thr->valstack_bottom && tv2 < thr->valstack_top); + DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects */ + + idx_args = idx_func + 2; + duk_remove_n(thr, 0, idx_args); /* may be NORZ */ + + idx_func = 0; DUK_UNREF(idx_func); /* really 'not applicable' anymore, should not be referenced after this */ + idx_args = 0; + + *out_nargs = ((duk_hcompfunc *) func)->nargs; + *out_nregs = ((duk_hcompfunc *) func)->nregs; + DUK_ASSERT(*out_nregs >= 0); + DUK_ASSERT(*out_nregs >= *out_nargs); + *out_vs_min_bytes = entry_valstack_bottom_byteoff + sizeof(duk_tval) * ((duk_size_t) *out_nregs + DUK_VALSTACK_INTERNAL_EXTRA); + + +#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY) +#if defined(DUK_USE_TAILCALL) +#error incorrect options: tail calls enabled with function caller property +#endif + /* XXX: This doesn't actually work properly for tail calls, so + * tail calls are disabled when DUK_USE_NONSTD_FUNC_CALLER_PROPERTY + * is in use. + */ + duk__update_func_caller_prop(thr, func); +#endif + + /* [ ... this_new | arg1 ... argN ] */ + + return 1; +} +#endif /* DUK_USE_TAILCALL */ + +DUK_LOCAL void duk__call_setup_act_not_tailcall(duk_hthread *thr, + duk_small_uint_t call_flags, + duk_idx_t idx_func, + duk_hobject *func, + duk_size_t entry_valstack_bottom_byteoff, + duk_size_t entry_valstack_end_byteoff, + duk_idx_t *out_nargs, + duk_idx_t *out_nregs, + duk_size_t *out_vs_min_bytes, + duk_activation **out_act) { + duk_activation *act; + duk_activation *new_act; + + DUK_UNREF(entry_valstack_end_byteoff); + + DUK_DDD(DUK_DDDPRINT("not a tail call, pushing a new activation to callstack, to index %ld", + (long) (thr->callstack_top))); + + duk__call_callstack_limit_check(thr); + new_act = duk_hthread_activation_alloc(thr); + DUK_ASSERT(new_act != NULL); + + act = thr->callstack_curr; + if (act != NULL) { + /* + * Update return value stack index of current activation (if any). + * + * Although it might seem this is not necessary (bytecode executor + * does this for ECMAScript-to-ECMAScript calls; other calls are + * handled here), this turns out to be necessary for handling yield + * and resume. For them, an ECMAScript-to-native call happens, and + * the ECMAScript call's retval_byteoff must be set for things to work. + */ + + act->retval_byteoff = entry_valstack_bottom_byteoff + (duk_size_t) idx_func * sizeof(duk_tval); + } + + new_act->parent = act; + thr->callstack_curr = new_act; + thr->callstack_top++; + act = new_act; + *out_act = act; + + DUK_ASSERT(thr->valstack_top > thr->valstack_bottom); /* at least effective 'this' */ + DUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func)); + + act->cat = NULL; + + act->flags = 0; + if (call_flags & DUK_CALL_FLAG_CONSTRUCT) { + act->flags |= DUK_ACT_FLAG_CONSTRUCT; + } +#if defined(DUK_USE_ES6_PROXY) + if (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) { + act->flags |= DUK_ACT_FLAG_CONSTRUCT_PROXY; + } +#endif + if (call_flags & DUK_CALL_FLAG_DIRECT_EVAL) { + act->flags |= DUK_ACT_FLAG_DIRECT_EVAL; + } + + /* start of arguments: idx_func + 2. */ + act->func = func; /* NULL for lightfunc */ + if (DUK_LIKELY(func != NULL)) { + DUK_TVAL_SET_OBJECT(&act->tv_func, func); /* borrowed, no refcount */ + if (DUK_HOBJECT_HAS_STRICT(func)) { + act->flags |= DUK_ACT_FLAG_STRICT; + } + if (DUK_HOBJECT_IS_COMPFUNC(func)) { + *out_nargs = ((duk_hcompfunc *) func)->nargs; + *out_nregs = ((duk_hcompfunc *) func)->nregs; + DUK_ASSERT(*out_nregs >= 0); + DUK_ASSERT(*out_nregs >= *out_nargs); + *out_vs_min_bytes = entry_valstack_bottom_byteoff + + sizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nregs + DUK_VALSTACK_INTERNAL_EXTRA); + } else { + /* True because of call target lookup checks. */ + DUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(func)); + + *out_nargs = ((duk_hnatfunc *) func)->nargs; + *out_nregs = *out_nargs; + if (*out_nargs >= 0) { + *out_vs_min_bytes = entry_valstack_bottom_byteoff + + sizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nregs + DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA); + } else { + /* Vararg function. */ + duk_size_t valstack_top_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - ((duk_uint8_t *) thr->valstack)); + *out_vs_min_bytes = valstack_top_byteoff + + sizeof(duk_tval) * (DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA); + } + } + } else { + duk_small_uint_t lf_flags; + duk_tval *tv_func; + + act->flags |= DUK_ACT_FLAG_STRICT; + + tv_func = DUK_GET_TVAL_POSIDX(thr, idx_func); + DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func)); + DUK_TVAL_SET_TVAL(&act->tv_func, tv_func); /* borrowed, no refcount */ + + lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv_func); + *out_nargs = DUK_LFUNC_FLAGS_GET_NARGS(lf_flags); + if (*out_nargs != DUK_LFUNC_NARGS_VARARGS) { + *out_vs_min_bytes = entry_valstack_bottom_byteoff + + sizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nargs + DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA); + } else { + duk_size_t valstack_top_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - ((duk_uint8_t *) thr->valstack)); + *out_vs_min_bytes = valstack_top_byteoff + + sizeof(duk_tval) * (DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA); + *out_nargs = -1; /* vararg */ + } + *out_nregs = *out_nargs; + } + + act->var_env = NULL; + act->lex_env = NULL; +#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY) + act->prev_caller = NULL; +#endif + act->curr_pc = NULL; +#if defined(DUK_USE_DEBUGGER_SUPPORT) + act->prev_line = 0; +#endif + act->bottom_byteoff = entry_valstack_bottom_byteoff + sizeof(duk_tval) * ((duk_size_t) idx_func + 2U); +#if 0 + act->retval_byteoff = 0; /* topmost activation retval_byteoff is considered garbage, no need to init */ +#endif + /* Filled in when final reserve is known, dummy value doesn't matter + * even in error unwind because reserve_byteoff is only used when + * returning to -this- activation. + */ + act->reserve_byteoff = 0; /* filled in by caller */ + + /* XXX: Is this INCREF necessary? 'func' is always a borrowed + * reference reachable through the value stack? If changed, stack + * unwind code also needs to be fixed to match. + */ + DUK_HOBJECT_INCREF_ALLOWNULL(thr, func); /* act->func */ + +#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY) + if (func) { + duk__update_func_caller_prop(thr, func); + } +#endif +} + +/* + * Environment setup. + */ + +DUK_LOCAL void duk__call_env_setup(duk_hthread *thr, duk_hobject *func, duk_activation *act, duk_idx_t idx_args) { + duk_hobject *env; + + DUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func)); /* bound function has already been resolved */ + + if (DUK_LIKELY(func != NULL)) { + if (DUK_LIKELY(DUK_HOBJECT_HAS_NEWENV(func))) { + DUK_STATS_INC(thr->heap, stats_envrec_newenv); + if (DUK_LIKELY(!DUK_HOBJECT_HAS_CREATEARGS(func))) { + /* Use a new environment but there's no 'arguments' object; + * delayed environment initialization. This is the most + * common case. + */ + DUK_ASSERT(act->lex_env == NULL); + DUK_ASSERT(act->var_env == NULL); + } else { + /* Use a new environment and there's an 'arguments' object. + * We need to initialize it right now. + */ + + /* third arg: absolute index (to entire valstack) of bottom_byteoff of new activation */ + env = duk_create_activation_environment_record(thr, func, act->bottom_byteoff); + DUK_ASSERT(env != NULL); + + /* [ ... func this arg1 ... argN envobj ] */ + + DUK_ASSERT(DUK_HOBJECT_HAS_CREATEARGS(func)); + duk__handle_createargs_for_call(thr, func, env, idx_args); + + /* [ ... func this arg1 ... argN envobj ] */ + + act->lex_env = env; + act->var_env = env; + DUK_HOBJECT_INCREF(thr, env); + DUK_HOBJECT_INCREF(thr, env); /* XXX: incref by count (2) directly */ + duk_pop(thr); + } + } else { + /* Use existing env (e.g. for non-strict eval); cannot have + * an own 'arguments' object (but can refer to an existing one). + */ + + DUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(func)); + + DUK_STATS_INC(thr->heap, stats_envrec_oldenv); + duk__handle_oldenv_for_call(thr, func, act); + + DUK_ASSERT(act->lex_env != NULL); + DUK_ASSERT(act->var_env != NULL); + } + } else { + /* Lightfuncs are always native functions and have "newenv". */ + DUK_ASSERT(act->lex_env == NULL); + DUK_ASSERT(act->var_env == NULL); + DUK_STATS_INC(thr->heap, stats_envrec_newenv); + } +} + +/* + * Misc shared helpers. + */ + +/* Check thread state, update current thread. */ +DUK_LOCAL void duk__call_thread_state_update(duk_hthread *thr) { + DUK_ASSERT(thr != NULL); + + if (DUK_LIKELY(thr == thr->heap->curr_thread)) { + if (DUK_UNLIKELY(thr->state != DUK_HTHREAD_STATE_RUNNING)) { + /* Should actually never happen, but check anyway. */ + goto thread_state_error; + } + } else { + DUK_ASSERT(thr->heap->curr_thread == NULL || + thr->heap->curr_thread->state == DUK_HTHREAD_STATE_RUNNING); + if (DUK_UNLIKELY(thr->state != DUK_HTHREAD_STATE_INACTIVE)) { + goto thread_state_error; + } + DUK_HEAP_SWITCH_THREAD(thr->heap, thr); + thr->state = DUK_HTHREAD_STATE_RUNNING; + + /* Multiple threads may be simultaneously in the RUNNING + * state, but not in the same "resume chain". + */ + } + DUK_ASSERT(thr->heap->curr_thread == thr); + DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING); + return; + + thread_state_error: + DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "invalid thread state (%ld)", (long) thr->state); + DUK_WO_NORETURN(return;); +} + +/* + * Main unprotected call handler, handles: + * + * - All combinations of native/ECMAScript caller and native/ECMAScript + * target. + * + * - Optimized ECMAScript-to-ECMAScript call where call handling only + * sets up a new duk_activation but reuses an existing bytecode executor + * (the caller) without native recursion. + * + * - Tailcalls, where an activation is reused without increasing call + * stack (duk_activation) depth. + * + * - Setup for an initial Duktape.Thread.resume(). + * + * The call handler doesn't provide any protection guarantees, protected calls + * must be implemented e.g. by wrapping the call in a duk_safe_call(). + * Call setup may fail at any stage, even when the new activation is in + * place; the only guarantee is that the state is consistent for unwinding. + */ + +DUK_LOCAL duk_int_t duk__handle_call_raw(duk_hthread *thr, + duk_idx_t idx_func, + duk_small_uint_t call_flags) { +#if defined(DUK_USE_ASSERTIONS) + duk_activation *entry_act; + duk_size_t entry_callstack_top; +#endif + duk_size_t entry_valstack_bottom_byteoff; + duk_size_t entry_valstack_end_byteoff; + duk_int_t entry_call_recursion_depth; + duk_hthread *entry_curr_thread; + duk_uint_fast8_t entry_thread_state; + duk_instr_t **entry_ptr_curr_pc; + duk_idx_t idx_args; + duk_idx_t nargs; /* # argument registers target function wants (< 0 => "as is") */ + duk_idx_t nregs; /* # total registers target function wants on entry (< 0 => "as is") */ + duk_size_t vs_min_bytes; /* minimum value stack size (bytes) for handling call */ + duk_hobject *func; /* 'func' on stack (borrowed reference) */ + duk_activation *act; + duk_ret_t rc; + duk_small_uint_t use_tailcall; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + /* Asserts for heap->curr_thread omitted: it may be NULL, 'thr', or + * any other thread (e.g. when heap thread is used to run finalizers). + */ + DUK_CTX_ASSERT_VALID(thr); + DUK_ASSERT(duk_is_valid_index(thr, idx_func)); + DUK_ASSERT(idx_func >= 0); + + DUK_STATS_INC(thr->heap, stats_call_all); + + /* If a tail call: + * - an ECMAScript activation must be on top of the callstack + * - there cannot be any catch stack entries that would catch + * a return + */ +#if defined(DUK_USE_ASSERTIONS) + if (call_flags & DUK_CALL_FLAG_TAILCALL) { + duk_activation *tmp_act; + duk_catcher *tmp_cat; + + DUK_ASSERT(thr->callstack_top >= 1); + DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr))); + + /* No entry in the catch stack which would actually catch a + * throw can refer to the callstack entry being reused. + * There *can* be catch stack entries referring to the current + * callstack entry as long as they don't catch (e.g. label sites). + */ + + tmp_act = thr->callstack_curr; + for (tmp_cat = tmp_act->cat; tmp_cat != NULL; tmp_cat = tmp_cat->parent) { + DUK_ASSERT(DUK_CAT_GET_TYPE(tmp_cat) == DUK_CAT_TYPE_LABEL); /* a non-catching entry */ + } + } +#endif /* DUK_USE_ASSERTIONS */ + + /* + * Store entry state. + */ + +#if defined(DUK_USE_ASSERTIONS) + entry_act = thr->callstack_curr; + entry_callstack_top = thr->callstack_top; +#endif + entry_valstack_bottom_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack); + entry_valstack_end_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack); + entry_call_recursion_depth = thr->heap->call_recursion_depth; + entry_curr_thread = thr->heap->curr_thread; /* may be NULL if first call */ + entry_thread_state = thr->state; + entry_ptr_curr_pc = thr->ptr_curr_pc; /* may be NULL */ + + /* If thr->ptr_curr_pc is set, sync curr_pc to act->pc. Then NULL + * thr->ptr_curr_pc so that it's not accidentally used with an incorrect + * activation when side effects occur. + */ + duk_hthread_sync_and_null_currpc(thr); + DUK_ASSERT(thr->ptr_curr_pc == NULL); + + DUK_DD(DUK_DDPRINT("duk__handle_call_raw: thr=%p, idx_func=%ld, " + "call_flags=0x%08lx (constructor=%ld), " + "valstack_top=%ld, idx_func=%ld, idx_args=%ld, rec_depth=%ld/%ld, " + "entry_valstack_bottom_byteoff=%ld, entry_valstack_end_byteoff=%ld, " + "entry_call_recursion_depth=%ld, " + "entry_curr_thread=%p, entry_thread_state=%ld", + (void *) thr, + (long) idx_func, + (unsigned long) call_flags, + (long) ((call_flags & DUK_CALL_FLAG_CONSTRUCT) != 0 ? 1 : 0), + (long) duk_get_top(thr), + (long) idx_func, + (long) (idx_func + 2), + (long) thr->heap->call_recursion_depth, + (long) thr->heap->call_recursion_limit, + (long) entry_valstack_bottom_byteoff, + (long) entry_valstack_end_byteoff, + (long) entry_call_recursion_depth, + (void *) entry_curr_thread, + (long) entry_thread_state)); + + /* + * Thread state check and book-keeping. + */ + + duk__call_thread_state_update(thr); + + /* + * Increase call recursion depth as early as possible so that if we + * enter a recursive call for any reason there's a backstop to native + * recursion. This can happen e.g. for almost any property read + * because it may cause a getter call or a Proxy trap (GC and finalizers + * are not an issue because they are not recursive). If we end up + * doing an Ecma-to-Ecma call, revert the increase. (See GH-2032.) + * + * For similar reasons, ensure there is a known value stack spare + * even before we actually prepare the value stack for the target + * function. If this isn't done, early recursion may consume the + * value stack space. + * + * XXX: Should bump yield preventcount early, for the same reason. + */ + + duk__call_c_recursion_limit_check(thr); + thr->heap->call_recursion_depth++; + duk_require_stack(thr, DUK__CALL_HANDLING_REQUIRE_STACK); + + /* + * Resolve final target function; handle bound functions and special + * functions like .call() and .apply(). Also figure out the effective + * 'this' binding, which replaces the current value at idx_func + 1. + */ + + if (DUK_LIKELY(duk__resolve_target_fastpath_check(thr, idx_func, &func, call_flags) != 0U)) { + DUK_DDD(DUK_DDDPRINT("fast path target resolve")); + } else { + DUK_DDD(DUK_DDDPRINT("slow path target resolve")); + func = duk__resolve_target_func_and_this_binding(thr, idx_func, &call_flags); + } + DUK_ASSERT(duk_get_top(thr) - idx_func >= 2); /* at least func and this present */ + + DUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func)); + DUK_ASSERT(func == NULL || (DUK_HOBJECT_IS_COMPFUNC(func) || + DUK_HOBJECT_IS_NATFUNC(func))); + + /* [ ... func this arg1 ... argN ] */ + + /* + * Setup a preliminary activation and figure out nargs/nregs and + * value stack minimum size. + * + * Don't touch valstack_bottom or valstack_top yet so that Duktape API + * calls work normally. + * + * Because 'act' is not zeroed, all fields must be filled in. + */ + + /* Should not be necessary, but initialize to silence warnings. */ + act = NULL; + nargs = 0; + nregs = 0; + vs_min_bytes = 0; + +#if defined(DUK_USE_TAILCALL) + use_tailcall = (call_flags & DUK_CALL_FLAG_TAILCALL); + if (use_tailcall) { + use_tailcall = duk__call_setup_act_attempt_tailcall(thr, + call_flags, + idx_func, + func, + entry_valstack_bottom_byteoff, + entry_valstack_end_byteoff, + &nargs, + &nregs, + &vs_min_bytes, + &act); + } +#else + DUK_ASSERT((call_flags & DUK_CALL_FLAG_TAILCALL) == 0); /* compiler ensures this */ + use_tailcall = 0; +#endif + + if (use_tailcall) { + idx_args = 0; + DUK_STATS_INC(thr->heap, stats_call_tailcall); + } else { + duk__call_setup_act_not_tailcall(thr, + call_flags, + idx_func, + func, + entry_valstack_bottom_byteoff, + entry_valstack_end_byteoff, + &nargs, + &nregs, + &vs_min_bytes, + &act); + idx_args = idx_func + 2; + } + /* After this point idx_func is no longer valid for tailcalls. */ + + DUK_ASSERT(act != NULL); + + /* [ ... func this arg1 ... argN ] */ + + /* + * Environment record creation and 'arguments' object creation. + * Named function expression name binding is handled by the + * compiler; the compiled function's parent env will contain + * the (immutable) binding already. + * + * This handling is now identical for C and ECMAScript functions. + * C functions always have the 'NEWENV' flag set, so their + * environment record initialization is delayed (which is good). + * + * Delayed creation (on demand) is handled in duk_js_var.c. + */ + + duk__call_env_setup(thr, func, act, idx_args); + + /* [ ... func this arg1 ... argN ] */ + + /* + * Setup value stack: clamp to 'nargs', fill up to 'nregs', + * ensure value stack size matches target requirements, and + * switch value stack bottom. Valstack top is kept. + * + * Value stack can only grow here. + */ + + duk_valstack_grow_check_throw(thr, vs_min_bytes); + act->reserve_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack); + + if (use_tailcall) { + DUK_ASSERT(nregs >= 0); + DUK_ASSERT(nregs >= nargs); + duk_set_top_and_wipe(thr, nregs, nargs); + } else { + if (nregs >= 0) { + DUK_ASSERT(nregs >= nargs); + duk_set_top_and_wipe(thr, idx_func + 2 + nregs, idx_func + 2 + nargs); + } else { + ; + } + thr->valstack_bottom = thr->valstack_bottom + idx_func + 2; + } + DUK_ASSERT(thr->valstack_bottom >= thr->valstack); + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + DUK_ASSERT(thr->valstack_end >= thr->valstack_top); + + /* + * Make the actual call. For Ecma-to-Ecma calls detect that + * setup is complete, then return with a status code that allows + * the caller to reuse the running executor. + */ + + if (func != NULL && DUK_HOBJECT_IS_COMPFUNC(func)) { + /* + * ECMAScript call. + */ + + DUK_ASSERT(func != NULL); + DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func)); + act->curr_pc = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) func); + + if (call_flags & DUK_CALL_FLAG_ALLOW_ECMATOECMA) { + DUK_DD(DUK_DDPRINT("avoid native call, use existing executor")); + DUK_STATS_INC(thr->heap, stats_call_ecmatoecma); + DUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0); + DUK_REFZERO_CHECK_FAST(thr); + DUK_ASSERT(thr->ptr_curr_pc == NULL); + thr->heap->call_recursion_depth--; /* No recursion increase for this case. */ + return 1; /* 1=reuse executor */ + } + DUK_ASSERT(use_tailcall == 0); + + /* duk_hthread_activation_unwind_norz() will decrease this on unwind */ + DUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0); + act->flags |= DUK_ACT_FLAG_PREVENT_YIELD; + thr->callstack_preventcount++; + + /* [ ... func this | arg1 ... argN ] ('this' must precede new bottom) */ + + /* + * Bytecode executor call. + * + * Execute bytecode, handling any recursive function calls and + * thread resumptions. Returns when execution would return from + * the entry level activation. When the executor returns, a + * single return value is left on the stack top. + * + * The only possible longjmp() is an error (DUK_LJ_TYPE_THROW), + * other types are handled internally by the executor. + */ + + /* thr->ptr_curr_pc is set by bytecode executor early on entry */ + DUK_ASSERT(thr->ptr_curr_pc == NULL); + DUK_DDD(DUK_DDDPRINT("entering bytecode execution")); + duk_js_execute_bytecode(thr); + DUK_DDD(DUK_DDDPRINT("returned from bytecode execution")); + } else { + /* + * Native call. + */ + + DUK_ASSERT(func == NULL || ((duk_hnatfunc *) func)->func != NULL); + DUK_ASSERT(use_tailcall == 0); + + /* [ ... func this | arg1 ... argN ] ('this' must precede new bottom) */ + + /* duk_hthread_activation_unwind_norz() will decrease this on unwind */ + DUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0); + act->flags |= DUK_ACT_FLAG_PREVENT_YIELD; + thr->callstack_preventcount++; + + /* For native calls must be NULL so we don't sync back */ + DUK_ASSERT(thr->ptr_curr_pc == NULL); + + /* XXX: native funcptr could come out of call setup. */ + if (func) { + rc = ((duk_hnatfunc *) func)->func(thr); + } else { + duk_tval *tv_func; + duk_c_function funcptr; + + tv_func = &act->tv_func; + DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func)); + funcptr = DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv_func); + rc = funcptr(thr); + } + + /* Automatic error throwing, retval check. */ + + if (rc == 0) { + DUK_ASSERT(thr->valstack < thr->valstack_end); + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top)); + thr->valstack_top++; + } else if (rc == 1) { + ; + } else if (rc < 0) { + duk_error_throw_from_negative_rc(thr, rc); + DUK_WO_NORETURN(return 0;); + } else { + DUK_ERROR_TYPE(thr, DUK_STR_INVALID_CFUNC_RC); + DUK_WO_NORETURN(return 0;); + } + } + DUK_ASSERT(thr->ptr_curr_pc == NULL); + DUK_ASSERT(use_tailcall == 0); + + /* + * Constructor call post processing. + */ + +#if defined(DUK_USE_ES6_PROXY) + if (call_flags & (DUK_CALL_FLAG_CONSTRUCT | DUK_CALL_FLAG_CONSTRUCT_PROXY)) { + duk_call_construct_postprocess(thr, call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY); + } +#else + if (call_flags & DUK_CALL_FLAG_CONSTRUCT) { + duk_call_construct_postprocess(thr, 0); + } +#endif + + /* + * Unwind, restore valstack bottom and other book-keeping. + */ + + DUK_ASSERT(thr->callstack_curr != NULL); + DUK_ASSERT(thr->callstack_curr->parent == entry_act); + DUK_ASSERT(thr->callstack_top == entry_callstack_top + 1); + duk_hthread_activation_unwind_norz(thr); + DUK_ASSERT(thr->callstack_curr == entry_act); + DUK_ASSERT(thr->callstack_top == entry_callstack_top); + + thr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_bottom_byteoff); + /* keep current valstack_top */ + DUK_ASSERT(thr->valstack_bottom >= thr->valstack); + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + DUK_ASSERT(thr->valstack_end >= thr->valstack_top); + DUK_ASSERT(thr->valstack_top - thr->valstack_bottom >= idx_func + 1); + + /* Return value handling. */ + + /* [ ... func this (crud) retval ] */ + + { + duk_tval *tv_ret; + duk_tval *tv_funret; + + tv_ret = thr->valstack_bottom + idx_func; + tv_funret = thr->valstack_top - 1; +#if defined(DUK_USE_FASTINT) + /* Explicit check for fastint downgrade. */ + DUK_TVAL_CHKFAST_INPLACE_FAST(tv_funret); +#endif + DUK_TVAL_SET_TVAL_UPDREF(thr, tv_ret, tv_funret); /* side effects */ + } + + duk_set_top_unsafe(thr, idx_func + 1); + + /* [ ... retval ] */ + + /* Restore caller's value stack reserve (cannot fail). */ + DUK_ASSERT((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff >= (duk_uint8_t *) thr->valstack_top); + DUK_ASSERT((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff <= (duk_uint8_t *) thr->valstack_alloc_end); + thr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff); + + /* XXX: Trial value stack shrink would be OK here, but we'd need + * to prevent side effects of the potential realloc. + */ + + /* Restore entry thread executor curr_pc stack frame pointer. */ + thr->ptr_curr_pc = entry_ptr_curr_pc; + + DUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread); /* may be NULL */ + thr->state = (duk_uint8_t) entry_thread_state; + + /* Disabled assert: triggered with some torture tests. */ +#if 0 + DUK_ASSERT((thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread == NULL) || /* first call */ + (thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread != NULL) || /* other call */ + (thr->state == DUK_HTHREAD_STATE_RUNNING && thr->heap->curr_thread == thr)); /* current thread */ +#endif + + thr->heap->call_recursion_depth = entry_call_recursion_depth; + + /* If the debugger is active we need to force an interrupt so that + * debugger breakpoints are rechecked. This is important for function + * calls caused by side effects (e.g. when doing a DUK_OP_GETPROP), see + * GH-303. Only needed for success path, error path always causes a + * breakpoint recheck in the executor. It would be enough to set this + * only when returning to an ECMAScript activation, but setting the flag + * on every return should have no ill effect. + */ +#if defined(DUK_USE_DEBUGGER_SUPPORT) + if (duk_debug_is_attached(thr->heap)) { + DUK_DD(DUK_DDPRINT("returning with debugger enabled, force interrupt")); + DUK_ASSERT(thr->interrupt_counter <= thr->interrupt_init); + thr->interrupt_init -= thr->interrupt_counter; + thr->interrupt_counter = 0; + thr->heap->dbg_force_restart = 1; + } +#endif + +#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG) + duk__interrupt_fixup(thr, entry_curr_thread); +#endif + + /* Restored by success path. */ + DUK_ASSERT(thr->heap->call_recursion_depth == entry_call_recursion_depth); + DUK_ASSERT(thr->ptr_curr_pc == entry_ptr_curr_pc); + DUK_ASSERT_LJSTATE_UNSET(thr->heap); + + DUK_REFZERO_CHECK_FAST(thr); + + return 0; /* 0=call handled inline */ +} + +DUK_INTERNAL duk_int_t duk_handle_call_unprotected_nargs(duk_hthread *thr, + duk_idx_t nargs, + duk_small_uint_t call_flags) { + duk_idx_t idx_func; + DUK_ASSERT(duk_get_top(thr) >= nargs + 2); + idx_func = duk_get_top(thr) - (nargs + 2); + DUK_ASSERT(idx_func >= 0); + return duk_handle_call_unprotected(thr, idx_func, call_flags); +} + +DUK_INTERNAL duk_int_t duk_handle_call_unprotected(duk_hthread *thr, + duk_idx_t idx_func, + duk_small_uint_t call_flags) { + DUK_ASSERT(duk_is_valid_index(thr, idx_func)); + DUK_ASSERT(idx_func >= 0); + return duk__handle_call_raw(thr, idx_func, call_flags); +} + +/* + * duk_handle_safe_call(): make a "C protected call" within the + * current activation. + * + * The allowed thread states for making a call are the same as for + * duk_handle_call_protected(). + * + * Even though this call is protected, errors are thrown for insane arguments + * and may result in a fatal error unless there's another protected call which + * catches such errors. + * + * The error handling path should be error free, even for out-of-memory + * errors, to ensure safe sandboxing. (As of Duktape 2.2.0 this is not + * yet the case for environment closing which may run out of memory, see + * XXX notes below.) + */ + +DUK_LOCAL void duk__handle_safe_call_inner(duk_hthread *thr, + duk_safe_call_function func, + void *udata, +#if defined(DUK_USE_ASSERTIONS) + duk_size_t entry_valstack_bottom_byteoff, + duk_size_t entry_callstack_top, +#endif + duk_hthread *entry_curr_thread, + duk_uint_fast8_t entry_thread_state, + duk_idx_t idx_retbase, + duk_idx_t num_stack_rets) { + duk_ret_t rc; + + DUK_ASSERT(thr != NULL); + DUK_CTX_ASSERT_VALID(thr); + + /* + * Thread state check and book-keeping. + */ + + duk__call_thread_state_update(thr); + + /* + * Recursion limit check. + */ + + duk__call_c_recursion_limit_check(thr); + thr->heap->call_recursion_depth++; + + /* + * Make the C call. + */ + + rc = func(thr, udata); + + DUK_DDD(DUK_DDDPRINT("safe_call, func rc=%ld", (long) rc)); + + /* + * Valstack manipulation for results. + */ + + /* we're running inside the caller's activation, so no change in call/catch stack or valstack bottom */ + DUK_ASSERT(thr->callstack_top == entry_callstack_top); + DUK_ASSERT(thr->valstack_bottom >= thr->valstack); + DUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) == entry_valstack_bottom_byteoff); + DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); + DUK_ASSERT(thr->valstack_end >= thr->valstack_top); + + if (DUK_UNLIKELY(rc < 0)) { + duk_error_throw_from_negative_rc(thr, rc); + DUK_WO_NORETURN(return;); + } + DUK_ASSERT(rc >= 0); + + duk__safe_call_adjust_valstack(thr, idx_retbase, num_stack_rets, rc); /* throws for insane rc */ + + DUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread); /* may be NULL */ + thr->state = (duk_uint8_t) entry_thread_state; +} + +DUK_LOCAL void duk__handle_safe_call_error(duk_hthread *thr, + duk_activation *entry_act, +#if defined(DUK_USE_ASSERTIONS) + duk_size_t entry_callstack_top, +#endif + duk_hthread *entry_curr_thread, + duk_uint_fast8_t entry_thread_state, + duk_idx_t idx_retbase, + duk_idx_t num_stack_rets, + duk_size_t entry_valstack_bottom_byteoff, + duk_jmpbuf *old_jmpbuf_ptr) { + DUK_ASSERT(thr != NULL); + DUK_CTX_ASSERT_VALID(thr); + + /* + * Error during call. The error value is at heap->lj.value1. + * + * The very first thing we do is restore the previous setjmp catcher. + * This means that any error in error handling will propagate outwards + * instead of causing a setjmp() re-entry above. + */ + + DUK_DDD(DUK_DDDPRINT("error caught during protected duk_handle_safe_call()")); + + /* Other longjmp types are handled by executor before propagating + * the error here. + */ + DUK_ASSERT(thr->heap->lj.type == DUK_LJ_TYPE_THROW); + DUK_ASSERT_LJSTATE_SET(thr->heap); + + /* Either pointer may be NULL (at entry), so don't assert. */ + thr->heap->lj.jmpbuf_ptr = old_jmpbuf_ptr; + + /* XXX: callstack unwind may now throw an error when closing + * scopes; this is a sandboxing issue, described in: + * https://github.com/svaarala/duktape/issues/476 + */ + /* XXX: "unwind to" primitive? */ + + DUK_ASSERT(thr->callstack_top >= entry_callstack_top); + while (thr->callstack_curr != entry_act) { + DUK_ASSERT(thr->callstack_curr != NULL); + duk_hthread_activation_unwind_norz(thr); + } + DUK_ASSERT(thr->callstack_top == entry_callstack_top); + + /* Switch active thread before any side effects to avoid a + * dangling curr_thread pointer. + */ + DUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread); /* may be NULL */ + thr->state = (duk_uint8_t) entry_thread_state; + + DUK_ASSERT(thr->heap->curr_thread == entry_curr_thread); + DUK_ASSERT(thr->state == entry_thread_state); + + /* Restore valstack bottom. */ + thr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_bottom_byteoff); + + /* [ ... | (crud) ] */ + + /* XXX: ensure space in valstack (now relies on internal reserve)? */ + duk_push_tval(thr, &thr->heap->lj.value1); + + /* [ ... | (crud) errobj ] */ + + DUK_ASSERT(duk_get_top(thr) >= 1); /* at least errobj must be on stack */ + + duk__safe_call_adjust_valstack(thr, idx_retbase, num_stack_rets, 1); /* 1 = num actual 'return values' */ + + /* [ ... | ] or [ ... | errobj (M * undefined)] where M = num_stack_rets - 1 */ + + /* Reset longjmp state. */ + thr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN; + thr->heap->lj.iserror = 0; + DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, &thr->heap->lj.value1); + DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, &thr->heap->lj.value2); + + /* Error handling complete, remove side effect protections. Caller + * will process pending finalizers. + */ +#if defined(DUK_USE_ASSERTIONS) + DUK_ASSERT(thr->heap->error_not_allowed == 1); + thr->heap->error_not_allowed = 0; +#endif + DUK_ASSERT(thr->heap->pf_prevent_count > 0); + thr->heap->pf_prevent_count--; + DUK_DD(DUK_DDPRINT("safe call error handled, pf_prevent_count updated to %ld", (long) thr->heap->pf_prevent_count)); + + /* thr->ptr_curr_pc is restored by + * duk__handle_safe_call_shared_unwind() which is also used for + * success path. + */ +} + +DUK_LOCAL void duk__handle_safe_call_shared_unwind(duk_hthread *thr, + duk_idx_t idx_retbase, + duk_idx_t num_stack_rets, +#if defined(DUK_USE_ASSERTIONS) + duk_size_t entry_callstack_top, +#endif + duk_int_t entry_call_recursion_depth, + duk_hthread *entry_curr_thread, + duk_instr_t **entry_ptr_curr_pc) { + DUK_ASSERT(thr != NULL); + DUK_CTX_ASSERT_VALID(thr); + DUK_UNREF(idx_retbase); + DUK_UNREF(num_stack_rets); + DUK_UNREF(entry_curr_thread); + + DUK_ASSERT(thr->callstack_top == entry_callstack_top); + + /* Restore entry thread executor curr_pc stack frame pointer. + * XXX: would be enough to do in error path only, should nest + * cleanly in success path. + */ + thr->ptr_curr_pc = entry_ptr_curr_pc; + + thr->heap->call_recursion_depth = entry_call_recursion_depth; + + /* stack discipline consistency check */ + DUK_ASSERT(duk_get_top(thr) == idx_retbase + num_stack_rets); + + /* A debugger forced interrupt check is not needed here, as + * problematic safe calls are not caused by side effects. + */ + +#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG) + duk__interrupt_fixup(thr, entry_curr_thread); +#endif +} + +DUK_INTERNAL duk_int_t duk_handle_safe_call(duk_hthread *thr, + duk_safe_call_function func, + void *udata, + duk_idx_t num_stack_args, + duk_idx_t num_stack_rets) { + duk_activation *entry_act; + duk_size_t entry_valstack_bottom_byteoff; +#if defined(DUK_USE_ASSERTIONS) + duk_size_t entry_valstack_end_byteoff; + duk_size_t entry_callstack_top; + duk_size_t entry_callstack_preventcount; +#endif + duk_int_t entry_call_recursion_depth; + duk_hthread *entry_curr_thread; + duk_uint_fast8_t entry_thread_state; + duk_instr_t **entry_ptr_curr_pc; + duk_jmpbuf *old_jmpbuf_ptr = NULL; + duk_jmpbuf our_jmpbuf; + duk_idx_t idx_retbase; + duk_int_t retval; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(duk_get_top(thr) >= num_stack_args); /* Caller ensures. */ + + DUK_STATS_INC(thr->heap, stats_safecall_all); + + /* Value stack reserve handling: safe call assumes caller has reserved + * space for nrets (assuming optimal unwind processing). Value stack + * reserve is not stored/restored as for normal calls because a safe + * call conceptually happens in the same activation. + */ + + /* Careful with indices like '-x'; if 'x' is zero, it refers to bottom */ + entry_act = thr->callstack_curr; + entry_valstack_bottom_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack); +#if defined(DUK_USE_ASSERTIONS) + entry_valstack_end_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack); + entry_callstack_top = thr->callstack_top; + entry_callstack_preventcount = thr->callstack_preventcount; +#endif + entry_call_recursion_depth = thr->heap->call_recursion_depth; + entry_curr_thread = thr->heap->curr_thread; /* may be NULL if first call */ + entry_thread_state = thr->state; + entry_ptr_curr_pc = thr->ptr_curr_pc; /* may be NULL */ + idx_retbase = duk_get_top(thr) - num_stack_args; /* not a valid stack index if num_stack_args == 0 */ + DUK_ASSERT(idx_retbase >= 0); + + DUK_ASSERT((duk_idx_t) (thr->valstack_top - thr->valstack_bottom) >= num_stack_args); /* Caller ensures. */ + DUK_ASSERT((duk_idx_t) (thr->valstack_end - (thr->valstack_bottom + idx_retbase)) >= num_stack_rets); /* Caller ensures. */ + + /* Cannot portably debug print a function pointer, hence 'func' not printed! */ + DUK_DD(DUK_DDPRINT("duk_handle_safe_call: thr=%p, num_stack_args=%ld, num_stack_rets=%ld, " + "valstack_top=%ld, idx_retbase=%ld, rec_depth=%ld/%ld, " + "entry_act=%p, entry_valstack_bottom_byteoff=%ld, entry_call_recursion_depth=%ld, " + "entry_curr_thread=%p, entry_thread_state=%ld", + (void *) thr, + (long) num_stack_args, + (long) num_stack_rets, + (long) duk_get_top(thr), + (long) idx_retbase, + (long) thr->heap->call_recursion_depth, + (long) thr->heap->call_recursion_limit, + (void *) entry_act, + (long) entry_valstack_bottom_byteoff, + (long) entry_call_recursion_depth, + (void *) entry_curr_thread, + (long) entry_thread_state)); + + /* Setjmp catchpoint setup. */ + old_jmpbuf_ptr = thr->heap->lj.jmpbuf_ptr; + thr->heap->lj.jmpbuf_ptr = &our_jmpbuf; + + /* Prevent yields for the duration of the safe call. This only + * matters if the executor makes safe calls to functions that + * yield, this doesn't currently happen. + */ + thr->callstack_preventcount++; + +#if defined(DUK_USE_CPP_EXCEPTIONS) + try { +#else + DUK_ASSERT(thr->heap->lj.jmpbuf_ptr == &our_jmpbuf); + if (DUK_SETJMP(our_jmpbuf.jb) == 0) { + /* Success path. */ +#endif + DUK_DDD(DUK_DDDPRINT("safe_call setjmp catchpoint setup complete")); + + duk__handle_safe_call_inner(thr, + func, + udata, +#if defined(DUK_USE_ASSERTIONS) + entry_valstack_bottom_byteoff, + entry_callstack_top, +#endif + entry_curr_thread, + entry_thread_state, + idx_retbase, + num_stack_rets); + + DUK_STATS_INC(thr->heap, stats_safecall_nothrow); + + /* Either pointer may be NULL (at entry), so don't assert */ + thr->heap->lj.jmpbuf_ptr = old_jmpbuf_ptr; + + /* If calls happen inside the safe call, these are restored by + * whatever calls are made. Reserve cannot decrease. + */ + DUK_ASSERT(thr->callstack_curr == entry_act); + DUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff); + + retval = DUK_EXEC_SUCCESS; +#if defined(DUK_USE_CPP_EXCEPTIONS) + } catch (duk_internal_exception &exc) { + DUK_UNREF(exc); +#else + } else { + /* Error path. */ +#endif + DUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff); + + DUK_STATS_INC(thr->heap, stats_safecall_throw); + + duk__handle_safe_call_error(thr, + entry_act, +#if defined(DUK_USE_ASSERTIONS) + entry_callstack_top, +#endif + entry_curr_thread, + entry_thread_state, + idx_retbase, + num_stack_rets, + entry_valstack_bottom_byteoff, + old_jmpbuf_ptr); + + retval = DUK_EXEC_ERROR; + } +#if defined(DUK_USE_CPP_EXCEPTIONS) + catch (duk_fatal_exception &exc) { + DUK_D(DUK_DPRINT("rethrow duk_fatal_exception")); + DUK_UNREF(exc); + throw; + } catch (std::exception &exc) { + const char *what = exc.what(); + DUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff); + DUK_STATS_INC(thr->heap, stats_safecall_throw); + if (!what) { + what = "unknown"; + } + DUK_D(DUK_DPRINT("unexpected c++ std::exception (perhaps thrown by user code)")); + try { + DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "caught invalid c++ std::exception '%s' (perhaps thrown by user code)", what); + DUK_WO_NORETURN(return 0;); + } catch (duk_internal_exception exc) { + DUK_D(DUK_DPRINT("caught api error thrown from unexpected c++ std::exception")); + DUK_UNREF(exc); + duk__handle_safe_call_error(thr, + entry_act, +#if defined(DUK_USE_ASSERTIONS) + entry_callstack_top, +#endif + entry_curr_thread, + entry_thread_state, + idx_retbase, + num_stack_rets, + entry_valstack_bottom_byteoff, + old_jmpbuf_ptr); + retval = DUK_EXEC_ERROR; + } + } catch (...) { + DUK_D(DUK_DPRINT("unexpected c++ exception (perhaps thrown by user code)")); + DUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff); + DUK_STATS_INC(thr->heap, stats_safecall_throw); + try { + DUK_ERROR_TYPE(thr, "caught invalid c++ exception (perhaps thrown by user code)"); + DUK_WO_NORETURN(return 0;); + } catch (duk_internal_exception exc) { + DUK_D(DUK_DPRINT("caught api error thrown from unexpected c++ exception")); + DUK_UNREF(exc); + duk__handle_safe_call_error(thr, + entry_act, +#if defined(DUK_USE_ASSERTIONS) + entry_callstack_top, +#endif + entry_curr_thread, + entry_thread_state, + idx_retbase, + num_stack_rets, + entry_valstack_bottom_byteoff, + old_jmpbuf_ptr); + retval = DUK_EXEC_ERROR; + } + } +#endif + + DUK_ASSERT(thr->heap->lj.jmpbuf_ptr == old_jmpbuf_ptr); /* success/error path both do this */ + + DUK_ASSERT_LJSTATE_UNSET(thr->heap); + + DUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff); + duk__handle_safe_call_shared_unwind(thr, + idx_retbase, + num_stack_rets, +#if defined(DUK_USE_ASSERTIONS) + entry_callstack_top, +#endif + entry_call_recursion_depth, + entry_curr_thread, + entry_ptr_curr_pc); + + /* Restore preventcount. */ + thr->callstack_preventcount--; + DUK_ASSERT(thr->callstack_preventcount == entry_callstack_preventcount); + + /* Final asserts. */ + DUK_ASSERT(thr->callstack_curr == entry_act); + DUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) == entry_valstack_bottom_byteoff); + DUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff); + DUK_ASSERT(thr->callstack_top == entry_callstack_top); + DUK_ASSERT(thr->heap->call_recursion_depth == entry_call_recursion_depth); + DUK_ASSERT(thr->heap->curr_thread == entry_curr_thread); + DUK_ASSERT(thr->state == entry_thread_state); + DUK_ASSERT(thr->ptr_curr_pc == entry_ptr_curr_pc); + DUK_ASSERT(duk_get_top(thr) == idx_retbase + num_stack_rets); + DUK_ASSERT_LJSTATE_UNSET(thr->heap); + + /* Pending side effects. */ + DUK_REFZERO_CHECK_FAST(thr); + + return retval; +} + +/* + * Property-based call (foo.noSuch()) error setup: replace target function + * on stack top with a hidden Symbol tagged non-callable wrapper object + * holding the error. The error gets thrown in call handling at the + * proper spot to follow ECMAScript semantics. + */ + +#if defined(DUK_USE_VERBOSE_ERRORS) +DUK_INTERNAL DUK_NOINLINE DUK_COLD void duk_call_setup_propcall_error(duk_hthread *thr, duk_tval *tv_base, duk_tval *tv_key) { + const char *str_targ, *str_key, *str_base; + duk_idx_t entry_top; + + entry_top = duk_get_top(thr); + + /* [ target ] */ + + /* Must stabilize pointers first. tv_targ is already on stack top. */ + duk_push_tval(thr, tv_base); + duk_push_tval(thr, tv_key); + + DUK_GC_TORTURE(thr->heap); + + duk_push_bare_object(thr); + + /* [ target base key {} ] */ + + /* We only push a wrapped error, replacing the call target (at + * idx_func) with the error to ensure side effects come out + * correctly: + * - Property read + * - Call argument evaluation + * - Callability check and error thrown + * + * A hidden Symbol on the wrapper object pushed above is used by + * call handling to figure out the error is to be thrown as is. + * It is CRITICAL that the hidden Symbol can never occur on a + * user visible object that may get thrown. + */ + +#if defined(DUK_USE_PARANOID_ERRORS) + str_targ = duk_get_type_name(thr, -4); + str_key = duk_get_type_name(thr, -2); + str_base = duk_get_type_name(thr, -3); + duk_push_error_object(thr, + DUK_ERR_TYPE_ERROR | DUK_ERRCODE_FLAG_NOBLAME_FILELINE, + "%s not callable (property %s of %s)", str_targ, str_key, str_base); + duk_xdef_prop_stridx(thr, -2, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE); /* Marker property, reuse _Target. */ + /* [ target base key { _Target: error } ] */ + duk_replace(thr, entry_top - 1); +#else + str_targ = duk_push_string_readable(thr, -4); + str_key = duk_push_string_readable(thr, -3); + str_base = duk_push_string_readable(thr, -5); + duk_push_error_object(thr, + DUK_ERR_TYPE_ERROR | DUK_ERRCODE_FLAG_NOBLAME_FILELINE, + "%s not callable (property %s of %s)", str_targ, str_key, str_base); + /* [ target base key {} str_targ str_key str_base error ] */ + duk_xdef_prop_stridx(thr, -5, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE); /* Marker property, reuse _Target. */ + /* [ target base key { _Target: error } str_targ str_key str_base ] */ + duk_swap(thr, -4, entry_top - 1); + /* [ { _Target: error } base key target str_targ str_key str_base ] */ +#endif + + /* [ { _Target: error } */ + duk_set_top(thr, entry_top); + + /* [ { _Target: error } */ + DUK_ASSERT(!duk_is_callable(thr, -1)); /* Critical so that call handling will throw the error. */ +} +#endif /* DUK_USE_VERBOSE_ERRORS */ diff --git a/third_party/duktape/duk_js_compiler.c b/third_party/duktape/duk_js_compiler.c new file mode 100644 index 00000000..3b5d2738 --- /dev/null +++ b/third_party/duktape/duk_js_compiler.c @@ -0,0 +1,8581 @@ +/* + * ECMAScript compiler. + * + * Parses an input string and generates a function template result. + * Compilation may happen in multiple contexts (global code, eval + * code, function code). + * + * The parser uses a traditional top-down recursive parsing for the + * statement level, and an operator precedence based top-down approach + * for the expression level. The attempt is to minimize the C stack + * depth. Bytecode is generated directly without an intermediate + * representation (tree), at the cost of needing two (and sometimes + * three) passes over each function. + * + * The top-down recursive parser functions are named "duk__parse_XXX". + * + * Recursion limits are in key functions to prevent arbitrary C recursion: + * function body parsing, statement parsing, and expression parsing. + * + * See doc/compiler.rst for discussion on the design. + * + * A few typing notes: + * + * - duk_regconst_t: signed, highest bit set (< 0) means constant, + * some call sites use -1 for "none" (equivalent to constant 0x7fffffff) + * - PC values: duk_int_t, negative values used as markers + */ + +#include "third_party/duktape/duk_internal.h" + +/* If highest bit of a register number is set, it refers to a constant instead. + * When interpreted as a signed value, this means const values are always + * negative (when interpreted as two's complement). For example + * DUK__ISREG_TEMP() uses this approach to avoid an explicit DUK__ISREG() check + * (the condition is logically "'x' is a register AND 'x' >= temp_first"). + */ +#define DUK__CONST_MARKER DUK_REGCONST_CONST_MARKER +#define DUK__REMOVECONST(x) ((x) & ~DUK__CONST_MARKER) +#define DUK__ISREG(x) ((x) >= 0) +#define DUK__ISCONST(x) ((x) < 0) +#define DUK__ISREG_TEMP(comp_ctx, x) \ + ((duk_int32_t)(x) >= \ + (duk_int32_t)( \ + (comp_ctx)->curr_func.temp_first)) /* Check for x >= temp_first && x >= \ + 0 by comparing as signed. */ +#define DUK__ISREG_NOTTEMP(comp_ctx, x) \ + ((duk_uint32_t)(x) < \ + (duk_uint32_t)( \ + (comp_ctx) \ + ->curr_func.temp_first)) /* Check for x >= 0 && x < temp_first by \ + interpreting as unsigned. */ +#define DUK__GETTEMP(comp_ctx) ((comp_ctx)->curr_func.temp_next) +#define DUK__SETTEMP(comp_ctx, x) \ + ((comp_ctx)->curr_func.temp_next = \ + (x)) /* dangerous: must only lower (temp_max not updated) */ +#define DUK__SETTEMP_CHECKMAX(comp_ctx, x) \ + duk__settemp_checkmax((comp_ctx), (x)) +#define DUK__ALLOCTEMP(comp_ctx) duk__alloctemp((comp_ctx)) +#define DUK__ALLOCTEMPS(comp_ctx, count) duk__alloctemps((comp_ctx), (count)) + +/* Init value set size for array and object literals. */ +#define DUK__MAX_ARRAY_INIT_VALUES 20 +#define DUK__MAX_OBJECT_INIT_PAIRS 10 + +/* XXX: hack, remove when const lookup is not O(n) */ +#define DUK__GETCONST_MAX_CONSTS_CHECK 256 + +/* These limits are based on bytecode limits. Max temps is limited + * by duk_hcompfunc nargs/nregs fields being 16 bits. + */ +#define DUK__MAX_CONSTS DUK_BC_BC_MAX +#define DUK__MAX_FUNCS DUK_BC_BC_MAX +#define DUK__MAX_TEMPS 0xffffL + +/* Initial bytecode size allocation. */ +#if defined(DUK_USE_PREFER_SIZE) +#define DUK__BC_INITIAL_INSTS 16 +#else +#define DUK__BC_INITIAL_INSTS 256 +#endif + +#define DUK__RECURSION_INCREASE(comp_ctx, thr) \ + do { \ + DUK_DDD(DUK_DDDPRINT("RECURSION INCREASE: %s:%ld", \ + (const char *)DUK_FILE_MACRO, (long)DUK_LINE_MACRO)); \ + duk__comp_recursion_increase((comp_ctx)); \ + } while (0) + +#define DUK__RECURSION_DECREASE(comp_ctx, thr) \ + do { \ + DUK_DDD(DUK_DDDPRINT("RECURSION DECREASE: %s:%ld", \ + (const char *)DUK_FILE_MACRO, (long)DUK_LINE_MACRO)); \ + duk__comp_recursion_decrease((comp_ctx)); \ + } while (0) + +/* Value stack slot limits: these are quite approximate right now, and + * because they overlap in control flow, some could be eliminated. + */ +#define DUK__COMPILE_ENTRY_SLOTS 8 +#define DUK__FUNCTION_INIT_REQUIRE_SLOTS 16 +#define DUK__FUNCTION_BODY_REQUIRE_SLOTS 16 +#define DUK__PARSE_STATEMENTS_SLOTS 16 +#define DUK__PARSE_EXPR_SLOTS 16 + +/* Temporary structure used to pass a stack allocated region through + * duk_safe_call(). + */ +typedef struct { + duk_small_uint_t flags; + duk_compiler_ctx comp_ctx_alloc; + duk_lexer_point lex_pt_alloc; +} duk__compiler_stkstate; + +/* + * Prototypes + */ + +/* lexing */ +DUK_LOCAL_DECL void duk__advance_helper(duk_compiler_ctx *comp_ctx, + duk_small_int_t expect); +DUK_LOCAL_DECL void duk__advance_expect(duk_compiler_ctx *comp_ctx, + duk_small_int_t expect); +DUK_LOCAL_DECL void duk__advance(duk_compiler_ctx *ctx); + +/* function helpers */ +DUK_LOCAL_DECL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx); +DUK_LOCAL_DECL void duk__reset_func_for_pass2(duk_compiler_ctx *comp_ctx); +DUK_LOCAL_DECL void duk__init_varmap_and_prologue_for_pass2( + duk_compiler_ctx *comp_ctx, duk_regconst_t *out_stmt_value_reg); +DUK_LOCAL_DECL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx); +DUK_LOCAL_DECL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx); + +/* code emission */ +DUK_LOCAL_DECL duk_int_t duk__get_current_pc(duk_compiler_ctx *comp_ctx); +DUK_LOCAL_DECL duk_compiler_instr *duk__get_instr_ptr( + duk_compiler_ctx *comp_ctx, duk_int_t pc); +DUK_LOCAL_DECL void duk__emit(duk_compiler_ctx *comp_ctx, duk_instr_t ins); +DUK_LOCAL_DECL void duk__emit_op_only(duk_compiler_ctx *comp_ctx, + duk_small_uint_t op); +DUK_LOCAL_DECL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, + duk_small_uint_t op_flags, duk_regconst_t a, + duk_regconst_t b, duk_regconst_t c); +DUK_LOCAL_DECL void duk__emit_a_b(duk_compiler_ctx *comp_ctx, + duk_small_uint_t op_flags, duk_regconst_t a, + duk_regconst_t b); +DUK_LOCAL_DECL void duk__emit_b_c(duk_compiler_ctx *comp_ctx, + duk_small_uint_t op_flags, duk_regconst_t b, + duk_regconst_t c); +#if 0 /* unused */ +DUK_LOCAL_DECL void duk__emit_a(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a); +DUK_LOCAL_DECL void duk__emit_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b); +#endif +DUK_LOCAL_DECL void duk__emit_a_bc(duk_compiler_ctx *comp_ctx, + duk_small_uint_t op_flags, duk_regconst_t a, + duk_regconst_t bc); +DUK_LOCAL_DECL void duk__emit_bc(duk_compiler_ctx *comp_ctx, + duk_small_uint_t op, duk_regconst_t bc); +DUK_LOCAL_DECL void duk__emit_abc(duk_compiler_ctx *comp_ctx, + duk_small_uint_t op, duk_regconst_t abc); +DUK_LOCAL_DECL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, + duk_regconst_t reg, duk_int32_t val); +DUK_LOCAL_DECL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, + duk_regconst_t reg, + duk_int32_t val); +DUK_LOCAL_DECL void duk__emit_jump(duk_compiler_ctx *comp_ctx, + duk_int_t target_pc); +DUK_LOCAL_DECL duk_int_t duk__emit_jump_empty(duk_compiler_ctx *comp_ctx); +DUK_LOCAL_DECL void duk__insert_jump_entry(duk_compiler_ctx *comp_ctx, + duk_int_t jump_pc); +DUK_LOCAL_DECL void duk__patch_jump(duk_compiler_ctx *comp_ctx, + duk_int_t jump_pc, duk_int_t target_pc); +DUK_LOCAL_DECL void duk__patch_jump_here(duk_compiler_ctx *comp_ctx, + duk_int_t jump_pc); +DUK_LOCAL_DECL void duk__patch_trycatch(duk_compiler_ctx *comp_ctx, + duk_int_t ldconst_pc, + duk_int_t trycatch_pc, + duk_regconst_t reg_catch, + duk_regconst_t const_varname, + duk_small_uint_t flags); +DUK_LOCAL_DECL void duk__emit_if_false_skip(duk_compiler_ctx *comp_ctx, + duk_regconst_t regconst); +DUK_LOCAL_DECL void duk__emit_if_true_skip(duk_compiler_ctx *comp_ctx, + duk_regconst_t regconst); +DUK_LOCAL_DECL void duk__emit_invalid(duk_compiler_ctx *comp_ctx); + +/* ivalue/ispec helpers */ +DUK_LOCAL_DECL void duk__ivalue_regconst(duk_ivalue *x, + duk_regconst_t regconst); +DUK_LOCAL_DECL void duk__ivalue_plain_fromstack(duk_compiler_ctx *comp_ctx, + duk_ivalue *x); +DUK_LOCAL_DECL void duk__ivalue_var_fromstack(duk_compiler_ctx *comp_ctx, + duk_ivalue *x); +DUK_LOCAL_DECL void duk__ivalue_var_hstring(duk_compiler_ctx *comp_ctx, + duk_ivalue *x, duk_hstring *h); +DUK_LOCAL_DECL void duk__copy_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *src, + duk_ispec *dst); +DUK_LOCAL_DECL void duk__copy_ivalue(duk_compiler_ctx *comp_ctx, + duk_ivalue *src, duk_ivalue *dst); +DUK_LOCAL_DECL duk_regconst_t duk__alloctemps(duk_compiler_ctx *comp_ctx, + duk_small_int_t num); +DUK_LOCAL_DECL duk_regconst_t duk__alloctemp(duk_compiler_ctx *comp_ctx); +DUK_LOCAL_DECL void duk__settemp_checkmax(duk_compiler_ctx *comp_ctx, + duk_regconst_t temp_next); +DUK_LOCAL_DECL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx); +DUK_LOCAL_DECL +duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx, + duk_ispec *x, + duk_regconst_t forced_reg, + duk_small_uint_t flags); +DUK_LOCAL_DECL void duk__ispec_toforcedreg(duk_compiler_ctx *comp_ctx, + duk_ispec *x, + duk_regconst_t forced_reg); +DUK_LOCAL_DECL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, + duk_ivalue *x, + duk_regconst_t forced_reg); +DUK_LOCAL_DECL void duk__ivalue_toplain(duk_compiler_ctx *comp_ctx, + duk_ivalue *x); +DUK_LOCAL_DECL void duk__ivalue_toplain_ignore(duk_compiler_ctx *comp_ctx, + duk_ivalue *x); +DUK_LOCAL_DECL +duk_regconst_t duk__ivalue_toregconst_raw(duk_compiler_ctx *comp_ctx, + duk_ivalue *x, + duk_regconst_t forced_reg, + duk_small_uint_t flags); +DUK_LOCAL_DECL duk_regconst_t duk__ivalue_toreg(duk_compiler_ctx *comp_ctx, + duk_ivalue *x); +#if 0 /* unused */ +DUK_LOCAL_DECL duk_regconst_t duk__ivalue_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *x); +#endif +DUK_LOCAL_DECL void duk__ivalue_toforcedreg(duk_compiler_ctx *comp_ctx, + duk_ivalue *x, + duk_int_t forced_reg); +DUK_LOCAL_DECL duk_regconst_t duk__ivalue_toregconst(duk_compiler_ctx *comp_ctx, + duk_ivalue *x); +DUK_LOCAL_DECL duk_regconst_t +duk__ivalue_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *x); + +/* identifier handling */ +DUK_LOCAL_DECL duk_regconst_t +duk__lookup_active_register_binding(duk_compiler_ctx *comp_ctx); +DUK_LOCAL_DECL duk_bool_t duk__lookup_lhs(duk_compiler_ctx *ctx, + duk_regconst_t *out_reg_varbind, + duk_regconst_t *out_rc_varname); + +/* label handling */ +DUK_LOCAL_DECL void duk__add_label(duk_compiler_ctx *comp_ctx, + duk_hstring *h_label, duk_int_t pc_label, + duk_int_t label_id); +DUK_LOCAL_DECL void duk__update_label_flags(duk_compiler_ctx *comp_ctx, + duk_int_t label_id, + duk_small_uint_t flags); +DUK_LOCAL_DECL void duk__lookup_active_label( + duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_bool_t is_break, + duk_int_t *out_label_id, duk_int_t *out_label_catch_depth, + duk_int_t *out_label_pc, duk_bool_t *out_is_closest); +DUK_LOCAL_DECL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, + duk_size_t len); + +/* top-down expression parser */ +DUK_LOCAL_DECL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res); +DUK_LOCAL_DECL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, + duk_ivalue *res); +DUK_LOCAL_DECL duk_small_uint_t duk__expr_lbp(duk_compiler_ctx *comp_ctx); +DUK_LOCAL_DECL duk_bool_t duk__expr_is_empty(duk_compiler_ctx *comp_ctx); + +/* exprtop is the top level variant which resets nud/led counts */ +DUK_LOCAL_DECL void duk__expr(duk_compiler_ctx *comp_ctx, duk_ivalue *res, + duk_small_uint_t rbp_flags); +DUK_LOCAL_DECL void duk__exprtop(duk_compiler_ctx *ctx, duk_ivalue *res, + duk_small_uint_t rbp_flags); + +/* convenience helpers */ +#if 0 /* unused */ +DUK_LOCAL_DECL duk_regconst_t duk__expr_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags); +#endif +#if 0 /* unused */ +DUK_LOCAL_DECL duk_regconst_t duk__expr_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags); +#endif +DUK_LOCAL_DECL void duk__expr_toforcedreg(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_small_uint_t rbp_flags, + duk_regconst_t forced_reg); +DUK_LOCAL_DECL duk_regconst_t duk__expr_toregconst(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_small_uint_t rbp_flags); +#if 0 /* unused */ +DUK_LOCAL_DECL duk_regconst_t duk__expr_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags); +#endif +DUK_LOCAL_DECL void duk__expr_toplain(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_small_uint_t rbp_flags); +DUK_LOCAL_DECL void duk__expr_toplain_ignore(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_small_uint_t rbp_flags); +DUK_LOCAL_DECL duk_regconst_t duk__exprtop_toreg(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_small_uint_t rbp_flags); +#if 0 /* unused */ +DUK_LOCAL_DECL duk_regconst_t duk__exprtop_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags); +#endif +DUK_LOCAL_DECL void duk__exprtop_toforcedreg(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_small_uint_t rbp_flags, + duk_regconst_t forced_reg); +DUK_LOCAL_DECL duk_regconst_t duk__exprtop_toregconst( + duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags); +#if 0 /* unused */ +DUK_LOCAL_DECL void duk__exprtop_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags); +#endif + +/* expression parsing helpers */ +DUK_LOCAL_DECL duk_int_t duk__parse_arguments(duk_compiler_ctx *comp_ctx, + duk_ivalue *res); +DUK_LOCAL_DECL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, + duk_ivalue *res); +DUK_LOCAL_DECL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, + duk_ivalue *res); + +/* statement parsing */ +DUK_LOCAL_DECL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_small_uint_t expr_flags, + duk_regconst_t *out_reg_varbind, + duk_regconst_t *out_rc_varname); +DUK_LOCAL_DECL void duk__parse_var_stmt(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_small_uint_t expr_flags); +DUK_LOCAL_DECL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_int_t pc_label_site); +DUK_LOCAL_DECL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_int_t pc_label_site); +DUK_LOCAL_DECL void duk__parse_if_stmt(duk_compiler_ctx *comp_ctx, + duk_ivalue *res); +DUK_LOCAL_DECL void duk__parse_do_stmt(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_int_t pc_label_site); +DUK_LOCAL_DECL void duk__parse_while_stmt(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_int_t pc_label_site); +DUK_LOCAL_DECL void duk__parse_break_or_continue_stmt( + duk_compiler_ctx *comp_ctx, duk_ivalue *res); +DUK_LOCAL_DECL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx, + duk_ivalue *res); +DUK_LOCAL_DECL void duk__parse_throw_stmt(duk_compiler_ctx *comp_ctx, + duk_ivalue *res); +DUK_LOCAL_DECL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, + duk_ivalue *res); +DUK_LOCAL_DECL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, + duk_ivalue *res); +DUK_LOCAL_DECL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, + duk_bool_t allow_source_elem); +DUK_LOCAL_DECL duk_int_t duk__stmt_label_site(duk_compiler_ctx *comp_ctx, + duk_int_t label_id); +DUK_LOCAL_DECL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, + duk_bool_t allow_source_elem, + duk_bool_t expect_eof, + duk_bool_t regexp_after); + +DUK_LOCAL_DECL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, + duk_bool_t expect_eof, + duk_bool_t implicit_return_value, + duk_bool_t regexp_after, + duk_small_int_t expect_token); +DUK_LOCAL_DECL void duk__parse_func_formals(duk_compiler_ctx *comp_ctx); +DUK_LOCAL_DECL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, + duk_small_uint_t flags); +DUK_LOCAL_DECL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, + duk_small_uint_t flags); + +#define DUK__FUNC_FLAG_DECL (1u << 0) /* Parsing a function declaration. */ +#define DUK__FUNC_FLAG_GETSET \ + (1u << 1) /* Parsing an object literal getter/setter. */ +#define DUK__FUNC_FLAG_METDEF \ + (1u << 2) /* Parsing an object literal method definition shorthand. */ +#define DUK__FUNC_FLAG_PUSHNAME_PASS1 \ + (1u << 3) /* Push function name when creating template (first pass only). */ +#define DUK__FUNC_FLAG_USE_PREVTOKEN \ + (1u << 4) /* Use prev_token to start function parsing (workaround for object \ + literal). */ + +/* + * Parser control values for tokens. The token table is ordered by the + * DUK_TOK_XXX defines. + * + * The binding powers are for lbp() use (i.e. for use in led() context). + * Binding powers are positive for typing convenience, and bits at the + * top should be reserved for flags. Binding power step must be higher + * than 1 so that binding power "lbp - 1" can be used for right associative + * operators. Currently a step of 2 is used (which frees one more bit for + * flags). + */ + +/* XXX: actually single step levels would work just fine, clean up */ + +/* binding power "levels" (see doc/compiler.rst) */ +#define DUK__BP_INVALID 0 /* always terminates led() */ +#define DUK__BP_EOF 2 +#define DUK__BP_CLOSING 4 /* token closes expression, e.g. ')', ']' */ +#define DUK__BP_FOR_EXPR \ + DUK__BP_CLOSING /* bp to use when parsing a top level Expression */ +#define DUK__BP_COMMA 6 +#define DUK__BP_ASSIGNMENT 8 +#define DUK__BP_CONDITIONAL 10 +#define DUK__BP_LOR 12 +#define DUK__BP_LAND 14 +#define DUK__BP_BOR 16 +#define DUK__BP_BXOR 18 +#define DUK__BP_BAND 20 +#define DUK__BP_EQUALITY 22 +#define DUK__BP_RELATIONAL 24 +#define DUK__BP_SHIFT 26 +#define DUK__BP_ADDITIVE 28 +#define DUK__BP_MULTIPLICATIVE 30 +#define DUK__BP_EXPONENTIATION 32 +#define DUK__BP_POSTFIX 34 +#define DUK__BP_CALL 36 +#define DUK__BP_MEMBER 38 + +#define DUK__TOKEN_LBP_BP_MASK 0x1f +#define DUK__TOKEN_LBP_FLAG_NO_REGEXP \ + (1u << 5) /* regexp literal must not follow this token */ +#define DUK__TOKEN_LBP_FLAG_TERMINATES \ + (1u << 6) /* terminates expression; e.g. post-increment/-decrement */ +#define DUK__TOKEN_LBP_FLAG_UNUSED (1u << 7) /* unused */ + +#define DUK__TOKEN_LBP_GET_BP(x) \ + ((duk_small_uint_t)(((x)&DUK__TOKEN_LBP_BP_MASK) * 2)) + +#define DUK__MK_LBP(bp) ((bp) >> 1) /* bp is assumed to be even */ +#define DUK__MK_LBP_FLAGS(bp, flags) (((bp) >> 1) | (flags)) + +DUK_LOCAL const duk_uint8_t duk__token_lbp[] = { + DUK__MK_LBP(DUK__BP_EOF), /* DUK_TOK_EOF */ + DUK__MK_LBP_FLAGS(DUK__BP_INVALID, + DUK__TOKEN_LBP_FLAG_NO_REGEXP), /* DUK_TOK_IDENTIFIER */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_BREAK */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_CASE */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_CATCH */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_CONTINUE */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_DEBUGGER */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_DEFAULT */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_DELETE */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_DO */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_ELSE */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_FINALLY */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_FOR */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_FUNCTION */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_IF */ + DUK__MK_LBP(DUK__BP_RELATIONAL), /* DUK_TOK_IN */ + DUK__MK_LBP(DUK__BP_RELATIONAL), /* DUK_TOK_INSTANCEOF */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_NEW */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_RETURN */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_SWITCH */ + DUK__MK_LBP_FLAGS(DUK__BP_INVALID, + DUK__TOKEN_LBP_FLAG_NO_REGEXP), /* DUK_TOK_THIS */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_THROW */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_TRY */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_TYPEOF */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_VAR */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_CONST */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_VOID */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_WHILE */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_WITH */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_CLASS */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_ENUM */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_EXPORT */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_EXTENDS */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_IMPORT */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_SUPER */ + DUK__MK_LBP_FLAGS(DUK__BP_INVALID, + DUK__TOKEN_LBP_FLAG_NO_REGEXP), /* DUK_TOK_NULL */ + DUK__MK_LBP_FLAGS(DUK__BP_INVALID, + DUK__TOKEN_LBP_FLAG_NO_REGEXP), /* DUK_TOK_TRUE */ + DUK__MK_LBP_FLAGS(DUK__BP_INVALID, + DUK__TOKEN_LBP_FLAG_NO_REGEXP), /* DUK_TOK_FALSE */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_GET */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_SET */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_IMPLEMENTS */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_INTERFACE */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_LET */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_PACKAGE */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_PRIVATE */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_PROTECTED */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_PUBLIC */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_STATIC */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_YIELD */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_LCURLY */ + DUK__MK_LBP_FLAGS(DUK__BP_INVALID, + DUK__TOKEN_LBP_FLAG_NO_REGEXP), /* DUK_TOK_RCURLY */ + DUK__MK_LBP(DUK__BP_MEMBER), /* DUK_TOK_LBRACKET */ + DUK__MK_LBP_FLAGS(DUK__BP_CLOSING, + DUK__TOKEN_LBP_FLAG_NO_REGEXP), /* DUK_TOK_RBRACKET */ + DUK__MK_LBP(DUK__BP_CALL), /* DUK_TOK_LPAREN */ + DUK__MK_LBP_FLAGS(DUK__BP_CLOSING, + DUK__TOKEN_LBP_FLAG_NO_REGEXP), /* DUK_TOK_RPAREN */ + DUK__MK_LBP(DUK__BP_MEMBER), /* DUK_TOK_PERIOD */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_SEMICOLON */ + DUK__MK_LBP(DUK__BP_COMMA), /* DUK_TOK_COMMA */ + DUK__MK_LBP(DUK__BP_RELATIONAL), /* DUK_TOK_LT */ + DUK__MK_LBP(DUK__BP_RELATIONAL), /* DUK_TOK_GT */ + DUK__MK_LBP(DUK__BP_RELATIONAL), /* DUK_TOK_LE */ + DUK__MK_LBP(DUK__BP_RELATIONAL), /* DUK_TOK_GE */ + DUK__MK_LBP(DUK__BP_EQUALITY), /* DUK_TOK_EQ */ + DUK__MK_LBP(DUK__BP_EQUALITY), /* DUK_TOK_NEQ */ + DUK__MK_LBP(DUK__BP_EQUALITY), /* DUK_TOK_SEQ */ + DUK__MK_LBP(DUK__BP_EQUALITY), /* DUK_TOK_SNEQ */ + DUK__MK_LBP(DUK__BP_ADDITIVE), /* DUK_TOK_ADD */ + DUK__MK_LBP(DUK__BP_ADDITIVE), /* DUK_TOK_SUB */ + DUK__MK_LBP(DUK__BP_MULTIPLICATIVE), /* DUK_TOK_MUL */ + DUK__MK_LBP(DUK__BP_MULTIPLICATIVE), /* DUK_TOK_DIV */ + DUK__MK_LBP(DUK__BP_MULTIPLICATIVE), /* DUK_TOK_MOD */ + DUK__MK_LBP(DUK__BP_EXPONENTIATION), /* DUK_TOK_EXP */ + DUK__MK_LBP_FLAGS(DUK__BP_POSTFIX, + DUK__TOKEN_LBP_FLAG_NO_REGEXP), /* DUK_TOK_INCREMENT */ + DUK__MK_LBP_FLAGS(DUK__BP_POSTFIX, + DUK__TOKEN_LBP_FLAG_NO_REGEXP), /* DUK_TOK_DECREMENT */ + DUK__MK_LBP(DUK__BP_SHIFT), /* DUK_TOK_ALSHIFT */ + DUK__MK_LBP(DUK__BP_SHIFT), /* DUK_TOK_ARSHIFT */ + DUK__MK_LBP(DUK__BP_SHIFT), /* DUK_TOK_RSHIFT */ + DUK__MK_LBP(DUK__BP_BAND), /* DUK_TOK_BAND */ + DUK__MK_LBP(DUK__BP_BOR), /* DUK_TOK_BOR */ + DUK__MK_LBP(DUK__BP_BXOR), /* DUK_TOK_BXOR */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_LNOT */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_BNOT */ + DUK__MK_LBP(DUK__BP_LAND), /* DUK_TOK_LAND */ + DUK__MK_LBP(DUK__BP_LOR), /* DUK_TOK_LOR */ + DUK__MK_LBP(DUK__BP_CONDITIONAL), /* DUK_TOK_QUESTION */ + DUK__MK_LBP(DUK__BP_INVALID), /* DUK_TOK_COLON */ + DUK__MK_LBP(DUK__BP_ASSIGNMENT), /* DUK_TOK_EQUALSIGN */ + DUK__MK_LBP(DUK__BP_ASSIGNMENT), /* DUK_TOK_ADD_EQ */ + DUK__MK_LBP(DUK__BP_ASSIGNMENT), /* DUK_TOK_SUB_EQ */ + DUK__MK_LBP(DUK__BP_ASSIGNMENT), /* DUK_TOK_MUL_EQ */ + DUK__MK_LBP(DUK__BP_ASSIGNMENT), /* DUK_TOK_DIV_EQ */ + DUK__MK_LBP(DUK__BP_ASSIGNMENT), /* DUK_TOK_MOD_EQ */ + DUK__MK_LBP(DUK__BP_ASSIGNMENT), /* DUK_TOK_EXP_EQ */ + DUK__MK_LBP(DUK__BP_ASSIGNMENT), /* DUK_TOK_ALSHIFT_EQ */ + DUK__MK_LBP(DUK__BP_ASSIGNMENT), /* DUK_TOK_ARSHIFT_EQ */ + DUK__MK_LBP(DUK__BP_ASSIGNMENT), /* DUK_TOK_RSHIFT_EQ */ + DUK__MK_LBP(DUK__BP_ASSIGNMENT), /* DUK_TOK_BAND_EQ */ + DUK__MK_LBP(DUK__BP_ASSIGNMENT), /* DUK_TOK_BOR_EQ */ + DUK__MK_LBP(DUK__BP_ASSIGNMENT), /* DUK_TOK_BXOR_EQ */ + DUK__MK_LBP_FLAGS(DUK__BP_INVALID, + DUK__TOKEN_LBP_FLAG_NO_REGEXP), /* DUK_TOK_NUMBER */ + DUK__MK_LBP_FLAGS(DUK__BP_INVALID, + DUK__TOKEN_LBP_FLAG_NO_REGEXP), /* DUK_TOK_STRING */ + DUK__MK_LBP_FLAGS(DUK__BP_INVALID, + DUK__TOKEN_LBP_FLAG_NO_REGEXP), /* DUK_TOK_REGEXP */ +}; + +/* + * Misc helpers + */ + +DUK_LOCAL void duk__comp_recursion_increase(duk_compiler_ctx *comp_ctx) { + DUK_ASSERT(comp_ctx != NULL); + DUK_ASSERT(comp_ctx->recursion_depth >= 0); + if (comp_ctx->recursion_depth >= comp_ctx->recursion_limit) { + DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_COMPILER_RECURSION_LIMIT); + DUK_WO_NORETURN(return;); + } + comp_ctx->recursion_depth++; +} + +DUK_LOCAL void duk__comp_recursion_decrease(duk_compiler_ctx *comp_ctx) { + DUK_ASSERT(comp_ctx != NULL); + DUK_ASSERT(comp_ctx->recursion_depth > 0); + comp_ctx->recursion_depth--; +} + +DUK_LOCAL duk_bool_t +duk__hstring_is_eval_or_arguments(duk_compiler_ctx *comp_ctx, duk_hstring *h) { + DUK_UNREF(comp_ctx); + DUK_ASSERT(h != NULL); + return DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(h); +} + +DUK_LOCAL duk_bool_t duk__hstring_is_eval_or_arguments_in_strict_mode( + duk_compiler_ctx *comp_ctx, duk_hstring *h) { + DUK_ASSERT(h != NULL); + return (comp_ctx->curr_func.is_strict && + DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(h)); +} + +/* + * Parser duk__advance() token eating functions + */ + +/* XXX: valstack handling is awkward. Add a valstack helper which + * avoids dup():ing; valstack_copy(src, dst)? + */ + +DUK_LOCAL void duk__advance_helper(duk_compiler_ctx *comp_ctx, + duk_small_int_t expect) { + duk_hthread *thr = comp_ctx->thr; + duk_bool_t regexp; + + DUK_ASSERT_DISABLE(comp_ctx->curr_token.t >= 0); /* unsigned */ + DUK_ASSERT(comp_ctx->curr_token.t <= + DUK_TOK_MAXVAL); /* MAXVAL is inclusive */ + + /* + * Use current token to decide whether a RegExp can follow. + * + * We can use either 't' or 't_nores'; the latter would not + * recognize keywords. Some keywords can be followed by a + * RegExp (e.g. "return"), so using 't' is better. This is + * not trivial, see doc/compiler.rst. + */ + + regexp = 1; + if (duk__token_lbp[comp_ctx->curr_token.t] & DUK__TOKEN_LBP_FLAG_NO_REGEXP) { + regexp = 0; + } + if (comp_ctx->curr_func.reject_regexp_in_adv) { + comp_ctx->curr_func.reject_regexp_in_adv = 0; + regexp = 0; + } + if (comp_ctx->curr_func.allow_regexp_in_adv) { + comp_ctx->curr_func.allow_regexp_in_adv = 0; + regexp = 1; + } + + if (expect >= 0 && comp_ctx->curr_token.t != (duk_small_uint_t)expect) { + DUK_D(DUK_DPRINT("parse error: expect=%ld, got=%ld", (long)expect, + (long)comp_ctx->curr_token.t)); + DUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR); + DUK_WO_NORETURN(return;); + } + + /* make current token the previous; need to fiddle with valstack "backing + * store" */ + duk_memcpy(&comp_ctx->prev_token, &comp_ctx->curr_token, sizeof(duk_token)); + duk_copy(thr, comp_ctx->tok11_idx, comp_ctx->tok21_idx); + duk_copy(thr, comp_ctx->tok12_idx, comp_ctx->tok22_idx); + + /* parse new token */ + duk_lexer_parse_js_input_element(&comp_ctx->lex, &comp_ctx->curr_token, + comp_ctx->curr_func.is_strict, regexp); + + DUK_DDD(DUK_DDDPRINT( + "advance: curr: tok=%ld/%ld,%ld,term=%ld,%!T,%!T " + "prev: tok=%ld/%ld,%ld,term=%ld,%!T,%!T", + (long)comp_ctx->curr_token.t, (long)comp_ctx->curr_token.t_nores, + (long)comp_ctx->curr_token.start_line, + (long)comp_ctx->curr_token.lineterm, + (duk_tval *)duk_get_tval(thr, comp_ctx->tok11_idx), + (duk_tval *)duk_get_tval(thr, comp_ctx->tok12_idx), + (long)comp_ctx->prev_token.t, (long)comp_ctx->prev_token.t_nores, + (long)comp_ctx->prev_token.start_line, + (long)comp_ctx->prev_token.lineterm, + (duk_tval *)duk_get_tval(thr, comp_ctx->tok21_idx), + (duk_tval *)duk_get_tval(thr, comp_ctx->tok22_idx))); +} + +/* advance, expecting current token to be a specific token; parse next token in + * regexp context */ +DUK_LOCAL void duk__advance_expect(duk_compiler_ctx *comp_ctx, + duk_small_int_t expect) { + duk__advance_helper(comp_ctx, expect); +} + +/* advance, whatever the current token is; parse next token in regexp context */ +DUK_LOCAL void duk__advance(duk_compiler_ctx *comp_ctx) { + duk__advance_helper(comp_ctx, -1); +} + +/* + * Helpers for duk_compiler_func. + */ + +/* init function state: inits valstack allocations */ +DUK_LOCAL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx) { + duk_compiler_func *func = &comp_ctx->curr_func; + duk_hthread *thr = comp_ctx->thr; + duk_idx_t entry_top; + + entry_top = duk_get_top(thr); + + duk_memzero(func, + sizeof(*func)); /* intentional overlap with earlier memzero */ +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + func->h_name = NULL; + func->h_consts = NULL; + func->h_funcs = NULL; + func->h_decls = NULL; + func->h_labelnames = NULL; + func->h_labelinfos = NULL; + func->h_argnames = NULL; + func->h_varmap = NULL; +#endif + + duk_require_stack(thr, DUK__FUNCTION_INIT_REQUIRE_SLOTS); + + DUK_BW_INIT_PUSHBUF(thr, &func->bw_code, + DUK__BC_INITIAL_INSTS * sizeof(duk_compiler_instr)); + /* code_idx = entry_top + 0 */ + + duk_push_bare_array(thr); + func->consts_idx = entry_top + 1; + func->h_consts = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 1); + DUK_ASSERT(func->h_consts != NULL); + + duk_push_bare_array(thr); + func->funcs_idx = entry_top + 2; + func->h_funcs = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 2); + DUK_ASSERT(func->h_funcs != NULL); + DUK_ASSERT(func->fnum_next == 0); + + duk_push_bare_array(thr); + func->decls_idx = entry_top + 3; + func->h_decls = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 3); + DUK_ASSERT(func->h_decls != NULL); + + duk_push_bare_array(thr); + func->labelnames_idx = entry_top + 4; + func->h_labelnames = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 4); + DUK_ASSERT(func->h_labelnames != NULL); + + duk_push_dynamic_buffer(thr, 0); + func->labelinfos_idx = entry_top + 5; + func->h_labelinfos = + (duk_hbuffer_dynamic *)duk_known_hbuffer(thr, entry_top + 5); + DUK_ASSERT(func->h_labelinfos != NULL); + DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(func->h_labelinfos) && + !DUK_HBUFFER_HAS_EXTERNAL(func->h_labelinfos)); + + duk_push_bare_array(thr); + func->argnames_idx = entry_top + 6; + func->h_argnames = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 6); + DUK_ASSERT(func->h_argnames != NULL); + + duk_push_bare_object(thr); + func->varmap_idx = entry_top + 7; + func->h_varmap = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 7); + DUK_ASSERT(func->h_varmap != NULL); +} + +/* reset function state (prepare for pass 2) */ +DUK_LOCAL void duk__reset_func_for_pass2(duk_compiler_ctx *comp_ctx) { + duk_compiler_func *func = &comp_ctx->curr_func; + duk_hthread *thr = comp_ctx->thr; + + /* reset bytecode buffer but keep current size; pass 2 will + * require same amount or more. + */ + DUK_BW_RESET_SIZE(thr, &func->bw_code); + + duk_set_length(thr, func->consts_idx, 0); + /* keep func->h_funcs; inner functions are not reparsed to avoid O(depth^2) + * parsing */ + func->fnum_next = 0; + /* duk_set_length(thr, func->funcs_idx, 0); */ + duk_set_length(thr, func->labelnames_idx, 0); + duk_hbuffer_reset(thr, func->h_labelinfos); + /* keep func->h_argnames; it is fixed for all passes */ + + /* truncated in case pass 3 needed */ + duk_push_bare_object(thr); + duk_replace(thr, func->varmap_idx); + func->h_varmap = DUK_GET_HOBJECT_POSIDX(thr, func->varmap_idx); + DUK_ASSERT(func->h_varmap != NULL); +} + +/* cleanup varmap from any null entries, compact it, etc; returns number + * of final entries after cleanup. + */ +DUK_LOCAL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx) { + duk_hthread *thr = comp_ctx->thr; + duk_hobject *h_varmap; + duk_hstring *h_key; + duk_tval *tv; + duk_uint32_t i, e_next; + duk_int_t ret; + + /* [ ... varmap ] */ + + h_varmap = DUK_GET_HOBJECT_NEGIDX(thr, -1); + DUK_ASSERT(h_varmap != NULL); + + ret = 0; + e_next = DUK_HOBJECT_GET_ENEXT(h_varmap); + for (i = 0; i < e_next; i++) { + h_key = DUK_HOBJECT_E_GET_KEY(thr->heap, h_varmap, i); + if (!h_key) { + continue; + } + + DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, h_varmap, i)); + + /* The entries can either be register numbers or 'null' values. + * Thus, no need to DECREF them and get side effects. DECREF'ing + * the keys (strings) can cause memory to be freed but no side + * effects as strings don't have finalizers. This is why we can + * rely on the object properties not changing from underneath us. + */ + + tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, h_varmap, i); + if (!DUK_TVAL_IS_NUMBER(tv)) { + DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv)); + DUK_HOBJECT_E_SET_KEY(thr->heap, h_varmap, i, NULL); + DUK_HSTRING_DECREF(thr, h_key); + /* when key is NULL, value is garbage so no need to set */ + } else { + ret++; + } + } + + duk_compact_m1(thr); + + return ret; +} + +/* Convert duk_compiler_func into a function template, leaving the result + * on top of stack. + */ +/* XXX: awkward and bloated asm -- use faster internal accesses */ +DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) { + duk_compiler_func *func = &comp_ctx->curr_func; + duk_hthread *thr = comp_ctx->thr; + duk_hcompfunc *h_res; + duk_hbuffer_fixed *h_data; + duk_size_t consts_count; + duk_size_t funcs_count; + duk_size_t code_count; + duk_size_t code_size; + duk_size_t data_size; + duk_size_t i; + duk_tval *p_const; + duk_hobject **p_func; + duk_instr_t *p_instr; + duk_compiler_instr *q_instr; + duk_tval *tv; + duk_bool_t keep_varmap; + duk_bool_t keep_formals; +#if !defined(DUK_USE_DEBUGGER_SUPPORT) + duk_size_t formals_length; +#endif + + DUK_DDD(DUK_DDDPRINT("converting duk_compiler_func to function/template")); + + /* + * Push result object and init its flags + */ + + /* Valstack should suffice here, required on function valstack init */ + + h_res = duk_push_hcompfunc(thr); + DUK_ASSERT(h_res != NULL); + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *)h_res) == + thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]); + DUK_HOBJECT_SET_PROTOTYPE_UPDREF( + thr, (duk_hobject *)h_res, + NULL); /* Function templates are "bare objects". */ + + if (func->is_function) { + DUK_DDD(DUK_DDDPRINT("function -> set NEWENV")); + DUK_HOBJECT_SET_NEWENV((duk_hobject *)h_res); + + if (!func->is_arguments_shadowed) { + /* arguments object would be accessible; note that shadowing + * bindings are arguments or function declarations, neither + * of which are deletable, so this is safe. + */ + + if (func->id_access_arguments || func->may_direct_eval) { + DUK_DDD( + DUK_DDDPRINT("function may access 'arguments' object directly or " + "indirectly -> set CREATEARGS")); + DUK_HOBJECT_SET_CREATEARGS((duk_hobject *)h_res); + } + } + } else if (func->is_eval && func->is_strict) { + DUK_DDD(DUK_DDDPRINT("strict eval code -> set NEWENV")); + DUK_HOBJECT_SET_NEWENV((duk_hobject *)h_res); + } else { + /* non-strict eval: env is caller's env or global env (direct vs. indirect + * call) global code: env is is global env + */ + DUK_DDD(DUK_DDDPRINT("non-strict eval code or global code -> no NEWENV")); + DUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV((duk_hobject *)h_res)); + } + +#if defined(DUK_USE_FUNC_NAME_PROPERTY) + if (func->is_function && func->is_namebinding && func->h_name != NULL) { + /* Object literal set/get functions have a name (property + * name) but must not have a lexical name binding, see + * test-bug-getset-func-name.js. + */ + DUK_DDD(DUK_DDDPRINT("function expression with a name -> set NAMEBINDING")); + DUK_HOBJECT_SET_NAMEBINDING((duk_hobject *)h_res); + } +#endif + + if (func->is_strict) { + DUK_DDD(DUK_DDDPRINT("function is strict -> set STRICT")); + DUK_HOBJECT_SET_STRICT((duk_hobject *)h_res); + } + + if (func->is_notail) { + DUK_DDD(DUK_DDDPRINT("function is notail -> set NOTAIL")); + DUK_HOBJECT_SET_NOTAIL((duk_hobject *)h_res); + } + + if (func->is_constructable) { + DUK_DDD(DUK_DDDPRINT("function is constructable -> set CONSTRUCTABLE")); + DUK_HOBJECT_SET_CONSTRUCTABLE((duk_hobject *)h_res); + } + + /* + * Build function fixed size 'data' buffer, which contains bytecode, + * constants, and inner function references. + * + * During the building phase 'data' is reachable but incomplete. + * Only incref's occur during building (no refzero or GC happens), + * so the building process is atomic. + */ + + consts_count = duk_hobject_get_length(thr, func->h_consts); + funcs_count = duk_hobject_get_length(thr, func->h_funcs) / 3; + code_count = + DUK_BW_GET_SIZE(thr, &func->bw_code) / sizeof(duk_compiler_instr); + code_size = code_count * sizeof(duk_instr_t); + + data_size = consts_count * sizeof(duk_tval) + + funcs_count * sizeof(duk_hobject *) + code_size; + + DUK_DDD(DUK_DDDPRINT("consts_count=%ld, funcs_count=%ld, code_size=%ld -> " + "data_size=%ld*%ld + %ld*%ld + %ld = %ld", + (long)consts_count, (long)funcs_count, (long)code_size, + (long)consts_count, (long)sizeof(duk_tval), + (long)funcs_count, (long)sizeof(duk_hobject *), + (long)code_size, (long)data_size)); + + duk_push_fixed_buffer_nozero(thr, data_size); + h_data = (duk_hbuffer_fixed *)(void *)duk_known_hbuffer(thr, -1); + + DUK_HCOMPFUNC_SET_DATA(thr->heap, h_res, (duk_hbuffer *)h_data); + DUK_HEAPHDR_INCREF(thr, h_data); + + p_const = + (duk_tval *)(void *)DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, h_data); + for (i = 0; i < consts_count; i++) { + DUK_ASSERT(i <= DUK_UARRIDX_MAX); /* const limits */ + tv = duk_hobject_find_array_entry_tval_ptr(thr->heap, func->h_consts, + (duk_uarridx_t)i); + DUK_ASSERT(tv != NULL); + DUK_TVAL_SET_TVAL(p_const, tv); + p_const++; + DUK_TVAL_INCREF(thr, tv); /* may be a string constant */ + + DUK_DDD(DUK_DDDPRINT("constant: %!T", (duk_tval *)tv)); + } + + p_func = (duk_hobject **)p_const; + DUK_HCOMPFUNC_SET_FUNCS(thr->heap, h_res, p_func); + for (i = 0; i < funcs_count; i++) { + duk_hobject *h; + DUK_ASSERT(i * 3 <= DUK_UARRIDX_MAX); /* func limits */ + tv = duk_hobject_find_array_entry_tval_ptr(thr->heap, func->h_funcs, + (duk_uarridx_t)(i * 3)); + DUK_ASSERT(tv != NULL); + DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv)); + h = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(h != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(h)); + *p_func++ = h; + DUK_HOBJECT_INCREF(thr, h); + + DUK_DDD(DUK_DDDPRINT("inner function: %p -> %!iO", (void *)h, + (duk_heaphdr *)h)); + } + + p_instr = (duk_instr_t *)p_func; + DUK_HCOMPFUNC_SET_BYTECODE(thr->heap, h_res, p_instr); + + /* copy bytecode instructions one at a time */ + q_instr = + (duk_compiler_instr *)(void *)DUK_BW_GET_BASEPTR(thr, &func->bw_code); + for (i = 0; i < code_count; i++) { + p_instr[i] = q_instr[i].ins; + } + /* Note: 'q_instr' is still used below */ + + DUK_ASSERT((duk_uint8_t *)(p_instr + code_count) == + DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, h_data) + data_size); + + duk_pop( + thr); /* 'data' (and everything in it) is reachable through h_res now */ + + /* + * Init non-property result fields + * + * 'nregs' controls how large a register frame is allocated. + * + * 'nargs' controls how many formal arguments are written to registers: + * r0, ... r(nargs-1). The remaining registers are initialized to + * undefined. + */ + + DUK_ASSERT(func->temp_max >= 0); + h_res->nregs = (duk_uint16_t)func->temp_max; + h_res->nargs = (duk_uint16_t)duk_hobject_get_length(thr, func->h_argnames); + DUK_ASSERT(h_res->nregs >= h_res->nargs); /* pass2 allocation handles this */ +#if defined(DUK_USE_DEBUGGER_SUPPORT) + h_res->start_line = (duk_uint32_t)func->min_line; + h_res->end_line = (duk_uint32_t)func->max_line; +#endif + + /* + * Init object properties + * + * Properties should be added in decreasing order of access frequency. + * (Not very critical for function templates.) + */ + + DUK_DDD(DUK_DDDPRINT("init function properties")); + + /* [ ... res ] */ + + /* _Varmap: omitted if function is guaranteed not to do a slow path + * identifier access that might be caught by locally declared variables. + * The varmap can also be omitted if it turns out empty of actual + * register mappings after a cleanup. When debugging is enabled, we + * always need the varmap to be able to lookup variables at any point. + */ + +#if defined(DUK_USE_DEBUGGER_SUPPORT) + DUK_DD(DUK_DDPRINT("keeping _Varmap because debugger support is enabled")); + keep_varmap = 1; +#else + if (func->id_access_slow_own || /* directly uses slow accesses that may match + own variables */ + func->id_access_arguments || /* accesses 'arguments' directly */ + func->may_direct_eval || /* may indirectly slow access through a direct + eval */ + funcs_count > + 0) { /* has inner functions which may slow access (XXX: this can be + optimized by looking at the inner functions) */ + DUK_DD(DUK_DDPRINT( + "keeping _Varmap because of direct eval, slow path access that may " + "match local variables, or presence of inner functions")); + keep_varmap = 1; + } else { + DUK_DD(DUK_DDPRINT("dropping _Varmap")); + keep_varmap = 0; + } +#endif + + if (keep_varmap) { + duk_int_t num_used; + duk_dup(thr, func->varmap_idx); + num_used = duk__cleanup_varmap(comp_ctx); + DUK_DDD(DUK_DDDPRINT("cleaned up varmap: %!T (num_used=%ld)", + (duk_tval *)duk_get_tval(thr, -1), (long)num_used)); + + if (num_used > 0) { + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VARMAP, + DUK_PROPDESC_FLAGS_NONE); + } else { + DUK_DD(DUK_DDPRINT("varmap is empty after cleanup -> no need to add")); + duk_pop(thr); + } + } + + /* _Formals: omitted if function is guaranteed not to need a (non-strict) + * arguments object, and _Formals.length matches nargs exactly. + * + * Non-arrow functions can't see an outer function's 'argument' binding + * (because they have their own), but arrow functions can. When arrow + * functions are added, this condition would need to be added: + * inner_arrow_funcs_count > 0 inner arrow functions may access + * 'arguments' + */ +#if defined(DUK_USE_DEBUGGER_SUPPORT) + DUK_DD(DUK_DDPRINT("keeping _Formals because debugger support is enabled")); + keep_formals = 1; +#else + formals_length = duk_get_length(thr, func->argnames_idx); + if (formals_length != (duk_size_t)h_res->nargs) { + /* Nargs not enough for closure .length: keep _Formals regardless + * of its length. Shouldn't happen in practice at the moment. + */ + DUK_DD(DUK_DDPRINT("keeping _Formals because _Formals.length != nargs")); + keep_formals = 1; + } else if ((func->id_access_arguments || func->may_direct_eval) && + (formals_length > 0)) { + /* Direct eval (may access 'arguments') or accesses 'arguments' + * explicitly: keep _Formals unless it is zero length. + */ + DUK_DD(DUK_DDPRINT("keeping _Formals because of direct eval or explicit " + "access to 'arguments', and _Formals.length != 0")); + keep_formals = 1; + } else { + DUK_DD( + DUK_DDPRINT("omitting _Formals, nargs matches _Formals.length, so no " + "properties added")); + keep_formals = 0; + } +#endif + + if (keep_formals) { + duk_dup(thr, func->argnames_idx); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_FORMALS, + DUK_PROPDESC_FLAGS_NONE); + } + + /* name */ +#if defined(DUK_USE_FUNC_NAME_PROPERTY) + if (func->h_name) { + duk_push_hstring(thr, func->h_name); + DUK_DD(DUK_DDPRINT("setting function template .name to %!T", + duk_get_tval(thr, -1))); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, + DUK_PROPDESC_FLAGS_NONE); + } +#endif /* DUK_USE_FUNC_NAME_PROPERTY */ + + /* _Source */ +#if defined(DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY) + if (0) { + /* XXX: Currently function source code is not stored, as it is not + * required by the standard. Source code should not be stored by + * default (user should enable it explicitly), and the source should + * probably be compressed with a trivial text compressor; average + * compression of 20-30% is quite easy to achieve even with a trivial + * compressor (RLE + backwards lookup). + * + * Debugging needs source code to be useful: sometimes input code is + * not found in files as it may be generated and then eval()'d, given + * by dynamic C code, etc. + * + * Other issues: + * + * - Need tokenizer indices for start and end to substring + * - Always normalize function declaration part? + * - If we keep _Formals, only need to store body + */ + + /* + * For global or eval code this is straightforward. For functions + * created with the Function constructor we only get the source for + * the body and must manufacture the "function ..." part. + * + * For instance, for constructed functions (v8): + * + * > a = new Function("foo", "bar", "print(foo)"); + * [Function] + * > a.toString() + * 'function anonymous(foo,bar) {\nprint(foo)\n}' + * + * Similarly for e.g. getters (v8): + * + * > x = { get a(foo,bar) { print(foo); } } + * { a: [Getter] } + * > Object.getOwnPropertyDescriptor(x, 'a').get.toString() + * 'function a(foo,bar) { print(foo); }' + */ + +#if 0 + duk_push_literal(thr, "XXX"); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_SOURCE, DUK_PROPDESC_FLAGS_NONE); +#endif + } +#endif /* DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY */ + + /* _Pc2line */ +#if defined(DUK_USE_PC2LINE) + if (1) { + /* + * Size-optimized pc->line mapping. + */ + + DUK_ASSERT(code_count <= DUK_COMPILER_MAX_BYTECODE_LENGTH); + duk_hobject_pc2line_pack( + thr, q_instr, + (duk_uint_fast32_t)code_count); /* -> pushes fixed buffer */ + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_PC2LINE, + DUK_PROPDESC_FLAGS_NONE); + + /* XXX: if assertions enabled, walk through all valid PCs + * and check line mapping. + */ + } +#endif /* DUK_USE_PC2LINE */ + + /* fileName */ +#if defined(DUK_USE_FUNC_FILENAME_PROPERTY) + if (comp_ctx->h_filename) { + /* + * Source filename (or equivalent), for identifying thrown errors. + */ + + duk_push_hstring(thr, comp_ctx->h_filename); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, + DUK_PROPDESC_FLAGS_NONE); + } +#endif + + DUK_DD(DUK_DDPRINT("converted function: %!ixT", + (duk_tval *)duk_get_tval(thr, -1))); + + /* + * Compact the function template. + */ + + duk_compact_m1(thr); + + /* + * Debug dumping + */ + +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2) + { + duk_hcompfunc *h; + duk_instr_t *p, *p_start, *p_end; + + h = (duk_hcompfunc *)duk_get_hobject(thr, -1); + p_start = (duk_instr_t *)DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, h); + p_end = (duk_instr_t *)DUK_HCOMPFUNC_GET_CODE_END(thr->heap, h); + + p = p_start; + while (p < p_end) { + DUK_DDD(DUK_DDDPRINT( + "BC %04ld: %!I ; 0x%08lx op=%ld (%!X) a=%ld b=%ld c=%ld", + (long)(p - p_start), (duk_instr_t)(*p), (unsigned long)(*p), + (long)DUK_DEC_OP(*p), (long)DUK_DEC_OP(*p), (long)DUK_DEC_A(*p), + (long)DUK_DEC_B(*p), (long)DUK_DEC_C(*p))); + p++; + } + } +#endif +} + +/* + * Code emission helpers + * + * Some emission helpers understand the range of target and source reg/const + * values and automatically emit shuffling code if necessary. This is the + * case when the slot in question (A, B, C) is used in the standard way and + * for opcodes the emission helpers explicitly understand (like + * DUK_OP_MPUTOBJ). + * + * The standard way is that: + * - slot A is a target register + * - slot B is a source register/constant + * - slot C is a source register/constant + * + * If a slot is used in a non-standard way the caller must indicate this + * somehow. If a slot is used as a target instead of a source (or vice + * versa), this can be indicated with a flag to trigger proper shuffling + * (e.g. DUK__EMIT_FLAG_B_IS_TARGET). If the value in the slot is not + * register/const related at all, the caller must ensure that the raw value + * fits into the corresponding slot so as to not trigger shuffling. The + * caller must set a "no shuffle" flag to ensure compilation fails if + * shuffling were to be triggered because of an internal error. + * + * For slots B and C the raw slot size is 9 bits but one bit is reserved for + * the reg/const indicator. To use the full 9-bit range for a raw value, + * shuffling must be disabled with the DUK__EMIT_FLAG_NO_SHUFFLE_{B,C} flag. + * Shuffling is only done for A, B, and C slots, not the larger BC or ABC + * slots. + * + * There is call handling specific understanding in the A-B-C emitter to + * convert call setup and call instructions into indirect ones if necessary. + */ + +/* Code emission flags, passed in the 'opcode' field. Opcode + flags + * fit into 16 bits for now, so use duk_small_uint_t. + */ +#define DUK__EMIT_FLAG_NO_SHUFFLE_A (1u << 8) +#define DUK__EMIT_FLAG_NO_SHUFFLE_B (1u << 9) +#define DUK__EMIT_FLAG_NO_SHUFFLE_C (1u << 10) +#define DUK__EMIT_FLAG_A_IS_SOURCE \ + (1u << 11) /* slot A is a source (default: target) */ +#define DUK__EMIT_FLAG_B_IS_TARGET \ + (1u << 12) /* slot B is a target (default: source) */ +#define DUK__EMIT_FLAG_C_IS_TARGET \ + (1u << 13) /* slot C is a target (default: source) */ +#define DUK__EMIT_FLAG_BC_REGCONST (1u << 14) /* slots B and C are reg/const \ + */ +#define DUK__EMIT_FLAG_RESERVE_JUMPSLOT \ + (1u << 15) /* reserve a jumpslot after instr before target spilling, used \ + for NEXTENUM */ + +/* XXX: macro smaller than call? */ +DUK_LOCAL duk_int_t duk__get_current_pc(duk_compiler_ctx *comp_ctx) { + duk_compiler_func *func; + func = &comp_ctx->curr_func; + return (duk_int_t)(DUK_BW_GET_SIZE(comp_ctx->thr, &func->bw_code) / + sizeof(duk_compiler_instr)); +} + +DUK_LOCAL duk_compiler_instr *duk__get_instr_ptr(duk_compiler_ctx *comp_ctx, + duk_int_t pc) { + DUK_ASSERT(pc >= 0); + DUK_ASSERT((duk_size_t)pc < + (duk_size_t)( + DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / + sizeof(duk_compiler_instr))); + return ((duk_compiler_instr *)(void *)DUK_BW_GET_BASEPTR( + comp_ctx->thr, &comp_ctx->curr_func.bw_code)) + + pc; +} + +/* emit instruction; could return PC but that's not needed in the majority + * of cases. + */ +DUK_LOCAL void duk__emit(duk_compiler_ctx *comp_ctx, duk_instr_t ins) { +#if defined(DUK_USE_PC2LINE) + duk_int_t line; +#endif + duk_compiler_instr *instr; + + DUK_DDD(DUK_DDDPRINT("duk__emit: 0x%08lx curr_token.start_line=%ld " + "prev_token.start_line=%ld pc=%ld --> %!I", + (unsigned long)ins, + (long)comp_ctx->curr_token.start_line, + (long)comp_ctx->prev_token.start_line, + (long)duk__get_current_pc(comp_ctx), (duk_instr_t)ins)); + + instr = (duk_compiler_instr *)(void *)DUK_BW_ENSURE_GETPTR( + comp_ctx->thr, &comp_ctx->curr_func.bw_code, sizeof(duk_compiler_instr)); + DUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, + sizeof(duk_compiler_instr)); + +#if defined(DUK_USE_PC2LINE) + /* The line number tracking is a bit inconsistent right now, which + * affects debugger accuracy. Mostly call sites emit opcodes when + * they have parsed a token (say a terminating semicolon) and called + * duk__advance(). In this case the line number of the previous + * token is the most accurate one (except in prologue where + * prev_token.start_line is 0). This is probably not 100% correct + * right now. + */ + /* approximation, close enough */ + line = comp_ctx->prev_token.start_line; + if (line == 0) { + line = comp_ctx->curr_token.start_line; + } +#endif + + instr->ins = ins; +#if defined(DUK_USE_PC2LINE) + instr->line = (duk_uint32_t)line; +#endif +#if defined(DUK_USE_DEBUGGER_SUPPORT) + if (line < comp_ctx->curr_func.min_line) { + comp_ctx->curr_func.min_line = line; + } + if (line > comp_ctx->curr_func.max_line) { + comp_ctx->curr_func.max_line = line; + } +#endif + + /* Limit checks for bytecode byte size and line number. */ + if (DUK_UNLIKELY( + DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) > + DUK_USE_ESBC_MAX_BYTES)) { + goto fail_bc_limit; + } +#if defined(DUK_USE_PC2LINE) && defined(DUK_USE_ESBC_LIMITS) +#if defined(DUK_USE_BUFLEN16) + /* Buffer length is bounded to 0xffff automatically, avoid compile warning. */ + if (DUK_UNLIKELY(line > DUK_USE_ESBC_MAX_LINENUMBER)) { + goto fail_bc_limit; + } +#else + if (DUK_UNLIKELY(line > DUK_USE_ESBC_MAX_LINENUMBER)) { + goto fail_bc_limit; + } +#endif +#endif + + return; + +fail_bc_limit: + DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_BYTECODE_LIMIT); + DUK_WO_NORETURN(return;); +} + +/* Update function min/max line from current token. Needed to improve + * function line range information for debugging, so that e.g. opening + * curly brace is covered by line range even when no opcodes are emitted + * for the line containing the brace. + */ +DUK_LOCAL void duk__update_lineinfo_currtoken(duk_compiler_ctx *comp_ctx) { +#if defined(DUK_USE_DEBUGGER_SUPPORT) + duk_int_t line; + + line = comp_ctx->curr_token.start_line; + if (line == 0) { + return; + } + if (line < comp_ctx->curr_func.min_line) { + comp_ctx->curr_func.min_line = line; + } + if (line > comp_ctx->curr_func.max_line) { + comp_ctx->curr_func.max_line = line; + } +#else + DUK_UNREF(comp_ctx); +#endif +} + +DUK_LOCAL void duk__emit_op_only(duk_compiler_ctx *comp_ctx, + duk_small_uint_t op) { + duk__emit(comp_ctx, DUK_ENC_OP_ABC(op, 0)); +} + +/* Important main primitive. */ +DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, + duk_small_uint_t op_flags, duk_regconst_t a, + duk_regconst_t b, duk_regconst_t c) { + duk_instr_t ins = 0; + duk_int_t a_out = -1; + duk_int_t b_out = -1; + duk_int_t c_out = -1; + duk_int_t tmp; + duk_small_uint_t op = op_flags & 0xffU; + + DUK_DDD(DUK_DDDPRINT("emit: op_flags=%04lx, a=%ld, b=%ld, c=%ld", + (unsigned long)op_flags, (long)a, (long)b, (long)c)); + + /* We could rely on max temp/const checks: if they don't exceed BC + * limit, nothing here can either (just asserts would be enough). + * Currently we check for the limits, which provides additional + * protection against creating invalid bytecode due to compiler + * bugs. + */ + + DUK_ASSERT_DISABLE((op_flags & 0xff) >= DUK_BC_OP_MIN); /* unsigned */ + DUK_ASSERT((op_flags & 0xff) <= DUK_BC_OP_MAX); + DUK_ASSERT(DUK__ISREG(a)); + DUK_ASSERT(b != -1); /* Not 'none'. */ + DUK_ASSERT(c != -1); /* Not 'none'. */ + + /* Input shuffling happens before the actual operation, while output + * shuffling happens afterwards. Output shuffling decisions are still + * made at the same time to reduce branch clutter; output shuffle decisions + * are recorded into X_out variables. + */ + + /* Slot A: currently no support for reg/const. */ + +#if defined(DUK_USE_SHUFFLE_TORTURE) + if (a <= DUK_BC_A_MAX && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A)) { +#else + if (a <= DUK_BC_A_MAX) { +#endif + ; + } else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A) { + DUK_D(DUK_DPRINT( + "out of regs: 'a' (reg) needs shuffling but shuffle prohibited, a: %ld", + (long)a)); + goto error_outofregs; + } else if (a <= DUK_BC_BC_MAX) { + comp_ctx->curr_func.needs_shuffle = 1; + tmp = comp_ctx->curr_func.shuffle1; + if (op_flags & DUK__EMIT_FLAG_A_IS_SOURCE) { + duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, a)); + } else { + /* Output shuffle needed after main operation */ + a_out = a; + + /* The DUK_OP_CSVAR output shuffle assumes shuffle registers are + * consecutive. + */ + DUK_ASSERT( + (comp_ctx->curr_func.shuffle1 == 0 && + comp_ctx->curr_func.shuffle2 == 0) || + (comp_ctx->curr_func.shuffle2 == comp_ctx->curr_func.shuffle1 + 1)); + if (op == DUK_OP_CSVAR) { + /* For CSVAR the limit is one smaller because output shuffle + * must be able to express 'a + 1' in BC. + */ + if (a + 1 > DUK_BC_BC_MAX) { + goto error_outofregs; + } + } + } + a = tmp; + } else { + DUK_D(DUK_DPRINT("out of regs: 'a' (reg) needs shuffling but does not fit " + "into BC, a: %ld", + (long)a)); + goto error_outofregs; + } + + /* Slot B: reg/const support, mapped to bit 0 of opcode. */ + + if ((b & DUK__CONST_MARKER) != 0) { + DUK_ASSERT((op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B) == 0); + DUK_ASSERT((op_flags & DUK__EMIT_FLAG_B_IS_TARGET) == 0); + b = b & ~DUK__CONST_MARKER; +#if defined(DUK_USE_SHUFFLE_TORTURE) + if (0) { +#else + if (b <= 0xff) { +#endif + if (op_flags & DUK__EMIT_FLAG_BC_REGCONST) { + /* Opcode follows B/C reg/const convention. */ + DUK_ASSERT((op & 0x01) == 0); + ins |= DUK_ENC_OP_A_B_C(0x01, 0, 0, 0); /* const flag for B */ + } else { + DUK_D(DUK_DPRINT("B is const, opcode is not B/C reg/const: %x", + op_flags)); + } + } else if (b <= DUK_BC_BC_MAX) { + comp_ctx->curr_func.needs_shuffle = 1; + tmp = comp_ctx->curr_func.shuffle2; + duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDCONST, tmp, b)); + b = tmp; + } else { + DUK_D(DUK_DPRINT("out of regs: 'b' (const) needs shuffling but does not " + "fit into BC, b: %ld", + (long)b)); + goto error_outofregs; + } + } else { +#if defined(DUK_USE_SHUFFLE_TORTURE) + if (b <= 0xff && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B)) { +#else + if (b <= 0xff) { +#endif + ; + } else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B) { + if (b > DUK_BC_B_MAX) { + /* Note: 0xff != DUK_BC_B_MAX */ + DUK_D(DUK_DPRINT("out of regs: 'b' (reg) needs shuffling but shuffle " + "prohibited, b: %ld", + (long)b)); + goto error_outofregs; + } + } else if (b <= DUK_BC_BC_MAX) { + comp_ctx->curr_func.needs_shuffle = 1; + tmp = comp_ctx->curr_func.shuffle2; + if (op_flags & DUK__EMIT_FLAG_B_IS_TARGET) { + /* Output shuffle needed after main operation */ + b_out = b; + } + if (!(op_flags & DUK__EMIT_FLAG_B_IS_TARGET)) { + if (op == DUK_OP_MPUTOBJ || op == DUK_OP_MPUTARR) { + /* Special handling for MPUTOBJ/MPUTARR shuffling. + * For each, slot B identifies the first register of a range + * of registers, so normal shuffling won't work. Instead, + * an indirect version of the opcode is used. + */ + DUK_ASSERT((op_flags & DUK__EMIT_FLAG_B_IS_TARGET) == 0); + duk__emit_load_int32_noshuffle(comp_ctx, tmp, b); + DUK_ASSERT(DUK_OP_MPUTOBJI == DUK_OP_MPUTOBJ + 1); + DUK_ASSERT(DUK_OP_MPUTARRI == DUK_OP_MPUTARR + 1); + op_flags++; /* indirect opcode follows direct */ + } else { + duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, b)); + } + } + b = tmp; + } else { + DUK_D( + DUK_DPRINT("out of regs: 'b' (reg) needs shuffling but does not fit " + "into BC, b: %ld", + (long)b)); + goto error_outofregs; + } + } + + /* Slot C: reg/const support, mapped to bit 1 of opcode. */ + + if ((c & DUK__CONST_MARKER) != 0) { + DUK_ASSERT((op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C) == 0); + DUK_ASSERT((op_flags & DUK__EMIT_FLAG_C_IS_TARGET) == 0); + c = c & ~DUK__CONST_MARKER; +#if defined(DUK_USE_SHUFFLE_TORTURE) + if (0) { +#else + if (c <= 0xff) { +#endif + if (op_flags & DUK__EMIT_FLAG_BC_REGCONST) { + /* Opcode follows B/C reg/const convention. */ + DUK_ASSERT((op & 0x02) == 0); + ins |= DUK_ENC_OP_A_B_C(0x02, 0, 0, 0); /* const flag for C */ + } else { + DUK_D(DUK_DPRINT("C is const, opcode is not B/C reg/const: %x", + op_flags)); + } + } else if (c <= DUK_BC_BC_MAX) { + comp_ctx->curr_func.needs_shuffle = 1; + tmp = comp_ctx->curr_func.shuffle3; + duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDCONST, tmp, c)); + c = tmp; + } else { + DUK_D(DUK_DPRINT("out of regs: 'c' (const) needs shuffling but does not " + "fit into BC, c: %ld", + (long)c)); + goto error_outofregs; + } + } else { +#if defined(DUK_USE_SHUFFLE_TORTURE) + if (c <= 0xff && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C)) { +#else + if (c <= 0xff) { +#endif + ; + } else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C) { + if (c > DUK_BC_C_MAX) { + /* Note: 0xff != DUK_BC_C_MAX */ + DUK_D(DUK_DPRINT("out of regs: 'c' (reg) needs shuffling but shuffle " + "prohibited, c: %ld", + (long)c)); + goto error_outofregs; + } + } else if (c <= DUK_BC_BC_MAX) { + comp_ctx->curr_func.needs_shuffle = 1; + tmp = comp_ctx->curr_func.shuffle3; + if (op_flags & DUK__EMIT_FLAG_C_IS_TARGET) { + /* Output shuffle needed after main operation */ + c_out = c; + } else { + duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, c)); + } + c = tmp; + } else { + DUK_D( + DUK_DPRINT("out of regs: 'c' (reg) needs shuffling but does not fit " + "into BC, c: %ld", + (long)c)); + goto error_outofregs; + } + } + + /* Main operation */ + + DUK_ASSERT(a >= DUK_BC_A_MIN); + DUK_ASSERT(a <= DUK_BC_A_MAX); + DUK_ASSERT(b >= DUK_BC_B_MIN); + DUK_ASSERT(b <= DUK_BC_B_MAX); + DUK_ASSERT(c >= DUK_BC_C_MIN); + DUK_ASSERT(c <= DUK_BC_C_MAX); + + ins |= DUK_ENC_OP_A_B_C(op_flags & 0xff, a, b, c); + duk__emit(comp_ctx, ins); + + /* NEXTENUM needs a jump slot right after the main instruction. + * When the JUMP is taken, output spilling is not needed so this + * workaround is possible. The jump slot PC is exceptionally + * plumbed through comp_ctx to minimize call sites. + */ + if (op_flags & DUK__EMIT_FLAG_RESERVE_JUMPSLOT) { + comp_ctx->emit_jumpslot_pc = duk__get_current_pc(comp_ctx); + duk__emit_abc(comp_ctx, DUK_OP_JUMP, 0); + } + + /* Output shuffling: only one output register is realistically possible. + * + * (Zero would normally be an OK marker value: if the target register + * was zero, it would never be shuffled. But with DUK_USE_SHUFFLE_TORTURE + * this is no longer true, so use -1 as a marker instead.) + */ + + if (a_out >= 0) { + DUK_ASSERT(b_out < 0); + DUK_ASSERT(c_out < 0); + duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, a, a_out)); + + if (op == DUK_OP_CSVAR) { + /* Special handling for CSVAR shuffling. The variable lookup + * results in a pair in successive + * registers so use two shuffle registers and two output + * loads. (In practice this is dead code because temp/const + * limit is reached first.) + */ + duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, a + 1, a_out + 1)); + } + } else if (b_out >= 0) { + DUK_ASSERT(a_out < 0); + DUK_ASSERT(c_out < 0); + duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, b, b_out)); + } else if (c_out >= 0) { + DUK_ASSERT(b_out < 0); + DUK_ASSERT(c_out < 0); + duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, c, c_out)); + } + + return; + +error_outofregs: + DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT); + DUK_WO_NORETURN(return;); +} + +/* For many of the helpers below it'd be technically correct to add + * "no shuffle" flags for parameters passed in as zero. For example, + * duk__emit_a_b() should call duk__emit_a_b_c() with C set to 0, and + * DUK__EMIT_FLAG_NO_SHUFFLE_C added to op_flags. However, since the + * C value is 0, it'll never get shuffled so adding the flag is just + * unnecessary additional code. This is unfortunately not true for + * "shuffle torture" mode which needs special handling. + */ + +DUK_LOCAL void duk__emit_a_b(duk_compiler_ctx *comp_ctx, + duk_small_uint_t op_flags, duk_regconst_t a, + duk_regconst_t b) { +#if defined(DUK_USE_SHUFFLE_TORTURE) + op_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_C; +#endif + duk__emit_a_b_c(comp_ctx, op_flags, a, b, 0); +} + +DUK_LOCAL void duk__emit_b_c(duk_compiler_ctx *comp_ctx, + duk_small_uint_t op_flags, duk_regconst_t b, + duk_regconst_t c) { +#if defined(DUK_USE_SHUFFLE_TORTURE) + op_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_A; +#endif + duk__emit_a_b_c(comp_ctx, op_flags, 0, b, c); +} + +#if 0 /* unused */ +DUK_LOCAL void duk__emit_a(duk_compiler_ctx *comp_ctx, int op_flags, int a) { +#if defined(DUK_USE_SHUFFLE_TORTURE) + op_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_B | DUK__EMIT_FLAG_NO_SHUFFLE_C; +#endif + duk__emit_a_b_c(comp_ctx, op_flags, a, 0, 0); +} +#endif + +#if 0 /* unused */ +DUK_LOCAL void duk__emit_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b) { +#if defined(DUK_USE_SHUFFLE_TORTURE) + op_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_NO_SHUFFLE_C; +#endif + duk__emit_a_b_c(comp_ctx, op_flags, 0, b, 0); +} +#endif + +DUK_LOCAL void duk__emit_a_bc(duk_compiler_ctx *comp_ctx, + duk_small_uint_t op_flags, duk_regconst_t a, + duk_regconst_t bc) { + duk_instr_t ins; + duk_int_t tmp; + + /* allow caller to give a const number with the DUK__CONST_MARKER */ + DUK_ASSERT(bc != -1); /* Not 'none'. */ + bc = bc & (~DUK__CONST_MARKER); + + DUK_ASSERT_DISABLE((op_flags & 0xff) >= DUK_BC_OP_MIN); /* unsigned */ + DUK_ASSERT((op_flags & 0xff) <= DUK_BC_OP_MAX); + DUK_ASSERT(bc >= DUK_BC_BC_MIN); + DUK_ASSERT(bc <= DUK_BC_BC_MAX); + DUK_ASSERT((bc & DUK__CONST_MARKER) == 0); + + if (bc <= DUK_BC_BC_MAX) { + ; + } else { + /* No BC shuffling now. */ + goto error_outofregs; + } + +#if defined(DUK_USE_SHUFFLE_TORTURE) + if (a <= DUK_BC_A_MAX && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A)) { +#else + if (a <= DUK_BC_A_MAX) { +#endif + ins = DUK_ENC_OP_A_BC(op_flags & 0xff, a, bc); + duk__emit(comp_ctx, ins); + } else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A) { + goto error_outofregs; + } else if ((op_flags & 0xf0U) == DUK_OP_CALL0) { + comp_ctx->curr_func.needs_shuffle = 1; + tmp = comp_ctx->curr_func.shuffle1; + duk__emit_load_int32_noshuffle(comp_ctx, tmp, a); + op_flags |= DUK_BC_CALL_FLAG_INDIRECT; + ins = DUK_ENC_OP_A_BC(op_flags & 0xff, tmp, bc); + duk__emit(comp_ctx, ins); + } else if (a <= DUK_BC_BC_MAX) { + comp_ctx->curr_func.needs_shuffle = 1; + tmp = comp_ctx->curr_func.shuffle1; + ins = DUK_ENC_OP_A_BC(op_flags & 0xff, tmp, bc); + if (op_flags & DUK__EMIT_FLAG_A_IS_SOURCE) { + duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, a)); + duk__emit(comp_ctx, ins); + } else { + duk__emit(comp_ctx, ins); + duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, tmp, a)); + } + } else { + goto error_outofregs; + } + return; + +error_outofregs: + DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT); + DUK_WO_NORETURN(return;); +} + +DUK_LOCAL void duk__emit_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, + duk_regconst_t bc) { +#if defined(DUK_USE_SHUFFLE_TORTURE) + op |= DUK__EMIT_FLAG_NO_SHUFFLE_A; +#endif + duk__emit_a_bc(comp_ctx, op, 0, bc); +} + +DUK_LOCAL void duk__emit_abc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, + duk_regconst_t abc) { + duk_instr_t ins; + + DUK_ASSERT_DISABLE(op >= DUK_BC_OP_MIN); /* unsigned */ + DUK_ASSERT(op <= DUK_BC_OP_MAX); + DUK_ASSERT_DISABLE(abc >= DUK_BC_ABC_MIN); /* unsigned */ + DUK_ASSERT(abc <= DUK_BC_ABC_MAX); + DUK_ASSERT((abc & DUK__CONST_MARKER) == 0); + DUK_ASSERT(abc != -1); /* Not 'none'. */ + + if (abc <= DUK_BC_ABC_MAX) { + ; + } else { + goto error_outofregs; + } + ins = DUK_ENC_OP_ABC(op, abc); + DUK_DDD(DUK_DDDPRINT( + "duk__emit_abc: 0x%08lx line=%ld pc=%ld op=%ld (%!X) abc=%ld (%!I)", + (unsigned long)ins, (long)comp_ctx->curr_token.start_line, + (long)duk__get_current_pc(comp_ctx), (long)op, (long)op, (long)abc, + (duk_instr_t)ins)); + duk__emit(comp_ctx, ins); + return; + +error_outofregs: + DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT); + DUK_WO_NORETURN(return;); +} + +DUK_LOCAL void duk__emit_load_int32_raw(duk_compiler_ctx *comp_ctx, + duk_regconst_t reg, duk_int32_t val, + duk_small_uint_t op_flags) { + /* XXX: Shuffling support could be implemented here so that LDINT+LDINTX + * would only shuffle once (instead of twice). The current code works + * though, and has a smaller compiler footprint. + */ + + if ((val >= (duk_int32_t)DUK_BC_BC_MIN - (duk_int32_t)DUK_BC_LDINT_BIAS) && + (val <= (duk_int32_t)DUK_BC_BC_MAX - (duk_int32_t)DUK_BC_LDINT_BIAS)) { + DUK_DDD( + DUK_DDDPRINT("emit LDINT to reg %ld for %ld", (long)reg, (long)val)); + duk__emit_a_bc(comp_ctx, DUK_OP_LDINT | op_flags, reg, + (duk_regconst_t)(val + (duk_int32_t)DUK_BC_LDINT_BIAS)); + } else { + duk_int32_t hi = val >> DUK_BC_LDINTX_SHIFT; + duk_int32_t lo = val & ((((duk_int32_t)1) << DUK_BC_LDINTX_SHIFT) - 1); + DUK_ASSERT(lo >= 0); + DUK_DDD( + DUK_DDDPRINT("emit LDINT+LDINTX to reg %ld for %ld -> hi %ld, lo %ld", + (long)reg, (long)val, (long)hi, (long)lo)); + duk__emit_a_bc(comp_ctx, DUK_OP_LDINT | op_flags, reg, + (duk_regconst_t)(hi + (duk_int32_t)DUK_BC_LDINT_BIAS)); + duk__emit_a_bc(comp_ctx, DUK_OP_LDINTX | op_flags, reg, (duk_regconst_t)lo); + } +} + +DUK_LOCAL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, + duk_regconst_t reg, duk_int32_t val) { + duk__emit_load_int32_raw(comp_ctx, reg, val, 0 /*op_flags*/); +} + +#if defined(DUK_USE_SHUFFLE_TORTURE) +/* Used by duk__emit*() calls so that we don't shuffle the loadints that + * are needed to handle indirect opcodes. + */ +DUK_LOCAL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, + duk_regconst_t reg, + duk_int32_t val) { + duk__emit_load_int32_raw(comp_ctx, reg, val, + DUK__EMIT_FLAG_NO_SHUFFLE_A /*op_flags*/); +} +#else +DUK_LOCAL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, + duk_regconst_t reg, + duk_int32_t val) { + /* When torture not enabled, can just use the same helper because + * 'reg' won't get spilled. + */ + DUK_ASSERT(reg <= DUK_BC_A_MAX); + duk__emit_load_int32(comp_ctx, reg, val); +} +#endif + +DUK_LOCAL void duk__emit_jump(duk_compiler_ctx *comp_ctx, duk_int_t target_pc) { + duk_int_t curr_pc; + duk_int_t offset; + + curr_pc = + (duk_int_t)(DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / + sizeof(duk_compiler_instr)); + offset = (duk_int_t)target_pc - (duk_int_t)curr_pc - 1; + DUK_ASSERT(offset + DUK_BC_JUMP_BIAS >= DUK_BC_ABC_MIN); + DUK_ASSERT(offset + DUK_BC_JUMP_BIAS <= DUK_BC_ABC_MAX); + duk__emit_abc(comp_ctx, DUK_OP_JUMP, + (duk_regconst_t)(offset + DUK_BC_JUMP_BIAS)); +} + +DUK_LOCAL duk_int_t duk__emit_jump_empty(duk_compiler_ctx *comp_ctx) { + duk_int_t ret; + + ret = duk__get_current_pc(comp_ctx); /* useful for patching jumps later */ + duk__emit_op_only(comp_ctx, DUK_OP_JUMP); + return ret; +} + +/* Insert an empty jump in the middle of code emitted earlier. This is + * currently needed for compiling for-in. + */ +DUK_LOCAL void duk__insert_jump_entry(duk_compiler_ctx *comp_ctx, + duk_int_t jump_pc) { +#if defined(DUK_USE_PC2LINE) + duk_int_t line; +#endif + duk_compiler_instr *instr; + duk_size_t offset; + + DUK_ASSERT(jump_pc >= 0); + offset = (duk_size_t)jump_pc * sizeof(duk_compiler_instr); + instr = (duk_compiler_instr *)(void *)DUK_BW_INSERT_ENSURE_AREA( + comp_ctx->thr, &comp_ctx->curr_func.bw_code, offset, + sizeof(duk_compiler_instr)); + +#if defined(DUK_USE_PC2LINE) + line = comp_ctx->curr_token.start_line; /* approximation, close enough */ +#endif + instr->ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, 0); +#if defined(DUK_USE_PC2LINE) + instr->line = (duk_uint32_t)line; +#endif + + DUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, + sizeof(duk_compiler_instr)); + if (DUK_UNLIKELY( + DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) > + DUK_USE_ESBC_MAX_BYTES)) { + goto fail_bc_limit; + } + return; + +fail_bc_limit: + DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_BYTECODE_LIMIT); + DUK_WO_NORETURN(return;); +} + +/* Does not assume that jump_pc contains a DUK_OP_JUMP previously; this is + * intentional to allow e.g. an INVALID opcode be overwritten with a JUMP (label + * management uses this). + */ +DUK_LOCAL void duk__patch_jump(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc, + duk_int_t target_pc) { + duk_compiler_instr *instr; + duk_int_t offset; + + /* allow negative PCs, behave as a no-op */ + if (jump_pc < 0) { + DUK_DDD(DUK_DDDPRINT( + "duk__patch_jump(): nop call, jump_pc=%ld (<0), target_pc=%ld", + (long)jump_pc, (long)target_pc)); + return; + } + DUK_ASSERT(jump_pc >= 0); + + /* XXX: range assert */ + instr = duk__get_instr_ptr(comp_ctx, jump_pc); + DUK_ASSERT(instr != NULL); + + /* XXX: range assert */ + offset = target_pc - jump_pc - 1; + + instr->ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, offset + DUK_BC_JUMP_BIAS); + DUK_DDD( + DUK_DDDPRINT("duk__patch_jump(): jump_pc=%ld, target_pc=%ld, offset=%ld", + (long)jump_pc, (long)target_pc, (long)offset)); +} + +DUK_LOCAL void duk__patch_jump_here(duk_compiler_ctx *comp_ctx, + duk_int_t jump_pc) { + duk__patch_jump(comp_ctx, jump_pc, duk__get_current_pc(comp_ctx)); +} + +DUK_LOCAL void duk__patch_trycatch(duk_compiler_ctx *comp_ctx, + duk_int_t ldconst_pc, duk_int_t trycatch_pc, + duk_regconst_t reg_catch, + duk_regconst_t const_varname, + duk_small_uint_t flags) { + duk_compiler_instr *instr; + + DUK_ASSERT(DUK__ISREG(reg_catch)); + + instr = duk__get_instr_ptr(comp_ctx, ldconst_pc); + DUK_ASSERT(DUK_DEC_OP(instr->ins) == DUK_OP_LDCONST); + DUK_ASSERT(instr != NULL); + if (const_varname & DUK__CONST_MARKER) { + /* Have a catch variable. */ + const_varname = const_varname & (~DUK__CONST_MARKER); + if (reg_catch > DUK_BC_BC_MAX || const_varname > DUK_BC_BC_MAX) { + /* Catch attempts to use out-of-range reg/const. Without this + * check Duktape 0.12.0 could generate invalid code which caused + * an assert failure on execution. This error is triggered e.g. + * for functions with a lot of constants and a try-catch statement. + * Shuffling or opcode semantics change is needed to fix the issue. + * See: test-bug-trycatch-many-constants.js. + */ + DUK_D(DUK_DPRINT("failed to patch trycatch: flags=%ld, reg_catch=%ld, " + "const_varname=%ld (0x%08lx)", + (long)flags, (long)reg_catch, (long)const_varname, + (long)const_varname)); + DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT); + DUK_WO_NORETURN(return;); + } + instr->ins |= DUK_ENC_OP_A_BC(0, 0, const_varname); + } else { + /* No catch variable, e.g. a try-finally; replace LDCONST with + * NOP to avoid a bogus LDCONST. + */ + instr->ins = DUK_ENC_OP(DUK_OP_NOP); + } + + instr = duk__get_instr_ptr(comp_ctx, trycatch_pc); + DUK_ASSERT(instr != NULL); + DUK_ASSERT_DISABLE(flags >= DUK_BC_A_MIN); + DUK_ASSERT(flags <= DUK_BC_A_MAX); + instr->ins = DUK_ENC_OP_A_BC(DUK_OP_TRYCATCH, flags, reg_catch); +} + +DUK_LOCAL void duk__emit_if_false_skip(duk_compiler_ctx *comp_ctx, + duk_regconst_t regconst) { + duk_small_uint_t op; + + op = DUK__ISREG(regconst) ? DUK_OP_IFFALSE_R : DUK_OP_IFFALSE_C; + duk__emit_bc(comp_ctx, op, regconst); /* helper will remove const flag */ +} + +DUK_LOCAL void duk__emit_if_true_skip(duk_compiler_ctx *comp_ctx, + duk_regconst_t regconst) { + duk_small_uint_t op; + + op = DUK__ISREG(regconst) ? DUK_OP_IFTRUE_R : DUK_OP_IFTRUE_C; + duk__emit_bc(comp_ctx, op, regconst); /* helper will remove const flag */ +} + +DUK_LOCAL void duk__emit_invalid(duk_compiler_ctx *comp_ctx) { + duk__emit_op_only(comp_ctx, DUK_OP_INVALID); +} + +/* + * Peephole optimizer for finished bytecode. + * + * Does not remove opcodes; currently only straightens out unconditional + * jump chains which are generated by several control structures. + */ + +DUK_LOCAL void duk__peephole_optimize_bytecode(duk_compiler_ctx *comp_ctx) { + duk_compiler_instr *bc; + duk_small_uint_t iter; + duk_int_t i, n; + duk_int_t count_opt; + + bc = (duk_compiler_instr *)(void *)DUK_BW_GET_BASEPTR( + comp_ctx->thr, &comp_ctx->curr_func.bw_code); +#if defined(DUK_USE_BUFLEN16) + /* No need to assert, buffer size maximum is 0xffff. */ +#else + DUK_ASSERT( + (duk_size_t)DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / + sizeof(duk_compiler_instr) <= + (duk_size_t)DUK_INT_MAX); /* bytecode limits */ +#endif + n = (duk_int_t)(DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / + sizeof(duk_compiler_instr)); + + for (iter = 0; iter < DUK_COMPILER_PEEPHOLE_MAXITER; iter++) { + count_opt = 0; + + for (i = 0; i < n; i++) { + duk_instr_t ins; + duk_int_t target_pc1; + duk_int_t target_pc2; + + ins = bc[i].ins; + if (DUK_DEC_OP(ins) != DUK_OP_JUMP) { + continue; + } + + target_pc1 = + i + 1 + (duk_int_t)DUK_DEC_ABC(ins) - (duk_int_t)DUK_BC_JUMP_BIAS; + DUK_DDD(DUK_DDDPRINT("consider jump at pc %ld; target_pc=%ld", (long)i, + (long)target_pc1)); + DUK_ASSERT(target_pc1 >= 0); + DUK_ASSERT(target_pc1 < n); + + /* Note: if target_pc1 == i, we'll optimize a jump to itself. + * This does not need to be checked for explicitly; the case + * is rare and max iter breaks us out. + */ + + ins = bc[target_pc1].ins; + if (DUK_DEC_OP(ins) != DUK_OP_JUMP) { + continue; + } + + target_pc2 = target_pc1 + 1 + (duk_int_t)DUK_DEC_ABC(ins) - + (duk_int_t)DUK_BC_JUMP_BIAS; + + DUK_DDD(DUK_DDDPRINT( + "optimizing jump at pc %ld; old target is %ld -> new target is %ld", + (long)i, (long)target_pc1, (long)target_pc2)); + + bc[i].ins = + DUK_ENC_OP_ABC(DUK_OP_JUMP, target_pc2 - (i + 1) + DUK_BC_JUMP_BIAS); + + count_opt++; + } + + DUK_DD(DUK_DDPRINT("optimized %ld jumps on peephole round %ld", + (long)count_opt, (long)(iter + 1))); + + if (count_opt == 0) { + break; + } + } +} + +/* + * Intermediate value helpers + */ + +/* Flags for intermediate value coercions. A flag for using a forced reg + * is not needed, the forced_reg argument suffices and generates better + * code (it is checked as it is used). + */ +/* XXX: DUK__IVAL_FLAG_REQUIRE_SHORT is passed but not currently implemented + * by ispec/ivalue operations. + */ +#define DUK__IVAL_FLAG_ALLOW_CONST \ + (1u << 0) /* allow a constant to be returned */ +#define DUK__IVAL_FLAG_REQUIRE_TEMP \ + (1u << 1) /* require a (mutable) temporary as a result (or a const if \ + allowed) */ +#define DUK__IVAL_FLAG_REQUIRE_SHORT \ + (1u << 2) /* require a short (8-bit) reg/const which fits into bytecode B/C \ + slot */ + +/* XXX: some code might benefit from DUK__SETTEMP_IFTEMP(thr,x) */ + +#if 0 /* enable manually for dumping */ +#define DUK__DUMP_ISPEC(compctx, ispec) \ + do { \ + duk__dump_ispec((compctx), (ispec)); \ + } while (0) +#define DUK__DUMP_IVALUE(compctx, ivalue) \ + do { \ + duk__dump_ivalue((compctx), (ivalue)); \ + } while (0) + +DUK_LOCAL void duk__dump_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *x) { + DUK_D(DUK_DPRINT("ispec dump: t=%ld regconst=0x%08lx, valstack_idx=%ld, value=%!T", + (long) x->t, (unsigned long) x->regconst, (long) x->valstack_idx, + duk_get_tval(comp_ctx->thr, x->valstack_idx))); +} +DUK_LOCAL void duk__dump_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *x) { + DUK_D(DUK_DPRINT("ivalue dump: t=%ld op=%ld " + "x1={t=%ld regconst=0x%08lx valstack_idx=%ld value=%!T} " + "x2={t=%ld regconst=0x%08lx valstack_idx=%ld value=%!T}", + (long) x->t, (long) x->op, + (long) x->x1.t, (unsigned long) x->x1.regconst, (long) x->x1.valstack_idx, + duk_get_tval(comp_ctx->thr, x->x1.valstack_idx), + (long) x->x2.t, (unsigned long) x->x2.regconst, (long) x->x2.valstack_idx, + duk_get_tval(comp_ctx->thr, x->x2.valstack_idx))); +} +#else +#define DUK__DUMP_ISPEC(comp_ctx, x) \ + do { \ + } while (0) +#define DUK__DUMP_IVALUE(comp_ctx, x) \ + do { \ + } while (0) +#endif + +DUK_LOCAL void duk__ivalue_regconst(duk_ivalue *x, duk_regconst_t regconst) { + x->t = DUK_IVAL_PLAIN; + x->x1.t = DUK_ISPEC_REGCONST; + x->x1.regconst = regconst; +} + +DUK_LOCAL void duk__ivalue_plain_fromstack(duk_compiler_ctx *comp_ctx, + duk_ivalue *x) { + x->t = DUK_IVAL_PLAIN; + x->x1.t = DUK_ISPEC_VALUE; + duk_replace(comp_ctx->thr, x->x1.valstack_idx); +} + +DUK_LOCAL void duk__ivalue_var_fromstack(duk_compiler_ctx *comp_ctx, + duk_ivalue *x) { + x->t = DUK_IVAL_VAR; + x->x1.t = DUK_ISPEC_VALUE; + duk_replace(comp_ctx->thr, x->x1.valstack_idx); +} + +DUK_LOCAL_DECL void duk__ivalue_var_hstring(duk_compiler_ctx *comp_ctx, + duk_ivalue *x, duk_hstring *h) { + DUK_ASSERT(h != NULL); + duk_push_hstring(comp_ctx->thr, h); + duk__ivalue_var_fromstack(comp_ctx, x); +} + +DUK_LOCAL void duk__copy_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *src, + duk_ispec *dst) { + dst->t = src->t; + dst->regconst = src->regconst; + duk_copy(comp_ctx->thr, src->valstack_idx, dst->valstack_idx); +} + +DUK_LOCAL void duk__copy_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *src, + duk_ivalue *dst) { + dst->t = src->t; + dst->op = src->op; + dst->x1.t = src->x1.t; + dst->x1.regconst = src->x1.regconst; + dst->x2.t = src->x2.t; + dst->x2.regconst = src->x2.regconst; + duk_copy(comp_ctx->thr, src->x1.valstack_idx, dst->x1.valstack_idx); + duk_copy(comp_ctx->thr, src->x2.valstack_idx, dst->x2.valstack_idx); +} + +DUK_LOCAL duk_regconst_t duk__alloctemps(duk_compiler_ctx *comp_ctx, + duk_small_int_t num) { + duk_regconst_t res; + + res = comp_ctx->curr_func.temp_next; + comp_ctx->curr_func.temp_next += num; + + if (comp_ctx->curr_func.temp_next > + DUK__MAX_TEMPS) { /* == DUK__MAX_TEMPS is OK */ + DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_TEMP_LIMIT); + DUK_WO_NORETURN(return 0;); + } + + /* maintain highest 'used' temporary, needed to figure out nregs of function + */ + if (comp_ctx->curr_func.temp_next > comp_ctx->curr_func.temp_max) { + comp_ctx->curr_func.temp_max = comp_ctx->curr_func.temp_next; + } + + return res; +} + +DUK_LOCAL duk_regconst_t duk__alloctemp(duk_compiler_ctx *comp_ctx) { + return duk__alloctemps(comp_ctx, 1); +} + +DUK_LOCAL void duk__settemp_checkmax(duk_compiler_ctx *comp_ctx, + duk_regconst_t temp_next) { + comp_ctx->curr_func.temp_next = temp_next; + if (temp_next > comp_ctx->curr_func.temp_max) { + comp_ctx->curr_func.temp_max = temp_next; + } +} + +/* get const for value at valstack top */ +DUK_LOCAL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx) { + duk_hthread *thr = comp_ctx->thr; + duk_compiler_func *f = &comp_ctx->curr_func; + duk_tval *tv1; + duk_int_t i, n, n_check; + + n = (duk_int_t)duk_get_length(thr, f->consts_idx); + + tv1 = DUK_GET_TVAL_NEGIDX(thr, -1); + DUK_ASSERT(tv1 != NULL); + +#if defined(DUK_USE_FASTINT) + /* Explicit check for fastint downgrade. */ + DUK_TVAL_CHKFAST_INPLACE_SLOW(tv1); +#endif + + /* Sanity workaround for handling functions with a large number of + * constants at least somewhat reasonably. Otherwise checking whether + * we already have the constant would grow very slow (as it is O(N^2)). + */ + n_check = + (n > DUK__GETCONST_MAX_CONSTS_CHECK ? DUK__GETCONST_MAX_CONSTS_CHECK : n); + for (i = 0; i < n_check; i++) { + duk_tval *tv2 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, f->h_consts, i); + + /* Strict equality is NOT enough, because we cannot use the same + * constant for e.g. +0 and -0. + */ + if (duk_js_samevalue(tv1, tv2)) { + DUK_DDD( + DUK_DDDPRINT("reused existing constant for %!T -> const index %ld", + (duk_tval *)tv1, (long)i)); + duk_pop(thr); + return (duk_regconst_t)i | (duk_regconst_t)DUK__CONST_MARKER; + } + } + + if (n > DUK__MAX_CONSTS) { + DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_CONST_LIMIT); + DUK_WO_NORETURN(return 0;); + } + + DUK_DDD(DUK_DDDPRINT("allocating new constant for %!T -> const index %ld", + (duk_tval *)tv1, (long)n)); + (void)duk_put_prop_index(thr, f->consts_idx, + (duk_uarridx_t)n); /* invalidates tv1, tv2 */ + return (duk_regconst_t)n | (duk_regconst_t)DUK__CONST_MARKER; +} + +DUK_LOCAL duk_bool_t duk__const_needs_refcount(duk_compiler_ctx *comp_ctx, + duk_regconst_t rc) { +#if defined(DUK_USE_REFERENCE_COUNTING) + duk_compiler_func *f = &comp_ctx->curr_func; + duk_bool_t ret; + + DUK_ASSERT((rc & DUK__CONST_MARKER) == 0); /* caller removes const marker */ + (void)duk_get_prop_index(comp_ctx->thr, f->consts_idx, (duk_uarridx_t)rc); + ret = !duk_is_number(comp_ctx->thr, + -1); /* now only number/string, so conservative check */ + duk_pop(comp_ctx->thr); + return ret; +#else + DUK_UNREF(comp_ctx); + DUK_UNREF(rc); + DUK_ASSERT((rc & DUK__CONST_MARKER) == 0); /* caller removes const marker */ + return 0; +#endif +} + +/* Get the value represented by an duk_ispec to a register or constant. + * The caller can control the result by indicating whether or not: + * + * (1) a constant is allowed (sometimes the caller needs the result to + * be in a register) + * + * (2) a temporary register is required (usually when caller requires + * the register to be safely mutable; normally either a bound + * register or a temporary register are both OK) + * + * (3) a forced register target needs to be used + * + * Bytecode may be emitted to generate the necessary value. The return + * value is either a register or a constant. + */ + +DUK_LOCAL +duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx, + duk_ispec *x, + duk_regconst_t forced_reg, + duk_small_uint_t flags) { + duk_hthread *thr = comp_ctx->thr; + + DUK_DDD(DUK_DDDPRINT("duk__ispec_toregconst_raw(): x={%ld:%ld:%!T}, " + "forced_reg=%ld, flags 0x%08lx: allow_const=%ld " + "require_temp=%ld require_short=%ld", + (long)x->t, (long)x->regconst, + (duk_tval *)duk_get_tval(thr, x->valstack_idx), + (long)forced_reg, (unsigned long)flags, + (long)((flags & DUK__IVAL_FLAG_ALLOW_CONST) ? 1 : 0), + (long)((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) ? 1 : 0), + (long)((flags & DUK__IVAL_FLAG_REQUIRE_SHORT) ? 1 : 0))); + + switch (x->t) { + case DUK_ISPEC_VALUE: { + duk_tval *tv; + + tv = DUK_GET_TVAL_POSIDX(thr, x->valstack_idx); + DUK_ASSERT(tv != NULL); + + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_UNDEFINED: { + /* Note: although there is no 'undefined' literal, undefined + * values can occur during compilation as a result of e.g. + * the 'void' operator. + */ + duk_regconst_t dest = + (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx)); + duk__emit_bc(comp_ctx, DUK_OP_LDUNDEF, dest); + return dest; + } + case DUK_TAG_NULL: { + duk_regconst_t dest = + (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx)); + duk__emit_bc(comp_ctx, DUK_OP_LDNULL, dest); + return dest; + } + case DUK_TAG_BOOLEAN: { + duk_regconst_t dest = + (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx)); + duk__emit_bc( + comp_ctx, + (DUK_TVAL_GET_BOOLEAN(tv) ? DUK_OP_LDTRUE : DUK_OP_LDFALSE), + dest); + return dest; + } + case DUK_TAG_POINTER: { + DUK_UNREACHABLE(); + break; + } + case DUK_TAG_STRING: { + duk_hstring *h; + duk_regconst_t dest; + duk_regconst_t constidx; + + h = DUK_TVAL_GET_STRING(tv); + DUK_UNREF(h); + DUK_ASSERT(h != NULL); + +#if 0 /* XXX: to be implemented? */ + /* Use special opcodes to load short strings */ + if (DUK_HSTRING_GET_BYTELEN(h) <= 2) { + /* Encode into a single opcode (18 bits can encode 1-2 bytes + length indicator) */ + } else if (DUK_HSTRING_GET_BYTELEN(h) <= 6) { + /* Encode into a double constant (53 bits can encode 6*8 = 48 bits + 3-bit length */ + } +#endif + duk_dup(thr, x->valstack_idx); + constidx = duk__getconst(comp_ctx); + + if (flags & DUK__IVAL_FLAG_ALLOW_CONST) { + return constidx; + } + + dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx)); + duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, constidx); + return dest; + } + case DUK_TAG_OBJECT: { + DUK_UNREACHABLE(); + break; + } + case DUK_TAG_BUFFER: { + DUK_UNREACHABLE(); + break; + } + case DUK_TAG_LIGHTFUNC: { + DUK_UNREACHABLE(); + break; + } +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: +#endif + default: { + /* number */ + duk_regconst_t dest; + duk_regconst_t constidx; + duk_double_t dval; + duk_int32_t ival; + + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv)); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); + dval = DUK_TVAL_GET_NUMBER(tv); + + if (!(flags & DUK__IVAL_FLAG_ALLOW_CONST)) { + /* A number can be loaded either through a constant, using + * LDINT, or using LDINT+LDINTX. LDINT is always a size win, + * LDINT+LDINTX is not if the constant is used multiple times. + * Currently always prefer LDINT+LDINTX over a double constant. + */ + + if (duk_is_whole_get_int32_nonegzero(dval, &ival)) { + dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx)); + duk__emit_load_int32(comp_ctx, dest, ival); + return dest; + } + } + + duk_dup(thr, x->valstack_idx); + constidx = duk__getconst(comp_ctx); + + if (flags & DUK__IVAL_FLAG_ALLOW_CONST) { + return constidx; + } else { + dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx)); + duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, constidx); + return dest; + } + } + } /* end switch */ + goto fail_internal; /* never here */ + } + case DUK_ISPEC_REGCONST: { + if (forced_reg >= 0) { + if (DUK__ISCONST(x->regconst)) { + duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, forced_reg, x->regconst); + } else if (x->regconst != forced_reg) { + duk__emit_a_bc(comp_ctx, DUK_OP_LDREG, forced_reg, x->regconst); + } else { + ; /* already in correct reg */ + } + return forced_reg; + } + + DUK_ASSERT(forced_reg < 0); + if (DUK__ISCONST(x->regconst)) { + if (!(flags & DUK__IVAL_FLAG_ALLOW_CONST)) { + duk_regconst_t dest = DUK__ALLOCTEMP(comp_ctx); + duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, x->regconst); + return dest; + } + return x->regconst; + } + + DUK_ASSERT(forced_reg < 0 && !DUK__ISCONST(x->regconst)); + if ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) && + !DUK__ISREG_TEMP(comp_ctx, x->regconst)) { + duk_regconst_t dest = DUK__ALLOCTEMP(comp_ctx); + duk__emit_a_bc(comp_ctx, DUK_OP_LDREG, dest, x->regconst); + return dest; + } + return x->regconst; + } + default: { + break; /* never here */ + } + } + +fail_internal: + DUK_ERROR_INTERNAL(thr); + DUK_WO_NORETURN(return 0;); +} + +DUK_LOCAL void duk__ispec_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ispec *x, + duk_regconst_t forced_reg) { + DUK_ASSERT(forced_reg >= 0); + (void)duk__ispec_toregconst_raw(comp_ctx, x, forced_reg, 0 /*flags*/); +} + +/* Coerce an duk_ivalue to a 'plain' value by generating the necessary + * arithmetic operations, property access, or variable access bytecode. + * The duk_ivalue argument ('x') is converted into a plain value as a + * side effect. + */ +DUK_LOCAL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, + duk_ivalue *x, + duk_regconst_t forced_reg) { + duk_hthread *thr = comp_ctx->thr; + + DUK_DDD(DUK_DDDPRINT( + "duk__ivalue_toplain_raw(): " + "x={t=%ld,op=%ld,x1={%ld:%ld:%!T},x2={%ld:%ld:%!T}}, " + "forced_reg=%ld", + (long)x->t, (long)x->op, (long)x->x1.t, (long)x->x1.regconst, + (duk_tval *)duk_get_tval(thr, x->x1.valstack_idx), (long)x->x2.t, + (long)x->x2.regconst, (duk_tval *)duk_get_tval(thr, x->x2.valstack_idx), + (long)forced_reg)); + + switch (x->t) { + case DUK_IVAL_PLAIN: { + return; + } + /* XXX: support unary arithmetic ivalues (useful?) */ + case DUK_IVAL_ARITH: { + duk_regconst_t arg1; + duk_regconst_t arg2; + duk_regconst_t dest; + duk_tval *tv1; + duk_tval *tv2; + + DUK_DDD(DUK_DDDPRINT("arith to plain conversion")); + + /* inline arithmetic check for constant values */ + /* XXX: use the exactly same arithmetic function here as in executor */ + if (x->x1.t == DUK_ISPEC_VALUE && x->x2.t == DUK_ISPEC_VALUE && + x->t == DUK_IVAL_ARITH) { + tv1 = DUK_GET_TVAL_POSIDX(thr, x->x1.valstack_idx); + tv2 = DUK_GET_TVAL_POSIDX(thr, x->x2.valstack_idx); + DUK_ASSERT(tv1 != NULL); + DUK_ASSERT(tv2 != NULL); + + DUK_DDD(DUK_DDDPRINT("arith: tv1=%!T, tv2=%!T", (duk_tval *)tv1, + (duk_tval *)tv2)); + + if (DUK_TVAL_IS_NUMBER(tv1) && DUK_TVAL_IS_NUMBER(tv2)) { + duk_double_t d1 = DUK_TVAL_GET_NUMBER(tv1); + duk_double_t d2 = DUK_TVAL_GET_NUMBER(tv2); + duk_double_t d3; + duk_bool_t accept_fold = 1; + + DUK_DDD(DUK_DDDPRINT("arith inline check: d1=%lf, d2=%lf, op=%ld", + (double)d1, (double)d2, (long)x->op)); + switch (x->op) { + case DUK_OP_ADD: { + d3 = d1 + d2; + break; + } + case DUK_OP_SUB: { + d3 = d1 - d2; + break; + } + case DUK_OP_MUL: { + d3 = d1 * d2; + break; + } + case DUK_OP_DIV: { + /* Division-by-zero is undefined + * behavior, so rely on a helper. + */ + d3 = duk_double_div(d1, d2); + break; + } + case DUK_OP_EXP: { + d3 = (duk_double_t)duk_js_arith_pow((double)d1, (double)d2); + break; + } + default: { + d3 = 0.0; /* Won't be used, but silence MSVC /W4 warning. */ + accept_fold = 0; + break; + } + } + + if (accept_fold) { + duk_double_union du; + du.d = d3; + DUK_DBLUNION_NORMALIZE_NAN_CHECK(&du); + d3 = du.d; + + x->t = DUK_IVAL_PLAIN; + DUK_ASSERT(x->x1.t == DUK_ISPEC_VALUE); + DUK_TVAL_SET_NUMBER(tv1, d3); /* old value is number: no refcount */ + return; + } + } else if (x->op == DUK_OP_ADD && DUK_TVAL_IS_STRING(tv1) && + DUK_TVAL_IS_STRING(tv2)) { + /* Inline string concatenation. No need to check for + * symbols, as all inputs are valid ECMAScript strings. + */ + duk_dup(thr, x->x1.valstack_idx); + duk_dup(thr, x->x2.valstack_idx); + duk_concat(thr, 2); + duk_replace(thr, x->x1.valstack_idx); + x->t = DUK_IVAL_PLAIN; + DUK_ASSERT(x->x1.t == DUK_ISPEC_VALUE); + return; + } + } + + arg1 = duk__ispec_toregconst_raw( + comp_ctx, &x->x1, -1, + DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/); + arg2 = duk__ispec_toregconst_raw( + comp_ctx, &x->x2, -1, + DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/); + + /* If forced reg, use it as destination. Otherwise try to + * use either coerced ispec if it is a temporary. + */ + if (forced_reg >= 0) { + dest = forced_reg; + } else if (DUK__ISREG_TEMP(comp_ctx, arg1)) { + dest = arg1; + } else if (DUK__ISREG_TEMP(comp_ctx, arg2)) { + dest = arg2; + } else { + dest = DUK__ALLOCTEMP(comp_ctx); + } + + DUK_ASSERT(DUK__ISREG(dest)); + duk__emit_a_b_c(comp_ctx, x->op | DUK__EMIT_FLAG_BC_REGCONST, dest, arg1, + arg2); + + duk__ivalue_regconst(x, dest); + return; + } + case DUK_IVAL_PROP: { + /* XXX: very similar to DUK_IVAL_ARITH - merge? */ + duk_regconst_t arg1; + duk_regconst_t arg2; + duk_regconst_t dest; + + /* Need a short reg/const, does not have to be a mutable temp. */ + arg1 = duk__ispec_toregconst_raw( + comp_ctx, &x->x1, -1, + DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/); + arg2 = duk__ispec_toregconst_raw( + comp_ctx, &x->x2, -1, + DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/); + + /* Pick a destination register. If either base value or key + * happens to be a temp value, reuse it as the destination. + * + * XXX: The temp must be a "mutable" one, i.e. such that no + * other expression is using it anymore. Here this should be + * the case because the value of a property access expression + * is neither the base nor the key, but the lookup result. + */ + + if (forced_reg >= 0) { + dest = forced_reg; + } else if (DUK__ISREG_TEMP(comp_ctx, arg1)) { + dest = arg1; + } else if (DUK__ISREG_TEMP(comp_ctx, arg2)) { + dest = arg2; + } else { + dest = DUK__ALLOCTEMP(comp_ctx); + } + + duk__emit_a_b_c(comp_ctx, DUK_OP_GETPROP | DUK__EMIT_FLAG_BC_REGCONST, + dest, arg1, arg2); + + duk__ivalue_regconst(x, dest); + return; + } + case DUK_IVAL_VAR: { + /* x1 must be a string */ + duk_regconst_t dest; + duk_regconst_t reg_varbind; + duk_regconst_t rc_varname; + + DUK_ASSERT(x->x1.t == DUK_ISPEC_VALUE); + + duk_dup(thr, x->x1.valstack_idx); + if (duk__lookup_lhs(comp_ctx, ®_varbind, &rc_varname)) { + duk__ivalue_regconst(x, reg_varbind); + } else { + dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx)); + duk__emit_a_bc(comp_ctx, DUK_OP_GETVAR, dest, rc_varname); + duk__ivalue_regconst(x, dest); + } + return; + } + case DUK_IVAL_NONE: + default: { + DUK_D(DUK_DPRINT("invalid ivalue type: %ld", (long)x->t)); + break; + } + } + + DUK_ERROR_INTERNAL(thr); + DUK_WO_NORETURN(return;); +} + +/* evaluate to plain value, no forced register (temp/bound reg both ok) */ +DUK_LOCAL void duk__ivalue_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *x) { + duk__ivalue_toplain_raw(comp_ctx, x, -1 /*forced_reg*/); +} + +/* evaluate to final form (e.g. coerce GETPROP to code), throw away temp */ +DUK_LOCAL void duk__ivalue_toplain_ignore(duk_compiler_ctx *comp_ctx, + duk_ivalue *x) { + duk_regconst_t temp; + + /* If duk__ivalue_toplain_raw() allocates a temp, forget it and + * restore next temp state. + */ + temp = DUK__GETTEMP(comp_ctx); + duk__ivalue_toplain_raw(comp_ctx, x, -1 /*forced_reg*/); + DUK__SETTEMP(comp_ctx, temp); +} + +/* Coerce an duk_ivalue to a register or constant; result register may + * be a temp or a bound register. + * + * The duk_ivalue argument ('x') is converted into a regconst as a + * side effect. + */ +DUK_LOCAL +duk_regconst_t duk__ivalue_toregconst_raw(duk_compiler_ctx *comp_ctx, + duk_ivalue *x, + duk_regconst_t forced_reg, + duk_small_uint_t flags) { + duk_hthread *thr = comp_ctx->thr; + duk_regconst_t reg; + DUK_UNREF(thr); + + DUK_DDD(DUK_DDDPRINT( + "duk__ivalue_toregconst_raw(): " + "x={t=%ld,op=%ld,x1={%ld:%ld:%!T},x2={%ld:%ld:%!T}}, " + "forced_reg=%ld, flags 0x%08lx: allow_const=%ld require_temp=%ld " + "require_short=%ld", + (long)x->t, (long)x->op, (long)x->x1.t, (long)x->x1.regconst, + (duk_tval *)duk_get_tval(thr, x->x1.valstack_idx), (long)x->x2.t, + (long)x->x2.regconst, (duk_tval *)duk_get_tval(thr, x->x2.valstack_idx), + (long)forced_reg, (unsigned long)flags, + (long)((flags & DUK__IVAL_FLAG_ALLOW_CONST) ? 1 : 0), + (long)((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) ? 1 : 0), + (long)((flags & DUK__IVAL_FLAG_REQUIRE_SHORT) ? 1 : 0))); + + /* first coerce to a plain value */ + duk__ivalue_toplain_raw(comp_ctx, x, forced_reg); + DUK_ASSERT(x->t == DUK_IVAL_PLAIN); + + /* then to a register */ + reg = duk__ispec_toregconst_raw(comp_ctx, &x->x1, forced_reg, flags); + duk__ivalue_regconst(x, reg); + + return reg; +} + +DUK_LOCAL duk_regconst_t duk__ivalue_toreg(duk_compiler_ctx *comp_ctx, + duk_ivalue *x) { + return duk__ivalue_toregconst_raw(comp_ctx, x, -1, 0 /*flags*/); +} + +#if 0 /* unused */ +DUK_LOCAL duk_regconst_t duk__ivalue_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *x) { + return duk__ivalue_toregconst_raw(comp_ctx, x, -1, DUK__IVAL_FLAG_REQUIRE_TEMP /*flags*/); +} +#endif + +DUK_LOCAL void duk__ivalue_toforcedreg(duk_compiler_ctx *comp_ctx, + duk_ivalue *x, duk_int_t forced_reg) { + DUK_ASSERT(forced_reg >= 0); + (void)duk__ivalue_toregconst_raw(comp_ctx, x, forced_reg, 0 /*flags*/); +} + +DUK_LOCAL duk_regconst_t duk__ivalue_toregconst(duk_compiler_ctx *comp_ctx, + duk_ivalue *x) { + return duk__ivalue_toregconst_raw(comp_ctx, x, -1, + DUK__IVAL_FLAG_ALLOW_CONST /*flags*/); +} + +DUK_LOCAL duk_regconst_t duk__ivalue_totempconst(duk_compiler_ctx *comp_ctx, + duk_ivalue *x) { + return duk__ivalue_toregconst_raw( + comp_ctx, x, -1, + DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_TEMP /*flags*/); +} + +/* The issues below can be solved with better flags */ + +/* XXX: many operations actually want toforcedtemp() -- brand new temp? */ +/* XXX: need a toplain_ignore() which will only coerce a value to a temp + * register if it might have a side effect. Side-effect free values do not + * need to be coerced. + */ + +/* + * Identifier handling + */ + +DUK_LOCAL duk_regconst_t +duk__lookup_active_register_binding(duk_compiler_ctx *comp_ctx) { + duk_hthread *thr = comp_ctx->thr; + duk_hstring *h_varname; + duk_regconst_t ret; + + DUK_DDD(DUK_DDDPRINT("resolving identifier reference to '%!T'", + (duk_tval *)duk_get_tval(thr, -1))); + + /* + * Special name handling + */ + + h_varname = duk_known_hstring(thr, -1); + + if (h_varname == DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)) { + DUK_DDD(DUK_DDDPRINT("flagging function as accessing 'arguments'")); + comp_ctx->curr_func.id_access_arguments = 1; + } + + /* + * Inside one or more 'with' statements fall back to slow path always. + * (See e.g. test-stmt-with.js.) + */ + + if (comp_ctx->curr_func.with_depth > 0) { + DUK_DDD(DUK_DDDPRINT( + "identifier lookup inside a 'with' -> fall back to slow path")); + goto slow_path_own; + } + + /* + * Any catch bindings ("catch (e)") also affect identifier binding. + * + * Currently, the varmap is modified for the duration of the catch + * clause to ensure any identifier accesses with the catch variable + * name will use slow path. + */ + + duk_get_prop(thr, comp_ctx->curr_func.varmap_idx); + if (duk_is_number(thr, -1)) { + ret = duk_to_int(thr, -1); + duk_pop(thr); + } else { + duk_pop(thr); + if (comp_ctx->curr_func.catch_depth > 0 || + comp_ctx->curr_func.with_depth > 0) { + DUK_DDD(DUK_DDDPRINT( + "slow path access from inside a try-catch or with needs _Varmap")); + goto slow_path_own; + } else { + /* In this case we're doing a variable lookup that doesn't + * match our own variables, so _Varmap won't be needed at + * run time. + */ + DUK_DDD(DUK_DDDPRINT("slow path access outside of try-catch and with, no " + "need for _Varmap")); + goto slow_path_notown; + } + } + + DUK_DDD(DUK_DDDPRINT("identifier lookup -> reg %ld", (long)ret)); + return ret; + +slow_path_notown: + DUK_DDD(DUK_DDDPRINT("identifier lookup -> slow path, not own variable")); + + comp_ctx->curr_func.id_access_slow = 1; + return (duk_regconst_t)-1; + +slow_path_own: + DUK_DDD(DUK_DDDPRINT("identifier lookup -> slow path, may be own variable")); + + comp_ctx->curr_func.id_access_slow = 1; + comp_ctx->curr_func.id_access_slow_own = 1; + return (duk_regconst_t)-1; +} + +/* Lookup an identifier name in the current varmap, indicating whether the + * identifier is register-bound and if not, allocating a constant for the + * identifier name. Returns 1 if register-bound, 0 otherwise. Caller can + * also check (out_reg_varbind >= 0) to check whether or not identifier is + * register bound. The caller must NOT use out_rc_varname at all unless + * return code is 0 or out_reg_varbind is < 0; this is becuase out_rc_varname + * is unsigned and doesn't have a "unused" / none value. + */ +DUK_LOCAL duk_bool_t duk__lookup_lhs(duk_compiler_ctx *comp_ctx, + duk_regconst_t *out_reg_varbind, + duk_regconst_t *out_rc_varname) { + duk_hthread *thr = comp_ctx->thr; + duk_regconst_t reg_varbind; + duk_regconst_t rc_varname; + + /* [ ... varname ] */ + + duk_dup_top(thr); + reg_varbind = duk__lookup_active_register_binding(comp_ctx); + + if (reg_varbind >= 0) { + *out_reg_varbind = reg_varbind; + *out_rc_varname = 0; /* duk_regconst_t is unsigned, so use 0 as dummy value + (ignored by caller) */ + duk_pop(thr); + return 1; + } else { + rc_varname = duk__getconst(comp_ctx); + *out_reg_varbind = -1; + *out_rc_varname = rc_varname; + return 0; + } +} + +/* + * Label handling + * + * Labels are initially added with flags prohibiting both break and continue. + * When the statement type is finally uncovered (after potentially multiple + * labels), all the labels are updated to allow/prohibit break and continue. + */ + +DUK_LOCAL void duk__add_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, + duk_int_t pc_label, duk_int_t label_id) { + duk_hthread *thr = comp_ctx->thr; + duk_size_t n; + duk_size_t new_size; + duk_uint8_t *p; + duk_labelinfo *li_start, *li; + + /* Duplicate (shadowing) labels are not allowed, except for the empty + * labels (which are used as default labels for switch and iteration + * statements). + * + * We could also allow shadowing of non-empty pending labels without any + * other issues than breaking the required label shadowing requirements + * of the E5 specification, see Section 12.12. + */ + + p = (duk_uint8_t *)DUK_HBUFFER_DYNAMIC_GET_DATA_PTR( + thr->heap, comp_ctx->curr_func.h_labelinfos); + li_start = (duk_labelinfo *)(void *)p; + li = (duk_labelinfo *)(void *)(p + DUK_HBUFFER_GET_SIZE( + comp_ctx->curr_func.h_labelinfos)); + n = (duk_size_t)(li - li_start); + + while (li > li_start) { + li--; + + if (li->h_label == h_label && + h_label != DUK_HTHREAD_STRING_EMPTY_STRING(thr)) { + DUK_ERROR_SYNTAX(thr, DUK_STR_DUPLICATE_LABEL); + DUK_WO_NORETURN(return;); + } + } + + duk_push_hstring(thr, h_label); + DUK_ASSERT(n <= DUK_UARRIDX_MAX); /* label limits */ + (void)duk_put_prop_index(thr, comp_ctx->curr_func.labelnames_idx, + (duk_uarridx_t)n); + + new_size = (n + 1) * sizeof(duk_labelinfo); + duk_hbuffer_resize(thr, comp_ctx->curr_func.h_labelinfos, new_size); + /* XXX: slack handling, slow now */ + + /* relookup after possible realloc */ + p = (duk_uint8_t *)DUK_HBUFFER_DYNAMIC_GET_DATA_PTR( + thr->heap, comp_ctx->curr_func.h_labelinfos); + li_start = (duk_labelinfo *)(void *)p; + DUK_UNREF(li_start); /* silence scan-build warning */ + li = (duk_labelinfo *)(void *)(p + DUK_HBUFFER_GET_SIZE( + comp_ctx->curr_func.h_labelinfos)); + li--; + + /* Labels can be used for iteration statements but also for other statements, + * in particular a label can be used for a block statement. All cases of a + * named label accept a 'break' so that flag is set here. Iteration + * statements also allow 'continue', so that flag is updated when we figure + * out the statement type. + */ + + li->flags = DUK_LABEL_FLAG_ALLOW_BREAK; + li->label_id = label_id; + li->h_label = h_label; + li->catch_depth = + comp_ctx->curr_func.catch_depth; /* catch depth from current func */ + li->pc_label = pc_label; + + DUK_DDD(DUK_DDDPRINT( + "registered label: flags=0x%08lx, id=%ld, name=%!O, catch_depth=%ld, " + "pc_label=%ld", + (unsigned long)li->flags, (long)li->label_id, (duk_heaphdr *)li->h_label, + (long)li->catch_depth, (long)li->pc_label)); +} + +/* Update all labels with matching label_id. */ +DUK_LOCAL void duk__update_label_flags(duk_compiler_ctx *comp_ctx, + duk_int_t label_id, + duk_small_uint_t flags) { + duk_uint8_t *p; + duk_labelinfo *li_start, *li; + + p = (duk_uint8_t *)DUK_HBUFFER_DYNAMIC_GET_DATA_PTR( + comp_ctx->thr->heap, comp_ctx->curr_func.h_labelinfos); + li_start = (duk_labelinfo *)(void *)p; + li = (duk_labelinfo *)(void *)(p + DUK_HBUFFER_GET_SIZE( + comp_ctx->curr_func.h_labelinfos)); + + /* Match labels starting from latest; once label_id no longer matches, we can + * safely exit without checking the rest of the labels (only the topmost + * labels are ever updated). + */ + while (li > li_start) { + li--; + + if (li->label_id != label_id) { + break; + } + + DUK_DDD(DUK_DDDPRINT( + "updating (overwriting) label flags for li=%p, label_id=%ld, flags=%ld", + (void *)li, (long)label_id, (long)flags)); + + li->flags = flags; + } +} + +/* Lookup active label information. Break/continue distinction is necessary to + * handle switch statement related labels correctly: a switch will only catch a + * 'break', not a 'continue'. + * + * An explicit label cannot appear multiple times in the active set, but empty + * labels (unlabelled iteration and switch statements) can. A break will match + * the closest unlabelled or labelled statement. A continue will match the + * closest unlabelled or labelled iteration statement. It is a syntax error if + * a continue matches a labelled switch statement; because an explicit label + * cannot be duplicated, the continue cannot match any valid label outside the + * switch. + * + * A side effect of these rules is that a LABEL statement related to a switch + * should never actually catch a continue abrupt completion at run-time. Hence + * an INVALID opcode can be placed in the continue slot of the switch's LABEL + * statement. + */ + +/* XXX: awkward, especially the bunch of separate output values -> output + * struct? */ +DUK_LOCAL void duk__lookup_active_label( + duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_bool_t is_break, + duk_int_t *out_label_id, duk_int_t *out_label_catch_depth, + duk_int_t *out_label_pc, duk_bool_t *out_is_closest) { + duk_hthread *thr = comp_ctx->thr; + duk_uint8_t *p; + duk_labelinfo *li_start, *li_end, *li; + duk_bool_t match = 0; + + DUK_DDD(DUK_DDDPRINT("looking up active label: label='%!O', is_break=%ld", + (duk_heaphdr *)h_label, (long)is_break)); + + DUK_UNREF(thr); + + p = (duk_uint8_t *)DUK_HBUFFER_DYNAMIC_GET_DATA_PTR( + thr->heap, comp_ctx->curr_func.h_labelinfos); + li_start = (duk_labelinfo *)(void *)p; + li_end = (duk_labelinfo *)(void *)(p + DUK_HBUFFER_GET_SIZE( + comp_ctx->curr_func.h_labelinfos)); + li = li_end; + + /* Match labels starting from latest label because there can be duplicate + * empty labels in the label set. + */ + while (li > li_start) { + li--; + + if (li->h_label != h_label) { + DUK_DDD(DUK_DDDPRINT("labelinfo[%ld] ->'%!O' != %!O", + (long)(li - li_start), (duk_heaphdr *)li->h_label, + (duk_heaphdr *)h_label)); + continue; + } + + DUK_DDD(DUK_DDDPRINT( + "labelinfo[%ld] -> '%!O' label name matches (still need to check type)", + (long)(li - li_start), (duk_heaphdr *)h_label)); + + /* currently all labels accept a break, so no explicit check for it now */ + DUK_ASSERT(li->flags & DUK_LABEL_FLAG_ALLOW_BREAK); + + if (is_break) { + /* break matches always */ + match = 1; + break; + } else if (li->flags & DUK_LABEL_FLAG_ALLOW_CONTINUE) { + /* iteration statements allow continue */ + match = 1; + break; + } else { + /* continue matched this label -- we can only continue if this is the + * empty label, for which duplication is allowed, and thus there is hope + * of finding a match deeper in the label stack. + */ + if (h_label != DUK_HTHREAD_STRING_EMPTY_STRING(thr)) { + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LABEL); + DUK_WO_NORETURN(return;); + } else { + DUK_DDD(DUK_DDDPRINT( + "continue matched an empty label which does not " + "allow a continue -> continue lookup deeper in label stack")); + } + } + } + /* XXX: match flag is awkward, rework */ + if (!match) { + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LABEL); + DUK_WO_NORETURN(return;); + } + + DUK_DDD(DUK_DDDPRINT( + "label match: %!O -> label_id %ld, catch_depth=%ld, pc_label=%ld", + (duk_heaphdr *)h_label, (long)li->label_id, (long)li->catch_depth, + (long)li->pc_label)); + + *out_label_id = li->label_id; + *out_label_catch_depth = li->catch_depth; + *out_label_pc = li->pc_label; + *out_is_closest = (li == li_end - 1); +} + +DUK_LOCAL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, + duk_size_t len) { + duk_hthread *thr = comp_ctx->thr; + + duk_set_length(thr, comp_ctx->curr_func.labelnames_idx, len); + duk_hbuffer_resize(thr, comp_ctx->curr_func.h_labelinfos, + sizeof(duk_labelinfo) * len); +} + +/* + * Expression parsing: duk__expr_nud(), duk__expr_led(), duk__expr_lbp(), and + * helpers. + * + * - duk__expr_nud(): ("null denotation"): process prev_token as a "start" of + * an expression (e.g. literal) + * - duk__expr_led(): ("left denotation"): process prev_token in the "middle" + * of an expression (e.g. operator) + * - duk__expr_lbp(): ("left-binding power"): return left-binding power of + * curr_token + */ + +/* object literal key tracking flags */ +#define DUK__OBJ_LIT_KEY_PLAIN \ + (1u << 0) /* key encountered as a plain property */ +#define DUK__OBJ_LIT_KEY_GET (1u << 1) /* key encountered as a getter */ +#define DUK__OBJ_LIT_KEY_SET (1u << 2) /* key encountered as a setter */ + +DUK_LOCAL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, + duk_ivalue *res) { + duk_hthread *thr = comp_ctx->thr; + duk_regconst_t reg_obj; /* result reg */ + duk_regconst_t reg_temp; /* temp reg */ + duk_regconst_t temp_start; /* temp reg value for start of loop */ + duk_small_uint_t + max_init_values; /* max # of values initialized in one MPUTARR set */ + duk_small_uint_t num_values; /* number of values in current MPUTARR set */ + duk_uarridx_t curr_idx; /* current (next) array index */ + duk_uarridx_t start_idx; /* start array index of current MPUTARR set */ + duk_uarridx_t init_idx; /* last array index explicitly initialized, +1 */ + duk_bool_t require_comma; /* next loop requires a comma */ +#if !defined(DUK_USE_PREFER_SIZE) + duk_int_t pc_newarr; + duk_compiler_instr *instr; +#endif + + /* DUK_TOK_LBRACKET already eaten, current token is right after that */ + DUK_ASSERT(comp_ctx->prev_token.t == DUK_TOK_LBRACKET); + + max_init_values = + DUK__MAX_ARRAY_INIT_VALUES; /* XXX: depend on available temps? */ + + reg_obj = DUK__ALLOCTEMP(comp_ctx); +#if !defined(DUK_USE_PREFER_SIZE) + pc_newarr = duk__get_current_pc(comp_ctx); +#endif + duk__emit_bc(comp_ctx, DUK_OP_NEWARR, + reg_obj); /* XXX: patch initial size hint afterwards? */ + temp_start = DUK__GETTEMP(comp_ctx); + + /* + * Emit initializers in sets of maximum max_init_values. + * Corner cases such as single value initializers do not have + * special handling now. + * + * Elided elements must not be emitted as 'undefined' values, + * because such values would be enumerable (which is incorrect). + * Also note that trailing elisions must be reflected in the + * length of the final array but cause no elements to be actually + * inserted. + */ + + curr_idx = 0; + init_idx = 0; /* tracks maximum initialized index + 1 */ + start_idx = 0; + require_comma = 0; + + for (;;) { + num_values = 0; + DUK__SETTEMP(comp_ctx, temp_start); + + if (comp_ctx->curr_token.t == DUK_TOK_RBRACKET) { + break; + } + + for (;;) { + if (comp_ctx->curr_token.t == DUK_TOK_RBRACKET) { + /* the outer loop will recheck and exit */ + break; + } + + /* comma check */ + if (require_comma) { + if (comp_ctx->curr_token.t == DUK_TOK_COMMA) { + /* comma after a value, expected */ + duk__advance(comp_ctx); + require_comma = 0; + continue; + } else { + goto syntax_error; + } + } else { + if (comp_ctx->curr_token.t == DUK_TOK_COMMA) { + /* elision - flush */ + curr_idx++; + duk__advance(comp_ctx); + /* if num_values > 0, MPUTARR emitted by outer loop after break */ + break; + } + } + /* else an array initializer element */ + + /* initial index */ + if (num_values == 0) { + start_idx = curr_idx; + reg_temp = DUK__ALLOCTEMP(comp_ctx); + duk__emit_load_int32(comp_ctx, reg_temp, (duk_int32_t)start_idx); + } + + reg_temp = DUK__ALLOCTEMP( + comp_ctx); /* alloc temp just in case, to update max temp */ + DUK__SETTEMP(comp_ctx, reg_temp); + duk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, + reg_temp /*forced_reg*/); + DUK__SETTEMP(comp_ctx, reg_temp + 1); + + num_values++; + curr_idx++; + require_comma = 1; + + if (num_values >= max_init_values) { + /* MPUTARR emitted by outer loop */ + break; + } + } + + if (num_values > 0) { + /* - A is a source register (it's not a write target, but used + * to identify the target object) but can be shuffled. + * - B cannot be shuffled normally because it identifies a range + * of registers, the emitter has special handling for this + * (the "no shuffle" flag must not be set). + * - C is a non-register number and cannot be shuffled, but + * never needs to be. + */ + duk__emit_a_b_c(comp_ctx, + DUK_OP_MPUTARR | DUK__EMIT_FLAG_NO_SHUFFLE_C | + DUK__EMIT_FLAG_A_IS_SOURCE, + reg_obj, temp_start, (duk_regconst_t)(num_values + 1)); + init_idx = start_idx + num_values; + + /* num_values and temp_start reset at top of outer loop */ + } + } + + /* Update initil size for NEWARR, doesn't need to be exact and is + * capped at A field limit. + */ +#if !defined(DUK_USE_PREFER_SIZE) + instr = duk__get_instr_ptr(comp_ctx, pc_newarr); + instr->ins |= + DUK_ENC_OP_A(0, curr_idx > DUK_BC_A_MAX ? DUK_BC_A_MAX : curr_idx); +#endif + + DUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RBRACKET); + duk__advance(comp_ctx); + + DUK_DDD(DUK_DDDPRINT("array literal done, curridx=%ld, initidx=%ld", + (long)curr_idx, (long)init_idx)); + + /* trailing elisions? */ + if (curr_idx > init_idx) { + /* yes, must set array length explicitly */ + DUK_DDD(DUK_DDDPRINT( + "array literal has trailing elisions which affect its length")); + reg_temp = DUK__ALLOCTEMP(comp_ctx); + duk__emit_load_int32(comp_ctx, reg_temp, (duk_int_t)curr_idx); + duk__emit_a_bc(comp_ctx, DUK_OP_SETALEN | DUK__EMIT_FLAG_A_IS_SOURCE, + reg_obj, reg_temp); + } + + DUK__SETTEMP(comp_ctx, temp_start); + + duk__ivalue_regconst(res, reg_obj); + return; + +syntax_error: + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_ARRAY_LITERAL); + DUK_WO_NORETURN(return;); +} + +typedef struct { + duk_regconst_t reg_obj; + duk_regconst_t temp_start; + duk_small_uint_t num_pairs; + duk_small_uint_t num_total_pairs; +} duk__objlit_state; + +DUK_LOCAL void duk__objlit_flush_keys(duk_compiler_ctx *comp_ctx, + duk__objlit_state *st) { + if (st->num_pairs > 0) { + /* - A is a source register (it's not a write target, but used + * to identify the target object) but can be shuffled. + * - B cannot be shuffled normally because it identifies a range + * of registers, the emitter has special handling for this + * (the "no shuffle" flag must not be set). + * - C is a non-register number and cannot be shuffled, but + * never needs to be. + */ + DUK_ASSERT(st->num_pairs > 0); + duk__emit_a_b_c(comp_ctx, + DUK_OP_MPUTOBJ | DUK__EMIT_FLAG_NO_SHUFFLE_C | + DUK__EMIT_FLAG_A_IS_SOURCE, + st->reg_obj, st->temp_start, + (duk_regconst_t)(st->num_pairs * 2)); + st->num_total_pairs += st->num_pairs; + st->num_pairs = 0; + } + DUK__SETTEMP(comp_ctx, st->temp_start); +} + +DUK_LOCAL duk_bool_t duk__objlit_load_key(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, duk_token *tok, + duk_regconst_t reg_temp) { + if (tok->t_nores == DUK_TOK_IDENTIFIER || tok->t_nores == DUK_TOK_STRING) { + /* same handling for identifiers and strings */ + DUK_ASSERT(tok->str1 != NULL); + duk_push_hstring(comp_ctx->thr, tok->str1); + } else if (tok->t == DUK_TOK_NUMBER) { + /* numbers can be loaded as numbers and coerced on the fly */ + duk_push_number(comp_ctx->thr, tok->num); + } else { + return 1; /* error */ + } + + duk__ivalue_plain_fromstack(comp_ctx, res); + DUK__SETTEMP(comp_ctx, reg_temp + 1); + duk__ivalue_toforcedreg(comp_ctx, res, reg_temp); + DUK__SETTEMP(comp_ctx, reg_temp + 1); + return 0; +} + +DUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, + duk_ivalue *res) { + duk_hthread *thr = comp_ctx->thr; + duk__objlit_state st; + duk_regconst_t reg_temp; /* temp reg */ + duk_small_uint_t max_init_pairs; /* max # of key-value pairs initialized in + one MPUTOBJ set */ + duk_bool_t first; /* first value: comma must not precede the value */ + duk_bool_t is_set, is_get; /* temps */ +#if !defined(DUK_USE_PREFER_SIZE) + duk_int_t pc_newobj; + duk_compiler_instr *instr; +#endif + + DUK_ASSERT(comp_ctx->prev_token.t == DUK_TOK_LCURLY); + + max_init_pairs = + DUK__MAX_OBJECT_INIT_PAIRS; /* XXX: depend on available temps? */ + + st.reg_obj = DUK__ALLOCTEMP(comp_ctx); /* target object */ + st.temp_start = DUK__GETTEMP(comp_ctx); /* start of MPUTOBJ argument list */ + st.num_pairs = + 0; /* number of key/value pairs emitted for current MPUTOBJ set */ + st.num_total_pairs = 0; /* number of key/value pairs emitted overall */ + +#if !defined(DUK_USE_PREFER_SIZE) + pc_newobj = duk__get_current_pc(comp_ctx); +#endif + duk__emit_bc(comp_ctx, DUK_OP_NEWOBJ, st.reg_obj); + + /* + * Emit initializers in sets of maximum max_init_pairs keys. + * Setter/getter is handled separately and terminates the + * current set of initializer values. Corner cases such as + * single value initializers do not have special handling now. + */ + + first = 1; + for (;;) { + /* + * ES5 and ES2015+ provide a lot of different PropertyDefinition + * formats, see + * http://www.ecma-international.org/ecma-262/6.0/#sec-object-initializer. + * + * PropertyName can be IdentifierName (includes reserved words), a string + * literal, or a number literal. Note that IdentifierName allows 'get' and + * 'set' too, so we need to look ahead to the next token to distinguish: + * + * { get : 1 } + * + * and + * + * { get foo() { return 1 } } + * { get get() { return 1 } } // 'get' as getter propertyname + * + * Finally, a trailing comma is allowed. + * + * Key name is coerced to string at compile time (and ends up as a + * a string constant) even for numeric keys (e.g. "{1:'foo'}"). + * These could be emitted using e.g. LDINT, but that seems hardly + * worth the effort and would increase code size. + */ + + DUK_DDD(DUK_DDDPRINT("object literal loop, curr_token->t = %ld", + (long)comp_ctx->curr_token.t)); + + if (comp_ctx->curr_token.t == DUK_TOK_RCURLY) { + break; + } + + if (first) { + first = 0; + } else { + if (comp_ctx->curr_token.t != DUK_TOK_COMMA) { + goto syntax_error; + } + duk__advance(comp_ctx); + if (comp_ctx->curr_token.t == DUK_TOK_RCURLY) { + /* trailing comma followed by rcurly */ + break; + } + } + + /* Advance to get one step of lookup. */ + duk__advance(comp_ctx); + + /* Flush current MPUTOBJ if enough many pairs gathered. */ + if (st.num_pairs >= max_init_pairs) { + duk__objlit_flush_keys(comp_ctx, &st); + DUK_ASSERT(st.num_pairs == 0); + } + + /* Reset temp register state and reserve reg_temp and + * reg_temp + 1 for handling the current property. + */ + DUK__SETTEMP(comp_ctx, st.temp_start + 2 * (duk_regconst_t)st.num_pairs); + reg_temp = DUK__ALLOCTEMPS(comp_ctx, 2); + + /* NOTE: "get" and "set" are not officially ReservedWords and the lexer + * currently treats them always like ordinary identifiers (DUK_TOK_GET + * and DUK_TOK_SET are unused). They need to be detected based on the + * identifier string content. + */ + + is_get = (comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER && + comp_ctx->prev_token.str1 == DUK_HTHREAD_STRING_GET(thr)); + is_set = (comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER && + comp_ctx->prev_token.str1 == DUK_HTHREAD_STRING_SET(thr)); + if ((is_get || is_set) && comp_ctx->curr_token.t != DUK_TOK_COLON) { + /* getter/setter */ + duk_int_t fnum; + + duk__objlit_flush_keys(comp_ctx, &st); + DUK_ASSERT(DUK__GETTEMP(comp_ctx) == + st.temp_start); /* 2 regs are guaranteed to be allocated w.r.t. + temp_max */ + reg_temp = DUK__ALLOCTEMPS(comp_ctx, 2); + + if (duk__objlit_load_key(comp_ctx, res, &comp_ctx->curr_token, + reg_temp) != 0) { + goto syntax_error; + } + + /* curr_token = get/set name */ + fnum = duk__parse_func_like_fnum(comp_ctx, DUK__FUNC_FLAG_GETSET); + + duk__emit_a_bc(comp_ctx, DUK_OP_CLOSURE, st.temp_start + 1, + (duk_regconst_t)fnum); + + /* Slot C is used in a non-standard fashion (range of regs), + * emitter code has special handling for it (must not set the + * "no shuffle" flag). + */ + duk__emit_a_bc( + comp_ctx, + (is_get ? DUK_OP_INITGET : DUK_OP_INITSET) | + DUK__EMIT_FLAG_A_IS_SOURCE, + st.reg_obj, + st.temp_start); /* temp_start+0 = key, temp_start+1 = closure */ + + DUK_ASSERT(st.num_pairs == 0); /* temp state is reset on next loop */ +#if defined(DUK_USE_ES6) + } else if (comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER && + (comp_ctx->curr_token.t == DUK_TOK_COMMA || + comp_ctx->curr_token.t == DUK_TOK_RCURLY)) { + duk_bool_t load_rc; + + load_rc = + duk__objlit_load_key(comp_ctx, res, &comp_ctx->prev_token, reg_temp); + DUK_UNREF(load_rc); + DUK_ASSERT(load_rc == + 0); /* always succeeds because token is identifier */ + + duk__ivalue_var_hstring(comp_ctx, res, comp_ctx->prev_token.str1); + DUK_ASSERT(DUK__GETTEMP(comp_ctx) == reg_temp + 1); + duk__ivalue_toforcedreg(comp_ctx, res, reg_temp + 1); + + st.num_pairs++; + } else if ((comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER || + comp_ctx->prev_token.t == DUK_TOK_STRING || + comp_ctx->prev_token.t == DUK_TOK_NUMBER) && + comp_ctx->curr_token.t == DUK_TOK_LPAREN) { + duk_int_t fnum; + + /* Parsing-wise there's a small hickup here: the token parsing + * state is one step too advanced for the function parse helper + * compared to other cases. The current solution is an extra + * flag to indicate whether function parsing should use the + * current or the previous token to starting parsing from. + */ + + if (duk__objlit_load_key(comp_ctx, res, &comp_ctx->prev_token, + reg_temp) != 0) { + goto syntax_error; + } + + fnum = duk__parse_func_like_fnum( + comp_ctx, DUK__FUNC_FLAG_USE_PREVTOKEN | DUK__FUNC_FLAG_METDEF); + + duk__emit_a_bc(comp_ctx, DUK_OP_CLOSURE, reg_temp + 1, + (duk_regconst_t)fnum); + + st.num_pairs++; +#endif /* DUK_USE_ES6 */ + } else { +#if defined(DUK_USE_ES6) + if (comp_ctx->prev_token.t == DUK_TOK_LBRACKET) { + /* ES2015 computed property name. Executor ToPropertyKey() + * coerces the key at runtime. + */ + DUK__SETTEMP(comp_ctx, reg_temp); + duk__expr_toforcedreg(comp_ctx, res, DUK__BP_FOR_EXPR, reg_temp); + duk__advance_expect(comp_ctx, DUK_TOK_RBRACKET); + + /* XXX: If next token is '(' we're dealing with + * the method shorthand with a computed name, + * e.g. { [Symbol.for('foo')](a,b) {} }. This + * form is not yet supported and causes a + * SyntaxError on the DUK_TOK_COLON check below. + */ + } else +#endif /* DUK_USE_ES6 */ + { + if (duk__objlit_load_key(comp_ctx, res, &comp_ctx->prev_token, + reg_temp) != 0) { + goto syntax_error; + } + } + + duk__advance_expect(comp_ctx, DUK_TOK_COLON); + + DUK__SETTEMP(comp_ctx, reg_temp + 1); + duk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, + reg_temp + 1 /*forced_reg*/); + + st.num_pairs++; + } + } /* property loop */ + + /* Flush remaining properties. */ + duk__objlit_flush_keys(comp_ctx, &st); + DUK_ASSERT(st.num_pairs == 0); + DUK_ASSERT(DUK__GETTEMP(comp_ctx) == st.temp_start); + + /* Update initial size for NEWOBJ. The init size doesn't need to be + * exact as the purpose is just to avoid object resizes in common + * cases. The size is capped to field A limit, and will be too high + * if the object literal contains duplicate keys (this is harmless but + * increases memory traffic if the object is compacted later on). + */ +#if !defined(DUK_USE_PREFER_SIZE) + instr = duk__get_instr_ptr(comp_ctx, pc_newobj); + instr->ins |= DUK_ENC_OP_A( + 0, st.num_total_pairs > DUK_BC_A_MAX ? DUK_BC_A_MAX : st.num_total_pairs); +#endif + + DUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RCURLY); + duk__advance(comp_ctx); /* No RegExp after object literal. */ + + duk__ivalue_regconst(res, st.reg_obj); + return; + +syntax_error: + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_OBJECT_LITERAL); + DUK_WO_NORETURN(return;); +} + +/* Parse argument list. Arguments are written to temps starting from + * "next temp". Returns number of arguments parsed. Expects left paren + * to be already eaten, and eats the right paren before returning. + */ +DUK_LOCAL duk_int_t duk__parse_arguments(duk_compiler_ctx *comp_ctx, + duk_ivalue *res) { + duk_int_t nargs = 0; + duk_regconst_t reg_temp; + + /* Note: expect that caller has already eaten the left paren */ + + DUK_DDD(DUK_DDDPRINT( + "start parsing arguments, prev_token.t=%ld, curr_token.t=%ld", + (long)comp_ctx->prev_token.t, (long)comp_ctx->curr_token.t)); + + for (;;) { + if (comp_ctx->curr_token.t == DUK_TOK_RPAREN) { + break; + } + if (nargs > 0) { + duk__advance_expect(comp_ctx, DUK_TOK_COMMA); + } + + /* We want the argument expression value to go to "next temp" + * without additional moves. That should almost always be the + * case, but we double check after expression parsing. + * + * This is not the cleanest possible approach. + */ + + reg_temp = DUK__ALLOCTEMP( + comp_ctx); /* bump up "allocated" reg count, just in case */ + DUK__SETTEMP(comp_ctx, reg_temp); + + /* binding power must be high enough to NOT allow comma expressions directly + */ + duk__expr_toforcedreg( + comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, + reg_temp); /* always allow 'in', coerce to 'tr' just in case */ + + DUK__SETTEMP(comp_ctx, reg_temp + 1); + nargs++; + + DUK_DDD(DUK_DDDPRINT("argument #%ld written into reg %ld", (long)nargs, + (long)reg_temp)); + } + + /* eat the right paren */ + duk__advance_expect(comp_ctx, + DUK_TOK_RPAREN); /* RegExp mode does not matter. */ + + DUK_DDD(DUK_DDDPRINT("end parsing arguments")); + + return nargs; +} + +DUK_LOCAL duk_bool_t duk__expr_is_empty(duk_compiler_ctx *comp_ctx) { + /* empty expressions can be detected conveniently with nud/led counts */ + return (comp_ctx->curr_func.nud_count == 0) && + (comp_ctx->curr_func.led_count == 0); +} + +DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) { + duk_hthread *thr = comp_ctx->thr; + duk_token *tk; + duk_regconst_t temp_at_entry; + duk_small_uint_t tok; + duk_uint32_t + args; /* temp variable to pass constants and flags to shared code */ + + /* + * ctx->prev_token token to process with duk__expr_nud() + * ctx->curr_token updated by caller + * + * Note: the token in the switch below has already been eaten. + */ + + temp_at_entry = DUK__GETTEMP(comp_ctx); + + comp_ctx->curr_func.nud_count++; + + tk = &comp_ctx->prev_token; + tok = tk->t; + res->t = DUK_IVAL_NONE; + + DUK_DDD(DUK_DDDPRINT( + "duk__expr_nud(), prev_token.t=%ld, allow_in=%ld, paren_level=%ld", + (long)tk->t, (long)comp_ctx->curr_func.allow_in, + (long)comp_ctx->curr_func.paren_level)); + + switch (tok) { + /* PRIMARY EXPRESSIONS */ + + case DUK_TOK_THIS: { + duk_regconst_t reg_temp; + reg_temp = DUK__ALLOCTEMP(comp_ctx); + duk__emit_bc(comp_ctx, DUK_OP_LDTHIS, reg_temp); + duk__ivalue_regconst(res, reg_temp); + return; + } + case DUK_TOK_IDENTIFIER: { + duk__ivalue_var_hstring(comp_ctx, res, tk->str1); + return; + } + case DUK_TOK_NULL: { + duk_push_null(thr); + goto plain_value; + } + case DUK_TOK_TRUE: { + duk_push_true(thr); + goto plain_value; + } + case DUK_TOK_FALSE: { + duk_push_false(thr); + goto plain_value; + } + case DUK_TOK_NUMBER: { + duk_push_number(thr, tk->num); + goto plain_value; + } + case DUK_TOK_STRING: { + DUK_ASSERT(tk->str1 != NULL); + duk_push_hstring(thr, tk->str1); + goto plain_value; + } + case DUK_TOK_REGEXP: { +#if defined(DUK_USE_REGEXP_SUPPORT) + duk_regconst_t reg_temp; + duk_regconst_t rc_re_bytecode; /* const */ + duk_regconst_t rc_re_source; /* const */ + + DUK_ASSERT(tk->str1 != NULL); + DUK_ASSERT(tk->str2 != NULL); + + DUK_DDD(DUK_DDDPRINT("emitting regexp op, str1=%!O, str2=%!O", + (duk_heaphdr *)tk->str1, (duk_heaphdr *)tk->str2)); + + reg_temp = DUK__ALLOCTEMP(comp_ctx); + duk_push_hstring(thr, tk->str1); + duk_push_hstring(thr, tk->str2); + + /* [ ... pattern flags ] */ + + duk_regexp_compile(thr); + + /* [ ... escaped_source bytecode ] */ + + rc_re_bytecode = duk__getconst(comp_ctx); + rc_re_source = duk__getconst(comp_ctx); + + duk__emit_a_b_c(comp_ctx, DUK_OP_REGEXP | DUK__EMIT_FLAG_BC_REGCONST, + reg_temp /*a*/, rc_re_bytecode /*b*/, rc_re_source /*c*/); + + duk__ivalue_regconst(res, reg_temp); + return; +#else /* DUK_USE_REGEXP_SUPPORT */ + goto syntax_error; +#endif /* DUK_USE_REGEXP_SUPPORT */ + } + case DUK_TOK_LBRACKET: { + DUK_DDD(DUK_DDDPRINT("parsing array literal")); + duk__nud_array_literal(comp_ctx, res); + return; + } + case DUK_TOK_LCURLY: { + DUK_DDD(DUK_DDDPRINT("parsing object literal")); + duk__nud_object_literal(comp_ctx, res); + return; + } + case DUK_TOK_LPAREN: { + duk_bool_t prev_allow_in; + + comp_ctx->curr_func.paren_level++; + prev_allow_in = comp_ctx->curr_func.allow_in; + comp_ctx->curr_func.allow_in = + 1; /* reset 'allow_in' for parenthesized expression */ + + duk__expr( + comp_ctx, res, + DUK__BP_FOR_EXPR /*rbp_flags*/); /* Expression, terminates at a ')' */ + + duk__advance_expect( + comp_ctx, + DUK_TOK_RPAREN); /* No RegExp after parenthesized expression. */ + comp_ctx->curr_func.allow_in = prev_allow_in; + comp_ctx->curr_func.paren_level--; + return; + } + + /* MEMBER/NEW/CALL EXPRESSIONS */ + + case DUK_TOK_NEW: { + /* + * Parsing an expression starting with 'new' is tricky because + * there are multiple possible productions deriving from + * LeftHandSideExpression which begin with 'new'. + * + * We currently resort to one-token lookahead to distinguish the + * cases. Hopefully this is correct. The binding power must be + * such that parsing ends at an LPAREN (CallExpression) but not at + * a PERIOD or LBRACKET (MemberExpression). + * + * See doc/compiler.rst for discussion on the parsing approach, + * and testcases/test-dev-new.js for a bunch of documented tests. + */ + + duk_regconst_t reg_target; + duk_int_t nargs; + + DUK_DDD(DUK_DDDPRINT("begin parsing new expression")); + + reg_target = DUK__ALLOCTEMPS(comp_ctx, 2); + +#if defined(DUK_USE_ES6) + if (comp_ctx->curr_token.t == DUK_TOK_PERIOD) { + /* new.target */ + DUK_DDD(DUK_DDDPRINT("new.target")); + duk__advance(comp_ctx); + if (comp_ctx->curr_token.t_nores != DUK_TOK_IDENTIFIER || + !duk_hstring_equals_ascii_cstring(comp_ctx->curr_token.str1, + "target")) { + goto syntax_error_newtarget; + } + if (comp_ctx->curr_func.is_global) { + goto syntax_error_newtarget; + } + duk__advance(comp_ctx); + duk__emit_bc(comp_ctx, DUK_OP_NEWTARGET, reg_target); + duk__ivalue_regconst(res, reg_target); + return; + } +#endif /* DUK_USE_ES6 */ + + duk__expr_toforcedreg(comp_ctx, res, DUK__BP_CALL /*rbp_flags*/, + reg_target /*forced_reg*/); + duk__emit_bc(comp_ctx, DUK_OP_NEWOBJ, + reg_target + 1); /* default instance */ + DUK__SETTEMP(comp_ctx, reg_target + 2); + + /* XXX: 'new obj.noSuch()' doesn't use GETPROPC now which + * makes the error message worse than for obj.noSuch(). + */ + + if (comp_ctx->curr_token.t == DUK_TOK_LPAREN) { + /* 'new' MemberExpression Arguments */ + DUK_DDD(DUK_DDDPRINT("new expression has argument list")); + duk__advance(comp_ctx); + nargs = duk__parse_arguments( + comp_ctx, + res); /* parse args starting from "next temp", reg_target + 1 */ + /* right paren eaten */ + } else { + /* 'new' MemberExpression */ + DUK_DDD(DUK_DDDPRINT("new expression has no argument list")); + nargs = 0; + } + + duk__emit_a_bc(comp_ctx, DUK_OP_CALL0 | DUK_BC_CALL_FLAG_CONSTRUCT, + nargs /*num_args*/, reg_target /*target*/); + + DUK_DDD(DUK_DDDPRINT("end parsing new expression")); + + duk__ivalue_regconst(res, reg_target); + return; + } + + /* FUNCTION EXPRESSIONS */ + + case DUK_TOK_FUNCTION: { + /* Function expression. Note that any statement beginning with 'function' + * is handled by the statement parser as a function declaration, or a + * non-standard function expression/statement (or a SyntaxError). We only + * handle actual function expressions (occurring inside an expression) + * here. + * + * O(depth^2) parse count for inner functions is handled by recording a + * lexer offset on the first compilation pass, so that the function can + * be efficiently skipped on the second pass. This is encapsulated into + * duk__parse_func_like_fnum(). + */ + + duk_regconst_t reg_temp; + duk_int_t fnum; + + reg_temp = DUK__ALLOCTEMP(comp_ctx); + + /* curr_token follows 'function' */ + fnum = duk__parse_func_like_fnum(comp_ctx, 0 /*flags*/); + DUK_DDD(DUK_DDDPRINT("parsed inner function -> fnum %ld", (long)fnum)); + + duk__emit_a_bc(comp_ctx, DUK_OP_CLOSURE, reg_temp /*a*/, + (duk_regconst_t)fnum /*bc*/); + + duk__ivalue_regconst(res, reg_temp); + return; + } + + /* UNARY EXPRESSIONS */ + + case DUK_TOK_DELETE: { + /* Delete semantics are a bit tricky. The description in E5 specification + * is kind of confusing, because it distinguishes between resolvability of + * a reference (which is only known at runtime) seemingly at compile time + * (= SyntaxError throwing). + */ + duk__expr(comp_ctx, res, + DUK__BP_MULTIPLICATIVE /*rbp_flags*/); /* UnaryExpression */ + if (res->t == DUK_IVAL_VAR) { + /* not allowed in strict mode, regardless of whether resolves; + * in non-strict mode DELVAR handles both non-resolving and + * resolving cases (the specification description is a bit confusing). + */ + + duk_regconst_t reg_temp; + duk_regconst_t reg_varbind; + duk_regconst_t rc_varname; + + if (comp_ctx->curr_func.is_strict) { + DUK_ERROR_SYNTAX(thr, DUK_STR_CANNOT_DELETE_IDENTIFIER); + DUK_WO_NORETURN(return;); + } + + DUK__SETTEMP(comp_ctx, temp_at_entry); + reg_temp = DUK__ALLOCTEMP(comp_ctx); + + duk_dup(thr, res->x1.valstack_idx); + if (duk__lookup_lhs(comp_ctx, ®_varbind, &rc_varname)) { + /* register bound variables are non-configurable -> always false */ + duk__emit_bc(comp_ctx, DUK_OP_LDFALSE, reg_temp); + } else { + duk_dup(thr, res->x1.valstack_idx); + rc_varname = duk__getconst(comp_ctx); + duk__emit_a_bc(comp_ctx, DUK_OP_DELVAR, reg_temp, rc_varname); + } + duk__ivalue_regconst(res, reg_temp); + } else if (res->t == DUK_IVAL_PROP) { + duk_regconst_t reg_temp; + duk_regconst_t reg_obj; + duk_regconst_t rc_key; + + DUK__SETTEMP(comp_ctx, temp_at_entry); + reg_temp = DUK__ALLOCTEMP(comp_ctx); + reg_obj = + duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, + 0 /*flags*/); /* don't allow const */ + rc_key = + duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, + DUK__IVAL_FLAG_ALLOW_CONST /*flags*/); + duk__emit_a_b_c(comp_ctx, DUK_OP_DELPROP | DUK__EMIT_FLAG_BC_REGCONST, + reg_temp, reg_obj, rc_key); + + duk__ivalue_regconst(res, reg_temp); + } else { + /* non-Reference deletion is always 'true', even in strict mode */ + duk_push_true(thr); + goto plain_value; + } + return; + } + case DUK_TOK_VOID: { + duk__expr_toplain_ignore( + comp_ctx, res, + DUK__BP_MULTIPLICATIVE /*rbp_flags*/); /* UnaryExpression */ + duk_push_undefined(thr); + goto plain_value; + } + case DUK_TOK_TYPEOF: { + /* 'typeof' must handle unresolvable references without throwing + * a ReferenceError (E5 Section 11.4.3). Register mapped values + * will never be unresolvable so special handling is only required + * when an identifier is a "slow path" one. + */ + duk__expr(comp_ctx, res, + DUK__BP_MULTIPLICATIVE /*rbp_flags*/); /* UnaryExpression */ + + if (res->t == DUK_IVAL_VAR) { + duk_regconst_t reg_varbind; + duk_regconst_t rc_varname; + duk_regconst_t reg_temp; + + duk_dup(thr, res->x1.valstack_idx); + if (!duk__lookup_lhs(comp_ctx, ®_varbind, &rc_varname)) { + DUK_DDD(DUK_DDDPRINT( + "typeof for an identifier name which could not be resolved " + "at compile time, need to use special run-time handling")); + reg_temp = DUK__ALLOCTEMP(comp_ctx); + duk__emit_a_bc(comp_ctx, DUK_OP_TYPEOFID, reg_temp, rc_varname); + duk__ivalue_regconst(res, reg_temp); + return; + } + } + + args = DUK_OP_TYPEOF; + goto unary; + } + case DUK_TOK_INCREMENT: { + args = (DUK_OP_PREINCP << 8) + DUK_OP_PREINCR; + goto preincdec; + } + case DUK_TOK_DECREMENT: { + args = (DUK_OP_PREDECP << 8) + DUK_OP_PREDECR; + goto preincdec; + } + case DUK_TOK_ADD: { + /* unary plus */ + duk__expr(comp_ctx, res, + DUK__BP_MULTIPLICATIVE /*rbp_flags*/); /* UnaryExpression */ + if (res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_VALUE && + duk_is_number(thr, res->x1.valstack_idx)) { + /* unary plus of a number is identity */ + return; + } + args = DUK_OP_UNP; + goto unary; + } + case DUK_TOK_SUB: { + /* unary minus */ + duk__expr(comp_ctx, res, + DUK__BP_MULTIPLICATIVE /*rbp_flags*/); /* UnaryExpression */ + if (res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_VALUE && + duk_is_number(thr, res->x1.valstack_idx)) { + /* this optimization is important to handle negative literals + * (which are not directly provided by the lexical grammar) + */ + duk_tval *tv_num; + duk_double_union du; + + tv_num = DUK_GET_TVAL_POSIDX(thr, res->x1.valstack_idx); + DUK_ASSERT(tv_num != NULL); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_num)); + du.d = DUK_TVAL_GET_NUMBER(tv_num); + du.d = -du.d; + DUK_DBLUNION_NORMALIZE_NAN_CHECK(&du); + DUK_TVAL_SET_NUMBER(tv_num, du.d); + return; + } + args = DUK_OP_UNM; + goto unary; + } + case DUK_TOK_BNOT: { + duk__expr(comp_ctx, res, + DUK__BP_MULTIPLICATIVE /*rbp_flags*/); /* UnaryExpression */ + args = DUK_OP_BNOT; + goto unary; + } + case DUK_TOK_LNOT: { + duk__expr(comp_ctx, res, + DUK__BP_MULTIPLICATIVE /*rbp_flags*/); /* UnaryExpression */ + if (res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_VALUE) { + /* Very minimal inlining to handle common idioms '!0' and '!1', + * and also boolean arguments like '!false' and '!true'. + */ + duk_tval *tv_val; + + tv_val = DUK_GET_TVAL_POSIDX(thr, res->x1.valstack_idx); + DUK_ASSERT(tv_val != NULL); + if (DUK_TVAL_IS_NUMBER(tv_val)) { + duk_double_t d; + d = DUK_TVAL_GET_NUMBER(tv_val); + if (duk_double_equals(d, 0.0)) { + /* Matches both +0 and -0 on purpose. */ + DUK_DDD(DUK_DDDPRINT("inlined lnot: !0 -> true")); + DUK_TVAL_SET_BOOLEAN_TRUE(tv_val); + return; + } else if (duk_double_equals(d, 1.0)) { + DUK_DDD(DUK_DDDPRINT("inlined lnot: !1 -> false")); + DUK_TVAL_SET_BOOLEAN_FALSE(tv_val); + return; + } + } else if (DUK_TVAL_IS_BOOLEAN(tv_val)) { + duk_small_uint_t v; + v = DUK_TVAL_GET_BOOLEAN(tv_val); + DUK_DDD(DUK_DDDPRINT("inlined lnot boolean: %ld", (long)v)); + DUK_ASSERT(v == 0 || v == 1); + DUK_TVAL_SET_BOOLEAN(tv_val, v ^ 0x01); + return; + } + } + args = DUK_OP_LNOT; + goto unary; + } + + } /* end switch */ + + DUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR); + DUK_WO_NORETURN(return;); + +unary : { + /* Unary opcodes use just the 'BC' register source because it + * matches current shuffle limits, and maps cleanly to 16 high + * bits of the opcode. + */ + + duk_regconst_t reg_src, reg_res; + + reg_src = + duk__ivalue_toregconst_raw(comp_ctx, res, -1 /*forced_reg*/, 0 /*flags*/); + if (DUK__ISREG_TEMP(comp_ctx, reg_src)) { + reg_res = reg_src; + } else { + reg_res = DUK__ALLOCTEMP(comp_ctx); + } + duk__emit_a_bc(comp_ctx, args, reg_res, reg_src); + duk__ivalue_regconst(res, reg_res); + return; +} + +preincdec : { + /* preincrement and predecrement */ + duk_regconst_t reg_res; + duk_small_uint_t args_op1 = args & 0xff; /* DUK_OP_PREINCR/DUK_OP_PREDECR */ + duk_small_uint_t args_op2 = + args >> 8; /* DUK_OP_PREINCP_RR/DUK_OP_PREDECP_RR */ + + /* Specific assumptions for opcode numbering. */ + DUK_ASSERT(DUK_OP_PREINCR + 4 == DUK_OP_PREINCV); + DUK_ASSERT(DUK_OP_PREDECR + 4 == DUK_OP_PREDECV); + + reg_res = DUK__ALLOCTEMP(comp_ctx); + + duk__expr(comp_ctx, res, + DUK__BP_MULTIPLICATIVE /*rbp_flags*/); /* UnaryExpression */ + if (res->t == DUK_IVAL_VAR) { + duk_hstring *h_varname; + duk_regconst_t reg_varbind; + duk_regconst_t rc_varname; + + h_varname = duk_known_hstring(thr, res->x1.valstack_idx); + + if (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) { + goto syntax_error; + } + + duk_dup(thr, res->x1.valstack_idx); + if (duk__lookup_lhs(comp_ctx, ®_varbind, &rc_varname)) { + duk__emit_a_bc(comp_ctx, args_op1, /* e.g. DUK_OP_PREINCR */ + reg_res, reg_varbind); + } else { + duk__emit_a_bc(comp_ctx, args_op1 + 4, /* e.g. DUK_OP_PREINCV */ + reg_res, rc_varname); + } + + DUK_DDD(DUK_DDDPRINT( + "preincdec to '%!O' -> reg_varbind=%ld, rc_varname=%ld", + (duk_heaphdr *)h_varname, (long)reg_varbind, (long)rc_varname)); + } else if (res->t == DUK_IVAL_PROP) { + duk_regconst_t reg_obj; /* allocate to reg only (not const) */ + duk_regconst_t rc_key; + reg_obj = duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, + 0 /*flags*/); /* don't allow const */ + rc_key = duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, + DUK__IVAL_FLAG_ALLOW_CONST /*flags*/); + duk__emit_a_b_c( + comp_ctx, + args_op2 | DUK__EMIT_FLAG_BC_REGCONST, /* e.g. DUK_OP_PREINCP */ + reg_res, reg_obj, rc_key); + } else { + /* Technically return value is not needed because INVLHS will + * unconditially throw a ReferenceError. Coercion is necessary + * for proper semantics (consider ToNumber() called for an object). + * Use DUK_OP_UNP with a dummy register to get ToNumber(). + */ + + duk__ivalue_toforcedreg(comp_ctx, res, reg_res); + duk__emit_bc(comp_ctx, DUK_OP_UNP, + reg_res); /* for side effects, result ignored */ + duk__emit_op_only(comp_ctx, DUK_OP_INVLHS); + } + DUK__SETTEMP(comp_ctx, reg_res + 1); + duk__ivalue_regconst(res, reg_res); + return; +} + +plain_value : { + /* Stack top contains plain value */ + duk__ivalue_plain_fromstack(comp_ctx, res); + return; +} + +#if defined(DUK_USE_ES6) +syntax_error_newtarget: + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_NEWTARGET); + DUK_WO_NORETURN(return;); +#endif + +syntax_error: + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_EXPRESSION); + DUK_WO_NORETURN(return;); +} + +/* XXX: add flag to indicate whether caller cares about return value; this + * affects e.g. handling of assignment expressions. This change needs API + * changes elsewhere too. + */ +DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, + duk_ivalue *res) { + duk_hthread *thr = comp_ctx->thr; + duk_token *tk; + duk_small_uint_t tok; + duk_uint32_t + args; /* temp variable to pass constants and flags to shared code */ + + /* + * ctx->prev_token token to process with duk__expr_led() + * ctx->curr_token updated by caller + */ + + comp_ctx->curr_func.led_count++; + + /* The token in the switch has already been eaten here */ + tk = &comp_ctx->prev_token; + tok = tk->t; + + DUK_DDD(DUK_DDDPRINT( + "duk__expr_led(), prev_token.t=%ld, allow_in=%ld, paren_level=%ld", + (long)tk->t, (long)comp_ctx->curr_func.allow_in, + (long)comp_ctx->curr_func.paren_level)); + + /* XXX: default priority for infix operators is duk__expr_lbp(tok) -> get it + * here? */ + + switch (tok) { + /* PRIMARY EXPRESSIONS */ + + case DUK_TOK_PERIOD: { + /* Property access expressions are critical for correct LHS ordering, + * see comments in duk__expr()! + * + * A conservative approach would be to use duk__ivalue_totempconst() + * for 'left'. However, allowing a reg-bound variable seems safe here + * and is nice because "foo.bar" is a common expression. If the ivalue + * is used in an expression a GETPROP will occur before any changes to + * the base value can occur. If the ivalue is used as an assignment + * LHS, the assignment code will ensure the base value is safe from + * RHS mutation. + */ + + /* XXX: This now coerces an identifier into a GETVAR to a temp, which + * causes an extra LDREG in call setup. It's sufficient to coerce to a + * unary ivalue? + */ + duk__ivalue_toplain(comp_ctx, left); + + /* NB: must accept reserved words as property name */ + if (comp_ctx->curr_token.t_nores != DUK_TOK_IDENTIFIER) { + DUK_ERROR_SYNTAX(thr, DUK_STR_EXPECTED_IDENTIFIER); + DUK_WO_NORETURN(return;); + } + + res->t = DUK_IVAL_PROP; + duk__copy_ispec(comp_ctx, &left->x1, &res->x1); /* left.x1 -> res.x1 */ + DUK_ASSERT(comp_ctx->curr_token.str1 != NULL); + duk_push_hstring(thr, comp_ctx->curr_token.str1); + duk_replace(thr, res->x2.valstack_idx); + res->x2.t = DUK_ISPEC_VALUE; + + /* special RegExp literal handling after IdentifierName */ + comp_ctx->curr_func.reject_regexp_in_adv = 1; + + duk__advance(comp_ctx); + return; + } + case DUK_TOK_LBRACKET: { + /* Property access expressions are critical for correct LHS ordering, + * see comments in duk__expr()! + */ + + /* XXX: optimize temp reg use */ + /* XXX: similar coercion issue as in DUK_TOK_PERIOD */ + /* XXX: coerce to regs? it might be better for enumeration use, where the + * same PROP ivalue is used multiple times. Or perhaps coerce PROP + * further there? + */ + /* XXX: for simple cases like x['y'] an unnecessary LDREG is + * emitted for the base value; could avoid it if we knew that + * the key expression is safe (e.g. just a single literal). + */ + + /* The 'left' value must not be a register bound variable + * because it may be mutated during the rest of the expression + * and E5.1 Section 11.2.1 specifies the order of evaluation + * so that the base value is evaluated first. + * See: test-bug-nested-prop-mutate.js. + */ + duk__ivalue_totempconst(comp_ctx, left); + duk__expr_toplain( + comp_ctx, res, + DUK__BP_FOR_EXPR /*rbp_flags*/); /* Expression, ']' terminates */ + duk__advance_expect(comp_ctx, DUK_TOK_RBRACKET); + + res->t = DUK_IVAL_PROP; + duk__copy_ispec(comp_ctx, &res->x1, &res->x2); /* res.x1 -> res.x2 */ + duk__copy_ispec(comp_ctx, &left->x1, &res->x1); /* left.x1 -> res.x1 */ + return; + } + case DUK_TOK_LPAREN: { + /* function call */ + duk_regconst_t reg_cs = DUK__ALLOCTEMPS(comp_ctx, 2); + duk_int_t nargs; + duk_small_uint_t call_op = DUK_OP_CALL0; + + /* XXX: attempt to get the call result to "next temp" whenever + * possible to avoid unnecessary register shuffles. + */ + + /* + * Setup call: target and 'this' binding. Three cases: + * + * 1. Identifier base (e.g. "foo()") + * 2. Property base (e.g. "foo.bar()") + * 3. Register base (e.g. "foo()()"; i.e. when a return value is a + * function) + */ + + if (left->t == DUK_IVAL_VAR) { + duk_hstring *h_varname; + duk_regconst_t reg_varbind; + duk_regconst_t rc_varname; + + DUK_DDD(DUK_DDDPRINT("function call with identifier base")); + + h_varname = duk_known_hstring(thr, left->x1.valstack_idx); + if (h_varname == DUK_HTHREAD_STRING_EVAL(thr)) { + /* Potential direct eval call detected, flag the CALL + * so that a run-time "direct eval" check is made and + * special behavior may be triggered. Note that this + * does not prevent 'eval' from being register bound. + */ + DUK_DDD(DUK_DDDPRINT("function call with identifier 'eval' " + "-> using EVALCALL, marking function " + "as may_direct_eval")); + call_op |= DUK_BC_CALL_FLAG_CALLED_AS_EVAL; + comp_ctx->curr_func.may_direct_eval = 1; + } + + duk_dup(thr, left->x1.valstack_idx); + if (duk__lookup_lhs(comp_ctx, ®_varbind, &rc_varname)) { + duk__emit_a_bc(comp_ctx, DUK_OP_CSREG | DUK__EMIT_FLAG_A_IS_SOURCE, + reg_varbind, reg_cs + 0); + } else { + /* XXX: expand target register or constant field to + * reduce shuffling. + */ + DUK_ASSERT(DUK__ISCONST(rc_varname)); + duk__emit_a_b(comp_ctx, DUK_OP_CSVAR | DUK__EMIT_FLAG_BC_REGCONST, + reg_cs + 0, rc_varname); + } + } else if (left->t == DUK_IVAL_PROP) { + /* Call through a property lookup, E5 Section 11.2.3, step 6.a.i, + * E5 Section 10.4.3. There used to be a separate CSPROP opcode + * but a typical call setup took 3 opcodes (e.g. LDREG, LDCONST, + * CSPROP) and the same can be achieved with ordinary loads. + */ +#if defined(DUK_USE_VERBOSE_ERRORS) + duk_regconst_t reg_key; +#endif + + DUK_DDD(DUK_DDDPRINT("function call with property base")); + + /* XXX: For Math.sin() this generates: LDCONST + LDREG + + * GETPROPC + call. The LDREG is unnecessary because LDCONST + * could be loaded directly into reg_cs + 1. This doesn't + * happen now because a variable cannot be in left->x1 of a + * DUK_IVAL_PROP. We could notice that left->x1 is a temp + * and reuse, but it would still be in the wrong position + * (reg_cs + 0 rather than reg_cs + 1). + */ + duk__ispec_toforcedreg(comp_ctx, &left->x1, reg_cs + 1); /* base */ +#if defined(DUK_USE_VERBOSE_ERRORS) + reg_key = duk__ispec_toregconst_raw( + comp_ctx, &left->x2, -1, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/); + duk__emit_a_b_c(comp_ctx, DUK_OP_GETPROPC | DUK__EMIT_FLAG_BC_REGCONST, + reg_cs + 0, reg_cs + 1, reg_key); +#else + duk__ivalue_toforcedreg(comp_ctx, left, reg_cs + 0); /* base[key] */ +#endif + } else { + DUK_DDD(DUK_DDDPRINT("function call with register base")); + + duk__ivalue_toforcedreg(comp_ctx, left, reg_cs + 0); +#if 0 + duk__emit_a_bc(comp_ctx, + DUK_OP_CSREG | DUK__EMIT_FLAG_A_IS_SOURCE, + reg_cs + 0, + reg_cs + 0); /* in-place setup */ +#endif + /* Because of in-place setup, REGCS is equivalent to + * just this LDUNDEF. + */ + duk__emit_bc(comp_ctx, DUK_OP_LDUNDEF, reg_cs + 1); + } + + DUK__SETTEMP(comp_ctx, reg_cs + 2); + nargs = duk__parse_arguments( + comp_ctx, res); /* parse args starting from "next temp" */ + + /* Tailcalls are handled by back-patching the already emitted opcode + * later in return statement parser. + */ + + duk__emit_a_bc(comp_ctx, call_op, (duk_regconst_t)nargs /*numargs*/, + reg_cs /*basereg*/); + DUK__SETTEMP(comp_ctx, reg_cs + 1); /* result in csreg */ + + duk__ivalue_regconst(res, reg_cs); + return; + } + + /* POSTFIX EXPRESSION */ + + case DUK_TOK_INCREMENT: { + args = (DUK_OP_POSTINCP_RR << 16) + (DUK_OP_POSTINCR << 8) + 0; + goto postincdec; + } + case DUK_TOK_DECREMENT: { + args = (DUK_OP_POSTDECP_RR << 16) + (DUK_OP_POSTDECR << 8) + 0; + goto postincdec; + } + + /* EXPONENTIATION EXPRESSION */ + +#if defined(DUK_USE_ES7_EXP_OPERATOR) + case DUK_TOK_EXP: { + args = + (DUK_OP_EXP << 8) + DUK__BP_EXPONENTIATION - 1; /* UnaryExpression */ + goto binary; + } +#endif + + /* MULTIPLICATIVE EXPRESSION */ + + case DUK_TOK_MUL: { + args = (DUK_OP_MUL << 8) + + DUK__BP_MULTIPLICATIVE; /* ExponentiationExpression */ + goto binary; + } + case DUK_TOK_DIV: { + args = (DUK_OP_DIV << 8) + + DUK__BP_MULTIPLICATIVE; /* ExponentiationExpression */ + goto binary; + } + case DUK_TOK_MOD: { + args = (DUK_OP_MOD << 8) + + DUK__BP_MULTIPLICATIVE; /* ExponentiationExpression */ + goto binary; + } + + /* ADDITIVE EXPRESSION */ + + case DUK_TOK_ADD: { + args = + (DUK_OP_ADD << 8) + DUK__BP_ADDITIVE; /* MultiplicativeExpression */ + goto binary; + } + case DUK_TOK_SUB: { + args = + (DUK_OP_SUB << 8) + DUK__BP_ADDITIVE; /* MultiplicativeExpression */ + goto binary; + } + + /* SHIFT EXPRESSION */ + + case DUK_TOK_ALSHIFT: { + /* << */ + args = (DUK_OP_BASL << 8) + DUK__BP_SHIFT; + goto binary; + } + case DUK_TOK_ARSHIFT: { + /* >> */ + args = (DUK_OP_BASR << 8) + DUK__BP_SHIFT; + goto binary; + } + case DUK_TOK_RSHIFT: { + /* >>> */ + args = (DUK_OP_BLSR << 8) + DUK__BP_SHIFT; + goto binary; + } + + /* RELATIONAL EXPRESSION */ + + case DUK_TOK_LT: { + /* < */ + args = (DUK_OP_LT << 8) + DUK__BP_RELATIONAL; + goto binary; + } + case DUK_TOK_GT: { + args = (DUK_OP_GT << 8) + DUK__BP_RELATIONAL; + goto binary; + } + case DUK_TOK_LE: { + args = (DUK_OP_LE << 8) + DUK__BP_RELATIONAL; + goto binary; + } + case DUK_TOK_GE: { + args = (DUK_OP_GE << 8) + DUK__BP_RELATIONAL; + goto binary; + } + case DUK_TOK_INSTANCEOF: { + args = (DUK_OP_INSTOF << 8) + DUK__BP_RELATIONAL; + goto binary; + } + case DUK_TOK_IN: { + args = (DUK_OP_IN << 8) + DUK__BP_RELATIONAL; + goto binary; + } + + /* EQUALITY EXPRESSION */ + + case DUK_TOK_EQ: { + args = (DUK_OP_EQ << 8) + DUK__BP_EQUALITY; + goto binary; + } + case DUK_TOK_NEQ: { + args = (DUK_OP_NEQ << 8) + DUK__BP_EQUALITY; + goto binary; + } + case DUK_TOK_SEQ: { + args = (DUK_OP_SEQ << 8) + DUK__BP_EQUALITY; + goto binary; + } + case DUK_TOK_SNEQ: { + args = (DUK_OP_SNEQ << 8) + DUK__BP_EQUALITY; + goto binary; + } + + /* BITWISE EXPRESSIONS */ + + case DUK_TOK_BAND: { + args = (DUK_OP_BAND << 8) + DUK__BP_BAND; + goto binary; + } + case DUK_TOK_BXOR: { + args = (DUK_OP_BXOR << 8) + DUK__BP_BXOR; + goto binary; + } + case DUK_TOK_BOR: { + args = (DUK_OP_BOR << 8) + DUK__BP_BOR; + goto binary; + } + + /* LOGICAL EXPRESSIONS */ + + case DUK_TOK_LAND: { + /* syntactically left-associative but parsed as right-associative */ + args = (1u << 8) + DUK__BP_LAND - 1; + goto binary_logical; + } + case DUK_TOK_LOR: { + /* syntactically left-associative but parsed as right-associative */ + args = (0 << 8) + DUK__BP_LOR - 1; + goto binary_logical; + } + + /* CONDITIONAL EXPRESSION */ + + case DUK_TOK_QUESTION: { + /* XXX: common reg allocation need is to reuse a sub-expression's temp + * reg, but only if it really is a temp. Nothing fancy here now. + */ + duk_regconst_t reg_temp; + duk_int_t pc_jump1; + duk_int_t pc_jump2; + + reg_temp = DUK__ALLOCTEMP(comp_ctx); + duk__ivalue_toforcedreg(comp_ctx, left, reg_temp); + duk__emit_if_true_skip(comp_ctx, reg_temp); + pc_jump1 = duk__emit_jump_empty(comp_ctx); /* jump to false */ + duk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, + reg_temp /*forced_reg*/); /* AssignmentExpression */ + duk__advance_expect(comp_ctx, DUK_TOK_COLON); + pc_jump2 = duk__emit_jump_empty(comp_ctx); /* jump to end */ + duk__patch_jump_here(comp_ctx, pc_jump1); + duk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, + reg_temp /*forced_reg*/); /* AssignmentExpression */ + duk__patch_jump_here(comp_ctx, pc_jump2); + + DUK__SETTEMP(comp_ctx, reg_temp + 1); + duk__ivalue_regconst(res, reg_temp); + return; + } + + /* ASSIGNMENT EXPRESSION */ + + case DUK_TOK_EQUALSIGN: { + /* + * Assignments are right associative, allows e.g. + * a = 5; + * a += b = 9; // same as a += (b = 9) + * -> expression value 14, a = 14, b = 9 + * + * Right associativiness is reflected in the BP for recursion, + * "-1" ensures assignment operations are allowed. + * + * XXX: just use DUK__BP_COMMA (i.e. no need for 2-step bp levels)? + */ + args = (DUK_OP_NONE << 8) + DUK__BP_ASSIGNMENT - + 1; /* DUK_OP_NONE marks a 'plain' assignment */ + goto assign; + } + case DUK_TOK_ADD_EQ: { + /* right associative */ + args = (DUK_OP_ADD << 8) + DUK__BP_ASSIGNMENT - 1; + goto assign; + } + case DUK_TOK_SUB_EQ: { + /* right associative */ + args = (DUK_OP_SUB << 8) + DUK__BP_ASSIGNMENT - 1; + goto assign; + } + case DUK_TOK_MUL_EQ: { + /* right associative */ + args = (DUK_OP_MUL << 8) + DUK__BP_ASSIGNMENT - 1; + goto assign; + } + case DUK_TOK_DIV_EQ: { + /* right associative */ + args = (DUK_OP_DIV << 8) + DUK__BP_ASSIGNMENT - 1; + goto assign; + } + case DUK_TOK_MOD_EQ: { + /* right associative */ + args = (DUK_OP_MOD << 8) + DUK__BP_ASSIGNMENT - 1; + goto assign; + } +#if defined(DUK_USE_ES7_EXP_OPERATOR) + case DUK_TOK_EXP_EQ: { + /* right associative */ + args = (DUK_OP_EXP << 8) + DUK__BP_ASSIGNMENT - 1; + goto assign; + } +#endif + case DUK_TOK_ALSHIFT_EQ: { + /* right associative */ + args = (DUK_OP_BASL << 8) + DUK__BP_ASSIGNMENT - 1; + goto assign; + } + case DUK_TOK_ARSHIFT_EQ: { + /* right associative */ + args = (DUK_OP_BASR << 8) + DUK__BP_ASSIGNMENT - 1; + goto assign; + } + case DUK_TOK_RSHIFT_EQ: { + /* right associative */ + args = (DUK_OP_BLSR << 8) + DUK__BP_ASSIGNMENT - 1; + goto assign; + } + case DUK_TOK_BAND_EQ: { + /* right associative */ + args = (DUK_OP_BAND << 8) + DUK__BP_ASSIGNMENT - 1; + goto assign; + } + case DUK_TOK_BOR_EQ: { + /* right associative */ + args = (DUK_OP_BOR << 8) + DUK__BP_ASSIGNMENT - 1; + goto assign; + } + case DUK_TOK_BXOR_EQ: { + /* right associative */ + args = (DUK_OP_BXOR << 8) + DUK__BP_ASSIGNMENT - 1; + goto assign; + } + + /* COMMA */ + + case DUK_TOK_COMMA: { + /* right associative */ + + duk__ivalue_toplain_ignore(comp_ctx, + left); /* need side effects, not value */ + duk__expr_toplain(comp_ctx, res, DUK__BP_COMMA - 1 /*rbp_flags*/); + + /* return 'res' (of right part) as our result */ + return; + } + + default: { + break; + } + } + + DUK_D(DUK_DPRINT("parse error: unexpected token: %ld", (long)tok)); + DUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR); + DUK_WO_NORETURN(return;); + +#if 0 + /* XXX: shared handling for 'duk__expr_lhs'? */ + if (comp_ctx->curr_func.paren_level == 0 && XXX) { + comp_ctx->curr_func.duk__expr_lhs = 0; + } +#endif + +binary: + /* + * Shared handling of binary operations + * + * args = (opcode << 8) + rbp + */ + { + duk__ivalue_toplain(comp_ctx, left); + duk__expr_toplain(comp_ctx, res, args & 0xff /*rbp_flags*/); + + /* combine left->x1 and res->x1 (right->x1, really) -> (left->x1 OP res->x1) + */ + DUK_ASSERT(left->t == DUK_IVAL_PLAIN); + DUK_ASSERT(res->t == DUK_IVAL_PLAIN); + + res->t = DUK_IVAL_ARITH; + res->op = (args >> 8) & 0xff; + + res->x2.t = res->x1.t; + res->x2.regconst = res->x1.regconst; + duk_copy(thr, res->x1.valstack_idx, res->x2.valstack_idx); + + res->x1.t = left->x1.t; + res->x1.regconst = left->x1.regconst; + duk_copy(thr, left->x1.valstack_idx, res->x1.valstack_idx); + + DUK_DDD(DUK_DDDPRINT( + "binary op, res: t=%ld, x1.t=%ld, x1.regconst=0x%08lx, x2.t=%ld, " + "x2.regconst=0x%08lx", + (long)res->t, (long)res->x1.t, (unsigned long)res->x1.regconst, + (long)res->x2.t, (unsigned long)res->x2.regconst)); + return; + } + +binary_logical: + /* + * Shared handling for logical AND and logical OR. + * + * args = (truthval << 8) + rbp + * + * Truthval determines when to skip right-hand-side. + * For logical AND truthval=1, for logical OR truthval=0. + * + * See doc/compiler.rst for discussion on compiling logical + * AND and OR expressions. The approach here is very simplistic, + * generating extra jumps and multiple evaluations of truth values, + * but generates code on-the-fly with only local back-patching. + * + * Both logical AND and OR are syntactically left-associated. + * However, logical ANDs are compiled as right associative + * expressions, i.e. "A && B && C" as "A && (B && C)", to allow + * skip jumps to skip over the entire tail. Similarly for logical OR. + */ + + { + duk_regconst_t reg_temp; + duk_int_t pc_jump; + duk_small_uint_t args_truthval = args >> 8; + duk_small_uint_t args_rbp = args & 0xff; + + /* XXX: unoptimal use of temps, resetting */ + + reg_temp = DUK__ALLOCTEMP(comp_ctx); + + duk__ivalue_toforcedreg(comp_ctx, left, reg_temp); + DUK_ASSERT(DUK__ISREG(reg_temp)); + duk__emit_bc(comp_ctx, (args_truthval ? DUK_OP_IFTRUE_R : DUK_OP_IFFALSE_R), + reg_temp); /* skip jump conditionally */ + pc_jump = duk__emit_jump_empty(comp_ctx); + duk__expr_toforcedreg(comp_ctx, res, args_rbp /*rbp_flags*/, + reg_temp /*forced_reg*/); + duk__patch_jump_here(comp_ctx, pc_jump); + + duk__ivalue_regconst(res, reg_temp); + return; + } + +assign: + /* + * Shared assignment expression handling + * + * args = (opcode << 8) + rbp + * + * If 'opcode' is DUK_OP_NONE, plain assignment without arithmetic. + * Syntactically valid left-hand-side forms which are not accepted as + * left-hand-side values (e.g. as in "f() = 1") must NOT cause a + * SyntaxError, but rather a run-time ReferenceError. + * + * When evaluating X = Y, the LHS (X) is conceptually evaluated + * to a temporary first. The RHS is then evaluated. Finally, the + * is applied to the initial value of RHS (not the value after + * RHS evaluation), and written to X. Doing so concretely generates + * inefficient code so we'd like to avoid the temporary when possible. + * See: https://github.com/svaarala/duktape/pull/992. + * + * The expression value (final LHS value, written to RHS) is + * conceptually copied into a fresh temporary so that it won't + * change even if the LHS/RHS values change in outer expressions. + * For example, it'd be generally incorrect for the expression value + * to be the RHS register binding, unless there's a guarantee that it + * won't change during further expression evaluation. Using the + * temporary concretely produces inefficient bytecode, so we try to + * avoid the extra temporary for some known-to-be-safe cases. + * Currently the only safe case we detect is a "top level assignment", + * for example "x = y + z;", where the assignment expression value is + * ignored. + * See: test-dev-assign-expr.js and test-bug-assign-mutate-gh381.js. + */ + + { + duk_small_uint_t args_op = args >> 8; + duk_small_uint_t args_rbp = args & 0xff; + duk_bool_t toplevel_assign; + + /* XXX: here we need to know if 'left' is left-hand-side compatible. + * That information is no longer available from current expr parsing + * state; it would need to be carried into the 'left' ivalue or by + * some other means. + */ + + /* A top-level assignment is e.g. "x = y;". For these it's safe + * to use the RHS as-is as the expression value, even if the RHS + * is a reg-bound identifier. The RHS ('res') is right associative + * so it has consumed all other assignment level operations; the + * only relevant lower binding power construct is comma operator + * which will ignore the expression value provided here. Usually + * the top level assignment expression value is ignored, but it + * is relevant for e.g. eval code. + */ + toplevel_assign = + (comp_ctx->curr_func.nud_count == 1 && /* one token before */ + comp_ctx->curr_func.led_count == 1); /* one operator (= assign) */ + DUK_DDD(DUK_DDDPRINT( + "assignment: nud_count=%ld, led_count=%ld, toplevel_assign=%ld", + (long)comp_ctx->curr_func.nud_count, + (long)comp_ctx->curr_func.led_count, (long)toplevel_assign)); + + if (left->t == DUK_IVAL_VAR) { + duk_hstring *h_varname; + duk_regconst_t reg_varbind; + duk_regconst_t rc_varname; + + DUK_ASSERT(left->x1.t == + DUK_ISPEC_VALUE); /* LHS is already side effect free */ + + h_varname = duk_known_hstring(thr, left->x1.valstack_idx); + if (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, + h_varname)) { + /* E5 Section 11.13.1 (and others for other assignments), step 4. */ + goto syntax_error_lvalue; + } + duk_dup(thr, left->x1.valstack_idx); + (void)duk__lookup_lhs(comp_ctx, ®_varbind, &rc_varname); + + if (args_op == DUK_OP_NONE) { + duk__expr(comp_ctx, res, args_rbp /*rbp_flags*/); + if (toplevel_assign) { + /* Any 'res' will do. */ + DUK_DDD(DUK_DDDPRINT("plain assignment, toplevel assign, use as is")); + } else { + /* 'res' must be a plain ivalue, and not register-bound variable. */ + DUK_DDD( + DUK_DDDPRINT("plain assignment, not toplevel assign, ensure not " + "a reg-bound identifier")); + if (res->t != DUK_IVAL_PLAIN || + (res->x1.t == DUK_ISPEC_REGCONST && + DUK__ISREG_NOTTEMP(comp_ctx, res->x1.regconst))) { + duk__ivalue_totempconst(comp_ctx, res); + } + } + } else { + /* For X = Y we need to evaluate the pre-op + * value of X before evaluating the RHS: the RHS + * can change X, but when we do we must use + * the pre-op value. + */ + duk_regconst_t reg_temp; + + reg_temp = DUK__ALLOCTEMP(comp_ctx); + + if (reg_varbind >= 0) { + duk_regconst_t reg_res; + duk_regconst_t reg_src; + duk_int_t pc_temp_load; + duk_int_t pc_before_rhs; + duk_int_t pc_after_rhs; + + if (toplevel_assign) { + /* 'reg_varbind' is the operation result and can also + * become the expression value for top level assignments + * such as: "var x; x += y;". + */ + DUK_DD( + DUK_DDPRINT("= expression is top level, write directly to " + "reg_varbind")); + reg_res = reg_varbind; + } else { + /* Not safe to use 'reg_varbind' as assignment expression + * value, so go through a temp. + */ + DUK_DD(DUK_DDPRINT( + "= expression is not top level, write to reg_temp")); + reg_res = reg_temp; /* reg_res should be smallest possible */ + reg_temp = DUK__ALLOCTEMP(comp_ctx); + } + + /* Try to optimize X = Y for reg-bound + * variables. Detect side-effect free RHS + * narrowly by seeing whether it emits code. + * If not, rewind the code emitter and overwrite + * the unnecessary temp reg load. + */ + + pc_temp_load = duk__get_current_pc(comp_ctx); + duk__emit_a_bc(comp_ctx, DUK_OP_LDREG, reg_temp, reg_varbind); + + pc_before_rhs = duk__get_current_pc(comp_ctx); + duk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/); + DUK_ASSERT(res->t == DUK_IVAL_PLAIN && + res->x1.t == DUK_ISPEC_REGCONST); + pc_after_rhs = duk__get_current_pc(comp_ctx); + + DUK_DD(DUK_DDPRINT( + "pc_temp_load=%ld, pc_before_rhs=%ld, pc_after_rhs=%ld", + (long)pc_temp_load, (long)pc_before_rhs, (long)pc_after_rhs)); + + if (pc_after_rhs == pc_before_rhs) { + /* Note: if the reg_temp load generated shuffling + * instructions, we may need to rewind more than + * one instruction, so use explicit PC computation. + */ + DUK_DD(DUK_DDPRINT("rhs is side effect free, rewind and avoid " + "unnecessary temp for reg-based =")); + DUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, + (pc_temp_load - pc_before_rhs) * + (duk_int_t)sizeof(duk_compiler_instr)); + reg_src = reg_varbind; + } else { + DUK_DD( + DUK_DDPRINT("rhs evaluation emitted code, not sure if rhs is " + "side effect free; use temp reg for LHS")); + reg_src = reg_temp; + } + + duk__emit_a_b_c(comp_ctx, args_op | DUK__EMIT_FLAG_BC_REGCONST, + reg_res, reg_src, res->x1.regconst); + + res->x1.regconst = reg_res; + + /* Ensure compact use of temps. */ + if (DUK__ISREG_TEMP(comp_ctx, reg_res)) { + DUK__SETTEMP(comp_ctx, reg_res + 1); + } + } else { + /* When LHS is not register bound, always go through a + * temporary. No optimization for top level assignment. + */ + + duk__emit_a_bc(comp_ctx, DUK_OP_GETVAR, reg_temp, rc_varname); + + duk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/); + DUK_ASSERT(res->t == DUK_IVAL_PLAIN && + res->x1.t == DUK_ISPEC_REGCONST); + + duk__emit_a_b_c(comp_ctx, args_op | DUK__EMIT_FLAG_BC_REGCONST, + reg_temp, reg_temp, res->x1.regconst); + res->x1.regconst = reg_temp; + } + + DUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST); + } + + /* At this point 'res' holds the potential expression value. + * It can be basically any ivalue here, including a reg-bound + * identifier (if code above deems it safe) or a unary/binary + * operation. Operations must be resolved to a side effect free + * plain value, and the side effects must happen exactly once. + */ + + if (reg_varbind >= 0) { + if (res->t != DUK_IVAL_PLAIN) { + /* Resolve 'res' directly into the LHS binding, and use + * that as the expression value if safe. If not safe, + * resolve to a temp/const and copy to LHS. + */ + if (toplevel_assign) { + duk__ivalue_toforcedreg(comp_ctx, res, (duk_int_t)reg_varbind); + } else { + duk__ivalue_totempconst(comp_ctx, res); + duk__copy_ivalue(comp_ctx, res, left); /* use 'left' as a temp */ + duk__ivalue_toforcedreg(comp_ctx, left, (duk_int_t)reg_varbind); + } + } else { + /* Use 'res' as the expression value (it's side effect + * free and may be a plain value, a register, or a + * constant) and write it to the LHS binding too. + */ + duk__copy_ivalue(comp_ctx, res, left); /* use 'left' as a temp */ + duk__ivalue_toforcedreg(comp_ctx, left, (duk_int_t)reg_varbind); + } + } else { + /* Only a reg fits into 'A' so coerce 'res' into a register + * for PUTVAR. + * + * XXX: here the current A/B/C split is suboptimal: we could + * just use 9 bits for reg_res (and support constants) and 17 + * instead of 18 bits for the varname const index. + */ + + duk__ivalue_toreg(comp_ctx, res); + duk__emit_a_bc(comp_ctx, DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE, + res->x1.regconst, rc_varname); + } + + /* 'res' contains expression value */ + } else if (left->t == DUK_IVAL_PROP) { + /* E5 Section 11.13.1 (and others) step 4 never matches for prop writes -> + * no check */ + duk_regconst_t reg_obj; + duk_regconst_t rc_key; + duk_regconst_t rc_res; + duk_regconst_t reg_temp; + + /* Property access expressions ('a[b]') are critical to correct + * LHS evaluation ordering, see test-dev-assign-eval-order*.js. + * We must make sure that the LHS target slot (base object and + * key) don't change during RHS evaluation. The only concrete + * problem is a register reference to a variable-bound register + * (i.e., non-temp). Require temp regs for both key and base. + * + * Don't allow a constant for the object (even for a number + * etc), as it goes into the 'A' field of the opcode. + */ + + reg_obj = + duk__ispec_toregconst_raw(comp_ctx, &left->x1, -1 /*forced_reg*/, + DUK__IVAL_FLAG_REQUIRE_TEMP /*flags*/); + + rc_key = duk__ispec_toregconst_raw( + comp_ctx, &left->x2, -1 /*forced_reg*/, + DUK__IVAL_FLAG_REQUIRE_TEMP | DUK__IVAL_FLAG_ALLOW_CONST /*flags*/); + + /* Evaluate RHS only when LHS is safe. */ + + if (args_op == DUK_OP_NONE) { + duk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/); + DUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST); + rc_res = res->x1.regconst; + } else { + reg_temp = DUK__ALLOCTEMP(comp_ctx); + duk__emit_a_b_c(comp_ctx, DUK_OP_GETPROP | DUK__EMIT_FLAG_BC_REGCONST, + reg_temp, reg_obj, rc_key); + + duk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/); + DUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST); + + duk__emit_a_b_c(comp_ctx, args_op | DUK__EMIT_FLAG_BC_REGCONST, + reg_temp, reg_temp, res->x1.regconst); + rc_res = reg_temp; + } + + duk__emit_a_b_c(comp_ctx, + DUK_OP_PUTPROP | DUK__EMIT_FLAG_A_IS_SOURCE | + DUK__EMIT_FLAG_BC_REGCONST, + reg_obj, rc_key, rc_res); + + duk__ivalue_regconst(res, rc_res); + } else { + /* No support for lvalues returned from new or function call expressions. + * However, these must NOT cause compile-time SyntaxErrors, but run-time + * ReferenceErrors. Both left and right sides of the assignment must be + * evaluated before throwing a ReferenceError. For instance: + * + * f() = g(); + * + * must result in f() being evaluated, then g() being evaluated, and + * finally, a ReferenceError being thrown. See E5 Section 11.13.1. + */ + + duk_regconst_t rc_res; + + /* First evaluate LHS fully to ensure all side effects are out. */ + duk__ivalue_toplain_ignore(comp_ctx, left); + + /* Then evaluate RHS fully (its value becomes the expression value too). + * Technically we'd need the side effect safety check here too, but + * because we always throw using INVLHS the result doesn't matter. + */ + rc_res = duk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/); + + duk__emit_op_only(comp_ctx, DUK_OP_INVLHS); + + duk__ivalue_regconst(res, rc_res); + } + + return; + } + +postincdec : { + /* + * Post-increment/decrement will return the original value as its + * result value. However, even that value will be coerced using + * ToNumber() which is quite awkward. Specific bytecode opcodes + * are used to handle these semantics. + * + * Note that post increment/decrement has a "no LineTerminator here" + * restriction. This is handled by duk__expr_lbp(), which forcibly + * terminates the previous expression if a LineTerminator occurs before + * '++'/'--'. + */ + + duk_regconst_t reg_res; + duk_small_uint_t args_op1 = + (args >> 8) & 0xff; /* DUK_OP_POSTINCR/DUK_OP_POSTDECR */ + duk_small_uint_t args_op2 = + args >> 16; /* DUK_OP_POSTINCP_RR/DUK_OP_POSTDECP_RR */ + + /* Specific assumptions for opcode numbering. */ + DUK_ASSERT(DUK_OP_POSTINCR + 4 == DUK_OP_POSTINCV); + DUK_ASSERT(DUK_OP_POSTDECR + 4 == DUK_OP_POSTDECV); + + reg_res = DUK__ALLOCTEMP(comp_ctx); + + if (left->t == DUK_IVAL_VAR) { + duk_hstring *h_varname; + duk_regconst_t reg_varbind; + duk_regconst_t rc_varname; + + h_varname = duk_known_hstring(thr, left->x1.valstack_idx); + + if (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) { + goto syntax_error; + } + + duk_dup(thr, left->x1.valstack_idx); + if (duk__lookup_lhs(comp_ctx, ®_varbind, &rc_varname)) { + duk__emit_a_bc(comp_ctx, args_op1, /* e.g. DUK_OP_POSTINCR */ + reg_res, reg_varbind); + } else { + duk__emit_a_bc(comp_ctx, args_op1 + 4, /* e.g. DUK_OP_POSTINCV */ + reg_res, rc_varname); + } + + DUK_DDD(DUK_DDDPRINT( + "postincdec to '%!O' -> reg_varbind=%ld, rc_varname=%ld", + (duk_heaphdr *)h_varname, (long)reg_varbind, (long)rc_varname)); + } else if (left->t == DUK_IVAL_PROP) { + duk_regconst_t reg_obj; /* allocate to reg only (not const) */ + duk_regconst_t rc_key; + + reg_obj = duk__ispec_toregconst_raw(comp_ctx, &left->x1, -1 /*forced_reg*/, + 0 /*flags*/); /* don't allow const */ + rc_key = duk__ispec_toregconst_raw(comp_ctx, &left->x2, -1 /*forced_reg*/, + DUK__IVAL_FLAG_ALLOW_CONST /*flags*/); + duk__emit_a_b_c( + comp_ctx, + args_op2 | DUK__EMIT_FLAG_BC_REGCONST, /* e.g. DUK_OP_POSTINCP */ + reg_res, reg_obj, rc_key); + } else { + /* Technically return value is not needed because INVLHS will + * unconditially throw a ReferenceError. Coercion is necessary + * for proper semantics (consider ToNumber() called for an object). + * Use DUK_OP_UNP with a dummy register to get ToNumber(). + */ + duk__ivalue_toforcedreg(comp_ctx, left, reg_res); + duk__emit_bc(comp_ctx, DUK_OP_UNP, + reg_res); /* for side effects, result ignored */ + duk__emit_op_only(comp_ctx, DUK_OP_INVLHS); + } + + DUK__SETTEMP(comp_ctx, reg_res + 1); + duk__ivalue_regconst(res, reg_res); + return; +} + +syntax_error: + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_EXPRESSION); + DUK_WO_NORETURN(return;); + +syntax_error_lvalue: + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LVALUE); + DUK_WO_NORETURN(return;); +} + +DUK_LOCAL duk_small_uint_t duk__expr_lbp(duk_compiler_ctx *comp_ctx) { + duk_small_uint_t tok = comp_ctx->curr_token.t; + + DUK_ASSERT_DISABLE(tok >= DUK_TOK_MINVAL); /* unsigned */ + DUK_ASSERT(tok <= DUK_TOK_MAXVAL); + DUK_ASSERT(sizeof(duk__token_lbp) == DUK_TOK_MAXVAL + 1); + + /* XXX: integrate support for this into led() instead? + * Similar issue as post-increment/post-decrement. + */ + + /* prevent duk__expr_led() by using a binding power less than anything valid + */ + if (tok == DUK_TOK_IN && !comp_ctx->curr_func.allow_in) { + return 0; + } + + if ((tok == DUK_TOK_DECREMENT || tok == DUK_TOK_INCREMENT) && + (comp_ctx->curr_token.lineterm)) { + /* '++' or '--' in a post-increment/decrement position, + * and a LineTerminator occurs between the operator and + * the preceding expression. Force the previous expr + * to terminate, in effect treating e.g. "a,b\n++" as + * "a,b;++" (= SyntaxError). + */ + return 0; + } + + return DUK__TOKEN_LBP_GET_BP(duk__token_lbp[tok]); /* format is bit packed */ +} + +/* + * Expression parsing. + * + * Upon entry to 'expr' and its variants, 'curr_tok' is assumed to be the + * first token of the expression. Upon exit, 'curr_tok' will be the first + * token not part of the expression (e.g. semicolon terminating an expression + * statement). + */ + +#define DUK__EXPR_RBP_MASK 0xff +#define DUK__EXPR_FLAG_REJECT_IN \ + (1u << 8) /* reject 'in' token (used for for-in) */ +#define DUK__EXPR_FLAG_ALLOW_EMPTY (1u << 9) /* allow empty expression */ +#define DUK__EXPR_FLAG_REQUIRE_INIT \ + (1u << 10) /* require initializer for var/const */ + +/* main expression parser function */ +DUK_LOCAL void duk__expr(duk_compiler_ctx *comp_ctx, duk_ivalue *res, + duk_small_uint_t rbp_flags) { + duk_hthread *thr = comp_ctx->thr; + duk_ivalue tmp_alloc; /* 'res' is used for "left", and 'tmp' for "right" */ + duk_ivalue *tmp = &tmp_alloc; + duk_small_uint_t rbp; + + DUK__RECURSION_INCREASE(comp_ctx, thr); + + duk_require_stack(thr, DUK__PARSE_EXPR_SLOTS); + + /* filter out flags from exprtop rbp_flags here to save space */ + rbp = rbp_flags & DUK__EXPR_RBP_MASK; + + DUK_DDD(DUK_DDDPRINT( + "duk__expr(), rbp_flags=%ld, rbp=%ld, allow_in=%ld, paren_level=%ld", + (long)rbp_flags, (long)rbp, (long)comp_ctx->curr_func.allow_in, + (long)comp_ctx->curr_func.paren_level)); + + duk_memzero(&tmp_alloc, sizeof(tmp_alloc)); + tmp->x1.valstack_idx = duk_get_top(thr); + tmp->x2.valstack_idx = tmp->x1.valstack_idx + 1; + duk_push_undefined(thr); + duk_push_undefined(thr); + + /* XXX: where to release temp regs in intermediate expressions? + * e.g. 1+2+3 -> don't inflate temp register count when parsing this. + * that particular expression temp regs can be forced here. + */ + + /* XXX: increase ctx->expr_tokens here for every consumed token + * (this would be a nice statistic)? + */ + + if (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON || + comp_ctx->curr_token.t == DUK_TOK_RPAREN) { + /* XXX: possibly incorrect handling of empty expression */ + DUK_DDD(DUK_DDDPRINT("empty expression")); + if (!(rbp_flags & DUK__EXPR_FLAG_ALLOW_EMPTY)) { + DUK_ERROR_SYNTAX(thr, DUK_STR_EMPTY_EXPR_NOT_ALLOWED); + DUK_WO_NORETURN(return;); + } + duk_push_undefined(thr); + duk__ivalue_plain_fromstack(comp_ctx, res); + goto cleanup; + } + + duk__advance(comp_ctx); + duk__expr_nud(comp_ctx, res); /* reuse 'res' as 'left' */ + while (rbp < duk__expr_lbp(comp_ctx)) { + duk__advance(comp_ctx); + duk__expr_led(comp_ctx, res, tmp); + duk__copy_ivalue(comp_ctx, tmp, res); /* tmp -> res */ + } + +cleanup: + /* final result is already in 'res' */ + + duk_pop_2(thr); + + DUK__RECURSION_DECREASE(comp_ctx, thr); +} + +DUK_LOCAL void duk__exprtop(duk_compiler_ctx *comp_ctx, duk_ivalue *res, + duk_small_uint_t rbp_flags) { + duk_hthread *thr = comp_ctx->thr; + + /* Note: these variables must reside in 'curr_func' instead of the global + * context: when parsing function expressions, expression parsing is nested. + */ + comp_ctx->curr_func.nud_count = 0; + comp_ctx->curr_func.led_count = 0; + comp_ctx->curr_func.paren_level = 0; + comp_ctx->curr_func.expr_lhs = 1; + comp_ctx->curr_func.allow_in = (rbp_flags & DUK__EXPR_FLAG_REJECT_IN ? 0 : 1); + + duk__expr(comp_ctx, res, rbp_flags); + + if (!(rbp_flags & DUK__EXPR_FLAG_ALLOW_EMPTY) && + duk__expr_is_empty(comp_ctx)) { + DUK_ERROR_SYNTAX(thr, DUK_STR_EMPTY_EXPR_NOT_ALLOWED); + DUK_WO_NORETURN(return;); + } +} + +/* A bunch of helpers (for size optimization) that combine + * duk__expr()/duk__exprtop() and result conversions. + * + * Each helper needs at least 2-3 calls to make it worth while to wrap. + */ + +#if 0 /* unused */ +DUK_LOCAL duk_regconst_t duk__expr_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) { + duk__expr(comp_ctx, res, rbp_flags); + return duk__ivalue_toreg(comp_ctx, res); +} +#endif + +#if 0 /* unused */ +DUK_LOCAL duk_regconst_t duk__expr_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) { + duk__expr(comp_ctx, res, rbp_flags); + return duk__ivalue_totemp(comp_ctx, res); +} +#endif + +DUK_LOCAL void duk__expr_toforcedreg(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_small_uint_t rbp_flags, + duk_regconst_t forced_reg) { + DUK_ASSERT(forced_reg >= 0); + duk__expr(comp_ctx, res, rbp_flags); + duk__ivalue_toforcedreg(comp_ctx, res, forced_reg); +} + +DUK_LOCAL duk_regconst_t duk__expr_toregconst(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_small_uint_t rbp_flags) { + duk__expr(comp_ctx, res, rbp_flags); + return duk__ivalue_toregconst(comp_ctx, res); +} + +#if 0 /* unused */ +DUK_LOCAL duk_regconst_t duk__expr_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) { + duk__expr(comp_ctx, res, rbp_flags); + return duk__ivalue_totempconst(comp_ctx, res); +} +#endif + +DUK_LOCAL void duk__expr_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *res, + duk_small_uint_t rbp_flags) { + duk__expr(comp_ctx, res, rbp_flags); + duk__ivalue_toplain(comp_ctx, res); +} + +DUK_LOCAL void duk__expr_toplain_ignore(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_small_uint_t rbp_flags) { + duk__expr(comp_ctx, res, rbp_flags); + duk__ivalue_toplain_ignore(comp_ctx, res); +} + +DUK_LOCAL duk_regconst_t duk__exprtop_toreg(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_small_uint_t rbp_flags) { + duk__exprtop(comp_ctx, res, rbp_flags); + return duk__ivalue_toreg(comp_ctx, res); +} + +#if 0 /* unused */ +DUK_LOCAL duk_regconst_t duk__exprtop_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) { + duk__exprtop(comp_ctx, res, rbp_flags); + return duk__ivalue_totemp(comp_ctx, res); +} +#endif + +DUK_LOCAL void duk__exprtop_toforcedreg(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_small_uint_t rbp_flags, + duk_regconst_t forced_reg) { + DUK_ASSERT(forced_reg >= 0); + duk__exprtop(comp_ctx, res, rbp_flags); + duk__ivalue_toforcedreg(comp_ctx, res, forced_reg); +} + +DUK_LOCAL duk_regconst_t duk__exprtop_toregconst(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_small_uint_t rbp_flags) { + duk__exprtop(comp_ctx, res, rbp_flags); + return duk__ivalue_toregconst(comp_ctx, res); +} + +#if 0 /* unused */ +DUK_LOCAL void duk__exprtop_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, int rbp_flags) { + duk__exprtop(comp_ctx, res, rbp_flags); + duk__ivalue_toplain_ignore(comp_ctx, res); +} +#endif + +/* + * Parse an individual source element (top level statement) or a statement. + * + * Handles labeled statements automatically (peeling away labels before + * parsing an expression that follows the label(s)). + * + * Upon entry, 'curr_tok' contains the first token of the statement (parsed + * in "allow regexp literal" mode). Upon exit, 'curr_tok' contains the first + * token following the statement (if the statement has a terminator, this is + * the token after the terminator). + */ + +#define DUK__HAS_VAL (1u << 0) /* stmt has non-empty value */ +#define DUK__HAS_TERM \ + (1u << 1) /* stmt has explicit/implicit semicolon terminator */ +#define DUK__ALLOW_AUTO_SEMI_ALWAYS \ + (1u << 2) /* allow automatic semicolon even without lineterm (compatibility) \ + */ +#define DUK__STILL_PROLOGUE \ + (1u << 3) /* statement does not terminate directive prologue */ +#define DUK__IS_TERMINAL \ + (1u << 4) /* statement is guaranteed to be terminal (control doesn't flow to \ + next statement) */ + +/* Parse a single variable declaration (e.g. "i" or "i=10"). A leading 'var' + * has already been eaten. These is no return value in 'res', it is used only + * as a temporary. + * + * When called from 'for-in' statement parser, the initializer expression must + * not allow the 'in' token. The caller supply additional expression parsing + * flags (like DUK__EXPR_FLAG_REJECT_IN) in 'expr_flags'. + * + * Finally, out_rc_varname and out_reg_varbind are updated to reflect where + * the identifier is bound: + * + * If register bound: out_reg_varbind >= 0, out_rc_varname == 0 (ignore) + * If not register bound: out_reg_varbind < 0, out_rc_varname >= 0 + * + * These allow the caller to use the variable for further assignment, e.g. + * as is done in 'for-in' parsing. + */ + +DUK_LOCAL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res, + duk_small_uint_t expr_flags, + duk_regconst_t *out_reg_varbind, + duk_regconst_t *out_rc_varname) { + duk_hthread *thr = comp_ctx->thr; + duk_hstring *h_varname; + duk_regconst_t reg_varbind; + duk_regconst_t rc_varname; + + /* assume 'var' has been eaten */ + + /* Note: Identifier rejects reserved words */ + if (comp_ctx->curr_token.t != DUK_TOK_IDENTIFIER) { + goto syntax_error; + } + h_varname = comp_ctx->curr_token.str1; + + DUK_ASSERT(h_varname != NULL); + + /* strict mode restrictions (E5 Section 12.2.1) */ + if (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) { + goto syntax_error; + } + + /* register declarations in first pass */ + if (comp_ctx->curr_func.in_scanning) { + duk_uarridx_t n; + DUK_DDD(DUK_DDDPRINT("register variable declaration %!O in pass 1", + (duk_heaphdr *)h_varname)); + n = (duk_uarridx_t)duk_get_length(thr, comp_ctx->curr_func.decls_idx); + duk_push_hstring(thr, h_varname); + duk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n); + duk_push_int(thr, DUK_DECL_TYPE_VAR + (0 << 8)); + duk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n + 1); + } + + duk_push_hstring(thr, + h_varname); /* push before advancing to keep reachable */ + + /* register binding lookup is based on varmap (even in first pass) */ + duk_dup_top(thr); + (void)duk__lookup_lhs(comp_ctx, ®_varbind, &rc_varname); + + duk__advance(comp_ctx); /* eat identifier */ + + if (comp_ctx->curr_token.t == DUK_TOK_EQUALSIGN) { + duk__advance(comp_ctx); + + DUK_DDD(DUK_DDDPRINT( + "vardecl, assign to '%!O' -> reg_varbind=%ld, rc_varname=%ld", + (duk_heaphdr *)h_varname, (long)reg_varbind, (long)rc_varname)); + + duk__exprtop( + comp_ctx, res, + DUK__BP_COMMA | expr_flags /*rbp_flags*/); /* AssignmentExpression */ + + if (reg_varbind >= 0) { + duk__ivalue_toforcedreg(comp_ctx, res, reg_varbind); + } else { + duk_regconst_t reg_val; + reg_val = duk__ivalue_toreg(comp_ctx, res); + duk__emit_a_bc(comp_ctx, DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE, + reg_val, rc_varname); + } + } else { + if (expr_flags & DUK__EXPR_FLAG_REQUIRE_INIT) { + /* Used for minimal 'const': initializer required. */ + goto syntax_error; + } + } + + duk_pop(thr); /* pop varname */ + + *out_rc_varname = rc_varname; + *out_reg_varbind = reg_varbind; + + return; + +syntax_error: + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_VAR_DECLARATION); + DUK_WO_NORETURN(return;); +} + +DUK_LOCAL void duk__parse_var_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, + duk_small_uint_t expr_flags) { + duk_regconst_t reg_varbind; + duk_regconst_t rc_varname; + + duk__advance(comp_ctx); /* eat 'var' */ + + for (;;) { + /* rc_varname and reg_varbind are ignored here */ + duk__parse_var_decl(comp_ctx, res, 0 | expr_flags, ®_varbind, + &rc_varname); + + if (comp_ctx->curr_token.t != DUK_TOK_COMMA) { + break; + } + duk__advance(comp_ctx); + } +} + +DUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, + duk_int_t pc_label_site) { + duk_hthread *thr = comp_ctx->thr; + duk_int_t pc_v34_lhs; /* start variant 3/4 left-hand-side code (L1 in + doc/compiler.rst example) */ + duk_regconst_t + temp_reset; /* knock back "next temp" to this whenever possible */ + duk_regconst_t + reg_temps; /* preallocated temporaries (2) for variants 3 and 4 */ + + DUK_DDD(DUK_DDDPRINT("start parsing a for/for-in statement")); + + /* Two temporaries are preallocated here for variants 3 and 4 which need + * registers which are never clobbered by expressions in the loop + * (concretely: for the enumerator object and the next enumerated value). + * Variants 1 and 2 "release" these temps. + */ + + reg_temps = DUK__ALLOCTEMPS(comp_ctx, 2); + + temp_reset = DUK__GETTEMP(comp_ctx); + + /* + * For/for-in main variants are: + * + * 1. for (ExpressionNoIn_opt; Expression_opt; Expression_opt) Statement + * 2. for (var VariableDeclarationNoIn; Expression_opt; Expression_opt) + * Statement + * 3. for (LeftHandSideExpression in Expression) Statement + * 4. for (var VariableDeclarationNoIn in Expression) Statement + * + * Parsing these without arbitrary lookahead or backtracking is relatively + * tricky but we manage to do so for now. + * + * See doc/compiler.rst for a detailed discussion of control flow + * issues, evaluation order issues, etc. + */ + + duk__advance(comp_ctx); /* eat 'for' */ + duk__advance_expect(comp_ctx, DUK_TOK_LPAREN); + + DUK_DDD(DUK_DDDPRINT("detecting for/for-in loop variant, pc=%ld", + (long)duk__get_current_pc(comp_ctx))); + + /* a label site has been emitted by duk__parse_stmt() automatically + * (it will also emit the ENDLABEL). + */ + + if (comp_ctx->curr_token.t == DUK_TOK_VAR) { + /* + * Variant 2 or 4 + */ + + duk_regconst_t reg_varbind; /* variable binding register if register-bound + (otherwise < 0) */ + duk_regconst_t rc_varname; /* variable name reg/const, if variable not + register-bound */ + + duk__advance(comp_ctx); /* eat 'var' */ + duk__parse_var_decl(comp_ctx, res, DUK__EXPR_FLAG_REJECT_IN, ®_varbind, + &rc_varname); + DUK__SETTEMP(comp_ctx, temp_reset); + + if (comp_ctx->curr_token.t == DUK_TOK_IN) { + /* + * Variant 4 + */ + + DUK_DDD(DUK_DDDPRINT("detected for variant 4: for (var " + "VariableDeclarationNoIn in Expression) Statement")); + pc_v34_lhs = duk__get_current_pc(comp_ctx); /* jump is inserted here */ + if (reg_varbind >= 0) { + duk__emit_a_bc(comp_ctx, DUK_OP_LDREG, reg_varbind, reg_temps + 0); + } else { + duk__emit_a_bc(comp_ctx, DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE, + reg_temps + 0, rc_varname); + } + goto parse_3_or_4; + } else { + /* + * Variant 2 + */ + + DUK_DDD(DUK_DDDPRINT( + "detected for variant 2: for (var VariableDeclarationNoIn; " + "Expression_opt; Expression_opt) Statement")); + for (;;) { + /* more initializers */ + if (comp_ctx->curr_token.t != DUK_TOK_COMMA) { + break; + } + DUK_DDD(DUK_DDDPRINT("variant 2 has another variable initializer")); + + duk__advance(comp_ctx); /* eat comma */ + duk__parse_var_decl(comp_ctx, res, DUK__EXPR_FLAG_REJECT_IN, + ®_varbind, &rc_varname); + } + goto parse_1_or_2; + } + } else { + /* + * Variant 1 or 3 + */ + + pc_v34_lhs = + duk__get_current_pc(comp_ctx); /* jump is inserted here (variant 3) */ + + /* Note that duk__exprtop() here can clobber any reg above current + * temp_next, so any loop variables (e.g. enumerator) must be + * "preallocated". + */ + + /* don't coerce yet to a plain value (variant 3 needs special handling) */ + duk__exprtop(comp_ctx, res, + DUK__BP_FOR_EXPR | DUK__EXPR_FLAG_REJECT_IN | + DUK__EXPR_FLAG_ALLOW_EMPTY /*rbp_flags*/); /* Expression */ + if (comp_ctx->curr_token.t == DUK_TOK_IN) { + /* + * Variant 3 + */ + + /* XXX: need to determine LHS type, and check that it is LHS compatible */ + DUK_DDD( + DUK_DDDPRINT("detected for variant 3: for (LeftHandSideExpression in " + "Expression) Statement")); + if (duk__expr_is_empty(comp_ctx)) { + goto syntax_error; /* LeftHandSideExpression does not allow empty + expression */ + } + + if (res->t == DUK_IVAL_VAR) { + duk_regconst_t reg_varbind; + duk_regconst_t rc_varname; + + duk_dup(thr, res->x1.valstack_idx); + if (duk__lookup_lhs(comp_ctx, ®_varbind, &rc_varname)) { + duk__emit_a_bc(comp_ctx, DUK_OP_LDREG, reg_varbind, reg_temps + 0); + } else { + duk__emit_a_bc(comp_ctx, DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE, + reg_temps + 0, rc_varname); + } + } else if (res->t == DUK_IVAL_PROP) { + /* Don't allow a constant for the object (even for a number etc), as + * it goes into the 'A' field of the opcode. + */ + duk_regconst_t reg_obj; + duk_regconst_t rc_key; + reg_obj = + duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, + 0 /*flags*/); /* don't allow const */ + rc_key = + duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, + DUK__IVAL_FLAG_ALLOW_CONST /*flags*/); + duk__emit_a_b_c(comp_ctx, + DUK_OP_PUTPROP | DUK__EMIT_FLAG_A_IS_SOURCE | + DUK__EMIT_FLAG_BC_REGCONST, + reg_obj, rc_key, reg_temps + 0); + } else { + duk__ivalue_toplain_ignore(comp_ctx, res); /* just in case */ + duk__emit_op_only(comp_ctx, DUK_OP_INVLHS); + } + goto parse_3_or_4; + } else { + /* + * Variant 1 + */ + + DUK_DDD(DUK_DDDPRINT("detected for variant 1: for (ExpressionNoIn_opt; " + "Expression_opt; Expression_opt) Statement")); + duk__ivalue_toplain_ignore(comp_ctx, res); + goto parse_1_or_2; + } + } + +parse_1_or_2: + /* + * Parse variant 1 or 2. The first part expression (which differs + * in the variants) has already been parsed and its code emitted. + * + * reg_temps + 0: unused + * reg_temps + 1: unused + */ + { + duk_regconst_t rc_cond; + duk_int_t pc_l1, pc_l2, pc_l3, pc_l4; + duk_int_t pc_jumpto_l3, pc_jumpto_l4; + duk_bool_t expr_c_empty; + + DUK_DDD(DUK_DDDPRINT("shared code for parsing variants 1 and 2")); + + /* "release" preallocated temps since we won't need them */ + temp_reset = reg_temps + 0; + DUK__SETTEMP(comp_ctx, temp_reset); + + duk__advance_expect(comp_ctx, DUK_TOK_SEMICOLON); + + pc_l1 = duk__get_current_pc(comp_ctx); + duk__exprtop( + comp_ctx, res, + DUK__BP_FOR_EXPR | + DUK__EXPR_FLAG_ALLOW_EMPTY /*rbp_flags*/); /* Expression_opt */ + if (duk__expr_is_empty(comp_ctx)) { + /* no need to coerce */ + pc_jumpto_l3 = duk__emit_jump_empty(comp_ctx); /* to body */ + pc_jumpto_l4 = -1; /* omitted */ + } else { + rc_cond = duk__ivalue_toregconst(comp_ctx, res); + duk__emit_if_false_skip(comp_ctx, rc_cond); + pc_jumpto_l3 = duk__emit_jump_empty(comp_ctx); /* to body */ + pc_jumpto_l4 = duk__emit_jump_empty(comp_ctx); /* to exit */ + } + DUK__SETTEMP(comp_ctx, temp_reset); + + duk__advance_expect(comp_ctx, DUK_TOK_SEMICOLON); + + pc_l2 = duk__get_current_pc(comp_ctx); + duk__exprtop( + comp_ctx, res, + DUK__BP_FOR_EXPR | + DUK__EXPR_FLAG_ALLOW_EMPTY /*rbp_flags*/); /* Expression_opt */ + if (duk__expr_is_empty(comp_ctx)) { + /* no need to coerce */ + expr_c_empty = 1; + /* JUMP L1 omitted */ + } else { + duk__ivalue_toplain_ignore(comp_ctx, res); + expr_c_empty = 0; + duk__emit_jump(comp_ctx, pc_l1); + } + DUK__SETTEMP(comp_ctx, temp_reset); + + comp_ctx->curr_func.allow_regexp_in_adv = 1; + duk__advance_expect( + comp_ctx, DUK_TOK_RPAREN); /* Allow RegExp as part of next stmt. */ + + pc_l3 = duk__get_current_pc(comp_ctx); + duk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/); + if (expr_c_empty) { + duk__emit_jump(comp_ctx, pc_l1); + } else { + duk__emit_jump(comp_ctx, pc_l2); + } + /* temp reset is not necessary after duk__parse_stmt(), which already does + * it */ + + pc_l4 = duk__get_current_pc(comp_ctx); + + DUK_DDD(DUK_DDDPRINT( + "patching jumps: jumpto_l3: %ld->%ld, jumpto_l4: %ld->%ld, " + "break: %ld->%ld, continue: %ld->%ld", + (long)pc_jumpto_l3, (long)pc_l3, (long)pc_jumpto_l4, (long)pc_l4, + (long)(pc_label_site + 1), (long)pc_l4, (long)(pc_label_site + 2), + (long)pc_l2)); + + duk__patch_jump(comp_ctx, pc_jumpto_l3, pc_l3); + duk__patch_jump(comp_ctx, pc_jumpto_l4, pc_l4); + duk__patch_jump(comp_ctx, pc_label_site + 1, pc_l4); /* break jump */ + duk__patch_jump(comp_ctx, pc_label_site + 2, + expr_c_empty ? pc_l1 : pc_l2); /* continue jump */ + } + goto finished; + +parse_3_or_4: + /* + * Parse variant 3 or 4. + * + * For variant 3 (e.g. "for (A in C) D;") the code for A (except the + * final property/variable write) has already been emitted. The first + * instruction of that code is at pc_v34_lhs; a JUMP needs to be inserted + * there to satisfy control flow needs. + * + * For variant 4, if the variable declaration had an initializer + * (e.g. "for (var A = B in C) D;") the code for the assignment + * (B) has already been emitted. + * + * Variables set before entering here: + * + * pc_v34_lhs: insert a "JUMP L2" here (see doc/compiler.rst example). + * reg_temps + 0: iteration target value (written to LHS) + * reg_temps + 1: enumerator object + */ + { + duk_int_t pc_l1, pc_l2, pc_l3, pc_l4, pc_l5; + duk_int_t pc_jumpto_l2, pc_jumpto_l3, pc_jumpto_l4, pc_jumpto_l5; + duk_regconst_t reg_target; + + DUK_DDD( + DUK_DDDPRINT("shared code for parsing variants 3 and 4, pc_v34_lhs=%ld", + (long)pc_v34_lhs)); + + DUK__SETTEMP(comp_ctx, temp_reset); + + /* First we need to insert a jump in the middle of previously + * emitted code to get the control flow right. No jumps can + * cross the position where the jump is inserted. See doc/compiler.rst + * for discussion on the intricacies of control flow and side effects + * for variants 3 and 4. + */ + + duk__insert_jump_entry(comp_ctx, pc_v34_lhs); + pc_jumpto_l2 = pc_v34_lhs; /* inserted jump */ + pc_l1 = pc_v34_lhs + 1; /* +1, right after inserted jump */ + + /* The code for writing reg_temps + 0 to the left hand side has already + * been emitted. + */ + + pc_jumpto_l3 = duk__emit_jump_empty(comp_ctx); /* -> loop body */ + + duk__advance(comp_ctx); /* eat 'in' */ + + /* Parse enumeration target and initialize enumerator. For 'null' and + * 'undefined', INITENUM will creates a 'null' enumerator which works like + * an empty enumerator (E5 Section 12.6.4, step 3). Note that INITENUM + * requires the value to be in a register (constant not allowed). + */ + + pc_l2 = duk__get_current_pc(comp_ctx); + reg_target = duk__exprtop_toreg( + comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/); /* Expression */ + duk__emit_b_c(comp_ctx, DUK_OP_INITENUM | DUK__EMIT_FLAG_B_IS_TARGET, + reg_temps + 1, reg_target); + pc_jumpto_l4 = duk__emit_jump_empty(comp_ctx); + DUK__SETTEMP(comp_ctx, temp_reset); + + comp_ctx->curr_func.allow_regexp_in_adv = 1; + duk__advance_expect( + comp_ctx, DUK_TOK_RPAREN); /* Allow RegExp as part of next stmt. */ + + pc_l3 = duk__get_current_pc(comp_ctx); + duk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/); + /* temp reset is not necessary after duk__parse_stmt(), which already does + * it */ + + /* NEXTENUM needs a jump slot right after the main opcode. + * We need the code emitter to reserve the slot: if there's + * target shuffling, the target shuffle opcodes must happen + * after the jump slot (for NEXTENUM the shuffle opcodes are + * not needed if the enum is finished). + */ + pc_l4 = duk__get_current_pc(comp_ctx); + duk__emit_b_c(comp_ctx, + DUK_OP_NEXTENUM | DUK__EMIT_FLAG_B_IS_TARGET | + DUK__EMIT_FLAG_RESERVE_JUMPSLOT, + reg_temps + 0, reg_temps + 1); + pc_jumpto_l5 = comp_ctx->emit_jumpslot_pc; /* NEXTENUM jump slot: executed + when enum finished */ + duk__emit_jump( + comp_ctx, + pc_l1); /* jump to next loop, using reg_v34_iter as iterated value */ + + pc_l5 = duk__get_current_pc(comp_ctx); + + /* XXX: since the enumerator may be a memory expensive object, + * perhaps clear it explicitly here? If so, break jump must + * go through this clearing operation. + */ + + DUK_DDD(DUK_DDDPRINT( + "patching jumps: jumpto_l2: %ld->%ld, jumpto_l3: %ld->%ld, " + "jumpto_l4: %ld->%ld, jumpto_l5: %ld->%ld, " + "break: %ld->%ld, continue: %ld->%ld", + (long)pc_jumpto_l2, (long)pc_l2, (long)pc_jumpto_l3, (long)pc_l3, + (long)pc_jumpto_l4, (long)pc_l4, (long)pc_jumpto_l5, (long)pc_l5, + (long)(pc_label_site + 1), (long)pc_l5, (long)(pc_label_site + 2), + (long)pc_l4)); + + duk__patch_jump(comp_ctx, pc_jumpto_l2, pc_l2); + duk__patch_jump(comp_ctx, pc_jumpto_l3, pc_l3); + duk__patch_jump(comp_ctx, pc_jumpto_l4, pc_l4); + duk__patch_jump(comp_ctx, pc_jumpto_l5, pc_l5); + duk__patch_jump(comp_ctx, pc_label_site + 1, pc_l5); /* break jump */ + duk__patch_jump(comp_ctx, pc_label_site + 2, pc_l4); /* continue jump */ + } + goto finished; + +finished: + DUK_DDD(DUK_DDDPRINT("end parsing a for/for-in statement")); + return; + +syntax_error: + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_FOR); + DUK_WO_NORETURN(return;); +} + +DUK_LOCAL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, + duk_int_t pc_label_site) { + duk_hthread *thr = comp_ctx->thr; + duk_regconst_t temp_at_loop; + duk_regconst_t rc_switch; /* reg/const for switch value */ + duk_regconst_t rc_case; /* reg/const for case value */ + duk_regconst_t reg_temp; /* general temp register */ + duk_int_t pc_prevcase = -1; + duk_int_t pc_prevstmt = -1; + duk_int_t pc_default = + -1; /* -1 == not set, -2 == pending (next statement list) */ + + /* Note: negative pc values are ignored when patching jumps, so no explicit + * checks needed */ + + /* + * Switch is pretty complicated because of several conflicting concerns: + * + * - Want to generate code without an intermediate representation, + * i.e., in one go + * + * - Case selectors are expressions, not values, and may thus e.g. throw + * exceptions (which causes evaluation order concerns) + * + * - Evaluation semantics of case selectors and default clause need to be + * carefully implemented to provide correct behavior even with case value + * side effects + * + * - Fall through case and default clauses; avoiding dead JUMPs if case + * ends with an unconditional jump (a break or a continue) + * + * - The same case value may occur multiple times, but evaluation rules + * only process the first match before switching to a "propagation" mode + * where case values are no longer evaluated + * + * See E5 Section 12.11. Also see doc/compiler.rst for compilation + * discussion. + */ + + duk__advance(comp_ctx); + duk__advance_expect(comp_ctx, DUK_TOK_LPAREN); + rc_switch = + duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/); + duk__advance_expect(comp_ctx, + DUK_TOK_RPAREN); /* RegExp mode does not matter. */ + duk__advance_expect(comp_ctx, DUK_TOK_LCURLY); + + DUK_DDD(DUK_DDDPRINT("switch value in register %ld", (long)rc_switch)); + + temp_at_loop = DUK__GETTEMP(comp_ctx); + + for (;;) { + duk_int_t num_stmts; + duk_small_uint_t tok; + + /* sufficient for keeping temp reg numbers in check */ + DUK__SETTEMP(comp_ctx, temp_at_loop); + + if (comp_ctx->curr_token.t == DUK_TOK_RCURLY) { + break; + } + + /* + * Parse a case or default clause. + */ + + if (comp_ctx->curr_token.t == DUK_TOK_CASE) { + /* + * Case clause. + * + * Note: cannot use reg_case as a temp register (for SEQ target) + * because it may be a constant. + */ + + duk__patch_jump_here(comp_ctx, pc_prevcase); /* chain jumps for case + * evaluation and checking + */ + + duk__advance(comp_ctx); + rc_case = duk__exprtop_toregconst(comp_ctx, res, + DUK__BP_FOR_EXPR /*rbp_flags*/); + duk__advance_expect(comp_ctx, DUK_TOK_COLON); + + reg_temp = DUK__ALLOCTEMP(comp_ctx); + duk__emit_a_b_c(comp_ctx, DUK_OP_SEQ | DUK__EMIT_FLAG_BC_REGCONST, + reg_temp, rc_switch, rc_case); + duk__emit_if_true_skip(comp_ctx, reg_temp); + + /* jump to next case clause */ + pc_prevcase = duk__emit_jump_empty(comp_ctx); /* no match, next case */ + + /* statements go here (if any) on next loop */ + } else if (comp_ctx->curr_token.t == DUK_TOK_DEFAULT) { + /* + * Default clause. + */ + + if (pc_default >= 0) { + goto syntax_error; + } + duk__advance(comp_ctx); + duk__advance_expect(comp_ctx, DUK_TOK_COLON); + + /* Fix for https://github.com/svaarala/duktape/issues/155: + * If 'default' is first clause (detected by pc_prevcase < 0) + * we need to ensure we stay in the matching chain. + */ + if (pc_prevcase < 0) { + DUK_DD(DUK_DDPRINT("default clause is first, emit prevcase jump")); + pc_prevcase = duk__emit_jump_empty(comp_ctx); + } + + /* default clause matches next statement list (if any) */ + pc_default = -2; + } else { + /* Code is not accepted before the first case/default clause */ + goto syntax_error; + } + + /* + * Parse code after the clause. Possible terminators are + * 'case', 'default', and '}'. + * + * Note that there may be no code at all, not even an empty statement, + * between case clauses. This must be handled just like an empty statement + * (omitting seemingly pointless JUMPs), to avoid situations like + * test-bug-case-fallthrough.js. + */ + + num_stmts = 0; + if (pc_default == -2) { + pc_default = duk__get_current_pc(comp_ctx); + } + + /* Note: this is correct even for default clause statements: + * they participate in 'fall-through' behavior even if the + * default clause is in the middle. + */ + duk__patch_jump_here(comp_ctx, + pc_prevstmt); /* chain jumps for 'fall-through' + * after a case matches. + */ + + for (;;) { + tok = comp_ctx->curr_token.t; + if (tok == DUK_TOK_CASE || tok == DUK_TOK_DEFAULT || + tok == DUK_TOK_RCURLY) { + break; + } + num_stmts++; + duk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/); + } + + /* fall-through jump to next code of next case (backpatched) */ + pc_prevstmt = duk__emit_jump_empty(comp_ctx); + + /* XXX: would be nice to omit this jump when the jump is not + * reachable, at least in the obvious cases (such as the case + * ending with a 'break'. + * + * Perhaps duk__parse_stmt() could provide some info on whether + * the statement is a "dead end"? + * + * If implemented, just set pc_prevstmt to -1 when not needed. + */ + } + + DUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RCURLY); + comp_ctx->curr_func.allow_regexp_in_adv = 1; + duk__advance(comp_ctx); /* Allow RegExp as part of next stmt. */ + + /* default case control flow patchup; note that if pc_prevcase < 0 + * (i.e. no case clauses), control enters default case automatically. + */ + if (pc_default >= 0) { + /* default case exists: go there if no case matches */ + duk__patch_jump(comp_ctx, pc_prevcase, pc_default); + } else { + /* default case does not exist, or no statements present + * after default case: finish case evaluation + */ + duk__patch_jump_here(comp_ctx, pc_prevcase); + } + + /* fall-through control flow patchup; note that pc_prevstmt may be + * < 0 (i.e. no case clauses), in which case this is a no-op. + */ + duk__patch_jump_here(comp_ctx, pc_prevstmt); + + /* continue jump not patched, an INVALID opcode remains there */ + duk__patch_jump_here(comp_ctx, pc_label_site + 1); /* break jump */ + + /* Note: 'fast' breaks will jump to pc_label_site + 1, which will + * then jump here. The double jump will be eliminated by a + * peephole pass, resulting in an optimal jump here. The label + * site jumps will remain in bytecode and will waste code size. + */ + + return; + +syntax_error: + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_SWITCH); + DUK_WO_NORETURN(return;); +} + +DUK_LOCAL void duk__parse_if_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) { + duk_regconst_t temp_reset; + duk_regconst_t rc_cond; + duk_int_t pc_jump_false; + + DUK_DDD(DUK_DDDPRINT("begin parsing if statement")); + + temp_reset = DUK__GETTEMP(comp_ctx); + + duk__advance(comp_ctx); /* eat 'if' */ + duk__advance_expect(comp_ctx, DUK_TOK_LPAREN); + + rc_cond = + duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/); + duk__emit_if_true_skip(comp_ctx, rc_cond); + pc_jump_false = duk__emit_jump_empty(comp_ctx); /* jump to end or else part */ + DUK__SETTEMP(comp_ctx, temp_reset); + + comp_ctx->curr_func.allow_regexp_in_adv = 1; + duk__advance_expect(comp_ctx, + DUK_TOK_RPAREN); /* Allow RegExp as part of next stmt. */ + + duk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/); + + /* The 'else' ambiguity is resolved by 'else' binding to the innermost + * construct, so greedy matching is correct here. + */ + + if (comp_ctx->curr_token.t == DUK_TOK_ELSE) { + duk_int_t pc_jump_end; + + DUK_DDD(DUK_DDDPRINT("if has else part")); + + duk__advance(comp_ctx); + + pc_jump_end = + duk__emit_jump_empty(comp_ctx); /* jump from true part to end */ + duk__patch_jump_here(comp_ctx, pc_jump_false); + + duk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/); + + duk__patch_jump_here(comp_ctx, pc_jump_end); + } else { + DUK_DDD(DUK_DDDPRINT("if does not have else part")); + + duk__patch_jump_here(comp_ctx, pc_jump_false); + } + + DUK_DDD(DUK_DDDPRINT("end parsing if statement")); +} + +DUK_LOCAL void duk__parse_do_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, + duk_int_t pc_label_site) { + duk_regconst_t rc_cond; + duk_int_t pc_start; + + DUK_DDD(DUK_DDDPRINT("begin parsing do statement")); + + duk__advance(comp_ctx); /* Eat 'do'; allow RegExp as part of next stmt. */ + + pc_start = duk__get_current_pc(comp_ctx); + duk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/); + duk__patch_jump_here(comp_ctx, pc_label_site + 2); /* continue jump */ + + duk__advance_expect(comp_ctx, DUK_TOK_WHILE); + duk__advance_expect(comp_ctx, DUK_TOK_LPAREN); + + rc_cond = + duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/); + duk__emit_if_false_skip(comp_ctx, rc_cond); + duk__emit_jump(comp_ctx, pc_start); + /* no need to reset temps, as we're finished emitting code */ + + comp_ctx->curr_func.allow_regexp_in_adv = + 1; /* Allow RegExp as part of next stmt. */ + duk__advance_expect(comp_ctx, DUK_TOK_RPAREN); + + duk__patch_jump_here(comp_ctx, pc_label_site + 1); /* break jump */ + + DUK_DDD(DUK_DDDPRINT("end parsing do statement")); +} + +DUK_LOCAL void duk__parse_while_stmt(duk_compiler_ctx *comp_ctx, + duk_ivalue *res, duk_int_t pc_label_site) { + duk_regconst_t temp_reset; + duk_regconst_t rc_cond; + duk_int_t pc_start; + duk_int_t pc_jump_false; + + DUK_DDD(DUK_DDDPRINT("begin parsing while statement")); + + temp_reset = DUK__GETTEMP(comp_ctx); + + duk__advance(comp_ctx); /* eat 'while' */ + + duk__advance_expect(comp_ctx, DUK_TOK_LPAREN); + + pc_start = duk__get_current_pc(comp_ctx); + duk__patch_jump_here(comp_ctx, pc_label_site + 2); /* continue jump */ + + rc_cond = + duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/); + duk__emit_if_true_skip(comp_ctx, rc_cond); + pc_jump_false = duk__emit_jump_empty(comp_ctx); + DUK__SETTEMP(comp_ctx, temp_reset); + + comp_ctx->curr_func.allow_regexp_in_adv = 1; + duk__advance_expect(comp_ctx, + DUK_TOK_RPAREN); /* Allow RegExp as part of next stmt. */ + + duk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/); + duk__emit_jump(comp_ctx, pc_start); + + duk__patch_jump_here(comp_ctx, pc_jump_false); + duk__patch_jump_here(comp_ctx, pc_label_site + 1); /* break jump */ + + DUK_DDD(DUK_DDDPRINT("end parsing while statement")); +} + +DUK_LOCAL void duk__parse_break_or_continue_stmt(duk_compiler_ctx *comp_ctx, + duk_ivalue *res) { + duk_hthread *thr = comp_ctx->thr; + duk_bool_t is_break = (comp_ctx->curr_token.t == DUK_TOK_BREAK); + duk_int_t label_id; + duk_int_t label_catch_depth; + duk_int_t label_pc; /* points to LABEL; pc+1 = jump site for break; pc+2 = + jump site for continue */ + duk_bool_t label_is_closest; + + DUK_UNREF(res); + + label_pc = 0; + label_id = 0; + label_catch_depth = 0; + label_is_closest = 0; + + duk__advance(comp_ctx); /* eat 'break' or 'continue' */ + + if (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON || /* explicit semi follows */ + comp_ctx->curr_token.lineterm || /* automatic semi will be inserted */ + comp_ctx->curr_token + .allow_auto_semi) { /* automatic semi will be inserted */ + /* break/continue without label */ + + duk__lookup_active_label(comp_ctx, DUK_HTHREAD_STRING_EMPTY_STRING(thr), + is_break, &label_id, &label_catch_depth, &label_pc, + &label_is_closest); + } else if (comp_ctx->curr_token.t == DUK_TOK_IDENTIFIER) { + /* break/continue with label (label cannot be a reserved word, production is + * 'Identifier' */ + DUK_ASSERT(comp_ctx->curr_token.str1 != NULL); + duk__lookup_active_label(comp_ctx, comp_ctx->curr_token.str1, is_break, + &label_id, &label_catch_depth, &label_pc, + &label_is_closest); + duk__advance(comp_ctx); + } else { + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_BREAK_CONT_LABEL); + DUK_WO_NORETURN(return;); + } + + /* Use a fast break/continue when possible. A fast break/continue is + * just a jump to the LABEL break/continue jump slot, which then jumps + * to an appropriate place (for break, going through ENDLABEL correctly). + * The peephole optimizer will optimize the jump to a direct one. + */ + + if (label_catch_depth == comp_ctx->curr_func.catch_depth && + label_is_closest) { + DUK_DDD(DUK_DDDPRINT( + "break/continue: is_break=%ld, label_id=%ld, label_is_closest=%ld, " + "label_catch_depth=%ld, catch_depth=%ld " + "-> use fast variant (direct jump)", + (long)is_break, (long)label_id, (long)label_is_closest, + (long)label_catch_depth, (long)comp_ctx->curr_func.catch_depth)); + + duk__emit_jump(comp_ctx, label_pc + (is_break ? 1 : 2)); + } else { + DUK_DDD(DUK_DDDPRINT( + "break/continue: is_break=%ld, label_id=%ld, label_is_closest=%ld, " + "label_catch_depth=%ld, catch_depth=%ld " + "-> use slow variant (longjmp)", + (long)is_break, (long)label_id, (long)label_is_closest, + (long)label_catch_depth, (long)comp_ctx->curr_func.catch_depth)); + + duk__emit_bc(comp_ctx, is_break ? DUK_OP_BREAK : DUK_OP_CONTINUE, + (duk_regconst_t)label_id); + } +} + +DUK_LOCAL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx, + duk_ivalue *res) { + duk_hthread *thr = comp_ctx->thr; + duk_regconst_t rc_val; + + duk__advance(comp_ctx); /* eat 'return' */ + + /* A 'return' statement is only allowed inside an actual function body, + * not as part of eval or global code. + */ + if (!comp_ctx->curr_func.is_function) { + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_RETURN); + DUK_WO_NORETURN(return;); + } + + if (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON || /* explicit semi follows */ + comp_ctx->curr_token.lineterm || /* automatic semi will be inserted */ + comp_ctx->curr_token + .allow_auto_semi) { /* automatic semi will be inserted */ + DUK_DDD(DUK_DDDPRINT("empty return value -> undefined")); + duk__emit_op_only(comp_ctx, DUK_OP_RETUNDEF); + } else { + duk_int_t pc_before_expr; + duk_int_t pc_after_expr; + + DUK_DDD(DUK_DDDPRINT("return with a value")); + + DUK_UNREF(pc_before_expr); + DUK_UNREF(pc_after_expr); + + pc_before_expr = duk__get_current_pc(comp_ctx); + rc_val = + duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/); + pc_after_expr = duk__get_current_pc(comp_ctx); + + /* Tail call check: if last opcode emitted was CALL, and + * the context allows it, add a tailcall flag to the CALL. + * This doesn't guarantee that a tail call will be allowed at + * runtime, so the RETURN must still be emitted. (Duktape + * 0.10.0 avoided this and simulated a RETURN if a tail call + * couldn't be used at runtime; but this didn't work + * correctly with a thread yield/resume, see + * test-bug-tailcall-thread-yield-resume.js for discussion.) + * + * In addition to the last opcode being CALL, we also need to + * be sure that 'rc_val' is the result register of the CALL. + * For instance, for the expression 'return 0, (function () + * { return 1; }), 2' the last opcode emitted is CALL (no + * bytecode is emitted for '2') but 'rc_val' indicates + * constant '2'. Similarly if '2' is replaced by a register + * bound variable, no opcodes are emitted but tail call would + * be incorrect. + * + * This is tricky and easy to get wrong. It would be best to + * track enough expression metadata to check that 'rc_val' came + * from that last CALL instruction. We don't have that metadata + * now, so we check that 'rc_val' is a temporary register result + * (not a constant or a register bound variable). There should + * be no way currently for 'rc_val' to be a temporary for an + * expression following the CALL instruction without emitting + * some opcodes following the CALL. This proxy check is used + * below. + * + * See: test-bug-comma-expr-gh131.js. + * + * The non-standard 'caller' property disables tail calls + * because they pose some special cases which haven't been + * fixed yet. + */ + +#if defined(DUK_USE_TAILCALL) + if (comp_ctx->curr_func.catch_depth == 0 && /* no catchers */ + pc_after_expr > pc_before_expr) { /* at least one opcode emitted */ + duk_compiler_instr *instr; + duk_instr_t ins; + duk_small_uint_t op; + + instr = duk__get_instr_ptr(comp_ctx, pc_after_expr - 1); + DUK_ASSERT(instr != NULL); + + ins = instr->ins; + op = (duk_small_uint_t)DUK_DEC_OP(ins); + if ((op & ~0x0fU) == DUK_OP_CALL0 && + DUK__ISREG_TEMP(comp_ctx, rc_val) /* see above */) { + DUK_DDD(DUK_DDDPRINT( + "return statement detected a tail call opportunity: " + "catch depth is 0, duk__exprtop() emitted >= 1 instructions, " + "and last instruction is a CALL " + "-> change to TAILCALL")); + ins |= DUK_ENC_OP(DUK_BC_CALL_FLAG_TAILCALL); + instr->ins = ins; + } + } +#endif /* DUK_USE_TAILCALL */ + + if (DUK__ISREG(rc_val)) { + duk__emit_bc(comp_ctx, DUK_OP_RETREG, rc_val); + } else { + rc_val = DUK__REMOVECONST(rc_val); + if (duk__const_needs_refcount(comp_ctx, rc_val)) { + duk__emit_bc(comp_ctx, DUK_OP_RETCONST, rc_val); + } else { + duk__emit_bc(comp_ctx, DUK_OP_RETCONSTN, rc_val); + } + } + } +} + +DUK_LOCAL void duk__parse_throw_stmt(duk_compiler_ctx *comp_ctx, + duk_ivalue *res) { + duk_regconst_t reg_val; + + duk__advance(comp_ctx); /* eat 'throw' */ + + /* Unlike break/continue, throw statement does not allow an empty value. */ + + if (comp_ctx->curr_token.lineterm) { + DUK_ERROR_SYNTAX(comp_ctx->thr, DUK_STR_INVALID_THROW); + DUK_WO_NORETURN(return;); + } + + reg_val = duk__exprtop_toreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/); + duk__emit_bc(comp_ctx, DUK_OP_THROW, reg_val); +} + +DUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, + duk_ivalue *res) { + duk_hthread *thr = comp_ctx->thr; + duk_regconst_t + reg_catch; /* reg_catch+0 and reg_catch+1 are reserved for TRYCATCH */ + duk_regconst_t rc_varname = 0; + duk_small_uint_t trycatch_flags = 0; + duk_int_t pc_ldconst = -1; + duk_int_t pc_trycatch = -1; + duk_int_t pc_catch = -1; + duk_int_t pc_finally = -1; + + DUK_UNREF(res); + + /* + * See the following documentation for discussion: + * + * doc/execution.rst: control flow details + * + * Try, catch, and finally "parts" are Blocks, not Statements, so + * they must always be delimited by curly braces. This is unlike e.g. + * the if statement, which accepts any Statement. This eliminates any + * questions of matching parts of nested try statements. The Block + * parsing is implemented inline here (instead of calling out). + * + * Finally part has a 'let scoped' variable, which requires a few kinks + * here. + */ + + comp_ctx->curr_func.catch_depth++; + + duk__advance(comp_ctx); /* eat 'try' */ + + reg_catch = DUK__ALLOCTEMPS(comp_ctx, 2); + + /* The target for this LDCONST may need output shuffling, but we assume + * that 'pc_ldconst' will be the LDCONST that we can patch later. This + * should be the case because there's no input shuffling. (If there's + * no catch clause, this LDCONST will be replaced with a NOP.) + */ + pc_ldconst = duk__get_current_pc(comp_ctx); + duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, reg_catch, 0 /*patched later*/); + + pc_trycatch = duk__get_current_pc(comp_ctx); + duk__emit_invalid(comp_ctx); /* TRYCATCH, cannot emit now (not enough info) */ + duk__emit_invalid(comp_ctx); /* jump for 'catch' case */ + duk__emit_invalid( + comp_ctx); /* jump for 'finally' case or end (if no finally) */ + + /* try part */ + duk__advance_expect(comp_ctx, DUK_TOK_LCURLY); + duk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, + 1 /*regexp_after*/); + /* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */ + duk__emit_op_only(comp_ctx, DUK_OP_ENDTRY); + + if (comp_ctx->curr_token.t == DUK_TOK_CATCH) { + /* + * The catch variable must be updated to reflect the new allocated + * register for the duration of the catch clause. We need to store + * and restore the original value for the varmap entry (if any). + */ + + /* + * Note: currently register bindings must be fixed for the entire + * function. So, even though the catch variable is in a register + * we know, we must use an explicit environment record and slow path + * accesses to read/write the catch binding to make closures created + * within the catch clause work correctly. This restriction should + * be fixable (at least in common cases) later. + * + * See: test-bug-catch-binding-2.js. + * + * XXX: improve to get fast path access to most catch clauses. + */ + + duk_hstring *h_var; + duk_int_t varmap_value; /* for storing/restoring the varmap binding for + catch variable */ + + DUK_DDD(DUK_DDDPRINT("stack top at start of catch clause: %ld", + (long)duk_get_top(thr))); + + trycatch_flags |= DUK_BC_TRYCATCH_FLAG_HAVE_CATCH; + + pc_catch = duk__get_current_pc(comp_ctx); + + duk__advance(comp_ctx); + duk__advance_expect(comp_ctx, DUK_TOK_LPAREN); + + if (comp_ctx->curr_token.t != DUK_TOK_IDENTIFIER) { + /* Identifier, i.e. don't allow reserved words */ + goto syntax_error; + } + h_var = comp_ctx->curr_token.str1; + DUK_ASSERT(h_var != NULL); + + duk_push_hstring(thr, + h_var); /* keep in on valstack, use borrowed ref below */ + + if (comp_ctx->curr_func.is_strict && + ((h_var == DUK_HTHREAD_STRING_EVAL(thr)) || + (h_var == DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)))) { + DUK_DDD( + DUK_DDDPRINT("catch identifier 'eval' or 'arguments' in strict mode " + "-> SyntaxError")); + goto syntax_error; + } + + duk_dup_top(thr); + rc_varname = duk__getconst(comp_ctx); + DUK_DDD(DUK_DDDPRINT("catch clause, rc_varname=0x%08lx (%ld)", + (unsigned long)rc_varname, (long)rc_varname)); + + duk__advance(comp_ctx); + duk__advance_expect(comp_ctx, DUK_TOK_RPAREN); + + duk__advance_expect(comp_ctx, DUK_TOK_LCURLY); + + DUK_DDD(DUK_DDDPRINT( + "varmap before modifying for catch clause: %!iT", + (duk_tval *)duk_get_tval(thr, comp_ctx->curr_func.varmap_idx))); + + duk_dup_top(thr); + duk_get_prop(thr, comp_ctx->curr_func.varmap_idx); + if (duk_is_undefined(thr, -1)) { + varmap_value = -2; + } else if (duk_is_null(thr, -1)) { + varmap_value = -1; + } else { + DUK_ASSERT(duk_is_number(thr, -1)); + varmap_value = duk_get_int(thr, -1); + DUK_ASSERT(varmap_value >= 0); + } + duk_pop(thr); + +#if 0 + /* It'd be nice to do something like this - but it doesn't + * work for closures created inside the catch clause. + */ + duk_dup_top(thr); + duk_push_int(thr, (duk_int_t) (reg_catch + 0)); + duk_put_prop(thr, comp_ctx->curr_func.varmap_idx); +#endif + duk_dup_top(thr); + duk_push_null(thr); + duk_put_prop(thr, comp_ctx->curr_func.varmap_idx); + + duk__emit_a_bc(comp_ctx, DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE, + reg_catch + 0 /*value*/, rc_varname /*varname*/); + + DUK_DDD(DUK_DDDPRINT( + "varmap before parsing catch clause: %!iT", + (duk_tval *)duk_get_tval(thr, comp_ctx->curr_func.varmap_idx))); + + duk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, + 1 /*regexp_after*/); + /* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */ + + if (varmap_value == -2) { + /* not present */ + duk_del_prop(thr, comp_ctx->curr_func.varmap_idx); + } else { + if (varmap_value == -1) { + duk_push_null(thr); + } else { + DUK_ASSERT(varmap_value >= 0); + duk_push_int(thr, varmap_value); + } + duk_put_prop(thr, comp_ctx->curr_func.varmap_idx); + } + /* varname is popped by above code */ + + DUK_DDD(DUK_DDDPRINT( + "varmap after restore catch clause: %!iT", + (duk_tval *)duk_get_tval(thr, comp_ctx->curr_func.varmap_idx))); + + duk__emit_op_only(comp_ctx, DUK_OP_ENDCATCH); + + /* + * XXX: for now, indicate that an expensive catch binding + * declarative environment is always needed. If we don't + * need it, we don't need the const_varname either. + */ + + trycatch_flags |= DUK_BC_TRYCATCH_FLAG_CATCH_BINDING; + + DUK_DDD(DUK_DDDPRINT("stack top at end of catch clause: %ld", + (long)duk_get_top(thr))); + } + + if (comp_ctx->curr_token.t == DUK_TOK_FINALLY) { + trycatch_flags |= DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY; + + pc_finally = duk__get_current_pc(comp_ctx); + + duk__advance(comp_ctx); + + duk__advance_expect(comp_ctx, DUK_TOK_LCURLY); + duk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, + 1 /*regexp_after*/); + /* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */ + duk__emit_abc(comp_ctx, DUK_OP_ENDFIN, reg_catch); /* rethrow */ + } + + if (!(trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) && + !(trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY)) { + /* must have catch and/or finally */ + goto syntax_error; + } + + /* If there's no catch block, rc_varname will be 0 and duk__patch_trycatch() + * will replace the LDCONST with a NOP. For any actual constant (including + * constant 0) the DUK__CONST_MARKER flag will be set in rc_varname. + */ + + duk__patch_trycatch(comp_ctx, pc_ldconst, pc_trycatch, reg_catch, rc_varname, + trycatch_flags); + + if (trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) { + DUK_ASSERT(pc_catch >= 0); + duk__patch_jump(comp_ctx, pc_trycatch + 1, pc_catch); + } + + if (trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY) { + DUK_ASSERT(pc_finally >= 0); + duk__patch_jump(comp_ctx, pc_trycatch + 2, pc_finally); + } else { + /* without finally, the second jump slot is used to jump to end of stmt */ + duk__patch_jump_here(comp_ctx, pc_trycatch + 2); + } + + comp_ctx->curr_func.catch_depth--; + return; + +syntax_error: + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_TRY); + DUK_WO_NORETURN(return;); +} + +DUK_LOCAL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, + duk_ivalue *res) { + duk_int_t pc_trycatch; + duk_int_t pc_finished; + duk_regconst_t reg_catch; + duk_small_uint_t trycatch_flags; + + if (comp_ctx->curr_func.is_strict) { + DUK_ERROR_SYNTAX(comp_ctx->thr, DUK_STR_WITH_IN_STRICT_MODE); + DUK_WO_NORETURN(return;); + } + + comp_ctx->curr_func.catch_depth++; + + duk__advance(comp_ctx); /* eat 'with' */ + + reg_catch = DUK__ALLOCTEMPS(comp_ctx, 2); + + duk__advance_expect(comp_ctx, DUK_TOK_LPAREN); + duk__exprtop_toforcedreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/, + reg_catch); + comp_ctx->curr_func.allow_regexp_in_adv = 1; + duk__advance_expect(comp_ctx, + DUK_TOK_RPAREN); /* Allow RegExp as part of next stmt. */ + + pc_trycatch = duk__get_current_pc(comp_ctx); + trycatch_flags = DUK_BC_TRYCATCH_FLAG_WITH_BINDING; + duk__emit_a_bc(comp_ctx, DUK_OP_TRYCATCH | DUK__EMIT_FLAG_NO_SHUFFLE_A, + (duk_regconst_t)trycatch_flags /*a*/, reg_catch /*bc*/); + duk__emit_invalid(comp_ctx); /* catch jump */ + duk__emit_invalid(comp_ctx); /* finished jump */ + + duk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/); + duk__emit_op_only(comp_ctx, DUK_OP_ENDTRY); + + pc_finished = duk__get_current_pc(comp_ctx); + + duk__patch_jump(comp_ctx, pc_trycatch + 2, pc_finished); + + comp_ctx->curr_func.catch_depth--; +} + +DUK_LOCAL duk_int_t duk__stmt_label_site(duk_compiler_ctx *comp_ctx, + duk_int_t label_id) { + /* if a site already exists, nop: max one label site per statement */ + if (label_id >= 0) { + return label_id; + } + + label_id = comp_ctx->curr_func.label_next++; + DUK_DDD(DUK_DDDPRINT("allocated new label id for label site: %ld", + (long)label_id)); + + duk__emit_bc(comp_ctx, DUK_OP_LABEL, (duk_regconst_t)label_id); + duk__emit_invalid(comp_ctx); + duk__emit_invalid(comp_ctx); + + return label_id; +} + +/* Parse a single statement. + * + * Creates a label site (with an empty label) automatically for iteration + * statements. Also "peels off" any label statements for explicit labels. + */ +DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, + duk_bool_t allow_source_elem) { + duk_hthread *thr = comp_ctx->thr; + duk_bool_t dir_prol_at_entry; /* directive prologue status at entry */ + duk_regconst_t temp_at_entry; + duk_size_t labels_len_at_entry; + duk_int_t pc_at_entry; /* assumed to also be PC of "LABEL" */ + duk_int_t stmt_id; + duk_small_uint_t stmt_flags = 0; + duk_int_t label_id = -1; + duk_small_uint_t tok; + duk_bool_t test_func_decl; + + DUK__RECURSION_INCREASE(comp_ctx, thr); + + temp_at_entry = DUK__GETTEMP(comp_ctx); + pc_at_entry = duk__get_current_pc(comp_ctx); + labels_len_at_entry = duk_get_length(thr, comp_ctx->curr_func.labelnames_idx); + stmt_id = comp_ctx->curr_func.stmt_next++; + dir_prol_at_entry = comp_ctx->curr_func.in_directive_prologue; + + DUK_UNREF(stmt_id); + + DUK_DDD(DUK_DDDPRINT( + "parsing a statement, stmt_id=%ld, temp_at_entry=%ld, " + "labels_len_at_entry=%ld, " + "is_strict=%ld, in_directive_prologue=%ld, catch_depth=%ld", + (long)stmt_id, (long)temp_at_entry, (long)labels_len_at_entry, + (long)comp_ctx->curr_func.is_strict, + (long)comp_ctx->curr_func.in_directive_prologue, + (long)comp_ctx->curr_func.catch_depth)); + + /* The directive prologue flag is cleared by default so that it is + * unset for any recursive statement parsing. It is only "revived" + * if a directive is detected. (We could also make directives only + * allowed if 'allow_source_elem' was true.) + */ + comp_ctx->curr_func.in_directive_prologue = 0; + +retry_parse: + + DUK_DDD(DUK_DDDPRINT("try stmt parse, stmt_id=%ld, label_id=%ld, " + "allow_source_elem=%ld, catch_depth=%ld", + (long)stmt_id, (long)label_id, (long)allow_source_elem, + (long)comp_ctx->curr_func.catch_depth)); + + /* + * Detect iteration statements; if encountered, establish an + * empty label. + */ + + tok = comp_ctx->curr_token.t; + if (tok == DUK_TOK_FOR || tok == DUK_TOK_DO || tok == DUK_TOK_WHILE || + tok == DUK_TOK_SWITCH) { + DUK_DDD(DUK_DDDPRINT("iteration/switch statement -> add empty label")); + + label_id = duk__stmt_label_site(comp_ctx, label_id); + duk__add_label(comp_ctx, DUK_HTHREAD_STRING_EMPTY_STRING(thr), + pc_at_entry /*pc_label*/, label_id); + } + + /* + * Main switch for statement / source element type. + */ + + switch (comp_ctx->curr_token.t) { + case DUK_TOK_FUNCTION: { + /* + * Function declaration, function expression, or (non-standard) + * function statement. + * + * The E5 specification only allows function declarations at + * the top level (in "source elements"). An ExpressionStatement + * is explicitly not allowed to begin with a "function" keyword + * (E5 Section 12.4). Hence any non-error semantics for such + * non-top-level statements are non-standard. Duktape semantics + * for function statements are modelled after V8, see + * test-dev-func-decl-outside-top.js. + */ + test_func_decl = allow_source_elem; +#if defined(DUK_USE_NONSTD_FUNC_STMT) + /* Lenient: allow function declarations outside top level in + * non-strict mode but reject them in strict mode. + */ + test_func_decl = test_func_decl || !comp_ctx->curr_func.is_strict; +#endif /* DUK_USE_NONSTD_FUNC_STMT */ + /* Strict: never allow function declarations outside top level. */ + if (test_func_decl) { + /* FunctionDeclaration: not strictly a statement but handled as such. + * + * O(depth^2) parse count for inner functions is handled by recording a + * lexer offset on the first compilation pass, so that the function can + * be efficiently skipped on the second pass. This is encapsulated into + * duk__parse_func_like_fnum(). + */ + + duk_int_t fnum; +#if defined(DUK_USE_ASSERTIONS) + duk_idx_t top_before; +#endif + + DUK_DDD(DUK_DDDPRINT("function declaration statement")); + +#if defined(DUK_USE_ASSERTIONS) + top_before = duk_get_top(thr); +#endif + + duk__advance(comp_ctx); /* eat 'function' */ + fnum = duk__parse_func_like_fnum( + comp_ctx, DUK__FUNC_FLAG_DECL | DUK__FUNC_FLAG_PUSHNAME_PASS1); + + /* The value stack convention here is a bit odd: the function + * name is only pushed on pass 1 (in_scanning), and is needed + * to process function declarations. + */ + if (comp_ctx->curr_func.in_scanning) { + duk_uarridx_t n; + +#if defined(DUK_USE_ASSERTIONS) + DUK_ASSERT(duk_get_top(thr) == top_before + 1); +#endif + DUK_DDD(DUK_DDDPRINT( + "register function declaration %!T in pass 1, fnum %ld", + duk_get_tval(thr, -1), (long)fnum)); + n = (duk_uarridx_t)duk_get_length(thr, comp_ctx->curr_func.decls_idx); + /* funcname is at index -1 */ + duk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n); + duk_push_int(thr, (duk_int_t)(DUK_DECL_TYPE_FUNC + (fnum << 8))); + duk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n + 1); + } else { +#if defined(DUK_USE_ASSERTIONS) + DUK_ASSERT(duk_get_top(thr) == top_before); +#endif + } + + /* no statement value (unlike function expression) */ + stmt_flags = 0; + break; + } else { + DUK_ERROR_SYNTAX(thr, DUK_STR_FUNC_STMT_NOT_ALLOWED); + DUK_WO_NORETURN(return;); + } + break; + } + case DUK_TOK_LCURLY: { + DUK_DDD(DUK_DDDPRINT("block statement")); + duk__advance(comp_ctx); + duk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, + 1 /*regexp_after*/); + /* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */ + if (label_id >= 0) { + duk__patch_jump_here(comp_ctx, pc_at_entry + 1); /* break jump */ + } + stmt_flags = 0; + break; + } + case DUK_TOK_CONST: { + DUK_DDD(DUK_DDDPRINT("constant declaration statement")); + duk__parse_var_stmt(comp_ctx, res, + DUK__EXPR_FLAG_REQUIRE_INIT /*expr_flags*/); + stmt_flags = DUK__HAS_TERM; + break; + } + case DUK_TOK_VAR: { + DUK_DDD(DUK_DDDPRINT("variable declaration statement")); + duk__parse_var_stmt(comp_ctx, res, 0 /*expr_flags*/); + stmt_flags = DUK__HAS_TERM; + break; + } + case DUK_TOK_SEMICOLON: { + /* empty statement with an explicit semicolon */ + DUK_DDD(DUK_DDDPRINT("empty statement")); + stmt_flags = DUK__HAS_TERM; + break; + } + case DUK_TOK_IF: { + DUK_DDD(DUK_DDDPRINT("if statement")); + duk__parse_if_stmt(comp_ctx, res); + if (label_id >= 0) { + duk__patch_jump_here(comp_ctx, pc_at_entry + 1); /* break jump */ + } + stmt_flags = 0; + break; + } + case DUK_TOK_DO: { + /* + * Do-while statement is mostly trivial, but there is special + * handling for automatic semicolon handling (triggered by the + * DUK__ALLOW_AUTO_SEMI_ALWAYS) flag related to a bug filed at: + * + * https://bugs.ecmascript.org/show_bug.cgi?id=8 + * + * See doc/compiler.rst for details. + */ + DUK_DDD(DUK_DDDPRINT("do statement")); + DUK_ASSERT(label_id >= 0); + duk__update_label_flags( + comp_ctx, label_id, + DUK_LABEL_FLAG_ALLOW_BREAK | DUK_LABEL_FLAG_ALLOW_CONTINUE); + duk__parse_do_stmt(comp_ctx, res, pc_at_entry); + stmt_flags = DUK__HAS_TERM | + DUK__ALLOW_AUTO_SEMI_ALWAYS; /* DUK__ALLOW_AUTO_SEMI_ALWAYS + workaround */ + break; + } + case DUK_TOK_WHILE: { + DUK_DDD(DUK_DDDPRINT("while statement")); + DUK_ASSERT(label_id >= 0); + duk__update_label_flags( + comp_ctx, label_id, + DUK_LABEL_FLAG_ALLOW_BREAK | DUK_LABEL_FLAG_ALLOW_CONTINUE); + duk__parse_while_stmt(comp_ctx, res, pc_at_entry); + stmt_flags = 0; + break; + } + case DUK_TOK_FOR: { + /* + * For/for-in statement is complicated to parse because + * determining the statement type (three-part for vs. a + * for-in) requires potential backtracking. + * + * See the helper for the messy stuff. + */ + DUK_DDD(DUK_DDDPRINT("for/for-in statement")); + DUK_ASSERT(label_id >= 0); + duk__update_label_flags( + comp_ctx, label_id, + DUK_LABEL_FLAG_ALLOW_BREAK | DUK_LABEL_FLAG_ALLOW_CONTINUE); + duk__parse_for_stmt(comp_ctx, res, pc_at_entry); + stmt_flags = 0; + break; + } + case DUK_TOK_CONTINUE: + case DUK_TOK_BREAK: { + DUK_DDD(DUK_DDDPRINT("break/continue statement")); + duk__parse_break_or_continue_stmt(comp_ctx, res); + stmt_flags = DUK__HAS_TERM | DUK__IS_TERMINAL; + break; + } + case DUK_TOK_RETURN: { + DUK_DDD(DUK_DDDPRINT("return statement")); + duk__parse_return_stmt(comp_ctx, res); + stmt_flags = DUK__HAS_TERM | DUK__IS_TERMINAL; + break; + } + case DUK_TOK_WITH: { + DUK_DDD(DUK_DDDPRINT("with statement")); + comp_ctx->curr_func.with_depth++; + duk__parse_with_stmt(comp_ctx, res); + if (label_id >= 0) { + duk__patch_jump_here(comp_ctx, pc_at_entry + 1); /* break jump */ + } + comp_ctx->curr_func.with_depth--; + stmt_flags = 0; + break; + } + case DUK_TOK_SWITCH: { + /* + * The switch statement is pretty messy to compile. + * See the helper for details. + */ + DUK_DDD(DUK_DDDPRINT("switch statement")); + DUK_ASSERT(label_id >= 0); + duk__update_label_flags( + comp_ctx, label_id, + DUK_LABEL_FLAG_ALLOW_BREAK); /* don't allow continue */ + duk__parse_switch_stmt(comp_ctx, res, pc_at_entry); + stmt_flags = 0; + break; + } + case DUK_TOK_THROW: { + DUK_DDD(DUK_DDDPRINT("throw statement")); + duk__parse_throw_stmt(comp_ctx, res); + stmt_flags = DUK__HAS_TERM | DUK__IS_TERMINAL; + break; + } + case DUK_TOK_TRY: { + DUK_DDD(DUK_DDDPRINT("try statement")); + duk__parse_try_stmt(comp_ctx, res); + stmt_flags = 0; + break; + } + case DUK_TOK_DEBUGGER: { + duk__advance(comp_ctx); +#if defined(DUK_USE_DEBUGGER_SUPPORT) + DUK_DDD(DUK_DDDPRINT( + "debugger statement: debugging enabled, emit debugger opcode")); + duk__emit_op_only(comp_ctx, DUK_OP_DEBUGGER); +#else + DUK_DDD(DUK_DDDPRINT("debugger statement: ignored")); +#endif + stmt_flags = DUK__HAS_TERM; + break; + } + default: { + /* + * Else, must be one of: + * - ExpressionStatement, possibly a directive (String) + * - LabelledStatement (Identifier followed by ':') + * + * Expressions beginning with 'function' keyword are covered by a case + * above (such expressions are not allowed in standard E5 anyway). + * Also expressions starting with '{' are interpreted as block + * statements. See E5 Section 12.4. + * + * Directive detection is tricky; see E5 Section 14.1 on directive + * prologue. A directive is an expression statement with a single + * string literal and an explicit or automatic semicolon. Escape + * characters are significant and no parens etc are allowed: + * + * 'use strict'; // valid 'use strict' directive + * 'use\u0020strict'; // valid directive, not a 'use strict' + * directive + * ('use strict'); // not a valid directive + * + * The expression is determined to consist of a single string literal + * based on duk__expr_nud() and duk__expr_led() call counts. The string + * literal of a 'use strict' directive is determined to lack any escapes + * based num_escapes count from the lexer. Note that other directives may + * be allowed to contain escapes, so a directive with escapes does not + * terminate a directive prologue. + * + * We rely on the fact that the expression parser will not emit any + * code for a single token expression. However, it will generate an + * intermediate value which we will then successfully ignore. + * + * A similar approach is used for labels. + */ + + duk_bool_t single_token; + + DUK_DDD(DUK_DDDPRINT("expression statement")); + duk__exprtop(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/); + + single_token = (comp_ctx->curr_func.nud_count == 1 && /* one token */ + comp_ctx->curr_func.led_count == 0); /* no operators */ + + if (single_token && comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER && + comp_ctx->curr_token.t == DUK_TOK_COLON) { + /* + * Detected label + */ + + duk_hstring *h_lab; + + /* expected ival */ + DUK_ASSERT(res->t == DUK_IVAL_VAR); + DUK_ASSERT(res->x1.t == DUK_ISPEC_VALUE); + DUK_ASSERT(DUK_TVAL_IS_STRING(duk_get_tval(thr, res->x1.valstack_idx))); + h_lab = comp_ctx->prev_token.str1; + DUK_ASSERT(h_lab != NULL); + + DUK_DDD(DUK_DDDPRINT("explicit label site for label '%!O'", + (duk_heaphdr *)h_lab)); + + duk__advance(comp_ctx); /* eat colon */ + + label_id = duk__stmt_label_site(comp_ctx, label_id); + + duk__add_label(comp_ctx, h_lab, pc_at_entry /*pc_label*/, label_id); + + /* a statement following a label cannot be a source element + * (a function declaration). + */ + allow_source_elem = 0; + + DUK_DDD(DUK_DDDPRINT("label handled, retry statement parsing")); + goto retry_parse; + } + + stmt_flags = 0; + + if (dir_prol_at_entry && /* still in prologue */ + single_token && /* single string token */ + comp_ctx->prev_token.t == DUK_TOK_STRING) { + /* + * Detected a directive + */ + duk_hstring *h_dir; + + /* expected ival */ + DUK_ASSERT(res->t == DUK_IVAL_PLAIN); + DUK_ASSERT(res->x1.t == DUK_ISPEC_VALUE); + DUK_ASSERT(DUK_TVAL_IS_STRING(duk_get_tval(thr, res->x1.valstack_idx))); + h_dir = comp_ctx->prev_token.str1; + DUK_ASSERT(h_dir != NULL); + + DUK_DDD(DUK_DDDPRINT("potential directive: %!O", h_dir)); + + stmt_flags |= DUK__STILL_PROLOGUE; + + /* Note: escaped characters differentiate directives */ + + if (comp_ctx->prev_token.num_escapes > 0) { + DUK_DDD(DUK_DDDPRINT("directive contains escapes: valid directive " + "but we ignore such directives")); + } else { + /* + * The length comparisons are present to handle + * strings like "use strict\u0000foo" as required. + */ + + if (DUK_HSTRING_GET_BYTELEN(h_dir) == 10 && + DUK_STRCMP((const char *)DUK_HSTRING_GET_DATA(h_dir), + "use strict") == 0) { +#if defined(DUK_USE_STRICT_DECL) + DUK_DDD(DUK_DDDPRINT( + "use strict directive detected: strict flag %ld -> %ld", + (long)comp_ctx->curr_func.is_strict, (long)1)); + comp_ctx->curr_func.is_strict = 1; +#else + DUK_DDD(DUK_DDDPRINT("use strict detected but strict declarations " + "disabled, ignoring")); +#endif + } else if (DUK_HSTRING_GET_BYTELEN(h_dir) == 14 && + DUK_STRCMP((const char *)DUK_HSTRING_GET_DATA(h_dir), + "use duk notail") == 0) { + DUK_DDD(DUK_DDDPRINT( + "use duk notail directive detected: notail flag %ld -> %ld", + (long)comp_ctx->curr_func.is_notail, (long)1)); + comp_ctx->curr_func.is_notail = 1; + } else { + DUK_DD(DUK_DDPRINT( + "unknown directive: '%!O', ignoring but not terminating " + "directive prologue", + (duk_hobject *)h_dir)); + } + } + } else { + DUK_DDD(DUK_DDDPRINT( + "non-directive expression statement or no longer in prologue; " + "prologue terminated if still active")); + } + + stmt_flags |= DUK__HAS_VAL | DUK__HAS_TERM; + } + } /* end switch (tok) */ + + /* + * Statement value handling. + * + * Global code and eval code has an implicit return value + * which comes from the last statement with a value + * (technically a non-"empty" continuation, which is + * different from an empty statement). + * + * Since we don't know whether a later statement will + * override the value of the current statement, we need + * to coerce the statement value to a register allocated + * for implicit return values. In other cases we need + * to coerce the statement value to a plain value to get + * any side effects out (consider e.g. "foo.bar;"). + */ + + /* XXX: what about statements which leave a half-cooked value in 'res' + * but have no stmt value? Any such statements? + */ + + if (stmt_flags & DUK__HAS_VAL) { + duk_regconst_t reg_stmt_value = comp_ctx->curr_func.reg_stmt_value; + if (reg_stmt_value >= 0) { + duk__ivalue_toforcedreg(comp_ctx, res, reg_stmt_value); + } else { + duk__ivalue_toplain_ignore(comp_ctx, res); + } + } else { + ; + } + + /* + * Statement terminator check, including automatic semicolon + * handling. After this step, 'curr_tok' should be the first + * token after a possible statement terminator. + */ + + if (stmt_flags & DUK__HAS_TERM) { + if (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON) { + DUK_DDD(DUK_DDDPRINT("explicit semicolon terminates statement")); + duk__advance(comp_ctx); + } else { + if (comp_ctx->curr_token.allow_auto_semi) { + DUK_DDD(DUK_DDDPRINT("automatic semicolon terminates statement")); + } else if (stmt_flags & DUK__ALLOW_AUTO_SEMI_ALWAYS) { + /* XXX: make this lenience dependent on flags or strictness? */ + DUK_DDD( + DUK_DDDPRINT("automatic semicolon terminates statement (allowed " + "for compatibility " + "even though no lineterm present before next token)")); + } else { + DUK_ERROR_SYNTAX(thr, DUK_STR_UNTERMINATED_STMT); + DUK_WO_NORETURN(return;); + } + } + } else { + DUK_DDD(DUK_DDDPRINT("statement has no terminator")); + } + + /* + * Directive prologue tracking. + */ + + if (stmt_flags & DUK__STILL_PROLOGUE) { + DUK_DDD(DUK_DDDPRINT("setting in_directive_prologue")); + comp_ctx->curr_func.in_directive_prologue = 1; + } + + /* + * Cleanups (all statement parsing flows through here). + * + * Pop label site and reset labels. Reset 'next temp' to value at + * entry to reuse temps. + */ + + if (label_id >= 0) { + duk__emit_bc(comp_ctx, DUK_OP_ENDLABEL, (duk_regconst_t)label_id); + } + + DUK__SETTEMP(comp_ctx, temp_at_entry); + + duk__reset_labels_to_length(comp_ctx, labels_len_at_entry); + + /* XXX: return indication of "terminalness" (e.g. a 'throw' is terminal) */ + + DUK__RECURSION_DECREASE(comp_ctx, thr); +} + +/* + * Parse a statement list. + * + * Handles automatic semicolon insertion and implicit return value. + * + * Upon entry, 'curr_tok' should contain the first token of the first + * statement (parsed in the "allow regexp literal" mode). Upon exit, + * 'curr_tok' contains the token following the statement list terminator + * (EOF or closing brace). + */ + +DUK_LOCAL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, + duk_bool_t allow_source_elem, + duk_bool_t expect_eof, + duk_bool_t regexp_after) { + duk_hthread *thr = comp_ctx->thr; + duk_ivalue res_alloc; + duk_ivalue *res = &res_alloc; + + /* Setup state. Initial ivalue is 'undefined'. */ + + duk_require_stack(thr, DUK__PARSE_STATEMENTS_SLOTS); + + /* XXX: 'res' setup can be moved to function body level; in fact, two 'res' + * intermediate values suffice for parsing of each function. Nesting is + * needed for nested functions (which may occur inside expressions). + */ + + duk_memzero(&res_alloc, sizeof(res_alloc)); + res->t = DUK_IVAL_PLAIN; + res->x1.t = DUK_ISPEC_VALUE; + res->x1.valstack_idx = duk_get_top(thr); + res->x2.valstack_idx = res->x1.valstack_idx + 1; + duk_push_undefined(thr); + duk_push_undefined(thr); + + /* Parse statements until a closing token (EOF or '}') is found. */ + + for (;;) { + /* Check whether statement list ends. */ + + if (expect_eof) { + if (comp_ctx->curr_token.t == DUK_TOK_EOF) { + break; + } + } else { + if (comp_ctx->curr_token.t == DUK_TOK_RCURLY) { + break; + } + } + + /* Check statement type based on the first token type. + * + * Note: expression parsing helpers expect 'curr_tok' to + * contain the first token of the expression upon entry. + */ + + DUK_DDD(DUK_DDDPRINT("TOKEN %ld (non-whitespace, non-comment)", + (long)comp_ctx->curr_token.t)); + + duk__parse_stmt(comp_ctx, res, allow_source_elem); + } + + /* RegExp is allowed / not allowed depending on context. For function + * declarations RegExp is allowed because it follows a function + * declaration statement and may appear as part of the next statement. + * For function expressions RegExp is not allowed, and it's possible + * to do something like '(function () {} / 123)'. + */ + if (regexp_after) { + comp_ctx->curr_func.allow_regexp_in_adv = 1; + } + duk__advance(comp_ctx); + + /* Tear down state. */ + + duk_pop_2(thr); +} + +/* + * Declaration binding instantiation conceptually happens when calling a + * function; for us it essentially means that function prologue. The + * conceptual process is described in E5 Section 10.5. + * + * We need to keep track of all encountered identifiers to (1) create an + * identifier-to-register map ("varmap"); and (2) detect duplicate + * declarations. Identifiers which are not bound to registers still need + * to be tracked for detecting duplicates. Currently such identifiers + * are put into the varmap with a 'null' value, which is later cleaned up. + * + * To support functions with a large number of variable and function + * declarations, registers are not allocated beyond a certain limit; + * after that limit, variables and functions need slow path access. + * Arguments are currently always register bound, which imposes a hard + * (and relatively small) argument count limit. + * + * Some bindings in E5 are not configurable (= deletable) and almost all + * are mutable (writable). Exceptions are: + * + * - The 'arguments' binding, established only if no shadowing argument + * or function declaration exists. We handle 'arguments' creation + * and binding through an explicit slow path environment record. + * + * - The "name" binding for a named function expression. This is also + * handled through an explicit slow path environment record. + */ + +/* XXX: add support for variables to not be register bound always, to + * handle cases with a very large number of variables? + */ + +DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2( + duk_compiler_ctx *comp_ctx, duk_regconst_t *out_stmt_value_reg) { + duk_hthread *thr = comp_ctx->thr; + duk_hstring *h_name; + duk_bool_t configurable_bindings; + duk_uarridx_t num_args; + duk_uarridx_t num_decls; + duk_regconst_t rc_name; + duk_small_uint_t declvar_flags; + duk_uarridx_t i; +#if defined(DUK_USE_ASSERTIONS) + duk_idx_t entry_top; +#endif + +#if defined(DUK_USE_ASSERTIONS) + entry_top = duk_get_top(thr); +#endif + + /* + * Preliminaries + */ + + configurable_bindings = comp_ctx->curr_func.is_eval; + DUK_DDD( + DUK_DDDPRINT("configurable_bindings=%ld", (long)configurable_bindings)); + + /* varmap is already in comp_ctx->curr_func.varmap_idx */ + + /* + * Function formal arguments, always bound to registers + * (there's no support for shuffling them now). + */ + + num_args = + (duk_uarridx_t)duk_get_length(thr, comp_ctx->curr_func.argnames_idx); + DUK_DDD(DUK_DDDPRINT("num_args=%ld", (long)num_args)); + /* XXX: check num_args */ + + for (i = 0; i < num_args; i++) { + duk_get_prop_index(thr, comp_ctx->curr_func.argnames_idx, i); + h_name = duk_known_hstring(thr, -1); + + if (comp_ctx->curr_func.is_strict) { + if (duk__hstring_is_eval_or_arguments(comp_ctx, h_name)) { + DUK_DDD(DUK_DDDPRINT( + "arg named 'eval' or 'arguments' in strict mode -> SyntaxError")); + goto error_argname; + } + duk_dup_top(thr); + if (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) { + DUK_DDD( + DUK_DDDPRINT("duplicate arg name in strict mode -> SyntaxError")); + goto error_argname; + } + + /* Ensure argument name is not a reserved word in current + * (final) strictness. Formal argument parsing may not + * catch reserved names if strictness changes during + * parsing. + * + * We only need to do this in strict mode because non-strict + * keyword are always detected in formal argument parsing. + */ + + if (DUK_HSTRING_HAS_STRICT_RESERVED_WORD(h_name)) { + goto error_argname; + } + } + + /* overwrite any previous binding of the same name; the effect is + * that last argument of a certain name wins. + */ + + /* only functions can have arguments */ + DUK_ASSERT(comp_ctx->curr_func.is_function); + duk_push_uarridx(thr, i); /* -> [ ... name index ] */ + duk_put_prop(thr, comp_ctx->curr_func.varmap_idx); /* -> [ ... ] */ + + /* no code needs to be emitted, the regs already have values */ + } + + /* use temp_next for tracking register allocations */ + DUK__SETTEMP_CHECKMAX(comp_ctx, (duk_regconst_t)num_args); + + /* + * After arguments, allocate special registers (like shuffling temps) + */ + + if (out_stmt_value_reg) { + *out_stmt_value_reg = DUK__ALLOCTEMP(comp_ctx); + } + if (comp_ctx->curr_func.needs_shuffle) { + duk_regconst_t shuffle_base = DUK__ALLOCTEMPS(comp_ctx, 3); + comp_ctx->curr_func.shuffle1 = shuffle_base; + comp_ctx->curr_func.shuffle2 = shuffle_base + 1; + comp_ctx->curr_func.shuffle3 = shuffle_base + 2; + DUK_D(DUK_DPRINT( + "shuffle registers needed by function, allocated: %ld %ld %ld", + (long)comp_ctx->curr_func.shuffle1, (long)comp_ctx->curr_func.shuffle2, + (long)comp_ctx->curr_func.shuffle3)); + } + if (comp_ctx->curr_func.temp_next > 0x100) { + DUK_D(DUK_DPRINT("not enough 8-bit regs: temp_next=%ld", + (long)comp_ctx->curr_func.temp_next)); + goto error_outofregs; + } + + /* + * Function declarations + */ + + num_decls = (duk_uarridx_t)duk_get_length(thr, comp_ctx->curr_func.decls_idx); + DUK_DDD(DUK_DDDPRINT( + "num_decls=%ld -> %!T", (long)num_decls, + (duk_tval *)duk_get_tval(thr, comp_ctx->curr_func.decls_idx))); + for (i = 0; i < num_decls; i += 2) { + duk_int_t decl_type; + duk_int_t fnum; + + duk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, + i + 1); /* decl type */ + decl_type = duk_to_int(thr, -1); + fnum = decl_type >> 8; /* XXX: macros */ + decl_type = decl_type & 0xff; + duk_pop(thr); + + if (decl_type != DUK_DECL_TYPE_FUNC) { + continue; + } + + duk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i); /* decl name */ + + /* XXX: spilling */ + if (comp_ctx->curr_func.is_function) { + duk_regconst_t reg_bind; + duk_dup_top(thr); + if (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) { + /* shadowed; update value */ + duk_dup_top(thr); + duk_get_prop(thr, comp_ctx->curr_func.varmap_idx); + reg_bind = duk_to_int(thr, -1); /* [ ... name reg_bind ] */ + duk__emit_a_bc(comp_ctx, DUK_OP_CLOSURE, reg_bind, + (duk_regconst_t)fnum); + } else { + /* function: always register bound */ + reg_bind = DUK__ALLOCTEMP(comp_ctx); + duk__emit_a_bc(comp_ctx, DUK_OP_CLOSURE, reg_bind, + (duk_regconst_t)fnum); + duk_push_int(thr, (duk_int_t)reg_bind); + } + } else { + /* Function declaration for global/eval code is emitted even + * for duplicates, because of E5 Section 10.5, step 5.e of + * E5.1 (special behavior for variable bound to global object). + * + * DECLVAR will not re-declare a variable as such, but will + * update the binding value. + */ + + duk_regconst_t reg_temp = DUK__ALLOCTEMP(comp_ctx); + duk_dup_top(thr); + rc_name = duk__getconst(comp_ctx); + duk_push_null(thr); + + duk__emit_a_bc(comp_ctx, DUK_OP_CLOSURE, reg_temp, (duk_regconst_t)fnum); + + declvar_flags = DUK_PROPDESC_FLAG_WRITABLE | + DUK_PROPDESC_FLAG_ENUMERABLE | + DUK_BC_DECLVAR_FLAG_FUNC_DECL; + + if (configurable_bindings) { + declvar_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE; + } + + duk__emit_a_b_c(comp_ctx, + DUK_OP_DECLVAR | DUK__EMIT_FLAG_NO_SHUFFLE_A | + DUK__EMIT_FLAG_BC_REGCONST, + (duk_regconst_t)declvar_flags /*flags*/, rc_name /*name*/, + reg_temp /*value*/); + + DUK__SETTEMP(comp_ctx, reg_temp); /* forget temp */ + } + + DUK_DDD(DUK_DDDPRINT("function declaration to varmap: %!T -> %!T", + (duk_tval *)duk_get_tval(thr, -2), + (duk_tval *)duk_get_tval(thr, -1))); + +#if defined(DUK_USE_FASTINT) + DUK_ASSERT(DUK_TVAL_IS_NULL(duk_get_tval(thr, -1)) || + DUK_TVAL_IS_FASTINT(duk_get_tval(thr, -1))); +#endif + duk_put_prop( + thr, + comp_ctx->curr_func.varmap_idx); /* [ ... name reg/null ] -> [ ... ] */ + } + + /* + * 'arguments' binding is special; if a shadowing argument or + * function declaration exists, an arguments object will + * definitely not be needed, regardless of whether the identifier + * 'arguments' is referenced inside the function body. + */ + + if (duk_has_prop_stridx(thr, comp_ctx->curr_func.varmap_idx, + DUK_STRIDX_LC_ARGUMENTS)) { + DUK_DDD(DUK_DDDPRINT( + "'arguments' is shadowed by argument or function declaration " + "-> arguments object creation can be skipped")); + comp_ctx->curr_func.is_arguments_shadowed = 1; + } + + /* + * Variable declarations. + * + * Unlike function declarations, variable declaration values don't get + * assigned on entry. If a binding of the same name already exists, just + * ignore it silently. + */ + + for (i = 0; i < num_decls; i += 2) { + duk_int_t decl_type; + + duk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, + i + 1); /* decl type */ + decl_type = duk_to_int(thr, -1); + decl_type = decl_type & 0xff; + duk_pop(thr); + + if (decl_type != DUK_DECL_TYPE_VAR) { + continue; + } + + duk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i); /* decl name */ + + if (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) { + /* shadowed, ignore */ + } else { + duk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i); /* decl name */ + h_name = duk_known_hstring(thr, -1); + + if (h_name == DUK_HTHREAD_STRING_LC_ARGUMENTS(thr) && + !comp_ctx->curr_func.is_arguments_shadowed) { + /* E5 Section steps 7-8 */ + DUK_DDD( + DUK_DDDPRINT("'arguments' not shadowed by a function declaration, " + "but appears as a variable declaration -> treat as " + "a no-op for variable declaration purposes")); + duk_pop(thr); + continue; + } + + /* XXX: spilling */ + if (comp_ctx->curr_func.is_function) { + duk_regconst_t reg_bind = DUK__ALLOCTEMP(comp_ctx); + /* no need to init reg, it will be undefined on entry */ + duk_push_int(thr, (duk_int_t)reg_bind); + } else { + duk_dup_top(thr); + rc_name = duk__getconst(comp_ctx); + duk_push_null(thr); + + declvar_flags = + DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_ENUMERABLE; + if (configurable_bindings) { + declvar_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE; + } + + duk__emit_a_b_c(comp_ctx, + DUK_OP_DECLVAR | DUK__EMIT_FLAG_NO_SHUFFLE_A | + DUK__EMIT_FLAG_BC_REGCONST, + (duk_regconst_t)declvar_flags /*flags*/, + rc_name /*name*/, 0 /*value*/); + } + + duk_put_prop(thr, comp_ctx->curr_func + .varmap_idx); /* [ ... name reg/null ] -> [ ... ] */ + } + } + + /* + * Wrap up + */ + + DUK_DDD(DUK_DDDPRINT( + "varmap: %!T, is_arguments_shadowed=%ld", + (duk_tval *)duk_get_tval(thr, comp_ctx->curr_func.varmap_idx), + (long)comp_ctx->curr_func.is_arguments_shadowed)); + + DUK_ASSERT_TOP(thr, entry_top); + return; + +error_outofregs: + DUK_ERROR_RANGE(thr, DUK_STR_REG_LIMIT); + DUK_WO_NORETURN(return;); + +error_argname: + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_ARG_NAME); + DUK_WO_NORETURN(return;); +} + +/* + * Parse a function-body-like expression (FunctionBody or Program + * in E5 grammar) using a two-pass parse. The productions appear + * in the following contexts: + * + * - function expression + * - function statement + * - function declaration + * - getter in object literal + * - setter in object literal + * - global code + * - eval code + * - Function constructor body + * + * This function only parses the statement list of the body; the argument + * list and possible function name must be initialized by the caller. + * For instance, for Function constructor, the argument names are originally + * on the value stack. The parsing of statements ends either at an EOF or + * a closing brace; this is controlled by an input flag. + * + * Note that there are many differences affecting parsing and even code + * generation: + * + * - Global and eval code have an implicit return value generated + * by the last statement; function code does not + * + * - Global code, eval code, and Function constructor body end in + * an EOF, other bodies in a closing brace ('}') + * + * Upon entry, 'curr_tok' is ignored and the function will pull in the + * first token on its own. Upon exit, 'curr_tok' is the terminating + * token (EOF or closing brace). + */ + +DUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, + duk_bool_t expect_eof, + duk_bool_t implicit_return_value, + duk_bool_t regexp_after, + duk_small_int_t expect_token) { + duk_compiler_func *func; + duk_hthread *thr; + duk_regconst_t reg_stmt_value = -1; + duk_lexer_point lex_pt; + duk_regconst_t temp_first; + duk_small_int_t compile_round = 1; + + DUK_ASSERT(comp_ctx != NULL); + + thr = comp_ctx->thr; + DUK_ASSERT(thr != NULL); + + func = &comp_ctx->curr_func; + DUK_ASSERT(func != NULL); + + DUK__RECURSION_INCREASE(comp_ctx, thr); + + duk_require_stack(thr, DUK__FUNCTION_BODY_REQUIRE_SLOTS); + + /* + * Store lexer position for a later rewind + */ + + DUK_LEXER_GETPOINT(&comp_ctx->lex, &lex_pt); + + /* + * Program code (global and eval code) has an implicit return value + * from the last statement value (e.g. eval("1; 2+3;") returns 3). + * This is not the case with functions. If implicit statement return + * value is requested, all statements are coerced to a register + * allocated here, and used in the implicit return statement below. + */ + + /* XXX: this is pointless here because pass 1 is throw-away */ + if (implicit_return_value) { + reg_stmt_value = DUK__ALLOCTEMP(comp_ctx); + + /* If an implicit return value is needed by caller, it must be + * initialized to 'undefined' because we don't know whether any + * non-empty (where "empty" is a continuation type, and different + * from an empty statement) statements will be executed. + * + * However, since 1st pass is a throwaway one, no need to emit + * it here. + */ +#if 0 + duk__emit_bc(comp_ctx, + DUK_OP_LDUNDEF, + 0); +#endif + } + + /* + * First pass. + * + * Gather variable/function declarations needed for second pass. + * Code generated is dummy and discarded. + */ + + func->in_directive_prologue = 1; + func->in_scanning = 1; + func->may_direct_eval = 0; + func->id_access_arguments = 0; + func->id_access_slow = 0; + func->id_access_slow_own = 0; + func->reg_stmt_value = reg_stmt_value; +#if defined(DUK_USE_DEBUGGER_SUPPORT) + func->min_line = DUK_INT_MAX; + func->max_line = 0; +#endif + + /* duk__parse_stmts() expects curr_tok to be set; parse in "allow + * regexp literal" mode with current strictness. + */ + if (expect_token >= 0) { + /* Eating a left curly; regexp mode is allowed by left curly + * based on duk__token_lbp[] automatically. + */ + DUK_ASSERT(expect_token == DUK_TOK_LCURLY); + duk__update_lineinfo_currtoken(comp_ctx); + duk__advance_expect(comp_ctx, expect_token); + } else { + /* Need to set curr_token.t because lexing regexp mode depends on current + * token type. Zero value causes "allow regexp" mode. + */ + comp_ctx->curr_token.t = 0; + duk__advance(comp_ctx); + } + + DUK_DDD(DUK_DDDPRINT("begin 1st pass")); + duk__parse_stmts(comp_ctx, 1, /* allow source elements */ + expect_eof, /* expect EOF instead of } */ + regexp_after); /* regexp after */ + DUK_DDD(DUK_DDDPRINT("end 1st pass")); + + /* + * Second (and possibly third) pass. + * + * Generate actual code. In most cases the need for shuffle + * registers is detected during pass 1, but in some corner cases + * we'll only detect it during pass 2 and a third pass is then + * needed (see GH-115). + */ + + for (;;) { + duk_bool_t needs_shuffle_before = comp_ctx->curr_func.needs_shuffle; + compile_round++; + + /* + * Rewind lexer. + * + * duk__parse_stmts() expects curr_tok to be set; parse in "allow regexp + * literal" mode with current strictness. + * + * curr_token line number info should be initialized for pass 2 before + * generating prologue, to ensure prologue bytecode gets nice line numbers. + */ + + DUK_DDD(DUK_DDDPRINT("rewind lexer")); + DUK_LEXER_SETPOINT(&comp_ctx->lex, &lex_pt); + comp_ctx->curr_token.t = 0; /* this is needed for regexp mode */ + comp_ctx->curr_token.start_line = + 0; /* needed for line number tracking (becomes prev_token.start_line) */ + duk__advance(comp_ctx); + + /* + * Reset function state and perform register allocation, which creates + * 'varmap' for second pass. Function prologue for variable declarations, + * binding value initializations etc is emitted as a by-product. + * + * Strict mode restrictions for duplicate and invalid argument + * names are checked here now that we know whether the function + * is actually strict. See: test-dev-strict-mode-boundary.js. + * + * Inner functions are compiled during pass 1 and are not reset. + */ + + duk__reset_func_for_pass2(comp_ctx); + func->in_directive_prologue = 1; + func->in_scanning = 0; + + /* must be able to emit code, alloc consts, etc. */ + + duk__init_varmap_and_prologue_for_pass2( + comp_ctx, (implicit_return_value ? ®_stmt_value : NULL)); + func->reg_stmt_value = reg_stmt_value; + + temp_first = DUK__GETTEMP(comp_ctx); + + func->temp_first = temp_first; + func->temp_next = temp_first; + func->stmt_next = 0; + func->label_next = 0; + + /* XXX: init or assert catch depth etc -- all values */ + func->id_access_arguments = 0; + func->id_access_slow = 0; + func->id_access_slow_own = 0; + + /* + * Check function name validity now that we know strictness. + * This only applies to function declarations and expressions, + * not setter/getter name. + * + * See: test-dev-strict-mode-boundary.js + */ + + if (func->is_function && !func->is_setget && func->h_name != NULL) { + if (func->is_strict) { + if (duk__hstring_is_eval_or_arguments(comp_ctx, func->h_name)) { + DUK_DDD(DUK_DDDPRINT( + "func name is 'eval' or 'arguments' in strict mode")); + goto error_funcname; + } + if (DUK_HSTRING_HAS_STRICT_RESERVED_WORD(func->h_name)) { + DUK_DDD(DUK_DDDPRINT("func name is a reserved word in strict mode")); + goto error_funcname; + } + } else { + if (DUK_HSTRING_HAS_RESERVED_WORD(func->h_name) && + !DUK_HSTRING_HAS_STRICT_RESERVED_WORD(func->h_name)) { + DUK_DDD( + DUK_DDDPRINT("func name is a reserved word in non-strict mode")); + goto error_funcname; + } + } + } + + /* + * Second pass parsing. + */ + + if (implicit_return_value) { + /* Default implicit return value. */ + duk__emit_bc(comp_ctx, DUK_OP_LDUNDEF, 0); + } + + DUK_DDD(DUK_DDDPRINT("begin 2nd pass")); + duk__parse_stmts(comp_ctx, 1, /* allow source elements */ + expect_eof, /* expect EOF instead of } */ + regexp_after); /* regexp after */ + DUK_DDD(DUK_DDDPRINT("end 2nd pass")); + + duk__update_lineinfo_currtoken(comp_ctx); + + if (needs_shuffle_before == comp_ctx->curr_func.needs_shuffle) { + /* Shuffle decision not changed. */ + break; + } + if (compile_round >= 3) { + /* Should never happen but avoid infinite loop just in case. */ + DUK_D( + DUK_DPRINT("more than 3 compile passes needed, should never happen")); + DUK_ERROR_INTERNAL(thr); + DUK_WO_NORETURN(return;); + } + DUK_D(DUK_DPRINT("need additional round to compile function, round now %d", + (int)compile_round)); + } + + /* + * Emit a final RETURN. + * + * It would be nice to avoid emitting an unnecessary "return" opcode + * if the current PC is not reachable. However, this cannot be reliably + * detected; even if the previous instruction is an unconditional jump, + * there may be a previous jump which jumps to current PC (which is the + * case for iteration and conditional statements, for instance). + */ + + /* XXX: request a "last statement is terminal" from duk__parse_stmt() and + * duk__parse_stmts(); we could avoid the last RETURN if we could ensure there + * is no way to get here (directly or via a jump) + */ + + DUK_ASSERT(comp_ctx->curr_func.catch_depth == 0); + if (reg_stmt_value >= 0) { + DUK_ASSERT(DUK__ISREG(reg_stmt_value)); + duk__emit_bc(comp_ctx, DUK_OP_RETREG, reg_stmt_value /*reg*/); + } else { + duk__emit_op_only(comp_ctx, DUK_OP_RETUNDEF); + } + + /* + * Peephole optimize JUMP chains. + */ + + duk__peephole_optimize_bytecode(comp_ctx); + + /* + * comp_ctx->curr_func is now ready to be converted into an actual + * function template. + */ + + DUK__RECURSION_DECREASE(comp_ctx, thr); + return; + +error_funcname: + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_FUNC_NAME); + DUK_WO_NORETURN(return;); +} + +/* + * Parse a function-like expression: + * + * - function expression + * - function declaration + * - function statement (non-standard) + * - setter/getter + * + * Adds the function to comp_ctx->curr_func function table and returns the + * function number. + * + * On entry, curr_token points to: + * + * - the token after 'function' for function expression/declaration/statement + * - the token after 'set' or 'get' for setter/getter + */ + +/* Parse formals. */ +DUK_LOCAL void duk__parse_func_formals(duk_compiler_ctx *comp_ctx) { + duk_hthread *thr = comp_ctx->thr; + duk_bool_t first = 1; + duk_uarridx_t n; + + for (;;) { + if (comp_ctx->curr_token.t == DUK_TOK_RPAREN) { + break; + } + + if (first) { + /* no comma */ + first = 0; + } else { + duk__advance_expect(comp_ctx, DUK_TOK_COMMA); + } + + /* Note: when parsing a formal list in non-strict context, e.g. + * "implements" is parsed as an identifier. When the function is + * later detected to be strict, the argument list must be rechecked + * against a larger set of reserved words (that of strict mode). + * This is handled by duk__parse_func_body(). Here we recognize + * whatever tokens are considered reserved in current strictness + * (which is not always enough). + */ + + if (comp_ctx->curr_token.t != DUK_TOK_IDENTIFIER) { + DUK_ERROR_SYNTAX(thr, DUK_STR_EXPECTED_IDENTIFIER); + DUK_WO_NORETURN(return;); + } + DUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_IDENTIFIER); + DUK_ASSERT(comp_ctx->curr_token.str1 != NULL); + DUK_DDD(DUK_DDDPRINT("formal argument: %!O", + (duk_heaphdr *)comp_ctx->curr_token.str1)); + + /* XXX: append primitive */ + duk_push_hstring(thr, comp_ctx->curr_token.str1); + n = (duk_uarridx_t)duk_get_length(thr, comp_ctx->curr_func.argnames_idx); + duk_put_prop_index(thr, comp_ctx->curr_func.argnames_idx, n); + + duk__advance(comp_ctx); /* eat identifier */ + } +} + +/* Parse a function-like expression, assuming that 'comp_ctx->curr_func' is + * correctly set up. Assumes that curr_token is just after 'function' (or + * 'set'/'get' etc). + */ +DUK_LOCAL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, + duk_small_uint_t flags) { + duk_hthread *thr = comp_ctx->thr; + duk_token *tok; + duk_bool_t no_advance; + + DUK_ASSERT(comp_ctx->curr_func.num_formals == 0); + DUK_ASSERT(comp_ctx->curr_func.is_function == 1); + DUK_ASSERT(comp_ctx->curr_func.is_eval == 0); + DUK_ASSERT(comp_ctx->curr_func.is_global == 0); + DUK_ASSERT(comp_ctx->curr_func.is_setget == + ((flags & DUK__FUNC_FLAG_GETSET) != 0)); + + duk__update_lineinfo_currtoken(comp_ctx); + + /* + * Function name (if any) + * + * We don't check for prohibited names here, because we don't + * yet know whether the function will be strict. Function body + * parsing handles this retroactively. + * + * For function expressions and declarations function name must + * be an Identifer (excludes reserved words). For setter/getter + * it is a PropertyName which allows reserved words and also + * strings and numbers (e.g. "{ get 1() { ... } }"). + * + * Function parsing may start either from prev_token or curr_token + * (object literal method definition uses prev_token for example). + * This is dealt with for the initial token. + */ + + no_advance = (flags & DUK__FUNC_FLAG_USE_PREVTOKEN); + if (no_advance) { + tok = &comp_ctx->prev_token; + } else { + tok = &comp_ctx->curr_token; + } + + if (flags & DUK__FUNC_FLAG_GETSET) { + /* PropertyName -> IdentifierName | StringLiteral | NumericLiteral */ + if (tok->t_nores == DUK_TOK_IDENTIFIER || tok->t == DUK_TOK_STRING) { + duk_push_hstring(thr, tok->str1); /* keep in valstack */ + } else if (tok->t == DUK_TOK_NUMBER) { + duk_push_number(thr, tok->num); + duk_to_string(thr, -1); + } else { + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_GETSET_NAME); + DUK_WO_NORETURN(return;); + } + comp_ctx->curr_func.h_name = + duk_known_hstring(thr, -1); /* borrowed reference */ + } else { + /* Function name is an Identifier (not IdentifierName), but we get + * the raw name (not recognizing keywords) here and perform the name + * checks only after pass 1. + */ + if (tok->t_nores == DUK_TOK_IDENTIFIER) { + duk_push_hstring(thr, tok->str1); /* keep in valstack */ + comp_ctx->curr_func.h_name = + duk_known_hstring(thr, -1); /* borrowed reference */ + } else { + /* valstack will be unbalanced, which is OK */ + DUK_ASSERT((flags & DUK__FUNC_FLAG_GETSET) == 0); + DUK_ASSERT(comp_ctx->curr_func.h_name == NULL); + no_advance = 1; + if (flags & DUK__FUNC_FLAG_DECL) { + DUK_ERROR_SYNTAX(thr, DUK_STR_FUNC_NAME_REQUIRED); + DUK_WO_NORETURN(return;); + } + } + } + + DUK_DD(DUK_DDPRINT("function name: %!O", + (duk_heaphdr *)comp_ctx->curr_func.h_name)); + + if (!no_advance) { + duk__advance(comp_ctx); + } + + /* + * Formal argument list + * + * We don't check for prohibited names or for duplicate argument + * names here, becase we don't yet know whether the function will + * be strict. Function body parsing handles this retroactively. + */ + + duk__advance_expect(comp_ctx, DUK_TOK_LPAREN); + + duk__parse_func_formals(comp_ctx); + + DUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RPAREN); + duk__advance(comp_ctx); + + /* + * Parse function body + */ + + duk__parse_func_body(comp_ctx, 0, /* expect_eof */ + 0, /* implicit_return_value */ + flags & DUK__FUNC_FLAG_DECL, /* regexp_after */ + DUK_TOK_LCURLY); /* expect_token */ + + /* + * Convert duk_compiler_func to a function template and add it + * to the parent function table. + */ + + duk__convert_to_func_template(comp_ctx); /* -> [ ... func ] */ +} + +/* Parse an inner function, adding the function template to the current + * function's function table. Return a function number to be used by the outer + * function. + * + * Avoiding O(depth^2) inner function parsing is handled here. On the first + * pass, compile and register the function normally into the 'funcs' array, also + * recording a lexer point (offset/line) to the closing brace of the function. + * On the second pass, skip the function and return the same 'fnum' as on the + * first pass by using a running counter. + * + * An unfortunate side effect of this is that when parsing the inner function, + * almost nothing is known of the outer function, i.e. the inner function's + * scope. We don't need that information at the moment, but it would allow some + * optimizations if it were used. + */ +DUK_LOCAL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, + duk_small_uint_t flags) { + duk_hthread *thr = comp_ctx->thr; + duk_compiler_func old_func; + duk_idx_t entry_top; + duk_int_t fnum; + + /* + * On second pass, skip the function. + */ + + if (!comp_ctx->curr_func.in_scanning) { + duk_lexer_point lex_pt; + + fnum = comp_ctx->curr_func.fnum_next++; + duk_get_prop_index(thr, comp_ctx->curr_func.funcs_idx, + (duk_uarridx_t)(fnum * 3 + 1)); + lex_pt.offset = (duk_size_t)duk_to_uint(thr, -1); + duk_pop(thr); + duk_get_prop_index(thr, comp_ctx->curr_func.funcs_idx, + (duk_uarridx_t)(fnum * 3 + 2)); + lex_pt.line = duk_to_int(thr, -1); + duk_pop(thr); + + DUK_DDD( + DUK_DDDPRINT("second pass of an inner func, skip the function, reparse " + "closing brace; lex offset=%ld, line=%ld", + (long)lex_pt.offset, (long)lex_pt.line)); + + DUK_LEXER_SETPOINT(&comp_ctx->lex, &lex_pt); + comp_ctx->curr_token.t = 0; /* this is needed for regexp mode */ + comp_ctx->curr_token.start_line = + 0; /* needed for line number tracking (becomes prev_token.start_line) */ + duk__advance(comp_ctx); + + /* RegExp is not allowed after a function expression, e.g. in + * (function () {} / 123). A RegExp *is* allowed after a + * function declaration! + */ + if (flags & DUK__FUNC_FLAG_DECL) { + comp_ctx->curr_func.allow_regexp_in_adv = 1; + } + duk__advance_expect(comp_ctx, DUK_TOK_RCURLY); + + return fnum; + } + + /* + * On first pass, perform actual parsing. Remember valstack top on entry + * to restore it later, and switch to using a new function in comp_ctx. + */ + + entry_top = duk_get_top(thr); + DUK_DDD(DUK_DDDPRINT("before func: entry_top=%ld, curr_tok.start_offset=%ld", + (long)entry_top, + (long)comp_ctx->curr_token.start_offset)); + + duk_memcpy(&old_func, &comp_ctx->curr_func, sizeof(duk_compiler_func)); + + duk_memzero(&comp_ctx->curr_func, sizeof(duk_compiler_func)); + duk__init_func_valstack_slots(comp_ctx); + DUK_ASSERT(comp_ctx->curr_func.num_formals == 0); + + /* inherit initial strictness from parent */ + comp_ctx->curr_func.is_strict = old_func.is_strict; + + /* XXX: It might be better to just store the flags into the curr_func + * struct and use them as is without this flag interpretation step + * here. + */ + DUK_ASSERT(comp_ctx->curr_func.is_notail == 0); + comp_ctx->curr_func.is_function = 1; + DUK_ASSERT(comp_ctx->curr_func.is_eval == 0); + DUK_ASSERT(comp_ctx->curr_func.is_global == 0); + comp_ctx->curr_func.is_setget = ((flags & DUK__FUNC_FLAG_GETSET) != 0); + comp_ctx->curr_func.is_namebinding = + !(flags & (DUK__FUNC_FLAG_GETSET | DUK__FUNC_FLAG_METDEF | + DUK__FUNC_FLAG_DECL)); /* no name binding for: declarations, + objlit getset, objlit method def */ + comp_ctx->curr_func.is_constructable = + !(flags & (DUK__FUNC_FLAG_GETSET | + DUK__FUNC_FLAG_METDEF)); /* not constructable: objlit getset, + objlit method def */ + + /* + * Parse inner function + */ + + duk__parse_func_like_raw(comp_ctx, flags); /* pushes function template */ + + /* prev_token.start_offset points to the closing brace here; when skipping + * we're going to reparse the closing brace to ensure semicolon insertion + * etc work as expected. + */ + DUK_DDD(DUK_DDDPRINT( + "after func: prev_tok.start_offset=%ld, curr_tok.start_offset=%ld", + (long)comp_ctx->prev_token.start_offset, + (long)comp_ctx->curr_token.start_offset)); + DUK_ASSERT(comp_ctx->lex.input[comp_ctx->prev_token.start_offset] == + (duk_uint8_t)DUK_ASC_RCURLY); + + /* XXX: append primitive */ + DUK_ASSERT(duk_get_length(thr, old_func.funcs_idx) == + (duk_size_t)(old_func.fnum_next * 3)); + fnum = old_func.fnum_next++; + + if (fnum > DUK__MAX_FUNCS) { + DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_FUNC_LIMIT); + DUK_WO_NORETURN(return 0;); + } + + /* array writes autoincrement length */ + (void)duk_put_prop_index(thr, old_func.funcs_idx, (duk_uarridx_t)(fnum * 3)); + duk_push_size_t(thr, comp_ctx->prev_token.start_offset); + (void)duk_put_prop_index(thr, old_func.funcs_idx, + (duk_uarridx_t)(fnum * 3 + 1)); + duk_push_int(thr, comp_ctx->prev_token.start_line); + (void)duk_put_prop_index(thr, old_func.funcs_idx, + (duk_uarridx_t)(fnum * 3 + 2)); + + /* + * Cleanup: restore original function, restore valstack state. + * + * Function declaration handling needs the function name to be pushed + * on the value stack. + */ + + if (flags & DUK__FUNC_FLAG_PUSHNAME_PASS1) { + DUK_ASSERT(comp_ctx->curr_func.h_name != NULL); + duk_push_hstring(thr, comp_ctx->curr_func.h_name); + duk_replace(thr, entry_top); + duk_set_top(thr, entry_top + 1); + } else { + duk_set_top(thr, entry_top); + } + duk_memcpy((void *)&comp_ctx->curr_func, (void *)&old_func, + sizeof(duk_compiler_func)); + + return fnum; +} + +/* + * Compile input string into an executable function template without + * arguments. + * + * The string is parsed as the "Program" production of ECMAScript E5. + * Compilation context can be either global code or eval code (see E5 + * Sections 14 and 15.1.2.1). + * + * Input stack: [ ... filename ] + * Output stack: [ ... func_template ] + */ + +/* XXX: source code property */ + +DUK_LOCAL duk_ret_t duk__js_compile_raw(duk_hthread *thr, void *udata) { + duk_hstring *h_filename; + duk__compiler_stkstate *comp_stk; + duk_compiler_ctx *comp_ctx; + duk_lexer_point *lex_pt; + duk_compiler_func *func; + duk_idx_t entry_top; + duk_bool_t is_strict; + duk_bool_t is_eval; + duk_bool_t is_funcexpr; + duk_small_uint_t flags; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(udata != NULL); + + /* + * Arguments check + */ + + entry_top = duk_get_top(thr); + DUK_ASSERT(entry_top >= 1); + + comp_stk = (duk__compiler_stkstate *)udata; + comp_ctx = &comp_stk->comp_ctx_alloc; + lex_pt = &comp_stk->lex_pt_alloc; + DUK_ASSERT(comp_ctx != NULL); + DUK_ASSERT(lex_pt != NULL); + + flags = comp_stk->flags; + is_eval = (flags & DUK_COMPILE_EVAL ? 1 : 0); + is_strict = (flags & DUK_COMPILE_STRICT ? 1 : 0); + is_funcexpr = (flags & DUK_COMPILE_FUNCEXPR ? 1 : 0); + + h_filename = duk_get_hstring(thr, -1); /* may be undefined */ + + /* + * Init compiler and lexer contexts + */ + + func = &comp_ctx->curr_func; +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + comp_ctx->thr = NULL; + comp_ctx->h_filename = NULL; + comp_ctx->prev_token.str1 = NULL; + comp_ctx->prev_token.str2 = NULL; + comp_ctx->curr_token.str1 = NULL; + comp_ctx->curr_token.str2 = NULL; +#endif + + duk_require_stack(thr, DUK__COMPILE_ENTRY_SLOTS); + + duk_push_dynamic_buffer(thr, 0); /* entry_top + 0 */ + duk_push_undefined(thr); /* entry_top + 1 */ + duk_push_undefined(thr); /* entry_top + 2 */ + duk_push_undefined(thr); /* entry_top + 3 */ + duk_push_undefined(thr); /* entry_top + 4 */ + + comp_ctx->thr = thr; + comp_ctx->h_filename = h_filename; + comp_ctx->tok11_idx = entry_top + 1; + comp_ctx->tok12_idx = entry_top + 2; + comp_ctx->tok21_idx = entry_top + 3; + comp_ctx->tok22_idx = entry_top + 4; + comp_ctx->recursion_limit = DUK_USE_COMPILER_RECLIMIT; + + /* comp_ctx->lex has been pre-initialized by caller: it has been + * zeroed and input/input_length has been set. + */ + comp_ctx->lex.thr = thr; + /* comp_ctx->lex.input and comp_ctx->lex.input_length filled by caller */ + comp_ctx->lex.slot1_idx = comp_ctx->tok11_idx; + comp_ctx->lex.slot2_idx = comp_ctx->tok12_idx; + comp_ctx->lex.buf_idx = entry_top + 0; + comp_ctx->lex.buf = + (duk_hbuffer_dynamic *)duk_known_hbuffer(thr, entry_top + 0); + DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(comp_ctx->lex.buf) && + !DUK_HBUFFER_HAS_EXTERNAL(comp_ctx->lex.buf)); + comp_ctx->lex.token_limit = DUK_COMPILER_TOKEN_LIMIT; + + lex_pt->offset = 0; + lex_pt->line = 1; + DUK_LEXER_SETPOINT(&comp_ctx->lex, lex_pt); /* fills window */ + comp_ctx->curr_token.start_line = + 0; /* needed for line number tracking (becomes prev_token.start_line) */ + + /* + * Initialize function state for a zero-argument function + */ + + duk__init_func_valstack_slots(comp_ctx); + DUK_ASSERT(func->num_formals == 0); + + if (is_funcexpr) { + /* Name will be filled from function expression, not by caller. + * This case is used by Function constructor and duk_compile() + * API with the DUK_COMPILE_FUNCTION option. + */ + DUK_ASSERT(func->h_name == NULL); + } else { + duk_push_hstring_stridx(thr, + (is_eval ? DUK_STRIDX_EVAL : DUK_STRIDX_GLOBAL)); + func->h_name = duk_get_hstring(thr, -1); + } + + /* + * Parse a function body or a function-like expression, depending + * on flags. + */ + + DUK_ASSERT(func->is_setget == 0); + func->is_strict = (duk_uint8_t)is_strict; + DUK_ASSERT(func->is_notail == 0); + + if (is_funcexpr) { + func->is_function = 1; + DUK_ASSERT(func->is_eval == 0); + DUK_ASSERT(func->is_global == 0); + func->is_namebinding = 1; + func->is_constructable = 1; + + duk__advance(comp_ctx); /* init 'curr_token' */ + duk__advance_expect(comp_ctx, DUK_TOK_FUNCTION); + (void)duk__parse_func_like_raw(comp_ctx, 0 /*flags*/); + } else { + DUK_ASSERT(func->is_function == 0); + DUK_ASSERT(is_eval == 0 || is_eval == 1); + func->is_eval = (duk_uint8_t)is_eval; + func->is_global = (duk_uint8_t)!is_eval; + DUK_ASSERT(func->is_namebinding == 0); + DUK_ASSERT(func->is_constructable == 0); + + duk__parse_func_body(comp_ctx, 1, /* expect_eof */ + 1, /* implicit_return_value */ + 1, /* regexp_after (does not matter) */ + -1); /* expect_token */ + } + + /* + * Convert duk_compiler_func to a function template + */ + + duk__convert_to_func_template(comp_ctx); + + /* + * Wrapping duk_safe_call() will mangle the stack, just return stack top + */ + + /* [ ... filename (temps) func ] */ + + return 1; +} + +DUK_INTERNAL void duk_js_compile(duk_hthread *thr, + const duk_uint8_t *src_buffer, + duk_size_t src_length, + duk_small_uint_t flags) { + duk__compiler_stkstate comp_stk; + duk_compiler_ctx *prev_ctx; + duk_ret_t safe_rc; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(src_buffer != NULL); + + /* preinitialize lexer state partially */ + duk_memzero(&comp_stk, sizeof(comp_stk)); + comp_stk.flags = flags; + DUK_LEXER_INITCTX(&comp_stk.comp_ctx_alloc.lex); + comp_stk.comp_ctx_alloc.lex.input = src_buffer; + comp_stk.comp_ctx_alloc.lex.input_length = src_length; + comp_stk.comp_ctx_alloc.lex.flags = + flags; /* Forward flags directly for now. */ + + /* [ ... filename ] */ + + prev_ctx = thr->compile_ctx; + thr->compile_ctx = &comp_stk.comp_ctx_alloc; /* for duk_error_augment.c */ + safe_rc = duk_safe_call(thr, duk__js_compile_raw, (void *)&comp_stk /*udata*/, + 1 /*nargs*/, 1 /*nrets*/); + thr->compile_ctx = prev_ctx; /* must restore reliably before returning */ + + if (safe_rc != DUK_EXEC_SUCCESS) { + DUK_D(DUK_DPRINT("compilation failed: %!T", duk_get_tval(thr, -1))); + (void)duk_throw(thr); + DUK_WO_NORETURN(return;); + } + + /* [ ... template ] */ +} diff --git a/third_party/duktape/duk_js_compiler.h b/third_party/duktape/duk_js_compiler.h new file mode 100644 index 00000000..06751748 --- /dev/null +++ b/third_party/duktape/duk_js_compiler.h @@ -0,0 +1,227 @@ +/* + * ECMAScript compiler. + */ + +#if !defined(DUK_JS_COMPILER_H_INCLUDED) +#define DUK_JS_COMPILER_H_INCLUDED + +/* ECMAScript compiler limits */ +#define DUK_COMPILER_TOKEN_LIMIT 100000000L /* 1e8: protects against deeply nested inner functions */ + +/* maximum loopcount for peephole optimization */ +#define DUK_COMPILER_PEEPHOLE_MAXITER 3 + +/* maximum bytecode length in instructions */ +#define DUK_COMPILER_MAX_BYTECODE_LENGTH (256L * 1024L * 1024L) /* 1 GB */ + +/* + * Compiler intermediate values + * + * Intermediate values describe either plain values (e.g. strings or + * numbers) or binary operations which have not yet been coerced into + * either a left-hand-side or right-hand-side role (e.g. object property). + */ + +#define DUK_IVAL_NONE 0 /* no value */ +#define DUK_IVAL_PLAIN 1 /* register, constant, or value */ +#define DUK_IVAL_ARITH 2 /* binary arithmetic; DUK_OP_ADD, DUK_OP_EQ, other binary ops */ +#define DUK_IVAL_PROP 3 /* property access */ +#define DUK_IVAL_VAR 4 /* variable access */ + +#define DUK_ISPEC_NONE 0 /* no value */ +#define DUK_ISPEC_VALUE 1 /* value resides in 'valstack_idx' */ +#define DUK_ISPEC_REGCONST 2 /* value resides in a register or constant */ + +/* Bit mask which indicates that a regconst is a constant instead of a register. + * Chosen so that when a regconst is cast to duk_int32_t, all consts are + * negative values. + */ +#define DUK_REGCONST_CONST_MARKER DUK_INT32_MIN /* = -0x80000000 */ + +/* Type to represent a reg/const reference during compilation, with <0 + * indicating a constant. Some call sites also use -1 to indicate 'none'. + */ +typedef duk_int32_t duk_regconst_t; + +typedef struct { + duk_small_uint_t t; /* DUK_ISPEC_XXX */ + duk_regconst_t regconst; + duk_idx_t valstack_idx; /* always set; points to a reserved valstack slot */ +} duk_ispec; + +typedef struct { + /* + * PLAIN: x1 + * ARITH: x1 x2 + * PROP: x1.x2 + * VAR: x1 (name) + */ + + /* XXX: can be optimized for smaller footprint esp. on 32-bit environments */ + duk_small_uint_t t; /* DUK_IVAL_XXX */ + duk_small_uint_t op; /* bytecode opcode for binary ops */ + duk_ispec x1; + duk_ispec x2; +} duk_ivalue; + +/* + * Bytecode instruction representation during compilation + * + * Contains the actual instruction and (optionally) debug info. + */ + +struct duk_compiler_instr { + duk_instr_t ins; +#if defined(DUK_USE_PC2LINE) + duk_uint32_t line; +#endif +}; + +/* + * Compiler state + */ + +#define DUK_LABEL_FLAG_ALLOW_BREAK (1U << 0) +#define DUK_LABEL_FLAG_ALLOW_CONTINUE (1U << 1) + +#define DUK_DECL_TYPE_VAR 0 +#define DUK_DECL_TYPE_FUNC 1 + +/* XXX: optimize to 16 bytes */ +typedef struct { + duk_small_uint_t flags; + duk_int_t label_id; /* numeric label_id (-1 reserved as marker) */ + duk_hstring *h_label; /* borrowed label name */ + duk_int_t catch_depth; /* catch depth at point of definition */ + duk_int_t pc_label; /* pc of label statement: + * pc+1: break jump site + * pc+2: continue jump site + */ + + /* Fast jumps (which avoid longjmp) jump directly to the jump sites + * which are always known even while the iteration/switch statement + * is still being parsed. A final peephole pass "straightens out" + * the jumps. + */ +} duk_labelinfo; + +/* Compiling state of one function, eventually converted to duk_hcompfunc */ +struct duk_compiler_func { + /* These pointers are at the start of the struct so that they pack + * nicely. Mixing pointers and integer values is bad on some + * platforms (e.g. if int is 32 bits and pointers are 64 bits). + */ + + duk_bufwriter_ctx bw_code; /* bufwriter for code */ + + duk_hstring *h_name; /* function name (borrowed reference), ends up in _name */ + /* h_code: held in bw_code */ + duk_hobject *h_consts; /* array */ + duk_hobject *h_funcs; /* array of function templates: [func1, offset1, line1, func2, offset2, line2] + * offset/line points to closing brace to allow skipping on pass 2 + */ + duk_hobject *h_decls; /* array of declarations: [ name1, val1, name2, val2, ... ] + * valN = (typeN) | (fnum << 8), where fnum is inner func number (0 for vars) + * record function and variable declarations in pass 1 + */ + duk_hobject *h_labelnames; /* array of active label names */ + duk_hbuffer_dynamic *h_labelinfos; /* C array of duk_labelinfo */ + duk_hobject *h_argnames; /* array of formal argument names (-> _Formals) */ + duk_hobject *h_varmap; /* variable map for pass 2 (identifier -> register number or null (unmapped)) */ + + /* Value stack indices for tracking objects. */ + /* code_idx: not needed */ + duk_idx_t consts_idx; + duk_idx_t funcs_idx; + duk_idx_t decls_idx; + duk_idx_t labelnames_idx; + duk_idx_t labelinfos_idx; + duk_idx_t argnames_idx; + duk_idx_t varmap_idx; + + /* Temp reg handling. */ + duk_regconst_t temp_first; /* first register that is a temporary (below: variables) */ + duk_regconst_t temp_next; /* next temporary register to allocate */ + duk_regconst_t temp_max; /* highest value of temp_reg (temp_max - 1 is highest used reg) */ + + /* Shuffle registers if large number of regs/consts. */ + duk_regconst_t shuffle1; + duk_regconst_t shuffle2; + duk_regconst_t shuffle3; + + /* Stats for current expression being parsed. */ + duk_int_t nud_count; + duk_int_t led_count; + duk_int_t paren_level; /* parenthesis count, 0 = top level */ + duk_bool_t expr_lhs; /* expression is left-hand-side compatible */ + duk_bool_t allow_in; /* current paren level allows 'in' token */ + + /* Misc. */ + duk_int_t stmt_next; /* statement id allocation (running counter) */ + duk_int_t label_next; /* label id allocation (running counter) */ + duk_int_t catch_depth; /* catch stack depth */ + duk_int_t with_depth; /* with stack depth (affects identifier lookups) */ + duk_int_t fnum_next; /* inner function numbering */ + duk_int_t num_formals; /* number of formal arguments */ + duk_regconst_t reg_stmt_value; /* register for writing value of 'non-empty' statements (global or eval code), -1 is marker */ +#if defined(DUK_USE_DEBUGGER_SUPPORT) + duk_int_t min_line; /* XXX: typing (duk_hcompfunc has duk_uint32_t) */ + duk_int_t max_line; +#endif + + /* Status booleans. */ + duk_uint8_t is_function; /* is an actual function (not global/eval code) */ + duk_uint8_t is_eval; /* is eval code */ + duk_uint8_t is_global; /* is global code */ + duk_uint8_t is_namebinding; /* needs a name binding */ + duk_uint8_t is_constructable; /* result is constructable */ + duk_uint8_t is_setget; /* is a setter/getter */ + duk_uint8_t is_strict; /* function is strict */ + duk_uint8_t is_notail; /* function must not be tail called */ + duk_uint8_t in_directive_prologue; /* parsing in "directive prologue", recognize directives */ + duk_uint8_t in_scanning; /* parsing in "scanning" phase (first pass) */ + duk_uint8_t may_direct_eval; /* function may call direct eval */ + duk_uint8_t id_access_arguments; /* function refers to 'arguments' identifier */ + duk_uint8_t id_access_slow; /* function makes one or more slow path accesses that won't match own static variables */ + duk_uint8_t id_access_slow_own; /* function makes one or more slow path accesses that may match own static variables */ + duk_uint8_t is_arguments_shadowed; /* argument/function declaration shadows 'arguments' */ + duk_uint8_t needs_shuffle; /* function needs shuffle registers */ + duk_uint8_t reject_regexp_in_adv; /* reject RegExp literal on next advance() call; needed for handling IdentifierName productions */ + duk_uint8_t allow_regexp_in_adv; /* allow RegExp literal on next advance() call */ +}; + +struct duk_compiler_ctx { + duk_hthread *thr; + + /* filename being compiled (ends up in functions' '_filename' property) */ + duk_hstring *h_filename; /* borrowed reference */ + + /* lexing (tokenization) state (contains two valstack slot indices) */ + duk_lexer_ctx lex; + + /* current and previous token for parsing */ + duk_token prev_token; + duk_token curr_token; + duk_idx_t tok11_idx; /* curr_token slot1 (matches 'lex' slot1_idx) */ + duk_idx_t tok12_idx; /* curr_token slot2 (matches 'lex' slot2_idx) */ + duk_idx_t tok21_idx; /* prev_token slot1 */ + duk_idx_t tok22_idx; /* prev_token slot2 */ + + /* recursion limit */ + duk_int_t recursion_depth; + duk_int_t recursion_limit; + + /* code emission temporary */ + duk_int_t emit_jumpslot_pc; + + /* current function being compiled (embedded instead of pointer for more compact access) */ + duk_compiler_func curr_func; +}; + +/* + * Prototypes + */ + +DUK_INTERNAL_DECL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer, duk_size_t src_length, duk_small_uint_t flags); + +#endif /* DUK_JS_COMPILER_H_INCLUDED */ diff --git a/third_party/duktape/duk_js_executor.c b/third_party/duktape/duk_js_executor.c new file mode 100644 index 00000000..375c9ccb --- /dev/null +++ b/third_party/duktape/duk_js_executor.c @@ -0,0 +1,5198 @@ +/* + * ECMAScript bytecode executor. + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Local declarations. + */ + +DUK_LOCAL_DECL void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, duk_activation *entry_act); + +/* + * Misc helpers. + */ + +/* Replace value stack top to value at 'tv_ptr'. Optimize for + * performance by only applying the net refcount change. + */ +#define DUK__REPLACE_TO_TVPTR(thr,tv_ptr) do { \ + duk_hthread *duk__thr; \ + duk_tval *duk__tvsrc; \ + duk_tval *duk__tvdst; \ + duk_tval duk__tvtmp; \ + duk__thr = (thr); \ + duk__tvsrc = DUK_GET_TVAL_NEGIDX(duk__thr, -1); \ + duk__tvdst = (tv_ptr); \ + DUK_TVAL_SET_TVAL(&duk__tvtmp, duk__tvdst); \ + DUK_TVAL_SET_TVAL(duk__tvdst, duk__tvsrc); \ + DUK_TVAL_SET_UNDEFINED(duk__tvsrc); /* value stack init policy */ \ + duk__thr->valstack_top = duk__tvsrc; \ + DUK_TVAL_DECREF(duk__thr, &duk__tvtmp); \ + } while (0) + +/* XXX: candidate of being an internal shared API call */ +#if 0 /* unused */ +DUK_LOCAL void duk__push_tvals_incref_only(duk_hthread *thr, duk_tval *tv_src, duk_small_uint_fast_t count) { + duk_tval *tv_dst; + duk_size_t copy_size; + duk_size_t i; + + tv_dst = thr->valstack_top; + copy_size = sizeof(duk_tval) * count; + duk_memcpy((void *) tv_dst, (const void *) tv_src, copy_size); + for (i = 0; i < count; i++) { + DUK_TVAL_INCREF(thr, tv_dst); + tv_dst++; + } + thr->valstack_top = tv_dst; +} +#endif + +/* + * Arithmetic, binary, and logical helpers. + * + * Note: there is no opcode for logical AND or logical OR; this is on + * purpose, because the evalution order semantics for them make such + * opcodes pretty pointless: short circuiting means they are most + * comfortably implemented as jumps. However, a logical NOT opcode + * is useful. + * + * Note: careful with duk_tval pointers here: they are potentially + * invalidated by any DECREF and almost any API call. It's still + * preferable to work without making a copy but that's not always + * possible. + */ + +DUK_LOCAL DUK_EXEC_ALWAYS_INLINE_PERF duk_double_t duk__compute_mod(duk_double_t d1, duk_double_t d2) { + return (duk_double_t) duk_js_arith_mod((double) d1, (double) d2); +} + +#if defined(DUK_USE_ES7_EXP_OPERATOR) +DUK_LOCAL DUK_EXEC_ALWAYS_INLINE_PERF duk_double_t duk__compute_exp(duk_double_t d1, duk_double_t d2) { + return (duk_double_t) duk_js_arith_pow((double) d1, (double) d2); +} +#endif + +DUK_LOCAL DUK_EXEC_ALWAYS_INLINE_PERF void duk__vm_arith_add(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_fast_t idx_z) { + /* + * Addition operator is different from other arithmetic + * operations in that it also provides string concatenation. + * Hence it is implemented separately. + * + * There is a fast path for number addition. Other cases go + * through potentially multiple coercions as described in the + * E5 specification. It may be possible to reduce the number + * of coercions, but this must be done carefully to preserve + * the exact semantics. + * + * E5 Section 11.6.1. + * + * Custom types also have special behavior implemented here. + */ + + duk_double_union du; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(tv_x != NULL); /* may be reg or const */ + DUK_ASSERT(tv_y != NULL); /* may be reg or const */ + DUK_ASSERT_DISABLE(idx_z >= 0); /* unsigned */ + DUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr)); + + /* + * Fast paths + */ + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) { + duk_int64_t v1, v2, v3; + duk_int32_t v3_hi; + duk_tval *tv_z; + + /* Input values are signed 48-bit so we can detect overflow + * reliably from high bits or just a comparison. + */ + + v1 = DUK_TVAL_GET_FASTINT(tv_x); + v2 = DUK_TVAL_GET_FASTINT(tv_y); + v3 = v1 + v2; + v3_hi = (duk_int32_t) (v3 >> 32); + if (DUK_LIKELY(v3_hi >= DUK_I64_CONSTANT(-0x8000) && v3_hi <= DUK_I64_CONSTANT(0x7fff))) { + tv_z = thr->valstack_bottom + idx_z; + DUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, v3); /* side effects */ + return; + } else { + /* overflow, fall through */ + ; + } + } +#endif /* DUK_USE_FASTINT */ + + if (DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y)) { +#if !defined(DUK_USE_EXEC_PREFER_SIZE) + duk_tval *tv_z; +#endif + + du.d = DUK_TVAL_GET_NUMBER(tv_x) + DUK_TVAL_GET_NUMBER(tv_y); +#if defined(DUK_USE_EXEC_PREFER_SIZE) + duk_push_number(thr, du.d); /* will NaN normalize result */ + duk_replace(thr, (duk_idx_t) idx_z); +#else /* DUK_USE_EXEC_PREFER_SIZE */ + DUK_DBLUNION_NORMALIZE_NAN_CHECK(&du); + DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du)); + tv_z = thr->valstack_bottom + idx_z; + DUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, du.d); /* side effects */ +#endif /* DUK_USE_EXEC_PREFER_SIZE */ + return; + } + + /* + * Slow path: potentially requires function calls for coercion + */ + + duk_push_tval(thr, tv_x); + duk_push_tval(thr, tv_y); + duk_to_primitive(thr, -2, DUK_HINT_NONE); /* side effects -> don't use tv_x, tv_y after */ + duk_to_primitive(thr, -1, DUK_HINT_NONE); + + /* Since Duktape 2.x plain buffers are treated like ArrayBuffer. */ + if (duk_is_string(thr, -2) || duk_is_string(thr, -1)) { + /* Symbols shouldn't technically be handled here, but should + * go into the default ToNumber() coercion path instead and + * fail there with a TypeError. However, there's a ToString() + * in duk_concat_2() which also fails with TypeError so no + * explicit check is needed. + */ + duk_concat_2(thr); /* [... s1 s2] -> [... s1+s2] */ + } else { + duk_double_t d1, d2; + + d1 = duk_to_number_m2(thr); + d2 = duk_to_number_m1(thr); + DUK_ASSERT(duk_is_number(thr, -2)); + DUK_ASSERT(duk_is_number(thr, -1)); + DUK_ASSERT_DOUBLE_IS_NORMALIZED(d1); + DUK_ASSERT_DOUBLE_IS_NORMALIZED(d2); + + du.d = d1 + d2; + duk_pop_2_unsafe(thr); + duk_push_number(thr, du.d); /* will NaN normalize result */ + } + duk_replace(thr, (duk_idx_t) idx_z); /* side effects */ +} + +DUK_LOCAL DUK_EXEC_ALWAYS_INLINE_PERF void duk__vm_arith_binary_op(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_uint_fast_t idx_z, duk_small_uint_fast_t opcode) { + /* + * Arithmetic operations other than '+' have number-only semantics + * and are implemented here. The separate switch-case here means a + * "double dispatch" of the arithmetic opcode, but saves code space. + * + * E5 Sections 11.5, 11.5.1, 11.5.2, 11.5.3, 11.6, 11.6.1, 11.6.2, 11.6.3. + */ + + duk_double_t d1, d2; + duk_double_union du; + duk_small_uint_fast_t opcode_shifted; +#if defined(DUK_USE_FASTINT) || !defined(DUK_USE_EXEC_PREFER_SIZE) + duk_tval *tv_z; +#endif + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(tv_x != NULL); /* may be reg or const */ + DUK_ASSERT(tv_y != NULL); /* may be reg or const */ + DUK_ASSERT_DISABLE(idx_z >= 0); /* unsigned */ + DUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr)); + + opcode_shifted = opcode >> 2; /* Get base opcode without reg/const modifiers. */ + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) { + duk_int64_t v1, v2, v3; + duk_int32_t v3_hi; + + v1 = DUK_TVAL_GET_FASTINT(tv_x); + v2 = DUK_TVAL_GET_FASTINT(tv_y); + + switch (opcode_shifted) { + case DUK_OP_SUB >> 2: { + v3 = v1 - v2; + break; + } + case DUK_OP_MUL >> 2: { + /* Must ensure result is 64-bit (no overflow); a + * simple and sufficient fast path is to allow only + * 32-bit inputs. Avoid zero inputs to avoid + * negative zero issues (-1 * 0 = -0, for instance). + */ + if (v1 >= DUK_I64_CONSTANT(-0x80000000) && v1 <= DUK_I64_CONSTANT(0x7fffffff) && v1 != 0 && + v2 >= DUK_I64_CONSTANT(-0x80000000) && v2 <= DUK_I64_CONSTANT(0x7fffffff) && v2 != 0) { + v3 = v1 * v2; + } else { + goto skip_fastint; + } + break; + } + case DUK_OP_DIV >> 2: { + /* Don't allow a zero divisor. Fast path check by + * "verifying" with multiplication. Also avoid zero + * dividend to avoid negative zero issues (0 / -1 = -0 + * for instance). + */ + if (v1 == 0 || v2 == 0) { + goto skip_fastint; + } + v3 = v1 / v2; + if (v3 * v2 != v1) { + goto skip_fastint; + } + break; + } + case DUK_OP_MOD >> 2: { + /* Don't allow a zero divisor. Restrict both v1 and + * v2 to positive values to avoid compiler specific + * behavior. + */ + if (v1 < 1 || v2 < 1) { + goto skip_fastint; + } + v3 = v1 % v2; + DUK_ASSERT(v3 >= 0); + DUK_ASSERT(v3 < v2); + DUK_ASSERT(v1 - (v1 / v2) * v2 == v3); + break; + } + default: { + /* Possible with DUK_OP_EXP. */ + goto skip_fastint; + } + } + + v3_hi = (duk_int32_t) (v3 >> 32); + if (DUK_LIKELY(v3_hi >= DUK_I64_CONSTANT(-0x8000) && v3_hi <= DUK_I64_CONSTANT(0x7fff))) { + tv_z = thr->valstack_bottom + idx_z; + DUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, v3); /* side effects */ + return; + } + /* fall through if overflow etc */ + } + skip_fastint: +#endif /* DUK_USE_FASTINT */ + + if (DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y)) { + /* fast path */ + d1 = DUK_TVAL_GET_NUMBER(tv_x); + d2 = DUK_TVAL_GET_NUMBER(tv_y); + } else { + duk_push_tval(thr, tv_x); + duk_push_tval(thr, tv_y); + d1 = duk_to_number_m2(thr); /* side effects */ + d2 = duk_to_number_m1(thr); + DUK_ASSERT(duk_is_number(thr, -2)); + DUK_ASSERT(duk_is_number(thr, -1)); + DUK_ASSERT_DOUBLE_IS_NORMALIZED(d1); + DUK_ASSERT_DOUBLE_IS_NORMALIZED(d2); + duk_pop_2_unsafe(thr); + } + + switch (opcode_shifted) { + case DUK_OP_SUB >> 2: { + du.d = d1 - d2; + break; + } + case DUK_OP_MUL >> 2: { + du.d = d1 * d2; + break; + } + case DUK_OP_DIV >> 2: { + /* Division-by-zero is undefined behavior, so + * rely on a helper. + */ + du.d = duk_double_div(d1, d2); + break; + } + case DUK_OP_MOD >> 2: { + du.d = duk__compute_mod(d1, d2); + break; + } +#if defined(DUK_USE_ES7_EXP_OPERATOR) + case DUK_OP_EXP >> 2: { + du.d = duk__compute_exp(d1, d2); + break; + } +#endif + default: { + DUK_UNREACHABLE(); + du.d = DUK_DOUBLE_NAN; /* should not happen */ + break; + } + } + +#if defined(DUK_USE_EXEC_PREFER_SIZE) + duk_push_number(thr, du.d); /* will NaN normalize result */ + duk_replace(thr, (duk_idx_t) idx_z); +#else /* DUK_USE_EXEC_PREFER_SIZE */ + /* important to use normalized NaN with 8-byte tagged types */ + DUK_DBLUNION_NORMALIZE_NAN_CHECK(&du); + DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du)); + tv_z = thr->valstack_bottom + idx_z; + DUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, du.d); /* side effects */ +#endif /* DUK_USE_EXEC_PREFER_SIZE */ +} + +DUK_LOCAL DUK_EXEC_ALWAYS_INLINE_PERF void duk__vm_bitwise_binary_op(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_fast_t idx_z, duk_small_uint_fast_t opcode) { + /* + * Binary bitwise operations use different coercions (ToInt32, ToUint32) + * depending on the operation. We coerce the arguments first using + * ToInt32(), and then cast to an 32-bit value if necessary. Note that + * such casts must be correct even if there is no native 32-bit type + * (e.g., duk_int32_t and duk_uint32_t are 64-bit). + * + * E5 Sections 11.10, 11.7.1, 11.7.2, 11.7.3 + */ + + duk_int32_t i1, i2, i3; + duk_uint32_t u1, u2, u3; +#if defined(DUK_USE_FASTINT) + duk_int64_t fi3; +#else + duk_double_t d3; +#endif + duk_small_uint_fast_t opcode_shifted; +#if defined(DUK_USE_FASTINT) || !defined(DUK_USE_EXEC_PREFER_SIZE) + duk_tval *tv_z; +#endif + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(tv_x != NULL); /* may be reg or const */ + DUK_ASSERT(tv_y != NULL); /* may be reg or const */ + DUK_ASSERT_DISABLE(idx_z >= 0); /* unsigned */ + DUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr)); + + opcode_shifted = opcode >> 2; /* Get base opcode without reg/const modifiers. */ + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) { + i1 = (duk_int32_t) DUK_TVAL_GET_FASTINT_I32(tv_x); + i2 = (duk_int32_t) DUK_TVAL_GET_FASTINT_I32(tv_y); + } + else +#endif /* DUK_USE_FASTINT */ + { + duk_push_tval(thr, tv_x); + duk_push_tval(thr, tv_y); + i1 = duk_to_int32(thr, -2); + i2 = duk_to_int32(thr, -1); + duk_pop_2_unsafe(thr); + } + + switch (opcode_shifted) { + case DUK_OP_BAND >> 2: { + i3 = i1 & i2; + break; + } + case DUK_OP_BOR >> 2: { + i3 = i1 | i2; + break; + } + case DUK_OP_BXOR >> 2: { + i3 = i1 ^ i2; + break; + } + case DUK_OP_BASL >> 2: { + /* Signed shift, named "arithmetic" (asl) because the result + * is signed, e.g. 4294967295 << 1 -> -2. Note that result + * must be masked. + */ + + u2 = ((duk_uint32_t) i2) & 0xffffffffUL; + i3 = (duk_int32_t) (((duk_uint32_t) i1) << (u2 & 0x1fUL)); /* E5 Section 11.7.1, steps 7 and 8 */ + i3 = i3 & ((duk_int32_t) 0xffffffffUL); /* Note: left shift, should mask */ + break; + } + case DUK_OP_BASR >> 2: { + /* signed shift */ + + u2 = ((duk_uint32_t) i2) & 0xffffffffUL; + i3 = i1 >> (u2 & 0x1fUL); /* E5 Section 11.7.2, steps 7 and 8 */ + break; + } + case DUK_OP_BLSR >> 2: { + /* unsigned shift */ + + u1 = ((duk_uint32_t) i1) & 0xffffffffUL; + u2 = ((duk_uint32_t) i2) & 0xffffffffUL; + + /* special result value handling */ + u3 = u1 >> (u2 & 0x1fUL); /* E5 Section 11.7.2, steps 7 and 8 */ +#if defined(DUK_USE_FASTINT) + fi3 = (duk_int64_t) u3; + goto fastint_result_set; +#else + d3 = (duk_double_t) u3; + goto result_set; +#endif + } + default: { + DUK_UNREACHABLE(); + i3 = 0; /* should not happen */ + break; + } + } + +#if defined(DUK_USE_FASTINT) + /* Result is always fastint compatible. */ + /* XXX: Set 32-bit result (but must then handle signed and + * unsigned results separately). + */ + fi3 = (duk_int64_t) i3; + + fastint_result_set: + tv_z = thr->valstack_bottom + idx_z; + DUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, fi3); /* side effects */ +#else /* DUK_USE_FASTINT */ + d3 = (duk_double_t) i3; + + result_set: + DUK_ASSERT(!DUK_ISNAN(d3)); /* 'd3' is never NaN, so no need to normalize */ + DUK_ASSERT_DOUBLE_IS_NORMALIZED(d3); /* always normalized */ + +#if defined(DUK_USE_EXEC_PREFER_SIZE) + duk_push_number(thr, d3); /* would NaN normalize result, but unnecessary */ + duk_replace(thr, (duk_idx_t) idx_z); +#else /* DUK_USE_EXEC_PREFER_SIZE */ + tv_z = thr->valstack_bottom + idx_z; + DUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, d3); /* side effects */ +#endif /* DUK_USE_EXEC_PREFER_SIZE */ +#endif /* DUK_USE_FASTINT */ +} + +/* In-place unary operation. */ +DUK_LOCAL DUK_EXEC_ALWAYS_INLINE_PERF void duk__vm_arith_unary_op(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst, duk_small_uint_fast_t opcode) { + /* + * Arithmetic operations other than '+' have number-only semantics + * and are implemented here. The separate switch-case here means a + * "double dispatch" of the arithmetic opcode, but saves code space. + * + * E5 Sections 11.5, 11.5.1, 11.5.2, 11.5.3, 11.6, 11.6.1, 11.6.2, 11.6.3. + */ + + duk_tval *tv; + duk_double_t d1; + duk_double_union du; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(opcode == DUK_OP_UNM || opcode == DUK_OP_UNP); + DUK_ASSERT_DISABLE(idx_src >= 0); + DUK_ASSERT_DISABLE(idx_dst >= 0); + + tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src); + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv)) { + duk_int64_t v1, v2; + + v1 = DUK_TVAL_GET_FASTINT(tv); + if (opcode == DUK_OP_UNM) { + /* The smallest fastint is no longer 48-bit when + * negated. Positive zero becames negative zero + * (cannot be represented) when negated. + */ + if (DUK_LIKELY(v1 != DUK_FASTINT_MIN && v1 != 0)) { + v2 = -v1; + tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst); + DUK_TVAL_SET_FASTINT_UPDREF(thr, tv, v2); + return; + } + } else { + /* ToNumber() for a fastint is a no-op. */ + DUK_ASSERT(opcode == DUK_OP_UNP); + v2 = v1; + tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst); + DUK_TVAL_SET_FASTINT_UPDREF(thr, tv, v2); + return; + } + /* fall through if overflow etc */ + } +#endif /* DUK_USE_FASTINT */ + + if (DUK_TVAL_IS_NUMBER(tv)) { + d1 = DUK_TVAL_GET_NUMBER(tv); + } else { + d1 = duk_to_number_tval(thr, tv); /* side effects */ + } + + if (opcode == DUK_OP_UNP) { + /* ToNumber() for a double is a no-op, but unary plus is + * used to force a fastint check so do that here. + */ + du.d = d1; + DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du)); +#if defined(DUK_USE_FASTINT) + tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst); + DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF(thr, tv, du.d); /* always 'fast', i.e. inlined */ + return; +#endif + } else { + DUK_ASSERT(opcode == DUK_OP_UNM); + du.d = -d1; + DUK_DBLUNION_NORMALIZE_NAN_CHECK(&du); /* mandatory if du.d is a NaN */ + DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du)); + } + + /* XXX: size optimize: push+replace? */ + tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst); + DUK_TVAL_SET_NUMBER_UPDREF(thr, tv, du.d); +} + +DUK_LOCAL DUK_EXEC_ALWAYS_INLINE_PERF void duk__vm_bitwise_not(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst) { + /* + * E5 Section 11.4.8 + */ + + duk_tval *tv; + duk_int32_t i1, i2; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT_DISABLE(idx_src >= 0); + DUK_ASSERT_DISABLE(idx_dst >= 0); + DUK_ASSERT((duk_uint_t) idx_src < (duk_uint_t) duk_get_top(thr)); + DUK_ASSERT((duk_uint_t) idx_dst < (duk_uint_t) duk_get_top(thr)); + + tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src); + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv)) { + i1 = (duk_int32_t) DUK_TVAL_GET_FASTINT_I32(tv); + } + else +#endif /* DUK_USE_FASTINT */ + { + duk_push_tval(thr, tv); + i1 = duk_to_int32(thr, -1); /* side effects */ + duk_pop_unsafe(thr); + } + + /* Result is always fastint compatible. */ + i2 = ~i1; + tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst); + DUK_TVAL_SET_I32_UPDREF(thr, tv, i2); /* side effects */ +} + +DUK_LOCAL DUK_EXEC_ALWAYS_INLINE_PERF void duk__vm_logical_not(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst) { + /* + * E5 Section 11.4.9 + */ + + duk_tval *tv; + duk_bool_t res; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT_DISABLE(idx_src >= 0); + DUK_ASSERT_DISABLE(idx_dst >= 0); + DUK_ASSERT((duk_uint_t) idx_src < (duk_uint_t) duk_get_top(thr)); + DUK_ASSERT((duk_uint_t) idx_dst < (duk_uint_t) duk_get_top(thr)); + + /* ToBoolean() does not require any operations with side effects so + * we can do it efficiently. For footprint it would be better to use + * duk_js_toboolean() and then push+replace to the result slot. + */ + tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src); + res = duk_js_toboolean(tv); /* does not modify 'tv' */ + DUK_ASSERT(res == 0 || res == 1); + res ^= 1; + tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst); + /* XXX: size optimize: push+replace? */ + DUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv, res); /* side effects */ +} + +/* XXX: size optimized variant */ +DUK_LOCAL DUK_EXEC_ALWAYS_INLINE_PERF void duk__prepost_incdec_reg_helper(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_small_uint_t op) { + duk_double_t x, y, z; + + /* Two lowest bits of opcode are used to distinguish + * variants. Bit 0 = inc(0)/dec(1), bit 1 = pre(0)/post(1). + */ + DUK_ASSERT((DUK_OP_PREINCR & 0x03) == 0x00); + DUK_ASSERT((DUK_OP_PREDECR & 0x03) == 0x01); + DUK_ASSERT((DUK_OP_POSTINCR & 0x03) == 0x02); + DUK_ASSERT((DUK_OP_POSTDECR & 0x03) == 0x03); + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv_src)) { + duk_int64_t x_fi, y_fi, z_fi; + x_fi = DUK_TVAL_GET_FASTINT(tv_src); + if (op & 0x01) { + if (DUK_UNLIKELY(x_fi == DUK_FASTINT_MIN)) { + goto skip_fastint; + } + y_fi = x_fi - 1; + } else { + if (DUK_UNLIKELY(x_fi == DUK_FASTINT_MAX)) { + goto skip_fastint; + } + y_fi = x_fi + 1; + } + + DUK_TVAL_SET_FASTINT(tv_src, y_fi); /* no need for refcount update */ + + z_fi = (op & 0x02) ? x_fi : y_fi; + DUK_TVAL_SET_FASTINT_UPDREF(thr, tv_dst, z_fi); /* side effects */ + return; + } + skip_fastint: +#endif + if (DUK_TVAL_IS_NUMBER(tv_src)) { + /* Fast path for the case where the register + * is a number (e.g. loop counter). + */ + + x = DUK_TVAL_GET_NUMBER(tv_src); + if (op & 0x01) { + y = x - 1.0; + } else { + y = x + 1.0; + } + + DUK_TVAL_SET_NUMBER(tv_src, y); /* no need for refcount update */ + } else { + /* Preserve duk_tval pointer(s) across a potential valstack + * resize by converting them into offsets temporarily. + */ + duk_idx_t bc; + duk_size_t off_dst; + + off_dst = (duk_size_t) ((duk_uint8_t *) tv_dst - (duk_uint8_t *) thr->valstack_bottom); + bc = (duk_idx_t) (tv_src - thr->valstack_bottom); /* XXX: pass index explicitly? */ + tv_src = NULL; /* no longer referenced */ + + x = duk_to_number(thr, bc); + if (op & 0x01) { + y = x - 1.0; + } else { + y = x + 1.0; + } + + duk_push_number(thr, y); + duk_replace(thr, bc); + + tv_dst = (duk_tval *) (void *) (((duk_uint8_t *) thr->valstack_bottom) + off_dst); + } + + z = (op & 0x02) ? x : y; + DUK_TVAL_SET_NUMBER_UPDREF(thr, tv_dst, z); /* side effects */ +} + +DUK_LOCAL DUK_EXEC_ALWAYS_INLINE_PERF void duk__prepost_incdec_var_helper(duk_hthread *thr, duk_small_uint_t idx_dst, duk_tval *tv_id, duk_small_uint_t op, duk_small_uint_t is_strict) { + duk_activation *act; + duk_double_t x, y; + duk_hstring *name; + + /* XXX: The pre/post inc/dec for an identifier lookup is + * missing the important fast path where the identifier + * has a storage location e.g. in a scope object so that + * it can be updated in-place. In particular, the case + * where the identifier has a storage location AND the + * previous value is a number should be optimized because + * it's side effect free. + */ + + /* Two lowest bits of opcode are used to distinguish + * variants. Bit 0 = inc(0)/dec(1), bit 1 = pre(0)/post(1). + */ + DUK_ASSERT((DUK_OP_PREINCV & 0x03) == 0x00); + DUK_ASSERT((DUK_OP_PREDECV & 0x03) == 0x01); + DUK_ASSERT((DUK_OP_POSTINCV & 0x03) == 0x02); + DUK_ASSERT((DUK_OP_POSTDECV & 0x03) == 0x03); + + DUK_ASSERT(DUK_TVAL_IS_STRING(tv_id)); + name = DUK_TVAL_GET_STRING(tv_id); + DUK_ASSERT(name != NULL); + act = thr->callstack_curr; + (void) duk_js_getvar_activation(thr, act, name, 1 /*throw*/); /* -> [ ... val this ] */ + + /* XXX: Fastint fast path would be useful here. Also fastints + * now lose their fastint status in current handling which is + * not intuitive. + */ + + x = duk_to_number_m2(thr); + if (op & 0x01) { + y = x - 1.0; + } else { + y = x + 1.0; + } + + /* [... x this] */ + + if (op & 0x02) { + duk_push_number(thr, y); /* -> [ ... x this y ] */ + DUK_ASSERT(act == thr->callstack_curr); + duk_js_putvar_activation(thr, act, name, DUK_GET_TVAL_NEGIDX(thr, -1), is_strict); + duk_pop_2_unsafe(thr); /* -> [ ... x ] */ + } else { + duk_pop_2_unsafe(thr); /* -> [ ... ] */ + duk_push_number(thr, y); /* -> [ ... y ] */ + DUK_ASSERT(act == thr->callstack_curr); + duk_js_putvar_activation(thr, act, name, DUK_GET_TVAL_NEGIDX(thr, -1), is_strict); + } + +#if defined(DUK_USE_EXEC_PREFER_SIZE) + duk_replace(thr, (duk_idx_t) idx_dst); +#else /* DUK_USE_EXEC_PREFER_SIZE */ + DUK__REPLACE_TO_TVPTR(thr, DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst)); +#endif /* DUK_USE_EXEC_PREFER_SIZE */ +} + +/* + * Longjmp and other control flow transfer for the bytecode executor. + * + * The longjmp handler can handle all longjmp types: error, yield, and + * resume (pseudotypes are never actually thrown). + * + * Error policy for longjmp: should not ordinarily throw errors; if errors + * occur (e.g. due to out-of-memory) they bubble outwards rather than being + * handled recursively. + */ + +#define DUK__LONGJMP_RESTART 0 /* state updated, restart bytecode execution */ +#define DUK__LONGJMP_RETHROW 1 /* exit bytecode executor by rethrowing an error to caller */ + +#define DUK__RETHAND_RESTART 0 /* state updated, restart bytecode execution */ +#define DUK__RETHAND_FINISHED 1 /* exit bytecode execution with return value */ + +/* XXX: optimize reconfig valstack operations so that resize, clamp, and setting + * top are combined into one pass. + */ + +/* Reconfigure value stack for return to an ECMAScript function at + * callstack top (caller unwinds). + */ +DUK_LOCAL void duk__reconfig_valstack_ecma_return(duk_hthread *thr) { + duk_activation *act; + duk_hcompfunc *h_func; + duk_idx_t clamp_top; + + DUK_ASSERT(thr != NULL); + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + DUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act))); + + /* Clamp so that values at 'clamp_top' and above are wiped and won't + * retain reachable garbage. Then extend to 'nregs' because we're + * returning to an ECMAScript function. + */ + + h_func = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act); + + thr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff); + DUK_ASSERT(act->retval_byteoff >= act->bottom_byteoff); + clamp_top = (duk_idx_t) ((act->retval_byteoff - act->bottom_byteoff + sizeof(duk_tval)) / sizeof(duk_tval)); /* +1 = one retval */ + duk_set_top_and_wipe(thr, h_func->nregs, clamp_top); + + DUK_ASSERT((duk_uint8_t *) thr->valstack_end >= (duk_uint8_t *) thr->valstack + act->reserve_byteoff); + thr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->reserve_byteoff); + + /* XXX: a best effort shrink check would be OK here */ +} + +/* Reconfigure value stack for an ECMAScript catcher. Use topmost catcher + * in 'act'. + */ +DUK_LOCAL void duk__reconfig_valstack_ecma_catcher(duk_hthread *thr, duk_activation *act) { + duk_catcher *cat; + duk_hcompfunc *h_func; + duk_size_t idx_bottom; + duk_idx_t clamp_top; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(act != NULL); + DUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act))); + cat = act->cat; + DUK_ASSERT(cat != NULL); + + h_func = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act); + + thr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff); + idx_bottom = (duk_size_t) (thr->valstack_bottom - thr->valstack); + DUK_ASSERT(cat->idx_base >= idx_bottom); + clamp_top = (duk_idx_t) (cat->idx_base - idx_bottom + 2); /* +2 = catcher value, catcher lj_type */ + duk_set_top_and_wipe(thr, h_func->nregs, clamp_top); + + DUK_ASSERT((duk_uint8_t *) thr->valstack_end >= (duk_uint8_t *) thr->valstack + act->reserve_byteoff); + thr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->reserve_byteoff); + + /* XXX: a best effort shrink check would be OK here */ +} + +/* Set catcher regs: idx_base+0 = value, idx_base+1 = lj_type. + * No side effects. + */ +DUK_LOCAL void duk__set_catcher_regs_norz(duk_hthread *thr, duk_catcher *cat, duk_tval *tv_val_unstable, duk_small_uint_t lj_type) { + duk_tval *tv1; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(tv_val_unstable != NULL); + + tv1 = thr->valstack + cat->idx_base; + DUK_ASSERT(tv1 < thr->valstack_top); + DUK_TVAL_SET_TVAL_UPDREF_NORZ(thr, tv1, tv_val_unstable); + + tv1++; + DUK_ASSERT(tv1 == thr->valstack + cat->idx_base + 1); + DUK_ASSERT(tv1 < thr->valstack_top); + DUK_TVAL_SET_U32_UPDREF_NORZ(thr, tv1, (duk_uint32_t) lj_type); +} + +DUK_LOCAL void duk__handle_catch_part1(duk_hthread *thr, duk_tval *tv_val_unstable, duk_small_uint_t lj_type, volatile duk_bool_t *out_delayed_catch_setup) { + duk_activation *act; + duk_catcher *cat; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(tv_val_unstable != NULL); + + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + DUK_DD(DUK_DDPRINT("handle catch, part 1; act=%!A, cat=%!C", act, act->cat)); + + DUK_ASSERT(act->cat != NULL); + DUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF); + + /* The part1/part2 split could also be made here at the very top + * of catch handling. Value stack would be reconfigured inside + * part2's protection. Value stack reconfiguration should be free + * of allocs, however. + */ + + duk__set_catcher_regs_norz(thr, act->cat, tv_val_unstable, lj_type); + + DUK_ASSERT(thr->callstack_top >= 1); + DUK_ASSERT(thr->callstack_curr != NULL); + DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr))); + + DUK_ASSERT(thr->callstack_top >= 1); + DUK_ASSERT(act == thr->callstack_curr); + DUK_ASSERT(act != NULL); + duk__reconfig_valstack_ecma_catcher(thr, act); + + DUK_ASSERT(thr->callstack_top >= 1); + DUK_ASSERT(act == thr->callstack_curr); + DUK_ASSERT(act != NULL); + cat = act->cat; + DUK_ASSERT(cat != NULL); + + act->curr_pc = cat->pc_base + 0; /* +0 = catch */ + + /* + * If the catch block has an automatic catch variable binding, + * we need to create a lexical environment for it which requires + * allocations. Move out of "error handling state" before the + * allocations to avoid e.g. out-of-memory errors (leading to + * GH-2022 or similar). + */ + + if (DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat)) { + DUK_DDD(DUK_DDDPRINT("catcher has an automatic catch binding, handle in part 2")); + *out_delayed_catch_setup = 1; + } else { + DUK_DDD(DUK_DDDPRINT("catcher has no catch binding")); + } + + DUK_CAT_CLEAR_CATCH_ENABLED(cat); +} + +DUK_LOCAL void duk__handle_catch_part2(duk_hthread *thr) { + duk_activation *act; + duk_catcher *cat; + duk_hdecenv *new_env; + + DUK_ASSERT(thr != NULL); + + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + DUK_DD(DUK_DDPRINT("handle catch, part 2; act=%!A, cat=%!C", act, act->cat)); + + DUK_ASSERT(act->cat != NULL); + cat = act->cat; + DUK_ASSERT(cat != NULL); + DUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF); + DUK_ASSERT(DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat)); + DUK_ASSERT(thr->valstack + cat->idx_base < thr->valstack_top); + + /* + * Create lexical environment for the catch clause, containing + * a binding for the caught value. + * + * The binding is mutable (= writable) but not deletable. + * Step 4 for the catch production in E5 Section 12.14; + * no value is given for CreateMutableBinding 'D' argument, + * which implies the binding is not deletable. + */ + + if (act->lex_env == NULL) { + DUK_ASSERT(act->var_env == NULL); + DUK_DDD(DUK_DDDPRINT("delayed environment initialization")); + + duk_js_init_activation_environment_records_delayed(thr, act); + DUK_ASSERT(act == thr->callstack_curr); + DUK_ASSERT(act != NULL); + } + DUK_ASSERT(act->lex_env != NULL); + DUK_ASSERT(act->var_env != NULL); + DUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL); + + new_env = duk_hdecenv_alloc(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV)); + DUK_ASSERT(new_env != NULL); + duk_push_hobject(thr, (duk_hobject *) new_env); + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL); + DUK_DDD(DUK_DDDPRINT("new_env allocated: %!iO", (duk_heaphdr *) new_env)); + + /* Note: currently the catch binding is handled without a register + * binding because we don't support dynamic register bindings (they + * must be fixed for an entire function). So, there is no need to + * record regbases etc. + */ + + /* [ ...env ] */ + + DUK_ASSERT(cat->h_varname != NULL); + duk_push_hstring(thr, cat->h_varname); + DUK_ASSERT(thr->valstack + cat->idx_base < thr->valstack_top); + duk_push_tval(thr, thr->valstack + cat->idx_base); + duk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_W); /* writable, not configurable */ + + /* [ ... env ] */ + + DUK_ASSERT(act == thr->callstack_curr); + DUK_ASSERT(act != NULL); + DUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, act->lex_env); + act->lex_env = (duk_hobject *) new_env; + DUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env); /* reachable through activation */ + /* Net refcount change to act->lex_env is 0: incref for new_env's + * prototype, decref for act->lex_env overwrite. + */ + + DUK_CAT_SET_LEXENV_ACTIVE(cat); + + duk_pop_unsafe(thr); + + DUK_DDD(DUK_DDDPRINT("new_env finished: %!iO", (duk_heaphdr *) new_env)); +} + +DUK_LOCAL void duk__handle_finally(duk_hthread *thr, duk_tval *tv_val_unstable, duk_small_uint_t lj_type) { + duk_activation *act; + duk_catcher *cat; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(tv_val_unstable != NULL); + + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + DUK_ASSERT(act->cat != NULL); + DUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF); + + duk__set_catcher_regs_norz(thr, act->cat, tv_val_unstable, lj_type); + + DUK_ASSERT(thr->callstack_top >= 1); + DUK_ASSERT(thr->callstack_curr != NULL); + DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr))); + + DUK_ASSERT(thr->callstack_top >= 1); + DUK_ASSERT(act == thr->callstack_curr); + DUK_ASSERT(act != NULL); + duk__reconfig_valstack_ecma_catcher(thr, act); + + DUK_ASSERT(thr->callstack_top >= 1); + DUK_ASSERT(act == thr->callstack_curr); + DUK_ASSERT(act != NULL); + cat = act->cat; + DUK_ASSERT(cat != NULL); + + act->curr_pc = cat->pc_base + 1; /* +1 = finally */ + + DUK_CAT_CLEAR_FINALLY_ENABLED(cat); +} + +DUK_LOCAL void duk__handle_label(duk_hthread *thr, duk_small_uint_t lj_type) { + duk_activation *act; + duk_catcher *cat; + + DUK_ASSERT(thr != NULL); + + DUK_ASSERT(thr->callstack_top >= 1); + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + DUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL); + DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(DUK_ACT_GET_FUNC(act))); + + /* +0 = break, +1 = continue */ + cat = act->cat; + DUK_ASSERT(cat != NULL); + DUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_LABEL); + + act->curr_pc = cat->pc_base + (lj_type == DUK_LJ_TYPE_CONTINUE ? 1 : 0); + + /* valstack should not need changes */ +#if defined(DUK_USE_ASSERTIONS) + DUK_ASSERT(thr->callstack_top >= 1); + DUK_ASSERT(act == thr->callstack_curr); + DUK_ASSERT(act != NULL); + DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) == + (duk_size_t) ((duk_hcompfunc *) DUK_ACT_GET_FUNC(act))->nregs); +#endif +} + +/* Called for handling both a longjmp() with type DUK_LJ_TYPE_YIELD and + * when a RETURN opcode terminates a thread and yields to the resumer. + * Caller unwinds so that top of callstack is the activation we return to. + */ +#if defined(DUK_USE_COROUTINE_SUPPORT) +DUK_LOCAL void duk__handle_yield(duk_hthread *thr, duk_hthread *resumer, duk_tval *tv_val_unstable) { + duk_activation *act_resumer; + duk_tval *tv1; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(resumer != NULL); + DUK_ASSERT(tv_val_unstable != NULL); + act_resumer = resumer->callstack_curr; + DUK_ASSERT(act_resumer != NULL); + DUK_ASSERT(DUK_ACT_GET_FUNC(act_resumer) != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act_resumer))); /* resume caller must be an ECMAScript func */ + + tv1 = (duk_tval *) (void *) ((duk_uint8_t *) resumer->valstack + act_resumer->retval_byteoff); /* return value from Duktape.Thread.resume() */ + DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv_val_unstable); /* side effects */ /* XXX: avoid side effects */ + + duk__reconfig_valstack_ecma_return(resumer); + + /* caller must change active thread, and set thr->resumer to NULL */ +} +#endif /* DUK_USE_COROUTINE_SUPPORT */ + +DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation *entry_act, volatile duk_bool_t *out_delayed_catch_setup) { + duk_small_uint_t retval = DUK__LONGJMP_RESTART; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(entry_act != NULL); + + /* 'thr' is the current thread, as no-one resumes except us and we + * switch 'thr' in that case. + */ + DUK_ASSERT(thr == thr->heap->curr_thread); + + /* + * (Re)try handling the longjmp. + * + * A longjmp handler may convert the longjmp to a different type and + * "virtually" rethrow by goto'ing to 'check_longjmp'. Before the goto, + * the following must be updated: + * - the heap 'lj' state + * - 'thr' must reflect the "throwing" thread + */ + + check_longjmp: + + DUK_DD(DUK_DDPRINT("handling longjmp: type=%ld, value1=%!T, value2=%!T, iserror=%ld, top=%ld", + (long) thr->heap->lj.type, + (duk_tval *) &thr->heap->lj.value1, + (duk_tval *) &thr->heap->lj.value2, + (long) thr->heap->lj.iserror, + (long) duk_get_top(thr))); + + switch (thr->heap->lj.type) { + +#if defined(DUK_USE_COROUTINE_SUPPORT) + case DUK_LJ_TYPE_RESUME: { + /* + * Note: lj.value1 is 'value', lj.value2 is 'resumee'. + * This differs from YIELD. + */ + + duk_tval *tv; + duk_tval *tv2; + duk_hthread *resumee; + + /* duk_bi_duk_object_yield() and duk_bi_duk_object_resume() ensure all of these are met */ + + DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING); /* unchanged by Duktape.Thread.resume() */ + DUK_ASSERT(thr->callstack_top >= 2); /* ECMAScript activation + Duktape.Thread.resume() activation */ + DUK_ASSERT(thr->callstack_curr != NULL); + DUK_ASSERT(thr->callstack_curr->parent != NULL); + DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL && + DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)) && + ((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->callstack_curr))->func == duk_bi_thread_resume); + + tv = &thr->heap->lj.value2; /* resumee */ + DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv)); + DUK_ASSERT(DUK_TVAL_GET_OBJECT(tv) != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_THREAD(DUK_TVAL_GET_OBJECT(tv))); + resumee = (duk_hthread *) DUK_TVAL_GET_OBJECT(tv); + + DUK_ASSERT(resumee != NULL); + DUK_ASSERT(resumee->resumer == NULL); + DUK_ASSERT(resumee->state == DUK_HTHREAD_STATE_INACTIVE || + resumee->state == DUK_HTHREAD_STATE_YIELDED); /* checked by Duktape.Thread.resume() */ + DUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_YIELDED || + resumee->callstack_top >= 2); /* YIELDED: ECMAScript activation + Duktape.Thread.yield() activation */ + DUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_YIELDED || + (DUK_ACT_GET_FUNC(resumee->callstack_curr) != NULL && + DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(resumee->callstack_curr)) && + ((duk_hnatfunc *) DUK_ACT_GET_FUNC(resumee->callstack_curr))->func == duk_bi_thread_yield)); + DUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_INACTIVE || + resumee->callstack_top == 0); /* INACTIVE: no activation, single function value on valstack */ + + if (thr->heap->lj.iserror) { + /* + * Throw the error in the resumed thread's context; the + * error value is pushed onto the resumee valstack. + * + * Note: the callstack of the target may empty in this case + * too (i.e. the target thread has never been resumed). The + * value stack will contain the initial function in that case, + * which we simply ignore. + */ + + DUK_ASSERT(resumee->resumer == NULL); + resumee->resumer = thr; + DUK_HTHREAD_INCREF(thr, thr); + resumee->state = DUK_HTHREAD_STATE_RUNNING; + thr->state = DUK_HTHREAD_STATE_RESUMED; + DUK_HEAP_SWITCH_THREAD(thr->heap, resumee); + thr = resumee; + + thr->heap->lj.type = DUK_LJ_TYPE_THROW; + + /* thr->heap->lj.value1 is already the value to throw */ + /* thr->heap->lj.value2 is 'thread', will be wiped out at the end */ + + DUK_ASSERT(thr->heap->lj.iserror); /* already set */ + + DUK_DD(DUK_DDPRINT("-> resume with an error, converted to a throw in the resumee, propagate")); + goto check_longjmp; + } else if (resumee->state == DUK_HTHREAD_STATE_YIELDED) { + /* Unwind previous Duktape.Thread.yield() call. The + * activation remaining must always be an ECMAScript + * call now (yield() accepts calls from ECMAScript + * only). + */ + duk_activation *act_resumee; + + DUK_ASSERT(resumee->callstack_top >= 2); + act_resumee = resumee->callstack_curr; /* Duktape.Thread.yield() */ + DUK_ASSERT(act_resumee != NULL); + act_resumee = act_resumee->parent; /* ECMAScript call site for yield() */ + DUK_ASSERT(act_resumee != NULL); + + tv = (duk_tval *) (void *) ((duk_uint8_t *) resumee->valstack + act_resumee->retval_byteoff); /* return value from Duktape.Thread.yield() */ + DUK_ASSERT(tv >= resumee->valstack && tv < resumee->valstack_top); + tv2 = &thr->heap->lj.value1; + DUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv2); /* side effects */ /* XXX: avoid side effects */ + + duk_hthread_activation_unwind_norz(resumee); /* unwind to 'yield' caller */ + /* no need to unwind catch stack */ + + duk__reconfig_valstack_ecma_return(resumee); + + DUK_ASSERT(resumee->resumer == NULL); + resumee->resumer = thr; + DUK_HTHREAD_INCREF(thr, thr); + resumee->state = DUK_HTHREAD_STATE_RUNNING; + thr->state = DUK_HTHREAD_STATE_RESUMED; + DUK_HEAP_SWITCH_THREAD(thr->heap, resumee); +#if 0 + thr = resumee; /* not needed, as we exit right away */ +#endif + DUK_DD(DUK_DDPRINT("-> resume with a value, restart execution in resumee")); + retval = DUK__LONGJMP_RESTART; + goto wipe_and_return; + } else { + /* Initial resume call. */ + duk_small_uint_t call_flags; + duk_int_t setup_rc; + + /* resumee: [... initial_func] (currently actually: [initial_func]) */ + + duk_push_undefined(resumee); + tv = &thr->heap->lj.value1; + duk_push_tval(resumee, tv); + + /* resumee: [... initial_func undefined(= this) resume_value ] */ + + call_flags = DUK_CALL_FLAG_ALLOW_ECMATOECMA; /* not tailcall, ecma-to-ecma (assumed to succeed) */ + + setup_rc = duk_handle_call_unprotected_nargs(resumee, 1 /*nargs*/, call_flags); + if (setup_rc == 0) { + /* This shouldn't happen; Duktape.Thread.resume() + * should make sure of that. If it does happen + * this internal error will propagate out of the + * executor which can be quite misleading. + */ + DUK_ERROR_INTERNAL(thr); + DUK_WO_NORETURN(return 0;); + } + + DUK_ASSERT(resumee->resumer == NULL); + resumee->resumer = thr; + DUK_HTHREAD_INCREF(thr, thr); + resumee->state = DUK_HTHREAD_STATE_RUNNING; + thr->state = DUK_HTHREAD_STATE_RESUMED; + DUK_HEAP_SWITCH_THREAD(thr->heap, resumee); +#if 0 + thr = resumee; /* not needed, as we exit right away */ +#endif + DUK_DD(DUK_DDPRINT("-> resume with a value, restart execution in resumee")); + retval = DUK__LONGJMP_RESTART; + goto wipe_and_return; + } + DUK_UNREACHABLE(); + break; /* never here */ + } + + case DUK_LJ_TYPE_YIELD: { + /* + * Currently only allowed only if yielding thread has only + * ECMAScript activations (except for the Duktape.Thread.yield() + * call at the callstack top) and none of them constructor + * calls. + * + * This excludes the 'entry' thread which will always have + * a preventcount > 0. + */ + + duk_hthread *resumer; + + /* duk_bi_duk_object_yield() and duk_bi_duk_object_resume() ensure all of these are met */ + +#if 0 /* entry_thread not available for assert */ + DUK_ASSERT(thr != entry_thread); /* Duktape.Thread.yield() should prevent */ +#endif + DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING); /* unchanged from Duktape.Thread.yield() */ + DUK_ASSERT(thr->callstack_top >= 2); /* ECMAScript activation + Duktape.Thread.yield() activation */ + DUK_ASSERT(thr->callstack_curr != NULL); + DUK_ASSERT(thr->callstack_curr->parent != NULL); + DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL && + DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)) && + ((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->callstack_curr))->func == duk_bi_thread_yield); + DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL && + DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr->parent))); /* an ECMAScript function */ + + resumer = thr->resumer; + + DUK_ASSERT(resumer != NULL); + DUK_ASSERT(resumer->state == DUK_HTHREAD_STATE_RESUMED); /* written by a previous RESUME handling */ + DUK_ASSERT(resumer->callstack_top >= 2); /* ECMAScript activation + Duktape.Thread.resume() activation */ + DUK_ASSERT(resumer->callstack_curr != NULL); + DUK_ASSERT(resumer->callstack_curr->parent != NULL); + DUK_ASSERT(DUK_ACT_GET_FUNC(resumer->callstack_curr) != NULL && + DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(resumer->callstack_curr)) && + ((duk_hnatfunc *) DUK_ACT_GET_FUNC(resumer->callstack_curr))->func == duk_bi_thread_resume); + DUK_ASSERT(DUK_ACT_GET_FUNC(resumer->callstack_curr->parent) != NULL && + DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(resumer->callstack_curr->parent))); /* an ECMAScript function */ + + if (thr->heap->lj.iserror) { + thr->state = DUK_HTHREAD_STATE_YIELDED; + thr->resumer = NULL; + DUK_HTHREAD_DECREF_NORZ(thr, resumer); + resumer->state = DUK_HTHREAD_STATE_RUNNING; + DUK_HEAP_SWITCH_THREAD(thr->heap, resumer); + thr = resumer; + + thr->heap->lj.type = DUK_LJ_TYPE_THROW; + /* lj.value1 is already set */ + DUK_ASSERT(thr->heap->lj.iserror); /* already set */ + + DUK_DD(DUK_DDPRINT("-> yield an error, converted to a throw in the resumer, propagate")); + goto check_longjmp; + } else { + duk_hthread_activation_unwind_norz(resumer); + duk__handle_yield(thr, resumer, &thr->heap->lj.value1); + + thr->state = DUK_HTHREAD_STATE_YIELDED; + thr->resumer = NULL; + DUK_HTHREAD_DECREF_NORZ(thr, resumer); + resumer->state = DUK_HTHREAD_STATE_RUNNING; + DUK_HEAP_SWITCH_THREAD(thr->heap, resumer); +#if 0 + thr = resumer; /* not needed, as we exit right away */ +#endif + + DUK_DD(DUK_DDPRINT("-> yield a value, restart execution in resumer")); + retval = DUK__LONGJMP_RESTART; + goto wipe_and_return; + } + DUK_UNREACHABLE(); + break; /* never here */ + } +#endif /* DUK_USE_COROUTINE_SUPPORT */ + + case DUK_LJ_TYPE_THROW: { + /* + * Three possible outcomes: + * * A try or finally catcher is found => resume there. + * (or) + * * The error propagates to the bytecode executor entry + * level (and we're in the entry thread) => rethrow + * with a new longjmp(), after restoring the previous + * catchpoint. + * * The error is not caught in the current thread, so + * the thread finishes with an error. This works like + * a yielded error, except that the thread is finished + * and can no longer be resumed. (There is always a + * resumer in this case.) + * + * Note: until we hit the entry level, there can only be + * ECMAScript activations. + */ + + duk_activation *act; + duk_catcher *cat; + duk_hthread *resumer; + + for (;;) { + act = thr->callstack_curr; + if (act == NULL) { + break; + } + + for (;;) { + cat = act->cat; + if (cat == NULL) { + break; + } + + if (DUK_CAT_HAS_CATCH_ENABLED(cat)) { + DUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF); + + DUK_DDD(DUK_DDDPRINT("before catch part 1: thr=%p, act=%p, cat=%p", + (void *) thr, (void *) act, (void *) act->cat)); + duk__handle_catch_part1(thr, + &thr->heap->lj.value1, + DUK_LJ_TYPE_THROW, + out_delayed_catch_setup); + + DUK_DD(DUK_DDPRINT("-> throw caught by a 'catch' clause, restart execution")); + retval = DUK__LONGJMP_RESTART; + goto wipe_and_return; + } + + if (DUK_CAT_HAS_FINALLY_ENABLED(cat)) { + DUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF); + DUK_ASSERT(!DUK_CAT_HAS_CATCH_ENABLED(cat)); + + duk__handle_finally(thr, + &thr->heap->lj.value1, + DUK_LJ_TYPE_THROW); + + DUK_DD(DUK_DDPRINT("-> throw caught by a 'finally' clause, restart execution")); + retval = DUK__LONGJMP_RESTART; + goto wipe_and_return; + } + + duk_hthread_catcher_unwind_norz(thr, act); + } + + if (act == entry_act) { + /* Not caught by anything before entry level; rethrow and let the + * final catcher finish unwinding (esp. value stack). + */ + DUK_D(DUK_DPRINT("-> throw propagated up to entry level, rethrow and exit bytecode executor")); + retval = DUK__LONGJMP_RETHROW; + goto just_return; + } + + duk_hthread_activation_unwind_norz(thr); + } + + DUK_DD(DUK_DDPRINT("-> throw not caught by current thread, yield error to resumer and recheck longjmp")); + + /* Not caught by current thread, thread terminates (yield error to resumer); + * note that this may cause a cascade if the resumer terminates with an uncaught + * exception etc (this is OK, but needs careful testing). + */ + + DUK_ASSERT(thr->resumer != NULL); + DUK_ASSERT(thr->resumer->callstack_top >= 2); /* ECMAScript activation + Duktape.Thread.resume() activation */ + DUK_ASSERT(thr->resumer->callstack_curr != NULL); + DUK_ASSERT(thr->resumer->callstack_curr->parent != NULL); + DUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent) != NULL && + DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent))); /* an ECMAScript function */ + + resumer = thr->resumer; + + /* reset longjmp */ + + DUK_ASSERT(thr->heap->lj.type == DUK_LJ_TYPE_THROW); /* already set */ + /* lj.value1 already set */ + + duk_hthread_terminate(thr); /* updates thread state, minimizes its allocations */ + DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_TERMINATED); + + thr->resumer = NULL; + DUK_HTHREAD_DECREF_NORZ(thr, resumer); + resumer->state = DUK_HTHREAD_STATE_RUNNING; + DUK_HEAP_SWITCH_THREAD(thr->heap, resumer); + thr = resumer; + goto check_longjmp; + } + + case DUK_LJ_TYPE_BREAK: /* pseudotypes, not used in actual longjmps */ + case DUK_LJ_TYPE_CONTINUE: + case DUK_LJ_TYPE_RETURN: + case DUK_LJ_TYPE_NORMAL: + default: { + /* should never happen, but be robust */ + DUK_D(DUK_DPRINT("caught unknown longjmp type %ld, treat as internal error", (long) thr->heap->lj.type)); + goto convert_to_internal_error; + } + + } /* end switch */ + + DUK_UNREACHABLE(); + + wipe_and_return: + DUK_DD(DUK_DDPRINT("handling longjmp done, wipe-and-return, top=%ld", + (long) duk_get_top(thr))); + thr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN; + thr->heap->lj.iserror = 0; + + DUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value1); /* side effects */ + DUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value2); /* side effects */ + + DUK_GC_TORTURE(thr->heap); + + just_return: + return retval; + + convert_to_internal_error: + /* This could also be thrown internally (set the error, goto check_longjmp), + * but it's better for internal errors to bubble outwards so that we won't + * infinite loop in this catchpoint. + */ + DUK_ERROR_INTERNAL(thr); + DUK_WO_NORETURN(return 0;); +} + +/* Handle a BREAK/CONTINUE opcode. Avoid using longjmp() for BREAK/CONTINUE + * handling because it has a measurable performance impact in ordinary + * environments and an extreme impact in Emscripten (GH-342). + */ +DUK_LOCAL DUK_EXEC_NOINLINE_PERF void duk__handle_break_or_continue(duk_hthread *thr, + duk_uint_t label_id, + duk_small_uint_t lj_type) { + duk_activation *act; + duk_catcher *cat; + + DUK_ASSERT(thr != NULL); + + /* Find a matching label catcher or 'finally' catcher in + * the same function, unwinding catchers as we go. + * + * A label catcher must always exist and will match unless + * a 'finally' captures the break/continue first. It is the + * compiler's responsibility to ensure that labels are used + * correctly. + */ + + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + + for (;;) { + cat = act->cat; + if (cat == NULL) { + break; + } + + DUK_DDD(DUK_DDDPRINT("considering catcher %p: type=%ld label=%ld", + (void *) cat, + (long) DUK_CAT_GET_TYPE(cat), + (long) DUK_CAT_GET_LABEL(cat))); + + /* XXX: bit mask test; FINALLY <-> TCF, single bit mask would suffice? */ + + if (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF && + DUK_CAT_HAS_FINALLY_ENABLED(cat)) { + duk_tval tv_tmp; + + DUK_TVAL_SET_U32(&tv_tmp, (duk_uint32_t) label_id); + duk__handle_finally(thr, &tv_tmp, lj_type); + + DUK_DD(DUK_DDPRINT("-> break/continue caught by 'finally', restart execution")); + return; + } + if (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_LABEL && + (duk_uint_t) DUK_CAT_GET_LABEL(cat) == label_id) { + duk__handle_label(thr, lj_type); + + DUK_DD(DUK_DDPRINT("-> break/continue caught by a label catcher (in the same function), restart execution")); + return; + } + + duk_hthread_catcher_unwind_norz(thr, act); + } + + /* Should never happen, but be robust. */ + DUK_D(DUK_DPRINT("-> break/continue not caught by anything in the current function (should never happen), throw internal error")); + DUK_ERROR_INTERNAL(thr); + DUK_WO_NORETURN(return;); +} + +/* Handle a RETURN opcode. Avoid using longjmp() for return handling because + * it has a measurable performance impact in ordinary environments and an extreme + * impact in Emscripten (GH-342). Return value is on value stack top. + */ +DUK_LOCAL duk_small_uint_t duk__handle_return(duk_hthread *thr, duk_activation *entry_act) { + duk_tval *tv1; + duk_tval *tv2; +#if defined(DUK_USE_COROUTINE_SUPPORT) + duk_hthread *resumer; +#endif + duk_activation *act; + duk_catcher *cat; + + /* We can directly access value stack here. */ + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(entry_act != NULL); + DUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom); + tv1 = thr->valstack_top - 1; + DUK_TVAL_CHKFAST_INPLACE_FAST(tv1); /* fastint downgrade check for return values */ + + /* + * Four possible outcomes: + * + * 1. A 'finally' in the same function catches the 'return'. + * It may continue to propagate when 'finally' is finished, + * or it may be neutralized by 'finally' (both handled by + * ENDFIN). + * + * 2. The return happens at the entry level of the bytecode + * executor, so return from the executor (in C stack). + * + * 3. There is a calling (ECMAScript) activation in the call + * stack => return to it, in the same executor instance. + * + * 4. There is no calling activation, and the thread is + * terminated. There is always a resumer in this case, + * which gets the return value similarly to a 'yield' + * (except that the current thread can no longer be + * resumed). + */ + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->callstack_top >= 1); + + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + + for (;;) { + cat = act->cat; + if (cat == NULL) { + break; + } + + if (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF && + DUK_CAT_HAS_FINALLY_ENABLED(cat)) { + DUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom); + duk__handle_finally(thr, thr->valstack_top - 1, DUK_LJ_TYPE_RETURN); + + DUK_DD(DUK_DDPRINT("-> return caught by 'finally', restart execution")); + return DUK__RETHAND_RESTART; + } + + duk_hthread_catcher_unwind_norz(thr, act); + } + + if (act == entry_act) { + /* Return to the bytecode executor caller who will unwind stacks + * and handle constructor post-processing. + * Return value is already on the stack top: [ ... retval ]. + */ + + DUK_DDD(DUK_DDDPRINT("-> return propagated up to entry level, exit bytecode executor")); + return DUK__RETHAND_FINISHED; + } + + if (thr->callstack_top >= 2) { + /* There is a caller; it MUST be an ECMAScript caller (otherwise it would + * match entry_act check). + */ + DUK_DDD(DUK_DDDPRINT("return to ECMAScript caller, retval_byteoff=%ld, lj_value1=%!T", + (long) (thr->callstack_curr->parent->retval_byteoff), + (duk_tval *) &thr->heap->lj.value1)); + + DUK_ASSERT(thr->callstack_curr != NULL); + DUK_ASSERT(thr->callstack_curr->parent != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr->parent))); /* must be ECMAScript */ + +#if defined(DUK_USE_ES6_PROXY) + if (thr->callstack_curr->flags & (DUK_ACT_FLAG_CONSTRUCT | DUK_ACT_FLAG_CONSTRUCT_PROXY)) { + duk_call_construct_postprocess(thr, thr->callstack_curr->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY); /* side effects */ + } +#else + if (thr->callstack_curr->flags & DUK_ACT_FLAG_CONSTRUCT) { + duk_call_construct_postprocess(thr, 0); /* side effects */ + } +#endif + + tv1 = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + thr->callstack_curr->parent->retval_byteoff); + DUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom); + tv2 = thr->valstack_top - 1; + DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects */ + + /* Catch stack unwind happens inline in callstack unwind. */ + duk_hthread_activation_unwind_norz(thr); + + duk__reconfig_valstack_ecma_return(thr); + + DUK_DD(DUK_DDPRINT("-> return not intercepted, restart execution in caller")); + return DUK__RETHAND_RESTART; + } + +#if defined(DUK_USE_COROUTINE_SUPPORT) + DUK_DD(DUK_DDPRINT("no calling activation, thread finishes (similar to yield)")); + + DUK_ASSERT(thr->resumer != NULL); + DUK_ASSERT(thr->resumer->callstack_top >= 2); /* ECMAScript activation + Duktape.Thread.resume() activation */ + DUK_ASSERT(thr->resumer->callstack_curr != NULL); + DUK_ASSERT(thr->resumer->callstack_curr->parent != NULL); + DUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr) != NULL && + DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr)) && + ((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->resumer->callstack_curr))->func == duk_bi_thread_resume); /* Duktape.Thread.resume() */ + DUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent) != NULL && + DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent))); /* an ECMAScript function */ + DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING); + DUK_ASSERT(thr->resumer->state == DUK_HTHREAD_STATE_RESUMED); + + resumer = thr->resumer; + + /* Share yield longjmp handler. + * + * This sequence of steps is a bit fragile (see GH-1845): + * - We need the return value from 'thr' (resumed thread) value stack. + * The termination unwinds its value stack, losing the value. + * - We need a refcounted reference for 'thr', which may only exist + * in the caller value stack. We can't unwind or reconfigure the + * caller's value stack without potentially freeing 'thr'. + * + * Current approach is to capture the 'thr' return value and store + * a reference to 'thr' in the caller value stack temporarily. This + * keeps 'thr' reachable until final yield/return handling which + * removes the references atomatically. + */ + + DUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom); + duk_hthread_activation_unwind_norz(resumer); /* May remove last reference to 'thr', but is NORZ. */ + duk_push_tval(resumer, thr->valstack_top - 1); /* Capture return value, side effect free. */ + duk_push_hthread(resumer, thr); /* Make 'thr' reachable again, before side effects. */ + + duk_hthread_terminate(thr); /* Updates thread state, minimizes its allocations. */ + thr->resumer = NULL; + DUK_HTHREAD_DECREF(thr, resumer); + DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_TERMINATED); + + resumer->state = DUK_HTHREAD_STATE_RUNNING; + DUK_HEAP_SWITCH_THREAD(thr->heap, resumer); + + DUK_ASSERT(resumer->valstack_top - 2 >= resumer->valstack_bottom); + duk__handle_yield(thr, resumer, resumer->valstack_top - 2); + thr = NULL; /* 'thr' invalidated by call */ + +#if 0 + thr = resumer; /* not needed */ +#endif + + DUK_DD(DUK_DDPRINT("-> return not caught, thread terminated; handle like yield, restart execution in resumer")); + return DUK__RETHAND_RESTART; +#else + /* Without coroutine support this case should never happen. */ + DUK_ERROR_INTERNAL(thr); + DUK_WO_NORETURN(return 0;); +#endif +} + +/* + * Executor interrupt handling + * + * The handler is called whenever the interrupt countdown reaches zero + * (or below). The handler must perform whatever checks are activated, + * e.g. check for cumulative step count to impose an execution step + * limit or check for breakpoints or other debugger interaction. + * + * When the actions are done, the handler must reinit the interrupt + * init and counter values. The 'init' value must indicate how many + * bytecode instructions are executed before the next interrupt. The + * counter must interface with the bytecode executor loop. Concretely, + * the new init value is normally one higher than the new counter value. + * For instance, to execute exactly one bytecode instruction the init + * value is set to 1 and the counter to 0. If an error is thrown by the + * interrupt handler, the counters are set to the same value (e.g. both + * to 0 to cause an interrupt when the next bytecode instruction is about + * to be executed after error handling). + * + * Maintaining the init/counter value properly is important for accurate + * behavior. For instance, executor step limit needs a cumulative step + * count which is simply computed as a sum of 'init' values. This must + * work accurately even when single stepping. + */ + +#if defined(DUK_USE_INTERRUPT_COUNTER) + +#define DUK__INT_NOACTION 0 /* no specific action, resume normal execution */ +#define DUK__INT_RESTART 1 /* must "goto restart_execution", e.g. breakpoints changed */ + +#if defined(DUK_USE_DEBUGGER_SUPPORT) +DUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_immediate, duk_small_uint_t *out_interrupt_retval) { + duk_activation *act; + duk_breakpoint *bp; + duk_breakpoint **bp_active; + duk_uint_fast32_t line = 0; + duk_bool_t process_messages; + duk_bool_t processed_messages = 0; + + DUK_ASSERT(thr->heap->dbg_processing == 0); /* don't re-enter e.g. during Eval */ + + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + + /* It might seem that replacing 'thr->heap' with just 'heap' below + * might be a good idea, but it increases code size slightly + * (probably due to unnecessary spilling) at least on x64. + */ + + /* + * Single opcode step check + */ + + if (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE) { + DUK_D(DUK_DPRINT("PAUSE TRIGGERED by one opcode step")); + duk_debug_set_paused(thr->heap); + } + + /* + * Breakpoint and step state checks + */ + + if (act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE || + (thr->heap->dbg_pause_act == thr->callstack_curr)) { + line = duk_debug_curr_line(thr); + + if (act->prev_line != line) { + /* Stepped? Step out is handled by callstack unwind. */ + if ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) && + (thr->heap->dbg_pause_act == thr->callstack_curr) && + (line != thr->heap->dbg_pause_startline)) { + DUK_D(DUK_DPRINT("PAUSE TRIGGERED by line change, at line %ld", + (long) line)); + duk_debug_set_paused(thr->heap); + } + + /* Check for breakpoints only on line transition. + * Breakpoint is triggered when we enter the target + * line from a different line, and the previous line + * was within the same function. + * + * This condition is tricky: the condition used to be + * that transition to -or across- the breakpoint line + * triggered the breakpoint. This seems intuitively + * better because it handles breakpoints on lines with + * no emitted opcodes; but this leads to the issue + * described in: https://github.com/svaarala/duktape/issues/263. + */ + bp_active = thr->heap->dbg_breakpoints_active; + for (;;) { + bp = *bp_active++; + if (bp == NULL) { + break; + } + + DUK_ASSERT(bp->filename != NULL); + if (act->prev_line != bp->line && line == bp->line) { + DUK_D(DUK_DPRINT("PAUSE TRIGGERED by breakpoint at %!O:%ld", + (duk_heaphdr *) bp->filename, (long) bp->line)); + duk_debug_set_paused(thr->heap); + } + } + } else { + ; + } + + act->prev_line = (duk_uint32_t) line; + } + + /* + * Rate limit check for sending status update or peeking into + * the debug transport. Both can be expensive operations that + * we don't want to do on every opcode. + * + * Making sure the interval remains reasonable on a wide variety + * of targets and bytecode is difficult without a timestamp, so + * we use a Date-provided timestamp for the rate limit check. + * But since it's also expensive to get a timestamp, a bytecode + * counter is used to rate limit getting timestamps. + */ + + process_messages = 0; + if (thr->heap->dbg_state_dirty || DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) || thr->heap->dbg_detaching) { + /* Enter message processing loop for sending Status notifys and + * to finish a pending detach. + */ + process_messages = 1; + } + + /* XXX: remove heap->dbg_exec_counter, use heap->inst_count_interrupt instead? */ + DUK_ASSERT(thr->interrupt_init >= 0); + thr->heap->dbg_exec_counter += (duk_uint_t) thr->interrupt_init; + if (thr->heap->dbg_exec_counter - thr->heap->dbg_last_counter >= DUK_HEAP_DBG_RATELIMIT_OPCODES) { + /* Overflow of the execution counter is fine and doesn't break + * anything here. + */ + + duk_double_t now, diff_last; + + thr->heap->dbg_last_counter = thr->heap->dbg_exec_counter; + now = duk_time_get_monotonic_time(thr); + + diff_last = now - thr->heap->dbg_last_time; + if (diff_last < 0.0 || diff_last >= (duk_double_t) DUK_HEAP_DBG_RATELIMIT_MILLISECS) { + /* Monotonic time should not experience time jumps, + * but the provider may be missing and we're actually + * using ECMAScript time. So, tolerate negative values + * so that a time jump works reasonably. + * + * Same interval is now used for status sending and + * peeking. + */ + + thr->heap->dbg_last_time = now; + thr->heap->dbg_state_dirty = 1; + process_messages = 1; + } + } + + /* + * Process messages and send status if necessary. + * + * If we're paused, we'll block for new messages. If we're not + * paused, we'll process anything we can peek but won't block + * for more. Detach (and re-attach) handling is all localized + * to duk_debug_process_messages() too. + * + * Debugger writes outside the message loop may cause debugger + * detach1 phase to run, after which dbg_read_cb == NULL and + * dbg_detaching != 0. The message loop will finish the detach + * by running detach2 phase, so enter the message loop also when + * detaching. + */ + + if (process_messages) { + DUK_ASSERT(thr->heap->dbg_processing == 0); + processed_messages = duk_debug_process_messages(thr, 0 /*no_block*/); + DUK_ASSERT(thr->heap->dbg_processing == 0); + } + + /* Continue checked execution if there are breakpoints or we're stepping. + * Also use checked execution if paused flag is active - it shouldn't be + * because the debug message loop shouldn't terminate if it was. Step out + * is handled by callstack unwind and doesn't need checked execution. + * Note that debugger may have detached due to error or explicit request + * above, so we must recheck attach status. + */ + + if (duk_debug_is_attached(thr->heap)) { + DUK_ASSERT(act == thr->callstack_curr); + DUK_ASSERT(act != NULL); + if (act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE || + (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE) || + ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) && + thr->heap->dbg_pause_act == thr->callstack_curr) || + DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap)) { + *out_immediate = 1; + } + + /* If we processed any debug messages breakpoints may have + * changed; restart execution to re-check active breakpoints. + */ + if (processed_messages) { + DUK_D(DUK_DPRINT("processed debug messages, restart execution to recheck possibly changed breakpoints")); + *out_interrupt_retval = DUK__INT_RESTART; + } else { + if (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE) { + /* Set 'pause after one opcode' active only when we're + * actually just about to execute code. + */ + thr->heap->dbg_pause_flags |= DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE; + } + } + } else { + DUK_D(DUK_DPRINT("debugger became detached, resume normal execution")); + } +} +#endif /* DUK_USE_DEBUGGER_SUPPORT */ + +DUK_LOCAL DUK_EXEC_NOINLINE_PERF DUK_COLD duk_small_uint_t duk__executor_interrupt(duk_hthread *thr) { + duk_int_t ctr; + duk_activation *act; + duk_hcompfunc *fun; + duk_bool_t immediate = 0; + duk_small_uint_t retval; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->heap != NULL); + DUK_ASSERT(thr->callstack_top > 0); + +#if defined(DUK_USE_DEBUG) + thr->heap->inst_count_interrupt += thr->interrupt_init; + DUK_DD(DUK_DDPRINT("execution interrupt, counter=%ld, init=%ld, " + "instruction counts: executor=%ld, interrupt=%ld", + (long) thr->interrupt_counter, (long) thr->interrupt_init, + (long) thr->heap->inst_count_exec, (long) thr->heap->inst_count_interrupt)); +#endif + + retval = DUK__INT_NOACTION; + ctr = DUK_HTHREAD_INTCTR_DEFAULT; + + /* + * Avoid nested calls. Concretely this happens during debugging, e.g. + * when we eval() an expression. + * + * Also don't interrupt if we're currently doing debug processing + * (which can be initiated outside the bytecode executor) as this + * may cause the debugger to be called recursively. Check required + * for correct operation of throw intercept and other "exotic" halting + * scenarios. + */ + +#if defined(DUK_USE_DEBUGGER_SUPPORT) + if (DUK_HEAP_HAS_INTERRUPT_RUNNING(thr->heap) || thr->heap->dbg_processing) { +#else + if (DUK_HEAP_HAS_INTERRUPT_RUNNING(thr->heap)) { +#endif + DUK_DD(DUK_DDPRINT("nested executor interrupt, ignoring")); + + /* Set a high interrupt counter; the original executor + * interrupt invocation will rewrite before exiting. + */ + thr->interrupt_init = ctr; + thr->interrupt_counter = ctr - 1; + return DUK__INT_NOACTION; + } + DUK_HEAP_SET_INTERRUPT_RUNNING(thr->heap); + + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + + fun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act); + DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC((duk_hobject *) fun)); + + DUK_UNREF(fun); + +#if defined(DUK_USE_EXEC_TIMEOUT_CHECK) + /* + * Execution timeout check + */ + + if (DUK_USE_EXEC_TIMEOUT_CHECK(thr->heap->heap_udata)) { + /* Keep throwing an error whenever we get here. The unusual values + * are set this way because no instruction is ever executed, we just + * throw an error until all try/catch/finally and other catchpoints + * have been exhausted. Duktape/C code gets control at each protected + * call but whenever it enters back into Duktape the RangeError gets + * raised. User exec timeout check must consistently indicate a timeout + * until we've fully bubbled out of Duktape. + */ + DUK_D(DUK_DPRINT("execution timeout, throwing a RangeError")); + thr->interrupt_init = 0; + thr->interrupt_counter = 0; + DUK_HEAP_CLEAR_INTERRUPT_RUNNING(thr->heap); + DUK_ERROR_RANGE(thr, "execution timeout"); + DUK_WO_NORETURN(return 0;); + } +#endif /* DUK_USE_EXEC_TIMEOUT_CHECK */ + +#if defined(DUK_USE_DEBUGGER_SUPPORT) + if (!thr->heap->dbg_processing && + (thr->heap->dbg_read_cb != NULL || thr->heap->dbg_detaching)) { + /* Avoid recursive re-entry; enter when we're attached or + * detaching (to finish off the pending detach). + */ + duk__interrupt_handle_debugger(thr, &immediate, &retval); + DUK_ASSERT(act == thr->callstack_curr); + } +#endif /* DUK_USE_DEBUGGER_SUPPORT */ + + /* + * Update the interrupt counter + */ + + if (immediate) { + /* Cause an interrupt after executing one instruction. */ + ctr = 1; + } + + /* The counter value is one less than the init value: init value should + * indicate how many instructions are executed before interrupt. To + * execute 1 instruction (after interrupt handler return), counter must + * be 0. + */ + DUK_ASSERT(ctr >= 1); + thr->interrupt_init = ctr; + thr->interrupt_counter = ctr - 1; + DUK_HEAP_CLEAR_INTERRUPT_RUNNING(thr->heap); + + return retval; +} +#endif /* DUK_USE_INTERRUPT_COUNTER */ + +/* + * Debugger handling for executor restart + * + * Check for breakpoints, stepping, etc, and figure out if we should execute + * in checked or normal mode. Note that we can't do this when an activation + * is created, because breakpoint status (and stepping status) may change + * later, so we must recheck every time we're executing an activation. + * This primitive should be side effect free to avoid changes during check. + */ + +#if defined(DUK_USE_DEBUGGER_SUPPORT) +DUK_LOCAL void duk__executor_recheck_debugger(duk_hthread *thr, duk_activation *act, duk_hcompfunc *fun) { + duk_heap *heap; + duk_tval *tv_tmp; + duk_hstring *filename; + duk_small_uint_t bp_idx; + duk_breakpoint **bp_active; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(act != NULL); + DUK_ASSERT(fun != NULL); + + heap = thr->heap; + bp_active = heap->dbg_breakpoints_active; + act->flags &= ~DUK_ACT_FLAG_BREAKPOINT_ACTIVE; + + tv_tmp = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) fun, DUK_STRIDX_FILE_NAME); + if (tv_tmp && DUK_TVAL_IS_STRING(tv_tmp)) { + filename = DUK_TVAL_GET_STRING(tv_tmp); + + /* Figure out all active breakpoints. A breakpoint is + * considered active if the current function's fileName + * matches the breakpoint's fileName, AND there is no + * inner function that has matching line numbers + * (otherwise a breakpoint would be triggered both + * inside and outside of the inner function which would + * be confusing). Example: + * + * function foo() { + * print('foo'); + * function bar() { <-. breakpoints in these + * print('bar'); | lines should not affect + * } <-' foo() execution + * bar(); + * } + * + * We need a few things that are only available when + * debugger support is enabled: (1) a line range for + * each function, and (2) access to the function + * template to access the inner functions (and their + * line ranges). + * + * It's important to have a narrow match for active + * breakpoints so that we don't enter checked execution + * when that's not necessary. For instance, if we're + * running inside a certain function and there's + * breakpoint outside in (after the call site), we + * don't want to slow down execution of the function. + */ + + for (bp_idx = 0; bp_idx < heap->dbg_breakpoint_count; bp_idx++) { + duk_breakpoint *bp = heap->dbg_breakpoints + bp_idx; + duk_hobject **funcs, **funcs_end; + duk_hcompfunc *inner_fun; + duk_bool_t bp_match; + + if (bp->filename == filename && + bp->line >= fun->start_line && bp->line <= fun->end_line) { + bp_match = 1; + DUK_DD(DUK_DDPRINT("breakpoint filename and line match: " + "%s:%ld vs. %s (line %ld vs. %ld-%ld)", + DUK_HSTRING_GET_DATA(bp->filename), + (long) bp->line, + DUK_HSTRING_GET_DATA(filename), + (long) bp->line, + (long) fun->start_line, + (long) fun->end_line)); + + funcs = DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, fun); + funcs_end = DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, fun); + while (funcs != funcs_end) { + inner_fun = (duk_hcompfunc *) *funcs; + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) inner_fun)); + if (bp->line >= inner_fun->start_line && bp->line <= inner_fun->end_line) { + DUK_DD(DUK_DDPRINT("inner function masks ('captures') breakpoint")); + bp_match = 0; + break; + } + funcs++; + } + + if (bp_match) { + /* No need to check for size of bp_active list, + * it's always larger than maximum number of + * breakpoints. + */ + act->flags |= DUK_ACT_FLAG_BREAKPOINT_ACTIVE; + *bp_active = heap->dbg_breakpoints + bp_idx; + bp_active++; + } + } + } + } + + *bp_active = NULL; /* terminate */ + + DUK_DD(DUK_DDPRINT("ACTIVE BREAKPOINTS: %ld", (long) (bp_active - thr->heap->dbg_breakpoints_active))); + + /* Force pause if we were doing "step into" in another activation. */ + if ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_ENTRY) && + thr->heap->dbg_pause_act != thr->callstack_curr) { + DUK_D(DUK_DPRINT("PAUSE TRIGGERED by function entry")); + duk_debug_set_paused(thr->heap); + } + + /* Force interrupt right away if we're paused or in "checked mode". + * Step out is handled by callstack unwind. + */ + if ((act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE) || + DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) || + ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) && + thr->heap->dbg_pause_act == thr->callstack_curr)) { + /* We'll need to interrupt early so recompute the init + * counter to reflect the number of bytecode instructions + * executed so that step counts for e.g. debugger rate + * limiting are accurate. + */ + DUK_ASSERT(thr->interrupt_counter <= thr->interrupt_init); + thr->interrupt_init = thr->interrupt_init - thr->interrupt_counter; + thr->interrupt_counter = 0; + } +} +#endif /* DUK_USE_DEBUGGER_SUPPORT */ + +/* + * Opcode handlers for opcodes with a lot of code and which are relatively + * rare; NOINLINE to reduce amount of code in main bytecode dispatcher. + */ + +DUK_LOCAL DUK_EXEC_NOINLINE_PERF void duk__handle_op_initset_initget(duk_hthread *thr, duk_uint_fast32_t ins) { + duk_bool_t is_set = (DUK_DEC_OP(ins) == DUK_OP_INITSET); + duk_uint_fast_t idx; + duk_uint_t defprop_flags; + + /* A -> object register (acts as a source) + * BC -> BC+0 contains key, BC+1 closure (value) + */ + + /* INITSET/INITGET are only used to initialize object literal keys. + * There may be a previous propery in ES2015 because duplicate property + * names are allowed. + */ + + /* This could be made more optimal by accessing internals directly. */ + + idx = (duk_uint_fast_t) DUK_DEC_BC(ins); + duk_dup(thr, (duk_idx_t) (idx + 0)); /* key */ + duk_dup(thr, (duk_idx_t) (idx + 1)); /* getter/setter */ + if (is_set) { + defprop_flags = DUK_DEFPROP_HAVE_SETTER | + DUK_DEFPROP_FORCE | + DUK_DEFPROP_SET_ENUMERABLE | + DUK_DEFPROP_SET_CONFIGURABLE; + } else { + defprop_flags = DUK_DEFPROP_HAVE_GETTER | + DUK_DEFPROP_FORCE | + DUK_DEFPROP_SET_ENUMERABLE | + DUK_DEFPROP_SET_CONFIGURABLE; + } + duk_def_prop(thr, (duk_idx_t) DUK_DEC_A(ins), defprop_flags); +} + +DUK_LOCAL DUK_EXEC_NOINLINE_PERF void duk__handle_op_trycatch(duk_hthread *thr, duk_uint_fast32_t ins, duk_instr_t *curr_pc) { + duk_activation *act; + duk_catcher *cat; + duk_tval *tv1; + duk_small_uint_fast_t a; + duk_small_uint_fast_t bc; + + /* A -> flags + * BC -> reg_catch; base register for two registers used both during + * trycatch setup and when catch is triggered + * + * If DUK_BC_TRYCATCH_FLAG_CATCH_BINDING set: + * reg_catch + 0: catch binding variable name (string). + * Automatic declarative environment is established for + * the duration of the 'catch' clause. + * + * If DUK_BC_TRYCATCH_FLAG_WITH_BINDING set: + * reg_catch + 0: with 'target value', which is coerced to + * an object and then used as a bindind object for an + * environment record. The binding is initialized here, for + * the 'try' clause. + * + * Note that a TRYCATCH generated for a 'with' statement has no + * catch or finally parts. + */ + + /* XXX: TRYCATCH handling should be reworked to avoid creating + * an explicit scope unless it is actually needed (e.g. function + * instances or eval is executed inside the catch block). This + * rework is not trivial because the compiler doesn't have an + * intermediate representation. When the rework is done, the + * opcode format can also be made more straightforward. + */ + + /* XXX: side effect handling is quite awkward here */ + + DUK_DDD(DUK_DDDPRINT("TRYCATCH: reg_catch=%ld, have_catch=%ld, " + "have_finally=%ld, catch_binding=%ld, with_binding=%ld (flags=0x%02lx)", + (long) DUK_DEC_BC(ins), + (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH ? 1 : 0), + (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY ? 1 : 0), + (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_CATCH_BINDING ? 1 : 0), + (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_WITH_BINDING ? 1 : 0), + (unsigned long) DUK_DEC_A(ins))); + + a = DUK_DEC_A(ins); + bc = DUK_DEC_BC(ins); + + /* Registers 'bc' and 'bc + 1' are written in longjmp handling + * and if their previous values (which are temporaries) become + * unreachable -and- have a finalizer, there'll be a function + * call during error handling which is not supported now (GH-287). + * Ensure that both 'bc' and 'bc + 1' have primitive values to + * guarantee no finalizer calls in error handling. Scrubbing also + * ensures finalizers for the previous values run here rather than + * later. Error handling related values are also written to 'bc' + * and 'bc + 1' but those values never become unreachable during + * error handling, so there's no side effect problem even if the + * error value has a finalizer. + */ + duk_dup(thr, (duk_idx_t) bc); /* Stabilize value. */ + duk_to_undefined(thr, (duk_idx_t) bc); + duk_to_undefined(thr, (duk_idx_t) (bc + 1)); + + /* Allocate catcher and populate it. Doesn't have to + * be fully atomic, but the catcher must be in a + * consistent state if side effects (such as finalizer + * calls) occur. + */ + + cat = duk_hthread_catcher_alloc(thr); + DUK_ASSERT(cat != NULL); + + cat->flags = DUK_CAT_TYPE_TCF; + cat->h_varname = NULL; + cat->pc_base = (duk_instr_t *) curr_pc; /* pre-incremented, points to first jump slot */ + cat->idx_base = (duk_size_t) (thr->valstack_bottom - thr->valstack) + bc; + + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + cat->parent = act->cat; + act->cat = cat; + + if (a & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) { + cat->flags |= DUK_CAT_FLAG_CATCH_ENABLED; + } + if (a & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY) { + cat->flags |= DUK_CAT_FLAG_FINALLY_ENABLED; + } + if (a & DUK_BC_TRYCATCH_FLAG_CATCH_BINDING) { + DUK_DDD(DUK_DDDPRINT("catch binding flag set to catcher")); + cat->flags |= DUK_CAT_FLAG_CATCH_BINDING_ENABLED; + tv1 = DUK_GET_TVAL_NEGIDX(thr, -1); + DUK_ASSERT(DUK_TVAL_IS_STRING(tv1)); + + /* borrowed reference; although 'tv1' comes from a register, + * its value was loaded using LDCONST so the constant will + * also exist and be reachable. + */ + cat->h_varname = DUK_TVAL_GET_STRING(tv1); + } else if (a & DUK_BC_TRYCATCH_FLAG_WITH_BINDING) { + duk_hobjenv *env; + duk_hobject *target; + + /* Delayed env initialization for activation (if needed). */ + DUK_ASSERT(thr->callstack_top >= 1); + DUK_ASSERT(act == thr->callstack_curr); + DUK_ASSERT(act != NULL); + if (act->lex_env == NULL) { + DUK_DDD(DUK_DDDPRINT("delayed environment initialization")); + DUK_ASSERT(act->var_env == NULL); + + duk_js_init_activation_environment_records_delayed(thr, act); + DUK_ASSERT(act == thr->callstack_curr); + DUK_UNREF(act); /* 'act' is no longer accessed, scanbuild fix */ + } + DUK_ASSERT(act->lex_env != NULL); + DUK_ASSERT(act->var_env != NULL); + + /* Coerce 'with' target. */ + target = duk_to_hobject(thr, -1); + DUK_ASSERT(target != NULL); + + /* Create an object environment; it is not pushed + * so avoid side effects very carefully until it is + * referenced. + */ + env = duk_hobjenv_alloc(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV)); + DUK_ASSERT(env != NULL); + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL); + env->target = target; /* always provideThis=true */ + DUK_HOBJECT_INCREF(thr, target); + env->has_this = 1; + DUK_HOBJENV_ASSERT_VALID(env); + DUK_DDD(DUK_DDDPRINT("environment for with binding: %!iO", env)); + + DUK_ASSERT(act == thr->callstack_curr); + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL); + DUK_ASSERT(act->lex_env != NULL); + DUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) env, act->lex_env); + act->lex_env = (duk_hobject *) env; /* Now reachable. */ + DUK_HOBJECT_INCREF(thr, (duk_hobject *) env); + /* Net refcount change to act->lex_env is 0: incref for env's + * prototype, decref for act->lex_env overwrite. + */ + + /* Set catcher lex_env active (affects unwind) + * only when the whole setup is complete. + */ + cat = act->cat; /* XXX: better to relookup? not mandatory because 'cat' is stable */ + cat->flags |= DUK_CAT_FLAG_LEXENV_ACTIVE; + } else { + ; + } + + DUK_DDD(DUK_DDDPRINT("TRYCATCH catcher: flags=0x%08lx, pc_base=%ld, " + "idx_base=%ld, h_varname=%!O", + (unsigned long) cat->flags, + (long) cat->pc_base, (long) cat->idx_base, (duk_heaphdr *) cat->h_varname)); + + duk_pop_unsafe(thr); +} + +DUK_LOCAL DUK_EXEC_NOINLINE_PERF duk_instr_t *duk__handle_op_endtry(duk_hthread *thr, duk_uint_fast32_t ins) { + duk_activation *act; + duk_catcher *cat; + duk_tval *tv1; + duk_instr_t *pc_base; + + DUK_UNREF(ins); + + DUK_ASSERT(thr->callstack_top >= 1); + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + cat = act->cat; + DUK_ASSERT(cat != NULL); + DUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF); + + DUK_DDD(DUK_DDDPRINT("ENDTRY: clearing catch active flag (regardless of whether it was set or not)")); + DUK_CAT_CLEAR_CATCH_ENABLED(cat); + + pc_base = cat->pc_base; + + if (DUK_CAT_HAS_FINALLY_ENABLED(cat)) { + DUK_DDD(DUK_DDDPRINT("ENDTRY: finally part is active, jump through 2nd jump slot with 'normal continuation'")); + + tv1 = thr->valstack + cat->idx_base; + DUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top); + DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1); /* side effects */ + tv1 = NULL; + + tv1 = thr->valstack + cat->idx_base + 1; + DUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top); + DUK_TVAL_SET_U32_UPDREF(thr, tv1, (duk_uint32_t) DUK_LJ_TYPE_NORMAL); /* side effects */ + tv1 = NULL; + + DUK_CAT_CLEAR_FINALLY_ENABLED(cat); + } else { + DUK_DDD(DUK_DDDPRINT("ENDTRY: no finally part, dismantle catcher, jump through 2nd jump slot (to end of statement)")); + + duk_hthread_catcher_unwind_norz(thr, act); /* lexenv may be set for 'with' binding */ + /* no need to unwind callstack */ + } + + return pc_base + 1; /* new curr_pc value */ +} + +DUK_LOCAL DUK_EXEC_NOINLINE_PERF duk_instr_t *duk__handle_op_endcatch(duk_hthread *thr, duk_uint_fast32_t ins) { + duk_activation *act; + duk_catcher *cat; + duk_tval *tv1; + duk_instr_t *pc_base; + + DUK_UNREF(ins); + + DUK_ASSERT(thr->callstack_top >= 1); + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + cat = act->cat; + DUK_ASSERT(cat != NULL); + DUK_ASSERT(!DUK_CAT_HAS_CATCH_ENABLED(cat)); /* cleared before entering catch part */ + + if (DUK_CAT_HAS_LEXENV_ACTIVE(cat)) { + duk_hobject *prev_env; + + /* 'with' binding has no catch clause, so can't be here unless a normal try-catch */ + DUK_ASSERT(DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat)); + DUK_ASSERT(act->lex_env != NULL); + + DUK_DDD(DUK_DDDPRINT("ENDCATCH: popping catcher part lexical environment")); + + prev_env = act->lex_env; + DUK_ASSERT(prev_env != NULL); + act->lex_env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, prev_env); + DUK_CAT_CLEAR_LEXENV_ACTIVE(cat); + DUK_HOBJECT_INCREF(thr, act->lex_env); + DUK_HOBJECT_DECREF(thr, prev_env); /* side effects */ + + DUK_ASSERT(act == thr->callstack_curr); + DUK_ASSERT(act != NULL); + } + + pc_base = cat->pc_base; + + if (DUK_CAT_HAS_FINALLY_ENABLED(cat)) { + DUK_DDD(DUK_DDDPRINT("ENDCATCH: finally part is active, jump through 2nd jump slot with 'normal continuation'")); + + tv1 = thr->valstack + cat->idx_base; + DUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top); + DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1); /* side effects */ + tv1 = NULL; + + tv1 = thr->valstack + cat->idx_base + 1; + DUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top); + DUK_TVAL_SET_U32_UPDREF(thr, tv1, (duk_uint32_t) DUK_LJ_TYPE_NORMAL); /* side effects */ + tv1 = NULL; + + DUK_CAT_CLEAR_FINALLY_ENABLED(cat); + } else { + DUK_DDD(DUK_DDDPRINT("ENDCATCH: no finally part, dismantle catcher, jump through 2nd jump slot (to end of statement)")); + + duk_hthread_catcher_unwind_norz(thr, act); + /* no need to unwind callstack */ + } + + return pc_base + 1; /* new curr_pc value */ +} + +DUK_LOCAL DUK_EXEC_NOINLINE_PERF duk_small_uint_t duk__handle_op_endfin(duk_hthread *thr, duk_uint_fast32_t ins, duk_activation *entry_act) { + duk_activation *act; + duk_tval *tv1; + duk_uint_t reg_catch; + duk_small_uint_t cont_type; + duk_small_uint_t ret_result; + + DUK_ASSERT(thr->ptr_curr_pc == NULL); + DUK_ASSERT(thr->callstack_top >= 1); + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + reg_catch = DUK_DEC_ABC(ins); + + /* CATCH flag may be enabled or disabled here; it may be enabled if + * the statement has a catch block but the try block does not throw + * an error. + */ + + DUK_DDD(DUK_DDDPRINT("ENDFIN: completion value=%!T, type=%!T", + (duk_tval *) (thr->valstack_bottom + reg_catch + 0), + (duk_tval *) (thr->valstack_bottom + reg_catch + 1))); + + tv1 = thr->valstack_bottom + reg_catch + 1; /* type */ + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1)); +#if defined(DUK_USE_FASTINT) + DUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1)); + cont_type = (duk_small_uint_t) DUK_TVAL_GET_FASTINT_U32(tv1); +#else + cont_type = (duk_small_uint_t) DUK_TVAL_GET_NUMBER(tv1); +#endif + + tv1--; /* value */ + + switch (cont_type) { + case DUK_LJ_TYPE_NORMAL: { + DUK_DDD(DUK_DDDPRINT("ENDFIN: finally part finishing with 'normal' (non-abrupt) completion -> " + "dismantle catcher, resume execution after ENDFIN")); + + duk_hthread_catcher_unwind_norz(thr, act); + /* no need to unwind callstack */ + return 0; /* restart execution */ + } + case DUK_LJ_TYPE_RETURN: { + DUK_DDD(DUK_DDDPRINT("ENDFIN: finally part finishing with 'return' complation -> dismantle " + "catcher, handle return, lj.value1=%!T", tv1)); + + /* Not necessary to unwind catch stack: return handling will + * do it. The finally flag of 'cat' is no longer set. The + * catch flag may be set, but it's not checked by return handling. + */ + + duk_push_tval(thr, tv1); + ret_result = duk__handle_return(thr, entry_act); + if (ret_result == DUK__RETHAND_RESTART) { + return 0; /* restart execution */ + } + DUK_ASSERT(ret_result == DUK__RETHAND_FINISHED); + + DUK_DDD(DUK_DDDPRINT("exiting executor after ENDFIN and RETURN (pseudo) longjmp type")); + return 1; /* exit executor */ + } + case DUK_LJ_TYPE_BREAK: + case DUK_LJ_TYPE_CONTINUE: { + duk_uint_t label_id; + duk_small_uint_t lj_type; + + /* Not necessary to unwind catch stack: break/continue + * handling will do it. The finally flag of 'cat' is + * no longer set. The catch flag may be set, but it's + * not checked by break/continue handling. + */ + + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1)); +#if defined(DUK_USE_FASTINT) + DUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1)); + label_id = (duk_small_uint_t) DUK_TVAL_GET_FASTINT_U32(tv1); +#else + label_id = (duk_small_uint_t) DUK_TVAL_GET_NUMBER(tv1); +#endif + lj_type = cont_type; + duk__handle_break_or_continue(thr, label_id, lj_type); + return 0; /* restart execution */ + } + default: { + DUK_DDD(DUK_DDDPRINT("ENDFIN: finally part finishing with abrupt completion, lj_type=%ld -> " + "dismantle catcher, re-throw error", + (long) cont_type)); + + duk_err_setup_ljstate1(thr, (duk_small_uint_t) cont_type, tv1); + /* No debugger Throw notify check on purpose (rethrow). */ + + DUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL); /* always in executor */ + duk_err_longjmp(thr); + DUK_UNREACHABLE(); + } + } + + DUK_UNREACHABLE(); + return 0; +} + +DUK_LOCAL DUK_EXEC_NOINLINE_PERF void duk__handle_op_initenum(duk_hthread *thr, duk_uint_fast32_t ins) { + duk_small_uint_t b; + duk_small_uint_t c; + + /* + * Enumeration semantics come from for-in statement, E5 Section 12.6.4. + * If called with 'null' or 'undefined', this opcode returns 'null' as + * the enumerator, which is special cased in NEXTENUM. This simplifies + * the compiler part + */ + + /* B -> register for writing enumerator object + * C -> value to be enumerated (register) + */ + b = DUK_DEC_B(ins); + c = DUK_DEC_C(ins); + + if (duk_is_null_or_undefined(thr, (duk_idx_t) c)) { + duk_push_null(thr); + duk_replace(thr, (duk_idx_t) b); + } else { + duk_dup(thr, (duk_idx_t) c); + duk_to_object(thr, -1); + duk_hobject_enumerator_create(thr, 0 /*enum_flags*/); /* [ ... val ] --> [ ... enum ] */ + duk_replace(thr, (duk_idx_t) b); + } +} + +DUK_LOCAL DUK_EXEC_NOINLINE_PERF duk_small_uint_t duk__handle_op_nextenum(duk_hthread *thr, duk_uint_fast32_t ins) { + duk_small_uint_t b; + duk_small_uint_t c; + duk_small_uint_t pc_skip = 0; + + /* + * NEXTENUM checks whether the enumerator still has unenumerated + * keys. If so, the next key is loaded to the target register + * and the next instruction is skipped. Otherwise the next instruction + * will be executed, jumping out of the enumeration loop. + */ + + /* B -> target register for next key + * C -> enum register + */ + b = DUK_DEC_B(ins); + c = DUK_DEC_C(ins); + + DUK_DDD(DUK_DDDPRINT("NEXTENUM: b->%!T, c->%!T", + (duk_tval *) duk_get_tval(thr, (duk_idx_t) b), + (duk_tval *) duk_get_tval(thr, (duk_idx_t) c))); + + if (duk_is_object(thr, (duk_idx_t) c)) { + /* XXX: assert 'c' is an enumerator */ + duk_dup(thr, (duk_idx_t) c); + if (duk_hobject_enumerator_next(thr, 0 /*get_value*/)) { + /* [ ... enum ] -> [ ... next_key ] */ + DUK_DDD(DUK_DDDPRINT("enum active, next key is %!T, skip jump slot ", + (duk_tval *) duk_get_tval(thr, -1))); + pc_skip = 1; + } else { + /* [ ... enum ] -> [ ... ] */ + DUK_DDD(DUK_DDDPRINT("enum finished, execute jump slot")); + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top)); /* valstack policy */ + thr->valstack_top++; + } + duk_replace(thr, (duk_idx_t) b); + } else { + /* 'null' enumerator case -> behave as with an empty enumerator */ + DUK_ASSERT(duk_is_null(thr, (duk_idx_t) c)); + DUK_DDD(DUK_DDDPRINT("enum is null, execute jump slot")); + } + + return pc_skip; +} + +/* + * Call handling helpers. + */ + +DUK_LOCAL duk_bool_t duk__executor_handle_call(duk_hthread *thr, duk_idx_t idx, duk_idx_t nargs, duk_small_uint_t call_flags) { + duk_bool_t rc; + + duk_set_top_unsafe(thr, (duk_idx_t) (idx + nargs + 2)); /* [ ... func this arg1 ... argN ] */ + + /* Attempt an Ecma-to-Ecma call setup. If the call + * target is (directly or indirectly) Reflect.construct(), + * the call may change into a constructor call on the fly. + */ + rc = (duk_bool_t) duk_handle_call_unprotected(thr, idx, call_flags); + if (rc != 0) { + /* Ecma-to-ecma call possible, may or may not + * be a tail call. Avoid C recursion by + * reusing current executor instance. + */ + DUK_DDD(DUK_DDDPRINT("ecma-to-ecma call setup possible, restart execution")); + /* curr_pc synced by duk_handle_call_unprotected() */ + DUK_ASSERT(thr->ptr_curr_pc == NULL); + return rc; + } else { + /* Call was handled inline. */ + } + DUK_ASSERT(thr->ptr_curr_pc != NULL); + return rc; +} + +/* + * ECMAScript bytecode executor. + * + * Resume execution for the current thread from its current activation. + * Returns when execution would return from the entry level activation, + * leaving a single return value on top of the stack. Function calls + * and thread resumptions are handled internally. If an error occurs, + * a longjmp() with type DUK_LJ_TYPE_THROW is called on the entry level + * setjmp() jmpbuf. + * + * ECMAScript function calls and coroutine resumptions are handled + * internally (by the outer executor function) without recursive C calls. + * Other function calls are handled using duk_handle_call(), increasing + * C recursion depth. + * + * Abrupt completions (= long control tranfers) are handled either + * directly by reconfiguring relevant stacks and restarting execution, + * or via a longjmp. Longjmp-free handling is preferable for performance + * (especially Emscripten performance), and is used for: break, continue, + * and return. + * + * For more detailed notes, see doc/execution.rst. + * + * Also see doc/code-issues.rst for discussion of setjmp(), longjmp(), + * and volatile. + */ + +/* Presence of 'fun' is config based, there's a marginal performance + * difference and the best option is architecture dependent. + */ +#if defined(DUK_USE_EXEC_FUN_LOCAL) +#define DUK__FUN() fun +#else +#define DUK__FUN() ((duk_hcompfunc *) DUK_ACT_GET_FUNC((thr)->callstack_curr)) +#endif + +/* Strict flag. */ +#define DUK__STRICT() ((duk_small_uint_t) DUK_HOBJECT_HAS_STRICT((duk_hobject *) DUK__FUN())) + +/* Reg/const access macros: these are very footprint and performance sensitive + * so modify with care. Arguments are sometimes evaluated multiple times which + * is not ideal. + */ +#define DUK__REG(x) (*(thr->valstack_bottom + (x))) +#define DUK__REGP(x) (thr->valstack_bottom + (x)) +#define DUK__CONST(x) (*(consts + (x))) +#define DUK__CONSTP(x) (consts + (x)) + +/* Reg/const access macros which take the 32-bit instruction and avoid an + * explicit field decoding step by using shifts and masks. These must be + * kept in sync with duk_js_bytecode.h. The shift/mask values are chosen + * so that 'ins' can be shifted and masked and used as a -byte- offset + * instead of a duk_tval offset which needs further shifting (which is an + * issue on some, but not all, CPUs). + */ +#define DUK__RCBIT_B DUK_BC_REGCONST_B +#define DUK__RCBIT_C DUK_BC_REGCONST_C +#if defined(DUK_USE_EXEC_REGCONST_OPTIMIZE) +#if defined(DUK_USE_PACKED_TVAL) +#define DUK__TVAL_SHIFT 3 /* sizeof(duk_tval) == 8 */ +#else +#define DUK__TVAL_SHIFT 4 /* sizeof(duk_tval) == 16; not always the case so also asserted for */ +#endif +#define DUK__SHIFT_A (DUK_BC_SHIFT_A - DUK__TVAL_SHIFT) +#define DUK__SHIFT_B (DUK_BC_SHIFT_B - DUK__TVAL_SHIFT) +#define DUK__SHIFT_C (DUK_BC_SHIFT_C - DUK__TVAL_SHIFT) +#define DUK__SHIFT_BC (DUK_BC_SHIFT_BC - DUK__TVAL_SHIFT) +#define DUK__MASK_A (DUK_BC_UNSHIFTED_MASK_A << DUK__TVAL_SHIFT) +#define DUK__MASK_B (DUK_BC_UNSHIFTED_MASK_B << DUK__TVAL_SHIFT) +#define DUK__MASK_C (DUK_BC_UNSHIFTED_MASK_C << DUK__TVAL_SHIFT) +#define DUK__MASK_BC (DUK_BC_UNSHIFTED_MASK_BC << DUK__TVAL_SHIFT) +#define DUK__BYTEOFF_A(ins) (((ins) >> DUK__SHIFT_A) & DUK__MASK_A) +#define DUK__BYTEOFF_B(ins) (((ins) >> DUK__SHIFT_B) & DUK__MASK_B) +#define DUK__BYTEOFF_C(ins) (((ins) >> DUK__SHIFT_C) & DUK__MASK_C) +#define DUK__BYTEOFF_BC(ins) (((ins) >> DUK__SHIFT_BC) & DUK__MASK_BC) + +#define DUK__REGP_A(ins) ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_A((ins)))) +#define DUK__REGP_B(ins) ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_B((ins)))) +#define DUK__REGP_C(ins) ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_C((ins)))) +#define DUK__REGP_BC(ins) ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_BC((ins)))) +#define DUK__CONSTP_A(ins) ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_A((ins)))) +#define DUK__CONSTP_B(ins) ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_B((ins)))) +#define DUK__CONSTP_C(ins) ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_C((ins)))) +#define DUK__CONSTP_BC(ins) ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_BC((ins)))) +#define DUK__REGCONSTP_B(ins) ((duk_tval *) (void *) ((duk_uint8_t *) (((ins) & DUK__RCBIT_B) ? consts : thr->valstack_bottom) + DUK__BYTEOFF_B((ins)))) +#define DUK__REGCONSTP_C(ins) ((duk_tval *) (void *) ((duk_uint8_t *) (((ins) & DUK__RCBIT_C) ? consts : thr->valstack_bottom) + DUK__BYTEOFF_C((ins)))) +#else /* DUK_USE_EXEC_REGCONST_OPTIMIZE */ +/* Safe alternatives, no assumption about duk_tval size. */ +#define DUK__REGP_A(ins) DUK__REGP(DUK_DEC_A((ins))) +#define DUK__REGP_B(ins) DUK__REGP(DUK_DEC_B((ins))) +#define DUK__REGP_C(ins) DUK__REGP(DUK_DEC_C((ins))) +#define DUK__REGP_BC(ins) DUK__REGP(DUK_DEC_BC((ins))) +#define DUK__CONSTP_A(ins) DUK__CONSTP(DUK_DEC_A((ins))) +#define DUK__CONSTP_B(ins) DUK__CONSTP(DUK_DEC_B((ins))) +#define DUK__CONSTP_C(ins) DUK__CONSTP(DUK_DEC_C((ins))) +#define DUK__CONSTP_BC(ins) DUK__CONSTP(DUK_DEC_BC((ins))) +#define DUK__REGCONSTP_B(ins) ((((ins) & DUK__RCBIT_B) ? consts : thr->valstack_bottom) + DUK_DEC_B((ins))) +#define DUK__REGCONSTP_C(ins) ((((ins) & DUK__RCBIT_C) ? consts : thr->valstack_bottom) + DUK_DEC_C((ins))) +#endif /* DUK_USE_EXEC_REGCONST_OPTIMIZE */ + +#if defined(DUK_USE_VERBOSE_EXECUTOR_ERRORS) +#define DUK__INTERNAL_ERROR(msg) do { \ + DUK_ERROR_ERROR(thr, (msg)); \ + DUK_WO_NORETURN(return;); \ + } while (0) +#else +#define DUK__INTERNAL_ERROR(msg) do { \ + goto internal_error; \ + } while (0) +#endif + +#define DUK__SYNC_CURR_PC() do { \ + duk_activation *duk__act; \ + duk__act = thr->callstack_curr; \ + duk__act->curr_pc = curr_pc; \ + } while (0) +#define DUK__SYNC_AND_NULL_CURR_PC() do { \ + duk_activation *duk__act; \ + duk__act = thr->callstack_curr; \ + duk__act->curr_pc = curr_pc; \ + thr->ptr_curr_pc = NULL; \ + } while (0) + +#if defined(DUK_USE_EXEC_PREFER_SIZE) +#define DUK__LOOKUP_INDIRECT(idx) do { \ + (idx) = (duk_uint_fast_t) duk_get_uint(thr, (duk_idx_t) (idx)); \ + } while (0) +#elif defined(DUK_USE_FASTINT) +#define DUK__LOOKUP_INDIRECT(idx) do { \ + duk_tval *tv_ind; \ + tv_ind = DUK__REGP((idx)); \ + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_ind)); \ + DUK_ASSERT(DUK_TVAL_IS_FASTINT(tv_ind)); /* compiler guarantees */ \ + (idx) = (duk_uint_fast_t) DUK_TVAL_GET_FASTINT_U32(tv_ind); \ + } while (0) +#else +#define DUK__LOOKUP_INDIRECT(idx) do { \ + duk_tval *tv_ind; \ + tv_ind = DUK__REGP(idx); \ + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_ind)); \ + idx = (duk_uint_fast_t) DUK_TVAL_GET_NUMBER(tv_ind); \ + } while (0) +#endif + +DUK_LOCAL void duk__handle_executor_error(duk_heap *heap, + duk_activation *entry_act, + duk_int_t entry_call_recursion_depth, + duk_jmpbuf *entry_jmpbuf_ptr, + volatile duk_bool_t *out_delayed_catch_setup) { + duk_small_uint_t lj_ret; + + /* Longjmp callers are required to sync-and-null thr->ptr_curr_pc + * before longjmp. + */ + DUK_ASSERT(heap->curr_thread != NULL); + DUK_ASSERT(heap->curr_thread->ptr_curr_pc == NULL); + + /* XXX: signalling the need to shrink check (only if unwound) */ + + /* Must be restored here to handle e.g. yields properly. */ + heap->call_recursion_depth = entry_call_recursion_depth; + + /* Switch to caller's setjmp() catcher so that if an error occurs + * during error handling, it is always propagated outwards instead + * of causing an infinite loop in our own handler. + */ + heap->lj.jmpbuf_ptr = (duk_jmpbuf *) entry_jmpbuf_ptr; + + lj_ret = duk__handle_longjmp(heap->curr_thread, entry_act, out_delayed_catch_setup); + + /* Error handling complete, remove side effect protections. + */ +#if defined(DUK_USE_ASSERTIONS) + DUK_ASSERT(heap->error_not_allowed == 1); + heap->error_not_allowed = 0; +#endif + DUK_ASSERT(heap->pf_prevent_count > 0); + heap->pf_prevent_count--; + DUK_DD(DUK_DDPRINT("executor error handled, pf_prevent_count updated to %ld", (long) heap->pf_prevent_count)); + + if (lj_ret == DUK__LONGJMP_RESTART) { + /* Restart bytecode execution, possibly with a changed thread. */ + DUK_REFZERO_CHECK_SLOW(heap->curr_thread); + } else { + /* If an error is propagated, don't run refzero checks here. + * The next catcher will deal with that. Pf_prevent_count + * will be re-bumped by the longjmp. + */ + + DUK_ASSERT(lj_ret == DUK__LONGJMP_RETHROW); /* Rethrow error to calling state. */ + DUK_ASSERT(heap->lj.jmpbuf_ptr == entry_jmpbuf_ptr); /* Longjmp handling has restored jmpbuf_ptr. */ + + /* Thread may have changed, e.g. YIELD converted to THROW. */ + duk_err_longjmp(heap->curr_thread); + DUK_UNREACHABLE(); + } +} + +/* Outer executor with setjmp/longjmp handling. */ +DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { + /* Entry level info. */ + duk_hthread *entry_thread; + duk_activation *entry_act; + duk_int_t entry_call_recursion_depth; + duk_jmpbuf *entry_jmpbuf_ptr; + duk_jmpbuf our_jmpbuf; + duk_heap *heap; + volatile duk_bool_t delayed_catch_setup = 0; + + DUK_ASSERT(exec_thr != NULL); + DUK_ASSERT(exec_thr->heap != NULL); + DUK_ASSERT(exec_thr->heap->curr_thread != NULL); + DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR((duk_heaphdr *) exec_thr); + DUK_ASSERT(exec_thr->callstack_top >= 1); /* at least one activation, ours */ + DUK_ASSERT(exec_thr->callstack_curr != NULL); + DUK_ASSERT(DUK_ACT_GET_FUNC(exec_thr->callstack_curr) != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(exec_thr->callstack_curr))); + + DUK_GC_TORTURE(exec_thr->heap); + + entry_thread = exec_thr; + heap = entry_thread->heap; + entry_act = entry_thread->callstack_curr; + DUK_ASSERT(entry_act != NULL); + entry_call_recursion_depth = entry_thread->heap->call_recursion_depth; + entry_jmpbuf_ptr = entry_thread->heap->lj.jmpbuf_ptr; + + /* + * Note: we currently assume that the setjmp() catchpoint is + * not re-entrant (longjmp() cannot be called more than once + * for a single setjmp()). + * + * See doc/code-issues.rst for notes on variable assignment + * before and after setjmp(). + */ + + for (;;) { + heap->lj.jmpbuf_ptr = &our_jmpbuf; + DUK_ASSERT(heap->lj.jmpbuf_ptr != NULL); + +#if defined(DUK_USE_CPP_EXCEPTIONS) + try { +#else + DUK_ASSERT(heap->lj.jmpbuf_ptr == &our_jmpbuf); + if (DUK_SETJMP(our_jmpbuf.jb) == 0) { +#endif + DUK_DDD(DUK_DDDPRINT("after setjmp, delayed catch setup: %ld\n", (long) delayed_catch_setup)); + + if (DUK_UNLIKELY(delayed_catch_setup != 0)) { + duk_hthread *thr = entry_thread->heap->curr_thread; + + delayed_catch_setup = 0; + duk__handle_catch_part2(thr); + DUK_ASSERT(delayed_catch_setup == 0); + DUK_DDD(DUK_DDDPRINT("top after delayed catch setup: %ld", (long) duk_get_top(entry_thread))); + } + + /* Execute bytecode until returned or longjmp(). */ + duk__js_execute_bytecode_inner(entry_thread, entry_act); + + /* Successful return: restore jmpbuf and return to caller. */ + heap->lj.jmpbuf_ptr = entry_jmpbuf_ptr; + + return; +#if defined(DUK_USE_CPP_EXCEPTIONS) + } catch (duk_internal_exception &exc) { +#else + } else { +#endif +#if defined(DUK_USE_CPP_EXCEPTIONS) + DUK_UNREF(exc); +#endif + DUK_DDD(DUK_DDDPRINT("longjmp caught by bytecode executor")); + DUK_STATS_INC(exec_thr->heap, stats_exec_throw); + + duk__handle_executor_error(heap, + entry_act, + entry_call_recursion_depth, + entry_jmpbuf_ptr, + &delayed_catch_setup); + } +#if defined(DUK_USE_CPP_EXCEPTIONS) + catch (duk_fatal_exception &exc) { + DUK_D(DUK_DPRINT("rethrow duk_fatal_exception")); + DUK_UNREF(exc); + throw; + } catch (std::exception &exc) { + const char *what = exc.what(); + if (!what) { + what = "unknown"; + } + DUK_D(DUK_DPRINT("unexpected c++ std::exception (perhaps thrown by user code)")); + DUK_STATS_INC(exec_thr->heap, stats_exec_throw); + try { + DUK_ASSERT(heap->curr_thread != NULL); + DUK_ERROR_FMT1(heap->curr_thread, DUK_ERR_TYPE_ERROR, "caught invalid c++ std::exception '%s' (perhaps thrown by user code)", what); + DUK_WO_NORETURN(return;); + } catch (duk_internal_exception exc) { + DUK_D(DUK_DPRINT("caught api error thrown from unexpected c++ std::exception")); + DUK_UNREF(exc); + duk__handle_executor_error(heap, + entry_act, + entry_call_recursion_depth, + entry_jmpbuf_ptr, + &delayed_catch_setup); + } + } catch (...) { + DUK_D(DUK_DPRINT("unexpected c++ exception (perhaps thrown by user code)")); + DUK_STATS_INC(exec_thr->heap, stats_exec_throw); + try { + DUK_ASSERT(heap->curr_thread != NULL); + DUK_ERROR_TYPE(heap->curr_thread, "caught invalid c++ exception (perhaps thrown by user code)"); + DUK_WO_NORETURN(return;); + } catch (duk_internal_exception exc) { + DUK_D(DUK_DPRINT("caught api error thrown from unexpected c++ exception")); + DUK_UNREF(exc); + duk__handle_executor_error(heap, + entry_act, + entry_call_recursion_depth, + entry_jmpbuf_ptr, + &delayed_catch_setup); + } + } +#endif + } + + DUK_WO_NORETURN(return;); +} + +/* Inner executor, performance critical. */ +DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, duk_activation *entry_act) { + /* Current PC, accessed by other functions through thr->ptr_to_curr_pc. + * Critical for performance. It would be safest to make this volatile, + * but that eliminates performance benefits; aliasing guarantees + * should be enough though. + */ + duk_instr_t *curr_pc; /* bytecode has a stable pointer */ + + /* Hot variables for interpretation. Critical for performance, + * but must add sparingly to minimize register shuffling. + */ + duk_hthread *thr; /* stable */ + duk_tval *consts; /* stable */ + duk_uint_fast32_t ins; + /* 'funcs' is quite rarely used, so no local for it */ +#if defined(DUK_USE_EXEC_FUN_LOCAL) + duk_hcompfunc *fun; +#else + /* 'fun' is quite rarely used, so no local for it */ +#endif + +#if defined(DUK_USE_INTERRUPT_COUNTER) + duk_int_t int_ctr; +#endif + +#if defined(DUK_USE_ASSERTIONS) + duk_size_t valstack_top_base; /* valstack top, should match before interpreting each op (no leftovers) */ +#endif + + /* Optimized reg/const access macros assume sizeof(duk_tval) to be + * either 8 or 16. Heap allocation checks this even without asserts + * enabled now because it can't be autodetected in duk_config.h. + */ +#if 1 +#if defined(DUK_USE_PACKED_TVAL) + DUK_ASSERT(sizeof(duk_tval) == 8); +#else + DUK_ASSERT(sizeof(duk_tval) == 16); +#endif +#endif + + DUK_GC_TORTURE(entry_thread->heap); + + /* + * Restart execution by reloading thread state. + * + * Note that 'thr' and any thread configuration may have changed, + * so all local variables are suspect and we need to reinitialize. + * + * The number of local variables should be kept to a minimum: if + * the variables are spilled, they will need to be loaded from + * memory anyway. + * + * Any 'goto restart_execution;' code path in opcode dispatch must + * ensure 'curr_pc' is synced back to act->curr_pc before the goto + * takes place. + * + * The interpreter must be very careful with memory pointers, as + * many pointers are not guaranteed to be 'stable' and may be + * reallocated and relocated on-the-fly quite easily (e.g. by a + * memory allocation or a property access). + * + * The following are assumed to have stable pointers: + * - the current thread + * - the current function + * - the bytecode, constant table, inner function table of the + * current function (as they are a part of the function allocation) + * + * The following are assumed to have semi-stable pointers: + * - the current activation entry: stable as long as callstack + * is not changed (reallocated by growing or shrinking), or + * by any garbage collection invocation (through finalizers) + * - Note in particular that ANY DECREF can invalidate the + * activation pointer, so for the most part a fresh lookup + * is required + * + * The following are not assumed to have stable pointers at all: + * - the value stack (registers) of the current thread + * + * See execution.rst for discussion. + */ + + restart_execution: + + /* Lookup current thread; use the stable 'entry_thread' for this to + * avoid clobber warnings. Any valid, reachable 'thr' value would be + * fine for this, so using 'entry_thread' is just to silence warnings. + */ + thr = entry_thread->heap->curr_thread; + DUK_ASSERT(thr != NULL); + DUK_ASSERT(thr->callstack_top >= 1); + DUK_ASSERT(thr->callstack_curr != NULL); + DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr))); + + DUK_GC_TORTURE(thr->heap); + + thr->ptr_curr_pc = &curr_pc; + + /* Relookup and initialize dispatch loop variables. Debugger check. */ + { + duk_activation *act; +#if !defined(DUK_USE_EXEC_FUN_LOCAL) + duk_hcompfunc *fun; +#endif + + /* Assume interrupt init/counter are properly initialized here. */ + /* Assume that thr->valstack_bottom has been set-up before getting here. */ + + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + fun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act); + DUK_ASSERT(fun != NULL); + DUK_ASSERT(thr->valstack_top - thr->valstack_bottom == fun->nregs); + consts = DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, fun); + DUK_ASSERT(consts != NULL); + +#if defined(DUK_USE_DEBUGGER_SUPPORT) + if (DUK_UNLIKELY(duk_debug_is_attached(thr->heap) && !thr->heap->dbg_processing)) { + duk__executor_recheck_debugger(thr, act, fun); + DUK_ASSERT(act == thr->callstack_curr); + DUK_ASSERT(act != NULL); + } +#endif /* DUK_USE_DEBUGGER_SUPPORT */ + +#if defined(DUK_USE_ASSERTIONS) + valstack_top_base = (duk_size_t) (thr->valstack_top - thr->valstack); +#endif + + /* Set up curr_pc for opcode dispatch. */ + curr_pc = act->curr_pc; + } + + DUK_DD(DUK_DDPRINT("restarting execution, thr %p, act idx %ld, fun %p," + "consts %p, funcs %p, lev %ld, regbot %ld, regtop %ld, " + "preventcount=%ld", + (void *) thr, + (long) (thr->callstack_top - 1), + (void *) DUK__FUN(), + (void *) DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, DUK__FUN()), + (void *) DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, DUK__FUN()), + (long) (thr->callstack_top - 1), + (long) (thr->valstack_bottom - thr->valstack), + (long) (thr->valstack_top - thr->valstack), + (long) thr->callstack_preventcount)); + + /* Dispatch loop. */ + + for (;;) { + duk_uint8_t op; + + DUK_ASSERT(thr->callstack_top >= 1); + DUK_ASSERT(thr->valstack_top - thr->valstack_bottom == DUK__FUN()->nregs); + DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack) == valstack_top_base); + + /* Executor interrupt counter check, used to implement breakpoints, + * debugging interface, execution timeouts, etc. The counter is heap + * specific but is maintained in the current thread to make the check + * as fast as possible. The counter is copied back to the heap struct + * whenever a thread switch occurs by the DUK_HEAP_SWITCH_THREAD() macro. + */ +#if defined(DUK_USE_INTERRUPT_COUNTER) + int_ctr = thr->interrupt_counter; + if (DUK_LIKELY(int_ctr > 0)) { + thr->interrupt_counter = int_ctr - 1; + } else { + /* Trigger at zero or below */ + duk_small_uint_t exec_int_ret; + + DUK_STATS_INC(thr->heap, stats_exec_interrupt); + + /* Write curr_pc back for the debugger. */ + { + duk_activation *act; + DUK_ASSERT(thr->callstack_top > 0); + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + act->curr_pc = (duk_instr_t *) curr_pc; + } + + /* Forced restart caused by a function return; must recheck + * debugger breakpoints before checking line transitions, + * see GH-303. Restart and then handle interrupt_counter + * zero again. + */ +#if defined(DUK_USE_DEBUGGER_SUPPORT) + if (thr->heap->dbg_force_restart) { + DUK_DD(DUK_DDPRINT("dbg_force_restart flag forced restart execution")); /* GH-303 */ + thr->heap->dbg_force_restart = 0; + goto restart_execution; + } +#endif + + exec_int_ret = duk__executor_interrupt(thr); + if (exec_int_ret == DUK__INT_RESTART) { + /* curr_pc synced back above */ + goto restart_execution; + } + } +#endif /* DUK_USE_INTERRUPT_COUNTER */ +#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG) + /* For cross-checking during development: ensure dispatch count + * matches cumulative interrupt counter init value sums. + */ + thr->heap->inst_count_exec++; +#endif + +#if defined(DUK_USE_ASSERTIONS) || defined(DUK_USE_DEBUG) + { + duk_activation *act; + act = thr->callstack_curr; + DUK_ASSERT(curr_pc >= DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, DUK__FUN())); + DUK_ASSERT(curr_pc < DUK_HCOMPFUNC_GET_CODE_END(thr->heap, DUK__FUN())); + DUK_UNREF(act); /* if debugging disabled */ + + DUK_DDD(DUK_DDDPRINT("executing bytecode: pc=%ld, ins=0x%08lx, op=%ld, valstack_top=%ld/%ld, nregs=%ld --> %!I", + (long) (curr_pc - DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, DUK__FUN())), + (unsigned long) *curr_pc, + (long) DUK_DEC_OP(*curr_pc), + (long) (thr->valstack_top - thr->valstack), + (long) (thr->valstack_end - thr->valstack), + (long) (DUK__FUN() ? DUK__FUN()->nregs : -1), + (duk_instr_t) *curr_pc)); + } +#endif + +#if defined(DUK_USE_ASSERTIONS) + /* Quite heavy assert: check valstack policy. Improper + * shuffle instructions can write beyond valstack_top/end + * so this check catches them in the act. + */ + { + duk_tval *tv; + tv = thr->valstack_top; + while (tv != thr->valstack_end) { + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv)); + tv++; + } + } +#endif + + ins = *curr_pc++; + DUK_STATS_INC(thr->heap, stats_exec_opcodes); + + /* Typing: use duk_small_(u)int_fast_t when decoding small + * opcode fields (op, A, B, C, BC) which fit into 16 bits + * and duk_(u)int_fast_t when decoding larger fields (e.g. + * ABC). Use unsigned variant by default, signed when the + * value is used in signed arithmetic. Using variable names + * such as 'a', 'b', 'c', 'bc', etc makes it easier to spot + * typing mismatches. + */ + + /* Switch based on opcode. Cast to 8-bit unsigned value and + * use a fully populated case clauses so that the compiler + * will (at least usually) omit a bounds check. + */ + op = (duk_uint8_t) DUK_DEC_OP(ins); + switch (op) { + + /* Some useful macros. These access inner executor variables + * directly so they only apply within the executor. + */ +#if defined(DUK_USE_EXEC_PREFER_SIZE) +#define DUK__REPLACE_TOP_A_BREAK() { goto replace_top_a; } +#define DUK__REPLACE_TOP_BC_BREAK() { goto replace_top_bc; } +#define DUK__REPLACE_BOOL_A_BREAK(bval) { \ + duk_bool_t duk__bval; \ + duk__bval = (bval); \ + DUK_ASSERT(duk__bval == 0 || duk__bval == 1); \ + duk_push_boolean(thr, duk__bval); \ + DUK__REPLACE_TOP_A_BREAK(); \ + } +#else +#define DUK__REPLACE_TOP_A_BREAK() { DUK__REPLACE_TO_TVPTR(thr, DUK__REGP_A(ins)); break; } +#define DUK__REPLACE_TOP_BC_BREAK() { DUK__REPLACE_TO_TVPTR(thr, DUK__REGP_BC(ins)); break; } +#define DUK__REPLACE_BOOL_A_BREAK(bval) { \ + duk_bool_t duk__bval; \ + duk_tval *duk__tvdst; \ + duk__bval = (bval); \ + DUK_ASSERT(duk__bval == 0 || duk__bval == 1); \ + duk__tvdst = DUK__REGP_A(ins); \ + DUK_TVAL_SET_BOOLEAN_UPDREF(thr, duk__tvdst, duk__bval); \ + break; \ + } +#endif + + /* XXX: 12 + 12 bit variant might make sense too, for both reg and + * const loads. + */ + + /* For LDREG, STREG, LDCONST footprint optimized variants would just + * duk_dup() + duk_replace(), but because they're used quite a lot + * they're currently intentionally not size optimized. + */ + case DUK_OP_LDREG: { + duk_tval *tv1, *tv2; + + tv1 = DUK__REGP_A(ins); + tv2 = DUK__REGP_BC(ins); + DUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv1, tv2); /* side effects */ + break; + } + + case DUK_OP_STREG: { + duk_tval *tv1, *tv2; + + tv1 = DUK__REGP_A(ins); + tv2 = DUK__REGP_BC(ins); + DUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv2, tv1); /* side effects */ + break; + } + + case DUK_OP_LDCONST: { + duk_tval *tv1, *tv2; + + tv1 = DUK__REGP_A(ins); + tv2 = DUK__CONSTP_BC(ins); + DUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv1, tv2); /* side effects */ + break; + } + + /* LDINT and LDINTX are intended to load an arbitrary signed + * 32-bit value. Only an LDINT+LDINTX sequence is supported. + * This also guarantees all values remain fastints. + */ +#if defined(DUK_USE_EXEC_PREFER_SIZE) + case DUK_OP_LDINT: { + duk_int32_t val; + + val = (duk_int32_t) DUK_DEC_BC(ins) - (duk_int32_t) DUK_BC_LDINT_BIAS; + duk_push_int(thr, val); + DUK__REPLACE_TOP_A_BREAK(); + } + case DUK_OP_LDINTX: { + duk_int32_t val; + + val = (duk_int32_t) duk_get_int(thr, DUK_DEC_A(ins)); + val = (val << DUK_BC_LDINTX_SHIFT) + (duk_int32_t) DUK_DEC_BC(ins); /* no bias */ + duk_push_int(thr, val); + DUK__REPLACE_TOP_A_BREAK(); + } +#else /* DUK_USE_EXEC_PREFER_SIZE */ + case DUK_OP_LDINT: { + duk_tval *tv1; + duk_int32_t val; + + val = (duk_int32_t) DUK_DEC_BC(ins) - (duk_int32_t) DUK_BC_LDINT_BIAS; + tv1 = DUK__REGP_A(ins); + DUK_TVAL_SET_I32_UPDREF(thr, tv1, val); /* side effects */ + break; + } + case DUK_OP_LDINTX: { + duk_tval *tv1; + duk_int32_t val; + + tv1 = DUK__REGP_A(ins); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1)); +#if defined(DUK_USE_FASTINT) + DUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1)); + val = DUK_TVAL_GET_FASTINT_I32(tv1); +#else + /* XXX: fast double-to-int conversion, we know number is integer in [-0x80000000,0xffffffff]. */ + val = (duk_int32_t) DUK_TVAL_GET_NUMBER(tv1); +#endif + val = (duk_int32_t) ((duk_uint32_t) val << DUK_BC_LDINTX_SHIFT) + (duk_int32_t) DUK_DEC_BC(ins); /* no bias */ + DUK_TVAL_SET_I32_UPDREF(thr, tv1, val); /* side effects */ + break; + } +#endif /* DUK_USE_EXEC_PREFER_SIZE */ + +#if defined(DUK_USE_EXEC_PREFER_SIZE) + case DUK_OP_LDTHIS: { + duk_push_this(thr); + DUK__REPLACE_TOP_BC_BREAK(); + } + case DUK_OP_LDUNDEF: { + duk_to_undefined(thr, (duk_idx_t) DUK_DEC_BC(ins)); + break; + } + case DUK_OP_LDNULL: { + duk_to_null(thr, (duk_idx_t) DUK_DEC_BC(ins)); + break; + } + case DUK_OP_LDTRUE: { + duk_push_true(thr); + DUK__REPLACE_TOP_BC_BREAK(); + } + case DUK_OP_LDFALSE: { + duk_push_false(thr); + DUK__REPLACE_TOP_BC_BREAK(); + } +#else /* DUK_USE_EXEC_PREFER_SIZE */ + case DUK_OP_LDTHIS: { + /* Note: 'this' may be bound to any value, not just an object */ + duk_tval *tv1, *tv2; + + tv1 = DUK__REGP_BC(ins); + tv2 = thr->valstack_bottom - 1; /* 'this binding' is just under bottom */ + DUK_ASSERT(tv2 >= thr->valstack); + DUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv1, tv2); /* side effects */ + break; + } + case DUK_OP_LDUNDEF: { + duk_tval *tv1; + + tv1 = DUK__REGP_BC(ins); + DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1); /* side effects */ + break; + } + case DUK_OP_LDNULL: { + duk_tval *tv1; + + tv1 = DUK__REGP_BC(ins); + DUK_TVAL_SET_NULL_UPDREF(thr, tv1); /* side effects */ + break; + } + case DUK_OP_LDTRUE: { + duk_tval *tv1; + + tv1 = DUK__REGP_BC(ins); + DUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv1, 1); /* side effects */ + break; + } + case DUK_OP_LDFALSE: { + duk_tval *tv1; + + tv1 = DUK__REGP_BC(ins); + DUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv1, 0); /* side effects */ + break; + } +#endif /* DUK_USE_EXEC_PREFER_SIZE */ + + case DUK_OP_BNOT: { + duk__vm_bitwise_not(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins)); + break; + } + + case DUK_OP_LNOT: { + duk__vm_logical_not(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins)); + break; + } + +#if defined(DUK_USE_EXEC_PREFER_SIZE) + case DUK_OP_UNM: + case DUK_OP_UNP: { + duk__vm_arith_unary_op(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins), op); + break; + } +#else /* DUK_USE_EXEC_PREFER_SIZE */ + case DUK_OP_UNM: { + duk__vm_arith_unary_op(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins), DUK_OP_UNM); + break; + } + case DUK_OP_UNP: { + duk__vm_arith_unary_op(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins), DUK_OP_UNP); + break; + } +#endif /* DUK_USE_EXEC_PREFER_SIZE */ + +#if defined(DUK_USE_EXEC_PREFER_SIZE) + case DUK_OP_TYPEOF: { + duk_small_uint_t stridx; + + stridx = duk_js_typeof_stridx(DUK__REGP_BC(ins)); + DUK_ASSERT_STRIDX_VALID(stridx); + duk_push_hstring_stridx(thr, stridx); + DUK__REPLACE_TOP_A_BREAK(); + } +#else /* DUK_USE_EXEC_PREFER_SIZE */ + case DUK_OP_TYPEOF: { + duk_tval *tv; + duk_small_uint_t stridx; + duk_hstring *h_str; + + tv = DUK__REGP_BC(ins); + stridx = duk_js_typeof_stridx(tv); + DUK_ASSERT_STRIDX_VALID(stridx); + h_str = DUK_HTHREAD_GET_STRING(thr, stridx); + tv = DUK__REGP_A(ins); + DUK_TVAL_SET_STRING_UPDREF(thr, tv, h_str); + break; + } +#endif /* DUK_USE_EXEC_PREFER_SIZE */ + + case DUK_OP_TYPEOFID: { + duk_small_uint_t stridx; +#if !defined(DUK_USE_EXEC_PREFER_SIZE) + duk_hstring *h_str; +#endif + duk_activation *act; + duk_hstring *name; + duk_tval *tv; + + /* A -> target register + * BC -> constant index of identifier name + */ + + tv = DUK__CONSTP_BC(ins); + DUK_ASSERT(DUK_TVAL_IS_STRING(tv)); + name = DUK_TVAL_GET_STRING(tv); + tv = NULL; /* lookup has side effects */ + act = thr->callstack_curr; + if (duk_js_getvar_activation(thr, act, name, 0 /*throw*/)) { + /* -> [... val this] */ + tv = DUK_GET_TVAL_NEGIDX(thr, -2); + stridx = duk_js_typeof_stridx(tv); + tv = NULL; /* no longer needed */ + duk_pop_2_unsafe(thr); + } else { + /* unresolvable, no stack changes */ + stridx = DUK_STRIDX_LC_UNDEFINED; + } + DUK_ASSERT_STRIDX_VALID(stridx); +#if defined(DUK_USE_EXEC_PREFER_SIZE) + duk_push_hstring_stridx(thr, stridx); + DUK__REPLACE_TOP_A_BREAK(); +#else /* DUK_USE_EXEC_PREFER_SIZE */ + h_str = DUK_HTHREAD_GET_STRING(thr, stridx); + tv = DUK__REGP_A(ins); + DUK_TVAL_SET_STRING_UPDREF(thr, tv, h_str); + break; +#endif /* DUK_USE_EXEC_PREFER_SIZE */ + } + + /* Equality: E5 Sections 11.9.1, 11.9.3 */ + +#define DUK__EQ_BODY(barg,carg) { \ + duk_bool_t tmp; \ + tmp = duk_js_equals(thr, (barg), (carg)); \ + DUK_ASSERT(tmp == 0 || tmp == 1); \ + DUK__REPLACE_BOOL_A_BREAK(tmp); \ + } +#define DUK__NEQ_BODY(barg,carg) { \ + duk_bool_t tmp; \ + tmp = duk_js_equals(thr, (barg), (carg)); \ + DUK_ASSERT(tmp == 0 || tmp == 1); \ + tmp ^= 1; \ + DUK__REPLACE_BOOL_A_BREAK(tmp); \ + } +#define DUK__SEQ_BODY(barg,carg) { \ + duk_bool_t tmp; \ + tmp = duk_js_strict_equals((barg), (carg)); \ + DUK_ASSERT(tmp == 0 || tmp == 1); \ + DUK__REPLACE_BOOL_A_BREAK(tmp); \ + } +#define DUK__SNEQ_BODY(barg,carg) { \ + duk_bool_t tmp; \ + tmp = duk_js_strict_equals((barg), (carg)); \ + DUK_ASSERT(tmp == 0 || tmp == 1); \ + tmp ^= 1; \ + DUK__REPLACE_BOOL_A_BREAK(tmp); \ + } +#if defined(DUK_USE_EXEC_PREFER_SIZE) + case DUK_OP_EQ_RR: + case DUK_OP_EQ_CR: + case DUK_OP_EQ_RC: + case DUK_OP_EQ_CC: + DUK__EQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins)); + case DUK_OP_NEQ_RR: + case DUK_OP_NEQ_CR: + case DUK_OP_NEQ_RC: + case DUK_OP_NEQ_CC: + DUK__NEQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins)); + case DUK_OP_SEQ_RR: + case DUK_OP_SEQ_CR: + case DUK_OP_SEQ_RC: + case DUK_OP_SEQ_CC: + DUK__SEQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins)); + case DUK_OP_SNEQ_RR: + case DUK_OP_SNEQ_CR: + case DUK_OP_SNEQ_RC: + case DUK_OP_SNEQ_CC: + DUK__SNEQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins)); +#else /* DUK_USE_EXEC_PREFER_SIZE */ + case DUK_OP_EQ_RR: + DUK__EQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_EQ_CR: + DUK__EQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_EQ_RC: + DUK__EQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_EQ_CC: + DUK__EQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_NEQ_RR: + DUK__NEQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_NEQ_CR: + DUK__NEQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_NEQ_RC: + DUK__NEQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_NEQ_CC: + DUK__NEQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_SEQ_RR: + DUK__SEQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_SEQ_CR: + DUK__SEQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_SEQ_RC: + DUK__SEQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_SEQ_CC: + DUK__SEQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_SNEQ_RR: + DUK__SNEQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_SNEQ_CR: + DUK__SNEQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_SNEQ_RC: + DUK__SNEQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_SNEQ_CC: + DUK__SNEQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins)); +#endif /* DUK_USE_EXEC_PREFER_SIZE */ + +#define DUK__COMPARE_BODY(arg1,arg2,flags) { \ + duk_bool_t tmp; \ + tmp = duk_js_compare_helper(thr, (arg1), (arg2), (flags)); \ + DUK_ASSERT(tmp == 0 || tmp == 1); \ + DUK__REPLACE_BOOL_A_BREAK(tmp); \ + } +#define DUK__GT_BODY(barg,carg) DUK__COMPARE_BODY((carg), (barg), 0) +#define DUK__GE_BODY(barg,carg) DUK__COMPARE_BODY((barg), (carg), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST | DUK_COMPARE_FLAG_NEGATE) +#define DUK__LT_BODY(barg,carg) DUK__COMPARE_BODY((barg), (carg), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST) +#define DUK__LE_BODY(barg,carg) DUK__COMPARE_BODY((carg), (barg), DUK_COMPARE_FLAG_NEGATE) +#if defined(DUK_USE_EXEC_PREFER_SIZE) + case DUK_OP_GT_RR: + case DUK_OP_GT_CR: + case DUK_OP_GT_RC: + case DUK_OP_GT_CC: + DUK__GT_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins)); + case DUK_OP_GE_RR: + case DUK_OP_GE_CR: + case DUK_OP_GE_RC: + case DUK_OP_GE_CC: + DUK__GE_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins)); + case DUK_OP_LT_RR: + case DUK_OP_LT_CR: + case DUK_OP_LT_RC: + case DUK_OP_LT_CC: + DUK__LT_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins)); + case DUK_OP_LE_RR: + case DUK_OP_LE_CR: + case DUK_OP_LE_RC: + case DUK_OP_LE_CC: + DUK__LE_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins)); +#else /* DUK_USE_EXEC_PREFER_SIZE */ + case DUK_OP_GT_RR: + DUK__GT_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_GT_CR: + DUK__GT_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_GT_RC: + DUK__GT_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_GT_CC: + DUK__GT_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_GE_RR: + DUK__GE_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_GE_CR: + DUK__GE_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_GE_RC: + DUK__GE_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_GE_CC: + DUK__GE_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_LT_RR: + DUK__LT_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_LT_CR: + DUK__LT_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_LT_RC: + DUK__LT_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_LT_CC: + DUK__LT_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_LE_RR: + DUK__LE_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_LE_CR: + DUK__LE_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_LE_RC: + DUK__LE_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_LE_CC: + DUK__LE_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins)); +#endif /* DUK_USE_EXEC_PREFER_SIZE */ + + /* No size optimized variant at present for IF. */ + case DUK_OP_IFTRUE_R: { + if (duk_js_toboolean(DUK__REGP_BC(ins)) != 0) { + curr_pc++; + } + break; + } + case DUK_OP_IFTRUE_C: { + if (duk_js_toboolean(DUK__CONSTP_BC(ins)) != 0) { + curr_pc++; + } + break; + } + case DUK_OP_IFFALSE_R: { + if (duk_js_toboolean(DUK__REGP_BC(ins)) == 0) { + curr_pc++; + } + break; + } + case DUK_OP_IFFALSE_C: { + if (duk_js_toboolean(DUK__CONSTP_BC(ins)) == 0) { + curr_pc++; + } + break; + } + +#if defined(DUK_USE_EXEC_PREFER_SIZE) + case DUK_OP_ADD_RR: + case DUK_OP_ADD_CR: + case DUK_OP_ADD_RC: + case DUK_OP_ADD_CC: { + /* XXX: could leave value on stack top and goto replace_top_a; */ + duk__vm_arith_add(thr, DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins), DUK_DEC_A(ins)); + break; + } +#else /* DUK_USE_EXEC_PREFER_SIZE */ + case DUK_OP_ADD_RR: { + duk__vm_arith_add(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins)); + break; + } + case DUK_OP_ADD_CR: { + duk__vm_arith_add(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins)); + break; + } + case DUK_OP_ADD_RC: { + duk__vm_arith_add(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins)); + break; + } + case DUK_OP_ADD_CC: { + duk__vm_arith_add(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins)); + break; + } +#endif /* DUK_USE_EXEC_PREFER_SIZE */ + +#if defined(DUK_USE_EXEC_PREFER_SIZE) + case DUK_OP_SUB_RR: + case DUK_OP_SUB_CR: + case DUK_OP_SUB_RC: + case DUK_OP_SUB_CC: + case DUK_OP_MUL_RR: + case DUK_OP_MUL_CR: + case DUK_OP_MUL_RC: + case DUK_OP_MUL_CC: + case DUK_OP_DIV_RR: + case DUK_OP_DIV_CR: + case DUK_OP_DIV_RC: + case DUK_OP_DIV_CC: + case DUK_OP_MOD_RR: + case DUK_OP_MOD_CR: + case DUK_OP_MOD_RC: + case DUK_OP_MOD_CC: +#if defined(DUK_USE_ES7_EXP_OPERATOR) + case DUK_OP_EXP_RR: + case DUK_OP_EXP_CR: + case DUK_OP_EXP_RC: + case DUK_OP_EXP_CC: +#endif /* DUK_USE_ES7_EXP_OPERATOR */ + { + /* XXX: could leave value on stack top and goto replace_top_a; */ + duk__vm_arith_binary_op(thr, DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins), DUK_DEC_A(ins), op); + break; + } +#else /* DUK_USE_EXEC_PREFER_SIZE */ + case DUK_OP_SUB_RR: { + duk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB); + break; + } + case DUK_OP_SUB_CR: { + duk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB); + break; + } + case DUK_OP_SUB_RC: { + duk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB); + break; + } + case DUK_OP_SUB_CC: { + duk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB); + break; + } + case DUK_OP_MUL_RR: { + duk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL); + break; + } + case DUK_OP_MUL_CR: { + duk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL); + break; + } + case DUK_OP_MUL_RC: { + duk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL); + break; + } + case DUK_OP_MUL_CC: { + duk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL); + break; + } + case DUK_OP_DIV_RR: { + duk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV); + break; + } + case DUK_OP_DIV_CR: { + duk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV); + break; + } + case DUK_OP_DIV_RC: { + duk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV); + break; + } + case DUK_OP_DIV_CC: { + duk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV); + break; + } + case DUK_OP_MOD_RR: { + duk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD); + break; + } + case DUK_OP_MOD_CR: { + duk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD); + break; + } + case DUK_OP_MOD_RC: { + duk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD); + break; + } + case DUK_OP_MOD_CC: { + duk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD); + break; + } +#if defined(DUK_USE_ES7_EXP_OPERATOR) + case DUK_OP_EXP_RR: { + duk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP); + break; + } + case DUK_OP_EXP_CR: { + duk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP); + break; + } + case DUK_OP_EXP_RC: { + duk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP); + break; + } + case DUK_OP_EXP_CC: { + duk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP); + break; + } +#endif /* DUK_USE_ES7_EXP_OPERATOR */ +#endif /* DUK_USE_EXEC_PREFER_SIZE */ + +#if defined(DUK_USE_EXEC_PREFER_SIZE) + case DUK_OP_BAND_RR: + case DUK_OP_BAND_CR: + case DUK_OP_BAND_RC: + case DUK_OP_BAND_CC: + case DUK_OP_BOR_RR: + case DUK_OP_BOR_CR: + case DUK_OP_BOR_RC: + case DUK_OP_BOR_CC: + case DUK_OP_BXOR_RR: + case DUK_OP_BXOR_CR: + case DUK_OP_BXOR_RC: + case DUK_OP_BXOR_CC: + case DUK_OP_BASL_RR: + case DUK_OP_BASL_CR: + case DUK_OP_BASL_RC: + case DUK_OP_BASL_CC: + case DUK_OP_BLSR_RR: + case DUK_OP_BLSR_CR: + case DUK_OP_BLSR_RC: + case DUK_OP_BLSR_CC: + case DUK_OP_BASR_RR: + case DUK_OP_BASR_CR: + case DUK_OP_BASR_RC: + case DUK_OP_BASR_CC: { + /* XXX: could leave value on stack top and goto replace_top_a; */ + duk__vm_bitwise_binary_op(thr, DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins), DUK_DEC_A(ins), op); + break; + } +#else /* DUK_USE_EXEC_PREFER_SIZE */ + case DUK_OP_BAND_RR: { + duk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND); + break; + } + case DUK_OP_BAND_CR: { + duk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND); + break; + } + case DUK_OP_BAND_RC: { + duk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND); + break; + } + case DUK_OP_BAND_CC: { + duk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND); + break; + } + case DUK_OP_BOR_RR: { + duk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR); + break; + } + case DUK_OP_BOR_CR: { + duk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR); + break; + } + case DUK_OP_BOR_RC: { + duk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR); + break; + } + case DUK_OP_BOR_CC: { + duk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR); + break; + } + case DUK_OP_BXOR_RR: { + duk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR); + break; + } + case DUK_OP_BXOR_CR: { + duk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR); + break; + } + case DUK_OP_BXOR_RC: { + duk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR); + break; + } + case DUK_OP_BXOR_CC: { + duk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR); + break; + } + case DUK_OP_BASL_RR: { + duk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL); + break; + } + case DUK_OP_BASL_CR: { + duk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL); + break; + } + case DUK_OP_BASL_RC: { + duk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL); + break; + } + case DUK_OP_BASL_CC: { + duk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL); + break; + } + case DUK_OP_BLSR_RR: { + duk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR); + break; + } + case DUK_OP_BLSR_CR: { + duk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR); + break; + } + case DUK_OP_BLSR_RC: { + duk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR); + break; + } + case DUK_OP_BLSR_CC: { + duk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR); + break; + } + case DUK_OP_BASR_RR: { + duk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR); + break; + } + case DUK_OP_BASR_CR: { + duk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR); + break; + } + case DUK_OP_BASR_RC: { + duk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR); + break; + } + case DUK_OP_BASR_CC: { + duk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR); + break; + } +#endif /* DUK_USE_EXEC_PREFER_SIZE */ + + /* For INSTOF and IN, B is always a register. */ +#define DUK__INSTOF_BODY(barg,carg) { \ + duk_bool_t tmp; \ + tmp = duk_js_instanceof(thr, (barg), (carg)); \ + DUK_ASSERT(tmp == 0 || tmp == 1); \ + DUK__REPLACE_BOOL_A_BREAK(tmp); \ + } +#define DUK__IN_BODY(barg,carg) { \ + duk_bool_t tmp; \ + tmp = duk_js_in(thr, (barg), (carg)); \ + DUK_ASSERT(tmp == 0 || tmp == 1); \ + DUK__REPLACE_BOOL_A_BREAK(tmp); \ + } +#if defined(DUK_USE_EXEC_PREFER_SIZE) + case DUK_OP_INSTOF_RR: + case DUK_OP_INSTOF_CR: + case DUK_OP_INSTOF_RC: + case DUK_OP_INSTOF_CC: + DUK__INSTOF_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins)); + case DUK_OP_IN_RR: + case DUK_OP_IN_CR: + case DUK_OP_IN_RC: + case DUK_OP_IN_CC: + DUK__IN_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins)); +#else /* DUK_USE_EXEC_PREFER_SIZE */ + case DUK_OP_INSTOF_RR: + DUK__INSTOF_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_INSTOF_CR: + DUK__INSTOF_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_INSTOF_RC: + DUK__INSTOF_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_INSTOF_CC: + DUK__INSTOF_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_IN_RR: + DUK__IN_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_IN_CR: + DUK__IN_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_IN_RC: + DUK__IN_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_IN_CC: + DUK__IN_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins)); +#endif /* DUK_USE_EXEC_PREFER_SIZE */ + + /* Pre/post inc/dec for register variables, important for loops. */ +#if defined(DUK_USE_EXEC_PREFER_SIZE) + case DUK_OP_PREINCR: + case DUK_OP_PREDECR: + case DUK_OP_POSTINCR: + case DUK_OP_POSTDECR: { + duk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), op); + break; + } + case DUK_OP_PREINCV: + case DUK_OP_PREDECV: + case DUK_OP_POSTINCV: + case DUK_OP_POSTDECV: { + duk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), op, DUK__STRICT()); + break; + } +#else /* DUK_USE_EXEC_PREFER_SIZE */ + case DUK_OP_PREINCR: { + duk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_PREINCR); + break; + } + case DUK_OP_PREDECR: { + duk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_PREDECR); + break; + } + case DUK_OP_POSTINCR: { + duk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_POSTINCR); + break; + } + case DUK_OP_POSTDECR: { + duk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_POSTDECR); + break; + } + case DUK_OP_PREINCV: { + duk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_PREINCV, DUK__STRICT()); + break; + } + case DUK_OP_PREDECV: { + duk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_PREDECV, DUK__STRICT()); + break; + } + case DUK_OP_POSTINCV: { + duk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_POSTINCV, DUK__STRICT()); + break; + } + case DUK_OP_POSTDECV: { + duk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_POSTDECV, DUK__STRICT()); + break; + } +#endif /* DUK_USE_EXEC_PREFER_SIZE */ + + /* XXX: Move to separate helper, optimize for perf/size separately. */ + /* Preinc/predec for object properties. */ + case DUK_OP_PREINCP_RR: + case DUK_OP_PREINCP_CR: + case DUK_OP_PREINCP_RC: + case DUK_OP_PREINCP_CC: + case DUK_OP_PREDECP_RR: + case DUK_OP_PREDECP_CR: + case DUK_OP_PREDECP_RC: + case DUK_OP_PREDECP_CC: + case DUK_OP_POSTINCP_RR: + case DUK_OP_POSTINCP_CR: + case DUK_OP_POSTINCP_RC: + case DUK_OP_POSTINCP_CC: + case DUK_OP_POSTDECP_RR: + case DUK_OP_POSTDECP_CR: + case DUK_OP_POSTDECP_RC: + case DUK_OP_POSTDECP_CC: { + duk_tval *tv_obj; + duk_tval *tv_key; + duk_tval *tv_val; + duk_bool_t rc; + duk_double_t x, y, z; +#if !defined(DUK_USE_EXEC_PREFER_SIZE) + duk_tval *tv_dst; +#endif /* DUK_USE_EXEC_PREFER_SIZE */ + + /* A -> target reg + * B -> object reg/const (may be const e.g. in "'foo'[1]") + * C -> key reg/const + */ + + /* Opcode bits 0-1 are used to distinguish reg/const variants. + * Opcode bits 2-3 are used to distinguish inc/dec variants: + * Bit 2 = inc(0)/dec(1), bit 3 = pre(0)/post(1). + */ + DUK_ASSERT((DUK_OP_PREINCP_RR & 0x0c) == 0x00); + DUK_ASSERT((DUK_OP_PREDECP_RR & 0x0c) == 0x04); + DUK_ASSERT((DUK_OP_POSTINCP_RR & 0x0c) == 0x08); + DUK_ASSERT((DUK_OP_POSTDECP_RR & 0x0c) == 0x0c); + + tv_obj = DUK__REGCONSTP_B(ins); + tv_key = DUK__REGCONSTP_C(ins); + rc = duk_hobject_getprop(thr, tv_obj, tv_key); /* -> [val] */ + DUK_UNREF(rc); /* ignore */ + tv_obj = NULL; /* invalidated */ + tv_key = NULL; /* invalidated */ + + /* XXX: Fastint fast path would be useful here. Also fastints + * now lose their fastint status in current handling which is + * not intuitive. + */ + + x = duk_to_number_m1(thr); + duk_pop_unsafe(thr); + if (ins & DUK_BC_INCDECP_FLAG_DEC) { + y = x - 1.0; + } else { + y = x + 1.0; + } + + duk_push_number(thr, y); + tv_val = DUK_GET_TVAL_NEGIDX(thr, -1); + DUK_ASSERT(tv_val != NULL); + tv_obj = DUK__REGCONSTP_B(ins); + tv_key = DUK__REGCONSTP_C(ins); + rc = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, DUK__STRICT()); + DUK_UNREF(rc); /* ignore */ + tv_obj = NULL; /* invalidated */ + tv_key = NULL; /* invalidated */ + duk_pop_unsafe(thr); + + z = (ins & DUK_BC_INCDECP_FLAG_POST) ? x : y; +#if defined(DUK_USE_EXEC_PREFER_SIZE) + duk_push_number(thr, z); + DUK__REPLACE_TOP_A_BREAK(); +#else + tv_dst = DUK__REGP_A(ins); + DUK_TVAL_SET_NUMBER_UPDREF(thr, tv_dst, z); + break; +#endif + } + + /* XXX: GETPROP where object is 'this', GETPROPT? + * Occurs relatively often in object oriented code. + */ + +#define DUK__GETPROP_BODY(barg,carg) { \ + /* A -> target reg \ + * B -> object reg/const (may be const e.g. in "'foo'[1]") \ + * C -> key reg/const \ + */ \ + (void) duk_hobject_getprop(thr, (barg), (carg)); \ + DUK__REPLACE_TOP_A_BREAK(); \ + } +#define DUK__GETPROPC_BODY(barg,carg) { \ + /* Same as GETPROP but callability check for property-based calls. */ \ + duk_tval *tv__targ; \ + (void) duk_hobject_getprop(thr, (barg), (carg)); \ + DUK_GC_TORTURE(thr->heap); \ + tv__targ = DUK_GET_TVAL_NEGIDX(thr, -1); \ + if (DUK_UNLIKELY(!duk_is_callable_tval(thr, tv__targ))) { \ + /* Here we intentionally re-evaluate the macro \ + * arguments to deal with potentially changed \ + * valstack base pointer! \ + */ \ + duk_call_setup_propcall_error(thr, (barg), (carg)); \ + } \ + DUK__REPLACE_TOP_A_BREAK(); \ + } +#define DUK__PUTPROP_BODY(aarg,barg,carg) { \ + /* A -> object reg \ + * B -> key reg/const \ + * C -> value reg/const \ + * \ + * Note: intentional difference to register arrangement \ + * of e.g. GETPROP; 'A' must contain a register-only value. \ + */ \ + (void) duk_hobject_putprop(thr, (aarg), (barg), (carg), DUK__STRICT()); \ + break; \ + } +#define DUK__DELPROP_BODY(barg,carg) { \ + /* A -> result reg \ + * B -> object reg \ + * C -> key reg/const \ + */ \ + duk_bool_t rc; \ + rc = duk_hobject_delprop(thr, (barg), (carg), DUK__STRICT()); \ + DUK_ASSERT(rc == 0 || rc == 1); \ + DUK__REPLACE_BOOL_A_BREAK(rc); \ + } +#if defined(DUK_USE_EXEC_PREFER_SIZE) + case DUK_OP_GETPROP_RR: + case DUK_OP_GETPROP_CR: + case DUK_OP_GETPROP_RC: + case DUK_OP_GETPROP_CC: + DUK__GETPROP_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins)); +#if defined(DUK_USE_VERBOSE_ERRORS) + case DUK_OP_GETPROPC_RR: + case DUK_OP_GETPROPC_CR: + case DUK_OP_GETPROPC_RC: + case DUK_OP_GETPROPC_CC: + DUK__GETPROPC_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins)); +#endif + case DUK_OP_PUTPROP_RR: + case DUK_OP_PUTPROP_CR: + case DUK_OP_PUTPROP_RC: + case DUK_OP_PUTPROP_CC: + DUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins)); + case DUK_OP_DELPROP_RR: + case DUK_OP_DELPROP_RC: /* B is always reg */ + DUK__DELPROP_BODY(DUK__REGP_B(ins), DUK__REGCONSTP_C(ins)); +#else /* DUK_USE_EXEC_PREFER_SIZE */ + case DUK_OP_GETPROP_RR: + DUK__GETPROP_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_GETPROP_CR: + DUK__GETPROP_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_GETPROP_RC: + DUK__GETPROP_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_GETPROP_CC: + DUK__GETPROP_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins)); +#if defined(DUK_USE_VERBOSE_ERRORS) + case DUK_OP_GETPROPC_RR: + DUK__GETPROPC_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_GETPROPC_CR: + DUK__GETPROPC_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_GETPROPC_RC: + DUK__GETPROPC_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_GETPROPC_CC: + DUK__GETPROPC_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins)); +#endif + case DUK_OP_PUTPROP_RR: + DUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__REGP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_PUTPROP_CR: + DUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__CONSTP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_PUTPROP_RC: + DUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__REGP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_PUTPROP_CC: + DUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__CONSTP_B(ins), DUK__CONSTP_C(ins)); + case DUK_OP_DELPROP_RR: /* B is always reg */ + DUK__DELPROP_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins)); + case DUK_OP_DELPROP_RC: + DUK__DELPROP_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins)); +#endif /* DUK_USE_EXEC_PREFER_SIZE */ + + /* No fast path for DECLVAR now, it's quite a rare instruction. */ + case DUK_OP_DECLVAR_RR: + case DUK_OP_DECLVAR_CR: + case DUK_OP_DECLVAR_RC: + case DUK_OP_DECLVAR_CC: { + duk_activation *act; + duk_small_uint_fast_t a = DUK_DEC_A(ins); + duk_tval *tv1; + duk_hstring *name; + duk_small_uint_t prop_flags; + duk_bool_t is_func_decl; + + tv1 = DUK__REGCONSTP_B(ins); + DUK_ASSERT(DUK_TVAL_IS_STRING(tv1)); + name = DUK_TVAL_GET_STRING(tv1); + DUK_ASSERT(name != NULL); + + is_func_decl = ((a & DUK_BC_DECLVAR_FLAG_FUNC_DECL) != 0); + + /* XXX: declvar takes an duk_tval pointer, which is awkward and + * should be reworked. + */ + + /* Compiler is responsible for selecting property flags (configurability, + * writability, etc). + */ + prop_flags = a & DUK_PROPDESC_FLAGS_MASK; + + if (is_func_decl) { + duk_push_tval(thr, DUK__REGCONSTP_C(ins)); + } else { + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top)); /* valstack policy */ + thr->valstack_top++; + } + tv1 = DUK_GET_TVAL_NEGIDX(thr, -1); + + act = thr->callstack_curr; + if (duk_js_declvar_activation(thr, act, name, tv1, prop_flags, is_func_decl)) { + if (is_func_decl) { + /* Already declared, update value. */ + tv1 = DUK_GET_TVAL_NEGIDX(thr, -1); + duk_js_putvar_activation(thr, act, name, tv1, DUK__STRICT()); + } else { + /* Already declared but no initializer value + * (e.g. 'var xyz;'), no-op. + */ + } + } + + duk_pop_unsafe(thr); + break; + } + +#if defined(DUK_USE_REGEXP_SUPPORT) + /* The compiler should never emit DUK_OP_REGEXP if there is no + * regexp support. + */ + case DUK_OP_REGEXP_RR: + case DUK_OP_REGEXP_CR: + case DUK_OP_REGEXP_RC: + case DUK_OP_REGEXP_CC: { + /* A -> target register + * B -> bytecode (also contains flags) + * C -> escaped source + */ + + duk_push_tval(thr, DUK__REGCONSTP_C(ins)); + duk_push_tval(thr, DUK__REGCONSTP_B(ins)); /* -> [ ... escaped_source bytecode ] */ + duk_regexp_create_instance(thr); /* -> [ ... regexp_instance ] */ + DUK__REPLACE_TOP_A_BREAK(); + } +#endif /* DUK_USE_REGEXP_SUPPORT */ + + /* XXX: 'c' is unused, use whole BC, etc. */ + case DUK_OP_CSVAR_RR: + case DUK_OP_CSVAR_CR: + case DUK_OP_CSVAR_RC: + case DUK_OP_CSVAR_CC: { + /* The speciality of calling through a variable binding is that the + * 'this' value may be provided by the variable lookup: E5 Section 6.b.i. + * + * The only (standard) case where the 'this' binding is non-null is when + * (1) the variable is found in an object environment record, and + * (2) that object environment record is a 'with' block. + */ + + duk_activation *act; + duk_uint_fast_t idx; + duk_tval *tv1; + duk_hstring *name; + + /* A -> target registers (A, A + 1) for call setup + * B -> identifier name, usually constant but can be a register due to shuffling + */ + + tv1 = DUK__REGCONSTP_B(ins); + DUK_ASSERT(DUK_TVAL_IS_STRING(tv1)); + name = DUK_TVAL_GET_STRING(tv1); + DUK_ASSERT(name != NULL); + act = thr->callstack_curr; + (void) duk_js_getvar_activation(thr, act, name, 1 /*throw*/); /* -> [... val this] */ + + idx = (duk_uint_fast_t) DUK_DEC_A(ins); + + /* Could add direct value stack handling. */ + duk_replace(thr, (duk_idx_t) (idx + 1)); /* 'this' binding */ + duk_replace(thr, (duk_idx_t) idx); /* variable value (function, we hope, not checked here) */ + break; + } + + case DUK_OP_CLOSURE: { + duk_activation *act; + duk_hcompfunc *fun_act; + duk_small_uint_fast_t bc = DUK_DEC_BC(ins); + duk_hobject *fun_temp; + + /* A -> target reg + * BC -> inner function index + */ + + DUK_DDD(DUK_DDDPRINT("CLOSURE to target register %ld, fnum %ld (count %ld)", + (long) DUK_DEC_A(ins), (long) DUK_DEC_BC(ins), (long) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, DUK__FUN()))); + + DUK_ASSERT_DISABLE(bc >= 0); /* unsigned */ + DUK_ASSERT((duk_uint_t) bc < (duk_uint_t) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, DUK__FUN())); + + act = thr->callstack_curr; + fun_act = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act); + fun_temp = DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, fun_act)[bc]; + DUK_ASSERT(fun_temp != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(fun_temp)); + + DUK_DDD(DUK_DDDPRINT("CLOSURE: function template is: %p -> %!O", + (void *) fun_temp, (duk_heaphdr *) fun_temp)); + + if (act->lex_env == NULL) { + DUK_ASSERT(act->var_env == NULL); + duk_js_init_activation_environment_records_delayed(thr, act); + act = thr->callstack_curr; + } + DUK_ASSERT(act->lex_env != NULL); + DUK_ASSERT(act->var_env != NULL); + + /* functions always have a NEWENV flag, i.e. they get a + * new variable declaration environment, so only lex_env + * matters here. + */ + duk_js_push_closure(thr, + (duk_hcompfunc *) fun_temp, + act->var_env, + act->lex_env, + 1 /*add_auto_proto*/); + DUK__REPLACE_TOP_A_BREAK(); + } + + case DUK_OP_GETVAR: { + duk_activation *act; + duk_tval *tv1; + duk_hstring *name; + + tv1 = DUK__CONSTP_BC(ins); + DUK_ASSERT(DUK_TVAL_IS_STRING(tv1)); + name = DUK_TVAL_GET_STRING(tv1); + DUK_ASSERT(name != NULL); + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + (void) duk_js_getvar_activation(thr, act, name, 1 /*throw*/); /* -> [... val this] */ + duk_pop_unsafe(thr); /* 'this' binding is not needed here */ + DUK__REPLACE_TOP_A_BREAK(); + } + + case DUK_OP_PUTVAR: { + duk_activation *act; + duk_tval *tv1; + duk_hstring *name; + + tv1 = DUK__CONSTP_BC(ins); + DUK_ASSERT(DUK_TVAL_IS_STRING(tv1)); + name = DUK_TVAL_GET_STRING(tv1); + DUK_ASSERT(name != NULL); + + /* XXX: putvar takes a duk_tval pointer, which is awkward and + * should be reworked. + */ + + tv1 = DUK__REGP_A(ins); /* val */ + act = thr->callstack_curr; + duk_js_putvar_activation(thr, act, name, tv1, DUK__STRICT()); + break; + } + + case DUK_OP_DELVAR: { + duk_activation *act; + duk_tval *tv1; + duk_hstring *name; + duk_bool_t rc; + + tv1 = DUK__CONSTP_BC(ins); + DUK_ASSERT(DUK_TVAL_IS_STRING(tv1)); + name = DUK_TVAL_GET_STRING(tv1); + DUK_ASSERT(name != NULL); + act = thr->callstack_curr; + rc = duk_js_delvar_activation(thr, act, name); + DUK__REPLACE_BOOL_A_BREAK(rc); + } + + case DUK_OP_JUMP: { + /* Note: without explicit cast to signed, MSVC will + * apparently generate a large positive jump when the + * bias-corrected value would normally be negative. + */ + curr_pc += (duk_int_fast_t) DUK_DEC_ABC(ins) - (duk_int_fast_t) DUK_BC_JUMP_BIAS; + break; + } + +#define DUK__RETURN_SHARED() do { \ + duk_small_uint_t ret_result; \ + /* duk__handle_return() is guaranteed never to throw, except \ + * for potential out-of-memory situations which will then \ + * propagate out of the executor longjmp handler. \ + */ \ + DUK_ASSERT(thr->ptr_curr_pc == NULL); \ + ret_result = duk__handle_return(thr, entry_act); \ + if (ret_result == DUK__RETHAND_RESTART) { \ + goto restart_execution; \ + } \ + DUK_ASSERT(ret_result == DUK__RETHAND_FINISHED); \ + return; \ + } while (0) +#if defined(DUK_USE_EXEC_PREFER_SIZE) + case DUK_OP_RETREG: + case DUK_OP_RETCONST: + case DUK_OP_RETCONSTN: + case DUK_OP_RETUNDEF: { + /* BC -> return value reg/const */ + + DUK__SYNC_AND_NULL_CURR_PC(); + + if (op == DUK_OP_RETREG) { + duk_push_tval(thr, DUK__REGP_BC(ins)); + } else if (op == DUK_OP_RETUNDEF) { + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top)); /* valstack policy */ + thr->valstack_top++; + } else { + DUK_ASSERT(op == DUK_OP_RETCONST || op == DUK_OP_RETCONSTN); + duk_push_tval(thr, DUK__CONSTP_BC(ins)); + } + + DUK__RETURN_SHARED(); + } +#else /* DUK_USE_EXEC_PREFER_SIZE */ + case DUK_OP_RETREG: { + duk_tval *tv; + + DUK__SYNC_AND_NULL_CURR_PC(); + tv = DUK__REGP_BC(ins); + DUK_TVAL_SET_TVAL(thr->valstack_top, tv); + DUK_TVAL_INCREF(thr, tv); + thr->valstack_top++; + DUK__RETURN_SHARED(); + } + /* This will be unused without refcounting. */ + case DUK_OP_RETCONST: { + duk_tval *tv; + + DUK__SYNC_AND_NULL_CURR_PC(); + tv = DUK__CONSTP_BC(ins); + DUK_TVAL_SET_TVAL(thr->valstack_top, tv); + DUK_TVAL_INCREF(thr, tv); + thr->valstack_top++; + DUK__RETURN_SHARED(); + } + case DUK_OP_RETCONSTN: { + duk_tval *tv; + + DUK__SYNC_AND_NULL_CURR_PC(); + tv = DUK__CONSTP_BC(ins); + DUK_TVAL_SET_TVAL(thr->valstack_top, tv); +#if defined(DUK_USE_REFERENCE_COUNTING) + /* Without refcounting only RETCONSTN is used. */ + DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv)); /* no INCREF for this constant */ +#endif + thr->valstack_top++; + DUK__RETURN_SHARED(); + } + case DUK_OP_RETUNDEF: { + DUK__SYNC_AND_NULL_CURR_PC(); + thr->valstack_top++; /* value at valstack top is already undefined by valstack policy */ + DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top)); + DUK__RETURN_SHARED(); + } +#endif /* DUK_USE_EXEC_PREFER_SIZE */ + + case DUK_OP_LABEL: { + duk_activation *act; + duk_catcher *cat; + duk_small_uint_fast_t bc = DUK_DEC_BC(ins); + + /* Allocate catcher and populate it (must be atomic). */ + + cat = duk_hthread_catcher_alloc(thr); + DUK_ASSERT(cat != NULL); + + cat->flags = (duk_uint32_t) (DUK_CAT_TYPE_LABEL | (bc << DUK_CAT_LABEL_SHIFT)); + cat->pc_base = (duk_instr_t *) curr_pc; /* pre-incremented, points to first jump slot */ + cat->idx_base = 0; /* unused for label */ + cat->h_varname = NULL; + + act = thr->callstack_curr; + DUK_ASSERT(act != NULL); + cat->parent = act->cat; + act->cat = cat; + + DUK_DDD(DUK_DDDPRINT("LABEL catcher: flags=0x%08lx, pc_base=%ld, " + "idx_base=%ld, h_varname=%!O, label_id=%ld", + (long) cat->flags, (long) cat->pc_base, + (long) cat->idx_base, (duk_heaphdr *) cat->h_varname, (long) DUK_CAT_GET_LABEL(cat))); + + curr_pc += 2; /* skip jump slots */ + break; + } + + case DUK_OP_ENDLABEL: { + duk_activation *act; +#if (defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)) || defined(DUK_USE_ASSERTIONS) + duk_small_uint_fast_t bc = DUK_DEC_BC(ins); +#endif +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2) + DUK_DDD(DUK_DDDPRINT("ENDLABEL %ld", (long) bc)); +#endif + + act = thr->callstack_curr; + DUK_ASSERT(act->cat != NULL); + DUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_LABEL); + DUK_ASSERT((duk_uint_fast_t) DUK_CAT_GET_LABEL(act->cat) == bc); + duk_hthread_catcher_unwind_nolexenv_norz(thr, act); + + /* no need to unwind callstack */ + break; + } + + case DUK_OP_BREAK: { + duk_small_uint_fast_t bc = DUK_DEC_BC(ins); + + DUK__SYNC_AND_NULL_CURR_PC(); + duk__handle_break_or_continue(thr, (duk_uint_t) bc, DUK_LJ_TYPE_BREAK); + goto restart_execution; + } + + case DUK_OP_CONTINUE: { + duk_small_uint_fast_t bc = DUK_DEC_BC(ins); + + DUK__SYNC_AND_NULL_CURR_PC(); + duk__handle_break_or_continue(thr, (duk_uint_t) bc, DUK_LJ_TYPE_CONTINUE); + goto restart_execution; + } + + /* XXX: move to helper, too large to be inline here */ + case DUK_OP_TRYCATCH: { + duk__handle_op_trycatch(thr, ins, curr_pc); + curr_pc += 2; /* skip jump slots */ + break; + } + + case DUK_OP_ENDTRY: { + curr_pc = duk__handle_op_endtry(thr, ins); + break; + } + + case DUK_OP_ENDCATCH: { + duk__handle_op_endcatch(thr, ins); + break; + } + + case DUK_OP_ENDFIN: { + /* Sync and NULL early. */ + DUK__SYNC_AND_NULL_CURR_PC(); + + if (duk__handle_op_endfin(thr, ins, entry_act) != 0) { + return; + } + + /* Must restart because we NULLed out curr_pc. */ + goto restart_execution; + } + + case DUK_OP_THROW: { + duk_small_uint_fast_t bc = DUK_DEC_BC(ins); + + /* Note: errors are augmented when they are created, not + * when they are thrown. So, don't augment here, it would + * break re-throwing for instance. + */ + + /* Sync so that augmentation sees up-to-date activations, NULL + * thr->ptr_curr_pc so that it's not used if side effects occur + * in augmentation or longjmp handling. + */ + DUK__SYNC_AND_NULL_CURR_PC(); + + duk_dup(thr, (duk_idx_t) bc); + DUK_DDD(DUK_DDDPRINT("THROW ERROR (BYTECODE): %!dT (before throw augment)", + (duk_tval *) duk_get_tval(thr, -1))); +#if defined(DUK_USE_AUGMENT_ERROR_THROW) + duk_err_augment_error_throw(thr); + DUK_DDD(DUK_DDDPRINT("THROW ERROR (BYTECODE): %!dT (after throw augment)", + (duk_tval *) duk_get_tval(thr, -1))); +#endif + + duk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, DUK_GET_TVAL_NEGIDX(thr, -1)); +#if defined(DUK_USE_DEBUGGER_SUPPORT) + duk_err_check_debugger_integration(thr); +#endif + + DUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL); /* always in executor */ + duk_err_longjmp(thr); + DUK_UNREACHABLE(); + break; + } + + case DUK_OP_CSREG: { + /* + * Assuming a register binds to a variable declared within this + * function (a declarative binding), the 'this' for the call + * setup is always 'undefined'. E5 Section 10.2.1.1.6. + */ + + duk_small_uint_fast_t a = DUK_DEC_A(ins); + duk_small_uint_fast_t bc = DUK_DEC_BC(ins); + + /* A -> register containing target function (not type checked here) + * BC -> target registers (BC, BC + 1) for call setup + */ + +#if defined(DUK_USE_PREFER_SIZE) + duk_dup(thr, (duk_idx_t) a); + duk_replace(thr, (duk_idx_t) bc); + duk_to_undefined(thr, (duk_idx_t) (bc + 1)); +#else + duk_tval *tv1; + duk_tval *tv2; + duk_tval *tv3; + duk_tval tv_tmp1; + duk_tval tv_tmp2; + + tv1 = DUK__REGP(bc); + tv2 = tv1 + 1; + DUK_TVAL_SET_TVAL(&tv_tmp1, tv1); + DUK_TVAL_SET_TVAL(&tv_tmp2, tv2); + tv3 = DUK__REGP(a); + DUK_TVAL_SET_TVAL(tv1, tv3); + DUK_TVAL_INCREF(thr, tv1); /* no side effects */ + DUK_TVAL_SET_UNDEFINED(tv2); /* no need for incref */ + DUK_TVAL_DECREF(thr, &tv_tmp1); + DUK_TVAL_DECREF(thr, &tv_tmp2); +#endif + break; + } + + + /* XXX: in some cases it's faster NOT to reuse the value + * stack but rather copy the arguments on top of the stack + * (mainly when the calling value stack is large and the value + * stack resize would be large). + */ + + case DUK_OP_CALL0: + case DUK_OP_CALL1: + case DUK_OP_CALL2: + case DUK_OP_CALL3: + case DUK_OP_CALL4: + case DUK_OP_CALL5: + case DUK_OP_CALL6: + case DUK_OP_CALL7: { + /* Opcode packs 4 flag bits: 1 for indirect, 3 map + * 1:1 to three lowest call handling flags. + * + * A -> nargs or register with nargs (indirect) + * BC -> base register for call (base -> func, base+1 -> this, base+2 -> arg1 ... base+2+N-1 -> argN) + */ + + duk_idx_t nargs; + duk_idx_t idx; + duk_small_uint_t call_flags; +#if !defined(DUK_USE_EXEC_FUN_LOCAL) + duk_hcompfunc *fun; +#endif + + DUK_ASSERT((DUK_OP_CALL0 & 0x0fU) == 0); + DUK_ASSERT((ins & DUK_BC_CALL_FLAG_INDIRECT) == 0); + + nargs = (duk_idx_t) DUK_DEC_A(ins); + call_flags = (ins & 0x07U) | DUK_CALL_FLAG_ALLOW_ECMATOECMA; + idx = (duk_idx_t) DUK_DEC_BC(ins); + + if (duk__executor_handle_call(thr, idx, nargs, call_flags)) { + /* curr_pc synced by duk_handle_call_unprotected() */ + DUK_ASSERT(thr->ptr_curr_pc == NULL); + goto restart_execution; + } + DUK_ASSERT(thr->ptr_curr_pc != NULL); + + /* duk_js_call.c is required to restore the stack reserve + * so we only need to reset the top. + */ +#if !defined(DUK_USE_EXEC_FUN_LOCAL) + fun = DUK__FUN(); +#endif + duk_set_top_unsafe(thr, (duk_idx_t) fun->nregs); + + /* No need to reinit setjmp() catchpoint, as call handling + * will store and restore our state. + * + * When debugger is enabled, we need to recheck the activation + * status after returning. This is now handled by call handling + * and heap->dbg_force_restart. + */ + break; + } + + case DUK_OP_CALL8: + case DUK_OP_CALL9: + case DUK_OP_CALL10: + case DUK_OP_CALL11: + case DUK_OP_CALL12: + case DUK_OP_CALL13: + case DUK_OP_CALL14: + case DUK_OP_CALL15: { + /* Indirect variant. */ + duk_uint_fast_t nargs; + duk_idx_t idx; + duk_small_uint_t call_flags; +#if !defined(DUK_USE_EXEC_FUN_LOCAL) + duk_hcompfunc *fun; +#endif + + DUK_ASSERT((DUK_OP_CALL0 & 0x0fU) == 0); + DUK_ASSERT((ins & DUK_BC_CALL_FLAG_INDIRECT) != 0); + + nargs = (duk_uint_fast_t) DUK_DEC_A(ins); + DUK__LOOKUP_INDIRECT(nargs); + call_flags = (ins & 0x07U) | DUK_CALL_FLAG_ALLOW_ECMATOECMA; + idx = (duk_idx_t) DUK_DEC_BC(ins); + + if (duk__executor_handle_call(thr, idx, (duk_idx_t) nargs, call_flags)) { + DUK_ASSERT(thr->ptr_curr_pc == NULL); + goto restart_execution; + } + DUK_ASSERT(thr->ptr_curr_pc != NULL); + +#if !defined(DUK_USE_EXEC_FUN_LOCAL) + fun = DUK__FUN(); +#endif + duk_set_top_unsafe(thr, (duk_idx_t) fun->nregs); + break; + } + + case DUK_OP_NEWOBJ: { + duk_push_object(thr); +#if defined(DUK_USE_ASSERTIONS) + { + duk_hobject *h; + h = duk_require_hobject(thr, -1); + DUK_ASSERT(DUK_HOBJECT_GET_ESIZE(h) == 0); + DUK_ASSERT(DUK_HOBJECT_GET_ENEXT(h) == 0); + DUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0); + DUK_ASSERT(DUK_HOBJECT_GET_HSIZE(h) == 0); + } +#endif +#if !defined(DUK_USE_PREFER_SIZE) + /* XXX: could do a direct props realloc, but need hash size */ + duk_hobject_resize_entrypart(thr, duk_known_hobject(thr, -1), DUK_DEC_A(ins)); +#endif + DUK__REPLACE_TOP_BC_BREAK(); + } + + case DUK_OP_NEWARR: { + duk_push_array(thr); +#if defined(DUK_USE_ASSERTIONS) + { + duk_hobject *h; + h = duk_require_hobject(thr, -1); + DUK_ASSERT(DUK_HOBJECT_GET_ESIZE(h) == 0); + DUK_ASSERT(DUK_HOBJECT_GET_ENEXT(h) == 0); + DUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0); + DUK_ASSERT(DUK_HOBJECT_GET_HSIZE(h) == 0); + DUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(h)); + } +#endif +#if !defined(DUK_USE_PREFER_SIZE) + duk_hobject_realloc_props(thr, + duk_known_hobject(thr, -1), + 0 /*new_e_size*/, + DUK_DEC_A(ins) /*new_a_size*/, + 0 /*new_h_size*/, + 0 /*abandon_array*/); +#if 0 + duk_hobject_resize_arraypart(thr, duk_known_hobject(thr, -1), DUK_DEC_A(ins)); +#endif +#endif + DUK__REPLACE_TOP_BC_BREAK(); + } + + case DUK_OP_MPUTOBJ: + case DUK_OP_MPUTOBJI: { + duk_idx_t obj_idx; + duk_uint_fast_t idx, idx_end; + duk_small_uint_fast_t count; + + /* A -> register of target object + * B -> first register of key/value pair list + * or register containing first register number if indirect + * C -> number of key/value pairs * 2 + * (= number of value stack indices used starting from 'B') + */ + + obj_idx = DUK_DEC_A(ins); + DUK_ASSERT(duk_is_object(thr, obj_idx)); + + idx = (duk_uint_fast_t) DUK_DEC_B(ins); + if (DUK_DEC_OP(ins) == DUK_OP_MPUTOBJI) { + DUK__LOOKUP_INDIRECT(idx); + } + + count = (duk_small_uint_fast_t) DUK_DEC_C(ins); + DUK_ASSERT(count > 0); /* compiler guarantees */ + idx_end = idx + count; + +#if defined(DUK_USE_EXEC_INDIRECT_BOUND_CHECK) + if (DUK_UNLIKELY(idx_end > (duk_uint_fast_t) duk_get_top(thr))) { + /* XXX: use duk_is_valid_index() instead? */ + /* XXX: improve check; check against nregs, not against top */ + DUK__INTERNAL_ERROR("MPUTOBJ out of bounds"); + } +#endif + + /* Use 'force' flag to duk_def_prop() to ensure that any + * inherited properties don't prevent the operation. + * With ES2015 duplicate properties are allowed, so that we + * must overwrite any previous data or accessor property. + * + * With ES2015 computed property names the literal keys + * may be arbitrary values and need to be ToPropertyKey() + * coerced at runtime. + */ + do { + /* XXX: faster initialization (direct access or better primitives) */ + duk_dup(thr, (duk_idx_t) idx); + duk_dup(thr, (duk_idx_t) (idx + 1)); + duk_def_prop(thr, obj_idx, DUK_DEFPROP_HAVE_VALUE | + DUK_DEFPROP_FORCE | + DUK_DEFPROP_SET_WRITABLE | + DUK_DEFPROP_SET_ENUMERABLE | + DUK_DEFPROP_SET_CONFIGURABLE); + idx += 2; + } while (idx < idx_end); + break; + } + + case DUK_OP_INITSET: + case DUK_OP_INITGET: { + duk__handle_op_initset_initget(thr, ins); + break; + } + + case DUK_OP_MPUTARR: + case DUK_OP_MPUTARRI: { + duk_idx_t obj_idx; + duk_uint_fast_t idx, idx_end; + duk_small_uint_fast_t count; + duk_tval *tv1; + duk_uint32_t arr_idx; + + /* A -> register of target object + * B -> first register of value data (start_index, value1, value2, ..., valueN) + * or register containing first register number if indirect + * C -> number of key/value pairs (N) + */ + + obj_idx = DUK_DEC_A(ins); + DUK_ASSERT(duk_is_object(thr, obj_idx)); + + idx = (duk_uint_fast_t) DUK_DEC_B(ins); + if (DUK_DEC_OP(ins) == DUK_OP_MPUTARRI) { + DUK__LOOKUP_INDIRECT(idx); + } + + count = (duk_small_uint_fast_t) DUK_DEC_C(ins); + DUK_ASSERT(count > 0 + 1); /* compiler guarantees */ + idx_end = idx + count; + +#if defined(DUK_USE_EXEC_INDIRECT_BOUND_CHECK) + if (idx_end > (duk_uint_fast_t) duk_get_top(thr)) { + /* XXX: use duk_is_valid_index() instead? */ + /* XXX: improve check; check against nregs, not against top */ + DUK__INTERNAL_ERROR("MPUTARR out of bounds"); + } +#endif + + tv1 = DUK__REGP(idx); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1)); +#if defined(DUK_USE_FASTINT) + DUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1)); + arr_idx = (duk_uint32_t) DUK_TVAL_GET_FASTINT_U32(tv1); +#else + arr_idx = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv1); +#endif + idx++; + + do { + /* duk_xdef_prop() will define an own property without any array + * special behaviors. We'll need to set the array length explicitly + * in the end. For arrays with elisions, the compiler will emit an + * explicit SETALEN which will update the length. + */ + + /* XXX: because we're dealing with 'own' properties of a fresh array, + * the array initializer should just ensure that the array has a large + * enough array part and write the values directly into array part, + * and finally set 'length' manually in the end (as already happens now). + */ + + duk_dup(thr, (duk_idx_t) idx); + duk_xdef_prop_index_wec(thr, obj_idx, arr_idx); + + idx++; + arr_idx++; + } while (idx < idx_end); + + /* XXX: E5.1 Section 11.1.4 coerces the final length through + * ToUint32() which is odd but happens now as a side effect of + * 'arr_idx' type. + */ + duk_set_length(thr, obj_idx, (duk_size_t) (duk_uarridx_t) arr_idx); + break; + } + + case DUK_OP_SETALEN: { + duk_tval *tv1; + duk_hobject *h; + duk_uint32_t len; + + tv1 = DUK__REGP_A(ins); + DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv1)); + h = DUK_TVAL_GET_OBJECT(tv1); + DUK_ASSERT(DUK_HOBJECT_IS_ARRAY(h)); + + tv1 = DUK__REGP_BC(ins); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1)); +#if defined(DUK_USE_FASTINT) + DUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1)); + len = (duk_uint32_t) DUK_TVAL_GET_FASTINT_U32(tv1); +#else + len = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv1); +#endif + ((duk_harray *) h)->length = len; + break; + } + + case DUK_OP_INITENUM: { + duk__handle_op_initenum(thr, ins); + break; + } + + case DUK_OP_NEXTENUM: { + curr_pc += duk__handle_op_nextenum(thr, ins); + break; + } + + case DUK_OP_INVLHS: { + DUK_ERROR_REFERENCE(thr, DUK_STR_INVALID_LVALUE); + DUK_WO_NORETURN(return;); + break; + } + + case DUK_OP_DEBUGGER: { + /* Opcode only emitted by compiler when debugger + * support is enabled. Ignore it silently without + * debugger support, in case it has been loaded + * from precompiled bytecode. + */ +#if defined(DUK_USE_DEBUGGER_SUPPORT) + if (duk_debug_is_attached(thr->heap)) { + DUK_D(DUK_DPRINT("DEBUGGER statement encountered, halt execution")); + DUK__SYNC_AND_NULL_CURR_PC(); + duk_debug_halt_execution(thr, 1 /*use_prev_pc*/); + DUK_D(DUK_DPRINT("DEBUGGER statement finished, resume execution")); + goto restart_execution; + } else { + DUK_D(DUK_DPRINT("DEBUGGER statement ignored, debugger not attached")); + } +#else + DUK_D(DUK_DPRINT("DEBUGGER statement ignored, no debugger support")); +#endif + break; + } + + case DUK_OP_NOP: { + /* Nop, ignored, but ABC fields may carry a value e.g. + * for indirect opcode handling. + */ + break; + } + + case DUK_OP_INVALID: { + DUK_ERROR_FMT1(thr, DUK_ERR_ERROR, "INVALID opcode (%ld)", (long) DUK_DEC_ABC(ins)); + DUK_WO_NORETURN(return;); + break; + } + +#if defined(DUK_USE_ES6) + case DUK_OP_NEWTARGET: { + duk_push_new_target(thr); + DUK__REPLACE_TOP_BC_BREAK(); + } +#endif /* DUK_USE_ES6 */ + +#if !defined(DUK_USE_EXEC_PREFER_SIZE) +#if !defined(DUK_USE_ES7_EXP_OPERATOR) + case DUK_OP_EXP_RR: + case DUK_OP_EXP_CR: + case DUK_OP_EXP_RC: + case DUK_OP_EXP_CC: +#endif +#if !defined(DUK_USE_ES6) + case DUK_OP_NEWTARGET: +#endif +#if !defined(DUK_USE_VERBOSE_ERRORS) + case DUK_OP_GETPROPC_RR: + case DUK_OP_GETPROPC_CR: + case DUK_OP_GETPROPC_RC: + case DUK_OP_GETPROPC_CC: +#endif + case DUK_OP_UNUSED207: + case DUK_OP_UNUSED212: + case DUK_OP_UNUSED213: + case DUK_OP_UNUSED214: + case DUK_OP_UNUSED215: + case DUK_OP_UNUSED216: + case DUK_OP_UNUSED217: + case DUK_OP_UNUSED218: + case DUK_OP_UNUSED219: + case DUK_OP_UNUSED220: + case DUK_OP_UNUSED221: + case DUK_OP_UNUSED222: + case DUK_OP_UNUSED223: + case DUK_OP_UNUSED224: + case DUK_OP_UNUSED225: + case DUK_OP_UNUSED226: + case DUK_OP_UNUSED227: + case DUK_OP_UNUSED228: + case DUK_OP_UNUSED229: + case DUK_OP_UNUSED230: + case DUK_OP_UNUSED231: + case DUK_OP_UNUSED232: + case DUK_OP_UNUSED233: + case DUK_OP_UNUSED234: + case DUK_OP_UNUSED235: + case DUK_OP_UNUSED236: + case DUK_OP_UNUSED237: + case DUK_OP_UNUSED238: + case DUK_OP_UNUSED239: + case DUK_OP_UNUSED240: + case DUK_OP_UNUSED241: + case DUK_OP_UNUSED242: + case DUK_OP_UNUSED243: + case DUK_OP_UNUSED244: + case DUK_OP_UNUSED245: + case DUK_OP_UNUSED246: + case DUK_OP_UNUSED247: + case DUK_OP_UNUSED248: + case DUK_OP_UNUSED249: + case DUK_OP_UNUSED250: + case DUK_OP_UNUSED251: + case DUK_OP_UNUSED252: + case DUK_OP_UNUSED253: + case DUK_OP_UNUSED254: + case DUK_OP_UNUSED255: + /* Force all case clauses to map to an actual handler + * so that the compiler can emit a jump without a bounds + * check: the switch argument is a duk_uint8_t so that + * the compiler may be able to figure it out. This is + * a small detail and obviously compiler dependent. + */ + /* default: clause omitted on purpose */ +#else /* DUK_USE_EXEC_PREFER_SIZE */ + default: +#endif /* DUK_USE_EXEC_PREFER_SIZE */ + { + /* Default case catches invalid/unsupported opcodes. */ + DUK_D(DUK_DPRINT("invalid opcode: %ld - %!I", (long) op, ins)); + DUK__INTERNAL_ERROR("invalid opcode"); + break; + } + + } /* end switch */ + + continue; + + /* Some shared exit paths for opcode handling below. These + * are mostly useful to reduce code footprint when multiple + * opcodes have a similar epilogue (like replacing stack top + * with index 'a'). + */ + +#if defined(DUK_USE_EXEC_PREFER_SIZE) + replace_top_a: + DUK__REPLACE_TO_TVPTR(thr, DUK__REGP_A(ins)); + continue; + replace_top_bc: + DUK__REPLACE_TO_TVPTR(thr, DUK__REGP_BC(ins)); + continue; +#endif + } + DUK_WO_NORETURN(return;); + +#if !defined(DUK_USE_VERBOSE_EXECUTOR_ERRORS) + internal_error: + DUK_ERROR_INTERNAL(thr); + DUK_WO_NORETURN(return;); +#endif +} diff --git a/third_party/duktape/duk_js_ops.c b/third_party/duktape/duk_js_ops.c new file mode 100644 index 00000000..8d49cd82 --- /dev/null +++ b/third_party/duktape/duk_js_ops.c @@ -0,0 +1,1476 @@ +/* + * ECMAScript specification algorithm and conversion helpers. + * + * These helpers encapsulate the primitive ECMAScript operation semantics, + * and are used by the bytecode executor and the API (among other places). + * Some primitives are only implemented as part of the API and have no + * "internal" helper. This is the case when an internal helper would not + * really be useful; e.g. the operation is rare, uses value stack heavily, + * etc. + * + * The operation arguments depend on what is required to implement + * the operation: + * + * - If an operation is simple and stateless, and has no side + * effects, it won't take an duk_hthread argument and its + * arguments may be duk_tval pointers (which are safe as long + * as no side effects take place). + * + * - If complex coercions are required (e.g. a "ToNumber" coercion) + * or errors may be thrown, the operation takes an duk_hthread + * argument. This also implies that the operation may have + * arbitrary side effects, invalidating any duk_tval pointers. + * + * - For operations with potential side effects, arguments can be + * taken in several ways: + * + * a) as duk_tval pointers, which makes sense if the "common case" + * can be resolved without side effects (e.g. coercion); the + * arguments are pushed to the valstack for coercion if + * necessary + * + * b) as duk_tval values + * + * c) implicitly on value stack top + * + * d) as indices to the value stack + * + * Future work: + * + * - Argument styles may not be the most sensible in every case now. + * + * - In-place coercions might be useful for several operations, if + * in-place coercion is OK for the bytecode executor and the API. + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * ToPrimitive() (E5 Section 9.1) + * + * ==> implemented in the API. + */ + +/* + * ToBoolean() (E5 Section 9.2) + */ + +DUK_INTERNAL duk_bool_t duk_js_toboolean(duk_tval *tv) { + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_UNDEFINED: + case DUK_TAG_NULL: + return 0; + case DUK_TAG_BOOLEAN: + DUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv) == 0 || DUK_TVAL_GET_BOOLEAN(tv) == 1); + return DUK_TVAL_GET_BOOLEAN(tv); + case DUK_TAG_STRING: { + /* Symbols ToBoolean() coerce to true, regardless of their + * description. This happens with no explicit check because + * of the symbol representation byte prefix. + */ + duk_hstring *h = DUK_TVAL_GET_STRING(tv); + DUK_ASSERT(h != NULL); + return (DUK_HSTRING_GET_BYTELEN(h) > 0 ? 1 : 0); + } + case DUK_TAG_OBJECT: { + return 1; + } + case DUK_TAG_BUFFER: { + /* Mimic Uint8Array semantics: objects coerce true, regardless + * of buffer length (zero or not) or context. + */ + return 1; + } + case DUK_TAG_POINTER: { + void *p = DUK_TVAL_GET_POINTER(tv); + return (p != NULL ? 1 : 0); + } + case DUK_TAG_LIGHTFUNC: { + return 1; + } +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: + if (DUK_TVAL_GET_FASTINT(tv) != 0) { + return 1; + } else { + return 0; + } +#endif + default: { + /* number */ + duk_double_t d; +#if defined(DUK_USE_PREFER_SIZE) + int c; +#endif + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv)); + DUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv)); + d = DUK_TVAL_GET_DOUBLE(tv); +#if defined(DUK_USE_PREFER_SIZE) + c = DUK_FPCLASSIFY((double) d); + if (c == DUK_FP_ZERO || c == DUK_FP_NAN) { + return 0; + } else { + return 1; + } +#else + DUK_ASSERT(duk_double_is_nan_or_zero(d) == 0 || duk_double_is_nan_or_zero(d) == 1); + return duk_double_is_nan_or_zero(d) ^ 1; +#endif + } + } + DUK_UNREACHABLE(); + DUK_WO_UNREACHABLE(return 0;); +} + +/* + * ToNumber() (E5 Section 9.3) + * + * Value to convert must be on stack top, and is popped before exit. + * + * See: http://www.cs.indiana.edu/~burger/FP-Printing-PLDI96.pdf + * http://www.cs.indiana.edu/~burger/fp/index.html + * + * Notes on the conversion: + * + * - There are specific requirements on the accuracy of the conversion + * through a "Mathematical Value" (MV), so this conversion is not + * trivial. + * + * - Quick rejects (e.g. based on first char) are difficult because + * the grammar allows leading and trailing white space. + * + * - Quick reject based on string length is difficult even after + * accounting for white space; there may be arbitrarily many + * decimal digits. + * + * - Standard grammar allows decimal values ("123"), hex values + * ("0x123") and infinities + * + * - Unlike source code literals, ToNumber() coerces empty strings + * and strings with only whitespace to zero (not NaN). However, + * while '' coerces to 0, '+' and '-' coerce to NaN. + */ + +/* E5 Section 9.3.1 */ +DUK_LOCAL duk_double_t duk__tonumber_string_raw(duk_hthread *thr) { + duk_small_uint_t s2n_flags; + duk_double_t d; + + DUK_ASSERT(duk_is_string(thr, -1)); + + /* Quite lenient, e.g. allow empty as zero, but don't allow trailing + * garbage. + */ + s2n_flags = DUK_S2N_FLAG_TRIM_WHITE | + DUK_S2N_FLAG_ALLOW_EXP | + DUK_S2N_FLAG_ALLOW_PLUS | + DUK_S2N_FLAG_ALLOW_MINUS | + DUK_S2N_FLAG_ALLOW_INF | + DUK_S2N_FLAG_ALLOW_FRAC | + DUK_S2N_FLAG_ALLOW_NAKED_FRAC | + DUK_S2N_FLAG_ALLOW_EMPTY_FRAC | + DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO | + DUK_S2N_FLAG_ALLOW_LEADING_ZERO | + DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT | + DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT | + DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT; + + duk_numconv_parse(thr, 10 /*radix*/, s2n_flags); + +#if defined(DUK_USE_PREFER_SIZE) + d = duk_get_number(thr, -1); + duk_pop_unsafe(thr); +#else + thr->valstack_top--; + DUK_ASSERT(DUK_TVAL_IS_NUMBER(thr->valstack_top)); + DUK_ASSERT(DUK_TVAL_IS_DOUBLE(thr->valstack_top)); /* no fastint conversion in numconv now */ + DUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(thr->valstack_top)); + d = DUK_TVAL_GET_DOUBLE(thr->valstack_top); /* assumes not a fastint */ + DUK_TVAL_SET_UNDEFINED(thr->valstack_top); +#endif + + return d; +} + +DUK_INTERNAL duk_double_t duk_js_tonumber(duk_hthread *thr, duk_tval *tv) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(tv != NULL); + + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_UNDEFINED: { + /* return a specific NaN (although not strictly necessary) */ + duk_double_union du; + DUK_DBLUNION_SET_NAN(&du); + DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du)); + return du.d; + } + case DUK_TAG_NULL: { + /* +0.0 */ + return 0.0; + } + case DUK_TAG_BOOLEAN: { + if (DUK_TVAL_IS_BOOLEAN_TRUE(tv)) { + return 1.0; + } + return 0.0; + } + case DUK_TAG_STRING: { + /* For Symbols ToNumber() is always a TypeError. */ + duk_hstring *h = DUK_TVAL_GET_STRING(tv); + if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) { + DUK_ERROR_TYPE(thr, DUK_STR_CANNOT_NUMBER_COERCE_SYMBOL); + DUK_WO_NORETURN(return 0.0;); + } + duk_push_hstring(thr, h); + return duk__tonumber_string_raw(thr); + } + case DUK_TAG_BUFFER: /* plain buffer treated like object */ + case DUK_TAG_OBJECT: { + duk_double_t d; + duk_push_tval(thr, tv); + duk_to_primitive(thr, -1, DUK_HINT_NUMBER); /* 'tv' becomes invalid */ + + /* recursive call for a primitive value (guaranteed not to cause second + * recursion). + */ + DUK_ASSERT(duk_get_tval(thr, -1) != NULL); + d = duk_js_tonumber(thr, duk_get_tval(thr, -1)); + + duk_pop_unsafe(thr); + return d; + } + case DUK_TAG_POINTER: { + /* Coerce like boolean */ + void *p = DUK_TVAL_GET_POINTER(tv); + return (p != NULL ? 1.0 : 0.0); + } + case DUK_TAG_LIGHTFUNC: { + /* +(function(){}) -> NaN */ + return DUK_DOUBLE_NAN; + } +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: + return (duk_double_t) DUK_TVAL_GET_FASTINT(tv); +#endif + default: { + /* number */ + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv)); + DUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv)); + return DUK_TVAL_GET_DOUBLE(tv); + } + } + + DUK_UNREACHABLE(); + DUK_WO_UNREACHABLE(return 0.0;); +} + +/* + * ToInteger() (E5 Section 9.4) + */ + +/* exposed, used by e.g. duk_bi_date.c */ +DUK_INTERNAL duk_double_t duk_js_tointeger_number(duk_double_t x) { +#if defined(DUK_USE_PREFER_SIZE) + duk_small_int_t c = (duk_small_int_t) DUK_FPCLASSIFY(x); + + if (DUK_UNLIKELY(c == DUK_FP_NAN)) { + return 0.0; + } else if (DUK_UNLIKELY(c == DUK_FP_INFINITE)) { + return x; + } else { + /* Finite, including neg/pos zero. Neg zero sign must be + * preserved. + */ + return duk_double_trunc_towards_zero(x); + } +#else /* DUK_USE_PREFER_SIZE */ + /* NaN and Infinity have the same exponent so it's a cheap + * initial check for the rare path. + */ + if (DUK_UNLIKELY(duk_double_is_nan_or_inf(x) != 0U)) { + if (duk_double_is_nan(x)) { + return 0.0; + } else { + return x; + } + } else { + return duk_double_trunc_towards_zero(x); + } +#endif /* DUK_USE_PREFER_SIZE */ +} + +DUK_INTERNAL duk_double_t duk_js_tointeger(duk_hthread *thr, duk_tval *tv) { + /* XXX: fastint */ + duk_double_t d = duk_js_tonumber(thr, tv); /* invalidates tv */ + return duk_js_tointeger_number(d); +} + +/* + * ToInt32(), ToUint32(), ToUint16() (E5 Sections 9.5, 9.6, 9.7) + */ + +/* combined algorithm matching E5 Sections 9.5 and 9.6 */ +DUK_LOCAL duk_double_t duk__toint32_touint32_helper(duk_double_t x, duk_bool_t is_toint32) { +#if defined (DUK_USE_PREFER_SIZE) + duk_small_int_t c; +#endif + +#if defined (DUK_USE_PREFER_SIZE) + c = (duk_small_int_t) DUK_FPCLASSIFY(x); + if (c == DUK_FP_NAN || c == DUK_FP_ZERO || c == DUK_FP_INFINITE) { + return 0.0; + } +#else + if (duk_double_is_nan_zero_inf(x)) { + return 0.0; + } +#endif + + /* x = sign(x) * floor(abs(x)), i.e. truncate towards zero, keep sign */ + x = duk_double_trunc_towards_zero(x); + + /* NOTE: fmod(x) result sign is same as sign of x, which + * differs from what Javascript wants (see Section 9.6). + */ + + x = DUK_FMOD(x, DUK_DOUBLE_2TO32); /* -> x in ]-2**32, 2**32[ */ + + if (x < 0.0) { + x += DUK_DOUBLE_2TO32; + } + DUK_ASSERT(x >= 0 && x < DUK_DOUBLE_2TO32); /* -> x in [0, 2**32[ */ + + if (is_toint32) { + if (x >= DUK_DOUBLE_2TO31) { + /* x in [2**31, 2**32[ */ + + x -= DUK_DOUBLE_2TO32; /* -> x in [-2**31,2**31[ */ + } + } + + return x; +} + +DUK_INTERNAL duk_int32_t duk_js_toint32(duk_hthread *thr, duk_tval *tv) { + duk_double_t d; + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv)) { + return DUK_TVAL_GET_FASTINT_I32(tv); + } +#endif + + d = duk_js_tonumber(thr, tv); /* invalidates tv */ + d = duk__toint32_touint32_helper(d, 1); + DUK_ASSERT(DUK_FPCLASSIFY(d) == DUK_FP_ZERO || DUK_FPCLASSIFY(d) == DUK_FP_NORMAL); + DUK_ASSERT(d >= -2147483648.0 && d <= 2147483647.0); /* [-0x80000000,0x7fffffff] */ + DUK_ASSERT(duk_double_equals(d, (duk_double_t) ((duk_int32_t) d))); /* whole, won't clip */ + return (duk_int32_t) d; +} + + +DUK_INTERNAL duk_uint32_t duk_js_touint32(duk_hthread *thr, duk_tval *tv) { + duk_double_t d; + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv)) { + return DUK_TVAL_GET_FASTINT_U32(tv); + } +#endif + + d = duk_js_tonumber(thr, tv); /* invalidates tv */ + d = duk__toint32_touint32_helper(d, 0); + DUK_ASSERT(DUK_FPCLASSIFY(d) == DUK_FP_ZERO || DUK_FPCLASSIFY(d) == DUK_FP_NORMAL); + DUK_ASSERT(d >= 0.0 && d <= 4294967295.0); /* [0x00000000, 0xffffffff] */ + DUK_ASSERT(duk_double_equals(d, (duk_double_t) ((duk_uint32_t) d))); /* whole, won't clip */ + return (duk_uint32_t) d; + +} + +DUK_INTERNAL duk_uint16_t duk_js_touint16(duk_hthread *thr, duk_tval *tv) { + /* should be a safe way to compute this */ + return (duk_uint16_t) (duk_js_touint32(thr, tv) & 0x0000ffffU); +} + +/* + * ToString() (E5 Section 9.8) + * ToObject() (E5 Section 9.9) + * CheckObjectCoercible() (E5 Section 9.10) + * IsCallable() (E5 Section 9.11) + * + * ==> implemented in the API. + */ + +/* + * Loose equality, strict equality, and SameValue (E5 Sections 11.9.1, 11.9.4, + * 9.12). These have much in common so they can share some helpers. + * + * Future work notes: + * + * - Current implementation (and spec definition) has recursion; this should + * be fixed if possible. + * + * - String-to-number coercion should be possible without going through the + * value stack (and be more compact) if a shared helper is invoked. + */ + +/* Note that this is the same operation for strict and loose equality: + * - E5 Section 11.9.3, step 1.c (loose) + * - E5 Section 11.9.6, step 4 (strict) + */ + +DUK_LOCAL duk_bool_t duk__js_equals_number(duk_double_t x, duk_double_t y) { +#if defined(DUK_USE_PARANOID_MATH) + /* Straightforward algorithm, makes fewer compiler assumptions. */ + duk_small_int_t cx = (duk_small_int_t) DUK_FPCLASSIFY(x); + duk_small_int_t cy = (duk_small_int_t) DUK_FPCLASSIFY(y); + if (cx == DUK_FP_NAN || cy == DUK_FP_NAN) { + return 0; + } + if (cx == DUK_FP_ZERO && cy == DUK_FP_ZERO) { + return 1; + } + if (x == y) { + return 1; + } + return 0; +#else /* DUK_USE_PARANOID_MATH */ + /* Better equivalent algorithm. If the compiler is compliant, C and + * ECMAScript semantics are identical for this particular comparison. + * In particular, NaNs must never compare equal and zeroes must compare + * equal regardless of sign. Could also use a macro, but this inlines + * already nicely (no difference on gcc, for instance). + */ + if (duk_double_equals(x, y)) { + /* IEEE requires that NaNs compare false */ + DUK_ASSERT(DUK_FPCLASSIFY(x) != DUK_FP_NAN); + DUK_ASSERT(DUK_FPCLASSIFY(y) != DUK_FP_NAN); + return 1; + } else { + /* IEEE requires that zeros compare the same regardless + * of their signed, so if both x and y are zeroes, they + * are caught above. + */ + DUK_ASSERT(!(DUK_FPCLASSIFY(x) == DUK_FP_ZERO && DUK_FPCLASSIFY(y) == DUK_FP_ZERO)); + return 0; + } +#endif /* DUK_USE_PARANOID_MATH */ +} + +DUK_LOCAL duk_bool_t duk__js_samevalue_number(duk_double_t x, duk_double_t y) { +#if defined(DUK_USE_PARANOID_MATH) + duk_small_int_t cx = (duk_small_int_t) DUK_FPCLASSIFY(x); + duk_small_int_t cy = (duk_small_int_t) DUK_FPCLASSIFY(y); + + if (cx == DUK_FP_NAN && cy == DUK_FP_NAN) { + /* SameValue(NaN, NaN) = true, regardless of NaN sign or extra bits */ + return 1; + } + if (cx == DUK_FP_ZERO && cy == DUK_FP_ZERO) { + /* Note: cannot assume that a non-zero return value of signbit() would + * always be the same -- hence cannot (portably) use something like: + * + * signbit(x) == signbit(y) + */ + duk_small_int_t sx = DUK_SIGNBIT(x) ? 1 : 0; + duk_small_int_t sy = DUK_SIGNBIT(y) ? 1 : 0; + return (sx == sy); + } + + /* normal comparison; known: + * - both x and y are not NaNs (but one of them can be) + * - both x and y are not zero (but one of them can be) + * - x and y may be denormal or infinite + */ + + return (x == y); +#else /* DUK_USE_PARANOID_MATH */ + duk_small_int_t cx = (duk_small_int_t) DUK_FPCLASSIFY(x); + duk_small_int_t cy = (duk_small_int_t) DUK_FPCLASSIFY(y); + + if (duk_double_equals(x, y)) { + /* IEEE requires that NaNs compare false */ + DUK_ASSERT(DUK_FPCLASSIFY(x) != DUK_FP_NAN); + DUK_ASSERT(DUK_FPCLASSIFY(y) != DUK_FP_NAN); + + /* Using classification has smaller footprint than direct comparison. */ + if (DUK_UNLIKELY(cx == DUK_FP_ZERO && cy == DUK_FP_ZERO)) { + /* Note: cannot assume that a non-zero return value of signbit() would + * always be the same -- hence cannot (portably) use something like: + * + * signbit(x) == signbit(y) + */ + return duk_double_same_sign(x, y); + } + return 1; + } else { + /* IEEE requires that zeros compare the same regardless + * of their sign, so if both x and y are zeroes, they + * are caught above. + */ + DUK_ASSERT(!(DUK_FPCLASSIFY(x) == DUK_FP_ZERO && DUK_FPCLASSIFY(y) == DUK_FP_ZERO)); + + /* Difference to non-strict/strict comparison is that NaNs compare + * equal and signed zero signs matter. + */ + if (DUK_UNLIKELY(cx == DUK_FP_NAN && cy == DUK_FP_NAN)) { + /* SameValue(NaN, NaN) = true, regardless of NaN sign or extra bits */ + return 1; + } + return 0; + } +#endif /* DUK_USE_PARANOID_MATH */ +} + +DUK_INTERNAL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags) { + duk_uint_t type_mask_x; + duk_uint_t type_mask_y; + + /* If flags != 0 (strict or SameValue), thr can be NULL. For loose + * equals comparison it must be != NULL. + */ + DUK_ASSERT(flags != 0 || thr != NULL); + + /* + * Same type? + * + * Note: since number values have no explicit tag in the 8-byte + * representation, need the awkward if + switch. + */ + +#if defined(DUK_USE_FASTINT) + if (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) { + if (DUK_TVAL_GET_FASTINT(tv_x) == DUK_TVAL_GET_FASTINT(tv_y)) { + return 1; + } else { + return 0; + } + } + else +#endif + if (DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y)) { + duk_double_t d1, d2; + + /* Catches both doubles and cases where only one argument is + * a fastint so can't assume a double. + */ + d1 = DUK_TVAL_GET_NUMBER(tv_x); + d2 = DUK_TVAL_GET_NUMBER(tv_y); + if (DUK_UNLIKELY((flags & DUK_EQUALS_FLAG_SAMEVALUE) != 0)) { + /* SameValue */ + return duk__js_samevalue_number(d1, d2); + } else { + /* equals and strict equals */ + return duk__js_equals_number(d1, d2); + } + } else if (DUK_TVAL_GET_TAG(tv_x) == DUK_TVAL_GET_TAG(tv_y)) { + switch (DUK_TVAL_GET_TAG(tv_x)) { + case DUK_TAG_UNDEFINED: + case DUK_TAG_NULL: { + return 1; + } + case DUK_TAG_BOOLEAN: { + return DUK_TVAL_GET_BOOLEAN(tv_x) == DUK_TVAL_GET_BOOLEAN(tv_y); + } + case DUK_TAG_POINTER: { + return DUK_TVAL_GET_POINTER(tv_x) == DUK_TVAL_GET_POINTER(tv_y); + } + case DUK_TAG_STRING: + case DUK_TAG_OBJECT: { + /* Heap pointer comparison suffices for strings and objects. + * Symbols compare equal if they have the same internal + * representation; again heap pointer comparison suffices. + */ + return DUK_TVAL_GET_HEAPHDR(tv_x) == DUK_TVAL_GET_HEAPHDR(tv_y); + } + case DUK_TAG_BUFFER: { + /* In Duktape 2.x plain buffers mimic Uint8Array objects + * so always compare by heap pointer. In Duktape 1.x + * strict comparison would compare heap pointers and + * non-strict would compare contents. + */ + return DUK_TVAL_GET_HEAPHDR(tv_x) == DUK_TVAL_GET_HEAPHDR(tv_y); + } + case DUK_TAG_LIGHTFUNC: { + /* At least 'magic' has a significant impact on function + * identity. + */ + duk_small_uint_t lf_flags_x; + duk_small_uint_t lf_flags_y; + duk_c_function func_x; + duk_c_function func_y; + + DUK_TVAL_GET_LIGHTFUNC(tv_x, func_x, lf_flags_x); + DUK_TVAL_GET_LIGHTFUNC(tv_y, func_y, lf_flags_y); + return ((func_x == func_y) && (lf_flags_x == lf_flags_y)) ? 1 : 0; + } +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: +#endif + default: { + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_x)); + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_y)); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_x)); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_y)); + DUK_UNREACHABLE(); + DUK_WO_UNREACHABLE(return 0;); + } + } + } + + if ((flags & (DUK_EQUALS_FLAG_STRICT | DUK_EQUALS_FLAG_SAMEVALUE)) != 0) { + return 0; + } + + DUK_ASSERT(flags == 0); /* non-strict equality from here on */ + + /* + * Types are different; various cases for non-strict comparison + * + * Since comparison is symmetric, we use a "swap trick" to reduce + * code size. + */ + + type_mask_x = duk_get_type_mask_tval(tv_x); + type_mask_y = duk_get_type_mask_tval(tv_y); + + /* Undefined/null are considered equal (e.g. "null == undefined" -> true). */ + if ((type_mask_x & (DUK_TYPE_MASK_UNDEFINED | DUK_TYPE_MASK_NULL)) && + (type_mask_y & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED))) { + return 1; + } + + /* Number/string -> coerce string to number (e.g. "'1.5' == 1.5" -> true). */ + if ((type_mask_x & DUK_TYPE_MASK_NUMBER) && (type_mask_y & DUK_TYPE_MASK_STRING)) { + if (!DUK_TVAL_STRING_IS_SYMBOL(tv_y)) { + duk_double_t d1, d2; + d1 = DUK_TVAL_GET_NUMBER(tv_x); + d2 = duk_to_number_tval(thr, tv_y); + return duk__js_equals_number(d1, d2); + } + } + if ((type_mask_x & DUK_TYPE_MASK_STRING) && (type_mask_y & DUK_TYPE_MASK_NUMBER)) { + if (!DUK_TVAL_STRING_IS_SYMBOL(tv_x)) { + duk_double_t d1, d2; + d1 = DUK_TVAL_GET_NUMBER(tv_y); + d2 = duk_to_number_tval(thr, tv_x); + return duk__js_equals_number(d1, d2); + } + } + + /* Boolean/any -> coerce boolean to number and try again. If boolean is + * compared to a pointer, the final comparison after coercion now always + * yields false (as pointer vs. number compares to false), but this is + * not special cased. + * + * ToNumber(bool) is +1.0 or 0.0. Tagged boolean value is always 0 or 1. + */ + if (type_mask_x & DUK_TYPE_MASK_BOOLEAN) { + DUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv_x) == 0 || DUK_TVAL_GET_BOOLEAN(tv_x) == 1); + duk_push_uint(thr, DUK_TVAL_GET_BOOLEAN(tv_x)); + duk_push_tval(thr, tv_y); + goto recursive_call; + } + if (type_mask_y & DUK_TYPE_MASK_BOOLEAN) { + DUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv_y) == 0 || DUK_TVAL_GET_BOOLEAN(tv_y) == 1); + duk_push_tval(thr, tv_x); + duk_push_uint(thr, DUK_TVAL_GET_BOOLEAN(tv_y)); + goto recursive_call; + } + + /* String-number-symbol/object -> coerce object to primitive (apparently without hint), then try again. */ + if ((type_mask_x & (DUK_TYPE_MASK_STRING | DUK_TYPE_MASK_NUMBER)) && + (type_mask_y & DUK_TYPE_MASK_OBJECT)) { + /* No symbol check needed because symbols and strings are accepted. */ + duk_push_tval(thr, tv_x); + duk_push_tval(thr, tv_y); + duk_to_primitive(thr, -1, DUK_HINT_NONE); /* apparently no hint? */ + goto recursive_call; + } + if ((type_mask_x & DUK_TYPE_MASK_OBJECT) && + (type_mask_y & (DUK_TYPE_MASK_STRING | DUK_TYPE_MASK_NUMBER))) { + /* No symbol check needed because symbols and strings are accepted. */ + duk_push_tval(thr, tv_x); + duk_push_tval(thr, tv_y); + duk_to_primitive(thr, -2, DUK_HINT_NONE); /* apparently no hint? */ + goto recursive_call; + } + + /* Nothing worked -> not equal. */ + return 0; + + recursive_call: + /* Shared code path to call the helper again with arguments on stack top. */ + { + duk_bool_t rc; + rc = duk_js_equals_helper(thr, + DUK_GET_TVAL_NEGIDX(thr, -2), + DUK_GET_TVAL_NEGIDX(thr, -1), + 0 /*flags:nonstrict*/); + duk_pop_2_unsafe(thr); + return rc; + } +} + +/* + * Comparisons (x >= y, x > y, x <= y, x < y) + * + * E5 Section 11.8.5: implement 'x < y' and then use negate and eval_left_first + * flags to get the rest. + */ + +/* XXX: this should probably just operate on the stack top, because it + * needs to push stuff on the stack anyway... + */ + +DUK_INTERNAL duk_small_int_t duk_js_data_compare(const duk_uint8_t *buf1, const duk_uint8_t *buf2, duk_size_t len1, duk_size_t len2) { + duk_size_t prefix_len; + duk_small_int_t rc; + + prefix_len = (len1 <= len2 ? len1 : len2); + + /* duk_memcmp() is guaranteed to return zero (equal) for zero length + * inputs. + */ + rc = duk_memcmp_unsafe((const void *) buf1, + (const void *) buf2, + (size_t) prefix_len); + + if (rc < 0) { + return -1; + } else if (rc > 0) { + return 1; + } + + /* prefix matches, lengths matter now */ + if (len1 < len2) { + /* e.g. "x" < "xx" */ + return -1; + } else if (len1 > len2) { + return 1; + } + + return 0; +} + +DUK_INTERNAL duk_small_int_t duk_js_string_compare(duk_hstring *h1, duk_hstring *h2) { + /* + * String comparison (E5 Section 11.8.5, step 4), which + * needs to compare codepoint by codepoint. + * + * However, UTF-8 allows us to use strcmp directly: the shared + * prefix will be encoded identically (UTF-8 has unique encoding) + * and the first differing character can be compared with a simple + * unsigned byte comparison (which strcmp does). + * + * This will not work properly for non-xutf-8 strings, but this + * is not an issue for compliance. + */ + + DUK_ASSERT(h1 != NULL); + DUK_ASSERT(h2 != NULL); + + return duk_js_data_compare((const duk_uint8_t *) DUK_HSTRING_GET_DATA(h1), + (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h2), + (duk_size_t) DUK_HSTRING_GET_BYTELEN(h1), + (duk_size_t) DUK_HSTRING_GET_BYTELEN(h2)); +} + +#if 0 /* unused */ +DUK_INTERNAL duk_small_int_t duk_js_buffer_compare(duk_heap *heap, duk_hbuffer *h1, duk_hbuffer *h2) { + /* Similar to String comparison. */ + + DUK_ASSERT(h1 != NULL); + DUK_ASSERT(h2 != NULL); + DUK_UNREF(heap); + + return duk_js_data_compare((const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(heap, h1), + (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(heap, h2), + (duk_size_t) DUK_HBUFFER_GET_SIZE(h1), + (duk_size_t) DUK_HBUFFER_GET_SIZE(h2)); +} +#endif + +#if defined(DUK_USE_FASTINT) +DUK_LOCAL duk_bool_t duk__compare_fastint(duk_bool_t retval, duk_int64_t v1, duk_int64_t v2) { + DUK_ASSERT(retval == 0 || retval == 1); + if (v1 < v2) { + return retval ^ 1; + } else { + return retval; + } +} +#endif + +#if defined(DUK_USE_PARANOID_MATH) +DUK_LOCAL duk_bool_t duk__compare_number(duk_bool_t retval, duk_double_t d1, duk_double_t d2) { + duk_small_int_t c1, s1, c2, s2; + + DUK_ASSERT(retval == 0 || retval == 1); + c1 = (duk_small_int_t) DUK_FPCLASSIFY(d1); + s1 = (duk_small_int_t) DUK_SIGNBIT(d1); + c2 = (duk_small_int_t) DUK_FPCLASSIFY(d2); + s2 = (duk_small_int_t) DUK_SIGNBIT(d2); + + if (c1 == DUK_FP_NAN || c2 == DUK_FP_NAN) { + return 0; /* Always false, regardless of negation. */ + } + + if (c1 == DUK_FP_ZERO && c2 == DUK_FP_ZERO) { + /* For all combinations: +0 < +0, +0 < -0, -0 < +0, -0 < -0, + * steps e, f, and g. + */ + return retval; /* false */ + } + + if (d1 == d2) { + return retval; /* false */ + } + + if (c1 == DUK_FP_INFINITE && s1 == 0) { + /* x == +Infinity */ + return retval; /* false */ + } + + if (c2 == DUK_FP_INFINITE && s2 == 0) { + /* y == +Infinity */ + return retval ^ 1; /* true */ + } + + if (c2 == DUK_FP_INFINITE && s2 != 0) { + /* y == -Infinity */ + return retval; /* false */ + } + + if (c1 == DUK_FP_INFINITE && s1 != 0) { + /* x == -Infinity */ + return retval ^ 1; /* true */ + } + + if (d1 < d2) { + return retval ^ 1; /* true */ + } + + return retval; /* false */ +} +#else /* DUK_USE_PARANOID_MATH */ +DUK_LOCAL duk_bool_t duk__compare_number(duk_bool_t retval, duk_double_t d1, duk_double_t d2) { + /* This comparison tree relies doesn't match the exact steps in + * E5 Section 11.8.5 but should produce the same results. The + * steps rely on exact IEEE semantics for NaNs, etc. + */ + + DUK_ASSERT(retval == 0 || retval == 1); + if (d1 < d2) { + /* In no case should both (d1 < d2) and (d2 < d1) be true. + * It's possible that neither is true though, and that's + * handled below. + */ + DUK_ASSERT(!(d2 < d1)); + + /* - d1 < d2, both d1/d2 are normals (not Infinity, not NaN) + * - d2 is +Infinity, d1 != +Infinity and NaN + * - d1 is -Infinity, d2 != -Infinity and NaN + */ + return retval ^ 1; + } else { + if (d2 < d1) { + /* - !(d1 < d2), both d1/d2 are normals (not Infinity, not NaN) + * - d1 is +Infinity, d2 != +Infinity and NaN + * - d2 is -Infinity, d1 != -Infinity and NaN + */ + return retval; + } else { + /* - d1 and/or d2 is NaN + * - d1 and d2 are both +/- 0 + * - d1 == d2 (including infinities) + */ + if (duk_double_is_nan(d1) || duk_double_is_nan(d2)) { + /* Note: undefined from Section 11.8.5 always + * results in false return (see e.g. Section + * 11.8.3) - hence special treatment here. + */ + return 0; /* zero regardless of negation */ + } else { + return retval; + } + } + } +} +#endif /* DUK_USE_PARANOID_MATH */ + +DUK_INTERNAL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags) { + duk_double_t d1, d2; + duk_small_int_t rc; + duk_bool_t retval; + + DUK_ASSERT(DUK_COMPARE_FLAG_NEGATE == 1); /* Rely on this flag being lowest. */ + retval = flags & DUK_COMPARE_FLAG_NEGATE; + DUK_ASSERT(retval == 0 || retval == 1); + + /* Fast path for fastints */ +#if defined(DUK_USE_FASTINT) + if (DUK_LIKELY(DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y))) { + return duk__compare_fastint(retval, + DUK_TVAL_GET_FASTINT(tv_x), + DUK_TVAL_GET_FASTINT(tv_y)); + } +#endif /* DUK_USE_FASTINT */ + + /* Fast path for numbers (one of which may be a fastint) */ +#if !defined(DUK_USE_PREFER_SIZE) + if (DUK_LIKELY(DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y))) { + return duk__compare_number(retval, + DUK_TVAL_GET_NUMBER(tv_x), + DUK_TVAL_GET_NUMBER(tv_y)); + } +#endif + + /* Slow path */ + + duk_push_tval(thr, tv_x); + duk_push_tval(thr, tv_y); + + if (flags & DUK_COMPARE_FLAG_EVAL_LEFT_FIRST) { + duk_to_primitive(thr, -2, DUK_HINT_NUMBER); + duk_to_primitive(thr, -1, DUK_HINT_NUMBER); + } else { + duk_to_primitive(thr, -1, DUK_HINT_NUMBER); + duk_to_primitive(thr, -2, DUK_HINT_NUMBER); + } + + /* Note: reuse variables */ + tv_x = DUK_GET_TVAL_NEGIDX(thr, -2); + tv_y = DUK_GET_TVAL_NEGIDX(thr, -1); + + if (DUK_TVAL_IS_STRING(tv_x) && DUK_TVAL_IS_STRING(tv_y)) { + duk_hstring *h1 = DUK_TVAL_GET_STRING(tv_x); + duk_hstring *h2 = DUK_TVAL_GET_STRING(tv_y); + DUK_ASSERT(h1 != NULL); + DUK_ASSERT(h2 != NULL); + + if (DUK_LIKELY(!DUK_HSTRING_HAS_SYMBOL(h1) && !DUK_HSTRING_HAS_SYMBOL(h2))) { + rc = duk_js_string_compare(h1, h2); + duk_pop_2_unsafe(thr); + if (rc < 0) { + return retval ^ 1; + } else { + return retval; + } + } + + /* One or both are Symbols: fall through to handle in the + * generic path. Concretely, ToNumber() will fail. + */ + } + + /* Ordering should not matter (E5 Section 11.8.5, step 3.a). */ +#if 0 + if (flags & DUK_COMPARE_FLAG_EVAL_LEFT_FIRST) { + d1 = duk_to_number_m2(thr); + d2 = duk_to_number_m1(thr); + } else { + d2 = duk_to_number_m1(thr); + d1 = duk_to_number_m2(thr); + } +#endif + d1 = duk_to_number_m2(thr); + d2 = duk_to_number_m1(thr); + + /* We want to duk_pop_2_unsafe(thr); because the values are numbers + * no decref check is needed. + */ +#if defined(DUK_USE_PREFER_SIZE) + duk_pop_2_nodecref_unsafe(thr); +#else + DUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk_get_tval(thr, -2))); + DUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk_get_tval(thr, -1))); + DUK_ASSERT(duk_get_top(thr) >= 2); + thr->valstack_top -= 2; + tv_x = thr->valstack_top; + tv_y = tv_x + 1; + DUK_TVAL_SET_UNDEFINED(tv_x); /* Value stack policy */ + DUK_TVAL_SET_UNDEFINED(tv_y); +#endif + + return duk__compare_number(retval, d1, d2); +} + +/* + * instanceof + */ + +/* + * ES2015 Section 7.3.19 describes the OrdinaryHasInstance() algorithm + * which covers both bound and non-bound functions; in effect the algorithm + * includes E5 Sections 11.8.6, 15.3.5.3, and 15.3.4.5.3. + * + * ES2015 Section 12.9.4 describes the instanceof operator which first + * checks @@hasInstance well-known symbol and falls back to + * OrdinaryHasInstance(). + * + * Limited Proxy support: don't support 'getPrototypeOf' trap but + * continue lookup in Proxy target if the value is a Proxy. + */ + +DUK_LOCAL duk_bool_t duk__js_instanceof_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_bool_t skip_sym_check) { + duk_hobject *func; + duk_hobject *val; + duk_hobject *proto; + duk_tval *tv; + duk_bool_t skip_first; + duk_uint_t sanity; + + /* + * Get the values onto the stack first. It would be possible to cover + * some normal cases without resorting to the value stack. + * + * The right hand side could be a light function (as they generally + * behave like objects). Light functions never have a 'prototype' + * property so E5.1 Section 15.3.5.3 step 3 always throws a TypeError. + * Using duk_require_hobject() is thus correct (except for error msg). + */ + + duk_push_tval(thr, tv_x); + duk_push_tval(thr, tv_y); + func = duk_require_hobject(thr, -1); + DUK_ASSERT(func != NULL); + +#if defined(DUK_USE_SYMBOL_BUILTIN) + /* + * @@hasInstance check, ES2015 Section 12.9.4, Steps 2-4. + */ + if (!skip_sym_check) { + if (duk_get_method_stridx(thr, -1, DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE)) { + /* [ ... lhs rhs func ] */ + duk_insert(thr, -3); /* -> [ ... func lhs rhs ] */ + duk_swap_top(thr, -2); /* -> [ ... func rhs(this) lhs ] */ + duk_call_method(thr, 1); + return duk_to_boolean_top_pop(thr); + } + } +#else + DUK_UNREF(skip_sym_check); +#endif + + /* + * For bound objects, [[HasInstance]] just calls the target function + * [[HasInstance]]. If that is again a bound object, repeat until + * we find a non-bound Function object. + * + * The bound function chain is now "collapsed" so there can be only + * one bound function in the chain. + */ + + if (!DUK_HOBJECT_IS_CALLABLE(func)) { + /* + * Note: of native ECMAScript objects, only Function instances + * have a [[HasInstance]] internal property. Custom objects might + * also have it, but not in current implementation. + * + * XXX: add a separate flag, DUK_HOBJECT_FLAG_ALLOW_INSTANCEOF? + */ + goto error_invalid_rval; + } + + if (DUK_HOBJECT_HAS_BOUNDFUNC(func)) { + duk_push_tval(thr, &((duk_hboundfunc *) (void *) func)->target); + duk_replace(thr, -2); + func = duk_require_hobject(thr, -1); /* lightfunc throws */ + + /* Rely on Function.prototype.bind() never creating bound + * functions whose target is not proper. + */ + DUK_ASSERT(func != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(func)); + } + + /* + * 'func' is now a non-bound object which supports [[HasInstance]] + * (which here just means DUK_HOBJECT_FLAG_CALLABLE). Move on + * to execute E5 Section 15.3.5.3. + */ + + DUK_ASSERT(func != NULL); + DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func)); + DUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(func)); + + /* [ ... lval rval(func) ] */ + + /* For lightfuncs, buffers, and pointers start the comparison directly + * from the virtual prototype object. + */ + skip_first = 0; + tv = DUK_GET_TVAL_NEGIDX(thr, -2); + switch (DUK_TVAL_GET_TAG(tv)) { + case DUK_TAG_LIGHTFUNC: + val = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]; + DUK_ASSERT(val != NULL); + break; + case DUK_TAG_BUFFER: + val = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE]; + DUK_ASSERT(val != NULL); + break; + case DUK_TAG_POINTER: + val = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE]; + DUK_ASSERT(val != NULL); + break; + case DUK_TAG_OBJECT: + skip_first = 1; /* Ignore object itself on first round. */ + val = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(val != NULL); + break; + default: + goto pop2_and_false; + } + DUK_ASSERT(val != NULL); /* Loop doesn't actually rely on this. */ + + /* Look up .prototype of rval. Leave it on the value stack in case it + * has been virtualized (e.g. getter, Proxy trap). + */ + duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_PROTOTYPE); /* -> [ ... lval rval rval.prototype ] */ +#if defined(DUK_USE_VERBOSE_ERRORS) + proto = duk_get_hobject(thr, -1); + if (proto == NULL) { + goto error_invalid_rval_noproto; + } +#else + proto = duk_require_hobject(thr, -1); +#endif + + sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY; + do { + /* + * Note: prototype chain is followed BEFORE first comparison. This + * means that the instanceof lval is never itself compared to the + * rval.prototype property. This is apparently intentional, see E5 + * Section 15.3.5.3, step 4.a. + * + * Also note: + * + * js> (function() {}) instanceof Function + * true + * js> Function instanceof Function + * true + * + * For the latter, h_proto will be Function.prototype, which is the + * built-in Function prototype. Because Function.[[Prototype]] is + * also the built-in Function prototype, the result is true. + */ + + if (!val) { + goto pop3_and_false; + } + + DUK_ASSERT(val != NULL); +#if defined(DUK_USE_ES6_PROXY) + val = duk_hobject_resolve_proxy_target(val); +#endif + + if (skip_first) { + skip_first = 0; + } else if (val == proto) { + goto pop3_and_true; + } + + DUK_ASSERT(val != NULL); + val = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, val); + } while (--sanity > 0); + + DUK_ASSERT(sanity == 0); + DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT); + DUK_WO_NORETURN(return 0;); + + pop2_and_false: + duk_pop_2_unsafe(thr); + return 0; + + pop3_and_false: + duk_pop_3_unsafe(thr); + return 0; + + pop3_and_true: + duk_pop_3_unsafe(thr); + return 1; + + error_invalid_rval: + DUK_ERROR_TYPE(thr, DUK_STR_INVALID_INSTANCEOF_RVAL); + DUK_WO_NORETURN(return 0;); + +#if defined(DUK_USE_VERBOSE_ERRORS) + error_invalid_rval_noproto: + DUK_ERROR_TYPE(thr, DUK_STR_INVALID_INSTANCEOF_RVAL_NOPROTO); + DUK_WO_NORETURN(return 0;); +#endif +} + +#if defined(DUK_USE_SYMBOL_BUILTIN) +DUK_INTERNAL duk_bool_t duk_js_instanceof_ordinary(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) { + return duk__js_instanceof_helper(thr, tv_x, tv_y, 1 /*skip_sym_check*/); +} +#endif + +DUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) { + return duk__js_instanceof_helper(thr, tv_x, tv_y, 0 /*skip_sym_check*/); +} + +/* + * in + */ + +/* + * E5 Sections 11.8.7, 8.12.6. + * + * Basically just a property existence check using [[HasProperty]]. + */ + +DUK_INTERNAL duk_bool_t duk_js_in(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) { + duk_bool_t retval; + + /* + * Get the values onto the stack first. It would be possible to cover + * some normal cases without resorting to the value stack (e.g. if + * lval is already a string). + */ + + /* XXX: The ES5/5.1/6 specifications require that the key in 'key in obj' + * must be string coerced before the internal HasProperty() algorithm is + * invoked. A fast path skipping coercion could be safely implemented for + * numbers (as number-to-string coercion has no side effects). For ES2015 + * proxy behavior, the trap 'key' argument must be in a string coerced + * form (which is a shame). + */ + + /* TypeError if rval is not an object or object like (e.g. lightfunc + * or plain buffer). + */ + duk_push_tval(thr, tv_x); + duk_push_tval(thr, tv_y); + duk_require_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT | DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER); + + (void) duk_to_property_key_hstring(thr, -2); + + retval = duk_hobject_hasprop(thr, + DUK_GET_TVAL_NEGIDX(thr, -1), + DUK_GET_TVAL_NEGIDX(thr, -2)); + + duk_pop_2_unsafe(thr); + return retval; +} + +/* + * typeof + * + * E5 Section 11.4.3. + * + * Very straightforward. The only question is what to return for our + * non-standard tag / object types. + * + * There is an unfortunate string constant define naming problem with + * typeof return values for e.g. "Object" and "object"; careful with + * the built-in string defines. The LC_XXX defines are used for the + * lowercase variants now. + */ + +DUK_INTERNAL duk_small_uint_t duk_js_typeof_stridx(duk_tval *tv_x) { + duk_small_uint_t stridx = 0; + + switch (DUK_TVAL_GET_TAG(tv_x)) { + case DUK_TAG_UNDEFINED: { + stridx = DUK_STRIDX_LC_UNDEFINED; + break; + } + case DUK_TAG_NULL: { + /* Note: not a typo, "object" is returned for a null value. */ + stridx = DUK_STRIDX_LC_OBJECT; + break; + } + case DUK_TAG_BOOLEAN: { + stridx = DUK_STRIDX_LC_BOOLEAN; + break; + } + case DUK_TAG_POINTER: { + /* Implementation specific. */ + stridx = DUK_STRIDX_LC_POINTER; + break; + } + case DUK_TAG_STRING: { + duk_hstring *str; + + /* All internal keys are identified as Symbols. */ + str = DUK_TVAL_GET_STRING(tv_x); + DUK_ASSERT(str != NULL); + if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(str))) { + stridx = DUK_STRIDX_LC_SYMBOL; + } else { + stridx = DUK_STRIDX_LC_STRING; + } + break; + } + case DUK_TAG_OBJECT: { + duk_hobject *obj = DUK_TVAL_GET_OBJECT(tv_x); + DUK_ASSERT(obj != NULL); + if (DUK_HOBJECT_IS_CALLABLE(obj)) { + stridx = DUK_STRIDX_LC_FUNCTION; + } else { + stridx = DUK_STRIDX_LC_OBJECT; + } + break; + } + case DUK_TAG_BUFFER: { + /* Implementation specific. In Duktape 1.x this would be + * 'buffer', in Duktape 2.x changed to 'object' because plain + * buffers now mimic Uint8Array objects. + */ + stridx = DUK_STRIDX_LC_OBJECT; + break; + } + case DUK_TAG_LIGHTFUNC: { + stridx = DUK_STRIDX_LC_FUNCTION; + break; + } +#if defined(DUK_USE_FASTINT) + case DUK_TAG_FASTINT: +#endif + default: { + /* number */ + DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_x)); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_x)); + stridx = DUK_STRIDX_LC_NUMBER; + break; + } + } + + DUK_ASSERT_STRIDX_VALID(stridx); + return stridx; +} + +/* + * IsArray() + */ + +DUK_INTERNAL duk_bool_t duk_js_isarray_hobject(duk_hobject *h) { + DUK_ASSERT(h != NULL); + h = duk_hobject_resolve_proxy_target(h); + return (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY ? 1 : 0); +} + +DUK_INTERNAL duk_bool_t duk_js_isarray(duk_tval *tv) { + DUK_ASSERT(tv != NULL); + if (DUK_TVAL_IS_OBJECT(tv)) { + return duk_js_isarray_hobject(DUK_TVAL_GET_OBJECT(tv)); + } + return 0; +} + +/* + * Array index and length + * + * Array index: E5 Section 15.4 + * Array length: E5 Section 15.4.5.1 steps 3.c - 3.d (array length write) + */ + +/* Compure array index from string context, or return a "not array index" + * indicator. + */ +DUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_string(const duk_uint8_t *str, duk_uint32_t blen) { + duk_uarridx_t res; + + /* Only strings with byte length 1-10 can be 32-bit array indices. + * Leading zeroes (except '0' alone), plus/minus signs are not allowed. + * We could do a lot of prechecks here, but since most strings won't + * start with any digits, it's simpler to just parse the number and + * fail quickly. + */ + + res = 0; + if (blen == 0) { + goto parse_fail; + } + do { + duk_uarridx_t dig; + dig = (duk_uarridx_t) (*str++) - DUK_ASC_0; + + if (dig <= 9U) { + /* Careful overflow handling. When multiplying by 10: + * - 0x19999998 x 10 = 0xfffffff0: no overflow, and adding + * 0...9 is safe. + * - 0x19999999 x 10 = 0xfffffffa: no overflow, adding + * 0...5 is safe, 6...9 overflows. + * - 0x1999999a x 10 = 0x100000004: always overflow. + */ + if (DUK_UNLIKELY(res >= 0x19999999UL)) { + if (res >= 0x1999999aUL) { + /* Always overflow. */ + goto parse_fail; + } + DUK_ASSERT(res == 0x19999999UL); + if (dig >= 6U) { + goto parse_fail; + } + res = 0xfffffffaUL + dig; + DUK_ASSERT(res >= 0xfffffffaUL); + DUK_ASSERT_DISABLE(res <= 0xffffffffUL); /* range */ + } else { + res = res * 10U + dig; + if (DUK_UNLIKELY(res == 0)) { + /* If 'res' is 0, previous 'res' must + * have been 0 and we scanned in a zero. + * This is only allowed if blen == 1, + * i.e. the exact string '0'. + */ + if (blen == (duk_uint32_t) 1) { + return 0; + } + goto parse_fail; + } + } + } else { + /* Because 'dig' is unsigned, catches both values + * above '9' and below '0'. + */ + goto parse_fail; + } + } while (--blen > 0); + + return res; + + parse_fail: + return DUK_HSTRING_NO_ARRAY_INDEX; +} + +#if !defined(DUK_USE_HSTRING_ARRIDX) +/* Get array index for a string which is known to be an array index. This helper + * is needed when duk_hstring doesn't concretely store the array index, but strings + * are flagged as array indices at intern time. + */ +DUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_hstring_fast_known(duk_hstring *h) { + const duk_uint8_t *p; + duk_uarridx_t res; + duk_uint8_t t; + + DUK_ASSERT(h != NULL); + DUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(h)); + + p = DUK_HSTRING_GET_DATA(h); + res = 0; + for (;;) { + t = *p++; + if (DUK_UNLIKELY(t == 0)) { + /* Scanning to NUL is always safe for interned strings. */ + break; + } + DUK_ASSERT(t >= (duk_uint8_t) DUK_ASC_0 && t <= (duk_uint8_t) DUK_ASC_9); + res = res * 10U + (duk_uarridx_t) t - (duk_uarridx_t) DUK_ASC_0; + } + return res; +} + +DUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_hstring_fast(duk_hstring *h) { + DUK_ASSERT(h != NULL); + if (!DUK_HSTRING_HAS_ARRIDX(h)) { + return DUK_HSTRING_NO_ARRAY_INDEX; + } + return duk_js_to_arrayindex_hstring_fast_known(h); +} +#endif /* DUK_USE_HSTRING_ARRIDX */ diff --git a/third_party/duktape/duk_js_var.c b/third_party/duktape/duk_js_var.c new file mode 100644 index 00000000..4c3d0d63 --- /dev/null +++ b/third_party/duktape/duk_js_var.c @@ -0,0 +1,1793 @@ +/* + * Identifier access and function closure handling. + * + * Provides the primitives for slow path identifier accesses: GETVAR, + * PUTVAR, DELVAR, etc. The fast path, direct register accesses, should + * be used for most identifier accesses. Consequently, these slow path + * primitives should be optimized for maximum compactness. + * + * ECMAScript environment records (declarative and object) are represented + * as internal objects with control keys. Environment records have a + * parent record ("outer environment reference") which is represented by + * the implicit prototype for technical reasons (in other words, it is a + * convenient field). The prototype chain is not followed in the ordinary + * sense for variable lookups. + * + * See identifier-handling.rst for more details on the identifier algorithms + * and the internal representation. See function-objects.rst for details on + * what function templates and instances are expected to look like. + * + * Care must be taken to avoid duk_tval pointer invalidation caused by + * e.g. value stack or object resizing. + * + * TODO: properties for function instances could be initialized much more + * efficiently by creating a property allocation for a certain size and + * filling in keys and values directly (and INCREFing both with "bulk incref" + * primitives. + * + * XXX: duk_hobject_getprop() and duk_hobject_putprop() calls are a bit + * awkward (especially because they follow the prototype chain); rework + * if "raw" own property helpers are added. + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Local result type for duk__get_identifier_reference() lookup. + */ + +typedef struct { + duk_hobject *env; + duk_hobject *holder; /* for object-bound identifiers */ + duk_tval *value; /* for register-bound and declarative env identifiers */ + duk_uint_t attrs; /* property attributes for identifier (relevant if value != NULL) */ + duk_bool_t has_this; /* for object-bound identifiers: provide 'this' binding */ +} duk__id_lookup_result; + +/* + * Create a new function object based on a "template function" which contains + * compiled bytecode, constants, etc, but lacks a lexical environment. + * + * ECMAScript requires that each created closure is a separate object, with + * its own set of editable properties. However, structured property values + * (such as the formal arguments list and the variable map) are shared. + * Also the bytecode, constants, and inner functions are shared. + * + * See E5 Section 13.2 for detailed requirements on the function objects; + * there are no similar requirements for function "templates" which are an + * implementation dependent internal feature. Also see function-objects.rst + * for a discussion on the function instance properties provided by this + * implementation. + * + * Notes: + * + * * Order of internal properties should match frequency of use, since the + * properties will be linearly scanned on lookup (functions usually don't + * have enough properties to warrant a hash part). + * + * * The created closure is independent of its template; they do share the + * same 'data' buffer object, but the template object itself can be freed + * even if the closure object remains reachable. + */ + +DUK_LOCAL void duk__inc_data_inner_refcounts(duk_hthread *thr, duk_hcompfunc *f) { + duk_tval *tv, *tv_end; + duk_hobject **funcs, **funcs_end; + + DUK_UNREF(thr); + + /* If function creation fails due to out-of-memory, the data buffer + * pointer may be NULL in some cases. That's actually possible for + * GC code, but shouldn't be possible here because the incomplete + * function will be unwound from the value stack and never instantiated. + */ + DUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, f) != NULL); + + tv = DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, f); + tv_end = DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, f); + while (tv < tv_end) { + DUK_TVAL_INCREF(thr, tv); + tv++; + } + + funcs = DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, f); + funcs_end = DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, f); + while (funcs < funcs_end) { + DUK_HEAPHDR_INCREF(thr, (duk_heaphdr *) *funcs); + funcs++; + } +} + +/* Push a new closure on the stack. + * + * Note: if fun_temp has NEWENV, i.e. a new lexical and variable declaration + * is created when the function is called, only outer_lex_env matters + * (outer_var_env is ignored and may or may not be same as outer_lex_env). + */ + +DUK_LOCAL const duk_uint16_t duk__closure_copy_proplist[] = { + /* order: most frequent to least frequent */ + DUK_STRIDX_INT_VARMAP, + DUK_STRIDX_INT_FORMALS, +#if defined(DUK_USE_PC2LINE) + DUK_STRIDX_INT_PC2LINE, +#endif +#if defined(DUK_USE_FUNC_FILENAME_PROPERTY) + DUK_STRIDX_FILE_NAME, +#endif +#if defined(DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY) + DUK_STRIDX_INT_SOURCE +#endif +}; + +DUK_INTERNAL +void duk_js_push_closure(duk_hthread *thr, + duk_hcompfunc *fun_temp, + duk_hobject *outer_var_env, + duk_hobject *outer_lex_env, + duk_bool_t add_auto_proto) { + duk_hcompfunc *fun_clos; + duk_harray *formals; + duk_small_uint_t i; + duk_uint_t len_value; + + DUK_ASSERT(fun_temp != NULL); + DUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_temp) != NULL); + DUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_temp) != NULL); + DUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_temp) != NULL); + DUK_ASSERT(outer_var_env != NULL); + DUK_ASSERT(outer_lex_env != NULL); + DUK_UNREF(len_value); + + DUK_STATS_INC(thr->heap, stats_envrec_pushclosure); + + fun_clos = duk_push_hcompfunc(thr); + DUK_ASSERT(fun_clos != NULL); + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) fun_clos) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]); + + duk_push_hobject(thr, &fun_temp->obj); /* -> [ ... closure template ] */ + + DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun_clos)); + DUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_clos) == NULL); + DUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_clos) == NULL); + DUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_clos) == NULL); + + DUK_HCOMPFUNC_SET_DATA(thr->heap, fun_clos, DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_temp)); + DUK_HCOMPFUNC_SET_FUNCS(thr->heap, fun_clos, DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_temp)); + DUK_HCOMPFUNC_SET_BYTECODE(thr->heap, fun_clos, DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_temp)); + + /* Note: all references inside 'data' need to get their refcounts + * upped too. This is the case because refcounts are decreased + * through every function referencing 'data' independently. + */ + + DUK_HBUFFER_INCREF(thr, DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_clos)); + duk__inc_data_inner_refcounts(thr, fun_temp); + + fun_clos->nregs = fun_temp->nregs; + fun_clos->nargs = fun_temp->nargs; +#if defined(DUK_USE_DEBUGGER_SUPPORT) + fun_clos->start_line = fun_temp->start_line; + fun_clos->end_line = fun_temp->end_line; +#endif + + DUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_clos) != NULL); + DUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_clos) != NULL); + DUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_clos) != NULL); + + /* XXX: Could also copy from template, but there's no way to have any + * other value here now (used code has no access to the template). + * Prototype is set by duk_push_hcompfunc(). + */ + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, &fun_clos->obj) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]); +#if 0 + DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, &fun_clos->obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]); +#endif + + /* Copy duk_hobject flags as is from the template using a mask. + * Leave out duk_heaphdr owned flags just in case (e.g. if there's + * some GC flag or similar). Some flags can then be adjusted + * separately if necessary. + */ + + /* DUK_HEAPHDR_SET_FLAGS() masks changes to non-duk_heaphdr flags only. */ + DUK_HEAPHDR_SET_FLAGS((duk_heaphdr *) fun_clos, DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) fun_temp)); + DUK_DD(DUK_DDPRINT("fun_temp heaphdr flags: 0x%08lx, fun_clos heaphdr flags: 0x%08lx", + (unsigned long) DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) fun_temp), + (unsigned long) DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) fun_clos))); + + DUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(&fun_clos->obj)); + DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&fun_clos->obj)); + DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(&fun_clos->obj)); + DUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(&fun_clos->obj)); + DUK_ASSERT(!DUK_HOBJECT_IS_THREAD(&fun_clos->obj)); + /* DUK_HOBJECT_FLAG_ARRAY_PART: don't care */ + /* DUK_HOBJECT_FLAG_NEWENV: handled below */ + DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(&fun_clos->obj)); + DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(&fun_clos->obj)); + DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(&fun_clos->obj)); + + if (!DUK_HOBJECT_HAS_CONSTRUCTABLE(&fun_clos->obj)) { + /* If the template is not constructable don't add an automatic + * .prototype property. This is the case for e.g. ES2015 object + * literal getters/setters and method definitions. + */ + add_auto_proto = 0; + } + + /* + * Setup environment record properties based on the template and + * its flags. + * + * If DUK_HOBJECT_HAS_NEWENV(fun_temp) is true, the environment + * records represent identifiers "outside" the function; the + * "inner" environment records are created on demand. Otherwise, + * the environment records are those that will be directly used + * (e.g. for declarations). + * + * _Lexenv is always set; _Varenv defaults to _Lexenv if missing, + * so _Varenv is only set if _Lexenv != _Varenv. + * + * This is relatively complex, see doc/identifier-handling.rst. + */ + + if (DUK_HOBJECT_HAS_NEWENV(&fun_clos->obj)) { +#if defined(DUK_USE_FUNC_NAME_PROPERTY) + if (DUK_HOBJECT_HAS_NAMEBINDING(&fun_clos->obj)) { + duk_hobject *proto; + duk_hdecenv *new_env; + + /* + * Named function expression, name needs to be bound + * in an intermediate environment record. The "outer" + * lexical/variable environment will thus be: + * + * a) { funcname: , __prototype: outer_lex_env } + * b) { funcname: , __prototype: } (if outer_lex_env missing) + */ + + if (outer_lex_env) { + proto = outer_lex_env; + } else { + proto = thr->builtins[DUK_BIDX_GLOBAL_ENV]; + } + + /* -> [ ... closure template env ] */ + new_env = duk_hdecenv_alloc(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV)); + DUK_ASSERT(new_env != NULL); + duk_push_hobject(thr, (duk_hobject *) new_env); + + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL); + DUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, proto); + DUK_HOBJECT_INCREF_ALLOWNULL(thr, proto); + + DUK_ASSERT(new_env->thread == NULL); /* Closed. */ + DUK_ASSERT(new_env->varmap == NULL); + + /* It's important that duk_xdef_prop() is a 'raw define' so that any + * properties in an ancestor are never an issue (they should never be + * e.g. non-writable, but just in case). + * + * Because template objects are not visible to user code, the case + * where .name is missing shouldn't happen in practice. It it does, + * the name 'undefined' gets bound and maps to the closure (which is + * a bit odd, but safe). + */ + (void) duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME); + /* -> [ ... closure template env funcname ] */ + duk_dup_m4(thr); /* -> [ ... closure template env funcname closure ] */ + duk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_NONE); /* -> [ ... closure template env ] */ + /* env[funcname] = closure */ + + /* [ ... closure template env ] */ + + DUK_HCOMPFUNC_SET_LEXENV(thr->heap, fun_clos, (duk_hobject *) new_env); + DUK_HCOMPFUNC_SET_VARENV(thr->heap, fun_clos, (duk_hobject *) new_env); + DUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env); + DUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env); + duk_pop_unsafe(thr); + + /* [ ... closure template ] */ + } + else +#endif /* DUK_USE_FUNC_NAME_PROPERTY */ + { + /* + * Other cases (function declaration, anonymous function expression, + * strict direct eval code). The "outer" environment will be whatever + * the caller gave us. + */ + + DUK_HCOMPFUNC_SET_LEXENV(thr->heap, fun_clos, outer_lex_env); + DUK_HCOMPFUNC_SET_VARENV(thr->heap, fun_clos, outer_lex_env); + DUK_HOBJECT_INCREF(thr, outer_lex_env); + DUK_HOBJECT_INCREF(thr, outer_lex_env); + + /* [ ... closure template ] */ + } + } else { + /* + * Function gets no new environment when called. This is the + * case for global code, indirect eval code, and non-strict + * direct eval code. There is no direct correspondence to the + * E5 specification, as global/eval code is not exposed as a + * function. + */ + + DUK_ASSERT(!DUK_HOBJECT_HAS_NAMEBINDING(&fun_temp->obj)); + + DUK_HCOMPFUNC_SET_LEXENV(thr->heap, fun_clos, outer_lex_env); + DUK_HCOMPFUNC_SET_VARENV(thr->heap, fun_clos, outer_var_env); + DUK_HOBJECT_INCREF(thr, outer_lex_env); /* NULLs not allowed; asserted on entry */ + DUK_HOBJECT_INCREF(thr, outer_var_env); + } + DUK_DDD(DUK_DDDPRINT("closure varenv -> %!ipO, lexenv -> %!ipO", + (duk_heaphdr *) fun_clos->var_env, + (duk_heaphdr *) fun_clos->lex_env)); + + /* Call handling assumes this for all callable closures. */ + DUK_ASSERT(DUK_HCOMPFUNC_GET_LEXENV(thr->heap, fun_clos) != NULL); + DUK_ASSERT(DUK_HCOMPFUNC_GET_VARENV(thr->heap, fun_clos) != NULL); + + /* + * Copy some internal properties directly + * + * The properties will be non-writable and non-enumerable, but + * configurable. + * + * Function templates are bare objects, so inheritance of internal + * Symbols is not an issue here even when using ordinary property + * reads. The function instance created is not bare, so internal + * Symbols must be defined without inheritance checks. + */ + + /* [ ... closure template ] */ + + DUK_DDD(DUK_DDDPRINT("copying properties: closure=%!iT, template=%!iT", + (duk_tval *) duk_get_tval(thr, -2), + (duk_tval *) duk_get_tval(thr, -1))); + + for (i = 0; i < (duk_small_uint_t) (sizeof(duk__closure_copy_proplist) / sizeof(duk_uint16_t)); i++) { + duk_small_int_t stridx = (duk_small_int_t) duk__closure_copy_proplist[i]; + if (duk_xget_owndataprop_stridx_short(thr, -1, stridx)) { + /* [ ... closure template val ] */ + DUK_DDD(DUK_DDDPRINT("copying property, stridx=%ld -> found", (long) stridx)); + duk_xdef_prop_stridx_short(thr, -3, stridx, DUK_PROPDESC_FLAGS_C); + } else { + DUK_DDD(DUK_DDDPRINT("copying property, stridx=%ld -> not found", (long) stridx)); + duk_pop_unsafe(thr); + } + } + + /* + * "length" maps to number of formals (E5 Section 13.2) for function + * declarations/expressions (non-bound functions). Note that 'nargs' + * is NOT necessarily equal to the number of arguments. Use length + * of _Formals; if missing, assume nargs matches .length. + */ + + /* [ ... closure template ] */ + + formals = duk_hobject_get_formals(thr, (duk_hobject *) fun_temp); + if (formals) { + len_value = (duk_uint_t) formals->length; + DUK_DD(DUK_DDPRINT("closure length from _Formals -> %ld", (long) len_value)); + } else { + len_value = fun_temp->nargs; + DUK_DD(DUK_DDPRINT("closure length defaulted from nargs -> %ld", (long) len_value)); + } + + duk_push_uint(thr, len_value); /* [ ... closure template len_value ] */ + duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C); + + /* + * "prototype" is, by default, a fresh object with the "constructor" + * property. + * + * Note that this creates a circular reference for every function + * instance (closure) which prevents refcount-based collection of + * function instances. + * + * XXX: Try to avoid creating the default prototype object, because + * many functions are not used as constructors and the default + * prototype is unnecessary. Perhaps it could be created on-demand + * when it is first accessed? + */ + + /* [ ... closure template ] */ + + if (add_auto_proto) { + duk_push_object(thr); /* -> [ ... closure template newobj ] */ + duk_dup_m3(thr); /* -> [ ... closure template newobj closure ] */ + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC); /* -> [ ... closure template newobj ] */ + duk_compact(thr, -1); /* compact the prototype */ + duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_W); /* -> [ ... closure template ] */ + } + + /* + * "arguments" and "caller" must be mapped to throwers for strict + * mode and bound functions (E5 Section 15.3.5). + * + * XXX: This is expensive to have for every strict function instance. + * Try to implement as virtual properties or on-demand created properties. + */ + + /* [ ... closure template ] */ + + if (DUK_HOBJECT_HAS_STRICT(&fun_clos->obj)) { + duk_xdef_prop_stridx_thrower(thr, -2, DUK_STRIDX_CALLER); + duk_xdef_prop_stridx_thrower(thr, -2, DUK_STRIDX_LC_ARGUMENTS); + } else { +#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY) + DUK_DDD(DUK_DDDPRINT("function is non-strict and non-standard 'caller' property in use, add initial 'null' value")); + duk_push_null(thr); + duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_CALLER, DUK_PROPDESC_FLAGS_NONE); +#else + DUK_DDD(DUK_DDDPRINT("function is non-strict and non-standard 'caller' property not used")); +#endif + } + + /* + * "name" used to be non-standard but is now defined by ES2015. + * In ES2015/ES2016 the .name property is configurable. + */ + + /* [ ... closure template ] */ + +#if defined(DUK_USE_FUNC_NAME_PROPERTY) + /* XXX: Look for own property only; doesn't matter much because + * templates are bare objects. + */ + if (duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME)) { + /* [ ... closure template name ] */ + DUK_ASSERT(duk_is_string(thr, -1)); + DUK_DD(DUK_DDPRINT("setting function instance name to %!T", duk_get_tval(thr, -1))); + duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C); /* -> [ ... closure template ] */ + } else { + /* Anonymous functions don't have a .name in ES2015, so don't set + * it on the instance either. The instance will then inherit + * it from Function.prototype.name. + */ + DUK_DD(DUK_DDPRINT("not setting function instance .name")); + duk_pop_unsafe(thr); + } +#endif + + /* + * Compact the closure, in most cases no properties will be added later. + * Also, without this the closures end up having unused property slots + * (e.g. in Duktape 0.9.0, 8 slots would be allocated and only 7 used). + * A better future solution would be to allocate the closure directly + * to correct size (and setup the properties directly without going + * through the API). + */ + + duk_compact(thr, -2); + + /* + * Some assertions (E5 Section 13.2). + */ + + DUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(&fun_clos->obj) == DUK_HOBJECT_CLASS_FUNCTION); + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, &fun_clos->obj) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]); + DUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(&fun_clos->obj)); + DUK_ASSERT(duk_has_prop_stridx(thr, -2, DUK_STRIDX_LENGTH) != 0); + DUK_ASSERT(add_auto_proto == 0 || duk_has_prop_stridx(thr, -2, DUK_STRIDX_PROTOTYPE) != 0); + /* May be missing .name */ + DUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(&fun_clos->obj) || + duk_has_prop_stridx(thr, -2, DUK_STRIDX_CALLER) != 0); + DUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(&fun_clos->obj) || + duk_has_prop_stridx(thr, -2, DUK_STRIDX_LC_ARGUMENTS) != 0); + + /* + * Finish + */ + + /* [ ... closure template ] */ + + DUK_DDD(DUK_DDDPRINT("created function instance: template=%!iT -> closure=%!iT", + (duk_tval *) duk_get_tval(thr, -1), + (duk_tval *) duk_get_tval(thr, -2))); + + duk_pop_unsafe(thr); + + /* [ ... closure ] */ +} + +/* + * Delayed activation environment record initialization (for functions + * with NEWENV). + * + * The non-delayed initialization is handled by duk_handle_call(). + */ + +DUK_LOCAL void duk__preallocate_env_entries(duk_hthread *thr, duk_hobject *varmap, duk_hobject *env) { + duk_uint_fast32_t i; + + for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(varmap); i++) { + duk_hstring *key; + + key = DUK_HOBJECT_E_GET_KEY(thr->heap, varmap, i); + DUK_ASSERT(key != NULL); /* assume keys are compact in _Varmap */ + DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, varmap, i)); /* assume plain values */ + + /* Predefine as 'undefined' to reserve a property slot. + * This makes the unwind process (where register values + * are copied to the env object) safe against throwing. + * + * XXX: This could be made much faster by creating the + * property table directly. + */ + duk_push_undefined(thr); + DUK_DDD(DUK_DDDPRINT("preallocate env entry for key %!O", key)); + duk_hobject_define_property_internal(thr, env, key, DUK_PROPDESC_FLAGS_WE); + } +} + +/* shared helper */ +DUK_INTERNAL +duk_hobject *duk_create_activation_environment_record(duk_hthread *thr, + duk_hobject *func, + duk_size_t bottom_byteoff) { + duk_hdecenv *env; + duk_hobject *parent; + duk_hcompfunc *f; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(func != NULL); + + DUK_STATS_INC(thr->heap, stats_envrec_create); + + f = (duk_hcompfunc *) func; + parent = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, f); + if (!parent) { + parent = thr->builtins[DUK_BIDX_GLOBAL_ENV]; + } + + env = duk_hdecenv_alloc(thr, + DUK_HOBJECT_FLAG_EXTENSIBLE | + DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV)); + DUK_ASSERT(env != NULL); + duk_push_hobject(thr, (duk_hobject *) env); + + DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL); + DUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) env, parent); + DUK_HOBJECT_INCREF_ALLOWNULL(thr, parent); /* parent env is the prototype */ + + /* open scope information, for compiled functions only */ + + DUK_ASSERT(env->thread == NULL); + DUK_ASSERT(env->varmap == NULL); + DUK_ASSERT(env->regbase_byteoff == 0); + if (DUK_HOBJECT_IS_COMPFUNC(func)) { + duk_hobject *varmap; + + varmap = duk_hobject_get_varmap(thr, func); + if (varmap != NULL) { + env->varmap = varmap; + DUK_HOBJECT_INCREF(thr, varmap); + env->thread = thr; + DUK_HTHREAD_INCREF(thr, thr); + env->regbase_byteoff = bottom_byteoff; + + /* Preallocate env property table to avoid potential + * for out-of-memory on unwind when the env is closed. + */ + duk__preallocate_env_entries(thr, varmap, (duk_hobject *) env); + } else { + /* If function has no _Varmap, leave the environment closed. */ + DUK_ASSERT(env->thread == NULL); + DUK_ASSERT(env->varmap == NULL); + DUK_ASSERT(env->regbase_byteoff == 0); + } + } + + return (duk_hobject *) env; +} + +DUK_INTERNAL +void duk_js_init_activation_environment_records_delayed(duk_hthread *thr, + duk_activation *act) { + duk_hobject *func; + duk_hobject *env; + + DUK_ASSERT(thr != NULL); + func = DUK_ACT_GET_FUNC(act); + DUK_ASSERT(func != NULL); + DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func)); /* bound functions are never in act 'func' */ + + /* + * Delayed initialization only occurs for 'NEWENV' functions. + */ + + DUK_ASSERT(DUK_HOBJECT_HAS_NEWENV(func)); + DUK_ASSERT(act->lex_env == NULL); + DUK_ASSERT(act->var_env == NULL); + + DUK_STATS_INC(thr->heap, stats_envrec_delayedcreate); + + env = duk_create_activation_environment_record(thr, func, act->bottom_byteoff); + DUK_ASSERT(env != NULL); + /* 'act' is a stable pointer, so still OK. */ + + DUK_DDD(DUK_DDDPRINT("created delayed fresh env: %!ipO", (duk_heaphdr *) env)); +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2) + { + duk_hobject *p = env; + while (p) { + DUK_DDD(DUK_DDDPRINT(" -> %!ipO", (duk_heaphdr *) p)); + p = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, p); + } + } +#endif + + act->lex_env = env; + act->var_env = env; + DUK_HOBJECT_INCREF(thr, env); /* XXX: incref by count (here 2 times) */ + DUK_HOBJECT_INCREF(thr, env); + + duk_pop_unsafe(thr); +} + +/* + * Closing environment records. + * + * The environment record MUST be closed with the thread where its activation + * is; i.e. if 'env' is open, 'thr' must match env->thread, and the regbase + * and varmap must still be valid. On entry, 'env' must be reachable. + */ + +DUK_INTERNAL void duk_js_close_environment_record(duk_hthread *thr, duk_hobject *env) { + duk_uint_fast32_t i; + duk_hobject *varmap; + duk_hstring *key; + duk_tval *tv; + duk_uint_t regnum; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(env != NULL); + + if (DUK_UNLIKELY(!DUK_HOBJECT_IS_DECENV(env))) { + DUK_DDD(DUK_DDDPRINT("env not a declarative record: %!iO", (duk_heaphdr *) env)); + return; + } + + varmap = ((duk_hdecenv *) env)->varmap; + if (varmap == NULL) { + DUK_DDD(DUK_DDDPRINT("env already closed: %!iO", (duk_heaphdr *) env)); + + return; + } + DUK_ASSERT(((duk_hdecenv *) env)->thread != NULL); + DUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env); + + DUK_DDD(DUK_DDDPRINT("closing env: %!iO", (duk_heaphdr *) env)); + DUK_DDD(DUK_DDDPRINT("varmap: %!O", (duk_heaphdr *) varmap)); + + /* Env must be closed in the same thread as where it runs. */ + DUK_ASSERT(((duk_hdecenv *) env)->thread == thr); + + /* XXX: additional conditions when to close variables? we don't want to do it + * unless the environment may have "escaped" (referenced in a function closure). + * With delayed environments, the existence is probably good enough of a check. + */ + + /* Note: we rely on the _Varmap having a bunch of nice properties, like: + * - being compacted and unmodified during this process + * - not containing an array part + * - having correct value types + */ + + DUK_DDD(DUK_DDDPRINT("copying bound register values, %ld bound regs", (long) DUK_HOBJECT_GET_ENEXT(varmap))); + + /* Copy over current variable values from value stack to the + * environment record. The scope object is empty but may + * inherit from another scope which has conflicting names. + */ + + /* XXX: Do this using a once allocated entry area, no side effects. + * Hash part would need special treatment however (maybe copy, and + * then realloc with hash part if large enough). + */ + for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(varmap); i++) { + duk_size_t regbase_byteoff; + + key = DUK_HOBJECT_E_GET_KEY(thr->heap, varmap, i); + DUK_ASSERT(key != NULL); /* assume keys are compact in _Varmap */ + DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, varmap, i)); /* assume plain values */ + + tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, varmap, i); + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); + DUK_ASSERT(DUK_TVAL_GET_NUMBER(tv) <= (duk_double_t) DUK_UINT32_MAX); /* limits */ +#if defined(DUK_USE_FASTINT) + DUK_ASSERT(DUK_TVAL_IS_FASTINT(tv)); + regnum = (duk_uint_t) DUK_TVAL_GET_FASTINT_U32(tv); +#else + regnum = (duk_uint_t) DUK_TVAL_GET_NUMBER(tv); +#endif + + regbase_byteoff = ((duk_hdecenv *) env)->regbase_byteoff; + DUK_ASSERT((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum >= (duk_uint8_t *) thr->valstack); + DUK_ASSERT((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum < (duk_uint8_t *) thr->valstack_top); + + /* Write register value into env as named properties. + * If property already exists, overwrites silently. + * Property is writable, but not deletable (not configurable + * in terms of property attributes). + * + * This property write must not throw because we're unwinding + * and unwind code is not allowed to throw at present. The + * call itself has no such guarantees, but we've preallocated + * entries for each property when the env was created, so no + * out-of-memory error should be possible. If this guarantee + * is not provided, problems like GH-476 may happen. + */ + duk_push_tval(thr, (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum)); + DUK_DDD(DUK_DDDPRINT("closing identifier %!O -> reg %ld, value %!T", + (duk_heaphdr *) key, + (long) regnum, + (duk_tval *) duk_get_tval(thr, -1))); + duk_hobject_define_property_internal(thr, env, key, DUK_PROPDESC_FLAGS_WE); + } + + /* NULL atomically to avoid inconsistent state + side effects. */ + DUK_HOBJECT_DECREF_NORZ(thr, ((duk_hdecenv *) env)->thread); + DUK_HOBJECT_DECREF_NORZ(thr, ((duk_hdecenv *) env)->varmap); + ((duk_hdecenv *) env)->thread = NULL; + ((duk_hdecenv *) env)->varmap = NULL; + + DUK_DDD(DUK_DDDPRINT("env after closing: %!O", (duk_heaphdr *) env)); +} + +/* + * GETIDREF: a GetIdentifierReference-like helper. + * + * Provides a parent traversing lookup and a single level lookup + * (for HasBinding). + * + * Instead of returning the value, returns a bunch of values allowing + * the caller to read, write, or delete the binding. Value pointers + * are duk_tval pointers which can be mutated directly as long as + * refcounts are properly updated. Note that any operation which may + * reallocate valstacks or compact objects may invalidate the returned + * duk_tval (but not object) pointers, so caller must be very careful. + * + * If starting environment record 'env' is given, 'act' is ignored. + * However, if 'env' is NULL, the caller may identify, in 'act', an + * activation which hasn't had its declarative environment initialized + * yet. The activation registers are then looked up, and its parent + * traversed normally. + * + * The 'out' structure values are only valid if the function returns + * success (non-zero). + */ + +/* lookup name from an open declarative record's registers */ +DUK_LOCAL +duk_bool_t duk__getid_open_decl_env_regs(duk_hthread *thr, + duk_hstring *name, + duk_hdecenv *env, + duk__id_lookup_result *out) { + duk_tval *tv; + duk_size_t reg_rel; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(name != NULL); + DUK_ASSERT(env != NULL); + DUK_ASSERT(out != NULL); + + DUK_ASSERT(DUK_HOBJECT_IS_DECENV((duk_hobject *) env)); + DUK_HDECENV_ASSERT_VALID(env); + + if (env->thread == NULL) { + /* already closed */ + return 0; + } + DUK_ASSERT(env->varmap != NULL); + + tv = duk_hobject_find_entry_tval_ptr(thr->heap, env->varmap, name); + if (DUK_UNLIKELY(tv == NULL)) { + return 0; + } + + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); + DUK_ASSERT(DUK_TVAL_GET_NUMBER(tv) <= (duk_double_t) DUK_UINT32_MAX); /* limits */ +#if defined(DUK_USE_FASTINT) + DUK_ASSERT(DUK_TVAL_IS_FASTINT(tv)); + reg_rel = (duk_size_t) DUK_TVAL_GET_FASTINT_U32(tv); +#else + reg_rel = (duk_size_t) DUK_TVAL_GET_NUMBER(tv); +#endif + DUK_ASSERT_DISABLE(reg_rel >= 0); /* unsigned */ + + tv = (duk_tval *) (void *) ((duk_uint8_t *) env->thread->valstack + env->regbase_byteoff + sizeof(duk_tval) * reg_rel); + DUK_ASSERT(tv >= env->thread->valstack && tv < env->thread->valstack_end); /* XXX: more accurate? */ + + out->value = tv; + out->attrs = DUK_PROPDESC_FLAGS_W; /* registers are mutable, non-deletable */ + out->env = (duk_hobject *) env; + out->holder = NULL; + out->has_this = 0; + return 1; +} + +/* lookup name from current activation record's functions' registers */ +DUK_LOCAL +duk_bool_t duk__getid_activation_regs(duk_hthread *thr, + duk_hstring *name, + duk_activation *act, + duk__id_lookup_result *out) { + duk_tval *tv; + duk_hobject *func; + duk_hobject *varmap; + duk_size_t reg_rel; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(name != NULL); + DUK_ASSERT(act != NULL); + DUK_ASSERT(out != NULL); + + func = DUK_ACT_GET_FUNC(act); + DUK_ASSERT(func != NULL); + DUK_ASSERT(DUK_HOBJECT_HAS_NEWENV(func)); + + if (!DUK_HOBJECT_IS_COMPFUNC(func)) { + return 0; + } + + /* XXX: move varmap to duk_hcompfunc struct field? */ + varmap = duk_hobject_get_varmap(thr, func); + if (!varmap) { + return 0; + } + + tv = duk_hobject_find_entry_tval_ptr(thr->heap, varmap, name); + if (!tv) { + return 0; + } + DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv)); + reg_rel = (duk_size_t) DUK_TVAL_GET_NUMBER(tv); + DUK_ASSERT_DISABLE(reg_rel >= 0); + DUK_ASSERT(reg_rel < ((duk_hcompfunc *) func)->nregs); + + tv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff); + tv += reg_rel; + + out->value = tv; + out->attrs = DUK_PROPDESC_FLAGS_W; /* registers are mutable, non-deletable */ + out->env = NULL; + out->holder = NULL; + out->has_this = 0; + return 1; +} + +DUK_LOCAL +duk_bool_t duk__get_identifier_reference(duk_hthread *thr, + duk_hobject *env, + duk_hstring *name, + duk_activation *act, + duk_bool_t parents, + duk__id_lookup_result *out) { + duk_tval *tv; + duk_uint_t sanity; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(env != NULL || act != NULL); + DUK_ASSERT(name != NULL); + DUK_ASSERT(out != NULL); + + DUK_ASSERT(!env || DUK_HOBJECT_IS_ENV(env)); + DUK_ASSERT(!env || !DUK_HOBJECT_HAS_ARRAY_PART(env)); + + /* + * Conceptually, we look for the identifier binding by starting from + * 'env' and following to chain of environment records (represented + * by the prototype chain). + * + * If 'env' is NULL, the current activation does not yet have an + * allocated declarative environment record; this should be treated + * exactly as if the environment record existed but had no bindings + * other than register bindings. + * + * Note: we assume that with the DUK_HOBJECT_FLAG_NEWENV cleared + * the environment will always be initialized immediately; hence + * a NULL 'env' should only happen with the flag set. This is the + * case for: (1) function calls, and (2) strict, direct eval calls. + */ + + if (env == NULL && act != NULL) { + duk_hobject *func; + duk_hcompfunc *f; + + DUK_DDD(DUK_DDDPRINT("duk__get_identifier_reference: env is NULL, activation is non-NULL -> " + "delayed env case, look up activation regs first")); + + /* + * Try registers + */ + + if (duk__getid_activation_regs(thr, name, act, out)) { + DUK_DDD(DUK_DDDPRINT("duk__get_identifier_reference successful: " + "name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O " + "(found from register bindings when env=NULL)", + (duk_heaphdr *) name, (duk_tval *) out->value, + (long) out->attrs, (long) out->has_this, + (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder)); + return 1; + } + + DUK_DDD(DUK_DDDPRINT("not found in current activation regs")); + + /* + * Not found in registers, proceed to the parent record. + * Here we need to determine what the parent would be, + * if 'env' was not NULL (i.e. same logic as when initializing + * the record). + * + * Note that environment initialization is only deferred when + * DUK_HOBJECT_HAS_NEWENV is set, and this only happens for: + * - Function code + * - Strict eval code + * + * We only need to check _Lexenv here; _Varenv exists only if it + * differs from _Lexenv (and thus _Lexenv will also be present). + */ + + if (!parents) { + DUK_DDD(DUK_DDDPRINT("duk__get_identifier_reference failed, no parent traversal " + "(not found from register bindings when env=NULL)")); + goto fail_not_found; + } + + func = DUK_ACT_GET_FUNC(act); + DUK_ASSERT(func != NULL); + DUK_ASSERT(DUK_HOBJECT_HAS_NEWENV(func)); + f = (duk_hcompfunc *) func; + + env = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, f); + if (!env) { + env = thr->builtins[DUK_BIDX_GLOBAL_ENV]; + } + + DUK_DDD(DUK_DDDPRINT("continue lookup from env: %!iO", + (duk_heaphdr *) env)); + } + + /* + * Prototype walking starting from 'env'. + * + * ('act' is not needed anywhere here.) + */ + + sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY; + while (env != NULL) { + duk_small_uint_t cl; + duk_uint_t attrs; + + DUK_DDD(DUK_DDDPRINT("duk__get_identifier_reference, name=%!O, considering env=%p -> %!iO", + (duk_heaphdr *) name, + (void *) env, + (duk_heaphdr *) env)); + + DUK_ASSERT(env != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_ENV(env)); + DUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(env)); + + cl = DUK_HOBJECT_GET_CLASS_NUMBER(env); + DUK_ASSERT(cl == DUK_HOBJECT_CLASS_OBJENV || cl == DUK_HOBJECT_CLASS_DECENV); + if (cl == DUK_HOBJECT_CLASS_DECENV) { + /* + * Declarative environment record. + * + * Identifiers can never be stored in ancestors and are + * always plain values, so we can use an internal helper + * and access the value directly with an duk_tval ptr. + * + * A closed environment is only indicated by it missing + * the "book-keeping" properties required for accessing + * register-bound variables. + */ + + DUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env); + if (duk__getid_open_decl_env_regs(thr, name, (duk_hdecenv *) env, out)) { + DUK_DDD(DUK_DDDPRINT("duk__get_identifier_reference successful: " + "name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O " + "(declarative environment record, scope open, found in regs)", + (duk_heaphdr *) name, (duk_tval *) out->value, + (long) out->attrs, (long) out->has_this, + (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder)); + return 1; + } + + tv = duk_hobject_find_entry_tval_ptr_and_attrs(thr->heap, env, name, &attrs); + if (tv) { + out->value = tv; + out->attrs = attrs; + out->env = env; + out->holder = env; + out->has_this = 0; + + DUK_DDD(DUK_DDDPRINT("duk__get_identifier_reference successful: " + "name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O " + "(declarative environment record, found in properties)", + (duk_heaphdr *) name, (duk_tval *) out->value, + (long) out->attrs, (long) out->has_this, + (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder)); + return 1; + } + } else { + /* + * Object environment record. + * + * Binding (target) object is an external, uncontrolled object. + * Identifier may be bound in an ancestor property, and may be + * an accessor. Target can also be a Proxy which we must support + * here. + */ + + /* XXX: we could save space by using _Target OR _This. If _Target, assume + * this binding is undefined. If _This, assumes this binding is _This, and + * target is also _This. One property would then be enough. + */ + + duk_hobject *target; + duk_bool_t found; + + DUK_ASSERT(cl == DUK_HOBJECT_CLASS_OBJENV); + DUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) env); + + target = ((duk_hobjenv *) env)->target; + DUK_ASSERT(target != NULL); + + /* Target may be a Proxy or property may be an accessor, so we must + * use an actual, Proxy-aware hasprop check here. + * + * out->holder is NOT set to the actual duk_hobject where the + * property is found, but rather the object binding target object. + */ + +#if defined(DUK_USE_ES6_PROXY) + if (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(target))) { + duk_tval tv_name; + duk_tval tv_target_tmp; + + DUK_ASSERT(name != NULL); + DUK_TVAL_SET_STRING(&tv_name, name); + DUK_TVAL_SET_OBJECT(&tv_target_tmp, target); + + found = duk_hobject_hasprop(thr, &tv_target_tmp, &tv_name); + } else +#endif /* DUK_USE_ES6_PROXY */ + { + /* XXX: duk_hobject_hasprop() would be correct for + * non-Proxy objects too, but it is about ~20-25% + * slower at present so separate code paths for + * Proxy and non-Proxy now. + */ + found = duk_hobject_hasprop_raw(thr, target, name); + } + + if (found) { + out->value = NULL; /* can't get value, may be accessor */ + out->attrs = 0; /* irrelevant when out->value == NULL */ + out->env = env; + out->holder = target; + out->has_this = ((duk_hobjenv *) env)->has_this; + + DUK_DDD(DUK_DDDPRINT("duk__get_identifier_reference successful: " + "name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O " + "(object environment record)", + (duk_heaphdr *) name, (duk_tval *) out->value, + (long) out->attrs, (long) out->has_this, + (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder)); + return 1; + } + } + + if (!parents) { + DUK_DDD(DUK_DDDPRINT("duk__get_identifier_reference failed, no parent traversal " + "(not found from first traversed env)")); + goto fail_not_found; + } + + if (DUK_UNLIKELY(sanity-- == 0)) { + DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT); + DUK_WO_NORETURN(return 0;); + } + env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, env); + } + + /* + * Not found (even in global object) + */ + + fail_not_found: + return 0; +} + +/* + * HASVAR: check identifier binding from a given environment record + * without traversing its parents. + * + * This primitive is not exposed to user code as such, but is used + * internally for e.g. declaration binding instantiation. + * + * See E5 Sections: + * 10.2.1.1.1 HasBinding(N) + * 10.2.1.2.1 HasBinding(N) + * + * Note: strictness has no bearing on this check. Hence we don't take + * a 'strict' parameter. + */ + +#if 0 /*unused*/ +DUK_INTERNAL +duk_bool_t duk_js_hasvar_envrec(duk_hthread *thr, + duk_hobject *env, + duk_hstring *name) { + duk__id_lookup_result ref; + duk_bool_t parents; + + DUK_DDD(DUK_DDDPRINT("hasvar: thr=%p, env=%p, name=%!O " + "(env -> %!dO)", + (void *) thr, (void *) env, (duk_heaphdr *) name, + (duk_heaphdr *) env)); + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(env != NULL); + DUK_ASSERT(name != NULL); + + DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env); + DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name); + + DUK_ASSERT(DUK_HOBJECT_IS_ENV(env)); + DUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(env)); + + /* lookup results is ignored */ + parents = 0; + return duk__get_identifier_reference(thr, env, name, NULL, parents, &ref); +} +#endif + +/* + * GETVAR + * + * See E5 Sections: + * 11.1.2 Identifier Reference + * 10.3.1 Identifier Resolution + * 11.13.1 Simple Assignment [example of where the Reference is GetValue'd] + * 8.7.1 GetValue (V) + * 8.12.1 [[GetOwnProperty]] (P) + * 8.12.2 [[GetProperty]] (P) + * 8.12.3 [[Get]] (P) + * + * If 'throw' is true, always leaves two values on top of stack: [val this]. + * + * If 'throw' is false, returns 0 if identifier cannot be resolved, and the + * stack will be unaffected in this case. If identifier is resolved, returns + * 1 and leaves [val this] on top of stack. + * + * Note: the 'strict' flag of a reference returned by GetIdentifierReference + * is ignored by GetValue. Hence we don't take a 'strict' parameter. + * + * The 'throw' flag is needed for implementing 'typeof' for an unreferenced + * identifier. An unreference identifier in other contexts generates a + * ReferenceError. + */ + +DUK_LOCAL +duk_bool_t duk__getvar_helper(duk_hthread *thr, + duk_hobject *env, + duk_activation *act, + duk_hstring *name, + duk_bool_t throw_flag) { + duk__id_lookup_result ref; + duk_tval tv_tmp_obj; + duk_tval tv_tmp_key; + duk_bool_t parents; + + DUK_DDD(DUK_DDDPRINT("getvar: thr=%p, env=%p, act=%p, name=%!O " + "(env -> %!dO)", + (void *) thr, (void *) env, (void *) act, + (duk_heaphdr *) name, (duk_heaphdr *) env)); + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(name != NULL); + /* env and act may be NULL */ + + DUK_STATS_INC(thr->heap, stats_getvar_all); + + DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env); + DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name); + + parents = 1; /* follow parent chain */ + if (duk__get_identifier_reference(thr, env, name, act, parents, &ref)) { + if (ref.value) { + duk_push_tval(thr, ref.value); + duk_push_undefined(thr); + } else { + DUK_ASSERT(ref.holder != NULL); + + /* ref.holder is safe across the getprop call (even + * with side effects) because 'env' is reachable and + * ref.holder is a direct heap pointer. + */ + + DUK_TVAL_SET_OBJECT(&tv_tmp_obj, ref.holder); + DUK_TVAL_SET_STRING(&tv_tmp_key, name); + (void) duk_hobject_getprop(thr, &tv_tmp_obj, &tv_tmp_key); /* [value] */ + + if (ref.has_this) { + duk_push_hobject(thr, ref.holder); + } else { + duk_push_undefined(thr); + } + + /* [value this] */ + } + + return 1; + } else { + if (throw_flag) { + DUK_ERROR_FMT1(thr, DUK_ERR_REFERENCE_ERROR, + "identifier '%s' undefined", + (const char *) DUK_HSTRING_GET_DATA(name)); + DUK_WO_NORETURN(return 0;); + } + + return 0; + } +} + +DUK_INTERNAL +duk_bool_t duk_js_getvar_envrec(duk_hthread *thr, + duk_hobject *env, + duk_hstring *name, + duk_bool_t throw_flag) { + return duk__getvar_helper(thr, env, NULL, name, throw_flag); +} + +DUK_INTERNAL +duk_bool_t duk_js_getvar_activation(duk_hthread *thr, + duk_activation *act, + duk_hstring *name, + duk_bool_t throw_flag) { + DUK_ASSERT(act != NULL); + return duk__getvar_helper(thr, act->lex_env, act, name, throw_flag); +} + +/* + * PUTVAR + * + * See E5 Sections: + * 11.1.2 Identifier Reference + * 10.3.1 Identifier Resolution + * 11.13.1 Simple Assignment [example of where the Reference is PutValue'd] + * 8.7.2 PutValue (V,W) [see especially step 3.b, undefined -> automatic global in non-strict mode] + * 8.12.4 [[CanPut]] (P) + * 8.12.5 [[Put]] (P) + * + * Note: may invalidate any valstack (or object) duk_tval pointers because + * putting a value may reallocate any object or any valstack. Caller beware. + */ + +DUK_LOCAL +void duk__putvar_helper(duk_hthread *thr, + duk_hobject *env, + duk_activation *act, + duk_hstring *name, + duk_tval *val, + duk_bool_t strict) { + duk__id_lookup_result ref; + duk_tval tv_tmp_obj; + duk_tval tv_tmp_key; + duk_bool_t parents; + + DUK_STATS_INC(thr->heap, stats_putvar_all); + + DUK_DDD(DUK_DDDPRINT("putvar: thr=%p, env=%p, act=%p, name=%!O, val=%p, strict=%ld " + "(env -> %!dO, val -> %!T)", + (void *) thr, (void *) env, (void *) act, + (duk_heaphdr *) name, (void *) val, (long) strict, + (duk_heaphdr *) env, (duk_tval *) val)); + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(name != NULL); + DUK_ASSERT(val != NULL); + /* env and act may be NULL */ + + DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env); + DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name); + DUK_ASSERT_REFCOUNT_NONZERO_TVAL(val); + + /* + * In strict mode E5 protects 'eval' and 'arguments' from being + * assigned to (or even declared anywhere). Attempt to do so + * should result in a compile time SyntaxError. See the internal + * design documentation for details. + * + * Thus, we should never come here, run-time, for strict code, + * and name 'eval' or 'arguments'. + */ + + DUK_ASSERT(!strict || + (name != DUK_HTHREAD_STRING_EVAL(thr) && + name != DUK_HTHREAD_STRING_LC_ARGUMENTS(thr))); + + /* + * Lookup variable and update in-place if found. + */ + + parents = 1; /* follow parent chain */ + + if (duk__get_identifier_reference(thr, env, name, act, parents, &ref)) { + if (ref.value && (ref.attrs & DUK_PROPDESC_FLAG_WRITABLE)) { + /* Update duk_tval in-place if pointer provided and the + * property is writable. If the property is not writable + * (immutable binding), use duk_hobject_putprop() which + * will respect mutability. + */ + duk_tval *tv_val; + + tv_val = ref.value; + DUK_ASSERT(tv_val != NULL); + DUK_TVAL_SET_TVAL_UPDREF(thr, tv_val, val); /* side effects */ + + /* ref.value invalidated here */ + } else { + DUK_ASSERT(ref.holder != NULL); + + DUK_TVAL_SET_OBJECT(&tv_tmp_obj, ref.holder); + DUK_TVAL_SET_STRING(&tv_tmp_key, name); + (void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, val, strict); + + /* ref.value invalidated here */ + } + + return; + } + + /* + * Not found: write to global object (non-strict) or ReferenceError + * (strict); see E5 Section 8.7.2, step 3. + */ + + if (strict) { + DUK_DDD(DUK_DDDPRINT("identifier binding not found, strict => reference error")); + DUK_ERROR_FMT1(thr, DUK_ERR_REFERENCE_ERROR, + "identifier '%s' undefined", + (const char *) DUK_HSTRING_GET_DATA(name)); + DUK_WO_NORETURN(return;); + } + + DUK_DDD(DUK_DDDPRINT("identifier binding not found, not strict => set to global")); + + DUK_TVAL_SET_OBJECT(&tv_tmp_obj, thr->builtins[DUK_BIDX_GLOBAL]); + DUK_TVAL_SET_STRING(&tv_tmp_key, name); + (void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, val, 0); /* 0 = no throw */ + + /* NB: 'val' may be invalidated here because put_value may realloc valstack, + * caller beware. + */ +} + +DUK_INTERNAL +void duk_js_putvar_envrec(duk_hthread *thr, + duk_hobject *env, + duk_hstring *name, + duk_tval *val, + duk_bool_t strict) { + duk__putvar_helper(thr, env, NULL, name, val, strict); +} + +DUK_INTERNAL +void duk_js_putvar_activation(duk_hthread *thr, + duk_activation *act, + duk_hstring *name, + duk_tval *val, + duk_bool_t strict) { + DUK_ASSERT(act != NULL); + duk__putvar_helper(thr, act->lex_env, act, name, val, strict); +} + +/* + * DELVAR + * + * See E5 Sections: + * 11.4.1 The delete operator + * 10.2.1.1.5 DeleteBinding (N) [declarative environment record] + * 10.2.1.2.5 DeleteBinding (N) [object environment record] + * + * Variable bindings established inside eval() are deletable (configurable), + * other bindings are not, including variables declared in global level. + * Registers are always non-deletable, and the deletion of other bindings + * is controlled by the configurable flag. + * + * For strict mode code, the 'delete' operator should fail with a compile + * time SyntaxError if applied to identifiers. Hence, no strict mode + * run-time deletion of identifiers should ever happen. This function + * should never be called from strict mode code! + */ + +DUK_LOCAL +duk_bool_t duk__delvar_helper(duk_hthread *thr, + duk_hobject *env, + duk_activation *act, + duk_hstring *name) { + duk__id_lookup_result ref; + duk_bool_t parents; + + DUK_DDD(DUK_DDDPRINT("delvar: thr=%p, env=%p, act=%p, name=%!O " + "(env -> %!dO)", + (void *) thr, (void *) env, (void *) act, + (duk_heaphdr *) name, (duk_heaphdr *) env)); + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(name != NULL); + /* env and act may be NULL */ + + DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name); + + parents = 1; /* follow parent chain */ + + if (duk__get_identifier_reference(thr, env, name, act, parents, &ref)) { + if (ref.value && !(ref.attrs & DUK_PROPDESC_FLAG_CONFIGURABLE)) { + /* Identifier found in registers (always non-deletable) + * or declarative environment record and non-configurable. + */ + return 0; + } + DUK_ASSERT(ref.holder != NULL); + + return duk_hobject_delprop_raw(thr, ref.holder, name, 0); + } + + /* + * Not found (even in global object). + * + * In non-strict mode this is a silent SUCCESS (!), see E5 Section 11.4.1, + * step 3.b. In strict mode this case is a compile time SyntaxError so + * we should not come here. + */ + + DUK_DDD(DUK_DDDPRINT("identifier to be deleted not found: name=%!O " + "(treated as silent success)", + (duk_heaphdr *) name)); + return 1; +} + +#if 0 /*unused*/ +DUK_INTERNAL +duk_bool_t duk_js_delvar_envrec(duk_hthread *thr, + duk_hobject *env, + duk_hstring *name) { + return duk__delvar_helper(thr, env, NULL, name); +} +#endif + +DUK_INTERNAL +duk_bool_t duk_js_delvar_activation(duk_hthread *thr, + duk_activation *act, + duk_hstring *name) { + DUK_ASSERT(act != NULL); + return duk__delvar_helper(thr, act->lex_env, act, name); +} + +/* + * DECLVAR + * + * See E5 Sections: + * 10.4.3 Entering Function Code + * 10.5 Declaration Binding Instantion + * 12.2 Variable Statement + * 11.1.2 Identifier Reference + * 10.3.1 Identifier Resolution + * + * Variable declaration behavior is mainly discussed in Section 10.5, + * and is not discussed in the execution semantics (Sections 11-13). + * + * Conceptually declarations happen when code (global, eval, function) + * is entered, before any user code is executed. In practice, register- + * bound identifiers are 'declared' automatically (by virtue of being + * allocated to registers with the initial value 'undefined'). Other + * identifiers are declared in the function prologue with this primitive. + * + * Since non-register bindings eventually back to an internal object's + * properties, the 'prop_flags' argument is used to specify binding + * type: + * + * - Immutable binding: set DUK_PROPDESC_FLAG_WRITABLE to false + * - Non-deletable binding: set DUK_PROPDESC_FLAG_CONFIGURABLE to false + * - The flag DUK_PROPDESC_FLAG_ENUMERABLE should be set, although it + * doesn't really matter for internal objects + * + * All bindings are non-deletable mutable bindings except: + * + * - Declarations in eval code (mutable, deletable) + * - 'arguments' binding in strict function code (immutable) + * - Function name binding of a function expression (immutable) + * + * Declarations may go to declarative environment records (always + * so for functions), but may also go to object environment records + * (e.g. global code). The global object environment has special + * behavior when re-declaring a function (but not a variable); see + * E5.1 specification, Section 10.5, step 5.e. + * + * Declarations always go to the 'top-most' environment record, i.e. + * we never check the record chain. It's not an error even if a + * property (even an immutable or non-deletable one) of the same name + * already exists. + * + * If a declared variable already exists, its value needs to be updated + * (if possible). Returns 1 if a PUTVAR needs to be done by the caller; + * otherwise returns 0. + */ + +DUK_LOCAL +duk_bool_t duk__declvar_helper(duk_hthread *thr, + duk_hobject *env, + duk_hstring *name, + duk_tval *val, + duk_small_uint_t prop_flags, + duk_bool_t is_func_decl) { + duk_hobject *holder; + duk_bool_t parents; + duk__id_lookup_result ref; + duk_tval *tv; + + DUK_DDD(DUK_DDDPRINT("declvar: thr=%p, env=%p, name=%!O, val=%!T, prop_flags=0x%08lx, is_func_decl=%ld " + "(env -> %!iO)", + (void *) thr, (void *) env, (duk_heaphdr *) name, + (duk_tval *) val, (unsigned long) prop_flags, + (unsigned int) is_func_decl, (duk_heaphdr *) env)); + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(env != NULL); + DUK_ASSERT(name != NULL); + DUK_ASSERT(val != NULL); + + /* Note: in strict mode the compiler should reject explicit + * declaration of 'eval' or 'arguments'. However, internal + * bytecode may declare 'arguments' in the function prologue. + * We don't bother checking (or asserting) for these now. + */ + + /* Note: val is a stable duk_tval pointer. The caller makes + * a value copy into its stack frame, so 'tv_val' is not subject + * to side effects here. + */ + + /* + * Check whether already declared. + * + * We need to check whether the binding exists in the environment + * without walking its parents. However, we still need to check + * register-bound identifiers and the prototype chain of an object + * environment target object. + */ + + parents = 0; /* just check 'env' */ + if (duk__get_identifier_reference(thr, env, name, NULL, parents, &ref)) { + duk_int_t e_idx; + duk_int_t h_idx; + duk_small_uint_t flags; + + /* + * Variable already declared, ignore re-declaration. + * The only exception is the updated behavior of E5.1 for + * global function declarations, E5.1 Section 10.5, step 5.e. + * This behavior does not apply to global variable declarations. + */ + + if (!(is_func_decl && env == thr->builtins[DUK_BIDX_GLOBAL_ENV])) { + DUK_DDD(DUK_DDDPRINT("re-declare a binding, ignoring")); + return 1; /* 1 -> needs a PUTVAR */ + } + + /* + * Special behavior in E5.1. + * + * Note that even though parents == 0, the conflicting property + * may be an inherited property (currently our global object's + * prototype is Object.prototype). Step 5.e first operates on + * the existing property (which is potentially in an ancestor) + * and then defines a new property in the global object (and + * never modifies the ancestor). + * + * Also note that this logic would become even more complicated + * if the conflicting property might be a virtual one. Object + * prototype has no virtual properties, though. + * + * XXX: this is now very awkward, rework. + */ + + DUK_DDD(DUK_DDDPRINT("re-declare a function binding in global object, " + "updated E5.1 processing")); + + DUK_ASSERT(ref.holder != NULL); + holder = ref.holder; + + /* holder will be set to the target object, not the actual object + * where the property was found (see duk__get_identifier_reference()). + */ + DUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(holder) == DUK_HOBJECT_CLASS_GLOBAL); + DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(holder)); /* global object doesn't have array part */ + + /* XXX: use a helper for prototype traversal; no loop check here */ + /* must be found: was found earlier, and cannot be inherited */ + for (;;) { + DUK_ASSERT(holder != NULL); + if (duk_hobject_find_entry(thr->heap, holder, name, &e_idx, &h_idx)) { + DUK_ASSERT(e_idx >= 0); + break; + } + /* SCANBUILD: NULL pointer dereference, doesn't actually trigger, + * asserted above. + */ + holder = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, holder); + } + DUK_ASSERT(holder != NULL); + DUK_ASSERT(e_idx >= 0); + /* SCANBUILD: scan-build produces a NULL pointer dereference warning + * below; it never actually triggers because holder is actually never + * NULL. + */ + + /* ref.holder is global object, holder is the object with the + * conflicting property. + */ + + flags = DUK_HOBJECT_E_GET_FLAGS(thr->heap, holder, e_idx); + if (!(flags & DUK_PROPDESC_FLAG_CONFIGURABLE)) { + if (flags & DUK_PROPDESC_FLAG_ACCESSOR) { + DUK_DDD(DUK_DDDPRINT("existing property is a non-configurable " + "accessor -> reject")); + goto fail_existing_attributes; + } + if (!((flags & DUK_PROPDESC_FLAG_WRITABLE) && + (flags & DUK_PROPDESC_FLAG_ENUMERABLE))) { + DUK_DDD(DUK_DDDPRINT("existing property is a non-configurable " + "plain property which is not writable and " + "enumerable -> reject")); + goto fail_existing_attributes; + } + + DUK_DDD(DUK_DDDPRINT("existing property is not configurable but " + "is plain, enumerable, and writable -> " + "allow redeclaration")); + } + + if (holder == ref.holder) { + /* XXX: if duk_hobject_define_property_internal() was updated + * to handle a pre-existing accessor property, this would be + * a simple call (like for the ancestor case). + */ + DUK_DDD(DUK_DDDPRINT("redefine, offending property in global object itself")); + + if (flags & DUK_PROPDESC_FLAG_ACCESSOR) { + duk_hobject *tmp; + + tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, holder, e_idx); + DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, holder, e_idx, NULL); + DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); + DUK_UNREF(tmp); + tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, holder, e_idx); + DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, holder, e_idx, NULL); + DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); + DUK_UNREF(tmp); + } else { + tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx); + DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv); + } + + /* Here val would be potentially invalid if we didn't make + * a value copy at the caller. + */ + + tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx); + DUK_TVAL_SET_TVAL(tv, val); + DUK_TVAL_INCREF(thr, tv); + DUK_HOBJECT_E_SET_FLAGS(thr->heap, holder, e_idx, prop_flags); + + DUK_DDD(DUK_DDDPRINT("updated global binding, final result: " + "value -> %!T, prop_flags=0x%08lx", + (duk_tval *) DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx), + (unsigned long) prop_flags)); + } else { + DUK_DDD(DUK_DDDPRINT("redefine, offending property in ancestor")); + + DUK_ASSERT(ref.holder == thr->builtins[DUK_BIDX_GLOBAL]); + duk_push_tval(thr, val); + duk_hobject_define_property_internal(thr, ref.holder, name, prop_flags); + } + + return 0; + } + + /* + * Not found (in registers or record objects). Declare + * to current variable environment. + */ + + /* + * Get holder object + */ + + if (DUK_HOBJECT_IS_DECENV(env)) { + DUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env); + holder = env; + } else { + DUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) env); + holder = ((duk_hobjenv *) env)->target; + DUK_ASSERT(holder != NULL); + } + + /* + * Define new property + * + * Note: this may fail if the holder is not extensible. + */ + + /* XXX: this is awkward as we use an internal method which doesn't handle + * extensibility etc correctly. Basically we'd want to do a [[DefineOwnProperty]] + * or Object.defineProperty() here. + */ + + if (!DUK_HOBJECT_HAS_EXTENSIBLE(holder)) { + goto fail_not_extensible; + } + + duk_push_hobject(thr, holder); + duk_push_hstring(thr, name); + duk_push_tval(thr, val); + duk_xdef_prop(thr, -3, prop_flags); /* [holder name val] -> [holder] */ + duk_pop_unsafe(thr); + + return 0; + + fail_existing_attributes: + fail_not_extensible: + DUK_ERROR_TYPE(thr, "declaration failed"); + DUK_WO_NORETURN(return 0;); +} + +DUK_INTERNAL +duk_bool_t duk_js_declvar_activation(duk_hthread *thr, + duk_activation *act, + duk_hstring *name, + duk_tval *val, + duk_small_uint_t prop_flags, + duk_bool_t is_func_decl) { + duk_hobject *env; + duk_tval tv_val_copy; + + DUK_ASSERT(act != NULL); + + /* + * Make a value copy of the input val. This ensures that + * side effects cannot invalidate the pointer. + */ + + DUK_TVAL_SET_TVAL(&tv_val_copy, val); + val = &tv_val_copy; + + /* + * Delayed env creation check + */ + + if (!act->var_env) { + DUK_ASSERT(act->lex_env == NULL); + duk_js_init_activation_environment_records_delayed(thr, act); + /* 'act' is a stable pointer, so still OK. */ + } + DUK_ASSERT(act->lex_env != NULL); + DUK_ASSERT(act->var_env != NULL); + + env = act->var_env; + DUK_ASSERT(env != NULL); + DUK_ASSERT(DUK_HOBJECT_IS_ENV(env)); + + return duk__declvar_helper(thr, env, name, val, prop_flags, is_func_decl); +} diff --git a/third_party/duktape/duk_json.h b/third_party/duktape/duk_json.h new file mode 100644 index 00000000..530d69b6 --- /dev/null +++ b/third_party/duktape/duk_json.h @@ -0,0 +1,68 @@ +/* + * Defines for JSON, especially duk_bi_json.c. + */ + +#if !defined(DUK_JSON_H_INCLUDED) +#define DUK_JSON_H_INCLUDED + +/* Encoding/decoding flags */ +#define DUK_JSON_FLAG_ASCII_ONLY (1U << 0) /* escape any non-ASCII characters */ +#define DUK_JSON_FLAG_AVOID_KEY_QUOTES (1U << 1) /* avoid key quotes when key is an ASCII Identifier */ +#define DUK_JSON_FLAG_EXT_CUSTOM (1U << 2) /* extended types: custom encoding */ +#define DUK_JSON_FLAG_EXT_COMPATIBLE (1U << 3) /* extended types: compatible encoding */ + +/* How much stack to require on entry to object/array encode */ +#define DUK_JSON_ENC_REQSTACK 32 + +/* How much stack to require on entry to object/array decode */ +#define DUK_JSON_DEC_REQSTACK 32 + +/* How large a loop detection stack to use */ +#define DUK_JSON_ENC_LOOPARRAY 64 + +/* Encoding state. Heap object references are all borrowed. */ +typedef struct { + duk_hthread *thr; + duk_bufwriter_ctx bw; /* output bufwriter */ + duk_hobject *h_replacer; /* replacer function */ + duk_hstring *h_gap; /* gap (if empty string, NULL) */ + duk_idx_t idx_proplist; /* explicit PropertyList */ + duk_idx_t idx_loop; /* valstack index of loop detection object */ + duk_small_uint_t flags; + duk_small_uint_t flag_ascii_only; + duk_small_uint_t flag_avoid_key_quotes; +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + duk_small_uint_t flag_ext_custom; + duk_small_uint_t flag_ext_compatible; + duk_small_uint_t flag_ext_custom_or_compatible; +#endif + duk_uint_t recursion_depth; + duk_uint_t recursion_limit; + duk_uint_t mask_for_undefined; /* type bit mask: types which certainly produce 'undefined' */ +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + duk_small_uint_t stridx_custom_undefined; + duk_small_uint_t stridx_custom_nan; + duk_small_uint_t stridx_custom_neginf; + duk_small_uint_t stridx_custom_posinf; + duk_small_uint_t stridx_custom_function; +#endif + duk_hobject *visiting[DUK_JSON_ENC_LOOPARRAY]; /* indexed by recursion_depth */ +} duk_json_enc_ctx; + +typedef struct { + duk_hthread *thr; + const duk_uint8_t *p; + const duk_uint8_t *p_start; + const duk_uint8_t *p_end; + duk_idx_t idx_reviver; + duk_small_uint_t flags; +#if defined(DUK_USE_JX) || defined(DUK_USE_JC) + duk_small_uint_t flag_ext_custom; + duk_small_uint_t flag_ext_compatible; + duk_small_uint_t flag_ext_custom_or_compatible; +#endif + duk_int_t recursion_depth; + duk_int_t recursion_limit; +} duk_json_dec_ctx; + +#endif /* DUK_JSON_H_INCLUDED */ diff --git a/third_party/duktape/duk_lexer.c b/third_party/duktape/duk_lexer.c new file mode 100644 index 00000000..24373f31 --- /dev/null +++ b/third_party/duktape/duk_lexer.c @@ -0,0 +1,2439 @@ +/* + * Lexer for source files, ToNumber() string conversions, RegExp expressions, + * and JSON. + * + * Provides a stream of ECMAScript tokens from an UTF-8/CESU-8 buffer. The + * caller can also rewind the token stream into a certain position which is + * needed by the compiler part for multi-pass scanning. Tokens are + * represented as duk_token structures, and contain line number information. + * Token types are identified with DUK_TOK_* defines. + * + * Characters are decoded into a fixed size lookup window consisting of + * decoded Unicode code points, with window positions past the end of the + * input filled with an invalid codepoint (-1). The tokenizer can thus + * perform multiple character lookups efficiently and with few sanity + * checks (such as access outside the end of the input), which keeps the + * tokenization code small at the cost of performance. + * + * Character data in tokens, such as identifier names and string literals, + * is encoded into CESU-8 format on-the-fly while parsing the token in + * question. The string data is made reachable to garbage collection by + * placing the token-related values in value stack entries allocated for + * this purpose by the caller. The characters exist in Unicode code point + * form only in the fixed size lookup window, which keeps character data + * expansion (of especially ASCII data) low. + * + * Token parsing supports the full range of Unicode characters as described + * in the E5 specification. Parsing has been optimized for ASCII characters + * because ordinary ECMAScript code consists almost entirely of ASCII + * characters. Matching of complex Unicode codepoint sets (such as in the + * IdentifierStart and IdentifierPart productions) is optimized for size, + * and is done using a linear scan of a bit-packed list of ranges. This is + * very slow, but should never be entered unless the source code actually + * contains Unicode characters. + * + * ECMAScript tokenization is partially context sensitive. First, + * additional future reserved words are recognized in strict mode (see E5 + * Section 7.6.1.2). Second, a forward slash character ('/') can be + * recognized either as starting a RegExp literal or as a division operator, + * depending on context. The caller must provide necessary context flags + * when requesting a new token. + * + * Future work: + * + * * Make line number tracking optional, as it consumes space. + * + * * Add a feature flag for disabling UTF-8 decoding of input, as most + * source code is ASCII. Because of Unicode escapes written in ASCII, + * this does not allow Unicode support to be removed from e.g. + * duk_unicode_is_identifier_start() nor does it allow removal of CESU-8 + * encoding of e.g. string literals. + * + * * Add a feature flag for disabling Unicode compliance of e.g. identifier + * names. This allows for a build more than a kilobyte smaller, because + * Unicode ranges needed by duk_unicode_is_identifier_start() and + * duk_unicode_is_identifier_part() can be dropped. String literals + * should still be allowed to contain escaped Unicode, so this still does + * not allow removal of CESU-8 encoding of e.g. string literals. + * + * * Character lookup tables for codepoints above BMP could be stripped. + * + * * Strictly speaking, E5 specification requires that source code consists + * of 16-bit code units, and if not, must be conceptually converted to + * that format first. The current lexer processes Unicode code points + * and allows characters outside the BMP. These should be converted to + * surrogate pairs while reading the source characters into the window, + * not after tokens have been formed (as is done now). However, the fix + * is not trivial because two characters are decoded from one codepoint. + * + * * Optimize for speed as well as size. Large if-else ladders are (at + * least potentially) slow. + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Various defines and file specific helper macros + */ + +#define DUK__MAX_RE_DECESC_DIGITS 9 +#define DUK__MAX_RE_QUANT_DIGITS 9 /* Does not allow e.g. 2**31-1, but one more would allow overflows of u32. */ + +/* whether to use macros or helper function depends on call count */ +#define DUK__ISDIGIT(x) ((x) >= DUK_ASC_0 && (x) <= DUK_ASC_9) +#define DUK__ISHEXDIGIT(x) duk__is_hex_digit((x)) +#define DUK__ISOCTDIGIT(x) ((x) >= DUK_ASC_0 && (x) <= DUK_ASC_7) +#define DUK__ISDIGIT03(x) ((x) >= DUK_ASC_0 && (x) <= DUK_ASC_3) +#define DUK__ISDIGIT47(x) ((x) >= DUK_ASC_4 && (x) <= DUK_ASC_7) + +/* lexer character window helpers */ +#define DUK__LOOKUP(lex_ctx,idx) ((lex_ctx)->window[(idx)].codepoint) +#define DUK__ADVANCECHARS(lex_ctx,count) duk__advance_chars((lex_ctx), (count)) +#define DUK__ADVANCEBYTES(lex_ctx,count) duk__advance_bytes((lex_ctx), (count)) +#define DUK__INITBUFFER(lex_ctx) duk__initbuffer((lex_ctx)) +#define DUK__APPENDBUFFER(lex_ctx,x) duk__appendbuffer((lex_ctx), (duk_codepoint_t) (x)) +#define DUK__APPENDBUFFER_ASCII(lex_ctx,x) duk__appendbuffer_ascii((lex_ctx), (duk_codepoint_t) (x)) + +/* lookup shorthands (note: assume context variable is named 'lex_ctx') */ +#define DUK__L0() DUK__LOOKUP(lex_ctx, 0) +#define DUK__L1() DUK__LOOKUP(lex_ctx, 1) +#define DUK__L2() DUK__LOOKUP(lex_ctx, 2) +#define DUK__L3() DUK__LOOKUP(lex_ctx, 3) +#define DUK__L4() DUK__LOOKUP(lex_ctx, 4) +#define DUK__L5() DUK__LOOKUP(lex_ctx, 5) + +/* packed advance/token number macro used by multiple functions */ +#define DUK__ADVTOK(advbytes,tok) ((((advbytes) * sizeof(duk_lexer_codepoint)) << 8) + (tok)) + +/* + * Advance lookup window by N characters, filling in new characters as + * necessary. After returning caller is guaranteed a character window of + * at least DUK_LEXER_WINDOW_SIZE characters. + * + * The main function duk__advance_bytes() is called at least once per every + * token so it has a major lexer/compiler performance impact. There are two + * variants for the main duk__advance_bytes() algorithm: a sliding window + * approach which is slightly faster at the cost of larger code footprint, + * and a simple copying one. + * + * Decoding directly from the source string would be another lexing option. + * But the lookup window based approach has the advantage of hiding the + * source string and its encoding effectively which gives more flexibility + * going forward to e.g. support chunked streaming of source from flash. + * + * Decodes UTF-8/CESU-8 leniently with support for code points from U+0000 to + * U+10FFFF, causing an error if the input is unparseable. Leniency means: + * + * * Unicode code point validation is intentionally not performed, + * except to check that the codepoint does not exceed 0x10ffff. + * + * * In particular, surrogate pairs are allowed and not combined, which + * allows source files to represent all SourceCharacters with CESU-8. + * Broken surrogate pairs are allowed, as ECMAScript does not mandate + * their validation. + * + * * Allow non-shortest UTF-8 encodings. + * + * Leniency here causes few security concerns because all character data is + * decoded into Unicode codepoints before lexer processing, and is then + * re-encoded into CESU-8. The source can be parsed as strict UTF-8 with + * a compiler option. However, ECMAScript source characters include -all- + * 16-bit unsigned integer codepoints, so leniency seems to be appropriate. + * + * Note that codepoints above the BMP are not strictly SourceCharacters, + * but the lexer still accepts them as such. Before ending up in a string + * or an identifier name, codepoints above BMP are converted into surrogate + * pairs and then CESU-8 encoded, resulting in 16-bit Unicode data as + * expected by ECMAScript. + * + * An alternative approach to dealing with invalid or partial sequences + * would be to skip them and replace them with e.g. the Unicode replacement + * character U+FFFD. This has limited utility because a replacement character + * will most likely cause a parse error, unless it occurs inside a string. + * Further, ECMAScript source is typically pure ASCII. + * + * See: + * + * http://en.wikipedia.org/wiki/UTF-8 + * http://en.wikipedia.org/wiki/CESU-8 + * http://tools.ietf.org/html/rfc3629 + * http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences + * + * Future work: + * + * * Reject other invalid Unicode sequences (see Wikipedia entry for examples) + * in strict UTF-8 mode. + * + * * Size optimize. An attempt to use a 16-byte lookup table for the first + * byte resulted in a code increase though. + * + * * Is checking against maximum 0x10ffff really useful? 4-byte encoding + * imposes a certain limit anyway. + * + * * Support chunked streaming of source code. Can be implemented either + * by streaming chunks of bytes or chunks of codepoints. + */ + +#if defined(DUK_USE_LEXER_SLIDING_WINDOW) +DUK_LOCAL void duk__fill_lexer_buffer(duk_lexer_ctx *lex_ctx, duk_small_uint_t start_offset_bytes) { + duk_lexer_codepoint *cp, *cp_end; + duk_ucodepoint_t x; + duk_small_uint_t contlen; + const duk_uint8_t *p, *p_end; +#if defined(DUK_USE_STRICT_UTF8_SOURCE) + duk_ucodepoint_t mincp; +#endif + duk_int_t input_line; + + /* Use temporaries and update lex_ctx only when finished. */ + input_line = lex_ctx->input_line; + p = lex_ctx->input + lex_ctx->input_offset; + p_end = lex_ctx->input + lex_ctx->input_length; + + cp = (duk_lexer_codepoint *) (void *) ((duk_uint8_t *) lex_ctx->buffer + start_offset_bytes); + cp_end = lex_ctx->buffer + DUK_LEXER_BUFFER_SIZE; + + for (; cp != cp_end; cp++) { + cp->offset = (duk_size_t) (p - lex_ctx->input); + cp->line = input_line; + + /* XXX: potential issue with signed pointers, p_end < p. */ + if (DUK_UNLIKELY(p >= p_end)) { + /* If input_offset were assigned a negative value, it would + * result in a large positive value. Most likely it would be + * larger than input_length and be caught here. In any case + * no memory unsafe behavior would happen. + */ + cp->codepoint = -1; + continue; + } + + x = (duk_ucodepoint_t) (*p++); + + /* Fast path. */ + + if (DUK_LIKELY(x < 0x80UL)) { + DUK_ASSERT(x != 0x2028UL && x != 0x2029UL); /* not LS/PS */ + if (DUK_UNLIKELY(x <= 0x000dUL)) { + if ((x == 0x000aUL) || + ((x == 0x000dUL) && (p >= p_end || *p != 0x000aUL))) { + /* lookup for 0x000a above assumes shortest encoding now */ + + /* E5 Section 7.3, treat the following as newlines: + * LF + * CR [not followed by LF] + * LS + * PS + * + * For CR LF, CR is ignored if it is followed by LF, and the LF will bump + * the line number. + */ + input_line++; + } + } + + cp->codepoint = (duk_codepoint_t) x; + continue; + } + + /* Slow path. */ + + if (x < 0xc0UL) { + /* 10xx xxxx -> invalid */ + goto error_encoding; + } else if (x < 0xe0UL) { + /* 110x xxxx 10xx xxxx */ + contlen = 1; +#if defined(DUK_USE_STRICT_UTF8_SOURCE) + mincp = 0x80UL; +#endif + x = x & 0x1fUL; + } else if (x < 0xf0UL) { + /* 1110 xxxx 10xx xxxx 10xx xxxx */ + contlen = 2; +#if defined(DUK_USE_STRICT_UTF8_SOURCE) + mincp = 0x800UL; +#endif + x = x & 0x0fUL; + } else if (x < 0xf8UL) { + /* 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx */ + contlen = 3; +#if defined(DUK_USE_STRICT_UTF8_SOURCE) + mincp = 0x10000UL; +#endif + x = x & 0x07UL; + } else { + /* no point in supporting encodings of 5 or more bytes */ + goto error_encoding; + } + + DUK_ASSERT(p_end >= p); + if ((duk_size_t) contlen > (duk_size_t) (p_end - p)) { + goto error_clipped; + } + + while (contlen > 0) { + duk_small_uint_t y; + y = *p++; + if ((y & 0xc0U) != 0x80U) { + /* check that byte has the form 10xx xxxx */ + goto error_encoding; + } + x = x << 6; + x += y & 0x3fUL; + contlen--; + } + + /* check final character validity */ + + if (x > 0x10ffffUL) { + goto error_encoding; + } +#if defined(DUK_USE_STRICT_UTF8_SOURCE) + if (x < mincp || (x >= 0xd800UL && x <= 0xdfffUL) || x == 0xfffeUL) { + goto error_encoding; + } +#endif + + DUK_ASSERT(x != 0x000aUL && x != 0x000dUL); + if ((x == 0x2028UL) || (x == 0x2029UL)) { + input_line++; + } + + cp->codepoint = (duk_codepoint_t) x; + } + + lex_ctx->input_offset = (duk_size_t) (p - lex_ctx->input); + lex_ctx->input_line = input_line; + return; + + error_clipped: /* clipped codepoint */ + error_encoding: /* invalid codepoint encoding or codepoint */ + lex_ctx->input_offset = (duk_size_t) (p - lex_ctx->input); + lex_ctx->input_line = input_line; + + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_SOURCE_DECODE_FAILED); + DUK_WO_NORETURN(return;); +} + +DUK_LOCAL void duk__advance_bytes(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_bytes) { + duk_small_uint_t used_bytes, avail_bytes; + + DUK_ASSERT_DISABLE(count_bytes >= 0); /* unsigned */ + DUK_ASSERT(count_bytes <= (duk_small_uint_t) (DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint))); + DUK_ASSERT(lex_ctx->window >= lex_ctx->buffer); + DUK_ASSERT(lex_ctx->window < lex_ctx->buffer + DUK_LEXER_BUFFER_SIZE); + DUK_ASSERT((duk_uint8_t *) lex_ctx->window + count_bytes <= (duk_uint8_t *) lex_ctx->buffer + DUK_LEXER_BUFFER_SIZE * sizeof(duk_lexer_codepoint)); + + /* Zero 'count' is also allowed to make call sites easier. + * Arithmetic in bytes generates better code in GCC. + */ + + lex_ctx->window = (duk_lexer_codepoint *) (void *) ((duk_uint8_t *) lex_ctx->window + count_bytes); /* avoid multiply */ + used_bytes = (duk_small_uint_t) ((duk_uint8_t *) lex_ctx->window - (duk_uint8_t *) lex_ctx->buffer); + avail_bytes = DUK_LEXER_BUFFER_SIZE * sizeof(duk_lexer_codepoint) - used_bytes; + if (avail_bytes < (duk_small_uint_t) (DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint))) { + /* Not enough data to provide a full window, so "scroll" window to + * start of buffer and fill up the rest. + */ + duk_memmove((void *) lex_ctx->buffer, + (const void *) lex_ctx->window, + (size_t) avail_bytes); + lex_ctx->window = lex_ctx->buffer; + duk__fill_lexer_buffer(lex_ctx, avail_bytes); + } +} + +DUK_LOCAL void duk__init_lexer_window(duk_lexer_ctx *lex_ctx) { + lex_ctx->window = lex_ctx->buffer; + duk__fill_lexer_buffer(lex_ctx, 0); +} +#else /* DUK_USE_LEXER_SLIDING_WINDOW */ +DUK_LOCAL duk_codepoint_t duk__read_char(duk_lexer_ctx *lex_ctx) { + duk_ucodepoint_t x; + duk_small_uint_t len; + duk_small_uint_t i; + const duk_uint8_t *p; +#if defined(DUK_USE_STRICT_UTF8_SOURCE) + duk_ucodepoint_t mincp; +#endif + duk_size_t input_offset; + + input_offset = lex_ctx->input_offset; + if (DUK_UNLIKELY(input_offset >= lex_ctx->input_length)) { + /* If input_offset were assigned a negative value, it would + * result in a large positive value. Most likely it would be + * larger than input_length and be caught here. In any case + * no memory unsafe behavior would happen. + */ + return -1; + } + + p = lex_ctx->input + input_offset; + x = (duk_ucodepoint_t) (*p); + + if (DUK_LIKELY(x < 0x80UL)) { + /* 0xxx xxxx -> fast path */ + + /* input offset tracking */ + lex_ctx->input_offset++; + + DUK_ASSERT(x != 0x2028UL && x != 0x2029UL); /* not LS/PS */ + if (DUK_UNLIKELY(x <= 0x000dUL)) { + if ((x == 0x000aUL) || + ((x == 0x000dUL) && (lex_ctx->input_offset >= lex_ctx->input_length || + lex_ctx->input[lex_ctx->input_offset] != 0x000aUL))) { + /* lookup for 0x000a above assumes shortest encoding now */ + + /* E5 Section 7.3, treat the following as newlines: + * LF + * CR [not followed by LF] + * LS + * PS + * + * For CR LF, CR is ignored if it is followed by LF, and the LF will bump + * the line number. + */ + lex_ctx->input_line++; + } + } + + return (duk_codepoint_t) x; + } + + /* Slow path. */ + + if (x < 0xc0UL) { + /* 10xx xxxx -> invalid */ + goto error_encoding; + } else if (x < 0xe0UL) { + /* 110x xxxx 10xx xxxx */ + len = 2; +#if defined(DUK_USE_STRICT_UTF8_SOURCE) + mincp = 0x80UL; +#endif + x = x & 0x1fUL; + } else if (x < 0xf0UL) { + /* 1110 xxxx 10xx xxxx 10xx xxxx */ + len = 3; +#if defined(DUK_USE_STRICT_UTF8_SOURCE) + mincp = 0x800UL; +#endif + x = x & 0x0fUL; + } else if (x < 0xf8UL) { + /* 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx */ + len = 4; +#if defined(DUK_USE_STRICT_UTF8_SOURCE) + mincp = 0x10000UL; +#endif + x = x & 0x07UL; + } else { + /* no point in supporting encodings of 5 or more bytes */ + goto error_encoding; + } + + DUK_ASSERT(lex_ctx->input_length >= lex_ctx->input_offset); + if ((duk_size_t) len > (duk_size_t) (lex_ctx->input_length - lex_ctx->input_offset)) { + goto error_clipped; + } + + p++; + for (i = 1; i < len; i++) { + duk_small_uint_t y; + y = *p++; + if ((y & 0xc0U) != 0x80U) { + /* check that byte has the form 10xx xxxx */ + goto error_encoding; + } + x = x << 6; + x += y & 0x3fUL; + } + + /* check final character validity */ + + if (x > 0x10ffffUL) { + goto error_encoding; + } +#if defined(DUK_USE_STRICT_UTF8_SOURCE) + if (x < mincp || (x >= 0xd800UL && x <= 0xdfffUL) || x == 0xfffeUL) { + goto error_encoding; + } +#endif + + /* input offset tracking */ + lex_ctx->input_offset += len; + + /* line tracking */ + DUK_ASSERT(x != 0x000aUL && x != 0x000dUL); + if ((x == 0x2028UL) || (x == 0x2029UL)) { + lex_ctx->input_line++; + } + + return (duk_codepoint_t) x; + + error_clipped: /* clipped codepoint */ + error_encoding: /* invalid codepoint encoding or codepoint */ + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_SOURCE_DECODE_FAILED); + DUK_WO_NORETURN(return 0;); +} + +DUK_LOCAL void duk__advance_bytes(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_bytes) { + duk_small_uint_t keep_bytes; + duk_lexer_codepoint *cp, *cp_end; + + DUK_ASSERT_DISABLE(count_bytes >= 0); /* unsigned */ + DUK_ASSERT(count_bytes <= (duk_small_uint_t) (DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint))); + + /* Zero 'count' is also allowed to make call sites easier. */ + + keep_bytes = DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint) - count_bytes; + duk_memmove((void *) lex_ctx->window, + (const void *) ((duk_uint8_t *) lex_ctx->window + count_bytes), + (size_t) keep_bytes); + + cp = (duk_lexer_codepoint *) ((duk_uint8_t *) lex_ctx->window + keep_bytes); + cp_end = lex_ctx->window + DUK_LEXER_WINDOW_SIZE; + for (; cp != cp_end; cp++) { + cp->offset = lex_ctx->input_offset; + cp->line = lex_ctx->input_line; + cp->codepoint = duk__read_char(lex_ctx); + } +} + +DUK_LOCAL void duk__init_lexer_window(duk_lexer_ctx *lex_ctx) { + /* Call with count == DUK_LEXER_WINDOW_SIZE to fill buffer initially. */ + duk__advance_bytes(lex_ctx, DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint)); /* fill window */ +} +#endif /* DUK_USE_LEXER_SLIDING_WINDOW */ + +DUK_LOCAL void duk__advance_chars(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_chars) { + duk__advance_bytes(lex_ctx, count_chars * sizeof(duk_lexer_codepoint)); +} + +/* + * (Re)initialize the temporary byte buffer. May be called extra times + * with little impact. + */ + +DUK_LOCAL void duk__initbuffer(duk_lexer_ctx *lex_ctx) { + /* Reuse buffer as is unless buffer has grown large. */ + if (DUK_HBUFFER_DYNAMIC_GET_SIZE(lex_ctx->buf) < DUK_LEXER_TEMP_BUF_LIMIT) { + /* Keep current size */ + } else { + duk_hbuffer_resize(lex_ctx->thr, lex_ctx->buf, DUK_LEXER_TEMP_BUF_LIMIT); + } + + DUK_BW_INIT_WITHBUF(lex_ctx->thr, &lex_ctx->bw, lex_ctx->buf); +} + +/* + * Append a Unicode codepoint to the temporary byte buffer. Performs + * CESU-8 surrogate pair encoding for codepoints above the BMP. + * Existing surrogate pairs are allowed and also encoded into CESU-8. + */ + +DUK_LOCAL void duk__appendbuffer(duk_lexer_ctx *lex_ctx, duk_codepoint_t x) { + /* + * Since character data is only generated by decoding the source or by + * the compiler itself, we rely on the input codepoints being correct + * and avoid a check here. + * + * Character data can also come here through decoding of Unicode + * escapes ("\udead\ubeef") so all 16-but unsigned values can be + * present, even when the source file itself is strict UTF-8. + */ + DUK_ASSERT(x >= 0 && x <= 0x10ffffL); + + DUK_BW_WRITE_ENSURE_CESU8(lex_ctx->thr, &lex_ctx->bw, (duk_ucodepoint_t) x); +} + +DUK_LOCAL void duk__appendbuffer_ascii(duk_lexer_ctx *lex_ctx, duk_codepoint_t x) { + /* ASCII characters can be emitted as a single byte without encoding + * which matters for some fast paths. + */ + DUK_ASSERT(x >= 0 && x <= 0x7f); + + DUK_BW_WRITE_ENSURE_U8(lex_ctx->thr, &lex_ctx->bw, (duk_uint8_t) x); +} + +/* + * Intern the temporary byte buffer into a valstack slot + * (in practice, slot1 or slot2). + */ + +DUK_LOCAL duk_hstring *duk__internbuffer(duk_lexer_ctx *lex_ctx, duk_idx_t valstack_idx) { + DUK_ASSERT(valstack_idx == lex_ctx->slot1_idx || valstack_idx == lex_ctx->slot2_idx); + + DUK_BW_PUSH_AS_STRING(lex_ctx->thr, &lex_ctx->bw); + duk_replace(lex_ctx->thr, valstack_idx); + return duk_known_hstring(lex_ctx->thr, valstack_idx); +} + +/* + * Init lexer context + */ + +DUK_INTERNAL void duk_lexer_initctx(duk_lexer_ctx *lex_ctx) { + DUK_ASSERT(lex_ctx != NULL); + + duk_memzero(lex_ctx, sizeof(*lex_ctx)); +#if defined(DUK_USE_EXPLICIT_NULL_INIT) +#if defined(DUK_USE_LEXER_SLIDING_WINDOW) + lex_ctx->window = NULL; +#endif + lex_ctx->thr = NULL; + lex_ctx->input = NULL; + lex_ctx->buf = NULL; +#endif +} + +/* + * Set lexer input position and reinitialize lookup window. + */ + +DUK_INTERNAL void duk_lexer_getpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt) { + pt->offset = lex_ctx->window[0].offset; + pt->line = lex_ctx->window[0].line; +} + +DUK_INTERNAL void duk_lexer_setpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt) { + DUK_ASSERT_DISABLE(pt->offset >= 0); /* unsigned */ + DUK_ASSERT(pt->line >= 1); + lex_ctx->input_offset = pt->offset; + lex_ctx->input_line = pt->line; + duk__init_lexer_window(lex_ctx); +} + +/* + * Lexing helpers + */ + +/* Numeric value of a hex digit (also covers octal and decimal digits) or + * -1 if not a valid hex digit. + */ +DUK_LOCAL duk_codepoint_t duk__hexval_validate(duk_codepoint_t x) { + duk_small_int_t t; + + /* Here 'x' is a Unicode codepoint */ + if (DUK_LIKELY(x >= 0 && x <= 0xff)) { + t = duk_hex_dectab[x]; + if (DUK_LIKELY(t >= 0)) { + return t; + } + } + + return -1; +} + +/* Just a wrapper for call sites where 'x' is known to be valid so + * we assert for it before decoding. + */ +DUK_LOCAL duk_codepoint_t duk__hexval(duk_codepoint_t x) { + duk_codepoint_t ret; + + DUK_ASSERT((x >= DUK_ASC_0 && x <= DUK_ASC_9) || + (x >= DUK_ASC_LC_A && x <= DUK_ASC_LC_F) || + (x >= DUK_ASC_UC_A && x <= DUK_ASC_UC_F)); + ret = duk__hexval_validate(x); + DUK_ASSERT(ret >= 0 && ret <= 15); + return ret; +} + +/* having this as a separate function provided a size benefit */ +DUK_LOCAL duk_bool_t duk__is_hex_digit(duk_codepoint_t x) { + if (DUK_LIKELY(x >= 0 && x <= 0xff)) { + return (duk_hex_dectab[x] >= 0); + } + return 0; +} + +/* Parse a Unicode escape of the form \xHH, \uHHHH, or \u{H+}. Shared by + * source and RegExp parsing. + */ +DUK_LOCAL duk_codepoint_t duk__lexer_parse_escape(duk_lexer_ctx *lex_ctx, duk_bool_t allow_es6) { + duk_small_int_t digits; /* Initial value 2 or 4 for fixed length escapes, 0 for ES2015 \u{H+}. */ + duk_codepoint_t escval; + duk_codepoint_t x; + duk_small_uint_t adv; + + DUK_ASSERT(DUK__L0() == DUK_ASC_BACKSLASH); /* caller responsibilities */ + DUK_ASSERT(DUK__L1() == DUK_ASC_LC_X || DUK__L1() == DUK_ASC_LC_U); + DUK_UNREF(allow_es6); + + adv = 2; + digits = 2; + if (DUK__L1() == DUK_ASC_LC_U) { + digits = 4; +#if defined(DUK_USE_ES6_UNICODE_ESCAPE) + if (DUK__L2() == DUK_ASC_LCURLY && allow_es6) { + digits = 0; + adv = 3; + } +#endif + } + DUK__ADVANCECHARS(lex_ctx, adv); + + escval = 0; + for (;;) { + /* One of the escape forms: \xHH, \uHHHH, \u{H+}. + * The 'digits' variable tracks parsing state and is + * initialized to: + * + * \xHH 2 + * \uHH 4 + * \u{H+} 0 first time, updated to -1 to indicate + * at least one digit has been parsed + * + * Octal parsing is handled separately because it can be + * done with fixed lookahead and also has validation + * rules which depend on the escape length (which is + * variable). + * + * We don't need a specific check for x < 0 (end of + * input) or duk_unicode_is_line_terminator(x) + * because the 'dig' decode will fail and lead to a + * SyntaxError. + */ + duk_codepoint_t dig; + + x = DUK__L0(); + DUK__ADVANCECHARS(lex_ctx, 1); + + dig = duk__hexval_validate(x); + if (digits > 0) { + digits--; + if (dig < 0) { + goto fail_escape; + } + DUK_ASSERT(dig >= 0x00 && dig <= 0x0f); + escval = (escval << 4) + dig; + if (digits == 0) { + DUK_ASSERT(escval >= 0 && escval <= 0xffffL); + break; + } + } else { +#if defined(DUK_USE_ES6_UNICODE_ESCAPE) + DUK_ASSERT(digits == 0 /* first time */ || digits == -1 /* others */); + if (dig >= 0) { + DUK_ASSERT(dig >= 0x00 && dig <= 0x0f); + escval = (escval << 4) + dig; + if (escval > 0x10ffffL) { + goto fail_escape; + } + } else if (x == DUK_ASC_RCURLY) { + if (digits == 0) { + /* Empty escape, \u{}. */ + goto fail_escape; + } + DUK_ASSERT(escval >= 0 && escval <= 0x10ffffL); + break; + } else { + goto fail_escape; + } + digits = -1; /* Indicate we have at least one digit. */ +#else /* DUK_USE_ES6_UNICODE_ESCAPE */ + DUK_ASSERT(0); /* Never happens if \u{H+} support disabled. */ +#endif /* DUK_USE_ES6_UNICODE_ESCAPE */ + } + } + + return escval; + + fail_escape: + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE); + DUK_WO_NORETURN(return 0;); +} + +/* Parse legacy octal escape of the form \N{1,3}, e.g. \0, \5, \0377. Maximum + * allowed value is \0377 (U+00FF), longest match is used. Used for both string + * RegExp octal escape parsing. Window[0] must be the slash '\' and the first + * digit must already be validated to be in [0-9] by the caller. + */ +DUK_LOCAL duk_codepoint_t duk__lexer_parse_legacy_octal(duk_lexer_ctx *lex_ctx, duk_small_uint_t *out_adv, duk_bool_t reject_annex_b) { + duk_codepoint_t cp; + duk_small_uint_t lookup_idx; + duk_small_uint_t adv; + duk_codepoint_t tmp; + + DUK_ASSERT(out_adv != NULL); + DUK_ASSERT(DUK__LOOKUP(lex_ctx, 0) == DUK_ASC_BACKSLASH); + DUK_ASSERT(DUK__LOOKUP(lex_ctx, 1) >= DUK_ASC_0 && DUK__LOOKUP(lex_ctx, 1) <= DUK_ASC_9); + + cp = 0; + tmp = 0; + for (lookup_idx = 1; lookup_idx <= 3; lookup_idx++) { + DUK_DDD(DUK_DDDPRINT("lookup_idx=%ld, cp=%ld", (long) lookup_idx, (long) cp)); + tmp = DUK__LOOKUP(lex_ctx, lookup_idx); + if (tmp < DUK_ASC_0 || tmp > DUK_ASC_7) { + /* No more valid digits. */ + break; + } + tmp = (cp << 3) + (tmp - DUK_ASC_0); + if (tmp > 0xff) { + /* Three digit octal escapes above \377 (= 0xff) + * are not allowed. + */ + break; + } + cp = tmp; + } + DUK_DDD(DUK_DDDPRINT("final lookup_idx=%ld, cp=%ld", (long) lookup_idx, (long) cp)); + + adv = lookup_idx; + if (lookup_idx == 1) { + DUK_DDD(DUK_DDDPRINT("\\8 or \\9 -> treat as literal, accept in strict mode too")); + DUK_ASSERT(tmp == DUK_ASC_8 || tmp == DUK_ASC_9); + cp = tmp; + adv++; /* correction to above, eat offending character */ + } else if (lookup_idx == 2 && cp == 0) { + /* Note: 'foo\0bar' is OK in strict mode, but 'foo\00bar' is not. + * It won't be interpreted as 'foo\u{0}0bar' but as a SyntaxError. + */ + DUK_DDD(DUK_DDDPRINT("\\0 -> accept in strict mode too")); + } else { + /* This clause also handles non-shortest zero, e.g. \00. */ + if (reject_annex_b) { + DUK_DDD(DUK_DDDPRINT("non-zero octal literal %ld -> reject in strict-mode", (long) cp)); + cp = -1; + } else { + DUK_DDD(DUK_DDDPRINT("non-zero octal literal %ld -> accepted", (long) cp)); + DUK_ASSERT(cp >= 0 && cp <= 0xff); + } + } + + *out_adv = adv; + + DUK_ASSERT((cp >= 0 && cp <= 0xff) || (cp == -1 && reject_annex_b)); + return cp; +} + +/* XXX: move strict mode to lex_ctx? */ +DUK_LOCAL void duk__lexer_parse_string_literal(duk_lexer_ctx *lex_ctx, duk_token *out_token, duk_small_int_t quote, duk_bool_t strict_mode) { + duk_small_uint_t adv; + + for (adv = 1 /* initial quote */ ;;) { + duk_codepoint_t x; + + DUK__ADVANCECHARS(lex_ctx, adv); /* eat opening quote on first loop */ + x = DUK__L0(); + + adv = 1; + if (x == quote) { + DUK__ADVANCECHARS(lex_ctx, 1); /* eat closing quote */ + break; + } else if (x == '\\') { + /* DUK__L0 -> '\' char + * DUK__L1 ... DUK__L5 -> more lookup + */ + duk_small_int_t emitcp = -1; + + x = DUK__L1(); + + /* How much to advance before next loop. */ + adv = 2; /* note: long live range */ + + switch (x) { + case '\'': + emitcp = 0x0027; + break; + case '"': + emitcp = 0x0022; + break; + case '\\': + emitcp = 0x005c; + break; + case 'b': + emitcp = 0x0008; + break; + case 'f': + emitcp = 0x000c; + break; + case 'n': + emitcp = 0x000a; + break; + case 'r': + emitcp = 0x000d; + break; + case 't': + emitcp = 0x0009; + break; + case 'v': + emitcp = 0x000b; + break; + case 'x': + case 'u': { + duk_codepoint_t esc_cp; + esc_cp = duk__lexer_parse_escape(lex_ctx, 1 /*allow_es6*/); + DUK__APPENDBUFFER(lex_ctx, esc_cp); + adv = 0; + break; + } + default: { + if (duk_unicode_is_line_terminator(x)) { + /* line continuation */ + if (x == 0x000d && DUK__L2() == 0x000a) { + /* CR LF again a special case */ + adv = 3; /* line terminator, CR, LF */ + } + } else if (DUK__ISDIGIT(x)) { + /* + * Octal escape or zero escape: + * \0 (lookahead not OctalDigit) + * \1 ... \7 (lookahead not OctalDigit) + * \ZeroToThree OctalDigit (lookahead not OctalDigit) + * \FourToSeven OctalDigit (no lookahead restrictions) + * \ZeroToThree OctalDigit OctalDigit (no lookahead restrictions) + * + * Zero escape is part of the standard syntax. Octal escapes are + * defined in E5 Section B.1.2, and are only allowed in non-strict mode. + * Any other productions starting with a decimal digit are invalid + * but are in practice treated like identity escapes. + * + * Parse octal (up to 3 digits) from the lookup window. + */ + + emitcp = duk__lexer_parse_legacy_octal(lex_ctx, &adv, strict_mode /*reject_annex_b*/); + if (emitcp < 0) { + goto fail_escape; + } + } else if (x < 0) { + goto fail_unterminated; + } else { + /* escaped NonEscapeCharacter */ + DUK__APPENDBUFFER(lex_ctx, x); + } + } /* end default clause */ + } /* end switch */ + + /* Shared handling for single codepoint escapes. */ + if (emitcp >= 0) { + DUK__APPENDBUFFER(lex_ctx, emitcp); + } + + /* Track number of escapes; count not really needed but directive + * prologues need to detect whether there were any escapes or line + * continuations or not. + */ + out_token->num_escapes++; + } else if (x >= 0x20 && x <= 0x7f) { + /* Fast path for ASCII case, avoids line terminator + * check and CESU-8 encoding. + */ + DUK_ASSERT(x >= 0); + DUK_ASSERT(!duk_unicode_is_line_terminator(x)); + DUK_ASSERT(x != quote); + DUK_ASSERT(x != DUK_ASC_BACKSLASH); + DUK__APPENDBUFFER_ASCII(lex_ctx, x); + } else if (x < 0 || duk_unicode_is_line_terminator(x)) { + goto fail_unterminated; + } else { + /* Character which is part of the string but wasn't handled + * by the fast path. + */ + DUK__APPENDBUFFER(lex_ctx, x); + } + } /* string parse loop */ + + return; + + fail_escape: + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE); + DUK_WO_NORETURN(return;); + + fail_unterminated: + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_STRING); + DUK_WO_NORETURN(return;); +} + +/* Skip to end-of-line (or end-of-file), used for single line comments. */ +DUK_LOCAL void duk__lexer_skip_to_endofline(duk_lexer_ctx *lex_ctx) { + for (;;) { + duk_codepoint_t x; + + x = DUK__L0(); + if (x < 0 || duk_unicode_is_line_terminator(x)) { + break; + } + DUK__ADVANCECHARS(lex_ctx, 1); + } +} + +/* + * Parse ECMAScript source InputElementDiv or InputElementRegExp + * (E5 Section 7), skipping whitespace, comments, and line terminators. + * + * Possible results are: + * (1) a token + * (2) a line terminator (skipped) + * (3) a comment (skipped) + * (4) EOF + * + * White space is automatically skipped from the current position (but + * not after the input element). If input has already ended, returns + * DUK_TOK_EOF indefinitely. If a parse error occurs, uses an DUK_ERROR() + * macro call (and hence a longjmp through current heap longjmp context). + * Comments and line terminator tokens are automatically skipped. + * + * The input element being matched is determined by regexp_mode; if set, + * parses a InputElementRegExp, otherwise a InputElementDiv. The + * difference between these are handling of productions starting with a + * forward slash. + * + * If strict_mode is set, recognizes additional future reserved words + * specific to strict mode, and refuses to parse octal literals. + * + * The matching strategy below is to (currently) use a six character + * lookup window to quickly determine which production is the -longest- + * matching one, and then parse that. The top-level if-else clauses + * match the first character, and the code blocks for each clause + * handle -all- alternatives for that first character. ECMAScript + * specification uses the "longest match wins" semantics, so the order + * of the if-clauses matters. + * + * Misc notes: + * + * * ECMAScript numeric literals do not accept a sign character. + * Consequently e.g. "-1.0" is parsed as two tokens: a negative + * sign and a positive numeric literal. The compiler performs + * the negation during compilation, so this has no adverse impact. + * + * * There is no token for "undefined": it is just a value available + * from the global object (or simply established by doing a reference + * to an undefined value). + * + * * Some contexts want Identifier tokens, which are IdentifierNames + * excluding reserved words, while some contexts want IdentifierNames + * directly. In the latter case e.g. "while" is interpreted as an + * identifier name, not a DUK_TOK_WHILE token. The solution here is + * to provide both token types: DUK_TOK_WHILE goes to 't' while + * DUK_TOK_IDENTIFIER goes to 't_nores', and 'slot1' always contains + * the identifier / keyword name. + * + * * Directive prologue needs to identify string literals such as + * "use strict" and 'use strict', which are sensitive to line + * continuations and escape sequences. For instance, "use\u0020strict" + * is a valid directive but is distinct from "use strict". The solution + * here is to decode escapes while tokenizing, but to keep track of the + * number of escapes. Directive detection can then check that the + * number of escapes is zero. + * + * * Multi-line comments with one or more internal LineTerminator are + * treated like a line terminator to comply with automatic semicolon + * insertion. + */ + +DUK_INTERNAL +void duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx, + duk_token *out_token, + duk_bool_t strict_mode, + duk_bool_t regexp_mode) { + duk_codepoint_t x; /* temporary, must be signed and 32-bit to hold Unicode code points */ + duk_small_uint_t advtok = 0; /* (advance << 8) + token_type, updated at function end, + * init is unnecessary but suppresses "may be used uninitialized" warnings. + */ + duk_bool_t got_lineterm = 0; /* got lineterm preceding non-whitespace, non-lineterm token */ + + if (++lex_ctx->token_count >= lex_ctx->token_limit) { + goto fail_token_limit; + } + + out_token->t = DUK_TOK_EOF; + out_token->t_nores = DUK_TOK_INVALID; /* marker: copy t if not changed */ +#if 0 /* not necessary to init, disabled for faster parsing */ + out_token->num = DUK_DOUBLE_NAN; + out_token->str1 = NULL; + out_token->str2 = NULL; +#endif + out_token->num_escapes = 0; + /* out_token->lineterm set by caller */ + + /* This would be nice, but parsing is faster without resetting the + * value slots. The only side effect is that references to temporary + * string values may linger until lexing is finished; they're then + * freed normally. + */ +#if 0 + duk_to_undefined(lex_ctx->thr, lex_ctx->slot1_idx); + duk_to_undefined(lex_ctx->thr, lex_ctx->slot2_idx); +#endif + + /* 'advtok' indicates how much to advance and which token id to assign + * at the end. This shared functionality minimizes code size. All + * code paths are required to set 'advtok' to some value, so no default + * init value is used. Code paths calling DUK_ERROR() never return so + * they don't need to set advtok. + */ + + /* + * Matching order: + * + * Punctuator first chars, also covers comments, regexps + * LineTerminator + * Identifier or reserved word, also covers null/true/false literals + * NumericLiteral + * StringLiteral + * EOF + * + * The order does not matter as long as the longest match is + * always correctly identified. There are order dependencies + * in the clauses, so it's not trivial to convert to a switch. + */ + + restart_lineupdate: + out_token->start_line = lex_ctx->window[0].line; + + restart: + out_token->start_offset = lex_ctx->window[0].offset; + + x = DUK__L0(); + + switch (x) { + case DUK_ASC_SPACE: + case DUK_ASC_HT: /* fast paths for space and tab */ + DUK__ADVANCECHARS(lex_ctx, 1); + goto restart; + case DUK_ASC_LF: /* LF line terminator; CR LF and Unicode lineterms are handled in slow path */ + DUK__ADVANCECHARS(lex_ctx, 1); + got_lineterm = 1; + goto restart_lineupdate; +#if defined(DUK_USE_SHEBANG_COMMENTS) + case DUK_ASC_HASH: /* '#' */ + if (DUK__L1() == DUK_ASC_EXCLAMATION && lex_ctx->window[0].offset == 0 && + (lex_ctx->flags & DUK_COMPILE_SHEBANG)) { + /* "Shebang" comment ('#! ...') on first line. */ + /* DUK__ADVANCECHARS(lex_ctx, 2) would be correct here, but not necessary */ + duk__lexer_skip_to_endofline(lex_ctx); + goto restart; /* line terminator will be handled on next round */ + } + goto fail_token; +#endif /* DUK_USE_SHEBANG_COMMENTS */ + case DUK_ASC_SLASH: /* '/' */ + if (DUK__L1() == DUK_ASC_SLASH) { + /* + * E5 Section 7.4, allow SourceCharacter (which is any 16-bit + * code point). + */ + + /* DUK__ADVANCECHARS(lex_ctx, 2) would be correct here, but not necessary */ + duk__lexer_skip_to_endofline(lex_ctx); + goto restart; /* line terminator will be handled on next round */ + } else if (DUK__L1() == DUK_ASC_STAR) { + /* + * E5 Section 7.4. If the multi-line comment contains a newline, + * it is treated like a single line terminator for automatic + * semicolon insertion. + */ + + duk_bool_t last_asterisk = 0; + DUK__ADVANCECHARS(lex_ctx, 2); + for (;;) { + x = DUK__L0(); + if (x < 0) { + goto fail_unterm_comment; + } + DUK__ADVANCECHARS(lex_ctx, 1); + if (last_asterisk && x == DUK_ASC_SLASH) { + break; + } + if (duk_unicode_is_line_terminator(x)) { + got_lineterm = 1; + } + last_asterisk = (x == DUK_ASC_STAR); + } + goto restart_lineupdate; + } else if (regexp_mode) { +#if defined(DUK_USE_REGEXP_SUPPORT) + /* + * "/" followed by something in regexp mode. See E5 Section 7.8.5. + * + * RegExp parsing is a bit complex. First, the regexp body is delimited + * by forward slashes, but the body may also contain forward slashes as + * part of an escape sequence or inside a character class (delimited by + * square brackets). A mini state machine is used to implement these. + * + * Further, an early (parse time) error must be thrown if the regexp + * would cause a run-time error when used in the expression new RegExp(...). + * Parsing here simply extracts the (candidate) regexp, and also accepts + * invalid regular expressions (which are delimited properly). The caller + * (compiler) must perform final validation and regexp compilation. + * + * RegExp first char may not be '/' (single line comment) or '*' (multi- + * line comment). These have already been checked above, so there is no + * need below for special handling of the first regexp character as in + * the E5 productions. + * + * About unicode escapes within regexp literals: + * + * E5 Section 7.8.5 grammar does NOT accept \uHHHH escapes. + * However, Section 6 states that regexps accept the escapes, + * see paragraph starting with "In string literals...". + * The regexp grammar, which sees the decoded regexp literal + * (after lexical parsing) DOES have a \uHHHH unicode escape. + * So, for instance: + * + * /\u1234/ + * + * should first be parsed by the lexical grammar as: + * + * '\' 'u' RegularExpressionBackslashSequence + * '1' RegularExpressionNonTerminator + * '2' RegularExpressionNonTerminator + * '3' RegularExpressionNonTerminator + * '4' RegularExpressionNonTerminator + * + * and the escape itself is then parsed by the regexp engine. + * This is the current implementation. + * + * Minor spec inconsistency: + * + * E5 Section 7.8.5 RegularExpressionBackslashSequence is: + * + * \ RegularExpressionNonTerminator + * + * while Section A.1 RegularExpressionBackslashSequence is: + * + * \ NonTerminator + * + * The latter is not normative and a typo. + * + */ + + /* first, parse regexp body roughly */ + + duk_small_int_t state = 0; /* 0=base, 1=esc, 2=class, 3=class+esc */ + + DUK__INITBUFFER(lex_ctx); + for (;;) { + DUK__ADVANCECHARS(lex_ctx, 1); /* skip opening slash on first loop */ + x = DUK__L0(); + if (x < 0 || duk_unicode_is_line_terminator(x)) { + goto fail_unterm_regexp; + } + x = DUK__L0(); /* re-read to avoid spill / fetch */ + if (state == 0) { + if (x == DUK_ASC_SLASH) { + DUK__ADVANCECHARS(lex_ctx, 1); /* eat closing slash */ + break; + } else if (x == DUK_ASC_BACKSLASH) { + state = 1; + } else if (x == DUK_ASC_LBRACKET) { + state = 2; + } + } else if (state == 1) { + state = 0; + } else if (state == 2) { + if (x == DUK_ASC_RBRACKET) { + state = 0; + } else if (x == DUK_ASC_BACKSLASH) { + state = 3; + } + } else { /* state == 3 */ + state = 2; + } + DUK__APPENDBUFFER(lex_ctx, x); + } + out_token->str1 = duk__internbuffer(lex_ctx, lex_ctx->slot1_idx); + + /* second, parse flags */ + + DUK__INITBUFFER(lex_ctx); + for (;;) { + x = DUK__L0(); + if (!duk_unicode_is_identifier_part(x)) { + break; + } + x = DUK__L0(); /* re-read to avoid spill / fetch */ + DUK__APPENDBUFFER(lex_ctx, x); + DUK__ADVANCECHARS(lex_ctx, 1); + } + out_token->str2 = duk__internbuffer(lex_ctx, lex_ctx->slot2_idx); + + DUK__INITBUFFER(lex_ctx); /* free some memory */ + + /* validation of the regexp is caller's responsibility */ + + advtok = DUK__ADVTOK(0, DUK_TOK_REGEXP); +#else /* DUK_USE_REGEXP_SUPPORT */ + goto fail_regexp_support; +#endif /* DUK_USE_REGEXP_SUPPORT */ + } else if (DUK__L1() == DUK_ASC_EQUALS) { + /* "/=" and not in regexp mode */ + advtok = DUK__ADVTOK(2, DUK_TOK_DIV_EQ); + } else { + /* "/" and not in regexp mode */ + advtok = DUK__ADVTOK(1, DUK_TOK_DIV); + } + break; + case DUK_ASC_LCURLY: /* '{' */ + advtok = DUK__ADVTOK(1, DUK_TOK_LCURLY); + break; + case DUK_ASC_RCURLY: /* '}' */ + advtok = DUK__ADVTOK(1, DUK_TOK_RCURLY); + break; + case DUK_ASC_LPAREN: /* '(' */ + advtok = DUK__ADVTOK(1, DUK_TOK_LPAREN); + break; + case DUK_ASC_RPAREN: /* ')' */ + advtok = DUK__ADVTOK(1, DUK_TOK_RPAREN); + break; + case DUK_ASC_LBRACKET: /* '[' */ + advtok = DUK__ADVTOK(1, DUK_TOK_LBRACKET); + break; + case DUK_ASC_RBRACKET: /* ']' */ + advtok = DUK__ADVTOK(1, DUK_TOK_RBRACKET); + break; + case DUK_ASC_PERIOD: /* '.' */ + if (DUK__ISDIGIT(DUK__L1())) { + /* Period followed by a digit can only start DecimalLiteral + * (handled in slow path). We could jump straight into the + * DecimalLiteral handling but should avoid goto to inside + * a block. + */ + goto slow_path; + } + advtok = DUK__ADVTOK(1, DUK_TOK_PERIOD); + break; + case DUK_ASC_SEMICOLON: /* ';' */ + advtok = DUK__ADVTOK(1, DUK_TOK_SEMICOLON); + break; + case DUK_ASC_COMMA: /* ',' */ + advtok = DUK__ADVTOK(1, DUK_TOK_COMMA); + break; + case DUK_ASC_LANGLE: /* '<' */ +#if defined(DUK_USE_HTML_COMMENTS) + if (DUK__L1() == DUK_ASC_EXCLAMATION && DUK__L2() == DUK_ASC_MINUS && DUK__L3() == DUK_ASC_MINUS) { + /* + * ES2015: B.1.3, handle "" SingleLineHTMLCloseComment + * Only allowed: + * - on new line + * - preceded only by whitespace + * - preceded by end of multiline comment and optional whitespace + * + * Since whitespace generates no tokens, and multiline comments + * are treated as a line ending, consulting `got_lineterm` is + * sufficient to test for these three options. + */ + + /* DUK__ADVANCECHARS(lex_ctx, 3) would be correct here, but not necessary */ + duk__lexer_skip_to_endofline(lex_ctx); + goto restart; /* line terminator will be handled on next round */ + } else +#endif /* DUK_USE_HTML_COMMENTS */ + if (DUK__L1() == DUK_ASC_MINUS) { + advtok = DUK__ADVTOK(2, DUK_TOK_DECREMENT); + } else if (DUK__L1() == DUK_ASC_EQUALS) { + advtok = DUK__ADVTOK(2, DUK_TOK_SUB_EQ); + } else { + advtok = DUK__ADVTOK(1, DUK_TOK_SUB); + } + break; + case DUK_ASC_STAR: /* '*' */ +#if defined(DUK_USE_ES7_EXP_OPERATOR) + if (DUK__L1() == DUK_ASC_STAR && DUK__L2() == DUK_ASC_EQUALS) { + advtok = DUK__ADVTOK(3, DUK_TOK_EXP_EQ); + } else if (DUK__L1() == DUK_ASC_STAR) { + advtok = DUK__ADVTOK(2, DUK_TOK_EXP); + } else +#endif + if (DUK__L1() == DUK_ASC_EQUALS) { + advtok = DUK__ADVTOK(2, DUK_TOK_MUL_EQ); + } else { + advtok = DUK__ADVTOK(1, DUK_TOK_MUL); + } + break; + case DUK_ASC_PERCENT: /* '%' */ + if (DUK__L1() == DUK_ASC_EQUALS) { + advtok = DUK__ADVTOK(2, DUK_TOK_MOD_EQ); + } else { + advtok = DUK__ADVTOK(1, DUK_TOK_MOD); + } + break; + case DUK_ASC_AMP: /* '&' */ + if (DUK__L1() == DUK_ASC_AMP) { + advtok = DUK__ADVTOK(2, DUK_TOK_LAND); + } else if (DUK__L1() == DUK_ASC_EQUALS) { + advtok = DUK__ADVTOK(2, DUK_TOK_BAND_EQ); + } else { + advtok = DUK__ADVTOK(1, DUK_TOK_BAND); + } + break; + case DUK_ASC_PIPE: /* '|' */ + if (DUK__L1() == DUK_ASC_PIPE) { + advtok = DUK__ADVTOK(2, DUK_TOK_LOR); + } else if (DUK__L1() == DUK_ASC_EQUALS) { + advtok = DUK__ADVTOK(2, DUK_TOK_BOR_EQ); + } else { + advtok = DUK__ADVTOK(1, DUK_TOK_BOR); + } + break; + case DUK_ASC_CARET: /* '^' */ + if (DUK__L1() == DUK_ASC_EQUALS) { + advtok = DUK__ADVTOK(2, DUK_TOK_BXOR_EQ); + } else { + advtok = DUK__ADVTOK(1, DUK_TOK_BXOR); + } + break; + case DUK_ASC_TILDE: /* '~' */ + advtok = DUK__ADVTOK(1, DUK_TOK_BNOT); + break; + case DUK_ASC_QUESTION: /* '?' */ + advtok = DUK__ADVTOK(1, DUK_TOK_QUESTION); + break; + case DUK_ASC_COLON: /* ':' */ + advtok = DUK__ADVTOK(1, DUK_TOK_COLON); + break; + case DUK_ASC_DOUBLEQUOTE: /* '"' */ + case DUK_ASC_SINGLEQUOTE: { /* '\'' */ + DUK__INITBUFFER(lex_ctx); + duk__lexer_parse_string_literal(lex_ctx, out_token, x /*quote*/, strict_mode); + duk__internbuffer(lex_ctx, lex_ctx->slot1_idx); + out_token->str1 = duk_known_hstring(lex_ctx->thr, lex_ctx->slot1_idx); + + DUK__INITBUFFER(lex_ctx); /* free some memory */ + + advtok = DUK__ADVTOK(0, DUK_TOK_STRING); + break; + } + default: + goto slow_path; + } /* switch */ + + goto skip_slow_path; + + slow_path: + if (duk_unicode_is_line_terminator(x)) { + if (x == 0x000d && DUK__L1() == 0x000a) { + /* + * E5 Section 7.3: CR LF is detected as a single line terminator for + * line numbers. Here we also detect it as a single line terminator + * token. + */ + DUK__ADVANCECHARS(lex_ctx, 2); + } else { + DUK__ADVANCECHARS(lex_ctx, 1); + } + got_lineterm = 1; + goto restart_lineupdate; + } else if (duk_unicode_is_identifier_start(x) || x == DUK_ASC_BACKSLASH) { + /* + * Parse an identifier and then check whether it is: + * - reserved word (keyword or other reserved word) + * - "null" (NullLiteral) + * - "true" (BooleanLiteral) + * - "false" (BooleanLiteral) + * - anything else => identifier + * + * This does not follow the E5 productions cleanly, but is + * useful and compact. + * + * Note that identifiers may contain Unicode escapes, + * see E5 Sections 6 and 7.6. They must be decoded first, + * and the result checked against allowed characters. + * The above if-clause accepts an identifier start and an + * '\' character -- no other token can begin with a '\'. + * + * Note that "get" and "set" are not reserved words in E5 + * specification so they are recognized as plain identifiers + * (the tokens DUK_TOK_GET and DUK_TOK_SET are actually not + * used now). The compiler needs to work around this. + * + * Strictly speaking, following ECMAScript longest match + * specification, an invalid escape for the first character + * should cause a syntax error. However, an invalid escape + * for IdentifierParts should just terminate the identifier + * early (longest match), and let the next tokenization + * fail. For instance Rhino croaks with 'foo\z' when + * parsing the identifier. This has little practical impact. + */ + + duk_small_uint_t i, i_end; + duk_bool_t first = 1; + duk_hstring *str; + + DUK__INITBUFFER(lex_ctx); + for (;;) { + /* re-lookup first char on first loop */ + if (DUK__L0() == DUK_ASC_BACKSLASH) { + duk_codepoint_t esc_cp; + if (DUK__L1() != DUK_ASC_LC_U) { + goto fail_escape; + } + esc_cp = duk__lexer_parse_escape(lex_ctx, 1 /*allow_es6*/); + DUK__APPENDBUFFER(lex_ctx, esc_cp); + + /* IdentifierStart is stricter than IdentifierPart, so if the first + * character is escaped, must have a stricter check here. + */ + if (!(first ? duk_unicode_is_identifier_start(esc_cp) : duk_unicode_is_identifier_part(esc_cp))) { + goto fail_escape; + } + + /* Track number of escapes: necessary for proper keyword + * detection. + */ + out_token->num_escapes++; + } else { + /* Note: first character is checked against this. But because + * IdentifierPart includes all IdentifierStart characters, and + * the first character (if unescaped) has already been checked + * in the if condition, this is OK. + */ + if (!duk_unicode_is_identifier_part(DUK__L0())) { + break; + } + DUK__APPENDBUFFER(lex_ctx, DUK__L0()); + DUK__ADVANCECHARS(lex_ctx, 1); + } + first = 0; + } + + out_token->str1 = duk__internbuffer(lex_ctx, lex_ctx->slot1_idx); + str = out_token->str1; + out_token->t_nores = DUK_TOK_IDENTIFIER; + + DUK__INITBUFFER(lex_ctx); /* free some memory */ + + /* + * Interned identifier is compared against reserved words, which are + * currently interned into the heap context. See genbuiltins.py. + * + * Note that an escape in the identifier disables recognition of + * keywords; e.g. "\u0069f = 1;" is a valid statement (assigns to + * identifier named "if"). This is not necessarily compliant, + * see test-dec-escaped-char-in-keyword.js. + * + * Note: "get" and "set" are awkward. They are not officially + * ReservedWords (and indeed e.g. "var set = 1;" is valid), and + * must come out as DUK_TOK_IDENTIFIER. The compiler needs to + * work around this a bit. + */ + + /* XXX: optimize by adding the token numbers directly into the + * always interned duk_hstring objects (there should be enough + * flag bits free for that)? + */ + + i_end = (strict_mode ? DUK_STRIDX_END_RESERVED : DUK_STRIDX_START_STRICT_RESERVED); + + advtok = DUK__ADVTOK(0, DUK_TOK_IDENTIFIER); + if (out_token->num_escapes == 0) { + for (i = DUK_STRIDX_START_RESERVED; i < i_end; i++) { + DUK_ASSERT_DISABLE(i >= 0); /* unsigned */ + DUK_ASSERT(i < DUK_HEAP_NUM_STRINGS); + if (DUK_HTHREAD_GET_STRING(lex_ctx->thr, i) == str) { + advtok = DUK__ADVTOK(0, DUK_STRIDX_TO_TOK(i)); + break; + } + } + } + } else if (DUK__ISDIGIT(x) || (x == DUK_ASC_PERIOD)) { + /* Note: decimal number may start with a period, but must be followed by a digit */ + + /* + * Pre-parsing for decimal, hex, octal (both legacy and ES2015), + * and binary literals, followed by an actual parser step + * provided by numconv. + * + * Note: the leading sign character ('+' or '-') is -not- part of + * the production in E5 grammar, and that the a DecimalLiteral + * starting with a '0' must be followed by a non-digit. + * + * XXX: the two step parsing process is quite awkward, it would + * be more straightforward to allow numconv to parse the longest + * valid prefix (it already does that, it only needs to indicate + * where the input ended). However, the lexer decodes characters + * using a limited lookup window, so this is not a trivial change. + */ + + /* XXX: because of the final check below (that the literal is not + * followed by a digit), this could maybe be simplified, if we bail + * out early from a leading zero (and if there are no periods etc). + * Maybe too complex. + */ + + duk_double_t val; + duk_bool_t legacy_oct = 0; + duk_small_int_t state; /* 0=before period/exp, + * 1=after period, before exp + * 2=after exp, allow '+' or '-' + * 3=after exp and exp sign + */ + duk_small_uint_t s2n_flags; + duk_codepoint_t y, z; + duk_small_int_t s2n_radix = 10; + duk_small_uint_t pre_adv = 0; + + DUK__INITBUFFER(lex_ctx); + y = DUK__L1(); + + if (x == DUK_ASC_0) { + z = DUK_LOWERCASE_CHAR_ASCII(y); + + pre_adv = 2; /* default for 0xNNN, 0oNNN, 0bNNN. */ + if (z == DUK_ASC_LC_X) { + s2n_radix = 16; + } else if (z == DUK_ASC_LC_O) { + s2n_radix = 8; + } else if (z == DUK_ASC_LC_B) { + s2n_radix = 2; + } else { + pre_adv = 0; + if (DUK__ISDIGIT(y)) { + if (strict_mode) { + /* Reject octal like \07 but also octal-lookalike + * decimal like \08 in strict mode. + */ + goto fail_number_literal; + } else { + /* Legacy OctalIntegerLiteral or octal-lookalice + * decimal. Deciding between the two happens below + * in digit scanning. + */ + DUK__APPENDBUFFER(lex_ctx, x); + pre_adv = 1; + legacy_oct = 1; + s2n_radix = 8; /* tentative unless conflicting digits found */ + } + } + } + } + + DUK__ADVANCECHARS(lex_ctx, pre_adv); + + /* XXX: we could parse integers here directly, and fall back + * to numconv only when encountering a fractional expression + * or when an octal literal turned out to be decimal (0778 etc). + */ + state = 0; + for (;;) { + x = DUK__L0(); /* re-lookup curr char on first round */ + if (DUK__ISDIGIT(x)) { + /* Note: intentionally allow leading zeroes here, as the + * actual parser will check for them. + */ + if (state == 0 && legacy_oct && (x == DUK_ASC_8 || x == DUK_ASC_9)) { + /* Started out as an octal-lookalike + * but interpreted as decimal, e.g. + * '0779' -> 779. This also means + * that fractions are allowed, e.g. + * '0779.123' is allowed but '0777.123' + * is not! + */ + s2n_radix = 10; + } + if (state == 2) { + state = 3; + } + } else if (s2n_radix == 16 && DUK__ISHEXDIGIT(x)) { + /* Note: 'e' and 'E' are also accepted here. */ + ; + } else if (x == DUK_ASC_PERIOD) { + if (state >= 1 || s2n_radix != 10) { + break; + } else { + state = 1; + } + } else if (x == DUK_ASC_LC_E || x == DUK_ASC_UC_E) { + if (state >= 2 || s2n_radix != 10) { + break; + } else { + state = 2; + } + } else if (x == DUK_ASC_MINUS || x == DUK_ASC_PLUS) { + if (state != 2) { + break; + } else { + state = 3; + } + } else { + break; + } + DUK__APPENDBUFFER(lex_ctx, x); + DUK__ADVANCECHARS(lex_ctx, 1); + } + + /* XXX: better coercion */ + (void) duk__internbuffer(lex_ctx, lex_ctx->slot1_idx); + + if (s2n_radix != 10) { + /* For bases other than 10, integer only. */ + s2n_flags = DUK_S2N_FLAG_ALLOW_LEADING_ZERO; + } else { + s2n_flags = DUK_S2N_FLAG_ALLOW_EXP | + DUK_S2N_FLAG_ALLOW_FRAC | + DUK_S2N_FLAG_ALLOW_NAKED_FRAC | + DUK_S2N_FLAG_ALLOW_EMPTY_FRAC | + DUK_S2N_FLAG_ALLOW_LEADING_ZERO; + } + + duk_dup(lex_ctx->thr, lex_ctx->slot1_idx); + duk_numconv_parse(lex_ctx->thr, s2n_radix, s2n_flags); + val = duk_to_number_m1(lex_ctx->thr); + if (DUK_ISNAN(val)) { + goto fail_number_literal; + } + duk_replace(lex_ctx->thr, lex_ctx->slot1_idx); /* could also just pop? */ + + DUK__INITBUFFER(lex_ctx); /* free some memory */ + + /* Section 7.8.3 (note): NumericLiteral must be followed by something other than + * IdentifierStart or DecimalDigit. + */ + + if (DUK__ISDIGIT(DUK__L0()) || duk_unicode_is_identifier_start(DUK__L0())) { + goto fail_number_literal; + } + + out_token->num = val; + advtok = DUK__ADVTOK(0, DUK_TOK_NUMBER); + } else if (duk_unicode_is_whitespace(DUK__LOOKUP(lex_ctx, 0))) { + DUK__ADVANCECHARS(lex_ctx, 1); + goto restart; + } else if (x < 0) { + advtok = DUK__ADVTOK(0, DUK_TOK_EOF); + } else { + goto fail_token; + } + skip_slow_path: + + /* + * Shared exit path + */ + + DUK__ADVANCEBYTES(lex_ctx, advtok >> 8); + out_token->t = advtok & 0xff; + if (out_token->t_nores == DUK_TOK_INVALID) { + out_token->t_nores = out_token->t; + } + out_token->lineterm = got_lineterm; + + /* Automatic semicolon insertion is allowed if a token is preceded + * by line terminator(s), or terminates a statement list (right curly + * or EOF). + */ + if (got_lineterm || out_token->t == DUK_TOK_RCURLY || out_token->t == DUK_TOK_EOF) { + out_token->allow_auto_semi = 1; + } else { + out_token->allow_auto_semi = 0; + } + + return; + + fail_token_limit: + DUK_ERROR_RANGE(lex_ctx->thr, DUK_STR_TOKEN_LIMIT); + DUK_WO_NORETURN(return;); + + fail_token: + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_TOKEN); + DUK_WO_NORETURN(return;); + + fail_number_literal: + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_NUMBER_LITERAL); + DUK_WO_NORETURN(return;); + + fail_escape: + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE); + DUK_WO_NORETURN(return;); + + fail_unterm_regexp: + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_REGEXP); + DUK_WO_NORETURN(return;); + + fail_unterm_comment: + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_COMMENT); + DUK_WO_NORETURN(return;); + +#if !defined(DUK_USE_REGEXP_SUPPORT) + fail_regexp_support: + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_REGEXP_SUPPORT_DISABLED); + DUK_WO_NORETURN(return;); +#endif +} + +#if defined(DUK_USE_REGEXP_SUPPORT) + +/* + * Parse a RegExp token. The grammar is described in E5 Section 15.10. + * Terminal constructions (such as quantifiers) are parsed directly here. + * + * 0xffffffffU is used as a marker for "infinity" in quantifiers. Further, + * DUK__MAX_RE_QUANT_DIGITS limits the maximum number of digits that + * will be accepted for a quantifier. + */ + +DUK_INTERNAL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token *out_token) { + duk_small_uint_t advtok = 0; /* init is unnecessary but suppresses "may be used uninitialized" warnings */ + duk_codepoint_t x, y; + + if (++lex_ctx->token_count >= lex_ctx->token_limit) { + goto fail_token_limit; + } + + duk_memzero(out_token, sizeof(*out_token)); + + x = DUK__L0(); + y = DUK__L1(); + + DUK_DDD(DUK_DDDPRINT("parsing regexp token, L0=%ld, L1=%ld", (long) x, (long) y)); + + switch (x) { + case DUK_ASC_PIPE: { + advtok = DUK__ADVTOK(1, DUK_RETOK_DISJUNCTION); + break; + } + case DUK_ASC_CARET: { + advtok = DUK__ADVTOK(1, DUK_RETOK_ASSERT_START); + break; + } + case DUK_ASC_DOLLAR: { + advtok = DUK__ADVTOK(1, DUK_RETOK_ASSERT_END); + break; + } + case DUK_ASC_QUESTION: { + out_token->qmin = 0; + out_token->qmax = 1; + if (y == DUK_ASC_QUESTION) { + advtok = DUK__ADVTOK(2, DUK_RETOK_QUANTIFIER); + out_token->greedy = 0; + } else { + advtok = DUK__ADVTOK(1, DUK_RETOK_QUANTIFIER); + out_token->greedy = 1; + } + break; + } + case DUK_ASC_STAR: { + out_token->qmin = 0; + out_token->qmax = DUK_RE_QUANTIFIER_INFINITE; + if (y == DUK_ASC_QUESTION) { + advtok = DUK__ADVTOK(2, DUK_RETOK_QUANTIFIER); + out_token->greedy = 0; + } else { + advtok = DUK__ADVTOK(1, DUK_RETOK_QUANTIFIER); + out_token->greedy = 1; + } + break; + } + case DUK_ASC_PLUS: { + out_token->qmin = 1; + out_token->qmax = DUK_RE_QUANTIFIER_INFINITE; + if (y == DUK_ASC_QUESTION) { + advtok = DUK__ADVTOK(2, DUK_RETOK_QUANTIFIER); + out_token->greedy = 0; + } else { + advtok = DUK__ADVTOK(1, DUK_RETOK_QUANTIFIER); + out_token->greedy = 1; + } + break; + } + case DUK_ASC_LCURLY: { + /* Production allows 'DecimalDigits', including leading zeroes */ + duk_uint32_t val1 = 0; + duk_uint32_t val2 = DUK_RE_QUANTIFIER_INFINITE; + duk_small_int_t digits = 0; +#if defined(DUK_USE_ES6_REGEXP_SYNTAX) + duk_lexer_point lex_pt; +#endif + +#if defined(DUK_USE_ES6_REGEXP_SYNTAX) + /* Store lexer position, restoring if quantifier is invalid. */ + DUK_LEXER_GETPOINT(lex_ctx, &lex_pt); +#endif + + for (;;) { + DUK__ADVANCECHARS(lex_ctx, 1); /* eat '{' on entry */ + x = DUK__L0(); + if (DUK__ISDIGIT(x)) { + digits++; + val1 = val1 * 10 + (duk_uint32_t) duk__hexval(x); + } else if (x == DUK_ASC_COMMA) { + if (digits > DUK__MAX_RE_QUANT_DIGITS) { + goto invalid_quantifier; + } + if (val2 != DUK_RE_QUANTIFIER_INFINITE) { + goto invalid_quantifier; + } + if (DUK__L1() == DUK_ASC_RCURLY) { + /* form: { DecimalDigits , }, val1 = min count */ + if (digits == 0) { + goto invalid_quantifier; + } + out_token->qmin = val1; + out_token->qmax = DUK_RE_QUANTIFIER_INFINITE; + DUK__ADVANCECHARS(lex_ctx, 2); + break; + } + val2 = val1; + val1 = 0; + digits = 0; /* not strictly necessary because of lookahead '}' above */ + } else if (x == DUK_ASC_RCURLY) { + if (digits > DUK__MAX_RE_QUANT_DIGITS) { + goto invalid_quantifier; + } + if (digits == 0) { + goto invalid_quantifier; + } + if (val2 != DUK_RE_QUANTIFIER_INFINITE) { + /* val2 = min count, val1 = max count */ + out_token->qmin = val2; + out_token->qmax = val1; + } else { + /* val1 = count */ + out_token->qmin = val1; + out_token->qmax = val1; + } + DUK__ADVANCECHARS(lex_ctx, 1); + break; + } else { + goto invalid_quantifier; + } + } + if (DUK__L0() == DUK_ASC_QUESTION) { + out_token->greedy = 0; + DUK__ADVANCECHARS(lex_ctx, 1); + } else { + out_token->greedy = 1; + } + advtok = DUK__ADVTOK(0, DUK_RETOK_QUANTIFIER); + break; + invalid_quantifier: +#if defined(DUK_USE_ES6_REGEXP_SYNTAX) + /* Failed to match the quantifier, restore lexer and parse + * opening brace as a literal. + */ + DUK_LEXER_SETPOINT(lex_ctx, &lex_pt); + advtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_CHAR); + out_token->num = DUK_ASC_LCURLY; +#else + goto fail_quantifier; +#endif + break; + } + case DUK_ASC_PERIOD: { + advtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_PERIOD); + break; + } + case DUK_ASC_BACKSLASH: { + /* The E5.1 specification does not seem to allow IdentifierPart characters + * to be used as identity escapes. Unfortunately this includes '$', which + * cannot be escaped as '\$'; it needs to be escaped e.g. as '\u0024'. + * Many other implementations (including V8 and Rhino, for instance) do + * accept '\$' as a valid identity escape, which is quite pragmatic, and + * ES2015 Annex B relaxes the rules to allow these (and other) real world forms. + */ + + advtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_CHAR); /* default: char escape (two chars) */ + if (y == DUK_ASC_LC_B) { + advtok = DUK__ADVTOK(2, DUK_RETOK_ASSERT_WORD_BOUNDARY); + } else if (y == DUK_ASC_UC_B) { + advtok = DUK__ADVTOK(2, DUK_RETOK_ASSERT_NOT_WORD_BOUNDARY); + } else if (y == DUK_ASC_LC_F) { + out_token->num = 0x000c; + } else if (y == DUK_ASC_LC_N) { + out_token->num = 0x000a; + } else if (y == DUK_ASC_LC_T) { + out_token->num = 0x0009; + } else if (y == DUK_ASC_LC_R) { + out_token->num = 0x000d; + } else if (y == DUK_ASC_LC_V) { + out_token->num = 0x000b; + } else if (y == DUK_ASC_LC_C) { + x = DUK__L2(); + if ((x >= DUK_ASC_LC_A && x <= DUK_ASC_LC_Z) || + (x >= DUK_ASC_UC_A && x <= DUK_ASC_UC_Z)) { + out_token->num = (duk_uint32_t) (x % 32); + advtok = DUK__ADVTOK(3, DUK_RETOK_ATOM_CHAR); + } else { + goto fail_escape; + } + } else if (y == DUK_ASC_LC_X || y == DUK_ASC_LC_U) { + /* The token value is the Unicode codepoint without + * it being decode into surrogate pair characters + * here. The \u{H+} is only allowed in Unicode mode + * which we don't support yet. + */ + out_token->num = (duk_uint32_t) duk__lexer_parse_escape(lex_ctx, 0 /*allow_es6*/); + advtok = DUK__ADVTOK(0, DUK_RETOK_ATOM_CHAR); + } else if (y == DUK_ASC_LC_D) { + advtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_DIGIT); + } else if (y == DUK_ASC_UC_D) { + advtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_NOT_DIGIT); + } else if (y == DUK_ASC_LC_S) { + advtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_WHITE); + } else if (y == DUK_ASC_UC_S) { + advtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_NOT_WHITE); + } else if (y == DUK_ASC_LC_W) { + advtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_WORD_CHAR); + } else if (y == DUK_ASC_UC_W) { + advtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_NOT_WORD_CHAR); + } else if (DUK__ISDIGIT(y)) { + /* E5 Section 15.10.2.11 */ + if (y == DUK_ASC_0) { + if (DUK__ISDIGIT(DUK__L2())) { + goto fail_escape; + } + out_token->num = 0x0000; + advtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_CHAR); + } else { + /* XXX: shared parsing? */ + duk_uint32_t val = 0; + duk_small_int_t i; + for (i = 0; ; i++) { + if (i >= DUK__MAX_RE_DECESC_DIGITS) { + goto fail_escape; + } + DUK__ADVANCECHARS(lex_ctx, 1); /* eat backslash on entry */ + x = DUK__L0(); + if (!DUK__ISDIGIT(x)) { + break; + } + val = val * 10 + (duk_uint32_t) duk__hexval(x); + } + /* DUK__L0() cannot be a digit, because the loop doesn't terminate if it is */ + advtok = DUK__ADVTOK(0, DUK_RETOK_ATOM_BACKREFERENCE); + out_token->num = val; + } +#if defined(DUK_USE_ES6_REGEXP_SYNTAX) + } else if (y >= 0) { + /* For ES2015 Annex B, accept any source character as identity + * escape except 'c' which is used for control characters. + * http://www.ecma-international.org/ecma-262/6.0/#sec-regular-expressions-patterns + * Careful not to match end-of-buffer (<0) here. + * This is not yet full ES2015 Annex B because cases above + * (like hex escape) won't backtrack. + */ + DUK_ASSERT(y != DUK_ASC_LC_C); /* covered above */ +#else /* DUK_USE_ES6_REGEXP_SYNTAX */ + } else if ((y >= 0 && !duk_unicode_is_identifier_part(y)) || + y == DUK_UNICODE_CP_ZWNJ || + y == DUK_UNICODE_CP_ZWJ) { + /* For ES5.1 identity escapes are not allowed for identifier + * parts. This conflicts with a lot of real world code as this + * doesn't e.g. allow escaping a dollar sign as /\$/, see + * test-regexp-identity-escape-dollar.js. + */ +#endif /* DUK_USE_ES6_REGEXP_SYNTAX */ + out_token->num = (duk_uint32_t) y; + } else { + goto fail_escape; + } + break; + } + case DUK_ASC_LPAREN: { + /* XXX: naming is inconsistent: ATOM_END_GROUP ends an ASSERT_START_LOOKAHEAD */ + + if (y == DUK_ASC_QUESTION) { + if (DUK__L2() == DUK_ASC_EQUALS) { + /* (?= */ + advtok = DUK__ADVTOK(3, DUK_RETOK_ASSERT_START_POS_LOOKAHEAD); + } else if (DUK__L2() == DUK_ASC_EXCLAMATION) { + /* (?! */ + advtok = DUK__ADVTOK(3, DUK_RETOK_ASSERT_START_NEG_LOOKAHEAD); + } else if (DUK__L2() == DUK_ASC_COLON) { + /* (?: */ + advtok = DUK__ADVTOK(3, DUK_RETOK_ATOM_START_NONCAPTURE_GROUP); + } else { + goto fail_group; + } + } else { + /* ( */ + advtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_START_CAPTURE_GROUP); + } + break; + } + case DUK_ASC_RPAREN: { + advtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_END_GROUP); + break; + } + case DUK_ASC_LBRACKET: { + /* + * To avoid creating a heavy intermediate value for the list of ranges, + * only the start token ('[' or '[^') is parsed here. The regexp + * compiler parses the ranges itself. + */ + + /* XXX: with DUK_USE_ES6_REGEXP_SYNTAX we should allow left bracket + * literal too, but it's not easy to parse without backtracking. + */ + + advtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_START_CHARCLASS); + if (y == DUK_ASC_CARET) { + advtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_START_CHARCLASS_INVERTED); + } + break; + } +#if !defined(DUK_USE_ES6_REGEXP_SYNTAX) + case DUK_ASC_RCURLY: + case DUK_ASC_RBRACKET: { + /* Although these could be parsed as PatternCharacters unambiguously (here), + * E5 Section 15.10.1 grammar explicitly forbids these as PatternCharacters. + */ + goto fail_invalid_char; + break; + } +#endif + case -1: { + /* EOF */ + advtok = DUK__ADVTOK(0, DUK_TOK_EOF); + break; + } + default: { + /* PatternCharacter, all excluded characters are matched by cases above */ + advtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_CHAR); + out_token->num = (duk_uint32_t) x; + break; + } + } + + /* + * Shared exit path + */ + + DUK__ADVANCEBYTES(lex_ctx, advtok >> 8); + out_token->t = advtok & 0xff; + return; + + fail_token_limit: + DUK_ERROR_RANGE(lex_ctx->thr, DUK_STR_TOKEN_LIMIT); + DUK_WO_NORETURN(return;); + + fail_escape: + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_ESCAPE); + DUK_WO_NORETURN(return;); + + fail_group: + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_GROUP); + DUK_WO_NORETURN(return;); + +#if !defined(DUK_USE_ES6_REGEXP_SYNTAX) + fail_invalid_char: + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_CHARACTER); + DUK_WO_NORETURN(return;); + + fail_quantifier: + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_QUANTIFIER); + DUK_WO_NORETURN(return;); +#endif +} + +/* + * Special parser for character classes; calls callback for every + * range parsed and returns the number of ranges present. + */ + +/* XXX: this duplicates functionality in duk_regexp.c where a similar loop is + * required anyway. We could use that BUT we need to update the regexp compiler + * 'nranges' too. Work this out a bit more cleanly to save space. + */ + +/* XXX: the handling of character range detection is a bit convoluted. + * Try to simplify and make smaller. + */ + +/* XXX: logic for handling character ranges is now incorrect, it will accept + * e.g. [\d-z] whereas it should croak from it? SMJS accepts this too, though. + * + * Needs a read through and a lot of additional tests. + */ + +DUK_LOCAL +void duk__emit_u16_direct_ranges(duk_lexer_ctx *lex_ctx, + duk_re_range_callback gen_range, + void *userdata, + const duk_uint16_t *ranges, + duk_small_int_t num) { + const duk_uint16_t *ranges_end; + + DUK_UNREF(lex_ctx); + + ranges_end = ranges + num; + while (ranges < ranges_end) { + /* mark range 'direct', bypass canonicalization (see Wiki) */ + gen_range(userdata, (duk_codepoint_t) ranges[0], (duk_codepoint_t) ranges[1], 1); + ranges += 2; + } +} + +DUK_INTERNAL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_range_callback gen_range, void *userdata) { + duk_codepoint_t start = -1; + duk_codepoint_t ch; + duk_codepoint_t x; + duk_bool_t dash = 0; + duk_small_uint_t adv = 0; + + DUK_DD(DUK_DDPRINT("parsing regexp ranges")); + + for (;;) { + DUK__ADVANCECHARS(lex_ctx, adv); + adv = 1; + + x = DUK__L0(); + + ch = -1; /* not strictly necessary, but avoids "uninitialized variable" warnings */ + DUK_UNREF(ch); + + if (x < 0) { + goto fail_unterm_charclass; + } else if (x == DUK_ASC_RBRACKET) { + if (start >= 0) { + gen_range(userdata, start, start, 0); + } + DUK__ADVANCECHARS(lex_ctx, 1); /* eat ']' before finishing */ + break; + } else if (x == DUK_ASC_MINUS) { + if (start >= 0 && !dash && DUK__L1() != DUK_ASC_RBRACKET) { + /* '-' as a range indicator */ + dash = 1; + continue; + } else { + /* '-' verbatim */ + ch = x; + } + } else if (x == DUK_ASC_BACKSLASH) { + /* + * The escapes are same as outside a character class, except that \b has a + * different meaning, and \B and backreferences are prohibited (see E5 + * Section 15.10.2.19). However, it's difficult to share code because we + * handle e.g. "\n" very differently: here we generate a single character + * range for it. + */ + + /* XXX: ES2015 surrogate pair handling. */ + + x = DUK__L1(); + + adv = 2; + + if (x == DUK_ASC_LC_B) { + /* Note: '\b' in char class is different than outside (assertion), + * '\B' is not allowed and is caught by the duk_unicode_is_identifier_part() + * check below. + */ + ch = 0x0008; + } else if (x == DUK_ASC_LC_F) { + ch = 0x000c; + } else if (x == DUK_ASC_LC_N) { + ch = 0x000a; + } else if (x == DUK_ASC_LC_T) { + ch = 0x0009; + } else if (x == DUK_ASC_LC_R) { + ch = 0x000d; + } else if (x == DUK_ASC_LC_V) { + ch = 0x000b; + } else if (x == DUK_ASC_LC_C) { + x = DUK__L2(); + adv = 3; + if ((x >= DUK_ASC_LC_A && x <= DUK_ASC_LC_Z) || + (x >= DUK_ASC_UC_A && x <= DUK_ASC_UC_Z)) { + ch = (x % 32); + } else { + goto fail_escape; + } + } else if (x == DUK_ASC_LC_X || x == DUK_ASC_LC_U) { + /* The \u{H+} form is only allowed in Unicode mode which + * we don't support yet. + */ + ch = duk__lexer_parse_escape(lex_ctx, 0 /*allow_es6*/); + adv = 0; + } else if (x == DUK_ASC_LC_D) { + duk__emit_u16_direct_ranges(lex_ctx, + gen_range, + userdata, + duk_unicode_re_ranges_digit, + sizeof(duk_unicode_re_ranges_digit) / sizeof(duk_uint16_t)); + ch = -1; + } else if (x == DUK_ASC_UC_D) { + duk__emit_u16_direct_ranges(lex_ctx, + gen_range, + userdata, + duk_unicode_re_ranges_not_digit, + sizeof(duk_unicode_re_ranges_not_digit) / sizeof(duk_uint16_t)); + ch = -1; + } else if (x == DUK_ASC_LC_S) { + duk__emit_u16_direct_ranges(lex_ctx, + gen_range, + userdata, + duk_unicode_re_ranges_white, + sizeof(duk_unicode_re_ranges_white) / sizeof(duk_uint16_t)); + ch = -1; + } else if (x == DUK_ASC_UC_S) { + duk__emit_u16_direct_ranges(lex_ctx, + gen_range, + userdata, + duk_unicode_re_ranges_not_white, + sizeof(duk_unicode_re_ranges_not_white) / sizeof(duk_uint16_t)); + ch = -1; + } else if (x == DUK_ASC_LC_W) { + duk__emit_u16_direct_ranges(lex_ctx, + gen_range, + userdata, + duk_unicode_re_ranges_wordchar, + sizeof(duk_unicode_re_ranges_wordchar) / sizeof(duk_uint16_t)); + ch = -1; + } else if (x == DUK_ASC_UC_W) { + duk__emit_u16_direct_ranges(lex_ctx, + gen_range, + userdata, + duk_unicode_re_ranges_not_wordchar, + sizeof(duk_unicode_re_ranges_not_wordchar) / sizeof(duk_uint16_t)); + ch = -1; + } else if (DUK__ISDIGIT(x)) { + /* DecimalEscape, only \0 is allowed, no leading + * zeroes are allowed. + * + * ES2015 Annex B also allows (maximal match) legacy + * octal escapes up to \377 and \8 and \9 are + * accepted as literal '8' and '9', also in strict mode. + */ + +#if defined(DUK_USE_ES6_REGEXP_SYNTAX) + ch = duk__lexer_parse_legacy_octal(lex_ctx, &adv, 0 /*reject_annex_b*/); + DUK_ASSERT(ch >= 0); /* no rejections */ +#else + if (x == DUK_ASC_0 && !DUK__ISDIGIT(DUK__L2())) { + ch = 0x0000; + } else { + goto fail_escape; + } +#endif +#if defined(DUK_USE_ES6_REGEXP_SYNTAX) + } else if (x >= 0) { + /* IdentityEscape: ES2015 Annex B allows almost all + * source characters here. Match anything except + * EOF here. + */ + ch = x; +#else /* DUK_USE_ES6_REGEXP_SYNTAX */ + } else if (!duk_unicode_is_identifier_part(x)) { + /* IdentityEscape: ES5.1 doesn't allow identity escape + * for identifier part characters, which conflicts with + * some real world code. For example, it doesn't allow + * /[\$]/ which is awkward. + */ + ch = x; +#endif /* DUK_USE_ES6_REGEXP_SYNTAX */ + } else { + goto fail_escape; + } + } else { + /* character represents itself */ + ch = x; + } + + /* ch is a literal character here or -1 if parsed entity was + * an escape such as "\s". + */ + + if (ch < 0) { + /* multi-character sets not allowed as part of ranges, see + * E5 Section 15.10.2.15, abstract operation CharacterRange. + */ + if (start >= 0) { + if (dash) { + goto fail_range; + } else { + gen_range(userdata, start, start, 0); + start = -1; + /* dash is already 0 */ + } + } + } else { + if (start >= 0) { + if (dash) { + if (start > ch) { + goto fail_range; + } + gen_range(userdata, start, ch, 0); + start = -1; + dash = 0; + } else { + gen_range(userdata, start, start, 0); + start = ch; + /* dash is already 0 */ + } + } else { + start = ch; + } + } + } + + return; + + fail_escape: + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_ESCAPE); + DUK_WO_NORETURN(return;); + + fail_range: + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_RANGE); + DUK_WO_NORETURN(return;); + + fail_unterm_charclass: + DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_CHARCLASS); + DUK_WO_NORETURN(return;); +} + +#endif /* DUK_USE_REGEXP_SUPPORT */ diff --git a/third_party/duktape/duk_lexer.h b/third_party/duktape/duk_lexer.h new file mode 100644 index 00000000..9837d1df --- /dev/null +++ b/third_party/duktape/duk_lexer.h @@ -0,0 +1,438 @@ +/* + * Lexer defines. + */ + +#if !defined(DUK_LEXER_H_INCLUDED) +#define DUK_LEXER_H_INCLUDED + +typedef void (*duk_re_range_callback)(void *user, duk_codepoint_t r1, duk_codepoint_t r2, duk_bool_t direct); + +/* + * A token is interpreted as any possible production of InputElementDiv + * and InputElementRegExp, see E5 Section 7 in its entirety. Note that + * the E5 "Token" production does not cover all actual tokens of the + * language (which is explicitly stated in the specification, Section 7.5). + * Null and boolean literals are defined as part of both ReservedWord + * (E5 Section 7.6.1) and Literal (E5 Section 7.8) productions. Here, + * null and boolean values have literal tokens, and are not reserved + * words. + * + * Decimal literal negative/positive sign is -not- part of DUK_TOK_NUMBER. + * The number tokens always have a non-negative value. The unary minus + * operator in "-1.0" is optimized during compilation to yield a single + * negative constant. + * + * Token numbering is free except that reserved words are required to be + * in a continuous range and in a particular order. See genstrings.py. + */ + +#define DUK_LEXER_INITCTX(ctx) duk_lexer_initctx((ctx)) + +#define DUK_LEXER_SETPOINT(ctx,pt) duk_lexer_setpoint((ctx), (pt)) + +#define DUK_LEXER_GETPOINT(ctx,pt) duk_lexer_getpoint((ctx), (pt)) + +/* Currently 6 characters of lookup are actually needed (duk_lexer.c). */ +#define DUK_LEXER_WINDOW_SIZE 6 +#if defined(DUK_USE_LEXER_SLIDING_WINDOW) +#define DUK_LEXER_BUFFER_SIZE 64 +#endif + +#define DUK_TOK_MINVAL 0 + +/* returned after EOF (infinite amount) */ +#define DUK_TOK_EOF 0 + +/* identifier names (E5 Section 7.6) */ +#define DUK_TOK_IDENTIFIER 1 + +/* reserved words: keywords */ +#define DUK_TOK_START_RESERVED 2 +#define DUK_TOK_BREAK 2 +#define DUK_TOK_CASE 3 +#define DUK_TOK_CATCH 4 +#define DUK_TOK_CONTINUE 5 +#define DUK_TOK_DEBUGGER 6 +#define DUK_TOK_DEFAULT 7 +#define DUK_TOK_DELETE 8 +#define DUK_TOK_DO 9 +#define DUK_TOK_ELSE 10 +#define DUK_TOK_FINALLY 11 +#define DUK_TOK_FOR 12 +#define DUK_TOK_FUNCTION 13 +#define DUK_TOK_IF 14 +#define DUK_TOK_IN 15 +#define DUK_TOK_INSTANCEOF 16 +#define DUK_TOK_NEW 17 +#define DUK_TOK_RETURN 18 +#define DUK_TOK_SWITCH 19 +#define DUK_TOK_THIS 20 +#define DUK_TOK_THROW 21 +#define DUK_TOK_TRY 22 +#define DUK_TOK_TYPEOF 23 +#define DUK_TOK_VAR 24 +#define DUK_TOK_CONST 25 +#define DUK_TOK_VOID 26 +#define DUK_TOK_WHILE 27 +#define DUK_TOK_WITH 28 + +/* reserved words: future reserved words */ +#define DUK_TOK_CLASS 29 +#define DUK_TOK_ENUM 30 +#define DUK_TOK_EXPORT 31 +#define DUK_TOK_EXTENDS 32 +#define DUK_TOK_IMPORT 33 +#define DUK_TOK_SUPER 34 + +/* "null", "true", and "false" are always reserved words. + * Note that "get" and "set" are not! + */ +#define DUK_TOK_NULL 35 +#define DUK_TOK_TRUE 36 +#define DUK_TOK_FALSE 37 + +/* reserved words: additional future reserved words in strict mode */ +#define DUK_TOK_START_STRICT_RESERVED 38 /* inclusive */ +#define DUK_TOK_IMPLEMENTS 38 +#define DUK_TOK_INTERFACE 39 +#define DUK_TOK_LET 40 +#define DUK_TOK_PACKAGE 41 +#define DUK_TOK_PRIVATE 42 +#define DUK_TOK_PROTECTED 43 +#define DUK_TOK_PUBLIC 44 +#define DUK_TOK_STATIC 45 +#define DUK_TOK_YIELD 46 + +#define DUK_TOK_END_RESERVED 47 /* exclusive */ + +/* "get" and "set" are tokens but NOT ReservedWords. They are currently + * parsed and identifiers and these defines are actually now unused. + */ +#define DUK_TOK_GET 47 +#define DUK_TOK_SET 48 + +/* punctuators (unlike the spec, also includes "/" and "/=") */ +#define DUK_TOK_LCURLY 49 +#define DUK_TOK_RCURLY 50 +#define DUK_TOK_LBRACKET 51 +#define DUK_TOK_RBRACKET 52 +#define DUK_TOK_LPAREN 53 +#define DUK_TOK_RPAREN 54 +#define DUK_TOK_PERIOD 55 +#define DUK_TOK_SEMICOLON 56 +#define DUK_TOK_COMMA 57 +#define DUK_TOK_LT 58 +#define DUK_TOK_GT 59 +#define DUK_TOK_LE 60 +#define DUK_TOK_GE 61 +#define DUK_TOK_EQ 62 +#define DUK_TOK_NEQ 63 +#define DUK_TOK_SEQ 64 +#define DUK_TOK_SNEQ 65 +#define DUK_TOK_ADD 66 +#define DUK_TOK_SUB 67 +#define DUK_TOK_MUL 68 +#define DUK_TOK_DIV 69 +#define DUK_TOK_MOD 70 +#define DUK_TOK_EXP 71 +#define DUK_TOK_INCREMENT 72 +#define DUK_TOK_DECREMENT 73 +#define DUK_TOK_ALSHIFT 74 /* named "arithmetic" because result is signed */ +#define DUK_TOK_ARSHIFT 75 +#define DUK_TOK_RSHIFT 76 +#define DUK_TOK_BAND 77 +#define DUK_TOK_BOR 78 +#define DUK_TOK_BXOR 79 +#define DUK_TOK_LNOT 80 +#define DUK_TOK_BNOT 81 +#define DUK_TOK_LAND 82 +#define DUK_TOK_LOR 83 +#define DUK_TOK_QUESTION 84 +#define DUK_TOK_COLON 85 +#define DUK_TOK_EQUALSIGN 86 +#define DUK_TOK_ADD_EQ 87 +#define DUK_TOK_SUB_EQ 88 +#define DUK_TOK_MUL_EQ 89 +#define DUK_TOK_DIV_EQ 90 +#define DUK_TOK_MOD_EQ 91 +#define DUK_TOK_EXP_EQ 92 +#define DUK_TOK_ALSHIFT_EQ 93 +#define DUK_TOK_ARSHIFT_EQ 94 +#define DUK_TOK_RSHIFT_EQ 95 +#define DUK_TOK_BAND_EQ 96 +#define DUK_TOK_BOR_EQ 97 +#define DUK_TOK_BXOR_EQ 98 + +/* literals (E5 Section 7.8), except null, true, false, which are treated + * like reserved words (above). + */ +#define DUK_TOK_NUMBER 99 +#define DUK_TOK_STRING 100 +#define DUK_TOK_REGEXP 101 + +#define DUK_TOK_MAXVAL 101 /* inclusive */ + +#define DUK_TOK_INVALID DUK_SMALL_UINT_MAX + +/* Convert heap string index to a token (reserved words) */ +#define DUK_STRIDX_TO_TOK(x) ((x) - DUK_STRIDX_START_RESERVED + DUK_TOK_START_RESERVED) + +/* Sanity check */ +#if (DUK_TOK_MAXVAL > 255) +#error DUK_TOK_MAXVAL too large, code assumes it fits into 8 bits +#endif + +/* Sanity checks for string and token defines */ +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_BREAK) != DUK_TOK_BREAK) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CASE) != DUK_TOK_CASE) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CATCH) != DUK_TOK_CATCH) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CONTINUE) != DUK_TOK_CONTINUE) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DEBUGGER) != DUK_TOK_DEBUGGER) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DEFAULT) != DUK_TOK_DEFAULT) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DELETE) != DUK_TOK_DELETE) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DO) != DUK_TOK_DO) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_ELSE) != DUK_TOK_ELSE) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_FINALLY) != DUK_TOK_FINALLY) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_FOR) != DUK_TOK_FOR) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_LC_FUNCTION) != DUK_TOK_FUNCTION) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IF) != DUK_TOK_IF) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IN) != DUK_TOK_IN) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_INSTANCEOF) != DUK_TOK_INSTANCEOF) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_NEW) != DUK_TOK_NEW) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_RETURN) != DUK_TOK_RETURN) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_SWITCH) != DUK_TOK_SWITCH) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_THIS) != DUK_TOK_THIS) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_THROW) != DUK_TOK_THROW) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_TRY) != DUK_TOK_TRY) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_TYPEOF) != DUK_TOK_TYPEOF) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_VAR) != DUK_TOK_VAR) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_VOID) != DUK_TOK_VOID) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_WHILE) != DUK_TOK_WHILE) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_WITH) != DUK_TOK_WITH) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CLASS) != DUK_TOK_CLASS) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CONST) != DUK_TOK_CONST) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_ENUM) != DUK_TOK_ENUM) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_EXPORT) != DUK_TOK_EXPORT) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_EXTENDS) != DUK_TOK_EXTENDS) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IMPORT) != DUK_TOK_IMPORT) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_SUPER) != DUK_TOK_SUPER) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_LC_NULL) != DUK_TOK_NULL) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_TRUE) != DUK_TOK_TRUE) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_FALSE) != DUK_TOK_FALSE) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IMPLEMENTS) != DUK_TOK_IMPLEMENTS) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_INTERFACE) != DUK_TOK_INTERFACE) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_LET) != DUK_TOK_LET) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PACKAGE) != DUK_TOK_PACKAGE) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PRIVATE) != DUK_TOK_PRIVATE) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PROTECTED) != DUK_TOK_PROTECTED) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PUBLIC) != DUK_TOK_PUBLIC) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_STATIC) != DUK_TOK_STATIC) +#error mismatch in token defines +#endif +#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_YIELD) != DUK_TOK_YIELD) +#error mismatch in token defines +#endif + +/* Regexp tokens */ +#define DUK_RETOK_EOF 0 +#define DUK_RETOK_DISJUNCTION 1 +#define DUK_RETOK_QUANTIFIER 2 +#define DUK_RETOK_ASSERT_START 3 +#define DUK_RETOK_ASSERT_END 4 +#define DUK_RETOK_ASSERT_WORD_BOUNDARY 5 +#define DUK_RETOK_ASSERT_NOT_WORD_BOUNDARY 6 +#define DUK_RETOK_ASSERT_START_POS_LOOKAHEAD 7 +#define DUK_RETOK_ASSERT_START_NEG_LOOKAHEAD 8 +#define DUK_RETOK_ATOM_PERIOD 9 +#define DUK_RETOK_ATOM_CHAR 10 +#define DUK_RETOK_ATOM_DIGIT 11 /* assumptions in regexp compiler */ +#define DUK_RETOK_ATOM_NOT_DIGIT 12 /* -""- */ +#define DUK_RETOK_ATOM_WHITE 13 /* -""- */ +#define DUK_RETOK_ATOM_NOT_WHITE 14 /* -""- */ +#define DUK_RETOK_ATOM_WORD_CHAR 15 /* -""- */ +#define DUK_RETOK_ATOM_NOT_WORD_CHAR 16 /* -""- */ +#define DUK_RETOK_ATOM_BACKREFERENCE 17 +#define DUK_RETOK_ATOM_START_CAPTURE_GROUP 18 +#define DUK_RETOK_ATOM_START_NONCAPTURE_GROUP 19 +#define DUK_RETOK_ATOM_START_CHARCLASS 20 +#define DUK_RETOK_ATOM_START_CHARCLASS_INVERTED 21 +#define DUK_RETOK_ATOM_END_GROUP 22 + +/* Constants for duk_lexer_ctx.buf. */ +#define DUK_LEXER_TEMP_BUF_LIMIT 256 + +/* A token value. Can be memcpy()'d, but note that slot1/slot2 values are on the valstack. + * Some fields (like num, str1, str2) are only valid for specific token types and may have + * stale values otherwise. + */ +struct duk_token { + duk_small_uint_t t; /* token type (with reserved word identification) */ + duk_small_uint_t t_nores; /* token type (with reserved words as DUK_TOK_IDENTIFER) */ + duk_double_t num; /* numeric value of token */ + duk_hstring *str1; /* string 1 of token (borrowed, stored to ctx->slot1_idx) */ + duk_hstring *str2; /* string 2 of token (borrowed, stored to ctx->slot2_idx) */ + duk_size_t start_offset; /* start byte offset of token in lexer input */ + duk_int_t start_line; /* start line of token (first char) */ + duk_int_t num_escapes; /* number of escapes and line continuations (for directive prologue) */ + duk_bool_t lineterm; /* token was preceded by a lineterm */ + duk_bool_t allow_auto_semi; /* token allows automatic semicolon insertion (eof or preceded by newline) */ +}; + +#define DUK_RE_QUANTIFIER_INFINITE ((duk_uint32_t) 0xffffffffUL) + +/* A regexp token value. */ +struct duk_re_token { + duk_small_uint_t t; /* token type */ + duk_small_uint_t greedy; + duk_uint32_t num; /* numeric value (character, count) */ + duk_uint32_t qmin; + duk_uint32_t qmax; +}; + +/* A structure for 'snapshotting' a point for rewinding */ +struct duk_lexer_point { + duk_size_t offset; + duk_int_t line; +}; + +/* Lexer codepoint with additional info like offset/line number */ +struct duk_lexer_codepoint { + duk_codepoint_t codepoint; + duk_size_t offset; + duk_int_t line; +}; + +/* Lexer context. Same context is used for ECMAScript and Regexp parsing. */ +struct duk_lexer_ctx { +#if defined(DUK_USE_LEXER_SLIDING_WINDOW) + duk_lexer_codepoint *window; /* unicode code points, window[0] is always next, points to 'buffer' */ + duk_lexer_codepoint buffer[DUK_LEXER_BUFFER_SIZE]; +#else + duk_lexer_codepoint window[DUK_LEXER_WINDOW_SIZE]; /* unicode code points, window[0] is always next */ +#endif + + duk_hthread *thr; /* thread; minimizes argument passing */ + + const duk_uint8_t *input; /* input string (may be a user pointer) */ + duk_size_t input_length; /* input byte length */ + duk_size_t input_offset; /* input offset for window leading edge (not window[0]) */ + duk_int_t input_line; /* input linenumber at input_offset (not window[0]), init to 1 */ + + duk_idx_t slot1_idx; /* valstack slot for 1st token value */ + duk_idx_t slot2_idx; /* valstack slot for 2nd token value */ + duk_idx_t buf_idx; /* valstack slot for temp buffer */ + duk_hbuffer_dynamic *buf; /* temp accumulation buffer */ + duk_bufwriter_ctx bw; /* bufwriter for temp accumulation */ + + duk_int_t token_count; /* number of tokens parsed */ + duk_int_t token_limit; /* maximum token count before error (sanity backstop) */ + + duk_small_uint_t flags; /* lexer flags, use compiler flag defines for now */ +}; + +/* + * Prototypes + */ + +DUK_INTERNAL_DECL void duk_lexer_initctx(duk_lexer_ctx *lex_ctx); + +DUK_INTERNAL_DECL void duk_lexer_getpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt); +DUK_INTERNAL_DECL void duk_lexer_setpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt); + +DUK_INTERNAL_DECL +void duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx, + duk_token *out_token, + duk_bool_t strict_mode, + duk_bool_t regexp_mode); +#if defined(DUK_USE_REGEXP_SUPPORT) +DUK_INTERNAL_DECL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token *out_token); +DUK_INTERNAL_DECL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_range_callback gen_range, void *userdata); +#endif /* DUK_USE_REGEXP_SUPPORT */ + +#endif /* DUK_LEXER_H_INCLUDED */ diff --git a/third_party/duktape/duk_numconv.c b/third_party/duktape/duk_numconv.c new file mode 100644 index 00000000..d5268c50 --- /dev/null +++ b/third_party/duktape/duk_numconv.c @@ -0,0 +1,2280 @@ +/* + * Number-to-string and string-to-number conversions. + * + * Slow path number-to-string and string-to-number conversion is based on + * a Dragon4 variant, with fast paths for small integers. Big integer + * arithmetic is needed for guaranteeing that the conversion is correct + * and uses a minimum number of digits. The big number arithmetic has a + * fixed maximum size and does not require dynamic allocations. + * + * See: doc/number-conversion.rst. + */ + +#include "third_party/duktape/duk_internal.h" + +#define DUK__IEEE_DOUBLE_EXP_BIAS 1023 +#define DUK__IEEE_DOUBLE_EXP_MIN (-1022) /* biased exp == 0 -> denormal, exp -1022 */ + +#define DUK__DIGITCHAR(x) duk_lc_digits[(x)] + +/* + * Tables generated with util/gennumdigits.py. + * + * duk__str2num_digits_for_radix indicates, for each radix, how many input + * digits should be considered significant for string-to-number conversion. + * The input is also padded to this many digits to give the Dragon4 + * conversion enough (apparent) precision to work with. + * + * duk__str2num_exp_limits indicates, for each radix, the radix-specific + * minimum/maximum exponent values (for a Dragon4 integer mantissa) + * below and above which the number is guaranteed to underflow to zero + * or overflow to Infinity. This allows parsing to keep bigint values + * bounded. + */ + +DUK_LOCAL const duk_uint8_t duk__str2num_digits_for_radix[] = { + 69, 44, 35, 30, 27, 25, 23, 22, 20, 20, /* 2 to 11 */ + 20, 19, 19, 18, 18, 17, 17, 17, 16, 16, /* 12 to 21 */ + 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, /* 22 to 31 */ + 14, 14, 14, 14, 14 /* 31 to 36 */ +}; + +typedef struct { + duk_int16_t upper; + duk_int16_t lower; +} duk__exp_limits; + +DUK_LOCAL const duk__exp_limits duk__str2num_exp_limits[] = { + { 957, -1147 }, { 605, -725 }, { 479, -575 }, { 414, -496 }, + { 372, -446 }, { 342, -411 }, { 321, -384 }, { 304, -364 }, + { 291, -346 }, { 279, -334 }, { 268, -323 }, { 260, -312 }, + { 252, -304 }, { 247, -296 }, { 240, -289 }, { 236, -283 }, + { 231, -278 }, { 227, -273 }, { 223, -267 }, { 220, -263 }, + { 216, -260 }, { 213, -256 }, { 210, -253 }, { 208, -249 }, + { 205, -246 }, { 203, -244 }, { 201, -241 }, { 198, -239 }, + { 196, -237 }, { 195, -234 }, { 193, -232 }, { 191, -230 }, + { 190, -228 }, { 188, -226 }, { 187, -225 }, +}; + +/* + * Limited functionality bigint implementation. + * + * Restricted to non-negative numbers with less than 32 * DUK__BI_MAX_PARTS bits, + * with the caller responsible for ensuring this is never exceeded. No memory + * allocation (except stack) is needed for bigint computation. Operations + * have been tailored for number conversion needs. + * + * Argument order is "assignment order", i.e. target first, then arguments: + * x <- y * z --> duk__bi_mul(x, y, z); + */ + +/* This upper value has been experimentally determined; debug build will check + * bigint size with assertions. + */ +#define DUK__BI_MAX_PARTS 37 /* 37x32 = 1184 bits */ + +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2) +#define DUK__BI_PRINT(name,x) duk__bi_print((name),(x)) +#else +#define DUK__BI_PRINT(name,x) +#endif + +/* Current size is about 152 bytes. */ +typedef struct { + duk_small_int_t n; + duk_uint32_t v[DUK__BI_MAX_PARTS]; /* low to high */ +} duk__bigint; + +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2) +DUK_LOCAL void duk__bi_print(const char *name, duk__bigint *x) { + /* Overestimate required size; debug code so not critical to be tight. */ + char buf[DUK__BI_MAX_PARTS * 9 + 64]; + char *p = buf; + duk_small_int_t i; + + /* No NUL term checks in this debug code. */ + p += DUK_SPRINTF(p, "%p n=%ld", (void *) x, (long) x->n); + if (x->n == 0) { + p += DUK_SPRINTF(p, " 0"); + } + for (i = x->n - 1; i >= 0; i--) { + p += DUK_SPRINTF(p, " %08lx", (unsigned long) x->v[i]); + } + + DUK_DDD(DUK_DDDPRINT("%s: %s", (const char *) name, (const char *) buf)); +} +#endif + +#if defined(DUK_USE_ASSERTIONS) +DUK_LOCAL duk_small_int_t duk__bi_is_valid(duk__bigint *x) { + return (duk_small_int_t) + ( ((x->n >= 0) && (x->n <= DUK__BI_MAX_PARTS)) /* is valid size */ && + ((x->n == 0) || (x->v[x->n - 1] != 0)) /* is normalized */ ); +} +#endif + +DUK_LOCAL void duk__bi_normalize(duk__bigint *x) { + duk_small_int_t i; + + for (i = x->n - 1; i >= 0; i--) { + if (x->v[i] != 0) { + break; + } + } + + /* Note: if 'x' is zero, x->n becomes 0 here */ + x->n = i + 1; + DUK_ASSERT(duk__bi_is_valid(x)); +} + +/* x <- y */ +DUK_LOCAL void duk__bi_copy(duk__bigint *x, duk__bigint *y) { + duk_small_int_t n; + + n = y->n; + x->n = n; + /* No need to special case n == 0. */ + duk_memcpy((void *) x->v, (const void *) y->v, (size_t) (sizeof(duk_uint32_t) * (size_t) n)); +} + +DUK_LOCAL void duk__bi_set_small(duk__bigint *x, duk_uint32_t v) { + if (v == 0U) { + x->n = 0; + } else { + x->n = 1; + x->v[0] = v; + } + DUK_ASSERT(duk__bi_is_valid(x)); +} + +/* Return value: <0 <=> x < y + * 0 <=> x == y + * >0 <=> x > y + */ +DUK_LOCAL int duk__bi_compare(duk__bigint *x, duk__bigint *y) { + duk_small_int_t i, nx, ny; + duk_uint32_t tx, ty; + + DUK_ASSERT(duk__bi_is_valid(x)); + DUK_ASSERT(duk__bi_is_valid(y)); + + nx = x->n; + ny = y->n; + if (nx > ny) { + goto ret_gt; + } + if (nx < ny) { + goto ret_lt; + } + for (i = nx - 1; i >= 0; i--) { + tx = x->v[i]; + ty = y->v[i]; + + if (tx > ty) { + goto ret_gt; + } + if (tx < ty) { + goto ret_lt; + } + } + + return 0; + + ret_gt: + return 1; + + ret_lt: + return -1; +} + +/* x <- y + z */ +#if defined(DUK_USE_64BIT_OPS) +DUK_LOCAL void duk__bi_add(duk__bigint *x, duk__bigint *y, duk__bigint *z) { + duk_uint64_t tmp; + duk_small_int_t i, ny, nz; + + DUK_ASSERT(duk__bi_is_valid(y)); + DUK_ASSERT(duk__bi_is_valid(z)); + + if (z->n > y->n) { + duk__bigint *t; + t = y; y = z; z = t; + } + DUK_ASSERT(y->n >= z->n); + + ny = y->n; nz = z->n; + tmp = 0U; + for (i = 0; i < ny; i++) { + DUK_ASSERT(i < DUK__BI_MAX_PARTS); + tmp += y->v[i]; + if (i < nz) { + tmp += z->v[i]; + } + x->v[i] = (duk_uint32_t) (tmp & 0xffffffffUL); + tmp = tmp >> 32; + } + if (tmp != 0U) { + DUK_ASSERT(i < DUK__BI_MAX_PARTS); + x->v[i++] = (duk_uint32_t) tmp; + } + x->n = i; + DUK_ASSERT(x->n <= DUK__BI_MAX_PARTS); + + /* no need to normalize */ + DUK_ASSERT(duk__bi_is_valid(x)); +} +#else /* DUK_USE_64BIT_OPS */ +DUK_LOCAL void duk__bi_add(duk__bigint *x, duk__bigint *y, duk__bigint *z) { + duk_uint32_t carry, tmp1, tmp2; + duk_small_int_t i, ny, nz; + + DUK_ASSERT(duk__bi_is_valid(y)); + DUK_ASSERT(duk__bi_is_valid(z)); + + if (z->n > y->n) { + duk__bigint *t; + t = y; y = z; z = t; + } + DUK_ASSERT(y->n >= z->n); + + ny = y->n; nz = z->n; + carry = 0U; + for (i = 0; i < ny; i++) { + /* Carry is detected based on wrapping which relies on exact 32-bit + * types. + */ + DUK_ASSERT(i < DUK__BI_MAX_PARTS); + tmp1 = y->v[i]; + tmp2 = tmp1; + if (i < nz) { + tmp2 += z->v[i]; + } + + /* Careful with carry condition: + * - If carry not added: 0x12345678 + 0 + 0xffffffff = 0x12345677 (< 0x12345678) + * - If carry added: 0x12345678 + 1 + 0xffffffff = 0x12345678 (== 0x12345678) + */ + if (carry) { + tmp2++; + carry = (tmp2 <= tmp1 ? 1U : 0U); + } else { + carry = (tmp2 < tmp1 ? 1U : 0U); + } + + x->v[i] = tmp2; + } + if (carry) { + DUK_ASSERT(i < DUK__BI_MAX_PARTS); + DUK_ASSERT(carry == 1U); + x->v[i++] = carry; + } + x->n = i; + DUK_ASSERT(x->n <= DUK__BI_MAX_PARTS); + + /* no need to normalize */ + DUK_ASSERT(duk__bi_is_valid(x)); +} +#endif /* DUK_USE_64BIT_OPS */ + +/* x <- y + z */ +DUK_LOCAL void duk__bi_add_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) { + duk__bigint tmp; + + DUK_ASSERT(duk__bi_is_valid(y)); + + /* XXX: this could be optimized; there is only one call site now though */ + duk__bi_set_small(&tmp, z); + duk__bi_add(x, y, &tmp); + + DUK_ASSERT(duk__bi_is_valid(x)); +} + +#if 0 /* unused */ +/* x <- x + y, use t as temp */ +DUK_LOCAL void duk__bi_add_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) { + duk__bi_add(t, x, y); + duk__bi_copy(x, t); +} +#endif + +/* x <- y - z, require x >= y => z >= 0, i.e. y >= z */ +#if defined(DUK_USE_64BIT_OPS) +DUK_LOCAL void duk__bi_sub(duk__bigint *x, duk__bigint *y, duk__bigint *z) { + duk_small_int_t i, ny, nz; + duk_uint32_t ty, tz; + duk_int64_t tmp; + + DUK_ASSERT(duk__bi_is_valid(y)); + DUK_ASSERT(duk__bi_is_valid(z)); + DUK_ASSERT(duk__bi_compare(y, z) >= 0); + DUK_ASSERT(y->n >= z->n); + + ny = y->n; nz = z->n; + tmp = 0; + for (i = 0; i < ny; i++) { + ty = y->v[i]; + if (i < nz) { + tz = z->v[i]; + } else { + tz = 0; + } + tmp = (duk_int64_t) ty - (duk_int64_t) tz + tmp; + x->v[i] = (duk_uint32_t) ((duk_uint64_t) tmp & 0xffffffffUL); + tmp = tmp >> 32; /* 0 or -1 */ + } + DUK_ASSERT(tmp == 0); + + x->n = i; + duk__bi_normalize(x); /* need to normalize, may even cancel to 0 */ + DUK_ASSERT(duk__bi_is_valid(x)); +} +#else +DUK_LOCAL void duk__bi_sub(duk__bigint *x, duk__bigint *y, duk__bigint *z) { + duk_small_int_t i, ny, nz; + duk_uint32_t tmp1, tmp2, borrow; + + DUK_ASSERT(duk__bi_is_valid(y)); + DUK_ASSERT(duk__bi_is_valid(z)); + DUK_ASSERT(duk__bi_compare(y, z) >= 0); + DUK_ASSERT(y->n >= z->n); + + ny = y->n; nz = z->n; + borrow = 0U; + for (i = 0; i < ny; i++) { + /* Borrow is detected based on wrapping which relies on exact 32-bit + * types. + */ + tmp1 = y->v[i]; + tmp2 = tmp1; + if (i < nz) { + tmp2 -= z->v[i]; + } + + /* Careful with borrow condition: + * - If borrow not subtracted: 0x12345678 - 0 - 0xffffffff = 0x12345679 (> 0x12345678) + * - If borrow subtracted: 0x12345678 - 1 - 0xffffffff = 0x12345678 (== 0x12345678) + */ + if (borrow) { + tmp2--; + borrow = (tmp2 >= tmp1 ? 1U : 0U); + } else { + borrow = (tmp2 > tmp1 ? 1U : 0U); + } + + x->v[i] = tmp2; + } + DUK_ASSERT(borrow == 0U); + + x->n = i; + duk__bi_normalize(x); /* need to normalize, may even cancel to 0 */ + DUK_ASSERT(duk__bi_is_valid(x)); +} +#endif + +#if 0 /* unused */ +/* x <- y - z */ +DUK_LOCAL void duk__bi_sub_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) { + duk__bigint tmp; + + DUK_ASSERT(duk__bi_is_valid(y)); + + /* XXX: this could be optimized */ + duk__bi_set_small(&tmp, z); + duk__bi_sub(x, y, &tmp); + + DUK_ASSERT(duk__bi_is_valid(x)); +} +#endif + +/* x <- x - y, use t as temp */ +DUK_LOCAL void duk__bi_sub_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) { + duk__bi_sub(t, x, y); + duk__bi_copy(x, t); +} + +/* x <- y * z */ +DUK_LOCAL void duk__bi_mul(duk__bigint *x, duk__bigint *y, duk__bigint *z) { + duk_small_int_t i, j, nx, nz; + + DUK_ASSERT(duk__bi_is_valid(y)); + DUK_ASSERT(duk__bi_is_valid(z)); + + nx = y->n + z->n; /* max possible */ + DUK_ASSERT(nx <= DUK__BI_MAX_PARTS); + + if (nx == 0) { + /* Both inputs are zero; cases where only one is zero can go + * through main algorithm. + */ + x->n = 0; + return; + } + + duk_memzero((void *) x->v, (size_t) (sizeof(duk_uint32_t) * (size_t) nx)); + x->n = nx; + + nz = z->n; + for (i = 0; i < y->n; i++) { +#if defined(DUK_USE_64BIT_OPS) + duk_uint64_t tmp = 0U; + for (j = 0; j < nz; j++) { + tmp += (duk_uint64_t) y->v[i] * (duk_uint64_t) z->v[j] + x->v[i+j]; + x->v[i+j] = (duk_uint32_t) (tmp & 0xffffffffUL); + tmp = tmp >> 32; + } + if (tmp > 0) { + DUK_ASSERT(i + j < nx); + DUK_ASSERT(i + j < DUK__BI_MAX_PARTS); + DUK_ASSERT(x->v[i+j] == 0U); + x->v[i+j] = (duk_uint32_t) tmp; + } +#else + /* + * Multiply + add + carry for 32-bit components using only 16x16->32 + * multiplies and carry detection based on unsigned overflow. + * + * 1st mult, 32-bit: (A*2^16 + B) + * 2nd mult, 32-bit: (C*2^16 + D) + * 3rd add, 32-bit: E + * 4th add, 32-bit: F + * + * (AC*2^16 + B) * (C*2^16 + D) + E + F + * = AC*2^32 + AD*2^16 + BC*2^16 + BD + E + F + * = AC*2^32 + (AD + BC)*2^16 + (BD + E + F) + * = AC*2^32 + AD*2^16 + BC*2^16 + (BD + E + F) + */ + duk_uint32_t a, b, c, d, e, f; + duk_uint32_t r, s, t; + + a = y->v[i]; b = a & 0xffffUL; a = a >> 16; + + f = 0; + for (j = 0; j < nz; j++) { + c = z->v[j]; d = c & 0xffffUL; c = c >> 16; + e = x->v[i+j]; + + /* build result as: (r << 32) + s: start with (BD + E + F) */ + r = 0; + s = b * d; + + /* add E */ + t = s + e; + if (t < s) { r++; } /* carry */ + s = t; + + /* add F */ + t = s + f; + if (t < s) { r++; } /* carry */ + s = t; + + /* add BC*2^16 */ + t = b * c; + r += (t >> 16); + t = s + ((t & 0xffffUL) << 16); + if (t < s) { r++; } /* carry */ + s = t; + + /* add AD*2^16 */ + t = a * d; + r += (t >> 16); + t = s + ((t & 0xffffUL) << 16); + if (t < s) { r++; } /* carry */ + s = t; + + /* add AC*2^32 */ + t = a * c; + r += t; + + DUK_DDD(DUK_DDDPRINT("ab=%08lx cd=%08lx ef=%08lx -> rs=%08lx %08lx", + (unsigned long) y->v[i], (unsigned long) z->v[j], + (unsigned long) x->v[i+j], (unsigned long) r, + (unsigned long) s)); + + x->v[i+j] = s; + f = r; + } + if (f > 0U) { + DUK_ASSERT(i + j < nx); + DUK_ASSERT(i + j < DUK__BI_MAX_PARTS); + DUK_ASSERT(x->v[i+j] == 0U); + x->v[i+j] = (duk_uint32_t) f; + } +#endif /* DUK_USE_64BIT_OPS */ + } + + duk__bi_normalize(x); + DUK_ASSERT(duk__bi_is_valid(x)); +} + +/* x <- y * z */ +DUK_LOCAL void duk__bi_mul_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) { + duk__bigint tmp; + + DUK_ASSERT(duk__bi_is_valid(y)); + + /* XXX: this could be optimized */ + duk__bi_set_small(&tmp, z); + duk__bi_mul(x, y, &tmp); + + DUK_ASSERT(duk__bi_is_valid(x)); +} + +/* x <- x * y, use t as temp */ +DUK_LOCAL void duk__bi_mul_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) { + duk__bi_mul(t, x, y); + duk__bi_copy(x, t); +} + +/* x <- x * y, use t as temp */ +DUK_LOCAL void duk__bi_mul_small_copy(duk__bigint *x, duk_uint32_t y, duk__bigint *t) { + duk__bi_mul_small(t, x, y); + duk__bi_copy(x, t); +} + +DUK_LOCAL int duk__bi_is_even(duk__bigint *x) { + DUK_ASSERT(duk__bi_is_valid(x)); + return (x->n == 0) || ((x->v[0] & 0x01) == 0); +} + +DUK_LOCAL int duk__bi_is_zero(duk__bigint *x) { + DUK_ASSERT(duk__bi_is_valid(x)); + return (x->n == 0); /* this is the case for normalized numbers */ +} + +/* Bigint is 2^52. Used to detect normalized IEEE double mantissa values + * which are at the lowest edge (next floating point value downwards has + * a different exponent). The lowest mantissa has the form: + * + * 1000........000 (52 zeroes; only "hidden bit" is set) + */ +DUK_LOCAL duk_small_int_t duk__bi_is_2to52(duk__bigint *x) { + DUK_ASSERT(duk__bi_is_valid(x)); + return (duk_small_int_t) + (x->n == 2) && (x->v[0] == 0U) && (x->v[1] == (1U << (52-32))); +} + +/* x <- (1< 0); + r = y % 32; + duk_memzero((void *) x->v, sizeof(duk_uint32_t) * (size_t) n); + x->n = n; + x->v[n - 1] = (((duk_uint32_t) 1) << r); +} + +/* x <- b^y; use t1 and t2 as temps */ +DUK_LOCAL void duk__bi_exp_small(duk__bigint *x, duk_small_int_t b, duk_small_int_t y, duk__bigint *t1, duk__bigint *t2) { + /* Fast path the binary case */ + + DUK_ASSERT(x != t1 && x != t2 && t1 != t2); /* distinct bignums, easy mistake to make */ + DUK_ASSERT(b >= 0); + DUK_ASSERT(y >= 0); + + if (b == 2) { + duk__bi_twoexp(x, y); + return; + } + + /* http://en.wikipedia.org/wiki/Exponentiation_by_squaring */ + + DUK_DDD(DUK_DDDPRINT("exp_small: b=%ld, y=%ld", (long) b, (long) y)); + + duk__bi_set_small(x, 1); + duk__bi_set_small(t1, (duk_uint32_t) b); + for (;;) { + /* Loop structure ensures that we don't compute t1^2 unnecessarily + * on the final round, as that might create a bignum exceeding the + * current DUK__BI_MAX_PARTS limit. + */ + if (y & 0x01) { + duk__bi_mul_copy(x, t1, t2); + } + y = y >> 1; + if (y == 0) { + break; + } + duk__bi_mul_copy(t1, t1, t2); + } + + DUK__BI_PRINT("exp_small result", x); +} + +/* + * A Dragon4 number-to-string variant, based on: + * + * Guy L. Steele Jr., Jon L. White: "How to Print Floating-Point Numbers + * Accurately" + * + * Robert G. Burger, R. Kent Dybvig: "Printing Floating-Point Numbers + * Quickly and Accurately" + * + * The current algorithm is based on Figure 1 of the Burger-Dybvig paper, + * i.e. the base implementation without logarithm estimation speedups + * (these would increase code footprint considerably). Fixed-format output + * does not follow the suggestions in the paper; instead, we generate an + * extra digit and round-with-carry. + * + * The same algorithm is used for number parsing (with b=10 and B=2) + * by generating one extra digit and doing rounding manually. + * + * See doc/number-conversion.rst for limitations. + */ + +/* Maximum number of digits generated. */ +#define DUK__MAX_OUTPUT_DIGITS 1040 /* (Number.MAX_VALUE).toString(2).length == 1024, + slack */ + +/* Maximum number of characters in formatted value. */ +#define DUK__MAX_FORMATTED_LENGTH 1040 /* (-Number.MAX_VALUE).toString(2).length == 1025, + slack */ + +/* Number and (minimum) size of bigints in the nc_ctx structure. */ +#define DUK__NUMCONV_CTX_NUM_BIGINTS 7 +#define DUK__NUMCONV_CTX_BIGINTS_SIZE (sizeof(duk__bigint) * DUK__NUMCONV_CTX_NUM_BIGINTS) + +typedef struct { + /* Currently about 7*152 = 1064 bytes. The space for these + * duk__bigints is used also as a temporary buffer for generating + * the final string. This is a bit awkard; a union would be + * more correct. + */ + duk__bigint f, r, s, mp, mm, t1, t2; + + duk_small_int_t is_s2n; /* if 1, doing a string-to-number; else doing a number-to-string */ + duk_small_int_t is_fixed; /* if 1, doing a fixed format output (not free format) */ + duk_small_int_t req_digits; /* requested number of output digits; 0 = free-format */ + duk_small_int_t abs_pos; /* digit position is absolute, not relative */ + duk_small_int_t e; /* exponent for 'f' */ + duk_small_int_t b; /* input radix */ + duk_small_int_t B; /* output radix */ + duk_small_int_t k; /* see algorithm */ + duk_small_int_t low_ok; /* see algorithm */ + duk_small_int_t high_ok; /* see algorithm */ + duk_small_int_t unequal_gaps; /* m+ != m- (very rarely) */ + + /* Buffer used for generated digits, values are in the range [0,B-1]. */ + duk_uint8_t digits[DUK__MAX_OUTPUT_DIGITS]; + duk_small_int_t count; /* digit count */ +} duk__numconv_stringify_ctx; + +/* Note: computes with 'idx' in assertions, so caller beware. + * 'idx' is preincremented, i.e. '1' on first call, because it + * is more convenient for the caller. + */ +#define DUK__DRAGON4_OUTPUT_PREINC(nc_ctx,preinc_idx,x) do { \ + DUK_ASSERT((preinc_idx) - 1 >= 0); \ + DUK_ASSERT((preinc_idx) - 1 < DUK__MAX_OUTPUT_DIGITS); \ + ((nc_ctx)->digits[(preinc_idx) - 1]) = (duk_uint8_t) (x); \ + } while (0) + +DUK_LOCAL duk_size_t duk__dragon4_format_uint32(duk_uint8_t *buf, duk_uint32_t x, duk_small_int_t radix) { + duk_uint8_t *p; + duk_size_t len; + duk_small_int_t dig; + duk_uint32_t t; + + DUK_ASSERT(buf != NULL); + DUK_ASSERT(radix >= 2 && radix <= 36); + + /* A 32-bit unsigned integer formats to at most 32 digits (the + * worst case happens with radix == 2). Output the digits backwards, + * and use a memmove() to get them in the right place. + */ + + p = buf + 32; + for (;;) { + t = x / (duk_uint32_t) radix; + dig = (duk_small_int_t) (x - t * (duk_uint32_t) radix); + x = t; + + DUK_ASSERT(dig >= 0 && dig < 36); + *(--p) = DUK__DIGITCHAR(dig); + + if (x == 0) { + break; + } + } + len = (duk_size_t) ((buf + 32) - p); + + duk_memmove((void *) buf, (const void *) p, (size_t) len); + + return len; +} + +DUK_LOCAL void duk__dragon4_prepare(duk__numconv_stringify_ctx *nc_ctx) { + duk_small_int_t lowest_mantissa; + +#if 1 + /* Assume IEEE round-to-even, so that shorter encoding can be used + * when round-to-even would produce correct result. By removing + * this check (and having low_ok == high_ok == 0) the results would + * still be accurate but in some cases longer than necessary. + */ + if (duk__bi_is_even(&nc_ctx->f)) { + DUK_DDD(DUK_DDDPRINT("f is even")); + nc_ctx->low_ok = 1; + nc_ctx->high_ok = 1; + } else { + DUK_DDD(DUK_DDDPRINT("f is odd")); + nc_ctx->low_ok = 0; + nc_ctx->high_ok = 0; + } +#else + /* Note: not honoring round-to-even should work but now generates incorrect + * results. For instance, 1e23 serializes to "a000...", i.e. the first digit + * equals the radix (10). Scaling stops one step too early in this case. + * Don't know why this is the case, but since this code path is unused, it + * doesn't matter. + */ + nc_ctx->low_ok = 0; + nc_ctx->high_ok = 0; +#endif + + /* For string-to-number, pretend we never have the lowest mantissa as there + * is no natural "precision" for inputs. Having lowest_mantissa == 0, we'll + * fall into the base cases for both e >= 0 and e < 0. + */ + if (nc_ctx->is_s2n) { + lowest_mantissa = 0; + } else { + lowest_mantissa = duk__bi_is_2to52(&nc_ctx->f); + } + + nc_ctx->unequal_gaps = 0; + if (nc_ctx->e >= 0) { + /* exponent non-negative (and thus not minimum exponent) */ + + if (lowest_mantissa) { + /* (>= e 0) AND (= f (expt b (- p 1))) + * + * be <- (expt b e) == b^e + * be1 <- (* be b) == (expt b (+ e 1)) == b^(e+1) + * r <- (* f be1 2) == 2 * f * b^(e+1) [if b==2 -> f * b^(e+2)] + * s <- (* b 2) [if b==2 -> 4] + * m+ <- be1 == b^(e+1) + * m- <- be == b^e + * k <- 0 + * B <- B + * low_ok <- round + * high_ok <- round + */ + + DUK_DDD(DUK_DDDPRINT("non-negative exponent (not smallest exponent); " + "lowest mantissa value for this exponent -> " + "unequal gaps")); + + duk__bi_exp_small(&nc_ctx->mm, nc_ctx->b, nc_ctx->e, &nc_ctx->t1, &nc_ctx->t2); /* mm <- b^e */ + duk__bi_mul_small(&nc_ctx->mp, &nc_ctx->mm, (duk_uint32_t) nc_ctx->b); /* mp <- b^(e+1) */ + duk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, 2); + duk__bi_mul(&nc_ctx->r, &nc_ctx->t1, &nc_ctx->mp); /* r <- (2 * f) * b^(e+1) */ + duk__bi_set_small(&nc_ctx->s, (duk_uint32_t) (nc_ctx->b * 2)); /* s <- 2 * b */ + nc_ctx->unequal_gaps = 1; + } else { + /* (>= e 0) AND (not (= f (expt b (- p 1)))) + * + * be <- (expt b e) == b^e + * r <- (* f be 2) == 2 * f * b^e [if b==2 -> f * b^(e+1)] + * s <- 2 + * m+ <- be == b^e + * m- <- be == b^e + * k <- 0 + * B <- B + * low_ok <- round + * high_ok <- round + */ + + DUK_DDD(DUK_DDDPRINT("non-negative exponent (not smallest exponent); " + "not lowest mantissa for this exponent -> " + "equal gaps")); + + duk__bi_exp_small(&nc_ctx->mm, nc_ctx->b, nc_ctx->e, &nc_ctx->t1, &nc_ctx->t2); /* mm <- b^e */ + duk__bi_copy(&nc_ctx->mp, &nc_ctx->mm); /* mp <- b^e */ + duk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, 2); + duk__bi_mul(&nc_ctx->r, &nc_ctx->t1, &nc_ctx->mp); /* r <- (2 * f) * b^e */ + duk__bi_set_small(&nc_ctx->s, 2); /* s <- 2 */ + } + } else { + /* When doing string-to-number, lowest_mantissa is always 0 so + * the exponent check, while incorrect, won't matter. + */ + if (nc_ctx->e > DUK__IEEE_DOUBLE_EXP_MIN /*not minimum exponent*/ && + lowest_mantissa /* lowest mantissa for this exponent*/) { + /* r <- (* f b 2) [if b==2 -> (* f 4)] + * s <- (* (expt b (- 1 e)) 2) == b^(1-e) * 2 [if b==2 -> b^(2-e)] + * m+ <- b == 2 + * m- <- 1 + * k <- 0 + * B <- B + * low_ok <- round + * high_ok <- round + */ + + DUK_DDD(DUK_DDDPRINT("negative exponent; not minimum exponent and " + "lowest mantissa for this exponent -> " + "unequal gaps")); + + duk__bi_mul_small(&nc_ctx->r, &nc_ctx->f, (duk_uint32_t) (nc_ctx->b * 2)); /* r <- (2 * b) * f */ + duk__bi_exp_small(&nc_ctx->t1, nc_ctx->b, 1 - nc_ctx->e, &nc_ctx->s, &nc_ctx->t2); /* NB: use 's' as temp on purpose */ + duk__bi_mul_small(&nc_ctx->s, &nc_ctx->t1, 2); /* s <- b^(1-e) * 2 */ + duk__bi_set_small(&nc_ctx->mp, 2); + duk__bi_set_small(&nc_ctx->mm, 1); + nc_ctx->unequal_gaps = 1; + } else { + /* r <- (* f 2) + * s <- (* (expt b (- e)) 2) == b^(-e) * 2 [if b==2 -> b^(1-e)] + * m+ <- 1 + * m- <- 1 + * k <- 0 + * B <- B + * low_ok <- round + * high_ok <- round + */ + + DUK_DDD(DUK_DDDPRINT("negative exponent; minimum exponent or not " + "lowest mantissa for this exponent -> " + "equal gaps")); + + duk__bi_mul_small(&nc_ctx->r, &nc_ctx->f, 2); /* r <- 2 * f */ + duk__bi_exp_small(&nc_ctx->t1, nc_ctx->b, -nc_ctx->e, &nc_ctx->s, &nc_ctx->t2); /* NB: use 's' as temp on purpose */ + duk__bi_mul_small(&nc_ctx->s, &nc_ctx->t1, 2); /* s <- b^(-e) * 2 */ + duk__bi_set_small(&nc_ctx->mp, 1); + duk__bi_set_small(&nc_ctx->mm, 1); + } + } +} + +DUK_LOCAL void duk__dragon4_scale(duk__numconv_stringify_ctx *nc_ctx) { + duk_small_int_t k = 0; + + /* This is essentially the 'scale' algorithm, with recursion removed. + * Note that 'k' is either correct immediately, or will move in one + * direction in the loop. There's no need to do the low/high checks + * on every round (like the Scheme algorithm does). + * + * The scheme algorithm finds 'k' and updates 's' simultaneously, + * while the logical algorithm finds 'k' with 's' having its initial + * value, after which 's' is updated separately (see the Burger-Dybvig + * paper, Section 3.1, steps 2 and 3). + * + * The case where m+ == m- (almost always) is optimized for, because + * it reduces the bigint operations considerably and almost always + * applies. The scale loop only needs to work with m+, so this works. + */ + + /* XXX: this algorithm could be optimized quite a lot by using e.g. + * a logarithm based estimator for 'k' and performing B^n multiplication + * using a lookup table or using some bit-representation based exp + * algorithm. Currently we just loop, with significant performance + * impact for very large and very small numbers. + */ + + DUK_DDD(DUK_DDDPRINT("scale: B=%ld, low_ok=%ld, high_ok=%ld", + (long) nc_ctx->B, (long) nc_ctx->low_ok, (long) nc_ctx->high_ok)); + DUK__BI_PRINT("r(init)", &nc_ctx->r); + DUK__BI_PRINT("s(init)", &nc_ctx->s); + DUK__BI_PRINT("mp(init)", &nc_ctx->mp); + DUK__BI_PRINT("mm(init)", &nc_ctx->mm); + + for (;;) { + DUK_DDD(DUK_DDDPRINT("scale loop (inc k), k=%ld", (long) k)); + DUK__BI_PRINT("r", &nc_ctx->r); + DUK__BI_PRINT("s", &nc_ctx->s); + DUK__BI_PRINT("m+", &nc_ctx->mp); + DUK__BI_PRINT("m-", &nc_ctx->mm); + + duk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp); /* t1 = (+ r m+) */ + if (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) >= (nc_ctx->high_ok ? 0 : 1)) { + DUK_DDD(DUK_DDDPRINT("k is too low")); + /* r <- r + * s <- (* s B) + * m+ <- m+ + * m- <- m- + * k <- (+ k 1) + */ + + duk__bi_mul_small_copy(&nc_ctx->s, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1); + k++; + } else { + break; + } + } + + /* k > 0 -> k was too low, and cannot be too high */ + if (k > 0) { + goto skip_dec_k; + } + + for (;;) { + DUK_DDD(DUK_DDDPRINT("scale loop (dec k), k=%ld", (long) k)); + DUK__BI_PRINT("r", &nc_ctx->r); + DUK__BI_PRINT("s", &nc_ctx->s); + DUK__BI_PRINT("m+", &nc_ctx->mp); + DUK__BI_PRINT("m-", &nc_ctx->mm); + + duk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp); /* t1 = (+ r m+) */ + duk__bi_mul_small(&nc_ctx->t2, &nc_ctx->t1, (duk_uint32_t) nc_ctx->B); /* t2 = (* (+ r m+) B) */ + if (duk__bi_compare(&nc_ctx->t2, &nc_ctx->s) <= (nc_ctx->high_ok ? -1 : 0)) { + DUK_DDD(DUK_DDDPRINT("k is too high")); + /* r <- (* r B) + * s <- s + * m+ <- (* m+ B) + * m- <- (* m- B) + * k <- (- k 1) + */ + duk__bi_mul_small_copy(&nc_ctx->r, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1); + duk__bi_mul_small_copy(&nc_ctx->mp, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1); + if (nc_ctx->unequal_gaps) { + DUK_DDD(DUK_DDDPRINT("m+ != m- -> need to update m- too")); + duk__bi_mul_small_copy(&nc_ctx->mm, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1); + } + k--; + } else { + break; + } + } + + skip_dec_k: + + if (!nc_ctx->unequal_gaps) { + DUK_DDD(DUK_DDDPRINT("equal gaps, copy m- from m+")); + duk__bi_copy(&nc_ctx->mm, &nc_ctx->mp); /* mm <- mp */ + } + nc_ctx->k = k; + + DUK_DDD(DUK_DDDPRINT("final k: %ld", (long) k)); + DUK__BI_PRINT("r(final)", &nc_ctx->r); + DUK__BI_PRINT("s(final)", &nc_ctx->s); + DUK__BI_PRINT("mp(final)", &nc_ctx->mp); + DUK__BI_PRINT("mm(final)", &nc_ctx->mm); +} + +DUK_LOCAL void duk__dragon4_generate(duk__numconv_stringify_ctx *nc_ctx) { + duk_small_int_t tc1, tc2; /* terminating conditions */ + duk_small_int_t d; /* current digit */ + duk_small_int_t count = 0; /* digit count */ + + /* + * Digit generation loop. + * + * Different termination conditions: + * + * 1. Free format output. Terminate when shortest accurate + * representation found. + * + * 2. Fixed format output, with specific number of digits. + * Ignore termination conditions, terminate when digits + * generated. Caller requests an extra digit and rounds. + * + * 3. Fixed format output, with a specific absolute cut-off + * position (e.g. 10 digits after decimal point). Note + * that we always generate at least one digit, even if + * the digit is below the cut-off point already. + */ + + for (;;) { + DUK_DDD(DUK_DDDPRINT("generate loop, count=%ld, k=%ld, B=%ld, low_ok=%ld, high_ok=%ld", + (long) count, (long) nc_ctx->k, (long) nc_ctx->B, + (long) nc_ctx->low_ok, (long) nc_ctx->high_ok)); + DUK__BI_PRINT("r", &nc_ctx->r); + DUK__BI_PRINT("s", &nc_ctx->s); + DUK__BI_PRINT("m+", &nc_ctx->mp); + DUK__BI_PRINT("m-", &nc_ctx->mm); + + /* (quotient-remainder (* r B) s) using a dummy subtraction loop */ + duk__bi_mul_small(&nc_ctx->t1, &nc_ctx->r, (duk_uint32_t) nc_ctx->B); /* t1 <- (* r B) */ + d = 0; + for (;;) { + if (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) < 0) { + break; + } + duk__bi_sub_copy(&nc_ctx->t1, &nc_ctx->s, &nc_ctx->t2); /* t1 <- t1 - s */ + d++; + } + duk__bi_copy(&nc_ctx->r, &nc_ctx->t1); /* r <- (remainder (* r B) s) */ + /* d <- (quotient (* r B) s) (in range 0...B-1) */ + DUK_DDD(DUK_DDDPRINT("-> d(quot)=%ld", (long) d)); + DUK__BI_PRINT("r(rem)", &nc_ctx->r); + + duk__bi_mul_small_copy(&nc_ctx->mp, (duk_uint32_t) nc_ctx->B, &nc_ctx->t2); /* m+ <- (* m+ B) */ + duk__bi_mul_small_copy(&nc_ctx->mm, (duk_uint32_t) nc_ctx->B, &nc_ctx->t2); /* m- <- (* m- B) */ + DUK__BI_PRINT("mp(upd)", &nc_ctx->mp); + DUK__BI_PRINT("mm(upd)", &nc_ctx->mm); + + /* Terminating conditions. For fixed width output, we just ignore the + * terminating conditions (and pretend that tc1 == tc2 == false). The + * the current shortcut for fixed-format output is to generate a few + * extra digits and use rounding (with carry) to finish the output. + */ + + if (nc_ctx->is_fixed == 0) { + /* free-form */ + tc1 = (duk__bi_compare(&nc_ctx->r, &nc_ctx->mm) <= (nc_ctx->low_ok ? 0 : -1)); + + duk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp); /* t1 <- (+ r m+) */ + tc2 = (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) >= (nc_ctx->high_ok ? 0 : 1)); + + DUK_DDD(DUK_DDDPRINT("tc1=%ld, tc2=%ld", (long) tc1, (long) tc2)); + } else { + /* fixed-format */ + tc1 = 0; + tc2 = 0; + } + + /* Count is incremented before DUK__DRAGON4_OUTPUT_PREINC() call + * on purpose, which is taken into account by the macro. + */ + count++; + + if (tc1) { + if (tc2) { + /* tc1 = true, tc2 = true */ + duk__bi_mul_small(&nc_ctx->t1, &nc_ctx->r, 2); + if (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) < 0) { /* (< (* r 2) s) */ + DUK_DDD(DUK_DDDPRINT("tc1=true, tc2=true, 2r > s: output d --> %ld (k=%ld)", + (long) d, (long) nc_ctx->k)); + DUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d); + } else { + DUK_DDD(DUK_DDDPRINT("tc1=true, tc2=true, 2r <= s: output d+1 --> %ld (k=%ld)", + (long) (d + 1), (long) nc_ctx->k)); + DUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d + 1); + } + break; + } else { + /* tc1 = true, tc2 = false */ + DUK_DDD(DUK_DDDPRINT("tc1=true, tc2=false: output d --> %ld (k=%ld)", + (long) d, (long) nc_ctx->k)); + DUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d); + break; + } + } else { + if (tc2) { + /* tc1 = false, tc2 = true */ + DUK_DDD(DUK_DDDPRINT("tc1=false, tc2=true: output d+1 --> %ld (k=%ld)", + (long) (d + 1), (long) nc_ctx->k)); + DUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d + 1); + break; + } else { + /* tc1 = false, tc2 = false */ + DUK_DDD(DUK_DDDPRINT("tc1=false, tc2=false: output d --> %ld (k=%ld)", + (long) d, (long) nc_ctx->k)); + DUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d); + + /* r <- r (updated above: r <- (remainder (* r B) s) + * s <- s + * m+ <- m+ (updated above: m+ <- (* m+ B) + * m- <- m- (updated above: m- <- (* m- B) + * B, low_ok, high_ok are fixed + */ + + /* fall through and continue for-loop */ + } + } + + /* fixed-format termination conditions */ + if (nc_ctx->is_fixed) { + if (nc_ctx->abs_pos) { + int pos = nc_ctx->k - count + 1; /* count is already incremented, take into account */ + DUK_DDD(DUK_DDDPRINT("fixed format, absolute: abs pos=%ld, k=%ld, count=%ld, req=%ld", + (long) pos, (long) nc_ctx->k, (long) count, (long) nc_ctx->req_digits)); + if (pos <= nc_ctx->req_digits) { + DUK_DDD(DUK_DDDPRINT("digit position reached req_digits, end generate loop")); + break; + } + } else { + DUK_DDD(DUK_DDDPRINT("fixed format, relative: k=%ld, count=%ld, req=%ld", + (long) nc_ctx->k, (long) count, (long) nc_ctx->req_digits)); + if (count >= nc_ctx->req_digits) { + DUK_DDD(DUK_DDDPRINT("digit count reached req_digits, end generate loop")); + break; + } + } + } + } /* for */ + + nc_ctx->count = count; + + DUK_DDD(DUK_DDDPRINT("generate finished")); + +#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2) + { + duk_uint8_t buf[2048]; + duk_small_int_t i, t; + duk_memzero(buf, sizeof(buf)); + for (i = 0; i < nc_ctx->count; i++) { + t = nc_ctx->digits[i]; + if (t < 0 || t > 36) { + buf[i] = (duk_uint8_t) '?'; + } else { + buf[i] = (duk_uint8_t) DUK__DIGITCHAR(t); + } + } + DUK_DDD(DUK_DDDPRINT("-> generated digits; k=%ld, digits='%s'", + (long) nc_ctx->k, (const char *) buf)); + } +#endif +} + +/* Round up digits to a given position. If position is out-of-bounds, + * does nothing. If carry propagates over the first digit, a '1' is + * prepended to digits and 'k' will be updated. Return value indicates + * whether carry propagated over the first digit. + * + * Note that nc_ctx->count is NOT updated based on the rounding position + * (it is updated only if carry overflows over the first digit and an + * extra digit is prepended). + */ +DUK_LOCAL duk_small_int_t duk__dragon4_fixed_format_round(duk__numconv_stringify_ctx *nc_ctx, duk_small_int_t round_idx) { + duk_small_int_t t; + duk_uint8_t *p; + duk_uint8_t roundup_limit; + duk_small_int_t ret = 0; + + /* + * round_idx points to the digit which is considered for rounding; the + * digit to its left is the final digit of the rounded value. If round_idx + * is zero, rounding will be performed; the result will either be an empty + * rounded value or if carry happens a '1' digit is generated. + */ + + if (round_idx >= nc_ctx->count) { + DUK_DDD(DUK_DDDPRINT("round_idx out of bounds (%ld >= %ld (count)) -> no rounding", + (long) round_idx, (long) nc_ctx->count)); + return 0; + } else if (round_idx < 0) { + DUK_DDD(DUK_DDDPRINT("round_idx out of bounds (%ld < 0) -> no rounding", + (long) round_idx)); + return 0; + } + + /* + * Round-up limit. + * + * For even values, divides evenly, e.g. 10 -> roundup_limit=5. + * + * For odd values, rounds up, e.g. 3 -> roundup_limit=2. + * If radix is 3, 0/3 -> down, 1/3 -> down, 2/3 -> up. + */ + roundup_limit = (duk_uint8_t) ((nc_ctx->B + 1) / 2); + + p = &nc_ctx->digits[round_idx]; + if (*p >= roundup_limit) { + DUK_DDD(DUK_DDDPRINT("fixed-format rounding carry required")); + /* carry */ + for (;;) { + *p = 0; + if (p == &nc_ctx->digits[0]) { + DUK_DDD(DUK_DDDPRINT("carry propagated to first digit -> special case handling")); + duk_memmove((void *) (&nc_ctx->digits[1]), + (const void *) (&nc_ctx->digits[0]), + (size_t) (sizeof(char) * (size_t) nc_ctx->count)); + nc_ctx->digits[0] = 1; /* don't increase 'count' */ + nc_ctx->k++; /* position of highest digit changed */ + nc_ctx->count++; /* number of digits changed */ + ret = 1; + break; + } + + DUK_DDD(DUK_DDDPRINT("fixed-format rounding carry: B=%ld, roundup_limit=%ld, p=%p, digits=%p", + (long) nc_ctx->B, (long) roundup_limit, (void *) p, (void *) nc_ctx->digits)); + p--; + t = *p; + DUK_DDD(DUK_DDDPRINT("digit before carry: %ld", (long) t)); + if (++t < nc_ctx->B) { + DUK_DDD(DUK_DDDPRINT("rounding carry terminated")); + *p = (duk_uint8_t) t; + break; + } + + DUK_DDD(DUK_DDDPRINT("wraps, carry to next digit")); + } + } + + return ret; +} + +#define DUK__NO_EXP (65536) /* arbitrary marker, outside valid exp range */ + +DUK_LOCAL void duk__dragon4_convert_and_push(duk__numconv_stringify_ctx *nc_ctx, + duk_hthread *thr, + duk_small_int_t radix, + duk_small_int_t digits, + duk_small_uint_t flags, + duk_small_int_t neg) { + duk_small_int_t k; + duk_small_int_t pos, pos_end; + duk_small_int_t expt; + duk_small_int_t dig; + duk_uint8_t *q; + duk_uint8_t *buf; + + /* + * The string conversion here incorporates all the necessary ECMAScript + * semantics without attempting to be generic. nc_ctx->digits contains + * nc_ctx->count digits (>= 1), with the topmost digit's 'position' + * indicated by nc_ctx->k as follows: + * + * digits="123" count=3 k=0 --> 0.123 + * digits="123" count=3 k=1 --> 1.23 + * digits="123" count=3 k=5 --> 12300 + * digits="123" count=3 k=-1 --> 0.0123 + * + * Note that the identifier names used for format selection are different + * in Burger-Dybvig paper and ECMAScript specification (quite confusingly + * so, because e.g. 'k' has a totally different meaning in each). See + * documentation for discussion. + * + * ECMAScript doesn't specify any specific behavior for format selection + * (e.g. when to use exponent notation) for non-base-10 numbers. + * + * The bigint space in the context is reused for string output, as there + * is more than enough space for that (>1kB at the moment), and we avoid + * allocating even more stack. + */ + + DUK_ASSERT(DUK__NUMCONV_CTX_BIGINTS_SIZE >= DUK__MAX_FORMATTED_LENGTH); + DUK_ASSERT(nc_ctx->count >= 1); + + k = nc_ctx->k; + buf = (duk_uint8_t *) &nc_ctx->f; /* XXX: union would be more correct */ + q = buf; + + /* Exponent handling: if exponent format is used, record exponent value and + * fake k such that one leading digit is generated (e.g. digits=123 -> "1.23"). + * + * toFixed() prevents exponent use; otherwise apply a set of criteria to + * match the other API calls (toString(), toPrecision, etc). + */ + + expt = DUK__NO_EXP; + if (!nc_ctx->abs_pos /* toFixed() */) { + if ((flags & DUK_N2S_FLAG_FORCE_EXP) || /* exponential notation forced */ + ((flags & DUK_N2S_FLAG_NO_ZERO_PAD) && /* fixed precision and zero padding would be required */ + (k - digits >= 1)) || /* (e.g. k=3, digits=2 -> "12X") */ + ((k > 21 || k <= -6) && (radix == 10))) { /* toString() conditions */ + DUK_DDD(DUK_DDDPRINT("use exponential notation: k=%ld -> expt=%ld", + (long) k, (long) (k - 1))); + expt = k - 1; /* e.g. 12.3 -> digits="123" k=2 -> 1.23e1 */ + k = 1; /* generate mantissa with a single leading whole number digit */ + } + } + + if (neg) { + *q++ = '-'; + } + + /* Start position (inclusive) and end position (exclusive) */ + pos = (k >= 1 ? k : 1); + if (nc_ctx->is_fixed) { + if (nc_ctx->abs_pos) { + /* toFixed() */ + pos_end = -digits; + } else { + pos_end = k - digits; + } + } else { + pos_end = k - nc_ctx->count; + } + if (pos_end > 0) { + pos_end = 0; + } + + DUK_DDD(DUK_DDDPRINT("expt=%ld, k=%ld, count=%ld, pos=%ld, pos_end=%ld, is_fixed=%ld, " + "digits=%ld, abs_pos=%ld", + (long) expt, (long) k, (long) nc_ctx->count, (long) pos, (long) pos_end, + (long) nc_ctx->is_fixed, (long) digits, (long) nc_ctx->abs_pos)); + + /* Digit generation */ + while (pos > pos_end) { + DUK_DDD(DUK_DDDPRINT("digit generation: pos=%ld, pos_end=%ld", + (long) pos, (long) pos_end)); + if (pos == 0) { + *q++ = (duk_uint8_t) '.'; + } + if (pos > k) { + *q++ = (duk_uint8_t) '0'; + } else if (pos <= k - nc_ctx->count) { + *q++ = (duk_uint8_t) '0'; + } else { + dig = nc_ctx->digits[k - pos]; + DUK_ASSERT(dig >= 0 && dig < nc_ctx->B); + *q++ = (duk_uint8_t) DUK__DIGITCHAR(dig); + } + + pos--; + } + DUK_ASSERT(pos <= 1); + + /* Exponent */ + if (expt != DUK__NO_EXP) { + /* + * Exponent notation for non-base-10 numbers isn't specified in ECMAScript + * specification, as it never explicitly turns up: non-decimal numbers can + * only be formatted with Number.prototype.toString([radix]) and for that, + * behavior is not explicitly specified. + * + * Logical choices include formatting the exponent as decimal (e.g. binary + * 100000 as 1e+5) or in current radix (e.g. binary 100000 as 1e+101). + * The Dragon4 algorithm (in the original paper) prints the exponent value + * in the target radix B. However, for radix values 15 and above, the + * exponent separator 'e' is no longer easily parseable. Consider, for + * instance, the number "1.faecee+1c". + */ + + duk_size_t len; + char expt_sign; + + *q++ = 'e'; + if (expt >= 0) { + expt_sign = '+'; + } else { + expt_sign = '-'; + expt = -expt; + } + *q++ = (duk_uint8_t) expt_sign; + len = duk__dragon4_format_uint32(q, (duk_uint32_t) expt, radix); + q += len; + } + + duk_push_lstring(thr, (const char *) buf, (size_t) (q - buf)); +} + +/* + * Conversion helpers + */ + +DUK_LOCAL void duk__dragon4_double_to_ctx(duk__numconv_stringify_ctx *nc_ctx, duk_double_t x) { + duk_double_union u; + duk_uint32_t tmp; + duk_small_int_t expt; + + /* + * seeeeeee eeeeffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff + * A B C D E F G H + * + * s sign bit + * eee... exponent field + * fff... fraction + * + * ieee value = 1.ffff... * 2^(e - 1023) (normal) + * = 0.ffff... * 2^(-1022) (denormal) + * + * algorithm v = f * b^e + */ + + DUK_DBLUNION_SET_DOUBLE(&u, x); + + nc_ctx->f.n = 2; + + tmp = DUK_DBLUNION_GET_LOW32(&u); + nc_ctx->f.v[0] = tmp; + tmp = DUK_DBLUNION_GET_HIGH32(&u); + nc_ctx->f.v[1] = tmp & 0x000fffffUL; + expt = (duk_small_int_t) ((tmp >> 20) & 0x07ffUL); + + if (expt == 0) { + /* denormal */ + expt = DUK__IEEE_DOUBLE_EXP_MIN - 52; + duk__bi_normalize(&nc_ctx->f); + } else { + /* normal: implicit leading 1-bit */ + nc_ctx->f.v[1] |= 0x00100000UL; + expt = expt - DUK__IEEE_DOUBLE_EXP_BIAS - 52; + DUK_ASSERT(duk__bi_is_valid(&nc_ctx->f)); /* true, because v[1] has at least one bit set */ + } + + DUK_ASSERT(duk__bi_is_valid(&nc_ctx->f)); + + nc_ctx->e = expt; +} + +DUK_LOCAL void duk__dragon4_ctx_to_double(duk__numconv_stringify_ctx *nc_ctx, duk_double_t *x) { + duk_double_union u; + duk_small_int_t expt; + duk_small_int_t i; + duk_small_int_t bitstart; + duk_small_int_t bitround; + duk_small_int_t bitidx; + duk_small_int_t skip_round; + duk_uint32_t t, v; + + DUK_ASSERT(nc_ctx->count == 53 + 1); + + /* Sometimes this assert is not true right now; it will be true after + * rounding. See: test-bug-numconv-mantissa-assert.js. + */ + DUK_ASSERT_DISABLE(nc_ctx->digits[0] == 1); /* zero handled by caller */ + + /* Should not be required because the code below always sets both high + * and low parts, but at least gcc-4.4.5 fails to deduce this correctly + * (perhaps because the low part is set (seemingly) conditionally in a + * loop), so this is here to avoid the bogus warning. + */ + duk_memzero((void *) &u, sizeof(u)); + + /* + * Figure out how generated digits match up with the mantissa, + * and then perform rounding. If mantissa overflows, need to + * recompute the exponent (it is bumped and may overflow to + * infinity). + * + * For normal numbers the leading '1' is hidden and ignored, + * and the last bit is used for rounding: + * + * rounding pt + * <--------52------->| + * 1 x x x x ... x x x x|y ==> x x x x ... x x x x + * + * For denormals, the leading '1' is included in the number, + * and the rounding point is different: + * + * rounding pt + * <--52 or less--->| + * 1 x x x x ... x x|x x y ==> 0 0 ... 1 x x ... x x + * + * The largest denormals will have a mantissa beginning with + * a '1' (the explicit leading bit); smaller denormals will + * have leading zero bits. + * + * If the exponent would become too high, the result becomes + * Infinity. If the exponent is so small that the entire + * mantissa becomes zero, the result becomes zero. + * + * Note: the Dragon4 'k' is off-by-one with respect to the IEEE + * exponent. For instance, k==0 indicates that the leading '1' + * digit is at the first binary fraction position (0.1xxx...); + * the corresponding IEEE exponent would be -1. + */ + + skip_round = 0; + + recheck_exp: + + expt = nc_ctx->k - 1; /* IEEE exp without bias */ + if (expt > 1023) { + /* Infinity */ + bitstart = -255; /* needed for inf: causes mantissa to become zero, + * and rounding to be skipped. + */ + expt = 2047; + } else if (expt >= -1022) { + /* normal */ + bitstart = 1; /* skip leading digit */ + expt += DUK__IEEE_DOUBLE_EXP_BIAS; + DUK_ASSERT(expt >= 1 && expt <= 2046); + } else { + /* denormal or zero */ + bitstart = 1023 + expt; /* expt==-1023 -> bitstart=0 (leading 1); + * expt==-1024 -> bitstart=-1 (one left of leading 1), etc + */ + expt = 0; + } + bitround = bitstart + 52; + + DUK_DDD(DUK_DDDPRINT("ieee expt=%ld, bitstart=%ld, bitround=%ld", + (long) expt, (long) bitstart, (long) bitround)); + + if (!skip_round) { + if (duk__dragon4_fixed_format_round(nc_ctx, bitround)) { + /* Corner case: see test-numconv-parse-mant-carry.js. We could + * just bump the exponent and update bitstart, but it's more robust + * to recompute (but avoid rounding twice). + */ + DUK_DDD(DUK_DDDPRINT("rounding caused exponent to be bumped, recheck exponent")); + skip_round = 1; + goto recheck_exp; + } + } + + /* + * Create mantissa + */ + + t = 0; + for (i = 0; i < 52; i++) { + bitidx = bitstart + 52 - 1 - i; + if (bitidx >= nc_ctx->count) { + v = 0; + } else if (bitidx < 0) { + v = 0; + } else { + v = nc_ctx->digits[bitidx]; + } + DUK_ASSERT(v == 0 || v == 1); + t += v << (i % 32); + if (i == 31) { + /* low 32 bits is complete */ + DUK_DBLUNION_SET_LOW32(&u, t); + t = 0; + } + } + /* t has high mantissa */ + + DUK_DDD(DUK_DDDPRINT("mantissa is complete: %08lx %08lx", + (unsigned long) t, + (unsigned long) DUK_DBLUNION_GET_LOW32(&u))); + + DUK_ASSERT(expt >= 0 && expt <= 0x7ffL); + t += ((duk_uint32_t) expt) << 20; +#if 0 /* caller handles sign change */ + if (negative) { + t |= 0x80000000U; + } +#endif + DUK_DBLUNION_SET_HIGH32(&u, t); + + DUK_DDD(DUK_DDDPRINT("number is complete: %08lx %08lx", + (unsigned long) DUK_DBLUNION_GET_HIGH32(&u), + (unsigned long) DUK_DBLUNION_GET_LOW32(&u))); + + *x = DUK_DBLUNION_GET_DOUBLE(&u); +} + +/* + * Exposed number-to-string API + * + * Input: [ number ] + * Output: [ string ] + */ + +DUK_LOCAL DUK_NOINLINE void duk__numconv_stringify_raw(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags) { + duk_double_t x; + duk_small_int_t c; + duk_small_int_t neg; + duk_uint32_t uval; + duk__numconv_stringify_ctx nc_ctx_alloc; /* large context; around 2kB now */ + duk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc; + + x = (duk_double_t) duk_require_number(thr, -1); + duk_pop(thr); + + /* + * Handle special cases (NaN, infinity, zero). + */ + + c = (duk_small_int_t) DUK_FPCLASSIFY(x); + if (DUK_SIGNBIT((double) x)) { + x = -x; + neg = 1; + } else { + neg = 0; + } + + /* NaN sign bit is platform specific with unpacked, un-normalized NaNs */ + DUK_ASSERT(c == DUK_FP_NAN || DUK_SIGNBIT((double) x) == 0); + + if (c == DUK_FP_NAN) { + duk_push_hstring_stridx(thr, DUK_STRIDX_NAN); + return; + } else if (c == DUK_FP_INFINITE) { + if (neg) { + /* -Infinity */ + duk_push_hstring_stridx(thr, DUK_STRIDX_MINUS_INFINITY); + } else { + /* Infinity */ + duk_push_hstring_stridx(thr, DUK_STRIDX_INFINITY); + } + return; + } else if (c == DUK_FP_ZERO) { + /* We can't shortcut zero here if it goes through special formatting + * (such as forced exponential notation). + */ + ; + } + + /* + * Handle integers in 32-bit range (that is, [-(2**32-1),2**32-1]) + * specially, as they're very likely for embedded programs. This + * is now done for all radix values. We must be careful not to use + * the fast path when special formatting (e.g. forced exponential) + * is in force. + * + * XXX: could save space by supporting radix 10 only and using + * sprintf "%lu" for the fast path and for exponent formatting. + */ + + uval = duk_double_to_uint32_t(x); + if (duk_double_equals((double) uval, x) && /* integer number in range */ + flags == 0) { /* no special formatting */ + /* use bigint area as a temp */ + duk_uint8_t *buf = (duk_uint8_t *) (&nc_ctx->f); + duk_uint8_t *p = buf; + + DUK_ASSERT(DUK__NUMCONV_CTX_BIGINTS_SIZE >= 32 + 1); /* max size: radix=2 + sign */ + if (neg && uval != 0) { + /* no negative sign for zero */ + *p++ = (duk_uint8_t) '-'; + } + p += duk__dragon4_format_uint32(p, uval, radix); + duk_push_lstring(thr, (const char *) buf, (duk_size_t) (p - buf)); + return; + } + + /* + * Dragon4 setup. + * + * Convert double from IEEE representation for conversion; + * normal finite values have an implicit leading 1-bit. The + * slow path algorithm doesn't handle zero, so zero is special + * cased here but still creates a valid nc_ctx, and goes + * through normal formatting in case special formatting has + * been requested (e.g. forced exponential format: 0 -> "0e+0"). + */ + + /* Would be nice to bulk clear the allocation, but the context + * is 1-2 kilobytes and nothing should rely on it being zeroed. + */ +#if 0 + duk_memzero((void *) nc_ctx, sizeof(*nc_ctx)); /* slow init, do only for slow path cases */ +#endif + + nc_ctx->is_s2n = 0; + nc_ctx->b = 2; + nc_ctx->B = radix; + nc_ctx->abs_pos = 0; + if (flags & DUK_N2S_FLAG_FIXED_FORMAT) { + nc_ctx->is_fixed = 1; + if (flags & DUK_N2S_FLAG_FRACTION_DIGITS) { + /* absolute req_digits; e.g. digits = 1 -> last digit is 0, + * but add an extra digit for rounding. + */ + nc_ctx->abs_pos = 1; + nc_ctx->req_digits = (-digits + 1) - 1; + } else { + nc_ctx->req_digits = digits + 1; + } + } else { + nc_ctx->is_fixed = 0; + nc_ctx->req_digits = 0; + } + + if (c == DUK_FP_ZERO) { + /* Zero special case: fake requested number of zero digits; ensure + * no sign bit is printed. Relative and absolute fixed format + * require separate handling. + */ + duk_small_int_t count; + if (nc_ctx->is_fixed) { + if (nc_ctx->abs_pos) { + count = digits + 2; /* lead zero + 'digits' fractions + 1 for rounding */ + } else { + count = digits + 1; /* + 1 for rounding */ + } + } else { + count = 1; + } + DUK_DDD(DUK_DDDPRINT("count=%ld", (long) count)); + DUK_ASSERT(count >= 1); + duk_memzero((void *) nc_ctx->digits, (size_t) count); + nc_ctx->count = count; + nc_ctx->k = 1; /* 0.000... */ + neg = 0; + goto zero_skip; + } + + duk__dragon4_double_to_ctx(nc_ctx, x); /* -> sets 'f' and 'e' */ + DUK__BI_PRINT("f", &nc_ctx->f); + DUK_DDD(DUK_DDDPRINT("e=%ld", (long) nc_ctx->e)); + + /* + * Dragon4 slow path digit generation. + */ + + duk__dragon4_prepare(nc_ctx); /* setup many variables in nc_ctx */ + + DUK_DDD(DUK_DDDPRINT("after prepare:")); + DUK__BI_PRINT("r", &nc_ctx->r); + DUK__BI_PRINT("s", &nc_ctx->s); + DUK__BI_PRINT("mp", &nc_ctx->mp); + DUK__BI_PRINT("mm", &nc_ctx->mm); + + duk__dragon4_scale(nc_ctx); + + DUK_DDD(DUK_DDDPRINT("after scale; k=%ld", (long) nc_ctx->k)); + DUK__BI_PRINT("r", &nc_ctx->r); + DUK__BI_PRINT("s", &nc_ctx->s); + DUK__BI_PRINT("mp", &nc_ctx->mp); + DUK__BI_PRINT("mm", &nc_ctx->mm); + + duk__dragon4_generate(nc_ctx); + + /* + * Convert and push final string. + */ + + zero_skip: + + if (flags & DUK_N2S_FLAG_FIXED_FORMAT) { + /* Perform fixed-format rounding. */ + duk_small_int_t roundpos; + if (flags & DUK_N2S_FLAG_FRACTION_DIGITS) { + /* 'roundpos' is relative to nc_ctx->k and increases to the right + * (opposite of how 'k' changes). + */ + roundpos = -digits; /* absolute position for digit considered for rounding */ + roundpos = nc_ctx->k - roundpos; + } else { + roundpos = digits; + } + DUK_DDD(DUK_DDDPRINT("rounding: k=%ld, count=%ld, digits=%ld, roundpos=%ld", + (long) nc_ctx->k, (long) nc_ctx->count, (long) digits, (long) roundpos)); + (void) duk__dragon4_fixed_format_round(nc_ctx, roundpos); + + /* Note: 'count' is currently not adjusted by rounding (i.e. the + * digits are not "chopped off". That shouldn't matter because + * the digit position (absolute or relative) is passed on to the + * convert-and-push function. + */ + } + + duk__dragon4_convert_and_push(nc_ctx, thr, radix, digits, flags, neg); +} + +DUK_INTERNAL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags) { + duk_native_stack_check(thr); + duk__numconv_stringify_raw(thr, radix, digits, flags); +} + +/* + * Exposed string-to-number API + * + * Input: [ string ] + * Output: [ number ] + * + * If number parsing fails, a NaN is pushed as the result. If number parsing + * fails due to an internal error, an InternalError is thrown. + */ + +DUK_LOCAL DUK_NOINLINE void duk__numconv_parse_raw(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags) { + duk__numconv_stringify_ctx nc_ctx_alloc; /* large context; around 2kB now */ + duk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc; + duk_double_t res; + duk_hstring *h_str; + duk_int_t expt; + duk_bool_t expt_neg; + duk_small_int_t expt_adj; + duk_small_int_t neg; + duk_small_int_t dig; + duk_small_int_t dig_whole; + duk_small_int_t dig_lzero; + duk_small_int_t dig_frac; + duk_small_int_t dig_expt; + duk_small_int_t dig_prec; + const duk__exp_limits *explim; + const duk_uint8_t *p; + duk_small_int_t ch; + + DUK_DDD(DUK_DDDPRINT("parse number: %!T, radix=%ld, flags=0x%08lx", + (duk_tval *) duk_get_tval(thr, -1), + (long) radix, (unsigned long) flags)); + + DUK_ASSERT(radix >= 2 && radix <= 36); + DUK_ASSERT(radix - 2 < (duk_small_int_t) sizeof(duk__str2num_digits_for_radix)); + + /* + * Preliminaries: trim, sign, Infinity check + * + * We rely on the interned string having a NUL terminator, which will + * cause a parse failure wherever it is encountered. As a result, we + * don't need separate pointer checks. + * + * There is no special parsing for 'NaN' in the specification although + * 'Infinity' (with an optional sign) is allowed in some contexts. + * Some contexts allow plus/minus sign, while others only allow the + * minus sign (like JSON.parse()). + * + * Automatic hex number detection (leading '0x' or '0X') and octal + * number detection (leading '0' followed by at least one octal digit) + * is done here too. + * + * Symbols are not explicitly rejected here (that's up to the caller). + * If a symbol were passed here, it should ultimately safely fail + * parsing due to a syntax error. + */ + + if (flags & DUK_S2N_FLAG_TRIM_WHITE) { + /* Leading / trailing whitespace is sometimes accepted and + * sometimes not. After white space trimming, all valid input + * characters are pure ASCII. + */ + duk_trim(thr, -1); + } + h_str = duk_require_hstring(thr, -1); + DUK_ASSERT(h_str != NULL); + p = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_str); + + neg = 0; + ch = *p; + if (ch == (duk_small_int_t) '+') { + if ((flags & DUK_S2N_FLAG_ALLOW_PLUS) == 0) { + DUK_DDD(DUK_DDDPRINT("parse failed: leading plus sign not allowed")); + goto parse_fail; + } + p++; + } else if (ch == (duk_small_int_t) '-') { + if ((flags & DUK_S2N_FLAG_ALLOW_MINUS) == 0) { + DUK_DDD(DUK_DDDPRINT("parse failed: leading minus sign not allowed")); + goto parse_fail; + } + p++; + neg = 1; + } + + if ((flags & DUK_S2N_FLAG_ALLOW_INF) && DUK_STRNCMP((const char *) p, "Infinity", 8) == 0) { + /* Don't check for Infinity unless the context allows it. + * 'Infinity' is a valid integer literal in e.g. base-36: + * + * parseInt('Infinity', 36) + * 1461559270678 + */ + + if ((flags & DUK_S2N_FLAG_ALLOW_GARBAGE) == 0 && p[8] != DUK_ASC_NUL) { + DUK_DDD(DUK_DDDPRINT("parse failed: trailing garbage after matching 'Infinity' not allowed")); + goto parse_fail; + } else { + res = DUK_DOUBLE_INFINITY; + goto negcheck_and_ret; + } + } + ch = *p; + if (ch == (duk_small_int_t) '0') { + duk_small_int_t detect_radix = 0; + ch = DUK_LOWERCASE_CHAR_ASCII(p[1]); /* 'x' or 'X' -> 'x' */ + if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT) && ch == DUK_ASC_LC_X) { + DUK_DDD(DUK_DDDPRINT("detected 0x/0X hex prefix, changing radix and preventing fractions and exponent")); + detect_radix = 16; +#if 0 + } else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_LEGACY_OCT_INT) && + (ch >= (duk_small_int_t) '0' && ch <= (duk_small_int_t) '9')) { + DUK_DDD(DUK_DDDPRINT("detected 0n oct prefix, changing radix and preventing fractions and exponent")); + detect_radix = 8; + + /* NOTE: if this legacy octal case is added back, it has + * different flags and 'p' advance so this needs to be + * reworked. + */ + flags |= DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO; /* interpret e.g. '09' as '0', not NaN */ + p += 1; +#endif + } else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT) && ch == DUK_ASC_LC_O) { + DUK_DDD(DUK_DDDPRINT("detected 0o oct prefix, changing radix and preventing fractions and exponent")); + detect_radix = 8; + } else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT) && ch == DUK_ASC_LC_B) { + DUK_DDD(DUK_DDDPRINT("detected 0b bin prefix, changing radix and preventing fractions and exponent")); + detect_radix = 2; + } + if (detect_radix > 0) { + radix = detect_radix; + /* Clear empty as zero flag: interpret e.g. '0x' and '0xg' as a NaN (= parse error) */ + flags &= ~(DUK_S2N_FLAG_ALLOW_EXP | DUK_S2N_FLAG_ALLOW_EMPTY_FRAC | + DUK_S2N_FLAG_ALLOW_FRAC | DUK_S2N_FLAG_ALLOW_NAKED_FRAC | + DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO); + flags |= DUK_S2N_FLAG_ALLOW_LEADING_ZERO; /* allow e.g. '0x0009' and '0b00010001' */ + p += 2; + } + } + + /* + * Scan number and setup for Dragon4. + * + * The fast path case is detected during setup: an integer which + * can be converted without rounding, no net exponent. The fast + * path could be implemented as a separate scan, but may not really + * be worth it: the multiplications for building 'f' are not + * expensive when 'f' is small. + * + * The significand ('f') must contain enough bits of (apparent) + * accuracy, so that Dragon4 will generate enough binary output digits. + * For decimal numbers, this means generating a 20-digit significand, + * which should yield enough practical accuracy to parse IEEE doubles. + * In fact, the ECMAScript specification explicitly allows an + * implementation to treat digits beyond 20 as zeroes (and even + * to round the 20th digit upwards). For non-decimal numbers, the + * appropriate number of digits has been precomputed for comparable + * accuracy. + * + * Digit counts: + * + * [ dig_lzero ] + * | + * .+-..---[ dig_prec ]----. + * | || | + * 0000123.456789012345678901234567890e+123456 + * | | | | | | + * `--+--' `------[ dig_frac ]-------' `-+--' + * | | + * [ dig_whole ] [ dig_expt ] + * + * dig_frac and dig_expt are -1 if not present + * dig_lzero is only computed for whole number part + * + * Parsing state + * + * Parsing whole part dig_frac < 0 AND dig_expt < 0 + * Parsing fraction part dig_frac >= 0 AND dig_expt < 0 + * Parsing exponent part dig_expt >= 0 (dig_frac may be < 0 or >= 0) + * + * Note: in case we hit an implementation limit (like exponent range), + * we should throw an error, NOT return NaN or Infinity. Even with + * very large exponent (or significand) values the final result may be + * finite, so NaN/Infinity would be incorrect. + */ + + duk__bi_set_small(&nc_ctx->f, 0); + dig_prec = 0; + dig_lzero = 0; + dig_whole = 0; + dig_frac = -1; + dig_expt = -1; + expt = 0; + expt_adj = 0; /* essentially tracks digit position of lowest 'f' digit */ + expt_neg = 0; + for (;;) { + ch = *p++; + + DUK_DDD(DUK_DDDPRINT("parse digits: p=%p, ch='%c' (%ld), expt=%ld, expt_adj=%ld, " + "dig_whole=%ld, dig_frac=%ld, dig_expt=%ld, dig_lzero=%ld, dig_prec=%ld", + (const void *) p, (int) ((ch >= 0x20 && ch <= 0x7e) ? ch : '?'), (long) ch, + (long) expt, (long) expt_adj, (long) dig_whole, (long) dig_frac, + (long) dig_expt, (long) dig_lzero, (long) dig_prec)); + DUK__BI_PRINT("f", &nc_ctx->f); + + /* Most common cases first. */ + if (ch >= (duk_small_int_t) '0' && ch <= (duk_small_int_t) '9') { + dig = (duk_small_int_t) ch - '0' + 0; + } else if (ch == (duk_small_int_t) '.') { + /* A leading digit is not required in some cases, e.g. accept ".123". + * In other cases (JSON.parse()) a leading digit is required. This + * is checked for after the loop. + */ + if (dig_frac >= 0 || dig_expt >= 0) { + if (flags & DUK_S2N_FLAG_ALLOW_GARBAGE) { + DUK_DDD(DUK_DDDPRINT("garbage termination (invalid period)")); + break; + } else { + DUK_DDD(DUK_DDDPRINT("parse failed: period not allowed")); + goto parse_fail; + } + } + + if ((flags & DUK_S2N_FLAG_ALLOW_FRAC) == 0) { + /* Some contexts don't allow fractions at all; this can't be a + * post-check because the state ('f' and expt) would be incorrect. + */ + if (flags & DUK_S2N_FLAG_ALLOW_GARBAGE) { + DUK_DDD(DUK_DDDPRINT("garbage termination (invalid first period)")); + break; + } else { + DUK_DDD(DUK_DDDPRINT("parse failed: fraction part not allowed")); + } + } + + DUK_DDD(DUK_DDDPRINT("start fraction part")); + dig_frac = 0; + continue; + } else if (ch == (duk_small_int_t) 0) { + DUK_DDD(DUK_DDDPRINT("NUL termination")); + break; + } else if ((flags & DUK_S2N_FLAG_ALLOW_EXP) && + dig_expt < 0 && (ch == (duk_small_int_t) 'e' || ch == (duk_small_int_t) 'E')) { + /* Note: we don't parse back exponent notation for anything else + * than radix 10, so this is not an ambiguous check (e.g. hex + * exponent values may have 'e' either as a significand digit + * or as an exponent separator). + * + * If the exponent separator occurs twice, 'e' will be interpreted + * as a digit (= 14) and will be rejected as an invalid decimal + * digit. + */ + + DUK_DDD(DUK_DDDPRINT("start exponent part")); + + /* Exponent without a sign or with a +/- sign is accepted + * by all call sites (even JSON.parse()). + */ + ch = *p; + if (ch == (duk_small_int_t) '-') { + expt_neg = 1; + p++; + } else if (ch == (duk_small_int_t) '+') { + p++; + } + dig_expt = 0; + continue; + } else if (ch >= (duk_small_int_t) 'a' && ch <= (duk_small_int_t) 'z') { + dig = (duk_small_int_t) (ch - (duk_small_int_t) 'a' + 0x0a); + } else if (ch >= (duk_small_int_t) 'A' && ch <= (duk_small_int_t) 'Z') { + dig = (duk_small_int_t) (ch - (duk_small_int_t) 'A' + 0x0a); + } else { + dig = 255; /* triggers garbage digit check below */ + } + DUK_ASSERT((dig >= 0 && dig <= 35) || dig == 255); + + if (dig >= radix) { + if (flags & DUK_S2N_FLAG_ALLOW_GARBAGE) { + DUK_DDD(DUK_DDDPRINT("garbage termination")); + break; + } else { + DUK_DDD(DUK_DDDPRINT("parse failed: trailing garbage or invalid digit")); + goto parse_fail; + } + } + + if (dig_expt < 0) { + /* whole or fraction digit */ + + if (dig_prec < duk__str2num_digits_for_radix[radix - 2]) { + /* significant from precision perspective */ + + duk_small_int_t f_zero = duk__bi_is_zero(&nc_ctx->f); + if (f_zero && dig == 0) { + /* Leading zero is not counted towards precision digits; not + * in the integer part, nor in the fraction part. + */ + if (dig_frac < 0) { + dig_lzero++; + } + } else { + /* XXX: join these ops (multiply-accumulate), but only if + * code footprint decreases. + */ + duk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, (duk_uint32_t) radix); + duk__bi_add_small(&nc_ctx->f, &nc_ctx->t1, (duk_uint32_t) dig); + dig_prec++; + } + } else { + /* Ignore digits beyond a radix-specific limit, but note them + * in expt_adj. + */ + expt_adj++; + } + + if (dig_frac >= 0) { + dig_frac++; + expt_adj--; + } else { + dig_whole++; + } + } else { + /* exponent digit */ + + DUK_ASSERT(radix == 10); + expt = expt * radix + dig; + if (expt > DUK_S2N_MAX_EXPONENT) { + /* Impose a reasonable exponent limit, so that exp + * doesn't need to get tracked using a bigint. + */ + DUK_DDD(DUK_DDDPRINT("parse failed: exponent too large")); + goto parse_explimit_error; + } + dig_expt++; + } + } + + /* Leading zero. */ + + if (dig_lzero > 0 && dig_whole > 1) { + if ((flags & DUK_S2N_FLAG_ALLOW_LEADING_ZERO) == 0) { + DUK_DDD(DUK_DDDPRINT("parse failed: leading zeroes not allowed in integer part")); + goto parse_fail; + } + } + + /* Validity checks for various fraction formats ("0.1", ".1", "1.", "."). */ + + if (dig_whole == 0) { + if (dig_frac == 0) { + /* "." is not accepted in any format */ + DUK_DDD(DUK_DDDPRINT("parse failed: plain period without leading or trailing digits")); + goto parse_fail; + } else if (dig_frac > 0) { + /* ".123" */ + if ((flags & DUK_S2N_FLAG_ALLOW_NAKED_FRAC) == 0) { + DUK_DDD(DUK_DDDPRINT("parse failed: fraction part not allowed without " + "leading integer digit(s)")); + goto parse_fail; + } + } else { + /* Empty ("") is allowed in some formats (e.g. Number(''), as zero, + * but it must not have a leading +/- sign (GH-2019). Note that + * for Number(), h_str is already trimmed so we can check for zero + * length and still get Number(' + ') == NaN. + */ + if ((flags & DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO) == 0) { + DUK_DDD(DUK_DDDPRINT("parse failed: empty string not allowed (as zero)")); + goto parse_fail; + } else if (DUK_HSTRING_GET_BYTELEN(h_str) != 0) { + DUK_DDD(DUK_DDDPRINT("parse failed: no digits, but not empty (had a +/- sign)")); + goto parse_fail; + } + } + } else { + if (dig_frac == 0) { + /* "123." is allowed in some formats */ + if ((flags & DUK_S2N_FLAG_ALLOW_EMPTY_FRAC) == 0) { + DUK_DDD(DUK_DDDPRINT("parse failed: empty fractions")); + goto parse_fail; + } + } else if (dig_frac > 0) { + /* "123.456" */ + ; + } else { + /* "123" */ + ; + } + } + + /* Exponent without digits (e.g. "1e" or "1e+"). If trailing garbage is + * allowed, ignore exponent part as garbage (= parse as "1", i.e. exp 0). + */ + + if (dig_expt == 0) { + if ((flags & DUK_S2N_FLAG_ALLOW_GARBAGE) == 0) { + DUK_DDD(DUK_DDDPRINT("parse failed: empty exponent")); + goto parse_fail; + } + DUK_ASSERT(expt == 0); + } + + if (expt_neg) { + expt = -expt; + } + DUK_DDD(DUK_DDDPRINT("expt=%ld, expt_adj=%ld, net exponent -> %ld", + (long) expt, (long) expt_adj, (long) (expt + expt_adj))); + expt += expt_adj; + + /* Fast path check. */ + + if (nc_ctx->f.n <= 1 && /* 32-bit value */ + expt == 0 /* no net exponent */) { + /* Fast path is triggered for no exponent and also for balanced exponent + * and fraction parts, e.g. for "1.23e2" == "123". Remember to respect + * zero sign. + */ + + /* XXX: could accept numbers larger than 32 bits, e.g. up to 53 bits? */ + DUK_DDD(DUK_DDDPRINT("fast path number parse")); + if (nc_ctx->f.n == 1) { + res = (double) nc_ctx->f.v[0]; + } else { + res = 0.0; + } + goto negcheck_and_ret; + } + + /* Significand ('f') padding. */ + + while (dig_prec < duk__str2num_digits_for_radix[radix - 2]) { + /* Pad significand with "virtual" zero digits so that Dragon4 will + * have enough (apparent) precision to work with. + */ + DUK_DDD(DUK_DDDPRINT("dig_prec=%ld, pad significand with zero", (long) dig_prec)); + duk__bi_mul_small_copy(&nc_ctx->f, (duk_uint32_t) radix, &nc_ctx->t1); + DUK__BI_PRINT("f", &nc_ctx->f); + expt--; + dig_prec++; + } + + DUK_DDD(DUK_DDDPRINT("final exponent: %ld", (long) expt)); + + /* Detect zero special case. */ + + if (nc_ctx->f.n == 0) { + /* This may happen even after the fast path check, if exponent is + * not balanced (e.g. "0e1"). Remember to respect zero sign. + */ + DUK_DDD(DUK_DDDPRINT("significand is zero")); + res = 0.0; + goto negcheck_and_ret; + } + + + /* Quick reject of too large or too small exponents. This check + * would be incorrect for zero (e.g. "0e1000" is zero, not Infinity) + * so zero check must be above. + */ + + explim = &duk__str2num_exp_limits[radix - 2]; + if (expt > explim->upper) { + DUK_DDD(DUK_DDDPRINT("exponent too large -> infinite")); + res = (duk_double_t) DUK_DOUBLE_INFINITY; + goto negcheck_and_ret; + } else if (expt < explim->lower) { + DUK_DDD(DUK_DDDPRINT("exponent too small -> zero")); + res = (duk_double_t) 0.0; + goto negcheck_and_ret; + } + + nc_ctx->is_s2n = 1; + nc_ctx->e = expt; + nc_ctx->b = radix; + nc_ctx->B = 2; + nc_ctx->is_fixed = 1; + nc_ctx->abs_pos = 0; + nc_ctx->req_digits = 53 + 1; + + DUK__BI_PRINT("f", &nc_ctx->f); + DUK_DDD(DUK_DDDPRINT("e=%ld", (long) nc_ctx->e)); + + /* + * Dragon4 slow path (binary) digit generation. + * An extra digit is generated for rounding. + */ + + duk__dragon4_prepare(nc_ctx); /* setup many variables in nc_ctx */ + + DUK_DDD(DUK_DDDPRINT("after prepare:")); + DUK__BI_PRINT("r", &nc_ctx->r); + DUK__BI_PRINT("s", &nc_ctx->s); + DUK__BI_PRINT("mp", &nc_ctx->mp); + DUK__BI_PRINT("mm", &nc_ctx->mm); + + duk__dragon4_scale(nc_ctx); + + DUK_DDD(DUK_DDDPRINT("after scale; k=%ld", (long) nc_ctx->k)); + DUK__BI_PRINT("r", &nc_ctx->r); + DUK__BI_PRINT("s", &nc_ctx->s); + DUK__BI_PRINT("mp", &nc_ctx->mp); + DUK__BI_PRINT("mm", &nc_ctx->mm); + + duk__dragon4_generate(nc_ctx); + + DUK_ASSERT(nc_ctx->count == 53 + 1); + + /* + * Convert binary digits into an IEEE double. Need to handle + * denormals and rounding correctly. + * + * Some call sites currently assume the result is always a + * non-fastint double. If this is changed, check all call + * sites. + */ + + duk__dragon4_ctx_to_double(nc_ctx, &res); + goto negcheck_and_ret; + + negcheck_and_ret: + if (neg) { + res = -res; + } + duk_pop(thr); + duk_push_number(thr, (double) res); + DUK_DDD(DUK_DDDPRINT("result: %!T", (duk_tval *) duk_get_tval(thr, -1))); + return; + + parse_fail: + DUK_DDD(DUK_DDDPRINT("parse failed")); + duk_pop(thr); + duk_push_nan(thr); + return; + + parse_explimit_error: + DUK_DDD(DUK_DDDPRINT("parse failed, internal error, can't return a value")); + DUK_ERROR_RANGE(thr, "exponent too large"); + DUK_WO_NORETURN(return;); +} + +DUK_INTERNAL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags) { + duk_native_stack_check(thr); + duk__numconv_parse_raw(thr, radix, flags); +} diff --git a/third_party/duktape/duk_numconv.h b/third_party/duktape/duk_numconv.h new file mode 100644 index 00000000..e0e9e0bf --- /dev/null +++ b/third_party/duktape/duk_numconv.h @@ -0,0 +1,104 @@ +/* + * Number-to-string conversion. The semantics of these is very tightly + * bound with the ECMAScript semantics required for call sites. + */ + +#if !defined(DUK_NUMCONV_H_INCLUDED) +#define DUK_NUMCONV_H_INCLUDED + +/* Output a specified number of digits instead of using the shortest + * form. Used for toPrecision() and toFixed(). + */ +#define DUK_N2S_FLAG_FIXED_FORMAT (1U << 0) + +/* Force exponential format. Used for toExponential(). */ +#define DUK_N2S_FLAG_FORCE_EXP (1U << 1) + +/* If number would need zero padding (for whole number part), use + * exponential format instead. E.g. if input number is 12300, 3 + * digits are generated ("123"), output "1.23e+4" instead of "12300". + * Used for toPrecision(). + */ +#define DUK_N2S_FLAG_NO_ZERO_PAD (1U << 2) + +/* Digit count indicates number of fractions (i.e. an absolute + * digit index instead of a relative one). Used together with + * DUK_N2S_FLAG_FIXED_FORMAT for toFixed(). + */ +#define DUK_N2S_FLAG_FRACTION_DIGITS (1U << 3) + +/* + * String-to-number conversion + */ + +/* Maximum exponent value when parsing numbers. This is not strictly + * compliant as there should be no upper limit, but as we parse the + * exponent without a bigint, impose some limit. The limit should be + * small enough that multiplying it (or limit-1 to be precise) won't + * overflow signed 32-bit integer range. Exponent is only parsed with + * radix 10, but with maximum radix (36) a safe limit is: + * (10000000*36).toString(16) -> '15752a00' + */ +#define DUK_S2N_MAX_EXPONENT 10000000L + +/* Trim white space (= allow leading and trailing whitespace) */ +#define DUK_S2N_FLAG_TRIM_WHITE (1U << 0) + +/* Allow exponent */ +#define DUK_S2N_FLAG_ALLOW_EXP (1U << 1) + +/* Allow trailing garbage (e.g. treat "123foo" as "123) */ +#define DUK_S2N_FLAG_ALLOW_GARBAGE (1U << 2) + +/* Allow leading plus sign */ +#define DUK_S2N_FLAG_ALLOW_PLUS (1U << 3) + +/* Allow leading minus sign */ +#define DUK_S2N_FLAG_ALLOW_MINUS (1U << 4) + +/* Allow 'Infinity' */ +#define DUK_S2N_FLAG_ALLOW_INF (1U << 5) + +/* Allow fraction part */ +#define DUK_S2N_FLAG_ALLOW_FRAC (1U << 6) + +/* Allow naked fraction (e.g. ".123") */ +#define DUK_S2N_FLAG_ALLOW_NAKED_FRAC (1U << 7) + +/* Allow empty fraction (e.g. "123.") */ +#define DUK_S2N_FLAG_ALLOW_EMPTY_FRAC (1U << 8) + +/* Allow empty string to be interpreted as 0 */ +#define DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO (1U << 9) + +/* Allow leading zeroes (e.g. "0123" -> "123") */ +#define DUK_S2N_FLAG_ALLOW_LEADING_ZERO (1U << 10) + +/* Allow automatic detection of hex base ("0x" or "0X" prefix), + * overrides radix argument and forces integer mode. + */ +#define DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT (1U << 11) + +/* Allow automatic detection of legacy octal base ("0n"), + * overrides radix argument and forces integer mode. + */ +#define DUK_S2N_FLAG_ALLOW_AUTO_LEGACY_OCT_INT (1U << 12) + +/* Allow automatic detection of ES2015 octal base ("0o123"), + * overrides radix argument and forces integer mode. + */ +#define DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT (1U << 13) + +/* Allow automatic detection of ES2015 binary base ("0b10001"), + * overrides radix argument and forces integer mode. + */ +#define DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT (1U << 14) + +/* + * Prototypes + */ + +DUK_INTERNAL_DECL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags); +DUK_INTERNAL_DECL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags); + +#endif /* DUK_NUMCONV_H_INCLUDED */ diff --git a/third_party/duktape/duk_refcount.h b/third_party/duktape/duk_refcount.h new file mode 100644 index 00000000..33e48226 --- /dev/null +++ b/third_party/duktape/duk_refcount.h @@ -0,0 +1,725 @@ +/* + * Reference counting helper macros. The macros take a thread argument + * and must thus always be executed in a specific thread context. The + * thread argument is not really needed anymore: DECREF can operate with + * a heap pointer only, and INCREF needs neither. + */ + +#if !defined(DUK_REFCOUNT_H_INCLUDED) +#define DUK_REFCOUNT_H_INCLUDED + +#if defined(DUK_USE_REFERENCE_COUNTING) + +#if defined(DUK_USE_ROM_OBJECTS) +/* With ROM objects "needs refcount update" is true when the value is + * heap allocated and is not a ROM object. + */ +/* XXX: double evaluation for 'tv' argument. */ +#define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv) \ + (DUK_TVAL_IS_HEAP_ALLOCATED((tv)) && !DUK_HEAPHDR_HAS_READONLY(DUK_TVAL_GET_HEAPHDR((tv)))) +#define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h) (!DUK_HEAPHDR_HAS_READONLY((h))) +#else /* DUK_USE_ROM_OBJECTS */ +/* Without ROM objects "needs refcount update" == is heap allocated. */ +#define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv) DUK_TVAL_IS_HEAP_ALLOCATED((tv)) +#define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h) 1 +#endif /* DUK_USE_ROM_OBJECTS */ + +/* Fast variants, inline refcount operations except for refzero handling. + * Can be used explicitly when speed is always more important than size. + * For a good compiler and a single file build, these are basically the + * same as a forced inline. + */ +#define DUK_TVAL_INCREF_FAST(thr,tv) do { \ + duk_tval *duk__tv = (tv); \ + DUK_ASSERT(duk__tv != NULL); \ + if (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \ + duk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \ + DUK_ASSERT(duk__h != NULL); \ + DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \ + DUK_HEAPHDR_PREINC_REFCOUNT(duk__h); \ + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) != 0); /* No wrapping. */ \ + } \ + } while (0) +#define DUK_TVAL_DECREF_FAST(thr,tv) do { \ + duk_tval *duk__tv = (tv); \ + DUK_ASSERT(duk__tv != NULL); \ + if (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \ + duk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \ + DUK_ASSERT(duk__h != NULL); \ + DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \ + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \ + if (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \ + duk_heaphdr_refzero((thr), duk__h); \ + } \ + } \ + } while (0) +#define DUK_TVAL_DECREF_NORZ_FAST(thr,tv) do { \ + duk_tval *duk__tv = (tv); \ + DUK_ASSERT(duk__tv != NULL); \ + if (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \ + duk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \ + DUK_ASSERT(duk__h != NULL); \ + DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \ + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \ + if (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \ + duk_heaphdr_refzero_norz((thr), duk__h); \ + } \ + } \ + } while (0) +#define DUK_HEAPHDR_INCREF_FAST(thr,h) do { \ + duk_heaphdr *duk__h = (duk_heaphdr *) (h); \ + DUK_ASSERT(duk__h != NULL); \ + DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \ + if (DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(duk__h)) { \ + DUK_HEAPHDR_PREINC_REFCOUNT(duk__h); \ + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) != 0); /* No wrapping. */ \ + } \ + } while (0) +#define DUK_HEAPHDR_DECREF_FAST_RAW(thr,h,rzcall,rzcast) do { \ + duk_heaphdr *duk__h = (duk_heaphdr *) (h); \ + DUK_ASSERT(duk__h != NULL); \ + DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \ + DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \ + if (DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(duk__h)) { \ + if (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \ + (rzcall)((thr), (rzcast) duk__h); \ + } \ + } \ + } while (0) +#define DUK_HEAPHDR_DECREF_FAST(thr,h) \ + DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero,duk_heaphdr *) +#define DUK_HEAPHDR_DECREF_NORZ_FAST(thr,h) \ + DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero_norz,duk_heaphdr *) + +/* Slow variants, call to a helper to reduce code size. + * Can be used explicitly when size is always more important than speed. + */ +#define DUK_TVAL_INCREF_SLOW(thr,tv) do { duk_tval_incref((tv)); } while (0) +#define DUK_TVAL_DECREF_SLOW(thr,tv) do { duk_tval_decref((thr), (tv)); } while (0) +#define DUK_TVAL_DECREF_NORZ_SLOW(thr,tv) do { duk_tval_decref_norz((thr), (tv)); } while (0) +#define DUK_HEAPHDR_INCREF_SLOW(thr,h) do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0) +#define DUK_HEAPHDR_DECREF_SLOW(thr,h) do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0) +#define DUK_HEAPHDR_DECREF_NORZ_SLOW(thr,h) do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0) +#define DUK_HSTRING_INCREF_SLOW(thr,h) do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0) +#define DUK_HSTRING_DECREF_SLOW(thr,h) do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0) +#define DUK_HSTRING_DECREF_NORZ_SLOW(thr,h) do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0) +#define DUK_HBUFFER_INCREF_SLOW(thr,h) do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0) +#define DUK_HBUFFER_DECREF_SLOW(thr,h) do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0) +#define DUK_HBUFFER_DECREF_NORZ_SLOW(thr,h) do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0) +#define DUK_HOBJECT_INCREF_SLOW(thr,h) do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0) +#define DUK_HOBJECT_DECREF_SLOW(thr,h) do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0) +#define DUK_HOBJECT_DECREF_NORZ_SLOW(thr,h) do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0) + +/* Default variants. Selection depends on speed/size preference. + * Concretely: with gcc 4.8.1 -Os x64 the difference in final binary + * is about +1kB for _FAST variants. + */ +#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT) +/* XXX: It would be nice to specialize for specific duk_hobject subtypes + * but current refzero queue handling prevents that. + */ +#define DUK_TVAL_INCREF(thr,tv) DUK_TVAL_INCREF_FAST((thr),(tv)) +#define DUK_TVAL_DECREF(thr,tv) DUK_TVAL_DECREF_FAST((thr),(tv)) +#define DUK_TVAL_DECREF_NORZ(thr,tv) DUK_TVAL_DECREF_NORZ_FAST((thr),(tv)) +#define DUK_HEAPHDR_INCREF(thr,h) DUK_HEAPHDR_INCREF_FAST((thr),(h)) +#define DUK_HEAPHDR_DECREF(thr,h) DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero,duk_heaphdr *) +#define DUK_HEAPHDR_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero_norz,duk_heaphdr *) +#define DUK_HSTRING_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h)) +#define DUK_HSTRING_DECREF(thr,h) DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hstring_refzero,duk_hstring *) +#define DUK_HSTRING_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hstring_refzero,duk_hstring *) /* no 'norz' variant */ +#define DUK_HOBJECT_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h)) +#define DUK_HOBJECT_DECREF(thr,h) DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *) +#define DUK_HOBJECT_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *) +#define DUK_HBUFFER_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h)) +#define DUK_HBUFFER_DECREF(thr,h) DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hbuffer_refzero,duk_hbuffer *) +#define DUK_HBUFFER_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hbuffer_refzero,duk_hbuffer *) /* no 'norz' variant */ +#define DUK_HCOMPFUNC_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj) +#define DUK_HCOMPFUNC_DECREF(thr,h) DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *) +#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *) +#define DUK_HNATFUNC_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj) +#define DUK_HNATFUNC_DECREF(thr,h) DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *) +#define DUK_HNATFUNC_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *) +#define DUK_HBUFOBJ_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj) +#define DUK_HBUFOBJ_DECREF(thr,h) DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *) +#define DUK_HBUFOBJ_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *) +#define DUK_HTHREAD_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj) +#define DUK_HTHREAD_DECREF(thr,h) DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *) +#define DUK_HTHREAD_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *) +#else +#define DUK_TVAL_INCREF(thr,tv) DUK_TVAL_INCREF_SLOW((thr),(tv)) +#define DUK_TVAL_DECREF(thr,tv) DUK_TVAL_DECREF_SLOW((thr),(tv)) +#define DUK_TVAL_DECREF_NORZ(thr,tv) DUK_TVAL_DECREF_NORZ_SLOW((thr),(tv)) +#define DUK_HEAPHDR_INCREF(thr,h) DUK_HEAPHDR_INCREF_SLOW((thr),(h)) +#define DUK_HEAPHDR_DECREF(thr,h) DUK_HEAPHDR_DECREF_SLOW((thr),(h)) +#define DUK_HEAPHDR_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_NORZ_SLOW((thr),(h)) +#define DUK_HSTRING_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h)) +#define DUK_HSTRING_DECREF(thr,h) DUK_HSTRING_DECREF_SLOW((thr),(h)) +#define DUK_HSTRING_DECREF_NORZ(thr,h) DUK_HSTRING_DECREF_NORZ_SLOW((thr),(h)) +#define DUK_HOBJECT_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h)) +#define DUK_HOBJECT_DECREF(thr,h) DUK_HOBJECT_DECREF_SLOW((thr),(h)) +#define DUK_HOBJECT_DECREF_NORZ(thr,h) DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(h)) +#define DUK_HBUFFER_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h)) +#define DUK_HBUFFER_DECREF(thr,h) DUK_HBUFFER_DECREF_SLOW((thr),(h)) +#define DUK_HBUFFER_DECREF_NORZ(thr,h) DUK_HBUFFER_DECREF_NORZ_SLOW((thr),(h)) +#define DUK_HCOMPFUNC_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj) +#define DUK_HCOMPFUNC_DECREF(thr,h) DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj) +#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h) DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj) +#define DUK_HNATFUNC_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj) +#define DUK_HNATFUNC_DECREF(thr,h) DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj) +#define DUK_HNATFUNC_DECREF_NORZ(thr,h) DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj) +#define DUK_HBUFOBJ_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj) +#define DUK_HBUFOBJ_DECREF(thr,h) DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj) +#define DUK_HBUFOB_DECREF_NORZ(thr,h) DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj) +#define DUK_HTHREAD_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj) +#define DUK_HTHREAD_DECREF(thr,h) DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj) +#define DUK_HTHREAD_DECREF_NORZ(thr,h) DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj) +#endif + +/* Convenience for some situations; the above macros don't allow NULLs + * for performance reasons. Macros cover only actually needed cases. + */ +#define DUK_HEAPHDR_INCREF_ALLOWNULL(thr,h) do { \ + if ((h) != NULL) { \ + DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h)); \ + } \ + } while (0) +#define DUK_HEAPHDR_DECREF_ALLOWNULL(thr,h) do { \ + if ((h) != NULL) { \ + DUK_HEAPHDR_DECREF((thr), (duk_heaphdr *) (h)); \ + } \ + } while (0) +#define DUK_HEAPHDR_DECREF_NORZ_ALLOWNULL(thr,h) do { \ + if ((h) != NULL) { \ + DUK_HEAPHDR_DECREF_NORZ((thr), (duk_heaphdr *) (h)); \ + } \ + } while (0) +#define DUK_HOBJECT_INCREF_ALLOWNULL(thr,h) do { \ + if ((h) != NULL) { \ + DUK_HOBJECT_INCREF((thr), (h)); \ + } \ + } while (0) +#define DUK_HOBJECT_DECREF_ALLOWNULL(thr,h) do { \ + if ((h) != NULL) { \ + DUK_HOBJECT_DECREF((thr), (h)); \ + } \ + } while (0) +#define DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr,h) do { \ + if ((h) != NULL) { \ + DUK_HOBJECT_DECREF_NORZ((thr), (h)); \ + } \ + } while (0) +#define DUK_HBUFFER_INCREF_ALLOWNULL(thr,h) do { \ + if ((h) != NULL) { \ + DUK_HBUFFER_INCREF((thr), (h)); \ + } \ + } while (0) +#define DUK_HBUFFER_DECREF_ALLOWNULL(thr,h) do { \ + if ((h) != NULL) { \ + DUK_HBUFFER_DECREF((thr), (h)); \ + } \ + } while (0) +#define DUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr,h) do { \ + if ((h) != NULL) { \ + DUK_HBUFFER_DECREF_NORZ((thr), (h)); \ + } \ + } while (0) +#define DUK_HTHREAD_INCREF_ALLOWNULL(thr,h) do { \ + if ((h) != NULL) { \ + DUK_HTHREAD_INCREF((thr), (h)); \ + } \ + } while (0) +#define DUK_HTHREAD_DECREF_ALLOWNULL(thr,h) do { \ + if ((h) != NULL) { \ + DUK_HTHREAD_DECREF((thr), (h)); \ + } \ + } while (0) +#define DUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr,h) do { \ + if ((h) != NULL) { \ + DUK_HTHREAD_DECREF_NORZ((thr), (h)); \ + } \ + } while (0) + +/* Called after one or more DECREF NORZ calls to handle pending side effects. + * At present DECREF NORZ does freeing inline but doesn't execute finalizers, + * so these macros check for pending finalizers and execute them. The FAST + * variant is performance critical. + */ +#if defined(DUK_USE_FINALIZER_SUPPORT) +#define DUK_REFZERO_CHECK_FAST(thr) do { \ + duk_refzero_check_fast((thr)); \ + } while (0) +#define DUK_REFZERO_CHECK_SLOW(thr) do { \ + duk_refzero_check_slow((thr)); \ + } while (0) +#else /* DUK_USE_FINALIZER_SUPPORT */ +#define DUK_REFZERO_CHECK_FAST(thr) do { } while (0) +#define DUK_REFZERO_CHECK_SLOW(thr) do { } while (0) +#endif /* DUK_USE_FINALIZER_SUPPORT */ + +/* + * Macros to set a duk_tval and update refcount of the target (decref the + * old value and incref the new value if necessary). This is both performance + * and footprint critical; any changes made should be measured for size/speed. + */ + +#define DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0(thr,tvptr_dst) do { \ + duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_UNDEFINED(tv__dst); \ + DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ + } while (0) + +#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ_ALT0(thr,tvptr_dst) do { \ + duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_UNDEFINED(tv__dst); \ + DUK_TVAL_DECREF_NORZ((thr), &tv__tmp); \ + } while (0) + +#define DUK_TVAL_SET_UNUSED_UPDREF_ALT0(thr,tvptr_dst) do { \ + duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_UNUSED(tv__dst); \ + DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ + } while (0) + +#define DUK_TVAL_SET_NULL_UPDREF_ALT0(thr,tvptr_dst) do { \ + duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_NULL(tv__dst); \ + DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ + } while (0) + +#define DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_BOOLEAN(tv__dst, (newval)); \ + DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ + } while (0) + +#define DUK_TVAL_SET_NUMBER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_NUMBER(tv__dst, (newval)); \ + DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ + } while (0) +#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv__dst, (newval)); \ + DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ + } while (0) +#define DUK_TVAL_SET_DOUBLE_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_DOUBLE(tv__dst, (newval)); \ + DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ + } while (0) +#define DUK_TVAL_SET_NAN_UPDREF_ALT0(thr,tvptr_dst) do { \ + duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_NAN(tv__dst); \ + DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ + } while (0) +#if defined(DUK_USE_FASTINT) +#define DUK_TVAL_SET_I48_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_I48(tv__dst, (newval)); \ + DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ + } while (0) +#define DUK_TVAL_SET_I32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_I32(tv__dst, (newval)); \ + DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ + } while (0) +#define DUK_TVAL_SET_U32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_U32(tv__dst, (newval)); \ + DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ + } while (0) +#else +#define DUK_TVAL_SET_DOUBLE_CAST_UPDREF(thr,tvptr_dst,newval) \ + DUK_TVAL_SET_DOUBLE_UPDREF((thr), (tvptr_dst), (duk_double_t) (newval)) +#endif /* DUK_USE_FASTINT */ + +#define DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0(thr,tvptr_dst,lf_v,lf_fp,lf_flags) do { \ + duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_LIGHTFUNC(tv__dst, (lf_v), (lf_fp), (lf_flags)); \ + DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ + } while (0) + +#define DUK_TVAL_SET_STRING_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_STRING(tv__dst, (newval)); \ + DUK_HSTRING_INCREF((thr), (newval)); \ + DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ + } while (0) + +#define DUK_TVAL_SET_OBJECT_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_OBJECT(tv__dst, (newval)); \ + DUK_HOBJECT_INCREF((thr), (newval)); \ + DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ + } while (0) + +#define DUK_TVAL_SET_BUFFER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_BUFFER(tv__dst, (newval)); \ + DUK_HBUFFER_INCREF((thr), (newval)); \ + DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ + } while (0) + +#define DUK_TVAL_SET_POINTER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_POINTER(tv__dst, (newval)); \ + DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ + } while (0) + +/* DUK_TVAL_SET_TVAL_UPDREF() is used a lot in executor, property lookups, + * etc, so it's very important for performance. Measure when changing. + * + * NOTE: the source and destination duk_tval pointers may be the same, and + * the macros MUST deal with that correctly. + */ + +/* Original idiom used, minimal code size. */ +#define DUK_TVAL_SET_TVAL_UPDREF_ALT0(thr,tvptr_dst,tvptr_src) do { \ + duk_tval *tv__dst, *tv__src; duk_tval tv__tmp; \ + tv__dst = (tvptr_dst); tv__src = (tvptr_src); \ + DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ + DUK_TVAL_SET_TVAL(tv__dst, tv__src); \ + DUK_TVAL_INCREF((thr), tv__src); \ + DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ + } while (0) + +/* Faster alternative: avoid making a temporary copy of tvptr_dst and use + * fast incref/decref macros. + */ +#define DUK_TVAL_SET_TVAL_UPDREF_ALT1(thr,tvptr_dst,tvptr_src) do { \ + duk_tval *tv__dst, *tv__src; duk_heaphdr *h__obj; \ + tv__dst = (tvptr_dst); tv__src = (tvptr_src); \ + DUK_TVAL_INCREF_FAST((thr), tv__src); \ + if (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv__dst)) { \ + h__obj = DUK_TVAL_GET_HEAPHDR(tv__dst); \ + DUK_ASSERT(h__obj != NULL); \ + DUK_TVAL_SET_TVAL(tv__dst, tv__src); \ + DUK_HEAPHDR_DECREF_FAST((thr), h__obj); /* side effects */ \ + } else { \ + DUK_TVAL_SET_TVAL(tv__dst, tv__src); \ + } \ + } while (0) + +/* XXX: no optimized variants yet */ +#define DUK_TVAL_SET_UNDEFINED_UPDREF DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0 +#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ_ALT0 +#define DUK_TVAL_SET_UNUSED_UPDREF DUK_TVAL_SET_UNUSED_UPDREF_ALT0 +#define DUK_TVAL_SET_NULL_UPDREF DUK_TVAL_SET_NULL_UPDREF_ALT0 +#define DUK_TVAL_SET_BOOLEAN_UPDREF DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0 +#define DUK_TVAL_SET_NUMBER_UPDREF DUK_TVAL_SET_NUMBER_UPDREF_ALT0 +#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0 +#define DUK_TVAL_SET_DOUBLE_UPDREF DUK_TVAL_SET_DOUBLE_UPDREF_ALT0 +#define DUK_TVAL_SET_NAN_UPDREF DUK_TVAL_SET_NAN_UPDREF_ALT0 +#if defined(DUK_USE_FASTINT) +#define DUK_TVAL_SET_I48_UPDREF DUK_TVAL_SET_I48_UPDREF_ALT0 +#define DUK_TVAL_SET_I32_UPDREF DUK_TVAL_SET_I32_UPDREF_ALT0 +#define DUK_TVAL_SET_U32_UPDREF DUK_TVAL_SET_U32_UPDREF_ALT0 +#else +#define DUK_TVAL_SET_I48_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF /* XXX: fast int-to-double */ +#define DUK_TVAL_SET_I32_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF +#define DUK_TVAL_SET_U32_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF +#endif /* DUK_USE_FASTINT */ +#define DUK_TVAL_SET_FASTINT_UPDREF DUK_TVAL_SET_I48_UPDREF /* convenience */ +#define DUK_TVAL_SET_LIGHTFUNC_UPDREF DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0 +#define DUK_TVAL_SET_STRING_UPDREF DUK_TVAL_SET_STRING_UPDREF_ALT0 +#define DUK_TVAL_SET_OBJECT_UPDREF DUK_TVAL_SET_OBJECT_UPDREF_ALT0 +#define DUK_TVAL_SET_BUFFER_UPDREF DUK_TVAL_SET_BUFFER_UPDREF_ALT0 +#define DUK_TVAL_SET_POINTER_UPDREF DUK_TVAL_SET_POINTER_UPDREF_ALT0 + +#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT) +/* Optimized for speed. */ +#define DUK_TVAL_SET_TVAL_UPDREF DUK_TVAL_SET_TVAL_UPDREF_ALT1 +#define DUK_TVAL_SET_TVAL_UPDREF_FAST DUK_TVAL_SET_TVAL_UPDREF_ALT1 +#define DUK_TVAL_SET_TVAL_UPDREF_SLOW DUK_TVAL_SET_TVAL_UPDREF_ALT0 +#else +/* Optimized for size. */ +#define DUK_TVAL_SET_TVAL_UPDREF DUK_TVAL_SET_TVAL_UPDREF_ALT0 +#define DUK_TVAL_SET_TVAL_UPDREF_FAST DUK_TVAL_SET_TVAL_UPDREF_ALT0 +#define DUK_TVAL_SET_TVAL_UPDREF_SLOW DUK_TVAL_SET_TVAL_UPDREF_ALT0 +#endif + +#else /* DUK_USE_REFERENCE_COUNTING */ + +#define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv) 0 +#define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h) 0 + +#define DUK_TVAL_INCREF_FAST(thr,v) do {} while (0) /* nop */ +#define DUK_TVAL_DECREF_FAST(thr,v) do {} while (0) /* nop */ +#define DUK_TVAL_DECREF_NORZ_FAST(thr,v) do {} while (0) /* nop */ +#define DUK_TVAL_INCREF_SLOW(thr,v) do {} while (0) /* nop */ +#define DUK_TVAL_DECREF_SLOW(thr,v) do {} while (0) /* nop */ +#define DUK_TVAL_DECREF_NORZ_SLOW(thr,v) do {} while (0) /* nop */ +#define DUK_TVAL_INCREF(thr,v) do {} while (0) /* nop */ +#define DUK_TVAL_DECREF(thr,v) do {} while (0) /* nop */ +#define DUK_TVAL_DECREF_NORZ(thr,v) do {} while (0) /* nop */ +#define DUK_HEAPHDR_INCREF_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HEAPHDR_DECREF_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HEAPHDR_DECREF_NORZ_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HEAPHDR_INCREF_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HEAPHDR_DECREF_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HEAPHDR_DECREF_NORZ_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HEAPHDR_INCREF(thr,h) do {} while (0) /* nop */ +#define DUK_HEAPHDR_DECREF(thr,h) do {} while (0) /* nop */ +#define DUK_HEAPHDR_DECREF_NORZ(thr,h) do {} while (0) /* nop */ +#define DUK_HSTRING_INCREF_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HSTRING_DECREF_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HSTRING_DECREF_NORZ_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HSTRING_INCREF_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HSTRING_DECREF_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HSTRING_DECREF_NORZ_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HSTRING_INCREF(thr,h) do {} while (0) /* nop */ +#define DUK_HSTRING_DECREF(thr,h) do {} while (0) /* nop */ +#define DUK_HSTRING_DECREF_NORZ(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_INCREF_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_DECREF_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_DECREF_NORZ_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_INCREF_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_DECREF_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_DECREF_NORZ_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_INCREF(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_DECREF(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_DECREF_NORZ(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_INCREF_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_DECREF_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_DECREF_NORZ_FAST(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_INCREF_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_DECREF_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_DECREF_NORZ_SLOW(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_INCREF(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_DECREF(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_DECREF_NORZ(thr,h) do {} while (0) /* nop */ + +#define DUK_HCOMPFUNC_INCREF(thr,h) do {} while (0) /* nop */ +#define DUK_HCOMPFUNC_DECREF(thr,h) do {} while (0) /* nop */ +#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h) do {} while (0) /* nop */ +#define DUK_HNATFUNC_INCREF(thr,h) do {} while (0) /* nop */ +#define DUK_HNATFUNC_DECREF(thr,h) do {} while (0) /* nop */ +#define DUK_HNATFUNC_DECREF_NORZ(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFOBJ_INCREF(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFOBJ_DECREF(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFOBJ_DECREF_NORZ(thr,h) do {} while (0) /* nop */ +#define DUK_HTHREAD_INCREF(thr,h) do {} while (0) /* nop */ +#define DUK_HTHREAD_DECREF(thr,h) do {} while (0) /* nop */ +#define DUK_HTHREAD_DECREF_NORZ(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_INCREF_ALLOWNULL(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_DECREF_ALLOWNULL(thr,h) do {} while (0) /* nop */ +#define DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_INCREF_ALLOWNULL(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_DECREF_ALLOWNULL(thr,h) do {} while (0) /* nop */ +#define DUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr,h) do {} while (0) /* nop */ + +#define DUK_REFZERO_CHECK_FAST(thr) do {} while (0) /* nop */ +#define DUK_REFZERO_CHECK_SLOW(thr) do {} while (0) /* nop */ + +#define DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0(thr,tvptr_dst) do { \ + duk_tval *tv__dst; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_UNDEFINED(tv__dst); \ + DUK_UNREF((thr)); \ + } while (0) + +#define DUK_TVAL_SET_UNUSED_UPDREF_ALT0(thr,tvptr_dst) do { \ + duk_tval *tv__dst; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_UNUSED(tv__dst); \ + DUK_UNREF((thr)); \ + } while (0) + +#define DUK_TVAL_SET_NULL_UPDREF_ALT0(thr,tvptr_dst) do { \ + duk_tval *tv__dst; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_NULL(tv__dst); \ + DUK_UNREF((thr)); \ + } while (0) + +#define DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_BOOLEAN(tv__dst, (newval)); \ + DUK_UNREF((thr)); \ + } while (0) + +#define DUK_TVAL_SET_NUMBER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_NUMBER(tv__dst, (newval)); \ + DUK_UNREF((thr)); \ + } while (0) +#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv__dst, (newval)); \ + DUK_UNREF((thr)); \ + } while (0) +#define DUK_TVAL_SET_DOUBLE_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_DOUBLE(tv__dst, (newval)); \ + DUK_UNREF((thr)); \ + } while (0) +#define DUK_TVAL_SET_NAN_UPDREF_ALT0(thr,tvptr_dst) do { \ + duk_tval *tv__dst; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_NAN(tv__dst); \ + DUK_UNREF((thr)); \ + } while (0) +#if defined(DUK_USE_FASTINT) +#define DUK_TVAL_SET_I48_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_I48(tv__dst, (newval)); \ + DUK_UNREF((thr)); \ + } while (0) +#define DUK_TVAL_SET_I32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_I32(tv__dst, (newval)); \ + DUK_UNREF((thr)); \ + } while (0) +#define DUK_TVAL_SET_U32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_U32(tv__dst, (newval)); \ + DUK_UNREF((thr)); \ + } while (0) +#else +#define DUK_TVAL_SET_DOUBLE_CAST_UPDREF(thr,tvptr_dst,newval) \ + DUK_TVAL_SET_DOUBLE_UPDREF((thr), (tvptr_dst), (duk_double_t) (newval)) +#endif /* DUK_USE_FASTINT */ + +#define DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0(thr,tvptr_dst,lf_v,lf_fp,lf_flags) do { \ + duk_tval *tv__dst; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_LIGHTFUNC(tv__dst, (lf_v), (lf_fp), (lf_flags)); \ + DUK_UNREF((thr)); \ + } while (0) + +#define DUK_TVAL_SET_STRING_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_STRING(tv__dst, (newval)); \ + DUK_UNREF((thr)); \ + } while (0) + +#define DUK_TVAL_SET_OBJECT_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_OBJECT(tv__dst, (newval)); \ + DUK_UNREF((thr)); \ + } while (0) + +#define DUK_TVAL_SET_BUFFER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_BUFFER(tv__dst, (newval)); \ + DUK_UNREF((thr)); \ + } while (0) + +#define DUK_TVAL_SET_POINTER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \ + duk_tval *tv__dst; tv__dst = (tvptr_dst); \ + DUK_TVAL_SET_POINTER(tv__dst, (newval)); \ + DUK_UNREF((thr)); \ + } while (0) + +#define DUK_TVAL_SET_TVAL_UPDREF_ALT0(thr,tvptr_dst,tvptr_src) do { \ + duk_tval *tv__dst, *tv__src; \ + tv__dst = (tvptr_dst); tv__src = (tvptr_src); \ + DUK_TVAL_SET_TVAL(tv__dst, tv__src); \ + DUK_UNREF((thr)); \ + } while (0) + +#define DUK_TVAL_SET_UNDEFINED_UPDREF DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0 +#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0 +#define DUK_TVAL_SET_UNUSED_UPDREF DUK_TVAL_SET_UNUSED_UPDREF_ALT0 +#define DUK_TVAL_SET_NULL_UPDREF DUK_TVAL_SET_NULL_UPDREF_ALT0 +#define DUK_TVAL_SET_BOOLEAN_UPDREF DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0 +#define DUK_TVAL_SET_NUMBER_UPDREF DUK_TVAL_SET_NUMBER_UPDREF_ALT0 +#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0 +#define DUK_TVAL_SET_DOUBLE_UPDREF DUK_TVAL_SET_DOUBLE_UPDREF_ALT0 +#define DUK_TVAL_SET_NAN_UPDREF DUK_TVAL_SET_NAN_UPDREF_ALT0 +#if defined(DUK_USE_FASTINT) +#define DUK_TVAL_SET_I48_UPDREF DUK_TVAL_SET_I48_UPDREF_ALT0 +#define DUK_TVAL_SET_I32_UPDREF DUK_TVAL_SET_I32_UPDREF_ALT0 +#define DUK_TVAL_SET_U32_UPDREF DUK_TVAL_SET_U32_UPDREF_ALT0 +#else +#define DUK_TVAL_SET_I48_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF /* XXX: fast-int-to-double */ +#define DUK_TVAL_SET_I32_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF +#define DUK_TVAL_SET_U32_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF +#endif /* DUK_USE_FASTINT */ +#define DUK_TVAL_SET_FASTINT_UPDREF DUK_TVAL_SET_I48_UPDREF /* convenience */ +#define DUK_TVAL_SET_LIGHTFUNC_UPDREF DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0 +#define DUK_TVAL_SET_STRING_UPDREF DUK_TVAL_SET_STRING_UPDREF_ALT0 +#define DUK_TVAL_SET_OBJECT_UPDREF DUK_TVAL_SET_OBJECT_UPDREF_ALT0 +#define DUK_TVAL_SET_BUFFER_UPDREF DUK_TVAL_SET_BUFFER_UPDREF_ALT0 +#define DUK_TVAL_SET_POINTER_UPDREF DUK_TVAL_SET_POINTER_UPDREF_ALT0 + +#define DUK_TVAL_SET_TVAL_UPDREF DUK_TVAL_SET_TVAL_UPDREF_ALT0 +#define DUK_TVAL_SET_TVAL_UPDREF_FAST DUK_TVAL_SET_TVAL_UPDREF_ALT0 +#define DUK_TVAL_SET_TVAL_UPDREF_SLOW DUK_TVAL_SET_TVAL_UPDREF_ALT0 + +#endif /* DUK_USE_REFERENCE_COUNTING */ + +/* + * Some convenience macros that don't have optimized implementations now. + */ + +#define DUK_TVAL_SET_TVAL_UPDREF_NORZ(thr,tv_dst,tv_src) do { \ + duk_hthread *duk__thr = (thr); \ + duk_tval *duk__dst = (tv_dst); \ + duk_tval *duk__src = (tv_src); \ + DUK_UNREF(duk__thr); \ + DUK_TVAL_DECREF_NORZ(thr, duk__dst); \ + DUK_TVAL_SET_TVAL(duk__dst, duk__src); \ + DUK_TVAL_INCREF(thr, duk__dst); \ + } while (0) + +#define DUK_TVAL_SET_U32_UPDREF_NORZ(thr,tv_dst,val) do { \ + duk_hthread *duk__thr = (thr); \ + duk_tval *duk__dst = (tv_dst); \ + duk_uint32_t duk__val = (duk_uint32_t) (val); \ + DUK_UNREF(duk__thr); \ + DUK_TVAL_DECREF_NORZ(thr, duk__dst); \ + DUK_TVAL_SET_U32(duk__dst, duk__val); \ + } while (0) + +/* + * Prototypes + */ + +#if defined(DUK_USE_REFERENCE_COUNTING) +#if defined(DUK_USE_FINALIZER_SUPPORT) +DUK_INTERNAL_DECL void duk_refzero_check_slow(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_refzero_check_fast(duk_hthread *thr); +#endif +DUK_INTERNAL_DECL void duk_heaphdr_refcount_finalize_norz(duk_heap *heap, duk_heaphdr *hdr); +DUK_INTERNAL_DECL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject *h); +#if 0 /* Not needed: fast path handles inline; slow path uses duk_heaphdr_decref() which is needed anyway. */ +DUK_INTERNAL_DECL void duk_hstring_decref(duk_hthread *thr, duk_hstring *h); +DUK_INTERNAL_DECL void duk_hstring_decref_norz(duk_hthread *thr, duk_hstring *h); +DUK_INTERNAL_DECL void duk_hbuffer_decref(duk_hthread *thr, duk_hbuffer *h); +DUK_INTERNAL_DECL void duk_hbuffer_decref_norz(duk_hthread *thr, duk_hbuffer *h); +DUK_INTERNAL_DECL void duk_hobject_decref(duk_hthread *thr, duk_hobject *h); +DUK_INTERNAL_DECL void duk_hobject_decref_norz(duk_hthread *thr, duk_hobject *h); +#endif +DUK_INTERNAL_DECL void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h); +DUK_INTERNAL_DECL void duk_heaphdr_refzero_norz(duk_hthread *thr, duk_heaphdr *h); +#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT) +DUK_INTERNAL_DECL void duk_hstring_refzero(duk_hthread *thr, duk_hstring *h); /* no 'norz' variant */ +DUK_INTERNAL_DECL void duk_hbuffer_refzero(duk_hthread *thr, duk_hbuffer *h); /* no 'norz' variant */ +DUK_INTERNAL_DECL void duk_hobject_refzero(duk_hthread *thr, duk_hobject *h); +DUK_INTERNAL_DECL void duk_hobject_refzero_norz(duk_hthread *thr, duk_hobject *h); +#else +DUK_INTERNAL_DECL void duk_tval_incref(duk_tval *tv); +DUK_INTERNAL_DECL void duk_tval_decref(duk_hthread *thr, duk_tval *tv); +DUK_INTERNAL_DECL void duk_tval_decref_norz(duk_hthread *thr, duk_tval *tv); +DUK_INTERNAL_DECL void duk_heaphdr_incref(duk_heaphdr *h); +DUK_INTERNAL_DECL void duk_heaphdr_decref(duk_hthread *thr, duk_heaphdr *h); +DUK_INTERNAL_DECL void duk_heaphdr_decref_norz(duk_hthread *thr, duk_heaphdr *h); +#endif +#else /* DUK_USE_REFERENCE_COUNTING */ +/* no refcounting */ +#endif /* DUK_USE_REFERENCE_COUNTING */ + +#endif /* DUK_REFCOUNT_H_INCLUDED */ diff --git a/third_party/duktape/duk_regexp.h b/third_party/duktape/duk_regexp.h new file mode 100644 index 00000000..b58335fe --- /dev/null +++ b/third_party/duktape/duk_regexp.h @@ -0,0 +1,84 @@ +/* + * Regular expression structs, constants, and bytecode defines. + */ + +#if !defined(DUK_REGEXP_H_INCLUDED) +#define DUK_REGEXP_H_INCLUDED + +/* maximum bytecode copies for {n,m} quantifiers */ +#define DUK_RE_MAX_ATOM_COPIES 1000 + +/* regexp compilation limits */ +#define DUK_RE_COMPILE_TOKEN_LIMIT 100000000L /* 1e8 */ + +/* regexp execution limits */ +#define DUK_RE_EXECUTE_STEPS_LIMIT 1000000000L /* 1e9 */ + +/* regexp opcodes */ +#define DUK_REOP_MATCH 1 +#define DUK_REOP_CHAR 2 +#define DUK_REOP_PERIOD 3 +#define DUK_REOP_RANGES 4 +#define DUK_REOP_INVRANGES 5 +#define DUK_REOP_JUMP 6 +#define DUK_REOP_SPLIT1 7 +#define DUK_REOP_SPLIT2 8 +#define DUK_REOP_SQMINIMAL 9 +#define DUK_REOP_SQGREEDY 10 +#define DUK_REOP_SAVE 11 +#define DUK_REOP_WIPERANGE 12 +#define DUK_REOP_LOOKPOS 13 +#define DUK_REOP_LOOKNEG 14 +#define DUK_REOP_BACKREFERENCE 15 +#define DUK_REOP_ASSERT_START 16 +#define DUK_REOP_ASSERT_END 17 +#define DUK_REOP_ASSERT_WORD_BOUNDARY 18 +#define DUK_REOP_ASSERT_NOT_WORD_BOUNDARY 19 + +/* flags */ +#define DUK_RE_FLAG_GLOBAL (1U << 0) +#define DUK_RE_FLAG_IGNORE_CASE (1U << 1) +#define DUK_RE_FLAG_MULTILINE (1U << 2) + +struct duk_re_matcher_ctx { + duk_hthread *thr; + + duk_uint32_t re_flags; + const duk_uint8_t *input; + const duk_uint8_t *input_end; + const duk_uint8_t *bytecode; + const duk_uint8_t *bytecode_end; + const duk_uint8_t **saved; /* allocated from valstack (fixed buffer) */ + duk_uint32_t nsaved; + duk_uint32_t recursion_depth; + duk_uint32_t recursion_limit; + duk_uint32_t steps_count; + duk_uint32_t steps_limit; +}; + +struct duk_re_compiler_ctx { + duk_hthread *thr; + + duk_uint32_t re_flags; + duk_lexer_ctx lex; + duk_re_token curr_token; + duk_bufwriter_ctx bw; + duk_uint32_t captures; /* highest capture number emitted so far (used as: ++captures) */ + duk_uint32_t highest_backref; + duk_uint32_t recursion_depth; + duk_uint32_t recursion_limit; + duk_uint32_t nranges; /* internal temporary value, used for char classes */ +}; + +/* + * Prototypes + */ + +#if defined(DUK_USE_REGEXP_SUPPORT) +DUK_INTERNAL_DECL void duk_regexp_compile(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_regexp_create_instance(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_regexp_match(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_regexp_match_force_global(duk_hthread *thr); /* hacky helper for String.prototype.split() */ +#endif + +#endif /* DUK_REGEXP_H_INCLUDED */ diff --git a/third_party/duktape/duk_regexp_compiler.c b/third_party/duktape/duk_regexp_compiler.c new file mode 100644 index 00000000..1de08156 --- /dev/null +++ b/third_party/duktape/duk_regexp_compiler.c @@ -0,0 +1,1287 @@ +/* + * Regexp compilation. + * + * See doc/regexp.rst for a discussion of the compilation approach and + * current limitations. + * + * Regexp bytecode assumes jumps can be expressed with signed 32-bit + * integers. Consequently the bytecode size must not exceed 0x7fffffffL. + * The implementation casts duk_size_t (buffer size) to duk_(u)int32_t + * in many places. Although this could be changed, the bytecode format + * limit would still prevent regexps exceeding the signed 32-bit limit + * from working. + * + * XXX: The implementation does not prevent bytecode from exceeding the + * maximum supported size. This could be done by limiting the maximum + * input string size (assuming an upper bound can be computed for number + * of bytecode bytes emitted per input byte) or checking buffer maximum + * size when emitting bytecode (slower). + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_REGEXP_SUPPORT) + +/* + * Helper macros + */ + +#define DUK__RE_INITIAL_BUFSIZE 64 + +#define DUK__RE_BUFLEN(re_ctx) \ + DUK_BW_GET_SIZE(re_ctx->thr, &re_ctx->bw) + +/* + * Disjunction struct: result of parsing a disjunction + */ + +typedef struct { + /* Number of characters that the atom matches (e.g. 3 for 'abc'), + * -1 if atom is complex and number of matched characters either + * varies or is not known. + */ + duk_int32_t charlen; + +#if 0 + /* These are not needed to implement quantifier capture handling, + * but might be needed at some point. + */ + + /* re_ctx->captures at start and end of atom parsing. + * Since 'captures' indicates highest capture number emitted + * so far in a DUK_REOP_SAVE, the captures numbers saved by + * the atom are: ]start_captures,end_captures]. + */ + duk_uint32_t start_captures; + duk_uint32_t end_captures; +#endif +} duk__re_disjunction_info; + +/* + * Encoding helpers + * + * Some of the typing is bytecode based, e.g. slice sizes are unsigned 32-bit + * even though the buffer operations will use duk_size_t. + */ + +/* XXX: the insert helpers should ensure that the bytecode result is not + * larger than expected (or at least assert for it). Many things in the + * bytecode, like skip offsets, won't work correctly if the bytecode is + * larger than say 2G. + */ + +DUK_LOCAL duk_uint32_t duk__encode_i32(duk_int32_t x) { + if (x < 0) { + return ((duk_uint32_t) (-x)) * 2 + 1; + } else { + return ((duk_uint32_t) x) * 2; + } +} + +/* XXX: return type should probably be duk_size_t, or explicit checks are needed for + * maximum size. + */ +DUK_LOCAL duk_uint32_t duk__insert_u32(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_uint32_t x) { + duk_uint8_t buf[DUK_UNICODE_MAX_XUTF8_LENGTH]; + duk_small_int_t len; + + len = duk_unicode_encode_xutf8((duk_ucodepoint_t) x, buf); + DUK_ASSERT(len >= 0); + DUK_BW_INSERT_ENSURE_BYTES(re_ctx->thr, &re_ctx->bw, offset, buf, (duk_size_t) len); + return (duk_uint32_t) len; +} + +DUK_LOCAL void duk__append_u32(duk_re_compiler_ctx *re_ctx, duk_uint32_t x) { + DUK_BW_WRITE_ENSURE_XUTF8(re_ctx->thr, &re_ctx->bw, x); +} + +DUK_LOCAL void duk__append_7bit(duk_re_compiler_ctx *re_ctx, duk_uint32_t x) { +#if defined(DUK_USE_PREFER_SIZE) + duk__append_u32(re_ctx, x); +#else + DUK_ASSERT(x <= 0x7fU); + DUK_BW_WRITE_ENSURE_U8(re_ctx->thr, &re_ctx->bw, (duk_uint8_t) x); +#endif +} + +#if 0 +DUK_LOCAL void duk__append_2bytes(duk_re_compiler_ctx *re_ctx, duk_uint8_t x, duk_uint8_t y) { + DUK_BW_WRITE_ENSURE_U8_2(re_ctx->thr, &re_ctx->bw, x, y); +} +#endif + +DUK_LOCAL duk_uint32_t duk__insert_i32(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_int32_t x) { + return duk__insert_u32(re_ctx, offset, duk__encode_i32(x)); +} + +DUK_LOCAL void duk__append_reop(duk_re_compiler_ctx *re_ctx, duk_uint32_t reop) { + DUK_ASSERT(reop <= 0x7fU); + (void) duk__append_7bit(re_ctx, reop); +} + +#if 0 /* unused */ +DUK_LOCAL void duk__append_i32(duk_re_compiler_ctx *re_ctx, duk_int32_t x) { + duk__append_u32(re_ctx, duk__encode_i32(x)); +} +#endif + +/* special helper for emitting u16 lists (used for character ranges for built-in char classes) */ +DUK_LOCAL void duk__append_u16_list(duk_re_compiler_ctx *re_ctx, const duk_uint16_t *values, duk_uint32_t count) { + /* Call sites don't need the result length so it's not accumulated. */ + while (count-- > 0) { + duk__append_u32(re_ctx, (duk_uint32_t) (*values++)); + } +} + +DUK_LOCAL void duk__insert_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_uint32_t data_offset, duk_uint32_t data_length) { + DUK_BW_INSERT_ENSURE_SLICE(re_ctx->thr, &re_ctx->bw, offset, data_offset, data_length); +} + +DUK_LOCAL void duk__append_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t data_offset, duk_uint32_t data_length) { + DUK_BW_WRITE_ENSURE_SLICE(re_ctx->thr, &re_ctx->bw, data_offset, data_length); +} + +DUK_LOCAL void duk__remove_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t data_offset, duk_uint32_t data_length) { + DUK_BW_REMOVE_ENSURE_SLICE(re_ctx->thr, &re_ctx->bw, data_offset, data_length); +} + +/* + * Insert a jump offset at 'offset' to complete an instruction + * (the jump offset is always the last component of an instruction). + * The 'skip' argument must be computed relative to 'offset', + * -without- taking into account the skip field being inserted. + * + * ... A B C ins X Y Z ... (ins may be a JUMP, SPLIT1/SPLIT2, etc) + * => ... A B C ins SKIP X Y Z + * + * Computing the final (adjusted) skip value, which is relative to the + * first byte of the next instruction, is a bit tricky because of the + * variable length UTF-8 encoding. See doc/regexp.rst for discussion. + */ +DUK_LOCAL duk_uint32_t duk__insert_jump_offset(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_int32_t skip) { +#if 0 + /* Iterative solution. */ + if (skip < 0) { + duk_small_int_t len; + /* two encoding attempts suffices */ + len = duk_unicode_get_xutf8_length((duk_codepoint_t) duk__encode_i32(skip)); + len = duk_unicode_get_xutf8_length((duk_codepoint_t) duk__encode_i32(skip - (duk_int32_t) len)); + DUK_ASSERT(duk_unicode_get_xutf8_length(duk__encode_i32(skip - (duk_int32_t) len)) == len); /* no change */ + skip -= (duk_int32_t) len; + } +#endif + +#if defined(DUK_USE_PREFER_SIZE) + /* Closed form solution, this produces smallest code. + * See re_neg_jump_offset (closed2). + */ + if (skip < 0) { + skip--; + if (skip < -0x3fL) { + skip--; + } + if (skip < -0x3ffL) { + skip--; + } + if (skip < -0x7fffL) { + skip--; + } + if (skip < -0xfffffL) { + skip--; + } + if (skip < -0x1ffffffL) { + skip--; + } + if (skip < -0x3fffffffL) { + skip--; + } + } +#else /* DUK_USE_PREFER_SIZE */ + /* Closed form solution, this produces fastest code. + * See re_neg_jump_offset (closed1). + */ + if (skip < 0) { + if (skip >= -0x3eL) { + skip -= 1; + } else if (skip >= -0x3fdL) { + skip -= 2; + } else if (skip >= -0x7ffcL) { + skip -= 3; + } else if (skip >= -0xffffbL) { + skip -= 4; + } else if (skip >= -0x1fffffaL) { + skip -= 5; + } else if (skip >= -0x3ffffff9L) { + skip -= 6; + } else { + skip -= 7; + } + } +#endif /* DUK_USE_PREFER_SIZE */ + + return duk__insert_i32(re_ctx, offset, skip); +} + +DUK_LOCAL duk_uint32_t duk__append_jump_offset(duk_re_compiler_ctx *re_ctx, duk_int32_t skip) { + return (duk_uint32_t) duk__insert_jump_offset(re_ctx, (duk_uint32_t) DUK__RE_BUFLEN(re_ctx), skip); +} + +/* + * duk_re_range_callback for generating character class ranges. + * + * When ignoreCase is false, the range is simply emitted as is. We don't, + * for instance, eliminate duplicates or overlapping ranges in a character + * class. + * + * When ignoreCase is true but the 'direct' flag is set, the caller knows + * that the range canonicalizes to itself for case insensitive matching, + * so the range is emitted as is. This is mainly useful for built-in ranges + * like \W. + * + * Otherwise, when ignoreCase is true, the range needs to be normalized + * through canonicalization. Unfortunately a canonicalized version of a + * continuous range is not necessarily continuous (e.g. [x-{] is continuous + * but [X-{] is not). As a result, a single input range may expand to a lot + * of output ranges. The current algorithm creates the canonicalized ranges + * footprint efficiently at the cost of compile time execution time; see + * doc/regexp.rst for discussion, and some more details below. + * + * Note that the ctx->nranges is a context-wide temporary value. This is OK + * because there cannot be multiple character classes being parsed + * simultaneously. + * + * More detail on canonicalization: + * + * Conceptually, a range is canonicalized by scanning the entire range, + * normalizing each codepoint by converting it to uppercase, and generating + * a set of result ranges. + * + * Ideally a minimal set of output ranges would be emitted by merging all + * possible ranges even if they're emitted out of sequence. Because the + * input string is also case normalized during matching, some codepoints + * never occur at runtime; these "don't care" codepoints can be included or + * excluded from ranges when merging/optimizing ranges. + * + * The current algorithm does not do optimal range merging. Rather, output + * codepoints are generated in sequence, and when the output codepoints are + * continuous (CP, CP+1, CP+2, ...), they are merged locally into as large a + * range as possible. A small canonicalization bitmap is used to reduce + * actual codepoint canonicalizations which are quite slow at present. The + * bitmap provides a "codepoint block is continuous with respect to + * canonicalization" for N-codepoint blocks. This allows blocks to be + * skipped quickly. + * + * There are a number of shortcomings and future work here: + * + * - Individual codepoint normalizations are slow because they involve + * walking bit-packed rules without a lookup index. + * + * - The conceptual algorithm needs to canonicalize every codepoint in the + * input range to figure out the output range(s). Even with the small + * canonicalization bitmap the algorithm runs quite slowly for worst case + * inputs. There are many data structure alternatives to improve this. + * + * - While the current algorithm generates maximal output ranges when the + * output codepoints are emitted linearly, output ranges are not sorted or + * merged otherwise. In the worst case a lot of ranges are emitted when + * most of the ranges could be merged. In this process one could take + * advantage of "don't care" codepoints, which are never matched against at + * runtime due to canonicalization of input codepoints before comparison, + * to merge otherwise discontinuous output ranges. + * + * - The runtime data structure is just a linear list of ranges to match + * against. This can be quite slow if there are a lot of output ranges. + * There are various ways to make matching against the ranges faster, + * e.g. sorting the ranges and using a binary search; skip lists; tree + * based representations; full or approximate codepoint bitmaps, etc. + * + * - Only BMP is supported, codepoints above BMP are assumed to canonicalize + * to themselves. For now this is one place where we don't want to + * support chars outside the BMP, because the exhaustive search would be + * massively larger. It would be possible to support non-BMP with a + * different algorithm, or perhaps doing case normalization only at match + * time. + */ + +DUK_LOCAL void duk__regexp_emit_range(duk_re_compiler_ctx *re_ctx, duk_codepoint_t r1, duk_codepoint_t r2) { + DUK_ASSERT(r2 >= r1); + duk__append_u32(re_ctx, (duk_uint32_t) r1); + duk__append_u32(re_ctx, (duk_uint32_t) r2); + re_ctx->nranges++; +} + +#if defined(DUK_USE_REGEXP_CANON_BITMAP) +/* Find next canonicalization discontinuity (conservative estimate) starting + * from 'start', not exceeding 'end'. If continuity is fine up to 'end' + * inclusive, returns end. Minimum possible return value is start. + */ +DUK_LOCAL duk_codepoint_t duk__re_canon_next_discontinuity(duk_codepoint_t start, duk_codepoint_t end) { + duk_uint_t start_blk; + duk_uint_t end_blk; + duk_uint_t blk; + duk_uint_t offset; + duk_uint8_t mask; + + /* Inclusive block range. */ + DUK_ASSERT(start >= 0); + DUK_ASSERT(end >= 0); + DUK_ASSERT(end >= start); + start_blk = (duk_uint_t) (start >> DUK_CANON_BITMAP_BLKSHIFT); + end_blk = (duk_uint_t) (end >> DUK_CANON_BITMAP_BLKSHIFT); + + for (blk = start_blk; blk <= end_blk; blk++) { + offset = blk >> 3; + mask = 1U << (blk & 0x07); + if (offset >= sizeof(duk_unicode_re_canon_bitmap)) { + /* Reached non-BMP range which is assumed continuous. */ + return end; + } + DUK_ASSERT(offset < sizeof(duk_unicode_re_canon_bitmap)); + if ((duk_unicode_re_canon_bitmap[offset] & mask) == 0) { + /* Block is discontinuous, continuity is guaranteed + * only up to end of previous block (+1 for exclusive + * return value => start of current block). Start + * block requires special handling. + */ + if (blk > start_blk) { + return (duk_codepoint_t) (blk << DUK_CANON_BITMAP_BLKSHIFT); + } else { + return start; + } + } + } + DUK_ASSERT(blk == end_blk + 1); /* Reached end block which is continuous. */ + return end; +} +#else /* DUK_USE_REGEXP_CANON_BITMAP */ +DUK_LOCAL duk_codepoint_t duk__re_canon_next_discontinuity(duk_codepoint_t start, duk_codepoint_t end) { + DUK_ASSERT(start >= 0); + DUK_ASSERT(end >= 0); + DUK_ASSERT(end >= start); + if (start >= 0x10000) { + /* Even without the bitmap, treat non-BMP as continuous. */ + return end; + } + return start; +} +#endif /* DUK_USE_REGEXP_CANON_BITMAP */ + +DUK_LOCAL void duk__regexp_generate_ranges(void *userdata, duk_codepoint_t r1, duk_codepoint_t r2, duk_bool_t direct) { + duk_re_compiler_ctx *re_ctx = (duk_re_compiler_ctx *) userdata; + duk_codepoint_t r_start; + duk_codepoint_t r_end; + duk_codepoint_t i; + duk_codepoint_t t; + duk_codepoint_t r_disc; + + DUK_DD(DUK_DDPRINT("duk__regexp_generate_ranges(): re_ctx=%p, range=[%ld,%ld] direct=%ld", + (void *) re_ctx, (long) r1, (long) r2, (long) direct)); + + DUK_ASSERT(r2 >= r1); /* SyntaxError for out of order range. */ + + if (direct || (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) == 0) { + DUK_DD(DUK_DDPRINT("direct or not case sensitive, emit range: [%ld,%ld]", (long) r1, (long) r2)); + duk__regexp_emit_range(re_ctx, r1, r2); + return; + } + + DUK_DD(DUK_DDPRINT("case sensitive, process range: [%ld,%ld]", (long) r1, (long) r2)); + + r_start = duk_unicode_re_canonicalize_char(re_ctx->thr, r1); + r_end = r_start; + + for (i = r1 + 1; i <= r2;) { + /* Input codepoint space processed up to i-1, and + * current range in r_{start,end} is up-to-date + * (inclusive) and may either break or continue. + */ + r_disc = duk__re_canon_next_discontinuity(i, r2); + DUK_ASSERT(r_disc >= i); + DUK_ASSERT(r_disc <= r2); + + r_end += r_disc - i; /* May be zero. */ + t = duk_unicode_re_canonicalize_char(re_ctx->thr, r_disc); + if (t == r_end + 1) { + /* Not actually a discontinuity, continue range + * to r_disc and recheck. + */ + r_end = t; + } else { + duk__regexp_emit_range(re_ctx, r_start, r_end); + r_start = t; + r_end = t; + } + i = r_disc + 1; /* Guarantees progress. */ + } + duk__regexp_emit_range(re_ctx, r_start, r_end); + +#if 0 /* Exhaustive search, very slow. */ + r_start = duk_unicode_re_canonicalize_char(re_ctx->thr, r1); + r_end = r_start; + for (i = r1 + 1; i <= r2; i++) { + t = duk_unicode_re_canonicalize_char(re_ctx->thr, i); + if (t == r_end + 1) { + r_end = t; + } else { + DUK_DD(DUK_DDPRINT("canonicalized, emit range: [%ld,%ld]", (long) r_start, (long) r_end)); + duk__append_u32(re_ctx, (duk_uint32_t) r_start); + duk__append_u32(re_ctx, (duk_uint32_t) r_end); + re_ctx->nranges++; + r_start = t; + r_end = t; + } + } + DUK_DD(DUK_DDPRINT("canonicalized, emit range: [%ld,%ld]", (long) r_start, (long) r_end)); + duk__append_u32(re_ctx, (duk_uint32_t) r_start); + duk__append_u32(re_ctx, (duk_uint32_t) r_end); + re_ctx->nranges++; +#endif +} + +/* + * Parse regexp Disjunction. Most of regexp compilation happens here. + * + * Handles Disjunction, Alternative, and Term productions directly without + * recursion. The only constructs requiring recursion are positive/negative + * lookaheads, capturing parentheses, and non-capturing parentheses. + * + * The function determines whether the entire disjunction is a 'simple atom' + * (see doc/regexp.rst discussion on 'simple quantifiers') and if so, + * returns the atom character length which is needed by the caller to keep + * track of its own atom character length. A disjunction with more than one + * alternative is never considered a simple atom (although in some cases + * that might be the case). + * + * Return value: simple atom character length or < 0 if not a simple atom. + * Appends the bytecode for the disjunction matcher to the end of the temp + * buffer. + * + * Regexp top level structure is: + * + * Disjunction = Term* + * | Term* | Disjunction + * + * Term = Assertion + * | Atom + * | Atom Quantifier + * + * An empty Term sequence is a valid disjunction alternative (e.g. /|||c||/). + * + * Notes: + * + * * Tracking of the 'simple-ness' of the current atom vs. the entire + * disjunction are separate matters. For instance, the disjunction + * may be complex, but individual atoms may be simple. Furthermore, + * simple quantifiers are used whenever possible, even if the + * disjunction as a whole is complex. + * + * * The estimate of whether an atom is simple is conservative now, + * and it would be possible to expand it. For instance, captures + * cause the disjunction to be marked complex, even though captures + * -can- be handled by simple quantifiers with some minor modifications. + * + * * Disjunction 'tainting' as 'complex' is handled at the end of the + * main for loop collectively for atoms. Assertions, quantifiers, + * and '|' tokens need to taint the result manually if necessary. + * Assertions cannot add to result char length, only atoms (and + * quantifiers) can; currently quantifiers will taint the result + * as complex though. + */ + +DUK_LOCAL const duk_uint16_t * const duk__re_range_lookup1[3] = { + duk_unicode_re_ranges_digit, + duk_unicode_re_ranges_white, + duk_unicode_re_ranges_wordchar +}; +DUK_LOCAL const duk_uint8_t duk__re_range_lookup2[3] = { + sizeof(duk_unicode_re_ranges_digit) / (2 * sizeof(duk_uint16_t)), + sizeof(duk_unicode_re_ranges_white) / (2 * sizeof(duk_uint16_t)), + sizeof(duk_unicode_re_ranges_wordchar) / (2 * sizeof(duk_uint16_t)) +}; + +DUK_LOCAL void duk__append_range_atom_matcher(duk_re_compiler_ctx *re_ctx, duk_small_uint_t re_op, const duk_uint16_t *ranges, duk_small_uint_t count) { +#if 0 + DUK_ASSERT(re_op <= 0x7fUL); + DUK_ASSERT(count <= 0x7fUL); + duk__append_2bytes(re_ctx, (duk_uint8_t) re_op, (duk_uint8_t) count); +#endif + duk__append_reop(re_ctx, re_op); + duk__append_7bit(re_ctx, count); + duk__append_u16_list(re_ctx, ranges, count * 2); +} + +DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t expect_eof, duk__re_disjunction_info *out_atom_info) { + duk_int32_t atom_start_offset = -1; /* negative -> no atom matched on previous round */ + duk_int32_t atom_char_length = 0; /* negative -> complex atom */ + duk_uint32_t atom_start_captures = re_ctx->captures; /* value of re_ctx->captures at start of atom */ + duk_int32_t unpatched_disjunction_split = -1; + duk_int32_t unpatched_disjunction_jump = -1; + duk_uint32_t entry_offset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx); + duk_int32_t res_charlen = 0; /* -1 if disjunction is complex, char length if simple */ + duk__re_disjunction_info tmp_disj; + + DUK_ASSERT(out_atom_info != NULL); + + duk_native_stack_check(re_ctx->thr); + if (re_ctx->recursion_depth >= re_ctx->recursion_limit) { + DUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_COMPILER_RECURSION_LIMIT); + DUK_WO_NORETURN(return;); + } + re_ctx->recursion_depth++; + +#if 0 + out_atom_info->start_captures = re_ctx->captures; +#endif + + for (;;) { + /* atom_char_length, atom_start_offset, atom_start_offset reflect the + * atom matched on the previous loop. If a quantifier is encountered + * on this loop, these are needed to handle the quantifier correctly. + * new_atom_char_length etc are for the atom parsed on this round; + * they're written to atom_char_length etc at the end of the round. + */ + duk_int32_t new_atom_char_length; /* char length of the atom parsed in this loop */ + duk_int32_t new_atom_start_offset; /* bytecode start offset of the atom parsed in this loop + * (allows quantifiers to copy the atom bytecode) + */ + duk_uint32_t new_atom_start_captures; /* re_ctx->captures at the start of the atom parsed in this loop */ + + duk_lexer_parse_re_token(&re_ctx->lex, &re_ctx->curr_token); + + DUK_DD(DUK_DDPRINT("re token: %ld (num=%ld, char=%c)", + (long) re_ctx->curr_token.t, + (long) re_ctx->curr_token.num, + (re_ctx->curr_token.num >= 0x20 && re_ctx->curr_token.num <= 0x7e) ? + (int) re_ctx->curr_token.num : (int) '?')); + + /* set by atom case clauses */ + new_atom_start_offset = -1; + new_atom_char_length = -1; + new_atom_start_captures = re_ctx->captures; + + switch (re_ctx->curr_token.t) { + case DUK_RETOK_DISJUNCTION: { + /* + * The handling here is a bit tricky. If a previous '|' has been processed, + * we have a pending split1 and a pending jump (for a previous match). These + * need to be back-patched carefully. See docs for a detailed example. + */ + + /* patch pending jump and split */ + if (unpatched_disjunction_jump >= 0) { + duk_uint32_t offset; + + DUK_ASSERT(unpatched_disjunction_split >= 0); + offset = (duk_uint32_t) unpatched_disjunction_jump; + offset += duk__insert_jump_offset(re_ctx, + offset, + (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - offset)); + /* offset is now target of the pending split (right after jump) */ + duk__insert_jump_offset(re_ctx, + (duk_uint32_t) unpatched_disjunction_split, + (duk_int32_t) offset - unpatched_disjunction_split); + } + + /* add a new pending split to the beginning of the entire disjunction */ + (void) duk__insert_u32(re_ctx, + entry_offset, + DUK_REOP_SPLIT1); /* prefer direct execution */ + unpatched_disjunction_split = (duk_int32_t) (entry_offset + 1); /* +1 for opcode */ + + /* add a new pending match jump for latest finished alternative */ + duk__append_reop(re_ctx, DUK_REOP_JUMP); + unpatched_disjunction_jump = (duk_int32_t) DUK__RE_BUFLEN(re_ctx); + + /* 'taint' result as complex */ + res_charlen = -1; + break; + } + case DUK_RETOK_QUANTIFIER: { + if (atom_start_offset < 0) { + DUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_INVALID_QUANTIFIER_NO_ATOM); + DUK_WO_NORETURN(return;); + } + if (re_ctx->curr_token.qmin > re_ctx->curr_token.qmax) { + DUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_INVALID_QUANTIFIER_VALUES); + DUK_WO_NORETURN(return;); + } + if (atom_char_length >= 0) { + /* + * Simple atom + * + * If atom_char_length is zero, we'll have unbounded execution time for e.g. + * /()*x/.exec('x'). We can't just skip the match because it might have some + * side effects (for instance, if we allowed captures in simple atoms, the + * capture needs to happen). The simple solution below is to force the + * quantifier to match at most once, since the additional matches have no effect. + * + * With a simple atom there can be no capture groups, so no captures need + * to be reset. + */ + duk_int32_t atom_code_length; + duk_uint32_t offset; + duk_uint32_t qmin, qmax; + + qmin = re_ctx->curr_token.qmin; + qmax = re_ctx->curr_token.qmax; + if (atom_char_length == 0) { + /* qmin and qmax will be 0 or 1 */ + if (qmin > 1) { + qmin = 1; + } + if (qmax > 1) { + qmax = 1; + } + } + + duk__append_reop(re_ctx, DUK_REOP_MATCH); /* complete 'sub atom' */ + atom_code_length = (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - (duk_size_t) atom_start_offset); + + offset = (duk_uint32_t) atom_start_offset; + if (re_ctx->curr_token.greedy) { + offset += duk__insert_u32(re_ctx, offset, DUK_REOP_SQGREEDY); + offset += duk__insert_u32(re_ctx, offset, qmin); + offset += duk__insert_u32(re_ctx, offset, qmax); + offset += duk__insert_u32(re_ctx, offset, (duk_uint32_t) atom_char_length); + offset += duk__insert_jump_offset(re_ctx, offset, atom_code_length); + } else { + offset += duk__insert_u32(re_ctx, offset, DUK_REOP_SQMINIMAL); + offset += duk__insert_u32(re_ctx, offset, qmin); + offset += duk__insert_u32(re_ctx, offset, qmax); + offset += duk__insert_jump_offset(re_ctx, offset, atom_code_length); + } + DUK_UNREF(offset); /* silence scan-build warning */ + } else { + /* + * Complex atom + * + * The original code is used as a template, and removed at the end + * (this differs from the handling of simple quantifiers). + * + * NOTE: there is no current solution for empty atoms in complex + * quantifiers. This would need some sort of a 'progress' instruction. + * + * XXX: impose limit on maximum result size, i.e. atom_code_len * atom_copies? + */ + duk_int32_t atom_code_length; + duk_uint32_t atom_copies; + duk_uint32_t tmp_qmin, tmp_qmax; + + /* pre-check how many atom copies we're willing to make (atom_copies not needed below) */ + atom_copies = (re_ctx->curr_token.qmax == DUK_RE_QUANTIFIER_INFINITE) ? + re_ctx->curr_token.qmin : re_ctx->curr_token.qmax; + if (atom_copies > DUK_RE_MAX_ATOM_COPIES) { + DUK_ERROR_RANGE(re_ctx->thr, DUK_STR_QUANTIFIER_TOO_MANY_COPIES); + DUK_WO_NORETURN(return;); + } + + /* wipe the capture range made by the atom (if any) */ + DUK_ASSERT(atom_start_captures <= re_ctx->captures); + if (atom_start_captures != re_ctx->captures) { + DUK_ASSERT(atom_start_captures < re_ctx->captures); + DUK_DDD(DUK_DDDPRINT("must wipe ]atom_start_captures,re_ctx->captures]: ]%ld,%ld]", + (long) atom_start_captures, (long) re_ctx->captures)); + + /* insert (DUK_REOP_WIPERANGE, start, count) in reverse order so the order ends up right */ + duk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, (re_ctx->captures - atom_start_captures) * 2U); + duk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, (atom_start_captures + 1) * 2); + duk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, DUK_REOP_WIPERANGE); + } else { + DUK_DDD(DUK_DDDPRINT("no need to wipe captures: atom_start_captures == re_ctx->captures == %ld", + (long) atom_start_captures)); + } + + atom_code_length = (duk_int32_t) DUK__RE_BUFLEN(re_ctx) - atom_start_offset; + + /* insert the required matches (qmin) by copying the atom */ + tmp_qmin = re_ctx->curr_token.qmin; + tmp_qmax = re_ctx->curr_token.qmax; + while (tmp_qmin > 0) { + duk__append_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length); + tmp_qmin--; + if (tmp_qmax != DUK_RE_QUANTIFIER_INFINITE) { + tmp_qmax--; + } + } + DUK_ASSERT(tmp_qmin == 0); + + /* insert code for matching the remainder - infinite or finite */ + if (tmp_qmax == DUK_RE_QUANTIFIER_INFINITE) { + /* reuse last emitted atom for remaining 'infinite' quantifier */ + + if (re_ctx->curr_token.qmin == 0) { + /* Special case: original qmin was zero so there is nothing + * to repeat. Emit an atom copy but jump over it here. + */ + duk__append_reop(re_ctx, DUK_REOP_JUMP); + duk__append_jump_offset(re_ctx, atom_code_length); + duk__append_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length); + } + if (re_ctx->curr_token.greedy) { + duk__append_reop(re_ctx, DUK_REOP_SPLIT2); /* prefer jump */ + } else { + duk__append_reop(re_ctx, DUK_REOP_SPLIT1); /* prefer direct */ + } + duk__append_jump_offset(re_ctx, -atom_code_length - 1); /* -1 for opcode */ + } else { + /* + * The remaining matches are emitted as sequence of SPLITs and atom + * copies; the SPLITs skip the remaining copies and match the sequel. + * This sequence needs to be emitted starting from the last copy + * because the SPLITs are variable length due to the variable length + * skip offset. This causes a lot of memory copying now. + * + * Example structure (greedy, match maximum # atoms): + * + * SPLIT1 LSEQ + * (atom) + * SPLIT1 LSEQ ; <- the byte length of this instruction is needed + * (atom) ; to encode the above SPLIT1 correctly + * ... + * LSEQ: + */ + duk_uint32_t offset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx); + while (tmp_qmax > 0) { + duk__insert_slice(re_ctx, offset, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length); + if (re_ctx->curr_token.greedy) { + duk__insert_u32(re_ctx, offset, DUK_REOP_SPLIT1); /* prefer direct */ + } else { + duk__insert_u32(re_ctx, offset, DUK_REOP_SPLIT2); /* prefer jump */ + } + duk__insert_jump_offset(re_ctx, + offset + 1, /* +1 for opcode */ + (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - (offset + 1))); + tmp_qmax--; + } + } + + /* remove the original 'template' atom */ + duk__remove_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length); + } + + /* 'taint' result as complex */ + res_charlen = -1; + break; + } + case DUK_RETOK_ASSERT_START: { + duk__append_reop(re_ctx, DUK_REOP_ASSERT_START); + break; + } + case DUK_RETOK_ASSERT_END: { + duk__append_reop(re_ctx, DUK_REOP_ASSERT_END); + break; + } + case DUK_RETOK_ASSERT_WORD_BOUNDARY: { + duk__append_reop(re_ctx, DUK_REOP_ASSERT_WORD_BOUNDARY); + break; + } + case DUK_RETOK_ASSERT_NOT_WORD_BOUNDARY: { + duk__append_reop(re_ctx, DUK_REOP_ASSERT_NOT_WORD_BOUNDARY); + break; + } + case DUK_RETOK_ASSERT_START_POS_LOOKAHEAD: + case DUK_RETOK_ASSERT_START_NEG_LOOKAHEAD: { + duk_uint32_t offset; + duk_uint32_t opcode = (re_ctx->curr_token.t == DUK_RETOK_ASSERT_START_POS_LOOKAHEAD) ? + DUK_REOP_LOOKPOS : DUK_REOP_LOOKNEG; + + offset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx); + duk__parse_disjunction(re_ctx, 0, &tmp_disj); + duk__append_reop(re_ctx, DUK_REOP_MATCH); + + (void) duk__insert_u32(re_ctx, offset, opcode); + (void) duk__insert_jump_offset(re_ctx, + offset + 1, /* +1 for opcode */ + (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - (offset + 1))); + + /* 'taint' result as complex -- this is conservative, + * as lookaheads do not backtrack. + */ + res_charlen = -1; + break; + } + case DUK_RETOK_ATOM_PERIOD: { + new_atom_char_length = 1; + new_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx); + duk__append_reop(re_ctx, DUK_REOP_PERIOD); + break; + } + case DUK_RETOK_ATOM_CHAR: { + /* Note: successive characters could be joined into string matches + * but this is not trivial (consider e.g. '/xyz+/); see docs for + * more discussion. + * + * No support for \u{H+} yet. While only BMP Unicode escapes are + * supported for RegExps at present, 'ch' may still be a non-BMP + * codepoint if it is decoded straight from source text UTF-8. + * There's no non-BMP support yet so this is handled simply by + * matching the non-BMP character (which is custom behavior). + */ + duk_uint32_t ch; + + new_atom_char_length = 1; + new_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx); + duk__append_reop(re_ctx, DUK_REOP_CHAR); + ch = re_ctx->curr_token.num; + if (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) { + ch = (duk_uint32_t) duk_unicode_re_canonicalize_char(re_ctx->thr, (duk_codepoint_t) ch); + } + duk__append_u32(re_ctx, ch); + break; + } + case DUK_RETOK_ATOM_DIGIT: + case DUK_RETOK_ATOM_NOT_DIGIT: + case DUK_RETOK_ATOM_WHITE: + case DUK_RETOK_ATOM_NOT_WHITE: + case DUK_RETOK_ATOM_WORD_CHAR: + case DUK_RETOK_ATOM_NOT_WORD_CHAR: { + duk_small_uint_t re_op; + duk_small_uint_t idx; + + new_atom_char_length = 1; + new_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx); + + DUK_ASSERT((DUK_RETOK_ATOM_DIGIT & 0x01) != 0); + DUK_ASSERT((DUK_RETOK_ATOM_WHITE & 0x01) != 0); + DUK_ASSERT((DUK_RETOK_ATOM_WORD_CHAR & 0x01) != 0); + DUK_ASSERT((DUK_RETOK_ATOM_NOT_DIGIT & 0x01) == 0); + DUK_ASSERT((DUK_RETOK_ATOM_NOT_WHITE & 0x01) == 0); + DUK_ASSERT((DUK_RETOK_ATOM_NOT_WORD_CHAR & 0x01) == 0); + re_op = (re_ctx->curr_token.t & 0x01) ? DUK_REOP_RANGES : DUK_REOP_INVRANGES; + + DUK_ASSERT(DUK_RETOK_ATOM_WHITE == DUK_RETOK_ATOM_DIGIT + 2); + DUK_ASSERT(DUK_RETOK_ATOM_WORD_CHAR == DUK_RETOK_ATOM_DIGIT + 4); + idx = (duk_small_uint_t) ((re_ctx->curr_token.t - DUK_RETOK_ATOM_DIGIT) >> 1U); + DUK_ASSERT(idx <= 2U); /* Assume continuous token numbers; also checks negative underflow. */ + + duk__append_range_atom_matcher(re_ctx, re_op, duk__re_range_lookup1[idx], duk__re_range_lookup2[idx]); + break; + } + case DUK_RETOK_ATOM_BACKREFERENCE: { + duk_uint32_t backref = (duk_uint32_t) re_ctx->curr_token.num; + if (backref > re_ctx->highest_backref) { + re_ctx->highest_backref = backref; + } + new_atom_char_length = -1; /* mark as complex */ + new_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx); + duk__append_reop(re_ctx, DUK_REOP_BACKREFERENCE); + duk__append_u32(re_ctx, backref); + break; + } + case DUK_RETOK_ATOM_START_CAPTURE_GROUP: { + duk_uint32_t cap; + + new_atom_char_length = -1; /* mark as complex (capture handling) */ + new_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx); + cap = ++re_ctx->captures; + duk__append_reop(re_ctx, DUK_REOP_SAVE); + duk__append_u32(re_ctx, cap * 2); + duk__parse_disjunction(re_ctx, 0, &tmp_disj); /* retval (sub-atom char length) unused, tainted as complex above */ + duk__append_reop(re_ctx, DUK_REOP_SAVE); + duk__append_u32(re_ctx, cap * 2 + 1); + break; + } + case DUK_RETOK_ATOM_START_NONCAPTURE_GROUP: { + new_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx); + duk__parse_disjunction(re_ctx, 0, &tmp_disj); + new_atom_char_length = tmp_disj.charlen; + break; + } + case DUK_RETOK_ATOM_START_CHARCLASS: + case DUK_RETOK_ATOM_START_CHARCLASS_INVERTED: { + /* + * Range parsing is done with a special lexer function which calls + * us for every range parsed. This is different from how rest of + * the parsing works, but avoids a heavy, arbitrary size intermediate + * value type to hold the ranges. + * + * Another complication is the handling of character ranges when + * case insensitive matching is used (see docs for discussion). + * The range handler callback given to the lexer takes care of this + * as well. + * + * Note that duplicate ranges are not eliminated when parsing character + * classes, so that canonicalization of + * + * [0-9a-fA-Fx-{] + * + * creates the result (note the duplicate ranges): + * + * [0-9A-FA-FX-Z{-{] + * + * where [x-{] is split as a result of canonicalization. The duplicate + * ranges are not a semantics issue: they work correctly. + */ + + duk_uint32_t offset; + + DUK_DD(DUK_DDPRINT("character class")); + + /* insert ranges instruction, range count patched in later */ + new_atom_char_length = 1; + new_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx); + duk__append_reop(re_ctx, + (re_ctx->curr_token.t == DUK_RETOK_ATOM_START_CHARCLASS) ? + DUK_REOP_RANGES : DUK_REOP_INVRANGES); + offset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx); /* patch in range count later */ + + /* parse ranges until character class ends */ + re_ctx->nranges = 0; /* note: ctx-wide temporary */ + duk_lexer_parse_re_ranges(&re_ctx->lex, duk__regexp_generate_ranges, (void *) re_ctx); + + /* insert range count */ + duk__insert_u32(re_ctx, offset, re_ctx->nranges); + break; + } + case DUK_RETOK_ATOM_END_GROUP: { + if (expect_eof) { + DUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_CLOSING_PAREN); + DUK_WO_NORETURN(return;); + } + goto done; + } + case DUK_RETOK_EOF: { + if (!expect_eof) { + DUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_END_OF_PATTERN); + DUK_WO_NORETURN(return;); + } + goto done; + } + default: { + DUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_REGEXP_TOKEN); + DUK_WO_NORETURN(return;); + } + } + + /* a complex (new) atom taints the result */ + if (new_atom_start_offset >= 0) { + if (new_atom_char_length < 0) { + res_charlen = -1; + } else if (res_charlen >= 0) { + /* only advance if not tainted */ + res_charlen += new_atom_char_length; + } + } + + /* record previous atom info in case next token is a quantifier */ + atom_start_offset = new_atom_start_offset; + atom_char_length = new_atom_char_length; + atom_start_captures = new_atom_start_captures; + } + + done: + + /* finish up pending jump and split for last alternative */ + if (unpatched_disjunction_jump >= 0) { + duk_uint32_t offset; + + DUK_ASSERT(unpatched_disjunction_split >= 0); + offset = (duk_uint32_t) unpatched_disjunction_jump; + offset += duk__insert_jump_offset(re_ctx, + offset, + (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - offset)); + /* offset is now target of the pending split (right after jump) */ + duk__insert_jump_offset(re_ctx, + (duk_uint32_t) unpatched_disjunction_split, + (duk_int32_t) offset - unpatched_disjunction_split); + } + +#if 0 + out_atom_info->end_captures = re_ctx->captures; +#endif + out_atom_info->charlen = res_charlen; + DUK_DDD(DUK_DDDPRINT("parse disjunction finished: charlen=%ld", + (long) out_atom_info->charlen)); + + re_ctx->recursion_depth--; +} + +/* + * Flags parsing (see E5 Section 15.10.4.1). + */ + +DUK_LOCAL duk_uint32_t duk__parse_regexp_flags(duk_hthread *thr, duk_hstring *h) { + const duk_uint8_t *p; + const duk_uint8_t *p_end; + duk_uint32_t flags = 0; + + p = DUK_HSTRING_GET_DATA(h); + p_end = p + DUK_HSTRING_GET_BYTELEN(h); + + /* Note: can be safely scanned as bytes (undecoded) */ + + while (p < p_end) { + duk_uint8_t c = *p++; + switch (c) { + case (duk_uint8_t) 'g': { + if (flags & DUK_RE_FLAG_GLOBAL) { + goto flags_error; + } + flags |= DUK_RE_FLAG_GLOBAL; + break; + } + case (duk_uint8_t) 'i': { + if (flags & DUK_RE_FLAG_IGNORE_CASE) { + goto flags_error; + } + flags |= DUK_RE_FLAG_IGNORE_CASE; + break; + } + case (duk_uint8_t) 'm': { + if (flags & DUK_RE_FLAG_MULTILINE) { + goto flags_error; + } + flags |= DUK_RE_FLAG_MULTILINE; + break; + } + default: { + goto flags_error; + } + } + } + + return flags; + + flags_error: + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_REGEXP_FLAGS); + DUK_WO_NORETURN(return 0U;); +} + +/* + * Create escaped RegExp source (E5 Section 15.10.3). + * + * The current approach is to special case the empty RegExp + * ('' -> '(?:)') and otherwise replace unescaped '/' characters + * with '\/' regardless of where they occur in the regexp. + * + * Note that normalization does not seem to be necessary for + * RegExp literals (e.g. '/foo/') because to be acceptable as + * a RegExp literal, the text between forward slashes must + * already match the escaping requirements (e.g. must not contain + * unescaped forward slashes or be empty). Escaping IS needed + * for expressions like 'new Regexp("...", "")' however. + * Currently, we re-escape in either case. + * + * Also note that we process the source here in UTF-8 encoded + * form. This is correct, because any non-ASCII characters are + * passed through without change. + */ + +DUK_LOCAL void duk__create_escaped_source(duk_hthread *thr, int idx_pattern) { + duk_hstring *h; + const duk_uint8_t *p; + duk_bufwriter_ctx bw_alloc; + duk_bufwriter_ctx *bw; + duk_uint8_t *q; + duk_size_t i, n; + duk_uint_fast8_t c_prev, c; + + h = duk_known_hstring(thr, idx_pattern); + p = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h); + n = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h); + + if (n == 0) { + duk_push_literal(thr, "(?:)"); + return; + } + + bw = &bw_alloc; + DUK_BW_INIT_PUSHBUF(thr, bw, n); + q = DUK_BW_GET_PTR(thr, bw); + + c_prev = (duk_uint_fast8_t) 0; + + for (i = 0; i < n; i++) { + c = p[i]; + + q = DUK_BW_ENSURE_RAW(thr, bw, 2, q); + + if (c == (duk_uint_fast8_t) '/' && c_prev != (duk_uint_fast8_t) '\\') { + /* Unescaped '/' ANYWHERE in the regexp (in disjunction, + * inside a character class, ...) => same escape works. + */ + *q++ = DUK_ASC_BACKSLASH; + } + *q++ = (duk_uint8_t) c; + + c_prev = c; + } + + DUK_BW_SETPTR_AND_COMPACT(thr, bw, q); + (void) duk_buffer_to_string(thr, -1); /* Safe if input is safe. */ + + /* [ ... escaped_source ] */ +} + +/* + * Exposed regexp compilation primitive. + * + * Sets up a regexp compilation context, and calls duk__parse_disjunction() to do the + * actual parsing. Handles generation of the compiled regexp header and the + * "boilerplate" capture of the matching substring (save 0 and 1). Also does some + * global level regexp checks after recursive compilation has finished. + * + * An escaped version of the regexp source, suitable for use as a RegExp instance + * 'source' property (see E5 Section 15.10.3), is also left on the stack. + * + * Input stack: [ pattern flags ] + * Output stack: [ bytecode escaped_source ] (both as strings) + */ + +DUK_INTERNAL void duk_regexp_compile(duk_hthread *thr) { + duk_re_compiler_ctx re_ctx; + duk_lexer_point lex_point; + duk_hstring *h_pattern; + duk_hstring *h_flags; + duk__re_disjunction_info ign_disj; + + DUK_ASSERT(thr != NULL); + + /* + * Args validation + */ + + /* TypeError if fails */ + h_pattern = duk_require_hstring_notsymbol(thr, -2); + h_flags = duk_require_hstring_notsymbol(thr, -1); + + /* + * Create normalized 'source' property (E5 Section 15.10.3). + */ + + /* [ ... pattern flags ] */ + + duk__create_escaped_source(thr, -2); + + /* [ ... pattern flags escaped_source ] */ + + /* + * Init compilation context + */ + + /* [ ... pattern flags escaped_source buffer ] */ + + duk_memzero(&re_ctx, sizeof(re_ctx)); + DUK_LEXER_INITCTX(&re_ctx.lex); /* duplicate zeroing, expect for (possible) NULL inits */ + re_ctx.thr = thr; + re_ctx.lex.thr = thr; + re_ctx.lex.input = DUK_HSTRING_GET_DATA(h_pattern); + re_ctx.lex.input_length = DUK_HSTRING_GET_BYTELEN(h_pattern); + re_ctx.lex.token_limit = DUK_RE_COMPILE_TOKEN_LIMIT; + re_ctx.recursion_limit = DUK_USE_REGEXP_COMPILER_RECLIMIT; + re_ctx.re_flags = duk__parse_regexp_flags(thr, h_flags); + + DUK_BW_INIT_PUSHBUF(thr, &re_ctx.bw, DUK__RE_INITIAL_BUFSIZE); + + DUK_DD(DUK_DDPRINT("regexp compiler ctx initialized, flags=0x%08lx, recursion_limit=%ld", + (unsigned long) re_ctx.re_flags, (long) re_ctx.recursion_limit)); + + /* + * Init lexer + */ + + lex_point.offset = 0; /* expensive init, just want to fill window */ + lex_point.line = 1; + DUK_LEXER_SETPOINT(&re_ctx.lex, &lex_point); + + /* + * Compilation + */ + + DUK_DD(DUK_DDPRINT("starting regexp compilation")); + + duk__append_reop(&re_ctx, DUK_REOP_SAVE); + duk__append_7bit(&re_ctx, 0); + duk__parse_disjunction(&re_ctx, 1 /*expect_eof*/, &ign_disj); + duk__append_reop(&re_ctx, DUK_REOP_SAVE); + duk__append_7bit(&re_ctx, 1); + duk__append_reop(&re_ctx, DUK_REOP_MATCH); + + /* + * Check for invalid backreferences; note that it is NOT an error + * to back-reference a capture group which has not yet been introduced + * in the pattern (as in /\1(foo)/); in fact, the backreference will + * always match! It IS an error to back-reference a capture group + * which will never be introduced in the pattern. Thus, we can check + * for such references only after parsing is complete. + */ + + if (re_ctx.highest_backref > re_ctx.captures) { + DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_BACKREFS); + DUK_WO_NORETURN(return;); + } + + /* + * Emit compiled regexp header: flags, ncaptures + * (insertion order inverted on purpose) + */ + + duk__insert_u32(&re_ctx, 0, (re_ctx.captures + 1) * 2); + duk__insert_u32(&re_ctx, 0, re_ctx.re_flags); + + /* [ ... pattern flags escaped_source buffer ] */ + + DUK_BW_COMPACT(thr, &re_ctx.bw); + (void) duk_buffer_to_string(thr, -1); /* Safe because flags is at most 7 bit. */ + + /* [ ... pattern flags escaped_source bytecode ] */ + + /* + * Finalize stack + */ + + duk_remove(thr, -4); /* -> [ ... flags escaped_source bytecode ] */ + duk_remove(thr, -3); /* -> [ ... escaped_source bytecode ] */ + + DUK_DD(DUK_DDPRINT("regexp compilation successful, bytecode: %!T, escaped source: %!T", + (duk_tval *) duk_get_tval(thr, -1), (duk_tval *) duk_get_tval(thr, -2))); +} + +/* + * Create a RegExp instance (E5 Section 15.10.7). + * + * Note: the output stack left by duk_regexp_compile() is directly compatible + * with the input here. + * + * Input stack: [ escaped_source bytecode ] (both as strings) + * Output stack: [ RegExp ] + */ + +DUK_INTERNAL void duk_regexp_create_instance(duk_hthread *thr) { + duk_hobject *h; + + /* [ ... escaped_source bytecode ] */ + + duk_push_object(thr); + h = duk_known_hobject(thr, -1); + duk_insert(thr, -3); + + /* [ ... regexp_object escaped_source bytecode ] */ + + DUK_HOBJECT_SET_CLASS_NUMBER(h, DUK_HOBJECT_CLASS_REGEXP); + DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, thr->builtins[DUK_BIDX_REGEXP_PROTOTYPE]); + + duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_BYTECODE, DUK_PROPDESC_FLAGS_NONE); + + /* [ ... regexp_object escaped_source ] */ + + /* In ES2015 .source, and the .global, .multiline, etc flags are + * inherited getters. Store the escaped source as an internal + * property for the getter. + */ + + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_SOURCE, DUK_PROPDESC_FLAGS_NONE); + + /* [ ... regexp_object ] */ + + duk_push_int(thr, 0); + duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LAST_INDEX, DUK_PROPDESC_FLAGS_W); + + /* [ ... regexp_object ] */ +} + +#else /* DUK_USE_REGEXP_SUPPORT */ + +/* regexp support disabled */ + +#endif /* DUK_USE_REGEXP_SUPPORT */ diff --git a/third_party/duktape/duk_regexp_executor.c b/third_party/duktape/duk_regexp_executor.c new file mode 100644 index 00000000..a348b63c --- /dev/null +++ b/third_party/duktape/duk_regexp_executor.c @@ -0,0 +1,1027 @@ +/* + * Regexp executor. + * + * Safety: the ECMAScript executor should prevent user from reading and + * replacing regexp bytecode. Even so, the executor must validate all + * memory accesses etc. When an invalid access is detected (e.g. a 'save' + * opcode to invalid, unallocated index) it should fail with an internal + * error but not cause a segmentation fault. + * + * Notes: + * + * - Backtrack counts are limited to unsigned 32 bits but should + * technically be duk_size_t for strings longer than 4G chars. + * This also requires a regexp bytecode change. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_REGEXP_SUPPORT) + +/* + * Helpers for UTF-8 handling + * + * For bytecode readers the duk_uint32_t and duk_int32_t types are correct + * because they're used for more than just codepoints. + */ + +DUK_LOCAL duk_uint32_t duk__bc_get_u32(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **pc) { + return (duk_uint32_t) duk_unicode_decode_xutf8_checked(re_ctx->thr, pc, re_ctx->bytecode, re_ctx->bytecode_end); +} + +DUK_LOCAL duk_int32_t duk__bc_get_i32(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **pc) { + duk_uint32_t t; + + /* signed integer encoding needed to work with UTF-8 */ + t = (duk_uint32_t) duk_unicode_decode_xutf8_checked(re_ctx->thr, pc, re_ctx->bytecode, re_ctx->bytecode_end); + if (t & 1) { + return -((duk_int32_t) (t >> 1)); + } else { + return (duk_int32_t) (t >> 1); + } +} + +DUK_LOCAL const duk_uint8_t *duk__utf8_backtrack(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_uint_fast32_t count) { + const duk_uint8_t *p; + + /* Note: allow backtracking from p == ptr_end */ + p = *ptr; + if (p < ptr_start || p > ptr_end) { + goto fail; + } + + while (count > 0) { + for (;;) { + p--; + if (p < ptr_start) { + goto fail; + } + if ((*p & 0xc0) != 0x80) { + /* utf-8 continuation bytes have the form 10xx xxxx */ + break; + } + } + count--; + } + *ptr = p; + return p; + + fail: + DUK_ERROR_INTERNAL(thr); + DUK_WO_NORETURN(return NULL;); +} + +DUK_LOCAL const duk_uint8_t *duk__utf8_advance(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_uint_fast32_t count) { + const duk_uint8_t *p; + + p = *ptr; + if (p < ptr_start || p >= ptr_end) { + goto fail; + } + + while (count > 0) { + for (;;) { + p++; + + /* Note: if encoding ends by hitting end of input, we don't check that + * the encoding is valid, we just assume it is. + */ + if (p >= ptr_end || ((*p & 0xc0) != 0x80)) { + /* utf-8 continuation bytes have the form 10xx xxxx */ + break; + } + } + count--; + } + + *ptr = p; + return p; + + fail: + DUK_ERROR_INTERNAL(thr); + DUK_WO_NORETURN(return NULL;); +} + +/* + * Helpers for dealing with the input string + */ + +/* Get a (possibly canonicalized) input character from current sp. The input + * itself is never modified, and captures always record non-canonicalized + * characters even in case-insensitive matching. Return <0 if out of input. + */ +DUK_LOCAL duk_codepoint_t duk__inp_get_cp(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **sp) { + duk_codepoint_t res; + + if (*sp >= re_ctx->input_end) { + return -1; + } + res = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(re_ctx->thr, sp, re_ctx->input, re_ctx->input_end); + if (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) { + res = duk_unicode_re_canonicalize_char(re_ctx->thr, res); + } + return res; +} + +DUK_LOCAL const duk_uint8_t *duk__inp_backtrack(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **sp, duk_uint_fast32_t count) { + return duk__utf8_backtrack(re_ctx->thr, sp, re_ctx->input, re_ctx->input_end, count); +} + +/* Backtrack utf-8 input and return a (possibly canonicalized) input character. */ +DUK_LOCAL duk_codepoint_t duk__inp_get_prev_cp(duk_re_matcher_ctx *re_ctx, const duk_uint8_t *sp) { + /* note: caller 'sp' is intentionally not updated here */ + (void) duk__inp_backtrack(re_ctx, &sp, (duk_uint_fast32_t) 1); + return duk__inp_get_cp(re_ctx, &sp); +} + +/* + * Regexp recursive matching function. + * + * Returns 'sp' on successful match (points to character after last matched one), + * NULL otherwise. + * + * The C recursion depth limit check is only performed in this function, this + * suffices because the function is present in all true recursion required by + * regexp execution. + */ + +DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const duk_uint8_t *pc, const duk_uint8_t *sp) { + duk_native_stack_check(re_ctx->thr); + if (re_ctx->recursion_depth >= re_ctx->recursion_limit) { + DUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_EXECUTOR_RECURSION_LIMIT); + DUK_WO_NORETURN(return NULL;); + } + re_ctx->recursion_depth++; + + for (;;) { + duk_small_int_t op; + + if (re_ctx->steps_count >= re_ctx->steps_limit) { + DUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_EXECUTOR_STEP_LIMIT); + DUK_WO_NORETURN(return NULL;); + } + re_ctx->steps_count++; + + /* Opcodes are at most 7 bits now so they encode to one byte. If this + * were not the case or 'pc' is invalid here (due to a bug etc) we'll + * still fail safely through the switch default case. + */ + DUK_ASSERT(pc[0] <= 0x7fU); +#if 0 + op = (duk_small_int_t) duk__bc_get_u32(re_ctx, &pc); +#endif + op = *pc++; + + DUK_DDD(DUK_DDDPRINT("match: rec=%ld, steps=%ld, pc (after op)=%ld, sp=%ld, op=%ld", + (long) re_ctx->recursion_depth, + (long) re_ctx->steps_count, + (long) (pc - re_ctx->bytecode), + (long) (sp - re_ctx->input), + (long) op)); + + switch (op) { + case DUK_REOP_MATCH: { + goto match; + } + case DUK_REOP_CHAR: { + /* + * Byte-based matching would be possible for case-sensitive + * matching but not for case-insensitive matching. So, we + * match by decoding the input and bytecode character normally. + * + * Bytecode characters are assumed to be already canonicalized. + * Input characters are canonicalized automatically by + * duk__inp_get_cp() if necessary. + * + * There is no opcode for matching multiple characters. The + * regexp compiler has trouble joining strings efficiently + * during compilation. See doc/regexp.rst for more discussion. + */ + duk_codepoint_t c1, c2; + + c1 = (duk_codepoint_t) duk__bc_get_u32(re_ctx, &pc); + DUK_ASSERT(!(re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) || + c1 == duk_unicode_re_canonicalize_char(re_ctx->thr, c1)); /* canonicalized by compiler */ + c2 = duk__inp_get_cp(re_ctx, &sp); + /* No need to check for c2 < 0 (end of input): because c1 >= 0, it + * will fail the match below automatically and cause goto fail. + */ +#if 0 + if (c2 < 0) { + goto fail; + } +#endif + DUK_ASSERT(c1 >= 0); + + DUK_DDD(DUK_DDDPRINT("char match, c1=%ld, c2=%ld", (long) c1, (long) c2)); + if (c1 != c2) { + goto fail; + } + break; + } + case DUK_REOP_PERIOD: { + duk_codepoint_t c; + + c = duk__inp_get_cp(re_ctx, &sp); + if (c < 0 || duk_unicode_is_line_terminator(c)) { + /* E5 Sections 15.10.2.8, 7.3 */ + goto fail; + } + break; + } + case DUK_REOP_RANGES: + case DUK_REOP_INVRANGES: { + duk_uint32_t n; + duk_codepoint_t c; + duk_small_int_t match; + + n = duk__bc_get_u32(re_ctx, &pc); + c = duk__inp_get_cp(re_ctx, &sp); + if (c < 0) { + goto fail; + } + + match = 0; + while (n) { + duk_codepoint_t r1, r2; + r1 = (duk_codepoint_t) duk__bc_get_u32(re_ctx, &pc); + r2 = (duk_codepoint_t) duk__bc_get_u32(re_ctx, &pc); + DUK_DDD(DUK_DDDPRINT("matching ranges/invranges, n=%ld, r1=%ld, r2=%ld, c=%ld", + (long) n, (long) r1, (long) r2, (long) c)); + if (c >= r1 && c <= r2) { + /* Note: don't bail out early, we must read all the ranges from + * bytecode. Another option is to skip them efficiently after + * breaking out of here. Prefer smallest code. + */ + match = 1; + } + n--; + } + + if (op == DUK_REOP_RANGES) { + if (!match) { + goto fail; + } + } else { + DUK_ASSERT(op == DUK_REOP_INVRANGES); + if (match) { + goto fail; + } + } + break; + } + case DUK_REOP_ASSERT_START: { + duk_codepoint_t c; + + if (sp <= re_ctx->input) { + break; + } + if (!(re_ctx->re_flags & DUK_RE_FLAG_MULTILINE)) { + goto fail; + } + c = duk__inp_get_prev_cp(re_ctx, sp); + if (duk_unicode_is_line_terminator(c)) { + /* E5 Sections 15.10.2.8, 7.3 */ + break; + } + goto fail; + } + case DUK_REOP_ASSERT_END: { + duk_codepoint_t c; + const duk_uint8_t *tmp_sp; + + tmp_sp = sp; + c = duk__inp_get_cp(re_ctx, &tmp_sp); + if (c < 0) { + break; + } + if (!(re_ctx->re_flags & DUK_RE_FLAG_MULTILINE)) { + goto fail; + } + if (duk_unicode_is_line_terminator(c)) { + /* E5 Sections 15.10.2.8, 7.3 */ + break; + } + goto fail; + } + case DUK_REOP_ASSERT_WORD_BOUNDARY: + case DUK_REOP_ASSERT_NOT_WORD_BOUNDARY: { + /* + * E5 Section 15.10.2.6. The previous and current character + * should -not- be canonicalized as they are now. However, + * canonicalization does not affect the result of IsWordChar() + * (which depends on Unicode characters never canonicalizing + * into ASCII characters) so this does not matter. + */ + duk_small_int_t w1, w2; + + if (sp <= re_ctx->input) { + w1 = 0; /* not a wordchar */ + } else { + duk_codepoint_t c; + c = duk__inp_get_prev_cp(re_ctx, sp); + w1 = duk_unicode_re_is_wordchar(c); + } + if (sp >= re_ctx->input_end) { + w2 = 0; /* not a wordchar */ + } else { + const duk_uint8_t *tmp_sp = sp; /* dummy so sp won't get updated */ + duk_codepoint_t c; + c = duk__inp_get_cp(re_ctx, &tmp_sp); + w2 = duk_unicode_re_is_wordchar(c); + } + + if (op == DUK_REOP_ASSERT_WORD_BOUNDARY) { + if (w1 == w2) { + goto fail; + } + } else { + DUK_ASSERT(op == DUK_REOP_ASSERT_NOT_WORD_BOUNDARY); + if (w1 != w2) { + goto fail; + } + } + break; + } + case DUK_REOP_JUMP: { + duk_int32_t skip; + + skip = duk__bc_get_i32(re_ctx, &pc); + pc += skip; + break; + } + case DUK_REOP_SPLIT1: { + /* split1: prefer direct execution (no jump) */ + const duk_uint8_t *sub_sp; + duk_int32_t skip; + + skip = duk__bc_get_i32(re_ctx, &pc); + sub_sp = duk__match_regexp(re_ctx, pc, sp); + if (sub_sp) { + sp = sub_sp; + goto match; + } + pc += skip; + break; + } + case DUK_REOP_SPLIT2: { + /* split2: prefer jump execution (not direct) */ + const duk_uint8_t *sub_sp; + duk_int32_t skip; + + skip = duk__bc_get_i32(re_ctx, &pc); + sub_sp = duk__match_regexp(re_ctx, pc + skip, sp); + if (sub_sp) { + sp = sub_sp; + goto match; + } + break; + } + case DUK_REOP_SQMINIMAL: { + duk_uint32_t q, qmin, qmax; + duk_int32_t skip; + const duk_uint8_t *sub_sp; + + qmin = duk__bc_get_u32(re_ctx, &pc); + qmax = duk__bc_get_u32(re_ctx, &pc); + skip = duk__bc_get_i32(re_ctx, &pc); + DUK_DDD(DUK_DDDPRINT("minimal quantifier, qmin=%lu, qmax=%lu, skip=%ld", + (unsigned long) qmin, (unsigned long) qmax, (long) skip)); + + q = 0; + while (q <= qmax) { + if (q >= qmin) { + sub_sp = duk__match_regexp(re_ctx, pc + skip, sp); + if (sub_sp) { + sp = sub_sp; + goto match; + } + } + sub_sp = duk__match_regexp(re_ctx, pc, sp); + if (!sub_sp) { + break; + } + sp = sub_sp; + q++; + } + goto fail; + } + case DUK_REOP_SQGREEDY: { + duk_uint32_t q, qmin, qmax, atomlen; + duk_int32_t skip; + const duk_uint8_t *sub_sp; + + qmin = duk__bc_get_u32(re_ctx, &pc); + qmax = duk__bc_get_u32(re_ctx, &pc); + atomlen = duk__bc_get_u32(re_ctx, &pc); + skip = duk__bc_get_i32(re_ctx, &pc); + DUK_DDD(DUK_DDDPRINT("greedy quantifier, qmin=%lu, qmax=%lu, atomlen=%lu, skip=%ld", + (unsigned long) qmin, (unsigned long) qmax, (unsigned long) atomlen, (long) skip)); + + q = 0; + while (q < qmax) { + sub_sp = duk__match_regexp(re_ctx, pc, sp); + if (!sub_sp) { + break; + } + sp = sub_sp; + q++; + } + while (q >= qmin) { + sub_sp = duk__match_regexp(re_ctx, pc + skip, sp); + if (sub_sp) { + sp = sub_sp; + goto match; + } + if (q == qmin) { + break; + } + + /* Note: if atom were to contain e.g. captures, we would need to + * re-match the atom to get correct captures. Simply quantifiers + * do not allow captures in their atom now, so this is not an issue. + */ + + DUK_DDD(DUK_DDDPRINT("greedy quantifier, backtrack %ld characters (atomlen)", + (long) atomlen)); + sp = duk__inp_backtrack(re_ctx, &sp, (duk_uint_fast32_t) atomlen); + q--; + } + goto fail; + } + case DUK_REOP_SAVE: { + duk_uint32_t idx; + const duk_uint8_t *old; + const duk_uint8_t *sub_sp; + + idx = duk__bc_get_u32(re_ctx, &pc); + if (idx >= re_ctx->nsaved) { + /* idx is unsigned, < 0 check is not necessary */ + DUK_D(DUK_DPRINT("internal error, regexp save index insane: idx=%ld", (long) idx)); + goto internal_error; + } + old = re_ctx->saved[idx]; + re_ctx->saved[idx] = sp; + sub_sp = duk__match_regexp(re_ctx, pc, sp); + if (sub_sp) { + sp = sub_sp; + goto match; + } + re_ctx->saved[idx] = old; + goto fail; + } + case DUK_REOP_WIPERANGE: { + /* Wipe capture range and save old values for backtracking. + * + * XXX: this typically happens with a relatively small idx_count. + * It might be useful to handle cases where the count is small + * (say <= 8) by saving the values in stack instead. This would + * reduce memory churn and improve performance, at the cost of a + * slightly higher code footprint. + */ + duk_uint32_t idx_start, idx_count; +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + duk_uint32_t idx_end, idx; +#endif + duk_uint8_t **range_save; + const duk_uint8_t *sub_sp; + + idx_start = duk__bc_get_u32(re_ctx, &pc); + idx_count = duk__bc_get_u32(re_ctx, &pc); + DUK_DDD(DUK_DDDPRINT("wipe saved range: start=%ld, count=%ld -> [%ld,%ld] (captures [%ld,%ld])", + (long) idx_start, (long) idx_count, + (long) idx_start, (long) (idx_start + idx_count - 1), + (long) (idx_start / 2), (long) ((idx_start + idx_count - 1) / 2))); + if (idx_start + idx_count > re_ctx->nsaved || idx_count == 0) { + /* idx is unsigned, < 0 check is not necessary */ + DUK_D(DUK_DPRINT("internal error, regexp wipe indices insane: idx_start=%ld, idx_count=%ld", + (long) idx_start, (long) idx_count)); + goto internal_error; + } + DUK_ASSERT(idx_count > 0); + + duk_require_stack(re_ctx->thr, 1); + range_save = (duk_uint8_t **) duk_push_fixed_buffer_nozero(re_ctx->thr, + sizeof(duk_uint8_t *) * idx_count); + DUK_ASSERT(range_save != NULL); + duk_memcpy(range_save, re_ctx->saved + idx_start, sizeof(duk_uint8_t *) * idx_count); +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + idx_end = idx_start + idx_count; + for (idx = idx_start; idx < idx_end; idx++) { + re_ctx->saved[idx] = NULL; + } +#else + duk_memzero((void *) (re_ctx->saved + idx_start), sizeof(duk_uint8_t *) * idx_count); +#endif + + sub_sp = duk__match_regexp(re_ctx, pc, sp); + if (sub_sp) { + /* match: keep wiped/resaved values */ + DUK_DDD(DUK_DDDPRINT("match: keep wiped/resaved values [%ld,%ld] (captures [%ld,%ld])", + (long) idx_start, (long) (idx_start + idx_count - 1), + (long) (idx_start / 2), (long) ((idx_start + idx_count - 1) / 2))); + duk_pop_unsafe(re_ctx->thr); + sp = sub_sp; + goto match; + } + + /* fail: restore saves */ + DUK_DDD(DUK_DDDPRINT("fail: restore wiped/resaved values [%ld,%ld] (captures [%ld,%ld])", + (long) idx_start, (long) (idx_start + idx_count - 1), + (long) (idx_start / 2), (long) ((idx_start + idx_count - 1) / 2))); + duk_memcpy((void *) (re_ctx->saved + idx_start), + (const void *) range_save, + sizeof(duk_uint8_t *) * idx_count); + duk_pop_unsafe(re_ctx->thr); + goto fail; + } + case DUK_REOP_LOOKPOS: + case DUK_REOP_LOOKNEG: { + /* + * Needs a save of multiple saved[] entries depending on what range + * may be overwritten. Because the regexp parser does no such analysis, + * we currently save the entire saved array here. Lookaheads are thus + * a bit expensive. Note that the saved array is not needed for just + * the lookahead sub-match, but for the matching of the entire sequel. + * + * The temporary save buffer is pushed on to the valstack to handle + * errors correctly. Each lookahead causes a C recursion and pushes + * more stuff on the value stack. If the C recursion limit is less + * than the value stack slack, there is no need to check the stack. + * We do so regardless, just in case. + */ + + duk_int32_t skip; + duk_uint8_t **full_save; + const duk_uint8_t *sub_sp; + + DUK_ASSERT(re_ctx->nsaved > 0); + + duk_require_stack(re_ctx->thr, 1); + full_save = (duk_uint8_t **) duk_push_fixed_buffer_nozero(re_ctx->thr, + sizeof(duk_uint8_t *) * re_ctx->nsaved); + DUK_ASSERT(full_save != NULL); + duk_memcpy(full_save, re_ctx->saved, sizeof(duk_uint8_t *) * re_ctx->nsaved); + + skip = duk__bc_get_i32(re_ctx, &pc); + sub_sp = duk__match_regexp(re_ctx, pc, sp); + if (op == DUK_REOP_LOOKPOS) { + if (!sub_sp) { + goto lookahead_fail; + } + } else { + if (sub_sp) { + goto lookahead_fail; + } + } + sub_sp = duk__match_regexp(re_ctx, pc + skip, sp); + if (sub_sp) { + /* match: keep saves */ + duk_pop_unsafe(re_ctx->thr); + sp = sub_sp; + goto match; + } + + /* fall through */ + + lookahead_fail: + /* fail: restore saves */ + duk_memcpy((void *) re_ctx->saved, + (const void *) full_save, + sizeof(duk_uint8_t *) * re_ctx->nsaved); + duk_pop_unsafe(re_ctx->thr); + goto fail; + } + case DUK_REOP_BACKREFERENCE: { + /* + * Byte matching for back-references would be OK in case- + * sensitive matching. In case-insensitive matching we need + * to canonicalize characters, so back-reference matching needs + * to be done with codepoints instead. So, we just decode + * everything normally here, too. + * + * Note: back-reference index which is 0 or higher than + * NCapturingParens (= number of capturing parens in the + * -entire- regexp) is a compile time error. However, a + * backreference referring to a valid capture which has + * not matched anything always succeeds! See E5 Section + * 15.10.2.9, step 5, sub-step 3. + */ + duk_uint32_t idx; + const duk_uint8_t *p; + + idx = duk__bc_get_u32(re_ctx, &pc); + idx = idx << 1; /* backref n -> saved indices [n*2, n*2+1] */ + if (idx < 2 || idx + 1 >= re_ctx->nsaved) { + /* regexp compiler should catch these */ + DUK_D(DUK_DPRINT("internal error, backreference index insane")); + goto internal_error; + } + if (!re_ctx->saved[idx] || !re_ctx->saved[idx+1]) { + /* capture is 'undefined', always matches! */ + DUK_DDD(DUK_DDDPRINT("backreference: saved[%ld,%ld] not complete, always match", + (long) idx, (long) (idx + 1))); + break; + } + DUK_DDD(DUK_DDDPRINT("backreference: match saved[%ld,%ld]", (long) idx, (long) (idx + 1))); + + p = re_ctx->saved[idx]; + while (p < re_ctx->saved[idx+1]) { + duk_codepoint_t c1, c2; + + /* Note: not necessary to check p against re_ctx->input_end: + * the memory access is checked by duk__inp_get_cp(), while + * valid compiled regexps cannot write a saved[] entry + * which points to outside the string. + */ + c1 = duk__inp_get_cp(re_ctx, &p); + DUK_ASSERT(c1 >= 0); + c2 = duk__inp_get_cp(re_ctx, &sp); + /* No need for an explicit c2 < 0 check: because c1 >= 0, + * the comparison will always fail if c2 < 0. + */ +#if 0 + if (c2 < 0) { + goto fail; + } +#endif + if (c1 != c2) { + goto fail; + } + } + break; + } + default: { + DUK_D(DUK_DPRINT("internal error, regexp opcode error: %ld", (long) op)); + goto internal_error; + } + } + } + + match: + re_ctx->recursion_depth--; + return sp; + + fail: + re_ctx->recursion_depth--; + return NULL; + + internal_error: + DUK_ERROR_INTERNAL(re_ctx->thr); + DUK_WO_NORETURN(return NULL;); +} + +/* + * Exposed matcher function which provides the semantics of RegExp.prototype.exec(). + * + * RegExp.prototype.test() has the same semantics as exec() but does not return the + * result object (which contains the matching string and capture groups). Currently + * there is no separate test() helper, so a temporary result object is created and + * discarded if test() is needed. This is intentional, to save code space. + * + * Input stack: [ ... re_obj input ] + * Output stack: [ ... result ] + */ + +DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_global) { + duk_re_matcher_ctx re_ctx; + duk_hobject *h_regexp; + duk_hstring *h_bytecode; + duk_hstring *h_input; + duk_uint8_t *p_buf; + const duk_uint8_t *pc; + const duk_uint8_t *sp; + duk_small_int_t match = 0; + duk_small_int_t global; + duk_uint_fast32_t i; + double d; + duk_uint32_t char_offset; + + DUK_ASSERT(thr != NULL); + + DUK_DD(DUK_DDPRINT("regexp match: regexp=%!T, input=%!T", + (duk_tval *) duk_get_tval(thr, -2), + (duk_tval *) duk_get_tval(thr, -1))); + + /* + * Regexp instance check, bytecode check, input coercion. + * + * See E5 Section 15.10.6. + */ + + /* TypeError if wrong; class check, see E5 Section 15.10.6 */ + h_regexp = duk_require_hobject_with_class(thr, -2, DUK_HOBJECT_CLASS_REGEXP); + DUK_ASSERT(h_regexp != NULL); + DUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_regexp) == DUK_HOBJECT_CLASS_REGEXP); + DUK_UNREF(h_regexp); + + h_input = duk_to_hstring(thr, -1); + DUK_ASSERT(h_input != NULL); + + duk_xget_owndataprop_stridx_short(thr, -2, DUK_STRIDX_INT_BYTECODE); /* [ ... re_obj input ] -> [ ... re_obj input bc ] */ + h_bytecode = duk_require_hstring(thr, -1); /* no regexp instance should exist without a non-configurable bytecode property */ + DUK_ASSERT(h_bytecode != NULL); + + /* + * Basic context initialization. + * + * Some init values are read from the bytecode header + * whose format is (UTF-8 codepoints): + * + * uint flags + * uint nsaved (even, 2n+2 where n = num captures) + */ + + /* [ ... re_obj input bc ] */ + + duk_memzero(&re_ctx, sizeof(re_ctx)); + + re_ctx.thr = thr; + re_ctx.input = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input); + re_ctx.input_end = re_ctx.input + DUK_HSTRING_GET_BYTELEN(h_input); + re_ctx.bytecode = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_bytecode); + re_ctx.bytecode_end = re_ctx.bytecode + DUK_HSTRING_GET_BYTELEN(h_bytecode); + re_ctx.saved = NULL; + re_ctx.recursion_limit = DUK_USE_REGEXP_EXECUTOR_RECLIMIT; + re_ctx.steps_limit = DUK_RE_EXECUTE_STEPS_LIMIT; + + /* read header */ + pc = re_ctx.bytecode; + re_ctx.re_flags = duk__bc_get_u32(&re_ctx, &pc); + re_ctx.nsaved = duk__bc_get_u32(&re_ctx, &pc); + re_ctx.bytecode = pc; + + DUK_ASSERT(DUK_RE_FLAG_GLOBAL < 0x10000UL); /* must fit into duk_small_int_t */ + global = (duk_small_int_t) (force_global | (duk_small_int_t) (re_ctx.re_flags & DUK_RE_FLAG_GLOBAL)); + + DUK_ASSERT(re_ctx.nsaved >= 2); + DUK_ASSERT((re_ctx.nsaved % 2) == 0); + + p_buf = (duk_uint8_t *) duk_push_fixed_buffer(thr, sizeof(duk_uint8_t *) * re_ctx.nsaved); /* rely on zeroing */ + DUK_UNREF(p_buf); + re_ctx.saved = (const duk_uint8_t **) duk_get_buffer(thr, -1, NULL); + DUK_ASSERT(re_ctx.saved != NULL); + + /* [ ... re_obj input bc saved_buf ] */ + +#if defined(DUK_USE_EXPLICIT_NULL_INIT) + for (i = 0; i < re_ctx.nsaved; i++) { + re_ctx.saved[i] = (duk_uint8_t *) NULL; + } +#elif defined(DUK_USE_ZERO_BUFFER_DATA) + /* buffer is automatically zeroed */ +#else + duk_memzero((void *) p_buf, sizeof(duk_uint8_t *) * re_ctx.nsaved); +#endif + + DUK_DDD(DUK_DDDPRINT("regexp ctx initialized, flags=0x%08lx, nsaved=%ld, recursion_limit=%ld, steps_limit=%ld", + (unsigned long) re_ctx.re_flags, (long) re_ctx.nsaved, (long) re_ctx.recursion_limit, + (long) re_ctx.steps_limit)); + + /* + * Get starting character offset for match, and initialize 'sp' based on it. + * + * Note: lastIndex is non-configurable so it must be present (we check the + * internal class of the object above, so we know it is). User code can set + * its value to an arbitrary (garbage) value though; E5 requires that lastIndex + * be coerced to a number before using. The code below works even if the + * property is missing: the value will then be coerced to zero. + * + * Note: lastIndex may be outside Uint32 range even after ToInteger() coercion. + * For instance, ToInteger(+Infinity) = +Infinity. We track the match offset + * as an integer, but pre-check it to be inside the 32-bit range before the loop. + * If not, the check in E5 Section 15.10.6.2, step 9.a applies. + */ + + /* XXX: lastIndex handling produces a lot of asm */ + + /* [ ... re_obj input bc saved_buf ] */ + + duk_get_prop_stridx_short(thr, -4, DUK_STRIDX_LAST_INDEX); /* -> [ ... re_obj input bc saved_buf lastIndex ] */ + (void) duk_to_int(thr, -1); /* ToInteger(lastIndex) */ + d = duk_get_number(thr, -1); /* integer, but may be +/- Infinite, +/- zero (not NaN, though) */ + duk_pop_nodecref_unsafe(thr); + + if (global) { + if (d < 0.0 || d > (double) DUK_HSTRING_GET_CHARLEN(h_input)) { + /* match fail */ + char_offset = 0; /* not really necessary */ + DUK_ASSERT(match == 0); + goto match_over; + } + char_offset = (duk_uint32_t) d; + } else { + /* lastIndex must be ignored for non-global regexps, but get the + * value for (theoretical) side effects. No side effects can + * really occur, because lastIndex is a normal property and is + * always non-configurable for RegExp instances. + */ + char_offset = (duk_uint32_t) 0; + } + + DUK_ASSERT(char_offset <= DUK_HSTRING_GET_CHARLEN(h_input)); + sp = re_ctx.input + duk_heap_strcache_offset_char2byte(thr, h_input, char_offset); + + /* + * Match loop. + * + * Try matching at different offsets until match found or input exhausted. + */ + + /* [ ... re_obj input bc saved_buf ] */ + + DUK_ASSERT(match == 0); + + for (;;) { + /* char offset in [0, h_input->clen] (both ends inclusive), checked before entry */ + DUK_ASSERT_DISABLE(char_offset >= 0); + DUK_ASSERT(char_offset <= DUK_HSTRING_GET_CHARLEN(h_input)); + + /* Note: re_ctx.steps is intentionally not reset, it applies to the entire unanchored match */ + DUK_ASSERT(re_ctx.recursion_depth == 0); + + DUK_DDD(DUK_DDDPRINT("attempt match at char offset %ld; %p [%p,%p]", + (long) char_offset, (const void *) sp, + (const void *) re_ctx.input, (const void *) re_ctx.input_end)); + + /* + * Note: + * + * - duk__match_regexp() is required not to longjmp() in ordinary "non-match" + * conditions; a longjmp() will terminate the entire matching process. + * + * - Clearing saved[] is not necessary because backtracking does it + * + * - Backtracking also rewinds re_ctx.recursion back to zero, unless an + * internal/limit error occurs (which causes a longjmp()) + * + * - If we supported anchored matches, we would break out here + * unconditionally; however, ECMAScript regexps don't have anchored + * matches. It might make sense to implement a fast bail-out if + * the regexp begins with '^' and sp is not 0: currently we'll just + * run through the entire input string, trivially failing the match + * at every non-zero offset. + */ + + if (duk__match_regexp(&re_ctx, re_ctx.bytecode, sp) != NULL) { + DUK_DDD(DUK_DDDPRINT("match at offset %ld", (long) char_offset)); + match = 1; + break; + } + + /* advance by one character (code point) and one char_offset */ + char_offset++; + if (char_offset > DUK_HSTRING_GET_CHARLEN(h_input)) { + /* + * Note: + * + * - Intentionally attempt (empty) match at char_offset == k_input->clen + * + * - Negative char_offsets have been eliminated and char_offset is duk_uint32_t + * -> no need or use for a negative check + */ + + DUK_DDD(DUK_DDDPRINT("no match after trying all sp offsets")); + break; + } + + /* avoid calling at end of input, will DUK_ERROR (above check suffices to avoid this) */ + (void) duk__utf8_advance(thr, &sp, re_ctx.input, re_ctx.input_end, (duk_uint_fast32_t) 1); + } + + match_over: + + /* + * Matching complete, create result array or return a 'null'. Update lastIndex + * if necessary. See E5 Section 15.10.6.2. + * + * Because lastIndex is a character (not byte) offset, we need the character + * length of the match which we conveniently get as a side effect of interning + * the matching substring (0th index of result array). + * + * saved[0] start pointer (~ byte offset) of current match + * saved[1] end pointer (~ byte offset) of current match (exclusive) + * char_offset start character offset of current match (-> .index of result) + * char_end_offset end character offset (computed below) + */ + + /* [ ... re_obj input bc saved_buf ] */ + + if (match) { +#if defined(DUK_USE_ASSERTIONS) + duk_hobject *h_res; +#endif + duk_uint32_t char_end_offset = 0; + + DUK_DDD(DUK_DDDPRINT("regexp matches at char_offset %ld", (long) char_offset)); + + DUK_ASSERT(re_ctx.nsaved >= 2); /* must have start and end */ + DUK_ASSERT((re_ctx.nsaved % 2) == 0); /* and even number */ + + /* XXX: Array size is known before and (2 * re_ctx.nsaved) but not taken + * advantage of now. The array is not compacted either, as regexp match + * objects are usually short lived. + */ + + duk_push_array(thr); + +#if defined(DUK_USE_ASSERTIONS) + h_res = duk_require_hobject(thr, -1); + DUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h_res)); + DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(h_res)); + DUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_res) == DUK_HOBJECT_CLASS_ARRAY); +#endif + + /* [ ... re_obj input bc saved_buf res_obj ] */ + + duk_push_u32(thr, char_offset); + duk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INDEX); + + duk_dup_m4(thr); + duk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INPUT); + + for (i = 0; i < re_ctx.nsaved; i += 2) { + /* Captures which are undefined have NULL pointers and are returned + * as 'undefined'. The same is done when saved[] pointers are insane + * (this should, of course, never happen in practice). + */ + if (re_ctx.saved[i] && re_ctx.saved[i + 1] && re_ctx.saved[i + 1] >= re_ctx.saved[i]) { + duk_push_lstring(thr, + (const char *) re_ctx.saved[i], + (duk_size_t) (re_ctx.saved[i+1] - re_ctx.saved[i])); + if (i == 0) { + /* Assumes that saved[0] and saved[1] are always + * set by regexp bytecode (if not, char_end_offset + * will be zero). Also assumes clen reflects the + * correct char length. + */ + char_end_offset = char_offset + (duk_uint32_t) duk_get_length(thr, -1); /* add charlen */ + } + } else { + duk_push_undefined(thr); + } + + /* [ ... re_obj input bc saved_buf res_obj val ] */ + duk_put_prop_index(thr, -2, (duk_uarridx_t) (i / 2)); + } + + /* [ ... re_obj input bc saved_buf res_obj ] */ + + /* NB: 'length' property is automatically updated by the array setup loop */ + + if (global) { + /* global regexp: lastIndex updated on match */ + duk_push_u32(thr, char_end_offset); + duk_put_prop_stridx_short(thr, -6, DUK_STRIDX_LAST_INDEX); + } else { + /* non-global regexp: lastIndex never updated on match */ + ; + } + } else { + /* + * No match, E5 Section 15.10.6.2, step 9.a.i - 9.a.ii apply, regardless + * of 'global' flag of the RegExp. In particular, if lastIndex is invalid + * initially, it is reset to zero. + */ + + DUK_DDD(DUK_DDDPRINT("regexp does not match")); + + duk_push_null(thr); + + /* [ ... re_obj input bc saved_buf res_obj ] */ + + duk_push_int(thr, 0); + duk_put_prop_stridx_short(thr, -6, DUK_STRIDX_LAST_INDEX); + } + + /* [ ... re_obj input bc saved_buf res_obj ] */ + + duk_insert(thr, -5); + + /* [ ... res_obj re_obj input bc saved_buf ] */ + + duk_pop_n_unsafe(thr, 4); + + /* [ ... res_obj ] */ + + /* XXX: these last tricks are unnecessary if the function is made + * a genuine native function. + */ +} + +DUK_INTERNAL void duk_regexp_match(duk_hthread *thr) { + duk__regexp_match_helper(thr, 0 /*force_global*/); +} + +/* This variant is needed by String.prototype.split(); it needs to perform + * global-style matching on a cloned RegExp which is potentially non-global. + */ +DUK_INTERNAL void duk_regexp_match_force_global(duk_hthread *thr) { + duk__regexp_match_helper(thr, 1 /*force_global*/); +} + +#else /* DUK_USE_REGEXP_SUPPORT */ + +/* regexp support disabled */ + +#endif /* DUK_USE_REGEXP_SUPPORT */ diff --git a/third_party/duktape/duk_replacements.c b/third_party/duktape/duk_replacements.c new file mode 100644 index 00000000..2389ea59 --- /dev/null +++ b/third_party/duktape/duk_replacements.c @@ -0,0 +1,82 @@ +/* + * Replacements for missing platform functions. + * + * Unlike the originals, fpclassify() and signbit() replacements don't + * work on any floating point types, only doubles. The C typing here + * mimics the standard prototypes. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_COMPUTED_NAN) +DUK_INTERNAL double duk_computed_nan; +#endif + +#if defined(DUK_USE_COMPUTED_INFINITY) +DUK_INTERNAL double duk_computed_infinity; +#endif + +#if defined(DUK_USE_REPL_FPCLASSIFY) +DUK_INTERNAL int duk_repl_fpclassify(double x) { + duk_double_union u; + duk_uint_fast16_t expt; + duk_small_int_t mzero; + + u.d = x; + expt = (duk_uint_fast16_t) (u.us[DUK_DBL_IDX_US0] & 0x7ff0UL); + if (expt > 0x0000UL && expt < 0x7ff0UL) { + /* expt values [0x001,0x7fe] = normal */ + return DUK_FP_NORMAL; + } + + mzero = (u.ui[DUK_DBL_IDX_UI1] == 0 && (u.ui[DUK_DBL_IDX_UI0] & 0x000fffffUL) == 0); + if (expt == 0x0000UL) { + /* expt 0x000 is zero/subnormal */ + if (mzero) { + return DUK_FP_ZERO; + } else { + return DUK_FP_SUBNORMAL; + } + } else { + /* expt 0xfff is infinite/nan */ + if (mzero) { + return DUK_FP_INFINITE; + } else { + return DUK_FP_NAN; + } + } +} +#endif + +#if defined(DUK_USE_REPL_SIGNBIT) +DUK_INTERNAL int duk_repl_signbit(double x) { + duk_double_union u; + u.d = x; + return (int) (u.uc[DUK_DBL_IDX_UC0] & 0x80UL); +} +#endif + +#if defined(DUK_USE_REPL_ISFINITE) +DUK_INTERNAL int duk_repl_isfinite(double x) { + int c = DUK_FPCLASSIFY(x); + if (c == DUK_FP_NAN || c == DUK_FP_INFINITE) { + return 0; + } else { + return 1; + } +} +#endif + +#if defined(DUK_USE_REPL_ISNAN) +DUK_INTERNAL int duk_repl_isnan(double x) { + int c = DUK_FPCLASSIFY(x); + return (c == DUK_FP_NAN); +} +#endif + +#if defined(DUK_USE_REPL_ISINF) +DUK_INTERNAL int duk_repl_isinf(double x) { + int c = DUK_FPCLASSIFY(x); + return (c == DUK_FP_INFINITE); +} +#endif diff --git a/third_party/duktape/duk_replacements.h b/third_party/duktape/duk_replacements.h new file mode 100644 index 00000000..ac8b81f7 --- /dev/null +++ b/third_party/duktape/duk_replacements.h @@ -0,0 +1,29 @@ +#if !defined(DUK_REPLACEMENTS_H_INCLUDED) +#define DUK_REPLACEMENTS_H_INCLUDED + +#if !defined(DUK_SINGLE_FILE) +#if defined(DUK_USE_COMPUTED_INFINITY) +DUK_INTERNAL_DECL double duk_computed_infinity; +#endif +#if defined(DUK_USE_COMPUTED_NAN) +DUK_INTERNAL_DECL double duk_computed_nan; +#endif +#endif /* !DUK_SINGLE_FILE */ + +#if defined(DUK_USE_REPL_FPCLASSIFY) +DUK_INTERNAL_DECL int duk_repl_fpclassify(double x); +#endif +#if defined(DUK_USE_REPL_SIGNBIT) +DUK_INTERNAL_DECL int duk_repl_signbit(double x); +#endif +#if defined(DUK_USE_REPL_ISFINITE) +DUK_INTERNAL_DECL int duk_repl_isfinite(double x); +#endif +#if defined(DUK_USE_REPL_ISNAN) +DUK_INTERNAL_DECL int duk_repl_isnan(double x); +#endif +#if defined(DUK_USE_REPL_ISINF) +DUK_INTERNAL_DECL int duk_repl_isinf(double x); +#endif + +#endif /* DUK_REPLACEMENTS_H_INCLUDED */ diff --git a/third_party/duktape/duk_selftest.c b/third_party/duktape/duk_selftest.c new file mode 100644 index 00000000..aa586559 --- /dev/null +++ b/third_party/duktape/duk_selftest.c @@ -0,0 +1,678 @@ +/* + * Self tests to ensure execution environment is sane. Intended to catch + * compiler/platform problems which cannot be detected at compile time. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_SELF_TESTS) + +/* + * Unions and structs for self tests + */ + +typedef union { + double d; + duk_uint8_t x[8]; +} duk__test_double_union; + +/* Self test failed. Expects a local variable 'error_count' to exist. */ +#define DUK__FAILED(msg) do { \ + DUK_D(DUK_DPRINT("self test failed: " #msg " at " DUK_FILE_MACRO ":" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO))); \ + error_count++; \ + } while (0) + +#define DUK__DBLUNION_CMP_TRUE(a,b) do { \ + if (duk_memcmp((const void *) (a), (const void *) (b), sizeof(duk__test_double_union)) != 0) { \ + DUK__FAILED("double union compares false (expected true)"); \ + } \ + } while (0) + +#define DUK__DBLUNION_CMP_FALSE(a,b) do { \ + if (duk_memcmp((const void *) (a), (const void *) (b), sizeof(duk__test_double_union)) == 0) { \ + DUK__FAILED("double union compares true (expected false)"); \ + } \ + } while (0) + +typedef union { + duk_uint32_t i; + duk_uint8_t x[8]; +} duk__test_u32_union; + +#if defined(DUK_USE_INTEGER_LE) +#define DUK__U32_INIT(u, a, b, c, d) do { \ + (u)->x[0] = (d); (u)->x[1] = (c); (u)->x[2] = (b); (u)->x[3] = (a); \ + } while (0) +#elif defined(DUK_USE_INTEGER_ME) +#error integer mixed endian not supported now +#elif defined(DUK_USE_INTEGER_BE) +#define DUK__U32_INIT(u, a, b, c, d) do { \ + (u)->x[0] = (a); (u)->x[1] = (b); (u)->x[2] = (c); (u)->x[3] = (d); \ + } while (0) +#else +#error unknown integer endianness +#endif + +#if defined(DUK_USE_DOUBLE_LE) +#define DUK__DOUBLE_INIT(u, a, b, c, d, e, f, g, h) do { \ + (u)->x[0] = (h); (u)->x[1] = (g); (u)->x[2] = (f); (u)->x[3] = (e); \ + (u)->x[4] = (d); (u)->x[5] = (c); (u)->x[6] = (b); (u)->x[7] = (a); \ + } while (0) +#define DUK__DOUBLE_COMPARE(u, a, b, c, d, e, f, g, h) \ + ((u)->x[0] == (h) && (u)->x[1] == (g) && (u)->x[2] == (f) && (u)->x[3] == (e) && \ + (u)->x[4] == (d) && (u)->x[5] == (c) && (u)->x[6] == (b) && (u)->x[7] == (a)) +#elif defined(DUK_USE_DOUBLE_ME) +#define DUK__DOUBLE_INIT(u, a, b, c, d, e, f, g, h) do { \ + (u)->x[0] = (d); (u)->x[1] = (c); (u)->x[2] = (b); (u)->x[3] = (a); \ + (u)->x[4] = (h); (u)->x[5] = (g); (u)->x[6] = (f); (u)->x[7] = (e); \ + } while (0) +#define DUK__DOUBLE_COMPARE(u, a, b, c, d, e, f, g, h) \ + ((u)->x[0] == (d) && (u)->x[1] == (c) && (u)->x[2] == (b) && (u)->x[3] == (a) && \ + (u)->x[4] == (h) && (u)->x[5] == (g) && (u)->x[6] == (f) && (u)->x[7] == (e)) +#elif defined(DUK_USE_DOUBLE_BE) +#define DUK__DOUBLE_INIT(u, a, b, c, d, e, f, g, h) do { \ + (u)->x[0] = (a); (u)->x[1] = (b); (u)->x[2] = (c); (u)->x[3] = (d); \ + (u)->x[4] = (e); (u)->x[5] = (f); (u)->x[6] = (g); (u)->x[7] = (h); \ + } while (0) +#define DUK__DOUBLE_COMPARE(u, a, b, c, d, e, f, g, h) \ + ((u)->x[0] == (a) && (u)->x[1] == (b) && (u)->x[2] == (c) && (u)->x[3] == (d) && \ + (u)->x[4] == (e) && (u)->x[5] == (f) && (u)->x[6] == (g) && (u)->x[7] == (h)) +#else +#error unknown double endianness +#endif + +/* + * Various sanity checks for typing + */ + +DUK_LOCAL duk_uint_t duk__selftest_types(void) { + duk_uint_t error_count = 0; + + if (!(sizeof(duk_int8_t) == 1 && + sizeof(duk_uint8_t) == 1 && + sizeof(duk_int16_t) == 2 && + sizeof(duk_uint16_t) == 2 && + sizeof(duk_int32_t) == 4 && + sizeof(duk_uint32_t) == 4)) { + DUK__FAILED("duk_(u)int{8,16,32}_t size"); + } +#if defined(DUK_USE_64BIT_OPS) + if (!(sizeof(duk_int64_t) == 8 && + sizeof(duk_uint64_t) == 8)) { + DUK__FAILED("duk_(u)int64_t size"); + } +#endif + + if (!(sizeof(duk_size_t) >= sizeof(duk_uint_t))) { + /* Some internal code now assumes that all duk_uint_t values + * can be expressed with a duk_size_t. + */ + DUK__FAILED("duk_size_t is smaller than duk_uint_t"); + } + if (!(sizeof(duk_int_t) >= 4)) { + DUK__FAILED("duk_int_t is not 32 bits"); + } + + return error_count; +} + +/* + * Packed tval sanity + */ + +DUK_LOCAL duk_uint_t duk__selftest_packed_tval(void) { + duk_uint_t error_count = 0; + +#if defined(DUK_USE_PACKED_TVAL) + if (sizeof(void *) > 4) { + DUK__FAILED("packed duk_tval in use but sizeof(void *) > 4"); + } +#endif + + return error_count; +} + +/* + * Two's complement arithmetic. + */ + +DUK_LOCAL duk_uint_t duk__selftest_twos_complement(void) { + duk_uint_t error_count = 0; + volatile int test; + test = -1; + + /* Note that byte order doesn't affect this test: all bytes in + * 'test' will be 0xFF for two's complement. + */ + if (((volatile duk_uint8_t *) &test)[0] != (duk_uint8_t) 0xff) { + DUK__FAILED("two's complement arithmetic"); + } + + return error_count; +} + +/* + * Byte order. Important to self check, because on some exotic platforms + * there is no actual detection but rather assumption based on platform + * defines. + */ + +DUK_LOCAL duk_uint_t duk__selftest_byte_order(void) { + duk_uint_t error_count = 0; + duk__test_u32_union u1; + duk__test_double_union u2; + + /* + * >>> struct.pack('>d', 102030405060).encode('hex') + * '4237c17c6dc40000' + */ + + DUK__U32_INIT(&u1, 0xde, 0xad, 0xbe, 0xef); + DUK__DOUBLE_INIT(&u2, 0x42, 0x37, 0xc1, 0x7c, 0x6d, 0xc4, 0x00, 0x00); + + if (u1.i != (duk_uint32_t) 0xdeadbeefUL) { + DUK__FAILED("duk_uint32_t byte order"); + } + + if (!duk_double_equals(u2.d, 102030405060.0)) { + DUK__FAILED("double byte order"); + } + + return error_count; +} + +/* + * DUK_BSWAP macros + */ + +DUK_LOCAL duk_uint_t duk__selftest_bswap_macros(void) { + duk_uint_t error_count = 0; + volatile duk_uint32_t x32_input, x32_output; + duk_uint32_t x32; + volatile duk_uint16_t x16_input, x16_output; + duk_uint16_t x16; + duk_double_union du; + duk_double_t du_diff; +#if defined(DUK_BSWAP64) + volatile duk_uint64_t x64_input, x64_output; + duk_uint64_t x64; +#endif + + /* Cover both compile time and runtime bswap operations, as these + * may have different bugs. + */ + + x16_input = 0xbeefUL; + x16 = x16_input; + x16 = DUK_BSWAP16(x16); + x16_output = x16; + if (x16_output != (duk_uint16_t) 0xefbeUL) { + DUK__FAILED("DUK_BSWAP16"); + } + + x16 = 0xbeefUL; + x16 = DUK_BSWAP16(x16); + if (x16 != (duk_uint16_t) 0xefbeUL) { + DUK__FAILED("DUK_BSWAP16"); + } + + x32_input = 0xdeadbeefUL; + x32 = x32_input; + x32 = DUK_BSWAP32(x32); + x32_output = x32; + if (x32_output != (duk_uint32_t) 0xefbeaddeUL) { + DUK__FAILED("DUK_BSWAP32"); + } + + x32 = 0xdeadbeefUL; + x32 = DUK_BSWAP32(x32); + if (x32 != (duk_uint32_t) 0xefbeaddeUL) { + DUK__FAILED("DUK_BSWAP32"); + } + +#if defined(DUK_BSWAP64) + x64_input = DUK_U64_CONSTANT(0x8899aabbccddeeff); + x64 = x64_input; + x64 = DUK_BSWAP64(x64); + x64_output = x64; + if (x64_output != (duk_uint64_t) DUK_U64_CONSTANT(0xffeeddccbbaa9988)) { + DUK__FAILED("DUK_BSWAP64"); + } + + x64 = DUK_U64_CONSTANT(0x8899aabbccddeeff); + x64 = DUK_BSWAP64(x64); + if (x64 != (duk_uint64_t) DUK_U64_CONSTANT(0xffeeddccbbaa9988)) { + DUK__FAILED("DUK_BSWAP64"); + } +#endif + + /* >>> struct.unpack('>d', '4000112233445566'.decode('hex')) + * (2.008366013071895,) + */ + + du.uc[0] = 0x40; du.uc[1] = 0x00; du.uc[2] = 0x11; du.uc[3] = 0x22; + du.uc[4] = 0x33; du.uc[5] = 0x44; du.uc[6] = 0x55; du.uc[7] = 0x66; + DUK_DBLUNION_DOUBLE_NTOH(&du); + du_diff = du.d - 2.008366013071895; +#if 0 + DUK_D(DUK_DPRINT("du_diff: %lg\n", (double) du_diff)); +#endif + if (du_diff > 1e-15) { + /* Allow very small lenience because some compilers won't parse + * exact IEEE double constants (happened in matrix testing with + * Linux gcc-4.8 -m32 at least). + */ +#if 0 + DUK_D(DUK_DPRINT("Result of DUK_DBLUNION_DOUBLE_NTOH: %02x %02x %02x %02x %02x %02x %02x %02x\n", + (unsigned int) du.uc[0], (unsigned int) du.uc[1], + (unsigned int) du.uc[2], (unsigned int) du.uc[3], + (unsigned int) du.uc[4], (unsigned int) du.uc[5], + (unsigned int) du.uc[6], (unsigned int) du.uc[7])); +#endif + DUK__FAILED("DUK_DBLUNION_DOUBLE_NTOH"); + } + + return error_count; +} + +/* + * Basic double / byte union memory layout. + */ + +DUK_LOCAL duk_uint_t duk__selftest_double_union_size(void) { + duk_uint_t error_count = 0; + + if (sizeof(duk__test_double_union) != 8) { + DUK__FAILED("invalid union size"); + } + + return error_count; +} + +/* + * Union aliasing, see misc/clang_aliasing.c. + */ + +DUK_LOCAL duk_uint_t duk__selftest_double_aliasing(void) { + /* This testcase fails when Emscripten-generated code runs on Firefox. + * It's not an issue because the failure should only affect packed + * duk_tval representation, which is not used with Emscripten. + */ +#if defined(DUK_USE_PACKED_TVAL) + duk_uint_t error_count = 0; + duk__test_double_union a, b; + + /* Test signaling NaN and alias assignment in all endianness combinations. + */ + + /* little endian */ + a.x[0] = 0x11; a.x[1] = 0x22; a.x[2] = 0x33; a.x[3] = 0x44; + a.x[4] = 0x00; a.x[5] = 0x00; a.x[6] = 0xf1; a.x[7] = 0xff; + b = a; + DUK__DBLUNION_CMP_TRUE(&a, &b); + + /* big endian */ + a.x[0] = 0xff; a.x[1] = 0xf1; a.x[2] = 0x00; a.x[3] = 0x00; + a.x[4] = 0x44; a.x[5] = 0x33; a.x[6] = 0x22; a.x[7] = 0x11; + b = a; + DUK__DBLUNION_CMP_TRUE(&a, &b); + + /* mixed endian */ + a.x[0] = 0x00; a.x[1] = 0x00; a.x[2] = 0xf1; a.x[3] = 0xff; + a.x[4] = 0x11; a.x[5] = 0x22; a.x[6] = 0x33; a.x[7] = 0x44; + b = a; + DUK__DBLUNION_CMP_TRUE(&a, &b); + + return error_count; +#else + DUK_D(DUK_DPRINT("skip double aliasing self test when duk_tval is not packed")); + return 0; +#endif +} + +/* + * Zero sign, see misc/tcc_zerosign2.c. + */ + +DUK_LOCAL duk_uint_t duk__selftest_double_zero_sign(void) { + duk_uint_t error_count = 0; + duk__test_double_union a, b; + + a.d = 0.0; + b.d = -a.d; + DUK__DBLUNION_CMP_FALSE(&a, &b); + + return error_count; +} + +/* + * Rounding mode: Duktape assumes round-to-nearest, check that this is true. + * If we had C99 fenv.h we could check that fegetround() == FE_TONEAREST, + * but we don't want to rely on that header; and even if we did, it's good + * to ensure the rounding actually works. + */ + +DUK_LOCAL duk_uint_t duk__selftest_double_rounding(void) { + duk_uint_t error_count = 0; + duk__test_double_union a, b, c; + +#if 0 + /* Include and test manually; these trigger failures: */ + fesetround(FE_UPWARD); + fesetround(FE_DOWNWARD); + fesetround(FE_TOWARDZERO); + + /* This is the default and passes. */ + fesetround(FE_TONEAREST); +#endif + + /* Rounding tests check that none of the other modes (round to + * +Inf, round to -Inf, round to zero) can be active: + * http://www.gnu.org/software/libc/manual/html_node/Rounding.html + */ + + /* 1.0 + 2^(-53): result is midway between 1.0 and 1.0 + ulp. + * Round to nearest: 1.0 + * Round to +Inf: 1.0 + ulp + * Round to -Inf: 1.0 + * Round to zero: 1.0 + * => Correct result eliminates round to +Inf. + */ + DUK__DOUBLE_INIT(&a, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + DUK__DOUBLE_INIT(&b, 0x3c, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + duk_memset((void *) &c, 0, sizeof(c)); + c.d = a.d + b.d; + if (!DUK__DOUBLE_COMPARE(&c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)) { + DUK_D(DUK_DPRINT("broken result (native endiannesss): %02x %02x %02x %02x %02x %02x %02x %02x", + (unsigned int) c.x[0], (unsigned int) c.x[1], + (unsigned int) c.x[2], (unsigned int) c.x[3], + (unsigned int) c.x[4], (unsigned int) c.x[5], + (unsigned int) c.x[6], (unsigned int) c.x[7])); + DUK__FAILED("invalid result from 1.0 + 0.5ulp"); + } + + /* (1.0 + ulp) + 2^(-53): result is midway between 1.0 + ulp and 1.0 + 2*ulp. + * Round to nearest: 1.0 + 2*ulp (round to even mantissa) + * Round to +Inf: 1.0 + 2*ulp + * Round to -Inf: 1.0 + ulp + * Round to zero: 1.0 + ulp + * => Correct result eliminates round to -Inf and round to zero. + */ + DUK__DOUBLE_INIT(&a, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01); + DUK__DOUBLE_INIT(&b, 0x3c, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + duk_memset((void *) &c, 0, sizeof(c)); + c.d = a.d + b.d; + if (!DUK__DOUBLE_COMPARE(&c, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02)) { + DUK_D(DUK_DPRINT("broken result (native endiannesss): %02x %02x %02x %02x %02x %02x %02x %02x", + (unsigned int) c.x[0], (unsigned int) c.x[1], + (unsigned int) c.x[2], (unsigned int) c.x[3], + (unsigned int) c.x[4], (unsigned int) c.x[5], + (unsigned int) c.x[6], (unsigned int) c.x[7])); + DUK__FAILED("invalid result from (1.0 + ulp) + 0.5ulp"); + } + + /* Could do negative number testing too, but the tests above should + * differentiate between IEEE 754 rounding modes. + */ + return error_count; +} + +/* + * fmod(): often a portability issue in embedded or bare platform targets. + * Check for at least minimally correct behavior. Unlike some other math + * functions (like cos()) Duktape relies on fmod() internally too. + */ + +DUK_LOCAL duk_uint_t duk__selftest_fmod(void) { + duk_uint_t error_count = 0; + duk__test_double_union u1, u2; + volatile duk_double_t t1, t2, t3; + + /* fmod() with integer argument and exponent 2^32 is used by e.g. + * ToUint32() and some Duktape internals. + */ + u1.d = DUK_FMOD(10.0, 4294967296.0); + u2.d = 10.0; + DUK__DBLUNION_CMP_TRUE(&u1, &u2); + + u1.d = DUK_FMOD(4294967306.0, 4294967296.0); + u2.d = 10.0; + DUK__DBLUNION_CMP_TRUE(&u1, &u2); + + u1.d = DUK_FMOD(73014444042.0, 4294967296.0); + u2.d = 10.0; + DUK__DBLUNION_CMP_TRUE(&u1, &u2); + + /* 52-bit integer split into two parts: + * >>> 0x1fedcba9876543 + * 8987183256397123 + * >>> float(0x1fedcba9876543) / float(2**53) + * 0.9977777777777778 + */ + u1.d = DUK_FMOD(8987183256397123.0, 4294967296.0); + u2.d = (duk_double_t) 0xa9876543UL; + DUK__DBLUNION_CMP_TRUE(&u1, &u2); + t1 = 8987183256397123.0; + t2 = 4294967296.0; + t3 = t1 / t2; + u1.d = DUK_FLOOR(t3); + u2.d = (duk_double_t) 0x1fedcbUL; + DUK__DBLUNION_CMP_TRUE(&u1, &u2); + + /* C99 behavior is for fmod() result sign to mathc argument sign. */ + u1.d = DUK_FMOD(-10.0, 4294967296.0); + u2.d = -10.0; + DUK__DBLUNION_CMP_TRUE(&u1, &u2); + + u1.d = DUK_FMOD(-4294967306.0, 4294967296.0); + u2.d = -10.0; + DUK__DBLUNION_CMP_TRUE(&u1, &u2); + + u1.d = DUK_FMOD(-73014444042.0, 4294967296.0); + u2.d = -10.0; + DUK__DBLUNION_CMP_TRUE(&u1, &u2); + + return error_count; +} + +/* + * Struct size/alignment if platform requires it + * + * There are some compiler specific struct padding pragmas etc in use, this + * selftest ensures they're correctly detected and used. + */ + +DUK_LOCAL duk_uint_t duk__selftest_struct_align(void) { + duk_uint_t error_count = 0; + +#if (DUK_USE_ALIGN_BY == 4) + if ((sizeof(duk_hbuffer_fixed) % 4) != 0) { + DUK__FAILED("sizeof(duk_hbuffer_fixed) not aligned to 4"); + } +#elif (DUK_USE_ALIGN_BY == 8) + if ((sizeof(duk_hbuffer_fixed) % 8) != 0) { + DUK__FAILED("sizeof(duk_hbuffer_fixed) not aligned to 8"); + } +#elif (DUK_USE_ALIGN_BY == 1) + /* no check */ +#else +#error invalid DUK_USE_ALIGN_BY +#endif + return error_count; +} + +/* + * 64-bit arithmetic + * + * There are some platforms/compilers where 64-bit types are available + * but don't work correctly. Test for known cases. + */ + +DUK_LOCAL duk_uint_t duk__selftest_64bit_arithmetic(void) { + duk_uint_t error_count = 0; +#if defined(DUK_USE_64BIT_OPS) + volatile duk_int64_t i; + volatile duk_double_t d; + + /* Catch a double-to-int64 cast issue encountered in practice. */ + d = 2147483648.0; + i = (duk_int64_t) d; + if (i != DUK_I64_CONSTANT(0x80000000)) { + DUK__FAILED("casting 2147483648.0 to duk_int64_t failed"); + } +#else + /* nop */ +#endif + return error_count; +} + +/* + * Casting + */ + +DUK_LOCAL duk_uint_t duk__selftest_cast_double_to_small_uint(void) { + /* + * https://github.com/svaarala/duktape/issues/127#issuecomment-77863473 + */ + + duk_uint_t error_count = 0; + + duk_double_t d1, d2; + duk_small_uint_t u; + + duk_double_t d1v, d2v; + duk_small_uint_t uv; + + /* Test without volatiles */ + + d1 = 1.0; + u = (duk_small_uint_t) d1; + d2 = (duk_double_t) u; + + if (!(duk_double_equals(d1, 1.0) && u == 1 && duk_double_equals(d2, 1.0) && duk_double_equals(d1, d2))) { + DUK__FAILED("double to duk_small_uint_t cast failed"); + } + + /* Same test with volatiles */ + + d1v = 1.0; + uv = (duk_small_uint_t) d1v; + d2v = (duk_double_t) uv; + + if (!(duk_double_equals(d1v, 1.0) && uv == 1 && duk_double_equals(d2v, 1.0) && duk_double_equals(d1v, d2v))) { + DUK__FAILED("double to duk_small_uint_t cast failed"); + } + + return error_count; +} + +DUK_LOCAL duk_uint_t duk__selftest_cast_double_to_uint32(void) { + /* + * This test fails on an exotic ARM target; double-to-uint + * cast is incorrectly clamped to -signed- int highest value. + * + * https://github.com/svaarala/duktape/issues/336 + */ + + duk_uint_t error_count = 0; + duk_double_t dv; + duk_uint32_t uv; + + dv = 3735928559.0; /* 0xdeadbeef in decimal */ + uv = (duk_uint32_t) dv; + + if (uv != 0xdeadbeefUL) { + DUK__FAILED("double to duk_uint32_t cast failed"); + } + + return error_count; +} + +/* + * Minimal test of user supplied allocation functions + * + * - Basic alloc + realloc + free cycle + * + * - Realloc to significantly larger size to (hopefully) trigger a + * relocation and check that relocation copying works + */ + +DUK_LOCAL duk_uint_t duk__selftest_alloc_funcs(duk_alloc_function alloc_func, + duk_realloc_function realloc_func, + duk_free_function free_func, + void *udata) { + duk_uint_t error_count = 0; + void *ptr; + void *new_ptr; + duk_small_int_t i, j; + unsigned char x; + + if (alloc_func == NULL || realloc_func == NULL || free_func == NULL) { + return 0; + } + + for (i = 1; i <= 256; i++) { + ptr = alloc_func(udata, (duk_size_t) i); + if (ptr == NULL) { + DUK_D(DUK_DPRINT("alloc failed, ignore")); + continue; /* alloc failed, ignore */ + } + for (j = 0; j < i; j++) { + ((unsigned char *) ptr)[j] = (unsigned char) (0x80 + j); + } + new_ptr = realloc_func(udata, ptr, 1024); + if (new_ptr == NULL) { + DUK_D(DUK_DPRINT("realloc failed, ignore")); + free_func(udata, ptr); + continue; /* realloc failed, ignore */ + } + ptr = new_ptr; + for (j = 0; j < i; j++) { + x = ((unsigned char *) ptr)[j]; + if (x != (unsigned char) (0x80 + j)) { + DUK_D(DUK_DPRINT("byte at index %ld doesn't match after realloc: %02lx", + (long) j, (unsigned long) x)); + DUK__FAILED("byte compare after realloc"); + break; + } + } + free_func(udata, ptr); + } + + return error_count; +} + +/* + * Self test main + */ + +DUK_INTERNAL duk_uint_t duk_selftest_run_tests(duk_alloc_function alloc_func, + duk_realloc_function realloc_func, + duk_free_function free_func, + void *udata) { + duk_uint_t error_count = 0; + + DUK_D(DUK_DPRINT("self test starting")); + + error_count += duk__selftest_types(); + error_count += duk__selftest_packed_tval(); + error_count += duk__selftest_twos_complement(); + error_count += duk__selftest_byte_order(); + error_count += duk__selftest_bswap_macros(); + error_count += duk__selftest_double_union_size(); + error_count += duk__selftest_double_aliasing(); + error_count += duk__selftest_double_zero_sign(); + error_count += duk__selftest_double_rounding(); + error_count += duk__selftest_fmod(); + error_count += duk__selftest_struct_align(); + error_count += duk__selftest_64bit_arithmetic(); + error_count += duk__selftest_cast_double_to_small_uint(); + error_count += duk__selftest_cast_double_to_uint32(); + error_count += duk__selftest_alloc_funcs(alloc_func, realloc_func, free_func, udata); + + DUK_D(DUK_DPRINT("self test complete, total error count: %ld", (long) error_count)); + + return error_count; +} + +#endif /* DUK_USE_SELF_TESTS */ diff --git a/third_party/duktape/duk_selftest.h b/third_party/duktape/duk_selftest.h new file mode 100644 index 00000000..6fb6cc37 --- /dev/null +++ b/third_party/duktape/duk_selftest.h @@ -0,0 +1,15 @@ +/* + * Selftest code + */ + +#if !defined(DUK_SELFTEST_H_INCLUDED) +#define DUK_SELFTEST_H_INCLUDED + +#if defined(DUK_USE_SELF_TESTS) +DUK_INTERNAL_DECL duk_uint_t duk_selftest_run_tests(duk_alloc_function alloc_func, + duk_realloc_function realloc_func, + duk_free_function free_func, + void *udata); +#endif + +#endif /* DUK_SELFTEST_H_INCLUDED */ diff --git a/third_party/duktape/duk_strings.h b/third_party/duktape/duk_strings.h new file mode 100644 index 00000000..194c389a --- /dev/null +++ b/third_party/duktape/duk_strings.h @@ -0,0 +1,167 @@ +/* + * Shared string macros. + * + * Using shared macros helps minimize strings data size because it's easy + * to check if an existing string could be used. String constants don't + * need to be all defined here; defining a string here makes sense if there's + * a high chance the string could be reused. Also, using macros allows + * a call site express the exact string needed, but the macro may map to an + * approximate string to reduce unique string count. Macros can also be + * more easily tuned for low memory targets than #if defined()s throughout + * the code base. + * + * Because format strings behave differently in the call site (they need to + * be followed by format arguments), they use a special prefix DUK_STR_FMT_. + * + * On some compilers using explicit shared strings is preferable; on others + * it may be better to use straight literals because the compiler will combine + * them anyway, and such strings won't end up unnecessarily in a symbol table. + */ + +#if !defined(DUK_ERRMSG_H_INCLUDED) +#define DUK_ERRMSG_H_INCLUDED + +/* Mostly API and built-in method related */ +#define DUK_STR_INTERNAL_ERROR "internal error" +#define DUK_STR_UNSUPPORTED "unsupported" +#define DUK_STR_INVALID_COUNT "invalid count" +#define DUK_STR_INVALID_ARGS "invalid args" +#define DUK_STR_INVALID_STATE "invalid state" +#define DUK_STR_INVALID_INPUT "invalid input" +#define DUK_STR_INVALID_LENGTH "invalid length" +#define DUK_STR_NOT_CONSTRUCTABLE "not constructable" +#define DUK_STR_CONSTRUCT_ONLY "constructor requires 'new'" +#define DUK_STR_NOT_CALLABLE "not callable" +#define DUK_STR_NOT_EXTENSIBLE "not extensible" +#define DUK_STR_NOT_WRITABLE "not writable" +#define DUK_STR_NOT_CONFIGURABLE "not configurable" +#define DUK_STR_INVALID_CONTEXT "invalid context" +#define DUK_STR_INVALID_INDEX "invalid args" +#define DUK_STR_PUSH_BEYOND_ALLOC_STACK "cannot push beyond allocated stack" +#define DUK_STR_NOT_UNDEFINED "unexpected type" +#define DUK_STR_NOT_NULL "unexpected type" +#define DUK_STR_NOT_BOOLEAN "unexpected type" +#define DUK_STR_NOT_NUMBER "unexpected type" +#define DUK_STR_NOT_STRING "unexpected type" +#define DUK_STR_NOT_OBJECT "unexpected type" +#define DUK_STR_NOT_POINTER "unexpected type" +#define DUK_STR_NOT_BUFFER "not buffer" /* still in use with verbose messages */ +#define DUK_STR_UNEXPECTED_TYPE "unexpected type" +#define DUK_STR_NOT_THREAD "unexpected type" +#define DUK_STR_NOT_COMPFUNC "unexpected type" +#define DUK_STR_NOT_NATFUNC "unexpected type" +#define DUK_STR_NOT_C_FUNCTION "unexpected type" +#define DUK_STR_NOT_FUNCTION "unexpected type" +#define DUK_STR_NOT_REGEXP "unexpected type" +#define DUK_STR_TOPRIMITIVE_FAILED "coercion to primitive failed" +#define DUK_STR_NUMBER_OUTSIDE_RANGE "number outside range" +#define DUK_STR_NOT_OBJECT_COERCIBLE "not object coercible" +#define DUK_STR_CANNOT_NUMBER_COERCE_SYMBOL "cannot number coerce Symbol" +#define DUK_STR_CANNOT_STRING_COERCE_SYMBOL "cannot string coerce Symbol" +#define DUK_STR_STRING_TOO_LONG "string too long" +#define DUK_STR_BUFFER_TOO_LONG "buffer too long" +#define DUK_STR_ALLOC_FAILED "alloc failed" +#define DUK_STR_WRONG_BUFFER_TYPE "wrong buffer type" +#define DUK_STR_BASE64_ENCODE_FAILED "base64 encode failed" +#define DUK_STR_SOURCE_DECODE_FAILED "source decode failed" +#define DUK_STR_UTF8_DECODE_FAILED "utf-8 decode failed" +#define DUK_STR_BASE64_DECODE_FAILED "base64 decode failed" +#define DUK_STR_HEX_DECODE_FAILED "hex decode failed" +#define DUK_STR_INVALID_BYTECODE "invalid bytecode" +#define DUK_STR_NO_SOURCECODE "no sourcecode" +#define DUK_STR_RESULT_TOO_LONG "result too long" +#define DUK_STR_INVALID_CFUNC_RC "invalid C function rc" +#define DUK_STR_INVALID_INSTANCEOF_RVAL "invalid instanceof rval" +#define DUK_STR_INVALID_INSTANCEOF_RVAL_NOPROTO "instanceof rval has no .prototype" + +/* JSON */ +#define DUK_STR_FMT_PTR "%p" +#define DUK_STR_FMT_INVALID_JSON "invalid json (at offset %ld)" +#define DUK_STR_JSONDEC_RECLIMIT "json decode recursion limit" +#define DUK_STR_JSONENC_RECLIMIT "json encode recursion limit" +#define DUK_STR_CYCLIC_INPUT "cyclic input" + +/* Object property access */ +#define DUK_STR_INVALID_BASE "invalid base value" +#define DUK_STR_STRICT_CALLER_READ "cannot read strict 'caller'" +#define DUK_STR_PROXY_REJECTED "proxy rejected" +#define DUK_STR_INVALID_ARRAY_LENGTH "invalid array length" +#define DUK_STR_SETTER_UNDEFINED "setter undefined" +#define DUK_STR_INVALID_DESCRIPTOR "invalid descriptor" + +/* Proxy */ +#define DUK_STR_PROXY_REVOKED "proxy revoked" +#define DUK_STR_INVALID_TRAP_RESULT "invalid trap result" + +/* Variables */ + +/* Lexer */ +#define DUK_STR_INVALID_ESCAPE "invalid escape" +#define DUK_STR_UNTERMINATED_STRING "unterminated string" +#define DUK_STR_UNTERMINATED_COMMENT "unterminated comment" +#define DUK_STR_UNTERMINATED_REGEXP "unterminated regexp" +#define DUK_STR_TOKEN_LIMIT "token limit" +#define DUK_STR_REGEXP_SUPPORT_DISABLED "regexp support disabled" +#define DUK_STR_INVALID_NUMBER_LITERAL "invalid number literal" +#define DUK_STR_INVALID_TOKEN "invalid token" + +/* Compiler */ +#define DUK_STR_PARSE_ERROR "parse error" +#define DUK_STR_DUPLICATE_LABEL "duplicate label" +#define DUK_STR_INVALID_LABEL "invalid label" +#define DUK_STR_INVALID_ARRAY_LITERAL "invalid array literal" +#define DUK_STR_INVALID_OBJECT_LITERAL "invalid object literal" +#define DUK_STR_INVALID_VAR_DECLARATION "invalid variable declaration" +#define DUK_STR_CANNOT_DELETE_IDENTIFIER "cannot delete identifier" +#define DUK_STR_INVALID_EXPRESSION "invalid expression" +#define DUK_STR_INVALID_LVALUE "invalid lvalue" +#define DUK_STR_INVALID_NEWTARGET "invalid new.target" +#define DUK_STR_EXPECTED_IDENTIFIER "expected identifier" +#define DUK_STR_EMPTY_EXPR_NOT_ALLOWED "empty expression not allowed" +#define DUK_STR_INVALID_FOR "invalid for statement" +#define DUK_STR_INVALID_SWITCH "invalid switch statement" +#define DUK_STR_INVALID_BREAK_CONT_LABEL "invalid break/continue label" +#define DUK_STR_INVALID_RETURN "invalid return" +#define DUK_STR_INVALID_TRY "invalid try" +#define DUK_STR_INVALID_THROW "invalid throw" +#define DUK_STR_WITH_IN_STRICT_MODE "with in strict mode" +#define DUK_STR_FUNC_STMT_NOT_ALLOWED "function statement not allowed" +#define DUK_STR_UNTERMINATED_STMT "unterminated statement" +#define DUK_STR_INVALID_ARG_NAME "invalid argument name" +#define DUK_STR_INVALID_FUNC_NAME "invalid function name" +#define DUK_STR_INVALID_GETSET_NAME "invalid getter/setter name" +#define DUK_STR_FUNC_NAME_REQUIRED "function name required" + +/* RegExp */ +#define DUK_STR_INVALID_QUANTIFIER "invalid regexp quantifier" +#define DUK_STR_INVALID_QUANTIFIER_NO_ATOM "quantifier without preceding atom" +#define DUK_STR_INVALID_QUANTIFIER_VALUES "quantifier values invalid (qmin > qmax)" +#define DUK_STR_QUANTIFIER_TOO_MANY_COPIES "quantifier requires too many atom copies" +#define DUK_STR_UNEXPECTED_CLOSING_PAREN "unexpected closing parenthesis" +#define DUK_STR_UNEXPECTED_END_OF_PATTERN "unexpected end of pattern" +#define DUK_STR_UNEXPECTED_REGEXP_TOKEN "unexpected token in regexp" +#define DUK_STR_INVALID_REGEXP_FLAGS "invalid regexp flags" +#define DUK_STR_INVALID_REGEXP_ESCAPE "invalid regexp escape" +#define DUK_STR_INVALID_BACKREFS "invalid backreference(s)" +#define DUK_STR_INVALID_REGEXP_CHARACTER "invalid regexp character" +#define DUK_STR_INVALID_REGEXP_GROUP "invalid regexp group" +#define DUK_STR_UNTERMINATED_CHARCLASS "unterminated character class" +#define DUK_STR_INVALID_RANGE "invalid range" + +/* Limits */ +#define DUK_STR_VALSTACK_LIMIT "valstack limit" +#define DUK_STR_CALLSTACK_LIMIT "callstack limit" +#define DUK_STR_PROTOTYPE_CHAIN_LIMIT "prototype chain limit" +#define DUK_STR_BOUND_CHAIN_LIMIT "function call bound chain limit" +#define DUK_STR_NATIVE_STACK_LIMIT "C stack depth limit" +#define DUK_STR_COMPILER_RECURSION_LIMIT "compiler recursion limit" +#define DUK_STR_BYTECODE_LIMIT "bytecode limit" +#define DUK_STR_REG_LIMIT "register limit" +#define DUK_STR_TEMP_LIMIT "temp limit" +#define DUK_STR_CONST_LIMIT "const limit" +#define DUK_STR_FUNC_LIMIT "function limit" +#define DUK_STR_REGEXP_COMPILER_RECURSION_LIMIT "regexp compiler recursion limit" +#define DUK_STR_REGEXP_EXECUTOR_RECURSION_LIMIT "regexp executor recursion limit" +#define DUK_STR_REGEXP_EXECUTOR_STEP_LIMIT "regexp step limit" + +#endif /* DUK_ERRMSG_H_INCLUDED */ diff --git a/third_party/duktape/duk_tval.c b/third_party/duktape/duk_tval.c new file mode 100644 index 00000000..b5dbdca4 --- /dev/null +++ b/third_party/duktape/duk_tval.c @@ -0,0 +1,152 @@ +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_FASTINT) + +/* + * Manually optimized double-to-fastint downgrade check. + * + * This check has a large impact on performance, especially for fastint + * slow paths, so must be changed carefully. The code should probably be + * optimized for the case where the result does not fit into a fastint, + * to minimize the penalty for "slow path code" dealing with fractions etc. + * + * At least on one tested soft float ARM platform double-to-int64 coercion + * is very slow (and sometimes produces incorrect results, see self tests). + * This algorithm combines a fastint compatibility check and extracting the + * integer value from an IEEE double for setting the tagged fastint. For + * other platforms a more naive approach might be better. + * + * See doc/fastint.rst for details. + */ + +DUK_INTERNAL DUK_ALWAYS_INLINE void duk_tval_set_number_chkfast_fast(duk_tval *tv, duk_double_t x) { + duk_double_union du; + duk_int64_t i; + duk_small_int_t expt; + duk_small_int_t shift; + + /* XXX: optimize for packed duk_tval directly? */ + + du.d = x; + i = (duk_int64_t) DUK_DBLUNION_GET_INT64(&du); + expt = (duk_small_int_t) ((i >> 52) & 0x07ff); + shift = expt - 1023; + + if (shift >= 0 && shift <= 46) { /* exponents 1023 to 1069 */ + duk_int64_t t; + + if (((DUK_I64_CONSTANT(0x000fffffffffffff) >> shift) & i) == 0) { + t = i | DUK_I64_CONSTANT(0x0010000000000000); /* implicit leading one */ + t = t & DUK_I64_CONSTANT(0x001fffffffffffff); + t = t >> (52 - shift); + if (i < 0) { + t = -t; + } + DUK_TVAL_SET_FASTINT(tv, t); + return; + } + } else if (shift == -1023) { /* exponent 0 */ + if (i >= 0 && (i & DUK_I64_CONSTANT(0x000fffffffffffff)) == 0) { + /* Note: reject negative zero. */ + DUK_TVAL_SET_FASTINT(tv, (duk_int64_t) 0); + return; + } + } else if (shift == 47) { /* exponent 1070 */ + if (i < 0 && (i & DUK_I64_CONSTANT(0x000fffffffffffff)) == 0) { + DUK_TVAL_SET_FASTINT(tv, (duk_int64_t) DUK_FASTINT_MIN); + return; + } + } + + DUK_TVAL_SET_DOUBLE(tv, x); + return; +} + +DUK_INTERNAL DUK_NOINLINE void duk_tval_set_number_chkfast_slow(duk_tval *tv, duk_double_t x) { + duk_tval_set_number_chkfast_fast(tv, x); +} + +/* + * Manually optimized number-to-double conversion + */ + +#if defined(DUK_USE_FASTINT) && defined(DUK_USE_PACKED_TVAL) +DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_packed(duk_tval *tv) { + duk_double_union du; + duk_uint64_t t; + + t = (duk_uint64_t) DUK_DBLUNION_GET_UINT64(tv); + if ((t >> 48) != DUK_TAG_FASTINT) { + return tv->d; + } else if (t & DUK_U64_CONSTANT(0x0000800000000000)) { + t = (duk_uint64_t) (-((duk_int64_t) t)); /* avoid unary minus on unsigned */ + t = t & DUK_U64_CONSTANT(0x0000ffffffffffff); /* negative */ + t |= DUK_U64_CONSTANT(0xc330000000000000); + DUK_DBLUNION_SET_UINT64(&du, t); + return du.d + 4503599627370496.0; /* 1 << 52 */ + } else if (t != 0) { + t &= DUK_U64_CONSTANT(0x0000ffffffffffff); /* positive */ + t |= DUK_U64_CONSTANT(0x4330000000000000); + DUK_DBLUNION_SET_UINT64(&du, t); + return du.d - 4503599627370496.0; /* 1 << 52 */ + } else { + return 0.0; /* zero */ + } +} +#endif /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */ + +#if 0 /* unused */ +#if defined(DUK_USE_FASTINT) && !defined(DUK_USE_PACKED_TVAL) +DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked(duk_tval *tv) { + duk_double_union du; + duk_uint64_t t; + + DUK_ASSERT(tv->t == DUK_TAG_NUMBER || tv->t == DUK_TAG_FASTINT); + + if (tv->t == DUK_TAG_FASTINT) { + if (tv->v.fi >= 0) { + t = DUK_U64_CONSTANT(0x4330000000000000) | (duk_uint64_t) tv->v.fi; + DUK_DBLUNION_SET_UINT64(&du, t); + return du.d - 4503599627370496.0; /* 1 << 52 */ + } else { + t = DUK_U64_CONSTANT(0xc330000000000000) | (duk_uint64_t) (-tv->v.fi); + DUK_DBLUNION_SET_UINT64(&du, t); + return du.d + 4503599627370496.0; /* 1 << 52 */ + } + } else { + return tv->v.d; + } +} +#endif /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */ +#endif /* 0 */ + +#if defined(DUK_USE_FASTINT) && !defined(DUK_USE_PACKED_TVAL) +DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked_fastint(duk_tval *tv) { + duk_double_union du; + duk_uint64_t t; + + DUK_ASSERT(tv->t == DUK_TAG_FASTINT); + + if (tv->v.fi >= 0) { + t = DUK_U64_CONSTANT(0x4330000000000000) | (duk_uint64_t) tv->v.fi; + DUK_DBLUNION_SET_UINT64(&du, t); + return du.d - 4503599627370496.0; /* 1 << 52 */ + } else { + t = DUK_U64_CONSTANT(0xc330000000000000) | (duk_uint64_t) (-tv->v.fi); + DUK_DBLUNION_SET_UINT64(&du, t); + return du.d + 4503599627370496.0; /* 1 << 52 */ + } +} +#endif /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */ + +#endif /* DUK_USE_FASTINT */ + +/* + * Assertion helpers. + */ + +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL void duk_tval_assert_valid(duk_tval *tv) { + DUK_ASSERT(tv != NULL); +} +#endif diff --git a/third_party/duktape/duk_tval.h b/third_party/duktape/duk_tval.h new file mode 100644 index 00000000..8e33ab6a --- /dev/null +++ b/third_party/duktape/duk_tval.h @@ -0,0 +1,639 @@ +/* + * Tagged type definition (duk_tval) and accessor macros. + * + * Access all fields through the accessor macros, as the representation + * is quite tricky. + * + * There are two packed type alternatives: an 8-byte representation + * based on an IEEE double (preferred for compactness), and a 12-byte + * representation (portability). The latter is needed also in e.g. + * 64-bit environments (it usually pads to 16 bytes per value). + * + * Selecting the tagged type format involves many trade-offs (memory + * use, size and performance of generated code, portability, etc). + * + * NB: because macro arguments are often expressions, macros should + * avoid evaluating their argument more than once. + */ + +#if !defined(DUK_TVAL_H_INCLUDED) +#define DUK_TVAL_H_INCLUDED + +/* sanity */ +#if !defined(DUK_USE_DOUBLE_LE) && !defined(DUK_USE_DOUBLE_ME) && !defined(DUK_USE_DOUBLE_BE) +#error unsupported: cannot determine byte order variant +#endif + +#if defined(DUK_USE_PACKED_TVAL) +/* ======================================================================== */ + +/* + * Packed 8-byte representation + */ + +/* use duk_double_union as duk_tval directly */ +typedef union duk_double_union duk_tval; +typedef struct { + duk_uint16_t a; + duk_uint16_t b; + duk_uint16_t c; + duk_uint16_t d; +} duk_tval_unused; + +/* tags */ +#define DUK_TAG_NORMALIZED_NAN 0x7ff8UL /* the NaN variant we use */ +/* avoid tag 0xfff0, no risk of confusion with negative infinity */ +#define DUK_TAG_MIN 0xfff1UL +#if defined(DUK_USE_FASTINT) +#define DUK_TAG_FASTINT 0xfff1UL /* embed: integer value */ +#endif +#define DUK_TAG_UNUSED 0xfff2UL /* marker; not actual tagged value */ +#define DUK_TAG_UNDEFINED 0xfff3UL /* embed: nothing */ +#define DUK_TAG_NULL 0xfff4UL /* embed: nothing */ +#define DUK_TAG_BOOLEAN 0xfff5UL /* embed: 0 or 1 (false or true) */ +/* DUK_TAG_NUMBER would logically go here, but it has multiple 'tags' */ +#define DUK_TAG_POINTER 0xfff6UL /* embed: void ptr */ +#define DUK_TAG_LIGHTFUNC 0xfff7UL /* embed: func ptr */ +#define DUK_TAG_STRING 0xfff8UL /* embed: duk_hstring ptr */ +#define DUK_TAG_OBJECT 0xfff9UL /* embed: duk_hobject ptr */ +#define DUK_TAG_BUFFER 0xfffaUL /* embed: duk_hbuffer ptr */ +#define DUK_TAG_MAX 0xfffaUL + +/* for convenience */ +#define DUK_XTAG_BOOLEAN_FALSE 0xfff50000UL +#define DUK_XTAG_BOOLEAN_TRUE 0xfff50001UL + +#define DUK_TVAL_IS_VALID_TAG(tv) \ + (DUK_TVAL_GET_TAG((tv)) - DUK_TAG_MIN <= DUK_TAG_MAX - DUK_TAG_MIN) + +/* DUK_TVAL_UNUSED initializer for duk_tval_unused, works for any endianness. */ +#define DUK_TVAL_UNUSED_INITIALIZER() \ + { DUK_TAG_UNUSED, DUK_TAG_UNUSED, DUK_TAG_UNUSED, DUK_TAG_UNUSED } + +/* two casts to avoid gcc warning: "warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]" */ +#if defined(DUK_USE_64BIT_OPS) +#if defined(DUK_USE_DOUBLE_ME) +#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag) do { \ + (tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) (tag)) << 16) | (((duk_uint64_t) (duk_uint32_t) (h)) << 32); \ + } while (0) +#else +#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag) do { \ + (tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) (tag)) << 48) | ((duk_uint64_t) (duk_uint32_t) (h)); \ + } while (0) +#endif +#else /* DUK_USE_64BIT_OPS */ +#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) (tag)) << 16; \ + duk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (h); \ + } while (0) +#endif /* DUK_USE_64BIT_OPS */ + +#if defined(DUK_USE_64BIT_OPS) +/* Double casting for pointer to avoid gcc warning (cast from pointer to integer of different size) */ +#if defined(DUK_USE_DOUBLE_ME) +#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags) do { \ + (tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_LIGHTFUNC) << 16) | \ + ((duk_uint64_t) (flags)) | \ + (((duk_uint64_t) (duk_uint32_t) (fp)) << 32); \ + } while (0) +#else +#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags) do { \ + (tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_LIGHTFUNC) << 48) | \ + (((duk_uint64_t) (flags)) << 32) | \ + ((duk_uint64_t) (duk_uint32_t) (fp)); \ + } while (0) +#endif +#else /* DUK_USE_64BIT_OPS */ +#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->ui[DUK_DBL_IDX_UI0] = (((duk_uint32_t) DUK_TAG_LIGHTFUNC) << 16) | ((duk_uint32_t) (flags)); \ + duk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (fp); \ + } while (0) +#endif /* DUK_USE_64BIT_OPS */ + +#if defined(DUK_USE_FASTINT) +/* Note: masking is done for 'i' to deal with negative numbers correctly */ +#if defined(DUK_USE_DOUBLE_ME) +#define DUK__TVAL_SET_I48(tv,i) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) DUK_TAG_FASTINT) << 16 | (((duk_uint32_t) ((i) >> 32)) & 0x0000ffffUL); \ + duk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (i); \ + } while (0) +#define DUK__TVAL_SET_U32(tv,i) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) DUK_TAG_FASTINT) << 16; \ + duk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (i); \ + } while (0) +#else +#define DUK__TVAL_SET_I48(tv,i) do { \ + (tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_FASTINT) << 48) | (((duk_uint64_t) (i)) & DUK_U64_CONSTANT(0x0000ffffffffffff)); \ + } while (0) +#define DUK__TVAL_SET_U32(tv,i) do { \ + (tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_FASTINT) << 48) | (duk_uint64_t) (i); \ + } while (0) +#endif + +/* This needs to go through a cast because sign extension is needed. */ +#define DUK__TVAL_SET_I32(tv,i) do { \ + duk_int64_t duk__tmp = (duk_int64_t) (i); \ + DUK_TVAL_SET_I48((tv), duk__tmp); \ + } while (0) + +/* XXX: Clumsy sign extend and masking of 16 topmost bits. */ +#if defined(DUK_USE_DOUBLE_ME) +#define DUK__TVAL_GET_FASTINT(tv) (((duk_int64_t) ((((duk_uint64_t) (tv)->ui[DUK_DBL_IDX_UI0]) << 32) | ((duk_uint64_t) (tv)->ui[DUK_DBL_IDX_UI1]))) << 16 >> 16) +#else +#define DUK__TVAL_GET_FASTINT(tv) ((((duk_int64_t) (tv)->ull[DUK_DBL_IDX_ULL0]) << 16) >> 16) +#endif +#define DUK__TVAL_GET_FASTINT_U32(tv) ((tv)->ui[DUK_DBL_IDX_UI1]) +#define DUK__TVAL_GET_FASTINT_I32(tv) ((duk_int32_t) (tv)->ui[DUK_DBL_IDX_UI1]) +#endif /* DUK_USE_FASTINT */ + +#define DUK_TVAL_SET_UNDEFINED(tv) do { \ + (tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_UNDEFINED; \ + } while (0) +#define DUK_TVAL_SET_UNUSED(tv) do { \ + (tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_UNUSED; \ + } while (0) +#define DUK_TVAL_SET_NULL(tv) do { \ + (tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_NULL; \ + } while (0) + +#define DUK_TVAL_SET_BOOLEAN(tv,val) DUK_DBLUNION_SET_HIGH32((tv), (((duk_uint32_t) DUK_TAG_BOOLEAN) << 16) | ((duk_uint32_t) (val))) + +#define DUK_TVAL_SET_NAN(tv) DUK_DBLUNION_SET_NAN_FULL((tv)) + +/* Assumes that caller has normalized NaNs, otherwise trouble ahead. */ +#if defined(DUK_USE_FASTINT) +#define DUK_TVAL_SET_DOUBLE(tv,d) do { \ + duk_double_t duk__dblval; \ + duk__dblval = (d); \ + DUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); \ + DUK_DBLUNION_SET_DOUBLE((tv), duk__dblval); \ + } while (0) +#define DUK_TVAL_SET_I48(tv,i) DUK__TVAL_SET_I48((tv), (i)) +#define DUK_TVAL_SET_I32(tv,i) DUK__TVAL_SET_I32((tv), (i)) +#define DUK_TVAL_SET_U32(tv,i) DUK__TVAL_SET_U32((tv), (i)) +#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d) duk_tval_set_number_chkfast_fast((tv), (d)) +#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d) duk_tval_set_number_chkfast_slow((tv), (d)) +#define DUK_TVAL_SET_NUMBER(tv,d) DUK_TVAL_SET_DOUBLE((tv), (d)) +#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv) do { \ + duk_tval *duk__tv; \ + duk_double_t duk__d; \ + duk__tv = (tv); \ + if (DUK_TVAL_IS_DOUBLE(duk__tv)) { \ + duk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \ + DUK_TVAL_SET_NUMBER_CHKFAST_FAST(duk__tv, duk__d); \ + } \ + } while (0) +#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv) do { \ + duk_tval *duk__tv; \ + duk_double_t duk__d; \ + duk__tv = (tv); \ + if (DUK_TVAL_IS_DOUBLE(duk__tv)) { \ + duk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \ + DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(duk__tv, duk__d); \ + } \ + } while (0) +#else /* DUK_USE_FASTINT */ +#define DUK_TVAL_SET_DOUBLE(tv,d) do { \ + duk_double_t duk__dblval; \ + duk__dblval = (d); \ + DUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); \ + DUK_DBLUNION_SET_DOUBLE((tv), duk__dblval); \ + } while (0) +#define DUK_TVAL_SET_I48(tv,i) DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i)) /* XXX: fast int-to-double */ +#define DUK_TVAL_SET_I32(tv,i) DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i)) +#define DUK_TVAL_SET_U32(tv,i) DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i)) +#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d) DUK_TVAL_SET_DOUBLE((tv), (d)) +#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d) DUK_TVAL_SET_DOUBLE((tv), (d)) +#define DUK_TVAL_SET_NUMBER(tv,d) DUK_TVAL_SET_DOUBLE((tv), (d)) +#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv) do { } while (0) +#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv) do { } while (0) +#endif /* DUK_USE_FASTINT */ + +#define DUK_TVAL_SET_FASTINT(tv,i) DUK_TVAL_SET_I48((tv), (i)) /* alias */ + +#define DUK_TVAL_SET_LIGHTFUNC(tv,fp,flags) DUK__TVAL_SET_LIGHTFUNC((tv), (fp), (flags)) +#define DUK_TVAL_SET_STRING(tv,h) DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_STRING) +#define DUK_TVAL_SET_OBJECT(tv,h) DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_OBJECT) +#define DUK_TVAL_SET_BUFFER(tv,h) DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_BUFFER) +#define DUK_TVAL_SET_POINTER(tv,p) DUK__TVAL_SET_TAGGEDPOINTER((tv), (p), DUK_TAG_POINTER) + +#define DUK_TVAL_SET_TVAL(tv,x) do { *(tv) = *(x); } while (0) + +/* getters */ +#define DUK_TVAL_GET_BOOLEAN(tv) ((duk_small_uint_t) (tv)->us[DUK_DBL_IDX_US1]) +#if defined(DUK_USE_FASTINT) +#define DUK_TVAL_GET_DOUBLE(tv) ((tv)->d) +#define DUK_TVAL_GET_FASTINT(tv) DUK__TVAL_GET_FASTINT((tv)) +#define DUK_TVAL_GET_FASTINT_U32(tv) DUK__TVAL_GET_FASTINT_U32((tv)) +#define DUK_TVAL_GET_FASTINT_I32(tv) DUK__TVAL_GET_FASTINT_I32((tv)) +#define DUK_TVAL_GET_NUMBER(tv) duk_tval_get_number_packed((tv)) +#else +#define DUK_TVAL_GET_NUMBER(tv) ((tv)->d) +#define DUK_TVAL_GET_DOUBLE(tv) ((tv)->d) +#endif +#define DUK_TVAL_GET_LIGHTFUNC(tv,out_fp,out_flags) do { \ + (out_flags) = (tv)->ui[DUK_DBL_IDX_UI0] & 0xffffUL; \ + (out_fp) = (duk_c_function) (tv)->ui[DUK_DBL_IDX_UI1]; \ + } while (0) +#define DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv) ((duk_c_function) ((tv)->ui[DUK_DBL_IDX_UI1])) +#define DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv) (((duk_small_uint_t) (tv)->ui[DUK_DBL_IDX_UI0]) & 0xffffUL) +#define DUK_TVAL_GET_STRING(tv) ((duk_hstring *) (tv)->vp[DUK_DBL_IDX_VP1]) +#define DUK_TVAL_GET_OBJECT(tv) ((duk_hobject *) (tv)->vp[DUK_DBL_IDX_VP1]) +#define DUK_TVAL_GET_BUFFER(tv) ((duk_hbuffer *) (tv)->vp[DUK_DBL_IDX_VP1]) +#define DUK_TVAL_GET_POINTER(tv) ((void *) (tv)->vp[DUK_DBL_IDX_VP1]) +#define DUK_TVAL_GET_HEAPHDR(tv) ((duk_heaphdr *) (tv)->vp[DUK_DBL_IDX_VP1]) + +/* decoding */ +#define DUK_TVAL_GET_TAG(tv) ((duk_small_uint_t) (tv)->us[DUK_DBL_IDX_US0]) + +#define DUK_TVAL_IS_UNDEFINED(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_UNDEFINED) +#define DUK_TVAL_IS_UNUSED(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_UNUSED) +#define DUK_TVAL_IS_NULL(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_NULL) +#define DUK_TVAL_IS_BOOLEAN(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_BOOLEAN) +#define DUK_TVAL_IS_BOOLEAN_TRUE(tv) ((tv)->ui[DUK_DBL_IDX_UI0] == DUK_XTAG_BOOLEAN_TRUE) +#define DUK_TVAL_IS_BOOLEAN_FALSE(tv) ((tv)->ui[DUK_DBL_IDX_UI0] == DUK_XTAG_BOOLEAN_FALSE) +#define DUK_TVAL_IS_LIGHTFUNC(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_LIGHTFUNC) +#define DUK_TVAL_IS_STRING(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_STRING) +#define DUK_TVAL_IS_OBJECT(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_OBJECT) +#define DUK_TVAL_IS_BUFFER(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_BUFFER) +#define DUK_TVAL_IS_POINTER(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_POINTER) +#if defined(DUK_USE_FASTINT) +/* 0xfff0 is -Infinity */ +#define DUK_TVAL_IS_DOUBLE(tv) (DUK_TVAL_GET_TAG((tv)) <= 0xfff0UL) +#define DUK_TVAL_IS_FASTINT(tv) (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_FASTINT) +#define DUK_TVAL_IS_NUMBER(tv) (DUK_TVAL_GET_TAG((tv)) <= 0xfff1UL) +#else +#define DUK_TVAL_IS_NUMBER(tv) (DUK_TVAL_GET_TAG((tv)) <= 0xfff0UL) +#define DUK_TVAL_IS_DOUBLE(tv) DUK_TVAL_IS_NUMBER((tv)) +#endif + +/* This is performance critical because it appears in every DECREF. */ +#define DUK_TVAL_IS_HEAP_ALLOCATED(tv) (DUK_TVAL_GET_TAG((tv)) >= DUK_TAG_STRING) + +#if defined(DUK_USE_FASTINT) +DUK_INTERNAL_DECL duk_double_t duk_tval_get_number_packed(duk_tval *tv); +#endif + +#else /* DUK_USE_PACKED_TVAL */ +/* ======================================================================== */ + +/* + * Portable 12-byte representation + */ + +/* Note: not initializing all bytes is normally not an issue: Duktape won't + * read or use the uninitialized bytes so valgrind won't issue warnings. + * In some special cases a harmless valgrind warning may be issued though. + * For example, the DumpHeap debugger command writes out a compiled function's + * 'data' area as is, including any uninitialized bytes, which causes a + * valgrind warning. + */ + +typedef struct duk_tval_struct duk_tval; + +struct duk_tval_struct { + duk_small_uint_t t; + duk_small_uint_t v_extra; + union { + duk_double_t d; + duk_small_int_t i; +#if defined(DUK_USE_FASTINT) + duk_int64_t fi; /* if present, forces 16-byte duk_tval */ +#endif + void *voidptr; + duk_hstring *hstring; + duk_hobject *hobject; + duk_hcompfunc *hcompfunc; + duk_hnatfunc *hnatfunc; + duk_hthread *hthread; + duk_hbuffer *hbuffer; + duk_heaphdr *heaphdr; + duk_c_function lightfunc; + } v; +}; + +typedef struct { + duk_small_uint_t t; + duk_small_uint_t v_extra; + /* The rest of the fields don't matter except for debug dumps and such + * for which a partial initializer may trigger out-ot-bounds memory + * reads. Include a double field which is usually as large or larger + * than pointers (not always however). + */ + duk_double_t d; +} duk_tval_unused; + +#define DUK_TVAL_UNUSED_INITIALIZER() \ + { DUK_TAG_UNUSED, 0, 0.0 } + +#define DUK_TAG_MIN 0 +#define DUK_TAG_NUMBER 0 /* DUK_TAG_NUMBER only defined for non-packed duk_tval */ +#if defined(DUK_USE_FASTINT) +#define DUK_TAG_FASTINT 1 +#endif +#define DUK_TAG_UNDEFINED 2 +#define DUK_TAG_NULL 3 +#define DUK_TAG_BOOLEAN 4 +#define DUK_TAG_POINTER 5 +#define DUK_TAG_LIGHTFUNC 6 +#define DUK_TAG_UNUSED 7 /* marker; not actual tagged type */ +#define DUK_TAG_STRING 8 /* first heap allocated, match bit boundary */ +#define DUK_TAG_OBJECT 9 +#define DUK_TAG_BUFFER 10 +#define DUK_TAG_MAX 10 + +#define DUK_TVAL_IS_VALID_TAG(tv) \ + (DUK_TVAL_GET_TAG((tv)) - DUK_TAG_MIN <= DUK_TAG_MAX - DUK_TAG_MIN) + +/* DUK_TAG_NUMBER is intentionally first, as it is the default clause in code + * to support the 8-byte representation. Further, it is a non-heap-allocated + * type so it should come before DUK_TAG_STRING. Finally, it should not break + * the tag value ranges covered by case-clauses in a switch-case. + */ + +/* setters */ +#define DUK_TVAL_SET_UNDEFINED(tv) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_UNDEFINED; \ + } while (0) + +#define DUK_TVAL_SET_UNUSED(tv) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_UNUSED; \ + } while (0) + +#define DUK_TVAL_SET_NULL(tv) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_NULL; \ + } while (0) + +#define DUK_TVAL_SET_BOOLEAN(tv,val) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_BOOLEAN; \ + duk__tv->v.i = (duk_small_int_t) (val); \ + } while (0) + +#if defined(DUK_USE_FASTINT) +#define DUK_TVAL_SET_DOUBLE(tv,val) do { \ + duk_tval *duk__tv; \ + duk_double_t duk__dblval; \ + duk__dblval = (val); \ + DUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); /* nop for unpacked duk_tval */ \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_NUMBER; \ + duk__tv->v.d = duk__dblval; \ + } while (0) +#define DUK_TVAL_SET_I48(tv,val) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_FASTINT; \ + duk__tv->v.fi = (val); \ + } while (0) +#define DUK_TVAL_SET_U32(tv,val) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_FASTINT; \ + duk__tv->v.fi = (duk_int64_t) (val); \ + } while (0) +#define DUK_TVAL_SET_I32(tv,val) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_FASTINT; \ + duk__tv->v.fi = (duk_int64_t) (val); \ + } while (0) +#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d) \ + duk_tval_set_number_chkfast_fast((tv), (d)) +#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d) \ + duk_tval_set_number_chkfast_slow((tv), (d)) +#define DUK_TVAL_SET_NUMBER(tv,val) \ + DUK_TVAL_SET_DOUBLE((tv), (val)) +#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv) do { \ + duk_tval *duk__tv; \ + duk_double_t duk__d; \ + duk__tv = (tv); \ + if (DUK_TVAL_IS_DOUBLE(duk__tv)) { \ + duk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \ + DUK_TVAL_SET_NUMBER_CHKFAST_FAST(duk__tv, duk__d); \ + } \ + } while (0) +#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv) do { \ + duk_tval *duk__tv; \ + duk_double_t duk__d; \ + duk__tv = (tv); \ + if (DUK_TVAL_IS_DOUBLE(duk__tv)) { \ + duk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \ + DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(duk__tv, duk__d); \ + } \ + } while (0) +#else /* DUK_USE_FASTINT */ +#define DUK_TVAL_SET_DOUBLE(tv,d) \ + DUK_TVAL_SET_NUMBER((tv), (d)) +#define DUK_TVAL_SET_I48(tv,val) \ + DUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val)) /* XXX: fast int-to-double */ +#define DUK_TVAL_SET_U32(tv,val) \ + DUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val)) +#define DUK_TVAL_SET_I32(tv,val) \ + DUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val)) +#define DUK_TVAL_SET_NUMBER(tv,val) do { \ + duk_tval *duk__tv; \ + duk_double_t duk__dblval; \ + duk__dblval = (val); \ + DUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); /* nop for unpacked duk_tval */ \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_NUMBER; \ + duk__tv->v.d = duk__dblval; \ + } while (0) +#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d) \ + DUK_TVAL_SET_NUMBER((tv), (d)) +#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d) \ + DUK_TVAL_SET_NUMBER((tv), (d)) +#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv) do { } while (0) +#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv) do { } while (0) +#endif /* DUK_USE_FASTINT */ + +#define DUK_TVAL_SET_FASTINT(tv,i) \ + DUK_TVAL_SET_I48((tv), (i)) /* alias */ + +#define DUK_TVAL_SET_POINTER(tv,hptr) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_POINTER; \ + duk__tv->v.voidptr = (hptr); \ + } while (0) + +#define DUK_TVAL_SET_LIGHTFUNC(tv,fp,flags) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_LIGHTFUNC; \ + duk__tv->v_extra = (flags); \ + duk__tv->v.lightfunc = (duk_c_function) (fp); \ + } while (0) + +#define DUK_TVAL_SET_STRING(tv,hptr) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_STRING; \ + duk__tv->v.hstring = (hptr); \ + } while (0) + +#define DUK_TVAL_SET_OBJECT(tv,hptr) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_OBJECT; \ + duk__tv->v.hobject = (hptr); \ + } while (0) + +#define DUK_TVAL_SET_BUFFER(tv,hptr) do { \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_BUFFER; \ + duk__tv->v.hbuffer = (hptr); \ + } while (0) + +#define DUK_TVAL_SET_NAN(tv) do { \ + /* in non-packed representation we don't care about which NaN is used */ \ + duk_tval *duk__tv; \ + duk__tv = (tv); \ + duk__tv->t = DUK_TAG_NUMBER; \ + duk__tv->v.d = DUK_DOUBLE_NAN; \ + } while (0) + +#define DUK_TVAL_SET_TVAL(tv,x) do { *(tv) = *(x); } while (0) + +/* getters */ +#define DUK_TVAL_GET_BOOLEAN(tv) ((duk_small_uint_t) (tv)->v.i) +#if defined(DUK_USE_FASTINT) +#define DUK_TVAL_GET_DOUBLE(tv) ((tv)->v.d) +#define DUK_TVAL_GET_FASTINT(tv) ((tv)->v.fi) +#define DUK_TVAL_GET_FASTINT_U32(tv) ((duk_uint32_t) ((tv)->v.fi)) +#define DUK_TVAL_GET_FASTINT_I32(tv) ((duk_int32_t) ((tv)->v.fi)) +#if 0 +#define DUK_TVAL_GET_NUMBER(tv) (DUK_TVAL_IS_FASTINT((tv)) ? \ + (duk_double_t) DUK_TVAL_GET_FASTINT((tv)) : \ + DUK_TVAL_GET_DOUBLE((tv))) +#define DUK_TVAL_GET_NUMBER(tv) duk_tval_get_number_unpacked((tv)) +#else +/* This seems reasonable overall. */ +#define DUK_TVAL_GET_NUMBER(tv) (DUK_TVAL_IS_FASTINT((tv)) ? \ + duk_tval_get_number_unpacked_fastint((tv)) : \ + DUK_TVAL_GET_DOUBLE((tv))) +#endif +#else +#define DUK_TVAL_GET_NUMBER(tv) ((tv)->v.d) +#define DUK_TVAL_GET_DOUBLE(tv) ((tv)->v.d) +#endif /* DUK_USE_FASTINT */ +#define DUK_TVAL_GET_POINTER(tv) ((tv)->v.voidptr) +#define DUK_TVAL_GET_LIGHTFUNC(tv,out_fp,out_flags) do { \ + (out_flags) = (duk_uint32_t) (tv)->v_extra; \ + (out_fp) = (tv)->v.lightfunc; \ + } while (0) +#define DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv) ((tv)->v.lightfunc) +#define DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv) ((duk_small_uint_t) ((tv)->v_extra)) +#define DUK_TVAL_GET_STRING(tv) ((tv)->v.hstring) +#define DUK_TVAL_GET_OBJECT(tv) ((tv)->v.hobject) +#define DUK_TVAL_GET_BUFFER(tv) ((tv)->v.hbuffer) +#define DUK_TVAL_GET_HEAPHDR(tv) ((tv)->v.heaphdr) + +/* decoding */ +#define DUK_TVAL_GET_TAG(tv) ((tv)->t) +#define DUK_TVAL_IS_UNDEFINED(tv) ((tv)->t == DUK_TAG_UNDEFINED) +#define DUK_TVAL_IS_UNUSED(tv) ((tv)->t == DUK_TAG_UNUSED) +#define DUK_TVAL_IS_NULL(tv) ((tv)->t == DUK_TAG_NULL) +#define DUK_TVAL_IS_BOOLEAN(tv) ((tv)->t == DUK_TAG_BOOLEAN) +#define DUK_TVAL_IS_BOOLEAN_TRUE(tv) (((tv)->t == DUK_TAG_BOOLEAN) && ((tv)->v.i != 0)) +#define DUK_TVAL_IS_BOOLEAN_FALSE(tv) (((tv)->t == DUK_TAG_BOOLEAN) && ((tv)->v.i == 0)) +#if defined(DUK_USE_FASTINT) +#define DUK_TVAL_IS_DOUBLE(tv) ((tv)->t == DUK_TAG_NUMBER) +#define DUK_TVAL_IS_FASTINT(tv) ((tv)->t == DUK_TAG_FASTINT) +#define DUK_TVAL_IS_NUMBER(tv) ((tv)->t == DUK_TAG_NUMBER || \ + (tv)->t == DUK_TAG_FASTINT) +#else +#define DUK_TVAL_IS_NUMBER(tv) ((tv)->t == DUK_TAG_NUMBER) +#define DUK_TVAL_IS_DOUBLE(tv) DUK_TVAL_IS_NUMBER((tv)) +#endif /* DUK_USE_FASTINT */ +#define DUK_TVAL_IS_POINTER(tv) ((tv)->t == DUK_TAG_POINTER) +#define DUK_TVAL_IS_LIGHTFUNC(tv) ((tv)->t == DUK_TAG_LIGHTFUNC) +#define DUK_TVAL_IS_STRING(tv) ((tv)->t == DUK_TAG_STRING) +#define DUK_TVAL_IS_OBJECT(tv) ((tv)->t == DUK_TAG_OBJECT) +#define DUK_TVAL_IS_BUFFER(tv) ((tv)->t == DUK_TAG_BUFFER) + +/* This is performance critical because it's needed for every DECREF. + * Take advantage of the fact that the first heap allocated tag is 8, + * so that bit 3 is set for all heap allocated tags (and never set for + * non-heap-allocated tags). + */ +#if 0 +#define DUK_TVAL_IS_HEAP_ALLOCATED(tv) ((tv)->t >= DUK_TAG_STRING) +#endif +#define DUK_TVAL_IS_HEAP_ALLOCATED(tv) ((tv)->t & 0x08) + +#if defined(DUK_USE_FASTINT) +#if 0 +DUK_INTERNAL_DECL duk_double_t duk_tval_get_number_unpacked(duk_tval *tv); +#endif +DUK_INTERNAL_DECL duk_double_t duk_tval_get_number_unpacked_fastint(duk_tval *tv); +#endif + +#endif /* DUK_USE_PACKED_TVAL */ + +/* + * Convenience (independent of representation) + */ + +#define DUK_TVAL_SET_BOOLEAN_TRUE(tv) DUK_TVAL_SET_BOOLEAN((tv), 1) +#define DUK_TVAL_SET_BOOLEAN_FALSE(tv) DUK_TVAL_SET_BOOLEAN((tv), 0) + +#define DUK_TVAL_STRING_IS_SYMBOL(tv) \ + DUK_HSTRING_HAS_SYMBOL(DUK_TVAL_GET_STRING((tv))) + +/* Lightfunc flags packing and unpacking. */ +/* Sign extend: 0x0000##00 -> 0x##000000 -> sign extend to 0xssssss##. + * Avoid signed shifts due to portability limitations. + */ +#define DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags) \ + ((duk_int32_t) (duk_int8_t) (((duk_uint16_t) (lf_flags)) >> 8)) +#define DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags) \ + (((lf_flags) >> 4) & 0x0fU) +#define DUK_LFUNC_FLAGS_GET_NARGS(lf_flags) \ + ((lf_flags) & 0x0fU) +#define DUK_LFUNC_FLAGS_PACK(magic,length,nargs) \ + ((((duk_small_uint_t) (magic)) & 0xffU) << 8) | ((length) << 4) | (nargs) + +#define DUK_LFUNC_NARGS_VARARGS 0x0f /* varargs marker */ +#define DUK_LFUNC_NARGS_MIN 0x00 +#define DUK_LFUNC_NARGS_MAX 0x0e /* max, excl. varargs marker */ +#define DUK_LFUNC_LENGTH_MIN 0x00 +#define DUK_LFUNC_LENGTH_MAX 0x0f +#define DUK_LFUNC_MAGIC_MIN (-0x80) +#define DUK_LFUNC_MAGIC_MAX 0x7f + +/* fastint constants etc */ +#if defined(DUK_USE_FASTINT) +#define DUK_FASTINT_MIN (DUK_I64_CONSTANT(-0x800000000000)) +#define DUK_FASTINT_MAX (DUK_I64_CONSTANT(0x7fffffffffff)) +#define DUK_FASTINT_BITS 48 + +DUK_INTERNAL_DECL void duk_tval_set_number_chkfast_fast(duk_tval *tv, duk_double_t x); +DUK_INTERNAL_DECL void duk_tval_set_number_chkfast_slow(duk_tval *tv, duk_double_t x); +#endif + +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL_DECL void duk_tval_assert_valid(duk_tval *tv); +#define DUK_TVAL_ASSERT_VALID(tv) do { duk_tval_assert_valid((tv)); } while (0) +#else +#define DUK_TVAL_ASSERT_VALID(tv) do {} while (0) +#endif + +#endif /* DUK_TVAL_H_INCLUDED */ diff --git a/third_party/duktape/duk_unicode.h b/third_party/duktape/duk_unicode.h new file mode 100644 index 00000000..e29cbf0a --- /dev/null +++ b/third_party/duktape/duk_unicode.h @@ -0,0 +1,290 @@ +/* + * Unicode helpers + */ + +#if !defined(DUK_UNICODE_H_INCLUDED) +#define DUK_UNICODE_H_INCLUDED + +/* + * UTF-8 / XUTF-8 / CESU-8 constants + */ + +#define DUK_UNICODE_MAX_XUTF8_LENGTH 7 /* up to 36 bit codepoints */ +#define DUK_UNICODE_MAX_XUTF8_BMP_LENGTH 3 /* all codepoints up to U+FFFF */ +#define DUK_UNICODE_MAX_CESU8_LENGTH 6 /* all codepoints up to U+10FFFF */ +#define DUK_UNICODE_MAX_CESU8_BMP_LENGTH 3 /* all codepoints up to U+FFFF */ + +/* + * Useful Unicode codepoints + * + * Integer constants must be signed to avoid unexpected coercions + * in comparisons. + */ + +#define DUK_UNICODE_CP_ZWNJ 0x200cL /* zero-width non-joiner */ +#define DUK_UNICODE_CP_ZWJ 0x200dL /* zero-width joiner */ +#define DUK_UNICODE_CP_REPLACEMENT_CHARACTER 0xfffdL /* http://en.wikipedia.org/wiki/Replacement_character#Replacement_character */ + +/* + * ASCII character constants + * + * C character literals like 'x' have a platform specific value and do + * not match ASCII (UTF-8) values on e.g. EBCDIC platforms. So, use + * these (admittedly awkward) constants instead. These constants must + * also have signed values to avoid unexpected coercions in comparisons. + * + * http://en.wikipedia.org/wiki/ASCII + */ + +#define DUK_ASC_NUL 0x00 +#define DUK_ASC_SOH 0x01 +#define DUK_ASC_STX 0x02 +#define DUK_ASC_ETX 0x03 +#define DUK_ASC_EOT 0x04 +#define DUK_ASC_ENQ 0x05 +#define DUK_ASC_ACK 0x06 +#define DUK_ASC_BEL 0x07 +#define DUK_ASC_BS 0x08 +#define DUK_ASC_HT 0x09 +#define DUK_ASC_LF 0x0a +#define DUK_ASC_VT 0x0b +#define DUK_ASC_FF 0x0c +#define DUK_ASC_CR 0x0d +#define DUK_ASC_SO 0x0e +#define DUK_ASC_SI 0x0f +#define DUK_ASC_DLE 0x10 +#define DUK_ASC_DC1 0x11 +#define DUK_ASC_DC2 0x12 +#define DUK_ASC_DC3 0x13 +#define DUK_ASC_DC4 0x14 +#define DUK_ASC_NAK 0x15 +#define DUK_ASC_SYN 0x16 +#define DUK_ASC_ETB 0x17 +#define DUK_ASC_CAN 0x18 +#define DUK_ASC_EM 0x19 +#define DUK_ASC_SUB 0x1a +#define DUK_ASC_ESC 0x1b +#define DUK_ASC_FS 0x1c +#define DUK_ASC_GS 0x1d +#define DUK_ASC_RS 0x1e +#define DUK_ASC_US 0x1f +#define DUK_ASC_SPACE 0x20 +#define DUK_ASC_EXCLAMATION 0x21 +#define DUK_ASC_DOUBLEQUOTE 0x22 +#define DUK_ASC_HASH 0x23 +#define DUK_ASC_DOLLAR 0x24 +#define DUK_ASC_PERCENT 0x25 +#define DUK_ASC_AMP 0x26 +#define DUK_ASC_SINGLEQUOTE 0x27 +#define DUK_ASC_LPAREN 0x28 +#define DUK_ASC_RPAREN 0x29 +#define DUK_ASC_STAR 0x2a +#define DUK_ASC_PLUS 0x2b +#define DUK_ASC_COMMA 0x2c +#define DUK_ASC_MINUS 0x2d +#define DUK_ASC_PERIOD 0x2e +#define DUK_ASC_SLASH 0x2f +#define DUK_ASC_0 0x30 +#define DUK_ASC_1 0x31 +#define DUK_ASC_2 0x32 +#define DUK_ASC_3 0x33 +#define DUK_ASC_4 0x34 +#define DUK_ASC_5 0x35 +#define DUK_ASC_6 0x36 +#define DUK_ASC_7 0x37 +#define DUK_ASC_8 0x38 +#define DUK_ASC_9 0x39 +#define DUK_ASC_COLON 0x3a +#define DUK_ASC_SEMICOLON 0x3b +#define DUK_ASC_LANGLE 0x3c +#define DUK_ASC_EQUALS 0x3d +#define DUK_ASC_RANGLE 0x3e +#define DUK_ASC_QUESTION 0x3f +#define DUK_ASC_ATSIGN 0x40 +#define DUK_ASC_UC_A 0x41 +#define DUK_ASC_UC_B 0x42 +#define DUK_ASC_UC_C 0x43 +#define DUK_ASC_UC_D 0x44 +#define DUK_ASC_UC_E 0x45 +#define DUK_ASC_UC_F 0x46 +#define DUK_ASC_UC_G 0x47 +#define DUK_ASC_UC_H 0x48 +#define DUK_ASC_UC_I 0x49 +#define DUK_ASC_UC_J 0x4a +#define DUK_ASC_UC_K 0x4b +#define DUK_ASC_UC_L 0x4c +#define DUK_ASC_UC_M 0x4d +#define DUK_ASC_UC_N 0x4e +#define DUK_ASC_UC_O 0x4f +#define DUK_ASC_UC_P 0x50 +#define DUK_ASC_UC_Q 0x51 +#define DUK_ASC_UC_R 0x52 +#define DUK_ASC_UC_S 0x53 +#define DUK_ASC_UC_T 0x54 +#define DUK_ASC_UC_U 0x55 +#define DUK_ASC_UC_V 0x56 +#define DUK_ASC_UC_W 0x57 +#define DUK_ASC_UC_X 0x58 +#define DUK_ASC_UC_Y 0x59 +#define DUK_ASC_UC_Z 0x5a +#define DUK_ASC_LBRACKET 0x5b +#define DUK_ASC_BACKSLASH 0x5c +#define DUK_ASC_RBRACKET 0x5d +#define DUK_ASC_CARET 0x5e +#define DUK_ASC_UNDERSCORE 0x5f +#define DUK_ASC_GRAVE 0x60 +#define DUK_ASC_LC_A 0x61 +#define DUK_ASC_LC_B 0x62 +#define DUK_ASC_LC_C 0x63 +#define DUK_ASC_LC_D 0x64 +#define DUK_ASC_LC_E 0x65 +#define DUK_ASC_LC_F 0x66 +#define DUK_ASC_LC_G 0x67 +#define DUK_ASC_LC_H 0x68 +#define DUK_ASC_LC_I 0x69 +#define DUK_ASC_LC_J 0x6a +#define DUK_ASC_LC_K 0x6b +#define DUK_ASC_LC_L 0x6c +#define DUK_ASC_LC_M 0x6d +#define DUK_ASC_LC_N 0x6e +#define DUK_ASC_LC_O 0x6f +#define DUK_ASC_LC_P 0x70 +#define DUK_ASC_LC_Q 0x71 +#define DUK_ASC_LC_R 0x72 +#define DUK_ASC_LC_S 0x73 +#define DUK_ASC_LC_T 0x74 +#define DUK_ASC_LC_U 0x75 +#define DUK_ASC_LC_V 0x76 +#define DUK_ASC_LC_W 0x77 +#define DUK_ASC_LC_X 0x78 +#define DUK_ASC_LC_Y 0x79 +#define DUK_ASC_LC_Z 0x7a +#define DUK_ASC_LCURLY 0x7b +#define DUK_ASC_PIPE 0x7c +#define DUK_ASC_RCURLY 0x7d +#define DUK_ASC_TILDE 0x7e +#define DUK_ASC_DEL 0x7f + +/* + * Miscellaneous + */ + +/* Uppercase A is 0x41, lowercase a is 0x61; OR 0x20 to convert uppercase + * to lowercase. + */ +#define DUK_LOWERCASE_CHAR_ASCII(x) ((x) | 0x20) + +/* + * Unicode tables + */ + +#if defined(DUK_USE_SOURCE_NONBMP) +/* + * Automatically generated by extract_chars.py, do not edit! + */ + +extern const duk_uint8_t duk_unicode_ids_noa[1116]; +#else +/* + * Automatically generated by extract_chars.py, do not edit! + */ + +extern const duk_uint8_t duk_unicode_ids_noabmp[625]; +#endif + +#if defined(DUK_USE_SOURCE_NONBMP) +/* + * Automatically generated by extract_chars.py, do not edit! + */ + +extern const duk_uint8_t duk_unicode_ids_m_let_noa[42]; +#else +/* + * Automatically generated by extract_chars.py, do not edit! + */ + +extern const duk_uint8_t duk_unicode_ids_m_let_noabmp[24]; +#endif + +#if defined(DUK_USE_SOURCE_NONBMP) +/* + * Automatically generated by extract_chars.py, do not edit! + */ + +extern const duk_uint8_t duk_unicode_idp_m_ids_noa[576]; +#else +/* + * Automatically generated by extract_chars.py, do not edit! + */ + +extern const duk_uint8_t duk_unicode_idp_m_ids_noabmp[358]; +#endif + +/* + * Automatically generated by extract_caseconv.py, do not edit! + */ + +extern const duk_uint8_t duk_unicode_caseconv_uc[1411]; +extern const duk_uint8_t duk_unicode_caseconv_lc[706]; + +#if defined(DUK_USE_REGEXP_CANON_WORKAROUND) +/* + * Automatically generated by extract_caseconv.py, do not edit! + */ + +extern const duk_uint16_t duk_unicode_re_canon_lookup[65536]; +#endif + +#if defined(DUK_USE_REGEXP_CANON_BITMAP) +/* + * Automatically generated by extract_caseconv.py, do not edit! + */ + +#define DUK_CANON_BITMAP_BLKSIZE 32 +#define DUK_CANON_BITMAP_BLKSHIFT 5 +#define DUK_CANON_BITMAP_BLKMASK 31 +extern const duk_uint8_t duk_unicode_re_canon_bitmap[256]; +#endif + +/* + * Extern + */ + +/* duk_unicode_support.c */ +#if !defined(DUK_SINGLE_FILE) +DUK_INTERNAL_DECL const duk_uint8_t duk_unicode_xutf8_markers[7]; +DUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_digit[2]; +DUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_white[22]; +DUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_wordchar[8]; +DUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_not_digit[4]; +DUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_not_white[24]; +DUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_not_wordchar[10]; +DUK_INTERNAL_DECL const duk_int8_t duk_is_idchar_tab[128]; +#endif /* !DUK_SINGLE_FILE */ + +/* + * Prototypes + */ + +DUK_INTERNAL_DECL duk_small_int_t duk_unicode_get_xutf8_length(duk_ucodepoint_t cp); +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL_DECL duk_small_int_t duk_unicode_get_cesu8_length(duk_ucodepoint_t cp); +#endif +DUK_INTERNAL_DECL duk_small_int_t duk_unicode_encode_xutf8(duk_ucodepoint_t cp, duk_uint8_t *out); +DUK_INTERNAL_DECL duk_small_int_t duk_unicode_encode_cesu8(duk_ucodepoint_t cp, duk_uint8_t *out); +DUK_INTERNAL_DECL duk_small_int_t duk_unicode_decode_xutf8(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_ucodepoint_t *out_cp); +DUK_INTERNAL_DECL duk_ucodepoint_t duk_unicode_decode_xutf8_checked(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end); +DUK_INTERNAL_DECL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *data, duk_size_t blen); +DUK_INTERNAL_DECL duk_bool_t duk_unicode_is_utf8_compatible(const duk_uint8_t *buf, duk_size_t len); +DUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_whitespace(duk_codepoint_t cp); +DUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_line_terminator(duk_codepoint_t cp); +DUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_identifier_start(duk_codepoint_t cp); +DUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_identifier_part(duk_codepoint_t cp); +DUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_letter(duk_codepoint_t cp); +DUK_INTERNAL_DECL void duk_unicode_case_convert_string(duk_hthread *thr, duk_bool_t uppercase); +#if defined(DUK_USE_REGEXP_SUPPORT) +DUK_INTERNAL_DECL duk_codepoint_t duk_unicode_re_canonicalize_char(duk_hthread *thr, duk_codepoint_t cp); +DUK_INTERNAL_DECL duk_small_int_t duk_unicode_re_is_wordchar(duk_codepoint_t cp); +#endif + +#endif /* DUK_UNICODE_H_INCLUDED */ diff --git a/third_party/duktape/duk_unicode_support.c b/third_party/duktape/duk_unicode_support.c new file mode 100644 index 00000000..0cb24142 --- /dev/null +++ b/third_party/duktape/duk_unicode_support.c @@ -0,0 +1,1265 @@ +/* + * Various Unicode help functions for character classification predicates, + * case conversion, decoding, etc. + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Fast path tables + */ + +#if defined(DUK_USE_IDCHAR_FASTPATH) +DUK_INTERNAL const duk_int8_t duk_is_idchar_tab[128] = { + /* 0: not IdentifierStart or IdentifierPart + * 1: IdentifierStart and IdentifierPart + * -1: IdentifierPart only + */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00...0x0f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10...0x1f */ + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20...0x2f */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, /* 0x30...0x3f */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40...0x4f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50...0x5f */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60...0x6f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 /* 0x70...0x7f */ +}; +#endif + +/* + * XUTF-8 and CESU-8 encoding/decoding + */ + +DUK_INTERNAL duk_small_int_t duk_unicode_get_xutf8_length(duk_ucodepoint_t cp) { + duk_uint_fast32_t x = (duk_uint_fast32_t) cp; + if (x < 0x80UL) { + /* 7 bits */ + return 1; + } else if (x < 0x800UL) { + /* 11 bits */ + return 2; + } else if (x < 0x10000UL) { + /* 16 bits */ + return 3; + } else if (x < 0x200000UL) { + /* 21 bits */ + return 4; + } else if (x < 0x4000000UL) { + /* 26 bits */ + return 5; + } else if (x < (duk_ucodepoint_t) 0x80000000UL) { + /* 31 bits */ + return 6; + } else { + /* 36 bits */ + return 7; + } +} + +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL duk_small_int_t duk_unicode_get_cesu8_length(duk_ucodepoint_t cp) { + duk_uint_fast32_t x = (duk_uint_fast32_t) cp; + if (x < 0x80UL) { + /* 7 bits */ + return 1; + } else if (x < 0x800UL) { + /* 11 bits */ + return 2; + } else if (x < 0x10000UL) { + /* 16 bits */ + return 3; + } else { + /* Encoded as surrogate pair, each encoding to 3 bytes for + * 6 bytes total. Codepoints above U+10FFFF encode as 6 bytes + * too, see duk_unicode_encode_cesu8(). + */ + return 3 + 3; + } +} +#endif /* DUK_USE_ASSERTIONS */ + +DUK_INTERNAL const duk_uint8_t duk_unicode_xutf8_markers[7] = { + 0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe +}; + +/* Encode to extended UTF-8; 'out' must have space for at least + * DUK_UNICODE_MAX_XUTF8_LENGTH bytes. Allows encoding of any + * 32-bit (unsigned) codepoint. + */ +DUK_INTERNAL duk_small_int_t duk_unicode_encode_xutf8(duk_ucodepoint_t cp, duk_uint8_t *out) { + duk_uint_fast32_t x = (duk_uint_fast32_t) cp; + duk_small_int_t len; + duk_uint8_t marker; + duk_small_int_t i; + + len = duk_unicode_get_xutf8_length(cp); + DUK_ASSERT(len > 0); + + marker = duk_unicode_xutf8_markers[len - 1]; /* 64-bit OK because always >= 0 */ + + i = len; + DUK_ASSERT(i > 0); + do { + i--; + if (i > 0) { + out[i] = (duk_uint8_t) (0x80 + (x & 0x3f)); + x >>= 6; + } else { + /* Note: masking of 'x' is not necessary because of + * range check and shifting -> no bits overlapping + * the marker should be set. + */ + out[0] = (duk_uint8_t) (marker + x); + } + } while (i > 0); + + return len; +} + +/* Encode to CESU-8; 'out' must have space for at least + * DUK_UNICODE_MAX_CESU8_LENGTH bytes; codepoints above U+10FFFF + * will encode to garbage but won't overwrite the output buffer. + */ +DUK_INTERNAL duk_small_int_t duk_unicode_encode_cesu8(duk_ucodepoint_t cp, duk_uint8_t *out) { + duk_uint_fast32_t x = (duk_uint_fast32_t) cp; + duk_small_int_t len; + + if (x < 0x80UL) { + out[0] = (duk_uint8_t) x; + len = 1; + } else if (x < 0x800UL) { + out[0] = (duk_uint8_t) (0xc0 + ((x >> 6) & 0x1f)); + out[1] = (duk_uint8_t) (0x80 + (x & 0x3f)); + len = 2; + } else if (x < 0x10000UL) { + /* surrogate pairs get encoded here */ + out[0] = (duk_uint8_t) (0xe0 + ((x >> 12) & 0x0f)); + out[1] = (duk_uint8_t) (0x80 + ((x >> 6) & 0x3f)); + out[2] = (duk_uint8_t) (0x80 + (x & 0x3f)); + len = 3; + } else { + /* + * Unicode codepoints above U+FFFF are encoded as surrogate + * pairs here. This ensures that all CESU-8 codepoints are + * 16-bit values as expected in ECMAScript. The surrogate + * pairs always get a 3-byte encoding (each) in CESU-8. + * See: http://en.wikipedia.org/wiki/Surrogate_pair + * + * 20-bit codepoint, 10 bits (A and B) per surrogate pair: + * + * x = 0b00000000 0000AAAA AAAAAABB BBBBBBBB + * sp1 = 0b110110AA AAAAAAAA (0xd800 + ((x >> 10) & 0x3ff)) + * sp2 = 0b110111BB BBBBBBBB (0xdc00 + (x & 0x3ff)) + * + * Encoded into CESU-8: + * + * sp1 -> 0b11101101 (0xe0 + ((sp1 >> 12) & 0x0f)) + * -> 0b1010AAAA (0x80 + ((sp1 >> 6) & 0x3f)) + * -> 0b10AAAAAA (0x80 + (sp1 & 0x3f)) + * sp2 -> 0b11101101 (0xe0 + ((sp2 >> 12) & 0x0f)) + * -> 0b1011BBBB (0x80 + ((sp2 >> 6) & 0x3f)) + * -> 0b10BBBBBB (0x80 + (sp2 & 0x3f)) + * + * Note that 0x10000 must be subtracted first. The code below + * avoids the sp1, sp2 temporaries which saves around 20 bytes + * of code. + */ + + x -= 0x10000UL; + + out[0] = (duk_uint8_t) (0xed); + out[1] = (duk_uint8_t) (0xa0 + ((x >> 16) & 0x0f)); + out[2] = (duk_uint8_t) (0x80 + ((x >> 10) & 0x3f)); + out[3] = (duk_uint8_t) (0xed); + out[4] = (duk_uint8_t) (0xb0 + ((x >> 6) & 0x0f)); + out[5] = (duk_uint8_t) (0x80 + (x & 0x3f)); + len = 6; + } + + return len; +} + +/* Decode helper. Return zero on error. */ +DUK_INTERNAL duk_small_int_t duk_unicode_decode_xutf8(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_ucodepoint_t *out_cp) { + const duk_uint8_t *p; + duk_uint32_t res; + duk_uint_fast8_t ch; + duk_small_int_t n; + + DUK_UNREF(thr); + + p = *ptr; + if (p < ptr_start || p >= ptr_end) { + goto fail; + } + + /* + * UTF-8 decoder which accepts longer than standard byte sequences. + * This allows full 32-bit code points to be used. + */ + + ch = (duk_uint_fast8_t) (*p++); + if (ch < 0x80) { + /* 0xxx xxxx [7 bits] */ + res = (duk_uint32_t) (ch & 0x7f); + n = 0; + } else if (ch < 0xc0) { + /* 10xx xxxx -> invalid */ + goto fail; + } else if (ch < 0xe0) { + /* 110x xxxx 10xx xxxx [11 bits] */ + res = (duk_uint32_t) (ch & 0x1f); + n = 1; + } else if (ch < 0xf0) { + /* 1110 xxxx 10xx xxxx 10xx xxxx [16 bits] */ + res = (duk_uint32_t) (ch & 0x0f); + n = 2; + } else if (ch < 0xf8) { + /* 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx [21 bits] */ + res = (duk_uint32_t) (ch & 0x07); + n = 3; + } else if (ch < 0xfc) { + /* 1111 10xx 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx [26 bits] */ + res = (duk_uint32_t) (ch & 0x03); + n = 4; + } else if (ch < 0xfe) { + /* 1111 110x 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx [31 bits] */ + res = (duk_uint32_t) (ch & 0x01); + n = 5; + } else if (ch < 0xff) { + /* 1111 1110 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx [36 bits] */ + res = (duk_uint32_t) (0); + n = 6; + } else { + /* 8-byte format could be: + * 1111 1111 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx 10xx xxxx [41 bits] + * + * However, this format would not have a zero bit following the + * leading one bits and would not allow 0xFF to be used as an + * "invalid xutf-8" marker for internal keys. Further, 8-byte + * encodings (up to 41 bit code points) are not currently needed. + */ + goto fail; + } + + DUK_ASSERT(p >= ptr_start); /* verified at beginning */ + if (p + n > ptr_end) { + /* check pointer at end */ + goto fail; + } + + while (n > 0) { + DUK_ASSERT(p >= ptr_start && p < ptr_end); + ch = (duk_uint_fast8_t) (*p++); +#if 0 + if (ch & 0xc0 != 0x80) { + /* not a continuation byte */ + p--; + *ptr = p; + *out_cp = DUK_UNICODE_CP_REPLACEMENT_CHARACTER; + return 1; + } +#endif + res = (res << 6) + (duk_uint32_t) (ch & 0x3f); + n--; + } + + *ptr = p; + *out_cp = res; + return 1; + + fail: + return 0; +} + +/* used by e.g. duk_regexp_executor.c, string built-ins */ +DUK_INTERNAL duk_ucodepoint_t duk_unicode_decode_xutf8_checked(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end) { + duk_ucodepoint_t cp; + + if (duk_unicode_decode_xutf8(thr, ptr, ptr_start, ptr_end, &cp)) { + return cp; + } + DUK_ERROR_INTERNAL(thr); + DUK_WO_NORETURN(return 0;); +} + +/* Compute (extended) utf-8 length without codepoint encoding validation, + * used for string interning. + * + * NOTE: This algorithm is performance critical, more so than string hashing + * in some cases. It is needed when interning a string and needs to scan + * every byte of the string with no skipping. Having an ASCII fast path + * is useful if possible in the algorithm. The current algorithms were + * chosen from several variants, based on x64 gcc -O2 testing. See: + * https://github.com/svaarala/duktape/pull/422 + * + * NOTE: must match tools/dukutil.py:duk_unicode_unvalidated_utf8_length(). + */ + +#if defined(DUK_USE_PREFER_SIZE) +/* Small variant; roughly 150 bytes smaller than the fast variant. */ +DUK_INTERNAL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *data, duk_size_t blen) { + const duk_uint8_t *p; + const duk_uint8_t *p_end; + duk_size_t ncont; + duk_size_t clen; + + p = data; + p_end = data + blen; + ncont = 0; + while (p != p_end) { + duk_uint8_t x; + x = *p++; + if (DUK_UNLIKELY(x >= 0x80 && x <= 0xbf)) { + ncont++; + } + } + + DUK_ASSERT(ncont <= blen); + clen = blen - ncont; + DUK_ASSERT(clen <= blen); + return clen; +} +#else /* DUK_USE_PREFER_SIZE */ +/* This seems like a good overall approach. Fast path for ASCII in 4 byte + * blocks. + */ +DUK_INTERNAL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *data, duk_size_t blen) { + const duk_uint8_t *p; + const duk_uint8_t *p_end; + const duk_uint32_t *p32_end; + const duk_uint32_t *p32; + duk_size_t ncont; + duk_size_t clen; + + ncont = 0; /* number of continuation (non-initial) bytes in [0x80,0xbf] */ + p = data; + p_end = data + blen; + if (blen < 16) { + goto skip_fastpath; + } + + /* Align 'p' to 4; the input data may have arbitrary alignment. + * End of string check not needed because blen >= 16. + */ + while (((duk_size_t) (const void *) p) & 0x03U) { + duk_uint8_t x; + x = *p++; + if (DUK_UNLIKELY(x >= 0x80 && x <= 0xbf)) { + ncont++; + } + } + + /* Full, aligned 4-byte reads. */ + p32_end = (const duk_uint32_t *) (const void *) (p + ((duk_size_t) (p_end - p) & (duk_size_t) (~0x03))); + p32 = (const duk_uint32_t *) (const void *) p; + while (p32 != (const duk_uint32_t *) p32_end) { + duk_uint32_t x; + x = *p32++; + if (DUK_LIKELY((x & 0x80808080UL) == 0)) { + ; /* ASCII fast path */ + } else { + /* Flip highest bit of each byte which changes + * the bit pattern 10xxxxxx into 00xxxxxx which + * allows an easy bit mask test. + */ + x ^= 0x80808080UL; + if (DUK_UNLIKELY(!(x & 0xc0000000UL))) { + ncont++; + } + if (DUK_UNLIKELY(!(x & 0x00c00000UL))) { + ncont++; + } + if (DUK_UNLIKELY(!(x & 0x0000c000UL))) { + ncont++; + } + if (DUK_UNLIKELY(!(x & 0x000000c0UL))) { + ncont++; + } + } + } + p = (const duk_uint8_t *) p32; + /* Fall through to handle the rest. */ + + skip_fastpath: + while (p != p_end) { + duk_uint8_t x; + x = *p++; + if (DUK_UNLIKELY(x >= 0x80 && x <= 0xbf)) { + ncont++; + } + } + + DUK_ASSERT(ncont <= blen); + clen = blen - ncont; + DUK_ASSERT(clen <= blen); + return clen; +} +#endif /* DUK_USE_PREFER_SIZE */ + +/* Check whether a string is UTF-8 compatible or not. */ +DUK_INTERNAL duk_bool_t duk_unicode_is_utf8_compatible(const duk_uint8_t *buf, duk_size_t len) { + duk_size_t i = 0; +#if !defined(DUK_USE_PREFER_SIZE) + duk_size_t len_safe; +#endif + + /* Many practical strings are ASCII only, so use a fast path check + * to check chunks of bytes at once with minimal branch cost. + */ +#if !defined(DUK_USE_PREFER_SIZE) + len_safe = len & ~0x03UL; + for (; i < len_safe; i += 4) { + duk_uint8_t t = buf[i] | buf[i + 1] | buf[i + 2] | buf[i + 3]; + if (DUK_UNLIKELY((t & 0x80U) != 0U)) { + /* At least one byte was outside 0x00-0x7f, break + * out to slow path (and remain there). + * + * XXX: We could also deal with the problem character + * and resume fast path later. + */ + break; + } + } +#endif + + for (; i < len;) { + duk_uint8_t t; + duk_size_t left; + duk_size_t ncont; + duk_uint32_t cp; + duk_uint32_t mincp; + + t = buf[i++]; + if (DUK_LIKELY((t & 0x80U) == 0U)) { + /* Fast path, ASCII. */ + continue; + } + + /* Non-ASCII start byte, slow path. + * + * 10xx xxxx -> continuation byte + * 110x xxxx + 1*CONT -> [0x80, 0x7ff] + * 1110 xxxx + 2*CONT -> [0x800, 0xffff], must reject [0xd800,0xdfff] + * 1111 0xxx + 3*CONT -> [0x10000, 0x10ffff] + */ + left = len - i; + if (t <= 0xdfU) { /* 1101 1111 = 0xdf */ + if (t <= 0xbfU) { /* 1011 1111 = 0xbf */ + return 0; + } + ncont = 1; + mincp = 0x80UL; + cp = t & 0x1fU; + } else if (t <= 0xefU) { /* 1110 1111 = 0xef */ + ncont = 2; + mincp = 0x800UL; + cp = t & 0x0fU; + } else if (t <= 0xf7U) { /* 1111 0111 = 0xf7 */ + ncont = 3; + mincp = 0x10000UL; + cp = t & 0x07U; + } else { + return 0; + } + if (left < ncont) { + return 0; + } + while (ncont > 0U) { + t = buf[i++]; + if ((t & 0xc0U) != 0x80U) { /* 10xx xxxx */ + return 0; + } + cp = (cp << 6) + (t & 0x3fU); + ncont--; + } + if (cp < mincp || cp > 0x10ffffUL || (cp >= 0xd800UL && cp <= 0xdfffUL)) { + return 0; + } + } + + return 1; +} + +/* + * Unicode range matcher + * + * Matches a codepoint against a packed bitstream of character ranges. + * Used for slow path Unicode matching. + */ + +/* Must match tools/extract_chars.py, generate_match_table3(). */ +DUK_LOCAL duk_uint32_t duk__uni_decode_value(duk_bitdecoder_ctx *bd_ctx) { + duk_uint32_t t; + + t = (duk_uint32_t) duk_bd_decode(bd_ctx, 4); + if (t <= 0x0eU) { + return t; + } + t = (duk_uint32_t) duk_bd_decode(bd_ctx, 8); + if (t <= 0xfdU) { + return t + 0x0f; + } + if (t == 0xfeU) { + t = (duk_uint32_t) duk_bd_decode(bd_ctx, 12); + return t + 0x0fU + 0xfeU; + } else { + t = (duk_uint32_t) duk_bd_decode(bd_ctx, 24); + return t + 0x0fU + 0xfeU + 0x1000UL; + } +} + +DUK_LOCAL duk_small_int_t duk__uni_range_match(const duk_uint8_t *unitab, duk_size_t unilen, duk_codepoint_t cp) { + duk_bitdecoder_ctx bd_ctx; + duk_codepoint_t prev_re; + + duk_memzero(&bd_ctx, sizeof(bd_ctx)); + bd_ctx.data = (const duk_uint8_t *) unitab; + bd_ctx.length = (duk_size_t) unilen; + + prev_re = 0; + for (;;) { + duk_codepoint_t r1, r2; + r1 = (duk_codepoint_t) duk__uni_decode_value(&bd_ctx); + if (r1 == 0) { + break; + } + r2 = (duk_codepoint_t) duk__uni_decode_value(&bd_ctx); + + r1 = prev_re + r1; + r2 = r1 + r2; + prev_re = r2; + + /* [r1,r2] is the range */ + + DUK_DDD(DUK_DDDPRINT("duk__uni_range_match: cp=%06lx range=[0x%06lx,0x%06lx]", + (unsigned long) cp, (unsigned long) r1, (unsigned long) r2)); + if (cp >= r1 && cp <= r2) { + return 1; + } + } + + return 0; +} + +/* + * "WhiteSpace" production check. + */ + +DUK_INTERNAL duk_small_int_t duk_unicode_is_whitespace(duk_codepoint_t cp) { + /* + * E5 Section 7.2 specifies six characters specifically as + * white space: + * + * 0009;;Cc;0;S;;;;;N;CHARACTER TABULATION;;;; + * 000B;;Cc;0;S;;;;;N;LINE TABULATION;;;; + * 000C;;Cc;0;WS;;;;;N;FORM FEED (FF);;;; + * 0020;SPACE;Zs;0;WS;;;;;N;;;;; + * 00A0;NO-BREAK SPACE;Zs;0;CS; 0020;;;;N;NON-BREAKING SPACE;;;; + * FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;; + * + * It also specifies any Unicode category 'Zs' characters as white + * space. These can be extracted with the "tools/extract_chars.py" script. + * Current result: + * + * RAW OUTPUT: + * =========== + * 0020;SPACE;Zs;0;WS;;;;;N;;;;; + * 00A0;NO-BREAK SPACE;Zs;0;CS; 0020;;;;N;NON-BREAKING SPACE;;;; + * 1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;; + * 180E;MONGOLIAN VOWEL SEPARATOR;Zs;0;WS;;;;;N;;;;; + * 2000;EN QUAD;Zs;0;WS;2002;;;;N;;;;; + * 2001;EM QUAD;Zs;0;WS;2003;;;;N;;;;; + * 2002;EN SPACE;Zs;0;WS; 0020;;;;N;;;;; + * 2003;EM SPACE;Zs;0;WS; 0020;;;;N;;;;; + * 2004;THREE-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; + * 2005;FOUR-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; + * 2006;SIX-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; + * 2007;FIGURE SPACE;Zs;0;WS; 0020;;;;N;;;;; + * 2008;PUNCTUATION SPACE;Zs;0;WS; 0020;;;;N;;;;; + * 2009;THIN SPACE;Zs;0;WS; 0020;;;;N;;;;; + * 200A;HAIR SPACE;Zs;0;WS; 0020;;;;N;;;;; + * 202F;NARROW NO-BREAK SPACE;Zs;0;CS; 0020;;;;N;;;;; + * 205F;MEDIUM MATHEMATICAL SPACE;Zs;0;WS; 0020;;;;N;;;;; + * 3000;IDEOGRAPHIC SPACE;Zs;0;WS; 0020;;;;N;;;;; + * + * RANGES: + * ======= + * 0x0020 + * 0x00a0 + * 0x1680 + * 0x180e + * 0x2000 ... 0x200a + * 0x202f + * 0x205f + * 0x3000 + * + * A manual decoder (below) is probably most compact for this. + */ + + duk_uint_fast8_t lo; + duk_uint_fast32_t hi; + + /* cp == -1 (EOF) never matches and causes return value 0 */ + + lo = (duk_uint_fast8_t) (cp & 0xff); + hi = (duk_uint_fast32_t) (cp >> 8); /* does not fit into an uchar */ + + if (hi == 0x0000UL) { + if (lo == 0x09U || lo == 0x0bU || lo == 0x0cU || + lo == 0x20U || lo == 0xa0U) { + return 1; + } + } else if (hi == 0x0020UL) { + if (lo <= 0x0aU || lo == 0x2fU || lo == 0x5fU) { + return 1; + } + } else if (cp == 0x1680L || cp == 0x180eL || cp == 0x3000L || + cp == 0xfeffL) { + return 1; + } + + return 0; +} + +/* + * "LineTerminator" production check. + */ + +DUK_INTERNAL duk_small_int_t duk_unicode_is_line_terminator(duk_codepoint_t cp) { + /* + * E5 Section 7.3 + * + * A LineTerminatorSequence essentially merges sequences + * into a single line terminator. This must be handled by the caller. + */ + + if (cp == 0x000aL || cp == 0x000dL || cp == 0x2028L || + cp == 0x2029L) { + return 1; + } + + return 0; +} + +/* + * "IdentifierStart" production check. + */ + +DUK_INTERNAL duk_small_int_t duk_unicode_is_identifier_start(duk_codepoint_t cp) { + /* + * E5 Section 7.6: + * + * IdentifierStart: + * UnicodeLetter + * $ + * _ + * \ UnicodeEscapeSequence + * + * IdentifierStart production has one multi-character production: + * + * \ UnicodeEscapeSequence + * + * The '\' character is -not- matched by this function. Rather, the caller + * should decode the escape and then call this function to check whether the + * decoded character is acceptable (see discussion in E5 Section 7.6). + * + * The "UnicodeLetter" alternative of the production allows letters + * from various Unicode categories. These can be extracted with the + * "tools/extract_chars.py" script. + * + * Because the result has hundreds of Unicode codepoint ranges, matching + * for any values >= 0x80 are done using a very slow range-by-range scan + * and a packed range format. + * + * The ASCII portion (codepoints 0x00 ... 0x7f) is fast-pathed below because + * it matters the most. The ASCII related ranges of IdentifierStart are: + * + * 0x0041 ... 0x005a ['A' ... 'Z'] + * 0x0061 ... 0x007a ['a' ... 'z'] + * 0x0024 ['$'] + * 0x005f ['_'] + */ + + /* ASCII (and EOF) fast path -- quick accept and reject */ + if (cp <= 0x7fL) { +#if defined(DUK_USE_IDCHAR_FASTPATH) + return (cp >= 0) && (duk_is_idchar_tab[cp] > 0); +#else + if ((cp >= 'a' && cp <= 'z') || + (cp >= 'A' && cp <= 'Z') || + cp == '_' || cp == '$') { + return 1; + } + return 0; +#endif + } + + /* Non-ASCII slow path (range-by-range linear comparison), very slow */ + +#if defined(DUK_USE_SOURCE_NONBMP) + if (duk__uni_range_match(duk_unicode_ids_noa, + (duk_size_t) sizeof(duk_unicode_ids_noa), + (duk_codepoint_t) cp)) { + return 1; + } + return 0; +#else + if (cp < 0x10000L) { + if (duk__uni_range_match(duk_unicode_ids_noabmp, + sizeof(duk_unicode_ids_noabmp), + (duk_codepoint_t) cp)) { + return 1; + } + return 0; + } else { + /* without explicit non-BMP support, assume non-BMP characters + * are always accepted as identifier characters. + */ + return 1; + } +#endif +} + +/* + * "IdentifierPart" production check. + */ + +DUK_INTERNAL duk_small_int_t duk_unicode_is_identifier_part(duk_codepoint_t cp) { + /* + * E5 Section 7.6: + * + * IdentifierPart: + * IdentifierStart + * UnicodeCombiningMark + * UnicodeDigit + * UnicodeConnectorPunctuation + * [U+200C] + * [U+200D] + * + * IdentifierPart production has one multi-character production + * as part of its IdentifierStart alternative. The '\' character + * of an escape sequence is not matched here, see discussion in + * duk_unicode_is_identifier_start(). + * + * To match non-ASCII characters (codepoints >= 0x80), a very slow + * linear range-by-range scan is used. The codepoint is first compared + * to the IdentifierStart ranges, and if it doesn't match, then to a + * set consisting of code points in IdentifierPart but not in + * IdentifierStart. This is done to keep the unicode range data small, + * at the expense of speed. + * + * The ASCII fast path consists of: + * + * 0x0030 ... 0x0039 ['0' ... '9', UnicodeDigit] + * 0x0041 ... 0x005a ['A' ... 'Z', IdentifierStart] + * 0x0061 ... 0x007a ['a' ... 'z', IdentifierStart] + * 0x0024 ['$', IdentifierStart] + * 0x005f ['_', IdentifierStart and + * UnicodeConnectorPunctuation] + * + * UnicodeCombiningMark has no code points <= 0x7f. + * + * The matching code reuses the "identifier start" tables, and then + * consults a separate range set for characters in "identifier part" + * but not in "identifier start". These can be extracted with the + * "tools/extract_chars.py" script. + * + * UnicodeCombiningMark -> categories Mn, Mc + * UnicodeDigit -> categories Nd + * UnicodeConnectorPunctuation -> categories Pc + */ + + /* ASCII (and EOF) fast path -- quick accept and reject */ + if (cp <= 0x7fL) { +#if defined(DUK_USE_IDCHAR_FASTPATH) + return (cp >= 0) && (duk_is_idchar_tab[cp] != 0); +#else + if ((cp >= 'a' && cp <= 'z') || + (cp >= 'A' && cp <= 'Z') || + (cp >= '0' && cp <= '9') || + cp == '_' || cp == '$') { + return 1; + } + return 0; +#endif + } + + /* Non-ASCII slow path (range-by-range linear comparison), very slow */ + +#if defined(DUK_USE_SOURCE_NONBMP) + if (duk__uni_range_match(duk_unicode_ids_noa, + sizeof(duk_unicode_ids_noa), + (duk_codepoint_t) cp) || + duk__uni_range_match(duk_unicode_idp_m_ids_noa, + sizeof(duk_unicode_idp_m_ids_noa), + (duk_codepoint_t) cp)) { + return 1; + } + return 0; +#else + if (cp < 0x10000L) { + if (duk__uni_range_match(duk_unicode_ids_noabmp, + sizeof(duk_unicode_ids_noabmp), + (duk_codepoint_t) cp) || + duk__uni_range_match(duk_unicode_idp_m_ids_noabmp, + sizeof(duk_unicode_idp_m_ids_noabmp), + (duk_codepoint_t) cp)) { + return 1; + } + return 0; + } else { + /* without explicit non-BMP support, assume non-BMP characters + * are always accepted as identifier characters. + */ + return 1; + } +#endif +} + +/* + * Unicode letter check. + */ + +DUK_INTERNAL duk_small_int_t duk_unicode_is_letter(duk_codepoint_t cp) { + /* + * Unicode letter is now taken to be the categories: + * + * Lu, Ll, Lt, Lm, Lo + * + * (Not sure if this is exactly correct.) + * + * The ASCII fast path consists of: + * + * 0x0041 ... 0x005a ['A' ... 'Z'] + * 0x0061 ... 0x007a ['a' ... 'z'] + */ + + /* ASCII (and EOF) fast path -- quick accept and reject */ + if (cp <= 0x7fL) { + if ((cp >= 'a' && cp <= 'z') || + (cp >= 'A' && cp <= 'Z')) { + return 1; + } + return 0; + } + + /* Non-ASCII slow path (range-by-range linear comparison), very slow */ + +#if defined(DUK_USE_SOURCE_NONBMP) + if (duk__uni_range_match(duk_unicode_ids_noa, + sizeof(duk_unicode_ids_noa), + (duk_codepoint_t) cp) && + !duk__uni_range_match(duk_unicode_ids_m_let_noa, + sizeof(duk_unicode_ids_m_let_noa), + (duk_codepoint_t) cp)) { + return 1; + } + return 0; +#else + if (cp < 0x10000L) { + if (duk__uni_range_match(duk_unicode_ids_noabmp, + sizeof(duk_unicode_ids_noabmp), + (duk_codepoint_t) cp) && + !duk__uni_range_match(duk_unicode_ids_m_let_noabmp, + sizeof(duk_unicode_ids_m_let_noabmp), + (duk_codepoint_t) cp)) { + return 1; + } + return 0; + } else { + /* without explicit non-BMP support, assume non-BMP characters + * are always accepted as letters. + */ + return 1; + } +#endif +} + +/* + * Complex case conversion helper which decodes a bit-packed conversion + * control stream generated by tools/extract_caseconv.py. The conversion + * is very slow because it runs through the conversion data in a linear + * fashion to save space (which is why ASCII characters have a special + * fast path before arriving here). + * + * The particular bit counts etc have been determined experimentally to + * be small but still sufficient, and must match the Python script + * (tools/extract_caseconv.py). + * + * The return value is the case converted codepoint or -1 if the conversion + * results in multiple characters (this is useful for regexp Canonicalization + * operation). If 'buf' is not NULL, the result codepoint(s) are also + * appended to the hbuffer. + * + * Context and locale specific rules must be checked before consulting + * this function. + */ + +DUK_LOCAL +duk_codepoint_t duk__slow_case_conversion(duk_hthread *thr, + duk_bufwriter_ctx *bw, + duk_codepoint_t cp, + duk_bitdecoder_ctx *bd_ctx) { + duk_small_int_t skip = 0; + duk_small_int_t n; + duk_small_int_t t; + duk_small_int_t count; + duk_codepoint_t tmp_cp; + duk_codepoint_t start_i; + duk_codepoint_t start_o; + + DUK_ASSERT(bd_ctx != NULL); + DUK_UNREF(thr); + + DUK_DDD(DUK_DDDPRINT("slow case conversion for codepoint: %ld", (long) cp)); + + /* range conversion with a "skip" */ + DUK_DDD(DUK_DDDPRINT("checking ranges")); + for (;;) { + skip++; + n = (duk_small_int_t) duk_bd_decode(bd_ctx, 6); + if (n == 0x3f) { + /* end marker */ + break; + } + DUK_DDD(DUK_DDDPRINT("skip=%ld, n=%ld", (long) skip, (long) n)); + + while (n--) { + start_i = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16); + start_o = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16); + count = (duk_small_int_t) duk_bd_decode(bd_ctx, 7); + DUK_DDD(DUK_DDDPRINT("range: start_i=%ld, start_o=%ld, count=%ld, skip=%ld", + (long) start_i, (long) start_o, (long) count, (long) skip)); + + if (cp >= start_i) { + tmp_cp = cp - start_i; /* always >= 0 */ + if (tmp_cp < (duk_codepoint_t) count * (duk_codepoint_t) skip && + (tmp_cp % (duk_codepoint_t) skip) == 0) { + DUK_DDD(DUK_DDDPRINT("range matches input codepoint")); + cp = start_o + tmp_cp; + goto single; + } + } + } + } + + /* 1:1 conversion */ + n = (duk_small_int_t) duk_bd_decode(bd_ctx, 7); + DUK_DDD(DUK_DDDPRINT("checking 1:1 conversions (count %ld)", (long) n)); + while (n--) { + start_i = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16); + start_o = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16); + DUK_DDD(DUK_DDDPRINT("1:1 conversion %ld -> %ld", (long) start_i, (long) start_o)); + if (cp == start_i) { + DUK_DDD(DUK_DDDPRINT("1:1 matches input codepoint")); + cp = start_o; + goto single; + } + } + + /* complex, multicharacter conversion */ + n = (duk_small_int_t) duk_bd_decode(bd_ctx, 7); + DUK_DDD(DUK_DDDPRINT("checking 1:n conversions (count %ld)", (long) n)); + while (n--) { + start_i = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16); + t = (duk_small_int_t) duk_bd_decode(bd_ctx, 2); + DUK_DDD(DUK_DDDPRINT("1:n conversion %ld -> %ld chars", (long) start_i, (long) t)); + if (cp == start_i) { + DUK_DDD(DUK_DDDPRINT("1:n matches input codepoint")); + if (bw != NULL) { + while (t--) { + tmp_cp = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16); + DUK_BW_WRITE_RAW_XUTF8(thr, bw, (duk_ucodepoint_t) tmp_cp); + } + } + return -1; + } else { + while (t--) { + (void) duk_bd_decode(bd_ctx, 16); + } + } + } + + /* default: no change */ + DUK_DDD(DUK_DDDPRINT("no rule matches, output is same as input")); + /* fall through */ + + single: + if (bw != NULL) { + DUK_BW_WRITE_RAW_XUTF8(thr, bw, (duk_ucodepoint_t) cp); + } + return cp; +} + +/* + * Case conversion helper, with context/local sensitivity. + * For proper case conversion, one needs to know the character + * and the preceding and following characters, as well as + * locale/language. + */ + +/* XXX: add 'language' argument when locale/language sensitive rule + * support added. + */ +DUK_LOCAL +duk_codepoint_t duk__case_transform_helper(duk_hthread *thr, + duk_bufwriter_ctx *bw, + duk_codepoint_t cp, + duk_codepoint_t prev, + duk_codepoint_t next, + duk_bool_t uppercase) { + duk_bitdecoder_ctx bd_ctx; + + /* fast path for ASCII */ + if (cp < 0x80L) { + /* XXX: there are language sensitive rules for the ASCII range. + * If/when language/locale support is implemented, they need to + * be implemented here for the fast path. There are no context + * sensitive rules for ASCII range. + */ + + if (uppercase) { + if (cp >= 'a' && cp <= 'z') { + cp = cp - 'a' + 'A'; + } + } else { + if (cp >= 'A' && cp <= 'Z') { + cp = cp - 'A' + 'a'; + } + } + + if (bw != NULL) { + DUK_BW_WRITE_RAW_U8(thr, bw, (duk_uint8_t) cp); + } + return cp; + } + + /* context and locale specific rules which cannot currently be represented + * in the caseconv bitstream: hardcoded rules in C + */ + if (uppercase) { + /* XXX: turkish / azeri */ + } else { + /* + * Final sigma context specific rule. This is a rather tricky + * rule and this handling is probably not 100% correct now. + * The rule is not locale/language specific so it is supported. + */ + + if (cp == 0x03a3L && /* U+03A3 = GREEK CAPITAL LETTER SIGMA */ + duk_unicode_is_letter(prev) && /* prev exists and is not a letter */ + !duk_unicode_is_letter(next)) { /* next does not exist or next is not a letter */ + /* Capital sigma occurred at "end of word", lowercase to + * U+03C2 = GREEK SMALL LETTER FINAL SIGMA. Otherwise + * fall through and let the normal rules lowercase it to + * U+03C3 = GREEK SMALL LETTER SIGMA. + */ + cp = 0x03c2L; + goto singlechar; + } + + /* XXX: lithuanian not implemented */ + /* XXX: lithuanian, explicit dot rules */ + /* XXX: turkish / azeri, lowercase rules */ + } + + /* 1:1 or special conversions, but not locale/context specific: script generated rules */ + duk_memzero(&bd_ctx, sizeof(bd_ctx)); + if (uppercase) { + bd_ctx.data = (const duk_uint8_t *) duk_unicode_caseconv_uc; + bd_ctx.length = (duk_size_t) sizeof(duk_unicode_caseconv_uc); + } else { + bd_ctx.data = (const duk_uint8_t *) duk_unicode_caseconv_lc; + bd_ctx.length = (duk_size_t) sizeof(duk_unicode_caseconv_lc); + } + return duk__slow_case_conversion(thr, bw, cp, &bd_ctx); + + singlechar: + if (bw != NULL) { + DUK_BW_WRITE_RAW_XUTF8(thr, bw, (duk_ucodepoint_t) cp); + } + return cp; + + /* unused now, not needed until Turkish/Azeri */ +#if 0 + nochar: + return -1; +#endif +} + +/* + * Replace valstack top with case converted version. + */ + +DUK_INTERNAL void duk_unicode_case_convert_string(duk_hthread *thr, duk_bool_t uppercase) { + duk_hstring *h_input; + duk_bufwriter_ctx bw_alloc; + duk_bufwriter_ctx *bw; + const duk_uint8_t *p, *p_start, *p_end; + duk_codepoint_t prev, curr, next; + + h_input = duk_require_hstring(thr, -1); /* Accept symbols. */ + DUK_ASSERT(h_input != NULL); + + bw = &bw_alloc; + DUK_BW_INIT_PUSHBUF(thr, bw, DUK_HSTRING_GET_BYTELEN(h_input)); + + /* [ ... input buffer ] */ + + p_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input); + p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input); + p = p_start; + + prev = -1; DUK_UNREF(prev); + curr = -1; + next = -1; + for (;;) { + prev = curr; + curr = next; + next = -1; + if (p < p_end) { + next = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end); + } else { + /* end of input and last char has been processed */ + if (curr < 0) { + break; + } + } + + /* on first round, skip */ + if (curr >= 0) { + /* XXX: could add a fast path to process chunks of input codepoints, + * but relative benefit would be quite small. + */ + + /* Ensure space for maximum multi-character result; estimate is overkill. */ + DUK_BW_ENSURE(thr, bw, 8 * DUK_UNICODE_MAX_XUTF8_LENGTH); + + duk__case_transform_helper(thr, + bw, + (duk_codepoint_t) curr, + prev, + next, + uppercase); + } + } + + DUK_BW_COMPACT(thr, bw); + (void) duk_buffer_to_string(thr, -1); /* Safe, output is encoded. */ + /* invalidates h_buf pointer */ + duk_remove_m2(thr); +} + +#if defined(DUK_USE_REGEXP_SUPPORT) + +/* + * Canonicalize() abstract operation needed for canonicalization of individual + * codepoints during regexp compilation and execution, see E5 Section 15.10.2.8. + * Note that codepoints are canonicalized one character at a time, so no context + * specific rules can apply. Locale specific rules can apply, though. + */ + +DUK_INTERNAL duk_codepoint_t duk_unicode_re_canonicalize_char(duk_hthread *thr, duk_codepoint_t cp) { +#if defined(DUK_USE_REGEXP_CANON_WORKAROUND) + /* Fast canonicalization lookup at the cost of 128kB footprint. */ + DUK_ASSERT(cp >= 0); + DUK_UNREF(thr); + if (DUK_LIKELY(cp < 0x10000L)) { + return (duk_codepoint_t) duk_unicode_re_canon_lookup[cp]; + } + return cp; +#else /* DUK_USE_REGEXP_CANON_WORKAROUND */ + duk_codepoint_t y; + + y = duk__case_transform_helper(thr, + NULL, /* NULL is allowed, no output */ + cp, /* curr char */ + -1, /* prev char */ + -1, /* next char */ + 1); /* uppercase */ + + if ((y < 0) || (cp >= 0x80 && y < 0x80)) { + /* multiple codepoint conversion or non-ASCII mapped to ASCII + * --> leave as is. + */ + return cp; + } + + return y; +#endif /* DUK_USE_REGEXP_CANON_WORKAROUND */ +} + +/* + * E5 Section 15.10.2.6 "IsWordChar" abstract operation. Assume + * x < 0 for characters read outside the string. + */ + +DUK_INTERNAL duk_small_int_t duk_unicode_re_is_wordchar(duk_codepoint_t x) { + /* + * Note: the description in E5 Section 15.10.2.6 has a typo, it + * contains 'A' twice and lacks 'a'; the intent is [0-9a-zA-Z_]. + */ + if ((x >= '0' && x <= '9') || + (x >= 'a' && x <= 'z') || + (x >= 'A' && x <= 'Z') || + (x == '_')) { + return 1; + } + return 0; +} + +/* + * Regexp range tables + */ + +/* exposed because lexer needs these too */ +DUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_digit[2] = { + (duk_uint16_t) 0x0030UL, (duk_uint16_t) 0x0039UL, +}; +DUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_white[22] = { + (duk_uint16_t) 0x0009UL, (duk_uint16_t) 0x000DUL, + (duk_uint16_t) 0x0020UL, (duk_uint16_t) 0x0020UL, + (duk_uint16_t) 0x00A0UL, (duk_uint16_t) 0x00A0UL, + (duk_uint16_t) 0x1680UL, (duk_uint16_t) 0x1680UL, + (duk_uint16_t) 0x180EUL, (duk_uint16_t) 0x180EUL, + (duk_uint16_t) 0x2000UL, (duk_uint16_t) 0x200AUL, + (duk_uint16_t) 0x2028UL, (duk_uint16_t) 0x2029UL, + (duk_uint16_t) 0x202FUL, (duk_uint16_t) 0x202FUL, + (duk_uint16_t) 0x205FUL, (duk_uint16_t) 0x205FUL, + (duk_uint16_t) 0x3000UL, (duk_uint16_t) 0x3000UL, + (duk_uint16_t) 0xFEFFUL, (duk_uint16_t) 0xFEFFUL, +}; +DUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_wordchar[8] = { + (duk_uint16_t) 0x0030UL, (duk_uint16_t) 0x0039UL, + (duk_uint16_t) 0x0041UL, (duk_uint16_t) 0x005AUL, + (duk_uint16_t) 0x005FUL, (duk_uint16_t) 0x005FUL, + (duk_uint16_t) 0x0061UL, (duk_uint16_t) 0x007AUL, +}; +DUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_digit[4] = { + (duk_uint16_t) 0x0000UL, (duk_uint16_t) 0x002FUL, + (duk_uint16_t) 0x003AUL, (duk_uint16_t) 0xFFFFUL, +}; +DUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_white[24] = { + (duk_uint16_t) 0x0000UL, (duk_uint16_t) 0x0008UL, + (duk_uint16_t) 0x000EUL, (duk_uint16_t) 0x001FUL, + (duk_uint16_t) 0x0021UL, (duk_uint16_t) 0x009FUL, + (duk_uint16_t) 0x00A1UL, (duk_uint16_t) 0x167FUL, + (duk_uint16_t) 0x1681UL, (duk_uint16_t) 0x180DUL, + (duk_uint16_t) 0x180FUL, (duk_uint16_t) 0x1FFFUL, + (duk_uint16_t) 0x200BUL, (duk_uint16_t) 0x2027UL, + (duk_uint16_t) 0x202AUL, (duk_uint16_t) 0x202EUL, + (duk_uint16_t) 0x2030UL, (duk_uint16_t) 0x205EUL, + (duk_uint16_t) 0x2060UL, (duk_uint16_t) 0x2FFFUL, + (duk_uint16_t) 0x3001UL, (duk_uint16_t) 0xFEFEUL, + (duk_uint16_t) 0xFF00UL, (duk_uint16_t) 0xFFFFUL, +}; +DUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_wordchar[10] = { + (duk_uint16_t) 0x0000UL, (duk_uint16_t) 0x002FUL, + (duk_uint16_t) 0x003AUL, (duk_uint16_t) 0x0040UL, + (duk_uint16_t) 0x005BUL, (duk_uint16_t) 0x005EUL, + (duk_uint16_t) 0x0060UL, (duk_uint16_t) 0x0060UL, + (duk_uint16_t) 0x007BUL, (duk_uint16_t) 0xFFFFUL, +}; + +#endif /* DUK_USE_REGEXP_SUPPORT */ diff --git a/third_party/duktape/duk_unicode_tables.c b/third_party/duktape/duk_unicode_tables.c new file mode 100644 index 00000000..b187899a --- /dev/null +++ b/third_party/duktape/duk_unicode_tables.c @@ -0,0 +1,6175 @@ +/* + * Unicode support tables automatically generated during build. + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Unicode tables containing ranges of Unicode characters in a + * packed format. These tables are used to match non-ASCII + * characters of complex productions by resorting to a linear + * range-by-range comparison. This is very slow, but is expected + * to be very rare in practical ECMAScript source code, and thus + * compactness is most important. + * + * The tables are matched using uni_range_match() and the format + * is described in tools/extract_chars.py. + */ + +#if defined(DUK_USE_SOURCE_NONBMP) +/* IdentifierStart production with ASCII excluded */ +/* duk_unicode_ids_noa[] */ +/* + * Automatically generated by extract_chars.py, do not edit! + */ + +const duk_uint8_t duk_unicode_ids_noa[1116] = { +249,176,176,80,111,7,47,15,47,254,11,197,191,0,72,2,15,115,66,19,50,7,2,34, +2,240,66,244,50,247,185,249,98,241,99,7,241,159,57,240,181,63,31,241,191, +21,18,245,50,15,1,24,27,35,15,2,2,240,239,15,244,156,15,10,241,26,21,6,240, +101,10,4,15,9,240,152,175,39,240,82,127,56,242,100,15,4,8,159,1,240,5,115, +19,240,98,98,4,52,15,2,14,18,47,0,27,9,85,19,240,98,98,18,18,31,17,50,15,5, +47,2,130,34,240,98,98,18,68,15,4,15,1,31,9,12,115,19,240,98,98,18,68,15,16, +18,47,1,15,3,2,84,34,52,18,2,20,20,36,191,8,15,38,114,34,240,114,240,4,15, +12,38,31,16,5,114,34,240,114,146,68,15,18,2,31,1,31,4,114,34,241,147,15,2, +6,41,47,10,86,240,36,240,130,130,3,111,44,242,2,29,111,44,18,2,66,240,130, +2,146,26,3,66,15,7,63,18,15,49,114,241,79,13,79,101,241,191,6,15,2,85,52,4, +24,37,205,15,3,241,98,6,3,241,178,255,224,63,35,54,32,35,63,25,35,63,17,35, +54,32,35,62,47,41,35,63,51,241,127,0,240,47,70,53,79,254,21,227,240,18,240, +166,243,180,168,194,63,0,240,47,0,240,47,0,194,47,1,242,79,21,5,15,53,244, +152,67,241,34,6,243,107,240,255,35,240,227,76,241,197,240,175,40,240,122, +242,95,68,15,79,241,255,3,111,41,240,238,27,241,207,12,241,79,27,43,241,67, +136,241,179,47,27,50,82,20,6,251,15,50,255,224,8,53,63,22,53,55,32,32,32, +47,15,63,37,38,32,66,38,67,53,92,98,38,246,96,224,240,44,245,112,80,57,32, +68,112,32,32,35,42,51,100,80,240,63,25,255,233,107,241,242,241,242,247,87, +52,29,241,98,6,3,242,136,15,2,240,122,98,98,98,98,98,98,98,111,66,15,254, +12,146,240,184,132,52,95,70,114,47,74,35,111,27,47,78,240,63,11,242,127,0, +255,224,244,255,240,0,138,143,60,255,240,4,14,47,2,255,227,127,243,95,30, +63,253,79,0,177,240,111,31,240,47,15,63,64,241,152,63,87,63,37,52,242,42, +34,35,47,7,240,255,36,240,15,34,243,5,64,33,207,12,191,7,240,191,13,143,31, +240,224,240,36,41,180,47,25,240,146,39,240,111,7,64,79,34,32,65,52,48,32, +240,162,58,130,213,53,53,166,38,47,27,43,159,99,240,255,255,0,26,150,223,7, +95,33,255,240,0,255,143,254,6,3,245,175,24,109,70,2,146,194,66,2,18,18,245, +207,19,255,224,93,240,79,48,63,38,241,171,246,100,47,119,241,111,10,127,10, +207,73,69,53,53,50,241,91,47,10,47,3,33,46,61,241,79,107,243,127,37,255, +223,13,79,33,242,31,16,239,14,111,22,191,14,63,20,87,36,241,207,142,240,79, +20,95,20,95,24,159,36,248,239,254,2,154,240,107,127,138,83,2,241,194,20,3, +240,123,240,122,240,255,51,240,50,27,240,107,240,175,56,242,135,31,50,15,1, +50,34,240,223,28,240,212,240,223,21,114,240,207,13,242,107,240,107,240,62, +240,47,96,243,159,41,242,62,242,62,241,79,254,13,15,13,176,159,6,248,207,7, +223,37,243,223,29,241,47,9,240,207,20,240,240,207,19,64,223,32,240,3,240, +112,32,241,95,2,47,9,244,102,32,35,46,41,143,31,241,135,49,63,6,38,33,36, +64,240,64,212,249,15,37,240,67,240,96,241,47,32,240,97,32,250,175,31,241, +179,241,111,32,240,96,242,223,27,224,243,159,11,253,127,28,246,111,48,241, +16,249,39,63,23,240,32,32,240,224,191,24,128,240,112,207,30,240,80,241,79, +41,255,152,47,21,240,48,242,63,14,246,38,33,47,22,240,112,240,181,33,47,16, +240,0,255,224,59,240,63,254,0,31,254,40,207,88,245,255,3,251,79,254,155,15, +254,50,31,254,236,95,254,19,159,255,0,16,173,255,225,43,143,15,246,63,14, +240,79,32,240,35,241,31,5,111,3,255,225,164,243,15,114,243,182,15,52,207, +50,18,15,14,255,240,0,110,169,255,225,229,255,240,1,64,31,254,1,31,35,47,3, +57,255,224,126,255,231,248,245,182,196,136,159,255,0,6,90,244,82,243,114, +19,3,19,50,178,2,98,243,18,51,114,98,240,194,50,66,4,98,255,224,70,63,9,47, +9,47,15,47,9,47,15,47,9,47,15,47,9,47,15,47,9,39,255,232,40,241,219,111,2, +15,254,6,95,28,255,228,8,251,95,45,243,72,15,254,58,131,47,11,33,32,48,41, +35,32,32,112,80,32,32,34,33,32,48,32,32,32,32,33,32,51,38,35,35,32,41,47,1, +98,36,47,1,255,240,0,3,143,255,0,149,201,241,191,254,242,124,252,227,255, +240,0,87,79,0,255,240,0,194,63,254,177,63,254,17,0, +}; +#else +/* IdentifierStart production with ASCII and non-BMP excluded */ +/* duk_unicode_ids_noabmp[] */ +/* + * Automatically generated by extract_chars.py, do not edit! + */ + +const duk_uint8_t duk_unicode_ids_noabmp[625] = { +249,176,176,80,111,7,47,15,47,254,11,197,191,0,72,2,15,115,66,19,50,7,2,34, +2,240,66,244,50,247,185,249,98,241,99,7,241,159,57,240,181,63,31,241,191, +21,18,245,50,15,1,24,27,35,15,2,2,240,239,15,244,156,15,10,241,26,21,6,240, +101,10,4,15,9,240,152,175,39,240,82,127,56,242,100,15,4,8,159,1,240,5,115, +19,240,98,98,4,52,15,2,14,18,47,0,27,9,85,19,240,98,98,18,18,31,17,50,15,5, +47,2,130,34,240,98,98,18,68,15,4,15,1,31,9,12,115,19,240,98,98,18,68,15,16, +18,47,1,15,3,2,84,34,52,18,2,20,20,36,191,8,15,38,114,34,240,114,240,4,15, +12,38,31,16,5,114,34,240,114,146,68,15,18,2,31,1,31,4,114,34,241,147,15,2, +6,41,47,10,86,240,36,240,130,130,3,111,44,242,2,29,111,44,18,2,66,240,130, +2,146,26,3,66,15,7,63,18,15,49,114,241,79,13,79,101,241,191,6,15,2,85,52,4, +24,37,205,15,3,241,98,6,3,241,178,255,224,63,35,54,32,35,63,25,35,63,17,35, +54,32,35,62,47,41,35,63,51,241,127,0,240,47,70,53,79,254,21,227,240,18,240, +166,243,180,168,194,63,0,240,47,0,240,47,0,194,47,1,242,79,21,5,15,53,244, +152,67,241,34,6,243,107,240,255,35,240,227,76,241,197,240,175,40,240,122, +242,95,68,15,79,241,255,3,111,41,240,238,27,241,207,12,241,79,27,43,241,67, +136,241,179,47,27,50,82,20,6,251,15,50,255,224,8,53,63,22,53,55,32,32,32, +47,15,63,37,38,32,66,38,67,53,92,98,38,246,96,224,240,44,245,112,80,57,32, +68,112,32,32,35,42,51,100,80,240,63,25,255,233,107,241,242,241,242,247,87, +52,29,241,98,6,3,242,136,15,2,240,122,98,98,98,98,98,98,98,111,66,15,254, +12,146,240,184,132,52,95,70,114,47,74,35,111,27,47,78,240,63,11,242,127,0, +255,224,244,255,240,0,138,143,60,255,240,4,14,47,2,255,227,127,243,95,30, +63,253,79,0,177,240,111,31,240,47,15,63,64,241,152,63,87,63,37,52,242,42, +34,35,47,7,240,255,36,240,15,34,243,5,64,33,207,12,191,7,240,191,13,143,31, +240,224,240,36,41,180,47,25,240,146,39,240,111,7,64,79,34,32,65,52,48,32, +240,162,58,130,213,53,53,166,38,47,27,43,159,99,240,255,255,0,26,150,223,7, +95,33,255,240,0,255,143,254,6,3,245,175,24,109,70,2,146,194,66,2,18,18,245, +207,19,255,224,93,240,79,48,63,38,241,171,246,100,47,119,241,111,10,127,10, +207,73,69,53,53,50,0, +}; +#endif + +#if defined(DUK_USE_SOURCE_NONBMP) +/* IdentifierStart production with Letter and ASCII excluded */ +/* duk_unicode_ids_m_let_noa[] */ +/* + * Automatically generated by extract_chars.py, do not edit! + */ + +const duk_uint8_t duk_unicode_ids_m_let_noa[42] = { +255,240,0,94,18,255,233,99,241,51,63,254,215,32,240,184,240,2,255,240,6,89, +249,255,240,4,148,79,37,255,224,192,9,15,120,79,255,0,15,30,245,240, +}; +#else +/* IdentifierStart production with Letter, ASCII, and non-BMP excluded */ +/* duk_unicode_ids_m_let_noabmp[] */ +/* + * Automatically generated by extract_chars.py, do not edit! + */ + +const duk_uint8_t duk_unicode_ids_m_let_noabmp[24] = { +255,240,0,94,18,255,233,99,241,51,63,254,215,32,240,184,240,2,255,240,6,89, +249,0, +}; +#endif + +#if defined(DUK_USE_SOURCE_NONBMP) +/* IdentifierPart production with IdentifierStart and ASCII excluded */ +/* duk_unicode_idp_m_ids_noa[] */ +/* + * Automatically generated by extract_chars.py, do not edit! + */ + +const duk_uint8_t duk_unicode_idp_m_ids_noa[576] = { +255,225,243,246,15,254,0,116,255,191,29,32,33,33,32,243,170,242,47,15,112, +245,118,53,49,35,57,240,144,241,15,11,244,218,240,25,241,56,160,240,163,40, +34,36,241,210,246,158,47,17,242,130,47,2,38,177,57,240,50,242,160,38,49,50, +160,177,57,240,0,50,242,160,36,81,50,64,240,107,64,194,242,160,39,34,34, +240,97,57,181,34,242,160,38,49,50,145,177,57,240,64,242,212,66,35,160,240, +9,240,36,242,182,34,35,129,193,57,240,50,242,160,38,34,35,129,193,57,240, +35,242,145,38,34,35,160,177,57,240,65,243,128,85,32,39,121,49,242,240,54, +215,41,244,144,56,197,57,243,1,121,192,32,32,81,242,63,4,33,106,47,20,160, +245,111,4,41,211,82,34,54,67,235,46,255,225,179,47,254,42,98,240,242,240, +241,241,1,243,47,16,160,57,241,50,57,245,209,241,64,246,139,91,185,247,41, +242,244,242,185,47,13,58,121,240,141,243,68,242,31,1,201,240,56,210,241,12, +57,241,237,242,47,4,153,121,246,130,47,5,80,112,50,251,143,42,36,255,225,0, +31,35,31,5,15,109,197,4,191,254,175,34,247,240,245,47,16,255,225,30,95,91, +31,255,0,100,121,159,55,5,159,18,31,66,31,254,0,64,64,80,240,148,244,161, +242,79,2,185,127,2,234,240,231,240,188,241,227,242,29,240,25,192,185,242, +29,208,145,57,241,50,242,64,34,49,97,32,241,180,97,253,231,33,57,255,240,3, +225,128,255,225,213,240,15,2,240,4,31,10,47,178,159,23,15,254,27,16,253,64, +248,116,255,224,25,159,254,68,178,33,99,241,162,80,249,113,255,225,49,57, +159,254,16,10,250,18,242,126,241,25,240,19,241,250,242,121,114,241,109,41, +97,241,224,210,242,45,147,73,244,75,112,249,43,105,115,242,145,38,49,50, +160,177,54,68,251,47,2,169,80,244,63,4,217,252,118,56,240,209,244,79,1,240, +25,244,60,153,244,94,89,254,78,249,121,253,150,54,64,240,233,241,166,35, +144,170,242,15,0,255,224,137,114,127,2,159,42,240,98,223,108,84,2,18,98,9, +159,34,66,18,73,159,254,3,211,255,240,3,165,217,247,132,242,214,240,185, +255,226,233,2,242,120,63,255,0,59,254,31,255,0,3,186,68,89,115,111,16,63, +134,47,254,71,223,34,255,224,244,242,117,242,41,15,0,15,8,66,239,254,68,70, +47,1,54,33,36,255,118,169,255,224,150,223,254,76,166,245,246,105,255,240, +192,105,175,224,0, +}; +#else +/* IdentifierPart production with IdentifierStart, ASCII, and non-BMP excluded */ +/* duk_unicode_idp_m_ids_noabmp[] */ +/* + * Automatically generated by extract_chars.py, do not edit! + */ + +const duk_uint8_t duk_unicode_idp_m_ids_noabmp[358] = { +255,225,243,246,15,254,0,116,255,191,29,32,33,33,32,243,170,242,47,15,112, +245,118,53,49,35,57,240,144,241,15,11,244,218,240,25,241,56,160,240,163,40, +34,36,241,210,246,158,47,17,242,130,47,2,38,177,57,240,50,242,160,38,49,50, +160,177,57,240,0,50,242,160,36,81,50,64,240,107,64,194,242,160,39,34,34, +240,97,57,181,34,242,160,38,49,50,145,177,57,240,64,242,212,66,35,160,240, +9,240,36,242,182,34,35,129,193,57,240,50,242,160,38,34,35,129,193,57,240, +35,242,145,38,34,35,160,177,57,240,65,243,128,85,32,39,121,49,242,240,54, +215,41,244,144,56,197,57,243,1,121,192,32,32,81,242,63,4,33,106,47,20,160, +245,111,4,41,211,82,34,54,67,235,46,255,225,179,47,254,42,98,240,242,240, +241,241,1,243,47,16,160,57,241,50,57,245,209,241,64,246,139,91,185,247,41, +242,244,242,185,47,13,58,121,240,141,243,68,242,31,1,201,240,56,210,241,12, +57,241,237,242,47,4,153,121,246,130,47,5,80,112,50,251,143,42,36,255,225,0, +31,35,31,5,15,109,197,4,191,254,175,34,247,240,245,47,16,255,225,30,95,91, +31,255,0,100,121,159,55,5,159,18,31,66,31,254,0,64,64,80,240,148,244,161, +242,79,2,185,127,2,234,240,231,240,188,241,227,242,29,240,25,192,185,242, +29,208,145,57,241,50,242,64,34,49,97,32,241,180,97,253,231,33,57,255,240,3, +225,128,255,225,213,240,15,2,240,4,31,10,47,178,159,23,0, +}; +#endif + +/* + * Case conversion tables generated using tools/extract_caseconv.py. + */ + +/* duk_unicode_caseconv_uc[] */ +/* duk_unicode_caseconv_lc[] */ + +/* + * Automatically generated by extract_caseconv.py, do not edit! + */ + +const duk_uint8_t duk_unicode_caseconv_uc[1411] = { +152,3,128,3,0,184,7,192,6,192,112,35,242,199,224,64,74,192,49,32,128,162, +128,108,65,1,189,129,254,131,3,173,3,136,6,7,98,7,34,68,15,12,14,140,72,30, +104,28,112,32,67,0,65,4,0,138,0,128,4,1,88,65,76,83,8,104,14,72,43,16,253, +28,189,6,39,240,39,224,24,114,12,16,132,16,248,0,248,64,129,241,1,241,128, +195,228,3,229,2,7,204,7,206,4,15,160,15,164,6,31,96,31,104,16,62,224,63, +116,8,125,200,127,32,32,251,176,254,208,33,247,129,255,128,67,239,67,253, +64,135,223,7,254,129,15,216,15,220,2,31,208,31,216,4,63,192,63,208,8,133, +192,133,128,129,38,129,37,177,162,195,2,192,5,229,160,2,20,9,170,220,4,232, +40,127,160,255,144,154,136,4,4,4,0,192,9,152,9,144,48,19,160,19,145,0,41, +96,41,69,192,94,128,94,65,128,193,128,193,2,1,161,1,160,6,3,104,3,102,8,7, +56,7,52,64,14,248,14,240,144,31,144,31,130,128,68,96,68,66,64,145,192,145, +130,129,184,129,184,2,3,217,3,216,24,8,194,8,192,68,18,44,18,40,216,38,16, +38,8,112,77,16,77,6,3,192,35,192,18,199,168,71,168,24,15,168,143,172,132, +44,104,44,103,6,89,2,89,0,200,179,176,179,172,21,50,13,50,1,122,104,26,104, +1,212,228,116,228,65,233,204,233,204,143,211,189,83,188,130,167,127,167, +126,11,79,35,79,32,10,158,94,158,88,85,61,173,61,160,97,192,107,64,107,1,0, +226,128,226,3,1,198,1,196,6,3,228,3,226,8,10,0,6,152,16,31,192,31,184,34, +199,50,199,32,65,128,196,0,195,130,1,185,1,184,4,4,205,79,84,8,0,192,143,0, +142,193,1,52,128,203,2,45,39,16,199,5,253,0,11,80,57,192,15,240,23,128,19, +16,4,144,23,240,5,48,24,0,36,48,25,32,25,16,25,80,31,96,25,144,25,128,25, +160,35,208,25,224,34,0,26,128,26,112,27,240,31,112,29,208,24,224,31,48,31, +16,37,2,198,240,37,18,198,208,37,34,199,0,37,48,24,16,37,64,24,96,37,144, +24,240,37,176,25,0,37,202,122,176,38,0,25,48,38,26,122,192,38,48,25,64,38, +90,120,208,38,128,25,112,38,178,198,32,38,202,122,208,39,18,198,224,39,32, +25,208,39,80,25,240,39,210,198,64,40,42,124,80,40,122,123,16,40,128,26,224, +40,144,36,64,40,192,36,80,41,32,27,112,41,218,123,32,41,234,123,0,52,80,57, +144,55,112,55,96,58,192,56,96,60,32,58,48,60,192,56,192,61,0,57,32,61,16, +57,128,61,80,58,96,61,96,58,0,61,112,60,240,63,0,57,160,63,16,58,16,63,32, +63,144,63,48,55,240,63,80,57,80,76,240,76,1,200,0,65,33,200,16,65,65,200, +32,65,225,200,80,66,33,200,96,66,161,200,112,70,33,200,138,100,161,215,154, +119,209,215,210,198,49,216,234,124,97,233,177,230,1,251,224,57,145,254,81, +254,194,20,226,19,34,24,66,24,50,198,18,198,2,198,80,35,162,198,96,35,226, +207,50,207,42,120,202,120,186,121,74,124,74,124,58,124,42,181,58,123,60, +192,27,240,2,152,2,152,10,76,5,120,0,156,3,225,0,37,1,134,1,200,96,115,32, +97,0,96,32,118,24,29,40,24,64,24,8,44,60,10,106,10,164,61,45,0,36,1,152, +143,75,192,10,128,97,3,211,16,2,184,24,80,244,204,0,178,6,20,61,53,0,32, +129,95,15,168,64,116,160,98,99,234,88,29,40,24,152,24,0,250,166,7,74,6,38, +6,2,62,173,129,210,129,137,129,161,15,192,67,225,0,115,35,240,48,248,72,28, +200,252,20,62,20,7,50,63,7,15,133,129,204,143,194,67,225,128,115,35,240, +176,248,104,28,200,252,52,62,28,7,50,63,15,15,135,129,204,143,196,67,225,0, +115,35,241,48,248,72,28,200,252,84,62,20,7,50,63,23,15,133,129,204,143,198, +67,225,128,115,35,241,176,248,104,28,200,252,116,62,28,7,50,63,31,15,135, +129,204,143,200,67,229,0,115,35,242,48,249,72,28,200,252,148,62,84,7,50,63, +39,15,149,129,204,143,202,67,229,128,115,35,242,176,249,104,28,200,252,180, +62,92,7,50,63,47,15,151,129,204,143,204,67,229,0,115,35,243,48,249,72,28, +200,252,212,62,84,7,50,63,55,15,149,129,204,143,206,67,229,128,115,35,243, +176,249,104,28,200,252,244,62,92,7,50,63,63,15,151,129,204,143,208,67,237, +0,115,35,244,48,251,72,28,200,253,20,62,212,7,50,63,71,15,181,129,204,143, +210,67,237,128,115,35,244,176,251,104,28,200,253,52,62,220,7,50,63,79,15, +183,129,204,143,212,67,237,0,115,35,245,48,251,72,28,200,253,84,62,212,7, +50,63,87,15,181,129,204,143,214,67,237,128,115,35,245,176,251,104,28,200, +253,116,62,220,7,50,63,95,15,183,129,204,143,217,67,247,64,115,35,246,112, +28,136,28,200,253,164,7,12,7,50,63,109,1,200,129,161,15,219,224,114,32,104, +64,115,35,247,144,28,136,28,200,254,20,63,148,7,50,63,135,1,203,129,204, +143,226,64,113,32,115,35,248,208,28,184,26,16,254,62,7,46,6,132,7,50,63, +153,1,203,129,204,143,233,96,115,32,97,0,96,3,250,120,28,200,24,64,24,8, +254,180,7,50,6,132,63,175,129,204,129,132,1,161,15,241,96,116,160,97,0,96, +3,252,120,29,40,24,64,24,8,255,36,7,66,6,38,63,205,1,210,129,161,15,243, +224,116,160,97,0,104,67,254,80,255,208,28,200,255,156,7,82,7,50,63,233,1, +199,129,204,143,251,64,117,32,104,67,254,248,29,72,26,16,28,200,255,228,7, +82,7,51,246,1,0,35,0,35,125,128,192,8,192,9,63,96,80,2,48,2,103,216,30,0, +140,0,140,0,147,246,9,128,35,0,35,0,38,125,130,192,10,96,10,159,96,208,2, +152,2,167,216,156,10,136,10,141,246,41,2,162,2,154,253,138,192,168,128,167, +127,98,208,42,112,42,55,216,188,10,136,10,122, +}; +const duk_uint8_t duk_unicode_caseconv_lc[706] = { +160,3,0,3,128,184,6,192,7,192,112,24,144,37,96,64,54,32,81,64,128,226,0, +235,65,129,199,1,230,130,3,145,3,177,34,7,70,7,134,36,15,244,13,236,24,32, +0,34,129,0,65,0,67,4,0,166,32,172,41,132,40,11,64,19,9,208,85,184,80,19, +240,19,248,12,57,32,33,160,172,114,244,67,244,24,248,64,248,0,129,241,129, +241,0,195,229,3,228,2,7,206,7,204,4,15,164,15,160,6,31,104,31,96,16,63,16, +63,0,32,126,96,126,64,64,253,64,253,0,129,251,129,251,0,67,247,67,238,0, +135,242,7,220,130,15,236,15,232,2,31,218,31,118,4,63,208,63,192,8,127,168, +125,232,16,255,192,251,192,33,255,161,247,192,68,44,4,46,4,9,45,137,52,13, +22,0,22,24,47,44,126,2,63,5,254,67,254,130,106,48,16,0,16,19,0,38,64,38,96, +192,78,64,78,132,0,165,0,165,151,1,121,1,122,6,3,4,3,6,8,6,128,6,132,24,13, +152,13,160,32,28,176,28,193,32,59,192,59,226,64,124,128,124,193,0,252,0, +252,148,2,34,2,35,18,4,140,4,142,20,13,192,13,196,16,30,192,30,200,192,70, +0,70,18,32,145,64,145,102,193,48,65,48,131,130,104,2,104,176,30,0,30,1,150, +61,64,61,66,192,125,100,125,68,33,99,57,99,64,50,200,2,200,22,69,157,101, +157,128,169,144,41,144,75,211,64,83,64,142,167,34,167,35,15,78,101,78,102, +126,157,230,157,232,21,59,245,59,248,90,121,10,121,16,84,242,212,242,226, +169,237,41,237,67,12,3,76,5,0,8,6,176,6,180,16,14,32,14,48,48,28,80,28,96, +64,126,224,127,0,139,28,139,28,193,6,3,14,3,16,8,6,224,6,228,21,61,80,19, +48,32,3,1,150,2,105,4,4,118,4,120,8,67,28,180,156,23,240,192,94,0,63,192, +96,64,148,192,97,128,149,0,99,128,119,64,99,192,150,64,100,0,150,192,100, +64,100,128,100,192,152,0,101,0,152,192,101,192,154,0,102,0,102,64,103,64, +156,128,103,192,157,64,105,192,106,0,107,128,162,0,109,192,164,128,124,64, +124,192,125,128,101,64,125,192,111,192,136,0,103,128,142,139,25,64,143,64, +102,128,143,139,25,128,144,192,96,0,145,0,162,64,145,64,163,0,221,128,221, +192,223,192,252,192,225,128,235,0,227,0,243,0,243,192,245,192,253,0,238,0, +254,64,252,129,48,1,51,199,167,128,55,199,239,7,236,199,243,7,240,199,251, +7,249,71,255,7,252,200,73,128,242,72,74,128,26,200,74,192,57,72,76,136,83, +136,96,200,97,11,24,11,24,75,24,128,154,203,24,199,95,75,25,0,159,75,27,64, +148,75,27,128,156,75,27,192,148,11,28,0,148,139,60,139,60,233,223,71,94, +105,226,233,227,41,227,64,153,105,234,192,151,41,235,0,152,105,235,64,155, +41,236,0,167,169,236,64,161,233,236,128,167,105,236,234,212,233,240,169, +240,233,241,41,229,41,241,64,160,169,241,135,99,128,128,152,64,13,32,96, +224, +}; + +#if defined(DUK_USE_REGEXP_CANON_WORKAROUND) +/* + * Automatically generated by extract_caseconv.py, do not edit! + */ + +const duk_uint16_t duk_unicode_re_canon_lookup[65536] = { +0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27, +28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52, +53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77, +78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,65,66,67,68,69,70, +71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,123,124,125, +126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, +144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161, +162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179, +180,924,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197, +198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215, +216,217,218,219,220,221,222,223,192,193,194,195,196,197,198,199,200,201, +202,203,204,205,206,207,208,209,210,211,212,213,214,247,216,217,218,219, +220,221,222,376,256,256,258,258,260,260,262,262,264,264,266,266,268,268, +270,270,272,272,274,274,276,276,278,278,280,280,282,282,284,284,286,286, +288,288,290,290,292,292,294,294,296,296,298,298,300,300,302,302,304,305, +306,306,308,308,310,310,312,313,313,315,315,317,317,319,319,321,321,323, +323,325,325,327,327,329,330,330,332,332,334,334,336,336,338,338,340,340, +342,342,344,344,346,346,348,348,350,350,352,352,354,354,356,356,358,358, +360,360,362,362,364,364,366,366,368,368,370,370,372,372,374,374,376,377, +377,379,379,381,381,383,579,385,386,386,388,388,390,391,391,393,394,395, +395,397,398,399,400,401,401,403,404,502,406,407,408,408,573,411,412,413, +544,415,416,416,418,418,420,420,422,423,423,425,426,427,428,428,430,431, +431,433,434,435,435,437,437,439,440,440,442,443,444,444,446,503,448,449, +450,451,452,452,452,455,455,455,458,458,458,461,461,463,463,465,465,467, +467,469,469,471,471,473,473,475,475,398,478,478,480,480,482,482,484,484, +486,486,488,488,490,490,492,492,494,494,496,497,497,497,500,500,502,503, +504,504,506,506,508,508,510,510,512,512,514,514,516,516,518,518,520,520, +522,522,524,524,526,526,528,528,530,530,532,532,534,534,536,536,538,538, +540,540,542,542,544,545,546,546,548,548,550,550,552,552,554,554,556,556, +558,558,560,560,562,562,564,565,566,567,568,569,570,571,571,573,574,11390, +11391,577,577,579,580,581,582,582,584,584,586,586,588,588,590,590,11375, +11373,11376,385,390,597,393,394,600,399,602,400,42923L,605,606,607,403, +42924L,610,404,612,42893L,42922L,615,407,406,42926L,11362,42925L,621,622, +412,624,11374,413,627,628,415,630,631,632,633,634,635,636,11364,638,639, +422,641,42949L,425,644,645,646,42929L,430,580,433,434,581,653,654,655,656, +657,439,659,660,661,662,663,664,665,666,667,668,42930L,42928L,671,672,673, +674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691, +692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709, +710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727, +728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745, +746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763, +764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781, +782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799, +800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817, +818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835, +836,921,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853, +854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871, +872,873,874,875,876,877,878,879,880,880,882,882,884,885,886,886,888,889, +890,1021,1022,1023,894,895,896,897,898,899,900,901,902,903,904,905,906,907, +908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925, +926,927,928,929,930,931,932,933,934,935,936,937,938,939,902,904,905,906, +944,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929, +931,931,932,933,934,935,936,937,938,939,908,910,911,975,914,920,978,979, +980,934,928,975,984,984,986,986,988,988,990,990,992,992,994,994,996,996, +998,998,1000,1000,1002,1002,1004,1004,1006,1006,922,929,1017,895,1012,917, +1014,1015,1015,1017,1018,1018,1020,1021,1022,1023,1024,1025,1026,1027,1028, +1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043, +1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058, +1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1040,1041, +1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056, +1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071, +1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038, +1039,1120,1120,1122,1122,1124,1124,1126,1126,1128,1128,1130,1130,1132,1132, +1134,1134,1136,1136,1138,1138,1140,1140,1142,1142,1144,1144,1146,1146,1148, +1148,1150,1150,1152,1152,1154,1155,1156,1157,1158,1159,1160,1161,1162,1162, +1164,1164,1166,1166,1168,1168,1170,1170,1172,1172,1174,1174,1176,1176,1178, +1178,1180,1180,1182,1182,1184,1184,1186,1186,1188,1188,1190,1190,1192,1192, +1194,1194,1196,1196,1198,1198,1200,1200,1202,1202,1204,1204,1206,1206,1208, +1208,1210,1210,1212,1212,1214,1214,1216,1217,1217,1219,1219,1221,1221,1223, +1223,1225,1225,1227,1227,1229,1229,1216,1232,1232,1234,1234,1236,1236,1238, +1238,1240,1240,1242,1242,1244,1244,1246,1246,1248,1248,1250,1250,1252,1252, +1254,1254,1256,1256,1258,1258,1260,1260,1262,1262,1264,1264,1266,1266,1268, +1268,1270,1270,1272,1272,1274,1274,1276,1276,1278,1278,1280,1280,1282,1282, +1284,1284,1286,1286,1288,1288,1290,1290,1292,1292,1294,1294,1296,1296,1298, +1298,1300,1300,1302,1302,1304,1304,1306,1306,1308,1308,1310,1310,1312,1312, +1314,1314,1316,1316,1318,1318,1320,1320,1322,1322,1324,1324,1326,1326,1328, +1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343, +1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358, +1359,1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,1373, +1374,1375,1376,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340, +1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355, +1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1415,1416,1417,1418, +1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433, +1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448, +1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463, +1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478, +1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493, +1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508, +1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523, +1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538, +1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553, +1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568, +1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583, +1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598, +1599,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613, +1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628, +1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643, +1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658, +1659,1660,1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673, +1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688, +1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703, +1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718, +1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733, +1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748, +1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763, +1764,1765,1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777,1778, +1779,1780,1781,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793, +1794,1795,1796,1797,1798,1799,1800,1801,1802,1803,1804,1805,1806,1807,1808, +1809,1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823, +1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838, +1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853, +1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1867,1868, +1869,1870,1871,1872,1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883, +1884,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,1896,1897,1898, +1899,1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913, +1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928, +1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943, +1944,1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958, +1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973, +1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988, +1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003, +2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018, +2019,2020,2021,2022,2023,2024,2025,2026,2027,2028,2029,2030,2031,2032,2033, +2034,2035,2036,2037,2038,2039,2040,2041,2042,2043,2044,2045,2046,2047,2048, +2049,2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,2060,2061,2062,2063, +2064,2065,2066,2067,2068,2069,2070,2071,2072,2073,2074,2075,2076,2077,2078, +2079,2080,2081,2082,2083,2084,2085,2086,2087,2088,2089,2090,2091,2092,2093, +2094,2095,2096,2097,2098,2099,2100,2101,2102,2103,2104,2105,2106,2107,2108, +2109,2110,2111,2112,2113,2114,2115,2116,2117,2118,2119,2120,2121,2122,2123, +2124,2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2137,2138, +2139,2140,2141,2142,2143,2144,2145,2146,2147,2148,2149,2150,2151,2152,2153, +2154,2155,2156,2157,2158,2159,2160,2161,2162,2163,2164,2165,2166,2167,2168, +2169,2170,2171,2172,2173,2174,2175,2176,2177,2178,2179,2180,2181,2182,2183, +2184,2185,2186,2187,2188,2189,2190,2191,2192,2193,2194,2195,2196,2197,2198, +2199,2200,2201,2202,2203,2204,2205,2206,2207,2208,2209,2210,2211,2212,2213, +2214,2215,2216,2217,2218,2219,2220,2221,2222,2223,2224,2225,2226,2227,2228, +2229,2230,2231,2232,2233,2234,2235,2236,2237,2238,2239,2240,2241,2242,2243, +2244,2245,2246,2247,2248,2249,2250,2251,2252,2253,2254,2255,2256,2257,2258, +2259,2260,2261,2262,2263,2264,2265,2266,2267,2268,2269,2270,2271,2272,2273, +2274,2275,2276,2277,2278,2279,2280,2281,2282,2283,2284,2285,2286,2287,2288, +2289,2290,2291,2292,2293,2294,2295,2296,2297,2298,2299,2300,2301,2302,2303, +2304,2305,2306,2307,2308,2309,2310,2311,2312,2313,2314,2315,2316,2317,2318, +2319,2320,2321,2322,2323,2324,2325,2326,2327,2328,2329,2330,2331,2332,2333, +2334,2335,2336,2337,2338,2339,2340,2341,2342,2343,2344,2345,2346,2347,2348, +2349,2350,2351,2352,2353,2354,2355,2356,2357,2358,2359,2360,2361,2362,2363, +2364,2365,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378, +2379,2380,2381,2382,2383,2384,2385,2386,2387,2388,2389,2390,2391,2392,2393, +2394,2395,2396,2397,2398,2399,2400,2401,2402,2403,2404,2405,2406,2407,2408, +2409,2410,2411,2412,2413,2414,2415,2416,2417,2418,2419,2420,2421,2422,2423, +2424,2425,2426,2427,2428,2429,2430,2431,2432,2433,2434,2435,2436,2437,2438, +2439,2440,2441,2442,2443,2444,2445,2446,2447,2448,2449,2450,2451,2452,2453, +2454,2455,2456,2457,2458,2459,2460,2461,2462,2463,2464,2465,2466,2467,2468, +2469,2470,2471,2472,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483, +2484,2485,2486,2487,2488,2489,2490,2491,2492,2493,2494,2495,2496,2497,2498, +2499,2500,2501,2502,2503,2504,2505,2506,2507,2508,2509,2510,2511,2512,2513, +2514,2515,2516,2517,2518,2519,2520,2521,2522,2523,2524,2525,2526,2527,2528, +2529,2530,2531,2532,2533,2534,2535,2536,2537,2538,2539,2540,2541,2542,2543, +2544,2545,2546,2547,2548,2549,2550,2551,2552,2553,2554,2555,2556,2557,2558, +2559,2560,2561,2562,2563,2564,2565,2566,2567,2568,2569,2570,2571,2572,2573, +2574,2575,2576,2577,2578,2579,2580,2581,2582,2583,2584,2585,2586,2587,2588, +2589,2590,2591,2592,2593,2594,2595,2596,2597,2598,2599,2600,2601,2602,2603, +2604,2605,2606,2607,2608,2609,2610,2611,2612,2613,2614,2615,2616,2617,2618, +2619,2620,2621,2622,2623,2624,2625,2626,2627,2628,2629,2630,2631,2632,2633, +2634,2635,2636,2637,2638,2639,2640,2641,2642,2643,2644,2645,2646,2647,2648, +2649,2650,2651,2652,2653,2654,2655,2656,2657,2658,2659,2660,2661,2662,2663, +2664,2665,2666,2667,2668,2669,2670,2671,2672,2673,2674,2675,2676,2677,2678, +2679,2680,2681,2682,2683,2684,2685,2686,2687,2688,2689,2690,2691,2692,2693, +2694,2695,2696,2697,2698,2699,2700,2701,2702,2703,2704,2705,2706,2707,2708, +2709,2710,2711,2712,2713,2714,2715,2716,2717,2718,2719,2720,2721,2722,2723, +2724,2725,2726,2727,2728,2729,2730,2731,2732,2733,2734,2735,2736,2737,2738, +2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750,2751,2752,2753, +2754,2755,2756,2757,2758,2759,2760,2761,2762,2763,2764,2765,2766,2767,2768, +2769,2770,2771,2772,2773,2774,2775,2776,2777,2778,2779,2780,2781,2782,2783, +2784,2785,2786,2787,2788,2789,2790,2791,2792,2793,2794,2795,2796,2797,2798, +2799,2800,2801,2802,2803,2804,2805,2806,2807,2808,2809,2810,2811,2812,2813, +2814,2815,2816,2817,2818,2819,2820,2821,2822,2823,2824,2825,2826,2827,2828, +2829,2830,2831,2832,2833,2834,2835,2836,2837,2838,2839,2840,2841,2842,2843, +2844,2845,2846,2847,2848,2849,2850,2851,2852,2853,2854,2855,2856,2857,2858, +2859,2860,2861,2862,2863,2864,2865,2866,2867,2868,2869,2870,2871,2872,2873, +2874,2875,2876,2877,2878,2879,2880,2881,2882,2883,2884,2885,2886,2887,2888, +2889,2890,2891,2892,2893,2894,2895,2896,2897,2898,2899,2900,2901,2902,2903, +2904,2905,2906,2907,2908,2909,2910,2911,2912,2913,2914,2915,2916,2917,2918, +2919,2920,2921,2922,2923,2924,2925,2926,2927,2928,2929,2930,2931,2932,2933, +2934,2935,2936,2937,2938,2939,2940,2941,2942,2943,2944,2945,2946,2947,2948, +2949,2950,2951,2952,2953,2954,2955,2956,2957,2958,2959,2960,2961,2962,2963, +2964,2965,2966,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976,2977,2978, +2979,2980,2981,2982,2983,2984,2985,2986,2987,2988,2989,2990,2991,2992,2993, +2994,2995,2996,2997,2998,2999,3000,3001,3002,3003,3004,3005,3006,3007,3008, +3009,3010,3011,3012,3013,3014,3015,3016,3017,3018,3019,3020,3021,3022,3023, +3024,3025,3026,3027,3028,3029,3030,3031,3032,3033,3034,3035,3036,3037,3038, +3039,3040,3041,3042,3043,3044,3045,3046,3047,3048,3049,3050,3051,3052,3053, +3054,3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066,3067,3068, +3069,3070,3071,3072,3073,3074,3075,3076,3077,3078,3079,3080,3081,3082,3083, +3084,3085,3086,3087,3088,3089,3090,3091,3092,3093,3094,3095,3096,3097,3098, +3099,3100,3101,3102,3103,3104,3105,3106,3107,3108,3109,3110,3111,3112,3113, +3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3124,3125,3126,3127,3128, +3129,3130,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140,3141,3142,3143, +3144,3145,3146,3147,3148,3149,3150,3151,3152,3153,3154,3155,3156,3157,3158, +3159,3160,3161,3162,3163,3164,3165,3166,3167,3168,3169,3170,3171,3172,3173, +3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186,3187,3188, +3189,3190,3191,3192,3193,3194,3195,3196,3197,3198,3199,3200,3201,3202,3203, +3204,3205,3206,3207,3208,3209,3210,3211,3212,3213,3214,3215,3216,3217,3218, +3219,3220,3221,3222,3223,3224,3225,3226,3227,3228,3229,3230,3231,3232,3233, +3234,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248, +3249,3250,3251,3252,3253,3254,3255,3256,3257,3258,3259,3260,3261,3262,3263, +3264,3265,3266,3267,3268,3269,3270,3271,3272,3273,3274,3275,3276,3277,3278, +3279,3280,3281,3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3293, +3294,3295,3296,3297,3298,3299,3300,3301,3302,3303,3304,3305,3306,3307,3308, +3309,3310,3311,3312,3313,3314,3315,3316,3317,3318,3319,3320,3321,3322,3323, +3324,3325,3326,3327,3328,3329,3330,3331,3332,3333,3334,3335,3336,3337,3338, +3339,3340,3341,3342,3343,3344,3345,3346,3347,3348,3349,3350,3351,3352,3353, +3354,3355,3356,3357,3358,3359,3360,3361,3362,3363,3364,3365,3366,3367,3368, +3369,3370,3371,3372,3373,3374,3375,3376,3377,3378,3379,3380,3381,3382,3383, +3384,3385,3386,3387,3388,3389,3390,3391,3392,3393,3394,3395,3396,3397,3398, +3399,3400,3401,3402,3403,3404,3405,3406,3407,3408,3409,3410,3411,3412,3413, +3414,3415,3416,3417,3418,3419,3420,3421,3422,3423,3424,3425,3426,3427,3428, +3429,3430,3431,3432,3433,3434,3435,3436,3437,3438,3439,3440,3441,3442,3443, +3444,3445,3446,3447,3448,3449,3450,3451,3452,3453,3454,3455,3456,3457,3458, +3459,3460,3461,3462,3463,3464,3465,3466,3467,3468,3469,3470,3471,3472,3473, +3474,3475,3476,3477,3478,3479,3480,3481,3482,3483,3484,3485,3486,3487,3488, +3489,3490,3491,3492,3493,3494,3495,3496,3497,3498,3499,3500,3501,3502,3503, +3504,3505,3506,3507,3508,3509,3510,3511,3512,3513,3514,3515,3516,3517,3518, +3519,3520,3521,3522,3523,3524,3525,3526,3527,3528,3529,3530,3531,3532,3533, +3534,3535,3536,3537,3538,3539,3540,3541,3542,3543,3544,3545,3546,3547,3548, +3549,3550,3551,3552,3553,3554,3555,3556,3557,3558,3559,3560,3561,3562,3563, +3564,3565,3566,3567,3568,3569,3570,3571,3572,3573,3574,3575,3576,3577,3578, +3579,3580,3581,3582,3583,3584,3585,3586,3587,3588,3589,3590,3591,3592,3593, +3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607,3608, +3609,3610,3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,3621,3622,3623, +3624,3625,3626,3627,3628,3629,3630,3631,3632,3633,3634,3635,3636,3637,3638, +3639,3640,3641,3642,3643,3644,3645,3646,3647,3648,3649,3650,3651,3652,3653, +3654,3655,3656,3657,3658,3659,3660,3661,3662,3663,3664,3665,3666,3667,3668, +3669,3670,3671,3672,3673,3674,3675,3676,3677,3678,3679,3680,3681,3682,3683, +3684,3685,3686,3687,3688,3689,3690,3691,3692,3693,3694,3695,3696,3697,3698, +3699,3700,3701,3702,3703,3704,3705,3706,3707,3708,3709,3710,3711,3712,3713, +3714,3715,3716,3717,3718,3719,3720,3721,3722,3723,3724,3725,3726,3727,3728, +3729,3730,3731,3732,3733,3734,3735,3736,3737,3738,3739,3740,3741,3742,3743, +3744,3745,3746,3747,3748,3749,3750,3751,3752,3753,3754,3755,3756,3757,3758, +3759,3760,3761,3762,3763,3764,3765,3766,3767,3768,3769,3770,3771,3772,3773, +3774,3775,3776,3777,3778,3779,3780,3781,3782,3783,3784,3785,3786,3787,3788, +3789,3790,3791,3792,3793,3794,3795,3796,3797,3798,3799,3800,3801,3802,3803, +3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,3814,3815,3816,3817,3818, +3819,3820,3821,3822,3823,3824,3825,3826,3827,3828,3829,3830,3831,3832,3833, +3834,3835,3836,3837,3838,3839,3840,3841,3842,3843,3844,3845,3846,3847,3848, +3849,3850,3851,3852,3853,3854,3855,3856,3857,3858,3859,3860,3861,3862,3863, +3864,3865,3866,3867,3868,3869,3870,3871,3872,3873,3874,3875,3876,3877,3878, +3879,3880,3881,3882,3883,3884,3885,3886,3887,3888,3889,3890,3891,3892,3893, +3894,3895,3896,3897,3898,3899,3900,3901,3902,3903,3904,3905,3906,3907,3908, +3909,3910,3911,3912,3913,3914,3915,3916,3917,3918,3919,3920,3921,3922,3923, +3924,3925,3926,3927,3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938, +3939,3940,3941,3942,3943,3944,3945,3946,3947,3948,3949,3950,3951,3952,3953, +3954,3955,3956,3957,3958,3959,3960,3961,3962,3963,3964,3965,3966,3967,3968, +3969,3970,3971,3972,3973,3974,3975,3976,3977,3978,3979,3980,3981,3982,3983, +3984,3985,3986,3987,3988,3989,3990,3991,3992,3993,3994,3995,3996,3997,3998, +3999,4000,4001,4002,4003,4004,4005,4006,4007,4008,4009,4010,4011,4012,4013, +4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027,4028, +4029,4030,4031,4032,4033,4034,4035,4036,4037,4038,4039,4040,4041,4042,4043, +4044,4045,4046,4047,4048,4049,4050,4051,4052,4053,4054,4055,4056,4057,4058, +4059,4060,4061,4062,4063,4064,4065,4066,4067,4068,4069,4070,4071,4072,4073, +4074,4075,4076,4077,4078,4079,4080,4081,4082,4083,4084,4085,4086,4087,4088, +4089,4090,4091,4092,4093,4094,4095,4096,4097,4098,4099,4100,4101,4102,4103, +4104,4105,4106,4107,4108,4109,4110,4111,4112,4113,4114,4115,4116,4117,4118, +4119,4120,4121,4122,4123,4124,4125,4126,4127,4128,4129,4130,4131,4132,4133, +4134,4135,4136,4137,4138,4139,4140,4141,4142,4143,4144,4145,4146,4147,4148, +4149,4150,4151,4152,4153,4154,4155,4156,4157,4158,4159,4160,4161,4162,4163, +4164,4165,4166,4167,4168,4169,4170,4171,4172,4173,4174,4175,4176,4177,4178, +4179,4180,4181,4182,4183,4184,4185,4186,4187,4188,4189,4190,4191,4192,4193, +4194,4195,4196,4197,4198,4199,4200,4201,4202,4203,4204,4205,4206,4207,4208, +4209,4210,4211,4212,4213,4214,4215,4216,4217,4218,4219,4220,4221,4222,4223, +4224,4225,4226,4227,4228,4229,4230,4231,4232,4233,4234,4235,4236,4237,4238, +4239,4240,4241,4242,4243,4244,4245,4246,4247,4248,4249,4250,4251,4252,4253, +4254,4255,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265,4266,4267,4268, +4269,4270,4271,4272,4273,4274,4275,4276,4277,4278,4279,4280,4281,4282,4283, +4284,4285,4286,4287,4288,4289,4290,4291,4292,4293,4294,4295,4296,4297,4298, +4299,4300,4301,4302,4303,7312,7313,7314,7315,7316,7317,7318,7319,7320,7321, +7322,7323,7324,7325,7326,7327,7328,7329,7330,7331,7332,7333,7334,7335,7336, +7337,7338,7339,7340,7341,7342,7343,7344,7345,7346,7347,7348,7349,7350,7351, +7352,7353,7354,4347,4348,7357,7358,7359,4352,4353,4354,4355,4356,4357,4358, +4359,4360,4361,4362,4363,4364,4365,4366,4367,4368,4369,4370,4371,4372,4373, +4374,4375,4376,4377,4378,4379,4380,4381,4382,4383,4384,4385,4386,4387,4388, +4389,4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403, +4404,4405,4406,4407,4408,4409,4410,4411,4412,4413,4414,4415,4416,4417,4418, +4419,4420,4421,4422,4423,4424,4425,4426,4427,4428,4429,4430,4431,4432,4433, +4434,4435,4436,4437,4438,4439,4440,4441,4442,4443,4444,4445,4446,4447,4448, +4449,4450,4451,4452,4453,4454,4455,4456,4457,4458,4459,4460,4461,4462,4463, +4464,4465,4466,4467,4468,4469,4470,4471,4472,4473,4474,4475,4476,4477,4478, +4479,4480,4481,4482,4483,4484,4485,4486,4487,4488,4489,4490,4491,4492,4493, +4494,4495,4496,4497,4498,4499,4500,4501,4502,4503,4504,4505,4506,4507,4508, +4509,4510,4511,4512,4513,4514,4515,4516,4517,4518,4519,4520,4521,4522,4523, +4524,4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,4536,4537,4538, +4539,4540,4541,4542,4543,4544,4545,4546,4547,4548,4549,4550,4551,4552,4553, +4554,4555,4556,4557,4558,4559,4560,4561,4562,4563,4564,4565,4566,4567,4568, +4569,4570,4571,4572,4573,4574,4575,4576,4577,4578,4579,4580,4581,4582,4583, +4584,4585,4586,4587,4588,4589,4590,4591,4592,4593,4594,4595,4596,4597,4598, +4599,4600,4601,4602,4603,4604,4605,4606,4607,4608,4609,4610,4611,4612,4613, +4614,4615,4616,4617,4618,4619,4620,4621,4622,4623,4624,4625,4626,4627,4628, +4629,4630,4631,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642,4643, +4644,4645,4646,4647,4648,4649,4650,4651,4652,4653,4654,4655,4656,4657,4658, +4659,4660,4661,4662,4663,4664,4665,4666,4667,4668,4669,4670,4671,4672,4673, +4674,4675,4676,4677,4678,4679,4680,4681,4682,4683,4684,4685,4686,4687,4688, +4689,4690,4691,4692,4693,4694,4695,4696,4697,4698,4699,4700,4701,4702,4703, +4704,4705,4706,4707,4708,4709,4710,4711,4712,4713,4714,4715,4716,4717,4718, +4719,4720,4721,4722,4723,4724,4725,4726,4727,4728,4729,4730,4731,4732,4733, +4734,4735,4736,4737,4738,4739,4740,4741,4742,4743,4744,4745,4746,4747,4748, +4749,4750,4751,4752,4753,4754,4755,4756,4757,4758,4759,4760,4761,4762,4763, +4764,4765,4766,4767,4768,4769,4770,4771,4772,4773,4774,4775,4776,4777,4778, +4779,4780,4781,4782,4783,4784,4785,4786,4787,4788,4789,4790,4791,4792,4793, +4794,4795,4796,4797,4798,4799,4800,4801,4802,4803,4804,4805,4806,4807,4808, +4809,4810,4811,4812,4813,4814,4815,4816,4817,4818,4819,4820,4821,4822,4823, +4824,4825,4826,4827,4828,4829,4830,4831,4832,4833,4834,4835,4836,4837,4838, +4839,4840,4841,4842,4843,4844,4845,4846,4847,4848,4849,4850,4851,4852,4853, +4854,4855,4856,4857,4858,4859,4860,4861,4862,4863,4864,4865,4866,4867,4868, +4869,4870,4871,4872,4873,4874,4875,4876,4877,4878,4879,4880,4881,4882,4883, +4884,4885,4886,4887,4888,4889,4890,4891,4892,4893,4894,4895,4896,4897,4898, +4899,4900,4901,4902,4903,4904,4905,4906,4907,4908,4909,4910,4911,4912,4913, +4914,4915,4916,4917,4918,4919,4920,4921,4922,4923,4924,4925,4926,4927,4928, +4929,4930,4931,4932,4933,4934,4935,4936,4937,4938,4939,4940,4941,4942,4943, +4944,4945,4946,4947,4948,4949,4950,4951,4952,4953,4954,4955,4956,4957,4958, +4959,4960,4961,4962,4963,4964,4965,4966,4967,4968,4969,4970,4971,4972,4973, +4974,4975,4976,4977,4978,4979,4980,4981,4982,4983,4984,4985,4986,4987,4988, +4989,4990,4991,4992,4993,4994,4995,4996,4997,4998,4999,5000,5001,5002,5003, +5004,5005,5006,5007,5008,5009,5010,5011,5012,5013,5014,5015,5016,5017,5018, +5019,5020,5021,5022,5023,5024,5025,5026,5027,5028,5029,5030,5031,5032,5033, +5034,5035,5036,5037,5038,5039,5040,5041,5042,5043,5044,5045,5046,5047,5048, +5049,5050,5051,5052,5053,5054,5055,5056,5057,5058,5059,5060,5061,5062,5063, +5064,5065,5066,5067,5068,5069,5070,5071,5072,5073,5074,5075,5076,5077,5078, +5079,5080,5081,5082,5083,5084,5085,5086,5087,5088,5089,5090,5091,5092,5093, +5094,5095,5096,5097,5098,5099,5100,5101,5102,5103,5104,5105,5106,5107,5108, +5109,5110,5111,5104,5105,5106,5107,5108,5109,5118,5119,5120,5121,5122,5123, +5124,5125,5126,5127,5128,5129,5130,5131,5132,5133,5134,5135,5136,5137,5138, +5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149,5150,5151,5152,5153, +5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164,5165,5166,5167,5168, +5169,5170,5171,5172,5173,5174,5175,5176,5177,5178,5179,5180,5181,5182,5183, +5184,5185,5186,5187,5188,5189,5190,5191,5192,5193,5194,5195,5196,5197,5198, +5199,5200,5201,5202,5203,5204,5205,5206,5207,5208,5209,5210,5211,5212,5213, +5214,5215,5216,5217,5218,5219,5220,5221,5222,5223,5224,5225,5226,5227,5228, +5229,5230,5231,5232,5233,5234,5235,5236,5237,5238,5239,5240,5241,5242,5243, +5244,5245,5246,5247,5248,5249,5250,5251,5252,5253,5254,5255,5256,5257,5258, +5259,5260,5261,5262,5263,5264,5265,5266,5267,5268,5269,5270,5271,5272,5273, +5274,5275,5276,5277,5278,5279,5280,5281,5282,5283,5284,5285,5286,5287,5288, +5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303, +5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318, +5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331,5332,5333, +5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347,5348, +5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363, +5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378, +5379,5380,5381,5382,5383,5384,5385,5386,5387,5388,5389,5390,5391,5392,5393, +5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408, +5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423, +5424,5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438, +5439,5440,5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453, +5454,5455,5456,5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468, +5469,5470,5471,5472,5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483, +5484,5485,5486,5487,5488,5489,5490,5491,5492,5493,5494,5495,5496,5497,5498, +5499,5500,5501,5502,5503,5504,5505,5506,5507,5508,5509,5510,5511,5512,5513, +5514,5515,5516,5517,5518,5519,5520,5521,5522,5523,5524,5525,5526,5527,5528, +5529,5530,5531,5532,5533,5534,5535,5536,5537,5538,5539,5540,5541,5542,5543, +5544,5545,5546,5547,5548,5549,5550,5551,5552,5553,5554,5555,5556,5557,5558, +5559,5560,5561,5562,5563,5564,5565,5566,5567,5568,5569,5570,5571,5572,5573, +5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584,5585,5586,5587,5588, +5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600,5601,5602,5603, +5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616,5617,5618, +5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632,5633, +5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648, +5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663, +5664,5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678, +5679,5680,5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693, +5694,5695,5696,5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708, +5709,5710,5711,5712,5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723, +5724,5725,5726,5727,5728,5729,5730,5731,5732,5733,5734,5735,5736,5737,5738, +5739,5740,5741,5742,5743,5744,5745,5746,5747,5748,5749,5750,5751,5752,5753, +5754,5755,5756,5757,5758,5759,5760,5761,5762,5763,5764,5765,5766,5767,5768, +5769,5770,5771,5772,5773,5774,5775,5776,5777,5778,5779,5780,5781,5782,5783, +5784,5785,5786,5787,5788,5789,5790,5791,5792,5793,5794,5795,5796,5797,5798, +5799,5800,5801,5802,5803,5804,5805,5806,5807,5808,5809,5810,5811,5812,5813, +5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828, +5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843, +5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856,5857,5858, +5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872,5873, +5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888, +5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903, +5904,5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918, +5919,5920,5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933, +5934,5935,5936,5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948, +5949,5950,5951,5952,5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963, +5964,5965,5966,5967,5968,5969,5970,5971,5972,5973,5974,5975,5976,5977,5978, +5979,5980,5981,5982,5983,5984,5985,5986,5987,5988,5989,5990,5991,5992,5993, +5994,5995,5996,5997,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008, +6009,6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020,6021,6022,6023, +6024,6025,6026,6027,6028,6029,6030,6031,6032,6033,6034,6035,6036,6037,6038, +6039,6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052,6053, +6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6068, +6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083, +6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098, +6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113, +6114,6115,6116,6117,6118,6119,6120,6121,6122,6123,6124,6125,6126,6127,6128, +6129,6130,6131,6132,6133,6134,6135,6136,6137,6138,6139,6140,6141,6142,6143, +6144,6145,6146,6147,6148,6149,6150,6151,6152,6153,6154,6155,6156,6157,6158, +6159,6160,6161,6162,6163,6164,6165,6166,6167,6168,6169,6170,6171,6172,6173, +6174,6175,6176,6177,6178,6179,6180,6181,6182,6183,6184,6185,6186,6187,6188, +6189,6190,6191,6192,6193,6194,6195,6196,6197,6198,6199,6200,6201,6202,6203, +6204,6205,6206,6207,6208,6209,6210,6211,6212,6213,6214,6215,6216,6217,6218, +6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6229,6230,6231,6232,6233, +6234,6235,6236,6237,6238,6239,6240,6241,6242,6243,6244,6245,6246,6247,6248, +6249,6250,6251,6252,6253,6254,6255,6256,6257,6258,6259,6260,6261,6262,6263, +6264,6265,6266,6267,6268,6269,6270,6271,6272,6273,6274,6275,6276,6277,6278, +6279,6280,6281,6282,6283,6284,6285,6286,6287,6288,6289,6290,6291,6292,6293, +6294,6295,6296,6297,6298,6299,6300,6301,6302,6303,6304,6305,6306,6307,6308, +6309,6310,6311,6312,6313,6314,6315,6316,6317,6318,6319,6320,6321,6322,6323, +6324,6325,6326,6327,6328,6329,6330,6331,6332,6333,6334,6335,6336,6337,6338, +6339,6340,6341,6342,6343,6344,6345,6346,6347,6348,6349,6350,6351,6352,6353, +6354,6355,6356,6357,6358,6359,6360,6361,6362,6363,6364,6365,6366,6367,6368, +6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379,6380,6381,6382,6383, +6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395,6396,6397,6398, +6399,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411,6412,6413, +6414,6415,6416,6417,6418,6419,6420,6421,6422,6423,6424,6425,6426,6427,6428, +6429,6430,6431,6432,6433,6434,6435,6436,6437,6438,6439,6440,6441,6442,6443, +6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,6455,6456,6457,6458, +6459,6460,6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471,6472,6473, +6474,6475,6476,6477,6478,6479,6480,6481,6482,6483,6484,6485,6486,6487,6488, +6489,6490,6491,6492,6493,6494,6495,6496,6497,6498,6499,6500,6501,6502,6503, +6504,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6516,6517,6518, +6519,6520,6521,6522,6523,6524,6525,6526,6527,6528,6529,6530,6531,6532,6533, +6534,6535,6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548, +6549,6550,6551,6552,6553,6554,6555,6556,6557,6558,6559,6560,6561,6562,6563, +6564,6565,6566,6567,6568,6569,6570,6571,6572,6573,6574,6575,6576,6577,6578, +6579,6580,6581,6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6593, +6594,6595,6596,6597,6598,6599,6600,6601,6602,6603,6604,6605,6606,6607,6608, +6609,6610,6611,6612,6613,6614,6615,6616,6617,6618,6619,6620,6621,6622,6623, +6624,6625,6626,6627,6628,6629,6630,6631,6632,6633,6634,6635,6636,6637,6638, +6639,6640,6641,6642,6643,6644,6645,6646,6647,6648,6649,6650,6651,6652,6653, +6654,6655,6656,6657,6658,6659,6660,6661,6662,6663,6664,6665,6666,6667,6668, +6669,6670,6671,6672,6673,6674,6675,6676,6677,6678,6679,6680,6681,6682,6683, +6684,6685,6686,6687,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,6698, +6699,6700,6701,6702,6703,6704,6705,6706,6707,6708,6709,6710,6711,6712,6713, +6714,6715,6716,6717,6718,6719,6720,6721,6722,6723,6724,6725,6726,6727,6728, +6729,6730,6731,6732,6733,6734,6735,6736,6737,6738,6739,6740,6741,6742,6743, +6744,6745,6746,6747,6748,6749,6750,6751,6752,6753,6754,6755,6756,6757,6758, +6759,6760,6761,6762,6763,6764,6765,6766,6767,6768,6769,6770,6771,6772,6773, +6774,6775,6776,6777,6778,6779,6780,6781,6782,6783,6784,6785,6786,6787,6788, +6789,6790,6791,6792,6793,6794,6795,6796,6797,6798,6799,6800,6801,6802,6803, +6804,6805,6806,6807,6808,6809,6810,6811,6812,6813,6814,6815,6816,6817,6818, +6819,6820,6821,6822,6823,6824,6825,6826,6827,6828,6829,6830,6831,6832,6833, +6834,6835,6836,6837,6838,6839,6840,6841,6842,6843,6844,6845,6846,6847,6848, +6849,6850,6851,6852,6853,6854,6855,6856,6857,6858,6859,6860,6861,6862,6863, +6864,6865,6866,6867,6868,6869,6870,6871,6872,6873,6874,6875,6876,6877,6878, +6879,6880,6881,6882,6883,6884,6885,6886,6887,6888,6889,6890,6891,6892,6893, +6894,6895,6896,6897,6898,6899,6900,6901,6902,6903,6904,6905,6906,6907,6908, +6909,6910,6911,6912,6913,6914,6915,6916,6917,6918,6919,6920,6921,6922,6923, +6924,6925,6926,6927,6928,6929,6930,6931,6932,6933,6934,6935,6936,6937,6938, +6939,6940,6941,6942,6943,6944,6945,6946,6947,6948,6949,6950,6951,6952,6953, +6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966,6967,6968, +6969,6970,6971,6972,6973,6974,6975,6976,6977,6978,6979,6980,6981,6982,6983, +6984,6985,6986,6987,6988,6989,6990,6991,6992,6993,6994,6995,6996,6997,6998, +6999,7000,7001,7002,7003,7004,7005,7006,7007,7008,7009,7010,7011,7012,7013, +7014,7015,7016,7017,7018,7019,7020,7021,7022,7023,7024,7025,7026,7027,7028, +7029,7030,7031,7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042,7043, +7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058, +7059,7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,7071,7072,7073, +7074,7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7086,7087,7088, +7089,7090,7091,7092,7093,7094,7095,7096,7097,7098,7099,7100,7101,7102,7103, +7104,7105,7106,7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118, +7119,7120,7121,7122,7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133, +7134,7135,7136,7137,7138,7139,7140,7141,7142,7143,7144,7145,7146,7147,7148, +7149,7150,7151,7152,7153,7154,7155,7156,7157,7158,7159,7160,7161,7162,7163, +7164,7165,7166,7167,7168,7169,7170,7171,7172,7173,7174,7175,7176,7177,7178, +7179,7180,7181,7182,7183,7184,7185,7186,7187,7188,7189,7190,7191,7192,7193, +7194,7195,7196,7197,7198,7199,7200,7201,7202,7203,7204,7205,7206,7207,7208, +7209,7210,7211,7212,7213,7214,7215,7216,7217,7218,7219,7220,7221,7222,7223, +7224,7225,7226,7227,7228,7229,7230,7231,7232,7233,7234,7235,7236,7237,7238, +7239,7240,7241,7242,7243,7244,7245,7246,7247,7248,7249,7250,7251,7252,7253, +7254,7255,7256,7257,7258,7259,7260,7261,7262,7263,7264,7265,7266,7267,7268, +7269,7270,7271,7272,7273,7274,7275,7276,7277,7278,7279,7280,7281,7282,7283, +7284,7285,7286,7287,7288,7289,7290,7291,7292,7293,7294,7295,1042,1044,1054, +1057,1058,1058,1066,1122,42570L,7305,7306,7307,7308,7309,7310,7311,7312, +7313,7314,7315,7316,7317,7318,7319,7320,7321,7322,7323,7324,7325,7326,7327, +7328,7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339,7340,7341,7342, +7343,7344,7345,7346,7347,7348,7349,7350,7351,7352,7353,7354,7355,7356,7357, +7358,7359,7360,7361,7362,7363,7364,7365,7366,7367,7368,7369,7370,7371,7372, +7373,7374,7375,7376,7377,7378,7379,7380,7381,7382,7383,7384,7385,7386,7387, +7388,7389,7390,7391,7392,7393,7394,7395,7396,7397,7398,7399,7400,7401,7402, +7403,7404,7405,7406,7407,7408,7409,7410,7411,7412,7413,7414,7415,7416,7417, +7418,7419,7420,7421,7422,7423,7424,7425,7426,7427,7428,7429,7430,7431,7432, +7433,7434,7435,7436,7437,7438,7439,7440,7441,7442,7443,7444,7445,7446,7447, +7448,7449,7450,7451,7452,7453,7454,7455,7456,7457,7458,7459,7460,7461,7462, +7463,7464,7465,7466,7467,7468,7469,7470,7471,7472,7473,7474,7475,7476,7477, +7478,7479,7480,7481,7482,7483,7484,7485,7486,7487,7488,7489,7490,7491,7492, +7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,7503,7504,7505,7506,7507, +7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519,7520,7521,7522, +7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535,7536,7537, +7538,7539,7540,7541,7542,7543,7544,42877L,7546,7547,7548,11363,7550,7551, +7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565, +42950L,7567,7568,7569,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579, +7580,7581,7582,7583,7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594, +7595,7596,7597,7598,7599,7600,7601,7602,7603,7604,7605,7606,7607,7608,7609, +7610,7611,7612,7613,7614,7615,7616,7617,7618,7619,7620,7621,7622,7623,7624, +7625,7626,7627,7628,7629,7630,7631,7632,7633,7634,7635,7636,7637,7638,7639, +7640,7641,7642,7643,7644,7645,7646,7647,7648,7649,7650,7651,7652,7653,7654, +7655,7656,7657,7658,7659,7660,7661,7662,7663,7664,7665,7666,7667,7668,7669, +7670,7671,7672,7673,7674,7675,7676,7677,7678,7679,7680,7680,7682,7682,7684, +7684,7686,7686,7688,7688,7690,7690,7692,7692,7694,7694,7696,7696,7698,7698, +7700,7700,7702,7702,7704,7704,7706,7706,7708,7708,7710,7710,7712,7712,7714, +7714,7716,7716,7718,7718,7720,7720,7722,7722,7724,7724,7726,7726,7728,7728, +7730,7730,7732,7732,7734,7734,7736,7736,7738,7738,7740,7740,7742,7742,7744, +7744,7746,7746,7748,7748,7750,7750,7752,7752,7754,7754,7756,7756,7758,7758, +7760,7760,7762,7762,7764,7764,7766,7766,7768,7768,7770,7770,7772,7772,7774, +7774,7776,7776,7778,7778,7780,7780,7782,7782,7784,7784,7786,7786,7788,7788, +7790,7790,7792,7792,7794,7794,7796,7796,7798,7798,7800,7800,7802,7802,7804, +7804,7806,7806,7808,7808,7810,7810,7812,7812,7814,7814,7816,7816,7818,7818, +7820,7820,7822,7822,7824,7824,7826,7826,7828,7828,7830,7831,7832,7833,7834, +7776,7836,7837,7838,7839,7840,7840,7842,7842,7844,7844,7846,7846,7848,7848, +7850,7850,7852,7852,7854,7854,7856,7856,7858,7858,7860,7860,7862,7862,7864, +7864,7866,7866,7868,7868,7870,7870,7872,7872,7874,7874,7876,7876,7878,7878, +7880,7880,7882,7882,7884,7884,7886,7886,7888,7888,7890,7890,7892,7892,7894, +7894,7896,7896,7898,7898,7900,7900,7902,7902,7904,7904,7906,7906,7908,7908, +7910,7910,7912,7912,7914,7914,7916,7916,7918,7918,7920,7920,7922,7922,7924, +7924,7926,7926,7928,7928,7930,7930,7932,7932,7934,7934,7944,7945,7946,7947, +7948,7949,7950,7951,7944,7945,7946,7947,7948,7949,7950,7951,7960,7961,7962, +7963,7964,7965,7958,7959,7960,7961,7962,7963,7964,7965,7966,7967,7976,7977, +7978,7979,7980,7981,7982,7983,7976,7977,7978,7979,7980,7981,7982,7983,7992, +7993,7994,7995,7996,7997,7998,7999,7992,7993,7994,7995,7996,7997,7998,7999, +8008,8009,8010,8011,8012,8013,8006,8007,8008,8009,8010,8011,8012,8013,8014, +8015,8016,8025,8018,8027,8020,8029,8022,8031,8024,8025,8026,8027,8028,8029, +8030,8031,8040,8041,8042,8043,8044,8045,8046,8047,8040,8041,8042,8043,8044, +8045,8046,8047,8122,8123,8136,8137,8138,8139,8154,8155,8184,8185,8170,8171, +8186,8187,8062,8063,8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074, +8075,8076,8077,8078,8079,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089, +8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8102,8103,8104, +8105,8106,8107,8108,8109,8110,8111,8120,8121,8114,8115,8116,8117,8118,8119, +8120,8121,8122,8123,8124,8125,921,8127,8128,8129,8130,8131,8132,8133,8134, +8135,8136,8137,8138,8139,8140,8141,8142,8143,8152,8153,8146,8147,8148,8149, +8150,8151,8152,8153,8154,8155,8156,8157,8158,8159,8168,8169,8162,8163,8164, +8172,8166,8167,8168,8169,8170,8171,8172,8173,8174,8175,8176,8177,8178,8179, +8180,8181,8182,8183,8184,8185,8186,8187,8188,8189,8190,8191,8192,8193,8194, +8195,8196,8197,8198,8199,8200,8201,8202,8203,8204,8205,8206,8207,8208,8209, +8210,8211,8212,8213,8214,8215,8216,8217,8218,8219,8220,8221,8222,8223,8224, +8225,8226,8227,8228,8229,8230,8231,8232,8233,8234,8235,8236,8237,8238,8239, +8240,8241,8242,8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254, +8255,8256,8257,8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269, +8270,8271,8272,8273,8274,8275,8276,8277,8278,8279,8280,8281,8282,8283,8284, +8285,8286,8287,8288,8289,8290,8291,8292,8293,8294,8295,8296,8297,8298,8299, +8300,8301,8302,8303,8304,8305,8306,8307,8308,8309,8310,8311,8312,8313,8314, +8315,8316,8317,8318,8319,8320,8321,8322,8323,8324,8325,8326,8327,8328,8329, +8330,8331,8332,8333,8334,8335,8336,8337,8338,8339,8340,8341,8342,8343,8344, +8345,8346,8347,8348,8349,8350,8351,8352,8353,8354,8355,8356,8357,8358,8359, +8360,8361,8362,8363,8364,8365,8366,8367,8368,8369,8370,8371,8372,8373,8374, +8375,8376,8377,8378,8379,8380,8381,8382,8383,8384,8385,8386,8387,8388,8389, +8390,8391,8392,8393,8394,8395,8396,8397,8398,8399,8400,8401,8402,8403,8404, +8405,8406,8407,8408,8409,8410,8411,8412,8413,8414,8415,8416,8417,8418,8419, +8420,8421,8422,8423,8424,8425,8426,8427,8428,8429,8430,8431,8432,8433,8434, +8435,8436,8437,8438,8439,8440,8441,8442,8443,8444,8445,8446,8447,8448,8449, +8450,8451,8452,8453,8454,8455,8456,8457,8458,8459,8460,8461,8462,8463,8464, +8465,8466,8467,8468,8469,8470,8471,8472,8473,8474,8475,8476,8477,8478,8479, +8480,8481,8482,8483,8484,8485,8486,8487,8488,8489,8490,8491,8492,8493,8494, +8495,8496,8497,8498,8499,8500,8501,8502,8503,8504,8505,8506,8507,8508,8509, +8510,8511,8512,8513,8514,8515,8516,8517,8518,8519,8520,8521,8522,8523,8524, +8525,8498,8527,8528,8529,8530,8531,8532,8533,8534,8535,8536,8537,8538,8539, +8540,8541,8542,8543,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554, +8555,8556,8557,8558,8559,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553, +8554,8555,8556,8557,8558,8559,8576,8577,8578,8579,8579,8581,8582,8583,8584, +8585,8586,8587,8588,8589,8590,8591,8592,8593,8594,8595,8596,8597,8598,8599, +8600,8601,8602,8603,8604,8605,8606,8607,8608,8609,8610,8611,8612,8613,8614, +8615,8616,8617,8618,8619,8620,8621,8622,8623,8624,8625,8626,8627,8628,8629, +8630,8631,8632,8633,8634,8635,8636,8637,8638,8639,8640,8641,8642,8643,8644, +8645,8646,8647,8648,8649,8650,8651,8652,8653,8654,8655,8656,8657,8658,8659, +8660,8661,8662,8663,8664,8665,8666,8667,8668,8669,8670,8671,8672,8673,8674, +8675,8676,8677,8678,8679,8680,8681,8682,8683,8684,8685,8686,8687,8688,8689, +8690,8691,8692,8693,8694,8695,8696,8697,8698,8699,8700,8701,8702,8703,8704, +8705,8706,8707,8708,8709,8710,8711,8712,8713,8714,8715,8716,8717,8718,8719, +8720,8721,8722,8723,8724,8725,8726,8727,8728,8729,8730,8731,8732,8733,8734, +8735,8736,8737,8738,8739,8740,8741,8742,8743,8744,8745,8746,8747,8748,8749, +8750,8751,8752,8753,8754,8755,8756,8757,8758,8759,8760,8761,8762,8763,8764, +8765,8766,8767,8768,8769,8770,8771,8772,8773,8774,8775,8776,8777,8778,8779, +8780,8781,8782,8783,8784,8785,8786,8787,8788,8789,8790,8791,8792,8793,8794, +8795,8796,8797,8798,8799,8800,8801,8802,8803,8804,8805,8806,8807,8808,8809, +8810,8811,8812,8813,8814,8815,8816,8817,8818,8819,8820,8821,8822,8823,8824, +8825,8826,8827,8828,8829,8830,8831,8832,8833,8834,8835,8836,8837,8838,8839, +8840,8841,8842,8843,8844,8845,8846,8847,8848,8849,8850,8851,8852,8853,8854, +8855,8856,8857,8858,8859,8860,8861,8862,8863,8864,8865,8866,8867,8868,8869, +8870,8871,8872,8873,8874,8875,8876,8877,8878,8879,8880,8881,8882,8883,8884, +8885,8886,8887,8888,8889,8890,8891,8892,8893,8894,8895,8896,8897,8898,8899, +8900,8901,8902,8903,8904,8905,8906,8907,8908,8909,8910,8911,8912,8913,8914, +8915,8916,8917,8918,8919,8920,8921,8922,8923,8924,8925,8926,8927,8928,8929, +8930,8931,8932,8933,8934,8935,8936,8937,8938,8939,8940,8941,8942,8943,8944, +8945,8946,8947,8948,8949,8950,8951,8952,8953,8954,8955,8956,8957,8958,8959, +8960,8961,8962,8963,8964,8965,8966,8967,8968,8969,8970,8971,8972,8973,8974, +8975,8976,8977,8978,8979,8980,8981,8982,8983,8984,8985,8986,8987,8988,8989, +8990,8991,8992,8993,8994,8995,8996,8997,8998,8999,9000,9001,9002,9003,9004, +9005,9006,9007,9008,9009,9010,9011,9012,9013,9014,9015,9016,9017,9018,9019, +9020,9021,9022,9023,9024,9025,9026,9027,9028,9029,9030,9031,9032,9033,9034, +9035,9036,9037,9038,9039,9040,9041,9042,9043,9044,9045,9046,9047,9048,9049, +9050,9051,9052,9053,9054,9055,9056,9057,9058,9059,9060,9061,9062,9063,9064, +9065,9066,9067,9068,9069,9070,9071,9072,9073,9074,9075,9076,9077,9078,9079, +9080,9081,9082,9083,9084,9085,9086,9087,9088,9089,9090,9091,9092,9093,9094, +9095,9096,9097,9098,9099,9100,9101,9102,9103,9104,9105,9106,9107,9108,9109, +9110,9111,9112,9113,9114,9115,9116,9117,9118,9119,9120,9121,9122,9123,9124, +9125,9126,9127,9128,9129,9130,9131,9132,9133,9134,9135,9136,9137,9138,9139, +9140,9141,9142,9143,9144,9145,9146,9147,9148,9149,9150,9151,9152,9153,9154, +9155,9156,9157,9158,9159,9160,9161,9162,9163,9164,9165,9166,9167,9168,9169, +9170,9171,9172,9173,9174,9175,9176,9177,9178,9179,9180,9181,9182,9183,9184, +9185,9186,9187,9188,9189,9190,9191,9192,9193,9194,9195,9196,9197,9198,9199, +9200,9201,9202,9203,9204,9205,9206,9207,9208,9209,9210,9211,9212,9213,9214, +9215,9216,9217,9218,9219,9220,9221,9222,9223,9224,9225,9226,9227,9228,9229, +9230,9231,9232,9233,9234,9235,9236,9237,9238,9239,9240,9241,9242,9243,9244, +9245,9246,9247,9248,9249,9250,9251,9252,9253,9254,9255,9256,9257,9258,9259, +9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,9273,9274, +9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,9288,9289, +9290,9291,9292,9293,9294,9295,9296,9297,9298,9299,9300,9301,9302,9303,9304, +9305,9306,9307,9308,9309,9310,9311,9312,9313,9314,9315,9316,9317,9318,9319, +9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,9332,9333,9334, +9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345,9346,9347,9348,9349, +9350,9351,9352,9353,9354,9355,9356,9357,9358,9359,9360,9361,9362,9363,9364, +9365,9366,9367,9368,9369,9370,9371,9372,9373,9374,9375,9376,9377,9378,9379, +9380,9381,9382,9383,9384,9385,9386,9387,9388,9389,9390,9391,9392,9393,9394, +9395,9396,9397,9398,9399,9400,9401,9402,9403,9404,9405,9406,9407,9408,9409, +9410,9411,9412,9413,9414,9415,9416,9417,9418,9419,9420,9421,9422,9423,9398, +9399,9400,9401,9402,9403,9404,9405,9406,9407,9408,9409,9410,9411,9412,9413, +9414,9415,9416,9417,9418,9419,9420,9421,9422,9423,9450,9451,9452,9453,9454, +9455,9456,9457,9458,9459,9460,9461,9462,9463,9464,9465,9466,9467,9468,9469, +9470,9471,9472,9473,9474,9475,9476,9477,9478,9479,9480,9481,9482,9483,9484, +9485,9486,9487,9488,9489,9490,9491,9492,9493,9494,9495,9496,9497,9498,9499, +9500,9501,9502,9503,9504,9505,9506,9507,9508,9509,9510,9511,9512,9513,9514, +9515,9516,9517,9518,9519,9520,9521,9522,9523,9524,9525,9526,9527,9528,9529, +9530,9531,9532,9533,9534,9535,9536,9537,9538,9539,9540,9541,9542,9543,9544, +9545,9546,9547,9548,9549,9550,9551,9552,9553,9554,9555,9556,9557,9558,9559, +9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574, +9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9588,9589, +9590,9591,9592,9593,9594,9595,9596,9597,9598,9599,9600,9601,9602,9603,9604, +9605,9606,9607,9608,9609,9610,9611,9612,9613,9614,9615,9616,9617,9618,9619, +9620,9621,9622,9623,9624,9625,9626,9627,9628,9629,9630,9631,9632,9633,9634, +9635,9636,9637,9638,9639,9640,9641,9642,9643,9644,9645,9646,9647,9648,9649, +9650,9651,9652,9653,9654,9655,9656,9657,9658,9659,9660,9661,9662,9663,9664, +9665,9666,9667,9668,9669,9670,9671,9672,9673,9674,9675,9676,9677,9678,9679, +9680,9681,9682,9683,9684,9685,9686,9687,9688,9689,9690,9691,9692,9693,9694, +9695,9696,9697,9698,9699,9700,9701,9702,9703,9704,9705,9706,9707,9708,9709, +9710,9711,9712,9713,9714,9715,9716,9717,9718,9719,9720,9721,9722,9723,9724, +9725,9726,9727,9728,9729,9730,9731,9732,9733,9734,9735,9736,9737,9738,9739, +9740,9741,9742,9743,9744,9745,9746,9747,9748,9749,9750,9751,9752,9753,9754, +9755,9756,9757,9758,9759,9760,9761,9762,9763,9764,9765,9766,9767,9768,9769, +9770,9771,9772,9773,9774,9775,9776,9777,9778,9779,9780,9781,9782,9783,9784, +9785,9786,9787,9788,9789,9790,9791,9792,9793,9794,9795,9796,9797,9798,9799, +9800,9801,9802,9803,9804,9805,9806,9807,9808,9809,9810,9811,9812,9813,9814, +9815,9816,9817,9818,9819,9820,9821,9822,9823,9824,9825,9826,9827,9828,9829, +9830,9831,9832,9833,9834,9835,9836,9837,9838,9839,9840,9841,9842,9843,9844, +9845,9846,9847,9848,9849,9850,9851,9852,9853,9854,9855,9856,9857,9858,9859, +9860,9861,9862,9863,9864,9865,9866,9867,9868,9869,9870,9871,9872,9873,9874, +9875,9876,9877,9878,9879,9880,9881,9882,9883,9884,9885,9886,9887,9888,9889, +9890,9891,9892,9893,9894,9895,9896,9897,9898,9899,9900,9901,9902,9903,9904, +9905,9906,9907,9908,9909,9910,9911,9912,9913,9914,9915,9916,9917,9918,9919, +9920,9921,9922,9923,9924,9925,9926,9927,9928,9929,9930,9931,9932,9933,9934, +9935,9936,9937,9938,9939,9940,9941,9942,9943,9944,9945,9946,9947,9948,9949, +9950,9951,9952,9953,9954,9955,9956,9957,9958,9959,9960,9961,9962,9963,9964, +9965,9966,9967,9968,9969,9970,9971,9972,9973,9974,9975,9976,9977,9978,9979, +9980,9981,9982,9983,9984,9985,9986,9987,9988,9989,9990,9991,9992,9993,9994, +9995,9996,9997,9998,9999,10000,10001,10002,10003,10004,10005,10006,10007, +10008,10009,10010,10011,10012,10013,10014,10015,10016,10017,10018,10019, +10020,10021,10022,10023,10024,10025,10026,10027,10028,10029,10030,10031, +10032,10033,10034,10035,10036,10037,10038,10039,10040,10041,10042,10043, +10044,10045,10046,10047,10048,10049,10050,10051,10052,10053,10054,10055, +10056,10057,10058,10059,10060,10061,10062,10063,10064,10065,10066,10067, +10068,10069,10070,10071,10072,10073,10074,10075,10076,10077,10078,10079, +10080,10081,10082,10083,10084,10085,10086,10087,10088,10089,10090,10091, +10092,10093,10094,10095,10096,10097,10098,10099,10100,10101,10102,10103, +10104,10105,10106,10107,10108,10109,10110,10111,10112,10113,10114,10115, +10116,10117,10118,10119,10120,10121,10122,10123,10124,10125,10126,10127, +10128,10129,10130,10131,10132,10133,10134,10135,10136,10137,10138,10139, +10140,10141,10142,10143,10144,10145,10146,10147,10148,10149,10150,10151, +10152,10153,10154,10155,10156,10157,10158,10159,10160,10161,10162,10163, +10164,10165,10166,10167,10168,10169,10170,10171,10172,10173,10174,10175, +10176,10177,10178,10179,10180,10181,10182,10183,10184,10185,10186,10187, +10188,10189,10190,10191,10192,10193,10194,10195,10196,10197,10198,10199, +10200,10201,10202,10203,10204,10205,10206,10207,10208,10209,10210,10211, +10212,10213,10214,10215,10216,10217,10218,10219,10220,10221,10222,10223, +10224,10225,10226,10227,10228,10229,10230,10231,10232,10233,10234,10235, +10236,10237,10238,10239,10240,10241,10242,10243,10244,10245,10246,10247, +10248,10249,10250,10251,10252,10253,10254,10255,10256,10257,10258,10259, +10260,10261,10262,10263,10264,10265,10266,10267,10268,10269,10270,10271, +10272,10273,10274,10275,10276,10277,10278,10279,10280,10281,10282,10283, +10284,10285,10286,10287,10288,10289,10290,10291,10292,10293,10294,10295, +10296,10297,10298,10299,10300,10301,10302,10303,10304,10305,10306,10307, +10308,10309,10310,10311,10312,10313,10314,10315,10316,10317,10318,10319, +10320,10321,10322,10323,10324,10325,10326,10327,10328,10329,10330,10331, +10332,10333,10334,10335,10336,10337,10338,10339,10340,10341,10342,10343, +10344,10345,10346,10347,10348,10349,10350,10351,10352,10353,10354,10355, +10356,10357,10358,10359,10360,10361,10362,10363,10364,10365,10366,10367, +10368,10369,10370,10371,10372,10373,10374,10375,10376,10377,10378,10379, +10380,10381,10382,10383,10384,10385,10386,10387,10388,10389,10390,10391, +10392,10393,10394,10395,10396,10397,10398,10399,10400,10401,10402,10403, +10404,10405,10406,10407,10408,10409,10410,10411,10412,10413,10414,10415, +10416,10417,10418,10419,10420,10421,10422,10423,10424,10425,10426,10427, +10428,10429,10430,10431,10432,10433,10434,10435,10436,10437,10438,10439, +10440,10441,10442,10443,10444,10445,10446,10447,10448,10449,10450,10451, +10452,10453,10454,10455,10456,10457,10458,10459,10460,10461,10462,10463, +10464,10465,10466,10467,10468,10469,10470,10471,10472,10473,10474,10475, +10476,10477,10478,10479,10480,10481,10482,10483,10484,10485,10486,10487, +10488,10489,10490,10491,10492,10493,10494,10495,10496,10497,10498,10499, +10500,10501,10502,10503,10504,10505,10506,10507,10508,10509,10510,10511, +10512,10513,10514,10515,10516,10517,10518,10519,10520,10521,10522,10523, +10524,10525,10526,10527,10528,10529,10530,10531,10532,10533,10534,10535, +10536,10537,10538,10539,10540,10541,10542,10543,10544,10545,10546,10547, +10548,10549,10550,10551,10552,10553,10554,10555,10556,10557,10558,10559, +10560,10561,10562,10563,10564,10565,10566,10567,10568,10569,10570,10571, +10572,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582,10583, +10584,10585,10586,10587,10588,10589,10590,10591,10592,10593,10594,10595, +10596,10597,10598,10599,10600,10601,10602,10603,10604,10605,10606,10607, +10608,10609,10610,10611,10612,10613,10614,10615,10616,10617,10618,10619, +10620,10621,10622,10623,10624,10625,10626,10627,10628,10629,10630,10631, +10632,10633,10634,10635,10636,10637,10638,10639,10640,10641,10642,10643, +10644,10645,10646,10647,10648,10649,10650,10651,10652,10653,10654,10655, +10656,10657,10658,10659,10660,10661,10662,10663,10664,10665,10666,10667, +10668,10669,10670,10671,10672,10673,10674,10675,10676,10677,10678,10679, +10680,10681,10682,10683,10684,10685,10686,10687,10688,10689,10690,10691, +10692,10693,10694,10695,10696,10697,10698,10699,10700,10701,10702,10703, +10704,10705,10706,10707,10708,10709,10710,10711,10712,10713,10714,10715, +10716,10717,10718,10719,10720,10721,10722,10723,10724,10725,10726,10727, +10728,10729,10730,10731,10732,10733,10734,10735,10736,10737,10738,10739, +10740,10741,10742,10743,10744,10745,10746,10747,10748,10749,10750,10751, +10752,10753,10754,10755,10756,10757,10758,10759,10760,10761,10762,10763, +10764,10765,10766,10767,10768,10769,10770,10771,10772,10773,10774,10775, +10776,10777,10778,10779,10780,10781,10782,10783,10784,10785,10786,10787, +10788,10789,10790,10791,10792,10793,10794,10795,10796,10797,10798,10799, +10800,10801,10802,10803,10804,10805,10806,10807,10808,10809,10810,10811, +10812,10813,10814,10815,10816,10817,10818,10819,10820,10821,10822,10823, +10824,10825,10826,10827,10828,10829,10830,10831,10832,10833,10834,10835, +10836,10837,10838,10839,10840,10841,10842,10843,10844,10845,10846,10847, +10848,10849,10850,10851,10852,10853,10854,10855,10856,10857,10858,10859, +10860,10861,10862,10863,10864,10865,10866,10867,10868,10869,10870,10871, +10872,10873,10874,10875,10876,10877,10878,10879,10880,10881,10882,10883, +10884,10885,10886,10887,10888,10889,10890,10891,10892,10893,10894,10895, +10896,10897,10898,10899,10900,10901,10902,10903,10904,10905,10906,10907, +10908,10909,10910,10911,10912,10913,10914,10915,10916,10917,10918,10919, +10920,10921,10922,10923,10924,10925,10926,10927,10928,10929,10930,10931, +10932,10933,10934,10935,10936,10937,10938,10939,10940,10941,10942,10943, +10944,10945,10946,10947,10948,10949,10950,10951,10952,10953,10954,10955, +10956,10957,10958,10959,10960,10961,10962,10963,10964,10965,10966,10967, +10968,10969,10970,10971,10972,10973,10974,10975,10976,10977,10978,10979, +10980,10981,10982,10983,10984,10985,10986,10987,10988,10989,10990,10991, +10992,10993,10994,10995,10996,10997,10998,10999,11000,11001,11002,11003, +11004,11005,11006,11007,11008,11009,11010,11011,11012,11013,11014,11015, +11016,11017,11018,11019,11020,11021,11022,11023,11024,11025,11026,11027, +11028,11029,11030,11031,11032,11033,11034,11035,11036,11037,11038,11039, +11040,11041,11042,11043,11044,11045,11046,11047,11048,11049,11050,11051, +11052,11053,11054,11055,11056,11057,11058,11059,11060,11061,11062,11063, +11064,11065,11066,11067,11068,11069,11070,11071,11072,11073,11074,11075, +11076,11077,11078,11079,11080,11081,11082,11083,11084,11085,11086,11087, +11088,11089,11090,11091,11092,11093,11094,11095,11096,11097,11098,11099, +11100,11101,11102,11103,11104,11105,11106,11107,11108,11109,11110,11111, +11112,11113,11114,11115,11116,11117,11118,11119,11120,11121,11122,11123, +11124,11125,11126,11127,11128,11129,11130,11131,11132,11133,11134,11135, +11136,11137,11138,11139,11140,11141,11142,11143,11144,11145,11146,11147, +11148,11149,11150,11151,11152,11153,11154,11155,11156,11157,11158,11159, +11160,11161,11162,11163,11164,11165,11166,11167,11168,11169,11170,11171, +11172,11173,11174,11175,11176,11177,11178,11179,11180,11181,11182,11183, +11184,11185,11186,11187,11188,11189,11190,11191,11192,11193,11194,11195, +11196,11197,11198,11199,11200,11201,11202,11203,11204,11205,11206,11207, +11208,11209,11210,11211,11212,11213,11214,11215,11216,11217,11218,11219, +11220,11221,11222,11223,11224,11225,11226,11227,11228,11229,11230,11231, +11232,11233,11234,11235,11236,11237,11238,11239,11240,11241,11242,11243, +11244,11245,11246,11247,11248,11249,11250,11251,11252,11253,11254,11255, +11256,11257,11258,11259,11260,11261,11262,11263,11264,11265,11266,11267, +11268,11269,11270,11271,11272,11273,11274,11275,11276,11277,11278,11279, +11280,11281,11282,11283,11284,11285,11286,11287,11288,11289,11290,11291, +11292,11293,11294,11295,11296,11297,11298,11299,11300,11301,11302,11303, +11304,11305,11306,11307,11308,11309,11310,11311,11264,11265,11266,11267, +11268,11269,11270,11271,11272,11273,11274,11275,11276,11277,11278,11279, +11280,11281,11282,11283,11284,11285,11286,11287,11288,11289,11290,11291, +11292,11293,11294,11295,11296,11297,11298,11299,11300,11301,11302,11303, +11304,11305,11306,11307,11308,11309,11310,11359,11360,11360,11362,11363, +11364,570,574,11367,11367,11369,11369,11371,11371,11373,11374,11375,11376, +11377,11378,11378,11380,11381,11381,11383,11384,11385,11386,11387,11388, +11389,11390,11391,11392,11392,11394,11394,11396,11396,11398,11398,11400, +11400,11402,11402,11404,11404,11406,11406,11408,11408,11410,11410,11412, +11412,11414,11414,11416,11416,11418,11418,11420,11420,11422,11422,11424, +11424,11426,11426,11428,11428,11430,11430,11432,11432,11434,11434,11436, +11436,11438,11438,11440,11440,11442,11442,11444,11444,11446,11446,11448, +11448,11450,11450,11452,11452,11454,11454,11456,11456,11458,11458,11460, +11460,11462,11462,11464,11464,11466,11466,11468,11468,11470,11470,11472, +11472,11474,11474,11476,11476,11478,11478,11480,11480,11482,11482,11484, +11484,11486,11486,11488,11488,11490,11490,11492,11493,11494,11495,11496, +11497,11498,11499,11499,11501,11501,11503,11504,11505,11506,11506,11508, +11509,11510,11511,11512,11513,11514,11515,11516,11517,11518,11519,4256, +4257,4258,4259,4260,4261,4262,4263,4264,4265,4266,4267,4268,4269,4270,4271, +4272,4273,4274,4275,4276,4277,4278,4279,4280,4281,4282,4283,4284,4285,4286, +4287,4288,4289,4290,4291,4292,4293,11558,4295,11560,11561,11562,11563, +11564,4301,11566,11567,11568,11569,11570,11571,11572,11573,11574,11575, +11576,11577,11578,11579,11580,11581,11582,11583,11584,11585,11586,11587, +11588,11589,11590,11591,11592,11593,11594,11595,11596,11597,11598,11599, +11600,11601,11602,11603,11604,11605,11606,11607,11608,11609,11610,11611, +11612,11613,11614,11615,11616,11617,11618,11619,11620,11621,11622,11623, +11624,11625,11626,11627,11628,11629,11630,11631,11632,11633,11634,11635, +11636,11637,11638,11639,11640,11641,11642,11643,11644,11645,11646,11647, +11648,11649,11650,11651,11652,11653,11654,11655,11656,11657,11658,11659, +11660,11661,11662,11663,11664,11665,11666,11667,11668,11669,11670,11671, +11672,11673,11674,11675,11676,11677,11678,11679,11680,11681,11682,11683, +11684,11685,11686,11687,11688,11689,11690,11691,11692,11693,11694,11695, +11696,11697,11698,11699,11700,11701,11702,11703,11704,11705,11706,11707, +11708,11709,11710,11711,11712,11713,11714,11715,11716,11717,11718,11719, +11720,11721,11722,11723,11724,11725,11726,11727,11728,11729,11730,11731, +11732,11733,11734,11735,11736,11737,11738,11739,11740,11741,11742,11743, +11744,11745,11746,11747,11748,11749,11750,11751,11752,11753,11754,11755, +11756,11757,11758,11759,11760,11761,11762,11763,11764,11765,11766,11767, +11768,11769,11770,11771,11772,11773,11774,11775,11776,11777,11778,11779, +11780,11781,11782,11783,11784,11785,11786,11787,11788,11789,11790,11791, +11792,11793,11794,11795,11796,11797,11798,11799,11800,11801,11802,11803, +11804,11805,11806,11807,11808,11809,11810,11811,11812,11813,11814,11815, +11816,11817,11818,11819,11820,11821,11822,11823,11824,11825,11826,11827, +11828,11829,11830,11831,11832,11833,11834,11835,11836,11837,11838,11839, +11840,11841,11842,11843,11844,11845,11846,11847,11848,11849,11850,11851, +11852,11853,11854,11855,11856,11857,11858,11859,11860,11861,11862,11863, +11864,11865,11866,11867,11868,11869,11870,11871,11872,11873,11874,11875, +11876,11877,11878,11879,11880,11881,11882,11883,11884,11885,11886,11887, +11888,11889,11890,11891,11892,11893,11894,11895,11896,11897,11898,11899, +11900,11901,11902,11903,11904,11905,11906,11907,11908,11909,11910,11911, +11912,11913,11914,11915,11916,11917,11918,11919,11920,11921,11922,11923, +11924,11925,11926,11927,11928,11929,11930,11931,11932,11933,11934,11935, +11936,11937,11938,11939,11940,11941,11942,11943,11944,11945,11946,11947, +11948,11949,11950,11951,11952,11953,11954,11955,11956,11957,11958,11959, +11960,11961,11962,11963,11964,11965,11966,11967,11968,11969,11970,11971, +11972,11973,11974,11975,11976,11977,11978,11979,11980,11981,11982,11983, +11984,11985,11986,11987,11988,11989,11990,11991,11992,11993,11994,11995, +11996,11997,11998,11999,12000,12001,12002,12003,12004,12005,12006,12007, +12008,12009,12010,12011,12012,12013,12014,12015,12016,12017,12018,12019, +12020,12021,12022,12023,12024,12025,12026,12027,12028,12029,12030,12031, +12032,12033,12034,12035,12036,12037,12038,12039,12040,12041,12042,12043, +12044,12045,12046,12047,12048,12049,12050,12051,12052,12053,12054,12055, +12056,12057,12058,12059,12060,12061,12062,12063,12064,12065,12066,12067, +12068,12069,12070,12071,12072,12073,12074,12075,12076,12077,12078,12079, +12080,12081,12082,12083,12084,12085,12086,12087,12088,12089,12090,12091, +12092,12093,12094,12095,12096,12097,12098,12099,12100,12101,12102,12103, +12104,12105,12106,12107,12108,12109,12110,12111,12112,12113,12114,12115, +12116,12117,12118,12119,12120,12121,12122,12123,12124,12125,12126,12127, +12128,12129,12130,12131,12132,12133,12134,12135,12136,12137,12138,12139, +12140,12141,12142,12143,12144,12145,12146,12147,12148,12149,12150,12151, +12152,12153,12154,12155,12156,12157,12158,12159,12160,12161,12162,12163, +12164,12165,12166,12167,12168,12169,12170,12171,12172,12173,12174,12175, +12176,12177,12178,12179,12180,12181,12182,12183,12184,12185,12186,12187, +12188,12189,12190,12191,12192,12193,12194,12195,12196,12197,12198,12199, +12200,12201,12202,12203,12204,12205,12206,12207,12208,12209,12210,12211, +12212,12213,12214,12215,12216,12217,12218,12219,12220,12221,12222,12223, +12224,12225,12226,12227,12228,12229,12230,12231,12232,12233,12234,12235, +12236,12237,12238,12239,12240,12241,12242,12243,12244,12245,12246,12247, +12248,12249,12250,12251,12252,12253,12254,12255,12256,12257,12258,12259, +12260,12261,12262,12263,12264,12265,12266,12267,12268,12269,12270,12271, +12272,12273,12274,12275,12276,12277,12278,12279,12280,12281,12282,12283, +12284,12285,12286,12287,12288,12289,12290,12291,12292,12293,12294,12295, +12296,12297,12298,12299,12300,12301,12302,12303,12304,12305,12306,12307, +12308,12309,12310,12311,12312,12313,12314,12315,12316,12317,12318,12319, +12320,12321,12322,12323,12324,12325,12326,12327,12328,12329,12330,12331, +12332,12333,12334,12335,12336,12337,12338,12339,12340,12341,12342,12343, +12344,12345,12346,12347,12348,12349,12350,12351,12352,12353,12354,12355, +12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367, +12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379, +12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391, +12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403, +12404,12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415, +12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427, +12428,12429,12430,12431,12432,12433,12434,12435,12436,12437,12438,12439, +12440,12441,12442,12443,12444,12445,12446,12447,12448,12449,12450,12451, +12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,12463, +12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475, +12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487, +12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499, +12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511, +12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523, +12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,12535, +12536,12537,12538,12539,12540,12541,12542,12543,12544,12545,12546,12547, +12548,12549,12550,12551,12552,12553,12554,12555,12556,12557,12558,12559, +12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,12570,12571, +12572,12573,12574,12575,12576,12577,12578,12579,12580,12581,12582,12583, +12584,12585,12586,12587,12588,12589,12590,12591,12592,12593,12594,12595, +12596,12597,12598,12599,12600,12601,12602,12603,12604,12605,12606,12607, +12608,12609,12610,12611,12612,12613,12614,12615,12616,12617,12618,12619, +12620,12621,12622,12623,12624,12625,12626,12627,12628,12629,12630,12631, +12632,12633,12634,12635,12636,12637,12638,12639,12640,12641,12642,12643, +12644,12645,12646,12647,12648,12649,12650,12651,12652,12653,12654,12655, +12656,12657,12658,12659,12660,12661,12662,12663,12664,12665,12666,12667, +12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679, +12680,12681,12682,12683,12684,12685,12686,12687,12688,12689,12690,12691, +12692,12693,12694,12695,12696,12697,12698,12699,12700,12701,12702,12703, +12704,12705,12706,12707,12708,12709,12710,12711,12712,12713,12714,12715, +12716,12717,12718,12719,12720,12721,12722,12723,12724,12725,12726,12727, +12728,12729,12730,12731,12732,12733,12734,12735,12736,12737,12738,12739, +12740,12741,12742,12743,12744,12745,12746,12747,12748,12749,12750,12751, +12752,12753,12754,12755,12756,12757,12758,12759,12760,12761,12762,12763, +12764,12765,12766,12767,12768,12769,12770,12771,12772,12773,12774,12775, +12776,12777,12778,12779,12780,12781,12782,12783,12784,12785,12786,12787, +12788,12789,12790,12791,12792,12793,12794,12795,12796,12797,12798,12799, +12800,12801,12802,12803,12804,12805,12806,12807,12808,12809,12810,12811, +12812,12813,12814,12815,12816,12817,12818,12819,12820,12821,12822,12823, +12824,12825,12826,12827,12828,12829,12830,12831,12832,12833,12834,12835, +12836,12837,12838,12839,12840,12841,12842,12843,12844,12845,12846,12847, +12848,12849,12850,12851,12852,12853,12854,12855,12856,12857,12858,12859, +12860,12861,12862,12863,12864,12865,12866,12867,12868,12869,12870,12871, +12872,12873,12874,12875,12876,12877,12878,12879,12880,12881,12882,12883, +12884,12885,12886,12887,12888,12889,12890,12891,12892,12893,12894,12895, +12896,12897,12898,12899,12900,12901,12902,12903,12904,12905,12906,12907, +12908,12909,12910,12911,12912,12913,12914,12915,12916,12917,12918,12919, +12920,12921,12922,12923,12924,12925,12926,12927,12928,12929,12930,12931, +12932,12933,12934,12935,12936,12937,12938,12939,12940,12941,12942,12943, +12944,12945,12946,12947,12948,12949,12950,12951,12952,12953,12954,12955, +12956,12957,12958,12959,12960,12961,12962,12963,12964,12965,12966,12967, +12968,12969,12970,12971,12972,12973,12974,12975,12976,12977,12978,12979, +12980,12981,12982,12983,12984,12985,12986,12987,12988,12989,12990,12991, +12992,12993,12994,12995,12996,12997,12998,12999,13000,13001,13002,13003, +13004,13005,13006,13007,13008,13009,13010,13011,13012,13013,13014,13015, +13016,13017,13018,13019,13020,13021,13022,13023,13024,13025,13026,13027, +13028,13029,13030,13031,13032,13033,13034,13035,13036,13037,13038,13039, +13040,13041,13042,13043,13044,13045,13046,13047,13048,13049,13050,13051, +13052,13053,13054,13055,13056,13057,13058,13059,13060,13061,13062,13063, +13064,13065,13066,13067,13068,13069,13070,13071,13072,13073,13074,13075, +13076,13077,13078,13079,13080,13081,13082,13083,13084,13085,13086,13087, +13088,13089,13090,13091,13092,13093,13094,13095,13096,13097,13098,13099, +13100,13101,13102,13103,13104,13105,13106,13107,13108,13109,13110,13111, +13112,13113,13114,13115,13116,13117,13118,13119,13120,13121,13122,13123, +13124,13125,13126,13127,13128,13129,13130,13131,13132,13133,13134,13135, +13136,13137,13138,13139,13140,13141,13142,13143,13144,13145,13146,13147, +13148,13149,13150,13151,13152,13153,13154,13155,13156,13157,13158,13159, +13160,13161,13162,13163,13164,13165,13166,13167,13168,13169,13170,13171, +13172,13173,13174,13175,13176,13177,13178,13179,13180,13181,13182,13183, +13184,13185,13186,13187,13188,13189,13190,13191,13192,13193,13194,13195, +13196,13197,13198,13199,13200,13201,13202,13203,13204,13205,13206,13207, +13208,13209,13210,13211,13212,13213,13214,13215,13216,13217,13218,13219, +13220,13221,13222,13223,13224,13225,13226,13227,13228,13229,13230,13231, +13232,13233,13234,13235,13236,13237,13238,13239,13240,13241,13242,13243, +13244,13245,13246,13247,13248,13249,13250,13251,13252,13253,13254,13255, +13256,13257,13258,13259,13260,13261,13262,13263,13264,13265,13266,13267, +13268,13269,13270,13271,13272,13273,13274,13275,13276,13277,13278,13279, +13280,13281,13282,13283,13284,13285,13286,13287,13288,13289,13290,13291, +13292,13293,13294,13295,13296,13297,13298,13299,13300,13301,13302,13303, +13304,13305,13306,13307,13308,13309,13310,13311,13312,13313,13314,13315, +13316,13317,13318,13319,13320,13321,13322,13323,13324,13325,13326,13327, +13328,13329,13330,13331,13332,13333,13334,13335,13336,13337,13338,13339, +13340,13341,13342,13343,13344,13345,13346,13347,13348,13349,13350,13351, +13352,13353,13354,13355,13356,13357,13358,13359,13360,13361,13362,13363, +13364,13365,13366,13367,13368,13369,13370,13371,13372,13373,13374,13375, +13376,13377,13378,13379,13380,13381,13382,13383,13384,13385,13386,13387, +13388,13389,13390,13391,13392,13393,13394,13395,13396,13397,13398,13399, +13400,13401,13402,13403,13404,13405,13406,13407,13408,13409,13410,13411, +13412,13413,13414,13415,13416,13417,13418,13419,13420,13421,13422,13423, +13424,13425,13426,13427,13428,13429,13430,13431,13432,13433,13434,13435, +13436,13437,13438,13439,13440,13441,13442,13443,13444,13445,13446,13447, +13448,13449,13450,13451,13452,13453,13454,13455,13456,13457,13458,13459, +13460,13461,13462,13463,13464,13465,13466,13467,13468,13469,13470,13471, +13472,13473,13474,13475,13476,13477,13478,13479,13480,13481,13482,13483, +13484,13485,13486,13487,13488,13489,13490,13491,13492,13493,13494,13495, +13496,13497,13498,13499,13500,13501,13502,13503,13504,13505,13506,13507, +13508,13509,13510,13511,13512,13513,13514,13515,13516,13517,13518,13519, +13520,13521,13522,13523,13524,13525,13526,13527,13528,13529,13530,13531, +13532,13533,13534,13535,13536,13537,13538,13539,13540,13541,13542,13543, +13544,13545,13546,13547,13548,13549,13550,13551,13552,13553,13554,13555, +13556,13557,13558,13559,13560,13561,13562,13563,13564,13565,13566,13567, +13568,13569,13570,13571,13572,13573,13574,13575,13576,13577,13578,13579, +13580,13581,13582,13583,13584,13585,13586,13587,13588,13589,13590,13591, +13592,13593,13594,13595,13596,13597,13598,13599,13600,13601,13602,13603, +13604,13605,13606,13607,13608,13609,13610,13611,13612,13613,13614,13615, +13616,13617,13618,13619,13620,13621,13622,13623,13624,13625,13626,13627, +13628,13629,13630,13631,13632,13633,13634,13635,13636,13637,13638,13639, +13640,13641,13642,13643,13644,13645,13646,13647,13648,13649,13650,13651, +13652,13653,13654,13655,13656,13657,13658,13659,13660,13661,13662,13663, +13664,13665,13666,13667,13668,13669,13670,13671,13672,13673,13674,13675, +13676,13677,13678,13679,13680,13681,13682,13683,13684,13685,13686,13687, +13688,13689,13690,13691,13692,13693,13694,13695,13696,13697,13698,13699, +13700,13701,13702,13703,13704,13705,13706,13707,13708,13709,13710,13711, +13712,13713,13714,13715,13716,13717,13718,13719,13720,13721,13722,13723, +13724,13725,13726,13727,13728,13729,13730,13731,13732,13733,13734,13735, +13736,13737,13738,13739,13740,13741,13742,13743,13744,13745,13746,13747, +13748,13749,13750,13751,13752,13753,13754,13755,13756,13757,13758,13759, +13760,13761,13762,13763,13764,13765,13766,13767,13768,13769,13770,13771, +13772,13773,13774,13775,13776,13777,13778,13779,13780,13781,13782,13783, +13784,13785,13786,13787,13788,13789,13790,13791,13792,13793,13794,13795, +13796,13797,13798,13799,13800,13801,13802,13803,13804,13805,13806,13807, +13808,13809,13810,13811,13812,13813,13814,13815,13816,13817,13818,13819, +13820,13821,13822,13823,13824,13825,13826,13827,13828,13829,13830,13831, +13832,13833,13834,13835,13836,13837,13838,13839,13840,13841,13842,13843, +13844,13845,13846,13847,13848,13849,13850,13851,13852,13853,13854,13855, +13856,13857,13858,13859,13860,13861,13862,13863,13864,13865,13866,13867, +13868,13869,13870,13871,13872,13873,13874,13875,13876,13877,13878,13879, +13880,13881,13882,13883,13884,13885,13886,13887,13888,13889,13890,13891, +13892,13893,13894,13895,13896,13897,13898,13899,13900,13901,13902,13903, +13904,13905,13906,13907,13908,13909,13910,13911,13912,13913,13914,13915, +13916,13917,13918,13919,13920,13921,13922,13923,13924,13925,13926,13927, +13928,13929,13930,13931,13932,13933,13934,13935,13936,13937,13938,13939, +13940,13941,13942,13943,13944,13945,13946,13947,13948,13949,13950,13951, +13952,13953,13954,13955,13956,13957,13958,13959,13960,13961,13962,13963, +13964,13965,13966,13967,13968,13969,13970,13971,13972,13973,13974,13975, +13976,13977,13978,13979,13980,13981,13982,13983,13984,13985,13986,13987, +13988,13989,13990,13991,13992,13993,13994,13995,13996,13997,13998,13999, +14000,14001,14002,14003,14004,14005,14006,14007,14008,14009,14010,14011, +14012,14013,14014,14015,14016,14017,14018,14019,14020,14021,14022,14023, +14024,14025,14026,14027,14028,14029,14030,14031,14032,14033,14034,14035, +14036,14037,14038,14039,14040,14041,14042,14043,14044,14045,14046,14047, +14048,14049,14050,14051,14052,14053,14054,14055,14056,14057,14058,14059, +14060,14061,14062,14063,14064,14065,14066,14067,14068,14069,14070,14071, +14072,14073,14074,14075,14076,14077,14078,14079,14080,14081,14082,14083, +14084,14085,14086,14087,14088,14089,14090,14091,14092,14093,14094,14095, +14096,14097,14098,14099,14100,14101,14102,14103,14104,14105,14106,14107, +14108,14109,14110,14111,14112,14113,14114,14115,14116,14117,14118,14119, +14120,14121,14122,14123,14124,14125,14126,14127,14128,14129,14130,14131, +14132,14133,14134,14135,14136,14137,14138,14139,14140,14141,14142,14143, +14144,14145,14146,14147,14148,14149,14150,14151,14152,14153,14154,14155, +14156,14157,14158,14159,14160,14161,14162,14163,14164,14165,14166,14167, +14168,14169,14170,14171,14172,14173,14174,14175,14176,14177,14178,14179, +14180,14181,14182,14183,14184,14185,14186,14187,14188,14189,14190,14191, +14192,14193,14194,14195,14196,14197,14198,14199,14200,14201,14202,14203, +14204,14205,14206,14207,14208,14209,14210,14211,14212,14213,14214,14215, +14216,14217,14218,14219,14220,14221,14222,14223,14224,14225,14226,14227, +14228,14229,14230,14231,14232,14233,14234,14235,14236,14237,14238,14239, +14240,14241,14242,14243,14244,14245,14246,14247,14248,14249,14250,14251, +14252,14253,14254,14255,14256,14257,14258,14259,14260,14261,14262,14263, +14264,14265,14266,14267,14268,14269,14270,14271,14272,14273,14274,14275, +14276,14277,14278,14279,14280,14281,14282,14283,14284,14285,14286,14287, +14288,14289,14290,14291,14292,14293,14294,14295,14296,14297,14298,14299, +14300,14301,14302,14303,14304,14305,14306,14307,14308,14309,14310,14311, +14312,14313,14314,14315,14316,14317,14318,14319,14320,14321,14322,14323, +14324,14325,14326,14327,14328,14329,14330,14331,14332,14333,14334,14335, +14336,14337,14338,14339,14340,14341,14342,14343,14344,14345,14346,14347, +14348,14349,14350,14351,14352,14353,14354,14355,14356,14357,14358,14359, +14360,14361,14362,14363,14364,14365,14366,14367,14368,14369,14370,14371, +14372,14373,14374,14375,14376,14377,14378,14379,14380,14381,14382,14383, +14384,14385,14386,14387,14388,14389,14390,14391,14392,14393,14394,14395, +14396,14397,14398,14399,14400,14401,14402,14403,14404,14405,14406,14407, +14408,14409,14410,14411,14412,14413,14414,14415,14416,14417,14418,14419, +14420,14421,14422,14423,14424,14425,14426,14427,14428,14429,14430,14431, +14432,14433,14434,14435,14436,14437,14438,14439,14440,14441,14442,14443, +14444,14445,14446,14447,14448,14449,14450,14451,14452,14453,14454,14455, +14456,14457,14458,14459,14460,14461,14462,14463,14464,14465,14466,14467, +14468,14469,14470,14471,14472,14473,14474,14475,14476,14477,14478,14479, +14480,14481,14482,14483,14484,14485,14486,14487,14488,14489,14490,14491, +14492,14493,14494,14495,14496,14497,14498,14499,14500,14501,14502,14503, +14504,14505,14506,14507,14508,14509,14510,14511,14512,14513,14514,14515, +14516,14517,14518,14519,14520,14521,14522,14523,14524,14525,14526,14527, +14528,14529,14530,14531,14532,14533,14534,14535,14536,14537,14538,14539, +14540,14541,14542,14543,14544,14545,14546,14547,14548,14549,14550,14551, +14552,14553,14554,14555,14556,14557,14558,14559,14560,14561,14562,14563, +14564,14565,14566,14567,14568,14569,14570,14571,14572,14573,14574,14575, +14576,14577,14578,14579,14580,14581,14582,14583,14584,14585,14586,14587, +14588,14589,14590,14591,14592,14593,14594,14595,14596,14597,14598,14599, +14600,14601,14602,14603,14604,14605,14606,14607,14608,14609,14610,14611, +14612,14613,14614,14615,14616,14617,14618,14619,14620,14621,14622,14623, +14624,14625,14626,14627,14628,14629,14630,14631,14632,14633,14634,14635, +14636,14637,14638,14639,14640,14641,14642,14643,14644,14645,14646,14647, +14648,14649,14650,14651,14652,14653,14654,14655,14656,14657,14658,14659, +14660,14661,14662,14663,14664,14665,14666,14667,14668,14669,14670,14671, +14672,14673,14674,14675,14676,14677,14678,14679,14680,14681,14682,14683, +14684,14685,14686,14687,14688,14689,14690,14691,14692,14693,14694,14695, +14696,14697,14698,14699,14700,14701,14702,14703,14704,14705,14706,14707, +14708,14709,14710,14711,14712,14713,14714,14715,14716,14717,14718,14719, +14720,14721,14722,14723,14724,14725,14726,14727,14728,14729,14730,14731, +14732,14733,14734,14735,14736,14737,14738,14739,14740,14741,14742,14743, +14744,14745,14746,14747,14748,14749,14750,14751,14752,14753,14754,14755, +14756,14757,14758,14759,14760,14761,14762,14763,14764,14765,14766,14767, +14768,14769,14770,14771,14772,14773,14774,14775,14776,14777,14778,14779, +14780,14781,14782,14783,14784,14785,14786,14787,14788,14789,14790,14791, +14792,14793,14794,14795,14796,14797,14798,14799,14800,14801,14802,14803, +14804,14805,14806,14807,14808,14809,14810,14811,14812,14813,14814,14815, +14816,14817,14818,14819,14820,14821,14822,14823,14824,14825,14826,14827, +14828,14829,14830,14831,14832,14833,14834,14835,14836,14837,14838,14839, +14840,14841,14842,14843,14844,14845,14846,14847,14848,14849,14850,14851, +14852,14853,14854,14855,14856,14857,14858,14859,14860,14861,14862,14863, +14864,14865,14866,14867,14868,14869,14870,14871,14872,14873,14874,14875, +14876,14877,14878,14879,14880,14881,14882,14883,14884,14885,14886,14887, +14888,14889,14890,14891,14892,14893,14894,14895,14896,14897,14898,14899, +14900,14901,14902,14903,14904,14905,14906,14907,14908,14909,14910,14911, +14912,14913,14914,14915,14916,14917,14918,14919,14920,14921,14922,14923, +14924,14925,14926,14927,14928,14929,14930,14931,14932,14933,14934,14935, +14936,14937,14938,14939,14940,14941,14942,14943,14944,14945,14946,14947, +14948,14949,14950,14951,14952,14953,14954,14955,14956,14957,14958,14959, +14960,14961,14962,14963,14964,14965,14966,14967,14968,14969,14970,14971, +14972,14973,14974,14975,14976,14977,14978,14979,14980,14981,14982,14983, +14984,14985,14986,14987,14988,14989,14990,14991,14992,14993,14994,14995, +14996,14997,14998,14999,15000,15001,15002,15003,15004,15005,15006,15007, +15008,15009,15010,15011,15012,15013,15014,15015,15016,15017,15018,15019, +15020,15021,15022,15023,15024,15025,15026,15027,15028,15029,15030,15031, +15032,15033,15034,15035,15036,15037,15038,15039,15040,15041,15042,15043, +15044,15045,15046,15047,15048,15049,15050,15051,15052,15053,15054,15055, +15056,15057,15058,15059,15060,15061,15062,15063,15064,15065,15066,15067, +15068,15069,15070,15071,15072,15073,15074,15075,15076,15077,15078,15079, +15080,15081,15082,15083,15084,15085,15086,15087,15088,15089,15090,15091, +15092,15093,15094,15095,15096,15097,15098,15099,15100,15101,15102,15103, +15104,15105,15106,15107,15108,15109,15110,15111,15112,15113,15114,15115, +15116,15117,15118,15119,15120,15121,15122,15123,15124,15125,15126,15127, +15128,15129,15130,15131,15132,15133,15134,15135,15136,15137,15138,15139, +15140,15141,15142,15143,15144,15145,15146,15147,15148,15149,15150,15151, +15152,15153,15154,15155,15156,15157,15158,15159,15160,15161,15162,15163, +15164,15165,15166,15167,15168,15169,15170,15171,15172,15173,15174,15175, +15176,15177,15178,15179,15180,15181,15182,15183,15184,15185,15186,15187, +15188,15189,15190,15191,15192,15193,15194,15195,15196,15197,15198,15199, +15200,15201,15202,15203,15204,15205,15206,15207,15208,15209,15210,15211, +15212,15213,15214,15215,15216,15217,15218,15219,15220,15221,15222,15223, +15224,15225,15226,15227,15228,15229,15230,15231,15232,15233,15234,15235, +15236,15237,15238,15239,15240,15241,15242,15243,15244,15245,15246,15247, +15248,15249,15250,15251,15252,15253,15254,15255,15256,15257,15258,15259, +15260,15261,15262,15263,15264,15265,15266,15267,15268,15269,15270,15271, +15272,15273,15274,15275,15276,15277,15278,15279,15280,15281,15282,15283, +15284,15285,15286,15287,15288,15289,15290,15291,15292,15293,15294,15295, +15296,15297,15298,15299,15300,15301,15302,15303,15304,15305,15306,15307, +15308,15309,15310,15311,15312,15313,15314,15315,15316,15317,15318,15319, +15320,15321,15322,15323,15324,15325,15326,15327,15328,15329,15330,15331, +15332,15333,15334,15335,15336,15337,15338,15339,15340,15341,15342,15343, +15344,15345,15346,15347,15348,15349,15350,15351,15352,15353,15354,15355, +15356,15357,15358,15359,15360,15361,15362,15363,15364,15365,15366,15367, +15368,15369,15370,15371,15372,15373,15374,15375,15376,15377,15378,15379, +15380,15381,15382,15383,15384,15385,15386,15387,15388,15389,15390,15391, +15392,15393,15394,15395,15396,15397,15398,15399,15400,15401,15402,15403, +15404,15405,15406,15407,15408,15409,15410,15411,15412,15413,15414,15415, +15416,15417,15418,15419,15420,15421,15422,15423,15424,15425,15426,15427, +15428,15429,15430,15431,15432,15433,15434,15435,15436,15437,15438,15439, +15440,15441,15442,15443,15444,15445,15446,15447,15448,15449,15450,15451, +15452,15453,15454,15455,15456,15457,15458,15459,15460,15461,15462,15463, +15464,15465,15466,15467,15468,15469,15470,15471,15472,15473,15474,15475, +15476,15477,15478,15479,15480,15481,15482,15483,15484,15485,15486,15487, +15488,15489,15490,15491,15492,15493,15494,15495,15496,15497,15498,15499, +15500,15501,15502,15503,15504,15505,15506,15507,15508,15509,15510,15511, +15512,15513,15514,15515,15516,15517,15518,15519,15520,15521,15522,15523, +15524,15525,15526,15527,15528,15529,15530,15531,15532,15533,15534,15535, +15536,15537,15538,15539,15540,15541,15542,15543,15544,15545,15546,15547, +15548,15549,15550,15551,15552,15553,15554,15555,15556,15557,15558,15559, +15560,15561,15562,15563,15564,15565,15566,15567,15568,15569,15570,15571, +15572,15573,15574,15575,15576,15577,15578,15579,15580,15581,15582,15583, +15584,15585,15586,15587,15588,15589,15590,15591,15592,15593,15594,15595, +15596,15597,15598,15599,15600,15601,15602,15603,15604,15605,15606,15607, +15608,15609,15610,15611,15612,15613,15614,15615,15616,15617,15618,15619, +15620,15621,15622,15623,15624,15625,15626,15627,15628,15629,15630,15631, +15632,15633,15634,15635,15636,15637,15638,15639,15640,15641,15642,15643, +15644,15645,15646,15647,15648,15649,15650,15651,15652,15653,15654,15655, +15656,15657,15658,15659,15660,15661,15662,15663,15664,15665,15666,15667, +15668,15669,15670,15671,15672,15673,15674,15675,15676,15677,15678,15679, +15680,15681,15682,15683,15684,15685,15686,15687,15688,15689,15690,15691, +15692,15693,15694,15695,15696,15697,15698,15699,15700,15701,15702,15703, +15704,15705,15706,15707,15708,15709,15710,15711,15712,15713,15714,15715, +15716,15717,15718,15719,15720,15721,15722,15723,15724,15725,15726,15727, +15728,15729,15730,15731,15732,15733,15734,15735,15736,15737,15738,15739, +15740,15741,15742,15743,15744,15745,15746,15747,15748,15749,15750,15751, +15752,15753,15754,15755,15756,15757,15758,15759,15760,15761,15762,15763, +15764,15765,15766,15767,15768,15769,15770,15771,15772,15773,15774,15775, +15776,15777,15778,15779,15780,15781,15782,15783,15784,15785,15786,15787, +15788,15789,15790,15791,15792,15793,15794,15795,15796,15797,15798,15799, +15800,15801,15802,15803,15804,15805,15806,15807,15808,15809,15810,15811, +15812,15813,15814,15815,15816,15817,15818,15819,15820,15821,15822,15823, +15824,15825,15826,15827,15828,15829,15830,15831,15832,15833,15834,15835, +15836,15837,15838,15839,15840,15841,15842,15843,15844,15845,15846,15847, +15848,15849,15850,15851,15852,15853,15854,15855,15856,15857,15858,15859, +15860,15861,15862,15863,15864,15865,15866,15867,15868,15869,15870,15871, +15872,15873,15874,15875,15876,15877,15878,15879,15880,15881,15882,15883, +15884,15885,15886,15887,15888,15889,15890,15891,15892,15893,15894,15895, +15896,15897,15898,15899,15900,15901,15902,15903,15904,15905,15906,15907, +15908,15909,15910,15911,15912,15913,15914,15915,15916,15917,15918,15919, +15920,15921,15922,15923,15924,15925,15926,15927,15928,15929,15930,15931, +15932,15933,15934,15935,15936,15937,15938,15939,15940,15941,15942,15943, +15944,15945,15946,15947,15948,15949,15950,15951,15952,15953,15954,15955, +15956,15957,15958,15959,15960,15961,15962,15963,15964,15965,15966,15967, +15968,15969,15970,15971,15972,15973,15974,15975,15976,15977,15978,15979, +15980,15981,15982,15983,15984,15985,15986,15987,15988,15989,15990,15991, +15992,15993,15994,15995,15996,15997,15998,15999,16000,16001,16002,16003, +16004,16005,16006,16007,16008,16009,16010,16011,16012,16013,16014,16015, +16016,16017,16018,16019,16020,16021,16022,16023,16024,16025,16026,16027, +16028,16029,16030,16031,16032,16033,16034,16035,16036,16037,16038,16039, +16040,16041,16042,16043,16044,16045,16046,16047,16048,16049,16050,16051, +16052,16053,16054,16055,16056,16057,16058,16059,16060,16061,16062,16063, +16064,16065,16066,16067,16068,16069,16070,16071,16072,16073,16074,16075, +16076,16077,16078,16079,16080,16081,16082,16083,16084,16085,16086,16087, +16088,16089,16090,16091,16092,16093,16094,16095,16096,16097,16098,16099, +16100,16101,16102,16103,16104,16105,16106,16107,16108,16109,16110,16111, +16112,16113,16114,16115,16116,16117,16118,16119,16120,16121,16122,16123, +16124,16125,16126,16127,16128,16129,16130,16131,16132,16133,16134,16135, +16136,16137,16138,16139,16140,16141,16142,16143,16144,16145,16146,16147, +16148,16149,16150,16151,16152,16153,16154,16155,16156,16157,16158,16159, +16160,16161,16162,16163,16164,16165,16166,16167,16168,16169,16170,16171, +16172,16173,16174,16175,16176,16177,16178,16179,16180,16181,16182,16183, +16184,16185,16186,16187,16188,16189,16190,16191,16192,16193,16194,16195, +16196,16197,16198,16199,16200,16201,16202,16203,16204,16205,16206,16207, +16208,16209,16210,16211,16212,16213,16214,16215,16216,16217,16218,16219, +16220,16221,16222,16223,16224,16225,16226,16227,16228,16229,16230,16231, +16232,16233,16234,16235,16236,16237,16238,16239,16240,16241,16242,16243, +16244,16245,16246,16247,16248,16249,16250,16251,16252,16253,16254,16255, +16256,16257,16258,16259,16260,16261,16262,16263,16264,16265,16266,16267, +16268,16269,16270,16271,16272,16273,16274,16275,16276,16277,16278,16279, +16280,16281,16282,16283,16284,16285,16286,16287,16288,16289,16290,16291, +16292,16293,16294,16295,16296,16297,16298,16299,16300,16301,16302,16303, +16304,16305,16306,16307,16308,16309,16310,16311,16312,16313,16314,16315, +16316,16317,16318,16319,16320,16321,16322,16323,16324,16325,16326,16327, +16328,16329,16330,16331,16332,16333,16334,16335,16336,16337,16338,16339, +16340,16341,16342,16343,16344,16345,16346,16347,16348,16349,16350,16351, +16352,16353,16354,16355,16356,16357,16358,16359,16360,16361,16362,16363, +16364,16365,16366,16367,16368,16369,16370,16371,16372,16373,16374,16375, +16376,16377,16378,16379,16380,16381,16382,16383,16384,16385,16386,16387, +16388,16389,16390,16391,16392,16393,16394,16395,16396,16397,16398,16399, +16400,16401,16402,16403,16404,16405,16406,16407,16408,16409,16410,16411, +16412,16413,16414,16415,16416,16417,16418,16419,16420,16421,16422,16423, +16424,16425,16426,16427,16428,16429,16430,16431,16432,16433,16434,16435, +16436,16437,16438,16439,16440,16441,16442,16443,16444,16445,16446,16447, +16448,16449,16450,16451,16452,16453,16454,16455,16456,16457,16458,16459, +16460,16461,16462,16463,16464,16465,16466,16467,16468,16469,16470,16471, +16472,16473,16474,16475,16476,16477,16478,16479,16480,16481,16482,16483, +16484,16485,16486,16487,16488,16489,16490,16491,16492,16493,16494,16495, +16496,16497,16498,16499,16500,16501,16502,16503,16504,16505,16506,16507, +16508,16509,16510,16511,16512,16513,16514,16515,16516,16517,16518,16519, +16520,16521,16522,16523,16524,16525,16526,16527,16528,16529,16530,16531, +16532,16533,16534,16535,16536,16537,16538,16539,16540,16541,16542,16543, +16544,16545,16546,16547,16548,16549,16550,16551,16552,16553,16554,16555, +16556,16557,16558,16559,16560,16561,16562,16563,16564,16565,16566,16567, +16568,16569,16570,16571,16572,16573,16574,16575,16576,16577,16578,16579, +16580,16581,16582,16583,16584,16585,16586,16587,16588,16589,16590,16591, +16592,16593,16594,16595,16596,16597,16598,16599,16600,16601,16602,16603, +16604,16605,16606,16607,16608,16609,16610,16611,16612,16613,16614,16615, +16616,16617,16618,16619,16620,16621,16622,16623,16624,16625,16626,16627, +16628,16629,16630,16631,16632,16633,16634,16635,16636,16637,16638,16639, +16640,16641,16642,16643,16644,16645,16646,16647,16648,16649,16650,16651, +16652,16653,16654,16655,16656,16657,16658,16659,16660,16661,16662,16663, +16664,16665,16666,16667,16668,16669,16670,16671,16672,16673,16674,16675, +16676,16677,16678,16679,16680,16681,16682,16683,16684,16685,16686,16687, +16688,16689,16690,16691,16692,16693,16694,16695,16696,16697,16698,16699, +16700,16701,16702,16703,16704,16705,16706,16707,16708,16709,16710,16711, +16712,16713,16714,16715,16716,16717,16718,16719,16720,16721,16722,16723, +16724,16725,16726,16727,16728,16729,16730,16731,16732,16733,16734,16735, +16736,16737,16738,16739,16740,16741,16742,16743,16744,16745,16746,16747, +16748,16749,16750,16751,16752,16753,16754,16755,16756,16757,16758,16759, +16760,16761,16762,16763,16764,16765,16766,16767,16768,16769,16770,16771, +16772,16773,16774,16775,16776,16777,16778,16779,16780,16781,16782,16783, +16784,16785,16786,16787,16788,16789,16790,16791,16792,16793,16794,16795, +16796,16797,16798,16799,16800,16801,16802,16803,16804,16805,16806,16807, +16808,16809,16810,16811,16812,16813,16814,16815,16816,16817,16818,16819, +16820,16821,16822,16823,16824,16825,16826,16827,16828,16829,16830,16831, +16832,16833,16834,16835,16836,16837,16838,16839,16840,16841,16842,16843, +16844,16845,16846,16847,16848,16849,16850,16851,16852,16853,16854,16855, +16856,16857,16858,16859,16860,16861,16862,16863,16864,16865,16866,16867, +16868,16869,16870,16871,16872,16873,16874,16875,16876,16877,16878,16879, +16880,16881,16882,16883,16884,16885,16886,16887,16888,16889,16890,16891, +16892,16893,16894,16895,16896,16897,16898,16899,16900,16901,16902,16903, +16904,16905,16906,16907,16908,16909,16910,16911,16912,16913,16914,16915, +16916,16917,16918,16919,16920,16921,16922,16923,16924,16925,16926,16927, +16928,16929,16930,16931,16932,16933,16934,16935,16936,16937,16938,16939, +16940,16941,16942,16943,16944,16945,16946,16947,16948,16949,16950,16951, +16952,16953,16954,16955,16956,16957,16958,16959,16960,16961,16962,16963, +16964,16965,16966,16967,16968,16969,16970,16971,16972,16973,16974,16975, +16976,16977,16978,16979,16980,16981,16982,16983,16984,16985,16986,16987, +16988,16989,16990,16991,16992,16993,16994,16995,16996,16997,16998,16999, +17000,17001,17002,17003,17004,17005,17006,17007,17008,17009,17010,17011, +17012,17013,17014,17015,17016,17017,17018,17019,17020,17021,17022,17023, +17024,17025,17026,17027,17028,17029,17030,17031,17032,17033,17034,17035, +17036,17037,17038,17039,17040,17041,17042,17043,17044,17045,17046,17047, +17048,17049,17050,17051,17052,17053,17054,17055,17056,17057,17058,17059, +17060,17061,17062,17063,17064,17065,17066,17067,17068,17069,17070,17071, +17072,17073,17074,17075,17076,17077,17078,17079,17080,17081,17082,17083, +17084,17085,17086,17087,17088,17089,17090,17091,17092,17093,17094,17095, +17096,17097,17098,17099,17100,17101,17102,17103,17104,17105,17106,17107, +17108,17109,17110,17111,17112,17113,17114,17115,17116,17117,17118,17119, +17120,17121,17122,17123,17124,17125,17126,17127,17128,17129,17130,17131, +17132,17133,17134,17135,17136,17137,17138,17139,17140,17141,17142,17143, +17144,17145,17146,17147,17148,17149,17150,17151,17152,17153,17154,17155, +17156,17157,17158,17159,17160,17161,17162,17163,17164,17165,17166,17167, +17168,17169,17170,17171,17172,17173,17174,17175,17176,17177,17178,17179, +17180,17181,17182,17183,17184,17185,17186,17187,17188,17189,17190,17191, +17192,17193,17194,17195,17196,17197,17198,17199,17200,17201,17202,17203, +17204,17205,17206,17207,17208,17209,17210,17211,17212,17213,17214,17215, +17216,17217,17218,17219,17220,17221,17222,17223,17224,17225,17226,17227, +17228,17229,17230,17231,17232,17233,17234,17235,17236,17237,17238,17239, +17240,17241,17242,17243,17244,17245,17246,17247,17248,17249,17250,17251, +17252,17253,17254,17255,17256,17257,17258,17259,17260,17261,17262,17263, +17264,17265,17266,17267,17268,17269,17270,17271,17272,17273,17274,17275, +17276,17277,17278,17279,17280,17281,17282,17283,17284,17285,17286,17287, +17288,17289,17290,17291,17292,17293,17294,17295,17296,17297,17298,17299, +17300,17301,17302,17303,17304,17305,17306,17307,17308,17309,17310,17311, +17312,17313,17314,17315,17316,17317,17318,17319,17320,17321,17322,17323, +17324,17325,17326,17327,17328,17329,17330,17331,17332,17333,17334,17335, +17336,17337,17338,17339,17340,17341,17342,17343,17344,17345,17346,17347, +17348,17349,17350,17351,17352,17353,17354,17355,17356,17357,17358,17359, +17360,17361,17362,17363,17364,17365,17366,17367,17368,17369,17370,17371, +17372,17373,17374,17375,17376,17377,17378,17379,17380,17381,17382,17383, +17384,17385,17386,17387,17388,17389,17390,17391,17392,17393,17394,17395, +17396,17397,17398,17399,17400,17401,17402,17403,17404,17405,17406,17407, +17408,17409,17410,17411,17412,17413,17414,17415,17416,17417,17418,17419, +17420,17421,17422,17423,17424,17425,17426,17427,17428,17429,17430,17431, +17432,17433,17434,17435,17436,17437,17438,17439,17440,17441,17442,17443, +17444,17445,17446,17447,17448,17449,17450,17451,17452,17453,17454,17455, +17456,17457,17458,17459,17460,17461,17462,17463,17464,17465,17466,17467, +17468,17469,17470,17471,17472,17473,17474,17475,17476,17477,17478,17479, +17480,17481,17482,17483,17484,17485,17486,17487,17488,17489,17490,17491, +17492,17493,17494,17495,17496,17497,17498,17499,17500,17501,17502,17503, +17504,17505,17506,17507,17508,17509,17510,17511,17512,17513,17514,17515, +17516,17517,17518,17519,17520,17521,17522,17523,17524,17525,17526,17527, +17528,17529,17530,17531,17532,17533,17534,17535,17536,17537,17538,17539, +17540,17541,17542,17543,17544,17545,17546,17547,17548,17549,17550,17551, +17552,17553,17554,17555,17556,17557,17558,17559,17560,17561,17562,17563, +17564,17565,17566,17567,17568,17569,17570,17571,17572,17573,17574,17575, +17576,17577,17578,17579,17580,17581,17582,17583,17584,17585,17586,17587, +17588,17589,17590,17591,17592,17593,17594,17595,17596,17597,17598,17599, +17600,17601,17602,17603,17604,17605,17606,17607,17608,17609,17610,17611, +17612,17613,17614,17615,17616,17617,17618,17619,17620,17621,17622,17623, +17624,17625,17626,17627,17628,17629,17630,17631,17632,17633,17634,17635, +17636,17637,17638,17639,17640,17641,17642,17643,17644,17645,17646,17647, +17648,17649,17650,17651,17652,17653,17654,17655,17656,17657,17658,17659, +17660,17661,17662,17663,17664,17665,17666,17667,17668,17669,17670,17671, +17672,17673,17674,17675,17676,17677,17678,17679,17680,17681,17682,17683, +17684,17685,17686,17687,17688,17689,17690,17691,17692,17693,17694,17695, +17696,17697,17698,17699,17700,17701,17702,17703,17704,17705,17706,17707, +17708,17709,17710,17711,17712,17713,17714,17715,17716,17717,17718,17719, +17720,17721,17722,17723,17724,17725,17726,17727,17728,17729,17730,17731, +17732,17733,17734,17735,17736,17737,17738,17739,17740,17741,17742,17743, +17744,17745,17746,17747,17748,17749,17750,17751,17752,17753,17754,17755, +17756,17757,17758,17759,17760,17761,17762,17763,17764,17765,17766,17767, +17768,17769,17770,17771,17772,17773,17774,17775,17776,17777,17778,17779, +17780,17781,17782,17783,17784,17785,17786,17787,17788,17789,17790,17791, +17792,17793,17794,17795,17796,17797,17798,17799,17800,17801,17802,17803, +17804,17805,17806,17807,17808,17809,17810,17811,17812,17813,17814,17815, +17816,17817,17818,17819,17820,17821,17822,17823,17824,17825,17826,17827, +17828,17829,17830,17831,17832,17833,17834,17835,17836,17837,17838,17839, +17840,17841,17842,17843,17844,17845,17846,17847,17848,17849,17850,17851, +17852,17853,17854,17855,17856,17857,17858,17859,17860,17861,17862,17863, +17864,17865,17866,17867,17868,17869,17870,17871,17872,17873,17874,17875, +17876,17877,17878,17879,17880,17881,17882,17883,17884,17885,17886,17887, +17888,17889,17890,17891,17892,17893,17894,17895,17896,17897,17898,17899, +17900,17901,17902,17903,17904,17905,17906,17907,17908,17909,17910,17911, +17912,17913,17914,17915,17916,17917,17918,17919,17920,17921,17922,17923, +17924,17925,17926,17927,17928,17929,17930,17931,17932,17933,17934,17935, +17936,17937,17938,17939,17940,17941,17942,17943,17944,17945,17946,17947, +17948,17949,17950,17951,17952,17953,17954,17955,17956,17957,17958,17959, +17960,17961,17962,17963,17964,17965,17966,17967,17968,17969,17970,17971, +17972,17973,17974,17975,17976,17977,17978,17979,17980,17981,17982,17983, +17984,17985,17986,17987,17988,17989,17990,17991,17992,17993,17994,17995, +17996,17997,17998,17999,18000,18001,18002,18003,18004,18005,18006,18007, +18008,18009,18010,18011,18012,18013,18014,18015,18016,18017,18018,18019, +18020,18021,18022,18023,18024,18025,18026,18027,18028,18029,18030,18031, +18032,18033,18034,18035,18036,18037,18038,18039,18040,18041,18042,18043, +18044,18045,18046,18047,18048,18049,18050,18051,18052,18053,18054,18055, +18056,18057,18058,18059,18060,18061,18062,18063,18064,18065,18066,18067, +18068,18069,18070,18071,18072,18073,18074,18075,18076,18077,18078,18079, +18080,18081,18082,18083,18084,18085,18086,18087,18088,18089,18090,18091, +18092,18093,18094,18095,18096,18097,18098,18099,18100,18101,18102,18103, +18104,18105,18106,18107,18108,18109,18110,18111,18112,18113,18114,18115, +18116,18117,18118,18119,18120,18121,18122,18123,18124,18125,18126,18127, +18128,18129,18130,18131,18132,18133,18134,18135,18136,18137,18138,18139, +18140,18141,18142,18143,18144,18145,18146,18147,18148,18149,18150,18151, +18152,18153,18154,18155,18156,18157,18158,18159,18160,18161,18162,18163, +18164,18165,18166,18167,18168,18169,18170,18171,18172,18173,18174,18175, +18176,18177,18178,18179,18180,18181,18182,18183,18184,18185,18186,18187, +18188,18189,18190,18191,18192,18193,18194,18195,18196,18197,18198,18199, +18200,18201,18202,18203,18204,18205,18206,18207,18208,18209,18210,18211, +18212,18213,18214,18215,18216,18217,18218,18219,18220,18221,18222,18223, +18224,18225,18226,18227,18228,18229,18230,18231,18232,18233,18234,18235, +18236,18237,18238,18239,18240,18241,18242,18243,18244,18245,18246,18247, +18248,18249,18250,18251,18252,18253,18254,18255,18256,18257,18258,18259, +18260,18261,18262,18263,18264,18265,18266,18267,18268,18269,18270,18271, +18272,18273,18274,18275,18276,18277,18278,18279,18280,18281,18282,18283, +18284,18285,18286,18287,18288,18289,18290,18291,18292,18293,18294,18295, +18296,18297,18298,18299,18300,18301,18302,18303,18304,18305,18306,18307, +18308,18309,18310,18311,18312,18313,18314,18315,18316,18317,18318,18319, +18320,18321,18322,18323,18324,18325,18326,18327,18328,18329,18330,18331, +18332,18333,18334,18335,18336,18337,18338,18339,18340,18341,18342,18343, +18344,18345,18346,18347,18348,18349,18350,18351,18352,18353,18354,18355, +18356,18357,18358,18359,18360,18361,18362,18363,18364,18365,18366,18367, +18368,18369,18370,18371,18372,18373,18374,18375,18376,18377,18378,18379, +18380,18381,18382,18383,18384,18385,18386,18387,18388,18389,18390,18391, +18392,18393,18394,18395,18396,18397,18398,18399,18400,18401,18402,18403, +18404,18405,18406,18407,18408,18409,18410,18411,18412,18413,18414,18415, +18416,18417,18418,18419,18420,18421,18422,18423,18424,18425,18426,18427, +18428,18429,18430,18431,18432,18433,18434,18435,18436,18437,18438,18439, +18440,18441,18442,18443,18444,18445,18446,18447,18448,18449,18450,18451, +18452,18453,18454,18455,18456,18457,18458,18459,18460,18461,18462,18463, +18464,18465,18466,18467,18468,18469,18470,18471,18472,18473,18474,18475, +18476,18477,18478,18479,18480,18481,18482,18483,18484,18485,18486,18487, +18488,18489,18490,18491,18492,18493,18494,18495,18496,18497,18498,18499, +18500,18501,18502,18503,18504,18505,18506,18507,18508,18509,18510,18511, +18512,18513,18514,18515,18516,18517,18518,18519,18520,18521,18522,18523, +18524,18525,18526,18527,18528,18529,18530,18531,18532,18533,18534,18535, +18536,18537,18538,18539,18540,18541,18542,18543,18544,18545,18546,18547, +18548,18549,18550,18551,18552,18553,18554,18555,18556,18557,18558,18559, +18560,18561,18562,18563,18564,18565,18566,18567,18568,18569,18570,18571, +18572,18573,18574,18575,18576,18577,18578,18579,18580,18581,18582,18583, +18584,18585,18586,18587,18588,18589,18590,18591,18592,18593,18594,18595, +18596,18597,18598,18599,18600,18601,18602,18603,18604,18605,18606,18607, +18608,18609,18610,18611,18612,18613,18614,18615,18616,18617,18618,18619, +18620,18621,18622,18623,18624,18625,18626,18627,18628,18629,18630,18631, +18632,18633,18634,18635,18636,18637,18638,18639,18640,18641,18642,18643, +18644,18645,18646,18647,18648,18649,18650,18651,18652,18653,18654,18655, +18656,18657,18658,18659,18660,18661,18662,18663,18664,18665,18666,18667, +18668,18669,18670,18671,18672,18673,18674,18675,18676,18677,18678,18679, +18680,18681,18682,18683,18684,18685,18686,18687,18688,18689,18690,18691, +18692,18693,18694,18695,18696,18697,18698,18699,18700,18701,18702,18703, +18704,18705,18706,18707,18708,18709,18710,18711,18712,18713,18714,18715, +18716,18717,18718,18719,18720,18721,18722,18723,18724,18725,18726,18727, +18728,18729,18730,18731,18732,18733,18734,18735,18736,18737,18738,18739, +18740,18741,18742,18743,18744,18745,18746,18747,18748,18749,18750,18751, +18752,18753,18754,18755,18756,18757,18758,18759,18760,18761,18762,18763, +18764,18765,18766,18767,18768,18769,18770,18771,18772,18773,18774,18775, +18776,18777,18778,18779,18780,18781,18782,18783,18784,18785,18786,18787, +18788,18789,18790,18791,18792,18793,18794,18795,18796,18797,18798,18799, +18800,18801,18802,18803,18804,18805,18806,18807,18808,18809,18810,18811, +18812,18813,18814,18815,18816,18817,18818,18819,18820,18821,18822,18823, +18824,18825,18826,18827,18828,18829,18830,18831,18832,18833,18834,18835, +18836,18837,18838,18839,18840,18841,18842,18843,18844,18845,18846,18847, +18848,18849,18850,18851,18852,18853,18854,18855,18856,18857,18858,18859, +18860,18861,18862,18863,18864,18865,18866,18867,18868,18869,18870,18871, +18872,18873,18874,18875,18876,18877,18878,18879,18880,18881,18882,18883, +18884,18885,18886,18887,18888,18889,18890,18891,18892,18893,18894,18895, +18896,18897,18898,18899,18900,18901,18902,18903,18904,18905,18906,18907, +18908,18909,18910,18911,18912,18913,18914,18915,18916,18917,18918,18919, +18920,18921,18922,18923,18924,18925,18926,18927,18928,18929,18930,18931, +18932,18933,18934,18935,18936,18937,18938,18939,18940,18941,18942,18943, +18944,18945,18946,18947,18948,18949,18950,18951,18952,18953,18954,18955, +18956,18957,18958,18959,18960,18961,18962,18963,18964,18965,18966,18967, +18968,18969,18970,18971,18972,18973,18974,18975,18976,18977,18978,18979, +18980,18981,18982,18983,18984,18985,18986,18987,18988,18989,18990,18991, +18992,18993,18994,18995,18996,18997,18998,18999,19000,19001,19002,19003, +19004,19005,19006,19007,19008,19009,19010,19011,19012,19013,19014,19015, +19016,19017,19018,19019,19020,19021,19022,19023,19024,19025,19026,19027, +19028,19029,19030,19031,19032,19033,19034,19035,19036,19037,19038,19039, +19040,19041,19042,19043,19044,19045,19046,19047,19048,19049,19050,19051, +19052,19053,19054,19055,19056,19057,19058,19059,19060,19061,19062,19063, +19064,19065,19066,19067,19068,19069,19070,19071,19072,19073,19074,19075, +19076,19077,19078,19079,19080,19081,19082,19083,19084,19085,19086,19087, +19088,19089,19090,19091,19092,19093,19094,19095,19096,19097,19098,19099, +19100,19101,19102,19103,19104,19105,19106,19107,19108,19109,19110,19111, +19112,19113,19114,19115,19116,19117,19118,19119,19120,19121,19122,19123, +19124,19125,19126,19127,19128,19129,19130,19131,19132,19133,19134,19135, +19136,19137,19138,19139,19140,19141,19142,19143,19144,19145,19146,19147, +19148,19149,19150,19151,19152,19153,19154,19155,19156,19157,19158,19159, +19160,19161,19162,19163,19164,19165,19166,19167,19168,19169,19170,19171, +19172,19173,19174,19175,19176,19177,19178,19179,19180,19181,19182,19183, +19184,19185,19186,19187,19188,19189,19190,19191,19192,19193,19194,19195, +19196,19197,19198,19199,19200,19201,19202,19203,19204,19205,19206,19207, +19208,19209,19210,19211,19212,19213,19214,19215,19216,19217,19218,19219, +19220,19221,19222,19223,19224,19225,19226,19227,19228,19229,19230,19231, +19232,19233,19234,19235,19236,19237,19238,19239,19240,19241,19242,19243, +19244,19245,19246,19247,19248,19249,19250,19251,19252,19253,19254,19255, +19256,19257,19258,19259,19260,19261,19262,19263,19264,19265,19266,19267, +19268,19269,19270,19271,19272,19273,19274,19275,19276,19277,19278,19279, +19280,19281,19282,19283,19284,19285,19286,19287,19288,19289,19290,19291, +19292,19293,19294,19295,19296,19297,19298,19299,19300,19301,19302,19303, +19304,19305,19306,19307,19308,19309,19310,19311,19312,19313,19314,19315, +19316,19317,19318,19319,19320,19321,19322,19323,19324,19325,19326,19327, +19328,19329,19330,19331,19332,19333,19334,19335,19336,19337,19338,19339, +19340,19341,19342,19343,19344,19345,19346,19347,19348,19349,19350,19351, +19352,19353,19354,19355,19356,19357,19358,19359,19360,19361,19362,19363, +19364,19365,19366,19367,19368,19369,19370,19371,19372,19373,19374,19375, +19376,19377,19378,19379,19380,19381,19382,19383,19384,19385,19386,19387, +19388,19389,19390,19391,19392,19393,19394,19395,19396,19397,19398,19399, +19400,19401,19402,19403,19404,19405,19406,19407,19408,19409,19410,19411, +19412,19413,19414,19415,19416,19417,19418,19419,19420,19421,19422,19423, +19424,19425,19426,19427,19428,19429,19430,19431,19432,19433,19434,19435, +19436,19437,19438,19439,19440,19441,19442,19443,19444,19445,19446,19447, +19448,19449,19450,19451,19452,19453,19454,19455,19456,19457,19458,19459, +19460,19461,19462,19463,19464,19465,19466,19467,19468,19469,19470,19471, +19472,19473,19474,19475,19476,19477,19478,19479,19480,19481,19482,19483, +19484,19485,19486,19487,19488,19489,19490,19491,19492,19493,19494,19495, +19496,19497,19498,19499,19500,19501,19502,19503,19504,19505,19506,19507, +19508,19509,19510,19511,19512,19513,19514,19515,19516,19517,19518,19519, +19520,19521,19522,19523,19524,19525,19526,19527,19528,19529,19530,19531, +19532,19533,19534,19535,19536,19537,19538,19539,19540,19541,19542,19543, +19544,19545,19546,19547,19548,19549,19550,19551,19552,19553,19554,19555, +19556,19557,19558,19559,19560,19561,19562,19563,19564,19565,19566,19567, +19568,19569,19570,19571,19572,19573,19574,19575,19576,19577,19578,19579, +19580,19581,19582,19583,19584,19585,19586,19587,19588,19589,19590,19591, +19592,19593,19594,19595,19596,19597,19598,19599,19600,19601,19602,19603, +19604,19605,19606,19607,19608,19609,19610,19611,19612,19613,19614,19615, +19616,19617,19618,19619,19620,19621,19622,19623,19624,19625,19626,19627, +19628,19629,19630,19631,19632,19633,19634,19635,19636,19637,19638,19639, +19640,19641,19642,19643,19644,19645,19646,19647,19648,19649,19650,19651, +19652,19653,19654,19655,19656,19657,19658,19659,19660,19661,19662,19663, +19664,19665,19666,19667,19668,19669,19670,19671,19672,19673,19674,19675, +19676,19677,19678,19679,19680,19681,19682,19683,19684,19685,19686,19687, +19688,19689,19690,19691,19692,19693,19694,19695,19696,19697,19698,19699, +19700,19701,19702,19703,19704,19705,19706,19707,19708,19709,19710,19711, +19712,19713,19714,19715,19716,19717,19718,19719,19720,19721,19722,19723, +19724,19725,19726,19727,19728,19729,19730,19731,19732,19733,19734,19735, +19736,19737,19738,19739,19740,19741,19742,19743,19744,19745,19746,19747, +19748,19749,19750,19751,19752,19753,19754,19755,19756,19757,19758,19759, +19760,19761,19762,19763,19764,19765,19766,19767,19768,19769,19770,19771, +19772,19773,19774,19775,19776,19777,19778,19779,19780,19781,19782,19783, +19784,19785,19786,19787,19788,19789,19790,19791,19792,19793,19794,19795, +19796,19797,19798,19799,19800,19801,19802,19803,19804,19805,19806,19807, +19808,19809,19810,19811,19812,19813,19814,19815,19816,19817,19818,19819, +19820,19821,19822,19823,19824,19825,19826,19827,19828,19829,19830,19831, +19832,19833,19834,19835,19836,19837,19838,19839,19840,19841,19842,19843, +19844,19845,19846,19847,19848,19849,19850,19851,19852,19853,19854,19855, +19856,19857,19858,19859,19860,19861,19862,19863,19864,19865,19866,19867, +19868,19869,19870,19871,19872,19873,19874,19875,19876,19877,19878,19879, +19880,19881,19882,19883,19884,19885,19886,19887,19888,19889,19890,19891, +19892,19893,19894,19895,19896,19897,19898,19899,19900,19901,19902,19903, +19904,19905,19906,19907,19908,19909,19910,19911,19912,19913,19914,19915, +19916,19917,19918,19919,19920,19921,19922,19923,19924,19925,19926,19927, +19928,19929,19930,19931,19932,19933,19934,19935,19936,19937,19938,19939, +19940,19941,19942,19943,19944,19945,19946,19947,19948,19949,19950,19951, +19952,19953,19954,19955,19956,19957,19958,19959,19960,19961,19962,19963, +19964,19965,19966,19967,19968,19969,19970,19971,19972,19973,19974,19975, +19976,19977,19978,19979,19980,19981,19982,19983,19984,19985,19986,19987, +19988,19989,19990,19991,19992,19993,19994,19995,19996,19997,19998,19999, +20000,20001,20002,20003,20004,20005,20006,20007,20008,20009,20010,20011, +20012,20013,20014,20015,20016,20017,20018,20019,20020,20021,20022,20023, +20024,20025,20026,20027,20028,20029,20030,20031,20032,20033,20034,20035, +20036,20037,20038,20039,20040,20041,20042,20043,20044,20045,20046,20047, +20048,20049,20050,20051,20052,20053,20054,20055,20056,20057,20058,20059, +20060,20061,20062,20063,20064,20065,20066,20067,20068,20069,20070,20071, +20072,20073,20074,20075,20076,20077,20078,20079,20080,20081,20082,20083, +20084,20085,20086,20087,20088,20089,20090,20091,20092,20093,20094,20095, +20096,20097,20098,20099,20100,20101,20102,20103,20104,20105,20106,20107, +20108,20109,20110,20111,20112,20113,20114,20115,20116,20117,20118,20119, +20120,20121,20122,20123,20124,20125,20126,20127,20128,20129,20130,20131, +20132,20133,20134,20135,20136,20137,20138,20139,20140,20141,20142,20143, +20144,20145,20146,20147,20148,20149,20150,20151,20152,20153,20154,20155, +20156,20157,20158,20159,20160,20161,20162,20163,20164,20165,20166,20167, +20168,20169,20170,20171,20172,20173,20174,20175,20176,20177,20178,20179, +20180,20181,20182,20183,20184,20185,20186,20187,20188,20189,20190,20191, +20192,20193,20194,20195,20196,20197,20198,20199,20200,20201,20202,20203, +20204,20205,20206,20207,20208,20209,20210,20211,20212,20213,20214,20215, +20216,20217,20218,20219,20220,20221,20222,20223,20224,20225,20226,20227, +20228,20229,20230,20231,20232,20233,20234,20235,20236,20237,20238,20239, +20240,20241,20242,20243,20244,20245,20246,20247,20248,20249,20250,20251, +20252,20253,20254,20255,20256,20257,20258,20259,20260,20261,20262,20263, +20264,20265,20266,20267,20268,20269,20270,20271,20272,20273,20274,20275, +20276,20277,20278,20279,20280,20281,20282,20283,20284,20285,20286,20287, +20288,20289,20290,20291,20292,20293,20294,20295,20296,20297,20298,20299, +20300,20301,20302,20303,20304,20305,20306,20307,20308,20309,20310,20311, +20312,20313,20314,20315,20316,20317,20318,20319,20320,20321,20322,20323, +20324,20325,20326,20327,20328,20329,20330,20331,20332,20333,20334,20335, +20336,20337,20338,20339,20340,20341,20342,20343,20344,20345,20346,20347, +20348,20349,20350,20351,20352,20353,20354,20355,20356,20357,20358,20359, +20360,20361,20362,20363,20364,20365,20366,20367,20368,20369,20370,20371, +20372,20373,20374,20375,20376,20377,20378,20379,20380,20381,20382,20383, +20384,20385,20386,20387,20388,20389,20390,20391,20392,20393,20394,20395, +20396,20397,20398,20399,20400,20401,20402,20403,20404,20405,20406,20407, +20408,20409,20410,20411,20412,20413,20414,20415,20416,20417,20418,20419, +20420,20421,20422,20423,20424,20425,20426,20427,20428,20429,20430,20431, +20432,20433,20434,20435,20436,20437,20438,20439,20440,20441,20442,20443, +20444,20445,20446,20447,20448,20449,20450,20451,20452,20453,20454,20455, +20456,20457,20458,20459,20460,20461,20462,20463,20464,20465,20466,20467, +20468,20469,20470,20471,20472,20473,20474,20475,20476,20477,20478,20479, +20480,20481,20482,20483,20484,20485,20486,20487,20488,20489,20490,20491, +20492,20493,20494,20495,20496,20497,20498,20499,20500,20501,20502,20503, +20504,20505,20506,20507,20508,20509,20510,20511,20512,20513,20514,20515, +20516,20517,20518,20519,20520,20521,20522,20523,20524,20525,20526,20527, +20528,20529,20530,20531,20532,20533,20534,20535,20536,20537,20538,20539, +20540,20541,20542,20543,20544,20545,20546,20547,20548,20549,20550,20551, +20552,20553,20554,20555,20556,20557,20558,20559,20560,20561,20562,20563, +20564,20565,20566,20567,20568,20569,20570,20571,20572,20573,20574,20575, +20576,20577,20578,20579,20580,20581,20582,20583,20584,20585,20586,20587, +20588,20589,20590,20591,20592,20593,20594,20595,20596,20597,20598,20599, +20600,20601,20602,20603,20604,20605,20606,20607,20608,20609,20610,20611, +20612,20613,20614,20615,20616,20617,20618,20619,20620,20621,20622,20623, +20624,20625,20626,20627,20628,20629,20630,20631,20632,20633,20634,20635, +20636,20637,20638,20639,20640,20641,20642,20643,20644,20645,20646,20647, +20648,20649,20650,20651,20652,20653,20654,20655,20656,20657,20658,20659, +20660,20661,20662,20663,20664,20665,20666,20667,20668,20669,20670,20671, +20672,20673,20674,20675,20676,20677,20678,20679,20680,20681,20682,20683, +20684,20685,20686,20687,20688,20689,20690,20691,20692,20693,20694,20695, +20696,20697,20698,20699,20700,20701,20702,20703,20704,20705,20706,20707, +20708,20709,20710,20711,20712,20713,20714,20715,20716,20717,20718,20719, +20720,20721,20722,20723,20724,20725,20726,20727,20728,20729,20730,20731, +20732,20733,20734,20735,20736,20737,20738,20739,20740,20741,20742,20743, +20744,20745,20746,20747,20748,20749,20750,20751,20752,20753,20754,20755, +20756,20757,20758,20759,20760,20761,20762,20763,20764,20765,20766,20767, +20768,20769,20770,20771,20772,20773,20774,20775,20776,20777,20778,20779, +20780,20781,20782,20783,20784,20785,20786,20787,20788,20789,20790,20791, +20792,20793,20794,20795,20796,20797,20798,20799,20800,20801,20802,20803, +20804,20805,20806,20807,20808,20809,20810,20811,20812,20813,20814,20815, +20816,20817,20818,20819,20820,20821,20822,20823,20824,20825,20826,20827, +20828,20829,20830,20831,20832,20833,20834,20835,20836,20837,20838,20839, +20840,20841,20842,20843,20844,20845,20846,20847,20848,20849,20850,20851, +20852,20853,20854,20855,20856,20857,20858,20859,20860,20861,20862,20863, +20864,20865,20866,20867,20868,20869,20870,20871,20872,20873,20874,20875, +20876,20877,20878,20879,20880,20881,20882,20883,20884,20885,20886,20887, +20888,20889,20890,20891,20892,20893,20894,20895,20896,20897,20898,20899, +20900,20901,20902,20903,20904,20905,20906,20907,20908,20909,20910,20911, +20912,20913,20914,20915,20916,20917,20918,20919,20920,20921,20922,20923, +20924,20925,20926,20927,20928,20929,20930,20931,20932,20933,20934,20935, +20936,20937,20938,20939,20940,20941,20942,20943,20944,20945,20946,20947, +20948,20949,20950,20951,20952,20953,20954,20955,20956,20957,20958,20959, +20960,20961,20962,20963,20964,20965,20966,20967,20968,20969,20970,20971, +20972,20973,20974,20975,20976,20977,20978,20979,20980,20981,20982,20983, +20984,20985,20986,20987,20988,20989,20990,20991,20992,20993,20994,20995, +20996,20997,20998,20999,21000,21001,21002,21003,21004,21005,21006,21007, +21008,21009,21010,21011,21012,21013,21014,21015,21016,21017,21018,21019, +21020,21021,21022,21023,21024,21025,21026,21027,21028,21029,21030,21031, +21032,21033,21034,21035,21036,21037,21038,21039,21040,21041,21042,21043, +21044,21045,21046,21047,21048,21049,21050,21051,21052,21053,21054,21055, +21056,21057,21058,21059,21060,21061,21062,21063,21064,21065,21066,21067, +21068,21069,21070,21071,21072,21073,21074,21075,21076,21077,21078,21079, +21080,21081,21082,21083,21084,21085,21086,21087,21088,21089,21090,21091, +21092,21093,21094,21095,21096,21097,21098,21099,21100,21101,21102,21103, +21104,21105,21106,21107,21108,21109,21110,21111,21112,21113,21114,21115, +21116,21117,21118,21119,21120,21121,21122,21123,21124,21125,21126,21127, +21128,21129,21130,21131,21132,21133,21134,21135,21136,21137,21138,21139, +21140,21141,21142,21143,21144,21145,21146,21147,21148,21149,21150,21151, +21152,21153,21154,21155,21156,21157,21158,21159,21160,21161,21162,21163, +21164,21165,21166,21167,21168,21169,21170,21171,21172,21173,21174,21175, +21176,21177,21178,21179,21180,21181,21182,21183,21184,21185,21186,21187, +21188,21189,21190,21191,21192,21193,21194,21195,21196,21197,21198,21199, +21200,21201,21202,21203,21204,21205,21206,21207,21208,21209,21210,21211, +21212,21213,21214,21215,21216,21217,21218,21219,21220,21221,21222,21223, +21224,21225,21226,21227,21228,21229,21230,21231,21232,21233,21234,21235, +21236,21237,21238,21239,21240,21241,21242,21243,21244,21245,21246,21247, +21248,21249,21250,21251,21252,21253,21254,21255,21256,21257,21258,21259, +21260,21261,21262,21263,21264,21265,21266,21267,21268,21269,21270,21271, +21272,21273,21274,21275,21276,21277,21278,21279,21280,21281,21282,21283, +21284,21285,21286,21287,21288,21289,21290,21291,21292,21293,21294,21295, +21296,21297,21298,21299,21300,21301,21302,21303,21304,21305,21306,21307, +21308,21309,21310,21311,21312,21313,21314,21315,21316,21317,21318,21319, +21320,21321,21322,21323,21324,21325,21326,21327,21328,21329,21330,21331, +21332,21333,21334,21335,21336,21337,21338,21339,21340,21341,21342,21343, +21344,21345,21346,21347,21348,21349,21350,21351,21352,21353,21354,21355, +21356,21357,21358,21359,21360,21361,21362,21363,21364,21365,21366,21367, +21368,21369,21370,21371,21372,21373,21374,21375,21376,21377,21378,21379, +21380,21381,21382,21383,21384,21385,21386,21387,21388,21389,21390,21391, +21392,21393,21394,21395,21396,21397,21398,21399,21400,21401,21402,21403, +21404,21405,21406,21407,21408,21409,21410,21411,21412,21413,21414,21415, +21416,21417,21418,21419,21420,21421,21422,21423,21424,21425,21426,21427, +21428,21429,21430,21431,21432,21433,21434,21435,21436,21437,21438,21439, +21440,21441,21442,21443,21444,21445,21446,21447,21448,21449,21450,21451, +21452,21453,21454,21455,21456,21457,21458,21459,21460,21461,21462,21463, +21464,21465,21466,21467,21468,21469,21470,21471,21472,21473,21474,21475, +21476,21477,21478,21479,21480,21481,21482,21483,21484,21485,21486,21487, +21488,21489,21490,21491,21492,21493,21494,21495,21496,21497,21498,21499, +21500,21501,21502,21503,21504,21505,21506,21507,21508,21509,21510,21511, +21512,21513,21514,21515,21516,21517,21518,21519,21520,21521,21522,21523, +21524,21525,21526,21527,21528,21529,21530,21531,21532,21533,21534,21535, +21536,21537,21538,21539,21540,21541,21542,21543,21544,21545,21546,21547, +21548,21549,21550,21551,21552,21553,21554,21555,21556,21557,21558,21559, +21560,21561,21562,21563,21564,21565,21566,21567,21568,21569,21570,21571, +21572,21573,21574,21575,21576,21577,21578,21579,21580,21581,21582,21583, +21584,21585,21586,21587,21588,21589,21590,21591,21592,21593,21594,21595, +21596,21597,21598,21599,21600,21601,21602,21603,21604,21605,21606,21607, +21608,21609,21610,21611,21612,21613,21614,21615,21616,21617,21618,21619, +21620,21621,21622,21623,21624,21625,21626,21627,21628,21629,21630,21631, +21632,21633,21634,21635,21636,21637,21638,21639,21640,21641,21642,21643, +21644,21645,21646,21647,21648,21649,21650,21651,21652,21653,21654,21655, +21656,21657,21658,21659,21660,21661,21662,21663,21664,21665,21666,21667, +21668,21669,21670,21671,21672,21673,21674,21675,21676,21677,21678,21679, +21680,21681,21682,21683,21684,21685,21686,21687,21688,21689,21690,21691, +21692,21693,21694,21695,21696,21697,21698,21699,21700,21701,21702,21703, +21704,21705,21706,21707,21708,21709,21710,21711,21712,21713,21714,21715, +21716,21717,21718,21719,21720,21721,21722,21723,21724,21725,21726,21727, +21728,21729,21730,21731,21732,21733,21734,21735,21736,21737,21738,21739, +21740,21741,21742,21743,21744,21745,21746,21747,21748,21749,21750,21751, +21752,21753,21754,21755,21756,21757,21758,21759,21760,21761,21762,21763, +21764,21765,21766,21767,21768,21769,21770,21771,21772,21773,21774,21775, +21776,21777,21778,21779,21780,21781,21782,21783,21784,21785,21786,21787, +21788,21789,21790,21791,21792,21793,21794,21795,21796,21797,21798,21799, +21800,21801,21802,21803,21804,21805,21806,21807,21808,21809,21810,21811, +21812,21813,21814,21815,21816,21817,21818,21819,21820,21821,21822,21823, +21824,21825,21826,21827,21828,21829,21830,21831,21832,21833,21834,21835, +21836,21837,21838,21839,21840,21841,21842,21843,21844,21845,21846,21847, +21848,21849,21850,21851,21852,21853,21854,21855,21856,21857,21858,21859, +21860,21861,21862,21863,21864,21865,21866,21867,21868,21869,21870,21871, +21872,21873,21874,21875,21876,21877,21878,21879,21880,21881,21882,21883, +21884,21885,21886,21887,21888,21889,21890,21891,21892,21893,21894,21895, +21896,21897,21898,21899,21900,21901,21902,21903,21904,21905,21906,21907, +21908,21909,21910,21911,21912,21913,21914,21915,21916,21917,21918,21919, +21920,21921,21922,21923,21924,21925,21926,21927,21928,21929,21930,21931, +21932,21933,21934,21935,21936,21937,21938,21939,21940,21941,21942,21943, +21944,21945,21946,21947,21948,21949,21950,21951,21952,21953,21954,21955, +21956,21957,21958,21959,21960,21961,21962,21963,21964,21965,21966,21967, +21968,21969,21970,21971,21972,21973,21974,21975,21976,21977,21978,21979, +21980,21981,21982,21983,21984,21985,21986,21987,21988,21989,21990,21991, +21992,21993,21994,21995,21996,21997,21998,21999,22000,22001,22002,22003, +22004,22005,22006,22007,22008,22009,22010,22011,22012,22013,22014,22015, +22016,22017,22018,22019,22020,22021,22022,22023,22024,22025,22026,22027, +22028,22029,22030,22031,22032,22033,22034,22035,22036,22037,22038,22039, +22040,22041,22042,22043,22044,22045,22046,22047,22048,22049,22050,22051, +22052,22053,22054,22055,22056,22057,22058,22059,22060,22061,22062,22063, +22064,22065,22066,22067,22068,22069,22070,22071,22072,22073,22074,22075, +22076,22077,22078,22079,22080,22081,22082,22083,22084,22085,22086,22087, +22088,22089,22090,22091,22092,22093,22094,22095,22096,22097,22098,22099, +22100,22101,22102,22103,22104,22105,22106,22107,22108,22109,22110,22111, +22112,22113,22114,22115,22116,22117,22118,22119,22120,22121,22122,22123, +22124,22125,22126,22127,22128,22129,22130,22131,22132,22133,22134,22135, +22136,22137,22138,22139,22140,22141,22142,22143,22144,22145,22146,22147, +22148,22149,22150,22151,22152,22153,22154,22155,22156,22157,22158,22159, +22160,22161,22162,22163,22164,22165,22166,22167,22168,22169,22170,22171, +22172,22173,22174,22175,22176,22177,22178,22179,22180,22181,22182,22183, +22184,22185,22186,22187,22188,22189,22190,22191,22192,22193,22194,22195, +22196,22197,22198,22199,22200,22201,22202,22203,22204,22205,22206,22207, +22208,22209,22210,22211,22212,22213,22214,22215,22216,22217,22218,22219, +22220,22221,22222,22223,22224,22225,22226,22227,22228,22229,22230,22231, +22232,22233,22234,22235,22236,22237,22238,22239,22240,22241,22242,22243, +22244,22245,22246,22247,22248,22249,22250,22251,22252,22253,22254,22255, +22256,22257,22258,22259,22260,22261,22262,22263,22264,22265,22266,22267, +22268,22269,22270,22271,22272,22273,22274,22275,22276,22277,22278,22279, +22280,22281,22282,22283,22284,22285,22286,22287,22288,22289,22290,22291, +22292,22293,22294,22295,22296,22297,22298,22299,22300,22301,22302,22303, +22304,22305,22306,22307,22308,22309,22310,22311,22312,22313,22314,22315, +22316,22317,22318,22319,22320,22321,22322,22323,22324,22325,22326,22327, +22328,22329,22330,22331,22332,22333,22334,22335,22336,22337,22338,22339, +22340,22341,22342,22343,22344,22345,22346,22347,22348,22349,22350,22351, +22352,22353,22354,22355,22356,22357,22358,22359,22360,22361,22362,22363, +22364,22365,22366,22367,22368,22369,22370,22371,22372,22373,22374,22375, +22376,22377,22378,22379,22380,22381,22382,22383,22384,22385,22386,22387, +22388,22389,22390,22391,22392,22393,22394,22395,22396,22397,22398,22399, +22400,22401,22402,22403,22404,22405,22406,22407,22408,22409,22410,22411, +22412,22413,22414,22415,22416,22417,22418,22419,22420,22421,22422,22423, +22424,22425,22426,22427,22428,22429,22430,22431,22432,22433,22434,22435, +22436,22437,22438,22439,22440,22441,22442,22443,22444,22445,22446,22447, +22448,22449,22450,22451,22452,22453,22454,22455,22456,22457,22458,22459, +22460,22461,22462,22463,22464,22465,22466,22467,22468,22469,22470,22471, +22472,22473,22474,22475,22476,22477,22478,22479,22480,22481,22482,22483, +22484,22485,22486,22487,22488,22489,22490,22491,22492,22493,22494,22495, +22496,22497,22498,22499,22500,22501,22502,22503,22504,22505,22506,22507, +22508,22509,22510,22511,22512,22513,22514,22515,22516,22517,22518,22519, +22520,22521,22522,22523,22524,22525,22526,22527,22528,22529,22530,22531, +22532,22533,22534,22535,22536,22537,22538,22539,22540,22541,22542,22543, +22544,22545,22546,22547,22548,22549,22550,22551,22552,22553,22554,22555, +22556,22557,22558,22559,22560,22561,22562,22563,22564,22565,22566,22567, +22568,22569,22570,22571,22572,22573,22574,22575,22576,22577,22578,22579, +22580,22581,22582,22583,22584,22585,22586,22587,22588,22589,22590,22591, +22592,22593,22594,22595,22596,22597,22598,22599,22600,22601,22602,22603, +22604,22605,22606,22607,22608,22609,22610,22611,22612,22613,22614,22615, +22616,22617,22618,22619,22620,22621,22622,22623,22624,22625,22626,22627, +22628,22629,22630,22631,22632,22633,22634,22635,22636,22637,22638,22639, +22640,22641,22642,22643,22644,22645,22646,22647,22648,22649,22650,22651, +22652,22653,22654,22655,22656,22657,22658,22659,22660,22661,22662,22663, +22664,22665,22666,22667,22668,22669,22670,22671,22672,22673,22674,22675, +22676,22677,22678,22679,22680,22681,22682,22683,22684,22685,22686,22687, +22688,22689,22690,22691,22692,22693,22694,22695,22696,22697,22698,22699, +22700,22701,22702,22703,22704,22705,22706,22707,22708,22709,22710,22711, +22712,22713,22714,22715,22716,22717,22718,22719,22720,22721,22722,22723, +22724,22725,22726,22727,22728,22729,22730,22731,22732,22733,22734,22735, +22736,22737,22738,22739,22740,22741,22742,22743,22744,22745,22746,22747, +22748,22749,22750,22751,22752,22753,22754,22755,22756,22757,22758,22759, +22760,22761,22762,22763,22764,22765,22766,22767,22768,22769,22770,22771, +22772,22773,22774,22775,22776,22777,22778,22779,22780,22781,22782,22783, +22784,22785,22786,22787,22788,22789,22790,22791,22792,22793,22794,22795, +22796,22797,22798,22799,22800,22801,22802,22803,22804,22805,22806,22807, +22808,22809,22810,22811,22812,22813,22814,22815,22816,22817,22818,22819, +22820,22821,22822,22823,22824,22825,22826,22827,22828,22829,22830,22831, +22832,22833,22834,22835,22836,22837,22838,22839,22840,22841,22842,22843, +22844,22845,22846,22847,22848,22849,22850,22851,22852,22853,22854,22855, +22856,22857,22858,22859,22860,22861,22862,22863,22864,22865,22866,22867, +22868,22869,22870,22871,22872,22873,22874,22875,22876,22877,22878,22879, +22880,22881,22882,22883,22884,22885,22886,22887,22888,22889,22890,22891, +22892,22893,22894,22895,22896,22897,22898,22899,22900,22901,22902,22903, +22904,22905,22906,22907,22908,22909,22910,22911,22912,22913,22914,22915, +22916,22917,22918,22919,22920,22921,22922,22923,22924,22925,22926,22927, +22928,22929,22930,22931,22932,22933,22934,22935,22936,22937,22938,22939, +22940,22941,22942,22943,22944,22945,22946,22947,22948,22949,22950,22951, +22952,22953,22954,22955,22956,22957,22958,22959,22960,22961,22962,22963, +22964,22965,22966,22967,22968,22969,22970,22971,22972,22973,22974,22975, +22976,22977,22978,22979,22980,22981,22982,22983,22984,22985,22986,22987, +22988,22989,22990,22991,22992,22993,22994,22995,22996,22997,22998,22999, +23000,23001,23002,23003,23004,23005,23006,23007,23008,23009,23010,23011, +23012,23013,23014,23015,23016,23017,23018,23019,23020,23021,23022,23023, +23024,23025,23026,23027,23028,23029,23030,23031,23032,23033,23034,23035, +23036,23037,23038,23039,23040,23041,23042,23043,23044,23045,23046,23047, +23048,23049,23050,23051,23052,23053,23054,23055,23056,23057,23058,23059, +23060,23061,23062,23063,23064,23065,23066,23067,23068,23069,23070,23071, +23072,23073,23074,23075,23076,23077,23078,23079,23080,23081,23082,23083, +23084,23085,23086,23087,23088,23089,23090,23091,23092,23093,23094,23095, +23096,23097,23098,23099,23100,23101,23102,23103,23104,23105,23106,23107, +23108,23109,23110,23111,23112,23113,23114,23115,23116,23117,23118,23119, +23120,23121,23122,23123,23124,23125,23126,23127,23128,23129,23130,23131, +23132,23133,23134,23135,23136,23137,23138,23139,23140,23141,23142,23143, +23144,23145,23146,23147,23148,23149,23150,23151,23152,23153,23154,23155, +23156,23157,23158,23159,23160,23161,23162,23163,23164,23165,23166,23167, +23168,23169,23170,23171,23172,23173,23174,23175,23176,23177,23178,23179, +23180,23181,23182,23183,23184,23185,23186,23187,23188,23189,23190,23191, +23192,23193,23194,23195,23196,23197,23198,23199,23200,23201,23202,23203, +23204,23205,23206,23207,23208,23209,23210,23211,23212,23213,23214,23215, +23216,23217,23218,23219,23220,23221,23222,23223,23224,23225,23226,23227, +23228,23229,23230,23231,23232,23233,23234,23235,23236,23237,23238,23239, +23240,23241,23242,23243,23244,23245,23246,23247,23248,23249,23250,23251, +23252,23253,23254,23255,23256,23257,23258,23259,23260,23261,23262,23263, +23264,23265,23266,23267,23268,23269,23270,23271,23272,23273,23274,23275, +23276,23277,23278,23279,23280,23281,23282,23283,23284,23285,23286,23287, +23288,23289,23290,23291,23292,23293,23294,23295,23296,23297,23298,23299, +23300,23301,23302,23303,23304,23305,23306,23307,23308,23309,23310,23311, +23312,23313,23314,23315,23316,23317,23318,23319,23320,23321,23322,23323, +23324,23325,23326,23327,23328,23329,23330,23331,23332,23333,23334,23335, +23336,23337,23338,23339,23340,23341,23342,23343,23344,23345,23346,23347, +23348,23349,23350,23351,23352,23353,23354,23355,23356,23357,23358,23359, +23360,23361,23362,23363,23364,23365,23366,23367,23368,23369,23370,23371, +23372,23373,23374,23375,23376,23377,23378,23379,23380,23381,23382,23383, +23384,23385,23386,23387,23388,23389,23390,23391,23392,23393,23394,23395, +23396,23397,23398,23399,23400,23401,23402,23403,23404,23405,23406,23407, +23408,23409,23410,23411,23412,23413,23414,23415,23416,23417,23418,23419, +23420,23421,23422,23423,23424,23425,23426,23427,23428,23429,23430,23431, +23432,23433,23434,23435,23436,23437,23438,23439,23440,23441,23442,23443, +23444,23445,23446,23447,23448,23449,23450,23451,23452,23453,23454,23455, +23456,23457,23458,23459,23460,23461,23462,23463,23464,23465,23466,23467, +23468,23469,23470,23471,23472,23473,23474,23475,23476,23477,23478,23479, +23480,23481,23482,23483,23484,23485,23486,23487,23488,23489,23490,23491, +23492,23493,23494,23495,23496,23497,23498,23499,23500,23501,23502,23503, +23504,23505,23506,23507,23508,23509,23510,23511,23512,23513,23514,23515, +23516,23517,23518,23519,23520,23521,23522,23523,23524,23525,23526,23527, +23528,23529,23530,23531,23532,23533,23534,23535,23536,23537,23538,23539, +23540,23541,23542,23543,23544,23545,23546,23547,23548,23549,23550,23551, +23552,23553,23554,23555,23556,23557,23558,23559,23560,23561,23562,23563, +23564,23565,23566,23567,23568,23569,23570,23571,23572,23573,23574,23575, +23576,23577,23578,23579,23580,23581,23582,23583,23584,23585,23586,23587, +23588,23589,23590,23591,23592,23593,23594,23595,23596,23597,23598,23599, +23600,23601,23602,23603,23604,23605,23606,23607,23608,23609,23610,23611, +23612,23613,23614,23615,23616,23617,23618,23619,23620,23621,23622,23623, +23624,23625,23626,23627,23628,23629,23630,23631,23632,23633,23634,23635, +23636,23637,23638,23639,23640,23641,23642,23643,23644,23645,23646,23647, +23648,23649,23650,23651,23652,23653,23654,23655,23656,23657,23658,23659, +23660,23661,23662,23663,23664,23665,23666,23667,23668,23669,23670,23671, +23672,23673,23674,23675,23676,23677,23678,23679,23680,23681,23682,23683, +23684,23685,23686,23687,23688,23689,23690,23691,23692,23693,23694,23695, +23696,23697,23698,23699,23700,23701,23702,23703,23704,23705,23706,23707, +23708,23709,23710,23711,23712,23713,23714,23715,23716,23717,23718,23719, +23720,23721,23722,23723,23724,23725,23726,23727,23728,23729,23730,23731, +23732,23733,23734,23735,23736,23737,23738,23739,23740,23741,23742,23743, +23744,23745,23746,23747,23748,23749,23750,23751,23752,23753,23754,23755, +23756,23757,23758,23759,23760,23761,23762,23763,23764,23765,23766,23767, +23768,23769,23770,23771,23772,23773,23774,23775,23776,23777,23778,23779, +23780,23781,23782,23783,23784,23785,23786,23787,23788,23789,23790,23791, +23792,23793,23794,23795,23796,23797,23798,23799,23800,23801,23802,23803, +23804,23805,23806,23807,23808,23809,23810,23811,23812,23813,23814,23815, +23816,23817,23818,23819,23820,23821,23822,23823,23824,23825,23826,23827, +23828,23829,23830,23831,23832,23833,23834,23835,23836,23837,23838,23839, +23840,23841,23842,23843,23844,23845,23846,23847,23848,23849,23850,23851, +23852,23853,23854,23855,23856,23857,23858,23859,23860,23861,23862,23863, +23864,23865,23866,23867,23868,23869,23870,23871,23872,23873,23874,23875, +23876,23877,23878,23879,23880,23881,23882,23883,23884,23885,23886,23887, +23888,23889,23890,23891,23892,23893,23894,23895,23896,23897,23898,23899, +23900,23901,23902,23903,23904,23905,23906,23907,23908,23909,23910,23911, +23912,23913,23914,23915,23916,23917,23918,23919,23920,23921,23922,23923, +23924,23925,23926,23927,23928,23929,23930,23931,23932,23933,23934,23935, +23936,23937,23938,23939,23940,23941,23942,23943,23944,23945,23946,23947, +23948,23949,23950,23951,23952,23953,23954,23955,23956,23957,23958,23959, +23960,23961,23962,23963,23964,23965,23966,23967,23968,23969,23970,23971, +23972,23973,23974,23975,23976,23977,23978,23979,23980,23981,23982,23983, +23984,23985,23986,23987,23988,23989,23990,23991,23992,23993,23994,23995, +23996,23997,23998,23999,24000,24001,24002,24003,24004,24005,24006,24007, +24008,24009,24010,24011,24012,24013,24014,24015,24016,24017,24018,24019, +24020,24021,24022,24023,24024,24025,24026,24027,24028,24029,24030,24031, +24032,24033,24034,24035,24036,24037,24038,24039,24040,24041,24042,24043, +24044,24045,24046,24047,24048,24049,24050,24051,24052,24053,24054,24055, +24056,24057,24058,24059,24060,24061,24062,24063,24064,24065,24066,24067, +24068,24069,24070,24071,24072,24073,24074,24075,24076,24077,24078,24079, +24080,24081,24082,24083,24084,24085,24086,24087,24088,24089,24090,24091, +24092,24093,24094,24095,24096,24097,24098,24099,24100,24101,24102,24103, +24104,24105,24106,24107,24108,24109,24110,24111,24112,24113,24114,24115, +24116,24117,24118,24119,24120,24121,24122,24123,24124,24125,24126,24127, +24128,24129,24130,24131,24132,24133,24134,24135,24136,24137,24138,24139, +24140,24141,24142,24143,24144,24145,24146,24147,24148,24149,24150,24151, +24152,24153,24154,24155,24156,24157,24158,24159,24160,24161,24162,24163, +24164,24165,24166,24167,24168,24169,24170,24171,24172,24173,24174,24175, +24176,24177,24178,24179,24180,24181,24182,24183,24184,24185,24186,24187, +24188,24189,24190,24191,24192,24193,24194,24195,24196,24197,24198,24199, +24200,24201,24202,24203,24204,24205,24206,24207,24208,24209,24210,24211, +24212,24213,24214,24215,24216,24217,24218,24219,24220,24221,24222,24223, +24224,24225,24226,24227,24228,24229,24230,24231,24232,24233,24234,24235, +24236,24237,24238,24239,24240,24241,24242,24243,24244,24245,24246,24247, +24248,24249,24250,24251,24252,24253,24254,24255,24256,24257,24258,24259, +24260,24261,24262,24263,24264,24265,24266,24267,24268,24269,24270,24271, +24272,24273,24274,24275,24276,24277,24278,24279,24280,24281,24282,24283, +24284,24285,24286,24287,24288,24289,24290,24291,24292,24293,24294,24295, +24296,24297,24298,24299,24300,24301,24302,24303,24304,24305,24306,24307, +24308,24309,24310,24311,24312,24313,24314,24315,24316,24317,24318,24319, +24320,24321,24322,24323,24324,24325,24326,24327,24328,24329,24330,24331, +24332,24333,24334,24335,24336,24337,24338,24339,24340,24341,24342,24343, +24344,24345,24346,24347,24348,24349,24350,24351,24352,24353,24354,24355, +24356,24357,24358,24359,24360,24361,24362,24363,24364,24365,24366,24367, +24368,24369,24370,24371,24372,24373,24374,24375,24376,24377,24378,24379, +24380,24381,24382,24383,24384,24385,24386,24387,24388,24389,24390,24391, +24392,24393,24394,24395,24396,24397,24398,24399,24400,24401,24402,24403, +24404,24405,24406,24407,24408,24409,24410,24411,24412,24413,24414,24415, +24416,24417,24418,24419,24420,24421,24422,24423,24424,24425,24426,24427, +24428,24429,24430,24431,24432,24433,24434,24435,24436,24437,24438,24439, +24440,24441,24442,24443,24444,24445,24446,24447,24448,24449,24450,24451, +24452,24453,24454,24455,24456,24457,24458,24459,24460,24461,24462,24463, +24464,24465,24466,24467,24468,24469,24470,24471,24472,24473,24474,24475, +24476,24477,24478,24479,24480,24481,24482,24483,24484,24485,24486,24487, +24488,24489,24490,24491,24492,24493,24494,24495,24496,24497,24498,24499, +24500,24501,24502,24503,24504,24505,24506,24507,24508,24509,24510,24511, +24512,24513,24514,24515,24516,24517,24518,24519,24520,24521,24522,24523, +24524,24525,24526,24527,24528,24529,24530,24531,24532,24533,24534,24535, +24536,24537,24538,24539,24540,24541,24542,24543,24544,24545,24546,24547, +24548,24549,24550,24551,24552,24553,24554,24555,24556,24557,24558,24559, +24560,24561,24562,24563,24564,24565,24566,24567,24568,24569,24570,24571, +24572,24573,24574,24575,24576,24577,24578,24579,24580,24581,24582,24583, +24584,24585,24586,24587,24588,24589,24590,24591,24592,24593,24594,24595, +24596,24597,24598,24599,24600,24601,24602,24603,24604,24605,24606,24607, +24608,24609,24610,24611,24612,24613,24614,24615,24616,24617,24618,24619, +24620,24621,24622,24623,24624,24625,24626,24627,24628,24629,24630,24631, +24632,24633,24634,24635,24636,24637,24638,24639,24640,24641,24642,24643, +24644,24645,24646,24647,24648,24649,24650,24651,24652,24653,24654,24655, +24656,24657,24658,24659,24660,24661,24662,24663,24664,24665,24666,24667, +24668,24669,24670,24671,24672,24673,24674,24675,24676,24677,24678,24679, +24680,24681,24682,24683,24684,24685,24686,24687,24688,24689,24690,24691, +24692,24693,24694,24695,24696,24697,24698,24699,24700,24701,24702,24703, +24704,24705,24706,24707,24708,24709,24710,24711,24712,24713,24714,24715, +24716,24717,24718,24719,24720,24721,24722,24723,24724,24725,24726,24727, +24728,24729,24730,24731,24732,24733,24734,24735,24736,24737,24738,24739, +24740,24741,24742,24743,24744,24745,24746,24747,24748,24749,24750,24751, +24752,24753,24754,24755,24756,24757,24758,24759,24760,24761,24762,24763, +24764,24765,24766,24767,24768,24769,24770,24771,24772,24773,24774,24775, +24776,24777,24778,24779,24780,24781,24782,24783,24784,24785,24786,24787, +24788,24789,24790,24791,24792,24793,24794,24795,24796,24797,24798,24799, +24800,24801,24802,24803,24804,24805,24806,24807,24808,24809,24810,24811, +24812,24813,24814,24815,24816,24817,24818,24819,24820,24821,24822,24823, +24824,24825,24826,24827,24828,24829,24830,24831,24832,24833,24834,24835, +24836,24837,24838,24839,24840,24841,24842,24843,24844,24845,24846,24847, +24848,24849,24850,24851,24852,24853,24854,24855,24856,24857,24858,24859, +24860,24861,24862,24863,24864,24865,24866,24867,24868,24869,24870,24871, +24872,24873,24874,24875,24876,24877,24878,24879,24880,24881,24882,24883, +24884,24885,24886,24887,24888,24889,24890,24891,24892,24893,24894,24895, +24896,24897,24898,24899,24900,24901,24902,24903,24904,24905,24906,24907, +24908,24909,24910,24911,24912,24913,24914,24915,24916,24917,24918,24919, +24920,24921,24922,24923,24924,24925,24926,24927,24928,24929,24930,24931, +24932,24933,24934,24935,24936,24937,24938,24939,24940,24941,24942,24943, +24944,24945,24946,24947,24948,24949,24950,24951,24952,24953,24954,24955, +24956,24957,24958,24959,24960,24961,24962,24963,24964,24965,24966,24967, +24968,24969,24970,24971,24972,24973,24974,24975,24976,24977,24978,24979, +24980,24981,24982,24983,24984,24985,24986,24987,24988,24989,24990,24991, +24992,24993,24994,24995,24996,24997,24998,24999,25000,25001,25002,25003, +25004,25005,25006,25007,25008,25009,25010,25011,25012,25013,25014,25015, +25016,25017,25018,25019,25020,25021,25022,25023,25024,25025,25026,25027, +25028,25029,25030,25031,25032,25033,25034,25035,25036,25037,25038,25039, +25040,25041,25042,25043,25044,25045,25046,25047,25048,25049,25050,25051, +25052,25053,25054,25055,25056,25057,25058,25059,25060,25061,25062,25063, +25064,25065,25066,25067,25068,25069,25070,25071,25072,25073,25074,25075, +25076,25077,25078,25079,25080,25081,25082,25083,25084,25085,25086,25087, +25088,25089,25090,25091,25092,25093,25094,25095,25096,25097,25098,25099, +25100,25101,25102,25103,25104,25105,25106,25107,25108,25109,25110,25111, +25112,25113,25114,25115,25116,25117,25118,25119,25120,25121,25122,25123, +25124,25125,25126,25127,25128,25129,25130,25131,25132,25133,25134,25135, +25136,25137,25138,25139,25140,25141,25142,25143,25144,25145,25146,25147, +25148,25149,25150,25151,25152,25153,25154,25155,25156,25157,25158,25159, +25160,25161,25162,25163,25164,25165,25166,25167,25168,25169,25170,25171, +25172,25173,25174,25175,25176,25177,25178,25179,25180,25181,25182,25183, +25184,25185,25186,25187,25188,25189,25190,25191,25192,25193,25194,25195, +25196,25197,25198,25199,25200,25201,25202,25203,25204,25205,25206,25207, +25208,25209,25210,25211,25212,25213,25214,25215,25216,25217,25218,25219, +25220,25221,25222,25223,25224,25225,25226,25227,25228,25229,25230,25231, +25232,25233,25234,25235,25236,25237,25238,25239,25240,25241,25242,25243, +25244,25245,25246,25247,25248,25249,25250,25251,25252,25253,25254,25255, +25256,25257,25258,25259,25260,25261,25262,25263,25264,25265,25266,25267, +25268,25269,25270,25271,25272,25273,25274,25275,25276,25277,25278,25279, +25280,25281,25282,25283,25284,25285,25286,25287,25288,25289,25290,25291, +25292,25293,25294,25295,25296,25297,25298,25299,25300,25301,25302,25303, +25304,25305,25306,25307,25308,25309,25310,25311,25312,25313,25314,25315, +25316,25317,25318,25319,25320,25321,25322,25323,25324,25325,25326,25327, +25328,25329,25330,25331,25332,25333,25334,25335,25336,25337,25338,25339, +25340,25341,25342,25343,25344,25345,25346,25347,25348,25349,25350,25351, +25352,25353,25354,25355,25356,25357,25358,25359,25360,25361,25362,25363, +25364,25365,25366,25367,25368,25369,25370,25371,25372,25373,25374,25375, +25376,25377,25378,25379,25380,25381,25382,25383,25384,25385,25386,25387, +25388,25389,25390,25391,25392,25393,25394,25395,25396,25397,25398,25399, +25400,25401,25402,25403,25404,25405,25406,25407,25408,25409,25410,25411, +25412,25413,25414,25415,25416,25417,25418,25419,25420,25421,25422,25423, +25424,25425,25426,25427,25428,25429,25430,25431,25432,25433,25434,25435, +25436,25437,25438,25439,25440,25441,25442,25443,25444,25445,25446,25447, +25448,25449,25450,25451,25452,25453,25454,25455,25456,25457,25458,25459, +25460,25461,25462,25463,25464,25465,25466,25467,25468,25469,25470,25471, +25472,25473,25474,25475,25476,25477,25478,25479,25480,25481,25482,25483, +25484,25485,25486,25487,25488,25489,25490,25491,25492,25493,25494,25495, +25496,25497,25498,25499,25500,25501,25502,25503,25504,25505,25506,25507, +25508,25509,25510,25511,25512,25513,25514,25515,25516,25517,25518,25519, +25520,25521,25522,25523,25524,25525,25526,25527,25528,25529,25530,25531, +25532,25533,25534,25535,25536,25537,25538,25539,25540,25541,25542,25543, +25544,25545,25546,25547,25548,25549,25550,25551,25552,25553,25554,25555, +25556,25557,25558,25559,25560,25561,25562,25563,25564,25565,25566,25567, +25568,25569,25570,25571,25572,25573,25574,25575,25576,25577,25578,25579, +25580,25581,25582,25583,25584,25585,25586,25587,25588,25589,25590,25591, +25592,25593,25594,25595,25596,25597,25598,25599,25600,25601,25602,25603, +25604,25605,25606,25607,25608,25609,25610,25611,25612,25613,25614,25615, +25616,25617,25618,25619,25620,25621,25622,25623,25624,25625,25626,25627, +25628,25629,25630,25631,25632,25633,25634,25635,25636,25637,25638,25639, +25640,25641,25642,25643,25644,25645,25646,25647,25648,25649,25650,25651, +25652,25653,25654,25655,25656,25657,25658,25659,25660,25661,25662,25663, +25664,25665,25666,25667,25668,25669,25670,25671,25672,25673,25674,25675, +25676,25677,25678,25679,25680,25681,25682,25683,25684,25685,25686,25687, +25688,25689,25690,25691,25692,25693,25694,25695,25696,25697,25698,25699, +25700,25701,25702,25703,25704,25705,25706,25707,25708,25709,25710,25711, +25712,25713,25714,25715,25716,25717,25718,25719,25720,25721,25722,25723, +25724,25725,25726,25727,25728,25729,25730,25731,25732,25733,25734,25735, +25736,25737,25738,25739,25740,25741,25742,25743,25744,25745,25746,25747, +25748,25749,25750,25751,25752,25753,25754,25755,25756,25757,25758,25759, +25760,25761,25762,25763,25764,25765,25766,25767,25768,25769,25770,25771, +25772,25773,25774,25775,25776,25777,25778,25779,25780,25781,25782,25783, +25784,25785,25786,25787,25788,25789,25790,25791,25792,25793,25794,25795, +25796,25797,25798,25799,25800,25801,25802,25803,25804,25805,25806,25807, +25808,25809,25810,25811,25812,25813,25814,25815,25816,25817,25818,25819, +25820,25821,25822,25823,25824,25825,25826,25827,25828,25829,25830,25831, +25832,25833,25834,25835,25836,25837,25838,25839,25840,25841,25842,25843, +25844,25845,25846,25847,25848,25849,25850,25851,25852,25853,25854,25855, +25856,25857,25858,25859,25860,25861,25862,25863,25864,25865,25866,25867, +25868,25869,25870,25871,25872,25873,25874,25875,25876,25877,25878,25879, +25880,25881,25882,25883,25884,25885,25886,25887,25888,25889,25890,25891, +25892,25893,25894,25895,25896,25897,25898,25899,25900,25901,25902,25903, +25904,25905,25906,25907,25908,25909,25910,25911,25912,25913,25914,25915, +25916,25917,25918,25919,25920,25921,25922,25923,25924,25925,25926,25927, +25928,25929,25930,25931,25932,25933,25934,25935,25936,25937,25938,25939, +25940,25941,25942,25943,25944,25945,25946,25947,25948,25949,25950,25951, +25952,25953,25954,25955,25956,25957,25958,25959,25960,25961,25962,25963, +25964,25965,25966,25967,25968,25969,25970,25971,25972,25973,25974,25975, +25976,25977,25978,25979,25980,25981,25982,25983,25984,25985,25986,25987, +25988,25989,25990,25991,25992,25993,25994,25995,25996,25997,25998,25999, +26000,26001,26002,26003,26004,26005,26006,26007,26008,26009,26010,26011, +26012,26013,26014,26015,26016,26017,26018,26019,26020,26021,26022,26023, +26024,26025,26026,26027,26028,26029,26030,26031,26032,26033,26034,26035, +26036,26037,26038,26039,26040,26041,26042,26043,26044,26045,26046,26047, +26048,26049,26050,26051,26052,26053,26054,26055,26056,26057,26058,26059, +26060,26061,26062,26063,26064,26065,26066,26067,26068,26069,26070,26071, +26072,26073,26074,26075,26076,26077,26078,26079,26080,26081,26082,26083, +26084,26085,26086,26087,26088,26089,26090,26091,26092,26093,26094,26095, +26096,26097,26098,26099,26100,26101,26102,26103,26104,26105,26106,26107, +26108,26109,26110,26111,26112,26113,26114,26115,26116,26117,26118,26119, +26120,26121,26122,26123,26124,26125,26126,26127,26128,26129,26130,26131, +26132,26133,26134,26135,26136,26137,26138,26139,26140,26141,26142,26143, +26144,26145,26146,26147,26148,26149,26150,26151,26152,26153,26154,26155, +26156,26157,26158,26159,26160,26161,26162,26163,26164,26165,26166,26167, +26168,26169,26170,26171,26172,26173,26174,26175,26176,26177,26178,26179, +26180,26181,26182,26183,26184,26185,26186,26187,26188,26189,26190,26191, +26192,26193,26194,26195,26196,26197,26198,26199,26200,26201,26202,26203, +26204,26205,26206,26207,26208,26209,26210,26211,26212,26213,26214,26215, +26216,26217,26218,26219,26220,26221,26222,26223,26224,26225,26226,26227, +26228,26229,26230,26231,26232,26233,26234,26235,26236,26237,26238,26239, +26240,26241,26242,26243,26244,26245,26246,26247,26248,26249,26250,26251, +26252,26253,26254,26255,26256,26257,26258,26259,26260,26261,26262,26263, +26264,26265,26266,26267,26268,26269,26270,26271,26272,26273,26274,26275, +26276,26277,26278,26279,26280,26281,26282,26283,26284,26285,26286,26287, +26288,26289,26290,26291,26292,26293,26294,26295,26296,26297,26298,26299, +26300,26301,26302,26303,26304,26305,26306,26307,26308,26309,26310,26311, +26312,26313,26314,26315,26316,26317,26318,26319,26320,26321,26322,26323, +26324,26325,26326,26327,26328,26329,26330,26331,26332,26333,26334,26335, +26336,26337,26338,26339,26340,26341,26342,26343,26344,26345,26346,26347, +26348,26349,26350,26351,26352,26353,26354,26355,26356,26357,26358,26359, +26360,26361,26362,26363,26364,26365,26366,26367,26368,26369,26370,26371, +26372,26373,26374,26375,26376,26377,26378,26379,26380,26381,26382,26383, +26384,26385,26386,26387,26388,26389,26390,26391,26392,26393,26394,26395, +26396,26397,26398,26399,26400,26401,26402,26403,26404,26405,26406,26407, +26408,26409,26410,26411,26412,26413,26414,26415,26416,26417,26418,26419, +26420,26421,26422,26423,26424,26425,26426,26427,26428,26429,26430,26431, +26432,26433,26434,26435,26436,26437,26438,26439,26440,26441,26442,26443, +26444,26445,26446,26447,26448,26449,26450,26451,26452,26453,26454,26455, +26456,26457,26458,26459,26460,26461,26462,26463,26464,26465,26466,26467, +26468,26469,26470,26471,26472,26473,26474,26475,26476,26477,26478,26479, +26480,26481,26482,26483,26484,26485,26486,26487,26488,26489,26490,26491, +26492,26493,26494,26495,26496,26497,26498,26499,26500,26501,26502,26503, +26504,26505,26506,26507,26508,26509,26510,26511,26512,26513,26514,26515, +26516,26517,26518,26519,26520,26521,26522,26523,26524,26525,26526,26527, +26528,26529,26530,26531,26532,26533,26534,26535,26536,26537,26538,26539, +26540,26541,26542,26543,26544,26545,26546,26547,26548,26549,26550,26551, +26552,26553,26554,26555,26556,26557,26558,26559,26560,26561,26562,26563, +26564,26565,26566,26567,26568,26569,26570,26571,26572,26573,26574,26575, +26576,26577,26578,26579,26580,26581,26582,26583,26584,26585,26586,26587, +26588,26589,26590,26591,26592,26593,26594,26595,26596,26597,26598,26599, +26600,26601,26602,26603,26604,26605,26606,26607,26608,26609,26610,26611, +26612,26613,26614,26615,26616,26617,26618,26619,26620,26621,26622,26623, +26624,26625,26626,26627,26628,26629,26630,26631,26632,26633,26634,26635, +26636,26637,26638,26639,26640,26641,26642,26643,26644,26645,26646,26647, +26648,26649,26650,26651,26652,26653,26654,26655,26656,26657,26658,26659, +26660,26661,26662,26663,26664,26665,26666,26667,26668,26669,26670,26671, +26672,26673,26674,26675,26676,26677,26678,26679,26680,26681,26682,26683, +26684,26685,26686,26687,26688,26689,26690,26691,26692,26693,26694,26695, +26696,26697,26698,26699,26700,26701,26702,26703,26704,26705,26706,26707, +26708,26709,26710,26711,26712,26713,26714,26715,26716,26717,26718,26719, +26720,26721,26722,26723,26724,26725,26726,26727,26728,26729,26730,26731, +26732,26733,26734,26735,26736,26737,26738,26739,26740,26741,26742,26743, +26744,26745,26746,26747,26748,26749,26750,26751,26752,26753,26754,26755, +26756,26757,26758,26759,26760,26761,26762,26763,26764,26765,26766,26767, +26768,26769,26770,26771,26772,26773,26774,26775,26776,26777,26778,26779, +26780,26781,26782,26783,26784,26785,26786,26787,26788,26789,26790,26791, +26792,26793,26794,26795,26796,26797,26798,26799,26800,26801,26802,26803, +26804,26805,26806,26807,26808,26809,26810,26811,26812,26813,26814,26815, +26816,26817,26818,26819,26820,26821,26822,26823,26824,26825,26826,26827, +26828,26829,26830,26831,26832,26833,26834,26835,26836,26837,26838,26839, +26840,26841,26842,26843,26844,26845,26846,26847,26848,26849,26850,26851, +26852,26853,26854,26855,26856,26857,26858,26859,26860,26861,26862,26863, +26864,26865,26866,26867,26868,26869,26870,26871,26872,26873,26874,26875, +26876,26877,26878,26879,26880,26881,26882,26883,26884,26885,26886,26887, +26888,26889,26890,26891,26892,26893,26894,26895,26896,26897,26898,26899, +26900,26901,26902,26903,26904,26905,26906,26907,26908,26909,26910,26911, +26912,26913,26914,26915,26916,26917,26918,26919,26920,26921,26922,26923, +26924,26925,26926,26927,26928,26929,26930,26931,26932,26933,26934,26935, +26936,26937,26938,26939,26940,26941,26942,26943,26944,26945,26946,26947, +26948,26949,26950,26951,26952,26953,26954,26955,26956,26957,26958,26959, +26960,26961,26962,26963,26964,26965,26966,26967,26968,26969,26970,26971, +26972,26973,26974,26975,26976,26977,26978,26979,26980,26981,26982,26983, +26984,26985,26986,26987,26988,26989,26990,26991,26992,26993,26994,26995, +26996,26997,26998,26999,27000,27001,27002,27003,27004,27005,27006,27007, +27008,27009,27010,27011,27012,27013,27014,27015,27016,27017,27018,27019, +27020,27021,27022,27023,27024,27025,27026,27027,27028,27029,27030,27031, +27032,27033,27034,27035,27036,27037,27038,27039,27040,27041,27042,27043, +27044,27045,27046,27047,27048,27049,27050,27051,27052,27053,27054,27055, +27056,27057,27058,27059,27060,27061,27062,27063,27064,27065,27066,27067, +27068,27069,27070,27071,27072,27073,27074,27075,27076,27077,27078,27079, +27080,27081,27082,27083,27084,27085,27086,27087,27088,27089,27090,27091, +27092,27093,27094,27095,27096,27097,27098,27099,27100,27101,27102,27103, +27104,27105,27106,27107,27108,27109,27110,27111,27112,27113,27114,27115, +27116,27117,27118,27119,27120,27121,27122,27123,27124,27125,27126,27127, +27128,27129,27130,27131,27132,27133,27134,27135,27136,27137,27138,27139, +27140,27141,27142,27143,27144,27145,27146,27147,27148,27149,27150,27151, +27152,27153,27154,27155,27156,27157,27158,27159,27160,27161,27162,27163, +27164,27165,27166,27167,27168,27169,27170,27171,27172,27173,27174,27175, +27176,27177,27178,27179,27180,27181,27182,27183,27184,27185,27186,27187, +27188,27189,27190,27191,27192,27193,27194,27195,27196,27197,27198,27199, +27200,27201,27202,27203,27204,27205,27206,27207,27208,27209,27210,27211, +27212,27213,27214,27215,27216,27217,27218,27219,27220,27221,27222,27223, +27224,27225,27226,27227,27228,27229,27230,27231,27232,27233,27234,27235, +27236,27237,27238,27239,27240,27241,27242,27243,27244,27245,27246,27247, +27248,27249,27250,27251,27252,27253,27254,27255,27256,27257,27258,27259, +27260,27261,27262,27263,27264,27265,27266,27267,27268,27269,27270,27271, +27272,27273,27274,27275,27276,27277,27278,27279,27280,27281,27282,27283, +27284,27285,27286,27287,27288,27289,27290,27291,27292,27293,27294,27295, +27296,27297,27298,27299,27300,27301,27302,27303,27304,27305,27306,27307, +27308,27309,27310,27311,27312,27313,27314,27315,27316,27317,27318,27319, +27320,27321,27322,27323,27324,27325,27326,27327,27328,27329,27330,27331, +27332,27333,27334,27335,27336,27337,27338,27339,27340,27341,27342,27343, +27344,27345,27346,27347,27348,27349,27350,27351,27352,27353,27354,27355, +27356,27357,27358,27359,27360,27361,27362,27363,27364,27365,27366,27367, +27368,27369,27370,27371,27372,27373,27374,27375,27376,27377,27378,27379, +27380,27381,27382,27383,27384,27385,27386,27387,27388,27389,27390,27391, +27392,27393,27394,27395,27396,27397,27398,27399,27400,27401,27402,27403, +27404,27405,27406,27407,27408,27409,27410,27411,27412,27413,27414,27415, +27416,27417,27418,27419,27420,27421,27422,27423,27424,27425,27426,27427, +27428,27429,27430,27431,27432,27433,27434,27435,27436,27437,27438,27439, +27440,27441,27442,27443,27444,27445,27446,27447,27448,27449,27450,27451, +27452,27453,27454,27455,27456,27457,27458,27459,27460,27461,27462,27463, +27464,27465,27466,27467,27468,27469,27470,27471,27472,27473,27474,27475, +27476,27477,27478,27479,27480,27481,27482,27483,27484,27485,27486,27487, +27488,27489,27490,27491,27492,27493,27494,27495,27496,27497,27498,27499, +27500,27501,27502,27503,27504,27505,27506,27507,27508,27509,27510,27511, +27512,27513,27514,27515,27516,27517,27518,27519,27520,27521,27522,27523, +27524,27525,27526,27527,27528,27529,27530,27531,27532,27533,27534,27535, +27536,27537,27538,27539,27540,27541,27542,27543,27544,27545,27546,27547, +27548,27549,27550,27551,27552,27553,27554,27555,27556,27557,27558,27559, +27560,27561,27562,27563,27564,27565,27566,27567,27568,27569,27570,27571, +27572,27573,27574,27575,27576,27577,27578,27579,27580,27581,27582,27583, +27584,27585,27586,27587,27588,27589,27590,27591,27592,27593,27594,27595, +27596,27597,27598,27599,27600,27601,27602,27603,27604,27605,27606,27607, +27608,27609,27610,27611,27612,27613,27614,27615,27616,27617,27618,27619, +27620,27621,27622,27623,27624,27625,27626,27627,27628,27629,27630,27631, +27632,27633,27634,27635,27636,27637,27638,27639,27640,27641,27642,27643, +27644,27645,27646,27647,27648,27649,27650,27651,27652,27653,27654,27655, +27656,27657,27658,27659,27660,27661,27662,27663,27664,27665,27666,27667, +27668,27669,27670,27671,27672,27673,27674,27675,27676,27677,27678,27679, +27680,27681,27682,27683,27684,27685,27686,27687,27688,27689,27690,27691, +27692,27693,27694,27695,27696,27697,27698,27699,27700,27701,27702,27703, +27704,27705,27706,27707,27708,27709,27710,27711,27712,27713,27714,27715, +27716,27717,27718,27719,27720,27721,27722,27723,27724,27725,27726,27727, +27728,27729,27730,27731,27732,27733,27734,27735,27736,27737,27738,27739, +27740,27741,27742,27743,27744,27745,27746,27747,27748,27749,27750,27751, +27752,27753,27754,27755,27756,27757,27758,27759,27760,27761,27762,27763, +27764,27765,27766,27767,27768,27769,27770,27771,27772,27773,27774,27775, +27776,27777,27778,27779,27780,27781,27782,27783,27784,27785,27786,27787, +27788,27789,27790,27791,27792,27793,27794,27795,27796,27797,27798,27799, +27800,27801,27802,27803,27804,27805,27806,27807,27808,27809,27810,27811, +27812,27813,27814,27815,27816,27817,27818,27819,27820,27821,27822,27823, +27824,27825,27826,27827,27828,27829,27830,27831,27832,27833,27834,27835, +27836,27837,27838,27839,27840,27841,27842,27843,27844,27845,27846,27847, +27848,27849,27850,27851,27852,27853,27854,27855,27856,27857,27858,27859, +27860,27861,27862,27863,27864,27865,27866,27867,27868,27869,27870,27871, +27872,27873,27874,27875,27876,27877,27878,27879,27880,27881,27882,27883, +27884,27885,27886,27887,27888,27889,27890,27891,27892,27893,27894,27895, +27896,27897,27898,27899,27900,27901,27902,27903,27904,27905,27906,27907, +27908,27909,27910,27911,27912,27913,27914,27915,27916,27917,27918,27919, +27920,27921,27922,27923,27924,27925,27926,27927,27928,27929,27930,27931, +27932,27933,27934,27935,27936,27937,27938,27939,27940,27941,27942,27943, +27944,27945,27946,27947,27948,27949,27950,27951,27952,27953,27954,27955, +27956,27957,27958,27959,27960,27961,27962,27963,27964,27965,27966,27967, +27968,27969,27970,27971,27972,27973,27974,27975,27976,27977,27978,27979, +27980,27981,27982,27983,27984,27985,27986,27987,27988,27989,27990,27991, +27992,27993,27994,27995,27996,27997,27998,27999,28000,28001,28002,28003, +28004,28005,28006,28007,28008,28009,28010,28011,28012,28013,28014,28015, +28016,28017,28018,28019,28020,28021,28022,28023,28024,28025,28026,28027, +28028,28029,28030,28031,28032,28033,28034,28035,28036,28037,28038,28039, +28040,28041,28042,28043,28044,28045,28046,28047,28048,28049,28050,28051, +28052,28053,28054,28055,28056,28057,28058,28059,28060,28061,28062,28063, +28064,28065,28066,28067,28068,28069,28070,28071,28072,28073,28074,28075, +28076,28077,28078,28079,28080,28081,28082,28083,28084,28085,28086,28087, +28088,28089,28090,28091,28092,28093,28094,28095,28096,28097,28098,28099, +28100,28101,28102,28103,28104,28105,28106,28107,28108,28109,28110,28111, +28112,28113,28114,28115,28116,28117,28118,28119,28120,28121,28122,28123, +28124,28125,28126,28127,28128,28129,28130,28131,28132,28133,28134,28135, +28136,28137,28138,28139,28140,28141,28142,28143,28144,28145,28146,28147, +28148,28149,28150,28151,28152,28153,28154,28155,28156,28157,28158,28159, +28160,28161,28162,28163,28164,28165,28166,28167,28168,28169,28170,28171, +28172,28173,28174,28175,28176,28177,28178,28179,28180,28181,28182,28183, +28184,28185,28186,28187,28188,28189,28190,28191,28192,28193,28194,28195, +28196,28197,28198,28199,28200,28201,28202,28203,28204,28205,28206,28207, +28208,28209,28210,28211,28212,28213,28214,28215,28216,28217,28218,28219, +28220,28221,28222,28223,28224,28225,28226,28227,28228,28229,28230,28231, +28232,28233,28234,28235,28236,28237,28238,28239,28240,28241,28242,28243, +28244,28245,28246,28247,28248,28249,28250,28251,28252,28253,28254,28255, +28256,28257,28258,28259,28260,28261,28262,28263,28264,28265,28266,28267, +28268,28269,28270,28271,28272,28273,28274,28275,28276,28277,28278,28279, +28280,28281,28282,28283,28284,28285,28286,28287,28288,28289,28290,28291, +28292,28293,28294,28295,28296,28297,28298,28299,28300,28301,28302,28303, +28304,28305,28306,28307,28308,28309,28310,28311,28312,28313,28314,28315, +28316,28317,28318,28319,28320,28321,28322,28323,28324,28325,28326,28327, +28328,28329,28330,28331,28332,28333,28334,28335,28336,28337,28338,28339, +28340,28341,28342,28343,28344,28345,28346,28347,28348,28349,28350,28351, +28352,28353,28354,28355,28356,28357,28358,28359,28360,28361,28362,28363, +28364,28365,28366,28367,28368,28369,28370,28371,28372,28373,28374,28375, +28376,28377,28378,28379,28380,28381,28382,28383,28384,28385,28386,28387, +28388,28389,28390,28391,28392,28393,28394,28395,28396,28397,28398,28399, +28400,28401,28402,28403,28404,28405,28406,28407,28408,28409,28410,28411, +28412,28413,28414,28415,28416,28417,28418,28419,28420,28421,28422,28423, +28424,28425,28426,28427,28428,28429,28430,28431,28432,28433,28434,28435, +28436,28437,28438,28439,28440,28441,28442,28443,28444,28445,28446,28447, +28448,28449,28450,28451,28452,28453,28454,28455,28456,28457,28458,28459, +28460,28461,28462,28463,28464,28465,28466,28467,28468,28469,28470,28471, +28472,28473,28474,28475,28476,28477,28478,28479,28480,28481,28482,28483, +28484,28485,28486,28487,28488,28489,28490,28491,28492,28493,28494,28495, +28496,28497,28498,28499,28500,28501,28502,28503,28504,28505,28506,28507, +28508,28509,28510,28511,28512,28513,28514,28515,28516,28517,28518,28519, +28520,28521,28522,28523,28524,28525,28526,28527,28528,28529,28530,28531, +28532,28533,28534,28535,28536,28537,28538,28539,28540,28541,28542,28543, +28544,28545,28546,28547,28548,28549,28550,28551,28552,28553,28554,28555, +28556,28557,28558,28559,28560,28561,28562,28563,28564,28565,28566,28567, +28568,28569,28570,28571,28572,28573,28574,28575,28576,28577,28578,28579, +28580,28581,28582,28583,28584,28585,28586,28587,28588,28589,28590,28591, +28592,28593,28594,28595,28596,28597,28598,28599,28600,28601,28602,28603, +28604,28605,28606,28607,28608,28609,28610,28611,28612,28613,28614,28615, +28616,28617,28618,28619,28620,28621,28622,28623,28624,28625,28626,28627, +28628,28629,28630,28631,28632,28633,28634,28635,28636,28637,28638,28639, +28640,28641,28642,28643,28644,28645,28646,28647,28648,28649,28650,28651, +28652,28653,28654,28655,28656,28657,28658,28659,28660,28661,28662,28663, +28664,28665,28666,28667,28668,28669,28670,28671,28672,28673,28674,28675, +28676,28677,28678,28679,28680,28681,28682,28683,28684,28685,28686,28687, +28688,28689,28690,28691,28692,28693,28694,28695,28696,28697,28698,28699, +28700,28701,28702,28703,28704,28705,28706,28707,28708,28709,28710,28711, +28712,28713,28714,28715,28716,28717,28718,28719,28720,28721,28722,28723, +28724,28725,28726,28727,28728,28729,28730,28731,28732,28733,28734,28735, +28736,28737,28738,28739,28740,28741,28742,28743,28744,28745,28746,28747, +28748,28749,28750,28751,28752,28753,28754,28755,28756,28757,28758,28759, +28760,28761,28762,28763,28764,28765,28766,28767,28768,28769,28770,28771, +28772,28773,28774,28775,28776,28777,28778,28779,28780,28781,28782,28783, +28784,28785,28786,28787,28788,28789,28790,28791,28792,28793,28794,28795, +28796,28797,28798,28799,28800,28801,28802,28803,28804,28805,28806,28807, +28808,28809,28810,28811,28812,28813,28814,28815,28816,28817,28818,28819, +28820,28821,28822,28823,28824,28825,28826,28827,28828,28829,28830,28831, +28832,28833,28834,28835,28836,28837,28838,28839,28840,28841,28842,28843, +28844,28845,28846,28847,28848,28849,28850,28851,28852,28853,28854,28855, +28856,28857,28858,28859,28860,28861,28862,28863,28864,28865,28866,28867, +28868,28869,28870,28871,28872,28873,28874,28875,28876,28877,28878,28879, +28880,28881,28882,28883,28884,28885,28886,28887,28888,28889,28890,28891, +28892,28893,28894,28895,28896,28897,28898,28899,28900,28901,28902,28903, +28904,28905,28906,28907,28908,28909,28910,28911,28912,28913,28914,28915, +28916,28917,28918,28919,28920,28921,28922,28923,28924,28925,28926,28927, +28928,28929,28930,28931,28932,28933,28934,28935,28936,28937,28938,28939, +28940,28941,28942,28943,28944,28945,28946,28947,28948,28949,28950,28951, +28952,28953,28954,28955,28956,28957,28958,28959,28960,28961,28962,28963, +28964,28965,28966,28967,28968,28969,28970,28971,28972,28973,28974,28975, +28976,28977,28978,28979,28980,28981,28982,28983,28984,28985,28986,28987, +28988,28989,28990,28991,28992,28993,28994,28995,28996,28997,28998,28999, +29000,29001,29002,29003,29004,29005,29006,29007,29008,29009,29010,29011, +29012,29013,29014,29015,29016,29017,29018,29019,29020,29021,29022,29023, +29024,29025,29026,29027,29028,29029,29030,29031,29032,29033,29034,29035, +29036,29037,29038,29039,29040,29041,29042,29043,29044,29045,29046,29047, +29048,29049,29050,29051,29052,29053,29054,29055,29056,29057,29058,29059, +29060,29061,29062,29063,29064,29065,29066,29067,29068,29069,29070,29071, +29072,29073,29074,29075,29076,29077,29078,29079,29080,29081,29082,29083, +29084,29085,29086,29087,29088,29089,29090,29091,29092,29093,29094,29095, +29096,29097,29098,29099,29100,29101,29102,29103,29104,29105,29106,29107, +29108,29109,29110,29111,29112,29113,29114,29115,29116,29117,29118,29119, +29120,29121,29122,29123,29124,29125,29126,29127,29128,29129,29130,29131, +29132,29133,29134,29135,29136,29137,29138,29139,29140,29141,29142,29143, +29144,29145,29146,29147,29148,29149,29150,29151,29152,29153,29154,29155, +29156,29157,29158,29159,29160,29161,29162,29163,29164,29165,29166,29167, +29168,29169,29170,29171,29172,29173,29174,29175,29176,29177,29178,29179, +29180,29181,29182,29183,29184,29185,29186,29187,29188,29189,29190,29191, +29192,29193,29194,29195,29196,29197,29198,29199,29200,29201,29202,29203, +29204,29205,29206,29207,29208,29209,29210,29211,29212,29213,29214,29215, +29216,29217,29218,29219,29220,29221,29222,29223,29224,29225,29226,29227, +29228,29229,29230,29231,29232,29233,29234,29235,29236,29237,29238,29239, +29240,29241,29242,29243,29244,29245,29246,29247,29248,29249,29250,29251, +29252,29253,29254,29255,29256,29257,29258,29259,29260,29261,29262,29263, +29264,29265,29266,29267,29268,29269,29270,29271,29272,29273,29274,29275, +29276,29277,29278,29279,29280,29281,29282,29283,29284,29285,29286,29287, +29288,29289,29290,29291,29292,29293,29294,29295,29296,29297,29298,29299, +29300,29301,29302,29303,29304,29305,29306,29307,29308,29309,29310,29311, +29312,29313,29314,29315,29316,29317,29318,29319,29320,29321,29322,29323, +29324,29325,29326,29327,29328,29329,29330,29331,29332,29333,29334,29335, +29336,29337,29338,29339,29340,29341,29342,29343,29344,29345,29346,29347, +29348,29349,29350,29351,29352,29353,29354,29355,29356,29357,29358,29359, +29360,29361,29362,29363,29364,29365,29366,29367,29368,29369,29370,29371, +29372,29373,29374,29375,29376,29377,29378,29379,29380,29381,29382,29383, +29384,29385,29386,29387,29388,29389,29390,29391,29392,29393,29394,29395, +29396,29397,29398,29399,29400,29401,29402,29403,29404,29405,29406,29407, +29408,29409,29410,29411,29412,29413,29414,29415,29416,29417,29418,29419, +29420,29421,29422,29423,29424,29425,29426,29427,29428,29429,29430,29431, +29432,29433,29434,29435,29436,29437,29438,29439,29440,29441,29442,29443, +29444,29445,29446,29447,29448,29449,29450,29451,29452,29453,29454,29455, +29456,29457,29458,29459,29460,29461,29462,29463,29464,29465,29466,29467, +29468,29469,29470,29471,29472,29473,29474,29475,29476,29477,29478,29479, +29480,29481,29482,29483,29484,29485,29486,29487,29488,29489,29490,29491, +29492,29493,29494,29495,29496,29497,29498,29499,29500,29501,29502,29503, +29504,29505,29506,29507,29508,29509,29510,29511,29512,29513,29514,29515, +29516,29517,29518,29519,29520,29521,29522,29523,29524,29525,29526,29527, +29528,29529,29530,29531,29532,29533,29534,29535,29536,29537,29538,29539, +29540,29541,29542,29543,29544,29545,29546,29547,29548,29549,29550,29551, +29552,29553,29554,29555,29556,29557,29558,29559,29560,29561,29562,29563, +29564,29565,29566,29567,29568,29569,29570,29571,29572,29573,29574,29575, +29576,29577,29578,29579,29580,29581,29582,29583,29584,29585,29586,29587, +29588,29589,29590,29591,29592,29593,29594,29595,29596,29597,29598,29599, +29600,29601,29602,29603,29604,29605,29606,29607,29608,29609,29610,29611, +29612,29613,29614,29615,29616,29617,29618,29619,29620,29621,29622,29623, +29624,29625,29626,29627,29628,29629,29630,29631,29632,29633,29634,29635, +29636,29637,29638,29639,29640,29641,29642,29643,29644,29645,29646,29647, +29648,29649,29650,29651,29652,29653,29654,29655,29656,29657,29658,29659, +29660,29661,29662,29663,29664,29665,29666,29667,29668,29669,29670,29671, +29672,29673,29674,29675,29676,29677,29678,29679,29680,29681,29682,29683, +29684,29685,29686,29687,29688,29689,29690,29691,29692,29693,29694,29695, +29696,29697,29698,29699,29700,29701,29702,29703,29704,29705,29706,29707, +29708,29709,29710,29711,29712,29713,29714,29715,29716,29717,29718,29719, +29720,29721,29722,29723,29724,29725,29726,29727,29728,29729,29730,29731, +29732,29733,29734,29735,29736,29737,29738,29739,29740,29741,29742,29743, +29744,29745,29746,29747,29748,29749,29750,29751,29752,29753,29754,29755, +29756,29757,29758,29759,29760,29761,29762,29763,29764,29765,29766,29767, +29768,29769,29770,29771,29772,29773,29774,29775,29776,29777,29778,29779, +29780,29781,29782,29783,29784,29785,29786,29787,29788,29789,29790,29791, +29792,29793,29794,29795,29796,29797,29798,29799,29800,29801,29802,29803, +29804,29805,29806,29807,29808,29809,29810,29811,29812,29813,29814,29815, +29816,29817,29818,29819,29820,29821,29822,29823,29824,29825,29826,29827, +29828,29829,29830,29831,29832,29833,29834,29835,29836,29837,29838,29839, +29840,29841,29842,29843,29844,29845,29846,29847,29848,29849,29850,29851, +29852,29853,29854,29855,29856,29857,29858,29859,29860,29861,29862,29863, +29864,29865,29866,29867,29868,29869,29870,29871,29872,29873,29874,29875, +29876,29877,29878,29879,29880,29881,29882,29883,29884,29885,29886,29887, +29888,29889,29890,29891,29892,29893,29894,29895,29896,29897,29898,29899, +29900,29901,29902,29903,29904,29905,29906,29907,29908,29909,29910,29911, +29912,29913,29914,29915,29916,29917,29918,29919,29920,29921,29922,29923, +29924,29925,29926,29927,29928,29929,29930,29931,29932,29933,29934,29935, +29936,29937,29938,29939,29940,29941,29942,29943,29944,29945,29946,29947, +29948,29949,29950,29951,29952,29953,29954,29955,29956,29957,29958,29959, +29960,29961,29962,29963,29964,29965,29966,29967,29968,29969,29970,29971, +29972,29973,29974,29975,29976,29977,29978,29979,29980,29981,29982,29983, +29984,29985,29986,29987,29988,29989,29990,29991,29992,29993,29994,29995, +29996,29997,29998,29999,30000,30001,30002,30003,30004,30005,30006,30007, +30008,30009,30010,30011,30012,30013,30014,30015,30016,30017,30018,30019, +30020,30021,30022,30023,30024,30025,30026,30027,30028,30029,30030,30031, +30032,30033,30034,30035,30036,30037,30038,30039,30040,30041,30042,30043, +30044,30045,30046,30047,30048,30049,30050,30051,30052,30053,30054,30055, +30056,30057,30058,30059,30060,30061,30062,30063,30064,30065,30066,30067, +30068,30069,30070,30071,30072,30073,30074,30075,30076,30077,30078,30079, +30080,30081,30082,30083,30084,30085,30086,30087,30088,30089,30090,30091, +30092,30093,30094,30095,30096,30097,30098,30099,30100,30101,30102,30103, +30104,30105,30106,30107,30108,30109,30110,30111,30112,30113,30114,30115, +30116,30117,30118,30119,30120,30121,30122,30123,30124,30125,30126,30127, +30128,30129,30130,30131,30132,30133,30134,30135,30136,30137,30138,30139, +30140,30141,30142,30143,30144,30145,30146,30147,30148,30149,30150,30151, +30152,30153,30154,30155,30156,30157,30158,30159,30160,30161,30162,30163, +30164,30165,30166,30167,30168,30169,30170,30171,30172,30173,30174,30175, +30176,30177,30178,30179,30180,30181,30182,30183,30184,30185,30186,30187, +30188,30189,30190,30191,30192,30193,30194,30195,30196,30197,30198,30199, +30200,30201,30202,30203,30204,30205,30206,30207,30208,30209,30210,30211, +30212,30213,30214,30215,30216,30217,30218,30219,30220,30221,30222,30223, +30224,30225,30226,30227,30228,30229,30230,30231,30232,30233,30234,30235, +30236,30237,30238,30239,30240,30241,30242,30243,30244,30245,30246,30247, +30248,30249,30250,30251,30252,30253,30254,30255,30256,30257,30258,30259, +30260,30261,30262,30263,30264,30265,30266,30267,30268,30269,30270,30271, +30272,30273,30274,30275,30276,30277,30278,30279,30280,30281,30282,30283, +30284,30285,30286,30287,30288,30289,30290,30291,30292,30293,30294,30295, +30296,30297,30298,30299,30300,30301,30302,30303,30304,30305,30306,30307, +30308,30309,30310,30311,30312,30313,30314,30315,30316,30317,30318,30319, +30320,30321,30322,30323,30324,30325,30326,30327,30328,30329,30330,30331, +30332,30333,30334,30335,30336,30337,30338,30339,30340,30341,30342,30343, +30344,30345,30346,30347,30348,30349,30350,30351,30352,30353,30354,30355, +30356,30357,30358,30359,30360,30361,30362,30363,30364,30365,30366,30367, +30368,30369,30370,30371,30372,30373,30374,30375,30376,30377,30378,30379, +30380,30381,30382,30383,30384,30385,30386,30387,30388,30389,30390,30391, +30392,30393,30394,30395,30396,30397,30398,30399,30400,30401,30402,30403, +30404,30405,30406,30407,30408,30409,30410,30411,30412,30413,30414,30415, +30416,30417,30418,30419,30420,30421,30422,30423,30424,30425,30426,30427, +30428,30429,30430,30431,30432,30433,30434,30435,30436,30437,30438,30439, +30440,30441,30442,30443,30444,30445,30446,30447,30448,30449,30450,30451, +30452,30453,30454,30455,30456,30457,30458,30459,30460,30461,30462,30463, +30464,30465,30466,30467,30468,30469,30470,30471,30472,30473,30474,30475, +30476,30477,30478,30479,30480,30481,30482,30483,30484,30485,30486,30487, +30488,30489,30490,30491,30492,30493,30494,30495,30496,30497,30498,30499, +30500,30501,30502,30503,30504,30505,30506,30507,30508,30509,30510,30511, +30512,30513,30514,30515,30516,30517,30518,30519,30520,30521,30522,30523, +30524,30525,30526,30527,30528,30529,30530,30531,30532,30533,30534,30535, +30536,30537,30538,30539,30540,30541,30542,30543,30544,30545,30546,30547, +30548,30549,30550,30551,30552,30553,30554,30555,30556,30557,30558,30559, +30560,30561,30562,30563,30564,30565,30566,30567,30568,30569,30570,30571, +30572,30573,30574,30575,30576,30577,30578,30579,30580,30581,30582,30583, +30584,30585,30586,30587,30588,30589,30590,30591,30592,30593,30594,30595, +30596,30597,30598,30599,30600,30601,30602,30603,30604,30605,30606,30607, +30608,30609,30610,30611,30612,30613,30614,30615,30616,30617,30618,30619, +30620,30621,30622,30623,30624,30625,30626,30627,30628,30629,30630,30631, +30632,30633,30634,30635,30636,30637,30638,30639,30640,30641,30642,30643, +30644,30645,30646,30647,30648,30649,30650,30651,30652,30653,30654,30655, +30656,30657,30658,30659,30660,30661,30662,30663,30664,30665,30666,30667, +30668,30669,30670,30671,30672,30673,30674,30675,30676,30677,30678,30679, +30680,30681,30682,30683,30684,30685,30686,30687,30688,30689,30690,30691, +30692,30693,30694,30695,30696,30697,30698,30699,30700,30701,30702,30703, +30704,30705,30706,30707,30708,30709,30710,30711,30712,30713,30714,30715, +30716,30717,30718,30719,30720,30721,30722,30723,30724,30725,30726,30727, +30728,30729,30730,30731,30732,30733,30734,30735,30736,30737,30738,30739, +30740,30741,30742,30743,30744,30745,30746,30747,30748,30749,30750,30751, +30752,30753,30754,30755,30756,30757,30758,30759,30760,30761,30762,30763, +30764,30765,30766,30767,30768,30769,30770,30771,30772,30773,30774,30775, +30776,30777,30778,30779,30780,30781,30782,30783,30784,30785,30786,30787, +30788,30789,30790,30791,30792,30793,30794,30795,30796,30797,30798,30799, +30800,30801,30802,30803,30804,30805,30806,30807,30808,30809,30810,30811, +30812,30813,30814,30815,30816,30817,30818,30819,30820,30821,30822,30823, +30824,30825,30826,30827,30828,30829,30830,30831,30832,30833,30834,30835, +30836,30837,30838,30839,30840,30841,30842,30843,30844,30845,30846,30847, +30848,30849,30850,30851,30852,30853,30854,30855,30856,30857,30858,30859, +30860,30861,30862,30863,30864,30865,30866,30867,30868,30869,30870,30871, +30872,30873,30874,30875,30876,30877,30878,30879,30880,30881,30882,30883, +30884,30885,30886,30887,30888,30889,30890,30891,30892,30893,30894,30895, +30896,30897,30898,30899,30900,30901,30902,30903,30904,30905,30906,30907, +30908,30909,30910,30911,30912,30913,30914,30915,30916,30917,30918,30919, +30920,30921,30922,30923,30924,30925,30926,30927,30928,30929,30930,30931, +30932,30933,30934,30935,30936,30937,30938,30939,30940,30941,30942,30943, +30944,30945,30946,30947,30948,30949,30950,30951,30952,30953,30954,30955, +30956,30957,30958,30959,30960,30961,30962,30963,30964,30965,30966,30967, +30968,30969,30970,30971,30972,30973,30974,30975,30976,30977,30978,30979, +30980,30981,30982,30983,30984,30985,30986,30987,30988,30989,30990,30991, +30992,30993,30994,30995,30996,30997,30998,30999,31000,31001,31002,31003, +31004,31005,31006,31007,31008,31009,31010,31011,31012,31013,31014,31015, +31016,31017,31018,31019,31020,31021,31022,31023,31024,31025,31026,31027, +31028,31029,31030,31031,31032,31033,31034,31035,31036,31037,31038,31039, +31040,31041,31042,31043,31044,31045,31046,31047,31048,31049,31050,31051, +31052,31053,31054,31055,31056,31057,31058,31059,31060,31061,31062,31063, +31064,31065,31066,31067,31068,31069,31070,31071,31072,31073,31074,31075, +31076,31077,31078,31079,31080,31081,31082,31083,31084,31085,31086,31087, +31088,31089,31090,31091,31092,31093,31094,31095,31096,31097,31098,31099, +31100,31101,31102,31103,31104,31105,31106,31107,31108,31109,31110,31111, +31112,31113,31114,31115,31116,31117,31118,31119,31120,31121,31122,31123, +31124,31125,31126,31127,31128,31129,31130,31131,31132,31133,31134,31135, +31136,31137,31138,31139,31140,31141,31142,31143,31144,31145,31146,31147, +31148,31149,31150,31151,31152,31153,31154,31155,31156,31157,31158,31159, +31160,31161,31162,31163,31164,31165,31166,31167,31168,31169,31170,31171, +31172,31173,31174,31175,31176,31177,31178,31179,31180,31181,31182,31183, +31184,31185,31186,31187,31188,31189,31190,31191,31192,31193,31194,31195, +31196,31197,31198,31199,31200,31201,31202,31203,31204,31205,31206,31207, +31208,31209,31210,31211,31212,31213,31214,31215,31216,31217,31218,31219, +31220,31221,31222,31223,31224,31225,31226,31227,31228,31229,31230,31231, +31232,31233,31234,31235,31236,31237,31238,31239,31240,31241,31242,31243, +31244,31245,31246,31247,31248,31249,31250,31251,31252,31253,31254,31255, +31256,31257,31258,31259,31260,31261,31262,31263,31264,31265,31266,31267, +31268,31269,31270,31271,31272,31273,31274,31275,31276,31277,31278,31279, +31280,31281,31282,31283,31284,31285,31286,31287,31288,31289,31290,31291, +31292,31293,31294,31295,31296,31297,31298,31299,31300,31301,31302,31303, +31304,31305,31306,31307,31308,31309,31310,31311,31312,31313,31314,31315, +31316,31317,31318,31319,31320,31321,31322,31323,31324,31325,31326,31327, +31328,31329,31330,31331,31332,31333,31334,31335,31336,31337,31338,31339, +31340,31341,31342,31343,31344,31345,31346,31347,31348,31349,31350,31351, +31352,31353,31354,31355,31356,31357,31358,31359,31360,31361,31362,31363, +31364,31365,31366,31367,31368,31369,31370,31371,31372,31373,31374,31375, +31376,31377,31378,31379,31380,31381,31382,31383,31384,31385,31386,31387, +31388,31389,31390,31391,31392,31393,31394,31395,31396,31397,31398,31399, +31400,31401,31402,31403,31404,31405,31406,31407,31408,31409,31410,31411, +31412,31413,31414,31415,31416,31417,31418,31419,31420,31421,31422,31423, +31424,31425,31426,31427,31428,31429,31430,31431,31432,31433,31434,31435, +31436,31437,31438,31439,31440,31441,31442,31443,31444,31445,31446,31447, +31448,31449,31450,31451,31452,31453,31454,31455,31456,31457,31458,31459, +31460,31461,31462,31463,31464,31465,31466,31467,31468,31469,31470,31471, +31472,31473,31474,31475,31476,31477,31478,31479,31480,31481,31482,31483, +31484,31485,31486,31487,31488,31489,31490,31491,31492,31493,31494,31495, +31496,31497,31498,31499,31500,31501,31502,31503,31504,31505,31506,31507, +31508,31509,31510,31511,31512,31513,31514,31515,31516,31517,31518,31519, +31520,31521,31522,31523,31524,31525,31526,31527,31528,31529,31530,31531, +31532,31533,31534,31535,31536,31537,31538,31539,31540,31541,31542,31543, +31544,31545,31546,31547,31548,31549,31550,31551,31552,31553,31554,31555, +31556,31557,31558,31559,31560,31561,31562,31563,31564,31565,31566,31567, +31568,31569,31570,31571,31572,31573,31574,31575,31576,31577,31578,31579, +31580,31581,31582,31583,31584,31585,31586,31587,31588,31589,31590,31591, +31592,31593,31594,31595,31596,31597,31598,31599,31600,31601,31602,31603, +31604,31605,31606,31607,31608,31609,31610,31611,31612,31613,31614,31615, +31616,31617,31618,31619,31620,31621,31622,31623,31624,31625,31626,31627, +31628,31629,31630,31631,31632,31633,31634,31635,31636,31637,31638,31639, +31640,31641,31642,31643,31644,31645,31646,31647,31648,31649,31650,31651, +31652,31653,31654,31655,31656,31657,31658,31659,31660,31661,31662,31663, +31664,31665,31666,31667,31668,31669,31670,31671,31672,31673,31674,31675, +31676,31677,31678,31679,31680,31681,31682,31683,31684,31685,31686,31687, +31688,31689,31690,31691,31692,31693,31694,31695,31696,31697,31698,31699, +31700,31701,31702,31703,31704,31705,31706,31707,31708,31709,31710,31711, +31712,31713,31714,31715,31716,31717,31718,31719,31720,31721,31722,31723, +31724,31725,31726,31727,31728,31729,31730,31731,31732,31733,31734,31735, +31736,31737,31738,31739,31740,31741,31742,31743,31744,31745,31746,31747, +31748,31749,31750,31751,31752,31753,31754,31755,31756,31757,31758,31759, +31760,31761,31762,31763,31764,31765,31766,31767,31768,31769,31770,31771, +31772,31773,31774,31775,31776,31777,31778,31779,31780,31781,31782,31783, +31784,31785,31786,31787,31788,31789,31790,31791,31792,31793,31794,31795, +31796,31797,31798,31799,31800,31801,31802,31803,31804,31805,31806,31807, +31808,31809,31810,31811,31812,31813,31814,31815,31816,31817,31818,31819, +31820,31821,31822,31823,31824,31825,31826,31827,31828,31829,31830,31831, +31832,31833,31834,31835,31836,31837,31838,31839,31840,31841,31842,31843, +31844,31845,31846,31847,31848,31849,31850,31851,31852,31853,31854,31855, +31856,31857,31858,31859,31860,31861,31862,31863,31864,31865,31866,31867, +31868,31869,31870,31871,31872,31873,31874,31875,31876,31877,31878,31879, +31880,31881,31882,31883,31884,31885,31886,31887,31888,31889,31890,31891, +31892,31893,31894,31895,31896,31897,31898,31899,31900,31901,31902,31903, +31904,31905,31906,31907,31908,31909,31910,31911,31912,31913,31914,31915, +31916,31917,31918,31919,31920,31921,31922,31923,31924,31925,31926,31927, +31928,31929,31930,31931,31932,31933,31934,31935,31936,31937,31938,31939, +31940,31941,31942,31943,31944,31945,31946,31947,31948,31949,31950,31951, +31952,31953,31954,31955,31956,31957,31958,31959,31960,31961,31962,31963, +31964,31965,31966,31967,31968,31969,31970,31971,31972,31973,31974,31975, +31976,31977,31978,31979,31980,31981,31982,31983,31984,31985,31986,31987, +31988,31989,31990,31991,31992,31993,31994,31995,31996,31997,31998,31999, +32000,32001,32002,32003,32004,32005,32006,32007,32008,32009,32010,32011, +32012,32013,32014,32015,32016,32017,32018,32019,32020,32021,32022,32023, +32024,32025,32026,32027,32028,32029,32030,32031,32032,32033,32034,32035, +32036,32037,32038,32039,32040,32041,32042,32043,32044,32045,32046,32047, +32048,32049,32050,32051,32052,32053,32054,32055,32056,32057,32058,32059, +32060,32061,32062,32063,32064,32065,32066,32067,32068,32069,32070,32071, +32072,32073,32074,32075,32076,32077,32078,32079,32080,32081,32082,32083, +32084,32085,32086,32087,32088,32089,32090,32091,32092,32093,32094,32095, +32096,32097,32098,32099,32100,32101,32102,32103,32104,32105,32106,32107, +32108,32109,32110,32111,32112,32113,32114,32115,32116,32117,32118,32119, +32120,32121,32122,32123,32124,32125,32126,32127,32128,32129,32130,32131, +32132,32133,32134,32135,32136,32137,32138,32139,32140,32141,32142,32143, +32144,32145,32146,32147,32148,32149,32150,32151,32152,32153,32154,32155, +32156,32157,32158,32159,32160,32161,32162,32163,32164,32165,32166,32167, +32168,32169,32170,32171,32172,32173,32174,32175,32176,32177,32178,32179, +32180,32181,32182,32183,32184,32185,32186,32187,32188,32189,32190,32191, +32192,32193,32194,32195,32196,32197,32198,32199,32200,32201,32202,32203, +32204,32205,32206,32207,32208,32209,32210,32211,32212,32213,32214,32215, +32216,32217,32218,32219,32220,32221,32222,32223,32224,32225,32226,32227, +32228,32229,32230,32231,32232,32233,32234,32235,32236,32237,32238,32239, +32240,32241,32242,32243,32244,32245,32246,32247,32248,32249,32250,32251, +32252,32253,32254,32255,32256,32257,32258,32259,32260,32261,32262,32263, +32264,32265,32266,32267,32268,32269,32270,32271,32272,32273,32274,32275, +32276,32277,32278,32279,32280,32281,32282,32283,32284,32285,32286,32287, +32288,32289,32290,32291,32292,32293,32294,32295,32296,32297,32298,32299, +32300,32301,32302,32303,32304,32305,32306,32307,32308,32309,32310,32311, +32312,32313,32314,32315,32316,32317,32318,32319,32320,32321,32322,32323, +32324,32325,32326,32327,32328,32329,32330,32331,32332,32333,32334,32335, +32336,32337,32338,32339,32340,32341,32342,32343,32344,32345,32346,32347, +32348,32349,32350,32351,32352,32353,32354,32355,32356,32357,32358,32359, +32360,32361,32362,32363,32364,32365,32366,32367,32368,32369,32370,32371, +32372,32373,32374,32375,32376,32377,32378,32379,32380,32381,32382,32383, +32384,32385,32386,32387,32388,32389,32390,32391,32392,32393,32394,32395, +32396,32397,32398,32399,32400,32401,32402,32403,32404,32405,32406,32407, +32408,32409,32410,32411,32412,32413,32414,32415,32416,32417,32418,32419, +32420,32421,32422,32423,32424,32425,32426,32427,32428,32429,32430,32431, +32432,32433,32434,32435,32436,32437,32438,32439,32440,32441,32442,32443, +32444,32445,32446,32447,32448,32449,32450,32451,32452,32453,32454,32455, +32456,32457,32458,32459,32460,32461,32462,32463,32464,32465,32466,32467, +32468,32469,32470,32471,32472,32473,32474,32475,32476,32477,32478,32479, +32480,32481,32482,32483,32484,32485,32486,32487,32488,32489,32490,32491, +32492,32493,32494,32495,32496,32497,32498,32499,32500,32501,32502,32503, +32504,32505,32506,32507,32508,32509,32510,32511,32512,32513,32514,32515, +32516,32517,32518,32519,32520,32521,32522,32523,32524,32525,32526,32527, +32528,32529,32530,32531,32532,32533,32534,32535,32536,32537,32538,32539, +32540,32541,32542,32543,32544,32545,32546,32547,32548,32549,32550,32551, +32552,32553,32554,32555,32556,32557,32558,32559,32560,32561,32562,32563, +32564,32565,32566,32567,32568,32569,32570,32571,32572,32573,32574,32575, +32576,32577,32578,32579,32580,32581,32582,32583,32584,32585,32586,32587, +32588,32589,32590,32591,32592,32593,32594,32595,32596,32597,32598,32599, +32600,32601,32602,32603,32604,32605,32606,32607,32608,32609,32610,32611, +32612,32613,32614,32615,32616,32617,32618,32619,32620,32621,32622,32623, +32624,32625,32626,32627,32628,32629,32630,32631,32632,32633,32634,32635, +32636,32637,32638,32639,32640,32641,32642,32643,32644,32645,32646,32647, +32648,32649,32650,32651,32652,32653,32654,32655,32656,32657,32658,32659, +32660,32661,32662,32663,32664,32665,32666,32667,32668,32669,32670,32671, +32672,32673,32674,32675,32676,32677,32678,32679,32680,32681,32682,32683, +32684,32685,32686,32687,32688,32689,32690,32691,32692,32693,32694,32695, +32696,32697,32698,32699,32700,32701,32702,32703,32704,32705,32706,32707, +32708,32709,32710,32711,32712,32713,32714,32715,32716,32717,32718,32719, +32720,32721,32722,32723,32724,32725,32726,32727,32728,32729,32730,32731, +32732,32733,32734,32735,32736,32737,32738,32739,32740,32741,32742,32743, +32744,32745,32746,32747,32748,32749,32750,32751,32752,32753,32754,32755, +32756,32757,32758,32759,32760,32761,32762,32763,32764,32765,32766,32767, +32768L,32769L,32770L,32771L,32772L,32773L,32774L,32775L,32776L,32777L, +32778L,32779L,32780L,32781L,32782L,32783L,32784L,32785L,32786L,32787L, +32788L,32789L,32790L,32791L,32792L,32793L,32794L,32795L,32796L,32797L, +32798L,32799L,32800L,32801L,32802L,32803L,32804L,32805L,32806L,32807L, +32808L,32809L,32810L,32811L,32812L,32813L,32814L,32815L,32816L,32817L, +32818L,32819L,32820L,32821L,32822L,32823L,32824L,32825L,32826L,32827L, +32828L,32829L,32830L,32831L,32832L,32833L,32834L,32835L,32836L,32837L, +32838L,32839L,32840L,32841L,32842L,32843L,32844L,32845L,32846L,32847L, +32848L,32849L,32850L,32851L,32852L,32853L,32854L,32855L,32856L,32857L, +32858L,32859L,32860L,32861L,32862L,32863L,32864L,32865L,32866L,32867L, +32868L,32869L,32870L,32871L,32872L,32873L,32874L,32875L,32876L,32877L, +32878L,32879L,32880L,32881L,32882L,32883L,32884L,32885L,32886L,32887L, +32888L,32889L,32890L,32891L,32892L,32893L,32894L,32895L,32896L,32897L, +32898L,32899L,32900L,32901L,32902L,32903L,32904L,32905L,32906L,32907L, +32908L,32909L,32910L,32911L,32912L,32913L,32914L,32915L,32916L,32917L, +32918L,32919L,32920L,32921L,32922L,32923L,32924L,32925L,32926L,32927L, +32928L,32929L,32930L,32931L,32932L,32933L,32934L,32935L,32936L,32937L, +32938L,32939L,32940L,32941L,32942L,32943L,32944L,32945L,32946L,32947L, +32948L,32949L,32950L,32951L,32952L,32953L,32954L,32955L,32956L,32957L, +32958L,32959L,32960L,32961L,32962L,32963L,32964L,32965L,32966L,32967L, +32968L,32969L,32970L,32971L,32972L,32973L,32974L,32975L,32976L,32977L, +32978L,32979L,32980L,32981L,32982L,32983L,32984L,32985L,32986L,32987L, +32988L,32989L,32990L,32991L,32992L,32993L,32994L,32995L,32996L,32997L, +32998L,32999L,33000L,33001L,33002L,33003L,33004L,33005L,33006L,33007L, +33008L,33009L,33010L,33011L,33012L,33013L,33014L,33015L,33016L,33017L, +33018L,33019L,33020L,33021L,33022L,33023L,33024L,33025L,33026L,33027L, +33028L,33029L,33030L,33031L,33032L,33033L,33034L,33035L,33036L,33037L, +33038L,33039L,33040L,33041L,33042L,33043L,33044L,33045L,33046L,33047L, +33048L,33049L,33050L,33051L,33052L,33053L,33054L,33055L,33056L,33057L, +33058L,33059L,33060L,33061L,33062L,33063L,33064L,33065L,33066L,33067L, +33068L,33069L,33070L,33071L,33072L,33073L,33074L,33075L,33076L,33077L, +33078L,33079L,33080L,33081L,33082L,33083L,33084L,33085L,33086L,33087L, +33088L,33089L,33090L,33091L,33092L,33093L,33094L,33095L,33096L,33097L, +33098L,33099L,33100L,33101L,33102L,33103L,33104L,33105L,33106L,33107L, +33108L,33109L,33110L,33111L,33112L,33113L,33114L,33115L,33116L,33117L, +33118L,33119L,33120L,33121L,33122L,33123L,33124L,33125L,33126L,33127L, +33128L,33129L,33130L,33131L,33132L,33133L,33134L,33135L,33136L,33137L, +33138L,33139L,33140L,33141L,33142L,33143L,33144L,33145L,33146L,33147L, +33148L,33149L,33150L,33151L,33152L,33153L,33154L,33155L,33156L,33157L, +33158L,33159L,33160L,33161L,33162L,33163L,33164L,33165L,33166L,33167L, +33168L,33169L,33170L,33171L,33172L,33173L,33174L,33175L,33176L,33177L, +33178L,33179L,33180L,33181L,33182L,33183L,33184L,33185L,33186L,33187L, +33188L,33189L,33190L,33191L,33192L,33193L,33194L,33195L,33196L,33197L, +33198L,33199L,33200L,33201L,33202L,33203L,33204L,33205L,33206L,33207L, +33208L,33209L,33210L,33211L,33212L,33213L,33214L,33215L,33216L,33217L, +33218L,33219L,33220L,33221L,33222L,33223L,33224L,33225L,33226L,33227L, +33228L,33229L,33230L,33231L,33232L,33233L,33234L,33235L,33236L,33237L, +33238L,33239L,33240L,33241L,33242L,33243L,33244L,33245L,33246L,33247L, +33248L,33249L,33250L,33251L,33252L,33253L,33254L,33255L,33256L,33257L, +33258L,33259L,33260L,33261L,33262L,33263L,33264L,33265L,33266L,33267L, +33268L,33269L,33270L,33271L,33272L,33273L,33274L,33275L,33276L,33277L, +33278L,33279L,33280L,33281L,33282L,33283L,33284L,33285L,33286L,33287L, +33288L,33289L,33290L,33291L,33292L,33293L,33294L,33295L,33296L,33297L, +33298L,33299L,33300L,33301L,33302L,33303L,33304L,33305L,33306L,33307L, +33308L,33309L,33310L,33311L,33312L,33313L,33314L,33315L,33316L,33317L, +33318L,33319L,33320L,33321L,33322L,33323L,33324L,33325L,33326L,33327L, +33328L,33329L,33330L,33331L,33332L,33333L,33334L,33335L,33336L,33337L, +33338L,33339L,33340L,33341L,33342L,33343L,33344L,33345L,33346L,33347L, +33348L,33349L,33350L,33351L,33352L,33353L,33354L,33355L,33356L,33357L, +33358L,33359L,33360L,33361L,33362L,33363L,33364L,33365L,33366L,33367L, +33368L,33369L,33370L,33371L,33372L,33373L,33374L,33375L,33376L,33377L, +33378L,33379L,33380L,33381L,33382L,33383L,33384L,33385L,33386L,33387L, +33388L,33389L,33390L,33391L,33392L,33393L,33394L,33395L,33396L,33397L, +33398L,33399L,33400L,33401L,33402L,33403L,33404L,33405L,33406L,33407L, +33408L,33409L,33410L,33411L,33412L,33413L,33414L,33415L,33416L,33417L, +33418L,33419L,33420L,33421L,33422L,33423L,33424L,33425L,33426L,33427L, +33428L,33429L,33430L,33431L,33432L,33433L,33434L,33435L,33436L,33437L, +33438L,33439L,33440L,33441L,33442L,33443L,33444L,33445L,33446L,33447L, +33448L,33449L,33450L,33451L,33452L,33453L,33454L,33455L,33456L,33457L, +33458L,33459L,33460L,33461L,33462L,33463L,33464L,33465L,33466L,33467L, +33468L,33469L,33470L,33471L,33472L,33473L,33474L,33475L,33476L,33477L, +33478L,33479L,33480L,33481L,33482L,33483L,33484L,33485L,33486L,33487L, +33488L,33489L,33490L,33491L,33492L,33493L,33494L,33495L,33496L,33497L, +33498L,33499L,33500L,33501L,33502L,33503L,33504L,33505L,33506L,33507L, +33508L,33509L,33510L,33511L,33512L,33513L,33514L,33515L,33516L,33517L, +33518L,33519L,33520L,33521L,33522L,33523L,33524L,33525L,33526L,33527L, +33528L,33529L,33530L,33531L,33532L,33533L,33534L,33535L,33536L,33537L, +33538L,33539L,33540L,33541L,33542L,33543L,33544L,33545L,33546L,33547L, +33548L,33549L,33550L,33551L,33552L,33553L,33554L,33555L,33556L,33557L, +33558L,33559L,33560L,33561L,33562L,33563L,33564L,33565L,33566L,33567L, +33568L,33569L,33570L,33571L,33572L,33573L,33574L,33575L,33576L,33577L, +33578L,33579L,33580L,33581L,33582L,33583L,33584L,33585L,33586L,33587L, +33588L,33589L,33590L,33591L,33592L,33593L,33594L,33595L,33596L,33597L, +33598L,33599L,33600L,33601L,33602L,33603L,33604L,33605L,33606L,33607L, +33608L,33609L,33610L,33611L,33612L,33613L,33614L,33615L,33616L,33617L, +33618L,33619L,33620L,33621L,33622L,33623L,33624L,33625L,33626L,33627L, +33628L,33629L,33630L,33631L,33632L,33633L,33634L,33635L,33636L,33637L, +33638L,33639L,33640L,33641L,33642L,33643L,33644L,33645L,33646L,33647L, +33648L,33649L,33650L,33651L,33652L,33653L,33654L,33655L,33656L,33657L, +33658L,33659L,33660L,33661L,33662L,33663L,33664L,33665L,33666L,33667L, +33668L,33669L,33670L,33671L,33672L,33673L,33674L,33675L,33676L,33677L, +33678L,33679L,33680L,33681L,33682L,33683L,33684L,33685L,33686L,33687L, +33688L,33689L,33690L,33691L,33692L,33693L,33694L,33695L,33696L,33697L, +33698L,33699L,33700L,33701L,33702L,33703L,33704L,33705L,33706L,33707L, +33708L,33709L,33710L,33711L,33712L,33713L,33714L,33715L,33716L,33717L, +33718L,33719L,33720L,33721L,33722L,33723L,33724L,33725L,33726L,33727L, +33728L,33729L,33730L,33731L,33732L,33733L,33734L,33735L,33736L,33737L, +33738L,33739L,33740L,33741L,33742L,33743L,33744L,33745L,33746L,33747L, +33748L,33749L,33750L,33751L,33752L,33753L,33754L,33755L,33756L,33757L, +33758L,33759L,33760L,33761L,33762L,33763L,33764L,33765L,33766L,33767L, +33768L,33769L,33770L,33771L,33772L,33773L,33774L,33775L,33776L,33777L, +33778L,33779L,33780L,33781L,33782L,33783L,33784L,33785L,33786L,33787L, +33788L,33789L,33790L,33791L,33792L,33793L,33794L,33795L,33796L,33797L, +33798L,33799L,33800L,33801L,33802L,33803L,33804L,33805L,33806L,33807L, +33808L,33809L,33810L,33811L,33812L,33813L,33814L,33815L,33816L,33817L, +33818L,33819L,33820L,33821L,33822L,33823L,33824L,33825L,33826L,33827L, +33828L,33829L,33830L,33831L,33832L,33833L,33834L,33835L,33836L,33837L, +33838L,33839L,33840L,33841L,33842L,33843L,33844L,33845L,33846L,33847L, +33848L,33849L,33850L,33851L,33852L,33853L,33854L,33855L,33856L,33857L, +33858L,33859L,33860L,33861L,33862L,33863L,33864L,33865L,33866L,33867L, +33868L,33869L,33870L,33871L,33872L,33873L,33874L,33875L,33876L,33877L, +33878L,33879L,33880L,33881L,33882L,33883L,33884L,33885L,33886L,33887L, +33888L,33889L,33890L,33891L,33892L,33893L,33894L,33895L,33896L,33897L, +33898L,33899L,33900L,33901L,33902L,33903L,33904L,33905L,33906L,33907L, +33908L,33909L,33910L,33911L,33912L,33913L,33914L,33915L,33916L,33917L, +33918L,33919L,33920L,33921L,33922L,33923L,33924L,33925L,33926L,33927L, +33928L,33929L,33930L,33931L,33932L,33933L,33934L,33935L,33936L,33937L, +33938L,33939L,33940L,33941L,33942L,33943L,33944L,33945L,33946L,33947L, +33948L,33949L,33950L,33951L,33952L,33953L,33954L,33955L,33956L,33957L, +33958L,33959L,33960L,33961L,33962L,33963L,33964L,33965L,33966L,33967L, +33968L,33969L,33970L,33971L,33972L,33973L,33974L,33975L,33976L,33977L, +33978L,33979L,33980L,33981L,33982L,33983L,33984L,33985L,33986L,33987L, +33988L,33989L,33990L,33991L,33992L,33993L,33994L,33995L,33996L,33997L, +33998L,33999L,34000L,34001L,34002L,34003L,34004L,34005L,34006L,34007L, +34008L,34009L,34010L,34011L,34012L,34013L,34014L,34015L,34016L,34017L, +34018L,34019L,34020L,34021L,34022L,34023L,34024L,34025L,34026L,34027L, +34028L,34029L,34030L,34031L,34032L,34033L,34034L,34035L,34036L,34037L, +34038L,34039L,34040L,34041L,34042L,34043L,34044L,34045L,34046L,34047L, +34048L,34049L,34050L,34051L,34052L,34053L,34054L,34055L,34056L,34057L, +34058L,34059L,34060L,34061L,34062L,34063L,34064L,34065L,34066L,34067L, +34068L,34069L,34070L,34071L,34072L,34073L,34074L,34075L,34076L,34077L, +34078L,34079L,34080L,34081L,34082L,34083L,34084L,34085L,34086L,34087L, +34088L,34089L,34090L,34091L,34092L,34093L,34094L,34095L,34096L,34097L, +34098L,34099L,34100L,34101L,34102L,34103L,34104L,34105L,34106L,34107L, +34108L,34109L,34110L,34111L,34112L,34113L,34114L,34115L,34116L,34117L, +34118L,34119L,34120L,34121L,34122L,34123L,34124L,34125L,34126L,34127L, +34128L,34129L,34130L,34131L,34132L,34133L,34134L,34135L,34136L,34137L, +34138L,34139L,34140L,34141L,34142L,34143L,34144L,34145L,34146L,34147L, +34148L,34149L,34150L,34151L,34152L,34153L,34154L,34155L,34156L,34157L, +34158L,34159L,34160L,34161L,34162L,34163L,34164L,34165L,34166L,34167L, +34168L,34169L,34170L,34171L,34172L,34173L,34174L,34175L,34176L,34177L, +34178L,34179L,34180L,34181L,34182L,34183L,34184L,34185L,34186L,34187L, +34188L,34189L,34190L,34191L,34192L,34193L,34194L,34195L,34196L,34197L, +34198L,34199L,34200L,34201L,34202L,34203L,34204L,34205L,34206L,34207L, +34208L,34209L,34210L,34211L,34212L,34213L,34214L,34215L,34216L,34217L, +34218L,34219L,34220L,34221L,34222L,34223L,34224L,34225L,34226L,34227L, +34228L,34229L,34230L,34231L,34232L,34233L,34234L,34235L,34236L,34237L, +34238L,34239L,34240L,34241L,34242L,34243L,34244L,34245L,34246L,34247L, +34248L,34249L,34250L,34251L,34252L,34253L,34254L,34255L,34256L,34257L, +34258L,34259L,34260L,34261L,34262L,34263L,34264L,34265L,34266L,34267L, +34268L,34269L,34270L,34271L,34272L,34273L,34274L,34275L,34276L,34277L, +34278L,34279L,34280L,34281L,34282L,34283L,34284L,34285L,34286L,34287L, +34288L,34289L,34290L,34291L,34292L,34293L,34294L,34295L,34296L,34297L, +34298L,34299L,34300L,34301L,34302L,34303L,34304L,34305L,34306L,34307L, +34308L,34309L,34310L,34311L,34312L,34313L,34314L,34315L,34316L,34317L, +34318L,34319L,34320L,34321L,34322L,34323L,34324L,34325L,34326L,34327L, +34328L,34329L,34330L,34331L,34332L,34333L,34334L,34335L,34336L,34337L, +34338L,34339L,34340L,34341L,34342L,34343L,34344L,34345L,34346L,34347L, +34348L,34349L,34350L,34351L,34352L,34353L,34354L,34355L,34356L,34357L, +34358L,34359L,34360L,34361L,34362L,34363L,34364L,34365L,34366L,34367L, +34368L,34369L,34370L,34371L,34372L,34373L,34374L,34375L,34376L,34377L, +34378L,34379L,34380L,34381L,34382L,34383L,34384L,34385L,34386L,34387L, +34388L,34389L,34390L,34391L,34392L,34393L,34394L,34395L,34396L,34397L, +34398L,34399L,34400L,34401L,34402L,34403L,34404L,34405L,34406L,34407L, +34408L,34409L,34410L,34411L,34412L,34413L,34414L,34415L,34416L,34417L, +34418L,34419L,34420L,34421L,34422L,34423L,34424L,34425L,34426L,34427L, +34428L,34429L,34430L,34431L,34432L,34433L,34434L,34435L,34436L,34437L, +34438L,34439L,34440L,34441L,34442L,34443L,34444L,34445L,34446L,34447L, +34448L,34449L,34450L,34451L,34452L,34453L,34454L,34455L,34456L,34457L, +34458L,34459L,34460L,34461L,34462L,34463L,34464L,34465L,34466L,34467L, +34468L,34469L,34470L,34471L,34472L,34473L,34474L,34475L,34476L,34477L, +34478L,34479L,34480L,34481L,34482L,34483L,34484L,34485L,34486L,34487L, +34488L,34489L,34490L,34491L,34492L,34493L,34494L,34495L,34496L,34497L, +34498L,34499L,34500L,34501L,34502L,34503L,34504L,34505L,34506L,34507L, +34508L,34509L,34510L,34511L,34512L,34513L,34514L,34515L,34516L,34517L, +34518L,34519L,34520L,34521L,34522L,34523L,34524L,34525L,34526L,34527L, +34528L,34529L,34530L,34531L,34532L,34533L,34534L,34535L,34536L,34537L, +34538L,34539L,34540L,34541L,34542L,34543L,34544L,34545L,34546L,34547L, +34548L,34549L,34550L,34551L,34552L,34553L,34554L,34555L,34556L,34557L, +34558L,34559L,34560L,34561L,34562L,34563L,34564L,34565L,34566L,34567L, +34568L,34569L,34570L,34571L,34572L,34573L,34574L,34575L,34576L,34577L, +34578L,34579L,34580L,34581L,34582L,34583L,34584L,34585L,34586L,34587L, +34588L,34589L,34590L,34591L,34592L,34593L,34594L,34595L,34596L,34597L, +34598L,34599L,34600L,34601L,34602L,34603L,34604L,34605L,34606L,34607L, +34608L,34609L,34610L,34611L,34612L,34613L,34614L,34615L,34616L,34617L, +34618L,34619L,34620L,34621L,34622L,34623L,34624L,34625L,34626L,34627L, +34628L,34629L,34630L,34631L,34632L,34633L,34634L,34635L,34636L,34637L, +34638L,34639L,34640L,34641L,34642L,34643L,34644L,34645L,34646L,34647L, +34648L,34649L,34650L,34651L,34652L,34653L,34654L,34655L,34656L,34657L, +34658L,34659L,34660L,34661L,34662L,34663L,34664L,34665L,34666L,34667L, +34668L,34669L,34670L,34671L,34672L,34673L,34674L,34675L,34676L,34677L, +34678L,34679L,34680L,34681L,34682L,34683L,34684L,34685L,34686L,34687L, +34688L,34689L,34690L,34691L,34692L,34693L,34694L,34695L,34696L,34697L, +34698L,34699L,34700L,34701L,34702L,34703L,34704L,34705L,34706L,34707L, +34708L,34709L,34710L,34711L,34712L,34713L,34714L,34715L,34716L,34717L, +34718L,34719L,34720L,34721L,34722L,34723L,34724L,34725L,34726L,34727L, +34728L,34729L,34730L,34731L,34732L,34733L,34734L,34735L,34736L,34737L, +34738L,34739L,34740L,34741L,34742L,34743L,34744L,34745L,34746L,34747L, +34748L,34749L,34750L,34751L,34752L,34753L,34754L,34755L,34756L,34757L, +34758L,34759L,34760L,34761L,34762L,34763L,34764L,34765L,34766L,34767L, +34768L,34769L,34770L,34771L,34772L,34773L,34774L,34775L,34776L,34777L, +34778L,34779L,34780L,34781L,34782L,34783L,34784L,34785L,34786L,34787L, +34788L,34789L,34790L,34791L,34792L,34793L,34794L,34795L,34796L,34797L, +34798L,34799L,34800L,34801L,34802L,34803L,34804L,34805L,34806L,34807L, +34808L,34809L,34810L,34811L,34812L,34813L,34814L,34815L,34816L,34817L, +34818L,34819L,34820L,34821L,34822L,34823L,34824L,34825L,34826L,34827L, +34828L,34829L,34830L,34831L,34832L,34833L,34834L,34835L,34836L,34837L, +34838L,34839L,34840L,34841L,34842L,34843L,34844L,34845L,34846L,34847L, +34848L,34849L,34850L,34851L,34852L,34853L,34854L,34855L,34856L,34857L, +34858L,34859L,34860L,34861L,34862L,34863L,34864L,34865L,34866L,34867L, +34868L,34869L,34870L,34871L,34872L,34873L,34874L,34875L,34876L,34877L, +34878L,34879L,34880L,34881L,34882L,34883L,34884L,34885L,34886L,34887L, +34888L,34889L,34890L,34891L,34892L,34893L,34894L,34895L,34896L,34897L, +34898L,34899L,34900L,34901L,34902L,34903L,34904L,34905L,34906L,34907L, +34908L,34909L,34910L,34911L,34912L,34913L,34914L,34915L,34916L,34917L, +34918L,34919L,34920L,34921L,34922L,34923L,34924L,34925L,34926L,34927L, +34928L,34929L,34930L,34931L,34932L,34933L,34934L,34935L,34936L,34937L, +34938L,34939L,34940L,34941L,34942L,34943L,34944L,34945L,34946L,34947L, +34948L,34949L,34950L,34951L,34952L,34953L,34954L,34955L,34956L,34957L, +34958L,34959L,34960L,34961L,34962L,34963L,34964L,34965L,34966L,34967L, +34968L,34969L,34970L,34971L,34972L,34973L,34974L,34975L,34976L,34977L, +34978L,34979L,34980L,34981L,34982L,34983L,34984L,34985L,34986L,34987L, +34988L,34989L,34990L,34991L,34992L,34993L,34994L,34995L,34996L,34997L, +34998L,34999L,35000L,35001L,35002L,35003L,35004L,35005L,35006L,35007L, +35008L,35009L,35010L,35011L,35012L,35013L,35014L,35015L,35016L,35017L, +35018L,35019L,35020L,35021L,35022L,35023L,35024L,35025L,35026L,35027L, +35028L,35029L,35030L,35031L,35032L,35033L,35034L,35035L,35036L,35037L, +35038L,35039L,35040L,35041L,35042L,35043L,35044L,35045L,35046L,35047L, +35048L,35049L,35050L,35051L,35052L,35053L,35054L,35055L,35056L,35057L, +35058L,35059L,35060L,35061L,35062L,35063L,35064L,35065L,35066L,35067L, +35068L,35069L,35070L,35071L,35072L,35073L,35074L,35075L,35076L,35077L, +35078L,35079L,35080L,35081L,35082L,35083L,35084L,35085L,35086L,35087L, +35088L,35089L,35090L,35091L,35092L,35093L,35094L,35095L,35096L,35097L, +35098L,35099L,35100L,35101L,35102L,35103L,35104L,35105L,35106L,35107L, +35108L,35109L,35110L,35111L,35112L,35113L,35114L,35115L,35116L,35117L, +35118L,35119L,35120L,35121L,35122L,35123L,35124L,35125L,35126L,35127L, +35128L,35129L,35130L,35131L,35132L,35133L,35134L,35135L,35136L,35137L, +35138L,35139L,35140L,35141L,35142L,35143L,35144L,35145L,35146L,35147L, +35148L,35149L,35150L,35151L,35152L,35153L,35154L,35155L,35156L,35157L, +35158L,35159L,35160L,35161L,35162L,35163L,35164L,35165L,35166L,35167L, +35168L,35169L,35170L,35171L,35172L,35173L,35174L,35175L,35176L,35177L, +35178L,35179L,35180L,35181L,35182L,35183L,35184L,35185L,35186L,35187L, +35188L,35189L,35190L,35191L,35192L,35193L,35194L,35195L,35196L,35197L, +35198L,35199L,35200L,35201L,35202L,35203L,35204L,35205L,35206L,35207L, +35208L,35209L,35210L,35211L,35212L,35213L,35214L,35215L,35216L,35217L, +35218L,35219L,35220L,35221L,35222L,35223L,35224L,35225L,35226L,35227L, +35228L,35229L,35230L,35231L,35232L,35233L,35234L,35235L,35236L,35237L, +35238L,35239L,35240L,35241L,35242L,35243L,35244L,35245L,35246L,35247L, +35248L,35249L,35250L,35251L,35252L,35253L,35254L,35255L,35256L,35257L, +35258L,35259L,35260L,35261L,35262L,35263L,35264L,35265L,35266L,35267L, +35268L,35269L,35270L,35271L,35272L,35273L,35274L,35275L,35276L,35277L, +35278L,35279L,35280L,35281L,35282L,35283L,35284L,35285L,35286L,35287L, +35288L,35289L,35290L,35291L,35292L,35293L,35294L,35295L,35296L,35297L, +35298L,35299L,35300L,35301L,35302L,35303L,35304L,35305L,35306L,35307L, +35308L,35309L,35310L,35311L,35312L,35313L,35314L,35315L,35316L,35317L, +35318L,35319L,35320L,35321L,35322L,35323L,35324L,35325L,35326L,35327L, +35328L,35329L,35330L,35331L,35332L,35333L,35334L,35335L,35336L,35337L, +35338L,35339L,35340L,35341L,35342L,35343L,35344L,35345L,35346L,35347L, +35348L,35349L,35350L,35351L,35352L,35353L,35354L,35355L,35356L,35357L, +35358L,35359L,35360L,35361L,35362L,35363L,35364L,35365L,35366L,35367L, +35368L,35369L,35370L,35371L,35372L,35373L,35374L,35375L,35376L,35377L, +35378L,35379L,35380L,35381L,35382L,35383L,35384L,35385L,35386L,35387L, +35388L,35389L,35390L,35391L,35392L,35393L,35394L,35395L,35396L,35397L, +35398L,35399L,35400L,35401L,35402L,35403L,35404L,35405L,35406L,35407L, +35408L,35409L,35410L,35411L,35412L,35413L,35414L,35415L,35416L,35417L, +35418L,35419L,35420L,35421L,35422L,35423L,35424L,35425L,35426L,35427L, +35428L,35429L,35430L,35431L,35432L,35433L,35434L,35435L,35436L,35437L, +35438L,35439L,35440L,35441L,35442L,35443L,35444L,35445L,35446L,35447L, +35448L,35449L,35450L,35451L,35452L,35453L,35454L,35455L,35456L,35457L, +35458L,35459L,35460L,35461L,35462L,35463L,35464L,35465L,35466L,35467L, +35468L,35469L,35470L,35471L,35472L,35473L,35474L,35475L,35476L,35477L, +35478L,35479L,35480L,35481L,35482L,35483L,35484L,35485L,35486L,35487L, +35488L,35489L,35490L,35491L,35492L,35493L,35494L,35495L,35496L,35497L, +35498L,35499L,35500L,35501L,35502L,35503L,35504L,35505L,35506L,35507L, +35508L,35509L,35510L,35511L,35512L,35513L,35514L,35515L,35516L,35517L, +35518L,35519L,35520L,35521L,35522L,35523L,35524L,35525L,35526L,35527L, +35528L,35529L,35530L,35531L,35532L,35533L,35534L,35535L,35536L,35537L, +35538L,35539L,35540L,35541L,35542L,35543L,35544L,35545L,35546L,35547L, +35548L,35549L,35550L,35551L,35552L,35553L,35554L,35555L,35556L,35557L, +35558L,35559L,35560L,35561L,35562L,35563L,35564L,35565L,35566L,35567L, +35568L,35569L,35570L,35571L,35572L,35573L,35574L,35575L,35576L,35577L, +35578L,35579L,35580L,35581L,35582L,35583L,35584L,35585L,35586L,35587L, +35588L,35589L,35590L,35591L,35592L,35593L,35594L,35595L,35596L,35597L, +35598L,35599L,35600L,35601L,35602L,35603L,35604L,35605L,35606L,35607L, +35608L,35609L,35610L,35611L,35612L,35613L,35614L,35615L,35616L,35617L, +35618L,35619L,35620L,35621L,35622L,35623L,35624L,35625L,35626L,35627L, +35628L,35629L,35630L,35631L,35632L,35633L,35634L,35635L,35636L,35637L, +35638L,35639L,35640L,35641L,35642L,35643L,35644L,35645L,35646L,35647L, +35648L,35649L,35650L,35651L,35652L,35653L,35654L,35655L,35656L,35657L, +35658L,35659L,35660L,35661L,35662L,35663L,35664L,35665L,35666L,35667L, +35668L,35669L,35670L,35671L,35672L,35673L,35674L,35675L,35676L,35677L, +35678L,35679L,35680L,35681L,35682L,35683L,35684L,35685L,35686L,35687L, +35688L,35689L,35690L,35691L,35692L,35693L,35694L,35695L,35696L,35697L, +35698L,35699L,35700L,35701L,35702L,35703L,35704L,35705L,35706L,35707L, +35708L,35709L,35710L,35711L,35712L,35713L,35714L,35715L,35716L,35717L, +35718L,35719L,35720L,35721L,35722L,35723L,35724L,35725L,35726L,35727L, +35728L,35729L,35730L,35731L,35732L,35733L,35734L,35735L,35736L,35737L, +35738L,35739L,35740L,35741L,35742L,35743L,35744L,35745L,35746L,35747L, +35748L,35749L,35750L,35751L,35752L,35753L,35754L,35755L,35756L,35757L, +35758L,35759L,35760L,35761L,35762L,35763L,35764L,35765L,35766L,35767L, +35768L,35769L,35770L,35771L,35772L,35773L,35774L,35775L,35776L,35777L, +35778L,35779L,35780L,35781L,35782L,35783L,35784L,35785L,35786L,35787L, +35788L,35789L,35790L,35791L,35792L,35793L,35794L,35795L,35796L,35797L, +35798L,35799L,35800L,35801L,35802L,35803L,35804L,35805L,35806L,35807L, +35808L,35809L,35810L,35811L,35812L,35813L,35814L,35815L,35816L,35817L, +35818L,35819L,35820L,35821L,35822L,35823L,35824L,35825L,35826L,35827L, +35828L,35829L,35830L,35831L,35832L,35833L,35834L,35835L,35836L,35837L, +35838L,35839L,35840L,35841L,35842L,35843L,35844L,35845L,35846L,35847L, +35848L,35849L,35850L,35851L,35852L,35853L,35854L,35855L,35856L,35857L, +35858L,35859L,35860L,35861L,35862L,35863L,35864L,35865L,35866L,35867L, +35868L,35869L,35870L,35871L,35872L,35873L,35874L,35875L,35876L,35877L, +35878L,35879L,35880L,35881L,35882L,35883L,35884L,35885L,35886L,35887L, +35888L,35889L,35890L,35891L,35892L,35893L,35894L,35895L,35896L,35897L, +35898L,35899L,35900L,35901L,35902L,35903L,35904L,35905L,35906L,35907L, +35908L,35909L,35910L,35911L,35912L,35913L,35914L,35915L,35916L,35917L, +35918L,35919L,35920L,35921L,35922L,35923L,35924L,35925L,35926L,35927L, +35928L,35929L,35930L,35931L,35932L,35933L,35934L,35935L,35936L,35937L, +35938L,35939L,35940L,35941L,35942L,35943L,35944L,35945L,35946L,35947L, +35948L,35949L,35950L,35951L,35952L,35953L,35954L,35955L,35956L,35957L, +35958L,35959L,35960L,35961L,35962L,35963L,35964L,35965L,35966L,35967L, +35968L,35969L,35970L,35971L,35972L,35973L,35974L,35975L,35976L,35977L, +35978L,35979L,35980L,35981L,35982L,35983L,35984L,35985L,35986L,35987L, +35988L,35989L,35990L,35991L,35992L,35993L,35994L,35995L,35996L,35997L, +35998L,35999L,36000L,36001L,36002L,36003L,36004L,36005L,36006L,36007L, +36008L,36009L,36010L,36011L,36012L,36013L,36014L,36015L,36016L,36017L, +36018L,36019L,36020L,36021L,36022L,36023L,36024L,36025L,36026L,36027L, +36028L,36029L,36030L,36031L,36032L,36033L,36034L,36035L,36036L,36037L, +36038L,36039L,36040L,36041L,36042L,36043L,36044L,36045L,36046L,36047L, +36048L,36049L,36050L,36051L,36052L,36053L,36054L,36055L,36056L,36057L, +36058L,36059L,36060L,36061L,36062L,36063L,36064L,36065L,36066L,36067L, +36068L,36069L,36070L,36071L,36072L,36073L,36074L,36075L,36076L,36077L, +36078L,36079L,36080L,36081L,36082L,36083L,36084L,36085L,36086L,36087L, +36088L,36089L,36090L,36091L,36092L,36093L,36094L,36095L,36096L,36097L, +36098L,36099L,36100L,36101L,36102L,36103L,36104L,36105L,36106L,36107L, +36108L,36109L,36110L,36111L,36112L,36113L,36114L,36115L,36116L,36117L, +36118L,36119L,36120L,36121L,36122L,36123L,36124L,36125L,36126L,36127L, +36128L,36129L,36130L,36131L,36132L,36133L,36134L,36135L,36136L,36137L, +36138L,36139L,36140L,36141L,36142L,36143L,36144L,36145L,36146L,36147L, +36148L,36149L,36150L,36151L,36152L,36153L,36154L,36155L,36156L,36157L, +36158L,36159L,36160L,36161L,36162L,36163L,36164L,36165L,36166L,36167L, +36168L,36169L,36170L,36171L,36172L,36173L,36174L,36175L,36176L,36177L, +36178L,36179L,36180L,36181L,36182L,36183L,36184L,36185L,36186L,36187L, +36188L,36189L,36190L,36191L,36192L,36193L,36194L,36195L,36196L,36197L, +36198L,36199L,36200L,36201L,36202L,36203L,36204L,36205L,36206L,36207L, +36208L,36209L,36210L,36211L,36212L,36213L,36214L,36215L,36216L,36217L, +36218L,36219L,36220L,36221L,36222L,36223L,36224L,36225L,36226L,36227L, +36228L,36229L,36230L,36231L,36232L,36233L,36234L,36235L,36236L,36237L, +36238L,36239L,36240L,36241L,36242L,36243L,36244L,36245L,36246L,36247L, +36248L,36249L,36250L,36251L,36252L,36253L,36254L,36255L,36256L,36257L, +36258L,36259L,36260L,36261L,36262L,36263L,36264L,36265L,36266L,36267L, +36268L,36269L,36270L,36271L,36272L,36273L,36274L,36275L,36276L,36277L, +36278L,36279L,36280L,36281L,36282L,36283L,36284L,36285L,36286L,36287L, +36288L,36289L,36290L,36291L,36292L,36293L,36294L,36295L,36296L,36297L, +36298L,36299L,36300L,36301L,36302L,36303L,36304L,36305L,36306L,36307L, +36308L,36309L,36310L,36311L,36312L,36313L,36314L,36315L,36316L,36317L, +36318L,36319L,36320L,36321L,36322L,36323L,36324L,36325L,36326L,36327L, +36328L,36329L,36330L,36331L,36332L,36333L,36334L,36335L,36336L,36337L, +36338L,36339L,36340L,36341L,36342L,36343L,36344L,36345L,36346L,36347L, +36348L,36349L,36350L,36351L,36352L,36353L,36354L,36355L,36356L,36357L, +36358L,36359L,36360L,36361L,36362L,36363L,36364L,36365L,36366L,36367L, +36368L,36369L,36370L,36371L,36372L,36373L,36374L,36375L,36376L,36377L, +36378L,36379L,36380L,36381L,36382L,36383L,36384L,36385L,36386L,36387L, +36388L,36389L,36390L,36391L,36392L,36393L,36394L,36395L,36396L,36397L, +36398L,36399L,36400L,36401L,36402L,36403L,36404L,36405L,36406L,36407L, +36408L,36409L,36410L,36411L,36412L,36413L,36414L,36415L,36416L,36417L, +36418L,36419L,36420L,36421L,36422L,36423L,36424L,36425L,36426L,36427L, +36428L,36429L,36430L,36431L,36432L,36433L,36434L,36435L,36436L,36437L, +36438L,36439L,36440L,36441L,36442L,36443L,36444L,36445L,36446L,36447L, +36448L,36449L,36450L,36451L,36452L,36453L,36454L,36455L,36456L,36457L, +36458L,36459L,36460L,36461L,36462L,36463L,36464L,36465L,36466L,36467L, +36468L,36469L,36470L,36471L,36472L,36473L,36474L,36475L,36476L,36477L, +36478L,36479L,36480L,36481L,36482L,36483L,36484L,36485L,36486L,36487L, +36488L,36489L,36490L,36491L,36492L,36493L,36494L,36495L,36496L,36497L, +36498L,36499L,36500L,36501L,36502L,36503L,36504L,36505L,36506L,36507L, +36508L,36509L,36510L,36511L,36512L,36513L,36514L,36515L,36516L,36517L, +36518L,36519L,36520L,36521L,36522L,36523L,36524L,36525L,36526L,36527L, +36528L,36529L,36530L,36531L,36532L,36533L,36534L,36535L,36536L,36537L, +36538L,36539L,36540L,36541L,36542L,36543L,36544L,36545L,36546L,36547L, +36548L,36549L,36550L,36551L,36552L,36553L,36554L,36555L,36556L,36557L, +36558L,36559L,36560L,36561L,36562L,36563L,36564L,36565L,36566L,36567L, +36568L,36569L,36570L,36571L,36572L,36573L,36574L,36575L,36576L,36577L, +36578L,36579L,36580L,36581L,36582L,36583L,36584L,36585L,36586L,36587L, +36588L,36589L,36590L,36591L,36592L,36593L,36594L,36595L,36596L,36597L, +36598L,36599L,36600L,36601L,36602L,36603L,36604L,36605L,36606L,36607L, +36608L,36609L,36610L,36611L,36612L,36613L,36614L,36615L,36616L,36617L, +36618L,36619L,36620L,36621L,36622L,36623L,36624L,36625L,36626L,36627L, +36628L,36629L,36630L,36631L,36632L,36633L,36634L,36635L,36636L,36637L, +36638L,36639L,36640L,36641L,36642L,36643L,36644L,36645L,36646L,36647L, +36648L,36649L,36650L,36651L,36652L,36653L,36654L,36655L,36656L,36657L, +36658L,36659L,36660L,36661L,36662L,36663L,36664L,36665L,36666L,36667L, +36668L,36669L,36670L,36671L,36672L,36673L,36674L,36675L,36676L,36677L, +36678L,36679L,36680L,36681L,36682L,36683L,36684L,36685L,36686L,36687L, +36688L,36689L,36690L,36691L,36692L,36693L,36694L,36695L,36696L,36697L, +36698L,36699L,36700L,36701L,36702L,36703L,36704L,36705L,36706L,36707L, +36708L,36709L,36710L,36711L,36712L,36713L,36714L,36715L,36716L,36717L, +36718L,36719L,36720L,36721L,36722L,36723L,36724L,36725L,36726L,36727L, +36728L,36729L,36730L,36731L,36732L,36733L,36734L,36735L,36736L,36737L, +36738L,36739L,36740L,36741L,36742L,36743L,36744L,36745L,36746L,36747L, +36748L,36749L,36750L,36751L,36752L,36753L,36754L,36755L,36756L,36757L, +36758L,36759L,36760L,36761L,36762L,36763L,36764L,36765L,36766L,36767L, +36768L,36769L,36770L,36771L,36772L,36773L,36774L,36775L,36776L,36777L, +36778L,36779L,36780L,36781L,36782L,36783L,36784L,36785L,36786L,36787L, +36788L,36789L,36790L,36791L,36792L,36793L,36794L,36795L,36796L,36797L, +36798L,36799L,36800L,36801L,36802L,36803L,36804L,36805L,36806L,36807L, +36808L,36809L,36810L,36811L,36812L,36813L,36814L,36815L,36816L,36817L, +36818L,36819L,36820L,36821L,36822L,36823L,36824L,36825L,36826L,36827L, +36828L,36829L,36830L,36831L,36832L,36833L,36834L,36835L,36836L,36837L, +36838L,36839L,36840L,36841L,36842L,36843L,36844L,36845L,36846L,36847L, +36848L,36849L,36850L,36851L,36852L,36853L,36854L,36855L,36856L,36857L, +36858L,36859L,36860L,36861L,36862L,36863L,36864L,36865L,36866L,36867L, +36868L,36869L,36870L,36871L,36872L,36873L,36874L,36875L,36876L,36877L, +36878L,36879L,36880L,36881L,36882L,36883L,36884L,36885L,36886L,36887L, +36888L,36889L,36890L,36891L,36892L,36893L,36894L,36895L,36896L,36897L, +36898L,36899L,36900L,36901L,36902L,36903L,36904L,36905L,36906L,36907L, +36908L,36909L,36910L,36911L,36912L,36913L,36914L,36915L,36916L,36917L, +36918L,36919L,36920L,36921L,36922L,36923L,36924L,36925L,36926L,36927L, +36928L,36929L,36930L,36931L,36932L,36933L,36934L,36935L,36936L,36937L, +36938L,36939L,36940L,36941L,36942L,36943L,36944L,36945L,36946L,36947L, +36948L,36949L,36950L,36951L,36952L,36953L,36954L,36955L,36956L,36957L, +36958L,36959L,36960L,36961L,36962L,36963L,36964L,36965L,36966L,36967L, +36968L,36969L,36970L,36971L,36972L,36973L,36974L,36975L,36976L,36977L, +36978L,36979L,36980L,36981L,36982L,36983L,36984L,36985L,36986L,36987L, +36988L,36989L,36990L,36991L,36992L,36993L,36994L,36995L,36996L,36997L, +36998L,36999L,37000L,37001L,37002L,37003L,37004L,37005L,37006L,37007L, +37008L,37009L,37010L,37011L,37012L,37013L,37014L,37015L,37016L,37017L, +37018L,37019L,37020L,37021L,37022L,37023L,37024L,37025L,37026L,37027L, +37028L,37029L,37030L,37031L,37032L,37033L,37034L,37035L,37036L,37037L, +37038L,37039L,37040L,37041L,37042L,37043L,37044L,37045L,37046L,37047L, +37048L,37049L,37050L,37051L,37052L,37053L,37054L,37055L,37056L,37057L, +37058L,37059L,37060L,37061L,37062L,37063L,37064L,37065L,37066L,37067L, +37068L,37069L,37070L,37071L,37072L,37073L,37074L,37075L,37076L,37077L, +37078L,37079L,37080L,37081L,37082L,37083L,37084L,37085L,37086L,37087L, +37088L,37089L,37090L,37091L,37092L,37093L,37094L,37095L,37096L,37097L, +37098L,37099L,37100L,37101L,37102L,37103L,37104L,37105L,37106L,37107L, +37108L,37109L,37110L,37111L,37112L,37113L,37114L,37115L,37116L,37117L, +37118L,37119L,37120L,37121L,37122L,37123L,37124L,37125L,37126L,37127L, +37128L,37129L,37130L,37131L,37132L,37133L,37134L,37135L,37136L,37137L, +37138L,37139L,37140L,37141L,37142L,37143L,37144L,37145L,37146L,37147L, +37148L,37149L,37150L,37151L,37152L,37153L,37154L,37155L,37156L,37157L, +37158L,37159L,37160L,37161L,37162L,37163L,37164L,37165L,37166L,37167L, +37168L,37169L,37170L,37171L,37172L,37173L,37174L,37175L,37176L,37177L, +37178L,37179L,37180L,37181L,37182L,37183L,37184L,37185L,37186L,37187L, +37188L,37189L,37190L,37191L,37192L,37193L,37194L,37195L,37196L,37197L, +37198L,37199L,37200L,37201L,37202L,37203L,37204L,37205L,37206L,37207L, +37208L,37209L,37210L,37211L,37212L,37213L,37214L,37215L,37216L,37217L, +37218L,37219L,37220L,37221L,37222L,37223L,37224L,37225L,37226L,37227L, +37228L,37229L,37230L,37231L,37232L,37233L,37234L,37235L,37236L,37237L, +37238L,37239L,37240L,37241L,37242L,37243L,37244L,37245L,37246L,37247L, +37248L,37249L,37250L,37251L,37252L,37253L,37254L,37255L,37256L,37257L, +37258L,37259L,37260L,37261L,37262L,37263L,37264L,37265L,37266L,37267L, +37268L,37269L,37270L,37271L,37272L,37273L,37274L,37275L,37276L,37277L, +37278L,37279L,37280L,37281L,37282L,37283L,37284L,37285L,37286L,37287L, +37288L,37289L,37290L,37291L,37292L,37293L,37294L,37295L,37296L,37297L, +37298L,37299L,37300L,37301L,37302L,37303L,37304L,37305L,37306L,37307L, +37308L,37309L,37310L,37311L,37312L,37313L,37314L,37315L,37316L,37317L, +37318L,37319L,37320L,37321L,37322L,37323L,37324L,37325L,37326L,37327L, +37328L,37329L,37330L,37331L,37332L,37333L,37334L,37335L,37336L,37337L, +37338L,37339L,37340L,37341L,37342L,37343L,37344L,37345L,37346L,37347L, +37348L,37349L,37350L,37351L,37352L,37353L,37354L,37355L,37356L,37357L, +37358L,37359L,37360L,37361L,37362L,37363L,37364L,37365L,37366L,37367L, +37368L,37369L,37370L,37371L,37372L,37373L,37374L,37375L,37376L,37377L, +37378L,37379L,37380L,37381L,37382L,37383L,37384L,37385L,37386L,37387L, +37388L,37389L,37390L,37391L,37392L,37393L,37394L,37395L,37396L,37397L, +37398L,37399L,37400L,37401L,37402L,37403L,37404L,37405L,37406L,37407L, +37408L,37409L,37410L,37411L,37412L,37413L,37414L,37415L,37416L,37417L, +37418L,37419L,37420L,37421L,37422L,37423L,37424L,37425L,37426L,37427L, +37428L,37429L,37430L,37431L,37432L,37433L,37434L,37435L,37436L,37437L, +37438L,37439L,37440L,37441L,37442L,37443L,37444L,37445L,37446L,37447L, +37448L,37449L,37450L,37451L,37452L,37453L,37454L,37455L,37456L,37457L, +37458L,37459L,37460L,37461L,37462L,37463L,37464L,37465L,37466L,37467L, +37468L,37469L,37470L,37471L,37472L,37473L,37474L,37475L,37476L,37477L, +37478L,37479L,37480L,37481L,37482L,37483L,37484L,37485L,37486L,37487L, +37488L,37489L,37490L,37491L,37492L,37493L,37494L,37495L,37496L,37497L, +37498L,37499L,37500L,37501L,37502L,37503L,37504L,37505L,37506L,37507L, +37508L,37509L,37510L,37511L,37512L,37513L,37514L,37515L,37516L,37517L, +37518L,37519L,37520L,37521L,37522L,37523L,37524L,37525L,37526L,37527L, +37528L,37529L,37530L,37531L,37532L,37533L,37534L,37535L,37536L,37537L, +37538L,37539L,37540L,37541L,37542L,37543L,37544L,37545L,37546L,37547L, +37548L,37549L,37550L,37551L,37552L,37553L,37554L,37555L,37556L,37557L, +37558L,37559L,37560L,37561L,37562L,37563L,37564L,37565L,37566L,37567L, +37568L,37569L,37570L,37571L,37572L,37573L,37574L,37575L,37576L,37577L, +37578L,37579L,37580L,37581L,37582L,37583L,37584L,37585L,37586L,37587L, +37588L,37589L,37590L,37591L,37592L,37593L,37594L,37595L,37596L,37597L, +37598L,37599L,37600L,37601L,37602L,37603L,37604L,37605L,37606L,37607L, +37608L,37609L,37610L,37611L,37612L,37613L,37614L,37615L,37616L,37617L, +37618L,37619L,37620L,37621L,37622L,37623L,37624L,37625L,37626L,37627L, +37628L,37629L,37630L,37631L,37632L,37633L,37634L,37635L,37636L,37637L, +37638L,37639L,37640L,37641L,37642L,37643L,37644L,37645L,37646L,37647L, +37648L,37649L,37650L,37651L,37652L,37653L,37654L,37655L,37656L,37657L, +37658L,37659L,37660L,37661L,37662L,37663L,37664L,37665L,37666L,37667L, +37668L,37669L,37670L,37671L,37672L,37673L,37674L,37675L,37676L,37677L, +37678L,37679L,37680L,37681L,37682L,37683L,37684L,37685L,37686L,37687L, +37688L,37689L,37690L,37691L,37692L,37693L,37694L,37695L,37696L,37697L, +37698L,37699L,37700L,37701L,37702L,37703L,37704L,37705L,37706L,37707L, +37708L,37709L,37710L,37711L,37712L,37713L,37714L,37715L,37716L,37717L, +37718L,37719L,37720L,37721L,37722L,37723L,37724L,37725L,37726L,37727L, +37728L,37729L,37730L,37731L,37732L,37733L,37734L,37735L,37736L,37737L, +37738L,37739L,37740L,37741L,37742L,37743L,37744L,37745L,37746L,37747L, +37748L,37749L,37750L,37751L,37752L,37753L,37754L,37755L,37756L,37757L, +37758L,37759L,37760L,37761L,37762L,37763L,37764L,37765L,37766L,37767L, +37768L,37769L,37770L,37771L,37772L,37773L,37774L,37775L,37776L,37777L, +37778L,37779L,37780L,37781L,37782L,37783L,37784L,37785L,37786L,37787L, +37788L,37789L,37790L,37791L,37792L,37793L,37794L,37795L,37796L,37797L, +37798L,37799L,37800L,37801L,37802L,37803L,37804L,37805L,37806L,37807L, +37808L,37809L,37810L,37811L,37812L,37813L,37814L,37815L,37816L,37817L, +37818L,37819L,37820L,37821L,37822L,37823L,37824L,37825L,37826L,37827L, +37828L,37829L,37830L,37831L,37832L,37833L,37834L,37835L,37836L,37837L, +37838L,37839L,37840L,37841L,37842L,37843L,37844L,37845L,37846L,37847L, +37848L,37849L,37850L,37851L,37852L,37853L,37854L,37855L,37856L,37857L, +37858L,37859L,37860L,37861L,37862L,37863L,37864L,37865L,37866L,37867L, +37868L,37869L,37870L,37871L,37872L,37873L,37874L,37875L,37876L,37877L, +37878L,37879L,37880L,37881L,37882L,37883L,37884L,37885L,37886L,37887L, +37888L,37889L,37890L,37891L,37892L,37893L,37894L,37895L,37896L,37897L, +37898L,37899L,37900L,37901L,37902L,37903L,37904L,37905L,37906L,37907L, +37908L,37909L,37910L,37911L,37912L,37913L,37914L,37915L,37916L,37917L, +37918L,37919L,37920L,37921L,37922L,37923L,37924L,37925L,37926L,37927L, +37928L,37929L,37930L,37931L,37932L,37933L,37934L,37935L,37936L,37937L, +37938L,37939L,37940L,37941L,37942L,37943L,37944L,37945L,37946L,37947L, +37948L,37949L,37950L,37951L,37952L,37953L,37954L,37955L,37956L,37957L, +37958L,37959L,37960L,37961L,37962L,37963L,37964L,37965L,37966L,37967L, +37968L,37969L,37970L,37971L,37972L,37973L,37974L,37975L,37976L,37977L, +37978L,37979L,37980L,37981L,37982L,37983L,37984L,37985L,37986L,37987L, +37988L,37989L,37990L,37991L,37992L,37993L,37994L,37995L,37996L,37997L, +37998L,37999L,38000L,38001L,38002L,38003L,38004L,38005L,38006L,38007L, +38008L,38009L,38010L,38011L,38012L,38013L,38014L,38015L,38016L,38017L, +38018L,38019L,38020L,38021L,38022L,38023L,38024L,38025L,38026L,38027L, +38028L,38029L,38030L,38031L,38032L,38033L,38034L,38035L,38036L,38037L, +38038L,38039L,38040L,38041L,38042L,38043L,38044L,38045L,38046L,38047L, +38048L,38049L,38050L,38051L,38052L,38053L,38054L,38055L,38056L,38057L, +38058L,38059L,38060L,38061L,38062L,38063L,38064L,38065L,38066L,38067L, +38068L,38069L,38070L,38071L,38072L,38073L,38074L,38075L,38076L,38077L, +38078L,38079L,38080L,38081L,38082L,38083L,38084L,38085L,38086L,38087L, +38088L,38089L,38090L,38091L,38092L,38093L,38094L,38095L,38096L,38097L, +38098L,38099L,38100L,38101L,38102L,38103L,38104L,38105L,38106L,38107L, +38108L,38109L,38110L,38111L,38112L,38113L,38114L,38115L,38116L,38117L, +38118L,38119L,38120L,38121L,38122L,38123L,38124L,38125L,38126L,38127L, +38128L,38129L,38130L,38131L,38132L,38133L,38134L,38135L,38136L,38137L, +38138L,38139L,38140L,38141L,38142L,38143L,38144L,38145L,38146L,38147L, +38148L,38149L,38150L,38151L,38152L,38153L,38154L,38155L,38156L,38157L, +38158L,38159L,38160L,38161L,38162L,38163L,38164L,38165L,38166L,38167L, +38168L,38169L,38170L,38171L,38172L,38173L,38174L,38175L,38176L,38177L, +38178L,38179L,38180L,38181L,38182L,38183L,38184L,38185L,38186L,38187L, +38188L,38189L,38190L,38191L,38192L,38193L,38194L,38195L,38196L,38197L, +38198L,38199L,38200L,38201L,38202L,38203L,38204L,38205L,38206L,38207L, +38208L,38209L,38210L,38211L,38212L,38213L,38214L,38215L,38216L,38217L, +38218L,38219L,38220L,38221L,38222L,38223L,38224L,38225L,38226L,38227L, +38228L,38229L,38230L,38231L,38232L,38233L,38234L,38235L,38236L,38237L, +38238L,38239L,38240L,38241L,38242L,38243L,38244L,38245L,38246L,38247L, +38248L,38249L,38250L,38251L,38252L,38253L,38254L,38255L,38256L,38257L, +38258L,38259L,38260L,38261L,38262L,38263L,38264L,38265L,38266L,38267L, +38268L,38269L,38270L,38271L,38272L,38273L,38274L,38275L,38276L,38277L, +38278L,38279L,38280L,38281L,38282L,38283L,38284L,38285L,38286L,38287L, +38288L,38289L,38290L,38291L,38292L,38293L,38294L,38295L,38296L,38297L, +38298L,38299L,38300L,38301L,38302L,38303L,38304L,38305L,38306L,38307L, +38308L,38309L,38310L,38311L,38312L,38313L,38314L,38315L,38316L,38317L, +38318L,38319L,38320L,38321L,38322L,38323L,38324L,38325L,38326L,38327L, +38328L,38329L,38330L,38331L,38332L,38333L,38334L,38335L,38336L,38337L, +38338L,38339L,38340L,38341L,38342L,38343L,38344L,38345L,38346L,38347L, +38348L,38349L,38350L,38351L,38352L,38353L,38354L,38355L,38356L,38357L, +38358L,38359L,38360L,38361L,38362L,38363L,38364L,38365L,38366L,38367L, +38368L,38369L,38370L,38371L,38372L,38373L,38374L,38375L,38376L,38377L, +38378L,38379L,38380L,38381L,38382L,38383L,38384L,38385L,38386L,38387L, +38388L,38389L,38390L,38391L,38392L,38393L,38394L,38395L,38396L,38397L, +38398L,38399L,38400L,38401L,38402L,38403L,38404L,38405L,38406L,38407L, +38408L,38409L,38410L,38411L,38412L,38413L,38414L,38415L,38416L,38417L, +38418L,38419L,38420L,38421L,38422L,38423L,38424L,38425L,38426L,38427L, +38428L,38429L,38430L,38431L,38432L,38433L,38434L,38435L,38436L,38437L, +38438L,38439L,38440L,38441L,38442L,38443L,38444L,38445L,38446L,38447L, +38448L,38449L,38450L,38451L,38452L,38453L,38454L,38455L,38456L,38457L, +38458L,38459L,38460L,38461L,38462L,38463L,38464L,38465L,38466L,38467L, +38468L,38469L,38470L,38471L,38472L,38473L,38474L,38475L,38476L,38477L, +38478L,38479L,38480L,38481L,38482L,38483L,38484L,38485L,38486L,38487L, +38488L,38489L,38490L,38491L,38492L,38493L,38494L,38495L,38496L,38497L, +38498L,38499L,38500L,38501L,38502L,38503L,38504L,38505L,38506L,38507L, +38508L,38509L,38510L,38511L,38512L,38513L,38514L,38515L,38516L,38517L, +38518L,38519L,38520L,38521L,38522L,38523L,38524L,38525L,38526L,38527L, +38528L,38529L,38530L,38531L,38532L,38533L,38534L,38535L,38536L,38537L, +38538L,38539L,38540L,38541L,38542L,38543L,38544L,38545L,38546L,38547L, +38548L,38549L,38550L,38551L,38552L,38553L,38554L,38555L,38556L,38557L, +38558L,38559L,38560L,38561L,38562L,38563L,38564L,38565L,38566L,38567L, +38568L,38569L,38570L,38571L,38572L,38573L,38574L,38575L,38576L,38577L, +38578L,38579L,38580L,38581L,38582L,38583L,38584L,38585L,38586L,38587L, +38588L,38589L,38590L,38591L,38592L,38593L,38594L,38595L,38596L,38597L, +38598L,38599L,38600L,38601L,38602L,38603L,38604L,38605L,38606L,38607L, +38608L,38609L,38610L,38611L,38612L,38613L,38614L,38615L,38616L,38617L, +38618L,38619L,38620L,38621L,38622L,38623L,38624L,38625L,38626L,38627L, +38628L,38629L,38630L,38631L,38632L,38633L,38634L,38635L,38636L,38637L, +38638L,38639L,38640L,38641L,38642L,38643L,38644L,38645L,38646L,38647L, +38648L,38649L,38650L,38651L,38652L,38653L,38654L,38655L,38656L,38657L, +38658L,38659L,38660L,38661L,38662L,38663L,38664L,38665L,38666L,38667L, +38668L,38669L,38670L,38671L,38672L,38673L,38674L,38675L,38676L,38677L, +38678L,38679L,38680L,38681L,38682L,38683L,38684L,38685L,38686L,38687L, +38688L,38689L,38690L,38691L,38692L,38693L,38694L,38695L,38696L,38697L, +38698L,38699L,38700L,38701L,38702L,38703L,38704L,38705L,38706L,38707L, +38708L,38709L,38710L,38711L,38712L,38713L,38714L,38715L,38716L,38717L, +38718L,38719L,38720L,38721L,38722L,38723L,38724L,38725L,38726L,38727L, +38728L,38729L,38730L,38731L,38732L,38733L,38734L,38735L,38736L,38737L, +38738L,38739L,38740L,38741L,38742L,38743L,38744L,38745L,38746L,38747L, +38748L,38749L,38750L,38751L,38752L,38753L,38754L,38755L,38756L,38757L, +38758L,38759L,38760L,38761L,38762L,38763L,38764L,38765L,38766L,38767L, +38768L,38769L,38770L,38771L,38772L,38773L,38774L,38775L,38776L,38777L, +38778L,38779L,38780L,38781L,38782L,38783L,38784L,38785L,38786L,38787L, +38788L,38789L,38790L,38791L,38792L,38793L,38794L,38795L,38796L,38797L, +38798L,38799L,38800L,38801L,38802L,38803L,38804L,38805L,38806L,38807L, +38808L,38809L,38810L,38811L,38812L,38813L,38814L,38815L,38816L,38817L, +38818L,38819L,38820L,38821L,38822L,38823L,38824L,38825L,38826L,38827L, +38828L,38829L,38830L,38831L,38832L,38833L,38834L,38835L,38836L,38837L, +38838L,38839L,38840L,38841L,38842L,38843L,38844L,38845L,38846L,38847L, +38848L,38849L,38850L,38851L,38852L,38853L,38854L,38855L,38856L,38857L, +38858L,38859L,38860L,38861L,38862L,38863L,38864L,38865L,38866L,38867L, +38868L,38869L,38870L,38871L,38872L,38873L,38874L,38875L,38876L,38877L, +38878L,38879L,38880L,38881L,38882L,38883L,38884L,38885L,38886L,38887L, +38888L,38889L,38890L,38891L,38892L,38893L,38894L,38895L,38896L,38897L, +38898L,38899L,38900L,38901L,38902L,38903L,38904L,38905L,38906L,38907L, +38908L,38909L,38910L,38911L,38912L,38913L,38914L,38915L,38916L,38917L, +38918L,38919L,38920L,38921L,38922L,38923L,38924L,38925L,38926L,38927L, +38928L,38929L,38930L,38931L,38932L,38933L,38934L,38935L,38936L,38937L, +38938L,38939L,38940L,38941L,38942L,38943L,38944L,38945L,38946L,38947L, +38948L,38949L,38950L,38951L,38952L,38953L,38954L,38955L,38956L,38957L, +38958L,38959L,38960L,38961L,38962L,38963L,38964L,38965L,38966L,38967L, +38968L,38969L,38970L,38971L,38972L,38973L,38974L,38975L,38976L,38977L, +38978L,38979L,38980L,38981L,38982L,38983L,38984L,38985L,38986L,38987L, +38988L,38989L,38990L,38991L,38992L,38993L,38994L,38995L,38996L,38997L, +38998L,38999L,39000L,39001L,39002L,39003L,39004L,39005L,39006L,39007L, +39008L,39009L,39010L,39011L,39012L,39013L,39014L,39015L,39016L,39017L, +39018L,39019L,39020L,39021L,39022L,39023L,39024L,39025L,39026L,39027L, +39028L,39029L,39030L,39031L,39032L,39033L,39034L,39035L,39036L,39037L, +39038L,39039L,39040L,39041L,39042L,39043L,39044L,39045L,39046L,39047L, +39048L,39049L,39050L,39051L,39052L,39053L,39054L,39055L,39056L,39057L, +39058L,39059L,39060L,39061L,39062L,39063L,39064L,39065L,39066L,39067L, +39068L,39069L,39070L,39071L,39072L,39073L,39074L,39075L,39076L,39077L, +39078L,39079L,39080L,39081L,39082L,39083L,39084L,39085L,39086L,39087L, +39088L,39089L,39090L,39091L,39092L,39093L,39094L,39095L,39096L,39097L, +39098L,39099L,39100L,39101L,39102L,39103L,39104L,39105L,39106L,39107L, +39108L,39109L,39110L,39111L,39112L,39113L,39114L,39115L,39116L,39117L, +39118L,39119L,39120L,39121L,39122L,39123L,39124L,39125L,39126L,39127L, +39128L,39129L,39130L,39131L,39132L,39133L,39134L,39135L,39136L,39137L, +39138L,39139L,39140L,39141L,39142L,39143L,39144L,39145L,39146L,39147L, +39148L,39149L,39150L,39151L,39152L,39153L,39154L,39155L,39156L,39157L, +39158L,39159L,39160L,39161L,39162L,39163L,39164L,39165L,39166L,39167L, +39168L,39169L,39170L,39171L,39172L,39173L,39174L,39175L,39176L,39177L, +39178L,39179L,39180L,39181L,39182L,39183L,39184L,39185L,39186L,39187L, +39188L,39189L,39190L,39191L,39192L,39193L,39194L,39195L,39196L,39197L, +39198L,39199L,39200L,39201L,39202L,39203L,39204L,39205L,39206L,39207L, +39208L,39209L,39210L,39211L,39212L,39213L,39214L,39215L,39216L,39217L, +39218L,39219L,39220L,39221L,39222L,39223L,39224L,39225L,39226L,39227L, +39228L,39229L,39230L,39231L,39232L,39233L,39234L,39235L,39236L,39237L, +39238L,39239L,39240L,39241L,39242L,39243L,39244L,39245L,39246L,39247L, +39248L,39249L,39250L,39251L,39252L,39253L,39254L,39255L,39256L,39257L, +39258L,39259L,39260L,39261L,39262L,39263L,39264L,39265L,39266L,39267L, +39268L,39269L,39270L,39271L,39272L,39273L,39274L,39275L,39276L,39277L, +39278L,39279L,39280L,39281L,39282L,39283L,39284L,39285L,39286L,39287L, +39288L,39289L,39290L,39291L,39292L,39293L,39294L,39295L,39296L,39297L, +39298L,39299L,39300L,39301L,39302L,39303L,39304L,39305L,39306L,39307L, +39308L,39309L,39310L,39311L,39312L,39313L,39314L,39315L,39316L,39317L, +39318L,39319L,39320L,39321L,39322L,39323L,39324L,39325L,39326L,39327L, +39328L,39329L,39330L,39331L,39332L,39333L,39334L,39335L,39336L,39337L, +39338L,39339L,39340L,39341L,39342L,39343L,39344L,39345L,39346L,39347L, +39348L,39349L,39350L,39351L,39352L,39353L,39354L,39355L,39356L,39357L, +39358L,39359L,39360L,39361L,39362L,39363L,39364L,39365L,39366L,39367L, +39368L,39369L,39370L,39371L,39372L,39373L,39374L,39375L,39376L,39377L, +39378L,39379L,39380L,39381L,39382L,39383L,39384L,39385L,39386L,39387L, +39388L,39389L,39390L,39391L,39392L,39393L,39394L,39395L,39396L,39397L, +39398L,39399L,39400L,39401L,39402L,39403L,39404L,39405L,39406L,39407L, +39408L,39409L,39410L,39411L,39412L,39413L,39414L,39415L,39416L,39417L, +39418L,39419L,39420L,39421L,39422L,39423L,39424L,39425L,39426L,39427L, +39428L,39429L,39430L,39431L,39432L,39433L,39434L,39435L,39436L,39437L, +39438L,39439L,39440L,39441L,39442L,39443L,39444L,39445L,39446L,39447L, +39448L,39449L,39450L,39451L,39452L,39453L,39454L,39455L,39456L,39457L, +39458L,39459L,39460L,39461L,39462L,39463L,39464L,39465L,39466L,39467L, +39468L,39469L,39470L,39471L,39472L,39473L,39474L,39475L,39476L,39477L, +39478L,39479L,39480L,39481L,39482L,39483L,39484L,39485L,39486L,39487L, +39488L,39489L,39490L,39491L,39492L,39493L,39494L,39495L,39496L,39497L, +39498L,39499L,39500L,39501L,39502L,39503L,39504L,39505L,39506L,39507L, +39508L,39509L,39510L,39511L,39512L,39513L,39514L,39515L,39516L,39517L, +39518L,39519L,39520L,39521L,39522L,39523L,39524L,39525L,39526L,39527L, +39528L,39529L,39530L,39531L,39532L,39533L,39534L,39535L,39536L,39537L, +39538L,39539L,39540L,39541L,39542L,39543L,39544L,39545L,39546L,39547L, +39548L,39549L,39550L,39551L,39552L,39553L,39554L,39555L,39556L,39557L, +39558L,39559L,39560L,39561L,39562L,39563L,39564L,39565L,39566L,39567L, +39568L,39569L,39570L,39571L,39572L,39573L,39574L,39575L,39576L,39577L, +39578L,39579L,39580L,39581L,39582L,39583L,39584L,39585L,39586L,39587L, +39588L,39589L,39590L,39591L,39592L,39593L,39594L,39595L,39596L,39597L, +39598L,39599L,39600L,39601L,39602L,39603L,39604L,39605L,39606L,39607L, +39608L,39609L,39610L,39611L,39612L,39613L,39614L,39615L,39616L,39617L, +39618L,39619L,39620L,39621L,39622L,39623L,39624L,39625L,39626L,39627L, +39628L,39629L,39630L,39631L,39632L,39633L,39634L,39635L,39636L,39637L, +39638L,39639L,39640L,39641L,39642L,39643L,39644L,39645L,39646L,39647L, +39648L,39649L,39650L,39651L,39652L,39653L,39654L,39655L,39656L,39657L, +39658L,39659L,39660L,39661L,39662L,39663L,39664L,39665L,39666L,39667L, +39668L,39669L,39670L,39671L,39672L,39673L,39674L,39675L,39676L,39677L, +39678L,39679L,39680L,39681L,39682L,39683L,39684L,39685L,39686L,39687L, +39688L,39689L,39690L,39691L,39692L,39693L,39694L,39695L,39696L,39697L, +39698L,39699L,39700L,39701L,39702L,39703L,39704L,39705L,39706L,39707L, +39708L,39709L,39710L,39711L,39712L,39713L,39714L,39715L,39716L,39717L, +39718L,39719L,39720L,39721L,39722L,39723L,39724L,39725L,39726L,39727L, +39728L,39729L,39730L,39731L,39732L,39733L,39734L,39735L,39736L,39737L, +39738L,39739L,39740L,39741L,39742L,39743L,39744L,39745L,39746L,39747L, +39748L,39749L,39750L,39751L,39752L,39753L,39754L,39755L,39756L,39757L, +39758L,39759L,39760L,39761L,39762L,39763L,39764L,39765L,39766L,39767L, +39768L,39769L,39770L,39771L,39772L,39773L,39774L,39775L,39776L,39777L, +39778L,39779L,39780L,39781L,39782L,39783L,39784L,39785L,39786L,39787L, +39788L,39789L,39790L,39791L,39792L,39793L,39794L,39795L,39796L,39797L, +39798L,39799L,39800L,39801L,39802L,39803L,39804L,39805L,39806L,39807L, +39808L,39809L,39810L,39811L,39812L,39813L,39814L,39815L,39816L,39817L, +39818L,39819L,39820L,39821L,39822L,39823L,39824L,39825L,39826L,39827L, +39828L,39829L,39830L,39831L,39832L,39833L,39834L,39835L,39836L,39837L, +39838L,39839L,39840L,39841L,39842L,39843L,39844L,39845L,39846L,39847L, +39848L,39849L,39850L,39851L,39852L,39853L,39854L,39855L,39856L,39857L, +39858L,39859L,39860L,39861L,39862L,39863L,39864L,39865L,39866L,39867L, +39868L,39869L,39870L,39871L,39872L,39873L,39874L,39875L,39876L,39877L, +39878L,39879L,39880L,39881L,39882L,39883L,39884L,39885L,39886L,39887L, +39888L,39889L,39890L,39891L,39892L,39893L,39894L,39895L,39896L,39897L, +39898L,39899L,39900L,39901L,39902L,39903L,39904L,39905L,39906L,39907L, +39908L,39909L,39910L,39911L,39912L,39913L,39914L,39915L,39916L,39917L, +39918L,39919L,39920L,39921L,39922L,39923L,39924L,39925L,39926L,39927L, +39928L,39929L,39930L,39931L,39932L,39933L,39934L,39935L,39936L,39937L, +39938L,39939L,39940L,39941L,39942L,39943L,39944L,39945L,39946L,39947L, +39948L,39949L,39950L,39951L,39952L,39953L,39954L,39955L,39956L,39957L, +39958L,39959L,39960L,39961L,39962L,39963L,39964L,39965L,39966L,39967L, +39968L,39969L,39970L,39971L,39972L,39973L,39974L,39975L,39976L,39977L, +39978L,39979L,39980L,39981L,39982L,39983L,39984L,39985L,39986L,39987L, +39988L,39989L,39990L,39991L,39992L,39993L,39994L,39995L,39996L,39997L, +39998L,39999L,40000L,40001L,40002L,40003L,40004L,40005L,40006L,40007L, +40008L,40009L,40010L,40011L,40012L,40013L,40014L,40015L,40016L,40017L, +40018L,40019L,40020L,40021L,40022L,40023L,40024L,40025L,40026L,40027L, +40028L,40029L,40030L,40031L,40032L,40033L,40034L,40035L,40036L,40037L, +40038L,40039L,40040L,40041L,40042L,40043L,40044L,40045L,40046L,40047L, +40048L,40049L,40050L,40051L,40052L,40053L,40054L,40055L,40056L,40057L, +40058L,40059L,40060L,40061L,40062L,40063L,40064L,40065L,40066L,40067L, +40068L,40069L,40070L,40071L,40072L,40073L,40074L,40075L,40076L,40077L, +40078L,40079L,40080L,40081L,40082L,40083L,40084L,40085L,40086L,40087L, +40088L,40089L,40090L,40091L,40092L,40093L,40094L,40095L,40096L,40097L, +40098L,40099L,40100L,40101L,40102L,40103L,40104L,40105L,40106L,40107L, +40108L,40109L,40110L,40111L,40112L,40113L,40114L,40115L,40116L,40117L, +40118L,40119L,40120L,40121L,40122L,40123L,40124L,40125L,40126L,40127L, +40128L,40129L,40130L,40131L,40132L,40133L,40134L,40135L,40136L,40137L, +40138L,40139L,40140L,40141L,40142L,40143L,40144L,40145L,40146L,40147L, +40148L,40149L,40150L,40151L,40152L,40153L,40154L,40155L,40156L,40157L, +40158L,40159L,40160L,40161L,40162L,40163L,40164L,40165L,40166L,40167L, +40168L,40169L,40170L,40171L,40172L,40173L,40174L,40175L,40176L,40177L, +40178L,40179L,40180L,40181L,40182L,40183L,40184L,40185L,40186L,40187L, +40188L,40189L,40190L,40191L,40192L,40193L,40194L,40195L,40196L,40197L, +40198L,40199L,40200L,40201L,40202L,40203L,40204L,40205L,40206L,40207L, +40208L,40209L,40210L,40211L,40212L,40213L,40214L,40215L,40216L,40217L, +40218L,40219L,40220L,40221L,40222L,40223L,40224L,40225L,40226L,40227L, +40228L,40229L,40230L,40231L,40232L,40233L,40234L,40235L,40236L,40237L, +40238L,40239L,40240L,40241L,40242L,40243L,40244L,40245L,40246L,40247L, +40248L,40249L,40250L,40251L,40252L,40253L,40254L,40255L,40256L,40257L, +40258L,40259L,40260L,40261L,40262L,40263L,40264L,40265L,40266L,40267L, +40268L,40269L,40270L,40271L,40272L,40273L,40274L,40275L,40276L,40277L, +40278L,40279L,40280L,40281L,40282L,40283L,40284L,40285L,40286L,40287L, +40288L,40289L,40290L,40291L,40292L,40293L,40294L,40295L,40296L,40297L, +40298L,40299L,40300L,40301L,40302L,40303L,40304L,40305L,40306L,40307L, +40308L,40309L,40310L,40311L,40312L,40313L,40314L,40315L,40316L,40317L, +40318L,40319L,40320L,40321L,40322L,40323L,40324L,40325L,40326L,40327L, +40328L,40329L,40330L,40331L,40332L,40333L,40334L,40335L,40336L,40337L, +40338L,40339L,40340L,40341L,40342L,40343L,40344L,40345L,40346L,40347L, +40348L,40349L,40350L,40351L,40352L,40353L,40354L,40355L,40356L,40357L, +40358L,40359L,40360L,40361L,40362L,40363L,40364L,40365L,40366L,40367L, +40368L,40369L,40370L,40371L,40372L,40373L,40374L,40375L,40376L,40377L, +40378L,40379L,40380L,40381L,40382L,40383L,40384L,40385L,40386L,40387L, +40388L,40389L,40390L,40391L,40392L,40393L,40394L,40395L,40396L,40397L, +40398L,40399L,40400L,40401L,40402L,40403L,40404L,40405L,40406L,40407L, +40408L,40409L,40410L,40411L,40412L,40413L,40414L,40415L,40416L,40417L, +40418L,40419L,40420L,40421L,40422L,40423L,40424L,40425L,40426L,40427L, +40428L,40429L,40430L,40431L,40432L,40433L,40434L,40435L,40436L,40437L, +40438L,40439L,40440L,40441L,40442L,40443L,40444L,40445L,40446L,40447L, +40448L,40449L,40450L,40451L,40452L,40453L,40454L,40455L,40456L,40457L, +40458L,40459L,40460L,40461L,40462L,40463L,40464L,40465L,40466L,40467L, +40468L,40469L,40470L,40471L,40472L,40473L,40474L,40475L,40476L,40477L, +40478L,40479L,40480L,40481L,40482L,40483L,40484L,40485L,40486L,40487L, +40488L,40489L,40490L,40491L,40492L,40493L,40494L,40495L,40496L,40497L, +40498L,40499L,40500L,40501L,40502L,40503L,40504L,40505L,40506L,40507L, +40508L,40509L,40510L,40511L,40512L,40513L,40514L,40515L,40516L,40517L, +40518L,40519L,40520L,40521L,40522L,40523L,40524L,40525L,40526L,40527L, +40528L,40529L,40530L,40531L,40532L,40533L,40534L,40535L,40536L,40537L, +40538L,40539L,40540L,40541L,40542L,40543L,40544L,40545L,40546L,40547L, +40548L,40549L,40550L,40551L,40552L,40553L,40554L,40555L,40556L,40557L, +40558L,40559L,40560L,40561L,40562L,40563L,40564L,40565L,40566L,40567L, +40568L,40569L,40570L,40571L,40572L,40573L,40574L,40575L,40576L,40577L, +40578L,40579L,40580L,40581L,40582L,40583L,40584L,40585L,40586L,40587L, +40588L,40589L,40590L,40591L,40592L,40593L,40594L,40595L,40596L,40597L, +40598L,40599L,40600L,40601L,40602L,40603L,40604L,40605L,40606L,40607L, +40608L,40609L,40610L,40611L,40612L,40613L,40614L,40615L,40616L,40617L, +40618L,40619L,40620L,40621L,40622L,40623L,40624L,40625L,40626L,40627L, +40628L,40629L,40630L,40631L,40632L,40633L,40634L,40635L,40636L,40637L, +40638L,40639L,40640L,40641L,40642L,40643L,40644L,40645L,40646L,40647L, +40648L,40649L,40650L,40651L,40652L,40653L,40654L,40655L,40656L,40657L, +40658L,40659L,40660L,40661L,40662L,40663L,40664L,40665L,40666L,40667L, +40668L,40669L,40670L,40671L,40672L,40673L,40674L,40675L,40676L,40677L, +40678L,40679L,40680L,40681L,40682L,40683L,40684L,40685L,40686L,40687L, +40688L,40689L,40690L,40691L,40692L,40693L,40694L,40695L,40696L,40697L, +40698L,40699L,40700L,40701L,40702L,40703L,40704L,40705L,40706L,40707L, +40708L,40709L,40710L,40711L,40712L,40713L,40714L,40715L,40716L,40717L, +40718L,40719L,40720L,40721L,40722L,40723L,40724L,40725L,40726L,40727L, +40728L,40729L,40730L,40731L,40732L,40733L,40734L,40735L,40736L,40737L, +40738L,40739L,40740L,40741L,40742L,40743L,40744L,40745L,40746L,40747L, +40748L,40749L,40750L,40751L,40752L,40753L,40754L,40755L,40756L,40757L, +40758L,40759L,40760L,40761L,40762L,40763L,40764L,40765L,40766L,40767L, +40768L,40769L,40770L,40771L,40772L,40773L,40774L,40775L,40776L,40777L, +40778L,40779L,40780L,40781L,40782L,40783L,40784L,40785L,40786L,40787L, +40788L,40789L,40790L,40791L,40792L,40793L,40794L,40795L,40796L,40797L, +40798L,40799L,40800L,40801L,40802L,40803L,40804L,40805L,40806L,40807L, +40808L,40809L,40810L,40811L,40812L,40813L,40814L,40815L,40816L,40817L, +40818L,40819L,40820L,40821L,40822L,40823L,40824L,40825L,40826L,40827L, +40828L,40829L,40830L,40831L,40832L,40833L,40834L,40835L,40836L,40837L, +40838L,40839L,40840L,40841L,40842L,40843L,40844L,40845L,40846L,40847L, +40848L,40849L,40850L,40851L,40852L,40853L,40854L,40855L,40856L,40857L, +40858L,40859L,40860L,40861L,40862L,40863L,40864L,40865L,40866L,40867L, +40868L,40869L,40870L,40871L,40872L,40873L,40874L,40875L,40876L,40877L, +40878L,40879L,40880L,40881L,40882L,40883L,40884L,40885L,40886L,40887L, +40888L,40889L,40890L,40891L,40892L,40893L,40894L,40895L,40896L,40897L, +40898L,40899L,40900L,40901L,40902L,40903L,40904L,40905L,40906L,40907L, +40908L,40909L,40910L,40911L,40912L,40913L,40914L,40915L,40916L,40917L, +40918L,40919L,40920L,40921L,40922L,40923L,40924L,40925L,40926L,40927L, +40928L,40929L,40930L,40931L,40932L,40933L,40934L,40935L,40936L,40937L, +40938L,40939L,40940L,40941L,40942L,40943L,40944L,40945L,40946L,40947L, +40948L,40949L,40950L,40951L,40952L,40953L,40954L,40955L,40956L,40957L, +40958L,40959L,40960L,40961L,40962L,40963L,40964L,40965L,40966L,40967L, +40968L,40969L,40970L,40971L,40972L,40973L,40974L,40975L,40976L,40977L, +40978L,40979L,40980L,40981L,40982L,40983L,40984L,40985L,40986L,40987L, +40988L,40989L,40990L,40991L,40992L,40993L,40994L,40995L,40996L,40997L, +40998L,40999L,41000L,41001L,41002L,41003L,41004L,41005L,41006L,41007L, +41008L,41009L,41010L,41011L,41012L,41013L,41014L,41015L,41016L,41017L, +41018L,41019L,41020L,41021L,41022L,41023L,41024L,41025L,41026L,41027L, +41028L,41029L,41030L,41031L,41032L,41033L,41034L,41035L,41036L,41037L, +41038L,41039L,41040L,41041L,41042L,41043L,41044L,41045L,41046L,41047L, +41048L,41049L,41050L,41051L,41052L,41053L,41054L,41055L,41056L,41057L, +41058L,41059L,41060L,41061L,41062L,41063L,41064L,41065L,41066L,41067L, +41068L,41069L,41070L,41071L,41072L,41073L,41074L,41075L,41076L,41077L, +41078L,41079L,41080L,41081L,41082L,41083L,41084L,41085L,41086L,41087L, +41088L,41089L,41090L,41091L,41092L,41093L,41094L,41095L,41096L,41097L, +41098L,41099L,41100L,41101L,41102L,41103L,41104L,41105L,41106L,41107L, +41108L,41109L,41110L,41111L,41112L,41113L,41114L,41115L,41116L,41117L, +41118L,41119L,41120L,41121L,41122L,41123L,41124L,41125L,41126L,41127L, +41128L,41129L,41130L,41131L,41132L,41133L,41134L,41135L,41136L,41137L, +41138L,41139L,41140L,41141L,41142L,41143L,41144L,41145L,41146L,41147L, +41148L,41149L,41150L,41151L,41152L,41153L,41154L,41155L,41156L,41157L, +41158L,41159L,41160L,41161L,41162L,41163L,41164L,41165L,41166L,41167L, +41168L,41169L,41170L,41171L,41172L,41173L,41174L,41175L,41176L,41177L, +41178L,41179L,41180L,41181L,41182L,41183L,41184L,41185L,41186L,41187L, +41188L,41189L,41190L,41191L,41192L,41193L,41194L,41195L,41196L,41197L, +41198L,41199L,41200L,41201L,41202L,41203L,41204L,41205L,41206L,41207L, +41208L,41209L,41210L,41211L,41212L,41213L,41214L,41215L,41216L,41217L, +41218L,41219L,41220L,41221L,41222L,41223L,41224L,41225L,41226L,41227L, +41228L,41229L,41230L,41231L,41232L,41233L,41234L,41235L,41236L,41237L, +41238L,41239L,41240L,41241L,41242L,41243L,41244L,41245L,41246L,41247L, +41248L,41249L,41250L,41251L,41252L,41253L,41254L,41255L,41256L,41257L, +41258L,41259L,41260L,41261L,41262L,41263L,41264L,41265L,41266L,41267L, +41268L,41269L,41270L,41271L,41272L,41273L,41274L,41275L,41276L,41277L, +41278L,41279L,41280L,41281L,41282L,41283L,41284L,41285L,41286L,41287L, +41288L,41289L,41290L,41291L,41292L,41293L,41294L,41295L,41296L,41297L, +41298L,41299L,41300L,41301L,41302L,41303L,41304L,41305L,41306L,41307L, +41308L,41309L,41310L,41311L,41312L,41313L,41314L,41315L,41316L,41317L, +41318L,41319L,41320L,41321L,41322L,41323L,41324L,41325L,41326L,41327L, +41328L,41329L,41330L,41331L,41332L,41333L,41334L,41335L,41336L,41337L, +41338L,41339L,41340L,41341L,41342L,41343L,41344L,41345L,41346L,41347L, +41348L,41349L,41350L,41351L,41352L,41353L,41354L,41355L,41356L,41357L, +41358L,41359L,41360L,41361L,41362L,41363L,41364L,41365L,41366L,41367L, +41368L,41369L,41370L,41371L,41372L,41373L,41374L,41375L,41376L,41377L, +41378L,41379L,41380L,41381L,41382L,41383L,41384L,41385L,41386L,41387L, +41388L,41389L,41390L,41391L,41392L,41393L,41394L,41395L,41396L,41397L, +41398L,41399L,41400L,41401L,41402L,41403L,41404L,41405L,41406L,41407L, +41408L,41409L,41410L,41411L,41412L,41413L,41414L,41415L,41416L,41417L, +41418L,41419L,41420L,41421L,41422L,41423L,41424L,41425L,41426L,41427L, +41428L,41429L,41430L,41431L,41432L,41433L,41434L,41435L,41436L,41437L, +41438L,41439L,41440L,41441L,41442L,41443L,41444L,41445L,41446L,41447L, +41448L,41449L,41450L,41451L,41452L,41453L,41454L,41455L,41456L,41457L, +41458L,41459L,41460L,41461L,41462L,41463L,41464L,41465L,41466L,41467L, +41468L,41469L,41470L,41471L,41472L,41473L,41474L,41475L,41476L,41477L, +41478L,41479L,41480L,41481L,41482L,41483L,41484L,41485L,41486L,41487L, +41488L,41489L,41490L,41491L,41492L,41493L,41494L,41495L,41496L,41497L, +41498L,41499L,41500L,41501L,41502L,41503L,41504L,41505L,41506L,41507L, +41508L,41509L,41510L,41511L,41512L,41513L,41514L,41515L,41516L,41517L, +41518L,41519L,41520L,41521L,41522L,41523L,41524L,41525L,41526L,41527L, +41528L,41529L,41530L,41531L,41532L,41533L,41534L,41535L,41536L,41537L, +41538L,41539L,41540L,41541L,41542L,41543L,41544L,41545L,41546L,41547L, +41548L,41549L,41550L,41551L,41552L,41553L,41554L,41555L,41556L,41557L, +41558L,41559L,41560L,41561L,41562L,41563L,41564L,41565L,41566L,41567L, +41568L,41569L,41570L,41571L,41572L,41573L,41574L,41575L,41576L,41577L, +41578L,41579L,41580L,41581L,41582L,41583L,41584L,41585L,41586L,41587L, +41588L,41589L,41590L,41591L,41592L,41593L,41594L,41595L,41596L,41597L, +41598L,41599L,41600L,41601L,41602L,41603L,41604L,41605L,41606L,41607L, +41608L,41609L,41610L,41611L,41612L,41613L,41614L,41615L,41616L,41617L, +41618L,41619L,41620L,41621L,41622L,41623L,41624L,41625L,41626L,41627L, +41628L,41629L,41630L,41631L,41632L,41633L,41634L,41635L,41636L,41637L, +41638L,41639L,41640L,41641L,41642L,41643L,41644L,41645L,41646L,41647L, +41648L,41649L,41650L,41651L,41652L,41653L,41654L,41655L,41656L,41657L, +41658L,41659L,41660L,41661L,41662L,41663L,41664L,41665L,41666L,41667L, +41668L,41669L,41670L,41671L,41672L,41673L,41674L,41675L,41676L,41677L, +41678L,41679L,41680L,41681L,41682L,41683L,41684L,41685L,41686L,41687L, +41688L,41689L,41690L,41691L,41692L,41693L,41694L,41695L,41696L,41697L, +41698L,41699L,41700L,41701L,41702L,41703L,41704L,41705L,41706L,41707L, +41708L,41709L,41710L,41711L,41712L,41713L,41714L,41715L,41716L,41717L, +41718L,41719L,41720L,41721L,41722L,41723L,41724L,41725L,41726L,41727L, +41728L,41729L,41730L,41731L,41732L,41733L,41734L,41735L,41736L,41737L, +41738L,41739L,41740L,41741L,41742L,41743L,41744L,41745L,41746L,41747L, +41748L,41749L,41750L,41751L,41752L,41753L,41754L,41755L,41756L,41757L, +41758L,41759L,41760L,41761L,41762L,41763L,41764L,41765L,41766L,41767L, +41768L,41769L,41770L,41771L,41772L,41773L,41774L,41775L,41776L,41777L, +41778L,41779L,41780L,41781L,41782L,41783L,41784L,41785L,41786L,41787L, +41788L,41789L,41790L,41791L,41792L,41793L,41794L,41795L,41796L,41797L, +41798L,41799L,41800L,41801L,41802L,41803L,41804L,41805L,41806L,41807L, +41808L,41809L,41810L,41811L,41812L,41813L,41814L,41815L,41816L,41817L, +41818L,41819L,41820L,41821L,41822L,41823L,41824L,41825L,41826L,41827L, +41828L,41829L,41830L,41831L,41832L,41833L,41834L,41835L,41836L,41837L, +41838L,41839L,41840L,41841L,41842L,41843L,41844L,41845L,41846L,41847L, +41848L,41849L,41850L,41851L,41852L,41853L,41854L,41855L,41856L,41857L, +41858L,41859L,41860L,41861L,41862L,41863L,41864L,41865L,41866L,41867L, +41868L,41869L,41870L,41871L,41872L,41873L,41874L,41875L,41876L,41877L, +41878L,41879L,41880L,41881L,41882L,41883L,41884L,41885L,41886L,41887L, +41888L,41889L,41890L,41891L,41892L,41893L,41894L,41895L,41896L,41897L, +41898L,41899L,41900L,41901L,41902L,41903L,41904L,41905L,41906L,41907L, +41908L,41909L,41910L,41911L,41912L,41913L,41914L,41915L,41916L,41917L, +41918L,41919L,41920L,41921L,41922L,41923L,41924L,41925L,41926L,41927L, +41928L,41929L,41930L,41931L,41932L,41933L,41934L,41935L,41936L,41937L, +41938L,41939L,41940L,41941L,41942L,41943L,41944L,41945L,41946L,41947L, +41948L,41949L,41950L,41951L,41952L,41953L,41954L,41955L,41956L,41957L, +41958L,41959L,41960L,41961L,41962L,41963L,41964L,41965L,41966L,41967L, +41968L,41969L,41970L,41971L,41972L,41973L,41974L,41975L,41976L,41977L, +41978L,41979L,41980L,41981L,41982L,41983L,41984L,41985L,41986L,41987L, +41988L,41989L,41990L,41991L,41992L,41993L,41994L,41995L,41996L,41997L, +41998L,41999L,42000L,42001L,42002L,42003L,42004L,42005L,42006L,42007L, +42008L,42009L,42010L,42011L,42012L,42013L,42014L,42015L,42016L,42017L, +42018L,42019L,42020L,42021L,42022L,42023L,42024L,42025L,42026L,42027L, +42028L,42029L,42030L,42031L,42032L,42033L,42034L,42035L,42036L,42037L, +42038L,42039L,42040L,42041L,42042L,42043L,42044L,42045L,42046L,42047L, +42048L,42049L,42050L,42051L,42052L,42053L,42054L,42055L,42056L,42057L, +42058L,42059L,42060L,42061L,42062L,42063L,42064L,42065L,42066L,42067L, +42068L,42069L,42070L,42071L,42072L,42073L,42074L,42075L,42076L,42077L, +42078L,42079L,42080L,42081L,42082L,42083L,42084L,42085L,42086L,42087L, +42088L,42089L,42090L,42091L,42092L,42093L,42094L,42095L,42096L,42097L, +42098L,42099L,42100L,42101L,42102L,42103L,42104L,42105L,42106L,42107L, +42108L,42109L,42110L,42111L,42112L,42113L,42114L,42115L,42116L,42117L, +42118L,42119L,42120L,42121L,42122L,42123L,42124L,42125L,42126L,42127L, +42128L,42129L,42130L,42131L,42132L,42133L,42134L,42135L,42136L,42137L, +42138L,42139L,42140L,42141L,42142L,42143L,42144L,42145L,42146L,42147L, +42148L,42149L,42150L,42151L,42152L,42153L,42154L,42155L,42156L,42157L, +42158L,42159L,42160L,42161L,42162L,42163L,42164L,42165L,42166L,42167L, +42168L,42169L,42170L,42171L,42172L,42173L,42174L,42175L,42176L,42177L, +42178L,42179L,42180L,42181L,42182L,42183L,42184L,42185L,42186L,42187L, +42188L,42189L,42190L,42191L,42192L,42193L,42194L,42195L,42196L,42197L, +42198L,42199L,42200L,42201L,42202L,42203L,42204L,42205L,42206L,42207L, +42208L,42209L,42210L,42211L,42212L,42213L,42214L,42215L,42216L,42217L, +42218L,42219L,42220L,42221L,42222L,42223L,42224L,42225L,42226L,42227L, +42228L,42229L,42230L,42231L,42232L,42233L,42234L,42235L,42236L,42237L, +42238L,42239L,42240L,42241L,42242L,42243L,42244L,42245L,42246L,42247L, +42248L,42249L,42250L,42251L,42252L,42253L,42254L,42255L,42256L,42257L, +42258L,42259L,42260L,42261L,42262L,42263L,42264L,42265L,42266L,42267L, +42268L,42269L,42270L,42271L,42272L,42273L,42274L,42275L,42276L,42277L, +42278L,42279L,42280L,42281L,42282L,42283L,42284L,42285L,42286L,42287L, +42288L,42289L,42290L,42291L,42292L,42293L,42294L,42295L,42296L,42297L, +42298L,42299L,42300L,42301L,42302L,42303L,42304L,42305L,42306L,42307L, +42308L,42309L,42310L,42311L,42312L,42313L,42314L,42315L,42316L,42317L, +42318L,42319L,42320L,42321L,42322L,42323L,42324L,42325L,42326L,42327L, +42328L,42329L,42330L,42331L,42332L,42333L,42334L,42335L,42336L,42337L, +42338L,42339L,42340L,42341L,42342L,42343L,42344L,42345L,42346L,42347L, +42348L,42349L,42350L,42351L,42352L,42353L,42354L,42355L,42356L,42357L, +42358L,42359L,42360L,42361L,42362L,42363L,42364L,42365L,42366L,42367L, +42368L,42369L,42370L,42371L,42372L,42373L,42374L,42375L,42376L,42377L, +42378L,42379L,42380L,42381L,42382L,42383L,42384L,42385L,42386L,42387L, +42388L,42389L,42390L,42391L,42392L,42393L,42394L,42395L,42396L,42397L, +42398L,42399L,42400L,42401L,42402L,42403L,42404L,42405L,42406L,42407L, +42408L,42409L,42410L,42411L,42412L,42413L,42414L,42415L,42416L,42417L, +42418L,42419L,42420L,42421L,42422L,42423L,42424L,42425L,42426L,42427L, +42428L,42429L,42430L,42431L,42432L,42433L,42434L,42435L,42436L,42437L, +42438L,42439L,42440L,42441L,42442L,42443L,42444L,42445L,42446L,42447L, +42448L,42449L,42450L,42451L,42452L,42453L,42454L,42455L,42456L,42457L, +42458L,42459L,42460L,42461L,42462L,42463L,42464L,42465L,42466L,42467L, +42468L,42469L,42470L,42471L,42472L,42473L,42474L,42475L,42476L,42477L, +42478L,42479L,42480L,42481L,42482L,42483L,42484L,42485L,42486L,42487L, +42488L,42489L,42490L,42491L,42492L,42493L,42494L,42495L,42496L,42497L, +42498L,42499L,42500L,42501L,42502L,42503L,42504L,42505L,42506L,42507L, +42508L,42509L,42510L,42511L,42512L,42513L,42514L,42515L,42516L,42517L, +42518L,42519L,42520L,42521L,42522L,42523L,42524L,42525L,42526L,42527L, +42528L,42529L,42530L,42531L,42532L,42533L,42534L,42535L,42536L,42537L, +42538L,42539L,42540L,42541L,42542L,42543L,42544L,42545L,42546L,42547L, +42548L,42549L,42550L,42551L,42552L,42553L,42554L,42555L,42556L,42557L, +42558L,42559L,42560L,42560L,42562L,42562L,42564L,42564L,42566L,42566L, +42568L,42568L,42570L,42570L,42572L,42572L,42574L,42574L,42576L,42576L, +42578L,42578L,42580L,42580L,42582L,42582L,42584L,42584L,42586L,42586L, +42588L,42588L,42590L,42590L,42592L,42592L,42594L,42594L,42596L,42596L, +42598L,42598L,42600L,42600L,42602L,42602L,42604L,42604L,42606L,42607L, +42608L,42609L,42610L,42611L,42612L,42613L,42614L,42615L,42616L,42617L, +42618L,42619L,42620L,42621L,42622L,42623L,42624L,42624L,42626L,42626L, +42628L,42628L,42630L,42630L,42632L,42632L,42634L,42634L,42636L,42636L, +42638L,42638L,42640L,42640L,42642L,42642L,42644L,42644L,42646L,42646L, +42648L,42648L,42650L,42650L,42652L,42653L,42654L,42655L,42656L,42657L, +42658L,42659L,42660L,42661L,42662L,42663L,42664L,42665L,42666L,42667L, +42668L,42669L,42670L,42671L,42672L,42673L,42674L,42675L,42676L,42677L, +42678L,42679L,42680L,42681L,42682L,42683L,42684L,42685L,42686L,42687L, +42688L,42689L,42690L,42691L,42692L,42693L,42694L,42695L,42696L,42697L, +42698L,42699L,42700L,42701L,42702L,42703L,42704L,42705L,42706L,42707L, +42708L,42709L,42710L,42711L,42712L,42713L,42714L,42715L,42716L,42717L, +42718L,42719L,42720L,42721L,42722L,42723L,42724L,42725L,42726L,42727L, +42728L,42729L,42730L,42731L,42732L,42733L,42734L,42735L,42736L,42737L, +42738L,42739L,42740L,42741L,42742L,42743L,42744L,42745L,42746L,42747L, +42748L,42749L,42750L,42751L,42752L,42753L,42754L,42755L,42756L,42757L, +42758L,42759L,42760L,42761L,42762L,42763L,42764L,42765L,42766L,42767L, +42768L,42769L,42770L,42771L,42772L,42773L,42774L,42775L,42776L,42777L, +42778L,42779L,42780L,42781L,42782L,42783L,42784L,42785L,42786L,42786L, +42788L,42788L,42790L,42790L,42792L,42792L,42794L,42794L,42796L,42796L, +42798L,42798L,42800L,42801L,42802L,42802L,42804L,42804L,42806L,42806L, +42808L,42808L,42810L,42810L,42812L,42812L,42814L,42814L,42816L,42816L, +42818L,42818L,42820L,42820L,42822L,42822L,42824L,42824L,42826L,42826L, +42828L,42828L,42830L,42830L,42832L,42832L,42834L,42834L,42836L,42836L, +42838L,42838L,42840L,42840L,42842L,42842L,42844L,42844L,42846L,42846L, +42848L,42848L,42850L,42850L,42852L,42852L,42854L,42854L,42856L,42856L, +42858L,42858L,42860L,42860L,42862L,42862L,42864L,42865L,42866L,42867L, +42868L,42869L,42870L,42871L,42872L,42873L,42873L,42875L,42875L,42877L, +42878L,42878L,42880L,42880L,42882L,42882L,42884L,42884L,42886L,42886L, +42888L,42889L,42890L,42891L,42891L,42893L,42894L,42895L,42896L,42896L, +42898L,42898L,42948L,42901L,42902L,42902L,42904L,42904L,42906L,42906L, +42908L,42908L,42910L,42910L,42912L,42912L,42914L,42914L,42916L,42916L, +42918L,42918L,42920L,42920L,42922L,42923L,42924L,42925L,42926L,42927L, +42928L,42929L,42930L,42931L,42932L,42932L,42934L,42934L,42936L,42936L, +42938L,42938L,42940L,42940L,42942L,42942L,42944L,42945L,42946L,42946L, +42948L,42949L,42950L,42951L,42952L,42953L,42954L,42955L,42956L,42957L, +42958L,42959L,42960L,42961L,42962L,42963L,42964L,42965L,42966L,42967L, +42968L,42969L,42970L,42971L,42972L,42973L,42974L,42975L,42976L,42977L, +42978L,42979L,42980L,42981L,42982L,42983L,42984L,42985L,42986L,42987L, +42988L,42989L,42990L,42991L,42992L,42993L,42994L,42995L,42996L,42997L, +42998L,42999L,43000L,43001L,43002L,43003L,43004L,43005L,43006L,43007L, +43008L,43009L,43010L,43011L,43012L,43013L,43014L,43015L,43016L,43017L, +43018L,43019L,43020L,43021L,43022L,43023L,43024L,43025L,43026L,43027L, +43028L,43029L,43030L,43031L,43032L,43033L,43034L,43035L,43036L,43037L, +43038L,43039L,43040L,43041L,43042L,43043L,43044L,43045L,43046L,43047L, +43048L,43049L,43050L,43051L,43052L,43053L,43054L,43055L,43056L,43057L, +43058L,43059L,43060L,43061L,43062L,43063L,43064L,43065L,43066L,43067L, +43068L,43069L,43070L,43071L,43072L,43073L,43074L,43075L,43076L,43077L, +43078L,43079L,43080L,43081L,43082L,43083L,43084L,43085L,43086L,43087L, +43088L,43089L,43090L,43091L,43092L,43093L,43094L,43095L,43096L,43097L, +43098L,43099L,43100L,43101L,43102L,43103L,43104L,43105L,43106L,43107L, +43108L,43109L,43110L,43111L,43112L,43113L,43114L,43115L,43116L,43117L, +43118L,43119L,43120L,43121L,43122L,43123L,43124L,43125L,43126L,43127L, +43128L,43129L,43130L,43131L,43132L,43133L,43134L,43135L,43136L,43137L, +43138L,43139L,43140L,43141L,43142L,43143L,43144L,43145L,43146L,43147L, +43148L,43149L,43150L,43151L,43152L,43153L,43154L,43155L,43156L,43157L, +43158L,43159L,43160L,43161L,43162L,43163L,43164L,43165L,43166L,43167L, +43168L,43169L,43170L,43171L,43172L,43173L,43174L,43175L,43176L,43177L, +43178L,43179L,43180L,43181L,43182L,43183L,43184L,43185L,43186L,43187L, +43188L,43189L,43190L,43191L,43192L,43193L,43194L,43195L,43196L,43197L, +43198L,43199L,43200L,43201L,43202L,43203L,43204L,43205L,43206L,43207L, +43208L,43209L,43210L,43211L,43212L,43213L,43214L,43215L,43216L,43217L, +43218L,43219L,43220L,43221L,43222L,43223L,43224L,43225L,43226L,43227L, +43228L,43229L,43230L,43231L,43232L,43233L,43234L,43235L,43236L,43237L, +43238L,43239L,43240L,43241L,43242L,43243L,43244L,43245L,43246L,43247L, +43248L,43249L,43250L,43251L,43252L,43253L,43254L,43255L,43256L,43257L, +43258L,43259L,43260L,43261L,43262L,43263L,43264L,43265L,43266L,43267L, +43268L,43269L,43270L,43271L,43272L,43273L,43274L,43275L,43276L,43277L, +43278L,43279L,43280L,43281L,43282L,43283L,43284L,43285L,43286L,43287L, +43288L,43289L,43290L,43291L,43292L,43293L,43294L,43295L,43296L,43297L, +43298L,43299L,43300L,43301L,43302L,43303L,43304L,43305L,43306L,43307L, +43308L,43309L,43310L,43311L,43312L,43313L,43314L,43315L,43316L,43317L, +43318L,43319L,43320L,43321L,43322L,43323L,43324L,43325L,43326L,43327L, +43328L,43329L,43330L,43331L,43332L,43333L,43334L,43335L,43336L,43337L, +43338L,43339L,43340L,43341L,43342L,43343L,43344L,43345L,43346L,43347L, +43348L,43349L,43350L,43351L,43352L,43353L,43354L,43355L,43356L,43357L, +43358L,43359L,43360L,43361L,43362L,43363L,43364L,43365L,43366L,43367L, +43368L,43369L,43370L,43371L,43372L,43373L,43374L,43375L,43376L,43377L, +43378L,43379L,43380L,43381L,43382L,43383L,43384L,43385L,43386L,43387L, +43388L,43389L,43390L,43391L,43392L,43393L,43394L,43395L,43396L,43397L, +43398L,43399L,43400L,43401L,43402L,43403L,43404L,43405L,43406L,43407L, +43408L,43409L,43410L,43411L,43412L,43413L,43414L,43415L,43416L,43417L, +43418L,43419L,43420L,43421L,43422L,43423L,43424L,43425L,43426L,43427L, +43428L,43429L,43430L,43431L,43432L,43433L,43434L,43435L,43436L,43437L, +43438L,43439L,43440L,43441L,43442L,43443L,43444L,43445L,43446L,43447L, +43448L,43449L,43450L,43451L,43452L,43453L,43454L,43455L,43456L,43457L, +43458L,43459L,43460L,43461L,43462L,43463L,43464L,43465L,43466L,43467L, +43468L,43469L,43470L,43471L,43472L,43473L,43474L,43475L,43476L,43477L, +43478L,43479L,43480L,43481L,43482L,43483L,43484L,43485L,43486L,43487L, +43488L,43489L,43490L,43491L,43492L,43493L,43494L,43495L,43496L,43497L, +43498L,43499L,43500L,43501L,43502L,43503L,43504L,43505L,43506L,43507L, +43508L,43509L,43510L,43511L,43512L,43513L,43514L,43515L,43516L,43517L, +43518L,43519L,43520L,43521L,43522L,43523L,43524L,43525L,43526L,43527L, +43528L,43529L,43530L,43531L,43532L,43533L,43534L,43535L,43536L,43537L, +43538L,43539L,43540L,43541L,43542L,43543L,43544L,43545L,43546L,43547L, +43548L,43549L,43550L,43551L,43552L,43553L,43554L,43555L,43556L,43557L, +43558L,43559L,43560L,43561L,43562L,43563L,43564L,43565L,43566L,43567L, +43568L,43569L,43570L,43571L,43572L,43573L,43574L,43575L,43576L,43577L, +43578L,43579L,43580L,43581L,43582L,43583L,43584L,43585L,43586L,43587L, +43588L,43589L,43590L,43591L,43592L,43593L,43594L,43595L,43596L,43597L, +43598L,43599L,43600L,43601L,43602L,43603L,43604L,43605L,43606L,43607L, +43608L,43609L,43610L,43611L,43612L,43613L,43614L,43615L,43616L,43617L, +43618L,43619L,43620L,43621L,43622L,43623L,43624L,43625L,43626L,43627L, +43628L,43629L,43630L,43631L,43632L,43633L,43634L,43635L,43636L,43637L, +43638L,43639L,43640L,43641L,43642L,43643L,43644L,43645L,43646L,43647L, +43648L,43649L,43650L,43651L,43652L,43653L,43654L,43655L,43656L,43657L, +43658L,43659L,43660L,43661L,43662L,43663L,43664L,43665L,43666L,43667L, +43668L,43669L,43670L,43671L,43672L,43673L,43674L,43675L,43676L,43677L, +43678L,43679L,43680L,43681L,43682L,43683L,43684L,43685L,43686L,43687L, +43688L,43689L,43690L,43691L,43692L,43693L,43694L,43695L,43696L,43697L, +43698L,43699L,43700L,43701L,43702L,43703L,43704L,43705L,43706L,43707L, +43708L,43709L,43710L,43711L,43712L,43713L,43714L,43715L,43716L,43717L, +43718L,43719L,43720L,43721L,43722L,43723L,43724L,43725L,43726L,43727L, +43728L,43729L,43730L,43731L,43732L,43733L,43734L,43735L,43736L,43737L, +43738L,43739L,43740L,43741L,43742L,43743L,43744L,43745L,43746L,43747L, +43748L,43749L,43750L,43751L,43752L,43753L,43754L,43755L,43756L,43757L, +43758L,43759L,43760L,43761L,43762L,43763L,43764L,43765L,43766L,43767L, +43768L,43769L,43770L,43771L,43772L,43773L,43774L,43775L,43776L,43777L, +43778L,43779L,43780L,43781L,43782L,43783L,43784L,43785L,43786L,43787L, +43788L,43789L,43790L,43791L,43792L,43793L,43794L,43795L,43796L,43797L, +43798L,43799L,43800L,43801L,43802L,43803L,43804L,43805L,43806L,43807L, +43808L,43809L,43810L,43811L,43812L,43813L,43814L,43815L,43816L,43817L, +43818L,43819L,43820L,43821L,43822L,43823L,43824L,43825L,43826L,43827L, +43828L,43829L,43830L,43831L,43832L,43833L,43834L,43835L,43836L,43837L, +43838L,43839L,43840L,43841L,43842L,43843L,43844L,43845L,43846L,43847L, +43848L,43849L,43850L,43851L,43852L,43853L,43854L,43855L,43856L,43857L, +43858L,42931L,43860L,43861L,43862L,43863L,43864L,43865L,43866L,43867L, +43868L,43869L,43870L,43871L,43872L,43873L,43874L,43875L,43876L,43877L, +43878L,43879L,43880L,43881L,43882L,43883L,43884L,43885L,43886L,43887L,5024, +5025,5026,5027,5028,5029,5030,5031,5032,5033,5034,5035,5036,5037,5038,5039, +5040,5041,5042,5043,5044,5045,5046,5047,5048,5049,5050,5051,5052,5053,5054, +5055,5056,5057,5058,5059,5060,5061,5062,5063,5064,5065,5066,5067,5068,5069, +5070,5071,5072,5073,5074,5075,5076,5077,5078,5079,5080,5081,5082,5083,5084, +5085,5086,5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099, +5100,5101,5102,5103,43968L,43969L,43970L,43971L,43972L,43973L,43974L, +43975L,43976L,43977L,43978L,43979L,43980L,43981L,43982L,43983L,43984L, +43985L,43986L,43987L,43988L,43989L,43990L,43991L,43992L,43993L,43994L, +43995L,43996L,43997L,43998L,43999L,44000L,44001L,44002L,44003L,44004L, +44005L,44006L,44007L,44008L,44009L,44010L,44011L,44012L,44013L,44014L, +44015L,44016L,44017L,44018L,44019L,44020L,44021L,44022L,44023L,44024L, +44025L,44026L,44027L,44028L,44029L,44030L,44031L,44032L,44033L,44034L, +44035L,44036L,44037L,44038L,44039L,44040L,44041L,44042L,44043L,44044L, +44045L,44046L,44047L,44048L,44049L,44050L,44051L,44052L,44053L,44054L, +44055L,44056L,44057L,44058L,44059L,44060L,44061L,44062L,44063L,44064L, +44065L,44066L,44067L,44068L,44069L,44070L,44071L,44072L,44073L,44074L, +44075L,44076L,44077L,44078L,44079L,44080L,44081L,44082L,44083L,44084L, +44085L,44086L,44087L,44088L,44089L,44090L,44091L,44092L,44093L,44094L, +44095L,44096L,44097L,44098L,44099L,44100L,44101L,44102L,44103L,44104L, +44105L,44106L,44107L,44108L,44109L,44110L,44111L,44112L,44113L,44114L, +44115L,44116L,44117L,44118L,44119L,44120L,44121L,44122L,44123L,44124L, +44125L,44126L,44127L,44128L,44129L,44130L,44131L,44132L,44133L,44134L, +44135L,44136L,44137L,44138L,44139L,44140L,44141L,44142L,44143L,44144L, +44145L,44146L,44147L,44148L,44149L,44150L,44151L,44152L,44153L,44154L, +44155L,44156L,44157L,44158L,44159L,44160L,44161L,44162L,44163L,44164L, +44165L,44166L,44167L,44168L,44169L,44170L,44171L,44172L,44173L,44174L, +44175L,44176L,44177L,44178L,44179L,44180L,44181L,44182L,44183L,44184L, +44185L,44186L,44187L,44188L,44189L,44190L,44191L,44192L,44193L,44194L, +44195L,44196L,44197L,44198L,44199L,44200L,44201L,44202L,44203L,44204L, +44205L,44206L,44207L,44208L,44209L,44210L,44211L,44212L,44213L,44214L, +44215L,44216L,44217L,44218L,44219L,44220L,44221L,44222L,44223L,44224L, +44225L,44226L,44227L,44228L,44229L,44230L,44231L,44232L,44233L,44234L, +44235L,44236L,44237L,44238L,44239L,44240L,44241L,44242L,44243L,44244L, +44245L,44246L,44247L,44248L,44249L,44250L,44251L,44252L,44253L,44254L, +44255L,44256L,44257L,44258L,44259L,44260L,44261L,44262L,44263L,44264L, +44265L,44266L,44267L,44268L,44269L,44270L,44271L,44272L,44273L,44274L, +44275L,44276L,44277L,44278L,44279L,44280L,44281L,44282L,44283L,44284L, +44285L,44286L,44287L,44288L,44289L,44290L,44291L,44292L,44293L,44294L, +44295L,44296L,44297L,44298L,44299L,44300L,44301L,44302L,44303L,44304L, +44305L,44306L,44307L,44308L,44309L,44310L,44311L,44312L,44313L,44314L, +44315L,44316L,44317L,44318L,44319L,44320L,44321L,44322L,44323L,44324L, +44325L,44326L,44327L,44328L,44329L,44330L,44331L,44332L,44333L,44334L, +44335L,44336L,44337L,44338L,44339L,44340L,44341L,44342L,44343L,44344L, +44345L,44346L,44347L,44348L,44349L,44350L,44351L,44352L,44353L,44354L, +44355L,44356L,44357L,44358L,44359L,44360L,44361L,44362L,44363L,44364L, +44365L,44366L,44367L,44368L,44369L,44370L,44371L,44372L,44373L,44374L, +44375L,44376L,44377L,44378L,44379L,44380L,44381L,44382L,44383L,44384L, +44385L,44386L,44387L,44388L,44389L,44390L,44391L,44392L,44393L,44394L, +44395L,44396L,44397L,44398L,44399L,44400L,44401L,44402L,44403L,44404L, +44405L,44406L,44407L,44408L,44409L,44410L,44411L,44412L,44413L,44414L, +44415L,44416L,44417L,44418L,44419L,44420L,44421L,44422L,44423L,44424L, +44425L,44426L,44427L,44428L,44429L,44430L,44431L,44432L,44433L,44434L, +44435L,44436L,44437L,44438L,44439L,44440L,44441L,44442L,44443L,44444L, +44445L,44446L,44447L,44448L,44449L,44450L,44451L,44452L,44453L,44454L, +44455L,44456L,44457L,44458L,44459L,44460L,44461L,44462L,44463L,44464L, +44465L,44466L,44467L,44468L,44469L,44470L,44471L,44472L,44473L,44474L, +44475L,44476L,44477L,44478L,44479L,44480L,44481L,44482L,44483L,44484L, +44485L,44486L,44487L,44488L,44489L,44490L,44491L,44492L,44493L,44494L, +44495L,44496L,44497L,44498L,44499L,44500L,44501L,44502L,44503L,44504L, +44505L,44506L,44507L,44508L,44509L,44510L,44511L,44512L,44513L,44514L, +44515L,44516L,44517L,44518L,44519L,44520L,44521L,44522L,44523L,44524L, +44525L,44526L,44527L,44528L,44529L,44530L,44531L,44532L,44533L,44534L, +44535L,44536L,44537L,44538L,44539L,44540L,44541L,44542L,44543L,44544L, +44545L,44546L,44547L,44548L,44549L,44550L,44551L,44552L,44553L,44554L, +44555L,44556L,44557L,44558L,44559L,44560L,44561L,44562L,44563L,44564L, +44565L,44566L,44567L,44568L,44569L,44570L,44571L,44572L,44573L,44574L, +44575L,44576L,44577L,44578L,44579L,44580L,44581L,44582L,44583L,44584L, +44585L,44586L,44587L,44588L,44589L,44590L,44591L,44592L,44593L,44594L, +44595L,44596L,44597L,44598L,44599L,44600L,44601L,44602L,44603L,44604L, +44605L,44606L,44607L,44608L,44609L,44610L,44611L,44612L,44613L,44614L, +44615L,44616L,44617L,44618L,44619L,44620L,44621L,44622L,44623L,44624L, +44625L,44626L,44627L,44628L,44629L,44630L,44631L,44632L,44633L,44634L, +44635L,44636L,44637L,44638L,44639L,44640L,44641L,44642L,44643L,44644L, +44645L,44646L,44647L,44648L,44649L,44650L,44651L,44652L,44653L,44654L, +44655L,44656L,44657L,44658L,44659L,44660L,44661L,44662L,44663L,44664L, +44665L,44666L,44667L,44668L,44669L,44670L,44671L,44672L,44673L,44674L, +44675L,44676L,44677L,44678L,44679L,44680L,44681L,44682L,44683L,44684L, +44685L,44686L,44687L,44688L,44689L,44690L,44691L,44692L,44693L,44694L, +44695L,44696L,44697L,44698L,44699L,44700L,44701L,44702L,44703L,44704L, +44705L,44706L,44707L,44708L,44709L,44710L,44711L,44712L,44713L,44714L, +44715L,44716L,44717L,44718L,44719L,44720L,44721L,44722L,44723L,44724L, +44725L,44726L,44727L,44728L,44729L,44730L,44731L,44732L,44733L,44734L, +44735L,44736L,44737L,44738L,44739L,44740L,44741L,44742L,44743L,44744L, +44745L,44746L,44747L,44748L,44749L,44750L,44751L,44752L,44753L,44754L, +44755L,44756L,44757L,44758L,44759L,44760L,44761L,44762L,44763L,44764L, +44765L,44766L,44767L,44768L,44769L,44770L,44771L,44772L,44773L,44774L, +44775L,44776L,44777L,44778L,44779L,44780L,44781L,44782L,44783L,44784L, +44785L,44786L,44787L,44788L,44789L,44790L,44791L,44792L,44793L,44794L, +44795L,44796L,44797L,44798L,44799L,44800L,44801L,44802L,44803L,44804L, +44805L,44806L,44807L,44808L,44809L,44810L,44811L,44812L,44813L,44814L, +44815L,44816L,44817L,44818L,44819L,44820L,44821L,44822L,44823L,44824L, +44825L,44826L,44827L,44828L,44829L,44830L,44831L,44832L,44833L,44834L, +44835L,44836L,44837L,44838L,44839L,44840L,44841L,44842L,44843L,44844L, +44845L,44846L,44847L,44848L,44849L,44850L,44851L,44852L,44853L,44854L, +44855L,44856L,44857L,44858L,44859L,44860L,44861L,44862L,44863L,44864L, +44865L,44866L,44867L,44868L,44869L,44870L,44871L,44872L,44873L,44874L, +44875L,44876L,44877L,44878L,44879L,44880L,44881L,44882L,44883L,44884L, +44885L,44886L,44887L,44888L,44889L,44890L,44891L,44892L,44893L,44894L, +44895L,44896L,44897L,44898L,44899L,44900L,44901L,44902L,44903L,44904L, +44905L,44906L,44907L,44908L,44909L,44910L,44911L,44912L,44913L,44914L, +44915L,44916L,44917L,44918L,44919L,44920L,44921L,44922L,44923L,44924L, +44925L,44926L,44927L,44928L,44929L,44930L,44931L,44932L,44933L,44934L, +44935L,44936L,44937L,44938L,44939L,44940L,44941L,44942L,44943L,44944L, +44945L,44946L,44947L,44948L,44949L,44950L,44951L,44952L,44953L,44954L, +44955L,44956L,44957L,44958L,44959L,44960L,44961L,44962L,44963L,44964L, +44965L,44966L,44967L,44968L,44969L,44970L,44971L,44972L,44973L,44974L, +44975L,44976L,44977L,44978L,44979L,44980L,44981L,44982L,44983L,44984L, +44985L,44986L,44987L,44988L,44989L,44990L,44991L,44992L,44993L,44994L, +44995L,44996L,44997L,44998L,44999L,45000L,45001L,45002L,45003L,45004L, +45005L,45006L,45007L,45008L,45009L,45010L,45011L,45012L,45013L,45014L, +45015L,45016L,45017L,45018L,45019L,45020L,45021L,45022L,45023L,45024L, +45025L,45026L,45027L,45028L,45029L,45030L,45031L,45032L,45033L,45034L, +45035L,45036L,45037L,45038L,45039L,45040L,45041L,45042L,45043L,45044L, +45045L,45046L,45047L,45048L,45049L,45050L,45051L,45052L,45053L,45054L, +45055L,45056L,45057L,45058L,45059L,45060L,45061L,45062L,45063L,45064L, +45065L,45066L,45067L,45068L,45069L,45070L,45071L,45072L,45073L,45074L, +45075L,45076L,45077L,45078L,45079L,45080L,45081L,45082L,45083L,45084L, +45085L,45086L,45087L,45088L,45089L,45090L,45091L,45092L,45093L,45094L, +45095L,45096L,45097L,45098L,45099L,45100L,45101L,45102L,45103L,45104L, +45105L,45106L,45107L,45108L,45109L,45110L,45111L,45112L,45113L,45114L, +45115L,45116L,45117L,45118L,45119L,45120L,45121L,45122L,45123L,45124L, +45125L,45126L,45127L,45128L,45129L,45130L,45131L,45132L,45133L,45134L, +45135L,45136L,45137L,45138L,45139L,45140L,45141L,45142L,45143L,45144L, +45145L,45146L,45147L,45148L,45149L,45150L,45151L,45152L,45153L,45154L, +45155L,45156L,45157L,45158L,45159L,45160L,45161L,45162L,45163L,45164L, +45165L,45166L,45167L,45168L,45169L,45170L,45171L,45172L,45173L,45174L, +45175L,45176L,45177L,45178L,45179L,45180L,45181L,45182L,45183L,45184L, +45185L,45186L,45187L,45188L,45189L,45190L,45191L,45192L,45193L,45194L, +45195L,45196L,45197L,45198L,45199L,45200L,45201L,45202L,45203L,45204L, +45205L,45206L,45207L,45208L,45209L,45210L,45211L,45212L,45213L,45214L, +45215L,45216L,45217L,45218L,45219L,45220L,45221L,45222L,45223L,45224L, +45225L,45226L,45227L,45228L,45229L,45230L,45231L,45232L,45233L,45234L, +45235L,45236L,45237L,45238L,45239L,45240L,45241L,45242L,45243L,45244L, +45245L,45246L,45247L,45248L,45249L,45250L,45251L,45252L,45253L,45254L, +45255L,45256L,45257L,45258L,45259L,45260L,45261L,45262L,45263L,45264L, +45265L,45266L,45267L,45268L,45269L,45270L,45271L,45272L,45273L,45274L, +45275L,45276L,45277L,45278L,45279L,45280L,45281L,45282L,45283L,45284L, +45285L,45286L,45287L,45288L,45289L,45290L,45291L,45292L,45293L,45294L, +45295L,45296L,45297L,45298L,45299L,45300L,45301L,45302L,45303L,45304L, +45305L,45306L,45307L,45308L,45309L,45310L,45311L,45312L,45313L,45314L, +45315L,45316L,45317L,45318L,45319L,45320L,45321L,45322L,45323L,45324L, +45325L,45326L,45327L,45328L,45329L,45330L,45331L,45332L,45333L,45334L, +45335L,45336L,45337L,45338L,45339L,45340L,45341L,45342L,45343L,45344L, +45345L,45346L,45347L,45348L,45349L,45350L,45351L,45352L,45353L,45354L, +45355L,45356L,45357L,45358L,45359L,45360L,45361L,45362L,45363L,45364L, +45365L,45366L,45367L,45368L,45369L,45370L,45371L,45372L,45373L,45374L, +45375L,45376L,45377L,45378L,45379L,45380L,45381L,45382L,45383L,45384L, +45385L,45386L,45387L,45388L,45389L,45390L,45391L,45392L,45393L,45394L, +45395L,45396L,45397L,45398L,45399L,45400L,45401L,45402L,45403L,45404L, +45405L,45406L,45407L,45408L,45409L,45410L,45411L,45412L,45413L,45414L, +45415L,45416L,45417L,45418L,45419L,45420L,45421L,45422L,45423L,45424L, +45425L,45426L,45427L,45428L,45429L,45430L,45431L,45432L,45433L,45434L, +45435L,45436L,45437L,45438L,45439L,45440L,45441L,45442L,45443L,45444L, +45445L,45446L,45447L,45448L,45449L,45450L,45451L,45452L,45453L,45454L, +45455L,45456L,45457L,45458L,45459L,45460L,45461L,45462L,45463L,45464L, +45465L,45466L,45467L,45468L,45469L,45470L,45471L,45472L,45473L,45474L, +45475L,45476L,45477L,45478L,45479L,45480L,45481L,45482L,45483L,45484L, +45485L,45486L,45487L,45488L,45489L,45490L,45491L,45492L,45493L,45494L, +45495L,45496L,45497L,45498L,45499L,45500L,45501L,45502L,45503L,45504L, +45505L,45506L,45507L,45508L,45509L,45510L,45511L,45512L,45513L,45514L, +45515L,45516L,45517L,45518L,45519L,45520L,45521L,45522L,45523L,45524L, +45525L,45526L,45527L,45528L,45529L,45530L,45531L,45532L,45533L,45534L, +45535L,45536L,45537L,45538L,45539L,45540L,45541L,45542L,45543L,45544L, +45545L,45546L,45547L,45548L,45549L,45550L,45551L,45552L,45553L,45554L, +45555L,45556L,45557L,45558L,45559L,45560L,45561L,45562L,45563L,45564L, +45565L,45566L,45567L,45568L,45569L,45570L,45571L,45572L,45573L,45574L, +45575L,45576L,45577L,45578L,45579L,45580L,45581L,45582L,45583L,45584L, +45585L,45586L,45587L,45588L,45589L,45590L,45591L,45592L,45593L,45594L, +45595L,45596L,45597L,45598L,45599L,45600L,45601L,45602L,45603L,45604L, +45605L,45606L,45607L,45608L,45609L,45610L,45611L,45612L,45613L,45614L, +45615L,45616L,45617L,45618L,45619L,45620L,45621L,45622L,45623L,45624L, +45625L,45626L,45627L,45628L,45629L,45630L,45631L,45632L,45633L,45634L, +45635L,45636L,45637L,45638L,45639L,45640L,45641L,45642L,45643L,45644L, +45645L,45646L,45647L,45648L,45649L,45650L,45651L,45652L,45653L,45654L, +45655L,45656L,45657L,45658L,45659L,45660L,45661L,45662L,45663L,45664L, +45665L,45666L,45667L,45668L,45669L,45670L,45671L,45672L,45673L,45674L, +45675L,45676L,45677L,45678L,45679L,45680L,45681L,45682L,45683L,45684L, +45685L,45686L,45687L,45688L,45689L,45690L,45691L,45692L,45693L,45694L, +45695L,45696L,45697L,45698L,45699L,45700L,45701L,45702L,45703L,45704L, +45705L,45706L,45707L,45708L,45709L,45710L,45711L,45712L,45713L,45714L, +45715L,45716L,45717L,45718L,45719L,45720L,45721L,45722L,45723L,45724L, +45725L,45726L,45727L,45728L,45729L,45730L,45731L,45732L,45733L,45734L, +45735L,45736L,45737L,45738L,45739L,45740L,45741L,45742L,45743L,45744L, +45745L,45746L,45747L,45748L,45749L,45750L,45751L,45752L,45753L,45754L, +45755L,45756L,45757L,45758L,45759L,45760L,45761L,45762L,45763L,45764L, +45765L,45766L,45767L,45768L,45769L,45770L,45771L,45772L,45773L,45774L, +45775L,45776L,45777L,45778L,45779L,45780L,45781L,45782L,45783L,45784L, +45785L,45786L,45787L,45788L,45789L,45790L,45791L,45792L,45793L,45794L, +45795L,45796L,45797L,45798L,45799L,45800L,45801L,45802L,45803L,45804L, +45805L,45806L,45807L,45808L,45809L,45810L,45811L,45812L,45813L,45814L, +45815L,45816L,45817L,45818L,45819L,45820L,45821L,45822L,45823L,45824L, +45825L,45826L,45827L,45828L,45829L,45830L,45831L,45832L,45833L,45834L, +45835L,45836L,45837L,45838L,45839L,45840L,45841L,45842L,45843L,45844L, +45845L,45846L,45847L,45848L,45849L,45850L,45851L,45852L,45853L,45854L, +45855L,45856L,45857L,45858L,45859L,45860L,45861L,45862L,45863L,45864L, +45865L,45866L,45867L,45868L,45869L,45870L,45871L,45872L,45873L,45874L, +45875L,45876L,45877L,45878L,45879L,45880L,45881L,45882L,45883L,45884L, +45885L,45886L,45887L,45888L,45889L,45890L,45891L,45892L,45893L,45894L, +45895L,45896L,45897L,45898L,45899L,45900L,45901L,45902L,45903L,45904L, +45905L,45906L,45907L,45908L,45909L,45910L,45911L,45912L,45913L,45914L, +45915L,45916L,45917L,45918L,45919L,45920L,45921L,45922L,45923L,45924L, +45925L,45926L,45927L,45928L,45929L,45930L,45931L,45932L,45933L,45934L, +45935L,45936L,45937L,45938L,45939L,45940L,45941L,45942L,45943L,45944L, +45945L,45946L,45947L,45948L,45949L,45950L,45951L,45952L,45953L,45954L, +45955L,45956L,45957L,45958L,45959L,45960L,45961L,45962L,45963L,45964L, +45965L,45966L,45967L,45968L,45969L,45970L,45971L,45972L,45973L,45974L, +45975L,45976L,45977L,45978L,45979L,45980L,45981L,45982L,45983L,45984L, +45985L,45986L,45987L,45988L,45989L,45990L,45991L,45992L,45993L,45994L, +45995L,45996L,45997L,45998L,45999L,46000L,46001L,46002L,46003L,46004L, +46005L,46006L,46007L,46008L,46009L,46010L,46011L,46012L,46013L,46014L, +46015L,46016L,46017L,46018L,46019L,46020L,46021L,46022L,46023L,46024L, +46025L,46026L,46027L,46028L,46029L,46030L,46031L,46032L,46033L,46034L, +46035L,46036L,46037L,46038L,46039L,46040L,46041L,46042L,46043L,46044L, +46045L,46046L,46047L,46048L,46049L,46050L,46051L,46052L,46053L,46054L, +46055L,46056L,46057L,46058L,46059L,46060L,46061L,46062L,46063L,46064L, +46065L,46066L,46067L,46068L,46069L,46070L,46071L,46072L,46073L,46074L, +46075L,46076L,46077L,46078L,46079L,46080L,46081L,46082L,46083L,46084L, +46085L,46086L,46087L,46088L,46089L,46090L,46091L,46092L,46093L,46094L, +46095L,46096L,46097L,46098L,46099L,46100L,46101L,46102L,46103L,46104L, +46105L,46106L,46107L,46108L,46109L,46110L,46111L,46112L,46113L,46114L, +46115L,46116L,46117L,46118L,46119L,46120L,46121L,46122L,46123L,46124L, +46125L,46126L,46127L,46128L,46129L,46130L,46131L,46132L,46133L,46134L, +46135L,46136L,46137L,46138L,46139L,46140L,46141L,46142L,46143L,46144L, +46145L,46146L,46147L,46148L,46149L,46150L,46151L,46152L,46153L,46154L, +46155L,46156L,46157L,46158L,46159L,46160L,46161L,46162L,46163L,46164L, +46165L,46166L,46167L,46168L,46169L,46170L,46171L,46172L,46173L,46174L, +46175L,46176L,46177L,46178L,46179L,46180L,46181L,46182L,46183L,46184L, +46185L,46186L,46187L,46188L,46189L,46190L,46191L,46192L,46193L,46194L, +46195L,46196L,46197L,46198L,46199L,46200L,46201L,46202L,46203L,46204L, +46205L,46206L,46207L,46208L,46209L,46210L,46211L,46212L,46213L,46214L, +46215L,46216L,46217L,46218L,46219L,46220L,46221L,46222L,46223L,46224L, +46225L,46226L,46227L,46228L,46229L,46230L,46231L,46232L,46233L,46234L, +46235L,46236L,46237L,46238L,46239L,46240L,46241L,46242L,46243L,46244L, +46245L,46246L,46247L,46248L,46249L,46250L,46251L,46252L,46253L,46254L, +46255L,46256L,46257L,46258L,46259L,46260L,46261L,46262L,46263L,46264L, +46265L,46266L,46267L,46268L,46269L,46270L,46271L,46272L,46273L,46274L, +46275L,46276L,46277L,46278L,46279L,46280L,46281L,46282L,46283L,46284L, +46285L,46286L,46287L,46288L,46289L,46290L,46291L,46292L,46293L,46294L, +46295L,46296L,46297L,46298L,46299L,46300L,46301L,46302L,46303L,46304L, +46305L,46306L,46307L,46308L,46309L,46310L,46311L,46312L,46313L,46314L, +46315L,46316L,46317L,46318L,46319L,46320L,46321L,46322L,46323L,46324L, +46325L,46326L,46327L,46328L,46329L,46330L,46331L,46332L,46333L,46334L, +46335L,46336L,46337L,46338L,46339L,46340L,46341L,46342L,46343L,46344L, +46345L,46346L,46347L,46348L,46349L,46350L,46351L,46352L,46353L,46354L, +46355L,46356L,46357L,46358L,46359L,46360L,46361L,46362L,46363L,46364L, +46365L,46366L,46367L,46368L,46369L,46370L,46371L,46372L,46373L,46374L, +46375L,46376L,46377L,46378L,46379L,46380L,46381L,46382L,46383L,46384L, +46385L,46386L,46387L,46388L,46389L,46390L,46391L,46392L,46393L,46394L, +46395L,46396L,46397L,46398L,46399L,46400L,46401L,46402L,46403L,46404L, +46405L,46406L,46407L,46408L,46409L,46410L,46411L,46412L,46413L,46414L, +46415L,46416L,46417L,46418L,46419L,46420L,46421L,46422L,46423L,46424L, +46425L,46426L,46427L,46428L,46429L,46430L,46431L,46432L,46433L,46434L, +46435L,46436L,46437L,46438L,46439L,46440L,46441L,46442L,46443L,46444L, +46445L,46446L,46447L,46448L,46449L,46450L,46451L,46452L,46453L,46454L, +46455L,46456L,46457L,46458L,46459L,46460L,46461L,46462L,46463L,46464L, +46465L,46466L,46467L,46468L,46469L,46470L,46471L,46472L,46473L,46474L, +46475L,46476L,46477L,46478L,46479L,46480L,46481L,46482L,46483L,46484L, +46485L,46486L,46487L,46488L,46489L,46490L,46491L,46492L,46493L,46494L, +46495L,46496L,46497L,46498L,46499L,46500L,46501L,46502L,46503L,46504L, +46505L,46506L,46507L,46508L,46509L,46510L,46511L,46512L,46513L,46514L, +46515L,46516L,46517L,46518L,46519L,46520L,46521L,46522L,46523L,46524L, +46525L,46526L,46527L,46528L,46529L,46530L,46531L,46532L,46533L,46534L, +46535L,46536L,46537L,46538L,46539L,46540L,46541L,46542L,46543L,46544L, +46545L,46546L,46547L,46548L,46549L,46550L,46551L,46552L,46553L,46554L, +46555L,46556L,46557L,46558L,46559L,46560L,46561L,46562L,46563L,46564L, +46565L,46566L,46567L,46568L,46569L,46570L,46571L,46572L,46573L,46574L, +46575L,46576L,46577L,46578L,46579L,46580L,46581L,46582L,46583L,46584L, +46585L,46586L,46587L,46588L,46589L,46590L,46591L,46592L,46593L,46594L, +46595L,46596L,46597L,46598L,46599L,46600L,46601L,46602L,46603L,46604L, +46605L,46606L,46607L,46608L,46609L,46610L,46611L,46612L,46613L,46614L, +46615L,46616L,46617L,46618L,46619L,46620L,46621L,46622L,46623L,46624L, +46625L,46626L,46627L,46628L,46629L,46630L,46631L,46632L,46633L,46634L, +46635L,46636L,46637L,46638L,46639L,46640L,46641L,46642L,46643L,46644L, +46645L,46646L,46647L,46648L,46649L,46650L,46651L,46652L,46653L,46654L, +46655L,46656L,46657L,46658L,46659L,46660L,46661L,46662L,46663L,46664L, +46665L,46666L,46667L,46668L,46669L,46670L,46671L,46672L,46673L,46674L, +46675L,46676L,46677L,46678L,46679L,46680L,46681L,46682L,46683L,46684L, +46685L,46686L,46687L,46688L,46689L,46690L,46691L,46692L,46693L,46694L, +46695L,46696L,46697L,46698L,46699L,46700L,46701L,46702L,46703L,46704L, +46705L,46706L,46707L,46708L,46709L,46710L,46711L,46712L,46713L,46714L, +46715L,46716L,46717L,46718L,46719L,46720L,46721L,46722L,46723L,46724L, +46725L,46726L,46727L,46728L,46729L,46730L,46731L,46732L,46733L,46734L, +46735L,46736L,46737L,46738L,46739L,46740L,46741L,46742L,46743L,46744L, +46745L,46746L,46747L,46748L,46749L,46750L,46751L,46752L,46753L,46754L, +46755L,46756L,46757L,46758L,46759L,46760L,46761L,46762L,46763L,46764L, +46765L,46766L,46767L,46768L,46769L,46770L,46771L,46772L,46773L,46774L, +46775L,46776L,46777L,46778L,46779L,46780L,46781L,46782L,46783L,46784L, +46785L,46786L,46787L,46788L,46789L,46790L,46791L,46792L,46793L,46794L, +46795L,46796L,46797L,46798L,46799L,46800L,46801L,46802L,46803L,46804L, +46805L,46806L,46807L,46808L,46809L,46810L,46811L,46812L,46813L,46814L, +46815L,46816L,46817L,46818L,46819L,46820L,46821L,46822L,46823L,46824L, +46825L,46826L,46827L,46828L,46829L,46830L,46831L,46832L,46833L,46834L, +46835L,46836L,46837L,46838L,46839L,46840L,46841L,46842L,46843L,46844L, +46845L,46846L,46847L,46848L,46849L,46850L,46851L,46852L,46853L,46854L, +46855L,46856L,46857L,46858L,46859L,46860L,46861L,46862L,46863L,46864L, +46865L,46866L,46867L,46868L,46869L,46870L,46871L,46872L,46873L,46874L, +46875L,46876L,46877L,46878L,46879L,46880L,46881L,46882L,46883L,46884L, +46885L,46886L,46887L,46888L,46889L,46890L,46891L,46892L,46893L,46894L, +46895L,46896L,46897L,46898L,46899L,46900L,46901L,46902L,46903L,46904L, +46905L,46906L,46907L,46908L,46909L,46910L,46911L,46912L,46913L,46914L, +46915L,46916L,46917L,46918L,46919L,46920L,46921L,46922L,46923L,46924L, +46925L,46926L,46927L,46928L,46929L,46930L,46931L,46932L,46933L,46934L, +46935L,46936L,46937L,46938L,46939L,46940L,46941L,46942L,46943L,46944L, +46945L,46946L,46947L,46948L,46949L,46950L,46951L,46952L,46953L,46954L, +46955L,46956L,46957L,46958L,46959L,46960L,46961L,46962L,46963L,46964L, +46965L,46966L,46967L,46968L,46969L,46970L,46971L,46972L,46973L,46974L, +46975L,46976L,46977L,46978L,46979L,46980L,46981L,46982L,46983L,46984L, +46985L,46986L,46987L,46988L,46989L,46990L,46991L,46992L,46993L,46994L, +46995L,46996L,46997L,46998L,46999L,47000L,47001L,47002L,47003L,47004L, +47005L,47006L,47007L,47008L,47009L,47010L,47011L,47012L,47013L,47014L, +47015L,47016L,47017L,47018L,47019L,47020L,47021L,47022L,47023L,47024L, +47025L,47026L,47027L,47028L,47029L,47030L,47031L,47032L,47033L,47034L, +47035L,47036L,47037L,47038L,47039L,47040L,47041L,47042L,47043L,47044L, +47045L,47046L,47047L,47048L,47049L,47050L,47051L,47052L,47053L,47054L, +47055L,47056L,47057L,47058L,47059L,47060L,47061L,47062L,47063L,47064L, +47065L,47066L,47067L,47068L,47069L,47070L,47071L,47072L,47073L,47074L, +47075L,47076L,47077L,47078L,47079L,47080L,47081L,47082L,47083L,47084L, +47085L,47086L,47087L,47088L,47089L,47090L,47091L,47092L,47093L,47094L, +47095L,47096L,47097L,47098L,47099L,47100L,47101L,47102L,47103L,47104L, +47105L,47106L,47107L,47108L,47109L,47110L,47111L,47112L,47113L,47114L, +47115L,47116L,47117L,47118L,47119L,47120L,47121L,47122L,47123L,47124L, +47125L,47126L,47127L,47128L,47129L,47130L,47131L,47132L,47133L,47134L, +47135L,47136L,47137L,47138L,47139L,47140L,47141L,47142L,47143L,47144L, +47145L,47146L,47147L,47148L,47149L,47150L,47151L,47152L,47153L,47154L, +47155L,47156L,47157L,47158L,47159L,47160L,47161L,47162L,47163L,47164L, +47165L,47166L,47167L,47168L,47169L,47170L,47171L,47172L,47173L,47174L, +47175L,47176L,47177L,47178L,47179L,47180L,47181L,47182L,47183L,47184L, +47185L,47186L,47187L,47188L,47189L,47190L,47191L,47192L,47193L,47194L, +47195L,47196L,47197L,47198L,47199L,47200L,47201L,47202L,47203L,47204L, +47205L,47206L,47207L,47208L,47209L,47210L,47211L,47212L,47213L,47214L, +47215L,47216L,47217L,47218L,47219L,47220L,47221L,47222L,47223L,47224L, +47225L,47226L,47227L,47228L,47229L,47230L,47231L,47232L,47233L,47234L, +47235L,47236L,47237L,47238L,47239L,47240L,47241L,47242L,47243L,47244L, +47245L,47246L,47247L,47248L,47249L,47250L,47251L,47252L,47253L,47254L, +47255L,47256L,47257L,47258L,47259L,47260L,47261L,47262L,47263L,47264L, +47265L,47266L,47267L,47268L,47269L,47270L,47271L,47272L,47273L,47274L, +47275L,47276L,47277L,47278L,47279L,47280L,47281L,47282L,47283L,47284L, +47285L,47286L,47287L,47288L,47289L,47290L,47291L,47292L,47293L,47294L, +47295L,47296L,47297L,47298L,47299L,47300L,47301L,47302L,47303L,47304L, +47305L,47306L,47307L,47308L,47309L,47310L,47311L,47312L,47313L,47314L, +47315L,47316L,47317L,47318L,47319L,47320L,47321L,47322L,47323L,47324L, +47325L,47326L,47327L,47328L,47329L,47330L,47331L,47332L,47333L,47334L, +47335L,47336L,47337L,47338L,47339L,47340L,47341L,47342L,47343L,47344L, +47345L,47346L,47347L,47348L,47349L,47350L,47351L,47352L,47353L,47354L, +47355L,47356L,47357L,47358L,47359L,47360L,47361L,47362L,47363L,47364L, +47365L,47366L,47367L,47368L,47369L,47370L,47371L,47372L,47373L,47374L, +47375L,47376L,47377L,47378L,47379L,47380L,47381L,47382L,47383L,47384L, +47385L,47386L,47387L,47388L,47389L,47390L,47391L,47392L,47393L,47394L, +47395L,47396L,47397L,47398L,47399L,47400L,47401L,47402L,47403L,47404L, +47405L,47406L,47407L,47408L,47409L,47410L,47411L,47412L,47413L,47414L, +47415L,47416L,47417L,47418L,47419L,47420L,47421L,47422L,47423L,47424L, +47425L,47426L,47427L,47428L,47429L,47430L,47431L,47432L,47433L,47434L, +47435L,47436L,47437L,47438L,47439L,47440L,47441L,47442L,47443L,47444L, +47445L,47446L,47447L,47448L,47449L,47450L,47451L,47452L,47453L,47454L, +47455L,47456L,47457L,47458L,47459L,47460L,47461L,47462L,47463L,47464L, +47465L,47466L,47467L,47468L,47469L,47470L,47471L,47472L,47473L,47474L, +47475L,47476L,47477L,47478L,47479L,47480L,47481L,47482L,47483L,47484L, +47485L,47486L,47487L,47488L,47489L,47490L,47491L,47492L,47493L,47494L, +47495L,47496L,47497L,47498L,47499L,47500L,47501L,47502L,47503L,47504L, +47505L,47506L,47507L,47508L,47509L,47510L,47511L,47512L,47513L,47514L, +47515L,47516L,47517L,47518L,47519L,47520L,47521L,47522L,47523L,47524L, +47525L,47526L,47527L,47528L,47529L,47530L,47531L,47532L,47533L,47534L, +47535L,47536L,47537L,47538L,47539L,47540L,47541L,47542L,47543L,47544L, +47545L,47546L,47547L,47548L,47549L,47550L,47551L,47552L,47553L,47554L, +47555L,47556L,47557L,47558L,47559L,47560L,47561L,47562L,47563L,47564L, +47565L,47566L,47567L,47568L,47569L,47570L,47571L,47572L,47573L,47574L, +47575L,47576L,47577L,47578L,47579L,47580L,47581L,47582L,47583L,47584L, +47585L,47586L,47587L,47588L,47589L,47590L,47591L,47592L,47593L,47594L, +47595L,47596L,47597L,47598L,47599L,47600L,47601L,47602L,47603L,47604L, +47605L,47606L,47607L,47608L,47609L,47610L,47611L,47612L,47613L,47614L, +47615L,47616L,47617L,47618L,47619L,47620L,47621L,47622L,47623L,47624L, +47625L,47626L,47627L,47628L,47629L,47630L,47631L,47632L,47633L,47634L, +47635L,47636L,47637L,47638L,47639L,47640L,47641L,47642L,47643L,47644L, +47645L,47646L,47647L,47648L,47649L,47650L,47651L,47652L,47653L,47654L, +47655L,47656L,47657L,47658L,47659L,47660L,47661L,47662L,47663L,47664L, +47665L,47666L,47667L,47668L,47669L,47670L,47671L,47672L,47673L,47674L, +47675L,47676L,47677L,47678L,47679L,47680L,47681L,47682L,47683L,47684L, +47685L,47686L,47687L,47688L,47689L,47690L,47691L,47692L,47693L,47694L, +47695L,47696L,47697L,47698L,47699L,47700L,47701L,47702L,47703L,47704L, +47705L,47706L,47707L,47708L,47709L,47710L,47711L,47712L,47713L,47714L, +47715L,47716L,47717L,47718L,47719L,47720L,47721L,47722L,47723L,47724L, +47725L,47726L,47727L,47728L,47729L,47730L,47731L,47732L,47733L,47734L, +47735L,47736L,47737L,47738L,47739L,47740L,47741L,47742L,47743L,47744L, +47745L,47746L,47747L,47748L,47749L,47750L,47751L,47752L,47753L,47754L, +47755L,47756L,47757L,47758L,47759L,47760L,47761L,47762L,47763L,47764L, +47765L,47766L,47767L,47768L,47769L,47770L,47771L,47772L,47773L,47774L, +47775L,47776L,47777L,47778L,47779L,47780L,47781L,47782L,47783L,47784L, +47785L,47786L,47787L,47788L,47789L,47790L,47791L,47792L,47793L,47794L, +47795L,47796L,47797L,47798L,47799L,47800L,47801L,47802L,47803L,47804L, +47805L,47806L,47807L,47808L,47809L,47810L,47811L,47812L,47813L,47814L, +47815L,47816L,47817L,47818L,47819L,47820L,47821L,47822L,47823L,47824L, +47825L,47826L,47827L,47828L,47829L,47830L,47831L,47832L,47833L,47834L, +47835L,47836L,47837L,47838L,47839L,47840L,47841L,47842L,47843L,47844L, +47845L,47846L,47847L,47848L,47849L,47850L,47851L,47852L,47853L,47854L, +47855L,47856L,47857L,47858L,47859L,47860L,47861L,47862L,47863L,47864L, +47865L,47866L,47867L,47868L,47869L,47870L,47871L,47872L,47873L,47874L, +47875L,47876L,47877L,47878L,47879L,47880L,47881L,47882L,47883L,47884L, +47885L,47886L,47887L,47888L,47889L,47890L,47891L,47892L,47893L,47894L, +47895L,47896L,47897L,47898L,47899L,47900L,47901L,47902L,47903L,47904L, +47905L,47906L,47907L,47908L,47909L,47910L,47911L,47912L,47913L,47914L, +47915L,47916L,47917L,47918L,47919L,47920L,47921L,47922L,47923L,47924L, +47925L,47926L,47927L,47928L,47929L,47930L,47931L,47932L,47933L,47934L, +47935L,47936L,47937L,47938L,47939L,47940L,47941L,47942L,47943L,47944L, +47945L,47946L,47947L,47948L,47949L,47950L,47951L,47952L,47953L,47954L, +47955L,47956L,47957L,47958L,47959L,47960L,47961L,47962L,47963L,47964L, +47965L,47966L,47967L,47968L,47969L,47970L,47971L,47972L,47973L,47974L, +47975L,47976L,47977L,47978L,47979L,47980L,47981L,47982L,47983L,47984L, +47985L,47986L,47987L,47988L,47989L,47990L,47991L,47992L,47993L,47994L, +47995L,47996L,47997L,47998L,47999L,48000L,48001L,48002L,48003L,48004L, +48005L,48006L,48007L,48008L,48009L,48010L,48011L,48012L,48013L,48014L, +48015L,48016L,48017L,48018L,48019L,48020L,48021L,48022L,48023L,48024L, +48025L,48026L,48027L,48028L,48029L,48030L,48031L,48032L,48033L,48034L, +48035L,48036L,48037L,48038L,48039L,48040L,48041L,48042L,48043L,48044L, +48045L,48046L,48047L,48048L,48049L,48050L,48051L,48052L,48053L,48054L, +48055L,48056L,48057L,48058L,48059L,48060L,48061L,48062L,48063L,48064L, +48065L,48066L,48067L,48068L,48069L,48070L,48071L,48072L,48073L,48074L, +48075L,48076L,48077L,48078L,48079L,48080L,48081L,48082L,48083L,48084L, +48085L,48086L,48087L,48088L,48089L,48090L,48091L,48092L,48093L,48094L, +48095L,48096L,48097L,48098L,48099L,48100L,48101L,48102L,48103L,48104L, +48105L,48106L,48107L,48108L,48109L,48110L,48111L,48112L,48113L,48114L, +48115L,48116L,48117L,48118L,48119L,48120L,48121L,48122L,48123L,48124L, +48125L,48126L,48127L,48128L,48129L,48130L,48131L,48132L,48133L,48134L, +48135L,48136L,48137L,48138L,48139L,48140L,48141L,48142L,48143L,48144L, +48145L,48146L,48147L,48148L,48149L,48150L,48151L,48152L,48153L,48154L, +48155L,48156L,48157L,48158L,48159L,48160L,48161L,48162L,48163L,48164L, +48165L,48166L,48167L,48168L,48169L,48170L,48171L,48172L,48173L,48174L, +48175L,48176L,48177L,48178L,48179L,48180L,48181L,48182L,48183L,48184L, +48185L,48186L,48187L,48188L,48189L,48190L,48191L,48192L,48193L,48194L, +48195L,48196L,48197L,48198L,48199L,48200L,48201L,48202L,48203L,48204L, +48205L,48206L,48207L,48208L,48209L,48210L,48211L,48212L,48213L,48214L, +48215L,48216L,48217L,48218L,48219L,48220L,48221L,48222L,48223L,48224L, +48225L,48226L,48227L,48228L,48229L,48230L,48231L,48232L,48233L,48234L, +48235L,48236L,48237L,48238L,48239L,48240L,48241L,48242L,48243L,48244L, +48245L,48246L,48247L,48248L,48249L,48250L,48251L,48252L,48253L,48254L, +48255L,48256L,48257L,48258L,48259L,48260L,48261L,48262L,48263L,48264L, +48265L,48266L,48267L,48268L,48269L,48270L,48271L,48272L,48273L,48274L, +48275L,48276L,48277L,48278L,48279L,48280L,48281L,48282L,48283L,48284L, +48285L,48286L,48287L,48288L,48289L,48290L,48291L,48292L,48293L,48294L, +48295L,48296L,48297L,48298L,48299L,48300L,48301L,48302L,48303L,48304L, +48305L,48306L,48307L,48308L,48309L,48310L,48311L,48312L,48313L,48314L, +48315L,48316L,48317L,48318L,48319L,48320L,48321L,48322L,48323L,48324L, +48325L,48326L,48327L,48328L,48329L,48330L,48331L,48332L,48333L,48334L, +48335L,48336L,48337L,48338L,48339L,48340L,48341L,48342L,48343L,48344L, +48345L,48346L,48347L,48348L,48349L,48350L,48351L,48352L,48353L,48354L, +48355L,48356L,48357L,48358L,48359L,48360L,48361L,48362L,48363L,48364L, +48365L,48366L,48367L,48368L,48369L,48370L,48371L,48372L,48373L,48374L, +48375L,48376L,48377L,48378L,48379L,48380L,48381L,48382L,48383L,48384L, +48385L,48386L,48387L,48388L,48389L,48390L,48391L,48392L,48393L,48394L, +48395L,48396L,48397L,48398L,48399L,48400L,48401L,48402L,48403L,48404L, +48405L,48406L,48407L,48408L,48409L,48410L,48411L,48412L,48413L,48414L, +48415L,48416L,48417L,48418L,48419L,48420L,48421L,48422L,48423L,48424L, +48425L,48426L,48427L,48428L,48429L,48430L,48431L,48432L,48433L,48434L, +48435L,48436L,48437L,48438L,48439L,48440L,48441L,48442L,48443L,48444L, +48445L,48446L,48447L,48448L,48449L,48450L,48451L,48452L,48453L,48454L, +48455L,48456L,48457L,48458L,48459L,48460L,48461L,48462L,48463L,48464L, +48465L,48466L,48467L,48468L,48469L,48470L,48471L,48472L,48473L,48474L, +48475L,48476L,48477L,48478L,48479L,48480L,48481L,48482L,48483L,48484L, +48485L,48486L,48487L,48488L,48489L,48490L,48491L,48492L,48493L,48494L, +48495L,48496L,48497L,48498L,48499L,48500L,48501L,48502L,48503L,48504L, +48505L,48506L,48507L,48508L,48509L,48510L,48511L,48512L,48513L,48514L, +48515L,48516L,48517L,48518L,48519L,48520L,48521L,48522L,48523L,48524L, +48525L,48526L,48527L,48528L,48529L,48530L,48531L,48532L,48533L,48534L, +48535L,48536L,48537L,48538L,48539L,48540L,48541L,48542L,48543L,48544L, +48545L,48546L,48547L,48548L,48549L,48550L,48551L,48552L,48553L,48554L, +48555L,48556L,48557L,48558L,48559L,48560L,48561L,48562L,48563L,48564L, +48565L,48566L,48567L,48568L,48569L,48570L,48571L,48572L,48573L,48574L, +48575L,48576L,48577L,48578L,48579L,48580L,48581L,48582L,48583L,48584L, +48585L,48586L,48587L,48588L,48589L,48590L,48591L,48592L,48593L,48594L, +48595L,48596L,48597L,48598L,48599L,48600L,48601L,48602L,48603L,48604L, +48605L,48606L,48607L,48608L,48609L,48610L,48611L,48612L,48613L,48614L, +48615L,48616L,48617L,48618L,48619L,48620L,48621L,48622L,48623L,48624L, +48625L,48626L,48627L,48628L,48629L,48630L,48631L,48632L,48633L,48634L, +48635L,48636L,48637L,48638L,48639L,48640L,48641L,48642L,48643L,48644L, +48645L,48646L,48647L,48648L,48649L,48650L,48651L,48652L,48653L,48654L, +48655L,48656L,48657L,48658L,48659L,48660L,48661L,48662L,48663L,48664L, +48665L,48666L,48667L,48668L,48669L,48670L,48671L,48672L,48673L,48674L, +48675L,48676L,48677L,48678L,48679L,48680L,48681L,48682L,48683L,48684L, +48685L,48686L,48687L,48688L,48689L,48690L,48691L,48692L,48693L,48694L, +48695L,48696L,48697L,48698L,48699L,48700L,48701L,48702L,48703L,48704L, +48705L,48706L,48707L,48708L,48709L,48710L,48711L,48712L,48713L,48714L, +48715L,48716L,48717L,48718L,48719L,48720L,48721L,48722L,48723L,48724L, +48725L,48726L,48727L,48728L,48729L,48730L,48731L,48732L,48733L,48734L, +48735L,48736L,48737L,48738L,48739L,48740L,48741L,48742L,48743L,48744L, +48745L,48746L,48747L,48748L,48749L,48750L,48751L,48752L,48753L,48754L, +48755L,48756L,48757L,48758L,48759L,48760L,48761L,48762L,48763L,48764L, +48765L,48766L,48767L,48768L,48769L,48770L,48771L,48772L,48773L,48774L, +48775L,48776L,48777L,48778L,48779L,48780L,48781L,48782L,48783L,48784L, +48785L,48786L,48787L,48788L,48789L,48790L,48791L,48792L,48793L,48794L, +48795L,48796L,48797L,48798L,48799L,48800L,48801L,48802L,48803L,48804L, +48805L,48806L,48807L,48808L,48809L,48810L,48811L,48812L,48813L,48814L, +48815L,48816L,48817L,48818L,48819L,48820L,48821L,48822L,48823L,48824L, +48825L,48826L,48827L,48828L,48829L,48830L,48831L,48832L,48833L,48834L, +48835L,48836L,48837L,48838L,48839L,48840L,48841L,48842L,48843L,48844L, +48845L,48846L,48847L,48848L,48849L,48850L,48851L,48852L,48853L,48854L, +48855L,48856L,48857L,48858L,48859L,48860L,48861L,48862L,48863L,48864L, +48865L,48866L,48867L,48868L,48869L,48870L,48871L,48872L,48873L,48874L, +48875L,48876L,48877L,48878L,48879L,48880L,48881L,48882L,48883L,48884L, +48885L,48886L,48887L,48888L,48889L,48890L,48891L,48892L,48893L,48894L, +48895L,48896L,48897L,48898L,48899L,48900L,48901L,48902L,48903L,48904L, +48905L,48906L,48907L,48908L,48909L,48910L,48911L,48912L,48913L,48914L, +48915L,48916L,48917L,48918L,48919L,48920L,48921L,48922L,48923L,48924L, +48925L,48926L,48927L,48928L,48929L,48930L,48931L,48932L,48933L,48934L, +48935L,48936L,48937L,48938L,48939L,48940L,48941L,48942L,48943L,48944L, +48945L,48946L,48947L,48948L,48949L,48950L,48951L,48952L,48953L,48954L, +48955L,48956L,48957L,48958L,48959L,48960L,48961L,48962L,48963L,48964L, +48965L,48966L,48967L,48968L,48969L,48970L,48971L,48972L,48973L,48974L, +48975L,48976L,48977L,48978L,48979L,48980L,48981L,48982L,48983L,48984L, +48985L,48986L,48987L,48988L,48989L,48990L,48991L,48992L,48993L,48994L, +48995L,48996L,48997L,48998L,48999L,49000L,49001L,49002L,49003L,49004L, +49005L,49006L,49007L,49008L,49009L,49010L,49011L,49012L,49013L,49014L, +49015L,49016L,49017L,49018L,49019L,49020L,49021L,49022L,49023L,49024L, +49025L,49026L,49027L,49028L,49029L,49030L,49031L,49032L,49033L,49034L, +49035L,49036L,49037L,49038L,49039L,49040L,49041L,49042L,49043L,49044L, +49045L,49046L,49047L,49048L,49049L,49050L,49051L,49052L,49053L,49054L, +49055L,49056L,49057L,49058L,49059L,49060L,49061L,49062L,49063L,49064L, +49065L,49066L,49067L,49068L,49069L,49070L,49071L,49072L,49073L,49074L, +49075L,49076L,49077L,49078L,49079L,49080L,49081L,49082L,49083L,49084L, +49085L,49086L,49087L,49088L,49089L,49090L,49091L,49092L,49093L,49094L, +49095L,49096L,49097L,49098L,49099L,49100L,49101L,49102L,49103L,49104L, +49105L,49106L,49107L,49108L,49109L,49110L,49111L,49112L,49113L,49114L, +49115L,49116L,49117L,49118L,49119L,49120L,49121L,49122L,49123L,49124L, +49125L,49126L,49127L,49128L,49129L,49130L,49131L,49132L,49133L,49134L, +49135L,49136L,49137L,49138L,49139L,49140L,49141L,49142L,49143L,49144L, +49145L,49146L,49147L,49148L,49149L,49150L,49151L,49152L,49153L,49154L, +49155L,49156L,49157L,49158L,49159L,49160L,49161L,49162L,49163L,49164L, +49165L,49166L,49167L,49168L,49169L,49170L,49171L,49172L,49173L,49174L, +49175L,49176L,49177L,49178L,49179L,49180L,49181L,49182L,49183L,49184L, +49185L,49186L,49187L,49188L,49189L,49190L,49191L,49192L,49193L,49194L, +49195L,49196L,49197L,49198L,49199L,49200L,49201L,49202L,49203L,49204L, +49205L,49206L,49207L,49208L,49209L,49210L,49211L,49212L,49213L,49214L, +49215L,49216L,49217L,49218L,49219L,49220L,49221L,49222L,49223L,49224L, +49225L,49226L,49227L,49228L,49229L,49230L,49231L,49232L,49233L,49234L, +49235L,49236L,49237L,49238L,49239L,49240L,49241L,49242L,49243L,49244L, +49245L,49246L,49247L,49248L,49249L,49250L,49251L,49252L,49253L,49254L, +49255L,49256L,49257L,49258L,49259L,49260L,49261L,49262L,49263L,49264L, +49265L,49266L,49267L,49268L,49269L,49270L,49271L,49272L,49273L,49274L, +49275L,49276L,49277L,49278L,49279L,49280L,49281L,49282L,49283L,49284L, +49285L,49286L,49287L,49288L,49289L,49290L,49291L,49292L,49293L,49294L, +49295L,49296L,49297L,49298L,49299L,49300L,49301L,49302L,49303L,49304L, +49305L,49306L,49307L,49308L,49309L,49310L,49311L,49312L,49313L,49314L, +49315L,49316L,49317L,49318L,49319L,49320L,49321L,49322L,49323L,49324L, +49325L,49326L,49327L,49328L,49329L,49330L,49331L,49332L,49333L,49334L, +49335L,49336L,49337L,49338L,49339L,49340L,49341L,49342L,49343L,49344L, +49345L,49346L,49347L,49348L,49349L,49350L,49351L,49352L,49353L,49354L, +49355L,49356L,49357L,49358L,49359L,49360L,49361L,49362L,49363L,49364L, +49365L,49366L,49367L,49368L,49369L,49370L,49371L,49372L,49373L,49374L, +49375L,49376L,49377L,49378L,49379L,49380L,49381L,49382L,49383L,49384L, +49385L,49386L,49387L,49388L,49389L,49390L,49391L,49392L,49393L,49394L, +49395L,49396L,49397L,49398L,49399L,49400L,49401L,49402L,49403L,49404L, +49405L,49406L,49407L,49408L,49409L,49410L,49411L,49412L,49413L,49414L, +49415L,49416L,49417L,49418L,49419L,49420L,49421L,49422L,49423L,49424L, +49425L,49426L,49427L,49428L,49429L,49430L,49431L,49432L,49433L,49434L, +49435L,49436L,49437L,49438L,49439L,49440L,49441L,49442L,49443L,49444L, +49445L,49446L,49447L,49448L,49449L,49450L,49451L,49452L,49453L,49454L, +49455L,49456L,49457L,49458L,49459L,49460L,49461L,49462L,49463L,49464L, +49465L,49466L,49467L,49468L,49469L,49470L,49471L,49472L,49473L,49474L, +49475L,49476L,49477L,49478L,49479L,49480L,49481L,49482L,49483L,49484L, +49485L,49486L,49487L,49488L,49489L,49490L,49491L,49492L,49493L,49494L, +49495L,49496L,49497L,49498L,49499L,49500L,49501L,49502L,49503L,49504L, +49505L,49506L,49507L,49508L,49509L,49510L,49511L,49512L,49513L,49514L, +49515L,49516L,49517L,49518L,49519L,49520L,49521L,49522L,49523L,49524L, +49525L,49526L,49527L,49528L,49529L,49530L,49531L,49532L,49533L,49534L, +49535L,49536L,49537L,49538L,49539L,49540L,49541L,49542L,49543L,49544L, +49545L,49546L,49547L,49548L,49549L,49550L,49551L,49552L,49553L,49554L, +49555L,49556L,49557L,49558L,49559L,49560L,49561L,49562L,49563L,49564L, +49565L,49566L,49567L,49568L,49569L,49570L,49571L,49572L,49573L,49574L, +49575L,49576L,49577L,49578L,49579L,49580L,49581L,49582L,49583L,49584L, +49585L,49586L,49587L,49588L,49589L,49590L,49591L,49592L,49593L,49594L, +49595L,49596L,49597L,49598L,49599L,49600L,49601L,49602L,49603L,49604L, +49605L,49606L,49607L,49608L,49609L,49610L,49611L,49612L,49613L,49614L, +49615L,49616L,49617L,49618L,49619L,49620L,49621L,49622L,49623L,49624L, +49625L,49626L,49627L,49628L,49629L,49630L,49631L,49632L,49633L,49634L, +49635L,49636L,49637L,49638L,49639L,49640L,49641L,49642L,49643L,49644L, +49645L,49646L,49647L,49648L,49649L,49650L,49651L,49652L,49653L,49654L, +49655L,49656L,49657L,49658L,49659L,49660L,49661L,49662L,49663L,49664L, +49665L,49666L,49667L,49668L,49669L,49670L,49671L,49672L,49673L,49674L, +49675L,49676L,49677L,49678L,49679L,49680L,49681L,49682L,49683L,49684L, +49685L,49686L,49687L,49688L,49689L,49690L,49691L,49692L,49693L,49694L, +49695L,49696L,49697L,49698L,49699L,49700L,49701L,49702L,49703L,49704L, +49705L,49706L,49707L,49708L,49709L,49710L,49711L,49712L,49713L,49714L, +49715L,49716L,49717L,49718L,49719L,49720L,49721L,49722L,49723L,49724L, +49725L,49726L,49727L,49728L,49729L,49730L,49731L,49732L,49733L,49734L, +49735L,49736L,49737L,49738L,49739L,49740L,49741L,49742L,49743L,49744L, +49745L,49746L,49747L,49748L,49749L,49750L,49751L,49752L,49753L,49754L, +49755L,49756L,49757L,49758L,49759L,49760L,49761L,49762L,49763L,49764L, +49765L,49766L,49767L,49768L,49769L,49770L,49771L,49772L,49773L,49774L, +49775L,49776L,49777L,49778L,49779L,49780L,49781L,49782L,49783L,49784L, +49785L,49786L,49787L,49788L,49789L,49790L,49791L,49792L,49793L,49794L, +49795L,49796L,49797L,49798L,49799L,49800L,49801L,49802L,49803L,49804L, +49805L,49806L,49807L,49808L,49809L,49810L,49811L,49812L,49813L,49814L, +49815L,49816L,49817L,49818L,49819L,49820L,49821L,49822L,49823L,49824L, +49825L,49826L,49827L,49828L,49829L,49830L,49831L,49832L,49833L,49834L, +49835L,49836L,49837L,49838L,49839L,49840L,49841L,49842L,49843L,49844L, +49845L,49846L,49847L,49848L,49849L,49850L,49851L,49852L,49853L,49854L, +49855L,49856L,49857L,49858L,49859L,49860L,49861L,49862L,49863L,49864L, +49865L,49866L,49867L,49868L,49869L,49870L,49871L,49872L,49873L,49874L, +49875L,49876L,49877L,49878L,49879L,49880L,49881L,49882L,49883L,49884L, +49885L,49886L,49887L,49888L,49889L,49890L,49891L,49892L,49893L,49894L, +49895L,49896L,49897L,49898L,49899L,49900L,49901L,49902L,49903L,49904L, +49905L,49906L,49907L,49908L,49909L,49910L,49911L,49912L,49913L,49914L, +49915L,49916L,49917L,49918L,49919L,49920L,49921L,49922L,49923L,49924L, +49925L,49926L,49927L,49928L,49929L,49930L,49931L,49932L,49933L,49934L, +49935L,49936L,49937L,49938L,49939L,49940L,49941L,49942L,49943L,49944L, +49945L,49946L,49947L,49948L,49949L,49950L,49951L,49952L,49953L,49954L, +49955L,49956L,49957L,49958L,49959L,49960L,49961L,49962L,49963L,49964L, +49965L,49966L,49967L,49968L,49969L,49970L,49971L,49972L,49973L,49974L, +49975L,49976L,49977L,49978L,49979L,49980L,49981L,49982L,49983L,49984L, +49985L,49986L,49987L,49988L,49989L,49990L,49991L,49992L,49993L,49994L, +49995L,49996L,49997L,49998L,49999L,50000L,50001L,50002L,50003L,50004L, +50005L,50006L,50007L,50008L,50009L,50010L,50011L,50012L,50013L,50014L, +50015L,50016L,50017L,50018L,50019L,50020L,50021L,50022L,50023L,50024L, +50025L,50026L,50027L,50028L,50029L,50030L,50031L,50032L,50033L,50034L, +50035L,50036L,50037L,50038L,50039L,50040L,50041L,50042L,50043L,50044L, +50045L,50046L,50047L,50048L,50049L,50050L,50051L,50052L,50053L,50054L, +50055L,50056L,50057L,50058L,50059L,50060L,50061L,50062L,50063L,50064L, +50065L,50066L,50067L,50068L,50069L,50070L,50071L,50072L,50073L,50074L, +50075L,50076L,50077L,50078L,50079L,50080L,50081L,50082L,50083L,50084L, +50085L,50086L,50087L,50088L,50089L,50090L,50091L,50092L,50093L,50094L, +50095L,50096L,50097L,50098L,50099L,50100L,50101L,50102L,50103L,50104L, +50105L,50106L,50107L,50108L,50109L,50110L,50111L,50112L,50113L,50114L, +50115L,50116L,50117L,50118L,50119L,50120L,50121L,50122L,50123L,50124L, +50125L,50126L,50127L,50128L,50129L,50130L,50131L,50132L,50133L,50134L, +50135L,50136L,50137L,50138L,50139L,50140L,50141L,50142L,50143L,50144L, +50145L,50146L,50147L,50148L,50149L,50150L,50151L,50152L,50153L,50154L, +50155L,50156L,50157L,50158L,50159L,50160L,50161L,50162L,50163L,50164L, +50165L,50166L,50167L,50168L,50169L,50170L,50171L,50172L,50173L,50174L, +50175L,50176L,50177L,50178L,50179L,50180L,50181L,50182L,50183L,50184L, +50185L,50186L,50187L,50188L,50189L,50190L,50191L,50192L,50193L,50194L, +50195L,50196L,50197L,50198L,50199L,50200L,50201L,50202L,50203L,50204L, +50205L,50206L,50207L,50208L,50209L,50210L,50211L,50212L,50213L,50214L, +50215L,50216L,50217L,50218L,50219L,50220L,50221L,50222L,50223L,50224L, +50225L,50226L,50227L,50228L,50229L,50230L,50231L,50232L,50233L,50234L, +50235L,50236L,50237L,50238L,50239L,50240L,50241L,50242L,50243L,50244L, +50245L,50246L,50247L,50248L,50249L,50250L,50251L,50252L,50253L,50254L, +50255L,50256L,50257L,50258L,50259L,50260L,50261L,50262L,50263L,50264L, +50265L,50266L,50267L,50268L,50269L,50270L,50271L,50272L,50273L,50274L, +50275L,50276L,50277L,50278L,50279L,50280L,50281L,50282L,50283L,50284L, +50285L,50286L,50287L,50288L,50289L,50290L,50291L,50292L,50293L,50294L, +50295L,50296L,50297L,50298L,50299L,50300L,50301L,50302L,50303L,50304L, +50305L,50306L,50307L,50308L,50309L,50310L,50311L,50312L,50313L,50314L, +50315L,50316L,50317L,50318L,50319L,50320L,50321L,50322L,50323L,50324L, +50325L,50326L,50327L,50328L,50329L,50330L,50331L,50332L,50333L,50334L, +50335L,50336L,50337L,50338L,50339L,50340L,50341L,50342L,50343L,50344L, +50345L,50346L,50347L,50348L,50349L,50350L,50351L,50352L,50353L,50354L, +50355L,50356L,50357L,50358L,50359L,50360L,50361L,50362L,50363L,50364L, +50365L,50366L,50367L,50368L,50369L,50370L,50371L,50372L,50373L,50374L, +50375L,50376L,50377L,50378L,50379L,50380L,50381L,50382L,50383L,50384L, +50385L,50386L,50387L,50388L,50389L,50390L,50391L,50392L,50393L,50394L, +50395L,50396L,50397L,50398L,50399L,50400L,50401L,50402L,50403L,50404L, +50405L,50406L,50407L,50408L,50409L,50410L,50411L,50412L,50413L,50414L, +50415L,50416L,50417L,50418L,50419L,50420L,50421L,50422L,50423L,50424L, +50425L,50426L,50427L,50428L,50429L,50430L,50431L,50432L,50433L,50434L, +50435L,50436L,50437L,50438L,50439L,50440L,50441L,50442L,50443L,50444L, +50445L,50446L,50447L,50448L,50449L,50450L,50451L,50452L,50453L,50454L, +50455L,50456L,50457L,50458L,50459L,50460L,50461L,50462L,50463L,50464L, +50465L,50466L,50467L,50468L,50469L,50470L,50471L,50472L,50473L,50474L, +50475L,50476L,50477L,50478L,50479L,50480L,50481L,50482L,50483L,50484L, +50485L,50486L,50487L,50488L,50489L,50490L,50491L,50492L,50493L,50494L, +50495L,50496L,50497L,50498L,50499L,50500L,50501L,50502L,50503L,50504L, +50505L,50506L,50507L,50508L,50509L,50510L,50511L,50512L,50513L,50514L, +50515L,50516L,50517L,50518L,50519L,50520L,50521L,50522L,50523L,50524L, +50525L,50526L,50527L,50528L,50529L,50530L,50531L,50532L,50533L,50534L, +50535L,50536L,50537L,50538L,50539L,50540L,50541L,50542L,50543L,50544L, +50545L,50546L,50547L,50548L,50549L,50550L,50551L,50552L,50553L,50554L, +50555L,50556L,50557L,50558L,50559L,50560L,50561L,50562L,50563L,50564L, +50565L,50566L,50567L,50568L,50569L,50570L,50571L,50572L,50573L,50574L, +50575L,50576L,50577L,50578L,50579L,50580L,50581L,50582L,50583L,50584L, +50585L,50586L,50587L,50588L,50589L,50590L,50591L,50592L,50593L,50594L, +50595L,50596L,50597L,50598L,50599L,50600L,50601L,50602L,50603L,50604L, +50605L,50606L,50607L,50608L,50609L,50610L,50611L,50612L,50613L,50614L, +50615L,50616L,50617L,50618L,50619L,50620L,50621L,50622L,50623L,50624L, +50625L,50626L,50627L,50628L,50629L,50630L,50631L,50632L,50633L,50634L, +50635L,50636L,50637L,50638L,50639L,50640L,50641L,50642L,50643L,50644L, +50645L,50646L,50647L,50648L,50649L,50650L,50651L,50652L,50653L,50654L, +50655L,50656L,50657L,50658L,50659L,50660L,50661L,50662L,50663L,50664L, +50665L,50666L,50667L,50668L,50669L,50670L,50671L,50672L,50673L,50674L, +50675L,50676L,50677L,50678L,50679L,50680L,50681L,50682L,50683L,50684L, +50685L,50686L,50687L,50688L,50689L,50690L,50691L,50692L,50693L,50694L, +50695L,50696L,50697L,50698L,50699L,50700L,50701L,50702L,50703L,50704L, +50705L,50706L,50707L,50708L,50709L,50710L,50711L,50712L,50713L,50714L, +50715L,50716L,50717L,50718L,50719L,50720L,50721L,50722L,50723L,50724L, +50725L,50726L,50727L,50728L,50729L,50730L,50731L,50732L,50733L,50734L, +50735L,50736L,50737L,50738L,50739L,50740L,50741L,50742L,50743L,50744L, +50745L,50746L,50747L,50748L,50749L,50750L,50751L,50752L,50753L,50754L, +50755L,50756L,50757L,50758L,50759L,50760L,50761L,50762L,50763L,50764L, +50765L,50766L,50767L,50768L,50769L,50770L,50771L,50772L,50773L,50774L, +50775L,50776L,50777L,50778L,50779L,50780L,50781L,50782L,50783L,50784L, +50785L,50786L,50787L,50788L,50789L,50790L,50791L,50792L,50793L,50794L, +50795L,50796L,50797L,50798L,50799L,50800L,50801L,50802L,50803L,50804L, +50805L,50806L,50807L,50808L,50809L,50810L,50811L,50812L,50813L,50814L, +50815L,50816L,50817L,50818L,50819L,50820L,50821L,50822L,50823L,50824L, +50825L,50826L,50827L,50828L,50829L,50830L,50831L,50832L,50833L,50834L, +50835L,50836L,50837L,50838L,50839L,50840L,50841L,50842L,50843L,50844L, +50845L,50846L,50847L,50848L,50849L,50850L,50851L,50852L,50853L,50854L, +50855L,50856L,50857L,50858L,50859L,50860L,50861L,50862L,50863L,50864L, +50865L,50866L,50867L,50868L,50869L,50870L,50871L,50872L,50873L,50874L, +50875L,50876L,50877L,50878L,50879L,50880L,50881L,50882L,50883L,50884L, +50885L,50886L,50887L,50888L,50889L,50890L,50891L,50892L,50893L,50894L, +50895L,50896L,50897L,50898L,50899L,50900L,50901L,50902L,50903L,50904L, +50905L,50906L,50907L,50908L,50909L,50910L,50911L,50912L,50913L,50914L, +50915L,50916L,50917L,50918L,50919L,50920L,50921L,50922L,50923L,50924L, +50925L,50926L,50927L,50928L,50929L,50930L,50931L,50932L,50933L,50934L, +50935L,50936L,50937L,50938L,50939L,50940L,50941L,50942L,50943L,50944L, +50945L,50946L,50947L,50948L,50949L,50950L,50951L,50952L,50953L,50954L, +50955L,50956L,50957L,50958L,50959L,50960L,50961L,50962L,50963L,50964L, +50965L,50966L,50967L,50968L,50969L,50970L,50971L,50972L,50973L,50974L, +50975L,50976L,50977L,50978L,50979L,50980L,50981L,50982L,50983L,50984L, +50985L,50986L,50987L,50988L,50989L,50990L,50991L,50992L,50993L,50994L, +50995L,50996L,50997L,50998L,50999L,51000L,51001L,51002L,51003L,51004L, +51005L,51006L,51007L,51008L,51009L,51010L,51011L,51012L,51013L,51014L, +51015L,51016L,51017L,51018L,51019L,51020L,51021L,51022L,51023L,51024L, +51025L,51026L,51027L,51028L,51029L,51030L,51031L,51032L,51033L,51034L, +51035L,51036L,51037L,51038L,51039L,51040L,51041L,51042L,51043L,51044L, +51045L,51046L,51047L,51048L,51049L,51050L,51051L,51052L,51053L,51054L, +51055L,51056L,51057L,51058L,51059L,51060L,51061L,51062L,51063L,51064L, +51065L,51066L,51067L,51068L,51069L,51070L,51071L,51072L,51073L,51074L, +51075L,51076L,51077L,51078L,51079L,51080L,51081L,51082L,51083L,51084L, +51085L,51086L,51087L,51088L,51089L,51090L,51091L,51092L,51093L,51094L, +51095L,51096L,51097L,51098L,51099L,51100L,51101L,51102L,51103L,51104L, +51105L,51106L,51107L,51108L,51109L,51110L,51111L,51112L,51113L,51114L, +51115L,51116L,51117L,51118L,51119L,51120L,51121L,51122L,51123L,51124L, +51125L,51126L,51127L,51128L,51129L,51130L,51131L,51132L,51133L,51134L, +51135L,51136L,51137L,51138L,51139L,51140L,51141L,51142L,51143L,51144L, +51145L,51146L,51147L,51148L,51149L,51150L,51151L,51152L,51153L,51154L, +51155L,51156L,51157L,51158L,51159L,51160L,51161L,51162L,51163L,51164L, +51165L,51166L,51167L,51168L,51169L,51170L,51171L,51172L,51173L,51174L, +51175L,51176L,51177L,51178L,51179L,51180L,51181L,51182L,51183L,51184L, +51185L,51186L,51187L,51188L,51189L,51190L,51191L,51192L,51193L,51194L, +51195L,51196L,51197L,51198L,51199L,51200L,51201L,51202L,51203L,51204L, +51205L,51206L,51207L,51208L,51209L,51210L,51211L,51212L,51213L,51214L, +51215L,51216L,51217L,51218L,51219L,51220L,51221L,51222L,51223L,51224L, +51225L,51226L,51227L,51228L,51229L,51230L,51231L,51232L,51233L,51234L, +51235L,51236L,51237L,51238L,51239L,51240L,51241L,51242L,51243L,51244L, +51245L,51246L,51247L,51248L,51249L,51250L,51251L,51252L,51253L,51254L, +51255L,51256L,51257L,51258L,51259L,51260L,51261L,51262L,51263L,51264L, +51265L,51266L,51267L,51268L,51269L,51270L,51271L,51272L,51273L,51274L, +51275L,51276L,51277L,51278L,51279L,51280L,51281L,51282L,51283L,51284L, +51285L,51286L,51287L,51288L,51289L,51290L,51291L,51292L,51293L,51294L, +51295L,51296L,51297L,51298L,51299L,51300L,51301L,51302L,51303L,51304L, +51305L,51306L,51307L,51308L,51309L,51310L,51311L,51312L,51313L,51314L, +51315L,51316L,51317L,51318L,51319L,51320L,51321L,51322L,51323L,51324L, +51325L,51326L,51327L,51328L,51329L,51330L,51331L,51332L,51333L,51334L, +51335L,51336L,51337L,51338L,51339L,51340L,51341L,51342L,51343L,51344L, +51345L,51346L,51347L,51348L,51349L,51350L,51351L,51352L,51353L,51354L, +51355L,51356L,51357L,51358L,51359L,51360L,51361L,51362L,51363L,51364L, +51365L,51366L,51367L,51368L,51369L,51370L,51371L,51372L,51373L,51374L, +51375L,51376L,51377L,51378L,51379L,51380L,51381L,51382L,51383L,51384L, +51385L,51386L,51387L,51388L,51389L,51390L,51391L,51392L,51393L,51394L, +51395L,51396L,51397L,51398L,51399L,51400L,51401L,51402L,51403L,51404L, +51405L,51406L,51407L,51408L,51409L,51410L,51411L,51412L,51413L,51414L, +51415L,51416L,51417L,51418L,51419L,51420L,51421L,51422L,51423L,51424L, +51425L,51426L,51427L,51428L,51429L,51430L,51431L,51432L,51433L,51434L, +51435L,51436L,51437L,51438L,51439L,51440L,51441L,51442L,51443L,51444L, +51445L,51446L,51447L,51448L,51449L,51450L,51451L,51452L,51453L,51454L, +51455L,51456L,51457L,51458L,51459L,51460L,51461L,51462L,51463L,51464L, +51465L,51466L,51467L,51468L,51469L,51470L,51471L,51472L,51473L,51474L, +51475L,51476L,51477L,51478L,51479L,51480L,51481L,51482L,51483L,51484L, +51485L,51486L,51487L,51488L,51489L,51490L,51491L,51492L,51493L,51494L, +51495L,51496L,51497L,51498L,51499L,51500L,51501L,51502L,51503L,51504L, +51505L,51506L,51507L,51508L,51509L,51510L,51511L,51512L,51513L,51514L, +51515L,51516L,51517L,51518L,51519L,51520L,51521L,51522L,51523L,51524L, +51525L,51526L,51527L,51528L,51529L,51530L,51531L,51532L,51533L,51534L, +51535L,51536L,51537L,51538L,51539L,51540L,51541L,51542L,51543L,51544L, +51545L,51546L,51547L,51548L,51549L,51550L,51551L,51552L,51553L,51554L, +51555L,51556L,51557L,51558L,51559L,51560L,51561L,51562L,51563L,51564L, +51565L,51566L,51567L,51568L,51569L,51570L,51571L,51572L,51573L,51574L, +51575L,51576L,51577L,51578L,51579L,51580L,51581L,51582L,51583L,51584L, +51585L,51586L,51587L,51588L,51589L,51590L,51591L,51592L,51593L,51594L, +51595L,51596L,51597L,51598L,51599L,51600L,51601L,51602L,51603L,51604L, +51605L,51606L,51607L,51608L,51609L,51610L,51611L,51612L,51613L,51614L, +51615L,51616L,51617L,51618L,51619L,51620L,51621L,51622L,51623L,51624L, +51625L,51626L,51627L,51628L,51629L,51630L,51631L,51632L,51633L,51634L, +51635L,51636L,51637L,51638L,51639L,51640L,51641L,51642L,51643L,51644L, +51645L,51646L,51647L,51648L,51649L,51650L,51651L,51652L,51653L,51654L, +51655L,51656L,51657L,51658L,51659L,51660L,51661L,51662L,51663L,51664L, +51665L,51666L,51667L,51668L,51669L,51670L,51671L,51672L,51673L,51674L, +51675L,51676L,51677L,51678L,51679L,51680L,51681L,51682L,51683L,51684L, +51685L,51686L,51687L,51688L,51689L,51690L,51691L,51692L,51693L,51694L, +51695L,51696L,51697L,51698L,51699L,51700L,51701L,51702L,51703L,51704L, +51705L,51706L,51707L,51708L,51709L,51710L,51711L,51712L,51713L,51714L, +51715L,51716L,51717L,51718L,51719L,51720L,51721L,51722L,51723L,51724L, +51725L,51726L,51727L,51728L,51729L,51730L,51731L,51732L,51733L,51734L, +51735L,51736L,51737L,51738L,51739L,51740L,51741L,51742L,51743L,51744L, +51745L,51746L,51747L,51748L,51749L,51750L,51751L,51752L,51753L,51754L, +51755L,51756L,51757L,51758L,51759L,51760L,51761L,51762L,51763L,51764L, +51765L,51766L,51767L,51768L,51769L,51770L,51771L,51772L,51773L,51774L, +51775L,51776L,51777L,51778L,51779L,51780L,51781L,51782L,51783L,51784L, +51785L,51786L,51787L,51788L,51789L,51790L,51791L,51792L,51793L,51794L, +51795L,51796L,51797L,51798L,51799L,51800L,51801L,51802L,51803L,51804L, +51805L,51806L,51807L,51808L,51809L,51810L,51811L,51812L,51813L,51814L, +51815L,51816L,51817L,51818L,51819L,51820L,51821L,51822L,51823L,51824L, +51825L,51826L,51827L,51828L,51829L,51830L,51831L,51832L,51833L,51834L, +51835L,51836L,51837L,51838L,51839L,51840L,51841L,51842L,51843L,51844L, +51845L,51846L,51847L,51848L,51849L,51850L,51851L,51852L,51853L,51854L, +51855L,51856L,51857L,51858L,51859L,51860L,51861L,51862L,51863L,51864L, +51865L,51866L,51867L,51868L,51869L,51870L,51871L,51872L,51873L,51874L, +51875L,51876L,51877L,51878L,51879L,51880L,51881L,51882L,51883L,51884L, +51885L,51886L,51887L,51888L,51889L,51890L,51891L,51892L,51893L,51894L, +51895L,51896L,51897L,51898L,51899L,51900L,51901L,51902L,51903L,51904L, +51905L,51906L,51907L,51908L,51909L,51910L,51911L,51912L,51913L,51914L, +51915L,51916L,51917L,51918L,51919L,51920L,51921L,51922L,51923L,51924L, +51925L,51926L,51927L,51928L,51929L,51930L,51931L,51932L,51933L,51934L, +51935L,51936L,51937L,51938L,51939L,51940L,51941L,51942L,51943L,51944L, +51945L,51946L,51947L,51948L,51949L,51950L,51951L,51952L,51953L,51954L, +51955L,51956L,51957L,51958L,51959L,51960L,51961L,51962L,51963L,51964L, +51965L,51966L,51967L,51968L,51969L,51970L,51971L,51972L,51973L,51974L, +51975L,51976L,51977L,51978L,51979L,51980L,51981L,51982L,51983L,51984L, +51985L,51986L,51987L,51988L,51989L,51990L,51991L,51992L,51993L,51994L, +51995L,51996L,51997L,51998L,51999L,52000L,52001L,52002L,52003L,52004L, +52005L,52006L,52007L,52008L,52009L,52010L,52011L,52012L,52013L,52014L, +52015L,52016L,52017L,52018L,52019L,52020L,52021L,52022L,52023L,52024L, +52025L,52026L,52027L,52028L,52029L,52030L,52031L,52032L,52033L,52034L, +52035L,52036L,52037L,52038L,52039L,52040L,52041L,52042L,52043L,52044L, +52045L,52046L,52047L,52048L,52049L,52050L,52051L,52052L,52053L,52054L, +52055L,52056L,52057L,52058L,52059L,52060L,52061L,52062L,52063L,52064L, +52065L,52066L,52067L,52068L,52069L,52070L,52071L,52072L,52073L,52074L, +52075L,52076L,52077L,52078L,52079L,52080L,52081L,52082L,52083L,52084L, +52085L,52086L,52087L,52088L,52089L,52090L,52091L,52092L,52093L,52094L, +52095L,52096L,52097L,52098L,52099L,52100L,52101L,52102L,52103L,52104L, +52105L,52106L,52107L,52108L,52109L,52110L,52111L,52112L,52113L,52114L, +52115L,52116L,52117L,52118L,52119L,52120L,52121L,52122L,52123L,52124L, +52125L,52126L,52127L,52128L,52129L,52130L,52131L,52132L,52133L,52134L, +52135L,52136L,52137L,52138L,52139L,52140L,52141L,52142L,52143L,52144L, +52145L,52146L,52147L,52148L,52149L,52150L,52151L,52152L,52153L,52154L, +52155L,52156L,52157L,52158L,52159L,52160L,52161L,52162L,52163L,52164L, +52165L,52166L,52167L,52168L,52169L,52170L,52171L,52172L,52173L,52174L, +52175L,52176L,52177L,52178L,52179L,52180L,52181L,52182L,52183L,52184L, +52185L,52186L,52187L,52188L,52189L,52190L,52191L,52192L,52193L,52194L, +52195L,52196L,52197L,52198L,52199L,52200L,52201L,52202L,52203L,52204L, +52205L,52206L,52207L,52208L,52209L,52210L,52211L,52212L,52213L,52214L, +52215L,52216L,52217L,52218L,52219L,52220L,52221L,52222L,52223L,52224L, +52225L,52226L,52227L,52228L,52229L,52230L,52231L,52232L,52233L,52234L, +52235L,52236L,52237L,52238L,52239L,52240L,52241L,52242L,52243L,52244L, +52245L,52246L,52247L,52248L,52249L,52250L,52251L,52252L,52253L,52254L, +52255L,52256L,52257L,52258L,52259L,52260L,52261L,52262L,52263L,52264L, +52265L,52266L,52267L,52268L,52269L,52270L,52271L,52272L,52273L,52274L, +52275L,52276L,52277L,52278L,52279L,52280L,52281L,52282L,52283L,52284L, +52285L,52286L,52287L,52288L,52289L,52290L,52291L,52292L,52293L,52294L, +52295L,52296L,52297L,52298L,52299L,52300L,52301L,52302L,52303L,52304L, +52305L,52306L,52307L,52308L,52309L,52310L,52311L,52312L,52313L,52314L, +52315L,52316L,52317L,52318L,52319L,52320L,52321L,52322L,52323L,52324L, +52325L,52326L,52327L,52328L,52329L,52330L,52331L,52332L,52333L,52334L, +52335L,52336L,52337L,52338L,52339L,52340L,52341L,52342L,52343L,52344L, +52345L,52346L,52347L,52348L,52349L,52350L,52351L,52352L,52353L,52354L, +52355L,52356L,52357L,52358L,52359L,52360L,52361L,52362L,52363L,52364L, +52365L,52366L,52367L,52368L,52369L,52370L,52371L,52372L,52373L,52374L, +52375L,52376L,52377L,52378L,52379L,52380L,52381L,52382L,52383L,52384L, +52385L,52386L,52387L,52388L,52389L,52390L,52391L,52392L,52393L,52394L, +52395L,52396L,52397L,52398L,52399L,52400L,52401L,52402L,52403L,52404L, +52405L,52406L,52407L,52408L,52409L,52410L,52411L,52412L,52413L,52414L, +52415L,52416L,52417L,52418L,52419L,52420L,52421L,52422L,52423L,52424L, +52425L,52426L,52427L,52428L,52429L,52430L,52431L,52432L,52433L,52434L, +52435L,52436L,52437L,52438L,52439L,52440L,52441L,52442L,52443L,52444L, +52445L,52446L,52447L,52448L,52449L,52450L,52451L,52452L,52453L,52454L, +52455L,52456L,52457L,52458L,52459L,52460L,52461L,52462L,52463L,52464L, +52465L,52466L,52467L,52468L,52469L,52470L,52471L,52472L,52473L,52474L, +52475L,52476L,52477L,52478L,52479L,52480L,52481L,52482L,52483L,52484L, +52485L,52486L,52487L,52488L,52489L,52490L,52491L,52492L,52493L,52494L, +52495L,52496L,52497L,52498L,52499L,52500L,52501L,52502L,52503L,52504L, +52505L,52506L,52507L,52508L,52509L,52510L,52511L,52512L,52513L,52514L, +52515L,52516L,52517L,52518L,52519L,52520L,52521L,52522L,52523L,52524L, +52525L,52526L,52527L,52528L,52529L,52530L,52531L,52532L,52533L,52534L, +52535L,52536L,52537L,52538L,52539L,52540L,52541L,52542L,52543L,52544L, +52545L,52546L,52547L,52548L,52549L,52550L,52551L,52552L,52553L,52554L, +52555L,52556L,52557L,52558L,52559L,52560L,52561L,52562L,52563L,52564L, +52565L,52566L,52567L,52568L,52569L,52570L,52571L,52572L,52573L,52574L, +52575L,52576L,52577L,52578L,52579L,52580L,52581L,52582L,52583L,52584L, +52585L,52586L,52587L,52588L,52589L,52590L,52591L,52592L,52593L,52594L, +52595L,52596L,52597L,52598L,52599L,52600L,52601L,52602L,52603L,52604L, +52605L,52606L,52607L,52608L,52609L,52610L,52611L,52612L,52613L,52614L, +52615L,52616L,52617L,52618L,52619L,52620L,52621L,52622L,52623L,52624L, +52625L,52626L,52627L,52628L,52629L,52630L,52631L,52632L,52633L,52634L, +52635L,52636L,52637L,52638L,52639L,52640L,52641L,52642L,52643L,52644L, +52645L,52646L,52647L,52648L,52649L,52650L,52651L,52652L,52653L,52654L, +52655L,52656L,52657L,52658L,52659L,52660L,52661L,52662L,52663L,52664L, +52665L,52666L,52667L,52668L,52669L,52670L,52671L,52672L,52673L,52674L, +52675L,52676L,52677L,52678L,52679L,52680L,52681L,52682L,52683L,52684L, +52685L,52686L,52687L,52688L,52689L,52690L,52691L,52692L,52693L,52694L, +52695L,52696L,52697L,52698L,52699L,52700L,52701L,52702L,52703L,52704L, +52705L,52706L,52707L,52708L,52709L,52710L,52711L,52712L,52713L,52714L, +52715L,52716L,52717L,52718L,52719L,52720L,52721L,52722L,52723L,52724L, +52725L,52726L,52727L,52728L,52729L,52730L,52731L,52732L,52733L,52734L, +52735L,52736L,52737L,52738L,52739L,52740L,52741L,52742L,52743L,52744L, +52745L,52746L,52747L,52748L,52749L,52750L,52751L,52752L,52753L,52754L, +52755L,52756L,52757L,52758L,52759L,52760L,52761L,52762L,52763L,52764L, +52765L,52766L,52767L,52768L,52769L,52770L,52771L,52772L,52773L,52774L, +52775L,52776L,52777L,52778L,52779L,52780L,52781L,52782L,52783L,52784L, +52785L,52786L,52787L,52788L,52789L,52790L,52791L,52792L,52793L,52794L, +52795L,52796L,52797L,52798L,52799L,52800L,52801L,52802L,52803L,52804L, +52805L,52806L,52807L,52808L,52809L,52810L,52811L,52812L,52813L,52814L, +52815L,52816L,52817L,52818L,52819L,52820L,52821L,52822L,52823L,52824L, +52825L,52826L,52827L,52828L,52829L,52830L,52831L,52832L,52833L,52834L, +52835L,52836L,52837L,52838L,52839L,52840L,52841L,52842L,52843L,52844L, +52845L,52846L,52847L,52848L,52849L,52850L,52851L,52852L,52853L,52854L, +52855L,52856L,52857L,52858L,52859L,52860L,52861L,52862L,52863L,52864L, +52865L,52866L,52867L,52868L,52869L,52870L,52871L,52872L,52873L,52874L, +52875L,52876L,52877L,52878L,52879L,52880L,52881L,52882L,52883L,52884L, +52885L,52886L,52887L,52888L,52889L,52890L,52891L,52892L,52893L,52894L, +52895L,52896L,52897L,52898L,52899L,52900L,52901L,52902L,52903L,52904L, +52905L,52906L,52907L,52908L,52909L,52910L,52911L,52912L,52913L,52914L, +52915L,52916L,52917L,52918L,52919L,52920L,52921L,52922L,52923L,52924L, +52925L,52926L,52927L,52928L,52929L,52930L,52931L,52932L,52933L,52934L, +52935L,52936L,52937L,52938L,52939L,52940L,52941L,52942L,52943L,52944L, +52945L,52946L,52947L,52948L,52949L,52950L,52951L,52952L,52953L,52954L, +52955L,52956L,52957L,52958L,52959L,52960L,52961L,52962L,52963L,52964L, +52965L,52966L,52967L,52968L,52969L,52970L,52971L,52972L,52973L,52974L, +52975L,52976L,52977L,52978L,52979L,52980L,52981L,52982L,52983L,52984L, +52985L,52986L,52987L,52988L,52989L,52990L,52991L,52992L,52993L,52994L, +52995L,52996L,52997L,52998L,52999L,53000L,53001L,53002L,53003L,53004L, +53005L,53006L,53007L,53008L,53009L,53010L,53011L,53012L,53013L,53014L, +53015L,53016L,53017L,53018L,53019L,53020L,53021L,53022L,53023L,53024L, +53025L,53026L,53027L,53028L,53029L,53030L,53031L,53032L,53033L,53034L, +53035L,53036L,53037L,53038L,53039L,53040L,53041L,53042L,53043L,53044L, +53045L,53046L,53047L,53048L,53049L,53050L,53051L,53052L,53053L,53054L, +53055L,53056L,53057L,53058L,53059L,53060L,53061L,53062L,53063L,53064L, +53065L,53066L,53067L,53068L,53069L,53070L,53071L,53072L,53073L,53074L, +53075L,53076L,53077L,53078L,53079L,53080L,53081L,53082L,53083L,53084L, +53085L,53086L,53087L,53088L,53089L,53090L,53091L,53092L,53093L,53094L, +53095L,53096L,53097L,53098L,53099L,53100L,53101L,53102L,53103L,53104L, +53105L,53106L,53107L,53108L,53109L,53110L,53111L,53112L,53113L,53114L, +53115L,53116L,53117L,53118L,53119L,53120L,53121L,53122L,53123L,53124L, +53125L,53126L,53127L,53128L,53129L,53130L,53131L,53132L,53133L,53134L, +53135L,53136L,53137L,53138L,53139L,53140L,53141L,53142L,53143L,53144L, +53145L,53146L,53147L,53148L,53149L,53150L,53151L,53152L,53153L,53154L, +53155L,53156L,53157L,53158L,53159L,53160L,53161L,53162L,53163L,53164L, +53165L,53166L,53167L,53168L,53169L,53170L,53171L,53172L,53173L,53174L, +53175L,53176L,53177L,53178L,53179L,53180L,53181L,53182L,53183L,53184L, +53185L,53186L,53187L,53188L,53189L,53190L,53191L,53192L,53193L,53194L, +53195L,53196L,53197L,53198L,53199L,53200L,53201L,53202L,53203L,53204L, +53205L,53206L,53207L,53208L,53209L,53210L,53211L,53212L,53213L,53214L, +53215L,53216L,53217L,53218L,53219L,53220L,53221L,53222L,53223L,53224L, +53225L,53226L,53227L,53228L,53229L,53230L,53231L,53232L,53233L,53234L, +53235L,53236L,53237L,53238L,53239L,53240L,53241L,53242L,53243L,53244L, +53245L,53246L,53247L,53248L,53249L,53250L,53251L,53252L,53253L,53254L, +53255L,53256L,53257L,53258L,53259L,53260L,53261L,53262L,53263L,53264L, +53265L,53266L,53267L,53268L,53269L,53270L,53271L,53272L,53273L,53274L, +53275L,53276L,53277L,53278L,53279L,53280L,53281L,53282L,53283L,53284L, +53285L,53286L,53287L,53288L,53289L,53290L,53291L,53292L,53293L,53294L, +53295L,53296L,53297L,53298L,53299L,53300L,53301L,53302L,53303L,53304L, +53305L,53306L,53307L,53308L,53309L,53310L,53311L,53312L,53313L,53314L, +53315L,53316L,53317L,53318L,53319L,53320L,53321L,53322L,53323L,53324L, +53325L,53326L,53327L,53328L,53329L,53330L,53331L,53332L,53333L,53334L, +53335L,53336L,53337L,53338L,53339L,53340L,53341L,53342L,53343L,53344L, +53345L,53346L,53347L,53348L,53349L,53350L,53351L,53352L,53353L,53354L, +53355L,53356L,53357L,53358L,53359L,53360L,53361L,53362L,53363L,53364L, +53365L,53366L,53367L,53368L,53369L,53370L,53371L,53372L,53373L,53374L, +53375L,53376L,53377L,53378L,53379L,53380L,53381L,53382L,53383L,53384L, +53385L,53386L,53387L,53388L,53389L,53390L,53391L,53392L,53393L,53394L, +53395L,53396L,53397L,53398L,53399L,53400L,53401L,53402L,53403L,53404L, +53405L,53406L,53407L,53408L,53409L,53410L,53411L,53412L,53413L,53414L, +53415L,53416L,53417L,53418L,53419L,53420L,53421L,53422L,53423L,53424L, +53425L,53426L,53427L,53428L,53429L,53430L,53431L,53432L,53433L,53434L, +53435L,53436L,53437L,53438L,53439L,53440L,53441L,53442L,53443L,53444L, +53445L,53446L,53447L,53448L,53449L,53450L,53451L,53452L,53453L,53454L, +53455L,53456L,53457L,53458L,53459L,53460L,53461L,53462L,53463L,53464L, +53465L,53466L,53467L,53468L,53469L,53470L,53471L,53472L,53473L,53474L, +53475L,53476L,53477L,53478L,53479L,53480L,53481L,53482L,53483L,53484L, +53485L,53486L,53487L,53488L,53489L,53490L,53491L,53492L,53493L,53494L, +53495L,53496L,53497L,53498L,53499L,53500L,53501L,53502L,53503L,53504L, +53505L,53506L,53507L,53508L,53509L,53510L,53511L,53512L,53513L,53514L, +53515L,53516L,53517L,53518L,53519L,53520L,53521L,53522L,53523L,53524L, +53525L,53526L,53527L,53528L,53529L,53530L,53531L,53532L,53533L,53534L, +53535L,53536L,53537L,53538L,53539L,53540L,53541L,53542L,53543L,53544L, +53545L,53546L,53547L,53548L,53549L,53550L,53551L,53552L,53553L,53554L, +53555L,53556L,53557L,53558L,53559L,53560L,53561L,53562L,53563L,53564L, +53565L,53566L,53567L,53568L,53569L,53570L,53571L,53572L,53573L,53574L, +53575L,53576L,53577L,53578L,53579L,53580L,53581L,53582L,53583L,53584L, +53585L,53586L,53587L,53588L,53589L,53590L,53591L,53592L,53593L,53594L, +53595L,53596L,53597L,53598L,53599L,53600L,53601L,53602L,53603L,53604L, +53605L,53606L,53607L,53608L,53609L,53610L,53611L,53612L,53613L,53614L, +53615L,53616L,53617L,53618L,53619L,53620L,53621L,53622L,53623L,53624L, +53625L,53626L,53627L,53628L,53629L,53630L,53631L,53632L,53633L,53634L, +53635L,53636L,53637L,53638L,53639L,53640L,53641L,53642L,53643L,53644L, +53645L,53646L,53647L,53648L,53649L,53650L,53651L,53652L,53653L,53654L, +53655L,53656L,53657L,53658L,53659L,53660L,53661L,53662L,53663L,53664L, +53665L,53666L,53667L,53668L,53669L,53670L,53671L,53672L,53673L,53674L, +53675L,53676L,53677L,53678L,53679L,53680L,53681L,53682L,53683L,53684L, +53685L,53686L,53687L,53688L,53689L,53690L,53691L,53692L,53693L,53694L, +53695L,53696L,53697L,53698L,53699L,53700L,53701L,53702L,53703L,53704L, +53705L,53706L,53707L,53708L,53709L,53710L,53711L,53712L,53713L,53714L, +53715L,53716L,53717L,53718L,53719L,53720L,53721L,53722L,53723L,53724L, +53725L,53726L,53727L,53728L,53729L,53730L,53731L,53732L,53733L,53734L, +53735L,53736L,53737L,53738L,53739L,53740L,53741L,53742L,53743L,53744L, +53745L,53746L,53747L,53748L,53749L,53750L,53751L,53752L,53753L,53754L, +53755L,53756L,53757L,53758L,53759L,53760L,53761L,53762L,53763L,53764L, +53765L,53766L,53767L,53768L,53769L,53770L,53771L,53772L,53773L,53774L, +53775L,53776L,53777L,53778L,53779L,53780L,53781L,53782L,53783L,53784L, +53785L,53786L,53787L,53788L,53789L,53790L,53791L,53792L,53793L,53794L, +53795L,53796L,53797L,53798L,53799L,53800L,53801L,53802L,53803L,53804L, +53805L,53806L,53807L,53808L,53809L,53810L,53811L,53812L,53813L,53814L, +53815L,53816L,53817L,53818L,53819L,53820L,53821L,53822L,53823L,53824L, +53825L,53826L,53827L,53828L,53829L,53830L,53831L,53832L,53833L,53834L, +53835L,53836L,53837L,53838L,53839L,53840L,53841L,53842L,53843L,53844L, +53845L,53846L,53847L,53848L,53849L,53850L,53851L,53852L,53853L,53854L, +53855L,53856L,53857L,53858L,53859L,53860L,53861L,53862L,53863L,53864L, +53865L,53866L,53867L,53868L,53869L,53870L,53871L,53872L,53873L,53874L, +53875L,53876L,53877L,53878L,53879L,53880L,53881L,53882L,53883L,53884L, +53885L,53886L,53887L,53888L,53889L,53890L,53891L,53892L,53893L,53894L, +53895L,53896L,53897L,53898L,53899L,53900L,53901L,53902L,53903L,53904L, +53905L,53906L,53907L,53908L,53909L,53910L,53911L,53912L,53913L,53914L, +53915L,53916L,53917L,53918L,53919L,53920L,53921L,53922L,53923L,53924L, +53925L,53926L,53927L,53928L,53929L,53930L,53931L,53932L,53933L,53934L, +53935L,53936L,53937L,53938L,53939L,53940L,53941L,53942L,53943L,53944L, +53945L,53946L,53947L,53948L,53949L,53950L,53951L,53952L,53953L,53954L, +53955L,53956L,53957L,53958L,53959L,53960L,53961L,53962L,53963L,53964L, +53965L,53966L,53967L,53968L,53969L,53970L,53971L,53972L,53973L,53974L, +53975L,53976L,53977L,53978L,53979L,53980L,53981L,53982L,53983L,53984L, +53985L,53986L,53987L,53988L,53989L,53990L,53991L,53992L,53993L,53994L, +53995L,53996L,53997L,53998L,53999L,54000L,54001L,54002L,54003L,54004L, +54005L,54006L,54007L,54008L,54009L,54010L,54011L,54012L,54013L,54014L, +54015L,54016L,54017L,54018L,54019L,54020L,54021L,54022L,54023L,54024L, +54025L,54026L,54027L,54028L,54029L,54030L,54031L,54032L,54033L,54034L, +54035L,54036L,54037L,54038L,54039L,54040L,54041L,54042L,54043L,54044L, +54045L,54046L,54047L,54048L,54049L,54050L,54051L,54052L,54053L,54054L, +54055L,54056L,54057L,54058L,54059L,54060L,54061L,54062L,54063L,54064L, +54065L,54066L,54067L,54068L,54069L,54070L,54071L,54072L,54073L,54074L, +54075L,54076L,54077L,54078L,54079L,54080L,54081L,54082L,54083L,54084L, +54085L,54086L,54087L,54088L,54089L,54090L,54091L,54092L,54093L,54094L, +54095L,54096L,54097L,54098L,54099L,54100L,54101L,54102L,54103L,54104L, +54105L,54106L,54107L,54108L,54109L,54110L,54111L,54112L,54113L,54114L, +54115L,54116L,54117L,54118L,54119L,54120L,54121L,54122L,54123L,54124L, +54125L,54126L,54127L,54128L,54129L,54130L,54131L,54132L,54133L,54134L, +54135L,54136L,54137L,54138L,54139L,54140L,54141L,54142L,54143L,54144L, +54145L,54146L,54147L,54148L,54149L,54150L,54151L,54152L,54153L,54154L, +54155L,54156L,54157L,54158L,54159L,54160L,54161L,54162L,54163L,54164L, +54165L,54166L,54167L,54168L,54169L,54170L,54171L,54172L,54173L,54174L, +54175L,54176L,54177L,54178L,54179L,54180L,54181L,54182L,54183L,54184L, +54185L,54186L,54187L,54188L,54189L,54190L,54191L,54192L,54193L,54194L, +54195L,54196L,54197L,54198L,54199L,54200L,54201L,54202L,54203L,54204L, +54205L,54206L,54207L,54208L,54209L,54210L,54211L,54212L,54213L,54214L, +54215L,54216L,54217L,54218L,54219L,54220L,54221L,54222L,54223L,54224L, +54225L,54226L,54227L,54228L,54229L,54230L,54231L,54232L,54233L,54234L, +54235L,54236L,54237L,54238L,54239L,54240L,54241L,54242L,54243L,54244L, +54245L,54246L,54247L,54248L,54249L,54250L,54251L,54252L,54253L,54254L, +54255L,54256L,54257L,54258L,54259L,54260L,54261L,54262L,54263L,54264L, +54265L,54266L,54267L,54268L,54269L,54270L,54271L,54272L,54273L,54274L, +54275L,54276L,54277L,54278L,54279L,54280L,54281L,54282L,54283L,54284L, +54285L,54286L,54287L,54288L,54289L,54290L,54291L,54292L,54293L,54294L, +54295L,54296L,54297L,54298L,54299L,54300L,54301L,54302L,54303L,54304L, +54305L,54306L,54307L,54308L,54309L,54310L,54311L,54312L,54313L,54314L, +54315L,54316L,54317L,54318L,54319L,54320L,54321L,54322L,54323L,54324L, +54325L,54326L,54327L,54328L,54329L,54330L,54331L,54332L,54333L,54334L, +54335L,54336L,54337L,54338L,54339L,54340L,54341L,54342L,54343L,54344L, +54345L,54346L,54347L,54348L,54349L,54350L,54351L,54352L,54353L,54354L, +54355L,54356L,54357L,54358L,54359L,54360L,54361L,54362L,54363L,54364L, +54365L,54366L,54367L,54368L,54369L,54370L,54371L,54372L,54373L,54374L, +54375L,54376L,54377L,54378L,54379L,54380L,54381L,54382L,54383L,54384L, +54385L,54386L,54387L,54388L,54389L,54390L,54391L,54392L,54393L,54394L, +54395L,54396L,54397L,54398L,54399L,54400L,54401L,54402L,54403L,54404L, +54405L,54406L,54407L,54408L,54409L,54410L,54411L,54412L,54413L,54414L, +54415L,54416L,54417L,54418L,54419L,54420L,54421L,54422L,54423L,54424L, +54425L,54426L,54427L,54428L,54429L,54430L,54431L,54432L,54433L,54434L, +54435L,54436L,54437L,54438L,54439L,54440L,54441L,54442L,54443L,54444L, +54445L,54446L,54447L,54448L,54449L,54450L,54451L,54452L,54453L,54454L, +54455L,54456L,54457L,54458L,54459L,54460L,54461L,54462L,54463L,54464L, +54465L,54466L,54467L,54468L,54469L,54470L,54471L,54472L,54473L,54474L, +54475L,54476L,54477L,54478L,54479L,54480L,54481L,54482L,54483L,54484L, +54485L,54486L,54487L,54488L,54489L,54490L,54491L,54492L,54493L,54494L, +54495L,54496L,54497L,54498L,54499L,54500L,54501L,54502L,54503L,54504L, +54505L,54506L,54507L,54508L,54509L,54510L,54511L,54512L,54513L,54514L, +54515L,54516L,54517L,54518L,54519L,54520L,54521L,54522L,54523L,54524L, +54525L,54526L,54527L,54528L,54529L,54530L,54531L,54532L,54533L,54534L, +54535L,54536L,54537L,54538L,54539L,54540L,54541L,54542L,54543L,54544L, +54545L,54546L,54547L,54548L,54549L,54550L,54551L,54552L,54553L,54554L, +54555L,54556L,54557L,54558L,54559L,54560L,54561L,54562L,54563L,54564L, +54565L,54566L,54567L,54568L,54569L,54570L,54571L,54572L,54573L,54574L, +54575L,54576L,54577L,54578L,54579L,54580L,54581L,54582L,54583L,54584L, +54585L,54586L,54587L,54588L,54589L,54590L,54591L,54592L,54593L,54594L, +54595L,54596L,54597L,54598L,54599L,54600L,54601L,54602L,54603L,54604L, +54605L,54606L,54607L,54608L,54609L,54610L,54611L,54612L,54613L,54614L, +54615L,54616L,54617L,54618L,54619L,54620L,54621L,54622L,54623L,54624L, +54625L,54626L,54627L,54628L,54629L,54630L,54631L,54632L,54633L,54634L, +54635L,54636L,54637L,54638L,54639L,54640L,54641L,54642L,54643L,54644L, +54645L,54646L,54647L,54648L,54649L,54650L,54651L,54652L,54653L,54654L, +54655L,54656L,54657L,54658L,54659L,54660L,54661L,54662L,54663L,54664L, +54665L,54666L,54667L,54668L,54669L,54670L,54671L,54672L,54673L,54674L, +54675L,54676L,54677L,54678L,54679L,54680L,54681L,54682L,54683L,54684L, +54685L,54686L,54687L,54688L,54689L,54690L,54691L,54692L,54693L,54694L, +54695L,54696L,54697L,54698L,54699L,54700L,54701L,54702L,54703L,54704L, +54705L,54706L,54707L,54708L,54709L,54710L,54711L,54712L,54713L,54714L, +54715L,54716L,54717L,54718L,54719L,54720L,54721L,54722L,54723L,54724L, +54725L,54726L,54727L,54728L,54729L,54730L,54731L,54732L,54733L,54734L, +54735L,54736L,54737L,54738L,54739L,54740L,54741L,54742L,54743L,54744L, +54745L,54746L,54747L,54748L,54749L,54750L,54751L,54752L,54753L,54754L, +54755L,54756L,54757L,54758L,54759L,54760L,54761L,54762L,54763L,54764L, +54765L,54766L,54767L,54768L,54769L,54770L,54771L,54772L,54773L,54774L, +54775L,54776L,54777L,54778L,54779L,54780L,54781L,54782L,54783L,54784L, +54785L,54786L,54787L,54788L,54789L,54790L,54791L,54792L,54793L,54794L, +54795L,54796L,54797L,54798L,54799L,54800L,54801L,54802L,54803L,54804L, +54805L,54806L,54807L,54808L,54809L,54810L,54811L,54812L,54813L,54814L, +54815L,54816L,54817L,54818L,54819L,54820L,54821L,54822L,54823L,54824L, +54825L,54826L,54827L,54828L,54829L,54830L,54831L,54832L,54833L,54834L, +54835L,54836L,54837L,54838L,54839L,54840L,54841L,54842L,54843L,54844L, +54845L,54846L,54847L,54848L,54849L,54850L,54851L,54852L,54853L,54854L, +54855L,54856L,54857L,54858L,54859L,54860L,54861L,54862L,54863L,54864L, +54865L,54866L,54867L,54868L,54869L,54870L,54871L,54872L,54873L,54874L, +54875L,54876L,54877L,54878L,54879L,54880L,54881L,54882L,54883L,54884L, +54885L,54886L,54887L,54888L,54889L,54890L,54891L,54892L,54893L,54894L, +54895L,54896L,54897L,54898L,54899L,54900L,54901L,54902L,54903L,54904L, +54905L,54906L,54907L,54908L,54909L,54910L,54911L,54912L,54913L,54914L, +54915L,54916L,54917L,54918L,54919L,54920L,54921L,54922L,54923L,54924L, +54925L,54926L,54927L,54928L,54929L,54930L,54931L,54932L,54933L,54934L, +54935L,54936L,54937L,54938L,54939L,54940L,54941L,54942L,54943L,54944L, +54945L,54946L,54947L,54948L,54949L,54950L,54951L,54952L,54953L,54954L, +54955L,54956L,54957L,54958L,54959L,54960L,54961L,54962L,54963L,54964L, +54965L,54966L,54967L,54968L,54969L,54970L,54971L,54972L,54973L,54974L, +54975L,54976L,54977L,54978L,54979L,54980L,54981L,54982L,54983L,54984L, +54985L,54986L,54987L,54988L,54989L,54990L,54991L,54992L,54993L,54994L, +54995L,54996L,54997L,54998L,54999L,55000L,55001L,55002L,55003L,55004L, +55005L,55006L,55007L,55008L,55009L,55010L,55011L,55012L,55013L,55014L, +55015L,55016L,55017L,55018L,55019L,55020L,55021L,55022L,55023L,55024L, +55025L,55026L,55027L,55028L,55029L,55030L,55031L,55032L,55033L,55034L, +55035L,55036L,55037L,55038L,55039L,55040L,55041L,55042L,55043L,55044L, +55045L,55046L,55047L,55048L,55049L,55050L,55051L,55052L,55053L,55054L, +55055L,55056L,55057L,55058L,55059L,55060L,55061L,55062L,55063L,55064L, +55065L,55066L,55067L,55068L,55069L,55070L,55071L,55072L,55073L,55074L, +55075L,55076L,55077L,55078L,55079L,55080L,55081L,55082L,55083L,55084L, +55085L,55086L,55087L,55088L,55089L,55090L,55091L,55092L,55093L,55094L, +55095L,55096L,55097L,55098L,55099L,55100L,55101L,55102L,55103L,55104L, +55105L,55106L,55107L,55108L,55109L,55110L,55111L,55112L,55113L,55114L, +55115L,55116L,55117L,55118L,55119L,55120L,55121L,55122L,55123L,55124L, +55125L,55126L,55127L,55128L,55129L,55130L,55131L,55132L,55133L,55134L, +55135L,55136L,55137L,55138L,55139L,55140L,55141L,55142L,55143L,55144L, +55145L,55146L,55147L,55148L,55149L,55150L,55151L,55152L,55153L,55154L, +55155L,55156L,55157L,55158L,55159L,55160L,55161L,55162L,55163L,55164L, +55165L,55166L,55167L,55168L,55169L,55170L,55171L,55172L,55173L,55174L, +55175L,55176L,55177L,55178L,55179L,55180L,55181L,55182L,55183L,55184L, +55185L,55186L,55187L,55188L,55189L,55190L,55191L,55192L,55193L,55194L, +55195L,55196L,55197L,55198L,55199L,55200L,55201L,55202L,55203L,55204L, +55205L,55206L,55207L,55208L,55209L,55210L,55211L,55212L,55213L,55214L, +55215L,55216L,55217L,55218L,55219L,55220L,55221L,55222L,55223L,55224L, +55225L,55226L,55227L,55228L,55229L,55230L,55231L,55232L,55233L,55234L, +55235L,55236L,55237L,55238L,55239L,55240L,55241L,55242L,55243L,55244L, +55245L,55246L,55247L,55248L,55249L,55250L,55251L,55252L,55253L,55254L, +55255L,55256L,55257L,55258L,55259L,55260L,55261L,55262L,55263L,55264L, +55265L,55266L,55267L,55268L,55269L,55270L,55271L,55272L,55273L,55274L, +55275L,55276L,55277L,55278L,55279L,55280L,55281L,55282L,55283L,55284L, +55285L,55286L,55287L,55288L,55289L,55290L,55291L,55292L,55293L,55294L, +55295L,55296L,55297L,55298L,55299L,55300L,55301L,55302L,55303L,55304L, +55305L,55306L,55307L,55308L,55309L,55310L,55311L,55312L,55313L,55314L, +55315L,55316L,55317L,55318L,55319L,55320L,55321L,55322L,55323L,55324L, +55325L,55326L,55327L,55328L,55329L,55330L,55331L,55332L,55333L,55334L, +55335L,55336L,55337L,55338L,55339L,55340L,55341L,55342L,55343L,55344L, +55345L,55346L,55347L,55348L,55349L,55350L,55351L,55352L,55353L,55354L, +55355L,55356L,55357L,55358L,55359L,55360L,55361L,55362L,55363L,55364L, +55365L,55366L,55367L,55368L,55369L,55370L,55371L,55372L,55373L,55374L, +55375L,55376L,55377L,55378L,55379L,55380L,55381L,55382L,55383L,55384L, +55385L,55386L,55387L,55388L,55389L,55390L,55391L,55392L,55393L,55394L, +55395L,55396L,55397L,55398L,55399L,55400L,55401L,55402L,55403L,55404L, +55405L,55406L,55407L,55408L,55409L,55410L,55411L,55412L,55413L,55414L, +55415L,55416L,55417L,55418L,55419L,55420L,55421L,55422L,55423L,55424L, +55425L,55426L,55427L,55428L,55429L,55430L,55431L,55432L,55433L,55434L, +55435L,55436L,55437L,55438L,55439L,55440L,55441L,55442L,55443L,55444L, +55445L,55446L,55447L,55448L,55449L,55450L,55451L,55452L,55453L,55454L, +55455L,55456L,55457L,55458L,55459L,55460L,55461L,55462L,55463L,55464L, +55465L,55466L,55467L,55468L,55469L,55470L,55471L,55472L,55473L,55474L, +55475L,55476L,55477L,55478L,55479L,55480L,55481L,55482L,55483L,55484L, +55485L,55486L,55487L,55488L,55489L,55490L,55491L,55492L,55493L,55494L, +55495L,55496L,55497L,55498L,55499L,55500L,55501L,55502L,55503L,55504L, +55505L,55506L,55507L,55508L,55509L,55510L,55511L,55512L,55513L,55514L, +55515L,55516L,55517L,55518L,55519L,55520L,55521L,55522L,55523L,55524L, +55525L,55526L,55527L,55528L,55529L,55530L,55531L,55532L,55533L,55534L, +55535L,55536L,55537L,55538L,55539L,55540L,55541L,55542L,55543L,55544L, +55545L,55546L,55547L,55548L,55549L,55550L,55551L,55552L,55553L,55554L, +55555L,55556L,55557L,55558L,55559L,55560L,55561L,55562L,55563L,55564L, +55565L,55566L,55567L,55568L,55569L,55570L,55571L,55572L,55573L,55574L, +55575L,55576L,55577L,55578L,55579L,55580L,55581L,55582L,55583L,55584L, +55585L,55586L,55587L,55588L,55589L,55590L,55591L,55592L,55593L,55594L, +55595L,55596L,55597L,55598L,55599L,55600L,55601L,55602L,55603L,55604L, +55605L,55606L,55607L,55608L,55609L,55610L,55611L,55612L,55613L,55614L, +55615L,55616L,55617L,55618L,55619L,55620L,55621L,55622L,55623L,55624L, +55625L,55626L,55627L,55628L,55629L,55630L,55631L,55632L,55633L,55634L, +55635L,55636L,55637L,55638L,55639L,55640L,55641L,55642L,55643L,55644L, +55645L,55646L,55647L,55648L,55649L,55650L,55651L,55652L,55653L,55654L, +55655L,55656L,55657L,55658L,55659L,55660L,55661L,55662L,55663L,55664L, +55665L,55666L,55667L,55668L,55669L,55670L,55671L,55672L,55673L,55674L, +55675L,55676L,55677L,55678L,55679L,55680L,55681L,55682L,55683L,55684L, +55685L,55686L,55687L,55688L,55689L,55690L,55691L,55692L,55693L,55694L, +55695L,55696L,55697L,55698L,55699L,55700L,55701L,55702L,55703L,55704L, +55705L,55706L,55707L,55708L,55709L,55710L,55711L,55712L,55713L,55714L, +55715L,55716L,55717L,55718L,55719L,55720L,55721L,55722L,55723L,55724L, +55725L,55726L,55727L,55728L,55729L,55730L,55731L,55732L,55733L,55734L, +55735L,55736L,55737L,55738L,55739L,55740L,55741L,55742L,55743L,55744L, +55745L,55746L,55747L,55748L,55749L,55750L,55751L,55752L,55753L,55754L, +55755L,55756L,55757L,55758L,55759L,55760L,55761L,55762L,55763L,55764L, +55765L,55766L,55767L,55768L,55769L,55770L,55771L,55772L,55773L,55774L, +55775L,55776L,55777L,55778L,55779L,55780L,55781L,55782L,55783L,55784L, +55785L,55786L,55787L,55788L,55789L,55790L,55791L,55792L,55793L,55794L, +55795L,55796L,55797L,55798L,55799L,55800L,55801L,55802L,55803L,55804L, +55805L,55806L,55807L,55808L,55809L,55810L,55811L,55812L,55813L,55814L, +55815L,55816L,55817L,55818L,55819L,55820L,55821L,55822L,55823L,55824L, +55825L,55826L,55827L,55828L,55829L,55830L,55831L,55832L,55833L,55834L, +55835L,55836L,55837L,55838L,55839L,55840L,55841L,55842L,55843L,55844L, +55845L,55846L,55847L,55848L,55849L,55850L,55851L,55852L,55853L,55854L, +55855L,55856L,55857L,55858L,55859L,55860L,55861L,55862L,55863L,55864L, +55865L,55866L,55867L,55868L,55869L,55870L,55871L,55872L,55873L,55874L, +55875L,55876L,55877L,55878L,55879L,55880L,55881L,55882L,55883L,55884L, +55885L,55886L,55887L,55888L,55889L,55890L,55891L,55892L,55893L,55894L, +55895L,55896L,55897L,55898L,55899L,55900L,55901L,55902L,55903L,55904L, +55905L,55906L,55907L,55908L,55909L,55910L,55911L,55912L,55913L,55914L, +55915L,55916L,55917L,55918L,55919L,55920L,55921L,55922L,55923L,55924L, +55925L,55926L,55927L,55928L,55929L,55930L,55931L,55932L,55933L,55934L, +55935L,55936L,55937L,55938L,55939L,55940L,55941L,55942L,55943L,55944L, +55945L,55946L,55947L,55948L,55949L,55950L,55951L,55952L,55953L,55954L, +55955L,55956L,55957L,55958L,55959L,55960L,55961L,55962L,55963L,55964L, +55965L,55966L,55967L,55968L,55969L,55970L,55971L,55972L,55973L,55974L, +55975L,55976L,55977L,55978L,55979L,55980L,55981L,55982L,55983L,55984L, +55985L,55986L,55987L,55988L,55989L,55990L,55991L,55992L,55993L,55994L, +55995L,55996L,55997L,55998L,55999L,56000L,56001L,56002L,56003L,56004L, +56005L,56006L,56007L,56008L,56009L,56010L,56011L,56012L,56013L,56014L, +56015L,56016L,56017L,56018L,56019L,56020L,56021L,56022L,56023L,56024L, +56025L,56026L,56027L,56028L,56029L,56030L,56031L,56032L,56033L,56034L, +56035L,56036L,56037L,56038L,56039L,56040L,56041L,56042L,56043L,56044L, +56045L,56046L,56047L,56048L,56049L,56050L,56051L,56052L,56053L,56054L, +56055L,56056L,56057L,56058L,56059L,56060L,56061L,56062L,56063L,56064L, +56065L,56066L,56067L,56068L,56069L,56070L,56071L,56072L,56073L,56074L, +56075L,56076L,56077L,56078L,56079L,56080L,56081L,56082L,56083L,56084L, +56085L,56086L,56087L,56088L,56089L,56090L,56091L,56092L,56093L,56094L, +56095L,56096L,56097L,56098L,56099L,56100L,56101L,56102L,56103L,56104L, +56105L,56106L,56107L,56108L,56109L,56110L,56111L,56112L,56113L,56114L, +56115L,56116L,56117L,56118L,56119L,56120L,56121L,56122L,56123L,56124L, +56125L,56126L,56127L,56128L,56129L,56130L,56131L,56132L,56133L,56134L, +56135L,56136L,56137L,56138L,56139L,56140L,56141L,56142L,56143L,56144L, +56145L,56146L,56147L,56148L,56149L,56150L,56151L,56152L,56153L,56154L, +56155L,56156L,56157L,56158L,56159L,56160L,56161L,56162L,56163L,56164L, +56165L,56166L,56167L,56168L,56169L,56170L,56171L,56172L,56173L,56174L, +56175L,56176L,56177L,56178L,56179L,56180L,56181L,56182L,56183L,56184L, +56185L,56186L,56187L,56188L,56189L,56190L,56191L,56192L,56193L,56194L, +56195L,56196L,56197L,56198L,56199L,56200L,56201L,56202L,56203L,56204L, +56205L,56206L,56207L,56208L,56209L,56210L,56211L,56212L,56213L,56214L, +56215L,56216L,56217L,56218L,56219L,56220L,56221L,56222L,56223L,56224L, +56225L,56226L,56227L,56228L,56229L,56230L,56231L,56232L,56233L,56234L, +56235L,56236L,56237L,56238L,56239L,56240L,56241L,56242L,56243L,56244L, +56245L,56246L,56247L,56248L,56249L,56250L,56251L,56252L,56253L,56254L, +56255L,56256L,56257L,56258L,56259L,56260L,56261L,56262L,56263L,56264L, +56265L,56266L,56267L,56268L,56269L,56270L,56271L,56272L,56273L,56274L, +56275L,56276L,56277L,56278L,56279L,56280L,56281L,56282L,56283L,56284L, +56285L,56286L,56287L,56288L,56289L,56290L,56291L,56292L,56293L,56294L, +56295L,56296L,56297L,56298L,56299L,56300L,56301L,56302L,56303L,56304L, +56305L,56306L,56307L,56308L,56309L,56310L,56311L,56312L,56313L,56314L, +56315L,56316L,56317L,56318L,56319L,56320L,56321L,56322L,56323L,56324L, +56325L,56326L,56327L,56328L,56329L,56330L,56331L,56332L,56333L,56334L, +56335L,56336L,56337L,56338L,56339L,56340L,56341L,56342L,56343L,56344L, +56345L,56346L,56347L,56348L,56349L,56350L,56351L,56352L,56353L,56354L, +56355L,56356L,56357L,56358L,56359L,56360L,56361L,56362L,56363L,56364L, +56365L,56366L,56367L,56368L,56369L,56370L,56371L,56372L,56373L,56374L, +56375L,56376L,56377L,56378L,56379L,56380L,56381L,56382L,56383L,56384L, +56385L,56386L,56387L,56388L,56389L,56390L,56391L,56392L,56393L,56394L, +56395L,56396L,56397L,56398L,56399L,56400L,56401L,56402L,56403L,56404L, +56405L,56406L,56407L,56408L,56409L,56410L,56411L,56412L,56413L,56414L, +56415L,56416L,56417L,56418L,56419L,56420L,56421L,56422L,56423L,56424L, +56425L,56426L,56427L,56428L,56429L,56430L,56431L,56432L,56433L,56434L, +56435L,56436L,56437L,56438L,56439L,56440L,56441L,56442L,56443L,56444L, +56445L,56446L,56447L,56448L,56449L,56450L,56451L,56452L,56453L,56454L, +56455L,56456L,56457L,56458L,56459L,56460L,56461L,56462L,56463L,56464L, +56465L,56466L,56467L,56468L,56469L,56470L,56471L,56472L,56473L,56474L, +56475L,56476L,56477L,56478L,56479L,56480L,56481L,56482L,56483L,56484L, +56485L,56486L,56487L,56488L,56489L,56490L,56491L,56492L,56493L,56494L, +56495L,56496L,56497L,56498L,56499L,56500L,56501L,56502L,56503L,56504L, +56505L,56506L,56507L,56508L,56509L,56510L,56511L,56512L,56513L,56514L, +56515L,56516L,56517L,56518L,56519L,56520L,56521L,56522L,56523L,56524L, +56525L,56526L,56527L,56528L,56529L,56530L,56531L,56532L,56533L,56534L, +56535L,56536L,56537L,56538L,56539L,56540L,56541L,56542L,56543L,56544L, +56545L,56546L,56547L,56548L,56549L,56550L,56551L,56552L,56553L,56554L, +56555L,56556L,56557L,56558L,56559L,56560L,56561L,56562L,56563L,56564L, +56565L,56566L,56567L,56568L,56569L,56570L,56571L,56572L,56573L,56574L, +56575L,56576L,56577L,56578L,56579L,56580L,56581L,56582L,56583L,56584L, +56585L,56586L,56587L,56588L,56589L,56590L,56591L,56592L,56593L,56594L, +56595L,56596L,56597L,56598L,56599L,56600L,56601L,56602L,56603L,56604L, +56605L,56606L,56607L,56608L,56609L,56610L,56611L,56612L,56613L,56614L, +56615L,56616L,56617L,56618L,56619L,56620L,56621L,56622L,56623L,56624L, +56625L,56626L,56627L,56628L,56629L,56630L,56631L,56632L,56633L,56634L, +56635L,56636L,56637L,56638L,56639L,56640L,56641L,56642L,56643L,56644L, +56645L,56646L,56647L,56648L,56649L,56650L,56651L,56652L,56653L,56654L, +56655L,56656L,56657L,56658L,56659L,56660L,56661L,56662L,56663L,56664L, +56665L,56666L,56667L,56668L,56669L,56670L,56671L,56672L,56673L,56674L, +56675L,56676L,56677L,56678L,56679L,56680L,56681L,56682L,56683L,56684L, +56685L,56686L,56687L,56688L,56689L,56690L,56691L,56692L,56693L,56694L, +56695L,56696L,56697L,56698L,56699L,56700L,56701L,56702L,56703L,56704L, +56705L,56706L,56707L,56708L,56709L,56710L,56711L,56712L,56713L,56714L, +56715L,56716L,56717L,56718L,56719L,56720L,56721L,56722L,56723L,56724L, +56725L,56726L,56727L,56728L,56729L,56730L,56731L,56732L,56733L,56734L, +56735L,56736L,56737L,56738L,56739L,56740L,56741L,56742L,56743L,56744L, +56745L,56746L,56747L,56748L,56749L,56750L,56751L,56752L,56753L,56754L, +56755L,56756L,56757L,56758L,56759L,56760L,56761L,56762L,56763L,56764L, +56765L,56766L,56767L,56768L,56769L,56770L,56771L,56772L,56773L,56774L, +56775L,56776L,56777L,56778L,56779L,56780L,56781L,56782L,56783L,56784L, +56785L,56786L,56787L,56788L,56789L,56790L,56791L,56792L,56793L,56794L, +56795L,56796L,56797L,56798L,56799L,56800L,56801L,56802L,56803L,56804L, +56805L,56806L,56807L,56808L,56809L,56810L,56811L,56812L,56813L,56814L, +56815L,56816L,56817L,56818L,56819L,56820L,56821L,56822L,56823L,56824L, +56825L,56826L,56827L,56828L,56829L,56830L,56831L,56832L,56833L,56834L, +56835L,56836L,56837L,56838L,56839L,56840L,56841L,56842L,56843L,56844L, +56845L,56846L,56847L,56848L,56849L,56850L,56851L,56852L,56853L,56854L, +56855L,56856L,56857L,56858L,56859L,56860L,56861L,56862L,56863L,56864L, +56865L,56866L,56867L,56868L,56869L,56870L,56871L,56872L,56873L,56874L, +56875L,56876L,56877L,56878L,56879L,56880L,56881L,56882L,56883L,56884L, +56885L,56886L,56887L,56888L,56889L,56890L,56891L,56892L,56893L,56894L, +56895L,56896L,56897L,56898L,56899L,56900L,56901L,56902L,56903L,56904L, +56905L,56906L,56907L,56908L,56909L,56910L,56911L,56912L,56913L,56914L, +56915L,56916L,56917L,56918L,56919L,56920L,56921L,56922L,56923L,56924L, +56925L,56926L,56927L,56928L,56929L,56930L,56931L,56932L,56933L,56934L, +56935L,56936L,56937L,56938L,56939L,56940L,56941L,56942L,56943L,56944L, +56945L,56946L,56947L,56948L,56949L,56950L,56951L,56952L,56953L,56954L, +56955L,56956L,56957L,56958L,56959L,56960L,56961L,56962L,56963L,56964L, +56965L,56966L,56967L,56968L,56969L,56970L,56971L,56972L,56973L,56974L, +56975L,56976L,56977L,56978L,56979L,56980L,56981L,56982L,56983L,56984L, +56985L,56986L,56987L,56988L,56989L,56990L,56991L,56992L,56993L,56994L, +56995L,56996L,56997L,56998L,56999L,57000L,57001L,57002L,57003L,57004L, +57005L,57006L,57007L,57008L,57009L,57010L,57011L,57012L,57013L,57014L, +57015L,57016L,57017L,57018L,57019L,57020L,57021L,57022L,57023L,57024L, +57025L,57026L,57027L,57028L,57029L,57030L,57031L,57032L,57033L,57034L, +57035L,57036L,57037L,57038L,57039L,57040L,57041L,57042L,57043L,57044L, +57045L,57046L,57047L,57048L,57049L,57050L,57051L,57052L,57053L,57054L, +57055L,57056L,57057L,57058L,57059L,57060L,57061L,57062L,57063L,57064L, +57065L,57066L,57067L,57068L,57069L,57070L,57071L,57072L,57073L,57074L, +57075L,57076L,57077L,57078L,57079L,57080L,57081L,57082L,57083L,57084L, +57085L,57086L,57087L,57088L,57089L,57090L,57091L,57092L,57093L,57094L, +57095L,57096L,57097L,57098L,57099L,57100L,57101L,57102L,57103L,57104L, +57105L,57106L,57107L,57108L,57109L,57110L,57111L,57112L,57113L,57114L, +57115L,57116L,57117L,57118L,57119L,57120L,57121L,57122L,57123L,57124L, +57125L,57126L,57127L,57128L,57129L,57130L,57131L,57132L,57133L,57134L, +57135L,57136L,57137L,57138L,57139L,57140L,57141L,57142L,57143L,57144L, +57145L,57146L,57147L,57148L,57149L,57150L,57151L,57152L,57153L,57154L, +57155L,57156L,57157L,57158L,57159L,57160L,57161L,57162L,57163L,57164L, +57165L,57166L,57167L,57168L,57169L,57170L,57171L,57172L,57173L,57174L, +57175L,57176L,57177L,57178L,57179L,57180L,57181L,57182L,57183L,57184L, +57185L,57186L,57187L,57188L,57189L,57190L,57191L,57192L,57193L,57194L, +57195L,57196L,57197L,57198L,57199L,57200L,57201L,57202L,57203L,57204L, +57205L,57206L,57207L,57208L,57209L,57210L,57211L,57212L,57213L,57214L, +57215L,57216L,57217L,57218L,57219L,57220L,57221L,57222L,57223L,57224L, +57225L,57226L,57227L,57228L,57229L,57230L,57231L,57232L,57233L,57234L, +57235L,57236L,57237L,57238L,57239L,57240L,57241L,57242L,57243L,57244L, +57245L,57246L,57247L,57248L,57249L,57250L,57251L,57252L,57253L,57254L, +57255L,57256L,57257L,57258L,57259L,57260L,57261L,57262L,57263L,57264L, +57265L,57266L,57267L,57268L,57269L,57270L,57271L,57272L,57273L,57274L, +57275L,57276L,57277L,57278L,57279L,57280L,57281L,57282L,57283L,57284L, +57285L,57286L,57287L,57288L,57289L,57290L,57291L,57292L,57293L,57294L, +57295L,57296L,57297L,57298L,57299L,57300L,57301L,57302L,57303L,57304L, +57305L,57306L,57307L,57308L,57309L,57310L,57311L,57312L,57313L,57314L, +57315L,57316L,57317L,57318L,57319L,57320L,57321L,57322L,57323L,57324L, +57325L,57326L,57327L,57328L,57329L,57330L,57331L,57332L,57333L,57334L, +57335L,57336L,57337L,57338L,57339L,57340L,57341L,57342L,57343L,57344L, +57345L,57346L,57347L,57348L,57349L,57350L,57351L,57352L,57353L,57354L, +57355L,57356L,57357L,57358L,57359L,57360L,57361L,57362L,57363L,57364L, +57365L,57366L,57367L,57368L,57369L,57370L,57371L,57372L,57373L,57374L, +57375L,57376L,57377L,57378L,57379L,57380L,57381L,57382L,57383L,57384L, +57385L,57386L,57387L,57388L,57389L,57390L,57391L,57392L,57393L,57394L, +57395L,57396L,57397L,57398L,57399L,57400L,57401L,57402L,57403L,57404L, +57405L,57406L,57407L,57408L,57409L,57410L,57411L,57412L,57413L,57414L, +57415L,57416L,57417L,57418L,57419L,57420L,57421L,57422L,57423L,57424L, +57425L,57426L,57427L,57428L,57429L,57430L,57431L,57432L,57433L,57434L, +57435L,57436L,57437L,57438L,57439L,57440L,57441L,57442L,57443L,57444L, +57445L,57446L,57447L,57448L,57449L,57450L,57451L,57452L,57453L,57454L, +57455L,57456L,57457L,57458L,57459L,57460L,57461L,57462L,57463L,57464L, +57465L,57466L,57467L,57468L,57469L,57470L,57471L,57472L,57473L,57474L, +57475L,57476L,57477L,57478L,57479L,57480L,57481L,57482L,57483L,57484L, +57485L,57486L,57487L,57488L,57489L,57490L,57491L,57492L,57493L,57494L, +57495L,57496L,57497L,57498L,57499L,57500L,57501L,57502L,57503L,57504L, +57505L,57506L,57507L,57508L,57509L,57510L,57511L,57512L,57513L,57514L, +57515L,57516L,57517L,57518L,57519L,57520L,57521L,57522L,57523L,57524L, +57525L,57526L,57527L,57528L,57529L,57530L,57531L,57532L,57533L,57534L, +57535L,57536L,57537L,57538L,57539L,57540L,57541L,57542L,57543L,57544L, +57545L,57546L,57547L,57548L,57549L,57550L,57551L,57552L,57553L,57554L, +57555L,57556L,57557L,57558L,57559L,57560L,57561L,57562L,57563L,57564L, +57565L,57566L,57567L,57568L,57569L,57570L,57571L,57572L,57573L,57574L, +57575L,57576L,57577L,57578L,57579L,57580L,57581L,57582L,57583L,57584L, +57585L,57586L,57587L,57588L,57589L,57590L,57591L,57592L,57593L,57594L, +57595L,57596L,57597L,57598L,57599L,57600L,57601L,57602L,57603L,57604L, +57605L,57606L,57607L,57608L,57609L,57610L,57611L,57612L,57613L,57614L, +57615L,57616L,57617L,57618L,57619L,57620L,57621L,57622L,57623L,57624L, +57625L,57626L,57627L,57628L,57629L,57630L,57631L,57632L,57633L,57634L, +57635L,57636L,57637L,57638L,57639L,57640L,57641L,57642L,57643L,57644L, +57645L,57646L,57647L,57648L,57649L,57650L,57651L,57652L,57653L,57654L, +57655L,57656L,57657L,57658L,57659L,57660L,57661L,57662L,57663L,57664L, +57665L,57666L,57667L,57668L,57669L,57670L,57671L,57672L,57673L,57674L, +57675L,57676L,57677L,57678L,57679L,57680L,57681L,57682L,57683L,57684L, +57685L,57686L,57687L,57688L,57689L,57690L,57691L,57692L,57693L,57694L, +57695L,57696L,57697L,57698L,57699L,57700L,57701L,57702L,57703L,57704L, +57705L,57706L,57707L,57708L,57709L,57710L,57711L,57712L,57713L,57714L, +57715L,57716L,57717L,57718L,57719L,57720L,57721L,57722L,57723L,57724L, +57725L,57726L,57727L,57728L,57729L,57730L,57731L,57732L,57733L,57734L, +57735L,57736L,57737L,57738L,57739L,57740L,57741L,57742L,57743L,57744L, +57745L,57746L,57747L,57748L,57749L,57750L,57751L,57752L,57753L,57754L, +57755L,57756L,57757L,57758L,57759L,57760L,57761L,57762L,57763L,57764L, +57765L,57766L,57767L,57768L,57769L,57770L,57771L,57772L,57773L,57774L, +57775L,57776L,57777L,57778L,57779L,57780L,57781L,57782L,57783L,57784L, +57785L,57786L,57787L,57788L,57789L,57790L,57791L,57792L,57793L,57794L, +57795L,57796L,57797L,57798L,57799L,57800L,57801L,57802L,57803L,57804L, +57805L,57806L,57807L,57808L,57809L,57810L,57811L,57812L,57813L,57814L, +57815L,57816L,57817L,57818L,57819L,57820L,57821L,57822L,57823L,57824L, +57825L,57826L,57827L,57828L,57829L,57830L,57831L,57832L,57833L,57834L, +57835L,57836L,57837L,57838L,57839L,57840L,57841L,57842L,57843L,57844L, +57845L,57846L,57847L,57848L,57849L,57850L,57851L,57852L,57853L,57854L, +57855L,57856L,57857L,57858L,57859L,57860L,57861L,57862L,57863L,57864L, +57865L,57866L,57867L,57868L,57869L,57870L,57871L,57872L,57873L,57874L, +57875L,57876L,57877L,57878L,57879L,57880L,57881L,57882L,57883L,57884L, +57885L,57886L,57887L,57888L,57889L,57890L,57891L,57892L,57893L,57894L, +57895L,57896L,57897L,57898L,57899L,57900L,57901L,57902L,57903L,57904L, +57905L,57906L,57907L,57908L,57909L,57910L,57911L,57912L,57913L,57914L, +57915L,57916L,57917L,57918L,57919L,57920L,57921L,57922L,57923L,57924L, +57925L,57926L,57927L,57928L,57929L,57930L,57931L,57932L,57933L,57934L, +57935L,57936L,57937L,57938L,57939L,57940L,57941L,57942L,57943L,57944L, +57945L,57946L,57947L,57948L,57949L,57950L,57951L,57952L,57953L,57954L, +57955L,57956L,57957L,57958L,57959L,57960L,57961L,57962L,57963L,57964L, +57965L,57966L,57967L,57968L,57969L,57970L,57971L,57972L,57973L,57974L, +57975L,57976L,57977L,57978L,57979L,57980L,57981L,57982L,57983L,57984L, +57985L,57986L,57987L,57988L,57989L,57990L,57991L,57992L,57993L,57994L, +57995L,57996L,57997L,57998L,57999L,58000L,58001L,58002L,58003L,58004L, +58005L,58006L,58007L,58008L,58009L,58010L,58011L,58012L,58013L,58014L, +58015L,58016L,58017L,58018L,58019L,58020L,58021L,58022L,58023L,58024L, +58025L,58026L,58027L,58028L,58029L,58030L,58031L,58032L,58033L,58034L, +58035L,58036L,58037L,58038L,58039L,58040L,58041L,58042L,58043L,58044L, +58045L,58046L,58047L,58048L,58049L,58050L,58051L,58052L,58053L,58054L, +58055L,58056L,58057L,58058L,58059L,58060L,58061L,58062L,58063L,58064L, +58065L,58066L,58067L,58068L,58069L,58070L,58071L,58072L,58073L,58074L, +58075L,58076L,58077L,58078L,58079L,58080L,58081L,58082L,58083L,58084L, +58085L,58086L,58087L,58088L,58089L,58090L,58091L,58092L,58093L,58094L, +58095L,58096L,58097L,58098L,58099L,58100L,58101L,58102L,58103L,58104L, +58105L,58106L,58107L,58108L,58109L,58110L,58111L,58112L,58113L,58114L, +58115L,58116L,58117L,58118L,58119L,58120L,58121L,58122L,58123L,58124L, +58125L,58126L,58127L,58128L,58129L,58130L,58131L,58132L,58133L,58134L, +58135L,58136L,58137L,58138L,58139L,58140L,58141L,58142L,58143L,58144L, +58145L,58146L,58147L,58148L,58149L,58150L,58151L,58152L,58153L,58154L, +58155L,58156L,58157L,58158L,58159L,58160L,58161L,58162L,58163L,58164L, +58165L,58166L,58167L,58168L,58169L,58170L,58171L,58172L,58173L,58174L, +58175L,58176L,58177L,58178L,58179L,58180L,58181L,58182L,58183L,58184L, +58185L,58186L,58187L,58188L,58189L,58190L,58191L,58192L,58193L,58194L, +58195L,58196L,58197L,58198L,58199L,58200L,58201L,58202L,58203L,58204L, +58205L,58206L,58207L,58208L,58209L,58210L,58211L,58212L,58213L,58214L, +58215L,58216L,58217L,58218L,58219L,58220L,58221L,58222L,58223L,58224L, +58225L,58226L,58227L,58228L,58229L,58230L,58231L,58232L,58233L,58234L, +58235L,58236L,58237L,58238L,58239L,58240L,58241L,58242L,58243L,58244L, +58245L,58246L,58247L,58248L,58249L,58250L,58251L,58252L,58253L,58254L, +58255L,58256L,58257L,58258L,58259L,58260L,58261L,58262L,58263L,58264L, +58265L,58266L,58267L,58268L,58269L,58270L,58271L,58272L,58273L,58274L, +58275L,58276L,58277L,58278L,58279L,58280L,58281L,58282L,58283L,58284L, +58285L,58286L,58287L,58288L,58289L,58290L,58291L,58292L,58293L,58294L, +58295L,58296L,58297L,58298L,58299L,58300L,58301L,58302L,58303L,58304L, +58305L,58306L,58307L,58308L,58309L,58310L,58311L,58312L,58313L,58314L, +58315L,58316L,58317L,58318L,58319L,58320L,58321L,58322L,58323L,58324L, +58325L,58326L,58327L,58328L,58329L,58330L,58331L,58332L,58333L,58334L, +58335L,58336L,58337L,58338L,58339L,58340L,58341L,58342L,58343L,58344L, +58345L,58346L,58347L,58348L,58349L,58350L,58351L,58352L,58353L,58354L, +58355L,58356L,58357L,58358L,58359L,58360L,58361L,58362L,58363L,58364L, +58365L,58366L,58367L,58368L,58369L,58370L,58371L,58372L,58373L,58374L, +58375L,58376L,58377L,58378L,58379L,58380L,58381L,58382L,58383L,58384L, +58385L,58386L,58387L,58388L,58389L,58390L,58391L,58392L,58393L,58394L, +58395L,58396L,58397L,58398L,58399L,58400L,58401L,58402L,58403L,58404L, +58405L,58406L,58407L,58408L,58409L,58410L,58411L,58412L,58413L,58414L, +58415L,58416L,58417L,58418L,58419L,58420L,58421L,58422L,58423L,58424L, +58425L,58426L,58427L,58428L,58429L,58430L,58431L,58432L,58433L,58434L, +58435L,58436L,58437L,58438L,58439L,58440L,58441L,58442L,58443L,58444L, +58445L,58446L,58447L,58448L,58449L,58450L,58451L,58452L,58453L,58454L, +58455L,58456L,58457L,58458L,58459L,58460L,58461L,58462L,58463L,58464L, +58465L,58466L,58467L,58468L,58469L,58470L,58471L,58472L,58473L,58474L, +58475L,58476L,58477L,58478L,58479L,58480L,58481L,58482L,58483L,58484L, +58485L,58486L,58487L,58488L,58489L,58490L,58491L,58492L,58493L,58494L, +58495L,58496L,58497L,58498L,58499L,58500L,58501L,58502L,58503L,58504L, +58505L,58506L,58507L,58508L,58509L,58510L,58511L,58512L,58513L,58514L, +58515L,58516L,58517L,58518L,58519L,58520L,58521L,58522L,58523L,58524L, +58525L,58526L,58527L,58528L,58529L,58530L,58531L,58532L,58533L,58534L, +58535L,58536L,58537L,58538L,58539L,58540L,58541L,58542L,58543L,58544L, +58545L,58546L,58547L,58548L,58549L,58550L,58551L,58552L,58553L,58554L, +58555L,58556L,58557L,58558L,58559L,58560L,58561L,58562L,58563L,58564L, +58565L,58566L,58567L,58568L,58569L,58570L,58571L,58572L,58573L,58574L, +58575L,58576L,58577L,58578L,58579L,58580L,58581L,58582L,58583L,58584L, +58585L,58586L,58587L,58588L,58589L,58590L,58591L,58592L,58593L,58594L, +58595L,58596L,58597L,58598L,58599L,58600L,58601L,58602L,58603L,58604L, +58605L,58606L,58607L,58608L,58609L,58610L,58611L,58612L,58613L,58614L, +58615L,58616L,58617L,58618L,58619L,58620L,58621L,58622L,58623L,58624L, +58625L,58626L,58627L,58628L,58629L,58630L,58631L,58632L,58633L,58634L, +58635L,58636L,58637L,58638L,58639L,58640L,58641L,58642L,58643L,58644L, +58645L,58646L,58647L,58648L,58649L,58650L,58651L,58652L,58653L,58654L, +58655L,58656L,58657L,58658L,58659L,58660L,58661L,58662L,58663L,58664L, +58665L,58666L,58667L,58668L,58669L,58670L,58671L,58672L,58673L,58674L, +58675L,58676L,58677L,58678L,58679L,58680L,58681L,58682L,58683L,58684L, +58685L,58686L,58687L,58688L,58689L,58690L,58691L,58692L,58693L,58694L, +58695L,58696L,58697L,58698L,58699L,58700L,58701L,58702L,58703L,58704L, +58705L,58706L,58707L,58708L,58709L,58710L,58711L,58712L,58713L,58714L, +58715L,58716L,58717L,58718L,58719L,58720L,58721L,58722L,58723L,58724L, +58725L,58726L,58727L,58728L,58729L,58730L,58731L,58732L,58733L,58734L, +58735L,58736L,58737L,58738L,58739L,58740L,58741L,58742L,58743L,58744L, +58745L,58746L,58747L,58748L,58749L,58750L,58751L,58752L,58753L,58754L, +58755L,58756L,58757L,58758L,58759L,58760L,58761L,58762L,58763L,58764L, +58765L,58766L,58767L,58768L,58769L,58770L,58771L,58772L,58773L,58774L, +58775L,58776L,58777L,58778L,58779L,58780L,58781L,58782L,58783L,58784L, +58785L,58786L,58787L,58788L,58789L,58790L,58791L,58792L,58793L,58794L, +58795L,58796L,58797L,58798L,58799L,58800L,58801L,58802L,58803L,58804L, +58805L,58806L,58807L,58808L,58809L,58810L,58811L,58812L,58813L,58814L, +58815L,58816L,58817L,58818L,58819L,58820L,58821L,58822L,58823L,58824L, +58825L,58826L,58827L,58828L,58829L,58830L,58831L,58832L,58833L,58834L, +58835L,58836L,58837L,58838L,58839L,58840L,58841L,58842L,58843L,58844L, +58845L,58846L,58847L,58848L,58849L,58850L,58851L,58852L,58853L,58854L, +58855L,58856L,58857L,58858L,58859L,58860L,58861L,58862L,58863L,58864L, +58865L,58866L,58867L,58868L,58869L,58870L,58871L,58872L,58873L,58874L, +58875L,58876L,58877L,58878L,58879L,58880L,58881L,58882L,58883L,58884L, +58885L,58886L,58887L,58888L,58889L,58890L,58891L,58892L,58893L,58894L, +58895L,58896L,58897L,58898L,58899L,58900L,58901L,58902L,58903L,58904L, +58905L,58906L,58907L,58908L,58909L,58910L,58911L,58912L,58913L,58914L, +58915L,58916L,58917L,58918L,58919L,58920L,58921L,58922L,58923L,58924L, +58925L,58926L,58927L,58928L,58929L,58930L,58931L,58932L,58933L,58934L, +58935L,58936L,58937L,58938L,58939L,58940L,58941L,58942L,58943L,58944L, +58945L,58946L,58947L,58948L,58949L,58950L,58951L,58952L,58953L,58954L, +58955L,58956L,58957L,58958L,58959L,58960L,58961L,58962L,58963L,58964L, +58965L,58966L,58967L,58968L,58969L,58970L,58971L,58972L,58973L,58974L, +58975L,58976L,58977L,58978L,58979L,58980L,58981L,58982L,58983L,58984L, +58985L,58986L,58987L,58988L,58989L,58990L,58991L,58992L,58993L,58994L, +58995L,58996L,58997L,58998L,58999L,59000L,59001L,59002L,59003L,59004L, +59005L,59006L,59007L,59008L,59009L,59010L,59011L,59012L,59013L,59014L, +59015L,59016L,59017L,59018L,59019L,59020L,59021L,59022L,59023L,59024L, +59025L,59026L,59027L,59028L,59029L,59030L,59031L,59032L,59033L,59034L, +59035L,59036L,59037L,59038L,59039L,59040L,59041L,59042L,59043L,59044L, +59045L,59046L,59047L,59048L,59049L,59050L,59051L,59052L,59053L,59054L, +59055L,59056L,59057L,59058L,59059L,59060L,59061L,59062L,59063L,59064L, +59065L,59066L,59067L,59068L,59069L,59070L,59071L,59072L,59073L,59074L, +59075L,59076L,59077L,59078L,59079L,59080L,59081L,59082L,59083L,59084L, +59085L,59086L,59087L,59088L,59089L,59090L,59091L,59092L,59093L,59094L, +59095L,59096L,59097L,59098L,59099L,59100L,59101L,59102L,59103L,59104L, +59105L,59106L,59107L,59108L,59109L,59110L,59111L,59112L,59113L,59114L, +59115L,59116L,59117L,59118L,59119L,59120L,59121L,59122L,59123L,59124L, +59125L,59126L,59127L,59128L,59129L,59130L,59131L,59132L,59133L,59134L, +59135L,59136L,59137L,59138L,59139L,59140L,59141L,59142L,59143L,59144L, +59145L,59146L,59147L,59148L,59149L,59150L,59151L,59152L,59153L,59154L, +59155L,59156L,59157L,59158L,59159L,59160L,59161L,59162L,59163L,59164L, +59165L,59166L,59167L,59168L,59169L,59170L,59171L,59172L,59173L,59174L, +59175L,59176L,59177L,59178L,59179L,59180L,59181L,59182L,59183L,59184L, +59185L,59186L,59187L,59188L,59189L,59190L,59191L,59192L,59193L,59194L, +59195L,59196L,59197L,59198L,59199L,59200L,59201L,59202L,59203L,59204L, +59205L,59206L,59207L,59208L,59209L,59210L,59211L,59212L,59213L,59214L, +59215L,59216L,59217L,59218L,59219L,59220L,59221L,59222L,59223L,59224L, +59225L,59226L,59227L,59228L,59229L,59230L,59231L,59232L,59233L,59234L, +59235L,59236L,59237L,59238L,59239L,59240L,59241L,59242L,59243L,59244L, +59245L,59246L,59247L,59248L,59249L,59250L,59251L,59252L,59253L,59254L, +59255L,59256L,59257L,59258L,59259L,59260L,59261L,59262L,59263L,59264L, +59265L,59266L,59267L,59268L,59269L,59270L,59271L,59272L,59273L,59274L, +59275L,59276L,59277L,59278L,59279L,59280L,59281L,59282L,59283L,59284L, +59285L,59286L,59287L,59288L,59289L,59290L,59291L,59292L,59293L,59294L, +59295L,59296L,59297L,59298L,59299L,59300L,59301L,59302L,59303L,59304L, +59305L,59306L,59307L,59308L,59309L,59310L,59311L,59312L,59313L,59314L, +59315L,59316L,59317L,59318L,59319L,59320L,59321L,59322L,59323L,59324L, +59325L,59326L,59327L,59328L,59329L,59330L,59331L,59332L,59333L,59334L, +59335L,59336L,59337L,59338L,59339L,59340L,59341L,59342L,59343L,59344L, +59345L,59346L,59347L,59348L,59349L,59350L,59351L,59352L,59353L,59354L, +59355L,59356L,59357L,59358L,59359L,59360L,59361L,59362L,59363L,59364L, +59365L,59366L,59367L,59368L,59369L,59370L,59371L,59372L,59373L,59374L, +59375L,59376L,59377L,59378L,59379L,59380L,59381L,59382L,59383L,59384L, +59385L,59386L,59387L,59388L,59389L,59390L,59391L,59392L,59393L,59394L, +59395L,59396L,59397L,59398L,59399L,59400L,59401L,59402L,59403L,59404L, +59405L,59406L,59407L,59408L,59409L,59410L,59411L,59412L,59413L,59414L, +59415L,59416L,59417L,59418L,59419L,59420L,59421L,59422L,59423L,59424L, +59425L,59426L,59427L,59428L,59429L,59430L,59431L,59432L,59433L,59434L, +59435L,59436L,59437L,59438L,59439L,59440L,59441L,59442L,59443L,59444L, +59445L,59446L,59447L,59448L,59449L,59450L,59451L,59452L,59453L,59454L, +59455L,59456L,59457L,59458L,59459L,59460L,59461L,59462L,59463L,59464L, +59465L,59466L,59467L,59468L,59469L,59470L,59471L,59472L,59473L,59474L, +59475L,59476L,59477L,59478L,59479L,59480L,59481L,59482L,59483L,59484L, +59485L,59486L,59487L,59488L,59489L,59490L,59491L,59492L,59493L,59494L, +59495L,59496L,59497L,59498L,59499L,59500L,59501L,59502L,59503L,59504L, +59505L,59506L,59507L,59508L,59509L,59510L,59511L,59512L,59513L,59514L, +59515L,59516L,59517L,59518L,59519L,59520L,59521L,59522L,59523L,59524L, +59525L,59526L,59527L,59528L,59529L,59530L,59531L,59532L,59533L,59534L, +59535L,59536L,59537L,59538L,59539L,59540L,59541L,59542L,59543L,59544L, +59545L,59546L,59547L,59548L,59549L,59550L,59551L,59552L,59553L,59554L, +59555L,59556L,59557L,59558L,59559L,59560L,59561L,59562L,59563L,59564L, +59565L,59566L,59567L,59568L,59569L,59570L,59571L,59572L,59573L,59574L, +59575L,59576L,59577L,59578L,59579L,59580L,59581L,59582L,59583L,59584L, +59585L,59586L,59587L,59588L,59589L,59590L,59591L,59592L,59593L,59594L, +59595L,59596L,59597L,59598L,59599L,59600L,59601L,59602L,59603L,59604L, +59605L,59606L,59607L,59608L,59609L,59610L,59611L,59612L,59613L,59614L, +59615L,59616L,59617L,59618L,59619L,59620L,59621L,59622L,59623L,59624L, +59625L,59626L,59627L,59628L,59629L,59630L,59631L,59632L,59633L,59634L, +59635L,59636L,59637L,59638L,59639L,59640L,59641L,59642L,59643L,59644L, +59645L,59646L,59647L,59648L,59649L,59650L,59651L,59652L,59653L,59654L, +59655L,59656L,59657L,59658L,59659L,59660L,59661L,59662L,59663L,59664L, +59665L,59666L,59667L,59668L,59669L,59670L,59671L,59672L,59673L,59674L, +59675L,59676L,59677L,59678L,59679L,59680L,59681L,59682L,59683L,59684L, +59685L,59686L,59687L,59688L,59689L,59690L,59691L,59692L,59693L,59694L, +59695L,59696L,59697L,59698L,59699L,59700L,59701L,59702L,59703L,59704L, +59705L,59706L,59707L,59708L,59709L,59710L,59711L,59712L,59713L,59714L, +59715L,59716L,59717L,59718L,59719L,59720L,59721L,59722L,59723L,59724L, +59725L,59726L,59727L,59728L,59729L,59730L,59731L,59732L,59733L,59734L, +59735L,59736L,59737L,59738L,59739L,59740L,59741L,59742L,59743L,59744L, +59745L,59746L,59747L,59748L,59749L,59750L,59751L,59752L,59753L,59754L, +59755L,59756L,59757L,59758L,59759L,59760L,59761L,59762L,59763L,59764L, +59765L,59766L,59767L,59768L,59769L,59770L,59771L,59772L,59773L,59774L, +59775L,59776L,59777L,59778L,59779L,59780L,59781L,59782L,59783L,59784L, +59785L,59786L,59787L,59788L,59789L,59790L,59791L,59792L,59793L,59794L, +59795L,59796L,59797L,59798L,59799L,59800L,59801L,59802L,59803L,59804L, +59805L,59806L,59807L,59808L,59809L,59810L,59811L,59812L,59813L,59814L, +59815L,59816L,59817L,59818L,59819L,59820L,59821L,59822L,59823L,59824L, +59825L,59826L,59827L,59828L,59829L,59830L,59831L,59832L,59833L,59834L, +59835L,59836L,59837L,59838L,59839L,59840L,59841L,59842L,59843L,59844L, +59845L,59846L,59847L,59848L,59849L,59850L,59851L,59852L,59853L,59854L, +59855L,59856L,59857L,59858L,59859L,59860L,59861L,59862L,59863L,59864L, +59865L,59866L,59867L,59868L,59869L,59870L,59871L,59872L,59873L,59874L, +59875L,59876L,59877L,59878L,59879L,59880L,59881L,59882L,59883L,59884L, +59885L,59886L,59887L,59888L,59889L,59890L,59891L,59892L,59893L,59894L, +59895L,59896L,59897L,59898L,59899L,59900L,59901L,59902L,59903L,59904L, +59905L,59906L,59907L,59908L,59909L,59910L,59911L,59912L,59913L,59914L, +59915L,59916L,59917L,59918L,59919L,59920L,59921L,59922L,59923L,59924L, +59925L,59926L,59927L,59928L,59929L,59930L,59931L,59932L,59933L,59934L, +59935L,59936L,59937L,59938L,59939L,59940L,59941L,59942L,59943L,59944L, +59945L,59946L,59947L,59948L,59949L,59950L,59951L,59952L,59953L,59954L, +59955L,59956L,59957L,59958L,59959L,59960L,59961L,59962L,59963L,59964L, +59965L,59966L,59967L,59968L,59969L,59970L,59971L,59972L,59973L,59974L, +59975L,59976L,59977L,59978L,59979L,59980L,59981L,59982L,59983L,59984L, +59985L,59986L,59987L,59988L,59989L,59990L,59991L,59992L,59993L,59994L, +59995L,59996L,59997L,59998L,59999L,60000L,60001L,60002L,60003L,60004L, +60005L,60006L,60007L,60008L,60009L,60010L,60011L,60012L,60013L,60014L, +60015L,60016L,60017L,60018L,60019L,60020L,60021L,60022L,60023L,60024L, +60025L,60026L,60027L,60028L,60029L,60030L,60031L,60032L,60033L,60034L, +60035L,60036L,60037L,60038L,60039L,60040L,60041L,60042L,60043L,60044L, +60045L,60046L,60047L,60048L,60049L,60050L,60051L,60052L,60053L,60054L, +60055L,60056L,60057L,60058L,60059L,60060L,60061L,60062L,60063L,60064L, +60065L,60066L,60067L,60068L,60069L,60070L,60071L,60072L,60073L,60074L, +60075L,60076L,60077L,60078L,60079L,60080L,60081L,60082L,60083L,60084L, +60085L,60086L,60087L,60088L,60089L,60090L,60091L,60092L,60093L,60094L, +60095L,60096L,60097L,60098L,60099L,60100L,60101L,60102L,60103L,60104L, +60105L,60106L,60107L,60108L,60109L,60110L,60111L,60112L,60113L,60114L, +60115L,60116L,60117L,60118L,60119L,60120L,60121L,60122L,60123L,60124L, +60125L,60126L,60127L,60128L,60129L,60130L,60131L,60132L,60133L,60134L, +60135L,60136L,60137L,60138L,60139L,60140L,60141L,60142L,60143L,60144L, +60145L,60146L,60147L,60148L,60149L,60150L,60151L,60152L,60153L,60154L, +60155L,60156L,60157L,60158L,60159L,60160L,60161L,60162L,60163L,60164L, +60165L,60166L,60167L,60168L,60169L,60170L,60171L,60172L,60173L,60174L, +60175L,60176L,60177L,60178L,60179L,60180L,60181L,60182L,60183L,60184L, +60185L,60186L,60187L,60188L,60189L,60190L,60191L,60192L,60193L,60194L, +60195L,60196L,60197L,60198L,60199L,60200L,60201L,60202L,60203L,60204L, +60205L,60206L,60207L,60208L,60209L,60210L,60211L,60212L,60213L,60214L, +60215L,60216L,60217L,60218L,60219L,60220L,60221L,60222L,60223L,60224L, +60225L,60226L,60227L,60228L,60229L,60230L,60231L,60232L,60233L,60234L, +60235L,60236L,60237L,60238L,60239L,60240L,60241L,60242L,60243L,60244L, +60245L,60246L,60247L,60248L,60249L,60250L,60251L,60252L,60253L,60254L, +60255L,60256L,60257L,60258L,60259L,60260L,60261L,60262L,60263L,60264L, +60265L,60266L,60267L,60268L,60269L,60270L,60271L,60272L,60273L,60274L, +60275L,60276L,60277L,60278L,60279L,60280L,60281L,60282L,60283L,60284L, +60285L,60286L,60287L,60288L,60289L,60290L,60291L,60292L,60293L,60294L, +60295L,60296L,60297L,60298L,60299L,60300L,60301L,60302L,60303L,60304L, +60305L,60306L,60307L,60308L,60309L,60310L,60311L,60312L,60313L,60314L, +60315L,60316L,60317L,60318L,60319L,60320L,60321L,60322L,60323L,60324L, +60325L,60326L,60327L,60328L,60329L,60330L,60331L,60332L,60333L,60334L, +60335L,60336L,60337L,60338L,60339L,60340L,60341L,60342L,60343L,60344L, +60345L,60346L,60347L,60348L,60349L,60350L,60351L,60352L,60353L,60354L, +60355L,60356L,60357L,60358L,60359L,60360L,60361L,60362L,60363L,60364L, +60365L,60366L,60367L,60368L,60369L,60370L,60371L,60372L,60373L,60374L, +60375L,60376L,60377L,60378L,60379L,60380L,60381L,60382L,60383L,60384L, +60385L,60386L,60387L,60388L,60389L,60390L,60391L,60392L,60393L,60394L, +60395L,60396L,60397L,60398L,60399L,60400L,60401L,60402L,60403L,60404L, +60405L,60406L,60407L,60408L,60409L,60410L,60411L,60412L,60413L,60414L, +60415L,60416L,60417L,60418L,60419L,60420L,60421L,60422L,60423L,60424L, +60425L,60426L,60427L,60428L,60429L,60430L,60431L,60432L,60433L,60434L, +60435L,60436L,60437L,60438L,60439L,60440L,60441L,60442L,60443L,60444L, +60445L,60446L,60447L,60448L,60449L,60450L,60451L,60452L,60453L,60454L, +60455L,60456L,60457L,60458L,60459L,60460L,60461L,60462L,60463L,60464L, +60465L,60466L,60467L,60468L,60469L,60470L,60471L,60472L,60473L,60474L, +60475L,60476L,60477L,60478L,60479L,60480L,60481L,60482L,60483L,60484L, +60485L,60486L,60487L,60488L,60489L,60490L,60491L,60492L,60493L,60494L, +60495L,60496L,60497L,60498L,60499L,60500L,60501L,60502L,60503L,60504L, +60505L,60506L,60507L,60508L,60509L,60510L,60511L,60512L,60513L,60514L, +60515L,60516L,60517L,60518L,60519L,60520L,60521L,60522L,60523L,60524L, +60525L,60526L,60527L,60528L,60529L,60530L,60531L,60532L,60533L,60534L, +60535L,60536L,60537L,60538L,60539L,60540L,60541L,60542L,60543L,60544L, +60545L,60546L,60547L,60548L,60549L,60550L,60551L,60552L,60553L,60554L, +60555L,60556L,60557L,60558L,60559L,60560L,60561L,60562L,60563L,60564L, +60565L,60566L,60567L,60568L,60569L,60570L,60571L,60572L,60573L,60574L, +60575L,60576L,60577L,60578L,60579L,60580L,60581L,60582L,60583L,60584L, +60585L,60586L,60587L,60588L,60589L,60590L,60591L,60592L,60593L,60594L, +60595L,60596L,60597L,60598L,60599L,60600L,60601L,60602L,60603L,60604L, +60605L,60606L,60607L,60608L,60609L,60610L,60611L,60612L,60613L,60614L, +60615L,60616L,60617L,60618L,60619L,60620L,60621L,60622L,60623L,60624L, +60625L,60626L,60627L,60628L,60629L,60630L,60631L,60632L,60633L,60634L, +60635L,60636L,60637L,60638L,60639L,60640L,60641L,60642L,60643L,60644L, +60645L,60646L,60647L,60648L,60649L,60650L,60651L,60652L,60653L,60654L, +60655L,60656L,60657L,60658L,60659L,60660L,60661L,60662L,60663L,60664L, +60665L,60666L,60667L,60668L,60669L,60670L,60671L,60672L,60673L,60674L, +60675L,60676L,60677L,60678L,60679L,60680L,60681L,60682L,60683L,60684L, +60685L,60686L,60687L,60688L,60689L,60690L,60691L,60692L,60693L,60694L, +60695L,60696L,60697L,60698L,60699L,60700L,60701L,60702L,60703L,60704L, +60705L,60706L,60707L,60708L,60709L,60710L,60711L,60712L,60713L,60714L, +60715L,60716L,60717L,60718L,60719L,60720L,60721L,60722L,60723L,60724L, +60725L,60726L,60727L,60728L,60729L,60730L,60731L,60732L,60733L,60734L, +60735L,60736L,60737L,60738L,60739L,60740L,60741L,60742L,60743L,60744L, +60745L,60746L,60747L,60748L,60749L,60750L,60751L,60752L,60753L,60754L, +60755L,60756L,60757L,60758L,60759L,60760L,60761L,60762L,60763L,60764L, +60765L,60766L,60767L,60768L,60769L,60770L,60771L,60772L,60773L,60774L, +60775L,60776L,60777L,60778L,60779L,60780L,60781L,60782L,60783L,60784L, +60785L,60786L,60787L,60788L,60789L,60790L,60791L,60792L,60793L,60794L, +60795L,60796L,60797L,60798L,60799L,60800L,60801L,60802L,60803L,60804L, +60805L,60806L,60807L,60808L,60809L,60810L,60811L,60812L,60813L,60814L, +60815L,60816L,60817L,60818L,60819L,60820L,60821L,60822L,60823L,60824L, +60825L,60826L,60827L,60828L,60829L,60830L,60831L,60832L,60833L,60834L, +60835L,60836L,60837L,60838L,60839L,60840L,60841L,60842L,60843L,60844L, +60845L,60846L,60847L,60848L,60849L,60850L,60851L,60852L,60853L,60854L, +60855L,60856L,60857L,60858L,60859L,60860L,60861L,60862L,60863L,60864L, +60865L,60866L,60867L,60868L,60869L,60870L,60871L,60872L,60873L,60874L, +60875L,60876L,60877L,60878L,60879L,60880L,60881L,60882L,60883L,60884L, +60885L,60886L,60887L,60888L,60889L,60890L,60891L,60892L,60893L,60894L, +60895L,60896L,60897L,60898L,60899L,60900L,60901L,60902L,60903L,60904L, +60905L,60906L,60907L,60908L,60909L,60910L,60911L,60912L,60913L,60914L, +60915L,60916L,60917L,60918L,60919L,60920L,60921L,60922L,60923L,60924L, +60925L,60926L,60927L,60928L,60929L,60930L,60931L,60932L,60933L,60934L, +60935L,60936L,60937L,60938L,60939L,60940L,60941L,60942L,60943L,60944L, +60945L,60946L,60947L,60948L,60949L,60950L,60951L,60952L,60953L,60954L, +60955L,60956L,60957L,60958L,60959L,60960L,60961L,60962L,60963L,60964L, +60965L,60966L,60967L,60968L,60969L,60970L,60971L,60972L,60973L,60974L, +60975L,60976L,60977L,60978L,60979L,60980L,60981L,60982L,60983L,60984L, +60985L,60986L,60987L,60988L,60989L,60990L,60991L,60992L,60993L,60994L, +60995L,60996L,60997L,60998L,60999L,61000L,61001L,61002L,61003L,61004L, +61005L,61006L,61007L,61008L,61009L,61010L,61011L,61012L,61013L,61014L, +61015L,61016L,61017L,61018L,61019L,61020L,61021L,61022L,61023L,61024L, +61025L,61026L,61027L,61028L,61029L,61030L,61031L,61032L,61033L,61034L, +61035L,61036L,61037L,61038L,61039L,61040L,61041L,61042L,61043L,61044L, +61045L,61046L,61047L,61048L,61049L,61050L,61051L,61052L,61053L,61054L, +61055L,61056L,61057L,61058L,61059L,61060L,61061L,61062L,61063L,61064L, +61065L,61066L,61067L,61068L,61069L,61070L,61071L,61072L,61073L,61074L, +61075L,61076L,61077L,61078L,61079L,61080L,61081L,61082L,61083L,61084L, +61085L,61086L,61087L,61088L,61089L,61090L,61091L,61092L,61093L,61094L, +61095L,61096L,61097L,61098L,61099L,61100L,61101L,61102L,61103L,61104L, +61105L,61106L,61107L,61108L,61109L,61110L,61111L,61112L,61113L,61114L, +61115L,61116L,61117L,61118L,61119L,61120L,61121L,61122L,61123L,61124L, +61125L,61126L,61127L,61128L,61129L,61130L,61131L,61132L,61133L,61134L, +61135L,61136L,61137L,61138L,61139L,61140L,61141L,61142L,61143L,61144L, +61145L,61146L,61147L,61148L,61149L,61150L,61151L,61152L,61153L,61154L, +61155L,61156L,61157L,61158L,61159L,61160L,61161L,61162L,61163L,61164L, +61165L,61166L,61167L,61168L,61169L,61170L,61171L,61172L,61173L,61174L, +61175L,61176L,61177L,61178L,61179L,61180L,61181L,61182L,61183L,61184L, +61185L,61186L,61187L,61188L,61189L,61190L,61191L,61192L,61193L,61194L, +61195L,61196L,61197L,61198L,61199L,61200L,61201L,61202L,61203L,61204L, +61205L,61206L,61207L,61208L,61209L,61210L,61211L,61212L,61213L,61214L, +61215L,61216L,61217L,61218L,61219L,61220L,61221L,61222L,61223L,61224L, +61225L,61226L,61227L,61228L,61229L,61230L,61231L,61232L,61233L,61234L, +61235L,61236L,61237L,61238L,61239L,61240L,61241L,61242L,61243L,61244L, +61245L,61246L,61247L,61248L,61249L,61250L,61251L,61252L,61253L,61254L, +61255L,61256L,61257L,61258L,61259L,61260L,61261L,61262L,61263L,61264L, +61265L,61266L,61267L,61268L,61269L,61270L,61271L,61272L,61273L,61274L, +61275L,61276L,61277L,61278L,61279L,61280L,61281L,61282L,61283L,61284L, +61285L,61286L,61287L,61288L,61289L,61290L,61291L,61292L,61293L,61294L, +61295L,61296L,61297L,61298L,61299L,61300L,61301L,61302L,61303L,61304L, +61305L,61306L,61307L,61308L,61309L,61310L,61311L,61312L,61313L,61314L, +61315L,61316L,61317L,61318L,61319L,61320L,61321L,61322L,61323L,61324L, +61325L,61326L,61327L,61328L,61329L,61330L,61331L,61332L,61333L,61334L, +61335L,61336L,61337L,61338L,61339L,61340L,61341L,61342L,61343L,61344L, +61345L,61346L,61347L,61348L,61349L,61350L,61351L,61352L,61353L,61354L, +61355L,61356L,61357L,61358L,61359L,61360L,61361L,61362L,61363L,61364L, +61365L,61366L,61367L,61368L,61369L,61370L,61371L,61372L,61373L,61374L, +61375L,61376L,61377L,61378L,61379L,61380L,61381L,61382L,61383L,61384L, +61385L,61386L,61387L,61388L,61389L,61390L,61391L,61392L,61393L,61394L, +61395L,61396L,61397L,61398L,61399L,61400L,61401L,61402L,61403L,61404L, +61405L,61406L,61407L,61408L,61409L,61410L,61411L,61412L,61413L,61414L, +61415L,61416L,61417L,61418L,61419L,61420L,61421L,61422L,61423L,61424L, +61425L,61426L,61427L,61428L,61429L,61430L,61431L,61432L,61433L,61434L, +61435L,61436L,61437L,61438L,61439L,61440L,61441L,61442L,61443L,61444L, +61445L,61446L,61447L,61448L,61449L,61450L,61451L,61452L,61453L,61454L, +61455L,61456L,61457L,61458L,61459L,61460L,61461L,61462L,61463L,61464L, +61465L,61466L,61467L,61468L,61469L,61470L,61471L,61472L,61473L,61474L, +61475L,61476L,61477L,61478L,61479L,61480L,61481L,61482L,61483L,61484L, +61485L,61486L,61487L,61488L,61489L,61490L,61491L,61492L,61493L,61494L, +61495L,61496L,61497L,61498L,61499L,61500L,61501L,61502L,61503L,61504L, +61505L,61506L,61507L,61508L,61509L,61510L,61511L,61512L,61513L,61514L, +61515L,61516L,61517L,61518L,61519L,61520L,61521L,61522L,61523L,61524L, +61525L,61526L,61527L,61528L,61529L,61530L,61531L,61532L,61533L,61534L, +61535L,61536L,61537L,61538L,61539L,61540L,61541L,61542L,61543L,61544L, +61545L,61546L,61547L,61548L,61549L,61550L,61551L,61552L,61553L,61554L, +61555L,61556L,61557L,61558L,61559L,61560L,61561L,61562L,61563L,61564L, +61565L,61566L,61567L,61568L,61569L,61570L,61571L,61572L,61573L,61574L, +61575L,61576L,61577L,61578L,61579L,61580L,61581L,61582L,61583L,61584L, +61585L,61586L,61587L,61588L,61589L,61590L,61591L,61592L,61593L,61594L, +61595L,61596L,61597L,61598L,61599L,61600L,61601L,61602L,61603L,61604L, +61605L,61606L,61607L,61608L,61609L,61610L,61611L,61612L,61613L,61614L, +61615L,61616L,61617L,61618L,61619L,61620L,61621L,61622L,61623L,61624L, +61625L,61626L,61627L,61628L,61629L,61630L,61631L,61632L,61633L,61634L, +61635L,61636L,61637L,61638L,61639L,61640L,61641L,61642L,61643L,61644L, +61645L,61646L,61647L,61648L,61649L,61650L,61651L,61652L,61653L,61654L, +61655L,61656L,61657L,61658L,61659L,61660L,61661L,61662L,61663L,61664L, +61665L,61666L,61667L,61668L,61669L,61670L,61671L,61672L,61673L,61674L, +61675L,61676L,61677L,61678L,61679L,61680L,61681L,61682L,61683L,61684L, +61685L,61686L,61687L,61688L,61689L,61690L,61691L,61692L,61693L,61694L, +61695L,61696L,61697L,61698L,61699L,61700L,61701L,61702L,61703L,61704L, +61705L,61706L,61707L,61708L,61709L,61710L,61711L,61712L,61713L,61714L, +61715L,61716L,61717L,61718L,61719L,61720L,61721L,61722L,61723L,61724L, +61725L,61726L,61727L,61728L,61729L,61730L,61731L,61732L,61733L,61734L, +61735L,61736L,61737L,61738L,61739L,61740L,61741L,61742L,61743L,61744L, +61745L,61746L,61747L,61748L,61749L,61750L,61751L,61752L,61753L,61754L, +61755L,61756L,61757L,61758L,61759L,61760L,61761L,61762L,61763L,61764L, +61765L,61766L,61767L,61768L,61769L,61770L,61771L,61772L,61773L,61774L, +61775L,61776L,61777L,61778L,61779L,61780L,61781L,61782L,61783L,61784L, +61785L,61786L,61787L,61788L,61789L,61790L,61791L,61792L,61793L,61794L, +61795L,61796L,61797L,61798L,61799L,61800L,61801L,61802L,61803L,61804L, +61805L,61806L,61807L,61808L,61809L,61810L,61811L,61812L,61813L,61814L, +61815L,61816L,61817L,61818L,61819L,61820L,61821L,61822L,61823L,61824L, +61825L,61826L,61827L,61828L,61829L,61830L,61831L,61832L,61833L,61834L, +61835L,61836L,61837L,61838L,61839L,61840L,61841L,61842L,61843L,61844L, +61845L,61846L,61847L,61848L,61849L,61850L,61851L,61852L,61853L,61854L, +61855L,61856L,61857L,61858L,61859L,61860L,61861L,61862L,61863L,61864L, +61865L,61866L,61867L,61868L,61869L,61870L,61871L,61872L,61873L,61874L, +61875L,61876L,61877L,61878L,61879L,61880L,61881L,61882L,61883L,61884L, +61885L,61886L,61887L,61888L,61889L,61890L,61891L,61892L,61893L,61894L, +61895L,61896L,61897L,61898L,61899L,61900L,61901L,61902L,61903L,61904L, +61905L,61906L,61907L,61908L,61909L,61910L,61911L,61912L,61913L,61914L, +61915L,61916L,61917L,61918L,61919L,61920L,61921L,61922L,61923L,61924L, +61925L,61926L,61927L,61928L,61929L,61930L,61931L,61932L,61933L,61934L, +61935L,61936L,61937L,61938L,61939L,61940L,61941L,61942L,61943L,61944L, +61945L,61946L,61947L,61948L,61949L,61950L,61951L,61952L,61953L,61954L, +61955L,61956L,61957L,61958L,61959L,61960L,61961L,61962L,61963L,61964L, +61965L,61966L,61967L,61968L,61969L,61970L,61971L,61972L,61973L,61974L, +61975L,61976L,61977L,61978L,61979L,61980L,61981L,61982L,61983L,61984L, +61985L,61986L,61987L,61988L,61989L,61990L,61991L,61992L,61993L,61994L, +61995L,61996L,61997L,61998L,61999L,62000L,62001L,62002L,62003L,62004L, +62005L,62006L,62007L,62008L,62009L,62010L,62011L,62012L,62013L,62014L, +62015L,62016L,62017L,62018L,62019L,62020L,62021L,62022L,62023L,62024L, +62025L,62026L,62027L,62028L,62029L,62030L,62031L,62032L,62033L,62034L, +62035L,62036L,62037L,62038L,62039L,62040L,62041L,62042L,62043L,62044L, +62045L,62046L,62047L,62048L,62049L,62050L,62051L,62052L,62053L,62054L, +62055L,62056L,62057L,62058L,62059L,62060L,62061L,62062L,62063L,62064L, +62065L,62066L,62067L,62068L,62069L,62070L,62071L,62072L,62073L,62074L, +62075L,62076L,62077L,62078L,62079L,62080L,62081L,62082L,62083L,62084L, +62085L,62086L,62087L,62088L,62089L,62090L,62091L,62092L,62093L,62094L, +62095L,62096L,62097L,62098L,62099L,62100L,62101L,62102L,62103L,62104L, +62105L,62106L,62107L,62108L,62109L,62110L,62111L,62112L,62113L,62114L, +62115L,62116L,62117L,62118L,62119L,62120L,62121L,62122L,62123L,62124L, +62125L,62126L,62127L,62128L,62129L,62130L,62131L,62132L,62133L,62134L, +62135L,62136L,62137L,62138L,62139L,62140L,62141L,62142L,62143L,62144L, +62145L,62146L,62147L,62148L,62149L,62150L,62151L,62152L,62153L,62154L, +62155L,62156L,62157L,62158L,62159L,62160L,62161L,62162L,62163L,62164L, +62165L,62166L,62167L,62168L,62169L,62170L,62171L,62172L,62173L,62174L, +62175L,62176L,62177L,62178L,62179L,62180L,62181L,62182L,62183L,62184L, +62185L,62186L,62187L,62188L,62189L,62190L,62191L,62192L,62193L,62194L, +62195L,62196L,62197L,62198L,62199L,62200L,62201L,62202L,62203L,62204L, +62205L,62206L,62207L,62208L,62209L,62210L,62211L,62212L,62213L,62214L, +62215L,62216L,62217L,62218L,62219L,62220L,62221L,62222L,62223L,62224L, +62225L,62226L,62227L,62228L,62229L,62230L,62231L,62232L,62233L,62234L, +62235L,62236L,62237L,62238L,62239L,62240L,62241L,62242L,62243L,62244L, +62245L,62246L,62247L,62248L,62249L,62250L,62251L,62252L,62253L,62254L, +62255L,62256L,62257L,62258L,62259L,62260L,62261L,62262L,62263L,62264L, +62265L,62266L,62267L,62268L,62269L,62270L,62271L,62272L,62273L,62274L, +62275L,62276L,62277L,62278L,62279L,62280L,62281L,62282L,62283L,62284L, +62285L,62286L,62287L,62288L,62289L,62290L,62291L,62292L,62293L,62294L, +62295L,62296L,62297L,62298L,62299L,62300L,62301L,62302L,62303L,62304L, +62305L,62306L,62307L,62308L,62309L,62310L,62311L,62312L,62313L,62314L, +62315L,62316L,62317L,62318L,62319L,62320L,62321L,62322L,62323L,62324L, +62325L,62326L,62327L,62328L,62329L,62330L,62331L,62332L,62333L,62334L, +62335L,62336L,62337L,62338L,62339L,62340L,62341L,62342L,62343L,62344L, +62345L,62346L,62347L,62348L,62349L,62350L,62351L,62352L,62353L,62354L, +62355L,62356L,62357L,62358L,62359L,62360L,62361L,62362L,62363L,62364L, +62365L,62366L,62367L,62368L,62369L,62370L,62371L,62372L,62373L,62374L, +62375L,62376L,62377L,62378L,62379L,62380L,62381L,62382L,62383L,62384L, +62385L,62386L,62387L,62388L,62389L,62390L,62391L,62392L,62393L,62394L, +62395L,62396L,62397L,62398L,62399L,62400L,62401L,62402L,62403L,62404L, +62405L,62406L,62407L,62408L,62409L,62410L,62411L,62412L,62413L,62414L, +62415L,62416L,62417L,62418L,62419L,62420L,62421L,62422L,62423L,62424L, +62425L,62426L,62427L,62428L,62429L,62430L,62431L,62432L,62433L,62434L, +62435L,62436L,62437L,62438L,62439L,62440L,62441L,62442L,62443L,62444L, +62445L,62446L,62447L,62448L,62449L,62450L,62451L,62452L,62453L,62454L, +62455L,62456L,62457L,62458L,62459L,62460L,62461L,62462L,62463L,62464L, +62465L,62466L,62467L,62468L,62469L,62470L,62471L,62472L,62473L,62474L, +62475L,62476L,62477L,62478L,62479L,62480L,62481L,62482L,62483L,62484L, +62485L,62486L,62487L,62488L,62489L,62490L,62491L,62492L,62493L,62494L, +62495L,62496L,62497L,62498L,62499L,62500L,62501L,62502L,62503L,62504L, +62505L,62506L,62507L,62508L,62509L,62510L,62511L,62512L,62513L,62514L, +62515L,62516L,62517L,62518L,62519L,62520L,62521L,62522L,62523L,62524L, +62525L,62526L,62527L,62528L,62529L,62530L,62531L,62532L,62533L,62534L, +62535L,62536L,62537L,62538L,62539L,62540L,62541L,62542L,62543L,62544L, +62545L,62546L,62547L,62548L,62549L,62550L,62551L,62552L,62553L,62554L, +62555L,62556L,62557L,62558L,62559L,62560L,62561L,62562L,62563L,62564L, +62565L,62566L,62567L,62568L,62569L,62570L,62571L,62572L,62573L,62574L, +62575L,62576L,62577L,62578L,62579L,62580L,62581L,62582L,62583L,62584L, +62585L,62586L,62587L,62588L,62589L,62590L,62591L,62592L,62593L,62594L, +62595L,62596L,62597L,62598L,62599L,62600L,62601L,62602L,62603L,62604L, +62605L,62606L,62607L,62608L,62609L,62610L,62611L,62612L,62613L,62614L, +62615L,62616L,62617L,62618L,62619L,62620L,62621L,62622L,62623L,62624L, +62625L,62626L,62627L,62628L,62629L,62630L,62631L,62632L,62633L,62634L, +62635L,62636L,62637L,62638L,62639L,62640L,62641L,62642L,62643L,62644L, +62645L,62646L,62647L,62648L,62649L,62650L,62651L,62652L,62653L,62654L, +62655L,62656L,62657L,62658L,62659L,62660L,62661L,62662L,62663L,62664L, +62665L,62666L,62667L,62668L,62669L,62670L,62671L,62672L,62673L,62674L, +62675L,62676L,62677L,62678L,62679L,62680L,62681L,62682L,62683L,62684L, +62685L,62686L,62687L,62688L,62689L,62690L,62691L,62692L,62693L,62694L, +62695L,62696L,62697L,62698L,62699L,62700L,62701L,62702L,62703L,62704L, +62705L,62706L,62707L,62708L,62709L,62710L,62711L,62712L,62713L,62714L, +62715L,62716L,62717L,62718L,62719L,62720L,62721L,62722L,62723L,62724L, +62725L,62726L,62727L,62728L,62729L,62730L,62731L,62732L,62733L,62734L, +62735L,62736L,62737L,62738L,62739L,62740L,62741L,62742L,62743L,62744L, +62745L,62746L,62747L,62748L,62749L,62750L,62751L,62752L,62753L,62754L, +62755L,62756L,62757L,62758L,62759L,62760L,62761L,62762L,62763L,62764L, +62765L,62766L,62767L,62768L,62769L,62770L,62771L,62772L,62773L,62774L, +62775L,62776L,62777L,62778L,62779L,62780L,62781L,62782L,62783L,62784L, +62785L,62786L,62787L,62788L,62789L,62790L,62791L,62792L,62793L,62794L, +62795L,62796L,62797L,62798L,62799L,62800L,62801L,62802L,62803L,62804L, +62805L,62806L,62807L,62808L,62809L,62810L,62811L,62812L,62813L,62814L, +62815L,62816L,62817L,62818L,62819L,62820L,62821L,62822L,62823L,62824L, +62825L,62826L,62827L,62828L,62829L,62830L,62831L,62832L,62833L,62834L, +62835L,62836L,62837L,62838L,62839L,62840L,62841L,62842L,62843L,62844L, +62845L,62846L,62847L,62848L,62849L,62850L,62851L,62852L,62853L,62854L, +62855L,62856L,62857L,62858L,62859L,62860L,62861L,62862L,62863L,62864L, +62865L,62866L,62867L,62868L,62869L,62870L,62871L,62872L,62873L,62874L, +62875L,62876L,62877L,62878L,62879L,62880L,62881L,62882L,62883L,62884L, +62885L,62886L,62887L,62888L,62889L,62890L,62891L,62892L,62893L,62894L, +62895L,62896L,62897L,62898L,62899L,62900L,62901L,62902L,62903L,62904L, +62905L,62906L,62907L,62908L,62909L,62910L,62911L,62912L,62913L,62914L, +62915L,62916L,62917L,62918L,62919L,62920L,62921L,62922L,62923L,62924L, +62925L,62926L,62927L,62928L,62929L,62930L,62931L,62932L,62933L,62934L, +62935L,62936L,62937L,62938L,62939L,62940L,62941L,62942L,62943L,62944L, +62945L,62946L,62947L,62948L,62949L,62950L,62951L,62952L,62953L,62954L, +62955L,62956L,62957L,62958L,62959L,62960L,62961L,62962L,62963L,62964L, +62965L,62966L,62967L,62968L,62969L,62970L,62971L,62972L,62973L,62974L, +62975L,62976L,62977L,62978L,62979L,62980L,62981L,62982L,62983L,62984L, +62985L,62986L,62987L,62988L,62989L,62990L,62991L,62992L,62993L,62994L, +62995L,62996L,62997L,62998L,62999L,63000L,63001L,63002L,63003L,63004L, +63005L,63006L,63007L,63008L,63009L,63010L,63011L,63012L,63013L,63014L, +63015L,63016L,63017L,63018L,63019L,63020L,63021L,63022L,63023L,63024L, +63025L,63026L,63027L,63028L,63029L,63030L,63031L,63032L,63033L,63034L, +63035L,63036L,63037L,63038L,63039L,63040L,63041L,63042L,63043L,63044L, +63045L,63046L,63047L,63048L,63049L,63050L,63051L,63052L,63053L,63054L, +63055L,63056L,63057L,63058L,63059L,63060L,63061L,63062L,63063L,63064L, +63065L,63066L,63067L,63068L,63069L,63070L,63071L,63072L,63073L,63074L, +63075L,63076L,63077L,63078L,63079L,63080L,63081L,63082L,63083L,63084L, +63085L,63086L,63087L,63088L,63089L,63090L,63091L,63092L,63093L,63094L, +63095L,63096L,63097L,63098L,63099L,63100L,63101L,63102L,63103L,63104L, +63105L,63106L,63107L,63108L,63109L,63110L,63111L,63112L,63113L,63114L, +63115L,63116L,63117L,63118L,63119L,63120L,63121L,63122L,63123L,63124L, +63125L,63126L,63127L,63128L,63129L,63130L,63131L,63132L,63133L,63134L, +63135L,63136L,63137L,63138L,63139L,63140L,63141L,63142L,63143L,63144L, +63145L,63146L,63147L,63148L,63149L,63150L,63151L,63152L,63153L,63154L, +63155L,63156L,63157L,63158L,63159L,63160L,63161L,63162L,63163L,63164L, +63165L,63166L,63167L,63168L,63169L,63170L,63171L,63172L,63173L,63174L, +63175L,63176L,63177L,63178L,63179L,63180L,63181L,63182L,63183L,63184L, +63185L,63186L,63187L,63188L,63189L,63190L,63191L,63192L,63193L,63194L, +63195L,63196L,63197L,63198L,63199L,63200L,63201L,63202L,63203L,63204L, +63205L,63206L,63207L,63208L,63209L,63210L,63211L,63212L,63213L,63214L, +63215L,63216L,63217L,63218L,63219L,63220L,63221L,63222L,63223L,63224L, +63225L,63226L,63227L,63228L,63229L,63230L,63231L,63232L,63233L,63234L, +63235L,63236L,63237L,63238L,63239L,63240L,63241L,63242L,63243L,63244L, +63245L,63246L,63247L,63248L,63249L,63250L,63251L,63252L,63253L,63254L, +63255L,63256L,63257L,63258L,63259L,63260L,63261L,63262L,63263L,63264L, +63265L,63266L,63267L,63268L,63269L,63270L,63271L,63272L,63273L,63274L, +63275L,63276L,63277L,63278L,63279L,63280L,63281L,63282L,63283L,63284L, +63285L,63286L,63287L,63288L,63289L,63290L,63291L,63292L,63293L,63294L, +63295L,63296L,63297L,63298L,63299L,63300L,63301L,63302L,63303L,63304L, +63305L,63306L,63307L,63308L,63309L,63310L,63311L,63312L,63313L,63314L, +63315L,63316L,63317L,63318L,63319L,63320L,63321L,63322L,63323L,63324L, +63325L,63326L,63327L,63328L,63329L,63330L,63331L,63332L,63333L,63334L, +63335L,63336L,63337L,63338L,63339L,63340L,63341L,63342L,63343L,63344L, +63345L,63346L,63347L,63348L,63349L,63350L,63351L,63352L,63353L,63354L, +63355L,63356L,63357L,63358L,63359L,63360L,63361L,63362L,63363L,63364L, +63365L,63366L,63367L,63368L,63369L,63370L,63371L,63372L,63373L,63374L, +63375L,63376L,63377L,63378L,63379L,63380L,63381L,63382L,63383L,63384L, +63385L,63386L,63387L,63388L,63389L,63390L,63391L,63392L,63393L,63394L, +63395L,63396L,63397L,63398L,63399L,63400L,63401L,63402L,63403L,63404L, +63405L,63406L,63407L,63408L,63409L,63410L,63411L,63412L,63413L,63414L, +63415L,63416L,63417L,63418L,63419L,63420L,63421L,63422L,63423L,63424L, +63425L,63426L,63427L,63428L,63429L,63430L,63431L,63432L,63433L,63434L, +63435L,63436L,63437L,63438L,63439L,63440L,63441L,63442L,63443L,63444L, +63445L,63446L,63447L,63448L,63449L,63450L,63451L,63452L,63453L,63454L, +63455L,63456L,63457L,63458L,63459L,63460L,63461L,63462L,63463L,63464L, +63465L,63466L,63467L,63468L,63469L,63470L,63471L,63472L,63473L,63474L, +63475L,63476L,63477L,63478L,63479L,63480L,63481L,63482L,63483L,63484L, +63485L,63486L,63487L,63488L,63489L,63490L,63491L,63492L,63493L,63494L, +63495L,63496L,63497L,63498L,63499L,63500L,63501L,63502L,63503L,63504L, +63505L,63506L,63507L,63508L,63509L,63510L,63511L,63512L,63513L,63514L, +63515L,63516L,63517L,63518L,63519L,63520L,63521L,63522L,63523L,63524L, +63525L,63526L,63527L,63528L,63529L,63530L,63531L,63532L,63533L,63534L, +63535L,63536L,63537L,63538L,63539L,63540L,63541L,63542L,63543L,63544L, +63545L,63546L,63547L,63548L,63549L,63550L,63551L,63552L,63553L,63554L, +63555L,63556L,63557L,63558L,63559L,63560L,63561L,63562L,63563L,63564L, +63565L,63566L,63567L,63568L,63569L,63570L,63571L,63572L,63573L,63574L, +63575L,63576L,63577L,63578L,63579L,63580L,63581L,63582L,63583L,63584L, +63585L,63586L,63587L,63588L,63589L,63590L,63591L,63592L,63593L,63594L, +63595L,63596L,63597L,63598L,63599L,63600L,63601L,63602L,63603L,63604L, +63605L,63606L,63607L,63608L,63609L,63610L,63611L,63612L,63613L,63614L, +63615L,63616L,63617L,63618L,63619L,63620L,63621L,63622L,63623L,63624L, +63625L,63626L,63627L,63628L,63629L,63630L,63631L,63632L,63633L,63634L, +63635L,63636L,63637L,63638L,63639L,63640L,63641L,63642L,63643L,63644L, +63645L,63646L,63647L,63648L,63649L,63650L,63651L,63652L,63653L,63654L, +63655L,63656L,63657L,63658L,63659L,63660L,63661L,63662L,63663L,63664L, +63665L,63666L,63667L,63668L,63669L,63670L,63671L,63672L,63673L,63674L, +63675L,63676L,63677L,63678L,63679L,63680L,63681L,63682L,63683L,63684L, +63685L,63686L,63687L,63688L,63689L,63690L,63691L,63692L,63693L,63694L, +63695L,63696L,63697L,63698L,63699L,63700L,63701L,63702L,63703L,63704L, +63705L,63706L,63707L,63708L,63709L,63710L,63711L,63712L,63713L,63714L, +63715L,63716L,63717L,63718L,63719L,63720L,63721L,63722L,63723L,63724L, +63725L,63726L,63727L,63728L,63729L,63730L,63731L,63732L,63733L,63734L, +63735L,63736L,63737L,63738L,63739L,63740L,63741L,63742L,63743L,63744L, +63745L,63746L,63747L,63748L,63749L,63750L,63751L,63752L,63753L,63754L, +63755L,63756L,63757L,63758L,63759L,63760L,63761L,63762L,63763L,63764L, +63765L,63766L,63767L,63768L,63769L,63770L,63771L,63772L,63773L,63774L, +63775L,63776L,63777L,63778L,63779L,63780L,63781L,63782L,63783L,63784L, +63785L,63786L,63787L,63788L,63789L,63790L,63791L,63792L,63793L,63794L, +63795L,63796L,63797L,63798L,63799L,63800L,63801L,63802L,63803L,63804L, +63805L,63806L,63807L,63808L,63809L,63810L,63811L,63812L,63813L,63814L, +63815L,63816L,63817L,63818L,63819L,63820L,63821L,63822L,63823L,63824L, +63825L,63826L,63827L,63828L,63829L,63830L,63831L,63832L,63833L,63834L, +63835L,63836L,63837L,63838L,63839L,63840L,63841L,63842L,63843L,63844L, +63845L,63846L,63847L,63848L,63849L,63850L,63851L,63852L,63853L,63854L, +63855L,63856L,63857L,63858L,63859L,63860L,63861L,63862L,63863L,63864L, +63865L,63866L,63867L,63868L,63869L,63870L,63871L,63872L,63873L,63874L, +63875L,63876L,63877L,63878L,63879L,63880L,63881L,63882L,63883L,63884L, +63885L,63886L,63887L,63888L,63889L,63890L,63891L,63892L,63893L,63894L, +63895L,63896L,63897L,63898L,63899L,63900L,63901L,63902L,63903L,63904L, +63905L,63906L,63907L,63908L,63909L,63910L,63911L,63912L,63913L,63914L, +63915L,63916L,63917L,63918L,63919L,63920L,63921L,63922L,63923L,63924L, +63925L,63926L,63927L,63928L,63929L,63930L,63931L,63932L,63933L,63934L, +63935L,63936L,63937L,63938L,63939L,63940L,63941L,63942L,63943L,63944L, +63945L,63946L,63947L,63948L,63949L,63950L,63951L,63952L,63953L,63954L, +63955L,63956L,63957L,63958L,63959L,63960L,63961L,63962L,63963L,63964L, +63965L,63966L,63967L,63968L,63969L,63970L,63971L,63972L,63973L,63974L, +63975L,63976L,63977L,63978L,63979L,63980L,63981L,63982L,63983L,63984L, +63985L,63986L,63987L,63988L,63989L,63990L,63991L,63992L,63993L,63994L, +63995L,63996L,63997L,63998L,63999L,64000L,64001L,64002L,64003L,64004L, +64005L,64006L,64007L,64008L,64009L,64010L,64011L,64012L,64013L,64014L, +64015L,64016L,64017L,64018L,64019L,64020L,64021L,64022L,64023L,64024L, +64025L,64026L,64027L,64028L,64029L,64030L,64031L,64032L,64033L,64034L, +64035L,64036L,64037L,64038L,64039L,64040L,64041L,64042L,64043L,64044L, +64045L,64046L,64047L,64048L,64049L,64050L,64051L,64052L,64053L,64054L, +64055L,64056L,64057L,64058L,64059L,64060L,64061L,64062L,64063L,64064L, +64065L,64066L,64067L,64068L,64069L,64070L,64071L,64072L,64073L,64074L, +64075L,64076L,64077L,64078L,64079L,64080L,64081L,64082L,64083L,64084L, +64085L,64086L,64087L,64088L,64089L,64090L,64091L,64092L,64093L,64094L, +64095L,64096L,64097L,64098L,64099L,64100L,64101L,64102L,64103L,64104L, +64105L,64106L,64107L,64108L,64109L,64110L,64111L,64112L,64113L,64114L, +64115L,64116L,64117L,64118L,64119L,64120L,64121L,64122L,64123L,64124L, +64125L,64126L,64127L,64128L,64129L,64130L,64131L,64132L,64133L,64134L, +64135L,64136L,64137L,64138L,64139L,64140L,64141L,64142L,64143L,64144L, +64145L,64146L,64147L,64148L,64149L,64150L,64151L,64152L,64153L,64154L, +64155L,64156L,64157L,64158L,64159L,64160L,64161L,64162L,64163L,64164L, +64165L,64166L,64167L,64168L,64169L,64170L,64171L,64172L,64173L,64174L, +64175L,64176L,64177L,64178L,64179L,64180L,64181L,64182L,64183L,64184L, +64185L,64186L,64187L,64188L,64189L,64190L,64191L,64192L,64193L,64194L, +64195L,64196L,64197L,64198L,64199L,64200L,64201L,64202L,64203L,64204L, +64205L,64206L,64207L,64208L,64209L,64210L,64211L,64212L,64213L,64214L, +64215L,64216L,64217L,64218L,64219L,64220L,64221L,64222L,64223L,64224L, +64225L,64226L,64227L,64228L,64229L,64230L,64231L,64232L,64233L,64234L, +64235L,64236L,64237L,64238L,64239L,64240L,64241L,64242L,64243L,64244L, +64245L,64246L,64247L,64248L,64249L,64250L,64251L,64252L,64253L,64254L, +64255L,64256L,64257L,64258L,64259L,64260L,64261L,64262L,64263L,64264L, +64265L,64266L,64267L,64268L,64269L,64270L,64271L,64272L,64273L,64274L, +64275L,64276L,64277L,64278L,64279L,64280L,64281L,64282L,64283L,64284L, +64285L,64286L,64287L,64288L,64289L,64290L,64291L,64292L,64293L,64294L, +64295L,64296L,64297L,64298L,64299L,64300L,64301L,64302L,64303L,64304L, +64305L,64306L,64307L,64308L,64309L,64310L,64311L,64312L,64313L,64314L, +64315L,64316L,64317L,64318L,64319L,64320L,64321L,64322L,64323L,64324L, +64325L,64326L,64327L,64328L,64329L,64330L,64331L,64332L,64333L,64334L, +64335L,64336L,64337L,64338L,64339L,64340L,64341L,64342L,64343L,64344L, +64345L,64346L,64347L,64348L,64349L,64350L,64351L,64352L,64353L,64354L, +64355L,64356L,64357L,64358L,64359L,64360L,64361L,64362L,64363L,64364L, +64365L,64366L,64367L,64368L,64369L,64370L,64371L,64372L,64373L,64374L, +64375L,64376L,64377L,64378L,64379L,64380L,64381L,64382L,64383L,64384L, +64385L,64386L,64387L,64388L,64389L,64390L,64391L,64392L,64393L,64394L, +64395L,64396L,64397L,64398L,64399L,64400L,64401L,64402L,64403L,64404L, +64405L,64406L,64407L,64408L,64409L,64410L,64411L,64412L,64413L,64414L, +64415L,64416L,64417L,64418L,64419L,64420L,64421L,64422L,64423L,64424L, +64425L,64426L,64427L,64428L,64429L,64430L,64431L,64432L,64433L,64434L, +64435L,64436L,64437L,64438L,64439L,64440L,64441L,64442L,64443L,64444L, +64445L,64446L,64447L,64448L,64449L,64450L,64451L,64452L,64453L,64454L, +64455L,64456L,64457L,64458L,64459L,64460L,64461L,64462L,64463L,64464L, +64465L,64466L,64467L,64468L,64469L,64470L,64471L,64472L,64473L,64474L, +64475L,64476L,64477L,64478L,64479L,64480L,64481L,64482L,64483L,64484L, +64485L,64486L,64487L,64488L,64489L,64490L,64491L,64492L,64493L,64494L, +64495L,64496L,64497L,64498L,64499L,64500L,64501L,64502L,64503L,64504L, +64505L,64506L,64507L,64508L,64509L,64510L,64511L,64512L,64513L,64514L, +64515L,64516L,64517L,64518L,64519L,64520L,64521L,64522L,64523L,64524L, +64525L,64526L,64527L,64528L,64529L,64530L,64531L,64532L,64533L,64534L, +64535L,64536L,64537L,64538L,64539L,64540L,64541L,64542L,64543L,64544L, +64545L,64546L,64547L,64548L,64549L,64550L,64551L,64552L,64553L,64554L, +64555L,64556L,64557L,64558L,64559L,64560L,64561L,64562L,64563L,64564L, +64565L,64566L,64567L,64568L,64569L,64570L,64571L,64572L,64573L,64574L, +64575L,64576L,64577L,64578L,64579L,64580L,64581L,64582L,64583L,64584L, +64585L,64586L,64587L,64588L,64589L,64590L,64591L,64592L,64593L,64594L, +64595L,64596L,64597L,64598L,64599L,64600L,64601L,64602L,64603L,64604L, +64605L,64606L,64607L,64608L,64609L,64610L,64611L,64612L,64613L,64614L, +64615L,64616L,64617L,64618L,64619L,64620L,64621L,64622L,64623L,64624L, +64625L,64626L,64627L,64628L,64629L,64630L,64631L,64632L,64633L,64634L, +64635L,64636L,64637L,64638L,64639L,64640L,64641L,64642L,64643L,64644L, +64645L,64646L,64647L,64648L,64649L,64650L,64651L,64652L,64653L,64654L, +64655L,64656L,64657L,64658L,64659L,64660L,64661L,64662L,64663L,64664L, +64665L,64666L,64667L,64668L,64669L,64670L,64671L,64672L,64673L,64674L, +64675L,64676L,64677L,64678L,64679L,64680L,64681L,64682L,64683L,64684L, +64685L,64686L,64687L,64688L,64689L,64690L,64691L,64692L,64693L,64694L, +64695L,64696L,64697L,64698L,64699L,64700L,64701L,64702L,64703L,64704L, +64705L,64706L,64707L,64708L,64709L,64710L,64711L,64712L,64713L,64714L, +64715L,64716L,64717L,64718L,64719L,64720L,64721L,64722L,64723L,64724L, +64725L,64726L,64727L,64728L,64729L,64730L,64731L,64732L,64733L,64734L, +64735L,64736L,64737L,64738L,64739L,64740L,64741L,64742L,64743L,64744L, +64745L,64746L,64747L,64748L,64749L,64750L,64751L,64752L,64753L,64754L, +64755L,64756L,64757L,64758L,64759L,64760L,64761L,64762L,64763L,64764L, +64765L,64766L,64767L,64768L,64769L,64770L,64771L,64772L,64773L,64774L, +64775L,64776L,64777L,64778L,64779L,64780L,64781L,64782L,64783L,64784L, +64785L,64786L,64787L,64788L,64789L,64790L,64791L,64792L,64793L,64794L, +64795L,64796L,64797L,64798L,64799L,64800L,64801L,64802L,64803L,64804L, +64805L,64806L,64807L,64808L,64809L,64810L,64811L,64812L,64813L,64814L, +64815L,64816L,64817L,64818L,64819L,64820L,64821L,64822L,64823L,64824L, +64825L,64826L,64827L,64828L,64829L,64830L,64831L,64832L,64833L,64834L, +64835L,64836L,64837L,64838L,64839L,64840L,64841L,64842L,64843L,64844L, +64845L,64846L,64847L,64848L,64849L,64850L,64851L,64852L,64853L,64854L, +64855L,64856L,64857L,64858L,64859L,64860L,64861L,64862L,64863L,64864L, +64865L,64866L,64867L,64868L,64869L,64870L,64871L,64872L,64873L,64874L, +64875L,64876L,64877L,64878L,64879L,64880L,64881L,64882L,64883L,64884L, +64885L,64886L,64887L,64888L,64889L,64890L,64891L,64892L,64893L,64894L, +64895L,64896L,64897L,64898L,64899L,64900L,64901L,64902L,64903L,64904L, +64905L,64906L,64907L,64908L,64909L,64910L,64911L,64912L,64913L,64914L, +64915L,64916L,64917L,64918L,64919L,64920L,64921L,64922L,64923L,64924L, +64925L,64926L,64927L,64928L,64929L,64930L,64931L,64932L,64933L,64934L, +64935L,64936L,64937L,64938L,64939L,64940L,64941L,64942L,64943L,64944L, +64945L,64946L,64947L,64948L,64949L,64950L,64951L,64952L,64953L,64954L, +64955L,64956L,64957L,64958L,64959L,64960L,64961L,64962L,64963L,64964L, +64965L,64966L,64967L,64968L,64969L,64970L,64971L,64972L,64973L,64974L, +64975L,64976L,64977L,64978L,64979L,64980L,64981L,64982L,64983L,64984L, +64985L,64986L,64987L,64988L,64989L,64990L,64991L,64992L,64993L,64994L, +64995L,64996L,64997L,64998L,64999L,65000L,65001L,65002L,65003L,65004L, +65005L,65006L,65007L,65008L,65009L,65010L,65011L,65012L,65013L,65014L, +65015L,65016L,65017L,65018L,65019L,65020L,65021L,65022L,65023L,65024L, +65025L,65026L,65027L,65028L,65029L,65030L,65031L,65032L,65033L,65034L, +65035L,65036L,65037L,65038L,65039L,65040L,65041L,65042L,65043L,65044L, +65045L,65046L,65047L,65048L,65049L,65050L,65051L,65052L,65053L,65054L, +65055L,65056L,65057L,65058L,65059L,65060L,65061L,65062L,65063L,65064L, +65065L,65066L,65067L,65068L,65069L,65070L,65071L,65072L,65073L,65074L, +65075L,65076L,65077L,65078L,65079L,65080L,65081L,65082L,65083L,65084L, +65085L,65086L,65087L,65088L,65089L,65090L,65091L,65092L,65093L,65094L, +65095L,65096L,65097L,65098L,65099L,65100L,65101L,65102L,65103L,65104L, +65105L,65106L,65107L,65108L,65109L,65110L,65111L,65112L,65113L,65114L, +65115L,65116L,65117L,65118L,65119L,65120L,65121L,65122L,65123L,65124L, +65125L,65126L,65127L,65128L,65129L,65130L,65131L,65132L,65133L,65134L, +65135L,65136L,65137L,65138L,65139L,65140L,65141L,65142L,65143L,65144L, +65145L,65146L,65147L,65148L,65149L,65150L,65151L,65152L,65153L,65154L, +65155L,65156L,65157L,65158L,65159L,65160L,65161L,65162L,65163L,65164L, +65165L,65166L,65167L,65168L,65169L,65170L,65171L,65172L,65173L,65174L, +65175L,65176L,65177L,65178L,65179L,65180L,65181L,65182L,65183L,65184L, +65185L,65186L,65187L,65188L,65189L,65190L,65191L,65192L,65193L,65194L, +65195L,65196L,65197L,65198L,65199L,65200L,65201L,65202L,65203L,65204L, +65205L,65206L,65207L,65208L,65209L,65210L,65211L,65212L,65213L,65214L, +65215L,65216L,65217L,65218L,65219L,65220L,65221L,65222L,65223L,65224L, +65225L,65226L,65227L,65228L,65229L,65230L,65231L,65232L,65233L,65234L, +65235L,65236L,65237L,65238L,65239L,65240L,65241L,65242L,65243L,65244L, +65245L,65246L,65247L,65248L,65249L,65250L,65251L,65252L,65253L,65254L, +65255L,65256L,65257L,65258L,65259L,65260L,65261L,65262L,65263L,65264L, +65265L,65266L,65267L,65268L,65269L,65270L,65271L,65272L,65273L,65274L, +65275L,65276L,65277L,65278L,65279L,65280L,65281L,65282L,65283L,65284L, +65285L,65286L,65287L,65288L,65289L,65290L,65291L,65292L,65293L,65294L, +65295L,65296L,65297L,65298L,65299L,65300L,65301L,65302L,65303L,65304L, +65305L,65306L,65307L,65308L,65309L,65310L,65311L,65312L,65313L,65314L, +65315L,65316L,65317L,65318L,65319L,65320L,65321L,65322L,65323L,65324L, +65325L,65326L,65327L,65328L,65329L,65330L,65331L,65332L,65333L,65334L, +65335L,65336L,65337L,65338L,65339L,65340L,65341L,65342L,65343L,65344L, +65313L,65314L,65315L,65316L,65317L,65318L,65319L,65320L,65321L,65322L, +65323L,65324L,65325L,65326L,65327L,65328L,65329L,65330L,65331L,65332L, +65333L,65334L,65335L,65336L,65337L,65338L,65371L,65372L,65373L,65374L, +65375L,65376L,65377L,65378L,65379L,65380L,65381L,65382L,65383L,65384L, +65385L,65386L,65387L,65388L,65389L,65390L,65391L,65392L,65393L,65394L, +65395L,65396L,65397L,65398L,65399L,65400L,65401L,65402L,65403L,65404L, +65405L,65406L,65407L,65408L,65409L,65410L,65411L,65412L,65413L,65414L, +65415L,65416L,65417L,65418L,65419L,65420L,65421L,65422L,65423L,65424L, +65425L,65426L,65427L,65428L,65429L,65430L,65431L,65432L,65433L,65434L, +65435L,65436L,65437L,65438L,65439L,65440L,65441L,65442L,65443L,65444L, +65445L,65446L,65447L,65448L,65449L,65450L,65451L,65452L,65453L,65454L, +65455L,65456L,65457L,65458L,65459L,65460L,65461L,65462L,65463L,65464L, +65465L,65466L,65467L,65468L,65469L,65470L,65471L,65472L,65473L,65474L, +65475L,65476L,65477L,65478L,65479L,65480L,65481L,65482L,65483L,65484L, +65485L,65486L,65487L,65488L,65489L,65490L,65491L,65492L,65493L,65494L, +65495L,65496L,65497L,65498L,65499L,65500L,65501L,65502L,65503L,65504L, +65505L,65506L,65507L,65508L,65509L,65510L,65511L,65512L,65513L,65514L, +65515L,65516L,65517L,65518L,65519L,65520L,65521L,65522L,65523L,65524L, +65525L,65526L,65527L,65528L,65529L,65530L,65531L,65532L,65533L,65534L, +65535L, +}; +#endif + +#if defined(DUK_USE_REGEXP_CANON_BITMAP) +/* + * Automatically generated by extract_caseconv.py, do not edit! + */ + +const duk_uint8_t duk_unicode_re_canon_bitmap[256] = { +23,0,224,19,1,228,255,255,255,255,255,255,255,255,255,255,63,254,255,127, +255,255,255,255,255,255,255,255,231,231,0,16,255,227,255,255,63,255,255, +255,255,255,255,255,1,252,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +227,129,255,255,255,147,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,251, +}; +#endif diff --git a/third_party/duktape/duk_util.h b/third_party/duktape/duk_util.h new file mode 100644 index 00000000..a63eba82 --- /dev/null +++ b/third_party/duktape/duk_util.h @@ -0,0 +1,731 @@ +/* + * Utilities + */ + +#if !defined(DUK_UTIL_H_INCLUDED) +#define DUK_UTIL_H_INCLUDED + +#if defined(DUK_USE_GET_RANDOM_DOUBLE) +#define DUK_UTIL_GET_RANDOM_DOUBLE(thr) DUK_USE_GET_RANDOM_DOUBLE((thr)->heap_udata) +#else +#define DUK_UTIL_GET_RANDOM_DOUBLE(thr) duk_util_tinyrandom_get_double(thr) +#endif + +/* + * Some useful constants + */ + +#define DUK_DOUBLE_2TO32 4294967296.0 +#define DUK_DOUBLE_2TO31 2147483648.0 +#define DUK_DOUBLE_LOG2E 1.4426950408889634 +#define DUK_DOUBLE_LOG10E 0.4342944819032518 + +/* + * Endian conversion + */ + +#if defined(DUK_USE_INTEGER_LE) +#define DUK_HTON32(x) DUK_BSWAP32((x)) +#define DUK_NTOH32(x) DUK_BSWAP32((x)) +#define DUK_HTON16(x) DUK_BSWAP16((x)) +#define DUK_NTOH16(x) DUK_BSWAP16((x)) +#elif defined(DUK_USE_INTEGER_BE) +#define DUK_HTON32(x) (x) +#define DUK_NTOH32(x) (x) +#define DUK_HTON16(x) (x) +#define DUK_NTOH16(x) (x) +#else +#error internal error, endianness defines broken +#endif + +/* + * Bitstream decoder + */ + +struct duk_bitdecoder_ctx { + const duk_uint8_t *data; + duk_size_t offset; + duk_size_t length; + duk_uint32_t currval; + duk_small_int_t currbits; +}; + +#define DUK_BD_BITPACKED_STRING_MAXLEN 256 + +/* + * Bitstream encoder + */ + +struct duk_bitencoder_ctx { + duk_uint8_t *data; + duk_size_t offset; + duk_size_t length; + duk_uint32_t currval; + duk_small_int_t currbits; + duk_small_int_t truncated; +}; + +/* + * Raw write/read macros for big endian, unaligned basic values. + * Caller ensures there's enough space. The INC macro variants + * update the pointer argument automatically. + */ + +#define DUK_RAW_WRITE_U8(ptr,val) do { \ + *(ptr) = (duk_uint8_t) (val); \ + } while (0) +#define DUK_RAW_WRITE_U16_BE(ptr,val) duk_raw_write_u16_be((ptr), (duk_uint16_t) (val)) +#define DUK_RAW_WRITE_U32_BE(ptr,val) duk_raw_write_u32_be((ptr), (duk_uint32_t) (val)) +#define DUK_RAW_WRITE_FLOAT_BE(ptr,val) duk_raw_write_float_be((ptr), (duk_float_t) (val)) +#define DUK_RAW_WRITE_DOUBLE_BE(ptr,val) duk_raw_write_double_be((ptr), (duk_double_t) (val)) +#define DUK_RAW_WRITE_XUTF8(ptr,val) duk_raw_write_xutf8((ptr), (duk_ucodepoint_t) (val)) + +#define DUK_RAW_WRITEINC_U8(ptr,val) do { \ + *(ptr)++ = (duk_uint8_t) (val); \ + } while (0) +#define DUK_RAW_WRITEINC_U16_BE(ptr,val) duk_raw_writeinc_u16_be(&(ptr), (duk_uint16_t) (val)) +#define DUK_RAW_WRITEINC_U32_BE(ptr,val) duk_raw_writeinc_u32_be(&(ptr), (duk_uint32_t) (val)) +#define DUK_RAW_WRITEINC_FLOAT_BE(ptr,val) duk_raw_writeinc_float_be(&(ptr), (duk_float_t) (val)) +#define DUK_RAW_WRITEINC_DOUBLE_BE(ptr,val) duk_raw_writeinc_double_be(&(ptr), (duk_double_t) (val)) +#define DUK_RAW_WRITEINC_XUTF8(ptr,val) duk_raw_writeinc_xutf8(&(ptr), (duk_ucodepoint_t) (val)) +#define DUK_RAW_WRITEINC_CESU8(ptr,val) duk_raw_writeinc_cesu8(&(ptr), (duk_ucodepoint_t) (val)) + +#define DUK_RAW_READ_U8(ptr) ((duk_uint8_t) (*(ptr))) +#define DUK_RAW_READ_U16_BE(ptr) duk_raw_read_u16_be((ptr)); +#define DUK_RAW_READ_U32_BE(ptr) duk_raw_read_u32_be((ptr)); +#define DUK_RAW_READ_DOUBLE_BE(ptr) duk_raw_read_double_be((ptr)); + +#define DUK_RAW_READINC_U8(ptr) ((duk_uint8_t) (*(ptr)++)) +#define DUK_RAW_READINC_U16_BE(ptr) duk_raw_readinc_u16_be(&(ptr)); +#define DUK_RAW_READINC_U32_BE(ptr) duk_raw_readinc_u32_be(&(ptr)); +#define DUK_RAW_READINC_DOUBLE_BE(ptr) duk_raw_readinc_double_be(&(ptr)); + +/* + * Double and float byte order operations. + */ + +DUK_INTERNAL_DECL void duk_dblunion_host_to_little(duk_double_union *u); +DUK_INTERNAL_DECL void duk_dblunion_little_to_host(duk_double_union *u); +DUK_INTERNAL_DECL void duk_dblunion_host_to_big(duk_double_union *u); +DUK_INTERNAL_DECL void duk_dblunion_big_to_host(duk_double_union *u); +DUK_INTERNAL_DECL void duk_fltunion_host_to_big(duk_float_union *u); +DUK_INTERNAL_DECL void duk_fltunion_big_to_host(duk_float_union *u); + +/* + * Buffer writer (dynamic buffer only) + * + * Helper for writing to a dynamic buffer with a concept of a "slack" area + * to reduce resizes. You can ensure there is enough space beforehand and + * then write for a while without further checks, relying on a stable data + * pointer. Slack handling is automatic so call sites only indicate how + * much data they need right now. + * + * There are several ways to write using bufwriter. The best approach + * depends mainly on how much performance matters over code footprint. + * The key issues are (1) ensuring there is space and (2) keeping the + * pointers consistent. Fast code should ensure space for multiple writes + * with one ensure call. Fastest inner loop code can temporarily borrow + * the 'p' pointer but must write it back eventually. + * + * Be careful to ensure all macro arguments (other than static pointers like + * 'thr' and 'bw_ctx') are evaluated exactly once, using temporaries if + * necessary (if that's not possible, there should be a note near the macro). + * Buffer write arguments often contain arithmetic etc so this is + * particularly important here. + */ + +/* XXX: Migrate bufwriter and other read/write helpers to its own header? */ + +struct duk_bufwriter_ctx { + duk_uint8_t *p; + duk_uint8_t *p_base; + duk_uint8_t *p_limit; + duk_hbuffer_dynamic *buf; +}; + +#if defined(DUK_USE_PREFER_SIZE) +#define DUK_BW_SLACK_ADD 64 +#define DUK_BW_SLACK_SHIFT 4 /* 2^4 -> 1/16 = 6.25% slack */ +#else +#define DUK_BW_SLACK_ADD 64 +#define DUK_BW_SLACK_SHIFT 2 /* 2^2 -> 1/4 = 25% slack */ +#endif + +/* Initialization and finalization (compaction), converting to other types. */ + +#define DUK_BW_INIT_PUSHBUF(thr,bw_ctx,sz) do { \ + duk_bw_init_pushbuf((thr), (bw_ctx), (sz)); \ + } while (0) +#define DUK_BW_INIT_WITHBUF(thr,bw_ctx,buf) do { \ + duk_bw_init((thr), (bw_ctx), (buf)); \ + } while (0) +#define DUK_BW_COMPACT(thr,bw_ctx) do { \ + /* Make underlying buffer compact to match DUK_BW_GET_SIZE(). */ \ + duk_bw_compact((thr), (bw_ctx)); \ + } while (0) +#define DUK_BW_PUSH_AS_STRING(thr,bw_ctx) do { \ + duk_push_lstring((thr), \ + (const char *) (bw_ctx)->p_base, \ + (duk_size_t) ((bw_ctx)->p - (bw_ctx)->p_base)); \ + } while (0) + +/* Pointers may be NULL for a while when 'buf' size is zero and before any + * ENSURE calls have been made. Once an ENSURE has been made, the pointers + * are required to be non-NULL so that it's always valid to use memcpy() and + * memmove(), even for zero size. + */ +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL_DECL void duk_bw_assert_valid(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx); +#define DUK_BW_ASSERT_VALID_EXPR(thr,bw_ctx) (duk_bw_assert_valid((thr), (bw_ctx))) +#define DUK_BW_ASSERT_VALID(thr,bw_ctx) do { duk_bw_assert_valid((thr), (bw_ctx)); } while (0) +#else +#define DUK_BW_ASSERT_VALID_EXPR(thr,bw_ctx) DUK_ASSERT_EXPR(1) +#define DUK_BW_ASSERT_VALID(thr,bw_ctx) do {} while (0) +#endif + +/* Working with the pointer and current size. */ + +#define DUK_BW_GET_PTR(thr,bw_ctx) \ + ((bw_ctx)->p) +#define DUK_BW_SET_PTR(thr,bw_ctx,ptr) do { \ + (bw_ctx)->p = (ptr); \ + } while (0) +#define DUK_BW_ADD_PTR(thr,bw_ctx,delta) do { \ + (bw_ctx)->p += (delta); \ + } while (0) +#define DUK_BW_GET_BASEPTR(thr,bw_ctx) \ + ((bw_ctx)->p_base) +#define DUK_BW_GET_LIMITPTR(thr,bw_ctx) \ + ((bw_ctx)->p_limit) +#define DUK_BW_GET_SIZE(thr,bw_ctx) \ + ((duk_size_t) ((bw_ctx)->p - (bw_ctx)->p_base)) +#define DUK_BW_SET_SIZE(thr,bw_ctx,sz) do { \ + DUK_ASSERT((duk_size_t) (sz) <= (duk_size_t) ((bw_ctx)->p - (bw_ctx)->p_base)); \ + (bw_ctx)->p = (bw_ctx)->p_base + (sz); \ + } while (0) +#define DUK_BW_RESET_SIZE(thr,bw_ctx) do { \ + /* Reset to zero size, keep current limit. */ \ + (bw_ctx)->p = (bw_ctx)->p_base; \ + } while (0) +#define DUK_BW_GET_BUFFER(thr,bw_ctx) \ + ((bw_ctx)->buf) + +/* Ensuring (reserving) space. */ + +#define DUK_BW_ENSURE(thr,bw_ctx,sz) do { \ + duk_size_t duk__sz, duk__space; \ + DUK_BW_ASSERT_VALID((thr), (bw_ctx)); \ + duk__sz = (sz); \ + duk__space = (duk_size_t) ((bw_ctx)->p_limit - (bw_ctx)->p); \ + if (duk__space < duk__sz) { \ + (void) duk_bw_resize((thr), (bw_ctx), duk__sz); \ + } \ + } while (0) +/* NOTE: Multiple evaluation of 'ptr' in this macro. */ +/* XXX: Rework to use an always-inline function? */ +#define DUK_BW_ENSURE_RAW(thr,bw_ctx,sz,ptr) \ + (((duk_size_t) ((bw_ctx)->p_limit - (ptr)) >= (sz)) ? \ + (ptr) : \ + ((bw_ctx)->p = (ptr), duk_bw_resize((thr),(bw_ctx),(sz)))) +#define DUK_BW_ENSURE_GETPTR(thr,bw_ctx,sz) \ + DUK_BW_ENSURE_RAW((thr), (bw_ctx), (sz), (bw_ctx)->p) +#define DUK_BW_ASSERT_SPACE_EXPR(thr,bw_ctx,sz) \ + (DUK_BW_ASSERT_VALID_EXPR((thr), (bw_ctx)), \ + DUK_ASSERT_EXPR((duk_size_t) ((bw_ctx)->p_limit - (bw_ctx)->p) >= (duk_size_t) (sz))) +#define DUK_BW_ASSERT_SPACE(thr,bw_ctx,sz) do { \ + DUK_BW_ASSERT_SPACE_EXPR((thr), (bw_ctx), (sz)); \ + } while (0) + +/* Miscellaneous. */ + +#define DUK_BW_SETPTR_AND_COMPACT(thr,bw_ctx,ptr) do { \ + (bw_ctx)->p = (ptr); \ + duk_bw_compact((thr), (bw_ctx)); \ + } while (0) + +/* Fast write calls which assume you control the slack beforehand. + * Multibyte write variants exist and use a temporary write pointer + * because byte writes alias with anything: with a stored pointer + * explicit pointer load/stores get generated (e.g. gcc -Os). + */ + +#define DUK_BW_WRITE_RAW_U8(thr,bw_ctx,val) do { \ + DUK_BW_ASSERT_SPACE((thr), (bw_ctx), 1); \ + *(bw_ctx)->p++ = (duk_uint8_t) (val); \ + } while (0) +#define DUK_BW_WRITE_RAW_U8_2(thr,bw_ctx,val1,val2) do { \ + duk_uint8_t *duk__p; \ + DUK_BW_ASSERT_SPACE((thr), (bw_ctx), 2); \ + duk__p = (bw_ctx)->p; \ + *duk__p++ = (duk_uint8_t) (val1); \ + *duk__p++ = (duk_uint8_t) (val2); \ + (bw_ctx)->p = duk__p; \ + } while (0) +#define DUK_BW_WRITE_RAW_U8_3(thr,bw_ctx,val1,val2,val3) do { \ + duk_uint8_t *duk__p; \ + DUK_BW_ASSERT_SPACE((thr), (bw_ctx), 3); \ + duk__p = (bw_ctx)->p; \ + *duk__p++ = (duk_uint8_t) (val1); \ + *duk__p++ = (duk_uint8_t) (val2); \ + *duk__p++ = (duk_uint8_t) (val3); \ + (bw_ctx)->p = duk__p; \ + } while (0) +#define DUK_BW_WRITE_RAW_U8_4(thr,bw_ctx,val1,val2,val3,val4) do { \ + duk_uint8_t *duk__p; \ + DUK_BW_ASSERT_SPACE((thr), (bw_ctx), 4); \ + duk__p = (bw_ctx)->p; \ + *duk__p++ = (duk_uint8_t) (val1); \ + *duk__p++ = (duk_uint8_t) (val2); \ + *duk__p++ = (duk_uint8_t) (val3); \ + *duk__p++ = (duk_uint8_t) (val4); \ + (bw_ctx)->p = duk__p; \ + } while (0) +#define DUK_BW_WRITE_RAW_U8_5(thr,bw_ctx,val1,val2,val3,val4,val5) do { \ + duk_uint8_t *duk__p; \ + DUK_BW_ASSERT_SPACE((thr), (bw_ctx), 5); \ + duk__p = (bw_ctx)->p; \ + *duk__p++ = (duk_uint8_t) (val1); \ + *duk__p++ = (duk_uint8_t) (val2); \ + *duk__p++ = (duk_uint8_t) (val3); \ + *duk__p++ = (duk_uint8_t) (val4); \ + *duk__p++ = (duk_uint8_t) (val5); \ + (bw_ctx)->p = duk__p; \ + } while (0) +#define DUK_BW_WRITE_RAW_U8_6(thr,bw_ctx,val1,val2,val3,val4,val5,val6) do { \ + duk_uint8_t *duk__p; \ + DUK_BW_ASSERT_SPACE((thr), (bw_ctx), 6); \ + duk__p = (bw_ctx)->p; \ + *duk__p++ = (duk_uint8_t) (val1); \ + *duk__p++ = (duk_uint8_t) (val2); \ + *duk__p++ = (duk_uint8_t) (val3); \ + *duk__p++ = (duk_uint8_t) (val4); \ + *duk__p++ = (duk_uint8_t) (val5); \ + *duk__p++ = (duk_uint8_t) (val6); \ + (bw_ctx)->p = duk__p; \ + } while (0) +#define DUK_BW_WRITE_RAW_XUTF8(thr,bw_ctx,cp) do { \ + duk_ucodepoint_t duk__cp; \ + duk_small_int_t duk__enc_len; \ + duk__cp = (duk_ucodepoint_t) (cp); \ + DUK_BW_ASSERT_SPACE((thr), (bw_ctx), duk_unicode_get_xutf8_length(duk__cp)); \ + duk__enc_len = duk_unicode_encode_xutf8(duk__cp, (bw_ctx)->p); \ + (bw_ctx)->p += duk__enc_len; \ + } while (0) +#define DUK_BW_WRITE_RAW_CESU8(thr,bw_ctx,cp) do { \ + duk_ucodepoint_t duk__cp; \ + duk_small_int_t duk__enc_len; \ + duk__cp = (duk_ucodepoint_t) (cp); \ + DUK_BW_ASSERT_SPACE((thr), (bw_ctx), duk_unicode_get_cesu8_length(duk__cp)); \ + duk__enc_len = duk_unicode_encode_cesu8(duk__cp, (bw_ctx)->p); \ + (bw_ctx)->p += duk__enc_len; \ + } while (0) +/* XXX: add temporary duk__p pointer here too; sharing */ +/* XXX: avoid unsafe variants */ +#define DUK_BW_WRITE_RAW_BYTES(thr,bw_ctx,valptr,valsz) do { \ + const void *duk__valptr; \ + duk_size_t duk__valsz; \ + duk__valptr = (const void *) (valptr); \ + duk__valsz = (duk_size_t) (valsz); \ + duk_memcpy_unsafe((void *) ((bw_ctx)->p), duk__valptr, duk__valsz); \ + (bw_ctx)->p += duk__valsz; \ + } while (0) +#define DUK_BW_WRITE_RAW_CSTRING(thr,bw_ctx,val) do { \ + const duk_uint8_t *duk__val; \ + duk_size_t duk__val_len; \ + duk__val = (const duk_uint8_t *) (val); \ + duk__val_len = DUK_STRLEN((const char *) duk__val); \ + duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) duk__val, duk__val_len); \ + (bw_ctx)->p += duk__val_len; \ + } while (0) +#define DUK_BW_WRITE_RAW_HSTRING(thr,bw_ctx,val) do { \ + duk_size_t duk__val_len; \ + duk__val_len = DUK_HSTRING_GET_BYTELEN((val)); \ + duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HSTRING_GET_DATA((val)), duk__val_len); \ + (bw_ctx)->p += duk__val_len; \ + } while (0) +#define DUK_BW_WRITE_RAW_HBUFFER(thr,bw_ctx,val) do { \ + duk_size_t duk__val_len; \ + duk__val_len = DUK_HBUFFER_GET_SIZE((val)); \ + duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \ + (bw_ctx)->p += duk__val_len; \ + } while (0) +#define DUK_BW_WRITE_RAW_HBUFFER_FIXED(thr,bw_ctx,val) do { \ + duk_size_t duk__val_len; \ + duk__val_len = DUK_HBUFFER_FIXED_GET_SIZE((val)); \ + duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_FIXED_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \ + (bw_ctx)->p += duk__val_len; \ + } while (0) +#define DUK_BW_WRITE_RAW_HBUFFER_DYNAMIC(thr,bw_ctx,val) do { \ + duk_size_t duk__val_len; \ + duk__val_len = DUK_HBUFFER_DYNAMIC_GET_SIZE((val)); \ + duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \ + (bw_ctx)->p += duk__val_len; \ + } while (0) + +/* Append bytes from a slice already in the buffer. */ +#define DUK_BW_WRITE_RAW_SLICE(thr,bw,dst_off,dst_len) \ + duk_bw_write_raw_slice((thr), (bw), (dst_off), (dst_len)) + +/* Insert bytes in the middle of the buffer from an external buffer. */ +#define DUK_BW_INSERT_RAW_BYTES(thr,bw,dst_off,buf,len) \ + duk_bw_insert_raw_bytes((thr), (bw), (dst_off), (buf), (len)) + +/* Insert bytes in the middle of the buffer from a slice already + * in the buffer. Source offset is interpreted "before" the operation. + */ +#define DUK_BW_INSERT_RAW_SLICE(thr,bw,dst_off,src_off,len) \ + duk_bw_insert_raw_slice((thr), (bw), (dst_off), (src_off), (len)) + +/* Insert a reserved area somewhere in the buffer; caller fills it. + * Evaluates to a (duk_uint_t *) pointing to the start of the reserved + * area for convenience. + */ +#define DUK_BW_INSERT_RAW_AREA(thr,bw,off,len) \ + duk_bw_insert_raw_area((thr), (bw), (off), (len)) + +/* Remove a slice from inside buffer. */ +#define DUK_BW_REMOVE_RAW_SLICE(thr,bw,off,len) \ + duk_bw_remove_raw_slice((thr), (bw), (off), (len)) + +/* Safe write calls which will ensure space first. */ + +#define DUK_BW_WRITE_ENSURE_U8(thr,bw_ctx,val) do { \ + DUK_BW_ENSURE((thr), (bw_ctx), 1); \ + DUK_BW_WRITE_RAW_U8((thr), (bw_ctx), (val)); \ + } while (0) +#define DUK_BW_WRITE_ENSURE_U8_2(thr,bw_ctx,val1,val2) do { \ + DUK_BW_ENSURE((thr), (bw_ctx), 2); \ + DUK_BW_WRITE_RAW_U8_2((thr), (bw_ctx), (val1), (val2)); \ + } while (0) +#define DUK_BW_WRITE_ENSURE_U8_3(thr,bw_ctx,val1,val2,val3) do { \ + DUK_BW_ENSURE((thr), (bw_ctx), 3); \ + DUK_BW_WRITE_RAW_U8_3((thr), (bw_ctx), (val1), (val2), (val3)); \ + } while (0) +#define DUK_BW_WRITE_ENSURE_U8_4(thr,bw_ctx,val1,val2,val3,val4) do { \ + DUK_BW_ENSURE((thr), (bw_ctx), 4); \ + DUK_BW_WRITE_RAW_U8_4((thr), (bw_ctx), (val1), (val2), (val3), (val4)); \ + } while (0) +#define DUK_BW_WRITE_ENSURE_U8_5(thr,bw_ctx,val1,val2,val3,val4,val5) do { \ + DUK_BW_ENSURE((thr), (bw_ctx), 5); \ + DUK_BW_WRITE_RAW_U8_5((thr), (bw_ctx), (val1), (val2), (val3), (val4), (val5)); \ + } while (0) +#define DUK_BW_WRITE_ENSURE_U8_6(thr,bw_ctx,val1,val2,val3,val4,val5,val6) do { \ + DUK_BW_ENSURE((thr), (bw_ctx), 6); \ + DUK_BW_WRITE_RAW_U8_6((thr), (bw_ctx), (val1), (val2), (val3), (val4), (val5), (val6)); \ + } while (0) +#define DUK_BW_WRITE_ENSURE_XUTF8(thr,bw_ctx,cp) do { \ + DUK_BW_ENSURE((thr), (bw_ctx), DUK_UNICODE_MAX_XUTF8_LENGTH); \ + DUK_BW_WRITE_RAW_XUTF8((thr), (bw_ctx), (cp)); \ + } while (0) +#define DUK_BW_WRITE_ENSURE_CESU8(thr,bw_ctx,cp) do { \ + DUK_BW_ENSURE((thr), (bw_ctx), DUK_UNICODE_MAX_CESU8_LENGTH); \ + DUK_BW_WRITE_RAW_CESU8((thr), (bw_ctx), (cp)); \ + } while (0) +/* XXX: add temporary duk__p pointer here too; sharing */ +/* XXX: avoid unsafe */ +#define DUK_BW_WRITE_ENSURE_BYTES(thr,bw_ctx,valptr,valsz) do { \ + const void *duk__valptr; \ + duk_size_t duk__valsz; \ + duk__valptr = (const void *) (valptr); \ + duk__valsz = (duk_size_t) (valsz); \ + DUK_BW_ENSURE((thr), (bw_ctx), duk__valsz); \ + duk_memcpy_unsafe((void *) ((bw_ctx)->p), duk__valptr, duk__valsz); \ + (bw_ctx)->p += duk__valsz; \ + } while (0) +#define DUK_BW_WRITE_ENSURE_CSTRING(thr,bw_ctx,val) do { \ + const duk_uint8_t *duk__val; \ + duk_size_t duk__val_len; \ + duk__val = (const duk_uint8_t *) (val); \ + duk__val_len = DUK_STRLEN((const char *) duk__val); \ + DUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \ + duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) duk__val, duk__val_len); \ + (bw_ctx)->p += duk__val_len; \ + } while (0) +#define DUK_BW_WRITE_ENSURE_HSTRING(thr,bw_ctx,val) do { \ + duk_size_t duk__val_len; \ + duk__val_len = DUK_HSTRING_GET_BYTELEN((val)); \ + DUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \ + duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HSTRING_GET_DATA((val)), duk__val_len); \ + (bw_ctx)->p += duk__val_len; \ + } while (0) +#define DUK_BW_WRITE_ENSURE_HBUFFER(thr,bw_ctx,val) do { \ + duk_size_t duk__val_len; \ + duk__val_len = DUK_HBUFFER_GET_SIZE((val)); \ + DUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \ + duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \ + (bw_ctx)->p += duk__val_len; \ + } while (0) +#define DUK_BW_WRITE_ENSURE_HBUFFER_FIXED(thr,bw_ctx,val) do { \ + duk_size_t duk__val_len; \ + duk__val_len = DUK_HBUFFER_FIXED_GET_SIZE((val)); \ + DUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \ + duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_FIXED_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \ + (bw_ctx)->p += duk__val_len; \ + } while (0) +#define DUK_BW_WRITE_ENSURE_HBUFFER_DYNAMIC(thr,bw_ctx,val) do { \ + duk_size_t duk__val_len; \ + duk__val_len = DUK_HBUFFER_DYNAMIC_GET_SIZE((val)); \ + DUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \ + duk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \ + (bw_ctx)->p += duk__val_len; \ + } while (0) + +#define DUK_BW_WRITE_ENSURE_SLICE(thr,bw,dst_off,dst_len) \ + duk_bw_write_ensure_slice((thr), (bw), (dst_off), (dst_len)) +#define DUK_BW_INSERT_ENSURE_BYTES(thr,bw,dst_off,buf,len) \ + duk_bw_insert_ensure_bytes((thr), (bw), (dst_off), (buf), (len)) +#define DUK_BW_INSERT_ENSURE_SLICE(thr,bw,dst_off,src_off,len) \ + duk_bw_insert_ensure_slice((thr), (bw), (dst_off), (src_off), (len)) +#define DUK_BW_INSERT_ENSURE_AREA(thr,bw,off,len) \ + /* Evaluates to (duk_uint8_t *) pointing to start of area. */ \ + duk_bw_insert_ensure_area((thr), (bw), (off), (len)) +#define DUK_BW_REMOVE_ENSURE_SLICE(thr,bw,off,len) \ + /* No difference between raw/ensure because the buffer shrinks. */ \ + DUK_BW_REMOVE_RAW_SLICE((thr), (bw), (off), (len)) + +/* + * Externs and prototypes + */ + +#if !defined(DUK_SINGLE_FILE) +DUK_INTERNAL_DECL const duk_uint8_t duk_lc_digits[36]; +DUK_INTERNAL_DECL const duk_uint8_t duk_uc_nybbles[16]; +DUK_INTERNAL_DECL const duk_int8_t duk_hex_dectab[256]; +#if defined(DUK_USE_HEX_FASTPATH) +DUK_INTERNAL_DECL const duk_int16_t duk_hex_dectab_shift4[256]; +DUK_INTERNAL_DECL const duk_uint16_t duk_hex_enctab[256]; +#endif +#endif /* !DUK_SINGLE_FILE */ + +/* Note: assumes that duk_util_probe_steps size is 32 */ +#if defined(DUK_USE_HOBJECT_HASH_PART) +#if !defined(DUK_SINGLE_FILE) +DUK_INTERNAL_DECL duk_uint8_t duk_util_probe_steps[32]; +#endif /* !DUK_SINGLE_FILE */ +#endif + +#if defined(DUK_USE_STRHASH_DENSE) +DUK_INTERNAL_DECL duk_uint32_t duk_util_hashbytes(const duk_uint8_t *data, duk_size_t len, duk_uint32_t seed); +#endif + +DUK_INTERNAL_DECL duk_uint32_t duk_bd_decode(duk_bitdecoder_ctx *ctx, duk_small_int_t bits); +DUK_INTERNAL_DECL duk_small_uint_t duk_bd_decode_flag(duk_bitdecoder_ctx *ctx); +DUK_INTERNAL_DECL duk_uint32_t duk_bd_decode_flagged(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_uint32_t def_value); +DUK_INTERNAL_DECL duk_int32_t duk_bd_decode_flagged_signed(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_int32_t def_value); +DUK_INTERNAL_DECL duk_uint32_t duk_bd_decode_varuint(duk_bitdecoder_ctx *ctx); +DUK_INTERNAL_DECL duk_small_uint_t duk_bd_decode_bitpacked_string(duk_bitdecoder_ctx *bd, duk_uint8_t *out); + +DUK_INTERNAL_DECL void duk_be_encode(duk_bitencoder_ctx *ctx, duk_uint32_t data, duk_small_int_t bits); +DUK_INTERNAL_DECL void duk_be_finish(duk_bitencoder_ctx *ctx); + +#if !defined(DUK_USE_GET_RANDOM_DOUBLE) +DUK_INTERNAL_DECL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr); +DUK_INTERNAL_DECL void duk_util_tinyrandom_prepare_seed(duk_hthread *thr); +#endif + +DUK_INTERNAL_DECL void duk_bw_init(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_hbuffer_dynamic *h_buf); +DUK_INTERNAL_DECL void duk_bw_init_pushbuf(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t buf_size); +DUK_INTERNAL_DECL duk_uint8_t *duk_bw_resize(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t sz); +DUK_INTERNAL_DECL void duk_bw_compact(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx); +DUK_INTERNAL_DECL void duk_bw_write_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len); +DUK_INTERNAL_DECL void duk_bw_write_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len); +DUK_INTERNAL_DECL void duk_bw_insert_raw_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len); +DUK_INTERNAL_DECL void duk_bw_insert_ensure_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len); +DUK_INTERNAL_DECL void duk_bw_insert_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len); +DUK_INTERNAL_DECL void duk_bw_insert_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len); +DUK_INTERNAL_DECL duk_uint8_t *duk_bw_insert_raw_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len); +DUK_INTERNAL_DECL duk_uint8_t *duk_bw_insert_ensure_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len); +DUK_INTERNAL_DECL void duk_bw_remove_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len); +/* No duk_bw_remove_ensure_slice(), functionality would be identical. */ + +DUK_INTERNAL_DECL duk_uint16_t duk_raw_read_u16_be(const duk_uint8_t *p); +DUK_INTERNAL_DECL duk_uint32_t duk_raw_read_u32_be(const duk_uint8_t *p); +DUK_INTERNAL_DECL duk_float_t duk_raw_read_float_be(const duk_uint8_t *p); +DUK_INTERNAL_DECL duk_double_t duk_raw_read_double_be(const duk_uint8_t *p); +DUK_INTERNAL_DECL duk_uint16_t duk_raw_readinc_u16_be(const duk_uint8_t **p); +DUK_INTERNAL_DECL duk_uint32_t duk_raw_readinc_u32_be(const duk_uint8_t **p); +DUK_INTERNAL_DECL duk_float_t duk_raw_readinc_float_be(const duk_uint8_t **p); +DUK_INTERNAL_DECL duk_double_t duk_raw_readinc_double_be(const duk_uint8_t **p); +DUK_INTERNAL_DECL void duk_raw_write_u16_be(duk_uint8_t *p, duk_uint16_t val); +DUK_INTERNAL_DECL void duk_raw_write_u32_be(duk_uint8_t *p, duk_uint32_t val); +DUK_INTERNAL_DECL void duk_raw_write_float_be(duk_uint8_t *p, duk_float_t val); +DUK_INTERNAL_DECL void duk_raw_write_double_be(duk_uint8_t *p, duk_double_t val); +DUK_INTERNAL_DECL duk_small_int_t duk_raw_write_xutf8(duk_uint8_t *p, duk_ucodepoint_t val); +DUK_INTERNAL_DECL duk_small_int_t duk_raw_write_cesu8(duk_uint8_t *p, duk_ucodepoint_t val); +DUK_INTERNAL_DECL void duk_raw_writeinc_u16_be(duk_uint8_t **p, duk_uint16_t val); +DUK_INTERNAL_DECL void duk_raw_writeinc_u32_be(duk_uint8_t **p, duk_uint32_t val); +DUK_INTERNAL_DECL void duk_raw_writeinc_float_be(duk_uint8_t **p, duk_float_t val); +DUK_INTERNAL_DECL void duk_raw_writeinc_double_be(duk_uint8_t **p, duk_double_t val); +DUK_INTERNAL_DECL void duk_raw_writeinc_xutf8(duk_uint8_t **p, duk_ucodepoint_t val); +DUK_INTERNAL_DECL void duk_raw_writeinc_cesu8(duk_uint8_t **p, duk_ucodepoint_t val); + +#if defined(DUK_USE_DEBUGGER_SUPPORT) /* For now only needed by the debugger. */ +DUK_INTERNAL_DECL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len); +#endif + +/* memcpy(), memmove() etc wrappers. The plain variants like duk_memcpy() + * assume C99+ and 'src' and 'dst' pointers must be non-NULL even when the + * operation size is zero. The unsafe variants like duk_memcpy_safe() deal + * with the zero size case explicitly, and allow NULL pointers in that case + * (which is undefined behavior in C99+). For the majority of actual targets + * a NULL pointer with a zero length is fine in practice. These wrappers are + * macros to force inlining; because there are hundreds of call sites, even a + * few extra bytes per call site adds up to ~1kB footprint. + */ +#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR) +#define duk_memcpy(dst,src,len) do { \ + void *duk__dst = (dst); \ + const void *duk__src = (src); \ + duk_size_t duk__len = (len); \ + DUK_ASSERT(duk__dst != NULL || duk__len == 0U); \ + DUK_ASSERT(duk__src != NULL || duk__len == 0U); \ + (void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \ + } while (0) +#define duk_memcpy_unsafe(dst,src,len) duk_memcpy((dst), (src), (len)) +#define duk_memmove(dst,src,len) do { \ + void *duk__dst = (dst); \ + const void *duk__src = (src); \ + duk_size_t duk__len = (len); \ + DUK_ASSERT(duk__dst != NULL || duk__len == 0U); \ + DUK_ASSERT(duk__src != NULL || duk__len == 0U); \ + (void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \ + } while (0) +#define duk_memmove_unsafe(dst,src,len) duk_memmove((dst), (src), (len)) +#define duk_memset(dst,val,len) do { \ + void *duk__dst = (dst); \ + duk_small_int_t duk__val = (val); \ + duk_size_t duk__len = (len); \ + DUK_ASSERT(duk__dst != NULL || duk__len == 0U); \ + (void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \ + } while (0) +#define duk_memset_unsafe(dst,val,len) duk_memset((dst), (val), (len)) +#define duk_memzero(dst,len) do { \ + void *duk__dst = (dst); \ + duk_size_t duk__len = (len); \ + DUK_ASSERT(duk__dst != NULL || duk__len == 0U); \ + (void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \ + } while (0) +#define duk_memzero_unsafe(dst,len) duk_memzero((dst), (len)) +#else /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */ +#define duk_memcpy(dst,src,len) do { \ + void *duk__dst = (dst); \ + const void *duk__src = (src); \ + duk_size_t duk__len = (len); \ + DUK_ASSERT(duk__dst != NULL); \ + DUK_ASSERT(duk__src != NULL); \ + (void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \ + } while (0) +#define duk_memcpy_unsafe(dst,src,len) do { \ + void *duk__dst = (dst); \ + const void *duk__src = (src); \ + duk_size_t duk__len = (len); \ + DUK_ASSERT(duk__dst != NULL || duk__len == 0U); \ + DUK_ASSERT(duk__src != NULL || duk__len == 0U); \ + if (DUK_LIKELY(duk__len > 0U)) { \ + DUK_ASSERT(duk__dst != NULL); \ + DUK_ASSERT(duk__src != NULL); \ + (void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \ + } \ + } while (0) +#define duk_memmove(dst,src,len) do { \ + void *duk__dst = (dst); \ + const void *duk__src = (src); \ + duk_size_t duk__len = (len); \ + DUK_ASSERT(duk__dst != NULL); \ + DUK_ASSERT(duk__src != NULL); \ + (void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \ + } while (0) +#define duk_memmove_unsafe(dst,src,len) do { \ + void *duk__dst = (dst); \ + const void *duk__src = (src); \ + duk_size_t duk__len = (len); \ + DUK_ASSERT(duk__dst != NULL || duk__len == 0U); \ + DUK_ASSERT(duk__src != NULL || duk__len == 0U); \ + if (DUK_LIKELY(duk__len > 0U)) { \ + DUK_ASSERT(duk__dst != NULL); \ + DUK_ASSERT(duk__src != NULL); \ + (void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \ + } \ + } while (0) +#define duk_memset(dst,val,len) do { \ + void *duk__dst = (dst); \ + duk_small_int_t duk__val = (val); \ + duk_size_t duk__len = (len); \ + DUK_ASSERT(duk__dst != NULL); \ + (void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \ + } while (0) +#define duk_memset_unsafe(dst,val,len) do { \ + void *duk__dst = (dst); \ + duk_small_int_t duk__val = (val); \ + duk_size_t duk__len = (len); \ + DUK_ASSERT(duk__dst != NULL || duk__len == 0U); \ + if (DUK_LIKELY(duk__len > 0U)) { \ + DUK_ASSERT(duk__dst != NULL); \ + (void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \ + } \ + } while (0) +#define duk_memzero(dst,len) do { \ + void *duk__dst = (dst); \ + duk_size_t duk__len = (len); \ + DUK_ASSERT(duk__dst != NULL); \ + (void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \ + } while (0) +#define duk_memzero_unsafe(dst,len) do { \ + void *duk__dst = (dst); \ + duk_size_t duk__len = (len); \ + DUK_ASSERT(duk__dst != NULL || duk__len == 0U); \ + if (DUK_LIKELY(duk__len > 0U)) { \ + DUK_ASSERT(duk__dst != NULL); \ + (void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \ + } \ + } while (0) +#endif /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */ + +DUK_INTERNAL_DECL duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len); +DUK_INTERNAL_DECL duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len); + +DUK_INTERNAL_DECL duk_bool_t duk_is_whole_get_int32_nonegzero(duk_double_t x, duk_int32_t *ival); +DUK_INTERNAL_DECL duk_bool_t duk_is_whole_get_int32(duk_double_t x, duk_int32_t *ival); +DUK_INTERNAL_DECL duk_bool_t duk_double_is_anyinf(duk_double_t x); +DUK_INTERNAL_DECL duk_bool_t duk_double_is_posinf(duk_double_t x); +DUK_INTERNAL_DECL duk_bool_t duk_double_is_neginf(duk_double_t x); +DUK_INTERNAL_DECL duk_bool_t duk_double_is_nan(duk_double_t x); +DUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_or_zero(duk_double_t x); +DUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_or_inf(duk_double_t x); +DUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_zero_inf(duk_double_t x); +DUK_INTERNAL_DECL duk_small_uint_t duk_double_signbit(duk_double_t x); +DUK_INTERNAL_DECL duk_double_t duk_double_trunc_towards_zero(duk_double_t x); +DUK_INTERNAL_DECL duk_bool_t duk_double_same_sign(duk_double_t x, duk_double_t y); +DUK_INTERNAL_DECL duk_double_t duk_double_fmin(duk_double_t x, duk_double_t y); +DUK_INTERNAL_DECL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y); +DUK_INTERNAL_DECL duk_bool_t duk_double_is_finite(duk_double_t x); +DUK_INTERNAL_DECL duk_bool_t duk_double_is_integer(duk_double_t x); +DUK_INTERNAL_DECL duk_bool_t duk_double_is_safe_integer(duk_double_t x); + +DUK_INTERNAL_DECL duk_double_t duk_double_div(duk_double_t x, duk_double_t y); +DUK_INTERNAL_DECL duk_int_t duk_double_to_int_t(duk_double_t x); +DUK_INTERNAL_DECL duk_uint_t duk_double_to_uint_t(duk_double_t x); +DUK_INTERNAL_DECL duk_int32_t duk_double_to_int32_t(duk_double_t x); +DUK_INTERNAL_DECL duk_uint32_t duk_double_to_uint32_t(duk_double_t x); +DUK_INTERNAL_DECL duk_float_t duk_double_to_float_t(duk_double_t x); +DUK_INTERNAL_DECL duk_bool_t duk_double_equals(duk_double_t x, duk_double_t y); +DUK_INTERNAL_DECL duk_bool_t duk_float_equals(duk_float_t x, duk_float_t y); + +/* + * Miscellaneous + */ + +/* Example: x = 0x10 = 0b00010000 + * x - 1 = 0x0f = 0b00001111 + * x & (x - 1) == 0 + * + * x = 0x07 = 0b00000111 + * x - 1 = 0x06 = 0b00000110 + * x & (x - 1) != 0 + * + * However, incorrectly true for x == 0 so check for that explicitly. + */ +#define DUK_IS_POWER_OF_TWO(x) \ + ((x) != 0U && ((x) & ((x) - 1U)) == 0U) + +#endif /* DUK_UTIL_H_INCLUDED */ diff --git a/third_party/duktape/duk_util_bitdecoder.c b/third_party/duktape/duk_util_bitdecoder.c new file mode 100644 index 00000000..fdf77439 --- /dev/null +++ b/third_party/duktape/duk_util_bitdecoder.c @@ -0,0 +1,157 @@ +/* + * Bitstream decoder. + */ + +#include "third_party/duktape/duk_internal.h" + +/* Decode 'bits' bits from the input stream (bits must be 1...24). + * When reading past bitstream end, zeroes are shifted in. The result + * is signed to match duk_bd_decode_flagged. + */ +DUK_INTERNAL duk_uint32_t duk_bd_decode(duk_bitdecoder_ctx *ctx, duk_small_int_t bits) { + duk_small_int_t shift; + duk_uint32_t mask; + duk_uint32_t tmp; + + /* Note: cannot read more than 24 bits without possibly shifting top bits out. + * Fixable, but adds complexity. + */ + DUK_ASSERT(bits >= 1 && bits <= 24); + + while (ctx->currbits < bits) { +#if 0 + DUK_DDD(DUK_DDDPRINT("decode_bits: shift more data (bits=%ld, currbits=%ld)", + (long) bits, (long) ctx->currbits)); +#endif + ctx->currval <<= 8; + if (ctx->offset < ctx->length) { + /* If ctx->offset >= ctx->length, we "shift zeroes in" + * instead of croaking. + */ + ctx->currval |= ctx->data[ctx->offset++]; + } + ctx->currbits += 8; + } +#if 0 + DUK_DDD(DUK_DDDPRINT("decode_bits: bits=%ld, currbits=%ld, currval=0x%08lx", + (long) bits, (long) ctx->currbits, (unsigned long) ctx->currval)); +#endif + + /* Extract 'top' bits of currval; note that the extracted bits do not need + * to be cleared, we just ignore them on next round. + */ + shift = ctx->currbits - bits; + mask = (((duk_uint32_t) 1U) << bits) - 1U; + tmp = (ctx->currval >> shift) & mask; + ctx->currbits = shift; /* remaining */ + +#if 0 + DUK_DDD(DUK_DDDPRINT("decode_bits: %ld bits -> 0x%08lx (%ld), currbits=%ld, currval=0x%08lx", + (long) bits, (unsigned long) tmp, (long) tmp, (long) ctx->currbits, (unsigned long) ctx->currval)); +#endif + + return tmp; +} + +DUK_INTERNAL duk_small_uint_t duk_bd_decode_flag(duk_bitdecoder_ctx *ctx) { + return (duk_small_uint_t) duk_bd_decode(ctx, 1); +} + +/* Decode a one-bit flag, and if set, decode a value of 'bits', otherwise return + * default value. + */ +DUK_INTERNAL duk_uint32_t duk_bd_decode_flagged(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_uint32_t def_value) { + if (duk_bd_decode_flag(ctx)) { + return duk_bd_decode(ctx, bits); + } else { + return def_value; + } +} + +/* Signed variant, allows negative marker value. */ +DUK_INTERNAL duk_int32_t duk_bd_decode_flagged_signed(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_int32_t def_value) { + return (duk_int32_t) duk_bd_decode_flagged(ctx, bits, (duk_uint32_t) def_value); +} + +/* Shared varint encoding. Match dukutil.py BitEncode.varuint(). */ +DUK_INTERNAL duk_uint32_t duk_bd_decode_varuint(duk_bitdecoder_ctx *ctx) { + duk_small_uint_t t; + + /* The bit encoding choices here are based on manual testing against + * the actual varuints generated by genbuiltins.py. + */ + switch (duk_bd_decode(ctx, 2)) { + case 0: + return 0; /* [0,0] */ + case 1: + return duk_bd_decode(ctx, 2) + 1; /* [1,4] */ + case 2: + return duk_bd_decode(ctx, 5) + 5; /* [5,36] */ + default: + t = duk_bd_decode(ctx, 7); + if (t == 0) { + return duk_bd_decode(ctx, 20); + } + return (t - 1) + 37; /* [37,163] */ + } +} + +/* Decode a bit packed string from a custom format used by genbuiltins.py. + * This function is here because it's used for both heap and thread inits. + * Caller must supply the output buffer whose size is NOT checked! + */ + +#define DUK__BITPACK_LETTER_LIMIT 26 +#define DUK__BITPACK_LOOKUP1 26 +#define DUK__BITPACK_LOOKUP2 27 +#define DUK__BITPACK_SWITCH1 28 +#define DUK__BITPACK_SWITCH 29 +#define DUK__BITPACK_UNUSED1 30 +#define DUK__BITPACK_EIGHTBIT 31 + +DUK_LOCAL const duk_uint8_t duk__bitpacked_lookup[16] = { + DUK_ASC_0, DUK_ASC_1, DUK_ASC_2, DUK_ASC_3, + DUK_ASC_4, DUK_ASC_5, DUK_ASC_6, DUK_ASC_7, + DUK_ASC_8, DUK_ASC_9, DUK_ASC_UNDERSCORE, DUK_ASC_SPACE, + 0x82, 0x80, DUK_ASC_DOUBLEQUOTE, DUK_ASC_LCURLY +}; + +DUK_INTERNAL duk_small_uint_t duk_bd_decode_bitpacked_string(duk_bitdecoder_ctx *bd, duk_uint8_t *out) { + duk_small_uint_t len; + duk_small_uint_t mode; + duk_small_uint_t t; + duk_small_uint_t i; + + len = duk_bd_decode(bd, 5); + if (len == 31) { + len = duk_bd_decode(bd, 8); /* Support up to 256 bytes; rare. */ + } + + mode = 32; /* 0 = uppercase, 32 = lowercase (= 'a' - 'A') */ + for (i = 0; i < len; i++) { + t = duk_bd_decode(bd, 5); + if (t < DUK__BITPACK_LETTER_LIMIT) { + t = t + DUK_ASC_UC_A + mode; + } else if (t == DUK__BITPACK_LOOKUP1) { + t = duk__bitpacked_lookup[duk_bd_decode(bd, 3)]; + } else if (t == DUK__BITPACK_LOOKUP2) { + t = duk__bitpacked_lookup[8 + duk_bd_decode(bd, 3)]; + } else if (t == DUK__BITPACK_SWITCH1) { + t = duk_bd_decode(bd, 5); + DUK_ASSERT_DISABLE(t >= 0); /* unsigned */ + DUK_ASSERT(t <= 25); + t = t + DUK_ASC_UC_A + (mode ^ 32); + } else if (t == DUK__BITPACK_SWITCH) { + mode = mode ^ 32; + t = duk_bd_decode(bd, 5); + DUK_ASSERT_DISABLE(t >= 0); + DUK_ASSERT(t <= 25); + t = t + DUK_ASC_UC_A + mode; + } else if (t == DUK__BITPACK_EIGHTBIT) { + t = duk_bd_decode(bd, 8); + } + out[i] = (duk_uint8_t) t; + } + + return len; +} diff --git a/third_party/duktape/duk_util_bitencoder.c b/third_party/duktape/duk_util_bitencoder.c new file mode 100644 index 00000000..7c749adf --- /dev/null +++ b/third_party/duktape/duk_util_bitencoder.c @@ -0,0 +1,43 @@ +/* + * Bitstream encoder. + */ + +#include "third_party/duktape/duk_internal.h" + +DUK_INTERNAL void duk_be_encode(duk_bitencoder_ctx *ctx, duk_uint32_t data, duk_small_int_t bits) { + duk_uint8_t tmp; + + DUK_ASSERT(ctx != NULL); + DUK_ASSERT(ctx->currbits < 8); + + /* This limitation would be fixable but adds unnecessary complexity. */ + DUK_ASSERT(bits >= 1 && bits <= 24); + + ctx->currval = (ctx->currval << bits) | data; + ctx->currbits += bits; + + while (ctx->currbits >= 8) { + if (ctx->offset < ctx->length) { + tmp = (duk_uint8_t) ((ctx->currval >> (ctx->currbits - 8)) & 0xff); + ctx->data[ctx->offset++] = tmp; + } else { + /* If buffer has been exhausted, truncate bitstream */ + ctx->truncated = 1; + } + + ctx->currbits -= 8; + } +} + +DUK_INTERNAL void duk_be_finish(duk_bitencoder_ctx *ctx) { + duk_small_int_t npad; + + DUK_ASSERT(ctx != NULL); + DUK_ASSERT(ctx->currbits < 8); + + npad = (duk_small_int_t) (8 - ctx->currbits); + if (npad > 0) { + duk_be_encode(ctx, 0, npad); + } + DUK_ASSERT(ctx->currbits == 0); +} diff --git a/third_party/duktape/duk_util_bufwriter.c b/third_party/duktape/duk_util_bufwriter.c new file mode 100644 index 00000000..917886ca --- /dev/null +++ b/third_party/duktape/duk_util_bufwriter.c @@ -0,0 +1,286 @@ +/* + * Fast buffer writer with slack management. + */ + +#include "third_party/duktape/duk_internal.h" + +/* XXX: Avoid duk_{memcmp,memmove}_unsafe() by imposing a minimum length of + * >0 for the underlying dynamic buffer. + */ + +/* + * Macro support functions (use only macros in calling code) + */ + +DUK_LOCAL void duk__bw_update_ptrs(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t curr_offset, duk_size_t new_length) { + duk_uint8_t *p; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(bw_ctx != NULL); + DUK_UNREF(thr); + + /* 'p' might be NULL when the underlying buffer is zero size. If so, + * the resulting pointers are not used unsafely. + */ + p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, bw_ctx->buf); + DUK_ASSERT(p != NULL || (DUK_HBUFFER_DYNAMIC_GET_SIZE(bw_ctx->buf) == 0 && curr_offset == 0 && new_length == 0)); + bw_ctx->p = p + curr_offset; + bw_ctx->p_base = p; + bw_ctx->p_limit = p + new_length; +} + +DUK_INTERNAL void duk_bw_init(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_hbuffer_dynamic *h_buf) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(bw_ctx != NULL); + DUK_ASSERT(h_buf != NULL); + + bw_ctx->buf = h_buf; + duk__bw_update_ptrs(thr, bw_ctx, 0, DUK_HBUFFER_DYNAMIC_GET_SIZE(h_buf)); +} + +DUK_INTERNAL void duk_bw_init_pushbuf(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t buf_size) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(bw_ctx != NULL); + + (void) duk_push_dynamic_buffer(thr, buf_size); + bw_ctx->buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, -1); + DUK_ASSERT(bw_ctx->buf != NULL); + duk__bw_update_ptrs(thr, bw_ctx, 0, buf_size); +} + +/* Resize target buffer for requested size. Called by the macro only when the + * fast path test (= there is space) fails. + */ +DUK_INTERNAL duk_uint8_t *duk_bw_resize(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t sz) { + duk_size_t curr_off; + duk_size_t add_sz; + duk_size_t new_sz; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(bw_ctx != NULL); + + /* We could do this operation without caller updating bw_ctx->ptr, + * but by writing it back here we can share code better. + */ + + curr_off = (duk_size_t) (bw_ctx->p - bw_ctx->p_base); + add_sz = (curr_off >> DUK_BW_SLACK_SHIFT) + DUK_BW_SLACK_ADD; + new_sz = curr_off + sz + add_sz; + if (DUK_UNLIKELY(new_sz < curr_off)) { + /* overflow */ + DUK_ERROR_RANGE(thr, DUK_STR_BUFFER_TOO_LONG); + DUK_WO_NORETURN(return NULL;); + } +#if 0 /* for manual torture testing: tight allocation, useful with valgrind */ + new_sz = curr_off + sz; +#endif + + /* This is important to ensure dynamic buffer data pointer is not + * NULL (which is possible if buffer size is zero), which in turn + * causes portability issues with e.g. memmove() and memcpy(). + */ + DUK_ASSERT(new_sz >= 1); + + DUK_DD(DUK_DDPRINT("resize bufferwriter from %ld to %ld (add_sz=%ld)", (long) curr_off, (long) new_sz, (long) add_sz)); + + duk_hbuffer_resize(thr, bw_ctx->buf, new_sz); + duk__bw_update_ptrs(thr, bw_ctx, curr_off, new_sz); + return bw_ctx->p; +} + +/* Make buffer compact, matching current written size. */ +DUK_INTERNAL void duk_bw_compact(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx) { + duk_size_t len; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(bw_ctx != NULL); + DUK_UNREF(thr); + + len = (duk_size_t) (bw_ctx->p - bw_ctx->p_base); + duk_hbuffer_resize(thr, bw_ctx->buf, len); + duk__bw_update_ptrs(thr, bw_ctx, len, len); +} + +DUK_INTERNAL void duk_bw_write_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len) { + duk_uint8_t *p_base; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(bw != NULL); + DUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw)); + DUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw)); + DUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw)); + DUK_UNREF(thr); + + p_base = bw->p_base; + duk_memcpy_unsafe((void *) bw->p, + (const void *) (p_base + src_off), + (size_t) len); + bw->p += len; +} + +DUK_INTERNAL void duk_bw_write_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(bw != NULL); + DUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw)); + DUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw)); + DUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw)); + + DUK_BW_ENSURE(thr, bw, len); + duk_bw_write_raw_slice(thr, bw, src_off, len); +} + +DUK_INTERNAL void duk_bw_insert_raw_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len) { + duk_uint8_t *p_base; + duk_size_t buf_sz, move_sz; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(bw != NULL); + DUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw)); + DUK_ASSERT(buf != NULL); + DUK_UNREF(thr); + + p_base = bw->p_base; + buf_sz = (duk_size_t) (bw->p - p_base); /* constrained by maximum buffer size */ + move_sz = buf_sz - dst_off; + + DUK_ASSERT(p_base != NULL); /* buffer size is >= 1 */ + duk_memmove_unsafe((void *) (p_base + dst_off + len), + (const void *) (p_base + dst_off), + (size_t) move_sz); + duk_memcpy_unsafe((void *) (p_base + dst_off), + (const void *) buf, + (size_t) len); + bw->p += len; +} + +DUK_INTERNAL void duk_bw_insert_ensure_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(bw != NULL); + DUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw)); + DUK_ASSERT(buf != NULL); + + DUK_BW_ENSURE(thr, bw, len); + duk_bw_insert_raw_bytes(thr, bw, dst_off, buf, len); +} + +DUK_INTERNAL void duk_bw_insert_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len) { + duk_uint8_t *p_base; + duk_size_t buf_sz, move_sz; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(bw != NULL); + DUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw)); + DUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw)); + DUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw)); + DUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw)); + DUK_UNREF(thr); + + p_base = bw->p_base; + + /* Don't support "straddled" source now. */ + DUK_ASSERT(dst_off <= src_off || dst_off >= src_off + len); + + if (dst_off <= src_off) { + /* Target is before source. Source offset is expressed as + * a "before change" offset. Account for the memmove. + */ + src_off += len; + } + + buf_sz = (duk_size_t) (bw->p - p_base); + move_sz = buf_sz - dst_off; + + DUK_ASSERT(p_base != NULL); /* buffer size is >= 1 */ + duk_memmove_unsafe((void *) (p_base + dst_off + len), + (const void *) (p_base + dst_off), + (size_t) move_sz); + duk_memcpy_unsafe((void *) (p_base + dst_off), + (const void *) (p_base + src_off), + (size_t) len); + bw->p += len; +} + +DUK_INTERNAL void duk_bw_insert_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(bw != NULL); + DUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw)); + DUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw)); + DUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw)); + DUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw)); + + /* Don't support "straddled" source now. */ + DUK_ASSERT(dst_off <= src_off || dst_off >= src_off + len); + + DUK_BW_ENSURE(thr, bw, len); + duk_bw_insert_raw_slice(thr, bw, dst_off, src_off, len); +} + +DUK_INTERNAL duk_uint8_t *duk_bw_insert_raw_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len) { + duk_uint8_t *p_base, *p_dst, *p_src; + duk_size_t buf_sz, move_sz; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(bw != NULL); + DUK_ASSERT(off <= DUK_BW_GET_SIZE(thr, bw)); + DUK_UNREF(thr); + + p_base = bw->p_base; + buf_sz = (duk_size_t) (bw->p - p_base); + move_sz = buf_sz - off; + p_dst = p_base + off + len; + p_src = p_base + off; + duk_memmove_unsafe((void *) p_dst, (const void *) p_src, (size_t) move_sz); + return p_src; /* point to start of 'reserved area' */ +} + +DUK_INTERNAL duk_uint8_t *duk_bw_insert_ensure_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len) { + DUK_ASSERT(thr != NULL); + DUK_ASSERT(bw != NULL); + DUK_ASSERT(off <= DUK_BW_GET_SIZE(thr, bw)); + + DUK_BW_ENSURE(thr, bw, len); + return duk_bw_insert_raw_area(thr, bw, off, len); +} + +DUK_INTERNAL void duk_bw_remove_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len) { + duk_size_t move_sz; + + duk_uint8_t *p_base; + duk_uint8_t *p_src; + duk_uint8_t *p_dst; + + DUK_ASSERT(thr != NULL); + DUK_ASSERT(bw != NULL); + DUK_ASSERT(off <= DUK_BW_GET_SIZE(thr, bw)); + DUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw)); + DUK_ASSERT(off + len <= DUK_BW_GET_SIZE(thr, bw)); + DUK_UNREF(thr); + + p_base = bw->p_base; + p_dst = p_base + off; + p_src = p_dst + len; + move_sz = (duk_size_t) (bw->p - p_src); + duk_memmove_unsafe((void *) p_dst, + (const void *) p_src, + (size_t) move_sz); + bw->p -= len; +} + +/* + * Assertion helpers + */ + +#if defined(DUK_USE_ASSERTIONS) +DUK_INTERNAL void duk_bw_assert_valid(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx) { + DUK_UNREF(thr); + DUK_ASSERT(bw_ctx != NULL); + DUK_ASSERT(bw_ctx->buf != NULL); + DUK_ASSERT((DUK_HBUFFER_DYNAMIC_GET_SIZE(bw_ctx->buf) == 0) || + (bw_ctx->p != NULL && + bw_ctx->p_base != NULL && + bw_ctx->p_limit != NULL && + bw_ctx->p_limit >= bw_ctx->p_base && + bw_ctx->p >= bw_ctx->p_base && + bw_ctx->p <= bw_ctx->p_limit)); +} +#endif diff --git a/third_party/duktape/duk_util_cast.c b/third_party/duktape/duk_util_cast.c new file mode 100644 index 00000000..00bc6cc3 --- /dev/null +++ b/third_party/duktape/duk_util_cast.c @@ -0,0 +1,160 @@ +/* + * Cast helpers. + * + * C99+ coercion is challenging portability-wise because out-of-range casts + * may invoke implementation defined or even undefined behavior. See e.g. + * http://blog.frama-c.com/index.php?post/2013/10/09/Overflow-float-integer. + * + * Provide explicit cast helpers which try to avoid implementation defined + * or undefined behavior. These helpers can then be simplified in the vast + * majority of cases where the implementation defined or undefined behavior + * is not problematic. + */ + +#include "third_party/duktape/duk_internal.h" + +/* Portable double-to-integer cast which avoids undefined behavior and avoids + * relying on fmin(), fmax(), or other intrinsics. Out-of-range results are + * not assumed by caller, but here value is clamped, NaN converts to minval. + */ +#define DUK__DOUBLE_INT_CAST1(tname,minval,maxval) do { \ + if (DUK_LIKELY(x >= (duk_double_t) (minval))) { \ + DUK_ASSERT(!DUK_ISNAN(x)); \ + if (DUK_LIKELY(x <= (duk_double_t) (maxval))) { \ + return (tname) x; \ + } else { \ + return (tname) (maxval); \ + } \ + } else { \ + /* NaN or below minval. Since we don't care about the result \ + * for out-of-range values, just return the minimum value for \ + * both. \ + */ \ + return (tname) (minval); \ + } \ + } while (0) + +/* Rely on specific NaN behavior for duk_double_{fmin,fmax}(): if either + * argument is a NaN, return the second argument. This avoids a + * NaN-to-integer cast which is undefined behavior. + */ +#define DUK__DOUBLE_INT_CAST2(tname,minval,maxval) do { \ + return (tname) duk_double_fmin(duk_double_fmax(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \ + } while (0) + +/* Another solution which doesn't need C99+ behavior for fmin() and fmax(). */ +#define DUK__DOUBLE_INT_CAST3(tname,minval,maxval) do { \ + if (DUK_ISNAN(x)) { \ + /* 0 or any other value is fine. */ \ + return (tname) 0; \ + } else \ + return (tname) DUK_FMIN(DUK_FMAX(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \ + } \ + } while (0) + +/* C99+ solution: relies on specific fmin() and fmax() behavior in C99: if + * one argument is NaN but the other isn't, the non-NaN argument is returned. + * Because the limits are non-NaN values, explicit NaN check is not needed. + * This may not work on all legacy platforms, and also doesn't seem to inline + * the fmin() and fmax() calls (unless one uses -ffast-math which we don't + * support). + */ +#define DUK__DOUBLE_INT_CAST4(tname,minval,maxval) do { \ + return (tname) DUK_FMIN(DUK_FMAX(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \ + } while (0) + +DUK_INTERNAL duk_int_t duk_double_to_int_t(duk_double_t x) { +#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR) + /* Real world solution: almost any practical platform will provide + * an integer value without any guarantees what it is (which is fine). + */ + return (duk_int_t) x; +#else + DUK__DOUBLE_INT_CAST1(duk_int_t, DUK_INT_MIN, DUK_INT_MAX); +#endif +} + +DUK_INTERNAL duk_uint_t duk_double_to_uint_t(duk_double_t x) { +#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR) + return (duk_uint_t) x; +#else + DUK__DOUBLE_INT_CAST1(duk_uint_t, DUK_UINT_MIN, DUK_UINT_MAX); +#endif +} + +DUK_INTERNAL duk_int32_t duk_double_to_int32_t(duk_double_t x) { +#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR) + return (duk_int32_t) x; +#else + DUK__DOUBLE_INT_CAST1(duk_int32_t, DUK_INT32_MIN, DUK_INT32_MAX); +#endif +} + +DUK_INTERNAL duk_uint32_t duk_double_to_uint32_t(duk_double_t x) { +#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR) + return (duk_uint32_t) x; +#else + DUK__DOUBLE_INT_CAST1(duk_uint32_t, DUK_UINT32_MIN, DUK_UINT32_MAX); +#endif +} + +/* Largest IEEE double that doesn't round to infinity in the default rounding + * mode. The exact midpoint between (1 - 2^(-24)) * 2^128 and 2^128 rounds to + * infinity, at least on x64. This number is one double unit below that + * midpoint. See misc/float_cast.c. + */ +#define DUK__FLOAT_ROUND_LIMIT 340282356779733623858607532500980858880.0 + +/* Maximum IEEE float. Double-to-float conversion above this would be out of + * range and thus technically undefined behavior. + */ +#define DUK__FLOAT_MAX 340282346638528859811704183484516925440.0 + +DUK_INTERNAL duk_float_t duk_double_to_float_t(duk_double_t x) { + /* Even a double-to-float cast is technically undefined behavior if + * the double is out-of-range. C99 Section 6.3.1.5: + * + * If the value being converted is in the range of values that can + * be represented but cannot be represented exactly, the result is + * either the nearest higher or nearest lower representable value, + * chosen in an implementation-defined manner. If the value being + * converted is outside the range of values that can be represented, + * the behavior is undefined. + */ +#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR) + return (duk_float_t) x; +#else + duk_double_t t; + + t = DUK_FABS(x); + DUK_ASSERT((DUK_ISNAN(x) && DUK_ISNAN(t)) || + (!DUK_ISNAN(x) && !DUK_ISNAN(t))); + + if (DUK_LIKELY(t <= DUK__FLOAT_MAX)) { + /* Standard in-range case, try to get here with a minimum + * number of checks and branches. + */ + DUK_ASSERT(!DUK_ISNAN(x)); + return (duk_float_t) x; + } else if (t <= DUK__FLOAT_ROUND_LIMIT) { + /* Out-of-range, but rounds to min/max float. */ + DUK_ASSERT(!DUK_ISNAN(x)); + if (x < 0.0) { + return (duk_float_t) -DUK__FLOAT_MAX; + } else { + return (duk_float_t) DUK__FLOAT_MAX; + } + } else if (DUK_ISNAN(x)) { + /* Assumes double NaN -> float NaN considered "in range". */ + DUK_ASSERT(DUK_ISNAN(x)); + return (duk_float_t) x; + } else { + /* Out-of-range, rounds to +/- Infinity. */ + if (x < 0.0) { + return (duk_float_t) -DUK_DOUBLE_INFINITY; + } else { + return (duk_float_t) DUK_DOUBLE_INFINITY; + } + } +#endif +} diff --git a/third_party/duktape/duk_util_double.c b/third_party/duktape/duk_util_double.c new file mode 100644 index 00000000..6b464d90 --- /dev/null +++ b/third_party/duktape/duk_util_double.c @@ -0,0 +1,343 @@ +/* + * IEEE double helpers. + */ + +#include "third_party/duktape/duk_internal.h" + +DUK_INTERNAL duk_bool_t duk_double_is_anyinf(duk_double_t x) { + duk_double_union du; + du.d = x; + return DUK_DBLUNION_IS_ANYINF(&du); +} + +DUK_INTERNAL duk_bool_t duk_double_is_posinf(duk_double_t x) { + duk_double_union du; + du.d = x; + return DUK_DBLUNION_IS_POSINF(&du); +} + +DUK_INTERNAL duk_bool_t duk_double_is_neginf(duk_double_t x) { + duk_double_union du; + du.d = x; + return DUK_DBLUNION_IS_NEGINF(&du); +} + +DUK_INTERNAL duk_bool_t duk_double_is_nan(duk_double_t x) { + duk_double_union du; + du.d = x; + /* Assumes we're dealing with a Duktape internal NaN which is + * NaN normalized if duk_tval requires it. + */ + DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du)); + return DUK_DBLUNION_IS_NAN(&du); +} + +DUK_INTERNAL duk_bool_t duk_double_is_nan_or_zero(duk_double_t x) { + duk_double_union du; + du.d = x; + /* Assumes we're dealing with a Duktape internal NaN which is + * NaN normalized if duk_tval requires it. + */ + DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du)); + return DUK_DBLUNION_IS_NAN(&du) || DUK_DBLUNION_IS_ANYZERO(&du); +} + +DUK_INTERNAL duk_bool_t duk_double_is_nan_or_inf(duk_double_t x) { + duk_double_union du; + du.d = x; + /* If exponent is 0x7FF the argument is either a NaN or an + * infinity. We don't need to check any other fields. + */ +#if defined(DUK_USE_64BIT_OPS) +#if defined(DUK_USE_DOUBLE_ME) + return (du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000)) == DUK_U64_CONSTANT(0x000000007ff00000); +#else + return (du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000)) == DUK_U64_CONSTANT(0x7ff0000000000000); +#endif +#else + return (du.ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL; +#endif +} + +DUK_INTERNAL duk_bool_t duk_double_is_nan_zero_inf(duk_double_t x) { + duk_double_union du; +#if defined(DUK_USE_64BIT_OPS) + duk_uint64_t t; +#else + duk_uint32_t t; +#endif + du.d = x; +#if defined(DUK_USE_64BIT_OPS) +#if defined(DUK_USE_DOUBLE_ME) + t = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000); + if (t == DUK_U64_CONSTANT(0x0000000000000000)) { + t = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x0000000080000000); + return t == 0; + } + if (t == DUK_U64_CONSTANT(0x000000007ff00000)) { + return 1; + } +#else + t = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000); + if (t == DUK_U64_CONSTANT(0x0000000000000000)) { + t = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x8000000000000000); + return t == 0; + } + if (t == DUK_U64_CONSTANT(0x7ff0000000000000)) { + return 1; + } +#endif +#else + t = du.ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL; + if (t == 0x00000000UL) { + return DUK_DBLUNION_IS_ANYZERO(&du); + } + if (t == 0x7ff00000UL) { + return 1; + } +#endif + return 0; +} + +DUK_INTERNAL duk_small_uint_t duk_double_signbit(duk_double_t x) { + duk_double_union du; + du.d = x; + return (duk_small_uint_t) DUK_DBLUNION_GET_SIGNBIT(&du); +} + +DUK_INTERNAL duk_double_t duk_double_trunc_towards_zero(duk_double_t x) { + /* XXX: optimize */ + duk_small_uint_t s = duk_double_signbit(x); + x = DUK_FLOOR(DUK_FABS(x)); /* truncate towards zero */ + if (s) { + x = -x; + } + return x; +} + +DUK_INTERNAL duk_bool_t duk_double_same_sign(duk_double_t x, duk_double_t y) { + duk_double_union du1; + duk_double_union du2; + du1.d = x; + du2.d = y; + + return (((du1.ui[DUK_DBL_IDX_UI0] ^ du2.ui[DUK_DBL_IDX_UI0]) & 0x80000000UL) == 0); +} + +DUK_INTERNAL duk_double_t duk_double_fmin(duk_double_t x, duk_double_t y) { + /* Doesn't replicate fmin() behavior exactly: for fmin() if one + * argument is a NaN, the other argument should be returned. + * Duktape doesn't rely on this behavior so the replacement can + * be simplified. + */ + return (x < y ? x : y); +} + +DUK_INTERNAL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y) { + /* Doesn't replicate fmax() behavior exactly: for fmax() if one + * argument is a NaN, the other argument should be returned. + * Duktape doesn't rely on this behavior so the replacement can + * be simplified. + */ + return (x > y ? x : y); +} + +DUK_INTERNAL duk_bool_t duk_double_is_finite(duk_double_t x) { + return !duk_double_is_nan_or_inf(x); +} + +DUK_INTERNAL duk_bool_t duk_double_is_integer(duk_double_t x) { + if (duk_double_is_nan_or_inf(x)) { + return 0; + } else { + return duk_double_equals(duk_js_tointeger_number(x), x); + } +} + +DUK_INTERNAL duk_bool_t duk_double_is_safe_integer(duk_double_t x) { + /* >>> 2**53-1 + * 9007199254740991 + */ + return duk_double_is_integer(x) && DUK_FABS(x) <= 9007199254740991.0; +} + +/* Check whether a duk_double_t is a whole number in the 32-bit range (reject + * negative zero), and if so, return a duk_int32_t. + * For compiler use: don't allow negative zero as it will cause trouble with + * LDINT+LDINTX, positive zero is OK. + */ +DUK_INTERNAL duk_bool_t duk_is_whole_get_int32_nonegzero(duk_double_t x, duk_int32_t *ival) { + duk_int32_t t; + + t = duk_double_to_int32_t(x); + if (!duk_double_equals((duk_double_t) t, x)) { + return 0; + } + if (t == 0) { + duk_double_union du; + du.d = x; + if (DUK_DBLUNION_HAS_SIGNBIT(&du)) { + return 0; + } + } + *ival = t; + return 1; +} + +/* Check whether a duk_double_t is a whole number in the 32-bit range, and if + * so, return a duk_int32_t. + */ +DUK_INTERNAL duk_bool_t duk_is_whole_get_int32(duk_double_t x, duk_int32_t *ival) { + duk_int32_t t; + + t = duk_double_to_int32_t(x); + if (!duk_double_equals((duk_double_t) t, x)) { + return 0; + } + *ival = t; + return 1; +} + +/* Division: division by zero is undefined behavior (and may in fact trap) + * so it needs special handling for portability. + */ + +DUK_INTERNAL DUK_INLINE duk_double_t duk_double_div(duk_double_t x, duk_double_t y) { +#if !defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR) + if (DUK_UNLIKELY(duk_double_equals(y, 0.0) != 0)) { + /* In C99+ division by zero is undefined behavior so + * avoid it entirely. Hopefully the compiler is + * smart enough to avoid emitting any actual code + * because almost all practical platforms behave as + * expected. + */ + if (x > 0.0) { + if (DUK_SIGNBIT(y)) { + return -DUK_DOUBLE_INFINITY; + } else { + return DUK_DOUBLE_INFINITY; + } + } else if (x < 0.0) { + if (DUK_SIGNBIT(y)) { + return DUK_DOUBLE_INFINITY; + } else { + return -DUK_DOUBLE_INFINITY; + } + } else { + /* +/- 0, NaN */ + return DUK_DOUBLE_NAN; + } + } +#endif + + return x / y; +} + +/* Double and float byteorder changes. */ + +DUK_INTERNAL DUK_INLINE void duk_dblunion_host_to_little(duk_double_union *u) { +#if defined(DUK_USE_DOUBLE_LE) + /* HGFEDCBA -> HGFEDCBA */ + DUK_UNREF(u); +#elif defined(DUK_USE_DOUBLE_ME) + duk_uint32_t a, b; + + /* DCBAHGFE -> HGFEDCBA */ + a = u->ui[0]; + b = u->ui[1]; + u->ui[0] = b; + u->ui[1] = a; +#elif defined(DUK_USE_DOUBLE_BE) + /* ABCDEFGH -> HGFEDCBA */ +#if defined(DUK_USE_64BIT_OPS) + u->ull[0] = DUK_BSWAP64(u->ull[0]); +#else + duk_uint32_t a, b; + + a = u->ui[0]; + b = u->ui[1]; + u->ui[0] = DUK_BSWAP32(b); + u->ui[1] = DUK_BSWAP32(a); +#endif +#else +#error internal error +#endif +} + +DUK_INTERNAL DUK_INLINE void duk_dblunion_little_to_host(duk_double_union *u) { + duk_dblunion_host_to_little(u); +} + +DUK_INTERNAL DUK_INLINE void duk_dblunion_host_to_big(duk_double_union *u) { +#if defined(DUK_USE_DOUBLE_LE) + /* HGFEDCBA -> ABCDEFGH */ +#if defined(DUK_USE_64BIT_OPS) + u->ull[0] = DUK_BSWAP64(u->ull[0]); +#else + duk_uint32_t a, b; + + a = u->ui[0]; + b = u->ui[1]; + u->ui[0] = DUK_BSWAP32(b); + u->ui[1] = DUK_BSWAP32(a); +#endif +#elif defined(DUK_USE_DOUBLE_ME) + duk_uint32_t a, b; + + /* DCBAHGFE -> ABCDEFGH */ + a = u->ui[0]; + b = u->ui[1]; + u->ui[0] = DUK_BSWAP32(a); + u->ui[1] = DUK_BSWAP32(b); +#elif defined(DUK_USE_DOUBLE_BE) + /* ABCDEFGH -> ABCDEFGH */ + DUK_UNREF(u); +#else +#error internal error +#endif +} + +DUK_INTERNAL DUK_INLINE void duk_dblunion_big_to_host(duk_double_union *u) { + duk_dblunion_host_to_big(u); +} + +DUK_INTERNAL DUK_INLINE void duk_fltunion_host_to_big(duk_float_union *u) { +#if defined(DUK_USE_DOUBLE_LE) || defined(DUK_USE_DOUBLE_ME) + /* DCBA -> ABCD */ + u->ui[0] = DUK_BSWAP32(u->ui[0]); +#elif defined(DUK_USE_DOUBLE_BE) + /* ABCD -> ABCD */ + DUK_UNREF(u); +#else +#error internal error +#endif +} + +DUK_INTERNAL DUK_INLINE void duk_fltunion_big_to_host(duk_float_union *u) { + duk_fltunion_host_to_big(u); +} + +/* Comparison: ensures comparison operates on exactly correct types, avoiding + * some floating point comparison pitfalls (e.g. atan2() assertions failed on + * -m32 with direct comparison, even with explicit casts). + */ +#if defined(DUK_USE_GCC_PRAGMAS) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#elif defined(DUK_USE_CLANG_PRAGMAS) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wfloat-equal" +#endif + +DUK_INTERNAL DUK_ALWAYS_INLINE duk_bool_t duk_double_equals(duk_double_t x, duk_double_t y) { + return x == y; +} + +DUK_INTERNAL DUK_ALWAYS_INLINE duk_bool_t duk_float_equals(duk_float_t x, duk_float_t y) { + return x == y; +} +#if defined(DUK_USE_GCC_PRAGMAS) +#pragma GCC diagnostic pop +#elif defined(DUK_USE_CLANG_PRAGMAS) +#pragma clang diagnostic pop +#endif diff --git a/third_party/duktape/duk_util_hashbytes.c b/third_party/duktape/duk_util_hashbytes.c new file mode 100644 index 00000000..65b9612b --- /dev/null +++ b/third_party/duktape/duk_util_hashbytes.c @@ -0,0 +1,57 @@ +/* + * Hash function duk_util_hashbytes(). + * + * Currently, 32-bit MurmurHash2. + * + * Don't rely on specific hash values; hash function may be endianness + * dependent, for instance. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_STRHASH_DENSE) +/* 'magic' constants for Murmurhash2 */ +#define DUK__MAGIC_M ((duk_uint32_t) 0x5bd1e995UL) +#define DUK__MAGIC_R 24 + +DUK_INTERNAL duk_uint32_t duk_util_hashbytes(const duk_uint8_t *data, duk_size_t len, duk_uint32_t seed) { + duk_uint32_t h = seed ^ ((duk_uint32_t) len); + + while (len >= 4) { + /* Portability workaround is required for platforms without + * unaligned access. The replacement code emulates little + * endian access even on big endian architectures, which is + * OK as long as it is consistent for a build. + */ +#if defined(DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS) + duk_uint32_t k = *((const duk_uint32_t *) (const void *) data); +#else + duk_uint32_t k = ((duk_uint32_t) data[0]) | + (((duk_uint32_t) data[1]) << 8) | + (((duk_uint32_t) data[2]) << 16) | + (((duk_uint32_t) data[3]) << 24); +#endif + + k *= DUK__MAGIC_M; + k ^= k >> DUK__MAGIC_R; + k *= DUK__MAGIC_M; + h *= DUK__MAGIC_M; + h ^= k; + data += 4; + len -= 4; + } + + switch (len) { + case 3: h ^= data[2] << 16; + case 2: h ^= data[1] << 8; + case 1: h ^= data[0]; + h *= DUK__MAGIC_M; + } + + h ^= h >> 13; + h *= DUK__MAGIC_M; + h ^= h >> 15; + + return h; +} +#endif /* DUK_USE_STRHASH_DENSE */ diff --git a/third_party/duktape/duk_util_memory.c b/third_party/duktape/duk_util_memory.c new file mode 100644 index 00000000..80ad132f --- /dev/null +++ b/third_party/duktape/duk_util_memory.c @@ -0,0 +1,36 @@ +/* + * Memory utils. + */ + +#include "third_party/duktape/duk_internal.h" + +#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR) +DUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len) { + DUK_ASSERT(s1 != NULL || len == 0U); + DUK_ASSERT(s2 != NULL || len == 0U); + return DUK_MEMCMP(s1, s2, (size_t) len); +} + +DUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len) { + DUK_ASSERT(s1 != NULL); + DUK_ASSERT(s2 != NULL); + return DUK_MEMCMP(s1, s2, (size_t) len); +} +#else /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */ +DUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len) { + DUK_ASSERT(s1 != NULL || len == 0U); + DUK_ASSERT(s2 != NULL || len == 0U); + if (DUK_UNLIKELY(len == 0U)) { + return 0; + } + DUK_ASSERT(s1 != NULL); + DUK_ASSERT(s2 != NULL); + return duk_memcmp(s1, s2, len); +} + +DUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len) { + DUK_ASSERT(s1 != NULL); + DUK_ASSERT(s2 != NULL); + return DUK_MEMCMP(s1, s2, (size_t) len); +} +#endif /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */ diff --git a/third_party/duktape/duk_util_memrw.c b/third_party/duktape/duk_util_memrw.c new file mode 100644 index 00000000..47672ae9 --- /dev/null +++ b/third_party/duktape/duk_util_memrw.c @@ -0,0 +1,148 @@ +/* + * Macro support functions for reading/writing raw data. + * + * These are done using memcpy to ensure they're valid even for unaligned + * reads/writes on platforms where alignment counts. On x86 at least gcc + * is able to compile these into a bswap+mov. "Always inline" is used to + * ensure these macros compile to minimal code. + */ + +#include "third_party/duktape/duk_internal.h" + +union duk__u16_union { + duk_uint8_t b[2]; + duk_uint16_t x; +}; +typedef union duk__u16_union duk__u16_union; + +union duk__u32_union { + duk_uint8_t b[4]; + duk_uint32_t x; +}; +typedef union duk__u32_union duk__u32_union; + +#if defined(DUK_USE_64BIT_OPS) +union duk__u64_union { + duk_uint8_t b[8]; + duk_uint64_t x; +}; +typedef union duk__u64_union duk__u64_union; +#endif + +DUK_INTERNAL DUK_ALWAYS_INLINE duk_uint16_t duk_raw_read_u16_be(const duk_uint8_t *p) { + duk__u16_union u; + duk_memcpy((void *) u.b, (const void *) p, (size_t) 2); + u.x = DUK_NTOH16(u.x); + return u.x; +} + +DUK_INTERNAL DUK_ALWAYS_INLINE duk_uint32_t duk_raw_read_u32_be(const duk_uint8_t *p) { + duk__u32_union u; + duk_memcpy((void *) u.b, (const void *) p, (size_t) 4); + u.x = DUK_NTOH32(u.x); + return u.x; +} + +DUK_INTERNAL DUK_ALWAYS_INLINE duk_float_t duk_raw_read_float_be(const duk_uint8_t *p) { + duk_float_union fu; + duk_memcpy((void *) fu.uc, (const void *) p, (size_t) 4); + duk_fltunion_big_to_host(&fu); + return fu.f; +} + +DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_raw_read_double_be(const duk_uint8_t *p) { + duk_double_union du; + duk_memcpy((void *) du.uc, (const void *) p, (size_t) 8); + duk_dblunion_big_to_host(&du); + return du.d; +} + +DUK_INTERNAL DUK_ALWAYS_INLINE duk_uint16_t duk_raw_readinc_u16_be(const duk_uint8_t **p) { + duk_uint16_t res = duk_raw_read_u16_be(*p); + *p += 2; + return res; +} + +DUK_INTERNAL DUK_ALWAYS_INLINE duk_uint32_t duk_raw_readinc_u32_be(const duk_uint8_t **p) { + duk_uint32_t res = duk_raw_read_u32_be(*p); + *p += 4; + return res; +} + +DUK_INTERNAL DUK_ALWAYS_INLINE duk_float_t duk_raw_readinc_float_be(const duk_uint8_t **p) { + duk_float_t res = duk_raw_read_float_be(*p); + *p += 4; + return res; +} + +DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_raw_readinc_double_be(const duk_uint8_t **p) { + duk_double_t res = duk_raw_read_double_be(*p); + *p += 8; + return res; +} + +DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_u16_be(duk_uint8_t *p, duk_uint16_t val) { + duk__u16_union u; + u.x = DUK_HTON16(val); + duk_memcpy((void *) p, (const void *) u.b, (size_t) 2); +} + +DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_u32_be(duk_uint8_t *p, duk_uint32_t val) { + duk__u32_union u; + u.x = DUK_HTON32(val); + duk_memcpy((void *) p, (const void *) u.b, (size_t) 4); +} + +DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_float_be(duk_uint8_t *p, duk_float_t val) { + duk_float_union fu; + fu.f = val; + duk_fltunion_host_to_big(&fu); + duk_memcpy((void *) p, (const void *) fu.uc, (size_t) 4); +} + +DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_double_be(duk_uint8_t *p, duk_double_t val) { + duk_double_union du; + du.d = val; + duk_dblunion_host_to_big(&du); + duk_memcpy((void *) p, (const void *) du.uc, (size_t) 8); +} + +DUK_INTERNAL duk_small_int_t duk_raw_write_xutf8(duk_uint8_t *p, duk_ucodepoint_t val) { + duk_small_int_t len = duk_unicode_encode_xutf8(val, p); + return len; +} + +DUK_INTERNAL duk_small_int_t duk_raw_write_cesu8(duk_uint8_t *p, duk_ucodepoint_t val) { + duk_small_int_t len = duk_unicode_encode_cesu8(val, p); + return len; +} + +DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_writeinc_u16_be(duk_uint8_t **p, duk_uint16_t val) { + duk_raw_write_u16_be(*p, val); + *p += 2; +} + +DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_writeinc_u32_be(duk_uint8_t **p, duk_uint32_t val) { + duk_raw_write_u32_be(*p, val); + *p += 4; +} + +DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_writeinc_float_be(duk_uint8_t **p, duk_float_t val) { + duk_raw_write_float_be(*p, val); + *p += 4; +} + +DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_writeinc_double_be(duk_uint8_t **p, duk_double_t val) { + duk_raw_write_double_be(*p, val); + *p += 8; +} + +DUK_INTERNAL void duk_raw_writeinc_xutf8(duk_uint8_t **p, duk_ucodepoint_t val) { + duk_small_int_t len = duk_unicode_encode_xutf8(val, *p); + *p += len; +} + +DUK_INTERNAL void duk_raw_writeinc_cesu8(duk_uint8_t **p, duk_ucodepoint_t val) { + duk_small_int_t len = duk_unicode_encode_cesu8(val, *p); + *p += len; +} diff --git a/third_party/duktape/duk_util_misc.c b/third_party/duktape/duk_util_misc.c new file mode 100644 index 00000000..ef3de265 --- /dev/null +++ b/third_party/duktape/duk_util_misc.c @@ -0,0 +1,183 @@ +/* + * Misc util stuff. + */ + +#include "third_party/duktape/duk_internal.h" + +/* + * Lowercase digits for radix values 2 to 36. Also doubles as lowercase + * hex nybble table. + */ + +DUK_INTERNAL const duk_uint8_t duk_lc_digits[36] = { + DUK_ASC_0, DUK_ASC_1, DUK_ASC_2, DUK_ASC_3, DUK_ASC_4, + DUK_ASC_5, DUK_ASC_6, DUK_ASC_7, DUK_ASC_8, DUK_ASC_9, + DUK_ASC_LC_A, DUK_ASC_LC_B, DUK_ASC_LC_C, DUK_ASC_LC_D, DUK_ASC_LC_E, + DUK_ASC_LC_F, DUK_ASC_LC_G, DUK_ASC_LC_H, DUK_ASC_LC_I, DUK_ASC_LC_J, + DUK_ASC_LC_K, DUK_ASC_LC_L, DUK_ASC_LC_M, DUK_ASC_LC_N, DUK_ASC_LC_O, + DUK_ASC_LC_P, DUK_ASC_LC_Q, DUK_ASC_LC_R, DUK_ASC_LC_S, DUK_ASC_LC_T, + DUK_ASC_LC_U, DUK_ASC_LC_V, DUK_ASC_LC_W, DUK_ASC_LC_X, DUK_ASC_LC_Y, + DUK_ASC_LC_Z}; + +DUK_INTERNAL const duk_uint8_t duk_uc_nybbles[16] = { + DUK_ASC_0, DUK_ASC_1, DUK_ASC_2, DUK_ASC_3, + DUK_ASC_4, DUK_ASC_5, DUK_ASC_6, DUK_ASC_7, + DUK_ASC_8, DUK_ASC_9, DUK_ASC_UC_A, DUK_ASC_UC_B, + DUK_ASC_UC_C, DUK_ASC_UC_D, DUK_ASC_UC_E, DUK_ASC_UC_F}; + +#if defined(DUK_USE_HEX_FASTPATH) +/* Preshifted << 4. Must use 16-bit entry to allow negative value signaling. */ +DUK_INTERNAL const duk_int16_t duk_hex_dectab_shift4[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x0f */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x1f */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x20-0x2f */ + 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, + 0x80, 0x90, -1, -1, -1, -1, -1, -1, /* 0x30-0x3f */ + -1, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, -1, + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x40-0x4f */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x50-0x5f */ + -1, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, -1, + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x60-0x6f */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x70-0x7f */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x80-0x8f */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x90-0x9f */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xa0-0xaf */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb0-0xbf */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xc0-0xcf */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xd0-0xdf */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xe0-0xef */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 /* 0xf0-0xff */ +}; +#endif + +/* + * Table for hex encoding bytes + */ + +#if defined(DUK_USE_HEX_FASTPATH) +/* Lookup to encode one byte directly into 2 characters: + * + * def genhextab(bswap): + * for i in xrange(256): + * t = chr(i).encode('hex') + * if bswap: + * t = t[1] + t[0] + * print('0x' + t.encode('hex') + 'U') + * print('big endian'); genhextab(False) + * print('little endian'); genhextab(True) + */ +DUK_INTERNAL const duk_uint16_t duk_hex_enctab[256] = { +#if defined(DUK_USE_INTEGER_BE) + 0x3030U, 0x3031U, 0x3032U, 0x3033U, 0x3034U, 0x3035U, 0x3036U, + 0x3037U, 0x3038U, 0x3039U, 0x3061U, 0x3062U, 0x3063U, 0x3064U, + 0x3065U, 0x3066U, 0x3130U, 0x3131U, 0x3132U, 0x3133U, 0x3134U, + 0x3135U, 0x3136U, 0x3137U, 0x3138U, 0x3139U, 0x3161U, 0x3162U, + 0x3163U, 0x3164U, 0x3165U, 0x3166U, 0x3230U, 0x3231U, 0x3232U, + 0x3233U, 0x3234U, 0x3235U, 0x3236U, 0x3237U, 0x3238U, 0x3239U, + 0x3261U, 0x3262U, 0x3263U, 0x3264U, 0x3265U, 0x3266U, 0x3330U, + 0x3331U, 0x3332U, 0x3333U, 0x3334U, 0x3335U, 0x3336U, 0x3337U, + 0x3338U, 0x3339U, 0x3361U, 0x3362U, 0x3363U, 0x3364U, 0x3365U, + 0x3366U, 0x3430U, 0x3431U, 0x3432U, 0x3433U, 0x3434U, 0x3435U, + 0x3436U, 0x3437U, 0x3438U, 0x3439U, 0x3461U, 0x3462U, 0x3463U, + 0x3464U, 0x3465U, 0x3466U, 0x3530U, 0x3531U, 0x3532U, 0x3533U, + 0x3534U, 0x3535U, 0x3536U, 0x3537U, 0x3538U, 0x3539U, 0x3561U, + 0x3562U, 0x3563U, 0x3564U, 0x3565U, 0x3566U, 0x3630U, 0x3631U, + 0x3632U, 0x3633U, 0x3634U, 0x3635U, 0x3636U, 0x3637U, 0x3638U, + 0x3639U, 0x3661U, 0x3662U, 0x3663U, 0x3664U, 0x3665U, 0x3666U, + 0x3730U, 0x3731U, 0x3732U, 0x3733U, 0x3734U, 0x3735U, 0x3736U, + 0x3737U, 0x3738U, 0x3739U, 0x3761U, 0x3762U, 0x3763U, 0x3764U, + 0x3765U, 0x3766U, 0x3830U, 0x3831U, 0x3832U, 0x3833U, 0x3834U, + 0x3835U, 0x3836U, 0x3837U, 0x3838U, 0x3839U, 0x3861U, 0x3862U, + 0x3863U, 0x3864U, 0x3865U, 0x3866U, 0x3930U, 0x3931U, 0x3932U, + 0x3933U, 0x3934U, 0x3935U, 0x3936U, 0x3937U, 0x3938U, 0x3939U, + 0x3961U, 0x3962U, 0x3963U, 0x3964U, 0x3965U, 0x3966U, 0x6130U, + 0x6131U, 0x6132U, 0x6133U, 0x6134U, 0x6135U, 0x6136U, 0x6137U, + 0x6138U, 0x6139U, 0x6161U, 0x6162U, 0x6163U, 0x6164U, 0x6165U, + 0x6166U, 0x6230U, 0x6231U, 0x6232U, 0x6233U, 0x6234U, 0x6235U, + 0x6236U, 0x6237U, 0x6238U, 0x6239U, 0x6261U, 0x6262U, 0x6263U, + 0x6264U, 0x6265U, 0x6266U, 0x6330U, 0x6331U, 0x6332U, 0x6333U, + 0x6334U, 0x6335U, 0x6336U, 0x6337U, 0x6338U, 0x6339U, 0x6361U, + 0x6362U, 0x6363U, 0x6364U, 0x6365U, 0x6366U, 0x6430U, 0x6431U, + 0x6432U, 0x6433U, 0x6434U, 0x6435U, 0x6436U, 0x6437U, 0x6438U, + 0x6439U, 0x6461U, 0x6462U, 0x6463U, 0x6464U, 0x6465U, 0x6466U, + 0x6530U, 0x6531U, 0x6532U, 0x6533U, 0x6534U, 0x6535U, 0x6536U, + 0x6537U, 0x6538U, 0x6539U, 0x6561U, 0x6562U, 0x6563U, 0x6564U, + 0x6565U, 0x6566U, 0x6630U, 0x6631U, 0x6632U, 0x6633U, 0x6634U, + 0x6635U, 0x6636U, 0x6637U, 0x6638U, 0x6639U, 0x6661U, 0x6662U, + 0x6663U, 0x6664U, 0x6665U, 0x6666U +#else /* DUK_USE_INTEGER_BE */ + 0x3030U, 0x3130U, 0x3230U, 0x3330U, 0x3430U, 0x3530U, 0x3630U, + 0x3730U, 0x3830U, 0x3930U, 0x6130U, 0x6230U, 0x6330U, 0x6430U, + 0x6530U, 0x6630U, 0x3031U, 0x3131U, 0x3231U, 0x3331U, 0x3431U, + 0x3531U, 0x3631U, 0x3731U, 0x3831U, 0x3931U, 0x6131U, 0x6231U, + 0x6331U, 0x6431U, 0x6531U, 0x6631U, 0x3032U, 0x3132U, 0x3232U, + 0x3332U, 0x3432U, 0x3532U, 0x3632U, 0x3732U, 0x3832U, 0x3932U, + 0x6132U, 0x6232U, 0x6332U, 0x6432U, 0x6532U, 0x6632U, 0x3033U, + 0x3133U, 0x3233U, 0x3333U, 0x3433U, 0x3533U, 0x3633U, 0x3733U, + 0x3833U, 0x3933U, 0x6133U, 0x6233U, 0x6333U, 0x6433U, 0x6533U, + 0x6633U, 0x3034U, 0x3134U, 0x3234U, 0x3334U, 0x3434U, 0x3534U, + 0x3634U, 0x3734U, 0x3834U, 0x3934U, 0x6134U, 0x6234U, 0x6334U, + 0x6434U, 0x6534U, 0x6634U, 0x3035U, 0x3135U, 0x3235U, 0x3335U, + 0x3435U, 0x3535U, 0x3635U, 0x3735U, 0x3835U, 0x3935U, 0x6135U, + 0x6235U, 0x6335U, 0x6435U, 0x6535U, 0x6635U, 0x3036U, 0x3136U, + 0x3236U, 0x3336U, 0x3436U, 0x3536U, 0x3636U, 0x3736U, 0x3836U, + 0x3936U, 0x6136U, 0x6236U, 0x6336U, 0x6436U, 0x6536U, 0x6636U, + 0x3037U, 0x3137U, 0x3237U, 0x3337U, 0x3437U, 0x3537U, 0x3637U, + 0x3737U, 0x3837U, 0x3937U, 0x6137U, 0x6237U, 0x6337U, 0x6437U, + 0x6537U, 0x6637U, 0x3038U, 0x3138U, 0x3238U, 0x3338U, 0x3438U, + 0x3538U, 0x3638U, 0x3738U, 0x3838U, 0x3938U, 0x6138U, 0x6238U, + 0x6338U, 0x6438U, 0x6538U, 0x6638U, 0x3039U, 0x3139U, 0x3239U, + 0x3339U, 0x3439U, 0x3539U, 0x3639U, 0x3739U, 0x3839U, 0x3939U, + 0x6139U, 0x6239U, 0x6339U, 0x6439U, 0x6539U, 0x6639U, 0x3061U, + 0x3161U, 0x3261U, 0x3361U, 0x3461U, 0x3561U, 0x3661U, 0x3761U, + 0x3861U, 0x3961U, 0x6161U, 0x6261U, 0x6361U, 0x6461U, 0x6561U, + 0x6661U, 0x3062U, 0x3162U, 0x3262U, 0x3362U, 0x3462U, 0x3562U, + 0x3662U, 0x3762U, 0x3862U, 0x3962U, 0x6162U, 0x6262U, 0x6362U, + 0x6462U, 0x6562U, 0x6662U, 0x3063U, 0x3163U, 0x3263U, 0x3363U, + 0x3463U, 0x3563U, 0x3663U, 0x3763U, 0x3863U, 0x3963U, 0x6163U, + 0x6263U, 0x6363U, 0x6463U, 0x6563U, 0x6663U, 0x3064U, 0x3164U, + 0x3264U, 0x3364U, 0x3464U, 0x3564U, 0x3664U, 0x3764U, 0x3864U, + 0x3964U, 0x6164U, 0x6264U, 0x6364U, 0x6464U, 0x6564U, 0x6664U, + 0x3065U, 0x3165U, 0x3265U, 0x3365U, 0x3465U, 0x3565U, 0x3665U, + 0x3765U, 0x3865U, 0x3965U, 0x6165U, 0x6265U, 0x6365U, 0x6465U, + 0x6565U, 0x6665U, 0x3066U, 0x3166U, 0x3266U, 0x3366U, 0x3466U, + 0x3566U, 0x3666U, 0x3766U, 0x3866U, 0x3966U, 0x6166U, 0x6266U, + 0x6366U, 0x6466U, 0x6566U, 0x6666U +#endif /* DUK_USE_INTEGER_BE */ +}; +#endif /* DUK_USE_HEX_FASTPATH */ + +/* + * Arbitrary byteswap for potentially unaligned values + * + * Used to byteswap pointers e.g. in debugger code. + */ + +#if defined(DUK_USE_DEBUGGER_SUPPORT) /* For now only needed by the debugger. \ + */ +DUK_INTERNAL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len) { + duk_uint8_t tmp; + duk_uint8_t *q = p + len - 1; + + while (p - q < 0) { + tmp = *p; + *p = *q; + *q = tmp; + p++; + q--; + } +} +#endif diff --git a/third_party/duktape/duk_util_tinyrandom.c b/third_party/duktape/duk_util_tinyrandom.c new file mode 100644 index 00000000..8ccc69fc --- /dev/null +++ b/third_party/duktape/duk_util_tinyrandom.c @@ -0,0 +1,125 @@ +/* + * A tiny random number generator used for Math.random() and other internals. + * + * Default algorithm is xoroshiro128+: http://xoroshiro.di.unimi.it/xoroshiro128plus.c + * with SplitMix64 seed preparation: http://xorshift.di.unimi.it/splitmix64.c. + * + * Low memory targets and targets without 64-bit types use a slightly smaller + * (but slower) algorithm by Adi Shamir: + * http://www.woodmann.com/forum/archive/index.php/t-3100.html. + * + */ + +#include "third_party/duktape/duk_internal.h" + +#if !defined(DUK_USE_GET_RANDOM_DOUBLE) + +#if defined(DUK_USE_PREFER_SIZE) || !defined(DUK_USE_64BIT_OPS) +#define DUK__RANDOM_SHAMIR3OP +#else +#define DUK__RANDOM_XOROSHIRO128PLUS +#endif + +#if defined(DUK__RANDOM_SHAMIR3OP) +#define DUK__UPDATE_RND(rnd) do { \ + (rnd) += ((rnd) * (rnd)) | 0x05UL; \ + (rnd) = ((rnd) & 0xffffffffUL); /* if duk_uint32_t is exactly 32 bits, this is a NOP */ \ + } while (0) + +#define DUK__RND_BIT(rnd) ((rnd) >> 31) /* only use the highest bit */ + +DUK_INTERNAL void duk_util_tinyrandom_prepare_seed(duk_hthread *thr) { + DUK_UNREF(thr); /* Nothing now. */ +} + +DUK_INTERNAL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr) { + duk_double_t t; + duk_small_int_t n; + duk_uint32_t rnd; + + rnd = thr->heap->rnd_state; + + n = 53; /* enough to cover the whole mantissa */ + t = 0.0; + + do { + DUK__UPDATE_RND(rnd); + t += DUK__RND_BIT(rnd); + t /= 2.0; + } while (--n); + + thr->heap->rnd_state = rnd; + + DUK_ASSERT(t >= (duk_double_t) 0.0); + DUK_ASSERT(t < (duk_double_t) 1.0); + + return t; +} +#endif /* DUK__RANDOM_SHAMIR3OP */ + +#if defined(DUK__RANDOM_XOROSHIRO128PLUS) +DUK_LOCAL DUK_ALWAYS_INLINE duk_uint64_t duk__rnd_splitmix64(duk_uint64_t *x) { + duk_uint64_t z; + z = (*x += DUK_U64_CONSTANT(0x9E3779B97F4A7C15)); + z = (z ^ (z >> 30U)) * DUK_U64_CONSTANT(0xBF58476D1CE4E5B9); + z = (z ^ (z >> 27U)) * DUK_U64_CONSTANT(0x94D049BB133111EB); + return z ^ (z >> 31U); +} + +DUK_LOCAL DUK_ALWAYS_INLINE duk_uint64_t duk__rnd_rotl(const duk_uint64_t x, duk_small_uint_t k) { + return (x << k) | (x >> (64U - k)); +} + +DUK_LOCAL DUK_ALWAYS_INLINE duk_uint64_t duk__xoroshiro128plus(duk_uint64_t *s) { + duk_uint64_t s0; + duk_uint64_t s1; + duk_uint64_t res; + + s0 = s[0]; + s1 = s[1]; + res = s0 + s1; + s1 ^= s0; + s[0] = duk__rnd_rotl(s0, 55) ^ s1 ^ (s1 << 14U); + s[1] = duk__rnd_rotl(s1, 36); + + return res; +} + +DUK_INTERNAL void duk_util_tinyrandom_prepare_seed(duk_hthread *thr) { + duk_small_uint_t i; + duk_uint64_t x; + + /* Mix both halves of the initial seed with SplitMix64. The intent + * is to ensure that very similar raw seeds (which is usually the case + * because current seed is Date.now()) result in different xoroshiro128+ + * seeds. + */ + x = thr->heap->rnd_state[0]; /* Only [0] is used as input here. */ + for (i = 0; i < 64; i++) { + thr->heap->rnd_state[i & 0x01] = duk__rnd_splitmix64(&x); /* Keep last 2 values. */ + } +} + +DUK_INTERNAL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr) { + duk_uint64_t v; + duk_double_union du; + + /* For big and little endian the integer and IEEE double byte order + * is the same so a direct assignment works. For mixed endian the + * 32-bit parts must be swapped. + */ + v = (DUK_U64_CONSTANT(0x3ff) << 52U) | (duk__xoroshiro128plus((duk_uint64_t *) thr->heap->rnd_state) >> 12U); + du.ull[0] = v; +#if defined(DUK_USE_DOUBLE_ME) + do { + duk_uint32_t tmp; + tmp = du.ui[0]; + du.ui[0] = du.ui[1]; + du.ui[1] = tmp; + } while (0); +#endif + return du.d - 1.0; +} +#endif /* DUK__RANDOM_XOROSHIRO128PLUS */ + +#endif /* !DUK_USE_GET_RANDOM_DOUBLE */ diff --git a/third_party/duktape/dukhexdectab.S b/third_party/duktape/dukhexdectab.S new file mode 100644 index 00000000..33415913 --- /dev/null +++ b/third_party/duktape/dukhexdectab.S @@ -0,0 +1,64 @@ +/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + + .initbss 300,_init_duk_hex_dectab +duk_hex_dectab: + .zero 256 + .endobj duk_hex_dectab,globl,hidden + .previous + + .initro 300,_init_duk_hex_dectab +.Lduk_hex_dectab.rodata: # 56 bytes (22%) + .byte 48,0xff # 00-2f ∅-/ + .byte 1,0x00 # 30-30 0 + .byte 1,0x01 # 31-31 1 + .byte 1,0x02 # 32-32 2 + .byte 1,0x03 # 33-33 3 + .byte 1,0x04 # 34-34 4 + .byte 1,0x05 # 35-35 5 + .byte 1,0x06 # 36-36 6 + .byte 1,0x07 # 37-37 7 + .byte 1,0x08 # 38-38 8 + .byte 1,0x09 # 39-39 9 + .byte 7,0xff # 3a-40 :-@ + .byte 1,0x0a # 41-41 A + .byte 1,0x0b # 42-42 B + .byte 1,0x0c # 43-43 C + .byte 1,0x0d # 44-44 D + .byte 1,0x0e # 45-45 E + .byte 1,0x0f # 46-46 F + .byte 26,0xff # 47-60 G-` + .byte 1,0x0a # 61-61 a + .byte 1,0x0b # 62-62 b + .byte 1,0x0c # 63-63 c + .byte 1,0x0d # 64-64 d + .byte 1,0x0e # 65-65 e + .byte 1,0x0f # 66-66 f + .byte 153,0xff # 67-ff g-λ + .endobj .Lduk_hex_dectab.rodata + .byte 0,0 # terminator + .byte 0,0 # padding + .previous + + .init.start 300,_init_duk_hex_dectab + call rldecode + lodsw + .init.end 300,_init_duk_hex_dectab diff --git a/third_party/duktape/duktape.h b/third_party/duktape/duktape.h new file mode 100644 index 00000000..28a927d3 --- /dev/null +++ b/third_party/duktape/duktape.h @@ -0,0 +1,1443 @@ +/* + * Duktape public API for Duktape 2.4.99. + * + * See the API reference for documentation on call semantics. The exposed, + * supported API is between the "BEGIN PUBLIC API" and "END PUBLIC API" + * comments. Other parts of the header are Duktape internal and related to + * e.g. platform/compiler/feature detection. + * + * Git commit 0dce8a3ba7eeb3fa3bec7e258b35edab1443ae60 (v2.4.0-55-g0dce8a3b-dirty). + * Git branch master. + * + * See Duktape AUTHORS.rst and LICENSE.txt for copyright and + * licensing information. + */ + +/* LICENSE.txt */ +/* + * =============== + * Duktape license + * =============== + * + * (http://opensource.org/licenses/MIT) + * + * Copyright (c) 2013-2019 by Duktape authors (see AUTHORS.rst) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* AUTHORS.rst */ +/* + * =============== + * Duktape authors + * =============== + * + * Copyright + * ========= + * + * Duktape copyrights are held by its authors. Each author has a copyright + * to their contribution, and agrees to irrevocably license the contribution + * under the Duktape ``LICENSE.txt``. + * + * Authors + * ======= + * + * Please include an e-mail address, a link to your GitHub profile, or something + * similar to allow your contribution to be identified accurately. + * + * The following people have contributed code, website contents, or Wiki contents, + * and agreed to irrevocably license their contributions under the Duktape + * ``LICENSE.txt`` (in order of appearance): + * + * * Sami Vaarala + * * Niki Dobrev + * * Andreas \u00d6man + * * L\u00e1szl\u00f3 Lang\u00f3 + * * Legimet + * * Karl Skomski + * * Bruce Pascoe + * * Ren\u00e9 Hollander + * * Julien Hamaide (https://github.com/crazyjul) + * * Sebastian G\u00f6tte (https://github.com/jaseg) + * * Tomasz Magulski (https://github.com/magul) + * * \D. Bohdan (https://github.com/dbohdan) + * * Ond\u0159ej Jirman (https://github.com/megous) + * * Sa\u00fal Ibarra Corretg\u00e9 + * * Jeremy HU + * * Ole Andr\u00e9 Vadla Ravn\u00e5s (https://github.com/oleavr) + * * Harold Brenes (https://github.com/harold-b) + * * Oliver Crow (https://github.com/ocrow) + * * Jakub Ch\u0142api\u0144ski (https://github.com/jchlapinski) + * * Brett Vickers (https://github.com/beevik) + * * Dominik Okwieka (https://github.com/okitec) + * * Remko Tron\u00e7on (https://el-tramo.be) + * * Romero Malaquias (rbsm@ic.ufal.br) + * * Michael Drake + * * Steven Don (https://github.com/shdon) + * * Simon Stone (https://github.com/sstone1) + * * \J. McC. (https://github.com/jmhmccr) + * * Jakub Nowakowski (https://github.com/jimvonmoon) + * * Tommy Nguyen (https://github.com/tn0502) + * * Fabrice Fontaine (https://github.com/ffontaine) + * * Christopher Hiller (https://github.com/boneskull) + * * Gonzalo Diethelm (https://github.com/gonzus) + * * Michal Kasperek (https://github.com/michalkas) + * * Andrew Janke (https://github.com/apjanke) + * * Steve Fan (https://github.com/stevefan1999) + * * Edward Betts (https://github.com/edwardbetts) + * * Ozhan Duz (https://github.com/webfolderio) + * * Akos Kiss (https://github.com/akosthekiss) + * * TheBrokenRail (https://github.com/TheBrokenRail) + * * Jesse Doyle (https://github.com/jessedoyle) + * * Gero Kuehn (https://github.com/dc6jgk) + * * James Swift (https://github.com/phraemer) + * * Luis de Bethencourt (https://github.com/luisbg) + * * Ian Whyman (https://github.com/v00d00) + * + * Other contributions + * =================== + * + * The following people have contributed something other than code (e.g. reported + * bugs, provided ideas, etc; roughly in order of appearance): + * + * * Greg Burns + * * Anthony Rabine + * * Carlos Costa + * * Aur\u00e9lien Bouilland + * * Preet Desai (Pris Matic) + * * judofyr (http://www.reddit.com/user/judofyr) + * * Jason Woofenden + * * Micha\u0142 Przyby\u015b + * * Anthony Howe + * * Conrad Pankoff + * * Jim Schimpf + * * Rajaran Gaunker (https://github.com/zimbabao) + * * Andreas \u00d6man + * * Doug Sanden + * * Josh Engebretson (https://github.com/JoshEngebretson) + * * Remo Eichenberger (https://github.com/remoe) + * * Mamod Mehyar (https://github.com/mamod) + * * David Demelier (https://github.com/markand) + * * Tim Caswell (https://github.com/creationix) + * * Mitchell Blank Jr (https://github.com/mitchblank) + * * https://github.com/yushli + * * Seo Sanghyeon (https://github.com/sanxiyn) + * * Han ChoongWoo (https://github.com/tunz) + * * Joshua Peek (https://github.com/josh) + * * Bruce E. Pascoe (https://github.com/fatcerberus) + * * https://github.com/Kelledin + * * https://github.com/sstruchtrup + * * Michael Drake (https://github.com/tlsa) + * * https://github.com/chris-y + * * Laurent Zubiaur (https://github.com/lzubiaur) + * * Neil Kolban (https://github.com/nkolban) + * * Wilhelm Wanecek (https://github.com/wanecek) + * * Andrew Janke (https://github.com/apjanke) + * * Unamer (https://github.com/unamer) + * * Karl Dahlke (eklhad@gmail.com) + * + * If you are accidentally missing from this list, send me an e-mail + * (``sami.vaarala@iki.fi``) and I'll fix the omission. + */ + +#if !defined(DUKTAPE_H_INCLUDED) +#define DUKTAPE_H_INCLUDED + +#undef DUK_SINGLE_FILE + +/* + * BEGIN PUBLIC API + */ + +/* + * Version and Git commit identification + */ + +/* Duktape version, (major * 10000) + (minor * 100) + patch. Allows C code + * to #if (DUK_VERSION >= NNN) against Duktape API version. The same value + * is also available to ECMAScript code in Duktape.version. Unofficial + * development snapshots have 99 for patch level (e.g. 0.10.99 would be a + * development version after 0.10.0 but before the next official release). + */ +#define DUK_VERSION 20499L + +/* Git commit, describe, and branch for Duktape build. Useful for + * non-official snapshot builds so that application code can easily log + * which Duktape snapshot was used. Not available in the ECMAScript + * environment. + */ +#define DUK_GIT_COMMIT "0dce8a3ba7eeb3fa3bec7e258b35edab1443ae60" +#define DUK_GIT_DESCRIBE "v2.4.0-55-g0dce8a3b-dirty" +#define DUK_GIT_BRANCH "master" + +/* External duk_config.h provides platform/compiler/OS dependent + * typedefs and macros, and DUK_USE_xxx config options so that + * the rest of Duktape doesn't need to do any feature detection. + * DUK_VERSION is defined before including so that configuration + * snippets can react to it. + */ +#include "third_party/duktape/duk_config.h" + +/* + * Avoid C++ name mangling + */ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * Some defines forwarded from feature detection + */ + +#undef DUK_API_VARIADIC_MACROS +#if defined(DUK_USE_VARIADIC_MACROS) +#define DUK_API_VARIADIC_MACROS +#endif + +#define DUK_API_NORETURN(decl) DUK_NORETURN(decl) + +/* + * Public API specific typedefs + * + * Many types are wrapped by Duktape for portability to rare platforms + * where e.g. 'int' is a 16-bit type. See practical typing discussion + * in Duktape web documentation. + */ + +struct duk_thread_state; +struct duk_memory_functions; +struct duk_function_list_entry; +struct duk_number_list_entry; +struct duk_time_components; + +/* duk_context is now defined in duk_config.h because it may also be + * referenced there by prototypes. + */ +typedef struct duk_thread_state duk_thread_state; +typedef struct duk_memory_functions duk_memory_functions; +typedef struct duk_function_list_entry duk_function_list_entry; +typedef struct duk_number_list_entry duk_number_list_entry; +typedef struct duk_time_components duk_time_components; + +typedef duk_ret_t (*duk_c_function)(duk_context *ctx); +typedef void *(*duk_alloc_function) (void *udata, duk_size_t size); +typedef void *(*duk_realloc_function) (void *udata, void *ptr, duk_size_t size); +typedef void (*duk_free_function) (void *udata, void *ptr); +typedef void (*duk_fatal_function) (void *udata, const char *msg); +typedef void (*duk_decode_char_function) (void *udata, duk_codepoint_t codepoint); +typedef duk_codepoint_t (*duk_map_char_function) (void *udata, duk_codepoint_t codepoint); +typedef duk_ret_t (*duk_safe_call_function) (duk_context *ctx, void *udata); +typedef duk_size_t (*duk_debug_read_function) (void *udata, char *buffer, duk_size_t length); +typedef duk_size_t (*duk_debug_write_function) (void *udata, const char *buffer, duk_size_t length); +typedef duk_size_t (*duk_debug_peek_function) (void *udata); +typedef void (*duk_debug_read_flush_function) (void *udata); +typedef void (*duk_debug_write_flush_function) (void *udata); +typedef duk_idx_t (*duk_debug_request_function) (duk_context *ctx, void *udata, duk_idx_t nvalues); +typedef void (*duk_debug_detached_function) (duk_context *ctx, void *udata); + +struct duk_thread_state { + /* XXX: Enough space to hold internal suspend/resume structure. + * This is rather awkward and to be fixed when the internal + * structure is visible for the public API header. + */ + char data[128]; +}; + +struct duk_memory_functions { + duk_alloc_function alloc_func; + duk_realloc_function realloc_func; + duk_free_function free_func; + void *udata; +}; + +struct duk_function_list_entry { + const char *key; + duk_c_function value; + duk_idx_t nargs; +}; + +struct duk_number_list_entry { + const char *key; + duk_double_t value; +}; + +struct duk_time_components { + duk_double_t year; /* year, e.g. 2016, ECMAScript year range */ + duk_double_t month; /* month: 1-12 */ + duk_double_t day; /* day: 1-31 */ + duk_double_t hours; /* hour: 0-59 */ + duk_double_t minutes; /* minute: 0-59 */ + duk_double_t seconds; /* second: 0-59 (in POSIX time no leap second) */ + duk_double_t milliseconds; /* may contain sub-millisecond fractions */ + duk_double_t weekday; /* weekday: 0-6, 0=Sunday, 1=Monday, ..., 6=Saturday */ +}; + +/* + * Constants + */ + +/* Duktape debug protocol version used by this build. */ +#define DUK_DEBUG_PROTOCOL_VERSION 2 + +/* Used to represent invalid index; if caller uses this without checking, + * this index will map to a non-existent stack entry. Also used in some + * API calls as a marker to denote "no value". + */ +#define DUK_INVALID_INDEX DUK_IDX_MIN + +/* Indicates that a native function does not have a fixed number of args, + * and the argument stack should not be capped/extended at all. + */ +#define DUK_VARARGS ((duk_int_t) (-1)) + +/* Number of value stack entries (in addition to actual call arguments) + * guaranteed to be allocated on entry to a Duktape/C function. + */ +#define DUK_API_ENTRY_STACK 64U + +/* Value types, used by e.g. duk_get_type() */ +#define DUK_TYPE_MIN 0U +#define DUK_TYPE_NONE 0U /* no value, e.g. invalid index */ +#define DUK_TYPE_UNDEFINED 1U /* ECMAScript undefined */ +#define DUK_TYPE_NULL 2U /* ECMAScript null */ +#define DUK_TYPE_BOOLEAN 3U /* ECMAScript boolean: 0 or 1 */ +#define DUK_TYPE_NUMBER 4U /* ECMAScript number: double */ +#define DUK_TYPE_STRING 5U /* ECMAScript string: CESU-8 / extended UTF-8 encoded */ +#define DUK_TYPE_OBJECT 6U /* ECMAScript object: includes objects, arrays, functions, threads */ +#define DUK_TYPE_BUFFER 7U /* fixed or dynamic, garbage collected byte buffer */ +#define DUK_TYPE_POINTER 8U /* raw void pointer */ +#define DUK_TYPE_LIGHTFUNC 9U /* lightweight function pointer */ +#define DUK_TYPE_MAX 9U + +/* Value mask types, used by e.g. duk_get_type_mask() */ +#define DUK_TYPE_MASK_NONE (1U << DUK_TYPE_NONE) +#define DUK_TYPE_MASK_UNDEFINED (1U << DUK_TYPE_UNDEFINED) +#define DUK_TYPE_MASK_NULL (1U << DUK_TYPE_NULL) +#define DUK_TYPE_MASK_BOOLEAN (1U << DUK_TYPE_BOOLEAN) +#define DUK_TYPE_MASK_NUMBER (1U << DUK_TYPE_NUMBER) +#define DUK_TYPE_MASK_STRING (1U << DUK_TYPE_STRING) +#define DUK_TYPE_MASK_OBJECT (1U << DUK_TYPE_OBJECT) +#define DUK_TYPE_MASK_BUFFER (1U << DUK_TYPE_BUFFER) +#define DUK_TYPE_MASK_POINTER (1U << DUK_TYPE_POINTER) +#define DUK_TYPE_MASK_LIGHTFUNC (1U << DUK_TYPE_LIGHTFUNC) +#define DUK_TYPE_MASK_THROW (1U << 10) /* internal flag value: throw if mask doesn't match */ +#define DUK_TYPE_MASK_PROMOTE (1U << 11) /* internal flag value: promote to object if mask matches */ + +/* Coercion hints */ +#define DUK_HINT_NONE 0 /* prefer number, unless input is a Date, in which + * case prefer string (E5 Section 8.12.8) + */ +#define DUK_HINT_STRING 1 /* prefer string */ +#define DUK_HINT_NUMBER 2 /* prefer number */ + +/* Enumeration flags for duk_enum() */ +#define DUK_ENUM_INCLUDE_NONENUMERABLE (1U << 0) /* enumerate non-numerable properties in addition to enumerable */ +#define DUK_ENUM_INCLUDE_HIDDEN (1U << 1) /* enumerate hidden symbols too (in Duktape 1.x called internal properties) */ +#define DUK_ENUM_INCLUDE_SYMBOLS (1U << 2) /* enumerate symbols */ +#define DUK_ENUM_EXCLUDE_STRINGS (1U << 3) /* exclude strings */ +#define DUK_ENUM_OWN_PROPERTIES_ONLY (1U << 4) /* don't walk prototype chain, only check own properties */ +#define DUK_ENUM_ARRAY_INDICES_ONLY (1U << 5) /* only enumerate array indices */ +/* XXX: misleading name */ +#define DUK_ENUM_SORT_ARRAY_INDICES (1U << 6) /* sort array indices (applied to full enumeration result, including inherited array indices); XXX: misleading name */ +#define DUK_ENUM_NO_PROXY_BEHAVIOR (1U << 7) /* enumerate a proxy object itself without invoking proxy behavior */ + +/* Compilation flags for duk_compile() and duk_eval() */ +/* DUK_COMPILE_xxx bits 0-2 are reserved for an internal 'nargs' argument. + */ +#define DUK_COMPILE_EVAL (1U << 3) /* compile eval code (instead of global code) */ +#define DUK_COMPILE_FUNCTION (1U << 4) /* compile function code (instead of global code) */ +#define DUK_COMPILE_STRICT (1U << 5) /* use strict (outer) context for global, eval, or function code */ +#define DUK_COMPILE_SHEBANG (1U << 6) /* allow shebang ('#! ...') comment on first line of source */ +#define DUK_COMPILE_SAFE (1U << 7) /* (internal) catch compilation errors */ +#define DUK_COMPILE_NORESULT (1U << 8) /* (internal) omit eval result */ +#define DUK_COMPILE_NOSOURCE (1U << 9) /* (internal) no source string on stack */ +#define DUK_COMPILE_STRLEN (1U << 10) /* (internal) take strlen() of src_buffer (avoids double evaluation in macro) */ +#define DUK_COMPILE_NOFILENAME (1U << 11) /* (internal) no filename on stack */ +#define DUK_COMPILE_FUNCEXPR (1U << 12) /* (internal) source is a function expression (used for Function constructor) */ + +/* Flags for duk_def_prop() and its variants; base flags + a lot of convenience shorthands */ +#define DUK_DEFPROP_WRITABLE (1U << 0) /* set writable (effective if DUK_DEFPROP_HAVE_WRITABLE set) */ +#define DUK_DEFPROP_ENUMERABLE (1U << 1) /* set enumerable (effective if DUK_DEFPROP_HAVE_ENUMERABLE set) */ +#define DUK_DEFPROP_CONFIGURABLE (1U << 2) /* set configurable (effective if DUK_DEFPROP_HAVE_CONFIGURABLE set) */ +#define DUK_DEFPROP_HAVE_WRITABLE (1U << 3) /* set/clear writable */ +#define DUK_DEFPROP_HAVE_ENUMERABLE (1U << 4) /* set/clear enumerable */ +#define DUK_DEFPROP_HAVE_CONFIGURABLE (1U << 5) /* set/clear configurable */ +#define DUK_DEFPROP_HAVE_VALUE (1U << 6) /* set value (given on value stack) */ +#define DUK_DEFPROP_HAVE_GETTER (1U << 7) /* set getter (given on value stack) */ +#define DUK_DEFPROP_HAVE_SETTER (1U << 8) /* set setter (given on value stack) */ +#define DUK_DEFPROP_FORCE (1U << 9) /* force change if possible, may still fail for e.g. virtual properties */ +#define DUK_DEFPROP_SET_WRITABLE (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE) +#define DUK_DEFPROP_CLEAR_WRITABLE DUK_DEFPROP_HAVE_WRITABLE +#define DUK_DEFPROP_SET_ENUMERABLE (DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE) +#define DUK_DEFPROP_CLEAR_ENUMERABLE DUK_DEFPROP_HAVE_ENUMERABLE +#define DUK_DEFPROP_SET_CONFIGURABLE (DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE) +#define DUK_DEFPROP_CLEAR_CONFIGURABLE DUK_DEFPROP_HAVE_CONFIGURABLE +#define DUK_DEFPROP_W DUK_DEFPROP_WRITABLE +#define DUK_DEFPROP_E DUK_DEFPROP_ENUMERABLE +#define DUK_DEFPROP_C DUK_DEFPROP_CONFIGURABLE +#define DUK_DEFPROP_WE (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_ENUMERABLE) +#define DUK_DEFPROP_WC (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_CONFIGURABLE) +#define DUK_DEFPROP_WEC (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_CONFIGURABLE) +#define DUK_DEFPROP_HAVE_W DUK_DEFPROP_HAVE_WRITABLE +#define DUK_DEFPROP_HAVE_E DUK_DEFPROP_HAVE_ENUMERABLE +#define DUK_DEFPROP_HAVE_C DUK_DEFPROP_HAVE_CONFIGURABLE +#define DUK_DEFPROP_HAVE_WE (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE) +#define DUK_DEFPROP_HAVE_WC (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_CONFIGURABLE) +#define DUK_DEFPROP_HAVE_WEC (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE) +#define DUK_DEFPROP_SET_W DUK_DEFPROP_SET_WRITABLE +#define DUK_DEFPROP_SET_E DUK_DEFPROP_SET_ENUMERABLE +#define DUK_DEFPROP_SET_C DUK_DEFPROP_SET_CONFIGURABLE +#define DUK_DEFPROP_SET_WE (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_ENUMERABLE) +#define DUK_DEFPROP_SET_WC (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_CONFIGURABLE) +#define DUK_DEFPROP_SET_WEC (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_ENUMERABLE | DUK_DEFPROP_SET_CONFIGURABLE) +#define DUK_DEFPROP_CLEAR_W DUK_DEFPROP_CLEAR_WRITABLE +#define DUK_DEFPROP_CLEAR_E DUK_DEFPROP_CLEAR_ENUMERABLE +#define DUK_DEFPROP_CLEAR_C DUK_DEFPROP_CLEAR_CONFIGURABLE +#define DUK_DEFPROP_CLEAR_WE (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_ENUMERABLE) +#define DUK_DEFPROP_CLEAR_WC (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_CONFIGURABLE) +#define DUK_DEFPROP_CLEAR_WEC (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_ENUMERABLE | DUK_DEFPROP_CLEAR_CONFIGURABLE) +#define DUK_DEFPROP_ATTR_W (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_W) +#define DUK_DEFPROP_ATTR_E (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_E) +#define DUK_DEFPROP_ATTR_C (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_C) +#define DUK_DEFPROP_ATTR_WE (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WE) +#define DUK_DEFPROP_ATTR_WC (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WC) +#define DUK_DEFPROP_ATTR_WEC (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WEC) + +/* Flags for duk_push_thread_raw() */ +#define DUK_THREAD_NEW_GLOBAL_ENV (1U << 0) /* create a new global environment */ + +/* Flags for duk_gc() */ +#define DUK_GC_COMPACT (1U << 0) /* compact heap objects */ + +/* Error codes (must be 8 bits at most, see duk_error.h) */ +#define DUK_ERR_NONE 0 /* no error (e.g. from duk_get_error_code()) */ +#define DUK_ERR_ERROR 1 /* Error */ +#define DUK_ERR_EVAL_ERROR 2 /* EvalError */ +#define DUK_ERR_RANGE_ERROR 3 /* RangeError */ +#define DUK_ERR_REFERENCE_ERROR 4 /* ReferenceError */ +#define DUK_ERR_SYNTAX_ERROR 5 /* SyntaxError */ +#define DUK_ERR_TYPE_ERROR 6 /* TypeError */ +#define DUK_ERR_URI_ERROR 7 /* URIError */ + +/* Return codes for C functions (shortcut for throwing an error) */ +#define DUK_RET_ERROR (-DUK_ERR_ERROR) +#define DUK_RET_EVAL_ERROR (-DUK_ERR_EVAL_ERROR) +#define DUK_RET_RANGE_ERROR (-DUK_ERR_RANGE_ERROR) +#define DUK_RET_REFERENCE_ERROR (-DUK_ERR_REFERENCE_ERROR) +#define DUK_RET_SYNTAX_ERROR (-DUK_ERR_SYNTAX_ERROR) +#define DUK_RET_TYPE_ERROR (-DUK_ERR_TYPE_ERROR) +#define DUK_RET_URI_ERROR (-DUK_ERR_URI_ERROR) + +/* Return codes for protected calls (duk_safe_call(), duk_pcall()) */ +#define DUK_EXEC_SUCCESS 0 +#define DUK_EXEC_ERROR 1 + +/* Debug levels for DUK_USE_DEBUG_WRITE(). */ +#define DUK_LEVEL_DEBUG 0 +#define DUK_LEVEL_DDEBUG 1 +#define DUK_LEVEL_DDDEBUG 2 + +/* + * Macros to create Symbols as C statically constructed strings. + * + * Call e.g. as DUK_HIDDEN_SYMBOL("myProperty") <=> ("\xFF" "myProperty"). + * + * Local symbols have a unique suffix, caller should take care to avoid + * conflicting with the Duktape internal representation by e.g. prepending + * a '!' character: DUK_LOCAL_SYMBOL("myLocal", "!123"). + * + * Note that these can only be used for string constants, not dynamically + * created strings. + * + * You shouldn't normally use DUK_INTERNAL_SYMBOL() at all. It is reserved + * for Duktape internal symbols only. There are no versioning guarantees + * for internal symbols. + */ + +#define DUK_HIDDEN_SYMBOL(x) ("\xFF" x) +#define DUK_GLOBAL_SYMBOL(x) ("\x80" x) +#define DUK_LOCAL_SYMBOL(x,uniq) ("\x81" x "\xff" uniq) +#define DUK_WELLKNOWN_SYMBOL(x) ("\x81" x "\xff") +#define DUK_INTERNAL_SYMBOL(x) ("\x82" x) + +/* + * If no variadic macros, __FILE__ and __LINE__ are passed through globals + * which is ugly and not thread safe. + */ + +#if !defined(DUK_API_VARIADIC_MACROS) +DUK_EXTERNAL_DECL const char *duk_api_global_filename; +DUK_EXTERNAL_DECL duk_int_t duk_api_global_line; +#endif + +/* + * Context management + */ + +DUK_EXTERNAL_DECL +duk_context *duk_create_heap(duk_alloc_function alloc_func, + duk_realloc_function realloc_func, + duk_free_function free_func, + void *heap_udata, + duk_fatal_function fatal_handler); +DUK_EXTERNAL_DECL void duk_destroy_heap(duk_context *ctx); + +DUK_EXTERNAL_DECL void duk_suspend(duk_context *ctx, duk_thread_state *state); +DUK_EXTERNAL_DECL void duk_resume(duk_context *ctx, const duk_thread_state *state); + +#define duk_create_heap_default() \ + duk_create_heap(NULL, NULL, NULL, NULL, NULL) + +/* + * Memory management + * + * Raw functions have no side effects (cannot trigger GC). + */ + +DUK_EXTERNAL_DECL void *duk_alloc_raw(duk_context *ctx, duk_size_t size); +DUK_EXTERNAL_DECL void duk_free_raw(duk_context *ctx, void *ptr); +DUK_EXTERNAL_DECL void *duk_realloc_raw(duk_context *ctx, void *ptr, duk_size_t size); +DUK_EXTERNAL_DECL void *duk_alloc(duk_context *ctx, duk_size_t size); +DUK_EXTERNAL_DECL void duk_free(duk_context *ctx, void *ptr); +DUK_EXTERNAL_DECL void *duk_realloc(duk_context *ctx, void *ptr, duk_size_t size); +DUK_EXTERNAL_DECL void duk_get_memory_functions(duk_context *ctx, duk_memory_functions *out_funcs); +DUK_EXTERNAL_DECL void duk_gc(duk_context *ctx, duk_uint_t flags); + +/* + * Error handling + */ + +DUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_throw_raw(duk_context *ctx)); +#define duk_throw(ctx) \ + (duk_throw_raw((ctx)), (duk_ret_t) 0) +DUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_fatal_raw(duk_context *ctx, const char *err_msg)); +#define duk_fatal(ctx,err_msg) \ + (duk_fatal_raw((ctx), (err_msg)), (duk_ret_t) 0) +DUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_error_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...)); + +#if defined(DUK_API_VARIADIC_MACROS) +#define duk_error(ctx,err_code,...) \ + (duk_error_raw((ctx), (duk_errcode_t) (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0) +#define duk_generic_error(ctx,...) \ + (duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0) +#define duk_eval_error(ctx,...) \ + (duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_EVAL_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0) +#define duk_range_error(ctx,...) \ + (duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_RANGE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0) +#define duk_reference_error(ctx,...) \ + (duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_REFERENCE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0) +#define duk_syntax_error(ctx,...) \ + (duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_SYNTAX_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0) +#define duk_type_error(ctx,...) \ + (duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_TYPE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0) +#define duk_uri_error(ctx,...) \ + (duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_URI_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0) +#else /* DUK_API_VARIADIC_MACROS */ +/* For legacy compilers without variadic macros a macro hack is used to allow + * variable arguments. While the macro allows "return duk_error(...)", it + * will fail with e.g. "(void) duk_error(...)". The calls are noreturn but + * with a return value to allow the "return duk_error(...)" idiom. This may + * cause some compiler warnings, but without noreturn the generated code is + * often worse. The same approach as with variadic macros (using + * "(duk_error(...), 0)") won't work due to the macro hack structure. + */ +DUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_error_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...)); +DUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_generic_error_stash(duk_context *ctx, const char *fmt, ...)); +DUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_eval_error_stash(duk_context *ctx, const char *fmt, ...)); +DUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_range_error_stash(duk_context *ctx, const char *fmt, ...)); +DUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_reference_error_stash(duk_context *ctx, const char *fmt, ...)); +DUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_syntax_error_stash(duk_context *ctx, const char *fmt, ...)); +DUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_type_error_stash(duk_context *ctx, const char *fmt, ...)); +DUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_uri_error_stash(duk_context *ctx, const char *fmt, ...)); +#define duk_error \ + (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ + duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ + duk_error_stash) /* last value is func pointer, arguments follow in parens */ +#define duk_generic_error \ + (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ + duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ + duk_generic_error_stash) +#define duk_eval_error \ + (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ + duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ + duk_eval_error_stash) +#define duk_range_error \ + (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ + duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ + duk_range_error_stash) +#define duk_reference_error \ + (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ + duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ + duk_reference_error_stash) +#define duk_syntax_error \ + (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ + duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ + duk_syntax_error_stash) +#define duk_type_error \ + (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ + duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ + duk_type_error_stash) +#define duk_uri_error \ + (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ + duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ + duk_uri_error_stash) +#endif /* DUK_API_VARIADIC_MACROS */ + +DUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_error_va_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap)); + +#define duk_error_va(ctx,err_code,fmt,ap) \ + (duk_error_va_raw((ctx), (duk_errcode_t) (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0) +#define duk_generic_error_va(ctx,fmt,ap) \ + (duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0) +#define duk_eval_error_va(ctx,fmt,ap) \ + (duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_EVAL_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0) +#define duk_range_error_va(ctx,fmt,ap) \ + (duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_RANGE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0) +#define duk_reference_error_va(ctx,fmt,ap) \ + (duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_REFERENCE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0) +#define duk_syntax_error_va(ctx,fmt,ap) \ + (duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_SYNTAX_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0) +#define duk_type_error_va(ctx,fmt,ap) \ + (duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_TYPE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0) +#define duk_uri_error_va(ctx,fmt,ap) \ + (duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_URI_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0) + +/* + * Other state related functions + */ + +DUK_EXTERNAL_DECL duk_bool_t duk_is_strict_call(duk_context *ctx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_constructor_call(duk_context *ctx); + +/* + * Stack management + */ + +DUK_EXTERNAL_DECL duk_idx_t duk_normalize_index(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_idx_t duk_require_normalize_index(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_valid_index(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void duk_require_valid_index(duk_context *ctx, duk_idx_t idx); + +DUK_EXTERNAL_DECL duk_idx_t duk_get_top(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_set_top(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_idx_t duk_get_top_index(duk_context *ctx); +DUK_EXTERNAL_DECL duk_idx_t duk_require_top_index(duk_context *ctx); + +/* Although extra/top could be an unsigned type here, using a signed type + * makes the API more robust to calling code calculation errors or corner + * cases (where caller might occasionally come up with negative values). + * Negative values are treated as zero, which is better than casting them + * to a large unsigned number. (This principle is used elsewhere in the + * API too.) + */ +DUK_EXTERNAL_DECL duk_bool_t duk_check_stack(duk_context *ctx, duk_idx_t extra); +DUK_EXTERNAL_DECL void duk_require_stack(duk_context *ctx, duk_idx_t extra); +DUK_EXTERNAL_DECL duk_bool_t duk_check_stack_top(duk_context *ctx, duk_idx_t top); +DUK_EXTERNAL_DECL void duk_require_stack_top(duk_context *ctx, duk_idx_t top); + +/* + * Stack manipulation (other than push/pop) + */ + +DUK_EXTERNAL_DECL void duk_swap(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2); +DUK_EXTERNAL_DECL void duk_swap_top(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void duk_dup(duk_context *ctx, duk_idx_t from_idx); +DUK_EXTERNAL_DECL void duk_dup_top(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_insert(duk_context *ctx, duk_idx_t to_idx); +DUK_EXTERNAL_DECL void duk_replace(duk_context *ctx, duk_idx_t to_idx); +DUK_EXTERNAL_DECL void duk_copy(duk_context *ctx, duk_idx_t from_idx, duk_idx_t to_idx); +DUK_EXTERNAL_DECL void duk_remove(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void duk_xcopymove_raw(duk_context *to_ctx, duk_context *from_ctx, duk_idx_t count, duk_bool_t is_copy); + +#define duk_xmove_top(to_ctx,from_ctx,count) \ + duk_xcopymove_raw((to_ctx), (from_ctx), (count), 0 /*is_copy*/) +#define duk_xcopy_top(to_ctx,from_ctx,count) \ + duk_xcopymove_raw((to_ctx), (from_ctx), (count), 1 /*is_copy*/) + +/* + * Push operations + * + * Push functions return the absolute (relative to bottom of frame) + * position of the pushed value for convenience. + * + * Note: duk_dup() is technically a push. + */ + +DUK_EXTERNAL_DECL void duk_push_undefined(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_push_null(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_push_boolean(duk_context *ctx, duk_bool_t val); +DUK_EXTERNAL_DECL void duk_push_true(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_push_false(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_push_number(duk_context *ctx, duk_double_t val); +DUK_EXTERNAL_DECL void duk_push_nan(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_push_int(duk_context *ctx, duk_int_t val); +DUK_EXTERNAL_DECL void duk_push_uint(duk_context *ctx, duk_uint_t val); +DUK_EXTERNAL_DECL const char *duk_push_string(duk_context *ctx, const char *str); +DUK_EXTERNAL_DECL const char *duk_push_lstring(duk_context *ctx, const char *str, duk_size_t len); +DUK_EXTERNAL_DECL void duk_push_pointer(duk_context *ctx, void *p); +DUK_EXTERNAL_DECL const char *duk_push_sprintf(duk_context *ctx, const char *fmt, ...); +DUK_EXTERNAL_DECL const char *duk_push_vsprintf(duk_context *ctx, const char *fmt, va_list ap); + +/* duk_push_literal() may evaluate its argument (a C string literal) more than + * once on purpose. When speed is preferred, sizeof() avoids an unnecessary + * strlen() at runtime. Sizeof("foo") == 4, so subtract 1. The argument + * must be non-NULL and should not contain internal NUL characters as the + * behavior will then depend on config options. + */ +#if defined(DUK_USE_PREFER_SIZE) +#define duk_push_literal(ctx,cstring) duk_push_string((ctx), (cstring)) +#else +DUK_EXTERNAL_DECL const char *duk_push_literal_raw(duk_context *ctx, const char *str, duk_size_t len); +#define duk_push_literal(ctx,cstring) duk_push_literal_raw((ctx), (cstring), sizeof((cstring)) - 1U) +#endif + +DUK_EXTERNAL_DECL void duk_push_this(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_push_new_target(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_push_current_function(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_push_current_thread(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_push_global_object(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_push_heap_stash(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_push_global_stash(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_push_thread_stash(duk_context *ctx, duk_context *target_ctx); + +DUK_EXTERNAL_DECL duk_idx_t duk_push_object(duk_context *ctx); +DUK_EXTERNAL_DECL duk_idx_t duk_push_bare_object(duk_context *ctx); +DUK_EXTERNAL_DECL duk_idx_t duk_push_array(duk_context *ctx); +DUK_EXTERNAL_DECL duk_idx_t duk_push_bare_array(duk_context *ctx); +DUK_EXTERNAL_DECL duk_idx_t duk_push_c_function(duk_context *ctx, duk_c_function func, duk_idx_t nargs); +DUK_EXTERNAL_DECL duk_idx_t duk_push_c_lightfunc(duk_context *ctx, duk_c_function func, duk_idx_t nargs, duk_idx_t length, duk_int_t magic); +DUK_EXTERNAL_DECL duk_idx_t duk_push_thread_raw(duk_context *ctx, duk_uint_t flags); +DUK_EXTERNAL_DECL duk_idx_t duk_push_proxy(duk_context *ctx, duk_uint_t proxy_flags); + +#define duk_push_thread(ctx) \ + duk_push_thread_raw((ctx), 0 /*flags*/) + +#define duk_push_thread_new_globalenv(ctx) \ + duk_push_thread_raw((ctx), DUK_THREAD_NEW_GLOBAL_ENV /*flags*/) + +DUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...); + +#if defined(DUK_API_VARIADIC_MACROS) +#define duk_push_error_object(ctx,err_code,...) \ + duk_push_error_object_raw((ctx), (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__) +#else +DUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...); +/* Note: parentheses are required so that the comma expression works in assignments. */ +#define duk_push_error_object \ + (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ + duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ + duk_push_error_object_stash) /* last value is func pointer, arguments follow in parens */ +#endif + +DUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_va_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap); +#define duk_push_error_object_va(ctx,err_code,fmt,ap) \ + duk_push_error_object_va_raw((ctx), (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)) + +#define DUK_BUF_FLAG_DYNAMIC (1 << 0) /* internal flag: dynamic buffer */ +#define DUK_BUF_FLAG_EXTERNAL (1 << 1) /* internal flag: external buffer */ +#define DUK_BUF_FLAG_NOZERO (1 << 2) /* internal flag: don't zero allocated buffer */ + +DUK_EXTERNAL_DECL void *duk_push_buffer_raw(duk_context *ctx, duk_size_t size, duk_small_uint_t flags); + +#define duk_push_buffer(ctx,size,dynamic) \ + duk_push_buffer_raw((ctx), (size), (dynamic) ? DUK_BUF_FLAG_DYNAMIC : 0) +#define duk_push_fixed_buffer(ctx,size) \ + duk_push_buffer_raw((ctx), (size), 0 /*flags*/) +#define duk_push_dynamic_buffer(ctx,size) \ + duk_push_buffer_raw((ctx), (size), DUK_BUF_FLAG_DYNAMIC /*flags*/) +#define duk_push_external_buffer(ctx) \ + ((void) duk_push_buffer_raw((ctx), 0, DUK_BUF_FLAG_DYNAMIC | DUK_BUF_FLAG_EXTERNAL)) + +#define DUK_BUFOBJ_ARRAYBUFFER 0 +#define DUK_BUFOBJ_NODEJS_BUFFER 1 +#define DUK_BUFOBJ_DATAVIEW 2 +#define DUK_BUFOBJ_INT8ARRAY 3 +#define DUK_BUFOBJ_UINT8ARRAY 4 +#define DUK_BUFOBJ_UINT8CLAMPEDARRAY 5 +#define DUK_BUFOBJ_INT16ARRAY 6 +#define DUK_BUFOBJ_UINT16ARRAY 7 +#define DUK_BUFOBJ_INT32ARRAY 8 +#define DUK_BUFOBJ_UINT32ARRAY 9 +#define DUK_BUFOBJ_FLOAT32ARRAY 10 +#define DUK_BUFOBJ_FLOAT64ARRAY 11 + +DUK_EXTERNAL_DECL void duk_push_buffer_object(duk_context *ctx, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags); + +DUK_EXTERNAL_DECL duk_idx_t duk_push_heapptr(duk_context *ctx, void *ptr); + +/* + * Pop operations + */ + +DUK_EXTERNAL_DECL void duk_pop(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_pop_n(duk_context *ctx, duk_idx_t count); +DUK_EXTERNAL_DECL void duk_pop_2(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_pop_3(duk_context *ctx); + +/* + * Type checks + * + * duk_is_none(), which would indicate whether index it outside of stack, + * is not needed; duk_is_valid_index() gives the same information. + */ + +DUK_EXTERNAL_DECL duk_int_t duk_get_type(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_check_type(duk_context *ctx, duk_idx_t idx, duk_int_t type); +DUK_EXTERNAL_DECL duk_uint_t duk_get_type_mask(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_check_type_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t mask); + +DUK_EXTERNAL_DECL duk_bool_t duk_is_undefined(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_null(duk_context *ctx, duk_idx_t idx); +#define duk_is_null_or_undefined(ctx, idx) \ + ((duk_get_type_mask((ctx), (idx)) & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED)) ? 1 : 0) + +DUK_EXTERNAL_DECL duk_bool_t duk_is_boolean(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_number(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_nan(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_string(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_object(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_buffer(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_buffer_data(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_pointer(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_lightfunc(duk_context *ctx, duk_idx_t idx); + +DUK_EXTERNAL_DECL duk_bool_t duk_is_symbol(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_array(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_function(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_c_function(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_ecmascript_function(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_bound_function(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_thread(duk_context *ctx, duk_idx_t idx); + +#define duk_is_callable(ctx,idx) \ + duk_is_function((ctx), (idx)) +DUK_EXTERNAL_DECL duk_bool_t duk_is_constructable(duk_context *ctx, duk_idx_t idx); + +DUK_EXTERNAL_DECL duk_bool_t duk_is_dynamic_buffer(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_fixed_buffer(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_is_external_buffer(duk_context *ctx, duk_idx_t idx); + +/* Buffers and lightfuncs are not considered primitive because they mimic + * objects and e.g. duk_to_primitive() will coerce them instead of returning + * them as is. Symbols are represented as strings internally. + */ +#define duk_is_primitive(ctx,idx) \ + duk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_UNDEFINED | \ + DUK_TYPE_MASK_NULL | \ + DUK_TYPE_MASK_BOOLEAN | \ + DUK_TYPE_MASK_NUMBER | \ + DUK_TYPE_MASK_STRING | \ + DUK_TYPE_MASK_POINTER) + +/* Symbols are object coercible, covered by DUK_TYPE_MASK_STRING. */ +#define duk_is_object_coercible(ctx,idx) \ + duk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_BOOLEAN | \ + DUK_TYPE_MASK_NUMBER | \ + DUK_TYPE_MASK_STRING | \ + DUK_TYPE_MASK_OBJECT | \ + DUK_TYPE_MASK_BUFFER | \ + DUK_TYPE_MASK_POINTER | \ + DUK_TYPE_MASK_LIGHTFUNC) + +DUK_EXTERNAL_DECL duk_errcode_t duk_get_error_code(duk_context *ctx, duk_idx_t idx); +#define duk_is_error(ctx,idx) \ + (duk_get_error_code((ctx), (idx)) != 0) +#define duk_is_eval_error(ctx,idx) \ + (duk_get_error_code((ctx), (idx)) == DUK_ERR_EVAL_ERROR) +#define duk_is_range_error(ctx,idx) \ + (duk_get_error_code((ctx), (idx)) == DUK_ERR_RANGE_ERROR) +#define duk_is_reference_error(ctx,idx) \ + (duk_get_error_code((ctx), (idx)) == DUK_ERR_REFERENCE_ERROR) +#define duk_is_syntax_error(ctx,idx) \ + (duk_get_error_code((ctx), (idx)) == DUK_ERR_SYNTAX_ERROR) +#define duk_is_type_error(ctx,idx) \ + (duk_get_error_code((ctx), (idx)) == DUK_ERR_TYPE_ERROR) +#define duk_is_uri_error(ctx,idx) \ + (duk_get_error_code((ctx), (idx)) == DUK_ERR_URI_ERROR) + +/* + * Get operations: no coercion, returns default value for invalid + * indices and invalid value types. + * + * duk_get_undefined() and duk_get_null() would be pointless and + * are not included. + */ + +DUK_EXTERNAL_DECL duk_bool_t duk_get_boolean(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_double_t duk_get_number(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_int_t duk_get_int(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_uint_t duk_get_uint(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL const char *duk_get_string(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL const char *duk_get_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len); +DUK_EXTERNAL_DECL void *duk_get_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size); +DUK_EXTERNAL_DECL void *duk_get_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size); +DUK_EXTERNAL_DECL void *duk_get_pointer(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_c_function duk_get_c_function(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_context *duk_get_context(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void *duk_get_heapptr(duk_context *ctx, duk_idx_t idx); + +/* + * Get-with-explicit default operations: like get operations but with an + * explicit default value. + */ + +DUK_EXTERNAL_DECL duk_bool_t duk_get_boolean_default(duk_context *ctx, duk_idx_t idx, duk_bool_t def_value); +DUK_EXTERNAL_DECL duk_double_t duk_get_number_default(duk_context *ctx, duk_idx_t idx, duk_double_t def_value); +DUK_EXTERNAL_DECL duk_int_t duk_get_int_default(duk_context *ctx, duk_idx_t idx, duk_int_t def_value); +DUK_EXTERNAL_DECL duk_uint_t duk_get_uint_default(duk_context *ctx, duk_idx_t idx, duk_uint_t def_value); +DUK_EXTERNAL_DECL const char *duk_get_string_default(duk_context *ctx, duk_idx_t idx, const char *def_value); +DUK_EXTERNAL_DECL const char *duk_get_lstring_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len); +DUK_EXTERNAL_DECL void *duk_get_buffer_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len); +DUK_EXTERNAL_DECL void *duk_get_buffer_data_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len); +DUK_EXTERNAL_DECL void *duk_get_pointer_default(duk_context *ctx, duk_idx_t idx, void *def_value); +DUK_EXTERNAL_DECL duk_c_function duk_get_c_function_default(duk_context *ctx, duk_idx_t idx, duk_c_function def_value); +DUK_EXTERNAL_DECL duk_context *duk_get_context_default(duk_context *ctx, duk_idx_t idx, duk_context *def_value); +DUK_EXTERNAL_DECL void *duk_get_heapptr_default(duk_context *ctx, duk_idx_t idx, void *def_value); + +/* + * Opt operations: like require operations but with an explicit default value + * when value is undefined or index is invalid, null and non-matching types + * cause a TypeError. + */ + +DUK_EXTERNAL_DECL duk_bool_t duk_opt_boolean(duk_context *ctx, duk_idx_t idx, duk_bool_t def_value); +DUK_EXTERNAL_DECL duk_double_t duk_opt_number(duk_context *ctx, duk_idx_t idx, duk_double_t def_value); +DUK_EXTERNAL_DECL duk_int_t duk_opt_int(duk_context *ctx, duk_idx_t idx, duk_int_t def_value); +DUK_EXTERNAL_DECL duk_uint_t duk_opt_uint(duk_context *ctx, duk_idx_t idx, duk_uint_t def_value); +DUK_EXTERNAL_DECL const char *duk_opt_string(duk_context *ctx, duk_idx_t idx, const char *def_ptr); +DUK_EXTERNAL_DECL const char *duk_opt_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len); +DUK_EXTERNAL_DECL void *duk_opt_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size); +DUK_EXTERNAL_DECL void *duk_opt_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size); +DUK_EXTERNAL_DECL void *duk_opt_pointer(duk_context *ctx, duk_idx_t idx, void *def_value); +DUK_EXTERNAL_DECL duk_c_function duk_opt_c_function(duk_context *ctx, duk_idx_t idx, duk_c_function def_value); +DUK_EXTERNAL_DECL duk_context *duk_opt_context(duk_context *ctx, duk_idx_t idx, duk_context *def_value); +DUK_EXTERNAL_DECL void *duk_opt_heapptr(duk_context *ctx, duk_idx_t idx, void *def_value); + +/* + * Require operations: no coercion, throw error if index or type + * is incorrect. No defaulting. + */ + +#define duk_require_type_mask(ctx,idx,mask) \ + ((void) duk_check_type_mask((ctx), (idx), (mask) | DUK_TYPE_MASK_THROW)) + +DUK_EXTERNAL_DECL void duk_require_undefined(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void duk_require_null(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_require_boolean(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_double_t duk_require_number(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_int_t duk_require_int(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_uint_t duk_require_uint(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL const char *duk_require_string(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL const char *duk_require_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len); +DUK_EXTERNAL_DECL void duk_require_object(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void *duk_require_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size); +DUK_EXTERNAL_DECL void *duk_require_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size); +DUK_EXTERNAL_DECL void *duk_require_pointer(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_c_function duk_require_c_function(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_context *duk_require_context(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void duk_require_function(duk_context *ctx, duk_idx_t idx); +#define duk_require_callable(ctx,idx) \ + duk_require_function((ctx), (idx)) +DUK_EXTERNAL_DECL void duk_require_constructor_call(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_require_constructable(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void *duk_require_heapptr(duk_context *ctx, duk_idx_t idx); + +/* Symbols are object coercible and covered by DUK_TYPE_MASK_STRING. */ +#define duk_require_object_coercible(ctx,idx) \ + ((void) duk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_BOOLEAN | \ + DUK_TYPE_MASK_NUMBER | \ + DUK_TYPE_MASK_STRING | \ + DUK_TYPE_MASK_OBJECT | \ + DUK_TYPE_MASK_BUFFER | \ + DUK_TYPE_MASK_POINTER | \ + DUK_TYPE_MASK_LIGHTFUNC | \ + DUK_TYPE_MASK_THROW)) + +/* + * Coercion operations: in-place coercion, return coerced value where + * applicable. If index is invalid, throw error. Some coercions may + * throw an expected error (e.g. from a toString() or valueOf() call) + * or an internal error (e.g. from out of memory). + */ + +DUK_EXTERNAL_DECL void duk_to_undefined(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void duk_to_null(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_bool_t duk_to_boolean(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_double_t duk_to_number(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_int_t duk_to_int(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_uint_t duk_to_uint(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_int32_t duk_to_int32(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_uint32_t duk_to_uint32(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_uint16_t duk_to_uint16(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL const char *duk_to_string(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL const char *duk_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len); +DUK_EXTERNAL_DECL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, duk_uint_t flags); +DUK_EXTERNAL_DECL void *duk_to_pointer(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void duk_to_object(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void duk_to_primitive(duk_context *ctx, duk_idx_t idx, duk_int_t hint); + +#define DUK_BUF_MODE_FIXED 0 /* internal: request fixed buffer result */ +#define DUK_BUF_MODE_DYNAMIC 1 /* internal: request dynamic buffer result */ +#define DUK_BUF_MODE_DONTCARE 2 /* internal: don't care about fixed/dynamic nature */ + +#define duk_to_buffer(ctx,idx,out_size) \ + duk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_DONTCARE) +#define duk_to_fixed_buffer(ctx,idx,out_size) \ + duk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_FIXED) +#define duk_to_dynamic_buffer(ctx,idx,out_size) \ + duk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_DYNAMIC) + +/* safe variants of a few coercion operations */ +DUK_EXTERNAL_DECL const char *duk_safe_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len); +DUK_EXTERNAL_DECL const char *duk_to_stacktrace(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL const char *duk_safe_to_stacktrace(duk_context *ctx, duk_idx_t idx); +#define duk_safe_to_string(ctx,idx) \ + duk_safe_to_lstring((ctx), (idx), NULL) + +/* + * Value length + */ + +DUK_EXTERNAL_DECL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void duk_set_length(duk_context *ctx, duk_idx_t idx, duk_size_t len); +#if 0 +/* duk_require_length()? */ +/* duk_opt_length()? */ +#endif + +/* + * Misc conversion + */ + +DUK_EXTERNAL_DECL const char *duk_base64_encode(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void duk_base64_decode(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL const char *duk_hex_encode(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void duk_hex_decode(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL const char *duk_json_encode(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void duk_json_decode(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void duk_cbor_encode(duk_context *ctx, duk_idx_t idx, duk_uint_t encode_flags); +DUK_EXTERNAL_DECL void duk_cbor_decode(duk_context *ctx, duk_idx_t idx, duk_uint_t decode_flags); + +DUK_EXTERNAL_DECL const char *duk_buffer_to_string(duk_context *ctx, duk_idx_t idx); + +/* + * Buffer + */ + +DUK_EXTERNAL_DECL void *duk_resize_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t new_size); +DUK_EXTERNAL_DECL void *duk_steal_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size); +DUK_EXTERNAL_DECL void duk_config_buffer(duk_context *ctx, duk_idx_t idx, void *ptr, duk_size_t len); + +/* + * Property access + * + * The basic function assumes key is on stack. The _(l)string variant takes + * a C string as a property name; the _literal variant takes a C literal. + * The _index variant takes an array index as a property name (e.g. 123 is + * equivalent to the key "123"). The _heapptr variant takes a raw, borrowed + * heap pointer. + */ + +DUK_EXTERNAL_DECL duk_bool_t duk_get_prop(duk_context *ctx, duk_idx_t obj_idx); +DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key); +DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len); +#if defined(DUK_USE_PREFER_SIZE) +#define duk_get_prop_literal(ctx,obj_idx,key) duk_get_prop_string((ctx), (obj_idx), (key)) +#else +DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len); +#define duk_get_prop_literal(ctx,obj_idx,key) duk_get_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U) +#endif +DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx); +DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr); +DUK_EXTERNAL_DECL duk_bool_t duk_put_prop(duk_context *ctx, duk_idx_t obj_idx); +DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key); +DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len); +#if defined(DUK_USE_PREFER_SIZE) +#define duk_put_prop_literal(ctx,obj_idx,key) duk_put_prop_string((ctx), (obj_idx), (key)) +#else +DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len); +#define duk_put_prop_literal(ctx,obj_idx,key) duk_put_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U) +#endif +DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx); +DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr); +DUK_EXTERNAL_DECL duk_bool_t duk_del_prop(duk_context *ctx, duk_idx_t obj_idx); +DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key); +DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len); +#if defined(DUK_USE_PREFER_SIZE) +#define duk_del_prop_literal(ctx,obj_idx,key) duk_del_prop_string((ctx), (obj_idx), (key)) +#else +DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len); +#define duk_del_prop_literal(ctx,obj_idx,key) duk_del_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U) +#endif +DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx); +DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr); +DUK_EXTERNAL_DECL duk_bool_t duk_has_prop(duk_context *ctx, duk_idx_t obj_idx); +DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key); +DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len); +#if defined(DUK_USE_PREFER_SIZE) +#define duk_has_prop_literal(ctx,obj_idx,key) duk_has_prop_string((ctx), (obj_idx), (key)) +#else +DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len); +#define duk_has_prop_literal(ctx,obj_idx,key) duk_has_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U) +#endif +DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx); +DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr); + +DUK_EXTERNAL_DECL void duk_get_prop_desc(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags); +DUK_EXTERNAL_DECL void duk_def_prop(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags); + +DUK_EXTERNAL_DECL duk_bool_t duk_get_global_string(duk_context *ctx, const char *key); +DUK_EXTERNAL_DECL duk_bool_t duk_get_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len); +#if defined(DUK_USE_PREFER_SIZE) +#define duk_get_global_literal(ctx,key) duk_get_global_string((ctx), (key)) +#else +DUK_EXTERNAL_DECL duk_bool_t duk_get_global_literal_raw(duk_context *ctx, const char *key, duk_size_t key_len); +#define duk_get_global_literal(ctx,key) duk_get_global_literal_raw((ctx), (key), sizeof((key)) - 1U) +#endif +DUK_EXTERNAL_DECL duk_bool_t duk_get_global_heapptr(duk_context *ctx, void *ptr); +DUK_EXTERNAL_DECL duk_bool_t duk_put_global_string(duk_context *ctx, const char *key); +DUK_EXTERNAL_DECL duk_bool_t duk_put_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len); +#if defined(DUK_USE_PREFER_SIZE) +#define duk_put_global_literal(ctx,key) duk_put_global_string((ctx), (key)) +#else +DUK_EXTERNAL_DECL duk_bool_t duk_put_global_literal_raw(duk_context *ctx, const char *key, duk_size_t key_len); +#define duk_put_global_literal(ctx,key) duk_put_global_literal_raw((ctx), (key), sizeof((key)) - 1U) +#endif +DUK_EXTERNAL_DECL duk_bool_t duk_put_global_heapptr(duk_context *ctx, void *ptr); + +/* + * Inspection + */ + +DUK_EXTERNAL_DECL void duk_inspect_value(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void duk_inspect_callstack_entry(duk_context *ctx, duk_int_t level); + +/* + * Object prototype + */ + +DUK_EXTERNAL_DECL void duk_get_prototype(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void duk_set_prototype(duk_context *ctx, duk_idx_t idx); + +/* + * Object finalizer + */ + +DUK_EXTERNAL_DECL void duk_get_finalizer(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void duk_set_finalizer(duk_context *ctx, duk_idx_t idx); + +/* + * Global object + */ + +DUK_EXTERNAL_DECL void duk_set_global_object(duk_context *ctx); + +/* + * Duktape/C function magic value + */ + +DUK_EXTERNAL_DECL duk_int_t duk_get_magic(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL void duk_set_magic(duk_context *ctx, duk_idx_t idx, duk_int_t magic); +DUK_EXTERNAL_DECL duk_int_t duk_get_current_magic(duk_context *ctx); + +/* + * Module helpers: put multiple function or constant properties + */ + +DUK_EXTERNAL_DECL void duk_put_function_list(duk_context *ctx, duk_idx_t obj_idx, const duk_function_list_entry *funcs); +DUK_EXTERNAL_DECL void duk_put_number_list(duk_context *ctx, duk_idx_t obj_idx, const duk_number_list_entry *numbers); + +/* + * Object operations + */ + +DUK_EXTERNAL_DECL void duk_compact(duk_context *ctx, duk_idx_t obj_idx); +DUK_EXTERNAL_DECL void duk_enum(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t enum_flags); +DUK_EXTERNAL_DECL duk_bool_t duk_next(duk_context *ctx, duk_idx_t enum_idx, duk_bool_t get_value); +DUK_EXTERNAL_DECL void duk_seal(duk_context *ctx, duk_idx_t obj_idx); +DUK_EXTERNAL_DECL void duk_freeze(duk_context *ctx, duk_idx_t obj_idx); + +/* + * String manipulation + */ + +DUK_EXTERNAL_DECL void duk_concat(duk_context *ctx, duk_idx_t count); +DUK_EXTERNAL_DECL void duk_join(duk_context *ctx, duk_idx_t count); +DUK_EXTERNAL_DECL void duk_decode_string(duk_context *ctx, duk_idx_t idx, duk_decode_char_function callback, void *udata); +DUK_EXTERNAL_DECL void duk_map_string(duk_context *ctx, duk_idx_t idx, duk_map_char_function callback, void *udata); +DUK_EXTERNAL_DECL void duk_substring(duk_context *ctx, duk_idx_t idx, duk_size_t start_char_offset, duk_size_t end_char_offset); +DUK_EXTERNAL_DECL void duk_trim(duk_context *ctx, duk_idx_t idx); +DUK_EXTERNAL_DECL duk_codepoint_t duk_char_code_at(duk_context *ctx, duk_idx_t idx, duk_size_t char_offset); + +/* + * ECMAScript operators + */ + +DUK_EXTERNAL_DECL duk_bool_t duk_equals(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2); +DUK_EXTERNAL_DECL duk_bool_t duk_strict_equals(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2); +DUK_EXTERNAL_DECL duk_bool_t duk_samevalue(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2); +DUK_EXTERNAL_DECL duk_bool_t duk_instanceof(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2); + +/* + * Random + */ + +DUK_EXTERNAL_DECL duk_double_t duk_random(duk_context *ctx); + +/* + * Function (method) calls + */ + +DUK_EXTERNAL_DECL void duk_call(duk_context *ctx, duk_idx_t nargs); +DUK_EXTERNAL_DECL void duk_call_method(duk_context *ctx, duk_idx_t nargs); +DUK_EXTERNAL_DECL void duk_call_prop(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t nargs); +DUK_EXTERNAL_DECL duk_int_t duk_pcall(duk_context *ctx, duk_idx_t nargs); +DUK_EXTERNAL_DECL duk_int_t duk_pcall_method(duk_context *ctx, duk_idx_t nargs); +DUK_EXTERNAL_DECL duk_int_t duk_pcall_prop(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t nargs); +DUK_EXTERNAL_DECL void duk_new(duk_context *ctx, duk_idx_t nargs); +DUK_EXTERNAL_DECL duk_int_t duk_pnew(duk_context *ctx, duk_idx_t nargs); +DUK_EXTERNAL_DECL duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function func, void *udata, duk_idx_t nargs, duk_idx_t nrets); + +/* + * Thread management + */ + +/* There are currently no native functions to yield/resume, due to the internal + * limitations on coroutine handling. These will be added later. + */ + +/* + * Compilation and evaluation + */ + +DUK_EXTERNAL_DECL duk_int_t duk_eval_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags); +DUK_EXTERNAL_DECL duk_int_t duk_compile_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags); + +/* plain */ +#define duk_eval(ctx) \ + ((void) duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOFILENAME)) + +#define duk_eval_noresult(ctx) \ + ((void) duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME)) + +#define duk_peval(ctx) \ + (duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOFILENAME)) + +#define duk_peval_noresult(ctx) \ + (duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME)) + +#define duk_compile(ctx,flags) \ + ((void) duk_compile_raw((ctx), NULL, 0, 2 /*args*/ | (flags))) + +#define duk_pcompile(ctx,flags) \ + (duk_compile_raw((ctx), NULL, 0, 2 /*args*/ | (flags) | DUK_COMPILE_SAFE)) + +/* string */ +#define duk_eval_string(ctx,src) \ + ((void) duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME)) + +#define duk_eval_string_noresult(ctx,src) \ + ((void) duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME)) + +#define duk_peval_string(ctx,src) \ + (duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME)) + +#define duk_peval_string_noresult(ctx,src) \ + (duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME)) + +#define duk_compile_string(ctx,flags,src) \ + ((void) duk_compile_raw((ctx), (src), 0, 0 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME)) + +#define duk_compile_string_filename(ctx,flags,src) \ + ((void) duk_compile_raw((ctx), (src), 0, 1 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN)) + +#define duk_pcompile_string(ctx,flags,src) \ + (duk_compile_raw((ctx), (src), 0, 0 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME)) + +#define duk_pcompile_string_filename(ctx,flags,src) \ + (duk_compile_raw((ctx), (src), 0, 1 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN)) + +/* lstring */ +#define duk_eval_lstring(ctx,buf,len) \ + ((void) duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME)) + +#define duk_eval_lstring_noresult(ctx,buf,len) \ + ((void) duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME)) + +#define duk_peval_lstring(ctx,buf,len) \ + (duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_SAFE | DUK_COMPILE_NOFILENAME)) + +#define duk_peval_lstring_noresult(ctx,buf,len) \ + (duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME)) + +#define duk_compile_lstring(ctx,flags,buf,len) \ + ((void) duk_compile_raw((ctx), buf, len, 0 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME)) + +#define duk_compile_lstring_filename(ctx,flags,buf,len) \ + ((void) duk_compile_raw((ctx), buf, len, 1 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE)) + +#define duk_pcompile_lstring(ctx,flags,buf,len) \ + (duk_compile_raw((ctx), buf, len, 0 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME)) + +#define duk_pcompile_lstring_filename(ctx,flags,buf,len) \ + (duk_compile_raw((ctx), buf, len, 1 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE)) + +/* + * Bytecode load/dump + */ + +DUK_EXTERNAL_DECL void duk_dump_function(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_load_function(duk_context *ctx); + +/* + * Debugging + */ + +DUK_EXTERNAL_DECL void duk_push_context_dump(duk_context *ctx); + +/* + * Debugger (debug protocol) + */ + +DUK_EXTERNAL_DECL void duk_debugger_attach(duk_context *ctx, + duk_debug_read_function read_cb, + duk_debug_write_function write_cb, + duk_debug_peek_function peek_cb, + duk_debug_read_flush_function read_flush_cb, + duk_debug_write_flush_function write_flush_cb, + duk_debug_request_function request_cb, + duk_debug_detached_function detached_cb, + void *udata); +DUK_EXTERNAL_DECL void duk_debugger_detach(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_debugger_cooperate(duk_context *ctx); +DUK_EXTERNAL_DECL duk_bool_t duk_debugger_notify(duk_context *ctx, duk_idx_t nvalues); +DUK_EXTERNAL_DECL void duk_debugger_pause(duk_context *ctx); + +/* + * Time handling + */ + +DUK_EXTERNAL_DECL duk_double_t duk_get_now(duk_context *ctx); +DUK_EXTERNAL_DECL void duk_time_to_components(duk_context *ctx, duk_double_t timeval, duk_time_components *comp); +DUK_EXTERNAL_DECL duk_double_t duk_components_to_time(duk_context *ctx, duk_time_components *comp); + +/* + * Date provider related constants + * + * NOTE: These are "semi public" - you should only use these if you write + * your own platform specific Date provider, see doc/datetime.rst. + */ + +/* Millisecond count constants. */ +#define DUK_DATE_MSEC_SECOND 1000L +#define DUK_DATE_MSEC_MINUTE (60L * 1000L) +#define DUK_DATE_MSEC_HOUR (60L * 60L * 1000L) +#define DUK_DATE_MSEC_DAY (24L * 60L * 60L * 1000L) + +/* ECMAScript date range is 100 million days from Epoch: + * > 100e6 * 24 * 60 * 60 * 1000 // 100M days in millisecs + * 8640000000000000 + * (= 8.64e15) + */ +#define DUK_DATE_MSEC_100M_DAYS (8.64e15) +#define DUK_DATE_MSEC_100M_DAYS_LEEWAY (8.64e15 + 24 * 3600e3) + +/* ECMAScript year range: + * > new Date(100e6 * 24 * 3600e3).toISOString() + * '+275760-09-13T00:00:00.000Z' + * > new Date(-100e6 * 24 * 3600e3).toISOString() + * '-271821-04-20T00:00:00.000Z' + */ +#define DUK_DATE_MIN_ECMA_YEAR (-271821L) +#define DUK_DATE_MAX_ECMA_YEAR 275760L + +/* Part indices for internal breakdowns. Part order from DUK_DATE_IDX_YEAR + * to DUK_DATE_IDX_MILLISECOND matches argument ordering of ECMAScript API + * calls (like Date constructor call). Some functions in duk_bi_date.c + * depend on the specific ordering, so change with care. 16 bits are not + * enough for all parts (year, specifically). + * + * Must be in-sync with genbuiltins.py. + */ +#define DUK_DATE_IDX_YEAR 0 /* year */ +#define DUK_DATE_IDX_MONTH 1 /* month: 0 to 11 */ +#define DUK_DATE_IDX_DAY 2 /* day within month: 0 to 30 */ +#define DUK_DATE_IDX_HOUR 3 +#define DUK_DATE_IDX_MINUTE 4 +#define DUK_DATE_IDX_SECOND 5 +#define DUK_DATE_IDX_MILLISECOND 6 +#define DUK_DATE_IDX_WEEKDAY 7 /* weekday: 0 to 6, 0=sunday, 1=monday, etc */ +#define DUK_DATE_IDX_NUM_PARTS 8 + +/* Internal API call flags, used for various functions in duk_bi_date.c. + * Certain flags are used by only certain functions, but since the flags + * don't overlap, a single flags value can be passed around to multiple + * functions. + * + * The unused top bits of the flags field are also used to pass values + * to helpers (duk__get_part_helper() and duk__set_part_helper()). + * + * Must be in-sync with genbuiltins.py. + */ + +/* NOTE: when writing a Date provider you only need a few specific + * flags from here, the rest are internal. Avoid using anything you + * don't need. + */ + +#define DUK_DATE_FLAG_NAN_TO_ZERO (1 << 0) /* timeval breakdown: internal time value NaN -> zero */ +#define DUK_DATE_FLAG_NAN_TO_RANGE_ERROR (1 << 1) /* timeval breakdown: internal time value NaN -> RangeError (toISOString) */ +#define DUK_DATE_FLAG_ONEBASED (1 << 2) /* timeval breakdown: convert month and day-of-month parts to one-based (default is zero-based) */ +#define DUK_DATE_FLAG_EQUIVYEAR (1 << 3) /* timeval breakdown: replace year with equivalent year in the [1971,2037] range for DST calculations */ +#define DUK_DATE_FLAG_LOCALTIME (1 << 4) /* convert time value to local time */ +#define DUK_DATE_FLAG_SUB1900 (1 << 5) /* getter: subtract 1900 from year when getting year part */ +#define DUK_DATE_FLAG_TOSTRING_DATE (1 << 6) /* include date part in string conversion result */ +#define DUK_DATE_FLAG_TOSTRING_TIME (1 << 7) /* include time part in string conversion result */ +#define DUK_DATE_FLAG_TOSTRING_LOCALE (1 << 8) /* use locale specific formatting if available */ +#define DUK_DATE_FLAG_TIMESETTER (1 << 9) /* setter: call is a time setter (affects hour, min, sec, ms); otherwise date setter (affects year, month, day-in-month) */ +#define DUK_DATE_FLAG_YEAR_FIXUP (1 << 10) /* setter: perform 2-digit year fixup (00...99 -> 1900...1999) */ +#define DUK_DATE_FLAG_SEP_T (1 << 11) /* string conversion: use 'T' instead of ' ' as a separator */ +#define DUK_DATE_FLAG_VALUE_SHIFT 12 /* additional values begin at bit 12 */ + +/* + * ROM pointer compression + */ + +/* Support array for ROM pointer compression. Only declared when ROM + * pointer compression is active. + */ +#if defined(DUK_USE_ROM_OBJECTS) && defined(DUK_USE_HEAPPTR16) +DUK_EXTERNAL_DECL const void * const duk_rom_compressed_pointers[]; +#endif + +/* + * C++ name mangling + */ + +#if defined(__cplusplus) +/* end 'extern "C"' wrapper */ +} +#endif + +/* + * END PUBLIC API + */ + +#endif /* DUKTAPE_H_INCLUDED */ diff --git a/third_party/duktape/duktape.mk b/third_party/duktape/duktape.mk new file mode 100644 index 00000000..69a25df8 --- /dev/null +++ b/third_party/duktape/duktape.mk @@ -0,0 +1,68 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += THIRD_PARTY_DUKTAPE + +THIRD_PARTY_DUKTAPE_ARTIFACTS += THIRD_PARTY_DUKTAPE_A +THIRD_PARTY_DUKTAPE = $(THIRD_PARTY_DUKTAPE_A_DEPS) $(THIRD_PARTY_DUKTAPE_A) +THIRD_PARTY_DUKTAPE_A = o/$(MODE)/third_party/duktape/duktape.a +THIRD_PARTY_DUKTAPE_A_FILES := $(wildcard third_party/duktape/*) +THIRD_PARTY_DUKTAPE_A_HDRS = $(filter %.h,$(THIRD_PARTY_DUKTAPE_A_FILES)) +THIRD_PARTY_DUKTAPE_A_SRCS_A = $(filter %.s,$(THIRD_PARTY_DUKTAPE_A_FILES)) +THIRD_PARTY_DUKTAPE_A_SRCS_S = $(filter %.S,$(THIRD_PARTY_DUKTAPE_A_FILES)) +THIRD_PARTY_DUKTAPE_A_SRCS_C = $(filter %.c,$(THIRD_PARTY_DUKTAPE_A_FILES)) + +THIRD_PARTY_DUKTAPE_A_SRCS = \ + $(THIRD_PARTY_DUKTAPE_A_SRCS_A) \ + $(THIRD_PARTY_DUKTAPE_A_SRCS_S) \ + $(THIRD_PARTY_DUKTAPE_A_SRCS_C) + +THIRD_PARTY_DUKTAPE_A_OBJS = \ + $(THIRD_PARTY_DUKTAPE_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(THIRD_PARTY_DUKTAPE_A_SRCS_A:%.s=o/$(MODE)/%.o) \ + $(THIRD_PARTY_DUKTAPE_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(THIRD_PARTY_DUKTAPE_A_SRCS_C:%.c=o/$(MODE)/%.o) + +THIRD_PARTY_DUKTAPE_A_CHECKS = \ + $(THIRD_PARTY_DUKTAPE_A).pkg + +THIRD_PARTY_DUKTAPE_A_DIRECTDEPS = \ + LIBC_STUBS \ + LIBC_FMT \ + LIBC_TIME \ + LIBC_MEM \ + LIBC_MATH \ + LIBC_UNICODE \ + LIBC_NEXGEN32E + +THIRD_PARTY_DUKTAPE_A_DEPS := \ + $(call uniq,$(foreach x,$(THIRD_PARTY_DUKTAPE_A_DIRECTDEPS),$($(x)))) + +$(THIRD_PARTY_DUKTAPE_A): \ + third_party/duktape/ \ + $(THIRD_PARTY_DUKTAPE_A).pkg \ + $(THIRD_PARTY_DUKTAPE_A_OBJS) + +$(THIRD_PARTY_DUKTAPE_A).pkg: \ + $(THIRD_PARTY_DUKTAPE_A_OBJS) \ + $(foreach x,$(THIRD_PARTY_DUKTAPE_A_DIRECTDEPS),$($(x)_A).pkg) + +$(THIRD_PARTY_DUKTAPE_A_OBJS): \ + OVERRIDE_CFLAGS += \ + $(IEEE_MATH) + +o/dbg/third_party/duktape/duk_js_executor.o: \ + OVERRIDE_CFLAGS += \ + -DSTACK_FRAME_UNLIMITED + +THIRD_PARTY_DUKTAPE_LIBS = $(foreach x,$(THIRD_PARTY_DUKTAPE_ARTIFACTS),$($(x))) +THIRD_PARTY_DUKTAPE_SRCS = $(foreach x,$(THIRD_PARTY_DUKTAPE_ARTIFACTS),$($(x)_SRCS)) +THIRD_PARTY_DUKTAPE_HDRS = $(foreach x,$(THIRD_PARTY_DUKTAPE_ARTIFACTS),$($(x)_HDRS)) +THIRD_PARTY_DUKTAPE_BINS = $(foreach x,$(THIRD_PARTY_DUKTAPE_ARTIFACTS),$($(x)_BINS)) +THIRD_PARTY_DUKTAPE_CHECKS = $(foreach x,$(THIRD_PARTY_DUKTAPE_ARTIFACTS),$($(x)_CHECKS)) +THIRD_PARTY_DUKTAPE_OBJS = $(foreach x,$(THIRD_PARTY_DUKTAPE_ARTIFACTS),$($(x)_OBJS)) +THIRD_PARTY_DUKTAPE_TESTS = $(foreach x,$(THIRD_PARTY_DUKTAPE_ARTIFACTS),$($(x)_TESTS)) +$(THIRD_PARTY_DUKTAPE_OBJS): $(BUILD_FILES) third_party/duktape/duktape.mk + +.PHONY: o/$(MODE)/third_party/duktape +o/$(MODE)/third_party/duktape: $(THIRD_PARTY_DUKTAPE) $(THIRD_PARTY_DUKTAPE_CHECKS) diff --git a/third_party/duktape/license.S b/third_party/duktape/license.S new file mode 100644 index 00000000..2b679c53 --- /dev/null +++ b/third_party/duktape/license.S @@ -0,0 +1,8 @@ +.section .comment +kDuktapeLicense: + .incbin "third_party/duktape/license.inc" +.type kDuktapeLicense,@object +.globl kDuktapeLicense +.popsection + +.include "libc/disclaimer.inc" diff --git a/third_party/duktape/license.inc b/third_party/duktape/license.inc new file mode 100644 index 00000000..62a66896 --- /dev/null +++ b/third_party/duktape/license.inc @@ -0,0 +1,48 @@ + + +duktape (MIT License) +Copyright 2013-2019 by The Duktape Authors +* Sami Vaarala +* Niki Dobrev +* Andreas Öman +* László Langó +* Legimet +* Karl Skomski +* Bruce Pascoe +* René Hollander +* Julien Hamaide (https://github.com/crazyjul) +* Sebastian Götte (https://github.com/jaseg) +* Tomasz Magulski (https://github.com/magul) +* \D. Bohdan (https://github.com/dbohdan) +* Ondřej Jirman (https://github.com/megous) +* Saúl Ibarra Corretgé +* Jeremy HU +* Ole André Vadla Ravnås (https://github.com/oleavr) +* Harold Brenes (https://github.com/harold-b) +* Oliver Crow (https://github.com/ocrow) +* Jakub Chłapiński (https://github.com/jchlapinski) +* Brett Vickers (https://github.com/beevik) +* Dominik Okwieka (https://github.com/okitec) +* Remko Tronçon (https://el-tramo.be) +* Romero Malaquias (rbsm@ic.ufal.br) +* Michael Drake +* Steven Don (https://github.com/shdon) +* Simon Stone (https://github.com/sstone1) +* \J. McC. (https://github.com/jmhmccr) +* Jakub Nowakowski (https://github.com/jimvonmoon) +* Tommy Nguyen (https://github.com/tn0502) +* Fabrice Fontaine (https://github.com/ffontaine) +* Christopher Hiller (https://github.com/boneskull) +* Gonzalo Diethelm (https://github.com/gonzus) +* Michal Kasperek (https://github.com/michalkas) +* Andrew Janke (https://github.com/apjanke) +* Steve Fan (https://github.com/stevefan1999) +* Edward Betts (https://github.com/edwardbetts) +* Ozhan Duz (https://github.com/webfolderio) +* Akos Kiss (https://github.com/akosthekiss) +* TheBrokenRail (https://github.com/TheBrokenRail) +* Jesse Doyle (https://github.com/jessedoyle) +* Gero Kuehn (https://github.com/dc6jgk) +* James Swift (https://github.com/phraemer) +* Luis de Bethencourt (https://github.com/luisbg) +* Ian Whyman (https://github.com/v00d00) \ No newline at end of file diff --git a/third_party/editline/ChangeLog.md b/third_party/editline/ChangeLog.md new file mode 100644 index 00000000..b2a0be66 --- /dev/null +++ b/third_party/editline/ChangeLog.md @@ -0,0 +1,248 @@ +Change Log +========== + +All notable changes to the project are documented in this file. + + +[1.16.1] - 2019-06-07 +--------------------- + +### Changes +- Major updates to the `editline.3` man page +- Cleanup of examples `cli.c` and `fileman.c` +- Add example of hidden input prompt to `cli.c` + +### Fixes +- Fix #20: `configure --disable-eof` does not bite +- Fix #23: Make Ctrl-L clear the screan instead of starting a new line + Like Ctrl-D, which exits, Ctrl-L only clears the screen when the line + is empty and the cursor is at the start of the line, otherwise Ctrl-L + will redraw/refresh the current line. +- Fix #24: Fix behavior when TTY is narrower than column width, by Will Dietz +- Fix #25: Avoid continuously duplicate commands in history +- Fix #31: Aborting i-search with Ctrl-C should not generate signal + + +[1.16.0][] - 2018-09-16 +----------------------- + +Event loop callback support. + +### Changes +- `rl_unintialize()`, new function to free all memory, by Claus Fischer +- `rl_insert_text()`, new GNU Readline compat function +- `rl_refresh_line()`, new GNU Readline compat function +- `rl_callback_*()`, alternate interface to plain `readline()` for event + loops. Modeled after the GNU Readline API +- `rl_completion_entry_function`, and `rl_attempted_completion_function` + are two new GNU Readline compat user hooks for the completion framework +- `rl_completion_matches()` and `rl_filename_completion_function()` + are two new GNU Readline compat functions +- Add new example: `fileman.c` from GNU Readline to demonstrate the + level of compatibility of the revamped completion framework +- Add support for Ctrl-Right and Ctrl-Left, forward/backward word +- Add .deb package to official release target + +### Fixes +- Fixed header guards, avoid using leading `__` +- Spell check fixes +- Remove duplicate code in history check +- Use `NULL` instead of `0`, and `-1` instead of `NULL`, where applicable +- Misc. minor Coverity Scan fixes +- Misc. minor fixes to `testit.c` example code +- Add `-Wextra` to std `CFLAGS` +- Check `fclose()` return value in in `write_history()` and `read_history()` +- Initialize global variables and reset to `NULL` on `free()` +- Fix off-by-one in forward kill word, avoid deleting too much +- Skip (or kill) leading whitespace when skipping (or killing) forwards + + +[1.15.3][] - 2017-09-07 +----------------------- + +Bug fix release. + +### Changes +- Refactor all enable/disable configure options, same problem as in #7 + +### Fixes +- Fix #7: `--enable-termcap` configure option does not work. The script + enabled termcap by default rather than the other way around. + + Also, check for terminfo as well, when `--enable-termcap` is selected. + + +[1.15.2][] - 2016-06-06 +----------------------- + +Bug fixes and minor feature creep in `pkg-config` support. + +### Changes +- Prevent mangling of symbols when linking with C++. Patch courtesy of + Jakub Pawlowski +- Add `libeditline.pc` for `pkg-config` + +### Fixes +- Do not assume a termcap library exists, check for `tgetent()` in + curses, ncurses, tinfo and termcap libraries +- Call `tty_flush()` when user calls `rl_forced_update_display()` + to prevent screen becoming garbled. Patch by Jakub Pawlowski + + +[1.15.1][] - 2015-11-16 +----------------------- + +Bug fixes only. + +### Changes +- Update README with origin of this version of editline + +### Fixes +- Fix build system, don't force automake v1.11, require at least v1.11 +- Fix build problem with examples using `--enable-termcap` + + +[1.15.0][] - 2015-09-10 +----------------------- + +### Changes +- Add support for `--disable-eof` and `--disable-sigint` to disable + default Ctrl-D and Ctrl-C behavior +- Add support for `el_no_hist` to disable access to and auto-save of history +- GNU readline compat functions for prompt handling and redisplay +- Refactor: replace variables named 'new' with non-reserved word +- Add support for [Travis-CI][], continuous integration with GitHub +- Add support for [Coverity Scan][], the best static code analyzer, + integrated with [Travis-CI][] -- scan runs for each push to master +- Rename NEWS.md --> ChangeLog.md, with symlinks for make install +- Attempt to align with http://keepachangelog.com/ for this file +- Cleanup and improve Markdown syntax in [README.md][] +- Add API and example to [README.md][], inspired by [libuEv][] +- Removed generated files from version control. Use `./autogen.sh` + to generate the `configure` script when working from GIT. This + does not affect distributed tarballs + +### Fixes +- Fix issue #2, regression in Ctrl-D (EOF) behavior. Regression + introduced in [1.14.1][]. Fixed by @TobyGoodwin +- Fix memory leak in completion handler. Found by [Coverity Scan][]. +- Fix suspicious use of `sizeof(char **)`, same as `sizeof(char *)` but + non-portable. Found by [Coverity Scan][] +- Fix out-of-bounds access in user key binding routines + Found by [Coverity Scan][]. +- Fix invisible example code in man page + + +[1.14.2][] - 2014-09-14 +----------------------- + +Bug fixes only. + +### Fixes + - Fix `el_no_echo` bug causing secrets to leak when disabling no-echo + - Handle `EINTR` in syscalls better + + +[1.14.1][] - 2014-09-14 +----------------------- + +Minor fixes and additions. + +### Changes +- Don't print status message on `stderr` in key binding funcions +- Export `el_del_char()` +- Check for and return pending signals when detected +- Allow custom key bindings ... + +### Fixes +- Bug fixes ... + + +[1.14.0][] - 2010-08-10 +----------------------- + +Major cleanups and further merges with Debian editline package. + +### Changes +- Merge in changes to `debian/` from `editline_1.12-6.debian.tar.gz` +- Migrate to use libtool +- Make `UNIQUE_HISTORY` configurable +- Make scrollback history (`HIST_SIZE`) configurable +- Configure options for toggling terminal bell and `SIGSTOP` (Ctrl-Z) +- Configure option for using termcap to read/control terminal size +- Rename Signal to `el_intr_pending`, from Festival speech-tools +- Merge support for capitalizing words (`M-c`) from Festival + speech-tools by Alan W Black +- Fallback backspace handling, in case `tgetstr("le")` fails + +### Fixes +- Cleanups and fixes thanks to the Sparse static code analysis tool +- Merge `el_no_echo` patch from Festival speech-tools +- Merge fixes from Heimdal project +- Completely refactor `rl_complete()` and `rl_list_possib()` with + fixes from the Heimdal project. Use `rl_set_complete_func()` and + `rl_set_list_possib_func()`. Default completion callbacks are now + available as a configure option `--enable-default-complete` +- Memory leak fixes +- Actually fix 8-bit handling by reverting old Debian patch +- Merge patch to improve compatibility with GNU readline, thanks to + Steve Tell from way back in 1997 and 1998 + + +[1.13.0][] - 2010-03-09 +----------------------- + +Adaptations to Debian editline package. + +### Changes +- Major version number bump, adapt to Jim Studt's v1.12 +- Import `debian/` directory and adapt it to configure et al. +- Change library name to libeditline to distinguish it from BSD libedit + + +[0.3.0][] - 2009-02-08 +---------------------- + +### Changes +- Support for ANSI arrow keys using configure --enable-arrow-keys + + +[0.2.3][] - 2008-12-02 +---------------------- + +### Changes +- Patches from Debian package merged +- Support for custom command completion + + +[0.1.0][] - 2008-06-07 +---------------------- + +### Changes +- First version, forked from Minix current 2008-06-06 + + +[UNRELEASED]: https://github.com/troglobit/finit/compare/1.16.0...HEAD +[1.16.1]: https://github.com/troglobit/finit/compare/1.16.0...1.16.1 +[1.16.0]: https://github.com/troglobit/finit/compare/1.15.3...1.16.0 +[1.15.3]: https://github.com/troglobit/finit/compare/1.15.2...1.15.3 +[1.15.2]: https://github.com/troglobit/finit/compare/1.15.1...1.15.2 +[1.15.1]: https://github.com/troglobit/finit/compare/1.15.0...1.15.1 +[1.15.0]: https://github.com/troglobit/finit/compare/1.14.2...1.15.0 +[1.14.2]: https://github.com/troglobit/finit/compare/1.14.1...1.14.2 +[1.14.1]: https://github.com/troglobit/finit/compare/1.14.0...1.14.1 +[1.14.0]: https://github.com/troglobit/finit/compare/1.13.0...1.14.0 +[1.13.0]: https://github.com/troglobit/finit/compare/0.3.0...1.13.0 +[0.3.0]: https://github.com/troglobit/finit/compare/0.2.3...0.3.0 +[0.2.3]: https://github.com/troglobit/finit/compare/0.1.0...0.2.3 +[0.1.0]: https://github.com/troglobit/finit/compare/0.0.0...0.1.0 +[libuEv]: http://github.com/troglobit/libuev +[Travis-CI]: https://travis-ci.org/troglobit/uftpd +[Coverity Scan]: https://scan.coverity.com/projects/2947 +[README.md]: https://github.com/troglobit/editline/blob/master/README.md + + diff --git a/third_party/editline/LICENSE b/third_party/editline/LICENSE new file mode 100644 index 00000000..1c0d909d --- /dev/null +++ b/third_party/editline/LICENSE @@ -0,0 +1,18 @@ + Copyright 1992,1993 Simmule Turner and Rich Salz + All rights reserved. + + This software is not subject to any license of the American Telephone + and Telegraph Company or of the Regents of the University of California. + + Permission is granted to anyone to use this software for any purpose on + any computer system, and to alter it and redistribute it freely, subject + to the following restrictions: + 1. The authors are not responsible for the consequences of use of this + software, no matter how awful, even if they arise from flaws in it. + 2. The origin of this software must not be misrepresented, either by + explicit claim or by omission. Since few users ever read sources, + credits must appear in the documentation. + 3. Altered versions must be plainly marked as such, and must not be + misrepresented as being the original software. Since few users + ever read sources, credits must appear in the documentation. + 4. This notice may not be removed or altered. diff --git a/third_party/editline/complete.c b/third_party/editline/complete.c new file mode 100644 index 00000000..54aafb6e --- /dev/null +++ b/third_party/editline/complete.c @@ -0,0 +1,362 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/alg/alg.h" +#include "libc/calls/calls.h" +#include "libc/calls/struct/dirent.h" +#include "libc/fmt/fmt.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" +#include "third_party/editline/editline.h" +#include "third_party/editline/internal.h" + +asm(".ident\t\"\\n\\n\ +Cosmopolitan Linenoise (BSD-like license)\\n\ +Copyright 2019 Justine Alexandra Roberts Tunney\\n\ +Copyright 1992,1993 Simmule Turner and Rich Salz\\n\ +All rights reserved.\\n\ +\\n\ +This software is not subject to any license of the American Telephone\\n\ +and Telegraph Company or of the Regents of the University of California.\\n\ +\\n\ +Permission is granted to anyone to use this software for any purpose on\\n\ +any computer system, and to alter it and redistribute it freely, subject\\n\ +to the following restrictions:\\n\ +1. The authors are not responsible for the consequences of use of this\\n\ + software, no matter how awful, even if they arise from flaws in it.\\n\ +2. The origin of this software must not be misrepresented, either by\\n\ + explicit claim or by omission. Since few users ever read sources,\\n\ + credits must appear in the documentation.\\n\ +3. Altered versions must be plainly marked as such, and must not be\\n\ + misrepresented as being the original software. Since few users\\n\ + ever read sources, credits must appear in the documentation.\\n\ +4. This notice may not be removed or altered.\""); +asm(".include \"libc/disclaimer.inc\""); + +#define MAX_TOTAL_MATCHES (256 << sizeof(char *)) + +int rl_attempted_completion_over = 0; +rl_completion_func_t *rl_attempted_completion_function = NULL; +rl_compentry_func_t *rl_completion_entry_function = NULL; + +/* Wrap strcmp() for qsort() -- weird construct to pass -Wcast-qual */ +static int compare(const void *p1, const void *p2) { + char *const *v1 = (char *const *)p1; + char *const *v2 = (char *const *)p2; + return strcmp(*v1, *v2); +} + +/* Fill in *avp with an array of names that match file, up to its length. + * Ignore . and .. . */ +static int FindMatches(char *dir, char *file, char ***avp) { + char **av; + char **word; + char *p; + DIR *dp; + struct dirent *ep; + size_t ac; + size_t len; + size_t choices; + size_t total; + if ((dp = opendir(dir)) == NULL) return 0; + av = NULL; + ac = 0; + len = strlen(file); + choices = 0; + total = 0; + while ((ep = readdir(dp)) != NULL) { + p = ep->d_name; + if (p[0] == '.' && (p[1] == '\0' || (p[1] == '.' && p[2] == '\0'))) + continue; + if (len && strncmp(p, file, len) != 0) continue; + choices++; + if ((total += strlen(p)) > MAX_TOTAL_MATCHES) { + /* This is a bit too much. */ + while (ac > 0) free(av[--ac]); + continue; + } + if ((ac % MEM_INC) == 0) { + word = malloc(sizeof(char *) * (ac + MEM_INC)); + if (!word) { + total = 0; + break; + } + if (ac) { + memcpy(word, av, ac * sizeof(char *)); + free(av); + } + *avp = av = word; + } + if ((av[ac] = strdup(p)) == NULL) { + if (ac == 0) free(av); + total = 0; + break; + } + ac++; + } + /* Clean up and return. */ + closedir(dp); + if (total > MAX_TOTAL_MATCHES) { + char many[sizeof(total) * 3]; + p = many + sizeof(many); + *--p = '\0'; + while (choices > 0) { + *--p = '0' + choices % 10; + choices /= 10; + } + while (p > many + sizeof(many) - 8) *--p = ' '; + if ((p = strdup(p)) != NULL) av[ac++] = p; + if ((p = strdup("choices")) != NULL) av[ac++] = p; + } else { + if (ac) qsort(av, ac, sizeof(char *), compare); + } + return ac; +} + +/* Split a pathname into allocated directory and trailing filename parts. */ +static int SplitPath(const char *path, char **dirpart, char **filepart) { + static char DOT[] = "."; + char *dpart; + char *fpart; + if ((fpart = strrchr(path, '/')) == NULL) { + if ((dpart = strdup(DOT)) == NULL) return -1; + if ((fpart = strdup(path)) == NULL) { + free(dpart); + return -1; + } + } else { + if ((dpart = strdup(path)) == NULL) return -1; + dpart[fpart - path + 1] = '\0'; + if ((fpart = strdup(fpart + 1)) == NULL) { + free(dpart); + return -1; + } + } + *dirpart = dpart; + *filepart = fpart; + return 0; +} + +static rl_complete_func_t *el_complete_func = NULL; + +/* For compatibility with the Heimdal project. */ +rl_complete_func_t *rl_set_complete_func(rl_complete_func_t *func) { + rl_complete_func_t *old = el_complete_func; + el_complete_func = func; + return old; +} + +/* Attempt to complete the pathname, returning an allocated copy. + * Fill in *match if we completed it, or set it to 0 if ambiguous. */ +char *el_filename_complete(char *pathname, int *match) { + char **av; + char *dir; + char *file; + char *path; + char *p; + size_t ac; + size_t end; + size_t i; + size_t j; + size_t len; + if (SplitPath((const char *)pathname, &dir, &file) < 0) return NULL; + if ((ac = FindMatches(dir, file, &av)) == 0) { + free(dir); + free(file); + return NULL; + } + p = NULL; + len = strlen(file); + if (ac == 1) { + /* Exactly one match -- finish it off. */ + *match = 1; + j = strlen(av[0]) - len + 2; + p = malloc(sizeof(char) * (j + 1)); + if (p) { + memcpy(p, av[0] + len, j); + len = strlen(dir) + strlen(av[0]) + 2; + path = malloc(sizeof(char) * len); + if (path) { + snprintf(path, len, "%s/%s", dir, av[0]); + rl_add_slash(path, p); + free(path); + } + } + } else { + *match = 0; + if (len) { + /* Find largest matching substring. */ + for (i = len, end = strlen(av[0]); i < end; i++) { + for (j = 1; j < ac; j++) { + if (av[0][i] != av[j][i]) goto breakout; + } + } + breakout: + if (i > len) { + j = i - len + 1; + p = malloc(sizeof(char) * j); + if (p) { + memcpy(p, av[0] + len, j); + p[j - 1] = '\0'; + } + } + } + } + /* Clean up and return. */ + free(dir); + free(file); + for (i = 0; i < ac; i++) free(av[i]); + free(av); + return p; +} + +char *rl_filename_completion_function(const char *text, int state) { + char *dir; + char *file; + static char **av; + static size_t i, ac; + if (!state) { + if (SplitPath(text, &dir, &file) < 0) return NULL; + ac = FindMatches(dir, file, &av); + free(dir); + free(file); + if (!ac) return NULL; + i = 0; + } + if (i < ac) return av[i++]; + do { + free(av[--i]); + } while (i > 0); + return NULL; +} + +/* Similar to el_find_word(), but used by GNU Readline API */ +static char *rl_find_token(size_t *len) { + char *ptr; + int pos; + for (pos = rl_point; pos < rl_end; pos++) { + if (isspace(rl_line_buffer[pos])) { + if (pos > 0) pos--; + break; + } + } + ptr = &rl_line_buffer[pos]; + while (pos >= 0 && !isspace(rl_line_buffer[pos])) { + if (pos == 0) break; + pos--; + } + if (ptr != &rl_line_buffer[pos]) { + *len = (size_t)(ptr - &rl_line_buffer[pos]); + return &rl_line_buffer[pos]; + } + return NULL; +} + +/* + * "uses an application-supplied generator function to generate the list + * of possible matches, and then returns the array of these matches. The + * caller should place the address of its generator function in + * rl_completion_entry_function" + */ +char **rl_completion_matches(const char *token, + rl_compentry_func_t *generator) { + int state = 0, num = 0; + char **array, *entry; + if (!generator) { + generator = rl_completion_entry_function; + if (!generator) generator = rl_filename_completion_function; + } + if (!generator) return NULL; + array = malloc(512 * sizeof(char *)); + if (!array) return NULL; + while (num < 511 && (entry = generator(token, state))) { + state = 1; + array[num++] = entry; + } + array[num] = NULL; + if (!num) { + free(array); + return NULL; + } + return array; +} + +static char *complete(char *token, int *match) { + size_t len = 0; + char *word, **words = NULL; + int start, end; + word = rl_find_token(&len); + if (!word) goto fallback; + start = word - rl_line_buffer; + end = start + len; + word = strndup(word, len); + if (!word) goto fallback; + rl_attempted_completion_over = 0; + words = rl_attempted_completion_function(word, start, end); + if (!rl_attempted_completion_over && !words) + words = rl_completion_matches(word, NULL); + if (words) { + int i = 0; + free(word); + word = NULL; + if (words[0]) word = strdup(words[0] + len); + while (words[i]) free(words[i++]); + free(words); + if (word) return word; + } +fallback: + return el_filename_complete(token, match); +} + +/* + * First check for editline specific custom completion function, then + * for any GNU Readline compat, then fallback to filename completion. + */ +char *rl_complete(char *token, int *match) { + if (el_complete_func) return el_complete_func(token, match); + if (rl_attempted_completion_function) return complete(token, match); + return el_filename_complete(token, match); +} + +static rl_list_possib_func_t *el_list_possib_func = NULL; + +/* For compatibility with the Heimdal project. */ +rl_list_possib_func_t *rl_set_list_possib_func(rl_list_possib_func_t *func) { + rl_list_possib_func_t *old = el_list_possib_func; + el_list_possib_func = func; + return old; +} + +/* Default possible completions. */ +int el_filename_list_possib(char *pathname, char ***av) { + char *dir; + char *file; + int ac; + if (SplitPath(pathname, &dir, &file) < 0) return 0; + ac = FindMatches(dir, file, av); + free(dir); + free(file); + return ac; +} + +/* Return all possible completions. */ +int rl_list_possib(char *token, char ***av) { + if (el_list_possib_func) return el_list_possib_func(token, av); + return el_filename_list_possib(token, av); +} diff --git a/third_party/editline/editline.3 b/third_party/editline/editline.3 new file mode 100644 index 00000000..b062c429 --- /dev/null +++ b/third_party/editline/editline.3 @@ -0,0 +1,274 @@ +.Dd April 27, 2019 +.Dt "THIRD_PARTY_EDITLINE" 30 "Cosmopolitan Field Manual" +.Os COSMOPOLITAN +.Sh NAME +.Nm "THIRD_PARTY_EDITLINE" +.Nd command-line editing library with history +.Sh SYNOPSIS +.Pp +.Sy #include "third_party/editline/editline.h" +.Pp +.Fn "char *readline" "const char *prompt" +.Fn "void add_history" "const char *line" +.Fn "int read_history" "const char *filename" +.Fn "int write_history" "const char *filename" +.Sh DESCRIPTION +.Nm +is a library that provides n line-editing interface with history. It +is intended to be functionally equivalent with the +.Nm readline +library provided by the Free Software Foundation, but much smaller. The +bulk of this manual page describes the basic user interface. More APIs, +both native and for +.Nm readline +compatibility , +are also available. See the +.Cm editline.h +header file for details. +.Pp +The +.Fn readline +function displays the given +.Fa prompt +on stdout, waits for user input on stdin and then returns a line of text +with the trailing newline removed. The data is returned in a buffer +allocated with +.Xr malloc 3 , +so the space should be released with +.Xr free 3 +when the calling program is done with it. +.Pp +Each line returned is automatically saved in the internal history list, +unless it happens to be equal to the previous line. This is +configurable if you are building editline from source, i.e. if you would +rather like to call +.Fn add_history +manually. +.Pp +The +.Fn read_history +and +.Fn write_history +functions can be used to load and store the history of your application. +.Em Note: +these APIs do not do any tilde or environment variable expansion of the +given filename. +.Ss User Interface +A program that uses this library provides a simple emacs-like editing +interface to its users. A line may be edited before it is sent to the +calling program by typing either control characters or escape sequences. +A control character, shown as a caret followed by a letter, is typed by +holding down the control key while the letter is typed. For example, +.Cm ^A +is a control-A. An escape sequence is entered by typing the escape key +followed by one or more characters. The escape key is abbreviated as +.Cm ESC . +Note that unlike control keys, case matters in escape sequences; +.Cm ESC F +is not the same as +.Cm ESC f . +.Pp +An editing command may be typed anywhere on the line, not just at the +beginning. In addition, a return may also be typed anywhere on the +line, not just at the end. +.Pp +Most editing commands may be given a repeat count, +.Ar n , +where +.Ar n +is a number. To enter a repeat count, type the escape key, the number, +and then the command to execute. For example, +.Cm ESC 4 ^f +moves forward four characters. If a command may be given a repeat count +then the text +.Cm [n] +is given at the end of its description. +.Pp +The following control characters are accepted: +.Pp +.Bl -tag -width "ESC DEL " -compact +.It ^A +Move to the beginning of the line +.It ^B +Move left (backwards) [n] +.It ^D +Delete character [n] +.It ^E +Move to end of line +.It ^F +Move right (forwards) [n] +.It ^G +Ring the bell +.It ^H +Delete character before cursor (backspace key) [n] +.It ^I +Complete filename (tab key); see below +.It ^J +Done with line (return key) +.It ^K +Kill to end of line (or column [n]) +.It ^L +Redisplay line +.It ^M +Done with line (alternate return key) +.It ^N +Get next line from history [n] +.It ^P +Get previous line from history [n] +.It ^R +Search backward (forward if [n]) through history for text; prefixing the +string with a caret (^) forces it to match only at the beginning of a +history line +.It ^T +Transpose characters +.It ^V +Insert next character, even if it is an edit command +.It ^W +Wipe to the mark +.It ^X^X +Exchange current location and mark +.It ^Y +Yank back last killed text +.It ^[ +Start an escape sequence (escape key) +.It ^]c +Move forward to next character +.Cm c +.It ^? +Delete character before cursor (delete key) [n] +.Ed +.Pp +The following escape sequences are provided: +.Pp +.Bl -tag -width "ESC DEL " -compact +.It ESC ^H +Delete previous word (backspace key) [n] +.It ESC DEL +Delete previous word (delete key) [n] +.It ESC SP +Set the mark (space key); see ^X^X and ^Y above +.It ESC\ . +Get the last (or [n]'th) word from previous line +.It ESC\ ? +Show possible completions; see below +.It ESC < +Move to start of history +.It ESC > +Move to end of history +.It ESC b +Move backward a word [n] +.It ESC d +Delete word under cursor [n] +.It ESC f +Move forward a word [n] +.It ESC l +Make word lowercase [n] +.It ESC m +Toggle if 8bit chars display normally or with an +.Ar M- +prefix +.It ESC u +Make word uppercase [n] +.It ESC y +Yank back last killed text +.It ESC v +Show library version +.It ESC w +Make area up to mark yankable +.It ESC nn +Set repeat count to the number nn +.It ESC C +Read from environment variable +.Ar $C , +where +.Ar C +is an uppercase letter +.El +.Pp +The +.Nm +library has a small macro facility. If you type the escape key followed +by an uppercase letter, +.Ar C , +then the contents of the environment variable +.Ar $C +are read in as if you had typed them at the keyboard. For example, if +the variable +.Ar $L +contains the following: +.Pp +.Dl ^A^Kecho '^V^[[H^V^[[2J'^M +.Pp +Then typing +.Cm ESC L +will move to the beginning of the line, kill the entire line, enter the +echo command needed to clear the terminal (if your terminal is like a +VT-100), and send the line back to the shell. +.Pp +The +.Nm +library also does filename completion. Suppose the root directory has +the following files in it: +.Pp +.Dl bin vmunix +.Dl core vmunix.old +.Pp +If you type +.Cm rm /v +and then the tab key, +.Nm +will then finish off as much of the name as possible by adding +.Ar munix . +Because the name is not unique, it will then beep. If you type the +escape key and a question mark, it will display the two choices. If you +then type a period and a tab, the library will finish off the filename +for you: +.Pp +.Bd -ragged -offset indent +rm /v[TAB] +.Em munix +\&.[TAB] +.Em old +.Ed +.Pp +The tab key is shown by [TAB] and the automatically-entered text +is shown in italics, or underline. +.Sh USAGE +To include +.Nm +in your program, call it as you do any other function and link your +program with +.Ar -leditline . +.Ss Example +The following brief example lets you enter a line and edit it, then displays it. +.Pp +.Bd -literal -offset indent +#include +#include +#include + +int main(void) +{ + char *p; + + while ((p = readline("CLI> "))) { + puts(p); + free(p); + } + + return 0; +} +.El +.Sh AUTHORS +The original editline library was posted to comp.sources.unix newsgroup +by created by Simmule R. Turner and Rich Salz in 1992. It now exists in +several forks: Debian, Minix, Heimdal, Festival speech tools, Mozilla, +Google Gadgets for Linux, and many other places. The original manual +page was made by David W. Sanderson. +.Pp +This version was originally based on the Minix 2 sources, but has since +evolved to include patches from all relevant forks. It is currently +maintained by Joachim Nilsson at GitHub, +.Aq http://github.com/troglobit/editline +.Sh BUGS +Does not handle multiple lines well. diff --git a/third_party/editline/editline.c b/third_party/editline/editline.c new file mode 100644 index 00000000..8d95f9e7 --- /dev/null +++ b/third_party/editline/editline.c @@ -0,0 +1,1557 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/termios.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/macros.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/termios.h" +#include "third_party/editline/editline.h" +#include "third_party/editline/internal.h" + +asm(".ident\t\"\\n\\n\ +Cosmopolitan Linenoise (BSD-like license)\\n\ +Copyright 2019 Justine Alexandra Roberts Tunney\\n\ +Copyright 1992,1993 Simmule Turner and Rich Salz\\n\ +All rights reserved.\\n\ +\\n\ +This software is not subject to any license of the American Telephone\\n\ +and Telegraph Company or of the Regents of the University of California.\\n\ +\\n\ +Permission is granted to anyone to use this software for any purpose on\\n\ +any computer system, and to alter it and redistribute it freely, subject\\n\ +to the following restrictions:\\n\ +1. The authors are not responsible for the consequences of use of this\\n\ + software, no matter how awful, even if they arise from flaws in it.\\n\ +2. The origin of this software must not be misrepresented, either by\\n\ + explicit claim or by omission. Since few users ever read sources,\\n\ + credits must appear in the documentation.\\n\ +3. Altered versions must be plainly marked as such, and must not be\\n\ + misrepresented as being the original software. Since few users\\n\ + ever read sources, credits must appear in the documentation.\\n\ +4. This notice may not be removed or altered.\""); +asm(".include \"libc/disclaimer.inc\""); + +#define SCREEN_COLS 80 +#define SCREEN_ROWS 24 +#define EL_STDIN 0 +#define EL_STDOUT 1 +#define NO_ARG (-1) +#define DEL 127 +#define SEPS "\"#$&'()*:;<=>?[\\]^`{|}~\n\t " + +enum EditlineCase { TOupper, TOlower, TOcapitalize }; + +struct EditlineKeymap { + int Key; + el_status_t (*Function)(void); +}; + +struct EditlineHistory { + int Size; + int Pos; + char **Lines; +}; + +rl_getc_func_t *rl_getc_function = rl_getc; +rl_hook_func_t *rl_event_hook; +rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal; +rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal; + +int rl_eof; +int rl_erase; +int rl_intr; +int rl_kill; +int rl_quit; +int rl_susp; +int el_hist_size = 15; + +static struct EditlineHistory g_hist = { + .Size = 0, + .Pos = 0, + .Lines = NULL, +}; + +static char NILSTR[] = ""; +static const char *el_input = NILSTR; +static char *Yanked; +static char *Screen; +static char NEWLINE[] = "\r\n"; +static char CLEAR[] = "\ec"; +static const char *el_term = "dumb"; +static int Repeat; +static int old_point; +static int el_push_back; +static int el_pushed; +static int el_intr_pending; +static int el_infd = EL_STDIN; +static int el_outfd = EL_STDOUT; +static struct EditlineKeymap Map[]; +static struct EditlineKeymap MetaMap[]; +static size_t Length = 0; +static size_t ScreenCount; +static size_t ScreenSize; +static char *backspace = "\b"; +static char *old_search = NULL; +static int tty_cols = SCREEN_COLS; +static int tty_rows = SCREEN_ROWS; +static int Searching = 0; +static const char *(*search_move)(void); +static const char *old_prompt = NULL; +static rl_vcpfunc_t *line_handler = NULL; +static const char *rl_saved_prompt = NULL; + +int el_no_echo = 0; /* e.g., under Emacs */ +int el_no_hist = 0; +int rl_point; +int rl_mark; +int rl_end; +int rl_meta_chars = 0; /* 8-bit chars as actual char(0) or `M-x'(1)? */ +int rl_inhibit_complete = 0; +char *rl_line_buffer = NULL; +const char *rl_prompt = NULL; +const char *rl_readline_name = + NULL; /* Set by calling program, for conditional parsing of ~/.inputrc - Not + supported yet! */ +FILE *rl_instream = NULL; /* The stdio stream from which input is read. Defaults + to stdin if NULL */ +FILE *rl_outstream = NULL; /* The stdio stream to which output is flushed. + Defaults to stdout if NULL */ + +/* Declarations. */ +static char *editinput(int complete); +#ifdef CONFIG_USE_TERMCAP +extern char *tgetstr(const char *, char **); +extern int tgetent(char *, const char *); +extern int tgetnum(const char *); +#endif + +/* +** Misc. local helper functions. +*/ +static int is_alpha_num(unsigned char c) { + if (isalnum(c)) return 1; + if (ISMETA(c)) return 1; + if (ISCTL(c)) return 1; + return 0; +} + +/* +** TTY input/output functions. +*/ + +static void tty_flush(void) { + ssize_t res; + if (!ScreenCount) return; + if (!el_no_echo) { + res = write(el_outfd, Screen, ScreenCount); + if (res > 0) ScreenCount = 0; + } +} + +static void tty_put(const char c) { + if (el_no_echo) return; + Screen[ScreenCount] = c; + if (++ScreenCount >= ScreenSize) { + ScreenSize += SCREEN_INC; + Screen = realloc(Screen, sizeof(char) * ScreenSize); + } +} + +static void tty_puts(const char *p) { + while (*p) tty_put(*p++); +} + +static void tty_show(unsigned char c) { + if (c == DEL) { + tty_put('^'); + tty_put('?'); + } else if (ISCTL(c)) { + tty_put('^'); + tty_put(UNCTL(c)); + } else if (rl_meta_chars && ISMETA(c)) { + tty_put('M'); + tty_put('-'); + tty_put(UNMETA(c)); + } else { + tty_put(c); + } +} + +static void tty_string(char *p) { + while (*p) tty_show(*p++); +} + +static void tty_push(int c) { + el_pushed = 1; + el_push_back = c; +} + +int rl_getc(void) { + int r; + char c; + do { + r = read(el_infd, &c, 1); + } while (r == -1 && errno == EINTR); + return r == 1 ? c : EOF; +} + +static int tty_get(void) { + tty_flush(); + if (el_pushed) { + el_pushed = 0; + return el_push_back; + } + if (*el_input) return *el_input++; + return rl_getc_function(); +} + +#define tty_back() tty_puts(backspace) + +static void tty_backn(int n) { + while (--n >= 0) tty_back(); +} + +static void tty_info(void) { + rl_reset_terminal(NULL); +} + +/* +** Glue routines to rl_ttyset() +*/ +void rl_prep_terminal(int meta_flag) { + rl_meta_chars = !meta_flag; + rl_ttyset(0); +} + +void rl_deprep_terminal(void) { + rl_ttyset(1); +} + +/* +** Print an array of words in columns. +*/ +void el_print_columns(int ac, char **av) { + char *p; + int i; + int j; + int k; + int len; + int skip; + int longest; + int cols; + int colwidth; + /* Find longest name, determine column count from that. */ + for (longest = 0, i = 0; i < ac; i++) { + if ((j = strlen((char *)av[i])) > longest) longest = j; + } + colwidth = longest + 3; + if (colwidth > tty_cols) colwidth = tty_cols; + cols = tty_cols / colwidth; + tty_puts(NEWLINE); + for (skip = ac / cols + 1, i = 0; i < skip; i++) { + for (j = i; j < ac; j += skip) { + for (p = av[j], len = strlen((char *)p), k = len; --k >= 0; p++) + tty_put(*p); + if (j + skip < ac) { + while (++len < colwidth) tty_put(' '); + } + } + tty_puts(NEWLINE); + } +} + +static void reposition(void) { + int i; + tty_put('\r'); + tty_puts(rl_prompt); + for (i = 0; i < rl_point; i++) tty_show(rl_line_buffer[i]); +} + +static void left(el_status_t Change) { + if (rl_point) { + tty_back(); + if (ISMETA(rl_line_buffer[rl_point - 1])) { + if (rl_meta_chars) { + tty_back(); + tty_back(); + } + } else if (ISCTL(rl_line_buffer[rl_point - 1])) { + tty_back(); + } + } + if (Change == CSmove) rl_point--; +} + +static void right(el_status_t Change) { + tty_show(rl_line_buffer[rl_point]); + if (Change == CSmove) rl_point++; +} + +el_status_t el_ring_bell(void) { + tty_put('\07'); + tty_flush(); + return CSstay; +} + +static el_status_t do_macro(int c) { + char name[4]; + name[0] = '_'; + name[1] = c; + name[2] = '_'; + name[3] = '\0'; + if ((el_input = (char *)getenv((char *)name)) == NULL) { + el_input = NILSTR; + return el_ring_bell(); + } + return CSstay; +} + +/* Skip forward to start of next word. If @move is set we also move the cursor. + */ +static el_status_t do_forward(el_status_t move) { + int i; + char *p; + i = 0; + do { + p = &rl_line_buffer[rl_point]; + /* Skip leading whitespace, like FSF Readline */ + for (; rl_point < rl_end && (p[0] == ' ' || !is_alpha_num(p[0])); + rl_point++, p++) { + if (move == CSmove) right(CSstay); + } + /* Skip to end of word, if inside a word. */ + for (; rl_point < rl_end && is_alpha_num(p[0]); rl_point++, p++) { + if (move == CSmove) right(CSstay); + } + /* Skip to next word, or skip leading white space if outside a word. */ + for (; rl_point < rl_end && (p[0] == ' ' || !is_alpha_num(p[0])); + rl_point++, p++) { + if (move == CSmove) right(CSstay); + } + if (rl_point == rl_end) break; + } while (++i < Repeat); + return CSstay; +} + +static el_status_t do_case(enum EditlineCase type) { + int i; + int end; + int count; + char *p; + do_forward(CSstay); + if (old_point != rl_point) { + if ((count = rl_point - old_point) < 0) count = -count; + rl_point = old_point; + if ((end = rl_point + count) > rl_end) end = rl_end; + for (i = rl_point, p = &rl_line_buffer[i]; rl_point < end; p++) { + if ((type == TOupper) || (type == TOcapitalize && rl_point == i)) { + if (islower(*p)) *p = toupper(*p); + } else if (isupper(*p)) { + *p = tolower(*p); + } + right(CSmove); + } + } + return CSstay; +} + +static el_status_t case_down_word(void) { + return do_case(TOlower); +} + +static el_status_t case_up_word(void) { + return do_case(TOupper); +} + +static el_status_t case_cap_word(void) { + return do_case(TOcapitalize); +} + +static void ceol(void) { + int extras = 0; + int i; + char *p; + while (rl_point < 0) { + tty_put(' '); + rl_point++; + extras++; + } + for (i = rl_point, p = &rl_line_buffer[i]; i <= rl_end; i++, p++) { + tty_put(' '); + if (ISMETA(*p)) { + if (rl_meta_chars) { + tty_put(' '); + tty_put(' '); + extras += 2; + } + } else if (ISCTL(*p)) { + tty_put(' '); + extras++; + } + } + for (i += extras; i > rl_point; i--) tty_back(); +} + +static void clear_line(void) { + rl_point = -(int)strlen(rl_prompt); + tty_put('\r'); + ceol(); + rl_point = 0; + rl_end = 0; + rl_line_buffer[0] = '\0'; +} + +static el_status_t insert_string(const char *p) { + size_t len; + int i; + char *line; + char *q; + len = strlen(p); + if (rl_end + len >= Length) { + line = malloc(sizeof(char) * (Length + len + MEM_INC)); + if (!line) return CSstay; + if (Length) { + memcpy(line, rl_line_buffer, Length); + free(rl_line_buffer); + } + rl_line_buffer = line; + Length += len + MEM_INC; + } + for (q = &rl_line_buffer[rl_point], i = rl_end - rl_point; --i >= 0;) + q[len + i] = q[i]; + memcpy(&rl_line_buffer[rl_point], p, len); + rl_end += len; + rl_line_buffer[rl_end] = '\0'; + tty_string(&rl_line_buffer[rl_point]); + rl_point += len; + return rl_point == rl_end ? CSstay : CSmove; +} + +int rl_insert_text(const char *text) { + int mark = rl_point; + insert_string(text); + ceol(); + return rl_point - mark; +} + +static el_status_t redisplay(int cls) { + if (cls && rl_point == 0 && rl_end == 0) + tty_puts(CLEAR); + else + tty_puts("\r\e[K"); + tty_puts(rl_prompt); + tty_string(rl_line_buffer); + return CSmove; +} + +static el_status_t refresh(void) { + return redisplay(1); +} + +int rl_refresh_line(int ignore1 __attribute__((unused)), + int ignore2 __attribute__((unused))) { + redisplay(0); + return 0; +} + +static el_status_t toggle_meta_mode(void) { + rl_meta_chars = !rl_meta_chars; + return redisplay(0); +} + +const char *el_next_hist(void) { + return g_hist.Pos >= g_hist.Size - 1 ? NULL : g_hist.Lines[++g_hist.Pos]; +} + +const char *el_prev_hist(void) { + return g_hist.Pos == 0 ? NULL : g_hist.Lines[--g_hist.Pos]; +} + +static el_status_t do_insert_hist(const char *p) { + if (p == NULL) return el_ring_bell(); + clear_line(); + rl_point = 0; + reposition(); + rl_end = 0; + return insert_string(p); +} + +static el_status_t do_hist(const char *(*move)(void)) { + const char *p; + int i = 0; + do { + if ((p = move()) == NULL) return el_ring_bell(); + } while (++i < Repeat); + return do_insert_hist(p); +} + +static el_status_t h_next(void) { + if (el_no_hist) return CSstay; + return do_hist(el_next_hist); +} + +static el_status_t h_prev(void) { + if (el_no_hist) return CSstay; + return do_hist(el_prev_hist); +} + +static el_status_t h_first(void) { + return do_insert_hist(g_hist.Lines[g_hist.Pos = 0]); +} + +static el_status_t h_last(void) { + return do_insert_hist(g_hist.Lines[g_hist.Pos = g_hist.Size - 1]); +} + +/* +** Return zero if pat appears as a substring in text. +*/ +static int substrcmp(const char *text, const char *pat, size_t len) { + char c; + if ((c = *pat) == '\0') return *text == '\0'; + for (; *text; text++) { + if (*text == c && strncmp(text, pat, len) == 0) return 0; + } + return 1; +} + +static const char *search_hist(const char *search, const char *(*move)(void)) { + int len; + int pos; + int (*match)(const char *s1, const char *s2, size_t n); + const char *pat; + /* Save or get remembered search pattern. */ + if (search && *search) { + if (old_search) free(old_search); + old_search = strdup(search); + } else { + if (old_search == NULL || *old_search == '\0') return NULL; + search = old_search; + } + /* Set up pattern-finder. */ + if (*search == '^') { + match = strncmp; + pat = search + 1; + } else { + match = substrcmp; + pat = search; + } + len = strlen(pat); + pos = g_hist.Pos; /* Save g_hist.Pos */ + while (move()) { + if (match(g_hist.Lines[g_hist.Pos], pat, len) == 0) + return g_hist.Lines[g_hist.Pos]; + } + g_hist.Pos = pos; /* Restore g_hist.Pos */ + return NULL; +} + +static el_status_t h_search_end(const char *p) { + rl_prompt = old_prompt; + Searching = 0; + if (el_intr_pending > 0) { + el_intr_pending = 0; + clear_line(); + return redisplay(0); + } + p = search_hist(p, search_move); + if (p == NULL) { + el_ring_bell(); + clear_line(); + return redisplay(0); + } + return do_insert_hist(p); +} + +static el_status_t h_search(void) { + if (Searching) return el_ring_bell(); + Searching = 1; + clear_line(); + old_prompt = rl_prompt; + rl_prompt = "Search: "; + tty_puts(rl_prompt); + search_move = Repeat == NO_ARG ? el_prev_hist : el_next_hist; + if (line_handler) { + editinput(0); + return CSstay; + } + return h_search_end(editinput(1)); +} + +static el_status_t fd_char(void) { + int i = 0; + do { + if (rl_point >= rl_end) break; + right(CSmove); + } while (++i < Repeat); + return CSstay; +} + +static void save_yank(int begin, int i) { + if (Yanked) { + free(Yanked); + Yanked = NULL; + } + if (i < 1) return; + Yanked = malloc(sizeof(char) * (i + 1)); + if (Yanked) { + memcpy(Yanked, &rl_line_buffer[begin], i); + Yanked[i] = '\0'; + } +} + +static el_status_t delete_string(int count) { + int i; + char *p; + if (count <= 0 || rl_end == rl_point) return el_ring_bell(); + if (count == 1 && rl_point == rl_end - 1) { + /* Optimize common case of delete at end of line. */ + rl_end--; + p = &rl_line_buffer[rl_point]; + i = 1; + tty_put(' '); + if (ISCTL(*p)) { + i = 2; + tty_put(' '); + } else if (rl_meta_chars && ISMETA(*p)) { + i = 3; + tty_put(' '); + tty_put(' '); + } + tty_backn(i); + *p = '\0'; + return CSmove; + } + if (rl_point + count > rl_end && (count = rl_end - rl_point) <= 0) + return CSstay; + if (count > 1) save_yank(rl_point, count); + for (p = &rl_line_buffer[rl_point], i = rl_end - (rl_point + count) + 1; + --i >= 0; p++) + p[0] = p[count]; + ceol(); + rl_end -= count; + tty_string(&rl_line_buffer[rl_point]); + return CSmove; +} + +static el_status_t bk_char(void) { + int i = 0; + do { + if (rl_point == 0) break; + left(CSmove); + } while (++i < Repeat); + return CSstay; +} + +static el_status_t bk_del_char(void) { + int i = 0; + do { + if (rl_point == 0) break; + left(CSmove); + } while (++i < Repeat); + return delete_string(i); +} + +static el_status_t kill_line(void) { + int i; + if (Repeat != NO_ARG) { + if (Repeat < rl_point) { + i = rl_point; + rl_point = Repeat; + reposition(); + delete_string(i - rl_point); + } else if (Repeat > rl_point) { + right(CSmove); + delete_string(Repeat - rl_point - 1); + } + return CSmove; + } + save_yank(rl_point, rl_end - rl_point); + rl_line_buffer[rl_point] = '\0'; + ceol(); + rl_end = rl_point; + return CSstay; +} + +static el_status_t insert_char(int c) { + el_status_t s; + char buff[2]; + char *p; + char *q; + int i; + if (Repeat == NO_ARG || Repeat < 2) { + buff[0] = c; + buff[1] = '\0'; + return insert_string(buff); + } + p = malloc(sizeof(char) * (Repeat + 1)); + if (!p) return CSstay; + for (i = Repeat, q = p; --i >= 0;) *q++ = c; + *q = '\0'; + Repeat = 0; + s = insert_string(p); + free(p); + return s; +} + +static el_status_t beg_line(void) { + if (rl_point) { + rl_point = 0; + return CSmove; + } + return CSstay; +} + +static el_status_t end_line(void) { + if (rl_point != rl_end) { + rl_point = rl_end; + return CSmove; + } + return CSstay; +} + +static el_status_t del_char(void) { + return delete_string(Repeat == NO_ARG ? CSeof : Repeat); +} + +el_status_t el_del_char(void) { + return del_char(); +} + +static el_status_t fd_word(void) { + return do_forward(CSmove); +} + +static el_status_t bk_word(void) { + int i; + char *p; + i = 0; + do { + for (p = &rl_line_buffer[rl_point]; + p > rl_line_buffer && !is_alpha_num(p[-1]); p--) + left(CSmove); + for (; p > rl_line_buffer && !isblank(p[-1]) && is_alpha_num(p[-1]); p--) + left(CSmove); + if (rl_point == 0) break; + } while (++i < Repeat); + return CSstay; +} + +static el_status_t meta(void) { + int c; + struct EditlineKeymap *kp; + if ((c = tty_get()) == EOF) return CSeof; +#ifdef CONFIG_ANSI_ARROWS + /* Also include VT-100 arrows. */ + if (c == '[' || c == 'O') { + switch (tty_get()) { + case EOF: + return CSeof; + case '1': { + char seq[4] = {0}; + for (c = 0; c < 3; c++) seq[c] = tty_get(); + if (!strncmp(seq, ";5C", 3)) return fd_word(); /* Ctrl+Right */ + if (!strncmp(seq, ";5D", 3)) return bk_word(); /* Ctrl+Left */ + break; + } + case '2': + tty_get(); + return CSstay; /* Insert */ + case '3': + tty_get(); + return del_char(); /* Delete */ + case '5': + tty_get(); + return CSstay; /* PgUp */ + case '6': + tty_get(); + return CSstay; /* PgDn */ + case 'A': + return h_prev(); /* Up */ + case 'B': + return h_next(); /* Down */ + case 'C': + return fd_char(); /* Left */ + case 'D': + return bk_char(); /* Right */ + case 'F': + return end_line(); /* End */ + case 'H': + return beg_line(); /* Home */ + default: /* Fall through */ + break; + } + return el_ring_bell(); + } +#endif /* CONFIG_ANSI_ARROWS */ + if (isdigit(c)) { + for (Repeat = c - '0'; (c = tty_get()) != EOF && isdigit(c);) + Repeat = Repeat * 10 + c - '0'; + tty_push(c); + return CSstay; + } + if (isupper(c)) return do_macro(c); + for (kp = MetaMap; kp->Function; kp++) { + if (kp->Key == c) return kp->Function(); + } + return el_ring_bell(); +} + +static el_status_t emacs(int c) { + el_status_t s; + struct EditlineKeymap *kp; + /* Save point before interpreting input character 'c'. */ + old_point = rl_point; + if (rl_meta_chars && ISMETA(c)) { + tty_push(UNMETA(c)); + return meta(); + } + for (kp = Map; kp->Function; kp++) { + if (kp->Key == c) break; + } + if (kp->Function) { + s = kp->Function(); + if (s == CSdispatch) /* If Function is inhibited. */ + s = insert_char(c); + } else { + s = insert_char(c); + } + if (!el_pushed) { + /* No pushback means no repeat count; hacky, but true. */ + Repeat = NO_ARG; + } + return s; +} + +static el_status_t tty_special(int c) { +#ifdef CONFIG_SIGINT + if (c == rl_intr) { + el_intr_pending = SIGINT; + return CSsignal; + } +#endif + if (c == rl_quit) { + el_intr_pending = SIGQUIT; + return CSeof; + } +#ifdef CONFIG_SIGSTOP + if (c == rl_susp) { + el_intr_pending = SIGTSTP; + return CSsignal; + } +#endif + if (rl_meta_chars && ISMETA(c)) return CSdispatch; + if (c == rl_erase || c == DEL) return bk_del_char(); + if (c == rl_kill) { + if (rl_point != 0) { + rl_point = 0; + reposition(); + } + Repeat = NO_ARG; + return kill_line(); + } +#ifdef CONFIG_EOF + if (c == rl_eof && rl_point == 0 && rl_end == 0) return CSeof; +#endif + return CSdispatch; +} + +static char *editinput(int complete) { + int c; + do { + c = tty_get(); + if (c == EOF) break; + switch (tty_special(c)) { + case CSdone: + return rl_line_buffer; + case CSeof: + return NULL; + case CSsignal: + return (char *)""; + case CSmove: + reposition(); + break; + case CSdispatch: + switch (emacs(c)) { + case CSdone: + return rl_line_buffer; + case CSeof: + return NULL; + case CSsignal: + return (char *)""; + case CSmove: + reposition(); + break; + case CSdispatch: + case CSstay: + break; + } + break; + case CSstay: + break; + } + } while (complete); + return NULL; +} + +static void hist_alloc(void) { + if (!g_hist.Lines) g_hist.Lines = calloc(el_hist_size, sizeof(char *)); +} + +static void hist_add(const char *p) { + int i; + char *s; +#ifdef CONFIG_UNIQUE_HISTORY + if (g_hist.Size && strcmp(p, g_hist.Lines[g_hist.Size - 1]) == 0) return; +#endif + s = strdup(p); + if (s == NULL) return; + if (g_hist.Size < el_hist_size) { + g_hist.Lines[g_hist.Size++] = s; + } else { + free(g_hist.Lines[0]); + for (i = 0; i < el_hist_size - 1; i++) + g_hist.Lines[i] = g_hist.Lines[i + 1]; + g_hist.Lines[i] = s; + } + g_hist.Pos = g_hist.Size - 1; +} + +static char *read_redirected(void) { + int size = MEM_INC; + char *p; + char *line; + char *end; + p = line = malloc(sizeof(char) * size); + if (!p) return NULL; + end = p + size; + while (1) { + if (p == end) { + int oldpos = end - line; + size += MEM_INC; + p = line = realloc(line, sizeof(char) * size); + if (!p) return NULL; + end = p + size; + p += oldpos; /* Continue where we left off... */ + } + if (read(el_infd, p, 1) <= 0) { + /* Ignore "incomplete" lines at EOF, just like we do for a tty. */ + free(line); + return NULL; + } + if (*p == '\n') break; + p++; + } + *p = '\0'; + return line; +} + +/* For compatibility with FSF readline. */ +void rl_reset_terminal(const char *terminal_name) { +#ifdef CONFIG_USE_TERMCAP + char buf[1024]; + char *bp; +#endif +#ifdef TIOCGWINSZ + struct winsize W; +#endif + if (terminal_name) { + el_term = terminal_name; + } else if ((el_term = getenv("TERM")) == NULL) { + el_term = "dumb"; + } + /* Initialize to faulty values to trigger fallback if nothing else works. */ + tty_cols = tty_rows = -1; +#ifdef CONFIG_USE_TERMCAP + bp = buf; + if (-1 != tgetent(buf, el_term)) { + if ((backspace = tgetstr("le", &bp)) != NULL) backspace = strdup(backspace); + tty_cols = tgetnum("co"); + tty_rows = tgetnum("li"); + } + /* Make sure to check width & rows and fallback to TIOCGWINSZ if available. */ +#endif + if (tty_cols <= 0 || tty_rows <= 0) { +#ifdef TIOCGWINSZ + if (ioctl(el_outfd, TIOCGWINSZ, &W) >= 0 && W.ws_col > 0 && W.ws_row > 0) { + tty_cols = (int)W.ws_col; + tty_rows = (int)W.ws_row; + return; + } +#endif + tty_cols = SCREEN_COLS; + tty_rows = SCREEN_ROWS; + } +} + +void rl_initialize(void) { + if (!rl_prompt) rl_prompt = "? "; + hist_alloc(); + /* Setup I/O descriptors */ + if (!rl_instream) + el_infd = EL_STDIN; + else + el_infd = fileno(rl_instream); + if (el_infd < 0) el_infd = EL_STDIN; + if (!rl_outstream) + el_outfd = EL_STDOUT; + else + el_outfd = fileno(rl_outstream); + if (el_outfd < 0) el_outfd = EL_STDOUT; +} + +void rl_uninitialize(void) { + int i; + /* Uninitialize the history */ + if (g_hist.Lines) { + for (i = 0; i < el_hist_size; i++) { + if (g_hist.Lines[i]) free(g_hist.Lines[i]); + g_hist.Lines[i] = NULL; + } + free(g_hist.Lines); + g_hist.Lines = NULL; + } + g_hist.Size = 0; + g_hist.Pos = 0; + if (old_search) free(old_search); + old_search = NULL; + /* Uninitialize the line buffer */ + if (rl_line_buffer) free(rl_line_buffer); + rl_line_buffer = NULL; + Length = 0; +} + +void rl_save_prompt(void) { + rl_saved_prompt = rl_prompt; +} + +void rl_restore_prompt(void) { + if (rl_saved_prompt) rl_prompt = rl_saved_prompt; +} + +void rl_set_prompt(const char *prompt) { + rl_prompt = prompt; +} + +void rl_clear_message(void) { /* Nothing to do atm. */ +} + +void rl_forced_update_display() { + redisplay(0); + tty_flush(); +} + +static int el_prep(const char *prompt) { + rl_initialize(); + if (!rl_line_buffer) { + Length = MEM_INC; + rl_line_buffer = malloc(sizeof(char) * Length); + if (!rl_line_buffer) return -1; + } + tty_info(); + rl_prep_term_function(!rl_meta_chars); + hist_add(NILSTR); + ScreenSize = SCREEN_INC; + Screen = malloc(sizeof(char) * ScreenSize); + if (!Screen) return -1; + rl_prompt = prompt ? prompt : NILSTR; + if (el_no_echo) { + int old = el_no_echo; + el_no_echo = 0; + tty_puts(rl_prompt); + tty_flush(); + el_no_echo = old; + } else { + tty_puts(rl_prompt); + } + Repeat = NO_ARG; + old_point = rl_point = rl_mark = rl_end = 0; + rl_line_buffer[0] = '\0'; + el_intr_pending = -1; + return 0; +} + +static char *el_deprep(char *line) { + if (line) { + line = strdup(line); + tty_puts(NEWLINE); + tty_flush(); + } + rl_deprep_term_function(); + if (Screen) { + free(Screen); + Screen = NULL; + } + free(g_hist.Lines[--g_hist.Size]); + g_hist.Lines[g_hist.Size] = NULL; + /* Add to history, unless no-echo or no-history mode ... */ + if (!el_no_echo && !el_no_hist) { + if (line != NULL && *line != '\0') hist_add(line); + } + if (el_intr_pending > 0) { + int signo = el_intr_pending; + el_intr_pending = 0; + kill(getpid(), signo); + } + return line; +} + +void rl_callback_handler_install(const char *prompt, rl_vcpfunc_t *lhandler) { + if (!lhandler) return; + line_handler = lhandler; + /* + * Any error from el_prep() is handled by the lhandler callbck as + * soon as the user calls rl_callback_read_char(). + */ + el_prep(prompt); + tty_flush(); +} + +/* + * Reads one character at a time, when a complete line has been received + * the lhandler from rl_callback_handler_install() is called with the + * line as argument. + * + * If the callback returns the terminal is prepped for reading a new + * line. + * + * If any error occurs, either in the _install() phase, or while reading + * one character, this function restores the terminal and calls lhandler + * with a NULL argument. + */ +void rl_callback_read_char(void) { + char *line; + if (!line_handler) { + errno = EINVAL; + return; + } + /* + * Check if rl_callback_handler_install() failed + * This is the only point where we can tell user + */ + if (!Screen || !rl_line_buffer) { + errno = ENOMEM; + line_handler(el_deprep(NULL)); + return; + } + line = editinput(0); + if (line) { + char *l; + if (Searching) { + h_search_end(line); + tty_flush(); + return; + } + l = el_deprep(line); + line_handler(l); + if (el_prep(rl_prompt)) line_handler(NULL); + } + tty_flush(); +} + +void rl_callback_handler_remove(void) { + if (!line_handler) return; + el_deprep(NULL); + line_handler = NULL; +} + +char *readline(const char *prompt) { + /* Unless called by the user already. */ + rl_initialize(); + if (!isatty(el_infd)) { + tty_flush(); + return read_redirected(); + } + if (el_prep(prompt)) return NULL; + return el_deprep(editinput(1)); +} + +/* + * Even though readline() itself adds history automatically, the user + * can also add lines. This is for compatibility with GNU Readline. + */ +void add_history(const char *p) { + if (p == NULL || *p == '\0') return; + hist_add(p); +} + +int read_history(const char *filename) { + FILE *fp; + char buf[SCREEN_INC]; + hist_alloc(); + fp = fopen(filename, "r"); + if (fp) { + g_hist.Size = 0; + while (g_hist.Size < el_hist_size) { + if (!fgets(buf, SCREEN_INC, fp)) break; + buf[strlen(buf) - 1] = 0; /* Remove '\n' */ + add_history(buf); + } + return fclose(fp); + } + return errno; +} + +int write_history(const char *filename) { + FILE *fp; + hist_alloc(); + fp = fopen(filename, "w"); + if (fp) { + int i = 0; + while (i < g_hist.Size) fprintf(fp, "%s\n", g_hist.Lines[i++]); + return fclose(fp); + } + return errno; +} + +/* +** Move back to the beginning of the current word and return an +** allocated copy of it. +*/ +char *el_find_word(void) { + char *p, *q; + char *word; + size_t len; + p = &rl_line_buffer[rl_point]; + while (p > rl_line_buffer) { + p--; + if (p > rl_line_buffer && p[-1] == '\\') { + p--; + } else { + if (strchr(SEPS, (char)*p) != NULL) { + p++; + break; + } + } + } + len = rl_point - (p - rl_line_buffer) + 1; + word = malloc(sizeof(char) * len); + if (!word) return NULL; + q = word; + while (p < &rl_line_buffer[rl_point]) { + if (*p == '\\') { + if (++p == &rl_line_buffer[rl_point]) break; + } + *q++ = *p++; + } + *q = '\0'; + return word; +} + +static el_status_t c_possible(void) { + char **av; + char *word; + int ac; + word = el_find_word(); + ac = rl_list_possib(word, &av); + if (word) free(word); + if (ac) { + el_print_columns(ac, av); + while (--ac >= 0) free(av[ac]); + free(av); + return CSmove; + } + return el_ring_bell(); +} + +static el_status_t c_complete(void) { + char *p, *q; + char *word, *string; + size_t len; + int unique; + el_status_t s = CSdone; + if (rl_inhibit_complete) return CSdispatch; + word = el_find_word(); + p = rl_complete(word, &unique); + if (word) free(word); + if (p) { + len = strlen(p); + word = p; + string = q = malloc(sizeof(char) * (2 * len + 1)); + if (!string) { + free(word); + return CSstay; + } + while (*p) { + if ((*p < ' ' || strchr(SEPS, *p) != NULL) && (!unique || p[1] != 0)) { + *q++ = '\\'; + } + *q++ = *p++; + } + *q = '\0'; + free(word); + if (len > 0) { + s = insert_string(string); +#ifdef CONFIG_TERMINAL_BELL + if (!unique) el_ring_bell(); +#endif + } + free(string); + if (len > 0) return s; + } + return c_possible(); +} + +static el_status_t accept_line(void) { + rl_line_buffer[rl_end] = '\0'; + return CSdone; +} + +static el_status_t end_of_input(void) { + rl_line_buffer[rl_end] = '\0'; + return CSeof; +} + +static el_status_t ctrl_z(void) { + if (IsWindows()) { + return end_of_input(); + } else { + return el_ring_bell(); + } +} + +static el_status_t transpose_(void) { + char c; + if (rl_point) { + if (rl_point == rl_end) left(CSmove); + c = rl_line_buffer[rl_point - 1]; + left(CSstay); + rl_line_buffer[rl_point - 1] = rl_line_buffer[rl_point]; + tty_show(rl_line_buffer[rl_point - 1]); + rl_line_buffer[rl_point++] = c; + tty_show(c); + } + return CSstay; +} + +static el_status_t quote(void) { + int c; + return (c = tty_get()) == EOF ? CSeof : insert_char((int)c); +} + +static el_status_t mk_set(void) { + rl_mark = rl_point; + return CSstay; +} + +static el_status_t exchange(void) { + int c; + if ((c = tty_get()) != CTL('X')) return c == EOF ? CSeof : el_ring_bell(); + if ((c = rl_mark) <= rl_end) { + rl_mark = rl_point; + rl_point = c; + return CSmove; + } + return CSstay; +} + +static el_status_t yank(void) { + if (Yanked && *Yanked) return insert_string(Yanked); + return CSstay; +} + +static el_status_t copy_region(void) { + if (rl_mark > rl_end) return el_ring_bell(); + if (rl_point > rl_mark) + save_yank(rl_mark, rl_point - rl_mark); + else + save_yank(rl_point, rl_mark - rl_point); + return CSstay; +} + +static el_status_t move_to_char(void) { + int i, c; + char *p; + if ((c = tty_get()) == EOF) return CSeof; + for (i = rl_point + 1, p = &rl_line_buffer[i]; i < rl_end; i++, p++) { + if (*p == c) { + rl_point = i; + return CSmove; + } + } + return CSstay; +} + +static el_status_t fd_kill_word(void) { + int i; + do_forward(CSstay); + if (old_point != rl_point) { + i = rl_point - old_point - 1; + rl_point = old_point; + return delete_string(i); + } + return CSstay; +} + +static el_status_t bk_kill_word(void) { + bk_word(); + if (old_point != rl_point) return delete_string(old_point - rl_point); + return CSstay; +} + +static int argify(char *line, char ***avp) { + char *c; + char **p; + char **arg; + int ac; + int i; + i = MEM_INC; + *avp = p = malloc(sizeof(char *) * i); + if (!p) return 0; + for (c = line; isspace(*c); c++) continue; + if (*c == '\n' || *c == '\0') return 0; + for (ac = 0, p[ac++] = c; *c && *c != '\n';) { + if (!isspace(*c)) { + c++; + continue; + } + *c++ = '\0'; + if (*c && *c != '\n') { + if (ac + 1 == i) { + arg = malloc(sizeof(char *) * (i + MEM_INC)); + if (!arg) { + p[ac] = NULL; + return ac; + } + memcpy(arg, p, i * sizeof(char *)); + i += MEM_INC; + free(p); + *avp = p = arg; + } + p[ac++] = c; + } + } + *c = '\0'; + p[ac] = NULL; + return ac; +} + +static el_status_t last_argument(void) { + char **av = NULL; + char *p; + el_status_t s; + int ac; + if (g_hist.Size == 1 || (p = (char *)g_hist.Lines[g_hist.Size - 2]) == NULL) + return el_ring_bell(); + p = strdup(p); + if (!p) return CSstay; + ac = argify(p, &av); + if (Repeat != NO_ARG) + s = Repeat < ac ? insert_string(av[Repeat]) : el_ring_bell(); + else + s = ac ? insert_string(av[ac - 1]) : CSstay; + if (av) free(av); + free(p); + return s; +} + +static struct EditlineKeymap MetaMap[64] = { + {CTL('H'), bk_kill_word}, {DEL, bk_kill_word}, {' ', mk_set}, + {'.', last_argument}, {'<', h_first}, {'>', h_last}, + {'?', c_possible}, {'b', bk_word}, {'c', case_cap_word}, + {'d', fd_kill_word}, {'f', fd_word}, {'l', case_down_word}, + {'m', toggle_meta_mode}, {'u', case_up_word}, {'y', yank}, + {'w', copy_region}, {0, NULL}, +}; + +static size_t find_key_in_map(int key, struct EditlineKeymap map[], + size_t mapsz) { + size_t i; + for (i = 0; map[i].Function && i < mapsz; i++) { + if (map[i].Key == key) return i; + } + if (i < mapsz) return i; + return mapsz; +} + +static el_status_t el_bind_key_in_map(int key, el_keymap_func_t function, + struct EditlineKeymap map[], + size_t mapsz) { + size_t creat, pos = find_key_in_map(key, map, mapsz); + /* Must check that pos is not the next to last array position, + * otherwise we will write out-of-bounds to terminate the list. */ + if (pos + 1 >= mapsz) { + errno = ENOMEM; + return CSeof; + } + /* Add at end, create new? */ + creat = map[pos].Function == NULL; + /* A new key so have to add it to end */ + map[pos].Key = key; + map[pos].Function = function; + /* Terminate list */ + if (creat) { + map[pos + 1].Key = 0; + map[pos + 1].Function = NULL; + } + return CSdone; +} + +static struct EditlineKeymap Map[64] = { + {CTL('@'), mk_set}, + {CTL('A'), beg_line}, + {CTL('B'), bk_char}, + {CTL('D'), del_char}, + {CTL('E'), end_line}, + {CTL('F'), fd_char}, + {CTL('G'), el_ring_bell}, + {CTL('H'), bk_del_char}, + {CTL('I'), c_complete}, + {CTL('J'), accept_line}, + {CTL('K'), kill_line}, + {CTL('L'), refresh}, + {CTL('M'), accept_line}, + {CTL('N'), h_next}, + {CTL('O'), el_ring_bell}, + {CTL('P'), h_prev}, + {CTL('Q'), el_ring_bell}, + {CTL('R'), h_search}, + {CTL('S'), el_ring_bell}, + {CTL('T'), transpose_}, + {CTL('U'), el_ring_bell}, + {CTL('V'), quote}, + {CTL('W'), bk_kill_word}, + {CTL('X'), exchange}, + {CTL('Y'), yank}, + {CTL('Z'), ctrl_z}, + {CTL('['), meta}, + {CTL(']'), move_to_char}, + {CTL('^'), el_ring_bell}, + {CTL('_'), el_ring_bell}, + {0, NULL}, +}; + +el_status_t el_bind_key(int key, el_keymap_func_t function) { + return el_bind_key_in_map(key, function, Map, ARRAYLEN(Map)); +} + +el_status_t el_bind_key_in_metamap(int key, el_keymap_func_t function) { + return el_bind_key_in_map(key, function, MetaMap, ARRAYLEN(MetaMap)); +} + +rl_getc_func_t *rl_set_getc_func(rl_getc_func_t *func) { + rl_getc_func_t *old = rl_getc_function; + rl_getc_function = func; + return old; +} diff --git a/third_party/editline/editline.h b/third_party/editline/editline.h new file mode 100644 index 00000000..a094490c --- /dev/null +++ b/third_party/editline/editline.h @@ -0,0 +1,91 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_EDITLINE_EDITLINE_H_ +#define COSMOPOLITAN_THIRD_PARTY_EDITLINE_EDITLINE_H_ +#include "libc/stdio/stdio.h" + +#define CTL(x) ((x)&0x1F) +#define ISCTL(x) ((x) && (x) < ' ') +#define UNCTL(x) ((x) + 64) +#define META(x) ((x) | 0x80) +#define ISMETA(x) ((x)&0x80) +#define UNMETA(x) ((x)&0x7F) + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +typedef enum { + CSdone = 0, /* OK */ + CSeof, /* Error, or EOF */ + CSmove, + CSdispatch, + CSstay, + CSsignal +} el_status_t; + +typedef int rl_list_possib_func_t(char *, char ***); +typedef el_status_t el_keymap_func_t(void); +typedef int rl_hook_func_t(void); +typedef int rl_getc_func_t(void); +typedef void rl_voidfunc_t(void); +typedef void rl_vintfunc_t(int); +typedef void rl_vcpfunc_t(char *); +compatfn typedef char *rl_complete_func_t(char *, int *); +compatfn typedef char *rl_compentry_func_t(const char *, int); +compatfn typedef char **rl_completion_func_t(const char *, int, int); + +extern int rl_point; +extern int rl_mark; +extern int rl_end; +extern int rl_inhibit_complete; +extern char *rl_line_buffer; +extern const char *rl_readline_name; +extern FILE *rl_instream; /* The stdio stream from which input is read. Defaults + to stdin if NULL - Not supported yet! */ +extern FILE *rl_outstream; /* The stdio stream to which output is flushed. + Defaults to stdout if NULL - Not supported yet! */ +extern int el_no_echo; /* E.g under emacs, don't echo except prompt */ +extern int el_no_hist; /* Disable auto-save of and access to history -- e.g. for + password prompts or wizards */ +extern int el_hist_size; /* size of history scrollback buffer, default: 15 */ +extern int rl_meta_chars; /* Display 8-bit chars "as-is" or as `M-x'? Toggle + with M-m. (Default:0 - "as-is") */ +extern rl_completion_func_t *rl_attempted_completion_function; + +char **rl_completion_matches(const char *, rl_compentry_func_t *); +char *el_find_word(void); +char *readline(const char *); +char *rl_complete(char *, int *); +char *rl_filename_completion_function(const char *, int); +const char *el_next_hist(void); +const char *el_prev_hist(void); +el_status_t el_bind_key(int, el_keymap_func_t); +el_status_t el_bind_key_in_metamap(int, el_keymap_func_t); +el_status_t el_del_char(void); +el_status_t el_ring_bell(void); +int read_history(const char *); +int rl_getc(void); +int rl_insert_text(const char *); +int rl_list_possib(char *, char ***); +int rl_refresh_line(int, int); +int write_history(const char *); +rl_complete_func_t *rl_set_complete_func(rl_complete_func_t *); +rl_getc_func_t *rl_set_getc_func(rl_getc_func_t *); +rl_list_possib_func_t *rl_set_list_possib_func(rl_list_possib_func_t *); +void add_history(const char *); +void el_print_columns(int, char **); +void rl_callback_handler_install(const char *, rl_vcpfunc_t *); +void rl_callback_handler_remove(void); +void rl_callback_read_char(void); +void rl_clear_message(void); +void rl_deprep_terminal(void); +void rl_forced_update_display(void); +void rl_initialize(void); +void rl_prep_terminal(int); +void rl_reset_terminal(const char *); +void rl_restore_prompt(void); +void rl_save_prompt(void); +void rl_set_prompt(const char *); +void rl_uninitialize(void); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_EDITLINE_EDITLINE_H_ */ diff --git a/third_party/editline/editline.mk b/third_party/editline/editline.mk new file mode 100644 index 00000000..e53263b1 --- /dev/null +++ b/third_party/editline/editline.mk @@ -0,0 +1,57 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += THIRD_PARTY_EDITLINE + +THIRD_PARTY_EDITLINE_ARTIFACTS += THIRD_PARTY_EDITLINE_A +THIRD_PARTY_EDITLINE = $(THIRD_PARTY_EDITLINE_A_DEPS) $(THIRD_PARTY_EDITLINE_A) +THIRD_PARTY_EDITLINE_A = o/$(MODE)/third_party/editline/editline.a +THIRD_PARTY_EDITLINE_A_FILES := $(wildcard third_party/editline/*) +THIRD_PARTY_EDITLINE_A_HDRS = $(filter %.h,$(THIRD_PARTY_EDITLINE_A_FILES)) +THIRD_PARTY_EDITLINE_A_SRCS = $(filter %.c,$(THIRD_PARTY_EDITLINE_A_FILES)) + +THIRD_PARTY_EDITLINE_A_OBJS = \ + $(THIRD_PARTY_EDITLINE_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(THIRD_PARTY_EDITLINE_A_SRCS:%.c=o/$(MODE)/%.o) + +THIRD_PARTY_EDITLINE_A_CHECKS = \ + $(THIRD_PARTY_EDITLINE_A).pkg + +THIRD_PARTY_EDITLINE_A_DIRECTDEPS = \ + LIBC_ALG \ + LIBC_CALLS \ + LIBC_CALLS_HEFTY \ + LIBC_FMT \ + LIBC_LOG \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_STDIO \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_SYSV + +THIRD_PARTY_EDITLINE_A_DEPS := \ + $(call uniq,$(foreach x,$(THIRD_PARTY_EDITLINE_A_DIRECTDEPS),$($(x)))) + +$(THIRD_PARTY_EDITLINE_A): \ + third_party/editline/ \ + $(THIRD_PARTY_EDITLINE_A).pkg \ + $(THIRD_PARTY_EDITLINE_A_OBJS) + +$(THIRD_PARTY_EDITLINE_A).pkg: \ + $(THIRD_PARTY_EDITLINE_A_OBJS) \ + $(foreach x,$(THIRD_PARTY_EDITLINE_A_DIRECTDEPS),$($(x)_A).pkg) + +THIRD_PARTY_EDITLINE_LIBS = $(foreach x,$(THIRD_PARTY_EDITLINE_ARTIFACTS),$($(x))) +THIRD_PARTY_EDITLINE_SRCS = $(foreach x,$(THIRD_PARTY_EDITLINE_ARTIFACTS),$($(x)_SRCS)) +THIRD_PARTY_EDITLINE_HDRS = $(foreach x,$(THIRD_PARTY_EDITLINE_ARTIFACTS),$($(x)_HDRS)) +THIRD_PARTY_EDITLINE_BINS = $(foreach x,$(THIRD_PARTY_EDITLINE_ARTIFACTS),$($(x)_BINS)) +THIRD_PARTY_EDITLINE_CHECKS = $(foreach x,$(THIRD_PARTY_EDITLINE_ARTIFACTS),$($(x)_CHECKS)) +THIRD_PARTY_EDITLINE_OBJS = $(foreach x,$(THIRD_PARTY_EDITLINE_ARTIFACTS),$($(x)_OBJS)) +THIRD_PARTY_EDITLINE_TESTS = $(foreach x,$(THIRD_PARTY_EDITLINE_ARTIFACTS),$($(x)_TESTS)) +$(THIRD_PARTY_EDITLINE_OBJS): $(BUILD_FILES) third_party/editline/editline.mk + +.PHONY: o/$(MODE)/third_party/editline +o/$(MODE)/third_party/editline: \ + $(THIRD_PARTY_EDITLINE) \ + $(THIRD_PARTY_EDITLINE_CHECKS) diff --git a/third_party/editline/internal.h b/third_party/editline/internal.h new file mode 100644 index 00000000..6eccdd30 --- /dev/null +++ b/third_party/editline/internal.h @@ -0,0 +1,21 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_EDITLINE_INTERNAL_H_ +#define COSMOPOLITAN_THIRD_PARTY_EDITLINE_INTERNAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define MEM_INC 64 +#define SCREEN_INC 256 + +extern int rl_eof; +extern int rl_erase; +extern int rl_intr; +extern int rl_kill; +extern int rl_quit; +extern int rl_susp; + +void rl_ttyset(int); +void rl_add_slash(char *, char *); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_EDITLINE_INTERNAL_H_ */ diff --git a/third_party/editline/sysunix.c b/third_party/editline/sysunix.c new file mode 100644 index 00000000..ec52494c --- /dev/null +++ b/third_party/editline/sysunix.c @@ -0,0 +1,112 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/struct/stat.h" +#include "libc/calls/termios.h" +#include "libc/errno.h" +#include "libc/log/log.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/termios.h" +#include "third_party/editline/editline.h" +#include "third_party/editline/internal.h" + +asm(".ident\t\"\\n\\n\ +Cosmopolitan Linenoise (BSD-like license)\\n\ +Copyright 2019 Justine Alexandra Roberts Tunney\\n\ +Copyright 1992,1993 Simmule Turner and Rich Salz\\n\ +All rights reserved.\\n\ +\\n\ +This software is not subject to any license of the American Telephone\\n\ +and Telegraph Company or of the Regents of the University of California.\\n\ +\\n\ +Permission is granted to anyone to use this software for any purpose on\\n\ +any computer system, and to alter it and redistribute it freely, subject\\n\ +to the following restrictions:\\n\ +1. The authors are not responsible for the consequences of use of this\\n\ + software, no matter how awful, even if they arise from flaws in it.\\n\ +2. The origin of this software must not be misrepresented, either by\\n\ + explicit claim or by omission. Since few users ever read sources,\\n\ + credits must appear in the documentation.\\n\ +3. Altered versions must be plainly marked as such, and must not be\\n\ + misrepresented as being the original software. Since few users\\n\ + ever read sources, credits must appear in the documentation.\\n\ +4. This notice may not be removed or altered.\""); +asm(".include \"libc/disclaimer.inc\""); + +/* Wrapper for tcgetattr */ +static int getattr(int fd, struct termios *arg) { + int result, retries = 3; + while (-1 == (result = tcgetattr(fd, arg)) && retries > 0) { + retries--; + if (EINTR == errno) continue; + break; + } + return result; +} + +/* Wrapper for tcgetattr */ +static int setattr(int fd, int opt, const struct termios *arg) { + int result, retries = 3; + while (-1 == (result = tcsetattr(fd, opt, arg)) && retries > 0) { + retries--; + if (EINTR == errno) continue; + break; + } + return result; +} + +void rl_ttyset(int Reset) { + static struct termios old; + struct termios new; + if (!Reset) { + if (-1 == getattr(0, &old)) { + perror("Failed tcgetattr()"); + } + rl_erase = old.c_cc[VERASE]; + rl_kill = old.c_cc[VKILL]; + rl_eof = old.c_cc[VEOF]; + rl_intr = old.c_cc[VINTR]; + rl_quit = old.c_cc[VQUIT]; +#ifdef CONFIG_SIGSTOP + rl_susp = old.c_cc[VSUSP]; +#endif + new = old; + new.c_lflag &= ~(ECHO | ICANON | ISIG); + new.c_iflag &= ~INPCK; + if (rl_meta_chars) + new.c_iflag |= ISTRIP; + else + new.c_iflag &= ~ISTRIP; + new.c_cc[VMIN] = 1; + new.c_cc[VTIME] = 0; + if (-1 == setattr(0, TCSADRAIN, &new)) { + perror("Failed tcsetattr(TCSADRAIN)"); + } + } else { + if (-1 == setattr(0, TCSADRAIN, &old)) { + perror("Failed tcsetattr(TCSADRAIN)"); + } + } +} + +void rl_add_slash(char *path, char *p) { + struct stat Sb; + if (stat(path, &Sb) >= 0) strcat(p, S_ISDIR(Sb.st_mode) ? "/" : " "); +} diff --git a/third_party/f2c/README.cosmo b/third_party/f2c/README.cosmo new file mode 100644 index 00000000..818602d0 --- /dev/null +++ b/third_party/f2c/README.cosmo @@ -0,0 +1,2 @@ +https://www.netlib.org/f2c/ +2020-02-14 diff --git a/third_party/f2c/close.c b/third_party/f2c/close.c new file mode 100644 index 00000000..c9e1ccdb --- /dev/null +++ b/third_party/f2c/close.c @@ -0,0 +1,58 @@ +#include "libc/calls/calls.h" +#include "libc/mem/mem.h" +#include "third_party/f2c/f2c.h" +#include "third_party/f2c/fio.h" + +integer f_clos(cllist *a) { + unit *b; + if (a->cunit >= MXUNIT) return (0); + b = &f__units[a->cunit]; + if (b->ufd == NULL) goto done; + if (b->uscrtch == 1) goto Delete; + if (!a->csta) goto Keep; + switch (*a->csta) { + default: + Keep: + case 'k': + case 'K': + if (b->uwrt == 1) t_runc((alist *)a); + if (b->ufnm) { + fclose(b->ufd); + free(b->ufnm); + } + break; + case 'd': + case 'D': + Delete: + fclose(b->ufd); + if (b->ufnm) { + unlink(b->ufnm); /*SYSDEP*/ + free(b->ufnm); + } + } + b->ufd = NULL; +done: + b->uend = 0; + b->ufnm = NULL; + return (0); +} + +void f_exit(void) { + int i; + static cllist xx; + if (!xx.cerr) { + xx.cerr = 1; + xx.csta = NULL; + for (i = 0; i < MXUNIT; i++) { + xx.cunit = i; + (void)f_clos(&xx); + } + } +} + +int flush_(void) { + int i; + for (i = 0; i < MXUNIT; i++) + if (f__units[i].ufd != NULL && f__units[i].uwrt) fflush(f__units[i].ufd); + return 0; +} diff --git a/third_party/f2c/endfile.c b/third_party/f2c/endfile.c new file mode 100644 index 00000000..f47b3f0a --- /dev/null +++ b/third_party/f2c/endfile.c @@ -0,0 +1,41 @@ +#include "libc/calls/calls.h" +#include "libc/fmt/fmt.h" +#include "libc/stdio/stdio.h" +#include "third_party/f2c/fio.h" + +extern char *f__r_mode[], *f__w_mode[]; + +integer f_end(alist *a) { + unit *b; + FILE *tf; + if (a->aunit >= MXUNIT || a->aunit < 0) err(a->aerr, 101, "endfile"); + b = &f__units[a->aunit]; + if (b->ufd == NULL) { + char nbuf[10]; + sprintf(nbuf, "fort.%ld", (long)a->aunit); + if (tf = fopen(nbuf, f__w_mode[0])) fclose(tf); + return (0); + } + b->uend = 1; + return (b->useek ? t_runc(a) : 0); +} + +int t_runc(alist *a) { + OFF_T loc, len; + unit *b; + int rc; + FILE *bf; + b = &f__units[a->aunit]; + if (b->url) return (0); /*don't truncate direct files*/ + loc = ftell(bf = b->ufd); + fseek(bf, (OFF_T)0, SEEK_END); + len = ftell(bf); + if (loc >= len || b->useek == 0) return (0); + if (b->urw & 2) fflush(b->ufd); /* necessary on some Linux systems */ + rc = ftruncate(fileno(b->ufd), loc); + /* The following FSEEK is unnecessary on some systems, */ + /* but should be harmless. */ + fseek(b->ufd, (OFF_T)0, SEEK_END); + if (rc) err(a->aerr, 111, "endfile"); + return 0; +} diff --git a/third_party/f2c/err.c b/third_party/f2c/err.c new file mode 100644 index 00000000..970998e2 --- /dev/null +++ b/third_party/f2c/err.c @@ -0,0 +1,221 @@ +#include "libc/calls/calls.h" +#include "libc/calls/struct/stat.h" +#include "libc/log/log.h" +#include "libc/stdio/stdio.h" +#include "third_party/f2c/f2c.h" +#include "third_party/f2c/fio.h" +#include "third_party/f2c/fmt.h" + +extern char *f__r_mode[], *f__w_mode[]; + +/*global definitions*/ +unit f__units[MXUNIT]; /*unit table*/ +flag f__init; /*0 on entry, 1 after initializations*/ +cilist *f__elist; /*active external io list*/ +icilist *f__svic; /*active internal io list*/ +flag f__reading; /*1 if reading, 0 if writing*/ +flag f__cplus, f__cblank; +const char *f__fmtbuf; +flag f__external; /*1 if external io, 0 if internal */ +flag f__sequential; /*1 if sequential io, 0 if direct*/ +flag f__formatted; /*1 if formatted io, 0 if unformatted*/ +FILE *f__cf; /*current file*/ +unit *f__curunit; /*current unit*/ +int f__recpos; /*place in current record*/ +OFF_T f__cursor, f__hiwater; +int f__scale; +char *f__icptr; +int (*f__getn)(void); /* for formatted input */ +void (*f__putn)(int); /* for formatted output */ +int (*f__doed)(struct syl *, char *, ftnlen), (*f__doned)(struct syl *); +int (*f__dorevert)(void), (*f__donewrec)(void), (*f__doend)(void); + +/*error messages*/ +const char *F_err[] = { + "error in format", /* 100 */ + "illegal unit number", /* 101 */ + "formatted io not allowed", /* 102 */ + "unformatted io not allowed", /* 103 */ + "direct io not allowed", /* 104 */ + "sequential io not allowed", /* 105 */ + "can't backspace file", /* 106 */ + "null file name", /* 107 */ + "can't stat file", /* 108 */ + "unit not connected", /* 109 */ + "off end of record", /* 110 */ + "truncation failed in endfile", /* 111 */ + "incomprehensible list input", /* 112 */ + "out of free space", /* 113 */ + "unit not connected", /* 114 */ + "read unexpected character", /* 115 */ + "bad logical input field", /* 116 */ + "bad variable type", /* 117 */ + "bad namelist name", /* 118 */ + "variable not in namelist", /* 119 */ + "no end record", /* 120 */ + "variable count incorrect", /* 121 */ + "subscript for scalar variable", /* 122 */ + "invalid array section", /* 123 */ + "substring out of bounds", /* 124 */ + "subscript out of bounds", /* 125 */ + "can't read file", /* 126 */ + "can't write file", /* 127 */ + "'new' file exists", /* 128 */ + "can't append to file", /* 129 */ + "non-positive record number", /* 130 */ + "nmLbuf overflow" /* 131 */ +}; + +#define MAXERR (sizeof(F_err) / sizeof(char *) + 100) + +int f__canseek(FILE *f) /*SYSDEP*/ +{ +#ifdef NON_UNIX_STDIO + return !isatty(fileno(f)); +#else + struct stat x; + + if (fstat(fileno(f), &x) < 0) return (0); +#ifdef S_IFMT + switch (x.st_mode & S_IFMT) { + case S_IFDIR: + case S_IFREG: + if (x.st_nlink > 0) /* !pipe */ + return (1); + else + return (0); + case S_IFCHR: + if (isatty(fileno(f))) return (0); + return (1); +#ifdef S_IFBLK + case S_IFBLK: + return (1); +#endif + } +#else +#ifdef S_ISDIR + /* POSIX version */ + if (S_ISREG(x.st_mode) || S_ISDIR(x.st_mode)) { + if (x.st_nlink > 0) /* !pipe */ + return (1); + else + return (0); + } + if (S_ISCHR(x.st_mode)) { + if (isatty(fileno(f))) return (0); + return (1); + } + if (S_ISBLK(x.st_mode)) return (1); +#else + Help !How does fstat work on this system + ? +#endif +#endif + return (0); /* who knows what it is? */ +#endif +} + +void f__fatal(int n, const char *s) { + if (n < 100 && n >= 0) + fprintf(stderr, "error: %s: %m\n", s); /*SYSDEP*/ + else if (n >= (int)MAXERR || n < -1) { + fprintf(stderr, "%s: illegal error number %d\n", s, n); + } else if (n == -1) + fprintf(stderr, "%s: end of file\n", s); + else + fprintf(stderr, "%s: %s\n", s, F_err[n - 100]); + if (f__curunit) { + fprintf(stderr, "apparent state: unit %d ", (int)(f__curunit - f__units)); + fprintf(stderr, f__curunit->ufnm ? "named %s\n" : "(unnamed)\n", + f__curunit->ufnm); + } else + fprintf(stderr, "apparent state: internal I/O\n"); + if (f__fmtbuf) fprintf(stderr, "last format: %s\n", f__fmtbuf); + fprintf(stderr, "lately %s %s %s %s", f__reading ? "reading" : "writing", + f__sequential ? "sequential" : "direct", + f__formatted ? "formatted" : "unformatted", + f__external ? "external" : "internal"); + sig_die(" IO", 1); +} + +/*initialization routine*/ +VOID f_init(Void) { + unit *p; + + f__init = 1; + p = &f__units[0]; + p->ufd = stderr; + p->useek = f__canseek(stderr); + p->ufmt = 1; + p->uwrt = 1; + p = &f__units[5]; + p->ufd = stdin; + p->useek = f__canseek(stdin); + p->ufmt = 1; + p->uwrt = 0; + p = &f__units[6]; + p->ufd = stdout; + p->useek = f__canseek(stdout); + p->ufmt = 1; + p->uwrt = 1; +} + +int f__nowreading(unit *x) { + OFF_T loc; + int ufmt, urw; + + if (x->urw & 1) goto done; + if (!x->ufnm) goto cantread; + ufmt = x->url ? 0 : x->ufmt; + loc = ftell(x->ufd); + urw = 3; + if (!freopen(x->ufnm, f__w_mode[ufmt | 2], x->ufd)) { + urw = 1; + if (!freopen(x->ufnm, f__r_mode[ufmt], x->ufd)) { + cantread: + errno = 126; + return 1; + } + } + fseek(x->ufd, loc, SEEK_SET); + x->urw = urw; +done: + x->uwrt = 0; + return 0; +} + +int f__nowwriting(unit *x) { + OFF_T loc; + int ufmt; + + if (x->urw & 2) { + if (x->urw & 1) fseek(x->ufd, (OFF_T)0, SEEK_CUR); + goto done; + } + if (!x->ufnm) goto cantwrite; + ufmt = x->url ? 0 : x->ufmt; + if (x->uwrt == 3) { /* just did write, rewind */ + if (!(f__cf = x->ufd = freopen(x->ufnm, f__w_mode[ufmt], x->ufd))) + goto cantwrite; + x->urw = 2; + } else { + loc = ftell(x->ufd); + if (!(f__cf = x->ufd = freopen(x->ufnm, f__w_mode[ufmt | 2], x->ufd))) { + x->ufd = NULL; + cantwrite: + errno = 127; + return (1); + } + x->urw = 3; + fseek(x->ufd, loc, SEEK_SET); + } +done: + x->uwrt = 1; + return 0; +} + +int err__fl(int f, int m, const char *s) { + if (!f) f__fatal(m, s); + if (f__doend) (*f__doend)(); + return errno = m; +} diff --git a/third_party/f2c/exit_.c b/third_party/f2c/exit_.c new file mode 100644 index 00000000..2e6cd9c4 --- /dev/null +++ b/third_party/f2c/exit_.c @@ -0,0 +1,18 @@ +#include "libc/runtime/runtime.h" +#include "third_party/f2c/f2c.h" +#include "third_party/f2c/internal.h" + +/** + * This gives the effect of + * + * subroutine exit(rc) + * integer*4 rc + * stop + * end + * + * with the added side effect of supplying rc as the program's exit code. + */ +void exit_(integer *rc) { + f_exit(); + exit(*rc); +} diff --git a/third_party/f2c/f2c.h b/third_party/f2c/f2c.h new file mode 100644 index 00000000..62aa4baf --- /dev/null +++ b/third_party/f2c/f2c.h @@ -0,0 +1,198 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_F2C_F2C_H_ +#define COSMOPOLITAN_THIRD_PARTY_F2C_F2C_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ +/* f2c.h -- Standard Fortran to C header file */ + +/** barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed." + + - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) */ + +typedef long int integer; +typedef unsigned long int uinteger; +typedef char *address; +typedef short int shortint; +typedef float real; +typedef double doublereal; +typedef struct { + real r, i; +} complex; +typedef struct { + doublereal r, i; +} doublecomplex; +typedef long int logical; +typedef short int shortlogical; +typedef char logical1; +typedef char integer1; +#ifdef INTEGER_STAR_8 /* Adjust for integer*8. */ +typedef long long longint; /* system-dependent */ +typedef unsigned long long ulongint; /* system-dependent */ +#define qbit_clear(a, b) ((a) & ~((ulongint)1 << (b))) +#define qbit_set(a, b) ((a) | ((ulongint)1 << (b))) +#endif + +#define TRUE_ (1) +#define FALSE_ (0) + +#ifndef Void +#define Void void +#endif + +/* Extern is for use with -E */ +#ifndef Extern +#define Extern extern +#endif + +/* I/O stuff */ + +#ifdef f2c_i2 +/* for -i2 */ +typedef short flag; +typedef short ftnlen; +typedef short ftnint; +#else +typedef long int flag; +typedef long int ftnlen; +typedef long int ftnint; +#endif + +/*external read, write*/ +typedef struct { + flag cierr; + ftnint ciunit; + flag ciend; + char *cifmt; + ftnint cirec; +} cilist; + +/*internal read, write*/ +typedef struct { + flag icierr; + char *iciunit; + flag iciend; + char *icifmt; + ftnint icirlen; + ftnint icirnum; +} icilist; + +/*open*/ +typedef struct { + flag oerr; + ftnint ounit; + char *ofnm; + ftnlen ofnmlen; + char *osta; + char *oacc; + char *ofm; + ftnint orl; + char *oblnk; +} olist; + +/*close*/ +typedef struct { + flag cerr; + ftnint cunit; + char *csta; +} cllist; + +/*rewind, backspace, endfile*/ +typedef struct { + flag aerr; + ftnint aunit; +} alist; + +/* inquire */ +typedef struct { + flag inerr; + ftnint inunit; + char *infile; + ftnlen infilen; + ftnint *inex; /*parameters in standard's order*/ + ftnint *inopen; + ftnint *innum; + ftnint *innamed; + char *inname; + ftnlen innamlen; + char *inacc; + ftnlen inacclen; + char *inseq; + ftnlen inseqlen; + char *indir; + ftnlen indirlen; + char *infmt; + ftnlen infmtlen; + char *inform; + ftnint informlen; + char *inunf; + ftnlen inunflen; + ftnint *inrecl; + ftnint *innrec; + char *inblank; + ftnlen inblanklen; +} inlist; + +#define VOID void + +union Multitype { /* for multiple entry points */ + integer1 g; + shortint h; + integer i; + /* longint j; */ + real r; + doublereal d; + complex c; + doublecomplex z; +}; + +typedef union Multitype Multitype; + +/*typedef long int Long;*/ /* No longer used; formerly in Namelist */ + +struct Vardesc { /* for Namelist */ + char *name; + char *addr; + ftnlen *dims; + int type; +}; +typedef struct Vardesc Vardesc; + +struct Namelist { + char *name; + Vardesc **vars; + int nvars; +}; +typedef struct Namelist Namelist; + +#define abs(x) ((x) >= 0 ? (x) : -(x)) +#define dabs(x) (doublereal) abs(x) +#define min(a, b) ((a) <= (b) ? (a) : (b)) +#define max(a, b) ((a) >= (b) ? (a) : (b)) +#define dmin(a, b) (doublereal) min(a, b) +#define dmax(a, b) (doublereal) max(a, b) +#define bit_test(a, b) ((a) >> (b)&1) +#define bit_clear(a, b) ((a) & ~((uinteger)1 << (b))) +#define bit_set(a, b) ((a) | ((uinteger)1 << (b))) + +/* procedure parameter types for -A and -C++ */ + +#define F2C_proc_par_types 1 +typedef int /* Unknown procedure type */ (*U_fp)(); +typedef shortint (*J_fp)(); +typedef integer (*I_fp)(); +typedef real (*R_fp)(); +typedef doublereal (*D_fp)(), (*E_fp)(); +typedef /* Complex */ VOID (*C_fp)(); +typedef /* Double Complex */ VOID (*Z_fp)(); +typedef logical (*L_fp)(); +typedef shortlogical (*K_fp)(); +typedef /* Character */ VOID (*H_fp)(); +typedef /* Subroutine */ int (*S_fp)(); +/* E_fp is for real functions when -R is not specified */ +typedef VOID C_f; /* complex function */ +typedef VOID H_f; /* character function */ +typedef VOID Z_f; /* double complex function */ +typedef doublereal E_f; /* real function with -R not specified */ + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_F2C_F2C_H_ */ diff --git a/third_party/f2c/f2c.mk b/third_party/f2c/f2c.mk new file mode 100644 index 00000000..fea23722 --- /dev/null +++ b/third_party/f2c/f2c.mk @@ -0,0 +1,57 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += THIRD_PARTY_F2C + +THIRD_PARTY_F2C_ARTIFACTS += THIRD_PARTY_F2C_A +THIRD_PARTY_F2C = $(THIRD_PARTY_F2C_A_DEPS) $(THIRD_PARTY_F2C_A) +THIRD_PARTY_F2C_A = o/$(MODE)/third_party/f2c/f2c.a +THIRD_PARTY_F2C_A_FILES := $(wildcard third_party/f2c/*) +THIRD_PARTY_F2C_A_HDRS = $(filter %.h,$(THIRD_PARTY_F2C_A_FILES)) +THIRD_PARTY_F2C_A_SRCS_C = $(filter %.c,$(THIRD_PARTY_F2C_A_FILES)) + +THIRD_PARTY_F2C_A_SRCS = \ + $(THIRD_PARTY_F2C_A_SRCS_C) + +THIRD_PARTY_F2C_A_OBJS = \ + $(THIRD_PARTY_F2C_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(THIRD_PARTY_F2C_A_SRCS_C:%.c=o/$(MODE)/%.o) + +THIRD_PARTY_F2C_A_CHECKS = \ + $(THIRD_PARTY_F2C_A).pkg \ + $(THIRD_PARTY_F2C_A_HDRS:%=o/$(MODE)/%.ok) + +THIRD_PARTY_F2C_A_DIRECTDEPS = \ + LIBC_CONV \ + LIBC_CALLS \ + LIBC_CALLS_HEFTY \ + LIBC_RUNTIME \ + LIBC_MEM \ + LIBC_FMT \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_STDIO \ + LIBC_NEXGEN32E \ + LIBC_UNICODE + +THIRD_PARTY_F2C_A_DEPS := \ + $(call uniq,$(foreach x,$(THIRD_PARTY_F2C_A_DIRECTDEPS),$($(x)))) + +$(THIRD_PARTY_F2C_A): \ + third_party/f2c/ \ + $(THIRD_PARTY_F2C_A).pkg \ + $(THIRD_PARTY_F2C_A_OBJS) + +$(THIRD_PARTY_F2C_A).pkg: \ + $(THIRD_PARTY_F2C_A_OBJS) \ + $(foreach x,$(THIRD_PARTY_F2C_A_DIRECTDEPS),$($(x)_A).pkg) + +THIRD_PARTY_F2C_LIBS = $(foreach x,$(THIRD_PARTY_F2C_ARTIFACTS),$($(x))) +THIRD_PARTY_F2C_SRCS = $(foreach x,$(THIRD_PARTY_F2C_ARTIFACTS),$($(x)_SRCS)) +THIRD_PARTY_F2C_HDRS = $(foreach x,$(THIRD_PARTY_F2C_ARTIFACTS),$($(x)_HDRS)) +THIRD_PARTY_F2C_CHECKS = $(foreach x,$(THIRD_PARTY_F2C_ARTIFACTS),$($(x)_CHECKS)) +THIRD_PARTY_F2C_OBJS = $(foreach x,$(THIRD_PARTY_F2C_ARTIFACTS),$($(x)_OBJS)) +$(THIRD_PARTY_F2C_OBJS): $(BUILD_FILES) third_party/f2c/f2c.mk + +.PHONY: o/$(MODE)/third_party/f2c +o/$(MODE)/third_party/f2c: $(THIRD_PARTY_F2C_CHECKS) diff --git a/third_party/f2c/fio.h b/third_party/f2c/fio.h new file mode 100644 index 00000000..e6917139 --- /dev/null +++ b/third_party/f2c/fio.h @@ -0,0 +1,97 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_F2C_LIB_FIO_H_ +#define COSMOPOLITAN_THIRD_PARTY_F2C_LIB_FIO_H_ +#include "libc/errno.h" +#include "libc/stdio/stdio.h" +#include "third_party/f2c/f2c.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#ifndef OFF_T +#define OFF_T long +#endif + +#ifdef UIOLEN_int +typedef int uiolen; +#else +typedef long uiolen; +#endif + +/*units*/ +typedef struct { + FILE *ufd; /*0=unconnected*/ + char *ufnm; + long uinode; + int udev; + int url; /*0=sequential*/ + flag useek; /*true=can backspace, use dir, ...*/ + flag ufmt; + flag urw; /* (1 for can read) | (2 for can write) */ + flag ublnk; + flag uend; + flag uwrt; /*last io was write*/ + flag uscrtch; +} unit; + +void x_putc(int); +long f__inode(char *, int *); +void sig_die(const char *, int); +void f__fatal(int, const char *); +int t_runc(alist *); +int f__nowreading(unit *); +int f__nowwriting(unit *); +int fk_open(int, int, ftnint); +int en_fio(void); +void f_init(void); +int t_putc(int); +int x_wSL(void); +void b_char(const char *, char *, ftnlen); +void g_char(const char *, ftnlen, char *); +int c_sfe(cilist *); +int z_rnew(void); +int err__fl(int, int, const char *); +int xrd_SL(void); +int f__putbuf(int); + +extern cilist *f__elist; /*active external io list*/ +extern flag f__reading, f__external, f__sequential, f__formatted; +extern flag f__init; +extern FILE *f__cf; /*current file*/ +extern unit *f__curunit; /*current unit*/ +extern unit f__units[]; +extern int (*f__doend)(void); +extern int (*f__getn)(void); /* for formatted input */ +extern void (*f__putn)(int); /* for formatted output */ +extern int (*f__donewrec)(void); + +#define err(f, m, s) \ + { \ + if (f) \ + errno = m; \ + else \ + f__fatal(m, s); \ + return (m); \ + } + +#define errfl(f, m, s) return err__fl((int)f, m, s) + +/*Table sizes*/ +#define MXUNIT 100 + +extern int f__recpos; /*position in current record*/ +extern OFF_T f__cursor; /* offset to move to */ +extern OFF_T f__hiwater; /* so TL doesn't confuse us */ + +#define WRITE 1 +#define READ 2 +#define SEQ 3 +#define DIR 4 +#define FMT 5 +#define UNF 6 +#define EXT 7 +#define INT 8 + +#define buf_end(x) (x->_flag & _IONBF ? x->_ptr : x->_base + BUFSIZ) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_F2C_LIB_FIO_H_ */ diff --git a/third_party/f2c/fmt.c b/third_party/f2c/fmt.c new file mode 100644 index 00000000..93e4368f --- /dev/null +++ b/third_party/f2c/fmt.c @@ -0,0 +1,477 @@ +#include "libc/calls/calls.h" +#include "libc/errno.h" +#include "third_party/f2c/f2c.h" +#include "third_party/f2c/fio.h" +#include "third_party/f2c/fmt.h" + +#define SYLMX 300 +#define GLITCH '\2' +#define Const const +#define STKSZ 10 + +#define skip(s) \ + while (*s == ' ') s++ + +/* special quote character for stu */ +static struct syl f__syl[SYLMX]; +int f__parenlvl, f__pc, f__revloc; +int f__cnt[STKSZ], f__ret[STKSZ], f__cp, f__rp; +flag f__workdone, f__nonl; + +static const char *ap_end(const char *s) { + char quote; + quote = *s++; + for (; *s; s++) { + if (*s != quote) continue; + if (*++s != quote) return (s); + } + if (f__elist->cierr) { + errno = 100; + return (NULL); + } + f__fatal(100, "bad string"); + /*NOTREACHED*/ return 0; +} + +static int op_gen(int a, int b, int c, int d) { + struct syl *p = &f__syl[f__pc]; + if (f__pc >= SYLMX) { + fprintf(stderr, "format too complicated:\n"); + sig_die(f__fmtbuf, 1); + } + p->op = a; + p->p1 = b; + p->p2.i[0] = c; + p->p2.i[1] = d; + return (f__pc++); +} + +static const char *f_list(const char *); +static const char *gt_num(const char *s, int *n, int n1) { + int m = 0, f__cnt = 0; + char c; + for (c = *s;; c = *s) { + if (c == ' ') { + s++; + continue; + } + if (c > '9' || c < '0') break; + m = 10 * m + c - '0'; + f__cnt++; + s++; + } + if (f__cnt == 0) { + if (!n1) s = 0; + *n = n1; + } else + *n = m; + return (s); +} + +static const char *f_s(const char *s, int curloc) { + skip(s); + if (*s++ != '(') { + return (NULL); + } + if (f__parenlvl++ == 1) f__revloc = curloc; + if (op_gen(RET1, curloc, 0, 0) < 0 || (s = f_list(s)) == NULL) { + return (NULL); + } + skip(s); + return (s); +} + +static int ne_d(const char *s, const char **p) { + int n, x, sign = 0; + struct syl *sp; + switch (*s) { + default: + return (0); + case ':': + (void)op_gen(COLON, 0, 0, 0); + break; + case '$': + (void)op_gen(NONL, 0, 0, 0); + break; + case 'B': + case 'b': + if (*++s == 'z' || *s == 'Z') + (void)op_gen(BZ, 0, 0, 0); + else + (void)op_gen(BN, 0, 0, 0); + break; + case 'S': + case 's': + if (*(s + 1) == 's' || *(s + 1) == 'S') { + x = SS; + s++; + } else if (*(s + 1) == 'p' || *(s + 1) == 'P') { + x = SP; + s++; + } else + x = S; + (void)op_gen(x, 0, 0, 0); + break; + case '/': + (void)op_gen(SLASH, 0, 0, 0); + break; + case '-': + sign = 1; + case '+': + s++; /*OUTRAGEOUS CODING TRICK*/ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (!(s = gt_num(s, &n, 0))) { + bad: + *p = 0; + return 1; + } + switch (*s) { + default: + return (0); + case 'P': + case 'p': + if (sign) n = -n; + (void)op_gen(P, n, 0, 0); + break; + case 'X': + case 'x': + (void)op_gen(X, n, 0, 0); + break; + case 'H': + case 'h': + sp = &f__syl[op_gen(H, n, 0, 0)]; + sp->p2.s = (char *)s + 1; + s += n; + break; + } + break; + case GLITCH: + case '"': + case '\'': + sp = &f__syl[op_gen(APOS, 0, 0, 0)]; + sp->p2.s = (char *)s; + if ((*p = ap_end(s)) == NULL) return (0); + return (1); + case 'T': + case 't': + if (*(s + 1) == 'l' || *(s + 1) == 'L') { + x = TL; + s++; + } else if (*(s + 1) == 'r' || *(s + 1) == 'R') { + x = TR; + s++; + } else + x = T; + if (!(s = gt_num(s + 1, &n, 0))) goto bad; + s--; + (void)op_gen(x, n, 0, 0); + break; + case 'X': + case 'x': + (void)op_gen(X, 1, 0, 0); + break; + case 'P': + case 'p': + (void)op_gen(P, 1, 0, 0); + break; + } + s++; + *p = s; + return (1); +} + +static int e_d(const char *s, const char **p) { + int i, im, n, w, d, e, found = 0, x = 0; + Const char *sv = s; + s = gt_num(s, &n, 1); + (void)op_gen(STACK, n, 0, 0); + switch (*s++) { + default: + break; + case 'E': + case 'e': + x = 1; + case 'G': + case 'g': + found = 1; + if (!(s = gt_num(s, &w, 0))) { + bad: + *p = 0; + return 1; + } + if (w == 0) break; + if (*s == '.') { + if (!(s = gt_num(s + 1, &d, 0))) goto bad; + } else + d = 0; + if (*s != 'E' && *s != 'e') + (void)op_gen(x == 1 ? E : G, w, d, 0); /* default is Ew.dE2 */ + else { + if (!(s = gt_num(s + 1, &e, 0))) goto bad; + (void)op_gen(x == 1 ? EE : GE, w, d, e); + } + break; + case 'O': + case 'o': + i = O; + im = OM; + goto finish_I; + case 'Z': + case 'z': + i = Z; + im = ZM; + goto finish_I; + case 'L': + case 'l': + found = 1; + if (!(s = gt_num(s, &w, 0))) goto bad; + if (w == 0) break; + (void)op_gen(L, w, 0, 0); + break; + case 'A': + case 'a': + found = 1; + skip(s); + if (*s >= '0' && *s <= '9') { + s = gt_num(s, &w, 1); + if (w == 0) break; + (void)op_gen(AW, w, 0, 0); + break; + } + (void)op_gen(A, 0, 0, 0); + break; + case 'F': + case 'f': + if (!(s = gt_num(s, &w, 0))) goto bad; + found = 1; + if (w == 0) break; + if (*s == '.') { + if (!(s = gt_num(s + 1, &d, 0))) goto bad; + } else + d = 0; + (void)op_gen(F, w, d, 0); + break; + case 'D': + case 'd': + found = 1; + if (!(s = gt_num(s, &w, 0))) goto bad; + if (w == 0) break; + if (*s == '.') { + if (!(s = gt_num(s + 1, &d, 0))) goto bad; + } else + d = 0; + (void)op_gen(D, w, d, 0); + break; + case 'I': + case 'i': + i = I; + im = IM; + finish_I: + if (!(s = gt_num(s, &w, 0))) goto bad; + found = 1; + if (w == 0) break; + if (*s != '.') { + (void)op_gen(i, w, 0, 0); + break; + } + if (!(s = gt_num(s + 1, &d, 0))) goto bad; + (void)op_gen(im, w, d, 0); + break; + } + if (found == 0) { + f__pc--; /*unSTACK*/ + *p = sv; + return (0); + } + *p = s; + return (1); +} + +static const char *i_tem(const char *s) { + const char *t; + int n, curloc; + if (*s == ')') return (s); + if (ne_d(s, &t)) return (t); + if (e_d(s, &t)) return (t); + s = gt_num(s, &n, 1); + if ((curloc = op_gen(STACK, n, 0, 0)) < 0) return (NULL); + return (f_s(s, curloc)); +} + +static const char *f_list(const char *s) { + for (; *s != 0;) { + skip(s); + if ((s = i_tem(s)) == NULL) return (NULL); + skip(s); + if (*s == ',') + s++; + else if (*s == ')') { + if (--f__parenlvl == 0) { + (void)op_gen(REVERT, f__revloc, 0, 0); + return (++s); + } + (void)op_gen(GOTO, 0, 0, 0); + return (++s); + } + } + return (NULL); +} + +int pars_f(const char *s) { + f__parenlvl = f__revloc = f__pc = 0; + if (f_s(s, 0) == NULL) { + return (-1); + } + return (0); +} + +static int type_f(int n) { + switch (n) { + default: + return (n); + case RET1: + return (RET1); + case REVERT: + return (REVERT); + case GOTO: + return (GOTO); + case STACK: + return (STACK); + case X: + case SLASH: + case APOS: + case H: + case T: + case TL: + case TR: + return (NED); + case F: + case I: + case IM: + case A: + case AW: + case O: + case OM: + case L: + case E: + case EE: + case D: + case G: + case GE: + case Z: + case ZM: + return (ED); + } +} +#ifdef KR_headers +integer do_fio(number, ptr, len) ftnint *number; +ftnlen len; +char *ptr; +#else +integer do_fio(ftnint *number, char *ptr, ftnlen len) +#endif +{ + struct syl *p; + int n, i; + for (i = 0; i < *number; i++, ptr += len) { + loop: + switch (type_f((p = &f__syl[f__pc])->op)) { + default: + fprintf(stderr, "unknown code in do_fio: %d\n%s\n", p->op, f__fmtbuf); + err(f__elist->cierr, 100, "do_fio"); + case NED: + if ((*f__doned)(p)) { + f__pc++; + goto loop; + } + f__pc++; + continue; + case ED: + if (f__cnt[f__cp] <= 0) { + f__cp--; + f__pc++; + goto loop; + } + if (ptr == NULL) return ((*f__doend)()); + f__cnt[f__cp]--; + f__workdone = 1; + if ((n = (*f__doed)(p, ptr, len)) > 0) + errfl(f__elist->cierr, errno, "fmt"); + if (n < 0) err(f__elist->ciend, (EOF), "fmt"); + continue; + case STACK: + f__cnt[++f__cp] = p->p1; + f__pc++; + goto loop; + case RET1: + f__ret[++f__rp] = p->p1; + f__pc++; + goto loop; + case GOTO: + if (--f__cnt[f__cp] <= 0) { + f__cp--; + f__rp--; + f__pc++; + goto loop; + } + f__pc = 1 + f__ret[f__rp--]; + goto loop; + case REVERT: + f__rp = f__cp = 0; + f__pc = p->p1; + if (ptr == NULL) return ((*f__doend)()); + if (!f__workdone) return (0); + if ((n = (*f__dorevert)()) != 0) return (n); + goto loop; + case COLON: + if (ptr == NULL) return ((*f__doend)()); + f__pc++; + goto loop; + case NONL: + f__nonl = 1; + f__pc++; + goto loop; + case S: + case SS: + f__cplus = 0; + f__pc++; + goto loop; + case SP: + f__cplus = 1; + f__pc++; + goto loop; + case P: + f__scale = p->p1; + f__pc++; + goto loop; + case BN: + f__cblank = 0; + f__pc++; + goto loop; + case BZ: + f__cblank = 1; + f__pc++; + goto loop; + } + } + return (0); +} + +int en_fio(Void) { + ftnint one = 1; + return (do_fio(&one, (char *)NULL, (ftnint)0)); +} + +VOID fmt_bg(Void) { + f__workdone = f__cp = f__rp = f__pc = f__cursor = 0; + f__cnt[0] = f__ret[0] = 0; +} diff --git a/third_party/f2c/fmt.h b/third_party/f2c/fmt.h new file mode 100644 index 00000000..b54ea09d --- /dev/null +++ b/third_party/f2c/fmt.h @@ -0,0 +1,103 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_F2C_FMT_H_ +#define COSMOPOLITAN_THIRD_PARTY_F2C_FMT_H_ +#include "third_party/f2c/f2c.h" +#include "third_party/f2c/fio.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define RET1 1 +#define REVERT 2 +#define GOTO 3 +#define X 4 +#define SLASH 5 +#define STACK 6 +#define I 7 +#define ED 8 +#define NED 9 +#define IM 10 +#define APOS 11 +#define H 12 +#define TL 13 +#define TR 14 +#define T 15 +#define COLON 16 +#define S 17 +#define SP 18 +#define SS 19 +#define P 20 +#define BN 21 +#define BZ 22 +#define F 23 +#define E 24 +#define EE 25 +#define D 26 +#define G 27 +#define GE 28 +#define L 29 +#define A 30 +#define AW 31 +#define O 32 +#define NONL 33 +#define OM 34 +#define Z 35 +#define ZM 36 + +struct syl { + int op; + int p1; + union { + int i[2]; + char *s; + } p2; +}; + +typedef union { + real pf; + doublereal pd; +} ufloat; + +typedef union { + short is; + signed char ic; + integer il; +#ifdef Allow_TYQUAD + longint ili; +#endif +} Uint; + +void fmt_bg(void); +int pars_f(const char *); +int rd_ed(struct syl *, char *, ftnlen); +int rd_ned(struct syl *); +int signbit_f2c(double *); +int w_ed(struct syl *, char *, ftnlen); +int w_ned(struct syl *); +int wrt_E(ufloat *, int, int, int, ftnlen); +int wrt_F(ufloat *, int, int, ftnlen); +int wrt_L(Uint *, int, ftnlen); + +extern const char *f__fmtbuf; +extern int (*f__doed)(struct syl *, char *, ftnlen), (*f__doned)(struct syl *); +extern int (*f__dorevert)(void); +extern int f__pc, f__parenlvl, f__revloc; +extern flag f__cblank, f__cplus, f__workdone, f__nonl; +extern int f__scale; + +#define GET(x) \ + if ((x = (*f__getn)()) < 0) return (x) +#define VAL(x) (x != '\n' ? x : ' ') +#define PUT(x) (*f__putn)(x) + +#undef TYQUAD +#ifndef Allow_TYQUAD +#undef longint +#define longint long +#else +#define TYQUAD 14 +#endif + +char *f__icvt(longint, int *, int *, int); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_F2C_FMT_H_ */ diff --git a/third_party/f2c/fmtlib.c b/third_party/f2c/fmtlib.c new file mode 100644 index 00000000..1ec62cdb --- /dev/null +++ b/third_party/f2c/fmtlib.c @@ -0,0 +1,33 @@ +#define MAXINTLENGTH 23 + +#ifndef Allow_TYQUAD +#undef longint +#define longint long +#undef ulongint +#define ulongint unsigned long +#endif + +char *f__icvt(longint value, int *ndigit, int *sign, int base) { + static char buf[MAXINTLENGTH + 1]; + register int i; + ulongint uvalue; + if (value > 0) { + uvalue = value; + *sign = 0; + } else if (value < 0) { + uvalue = -value; + *sign = 1; + } else { + *sign = 0; + *ndigit = 1; + buf[MAXINTLENGTH - 1] = '0'; + return &buf[MAXINTLENGTH - 1]; + } + i = MAXINTLENGTH; + do { + buf[--i] = (uvalue % base) + '0'; + uvalue /= base; + } while (uvalue > 0); + *ndigit = MAXINTLENGTH - i; + return &buf[i]; +} diff --git a/third_party/f2c/fp.h b/third_party/f2c/fp.h new file mode 100644 index 00000000..c646b3f2 --- /dev/null +++ b/third_party/f2c/fp.h @@ -0,0 +1,25 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_F2C_FP_H_ +#define COSMOPOLITAN_THIRD_PARTY_F2C_FP_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#include "libc/math.h" + +#define FMAX 40 +#define EXPMAXDIGS 8 +#define EXPMAX 99999999 +/* FMAX = max number of nonzero digits passed to atof() */ +/* EXPMAX = 10^EXPMAXDIGS - 1 = largest allowed exponent absolute value */ + +/* MAXFRACDIGS and MAXINTDIGS are for wrt_F -- bounds (not necessarily + tight) on the maximum number of digits to the right and left of + * the decimal point. + */ + +/* values that suffice for IEEE double */ +#define MAXFRACDIGS 344 +#define MAXINTDIGS DBL_MAX_10_EXP + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_F2C_FP_H_ */ diff --git a/third_party/f2c/i_len.c b/third_party/f2c/i_len.c new file mode 100644 index 00000000..cbd687d6 --- /dev/null +++ b/third_party/f2c/i_len.c @@ -0,0 +1,24 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "third_party/f2c/f2c.h" + +integer i_len(char *s, ftnlen n) { + return n; +} diff --git a/third_party/f2c/internal.h b/third_party/f2c/internal.h new file mode 100644 index 00000000..78049427 --- /dev/null +++ b/third_party/f2c/internal.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_F2C_INTERNAL_H_ +#define COSMOPOLITAN_THIRD_PARTY_F2C_INTERNAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +void f_exit(void); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_F2C_INTERNAL_H_ */ diff --git a/third_party/f2c/open.c b/third_party/f2c/open.c new file mode 100644 index 00000000..28bfa395 --- /dev/null +++ b/third_party/f2c/open.c @@ -0,0 +1,284 @@ +#include "libc/calls/calls.h" +#include "libc/fmt/fmt.h" +#include "libc/mem/mem.h" +#include "libc/stdio/stdio.h" +#include "libc/stdio/temp.h" +#include "libc/str/str.h" +#include "third_party/f2c/f2c.h" +#include "third_party/f2c/fio.h" + +#ifdef KR_headers +extern char *malloc(); +#ifdef NON_ANSI_STDIO +extern char *mktemp(); +#endif +extern integer f_clos(); +#define Const /*nothing*/ +#else +#define Const const +#undef abs +#undef min +#undef max +#ifdef __cplusplus +extern "C" { +#endif +extern int f__canseek(FILE *); +extern integer f_clos(cllist *); +#endif + +#ifdef NON_ANSI_RW_MODES +Const char *f__r_mode[2] = {"r", "r"}; +Const char *f__w_mode[4] = {"w", "w", "r+w", "r+w"}; +#else +Const char *f__r_mode[2] = {"rb", "r"}; +Const char *f__w_mode[4] = {"wb", "w", "r+b", "r+"}; +#endif + +static char f__buf0[400], *f__buf = f__buf0; +int f__buflen = (int)sizeof(f__buf0); + +static void +#ifdef KR_headers + f__bufadj(n, c) int n, + c; +#else +f__bufadj(int n, int c) +#endif +{ + unsigned int len; + char *nbuf, *s, *t, *te; + + if (f__buf == f__buf0) f__buflen = 1024; + while (f__buflen <= n) f__buflen <<= 1; + len = (unsigned int)f__buflen; + if (len != f__buflen || !(nbuf = (char *)malloc(len))) + f__fatal(113, "malloc failure"); + s = nbuf; + t = f__buf; + te = t + c; + while (t < te) *s++ = *t++; + if (f__buf != f__buf0) free(f__buf); + f__buf = nbuf; +} + +int +#ifdef KR_headers + f__putbuf(c) int c; +#else +f__putbuf(int c) +#endif +{ + char *s, *se; + int n; + + if (f__hiwater > f__recpos) f__recpos = f__hiwater; + n = f__recpos + 1; + if (n >= f__buflen) f__bufadj(n, f__recpos); + s = f__buf; + se = s + f__recpos; + if (c) *se++ = c; + *se = 0; + for (;;) { + fputs(s, f__cf); + s += strlen(s); + if (s >= se) break; /* normally happens the first time */ + putc(*s++, f__cf); + } + return 0; +} + +void +#ifdef KR_headers +x_putc(c) +#else +x_putc(int c) +#endif +{ + if (f__recpos >= f__buflen) f__bufadj(f__recpos, f__buflen); + f__buf[f__recpos++] = c; +} + +#define opnerr(f, m, s) \ + { \ + if (f) \ + errno = m; \ + else \ + opn_err(m, s, a); \ + return (m); \ + } + +static void +#ifdef KR_headers + opn_err(m, s, a) int m; +char *s; +olist *a; +#else +opn_err(int m, const char *s, olist *a) +#endif +{ + if (a->ofnm) { + /* supply file name to error message */ + if (a->ofnmlen >= f__buflen) f__bufadj((int)a->ofnmlen, 0); + g_char(a->ofnm, a->ofnmlen, f__curunit->ufnm = f__buf); + } + f__fatal(m, s); +} + +#ifdef KR_headers +integer f_open(a) olist *a; +#else +integer f_open(olist *a) +#endif +{ + unit *b; + integer rv; + char buf[256], *s; + cllist x; + int ufmt; + FILE *tf; +#ifndef NON_UNIX_STDIO + int n; +#endif + f__external = 1; + if (a->ounit >= MXUNIT || a->ounit < 0) + err(a->oerr, 101, "open") if (!f__init) f_init(); + f__curunit = b = &f__units[a->ounit]; + if (b->ufd) { + if (a->ofnm == 0) { + same: + if (a->oblnk) b->ublnk = *a->oblnk == 'z' || *a->oblnk == 'Z'; + return (0); + } +#ifdef NON_UNIX_STDIO + if (b->ufnm && strlen(b->ufnm) == a->ofnmlen && + !strncmp(b->ufnm, a->ofnm, (unsigned)a->ofnmlen)) + goto same; +#else + g_char(a->ofnm, a->ofnmlen, buf); + if (f__inode(buf, &n) == b->uinode && n == b->udev) goto same; +#endif + x.cunit = a->ounit; + x.csta = 0; + x.cerr = a->oerr; + if ((rv = f_clos(&x)) != 0) return rv; + } + b->url = (int)a->orl; + b->ublnk = a->oblnk && (*a->oblnk == 'z' || *a->oblnk == 'Z'); + if (a->ofm == 0) { + if (b->url > 0) + b->ufmt = 0; + else + b->ufmt = 1; + } else if (*a->ofm == 'f' || *a->ofm == 'F') + b->ufmt = 1; + else + b->ufmt = 0; + ufmt = b->ufmt; +#ifdef url_Adjust + if (b->url && !ufmt) url_Adjust(b->url); +#endif + if (a->ofnm) { + g_char(a->ofnm, a->ofnmlen, buf); + if (!buf[0]) opnerr(a->oerr, 107, "open") + } else + sprintf(buf, "fort.%ld", (long)a->ounit); + b->uscrtch = 0; + b->uend = 0; + b->uwrt = 0; + b->ufd = 0; + b->urw = 3; + switch (a->osta ? *a->osta : 'u') { + case 'o': + case 'O': +#ifdef NON_POSIX_STDIO + if (!(tf = FOPEN(buf, "r"))) opnerr(a->oerr, errno, "open") fclose(tf); +#else + if (access(buf, 0)) + opnerr(a->oerr, errno, "open") +#endif + break; + case 's': + case 'S': + b->uscrtch = 1; +#ifdef NON_ANSI_STDIO + (void)strcpy(buf, "tmp.FXXXXXX"); + (void)mktemp(buf); + goto replace; +#else + if (!(b->ufd = tmpfile())) opnerr(a->oerr, errno, "open") b->ufnm = 0; +#ifndef NON_UNIX_STDIO + b->uinode = b->udev = -1; +#endif + b->useek = 1; + return 0; +#endif + + case 'n': + case 'N': +#ifdef NON_POSIX_STDIO + if ((tf = FOPEN(buf, "r")) || (tf = FOPEN(buf, "a"))) { + fclose(tf); + opnerr(a->oerr, 128, "open") + } +#else + if (!access(buf, 0)) + opnerr(a->oerr, 128, "open") +#endif + /* no break */ + case 'r': /* Fortran 90 replace option */ + case 'R': +#ifdef NON_ANSI_STDIO + replace: +#endif + if (tf = fopen(buf, f__w_mode[0])) fclose(tf); + } + + b->ufnm = (char *)malloc((unsigned int)(strlen(buf) + 1)); + if (b->ufnm == NULL) opnerr(a->oerr, 113, "no space"); + (void)strcpy(b->ufnm, buf); + if ((s = a->oacc) && b->url) ufmt = 0; + if (!(tf = fopen(buf, f__w_mode[ufmt | 2]))) { + if (tf = fopen(buf, f__r_mode[ufmt])) + b->urw = 1; + else if (tf = fopen(buf, f__w_mode[ufmt])) { + b->uwrt = 1; + b->urw = 2; + } else + err(a->oerr, errno, "open"); + } + b->useek = f__canseek(b->ufd = tf); +#ifndef NON_UNIX_STDIO + if ((b->uinode = f__inode(buf, &b->udev)) == -1) + opnerr(a->oerr, 108, "open") +#endif + if (b->useek) if (a->orl) rewind(b->ufd); + else if ((s = a->oacc) && (*s == 'a' || *s == 'A') && + fseek(b->ufd, 0L, SEEK_END)) + opnerr(a->oerr, 129, "open"); + return (0); +} + +int +#ifdef KR_headers + fk_open(seq, fmt, n) ftnint n; +#else +fk_open(int seq, int fmt, ftnint n) +#endif +{ + char nbuf[10]; + olist a; + (void)sprintf(nbuf, "fort.%ld", (long)n); + a.oerr = 1; + a.ounit = n; + a.ofnm = nbuf; + a.ofnmlen = strlen(nbuf); + a.osta = NULL; + a.oacc = (char *)(seq == SEQ ? "s" : "d"); + a.ofm = (char *)(fmt == FMT ? "f" : "u"); + a.orl = seq == DIR ? 1 : 0; + a.oblnk = NULL; + return (f_open(&a)); +} +#ifdef __cplusplus +} +#endif diff --git a/third_party/f2c/s_stop.c b/third_party/f2c/s_stop.c new file mode 100644 index 00000000..3277bc41 --- /dev/null +++ b/third_party/f2c/s_stop.c @@ -0,0 +1,21 @@ +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "third_party/f2c/f2c.h" +#include "third_party/f2c/internal.h" + +int s_stop(char *s, ftnlen n) { + int i; + if (n > 0) { + fprintf(stderr, "STOP "); + for (i = 0; i < n; ++i) putc(*s++, stderr); + fprintf(stderr, " statement executed\n"); + } +#ifdef NO_ONEXIT + f_exit(); +#endif + exit(0); + /* We cannot avoid (useless) compiler diagnostics here: */ + /* some compilers complain if there is no return statement, */ + /* and others complain that this one cannot be reached. */ + return 0; /* NOT REACHED */ +} diff --git a/third_party/f2c/sfe.c b/third_party/f2c/sfe.c new file mode 100644 index 00000000..e81b7686 --- /dev/null +++ b/third_party/f2c/sfe.c @@ -0,0 +1,29 @@ +/* sequential formatted external common routines*/ +#include "third_party/f2c/fio.h" +#include "third_party/f2c/fmt.h" + +integer e_rsfe(Void) { + int n; + n = en_fio(); + f__fmtbuf = NULL; + return (n); +} + +int c_sfe(cilist *a) /* check */ +{ + unit *p; + f__curunit = p = &f__units[a->ciunit]; + if (a->ciunit >= MXUNIT || a->ciunit < 0) err(a->cierr, 101, "startio"); + if (p->ufd == NULL && fk_open(SEQ, FMT, a->ciunit)) + err(a->cierr, 114, "sfe") if (!p->ufmt) + err(a->cierr, 102, "sfe") return (0); +} + +integer e_wsfe(Void) { + int n = en_fio(); + f__fmtbuf = NULL; +#ifdef ALWAYS_FLUSH + if (!n && fflush(f__cf)) err(f__elist->cierr, errno, "write end"); +#endif + return n; +} diff --git a/third_party/f2c/sig_die.c b/third_party/f2c/sig_die.c new file mode 100644 index 00000000..b9491407 --- /dev/null +++ b/third_party/f2c/sig_die.c @@ -0,0 +1,21 @@ +#include "libc/calls/calls.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/sig.h" +#include "third_party/f2c/internal.h" + +void sig_die(const char *s, int kill) { + /* print error message, then clear buffers */ + fprintf(stderr, "%s\n", s); + if (kill) { + fflush(stderr); + f_exit(); + fflush(stderr); + /* now get a core */ + signal(SIGIOT, SIG_DFL); + abort(); + } else { + f_exit(); + exit(1); + } +} diff --git a/third_party/f2c/trmlen.c b/third_party/f2c/trmlen.c new file mode 100644 index 00000000..9aeb7c5a --- /dev/null +++ b/third_party/f2c/trmlen.c @@ -0,0 +1,36 @@ +/* trmlen.f -- translated by f2c (version 20191129). + You must link the resulting object file with libf2c: + on Microsoft Windows system, link with libf2c.lib; + on Linux or Unix systems, link with .../path/to/libf2c.a -lm + or, if you install libf2c.a in a standard place, with -lf2c -lm + -- in that order, at the end of the command line, as in + cc *.o -lf2c -lm + Source for libf2c is in /netlib/f2c/libf2c.zip, e.g., + + http://www.netlib.org/f2c/libf2c.zip +*/ + +#include "third_party/f2c/f2c.h" + +extern void _uninit_f2c(void *, int, long); +extern double _0; + +/* Length of character string, excluding trailing blanks */ +/* Same thing as LEN_TRIM() */ +integer trmlen_(char *t, ftnlen t_len) { + /* System generated locals */ + integer ret_val; + + /* Builtin functions */ + integer i_len(char *, ftnlen); + + /* Parameter: */ + for (ret_val = i_len(t, t_len); ret_val >= 1; --ret_val) { + /* L1: */ + if (*(unsigned char *)&t[ret_val - 1] != ' ') { + return ret_val; + } + } + ret_val = 1; + return ret_val; +} /* trmlen_ */ diff --git a/third_party/f2c/trmlen.f b/third_party/f2c/trmlen.f new file mode 100644 index 00000000..b3995e28 --- /dev/null +++ b/third_party/f2c/trmlen.f @@ -0,0 +1,14 @@ +c Length of character string, excluding trailing blanks +c Same thing as LEN_TRIM() + + integer function trmlen(t) + + implicit none + +c Parameter: + character t*(*) + + do 1 trmlen=LEN(t),1,-1 + 1 if(t(trmlen:trmlen).ne.' ')RETURN + trmlen=1 + end ! of integer function trmlen diff --git a/third_party/f2c/util.c b/third_party/f2c/util.c new file mode 100644 index 00000000..5fd22f2e --- /dev/null +++ b/third_party/f2c/util.c @@ -0,0 +1,58 @@ +#include "libc/calls/calls.h" +#include "libc/calls/struct/stat.h" +#include "third_party/f2c/f2c.h" + +VOID +#ifdef KR_headers +#define Const /*nothing*/ + g_char(a, alen, b) char *a, + *b; +ftnlen alen; +#else +#define Const const +g_char(const char *a, ftnlen alen, char *b) +#endif +{ + Const char *x = a + alen; + char *y = b + alen; + + for (;; y--) { + if (x <= a) { + *b = 0; + return; + } + if (*--x != ' ') break; + } + *y-- = 0; + do + *y-- = *x; + while (x-- > a); +} + +VOID +#ifdef KR_headers + b_char(a, b, blen) char *a, + *b; +ftnlen blen; +#else +b_char(const char *a, char *b, ftnlen blen) +#endif +{ + int i; + for (i = 0; i < blen && *a != 0; i++) *b++ = *a++; + for (; i < blen; i++) *b++ = ' '; +} +#ifndef NON_UNIX_STDIO +#ifdef KR_headers +long f__inode(a, dev) char *a; +int *dev; +#else +long f__inode(char *a, int *dev) +#endif +{ + struct stat x; + if (stat(a, &x) < 0) return (-1); + *dev = x.st_dev; + return (x.st_ino); +} +#endif diff --git a/third_party/f2c/wref.c b/third_party/f2c/wref.c new file mode 100644 index 00000000..47f947b6 --- /dev/null +++ b/third_party/f2c/wref.c @@ -0,0 +1,246 @@ +#include "libc/conv/conv.h" +#include "libc/fmt/fmt.h" +#include "libc/str/str.h" +#include "third_party/f2c/fmt.h" +#include "third_party/f2c/fp.h" + +int wrt_E(ufloat *p, int w, int d, int e, ftnlen len) { + char buf[FMAX + EXPMAXDIGS + 4], *s, *se; + int d1, delta, e1, i, sign, signspace; + double dd; +#ifdef WANT_LEAD_0 + int insert0 = 0; +#endif +#ifndef VAX + int e0 = e; +#endif + + if (e <= 0) e = 2; + if (f__scale) { + if (f__scale >= d + 2 || f__scale <= -d) goto nogood; + } + if (f__scale <= 0) --d; + if (len == sizeof(real)) + dd = p->pf; + else + dd = p->pd; + if (dd < 0.) { + signspace = sign = 1; + dd = -dd; + } else { + sign = 0; + signspace = (int)f__cplus; +#ifndef VAX + if (!dd) { +#ifdef SIGNED_ZEROS + if (signbit_f2c(&dd)) signspace = sign = 1; +#endif + dd = 0.; /* avoid -0 */ + } +#endif + } + delta = w - (2 /* for the . and the d adjustment above */ + + 2 /* for the E+ */ + signspace + d + e); +#ifdef WANT_LEAD_0 + if (f__scale <= 0 && delta > 0) { + delta--; + insert0 = 1; + } else +#endif + if (delta < 0) { + nogood: + while (--w >= 0) PUT('*'); + return (0); + } + if (f__scale < 0) d += f__scale; + if (d > FMAX) { + d1 = d - FMAX; + d = FMAX; + } else + d1 = 0; + sprintf(buf, "%#.*E", d, dd); +#ifndef VAX + /* check for NaN, Infinity */ + if (!isdigit(buf[0])) { + switch (buf[0]) { + case 'n': + case 'N': + signspace = 0; /* no sign for NaNs */ + } + delta = w - strlen(buf) - signspace; + if (delta < 0) goto nogood; + while (--delta >= 0) PUT(' '); + if (signspace) PUT(sign ? '-' : '+'); + for (s = buf; *s; s++) PUT(*s); + return 0; + } +#endif + se = buf + d + 3; +#ifdef GOOD_SPRINTF_EXPONENT /* When possible, exponent has 2 digits. */ + if (f__scale != 1 && dd) sprintf(se, "%+.2d", atoi(se) + 1 - f__scale); +#else + if (dd) + sprintf(se, "%+.2d", atoi(se) + 1 - f__scale); + else + strcpy(se, "+00"); +#endif + s = ++se; + if (e < 2) { + if (*s != '0') goto nogood; + } +#ifndef VAX + /* accommodate 3 significant digits in exponent */ + if (s[2]) { +#ifdef Pedantic + if (!e0 && !s[3]) + for (s -= 2, e1 = 2; s[0] = s[1]; s++) + ; + + /* Pedantic gives the behavior that Fortran 77 specifies, */ + /* i.e., requires that E be specified for exponent fields */ + /* of more than 3 digits. With Pedantic undefined, we get */ + /* the behavior that Cray displays -- you get a bigger */ + /* exponent field if it fits. */ +#else + if (!e0) { + for (s -= 2, e1 = 2; s[0] = s[1]; s++) +#ifdef CRAY + delta--; + if ((delta += 4) < 0) + goto nogood +#endif + ; + } +#endif + else if (e0 >= 0) + goto shift; + else + e1 = e; + } else + shift: +#endif + for (s += 2, e1 = 2; *s; ++e1, ++s) + if (e1 >= e) goto nogood; + while (--delta >= 0) PUT(' '); + if (signspace) PUT(sign ? '-' : '+'); + s = buf; + i = f__scale; + if (f__scale <= 0) { +#ifdef WANT_LEAD_0 + if (insert0) PUT('0'); +#endif + PUT('.'); + for (; i < 0; ++i) PUT('0'); + PUT(*s); + s += 2; + } else if (f__scale > 1) { + PUT(*s); + s += 2; + while (--i > 0) PUT(*s++); + PUT('.'); + } + if (d1) { + se -= 2; + while (s < se) PUT(*s++); + se += 2; + do + PUT('0'); + while (--d1 > 0); + } + while (s < se) PUT(*s++); + if (e < 2) + PUT(s[1]); + else { + while (++e1 <= e) PUT('0'); + while (*s) PUT(*s++); + } + return 0; +} + +int wrt_F(ufloat *p, int w, int d, ftnlen len) { + int d1, sign, n; + double x; + char *b, buf[MAXINTDIGS + MAXFRACDIGS + 4], *s; + + x = (len == sizeof(real) ? p->pf : p->pd); + if (d < MAXFRACDIGS) + d1 = 0; + else { + d1 = d - MAXFRACDIGS; + d = MAXFRACDIGS; + } + if (x < 0.) { + x = -x; + sign = 1; + } else { + sign = 0; +#ifndef VAX + if (!x) { +#ifdef SIGNED_ZEROS + if (signbit_f2c(&x)) sign = 2; +#endif + x = 0.; + } +#endif + } + + if (n = f__scale) + if (n > 0) do + x *= 10.; + while (--n > 0); + else + do + x *= 0.1; + while (++n < 0); + +#ifdef USE_STRLEN + sprintf(b = buf, "%#.*f", d, x); + n = strlen(b) + d1; +#else + n = sprintf(b = buf, "%#.*f", d, x) + d1; +#endif + +#ifndef WANT_LEAD_0 + if (buf[0] == '0' && d) { + ++b; + --n; + } +#endif + if (sign == 1) { + /* check for all zeros */ + for (s = b;;) { + while (*s == '0') s++; + switch (*s) { + case '.': + s++; + continue; + case 0: + sign = 0; + } + break; + } + } + if (sign || f__cplus) ++n; + if (n > w) { +#ifdef WANT_LEAD_0 + if (buf[0] == '0' && --n == w) + ++b; + else +#endif + { + while (--w >= 0) PUT('*'); + return 0; + } + } + for (w -= n; --w >= 0;) PUT(' '); + if (sign) + PUT('-'); + else if (f__cplus) + PUT('+'); + while (n = *b++) PUT(n); + while (--d1 >= 0) PUT('0'); + return 0; +} +#ifdef __cplusplus +} +#endif diff --git a/third_party/f2c/wrtfmt.c b/third_party/f2c/wrtfmt.c new file mode 100644 index 00000000..c325bc5c --- /dev/null +++ b/third_party/f2c/wrtfmt.c @@ -0,0 +1,318 @@ +#include "third_party/f2c/f2c.h" +#include "third_party/f2c/fio.h" +#include "third_party/f2c/fmt.h" + +extern icilist *f__svic; +extern char *f__icptr; + +/* shouldn't use fseek because it insists on calling fflush */ +/* instead we know too much about stdio */ +static int mv_cur(void) { + int cursor = f__cursor; + f__cursor = 0; + if (f__external == 0) { + if (cursor < 0) { + if (f__hiwater < f__recpos) f__hiwater = f__recpos; + f__recpos += cursor; + f__icptr += cursor; + if (f__recpos < 0) err(f__elist->cierr, 110, "left off"); + } else if (cursor > 0) { + if (f__recpos + cursor >= f__svic->icirlen) + err(f__elist->cierr, 110, "recend"); + if (f__hiwater <= f__recpos) + for (; cursor > 0; cursor--) (*f__putn)(' '); + else if (f__hiwater <= f__recpos + cursor) { + cursor -= f__hiwater - f__recpos; + f__icptr += f__hiwater - f__recpos; + f__recpos = f__hiwater; + for (; cursor > 0; cursor--) (*f__putn)(' '); + } else { + f__icptr += cursor; + f__recpos += cursor; + } + } + return (0); + } + if (cursor > 0) { + if (f__hiwater <= f__recpos) + for (; cursor > 0; cursor--) (*f__putn)(' '); + else if (f__hiwater <= f__recpos + cursor) { + cursor -= f__hiwater - f__recpos; + f__recpos = f__hiwater; + for (; cursor > 0; cursor--) (*f__putn)(' '); + } else { + f__recpos += cursor; + } + } else if (cursor < 0) { + if (cursor + f__recpos < 0) err(f__elist->cierr, 110, "left off"); + if (f__hiwater < f__recpos) f__hiwater = f__recpos; + f__recpos += cursor; + } + return (0); +} + +static int wrt_Z(Uint *n, int w, int minlen, ftnlen len) { + register char *s, *se; + register int i, w1; + static int one = 1; + static char hex[] = "0123456789ABCDEF"; + s = (char *)n; + --len; + if (*(char *)&one) { + /* little endian */ + se = s; + s += len; + i = -1; + } else { + se = s + len; + i = 1; + } + for (;; s += i) + if (s == se || *s) break; + w1 = (i * (se - s) << 1) + 1; + if (*s & 0xf0) w1++; + if (w1 > w) + for (i = 0; i < w; i++) (*f__putn)('*'); + else { + if ((minlen -= w1) > 0) w1 += minlen; + while (--w >= w1) (*f__putn)(' '); + while (--minlen >= 0) (*f__putn)('0'); + if (!(*s & 0xf0)) { + (*f__putn)(hex[*s & 0xf]); + if (s == se) return 0; + s += i; + } + for (;; s += i) { + (*f__putn)(hex[*s >> 4 & 0xf]); + (*f__putn)(hex[*s & 0xf]); + if (s == se) break; + } + } + return 0; +} + +static int wrt_I(Uint *n, int w, ftnlen len, register int base) { + int ndigit, sign, spare, i; + longint x; + char *ans; + if (len == sizeof(integer)) + x = n->il; + else if (len == sizeof(char)) + x = n->ic; +#ifdef Allow_TYQUAD + else if (len == sizeof(longint)) + x = n->ili; +#endif + else + x = n->is; + ans = f__icvt(x, &ndigit, &sign, base); + spare = w - ndigit; + if (sign || f__cplus) spare--; + if (spare < 0) + for (i = 0; i < w; i++) (*f__putn)('*'); + else { + for (i = 0; i < spare; i++) (*f__putn)(' '); + if (sign) + (*f__putn)('-'); + else if (f__cplus) + (*f__putn)('+'); + for (i = 0; i < ndigit; i++) (*f__putn)(*ans++); + } + return (0); +} + +static int wrt_IM(Uint *n, int w, int m, ftnlen len, int base) { + int ndigit, sign, spare, i, xsign; + longint x; + char *ans; + if (sizeof(integer) == len) + x = n->il; + else if (len == sizeof(char)) + x = n->ic; +#ifdef Allow_TYQUAD + else if (len == sizeof(longint)) + x = n->ili; +#endif + else + x = n->is; + ans = f__icvt(x, &ndigit, &sign, base); + if (sign || f__cplus) + xsign = 1; + else + xsign = 0; + if (ndigit + xsign > w || m + xsign > w) { + for (i = 0; i < w; i++) (*f__putn)('*'); + return (0); + } + if (x == 0 && m == 0) { + for (i = 0; i < w; i++) (*f__putn)(' '); + return (0); + } + if (ndigit >= m) + spare = w - ndigit - xsign; + else + spare = w - m - xsign; + for (i = 0; i < spare; i++) (*f__putn)(' '); + if (sign) + (*f__putn)('-'); + else if (f__cplus) + (*f__putn)('+'); + for (i = 0; i < m - ndigit; i++) (*f__putn)('0'); + for (i = 0; i < ndigit; i++) (*f__putn)(*ans++); + return (0); +} + +static int wrt_AP(char *s) { + char quote; + int i; + + if (f__cursor && (i = mv_cur())) return i; + quote = *s++; + for (; *s; s++) { + if (*s != quote) + (*f__putn)(*s); + else if (*++s == quote) + (*f__putn)(*s); + else + return (1); + } + return (1); +} + +static int wrt_H(int a, char *s) { + int i; + + if (f__cursor && (i = mv_cur())) return i; + while (a--) (*f__putn)(*s++); + return (1); +} + +int wrt_L(Uint *n, int len, ftnlen sz) { + int i; + long x; + if (sizeof(long) == sz) + x = n->il; + else if (sz == sizeof(char)) + x = n->ic; + else + x = n->is; + for (i = 0; i < len - 1; i++) (*f__putn)(' '); + if (x) + (*f__putn)('T'); + else + (*f__putn)('F'); + return (0); +} + +static int wrt_A(char *p, ftnlen len) { + while (len-- > 0) (*f__putn)(*p++); + return (0); +} + +static int wrt_AW(char *p, int w, ftnlen len) { + while (w > len) { + w--; + (*f__putn)(' '); + } + while (w-- > 0) (*f__putn)(*p++); + return (0); +} + +static int wrt_G(ufloat *p, int w, int d, int e, ftnlen len) { + double up = 1, x; + int i = 0, oldscale, n, j; + x = len == sizeof(real) ? p->pf : p->pd; + if (x < 0) x = -x; + if (x < .1) { + if (x != 0.) return (wrt_E(p, w, d, e, len)); + i = 1; + goto have_i; + } + for (; i <= d; i++, up *= 10) { + if (x >= up) continue; + have_i: + oldscale = f__scale; + f__scale = 0; + if (e == 0) + n = 4; + else + n = e + 2; + i = wrt_F(p, w - n, d - i, len); + for (j = 0; j < n; j++) (*f__putn)(' '); + f__scale = oldscale; + return (i); + } + return (wrt_E(p, w, d, e, len)); +} + +int w_ed(struct syl *p, char *ptr, ftnlen len) { + int i; + + if (f__cursor && (i = mv_cur())) return i; + switch (p->op) { + default: + fprintf(stderr, "w_ed, unexpected code: %d\n", p->op); + sig_die(f__fmtbuf, 1); + case I: + return (wrt_I((Uint *)ptr, p->p1, len, 10)); + case IM: + return (wrt_IM((Uint *)ptr, p->p1, p->p2.i[0], len, 10)); + + /* O and OM don't work right for character, double, complex, */ + /* or doublecomplex, and they differ from Fortran 90 in */ + /* showing a minus sign for negative values. */ + + case O: + return (wrt_I((Uint *)ptr, p->p1, len, 8)); + case OM: + return (wrt_IM((Uint *)ptr, p->p1, p->p2.i[0], len, 8)); + case L: + return (wrt_L((Uint *)ptr, p->p1, len)); + case A: + return (wrt_A(ptr, len)); + case AW: + return (wrt_AW(ptr, p->p1, len)); + case D: + case E: + case EE: + return (wrt_E((ufloat *)ptr, p->p1, p->p2.i[0], p->p2.i[1], len)); + case G: + case GE: + return (wrt_G((ufloat *)ptr, p->p1, p->p2.i[0], p->p2.i[1], len)); + case F: + return (wrt_F((ufloat *)ptr, p->p1, p->p2.i[0], len)); + + /* Z and ZM assume 8-bit bytes. */ + + case Z: + return (wrt_Z((Uint *)ptr, p->p1, 0, len)); + case ZM: + return (wrt_Z((Uint *)ptr, p->p1, p->p2.i[0], len)); + } +} + +int w_ned(struct syl *p) { + switch (p->op) { + default: + fprintf(stderr, "w_ned, unexpected code: %d\n", p->op); + sig_die(f__fmtbuf, 1); + case SLASH: + return ((*f__donewrec)()); + case T: + f__cursor = p->p1 - f__recpos - 1; + return (1); + case TL: + f__cursor -= p->p1; + if (f__cursor < -f__recpos) /* TL1000, 1X */ + f__cursor = -f__recpos; + return (1); + case TR: + case X: + f__cursor += p->p1; + return (1); + case APOS: + return (wrt_AP(p->p2.s)); + case H: + return (wrt_H(p->p1, p->p2.s)); + } +} diff --git a/third_party/f2c/wsfe.c b/third_party/f2c/wsfe.c new file mode 100644 index 00000000..f3ad1b9c --- /dev/null +++ b/third_party/f2c/wsfe.c @@ -0,0 +1,61 @@ +#include "third_party/f2c/f2c.h" +#include "third_party/f2c/fio.h" +#include "third_party/f2c/fmt.h" +/*write sequential formatted external*/ + +int x_wSL(Void) { + int n = f__putbuf('\n'); + f__hiwater = f__recpos = f__cursor = 0; + return (n == 0); +} + +static int xw_end(Void) { + int n; + if (f__nonl) { + f__putbuf(n = 0); + fflush(f__cf); + } else + n = f__putbuf('\n'); + f__hiwater = f__recpos = f__cursor = 0; + return n; +} + +static int xw_rev(Void) { + int n = 0; + if (f__workdone) { + n = f__putbuf('\n'); + f__workdone = 0; + } + f__hiwater = f__recpos = f__cursor = 0; + return n; +} + +/*start*/ +integer s_wsfe(cilist *a) { + int n; + if (!f__init) f_init(); + f__reading = 0; + f__sequential = 1; + f__formatted = 1; + f__external = 1; + if (n = c_sfe(a)) return (n); + f__elist = a; + f__hiwater = f__cursor = f__recpos = 0; + f__nonl = 0; + f__scale = 0; + f__fmtbuf = a->cifmt; + f__cf = f__curunit->ufd; + if (pars_f(f__fmtbuf) < 0) err(a->cierr, 100, "startio"); + f__putn = x_putc; + f__doed = w_ed; + f__doned = w_ned; + f__doend = xw_end; + f__dorevert = xw_rev; + f__donewrec = x_wSL; + fmt_bg(); + f__cplus = 0; + f__cblank = f__curunit->ublnk; + if (f__curunit->uwrt != 1 && f__nowwriting(f__curunit)) + err(a->cierr, errno, "write start"); + return (0); +} diff --git a/third_party/gcc/LICENSE.txt b/third_party/gcc/LICENSE.txt new file mode 100644 index 00000000..763cb259 --- /dev/null +++ b/third_party/gcc/LICENSE.txt @@ -0,0 +1,17107 @@ + +./binutils-2.32/COPYING +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + +./binutils-2.32/COPYING.LIB +======================================================================== + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + +./binutils-2.32/COPYING3 +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + +./binutils-2.32/COPYING3.LIB +======================================================================== + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + +./binutils-2.32/bfd/COPYING +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + +./binutils-2.32/gas/COPYING +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + +./binutils-2.32/include/COPYING +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + +./binutils-2.32/include/COPYING3 +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + +./binutils-2.32/libiberty/COPYING.LIB +======================================================================== + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + + +./binutils-2.32/libiberty/copying-lib.texi +======================================================================== +@node Library Copying +@appendixsec GNU LESSER GENERAL PUBLIC LICENSE + +@cindex LGPL, Lesser General Public License +@center Version 2.1, February 1999 + +@display +Copyright @copyright{} 1991-2019 Free Software Foundation, Inc. +51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts +as the successor of the GNU Library Public License, version 2, hence the +version number 2.1.] +@end display + +@appendixsubsec Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software---to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software---typically libraries---of the Free +Software Foundation and other authors who decide to use it. You can use +it too, but we suggest you first think carefully about whether this +license or the ordinary General Public License is the better strategy to +use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of it +in new free programs; and that you are informed that you can do these +things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the @dfn{Lesser} General Public License because it +does @emph{Less} to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +``work based on the library'' and a ``work that uses the library''. The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + +@iftex +@appendixsubsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +@end iftex +@ifinfo +@center GNU LESSER GENERAL PUBLIC LICENSE +@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +@end ifinfo + +@enumerate 0 +@item +This License Agreement applies to any software library or other program +which contains a notice placed by the copyright holder or other +authorized party saying it may be distributed under the terms of this +Lesser General Public License (also called ``this License''). Each +licensee is addressed as ``you''. + + A ``library'' means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The ``Library'', below, refers to any such software library or work +which has been distributed under these terms. A ``work based on the +Library'' means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term ``modification''.) + + ``Source code'' for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + +@item +You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + +@item +You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + +@enumerate a +@item +The modified work must itself be a software library. + +@item +You must cause the files modified to carry prominent notices +stating that you changed the files and the date of any change. + +@item +You must cause the whole of the work to be licensed at no +charge to all third parties under the terms of this License. + +@item +If a facility in the modified Library refers to a function or a +table of data to be supplied by an application program that uses +the facility, other than as an argument passed when the facility +is invoked, then you must make a good faith effort to ensure that, +in the event an application does not supply such function or +table, the facility still operates, and performs whatever part of +its purpose remains meaningful. + +(For example, a function in a library to compute square roots has +a purpose that is entirely well-defined independent of the +application. Therefore, Subsection 2d requires that any +application-supplied function or table used by this function must +be optional: if the application does not supply it, the square +root function must still compute square roots.) +@end enumerate + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +@item +You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + +@item +You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + +@item +A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a ``work that uses the Library''. Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a ``work that uses the Library'' with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a ``work that uses the +library''. The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a ``work that uses the Library'' uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + +@item +As an exception to the Sections above, you may also combine or +link a ``work that uses the Library'' with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + +@enumerate a +@item +Accompany the work with the complete corresponding +machine-readable source code for the Library including whatever +changes were used in the work (which must be distributed under +Sections 1 and 2 above); and, if the work is an executable linked +with the Library, with the complete machine-readable ``work that +uses the Library'', as object code and/or source code, so that the +user can modify the Library and then relink to produce a modified +executable containing the modified Library. (It is understood +that the user who changes the contents of definitions files in the +Library will not necessarily be able to recompile the application +to use the modified definitions.) + +@item +Use a suitable shared library mechanism for linking with the Library. A +suitable mechanism is one that (1) uses at run time a copy of the +library already present on the user's computer system, rather than +copying library functions into the executable, and (2) will operate +properly with a modified version of the library, if the user installs +one, as long as the modified version is interface-compatible with the +version that the work was made with. + +@item +Accompany the work with a written offer, valid for at +least three years, to give the same user the materials +specified in Subsection 6a, above, for a charge no more +than the cost of performing this distribution. + +@item +If distribution of the work is made by offering access to copy +from a designated place, offer equivalent access to copy the above +specified materials from the same place. + +@item +Verify that the user has already received a copy of these +materials or that you have already sent this user a copy. +@end enumerate + + For an executable, the required form of the ``work that uses the +Library'' must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies the +executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + +@item +You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + +@enumerate a +@item +Accompany the combined library with a copy of the same work +based on the Library, uncombined with any other library +facilities. This must be distributed under the terms of the +Sections above. + +@item +Give prominent notice with the combined library of the fact +that part of it is a work based on the Library, and explaining +where to find the accompanying uncombined form of the same work. +@end enumerate + +@item +You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + +@item +You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +@item +Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + +@item +If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +@item +If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + +@item +The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +``any later version'', you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + +@item +If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + +@center NO WARRANTY + +@item +BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY ``AS IS'' WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +@item +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. +@end enumerate + +@iftex +@heading END OF TERMS AND CONDITIONS +@end iftex +@ifinfo +@center END OF TERMS AND CONDITIONS +@end ifinfo + +@page +@appendixsubsec How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +``copyright'' line and a pointer to where the full notice is found. + +@smallexample +@var{one line to give the library's name and an idea of what it does.} +Copyright (C) @var{year} @var{name of author} + +This library is free software; you can redistribute it and/or modify it +under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at +your option) any later version. + +This library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. +@end smallexample + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a ``copyright disclaimer'' for the library, if +necessary. Here is a sample; alter the names: + +@smallexample +Yoyodyne, Inc., hereby disclaims all copyright interest in the library +`Frob' (a library for tweaking knobs) written by James Random Hacker. + +@var{signature of Ty Coon}, 1 April 1990 +Ty Coon, President of Vice +@end smallexample + +That's all there is to it! + +./binutils-2.32/zlib/contrib/dotzlib/LICENSE_1_0.txt +======================================================================== +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +./build/local/x86_64-linux-musl/src_gcc/COPYING +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + +./build/local/x86_64-linux-musl/src_gcc/COPYING.LIB +======================================================================== + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the library, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James + Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + + +./build/local/x86_64-linux-musl/src_gcc/COPYING.RUNTIME +======================================================================== +GCC RUNTIME LIBRARY EXCEPTION + +Version 3.1, 31 March 2009 + +Copyright (C) 2009 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + +This GCC Runtime Library Exception ("Exception") is an additional +permission under section 7 of the GNU General Public License, version +3 ("GPLv3"). It applies to a given file (the "Runtime Library") that +bears a notice placed by the copyright holder of the file stating that +the file is governed by GPLv3 along with this Exception. + +When you use GCC to compile a program, GCC may combine portions of +certain GCC header files and runtime libraries with the compiled +program. The purpose of this Exception is to allow compilation of +non-GPL (including proprietary) programs to use, in this way, the +header files and runtime libraries covered by this Exception. + +0. Definitions. + +A file is an "Independent Module" if it either requires the Runtime +Library for execution after a Compilation Process, or makes use of an +interface provided by the Runtime Library, but is not otherwise based +on the Runtime Library. + +"GCC" means a version of the GNU Compiler Collection, with or without +modifications, governed by version 3 (or a specified later version) of +the GNU General Public License (GPL) with the option of using any +subsequent versions published by the FSF. + +"GPL-compatible Software" is software whose conditions of propagation, +modification and use would permit combination with GCC in accord with +the license of GCC. + +"Target Code" refers to output from any compiler for a real or virtual +target processor architecture, in executable form or suitable for +input to an assembler, loader, linker and/or execution +phase. Notwithstanding that, Target Code does not include data in any +format that is used as a compiler intermediate representation, or used +for producing a compiler intermediate representation. + +The "Compilation Process" transforms code entirely represented in +non-intermediate languages designed for human-written code, and/or in +Java Virtual Machine byte code, into Target Code. Thus, for example, +use of source code generators and preprocessors need not be considered +part of the Compilation Process, since the Compilation Process can be +understood as starting with the output of the generators or +preprocessors. + +A Compilation Process is "Eligible" if it is done using GCC, alone or +with other GPL-compatible software, or if it is done without using any +work based on GCC. For example, using non-GPL-compatible Software to +optimize any GCC intermediate representations would not qualify as an +Eligible Compilation Process. + +1. Grant of Additional Permission. + +You have permission to propagate a work of Target Code formed by +combining the Runtime Library with Independent Modules, even if such +propagation would otherwise violate the terms of GPLv3, provided that +all Target Code was generated by Eligible Compilation Processes. You +may then convey such a combination under terms of your choice, +consistent with the licensing of the Independent Modules. + +2. No Weakening of GCC Copyleft. + +The availability of this Exception does not imply any general +presumption that third-party software is unaffected by the copyleft +requirements of the license of GCC. + + +./build/local/x86_64-linux-musl/src_gcc/COPYING3 +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + +./build/local/x86_64-linux-musl/src_gcc/COPYING3.LIB +======================================================================== + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + +./gcc-9.2.0/COPYING +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + +./gcc-9.2.0/COPYING.LIB +======================================================================== + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the library, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James + Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + + +./gcc-9.2.0/COPYING.RUNTIME +======================================================================== +GCC RUNTIME LIBRARY EXCEPTION + +Version 3.1, 31 March 2009 + +Copyright (C) 2009 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + +This GCC Runtime Library Exception ("Exception") is an additional +permission under section 7 of the GNU General Public License, version +3 ("GPLv3"). It applies to a given file (the "Runtime Library") that +bears a notice placed by the copyright holder of the file stating that +the file is governed by GPLv3 along with this Exception. + +When you use GCC to compile a program, GCC may combine portions of +certain GCC header files and runtime libraries with the compiled +program. The purpose of this Exception is to allow compilation of +non-GPL (including proprietary) programs to use, in this way, the +header files and runtime libraries covered by this Exception. + +0. Definitions. + +A file is an "Independent Module" if it either requires the Runtime +Library for execution after a Compilation Process, or makes use of an +interface provided by the Runtime Library, but is not otherwise based +on the Runtime Library. + +"GCC" means a version of the GNU Compiler Collection, with or without +modifications, governed by version 3 (or a specified later version) of +the GNU General Public License (GPL) with the option of using any +subsequent versions published by the FSF. + +"GPL-compatible Software" is software whose conditions of propagation, +modification and use would permit combination with GCC in accord with +the license of GCC. + +"Target Code" refers to output from any compiler for a real or virtual +target processor architecture, in executable form or suitable for +input to an assembler, loader, linker and/or execution +phase. Notwithstanding that, Target Code does not include data in any +format that is used as a compiler intermediate representation, or used +for producing a compiler intermediate representation. + +The "Compilation Process" transforms code entirely represented in +non-intermediate languages designed for human-written code, and/or in +Java Virtual Machine byte code, into Target Code. Thus, for example, +use of source code generators and preprocessors need not be considered +part of the Compilation Process, since the Compilation Process can be +understood as starting with the output of the generators or +preprocessors. + +A Compilation Process is "Eligible" if it is done using GCC, alone or +with other GPL-compatible software, or if it is done without using any +work based on GCC. For example, using non-GPL-compatible Software to +optimize any GCC intermediate representations would not qualify as an +Eligible Compilation Process. + +1. Grant of Additional Permission. + +You have permission to propagate a work of Target Code formed by +combining the Runtime Library with Independent Modules, even if such +propagation would otherwise violate the terms of GPLv3, provided that +all Target Code was generated by Eligible Compilation Processes. You +may then convey such a combination under terms of your choice, +consistent with the licensing of the Independent Modules. + +2. No Weakening of GCC Copyleft. + +The availability of this Exception does not imply any general +presumption that third-party software is unaffected by the copyleft +requirements of the license of GCC. + + +./gcc-9.2.0/COPYING3 +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + +./gcc-9.2.0/COPYING3.LIB +======================================================================== + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + +./gcc-9.2.0/gcc/COPYING +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + +./gcc-9.2.0/gcc/COPYING.LIB +======================================================================== + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + + +./gcc-9.2.0/gcc/COPYING3 +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + +./gcc-9.2.0/gcc/COPYING3.LIB +======================================================================== + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + +./gcc-9.2.0/gcc/ada/doc/share/gnu_free_documentation_license.rst +======================================================================== +.. _gnu_fdl: + +****************************** +GNU Free Documentation License +****************************** + +Version 1.3, 3 November 2008 + +Copyright 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc +http://fsf.org/ + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + +**Preamble** + +The purpose of this License is to make a manual, textbook, or other +functional and useful document "free" in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of "copyleft", which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + +**1. APPLICABILITY AND DEFINITIONS** + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The **Document**, below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as "**you**". You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A "**Modified Version**" of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A "**Secondary Section**" is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall subject +(or to related matters) and contains nothing that could fall directly +within that overall subject. (Thus, if the Document is in part a +textbook of mathematics, a Secondary Section may not explain any +mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The "**Invariant Sections**" are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The "**Cover Texts**" are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A "**Transparent**" copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not "Transparent" is called **Opaque**. + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML, PostScript or PDF designed for human modification. Examples of +transparent image formats include PNG, XCF and JPG. Opaque formats +include proprietary formats that can be read and edited only by +proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML, PostScript or PDF produced by some word +processors for output purposes only. + +The "**Title Page**" means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, "Title Page" means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +The "**publisher**" means any person or entity that distributes +copies of the Document to the public. + +A section "**Entitled XYZ**" means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as "**Acknowledgements**", +"**Dedications**", "**Endorsements**", or "**History**".) +To "**Preserve the Title**" +of such a section when you modify the Document means that it remains a +section "Entitled XYZ" according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + +**2. VERBATIM COPYING** + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + +**3. COPYING IN QUANTITY** + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + +**4. MODIFICATIONS** + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. + +B. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has fewer than five), + unless they release you from this requirement. + +C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. + +D. Preserve all the copyright notices of the Document. + +E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. + +F. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. + +G. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +H. Include an unaltered copy of this License. + +I. Preserve the section Entitled "History", Preserve its Title, and add + to it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section Entitled "History" in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. + +J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the "History" section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. + +K. For any section Entitled "Acknowledgements" or "Dedications", + Preserve the Title of the section, and preserve in the section all + the substance and tone of each of the contributor acknowledgements + and/or dedications given therein. + +L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. + +M. Delete any section Entitled "Endorsements". Such a section + may not be included in the Modified Version. + +N. Do not retitle any existing section to be Entitled "Endorsements" + or to conflict in title with any Invariant Section. + +O. Preserve any Warranty Disclaimers. + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled "Endorsements", provided it contains +nothing but endorsements of your Modified Version by various +parties---for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + +**5. COMBINING DOCUMENTS** + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled "History" +in the various original documents, forming one section Entitled +"History"; likewise combine any sections Entitled "Acknowledgements", +and any sections Entitled "Dedications". You must delete all sections +Entitled "Endorsements". + +**6. COLLECTIONS OF DOCUMENTS** + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + +**7. AGGREGATION WITH INDEPENDENT WORKS** + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an "aggregate" if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + +**8. TRANSLATION** + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled "Acknowledgements", +"Dedications", or "History", the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + +**9. TERMINATION** + +You may not copy, modify, sublicense, or distribute the Document +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense, or distribute it is void, and +will automatically terminate your rights under this License. + +However, if you cease all violation of this License, then your license +from a particular copyright holder is reinstated (a) provisionally, +unless and until the copyright holder explicitly and finally +terminates your license, and (b) permanently, if the copyright holder +fails to notify you of the violation by some reasonable means prior to +60 days after the cessation. + +Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, receipt of a copy of some or all of the same material does +not give you any rights to use it. + +**10. FUTURE REVISIONS OF THIS LICENSE** + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +http://www.gnu.org/copyleft/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. If the Document +specifies that a proxy can decide which future versions of this +License can be used, that proxy's public statement of acceptance of a +version permanently authorizes you to choose that version for the +Document. + +**11. RELICENSING** + +"Massive Multiauthor Collaboration Site" (or "MMC Site") means any +World Wide Web server that publishes copyrightable works and also +provides prominent facilities for anybody to edit those works. A +public wiki that anybody can edit is an example of such a server. A +"Massive Multiauthor Collaboration" (or "MMC") contained in the +site means any set of copyrightable works thus published on the MMC +site. + +"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 +license published by Creative Commons Corporation, a not-for-profit +corporation with a principal place of business in San Francisco, +California, as well as future copyleft versions of that license +published by that same organization. + +"Incorporate" means to publish or republish a Document, in whole or +in part, as part of another Document. + +An MMC is "eligible for relicensing" if it is licensed under this +License, and if all works that were first published under this License +somewhere other than this MMC, and subsequently incorporated in whole +or in part into the MMC, (1) had no cover texts or invariant sections, +and (2) were thus incorporated prior to November 1, 2008. + +The operator of an MMC Site may republish an MMC contained in the site +under CC-BY-SA on the same site at any time before August 1, 2009, +provided the MMC is eligible for relicensing. + +**ADDENDUM: How to use this License for your documents** + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + + Copyright © YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the "with ... Texts." line with this: + + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. + +./gcc-9.2.0/gcc/d/dmd/boostlicense.txt +======================================================================== +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +./gcc-9.2.0/gcc/go/gofrontend/LICENSE +======================================================================== +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +./gcc-9.2.0/gcc/testsuite/gcc.dg/params/LICENSE +======================================================================== + +-------------------------------------------------------------------------- + +This program, "bzip2", the associated library "libbzip2", and all +documentation, are copyright (C) 1996-2010 Julian R Seward. All +rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + +3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + +4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Julian Seward, jseward@bzip.org +bzip2/libbzip2 version 1.0.6 of 6 September 2010 + +-------------------------------------------------------------------------- + +./gcc-9.2.0/include/COPYING +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + +./gcc-9.2.0/include/COPYING3 +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + +./gcc-9.2.0/libffi/LICENSE +======================================================================== +libffi - Copyright (c) 1996-2014 Anthony Green, Red Hat, Inc and others. +See source files for details. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +``Software''), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +./gcc-9.2.0/libgo/LICENSE +======================================================================== +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +./gcc-9.2.0/libgo/go/golang.org/x/tools/LICENSE +======================================================================== +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +./gcc-9.2.0/libiberty/COPYING.LIB +======================================================================== + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + + +./gcc-9.2.0/libiberty/copying-lib.texi +======================================================================== +@node Library Copying +@appendixsec GNU LESSER GENERAL PUBLIC LICENSE + +@cindex LGPL, Lesser General Public License +@center Version 2.1, February 1999 + +@display +Copyright @copyright{} 1991-2019 Free Software Foundation, Inc. +51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts +as the successor of the GNU Library Public License, version 2, hence the +version number 2.1.] +@end display + +@appendixsubsec Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software---to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software---typically libraries---of the Free +Software Foundation and other authors who decide to use it. You can use +it too, but we suggest you first think carefully about whether this +license or the ordinary General Public License is the better strategy to +use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of it +in new free programs; and that you are informed that you can do these +things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the @dfn{Lesser} General Public License because it +does @emph{Less} to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +``work based on the library'' and a ``work that uses the library''. The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + +@iftex +@appendixsubsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +@end iftex +@ifinfo +@center GNU LESSER GENERAL PUBLIC LICENSE +@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +@end ifinfo + +@enumerate 0 +@item +This License Agreement applies to any software library or other program +which contains a notice placed by the copyright holder or other +authorized party saying it may be distributed under the terms of this +Lesser General Public License (also called ``this License''). Each +licensee is addressed as ``you''. + + A ``library'' means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The ``Library'', below, refers to any such software library or work +which has been distributed under these terms. A ``work based on the +Library'' means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term ``modification''.) + + ``Source code'' for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + +@item +You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + +@item +You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + +@enumerate a +@item +The modified work must itself be a software library. + +@item +You must cause the files modified to carry prominent notices +stating that you changed the files and the date of any change. + +@item +You must cause the whole of the work to be licensed at no +charge to all third parties under the terms of this License. + +@item +If a facility in the modified Library refers to a function or a +table of data to be supplied by an application program that uses +the facility, other than as an argument passed when the facility +is invoked, then you must make a good faith effort to ensure that, +in the event an application does not supply such function or +table, the facility still operates, and performs whatever part of +its purpose remains meaningful. + +(For example, a function in a library to compute square roots has +a purpose that is entirely well-defined independent of the +application. Therefore, Subsection 2d requires that any +application-supplied function or table used by this function must +be optional: if the application does not supply it, the square +root function must still compute square roots.) +@end enumerate + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +@item +You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + +@item +You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + +@item +A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a ``work that uses the Library''. Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a ``work that uses the Library'' with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a ``work that uses the +library''. The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a ``work that uses the Library'' uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + +@item +As an exception to the Sections above, you may also combine or +link a ``work that uses the Library'' with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + +@enumerate a +@item +Accompany the work with the complete corresponding +machine-readable source code for the Library including whatever +changes were used in the work (which must be distributed under +Sections 1 and 2 above); and, if the work is an executable linked +with the Library, with the complete machine-readable ``work that +uses the Library'', as object code and/or source code, so that the +user can modify the Library and then relink to produce a modified +executable containing the modified Library. (It is understood +that the user who changes the contents of definitions files in the +Library will not necessarily be able to recompile the application +to use the modified definitions.) + +@item +Use a suitable shared library mechanism for linking with the Library. A +suitable mechanism is one that (1) uses at run time a copy of the +library already present on the user's computer system, rather than +copying library functions into the executable, and (2) will operate +properly with a modified version of the library, if the user installs +one, as long as the modified version is interface-compatible with the +version that the work was made with. + +@item +Accompany the work with a written offer, valid for at +least three years, to give the same user the materials +specified in Subsection 6a, above, for a charge no more +than the cost of performing this distribution. + +@item +If distribution of the work is made by offering access to copy +from a designated place, offer equivalent access to copy the above +specified materials from the same place. + +@item +Verify that the user has already received a copy of these +materials or that you have already sent this user a copy. +@end enumerate + + For an executable, the required form of the ``work that uses the +Library'' must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies the +executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + +@item +You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + +@enumerate a +@item +Accompany the combined library with a copy of the same work +based on the Library, uncombined with any other library +facilities. This must be distributed under the terms of the +Sections above. + +@item +Give prominent notice with the combined library of the fact +that part of it is a work based on the Library, and explaining +where to find the accompanying uncombined form of the same work. +@end enumerate + +@item +You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + +@item +You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +@item +Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + +@item +If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +@item +If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + +@item +The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +``any later version'', you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + +@item +If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + +@center NO WARRANTY + +@item +BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY ``AS IS'' WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +@item +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. +@end enumerate + +@iftex +@heading END OF TERMS AND CONDITIONS +@end iftex +@ifinfo +@center END OF TERMS AND CONDITIONS +@end ifinfo + +@page +@appendixsubsec How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +``copyright'' line and a pointer to where the full notice is found. + +@smallexample +@var{one line to give the library's name and an idea of what it does.} +Copyright (C) @var{year} @var{name of author} + +This library is free software; you can redistribute it and/or modify it +under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at +your option) any later version. + +This library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. +@end smallexample + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a ``copyright disclaimer'' for the library, if +necessary. Here is a sample; alter the names: + +@smallexample +Yoyodyne, Inc., hereby disclaims all copyright interest in the library +`Frob' (a library for tweaking knobs) written by James Random Hacker. + +@var{signature of Ty Coon}, 1 April 1990 +Ty Coon, President of Vice +@end smallexample + +That's all there is to it! + +./gcc-9.2.0/libphobos/libdruntime/LICENSE +======================================================================== +DRuntime: Runtime Library for the D Programming Language +======================================================== + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +./gcc-9.2.0/libphobos/src/LICENSE_1_0.txt +======================================================================== +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +./gcc-9.2.0/libquadmath/COPYING.LIB +======================================================================== + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + + +./gcc-9.2.0/libsanitizer/LICENSE.TXT +======================================================================== +============================================================================== +compiler_rt License +============================================================================== + +The compiler_rt library is dual licensed under both the University of Illinois +"BSD-Like" license and the MIT license. As a user of this code you may choose +to use it under either license. As a contributor, you agree to allow your code +to be used under both. + +Full text of the relevant licenses is included below. + +============================================================================== + +University of Illinois/NCSA +Open Source License + +Copyright (c) 2009-2012 by the contributors listed in CREDITS.TXT + +All rights reserved. + +Developed by: + + LLVM Team + + University of Illinois at Urbana-Champaign + + http://llvm.org + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE +SOFTWARE. + +============================================================================== + +Copyright (c) 2009-2012 by the contributors listed in CREDITS.TXT + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +============================================================================== +Copyrights and Licenses for Third Party Software Distributed with LLVM: +============================================================================== +The LLVM software contains code written by third parties. Such software will +have its own individual LICENSE.TXT file in the directory in which it appears. +This file will describe the copyrights, license, and restrictions which apply +to that code. + +The disclaimer of warranty in the University of Illinois Open Source License +applies to all code in the LLVM Distribution, and nothing in any of the +other licenses gives permission to use the names of the LLVM Team or the +University of Illinois to endorse or promote products derived from this +Software. + +The following pieces of software have additional or alternate copyrights, +licenses, and/or restrictions: + +Program Directory +------- --------- +mach_override lib/interception/mach_override + +./gcc-9.2.0/libstdc++-v3/doc/html/manual/license.html +======================================================================== + +License

License

+ There are two licenses affecting GNU libstdc++: one for the code, + and one for the documentation. +

+ There is a license section in the FAQ regarding common questions. If you have more + questions, ask the FSF or the gcc mailing list. +

The Code: GPL

+ The source code is distributed under the GNU General Public License version 3, + with the addition under section 7 of an exception described in + the GCC Runtime Library Exception, version 3.1 + as follows (or see the file COPYING.RUNTIME): +


+GCC RUNTIME LIBRARY EXCEPTION
+
+Version 3.1, 31 March 2009
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+This GCC Runtime Library Exception ("Exception") is an additional
+permission under section 7 of the GNU General Public License, version
+3 ("GPLv3"). It applies to a given file (the "Runtime Library") that
+bears a notice placed by the copyright holder of the file stating that
+the file is governed by GPLv3 along with this Exception.
+
+When you use GCC to compile a program, GCC may combine portions of
+certain GCC header files and runtime libraries with the compiled
+program. The purpose of this Exception is to allow compilation of
+non-GPL (including proprietary) programs to use, in this way, the
+header files and runtime libraries covered by this Exception.
+
+0. Definitions.
+
+A file is an "Independent Module" if it either requires the Runtime
+Library for execution after a Compilation Process, or makes use of an
+interface provided by the Runtime Library, but is not otherwise based
+on the Runtime Library.
+
+"GCC" means a version of the GNU Compiler Collection, with or without
+modifications, governed by version 3 (or a specified later version) of
+the GNU General Public License (GPL) with the option of using any
+subsequent versions published by the FSF.
+
+"GPL-compatible Software" is software whose conditions of propagation,
+modification and use would permit combination with GCC in accord with
+the license of GCC.
+
+"Target Code" refers to output from any compiler for a real or virtual
+target processor architecture, in executable form or suitable for
+input to an assembler, loader, linker and/or execution
+phase. Notwithstanding that, Target Code does not include data in any
+format that is used as a compiler intermediate representation, or used
+for producing a compiler intermediate representation.
+
+The "Compilation Process" transforms code entirely represented in
+non-intermediate languages designed for human-written code, and/or in
+Java Virtual Machine byte code, into Target Code. Thus, for example,
+use of source code generators and preprocessors need not be considered
+part of the Compilation Process, since the Compilation Process can be
+understood as starting with the output of the generators or
+preprocessors.
+
+A Compilation Process is "Eligible" if it is done using GCC, alone or
+with other GPL-compatible software, or if it is done without using any
+work based on GCC. For example, using non-GPL-compatible Software to
+optimize any GCC intermediate representations would not qualify as an
+Eligible Compilation Process.
+
+1. Grant of Additional Permission.
+
+You have permission to propagate a work of Target Code formed by
+combining the Runtime Library with Independent Modules, even if such
+propagation would otherwise violate the terms of GPLv3, provided that
+all Target Code was generated by Eligible Compilation Processes. You
+may then convey such a combination under terms of your choice,
+consistent with the licensing of the Independent Modules.
+
+2. No Weakening of GCC Copyleft.
+
+The availability of this Exception does not imply any general
+presumption that third-party software is unaffected by the copyleft
+requirements of the license of GCC.
+    

+ Hopefully that text is self-explanatory. If it isn't, you need to speak + to your lawyer, or the Free Software Foundation. +

The Documentation: GPL, FDL

+ The documentation shipped with the library and made available over + the web, excluding the pages generated from source comments, are + copyrighted by the Free Software Foundation, and placed under the + GNU Free Documentation + License version 1.3. There are no Front-Cover Texts, no + Back-Cover Texts, and no Invariant Sections. +

+ For documentation generated by doxygen or other automated tools + via processing source code comments and markup, the original source + code license applies to the generated files. Thus, the doxygen + documents are licensed GPL. +

+ If you plan on making copies of the documentation, please let us know. + We can probably offer suggestions. +

+./gcc-9.2.0/libstdc++-v3/include/pstl/LICENSE.txt +======================================================================== +============================================================================== +The LLVM Project is under the Apache License v2.0 with LLVM Exceptions: +============================================================================== + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +---- LLVM Exceptions to the Apache 2.0 License ---- + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into an Object form of such source code, you +may redistribute such embedded portions in such Object form without complying +with the conditions of Sections 4(a), 4(b) and 4(d) of the License. + +In addition, if you combine or link compiled forms of this Software with +software that is licensed under the GPLv2 ("Combined Software") and if a +court of competent jurisdiction determines that the patent provision (Section +3), the indemnity provision (Section 9) or other Section of the License +conflicts with the conditions of the GPLv2, you may retroactively and +prospectively choose to deem waived or otherwise exclude such Section(s) of +the License, but only in their entirety and only with respect to the Combined +Software. + +============================================================================== +Software from third parties included in the LLVM Project: +============================================================================== +The LLVM Project contains third party software which is under different license +terms. All such code will be identified clearly using at least one of two +mechanisms: +1) It will be in a separate directory tree with its own `LICENSE.txt` or + `LICENSE` file at the top containing the specific license and restrictions + which apply to that software, or +2) It will contain specific license and restriction terms at the top of every + file. + +============================================================================== +Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy): +============================================================================== + +The software contained in this directory tree is dual licensed under both the +University of Illinois "BSD-Like" license and the MIT license. As a user of +this code you may choose to use it under either license. As a contributor, +you agree to allow your code to be used under both. + +Full text of the relevant licenses is included below. + +============================================================================== + +University of Illinois/NCSA +Open Source License + +Copyright (c) 2017-2019 by the contributors listed in CREDITS.TXT + +All rights reserved. + +Developed by: + Threading Runtimes Team + Intel Corporation + http://www.intel.com + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of Intel Corporation Threading Runtimes Team nor the + names of its contributors may be used to endorse or promote products + derived from this Software without specific prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE +SOFTWARE. + +============================================================================== + +Copyright (c) 2017-2019 by the contributors listed in CREDITS.TXT + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +./gcc-9.2.0/zlib/contrib/dotzlib/LICENSE_1_0.txt +======================================================================== +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +./gmp-6.1.2/COPYING +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + +./gmp-6.1.2/COPYING.LESSERv3 +======================================================================== + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + +./gmp-6.1.2/COPYINGv2 +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. + +./gmp-6.1.2/COPYINGv3 +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + +./mpc-1.1.0/COPYING.LESSER +======================================================================== + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + +./mpfr-4.0.2/COPYING +======================================================================== + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + +./mpfr-4.0.2/COPYING.LESSER +======================================================================== + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/third_party/gcc/README.cosmo b/third_party/gcc/README.cosmo new file mode 100644 index 00000000..0b2e7341 --- /dev/null +++ b/third_party/gcc/README.cosmo @@ -0,0 +1,232 @@ +This is a modern statically-linked GNU C2X toolchain. + +You have the freedom to obtain the original sources to these binaries, +and build ones just like them, by visiting: + + https://www.gnu.org/ + https://github.com/richfelker/musl-cross-make + +The musl-cross-make tool also produces libraries and header files. We've +only vendored the statically-linked executable files, since Cosmopolitan +won't depend on GPL-licensed headers / runtime libraries. + +We haven't made any modifications to the original software. The versions +we chose are documented in $PKG/LICENSE.txt. Here's our Musl +build config for maximum transparency: + +commit 38e52db8358c043ae82b346a2e6e66bc86a53bc1 +Author: Rich Felker +Date: Wed Dec 18 14:29:07 2019 -0500 + + switch linux kernel headers to 4.19.88 by default + + using slim headers-only version. this change is needed to support all + future versions of musl on 32-bit archs, since prior to 4.16 the + kernel headers had incompatibility with userspace time_t not matching + the kernel's old (32-bit) time_t. support for older headers will be + dropped entirely soon. + +TARGET = x86_64-linux-musl +OUTPUT = /opt/cross9 +GCC_VER = 9.2.0 +export LANG=en_US.UTF-8 +export LC_CTYPE=en_US.UTF-8 +COMMON_CONFIG += CC="/opt/cross9/bin/x86_64-linux-musl-cc -static --static -g -Os -ftree-vectorize -fvect-cost-model=unlimited -mstringop-strategy=vector_loop -save-temps -fno-ident" +COMMON_CONFIG += CXX="/opt/cross9/bin/x86_64-linux-musl-c++ -static --static -g -Os -ftree-vectorize -fvect-cost-model=unlimited -mstringop-strategy=vector_loop -save-temps -fno-ident" +COMMON_CONFIG += LD="/opt/cross9/bin/x86_64-linux-musl-ld --build-id=none" +COMMON_CONFIG += NM="/opt/cross9/bin/x86_64-linux-musl-nm" +COMMON_CONFIG += LDFLAGS="-Wl,--build-id=none" +COMMON_CONFIG += OBJCOPY="/opt/cross9/bin/x86_64-linux-musl-objcopy" +COMMON_CONFIG += --disable-nls --disable-lto +GCC_CONFIG += --enable-languages=c,c++ +GCC_CONFIG += --disable-multilib +GCC_CONFIG += --with-gnu-as +GCC_CONFIG += --with-gnu-ld +GCC_CONFIG += --disable-multilib +GCC_CONFIG += --enable-sjlj-exceptions +GCC_CONFIG += --disable-threads +GCC_CONFIG += --disable-tls +COMMON_CONFIG += --with-debug-prefix-map=$(CURDIR)= + +#!/bin/sh +set -e +export LC_ALL=C +export GUNZ="/bin/gzip --rsyncable -9 -c" +BASE=/opt/cross9 +PKG=third_party/gcc +VERS=9.2.0 + +if [ ! -d $BASE ]; then + echo error: run make install >&2 + exit 1 +fi + +if [ -d $BASE/$PKG ]; then + rm -rf $BASE/$PKG +fi + +mkdir -p $BASE/$PKG/bin +mkdir -p $BASE/$PKG/libexec/gcc/x86_64-linux-musl/$VERS +mkdir -p $BASE/$PKG/x86_64-linux-musl/bin + +cp $BASE/bin/x86_64-linux-musl-gcov-dump $BASE/$PKG/bin/x86_64-linux-musl-gcov-dump +cp $BASE/bin/x86_64-linux-musl-cc $BASE/$PKG/bin/x86_64-linux-musl-gcc +cp $BASE/bin/x86_64-linux-musl-addr2line $BASE/$PKG/bin/x86_64-linux-musl-addr2line +cp $BASE/bin/x86_64-linux-musl-ar $BASE/$PKG/bin/x86_64-linux-musl-ar +cp $BASE/libexec/gcc/x86_64-linux-musl/9.2.0/cc1plus $BASE/$PKG/libexec/gcc/x86_64-linux-musl/9.2.0/cc1plus +cp $BASE/bin/x86_64-linux-musl-c++ $BASE/$PKG/bin/x86_64-linux-musl-g++ +cp $BASE/libexec/gcc/x86_64-linux-musl/9.2.0/collect2 $BASE/$PKG/libexec/gcc/x86_64-linux-musl/9.2.0/collect2 +cp $BASE/bin/x86_64-linux-musl-gcc-nm $BASE/$PKG/bin/x86_64-linux-musl-gcc-nm +cp $BASE/bin/x86_64-linux-musl-c++filt $BASE/$PKG/bin/x86_64-linux-musl-c++filt +cp $BASE/bin/x86_64-linux-musl-elfedit $BASE/$PKG/bin/x86_64-linux-musl-elfedit +cp $BASE/bin/x86_64-linux-musl-ld $BASE/$PKG/x86_64-linux-musl/bin/ld.bfd +cp $BASE/bin/x86_64-linux-musl-size $BASE/$PKG/bin/x86_64-linux-musl-size +cp $BASE/bin/x86_64-linux-musl-strings $BASE/$PKG/bin/x86_64-linux-musl-strings +cp $BASE/bin/x86_64-linux-musl-objcopy $BASE/$PKG/bin/x86_64-linux-musl-objcopy +cp $BASE/bin/x86_64-linux-musl-nm $BASE/$PKG/bin/x86_64-linux-musl-nm +cp $BASE/libexec/gcc/x86_64-linux-musl/9.2.0/cc1 $BASE/$PKG/libexec/gcc/x86_64-linux-musl/9.2.0/cc1 +cp $BASE/bin/x86_64-linux-musl-readelf $BASE/$PKG/bin/x86_64-linux-musl-readelf +cp $BASE/bin/x86_64-linux-musl-objdump $BASE/$PKG/bin/x86_64-linux-musl-objdump +cp $BASE/bin/x86_64-linux-musl-gcc-ar $BASE/$PKG/bin/x86_64-linux-musl-gcc-ar +cp $BASE/bin/x86_64-linux-musl-gcov $BASE/$PKG/bin/x86_64-linux-musl-gcov +cp $BASE/bin/x86_64-linux-musl-ranlib $BASE/$PKG/bin/x86_64-linux-musl-ranlib +cp $BASE/bin/x86_64-linux-musl-as $BASE/$PKG/bin/x86_64-linux-musl-as +cp $BASE/bin/x86_64-linux-musl-gcc-ranlib $BASE/$PKG/bin/x86_64-linux-musl-gcc-ranlib +cp $BASE/bin/x86_64-linux-musl-cpp $BASE/$PKG/bin/x86_64-linux-musl-cpp +cp $BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-strip +cp $BASE/bin/x86_64-linux-musl-gprof $BASE/$PKG/bin/x86_64-linux-musl-gprof +cp $BASE/bin/x86_64-linux-musl-gcov-tool $BASE/$PKG/bin/x86_64-linux-musl-gcov-tool + +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-gcov-dump +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-gcc +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-addr2line +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-ar +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/libexec/gcc/x86_64-linux-musl/9.2.0/cc1plus +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-g++ +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/libexec/gcc/x86_64-linux-musl/9.2.0/collect2 +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-gcc-nm +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-c++filt +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-elfedit +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/x86_64-linux-musl/bin/ld.bfd +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-size +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-strings +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-objcopy +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-nm +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/libexec/gcc/x86_64-linux-musl/9.2.0/cc1 +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-readelf +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-objdump +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-gcc-ar +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-gcov +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-ranlib +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-as +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-gcc-ranlib +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-cpp +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-strip +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-gprof +$BASE/bin/x86_64-linux-musl-strip $BASE/$PKG/bin/x86_64-linux-musl-gcov-tool + +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-gcov-dump >$BASE/$PKG/bin/x86_64-linux-musl-gcov-dump.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-gcc >$BASE/$PKG/bin/x86_64-linux-musl-gcc.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-addr2line >$BASE/$PKG/bin/x86_64-linux-musl-addr2line.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-ar >$BASE/$PKG/bin/x86_64-linux-musl-ar.gz +$GUNZ $BASE/$PKG/libexec/gcc/x86_64-linux-musl/9.2.0/cc1plus >$BASE/$PKG/libexec/gcc/x86_64-linux-musl/9.2.0/cc1plus.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-g++ >$BASE/$PKG/bin/x86_64-linux-musl-g++.gz +$GUNZ $BASE/$PKG/libexec/gcc/x86_64-linux-musl/9.2.0/collect2 >$BASE/$PKG/libexec/gcc/x86_64-linux-musl/9.2.0/collect2.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-gcc-nm >$BASE/$PKG/bin/x86_64-linux-musl-gcc-nm.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-c++filt >$BASE/$PKG/bin/x86_64-linux-musl-c++filt.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-elfedit >$BASE/$PKG/bin/x86_64-linux-musl-elfedit.gz +$GUNZ $BASE/$PKG/x86_64-linux-musl/bin/ld.bfd >$BASE/$PKG/x86_64-linux-musl/bin/ld.bfd.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-size >$BASE/$PKG/bin/x86_64-linux-musl-size.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-strings >$BASE/$PKG/bin/x86_64-linux-musl-strings.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-objcopy >$BASE/$PKG/bin/x86_64-linux-musl-objcopy.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-nm >$BASE/$PKG/bin/x86_64-linux-musl-nm.gz +$GUNZ $BASE/$PKG/libexec/gcc/x86_64-linux-musl/9.2.0/cc1 >$BASE/$PKG/libexec/gcc/x86_64-linux-musl/9.2.0/cc1.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-readelf >$BASE/$PKG/bin/x86_64-linux-musl-readelf.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-objdump >$BASE/$PKG/bin/x86_64-linux-musl-objdump.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-gcc-ar >$BASE/$PKG/bin/x86_64-linux-musl-gcc-ar.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-gcov >$BASE/$PKG/bin/x86_64-linux-musl-gcov.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-ranlib >$BASE/$PKG/bin/x86_64-linux-musl-ranlib.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-as >$BASE/$PKG/bin/x86_64-linux-musl-as.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-gcc-ranlib >$BASE/$PKG/bin/x86_64-linux-musl-gcc-ranlib.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-cpp >$BASE/$PKG/bin/x86_64-linux-musl-cpp.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-strip >$BASE/$PKG/bin/x86_64-linux-musl-strip.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-gprof >$BASE/$PKG/bin/x86_64-linux-musl-gprof.gz +$GUNZ $BASE/$PKG/bin/x86_64-linux-musl-gcov-tool >$BASE/$PKG/bin/x86_64-linux-musl-gcov-tool.gz + +rm $BASE/$PKG/bin/x86_64-linux-musl-gcov-dump +rm $BASE/$PKG/bin/x86_64-linux-musl-gcc +rm $BASE/$PKG/bin/x86_64-linux-musl-addr2line +rm $BASE/$PKG/bin/x86_64-linux-musl-ar +rm $BASE/$PKG/libexec/gcc/x86_64-linux-musl/9.2.0/cc1plus +rm $BASE/$PKG/bin/x86_64-linux-musl-g++ +rm $BASE/$PKG/libexec/gcc/x86_64-linux-musl/9.2.0/collect2 +rm $BASE/$PKG/bin/x86_64-linux-musl-gcc-nm +rm $BASE/$PKG/bin/x86_64-linux-musl-c++filt +rm $BASE/$PKG/bin/x86_64-linux-musl-elfedit +rm $BASE/$PKG/x86_64-linux-musl/bin/ld.bfd +rm $BASE/$PKG/bin/x86_64-linux-musl-size +rm $BASE/$PKG/bin/x86_64-linux-musl-strings +rm $BASE/$PKG/bin/x86_64-linux-musl-objcopy +rm $BASE/$PKG/bin/x86_64-linux-musl-nm +rm $BASE/$PKG/libexec/gcc/x86_64-linux-musl/9.2.0/cc1 +rm $BASE/$PKG/bin/x86_64-linux-musl-readelf +rm $BASE/$PKG/bin/x86_64-linux-musl-objdump +rm $BASE/$PKG/bin/x86_64-linux-musl-gcc-ar +rm $BASE/$PKG/bin/x86_64-linux-musl-gcov +rm $BASE/$PKG/bin/x86_64-linux-musl-ranlib +rm $BASE/$PKG/bin/x86_64-linux-musl-as +rm $BASE/$PKG/bin/x86_64-linux-musl-gcc-ranlib +rm $BASE/$PKG/bin/x86_64-linux-musl-cpp +rm $BASE/$PKG/bin/x86_64-linux-musl-strip +rm $BASE/$PKG/bin/x86_64-linux-musl-gprof +rm $BASE/$PKG/bin/x86_64-linux-musl-gcov-tool + +ln -s x86_64-linux-musl-gcc $BASE/$PKG/bin/x86_64-linux-musl-cc +ln -s x86_64-linux-musl-gcc $BASE/$PKG/bin/x86_64-linux-musl-gcc-9.2.0 +ln -s ../../bin/x86_64-linux-musl-ar $BASE/$PKG/x86_64-linux-musl/bin/ar +ln -s x86_64-linux-musl-g++ $BASE/$PKG/bin/x86_64-linux-musl-c++ +ln -s ld.bfd $BASE/$PKG/x86_64-linux-musl/bin/ld +ln -s ../x86_64-linux-musl/bin/ld.bfd $BASE/$PKG/bin/x86_64-linux-musl-ld.bfd +ln -s ../x86_64-linux-musl/bin/ld.bfd $BASE/$PKG/bin/x86_64-linux-musl-ld +ln -s ../../bin/x86_64-linux-musl-objcopy $BASE/$PKG/x86_64-linux-musl/bin/objcopy +ln -s ../../bin/x86_64-linux-musl-nm $BASE/$PKG/x86_64-linux-musl/bin/nm +ln -s ../../bin/x86_64-linux-musl-readelf $BASE/$PKG/x86_64-linux-musl/bin/readelf +ln -s ../../bin/x86_64-linux-musl-objdump $BASE/$PKG/x86_64-linux-musl/bin/objdump +ln -s ../../bin/x86_64-linux-musl-ranlib $BASE/$PKG/x86_64-linux-musl/bin/ranlib +ln -s ../../bin/x86_64-linux-musl-as $BASE/$PKG/x86_64-linux-musl/bin/as +ln -s ../../bin/x86_64-linux-musl-strip $BASE/$PKG/x86_64-linux-musl/bin/strip + +{ + cat <<'EOF' +This is a modern statically-linked GNU C2X toolchain. + +You have the freedom to obtain the original sources to these binaries, +and build ones just like them, by visiting: + + https://www.gnu.org/ + https://github.com/richfelker/musl-cross-make + +The musl-cross-make tool also produces libraries and header files. We've +only vendored the statically-linked executable files, since Cosmopolitan +won't depend on GPL-licensed headers / runtime libraries. + +We haven't made any modifications to the original software. The versions +we chose are documented in $PKG/LICENSE.txt. Here's our Musl +build config for maximum transparency: + +EOF + git show --quiet + echo + cat config.mak + echo + cat bundle.sh +} >$BASE/$PKG/README.cosmo + +{ + for f in $(find . -iname \*copying\* -or -iname \*license\* | sort); do + printf '\n' + printf '%s\n' "$f" + printf '========================================================================\n' + cat "$f" + done +} >$BASE/$PKG/LICENSE.txt diff --git a/third_party/gcc/bin/x86_64-linux-musl-addr2line.gz b/third_party/gcc/bin/x86_64-linux-musl-addr2line.gz new file mode 100644 index 00000000..6022f8df Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-addr2line.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-ar.gz b/third_party/gcc/bin/x86_64-linux-musl-ar.gz new file mode 100644 index 00000000..40448bd0 Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-ar.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-as.gz b/third_party/gcc/bin/x86_64-linux-musl-as.gz new file mode 100644 index 00000000..65d3eb1a Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-as.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-c++ b/third_party/gcc/bin/x86_64-linux-musl-c++ new file mode 120000 index 00000000..5311ab2a --- /dev/null +++ b/third_party/gcc/bin/x86_64-linux-musl-c++ @@ -0,0 +1 @@ +x86_64-linux-musl-g++ \ No newline at end of file diff --git a/third_party/gcc/bin/x86_64-linux-musl-c++filt.gz b/third_party/gcc/bin/x86_64-linux-musl-c++filt.gz new file mode 100644 index 00000000..2cd6fdae Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-c++filt.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-cc b/third_party/gcc/bin/x86_64-linux-musl-cc new file mode 120000 index 00000000..d7bd3b20 --- /dev/null +++ b/third_party/gcc/bin/x86_64-linux-musl-cc @@ -0,0 +1 @@ +x86_64-linux-musl-gcc \ No newline at end of file diff --git a/third_party/gcc/bin/x86_64-linux-musl-cpp.gz b/third_party/gcc/bin/x86_64-linux-musl-cpp.gz new file mode 100644 index 00000000..06ad513f Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-cpp.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-elfedit.gz b/third_party/gcc/bin/x86_64-linux-musl-elfedit.gz new file mode 100644 index 00000000..ebbbca3e Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-elfedit.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-g++.gz b/third_party/gcc/bin/x86_64-linux-musl-g++.gz new file mode 100644 index 00000000..c680cf2d Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-g++.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-gcc-9.2.0 b/third_party/gcc/bin/x86_64-linux-musl-gcc-9.2.0 new file mode 120000 index 00000000..d7bd3b20 --- /dev/null +++ b/third_party/gcc/bin/x86_64-linux-musl-gcc-9.2.0 @@ -0,0 +1 @@ +x86_64-linux-musl-gcc \ No newline at end of file diff --git a/third_party/gcc/bin/x86_64-linux-musl-gcc-ar.gz b/third_party/gcc/bin/x86_64-linux-musl-gcc-ar.gz new file mode 100644 index 00000000..c79d4f0b Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-gcc-ar.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-gcc-nm.gz b/third_party/gcc/bin/x86_64-linux-musl-gcc-nm.gz new file mode 100644 index 00000000..5c36e2ae Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-gcc-nm.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-gcc-ranlib.gz b/third_party/gcc/bin/x86_64-linux-musl-gcc-ranlib.gz new file mode 100644 index 00000000..fd0e4bcd Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-gcc-ranlib.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-gcc.gz b/third_party/gcc/bin/x86_64-linux-musl-gcc.gz new file mode 100644 index 00000000..6fd25cdc Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-gcc.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-gcov-dump.gz b/third_party/gcc/bin/x86_64-linux-musl-gcov-dump.gz new file mode 100644 index 00000000..630a8676 Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-gcov-dump.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-gcov-tool.gz b/third_party/gcc/bin/x86_64-linux-musl-gcov-tool.gz new file mode 100644 index 00000000..6411347a Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-gcov-tool.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-gcov.gz b/third_party/gcc/bin/x86_64-linux-musl-gcov.gz new file mode 100644 index 00000000..70dcebdb Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-gcov.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-gprof.gz b/third_party/gcc/bin/x86_64-linux-musl-gprof.gz new file mode 100644 index 00000000..99363407 Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-gprof.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-ld b/third_party/gcc/bin/x86_64-linux-musl-ld new file mode 120000 index 00000000..cf399b99 --- /dev/null +++ b/third_party/gcc/bin/x86_64-linux-musl-ld @@ -0,0 +1 @@ +../x86_64-linux-musl/bin/ld.bfd \ No newline at end of file diff --git a/third_party/gcc/bin/x86_64-linux-musl-ld.bfd b/third_party/gcc/bin/x86_64-linux-musl-ld.bfd new file mode 120000 index 00000000..cf399b99 --- /dev/null +++ b/third_party/gcc/bin/x86_64-linux-musl-ld.bfd @@ -0,0 +1 @@ +../x86_64-linux-musl/bin/ld.bfd \ No newline at end of file diff --git a/third_party/gcc/bin/x86_64-linux-musl-nm.gz b/third_party/gcc/bin/x86_64-linux-musl-nm.gz new file mode 100644 index 00000000..ade64c9b Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-nm.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-objcopy.gz b/third_party/gcc/bin/x86_64-linux-musl-objcopy.gz new file mode 100644 index 00000000..9dfed872 Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-objcopy.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-objdump.gz b/third_party/gcc/bin/x86_64-linux-musl-objdump.gz new file mode 100644 index 00000000..13415520 Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-objdump.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-ranlib.gz b/third_party/gcc/bin/x86_64-linux-musl-ranlib.gz new file mode 100644 index 00000000..39e9e727 Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-ranlib.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-readelf.gz b/third_party/gcc/bin/x86_64-linux-musl-readelf.gz new file mode 100644 index 00000000..4b7db889 Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-readelf.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-size.gz b/third_party/gcc/bin/x86_64-linux-musl-size.gz new file mode 100644 index 00000000..55c3386a Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-size.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-strings.gz b/third_party/gcc/bin/x86_64-linux-musl-strings.gz new file mode 100644 index 00000000..1a77aa76 Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-strings.gz differ diff --git a/third_party/gcc/bin/x86_64-linux-musl-strip.gz b/third_party/gcc/bin/x86_64-linux-musl-strip.gz new file mode 100644 index 00000000..54b42ca0 Binary files /dev/null and b/third_party/gcc/bin/x86_64-linux-musl-strip.gz differ diff --git a/third_party/gcc/lib/gcc/x86_64-linux-musl/9.2.0/specs b/third_party/gcc/lib/gcc/x86_64-linux-musl/9.2.0/specs new file mode 100644 index 00000000..ae7116a0 --- /dev/null +++ b/third_party/gcc/lib/gcc/x86_64-linux-musl/9.2.0/specs @@ -0,0 +1,141 @@ +*asm: +%{m16|m32:--32} %{m16|m32:;:--64} %{msse2avx:%{!mavx:-msse2avx}} + +*asm_debug: +%{%:debug-level-gt(0):%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}}} %{fdebug-prefix-map=*:--debug-prefix-map %*} + +*asm_final: +%{gsplit-dwarf: + objcopy --extract-dwo %{c:%{o*:%*}%{!o*:%b%O}}%{!c:%U%O} %{c:%{o*:%:replace-extension(%{o*:%*} .dwo)}%{!o*:%b.dwo}}%{!c:%b.dwo} + objcopy --strip-dwo %{c:%{o*:%*}%{!o*:%b%O}}%{!c:%U%O} } + +*asm_options: +%{-target-help:%:print-asm-header()} %{v} %{w:-W} %{I*} %{gz|gz=zlib:--compress-debug-sections=zlib} %{gz=none:--compress-debug-sections=none} %{gz=zlib-gnu:--compress-debug-sections=zlib-gnu} %a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O} + +*invoke_as: +%{!fwpa*: %{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()} %{!S:-o %|.s | + as %(asm_options) %m.s %A } } + +*cpp: +%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT} + +*cpp_options: +%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w} %{f*} %{g*:%{%:debug-level-gt(0):%{g*} %{!fno-working-directory:-fworking-directory}}} %{O*} %{undef} %{save-temps*:-fpch-preprocess} + +*cpp_debug_options: +%{d*} + +*cpp_unique_options: +%{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %@{I*&F*} %{P} %I %{MD:-MD %{!o:%b.d}%{o*:%.d%*}} %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}} %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*} %{!E:%{!M:%{!MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}} %{remap} %{g3|ggdb3|gstabs3|gxcoff3|gvms3:-dD} %{!iplugindir*:%{fplugin*:%:find-plugindir()}} %{H} %C %{D*&U*&A*} %{i*} %Z %i %{E|M|MM:%W{o*}} + +*trad_capable_cpp: +cc1 -E %{traditional|traditional-cpp:-traditional-cpp} + +*cc1: +%{!mandroid|tno-android-cc:%(cc1_cpu) %{profile:-p};:%(cc1_cpu) %{profile:-p} %{!fno-pic:%{!fno-PIC:%{!fpic:%{!fPIC: -fPIC}}}}} + +*cc1_options: +%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}} %{!iplugindir*:%{fplugin*:%:find-plugindir()}} %1 %{!Q:-quiet} %{!dumpbase:-dumpbase %B} %{d*} %{m*} %{aux-info*} %{fcompare-debug-second:%:compare-debug-auxbase-opt(%b)} %{!fcompare-debug-second:%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}}%{!c:%{!S:-auxbase %b}} %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs} %{v:-version} %{pg:-p} %{p} %{f*} %{undef} %{Qn:-fno-ident} %{Qy:} %{-help:--help} %{-target-help:--target-help} %{-version:--version} %{-help=*:--help=%*} %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}} %{fsyntax-only:-o %j} %{-param*} %{coverage:-fprofile-arcs -ftest-coverage} %{fprofile-arcs|fprofile-generate*|coverage: %{!fprofile-update=single: %{pthread:-fprofile-update=prefer-atomic}}} + +*cc1plus: + + +*link_gcc_c_sequence: +%{static|static-pie:--start-group} %G %{!nolibc:%L} %{static|static-pie:--end-group}%{!static:%{!static-pie:%G}} + +*link_ssp: +%{fstack-protector|fstack-protector-all|fstack-protector-strong|fstack-protector-explicit:-lssp_nonshared} + +*endfile: +--push-state --pop-state + +*link: +%{!mandroid|tno-android-ld:%{m16|m32:;:-m elf_x86_64} %{m16|m32:-m elf_i386} %{shared:-shared} %{!shared: %{!static: %{!static-pie: %{rdynamic:-export-dynamic} }} %{static:-static} %{static-pie:-static -pie --no-dynamic-linker -z text}};:%{m16|m32:;:-m elf_x86_64} %{m16|m32:-m elf_i386} %{mx32:-m elf32_x86_64} %{shared:-shared} %{!shared: %{!static: %{!static-pie: %{rdynamic:-export-dynamic} %{m16|m32:-dynamic-linker } %{m16|m32:;:-dynamic-linker} }} %{static:-static} %{static-pie:-static -pie --no-dynamic-linker -z text}} %{shared: -Bsymbolic}} + +*lib: +--push-state --pop-state + +*link_gomp: + + +*libgcc: +--push-state --pop-state + +*startfile: +--push-state --pop-state + +*cross_compile: +1 + +*version: +9.2.0 + +*multilib: +. ; + +*multilib_defaults: +m64 + +*multilib_extra: + + +*multilib_matches: + + +*multilib_exclusions: + + +*multilib_options: + + +*multilib_reuse: + + +*linker: +collect2 + +*linker_plugin_file: + + +*lto_wrapper: + + +*lto_gcc: + + +*post_link: + + +*link_libgcc: +%D + +*md_exec_prefix: + + +*md_startfile_prefix: + + +*md_startfile_prefix_1: + + +*startfile_prefix_spec: + + +*sysroot_spec: +--sysroot=%R + +*sysroot_suffix_spec: + + +*sysroot_hdrs_suffix_spec: + + +*self_spec: + + +*cc1_cpu: +%{march=native:%>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)} + +*link_command: +%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S: %(linker) %{fuse-linker-plugin: %e-fuse-linker-plugin is not supported in this configuration}%{flto|flto=*:% + + e̲x̲t̲e̲r̲n̲ c̲h̲a̲r̲ *̲o̲p̲t̲a̲r̲g̲;̲ + e̲x̲t̲e̲r̲n̲ i̲n̲t̲ o̲p̲t̲e̲r̲r̲;̲ + e̲x̲t̲e̲r̲n̲ i̲n̲t̲ o̲p̲t̲i̲n̲d̲;̲ + e̲x̲t̲e̲r̲n̲ i̲n̲t̲ o̲p̲t̲o̲p̲t̲;̲ + e̲x̲t̲e̲r̲n̲ i̲n̲t̲ o̲p̲t̲r̲e̲s̲e̲t̲;̲ + + i̲n̲t̲ + 𝗴𝗲𝘁𝗼𝗽𝘁(i̲n̲t̲ a̲r̲g̲c̲, c̲h̲a̲r̲ *̲ c̲o̲n̲s̲t̲ *̲a̲r̲g̲v̲, c̲o̲n̲s̲t̲ c̲h̲a̲r̲ *̲o̲p̲t̲s̲t̲r̲i̲n̲g̲); + +𝐃𝐄𝐒𝐂𝐑𝐈𝐏𝐓𝐈𝐎𝐍 + The 𝗴𝗲𝘁𝗼𝗽𝘁() function incrementally parses a command line argument + list a̲r̲g̲v̲ and returns the next k̲n̲o̲w̲n̲ option character. An option + character is k̲n̲o̲w̲n̲ if it has been specified in the string of + accepted option characters, o̲p̲t̲s̲t̲r̲i̲n̲g̲. + + The option string o̲p̲t̲s̲t̲r̲i̲n̲g̲ may contain the following elements: + individual characters, characters followed by a colon, and charac‐ + ters followed by two colons. A character followed by a single + colon indicates that an argument is to follow the option on the + command line. Two colons indicates that the argument is optional - + this is an extension not covered by POSIX. For example, an option + string "x" recognizes an option -𝘅, and an option string "x:" rec‐ + ognizes an option and argument -𝘅 a̲r̲g̲u̲m̲e̲n̲t̲. It does not matter to + 𝗴𝗲𝘁𝗼𝗽𝘁() if a following argument has leading whitespace; except in + the case where the argument is optional, denoted with two colons, + no leading whitespace is permitted. + + On return from 𝗴𝗲𝘁𝗼𝗽𝘁(), o̲p̲t̲a̲r̲g̲ points to an option argument, if it + is anticipated, and the variable o̲p̲t̲i̲n̲d̲ contains the index to the + next a̲r̲g̲v̲ argument for a subsequent call to 𝗴𝗲𝘁𝗼𝗽𝘁(). + + The variables o̲p̲t̲e̲r̲r̲ and o̲p̲t̲i̲n̲d̲ are both initialized to 1. The + o̲p̲t̲i̲n̲d̲ variable may be set to another value larger than 0 before a + set of calls to 𝗴𝗲𝘁𝗼𝗽𝘁() in order to skip over more or less a̲r̲g̲v̲ + entries. An o̲p̲t̲i̲n̲d̲ value of 0 is reserved for compatibility with + GNU 𝗴𝗲𝘁𝗼𝗽𝘁(). + + In order to use 𝗴𝗲𝘁𝗼𝗽𝘁() to evaluate multiple sets of arguments, or + to evaluate a single set of arguments multiple times, the variable + o̲p̲t̲r̲e̲s̲e̲t̲ must be set to 1 before the second and each additional set + of calls to 𝗴𝗲𝘁𝗼𝗽𝘁(), and the variable o̲p̲t̲i̲n̲d̲ must be reinitial‐ + ized. + + The 𝗴𝗲𝘁𝗼𝗽𝘁() function returns -1 when the argument list is + exhausted. The interpretation of options in the argument list may + be cancelled by the option ‘--’ (double dash) which causes 𝗴𝗲𝘁𝗼𝗽𝘁() + to signal the end of argument processing and return -1. When all + options have been processed (i.e., up to the first non-option argu‐ + ment), 𝗴𝗲𝘁𝗼𝗽𝘁() returns -1. + +𝐑𝐄𝐓𝐔𝐑𝐍 𝐕𝐀𝐋𝐔𝐄𝐒 + The 𝗴𝗲𝘁𝗼𝗽𝘁() function returns the next known option character in + o̲p̲t̲s̲t̲r̲i̲n̲g̲. If 𝗴𝗲𝘁𝗼𝗽𝘁() encounters a character not found in + o̲p̲t̲s̲t̲r̲i̲n̲g̲ or if it detects a missing option argument, it returns + ‘?’ (question mark). If o̲p̲t̲s̲t̲r̲i̲n̲g̲ has a leading ‘:’ then a missing + option argument causes ‘:’ to be returned instead of ‘?’. In + either case, the variable o̲p̲t̲o̲p̲t̲ is set to the character that + caused the error. The 𝗴𝗲𝘁𝗼𝗽𝘁() function returns -1 when the argu‐ + ment list is exhausted. + +𝐄𝐗𝐀𝐌𝐏𝐋𝐄𝐒 + The following code accepts the options -𝗯 and -𝗳 a̲r̲g̲u̲m̲e̲n̲t̲ and + adjusts a̲r̲g̲c̲ and a̲r̲g̲v̲ after option argument processing has com‐ + pleted. + + int bflag, ch, fd; + + bflag = 0; + while ((ch = getopt(argc, argv, "bf:")) != -1) { + switch (ch) { + case 'b': + bflag = 1; + break; + case 'f': + if ((fd = open(optarg, O_RDONLY, 0)) == -1) + err(1, "%s", optarg); + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + +𝐃𝐈𝐀𝐆𝐍𝐎𝐒𝐓𝐈𝐂𝐒 + If the 𝗴𝗲𝘁𝗼𝗽𝘁() function encounters a character not found in the + string o̲p̲t̲s̲t̲r̲i̲n̲g̲ or detects a missing option argument, it writes an + error message to s̲t̲d̲e̲r̲r̲ and returns ‘?’. Setting o̲p̲t̲e̲r̲r̲ to a zero + will disable these error messages. If o̲p̲t̲s̲t̲r̲i̲n̲g̲ has a leading ‘:’ + then a missing option argument causes a ‘:’ to be returned in addi‐ + tion to suppressing any error messages. + + Option arguments are allowed to begin with ‘-’; this is reasonable + but reduces the amount of error checking possible. + +𝐒𝐄𝐄 𝐀𝐋𝐒𝐎 + getopt(1), getopt_long(3), getsubopt(3) + +𝐒𝐓𝐀𝐍𝐃𝐀𝐑𝐃𝐒 + The 𝗴𝗲𝘁𝗼𝗽𝘁() function implements a superset of the functionality + specified by IEEE Std 1003.1 (“POSIX.1”). + + The following extensions are supported: + + · The o̲p̲t̲r̲e̲s̲e̲t̲ variable was added to make it possible to call the + 𝗴𝗲𝘁𝗼𝗽𝘁() function multiple times. + + · If the o̲p̲t̲i̲n̲d̲ variable is set to 0, 𝗴𝗲𝘁𝗼𝗽𝘁() will behave as if + the o̲p̲t̲r̲e̲s̲e̲t̲ variable has been set. This is for compatibility + with GNU 𝗴𝗲𝘁𝗼𝗽𝘁(). New code should use o̲p̲t̲r̲e̲s̲e̲t̲ instead. + + · If the first character of o̲p̲t̲s̲t̲r̲i̲n̲g̲ is a plus sign (‘+’), it + will be ignored. This is for compatibility with GNU 𝗴𝗲𝘁𝗼𝗽𝘁(). + + · If the first character of o̲p̲t̲s̲t̲r̲i̲n̲g̲ is a dash (‘-’), non- + options will be returned as arguments to the option character + ‘\1’. This is for compatibility with GNU 𝗴𝗲𝘁𝗼𝗽𝘁(). + + · A single dash (‘-’) may be specified as a character in + o̲p̲t̲s̲t̲r̲i̲n̲g̲, however it should n̲e̲v̲e̲r̲ have an argument associated + with it. This allows 𝗴𝗲𝘁𝗼𝗽𝘁() to be used with programs that + expect ‘-’ as an option flag. This practice is wrong, and + should not be used in any current development. It is provided + for backward compatibility o̲n̲l̲y̲. Care should be taken not to + use ‘-’ as the first character in o̲p̲t̲s̲t̲r̲i̲n̲g̲ to avoid a semantic + conflict with GNU 𝗴𝗲𝘁𝗼𝗽𝘁() semantics (see above). By default, + a single dash causes 𝗴𝗲𝘁𝗼𝗽𝘁() to return -1. + + Historic BSD versions of 𝗴𝗲𝘁𝗼𝗽𝘁() set o̲p̲t̲o̲p̲t̲ to the last option + character processed. However, this conflicts with IEEE Std 1003.1 + (“POSIX.1”) which stipulates that o̲p̲t̲o̲p̲t̲ be set to the last charac‐ + ter that caused an error. + +𝐇𝐈𝐒𝐓𝐎𝐑𝐘 + The 𝗴𝗲𝘁𝗼𝗽𝘁() function appeared in 4.3BSD. + +𝐁𝐔𝐆𝐒 + The 𝗴𝗲𝘁𝗼𝗽𝘁() function was once specified to return EOF instead of + -1. This was changed by IEEE Std 1003.2-1992 (“POSIX.2”) to decou‐ + ple 𝗴𝗲𝘁𝗼𝗽𝘁() from . + + It is possible to handle digits as option letters. This allows + 𝗴𝗲𝘁𝗼𝗽𝘁() to be used with programs that expect a number (“-3”) as an + option. This practice is wrong, and should not be used in any cur‐ + rent development. It is provided for backward compatibility o̲n̲l̲y̲. + The following code fragment works in most cases and can handle + mixed number and letter arguments. + + int aflag = 0, bflag = 0, ch, lastch = '\0'; + int length = -1, newarg = 1, prevoptind = 1; + + while ((ch = getopt(argc, argv, "0123456789ab")) != -1) { + switch (ch) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (newarg || !isdigit(lastch)) + length = 0; + else if (length > INT_MAX / 10) + usage(); + length = (length * 10) + (ch - '0'); + break; + case 'a': + aflag = 1; + break; + case 'b': + bflag = 1; + break; + default: + usage(); + } + lastch = ch; + newarg = optind != prevoptind; + prevoptind = optind; + } + +COSMOPOLITAN January 4, 2016 BSD + + ──────────────────────────────────────────────────────────────────────────── + +GETOPT_LONG(3) Cosmopolitan Library Functions Manual GETOPT_LONG(3) + +𝐍𝐀𝐌𝐄 + 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴, 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴_𝗼𝗻𝗹𝘆 — get long options from command line + argument list + +𝐒𝐘𝐍𝐎𝐏𝐒𝐈𝐒 + #𝗶𝗻𝗰𝗹𝘂𝗱𝗲 <𝗴𝗲𝘁𝗼𝗽𝘁.𝗵> + + e̲x̲t̲e̲r̲n̲ c̲h̲a̲r̲ *̲o̲p̲t̲a̲r̲g̲;̲ + e̲x̲t̲e̲r̲n̲ i̲n̲t̲ o̲p̲t̲i̲n̲d̲;̲ + e̲x̲t̲e̲r̲n̲ i̲n̲t̲ o̲p̲t̲o̲p̲t̲;̲ + e̲x̲t̲e̲r̲n̲ i̲n̲t̲ o̲p̲t̲e̲r̲r̲;̲ + e̲x̲t̲e̲r̲n̲ i̲n̲t̲ o̲p̲t̲r̲e̲s̲e̲t̲;̲ + + i̲n̲t̲ + 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴(i̲n̲t̲ a̲r̲g̲c̲, c̲h̲a̲r̲ *̲ c̲o̲n̲s̲t̲ *̲a̲r̲g̲v̲, c̲o̲n̲s̲t̲ c̲h̲a̲r̲ *̲o̲p̲t̲s̲t̲r̲i̲n̲g̲, + c̲o̲n̲s̲t̲ s̲t̲r̲u̲c̲t̲ o̲p̲t̲i̲o̲n̲ *̲l̲o̲n̲g̲o̲p̲t̲s̲, i̲n̲t̲ *̲l̲o̲n̲g̲i̲n̲d̲e̲x̲); + + i̲n̲t̲ + 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴_𝗼𝗻𝗹𝘆(i̲n̲t̲ a̲r̲g̲c̲, c̲h̲a̲r̲ *̲ c̲o̲n̲s̲t̲ *̲a̲r̲g̲v̲, + c̲o̲n̲s̲t̲ c̲h̲a̲r̲ *̲o̲p̲t̲s̲t̲r̲i̲n̲g̲, c̲o̲n̲s̲t̲ s̲t̲r̲u̲c̲t̲ o̲p̲t̲i̲o̲n̲ *̲l̲o̲n̲g̲o̲p̲t̲s̲, + i̲n̲t̲ *̲l̲o̲n̲g̲i̲n̲d̲e̲x̲); + +𝐃𝐄𝐒𝐂𝐑𝐈𝐏𝐓𝐈𝐎𝐍 + The 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴() function is similar to getopt(3) but it accepts + options in two forms: words and characters. The 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴() + function provides a superset of the functionality of getopt(3). + 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴() can be used in two ways. In the first way, every + long option understood by the program has a corresponding short + option, and the option structure is only used to translate from + long options to short options. When used in this fashion, + 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴() behaves identically to getopt(3). This is a good way + to add long option processing to an existing program with the mini‐ + mum of rewriting. + + In the second mechanism, a long option sets a flag in the o̲p̲t̲i̲o̲n̲ + structure passed, or will store a pointer to the command line argu‐ + ment in the o̲p̲t̲i̲o̲n̲ structure passed to it for options that take + arguments. Additionally, the long option's argument may be speci‐ + fied as a single argument with an equal sign, e.g. + + $ myprogram --myoption=somevalue + + When a long option is processed, the call to 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴() will + return 0. For this reason, long option processing without short‐ + cuts is not backwards compatible with getopt(3). + + It is possible to combine these methods, providing for long options + processing with short option equivalents for some options. Less + frequently used options would be processed as long options only. + + Abbreviated long option names are accepted when 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴() pro‐ + cesses long options if the abbreviation is unique. An exact match + is always preferred for a defined long option. + + The 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴() call requires an array to be initialized describ‐ + ing the long options. Each element of the array is a structure: + + struct option { + char *name; + int has_arg; + int *flag; + int val; + }; + + The n̲a̲m̲e̲ field should contain the option name without the leading + double dash. + + The h̲a̲s̲_a̲r̲g̲ field should be one of: + + no_argument no argument to the option is expected. + required_argument an argument to the option is required. + optional_argument an argument to the option may be pre‐ + sented. + + If f̲l̲a̲g̲ is not NULL, then the integer pointed to by it will be set + to the value in the v̲a̲l̲ field. If the f̲l̲a̲g̲ field is NULL, then the + v̲a̲l̲ field will be returned. Setting f̲l̲a̲g̲ to NULL and setting v̲a̲l̲ + to the corresponding short option will make this function act just + like getopt(3). + + If the l̲o̲n̲g̲i̲n̲d̲e̲x̲ field is not NULL, then the integer pointed to by + it will be set to the index of the long option relative to + l̲o̲n̲g̲o̲p̲t̲s̲. + + The last element of the l̲o̲n̲g̲o̲p̲t̲s̲ array has to be filled with + zeroes. + + The 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴_𝗼𝗻𝗹𝘆() function behaves identically to + 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴() with the exception that long options may start with + ‘-’ in addition to ‘--’. If an option starting with ‘-’ does not + match a long option but does match a single-character option, the + single-character option is returned. + +𝐑𝐄𝐓𝐔𝐑𝐍 𝐕𝐀𝐋𝐔𝐄𝐒 + If the f̲l̲a̲g̲ field in struct option is NULL, 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴() and + 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴_𝗼𝗻𝗹𝘆() return the value specified in the v̲a̲l̲ field, + which is usually just the corresponding short option. If f̲l̲a̲g̲ is + not NULL, these functions return 0 and store v̲a̲l̲ in the location + pointed to by f̲l̲a̲g̲. These functions return ‘:’ if there was a + missing option argument, ‘?’ if the user specified an unknown or + ambiguous option, and -1 when the argument list has been exhausted. + +𝐈𝐌𝐏𝐋𝐄𝐌𝐄𝐍𝐓𝐀𝐓𝐈𝐎𝐍 𝐃𝐈𝐅𝐅𝐄𝐑𝐄𝐍𝐂𝐄𝐒 + This section describes differences to the GNU implementation found + in glibc-2.1.3: + + · handling of ‘-’ within the option string (not the first charac‐ + ter): + + GNU treats a ‘-’ on the command line as a non-argument. + + OpenBSD a ‘-’ within the option string matches a ‘-’ (single + dash) on the command line. This functionality is pro‐ + vided for backward compatibility with programs, such + as su(1), that use ‘-’ as an option flag. This prac‐ + tice is wrong, and should not be used in any current + development. + + · handling of ‘::’ in the option string in the presence of + POSIXLY_CORRECT: + + Both GNU and OpenBSD ignore POSIXLY_CORRECT here and take + ‘::’ to mean the preceding option takes an optional + argument. + + · return value in case of missing argument if first character + (after ‘+’ or ‘-’) in the option string is not ‘:’: + + GNU returns ‘?’ + + OpenBSD returns ‘:’ (since OpenBSD's getopt(3) does). + + · handling of ‘--a’ in getopt(3): + + GNU parses this as option ‘-’, option ‘a’. + + OpenBSD parses this as ‘--’, and returns -1 (ignoring the ‘a’) + (because the original 𝗴𝗲𝘁𝗼𝗽𝘁() did.) + + · setting of o̲p̲t̲o̲p̲t̲ for long options with f̲l̲a̲g̲ non-NULL: + + GNU sets o̲p̲t̲o̲p̲t̲ to v̲a̲l̲. + + OpenBSD sets o̲p̲t̲o̲p̲t̲ to 0 (since v̲a̲l̲ would never be returned). + + · handling of ‘-W’ with ‘W;’ in the option string in getopt(3) + (not 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴()): + + GNU causes a segmentation fault. + + OpenBSD no special handling is done; ‘W;’ is interpreted as + two separate options, neither of which take an argu‐ + ment. + + · setting of o̲p̲t̲a̲r̲g̲ for long options without an argument that are + invoked via ‘-W’ (with ‘W;’ in the option string): + + GNU sets o̲p̲t̲a̲r̲g̲ to the option name (the argument of ‘-W’). + + OpenBSD sets o̲p̲t̲a̲r̲g̲ to NULL (the argument of the long option). + + · handling of ‘-W’ with an argument that is not (a prefix to) a + known long option (with ‘W;’ in the option string): + + GNU returns ‘-W’ with o̲p̲t̲a̲r̲g̲ set to the unknown option. + + OpenBSD treats this as an error (unknown option) and returns + ‘?’ with o̲p̲t̲o̲p̲t̲ set to 0 and o̲p̲t̲a̲r̲g̲ set to NULL (as + GNU's man page documents). + + · The error messages are different. + + · OpenBSD does not permute the argument vector at the same points + in the calling sequence as GNU does. The aspects normally used + by the caller (ordering after -1 is returned, value of o̲p̲t̲i̲n̲d̲ + relative to current positions) are the same, though. (We do + fewer variable swaps.) + +𝐄𝐍𝐕𝐈𝐑𝐎𝐍𝐌𝐄𝐍𝐓 + POSIXLY_CORRECT If set, option processing stops when the first + non-option is found and a leading ‘+’ in the + o̲p̲t̲s̲t̲r̲i̲n̲g̲ is ignored. + +𝐄𝐗𝐀𝐌𝐏𝐋𝐄𝐒 + int bflag, ch, fd; + int daggerset; + + /* options descriptor */ + static struct option longopts[] = { + { "buffy", no_argument, NULL, 'b' }, + { "fluoride", required_argument, NULL, 'f' }, + { "daggerset", no_argument, &daggerset, 1 }, + { NULL, 0, NULL, 0 } + }; + + bflag = 0; + while ((ch = getopt_long(argc, argv, "bf:", longopts, NULL)) != -1) + switch (ch) { + case 'b': + bflag = 1; + break; + case 'f': + if ((fd = open(optarg, O_RDONLY, 0)) == -1) + err(1, "unable to open %s", optarg); + break; + case 0: + if (daggerset) + fprintf(stderr, "Buffy will use her dagger to " + "apply fluoride to dracula's teeth\n"); + break; + default: + usage(); + } + argc -= optind; + argv += optind; + +𝐒𝐄𝐄 𝐀𝐋𝐒𝐎 + getopt(3) + +𝐇𝐈𝐒𝐓𝐎𝐑𝐘 + The 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴() and 𝗴𝗲𝘁𝗼𝗽𝘁_𝗹𝗼𝗻𝗴_𝗼𝗻𝗹𝘆() functions first appeared + in GNU libiberty. This implementation first appeared in + OpenBSD 3.3. + +𝐁𝐔𝐆𝐒 + The a̲r̲g̲v̲ argument is not really const as its elements may be per‐ + muted (unless POSIXLY_CORRECT is set). + +COSMOPOLITAN January 4, 2016 BSD diff --git a/third_party/getopt/getopt.3 b/third_party/getopt/getopt.3 new file mode 100644 index 00000000..af43ca66 --- /dev/null +++ b/third_party/getopt/getopt.3 @@ -0,0 +1,363 @@ +.\" Copyright (c) 1988, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $OpenBSD: getopt.3,v 1.46 2016/01/04 19:43:13 tb Exp $ +.\" +.Dd $Mdocdate: January 4 2016 $ +.Dt GETOPT 3 +.Os +.Sh NAME +.Nm getopt +.Nd get option character from command line argument list +.Sh SYNOPSIS +.In unistd.h +.Vt extern char *optarg; +.Vt extern int opterr; +.Vt extern int optind; +.Vt extern int optopt; +.Vt extern int optreset; +.Ft int +.Fn getopt "int argc" "char * const *argv" "const char *optstring" +.Sh DESCRIPTION +The +.Fn getopt +function incrementally parses a command line argument list +.Fa argv +and returns the next +.Em known +option character. +An option character is +.Em known +if it has been specified in the string of accepted option characters, +.Fa optstring . +.Pp +The option string +.Fa optstring +may contain the following elements: individual characters, +characters followed by a colon, and characters followed by two colons. +A character followed by a single colon indicates that an argument +is to follow the option on the command line. +Two colons indicates that the argument is optional \- this is an +extension not covered by POSIX. +For example, an option string +.Qq x +recognizes an option +.Fl x , +and an option string +.Qq Li x: +recognizes an option and argument +.Fl x Ar argument . +It does not matter to +.Fn getopt +if a following argument has leading whitespace; except in the case where +the argument is optional, denoted with two colons, no leading whitespace +is permitted. +.Pp +On return from +.Fn getopt , +.Va optarg +points to an option argument, if it is anticipated, +and the variable +.Va optind +contains the index to the next +.Fa argv +argument for a subsequent call +to +.Fn getopt . +.Pp +The variables +.Va opterr +and +.Va optind +are both initialized to 1. +The +.Va optind +variable may be set to another value larger than 0 before a set of calls to +.Fn getopt +in order to skip over more or less +.Fa argv +entries. +An +.Va optind +value of 0 is reserved for compatibility with GNU +.Fn getopt . +.Pp +In order to use +.Fn getopt +to evaluate multiple sets of arguments, or to evaluate a single set of +arguments multiple times, +the variable +.Va optreset +must be set to 1 before the second and each additional set of calls to +.Fn getopt , +and the variable +.Va optind +must be reinitialized. +.Pp +The +.Fn getopt +function returns \-1 when the argument list is exhausted. +The interpretation of options in the argument list may be cancelled +by the option +.Ql -- +(double dash) which causes +.Fn getopt +to signal the end of argument processing and return \-1. +When all options have been processed (i.e., up to the first non-option +argument), +.Fn getopt +returns \-1. +.Sh RETURN VALUES +The +.Fn getopt +function returns the next known option character in +.Fa optstring . +If +.Fn getopt +encounters a character not found in +.Fa optstring +or if it detects a missing option argument, +it returns +.Sq \&? +(question mark). +If +.Fa optstring +has a leading +.Sq \&: +then a missing option argument causes +.Sq \&: +to be returned instead of +.Sq \&? . +In either case, the variable +.Va optopt +is set to the character that caused the error. +The +.Fn getopt +function returns \-1 when the argument list is exhausted. +.Sh EXAMPLES +The following code accepts the options +.Fl b +and +.Fl f Ar argument +and adjusts +.Va argc +and +.Va argv +after option argument processing has completed. +.Bd -literal -offset indent +int bflag, ch, fd; + +bflag = 0; +while ((ch = getopt(argc, argv, "bf:")) != -1) { + switch (ch) { + case 'b': + bflag = 1; + break; + case 'f': + if ((fd = open(optarg, O_RDONLY, 0)) == -1) + err(1, "%s", optarg); + break; + default: + usage(); + } +} +argc -= optind; +argv += optind; +.Ed +.Sh DIAGNOSTICS +If the +.Fn getopt +function encounters a character not found in the string +.Fa optstring +or detects +a missing option argument, it writes an error message to +.Em stderr +and returns +.Ql \&? . +Setting +.Va opterr +to a zero will disable these error messages. +If +.Fa optstring +has a leading +.Ql \&: +then a missing option argument causes a +.Ql \&: +to be returned in addition to suppressing any error messages. +.Pp +Option arguments are allowed to begin with +.Ql - ; +this is reasonable but reduces the amount of error checking possible. +.Sh SEE ALSO +.Xr getopt 1 , +.Xr getopt_long 3 , +.Xr getsubopt 3 +.Sh STANDARDS +The +.Fn getopt +function implements a superset of the functionality specified by +.St -p1003.1 . +.Pp +The following extensions are supported: +.Bl -bullet +.It +The +.Va optreset +variable was added to make it possible to call the +.Fn getopt +function multiple times. +.It +If the +.Va optind +variable is set to 0, +.Fn getopt +will behave as if the +.Va optreset +variable has been set. +This is for compatibility with +.Tn GNU +.Fn getopt . +New code should use +.Va optreset +instead. +.It +If the first character of +.Fa optstring +is a plus sign +.Pq Ql + , +it will be ignored. +This is for compatibility with +.Tn GNU +.Fn getopt . +.It +If the first character of +.Fa optstring +is a dash +.Pq Ql - , +non-options will be returned as arguments to the option character +.Ql \e1 . +This is for compatibility with +.Tn GNU +.Fn getopt . +.It +A single dash +.Pq Ql - +may be specified as a character in +.Fa optstring , +however it should +.Em never +have an argument associated with it. +This allows +.Fn getopt +to be used with programs that expect +.Ql - +as an option flag. +This practice is wrong, and should not be used in any current development. +It is provided for backward compatibility +.Em only . +Care should be taken not to use +.Ql - +as the first character in +.Fa optstring +to avoid a semantic conflict with +.Tn GNU +.Fn getopt +semantics (see above). +By default, a single dash causes +.Fn getopt +to return \-1. +.El +.Pp +Historic +.Bx +versions of +.Fn getopt +set +.Fa optopt +to the last option character processed. +However, this conflicts with +.St -p1003.1 +which stipulates that +.Fa optopt +be set to the last character that caused an error. +.Sh HISTORY +The +.Fn getopt +function appeared in +.Bx 4.3 . +.Sh BUGS +The +.Fn getopt +function was once specified to return +.Dv EOF +instead of \-1. +This was changed by +.St -p1003.2-92 +to decouple +.Fn getopt +from +.In stdio.h . +.Pp +It is possible to handle digits as option letters. +This allows +.Fn getopt +to be used with programs that expect a number +.Pq Dq Li \-3 +as an option. +This practice is wrong, and should not be used in any current development. +It is provided for backward compatibility +.Em only . +The following code fragment works in most cases and can handle mixed +number and letter arguments. +.Bd -literal -offset indent +int aflag = 0, bflag = 0, ch, lastch = '\e0'; +int length = -1, newarg = 1, prevoptind = 1; + +while ((ch = getopt(argc, argv, "0123456789ab")) != -1) { + switch (ch) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (newarg || !isdigit(lastch)) + length = 0; + else if (length > INT_MAX / 10) + usage(); + length = (length * 10) + (ch - '0'); + break; + case 'a': + aflag = 1; + break; + case 'b': + bflag = 1; + break; + default: + usage(); + } + lastch = ch; + newarg = optind != prevoptind; + prevoptind = optind; +} +.Ed diff --git a/third_party/getopt/getopt.c b/third_party/getopt/getopt.c new file mode 100644 index 00000000..c713c2a6 --- /dev/null +++ b/third_party/getopt/getopt.c @@ -0,0 +1,145 @@ +asm(".ident\t\"\\n\\n\ +getopt (BSD-3)\\n\ +Copyright 1987, 1993, 1994 The Regents of the University of California\""); +asm(".include \"libc/disclaimer.inc\""); + +/* clang-format off */ +/* $NetBSD: getopt.c,v 1.26 2003/08/07 16:43:40 agc Exp $ */ + +/* + * Copyright (c) 1987, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)getopt.c 8.3 (Berkeley) 4/27/95 + * $FreeBSD: src/lib/libc/stdlib/getopt.c,v 1.8 2007/01/09 00:28:10 imp Exp $ + * $DragonFly: src/lib/libc/stdlib/getopt.c,v 1.7 2005/11/20 12:37:48 swildner Exp $ + */ + +#include "libc/str/str.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" + +int opterr, /* if error message should be printed */ + optind, /* index into parent argv vector */ + optopt, /* character checked for validity */ + optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ +static char *place; /* option letter processing */ + +#define BADCH (int)'?' +#define BADARG (int)':' + +static char EMSG[] = { '\0' }; + +INITIALIZER(300, _init_getopt, { + opterr = 1; + optind = 1; + place = EMSG; +}); + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int +getopt(int nargc, char * const nargv[], const char *ostr) +{ + char *oli; /* option letter list index */ + + /* + * Some programs like cvs expect optind = 0 to trigger + * a reset of getopt. + */ + if (optind == 0) + optind = 1; + + if (optreset || *place == 0) { /* update scanning pointer */ + optreset = 0; + place = nargv[optind]; + if (optind >= nargc || *place++ != '-') { + /* Argument is absent or is not an option */ + place = EMSG; + return (-1); + } + optopt = *place++; + if (optopt == '-' && *place == 0) { + /* "--" => end of options */ + ++optind; + place = EMSG; + return (-1); + } + if (optopt == 0) { + /* Solitary '-', treat as a '-' option + if the program (eg su) is looking for it. */ + place = EMSG; + if (strchr(ostr, '-') == NULL) + return (-1); + optopt = '-'; + } + } else + optopt = *place++; + + /* See if option letter is one the caller wanted... */ + if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) { + if (*place == 0) + ++optind; + if (opterr && *ostr != ':') + fprintf(stderr, + "%s: illegal option -- %c\n", program_invocation_name, + optopt); + return (BADCH); + } + + /* Does this option need an argument? */ + if (oli[1] != ':') { + /* don't need argument */ + optarg = NULL; + if (*place == 0) + ++optind; + } else { + /* Option-argument is either the rest of this argument or the + entire next argument. */ + if (*place) + optarg = place; + else if (nargc > ++optind) + optarg = nargv[optind]; + else { + /* option-argument absent */ + place = EMSG; + if (*ostr == ':') + return (BADARG); + if (opterr) + fprintf(stderr, + "%s: option requires an argument -- %c\n", + program_invocation_name, optopt); + return (BADCH); + } + place = EMSG; + ++optind; + } + return (optopt); /* return option letter */ +} diff --git a/third_party/getopt/getopt.h b/third_party/getopt/getopt.h new file mode 100644 index 00000000..06767a39 --- /dev/null +++ b/third_party/getopt/getopt.h @@ -0,0 +1,26 @@ +#ifndef COSMOPOLITAN_THIRD_PARTY_GETOPT_GETOPT_H_ +#define COSMOPOLITAN_THIRD_PARTY_GETOPT_GETOPT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +extern char *optarg; +extern int optind, opterr, optopt, optreset; +int getopt(int nargc, char *const nargv[], const char *ostr); + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 +struct option { + const char *name; + int has_arg; + int *flag; + int val; +}; +int getopt_long(int nargc, char *const *nargv, const char *options, + const struct option *long_options, int *idx); +int getopt_long_only(int nargc, char *const *nargv, const char *options, + const struct option *long_options, int *idx); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_GETOPT_GETOPT_H_ */ diff --git a/third_party/getopt/getopt.mk b/third_party/getopt/getopt.mk new file mode 100644 index 00000000..c47768b0 --- /dev/null +++ b/third_party/getopt/getopt.mk @@ -0,0 +1,56 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += THIRD_PARTY_GETOPT + +THIRD_PARTY_GETOPT_ARTIFACTS += THIRD_PARTY_GETOPT_A +THIRD_PARTY_GETOPT = $(THIRD_PARTY_GETOPT_A_DEPS) $(THIRD_PARTY_GETOPT_A) +THIRD_PARTY_GETOPT_A = o/$(MODE)/third_party/getopt/getopt.a +THIRD_PARTY_GETOPT_A_FILES := $(wildcard third_party/getopt/*) +THIRD_PARTY_GETOPT_A_HDRS = $(filter %.h,$(THIRD_PARTY_GETOPT_A_FILES)) +THIRD_PARTY_GETOPT_A_SRCS_S = $(filter %.S,$(THIRD_PARTY_GETOPT_A_FILES)) +THIRD_PARTY_GETOPT_A_SRCS_C = $(filter %.c,$(THIRD_PARTY_GETOPT_A_FILES)) + +THIRD_PARTY_GETOPT_A_SRCS = \ + $(THIRD_PARTY_GETOPT_A_SRCS_S) \ + $(THIRD_PARTY_GETOPT_A_SRCS_C) + +THIRD_PARTY_GETOPT_A_OBJS = \ + $(THIRD_PARTY_GETOPT_A_SRCS:%=o/$(MODE)/%.zip.o) \ + $(THIRD_PARTY_GETOPT_A_SRCS_S:%.S=o/$(MODE)/%.o) \ + $(THIRD_PARTY_GETOPT_A_SRCS_C:%.c=o/$(MODE)/%.o) + +THIRD_PARTY_GETOPT_A_CHECKS = \ + $(THIRD_PARTY_GETOPT_A).pkg \ + $(THIRD_PARTY_GETOPT_A_HDRS:%=o/$(MODE)/%.ok) + +THIRD_PARTY_GETOPT_A_DIRECTDEPS = \ + LIBC_CALLS \ + LIBC_FMT \ + LIBC_LOG \ + LIBC_NEXGEN32E \ + LIBC_STDIO \ + LIBC_STUBS \ + LIBC_STR + +THIRD_PARTY_GETOPT_A_DEPS := \ + $(call uniq,$(foreach x,$(THIRD_PARTY_GETOPT_A_DIRECTDEPS),$($(x)))) + +$(THIRD_PARTY_GETOPT_A): \ + third_party/getopt/ \ + $(THIRD_PARTY_GETOPT_A).pkg \ + $(THIRD_PARTY_GETOPT_A_OBJS) + +$(THIRD_PARTY_GETOPT_A).pkg: \ + $(THIRD_PARTY_GETOPT_A_OBJS) \ + $(foreach x,$(THIRD_PARTY_GETOPT_A_DIRECTDEPS),$($(x)_A).pkg) + +THIRD_PARTY_GETOPT_LIBS = $(foreach x,$(THIRD_PARTY_GETOPT_ARTIFACTS),$($(x))) +THIRD_PARTY_GETOPT_SRCS = $(foreach x,$(THIRD_PARTY_GETOPT_ARTIFACTS),$($(x)_SRCS)) +THIRD_PARTY_GETOPT_HDRS = $(foreach x,$(THIRD_PARTY_GETOPT_ARTIFACTS),$($(x)_HDRS)) +THIRD_PARTY_GETOPT_CHECKS = $(foreach x,$(THIRD_PARTY_GETOPT_ARTIFACTS),$($(x)_CHECKS)) +THIRD_PARTY_GETOPT_OBJS = $(foreach x,$(THIRD_PARTY_GETOPT_ARTIFACTS),$($(x)_OBJS)) +$(THIRD_PARTY_GETOPT_OBJS): $(BUILD_FILES) third_party/getopt/getopt.mk + +.PHONY: o/$(MODE)/third_party/getopt +o/$(MODE)/third_party/getopt: $(THIRD_PARTY_GETOPT_CHECKS) diff --git a/third_party/getopt/getopt_long.3 b/third_party/getopt/getopt_long.3 new file mode 100644 index 00000000..88e0dffb --- /dev/null +++ b/third_party/getopt/getopt_long.3 @@ -0,0 +1,444 @@ +.\" $OpenBSD: getopt_long.3,v 1.21 2016/01/04 19:43:13 tb Exp $ +.\" $NetBSD: getopt_long.3,v 1.11 2002/10/02 10:54:19 wiz Exp $ +.\" +.\" Copyright (c) 1988, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)getopt.3 8.5 (Berkeley) 4/27/95 +.\" +.Dd $Mdocdate: January 4 2016 $ +.Dt GETOPT_LONG 3 +.Os +.Sh NAME +.Nm getopt_long , +.Nm getopt_long_only +.Nd get long options from command line argument list +.Sh SYNOPSIS +.In getopt.h +.Vt extern char *optarg; +.Vt extern int optind; +.Vt extern int optopt; +.Vt extern int opterr; +.Vt extern int optreset; +.Ft int +.Fn getopt_long "int argc" "char * const *argv" "const char *optstring" "const struct option *longopts" "int *longindex" +.Ft int +.Fn getopt_long_only "int argc" "char * const *argv" "const char *optstring" "const struct option *longopts" "int *longindex" +.Sh DESCRIPTION +The +.Fn getopt_long +function is similar to +.Xr getopt 3 +but it accepts options in two forms: words and characters. +The +.Fn getopt_long +function provides a superset of the functionality of +.Xr getopt 3 . +.Fn getopt_long +can be used in two ways. +In the first way, every long option understood by the program has a +corresponding short option, and the option structure is only used to +translate from long options to short options. +When used in this fashion, +.Fn getopt_long +behaves identically to +.Xr getopt 3 . +This is a good way to add long option processing to an existing program +with the minimum of rewriting. +.Pp +In the second mechanism, a long option sets a flag in the +.Fa option +structure passed, or will store a pointer to the command line argument +in the +.Fa option +structure passed to it for options that take arguments. +Additionally, the long option's argument may be specified as a single +argument with an equal sign, e.g. +.Bd -literal -offset indent +$ myprogram --myoption=somevalue +.Ed +.Pp +When a long option is processed, the call to +.Fn getopt_long +will return 0. +For this reason, long option processing without +shortcuts is not backwards compatible with +.Xr getopt 3 . +.Pp +It is possible to combine these methods, providing for long options +processing with short option equivalents for some options. +Less frequently used options would be processed as long options only. +.Pp +Abbreviated long option names are accepted when +.Fn getopt_long +processes long options if the abbreviation is unique. +An exact match is always preferred for a defined long option. +.Pp +The +.Fn getopt_long +call requires an array to be initialized describing the long +options. +Each element of the array is a structure: +.Bd -literal -offset indent +struct option { + char *name; + int has_arg; + int *flag; + int val; +}; +.Ed +.Pp +The +.Fa name +field should contain the option name without the leading double dash. +.Pp +The +.Fa has_arg +field should be one of: +.Pp +.Bl -tag -width "optional_argument" -compact -offset indent +.It Dv no_argument +no argument to the option is expected. +.It Dv required_argument +an argument to the option is required. +.It Dv optional_argument +an argument to the option may be presented. +.El +.Pp +If +.Fa flag +is not +.Dv NULL , +then the integer pointed to by it will be set to the value in the +.Fa val +field. +If the +.Fa flag +field is +.Dv NULL , +then the +.Fa val +field will be returned. +Setting +.Fa flag +to +.Dv NULL +and setting +.Fa val +to the corresponding short option will make this function act just +like +.Xr getopt 3 . +.Pp +If the +.Fa longindex +field is not +.Dv NULL , +then the integer pointed to by it will be set to the index of the long +option relative to +.Fa longopts . +.Pp +The last element of the +.Fa longopts +array has to be filled with zeroes. +.Pp +The +.Fn getopt_long_only +function behaves identically to +.Fn getopt_long +with the exception that long options may start with +.Sq - +in addition to +.Sq -- . +If an option starting with +.Sq - +does not match a long option but does match a single-character option, +the single-character option is returned. +.Sh RETURN VALUES +If the +.Fa flag +field in +.Li struct option +is +.Dv NULL , +.Fn getopt_long +and +.Fn getopt_long_only +return the value specified in the +.Fa val +field, which is usually just the corresponding short option. +If +.Fa flag +is not +.Dv NULL , +these functions return 0 and store +.Fa val +in the location pointed to by +.Fa flag . +These functions return +.Sq \&: +if there was a missing option argument, +.Sq \&? +if the user specified an unknown or ambiguous option, and +\-1 when the argument list has been exhausted. +.Sh IMPLEMENTATION DIFFERENCES +This section describes differences to the GNU implementation +found in glibc-2.1.3: +.Bl -bullet +.It +handling of +.Ql - +within the option string (not the first character): +.Bl -tag -width "OpenBSD" +.It GNU +treats a +.Ql - +on the command line as a non-argument. +.It OpenBSD +a +.Ql - +within the option string matches a +.Ql - +(single dash) on the command line. +This functionality is provided for backward compatibility with +programs, such as +.Xr su 1 , +that use +.Ql - +as an option flag. +This practice is wrong, and should not be used in any current development. +.El +.It +handling of +.Ql :: +in the option string in the presence of +.Ev POSIXLY_CORRECT : +.Bl -tag -width "OpenBSD" +.It Both +GNU and +.Ox +ignore +.Ev POSIXLY_CORRECT +here and take +.Ql :: +to mean the preceding option takes an optional argument. +.El +.It +return value in case of missing argument if first character +(after +.Ql + +or +.Ql - ) +in the option string is not +.Ql \&: : +.Bl -tag -width "OpenBSD" +.It GNU +returns +.Ql \&? +.It OpenBSD +returns +.Ql \&: +(since +.Ox Ns 's +.Xr getopt 3 +does). +.El +.It +handling of +.Ql --a +in +.Xr getopt 3 : +.Bl -tag -width "OpenBSD" +.It GNU +parses this as option +.Ql - , +option +.Ql a . +.It OpenBSD +parses this as +.Ql -- , +and returns \-1 (ignoring the +.Ql a ) +(because the original +.Fn getopt +did.) +.El +.It +setting of +.Va optopt +for long options with +.Va flag +.No non- Ns Dv NULL : +.Bl -tag -width "OpenBSD" +.It GNU +sets +.Va optopt +to +.Va val . +.It OpenBSD +sets +.Va optopt +to 0 (since +.Va val +would never be returned). +.El +.It +handling of +.Ql -W +with +.Ql W; +in the option string in +.Xr getopt 3 +(not +.Fn getopt_long ) : +.Bl -tag -width "OpenBSD" +.It GNU +causes a segmentation fault. +.It OpenBSD +no special handling is done; +.Ql W; +is interpreted as two separate options, neither of which take an argument. +.El +.It +setting of +.Va optarg +for long options without an argument that are invoked via +.Ql -W +(with +.Ql W; +in the option string): +.Bl -tag -width "OpenBSD" +.It GNU +sets +.Va optarg +to the option name (the argument of +.Ql -W ) . +.It OpenBSD +sets +.Va optarg +to +.Dv NULL +(the argument of the long option). +.El +.It +handling of +.Ql -W +with an argument that is not (a prefix to) a known long option +(with +.Ql W; +in the option string): +.Bl -tag -width "OpenBSD" +.It GNU +returns +.Ql -W +with +.Va optarg +set to the unknown option. +.It OpenBSD +treats this as an error (unknown option) and returns +.Ql \&? +with +.Va optopt +set to 0 and +.Va optarg +set to +.Dv NULL +(as GNU's man page documents). +.El +.It +The error messages are different. +.It +.Ox +does not permute the argument vector at the same points in +the calling sequence as GNU does. +The aspects normally used by the caller +(ordering after \-1 is returned, value of +.Va optind +relative to current positions) are the same, though. +(We do fewer variable swaps.) +.El +.Sh ENVIRONMENT +.Bl -tag -width Ev +.It Ev POSIXLY_CORRECT +If set, option processing stops when the first non-option is found and +a leading +.Sq + +in the +.Ar optstring +is ignored. +.El +.Sh EXAMPLES +.Bd -literal +int bflag, ch, fd; +int daggerset; + +/* options descriptor */ +static struct option longopts[] = { + { "buffy", no_argument, NULL, 'b' }, + { "fluoride", required_argument, NULL, 'f' }, + { "daggerset", no_argument, &daggerset, 1 }, + { NULL, 0, NULL, 0 } +}; + +bflag = 0; +while ((ch = getopt_long(argc, argv, "bf:", longopts, NULL)) != -1) + switch (ch) { + case 'b': + bflag = 1; + break; + case 'f': + if ((fd = open(optarg, O_RDONLY, 0)) == -1) + err(1, "unable to open %s", optarg); + break; + case 0: + if (daggerset) + fprintf(stderr, "Buffy will use her dagger to " + "apply fluoride to dracula's teeth\en"); + break; + default: + usage(); + } +argc -= optind; +argv += optind; +.Ed +.Sh SEE ALSO +.Xr getopt 3 +.Sh HISTORY +The +.Fn getopt_long +and +.Fn getopt_long_only +functions first appeared in GNU libiberty. +This implementation first appeared in +.Ox 3.3 . +.Sh BUGS +The +.Ar argv +argument is not really +.Dv const +as its elements may be permuted (unless +.Ev POSIXLY_CORRECT +is set). diff --git a/third_party/getopt/getopt_long.c b/third_party/getopt/getopt_long.c new file mode 100644 index 00000000..39c75bf6 --- /dev/null +++ b/third_party/getopt/getopt_long.c @@ -0,0 +1,553 @@ +/** + * This file has an inappropriate amount of legal text for its + * complexity and should be rewritten. Consider using getopt(). + */ +asm(".ident\t\"\\n\\n\ +getopt_long (Licensed BSD-4, MIT)\\n\ +Copyright (c) 2000 The NetBSD Foundation, Inc.\\n\ +Copyright (c) 2002 Todd C. Miller \\n\ +The getopt_long code is derived from software contributed to The\\n\ +NetBSD Foundation by Dieter Baron and Thomas Klausner. This code\\n\ +has received sponsorship from the U.S. Military. Special thanks\\n\ +to the OpenBSD, NetBSD, FreeBSD, and DragonFlyBSD teams.\""); +asm(".include \"libc/disclaimer.inc\""); + +#define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var)) + +/* clang-format off */ +/* $OpenBSD: getopt_long.c,v 1.21 2006/09/22 17:22:05 millert Exp $*/ +/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ + +/* + * Copyright (c) 2002 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/stdlib/getopt_long.c,v 1.15 2006/09/23 14:48:31 ache Exp $ + * $DragonFly: src/lib/libc/stdlib/getopt_long.c,v 1.14 2005/11/20 12:37:48 swildner Exp $ + */ + +#include "third_party/getopt/getopt.h" +#include "libc/str/str.h" +#include "libc/runtime/runtime.h" +#include "libc/log/bsd.h" + +STATIC_YOINK("stoa"); + +#define PRINT_ERROR ((opterr) && (*options != ':')) + +#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ +#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ +#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ + +/* return values */ +#define BADCH (int)'?' +#define BADARG2 ((*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +#define EMSG "" + +#define NO_PREFIX (-1) +#define D_PREFIX 0 +#define DD_PREFIX 1 +#define W_PREFIX 2 + +static int getopt_internal(int, char * const *, const char *, + const struct option *, int *, int); +static int parse_long_options(char * const *, const char *, + const struct option *, int *, int, int); +static int gcd(int, int); +static void permute_args(int, int, int, char * const *); + +static char *place = EMSG; /* option letter processing */ + +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static int dash_prefix = NO_PREFIX; +#define recargchar "option requires an argument -- %c" +#define illoptchar "illegal option -- %c" /* From P1003.2 */ +#define gnuoptchar "invalid option -- %c" +#define recargstring "option `%s%s' requires an argument" +#define ambig "option `%s%.*s' is ambiguous" +#define noarg "option `%s%.*s' doesn't allow an argument" +#define illoptstring "unrecognized option `%s%s'" + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(int a, int b) +{ + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return (b); +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(int panonopt_start, int panonopt_end, int opt_end, + char * const *nargv) +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + /* LINTED const cast */ + (__DECONST(char **, nargv))[pos] = nargv[cstart]; + /* LINTED const cast */ + (__DECONST(char **, nargv))[cstart] = swap; + } + } +} + +/* + * parse_long_options -- + * Parse long options in argc/argv argument vector. + * Returns -1 if short_too is set and the option does not match long_options. + */ +static int +parse_long_options(char * const *nargv, const char *options, + const struct option *long_options, int *idx, int short_too, int flags) +{ + char *current_argv, *has_equal; + char *current_dash; + size_t current_argv_len; + int i, match, exact_match, second_partial_match; + + current_argv = place; + switch (dash_prefix) { + case D_PREFIX: + current_dash = "-"; + break; + case DD_PREFIX: + current_dash = "--"; + break; + case W_PREFIX: + current_dash = "-W "; + break; + default: + current_dash = ""; + break; + } + match = -1; + exact_match = 0; + second_partial_match = 0; + + optind++; + + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == current_argv_len) { + /* exact match */ + match = i; + exact_match = 1; + break; + } + /* + * If this is a known short option, don't allow + * a partial match of a single character. + */ + if (short_too && current_argv_len == 1) + continue; + + if (match == -1) /* first partial match */ + match = i; + else if ((flags & FLAG_LONGONLY) || + long_options[i].has_arg != + long_options[match].has_arg || + long_options[i].flag != long_options[match].flag || + long_options[i].val != long_options[match].val) + second_partial_match = 1; + } + if (!exact_match && second_partial_match) { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + (warnx)(ambig, + current_dash, + (int)current_argv_len, + current_argv); + optopt = 0; + return (BADCH); + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { + if (PRINT_ERROR) + (warnx)(noarg, + current_dash, + (int)current_argv_len, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return (BADCH); + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' indicates no error + * should be generated. + */ + if (PRINT_ERROR) + (warnx)(recargstring, + current_dash, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return (BADARG2); + } + } else { /* unknown option */ + if (short_too) { + --optind; + return (-1); + } + if (PRINT_ERROR) + (warnx)(illoptstring, + current_dash, + current_argv); + optopt = 0; + return (BADCH); + } + if (idx) + *idx = match; + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + return (0); + } else + return (long_options[match].val); +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + */ +static int +getopt_internal(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx, int flags) +{ + char *oli; /* option letter list index */ + int optchar, short_too; + int posixly_correct; /* no static, can be changed on the fly */ + + if (options == NULL) + return (-1); + + /* + * Disable GNU extensions if POSIXLY_CORRECT is set or options + * string begins with a '+'. + */ + posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); + if (*options == '-') + flags |= FLAG_ALLARGS; + else if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; + if (*options == '+' || *options == '-') + options++; + + /* + * XXX Some GNU programs (like cvs) set optind to 0 instead of + * XXX using optreset. Work around this braindamage. + */ + if (optind == 0) + optind = optreset = 1; + + optarg = NULL; + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + if (*(place = nargv[optind]) != '-' || + place[1] == '\0') { + place = EMSG; /* found non-option */ + if (flags & FLAG_ALLARGS) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return (INORDER); + } + if (!(flags & FLAG_PERMUTE)) { + /* + * If no permutation wanted, stop parsing + * at first non-option. + */ + return (-1); + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + + /* + * If we have "-" do nothing, if "--" we are done. + */ + if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { + optind++; + place = EMSG; + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + } + + /* + * Check long options if: + * 1) we were passed some + * 2) the arg is not just "-" + * 3) either the arg starts with -- we are getopt_long_only() + */ + if (long_options != NULL && place != nargv[optind] && + (*place == '-' || (flags & FLAG_LONGONLY))) { + short_too = 0; + dash_prefix = D_PREFIX; + if (*place == '-') { + place++; /* --foo long option */ + dash_prefix = DD_PREFIX; + } else if (*place != ':' && strchr(options, *place) != NULL) + short_too = 1; /* could be short option too */ + + optchar = parse_long_options(nargv, options, long_options, + idx, short_too, flags); + if (optchar != -1) { + place = EMSG; + return (optchar); + } + } + + if ((optchar = (int)*place++) == (int)':' || + (optchar == (int)'-' && *place != '\0') || + (oli = strchr(options, optchar)) == NULL) { + /* + * If the user specified "-" and '-' isn't listed in + * options, return -1 (non-option) as per POSIX. + * Otherwise, it is an unknown option character (or ':'). + */ + if (optchar == (int)'-' && *place == '\0') + return (-1); + if (!*place) + ++optind; + if (PRINT_ERROR) + (warnx)(posixly_correct ? illoptchar : gnuoptchar, + optchar); + optopt = optchar; + return (BADCH); + } + if (long_options != NULL && optchar == 'W' && oli[1] == ';') { + /* -W long-option */ + if (*place) /* no space */ + /* NOTHING */; + else if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + (warnx)(recargchar, optchar); + optopt = optchar; + return (BADARG2); + } else /* white space */ + place = nargv[optind]; + dash_prefix = W_PREFIX; + optchar = parse_long_options(nargv, options, long_options, + idx, 0, flags); + place = EMSG; + return (optchar); + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = place; + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + (warnx)(recargchar, optchar); + optopt = optchar; + return (BADARG2); + } else + optarg = nargv[optind]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return (optchar); +} + +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +int +getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE)); +} + +/* + * getopt_long_only -- + * Parse argc/argv argument vector. + */ +int +getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE|FLAG_LONGONLY)); +} diff --git a/third_party/lex/COPYING b/third_party/lex/COPYING new file mode 100644 index 00000000..aa3af4ef --- /dev/null +++ b/third_party/lex/COPYING @@ -0,0 +1,43 @@ +.ident "\n +Flex carries the copyright used for BSD software, slightly modified +because it originated at the Lawrence Berkeley (not Livermore!) Laboratory, +which operates under a contract with the Department of Energy: + +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The Flex Project. + +Copyright (c) 1990, 1997 The Regents of the University of California. +All rights reserved. + +This code is derived from software contributed to Berkeley by +Vern Paxson. + +The United States Government has rights in this work pursuant +to contract no. DE-AC03-76SF00098 between the United States +Department of Energy and the University of California. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +Neither the name of the University nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. + +This basically says \"do whatever you please with this software except +remove this notice or take advantage of the University's (or the flex +authors') name\". + +Note that the \"flex.skl\" scanner skeleton carries no copyright notice. +You are free to do whatever you please with scanners generated using flex; +for them, you are not even bound by the above copyright." diff --git a/third_party/lex/ChangeLog b/third_party/lex/ChangeLog new file mode 100644 index 00000000..5276ae63 --- /dev/null +++ b/third_party/lex/ChangeLog @@ -0,0 +1,8226 @@ +2019-06-08 Justine Tunney + + * Lex is now available in Cosmopolitan, thanks to OpenBSD! + +2014-02-16 Translation Project + + * po/ru.po: update ru translation from the translation project + +2014-02-14 Will Estes + + * NEWS: mention updated da translation in release news + +2014-02-14 Translation Project + + * po/da.po: update da translation from the translation project + +2014-02-14 Will Estes + + * NEWS: mention updated es translation in release news + +2014-02-14 Translation Project + + * po/es.po: update es translation from the translation project + +2014-02-14 Will Estes + + * NEWS: mention updated ko translation in release news + +2014-02-14 Translation Project + + * po/ko.po: update ko translation from the translation project + +2014-02-14 Will Estes + + * NEWS: mention updated ro translation in release news + +2014-02-14 Translation Project + + * po/ro.po: update ro translation from the translation project + +2014-02-14 Will Estes + + * NEWS: mention updated ru translation in release news + +2014-02-14 Translation Project + + * po/ru.po: update ru translation from the translation project + +2014-02-14 Will Estes + + * NEWS: mention updated sv translation in news + +2014-02-14 Translation Project + + * po/sv.po: update sv translation from the translation project + +2014-02-14 Will Estes + + * NEWS: mention updated tr translation in news + +2014-02-14 Translation Project + + * po/tr.po: update tr translation from the translation project + +2014-02-14 Will Estes + + * NEWS: mention updated zh_CN in release news + +2014-02-14 Translation Project + + * po/zh_CN.po: update zh_CN translation from the translation project + +2014-02-14 Will Estes + + * NEWS, po/LINGUAS, po/zh_TW.po, po/zh_tw.po: rename zh_tw + translation to its proper zh_TW name + +2014-02-14 Will Estes + + * NEWS: mention updated nl, vi translations in release news + +2014-02-14 Translation Project + + * po/vi.po: update vi translation from the translation project + +2014-02-14 Translation Project + + * po/nl.po: update nl translation from the translation project + +2014-02-14 Will Estes + + * TODO: remove some unneeded entries from the todo list + +2014-02-13 Will Estes + + * doc/Makefile.am: list more generated files in CLEANFILES + +2014-02-13 Will Estes + + * doc/flex.xml: remove unmaintained xml documentation + +2014-02-13 Will Estes + + * configure.ac: bump AM_GNU_GETTEXT_VERSION to 0.18.1 + +2014-02-13 Will Estes + + * README: list new location of flex git repo + +2014-02-13 Will Estes + + * po/.gitignore: git ignore generated files from english quoting + variant translations + +2014-02-13 Will Estes + + * po/LINGUAS: name english quoting variants correctly + +2014-02-13 Will Estes + + * Makefile.am, configure.ac, tools/Makefile.am: removed tools/ + subdirectory from distribution Since it is not possible to rebuild the ChangeLog file without being + in a git working directory of flex, distributing the tools directory + is misleading. In particular, git2cl will always fail. + +2014-02-13 Will Estes + + * po/LINGUAS: removed unneeded blank line from translation list + +2014-02-13 Will Estes + + * po/LINGUAS: added en quoting variants to translation list + +2014-02-11 Will Estes + + * configure.ac: use gnu automake option instead of gnits option + +2014-02-11 Will Estes + + * README-alpha: remove README_alpha file since it is no longer + needed + +2014-02-10 Will Estes + + * configure.ac: increment version to 2.5.38 + +2013-11-27 Will Estes + + * NEWS: flesh out internationalization section of NEWS file; mention + pt_BR translation + +2013-11-27 Translation Project + + * po/pt_BR.po: update pt_BR translation from the translation project + +2013-10-31 Will Estes + + * NEWS: begin listing 2.5.38 version in NEWS; list new sr + translation + +2013-10-31 Will Estes + + * po/LINGUAS: list new sr translation in list of translations + +2013-10-31 Will Estes + + * po/sr.po: add sr translation from the translation project + +2013-07-02 Till Varoquaux + + * configure.ac, flex.skl, nfa.c, tests/Makefile.am, + tests/test-lineno-trailing/.gitignore, + tests/test-lineno-trailing/Makefile.am, + tests/test-lineno-trailing/scanner.l, + tests/test-lineno-trailing/test.input: Adjust yylineno properly when + rewinding trailing contexts. + +2013-05-28 Will Estes + + * Makefile.am: Remove incorrect / in install-exec-hook target + +2013-02-16 Translation Project + + * po/LINGUAS, po/zh_tw.po: add zh_tw translation from the + translation project + +2012-12-06 Christoph Junghans + + * Makefile.am, configure.ac: add version information to shared + library Signed-off-by: Will Estes + +2012-12-04 Christoph Junghans + + * .gitignore, Makefile.am, configure.ac, lib/Makefile.am: Build + libfl and libcompat using libtool; resolves #3586814 Signed-off-by: Will Estes + +2012-12-04 Translation Project + + * po/ca.po: update ca translation + +2012-10-31 Hugh Sasse + + * tests/test-extended/Makefile.am, tests/test-quotes/Makefile.am: + use cmp instead of diff in some tests for portability reasons Signed-off-by: Will Estes + +2012-10-31 Dennis Clarke + + * tests/TEMPLATE/Makefile.am, tests/test-alloc-extra/Makefile.am, + tests/test-array-nr/Makefile.am, tests/test-array-r/Makefile.am, + tests/test-basic-nr/Makefile.am, tests/test-basic-r/Makefile.am, + tests/test-bison-nr/Makefile.am, + tests/test-bison-yylloc/Makefile.am, + tests/test-bison-yylval/Makefile.am, + tests/test-c++-basic/Makefile.am, + tests/test-c++-multiple-scanners/Makefile.am, + tests/test-c++-yywrap/Makefile.am, tests/test-c-cpp-nr/Makefile.am, + tests/test-c-cpp-r/Makefile.am, tests/test-ccl/Makefile.am, + tests/test-debug-nr/Makefile.am, tests/test-debug-r/Makefile.am, + tests/test-extended/Makefile.am, tests/test-header-nr/Makefile.am, + tests/test-header-r/Makefile.am, + tests/test-include-by-buffer/Makefile.am, + tests/test-include-by-push/Makefile.am, + tests/test-include-by-reentrant/Makefile.am, + tests/test-linedir-r/Makefile.am, tests/test-lineno-nr/Makefile.am, + tests/test-lineno-r/Makefile.am, tests/test-mem-nr/Makefile.am, + tests/test-mem-r/Makefile.am, + tests/test-multiple-scanners-nr/Makefile.am, + tests/test-multiple-scanners-r/Makefile.am, + tests/test-noansi-nr/Makefile.am, tests/test-noansi-r/Makefile.am, + tests/test-posix/Makefile.am, + tests/test-posixly-correct/Makefile.am, + tests/test-prefix-nr/Makefile.am, tests/test-prefix-r/Makefile.am, + tests/test-pthread/Makefile.am, tests/test-quotes/Makefile.am, + tests/test-reject/Makefile.am, tests/test-rescan-nr/Makefile.am, + tests/test-rescan-r/Makefile.am, tests/test-string-nr/Makefile.am, + tests/test-string-r/Makefile.am, tests/test-table-opts/Makefile.am, + tests/test-top/Makefile.am, tests/test-yyextra/Makefile.am: add + CFLAGS and CXXFLAGS options as appropriate to testsuite Makefile.am + files Signed-off-by: Will Estes + +2012-10-25 Will Estes + + * po/LINGUAS: add hr to list of translations + +2012-10-25 Translation Project + + * po/hr.po: add hr translation from the translation project + +2012-10-25 Translation Project + + * po/fr.po: new fr translation project from the translation project + +2012-09-08 Will Estes + + * po/LINGUAS: update languages list to include esperanto translation + +2012-09-08 Translation Project + + * po/eo.po: add eo translation from the translation project + +2012-08-26 Will Estes + + * configure.ac: add dist-xz to automake options; resolves #3561837 + +2012-08-26 Will Estes + + * autogen.sh, configure.ac: require gettext 0.18; force autoreconf + in autogen.sh; resolves #3561759 Autoconf had trouble finding the shared libraries for gettext. Using + gettext 0.18 fixes that. When updating the gettext version number, autoreconf could fail to + update files, since autopoint would assume the gettext-related files + had been locally modified. Passing --force prevents that from + happening. + +2012-08-15 Will Estes + + * Makefile.am: remove README.cvs from dist_doc_DATA in Makefile.am + +2012-08-13 Will Estes + + * : commit 9256a268e2a1000cb410766e95487912a7d66d61 Author: Will + Estes Date: Mon Aug 13 16:23:35 2012 -0400 + +2012-08-08 Will Estes + + * README, README.cvs: append README.cvs contents to README + +2012-08-08 Will Estes + + * gen.c: fix m4 error when useecs and nultrans are true; resolves + #1816878 + +2012-08-08 Robert Minsk + + * flex.skl: put user code after yyguts init; resolves #1744516 Signed-off-by: Will Estes + +2012-08-08 Robert Minsk + + * flex.skl, main.c: do not output yy_nxt to header with %option + full; resolves #1739922 Signed-off-by: Will Estes + +2012-08-07 Will Estes + + * main.c: let flex decide if yymore and reject are needed in lex + compatible mode This resolves bug #3510440. + +2012-08-06 Translation Project + + * po/vi.po: new vi translation from the translation project + +2012-08-06 Will Estes + + * .gitignore: add more patterns to .gitignore Undersome circumstances, the build process will generate conf.in~, + which we want to ignore. Also, some patch files will apply but not + cleanly and *.orig and *.rej files are generated. We want to ignore + them as well. + +2012-08-06 Will Estes + + * configure.ac, configure.in: rename configure.in to configure.ac to + prep for upcoming automake changes + +2012-08-06 Elias Pipping + + * tests/test-bison-yylloc/main.c, tests/test-bison-yylloc/parser.y, + tests/test-bison-yylval/main.c, tests/test-bison-yylval/parser.y: + Fix two tests to pass under bison 2.6 Given that bison is moving forward with the %parse-param instead of + YYPARSE_PARAM syntax, it makes sense to switch over to using the new + style declaration. In particular, this means that flex scanners that + use bison features will now require bison 2.6 or higher. Signed-off-by: Will Estes + +2012-08-04 Will Estes + + * po/nl.po: new nl translation from the translation project + +2012-08-04 Mike Frysinger + + * flexdef.h: add prototype for lerrsf_fatal to flexdef.h Signed-off-by: Will Estes + +2012-08-04 nomis52 + + * flex.skl, gen.c: Change variable types to silence compiler + warnings; resolves #3552806 Signed-off-by: Will Estes + +2012-08-03 Will Estes + + * NEWS: update NEWS to reflect changes in 2.5.37 + +2012-08-03 Will Estes + + * configure.in: update flex version to 2.5.37 + +2012-08-03 Will Estes + + * po/de.po: new de translation from the translation project + +2012-08-02 Will Estes + + * po/vi.po: new vi translation from the translation project + +2012-08-02 Will Estes + + * po/pl.po: new pl translation from the translation project + +2012-08-02 Will Estes + + * po/fi.po: new fi translation from the translation project + +2012-08-02 Will Estes + + * Makefile.am: Add -f option to LN_S to create flex++ The autoconf macro LN_S needs -f to successfully install flex++ if + flex++ already exists. Fortunately, ln, ln -s and cp -p, which are + the various forms that LN_S can take all will do the right thing + with a -f argument passed. + +2012-08-02 Will Estes + + * Makefile.am, tools/Makefile.am, tools/cvs2cl.pl, + tools/cvsauthors, tools/git2cl: replace cvs2cl with git2cl Add the git2cl script in tools/ and remove the (now unnecessary) + cvs2cl script. Remove tools/cvsauthors since git2cl does not need + that file. Account for all the above in Makefile.am and + tools/Makefile.am + +2012-07-29 Will Estes + + * tests/.cvsignore, tests/.gitignore, tests/TEMPLATE/.cvsignore, + tests/TEMPLATE/.gitignore, tests/test-alloc-extra/.cvsignore, + tests/test-alloc-extra/.gitignore, tests/test-array-nr/.cvsignore, + tests/test-array-nr/.gitignore, tests/test-array-r/.cvsignore, + tests/test-array-r/.gitignore, tests/test-basic-nr/.cvsignore, + tests/test-basic-nr/.gitignore, tests/test-basic-r/.cvsignore, + tests/test-basic-r/.gitignore, tests/test-bison-nr/.cvsignore, + tests/test-bison-nr/.gitignore, tests/test-bison-yylloc/.cvsignore, + tests/test-bison-yylloc/.gitignore, + tests/test-bison-yylval/.cvsignore, + tests/test-bison-yylval/.gitignore, + tests/test-c++-basic/.cvsignore, tests/test-c++-basic/.gitignore, + tests/test-c++-multiple-scanners/.cvsignore, + tests/test-c++-multiple-scanners/.gitignore, + tests/test-c++-yywrap/.cvsignore, tests/test-c++-yywrap/.gitignore, + tests/test-c-cpp-nr/.cvsignore, tests/test-c-cpp-nr/.gitignore, + tests/test-c-cpp-r/.cvsignore, tests/test-c-cpp-r/.gitignore, + tests/test-ccl/.cvsignore, tests/test-ccl/.gitignore, + tests/test-concatenated-options/.cvsignore, + tests/test-concatenated-options/.gitignore, + tests/test-debug-nr/.cvsignore, tests/test-debug-nr/.gitignore, + tests/test-debug-r/.cvsignore, tests/test-debug-r/.gitignore, + tests/test-extended/.cvsignore, tests/test-extended/.gitignore, + tests/test-header-nr/.cvsignore, tests/test-header-nr/.gitignore, + tests/test-header-r/.cvsignore, tests/test-header-r/.gitignore, + tests/test-include-by-buffer/.cvsignore, + tests/test-include-by-buffer/.gitignore, + tests/test-include-by-push/.cvsignore, + tests/test-include-by-push/.gitignore, + tests/test-include-by-reentrant/.cvsignore, + tests/test-include-by-reentrant/.gitignore, + tests/test-linedir-r/.cvsignore, tests/test-linedir-r/.gitignore, + tests/test-lineno-nr/.cvsignore, tests/test-lineno-nr/.gitignore, + tests/test-lineno-r/.cvsignore, tests/test-lineno-r/.gitignore, + tests/test-mem-nr/.cvsignore, tests/test-mem-nr/.gitignore, + tests/test-mem-r/.cvsignore, tests/test-mem-r/.gitignore, + tests/test-multiple-scanners-nr/.cvsignore, + tests/test-multiple-scanners-nr/.gitignore, + tests/test-multiple-scanners-r/.cvsignore, + tests/test-multiple-scanners-r/.gitignore, + tests/test-noansi-nr/.cvsignore, tests/test-noansi-nr/.gitignore, + tests/test-noansi-r/.cvsignore, tests/test-noansi-r/.gitignore, + tests/test-posix/.cvsignore, tests/test-posix/.gitignore, + tests/test-posixly-correct/.cvsignore, + tests/test-posixly-correct/.gitignore, + tests/test-prefix-nr/.cvsignore, tests/test-prefix-nr/.gitignore, + tests/test-prefix-r/.cvsignore, tests/test-prefix-r/.gitignore, + tests/test-pthread/.cvsignore, tests/test-pthread/.gitignore, + tests/test-quotes/.cvsignore, tests/test-quotes/.gitignore, + tests/test-reject/.cvsignore, tests/test-reject/.gitignore, + tests/test-rescan-nr/.cvsignore, tests/test-rescan-nr/.gitignore, + tests/test-rescan-r/.cvsignore, tests/test-rescan-r/.gitignore, + tests/test-string-nr/.cvsignore, tests/test-string-nr/.gitignore, + tests/test-string-r/.cvsignore, tests/test-string-r/.gitignore, + tests/test-table-opts/.cvsignore, tests/test-table-opts/.gitignore, + tests/test-top/.cvsignore, tests/test-top/.gitignore, + tests/test-yyextra/.cvsignore, tests/test-yyextra/.gitignore: rename + .cvsignore files in tests/ subdirectories to gitignore + +2012-07-23 Will Estes + + * examples/.cvsignore, examples/fastwc/.cvsignore, + examples/manual/.cvsignore, lib/.cvsignore, tools/.cvsignore: remove + unneeded .cvsignore files + +2012-07-22 Will Estes + + * .gitignore: add *.o and *.a to top level .gitignore The cvs tree did not need these additions because cvs assumed a lot + of C-style defaults for .cvsignore files. flex builds *.o object + files in the course of compilation and *.a files are built as a part + of the libraries that flex compiles in the build process. + +2012-07-22 Will Estes + + * .cvsignore, .gitignore, doc/.cvsignore, doc/.gitignore, + m4/.cvsignore, m4/.gitignore, po/.cvsignore, po/.gitignore: rename + .cvsignore files to .gitignore The .cvsignore files from the legacy cvs repository tracked what + files got autogenerated during various stages of the flex build. + Renaming the .cvsignore files to .gitignore lets git do the same + thing. git is better about letting higher level .gitignore files + not-track files in lower level directories. As I work my way through + the test directories, we may add additional .gitignore files from + the old .cvsignore files. The po/ directory has a lot of special files used by gettext, so the + patterns in po/.gitignore look very different. The doc/.gitignore file accounts for what texinfo/makeinfo do, and + so it also has special patterns. The m4 directory is mainly present for autoconf's benefit, but we + have to account for it so make can do the right thing. Hence, + m4/.gitignore says to ignore *.m4, as counterintuitive as that may + seem. + +2012-07-22 Will Estes + + * NEWS: update NEWS file to note release date of 2.5.36 + +2012-06-23 Will Estes + + * doc/flex.texi: fix call to version in manual + +2012-06-22 Will Estes + + * doc/flex.texi: add missing argument to call to yylex in manual + +2012-04-27 Will Estes + + * flex.skl: lintish cleanup in flex.skl; resolves #2040664 + +2012-04-27 Will Estes + + * doc/flex.texi: add a 7 to the c99 octal pattern; resolves #3518269 + +2012-03-31 Will Estes + + * doc/flex.texi: copyedit; resolves #3513670 + +2012-03-23 Will Estes + + * buf.c: escape backslashes in #line filenames in %top section; + resolves #3212400; patch submitted by scfc_de + +2012-03-21 Will Estes + + * Makefile.am, configure.in, lib/Makefile.am, lib/lib.c, + lib/malloc.c, lib/realloc.c: provide malloc() and realloc() for + systems that do not have satisfactory versions; resolves #1899047 + +2012-03-21 Will Estes + + * Makefile.am: install flex++ as a link; resolves bug #2939681 + +2012-03-21 Will Estes + + * tests/test-bison-nr/Makefile.am, + tests/test-bison-yylloc/Makefile.am, + tests/test-bison-yylval/Makefile.am: fix dependencies for make -j in + test suite + +2012-03-19 Will Estes + + * flex.skl: add missing prototypes for yyset_column() and + yyget_column(); resolves #3029024; patch submitted by scfc_de + +2012-03-02 Will Estes + + * flex.skl, tests/test-reject/scanner.l, + tests/test-table-opts/scanner.l: wrap yy_fatal_error calls + appropriately + +2012-03-02 Will Estes + + * regex.c: fix overlapping data buffer issue; patch from Tim + Landsheet scfc_de + +2012-03-02 Will Estes + + * scan.l: better bracket handling in the scanner + +2012-03-02 Will Estes + + * flexdef.h, main.c, misc.c: Remove unneeded tracking of line/column + output; patch from Tim Landsheet scfc_de + +2012-03-02 Will Estes + + * configure.in: fix test for m4 to accept an m4 with -P and not jus + tGNU m4; patch from Tim Landsheet scfc_de on sourceforge + +2012-03-02 Will Estes + + * doc/flex.texi: fix order of td_lolen and td_hilen in + documentation; resolves #2913693; patch submitted by Andreas + Gruenbacher + +2012-03-02 Will Estes + + * doc/flex.texi: correct document of YY_FLUSH_BUFFER; resolves + #1723028 + +2012-02-17 Will Estes + + * dfa.c, flexdef.h, misc.c, parse.y: speed up things for complex + inputs; resolves #2891390 + +2012-02-17 Will Estes + + * doc/flex.texi: fix ipv6 pattern in manual; update manual copyright + to 2012 + +2012-02-17 Will Estes + + * flex.skl: fremove isatty() declaration; resolves #1984987 + +2012-02-17 Will Estes + + * doc/flex.texi: Add link for RFC 2396 + +2012-02-17 Will Estes + + * flex.skl: resolve #1990170 + +2012-02-17 Will Estes + + * flex.skl: fix documentation to reflect arguments actually used; + bug #2783023 + +2012-02-05 Will Estes + + * main.c: fix yywrap behavior for reentrant scanners + +2012-02-04 Will Estes + + * NEWS: Mmention tr translation + +2012-02-04 Will Estes + + * tables.c: prevent unused stuff from being compiled so as to reduce + warnings + +2012-02-03 Will Estes + + * buf.c, filter.c, main.c, misc.c, regex.c, scanflags.c: more better + error messages; more better memory handling + +2012-02-03 Will Estes + + * misc.c: more careful/paranoia + +2012-02-03 Will Estes + + * scanopt.c: more careful memory allocation in option processing + +2012-02-03 Will Estes + + * Makefile.am, configure.in: remove m4/ directory and generally + clean up automake/autoconf inputs + +2012-02-03 Will Estes + + * lib/.cvsignore: cvsignore files that need that + +2012-02-03 Will Estes + + * NEWS, po/da.po, po/es.po, po/ko.po, po/pt_BR.po, po/ro.po, + po/ru.po, po/sv.po, po/tr.po, po/zh_CN.po: check in translations + +2012-02-03 Will Estes + + * main.c: correct macro definition of yywrap + +2012-02-03 Will Estes + + * scan.l: Greater specificity in error messages + +2012-02-03 Will Estes + + * parse.y: improve rule handling at EOF + +2012-02-03 Will Estes + + * flex.skl: include cstdio for definition of EOF in all cases + +2012-02-03 Will Estes + + * flex.skl: suppress warning on unused yyguts_t + +2010-08-13 Will Estes + + * NEWS, po/LINGUAS, po/fi.po: new fi translation from the + translation project + +2009-03-31 Will Estes + + * doc/flex.texi: Include version.texi after @setfilename, so that @set values are correctly evaluated. (Start Conditions, Performance, Lex and Posix): Fix some markup errors. (Cxx): Likewise. Also, fix C++ example to actually be compilable. Patch from Ralf Wildenhues + +2008-12-28 Will Estes + + * configure.in: remove line break that broke configure + +2008-12-28 Will Estes + + * doc/flex.texi: specify the title on the title page since @settitle + doesn't do that for us; resolves bug #2043491 + +2008-12-28 Will Estes + + * configure.in, flexdef.h: check for regex.h; resolves bug #2337486 + +2008-07-23 Will Estes + + * NEWS, po/ga.po: new ga translation from the translation project + +2008-06-10 Will Estes + + * NEWS, po/ca.po: new ca translation + +2008-05-31 Will Estes + + * Makefile.am: move ABOUT-NLS back to EXTRA_DIST + +2008-05-31 Will Estes + + * Makefile.am: create new dist_doc_DATA; move some EXTRA_DIST files + to new dist_doc_DATA target + +2008-05-31 Will Estes + + * .cvsignore: ignore more automake generated config.status* files + +2008-05-31 Will Estes + + * NEWS: flex distribution now built with automake and autoconf + versions ... + +2008-05-31 Will Estes + + * README.cvs: document GNU auto* version changes for building flex + from cvs + +2008-05-31 Will Estes + + * .cvsignore, doc/Makefile.am: ignore automake-supplied ylwrap + +2008-05-15 Will Estes + + * NEWS, flex.skl: clean up types; resolves 1961902 + +2008-05-15 Will Estes + + * NEWS: update NEWS re manual + +2008-05-15 Will Estes + + * doc/flex.texi: correct eroneous references to 'nowrap' to refer to + 'noyywrap'; resolves bug #1739912 + +2008-05-14 Will Estes + + * filter.c: call clearerr on stdin before dup2'ing it; resolves bug + #1902612 + +2008-05-14 Will Estes + + * NEWS: generic updates to NEWS + +2008-05-14 Will Estes + + * tests/test-pthread/Makefile.am: move library flags in linker + command; resolves patch #1943403; patch submitted by + nullnix@users.sourceforge.net + +2008-05-14 Will Estes + + * doc/flex.texi: use ansi syntax in simple examples; resolves patch + #1909844; patch submitted by Tom Browder, + tbrowder2@users.sourceforge.net + +2008-04-10 Will Estes + + * doc/flex.texi: fix typo in example (from Paolo J. Matos + +2008-04-10 Will Estes + + * flexint.h: move endif to better account for what C99 defines for + integer types (fix from debian project) + +2008-04-10 Will Estes + + * gen.c: fix another int type to be size_t + +2008-03-30 Will Estes + + * NEWS, po/fr.po: new fr translation + +2008-03-30 Will Estes + + * NEWS, configure.in: start version 2.5.36 + +2008-02-26 Will Estes + + * NEWS: add date of release + +2008-02-15 Will Estes + + * NEWS, parse.y: fix bug that prevented comments from working + properly + +2008-02-12 Will Estes + + * po/de.po: new de translation + +2008-02-10 Will Estes + + * NEWS, po/vi.po: new vi translation + +2008-02-10 Will Estes + + * NEWS, po/nl.po: new nl translation + +2008-02-09 Will Estes + + * NEWS, po/pl.po: new pl translation + +2008-02-09 Will Estes + + * NEWS, po/de.po, po/pt_BR.po: new de, pt_br translations + +2008-02-09 Will Estes + + * NEWS, flex.skl: generate headers for all functions (resolves bug + #1628314) + +2008-02-09 Will Estes + + * NEWS, flex.skl: change yy_size_t to be size_t (resolves bug + #1849812) + +2008-02-09 Will Estes + + * configure.in: start work on version 2.5.35 + +2007-12-12 Will Estes + + * NEWS, configure.in: revert NEWS and configure.in to version 2.5.34 + +2007-09-12 Will Estes + + * NEWS, configure.in: update version number to 2.5.35 + +2007-09-10 Aaron Stone + + * tests/test-alloc-extra/scanner.l: Use %option extra-type. + +2007-09-10 Aaron Stone + + * NEWS, doc/flex.texi, flex.skl, flexdef.h, main.c, parse.y, scan.l: + Introduce %option extra-type="your_type *" (resolves bug #1744505). + +2007-08-15 Will Estes + + * po/nl.po: new nl translations from the translation project + +2007-06-28 Will Estes + + * NEWS: change release date + +2007-06-28 Will Estes + + * flex.skl: adjustment for prefix classes; patch submitted by Petr + Machata + +2007-06-28 Will Estes + + * NEWS: NEWS item for yy_init_extra + +2007-06-12 Aaron Stone + + * doc/flex.texi: Docs and example for yylex_init_extra. + +2007-06-01 Will Estes + + * tests/test-alloc-extra/.cvsignore: ignore OUTPUT file in + test-alloc-extra + +2007-06-01 Will Estes + + * tests/descriptions: add description of concatenated options test + +2007-05-31 Will Estes + + * tests/test-alloc-extra/.cvsignore: add missing .cvsignore to + test-alloc-extra + +2007-05-31 Aaron Stone + + * configure.in, flex.skl, gen.c, main.c: Changes to resolve SF bugs + 1568325 and 1563589. + +2007-05-31 Aaron Stone + + * tests/Makefile.am, tests/descriptions, + tests/test-alloc-extra/Makefile.am, + tests/test-alloc-extra/scanner.l, tests/test-alloc-extra/test.input: + Adding test cases for yylex_init_extra. + +2007-05-12 Will Estes + + * configure.in, tests/test-pthread/scanner.l: fixes to test-pthread + +2007-05-12 Will Estes + + * NEWS: NEWS item for concatenated options + +2007-05-12 Will Estes + + * configure.in, tests/Makefile.am, + tests/test-concatenated-options/.cvsignore, + tests/test-concatenated-options/Makefile.am: unit test to verify + concatenated options parsing + +2007-05-12 Will Estes + + * scanopt.c: parse multiple short concatenated options; patch + submitted by Petr Machata + + * autogen.sh: remove --force option from autogen.sh; much faster + without it + +2007-05-11 Will Estes + + * NEWS, configure.in: version 2.5.34 + +2007-05-08 Aaron Stone + + * NEWS, flex.skl: Better checking after yyalloc/yyrealloc (resolves + bug #1595967) + +2007-05-01 Will Estes + + * doc/flex.texi: change title of manual to 'Lexical Analysis with + Flex' + +2007-04-25 Will Estes + + * flex.skl: c++ memory leak plug + +2007-04-23 Will Estes + + * flex.skl: roll back c++ memory patch as it causes the test suite + no end of grief + +2007-04-23 Will Estes + + * flex.skl: fix function definitions for non-ANSI environments (from + Manoj Srivastava from Debian patchset) + +2007-04-23 Will Estes + + * flex.skl: fix c++ memory leak (from Manoj Srivastava from Debian + patchset) + +2007-04-23 Will Estes + + * flex.skl: fix parameter name in comment (patch from Manoj + Srivastava from the debian patchset + +2007-04-23 Will Estes + + * flex.skl: add a size_t cast (patch from Manoj Srivastava from the + debian patchset + +2007-04-16 Will Estes + + * tests/test-extended/Makefile.am, tests/test-quotes/Makefile.am: + cleanups to handle VPATH builds better; passifies make distcheck + +2007-04-16 Will Estes + + * doc/flex.texi: drop using the \ in \ escaping as it throws pdf + generation for a loop + +2007-04-14 Will Estes + + * .cvsignore: add compile and *.tar.bz2 to .cvsignore + +2007-04-14 Will Estes + + * main.c: add call to setlocale for ctype as per debian patchset + +2007-04-14 Will Estes + + * Makefile.am, NEWS: provide for a PIC version of libfl.a for shared + libraries using flex scanners + +2007-04-13 Will Estes + + * FlexLexer.h: annotate endifs since they're a bit far from their + opening #if statements + +2007-04-13 Will Estes + + * flexdef.h, parse.y: refactor and slightly redo alloca testing, + resolves bug #1675899 + +2007-04-13 Will Estes + + * : overhaul configure.in: use octathorps for comments so they're + passed through m4 processing; better bracketing of m4 arguments; + retool checks as per suggestions from autoscan(1) + +2007-04-13 Will Estes + + * flex.skl: fix skeleton for reentrant scanners + +2007-04-13 Will Estes + + * Makefile.am: remove homegrown tags target; automake does that for + us + +2007-04-12 Will Estes + + * flex.skl: fix skeleton for reentrant scanners, resolves bug + #1694318 + +2007-04-12 Will Estes + + * FlexLexer.h: declare some const where missing in c++ header file + +2007-04-10 Will Estes + + * doc/flex.texi: corrections to the manual as per suggestions from + flex-help@ + +2007-04-03 Will Estes + + * doc/flex.texi: include author names in online versions of the + manual + +2007-04-03 Will Estes + + * COPYING: update copyright notice + +2007-04-03 Will Estes + + * AUTHORS: rearrange and update AUTHORS + +2007-03-29 Will Estes + + * NEWS: note sf feature request 1658379 in NEWS + +2007-03-29 Will Estes + + * tools/cvsauthors: add sodabrew to cvsauthors file + +2007-03-29 Aaron Stone + + * flex.skl: SourceForge feature request #1658379: Expose YY_BUF_SIZE + in the header file. + +2007-03-07 Will Estes + + * NEWS, filter.c, flex.skl: apply patches submitted by sodabrew + +2007-03-07 Will Estes + + * README.cvs: more changes describing building flex from cvs + +2007-03-07 Will Estes + + * Makefile.am, README.cvs, README.cvs-snapshot: rename + README.cvs-snapshot to README.cvs + +2007-03-07 Will Estes + + * README.cvs-snapshot: update to explain where flex cvs lives + +2007-03-07 Will Estes + + * README, doc/flex.texi: correct how to submit bugs + +2007-02-16 Will Estes + + * NEWS: clarify NEWS item re man page and pdf manual + +2007-02-14 Will Estes + + * po/Makevars: update bug address to point to flex-devel instead of + lex-help + +2007-02-13 Will Estes + + * configure.in, doc/Makefile.am: make better use of AC_INIT; clean + up, simplify and make more robust the generation of the man page + +2007-02-13 Will Estes + + * configure.in: remove option check-news from call to + AM_INIT_AUTOMAKE as gnits implies check-news + +2007-02-13 Will Estes + + * Makefile.am, configure.in: move automake options from Makefile.am + to configure.in + +2007-02-13 Will Estes + + * autogen.sh: restore --install option to autogen.sh since --force + does not imply --install + +2007-02-13 Will Estes + + * tools/cvsauthors: add john43 to cvsauthors file + +2007-02-13 Will Estes + + * autogen.sh: call autoreconf with --force instead of --install + +2007-02-13 Will Estes + + * doc/.cvsignore: remove texinfo.tex from cvs tree + +2007-02-13 Will Estes + + * NEWS: updates to NEWS file to reflect recent changes + +2007-02-13 Will Estes + + * doc/Makefile.am: add flex.pdf to EXTRA_DIST + +2007-02-13 Will Estes + + * configure.in: remove flex.spec + +2007-02-13 Will Estes + + * Makefile.am: remove maintainercleanfiles + +2007-02-01 Will Estes + + * doc/Makefile.am: more changes to build system to distribute man + page + +2007-02-01 Will Estes + + * doc/Makefile.am: add flex man page to distribution + +2007-02-01 Will Estes + + * .cvsignore, flex.spec.in: remove flex spec file + +2006-11-17 Will Estes + + * tests/test-table-opts/Makefile.am: make test target depend on test + groupings, which in turn depend on building executables; cygwin + portability fix + +2006-11-10 Will Estes + + * tests/create-test: change create-test script to edit files in + place + +2006-11-09 Will Estes + + * tests/test-array-nr/Makefile.am, tests/test-array-r/Makefile.am, + tests/test-basic-nr/Makefile.am, tests/test-basic-r/Makefile.am, + tests/test-bison-nr/Makefile.am, + tests/test-bison-yylloc/Makefile.am, + tests/test-bison-yylval/Makefile.am, + tests/test-c++-basic/Makefile.am, + tests/test-c++-multiple-scanners/Makefile.am, + tests/test-c++-yywrap/Makefile.am, tests/test-c-cpp-nr/Makefile.am, + tests/test-c-cpp-r/Makefile.am, tests/test-ccl/Makefile.am, + tests/test-debug-nr/Makefile.am, tests/test-debug-r/Makefile.am, + tests/test-extended/Makefile.am, tests/test-header-nr/Makefile.am, + tests/test-header-r/Makefile.am, + tests/test-include-by-buffer/Makefile.am, + tests/test-include-by-push/Makefile.am, + tests/test-include-by-reentrant/Makefile.am, + tests/test-linedir-r/Makefile.am, tests/test-lineno-nr/Makefile.am, + tests/test-lineno-r/Makefile.am, tests/test-mem-nr/Makefile.am, + tests/test-mem-r/Makefile.am, + tests/test-multiple-scanners-nr/Makefile.am, + tests/test-multiple-scanners-r/Makefile.am, + tests/test-noansi-nr/Makefile.am, tests/test-noansi-r/Makefile.am, + tests/test-posix/Makefile.am, + tests/test-posixly-correct/Makefile.am, + tests/test-prefix-nr/Makefile.am, tests/test-prefix-r/Makefile.am, + tests/test-pthread/Makefile.am, tests/test-quotes/Makefile.am, + tests/test-reject/Makefile.am, tests/test-rescan-nr/Makefile.am, + tests/test-rescan-r/Makefile.am, tests/test-string-nr/Makefile.am, + tests/test-string-r/Makefile.am, tests/test-top/Makefile.am, + tests/test-yyextra/Makefile.am: change CLEANFILES to include + instead of just the testname for the executable + +2006-11-09 Will Estes + + * doc/flex.texi: fix typos in manual; resolves bug #1592857 + +2006-11-09 Will Estes + + * tests/TEMPLATE/Makefile.am: change test template to remove test + executable when that executable has an extension, e.g. under Cygwin + +2006-11-08 Will Estes + + * tests/Makefile.am: test names weren't displaying in test + success/failure messages (from #1591672 + +2006-10-30 Will Estes + + * doc/.cvsignore: add flex.html to .cvsignore in doc directory + +2006-10-22 Will Estes + + * NEWS: update NEWS file for the work that millaway did + +2006-10-22 Will Estes + + * FlexLexer.h, NEWS, main.c, + tests/test-c++-multiple-scanners/scanner-2.l: make yywrap work with + c++ scanners as per sf bug report + +2006-10-20 Will Estes + + * NEWS, flex.skl, tests/test-c++-multiple-scanners/main.cpp, + tests/test-c-cpp-nr/scanner.l: memory leak issues in c++ scanner + +2006-10-20 Will Estes + + * NEWS, configure.in, tests/Makefile.am, tests/descriptions, + tests/test-c++-yywrap/.cvsignore, + tests/test-c++-yywrap/Makefile.am, tests/test-c++-yywrap/scanner.l, + tests/test-c++-yywrap/test.input: add unit test for c++ with yywrap + +2006-10-20 Will Estes + + * NEWS, tests/test-c++-basic/Makefile.am, + tests/test-linedir-r/Makefile.am: use configure-provided awk + variable for portability; add loadlibes variable to c++ test + +2006-10-17 Will Estes + + * doc/flex.texi: add noyywrap option to example; use whitespace to + clarify example + +2006-08-02 Will Estes + + * NEWS, po/ca.po, po/vi.po: new translations + +2006-04-11 John Millaway + + * tables.c: Casted away signedness to appease -Werror freaks. + +2006-03-28 John Millaway + + * ccl.c, doc/flex.texi, flexdef.h, parse.y, scan.l, sym.c, + tests/test-ccl/scanner.l, tests/test-ccl/test.input: Added ccl union + operator. Added test in test suite for ccl union operator. + Documented ccl union operator. Removed crufty ccl cache to prevent + parser problems. + +2006-03-28 John Millaway + + * doc/flex.texi, scan.l, tests/test-extended/scanner.l, + tests/test-extended/test.input: Extended syntax excluded for + lex/posix compat mode. Comments discarded inside (?x:) patterns. + Added test in test suite for comments in extended patterns. + Documented syntax additions. + +2006-03-27 John Millaway + + * scan.l, tests/test-ccl/scanner.l, tests/test-ccl/test.input: + Implemented (?x:) syntax to allow whitespace in patterns. Added + test for (?x:) syntax in test suite. + +2006-03-27 John Millaway + + * parse.y, tests/test-ccl/scanner.l, tests/test-ccl/test.input: + Implemented dot-all syntax. Added test for dot-all syntax in test + suite. + +2006-03-27 John Millaway + + * dfa.c, doc/flex.texi, flexdef.h, gen.c, main.c, parse.y, scan.l, + scanflags.c, tests/test-ccl/scanner.l, tests/test-ccl/test.input: + Removed global variable caseins. Added scanner stack flags for + case-insensitivity. Moved case-folding code from DFA-generation to + parse time read-macros. Added localized case-sensitivity syntax + from Perl. Added test for new syntax in test suite. Documented new + syntax. + +2006-03-27 John Millaway + + * Makefile.am, configure.in, flexdef.h, scanflags.c: Added configure + check for assert.h. Added scanner flags stack. + +2006-03-25 John Millaway + + * configure.in, doc/flex.texi, scan.l, tests/Makefile.am, + tests/descriptions, tests/test-extended/.cvsignore, + tests/test-extended/Makefile.am, tests/test-extended/scanner.l, + tests/test-extended/test.input: Added extended, perl-compatible + comment syntax. Added test for extended comment syntax. Documented + extended comment syntax. + +2006-03-25 John Millaway + + * doc/flex.texi, parse.y: Changed explicit 'A'-'Z' to isupper(), + where correct to do so. Documentation. + +2006-03-24 John Millaway + + * doc/flex.texi: Documentation. + +2006-03-24 John Millaway + + * doc/flex.texi: Added appendix of patterns to manual. + +2006-03-23 John Millaway + + * doc/flex.texi: . + +2006-03-22 John Millaway + + * doc/flex.texi: Documentation. + +2006-03-22 John Millaway + + * doc/flex.texi: Documented set difference operator {-}. + +2006-03-22 John Millaway + + * ccl.c, flexdef.h, parse.y, scan.l, tests/test-ccl/scanner.l, + tests/test-ccl/test.input: Added set difference operator {-} for + character classes. + +2006-03-22 John Millaway + + * configure.in, doc/flex.texi, parse.y, scan.l, tests/Makefile.am, + tests/descriptions, tests/test-ccl/.cvsignore, + tests/test-ccl/Makefile.am, tests/test-ccl/scanner.l, + tests/test-ccl/test.input: Added negated character class + expressions. Documented negated character class expressions. Added + regression test for negated character class expressions. + +2006-03-22 John Millaway + + * buf.c, filter.c, gen.c, main.c, misc.c, nfa.c, parse.y, regex.c: + Replaced sprintf with snprintf everywhere. + +2006-03-22 John Millaway + + * Makefile.am: Removed includedir from AM_CPPFLAGS #1439351. + +2006-03-21 John Millaway + + * configure.in, tests/Makefile.am, tests/descriptions, + tests/test-quotes/.cvsignore, tests/test-quotes/Makefile.am, + tests/test-quotes/scanner.l, tests/test-quotes/test.input: Added + test to verify user code is unmangled. + +2006-03-21 John Millaway + + * flexdef.h, misc.c, scan.l: Fixed escape in actions. + +2006-03-21 John Millaway + + * filter.c, flexdef.h, main.c, scan.l: Reverted previous input + filter changes. Added noop macro to scanner output. Modified + scan.l to escape m4 quotes found in user code. + +2006-03-21 John Millaway + + * tests/test-table-opts/Makefile.am, + tests/test-table-opts/scanner.l: Removed m4 from test-table-opts + +2006-03-21 John Millaway + + * tests/test-reject/Makefile.am, tests/test-reject/scanner.l: + Removed m4 from test-reject + +2006-03-21 John Millaway + + * filter.c, flexdef.h, main.c, scan.l: Moved set_input_file to + different file. + +2006-03-21 John Millaway + + * flex.skl, flexdef.h, flexint.h, misc.c: Relaxed tests for __STDC__ + and __STDC_VERSION__ to cope with bugs in GCC and Sun cc. + +2006-03-20 John Millaway + + * filter.c: Documented filter chain. Removed fdopen. Added no-op + fseek. + +2006-03-13 John Millaway + + * gen.c: Fixed another -Wall report. + +2006-03-10 Will Estes + + * NEWS, po/vi.po: new vi translation + +2006-03-09 Will Estes + + * NEWS, po/ga.po, po/nl.po: new nl, ga translations + +2006-02-21 Will Estes + + * m4/Makefile.am: add po.m4 to extra_dist in m4/ so it gets picked + up by distributions + +2006-02-21 Will Estes + + * m4/Makefile.am: add nls.m4 to extra_dist in m4/ so it will get + picked up in distribution tarballs + +2006-02-21 Will Estes + + * configure.in: remove website directory from configure.in + +2006-02-20 Will Estes + + * NEWS, configure.in: version 2.5.33 marks in NEWS and configure.in + +2006-02-20 Will Estes + + * configure.in: change email address in configure.in to point to + flex-help@sourceforge.net + +2006-02-20 John Millaway + + * doc/flex.texi: Documentation. + +2006-02-20 John Millaway + + * BUGS: Appended to BUGS file. + +2006-02-18 Will Estes + + * Makefile.am: remove website directory (since it now has its own + module in the flex project + +2006-02-16 John Millaway + + * doc/flex.texi, flex.skl: Fixed buffer overflow in reject state + buffer. Corrected documentation on the state buffer. + +2006-02-16 John Millaway + + * flex.skl: Reverted num_read from size_t back to int. + +2006-02-15 John Millaway + + * Makefile.am, configure.in: Removed reference to RoadMap in + Makefile.am. Added website directory. + +2006-02-15 Will Estes + + * README, RoadMap: remove RoadMap and reference to it in README + +2006-02-15 John Millaway + + * BUGS, README, doc/flex.texi, doc/flex.xml: Eliminated references + to lex.sf.net. + +2006-02-15 John Millaway + + * BUGS, flex.skl: Transfered bugs list from lex.sf.net to BUGS file. + +2006-02-15 John Millaway + + * tests/test-rescan-nr/.cvsignore, + tests/test-rescan-nr/Makefile.am, tests/test-rescan-nr/scanner.l, + tests/test-rescan-nr/test.input, tests/test-rescan-r/.cvsignore, + tests/test-rescan-r/Makefile.am, tests/test-rescan-r/scanner.l, + tests/test-rescan-r/test.input: Recommit of last commit -- broken + pipe. + +2006-02-15 John Millaway + + * configure.in, flex.skl, tests/Makefile.am, tests/descriptions: + yy_lex_destroy calls yy_init_globals to reset everything for next + call to yylex. Added two new tests for reusing scanners. + +2006-02-14 John Millaway + + * flex.spec.in: Patched rpm spec file. + +2006-02-14 John Millaway + + * configure.in, flexint.h: Added C99 macro for inttypes, just to be + conformant. + +2006-02-14 John Millaway + + * flexdef.h, nfa.c, parse.y: Changed symbol INFINITE to fix conflict + with C math symbol. + +2006-02-14 John Millaway + + * scan.l: Omitting parens for named rules in trailing context. + +2006-02-14 John Millaway + + * configure.in, main.c, po/ca.po, po/da.po, po/de.po, po/es.po, + po/fr.po, po/ga.po, po/ko.po, po/nl.po, po/pl.po, po/pt_BR.po, + po/ro.po, po/ru.po, po/sv.po, po/tr.po, po/vi.po, po/zh_CN.po, + tests/test-mem-nr/scanner.l, tests/test-mem-r/scanner.l: Added check + for locale.h and libintl.h in configure script. + +2006-02-14 John Millaway + + * flex.skl: Removed unused local vars. + +2006-02-14 John Millaway + + * flex.skl: Removed certain offending #undefs. + +2006-02-14 John Millaway + + * flexint.h: Removed logical and from preprocessor statement. + +2006-02-14 Will Estes + + * po/nl.po, po/nl.po.1: remove eroneously named nl.po.1; update + nl.po + +2006-02-14 John Millaway + + * dfa.c: . + +2006-02-14 John Millaway + + * flex.skl: Included for serialized tables. + +2006-02-14 John Millaway + + * configure.in: Minor patch to call to head in configure script. + +2006-02-14 John Millaway + + * doc/flex.texi: Documentation patch. + +2006-02-14 John Millaway + + * filter.c, gen.c, libyywrap.c, main.c: Patch for full file system + failure. + +2006-02-13 John Millaway + + * doc/flex.texi: Documentation. + +2006-02-13 John Millaway + + * main.c: Fixed double-fclose when input file is empty. + +2006-02-10 Will Estes + + * po/ca.po, po/da.po, po/de.po, po/es.po, po/fr.po, po/ga.po, + po/ko.po, po/nl.po.1, po/pl.po, po/pt_BR.po, po/ro.po, po/ru.po, + po/sv.po, po/tr.po, po/vi.po, po/zh_CN.po: newtranslations + +2005-12-22 John Millaway + + * buf.c, main.c: Improvement request 1069716 log vs. log10 + +2005-12-22 John Millaway + + * flex.skl: Fixed bug 1257093 yy_init_globals in header file + +2005-04-14 Will Estes + + * po/nl.po: new nl translation + +2005-04-07 Will Estes + + * NEWS, po/LINGUAS, po/nl.po, po/vi.po: new nl and vi translations + +2004-07-20 Will Estes + + * filter.c: correct improper stdin assignment + +2004-05-22 Will Estes + + * NEWS, po/tr.po: new tr translation + +2004-05-12 Will Estes + + * .cvsignore, .indent.pro: .cvsignore and .indent.pro got missed in + the import to sourceforge; replace them + +2004-05-11 Will Estes + + * po/fr.po: new fr translation + +2004-05-03 Will Estes + + * po/LINGUAS: polish is pl, not po + +2004-03-22 Will Estes + + * po/sv.po: yet another sweedish update + +2004-03-19 Will Estes + + * NEWS, po/sv.po: new sv translation + +2003-12-11 John Millaway + + * configure.in, filter.c, main.c: Configure checks for GNU m4. + Environment variable M4 overrides built-in m4 path. Generated m4 + does a late check for GNU m4. + +2003-12-09 John Millaway + + * doc/flex.texi: added 3 faqs + +2003-11-24 Will Estes + + * po/ro.po: new ro translation + +2003-11-07 Will Estes + + * NEWS, po/fr.po: new french translation + +2003-11-07 Will Estes + + * NEWS, po/ca.po: new catalan translation from the translation + project + +2003-11-07 Will Estes + + * NEWS, po/LINGUAS, po/ga.po, po/pl.po: new polish translation; + updated irish translation from translation project + +2003-10-10 Will Estes + + * NEWS, po/LINGUAS, po/ga.po: new Irish translation + +2003-08-25 Will Estes + + * NEWS, po/LINGUAS, po/ro.po: add romanian translation + +2003-07-16 Will Estes + + * flex.skl: flex_*int* type fixes + +2003-07-16 Will Estes + + * tools/cvsauthors: change wlestes email address + +2003-07-16 Will Estes + + * flex.skl: undef yytext_ptr has some bad side effects + +2003-07-07 John Millaway + + * doc/flex.texi: Documented m4 incompatibility with lex. + +2003-05-21 Will Estes + + * NEWS: upgrade to gettext 0.12 + +2003-05-20 Will Estes + + * flex.skl, gen.c: patches from manoj via sourceforge + +2003-05-20 Will Estes + + * configure.in, po/.cvsignore, po/Makevars: upgrade gettext to 0.12; + this allows running make pdf and make ps to be successful + +2003-05-20 Will Estes + + * doc/.cvsignore: cvs should ignore flex.pdf and flex.ps + +2003-04-25 John Millaway + + * TODO: Added yylineno bugs to TODO list. + +2003-04-03 John Millaway + + * doc/flex.xml: Docbook. + +2003-04-03 John Millaway + + * doc/flex.xml: xml now validates. + +2003-04-02 John Millaway + + * doc/flex.xml: Began conversion to DocBook. + +2003-04-01 Will Estes + + * NEWS, configure.in: version 2.5.31 + +2003-04-01 Will Estes + + * NEWS: remove --enable-maintainer-mode configure option + +2003-04-01 Will Estes + + * configure.in: remove AM_MAINTAINER_MODE + +2003-04-01 John Millaway + + * flex.skl, flexdef.h, main.c, misc.c, scan.l: Renamed some internal + variables. + +2003-03-31 Will Estes + + * NEWS: yylineno is now per-buffer in reentrant scanners + +2003-03-31 John Millaway + + * TODO: Added TODO item. + +2003-03-30 John Millaway + + * flex.skl, gen.c: yylineno is per-buffer in the reentrant scanner. + support for yycolumn exists, but is not yet developed. + +2003-03-28 John Millaway + + * flex.skl: Minor documentation. + +2003-03-28 Will Estes + + * NEWS: added %top directive + +2003-03-27 John Millaway + + * buf.c, configure.in, doc/flex.texi, flexdef.h, main.c, scan.l, + tests/Makefile.am, tests/descriptions, tests/test-top/.cvsignore, + tests/test-top/Makefile.am, tests/test-top/main.c, + tests/test-top/scanner.l, tests/test-top/test.input: Added %top + block syntax. Added test for %top block. Documented %top block. + +2003-03-27 John Millaway + + * TODO, doc/flex.texi: Documented the m4 dependency. + +2003-03-26 Will Estes + + * configure.in, flexdef.h: check for sys/wait.h since we use wait(2) + +2003-03-26 Will Estes + + * flexdef.h: reorder include directives so as to catch system + integer types before flex defined values for same + +2003-03-26 Will Estes + + * TODO: assign tasks due before major release can happen; remove + --enable-maintainer-mode entry + +2003-03-26 Will Estes + + * Makefile.am: only rebuild the ChangeLog if we're inside a cvs + working directory + +2003-03-26 Will Estes + + * configure.in, tools/.cvsignore, tools/Makefile.am: add tools/ + subdirectory to distribution + +2003-03-26 Will Estes + + * Makefile.am: remove maintainer_mode conditional; add filter.c and + regex.c to indentfiles; reformat and sort indentfiles so it's easier + to add files in the future + +2003-03-26 Will Estes + + * doc/Makefile.am: clean up flex.texi processing leftovers with + cleanfiles + +2003-03-26 Will Estes + + * tests/test-linedir-r/Makefile.am: an awk script wasn't included in + the distribution + +2003-03-26 John Millaway + + * TODO, configure.in, tests/Makefile.am, tests/descriptions, + tests/test-include-by-push/.cvsignore, + tests/test-include-by-push/Makefile.am, + tests/test-include-by-push/scanner.l, + tests/test-include-by-push/test-1.input, + tests/test-include-by-push/test-2.input, + tests/test-include-by-push/test-3.input: Added test for + yypush_buffer_state and yypop_buffer_state. + +2003-03-26 John Millaway + + * TODO: Removed items from TODO list. + +2003-03-26 John Millaway + + * configure.in, tests/Makefile.am, tests/descriptions, + tests/test-linedir-r/.cvsignore, tests/test-linedir-r/Makefile.am, + tests/test-linedir-r/check-lines.awk, tests/test-linedir-r/main.c, + tests/test-linedir-r/scanner.l, tests/test-linedir-r/test.input: + Added test for #line directives. + +2003-03-26 John Millaway + + * configure.in, tests/Makefile.am, tests/test-noansi-nr/.cvsignore, + tests/test-noansi-nr/Makefile.am, tests/test-noansi-nr/scanner.l, + tests/test-noansi-nr/test.input, tests/test-noansi-r/.cvsignore, + tests/test-noansi-r/Makefile.am, tests/test-noansi-r/scanner.l, + tests/test-noansi-r/test.input: Added test for noansi (traditional) + options. Reordered the tests so the basic ones are first. + +2003-03-25 Will Estes + + * TODO, doc/Makefile.am: remove maintainer-mode conditional around + rebuilding of manpage + +2003-03-25 Will Estes + + * README: mention doc/ for user documentation + +2003-03-25 Will Estes + + * TODO: rework distribution items + +2003-03-25 Will Estes + + * NEWS: mention m4 processing + +2003-03-25 Will Estes + + * tests/README: update instructions for running test suite + +2003-03-25 Will Estes + + * FlexLexer.h, Makefile.am, TODO, buf.c, configure.in, + doc/flex.texi, filter.c, flex.skl, flexdef.h, gen.c, main.c, + misc.c, options.c, options.h, regex.c, scan.l, sym.c, + tests/test-bison-nr/scanner.l, tests/test-bison-yylloc/scanner.l, + tests/test-reject/scanner.l, tests/test-table-opts/scanner.l: merge + millaway's m4 branch work + +2003-03-24 John Millaway + + * doc/flex.texi, flex.skl, flexdef.h, gen.c, main.c, options.c, + options.h, scan.l: Option ansi-definitions. Option ansi-prototypes. + Cleaned up some of header. Documented bison-locations. + +2003-03-24 John Millaway + + * scan.l: Escaped m4 macros in scan.l which would cause + bootstrapping issues. + +2003-03-21 John Millaway + + * doc/flex.texi, flex.skl, main.c: Cleaning up the skel. + +2003-03-20 Will Estes + + * TODO: we want to move the contents of to.do/Wishlist to top level + TODO + +2003-03-20 John Millaway + + * to.do/Wish-List: Assessment of every item in Wish-List. + +2003-03-19 John Millaway + + * main.c: Fixed allocation of slightly more memory than needed. + +2003-03-19 John Millaway + + * TODO, buf.c, configure.in, flex.skl, flexdef.h, main.c, sym.c: + Start conditions now generated in a single place. + +2003-03-19 Will Estes + + * TODO: cosmetic changes to TODO list + +2003-03-19 John Millaway + + * flex.skl: Cleaned up warnings so multiple headers could coincide. + +2003-03-19 John Millaway + + * TODO, flex.skl, main.c: Moved prefixes to m4. + +2003-03-19 John Millaway + + * FlexLexer.h, filter.c, flex.skl, flexdef.h, main.c, misc.c, + regex.c: Removed Paxson/Berkeley copyright restriction from filter.c + and regex.c. Inline documentation of much of the generated API. + Line directives now fixed for header and stdin/stdout. Blank lines + squeezed from generated scanner. + +2003-03-18 John Millaway + + * filter.c, flexdef.h, main.c, regex.c: Fixed #line directives. + +2003-03-17 John Millaway + + * Makefile.am, filter.c, flexdef.h, regex.c: Added regex.c for + regex-related code. Worked on fixing line directives;incomplete. + +2003-03-14 John Millaway + + * TODO: Added some TODOs. + +2003-03-14 John Millaway + + * flexdef.h, main.c, options.c, options.h, scan.l, + tests/test-bison-nr/scanner.l, tests/test-bison-yylloc/scanner.l: + Bison bridge was simplified to rely less on bison output. New + option bison-locations. + +2003-03-14 John Millaway + + * filter.c, flex.skl, flexdef.h, gen.c, main.c, scan.l, + tests/test-reject/scanner.l: Filters are now direct children of main + process. Header file now generated through m4. + +2003-03-14 John Millaway + + * buf.c, filter.c, flexdef.h, main.c, misc.c: Added internal filter + ability. Deleted various unused variables. + +2003-03-14 John Millaway + + * main.c, tests/test-table-opts/scanner.l: Keeping tests up to date + with m4 changes. Proper wait for all children. + +2003-03-14 John Millaway + + * flex.skl, tests/test-table-opts/scanner.l: Moved test-tables to + m4. + +2003-03-14 John Millaway + + * flex.skl, main.c, options.c: Moved bison bridge code to m4. + +2003-03-13 John Millaway + + * flex.skl, gen.c, main.c, scan.l: Moved YY_USE_LINENO to m4. + +2003-03-13 John Millaway + + * buf.c, flexdef.h, scan.l: Added function buf_m4_undefine. + +2003-03-13 John Millaway + + * flex.skl, main.c, scan.l: Replaced YY_ALWAYS_INTERACTIVE with m4. + Replaced YY_NEVER_INTERACTIVE with m4. + +2003-03-13 John Millaway + + * flex.skl, main.c: Moved YY_TEXT_IS_ARRAY to m4. + +2003-03-12 John Millaway + + * flex.skl, gen.c, main.c, tests/test-reject/scanner.l: Renaming + macros from YY_* to M4_YY_* where appropriate. + +2003-03-12 John Millaway + + * flex.skl, tests/test-reject/scanner.l, + tests/test-table-opts/scanner.l: Now using local variable "yyg" + instead of lengthly YY_G expansion. + +2003-03-12 John Millaway + + * buf.c, filter.c, flex.skl, flexdef.h, main.c, misc.c, options.c, + options.h, scan.l, tests/test-reject/scanner.l: More m4 macro + conversions. Added debugging option --preproc-level=NUM. + +2003-03-11 John Millaway + + * Makefile.am, buf.c, flex.skl, flexdef.h, gen.c, main.c, misc.c, + scan.l: Replaced many CPP macros with m4 equivalents. + +2003-03-10 John Millaway + + * Makefile.am, filter.c, flex.skl, flexdef.h, main.c, misc.c: Added + filter.c Added filter.c rules to Makefile.am Added filter prototypes + to flexdef.h Flex now filters output through m4. + +2003-03-05 Will Estes + + * doc/.cvsignore, texinfo.tex: move texinfo.tex to doc/ + +2003-03-05 Will Estes + + * TODO: update TODO + +2003-03-05 Will Estes + + * NEWS, configure.in: version 2.5.29 + +2003-03-04 John Millaway + + * FlexLexer.h, flex.skl: Added growable buffer stack to C++ scanner + as well. yyensure_buffer_stack is now static. + +2003-03-02 John Millaway + + * flex.skl, misc.c: Removed awkward %push %pop syntax from skeleton. + +2003-03-02 John Millaway + + * flex.skl: Renamed YY_CURRENT_BUFFER_FAST to + YY_CURRENT_BUFFER_LVALUE to better reflect its purpose. + +2003-02-28 John Millaway + + * NEWS: made entry on input buffer stacks. + +2003-02-28 Will Estes + + * Makefile.am, doc/Makefile.am: build on . in top level first; this + will simplify calling help2man + +2003-02-28 John Millaway + + * TODO, doc/flex.texi, flex.skl, gen.c, main.c: Removed + yy_current_buffer from the planet. Input buffer states are now in + an internal unbounded stack. Added new internal function, + yyensure_buffer_stack. Added new API function, yypush_buffer_state. + Added new API function, yypop_buffer_state. Documented the new API + calls in the manual. Macro YY_BUFFER_STATE now refers to top of + stack. This revision breaks the C++ scanner (again.) + +2003-02-28 John Millaway + + * main.c: Removed some symbols from the undef list. They are needed + for multiple headers to coexist. + +2003-02-27 Will Estes + + * Makefile.am, NEWS, configure.in, doc/.cvsignore, doc/Makefile.am, + doc/flex.texi, flex.texi: move flex.texi and flex.1 to new doc/ + subdirectory + +2003-02-27 Will Estes + + * NEWS: namespace cleanups + +2003-02-26 John Millaway + + * main.c: Added a few macros to the undef list. + +2003-02-26 John Millaway + + * main.c: Put the undef macros in an array. + +2003-02-12 Will Estes + + * NEWS, configure.in: version 2.5.28 + +2003-02-10 Will Estes + + * README, TODO, configure.in, flex.texi: update documentation to + reflect the sourceforge move + +2003-02-06 Will Estes + + * TODO: update according to current thinking + +2003-02-06 Will Estes + + * TODO: mcvs reviewed + +2003-02-06 Will Estes + + * TODO: sourceforge migration tasks + +2003-02-04 Will Estes + + * NEWS: Flex now warns if always-interactive is specified with fast + or full; Fixed trailing slash bug in YY_INPUT macro def + +2003-01-31 John Millaway + + * scan.l: Flex now warns if always-interactive is specified with + fast or full. + +2003-01-31 Will Estes + + * Makefile.am: switch to using cvs2cl.pl to generate the ChangeLog + +2003-01-31 Will Estes + + * tools/cvs2cl.pl, tools/cvsauthors: we're going to be switching how + we handle our ChangeLog + +2003-01-29 John Millaway + + * gen.c, misc.c: Fixed trailing slash bug in YY_INPUT macro def. + +2003-01-29 Will Estes + + * README.cvs-snapshot: upgrade texinfo to 4.3d + +2003-01-29 Will Estes + + * flex.texi: the @copying construct works now; thanks to the texinfo + maintainers for finding the problem + +2003-01-21 Will Estes + + * NEWS, configure.in: version 2.5.27 + +2003-01-21 Will Estes + + * NEWS: flex now works with recent bison versions + +2003-01-18 John Millaway + + * flex.skl: Check for YYLTYPE_IS_DECLARED. This fixes bison-bridge + with latest bison. + +2003-01-15 Will Estes + + * NEWS, po/pt_BR.po: new pt_br translation + +2003-01-14 Will Estes + + * NEWS, configure.in: version 2.5.26 + +2003-01-14 Will Estes + + * NEWS: Fixed table deserialization bug on big-endian archs. Patch + sent from Bryce Nichols + +2003-01-12 John Millaway + + * tables_shared.h: Fixed table deserialization bug on big-endian + archs. Patch sent from Bryce Nichols . + +2003-01-10 Will Estes + + * README.cvs-snapshot: add version numbers for some tools and + explain about version.texi and --enable-maintainer-mode + +2003-01-10 Will Estes + + * NEWS: catch news up + +2003-01-09 John Millaway + + * tests/test-mem-nr/scanner.l, tests/test-mem-r/scanner.l: Changed + size_t to yy_size_t in yyalloc() and yyrealloc(). Is this really + what we want? + +2003-01-09 John Millaway + + * flex.skl: Changed type of yyleng from size_t to int. This fixes + bug in PostgreSQL compilation. + +2003-01-09 Will Estes + + * NEWS: catch news up + +2003-01-09 Will Estes + + * flex.skl: more c++ fixes + +2003-01-09 Will Estes + + * Makefile.am, configure.in, flex.spec.in: add a spec file + +2003-01-09 Will Estes + + * flex.skl: type cast to pacify c++ compilers; patch from Bruce + Lilly + +2003-01-08 Will Estes + + * NEWS: new es translation + +2003-01-08 Will Estes + + * po/es.po: new spanish translation + +2002-12-19 John Millaway + + * gen.c: Fixed bug where YY_G(0) sometimes occurs (created by my + previous commit.) + +2002-12-17 John Millaway + + * gen.c: Fixed bug submitted by Bojan Smojver + where the use of yylineno, reentrant, and yymore together caused a + compile-time error. + +2002-12-17 Will Estes + + * NEWS: update NEWS + +2002-12-17 John Millaway + + * flex.texi: Documented new behavior with character ranges. + +2002-12-16 John Millaway + + * parse.y: Fixed bug submitted by Bruce Lilly + where character ranges would yield unexpected behavior in a caseless + scanner. Also, flex now emits a warning if the range looks like + trouble. + +2002-12-16 John Millaway + + * ccl.c, flexdef.h: Added utility functions to deal with character + case. + +2002-12-09 Will Estes + + * flexint.h: we don't really need int64 anyway + +2002-12-09 Will Estes + + * flex.skl: apparently some lints are happier with fllthrough + without a space + +2002-12-02 Will Estes + + * NEWS, configure.in: version 2.5.25 + +2002-12-02 Will Estes + + * Makefile.am: enclose flex.1 target in MAINTERNER_MODE + +2002-12-02 Will Estes + + * po/pt_BR.po: new pt_br translation + +2002-12-01 John Millaway + + * flex.texi: Indexed some more faqs. + +2002-11-29 John Millaway + + * flex.skl: Fixed bug in SECOND yyless definition where argument was + not enclosed in parentheses. + +2002-11-29 John Millaway + + * flex.skl: Fixed bug in yyless definition where argument was not + enclosed in parentheses. + +2002-11-27 Will Estes + + * NEWS: flex uses flex_int*_t types + +2002-11-27 Will Estes + + * flexint.h: integer types for non-C99 systems flexint.h + +2002-11-27 John Millaway + + * dfa.c, flexint.h, gen.c, tables.c, tables.h, tables_shared.c, + tables_shared.h: Changed int types to flex_intX_t. The build is now + broken until typedef's are established. + +2002-11-27 Will Estes + + * Makefile.am: MAINTAINERCLEANFILES: new variable: try to make it so + that make maintainer-clean erases everything not under version + control + +2002-11-27 Will Estes + + * config.rpath: remove config.rpath + +2002-11-27 Will Estes + + * README-alpha: just list location of betas + +2002-11-26 Will Estes + + * flexint.h: __STDC_VERSION__ needs an L suffix + +2002-11-26 Will Estes + + * NEWS, po/LINGUAS, po/pt_BR.po: new pt_br translation from the + translation project + +2002-11-25 Will Estes + + * flexint.h: include inttypes.h for folks who really are C99 + +2002-11-25 Will Estes + + * TODO: fix a typo + +2002-11-25 Will Estes + + * NEWS, configure.in: version 2.5.24 + +2002-11-23 Will Estes + + * configure.in: try to make sure we have GNU m4 + +2002-11-23 Will Estes + + * tests/test-c++-multiple-scanners/Makefile.am: include + tests/test-c++-multipl-scanners/test.input + +2002-11-23 Will Estes + + * NEWS: more portability fixes + +2002-11-23 Will Estes + + * configure.in, flexdef.h: apparently on some BSD systems, we need + sys/params.h; reported by millaway + +2002-11-22 Will Estes + + * NEWS: update NEWS + +2002-11-22 John Millaway + + * flex.skl, main.c, tests/test-c++-multiple-scanners/Makefile.am: + Fixed prefix of yyalloc,yyfree,yyrealloc in C++ scanner. Removed + yylex_destroy from C++ scanner. + +2002-11-22 John Millaway + + * flex.texi: renamed some faqs. + +2002-11-22 Will Estes + + * AUTHORS: update wording about authorship + +2002-11-17 John Millaway + + * parse.y: Removed space before line num in error messages to look + more like gcc's errors. + +2002-11-06 Will Estes + + * NEWS, po/tr.po: new turkish translation from the translation + project + +2002-10-28 Will Estes + + * gen.c: applied c++ from lilypond folks for std:: reasons + +2002-10-25 Will Estes + + * flex.texi: proofreading + +2002-10-24 Will Estes + + * flex.texi: proofreading + +2002-10-22 Will Estes + + * flex.skl: use c-style header names in c++ for now; at some point + we'll have a separate c++ skeleton and we can go whole-hog pure c++ + +2002-10-22 Will Estes + + * TODO: c++ rants + +2002-10-22 Will Estes + + * flex.texi: more proofreading + +2002-10-22 Will Estes + + * Makefile.am: include intent.pro; indent target is MAINTAINER_MODE + conditional + +2002-10-22 Will Estes + + * configure.in: When we use AC_PATH_PROG, value-if-not-found is the + name of the program we wanted to find; this will generate more + helpful error messages + +2002-10-21 John Millaway + + * tables.c: Added a missing function prototype. + +2002-10-21 Will Estes + + * NEWS, configure.in: version 2.5.23 + +2002-10-21 Will Estes + + * NEWS: update NEWS on recent changes + +2002-10-21 Will Estes + + * flexint.h: use sys/types.h and not inttypes.h + +2002-10-21 Will Estes + + * configure.in: check for limits.h + +2002-10-21 Will Estes + + * TODO: update TODO on recent suggestions + +2002-10-21 Will Estes + + * flex.texi: titlepage and contents + +2002-10-21 Will Estes + + * Makefile.am: typo + +2002-10-21 Will Estes + + * Makefile.am, README.cvs-snapshot: include README.cvs-snapshot in + the distribution; in README-cvs-snapshot, mention the need for + enable-maintainer-mode + +2002-10-21 John Millaway + + * flex.texi: typo. + +2002-10-18 Will Estes + + * flex.texi: report the current version info that flex provides; + reformat a list of non-posix features + +2002-10-18 Will Estes + + * NEWS: report the current version info that flex provides + +2002-10-18 Will Estes + + * flex.skl: FLEX_BETA defined if flex is beta + +2002-10-16 Will Estes + + * flexint.h: if we're doing c++, then we can't use long long + +2002-10-14 Will Estes + + * TODO: update TODO on several things + +2002-10-11 Will Estes + + * flex.texi: more proofreading + +2002-10-11 Will Estes + + * tests/TEMPLATE/Makefile.am, tests/test-array-nr/Makefile.am, + tests/test-array-r/Makefile.am, tests/test-basic-nr/Makefile.am, + tests/test-basic-r/Makefile.am, tests/test-bison-nr/Makefile.am, + tests/test-bison-yylloc/Makefile.am, + tests/test-bison-yylval/Makefile.am, + tests/test-c++-basic/Makefile.am, + tests/test-c++-multiple-scanners/Makefile.am, + tests/test-c-cpp-nr/Makefile.am, tests/test-c-cpp-r/Makefile.am, + tests/test-debug-nr/Makefile.am, tests/test-debug-r/Makefile.am, + tests/test-header-nr/Makefile.am, tests/test-header-r/Makefile.am, + tests/test-include-by-buffer/Makefile.am, + tests/test-include-by-reentrant/Makefile.am, + tests/test-lineno-nr/Makefile.am, tests/test-lineno-r/Makefile.am, + tests/test-mem-nr/Makefile.am, tests/test-mem-r/Makefile.am, + tests/test-multiple-scanners-nr/Makefile.am, + tests/test-multiple-scanners-r/Makefile.am, + tests/test-posix/Makefile.am, + tests/test-posixly-correct/Makefile.am, + tests/test-prefix-nr/Makefile.am, tests/test-prefix-r/Makefile.am, + tests/test-pthread/Makefile.am, tests/test-reject/Makefile.am, + tests/test-string-nr/Makefile.am, tests/test-string-r/Makefile.am, + tests/test-table-opts/Makefile.am, tests/test-yyextra/Makefile.am: + remove BISON assignment as per suggestion from Akim Demaille + +2002-10-11 Will Estes + + * Makefile.am, configure.in: remove intl from dist + +2002-10-11 Will Estes + + * configure.in: we use maintainer mode now + +2002-10-11 Will Estes + + * NEWS: include create-test + +2002-10-11 Will Estes + + * tests/Makefile.am: rename test to check-local as per Akim + Demaille; test for failed tests so that make check fails if any + tests do + +2002-10-11 Will Estes + + * tests/Makefile.am: use dist_noinst_scripts as per email from Akim + Demaille + +2002-10-10 John Millaway + + * flex.texi: Documentation. + +2002-10-10 Will Estes + + * NEWS, configure.in: version 2.5.22; portability fixes and attn to + the test suite + +2002-10-10 Will Estes + + * flexint.h: ok, this seems to work + +2002-10-10 Will Estes + + * tests/TEMPLATE/Makefile.am, tests/test-bison-nr/Makefile.am, + tests/test-bison-yylloc/Makefile.am, + tests/test-bison-yylval/Makefile.am, + tests/test-header-nr/Makefile.am, tests/test-header-r/Makefile.am, + tests/test-multiple-scanners-nr/Makefile.am, + tests/test-multiple-scanners-r/Makefile.am: use builddir in tests + that need it in their include path + +2002-10-10 Will Estes + + * tests/TEMPLATE/Makefile.am: sometimes we put header files in the + builddir and so we should account for that + +2002-10-10 Will Estes + + * tests/TEMPLATE/Makefile.am: replace the last instance + +2002-10-10 Will Estes + + * flex.skl: include unistd.h and not cunistd as cunistd only seems + to be present on very recent systems + +2002-10-10 Will Estes + + * Makefile.am, configure.in, flex.skl, flexdef.h, flexint.h: redo + integral types again; add flexint.h; change dependencies caused by + adding flexint.h; remove autoconf wrapper around cunistd; restore + netinet/in.h includes; remove unneded feature checks in configure.in + +2002-10-08 Will Estes + + * configure.in, flex.skl, flexdef.h: current swipe at header magic; + int types be damned + +2002-10-08 Will Estes + + * NEWS: change version constant info to reflect change to flex.skl + +2002-10-08 Will Estes + + * Makefile.am: remove README-alpha option; add definitions for + FLEX_{MAJOR,MINOR,SUBMINOR}_VERSION + +2002-10-07 Will Estes + + * flex.skl, flexdef.h: ok, here goes; try to handle integral + typedefs in one swell foop + +2002-10-07 Will Estes + + * configure.in: we check for {u,}int*_t types; maybe this will + simplify things + +2002-10-07 Will Estes + + * configure.in: we create the tests/TEMPLATE/Makefile so that we can + build the dist archives + +2002-10-07 Will Estes + + * NEWS: more test suite cleanups + +2002-10-07 Will Estes + + * tests/test-c++-multiple-scanners/Makefile.am: we don't use header + files... + +2002-10-07 Will Estes + + * flexdef.h: remove include of malloc.h + +2002-10-04 Will Estes + + * flex.texi: more editing; remove examples index; merge examples + into concept index + +2002-10-04 Will Estes + + * flex.texi: edited one more faq; used C-u C-c C-u C-a to update + menus and nodes since the other updating commands are somewhat + broken; unfortunately this means that all nodes have all pointers + filled in + +2002-10-04 Will Estes + + * flex.texi: yesterday's proofreading + +2002-10-02 Will Estes + + * flex.texi: proofread some more + +2002-10-02 Will Estes + + * flex.texi: proofread edit begins + +2002-10-01 Will Estes + + * configure.in, tests/Makefile.am, + tests/test-c++-multiple-scanners/.cvsignore, + tests/test-c++-multiple-scanners/Makefile.am, + tests/test-c++-multiple-scanners/main.cpp, + tests/test-c++-multiple-scanners/scanner-1.l, + tests/test-c++-multiple-scanners/scanner-2.l, + tests/test-c++-multiple-scanners/test.input: test c++ with multiple + scanners + +2002-09-27 Will Estes + + * tests/test-array-nr/Makefile.am, tests/test-array-r/Makefile.am, + tests/test-basic-nr/Makefile.am, tests/test-basic-r/Makefile.am, + tests/test-bison-nr/Makefile.am, + tests/test-bison-yylloc/Makefile.am, + tests/test-bison-yylval/Makefile.am, + tests/test-c++-basic/Makefile.am, tests/test-c-cpp-nr/Makefile.am, + tests/test-c-cpp-r/Makefile.am, tests/test-debug-nr/Makefile.am, + tests/test-debug-r/Makefile.am, tests/test-header-nr/Makefile.am, + tests/test-header-r/Makefile.am, + tests/test-include-by-buffer/Makefile.am, + tests/test-include-by-reentrant/Makefile.am, + tests/test-lineno-nr/Makefile.am, tests/test-lineno-r/Makefile.am, + tests/test-mem-nr/Makefile.am, tests/test-mem-r/Makefile.am, + tests/test-multiple-scanners-nr/Makefile.am, + tests/test-multiple-scanners-r/Makefile.am, + tests/test-posix/Makefile.am, + tests/test-posixly-correct/Makefile.am, + tests/test-prefix-nr/Makefile.am, tests/test-prefix-r/Makefile.am, + tests/test-pthread/Makefile.am, tests/test-reject/Makefile.am, + tests/test-string-nr/Makefile.am, tests/test-string-r/Makefile.am, + tests/test-table-opts/Makefile.am, tests/test-yyextra/Makefile.am: + we used INCLUDES in another place in the Makefile.am files in the + test suite + +2002-09-27 Will Estes + + * tests/test-array-nr/Makefile.am, tests/test-array-r/Makefile.am, + tests/test-basic-nr/Makefile.am, tests/test-basic-r/Makefile.am, + tests/test-bison-nr/Makefile.am, + tests/test-bison-yylloc/Makefile.am, + tests/test-bison-yylval/Makefile.am, + tests/test-c++-basic/Makefile.am, tests/test-c-cpp-nr/Makefile.am, + tests/test-c-cpp-r/Makefile.am, tests/test-debug-nr/Makefile.am, + tests/test-debug-r/Makefile.am, tests/test-header-nr/Makefile.am, + tests/test-header-r/Makefile.am, + tests/test-include-by-buffer/Makefile.am, + tests/test-include-by-reentrant/Makefile.am, + tests/test-lineno-nr/Makefile.am, tests/test-lineno-r/Makefile.am, + tests/test-mem-nr/Makefile.am, tests/test-mem-r/Makefile.am, + tests/test-multiple-scanners-nr/Makefile.am, + tests/test-multiple-scanners-r/Makefile.am, + tests/test-posix/Makefile.am, + tests/test-posixly-correct/Makefile.am, + tests/test-prefix-nr/Makefile.am, tests/test-prefix-r/Makefile.am, + tests/test-pthread/Makefile.am, tests/test-reject/Makefile.am, + tests/test-string-nr/Makefile.am, tests/test-string-r/Makefile.am, + tests/test-table-opts/Makefile.am, tests/test-yyextra/Makefile.am: + oops, I typed that last s/// command to perl way wrong + +2002-09-27 Will Estes + + * tests/TEMPLATE/Makefile.am, tests/test-array-nr/Makefile.am, + tests/test-array-r/Makefile.am, tests/test-basic-nr/Makefile.am, + tests/test-basic-r/Makefile.am, tests/test-bison-nr/Makefile.am, + tests/test-bison-yylloc/Makefile.am, + tests/test-bison-yylval/Makefile.am, + tests/test-c++-basic/Makefile.am, tests/test-c-cpp-nr/Makefile.am, + tests/test-c-cpp-r/Makefile.am, tests/test-debug-nr/Makefile.am, + tests/test-debug-r/Makefile.am, tests/test-header-nr/Makefile.am, + tests/test-header-r/Makefile.am, + tests/test-include-by-buffer/Makefile.am, + tests/test-include-by-reentrant/Makefile.am, + tests/test-lineno-nr/Makefile.am, tests/test-lineno-r/Makefile.am, + tests/test-mem-nr/Makefile.am, tests/test-mem-r/Makefile.am, + tests/test-multiple-scanners-nr/Makefile.am, + tests/test-multiple-scanners-r/Makefile.am, + tests/test-posix/Makefile.am, + tests/test-posixly-correct/Makefile.am, + tests/test-prefix-nr/Makefile.am, tests/test-prefix-r/Makefile.am, + tests/test-pthread/Makefile.am, tests/test-reject/Makefile.am, + tests/test-string-nr/Makefile.am, tests/test-string-r/Makefile.am, + tests/test-table-opts/Makefile.am, tests/test-yyextra/Makefile.am: + use AM_CPPFLAGS instead of INCLUDES; write -I with no space after it + for broken compilers + +2002-09-27 Will Estes + + * Makefile.am: INCLUDES is obsolete; use AM_CPPFLAGS instead + +2002-09-27 Will Estes + + * configure.in: apparently, AM_CONFIG_HEADER is obsolete + +2002-09-27 Will Estes + + * TODO: integrate test suite into automake + +2002-09-27 Will Estes + + * configure.in: since we dont run the template test, we dont need to + generate its Makefile either + +2002-09-27 Will Estes + + * autogen.sh: use autoreconf instead of calling individual utilities + separately + +2002-09-27 Will Estes + + * configure.in: check for c++ compiler + +2002-09-27 Will Estes + + * configure.in: re-organize according to suggested layout in + autoconf manual + +2002-09-26 Will Estes + + * Makefile.am, NEWS, configure.in: update automake to 1.7 and + autoconf to 2.54 + +2002-09-26 Will Estes + + * Makefile.am: use AM_YFLAGS since YFLAGS is a user variable + +2002-09-25 Will Estes + + * NEWS: catch NEWS up on things, some of which happened a long time + ago; correct punctuation; try to remove some editorializing + +2002-09-25 Will Estes + + * Makefile.am, flex.skl, flex.texi: include a single, automatically + generated version number in flex scanners + +2002-09-23 Will Estes + + * tests/create-test: complain audibly when argument not supplied; + echo on stderr when writing error messages + +2002-09-23 Will Estes + + * tests/Makefile.am, tests/create-test: DIST_SUBDIRS so we don't + have to run the TEMPLATE test; so we add new tests to SUBDIRS and + DIST_SUBDIRS + +2002-09-23 Will Estes + + * tests/TEMPLATE/Makefile.am: not all compilers support '-I dir' so + we write '-Idir' instead + +2002-09-23 Will Estes + + * TODO: reorganize faq entries; proofread the manual + +2002-09-23 Will Estes + + * flex.texi: move c++ experimental warning to top of cxx node + +2002-09-20 Will Estes + + * flex.skl: move stdint.h include to table-serialization section; + we'll still need to think about stdint.h more though + +2002-09-20 Will Estes + + * NEWS: new smarter skeleton/scanner generation + +2002-09-20 John Millaway + + * flex.skl, misc.c: bison-bridge skel handled via %if/%endif pairs. + +2002-09-19 John Millaway + + * flex.skl, misc.c: reentrant skel handled via %if/%endif pairs. + +2002-09-19 John Millaway + + * flex.skl, misc.c: skeleton uses %push/%pop to keep skelout() scope + sane. skel commands are omitted unless --debug enabled. + +2002-09-19 John Millaway + + * flex.skl, main.c, misc.c, tables.h: Added %push and %pop + operations to skel processing. + +2002-09-17 Will Estes + + * NEWS, configure.in: flex 2.5.21 + +2002-09-17 John Millaway + + * tests/test-reject/Makefile.am: minor fixup for dist. + +2002-09-16 Will Estes + + * NEWS, configure.in: version 2.5.20 + +2002-09-16 Will Estes + + * flex.texi: correct typo + +2002-09-16 Will Estes + + * NEWS: note the new tables functionality + +2002-09-16 John Millaway + + * tests/test-multiple-scanners-r/.cvsignore, + tests/test-multiple-scanners-r/Makefile.am: Fixed `clean' target and + .cvsignore. + +2002-09-16 John Millaway + + * TODO, flex.skl, flex.texi, main.c, tables_shared.h, + tests/test-multiple-scanners-r/main.c, + tests/test-multiple-scanners-r/scanner-1.l, + tests/test-multiple-scanners-r/scanner-2.l: Serialization works in + headers (%option headers). Serialization code (Tables API) is + complete. + +2002-09-16 Will Estes + + * tests/test-reject/scanner.l: replace yytables_load with + yytables_fload as per millaway's other changes + +2002-09-15 John Millaway + + * TODO, flex.texi: Created user API for tables deserialization. + Documented API and --tables-* options in manual. + +2002-09-15 John Millaway + + * flex.skl, tests/test-table-opts/scanner.l: Tables deserialization + uses yyalloc/yyfree. Changed yytables_load to yytables_fload. + +2002-09-15 John Millaway + + * tests/test-bison-nr/.cvsignore: minor upkeep. + +2002-09-15 John Millaway + + * flex.texi: Categorized and indexed scanner options in manual. + +2002-09-15 John Millaway + + * flex.skl: Initialization of reject vars and %array vars in + reentrant scanner. + +2002-09-13 John Millaway + + * TODO, configure.in, devel/tables.pl, dfa.c, flex.skl, flex.texi, + gen.c, tables.c, tables_shared.c, tables_shared.h, + tests/Makefile.am, tests/test-reject/.cvsignore, + tests/test-reject/Makefile.am, tests/test-reject/scanner.l, + tests/test-reject/test.input, tests/test-table-opts/Makefile.am: + Created test for reject. Handled reject-triggered tables in + serialization. + +2002-09-13 Will Estes + + * NEWS: millaway has been very busy + +2002-09-13 John Millaway + + * flex.skl, tests/test-table-opts/Makefile.am, + tests/test-table-opts/scanner.l: Added test for multiple tables in + one file. + +2002-09-13 John Millaway + + * tests/test-bison-nr/.cvsignore: forgot to add .cvsignore on last + commit. + +2002-09-13 John Millaway + + * tests/test-bison-nr/Makefile.am, tests/test-bison-nr/main.c, + tests/test-bison-nr/parser.y, tests/test-bison-nr/scanner.l, + tests/test-bison-nr/test.input: Added test-bison-bridge. + +2002-09-13 John Millaway + + * configure.in, flex.skl, flex.texi, flexdef.h, gen.c, main.c, + misc.c, options.c, options.h, scan.l, tables.h, tests/Makefile.am, + tests/descriptions, tests/test-bison-yylloc/scanner.l, + tests/test-bison-yylval/scanner.l, tests/test-table-opts/scanner.l: + Bison bridge code now works for all C scanners and pure/non-pure + bison parsers. Added %option bison-bridge (--bison-bridge). + Removed %option reentrant-bison/--reentrant-bison/-Rb. Scanner + knows the name of its tables. Tables serialization is OK on EOF. + yylineno is present in all scanners. Modified nasty performance + penalty warning w/ yylineno. test-table-opts is now run last + because it's so fat. Updated manual. + +2002-09-12 John Millaway + + * flex.texi: documentation of tabels api in manual + +2002-09-12 John Millaway + + * TODO, tables.c: Renamed *_fwrite to *_write to reflect writer + abstraction. + +2002-09-11 John Millaway + + * devel/tables.pl: Added perl script to read/dump serialized tables + in devel/ + +2002-09-11 Will Estes + + * scan.l: the debian patch used strlen(yytext) and similar + constructs--as millaway points out, this is better known as yyleng + +2002-09-11 Will Estes + + * NEWS, po/de.po: new de translation from the translation project + +2002-09-11 John Millaway + + * flex.skl: yytbl_load now checks tables set by name. Localized var + scaope in yytbl_load. + +2002-09-10 Will Estes + + * tests/Makefile.am: make clean before make test + +2002-09-09 John Millaway + + * TODO, flex.skl: Fixed deserialization of --fast tables. + +2002-09-09 Will Estes + + * TODO: fix typo; remove the yylineo entry + +2002-09-09 John Millaway + + * TODO, buf.c, devel/dump-tables.pl, dfa.c, flex.skl, flexdef.h, + gen.c, main.c, misc.c, options.c, options.h, scan.l, tables.c, + tables.h, tables_shared.h, tests/test-table-opts/.cvsignore, + tests/test-table-opts/Makefile.am, tests/test-table-opts/scanner.l: + Table deserialization works for everything except --fast scanners. + Scanners can auto-verify serialized table integrity via + --tables-verify. Added tables API items to TODO list. + test-table-opts is becoming exhaustive (a good thing). + +2002-09-09 Will Estes + + * NEWS: flex has better internal diagnostics + +2002-09-09 Will Estes + + * configure.in, flexdef.h: test for presence of __func__ and + compensate if absent + +2002-09-09 Will Estes + + * Makefile.am: include the intl/ subdirectory when searching for + include files + +2002-09-09 Will Estes + + * NEWS, po/ru.po, po/sv.po: new sv, ru translations from the + translation project + +2002-09-07 John Millaway + + * flex.skl, misc.c: Changed cryptic skeleton markers to readable + form. + +2002-09-07 John Millaway + + * Makefile.am, dfa.c, flex.skl, flex.texi, flexdef.h, gen.c, + main.c, misc.c, parse.y, tables.c, tables.h, tables_shared.c, + tables_shared.h: Members of struct yy_trans_info are now forced to + be the same size. Added shared file tables_shared.c. Separated + tables.h from flexdef.h Bulk of table deserialization code is done. + +2002-09-06 Will Estes + + * NEWS, po/ca.po: new ca translation + +2002-09-06 Will Estes + + * NEWS: new fr translation + +2002-09-06 Will Estes + + * po/fr.po: new french translation from the translation project + +2002-09-05 Will Estes + + * NEWS: c99 function defs by default + +2002-09-05 John Millaway + + * flexdef.h, tables.c: Added flex_die macro. May need some autoconf + massaging. Added thorough error checking in tables code. + +2002-09-05 John Millaway + + * flex.skl, flex.texi: Flex generates C99 defs now. Documented the + above change in manual. + +2002-09-05 John Millaway + + * tests/test-table-opts/.cvsignore, + tests/test-table-opts/Makefile.am: Added serialization test to + table-opts test. + +2002-09-05 Will Estes + + * configure.in: oops, i made a typo + +2002-09-05 Will Estes + + * NEWS, configure.in: version 2.5.19 + +2002-09-05 Will Estes + + * scan.l: use FLEX_EXIT(), not exit() + +2002-09-05 John Millaway + + * devel/00EXTRACT-ALL-SYMS.sh, devel/README, devel/dump-tables.pl: + Added devel/ directory for junk that we don't want in the + distribution, but that we want in CVS. + +2002-09-05 Will Estes + + * scan.l: s/exit(1)/exit(EXIT_FAILURE) + +2002-09-05 John Millaway + + * dfa.c, gen.c: Tables are now generated with %option + tables-file=FILE. + +2002-09-05 Will Estes + + * NEWS: catch up on a few things + +2002-09-05 Will Estes + + * scan.l: prevent segfault on input lines which are longer than the + allocated space (problem report from Manoj Srivastava + ) + +2002-09-05 John Millaway + + * flex.texi, main.c, options.c, options.h: Changed option 'header' + to 'header-file'. 'header' still works, though. + +2002-09-05 John Millaway + + * flex.texi, flexdef.h, gen.c, main.c, options.c, options.h, + scan.l, tables.c: Tons more work on tables. + +2002-09-05 John Millaway + + * flexdef.h, gen.c, tables.c, tables_shared.h: Lots of work on + tables serialization code. + +2002-09-04 Will Estes + + * README.cvs-snapshot: mention GNU indent + +2002-09-04 Will Estes + + * NEWS: remove the word after from the version line + +2002-09-03 Will Estes + + * NEWS, configure.in: version 2.5.18 + +2002-09-03 Will Estes + + * NEWS: catch up on the NEWS + +2002-09-03 Will Estes + + * tests/Makefile.am: target test: quote the results echoing so that + the ECHO_C will work on systems where it is used + +2002-09-03 Will Estes + + * configure.in: when we don't have GNU indent, the test will + generate output on stderr, so we send that to /dev/null + +2002-09-03 Will Estes + + * configure.in: fixed bug whereby bison was reported missing even + when it was found + +2002-09-02 John Millaway + + * tables.c: In-code documentation. + +2002-09-02 John Millaway + + * flexdef.h: Forgot to indent before previous commit. + +2002-09-02 John Millaway + + * flexdef.h: Added known integer limits if undefined. + +2002-08-29 Will Estes + + * configure.in: version 2.5.17 + +2002-08-29 Will Estes + + * NEWS: more portability fixes; new version number + +2002-08-29 Will Estes + + * flexdef.h, main.c, misc.c, scanopt.c: #include fixes; we've + factored out all the system include files and put them in flexdef.h + +2002-08-29 Will Estes + + * dfa.c: eat a blank line + +2002-08-29 Will Estes + + * NEWS: new config.{sub,guess} files; mention that we use indent on + flex + +2002-08-28 Will Estes + + * configure.in: warn if no indent found; version 2.5.16 + +2002-08-28 Will Estes + + * NEWS: catch up on recent changes; version 2.5.16 + +2002-08-27 Will Estes + + * buf.c, ccl.c, dfa.c, ecs.c, flexdef.h, gen.c, libmain.c, + libyywrap.c, main.c, misc.c, nfa.c, options.c, options.h, + scanopt.c, scanopt.h, sym.c, tables.c, tables_shared.h, tblcmp.c, + yylex.c: ran the indent target; commit the results + +2002-08-27 Will Estes + + * Makefile.am: touch up the indent targeet; it's ready for + production use now + +2002-08-27 Will Estes + + * configure.in: test for GNU indent; reorder the tests somewhat + +2002-08-23 Will Estes + + * configure.in: automake is smarter about autoconf's versioning + scheme + +2002-08-23 Will Estes + + * NEWS: catch NEWS up on what we've been doing + +2002-08-22 Will Estes + + * flexdef.h: do some more conditional including for folks without + standard systems + +2002-08-22 Will Estes + + * tests/test-c++-basic/Makefile.am: use CXX to link the test scanner + here + +2002-08-22 John Millaway + + * flex.texi: Documentation. + +2002-08-22 John Millaway + + * Makefile.am: Created 'indent' target and added .indent.pro. + +2002-08-22 John Millaway + + * tests/test-array-nr/Makefile.am, tests/test-array-r/Makefile.am, + tests/test-basic-nr/Makefile.am, tests/test-basic-r/Makefile.am, + tests/test-c-cpp-nr/Makefile.am: Fixed missing 'make clean' files. + +2002-08-22 John Millaway + + * tests/test-bison-yylloc/Makefile.am, + tests/test-bison-yylval/Makefile.am: fixed missing 'clean' file. + +2002-08-22 John Millaway + + * flex.skl, tests/test-c++-basic/Makefile.am, + tests/test-c++-basic/scanner.l: Removed core of yylex_destroy from + c++ scanner -- hack! Added -lstdc++ to LDFLAGS (should we have to do + this??) + +2002-08-21 Will Estes + + * README: official releases are being hosted by Vern + +2002-08-21 Will Estes + + * NEWS, configure.in: new beta version; more entries in NEWS from + millaway; the top level entry for test-c++-basic + +2002-08-21 Will Estes + + * tests/Makefile.am, tests/test-c++-basic/.cvsignore, + tests/test-c++-basic/Makefile.am, tests/test-c++-basic/scanner.l, + tests/test-c++-basic/test.input: add test-c++-basic + +2002-08-21 John Millaway + + * gen.c, nfa.c: More tabels work. + +2002-08-21 John Millaway + + * flexdef.h, gen.c, tables.c, tables_shared.h: More work on tables. + +2002-08-20 John Millaway + + * dfa.c: Cleaned up macros that took no ';'. + +2002-08-20 John Millaway + + * scanopt.c: Fixed oddball '=-'. + +2002-08-20 John Millaway + + * flex.skl, flex.texi, gen.c: Dynamically allocate REJECT state + buffer. Mentioned memory usage in docs. Made REJECT buffer + variables reentrant-safe. + +2002-08-20 John Millaway + + * tables.c: More work on tables code. + +2002-08-20 Will Estes + + * Makefile.am, NEWS, configure.in: we're using m4 so have configure + test for it + +2002-08-20 John Millaway + + * Makefile.am, tables.c: Added tables.c and rebuilt dependencies. + +2002-08-20 John Millaway + + * TODO, flex.texi: Dicussed prototypes and header in manual. + +2002-08-19 John Millaway + + * Makefile.am, configure.in, flex.skl, flexdef.h, tables_shared.h: + More work on tables serialization. + +2002-08-19 John Millaway + + * Makefile.am, mkskel.sh: Skeleton is now passed through m4 (before + dist is built). + +2002-08-19 Will Estes + + * po/LINGUAS, po/zh_CN.po: add zh_cn translation from the + translation project + +2002-08-19 Will Estes + + * NEWS: millaway's done a lot of things which need to be mentioned + in NEWS + +2002-08-18 John Millaway + + * main.c: Removed #undef of start conditions. + +2002-08-17 John Millaway + + * TODO: todo list + +2002-08-17 John Millaway + + * flexdef.h, main.c, misc.c: Start conditions now optional in + header. undef's now optional in header. Start conditions are NOT + prefixed. + +2002-08-17 John Millaway + + * flex.skl, flex.texi: Working on tables API. + +2002-08-16 John Millaway + + * flexdef.h, main.c, misc.c, options.c, options.h, parse.y, scan.l: + Added --tables option. Omitted tables code from generated scanner + when unused. + +2002-08-16 John Millaway + + * flex.skl, flex.texi, misc.c: Prelimary work on tables API. + +2002-08-16 John Millaway + + * tests/TEMPLATE/Makefile.am, tests/test-array-nr/Makefile.am, + tests/test-array-r/Makefile.am, tests/test-basic-nr/Makefile.am, + tests/test-basic-r/Makefile.am, + tests/test-bison-yylloc/Makefile.am, + tests/test-bison-yylval/Makefile.am, + tests/test-c-cpp-nr/Makefile.am, tests/test-c-cpp-r/Makefile.am, + tests/test-debug-nr/Makefile.am, tests/test-debug-r/Makefile.am, + tests/test-header-nr/Makefile.am, tests/test-header-r/Makefile.am, + tests/test-include-by-buffer/Makefile.am, + tests/test-include-by-reentrant/Makefile.am, + tests/test-lineno-nr/Makefile.am, tests/test-lineno-r/Makefile.am, + tests/test-mem-nr/Makefile.am, tests/test-mem-r/Makefile.am, + tests/test-multiple-scanners-nr/Makefile.am, + tests/test-multiple-scanners-r/Makefile.am, + tests/test-posix/Makefile.am, + tests/test-posixly-correct/Makefile.am, + tests/test-prefix-nr/Makefile.am, tests/test-prefix-r/Makefile.am, + tests/test-pthread/Makefile.am, tests/test-string-nr/Makefile.am, + tests/test-string-r/Makefile.am, tests/test-table-opts/Makefile.am, + tests/test-yyextra/Makefile.am: Tests now respect CFLAGS, CPPFLAGS, + etc.. + +2002-08-16 John Millaway + + * tests/test-basic-nr/scanner.l, tests/test-basic-r/scanner.l, + tests/test-lineno-nr/scanner.l, tests/test-lineno-r/scanner.l: Got + rid of flex -s warnings in tests. + +2002-08-16 John Millaway + + * Makefile.am: Updated dependencies list. + +2002-08-15 John Millaway + + * main.c: Fixed seg fault bug in ecs. + +2002-08-15 Will Estes + + * tests/test-c-cpp-nr/.cvsignore, tests/test-c-cpp-r/.cvsignore: + ignore .cpp files since we generate them instead of .c + +2002-08-15 Will Estes + + * configure.in: version 2.5.14 + +2002-08-15 Will Estes + + * NEWS: c-as-c++ tests reworked + +2002-08-15 John Millaway + + * tests/test-c-cpp-nr/Makefile.am, tests/test-c-cpp-nr/scanner.l, + tests/test-c-cpp-r/Makefile.am, tests/test-c-cpp-r/scanner.l: The + c++ tests use .cpp instead of .c extensions just to be on the safe + side. + +2002-08-15 Will Estes + + * main.c: conditionally include ; include config.h as well + +2002-08-15 Will Estes + + * configure.in, flex.skl: only include if we have it + +2002-08-15 Will Estes + + * NEWS: portability fixes; added missing punctuation; de translation + now included + +2002-08-15 Will Estes + + * po/LINGUAS: we also translate to german + +2002-08-15 Will Estes + + * Makefile.am: require automake at least 1.6 + +2002-08-15 Will Estes + + * NEWS, configure.in: version 2.5.13 + +2002-08-14 Will Estes + + * flex.texi: reverted away from the @copying as it breaks the info + reader + +2002-08-14 John Millaway + + * flex.texi, flexdef.h, main.c, misc.c: Start condition prefixes + attempts to adjust to user preferences. + +2002-08-13 John Millaway + + * main.c: Include start condition symbols in header. + +2002-08-13 John Millaway + + * flexdef.h, main.c: Omit user code and tables from generated header + file. + +2002-08-13 Will Estes + + * flex.texi: use @copying construct to display the flex license; + move copying and bug reporting to the front of the manual + +2002-08-13 Will Estes + + * NEWS: printf fix and yylex_init reports errors + +2002-08-12 John Millaway + + * flex.texi: Updated manual for %option header. + +2002-08-12 John Millaway + + * flex.skl, flex.texi, gen.c: Fixed type mismatch in printf. + yylex_init now reports errors. + +2002-08-10 John Millaway + + * dfa.c, main.c: Added alignment flag for future use. + +2002-08-10 John Millaway + + * tests/test-table-opts/.cvsignore, + tests/test-table-opts/Makefile.am: Added options to test-table-opts + +2002-08-10 John Millaway + + * configure.in, tests/Makefile.am, tests/descriptions, + tests/test-c-cpp-nr/Makefile.am, tests/test-table-opts/.cvsignore, + tests/test-table-opts/Makefile.am, tests/test-table-opts/scanner.l, + tests/test-table-opts/test.input: Added a test for various DFA table + options. + +2002-08-09 Will Estes + + * flex.texi: more faq editing; corrected mistyped nodenames + +2002-08-09 Will Estes + + * flex.skl: fix typo which propogates out to generated scanners + +2002-08-09 Will Estes + + * flex.texi: edited a few more faqs + +2002-08-09 Will Estes + + * Makefile.am, faq.texi: remove faq.texi as it's included in + flex.texi + +2002-08-08 Will Estes + + * flex.texi: a few more faq edits; remove faq-89 + +2002-08-08 Will Estes + + * flex.texi: cite, not site + +2002-08-08 Will Estes + + * flex.texi: and get the faq included + +2002-08-08 Will Estes + + * flex.texi: fix some grammer/typography in the top node and add a + detailed menu + +2002-08-08 Will Estes + + * TODO: we've updated gettext + +2002-08-08 Will Estes + + * po/.cvsignore: we need to ignore a few more gettext files + +2002-08-08 Will Estes + + * NEWS, configure.in: version 2.5.12 + +2002-08-08 Will Estes + + * NEWS: mention gettext; document the non-need for bison/flex in the + build process + +2002-08-08 Will Estes + + * Makefile.am, configure.in: include intl in the distribution and in + the build process + +2002-08-08 Will Estes + + * Makefile.am: builddir in help2man call needed @-signs around it + +2002-08-08 Will Estes + + * po/.cvsignore: we can ignore Makefile.in.in + +2002-08-08 Will Estes + + * m4/.cvsignore, m4/Makefile.am: oops, too hasty on deleting this + directory, sigh + +2002-08-08 Will Estes + + * autogen.sh: if autopoint is going to run automatically, it's going + to need to be able to update existing files + +2002-08-08 Will Estes + + * ABOUT-NLS, autogen.sh, configure.in, m4/.cvsignore, + m4/Makefile.am, m4/codeset.m4, m4/gettext.m4, m4/glibc21.m4, + m4/iconv.m4, m4/isc-posix.m4, m4/lcmessage.m4, m4/lib-ld.m4, + m4/lib-link.m4, m4/lib-prefix.m4, m4/progtest.m4: autopoint now + works so let's let it run the gettext show + +2002-08-07 Will Estes + + * TODO: we need to index the faq entries + +2002-08-07 Will Estes + + * faq.texi: proofed "Why do flex scanners call fileno if it is not + ANSI compatible?" + +2002-08-07 Will Estes + + * faq.texi: proofed "How do I expand \ escape sequences in C-style + quoted strings?" + +2002-08-07 Will Estes + + * README: changes to README to align with GNU coding standards + +2002-08-06 Will Estes + + * Makefile.am: help2man should look in builddir for the flex binary + +2002-08-02 John Millaway + + * flex.skl: Fixed yyunput prototype. + +2002-08-01 Will Estes + + * NEWS: new fr translation from the translation project + +2002-08-01 Will Estes + + * po/fr.po: new fr.po translation from the translation project + +2002-08-01 Will Estes + + * NEWS: yylineno performance hit is fixed + +2002-07-31 John Millaway + + * TODO, flex.texi: Updated docs on yylineno. + +2002-07-31 Will Estes + + * TODO: discuss yylineno performance + +2002-07-31 Will Estes + + * NEWS: forgot to say what the date was that we made the release + +2002-07-31 Will Estes + + * NEWS, configure.in: version 2.5.11 + +2002-07-31 Will Estes + + * faq.texi: fixed a menu entry and related problems + +2002-07-31 Will Estes + + * configure.in: someday, maybe we can use autopoint + +2002-07-31 Will Estes + + * Makefile.am: we need to include texinfo.tex now + +2002-07-31 Will Estes + + * texinfo.tex: add texinfo.tex + +2002-07-30 Will Estes + + * faq.texi: fix up some fatal bugs in the texinfo of the faq; begin + the clean up; remove trailing and leading white space + +2002-07-30 Will Estes + + * TODO: faqs need work + +2002-07-30 Will Estes + + * NEWS, TODO: prototypes get airtime these days + +2002-07-28 John Millaway + + * flex.skl: Added some comments. + +2002-07-28 John Millaway + + * flex.skl: Fixed bug where yyless did not consider yylineno. + +2002-07-28 John Millaway + + * scan.l: Fixed bug I created in previous commit. + +2002-07-28 John Millaway + + * scan.l: Don't wrap ()s around {NAMEDEFS} at the end of a rule. + +2002-07-27 John Millaway + + * flex.skl, tests/test-c-cpp-nr/Makefile.am, + tests/test-c-cpp-r/Makefile.am: Fixed test-c-cpp to actually use the + C++ compiler for the test. Fixed the bug that this exposed. + +2002-07-27 John Millaway + + * ccl.c, flex.skl, flexdef.h, gen.c, main.c, nfa.c, parse.y, scan.l: + yylineno check is only performed on rules whose regexs can match a + newline. + +2002-07-25 John Millaway + + * flex.skl, tests/TEMPLATE/scanner.l, + tests/test-array-nr/scanner.l, tests/test-array-r/scanner.l, + tests/test-basic-nr/scanner.l, tests/test-basic-r/scanner.l, + tests/test-bison-yylloc/parser.y, tests/test-c-cpp-nr/scanner.l, + tests/test-c-cpp-r/scanner.l, tests/test-debug-nr/scanner.l, + tests/test-debug-r/scanner.l, + tests/test-include-by-buffer/scanner.l, + tests/test-include-by-reentrant/scanner.l, + tests/test-lineno-nr/scanner.l, tests/test-lineno-r/scanner.l, + tests/test-mem-nr/scanner.l, tests/test-mem-r/scanner.l, + tests/test-posix/scanner.l, tests/test-posixly-correct/scanner.l, + tests/test-prefix-nr/scanner.l, tests/test-prefix-r/scanner.l, + tests/test-pthread/scanner.l, tests/test-string-nr/scanner.l, + tests/test-string-r/scanner.l, tests/test-yyextra/scanner.l: All + prototypes were rewritten to depend upon the macro + YY_TRADITIONAL_FUNC_DEFS, which is defined by default. The + generated scanners build cleanly under gcc's traditional strictness + and under C++ compilers. + +2002-07-24 Will Estes + + * NEWS: dist-bzip2 and rename yy_globals and yy_globals_t + +2002-07-24 Will Estes + + * configure.in: version 2.5.10 + +2002-07-24 Will Estes + + * Makefile.am: add dist-bzip2 to automake_options so we'll start + getting tar.bz2 archives + +2002-07-23 John Millaway + + * flex.skl, flex.texi, tests/test-bison-yylval/scanner.l, + tests/test-mem-r/scanner.l, + tests/test-multiple-scanners-r/scanner-1.l, + tests/test-multiple-scanners-r/scanner-2.l, + tests/test-prefix-r/scanner.l, tests/test-pthread/scanner.l, + tests/test-yyextra/scanner.l: s/yy_globals_t/yyguts_t/g + s/yy_globals/yyscanner/g + +2002-07-23 John Millaway + + * Makefile.am: typo in tags target + +2002-07-22 John Millaway + + * Makefile.am: Removed erroneous $(srcdir) from help2man target. + +2002-07-22 Will Estes + + * NEWS, configure.in: it's version 2.5.9 now + +2002-07-22 Will Estes + + * po/.cvsignore: updated gettext to 0.11.3 + +2002-07-22 Will Estes + + * ABOUT-NLS, config.rpath, m4/gettext.m4, m4/iconv.m4, + m4/isc-posix.m4, m4/lcmessage.m4, m4/lib-link.m4: updated gettext to + version 0.11.3 + +2002-07-22 Will Estes + + * autogen.sh, configure.in: rollback on configure.in and autogen.sh + because autpoint is broken + +2002-07-22 Will Estes + + * po/ru.po: new russian translation from translation project + +2002-07-19 Will Estes + + * autogen.sh: ok, we're going to start using autopoint, but the tree + is going to undergo some changes after this + +2002-07-19 Will Estes + + * configure.in: we're preparing for autopoint + +2002-07-17 John Millaway + + * flex.texi: Updated manual. + +2002-07-17 Will Estes + + * NEWS: update the NEWS file for lots of things millaway has done + +2002-07-17 John Millaway + + * flex.skl, main.c, misc.c, scan.l, scanopt.c, sym.c, + tests/test-mem-nr/scanner.l, tests/test-mem-r/scanner.l: Fixed + prototype/definition conflicts with "traditional" C in skeleton at + request of gcc developer. Removed duplicate prototypes in gen.c, + sym.c, main.c. Added missing prototypes where needed. All + functions in skeleton follow ISO C style protos and defs, instead of + BOTH ISO and new-style. Skeleton now compiles cleanly under + super-strict gcc flags. Flex itself almost compiles cleanly under + strict flags. + +2002-07-15 John Millaway + + * faq.texi, flex.texi: Worked on mem mgmt sect of manual. + +2002-07-15 Will Estes + + * scan.l: allow blank lines and continuations in more places + +2002-07-12 Will Estes + + * TODO: millaway finished the faqs directory + +2002-07-12 Will Estes + + * TODO: removed items as per email from millaway + +2002-07-12 John Millaway + + * configure.in, tests/Makefile.am, tests/descriptions, + tests/test-posix/.cvsignore, tests/test-posix/Makefile.am, + tests/test-posix/scanner.l, tests/test-posixly-correct/.cvsignore, + tests/test-posixly-correct/Makefile.am, + tests/test-posixly-correct/scanner.l: Added test for %option + posix-compat and repeat operator. Added test for POSIXLY_CORRECT + environment variable and repeat operator. + +2002-07-12 John Millaway + + * main.c, scan.l: Fixed POSIXLY_CORRECT detection in scanner. + +2002-07-11 John Millaway + + * faq.texi: More work on faq. + +2002-07-11 John Millaway + + * faq.texi: Moved all faqs into manual -- but did not evaluate them + yet. Removed the old faq files. + +2002-07-10 John Millaway + + * main.c: Removed duplicate definition of FLEX_DEBUG. gcc doesn't + care, but other compilers might. + +2002-07-10 John Millaway + + * flex.texi: Wrote some more about memory mgmt in the manual. + +2002-07-10 John Millaway + + * flex.texi: flex.texi now works with install-info. + +2002-07-10 Will Estes + + * TODO: added items as per email from millaway + +2002-07-10 Will Estes + + * NEWS: after we release a version, we have to keep the version + number in NEWS current + +2002-07-10 John Millaway + + * flex.skl, flex.texi, main.c, scan.l, tests/test-mem-nr/scanner.l, + tests/test-mem-r/scanner.l: Fixed prefix issue with get/set debug + functions. Fixed prefix issues with memory functions. + +2002-07-09 John Millaway + + * flex.skl: Memory functions are no longer static. + +2002-07-09 John Millaway + + * tests/test-mem-nr/test.input: Added a missing input file for + test-mem-nr/ + +2002-07-09 John Millaway + + * tests/test-mem-nr/.cvsignore, tests/test-mem-nr/Makefile.am, + tests/test-mem-nr/scanner.l, tests/test-mem-r/.cvsignore, + tests/test-mem-r/Makefile.am, tests/test-mem-r/scanner.l, + tests/test-mem-r/test.input: Added tests for overriding memory. + +2002-07-09 John Millaway + + * flex.texi: Added sections in manual for memory management. + +2002-07-09 Will Estes + + * NEWS: noted more user visible changes + +2002-07-09 John Millaway + + * configure.in, flex.skl, scan.l, tests/Makefile.am: Added + yylex_destroy() to non-reentrant scanner. Added ability to override + memory functions. Added tests for overriding memory functions. + +2002-07-09 Will Estes + + * NEWS: new POSIXLY_CORRECT and new ru translation + +2002-07-09 Will Estes + + * po/ru.po: new ru translation from the translation project + +2002-07-09 John Millaway + + * flex.texi: Made note of set/get debug in docs. + +2002-07-09 John Millaway + + * configure.in, flexdef.h, tests/create-test: Replaced obsolete + macros in configure.in. Modified create-test to handle the above + changes in configure.in. Added support for . + +2002-07-09 John Millaway + + * main.c: Check POSIXLY_CORRECT env variable. + +2002-07-09 John Millaway + + * flex.skl: Added prototypes for the get/set debug functions. + +2002-07-09 John Millaway + + * configure.in, flex.skl, gen.c, main.c, scan.l, tests/Makefile.am, + tests/test-debug-nr/.cvsignore, tests/test-debug-nr/Makefile.am, + tests/test-debug-nr/scanner.l, tests/test-debug-nr/test.input, + tests/test-debug-r/.cvsignore, tests/test-debug-r/Makefile.am, + tests/test-debug-r/scanner.l, tests/test-debug-r/test.input: Made + yy_flex_debug non-global in reentrant scanner. Created get/set + functions for yy_flex_debug. Defined prefixes for new yy_flex_debug + symbols. Added tests/ for yy_flex_debug. + +2002-07-09 John Millaway + + * tests/create-test: create-test script now modifies .cvsignore + +2002-07-09 John Millaway + + * tests/create-test: Improved the error checking. + +2002-07-03 Will Estes + + * main.c: fix bug whereby prefix didn't get passed to everybody; + patch by rse@engelschall.com + +2002-07-03 Will Estes + + * faq.texi: ~ is an active character, so we'll just use the word + 'about' + +2002-07-02 John Millaway + + * Makefile.am: Fixed typo. + +2002-07-02 John Millaway + + * faq.texi: Added a faq. + +2002-06-28 John Millaway + + * Makefile.am: Added 'tags' target -- something I should have done + long ago. + +2002-06-28 Will Estes + + * TODO: add two new items regarding coding; remove tests/ copyright + notice item as it's done + +2002-06-26 Will Estes + + * NEWS: note the copyright messages in tests/ + +2002-06-25 John Millaway + + * tests/TEMPLATE/Makefile.am, tests/TEMPLATE/parser.y, + tests/TEMPLATE/scanner.l, tests/test-array-nr/Makefile.am, + tests/test-array-nr/scanner.l, tests/test-array-r/Makefile.am, + tests/test-array-r/scanner.l, tests/test-basic-nr/Makefile.am, + tests/test-basic-nr/scanner.l, tests/test-basic-r/Makefile.am, + tests/test-basic-r/scanner.l, tests/test-bison-yylloc/Makefile.am, + tests/test-bison-yylloc/main.c, tests/test-bison-yylloc/parser.y, + tests/test-bison-yylloc/scanner.l, + tests/test-bison-yylval/Makefile.am, + tests/test-bison-yylval/main.c, tests/test-bison-yylval/parser.y, + tests/test-bison-yylval/scanner.l, tests/test-c-cpp-nr/Makefile.am, + tests/test-c-cpp-nr/scanner.l, tests/test-c-cpp-r/Makefile.am, + tests/test-c-cpp-r/scanner.l, tests/test-header-nr/Makefile.am, + tests/test-header-nr/main.c, tests/test-header-nr/scanner.l, + tests/test-header-r/Makefile.am, tests/test-header-r/main.c, + tests/test-header-r/scanner.l, + tests/test-include-by-buffer/Makefile.am, + tests/test-include-by-buffer/scanner.l, + tests/test-include-by-reentrant/Makefile.am, + tests/test-include-by-reentrant/scanner.l, + tests/test-lineno-nr/Makefile.am, tests/test-lineno-nr/scanner.l, + tests/test-lineno-r/Makefile.am, tests/test-lineno-r/scanner.l, + tests/test-multiple-scanners-nr/Makefile.am, + tests/test-multiple-scanners-nr/main.c, + tests/test-multiple-scanners-nr/scanner-1.l, + tests/test-multiple-scanners-nr/scanner-2.l, + tests/test-multiple-scanners-r/Makefile.am, + tests/test-multiple-scanners-r/main.c, + tests/test-multiple-scanners-r/scanner-1.l, + tests/test-multiple-scanners-r/scanner-2.l, + tests/test-prefix-nr/Makefile.am, tests/test-prefix-nr/scanner.l, + tests/test-prefix-r/Makefile.am, tests/test-prefix-r/scanner.l, + tests/test-pthread/Makefile.am, tests/test-pthread/scanner.l, + tests/test-string-nr/Makefile.am, tests/test-string-nr/scanner.l, + tests/test-string-r/Makefile.am, tests/test-string-r/scanner.l, + tests/test-yyextra/Makefile.am, tests/test-yyextra/scanner.l: + Prepended explicit license to all test-*/ sources. + +2002-06-25 Will Estes + + * NEWS, po/ca.po, po/de.po, po/fr.po, po/sv.po, po/tr.po: new ca, + de, fr, sv, tr translations + +2002-06-19 Will Estes + + * TODO: add bootstrapper to the todo list + +2002-06-19 Will Estes + + * configure.in: new version number + +2002-06-19 Will Estes + + * TODO: update TODO list + +2002-06-19 Will Estes + + * NEWS, TODO, flex.texi, flexdef.h, main.c, options.c, options.h, + parse.y, scan.l: address typos in NEWS; add --posix option for ERE + parsing the way posix wants it; update the TODO file + +2002-05-31 Will Estes + + * README-alpha: made code quality warning more explicit; gave url + for cvs and beta flex + +2002-05-23 John Millaway + + * gen.c: Fixed bug where omission of user section 3 caused unmatched + #ifdef's in generated code. + +2002-05-20 Will Estes + + * configure.in: configure.in requires at least autoconf 2.50 + +2002-05-13 John Millaway + + * Makefile.am: Updated my email address. + +2002-05-10 John Millaway + + * flexdef.h, misc.c: chomp'd lines when reading external skel file. + +2002-05-07 Will Estes + + * po/sv.po: new sweedish translation from the translation project + +2002-04-29 Will Estes + + * po/ca.po: new catalan translation from the translation project + +2002-04-29 Will Estes + + * po/es.po: new spanish translation from the translation project + +2002-04-25 Will Estes + + * TODO: note that the lex matching of abc{1,3} is the posix behavior + and so we have a problem + +2002-04-25 Will Estes + + * flex.texi: note that the lex matching of abc{1,3} is the posix + behavior + +2002-04-23 Will Estes + + * configure.in: new version 2.5.7; use autoconf versioning info + +2002-04-23 Will Estes + + * NEWS: note changes in 2.5.7 + +2002-04-23 Will Estes + + * main.c: conditional compile gettext initialization + +2002-04-22 Will Estes + + * po/de.po: new german translation from the translation project + +2002-04-19 John Millaway + + * tests/test-include-by-reentrant/Makefile.am: Fixed command line + for test-include-by-reentrant/Makefile.am + +2002-04-19 John Millaway + + * tests/Makefile.am, tests/TEMPLATE/Makefile.am, + tests/test-array-nr/Makefile.am, tests/test-array-r/Makefile.am, + tests/test-basic-nr/Makefile.am, tests/test-basic-r/Makefile.am, + tests/test-bison-yylloc/Makefile.am, + tests/test-bison-yylval/Makefile.am, + tests/test-c-cpp-nr/Makefile.am, tests/test-c-cpp-r/Makefile.am, + tests/test-header-nr/Makefile.am, tests/test-header-r/Makefile.am, + tests/test-include-by-buffer/Makefile.am, + tests/test-include-by-reentrant/Makefile.am, + tests/test-lineno-nr/Makefile.am, tests/test-lineno-r/Makefile.am, + tests/test-multiple-scanners-nr/Makefile.am, + tests/test-multiple-scanners-r/Makefile.am, + tests/test-prefix-nr/Makefile.am, tests/test-prefix-r/Makefile.am, + tests/test-pthread/Makefile.am, tests/test-string-nr/Makefile.am, + tests/test-string-r/Makefile.am, tests/test-yyextra/Makefile.am: + Added -I . to compiler search path in tests (so it finds the + generated parser.h). + +2002-04-19 John Millaway + + * flexdef.h, misc.c, parse.y, sym.c: Applied 'const' to a few more + char*, where appropriate. + +2002-04-19 John Millaway + + * tests/TEMPLATE/Makefile.am, tests/test-array-nr/Makefile.am, + tests/test-array-r/Makefile.am, tests/test-basic-nr/Makefile.am, + tests/test-basic-r/Makefile.am, + tests/test-bison-yylloc/Makefile.am, + tests/test-bison-yylval/Makefile.am, + tests/test-c-cpp-nr/Makefile.am, tests/test-c-cpp-r/Makefile.am, + tests/test-header-nr/Makefile.am, tests/test-header-r/Makefile.am, + tests/test-include-by-buffer/Makefile.am, + tests/test-include-by-reentrant/Makefile.am, + tests/test-lineno-nr/Makefile.am, tests/test-lineno-r/Makefile.am, + tests/test-multiple-scanners-nr/Makefile.am, + tests/test-multiple-scanners-r/Makefile.am, + tests/test-prefix-nr/Makefile.am, tests/test-prefix-r/Makefile.am, + tests/test-pthread/Makefile.am, tests/test-string-nr/Makefile.am, + tests/test-string-r/Makefile.am, tests/test-yyextra/Makefile.am: + Added top_builddir to -I path. Changed $(srcdir)/$(testname) to + ./$(testname) in 'make test' rule. + +2002-04-19 John Millaway + + * flexdef.h, gen.c, misc.c: Changed 'char[]' to 'const char*' + wherever in conflicted with gettext. + +2002-04-19 Will Estes + + * po/fr.po, po/sv.po: new files from translation after 2.5.6 beta + release + +2002-04-18 John Millaway + + * tests/test-lineno-r/Makefile.am: Fixed minor typo/cut and paste + error. + +2002-04-18 John Millaway + + * configure.in: Added yylineno test. + +2002-04-18 John Millaway + + * tests/Makefile.am: Added yylineno tests. + +2002-04-18 John Millaway + + * tests/test-lineno-nr/.cvsignore, + tests/test-lineno-nr/Makefile.am, tests/test-lineno-nr/scanner.l, + tests/test-lineno-nr/test.input, tests/test-lineno-r/.cvsignore, + tests/test-lineno-r/Makefile.am, tests/test-lineno-r/scanner.l, + tests/test-lineno-r/test.input: Created yylineno tests. + +2002-04-15 John Millaway + + * scanopt.c: Applied gettext macros to error messages from scanopt. + +2002-04-15 John Millaway + + * buf.c, faq.texi, options.c, options.h, scanopt.c, scanopt.h: + Changed copyright from Millaway to flex? U.S. Gov't? Regents of U. + Cali.? Paxson? + +2002-04-15 Will Estes + + * tests/test-bison-yylloc/Makefile.am, + tests/test-header-nr/Makefile.am, tests/test-header-r/Makefile.am: + we missed a few main.c files in the distribution + +2002-04-15 Will Estes + + * TODO: a lot more work has happened to flex; note this by removing + a number of TODO entries + +2002-04-15 Will Estes + + * TODO: make sure all gettext modules use gettext translation + facilities + +2002-04-14 John Millaway + + * faq.texi: Converted faqs 34-41 to texinfo. + +2002-04-14 John Millaway + + * Makefile.am, faq.texi, flex.texi: Added faq.texi to archive. + Added faq.texi to flex_TEXINFOS macro in Makefile.am. flex.texi now + includes faq.texi. + +2002-04-13 John Millaway + + * flexdef.h: defined FLEX_EXIT macro to call longjmp on errors. + +2002-04-13 John Millaway + + * main.c, misc.c: Replaced exit(2) calls with longjmps (in the form + of FLEX_EXIT macro). Moved main() to flex_main() to allow flex to + be called from a library. + +2002-04-13 John Millaway + + * scanopt.c: Fixed minor typo in error message + +2002-04-12 Will Estes + + * tests/test-header-nr/Makefile.am, + tests/test-header-r/Makefile.am, + tests/test-multiple-scanners-nr/Makefile.am, + tests/test-multiple-scanners-r/Makefile.am, + tests/test-pthread/Makefile.am, tests/test-string-nr/Makefile.am, + tests/test-string-r/Makefile.am, tests/test-yyextra/Makefile.am: + removed eroneous files listed in EXTRA_DIST + +2002-04-12 Will Estes + + * tests/test-yyextra/.cvsignore: ignore Makefile.in + +2002-04-12 Will Estes + + * tests/test-string-r/.cvsignore: it's Makefile.in, not makefile.in + +2002-04-12 Will Estes + + * tests/test-yyextra/Makefile.am, tests/test-yyextra/Makefile.in: + put test-yyextra under automake + +2002-04-12 Will Estes + + * tests/test-string-r/Makefile.am, tests/test-string-r/Makefile.in: + put test-string-r under automake + +2002-04-12 Will Estes + + * tests/test-string-nr/.cvsignore, tests/test-string-r/.cvsignore: + we can ignore Makefile.in + +2002-04-12 Will Estes + + * tests/test-string-nr/Makefile.am, + tests/test-string-nr/Makefile.in: put test-string-nr under automake + +2002-04-12 Will Estes + + * tests/test-pthread/.cvsignore: ignore Makefile.in + +2002-04-12 Will Estes + + * tests/test-pthread/Makefile.am, tests/test-pthread/Makefile.in: + put test-pthread under automake + +2002-04-12 Will Estes + + * tests/test-prefix-r/Makefile.am, tests/test-prefix-r/Makefile.in: + put test-prefix-r under automake + +2002-04-12 Will Estes + + * tests/test-prefix-nr/.cvsignore, tests/test-prefix-r/.cvsignore: + we can ignore Makefile.in + +2002-04-12 Will Estes + + * tests/test-prefix-nr/Makefile.am, + tests/test-prefix-nr/Makefile.in: put test-prefix-nr under automake + +2002-04-12 Will Estes + + * tests/test-multiple-scanners-r/Makefile.am, + tests/test-multiple-scanners-r/Makefile.in: put + test-multiple-scanners-r under automake + +2002-04-12 Will Estes + + * tests/test-multiple-scanners-nr/.cvsignore, + tests/test-multiple-scanners-r/.cvsignore: we can ignore Makefile.in + now + +2002-04-12 Will Estes + + * tests/test-multiple-scanners-nr/Makefile.am, + tests/test-multiple-scanners-nr/Makefile.in: put + test-multiple-scanners-nr under automake + +2002-04-11 Will Estes + + * tests/test-c-cpp-nr/Makefile.am, tests/test-c-cpp-r/Makefile.am: + we didn't need parser.y + +2002-04-11 Will Estes + + * TODO: work done on the test suite; remove relevant entries from + TODO + +2002-04-10 Will Estes + + * tests/test-include-by-reentrant/.cvsignore, + tests/test-include-by-reentrant/Makefile.am, + tests/test-include-by-reentrant/Makefile.in: put + test-include-by-reentrant under automake + +2002-04-09 Will Estes + + * tests/test-include-by-buffer/.cvsignore: we have a Makefile.in + which we need to ignore + +2002-04-09 Will Estes + + * tests/test-include-by-buffer/Makefile.am, + tests/test-include-by-buffer/Makefile.in: test-include-by-buffer now + under automake control + +2002-04-09 Will Estes + + * tests/TEMPLATE/Makefile.am: and we want LFLAGS in the rule to make + scanner.c as well + +2002-04-09 Will Estes + + * tests/test-header-r/.cvsignore, tests/test-header-r/Makefile.am, + tests/test-header-r/Makefile.in: put test-header-r under automake + +2002-04-09 Will Estes + + * tests/test-header-nr/.cvsignore: we now generate a Makefile.in + from automake; cvs should ignore it + +2002-04-09 Will Estes + + * tests/test-header-nr/Makefile.am: add dependencies for main.o and + scaner.h + +2002-04-09 Will Estes + + * tests/TEMPLATE/Makefile.am: We may want to have LFLAGS readily + available + +2002-04-09 Will Estes + + * tests/test-header-nr/Makefile.am, + tests/test-header-nr/Makefile.in: put test-header-nr under automake + +2002-04-09 Will Estes + + * tests/TEMPLATE/Makefile.am: oops, we need to clean objects too + +2002-04-09 Will Estes + + * tests/TEMPLATE/Makefile.am, tests/test-array-nr/Makefile.am, + tests/test-array-r/Makefile.am, tests/test-basic-nr/Makefile.am, + tests/test-basic-r/Makefile.am, + tests/test-bison-yylloc/Makefile.am, + tests/test-bison-yylval/Makefile.am, + tests/test-c-cpp-nr/Makefile.am, tests/test-c-cpp-r/Makefile.am: now + that config.h lives in the top-level directory, we need to tell the + testsuite + +2002-04-08 Will Estes + + * tests/test-array-nr/.cvsignore, tests/test-array-r/.cvsignore, + tests/test-basic-nr/.cvsignore, tests/test-basic-r/.cvsignore, + tests/test-bison-yylval/.cvsignore, tests/test-c-cpp-nr/.cvsignore, + tests/test-c-cpp-r/.cvsignore: we can ignore some Makefile.in + +2002-04-08 Will Estes + + * configure.in, tests/TEMPLATE/Makefile.am: only one config file + header apparently; this will have consequences in the test suite + +2002-04-08 Will Estes + + * tests/test-bison-yylval/Makefile.am, + tests/test-bison-yylval/Makefile.in: adding automake support + +2002-04-08 Will Estes + + * tests/test-bison-yylloc/.cvsignore, + tests/test-bison-yylloc/Makefile.am: tuned Makefile.am to build + correctly; ignore Makefile.in now + +2002-04-08 Will Estes + + * tests/configure.in: test suite changes + +2002-04-08 Will Estes + + * autogen.sh, configure.in, tests/.cvsignore, tests/Makefile.am, + tests/Makefile.in, tests/README, tests/TEMPLATE/.cvsignore, + tests/TEMPLATE/Makefile.am, tests/TEMPLATE/Makefile.in, + tests/configure.in, tests/create-test, tests/create-test.pl, + tests/test-array-nr/Makefile.am, tests/test-array-nr/Makefile.in, + tests/test-array-r/Makefile.am, tests/test-array-r/Makefile.in, + tests/test-basic-nr/Makefile.am, tests/test-basic-nr/Makefile.in, + tests/test-basic-r/Makefile.am, tests/test-basic-r/Makefile.in, + tests/test-bison-yylloc/Makefile.am, + tests/test-bison-yylloc/Makefile.in, + tests/test-c-cpp-nr/Makefile.am, tests/test-c-cpp-nr/Makefile.in, + tests/test-c-cpp-r/Makefile.am, tests/test-c-cpp-r/Makefile.in: test + suite changes + +2002-04-05 John Millaway + + * flex.texi: Corrected error in manual regarding return type for + yy_scan_{string,buffer,bytes}. + +2002-04-05 Will Estes + + * po/de.po: new german translations from the translation project + +2002-04-03 Will Estes + + * po/es.po: new spanish translations + +2002-04-01 Will Estes + + * Makefile.am: DIST_SUBDIRS: new variable. we can build flex with + SUBDIRS and then build the distribution using DIST_SUBDIRS + +2002-04-01 Will Estes + + * main.c: fix typo in comment + +2002-03-31 John Millaway + + * main.c: Documented the header file kludge, (in anticipation of + buffering Section 1.) + +2002-03-31 John Millaway + + * flex.texi: Created appendix "Makefiles and Flex" in the manual. + +2002-03-30 John Millaway + + * flex.texi: updating manual. + +2002-03-29 Will Estes + + * po/POTFILES.in: we want parse.y, not parse.c + +2002-03-29 John Millaway + + * flex.texi: Indexing the manual (75% done). + +2002-03-29 Will Estes + + * Makefile.am: unlisted intermediate flex/yacc-created files + +2002-03-29 Will Estes + + * TODO: millaway has done more work + +2002-03-29 Will Estes + + * Makefile.am, configure.in: ok, one last touch up; users most + likely wont have help2man so we need to insure that's ok + +2002-03-29 Will Estes + + * Makefile.am: fine tune flex.1 some more + +2002-03-29 Will Estes + + * Makefile.am, configure.in: generalize the manpage a bit and tell + autofoo about help2man + +2002-03-29 Will Estes + + * po/da.po: new danish from translation project robot + +2002-03-28 John Millaway + + * flex.texi: Indexing the manual -- it's only half done. + +2002-03-28 John Millaway + + * flex.texi: flex manual now uses automake's versioning info. + +2002-03-28 John Millaway + + * README.cvs-snapshot: Mentioned requirements for gettext and + help2man. + +2002-03-28 John Millaway + + * Makefile.am, main.c: Output of `flex --version` now matches GNU + coding standards. Makefile.am now uses `help2man` to generate + flex.1 + +2002-03-27 Will Estes + + * TODO: millaway has done a lot on the TODO list; remove those items + that he has take care of + +2002-03-27 Will Estes + + * README.cvs-snapshot: edited millaway's initial draft + +2002-03-27 John Millaway + + * README.cvs-snapshot: Created file. + +2002-03-27 John Millaway + + * flex.texi: Fixed case of node names in flex.texi. + +2002-03-24 Will Estes + + * TODO: lex- and yacc- generated files + +2002-03-24 Will Estes + + * po/fr.po: new french + +2002-03-18 Will Estes + + * NEWS: ending periods in news items removed; mention nounistd + options + +2002-03-18 Will Estes + + * po/sv.po: updated sweedish translations + +2002-03-18 Will Estes + + * po/de.po: german translation + +2002-03-18 John Millaway + + * flex.skl, flex.texi, main.c, options.c, options.h, scan.l: Removed + CFront 1.2 -specific code from skeleton, because CFront now defines + __cplusplus properly. Removed TurboC-specific code from skeleton. + Skeleton now includes proper C++ standard headers. Relocated + "unistd.h" code after user section 1 to allow user to overrid it. + New option "nounistd" to suppress unistd.h from being included. + +2002-03-15 Will Estes + + * po/tr.po: new turkish translation + +2002-03-15 Will Estes + + * NEWS: mention included translations + +2002-03-15 Will Estes + + * TODO: we've done the gettext thing, but sometime we should get + 0.11.1 + +2002-03-15 Will Estes + + * po/ca.po: new catalan translation + +2002-03-14 John Millaway + + * flex.texi: Added section on format of comments. + +2002-03-14 John Millaway + + * flex.texi: Split format chapter into sections. + +2002-03-14 John Millaway + + * flex.texi: Removed explicit pointers in node definitions. + +2002-03-14 Will Estes + + * configure.in: unistd.h can be problematic + +2002-03-14 Will Estes + + * tests/README: editing changes to README + +2002-03-13 Will Estes + + * po/POTFILES.in: scan.l, not scan.c because gettext gets confused + +2002-03-13 Will Estes + + * scan.l: gettext cruft + +2002-03-13 Will Estes + + * tests/descriptions: separate out test descriptions + +2002-03-13 Will Estes + + * po/LINGUAS: french and korean dont crash now + +2002-03-12 Will Estes + + * po/fr.po, po/ko.po: remove duplicate messages as per advice from + Jordi Mallach + +2002-03-12 Will Estes + + * gettext.h: yes, more gettext cruft + +2002-03-12 Will Estes + + * ABOUT-NLS, config.rpath, m4/codeset.m4, m4/gettext.m4, + m4/glibc21.m4, m4/iconv.m4, m4/isc-posix.m4, m4/lcmessage.m4, + m4/lib-ld.m4, m4/lib-link.m4, m4/lib-prefix.m4, m4/progtest.m4: this + is gettext cruft + +2002-03-12 Will Estes + + * NEWS: gettext and autofoo are now involved + +2002-03-12 Will Estes + + * Makefile.am, autogen.sh, configure.in, flexdef.h, main.c: mostly, + changes for gettext + +2002-03-12 Will Estes + + * po/ca.po, po/da.po, po/es.po, po/ru.po, po/sv.po, po/tr.po: these + sure change a lot + +2002-03-12 Will Estes + + * TODO: note about cvs documentation + +2002-03-12 Will Estes + + * po/LINGUAS: we now have turkish + +2002-03-12 Will Estes + + * po/tr.po: updated translations, i think + +2002-03-12 Will Estes + + * po/ca.po, po/da.po, po/es.po, po/fr.po, po/ko.po, po/ru.po, + po/sv.po, po/tr.po: ok, maybe we do keep these things? + +2002-03-12 Will Estes + + * README-alpha: README-alpha for those bad-hair days + +2002-03-12 Will Estes + + * m4/.cvsignore, m4/Makefile.am: ok,now we kinda have a m4/ subdir + for gettext + +2002-03-12 Will Estes + + * po/.cvsignore, po/LINGUAS, po/Makevars, po/POTFILES.in, po/da.po, + po/es.po, po/fr.po, po/ko.po, po/ru.po, po/sv.po: now, we have a po/ + subdirectory for gettext. i hope you're happy + +2002-03-12 Will Estes + + * po/ca.po: removing po files, maybe + +2002-03-12 Will Estes + + * tests/.cvsignore: ignore autom4te.cache + +2002-03-11 Will Estes + + * po/ca.po, po/da.po, po/es.po, po/fr.po, po/ko.po, po/ru.po, + po/sv.po: po files from debian + +2002-03-08 Will Estes + + * TODO: add several notes about tasks which need doing; create a new + top-level entry for generic coding concerns (this is distinct from + specific API or other such issues) + +2002-03-06 Will Estes + + * README: eliminate to.do and faqs from the README file + +2002-03-06 Will Estes + + * TODO: more notes on tests/ + +2002-03-06 Will Estes + + * Makefile.am: remove subdirectories from EXTRA_DIST; add a SUBDIRS + macro to handle examples/; clean up the dist-hook target + +2002-03-06 Will Estes + + * configure.in: we want to generate Makefiles in some more + subdirectories; automake will like this + +2002-03-06 Will Estes + + * TODO: notes on subdirectories + +2002-03-05 Will Estes + + * examples/.cvsignore, examples/Makefile.am: now examples/ fits into + automake + +2002-03-05 Will Estes + + * examples/fastwc/.cvsignore, examples/fastwc/Makefile.am: + examples/fastwc now fits into automake + +2002-03-05 Will Estes + + * examples/manual/.cvsignore, examples/manual/Makefile.am, + examples/manual/Makefile.examples, examples/manual/README: + examples/manual directory now fits into automake + +2002-03-05 Will Estes + + * examples/manual/Makefile: renamed Makefile to Makefile.examples + for automake's sake + +2002-03-04 Will Estes + + * Makefile.am: add parse.c and scan.c to built_sources + +2002-02-24 John Millaway + + * Makefile.am: Removed CVS-specific code from 'dist-hook' target so + anybody with a copy of the tree can build a dist. + +2002-02-22 John Millaway + + * tests/Makefile.in: Converted test script to portable /bin/sh. + +2002-02-22 John Millaway + + * tests/test-bison-yylloc/Makefile.in: Added some spaces in shell + scripts for portability. + +2002-02-22 John Millaway + + * tests/create-test.pl: Fixed #! line for portability. + +2002-02-22 John Millaway + + * tests/test-bison-yylloc/Makefile.in: Fixed return status code on + bison-lloc test. + +2002-02-21 John Millaway + + * tests/create-test.pl: Added script to auto-create tests. Probably + overkill. + +2002-02-21 John Millaway + + * flex.skl: Fixed C++ #ifdef problem. Removed mistyped __CPLUSPLUS + macro. Removed THROW_NIL. Not sure where it came from in the first + place. + +2002-02-21 John Millaway + + * tests/README, tests/TEMPLATE/Makefile.in, tests/configure.in, + tests/test-c-cpp-nr/.cvsignore, tests/test-c-cpp-nr/Makefile.in, + tests/test-c-cpp-nr/scanner.l, tests/test-c-cpp-nr/test.input, + tests/test-c-cpp-r/.cvsignore, tests/test-c-cpp-r/Makefile.in, + tests/test-c-cpp-r/scanner.l, tests/test-c-cpp-r/test.input: Added + test-c-cpp-nr and test-c-cpp-r. + +2002-02-16 John Millaway + + * flex.skl: Added missing #endif. + +2002-02-07 Will Estes + + * tests/TEMPLATE/.cvsignore, tests/test-array-nr/.cvsignore, + tests/test-array-r/.cvsignore, tests/test-basic-nr/.cvsignore, + tests/test-basic-r/.cvsignore, tests/test-bison-yylloc/.cvsignore, + tests/test-bison-yylval/.cvsignore, + tests/test-header-nr/.cvsignore, tests/test-header-r/.cvsignore, + tests/test-include-by-buffer/.cvsignore, + tests/test-include-by-reentrant/.cvsignore, + tests/test-multiple-scanners-nr/.cvsignore, + tests/test-multiple-scanners-r/.cvsignore, + tests/test-prefix-nr/.cvsignore, tests/test-prefix-r/.cvsignore, + tests/test-pthread/.cvsignore, tests/test-string-nr/.cvsignore, + tests/test-string-r/.cvsignore, tests/test-yyextra/.cvsignore: add + OUTPUT to .cvsignore files in test directories; it's also in the + template directory + +2002-02-06 Will Estes + + * gen.c: fix interrupted reads and freads; from the debian package + maintainer + +2002-02-06 Will Estes + + * flex.texi, flexdef.h, main.c, nfa.c: support large flex tables; + from debian package maintainer + +2002-01-29 Will Estes + + * tests/configure.in: add more output files to account for new tests + +2002-01-03 Will Estes + + * tests/test-array-nr/.cvsignore, tests/test-array-nr/Makefile.in, + tests/test-array-nr/scanner.l, tests/test-array-nr/test.input: add + this test + +2002-01-03 Will Estes + + * tests/test-array-r/.cvsignore, tests/test-array-r/Makefile.in, + tests/test-array-r/scanner.l, tests/test-array-r/test.input: add + this test suite + +2001-11-20 Will Estes + + * flex.skl, main.c: millaway: Fixed yytext_ptr when using %array in + reentrant scanner + +2001-11-20 Will Estes + + * buf.c: oops, forgot this one line + +2001-11-14 Will Estes + + * tests/test-header-r/.cvsignore, tests/test-header-r/Makefile.in, + tests/test-header-r/main.c, tests/test-header-r/scanner.l, + tests/test-header-r/test.input: and more fallout + +2001-11-14 Will Estes + + * TODO, flex.skl, flex.texi, flexdef.h, main.c, misc.c, + tests/README, tests/TEMPLATE/Makefile.in, tests/configure.in, + tests/test-basic-r/scanner.l, tests/test-bison-yylloc/.cvsignore, + tests/test-bison-yylloc/Makefile.in, + tests/test-bison-yylloc/parser.y, + tests/test-bison-yylloc/scanner.l, + tests/test-bison-yylval/.cvsignore, + tests/test-bison-yylval/Makefile.in, + tests/test-bison-yylval/parser.y, + tests/test-bison-yylval/scanner.l, + tests/test-include-by-reentrant/scanner.l, + tests/test-prefix-r/scanner.l, tests/test-pthread/scanner.l, + tests/test-string-r/scanner.l, tests/test-yyextra/scanner.l: more + from the same batch + +2001-11-14 Will Estes + + * tests/test-bison-yylloc/main.c, tests/test-bison-yylval/main.c, + tests/test-header-nr/.cvsignore, tests/test-header-nr/Makefile.in, + tests/test-header-nr/main.c, tests/test-header-nr/scanner.l, + tests/test-header-nr/test.input, + tests/test-multiple-scanners-nr/.cvsignore, + tests/test-multiple-scanners-nr/Makefile.in, + tests/test-multiple-scanners-nr/main.c, + tests/test-multiple-scanners-nr/scanner-1.l, + tests/test-multiple-scanners-nr/scanner-2.l, + tests/test-multiple-scanners-r/.cvsignore, + tests/test-multiple-scanners-r/Makefile.in, + tests/test-multiple-scanners-r/main.c, + tests/test-multiple-scanners-r/scanner-1.l, + tests/test-multiple-scanners-r/scanner-2.l: a big batch from + millaway + +2001-10-26 Will Estes + + * NEWS: now NEWS has forgotten about the _r variables + +2001-10-26 Will Estes + + * flex.skl, flex.texi, gen.c, main.c, + tests/test-bison-yylloc/scanner.l, + tests/test-bison-yylval/scanner.l, + tests/test-include-by-reentrant/scanner.l, + tests/test-prefix-nr/scanner.l, tests/test-pthread/scanner.l, + tests/test-string-r/scanner.l, tests/test-yyextra/scanner.l: + millaway simplified the reentrant api; here's the result + +2001-10-23 Will Estes + + * main.c, options.c, options.h: more from millaway + +2001-10-22 Will Estes + + * main.c, options.c, options.h: the last checkin was broken; + millaway fixed it + +2001-10-22 Will Estes + + * flex.skl, flex.texi, gen.c, main.c, misc.c, options.h, scan.l, + scanopt.c, tests/README, tests/configure.in: phew, millaway's latest + batch + +2001-10-21 Will Estes + + * flex.skl: flex.skl should come up in C mode + +2001-10-21 Will Estes + + * flex.skl: apparently, isatty and c++ need help getting along (from + octave) + +2001-10-19 Will Estes + + * NEWS: document new options and new option handling + +2001-10-19 Will Estes + + * TODO: tell emacs that TODO is a text/outline mode file + +2001-10-19 Will Estes + + * TODO: we have new long options; we need to document that + +2001-10-19 Will Estes + + * NEWS: tell emacs that NEWS is text/outline mode + +2001-10-19 Will Estes + + * flex.skl: oops, lost a line somewhere in the merge process on + millaway's work + +2001-10-17 Will Estes + + * Makefile.am, buf.c, flex.skl, flex.texi, flexdef.h, main.c, + misc.c, options.c, options.h, parse.y, scan.l, scanopt.c, scanopt.h: + merge latest batch of millaway's changes + +2001-09-22 Will Estes + + * main.c: Fixed typo in options display + +2001-09-20 Will Estes + + * main.c: reentrant and non-reentrant scanners share the same yywrap + MACRO. millaway + +2001-09-20 Will Estes + + * TODO: clarify item on comments in lexical files + +2001-09-20 Will Estes + + * NEWS, scan.l: now flex recognizes \r as an eol character + +2001-09-20 Will Estes + + * Makefile.am: specify cvsroot so automake distcheck works + +2001-09-19 Will Estes + + * flex.texi: tex has lost its mind; we remove parentheses to + compensate + +2001-09-19 Will Estes + + * NEWS: now that c++ is better supported, let's mention it as a news + item + +2001-09-19 Will Estes + + * examples/fastwc/wc1.l, examples/fastwc/wc2.l, + examples/fastwc/wc3.l, examples/fastwc/wc4.l, + examples/fastwc/wc5.l, flex.skl, main.c: commit the backwash from + the branch merges + +2001-09-19 Will Estes + + * FlexLexer.h, examples/testxxLexer.l, flex.skl: made preliminary + c++ fixes; the intent is to make it work with recent c++ compilers + +2001-08-26 Will Estes + + * main.c: remove argv_fixup; fix typo in error message; changes from + millaway's branch + +2001-08-24 Will Estes + + * NEWS: mention no more c++ comments in c scanners + +2001-08-21 John Millaway + + * flex.skl: Changed // comments to /* */ comments in skeleton. + +2001-08-19 John Millaway + + * flex.texi: Changed @var to @code everywhere. + +2001-08-16 Will Estes + + * to.do/flex.rmail: more mail + +2001-08-16 Will Estes + + * TODO: the manual now has its own section; we're not adding + comments either + +2001-08-04 John Millaway + + * tests/Makefile.in, tests/README, tests/TEMPLATE/Makefile.in, + tests/test-basic-nr/Makefile.in, tests/test-basic-r/Makefile.in, + tests/test-bison-yylloc/Makefile.in, + tests/test-bison-yylval/Makefile.in, + tests/test-include-by-buffer/Makefile.in, + tests/test-include-by-reentrant/Makefile.in, + tests/test-prefix-nr/Makefile.in, tests/test-prefix-r/Makefile.in, + tests/test-pthread/Makefile.in, tests/test-string-nr/Makefile.in, + tests/test-string-r/Makefile.in, tests/test-yyextra/Makefile.in: + Cleaned up the output of the tests. + +2001-08-03 Will Estes + + * TODO: note jason's thoughts on having a manpage + +2001-08-03 Will Estes + + * TODO: note millaway's assignment and tests to be under flex + license + +2001-08-01 John Millaway + + * tests/test-bison-yylval/scanner.l: Fixed semantics of test (the + success or failure of this test should be unaffected by this + change.) + +2001-08-01 Will Estes + + * autogen.sh: fake automake into believing that ChangeLog already + exists + +2001-08-01 Will Estes + + * Makefile.am: millaway needs to be covered in the ChangeLog + +2001-08-01 Will Estes + + * version.h: automake is supplying version info now so we just pick + it up + +2001-08-01 Will Estes + + * flex.texi: forgot braces on @copyright + +2001-08-01 John Millaway + + * flex.skl: Added missing argument to yy_flex_free. + +2001-08-01 Will Estes + + * AUTHORS: john millaway wrote the reentrant C support + +2001-08-01 Will Estes + + * flex.texi: add license node to the manual + +2001-08-01 Will Estes + + * TODO: c++ ideas + +2001-07-31 Will Estes + + * parse.y: error messages will now show up the way that emacs likes + them + +2001-07-31 Will Estes + + * Makefile.am: oops, left in an extra backslash + +2001-07-31 Will Estes + + * TODO: flex.texi is here; clarify tests/ rewrite issue + +2001-07-31 Will Estes + + * NEWS: hey, we have texinfo, not man + +2001-07-31 Will Estes + + * flex.1: no more manpage + +2001-07-31 Will Estes + + * Makefile.am: remove flex.1 and rewrite the dist-hook so that we + pick up a couple more directories + +2001-07-31 Will Estes + + * flex.texi: the namual now compiles; hurray + +2001-07-31 Will Estes + + * Makefile.am: first attempt at including the tests/ directory via + automake, dist-hook target added + +2001-07-31 Will Estes + + * tests/.cvsignore: ignore config.cache in tests/ directory + +2001-07-31 Will Estes + + * Makefile.am: automake groks the ChangeLog now so we don't have to + remind the maintainer to remake it + +2001-07-30 Will Estes + + * flex.texi: more corrections to the manual; the end is in site + +2001-07-30 Will Estes + + * TODO: auto-generated backup? + +2001-07-27 Will Estes + + * flex.texi: today's tinkering on the manual + +2001-07-27 Will Estes + + * Makefile.am: if we want flex.1 we have to say so in EXTRA_DIST + +2001-07-27 Will Estes + + * TODO: note future issues with flex.texi + +2001-07-27 Will Estes + + * Makefile.am: include flex.1 as it's the only working documentation + for now + +2001-07-27 Will Estes + + * Makefile.am: rearrange to work with automake on building the + ChangeLog + +2001-07-27 Will Estes + + * scan.l: automake is unhappy if we specify the outfile + +2001-07-26 Will Estes + + * flex.texi: more conversions/corrections + +2001-07-26 Will Estes + + * README: we removed misc/ so we don't mention it any more + +2001-07-25 Will Estes + + * flex.texi: begin the manual conversion to texinfo; yes, it's + broken right now + +2001-07-25 Will Estes + + * AUTHORS, THANKS: copy in manual author and thanks info + +2001-07-25 Will Estes + + * Makefile.am: how to fake the ChangeLog into showing up in the + distribution + +2001-07-25 Will Estes + + * Makefile.am: add YFLAGS so parse.h gets made + +2001-07-24 Will Estes + + * examples/fastwc/README, examples/fastwc/mywc.c, + examples/fastwc/wc1.l, examples/fastwc/wc2.l, + examples/fastwc/wc3.l, examples/fastwc/wc4.l, examples/fastwc/wc5.l: + re-add these files + +2001-07-24 Will Estes + + * TODO: reflect recent doings + +2001-07-24 Will Estes + + * Makefile.in: what with automake, we don't need Makefile.in any + more + +2001-07-24 Will Estes + + * configure.in: more rearranging for automake + +2001-07-24 Will Estes + + * to.do/flex.rmail: more mail came in + +2001-07-24 Will Estes + + * autogen.sh: adjust to automake's idea of the world + +2001-07-24 Will Estes + + * Makefile.am: add Vern's misc dependencies; noinst_SCRIPTS was + broken?; list a few last files to be included in the distribution + +2001-07-24 Will Estes + + * NEWS: rearrange for better order; add automake support as a news + item + +2001-07-24 Will Estes + + * Makefile.am: copyright notice on Makefile.am; document some -D + switches (are they still usable?) + +2001-07-24 Will Estes + + * TODO: add lex-replacement issue + +2001-07-24 Will Estes + + * Makefile.am: add EXTRA_DIST + +2001-07-23 Will Estes + + * autogen.sh: we need to do the same thing in each directory + +2001-07-23 Will Estes + + * configure.in: introduce automake into the macro calls + +2001-07-23 Will Estes + + * Makefile.am: add AUTOMAKE_OPTIONS, info_TEXINFOS, include_HEADERS, + noinst_HEADERS; it's libfl.a, not libflex.a + +2001-07-23 Will Estes + + * Makefile.am: bin_PROGRAMS and lib_LIBRARIES + +2001-07-23 Will Estes + + * to.do/streams.mail: streams.mail has moved here + +2001-07-23 Will Estes + + * TODO: add xref for teximanual + +2001-07-19 Will Estes + + * flex.1: include typo/punctuation fixes from a patch submitted by + noon@cote-dazur.com (Fabrice Bauzac) + +2001-07-17 Will Estes + + * TODO: we want gettext + +2001-06-24 Will Estes + + * flex.skl: include c++ STD fixes from quanstro@quanstro.net + +2001-06-24 Will Estes + + * flex.skl, gen.c: change some int types to size_t as per FreeBSD + 28364 from avn@any.ru + +2001-06-24 Will Estes + + * TODO: remove parse.[ch] from make clean target; repackage + distribution (not rework) + +2001-06-19 Will Estes + + * TODO: add memory api and reworking of flex.skl reworking + +2001-06-18 Will Estes + + * flex.skl: remove extraneous notice from flex.skl + +2001-06-18 Will Estes + + * flex.skl: patch memory leak as per millaway + +2001-06-17 Will Estes + + * to.do/flex.rmail: add vern's ok for copyright/license changes and + john's answer on line offsets + +2001-06-17 Will Estes + + * TODO: remove creation of .cvsignore files (it's done); add other + notes about the test suite + +2001-06-17 Will Estes + + * tests/TEMPLATE/.cvsignore, tests/test-basic-nr/.cvsignore, + tests/test-basic-r/.cvsignore, tests/test-bison-yylloc/.cvsignore, + tests/test-bison-yylval/.cvsignore, + tests/test-include-by-buffer/.cvsignore, + tests/test-include-by-reentrant/.cvsignore, + tests/test-prefix-nr/.cvsignore, tests/test-prefix-r/.cvsignore, + tests/test-pthread/.cvsignore, tests/test-string-nr/.cvsignore, + tests/test-string-r/.cvsignore, tests/test-yyextra/.cvsignore: + adding .cvsignore files for existing tests/ subdirectories + +2001-06-17 Will Estes + + * tests/README: reformat, say to add a description to this file and + mention what to do re .cvsignore + +2001-06-17 Will Estes + + * tests/TEMPLATE/cvsignore: create template for .cvsignore + +2001-06-17 Will Estes + + * TODO: reorganize for logical reasons; test suite now seems to run + out of the box + +2001-06-17 Will Estes + + * tests/.cvsignore: we dont want the Makefile either + +2001-06-17 Will Estes + + * tests/test-prefix-nr/test.input, tests/test-prefix-r/test.input: + test.input was supposed to be here + +2001-06-17 Will Estes + + * tests/.cvsignore: add autoconf legacy files to be ignored + +2001-06-17 Will Estes + + * autogen.sh: clarify usage instructions; prepare tests/ as well + +2001-06-17 Will Estes + + * tests/.cvsignore: . cvsignore for tests/ subdirectory + +2001-06-17 Will Estes + + * FlexLexer.h: tell emacs that FlexLexer.h is c++ + +2001-06-17 Will Estes + + * scan.l: tell emacs scan.l is in C mode + +2001-06-17 Will Estes + + * flex.skl: added punctuation + +2001-06-17 Will Estes + + * FlexLexer.h, Makefile.in, README, RoadMap, autogen.sh, ccl.c, + configure.in, dfa.c, ecs.c, flex.1, flex.skl, flexdef.h, gen.c, + libmain.c, libyywrap.c, main.c, misc.c, mkskel.sh, nfa.c, parse.y, + scan.l, sym.c, tblcmp.c, yylex.c: change copyright/license notices + as per Vern's response to Theo + +2001-06-15 Will Estes + + * to.do/flex.rmail: add bill fenlason's emails + +2001-06-15 Will Estes + + * COPYING: make changes as per Theo De Raadt; remove tabs + +2001-06-08 Will Estes + + * flex.skl: save errno as per Theo de Raadt + +2001-06-07 Will Estes + + * flex.1: correct hyphenation as per openbsd tree + +2001-06-05 Will Estes + + * Makefile.in, configure.in: change references to TESTS/ to tests/ + to account for the directory name changes + +2001-05-27 Will Estes + + * flex.skl, gen.c: commit john millaway's YY_G wrapper corrections + +2001-05-21 Will Estes + + * tests/Makefile.in: remove || exit calls + +2001-05-21 Will Estes + + * gen.c: complete john millaway's reentrant patch + +2001-05-21 Will Estes + + * to.do/flex.rmail: more flex messages in the queue + +2001-05-18 Will Estes + + * flex.skl, flexdef.h, gen.c, main.c, nfa.c, scan.l: john millaway's + reentrancy patch + +2001-05-18 Will Estes + + * tests/Makefile.in: remove || exit from testing loop + +2001-05-18 Will Estes + + * Makefile.in: tell make about the tests directory and its + associated targets + +2001-05-18 Will Estes + + * TODO: rethink the todo list + +2001-05-18 Will Estes + + * flex.1: describe reentrant api changes + +2001-05-18 Will Estes + + * TODO: mention work needed for tests/ + +2001-05-18 Will Estes + + * configure.in: tell auto* about the test directory + +2001-05-18 Will Estes + + * README: make punctuation uniform, mention the new tests/ directory + +2001-05-18 Will Estes + + * NEWS: reformat items; cut out old items and move them to ONEWS + +2001-05-18 Will Estes + + * ONEWS: move old NEWS items to ONEWS + +2001-05-18 Will Estes + + * tests/Makefile.in, tests/README, tests/TEMPLATE/Makefile.in, + tests/TEMPLATE/parser.y, tests/TEMPLATE/scanner.l, + tests/TEMPLATE/test.input, tests/configure.in, + tests/test-basic-nr/Makefile.in, tests/test-basic-nr/scanner.l, + tests/test-basic-nr/test.input, tests/test-basic-r/Makefile.in, + tests/test-basic-r/scanner.l, tests/test-basic-r/test.input, + tests/test-bison-yylloc/Makefile.in, + tests/test-bison-yylloc/parser.y, + tests/test-bison-yylloc/scanner.l, + tests/test-bison-yylloc/test.input, + tests/test-bison-yylval/Makefile.in, + tests/test-bison-yylval/parser.y, + tests/test-bison-yylval/scanner.l, + tests/test-bison-yylval/test.input, + tests/test-include-by-buffer/Makefile.in, + tests/test-include-by-buffer/scanner.l, + tests/test-include-by-buffer/test-1.input, + tests/test-include-by-buffer/test-2.input, + tests/test-include-by-buffer/test-3.input, + tests/test-include-by-reentrant/Makefile.in, + tests/test-include-by-reentrant/scanner.l, + tests/test-include-by-reentrant/test-1.input, + tests/test-include-by-reentrant/test-2.input, + tests/test-include-by-reentrant/test-3.input, + tests/test-prefix-nr/Makefile.in, tests/test-prefix-nr/README, + tests/test-prefix-nr/scanner.l, tests/test-prefix-r/Makefile.in, + tests/test-prefix-r/README, tests/test-prefix-r/scanner.l, + tests/test-pthread/Makefile.in, tests/test-pthread/scanner.l, + tests/test-pthread/test-1.input, tests/test-pthread/test-2.input, + tests/test-pthread/test-3.input, tests/test-pthread/test-4.input, + tests/test-pthread/test-5.input, tests/test-string-nr/Makefile.in, + tests/test-string-nr/scanner.l, tests/test-string-r/Makefile.in, + tests/test-string-r/scanner.l, tests/test-yyextra/Makefile.in, + tests/test-yyextra/scanner.l, tests/test-yyextra/test.input: add + john millaway's test directory + +2001-05-04 Will Estes + + * to.do/flex.rmail: more mail in flex.rmail + +2001-05-03 Will Estes + + * FlexLexer.h, ccl.c, dfa.c, ecs.c, flex.skl, flexdef.h, gen.c, + libmain.c, libyywrap.c, main.c, misc.c, nfa.c, parse.y, scan.l, + sym.c, tblcmp.c, yylex.c: remove extraneous rcs keywords + +2001-05-03 Will Estes + + * README: mention RoadMap + +2001-05-01 Will Estes + + * examples/README, examples/debflex.awk, examples/manual/ChangeLog, + examples/manual/Makefile, examples/manual/README, + examples/manual/cat.lex, examples/manual/dates.lex, + examples/manual/datetest.dat, examples/manual/eof_rules.lex, + examples/manual/eof_test01.txt, examples/manual/eof_test02.txt, + examples/manual/eof_test03.txt, examples/manual/expr.lex, + examples/manual/expr.y, examples/manual/front.lex, + examples/manual/front.y, examples/manual/j2t.lex, + examples/manual/myname.lex, examples/manual/myname.txt, + examples/manual/myname2.lex, examples/manual/numbers.lex, + examples/manual/pas_include.lex, examples/manual/pascal.lex, + examples/manual/reject.lex, examples/manual/replace.lex, + examples/manual/string1.lex, examples/manual/string2.lex, + examples/manual/strtest.dat, examples/manual/unput.lex, + examples/manual/user_act.lex, examples/manual/userinit.lex, + examples/manual/wc.lex, examples/manual/yymore.lex, + examples/manual/yymore2.lex, examples/manual/yymoretest.dat, + examples/testxxLexer.l, to.do/README, to.do/Wilhelms.todo, + to.do/Wish-List, to.do/flex.rmail, to.do/unicode/FlexLexer.h, + to.do/unicode/ccl.c, to.do/unicode/changes.txt, + to.do/unicode/ecs.c, to.do/unicode/flex.1, to.do/unicode/flex.skl, + to.do/unicode/flexdef.h, to.do/unicode/gen.c, to.do/unicode/main.c, + to.do/unicode/misc.c, to.do/unicode/scan.l, to.do/unicode/tblcmp.c: + adding the rest of vern's files + +2001-05-01 Will Estes + + * README: mention misc/ directory + +2001-05-01 Will Estes + + * version.h: version is 2.5.5b + +2001-05-01 Will Estes + + * Makefile.in: remove header from top; add rule to generate + initscan.c just in case + +2001-05-01 Will Estes + + * configure.in: dont check for initscan.c; check for scan.l instead + +2001-05-01 Will Estes + + * RoadMap: list of source files + +2001-05-01 Will Estes + + * README: rewrite README to reflect changes in layout of directories + +2001-05-01 Will Estes + + * AUTHORS, THANKS, TODO: initial attempt at the files + +2001-05-01 Will Estes + + * COPYING: add 2001 copyright notice + +2001-05-01 Will Estes + + * autogen.sh: initial attempt at a bootstrap script for developers + +2001-05-01 Will Estes + + * flex.texi: texinfo manual, old contributed version + +2000-08-21 Vern Paxson + + * flex.1: fixed some bugs in examples of [[:...:]] ccls + +2000-08-21 Vern Paxson + + * version.h: version shipped to Dick King + +2000-08-21 Vern Paxson + + * flex.skl: explicit include of iostream.h + +2000-08-21 Vern Paxson + + * scan.l: if a newline is seen in , assume it + terminates the string. + +2000-08-21 Vern Paxson + + * flexdef.h, sym.c: moved symbol table definitions from flexdef.h + into sym.c + +2000-08-21 Vern Paxson + + * dfa.c: fixed underallocation for accset + +1997-06-27 Vern Paxson + + * COPYING: revised for rms + +1997-06-23 Vern Paxson + + * flex.skl: fixed memory leak + +1997-06-23 Vern Paxson + + * flex.1: input() doesn't destroy yytext + +1997-06-23 Vern Paxson + + * FlexLexer.h: wrapped with extern "C++" + +1996-12-13 Vern Paxson + + * flex.skl: use delete [] for yy_state_buf + +1996-10-29 Vern Paxson + + * flex.skl: fixed %option noinput + +1996-10-29 Vern Paxson + + * flex.skl: free(char*) fix ... Sigh ... + +1996-10-11 Vern Paxson + + * gen.c: bug fix for yymore()/yylineno interaction + +1996-10-11 Vern Paxson + + * gen.c: fixed memory leak + +1996-09-10 Vern Paxson + + * NEWS: release 2.5.4 + +1996-09-10 Vern Paxson + + * Makefile.in: more stuff for distclean + +1996-09-10 Vern Paxson + + * flex.skl: "str" -> "yy_str" + +1996-09-10 Vern Paxson + + * version.h: 2.5.4 + +1996-07-02 Vern Paxson + + * flex.skl: (attempted) fix for input() crossing a file boundary + +1996-05-29 Vern Paxson + + * NEWS: don't do Acorn diffs + +1996-05-29 Vern Paxson + + * NEWS: some minor additions for 2.5.3 + +1996-05-29 Vern Paxson + + * NEWS, version.h: 2.5.3 + +1996-05-25 Vern Paxson + + * flex.skl: initialize yy_more_offset etc. for yyFlexLexer class + +1996-05-25 Vern Paxson + + * flex.skl: niggling cosmetic tweak + +1996-05-25 Vern Paxson + + * flex.skl: bug fixes for yymore (especially with %array) + +1996-05-25 Vern Paxson + + * gen.c: yymore + %array tweaks + +1996-05-25 Vern Paxson + + * FlexLexer.h: added yy_{,prev_}more_offset + +1996-05-25 Vern Paxson + + * main.c: removed decl of unused library function + +1996-05-25 Vern Paxson + + * flex.skl: snapshot of cscope yymore fixes, prior to switching + yymore-on-%array approach + +1995-12-18 Vern Paxson + + * gen.c: don't stack states on NUL-transitions that are jams + +1995-09-27 Vern Paxson + + * libmain.c: fixed re Esmond Pitt's ancient suggestion + +1995-04-28 Vern Paxson + + * misc.c: ANSI C / Solaris tweak + +1995-04-24 Vern Paxson + + * flex.1: credits + +1995-04-24 Vern Paxson + + * NEWS: multiple FlexLexer.h includes + +1995-04-24 Vern Paxson + + * FlexLexer.h: fix multiple inclusions + +1995-04-24 Vern Paxson + + * scan.l: lint tweak + +1995-04-24 Vern Paxson + + * flex.1: typo fixed + +1995-04-24 Vern Paxson + + * flex.1: credits update + +1995-04-24 Vern Paxson + + * flex.skl: (char*) cast for realloc + +1995-04-24 Vern Paxson + + * NEWS: (char*) tweak + +1995-04-21 Vern Paxson + + * NEWS: VMS update for 2.5.2 + +1995-04-21 Vern Paxson + + * Makefile.in: clarify when 8-bit scanners are created by default, + vs. 7-bit + +1995-04-21 Vern Paxson + + * parse.y: reworked alloca() chud, from Francois + +1995-04-20 Vern Paxson + + * NEWS, version.h: 2.5.2 + +1995-04-20 Vern Paxson + + * flex.1: 2.5.2 update + +1995-04-20 Vern Paxson + + * dfa.c, main.c: const -> yyconst + +1995-04-20 Vern Paxson + + * Makefile.in: fixed some old libfl.a references + +1995-04-20 Vern Paxson + + * Makefile.in: some (but not all) of Francois' tweaks + +1995-04-20 Vern Paxson + + * configure.in: tweaks from Francois + +1995-04-20 Vern Paxson + + * flex.skl: yy_delete_buffer allows nil buffer pointer + +1995-04-20 Vern Paxson + + * main.c: do_stdinit now defaults to false + +1995-04-20 Vern Paxson + + * FlexLexer.h: remove first default for yylex(new_in, new_out) + +1995-04-20 Vern Paxson + + * flex.skl: rearrange some definitions; fix YY_NO_UNPUT + +1995-04-20 Vern Paxson + + * parse.y: more alloca() bullshit + +1995-04-20 Vern Paxson + + * misc.c: octal escape sequence must have just digits 0-7 + +1995-04-20 Vern Paxson + + * scan.l: '-' means stdin octal escape sequence must just be digits + 0-7 + +1995-04-20 Vern Paxson + + * main.c: -- terminates options + +1995-04-20 Vern Paxson + + * flexdef.h: added dataflush() prototype + +1995-04-20 Vern Paxson + + * misc.c: move dataflush, otoi prototypes into flexdef.h + +1995-04-20 Vern Paxson + + * flex.skl, gen.c: const -> yyconst + +1995-04-20 Vern Paxson + + * gen.c: fixed bug in needing yy_cp for -Cf w/ backing up + +1995-03-28 Vern Paxson + + * README, flex.1: Stan Adermann credit + +1995-03-27 Vern Paxson + + * README: beta-tester update + +1995-03-27 Vern Paxson + + * NEWS, version.h: 2.5.1 + +1995-03-27 Vern Paxson + + * flex.1: update date for 2.5.1 release, some feedbacker credits + +1995-03-27 Vern Paxson + + * gen.c: fixed lint problem with declaring yy_cp unnecessarily + +1995-03-27 Vern Paxson + + * dfa.c: {}'s around full-table initializations + +1995-03-21 Vern Paxson + + * README: for version 2.5 + +1995-03-21 Vern Paxson + + * flex.1: added note regarding yylineno should be maintained on a + per-buffer basis + +1995-03-21 Vern Paxson + + * NEWS: new C++ member functions + +1995-03-21 Vern Paxson + + * NEWS, flex.1: 2.5.0.8 update + +1995-03-21 Vern Paxson + + * main.c: rename yylineno if -P + +1995-03-20 Vern Paxson + + * flexdef.h: do_yylineno MARKER_DIFFERENCE depends on MAXIMUM_MNS + +1995-03-20 Vern Paxson + + * Makefile.in: removed redundant skel.c from DISTFILES + +1995-03-20 Vern Paxson + + * FlexLexer.h: debug(), setdebug(), lineno() + +1995-03-20 Vern Paxson + + * flex.skl: %option yylineno support + +1995-03-20 Vern Paxson + + * gen.c: read up to newline for interactive reads, rather than one + char + +1995-03-20 Vern Paxson + + * main.c, scan.l: added %option yylineno + +1995-03-18 Vern Paxson + + * gen.c: added do_yylineno + +1995-03-06 Vern Paxson + + * NEWS, flex.1: 2.5.0.7 + +1995-03-05 Vern Paxson + + * Makefile.in: realclean -> maintainer-clean + +1995-03-05 Vern Paxson + + * flex.skl: Added yy_flush_buffer + +1995-03-05 Vern Paxson + + * FlexLexer.h: added yy_flush_buffer + +1995-03-05 Vern Paxson + + * main.c: prefix support for yy_flush_buffer + +1995-03-05 Vern Paxson + + * parse.y: added %option yyclass + +1995-03-05 Vern Paxson + + * flexdef.h, main.c, scan.l: added yyclass + +1995-03-05 Vern Paxson + + * FlexLexer.h: Added switch_streams + +1995-03-05 Vern Paxson + + * flex.skl: added switch_streams + +1995-03-05 Vern Paxson + + * main.c: don't rename yy_flex_debug for C++ + +1995-03-05 Vern Paxson + + * gen.c: yy_flex_debug extern only if not C++ + +1995-03-05 Vern Paxson + + * FlexLexer.h: added yy_flex_debug member variable + +1995-03-05 Vern Paxson + + * flex.skl: yyFlexLexer initialization of yy_flex_debug + +1995-03-04 Vern Paxson + + * flexdef.h, main.c: VMS POSIX stuff + +1995-03-04 Vern Paxson + + * flex.skl: moved position of yy_init = 0 + +1995-03-04 Vern Paxson + + * flex.skl: added YY_EXIT_FAILURE + +1995-03-04 Vern Paxson + + * main.c: removed VMS-specific exit + +1995-03-04 Vern Paxson + + * dfa.c, flexdef.h, gen.c, main.c, misc.c, nfa.c, scan.l, sym.c, + yylex.c: internationalization aids + +1995-03-04 Vern Paxson + + * main.c: do yy_flex_debug prefix for both C++ and C + +1995-02-06 Vern Paxson + + * main.c: fixed program_name tweak again + +1995-01-11 Vern Paxson + + * main.c: oops, fixed program_name tweak + +1995-01-11 Vern Paxson + + * main.c: program_name is "flex" if argv[0] nil + +1995-01-10 Vern Paxson + + * NEWS: 2.5.0.5 + +1995-01-10 Vern Paxson + + * flex.1: Documented YY_NUM_RULES + +1995-01-10 Vern Paxson + + * Makefile.in: added formatted man page to MISC + +1995-01-10 Vern Paxson + + * main.c: help messages to stdout + +1995-01-09 Vern Paxson + + * gen.c: Added YY_NUM_RULES + +1995-01-09 Vern Paxson + + * flex.skl: better fix for #pragma problem + +1995-01-09 Vern Paxson + + * flexdef.h: better fix for #pragma portability problem + +1995-01-09 Vern Paxson + + * misc.c: "# line" -> #line + +1995-01-09 Vern Paxson + + * flex.skl, flexdef.h: comment out Turbo C #pragma's + +1995-01-09 Vern Paxson + + * scan.l: reset linenum on new file + +1995-01-09 Vern Paxson + + * flex.skl: isatty() extern + +1995-01-09 Vern Paxson + + * NEWS, flex.1: 2.5.0.4 + +1995-01-09 Vern Paxson + + * main.c: long options, VMS tweaks + +1995-01-09 Vern Paxson + + * Makefile.in: Added parse.c, parse.h for dist MISC directory + +1995-01-09 Vern Paxson + + * flexdef.h: some "const" cleansing + +1995-01-09 Vern Paxson + + * mkskel.sh: skel[] is now const + +1995-01-09 Vern Paxson + + * misc.c: some const cleansing + +1995-01-09 Vern Paxson + + * scan.l: #line in section 1 + +1995-01-05 Vern Paxson + + * sym.c: preen + +1994-12-29 Vern Paxson + + * configure.in: config.h from conf.in + +1994-12-29 Vern Paxson + + * flexdef.h: for VMS, delete -> remove + +1994-12-29 Vern Paxson + + * Makefile.in: config.h.in -> conf.in rm config.h on distclean + +1994-12-29 Vern Paxson + + * main.c: stdinit tweaks + +1994-12-29 Vern Paxson + + * scan.l: added nostdinit + +1994-12-28 Vern Paxson + + * NEWS: added MS-DOS note for 2.5.0.2 + +1994-12-28 Vern Paxson + + * flex.1: typos, tweaks + +1994-12-28 Vern Paxson + + * Makefile.in: removed flexdoc + +1994-12-28 Vern Paxson + + * flex.1: flexdoc/flex merge + +1994-12-28 Vern Paxson + + * flex.1: typos + +1994-12-28 Vern Paxson + + * NEWS: typo + +1994-12-28 Vern Paxson + + * flex.1: 2.5 update + +1994-12-28 Vern Paxson + + * NEWS: 2.5.0.2 + +1994-12-28 Vern Paxson + + * scan.l: fixed sense of %option main implying %option noyywrap + +1994-12-28 Vern Paxson + + * flex.skl: YY_FLEX_{MAJOR,MINOR}_VERSION fixed bug in unput + trashing yytext even with %array + +1994-12-17 Vern Paxson + + * flex.1: prior to 2.5 update + +1994-12-17 Vern Paxson + + * main.c: C++/-P fixes + +1994-12-17 Vern Paxson + + * FlexLexer.h: -P fixes constructor, destructor moved to flex.skl + +1994-12-17 Vern Paxson + + * flex.skl: YY_SKIP_YYWRAP yyFlexLexer constructor, destructor + +1994-12-15 Vern Paxson + + * gen.c: formatting + +1994-12-15 Vern Paxson + + * gen.c: fixed bug in adjusting yytext before backing up + +1994-12-10 Vern Paxson + + * scan.l: switched scanner itself over to [:xxx:] + +1994-12-10 Vern Paxson + + * flex.skl: added YY_FLEX_VERSION + +1994-12-10 Vern Paxson + + * scan.l: Fixed CCL-match pattern for [:whatever:] + +1994-12-10 Vern Paxson + + * parse.y: treat [:upper:] as [:lower:] if -i + +1994-12-06 Vern Paxson + + * NEWS: 2.5.0.1 + +1994-12-06 Vern Paxson + + * flex.skl, gen.c: input() maintains BOL + +1994-12-06 Vern Paxson + + * flex.skl: check size of buffer in yy_scan_buffer + +1994-12-06 Vern Paxson + + * flex.skl: added %option main, fixed missing %* + +1994-12-06 Vern Paxson + + * parse.y: added ccl exprs + +1994-12-06 Vern Paxson + + * scan.l: added ccl exprs, %option main + +1994-12-06 Vern Paxson + + * yylex.c: added %options, ccl exprs + +1994-12-05 Vern Paxson + + * misc.c: undid previous change + +1994-12-04 Vern Paxson + + * Makefile.in: Makefile.in from srcdir + +1994-12-04 Vern Paxson + + * Makefile.in: added skel.c to DISTFILES + +1994-12-04 Vern Paxson + + * flex.skl: added YYSTATE alias + +1994-12-04 Vern Paxson + + * scan.l: NL is now \r?\n + +1994-12-04 Vern Paxson + + * gen.c: use cerr for C++ diagnostics + +1994-12-03 Vern Paxson + + * flex.skl: undid YY_UNIX_NEWLINE + +1994-12-03 Vern Paxson + + * flexdef.h: STDC_HEADERS to check for stdlib + +1994-12-03 Vern Paxson + + * configure.in: AC_STDC_HEADERS -> AC_HEADER_STDC + +1994-12-03 Vern Paxson + + * misc.c: \n -> '\012' + +1994-12-03 Vern Paxson + + * flex.skl: Added YY_UNIX_NEWLINE + +1994-12-03 Vern Paxson + + * flex.skl: BOL changes + +1994-12-03 Vern Paxson + + * dfa.c: fixed bug with caseins but not ecs + +1994-12-03 Vern Paxson + + * gen.c: BOL changes some casts for Turbo C + +1994-12-03 Vern Paxson + + * main.c: messages identify filenames + +1994-12-03 Vern Paxson + + * misc.c: Increase slowly if realloc double overflows + +1994-12-03 Vern Paxson + + * nfa.c: YY_RULE_SETUP + +1994-12-03 Vern Paxson + + * scan.l: Added yy_XX_state %option's Added yy_set_bol + +1994-11-29 Vern Paxson + + * Makefile.in: don't remove ~ files + +1994-11-24 Vern Paxson + + * Makefile.in: get CFLAGS from autoconf + +1994-11-24 Vern Paxson + + * dfa.c, flex.skl, flexdef.h, gen.c, misc.c, parse.y, scan.l, sym.c: + Brian Madsen's tweaks for Borland + +1994-11-24 Vern Paxson + + * version.h: 2.5.0 + +1994-11-24 Vern Paxson + + * flexdef.h: Added do_stdinit + +1994-11-24 Vern Paxson + + * FlexLexer.h: Added yy_delete_buffer() in destructor + +1994-11-24 Vern Paxson + + * flex.skl: Added yy_set_interactive, YY_ALWAYS_INTERACTIVE, + YY_NEVER_INTERACTIVE, YY_NO_INPUT, YY_NO_UNPUT, YY_NO_*_STATE + +1994-11-24 Vern Paxson + + * main.c: Added do_stdinit, Think C hacks + +1994-11-24 Vern Paxson + + * scan.l: Added %options for input, always-interactive, + never-interactive, yy_scan_{buffer,bytes,string} + +1994-11-05 Vern Paxson + + * flex.skl: size_t #ifdef's for not compiling some statics + +1994-11-05 Vern Paxson + + * Makefile.in: $(FLEX) config.h + +1994-11-05 Vern Paxson + + * configure.in: config.h, size_t, malloc.h, sys/types.h + +1994-11-05 Vern Paxson + + * flexdef.h: config.h, size_t + +1994-11-05 Vern Paxson + + * main.c: yywrap option, no stdin/out init for VMS, mundane tweaks + +1994-11-05 Vern Paxson + + * parse.y: alloca, lint tweaks + +1994-11-05 Vern Paxson + + * scan.l: %option yywrap size_t tweaks + +1994-11-05 Vern Paxson + + * tblcmp.c: size_t tweaks + +1994-11-05 Vern Paxson + + * misc.c: size_t, STDC tweaks + +1994-11-05 Vern Paxson + + * flex.skl: Added yy_scan_{buffer,bytes,string}, plus tweaks + +1994-10-12 Vern Paxson + + * flex.skl: made stack code conditional on "stack" option + +1994-10-12 Vern Paxson + + * scan.l: added use of "stack" %option + +1994-08-03 Vern Paxson + + * gen.c: Fixed fencepost in call to yy_flex_strncpy + +1994-07-25 Vern Paxson + + * flex.skl: yy_eof_status -> yy_buffer_status + +1994-07-25 Vern Paxson + + * flex.skl: yy_flex_strcpy -> yy_flex_strncpy minor prototype tweak + +1994-07-25 Vern Paxson + + * gen.c: Bug fix for matching NUL's at end of token when + interactive. yy_flex_strcpy -> yy_flex_strncpy + +1994-07-25 Vern Paxson + + * nfa.c: No YY_USER_ACTION if continued action + +1994-03-16 Vern Paxson + + * flex.skl: Added fix for 8-bit chars returned by input() + +1994-03-16 Vern Paxson + + * flex.skl: Move definition of yy_flex_strcpy to come after #define + of yytext_ptr + +1994-01-08 Vern Paxson + + * mkskel.sh: flex.skel -> flex.skl + +1994-01-08 Vern Paxson + + * mkskel.sh: Initial revision + +1993-12-29 Vern Paxson + + * Makefile.in: Fixed scan.c target so "make" detects flex failure + +1993-12-27 Vern Paxson + + * scan.l: Added %option's + +1993-12-27 Vern Paxson + + * Makefile.in: Nuked FLEX_FLAGS that are now done using %option + +1993-12-27 Vern Paxson + + * parse.y, scan.l: %option + +1993-12-27 Vern Paxson + + * main.c: Reworked for %option + +1993-12-27 Vern Paxson + + * flexdef.h: Added "unspecified", globals for %option + +1993-12-27 Vern Paxson + + * sym.c: start condition #define's go to action file + +1993-12-27 Vern Paxson + + * misc.c: Added action_define() + +1993-12-27 Vern Paxson + + * scan.l: Minor consolidation using scon scopes etc + +1993-12-27 Vern Paxson + + * scan.l: Modified to use scon scopes + +1993-12-27 Vern Paxson + + * scan.l: indented rules + +1993-12-26 Vern Paxson + + * parse.y: Added scon_stk stuff, format_warn + +1993-12-26 Vern Paxson + + * flexdef.h: Added format_warn + +1993-12-26 Vern Paxson + + * parse.y: Working checkpoint prior to adding { stuff + +1993-12-26 Vern Paxson + + * flexdef.h, main.c: Added in_rule, deleted actvsc + +1993-12-26 Vern Paxson + + * misc.c: Added doubling of '\'s in filenames + +1993-12-26 Vern Paxson + + * scan.l: Added in_rule, doing_rule_action + +1993-12-26 Vern Paxson + + * sym.c: Removed actvsc + +1993-12-23 Vern Paxson + + * flex.1: -ooutput #line directives credits + +1993-12-23 Vern Paxson + + * flex.skl: Fixsed sense of test for %array + +1993-12-23 Vern Paxson + + * NEWS: 2.5.0 snapshot for Craig + +1993-12-23 Vern Paxson + + * parse.y: Added beginnings of { ... } + +1993-12-23 Vern Paxson + + * scan.l: Simplified scanning {}'s + +1993-12-20 Vern Paxson + + * flexdef.h: Added + +1993-12-17 Vern Paxson + + * flex.skl: prototypes for alloc/string routines + +1993-12-17 Vern Paxson + + * flex.skl: alloc, string routines internal + +1993-12-17 Vern Paxson + + * Makefile.in: Nuked lib{string,alloc}.c, added dependency of + yylex.o on parse.h + +1993-12-17 Vern Paxson + + * configure.in: Check for string.h + +1993-12-17 Vern Paxson + + * flexdef.h: Use autoconf for string/strings.h yy_flex_XXX -> + flex_XXX + +1993-12-17 Vern Paxson + + * scan.l: Added flex_XXX -> yy_flex_XXX wrappers + +1993-12-17 Vern Paxson + + * dfa.c, misc.c, sym.c: yy_flex_XXX -> flex_XXX + +1993-12-17 Vern Paxson + + * yylex.c: No more WHITESPACE token + +1993-12-16 Vern Paxson + + * FlexLexer.h, flex.skl: Added yy_top_state() + +1993-12-16 Vern Paxson + + * scan.l: simplified comment-scanning using push/pop states + +1993-12-16 Vern Paxson + + * parse.y: removed crufty WHITESPACE token, some uses of '\n' token + +1993-12-15 Vern Paxson + + * FlexLexer.h: start stack, extern "C++" moved + +1993-12-15 Vern Paxson + + * dfa.c: Bug fix for -CF + +1993-12-15 Vern Paxson + + * flexdef.h, misc.c: alloc routines take unsigned + +1993-12-15 Vern Paxson + + * flex.skl: start-state stacks, alloc routines take unsigned + +1993-12-15 Vern Paxson + + * flexdef.h, misc.c: bracket -CF table elements + +1993-12-13 Vern Paxson + + * misc.c: Do #bytes computation in {re,}allocate_array() only once + +1993-12-11 Vern Paxson + + * flex.skl, flexdef.h, gen.c, main.c, misc.c, scan.l, sym.c: + yy_str*() -> str*() + +1993-12-11 Vern Paxson + + * Makefile.in, dfa.c, flexdef.h, gen.c, main.c, misc.c, nfa.c, + parse.y, scan.l, sym.c: -o option + +1993-12-11 Vern Paxson + + * gen.c: lint tweak + +1993-12-11 Vern Paxson + + * NEWS: Expanded on extern "C++" news item + +1993-12-11 Vern Paxson + + * NEWS: 2.4.5 + +1993-12-11 Vern Paxson + + * flex.skl: Added yy_fill_buffer + +1993-12-11 Vern Paxson + + * gen.c: is_interactive -> yy_is_interactive + +1993-12-11 Vern Paxson + + * flex.1: Updated credits + +1993-12-11 Vern Paxson + + * Makefile.in: Fixed typo in "uninstall" target + +1993-12-11 Vern Paxson + + * gen.c: Updated comment regarding 0-based vs. 1-based arrays for + -CF. + +1993-12-11 Vern Paxson + + * dfa.c: Initialize dfaacc[0] for -CF representation Fixed minor + memory leak + +1993-12-11 Vern Paxson + + * main.c: #include "FlexLexer.h" -> + +1993-12-11 Vern Paxson + + * FlexLexer.h: Added extern "C++" wrapper + +1993-12-09 Vern Paxson + + * main.c: Detect REJECT etc. before generating YY_USES_REJECT! + +1993-12-09 Vern Paxson + + * gen.c: Fixed bug in interactive reads where char is unsigned + +1993-12-09 Vern Paxson + + * parse.y: Fixed bug in treating '$' as variable trailing context + +1993-12-09 Vern Paxson + + * version.h: 2.4.5 + +1993-12-07 Vern Paxson + + * README: pretester update + +1993-12-07 Vern Paxson + + * NEWS: 2.4.4 + +1993-12-07 Vern Paxson + + * flex.1: LexError(), C++ experiment warning, credits + +1993-12-07 Vern Paxson + + * scan.l: Fixed 8-bit bug + +1993-12-07 Vern Paxson + + * flex.skl, gen.c: Fixed nasty 8-bit bugs + +1993-12-07 Vern Paxson + + * dfa.c, ecs.c, flexdef.h, gen.c, main.c, nfa.c, tblcmp.c: + {min,max,abs} -> {MIN,MAX,ABS} + +1993-12-07 Vern Paxson + + * FlexLexer.h, flex.skl: Support for yyFlexLexer::LexerError + +1993-12-06 Vern Paxson + + * version.h: 2.4.4 + +1993-12-05 Vern Paxson + + * flex.1: credits update + +1993-12-05 Vern Paxson + + * Makefile.in: very minor "install" tweaks + +1993-12-05 Vern Paxson + + * flex.skl, nfa.c: YY_USER_ACTION generated now for each case in + action switch + +1993-12-04 Vern Paxson + + * flex.skl: Fixed bug in pointing yyin at a new file and resuming + scanning + +1993-12-03 Vern Paxson + + * NEWS: Added note regarding g++ 2.5.X + +1993-12-03 Vern Paxson + + * flex.1: updated credits + +1993-12-03 Vern Paxson + + * NEWS: ranlib addition for 2.4.3 + +1993-12-03 Vern Paxson + + * Makefile.in: Minor tweak to last change + +1993-12-03 Vern Paxson + + * Makefile.in: run ranlib on libfl.a + +1993-12-03 Vern Paxson + + * NEWS: Hopefully last update prior to 2.4.3 + +1993-12-03 Vern Paxson + + * flexdef.h, gen.c, misc.c, sym.c: lint tweaks + +1993-12-03 Vern Paxson + + * Makefile.in: Added exec_prefix + +1993-12-03 Vern Paxson + + * flex.1: credit update + +1993-12-03 Vern Paxson + + * flex.skl: lint tweak + +1993-12-03 Vern Paxson + + * NEWS: FlexLexer.h fixed for separate inclusion + +1993-12-03 Vern Paxson + + * FlexLexer.h, flex.skl, main.c: mods so FlexLexer.h can be included + separately + +1993-12-03 Vern Paxson + + * flex.1: -F incompatible with -+ + +1993-12-02 Vern Paxson + + * NEWS: Elaborated comments for 2.4.3 + +1993-12-02 Vern Paxson + + * NEWS: 2.4.3 + +1993-12-02 Vern Paxson + + * flex.1: Updated message regarding missing libfl.a routines Added + thanks to Noah Friedman + +1993-12-02 Vern Paxson + + * Makefile.in: Added libstring.c Modified "lint" target to use + -Dconst= Added a.out, lex.yy.cc to sundry clean targets + +1993-12-02 Vern Paxson + + * flex.skl, flexdef.h, gen.c, main.c, misc.c, scan.l, sym.c: Use + yy_strXXX() routines instead of + +1993-12-01 Vern Paxson + + * version.h: 2.4.3 + +1993-12-01 Vern Paxson + + * flexdef.h, misc.c: yy_flex_xmalloc() moved to misc.c + +1993-12-01 Vern Paxson + + * flex.skl: Fixed bug in yy_fatal_error() + +1993-12-01 Vern Paxson + + * Makefile.in: ... and remove plain tar file after compression + +1993-12-01 Vern Paxson + + * NEWS: 2.4.2 + +1993-12-01 Vern Paxson + + * Makefile.in: Produce both compress'd and gzip'd distribution tar + files + +1993-12-01 Vern Paxson + + * version.h: Release 2.4.2 + +1993-11-30 Vern Paxson + + * NEWS: -a -> -Ca + +1993-11-30 Vern Paxson + + * README: described configuration files in manifest + +1993-11-30 Vern Paxson + + * Makefile.in: Added intermediate step of copying MISC/alloca.c -> + alloca.c Included CPPFLAGS when compiling alloca.c + +1993-11-30 Vern Paxson + + * README: Credit to 2.4 pre-testers. + +1993-11-30 Vern Paxson + + * gen.c: Fixed nasty bug in short/long decl decision + +1993-11-30 Vern Paxson + + * flexdef.h: Lowered MAX_SHORT out of increased general paranoia. + Added yy_flex_xmalloc() proto + +1993-11-30 Vern Paxson + + * main.c: Fixed very minor typo in -v output + +1993-11-30 Vern Paxson + + * misc.c: Removed vestigal cast to (char) in isupper() call + +1993-11-30 Vern Paxson + + * misc.c: Added casts to unsigned Char for isascii() calls + +1993-11-30 Vern Paxson + + * parse.y: Added #ifdef chud for alloca() + +1993-11-30 Vern Paxson + + * Makefile.in: Added alloca + +1993-11-30 Vern Paxson + + * configure.in: Add AC_ALLOCA if using bison + +1993-11-29 Vern Paxson + + * Makefile.in: Added intermediate file going scan.l -> scan.c + +1993-11-29 Vern Paxson + + * Makefile.in: Removed parse.{c,h} from distribution files, since + they may not be all that portable. + +1993-11-29 Vern Paxson + + * flex.skl: Fixed %array YYLMAX headaches, added error message if + buffer needs growing but REJECT used + +1993-11-29 Vern Paxson + + * gen.c, main.c: Fixed YYLMAX headaches + +1993-11-29 Vern Paxson + + * flex.1: Documented that buffer can't grow if REJECT used + +1993-11-29 Vern Paxson + + * Makefile.in: Added parse.{c,h} to dist files + +1993-11-29 Vern Paxson + + * flex.skl, flexdef.h, gen.c, main.c, misc.c, scan.l: Fixed to + buffer section 1 definitions + +1993-11-29 Vern Paxson + + * sym.c: Fixed ANSI-C glitch with '%' operator + +1993-11-29 Vern Paxson + + * scan.l: Fixed mis-definition of ndlookup() + +1993-11-29 Vern Paxson + + * NEWS: 2.4 -> 2.4.1 + +1993-11-29 Vern Paxson + + * Makefile.in: Added install.sh, mkinstalldirs to distribution files + +1993-11-29 Vern Paxson + + * flex.1: Added Nathan Zelle, "promoted" Francois + +1993-11-29 Vern Paxson + + * Makefile.in: only "realclean" removes flex dist depends on flex + +1993-11-29 Vern Paxson + + * flexdef.h, misc.c: myctoi takes char[] instead of Char[] + +1993-11-28 Vern Paxson + + * flexdef.h: -a -> -Ca all_lower, all_upper -> work on char* + +1993-11-28 Vern Paxson + + * Makefile.in: Added -Ca to bigcheck + +1993-11-28 Vern Paxson + + * main.c: -a -> -Ca; fixed help output + +1993-11-28 Vern Paxson + + * dfa.c, flex.1: -a -> -Ca + +1993-11-28 Vern Paxson + + * misc.c: all_lower, all_upper work on char* + +1993-11-28 Vern Paxson + + * scan.l: Fixed some casts now that yytext is always char* and never + unsigned char* + +1993-11-28 Vern Paxson + + * Makefile.in: Francois' tweaks + +1993-11-28 Vern Paxson + + * configure.in: AC_LN_S, AC_STDC_HEADERS (but not AC_ALLOCA) + +1993-11-27 Vern Paxson + + * NEWS: fixed typo + +1993-11-27 Vern Paxson + + * Makefile.in: Don't remove dist directory + +1993-11-27 Vern Paxson + + * Makefile.in: Include liballoc.c in lint targets + +1993-11-27 Vern Paxson + + * misc.c: lint tweak + +1993-11-27 Vern Paxson + + * Makefile.in: Added -l compression to bigcheck + +1993-11-27 Vern Paxson + + * Makefile.in: permission tweaking for "dist" + +1993-11-27 Vern Paxson + + * Makefile.in: more "dist" tweaks + +1993-11-27 Vern Paxson + + * Makefile.in: Changed "make dist" to use version.h, include scan.c + in initial dir copy + +1993-11-27 Vern Paxson + + * version.h: 2.4.1 + +1993-11-27 Vern Paxson + + * README: Revised as per Francois Pinard + +1993-11-27 Vern Paxson + + * COPYING: flex.skel -> flex.skl + +1993-11-27 Vern Paxson + + * NEWS: Updated date of 2.4 release + +1993-11-27 Vern Paxson + + * Makefile.in: Removed manual & nroff output from distribution + +1993-11-27 Vern Paxson + + * NEWS: 2.4.1 release + +1993-11-27 Vern Paxson + + * configure.in: Initial revision + +1993-11-27 Vern Paxson + + * Makefile.in: Merge w/ 2.4.1 changes added "dist2" target + +1993-11-26 Vern Paxson + + * Makefile.in: Initial revision + +1993-11-26 Vern Paxson + + * flexdef.h: Removed #ifndef FILE protection from include of stdio + +1993-11-26 Vern Paxson + + * flex.1: Added Francois Pinard to distribution headache helpers + +1993-11-26 Vern Paxson + + * flex.skl: Modified C++ scanners to get input a character at a time + for interactive scanners. + +1993-11-26 Vern Paxson + + * main.c: Added YY_INTERACTIVE. + +1993-11-26 Vern Paxson + + * scan.l: Put definitions inside ()'s so we can test -l option for + "make bigcheck" + +1993-11-26 Vern Paxson + + * flex.1: Documented YY_INTERACTIVE. + +1993-11-26 Vern Paxson + + * flex.1, flex.skl, flexdef.h, gen.c, main.c, parse.y, scan.l: -l + lex compatibility flag + +1993-11-20 Vern Paxson + + * flex.skl: Support for read()/fread() section 1 definitions precede + default macro definitions + +1993-11-20 Vern Paxson + + * flexdef.h: Added use_read global + +1993-11-20 Vern Paxson + + * gen.c: Cleaner definition for yymore() Fixed string broken across + multiple lines + +1993-11-20 Vern Paxson + + * main.c: Added -Cr + +1993-11-20 Vern Paxson + + * misc.c: K&R declaration for check_char() + +1993-11-20 Vern Paxson + + * flex.1: Documented -Cr + +1993-11-20 Vern Paxson + + * flex.1: No need to #undef before redefining prior to -Cr + documentation + +1993-11-10 Vern Paxson + + * README: Heavily massaged for 2.4 + +1993-11-10 Vern Paxson + + * flex.1: Added Landon Noll to thanks. + +1993-11-10 Vern Paxson + + * NEWS: 2.4 release + +1993-11-10 Vern Paxson + + * flex.1: 2.4 documentation + +1993-11-10 Vern Paxson + + * main.c: Added global to remember -P prefix so it can be written in + -v summary. Alphabetized prefix generation, added yywrap + +1993-11-09 Vern Paxson + + * version.h: updated date for 2.4.0 :-( + +1993-10-10 Vern Paxson + + * FlexLexer.h: Whitespace tweaking + +1993-10-10 Vern Paxson + + * main.c: Use DEFAULT_CSIZE only if not using equivalence classes. + +1993-10-10 Vern Paxson + + * flex.1: Checkpoint prior to final 2.4 update + +1993-10-04 Vern Paxson + + * NEWS: Raw 2.4 changes + +1993-10-04 Vern Paxson + + * flex.skl: osfcn.h -> unistd.h + +1993-10-04 Vern Paxson + + * flex.skl: Added "static" to definition of yy_fatal_error as well + as fwd decl. + +1993-10-04 Vern Paxson + + * flex.skl: Added yy_fatal_error function. + +1993-10-03 Vern Paxson + + * flex.skl, gen.c: Got rid of (char *) casts of yytext, no longer + needed. + +1993-10-03 Vern Paxson + + * FlexLexer.h: YY_CHAR -> char added YYText(), YYLeng() + +1993-10-03 Vern Paxson + + * flex.skl, gen.c: Minimized use of YY_CHAR + +1993-10-03 Vern Paxson + + * main.c: Added "flex++" feature Minimized use of YY_CHAR + +1993-10-02 Vern Paxson + + * main.c: Clarified help message for -S + +1993-10-02 Vern Paxson + + * libyywrap.c, version.h: Initial revision + +1993-10-02 Vern Paxson + + * main.c: If -+ used, output to lex.yy.cc + +1993-10-02 Vern Paxson + + * FlexLexer.h, flex.skl: Switched from FILE*'s to stream's + +1993-10-02 Vern Paxson + + * flexdef.h: Added expand_nxt_chk() extern. + +1993-10-02 Vern Paxson + + * flex.skl: Added dynamic buffer growing. Added yyless() for + section 3. + +1993-10-02 Vern Paxson + + * dfa.c, flexdef.h, gen.c, main.c: Added -a option for long-align. + +1993-10-02 Vern Paxson + + * scan.l: formfeed no longer considered whitespace + +1993-09-21 Vern Paxson + + * flexdef.h: Nuked FILENAMESIZE + +1993-09-21 Vern Paxson + + * main.c: yyflexlexer.h -> FlexLexer.h minor portability tweak + +1993-09-21 Vern Paxson + + * gen.c: Added start condition to EOF trace output + +1993-09-21 Vern Paxson + + * flex.skl: Added YY_START changed yyFlexLexer to define yylex() + +1993-09-21 Vern Paxson + + * misc.c: Minor portability tweaks + +1993-09-21 Vern Paxson + + * FlexLexer.h: Split into two classes, one fully abstract. yylex() + no longer abstract in yyFlexLexer + +1993-09-21 Vern Paxson + + * scan.l: PC lint tweak + +1993-09-21 Vern Paxson + + * parse.y: YYSTYPE #define'd to int + +1993-09-21 Vern Paxson + + * nfa.c: minor lint tweak + +1993-09-16 Vern Paxson + + * FlexLexer.h: Initial revision + +1993-09-16 Vern Paxson + + * flexdef.h: Delete prototypes for Unix system calls. + +1993-09-16 Vern Paxson + + * ccl.c, dfa.c, ecs.c, gen.c, main.c, misc.c, nfa.c, parse.y, + scan.l, sym.c, tblcmp.c, yylex.c: nuked static RCS string + +1993-09-16 Vern Paxson + + * main.c: %array not allowed with C++ scanners + +1993-09-16 Vern Paxson + + * scan.l: Fixed bugs regarding %{%} code in section 2 prolog %array + not allowed with C++ scanners + +1993-08-25 Vern Paxson + + * flexdef.h: Added C_plus_plus flag. + +1993-08-25 Vern Paxson + + * flex.skl: First version of C/C++ skeleton + +1993-08-25 Vern Paxson + + * gen.c: yy_state_type declared earlier. Made a bunch of statics + only output if not -+ + +1993-08-25 Vern Paxson + + * main.c: Added -+ option, updated usage() output, rearranged some + generated code to come at the right point in the output for + yyflexlexer.h. + +1993-08-25 Vern Paxson + + * misc.c: Added %+/%-/%* to skelout() + +1993-08-25 Vern Paxson + + * scan.l: EOF in section 2 prolog leads to section 0, not section 3 + +1993-08-25 Vern Paxson + + * yylex.c: Dump promotion of EOF in section 2 to turn on section 3; + instead just treat it like a final EOF + +1993-08-25 Vern Paxson + + * dfa.c: yy_nxt table should be "const" + +1993-08-24 Vern Paxson + + * flexdef.h: Removed a lot of #ifdef chud "backtracking" -> "backing + up" + +1993-08-24 Vern Paxson + + * main.c: "backtracking" -> "backing up" got rid of time reports + +1993-08-24 Vern Paxson + + * gen.c: "backtracking" -> "backing up" some portability tweaks + fixed to only call flexscan() when done if known to be in section 3 + +1993-08-24 Vern Paxson + + * misc.c: isascii() moved to flexdef.h nuked flex_gettime() + +1993-08-24 Vern Paxson + + * scan.l: Fixed bug with empty section 2 + +1993-08-24 Vern Paxson + + * yylex.c: Chucked definition of isascii() + +1993-08-24 Vern Paxson + + * flex.skl: preserve yytext on input() bug fix when combining + yyless() with yymore() checkpoint prior to C++ option + +1993-08-24 Vern Paxson + + * dfa.c: "backtracking" -> "backing up" + +1993-07-09 Vern Paxson + + * flex.skl: Fixed to not generate extra EOF's after reading one. + +1993-07-05 Vern Paxson + + * main.c: Spit out definition of YY_CHAR early + +1993-07-05 Vern Paxson + + * flex.skl: Some rearranging to make sure things get declared in the + right order + +1993-07-05 Vern Paxson + + * tblcmp.c: Some comment fixes as per Wilhelms + +1993-07-05 Vern Paxson + + * scan.l: Nuked #undef of yywrap, now that it's a function + +1993-07-05 Vern Paxson + + * parse.y: Fixed bug with Z-a character classes as per Wilhelms + +1993-07-05 Vern Paxson + + * nfa.c: added check_char call in mkstate() to prevent bad xtion + chars + +1993-07-05 Vern Paxson + + * gen.c: Fixed some reallocation bugs, etc. as per Wilhelms + +1993-07-05 Vern Paxson + + * flexdef.h: Added check_char(), readable_form() + +1993-07-05 Vern Paxson + + * flex.skl: Added #ifndef's around #define's to let user override + Moved a bunch of definitions prior to section 1 + +1993-07-05 Vern Paxson + + * dfa.c: Wilhems bug fixes. + +1993-07-05 Vern Paxson + + * ccl.c, misc.c: Added check_char() + +1993-06-12 Vern Paxson + + * flexdef.h: Changed to use yy_flex_alloc() and friends + +1993-06-12 Vern Paxson + + * main.c: Added -P flag + +1993-06-12 Vern Paxson + + * scan.l: Fixed bug in lex % directives + +1993-06-12 Vern Paxson + + * misc.c: Modified to use yy_flex_alloc() and friends + +1993-06-12 Vern Paxson + + * sym.c: Modified to use yy_flex_alloc() + +1993-06-12 Vern Paxson + + * flex.skl: Modified to use yy_flex_alloc() and friends Moved some + globals earlier in the file to permit access in section 1 + +1993-06-12 Vern Paxson + + * dfa.c: Got rid of code needed for %t + +1993-04-14 Vern Paxson + + * ccl.c, dfa.c, ecs.c, flex.skl, flexdef.h, gen.c, libmain.c, + main.c, misc.c, nfa.c, parse.y, scan.l, sym.c, tblcmp.c, yylex.c: + Reformatting. + +1993-04-05 Vern Paxson + + * flex.1: Fixed bug in description of backtracking + +1993-04-05 Vern Paxson + + * NEWS: 2.3.8 + +1993-04-05 Vern Paxson + + * flex.skl, main.c: %array support + +1993-04-05 Vern Paxson + + * misc.c: Added non-STDC clause for '\a' + +1993-04-05 Vern Paxson + + * scan.l: Fixed subtle problems regarding '*'s in comments + %pointer/%array match entire lines + +1993-04-05 Vern Paxson + + * gen.c: Added %array support + +1993-02-06 Vern Paxson + + * README: Finally updated email addr + +1993-02-06 Vern Paxson + + * flex.1: Mostly .LP -> .PP + +1993-02-06 Vern Paxson + + * flexdef.h: [no log message] + +1993-02-06 Vern Paxson + + * main.c, scan.l: A lot of tweaks ... + +1993-02-06 Vern Paxson + + * ccl.c: reallocate_character_array -> reallocate_Character_array + +1993-02-06 Vern Paxson + + * gen.c: Bug/lint fixes Modified to work with "action" array instead + of temp file + +1993-02-06 Vern Paxson + + * sym.c: Fixed bug in 8-bit hashing + +1993-02-06 Vern Paxson + + * parse.y: numerous bug fixes extra formatting of error/warning + messages added support of <*>, partial support for nested start + conditions + +1993-02-06 Vern Paxson + + * ecs.c: Remove %t cruft + +1993-02-06 Vern Paxson + + * flex.skl: Beginning of %pointer/%array support + +1993-02-06 Vern Paxson + + * dfa.c: Added keeping track of which rules are useful fixed a + fencepost error in checking for scanners that require -8 + +1993-02-06 Vern Paxson + + * nfa.c: Added checking for whether rules are useful modified to + work with internal "action" array + +1993-02-06 Vern Paxson + + * misc.c: Added internal "action" array, internal skeleton, + zero_out() in lieu of bzero + +1993-02-06 Vern Paxson + + * tblcmp.c: Fixed a bunch of fencepost errors in increasing tables. + +1993-02-06 Vern Paxson + + * yylex.c: -Wall fix + +1991-03-28 Vern Paxson + + * gen.c: Fixed out-of-bounds access bug; patch #7 for release 2.3 + +1991-03-28 Vern Paxson + + * NEWS: Patch #7 for 2.3 + +1990-10-23 Vern Paxson + + * gen.c: fixed missing "rule_type" entry for end-of-buffer action + +1990-08-29 Vern Paxson + + * gen.c: Fixed yymore() but in not resetting yy_more_len + +1990-08-29 Vern Paxson + + * NEWS: Patch #6 for 2.3 + +1990-08-16 Vern Paxson + + * NEWS: Patch #5 + +1990-08-14 Vern Paxson + + * misc.c: fixed comment in myesc() + +1990-08-14 Vern Paxson + + * NEWS: fixed date in patch #4 + +1990-08-14 Vern Paxson + + * NEWS: patch #4 + +1990-08-14 Vern Paxson + + * misc.c: fixed hexadecimal escapes; added is_hex_digit() + +1990-08-03 Vern Paxson + + * NEWS: Patch #3 + +1990-08-03 Vern Paxson + + * flex.skl, flexdef.h: changed to include for __GNUC__ + +1990-08-02 Vern Paxson + + * NEWS: 2.3 patch #2 + +1990-08-02 Vern Paxson + + * flex.skl: Another try at getting the malloc() definitions correct; + this time for g++, too + +1990-08-02 Vern Paxson + + * flex.skl, flexdef.h: fixed to declare malloc() and free() by hand + if __GNUC__ + +1990-07-28 Vern Paxson + + * flexdef.h: Changed to get malloc definition in identical fashion + to that used by flex.skel + +1990-06-28 Vern Paxson + + * NEWS: [no log message] + +1990-06-28 Vern Paxson + + * flex.1: Fixed bug in mini-scanner examle Fixed bug in YY_INPUT + redefinition yylineno defense reentrancy documentation Something + else which I forget. + +1990-06-27 Vern Paxson + + * COPYING, ccl.c, dfa.c, ecs.c, flexdef.h, gen.c, main.c, misc.c, + nfa.c, parse.y, scan.l, sym.c, tblcmp.c, yylex.c: 4.4 BSD copyright + +1990-05-26 Vern Paxson + + * README: Changed prolog to reflect 2.3 release. + +1990-05-26 Vern Paxson + + * NEWS: pointed reader at Makefile instead of README for porting + considerations added Makefile comments: support for SCO Unix; + parameterization + +1990-05-26 Vern Paxson + + * flex.skl: Added DONT_HAVE_STDLIB_H and declarations of malloc() + +1990-05-26 Vern Paxson + + * NEWS: 2.3 changes + +1990-05-26 Vern Paxson + + * flex.1: documentation on new features Comment regarding Ove's work + ^foo|bar difference between flex / lex yyin initialization + difference documented that yy_switch_to_buffer can be used in + yywrap() documented that # comments are deprecated + +1990-05-26 Vern Paxson + + * main.c: declared void functions as such added prototypes for + forward references changed to check for error status when closing + files + +1990-05-26 Vern Paxson + + * yylex.c: Added macro definition for isascii() if not already + present + +1990-05-26 Vern Paxson + + * sym.c: declared void functions as such added prototypes for + forward references changed to use format_pinpoint_message where + appropriate + +1990-05-26 Vern Paxson + + * scan.l: declared void functions as such changed to strip # + comments, as documented moved #undef of yywrap() to before include + of flexdef, so prototype doesn't get screwed up + +1990-05-26 Vern Paxson + + * parse.y: introduced format_pinpoint_message() declared void + functions as such changed lone <> to apply to all outstanding + start conditions + +1990-05-26 Vern Paxson + + * nfa.c, tblcmp.c: declared void functions as such added prototypes + for forward references + +1990-05-26 Vern Paxson + + * misc.c: declared void functions as such prototypes for forward + references shuffled around some routines to make the order perhaps a + little more logical changed memory references to use void* instead + of char* + +1990-05-26 Vern Paxson + + * libmain.c: Added declaration of arguments made yylex() a function + +1990-05-26 Vern Paxson + + * gen.c: prototypes for forward references declared void functions + as such yy_flex_debug testing of error on file closes casts to void + for sprintf() and strcpy() + +1990-05-26 Vern Paxson + + * flexdef.h: Added prototypes changed memory allocation routines to + deal with void*'s instead of char*'s some rearranging for VMS + +1990-05-26 Vern Paxson + + * flex.skl: Added YY_USER_INIT Added yy_new_buffer() alias for + yy_create_buffer() fixed (hopefully) malloc declaration headaches + +1990-05-26 Vern Paxson + + * ecs.c: declared void functions as such declared void functions as + such + +1990-05-26 Vern Paxson + + * dfa.c: prototypes for forward references declared void functions + as such + +1990-05-26 Vern Paxson + + * ccl.c: Declared void functions as such + +1990-04-12 Vern Paxson + + * flex.skl: added fix for allowing yy_switch_to_buffer() in yywrap() + +1990-04-03 Vern Paxson + + * NEWS: patch #3 - -I fix + +1990-03-30 Vern Paxson + + * gen.c: Changed generation of archaic "continue" to "goto + yy_find_action" + +1990-03-27 Vern Paxson + + * NEWS: Patch #2 changes + +1990-03-27 Vern Paxson + + * flex.skl: fixed fencepost errors with yy_buf_size and detecting + NUL's + +1990-03-26 Vern Paxson + + * NEWS: [no log message] + +1990-03-26 Vern Paxson + + * flex.skl: g++ tweaks + +1990-03-23 Vern Paxson + + * NEWS: Changes for Patch #1. + +1990-03-23 Vern Paxson + + * flex.skl: fix for g++ + +1990-03-23 Vern Paxson + + * flex.1: minor typos and formatting changes. Removed BITNET + address. + +1990-03-23 Vern Paxson + + * README: nuked BITNET address. + +1990-03-20 Vern Paxson + + * README: 2.2 README + +1990-03-20 Vern Paxson + + * NEWS: USG alias. + +1990-03-20 Vern Paxson + + * flexdef.h: Added USG alias for SYS_V + +1990-03-20 Vern Paxson + + * : [no log message] + +1990-03-20 Vern Paxson + + * flex.skl: Tweaks for lint and C++ + +1990-03-20 Vern Paxson + + * flex.1: -ll => -lfl + +1990-03-20 Vern Paxson + + * NEWS: 2.2 changes + +1990-03-20 Vern Paxson + + * flex.skl: Changed to use YY_BUFFER_STATE everywhere. + +1990-03-20 Vern Paxson + + * flex.1: [no log message] + +1990-03-20 Vern Paxson + + * dfa.c: "associated rules" changed to "associated rule line + numbers". + +1990-03-20 Vern Paxson + + * scan.l: cast added to malloc() call to keep lint happy. + +1990-03-20 Vern Paxson + + * yylex.c: Fixed handling of premature EOF's. + +1990-03-20 Vern Paxson + + * sym.c: Removed declaration of malloc() + +1990-03-20 Vern Paxson + + * scan.l: Removed malloc() declaration. Added detection of EOF in + actions. + +1990-03-20 Vern Paxson + + * parse.y: Rules rewritten so '/' and '$' parsed correctly. + +1990-03-20 Vern Paxson + + * nfa.c: Corrected line numbers for continued actions. + +1990-03-20 Vern Paxson + + * misc.c: Removed declarations of malloc() and realloc(). + +1990-03-20 Vern Paxson + + * main.c: Summary of generation flags. Minor -8 tweaks. + +1990-03-20 Vern Paxson + + * gen.c: full support for -d + +1990-03-20 Vern Paxson + + * flexdef.h: defines for malloc() and realloc() conditional defines + for abs(), min(), and max() + +1990-03-20 Vern Paxson + + * flex.skl: Many multiple-buffer additions. + +1990-03-20 Vern Paxson + + * dfa.c: -8 tweaks. + +1990-03-19 Vern Paxson + + * flex.skl: Proto hacks. NUL hacks. Debugging hacks. C++ hacks. + +1990-03-16 Vern Paxson + + * : RCS won't let me unedit! gets "Missing access list" + +1990-03-16 Vern Paxson + + * tblcmp.c: Minor tweaks for NUL's. + +1990-03-16 Vern Paxson + + * : no changes -- had checked out for testing smaller read buffer + sizes + +1990-03-16 Vern Paxson + + * nfa.c: hack for NUL's. + +1990-03-16 Vern Paxson + + * misc.c: Hack to cshell for NUL's. + +1990-03-16 Vern Paxson + + * main.c: NUL's. -8 + +1990-03-16 Vern Paxson + + * gen.c: NUL's. + +1990-03-16 Vern Paxson + + * flexdef.h: NUL's. 8-bit chars. + +1990-03-16 Vern Paxson + + * flex.skl: NUL's; indenting + +1990-03-16 Vern Paxson + + * dfa.c: more thrashing around with NUL's + +1990-03-16 Vern Paxson + + * ccl.c: removed NUL hack + +1990-03-14 Vern Paxson + + * yylex.c: Added <> token + +1990-03-14 Vern Paxson + + * ecs.c, flexdef.h: Tweaks for NUL chars. + +1990-03-14 Vern Paxson + + * dfa.c, gen.c, main.c, misc.c, parse.y, scan.l, tblcmp.c: Tweaks + for NUL chars. + +1990-03-14 Vern Paxson + + * ccl.c: Tweaks for handling NUL's. + +1990-02-28 Vern Paxson + + * flex.1: [no log message] + +1990-02-28 Vern Paxson + + * flex.1: Changed .so options.man to inlined version since flex.1 + will have a different (shorter) options description. + +1990-02-28 Vern Paxson + + * flex.1: [no log message] + +1990-02-28 Vern Paxson + + * flex.1: [no log message] + +1990-02-26 Vern Paxson + + * flex.1: [no log message] + +1990-02-25 Vern Paxson + + * flex.1: [no log message] + +1990-02-25 Vern Paxson + + * flex.1: Initial revision + +1990-01-16 Vern Paxson + + * gen.c: Restored EOB accepting list for REJECT. Second try at 2.2 + Release. + +1990-01-16 Vern Paxson + + * misc.c: Added missing ',' in error message. 2.2 Release, second + try. + +1990-01-16 Vern Paxson + + * yylex.c: 8-bit char support. 2.2 Release. + +1990-01-15 Vern Paxson + + * scan.l: 8-bit char support. Arbitrary indented/%{} code allowed + in section 2. \x escapes. %t support. Minor POSIX-compliance + changes. BEGIN(0) -> BEGIN(INITIAL). yywrap() and set_input_file() + for multiple input files. C_COMMENT_2 removed. 2.2 Release. + +1990-01-15 Vern Paxson + + * flexdef.h: 8-bit char support. SYS_V / Atari portability fixes. + Removed generated array names. CSIZE now only defined if not + already defined. Added "csize" global. Added "input_files", + "num_input_files", and "program_name" globals. %t support globals. + 2.2 Release. + +1990-01-15 Vern Paxson + + * gen.c: Removed unused EOB_accepting_list array. 2.2 Release. + +1990-01-15 Vern Paxson + + * gen.c: Bug in -F table generation fixed. 8-bit char support. + Hardwired generated array names. "const"'s added to generated code. + Fixed yymore() / trailing context bug. + +1990-01-15 Vern Paxson + + * parse.y: 8-bit char support. Error-message pinpointing. 2.2 + Release. + +1990-01-15 Vern Paxson + + * main.c: Unsigned char support. %t support. Removed hard-wiring + of program name "flex". -c changed to -C; -c now deprecated. -n + added. :-( Multiple input files. SYSV tmpnam() use. Removed old + #define's from output. Identified error messages w/ filename and + line. 2.2 Release. + +1990-01-15 Vern Paxson + + * sym.c: Unsigned char support. 2.2 Release. + +1990-01-15 Vern Paxson + + * nfa.c: Removed redundant test. 2.2 Release. + +1990-01-15 Vern Paxson + + * misc.c: Unsigned char support. \x support. 2.2 Release. + +1990-01-15 Vern Paxson + + * tblcmp.c: 8-bit char support. 2.2 Release. + +1990-01-15 Vern Paxson + + * flex.skl: C++ support. Turbo-C support. 8-bit char support. + yyleng is an int. unput() callable in section 3. yymore hacks. + yyrestart() no longer closes stdin. 2.2 Release. + +1990-01-15 Vern Paxson + + * ecs.c: %t support. 8-bit/unsigned char support. 2.2 Release. + +1990-01-15 Vern Paxson + + * dfa.c: %t hacks. minor cosmetics. 2.2 Relase. + +1990-01-15 Vern Paxson + + * ccl.c: Changes for unsigned/8-bit chars. 2.2 Release. + +1990-01-10 Vern Paxson + + * libmain.c: Initial revision + +1989-12-30 Vern Paxson + + * nfa.c: removed gratuitous trailing context code + +1989-12-30 Vern Paxson + + * main.c: made -c case-sensitive + +1989-12-30 Vern Paxson + + * flex.skl: unput() bug fix + +1989-12-30 Vern Paxson + + * README: [no log message] + +1989-06-20 Vern Paxson + + * scan.l: changed to not use '|' and trailing context combo so users + can test using -F ... + +1989-06-20 Vern Paxson + + * parse.y: made trailing context combined with '|' warning always + come out + +1989-06-20 Vern Paxson + + * README: [no log message] + +1989-06-20 Vern Paxson + + * COPYING: Initial revision + +1989-06-20 Vern Paxson + + * NEWS, README, main.c: [no log message] + +1989-06-20 Vern Paxson + + * README: [no log message] + +1989-06-20 Vern Paxson + + * NEWS, README, main.c: [no log message] + +1989-06-20 Vern Paxson + + * : Beta release + +1989-06-20 Vern Paxson + + * NEWS, main.c: [no log message] + +1989-06-20 Vern Paxson + + * flex.skl, flexdef.h, gen.c, misc.c, nfa.c, parse.y, scan.l, sym.c: + 2.0.1 beta + +1989-06-20 Vern Paxson + + * README: [no log message] + +1989-05-25 Vern Paxson + + * gen.c: fixsed bug with -I and backtracking + +1989-05-25 Vern Paxson + + * flex.skl: Cleaned up forward declarations of yyunput() and input() + +1989-05-25 Vern Paxson + + * parse.y: Split copyright string. + +1989-05-25 Vern Paxson + + * nfa.c: Split copyright string. Added check for empty machine in + dupmachine(). + +1989-05-25 Vern Paxson + + * ccl.c, dfa.c, ecs.c, gen.c, main.c, misc.c, scan.l, sym.c, + tblcmp.c, yylex.c: Split copyright string into two to avoid tempting + fate with \ sequences ... + +1989-05-24 Vern Paxson + + * README: updated for 2nd release Beta test added RCS header + +1989-05-24 Vern Paxson + + * flexdef.h: removed static char copyright + +1989-05-24 Vern Paxson + + * flexdef.h: Added BSD copyright notice. Removed + FAST_SKELETON_FILE. + +1989-05-24 Vern Paxson + + * main.c: added BSD copyright notice. Removed references to + FAST_SKELETON_FILE. + +1989-05-24 Vern Paxson + + * ecs.c, gen.c, nfa.c: Added BSD copyright notice + +1989-05-24 Vern Paxson + + * ccl.c, dfa.c, misc.c, parse.y, scan.l, sym.c, tblcmp.c, yylex.c: + added BSD copyright notice + +1989-05-24 Vern Paxson + + * flex.skl: Initial revision + +1989-05-19 Vern Paxson + + * yylex.c: renamed accnum to num_rules + +1989-05-19 Vern Paxson + + * tblcmp.c: moved table generation code to gen.c moved ntod() to + dfa.c + +1989-05-19 Vern Paxson + + * sym.c: the most piddling format change imaginable + +1989-05-19 Vern Paxson + + * scan.l: changed to look for yymore, REJECT, %used and %unused + removed gross magic for dealing with section 3 + +1989-05-19 Vern Paxson + + * nfa.c, parse.y: changes for variable trailing context + +1989-05-19 Vern Paxson + + * misc.c: added all_lower() and all_upper() + +1989-05-19 Vern Paxson + + * main.c: added checking for features being Really used + backtracking, performance reports misc. cleanup + +1989-05-19 Vern Paxson + + * gen.c: major overhaul for merged skeleton + +1989-05-19 Vern Paxson + + * flexdef.h: a zillion changes/additions/cleanups + +1989-05-19 Vern Paxson + + * dfa.c: added backtrack report added checking for dangerous + trailing context considerable minor cleanup + +1989-05-19 Vern Paxson + + * ccl.c: list_character_set() modified to take a FILE to write to + ... + +1989-05-19 Vern Paxson + + * README: updated for beta release + +1988-11-25 Vern Paxson + + * main.c: added -p flag generation of #define's for scanner + +1988-11-25 Vern Paxson + + * flexdef.h: Added END_OF_BUFFER_ACTION and bol_needed + +1988-11-25 Vern Paxson + + * dfa.c: added ntod() + +1988-05-09 Vern Paxson + + * gen.c: Initial revision + +1988-05-08 Vern Paxson + + * yylex.c: RCS header changed display style of non-printings from ^x + to \0xx + +1988-05-08 Vern Paxson + + * tblcmp.c: RCS header MAX_XTIONS_FOR_FULL_INTERIOR_FIT -> + MAX_XTIONS_FULL_INTERIOR_FIT made back-tracking accepting number be + one greater than the last legit accepting number, instead of 0. + This way, end-of-buffer can take 0 and no negative accepting numbers + are needed. added genftbl() changed last ftl references to C added + check for UNSIGNED_CHAR's added back-track logic to make_tables() + added checking and report for backtracking fixed fence-post error + with onesp stack pointer + +1988-05-08 Vern Paxson + + * sym.c: RCS header changed "entry" to "sym_entry" to avoid conflict + with old keyword + +1988-05-08 Vern Paxson + + * scan.l: RCS header removed \^ from ESCSEQ + +1988-05-08 Vern Paxson + + * parse.y: RCS header bug fix due to missing default rule, could + have to backtrack when backtrack variables haven't been set up + +1988-05-08 Vern Paxson + + * nfa.c: RCS ident yy_cp, yy_bp support name shortenings assoc_rule + support + +1988-05-08 Vern Paxson + + * misc.c: RCS header check before malloc()'ing for 16 bit overflow + MS_DOS, VMS ifdef's removed commented-out \^ code removed FTLSOURCE + code added readable_form() + +1988-05-08 Vern Paxson + + * main.c: Added RCS header removed revision history misc additions + and fixes to globals VMS ifdef's backtracking statistics -p flag + name shortenings + +1988-05-08 Vern Paxson + + * flexdef.h: removed revision history added RCS header added VMS, + MS_DOS ifdef's removed DEFAULT_ACTION, changed END_OF_BUFFER_ACTION + shortened MAX_XTIONS_FOR_FULL_INTERIOR_FIT to + MAX_XTIONS_FULL_INTERIOR_FIT added MAX_ASSOC_RULES added + performance_report, assoc_rule gloabls added num_backtracking gloabl + shortened allocate_integer_pointer_array, + reallocate_integer_pointer_array + +1988-05-08 Vern Paxson + + * ecs.c: added RCS id added PROCFLG to avoid assumption of signed + char's + +1988-05-08 Vern Paxson + + * dfa.c: added RCS id added check_for_backtracking() added + dump_associated_rules() added dump_transitions() shortened + reallocate_integer_pointer_array to reallocate_int_ptr_array removed + some dfaacc_{state,set} abuses + +1988-05-08 Vern Paxson + + * ccl.c: Added list_character_set() + +1988-05-07 Vern Paxson + + * ccl.c: added RCS id + +1988-04-10 Vern Paxson + + * README: minor tweaks + +1988-04-10 Vern Paxson + + * README: forgot sh flex.shar + +1988-04-10 Vern Paxson + + * README: final tweaking + +1988-04-10 Vern Paxson + + * tblcmp.c: removed minor lint fluff + +1988-04-10 Vern Paxson + + * NEWS: [no log message] + +1988-04-10 Vern Paxson + + * NEWS, README: Initial revision + +1988-04-10 Vern Paxson + + * yylex.c: added identifying comment. changed to include "parse.h" + instead of "y.tab.h" + +1988-04-10 Vern Paxson + + * tblcmp.c: Changed name from flexcmp.c -> tblcmp.c fixed misc. + typos made generating ec tables be a routine + +1988-04-10 Vern Paxson + + * sym.c: changed name from flexsym.c -> sym.c revamped calling + sequences, etc., for extended table struct definition which now has + both char * and int fields. + +1988-04-10 Vern Paxson + + * scan.l: Changed name from flexscan.l -> scan.l fixed bug in + added block comments between rules. + +1988-04-10 Vern Paxson + + * parse.y: changed name from flexparse.y -> parse.y added start + condition "INITIAL" made a{3} have "variable length" + +1988-04-10 Vern Paxson + + * nfa.c: changed name from flexnfa.c -> nfa.c corrected some typos. + +1988-04-10 Vern Paxson + + * misc.c: changed name from flexmisc.c -> misc.c + +1988-04-10 Vern Paxson + + * main.c: fixed bug causing core dumps if skeleton files could not + be opened. Added -cF. Added fullspd to be equivalent to fulltbl + for which options is cannot be mixed with. + +1988-04-10 Vern Paxson + + * flexdef.h: fixed typos, enhanced symbol table definition. + +1988-04-10 Vern Paxson + + * ecs.c: changed name from flexecs.c to ecs.c + +1988-04-10 Vern Paxson + + * dfa.c: changed name from flexdfa.c to dfa.c + +1988-04-10 Vern Paxson + + * ccl.c: changed name from flexccl.c -> ccl.c + +1988-02-13 Vern Paxson + + * ccl.c, dfa.c, ecs.c, flexdef.h, main.c, misc.c, nfa.c, parse.y, + scan.l, sym.c, tblcmp.c, yylex.c: Beta Release. + +1987-11-08 Vern Paxson + + * Initial revision + diff --git a/third_party/lex/FlexLexer.h b/third_party/lex/FlexLexer.h new file mode 100644 index 00000000..70663e37 --- /dev/null +++ b/third_party/lex/FlexLexer.h @@ -0,0 +1,211 @@ +/* clang-format off */ +/* $OpenBSD: FlexLexer.h,v 1.7 2015/11/19 19:43:40 tedu Exp $ */ + +// $Header: /cvs/src/usr.bin/lex/FlexLexer.h,v 1.7 2015/11/19 19:43:40 tedu Exp $ + +// -*-C++-*- +// FlexLexer.h -- define interfaces for lexical analyzer classes generated +// by flex + +// Copyright (c) 1993 The Regents of the University of California. +// All rights reserved. +// +// This code is derived from software contributed to Berkeley by +// Kent Williams and Tom Epperly. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: + +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. + +// Neither the name of the University nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. + +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE. + +// This file defines FlexLexer, an abstract class which specifies the +// external interface provided to flex C++ lexer objects, and yyFlexLexer, +// which defines a particular lexer class. +// +// If you want to create multiple lexer classes, you use the -P flag +// to rename each yyFlexLexer to some other xxFlexLexer. You then +// include in your other sources once per lexer class: +// +// #undef yyFlexLexer +// #define yyFlexLexer xxFlexLexer +// #include +// +// #undef yyFlexLexer +// #define yyFlexLexer zzFlexLexer +// #include +// ... + +#ifndef __FLEX_LEXER_H +// Never included before - need to define base class. +#define __FLEX_LEXER_H + +#include +# ifndef FLEX_STD +# define FLEX_STD std:: +# endif + +extern "C++" { + +struct yy_buffer_state; +typedef int yy_state_type; + +class FlexLexer { +public: + virtual ~FlexLexer() { } + + const char* YYText() const { return yytext; } + int YYLeng() const { return yyleng; } + + virtual void + yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0; + virtual struct yy_buffer_state* + yy_create_buffer( FLEX_STD istream* s, int size ) = 0; + virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0; + virtual void yyrestart( FLEX_STD istream* s ) = 0; + + virtual int yylex() = 0; + + // Call yylex with new input/output sources. + int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 ) + { + switch_streams( new_in, new_out ); + return yylex(); + } + + // Switch to new input/output streams. A nil stream pointer + // indicates "keep the current one". + virtual void switch_streams( FLEX_STD istream* new_in = 0, + FLEX_STD ostream* new_out = 0 ) = 0; + + int lineno() const { return yylineno; } + + int debug() const { return yy_flex_debug; } + void set_debug( int flag ) { yy_flex_debug = flag; } + +protected: + char* yytext; + int yyleng; + int yylineno; // only maintained if you use %option yylineno + int yy_flex_debug; // only has effect with -d or "%option debug" +}; + +} +#endif // FLEXLEXER_H + +#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce) +// Either this is the first time through (yyFlexLexerOnce not defined), +// or this is a repeated include to define a different flavor of +// yyFlexLexer, as discussed in the flex manual. +#define yyFlexLexerOnce + +extern "C++" { + +class yyFlexLexer : public FlexLexer { +public: + // arg_yyin and arg_yyout default to the cin and cout, but we + // only make that assignment when initializing in yylex(). + yyFlexLexer( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 ); + + virtual ~yyFlexLexer(); + + void yy_switch_to_buffer( struct yy_buffer_state* new_buffer ); + struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size ); + void yy_delete_buffer( struct yy_buffer_state* b ); + void yyrestart( FLEX_STD istream* s ); + + void yypush_buffer_state( struct yy_buffer_state* new_buffer ); + void yypop_buffer_state(); + + virtual int yylex(); + virtual void switch_streams( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 ); + virtual int yywrap(); + +protected: + virtual int LexerInput( char* buf, int max_size ); + virtual void LexerOutput( const char* buf, int size ); + virtual void LexerError( const char* msg ); + + void yyunput( int c, char* buf_ptr ); + int yyinput(); + + void yy_load_buffer_state(); + void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream* s ); + void yy_flush_buffer( struct yy_buffer_state* b ); + + int yy_start_stack_ptr; + int yy_start_stack_depth; + int* yy_start_stack; + + void yy_push_state( int new_state ); + void yy_pop_state(); + int yy_top_state(); + + yy_state_type yy_get_previous_state(); + yy_state_type yy_try_NUL_trans( yy_state_type current_state ); + int yy_get_next_buffer(); + + FLEX_STD istream* yyin; // input source for default LexerInput + FLEX_STD ostream* yyout; // output sink for default LexerOutput + + // yy_hold_char holds the character lost when yytext is formed. + char yy_hold_char; + + // Number of characters read into yy_ch_buf. + int yy_n_chars; + + // Points to current character in buffer. + char* yy_c_buf_p; + + int yy_init; // whether we need to initialize + int yy_start; // start state number + + // Flag which is used to allow yywrap()'s to do buffer switches + // instead of setting up a fresh yyin. A bit of a hack ... + int yy_did_buffer_switch_on_eof; + + + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + struct yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */ + void yyensure_buffer_stack(void); + + // The following are not always needed, but may be depending + // on use of certain flex features (like REJECT or yymore()). + + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + yy_state_type* yy_state_buf; + yy_state_type* yy_state_ptr; + + char* yy_full_match; + int* yy_full_state; + int yy_full_lp; + + int yy_lp; + int yy_looking_for_trail_begin; + + int yy_more_flag; + int yy_more_len; + int yy_more_offset; + int yy_prev_more_offset; +}; + +} + +#endif // yyFlexLexer || ! yyFlexLexerOnce + diff --git a/third_party/lex/NEWS b/third_party/lex/NEWS new file mode 100644 index 00000000..aa30e43d --- /dev/null +++ b/third_party/lex/NEWS @@ -0,0 +1,532 @@ +This is the file NEWS for the flex package. It records user -visible +changes between releases of flex. + +See the file COPYING for copying conditions. + +* flex version 2.5.39 + +** no user visible changes in this release + +* version 2.5.38 released 2014-02-14 + +** internationalization + +*** add sr translation from the translation project + +*** update da, es, ko, nl, pt_BR, ro, ru, sv, tr, vi, zh_CN translations from the translation project + +*** rename zh_tw to its proper zh_TW name + +* version 2.5.37 released 2012-08-03 + +** Import flex into git. See + git://flex.git.sourceforge.net/gitroot/flex/flex. + +** Fix make install target to not fail when the flex++ program is + already installed + +** New translations from the translation project: de, fi, pl, vi + +* version 2.5.36 released 2012-07-20 + +** various portability fixes that quiet compiler warnings on 64-bit + hosts + +** various manual fixes, including correcting the name of a %option and + updating some simple examples to use ANSI C syntax + +** various bug fixes that prevent certain error conditions from + persisting when they should not persist + +** improvements to the test suite so it behaves better when linking + compiled files + +** new translations from the translation project: ca, da, es, fi, fr, + ga, ko, pt_br, ro, ru, sv, tr, zh_cn + +** the flex distribution is now built with automake 1.10.1 and automake + 2.61 + +* version 2.5.35 released 2008-02-26 + +** fixed bug that prevented flex from accepting certain comments in the + scanner file (resolves bugs #1849809 and #1849805) + +** fix bug that prevented headers for all functions from being generated + (resolves bug #1628314) + +** change yy_size_t to be size_t (resolves bug #1849812) + +** new de, nl, pl, pt_br, vi translations from the translation project + +* version 2.5.34 released 2007-12-12 + +** introduce yylex_init_extra; see the manual for details + +** introduce %option extra-type="your_type *" (resolves bug #1744505) + +** The flex program now parses multiple short concatenated options (resolves bug + #1619820). Thanks to Petr Machata of Red Hat on this issue. + +** better checking after yyalloc/yyrealloc (resolves bug #1595967) + +** flex now provides for a libfl_pic.a compiled with position + independent code. Particularly useful when including a flex scanner + in a shared library and with more recent versions of gcc. Thanks to the Debian project for the idea. + +** SourceForge feature request #1658379: Expose YY_BUF_SIZE in the + header file. + +** flex better escapes filenames with special characters in them + (resolves bug #1623600) + +** a memory leak was plugged(resolves bug #1601111) + +** pattern language expanded; see the manual for details on the below + highlights + +*** pattern options added to specify patterns as case-insensitive or + case-sensitive + +*** pattern options to specify whether the "." character should match + the newline character + +*** pattern options added to allow ignoring of whitespace in patterns + +*** POSIX character classes may be negated in patterns + +*** patterns may now use set difference, union operators + +** the manual now contains an appendix listing various common patterns + which may be useful when writing scanners + +** some memory leaks were removed from the C++ scanner (but the C++ + scanner is still experimental and may change radically without + notice) + +** c++ scanners can now use yywrap + +** added new unit test for c++ and yywrap + +** portability fixes to some unit tests + +** flex man page and flex manual in pdf now distributed in the flex +distribution + +** new ca, vi, ga, nl translations from the translation project + +** flex no longer comes with an rpm spec file + +** flex development now happens with automake 1.9.6 + +* version 2.5.33 released 2006-2-20 + +** all flex resources are now to be found from the website at + http://flex.sourceforge.net/ + +** there was no release 2.5.32 published + +** numerous bug and security fixes + +** new nl, vi, sv, ro, po, ga, ca, fr, tr translations from the translation project + +** upgrade to use gettext 0.12 (this now makes the "pdf" and "ps" + targets in the build system able to be run successfully) + +* version 2.5.31 released 2003-4-1 + +** remove --enable-maintainer-mode configure option; none of the + Makefiles were using it and it can be unduely confusing + +* version 2.5.30 released 2003-4-1 + +** yylineno is per-buffer in reentrant scanners + +** added %top directive for placing code at the top of the generated + scanner; see manual for details + +** flex now uses m4 to generate scanners; while this means that + scanners are more readable, it means that flex requires m4 to be + installed; see manual for details + +* version 2.5.29 released 2003-3-5 + +** Automatic stack management for multiple input buffers in C and C++ scanners + +** moved the flex documentation to a new doc/ subdirectory + +** cleanups to the yy namespace + +* version 2.5.28 released 2003-2-12 + +** flex is now hosted at sourceforge + +** Fixed trailing slash bug in YY_INPUT macro def + +** Flex now warns if always-interactive is specified with fast or full + +* version 2.5.27 released 2003-1-21 + +** flex now works with recent bison versions + +** new pt_br translation from the translation project + +* version 2.5.26 released 2003-1-14 + +** Fixed table deserialization bug on big-endian archs. Patch sent from Bryce Nichols + +** yyleng has proper declarations now; this caused flex to generate + unusable scanners for some programs + +** the flex distribution now includes a spec file suitable for use + with rpm + +** some more c++ fixes + +** new es translation from the translation project + +** slight tweeks to the flex_int*_t types + +** flex now warns about pattern ranges that might be ambiguous when + generating a case-insensitive scanner + + +* version 2.5.25 released 2002-12-2 + +** flex now uses flex_int*_t types. For C99 systems, they are just the + int*_t types; for non-C99 systems, we just make some typedefs + +** new pt_br translation from the translation project + +* version 2.5.24 released 2002-11-25 + +* more portability fixes + +** the manual continues to be updated and edited, but it's still got a + ways to go + +** it is possible to have multiple c++ scanners in the same program again + +** new turkish translation from the translation project + +* version 2.5.23 released 2002-10-21 + +** more portability fixes + +** the manual includes a title page and a table-of-contents when printed + +** the test suite can be run with "make check" from the top-level + directory + +** configure now accepts the --enable-maintainer-mode option + +** gettext functionality is now only available externally + +** the constant FLEX_BETA is defined if flex is a beta release + +** the script create-test was not included in the distribution and it + should have been + +* version 2.5.22 released 2002-10-10 + +** more portability fixes around how we get ahold of the integral + types; there is a constant FLEX_NEED_INTEGRAL_TYPE_DEFINITIONS + which you should define if you don't have the header + file (after you complain to your C vendor for not providing a + reasonable C environment) + +** more test suite cleanups; in particular, the test suite should run + correctly when build from a different directory + +** upgraded automake to 1.7 and consequently autoconf to 2.54; this + means, among other things, that there is some support for +formatting the manual in postscript and pdf in the distributed + Makefile.in (and therefore in the Makefile built by configure) + +** the flex.1 manpage is generated by help2man; (this has been true + for quite a while but was not listed here) + +** flex now includes three defined constants to indicate which version + of flex generated a scanner (YY_FLEX_{MAJOR,MINOR,SUBMINOR}_VERSION) + +** flex tries its best to output only the relevant portions of the + skeleton when generating a scanner, thus avoiding as much + conditional compilation as possible + +* version 2.5.21 released 2002-9-17 + +** one of the tests in the test suite broke the dist target + +* version 2.5.20 released 2002-9-16 + +** A flex scanner has the ability to save the DFA tables to a file, + and load them at runtime when needed; see the manual for details + +** Added %option bison-bridge (--bison-bridge) + +** Removed %option reentrant-bison/--reentrant-bison/-Rb + +** yylineno is present in all scanners; Modified nasty performance + penalty warning with yylineno in documentation + +** test-table-opts is now run last in the test suite because it's so fat + +** flex can, to some extent, diagnose where internal problems occur + +** new translations from the translation project: fr, ca, de, ru, sv + +**Flex generates C99 defs now; see YY_TRADITIONAL_FUNC_DEFS in the + manual if that's not a good thing for you + +* version 2.5.19 released 2002-9-5 + +** prevent segfault on input lines which are longer than the allocated + space (problem report from Manoj Srivastava + ) + +** Changed option 'header' to 'header-file' + +* version 2.5.18 released 2002-9-4 + +** portability fixes for integer constants and in the way the test + suite reports its results + +** the test for bison was reporting bison missing when it was, in + fact, found + +** if we don't find GNU indent, we're more careful when we're not + finding it + +* version 2.5.17 released 2002-8-29 + +** more portability fixes + +** updated config.sub and config.guess + +** flex is indented by GNU indent (this was done earlier but not + explicitly documented) + +* version 2.5.16 released 2002-8-28 + +** c++ scanners compile again + +** there is now an indent target in the top-level Makefile; configure + checks for GNU indent which is required for proper operation of the + indent target + +** some more portability fixes were made + +** %options and invocation sections of manual merged + +** a c++ test was added to the test suite + +** we're trying to clean up more files in the test suite's make clean + targets + +* version 2.5.15 released 2002-8-21 + +** reject-state buffer is now dynamically allocated and REJECT buffer + variables are reentrant-safe + +** manual now discusses memory usage + +** skeleton now processed by m4 before mkskel.sh; (this only matters + if you want to change the skeleton or if you're doing flex development) + +** zh_cn translation added from translation project + +** a bug that caused a segfault has now been fixed + +** the test suite now respects the usual CFLAGS, etc. variables + +** removed some warnings which some tests trigggered with the -s option + +** the flex-generated header file now tries to be smarter about + conditionally including start conditions + +** tables code omitted from generated scanner when not used + +* version 2.5.14 released 2002-8-15 + +** the tests using the reentrant c scanner as c++ were reworked + slightly to be sure that the c++ was enforced + +** de translation now included in the distribution + +** various portability fixes regarding nls support, c++ include + headers, etc. + +* version 2.5.13 released 2002-8-15 + +** the header file output with %option header is now much smaller + +** Fixed type mismatch in printf in scanner skeleton + +** yylex_init now reports errors + +* version 2.5.12 released 2002-8-8 + +** updated gettext support to 0.11.5 + +** new fr translation from the translation project + +** bison is no longer needed to build flex; If you are building flex + from a release (i.e., not from a cvs snapshot), then you don't need + to have a pre-built lex around either (unless you modify scan.l, of + course); (This has been true for some time, but was not mentioned + here.) + +* version 2.5.11 released 2002-7-31 + +** Fixed bug where yyless did not consider yylineno + +** the yylineno performance hit is now gone + +** fixed some typos in the manual and we now include texinfo.tex in + the distribution + +** traditional prototypes output for C scanners, controlled by a + preprocessor symbol; see documentation for details + +* version 2.5.10 released 2002-7-24 + +** yy_globals renamed to yyscanner and yy_globals_t renamed to + yy_guts_t + +** added dist-bzip2 option to Makefile.am so we now produce a bzip2'd + archive in addition to the standard gzip archive + +* version 2.5.9 + +** new tests in test suite: test-mem-{nr,r}, test-posix, + test-posixly-correct, test-debug-{nr,r} + +** made changes to work with gcc-3.2 development code + +** ability to choose which memory functions are used in flex + +** new yylex_destroy() function for the non-reentrant scanner + +** new handling of POSIXLY_CORRECT environment variable + +** the test suite now has its copyrights explicitly described + +** new ca, de, fr, ru, sv, tr translations + +* version 2.5.8 + +** a new --posix option generates scanners with posix-style abc{1,3} + compatible parsing, see manual for the screwy details + +* version 2.5.7 + +** configure.in now includes a call to AC_PREREQ to enforce the + requirement for autoconf at least 2.50 (This only effects you if + you're doing flex development.) + +** configure now uses autoconf's versioning information and configure + --help reports the bug-reporting address for flex + +** test suite now only reports success versus failure; reporting + skipped is problematic under the current setup + +** compilation with --disable-nls now works + +** flex can now be built in a separate directory + +* version 2.5.6 + +** gettext support added (from gettext 0.11) + +*** translations for ca, da, de, es, fr, ko, ru, sv, tr included + +** distribution now built under automake 1.6 and autoconf 2.53 + +** command-line option parsing happens differently now: + +*** Added long option parsing + +*** Options -n and -c, previously deprecated, now simply do nothing + +*** Options are now parsed left to right + +** added a number of new options + +*** All positive %options are now accessible from the command line + +*** Added option -D, to define a preprocessor symbol + +*** Added option --header=FILE to specify a C .h file to generate + +*** added option --yywrap to call yywrap on EOF + +*** added option --yylineno to track line count in yylineno + +*** --yyclass=NAME name of C++ class when generating c++ scanners + +*** for long option names which are associated with existing short +options, see accompanying documentation + +*** new %option nounistd or command-line --nounistd added to prevent + flex from generating #include on systems that don't + have that include file + +** Support for reentrant C scanners has been added + +*** Updated the manual with the new reentrant API + +*** Two new options %option reentrant (-R) and +%option reentrant-bison (-Rb) + +*** All globals optionally placed into struct yyglobals_t + +*** All access to globals replaced by macro invocations + +*** All functions optionally take one additional +argument, yy_globals + +*** New style for invoking reentrant scanner: +yylex_init(void** scanner ); +yylex( scanner ); +yylex_destroy( scanner ); + +*** Added get/set functions for members of struct yy_globals_t +e.g., yyget_text, yyget_leng, etc + +*** Prefix substitution added for new functions + +*** Macro shortcuts to the lengthy get/set functions +provided for use in actions, e.g., yytext, yyleng, etc + +*** Arbitrary, user-defined data, "yyextra", may be added to scanner + +** %option nomain no longer implies %option yywrap +But the inverse is still true + +** Developer test suite added + +*** TESTS/ directory has been added. Users can +'make test' in the TESTS directory to execute the test suite + +** Support for bison variables yylval and yylloc added + +** automake support for the build process + +** manual is now in texinfo/info format + +*** flex.1 removed from distribution + +** flex no longer generates C-language scanners with C++-style + comments + +** flex now generates scanners in c++ which are compatible with + recent c++ compilers + +** flex input scanner now recognizes '\r' as an EOL character + +See the file ONEWS for changes in earlier releases. + +Local Variables: +mode: text +mode: outline-minor +end: diff --git a/third_party/lex/NOTES b/third_party/lex/NOTES new file mode 100644 index 00000000..8906709e --- /dev/null +++ b/third_party/lex/NOTES @@ -0,0 +1,113 @@ +This is flex, the fast lexical analyzer generator. + +flex is a tool for generating scanners: programs which recognize +lexical patterns in text. + +More information about flex as well as the latest official release of +flex can be found at: + +http://flex.sourceforge.net/ + +Bug reports should be submitted using the SourceForge Bug Tracker for +flex at: + +http://sourceforge.net/tracker/?group_id=97492&atid=618177 + +The flex codebase is kept in git at: + +https://github.com/westes/flex + +There are several mailing lists available as well: + +flex-announce@lists.sourceforge.net - where posts will be made +announcing new releases of flex. + +flex-help@lists.sourceforge.net - where you can post questions about +using flex + +flex-devel@lists.sourceforge.net - where you can discuss development of +flex itself + +Find information on subscribing to the mailing lists at: + +http://sourceforge.net/mail/?group_id=97492 + +The flex distribution contains the following files which may be of interest: + +README - This file. + +NEWS - current version number and list of user-visible changes. + +INSTALL - basic installation information. + +ABOUT-NLS - description of internationalization support in flex. + +COPYING - flex's copyright and license. + +doc/ - user documentation. + +examples/ - containing examples of some possible flex scanners and a +few other things. See the file examples/README for more details. + +TODO - outstanding bug reports, desired features, etc. + +tests/ - regression tests. See TESTS/README for details. + +po/ - internationalization support files. + +You need the following tools to build flex from the maintainer's +repository: + +compiler suite - flex is built with gcc +bash, or a good Bourne-style shell +m4 - m4 -p needs to work; GNU m4 and a few others are suitable +GNU bison; to generate parse.c from parse.y +autoconf 2.69; for handling the build system +automake 1.12.2; for Makefile generation +gettext 0.18; fori18n support +help2man 1.36; to generate the flex man page +tar, gzip, etc.; for packaging of the source distribution +GNU texinfo 498; to build and test the flex manual +GNU indent 2.8; for indenting the flex source the way we want it done + +Once you have all the necessary tools installed, life becomes +simple. To prepare the flex tree for building, run the script: + +$ ./autogen.sh + +in the top level of the flex source tree. +This script calls the various tools needed to get flex ready for the +GNU-style configure script to be able to work. + +From this point on, building flex follows the usual configure, make, +make install routine. + +This file is part of flex. + +This code is derived from software contributed to Berkeley by +Vern Paxson. + +The United States Government has rights in this work pursuant +to contract no. DE-AC03-76SF00098 between the United States +Department of Energy and the University of California. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +Neither the name of the University nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. + + diff --git a/third_party/lex/ONEWS b/third_party/lex/ONEWS new file mode 100644 index 00000000..33415772 --- /dev/null +++ b/third_party/lex/ONEWS @@ -0,0 +1,1233 @@ +Changes between release 2.5.4 (11Sep96) and release 2.5.3: + + - Fixed a bug introduced in 2.5.3 that blew it when a call + to input() occurred at the end of an input file. + + - Fixed scanner skeleton so the example in the man page of + scanning strings using exclusive start conditions works. + + - Minor Makefile tweaks. + + +Changes between release 2.5.3 (29May96) and release 2.5.2: + + - Some serious bugs in yymore() have been fixed. In particular, + when using AT&T-lex-compatibility or %array, you can intermix + calls to input(), unput(), and yymore(). (This still doesn't + work for %pointer, and isn't likely to in the future.) + + - A bug in handling NUL's in the input stream of scanners using + REJECT has been fixed. + + - The default main() in libfl.a now repeatedly calls yylex() until + it returns 0, rather than just calling it once. + + - Minor tweak for Windows NT Makefile, MISC/NT/Makefile. + + +Changes between release 2.5.2 (25Apr95) and release 2.5.1: + + - The --prefix configuration option now works. + + - A bug that completely broke the "-Cf" table compression + option has been fixed. + + - A major headache involving "const" declarators and Solaris + systems has been fixed. + + - An octal escape sequence in a flex regular expression must + now contain only the digits 0-7. + + - You can now use "--" on the flex command line to mark the + end of flex options. + + - You can now specify the filename '-' as a synonym for stdin. + + - By default, the scanners generated by flex no longer + statically initialize yyin and yyout to stdin and stdout. + This change is necessary because in some ANSI environments, + stdin and stdout are not compile-time constant. You can + force the initialization using "%option stdinit" in the first + section of your flex input. + + - "%option nounput" now correctly omits the unput() routine + from the output. + + - "make clean" now removes config.log, config.cache, and the + flex binary. The fact that it removes the flex binary means + you should take care if making changes to scan.l, to make + sure you don't wind up in a bootstrap problem. + + - In general, the Makefile has been reworked somewhat (thanks + to Francois Pinard) for added flexibility - more changes will + follow in subsequent releases. + + - The .texi and .info files in MISC/texinfo/ have been updated, + thanks also to Francois Pinard. + + - The FlexLexer::yylex(istream* new_in, ostream* new_out) method + now does not have a default for the first argument, to disambiguate + it from FlexLexer::yylex(). + + - A bug in destructing a FlexLexer object before doing any scanning + with it has been fixed. + + - A problem with including FlexLexer.h multiple times has been fixed. + + - The alloca() chud necessary to accommodate bison has grown + even uglier, but hopefully more correct. + + - A portability tweak has been added to accommodate compilers that + use char* generic pointers. + + - EBCDIC contact information in the file MISC/EBCDIC has been updated. + + - An OS/2 Makefile and config.h for flex 2.5 is now available in + MISC/OS2/, contributed by Kai Uwe Rommel. + + - The descrip.mms file for building flex under VMS has been updated, + thanks to Pat Rankin. + + - The notes on building flex for the Amiga have been updated for + flex 2.5, contributed by Andreas Scherer. + + +Changes between release 2.5.1 (28Mar95) and release 2.4.7: + + - A new concept of "start condition" scope has been introduced. + A start condition scope is begun with: + + { + + where SCs is a list of one or more start conditions. Inside + the start condition scope, every rule automatically has the + prefix applied to it, until a '}' which matches the + initial '{'. So, for example: + + { + "\\n" return '\n'; + "\\r" return '\r'; + "\\f" return '\f'; + "\\0" return '\0'; + } + + is equivalent to: + + "\\n" return '\n'; + "\\r" return '\r'; + "\\f" return '\f'; + "\\0" return '\0'; + + As indicated in this example, rules inside start condition scopes + (and any rule, actually, other than the first) can be indented, + to better show the extent of the scope. + + Start condition scopes may be nested. + + - The new %option directive can be used in the first section of + a flex scanner to control scanner-generation options. Most + options are given simply as names, optionally preceded by the + word "no" (with no intervening whitespace) to negate their + meaning. Some are equivalent to flex flags, so putting them + in your scanner source is equivalent to always specifying + the flag (%option's take precedence over flags): + + 7bit -7 option + 8bit -8 option + align -Ca option + backup -b option + batch -B option + c++ -+ option + caseful opposite of -i option (caseful is the default); + case-sensitive same as above + caseless -i option; + case-insensitive same as above + debug -d option + default opposite of -s option + ecs -Ce option + fast -F option + full -f option + interactive -I option + lex-compat -l option + meta-ecs -Cm option + perf-report -p option + read -Cr option + stdout -t option + verbose -v option + warn opposite of -w option (so use "%option nowarn" for -w) + + array equivalent to "%array" + pointer equivalent to "%pointer" (default) + + Some provide new features: + + always-interactive generate a scanner which always + considers its input "interactive" (no call to isatty() + will be made when the scanner runs) + main supply a main program for the scanner, which + simply calls yylex(). Implies %option noyywrap. + never-interactive generate a scanner which never + considers its input "interactive" (no call to isatty() + will be made when the scanner runs) + stack if set, enable start condition stacks (see below) + stdinit if unset ("%option nostdinit"), initialize yyin + and yyout statically to nil FILE* pointers, instead + of stdin and stdout + yylineno if set, keep track of the current line + number in global yylineno (this option is expensive + in terms of performance). The line number is available + to C++ scanning objects via the new member function + lineno(). + yywrap if unset ("%option noyywrap"), scanner does not + call yywrap() upon EOF but simply assumes there + are no more files to scan + + Flex scans your rule actions to determine whether you use the + REJECT or yymore features (this is not new). Two %options can be + used to override its decision, either by setting them to indicate + the feature is indeed used, or unsetting them to indicate it + actually is not used: + + reject + yymore + + Three %option's take string-delimited values, offset with '=': + + outfile="" equivalent to -o + prefix="" equivalent to -P + yyclass="" set the name of the C++ scanning class + (see below) + + A number of %option's are available for lint purists who + want to suppress the appearance of unneeded routines in + the generated scanner. Each of the following, if unset, + results in the corresponding routine not appearing in the + generated scanner: + + input, unput + yy_push_state, yy_pop_state, yy_top_state + yy_scan_buffer, yy_scan_bytes, yy_scan_string + + You can specify multiple options with a single %option directive, + and multiple directives in the first section of your flex input file. + + - The new function: + + YY_BUFFER_STATE yy_scan_string( const char *str ) + + returns a YY_BUFFER_STATE (which also becomes the current input + buffer) for scanning the given string, which occurs starting + with the next call to yylex(). The string must be NUL-terminated. + A related function: + + YY_BUFFER_STATE yy_scan_bytes( const char *bytes, int len ) + + creates a buffer for scanning "len" bytes (including possibly NUL's) + starting at location "bytes". + + Note that both of these functions create and scan a *copy* of + the string/bytes. (This may be desirable, since yylex() modifies + the contents of the buffer it is scanning.) You can avoid the + copy by using: + + YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) + + which scans in place the buffer starting at "base", consisting + of "size" bytes, the last two bytes of which *must* be + YY_END_OF_BUFFER_CHAR (these bytes are not scanned; thus, scanning + consists of base[0] through base[size-2], inclusive). If you + fail to set up "base" in this manner, yy_scan_buffer returns a + nil pointer instead of creating a new input buffer. + + The type yy_size_t is an integral type to which you can cast + an integer expression reflecting the size of the buffer. + + - Three new routines are available for manipulating stacks of + start conditions: + + void yy_push_state( int new_state ) + + pushes the current start condition onto the top of the stack + and BEGIN's "new_state" (recall that start condition names are + also integers). + + void yy_pop_state() + + pops the top of the stack and BEGIN's to it, and + + int yy_top_state() + + returns the top of the stack without altering the stack's + contents. + + The start condition stack grows dynamically and so has no built-in + size limitation. If memory is exhausted, program execution + is aborted. + + To use start condition stacks, your scanner must include + a "%option stack" directive. + + - flex now supports POSIX character class expressions. These + are expressions enclosed inside "[:" and ":]" delimiters (which + themselves must appear between the '[' and ']' of a character + class; other elements may occur inside the character class, too). + The expressions flex recognizes are: + + [:alnum:] [:alpha:] [:blank:] [:cntrl:] [:digit:] [:graph:] + [:lower:] [:print:] [:punct:] [:space:] [:upper:] [:xdigit:] + + These expressions all designate a set of characters equivalent to + the corresponding isXXX function (for example, [:alnum:] designates + those characters for which isalnum() returns true - i.e., any + alphabetic or numeric). Some systems don't provide isblank(), + so flex defines [:blank:] as a blank or a tab. + + For example, the following character classes are all equivalent: + + [[:alnum:]] + [[:alpha:][:digit:] + [[:alpha:]0-9] + [a-zA-Z0-9] + + If your scanner is case-insensitive (-i flag), then [:upper:] + and [:lower:] are equivalent to [:alpha:]. + + - The promised rewrite of the C++ FlexLexer class has not yet + been done. Support for FlexLexer is limited at the moment to + fixing show-stopper bugs, so, for example, the new functions + yy_scan_string() & friends are not available to FlexLexer + objects. + + - The new macro + + yy_set_interactive(is_interactive) + + can be used to control whether the current buffer is considered + "interactive". An interactive buffer is processed more slowly, + but must be used when the scanner's input source is indeed + interactive to avoid problems due to waiting to fill buffers + (see the discussion of the -I flag in flex.1). A non-zero value + in the macro invocation marks the buffer as interactive, a zero + value as non-interactive. Note that use of this macro overrides + "%option always-interactive" or "%option never-interactive". + + yy_set_interactive() must be invoked prior to beginning to + scan the buffer. + + - The new macro + + yy_set_bol(at_bol) + + can be used to control whether the current buffer's scanning + context for the next token match is done as though at the + beginning of a line (non-zero macro argument; makes '^' anchored + rules active) or not at the beginning of a line (zero argument, + '^' rules inactive). + + - Related to this change, the mechanism for determining when a scan is + starting at the beginning of a line has changed. It used to be + that '^' was active iff the character prior to that at which the + scan started was a newline. The mechanism now is that '^' is + active iff the last token ended in a newline (or the last call to + input() returned a newline). For most users, the difference in + mechanisms is negligible. Where it will make a difference, + however, is if unput() or yyless() is used to alter the input + stream. When in doubt, use yy_set_bol(). + + - The new beginning-of-line mechanism involved changing some fairly + twisted code, so it may have introduced bugs - beware ... + + - The macro YY_AT_BOL() returns true if the next token scanned from + the current buffer will have '^' rules active, false otherwise. + + - The new function + + void yy_flush_buffer( struct yy_buffer_state* b ) + + flushes the contents of the current buffer (i.e., next time + the scanner attempts to match a token using b as the current + buffer, it will begin by invoking YY_INPUT to fill the buffer). + This routine is also available to C++ scanners (unlike some + of the other new routines). + + The related macro + + YY_FLUSH_BUFFER + + flushes the contents of the current buffer. + + - A new "-ooutput" option writes the generated scanner to "output". + If used with -t, the scanner is still written to stdout, but + its internal #line directives (see previous item) use "output". + + - Flex now generates #line directives relating the code it + produces to the output file; this means that error messages + in the flex-generated code should be correctly pinpointed. + + - When generating #line directives, filenames with embedded '\'s + have those characters escaped (i.e., turned into '\\'). This + feature helps with reporting filenames for some MS-DOS and OS/2 + systems. + + - The FlexLexer class includes two new public member functions: + + virtual void switch_streams( istream* new_in = 0, + ostream* new_out = 0 ) + + reassigns yyin to new_in (if non-nil) and yyout to new_out + (ditto), deleting the previous input buffer if yyin is + reassigned. It is used by: + + int yylex( istream* new_in = 0, ostream* new_out = 0 ) + + which first calls switch_streams() and then returns the value + of calling yylex(). + + - C++ scanners now have yy_flex_debug as a member variable of + FlexLexer rather than a global, and member functions for testing + and setting it. + + - When generating a C++ scanning class, you can now use + + %option yyclass="foo" + + to inform flex that you have derived "foo" as a subclass of + yyFlexLexer, so flex will place your actions in the member + function foo::yylex() instead of yyFlexLexer::yylex(). It also + generates a yyFlexLexer::yylex() member function that generates a + run-time error if called (by invoking yyFlexLexer::LexerError()). + This feature is necessary if your subclass "foo" introduces some + additional member functions or variables that you need to access + from yylex(). + + - Current texinfo files in MISC/texinfo, contributed by Francois + Pinard. + + - You can now change the name "flex" to something else (e.g., "lex") + by redefining $(FLEX) in the Makefile. + + - Two bugs (one serious) that could cause "bigcheck" to fail have + been fixed. + + - A number of portability/configuration changes have been made + for easier portability. + + - You can use "YYSTATE" in your scanner as an alias for YY_START + (for AT&T lex compatibility). + + - input() now maintains yylineno. + + - input() no longer trashes yytext. + + - interactive scanners now read characters in YY_INPUT up to a + newline, a large performance gain. + + - C++ scanner objects now work with the -P option. You include + once per scanner - see comments in + (or flex.1) for details. + + - C++ FlexLexer objects now use the "cerr" stream to report -d output + instead of stdio. + + - The -c flag now has its full glorious POSIX interpretation (do + nothing), rather than being interpreted as an old-style -C flag. + + - Scanners generated by flex now include two #define's giving + the major and minor version numbers (YY_FLEX_MAJOR_VERSION, + YY_FLEX_MINOR_VERSION). These can then be tested to see + whether certain flex features are available. + + - Scanners generated using -l lex compatibility now have the symbol + YY_FLEX_LEX_COMPAT #define'd. + + - When initializing (i.e., yy_init is non-zero on entry to yylex()), + generated scanners now set yy_init to zero before executing + YY_USER_INIT. This means that you can set yy_init back to a + non-zero value in YY_USER_INIT if you need the scanner to be + reinitialized on the next call. + + - You can now use "#line" directives in the first section of your + scanner specification. + + - When generating full-table scanners (-Cf), flex now puts braces + around each row of the 2-d array initialization, to silence warnings + on over-zealous compilers. + + - Improved support for MS-DOS. The flex sources have been successfully + built, unmodified, for Borland 4.02 (all that's required is a + Borland Makefile and config.h file, which are supplied in + MISC/Borland - contributed by Terrence O Kane). + + - Improved support for Macintosh using Think C - the sources should + build for this platform "out of the box". Contributed by Scott + Hofmann. + + - Improved support for VMS, in MISC/VMS/, contributed by Pat Rankin. + + - Support for the Amiga, in MISC/Amiga/, contributed by Andreas + Scherer. Note that the contributed files were developed for + flex 2.4 and have not been tested with flex 2.5. + + - Some notes on support for the NeXT, in MISC/NeXT, contributed + by Raf Schietekat. + + - The MISC/ directory now includes a preformatted version of flex.1 + in flex.man, and pre-yacc'd versions of parse.y in parse.{c,h}. + + - The flex.1 and flexdoc.1 manual pages have been merged. There + is now just one document, flex.1, which includes an overview + at the beginning to help you find the section you need. + + - Documentation now clarifies that start conditions persist across + switches to new input files or different input buffers. If you + want to e.g., return to INITIAL, you must explicitly do so. + + - The "Performance Considerations" section of the manual has been + updated. + + - Documented the "yy_act" variable, which when YY_USER_ACTION is + invoked holds the number of the matched rule, and added an + example of using yy_act to profile how often each rule is matched. + + - Added YY_NUM_RULES, a definition that gives the total number + of rules in the file, including the default rule (even if you + use -s). + + - Documentation now clarifies that you can pass a nil FILE* pointer + to yy_create_buffer() or yyrestart() if you've arrange YY_INPUT + to not need yyin. + + - Documentation now clarifies that YY_BUFFER_STATE is a pointer to + an opaque "struct yy_buffer_state". + + - Documentation now stresses that you gain the benefits of removing + backing-up states only if you remove *all* of them. + + - Documentation now points out that traditional lex allows you + to put the action on a separate line from the rule pattern if + the pattern has trailing whitespace (ugh!), but flex doesn't + support this. + + - A broken example in documentation of the difference between + inclusive and exclusive start conditions is now fixed. + + - Usage (-h) report now goes to stdout. + + - Version (-V) info now goes to stdout. + + - More #ifdef chud has been added to the parser in attempt to + deal with bison's use of alloca(). + + - "make clean" no longer deletes emacs backup files (*~). + + - Some memory leaks have been fixed. + + - A bug was fixed in which dynamically-expanded buffers were + reallocated a couple of bytes too small. + + - A bug was fixed which could cause flex to read and write beyond + the end of the input buffer. + + - -S will not be going away. + + +Changes between release 2.4.7 (03Aug94) and release 2.4.6: + + - Fixed serious bug in reading multiple files. + + - Fixed bug in scanning NUL's. + + - Fixed bug in input() returning 8-bit characters. + + - Fixed bug in matching text with embedded NUL's when + using %array or lex compatibility. + + - Fixed multiple invocations of YY_USER_ACTION when using '|' + continuation action. + + - Minor prototyping fixes. + +Changes between release 2.4.6 (04Jan94) and release 2.4.5: + + - Linking with -lfl no longer required if your program includes + its own yywrap() and main() functions. (This change will cause + problems if you have a non-ANSI compiler on a system for which + sizeof(int) != sizeof(void*) or sizeof(int) != sizeof(size_t).) + + - The use of 'extern "C++"' in FlexLexer.h has been modified to + get around an incompatibility with g++'s header files. + +Changes between release 2.4.5 (11Dec93) and release 2.4.4: + + - Fixed bug breaking C++ scanners that use REJECT or variable + trailing context. + + - Fixed serious input problem for interactive scanners on + systems for which char is unsigned. + + - Fixed bug in incorrectly treating '$' operator as variable + trailing context. + + - Fixed bug in -CF table representation that could lead to + corrupt tables. + + - Fixed fairly benign memory leak. + + - Added `extern "C++"' wrapper to FlexLexer.h header. This + should overcome the g++ 2.5.X problems mentioned in the + NEWS for release 2.4.3. + + - Changed #include of FlexLexer.h to use <> instead of "". + + - Added feature to control whether the scanner attempts to + refill the input buffer once it's exhausted. This feature + will be documented in the 2.5 release. + + +Changes between release 2.4.4 (07Dec93) and release 2.4.3: + + - Fixed two serious bugs in scanning 8-bit characters. + + - Fixed bug in YY_USER_ACTION that caused it to be executed + inappropriately (on the scanner's own internal actions, and + with incorrect yytext/yyleng values). + + - Fixed bug in pointing yyin at a new file and resuming scanning. + + - Portability fix regarding min/max/abs macros conflicting with + function definitions in standard header files. + + - Added a virtual LexerError() method to the C++ yyFlexLexer class + for reporting error messages instead of always using cerr. + + - Added warning in flexdoc that the C++ scanning class is presently + experimental and subject to considerable change between major + releases. + + +Changes between release 2.4.3 (03Dec93) and release 2.4.2: + + - Fixed bug causing fatal scanner messages to fail to print. + + - Fixed things so FlexLexer.h can be included in other C++ + sources. One side-effect of this change is that -+ and -CF + are now incompatible. + + - libfl.a now supplies private versions of the the / + string routines needed by flex and the scanners + it generates, to enhance portability to some BSD systems. + + - More robust solution to 2.4.2's flexfatal() bug fix. + + - Added ranlib of installed libfl.a. + + - Some lint tweaks. + + - NOTE: problems have been encountered attempting to build flex + C++ scanners using g++ version 2.5.X. The problem is due to an + unfortunate heuristic in g++ 2.5.X that attempts to discern between + C and C++ headers. Because FlexLexer.h is installed (by default) + in /usr/local/include and not /usr/local/lib/g++-include, g++ 2.5.X + decides that it's a C header :-(. So if you have problems, install + the header in /usr/local/lib/g++-include instead. + + +Changes between release 2.4.2 (01Dec93) and release 2.4.1: + + - Fixed bug in libfl.a referring to non-existent "flexfatal" function. + + - Modified to produce both compress'd and gzip'd tar files for + distributions (you probably don't care about this change!). + + +Changes between release 2.4.1 (30Nov93) and release 2.3.8: + + - The new '-+' flag instructs flex to generate a C++ scanner class + (thanks to Kent Williams). flex writes an implementation of the + class defined in FlexLexer.h to lex.yy.cc. You may include + multiple scanner classes in your program using the -P flag. Note + that the scanner class also provides a mechanism for creating + reentrant scanners. The scanner class uses C++ streams for I/O + instead of FILE*'s (thanks to Tom Epperly). If the flex executable's + name ends in '+' then the '-+' flag is automatically on, so creating + a symlink or copy of "flex" to "flex++" results in a version of + flex that can be used exclusively for C++ scanners. + + Note that without the '-+' flag, flex-generated scanners can still + be compiled using C++ compilers, though they use FILE*'s for I/O + instead of streams. + + See the "GENERATING C++ SCANNERS" section of flexdoc for details. + + - The new '-l' flag turns on maximum AT&T lex compatibility. In + particular, -l includes support for "yylineno" and makes yytext + be an array instead of a pointer. It does not, however, do away + with all incompatibilities. See the "INCOMPATIBILITIES WITH LEX + AND POSIX" section of flexdoc for details. + + - The new '-P' option specifies a prefix to use other than "yy" + for the scanner's globally-visible variables, and for the + "lex.yy.c" filename. Using -P you can link together multiple + flex scanners in the same executable. + + - The distribution includes a "texinfo" version of flexdoc.1, + contributed by Roland Pesch (thanks also to Marq Kole, who + contributed another version). It has not been brought up to + date, but reflects version 2.3. See MISC/flex.texinfo. + + The flex distribution will soon include G.T. Nicol's flex + manual; he is presently bringing it up-to-date for version 2.4. + + - yywrap() is now a function, and you now *must* link flex scanners + with libfl.a. + + - Site-configuration is now done via an autoconf-generated + "configure" script contributed by Francois Pinard. + + - Scanners now use fread() (or getc(), if interactive) and not + read() for input. A new "table compression" option, -Cr, + overrides this change and causes the scanner to use read() + (because read() is a bit faster than fread()). -f and -F + are now equivalent to -Cfr and -CFr; i.e., they imply the + -Cr option. + + - In the blessed name of POSIX compliance, flex supports "%array" + and "%pointer" directives in the definitions (first) section of + the scanner specification. The former specifies that yytext + should be an array (of size YYLMAX), the latter, that it should + be a pointer. The array version of yytext is universally slower + than the pointer version, but has the advantage that its contents + remain unmodified across calls to input() and unput() (the pointer + version of yytext is, still, trashed by such calls). + + "%array" cannot be used with the '-+' C++ scanner class option. + + - The new '-Ca' option directs flex to trade off memory for + natural alignment when generating a scanner's tables. In + particular, table entries that would otherwise be "short" + become "long". + + - The new '-h' option produces a summary of the flex flags. + + - The new '-V' option reports the flex version number and exits. + + - The new scanner macro YY_START returns an integer value + corresponding to the current start condition. You can return + to that start condition by passing the value to a subsequent + "BEGIN" action. You also can implement "start condition stacks" + by storing the values in an integer stack. + + - You can now redefine macros such as YY_INPUT by just #define'ing + them to some other value in the first section of the flex input; + no need to first #undef them. + + - flex now generates warnings for rules that can't be matched. + These warnings can be turned off using the new '-w' flag. If + your scanner uses REJECT then you will not get these warnings. + + - If you specify the '-s' flag but the default rule can be matched, + flex now generates a warning. + + - "yyleng" is now a global, and may be modified by the user (though + doing so and then using yymore() will yield weird results). + + - Name definitions in the first section of a scanner specification + can now include a leading '^' or trailing '$' operator. In this + case, the definition is *not* pushed back inside of parentheses. + + - Scanners with compressed tables are now "interactive" (-I option) + by default. You can suppress this attribute (which makes them + run slightly slower) using the new '-B' flag. + + - Flex now generates 8-bit scanners by default, unless you use the + -Cf or -CF compression options (-Cfe and -CFe result in 8-bit + scanners). You can force it to generate a 7-bit scanner using + the new '-7' flag. You can build flex to generate 8-bit scanners + for -Cf and -CF, too, by adding -DDEFAULT_CSIZE=256 to CFLAGS + in the Makefile. + + - You no longer need to call the scanner routine yyrestart() to + inform the scanner that you have switched to a new file after + having seen an EOF on the current input file. Instead, just + point yyin at the new file and continue scanning. + + - You no longer need to invoke YY_NEW_FILE in an <> action + to indicate you wish to continue scanning. Simply point yyin + at a new file. + + - A leading '#' no longer introduces a comment in a flex input. + + - flex no longer considers formfeed ('\f') a whitespace character. + + - %t, I'm happy to report, has been nuked. + + - The '-p' option may be given twice ('-pp') to instruct flex to + report minor performance problems as well as major ones. + + - The '-v' verbose output no longer includes start/finish time + information. + + - Newlines in flex inputs can optionally include leading or + trailing carriage-returns ('\r'), in support of several PC/Mac + run-time libraries that automatically include these. + + - A start condition of the form "<*>" makes the following rule + active in every start condition, whether exclusive or inclusive. + + - The following items have been corrected in the flex documentation: + + - '-C' table compression options *are* cumulative. + + - You may modify yytext but not lengthen it by appending + characters to the end. Modifying its final character + will affect '^' anchoring for the next rule matched + if the character is changed to or from a newline. + + - The term "backtracking" has been renamed "backing up", + since it is a one-time repositioning and not a repeated + search. What used to be the "lex.backtrack" file is now + "lex.backup". + + - Unindented "/* ... */" comments are allowed in the first + flex input section, but not in the second. + + - yyless() can only be used in the flex input source, not + externally. + + - You can use "yyrestart(yyin)" to throw away the + current contents of the input buffer. + + - To write high-speed scanners, attempt to match as much + text as possible with each rule. See MISC/fastwc/README + for more information. + + - Using the beginning-of-line operator ('^') is fairly + cheap. Using unput() is expensive. Using yyless() is + cheap. + + - An example of scanning strings with embedded escape + sequences has been added. + + - The example of backing-up in flexdoc was erroneous; it + has been corrected. + + - A flex scanner's internal buffer now dynamically grows if needed + to match large tokens. Note that growing the buffer presently + requires rescanning the (large) token, so consuming a lot of + text this way is a slow process. Also note that presently the + buffer does *not* grow if you unput() more text than can fit + into the buffer. + + - The MISC/ directory has been reorganized; see MISC/README for + details. + + - yyless() can now be used in the third (user action) section + of a scanner specification, thanks to Ceriel Jacobs. yyless() + remains a macro and cannot be used outside of the scanner source. + + - The skeleton file is no longer opened at run-time, but instead + compiled into a large string array (thanks to John Gilmore and + friends at Cygnus). You can still use the -S flag to point flex + at a different skeleton file. + + - flex no longer uses a temporary file to store the scanner's + actions. + + - A number of changes have been made to decrease porting headaches. + In particular, flex no longer uses memset() or ctime(), and + provides a single simple mechanism for dealing with C compilers + that still define malloc() as returning char* instead of void*. + + - Flex now detects if the scanner specification requires the -8 flag + but the flag was not given or on by default. + + - A number of table-expansion fencepost bugs have been fixed, + making flex more robust for generating large scanners. + + - flex more consistently identifies the location of errors in + its input. + + - YY_USER_ACTION is now invoked only for "real" actions, not for + internal actions used by the scanner for things like filling + the buffer or handling EOF. + + - The rule "[^]]" now matches any character other than a ']'; + formerly it matched any character at all followed by a ']'. + This change was made for compatibility with AT&T lex. + + - A large number of miscellaneous bugs have been found and fixed + thanks to Gerhard Wilhelms. + + - The source code has been heavily reformatted, making patches + relative to previous flex releases no longer accurate. + + +Changes between 2.3 Patch #8 (21Feb93) and 2.3 Patch #7: + + - Fixed bugs in dynamic memory allocation leading to grievous + fencepost problems when generating large scanners. + - Fixed bug causing infinite loops on character classes with 8-bit + characters in them. + - Fixed bug in matching repetitions with a lower bound of 0. + - Fixed bug in scanning NUL characters using an "interactive" scanner. + - Fixed bug in using yymore() at the end of a file. + - Fixed bug in misrecognizing rules with variable trailing context. + - Fixed bug compiling flex on Suns using gcc 2. + - Fixed bug in not recognizing that input files with the character + ASCII 128 in them require the -8 flag. + - Fixed bug that could cause an infinite loop writing out + error messages. + - Fixed bug in not recognizing old-style lex % declarations if + followed by a tab instead of a space. + - Fixed potential crash when flex terminated early (usually due + to a bad flag) and the -v flag had been given. + - Added some missing declarations of void functions. + - Changed to only use '\a' for __STDC__ compilers. + - Updated mailing addresses. + + +Changes between 2.3 Patch #7 (28Mar91) and 2.3 Patch #6: + + - Fixed out-of-bounds array access that caused bad tables + to be produced on machines where the bad reference happened + to yield a 1. This caused problems installing or running + flex on some Suns, in particular. + + +Changes between 2.3 Patch #6 (29Aug90) and 2.3 Patch #5: + + - Fixed a serious bug in yymore() which basically made it + completely broken. Thanks goes to Jean Christophe of + the Nethack development team for finding the problem + and passing along the fix. + + +Changes between 2.3 Patch #5 (16Aug90) and 2.3 Patch #4: + + - An up-to-date version of initscan.c so "make test" will + work after applying the previous patches + + +Changes between 2.3 Patch #4 (14Aug90) and 2.3 Patch #3: + + - Fixed bug in hexadecimal escapes which allowed only digits, + not letters, in escapes + - Fixed bug in previous "Changes" file! + + +Changes between 2.3 Patch #3 (03Aug90) and 2.3 Patch #2: + + - Correction to patch #2 for gcc compilation; thanks goes to + Paul Eggert for catching this. + + +Changes between 2.3 Patch #2 (02Aug90) and original 2.3 release: + + - Fixed (hopefully) headaches involving declaring malloc() + and free() for gcc, which defines __STDC__ but (often) doesn't + come with the standard include files such as . + Reordered #ifdef maze in the scanner skeleton in the hope of + getting the declarations right for cfront and g++, too. + + - Note that this patch supercedes patch #1 for release 2.3, + which was never announced but was available briefly for + anonymous ftp. + + +Changes between 2.3 (full) release of 28Jun90 and 2.2 (alpha) release: + +User-visible: + + - A lone <> rule (that is, one which is not qualified with + a list of start conditions) now specifies the EOF action for + *all* start conditions which haven't already had <> actions + given. To specify an end-of-file action for just the initial + state, use <>. + + - -d debug output is now contigent on the global yy_flex_debug + being set to a non-zero value, which it is by default. + + - A new macro, YY_USER_INIT, is provided for the user to specify + initialization action to be taken on the first call to the + scanner. This action is done before the scanner does its + own initialization. + + - yy_new_buffer() has been added as an alias for yy_create_buffer() + + - Comments beginning with '#' and extending to the end of the line + now work, but have been deprecated (in anticipation of making + flex recognize #line directives). + + - The funky restrictions on when semi-colons could follow the + YY_NEW_FILE and yyless macros have been removed. They now + behave identically to functions. + + - A bug in the sample redefinition of YY_INPUT in the documentation + has been corrected. + + - A bug in the sample simple tokener in the documentation has + been corrected. + + - The documentation on the incompatibilities between flex and + lex has been reordered so that the discussion of yylineno + and input() come first, as it's anticipated that these will + be the most common source of headaches. + + +Things which didn't used to be documented but now are: + + - flex interprets "^foo|bar" differently from lex. flex interprets + it as "match either a 'foo' or a 'bar', providing it comes at the + beginning of a line", whereas lex interprets it as "match either + a 'foo' at the beginning of a line, or a 'bar' anywhere". + + - flex initializes the global "yyin" on the first call to the + scanner, while lex initializes it at compile-time. + + - yy_switch_to_buffer() can be used in the yywrap() macro/routine. + + - flex scanners do not use stdio for their input, and hence when + writing an interactive scanner one must explictly call fflush() + after writing out a prompt. + + - flex scanner can be made reentrant (after a fashion) by using + "yyrestart( yyin );". This is useful for interactive scanners + which have interrupt handlers that long-jump out of the scanner. + + - a defense of why yylineno is not supported is included, along + with a suggestion on how to convert scanners which rely on it. + + +Other changes: + + - Prototypes and proper declarations of void routines have + been added to the flex source code, courtesy of Kevin B. Kenny. + + - Routines dealing with memory allocation now use void* pointers + instead of char* - see Makefile for porting implications. + + - Error-checking is now done when flex closes a file. + + - Various lint tweaks were added to reduce the number of gripes. + + - Makefile has been further parameterized to aid in porting. + + - Support for SCO Unix added. + + - Flex now sports the latest & greatest UC copyright notice + (which is only slightly different from the previous one). + + - A note has been added to flexdoc.1 mentioning work in progress + on modifying flex to generate straight C code rather than a + table-driven automaton, with an email address of whom to contact + if you are working along similar lines. + + +Changes between 2.2 Patch #3 (30Mar90) and 2.2 Patch #2: + + - fixed bug which caused -I scanners to bomb + + +Changes between 2.2 Patch #2 (27Mar90) and 2.2 Patch #1: + + - fixed bug writing past end of input buffer in yyunput() + - fixed bug detecting NUL's at the end of a buffer + + +Changes between 2.2 Patch #1 (23Mar90) and 2.2 (alpha) release: + + - Makefile fixes: definition of MAKE variable for systems + which don't have it; installation of flexdoc.1 along with + flex.1; fixed two bugs which could cause "bigtest" to fail. + + - flex.skel fix for compiling with g++. + + - README and flexdoc.1 no longer list an out-of-date BITNET address + for contacting me. + + - minor typos and formatting changes to flex.1 and flexdoc.1. + + +Changes between 2.2 (alpha) release of March '90 and previous release: + +User-visible: + + - Full user documentation now available. + + - Support for 8-bit scanners. + + - Scanners now accept NUL's. + + - A facility has been added for dealing with multiple + input buffers. + + - Two manual entries now. One which fully describes flex + (rather than just its differences from lex), and the + other for quick(er) reference. + + - A number of changes to bring flex closer into compliance + with the latest POSIX lex draft: + + %t support + flex now accepts multiple input files and concatenates + them together to form its input + previous -c (compress) flag renamed -C + do-nothing -c and -n flags added + Any indented code or code within %{}'s in section 2 is + now copied to the output + + - yyleng is now a bona fide global integer. + + - -d debug information now gives the line number of the + matched rule instead of which number rule it was from + the beginning of the file. + + - -v output now includes a summary of the flags used to generate + the scanner. + + - unput() and yyrestart() are now globally callable. + + - yyrestart() no longer closes the previous value of yyin. + + - C++ support; generated scanners can be compiled with C++ compiler. + + - Primitive -lfl library added, containing default main() + which calls yylex(). A number of routines currently living + in the scanner skeleton will probably migrate to here + in the future (in particular, yywrap() will probably cease + to be a macro and instead be a function in the -lfl library). + + - Hexadecimal (\x) escape sequences added. + + - Support for MS-DOS, VMS, and Turbo-C integrated. + + - The %used/%unused operators have been deprecated. They + may go away soon. + + +Other changes: + + - Makefile enhanced for easier testing and installation. + - The parser has been tweaked to detect some erroneous + constructions which previously were missed. + - Scanner input buffer overflow is now detected. + - Bugs with missing "const" declarations fixed. + - Out-of-date Minix/Atari patches provided. + - Scanners no longer require printf() unless FLEX_DEBUG is being used. + - A subtle input() bug has been fixed. + - Line numbers for "continued action" rules (those following + the special '|' action) are now correct. + - unput() bug fixed; had been causing problems porting flex to VMS. + - yymore() handling rewritten to fix bug with interaction + between yymore() and trailing context. + - EOF in actions now generates an error message. + - Bug involving -CFe and generating equivalence classes fixed. + - Bug which made -CF be treated as -Cf fixed. + - Support for SysV tmpnam() added. + - Unused #define's for scanner no longer generated. + - Error messages which are associated with a particular input + line are now all identified with their input line in standard + format. + - % directives which are valid to lex but not to flex are + now ignored instead of generating warnings. + - -DSYS_V flag can now also be specified -DUSG for System V + compilation. + + +Changes between 2.1 beta-test release of June '89 and previous release: + +User-visible: + + - -p flag generates a performance report to stderr. The report + consists of comments regarding features of the scanner rules + which result in slower scanners. + + - -b flag generates backtracking information to lex.backtrack. + This is a list of scanner states which require backtracking + and the characters on which they do so. By adding rules + one can remove backtracking states. If all backtracking states + are eliminated, the generated scanner will run faster. + Backtracking is not yet documented in the manual entry. + + - Variable trailing context now works, i.e., one can have + rules like "(foo)*/[ \t]*bletch". Some trailing context + patterns still cannot be properly matched and generate + error messages. These are patterns where the ending of the + first part of the rule matches the beginning of the second + part, such as "zx*/xy*", where the 'x*' matches the 'x' at + the beginning of the trailing context. Lex won't get these + patterns right either. + + - Faster scanners. + + - End-of-file rules. The special rule "<>" indicates + actions which are to be taken when an end-of-file is + encountered and yywrap() returns non-zero (i.e., indicates + no further files to process). See manual entry for example. + + - The -r (reject used) flag is gone. flex now scans the input + for occurrences of the string "REJECT" to determine if the + action is needed. It tries to be intelligent about this but + can be fooled. One can force the presence or absence of + REJECT by adding a line in the first section of the form + "%used REJECT" or "%unused REJECT". + + - yymore() has been implemented. Similarly to REJECT, flex + detects the use of yymore(), which can be overridden using + "%used" or "%unused". + + - Patterns like "x{0,3}" now work (i.e., with lower-limit == 0). + + - Removed '\^x' for ctrl-x misfeature. + + - Added '\a' and '\v' escape sequences. + + - \ now works for octal escape sequences; previously + \0 was required. + + - Better error reporting; line numbers are associated with rules. + + - yyleng is a macro; it cannot be accessed outside of the + scanner source file. + + - yytext and yyleng should not be modified within a flex action. + + - Generated scanners #define the name FLEX_SCANNER. + + - Rules are internally separated by YY_BREAK in lex.yy.c rather + than break, to allow redefinition. + + - The macro YY_USER_ACTION can be redefined to provide an action + which is always executed prior to the matched rule's action. + + - yyrestart() is a new action which can be used to restart + the scanner after it has seen an end-of-file (a "real" one, + that is, one for which yywrap() returned non-zero). It takes + a FILE* argument indicating a new file to scan and sets + things up so that a subsequent call to yylex() will start + scanning that file. + + - Internal scanner names all preceded by "yy_" + + - lex.yy.c is deleted if errors are encountered during processing. + + - Comments may be put in the first section of the input by preceding + them with '#'. + + + +Other changes: + + - Some portability-related bugs fixed, in particular for machines + with unsigned characters or sizeof( int* ) != sizeof( int ). + Also, tweaks for VMS and Microsoft C (MS-DOS), and identifiers all + trimmed to be 31 or fewer characters. Shortened file names + for dinosaur OS's. Checks for allocating > 64K memory + on 16 bit'ers. Amiga tweaks. Compiles using gcc on a Sun-3. + - Compressed and fast scanner skeletons merged. + - Skeleton header files done away with. + - Generated scanner uses prototypes and "const" for __STDC__. + - -DSV flag is now -DSYS_V for System V compilation. + - Removed all references to FTL language. + - Software now covered by BSD Copyright. + - flex will replace lex in subsequent BSD releases. diff --git a/third_party/lex/README.txt b/third_party/lex/README.txt new file mode 100644 index 00000000..f7bd40b7 --- /dev/null +++ b/third_party/lex/README.txt @@ -0,0 +1,2759 @@ +FLEX(1) Cosmopolitan General Commands Manual -*-text-*- + +𝐍𝐀𝐌𝐄 + 𝗳𝗹𝗲𝘅, 𝗳𝗹𝗲𝘅++, 𝗹𝗲𝘅 — fast lexical analyzer generator + +𝐒𝐘𝐍𝐎𝐏𝐒𝐈𝐒 + 𝗳𝗹𝗲𝘅 [-𝟳𝟴𝐁𝗯𝗱𝐅𝗳𝗵𝐈𝗶𝐋𝗹𝗻𝗽𝘀𝐓𝘁𝐕𝘃𝘄+?] [-𝐂[𝗮𝗲𝐅𝗳𝗺𝗿]] [--𝗵𝗲𝗹𝗽] [--𝘃𝗲𝗿𝘀𝗶𝗼𝗻] + [-𝗼o̲u̲t̲p̲u̲t̲] [-𝐏p̲r̲e̲f̲i̲x̲] [-𝐒s̲k̲e̲l̲e̲t̲o̲n̲] [f̲i̲l̲e̲ .̲.̲.̲] + +𝐃𝐄𝐒𝐂𝐑𝐈𝐏𝐓𝐈𝐎𝐍 + 𝗳𝗹𝗲𝘅 is a tool for generating s̲c̲a̲n̲n̲e̲r̲s̲: programs which recognize + lexical patterns in text. 𝗳𝗹𝗲𝘅 reads the given input files, or its + standard input if no file names are given, for a description of a + scanner to generate. The description is in the form of pairs of + regular expressions and C code, called r̲u̲l̲e̲s̲. 𝗳𝗹𝗲𝘅 generates as + output a C source file, l̲e̲x̲.̲y̲y̲.̲c̲, which defines a routine 𝘆𝘆𝗹𝗲𝘅(). + This file is compiled and linked with the -𝗹𝗳𝗹 library to produce + an executable. When the executable is run, it analyzes its input + for occurrences of the regular expressions. Whenever it finds one, + it executes the corresponding C code. + + 𝗹𝗲𝘅 is a synonym for 𝗳𝗹𝗲𝘅. 𝗳𝗹𝗲𝘅++ is a synonym for 𝗳𝗹𝗲𝘅 -+. + + The manual includes both tutorial and reference sections: + + 𝐒𝗼𝗺𝗲 𝐒𝗶𝗺𝗽𝗹𝗲 𝐄𝘅𝗮𝗺𝗽𝗹𝗲𝘀 + + 𝐅𝗼𝗿𝗺𝗮𝘁 𝗼𝗳 𝘁𝗵𝗲 𝐈𝗻𝗽𝘂𝘁 𝐅𝗶𝗹𝗲 + + 𝐏𝗮𝘁𝘁𝗲𝗿𝗻𝘀 + The extended regular expressions used by 𝗳𝗹𝗲𝘅. + + 𝐇𝗼𝘄 𝘁𝗵𝗲 𝐈𝗻𝗽𝘂𝘁 𝗶𝘀 𝐌𝗮𝘁𝗰𝗵𝗲𝗱 + The rules for determining what has been matched. + + 𝐀𝗰𝘁𝗶𝗼𝗻𝘀 + How to specify what to do when a pattern is matched. + + 𝐓𝗵𝗲 𝐆𝗲𝗻𝗲𝗿𝗮𝘁𝗲𝗱 𝐒𝗰𝗮𝗻𝗻𝗲𝗿 + Details regarding the scanner that 𝗳𝗹𝗲𝘅 produces; how to control + the input source. + + 𝐒𝘁𝗮𝗿𝘁 𝐂𝗼𝗻𝗱𝗶𝘁𝗶𝗼𝗻𝘀 + Introducing context into scanners, and managing "mini-scanners". + + 𝐌𝘂𝗹𝘁𝗶𝗽𝗹𝗲 𝐈𝗻𝗽𝘂𝘁 𝐁𝘂𝗳𝗳𝗲𝗿𝘀 + How to manipulate multiple input sources; how to scan from strings + instead of files. + + 𝐄𝗻𝗱-𝗼𝗳-𝐅𝗶𝗹𝗲 𝐑𝘂𝗹𝗲𝘀 + Special rules for matching the end of the input. + + 𝐌𝗶𝘀𝗰𝗲𝗹𝗹𝗮𝗻𝗲𝗼𝘂𝘀 𝐌𝗮𝗰𝗿𝗼𝘀 + A summary of macros available to the actions. + + 𝐕𝗮𝗹𝘂𝗲𝘀 𝐀𝘃𝗮𝗶𝗹𝗮𝗯𝗹𝗲 𝘁𝗼 𝘁𝗵𝗲 𝐔𝘀𝗲𝗿 + A summary of values available to the actions. + + 𝐈𝗻𝘁𝗲𝗿𝗳𝗮𝗰𝗶𝗻𝗴 𝘄𝗶𝘁𝗵 𝐘𝗮𝗰𝗰 + Connecting flex scanners together with yacc(1) parsers. + + 𝐎𝗽𝘁𝗶𝗼𝗻𝘀 + 𝗳𝗹𝗲𝘅 command-line options, and the “%option” directive. + + 𝐏𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲 𝐂𝗼𝗻𝘀𝗶𝗱𝗲𝗿𝗮𝘁𝗶𝗼𝗻𝘀 + How to make scanners go as fast as possible. + + 𝐆𝗲𝗻𝗲𝗿𝗮𝘁𝗶𝗻𝗴 𝐂++ 𝐒𝗰𝗮𝗻𝗻𝗲𝗿𝘀 + The (experimental) facility for generating C++ scanner classes. + + 𝐈𝗻𝗰𝗼𝗺𝗽𝗮𝘁𝗶𝗯𝗶𝗹𝗶𝘁𝗶𝗲𝘀 𝘄𝗶𝘁𝗵 𝐋𝗲𝘅 𝗮𝗻𝗱 𝐏𝐎𝐒𝐈𝐗 + How 𝗳𝗹𝗲𝘅 differs from AT&T UNIX 𝗹𝗲𝘅 and the POSIX 𝗹𝗲𝘅 standard. + + 𝐅𝗶𝗹𝗲𝘀 + Files used by 𝗳𝗹𝗲𝘅. + + 𝐃𝗶𝗮𝗴𝗻𝗼𝘀𝘁𝗶𝗰𝘀 + Those error messages produced by 𝗳𝗹𝗲𝘅 (or scanners it generates) + whose meanings might not be apparent. + + 𝐒𝗲𝗲 𝐀𝗹𝘀𝗼 + Other documentation, related tools. + + 𝐀𝘂𝘁𝗵𝗼𝗿𝘀 + Includes contact information. + + 𝐁𝘂𝗴𝘀 + Known problems with 𝗳𝗹𝗲𝘅. + +𝐒𝐎𝐌𝐄 𝐒𝐈𝐌𝐏𝐋𝐄 𝐄𝐗𝐀𝐌𝐏𝐋𝐄𝐒 + First some simple examples to get the flavor of how one uses 𝗳𝗹𝗲𝘅. + The following 𝗳𝗹𝗲𝘅 input specifies a scanner which whenever it + encounters the string "username" will replace it with the user's + login name: + + %% + username printf("%s", getlogin()); + + By default, any text not matched by a 𝗳𝗹𝗲𝘅 scanner is copied to the + output, so the net effect of this scanner is to copy its input file + to its output with each occurrence of "username" expanded. In this + input, there is just one rule. "username" is the p̲a̲t̲t̲e̲r̲n̲ and the + "printf" is the a̲c̲t̲i̲o̲n̲. The "%%" marks the beginning of the rules. + + Here's another simple example: + + %{ + int num_lines = 0, num_chars = 0; + %} + + %% + \n ++num_lines; ++num_chars; + . ++num_chars; + + %% + main() + { + yylex(); + printf("# of lines = %d, # of chars = %d\n", + num_lines, num_chars); + } + + This scanner counts the number of characters and the number of + lines in its input (it produces no output other than the final + report on the counts). The first line declares two globals, + "num_lines" and "num_chars", which are accessible both inside + 𝘆𝘆𝗹𝗲𝘅() and in the 𝗺𝗮𝗶𝗻() routine declared after the second "%%". + There are two rules, one which matches a newline ("\n") and incre‐ + ments both the line count and the character count, and one which + matches any character other than a newline (indicated by the "." + regular expression). + + A somewhat more complicated example: + + /* scanner for a toy Pascal-like language */ + + %{ + /* need this for the call to atof() below */ + #include + %} + + DIGIT [0-9] + ID [a-z][a-z0-9]* + + %% + + {DIGIT}+ { + printf("An integer: %s (%d)\n", yytext, + atoi(yytext)); + } + + {DIGIT}+"."{DIGIT}* { + printf("A float: %s (%g)\n", yytext, + atof(yytext)); + } + + if|then|begin|end|procedure|function { + printf("A keyword: %s\n", yytext); + } + + {ID} printf("An identifier: %s\n", yytext); + + "+"|"-"|"*"|"/" printf("An operator: %s\n", yytext); + + "{"[^}\n]*"}" /* eat up one-line comments */ + + [ \t\n]+ /* eat up whitespace */ + + . printf("Unrecognized character: %s\n", yytext); + + %% + + main(int argc, char *argv[]) + { + ++argv; --argc; /* skip over program name */ + if (argc > 0) + yyin = fopen(argv[0], "r"); + else + yyin = stdin; + + yylex(); + } + + This is the beginnings of a simple scanner for a language like Pas‐ + cal. It identifies different types of t̲o̲k̲e̲n̲s̲ and reports on what + it has seen. + + The details of this example will be explained in the following sec‐ + tions. + +𝐅𝐎𝐑𝐌𝐀𝐓 𝐎𝐅 𝐓𝐇𝐄 𝐈𝐍𝐏𝐔𝐓 𝐅𝐈𝐋𝐄 + The 𝗳𝗹𝗲𝘅 input file consists of three sections, separated by a line + with just "%%" in it: + + definitions + %% + rules + %% + user code + + The d̲e̲f̲i̲n̲i̲t̲i̲o̲n̲s̲ section contains declarations of simple n̲a̲m̲e̲ defi‐ + nitions to simplify the scanner specification, and declarations of + s̲t̲a̲r̲t̲ c̲o̲n̲d̲i̲t̲i̲o̲n̲s̲, which are explained in a later section. + + Name definitions have the form: + + name definition + + The "name" is a word beginning with a letter or an underscore (‘_’) + followed by zero or more letters, digits, ‘_’, or ‘-’ (dash). The + definition is taken to begin at the first non-whitespace character + following the name and continuing to the end of the line. The def‐ + inition can subsequently be referred to using "{name}", which will + expand to "(definition)". For example: + + DIGIT [0-9] + ID [a-z][a-z0-9]* + + This defines "DIGIT" to be a regular expression which matches a + single digit, and "ID" to be a regular expression which matches a + letter followed by zero-or-more letters-or-digits. A subsequent + reference to + + {DIGIT}+"."{DIGIT}* + + is identical to + + ([0-9])+"."([0-9])* + + and matches one-or-more digits followed by a ‘.’ followed by zero- + or-more digits. + + The r̲u̲l̲e̲s̲ section of the 𝗳𝗹𝗲𝘅 input contains a series of rules of + the form: + + pattern action + + The pattern must be unindented and the action must begin on the + same line. + + See below for a further description of patterns and actions. + + Finally, the user code section is simply copied to l̲e̲x̲.̲y̲y̲.̲c̲ verba‐ + tim. It is used for companion routines which call or are called by + the scanner. The presence of this section is optional; if it is + missing, the second "%%" in the input file may be skipped too. + + In the definitions and rules sections, any indented text or text + enclosed in ‘%{’ and ‘%}’ is copied verbatim to the output (with + the %{}'s removed). The %{}'s must appear unindented on lines by + themselves. + + In the rules section, any indented or %{} text appearing before the + first rule may be used to declare variables which are local to the + scanning routine and (after the declarations) code which is to be + executed whenever the scanning routine is entered. Other indented + or %{} text in the rule section is still copied to the output, but + its meaning is not well-defined and it may well cause compile-time + errors (this feature is present for POSIX compliance; see below for + other such features). + + In the definitions section (but not in the rules section), an unin‐ + dented comment (i.e., a line beginning with "/*") is also copied + verbatim to the output up to the next "*/". + +𝐏𝐀𝐓𝐓𝐄𝐑𝐍𝐒 + The patterns in the input are written using an extended set of reg‐ + ular expressions. These are: + + x Match the character ‘x’. + + . Any character (byte) except newline. + + [xyz] A "character class"; in this case, the pattern matches + either an ‘x’, a ‘y’, or a ‘z’. + + [abj-oZ] A "character class" with a range in it; matches an ‘a’, a + ‘b’, any letter from ‘j’ through ‘o’, or a ‘Z’. + + [^A-Z] A "negated character class", i.e., any character but + those in the class. In this case, any character EXCEPT + an uppercase letter. + + [^A-Z\n] Any character EXCEPT an uppercase letter or a newline. + + r* Zero or more r's, where ‘r’ is any regular expression. + + r+ One or more r's. + + r? Zero or one r's (that is, "an optional r"). + + r{2,5} Anywhere from two to five r's. + + r{2,} Two or more r's. + + r{4} Exactly 4 r's. + + {name} The expansion of the "name" definition (see above). + + "[xyz]\"foo" + The literal string: [xyz]"foo. + + \X If ‘X’ is an ‘a’, ‘b’, ‘f’, ‘n’, ‘r’, ‘t’, or ‘v’, then + the ANSI-C interpretation of ‘\X’. Otherwise, a literal + ‘X’ (used to escape operators such as ‘*’). + + \0 A NUL character (ASCII code 0). + + \123 The character with octal value 123. + + \x2a The character with hexadecimal value 2a. + + (r) Match an ‘r’; parentheses are used to override precedence + (see below). + + rs The regular expression ‘r’ followed by the regular + expression ‘s’; called "concatenation". + + r|s Either an ‘r’ or an ‘s’. + + r/s An ‘r’, but only if it is followed by an ‘s’. The text + matched by ‘s’ is included when determining whether this + rule is the "longest match", but is then returned to the + input before the action is executed. So the action only + sees the text matched by ‘r’. This type of pattern is + called "trailing context". (There are some combinations + of r/s that 𝗳𝗹𝗲𝘅 cannot match correctly; see notes in the + B̲U̲G̲S̲ section below regarding "dangerous trailing + context".) + + ^r An ‘r’, but only at the beginning of a line (i.e., just + starting to scan, or right after a newline has been + scanned). + + r$ An ‘r’, but only at the end of a line (i.e., just before + a newline). Equivalent to "r/\n". + + Note that 𝗳𝗹𝗲𝘅's notion of "newline" is exactly whatever + the C compiler used to compile 𝗳𝗹𝗲𝘅 interprets ‘\n’ as. + + r An ‘r’, but only in start condition ‘s’ (see below for + discussion of start conditions). + + r + The same, but in any of start conditions s1, s2, or s3. + + <*>r An ‘r’ in any start condition, even an exclusive one. + + <> An end-of-file. + + <> + An end-of-file when in start condition s1 or s2. + + Note that inside of a character class, all regular expression oper‐ + ators lose their special meaning except escape (‘\’) and the char‐ + acter class operators, ‘-’, ‘]’, and, at the beginning of the + class, ‘^’. + + The regular expressions listed above are grouped according to + precedence, from highest precedence at the top to lowest at the + bottom. Those grouped together have equal precedence. For exam‐ + ple, + + foo|bar* + + is the same as + + (foo)|(ba(r*)) + + since the ‘*’ operator has higher precedence than concatenation, + and concatenation higher than alternation (‘|’). This pattern + therefore matches e̲i̲t̲h̲e̲r̲ the string "foo" o̲r̲ the string "ba" fol‐ + lowed by zero-or-more r's. To match "foo" or zero-or-more "bar"'s, + use: + + foo|(bar)* + + and to match zero-or-more "foo"'s-or-"bar"'s: + + (foo|bar)* + + In addition to characters and ranges of characters, character + classes can also contain character class e̲x̲p̲r̲e̲s̲s̲i̲o̲n̲s̲. These are + expressions enclosed inside ‘[:’ and ‘:]’ delimiters (which them‐ + selves must appear between the ‘[’ and ‘]’ of the character class; + other elements may occur inside the character class, too). The + valid expressions are: + + [:alnum:] [:alpha:] [:blank:] + [:cntrl:] [:digit:] [:graph:] + [:lower:] [:print:] [:punct:] + [:space:] [:upper:] [:xdigit:] + + These expressions all designate a set of characters equivalent to + the corresponding standard C 𝗶𝘀𝐗𝐗𝐗() function. For example, + [:alnum:] designates those characters for which isalnum(3) returns + true - i.e., any alphabetic or numeric. Some systems don't provide + isblank(3), so 𝗳𝗹𝗲𝘅 defines [:blank:] as a blank or a tab. + + For example, the following character classes are all equivalent: + + [[:alnum:]] + [[:alpha:][:digit:]] + [[:alpha:]0-9] + [a-zA-Z0-9] + + If the scanner is case-insensitive (the -𝗶 flag), then [:upper:] + and [:lower:] are equivalent to [:alpha:]. + + Some notes on patterns: + + - A negated character class such as the example "[^A-Z]" above + will match a newline unless "\n" (or an equivalent escape + sequence) is one of the characters explicitly present in the + negated character class (e.g., "[^A-Z\n]"). This is unlike how + many other regular expression tools treat negated character + classes, but unfortunately the inconsistency is historically + entrenched. Matching newlines means that a pattern like + "[^"]*" can match the entire input unless there's another quote + in the input. + + - A rule can have at most one instance of trailing context (the + ‘/’ operator or the ‘$’ operator). The start condition, ‘^’, + and "<>" patterns can only occur at the beginning of a + pattern and, as well as with ‘/’ and ‘$’, cannot be grouped + inside parentheses. A ‘^’ which does not occur at the begin‐ + ning of a rule or a ‘$’ which does not occur at the end of a + rule loses its special properties and is treated as a normal + character. + + - The following are illegal: + + foo/bar$ + foobar + + Note that the first of these, can be written "foo/bar\n". + + - The following will result in ‘$’ or ‘^’ being treated as a nor‐ + mal character: + + foo|(bar$) + foo|^bar + + If what's wanted is a "foo" or a bar-followed-by-a-newline, the + following could be used (the special ‘|’ action is explained + below): + + foo | + bar$ /* action goes here */ + + A similar trick will work for matching a foo or a bar-at-the- + beginning-of-a-line. + +𝐇𝐎𝐖 𝐓𝐇𝐄 𝐈𝐍𝐏𝐔𝐓 𝐈𝐒 𝐌𝐀𝐓𝐂𝐇𝐄𝐃 + When the generated scanner is run, it analyzes its input looking + for strings which match any of its patterns. If it finds more than + one match, it takes the one matching the most text (for trailing + context rules, this includes the length of the trailing part, even + though it will then be returned to the input). If it finds two or + more matches of the same length, the rule listed first in the 𝗳𝗹𝗲𝘅 + input file is chosen. + + Once the match is determined, the text corresponding to the match + (called the t̲o̲k̲e̲n̲) is made available in the global character + pointer y̲y̲t̲e̲x̲t̲, and its length in the global integer y̲y̲l̲e̲n̲g̲. The + a̲c̲t̲i̲o̲n̲ corresponding to the matched pattern is then executed (a + more detailed description of actions follows), and then the remain‐ + ing input is scanned for another match. + + If no match is found, then the default rule is executed: the next + character in the input is considered matched and copied to the + standard output. Thus, the simplest legal 𝗳𝗹𝗲𝘅 input is: + + %% + + which generates a scanner that simply copies its input (one + character at a time) to its output. + + Note that y̲y̲t̲e̲x̲t̲ can be defined in two different ways: either as a + character pointer or as a character array. Which definition 𝗳𝗹𝗲𝘅 + uses can be controlled by including one of the special directives + “%pointer” or “%array” in the first (definitions) section of flex + input. The default is “%pointer”, unless the -𝗹 𝗹𝗲𝘅 compatibility + option is used, in which case y̲y̲t̲e̲x̲t̲ will be an array. The advan‐ + tage of using “%pointer” is substantially faster scanning and no + buffer overflow when matching very large tokens (unless not enough + dynamic memory is available). The disadvantage is that actions are + restricted in how they can modify y̲y̲t̲e̲x̲t̲ (see the next section), + and calls to the 𝘂𝗻𝗽𝘂𝘁() function destroy the present contents of + y̲y̲t̲e̲x̲t̲, which can be a considerable porting headache when moving + between different 𝗹𝗲𝘅 versions. + + The advantage of “%array” is that y̲y̲t̲e̲x̲t̲ can be modified as much as + wanted, and calls to 𝘂𝗻𝗽𝘂𝘁() do not destroy y̲y̲t̲e̲x̲t̲ (see below). + Furthermore, existing 𝗹𝗲𝘅 programs sometimes access y̲y̲t̲e̲x̲t̲ exter‐ + nally using declarations of the form: + + extern char yytext[]; + + This definition is erroneous when used with “%pointer”, but correct + for “%array”. + + “%array” defines y̲y̲t̲e̲x̲t̲ to be an array of YYLMAX characters, which + defaults to a fairly large value. The size can be changed by sim‐ + ply #define'ing YYLMAX to a different value in the first section of + 𝗳𝗹𝗲𝘅 input. As mentioned above, with “%pointer” yytext grows + dynamically to accommodate large tokens. While this means a + “%pointer” scanner can accommodate very large tokens (such as + matching entire blocks of comments), bear in mind that each time + the scanner must resize y̲y̲t̲e̲x̲t̲ it also must rescan the entire token + from the beginning, so matching such tokens can prove slow. y̲y̲t̲e̲x̲t̲ + presently does not dynamically grow if a call to 𝘂𝗻𝗽𝘂𝘁() results in + too much text being pushed back; instead, a run-time error results. + + Also note that “%array” cannot be used with C++ scanner classes + (the c++ option; see below). + +𝐀𝐂𝐓𝐈𝐎𝐍𝐒 + Each pattern in a rule has a corresponding action, which can be any + arbitrary C statement. The pattern ends at the first non-escaped + whitespace character; the remainder of the line is its action. If + the action is empty, then when the pattern is matched the input + token is simply discarded. For example, here is the specification + for a program which deletes all occurrences of "zap me" from its + input: + + %% + "zap me" + + (It will copy all other characters in the input to the output since + they will be matched by the default rule.) + + Here is a program which compresses multiple blanks and tabs down to + a single blank, and throws away whitespace found at the end of a + line: + + %% + [ \t]+ putchar(' '); + [ \t]+$ /* ignore this token */ + + If the action contains a ‘{’, then the action spans till the bal‐ + ancing ‘}’ is found, and the action may cross multiple lines. 𝗳𝗹𝗲𝘅 + knows about C strings and comments and won't be fooled by braces + found within them, but also allows actions to begin with ‘%{’ and + will consider the action to be all the text up to the next ‘%}’ + (regardless of ordinary braces inside the action). + + An action consisting solely of a vertical bar (‘|’) means "same as + the action for the next rule". See below for an illustration. + + Actions can include arbitrary C code, including return statements + to return a value to whatever routine called 𝘆𝘆𝗹𝗲𝘅(). Each time + 𝘆𝘆𝗹𝗲𝘅() is called, it continues processing tokens from where it + last left off until it either reaches the end of the file or exe‐ + cutes a return. + + Actions are free to modify y̲y̲t̲e̲x̲t̲ except for lengthening it (adding + characters to its end - these will overwrite later characters in + the input stream). This, however, does not apply when using + “%array” (see above); in that case, y̲y̲t̲e̲x̲t̲ may be freely modified + in any way. + + Actions are free to modify y̲y̲l̲e̲n̲g̲ except they should not do so if + the action also includes use of 𝘆𝘆𝗺𝗼𝗿𝗲() (see below). + + There are a number of special directives which can be included + within an action: + + ECHO Copies y̲y̲t̲e̲x̲t̲ to the scanner's output. + + BEGIN Followed by the name of a start condition, places the scan‐ + ner in the corresponding start condition (see below). + + REJECT Directs the scanner to proceed on to the "second best" rule + which matched the input (or a prefix of the input). The + rule is chosen as described above in H̲O̲W̲ T̲H̲E̲ I̲N̲P̲U̲T̲ I̲S̲ + M̲A̲T̲C̲H̲E̲D̲, and y̲y̲t̲e̲x̲t̲ and y̲y̲l̲e̲n̲g̲ set up appropriately. It + may either be one which matched as much text as the origi‐ + nally chosen rule but came later in the 𝗳𝗹𝗲𝘅 input file, or + one which matched less text. For example, the following + will both count the words in the input and call the routine + 𝘀𝗽𝗲𝗰𝗶𝗮𝗹() whenever "frob" is seen: + + int word_count = 0; + %% + + frob special(); REJECT; + [^ \t\n]+ ++word_count; + + Without the R̲E̲J̲E̲C̲T̲, any "frob"'s in the input would not be + counted as words, since the scanner normally executes only + one action per token. Multiple R̲E̲J̲E̲C̲T̲'s are allowed, each + one finding the next best choice to the currently active + rule. For example, when the following scanner scans the + token "abcd", it will write "abcdabcaba" to the output: + + %% + a | + ab | + abc | + abcd ECHO; REJECT; + .|\n /* eat up any unmatched character */ + + (The first three rules share the fourth's action since they + use the special ‘|’ action.) R̲E̲J̲E̲C̲T̲ is a particularly + expensive feature in terms of scanner performance; if it is + used in any of the scanner's actions it will slow down all + of the scanner's matching. Furthermore, R̲E̲J̲E̲C̲T̲ cannot be + used with the -𝐂𝗳 or -𝐂𝐅 options (see below). + + Note also that unlike the other special actions, R̲E̲J̲E̲C̲T̲ is + a b̲r̲a̲n̲c̲h̲; code immediately following it in the action will + not be executed. + + yymore() + Tells the scanner that the next time it matches a rule, the + corresponding token should be appended onto the current + value of y̲y̲t̲e̲x̲t̲ rather than replacing it. For example, + given the input "mega-kludge" the following will write + "mega-mega-kludge" to the output: + + %% + mega- ECHO; yymore(); + kludge ECHO; + + First "mega-" is matched and echoed to the output. Then + "kludge" is matched, but the previous "mega-" is still + hanging around at the beginning of y̲y̲t̲e̲x̲t̲ so the E̲C̲H̲O̲ for + the "kludge" rule will actually write "mega-kludge". + + Two notes regarding use of 𝘆𝘆𝗺𝗼𝗿𝗲(): First, 𝘆𝘆𝗺𝗼𝗿𝗲() + depends on the value of y̲y̲l̲e̲n̲g̲ correctly reflecting the + size of the current token, so y̲y̲l̲e̲n̲g̲ must not be modified + when using 𝘆𝘆𝗺𝗼𝗿𝗲(). Second, the presence of 𝘆𝘆𝗺𝗼𝗿𝗲() in + the scanner's action entails a minor performance penalty in + the scanner's matching speed. + + yyless(n) + Returns all but the first n̲ characters of the current token + back to the input stream, where they will be rescanned when + the scanner looks for the next match. y̲y̲t̲e̲x̲t̲ and y̲y̲l̲e̲n̲g̲ + are adjusted appropriately (e.g., y̲y̲l̲e̲n̲g̲ will now be equal + to n̲). For example, on the input "foobar" the following + will write out "foobarbar": + + %% + foobar ECHO; yyless(3); + [a-z]+ ECHO; + + An argument of 0 to y̲y̲l̲e̲s̲s̲ will cause the entire current + input string to be scanned again. Unless how the scanner + will subsequently process its input has been changed (using + B̲E̲G̲I̲N̲, for example), this will result in an endless loop. + + Note that y̲y̲l̲e̲s̲s̲ is a macro and can only be used in the + 𝗳𝗹𝗲𝘅 input file, not from other source files. + + unput(c) + Puts the character c̲ back into the input stream. It will + be the next character scanned. The following action will + take the current token and cause it to be rescanned + enclosed in parentheses. + + { + int i; + char *yycopy; + + /* Copy yytext because unput() trashes yytext */ + if ((yycopy = strdup(yytext)) == NULL) + err(1, NULL); + unput(')'); + for (i = yyleng - 1; i >= 0; --i) + unput(yycopy[i]); + unput('('); + free(yycopy); + } + + Note that since each 𝘂𝗻𝗽𝘂𝘁() puts the given character back + at the beginning of the input stream, pushing back strings + must be done back-to-front. + + An important potential problem when using 𝘂𝗻𝗽𝘂𝘁() is that + if using “%pointer” (the default), a call to 𝘂𝗻𝗽𝘂𝘁() + destroys the contents of y̲y̲t̲e̲x̲t̲, starting with its right‐ + most character and devouring one character to the left with + each call. If the value of y̲y̲t̲e̲x̲t̲ should be preserved + after a call to 𝘂𝗻𝗽𝘂𝘁() (as in the above example), it must + either first be copied elsewhere, or the scanner must be + built using “%array” instead (see H̲O̲W̲ T̲H̲E̲ I̲N̲P̲U̲T̲ I̲S̲ + M̲A̲T̲C̲H̲E̲D̲). + + Finally, note that EOF cannot be put back to attempt to + mark the input stream with an end-of-file. + + input() + Reads the next character from the input stream. For exam‐ + ple, the following is one way to eat up C comments: + + %% + "/*" { + int c; + + for (;;) { + while ((c = input()) != '*' && c != EOF) + ; /* eat up text of comment */ + + if (c == '*') { + while ((c = input()) == '*') + ; + if (c == '/') + break; /* found the end */ + } + + if (c == EOF) { + errx(1, "EOF in comment"); + break; + } + } + } + + (Note that if the scanner is compiled using C++, then + 𝗶𝗻𝗽𝘂𝘁() is instead referred to as 𝘆𝘆𝗶𝗻𝗽𝘂𝘁(), in order to + avoid a name clash with the C++ stream by the name of + input.) + + YY_FLUSH_BUFFER + Flushes the scanner's internal buffer so that the next time + the scanner attempts to match a token, it will first refill + the buffer using YY_INPUT (see T̲H̲E̲ G̲E̲N̲E̲R̲A̲T̲E̲D̲ S̲C̲A̲N̲N̲E̲R̲, + below). This action is a special case of the more general + 𝘆𝘆_𝗳𝗹𝘂𝘀𝗵_𝗯𝘂𝗳𝗳𝗲𝗿() function, described below in the section + M̲U̲L̲T̲I̲P̲L̲E̲ I̲N̲P̲U̲T̲ B̲U̲F̲F̲E̲R̲S̲. + + yyterminate() + Can be used in lieu of a return statement in an action. It + terminates the scanner and returns a 0 to the scanner's + caller, indicating "all done". By default, 𝘆𝘆𝘁𝗲𝗿𝗺𝗶𝗻𝗮𝘁𝗲() + is also called when an end-of-file is encountered. It is a + macro and may be redefined. + +𝐓𝐇𝐄 𝐆𝐄𝐍𝐄𝐑𝐀𝐓𝐄𝐃 𝐒𝐂𝐀𝐍𝐍𝐄𝐑 + The output of 𝗳𝗹𝗲𝘅 is the file l̲e̲x̲.̲y̲y̲.̲c̲, which contains the scan‐ + ning routine 𝘆𝘆𝗹𝗲𝘅(), a number of tables used by it for matching + tokens, and a number of auxiliary routines and macros. By default, + 𝘆𝘆𝗹𝗲𝘅() is declared as follows: + + int yylex() + { + ... various definitions and the actions in here ... + } + + (If the environment supports function prototypes, then it will be + "int yylex(void)".) This definition may be changed by defining the + YY_DECL macro. For example: + + #define YY_DECL float lexscan(a, b) float a, b; + + would give the scanning routine the name l̲e̲x̲s̲c̲a̲n̲, returning a + float, and taking two floats as arguments. Note that if arguments + are given to the scanning routine using a K&R-style/non-prototyped + function declaration, the definition must be terminated with a + semi-colon (‘;’). + + Whenever 𝘆𝘆𝗹𝗲𝘅() is called, it scans tokens from the global input + file y̲y̲i̲n̲ (which defaults to stdin). It continues until it either + reaches an end-of-file (at which point it returns the value 0) or + one of its actions executes a r̲e̲t̲u̲r̲n̲ statement. + + If the scanner reaches an end-of-file, subsequent calls are unde‐ + fined unless either y̲y̲i̲n̲ is pointed at a new input file (in which + case scanning continues from that file), or 𝘆𝘆𝗿𝗲𝘀𝘁𝗮𝗿𝘁() is called. + 𝘆𝘆𝗿𝗲𝘀𝘁𝗮𝗿𝘁() takes one argument, a F̲I̲L̲E̲ *̲ pointer (which can be nil, + if YY_INPUT has been set up to scan from a source other than y̲y̲i̲n̲), + and initializes y̲y̲i̲n̲ for scanning from that file. Essentially + there is no difference between just assigning y̲y̲i̲n̲ to a new input + file or using 𝘆𝘆𝗿𝗲𝘀𝘁𝗮𝗿𝘁() to do so; the latter is available for + compatibility with previous versions of 𝗳𝗹𝗲𝘅, and because it can be + used to switch input files in the middle of scanning. It can also + be used to throw away the current input buffer, by calling it with + an argument of y̲y̲i̲n̲; but better is to use YY_FLUSH_BUFFER (see + above). Note that 𝘆𝘆𝗿𝗲𝘀𝘁𝗮𝗿𝘁() does not reset the start condition + to I̲N̲I̲T̲I̲A̲L̲ (see S̲T̲A̲R̲T̲ C̲O̲N̲D̲I̲T̲I̲O̲N̲S̲, below). + + If 𝘆𝘆𝗹𝗲𝘅() stops scanning due to executing a r̲e̲t̲u̲r̲n̲ statement in + one of the actions, the scanner may then be called again and it + will resume scanning where it left off. + + By default (and for purposes of efficiency), the scanner uses + block-reads rather than simple getc(3) calls to read characters + from y̲y̲i̲n̲. The nature of how it gets its input can be controlled + by defining the YY_INPUT macro. YY_INPUT's calling sequence is + "YY_INPUT(buf,result,max_size)". Its action is to place up to + max_size characters in the character array b̲u̲f̲ and return in the + integer variable r̲e̲s̲u̲l̲t̲ either the number of characters read or the + constant YY_NULL (0 on UNIX systems) to indicate EOF. The default + YY_INPUT reads from the global file-pointer "yyin". + + A sample definition of YY_INPUT (in the definitions section of the + input file): + + %{ + #define YY_INPUT(buf,result,max_size) \ + { \ + int c = getchar(); \ + result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \ + } + %} + + This definition will change the input processing to occur one char‐ + acter at a time. + + When the scanner receives an end-of-file indication from YY_INPUT, + it then checks the 𝘆𝘆𝘄𝗿𝗮𝗽() function. If 𝘆𝘆𝘄𝗿𝗮𝗽() returns false + (zero), then it is assumed that the function has gone ahead and set + up y̲y̲i̲n̲ to point to another input file, and scanning continues. If + it returns true (non-zero), then the scanner terminates, returning + 0 to its caller. Note that in either case, the start condition + remains unchanged; it does not revert to I̲N̲I̲T̲I̲A̲L̲. + + If you do not supply your own version of 𝘆𝘆𝘄𝗿𝗮𝗽(), then you must + either use “%option noyywrap” (in which case the scanner behaves as + though 𝘆𝘆𝘄𝗿𝗮𝗽() returned 1), or you must link with -𝗹𝗳𝗹 to obtain + the default version of the routine, which always returns 1. + + Three routines are available for scanning from in-memory buffers + rather than files: 𝘆𝘆_𝘀𝗰𝗮𝗻_𝘀𝘁𝗿𝗶𝗻𝗴(), 𝘆𝘆_𝘀𝗰𝗮𝗻_𝗯𝘆𝘁𝗲𝘀(), and + 𝘆𝘆_𝘀𝗰𝗮𝗻_𝗯𝘂𝗳𝗳𝗲𝗿(). See the discussion of them below in the section + M̲U̲L̲T̲I̲P̲L̲E̲ I̲N̲P̲U̲T̲ B̲U̲F̲F̲E̲R̲S̲. + + The scanner writes its E̲C̲H̲O̲ output to the y̲y̲o̲u̲t̲ global (default, + stdout), which may be redefined by the user simply by assigning it + to some other F̲I̲L̲E̲ pointer. + +𝐒𝐓𝐀𝐑𝐓 𝐂𝐎𝐍𝐃𝐈𝐓𝐈𝐎𝐍𝐒 + 𝗳𝗹𝗲𝘅 provides a mechanism for conditionally activating rules. Any + rule whose pattern is prefixed with "⟨sc⟩" will only be active when + the scanner is in the start condition named "sc". For example, + + [^"]* { /* eat up the string body ... */ + ... + } + + will be active only when the scanner is in the "STRING" start con‐ + dition, and + + \. { /* handle an escape ... */ + ... + } + + will be active only when the current start condition is either + "INITIAL", "STRING", or "QUOTE". + + Start conditions are declared in the definitions (first) section of + the input using unindented lines beginning with either ‘%s’ or ‘%x’ + followed by a list of names. The former declares i̲n̲c̲l̲u̲s̲i̲v̲e̲ start + conditions, the latter e̲x̲c̲l̲u̲s̲i̲v̲e̲ start conditions. A start condi‐ + tion is activated using the B̲E̲G̲I̲N̲ action. Until the next B̲E̲G̲I̲N̲ + action is executed, rules with the given start condition will be + active and rules with other start conditions will be inactive. If + the start condition is inclusive, then rules with no start condi‐ + tions at all will also be active. If it is exclusive, then only + rules qualified with the start condition will be active. A set of + rules contingent on the same exclusive start condition describe a + scanner which is independent of any of the other rules in the 𝗳𝗹𝗲𝘅 + input. Because of this, exclusive start conditions make it easy to + specify "mini-scanners" which scan portions of the input that are + syntactically different from the rest (e.g., comments). + + If the distinction between inclusive and exclusive start conditions + is still a little vague, here's a simple example illustrating the + connection between the two. The set of rules: + + %s example + %% + + foo do_something(); + + bar something_else(); + + is equivalent to + + %x example + %% + + foo do_something(); + + bar something_else(); + + Without the ⟨INITIAL,example⟩ qualifier, the “bar” pattern in the + second example wouldn't be active (i.e., couldn't match) when in + start condition “example”. If we just used ⟨example⟩ to qualify + “bar”, though, then it would only be active in “example” and not in + I̲N̲I̲T̲I̲A̲L̲, while in the first example it's active in both, because in + the first example the “example” start condition is an inclusive + (‘%s’) start condition. + + Also note that the special start-condition specifier ‘⟨*⟩’ matches + every start condition. Thus, the above example could also have + been written: + + %x example + %% + + foo do_something(); + + <*>bar something_else(); + + The default rule (to E̲C̲H̲O̲ any unmatched character) remains active + in start conditions. It is equivalent to: + + <*>.|\n ECHO; + + “BEGIN(0)” returns to the original state where only the rules with + no start conditions are active. This state can also be referred to + as the start-condition I̲N̲I̲T̲I̲A̲L̲, so “BEGIN(INITIAL)” is equivalent + to “BEGIN(0)”. (The parentheses around the start condition name + are not required but are considered good style.) + + B̲E̲G̲I̲N̲ actions can also be given as indented code at the beginning + of the rules section. For example, the following will cause the + scanner to enter the "SPECIAL" start condition whenever 𝘆𝘆𝗹𝗲𝘅() is + called and the global variable e̲n̲t̲e̲r̲_s̲p̲e̲c̲i̲a̲l̲ is true: + + int enter_special; + + %x SPECIAL + %% + if (enter_special) + BEGIN(SPECIAL); + + blahblahblah + ...more rules follow... + + To illustrate the uses of start conditions, here is a scanner which + provides two different interpretations of a string like "123.456". + By default it will treat it as three tokens: the integer "123", a + dot (‘.’), and the integer "456". But if the string is preceded + earlier in the line by the string "expect-floats" it will treat it + as a single token, the floating-point number 123.456: + + %{ + #include + %} + %s expect + + %% + expect-floats BEGIN(expect); + + [0-9]+"."[0-9]+ { + printf("found a float, = %f\n", + atof(yytext)); + } + \n { + /* + * That's the end of the line, so + * we need another "expect-number" + * before we'll recognize any more + * numbers. + */ + BEGIN(INITIAL); + } + + [0-9]+ { + printf("found an integer, = %d\n", + atoi(yytext)); + } + + "." printf("found a dot\n"); + + Here is a scanner which recognizes (and discards) C comments while + maintaining a count of the current input line: + + %x comment + %% + int line_num = 1; + + "/*" BEGIN(comment); + + [^*\n]* /* eat anything that's not a '*' */ + "*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ + \n ++line_num; + "*"+"/" BEGIN(INITIAL); + + This scanner goes to a bit of trouble to match as much text as pos‐ + sible with each rule. In general, when attempting to write a high- + speed scanner try to match as much as possible in each rule, as + it's a big win. + + Note that start-condition names are really integer values and can + be stored as such. Thus, the above could be extended in the fol‐ + lowing fashion: + + %x comment foo + %% + int line_num = 1; + int comment_caller; + + "/*" { + comment_caller = INITIAL; + BEGIN(comment); + } + + ... + + "/*" { + comment_caller = foo; + BEGIN(comment); + } + + [^*\n]* /* eat anything that's not a '*' */ + "*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ + \n ++line_num; + "*"+"/" BEGIN(comment_caller); + + Furthermore, the current start condition can be accessed by using + the integer-valued YY_START macro. For example, the above assign‐ + ments to c̲o̲m̲m̲e̲n̲t̲_c̲a̲l̲l̲e̲r̲ could instead be written + + comment_caller = YY_START; + + Flex provides YYSTATE as an alias for YY_START (since that is + what's used by AT&T UNIX 𝗹𝗲𝘅). + + Note that start conditions do not have their own name-space; %s's + and %x's declare names in the same fashion as #define's. + + Finally, here's an example of how to match C-style quoted strings + using exclusive start conditions, including expanded escape + sequences (but not including checking for a string that's too + long): + + %x str + + %% + #define MAX_STR_CONST 1024 + char string_buf[MAX_STR_CONST]; + char *string_buf_ptr; + + \" string_buf_ptr = string_buf; BEGIN(str); + + \" { /* saw closing quote - all done */ + BEGIN(INITIAL); + *string_buf_ptr = '\0'; + /* + * return string constant token type and + * value to parser + */ + } + + \n { + /* error - unterminated string constant */ + /* generate error message */ + } + + \\[0-7]{1,3} { + /* octal escape sequence */ + int result; + + (void) sscanf(yytext + 1, "%o", &result); + + if (result > 0xff) { + /* error, constant is out-of-bounds */ + } else + *string_buf_ptr++ = result; + } + + \\[0-9]+ { + /* + * generate error - bad escape sequence; something + * like '\48' or '\0777777' + */ + } + + \\n *string_buf_ptr++ = '\n'; + \\t *string_buf_ptr++ = '\t'; + \\r *string_buf_ptr++ = '\r'; + \\b *string_buf_ptr++ = '\b'; + \\f *string_buf_ptr++ = '\f'; + + \\(.|\n) *string_buf_ptr++ = yytext[1]; + + [^\\\n\"]+ { + char *yptr = yytext; + + while (*yptr) + *string_buf_ptr++ = *yptr++; + } + + Often, such as in some of the examples above, a whole bunch of + rules are all preceded by the same start condition(s). 𝗳𝗹𝗲𝘅 makes + this a little easier and cleaner by introducing a notion of start + condition s̲c̲o̲p̲e̲. A start condition scope is begun with: + + { + + where “SCs” is a list of one or more start conditions. Inside the + start condition scope, every rule automatically has the prefix + ⟨SCs⟩ applied to it, until a ‘}’ which matches the initial ‘{’. + So, for example, + + { + "\\n" return '\n'; + "\\r" return '\r'; + "\\f" return '\f'; + "\\0" return '\0'; + } + + is equivalent to: + + "\\n" return '\n'; + "\\r" return '\r'; + "\\f" return '\f'; + "\\0" return '\0'; + + Start condition scopes may be nested. + + Three routines are available for manipulating stacks of start con‐ + ditions: + + void yy_push_state(int new_state) + Pushes the current start condition onto the top of the + start condition stack and switches to n̲e̲w̲_s̲t̲a̲t̲e̲ as though + “BEGIN new_state” had been used (recall that start + condition names are also integers). + + void yy_pop_state() + Pops the top of the stack and switches to it via B̲E̲G̲I̲N̲. + + int yy_top_state() + Returns the top of the stack without altering the stack's + contents. + + The start condition stack grows dynamically and so has no built-in + size limitation. If memory is exhausted, program execution aborts. + + To use start condition stacks, scanners must include a “%option + stack” directive (see O̲P̲T̲I̲O̲N̲S̲ below). + +𝐌𝐔𝐋𝐓𝐈𝐏𝐋𝐄 𝐈𝐍𝐏𝐔𝐓 𝐁𝐔𝐅𝐅𝐄𝐑𝐒 + Some scanners (such as those which support "include" files) require + reading from several input streams. As 𝗳𝗹𝗲𝘅 scanners do a large + amount of buffering, one cannot control where the next input will + be read from by simply writing a YY_INPUT which is sensitive to the + scanning context. YY_INPUT is only called when the scanner reaches + the end of its buffer, which may be a long time after scanning a + statement such as an "include" which requires switching the input + source. + + To negotiate these sorts of problems, 𝗳𝗹𝗲𝘅 provides a mechanism for + creating and switching between multiple input buffers. An input + buffer is created by using: + + YY_BUFFER_STATE yy_create_buffer(FILE *file, int size) + + which takes a F̲I̲L̲E̲ pointer and a s̲i̲z̲e̲ and creates a buffer associ‐ + ated with the given file and large enough to hold s̲i̲z̲e̲ characters + (when in doubt, use YY_BUF_SIZE for the size). It returns a + YY_BUFFER_STATE handle, which may then be passed to other routines + (see below). The YY_BUFFER_STATE type is a pointer to an opaque + “struct yy_buffer_state” structure, so YY_BUFFER_STATE variables + may be safely initialized to “((YY_BUFFER_STATE) 0)” if desired, + and the opaque structure can also be referred to in order to cor‐ + rectly declare input buffers in source files other than that of + scanners. Note that the F̲I̲L̲E̲ pointer in the call to + 𝘆𝘆_𝗰𝗿𝗲𝗮𝘁𝗲_𝗯𝘂𝗳𝗳𝗲𝗿() is only used as the value of y̲y̲i̲n̲ seen by + YY_INPUT; if YY_INPUT is redefined so that it no longer uses y̲y̲i̲n̲, + then a nil F̲I̲L̲E̲ pointer can safely be passed to 𝘆𝘆_𝗰𝗿𝗲𝗮𝘁𝗲_𝗯𝘂𝗳𝗳𝗲𝗿(). + To select a particular buffer to scan: + + void yy_switch_to_buffer(YY_BUFFER_STATE new_buffer) + + It switches the scanner's input buffer so subsequent tokens will + come from n̲e̲w̲_b̲u̲f̲f̲e̲r̲. Note that 𝘆𝘆_𝘀𝘄𝗶𝘁𝗰𝗵_𝘁𝗼_𝗯𝘂𝗳𝗳𝗲𝗿() may be used + by 𝘆𝘆𝘄𝗿𝗮𝗽() to set things up for continued scanning, instead of + opening a new file and pointing y̲y̲i̲n̲ at it. Note also that switch‐ + ing input sources via either 𝘆𝘆_𝘀𝘄𝗶𝘁𝗰𝗵_𝘁𝗼_𝗯𝘂𝗳𝗳𝗲𝗿() or 𝘆𝘆𝘄𝗿𝗮𝗽() does + not change the start condition. + + void yy_delete_buffer(YY_BUFFER_STATE buffer) + + is used to reclaim the storage associated with a buffer. (b̲u̲f̲f̲e̲r̲ + can be nil, in which case the routine does nothing.) To clear the + current contents of a buffer: + + void yy_flush_buffer(YY_BUFFER_STATE buffer) + + This function discards the buffer's contents, so the next time the + scanner attempts to match a token from the buffer, it will first + fill the buffer anew using YY_INPUT. + + 𝘆𝘆_𝗻𝗲𝘄_𝗯𝘂𝗳𝗳𝗲𝗿() is an alias for 𝘆𝘆_𝗰𝗿𝗲𝗮𝘁𝗲_𝗯𝘂𝗳𝗳𝗲𝗿(), provided for + compatibility with the C++ use of n̲e̲w̲ and d̲e̲l̲e̲t̲e̲ for creating and + destroying dynamic objects. + + Finally, the YY_CURRENT_BUFFER macro returns a YY_BUFFER_STATE han‐ + dle to the current buffer. + + Here is an example of using these features for writing a scanner + which expands include files (the ⟨⟨EOF⟩⟩ feature is discussed + below): + + /* + * the "incl" state is used for picking up the name + * of an include file + */ + %x incl + + %{ + #define MAX_INCLUDE_DEPTH 10 + YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; + int include_stack_ptr = 0; + %} + + %% + include BEGIN(incl); + + [a-z]+ ECHO; + [^a-z\n]*\n? ECHO; + + [ \t]* /* eat the whitespace */ + [^ \t\n]+ { /* got the include file name */ + if (include_stack_ptr >= MAX_INCLUDE_DEPTH) + errx(1, "Includes nested too deeply"); + + include_stack[include_stack_ptr++] = + YY_CURRENT_BUFFER; + + yyin = fopen(yytext, "r"); + + if (yyin == NULL) + err(1, NULL); + + yy_switch_to_buffer( + yy_create_buffer(yyin, YY_BUF_SIZE)); + + BEGIN(INITIAL); + } + + <> { + if (--include_stack_ptr < 0) + yyterminate(); + else { + yy_delete_buffer(YY_CURRENT_BUFFER); + yy_switch_to_buffer( + include_stack[include_stack_ptr]); + } + } + + Three routines are available for setting up input buffers for scan‐ + ning in-memory strings instead of files. All of them create a new + input buffer for scanning the string, and return a corresponding + YY_BUFFER_STATE handle (which should be deleted afterwards using + 𝘆𝘆_𝗱𝗲𝗹𝗲𝘁𝗲_𝗯𝘂𝗳𝗳𝗲𝗿()). They also switch to the new buffer using + 𝘆𝘆_𝘀𝘄𝗶𝘁𝗰𝗵_𝘁𝗼_𝗯𝘂𝗳𝗳𝗲𝗿(), so the next call to 𝘆𝘆𝗹𝗲𝘅() will start scan‐ + ning the string. + + yy_scan_string(const char *str) + Scans a NUL-terminated string. + + yy_scan_bytes(const char *bytes, int len) + Scans l̲e̲n̲ bytes (including possibly NUL's) starting at + location b̲y̲t̲e̲s̲. + + Note that both of these functions create and scan a copy of the + string or bytes. (This may be desirable, since 𝘆𝘆𝗹𝗲𝘅() modifies + the contents of the buffer it is scanning.) The copy can be + avoided by using: + + yy_scan_buffer(char *base, yy_size_t size) + Which scans the buffer starting at b̲a̲s̲e̲, consisting of s̲i̲z̲e̲ + bytes, the last two bytes of which must be + YY_END_OF_BUFFER_CHAR (ASCII NUL). These last two bytes + are not scanned; thus, scanning consists of base[0] through + base[size-2], inclusive. + + If b̲a̲s̲e̲ is not set up in this manner (i.e., forget the + final two YY_END_OF_BUFFER_CHAR bytes), then + 𝘆𝘆_𝘀𝗰𝗮𝗻_𝗯𝘂𝗳𝗳𝗲𝗿() returns a nil pointer instead of creating + a new input buffer. + + The type y̲y̲_s̲i̲z̲e̲_t̲ is an integral type which can be cast to + an integer expression reflecting the size of the buffer. + +𝐄𝐍𝐃-𝐎𝐅-𝐅𝐈𝐋𝐄 𝐑𝐔𝐋𝐄𝐒 + The special rule "⟨⟨EOF⟩⟩" indicates actions which are to be taken + when an end-of-file is encountered and 𝘆𝘆𝘄𝗿𝗮𝗽() returns non-zero + (i.e., indicates no further files to process). The action must + finish by doing one of four things: + + - Assigning y̲y̲i̲n̲ to a new input file (in previous versions of + 𝗳𝗹𝗲𝘅, after doing the assignment, it was necessary to call the + special action YY_NEW_FILE; this is no longer necessary). + + - Executing a r̲e̲t̲u̲r̲n̲ statement. + + - Executing the special 𝘆𝘆𝘁𝗲𝗿𝗺𝗶𝗻𝗮𝘁𝗲() action. + + - Switching to a new buffer using 𝘆𝘆_𝘀𝘄𝗶𝘁𝗰𝗵_𝘁𝗼_𝗯𝘂𝗳𝗳𝗲𝗿() as shown + in the example above. + + ⟨⟨EOF⟩⟩ rules may not be used with other patterns; they may only be + qualified with a list of start conditions. If an unqualified + ⟨⟨EOF⟩⟩ rule is given, it applies to all start conditions which do + not already have ⟨⟨EOF⟩⟩ actions. To specify an ⟨⟨EOF⟩⟩ rule for + only the initial start condition, use + + <> + + These rules are useful for catching things like unclosed comments. + An example: + + %x quote + %% + + ...other rules for dealing with quotes... + + <> { + error("unterminated quote"); + yyterminate(); + } + <> { + if (*++filelist) + yyin = fopen(*filelist, "r"); + else + yyterminate(); + } + +𝐌𝐈𝐒𝐂𝐄𝐋𝐋𝐀𝐍𝐄𝐎𝐔𝐒 𝐌𝐀𝐂𝐑𝐎𝐒 + The macro YY_USER_ACTION can be defined to provide an action which + is always executed prior to the matched rule's action. For exam‐ + ple, it could be #define'd to call a routine to convert yytext to + lower-case. When YY_USER_ACTION is invoked, the variable y̲y̲_a̲c̲t̲ + gives the number of the matched rule (rules are numbered starting + with 1). For example, to profile how often each rule is matched, + the following would do the trick: + + #define YY_USER_ACTION ++ctr[yy_act] + + where c̲t̲r̲ is an array to hold the counts for the different rules. + Note that the macro YY_NUM_RULES gives the total number of rules + (including the default rule, even if -𝘀 is used), so a correct dec‐ + laration for c̲t̲r̲ is: + + int ctr[YY_NUM_RULES]; + + The macro YY_USER_INIT may be defined to provide an action which is + always executed before the first scan (and before the scanner's + internal initializations are done). For example, it could be used + to call a routine to read in a data table or open a logging file. + + The macro yy_set_interactive(is_interactive) can be used to control + whether the current buffer is considered i̲n̲t̲e̲r̲a̲c̲t̲i̲v̲e̲. An interac‐ + tive buffer is processed more slowly, but must be used when the + scanner's input source is indeed interactive to avoid problems due + to waiting to fill buffers (see the discussion of the -𝐈 flag + below). A non-zero value in the macro invocation marks the buffer + as interactive, a zero value as non-interactive. Note that use of + this macro overrides “%option always-interactive” or “%option + never-interactive” (see O̲P̲T̲I̲O̲N̲S̲ below). 𝘆𝘆_𝘀𝗲𝘁_𝗶𝗻𝘁𝗲𝗿𝗮𝗰𝘁𝗶𝘃𝗲() must + be invoked prior to beginning to scan the buffer that is (or is + not) to be considered interactive. + + The macro yy_set_bol(at_bol) can be used to control whether the + current buffer's scanning context for the next token match is done + as though at the beginning of a line. A non-zero macro argument + makes rules anchored with ‘^’ active, while a zero argument makes + ‘^’ rules inactive. + + The macro YY_AT_BOL returns true if the next token scanned from the + current buffer will have ‘^’ rules active, false otherwise. + + In the generated scanner, the actions are all gathered in one large + switch statement and separated using YY_BREAK, which may be rede‐ + fined. By default, it is simply a "break", to separate each rule's + action from the following rules. Redefining YY_BREAK allows, for + example, C++ users to “#define YY_BREAK” to do nothing (while being + very careful that every rule ends with a "break" or a "return"!) + to avoid suffering from unreachable statement warnings where + because a rule's action ends with “return”, the YY_BREAK is inac‐ + cessible. + +𝐕𝐀𝐋𝐔𝐄𝐒 𝐀𝐕𝐀𝐈𝐋𝐀𝐁𝐋𝐄 𝐓𝐎 𝐓𝐇𝐄 𝐔𝐒𝐄𝐑 + This section summarizes the various values available to the user in + the rule actions. + + char *yytext + Holds the text of the current token. It may be modified + but not lengthened (characters cannot be appended to the + end). + + If the special directive “%array” appears in the first sec‐ + tion of the scanner description, then y̲y̲t̲e̲x̲t̲ is instead + declared “char yytext[YYLMAX]”, where YYLMAX is a macro + definition that can be redefined in the first section to + change the default value (generally 8KB). Using “%array” + results in somewhat slower scanners, but the value of + y̲y̲t̲e̲x̲t̲ becomes immune to calls to 𝗶𝗻𝗽𝘂𝘁() and 𝘂𝗻𝗽𝘂𝘁(), + which potentially destroy its value when y̲y̲t̲e̲x̲t̲ is a char‐ + acter pointer. The opposite of “%array” is “%pointer”, + which is the default. + + “%array” cannot be used when generating C++ scanner classes + (the -+ flag). + + int yyleng + Holds the length of the current token. + + FILE *yyin + Is the file which by default 𝗳𝗹𝗲𝘅 reads from. It may be + redefined, but doing so only makes sense before scanning + begins or after an EOF has been encountered. Changing it + in the midst of scanning will have unexpected results since + 𝗳𝗹𝗲𝘅 buffers its input; use 𝘆𝘆𝗿𝗲𝘀𝘁𝗮𝗿𝘁() instead. Once + scanning terminates because an end-of-file has been seen, + y̲y̲i̲n̲ can be assigned as the new input file and the scanner + can be called again to continue scanning. + + void yyrestart(FILE *new_file) + May be called to point y̲y̲i̲n̲ at the new input file. The + switch-over to the new file is immediate (any previously + buffered-up input is lost). Note that calling 𝘆𝘆𝗿𝗲𝘀𝘁𝗮𝗿𝘁() + with y̲y̲i̲n̲ as an argument thus throws away the current input + buffer and continues scanning the same input file. + + FILE *yyout + Is the file to which E̲C̲H̲O̲ actions are done. It can be + reassigned by the user. + + YY_CURRENT_BUFFER + Returns a YY_BUFFER_STATE handle to the current buffer. + + YY_START + Returns an integer value corresponding to the current start + condition. This value can subsequently be used with B̲E̲G̲I̲N̲ + to return to that start condition. + +𝐈𝐍𝐓𝐄𝐑𝐅𝐀𝐂𝐈𝐍𝐆 𝐖𝐈𝐓𝐇 𝐘𝐀𝐂𝐂 + One of the main uses of 𝗳𝗹𝗲𝘅 is as a companion to the yacc(1) + parser-generator. yacc parsers expect to call a routine named + 𝘆𝘆𝗹𝗲𝘅() to find the next input token. The routine is supposed to + return the type of the next token as well as putting any associated + value in the global y̲y̲l̲v̲a̲l̲, which is defined externally, and can be + a union or any other complex data structure. To use 𝗳𝗹𝗲𝘅 with + yacc, one specifies the -𝗱 option to yacc to instruct it to gener‐ + ate the file y̲.̲t̲a̲b̲.̲h̲ containing definitions of all the “%tokens” + appearing in the yacc input. This file is then included in the + 𝗳𝗹𝗲𝘅 scanner. For example, if one of the tokens is "TOK_NUMBER", + part of the scanner might look like: + + %{ + #include "y.tab.h" + %} + + %% + + [0-9]+ yylval = atoi(yytext); return TOK_NUMBER; + +𝐎𝐏𝐓𝐈𝐎𝐍𝐒 + 𝗳𝗹𝗲𝘅 has the following options: + + -𝟳 Instructs 𝗳𝗹𝗲𝘅 to generate a 7-bit scanner, i.e., one which + can only recognize 7-bit characters in its input. The + advantage of using -𝟳 is that the scanner's tables can be + up to half the size of those generated using the -𝟴 option + (see below). The disadvantage is that such scanners often + hang or crash if their input contains an 8-bit character. + + Note, however, that unless generating a scanner using the + -𝐂𝗳 or -𝐂𝐅 table compression options, use of -𝟳 will save + only a small amount of table space, and make the scanner + considerably less portable. 𝗳𝗹𝗲𝘅's default behavior is to + generate an 8-bit scanner unless -𝐂𝗳 or -𝐂𝐅 is specified, + in which case 𝗳𝗹𝗲𝘅 defaults to generating 7-bit scanners + unless it was configured to generate 8-bit scanners (as + will often be the case with non-USA sites). It is possible + tell whether 𝗳𝗹𝗲𝘅 generated a 7-bit or an 8-bit scanner by + inspecting the flag summary in the -𝘃 output as described + below. + + Note that if -𝐂𝗳𝗲 or -𝐂𝐅𝗲 are used (the table compression + options, but also using equivalence classes as discussed + below), 𝗳𝗹𝗲𝘅 still defaults to generating an 8-bit scanner, + since usually with these compression options full 8-bit + tables are not much more expensive than 7-bit tables. + + -𝟴 Instructs 𝗳𝗹𝗲𝘅 to generate an 8-bit scanner, i.e., one + which can recognize 8-bit characters. This flag is only + needed for scanners generated using -𝐂𝗳 or -𝐂𝐅, as other‐ + wise 𝗳𝗹𝗲𝘅 defaults to generating an 8-bit scanner anyway. + + See the discussion of -𝟳 above for 𝗳𝗹𝗲𝘅's default behavior + and the tradeoffs between 7-bit and 8-bit scanners. + + -𝐁 Instructs 𝗳𝗹𝗲𝘅 to generate a b̲a̲t̲c̲h̲ scanner, the opposite of + i̲n̲t̲e̲r̲a̲c̲t̲i̲v̲e̲ scanners generated by -𝐈 (see below). In gen‐ + eral, -𝐁 is used when the scanner will never be used inter‐ + actively, and you want to squeeze a little more performance + out of it. If the aim is instead to squeeze out a lot more + performance, use the -𝐂𝗳 or -𝐂𝐅 options (discussed below), + which turn on -𝐁 automatically anyway. + + -𝗯 Generate backing-up information to l̲e̲x̲.̲b̲a̲c̲k̲u̲p̲. This is a + list of scanner states which require backing up and the + input characters on which they do so. By adding rules one + can remove backing-up states. If all backing-up states are + eliminated and -𝐂𝗳 or -𝐂𝐅 is used, the generated scanner + will run faster (see the -𝗽 flag). Only users who wish to + squeeze every last cycle out of their scanners need worry + about this option. (See the section on P̲E̲R̲F̲O̲R̲M̲A̲N̲C̲E̲ + C̲O̲N̲S̲I̲D̲E̲R̲A̲T̲I̲O̲N̲S̲ below.) + + -𝐂[𝗮𝗲𝐅𝗳𝗺𝗿] + Controls the degree of table compression and, more gener‐ + ally, trade-offs between small scanners and fast scanners. + + -𝐂𝗮 Instructs 𝗳𝗹𝗲𝘅 to trade off larger tables in the + generated scanner for faster performance because + the elements of the tables are better aligned for + memory access and computation. On some RISC archi‐ + tectures, fetching and manipulating longwords is + more efficient than with smaller-sized units such + as shortwords. This option can double the size of + the tables used by the scanner. + + -𝐂𝗲 Directs 𝗳𝗹𝗲𝘅 to construct e̲q̲u̲i̲v̲a̲l̲e̲n̲c̲e̲ c̲l̲a̲s̲s̲e̲s̲, + i.e., sets of characters which have identical lexi‐ + cal properties (for example, if the only appearance + of digits in the 𝗳𝗹𝗲𝘅 input is in the character + class "[0-9]" then the digits ‘0’, ‘1’, ‘...’, ‘9’ + will all be put in the same equivalence class). + Equivalence classes usually give dramatic reduc‐ + tions in the final table/object file sizes + (typically a factor of 2-5) and are pretty cheap + performance-wise (one array look-up per character + scanned). + + -𝐂𝐅 Specifies that the alternate fast scanner represen‐ + tation (described below under the -𝐅 option) should + be used. This option cannot be used with -+. + + -𝐂𝗳 Specifies that the f̲u̲l̲l̲ scanner tables should be + generated - 𝗳𝗹𝗲𝘅 should not compress the tables by + taking advantage of similar transition functions + for different states. + + -𝐂𝗺 Directs 𝗳𝗹𝗲𝘅 to construct m̲e̲t̲a̲-̲e̲q̲u̲i̲v̲a̲l̲e̲n̲c̲e̲ c̲l̲a̲s̲s̲e̲s̲, + which are sets of equivalence classes (or charac‐ + ters, if equivalence classes are not being used) + that are commonly used together. Meta-equivalence + classes are often a big win when using compressed + tables, but they have a moderate performance impact + (one or two "if" tests and one array look-up per + character scanned). + + -𝐂𝗿 Causes the generated scanner to b̲y̲p̲a̲s̲s̲ use of the + standard I/O library (stdio) for input. Instead of + calling fread(3) or getc(3), the scanner will use + the read(2) system call, resulting in a performance + gain which varies from system to system, but in + general is probably negligible unless -𝐂𝗳 or -𝐂𝐅 + are being used. Using -𝐂𝗿 can cause strange behav‐ + ior if, for example, reading from y̲y̲i̲n̲ using stdio + prior to calling the scanner (because the scanner + will miss whatever text previous reads left in the + stdio input buffer). + + -𝐂𝗿 has no effect if YY_INPUT is defined (see T̲H̲E̲ + G̲E̲N̲E̲R̲A̲T̲E̲D̲ S̲C̲A̲N̲N̲E̲R̲ above). + + A lone -𝐂 specifies that the scanner tables should be com‐ + pressed but neither equivalence classes nor meta-equiva‐ + lence classes should be used. + + The options -𝐂𝗳 or -𝐂𝐅 and -𝐂𝗺 do not make sense together - + there is no opportunity for meta-equivalence classes if the + table is not being compressed. Otherwise the options may + be freely mixed, and are cumulative. + + The default setting is -𝐂𝗲𝗺 which specifies that 𝗳𝗹𝗲𝘅 + should generate equivalence classes and meta-equivalence + classes. This setting provides the highest degree of table + compression. It is possible to trade off faster-executing + scanners at the cost of larger tables with the following + generally being true: + + slowest & smallest + -Cem + -Cm + -Ce + -C + -C{f,F}e + -C{f,F} + -C{f,F}a + fastest & largest + + Note that scanners with the smallest tables are usually + generated and compiled the quickest, so during development + the default is usually best, maximal compression. + + -𝐂𝗳𝗲 is often a good compromise between speed and size for + production scanners. + + -𝗱 Makes the generated scanner run in debug mode. Whenever a + pattern is recognized and the global y̲y̲_f̲l̲e̲x̲_d̲e̲b̲u̲g̲ is non- + zero (which is the default), the scanner will write to + stderr a line of the form: + + --accepting rule at line 53 ("the matched text") + + The line number refers to the location of the rule in the + file defining the scanner (i.e., the file that was fed to + 𝗳𝗹𝗲𝘅). Messages are also generated when the scanner backs + up, accepts the default rule, reaches the end of its input + buffer (or encounters a NUL; at this point, the two look + the same as far as the scanner's concerned), or reaches an + end-of-file. + + -𝐅 Specifies that the fast scanner table representation should + be used (and stdio bypassed). This representation is about + as fast as the full table representation (-𝗳), and for some + sets of patterns will be considerably smaller (and for + others, larger). In general, if the pattern set contains + both "keywords" and a catch-all, "identifier" rule, such as + in the set: + + "case" return TOK_CASE; + "switch" return TOK_SWITCH; + ... + "default" return TOK_DEFAULT; + [a-z]+ return TOK_ID; + + then it's better to use the full table representation. If + only the "identifier" rule is present and a hash table or + some such is used to detect the keywords, it's better to + use -𝐅. + + This option is equivalent to -𝐂𝐅𝗿 (see above). It cannot + be used with -+. + + -𝗳 Specifies f̲a̲s̲t̲ s̲c̲a̲n̲n̲e̲r̲. No table compression is done and + stdio is bypassed. The result is large but fast. This + option is equivalent to -𝐂𝗳𝗿 (see above). + + -𝗵 Generates a help summary of 𝗳𝗹𝗲𝘅's options to stdout and + then exits. -? and --𝗵𝗲𝗹𝗽 are synonyms for -𝗵. + + -𝐈 Instructs 𝗳𝗹𝗲𝘅 to generate an i̲n̲t̲e̲r̲a̲c̲t̲i̲v̲e̲ scanner. An + interactive scanner is one that only looks ahead to decide + what token has been matched if it absolutely must. It + turns out that always looking one extra character ahead, + even if the scanner has already seen enough text to disam‐ + biguate the current token, is a bit faster than only look‐ + ing ahead when necessary. But scanners that always look + ahead give dreadful interactive performance; for example, + when a user types a newline, it is not recognized as a new‐ + line token until they enter a̲n̲o̲t̲h̲e̲r̲ token, which often + means typing in another whole line. + + 𝗳𝗹𝗲𝘅 scanners default to i̲n̲t̲e̲r̲a̲c̲t̲i̲v̲e̲ unless -𝐂𝗳 or -𝐂𝐅 ta‐ + ble-compression options are specified (see above). That's + because if high-performance is most important, one of these + options should be used, so if they weren't, 𝗳𝗹𝗲𝘅 assumes it + is preferable to trade off a bit of run-time performance + for intuitive interactive behavior. Note also that -𝐈 can‐ + not be used in conjunction with -𝐂𝗳 or -𝐂𝐅. Thus, this + option is not really needed; it is on by default for all + those cases in which it is allowed. + + A scanner can be forced to not be interactive by using -𝐁 + (see above). + + -𝗶 Instructs 𝗳𝗹𝗲𝘅 to generate a case-insensitive scanner. The + case of letters given in the 𝗳𝗹𝗲𝘅 input patterns will be + ignored, and tokens in the input will be matched regardless + of case. The matched text given in y̲y̲t̲e̲x̲t̲ will have the + preserved case (i.e., it will not be folded). + + -𝐋 Instructs 𝗳𝗹𝗲𝘅 not to generate “#line” directives. Without + this option, 𝗳𝗹𝗲𝘅 peppers the generated scanner with #line + directives so error messages in the actions will be cor‐ + rectly located with respect to either the original 𝗳𝗹𝗲𝘅 + input file (if the errors are due to code in the input + file), or l̲e̲x̲.̲y̲y̲.̲c̲ (if the errors are 𝗳𝗹𝗲𝘅's fault - these + sorts of errors should be reported to the email address + given below). + + -𝗹 Turns on maximum compatibility with the original AT&T UNIX + 𝗹𝗲𝘅 implementation. Note that this does not mean full com‐ + patibility. Use of this option costs a considerable amount + of performance, and it cannot be used with the -+, -𝗳, -𝐅, + -𝐂𝗳, or -𝐂𝐅 options. For details on the compatibilities it + provides, see the section I̲N̲C̲O̲M̲P̲A̲T̲I̲B̲I̲L̲I̲T̲I̲E̲S̲ W̲I̲T̲H̲ L̲E̲X̲ A̲N̲D̲ + P̲O̲S̲I̲X̲ below. This option also results in the name + YY_FLEX_LEX_COMPAT being #define'd in the generated scan‐ + ner. + + -𝗻 Another do-nothing, deprecated option included only for + POSIX compliance. + + -𝗼o̲u̲t̲p̲u̲t̲ + Directs 𝗳𝗹𝗲𝘅 to write the scanner to the file o̲u̲t̲p̲u̲t̲ + instead of l̲e̲x̲.̲y̲y̲.̲c̲. If -𝗼 is combined with the -𝘁 option, + then the scanner is written to stdout but its “#line” + directives (see the -𝐋 option above) refer to the file + o̲u̲t̲p̲u̲t̲. + + -𝐏p̲r̲e̲f̲i̲x̲ + Changes the default "yy" prefix used by 𝗳𝗹𝗲𝘅 for all glob‐ + ally visible variable and function names to instead be + p̲r̲e̲f̲i̲x̲. For example, -𝐏f̲o̲o̲ changes the name of y̲y̲t̲e̲x̲t̲ to + f̲o̲o̲t̲e̲x̲t̲. It also changes the name of the default output + file from l̲e̲x̲.̲y̲y̲.̲c̲ to l̲e̲x̲.̲f̲o̲o̲.̲c̲. Here are all of the names + affected: + + yy_create_buffer + yy_delete_buffer + yy_flex_debug + yy_init_buffer + yy_flush_buffer + yy_load_buffer_state + yy_switch_to_buffer + yyin + yyleng + yylex + yylineno + yyout + yyrestart + yytext + yywrap + + (If using a C++ scanner, then only y̲y̲w̲r̲a̲p̲ and y̲y̲F̲l̲e̲x̲L̲e̲x̲e̲r̲ + are affected.) Within the scanner itself, it is still pos‐ + sible to refer to the global variables and functions using + either version of their name; but externally, they have the + modified name. + + This option allows multiple 𝗳𝗹𝗲𝘅 programs to be easily + linked together into the same executable. Note, though, + that using this option also renames 𝘆𝘆𝘄𝗿𝗮𝗽(), so now either + an (appropriately named) version of the routine for the + scanner must be supplied, or “%option noyywrap” must be + used, as linking with -𝗹𝗳𝗹 no longer provides one by + default. + + -𝗽 Generates a performance report to stderr. The report con‐ + sists of comments regarding features of the 𝗳𝗹𝗲𝘅 input file + which will cause a serious loss of performance in the + resulting scanner. If the flag is specified twice, com‐ + ments regarding features that lead to minor performance + losses will also be reported> + + Note that the use of R̲E̲J̲E̲C̲T̲, “%option yylineno”, and vari‐ + able trailing context (see the B̲U̲G̲S̲ section below) entails + a substantial performance penalty; use of 𝘆𝘆𝗺𝗼𝗿𝗲(), the ‘^’ + operator, and the -𝐈 flag entail minor performance penal‐ + ties. + + -𝐒s̲k̲e̲l̲e̲t̲o̲n̲ + Overrides the default skeleton file from which 𝗳𝗹𝗲𝘅 con‐ + structs its scanners. This option is needed only for 𝗳𝗹𝗲𝘅 + maintenance or development. + + -𝘀 Causes the default rule (that unmatched scanner input is + echoed to stdout) to be suppressed. If the scanner encoun‐ + ters input that does not match any of its rules, it aborts + with an error. This option is useful for finding holes in + a scanner's rule set. + + -𝐓 Makes 𝗳𝗹𝗲𝘅 run in t̲r̲a̲c̲e̲ mode. It will generate a lot of + messages to stderr concerning the form of the input and the + resultant non-deterministic and deterministic finite autom‐ + ata. This option is mostly for use in maintaining 𝗳𝗹𝗲𝘅. + + -𝘁 Instructs 𝗳𝗹𝗲𝘅 to write the scanner it generates to stan‐ + dard output instead of l̲e̲x̲.̲y̲y̲.̲c̲. + + -𝐕 Prints the version number to stdout and exits. --𝘃𝗲𝗿𝘀𝗶𝗼𝗻 + is a synonym for -𝐕. + + -𝘃 Specifies that 𝗳𝗹𝗲𝘅 should write to stderr a summary of + statistics regarding the scanner it generates. Most of the + statistics are meaningless to the casual 𝗳𝗹𝗲𝘅 user, but the + first line identifies the version of 𝗳𝗹𝗲𝘅 (same as reported + by -𝐕), and the next line the flags used when generating + the scanner, including those that are on by default. + + -𝘄 Suppresses warning messages. + + -+ Specifies that 𝗳𝗹𝗲𝘅 should generate a C++ scanner class. + See the section on G̲E̲N̲E̲R̲A̲T̲I̲N̲G̲ C̲+̲+̲ S̲C̲A̲N̲N̲E̲R̲S̲ below for + details. + + 𝗳𝗹𝗲𝘅 also provides a mechanism for controlling options within the + scanner specification itself, rather than from the 𝗳𝗹𝗲𝘅 command + line. This is done by including “%option” directives in the first + section of the scanner specification. Multiple options can be + specified with a single “%option” directive, and multiple direc‐ + tives in the first section of the 𝗳𝗹𝗲𝘅 input file. + + Most options are given simply as names, optionally preceded by the + word "no" (with no intervening whitespace) to negate their meaning. + A number are equivalent to 𝗳𝗹𝗲𝘅 flags or their negation: + + 7bit -7 option + 8bit -8 option + align -Ca option + backup -b option + batch -B option + c++ -+ option + + caseful or + case-sensitive opposite of -i (default) + + case-insensitive or + caseless -i option + + debug -d option + default opposite of -s option + ecs -Ce option + fast -F option + full -f option + interactive -I option + lex-compat -l option + meta-ecs -Cm option + perf-report -p option + read -Cr option + stdout -t option + verbose -v option + warn opposite of -w option + (use "%option nowarn" for -w) + + array equivalent to "%array" + pointer equivalent to "%pointer" (default) + + Some %option's provide features otherwise not available: + + always-interactive + Instructs 𝗳𝗹𝗲𝘅 to generate a scanner which always considers + its input "interactive". Normally, on each new input file + the scanner calls 𝗶𝘀𝗮𝘁𝘁𝘆() in an attempt to determine + whether the scanner's input source is interactive and thus + should be read a character at a time. When this option is + used, however, no such call is made. + + main Directs 𝗳𝗹𝗲𝘅 to provide a default 𝗺𝗮𝗶𝗻() program for the + scanner, which simply calls 𝘆𝘆𝗹𝗲𝘅(). This option implies + “noyywrap” (see below). + + never-interactive + Instructs 𝗳𝗹𝗲𝘅 to generate a scanner which never considers + its input "interactive" (again, no call made to 𝗶𝘀𝗮𝘁𝘁𝘆()). + This is the opposite of “always-interactive”. + + stack Enables the use of start condition stacks (see S̲T̲A̲R̲T̲ + C̲O̲N̲D̲I̲T̲I̲O̲N̲S̲ above). + + stdinit + If set (i.e., “%option stdinit”), initializes y̲y̲i̲n̲ and + y̲y̲o̲u̲t̲ to stdin and stdout, instead of the default of “nil”. + Some existing 𝗹𝗲𝘅 programs depend on this behavior, even + though it is not compliant with ANSI C, which does not + require stdin and stdout to be compile-time constant. + + yylineno + Directs 𝗳𝗹𝗲𝘅 to generate a scanner that maintains the num‐ + ber of the current line read from its input in the global + variable y̲y̲l̲i̲n̲e̲n̲o̲. This option is implied by “%option + lex-compat”. + + yywrap If unset (i.e., “%option noyywrap”), makes the scanner not + call 𝘆𝘆𝘄𝗿𝗮𝗽() upon an end-of-file, but simply assume that + there are no more files to scan (until the user points y̲y̲i̲n̲ + at a new file and calls 𝘆𝘆𝗹𝗲𝘅() again). + + 𝗳𝗹𝗲𝘅 scans rule actions to determine whether the R̲E̲J̲E̲C̲T̲ or 𝘆𝘆𝗺𝗼𝗿𝗲() + features are being used. The “reject” and “yymore” options are + available to override its decision as to whether to use the + options, either by setting them (e.g., “%option reject”) to indi‐ + cate the feature is indeed used, or unsetting them to indicate it + actually is not used (e.g., “%option noyymore”). + + Three options take string-delimited values, offset with ‘=’: + + %option outfile="ABC" + + is equivalent to -𝗼A̲B̲C̲, and + + %option prefix="XYZ" + + is equivalent to -𝐏X̲Y̲Z̲. Finally, + + %option yyclass="foo" + + only applies when generating a C++ scanner (-+ option). It informs + 𝗳𝗹𝗲𝘅 that “foo” has been derived as a subclass of yyFlexLexer, so + 𝗳𝗹𝗲𝘅 will place actions in the member function “foo::yylex()” + instead of “yyFlexLexer::yylex()”. It also generates a + “yyFlexLexer::yylex()” member function that emits a run-time error + (by invoking “yyFlexLexer::LexerError()”) if called. See + G̲E̲N̲E̲R̲A̲T̲I̲N̲G̲ C̲+̲+̲ S̲C̲A̲N̲N̲E̲R̲S̲, below, for additional information. + + A number of options are available for lint purists who want to sup‐ + press the appearance of unneeded routines in the generated scanner. + Each of the following, if unset (e.g., “%option nounput”), results + in the corresponding routine not appearing in the generated scan‐ + ner: + + input, unput + yy_push_state, yy_pop_state, yy_top_state + yy_scan_buffer, yy_scan_bytes, yy_scan_string + + (though 𝘆𝘆_𝗽𝘂𝘀𝗵_𝘀𝘁𝗮𝘁𝗲() and friends won't appear anyway unless + “%option stack” is being used). + +𝐏𝐄𝐑𝐅𝐎𝐑𝐌𝐀𝐍𝐂𝐄 𝐂𝐎𝐍𝐒𝐈𝐃𝐄𝐑𝐀𝐓𝐈𝐎𝐍𝐒 + The main design goal of 𝗳𝗹𝗲𝘅 is that it generate high-performance + scanners. It has been optimized for dealing well with large sets + of rules. Aside from the effects on scanner speed of the table + compression -𝐂 options outlined above, there are a number of + options/actions which degrade performance. These are, from most + expensive to least: + + REJECT + %option yylineno + arbitrary trailing context + + pattern sets that require backing up + %array + %option interactive + %option always-interactive + + '^' beginning-of-line operator + yymore() + + with the first three all being quite expensive and the last two + being quite cheap. Note also that 𝘂𝗻𝗽𝘂𝘁() is implemented as a rou‐ + tine call that potentially does quite a bit of work, while 𝘆𝘆𝗹𝗲𝘀𝘀() + is a quite-cheap macro; so if just putting back some excess text, + use 𝘆𝘆𝗹𝗲𝘀𝘀(). + + R̲E̲J̲E̲C̲T̲ should be avoided at all costs when performance is impor‐ + tant. It is a particularly expensive option. + + Getting rid of backing up is messy and often may be an enormous + amount of work for a complicated scanner. In principal, one begins + by using the -𝗯 flag to generate a l̲e̲x̲.̲b̲a̲c̲k̲u̲p̲ file. For example, + on the input + + %% + foo return TOK_KEYWORD; + foobar return TOK_KEYWORD; + + the file looks like: + + State #6 is non-accepting - + associated rule line numbers: + 2 3 + out-transitions: [ o ] + jam-transitions: EOF [ \001-n p-\177 ] + + State #8 is non-accepting - + associated rule line numbers: + 3 + out-transitions: [ a ] + jam-transitions: EOF [ \001-` b-\177 ] + + State #9 is non-accepting - + associated rule line numbers: + 3 + out-transitions: [ r ] + jam-transitions: EOF [ \001-q s-\177 ] + + Compressed tables always back up. + + The first few lines tell us that there's a scanner state in which + it can make a transition on an ‘o’ but not on any other character, + and that in that state the currently scanned text does not match + any rule. The state occurs when trying to match the rules found at + lines 2 and 3 in the input file. If the scanner is in that state + and then reads something other than an ‘o’, it will have to back up + to find a rule which is matched. With a bit of headscratching one + can see that this must be the state it's in when it has seen ‘fo’. + When this has happened, if anything other than another ‘o’ is seen, + the scanner will have to back up to simply match the ‘f’ (by the + default rule). + + The comment regarding State #8 indicates there's a problem when + "foob" has been scanned. Indeed, on any character other than an + ‘a’, the scanner will have to back up to accept "foo". Similarly, + the comment for State #9 concerns when "fooba" has been scanned and + an ‘r’ does not follow. + + The final comment reminds us that there's no point going to all the + trouble of removing backing up from the rules unless we're using + -𝐂𝗳 or -𝐂𝐅, since there's no performance gain doing so with com‐ + pressed scanners. + + The way to remove the backing up is to add "error" rules: + + %% + foo return TOK_KEYWORD; + foobar return TOK_KEYWORD; + + fooba | + foob | + fo { + /* false alarm, not really a keyword */ + return TOK_ID; + } + + Eliminating backing up among a list of keywords can also be done + using a "catch-all" rule: + + %% + foo return TOK_KEYWORD; + foobar return TOK_KEYWORD; + + [a-z]+ return TOK_ID; + + This is usually the best solution when appropriate. + + Backing up messages tend to cascade. With a complicated set of + rules it's not uncommon to get hundreds of messages. If one can + decipher them, though, it often only takes a dozen or so rules to + eliminate the backing up (though it's easy to make a mistake and + have an error rule accidentally match a valid token; a possible + future 𝗳𝗹𝗲𝘅 feature will be to automatically add rules to eliminate + backing up). + + It's important to keep in mind that the benefits of eliminating + backing up are gained only if e̲v̲e̲r̲y̲ instance of backing up is elim‐ + inated. Leaving just one gains nothing. + + V̲a̲r̲i̲a̲b̲l̲e̲ trailing context (where both the leading and trailing + parts do not have a fixed length) entails almost the same perfor‐ + mance loss as R̲E̲J̲E̲C̲T̲ (i.e., substantial). So when possible a rule + like: + + %% + mouse|rat/(cat|dog) run(); + + is better written: + + %% + mouse/cat|dog run(); + rat/cat|dog run(); + + or as + + %% + mouse|rat/cat run(); + mouse|rat/dog run(); + + Note that here the special ‘|’ action does not provide any savings, + and can even make things worse (see B̲U̲G̲S̲ below). + + Another area where the user can increase a scanner's performance + (and one that's easier to implement) arises from the fact that the + longer the tokens matched, the faster the scanner will run. This + is because with long tokens the processing of most input characters + takes place in the (short) inner scanning loop, and does not often + have to go through the additional work of setting up the scanning + environment (e.g., y̲y̲t̲e̲x̲t̲) for the action. Recall the scanner for + C comments: + + %x comment + %% + int line_num = 1; + + "/*" BEGIN(comment); + + [^*\n]* + "*"+[^*/\n]* + \n ++line_num; + "*"+"/" BEGIN(INITIAL); + + This could be sped up by writing it as: + + %x comment + %% + int line_num = 1; + + "/*" BEGIN(comment); + + [^*\n]* + [^*\n]*\n ++line_num; + "*"+[^*/\n]* + "*"+[^*/\n]*\n ++line_num; + "*"+"/" BEGIN(INITIAL); + + Now instead of each newline requiring the processing of another + action, recognizing the newlines is "distributed" over the other + rules to keep the matched text as long as possible. Note that + adding rules does n̲o̲t̲ slow down the scanner! The speed of the + scanner is independent of the number of rules or (modulo the con‐ + siderations given at the beginning of this section) how complicated + the rules are with regard to operators such as ‘*’ and ‘|’. + + A final example in speeding up a scanner: scan through a file con‐ + taining identifiers and keywords, one per line and with no other + extraneous characters, and recognize all the keywords. A natural + first approach is: + + %% + asm | + auto | + break | + ... etc ... + volatile | + while /* it's a keyword */ + + .|\n /* it's not a keyword */ + + To eliminate the back-tracking, introduce a catch-all rule: + + %% + asm | + auto | + break | + ... etc ... + volatile | + while /* it's a keyword */ + + [a-z]+ | + .|\n /* it's not a keyword */ + + Now, if it's guaranteed that there's exactly one word per line, + then we can reduce the total number of matches by a half by merging + in the recognition of newlines with that of the other tokens: + + %% + asm\n | + auto\n | + break\n | + ... etc ... + volatile\n | + while\n /* it's a keyword */ + + [a-z]+\n | + .|\n /* it's not a keyword */ + + One has to be careful here, as we have now reintroduced backing up + into the scanner. In particular, while we know that there will + never be any characters in the input stream other than letters or + newlines, 𝗳𝗹𝗲𝘅 can't figure this out, and it will plan for possibly + needing to back up when it has scanned a token like "auto" and then + the next character is something other than a newline or a letter. + Previously it would then just match the "auto" rule and be done, + but now it has no "auto" rule, only an "auto\n" rule. To eliminate + the possibility of backing up, we could either duplicate all rules + but without final newlines or, since we never expect to encounter + such an input and therefore don't how it's classified, we can + introduce one more catch-all rule, this one which doesn't include a + newline: + + %% + asm\n | + auto\n | + break\n | + ... etc ... + volatile\n | + while\n /* it's a keyword */ + + [a-z]+\n | + [a-z]+ | + .|\n /* it's not a keyword */ + + Compiled with -𝐂𝗳, this is about as fast as one can get a 𝗳𝗹𝗲𝘅 + scanner to go for this particular problem. + + A final note: 𝗳𝗹𝗲𝘅 is slow when matching NUL's, particularly when a + token contains multiple NUL's. It's best to write rules which + match short amounts of text if it's anticipated that the text will + often include NUL's. + + Another final note regarding performance: as mentioned above in the + section H̲O̲W̲ T̲H̲E̲ I̲N̲P̲U̲T̲ I̲S̲ M̲A̲T̲C̲H̲E̲D̲, dynamically resizing y̲y̲t̲e̲x̲t̲ to + accommodate huge tokens is a slow process because it presently + requires that the (huge) token be rescanned from the beginning. + Thus if performance is vital, it is better to attempt to match + "large" quantities of text but not "huge" quantities, where the + cutoff between the two is at about 8K characters/token. + +𝐆𝐄𝐍𝐄𝐑𝐀𝐓𝐈𝐍𝐆 𝐂++ 𝐒𝐂𝐀𝐍𝐍𝐄𝐑𝐒 + 𝗳𝗹𝗲𝘅 provides two different ways to generate scanners for use with + C++. The first way is to simply compile a scanner generated by + 𝗳𝗹𝗲𝘅 using a C++ compiler instead of a C compiler. This should not + generate any compilation errors (please report any found to the + email address given in the A̲U̲T̲H̲O̲R̲S̲ section below). C++ code can + then be used in rule actions instead of C code. Note that the + default input source for scanners remains y̲y̲i̲n̲, and default echoing + is still done to y̲y̲o̲u̲t̲. Both of these remain F̲I̲L̲E̲ *̲ variables and + not C++ streams. + + 𝗳𝗹𝗲𝘅 can also be used to generate a C++ scanner class, using the -+ + option (or, equivalently, “%option c++”), which is automatically + specified if the name of the flex executable ends in a ‘+’, such as + 𝗳𝗹𝗲𝘅++. When using this option, 𝗳𝗹𝗲𝘅 defaults to generating the + scanner to the file l̲e̲x̲.̲y̲y̲.̲c̲c̲ instead of l̲e̲x̲.̲y̲y̲.̲c̲. The generated + scanner includes the header file , which defines + the interface to two C++ classes. + + The first class, F̲l̲e̲x̲L̲e̲x̲e̲r̲, provides an abstract base class defin‐ + ing the general scanner class interface. It provides the following + member functions: + + const char* YYText() + Returns the text of the most recently matched token, the + equivalent of y̲y̲t̲e̲x̲t̲. + + int YYLeng() + Returns the length of the most recently matched token, the + equivalent of y̲y̲l̲e̲n̲g̲. + + int lineno() const + Returns the current input line number (see “%option + yylineno”), or 1 if “%option yylineno” was not used. + + void set_debug(int flag) + Sets the debugging flag for the scanner, equivalent to + assigning to y̲y̲_f̲l̲e̲x̲_d̲e̲b̲u̲g̲ (see the O̲P̲T̲I̲O̲N̲S̲ section above). + Note that the scanner must be built using “%option debug” + to include debugging information in it. + + int debug() const + Returns the current setting of the debugging flag. + + Also provided are member functions equivalent to + 𝘆𝘆_𝘀𝘄𝗶𝘁𝗰𝗵_𝘁𝗼_𝗯𝘂𝗳𝗳𝗲𝗿(), 𝘆𝘆_𝗰𝗿𝗲𝗮𝘁𝗲_𝗯𝘂𝗳𝗳𝗲𝗿() (though the first argu‐ + ment is an s̲t̲d̲:̲:̲i̲s̲t̲r̲e̲a̲m̲*̲ object pointer and not a F̲I̲L̲E̲*̲), + 𝘆𝘆_𝗳𝗹𝘂𝘀𝗵_𝗯𝘂𝗳𝗳𝗲𝗿(), 𝘆𝘆_𝗱𝗲𝗹𝗲𝘁𝗲_𝗯𝘂𝗳𝗳𝗲𝗿(), and 𝘆𝘆𝗿𝗲𝘀𝘁𝗮𝗿𝘁() (again, the + first argument is an s̲t̲d̲:̲:̲i̲s̲t̲r̲e̲a̲m̲*̲ object pointer). + + The second class defined in is y̲y̲F̲l̲e̲x̲L̲e̲x̲e̲r̲, which + is derived from F̲l̲e̲x̲L̲e̲x̲e̲r̲. It defines the following additional + member functions: + + yyFlexLexer(std::istream* arg_yyin = 0, std::ostream* arg_yyout = + 0) + Constructs a y̲y̲F̲l̲e̲x̲L̲e̲x̲e̲r̲ object using the given streams for + input and output. If not specified, the streams default to + c̲i̲n̲ and c̲o̲u̲t̲, respectively. + + virtual int yylex() + Performs the same role as 𝘆𝘆𝗹𝗲𝘅() does for ordinary flex + scanners: it scans the input stream, consuming tokens, + until a rule's action returns a value. If subclass ‘S’ is + derived from y̲y̲F̲l̲e̲x̲L̲e̲x̲e̲r̲, in order to access the member + functions and variables of ‘S’ inside 𝘆𝘆𝗹𝗲𝘅(), use “%option + yyclass="S"” to inform 𝗳𝗹𝗲𝘅 that the ‘S’ subclass will be + used instead of y̲y̲F̲l̲e̲x̲L̲e̲x̲e̲r̲. In this case, rather than + generating “yyFlexLexer::yylex()”, 𝗳𝗹𝗲𝘅 generates + “S::yylex()” (and also generates a dummy + “yyFlexLexer::yylex()” that calls + “yyFlexLexer::LexerError()” if called). + + virtual void switch_streams(std::istream* new_in = 0, std::ostream* + new_out = 0) + Reassigns y̲y̲i̲n̲ to n̲e̲w̲_i̲n̲ (if non-nil) and y̲y̲o̲u̲t̲ to n̲e̲w̲_o̲u̲t̲ + (ditto), deleting the previous input buffer if y̲y̲i̲n̲ is + reassigned. + + int yylex(std::istream* new_in, std::ostream* new_out = 0) + First switches the input streams via + “switch_streams(new_in, new_out)” and then returns the + value of 𝘆𝘆𝗹𝗲𝘅(). + + In addition, y̲y̲F̲l̲e̲x̲L̲e̲x̲e̲r̲ defines the following protected virtual + functions which can be redefined in derived classes to tailor the + scanner: + + virtual int LexerInput(char* buf, int max_size) + Reads up to m̲a̲x̲_s̲i̲z̲e̲ characters into b̲u̲f̲ and returns the + number of characters read. To indicate end-of-input, + return 0 characters. Note that "interactive" scanners (see + the -𝐁 and -𝐈 flags) define the macro YY_INTERACTIVE. If + 𝐋𝗲𝘅𝗲𝗿𝐈𝗻𝗽𝘂𝘁() has been redefined, and it's necessary to take + different actions depending on whether or not the scanner + might be scanning an interactive input source, it's possi‐ + ble to test for the presence of this name via “#ifdef”. + + virtual void LexerOutput(const char* buf, int size) + Writes out s̲i̲z̲e̲ characters from the buffer b̲u̲f̲, which, + while NUL-terminated, may also contain "internal" NUL's if + the scanner's rules can match text with NUL's in them. + + virtual void LexerError(const char* msg) + Reports a fatal error message. The default version of this + function writes the message to the stream c̲e̲r̲r̲ and exits. + + Note that a y̲y̲F̲l̲e̲x̲L̲e̲x̲e̲r̲ object contains its entire scanning state. + Thus such objects can be used to create reentrant scanners. Multi‐ + ple instances of the same y̲y̲F̲l̲e̲x̲L̲e̲x̲e̲r̲ class can be instantiated, + and multiple C++ scanner classes can be combined in the same pro‐ + gram using the -𝐏 option discussed above. + + Finally, note that the “%array” feature is not available to C++ + scanner classes; “%pointer” must be used (the default). + + Here is an example of a simple C++ scanner: + + // An example of using the flex C++ scanner class. + + %{ + #include + int mylineno = 0; + %} + + string \"[^\n"]+\" + + ws [ \t]+ + + alpha [A-Za-z] + dig [0-9] + name ({alpha}|{dig}|\$)({alpha}|{dig}|[_.\-/$])* + num1 [-+]?{dig}+\.?([eE][-+]?{dig}+)? + num2 [-+]?{dig}*\.{dig}+([eE][-+]?{dig}+)? + number {num1}|{num2} + + %% + + {ws} /* skip blanks and tabs */ + + "/*" { + int c; + + while ((c = yyinput()) != 0) { + if(c == '\n') + ++mylineno; + else if(c == '*') { + if ((c = yyinput()) == '/') + break; + else + unput(c); + } + } + } + + {number} cout << "number " << YYText() << '\n'; + + \n mylineno++; + + {name} cout << "name " << YYText() << '\n'; + + {string} cout << "string " << YYText() << '\n'; + + %% + + int main(int /* argc */, char** /* argv */) + { + FlexLexer* lexer = new yyFlexLexer; + while(lexer->yylex() != 0) + ; + return 0; + } + + To create multiple (different) lexer classes, use the -𝐏 flag (or + the “prefix=” option) to rename each y̲y̲F̲l̲e̲x̲L̲e̲x̲e̲r̲ to some other + x̲x̲F̲l̲e̲x̲L̲e̲x̲e̲r̲. can then be included in other + sources once per lexer class, first renaming y̲y̲F̲l̲e̲x̲L̲e̲x̲e̲r̲ as fol‐ + lows: + + #undef yyFlexLexer + #define yyFlexLexer xxFlexLexer + #include + + #undef yyFlexLexer + #define yyFlexLexer zzFlexLexer + #include + + If, for example, “%option prefix="xx"” is used for one scanner and + “%option prefix="zz"” is used for the other. + + 𝐈𝐌𝐏𝐎𝐑𝐓𝐀𝐍𝐓: the present form of the scanning class is experimental + and may change considerably between major releases. + +𝐈𝐍𝐂𝐎𝐌𝐏𝐀𝐓𝐈𝐁𝐈𝐋𝐈𝐓𝐈𝐄𝐒 𝐖𝐈𝐓𝐇 𝐋𝐄𝐗 𝐀𝐍𝐃 𝐏𝐎𝐒𝐈𝐗 + 𝗳𝗹𝗲𝘅 is a rewrite of the AT&T UNIX 𝗹𝗲𝘅 tool (the two implementa‐ + tions do not share any code, though), with some extensions and + incompatibilities, both of which are of concern to those who wish + to write scanners acceptable to either implementation. 𝗳𝗹𝗲𝘅 is + fully compliant with the POSIX 𝗹𝗲𝘅 specification, except that when + using “%pointer” (the default), a call to 𝘂𝗻𝗽𝘂𝘁() destroys the con‐ + tents of y̲y̲t̲e̲x̲t̲, which is counter to the POSIX specification. + + In this section we discuss all of the known areas of incompatibil‐ + ity between 𝗳𝗹𝗲𝘅, AT&T UNIX 𝗹𝗲𝘅, and the POSIX specification. + + 𝗳𝗹𝗲𝘅's -𝗹 option turns on maximum compatibility with the original + AT&T UNIX 𝗹𝗲𝘅 implementation, at the cost of a major loss in the + generated scanner's performance. We note below which incompatibil‐ + ities can be overcome using the -𝗹 option. + + 𝗳𝗹𝗲𝘅 is fully compatible with 𝗹𝗲𝘅 with the following exceptions: + + - The undocumented 𝗹𝗲𝘅 scanner internal variable y̲y̲l̲i̲n̲e̲n̲o̲ is not + supported unless -𝗹 or “%option yylineno” is used. + + y̲y̲l̲i̲n̲e̲n̲o̲ should be maintained on a per-buffer basis, rather + than a per-scanner (single global variable) basis. + + y̲y̲l̲i̲n̲e̲n̲o̲ is not part of the POSIX specification. + + - The 𝗶𝗻𝗽𝘂𝘁() routine is not redefinable, though it may be called + to read characters following whatever has been matched by a + rule. If 𝗶𝗻𝗽𝘂𝘁() encounters an end-of-file, the normal + 𝘆𝘆𝘄𝗿𝗮𝗽() processing is done. A “real” end-of-file is returned + by 𝗶𝗻𝗽𝘂𝘁() as EOF. + + Input is instead controlled by defining the YY_INPUT macro. + + The 𝗳𝗹𝗲𝘅 restriction that 𝗶𝗻𝗽𝘂𝘁() cannot be redefined is in + accordance with the POSIX specification, which simply does not + specify any way of controlling the scanner's input other than + by making an initial assignment to y̲y̲i̲n̲. + + - The 𝘂𝗻𝗽𝘂𝘁() routine is not redefinable. This restriction is in + accordance with POSIX. + + - 𝗳𝗹𝗲𝘅 scanners are not as reentrant as 𝗹𝗲𝘅 scanners. In partic‐ + ular, if a scanner is interactive and an interrupt handler + long-jumps out of the scanner, and the scanner is subsequently + called again, the following error message may be displayed: + + fatal flex scanner internal error--end of buffer missed + + To reenter the scanner, first use + + yyrestart(yyin); + + Note that this call will throw away any buffered input; usually + this isn't a problem with an interactive scanner. + + Also note that flex C++ scanner classes are reentrant, so if + using C++ is an option , they should be used instead. See + G̲E̲N̲E̲R̲A̲T̲I̲N̲G̲ C̲+̲+̲ S̲C̲A̲N̲N̲E̲R̲S̲ above for details. + + - 𝗼𝘂𝘁𝗽𝘂𝘁() is not supported. Output from the E̲C̲H̲O̲ macro is done + to the file-pointer y̲y̲o̲u̲t̲ (default stdout). + + 𝗼𝘂𝘁𝗽𝘂𝘁() is not part of the POSIX specification. + + - 𝗹𝗲𝘅 does not support exclusive start conditions (%x), though + they are in the POSIX specification. + + - When definitions are expanded, 𝗳𝗹𝗲𝘅 encloses them in parenthe‐ + ses. With 𝗹𝗲𝘅, the following: + + NAME [A-Z][A-Z0-9]* + %% + foo{NAME}? printf("Found it\n"); + %% + + will not match the string "foo" because when the macro is + expanded the rule is equivalent to "foo[A-Z][A-Z0-9]*?" and the + precedence is such that the ‘?’ is associated with "[A-Z0-9]*". + With 𝗳𝗹𝗲𝘅, the rule will be expanded to "foo([A-Z][A-Z0-9]*)?" + and so the string "foo" will match. + + Note that if the definition begins with ‘^’ or ends with ‘$’ + then it is not expanded with parentheses, to allow these opera‐ + tors to appear in definitions without losing their special + meanings. But the ‘⟨s⟩’, ‘/’, and ⟨⟨EOF⟩⟩ operators cannot be + used in a 𝗳𝗹𝗲𝘅 definition. + + Using -𝗹 results in the 𝗹𝗲𝘅 behavior of no parentheses around + the definition. + + The POSIX specification is that the definition be enclosed in + parentheses. + + - Some implementations of 𝗹𝗲𝘅 allow a rule's action to begin on a + separate line, if the rule's pattern has trailing whitespace: + + %% + foo|bar + { foobar_action(); } + + 𝗳𝗹𝗲𝘅 does not support this feature. + + - The 𝗹𝗲𝘅 ‘%r’ (generate a Ratfor scanner) option is not sup‐ + ported. It is not part of the POSIX specification. + + - After a call to 𝘂𝗻𝗽𝘂𝘁(), y̲y̲t̲e̲x̲t̲ is undefined until the next + token is matched, unless the scanner was built using “%array”. + This is not the case with 𝗹𝗲𝘅 or the POSIX specification. The + -𝗹 option does away with this incompatibility. + + - The precedence of the ‘{}’ (numeric range) operator is differ‐ + ent. 𝗹𝗲𝘅 interprets "abc{1,3}" as match one, two, or three + occurrences of ‘abc’, whereas 𝗳𝗹𝗲𝘅 interprets it as match ‘ab’ + followed by one, two, or three occurrences of ‘c’. The latter + is in agreement with the POSIX specification. + + - The precedence of the ‘^’ operator is different. 𝗹𝗲𝘅 inter‐ + prets "^foo|bar" as match either ‘foo’ at the beginning of a + line, or ‘bar’ anywhere, whereas 𝗳𝗹𝗲𝘅 interprets it as match + either ‘foo’ or ‘bar’ if they come at the beginning of a line. + The latter is in agreement with the POSIX specification. + + - The special table-size declarations such as ‘%a’ supported by + 𝗹𝗲𝘅 are not required by 𝗳𝗹𝗲𝘅 scanners; 𝗳𝗹𝗲𝘅 ignores them. + + - The name FLEX_SCANNER is #define'd so scanners may be written + for use with either 𝗳𝗹𝗲𝘅 or 𝗹𝗲𝘅. Scanners also include + YY_FLEX_MAJOR_VERSION and YY_FLEX_MINOR_VERSION indicating + which version of 𝗳𝗹𝗲𝘅 generated the scanner (for example, for + the 2.5 release, these defines would be 2 and 5, respectively). + + The following 𝗳𝗹𝗲𝘅 features are not included in 𝗹𝗲𝘅 or the POSIX + specification: + + C++ scanners + %option + start condition scopes + start condition stacks + interactive/non-interactive scanners + yy_scan_string() and friends + yyterminate() + yy_set_interactive() + yy_set_bol() + YY_AT_BOL() + <> + <*> + YY_DECL + YY_START + YY_USER_ACTION + YY_USER_INIT + #line directives + %{}'s around actions + multiple actions on a line + + plus almost all of the 𝗳𝗹𝗲𝘅 flags. The last feature in the list + refers to the fact that with 𝗳𝗹𝗲𝘅 multiple actions can be placed on + the same line, separated with semi-colons, while with 𝗹𝗲𝘅, the fol‐ + lowing + + foo handle_foo(); ++num_foos_seen; + + is (rather surprisingly) truncated to + + foo handle_foo(); + + 𝗳𝗹𝗲𝘅 does not truncate the action. Actions that are not enclosed + in braces are simply terminated at the end of the line. + +𝐅𝐈𝐋𝐄𝐒 + flex.skl Skeleton scanner. This file is only used when + building flex, not when 𝗳𝗹𝗲𝘅 executes. + + lex.backup Backing-up information for the -𝗯 flag (called + l̲e̲x̲.̲b̲c̲k̲ on some systems). + + lex.yy.c Generated scanner (called l̲e̲x̲y̲y̲.̲c̲ on some sys‐ + tems). + + lex.yy.cc Generated C++ scanner class, when using -+. + + Header file defining the C++ scanner base class, + F̲l̲e̲x̲L̲e̲x̲e̲r̲, and its derived class, y̲y̲F̲l̲e̲x̲L̲e̲x̲e̲r̲. + + /usr/lib/libl.* 𝗳𝗹𝗲𝘅 libraries. The /̲u̲s̲r̲/̲l̲i̲b̲/̲l̲i̲b̲f̲l̲.̲*̲ libraries + are links to these. Scanners must be linked + using either -𝗹𝗹 or -𝗹𝗳𝗹. + +𝐄𝐗𝐈𝐓 𝐒𝐓𝐀𝐓𝐔𝐒 + The 𝗳𝗹𝗲𝘅 utility exits 0 on success, and >0 if an error occurs. + +𝐃𝐈𝐀𝐆𝐍𝐎𝐒𝐓𝐈𝐂𝐒 + 𝘄𝗮𝗿𝗻𝗶𝗻𝗴, 𝗿𝘂𝗹𝗲 𝗰𝗮𝗻𝗻𝗼𝘁 𝗯𝗲 𝗺𝗮𝘁𝗰𝗵𝗲𝗱 Indicates that the given rule can‐ + not be matched because it follows other rules that will always + match the same text as it. For example, in the following “foo” + cannot be matched because it comes after an identifier "catch-all" + rule: + + [a-z]+ got_identifier(); + foo got_foo(); + + Using R̲E̲J̲E̲C̲T̲ in a scanner suppresses this warning. + + 𝘄𝗮𝗿𝗻𝗶𝗻𝗴, -𝘀 𝗼𝗽𝘁𝗶𝗼𝗻 𝗴𝗶𝘃𝗲𝗻 𝗯𝘂𝘁 𝗱𝗲𝗳𝗮𝘂𝗹𝘁 𝗿𝘂𝗹𝗲 𝗰𝗮𝗻 𝗯𝗲 𝗺𝗮𝘁𝗰𝗵𝗲𝗱 Means + that it is possible (perhaps only in a particular start condition) + that the default rule (match any single character) is the only one + that will match a particular input. Since -𝘀 was given, presumably + this is not intended. + + 𝗿𝗲𝗷𝗲𝗰𝘁_𝘂𝘀𝗲𝗱_𝗯𝘂𝘁_𝗻𝗼𝘁_𝗱𝗲𝘁𝗲𝗰𝘁𝗲𝗱 𝘂𝗻𝗱𝗲𝗳𝗶𝗻𝗲𝗱 + 𝘆𝘆𝗺𝗼𝗿𝗲_𝘂𝘀𝗲𝗱_𝗯𝘂𝘁_𝗻𝗼𝘁_𝗱𝗲𝘁𝗲𝗰𝘁𝗲𝗱 𝘂𝗻𝗱𝗲𝗳𝗶𝗻𝗲𝗱 These errors can occur at + compile time. They indicate that the scanner uses R̲E̲J̲E̲C̲T̲ or + 𝘆𝘆𝗺𝗼𝗿𝗲() but that 𝗳𝗹𝗲𝘅 failed to notice the fact, meaning that 𝗳𝗹𝗲𝘅 + scanned the first two sections looking for occurrences of these + actions and failed to find any, but somehow they snuck in (via an + #include file, for example). Use “%option reject” or “%option + yymore” to indicate to 𝗳𝗹𝗲𝘅 that these features are really needed. + + 𝗳𝗹𝗲𝘅 𝘀𝗰𝗮𝗻𝗻𝗲𝗿 𝗷𝗮𝗺𝗺𝗲𝗱 A scanner compiled with -𝘀 has encountered an + input string which wasn't matched by any of its rules. This error + can also occur due to internal problems. + + 𝘁𝗼𝗸𝗲𝗻 𝘁𝗼𝗼 𝗹𝗮𝗿𝗴𝗲, 𝗲𝘅𝗰𝗲𝗲𝗱𝘀 𝐘𝐘𝐋𝐌𝐀𝐗 The scanner uses “%array” and one + of its rules matched a string longer than the YYLMAX constant (8K + bytes by default). The value can be increased by #define'ing + YYLMAX in the definitions section of 𝗳𝗹𝗲𝘅 input. + + 𝘀𝗰𝗮𝗻𝗻𝗲𝗿 𝗿𝗲𝗾𝘂𝗶𝗿𝗲𝘀 -𝟴 𝗳𝗹𝗮𝗴 𝘁𝗼 𝘂𝘀𝗲 𝘁𝗵𝗲 𝗰𝗵𝗮𝗿𝗮𝗰𝘁𝗲𝗿 '𝘅' The scanner + specification includes recognizing the 8-bit character ‘x’ and the + -𝟴 flag was not specified, and defaulted to 7-bit because the -𝐂𝗳 + or -𝐂𝐅 table compression options were used. See the discussion of + the -𝟳 flag for details. + + 𝗳𝗹𝗲𝘅 𝘀𝗰𝗮𝗻𝗻𝗲𝗿 𝗽𝘂𝘀𝗵-𝗯𝗮𝗰𝗸 𝗼𝘃𝗲𝗿𝗳𝗹𝗼𝘄 unput() was used to push back so + much text that the scanner's buffer could not hold both the pushed- + back text and the current token in y̲y̲t̲e̲x̲t̲. Ideally the scanner + should dynamically resize the buffer in this case, but at present + it does not. + + 𝗶𝗻𝗽𝘂𝘁 𝗯𝘂𝗳𝗳𝗲𝗿 𝗼𝘃𝗲𝗿𝗳𝗹𝗼𝘄, 𝗰𝗮𝗻'𝘁 𝗲𝗻𝗹𝗮𝗿𝗴𝗲 𝗯𝘂𝗳𝗳𝗲𝗿 𝗯𝗲𝗰𝗮𝘂𝘀𝗲 𝘀𝗰𝗮𝗻𝗻𝗲𝗿 𝘂𝘀𝗲𝘀 + 𝐑𝐄𝐉𝐄𝐂𝐓 The scanner was working on matching an extremely large + token and needed to expand the input buffer. This doesn't work + with scanners that use R̲E̲J̲E̲C̲T̲. + + 𝗳𝗮𝘁𝗮𝗹 𝗳𝗹𝗲𝘅 𝘀𝗰𝗮𝗻𝗻𝗲𝗿 𝗶𝗻𝘁𝗲𝗿𝗻𝗮𝗹 𝗲𝗿𝗿𝗼𝗿--𝗲𝗻𝗱 𝗼𝗳 𝗯𝘂𝗳𝗳𝗲𝗿 𝗺𝗶𝘀𝘀𝗲𝗱 This can + occur in an scanner which is reentered after a long-jump has jumped + out (or over) the scanner's activation frame. Before reentering + the scanner, use: + + yyrestart(yyin); + + or, as noted above, switch to using the C++ scanner class. + + 𝘁𝗼𝗼 𝗺𝗮𝗻𝘆 𝘀𝘁𝗮𝗿𝘁 𝗰𝗼𝗻𝗱𝗶𝘁𝗶𝗼𝗻𝘀 𝗶𝗻 <> 𝗰𝗼𝗻𝘀𝘁𝗿𝘂𝗰𝘁! More start conditions + than exist were listed in a <> construct (so at least one of them + must have been listed twice). + +𝐒𝐄𝐄 𝐀𝐋𝐒𝐎 + awk(1), sed(1), yacc(1) + + John Levine, Tony Mason, and Doug Brown, L̲e̲x̲ &̲ Y̲a̲c̲c̲, O̲'̲R̲e̲i̲l̲l̲y̲ a̲n̲d̲ + A̲s̲s̲o̲c̲i̲a̲t̲e̲s̲, 2nd edition. + + Alfred Aho, Ravi Sethi, and Jeffrey Ullman, C̲o̲m̲p̲i̲l̲e̲r̲s̲:̲ P̲r̲i̲n̲c̲i̲p̲l̲e̲s̲,̲ + T̲e̲c̲h̲n̲i̲q̲u̲e̲s̲ a̲n̲d̲ T̲o̲o̲l̲s̲, A̲d̲d̲i̲s̲o̲n̲-̲W̲e̲s̲l̲e̲y̲, 1986, Describes the pattern- + matching techniques used by flex (deterministic finite automata). + +𝐒𝐓𝐀𝐍𝐃𝐀𝐑𝐃𝐒 + The 𝗹𝗲𝘅 utility is compliant with the IEEE Std 1003.1-2008 + (“POSIX.1”) specification, though its presence is optional. + + The flags [-𝟳𝟴𝐁𝗯𝐂𝗱𝐅𝗳𝗵𝐈𝗶𝐋𝗹𝗼𝐏𝗽𝐒𝘀𝐓𝐕𝘄+?], [--𝗵𝗲𝗹𝗽], and [--𝘃𝗲𝗿𝘀𝗶𝗼𝗻] are + extensions to that specification. + + See also the I̲N̲C̲O̲M̲P̲A̲T̲I̲B̲I̲L̲I̲T̲I̲E̲S̲ W̲I̲T̲H̲ L̲E̲X̲ A̲N̲D̲ P̲O̲S̲I̲X̲ section, above. + +𝐀𝐔𝐓𝐇𝐎𝐑𝐒 + Vern Paxson, with the help of many ideas and much inspiration from + Van Jacobson. Original version by Jef Poskanzer. The fast table + representation is a partial implementation of a design done by Van + Jacobson. The implementation was done by Kevin Gong and Vern Pax‐ + son. + + Thanks to the many 𝗳𝗹𝗲𝘅 beta-testers, feedbackers, and contribu‐ + tors, especially Francois Pinard, Casey Leedom, Robert Abramovitz, + Stan Adermann, Terry Allen, David Barker-Plummer, John Basrai, Neal + Becker, Nelson H.F. Beebe, b̲e̲n̲s̲o̲n̲@̲o̲d̲i̲.̲c̲o̲m̲, Karl Berry, Peter A. + Bigot, Simon Blanchard, Keith Bostic, Frederic Brehm, Ian Brock‐ + bank, Kin Cho, Nick Christopher, Brian Clapper, J.T. Conklin, Jason + Coughlin, Bill Cox, Nick Cropper, Dave Curtis, Scott David Daniels, + Chris G. Demetriou, Theo de Raadt, Mike Donahue, Chuck Doucette, + Tom Epperly, Leo Eskin, Chris Faylor, Chris Flatters, Jon Forrest, + Jeffrey Friedl, Joe Gayda, Kaveh R. Ghazi, Wolfgang Glunz, Eric + Goldman, Christopher M. Gould, Ulrich Grepel, Peer Griebel, Jan + Hajic, Charles Hemphill, NORO Hideo, Jarkko Hietaniemi, Scott Hof‐ + mann, Jeff Honig, Dana Hudes, Eric Hughes, John Interrante, Ceriel + Jacobs, Michal Jaegermann, Sakari Jalovaara, Jeffrey R. Jones, + Henry Juengst, Klaus Kaempf, Jonathan I. Kamens, Terrence O Kane, + Amir Katz, k̲e̲n̲@̲k̲e̲n̲.̲h̲i̲l̲c̲o̲.̲c̲o̲m̲, Kevin B. Kenny, Steve Kirsch, Win‐ + fried Koenig, Marq Kole, Ronald Lamprecht, Greg Lee, Rohan Lenard, + Craig Leres, John Levine, Steve Liddle, David Loffredo, Mike Long, + Mohamed el Lozy, Brian Madsen, Malte, Joe Marshall, Bengt Martens‐ + son, Chris Metcalf, Luke Mewburn, Jim Meyering, R. Alexander + Milowski, Erik Naggum, G.T. Nicol, Landon Noll, James Nordby, Marc + Nozell, Richard Ohnemus, Karsten Pahnke, Sven Panne, Roland Pesch, + Walter Pelissero, Gaumond Pierre, Esmond Pitt, Jef Poskanzer, Joe + Rahmeh, Jarmo Raiha, Frederic Raimbault, Pat Rankin, Rick Richard‐ + son, Kevin Rodgers, Kai Uwe Rommel, Jim Roskind, Alberto Santini, + Andreas Scherer, Darrell Schiebel, Raf Schietekat, Doug Schmidt, + Philippe Schnoebelen, Andreas Schwab, Larry Schwimmer, Alex Siegel, + Eckehard Stolz, Jan-Erik Strvmquist, Mike Stump, Paul Stuart, Dave + Tallman, Ian Lance Taylor, Chris Thewalt, Richard M. Timoney, Jodi + Tsai, Paul Tuinenga, Gary Weik, Frank Whaley, Gerhard Wilhelms, + Kent Williams, Ken Yap, Ron Zellar, Nathan Zelle, David Zuhn, and + those whose names have slipped my marginal mail-archiving skills + but whose contributions are appreciated all the same. + + Thanks to Keith Bostic, Jon Forrest, Noah Friedman, John Gilmore, + Craig Leres, John Levine, Bob Mulcahy, G.T. Nicol, Francois + Pinard, Rich Salz, and Richard Stallman for help with various dis‐ + tribution headaches. + + Thanks to Esmond Pitt and Earle Horton for 8-bit character support; + to Benson Margulies and Fred Burke for C++ support; to Kent + Williams and Tom Epperly for C++ class support; to Ove Ewerlid for + support of NUL's; and to Eric Hughes for support of multiple buf‐ + fers. + + This work was primarily done when I was with the Real Time Systems + Group at the Lawrence Berkeley Laboratory in Berkeley, CA. Many + thanks to all there for the support I received. + + Send comments to ⟨v̲e̲r̲n̲@̲e̲e̲.̲l̲b̲l̲.̲g̲o̲v̲⟩. + +𝐁𝐔𝐆𝐒 + Some trailing context patterns cannot be properly matched and gen‐ + erate warning messages (dangerous trailing context). These are + patterns where the ending of the first part of the rule matches the + beginning of the second part, such as "zx*/xy*", where the ‘x*’ + matches the ‘x’ at the beginning of the trailing context. (Note + that the POSIX draft states that the text matched by such patterns + is undefined.) + + For some trailing context rules, parts which are actually fixed- + length are not recognized as such, leading to the above mentioned + performance loss. In particular, parts using ‘|’ or ‘{n}’ (such as + "foo{3}") are always considered variable-length. + + Combining trailing context with the special ‘|’ action can result + in fixed trailing context being turned into the more expensive + variable trailing context. For example, in the following: + + %% + abc | + xyz/def + + Use of 𝘂𝗻𝗽𝘂𝘁() invalidates yytext and yyleng, unless the “%array” + directive or the -𝗹 option has been used. + + Pattern-matching of NUL's is substantially slower than matching + other characters. + + Dynamic resizing of the input buffer is slow, as it entails rescan‐ + ning all the text matched so far by the current (generally huge) + token. + + Due to both buffering of input and read-ahead, it is not possible + to intermix calls to routines, such as, for example, + 𝗴𝗲𝘁𝗰𝗵𝗮𝗿(), with 𝗳𝗹𝗲𝘅 rules and expect it to work. Call 𝗶𝗻𝗽𝘂𝘁() + instead. + + The total table entries listed by the -𝘃 flag excludes the number + of table entries needed to determine what rule has been matched. + The number of entries is equal to the number of DFA states if the + scanner does not use R̲E̲J̲E̲C̲T̲, and somewhat greater than the number + of states if it does. + + R̲E̲J̲E̲C̲T̲ cannot be used with the -𝗳 or -𝐅 options. + + The 𝗳𝗹𝗲𝘅 internal algorithms need documentation. + +COSMOPOLITAN September 21, 2015 BSD diff --git a/third_party/lex/buf.c b/third_party/lex/buf.c new file mode 100644 index 00000000..96b0afa2 --- /dev/null +++ b/third_party/lex/buf.c @@ -0,0 +1,286 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 sw=8 fenc=utf-8 :vi│ +└─────────────────────────────────────────────────────────────────────────────*/ +/* clang-format off */ +/* $OpenBSD: buf.c,v 1.7 2015/11/20 18:54:49 tedu Exp $ */ + +/* flex - tool to generate fast lexical analyzers */ + +/* Copyright (c) 1990 The Regents of the University of California. */ +/* All rights reserved. */ + +/* This code is derived from software contributed to Berkeley by */ +/* Vern Paxson. */ + +/* The United States Government has rights in this work pursuant */ +/* to contract no. DE-AC03-76SF00098 between the United States */ +/* Department of Energy and the University of California. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + + +#include "libc/str/str.h" +#include "libc/mem/mem.h" +#include "libc/fmt/fmt.h" +#include "libc/math.h" +#include "libc/conv/conv.h" +#include "flexdef.h" + +/* Take note: The buffer object is sometimes used as a String buffer (one + * continuous string), and sometimes used as a list of strings, usually line by + * line. + * + * The type is specified in buf_init by the elt_size. If the elt_size is + * sizeof(char), then the buffer should be treated as string buffer. If the + * elt_size is sizeof(char*), then the buffer should be treated as a list of + * strings. + * + * Certain functions are only appropriate for one type or the other. + */ + +/* global buffers. */ +struct Buf userdef_buf; /**< for user #definitions triggered by cmd-line. */ +struct Buf defs_buf; /**< for #define's autogenerated. List of strings. */ +struct Buf yydmap_buf; /**< string buffer to hold yydmap elements */ +struct Buf m4defs_buf; /**< m4 definitions. List of strings. */ +struct Buf top_buf; /**< contains %top code. String buffer. */ + +struct Buf * +buf_print_strings(struct Buf * buf, FILE * out) +{ + int i; + + if (!buf || !out) + return buf; + + for (i = 0; i < buf->nelts; i++) { + const char *s = ((char **) buf->elts)[i]; + if (s) + fprintf(out, "%s", s); + } + return buf; +} + +/* Append a "%s" formatted string to a string buffer */ +struct Buf * +buf_prints(struct Buf * buf, const char *fmt, const char *s) +{ + char *t; + size_t tsz; + + tsz = strlen(fmt) + strlen(s) + 1; + t = malloc(tsz); + if (!t) + flexfatal(_("Allocation of buffer to print string failed")); + snprintf(t, tsz, fmt, s); + buf = buf_strappend(buf, t); + free(t); + return buf; +} + +/** Append a line directive to the string buffer. + * @param buf A string buffer. + * @param filename file name + * @param lineno line number + * @return buf + */ +struct Buf * +buf_linedir(struct Buf * buf, const char *filename, int lineno) +{ + const char *src; + char *dst, *t; + size_t tsz; + + tsz = strlen("#line \"\"\n") + /* constant parts */ + 2 * strlen(filename) + /* filename with possibly all backslashes escaped */ + (int) (1 + log10(abs(lineno))) + /* line number */ + 1; /* NUL */ + t = malloc(tsz); + if (!t) + flexfatal(_("Allocation of buffer for line directive failed")); + dst = t + snprintf(t, tsz, "#line %d \"", lineno); + for (src = filename; *src; *dst++ = *src++) + if (*src == '\\') /* escape backslashes */ + *dst++ = '\\'; + *dst++ = '"'; + *dst++ = '\n'; + *dst = '\0'; + buf = buf_strappend(buf, t); + free(t); + return buf; +} + + +/** Append the contents of @a src to @a dest. + * @param @a dest the destination buffer + * @param @a dest the source buffer + * @return @a dest + */ +struct Buf * +buf_concat(struct Buf * dest, const struct Buf * src) +{ + buf_append(dest, src->elts, src->nelts); + return dest; +} + + +/* Appends n characters in str to buf. */ +struct Buf * +buf_strnappend(struct Buf *buf, const char *str, int n) +{ + buf_append(buf, str, n + 1); + + /* "undo" the '\0' character that buf_append() already copied. */ + buf->nelts--; + + return buf; +} + +/* Appends characters in str to buf. */ +struct Buf * +buf_strappend(struct Buf *buf, const char *str) +{ + return buf_strnappend(buf, str, strlen(str)); +} + +/* appends "#define str def\n" */ +struct Buf * +buf_strdefine(struct Buf *buf, const char *str, const char *def2) +{ + buf_strappend(buf, "#define "); + buf_strappend(buf, " "); + buf_strappend(buf, str); + buf_strappend(buf, " "); + buf_strappend(buf, def2); + buf_strappend(buf, "\n"); + return buf; +} + +/** Pushes "m4_define( [[def]], [[val]])m4_dnl" to end of buffer. + * @param buf A buffer as a list of strings. + * @param def The m4 symbol to define. + * @param val The definition; may be NULL. + * @return buf + */ +struct Buf * +buf_m4_define(struct Buf * buf, const char *def2, const char *val) +{ + const char *fmt = "m4_define( [[%s]], [[%s]])m4_dnl\n"; + char *str; + size_t strsz; + + val = val ? val : ""; + strsz = strlen(fmt) + strlen(def2) + strlen(val) + 2; + str = malloc(strsz); + if (!str) + flexfatal(_("Allocation of buffer for m4 def failed")); + + snprintf(str, strsz, fmt, def2, val); + buf_append(buf, &str, 1); + return buf; +} + +/** Pushes "m4_undefine([[def]])m4_dnl" to end of buffer. + * @param buf A buffer as a list of strings. + * @param def The m4 symbol to undefine. + * @return buf + */ +struct Buf * +buf_m4_undefine(struct Buf * buf, const char *def2) +{ + const char *fmt = "m4_undefine( [[%s]])m4_dnl\n"; + char *str; + size_t strsz; + + strsz = strlen(fmt) + strlen(def2) + 2; + str = malloc(strsz); + if (!str) + flexfatal(_("Allocation of buffer for m4 undef failed")); + + snprintf(str, strsz, fmt, def2); + buf_append(buf, &str, 1); + return buf; +} + +/* create buf with 0 elements, each of size elem_size. */ +void +buf_init(struct Buf *buf, size_t elem_size) +{ + buf->elts = NULL; + buf->nelts = 0; + buf->elt_size = elem_size; + buf->nmax = 0; +} + +/* frees memory */ +void +buf_destroy(struct Buf *buf) +{ + free(buf->elts); + buf->elts = NULL; +} + + +/* appends ptr[] to buf, grow if necessary. + * n_elem is number of elements in ptr[], NOT bytes. + * returns buf. + * We grow by mod(512) boundaries. + */ + +struct Buf * +buf_append(struct Buf *buf, const void *ptr, int n_elem) +{ + int n_alloc = 0; + + if (!ptr || n_elem == 0) + return buf; + + /* May need to alloc more. */ + if (n_elem + buf->nelts > buf->nmax) { + + /* exact amount needed... */ + n_alloc = (n_elem + buf->nelts) * buf->elt_size; + + /* ...plus some extra */ + if (((n_alloc * buf->elt_size) % 512) != 0 + && buf->elt_size < 512) + n_alloc += + (512 - + ((n_alloc * buf->elt_size) % 512)) / + buf->elt_size; + + if (!buf->elts) + buf->elts = + allocate_array(n_alloc, buf->elt_size); + else + buf->elts = + reallocate_array(buf->elts, n_alloc, + buf->elt_size); + + buf->nmax = n_alloc; + } + memcpy((char *) buf->elts + buf->nelts * buf->elt_size, ptr, + n_elem * buf->elt_size); + buf->nelts += n_elem; + + return buf; +} diff --git a/third_party/lex/ccl.c b/third_party/lex/ccl.c new file mode 100644 index 00000000..e7d69d05 --- /dev/null +++ b/third_party/lex/ccl.c @@ -0,0 +1,325 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 sw=8 fenc=utf-8 :vi│ +└─────────────────────────────────────────────────────────────────────────────*/ +/* clang-format off */ +/* $OpenBSD: ccl.c,v 1.8 2015/11/19 22:55:13 tedu Exp $ */ + +/* ccl - routines for character classes */ + +/* Copyright (c) 1990 The Regents of the University of California. */ +/* All rights reserved. */ + +/* This code is derived from software contributed to Berkeley by */ +/* Vern Paxson. */ + +/* The United States Government has rights in this work pursuant */ +/* to contract no. DE-AC03-76SF00098 between the United States */ + /* Department of Energy and the University of California. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + +#include "libc/str/str.h" +#include "flexdef.h" + +/* return true if the chr is in the ccl. Takes negation into account. */ +static bool +ccl_contains(const int cclp, const int ch) +{ + int ind, len, i; + + len = ccllen[cclp]; + ind = cclmap[cclp]; + + for (i = 0; i < len; ++i) + if (ccltbl[ind + i] == ch) + return !cclng[cclp]; + + return cclng[cclp]; +} + + +/* ccladd - add a single character to a ccl */ + +void +ccladd(cclp, ch) + int cclp; + int ch; +{ + int ind, len, newpos, i; + + check_char(ch); + + len = ccllen[cclp]; + ind = cclmap[cclp]; + + /* check to see if the character is already in the ccl */ + + for (i = 0; i < len; ++i) + if (ccltbl[ind + i] == ch) + return; + + /* mark newlines */ + if (ch == nlch) + ccl_has_nl[cclp] = true; + + newpos = ind + len; + + if (newpos >= current_max_ccl_tbl_size) { + current_max_ccl_tbl_size += MAX_CCL_TBL_SIZE_INCREMENT; + + ++num_reallocs; + + ccltbl = reallocate_Character_array(ccltbl, + current_max_ccl_tbl_size); + } + ccllen[cclp] = len + 1; + ccltbl[newpos] = ch; +} + +/* dump_cclp - same thing as list_character_set, but for cclps. */ + +static void +dump_cclp(FILE * file, int cclp) +{ + int i; + + putc('[', file); + + for (i = 0; i < csize; ++i) { + if (ccl_contains(cclp, i)) { + int start_char = i; + + putc(' ', file); + + fputs(readable_form(i), file); + + while (++i < csize && ccl_contains(cclp, i)); + + if (i - 1 > start_char) + /* this was a run */ + fprintf(file, "-%s", + readable_form(i - 1)); + + putc(' ', file); + } + } + + putc(']', file); +} + + + +/* ccl_set_diff - create a new ccl as the set difference of the two given ccls. */ +int +ccl_set_diff(int a, int b) +{ + int d, ch; + + /* create new class */ + d = cclinit(); + + /* + * In order to handle negation, we spin through all possible chars, + * addding each char in a that is not in b. (This could be O(n^2), + * but n is small and bounded.) + */ + for (ch = 0; ch < csize; ++ch) + if (ccl_contains(a, ch) && !ccl_contains(b, ch)) + ccladd(d, ch); + + /* debug */ + if (0) { + fprintf(stderr, "ccl_set_diff ("); + fprintf(stderr, "\n "); + dump_cclp(stderr, a); + fprintf(stderr, "\n "); + dump_cclp(stderr, b); + fprintf(stderr, "\n "); + dump_cclp(stderr, d); + fprintf(stderr, "\n)\n"); + } + return d; +} + +/* ccl_set_union - create a new ccl as the set union of the two given ccls. */ +int +ccl_set_union(int a, int b) +{ + int d, i; + + /* create new class */ + d = cclinit(); + + /* Add all of a */ + for (i = 0; i < ccllen[a]; ++i) + ccladd(d, ccltbl[cclmap[a] + i]); + + /* Add all of b */ + for (i = 0; i < ccllen[b]; ++i) + ccladd(d, ccltbl[cclmap[b] + i]); + + /* debug */ + if (0) { + fprintf(stderr, "ccl_set_union (%d + %d = %d", a, b, d); + fprintf(stderr, "\n "); + dump_cclp(stderr, a); + fprintf(stderr, "\n "); + dump_cclp(stderr, b); + fprintf(stderr, "\n "); + dump_cclp(stderr, d); + fprintf(stderr, "\n)\n"); + } + return d; +} + + +/* cclinit - return an empty ccl */ + +int +cclinit() +{ + if (++lastccl >= current_maxccls) { + current_maxccls += MAX_CCLS_INCREMENT; + + ++num_reallocs; + + cclmap = + reallocate_integer_array(cclmap, current_maxccls); + ccllen = + reallocate_integer_array(ccllen, current_maxccls); + cclng = reallocate_integer_array(cclng, current_maxccls); + ccl_has_nl = + reallocate_bool_array(ccl_has_nl, + current_maxccls); + } + if (lastccl == 1) + /* we're making the first ccl */ + cclmap[lastccl] = 0; + + else + /* + * The new pointer is just past the end of the last ccl. + * Since the cclmap points to the \first/ character of a ccl, + * adding the length of the ccl to the cclmap pointer will + * produce a cursor to the first free space. + */ + cclmap[lastccl] = + cclmap[lastccl - 1] + ccllen[lastccl - 1]; + + ccllen[lastccl] = 0; + cclng[lastccl] = 0; /* ccl's start out life un-negated */ + ccl_has_nl[lastccl] = false; + + return lastccl; +} + + +/* cclnegate - negate the given ccl */ + +void +cclnegate(cclp) + int cclp; +{ + cclng[cclp] = 1; + ccl_has_nl[cclp] = !ccl_has_nl[cclp]; +} + + +/* list_character_set - list the members of a set of characters in CCL form + * + * Writes to the given file a character-class representation of those + * characters present in the given CCL. A character is present if it + * has a non-zero value in the cset array. + */ + +void +list_character_set(file, cset) + FILE *file; + int cset[]; +{ + int i; + + putc('[', file); + + for (i = 0; i < csize; ++i) { + if (cset[i]) { + int start_char = i; + + putc(' ', file); + + fputs(readable_form(i), file); + + while (++i < csize && cset[i]); + + if (i - 1 > start_char) + /* this was a run */ + fprintf(file, "-%s", + readable_form(i - 1)); + + putc(' ', file); + } + } + + putc(']', file); +} + +/** Determines if the range [c1-c2] is unambiguous in a case-insensitive + * scanner. Specifically, if a lowercase or uppercase character, x, is in the + * range [c1-c2], then we require that UPPERCASE(x) and LOWERCASE(x) must also + * be in the range. If not, then this range is ambiguous, and the function + * returns false. For example, [@-_] spans [a-z] but not [A-Z]. Beware that + * [a-z] will be labeled ambiguous because it does not include [A-Z]. + * + * @param c1 the lower end of the range + * @param c2 the upper end of the range + * @return true if [c1-c2] is not ambiguous for a caseless scanner. + */ +bool +range_covers_case(int c1, int c2) +{ + int i, o; + + for (i = c1; i <= c2; i++) { + if (has_case(i)) { + o = reverse_case(i); + if (o < c1 || c2 < o) + return false; + } + } + return true; +} + +/** Reverse the case of a character, if possible. + * @return c if case-reversal does not apply. + */ +int +reverse_case(int c) +{ + return isupper(c) ? tolower(c) : (islower(c) ? toupper(c) : c); +} + +/** Return true if c is uppercase or lowercase. */ +bool +has_case(int c) +{ + return (isupper(c) || islower(c)) ? true : false; +} diff --git a/third_party/lex/config.h b/third_party/lex/config.h new file mode 100644 index 00000000..0b3f42da --- /dev/null +++ b/third_party/lex/config.h @@ -0,0 +1,207 @@ +/* $OpenBSD: config.h,v 1.5 2015/11/19 23:48:06 tedu Exp $ */ + +/* config.h. Generated from conf.in by configure. */ +/* conf.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the + CoreFoundation framework. */ +/* #undef HAVE_CFLOCALECOPYCURRENT */ + +/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in + the CoreFoundation framework. */ +/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */ + +/* Define if the GNU dcgettext() function is already present or preinstalled. + */ +/* #undef HAVE_DCGETTEXT */ + +/* Define to 1 if you have the header file. */ +/* #define HAVE_DLFCN_H 1 */ + +/* Define to 1 if you have the `dup2' function. */ +#define HAVE_DUP2 1 + +/* Define to 1 if you have the `fork' function. */ +#define HAVE_FORK 1 + +/* Define if the GNU gettext() function is already present or preinstalled. */ +/* #undef HAVE_GETTEXT */ + +/* Define if you have the iconv() function and it works. */ +#define HAVE_ICONV 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `isascii' function. */ +#define HAVE_ISASCII 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LIBINTL_H */ + +/* Define to 1 if you have the `m' library (-lm). */ +#define HAVE_LIBM 1 + +/* pthread library */ +#define HAVE_LIBPTHREAD 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the header file. */ +/* #define HAVE_LOCALE_H 1 */ + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#define HAVE_MALLOC 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `memset' function. */ +#define HAVE_MEMSET 1 + +/* Define to 1 if you have the header file. */ +/* #define HAVE_NETINET_IN_H 1 */ + +/* Define to 1 if you have the `pow' function. */ +#define HAVE_POW 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PTHREAD_H 1 + +/* Define to 1 if your system has a GNU libc compatible `realloc' function, + and to 0 otherwise. */ +#define HAVE_REALLOC 1 + +/* Define to 1 if you have the `regcomp' function. */ +#define HAVE_REGCOMP 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_REGEX_H 1 + +/* Define to 1 if you have the `setlocale' function. */ +/* #define HAVE_SETLOCALE 1 */ + +/* Define to 1 if stdbool.h conforms to C99. */ +#define HAVE_STDBOOL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strchr' function. */ +#define HAVE_STRCHR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strtol' function. */ +#define HAVE_STRTOL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `vfork' function. */ +#define HAVE_VFORK 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_VFORK_H */ + +/* Define to 1 if `fork' works. */ +#define HAVE_WORKING_FORK 1 + +/* Define to 1 if `vfork' works. */ +#define HAVE_WORKING_VFORK 1 + +/* Define to 1 if the system has the type `_Bool'. */ +#define HAVE__BOOL 1 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Define to the m4 executable name. */ +#define M4 "o/$(MODE)/third_party/m4/m4.com.dbg" + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Name of package */ +#define PACKAGE "flex" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "flex-help@lists.sourceforge.net" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "the fast lexical analyser generator" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "the fast lexical analyser generator 2.5.39" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "flex" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "2.5.39" + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +/* #undef STACK_DIRECTION */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "2.5.39" + +/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a + `char[]'. */ +#define YYTEXT_POINTER 1 + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to rpl_malloc if the replacement function should be used. */ +/* #undef malloc */ + +/* Define to `int' if does not define. */ +/* #undef pid_t */ + +/* Define to rpl_realloc if the replacement function should be used. */ +/* #undef realloc */ + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +/* Define as `fork' if `vfork' does not work. */ +/* #undef vfork */ + +#define HAVE_ASSERT_H diff --git a/third_party/lex/dfa.c b/third_party/lex/dfa.c new file mode 100644 index 00000000..8ca6b5ce --- /dev/null +++ b/third_party/lex/dfa.c @@ -0,0 +1,1105 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 sw=8 fenc=utf-8 :vi│ +└─────────────────────────────────────────────────────────────────────────────*/ + +/* clang-format off */ +/* $OpenBSD: dfa.c,v 1.8 2015/11/19 23:20:34 tedu Exp $ */ + +/* dfa - DFA construction routines */ + +/* Copyright (c) 1990 The Regents of the University of California. */ +/* All rights reserved. */ + +/* This code is derived from software contributed to Berkeley by */ +/* Vern Paxson. */ + +/* The United States Government has rights in this work pursuant */ +/* to contract no. DE-AC03-76SF00098 between the United States */ +/* Department of Energy and the University of California. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + +#include "flexdef.h" +#include "libc/alg/alg.h" +#include "libc/mem/mem.h" +#include "tables.h" + +/* declare functions that have forward references */ + +void dump_associated_rules PROTO ((FILE *, int)); +void dump_transitions PROTO ((FILE *, int[])); +void sympartition PROTO ((int[], int, int[], int[])); +int symfollowset PROTO ((int[], int, int, int[])); + + +/* check_for_backing_up - check a DFA state for backing up + * + * synopsis + * void check_for_backing_up( int ds, int state[numecs] ); + * + * ds is the number of the state to check and state[] is its out-transitions, + * indexed by equivalence class. + */ + +void check_for_backing_up (ds, state) + int ds; + int state[]; +{ + if ((reject && !dfaacc[ds].dfaacc_set) || (!reject && !dfaacc[ds].dfaacc_state)) { /* state is non-accepting */ + ++num_backing_up; + + if (backing_up_report) { + fprintf (backing_up_file, + _("State #%d is non-accepting -\n"), ds); + + /* identify the state */ + dump_associated_rules (backing_up_file, ds); + + /* Now identify it further using the out- and + * jam-transitions. + */ + dump_transitions (backing_up_file, state); + + putc ('\n', backing_up_file); + } + } +} + + +/* check_trailing_context - check to see if NFA state set constitutes + * "dangerous" trailing context + * + * synopsis + * void check_trailing_context( int nfa_states[num_states+1], int num_states, + * int accset[nacc+1], int nacc ); + * + * NOTES + * Trailing context is "dangerous" if both the head and the trailing + * part are of variable size \and/ there's a DFA state which contains + * both an accepting state for the head part of the rule and NFA states + * which occur after the beginning of the trailing context. + * + * When such a rule is matched, it's impossible to tell if having been + * in the DFA state indicates the beginning of the trailing context or + * further-along scanning of the pattern. In these cases, a warning + * message is issued. + * + * nfa_states[1 .. num_states] is the list of NFA states in the DFA. + * accset[1 .. nacc] is the list of accepting numbers for the DFA state. + */ + +void check_trailing_context (nfa_states, num_states, accset, nacc) + int *nfa_states, num_states; + int *accset; + int nacc; +{ + int i, j; + + for (i = 1; i <= num_states; ++i) { + int ns = nfa_states[i]; + int type = state_type[ns]; + int ar = assoc_rule[ns]; + + if (type == STATE_NORMAL || rule_type[ar] != RULE_VARIABLE) { /* do nothing */ + } + + else if (type == STATE_TRAILING_CONTEXT) { + /* Potential trouble. Scan set of accepting numbers + * for the one marking the end of the "head". We + * assume that this looping will be fairly cheap + * since it's rare that an accepting number set + * is large. + */ + for (j = 1; j <= nacc; ++j) + if (accset[j] & YY_TRAILING_HEAD_MASK) { + line_warning (_ + ("dangerous trailing context"), + rule_linenum[ar]); + return; + } + } + } +} + + +/* dump_associated_rules - list the rules associated with a DFA state + * + * Goes through the set of NFA states associated with the DFA and + * extracts the first MAX_ASSOC_RULES unique rules, sorts them, + * and writes a report to the given file. + */ + +void dump_associated_rules (file, ds) + FILE *file; + int ds; +{ + int i, j; + int num_associated_rules = 0; + int rule_set[MAX_ASSOC_RULES + 1]; + int *dset = dss[ds]; + int size = dfasiz[ds]; + + for (i = 1; i <= size; ++i) { + int rule_num = rule_linenum[assoc_rule[dset[i]]]; + + for (j = 1; j <= num_associated_rules; ++j) + if (rule_num == rule_set[j]) + break; + + if (j > num_associated_rules) { /* new rule */ + if (num_associated_rules < MAX_ASSOC_RULES) + rule_set[++num_associated_rules] = + rule_num; + } + } + + qsort (&rule_set [1], num_associated_rules, sizeof (rule_set [1]), intcmp); + + fprintf (file, _(" associated rule line numbers:")); + + for (i = 1; i <= num_associated_rules; ++i) { + if (i % 8 == 1) + putc ('\n', file); + + fprintf (file, "\t%d", rule_set[i]); + } + + putc ('\n', file); +} + + +/* dump_transitions - list the transitions associated with a DFA state + * + * synopsis + * dump_transitions( FILE *file, int state[numecs] ); + * + * Goes through the set of out-transitions and lists them in human-readable + * form (i.e., not as equivalence classes); also lists jam transitions + * (i.e., all those which are not out-transitions, plus EOF). The dump + * is done to the given file. + */ + +void dump_transitions (file, state) + FILE *file; + int state[]; +{ + int i, ec; + int out_char_set[CSIZE]; + + for (i = 0; i < csize; ++i) { + ec = ABS (ecgroup[i]); + out_char_set[i] = state[ec]; + } + + fprintf (file, _(" out-transitions: ")); + + list_character_set (file, out_char_set); + + /* now invert the members of the set to get the jam transitions */ + for (i = 0; i < csize; ++i) + out_char_set[i] = !out_char_set[i]; + + fprintf (file, _("\n jam-transitions: EOF ")); + + list_character_set (file, out_char_set); + + putc ('\n', file); +} + + +/* epsclosure - construct the epsilon closure of a set of ndfa states + * + * synopsis + * int *epsclosure( int t[num_states], int *numstates_addr, + * int accset[num_rules+1], int *nacc_addr, + * int *hashval_addr ); + * + * NOTES + * The epsilon closure is the set of all states reachable by an arbitrary + * number of epsilon transitions, which themselves do not have epsilon + * transitions going out, unioned with the set of states which have non-null + * accepting numbers. t is an array of size numstates of nfa state numbers. + * Upon return, t holds the epsilon closure and *numstates_addr is updated. + * accset holds a list of the accepting numbers, and the size of accset is + * given by *nacc_addr. t may be subjected to reallocation if it is not + * large enough to hold the epsilon closure. + * + * hashval is the hash value for the dfa corresponding to the state set. + */ + +int *epsclosure (t, ns_addr, accset, nacc_addr, hv_addr) + int *t, *ns_addr, accset[], *nacc_addr, *hv_addr; +{ + int stkpos, ns, tsp; + int numstates = *ns_addr, nacc, hashval, transsym, nfaccnum; + int stkend, nstate; + static int did_stk_init = false, *stk; + +#define MARK_STATE(state) \ +do{ trans1[state] = trans1[state] - MARKER_DIFFERENCE;} while(0) + +#define IS_MARKED(state) (trans1[state] < 0) + +#define UNMARK_STATE(state) \ +do{ trans1[state] = trans1[state] + MARKER_DIFFERENCE;} while(0) + +#define CHECK_ACCEPT(state) \ +do{ \ +nfaccnum = accptnum[state]; \ +if ( nfaccnum != NIL ) \ +accset[++nacc] = nfaccnum; \ +}while(0) + +#define DO_REALLOCATION() \ +do { \ +current_max_dfa_size += MAX_DFA_SIZE_INCREMENT; \ +++num_reallocs; \ +t = reallocate_integer_array( t, current_max_dfa_size ); \ +stk = reallocate_integer_array( stk, current_max_dfa_size ); \ +}while(0) \ + +#define PUT_ON_STACK(state) \ +do { \ +if ( ++stkend >= current_max_dfa_size ) \ +DO_REALLOCATION(); \ +stk[stkend] = state; \ +MARK_STATE(state); \ +}while(0) + +#define ADD_STATE(state) \ +do { \ +if ( ++numstates >= current_max_dfa_size ) \ +DO_REALLOCATION(); \ +t[numstates] = state; \ +hashval += state; \ +}while(0) + +#define STACK_STATE(state) \ +do { \ +PUT_ON_STACK(state); \ +CHECK_ACCEPT(state); \ +if ( nfaccnum != NIL || transchar[state] != SYM_EPSILON ) \ +ADD_STATE(state); \ +}while(0) + + + if (!did_stk_init) { + stk = allocate_integer_array (current_max_dfa_size); + did_stk_init = true; + } + + nacc = stkend = hashval = 0; + + for (nstate = 1; nstate <= numstates; ++nstate) { + ns = t[nstate]; + + /* The state could be marked if we've already pushed it onto + * the stack. + */ + if (!IS_MARKED (ns)) { + PUT_ON_STACK (ns); + CHECK_ACCEPT (ns); + hashval += ns; + } + } + + for (stkpos = 1; stkpos <= stkend; ++stkpos) { + ns = stk[stkpos]; + transsym = transchar[ns]; + + if (transsym == SYM_EPSILON) { + tsp = trans1[ns] + MARKER_DIFFERENCE; + + if (tsp != NO_TRANSITION) { + if (!IS_MARKED (tsp)) + STACK_STATE (tsp); + + tsp = trans2[ns]; + + if (tsp != NO_TRANSITION + && !IS_MARKED (tsp)) + STACK_STATE (tsp); + } + } + } + + /* Clear out "visit" markers. */ + + for (stkpos = 1; stkpos <= stkend; ++stkpos) { + if (IS_MARKED (stk[stkpos])) + UNMARK_STATE (stk[stkpos]); + else + flexfatal (_ + ("consistency check failed in epsclosure()")); + } + + *ns_addr = numstates; + *hv_addr = hashval; + *nacc_addr = nacc; + + return t; +} + + +/* increase_max_dfas - increase the maximum number of DFAs */ + +void increase_max_dfas () +{ + current_max_dfas += MAX_DFAS_INCREMENT; + + ++num_reallocs; + + base = reallocate_integer_array (base, current_max_dfas); + def = reallocate_integer_array (def, current_max_dfas); + dfasiz = reallocate_integer_array (dfasiz, current_max_dfas); + accsiz = reallocate_integer_array (accsiz, current_max_dfas); + dhash = reallocate_integer_array (dhash, current_max_dfas); + dss = reallocate_int_ptr_array (dss, current_max_dfas); + dfaacc = reallocate_dfaacc_union (dfaacc, current_max_dfas); + + if (nultrans) + nultrans = + reallocate_integer_array (nultrans, + current_max_dfas); +} + + +/* ntod - convert an ndfa to a dfa + * + * Creates the dfa corresponding to the ndfa we've constructed. The + * dfa starts out in state #1. + */ + +void ntod () +{ + int *accset, ds, nacc, newds; + int sym, hashval, numstates, dsize; + int num_full_table_rows=0; /* used only for -f */ + int *nset, *dset; + int targptr, totaltrans, i, comstate, comfreq, targ; + int symlist[CSIZE + 1]; + int num_start_states; + int todo_head, todo_next; + + struct yytbl_data *yynxt_tbl = 0; + flex_int32_t *yynxt_data = 0, yynxt_curr = 0; + + /* Note that the following are indexed by *equivalence classes* + * and not by characters. Since equivalence classes are indexed + * beginning with 1, even if the scanner accepts NUL's, this + * means that (since every character is potentially in its own + * equivalence class) these arrays must have room for indices + * from 1 to CSIZE, so their size must be CSIZE + 1. + */ + int duplist[CSIZE + 1], state[CSIZE + 1]; + int targfreq[CSIZE + 1], targstate[CSIZE + 1]; + + /* accset needs to be large enough to hold all of the rules present + * in the input, *plus* their YY_TRAILING_HEAD_MASK variants. + */ + accset = allocate_integer_array ((num_rules + 1) * 2); + nset = allocate_integer_array (current_max_dfa_size); + + /* The "todo" queue is represented by the head, which is the DFA + * state currently being processed, and the "next", which is the + * next DFA state number available (not in use). We depend on the + * fact that snstods() returns DFA's \in increasing order/, and thus + * need only know the bounds of the dfas to be processed. + */ + todo_head = todo_next = 0; + + for (i = 0; i <= csize; ++i) { + duplist[i] = NIL; + symlist[i] = false; + } + + for (i = 0; i <= num_rules; ++i) + accset[i] = NIL; + + if (trace) { + dumpnfa (scset[1]); + fputs (_("\n\nDFA Dump:\n\n"), stderr); + } + + inittbl (); + + /* Check to see whether we should build a separate table for + * transitions on NUL characters. We don't do this for full-speed + * (-F) scanners, since for them we don't have a simple state + * number lying around with which to index the table. We also + * don't bother doing it for scanners unless (1) NUL is in its own + * equivalence class (indicated by a positive value of + * ecgroup[NUL]), (2) NUL's equivalence class is the last + * equivalence class, and (3) the number of equivalence classes is + * the same as the number of characters. This latter case comes + * about when useecs is false or when it's true but every character + * still manages to land in its own class (unlikely, but it's + * cheap to check for). If all these things are true then the + * character code needed to represent NUL's equivalence class for + * indexing the tables is going to take one more bit than the + * number of characters, and therefore we won't be assured of + * being able to fit it into a YY_CHAR variable. This rules out + * storing the transitions in a compressed table, since the code + * for interpreting them uses a YY_CHAR variable (perhaps it + * should just use an integer, though; this is worth pondering ... + * ###). + * + * Finally, for full tables, we want the number of entries in the + * table to be a power of two so the array references go fast (it + * will just take a shift to compute the major index). If + * encoding NUL's transitions in the table will spoil this, we + * give it its own table (note that this will be the case if we're + * not using equivalence classes). + */ + + /* Note that the test for ecgroup[0] == numecs below accomplishes + * both (1) and (2) above + */ + if (!fullspd && ecgroup[0] == numecs) { + /* NUL is alone in its equivalence class, which is the + * last one. + */ + int use_NUL_table = (numecs == csize); + + if (fulltbl && !use_NUL_table) { + /* We still may want to use the table if numecs + * is a power of 2. + */ + int power_of_two; + + for (power_of_two = 1; power_of_two <= csize; + power_of_two *= 2) + if (numecs == power_of_two) { + use_NUL_table = true; + break; + } + } + + if (use_NUL_table) + nultrans = + allocate_integer_array (current_max_dfas); + + /* From now on, nultrans != nil indicates that we're + * saving null transitions for later, separate encoding. + */ + } + + + if (fullspd) { + for (i = 0; i <= numecs; ++i) + state[i] = 0; + + place_state (state, 0, 0); + dfaacc[0].dfaacc_state = 0; + } + + else if (fulltbl) { + if (nultrans) + /* We won't be including NUL's transitions in the + * table, so build it for entries from 0 .. numecs - 1. + */ + num_full_table_rows = numecs; + + else + /* Take into account the fact that we'll be including + * the NUL entries in the transition table. Build it + * from 0 .. numecs. + */ + num_full_table_rows = numecs + 1; + + /* Begin generating yy_nxt[][] + * This spans the entire LONG function. + * This table is tricky because we don't know how big it will be. + * So we'll have to realloc() on the way... + * we'll wait until we can calculate yynxt_tbl->td_hilen. + */ + yynxt_tbl = + (struct yytbl_data *) calloc (1, + sizeof (struct + yytbl_data)); + yytbl_data_init (yynxt_tbl, YYTD_ID_NXT); + yynxt_tbl->td_hilen = 1; + yynxt_tbl->td_lolen = num_full_table_rows; + yynxt_tbl->td_data = yynxt_data = + (flex_int32_t *) calloc (yynxt_tbl->td_lolen * + yynxt_tbl->td_hilen, + sizeof (flex_int32_t)); + yynxt_curr = 0; + + buf_prints (&yydmap_buf, + "\t{YYTD_ID_NXT, (void**)&yy_nxt, sizeof(%s)},\n", + long_align ? "flex_int32_t" : "flex_int16_t"); + + /* Unless -Ca, declare it "short" because it's a real + * long-shot that that won't be large enough. + */ + if (gentables) + out_str_dec + ("static yyconst %s yy_nxt[][%d] =\n {\n", + long_align ? "flex_int32_t" : "flex_int16_t", + num_full_table_rows); + else { + out_dec ("#undef YY_NXT_LOLEN\n#define YY_NXT_LOLEN (%d)\n", num_full_table_rows); + out_str ("static yyconst %s *yy_nxt =0;\n", + long_align ? "flex_int32_t" : "flex_int16_t"); + } + + + if (gentables) + outn (" {"); + + /* Generate 0 entries for state #0. */ + for (i = 0; i < num_full_table_rows; ++i) { + mk2data (0); + yynxt_data[yynxt_curr++] = 0; + } + + dataflush (); + if (gentables) + outn (" },\n"); + } + + /* Create the first states. */ + + num_start_states = lastsc * 2; + + for (i = 1; i <= num_start_states; ++i) { + numstates = 1; + + /* For each start condition, make one state for the case when + * we're at the beginning of the line (the '^' operator) and + * one for the case when we're not. + */ + if (i % 2 == 1) + nset[numstates] = scset[(i / 2) + 1]; + else + nset[numstates] = + mkbranch (scbol[i / 2], scset[i / 2]); + + nset = epsclosure (nset, &numstates, accset, &nacc, + &hashval); + + if (snstods (nset, numstates, accset, nacc, hashval, &ds)) { + numas += nacc; + totnst += numstates; + ++todo_next; + + if (variable_trailing_context_rules && nacc > 0) + check_trailing_context (nset, numstates, + accset, nacc); + } + } + + if (!fullspd) { + if (!snstods (nset, 0, accset, 0, 0, &end_of_buffer_state)) + flexfatal (_ + ("could not create unique end-of-buffer state")); + + ++numas; + ++num_start_states; + ++todo_next; + } + + + while (todo_head < todo_next) { + targptr = 0; + totaltrans = 0; + + for (i = 1; i <= numecs; ++i) + state[i] = 0; + + ds = ++todo_head; + + dset = dss[ds]; + dsize = dfasiz[ds]; + + if (trace) + fprintf (stderr, _("state # %d:\n"), ds); + + sympartition (dset, dsize, symlist, duplist); + + for (sym = 1; sym <= numecs; ++sym) { + if (symlist[sym]) { + symlist[sym] = 0; + + if (duplist[sym] == NIL) { + /* Symbol has unique out-transitions. */ + numstates = + symfollowset (dset, dsize, + sym, nset); + nset = epsclosure (nset, + &numstates, + accset, &nacc, + &hashval); + + if (snstods + (nset, numstates, accset, nacc, + hashval, &newds)) { + totnst = totnst + + numstates; + ++todo_next; + numas += nacc; + + if (variable_trailing_context_rules && nacc > 0) + check_trailing_context + (nset, + numstates, + accset, + nacc); + } + + state[sym] = newds; + + if (trace) + fprintf (stderr, + "\t%d\t%d\n", sym, + newds); + + targfreq[++targptr] = 1; + targstate[targptr] = newds; + ++numuniq; + } + + else { + /* sym's equivalence class has the same + * transitions as duplist(sym)'s + * equivalence class. + */ + targ = state[duplist[sym]]; + state[sym] = targ; + + if (trace) + fprintf (stderr, + "\t%d\t%d\n", sym, + targ); + + /* Update frequency count for + * destination state. + */ + + i = 0; + while (targstate[++i] != targ) ; + + ++targfreq[i]; + ++numdup; + } + + ++totaltrans; + duplist[sym] = NIL; + } + } + + + numsnpairs += totaltrans; + + if (ds > num_start_states) + check_for_backing_up (ds, state); + + if (nultrans) { + nultrans[ds] = state[NUL_ec]; + state[NUL_ec] = 0; /* remove transition */ + } + + if (fulltbl) { + + /* Each time we hit here, it's another td_hilen, so we realloc. */ + yynxt_tbl->td_hilen++; + yynxt_tbl->td_data = yynxt_data = + (flex_int32_t *) realloc (yynxt_data, + yynxt_tbl->td_hilen * + yynxt_tbl->td_lolen * + sizeof (flex_int32_t)); + + + if (gentables) + outn (" {"); + + /* Supply array's 0-element. */ + if (ds == end_of_buffer_state) { + mk2data (-end_of_buffer_state); + yynxt_data[yynxt_curr++] = + -end_of_buffer_state; + } + else { + mk2data (end_of_buffer_state); + yynxt_data[yynxt_curr++] = + end_of_buffer_state; + } + + for (i = 1; i < num_full_table_rows; ++i) { + /* Jams are marked by negative of state + * number. + */ + mk2data (state[i] ? state[i] : -ds); + yynxt_data[yynxt_curr++] = + state[i] ? state[i] : -ds; + } + + dataflush (); + if (gentables) + outn (" },\n"); + } + + else if (fullspd) + place_state (state, ds, totaltrans); + + else if (ds == end_of_buffer_state) + /* Special case this state to make sure it does what + * it's supposed to, i.e., jam on end-of-buffer. + */ + stack1 (ds, 0, 0, JAMSTATE); + + else { /* normal, compressed state */ + + /* Determine which destination state is the most + * common, and how many transitions to it there are. + */ + + comfreq = 0; + comstate = 0; + + for (i = 1; i <= targptr; ++i) + if (targfreq[i] > comfreq) { + comfreq = targfreq[i]; + comstate = targstate[i]; + } + + bldtbl (state, ds, totaltrans, comstate, comfreq); + } + } + + if (fulltbl) { + dataend (); + if (tablesext) { + yytbl_data_compress (yynxt_tbl); + if (yytbl_data_fwrite (&tableswr, yynxt_tbl) < 0) + flexerror (_ + ("Could not write yynxt_tbl[][]")); + } + if (yynxt_tbl) { + yytbl_data_destroy (yynxt_tbl); + yynxt_tbl = 0; + } + } + + else if (!fullspd) { + cmptmps (); /* create compressed template entries */ + + /* Create tables for all the states with only one + * out-transition. + */ + while (onesp > 0) { + mk1tbl (onestate[onesp], onesym[onesp], + onenext[onesp], onedef[onesp]); + --onesp; + } + + mkdeftbl (); + } + + free ((void *) accset); + free ((void *) nset); +} + + +/* snstods - converts a set of ndfa states into a dfa state + * + * synopsis + * is_new_state = snstods( int sns[numstates], int numstates, + * int accset[num_rules+1], int nacc, + * int hashval, int *newds_addr ); + * + * On return, the dfa state number is in newds. + */ + +int snstods (sns, numstates, accset, nacc, hashval, newds_addr) + int sns[], numstates, accset[], nacc, hashval, *newds_addr; +{ + int didsort = 0; + int i, j; + int newds, *oldsns; + + for (i = 1; i <= lastdfa; ++i) + if (hashval == dhash[i]) { + if (numstates == dfasiz[i]) { + oldsns = dss[i]; + + if (!didsort) { + /* We sort the states in sns so we + * can compare it to oldsns quickly. + */ + qsort (&sns [1], numstates, sizeof (sns [1]), intcmp); + didsort = 1; + } + + for (j = 1; j <= numstates; ++j) + if (sns[j] != oldsns[j]) + break; + + if (j > numstates) { + ++dfaeql; + *newds_addr = i; + return 0; + } + + ++hshcol; + } + + else + ++hshsave; + } + + /* Make a new dfa. */ + + if (++lastdfa >= current_max_dfas) + increase_max_dfas (); + + newds = lastdfa; + + dss[newds] = allocate_integer_array (numstates + 1); + + /* If we haven't already sorted the states in sns, we do so now, + * so that future comparisons with it can be made quickly. + */ + + if (!didsort) + qsort (&sns [1], numstates, sizeof (sns [1]), intcmp); + + for (i = 1; i <= numstates; ++i) + dss[newds][i] = sns[i]; + + dfasiz[newds] = numstates; + dhash[newds] = hashval; + + if (nacc == 0) { + if (reject) + dfaacc[newds].dfaacc_set = (int *) 0; + else + dfaacc[newds].dfaacc_state = 0; + + accsiz[newds] = 0; + } + + else if (reject) { + /* We sort the accepting set in increasing order so the + * disambiguating rule that the first rule listed is considered + * match in the event of ties will work. + */ + + qsort (&accset [1], nacc, sizeof (accset [1]), intcmp); + + dfaacc[newds].dfaacc_set = + allocate_integer_array (nacc + 1); + + /* Save the accepting set for later */ + for (i = 1; i <= nacc; ++i) { + dfaacc[newds].dfaacc_set[i] = accset[i]; + + if (accset[i] <= num_rules) + /* Who knows, perhaps a REJECT can yield + * this rule. + */ + rule_useful[accset[i]] = true; + } + + accsiz[newds] = nacc; + } + + else { + /* Find lowest numbered rule so the disambiguating rule + * will work. + */ + j = num_rules + 1; + + for (i = 1; i <= nacc; ++i) + if (accset[i] < j) + j = accset[i]; + + dfaacc[newds].dfaacc_state = j; + + if (j <= num_rules) + rule_useful[j] = true; + } + + *newds_addr = newds; + + return 1; +} + + +/* symfollowset - follow the symbol transitions one step + * + * synopsis + * numstates = symfollowset( int ds[current_max_dfa_size], int dsize, + * int transsym, int nset[current_max_dfa_size] ); + */ + +int symfollowset (ds, dsize, transsym, nset) + int ds[], dsize, transsym, nset[]; +{ + int ns, tsp, sym, i, j, lenccl, ch, numstates, ccllist; + + numstates = 0; + + for (i = 1; i <= dsize; ++i) { /* for each nfa state ns in the state set of ds */ + ns = ds[i]; + sym = transchar[ns]; + tsp = trans1[ns]; + + if (sym < 0) { /* it's a character class */ + sym = -sym; + ccllist = cclmap[sym]; + lenccl = ccllen[sym]; + + if (cclng[sym]) { + for (j = 0; j < lenccl; ++j) { + /* Loop through negated character + * class. + */ + ch = ccltbl[ccllist + j]; + + if (ch == 0) + ch = NUL_ec; + + if (ch > transsym) + /* Transsym isn't in negated + * ccl. + */ + break; + + else if (ch == transsym) + /* next 2 */ + goto bottom; + } + + /* Didn't find transsym in ccl. */ + nset[++numstates] = tsp; + } + + else + for (j = 0; j < lenccl; ++j) { + ch = ccltbl[ccllist + j]; + + if (ch == 0) + ch = NUL_ec; + + if (ch > transsym) + break; + else if (ch == transsym) { + nset[++numstates] = tsp; + break; + } + } + } + + else if (sym == SYM_EPSILON) { /* do nothing */ + } + + else if (ABS (ecgroup[sym]) == transsym) + nset[++numstates] = tsp; + + bottom:; + } + + return numstates; +} + + +/* sympartition - partition characters with same out-transitions + * + * synopsis + * sympartition( int ds[current_max_dfa_size], int numstates, + * int symlist[numecs], int duplist[numecs] ); + */ + +void sympartition (ds, numstates, symlist, duplist) + int ds[], numstates; + int symlist[], duplist[]; +{ + int tch, i, j, k, ns, dupfwd[CSIZE + 1], lenccl, cclp, ich; + + /* Partitioning is done by creating equivalence classes for those + * characters which have out-transitions from the given state. Thus + * we are really creating equivalence classes of equivalence classes. + */ + + for (i = 1; i <= numecs; ++i) { /* initialize equivalence class list */ + duplist[i] = i - 1; + dupfwd[i] = i + 1; + } + + duplist[1] = NIL; + dupfwd[numecs] = NIL; + + for (i = 1; i <= numstates; ++i) { + ns = ds[i]; + tch = transchar[ns]; + + if (tch != SYM_EPSILON) { + if (tch < -lastccl || tch >= csize) { + flexfatal (_ + ("bad transition character detected in sympartition()")); + } + + if (tch >= 0) { /* character transition */ + int ec = ecgroup[tch]; + + mkechar (ec, dupfwd, duplist); + symlist[ec] = 1; + } + + else { /* character class */ + tch = -tch; + + lenccl = ccllen[tch]; + cclp = cclmap[tch]; + mkeccl (ccltbl + cclp, lenccl, dupfwd, + duplist, numecs, NUL_ec); + + if (cclng[tch]) { + j = 0; + + for (k = 0; k < lenccl; ++k) { + ich = ccltbl[cclp + k]; + + if (ich == 0) + ich = NUL_ec; + + for (++j; j < ich; ++j) + symlist[j] = 1; + } + + for (++j; j <= numecs; ++j) + symlist[j] = 1; + } + + else + for (k = 0; k < lenccl; ++k) { + ich = ccltbl[cclp + k]; + + if (ich == 0) + ich = NUL_ec; + + symlist[ich] = 1; + } + } + } + } +} diff --git a/third_party/lex/ecs.c b/third_party/lex/ecs.c new file mode 100644 index 00000000..450329a6 --- /dev/null +++ b/third_party/lex/ecs.c @@ -0,0 +1,230 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 sw=8 fenc=utf-8 :vi│ +└─────────────────────────────────────────────────────────────────────────────*/ + +/* clang-format off */ +/* $OpenBSD: ecs.c,v 1.9 2015/11/20 18:54:49 tedu Exp $ */ + +/* ecs - equivalence class routines */ + +/* Copyright (c) 1990 The Regents of the University of California. */ +/* All rights reserved. */ + +/* This code is derived from software contributed to Berkeley by */ +/* Vern Paxson. */ + +/* The United States Government has rights in this work pursuant */ +/* to contract no. DE-AC03-76SF00098 between the United States */ +/* Department of Energy and the University of California. */ + +/* This file is part of flex */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + + +#include "flexdef.h" + +/* ccl2ecl - convert character classes to set of equivalence classes */ + +void +ccl2ecl(void) +{ + int i, ich, newlen, cclp, ccls, cclmec; + + for (i = 1; i <= lastccl; ++i) { + /* + * We loop through each character class, and for each + * character in the class, add the character's equivalence + * class to the new "character" class we are creating. Thus + * when we are all done, character classes will really + * consist of collections of equivalence classes + */ + + newlen = 0; + cclp = cclmap[i]; + + for (ccls = 0; ccls < ccllen[i]; ++ccls) { + ich = ccltbl[cclp + ccls]; + cclmec = ecgroup[ich]; + + if (cclmec > 0) { + ccltbl[cclp + newlen] = cclmec; + ++newlen; + } + } + + ccllen[i] = newlen; + } +} + + +/* cre8ecs - associate equivalence class numbers with class members + * + * fwd is the forward linked-list of equivalence class members. bck + * is the backward linked-list, and num is the number of class members. + * + * Returned is the number of classes. + */ + +int +cre8ecs(int *fwd, int *bck, int num) +{ + int i, j, numcl; + + numcl = 0; + + /* + * Create equivalence class numbers. From now on, ABS( bck(x) ) is + * the equivalence class number for object x. If bck(x) is positive, + * then x is the representative of its equivalence class. + */ + for (i = 1; i <= num; ++i) + if (bck[i] == NIL) { + bck[i] = ++numcl; + for (j = fwd[i]; j != NIL; j = fwd[j]) + bck[j] = -numcl; + } + return numcl; +} + + +/* mkeccl - update equivalence classes based on character class xtions + * + * synopsis + * u_char ccls[]; + * int lenccl, fwd[llsiz], bck[llsiz], llsiz, NUL_mapping; + * void mkeccl( u_char ccls[], int lenccl, int fwd[llsiz], int bck[llsiz], + * int llsiz, int NUL_mapping ); + * + * ccls contains the elements of the character class, lenccl is the + * number of elements in the ccl, fwd is the forward link-list of equivalent + * characters, bck is the backward link-list, and llsiz size of the link-list. + * + * NUL_mapping is the value which NUL (0) should be mapped to. + */ + +void +mkeccl(u_char *ccls, int lenccl, int *fwd, int *bck, int llsiz, int NUL_mapping) +{ + int cclp, oldec, newec; + int cclm, i, j; + static unsigned char cclflags[CSIZE]; /* initialized to all '\0' */ + + /* + * Note that it doesn't matter whether or not the character class is + * negated. The same results will be obtained in either case. + */ + + cclp = 0; + + while (cclp < lenccl) { + cclm = ccls[cclp]; + + if (NUL_mapping && cclm == 0) + cclm = NUL_mapping; + + oldec = bck[cclm]; + newec = cclm; + + j = cclp + 1; + + for (i = fwd[cclm]; i != NIL && i <= llsiz; i = fwd[i]) { + /* look for the symbol in the character class */ + for (; j < lenccl; ++j) { + int ccl_char; + + if (NUL_mapping && ccls[j] == 0) + ccl_char = NUL_mapping; + else + ccl_char = ccls[j]; + + if (ccl_char > i) + break; + + if (ccl_char == i && !cclflags[j]) { + /* + * We found an old companion of cclm + * in the ccl. Link it into the new + * equivalence class and flag it as + * having been processed. + */ + + bck[i] = newec; + fwd[newec] = i; + newec = i; + /* Set flag so we don't reprocess. */ + cclflags[j] = 1; + + /* Get next equivalence class member. */ + /* continue 2 */ + goto next_pt; + } + } + + /* + * Symbol isn't in character class. Put it in the + * old equivalence class. + */ + + bck[i] = oldec; + + if (oldec != NIL) + fwd[oldec] = i; + + oldec = i; + + next_pt: ; + } + + if (bck[cclm] != NIL || oldec != bck[cclm]) { + bck[cclm] = NIL; + fwd[oldec] = NIL; + } + fwd[newec] = NIL; + + /* Find next ccl member to process. */ + + for (++cclp; cclflags[cclp] && cclp < lenccl; ++cclp) { + /* Reset "doesn't need processing" flag. */ + cclflags[cclp] = 0; + } + } +} + + +/* mkechar - create equivalence class for single character */ + +void +mkechar(int tch, int *fwd, int *bck) +{ + /* + * If until now the character has been a proper subset of an + * equivalence class, break it away to create a new ec + */ + + if (fwd[tch] != NIL) + bck[fwd[tch]] = bck[tch]; + + if (bck[tch] != NIL) + fwd[bck[tch]] = fwd[tch]; + + fwd[tch] = NIL; + bck[tch] = NIL; +} diff --git a/third_party/lex/filter.c b/third_party/lex/filter.c new file mode 100644 index 00000000..f60300fe --- /dev/null +++ b/third_party/lex/filter.c @@ -0,0 +1,452 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 sw=8 fenc=utf-8 :vi│ +└─────────────────────────────────────────────────────────────────────────────*/ +/* clang-format off */ +/* $OpenBSD: filter.c,v 1.9 2017/08/30 02:54:07 lteo Exp $ */ + +/* filter - postprocessing of flex output through filters */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + +#include "libc/mem/mem.h" +#include "libc/calls/calls.h" +#include "libc/calls/calls.h" +#include "libc/str/str.h" +#include "libc/fmt/fmt.h" +#include "libc/calls/calls.h" +#include "libc/runtime/runtime.h" +#include "libc/log/log.h" +#include "flexdef.h" + +const char *check_4_gnu_m4 = +"m4_dnl ifdef(`__gnu__', ," +"`errprint(Flex requires GNU M4. Set the PATH or set the M4 environment variable to its path name.)" +" m4exit(2)')\n"; + + +/** global chain. */ +struct filter *output_chain = NULL; + +/* Allocate and initialize an external filter. + * @param chain the current chain or NULL for new chain + * @param cmd the command to execute. + * @param ... a NULL terminated list of (const char*) arguments to command, + * not including argv[0]. + * @return newest filter in chain + */ +struct filter * +filter_create_ext(struct filter * chain, const char *cmd, + ...) +{ + struct filter *f; + int max_args; + const char *s; + va_list ap; + + /* allocate and initialize new filter */ + f = calloc(sizeof(struct filter), 1); + if (!f) + flexerror(_("calloc failed (f) in filter_create_ext")); + f->filter_func = NULL; + f->extra = NULL; + f->next = NULL; + f->argc = 0; + + if (chain != NULL) { + /* append f to end of chain */ + while (chain->next) + chain = chain->next; + chain->next = f; + } + /* allocate argv, and populate it with the argument list. */ + max_args = 8; + f->argv = malloc(sizeof(char *) * (max_args + 1)); + if (!f->argv) + flexerror(_("malloc failed (f->argv) in filter_create_ext")); + f->argv[f->argc++] = cmd; + + va_start(ap, cmd); + while ((s = va_arg(ap, const char *)) != NULL) { + if (f->argc >= max_args) { + max_args += 8; + f->argv = realloc(f->argv, + sizeof(char *) * (max_args + 1)); + } + f->argv[f->argc++] = s; + } + f->argv[f->argc] = NULL; + + va_end(ap); + return f; +} + +/* Allocate and initialize an internal filter. + * @param chain the current chain or NULL for new chain + * @param filter_func The function that will perform the filtering. + * filter_func should return 0 if successful, and -1 + * if an error occurs -- or it can simply exit(). + * @param extra optional user-defined data to pass to the filter. + * @return newest filter in chain + */ +struct filter * +filter_create_int(struct filter * chain, + int (*filter_func) (struct filter *), + void *extra) +{ + struct filter *f; + + /* allocate and initialize new filter */ + f = calloc(sizeof(struct filter), 1); + if (!f) + flexerror(_("calloc failed in filter_create_int")); + f->next = NULL; + f->argc = 0; + f->argv = NULL; + + f->filter_func = filter_func; + f->extra = extra; + + if (chain != NULL) { + /* append f to end of chain */ + while (chain->next) + chain = chain->next; + chain->next = f; + } + return f; +} + +/** Fork and exec entire filter chain. + * @param chain The head of the chain. + * @return true on success. + */ +bool +filter_apply_chain(struct filter * chain) +{ + int pid; + int pipes[2]; + + /* + * Tricky recursion, since we want to begin the chain at the END. + * Why? Because we need all the forked processes to be children of + * the main flex process. + */ + if (chain) + filter_apply_chain(chain->next); + else + return true; + + /* + * Now we are the right-most unprocessed link in the chain. + */ + + fflush(stdout); + fflush(stderr); + + + if (pipe(pipes) == -1) + flexerror(_("pipe failed")); + + if ((pid = fork()) == -1) + flexerror(_("fork failed")); + + if (pid == 0) { + /* child */ + + /* + * We need stdin (the FILE* stdin) to connect to this new + * pipe. There is no portable way to set stdin to a new file + * descriptor, as stdin is not an lvalue on some systems + * (BSD). So we dup the new pipe onto the stdin descriptor + * and use a no-op fseek to sync the stream. This is a Hail + * Mary situation. It seems to work. + */ + close(pipes[1]); + clearerr(stdin); + if (dup2(pipes[0], fileno(stdin)) == -1) + flexfatal(_("dup2(pipes[0],0)")); + close(pipes[0]); + fseek(stdin, 0, SEEK_CUR); + + /* run as a filter, either internally or by exec */ + if (chain->filter_func) { + if (chain->filter_func(chain) == -1) + flexfatal(_("filter_func failed")); + exit(0); + } else { + execvp(chain->argv[0], + (char **const) (chain->argv)); + lerrsf_fatal(_("exec of %s failed"), + chain->argv[0]); + } + + exit(1); + } + /* Parent */ + close(pipes[0]); + if (dup2(pipes[1], fileno(stdout)) == -1) + flexfatal(_("dup2(pipes[1],1)")); + close(pipes[1]); + fseek(stdout, 0, SEEK_CUR); + + return true; +} + +/** Truncate the chain to max_len number of filters. + * @param chain the current chain. + * @param max_len the maximum length of the chain. + * @return the resulting length of the chain. + */ +int +filter_truncate(struct filter * chain, int max_len) +{ + int len = 1; + + if (!chain) + return 0; + + while (chain->next && len < max_len) { + chain = chain->next; + ++len; + } + + chain->next = NULL; + return len; +} + +/** Splits the chain in order to write to a header file. + * Similar in spirit to the 'tee' program. + * The header file name is in extra. + * @return 0 (zero) on success, and -1 on failure. + */ +int +filter_tee_header(struct filter * chain) +{ + /* + * This function reads from stdin and writes to both the C file and + * the header file at the same time. + */ + + const int readsz = 512; + char *buf; + int to_cfd = -1; + FILE *to_c = NULL, *to_h = NULL; + bool write_header; + + write_header = (chain->extra != NULL); + + /* + * Store a copy of the stdout pipe, which is already piped to C file + * through the running chain. Then create a new pipe to the H file as + * stdout, and fork the rest of the chain again. + */ + + if ((to_cfd = dup(1)) == -1) + flexfatal(_("dup(1) failed")); + to_c = fdopen(to_cfd, "w"); + + if (write_header) { + if (freopen((char *) chain->extra, "w", stdout) == NULL) + flexfatal(_("freopen(headerfilename) failed")); + + filter_apply_chain(chain->next); + to_h = stdout; + } + /* + * Now to_c is a pipe to the C branch, and to_h is a pipe to the H + * branch. + */ + + if (write_header) { + /* fputs(check_4_gnu_m4, to_h); */ + fputs("m4_changecom`'m4_dnl\n", to_h); + fputs("m4_changequote`'m4_dnl\n", to_h); + fputs("m4_changequote([[,]])[[]]m4_dnl\n", to_h); + fputs("m4_define([[M4_YY_NOOP]])[[]]m4_dnl\n", to_h); + fputs("m4_define( [[M4_YY_IN_HEADER]],[[]])m4_dnl\n", + to_h); + fprintf(to_h, "#ifndef %sHEADER_H\n", prefix); + fprintf(to_h, "#define %sHEADER_H 1\n", prefix); + fprintf(to_h, "#define %sIN_HEADER 1\n\n", prefix); + fprintf(to_h, + "m4_define( [[M4_YY_OUTFILE_NAME]],[[%s]])m4_dnl\n", + headerfilename ? headerfilename : ""); + + } + /* fputs(check_4_gnu_m4, to_c); */ + fputs("m4_changecom`'m4_dnl\n", to_c); + fputs("m4_changequote`'m4_dnl\n", to_c); + fputs("m4_changequote([[,]])[[]]m4_dnl\n", to_c); + fputs("m4_define([[M4_YY_NOOP]])[[]]m4_dnl\n", to_c); + fprintf(to_c, "m4_define( [[M4_YY_OUTFILE_NAME]],[[%s]])m4_dnl\n", + outfilename ? outfilename : ""); + + buf = malloc(readsz); + if (!buf) + flexerror(_("malloc failed in filter_tee_header")); + while (fgets(buf, readsz, stdin)) { + fputs(buf, to_c); + if (write_header) + fputs(buf, to_h); + } + + if (write_header) { + fprintf(to_h, "\n"); + + /* + * write a fake line number. It will get fixed by the linedir + * filter. + */ + fprintf(to_h, "#line 4000 \"M4_YY_OUTFILE_NAME\"\n"); + + fprintf(to_h, "#undef %sIN_HEADER\n", prefix); + fprintf(to_h, "#endif /* %sHEADER_H */\n", prefix); + fputs("m4_undefine( [[M4_YY_IN_HEADER]])m4_dnl\n", to_h); + + fflush(to_h); + if (ferror(to_h)) + lerrsf(_("error writing output file %s"), + (char *) chain->extra); + + else if (fclose(to_h)) + lerrsf(_("error closing output file %s"), + (char *) chain->extra); + } + fflush(to_c); + if (ferror(to_c)) + lerrsf(_("error writing output file %s"), + outfilename ? outfilename : ""); + + else if (fclose(to_c)) + lerrsf(_("error closing output file %s"), + outfilename ? outfilename : ""); + + while (wait(0) > 0); + + exit(0); + return 0; +} + +/** Adjust the line numbers in the #line directives of the generated scanner. + * After the m4 expansion, the line numbers are incorrect since the m4 macros + * can add or remove lines. This only adjusts line numbers for generated code, + * not user code. This also happens to be a good place to squeeze multiple + * blank lines into a single blank line. + */ +int +filter_fix_linedirs(struct filter * chain) +{ + char *buf; + const int readsz = 512 + MAXLINE; + int lineno = 1; + bool in_gen = true; /* in generated code */ + bool last_was_blank = false; + + if (!chain) + return 0; + + buf = malloc(readsz); + if (!buf) + flexerror(_("malloc failed in filter_fix_linedirs")); + + while (fgets(buf, readsz, stdin)) { + + regmatch_t m[10]; + + /* Check for #line directive. */ + if (buf[0] == '#' + && regexec(®ex_linedir, buf, 3, m, 0) == 0) { + + int num; + char *fname; + + /* extract the line number and filename */ + num = regmatch_strtol(&m[1], buf, NULL, 0); + fname = regmatch_dup(&m[2], buf); + + /* TODO(jart): Why isn't num being used? */ + (void)num; + + if (strcmp(fname, + outfilename ? outfilename : "") == 0 || + strcmp(fname, headerfilename ? headerfilename : + "") == 0) { + + char *s1, *s2; + char filename[MAXLINE]; + + s1 = fname; + s2 = filename; + + while ((s2 - filename) < (MAXLINE - 1) && *s1) { + /* Escape the backslash */ + if (*s1 == '\\') + *s2++ = '\\'; + /* Escape the double quote */ + if (*s1 == '\"') + *s2++ = '\\'; + /* Copy the character as usual */ + *s2++ = *s1++; + } + + *s2 = '\0'; + + /* Adjust the line directives. */ + in_gen = true; + snprintf(buf, readsz, "#line %d \"%s\"\n", + lineno + 1, filename); + } else { + /* + * it's a #line directive for code we didn't + * write + */ + in_gen = false; + } + + free(fname); + last_was_blank = false; + } + /* squeeze blank lines from generated code */ + else if (in_gen && + regexec(®ex_blank_line, buf, 0, NULL, 0) == 0) { + if (last_was_blank) + continue; + else + last_was_blank = true; + } else { + /* it's a line of normal, non-empty code. */ + last_was_blank = false; + } + + fputs(buf, stdout); + lineno++; + } + fflush(stdout); + if (ferror(stdout)) + lerrsf(_("error writing output file %s"), + outfilename ? outfilename : ""); + + else if (fclose(stdout)) + lerrsf(_("error closing output file %s"), + outfilename ? outfilename : ""); + + return 0; +} diff --git a/third_party/lex/flex.1 b/third_party/lex/flex.1 new file mode 100644 index 00000000..138765cb --- /dev/null +++ b/third_party/lex/flex.1 @@ -0,0 +1,4438 @@ +.\" $OpenBSD: flex.1,v 1.43 2015/09/21 10:03:46 jmc Exp $ +.\" +.\" Copyright (c) 1990 The Regents of the University of California. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Vern Paxson. +.\" +.\" The United States Government has rights in this work pursuant +.\" to contract no. DE-AC03-76SF00098 between the United States +.\" Department of Energy and the University of California. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE. +.\" +.Dd $Mdocdate: September 21 2015 $ +.Dt FLEX 1 +.Os +.Sh NAME +.Nm flex , +.Nm flex++ , +.Nm lex +.Nd fast lexical analyzer generator +.Sh SYNOPSIS +.Nm +.Bk -words +.Op Fl 78BbdFfhIiLlnpsTtVvw+? +.Op Fl C Ns Op Cm aeFfmr +.Op Fl Fl help +.Op Fl Fl version +.Op Fl o Ns Ar output +.Op Fl P Ns Ar prefix +.Op Fl S Ns Ar skeleton +.Op Ar +.Ek +.Sh DESCRIPTION +.Nm +is a tool for generating +.Em scanners : +programs which recognize lexical patterns in text. +.Nm +reads the given input files, or its standard input if no file names are given, +for a description of a scanner to generate. +The description is in the form of pairs of regular expressions and C code, +called +.Em rules . +.Nm +generates as output a C source file, +.Pa lex.yy.c , +which defines a routine +.Fn yylex . +This file is compiled and linked with the +.Fl lfl +library to produce an executable. +When the executable is run, it analyzes its input for occurrences +of the regular expressions. +Whenever it finds one, it executes the corresponding C code. +.Pp +.Nm lex +is a synonym for +.Nm flex . +.Nm flex++ +is a synonym for +.Nm +.Fl + . +.Pp +The manual includes both tutorial and reference sections: +.Bl -ohang +.It Sy Some Simple Examples +.It Sy Format of the Input File +.It Sy Patterns +The extended regular expressions used by +.Nm . +.It Sy How the Input is Matched +The rules for determining what has been matched. +.It Sy Actions +How to specify what to do when a pattern is matched. +.It Sy The Generated Scanner +Details regarding the scanner that +.Nm +produces; +how to control the input source. +.It Sy Start Conditions +Introducing context into scanners, and managing +.Qq mini-scanners . +.It Sy Multiple Input Buffers +How to manipulate multiple input sources; +how to scan from strings instead of files. +.It Sy End-of-File Rules +Special rules for matching the end of the input. +.It Sy Miscellaneous Macros +A summary of macros available to the actions. +.It Sy Values Available to the User +A summary of values available to the actions. +.It Sy Interfacing with Yacc +Connecting flex scanners together with +.Xr yacc 1 +parsers. +.It Sy Options +.Nm +command-line options, and the +.Dq %option +directive. +.It Sy Performance Considerations +How to make scanners go as fast as possible. +.It Sy Generating C++ Scanners +The +.Pq experimental +facility for generating C++ scanner classes. +.It Sy Incompatibilities with Lex and POSIX +How +.Nm +differs from +.At +.Nm lex +and the +.Tn POSIX +.Nm lex +standard. +.It Sy Files +Files used by +.Nm . +.It Sy Diagnostics +Those error messages produced by +.Nm +.Pq or scanners it generates +whose meanings might not be apparent. +.It Sy See Also +Other documentation, related tools. +.It Sy Authors +Includes contact information. +.It Sy Bugs +Known problems with +.Nm . +.El +.Sh SOME SIMPLE EXAMPLES +First some simple examples to get the flavor of how one uses +.Nm . +The following +.Nm +input specifies a scanner which whenever it encounters the string +.Qq username +will replace it with the user's login name: +.Bd -literal -offset indent +%% +username printf("%s", getlogin()); +.Ed +.Pp +By default, any text not matched by a +.Nm +scanner is copied to the output, so the net effect of this scanner is +to copy its input file to its output with each occurrence of +.Qq username +expanded. +In this input, there is just one rule. +.Qq username +is the +.Em pattern +and the +.Qq printf +is the +.Em action . +The +.Qq %% +marks the beginning of the rules. +.Pp +Here's another simple example: +.Bd -literal -offset indent +%{ +int num_lines = 0, num_chars = 0; +%} + +%% +\en ++num_lines; ++num_chars; +\&. ++num_chars; + +%% +main() +{ + yylex(); + printf("# of lines = %d, # of chars = %d\en", + num_lines, num_chars); +} +.Ed +.Pp +This scanner counts the number of characters and the number +of lines in its input +(it produces no output other than the final report on the counts). +The first line declares two globals, +.Qq num_lines +and +.Qq num_chars , +which are accessible both inside +.Fn yylex +and in the +.Fn main +routine declared after the second +.Qq %% . +There are two rules, one which matches a newline +.Pq \&"\en\&" +and increments both the line count and the character count, +and one which matches any character other than a newline +(indicated by the +.Qq \&. +regular expression). +.Pp +A somewhat more complicated example: +.Bd -literal -offset indent +/* scanner for a toy Pascal-like language */ + +%{ +/* need this for the call to atof() below */ +#include +%} + +DIGIT [0-9] +ID [a-z][a-z0-9]* + +%% + +{DIGIT}+ { + printf("An integer: %s (%d)\en", yytext, + atoi(yytext)); +} + +{DIGIT}+"."{DIGIT}* { + printf("A float: %s (%g)\en", yytext, + atof(yytext)); +} + +if|then|begin|end|procedure|function { + printf("A keyword: %s\en", yytext); +} + +{ID} printf("An identifier: %s\en", yytext); + +"+"|"-"|"*"|"/" printf("An operator: %s\en", yytext); + +"{"[^}\en]*"}" /* eat up one-line comments */ + +[ \et\en]+ /* eat up whitespace */ + +\&. printf("Unrecognized character: %s\en", yytext); + +%% + +main(int argc, char *argv[]) +{ + ++argv; --argc; /* skip over program name */ + if (argc > 0) + yyin = fopen(argv[0], "r"); + else + yyin = stdin; + + yylex(); +} +.Ed +.Pp +This is the beginnings of a simple scanner for a language like Pascal. +It identifies different types of +.Em tokens +and reports on what it has seen. +.Pp +The details of this example will be explained in the following sections. +.Sh FORMAT OF THE INPUT FILE +The +.Nm +input file consists of three sections, separated by a line with just +.Qq %% +in it: +.Bd -unfilled -offset indent +definitions +%% +rules +%% +user code +.Ed +.Pp +The +.Em definitions +section contains declarations of simple +.Em name +definitions to simplify the scanner specification, and declarations of +.Em start conditions , +which are explained in a later section. +.Pp +Name definitions have the form: +.Pp +.D1 name definition +.Pp +The +.Qq name +is a word beginning with a letter or an underscore +.Pq Sq _ +followed by zero or more letters, digits, +.Sq _ , +or +.Sq - +.Pq dash . +The definition is taken to begin at the first non-whitespace character +following the name and continuing to the end of the line. +The definition can subsequently be referred to using +.Qq {name} , +which will expand to +.Qq (definition) . +For example: +.Bd -literal -offset indent +DIGIT [0-9] +ID [a-z][a-z0-9]* +.Ed +.Pp +This defines +.Qq DIGIT +to be a regular expression which matches a single digit, and +.Qq ID +to be a regular expression which matches a letter +followed by zero-or-more letters-or-digits. +A subsequent reference to +.Pp +.Dl {DIGIT}+"."{DIGIT}* +.Pp +is identical to +.Pp +.Dl ([0-9])+"."([0-9])* +.Pp +and matches one-or-more digits followed by a +.Sq .\& +followed by zero-or-more digits. +.Pp +The +.Em rules +section of the +.Nm +input contains a series of rules of the form: +.Pp +.Dl pattern action +.Pp +The pattern must be unindented and the action must begin +on the same line. +.Pp +See below for a further description of patterns and actions. +.Pp +Finally, the user code section is simply copied to +.Pa lex.yy.c +verbatim. +It is used for companion routines which call or are called by the scanner. +The presence of this section is optional; +if it is missing, the second +.Qq %% +in the input file may be skipped too. +.Pp +In the definitions and rules sections, any indented text or text enclosed in +.Sq %{ +and +.Sq %} +is copied verbatim to the output +.Pq with the %{}'s removed . +The %{}'s must appear unindented on lines by themselves. +.Pp +In the rules section, +any indented or %{} text appearing before the first rule may be used to +declare variables which are local to the scanning routine and +.Pq after the declarations +code which is to be executed whenever the scanning routine is entered. +Other indented or %{} text in the rule section is still copied to the output, +but its meaning is not well-defined and it may well cause compile-time +errors (this feature is present for +.Tn POSIX +compliance; see below for other such features). +.Pp +In the definitions section +.Pq but not in the rules section , +an unindented comment +(i.e., a line beginning with +.Qq /* ) +is also copied verbatim to the output up to the next +.Qq */ . +.Sh PATTERNS +The patterns in the input are written using an extended set of regular +expressions. +These are: +.Bl -tag -width "XXXXXXXX" +.It x +Match the character +.Sq x . +.It .\& +Any character +.Pq byte +except newline. +.It [xyz] +A +.Qq character class ; +in this case, the pattern matches either an +.Sq x , +a +.Sq y , +or a +.Sq z . +.It [abj-oZ] +A +.Qq character class +with a range in it; matches an +.Sq a , +a +.Sq b , +any letter from +.Sq j +through +.Sq o , +or a +.Sq Z . +.It [^A-Z] +A +.Qq negated character class , +i.e., any character but those in the class. +In this case, any character EXCEPT an uppercase letter. +.It [^A-Z\en] +Any character EXCEPT an uppercase letter or a newline. +.It r* +Zero or more r's, where +.Sq r +is any regular expression. +.It r+ +One or more r's. +.It r? +Zero or one r's (that is, +.Qq an optional r ) . +.It r{2,5} +Anywhere from two to five r's. +.It r{2,} +Two or more r's. +.It r{4} +Exactly 4 r's. +.It {name} +The expansion of the +.Qq name +definition +.Pq see above . +.It \&"[xyz]\e\&"foo\&" +The literal string: [xyz]"foo. +.It \eX +If +.Sq X +is an +.Sq a , +.Sq b , +.Sq f , +.Sq n , +.Sq r , +.Sq t , +or +.Sq v , +then the ANSI-C interpretation of +.Sq \eX . +Otherwise, a literal +.Sq X +(used to escape operators such as +.Sq * ) . +.It \e0 +A NUL character +.Pq ASCII code 0 . +.It \e123 +The character with octal value 123. +.It \ex2a +The character with hexadecimal value 2a. +.It (r) +Match an +.Sq r ; +parentheses are used to override precedence +.Pq see below . +.It rs +The regular expression +.Sq r +followed by the regular expression +.Sq s ; +called +.Qq concatenation . +.It r|s +Either an +.Sq r +or an +.Sq s . +.It r/s +An +.Sq r , +but only if it is followed by an +.Sq s . +The text matched by +.Sq s +is included when determining whether this rule is the +.Qq longest match , +but is then returned to the input before the action is executed. +So the action only sees the text matched by +.Sq r . +This type of pattern is called +.Qq trailing context . +(There are some combinations of r/s that +.Nm +cannot match correctly; see notes in the +.Sx BUGS +section below regarding +.Qq dangerous trailing context . ) +.It ^r +An +.Sq r , +but only at the beginning of a line +(i.e., just starting to scan, or right after a newline has been scanned). +.It r$ +An +.Sq r , +but only at the end of a line +.Pq i.e., just before a newline . +Equivalent to +.Qq r/\en . +.Pp +Note that +.Nm flex Ns 's +notion of +.Qq newline +is exactly whatever the C compiler used to compile +.Nm +interprets +.Sq \en +as. +.\" In particular, on some DOS systems you must either filter out \er's in the +.\" input yourself, or explicitly use r/\er\en for +.\" .Qq r$ . +.It r +An +.Sq r , +but only in start condition +.Sq s +.Pq see below for discussion of start conditions . +.It r +The same, but in any of start conditions s1, s2, or s3. +.It <*>r +An +.Sq r +in any start condition, even an exclusive one. +.It <> +An end-of-file. +.It <> +An end-of-file when in start condition s1 or s2. +.El +.Pp +Note that inside of a character class, all regular expression operators +lose their special meaning except escape +.Pq Sq \e +and the character class operators, +.Sq - , +.Sq ]\& , +and, at the beginning of the class, +.Sq ^ . +.Pp +The regular expressions listed above are grouped according to +precedence, from highest precedence at the top to lowest at the bottom. +Those grouped together have equal precedence. +For example, +.Pp +.D1 foo|bar* +.Pp +is the same as +.Pp +.D1 (foo)|(ba(r*)) +.Pp +since the +.Sq * +operator has higher precedence than concatenation, +and concatenation higher than alternation +.Pq Sq |\& . +This pattern therefore matches +.Em either +the string +.Qq foo +.Em or +the string +.Qq ba +followed by zero-or-more r's. +To match +.Qq foo +or zero-or-more "bar"'s, +use: +.Pp +.D1 foo|(bar)* +.Pp +and to match zero-or-more "foo"'s-or-"bar"'s: +.Pp +.D1 (foo|bar)* +.Pp +In addition to characters and ranges of characters, character classes +can also contain character class +.Em expressions . +These are expressions enclosed inside +.Sq [: +and +.Sq :] +delimiters (which themselves must appear between the +.Sq \&[ +and +.Sq ]\& +of the +character class; other elements may occur inside the character class, too). +The valid expressions are: +.Bd -unfilled -offset indent +[:alnum:] [:alpha:] [:blank:] +[:cntrl:] [:digit:] [:graph:] +[:lower:] [:print:] [:punct:] +[:space:] [:upper:] [:xdigit:] +.Ed +.Pp +These expressions all designate a set of characters equivalent to +the corresponding standard C +.Fn isXXX +function. +For example, [:alnum:] designates those characters for which +.Xr isalnum 3 +returns true \- i.e., any alphabetic or numeric. +Some systems don't provide +.Xr isblank 3 , +so +.Nm +defines [:blank:] as a blank or a tab. +.Pp +For example, the following character classes are all equivalent: +.Bd -unfilled -offset indent +[[:alnum:]] +[[:alpha:][:digit:]] +[[:alpha:]0-9] +[a-zA-Z0-9] +.Ed +.Pp +If the scanner is case-insensitive (the +.Fl i +flag), then [:upper:] and [:lower:] are equivalent to [:alpha:]. +.Pp +Some notes on patterns: +.Bl -dash +.It +A negated character class such as the example +.Qq [^A-Z] +above will match a newline unless "\en" +.Pq or an equivalent escape sequence +is one of the characters explicitly present in the negated character class +(e.g., +.Qq [^A-Z\en] ) . +This is unlike how many other regular expression tools treat negated character +classes, but unfortunately the inconsistency is historically entrenched. +Matching newlines means that a pattern like +.Qq [^"]* +can match the entire input unless there's another quote in the input. +.It +A rule can have at most one instance of trailing context +(the +.Sq / +operator or the +.Sq $ +operator). +The start condition, +.Sq ^ , +and +.Qq <> +patterns can only occur at the beginning of a pattern and, as well as with +.Sq / +and +.Sq $ , +cannot be grouped inside parentheses. +A +.Sq ^ +which does not occur at the beginning of a rule or a +.Sq $ +which does not occur at the end of a rule loses its special properties +and is treated as a normal character. +.It +The following are illegal: +.Bd -unfilled -offset indent +foo/bar$ +foobar +.Ed +.Pp +Note that the first of these, can be written +.Qq foo/bar\en . +.It +The following will result in +.Sq $ +or +.Sq ^ +being treated as a normal character: +.Bd -unfilled -offset indent +foo|(bar$) +foo|^bar +.Ed +.Pp +If what's wanted is a +.Qq foo +or a bar-followed-by-a-newline, the following could be used +(the special +.Sq |\& +action is explained below): +.Bd -unfilled -offset indent +foo | +bar$ /* action goes here */ +.Ed +.Pp +A similar trick will work for matching a foo or a +bar-at-the-beginning-of-a-line. +.El +.Sh HOW THE INPUT IS MATCHED +When the generated scanner is run, +it analyzes its input looking for strings which match any of its patterns. +If it finds more than one match, +it takes the one matching the most text +(for trailing context rules, this includes the length of the trailing part, +even though it will then be returned to the input). +If it finds two or more matches of the same length, +the rule listed first in the +.Nm +input file is chosen. +.Pp +Once the match is determined, the text corresponding to the match +(called the +.Em token ) +is made available in the global character pointer +.Fa yytext , +and its length in the global integer +.Fa yyleng . +The +.Em action +corresponding to the matched pattern is then executed +.Pq a more detailed description of actions follows , +and then the remaining input is scanned for another match. +.Pp +If no match is found, then the default rule is executed: +the next character in the input is considered matched and +copied to the standard output. +Thus, the simplest legal +.Nm +input is: +.Pp +.D1 %% +.Pp +which generates a scanner that simply copies its input +.Pq one character at a time +to its output. +.Pp +Note that +.Fa yytext +can be defined in two different ways: +either as a character pointer or as a character array. +Which definition +.Nm +uses can be controlled by including one of the special directives +.Dq %pointer +or +.Dq %array +in the first +.Pq definitions +section of flex input. +The default is +.Dq %pointer , +unless the +.Fl l +.Nm lex +compatibility option is used, in which case +.Fa yytext +will be an array. +The advantage of using +.Dq %pointer +is substantially faster scanning and no buffer overflow when matching +very large tokens +.Pq unless not enough dynamic memory is available . +The disadvantage is that actions are restricted in how they can modify +.Fa yytext +.Pq see the next section , +and calls to the +.Fn unput +function destroy the present contents of +.Fa yytext , +which can be a considerable porting headache when moving between different +.Nm lex +versions. +.Pp +The advantage of +.Dq %array +is that +.Fa yytext +can be modified as much as wanted, and calls to +.Fn unput +do not destroy +.Fa yytext +.Pq see below . +Furthermore, existing +.Nm lex +programs sometimes access +.Fa yytext +externally using declarations of the form: +.Pp +.D1 extern char yytext[]; +.Pp +This definition is erroneous when used with +.Dq %pointer , +but correct for +.Dq %array . +.Pp +.Dq %array +defines +.Fa yytext +to be an array of +.Dv YYLMAX +characters, which defaults to a fairly large value. +The size can be changed by simply #define'ing +.Dv YYLMAX +to a different value in the first section of +.Nm +input. +As mentioned above, with +.Dq %pointer +yytext grows dynamically to accommodate large tokens. +While this means a +.Dq %pointer +scanner can accommodate very large tokens +.Pq such as matching entire blocks of comments , +bear in mind that each time the scanner must resize +.Fa yytext +it also must rescan the entire token from the beginning, so matching such +tokens can prove slow. +.Fa yytext +presently does not dynamically grow if a call to +.Fn unput +results in too much text being pushed back; instead, a run-time error results. +.Pp +Also note that +.Dq %array +cannot be used with C++ scanner classes +.Pq the c++ option; see below . +.Sh ACTIONS +Each pattern in a rule has a corresponding action, +which can be any arbitrary C statement. +The pattern ends at the first non-escaped whitespace character; +the remainder of the line is its action. +If the action is empty, +then when the pattern is matched the input token is simply discarded. +For example, here is the specification for a program +which deletes all occurrences of +.Qq zap me +from its input: +.Bd -literal -offset indent +%% +"zap me" +.Ed +.Pp +(It will copy all other characters in the input to the output since +they will be matched by the default rule.) +.Pp +Here is a program which compresses multiple blanks and tabs down to +a single blank, and throws away whitespace found at the end of a line: +.Bd -literal -offset indent +%% +[ \et]+ putchar(' '); +[ \et]+$ /* ignore this token */ +.Ed +.Pp +If the action contains a +.Sq { , +then the action spans till the balancing +.Sq } +is found, and the action may cross multiple lines. +.Nm +knows about C strings and comments and won't be fooled by braces found +within them, but also allows actions to begin with +.Sq %{ +and will consider the action to be all the text up to the next +.Sq %} +.Pq regardless of ordinary braces inside the action . +.Pp +An action consisting solely of a vertical bar +.Pq Sq |\& +means +.Qq same as the action for the next rule . +See below for an illustration. +.Pp +Actions can include arbitrary C code, +including return statements to return a value to whatever routine called +.Fn yylex . +Each time +.Fn yylex +is called, it continues processing tokens from where it last left off +until it either reaches the end of the file or executes a return. +.Pp +Actions are free to modify +.Fa yytext +except for lengthening it +(adding characters to its end \- these will overwrite later characters in the +input stream). +This, however, does not apply when using +.Dq %array +.Pq see above ; +in that case, +.Fa yytext +may be freely modified in any way. +.Pp +Actions are free to modify +.Fa yyleng +except they should not do so if the action also includes use of +.Fn yymore +.Pq see below . +.Pp +There are a number of special directives which can be included within +an action: +.Bl -tag -width Ds +.It ECHO +Copies +.Fa yytext +to the scanner's output. +.It BEGIN +Followed by the name of a start condition, places the scanner in the +corresponding start condition +.Pq see below . +.It REJECT +Directs the scanner to proceed on to the +.Qq second best +rule which matched the input +.Pq or a prefix of the input . +The rule is chosen as described above in +.Sx HOW THE INPUT IS MATCHED , +and +.Fa yytext +and +.Fa yyleng +set up appropriately. +It may either be one which matched as much text +as the originally chosen rule but came later in the +.Nm +input file, or one which matched less text. +For example, the following will both count the +words in the input and call the routine +.Fn special +whenever +.Qq frob +is seen: +.Bd -literal -offset indent +int word_count = 0; +%% + +frob special(); REJECT; +[^ \et\en]+ ++word_count; +.Ed +.Pp +Without the +.Em REJECT , +any "frob"'s in the input would not be counted as words, +since the scanner normally executes only one action per token. +Multiple +.Em REJECT Ns 's +are allowed, +each one finding the next best choice to the currently active rule. +For example, when the following scanner scans the token +.Qq abcd , +it will write +.Qq abcdabcaba +to the output: +.Bd -literal -offset indent +%% +a | +ab | +abc | +abcd ECHO; REJECT; +\&.|\en /* eat up any unmatched character */ +.Ed +.Pp +(The first three rules share the fourth's action since they use +the special +.Sq |\& +action.) +.Em REJECT +is a particularly expensive feature in terms of scanner performance; +if it is used in any of the scanner's actions it will slow down +all of the scanner's matching. +Furthermore, +.Em REJECT +cannot be used with the +.Fl Cf +or +.Fl CF +options +.Pq see below . +.Pp +Note also that unlike the other special actions, +.Em REJECT +is a +.Em branch ; +code immediately following it in the action will not be executed. +.It yymore() +Tells the scanner that the next time it matches a rule, the corresponding +token should be appended onto the current value of +.Fa yytext +rather than replacing it. +For example, given the input +.Qq mega-kludge +the following will write +.Qq mega-mega-kludge +to the output: +.Bd -literal -offset indent +%% +mega- ECHO; yymore(); +kludge ECHO; +.Ed +.Pp +First +.Qq mega- +is matched and echoed to the output. +Then +.Qq kludge +is matched, but the previous +.Qq mega- +is still hanging around at the beginning of +.Fa yytext +so the +.Em ECHO +for the +.Qq kludge +rule will actually write +.Qq mega-kludge . +.Pp +Two notes regarding use of +.Fn yymore : +First, +.Fn yymore +depends on the value of +.Fa yyleng +correctly reflecting the size of the current token, so +.Fa yyleng +must not be modified when using +.Fn yymore . +Second, the presence of +.Fn yymore +in the scanner's action entails a minor performance penalty in the +scanner's matching speed. +.It yyless(n) +Returns all but the first +.Ar n +characters of the current token back to the input stream, where they +will be rescanned when the scanner looks for the next match. +.Fa yytext +and +.Fa yyleng +are adjusted appropriately (e.g., +.Fa yyleng +will now be equal to +.Ar n ) . +For example, on the input +.Qq foobar +the following will write out +.Qq foobarbar : +.Bd -literal -offset indent +%% +foobar ECHO; yyless(3); +[a-z]+ ECHO; +.Ed +.Pp +An argument of 0 to +.Fa yyless +will cause the entire current input string to be scanned again. +Unless how the scanner will subsequently process its input has been changed +(using +.Em BEGIN , +for example), +this will result in an endless loop. +.Pp +Note that +.Fa yyless +is a macro and can only be used in the +.Nm +input file, not from other source files. +.It unput(c) +Puts the character +.Ar c +back into the input stream. +It will be the next character scanned. +The following action will take the current token and cause it +to be rescanned enclosed in parentheses. +.Bd -literal -offset indent +{ + int i; + char *yycopy; + + /* Copy yytext because unput() trashes yytext */ + if ((yycopy = strdup(yytext)) == NULL) + err(1, NULL); + unput(')'); + for (i = yyleng - 1; i >= 0; --i) + unput(yycopy[i]); + unput('('); + free(yycopy); +} +.Ed +.Pp +Note that since each +.Fn unput +puts the given character back at the beginning of the input stream, +pushing back strings must be done back-to-front. +.Pp +An important potential problem when using +.Fn unput +is that if using +.Dq %pointer +.Pq the default , +a call to +.Fn unput +destroys the contents of +.Fa yytext , +starting with its rightmost character and devouring one character to +the left with each call. +If the value of +.Fa yytext +should be preserved after a call to +.Fn unput +.Pq as in the above example , +it must either first be copied elsewhere, or the scanner must be built using +.Dq %array +instead (see +.Sx HOW THE INPUT IS MATCHED ) . +.Pp +Finally, note that EOF cannot be put back +to attempt to mark the input stream with an end-of-file. +.It input() +Reads the next character from the input stream. +For example, the following is one way to eat up C comments: +.Bd -literal -offset indent +%% +"/*" { + int c; + + for (;;) { + while ((c = input()) != '*' && c != EOF) + ; /* eat up text of comment */ + + if (c == '*') { + while ((c = input()) == '*') + ; + if (c == '/') + break; /* found the end */ + } + + if (c == EOF) { + errx(1, "EOF in comment"); + break; + } + } +} +.Ed +.Pp +(Note that if the scanner is compiled using C++, then +.Fn input +is instead referred to as +.Fn yyinput , +in order to avoid a name clash with the C++ stream by the name of input.) +.It YY_FLUSH_BUFFER +Flushes the scanner's internal buffer +so that the next time the scanner attempts to match a token, +it will first refill the buffer using +.Dv YY_INPUT +(see +.Sx THE GENERATED SCANNER , +below). +This action is a special case of the more general +.Fn yy_flush_buffer +function, described below in the section +.Sx MULTIPLE INPUT BUFFERS . +.It yyterminate() +Can be used in lieu of a return statement in an action. +It terminates the scanner and returns a 0 to the scanner's caller, indicating +.Qq all done . +By default, +.Fn yyterminate +is also called when an end-of-file is encountered. +It is a macro and may be redefined. +.El +.Sh THE GENERATED SCANNER +The output of +.Nm +is the file +.Pa lex.yy.c , +which contains the scanning routine +.Fn yylex , +a number of tables used by it for matching tokens, +and a number of auxiliary routines and macros. +By default, +.Fn yylex +is declared as follows: +.Bd -unfilled -offset indent +int yylex() +{ + ... various definitions and the actions in here ... +} +.Ed +.Pp +(If the environment supports function prototypes, then it will +be "int yylex(void)".) +This definition may be changed by defining the +.Dv YY_DECL +macro. +For example: +.Bd -literal -offset indent +#define YY_DECL float lexscan(a, b) float a, b; +.Ed +.Pp +would give the scanning routine the name +.Em lexscan , +returning a float, and taking two floats as arguments. +Note that if arguments are given to the scanning routine using a +K&R-style/non-prototyped function declaration, +the definition must be terminated with a semi-colon +.Pq Sq ;\& . +.Pp +Whenever +.Fn yylex +is called, it scans tokens from the global input file +.Pa yyin +.Pq which defaults to stdin . +It continues until it either reaches an end-of-file +.Pq at which point it returns the value 0 +or one of its actions executes a +.Em return +statement. +.Pp +If the scanner reaches an end-of-file, subsequent calls are undefined +unless either +.Em yyin +is pointed at a new input file +.Pq in which case scanning continues from that file , +or +.Fn yyrestart +is called. +.Fn yyrestart +takes one argument, a +.Fa FILE * +pointer (which can be nil, if +.Dv YY_INPUT +has been set up to scan from a source other than +.Em yyin ) , +and initializes +.Em yyin +for scanning from that file. +Essentially there is no difference between just assigning +.Em yyin +to a new input file or using +.Fn yyrestart +to do so; the latter is available for compatibility with previous versions of +.Nm , +and because it can be used to switch input files in the middle of scanning. +It can also be used to throw away the current input buffer, +by calling it with an argument of +.Em yyin ; +but better is to use +.Dv YY_FLUSH_BUFFER +.Pq see above . +Note that +.Fn yyrestart +does not reset the start condition to +.Em INITIAL +(see +.Sx START CONDITIONS , +below). +.Pp +If +.Fn yylex +stops scanning due to executing a +.Em return +statement in one of the actions, the scanner may then be called again and it +will resume scanning where it left off. +.Pp +By default +.Pq and for purposes of efficiency , +the scanner uses block-reads rather than simple +.Xr getc 3 +calls to read characters from +.Em yyin . +The nature of how it gets its input can be controlled by defining the +.Dv YY_INPUT +macro. +.Dv YY_INPUT Ns 's +calling sequence is +.Qq YY_INPUT(buf,result,max_size) . +Its action is to place up to +.Dv max_size +characters in the character array +.Em buf +and return in the integer variable +.Em result +either the number of characters read or the constant +.Dv YY_NULL +(0 on +.Ux +systems) +to indicate +.Dv EOF . +The default +.Dv YY_INPUT +reads from the global file-pointer +.Qq yyin . +.Pp +A sample definition of +.Dv YY_INPUT +.Pq in the definitions section of the input file : +.Bd -unfilled -offset indent +%{ +#define YY_INPUT(buf,result,max_size) \e +{ \e + int c = getchar(); \e + result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \e +} +%} +.Ed +.Pp +This definition will change the input processing to occur +one character at a time. +.Pp +When the scanner receives an end-of-file indication from +.Dv YY_INPUT , +it then checks the +.Fn yywrap +function. +If +.Fn yywrap +returns false +.Pq zero , +then it is assumed that the function has gone ahead and set up +.Em yyin +to point to another input file, and scanning continues. +If it returns true +.Pq non-zero , +then the scanner terminates, returning 0 to its caller. +Note that in either case, the start condition remains unchanged; +it does not revert to +.Em INITIAL . +.Pp +If you do not supply your own version of +.Fn yywrap , +then you must either use +.Dq %option noyywrap +(in which case the scanner behaves as though +.Fn yywrap +returned 1), or you must link with +.Fl lfl +to obtain the default version of the routine, which always returns 1. +.Pp +Three routines are available for scanning from in-memory buffers rather +than files: +.Fn yy_scan_string , +.Fn yy_scan_bytes , +and +.Fn yy_scan_buffer . +See the discussion of them below in the section +.Sx MULTIPLE INPUT BUFFERS . +.Pp +The scanner writes its +.Em ECHO +output to the +.Em yyout +global +.Pq default, stdout , +which may be redefined by the user simply by assigning it to some other +.Va FILE +pointer. +.Sh START CONDITIONS +.Nm +provides a mechanism for conditionally activating rules. +Any rule whose pattern is prefixed with +.Qq Aq sc +will only be active when the scanner is in the start condition named +.Qq sc . +For example, +.Bd -literal -offset indent +[^"]* { /* eat up the string body ... */ + ... +} +.Ed +.Pp +will be active only when the scanner is in the +.Qq STRING +start condition, and +.Bd -literal -offset indent +\e. { /* handle an escape ... */ + ... +} +.Ed +.Pp +will be active only when the current start condition is either +.Qq INITIAL , +.Qq STRING , +or +.Qq QUOTE . +.Pp +Start conditions are declared in the definitions +.Pq first +section of the input using unindented lines beginning with either +.Sq %s +or +.Sq %x +followed by a list of names. +The former declares +.Em inclusive +start conditions, the latter +.Em exclusive +start conditions. +A start condition is activated using the +.Em BEGIN +action. +Until the next +.Em BEGIN +action is executed, rules with the given start condition will be active and +rules with other start conditions will be inactive. +If the start condition is inclusive, +then rules with no start conditions at all will also be active. +If it is exclusive, +then only rules qualified with the start condition will be active. +A set of rules contingent on the same exclusive start condition +describe a scanner which is independent of any of the other rules in the +.Nm +input. +Because of this, exclusive start conditions make it easy to specify +.Qq mini-scanners +which scan portions of the input that are syntactically different +from the rest +.Pq e.g., comments . +.Pp +If the distinction between inclusive and exclusive start conditions +is still a little vague, here's a simple example illustrating the +connection between the two. +The set of rules: +.Bd -literal -offset indent +%s example +%% + +foo do_something(); + +bar something_else(); +.Ed +.Pp +is equivalent to +.Bd -literal -offset indent +%x example +%% + +foo do_something(); + +bar something_else(); +.Ed +.Pp +Without the +.Aq INITIAL,example +qualifier, the +.Dq bar +pattern in the second example wouldn't be active +.Pq i.e., couldn't match +when in start condition +.Dq example . +If we just used +.Aq example +to qualify +.Dq bar , +though, then it would only be active in +.Dq example +and not in +.Em INITIAL , +while in the first example it's active in both, +because in the first example the +.Dq example +start condition is an inclusive +.Pq Sq %s +start condition. +.Pp +Also note that the special start-condition specifier +.Sq Aq * +matches every start condition. +Thus, the above example could also have been written: +.Bd -literal -offset indent +%x example +%% + +foo do_something(); + +<*>bar something_else(); +.Ed +.Pp +The default rule (to +.Em ECHO +any unmatched character) remains active in start conditions. +It is equivalent to: +.Bd -literal -offset indent +<*>.|\en ECHO; +.Ed +.Pp +.Dq BEGIN(0) +returns to the original state where only the rules with +no start conditions are active. +This state can also be referred to as the start-condition +.Em INITIAL , +so +.Dq BEGIN(INITIAL) +is equivalent to +.Dq BEGIN(0) . +(The parentheses around the start condition name are not required but +are considered good style.) +.Pp +.Em BEGIN +actions can also be given as indented code at the beginning +of the rules section. +For example, the following will cause the scanner to enter the +.Qq SPECIAL +start condition whenever +.Fn yylex +is called and the global variable +.Fa enter_special +is true: +.Bd -literal -offset indent +int enter_special; + +%x SPECIAL +%% + if (enter_special) + BEGIN(SPECIAL); + +blahblahblah +\&...more rules follow... +.Ed +.Pp +To illustrate the uses of start conditions, +here is a scanner which provides two different interpretations +of a string like +.Qq 123.456 . +By default it will treat it as three tokens: the integer +.Qq 123 , +a dot +.Pq Sq .\& , +and the integer +.Qq 456 . +But if the string is preceded earlier in the line by the string +.Qq expect-floats +it will treat it as a single token, the floating-point number 123.456: +.Bd -literal -offset indent +%{ +#include +%} +%s expect + +%% +expect-floats BEGIN(expect); + +[0-9]+"."[0-9]+ { + printf("found a float, = %f\en", + atof(yytext)); +} +\en { + /* + * That's the end of the line, so + * we need another "expect-number" + * before we'll recognize any more + * numbers. + */ + BEGIN(INITIAL); +} + +[0-9]+ { + printf("found an integer, = %d\en", + atoi(yytext)); +} + +"." printf("found a dot\en"); +.Ed +.Pp +Here is a scanner which recognizes +.Pq and discards +C comments while maintaining a count of the current input line: +.Bd -literal -offset indent +%x comment +%% +int line_num = 1; + +"/*" BEGIN(comment); + +[^*\en]* /* eat anything that's not a '*' */ +"*"+[^*/\en]* /* eat up '*'s not followed by '/'s */ +\en ++line_num; +"*"+"/" BEGIN(INITIAL); +.Ed +.Pp +This scanner goes to a bit of trouble to match as much +text as possible with each rule. +In general, when attempting to write a high-speed scanner +try to match as much as possible in each rule, as it's a big win. +.Pp +Note that start-condition names are really integer values and +can be stored as such. +Thus, the above could be extended in the following fashion: +.Bd -literal -offset indent +%x comment foo +%% +int line_num = 1; +int comment_caller; + +"/*" { + comment_caller = INITIAL; + BEGIN(comment); +} + +\&... + +"/*" { + comment_caller = foo; + BEGIN(comment); +} + +[^*\en]* /* eat anything that's not a '*' */ +"*"+[^*/\en]* /* eat up '*'s not followed by '/'s */ +\en ++line_num; +"*"+"/" BEGIN(comment_caller); +.Ed +.Pp +Furthermore, the current start condition can be accessed by using +the integer-valued +.Dv YY_START +macro. +For example, the above assignments to +.Em comment_caller +could instead be written +.Pp +.Dl comment_caller = YY_START; +.Pp +Flex provides +.Dv YYSTATE +as an alias for +.Dv YY_START +(since that is what's used by +.At +.Nm lex ) . +.Pp +Note that start conditions do not have their own name-space; +%s's and %x's declare names in the same fashion as #define's. +.Pp +Finally, here's an example of how to match C-style quoted strings using +exclusive start conditions, including expanded escape sequences +(but not including checking for a string that's too long): +.Bd -literal -offset indent +%x str + +%% +#define MAX_STR_CONST 1024 +char string_buf[MAX_STR_CONST]; +char *string_buf_ptr; + +\e" string_buf_ptr = string_buf; BEGIN(str); + +\e" { /* saw closing quote - all done */ + BEGIN(INITIAL); + *string_buf_ptr = '\e0'; + /* + * return string constant token type and + * value to parser + */ +} + +\en { + /* error - unterminated string constant */ + /* generate error message */ +} + +\e\e[0-7]{1,3} { + /* octal escape sequence */ + int result; + + (void) sscanf(yytext + 1, "%o", &result); + + if (result > 0xff) { + /* error, constant is out-of-bounds */ + } else + *string_buf_ptr++ = result; +} + +\e\e[0-9]+ { + /* + * generate error - bad escape sequence; something + * like '\e48' or '\e0777777' + */ +} + +\e\en *string_buf_ptr++ = '\en'; +\e\et *string_buf_ptr++ = '\et'; +\e\er *string_buf_ptr++ = '\er'; +\e\eb *string_buf_ptr++ = '\eb'; +\e\ef *string_buf_ptr++ = '\ef'; + +\e\e(.|\en) *string_buf_ptr++ = yytext[1]; + +[^\e\e\en\e"]+ { + char *yptr = yytext; + + while (*yptr) + *string_buf_ptr++ = *yptr++; +} +.Ed +.Pp +Often, such as in some of the examples above, +a whole bunch of rules are all preceded by the same start condition(s). +.Nm +makes this a little easier and cleaner by introducing a notion of +start condition +.Em scope . +A start condition scope is begun with: +.Pp +.Dl { +.Pp +where +.Dq SCs +is a list of one or more start conditions. +Inside the start condition scope, every rule automatically has the prefix +.Aq SCs +applied to it, until a +.Sq } +which matches the initial +.Sq { . +So, for example, +.Bd -literal -offset indent +{ + "\e\en" return '\en'; + "\e\er" return '\er'; + "\e\ef" return '\ef'; + "\e\e0" return '\e0'; +} +.Ed +.Pp +is equivalent to: +.Bd -literal -offset indent +"\e\en" return '\en'; +"\e\er" return '\er'; +"\e\ef" return '\ef'; +"\e\e0" return '\e0'; +.Ed +.Pp +Start condition scopes may be nested. +.Pp +Three routines are available for manipulating stacks of start conditions: +.Bl -tag -width Ds +.It void yy_push_state(int new_state) +Pushes the current start condition onto the top of the start condition +stack and switches to +.Fa new_state +as though +.Dq BEGIN new_state +had been used +.Pq recall that start condition names are also integers . +.It void yy_pop_state() +Pops the top of the stack and switches to it via +.Em BEGIN . +.It int yy_top_state() +Returns the top of the stack without altering the stack's contents. +.El +.Pp +The start condition stack grows dynamically and so has no built-in +size limitation. +If memory is exhausted, program execution aborts. +.Pp +To use start condition stacks, scanners must include a +.Dq %option stack +directive (see +.Sx OPTIONS +below). +.Sh MULTIPLE INPUT BUFFERS +Some scanners +(such as those which support +.Qq include +files) +require reading from several input streams. +As +.Nm +scanners do a large amount of buffering, one cannot control +where the next input will be read from by simply writing a +.Dv YY_INPUT +which is sensitive to the scanning context. +.Dv YY_INPUT +is only called when the scanner reaches the end of its buffer, which +may be a long time after scanning a statement such as an +.Qq include +which requires switching the input source. +.Pp +To negotiate these sorts of problems, +.Nm +provides a mechanism for creating and switching between multiple +input buffers. +An input buffer is created by using: +.Pp +.D1 YY_BUFFER_STATE yy_create_buffer(FILE *file, int size) +.Pp +which takes a +.Fa FILE +pointer and a +.Fa size +and creates a buffer associated with the given file and large enough to hold +.Fa size +characters (when in doubt, use +.Dv YY_BUF_SIZE +for the size). +It returns a +.Dv YY_BUFFER_STATE +handle, which may then be passed to other routines +.Pq see below . +The +.Dv YY_BUFFER_STATE +type is a pointer to an opaque +.Dq struct yy_buffer_state +structure, so +.Dv YY_BUFFER_STATE +variables may be safely initialized to +.Dq ((YY_BUFFER_STATE) 0) +if desired, and the opaque structure can also be referred to in order to +correctly declare input buffers in source files other than that of scanners. +Note that the +.Fa FILE +pointer in the call to +.Fn yy_create_buffer +is only used as the value of +.Fa yyin +seen by +.Dv YY_INPUT ; +if +.Dv YY_INPUT +is redefined so that it no longer uses +.Fa yyin , +then a nil +.Fa FILE +pointer can safely be passed to +.Fn yy_create_buffer . +To select a particular buffer to scan: +.Pp +.D1 void yy_switch_to_buffer(YY_BUFFER_STATE new_buffer) +.Pp +It switches the scanner's input buffer so subsequent tokens will +come from +.Fa new_buffer . +Note that +.Fn yy_switch_to_buffer +may be used by +.Fn yywrap +to set things up for continued scanning, +instead of opening a new file and pointing +.Fa yyin +at it. +Note also that switching input sources via either +.Fn yy_switch_to_buffer +or +.Fn yywrap +does not change the start condition. +.Pp +.D1 void yy_delete_buffer(YY_BUFFER_STATE buffer) +.Pp +is used to reclaim the storage associated with a buffer. +.Pf ( Fa buffer +can be nil, in which case the routine does nothing.) +To clear the current contents of a buffer: +.Pp +.D1 void yy_flush_buffer(YY_BUFFER_STATE buffer) +.Pp +This function discards the buffer's contents, +so the next time the scanner attempts to match a token from the buffer, +it will first fill the buffer anew using +.Dv YY_INPUT . +.Pp +.Fn yy_new_buffer +is an alias for +.Fn yy_create_buffer , +provided for compatibility with the C++ use of +.Em new +and +.Em delete +for creating and destroying dynamic objects. +.Pp +Finally, the +.Dv YY_CURRENT_BUFFER +macro returns a +.Dv YY_BUFFER_STATE +handle to the current buffer. +.Pp +Here is an example of using these features for writing a scanner +which expands include files (the +.Aq Aq EOF +feature is discussed below): +.Bd -literal -offset indent +/* + * the "incl" state is used for picking up the name + * of an include file + */ +%x incl + +%{ +#define MAX_INCLUDE_DEPTH 10 +YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; +int include_stack_ptr = 0; +%} + +%% +include BEGIN(incl); + +[a-z]+ ECHO; +[^a-z\en]*\en? ECHO; + +[ \et]* /* eat the whitespace */ +[^ \et\en]+ { /* got the include file name */ + if (include_stack_ptr >= MAX_INCLUDE_DEPTH) + errx(1, "Includes nested too deeply"); + + include_stack[include_stack_ptr++] = + YY_CURRENT_BUFFER; + + yyin = fopen(yytext, "r"); + + if (yyin == NULL) + err(1, NULL); + + yy_switch_to_buffer( + yy_create_buffer(yyin, YY_BUF_SIZE)); + + BEGIN(INITIAL); +} + +<> { + if (--include_stack_ptr < 0) + yyterminate(); + else { + yy_delete_buffer(YY_CURRENT_BUFFER); + yy_switch_to_buffer( + include_stack[include_stack_ptr]); + } +} +.Ed +.Pp +Three routines are available for setting up input buffers for +scanning in-memory strings instead of files. +All of them create a new input buffer for scanning the string, +and return a corresponding +.Dv YY_BUFFER_STATE +handle (which should be deleted afterwards using +.Fn yy_delete_buffer ) . +They also switch to the new buffer using +.Fn yy_switch_to_buffer , +so the next call to +.Fn yylex +will start scanning the string. +.Bl -tag -width Ds +.It yy_scan_string(const char *str) +Scans a NUL-terminated string. +.It yy_scan_bytes(const char *bytes, int len) +Scans +.Fa len +bytes +.Pq including possibly NUL's +starting at location +.Fa bytes . +.El +.Pp +Note that both of these functions create and scan a copy +of the string or bytes. +(This may be desirable, since +.Fn yylex +modifies the contents of the buffer it is scanning.) +The copy can be avoided by using: +.Bl -tag -width Ds +.It yy_scan_buffer(char *base, yy_size_t size) +Which scans the buffer starting at +.Fa base , +consisting of +.Fa size +bytes, the last two bytes of which must be +.Dv YY_END_OF_BUFFER_CHAR +.Pq ASCII NUL . +These last two bytes are not scanned; thus, scanning consists of +base[0] through base[size-2], inclusive. +.Pp +If +.Fa base +is not set up in this manner +(i.e., forget the final two +.Dv YY_END_OF_BUFFER_CHAR +bytes), then +.Fn yy_scan_buffer +returns a nil pointer instead of creating a new input buffer. +.Pp +The type +.Fa yy_size_t +is an integral type which can be cast to an integer expression +reflecting the size of the buffer. +.El +.Sh END-OF-FILE RULES +The special rule +.Qq Aq Aq EOF +indicates actions which are to be taken when an end-of-file is encountered and +.Fn yywrap +returns non-zero +.Pq i.e., indicates no further files to process . +The action must finish by doing one of four things: +.Bl -dash +.It +Assigning +.Em yyin +to a new input file +(in previous versions of +.Nm , +after doing the assignment, it was necessary to call the special action +.Dv YY_NEW_FILE ; +this is no longer necessary). +.It +Executing a +.Em return +statement. +.It +Executing the special +.Fn yyterminate +action. +.It +Switching to a new buffer using +.Fn yy_switch_to_buffer +as shown in the example above. +.El +.Pp +.Aq Aq EOF +rules may not be used with other patterns; +they may only be qualified with a list of start conditions. +If an unqualified +.Aq Aq EOF +rule is given, it applies to all start conditions which do not already have +.Aq Aq EOF +actions. +To specify an +.Aq Aq EOF +rule for only the initial start condition, use +.Pp +.Dl <> +.Pp +These rules are useful for catching things like unclosed comments. +An example: +.Bd -literal -offset indent +%x quote +%% + +\&...other rules for dealing with quotes... + +<> { + error("unterminated quote"); + yyterminate(); +} +<> { + if (*++filelist) + yyin = fopen(*filelist, "r"); + else + yyterminate(); +} +.Ed +.Sh MISCELLANEOUS MACROS +The macro +.Dv YY_USER_ACTION +can be defined to provide an action +which is always executed prior to the matched rule's action. +For example, +it could be #define'd to call a routine to convert yytext to lower-case. +When +.Dv YY_USER_ACTION +is invoked, the variable +.Fa yy_act +gives the number of the matched rule +.Pq rules are numbered starting with 1 . +For example, to profile how often each rule is matched, +the following would do the trick: +.Pp +.Dl #define YY_USER_ACTION ++ctr[yy_act] +.Pp +where +.Fa ctr +is an array to hold the counts for the different rules. +Note that the macro +.Dv YY_NUM_RULES +gives the total number of rules +(including the default rule, even if +.Fl s +is used), +so a correct declaration for +.Fa ctr +is: +.Pp +.Dl int ctr[YY_NUM_RULES]; +.Pp +The macro +.Dv YY_USER_INIT +may be defined to provide an action which is always executed before +the first scan +.Pq and before the scanner's internal initializations are done . +For example, it could be used to call a routine to read +in a data table or open a logging file. +.Pp +The macro +.Dv yy_set_interactive(is_interactive) +can be used to control whether the current buffer is considered +.Em interactive . +An interactive buffer is processed more slowly, +but must be used when the scanner's input source is indeed +interactive to avoid problems due to waiting to fill buffers +(see the discussion of the +.Fl I +flag below). +A non-zero value in the macro invocation marks the buffer as interactive, +a zero value as non-interactive. +Note that use of this macro overrides +.Dq %option always-interactive +or +.Dq %option never-interactive +(see +.Sx OPTIONS +below). +.Fn yy_set_interactive +must be invoked prior to beginning to scan the buffer that is +.Pq or is not +to be considered interactive. +.Pp +The macro +.Dv yy_set_bol(at_bol) +can be used to control whether the current buffer's scanning +context for the next token match is done as though at the +beginning of a line. +A non-zero macro argument makes rules anchored with +.Sq ^ +active, while a zero argument makes +.Sq ^ +rules inactive. +.Pp +The macro +.Dv YY_AT_BOL +returns true if the next token scanned from the current buffer will have +.Sq ^ +rules active, false otherwise. +.Pp +In the generated scanner, the actions are all gathered in one large +switch statement and separated using +.Dv YY_BREAK , +which may be redefined. +By default, it is simply a +.Qq break , +to separate each rule's action from the following rules. +Redefining +.Dv YY_BREAK +allows, for example, C++ users to +.Dq #define YY_BREAK +to do nothing +(while being very careful that every rule ends with a +.Qq break +or a +.Qq return ! ) +to avoid suffering from unreachable statement warnings where because a rule's +action ends with +.Dq return , +the +.Dv YY_BREAK +is inaccessible. +.Sh VALUES AVAILABLE TO THE USER +This section summarizes the various values available to the user +in the rule actions. +.Bl -tag -width Ds +.It char *yytext +Holds the text of the current token. +It may be modified but not lengthened +.Pq characters cannot be appended to the end . +.Pp +If the special directive +.Dq %array +appears in the first section of the scanner description, then +.Fa yytext +is instead declared +.Dq char yytext[YYLMAX] , +where +.Dv YYLMAX +is a macro definition that can be redefined in the first section +to change the default value +.Pq generally 8KB . +Using +.Dq %array +results in somewhat slower scanners, but the value of +.Fa yytext +becomes immune to calls to +.Fn input +and +.Fn unput , +which potentially destroy its value when +.Fa yytext +is a character pointer. +The opposite of +.Dq %array +is +.Dq %pointer , +which is the default. +.Pp +.Dq %array +cannot be used when generating C++ scanner classes +(the +.Fl + +flag). +.It int yyleng +Holds the length of the current token. +.It FILE *yyin +Is the file which by default +.Nm +reads from. +It may be redefined, but doing so only makes sense before +scanning begins or after an +.Dv EOF +has been encountered. +Changing it in the midst of scanning will have unexpected results since +.Nm +buffers its input; use +.Fn yyrestart +instead. +Once scanning terminates because an end-of-file +has been seen, +.Fa yyin +can be assigned as the new input file +and the scanner can be called again to continue scanning. +.It void yyrestart(FILE *new_file) +May be called to point +.Fa yyin +at the new input file. +The switch-over to the new file is immediate +.Pq any previously buffered-up input is lost . +Note that calling +.Fn yyrestart +with +.Fa yyin +as an argument thus throws away the current input buffer and continues +scanning the same input file. +.It FILE *yyout +Is the file to which +.Em ECHO +actions are done. +It can be reassigned by the user. +.It YY_CURRENT_BUFFER +Returns a +.Dv YY_BUFFER_STATE +handle to the current buffer. +.It YY_START +Returns an integer value corresponding to the current start condition. +This value can subsequently be used with +.Em BEGIN +to return to that start condition. +.El +.Sh INTERFACING WITH YACC +One of the main uses of +.Nm +is as a companion to the +.Xr yacc 1 +parser-generator. +yacc parsers expect to call a routine named +.Fn yylex +to find the next input token. +The routine is supposed to return the type of the next token +as well as putting any associated value in the global +.Fa yylval , +which is defined externally, +and can be a union or any other complex data structure. +To use +.Nm +with yacc, one specifies the +.Fl d +option to yacc to instruct it to generate the file +.Pa y.tab.h +containing definitions of all the +.Dq %tokens +appearing in the yacc input. +This file is then included in the +.Nm +scanner. +For example, if one of the tokens is +.Qq TOK_NUMBER , +part of the scanner might look like: +.Bd -literal -offset indent +%{ +#include "y.tab.h" +%} + +%% + +[0-9]+ yylval = atoi(yytext); return TOK_NUMBER; +.Ed +.Sh OPTIONS +.Nm +has the following options: +.Bl -tag -width Ds +.It Fl 7 +Instructs +.Nm +to generate a 7-bit scanner, i.e., one which can only recognize 7-bit +characters in its input. +The advantage of using +.Fl 7 +is that the scanner's tables can be up to half the size of those generated +using the +.Fl 8 +option +.Pq see below . +The disadvantage is that such scanners often hang +or crash if their input contains an 8-bit character. +.Pp +Note, however, that unless generating a scanner using the +.Fl Cf +or +.Fl CF +table compression options, use of +.Fl 7 +will save only a small amount of table space, +and make the scanner considerably less portable. +.Nm flex Ns 's +default behavior is to generate an 8-bit scanner unless +.Fl Cf +or +.Fl CF +is specified, in which case +.Nm +defaults to generating 7-bit scanners unless it was +configured to generate 8-bit scanners +(as will often be the case with non-USA sites). +It is possible tell whether +.Nm +generated a 7-bit or an 8-bit scanner by inspecting the flag summary in the +.Fl v +output as described below. +.Pp +Note that if +.Fl Cfe +or +.Fl CFe +are used +(the table compression options, but also using equivalence classes as +discussed below), +.Nm +still defaults to generating an 8-bit scanner, +since usually with these compression options full 8-bit tables +are not much more expensive than 7-bit tables. +.It Fl 8 +Instructs +.Nm +to generate an 8-bit scanner, i.e., one which can recognize 8-bit +characters. +This flag is only needed for scanners generated using +.Fl Cf +or +.Fl CF , +as otherwise +.Nm +defaults to generating an 8-bit scanner anyway. +.Pp +See the discussion of +.Fl 7 +above for +.Nm flex Ns 's +default behavior and the tradeoffs between 7-bit and 8-bit scanners. +.It Fl B +Instructs +.Nm +to generate a +.Em batch +scanner, the opposite of +.Em interactive +scanners generated by +.Fl I +.Pq see below . +In general, +.Fl B +is used when the scanner will never be used interactively, +and you want to squeeze a little more performance out of it. +If the aim is instead to squeeze out a lot more performance, +use the +.Fl Cf +or +.Fl CF +options +.Pq discussed below , +which turn on +.Fl B +automatically anyway. +.It Fl b +Generate backing-up information to +.Pa lex.backup . +This is a list of scanner states which require backing up +and the input characters on which they do so. +By adding rules one can remove backing-up states. +If all backing-up states are eliminated and +.Fl Cf +or +.Fl CF +is used, the generated scanner will run faster (see the +.Fl p +flag). +Only users who wish to squeeze every last cycle out of their +scanners need worry about this option. +(See the section on +.Sx PERFORMANCE CONSIDERATIONS +below.) +.It Fl C Ns Op Cm aeFfmr +Controls the degree of table compression and, more generally, trade-offs +between small scanners and fast scanners. +.Bl -tag -width Ds +.It Fl Ca +Instructs +.Nm +to trade off larger tables in the generated scanner for faster performance +because the elements of the tables are better aligned for memory access +and computation. +On some +.Tn RISC +architectures, fetching and manipulating longwords is more efficient +than with smaller-sized units such as shortwords. +This option can double the size of the tables used by the scanner. +.It Fl Ce +Directs +.Nm +to construct +.Em equivalence classes , +i.e., sets of characters which have identical lexical properties +(for example, if the only appearance of digits in the +.Nm +input is in the character class +.Qq [0-9] +then the digits +.Sq 0 , +.Sq 1 , +.Sq ... , +.Sq 9 +will all be put in the same equivalence class). +Equivalence classes usually give dramatic reductions in the final +table/object file sizes +.Pq typically a factor of 2\-5 +and are pretty cheap performance-wise +.Pq one array look-up per character scanned . +.It Fl CF +Specifies that the alternate fast scanner representation +(described below under the +.Fl F +option) +should be used. +This option cannot be used with +.Fl + . +.It Fl Cf +Specifies that the +.Em full +scanner tables should be generated \- +.Nm +should not compress the tables by taking advantage of +similar transition functions for different states. +.It Fl \&Cm +Directs +.Nm +to construct +.Em meta-equivalence classes , +which are sets of equivalence classes +(or characters, if equivalence classes are not being used) +that are commonly used together. +Meta-equivalence classes are often a big win when using compressed tables, +but they have a moderate performance impact +(one or two +.Qq if +tests and one array look-up per character scanned). +.It Fl Cr +Causes the generated scanner to +.Em bypass +use of the standard I/O library +.Pq stdio +for input. +Instead of calling +.Xr fread 3 +or +.Xr getc 3 , +the scanner will use the +.Xr read 2 +system call, +resulting in a performance gain which varies from system to system, +but in general is probably negligible unless +.Fl Cf +or +.Fl CF +are being used. +Using +.Fl Cr +can cause strange behavior if, for example, reading from +.Fa yyin +using stdio prior to calling the scanner +(because the scanner will miss whatever text previous reads left +in the stdio input buffer). +.Pp +.Fl Cr +has no effect if +.Dv YY_INPUT +is defined +(see +.Sx THE GENERATED SCANNER +above). +.El +.Pp +A lone +.Fl C +specifies that the scanner tables should be compressed but neither +equivalence classes nor meta-equivalence classes should be used. +.Pp +The options +.Fl Cf +or +.Fl CF +and +.Fl \&Cm +do not make sense together \- there is no opportunity for meta-equivalence +classes if the table is not being compressed. +Otherwise the options may be freely mixed, and are cumulative. +.Pp +The default setting is +.Fl Cem +which specifies that +.Nm +should generate equivalence classes and meta-equivalence classes. +This setting provides the highest degree of table compression. +It is possible to trade off faster-executing scanners at the cost of +larger tables with the following generally being true: +.Bd -unfilled -offset indent +slowest & smallest + -Cem + -Cm + -Ce + -C + -C{f,F}e + -C{f,F} + -C{f,F}a +fastest & largest +.Ed +.Pp +Note that scanners with the smallest tables are usually generated and +compiled the quickest, +so during development the default is usually best, +maximal compression. +.Pp +.Fl Cfe +is often a good compromise between speed and size for production scanners. +.It Fl d +Makes the generated scanner run in debug mode. +Whenever a pattern is recognized and the global +.Fa yy_flex_debug +is non-zero +.Pq which is the default , +the scanner will write to stderr a line of the form: +.Pp +.D1 --accepting rule at line 53 ("the matched text") +.Pp +The line number refers to the location of the rule in the file +defining the scanner +(i.e., the file that was fed to +.Nm ) . +Messages are also generated when the scanner backs up, +accepts the default rule, +reaches the end of its input buffer +(or encounters a NUL; +at this point, the two look the same as far as the scanner's concerned), +or reaches an end-of-file. +.It Fl F +Specifies that the fast scanner table representation should be used +.Pq and stdio bypassed . +This representation is about as fast as the full table representation +.Pq Fl f , +and for some sets of patterns will be considerably smaller +.Pq and for others, larger . +In general, if the pattern set contains both +.Qq keywords +and a catch-all, +.Qq identifier +rule, such as in the set: +.Bd -unfilled -offset indent +"case" return TOK_CASE; +"switch" return TOK_SWITCH; +\&... +"default" return TOK_DEFAULT; +[a-z]+ return TOK_ID; +.Ed +.Pp +then it's better to use the full table representation. +If only the +.Qq identifier +rule is present and a hash table or some such is used to detect the keywords, +it's better to use +.Fl F . +.Pp +This option is equivalent to +.Fl CFr +.Pq see above . +It cannot be used with +.Fl + . +.It Fl f +Specifies +.Em fast scanner . +No table compression is done and stdio is bypassed. +The result is large but fast. +This option is equivalent to +.Fl Cfr +.Pq see above . +.It Fl h +Generates a help summary of +.Nm flex Ns 's +options to stdout and then exits. +.Fl ?\& +and +.Fl Fl help +are synonyms for +.Fl h . +.It Fl I +Instructs +.Nm +to generate an +.Em interactive +scanner. +An interactive scanner is one that only looks ahead to decide +what token has been matched if it absolutely must. +It turns out that always looking one extra character ahead, +even if the scanner has already seen enough text +to disambiguate the current token, is a bit faster than +only looking ahead when necessary. +But scanners that always look ahead give dreadful interactive performance; +for example, when a user types a newline, +it is not recognized as a newline token until they enter +.Em another +token, which often means typing in another whole line. +.Pp +.Nm +scanners default to +.Em interactive +unless +.Fl Cf +or +.Fl CF +table-compression options are specified +.Pq see above . +That's because if high-performance is most important, +one of these options should be used, +so if they weren't, +.Nm +assumes it is preferable to trade off a bit of run-time performance for +intuitive interactive behavior. +Note also that +.Fl I +cannot be used in conjunction with +.Fl Cf +or +.Fl CF . +Thus, this option is not really needed; it is on by default for all those +cases in which it is allowed. +.Pp +A scanner can be forced to not be interactive by using +.Fl B +.Pq see above . +.It Fl i +Instructs +.Nm +to generate a case-insensitive scanner. +The case of letters given in the +.Nm +input patterns will be ignored, +and tokens in the input will be matched regardless of case. +The matched text given in +.Fa yytext +will have the preserved case +.Pq i.e., it will not be folded . +.It Fl L +Instructs +.Nm +not to generate +.Dq #line +directives. +Without this option, +.Nm +peppers the generated scanner with #line directives so error messages +in the actions will be correctly located with respect to either the original +.Nm +input file +(if the errors are due to code in the input file), +or +.Pa lex.yy.c +(if the errors are +.Nm flex Ns 's +fault \- these sorts of errors should be reported to the email address +given below). +.It Fl l +Turns on maximum compatibility with the original +.At +.Nm lex +implementation. +Note that this does not mean full compatibility. +Use of this option costs a considerable amount of performance, +and it cannot be used with the +.Fl + , f , F , Cf , +or +.Fl CF +options. +For details on the compatibilities it provides, see the section +.Sx INCOMPATIBILITIES WITH LEX AND POSIX +below. +This option also results in the name +.Dv YY_FLEX_LEX_COMPAT +being #define'd in the generated scanner. +.It Fl n +Another do-nothing, deprecated option included only for +.Tn POSIX +compliance. +.It Fl o Ns Ar output +Directs +.Nm +to write the scanner to the file +.Ar output +instead of +.Pa lex.yy.c . +If +.Fl o +is combined with the +.Fl t +option, then the scanner is written to stdout but its +.Dq #line +directives +(see the +.Fl L +option above) +refer to the file +.Ar output . +.It Fl P Ns Ar prefix +Changes the default +.Qq yy +prefix used by +.Nm +for all globally visible variable and function names to instead be +.Ar prefix . +For example, +.Fl P Ns Ar foo +changes the name of +.Fa yytext +to +.Fa footext . +It also changes the name of the default output file from +.Pa lex.yy.c +to +.Pa lex.foo.c . +Here are all of the names affected: +.Bd -unfilled -offset indent +yy_create_buffer +yy_delete_buffer +yy_flex_debug +yy_init_buffer +yy_flush_buffer +yy_load_buffer_state +yy_switch_to_buffer +yyin +yyleng +yylex +yylineno +yyout +yyrestart +yytext +yywrap +.Ed +.Pp +(If using a C++ scanner, then only +.Fa yywrap +and +.Fa yyFlexLexer +are affected.) +Within the scanner itself, it is still possible to refer to the global variables +and functions using either version of their name; but externally, they +have the modified name. +.Pp +This option allows multiple +.Nm +programs to be easily linked together into the same executable. +Note, though, that using this option also renames +.Fn yywrap , +so now either an +.Pq appropriately named +version of the routine for the scanner must be supplied, or +.Dq %option noyywrap +must be used, as linking with +.Fl lfl +no longer provides one by default. +.It Fl p +Generates a performance report to stderr. +The report consists of comments regarding features of the +.Nm +input file which will cause a serious loss of performance in the resulting +scanner. +If the flag is specified twice, +comments regarding features that lead to minor performance losses +will also be reported> +.Pp +Note that the use of +.Em REJECT , +.Dq %option yylineno , +and variable trailing context +(see the +.Sx BUGS +section below) +entails a substantial performance penalty; use of +.Fn yymore , +the +.Sq ^ +operator, and the +.Fl I +flag entail minor performance penalties. +.It Fl S Ns Ar skeleton +Overrides the default skeleton file from which +.Nm +constructs its scanners. +This option is needed only for +.Nm +maintenance or development. +.It Fl s +Causes the default rule +.Pq that unmatched scanner input is echoed to stdout +to be suppressed. +If the scanner encounters input that does not +match any of its rules, it aborts with an error. +This option is useful for finding holes in a scanner's rule set. +.It Fl T +Makes +.Nm +run in +.Em trace +mode. +It will generate a lot of messages to stderr concerning +the form of the input and the resultant non-deterministic and deterministic +finite automata. +This option is mostly for use in maintaining +.Nm . +.It Fl t +Instructs +.Nm +to write the scanner it generates to standard output instead of +.Pa lex.yy.c . +.It Fl V +Prints the version number to stdout and exits. +.Fl Fl version +is a synonym for +.Fl V . +.It Fl v +Specifies that +.Nm +should write to stderr +a summary of statistics regarding the scanner it generates. +Most of the statistics are meaningless to the casual +.Nm +user, but the first line identifies the version of +.Nm +(same as reported by +.Fl V ) , +and the next line the flags used when generating the scanner, +including those that are on by default. +.It Fl w +Suppresses warning messages. +.It Fl + +Specifies that +.Nm +should generate a C++ scanner class. +See the section on +.Sx GENERATING C++ SCANNERS +below for details. +.El +.Pp +.Nm +also provides a mechanism for controlling options within the +scanner specification itself, rather than from the +.Nm +command line. +This is done by including +.Dq %option +directives in the first section of the scanner specification. +Multiple options can be specified with a single +.Dq %option +directive, and multiple directives in the first section of the +.Nm +input file. +.Pp +Most options are given simply as names, optionally preceded by the word +.Qq no +.Pq with no intervening whitespace +to negate their meaning. +A number are equivalent to +.Nm +flags or their negation: +.Bd -unfilled -offset indent +7bit -7 option +8bit -8 option +align -Ca option +backup -b option +batch -B option +c++ -+ option + +caseful or +case-sensitive opposite of -i (default) + +case-insensitive or +caseless -i option + +debug -d option +default opposite of -s option +ecs -Ce option +fast -F option +full -f option +interactive -I option +lex-compat -l option +meta-ecs -Cm option +perf-report -p option +read -Cr option +stdout -t option +verbose -v option +warn opposite of -w option + (use "%option nowarn" for -w) + +array equivalent to "%array" +pointer equivalent to "%pointer" (default) +.Ed +.Pp +Some %option's provide features otherwise not available: +.Bl -tag -width Ds +.It always-interactive +Instructs +.Nm +to generate a scanner which always considers its input +.Qq interactive . +Normally, on each new input file the scanner calls +.Fn isatty +in an attempt to determine whether the scanner's input source is interactive +and thus should be read a character at a time. +When this option is used, however, no such call is made. +.It main +Directs +.Nm +to provide a default +.Fn main +program for the scanner, which simply calls +.Fn yylex . +This option implies +.Dq noyywrap +.Pq see below . +.It never-interactive +Instructs +.Nm +to generate a scanner which never considers its input +.Qq interactive +(again, no call made to +.Fn isatty ) . +This is the opposite of +.Dq always-interactive . +.It stack +Enables the use of start condition stacks +(see +.Sx START CONDITIONS +above). +.It stdinit +If set (i.e., +.Dq %option stdinit ) , +initializes +.Fa yyin +and +.Fa yyout +to stdin and stdout, instead of the default of +.Dq nil . +Some existing +.Nm lex +programs depend on this behavior, even though it is not compliant with ANSI C, +which does not require stdin and stdout to be compile-time constant. +.It yylineno +Directs +.Nm +to generate a scanner that maintains the number of the current line +read from its input in the global variable +.Fa yylineno . +This option is implied by +.Dq %option lex-compat . +.It yywrap +If unset (i.e., +.Dq %option noyywrap ) , +makes the scanner not call +.Fn yywrap +upon an end-of-file, but simply assume that there are no more files to scan +(until the user points +.Fa yyin +at a new file and calls +.Fn yylex +again). +.El +.Pp +.Nm +scans rule actions to determine whether the +.Em REJECT +or +.Fn yymore +features are being used. +The +.Dq reject +and +.Dq yymore +options are available to override its decision as to whether to use the +options, either by setting them (e.g., +.Dq %option reject ) +to indicate the feature is indeed used, +or unsetting them to indicate it actually is not used +(e.g., +.Dq %option noyymore ) . +.Pp +Three options take string-delimited values, offset with +.Sq = : +.Pp +.D1 %option outfile="ABC" +.Pp +is equivalent to +.Fl o Ns Ar ABC , +and +.Pp +.D1 %option prefix="XYZ" +.Pp +is equivalent to +.Fl P Ns Ar XYZ . +Finally, +.Pp +.D1 %option yyclass="foo" +.Pp +only applies when generating a C++ scanner +.Pf ( Fl + +option). +It informs +.Nm +that +.Dq foo +has been derived as a subclass of yyFlexLexer, so +.Nm +will place actions in the member function +.Dq foo::yylex() +instead of +.Dq yyFlexLexer::yylex() . +It also generates a +.Dq yyFlexLexer::yylex() +member function that emits a run-time error (by invoking +.Dq yyFlexLexer::LexerError() ) +if called. +See +.Sx GENERATING C++ SCANNERS , +below, for additional information. +.Pp +A number of options are available for +lint +purists who want to suppress the appearance of unneeded routines +in the generated scanner. +Each of the following, if unset +(e.g., +.Dq %option nounput ) , +results in the corresponding routine not appearing in the generated scanner: +.Bd -unfilled -offset indent +input, unput +yy_push_state, yy_pop_state, yy_top_state +yy_scan_buffer, yy_scan_bytes, yy_scan_string +.Ed +.Pp +(though +.Fn yy_push_state +and friends won't appear anyway unless +.Dq %option stack +is being used). +.Sh PERFORMANCE CONSIDERATIONS +The main design goal of +.Nm +is that it generate high-performance scanners. +It has been optimized for dealing well with large sets of rules. +Aside from the effects on scanner speed of the table compression +.Fl C +options outlined above, +there are a number of options/actions which degrade performance. +These are, from most expensive to least: +.Bd -unfilled -offset indent +REJECT +%option yylineno +arbitrary trailing context + +pattern sets that require backing up +%array +%option interactive +%option always-interactive + +\&'^' beginning-of-line operator +yymore() +.Ed +.Pp +with the first three all being quite expensive +and the last two being quite cheap. +Note also that +.Fn unput +is implemented as a routine call that potentially does quite a bit of work, +while +.Fn yyless +is a quite-cheap macro; so if just putting back some excess text, +use +.Fn yyless . +.Pp +.Em REJECT +should be avoided at all costs when performance is important. +It is a particularly expensive option. +.Pp +Getting rid of backing up is messy and often may be an enormous +amount of work for a complicated scanner. +In principal, one begins by using the +.Fl b +flag to generate a +.Pa lex.backup +file. +For example, on the input +.Bd -literal -offset indent +%% +foo return TOK_KEYWORD; +foobar return TOK_KEYWORD; +.Ed +.Pp +the file looks like: +.Bd -literal -offset indent +State #6 is non-accepting - + associated rule line numbers: + 2 3 + out-transitions: [ o ] + jam-transitions: EOF [ \e001-n p-\e177 ] + +State #8 is non-accepting - + associated rule line numbers: + 3 + out-transitions: [ a ] + jam-transitions: EOF [ \e001-` b-\e177 ] + +State #9 is non-accepting - + associated rule line numbers: + 3 + out-transitions: [ r ] + jam-transitions: EOF [ \e001-q s-\e177 ] + +Compressed tables always back up. +.Ed +.Pp +The first few lines tell us that there's a scanner state in +which it can make a transition on an +.Sq o +but not on any other character, +and that in that state the currently scanned text does not match any rule. +The state occurs when trying to match the rules found +at lines 2 and 3 in the input file. +If the scanner is in that state and then reads something other than an +.Sq o , +it will have to back up to find a rule which is matched. +With a bit of headscratching one can see that this must be the +state it's in when it has seen +.Sq fo . +When this has happened, if anything other than another +.Sq o +is seen, the scanner will have to back up to simply match the +.Sq f +.Pq by the default rule . +.Pp +The comment regarding State #8 indicates there's a problem when +.Qq foob +has been scanned. +Indeed, on any character other than an +.Sq a , +the scanner will have to back up to accept +.Qq foo . +Similarly, the comment for State #9 concerns when +.Qq fooba +has been scanned and an +.Sq r +does not follow. +.Pp +The final comment reminds us that there's no point going to +all the trouble of removing backing up from the rules unless we're using +.Fl Cf +or +.Fl CF , +since there's no performance gain doing so with compressed scanners. +.Pp +The way to remove the backing up is to add +.Qq error +rules: +.Bd -literal -offset indent +%% +foo return TOK_KEYWORD; +foobar return TOK_KEYWORD; + +fooba | +foob | +fo { + /* false alarm, not really a keyword */ + return TOK_ID; +} +.Ed +.Pp +Eliminating backing up among a list of keywords can also be done using a +.Qq catch-all +rule: +.Bd -literal -offset indent +%% +foo return TOK_KEYWORD; +foobar return TOK_KEYWORD; + +[a-z]+ return TOK_ID; +.Ed +.Pp +This is usually the best solution when appropriate. +.Pp +Backing up messages tend to cascade. +With a complicated set of rules it's not uncommon to get hundreds of messages. +If one can decipher them, though, +it often only takes a dozen or so rules to eliminate the backing up +(though it's easy to make a mistake and have an error rule accidentally match +a valid token; a possible future +.Nm +feature will be to automatically add rules to eliminate backing up). +.Pp +It's important to keep in mind that the benefits of eliminating +backing up are gained only if +.Em every +instance of backing up is eliminated. +Leaving just one gains nothing. +.Pp +.Em Variable +trailing context +(where both the leading and trailing parts do not have a fixed length) +entails almost the same performance loss as +.Em REJECT +.Pq i.e., substantial . +So when possible a rule like: +.Bd -literal -offset indent +%% +mouse|rat/(cat|dog) run(); +.Ed +.Pp +is better written: +.Bd -literal -offset indent +%% +mouse/cat|dog run(); +rat/cat|dog run(); +.Ed +.Pp +or as +.Bd -literal -offset indent +%% +mouse|rat/cat run(); +mouse|rat/dog run(); +.Ed +.Pp +Note that here the special +.Sq |\& +action does not provide any savings, and can even make things worse (see +.Sx BUGS +below). +.Pp +Another area where the user can increase a scanner's performance +.Pq and one that's easier to implement +arises from the fact that the longer the tokens matched, +the faster the scanner will run. +This is because with long tokens the processing of most input +characters takes place in the +.Pq short +inner scanning loop, and does not often have to go through the additional work +of setting up the scanning environment (e.g., +.Fa yytext ) +for the action. +Recall the scanner for C comments: +.Bd -literal -offset indent +%x comment +%% +int line_num = 1; + +"/*" BEGIN(comment); + +[^*\en]* +"*"+[^*/\en]* +\en ++line_num; +"*"+"/" BEGIN(INITIAL); +.Ed +.Pp +This could be sped up by writing it as: +.Bd -literal -offset indent +%x comment +%% +int line_num = 1; + +"/*" BEGIN(comment); + +[^*\en]* +[^*\en]*\en ++line_num; +"*"+[^*/\en]* +"*"+[^*/\en]*\en ++line_num; +"*"+"/" BEGIN(INITIAL); +.Ed +.Pp +Now instead of each newline requiring the processing of another action, +recognizing the newlines is +.Qq distributed +over the other rules to keep the matched text as long as possible. +Note that adding rules does +.Em not +slow down the scanner! +The speed of the scanner is independent of the number of rules or +(modulo the considerations given at the beginning of this section) +how complicated the rules are with regard to operators such as +.Sq * +and +.Sq |\& . +.Pp +A final example in speeding up a scanner: +scan through a file containing identifiers and keywords, one per line +and with no other extraneous characters, and recognize all the keywords. +A natural first approach is: +.Bd -literal -offset indent +%% +asm | +auto | +break | +\&... etc ... +volatile | +while /* it's a keyword */ + +\&.|\en /* it's not a keyword */ +.Ed +.Pp +To eliminate the back-tracking, introduce a catch-all rule: +.Bd -literal -offset indent +%% +asm | +auto | +break | +\&... etc ... +volatile | +while /* it's a keyword */ + +[a-z]+ | +\&.|\en /* it's not a keyword */ +.Ed +.Pp +Now, if it's guaranteed that there's exactly one word per line, +then we can reduce the total number of matches by a half by +merging in the recognition of newlines with that of the other tokens: +.Bd -literal -offset indent +%% +asm\en | +auto\en | +break\en | +\&... etc ... +volatile\en | +while\en /* it's a keyword */ + +[a-z]+\en | +\&.|\en /* it's not a keyword */ +.Ed +.Pp +One has to be careful here, +as we have now reintroduced backing up into the scanner. +In particular, while we know that there will never be any characters +in the input stream other than letters or newlines, +.Nm +can't figure this out, and it will plan for possibly needing to back up +when it has scanned a token like +.Qq auto +and then the next character is something other than a newline or a letter. +Previously it would then just match the +.Qq auto +rule and be done, but now it has no +.Qq auto +rule, only an +.Qq auto\en +rule. +To eliminate the possibility of backing up, +we could either duplicate all rules but without final newlines or, +since we never expect to encounter such an input and therefore don't +how it's classified, we can introduce one more catch-all rule, +this one which doesn't include a newline: +.Bd -literal -offset indent +%% +asm\en | +auto\en | +break\en | +\&... etc ... +volatile\en | +while\en /* it's a keyword */ + +[a-z]+\en | +[a-z]+ | +\&.|\en /* it's not a keyword */ +.Ed +.Pp +Compiled with +.Fl Cf , +this is about as fast as one can get a +.Nm +scanner to go for this particular problem. +.Pp +A final note: +.Nm +is slow when matching NUL's, +particularly when a token contains multiple NUL's. +It's best to write rules which match short +amounts of text if it's anticipated that the text will often include NUL's. +.Pp +Another final note regarding performance: as mentioned above in the section +.Sx HOW THE INPUT IS MATCHED , +dynamically resizing +.Fa yytext +to accommodate huge tokens is a slow process because it presently requires that +the +.Pq huge +token be rescanned from the beginning. +Thus if performance is vital, it is better to attempt to match +.Qq large +quantities of text but not +.Qq huge +quantities, where the cutoff between the two is at about 8K characters/token. +.Sh GENERATING C++ SCANNERS +.Nm +provides two different ways to generate scanners for use with C++. +The first way is to simply compile a scanner generated by +.Nm +using a C++ compiler instead of a C compiler. +This should not generate any compilation errors +(please report any found to the email address given in the +.Sx AUTHORS +section below). +C++ code can then be used in rule actions instead of C code. +Note that the default input source for scanners remains +.Fa yyin , +and default echoing is still done to +.Fa yyout . +Both of these remain +.Fa FILE * +variables and not C++ streams. +.Pp +.Nm +can also be used to generate a C++ scanner class, using the +.Fl + +option (or, equivalently, +.Dq %option c++ ) , +which is automatically specified if the name of the flex executable ends in a +.Sq + , +such as +.Nm flex++ . +When using this option, +.Nm +defaults to generating the scanner to the file +.Pa lex.yy.cc +instead of +.Pa lex.yy.c . +The generated scanner includes the header file +.In g++/FlexLexer.h , +which defines the interface to two C++ classes. +.Pp +The first class, +.Em FlexLexer , +provides an abstract base class defining the general scanner class interface. +It provides the following member functions: +.Bl -tag -width Ds +.It const char* YYText() +Returns the text of the most recently matched token, the equivalent of +.Fa yytext . +.It int YYLeng() +Returns the length of the most recently matched token, the equivalent of +.Fa yyleng . +.It int lineno() const +Returns the current input line number +(see +.Dq %option yylineno ) , +or 1 if +.Dq %option yylineno +was not used. +.It void set_debug(int flag) +Sets the debugging flag for the scanner, equivalent to assigning to +.Fa yy_flex_debug +(see the +.Sx OPTIONS +section above). +Note that the scanner must be built using +.Dq %option debug +to include debugging information in it. +.It int debug() const +Returns the current setting of the debugging flag. +.El +.Pp +Also provided are member functions equivalent to +.Fn yy_switch_to_buffer , +.Fn yy_create_buffer +(though the first argument is an +.Fa std::istream* +object pointer and not a +.Fa FILE* ) , +.Fn yy_flush_buffer , +.Fn yy_delete_buffer , +and +.Fn yyrestart +(again, the first argument is an +.Fa std::istream* +object pointer). +.Pp +The second class defined in +.In g++/FlexLexer.h +is +.Fa yyFlexLexer , +which is derived from +.Fa FlexLexer . +It defines the following additional member functions: +.Bl -tag -width Ds +.It "yyFlexLexer(std::istream* arg_yyin = 0, std::ostream* arg_yyout = 0)" +Constructs a +.Fa yyFlexLexer +object using the given streams for input and output. +If not specified, the streams default to +.Fa cin +and +.Fa cout , +respectively. +.It virtual int yylex() +Performs the same role as +.Fn yylex +does for ordinary flex scanners: it scans the input stream, consuming +tokens, until a rule's action returns a value. +If subclass +.Sq S +is derived from +.Fa yyFlexLexer , +in order to access the member functions and variables of +.Sq S +inside +.Fn yylex , +use +.Dq %option yyclass="S" +to inform +.Nm +that the +.Sq S +subclass will be used instead of +.Fa yyFlexLexer . +In this case, rather than generating +.Dq yyFlexLexer::yylex() , +.Nm +generates +.Dq S::yylex() +(and also generates a dummy +.Dq yyFlexLexer::yylex() +that calls +.Dq yyFlexLexer::LexerError() +if called). +.It "virtual void switch_streams(std::istream* new_in = 0, std::ostream* new_out = 0)" +Reassigns +.Fa yyin +to +.Fa new_in +.Pq if non-nil +and +.Fa yyout +to +.Fa new_out +.Pq ditto , +deleting the previous input buffer if +.Fa yyin +is reassigned. +.It int yylex(std::istream* new_in, std::ostream* new_out = 0) +First switches the input streams via +.Dq switch_streams(new_in, new_out) +and then returns the value of +.Fn yylex . +.El +.Pp +In addition, +.Fa yyFlexLexer +defines the following protected virtual functions which can be redefined +in derived classes to tailor the scanner: +.Bl -tag -width Ds +.It virtual int LexerInput(char* buf, int max_size) +Reads up to +.Fa max_size +characters into +.Fa buf +and returns the number of characters read. +To indicate end-of-input, return 0 characters. +Note that +.Qq interactive +scanners (see the +.Fl B +and +.Fl I +flags) define the macro +.Dv YY_INTERACTIVE . +If +.Fn LexerInput +has been redefined, and it's necessary to take different actions depending on +whether or not the scanner might be scanning an interactive input source, +it's possible to test for the presence of this name via +.Dq #ifdef . +.It virtual void LexerOutput(const char* buf, int size) +Writes out +.Fa size +characters from the buffer +.Fa buf , +which, while NUL-terminated, may also contain +.Qq internal +NUL's if the scanner's rules can match text with NUL's in them. +.It virtual void LexerError(const char* msg) +Reports a fatal error message. +The default version of this function writes the message to the stream +.Fa cerr +and exits. +.El +.Pp +Note that a +.Fa yyFlexLexer +object contains its entire scanning state. +Thus such objects can be used to create reentrant scanners. +Multiple instances of the same +.Fa yyFlexLexer +class can be instantiated, and multiple C++ scanner classes can be combined +in the same program using the +.Fl P +option discussed above. +.Pp +Finally, note that the +.Dq %array +feature is not available to C++ scanner classes; +.Dq %pointer +must be used +.Pq the default . +.Pp +Here is an example of a simple C++ scanner: +.Bd -literal -offset indent +// An example of using the flex C++ scanner class. + +%{ +#include +int mylineno = 0; +%} + +string \e"[^\en"]+\e" + +ws [ \et]+ + +alpha [A-Za-z] +dig [0-9] +name ({alpha}|{dig}|\e$)({alpha}|{dig}|[_.\e-/$])* +num1 [-+]?{dig}+\e.?([eE][-+]?{dig}+)? +num2 [-+]?{dig}*\e.{dig}+([eE][-+]?{dig}+)? +number {num1}|{num2} + +%% + +{ws} /* skip blanks and tabs */ + +"/*" { + int c; + + while ((c = yyinput()) != 0) { + if(c == '\en') + ++mylineno; + else if(c == '*') { + if ((c = yyinput()) == '/') + break; + else + unput(c); + } + } +} + +{number} cout << "number " << YYText() << '\en'; + +\en mylineno++; + +{name} cout << "name " << YYText() << '\en'; + +{string} cout << "string " << YYText() << '\en'; + +%% + +int main(int /* argc */, char** /* argv */) +{ + FlexLexer* lexer = new yyFlexLexer; + while(lexer->yylex() != 0) + ; + return 0; +} +.Ed +.Pp +To create multiple +.Pq different +lexer classes, use the +.Fl P +flag +(or the +.Dq prefix= +option) +to rename each +.Fa yyFlexLexer +to some other +.Fa xxFlexLexer . +.In g++/FlexLexer.h +can then be included in other sources once per lexer class, first renaming +.Fa yyFlexLexer +as follows: +.Bd -literal -offset indent +#undef yyFlexLexer +#define yyFlexLexer xxFlexLexer +#include + +#undef yyFlexLexer +#define yyFlexLexer zzFlexLexer +#include +.Ed +.Pp +If, for example, +.Dq %option prefix="xx" +is used for one scanner and +.Dq %option prefix="zz" +is used for the other. +.Pp +.Sy IMPORTANT : +the present form of the scanning class is experimental +and may change considerably between major releases. +.Sh INCOMPATIBILITIES WITH LEX AND POSIX +.Nm +is a rewrite of the +.At +.Nm lex +tool +(the two implementations do not share any code, though), +with some extensions and incompatibilities, both of which are of concern +to those who wish to write scanners acceptable to either implementation. +.Nm +is fully compliant with the +.Tn POSIX +.Nm lex +specification, except that when using +.Dq %pointer +.Pq the default , +a call to +.Fn unput +destroys the contents of +.Fa yytext , +which is counter to the +.Tn POSIX +specification. +.Pp +In this section we discuss all of the known areas of incompatibility between +.Nm , +.At +.Nm lex , +and the +.Tn POSIX +specification. +.Pp +.Nm flex Ns 's +.Fl l +option turns on maximum compatibility with the original +.At +.Nm lex +implementation, at the cost of a major loss in the generated scanner's +performance. +We note below which incompatibilities can be overcome using the +.Fl l +option. +.Pp +.Nm +is fully compatible with +.Nm lex +with the following exceptions: +.Bl -dash +.It +The undocumented +.Nm lex +scanner internal variable +.Fa yylineno +is not supported unless +.Fl l +or +.Dq %option yylineno +is used. +.Pp +.Fa yylineno +should be maintained on a per-buffer basis, rather than a per-scanner +.Pq single global variable +basis. +.Pp +.Fa yylineno +is not part of the +.Tn POSIX +specification. +.It +The +.Fn input +routine is not redefinable, though it may be called to read characters +following whatever has been matched by a rule. +If +.Fn input +encounters an end-of-file, the normal +.Fn yywrap +processing is done. +A +.Dq real +end-of-file is returned by +.Fn input +as +.Dv EOF . +.Pp +Input is instead controlled by defining the +.Dv YY_INPUT +macro. +.Pp +The +.Nm +restriction that +.Fn input +cannot be redefined is in accordance with the +.Tn POSIX +specification, which simply does not specify any way of controlling the +scanner's input other than by making an initial assignment to +.Fa yyin . +.It +The +.Fn unput +routine is not redefinable. +This restriction is in accordance with +.Tn POSIX . +.It +.Nm +scanners are not as reentrant as +.Nm lex +scanners. +In particular, if a scanner is interactive and +an interrupt handler long-jumps out of the scanner, +and the scanner is subsequently called again, +the following error message may be displayed: +.Pp +.D1 fatal flex scanner internal error--end of buffer missed +.Pp +To reenter the scanner, first use +.Pp +.Dl yyrestart(yyin); +.Pp +Note that this call will throw away any buffered input; +usually this isn't a problem with an interactive scanner. +.Pp +Also note that flex C++ scanner classes are reentrant, +so if using C++ is an option , they should be used instead. +See +.Sx GENERATING C++ SCANNERS +above for details. +.It +.Fn output +is not supported. +Output from the +.Em ECHO +macro is done to the file-pointer +.Fa yyout +.Pq default stdout . +.Pp +.Fn output +is not part of the +.Tn POSIX +specification. +.It +.Nm lex +does not support exclusive start conditions +.Pq %x , +though they are in the +.Tn POSIX +specification. +.It +When definitions are expanded, +.Nm +encloses them in parentheses. +With +.Nm lex , +the following: +.Bd -literal -offset indent +NAME [A-Z][A-Z0-9]* +%% +foo{NAME}? printf("Found it\en"); +%% +.Ed +.Pp +will not match the string +.Qq foo +because when the macro is expanded the rule is equivalent to +.Qq foo[A-Z][A-Z0-9]*? +and the precedence is such that the +.Sq ?\& +is associated with +.Qq [A-Z0-9]* . +With +.Nm , +the rule will be expanded to +.Qq foo([A-Z][A-Z0-9]*)? +and so the string +.Qq foo +will match. +.Pp +Note that if the definition begins with +.Sq ^ +or ends with +.Sq $ +then it is not expanded with parentheses, to allow these operators to appear in +definitions without losing their special meanings. +But the +.Sq Aq s , +.Sq / , +and +.Aq Aq EOF +operators cannot be used in a +.Nm +definition. +.Pp +Using +.Fl l +results in the +.Nm lex +behavior of no parentheses around the definition. +.Pp +The +.Tn POSIX +specification is that the definition be enclosed in parentheses. +.It +Some implementations of +.Nm lex +allow a rule's action to begin on a separate line, +if the rule's pattern has trailing whitespace: +.Bd -literal -offset indent +%% +foo|bar + { foobar_action(); } +.Ed +.Pp +.Nm +does not support this feature. +.It +The +.Nm lex +.Sq %r +.Pq generate a Ratfor scanner +option is not supported. +It is not part of the +.Tn POSIX +specification. +.It +After a call to +.Fn unput , +.Fa yytext +is undefined until the next token is matched, +unless the scanner was built using +.Dq %array . +This is not the case with +.Nm lex +or the +.Tn POSIX +specification. +The +.Fl l +option does away with this incompatibility. +.It +The precedence of the +.Sq {} +.Pq numeric range +operator is different. +.Nm lex +interprets +.Qq abc{1,3} +as match one, two, or three occurrences of +.Sq abc , +whereas +.Nm +interprets it as match +.Sq ab +followed by one, two, or three occurrences of +.Sq c . +The latter is in agreement with the +.Tn POSIX +specification. +.It +The precedence of the +.Sq ^ +operator is different. +.Nm lex +interprets +.Qq ^foo|bar +as match either +.Sq foo +at the beginning of a line, or +.Sq bar +anywhere, whereas +.Nm +interprets it as match either +.Sq foo +or +.Sq bar +if they come at the beginning of a line. +The latter is in agreement with the +.Tn POSIX +specification. +.It +The special table-size declarations such as +.Sq %a +supported by +.Nm lex +are not required by +.Nm +scanners; +.Nm +ignores them. +.It +The name +.Dv FLEX_SCANNER +is #define'd so scanners may be written for use with either +.Nm +or +.Nm lex . +Scanners also include +.Dv YY_FLEX_MAJOR_VERSION +and +.Dv YY_FLEX_MINOR_VERSION +indicating which version of +.Nm +generated the scanner +(for example, for the 2.5 release, these defines would be 2 and 5, +respectively). +.El +.Pp +The following +.Nm +features are not included in +.Nm lex +or the +.Tn POSIX +specification: +.Bd -unfilled -offset indent +C++ scanners +%option +start condition scopes +start condition stacks +interactive/non-interactive scanners +yy_scan_string() and friends +yyterminate() +yy_set_interactive() +yy_set_bol() +YY_AT_BOL() +<> +<*> +YY_DECL +YY_START +YY_USER_ACTION +YY_USER_INIT +#line directives +%{}'s around actions +multiple actions on a line +.Ed +.Pp +plus almost all of the +.Nm +flags. +The last feature in the list refers to the fact that with +.Nm +multiple actions can be placed on the same line, +separated with semi-colons, while with +.Nm lex , +the following +.Pp +.Dl foo handle_foo(); ++num_foos_seen; +.Pp +is +.Pq rather surprisingly +truncated to +.Pp +.Dl foo handle_foo(); +.Pp +.Nm +does not truncate the action. +Actions that are not enclosed in braces +are simply terminated at the end of the line. +.Sh FILES +.Bl -tag -width "" +.It Pa flex.skl +Skeleton scanner. +This file is only used when building flex, not when +.Nm +executes. +.It Pa lex.backup +Backing-up information for the +.Fl b +flag (called +.Pa lex.bck +on some systems). +.It Pa lex.yy.c +Generated scanner +(called +.Pa lexyy.c +on some systems). +.It Pa lex.yy.cc +Generated C++ scanner class, when using +.Fl + . +.It In g++/FlexLexer.h +Header file defining the C++ scanner base class, +.Fa FlexLexer , +and its derived class, +.Fa yyFlexLexer . +.It Pa /usr/lib/libl.* +.Nm +libraries. +The +.Pa /usr/lib/libfl.*\& +libraries are links to these. +Scanners must be linked using either +.Fl \&ll +or +.Fl lfl . +.El +.Sh EXIT STATUS +.Ex -std flex +.Sh DIAGNOSTICS +.Bl -diag +.It warning, rule cannot be matched +Indicates that the given rule cannot be matched because it follows other rules +that will always match the same text as it. +For example, in the following +.Dq foo +cannot be matched because it comes after an identifier +.Qq catch-all +rule: +.Bd -literal -offset indent +[a-z]+ got_identifier(); +foo got_foo(); +.Ed +.Pp +Using +.Em REJECT +in a scanner suppresses this warning. +.It "warning, \-s option given but default rule can be matched" +Means that it is possible +.Pq perhaps only in a particular start condition +that the default rule +.Pq match any single character +is the only one that will match a particular input. +Since +.Fl s +was given, presumably this is not intended. +.It reject_used_but_not_detected undefined +.It yymore_used_but_not_detected undefined +These errors can occur at compile time. +They indicate that the scanner uses +.Em REJECT +or +.Fn yymore +but that +.Nm +failed to notice the fact, meaning that +.Nm +scanned the first two sections looking for occurrences of these actions +and failed to find any, but somehow they snuck in +.Pq via an #include file, for example . +Use +.Dq %option reject +or +.Dq %option yymore +to indicate to +.Nm +that these features are really needed. +.It flex scanner jammed +A scanner compiled with +.Fl s +has encountered an input string which wasn't matched by any of its rules. +This error can also occur due to internal problems. +.It token too large, exceeds YYLMAX +The scanner uses +.Dq %array +and one of its rules matched a string longer than the +.Dv YYLMAX +constant +.Pq 8K bytes by default . +The value can be increased by #define'ing +.Dv YYLMAX +in the definitions section of +.Nm +input. +.It "scanner requires \-8 flag to use the character 'x'" +The scanner specification includes recognizing the 8-bit character +.Sq x +and the +.Fl 8 +flag was not specified, and defaulted to 7-bit because the +.Fl Cf +or +.Fl CF +table compression options were used. +See the discussion of the +.Fl 7 +flag for details. +.It flex scanner push-back overflow +unput() was used to push back so much text that the scanner's buffer +could not hold both the pushed-back text and the current token in +.Fa yytext . +Ideally the scanner should dynamically resize the buffer in this case, +but at present it does not. +.It "input buffer overflow, can't enlarge buffer because scanner uses REJECT" +The scanner was working on matching an extremely large token and needed +to expand the input buffer. +This doesn't work with scanners that use +.Em REJECT . +.It "fatal flex scanner internal error--end of buffer missed" +This can occur in an scanner which is reentered after a long-jump +has jumped out +.Pq or over +the scanner's activation frame. +Before reentering the scanner, use: +.Pp +.Dl yyrestart(yyin); +.Pp +or, as noted above, switch to using the C++ scanner class. +.It "too many start conditions in <> construct!" +More start conditions than exist were listed in a <> construct +(so at least one of them must have been listed twice). +.El +.Sh SEE ALSO +.Xr awk 1 , +.Xr sed 1 , +.Xr yacc 1 +.Rs +.%A John Levine +.%A Tony Mason +.%A Doug Brown +.%B Lex & Yacc +.%I O'Reilly and Associates +.%N 2nd edition +.Re +.Rs +.%A Alfred Aho +.%A Ravi Sethi +.%A Jeffrey Ullman +.%B Compilers: Principles, Techniques and Tools +.%I Addison-Wesley +.%D 1986 +.%O "Describes the pattern-matching techniques used by flex (deterministic finite automata)" +.Re +.Sh STANDARDS +The +.Nm lex +utility is compliant with the +.St -p1003.1-2008 +specification, +though its presence is optional. +.Pp +The flags +.Op Fl 78BbCdFfhIiLloPpSsTVw+? , +.Op Fl -help , +and +.Op Fl -version +are extensions to that specification. +.Pp +See also the +.Sx INCOMPATIBILITIES WITH LEX AND POSIX +section, above. +.Sh AUTHORS +Vern Paxson, with the help of many ideas and much inspiration from +Van Jacobson. +Original version by Jef Poskanzer. +The fast table representation is a partial implementation of a design done by +Van Jacobson. +The implementation was done by Kevin Gong and Vern Paxson. +.Pp +Thanks to the many +.Nm +beta-testers, feedbackers, and contributors, especially Francois Pinard, +Casey Leedom, +Robert Abramovitz, +Stan Adermann, Terry Allen, David Barker-Plummer, John Basrai, +Neal Becker, Nelson H.F. Beebe, +.Mt benson@odi.com , +Karl Berry, Peter A. Bigot, Simon Blanchard, +Keith Bostic, Frederic Brehm, Ian Brockbank, Kin Cho, Nick Christopher, +Brian Clapper, J.T. Conklin, +Jason Coughlin, Bill Cox, Nick Cropper, Dave Curtis, Scott David +Daniels, Chris G. Demetriou, Theo de Raadt, +Mike Donahue, Chuck Doucette, Tom Epperly, Leo Eskin, +Chris Faylor, Chris Flatters, Jon Forrest, Jeffrey Friedl, +Joe Gayda, Kaveh R. Ghazi, Wolfgang Glunz, +Eric Goldman, Christopher M. Gould, Ulrich Grepel, Peer Griebel, +Jan Hajic, Charles Hemphill, NORO Hideo, +Jarkko Hietaniemi, Scott Hofmann, +Jeff Honig, Dana Hudes, Eric Hughes, John Interrante, +Ceriel Jacobs, Michal Jaegermann, Sakari Jalovaara, Jeffrey R. Jones, +Henry Juengst, Klaus Kaempf, Jonathan I. Kamens, Terrence O Kane, +Amir Katz, +.Mt ken@ken.hilco.com , +Kevin B. Kenny, +Steve Kirsch, Winfried Koenig, Marq Kole, Ronald Lamprecht, +Greg Lee, Rohan Lenard, Craig Leres, John Levine, Steve Liddle, +David Loffredo, Mike Long, +Mohamed el Lozy, Brian Madsen, Malte, Joe Marshall, +Bengt Martensson, Chris Metcalf, +Luke Mewburn, Jim Meyering, R. Alexander Milowski, Erik Naggum, +G.T. Nicol, Landon Noll, James Nordby, Marc Nozell, +Richard Ohnemus, Karsten Pahnke, +Sven Panne, Roland Pesch, Walter Pelissero, Gaumond Pierre, +Esmond Pitt, Jef Poskanzer, Joe Rahmeh, Jarmo Raiha, +Frederic Raimbault, Pat Rankin, Rick Richardson, +Kevin Rodgers, Kai Uwe Rommel, Jim Roskind, Alberto Santini, +Andreas Scherer, Darrell Schiebel, Raf Schietekat, +Doug Schmidt, Philippe Schnoebelen, Andreas Schwab, +Larry Schwimmer, Alex Siegel, Eckehard Stolz, Jan-Erik Strvmquist, +Mike Stump, Paul Stuart, Dave Tallman, Ian Lance Taylor, +Chris Thewalt, Richard M. Timoney, Jodi Tsai, +Paul Tuinenga, Gary Weik, Frank Whaley, Gerhard Wilhelms, Kent Williams, +Ken Yap, Ron Zellar, Nathan Zelle, David Zuhn, +and those whose names have slipped my marginal mail-archiving skills +but whose contributions are appreciated all the +same. +.Pp +Thanks to Keith Bostic, Jon Forrest, Noah Friedman, +John Gilmore, Craig Leres, John Levine, Bob Mulcahy, G.T. +Nicol, Francois Pinard, Rich Salz, and Richard Stallman for help with various +distribution headaches. +.Pp +Thanks to Esmond Pitt and Earle Horton for 8-bit character support; +to Benson Margulies and Fred Burke for C++ support; +to Kent Williams and Tom Epperly for C++ class support; +to Ove Ewerlid for support of NUL's; +and to Eric Hughes for support of multiple buffers. +.Pp +This work was primarily done when I was with the Real Time Systems Group +at the Lawrence Berkeley Laboratory in Berkeley, CA. +Many thanks to all there for the support I received. +.Pp +Send comments to +.Aq Mt vern@ee.lbl.gov . +.Sh BUGS +Some trailing context patterns cannot be properly matched and generate +warning messages +.Pq "dangerous trailing context" . +These are patterns where the ending of the first part of the rule +matches the beginning of the second part, such as +.Qq zx*/xy* , +where the +.Sq x* +matches the +.Sq x +at the beginning of the trailing context. +(Note that the POSIX draft states that the text matched by such patterns +is undefined.) +.Pp +For some trailing context rules, parts which are actually fixed-length are +not recognized as such, leading to the above mentioned performance loss. +In particular, parts using +.Sq |\& +or +.Sq {n} +(such as +.Qq foo{3} ) +are always considered variable-length. +.Pp +Combining trailing context with the special +.Sq |\& +action can result in fixed trailing context being turned into +the more expensive variable trailing context. +For example, in the following: +.Bd -literal -offset indent +%% +abc | +xyz/def +.Ed +.Pp +Use of +.Fn unput +invalidates yytext and yyleng, unless the +.Dq %array +directive +or the +.Fl l +option has been used. +.Pp +Pattern-matching of NUL's is substantially slower than matching other +characters. +.Pp +Dynamic resizing of the input buffer is slow, as it entails rescanning +all the text matched so far by the current +.Pq generally huge +token. +.Pp +Due to both buffering of input and read-ahead, +it is not possible to intermix calls to +.In stdio.h +routines, such as, for example, +.Fn getchar , +with +.Nm +rules and expect it to work. +Call +.Fn input +instead. +.Pp +The total table entries listed by the +.Fl v +flag excludes the number of table entries needed to determine +what rule has been matched. +The number of entries is equal to the number of DFA states +if the scanner does not use +.Em REJECT , +and somewhat greater than the number of states if it does. +.Pp +.Em REJECT +cannot be used with the +.Fl f +or +.Fl F +options. +.Pp +The +.Nm +internal algorithms need documentation. diff --git a/third_party/lex/flex.skl b/third_party/lex/flex.skl new file mode 100644 index 00000000..ca36c8fe --- /dev/null +++ b/third_party/lex/flex.skl @@ -0,0 +1,3451 @@ +/* $OpenBSD: flex.skl,v 1.16 2017/05/02 19:16:19 millert Exp $ */ + +%# -*-C-*- vi: set ft=c: +%# This file is processed in several stages. +%# Here are the stages, as best as I can describe: +%# +%# 1. flex.skl is processed through GNU m4 during the +%# pre-compilation stage of flex. Only macros starting +%# with `m4preproc_' are processed, and quoting is normal. +%# +%# 2. The preprocessed skeleton is translated verbatim into a +%# C array, saved as "skel.c" and compiled into the flex binary. +%# +%# 3. At runtime, the skeleton is generated and filtered (again) +%# through m4. Macros beginning with `m4_' will be processed. +%# The quoting is "[[" and "]]" so we don't interfere with +%# user code. +%# +%# All generate macros for the m4 stage contain the text "m4" or "M4" +%# in them. This is to distinguish them from CPP macros. +%# The exception to this rule is YY_G, which is an m4 macro, +%# but it needs to be remain short because it is used everywhere. +%# +/* A lexical scanner generated by flex */ + +%# Macros for preproc stage. +m4preproc_changecom + +%# Macros for runtime processing stage. +m4_changecom +m4_changequote +m4_changequote([[, ]]) + +%# +%# Lines in this skeleton starting with a "%" character are "control lines" +%# and affect the generation of the scanner. The possible control codes are +%# listed and processed in misc.c. +%# +%# %# - A comment. The current line is omitted from the generated scanner. +%# %if-c++-only - The following lines are printed for C++ scanners ONLY. +%# %if-c-only - The following lines are NOT printed for C++ scanners. +%# %if-c-or-c++ - The following lines are printed in BOTH C and C++ scanners. +%# %if-reentrant - Print for reentrant scanners.(push) +%# %if-not-reentrant - Print for non-reentrant scanners. (push) +%# %if-bison-bridge - Print for bison-bridge. (push) +%# %if-not-bison-bridge - Print for non-bison-bridge. (push) +%# %endif - pop from the previous if code. +%# %% - A stop-point, where code is inserted by flex. +%# Each stop-point is numbered here and also in the code generator. +%# (See gen.c, etc. for details.) +%# %not-for-header - Begin code that should NOT appear in a ".h" file. +%# %ok-for-header - %c and %e are used for building a header file. +%# %if-tables-serialization +%# +%# All control-lines EXCEPT comment lines ("%#") will be inserted into +%# the generated scanner as a C-style comment. This is to aid those who +%# edit the skeleton. +%# + +%not-for-header +%if-c-only +%if-not-reentrant +m4_ifelse(M4_YY_PREFIX,yy,, +#define yy_create_buffer M4_YY_PREFIX[[_create_buffer]] +#define yy_delete_buffer M4_YY_PREFIX[[_delete_buffer]] +#define yy_flex_debug M4_YY_PREFIX[[_flex_debug]] +#define yy_init_buffer M4_YY_PREFIX[[_init_buffer]] +#define yy_flush_buffer M4_YY_PREFIX[[_flush_buffer]] +#define yy_load_buffer_state M4_YY_PREFIX[[_load_buffer_state]] +#define yy_switch_to_buffer M4_YY_PREFIX[[_switch_to_buffer]] +#define yyin M4_YY_PREFIX[[in]] +#define yyleng M4_YY_PREFIX[[leng]] +#define yylex M4_YY_PREFIX[[lex]] +#define yylineno M4_YY_PREFIX[[lineno]] +#define yyout M4_YY_PREFIX[[out]] +#define yyrestart M4_YY_PREFIX[[restart]] +#define yytext M4_YY_PREFIX[[text]] +#define yywrap M4_YY_PREFIX[[wrap]] +#define yyalloc M4_YY_PREFIX[[alloc]] +#define yyrealloc M4_YY_PREFIX[[realloc]] +#define yyfree M4_YY_PREFIX[[free]] +) +%endif +%endif +%ok-for-header + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION FLEX_MAJOR_VERSION +#define YY_FLEX_MINOR_VERSION FLEX_MINOR_VERSION +#define YY_FLEX_SUBMINOR_VERSION FLEX_SUBMINOR_VERSION +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +%# Some negated symbols +m4_ifdef( [[M4_YY_IN_HEADER]], , [[m4_define([[M4_YY_NOT_IN_HEADER]], [[]])]]) +m4_ifdef( [[M4_YY_REENTRANT]], , [[m4_define([[M4_YY_NOT_REENTRANT]], [[]])]]) + +%# This is the m4 way to say "(stack_used || is_reentrant) +m4_ifdef( [[M4_YY_STACK_USED]], [[m4_define([[M4_YY_HAS_START_STACK_VARS]])]]) +m4_ifdef( [[M4_YY_REENTRANT]], [[m4_define([[M4_YY_HAS_START_STACK_VARS]])]]) + +%# Prefixes. +%# The complexity here is necessary so that m4 preserves +%# the argument lists to each C function. + + +m4_ifdef( [[M4_YY_PREFIX]],, [[m4_define([[M4_YY_PREFIX]], [[yy]])]]) + +m4preproc_define(`M4_GEN_PREFIX', + ``m4_define(yy[[$1]], [[M4_YY_PREFIX[[$1]]m4_ifelse($'`#,0,,[[($'`@)]])]])'') + +%if-c++-only + /* The c++ scanner is a mess. The FlexLexer.h header file relies on the + * following macro. This is required in order to pass the c++-multiple-scanners + * test in the regression suite. We get reports that it breaks inheritance. + * We will address this in a future release of flex, or omit the C++ scanner + * altogether. + */ + #define yyFlexLexer M4_YY_PREFIX[[FlexLexer]] +%endif + +%if-c-only + M4_GEN_PREFIX(`_create_buffer') + M4_GEN_PREFIX(`_delete_buffer') + M4_GEN_PREFIX(`_scan_buffer') + M4_GEN_PREFIX(`_scan_string') + M4_GEN_PREFIX(`_scan_bytes') + M4_GEN_PREFIX(`_init_buffer') + M4_GEN_PREFIX(`_flush_buffer') + M4_GEN_PREFIX(`_load_buffer_state') + M4_GEN_PREFIX(`_switch_to_buffer') + M4_GEN_PREFIX(`push_buffer_state') + M4_GEN_PREFIX(`pop_buffer_state') + M4_GEN_PREFIX(`ensure_buffer_stack') + M4_GEN_PREFIX(`lex') + M4_GEN_PREFIX(`restart') + M4_GEN_PREFIX(`lex_init') + M4_GEN_PREFIX(`lex_init_extra') + M4_GEN_PREFIX(`lex_destroy') + M4_GEN_PREFIX(`get_debug') + M4_GEN_PREFIX(`set_debug') + M4_GEN_PREFIX(`get_extra') + M4_GEN_PREFIX(`set_extra') + M4_GEN_PREFIX(`get_in') + M4_GEN_PREFIX(`set_in') + M4_GEN_PREFIX(`get_out') + M4_GEN_PREFIX(`set_out') + M4_GEN_PREFIX(`get_leng') + M4_GEN_PREFIX(`get_text') + M4_GEN_PREFIX(`get_lineno') + M4_GEN_PREFIX(`set_lineno') + m4_ifdef( [[M4_YY_REENTRANT]], + [[ + M4_GEN_PREFIX(`get_column') + M4_GEN_PREFIX(`set_column') + ]]) + M4_GEN_PREFIX(`wrap') +%endif + +m4_ifdef( [[M4_YY_BISON_LVAL]], +[[ + M4_GEN_PREFIX(`get_lval') + M4_GEN_PREFIX(`set_lval') +]]) + +m4_ifdef( [[]], +[[ + M4_GEN_PREFIX(`get_lloc') + M4_GEN_PREFIX(`set_lloc') +]]) + + + M4_GEN_PREFIX(`alloc') + M4_GEN_PREFIX(`realloc') + M4_GEN_PREFIX(`free') + +%if-c-only +m4_ifdef( [[M4_YY_NOT_REENTRANT]], +[[ + M4_GEN_PREFIX(`text') + M4_GEN_PREFIX(`leng') + M4_GEN_PREFIX(`in') + M4_GEN_PREFIX(`out') + M4_GEN_PREFIX(`_flex_debug') + M4_GEN_PREFIX(`lineno') +]]) +%endif + + +m4_ifdef( [[M4_YY_TABLES_EXTERNAL]], +[[ + M4_GEN_PREFIX(`tables_fload') + M4_GEN_PREFIX(`tables_destroy') + M4_GEN_PREFIX(`TABLES_NAME') +]]) + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +%if-c-only +#include +#include +#include +#include +%endif + +%if-tables-serialization +#include +#include +%endif +/* end standard C headers. */ + +%if-c-or-c++ +m4preproc_include(`flexint.h') +%endif + +%if-c++-only +/* begin standard C++ headers. */ +#include +#include +#include +#include +#include +/* end standard C++ headers. */ +%endif + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +%# For compilers that can not handle prototypes. +%# e.g., +%# The function prototype +%# int foo(int x, char* y); +%# +%# ...should be written as +%# int foo M4_YY_PARAMS(int x, char* y); +%# +%# ...which could possibly generate +%# int foo (); +%# +m4_ifdef( [[M4_YY_NO_ANSI_FUNC_PROTOS]], +[[ + m4_define( [[M4_YY_PARAMS]], [[()]]) +]], +[[ + m4_define( [[M4_YY_PARAMS]], [[($*)]]) +]]) + +%not-for-header +/* Returned upon end-of-file. */ +#define YY_NULL 0 +%ok-for-header + +%not-for-header +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) +%ok-for-header + + + +%if-reentrant + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +%# Declare yyguts variable +m4_define( [[M4_YY_DECL_GUTS_VAR]], [[struct yyguts_t * yyg = (struct yyguts_t*)yyscanner]]) +%# Perform a noop access on yyguts to prevent unused variable complains +m4_define( [[M4_YY_NOOP_GUTS_VAR]], [[(void)yyg]]) +%# For use wherever a Global is accessed or assigned. +m4_define( [[YY_G]], [[yyg->$1]]) + +%# For use in function prototypes to append the additional argument. +m4_define( [[M4_YY_PROTO_LAST_ARG]], [[, yyscan_t yyscanner]]) +m4_define( [[M4_YY_PROTO_ONLY_ARG]], [[yyscan_t yyscanner]]) + +%# For use in function definitions to append the additional argument. +m4_ifdef( [[M4_YY_NO_ANSI_FUNC_DEFS]], +[[ + m4_define( [[M4_YY_DEF_LAST_ARG]], [[, yyscanner]]) + m4_define( [[M4_YY_DEF_ONLY_ARG]], [[yyscanner]]) +]], +[[ + m4_define( [[M4_YY_DEF_LAST_ARG]], [[, yyscan_t yyscanner]]) + m4_define( [[M4_YY_DEF_ONLY_ARG]], [[yyscan_t yyscanner]]) +]]) +m4_define( [[M4_YY_DECL_LAST_ARG]], [[yyscan_t yyscanner;]]) + +%# For use in function calls to pass the additional argument. +m4_define( [[M4_YY_CALL_LAST_ARG]], [[, yyscanner]]) +m4_define( [[M4_YY_CALL_ONLY_ARG]], [[yyscanner]]) + +%# For use in function documentation to adjust for additional argument. +m4_define( [[M4_YY_DOC_PARAM]], [[@param yyscanner The scanner object.]]) + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin YY_G(yyin_r) +#define yyout YY_G(yyout_r) +#define yyextra YY_G(yyextra_r) +#define yyleng YY_G(yyleng_r) +#define yytext YY_G(yytext_r) +#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) +#define yy_flex_debug YY_G(yy_flex_debug_r) + +m4_define( [[M4_YY_INCR_LINENO]], +[[ + do{ yylineno++; + yycolumn=0; + }while(0) +]]) + +%endif + + + +%if-not-reentrant + +m4_define( [[M4_YY_INCR_LINENO]], +[[ + yylineno++; +]]) + +%# Define these macros to be no-ops. +m4_define( [[M4_YY_DECL_GUTS_VAR]], [[m4_dnl]]) +m4_define( [[M4_YY_NOOP_GUTS_VAR]], [[m4_dnl]]) +m4_define( [[YY_G]], [[($1)]]) +m4_define( [[M4_YY_PROTO_LAST_ARG]]) +m4_define( [[M4_YY_PROTO_ONLY_ARG]], [[void]]) +m4_define( [[M4_YY_DEF_LAST_ARG]]) + +m4_ifdef( [[M4_YY_NO_ANSI_FUNC_DEFS]], +[[ + m4_define( [[M4_YY_DEF_ONLY_ARG]]) +]], +[[ + m4_define( [[M4_YY_DEF_ONLY_ARG]], [[void]]) +]]) +m4_define([[M4_YY_DECL_LAST_ARG]]) +m4_define([[M4_YY_CALL_LAST_ARG]]) +m4_define([[M4_YY_CALL_ONLY_ARG]]) +m4_define( [[M4_YY_DOC_PARAM]], [[]]) + +%endif + + +m4_ifdef( [[M4_YY_NO_ANSI_FUNC_DEFS]], +[[ +%# For compilers that need traditional function definitions. +%# e.g., +%# The function prototype taking 2 arguments +%# int foo (int x, char* y) +%# +%# ...should be written as +%# int foo YYFARGS2(int,x, char*,y) +%# +%# ...which could possibly generate +%# int foo (x,y,yyscanner) +%# int x; +%# char * y; +%# yyscan_t yyscanner; +%# +%# Generate traditional function defs + m4_define( [[YYFARGS0]], [[(M4_YY_DEF_ONLY_ARG) [[\]] + M4_YY_DECL_LAST_ARG]]) + m4_define( [[YYFARGS1]], [[($2 M4_YY_DEF_LAST_ARG) [[\]] + $1 $2; [[\]] + M4_YY_DECL_LAST_ARG]]) + m4_define( [[YYFARGS2]], [[($2,$4 M4_YY_DEF_LAST_ARG) [[\]] + $1 $2; [[\]] + $3 $4; [[\]] + M4_YY_DECL_LAST_ARG]]) + m4_define( [[YYFARGS3]], [[($2,$4,$6 M4_YY_DEF_LAST_ARG) [[\]] + $1 $2; [[\]] + $3 $4; [[\]] + $5 $6; [[\]] + M4_YY_DECL_LAST_ARG]]) +]], +[[ +%# Generate C99 function defs. + m4_define( [[YYFARGS0]], [[(M4_YY_DEF_ONLY_ARG)]]) + m4_define( [[YYFARGS1]], [[($1 $2 M4_YY_DEF_LAST_ARG)]]) + m4_define( [[YYFARGS2]], [[($1 $2, $3 $4 M4_YY_DEF_LAST_ARG)]]) + m4_define( [[YYFARGS3]], [[($1 $2, $3 $4, $5 $6 M4_YY_DEF_LAST_ARG)]]) +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN YY_G(yy_start) = 1 + 2 * +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((YY_G(yy_start) - 1) / 2) +#define YYSTATE YY_START +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin M4_YY_CALL_LAST_ARG ) +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +#define YY_END_OF_BUFFER_CHAR 0 +]]) + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) +]]) + + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +%if-not-reentrant +extern yy_size_t yyleng; +%endif + +%if-c-only +%if-not-reentrant +extern FILE *yyin, *yyout; +%endif +%endif + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ + m4_ifdef( [[M4_YY_USE_LINENO]], + [[ + /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires + * access to the local variable yy_act. Since yyless() is a macro, it would break + * existing scanners that call yyless() from OUTSIDE yylex. + * One obvious solution it to make yy_act a global. I tried that, and saw + * a 5% performance hit in a non-yylineno scanner, because yy_act is + * normally declared as a register variable-- so it is not worth it. + */ + #define YY_LESS_LINENO(n) \ + do { \ + int yyl;\ + for ( yyl = n; yyl < yyleng; ++yyl )\ + if ( yytext[yyl] == '\n' )\ + --yylineno;\ + }while(0) + #define YY_LINENO_REWIND_TO(dst) \ + do {\ + const char *p;\ + for ( p = yy_cp-1; p >= (dst); --p)\ + if ( *p == '\n' )\ + --yylineno;\ + }while(0) + ]], + [[ + #define YY_LESS_LINENO(n) + #define YY_LINENO_REWIND_TO(ptr) + ]]) +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = YY_G(yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + YY_G(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +#define unput(c) yyunput( c, YY_G(yytext_ptr) M4_YY_CALL_LAST_ARG ) +]]) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { +%if-c-only + FILE *yy_input_file; +%endif + +%if-c++-only + std::istream* yy_input_file; +%endif + + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 +]]) + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +%if-c-only Standard (non-C++) definition +%not-for-header +%if-not-reentrant + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ +%endif +%ok-for-header +%endif + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( YY_G(yy_buffer_stack) \ + ? YY_G(yy_buffer_stack)[YY_G(yy_buffer_stack_top)] \ + : NULL) +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE YY_G(yy_buffer_stack)[YY_G(yy_buffer_stack_top)] +]]) + +%if-c-only Standard (non-C++) definition + +%if-not-reentrant +%not-for-header +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; +%ok-for-header +%endif + +void yyrestart M4_YY_PARAMS( FILE *input_file M4_YY_PROTO_LAST_ARG ); +void yy_switch_to_buffer M4_YY_PARAMS( YY_BUFFER_STATE new_buffer M4_YY_PROTO_LAST_ARG ); +YY_BUFFER_STATE yy_create_buffer M4_YY_PARAMS( FILE *file, int size M4_YY_PROTO_LAST_ARG ); +void yy_delete_buffer M4_YY_PARAMS( YY_BUFFER_STATE b M4_YY_PROTO_LAST_ARG ); +void yy_flush_buffer M4_YY_PARAMS( YY_BUFFER_STATE b M4_YY_PROTO_LAST_ARG ); +void yypush_buffer_state M4_YY_PARAMS( YY_BUFFER_STATE new_buffer M4_YY_PROTO_LAST_ARG ); +void yypop_buffer_state M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +static void yyensure_buffer_stack M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +static void yy_load_buffer_state M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +static void yy_init_buffer M4_YY_PARAMS( YY_BUFFER_STATE b, FILE *file M4_YY_PROTO_LAST_ARG ); +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER M4_YY_CALL_LAST_ARG) +]]) + +YY_BUFFER_STATE yy_scan_buffer M4_YY_PARAMS( char *base, yy_size_t size M4_YY_PROTO_LAST_ARG ); +YY_BUFFER_STATE yy_scan_string M4_YY_PARAMS( yyconst char *yy_str M4_YY_PROTO_LAST_ARG ); +YY_BUFFER_STATE yy_scan_bytes M4_YY_PARAMS( yyconst char *bytes, yy_size_t len M4_YY_PROTO_LAST_ARG ); + +%endif + +void *yyalloc M4_YY_PARAMS( yy_size_t M4_YY_PROTO_LAST_ARG ); +void *yyrealloc M4_YY_PARAMS( void *, yy_size_t M4_YY_PROTO_LAST_ARG ); +void yyfree M4_YY_PARAMS( void * M4_YY_PROTO_LAST_ARG ); + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +#define yy_new_buffer yy_create_buffer +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (M4_YY_CALL_ONLY_ARG); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE M4_YY_CALL_LAST_ARG); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (M4_YY_CALL_ONLY_ARG); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE M4_YY_CALL_LAST_ARG); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) +]]) + +%% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +%% [1.5] DFA +]]) + +%if-c-only Standard (non-C++) definition + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +static yy_state_type yy_get_previous_state M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +static yy_state_type yy_try_NUL_trans M4_YY_PARAMS( yy_state_type current_state M4_YY_PROTO_LAST_ARG); +static int yy_get_next_buffer M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +static void yy_fatal_error M4_YY_PARAMS( yyconst char msg[] M4_YY_PROTO_LAST_ARG ); +]]) + +%endif + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + YY_G(yytext_ptr) = yy_bp; \ +%% [2.0] code to fiddle yytext and yyleng for yymore() goes here \ + YY_G(yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ +%% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ + YY_G(yy_c_buf_p) = yy_cp; +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +%% [4.0] data tables for the DFA and the user's section 1 definitions go here +]]) + +m4_ifdef( [[M4_YY_IN_HEADER]], [[#ifdef YY_HEADER_EXPORT_START_CONDITIONS]]) +M4_YY_SC_DEFS +m4_ifdef( [[M4_YY_IN_HEADER]], [[#endif]]) + +m4_ifdef( [[M4_YY_NO_UNISTD_H]],, +[[ +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +%if-c-only +#include +%endif +%if-c++-only +#include +%endif +#endif +]]) + +m4_ifdef( [[M4_EXTRA_TYPE_DEFS]], +[[ +#define YY_EXTRA_TYPE M4_EXTRA_TYPE_DEFS +]], +[[ +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif +]] +) + +%if-c-only Reentrant structure and macros (non-C++). +%if-reentrant + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* Holds the entire state of the reentrant scanner. */ +struct yyguts_t + { + + /* User-defined. Not touched by flex. */ + YY_EXTRA_TYPE yyextra_r; + + /* The rest are the same as the globals declared in the non-reentrant scanner. */ + FILE *yyin_r, *yyout_r; + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ + char yy_hold_char; + yy_size_t yy_n_chars; + yy_size_t yyleng_r; + char *yy_c_buf_p; + int yy_init; + int yy_start; + int yy_did_buffer_switch_on_eof; + int yy_start_stack_ptr; + int yy_start_stack_depth; + int *yy_start_stack; + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + int yylineno_r; + int yy_flex_debug_r; + +m4_ifdef( [[M4_YY_USES_REJECT]], +[[ + yy_state_type *yy_state_buf; + yy_state_type *yy_state_ptr; + char *yy_full_match; + int yy_lp; + + /* These are only needed for trailing context rules, + * but there's no conditional variable for that yet. */ + int yy_looking_for_trail_begin; + int yy_full_lp; + int *yy_full_state; +]]) + +m4_ifdef( [[M4_YY_TEXT_IS_ARRAY]], +[[ + char yytext_r[YYLMAX]; + char *yytext_ptr; + int yy_more_offset; + int yy_prev_more_offset; +]], +[[ + char *yytext_r; + int yy_more_flag; + int yy_more_len; +]]) + +m4_ifdef( [[M4_YY_BISON_LVAL]], +[[ + YYSTYPE * yylval_r; +]]) + +m4_ifdef( [[]], +[[ + YYLTYPE * yylloc_r; +]]) + + }; /* end struct yyguts_t */ +]]) + + +%if-c-only +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +static int yy_init_globals M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +]]) +%endif + +%if-reentrant + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ + m4_ifdef( [[M4_YY_BISON_LVAL]], + [[ + /* This must go here because YYSTYPE and YYLTYPE are included + * from bison output in section 1.*/ + # define yylval YY_G(yylval_r) + ]]) + + m4_ifdef( [[]], + [[ + # define yylloc YY_G(yylloc_r) + ]]) +]]) + +int yylex_init M4_YY_PARAMS(yyscan_t* scanner); + +int yylex_init_extra M4_YY_PARAMS( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); + +%endif + +%endif End reentrant structures and macros. + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +m4_ifdef( [[M4_YY_NO_DESTROY]],, +[[ +int yylex_destroy M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +]]) + +m4_ifdef( [[M4_YY_NO_GET_DEBUG]],, +[[ +int yyget_debug M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +]]) + +m4_ifdef( [[M4_YY_NO_SET_DEBUG]],, +[[ +void yyset_debug M4_YY_PARAMS( int debug_flag M4_YY_PROTO_LAST_ARG ); +]]) + +m4_ifdef( [[M4_YY_NO_GET_EXTRA]],, +[[ +YY_EXTRA_TYPE yyget_extra M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +]]) + +m4_ifdef( [[M4_YY_NO_SET_EXTRA]],, +[[ +void yyset_extra M4_YY_PARAMS( YY_EXTRA_TYPE user_defined M4_YY_PROTO_LAST_ARG ); +]]) + +m4_ifdef( [[M4_YY_NO_GET_IN]],, +[[ +FILE *yyget_in M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +]]) + +m4_ifdef( [[M4_YY_NO_SET_IN]],, +[[ +void yyset_in M4_YY_PARAMS( FILE * in_str M4_YY_PROTO_LAST_ARG ); +]]) + +m4_ifdef( [[M4_YY_NO_GET_OUT]],, +[[ +FILE *yyget_out M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +]]) + +m4_ifdef( [[M4_YY_NO_SET_OUT]],, +[[ +void yyset_out M4_YY_PARAMS( FILE * out_str M4_YY_PROTO_LAST_ARG ); +]]) + +m4_ifdef( [[M4_YY_NO_GET_LENG]],, +[[ +yy_size_t yyget_leng M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +]]) + +m4_ifdef( [[M4_YY_NO_GET_TEXT]],, +[[ +char *yyget_text M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +]]) + +m4_ifdef( [[M4_YY_NO_GET_LINENO]],, +[[ +int yyget_lineno M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +]]) + +m4_ifdef( [[M4_YY_NO_SET_LINENO]],, +[[ +void yyset_lineno M4_YY_PARAMS( int line_number M4_YY_PROTO_LAST_ARG ); +]]) + +m4_ifdef( [[M4_YY_REENTRANT]], +[[ +m4_ifdef( [[M4_YY_NO_GET_COLUMN]],, +[[ +int yyget_column M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +]]) +]]) + +m4_ifdef( [[M4_YY_REENTRANT]], +[[ +m4_ifdef( [[M4_YY_NO_SET_COLUMN]],, +[[ +void yyset_column M4_YY_PARAMS( int column_no M4_YY_PROTO_LAST_ARG ); +]]) +]]) + +%if-bison-bridge +m4_ifdef( [[M4_YY_NO_GET_LVAL]],, +[[ +YYSTYPE * yyget_lval M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +]]) + +void yyset_lval M4_YY_PARAMS( YYSTYPE * yylval_param M4_YY_PROTO_LAST_ARG ); + +m4_ifdef( [[]], +[[ + m4_ifdef( [[M4_YY_NO_GET_LLOC]],, + [[ + YYLTYPE *yyget_lloc M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); + ]]) + + m4_ifdef( [[M4_YY_NO_SET_LLOC]],, + [[ + void yyset_lloc M4_YY_PARAMS( YYLTYPE * yylloc_param M4_YY_PROTO_LAST_ARG ); + ]]) +]]) +%endif + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +#else +extern int yywrap M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +#endif +#endif + +%not-for-header + m4_ifdef( [[M4_YY_NO_UNPUT]],, + [[ + static void yyunput M4_YY_PARAMS( int c, char *buf_ptr M4_YY_PROTO_LAST_ARG); + ]]) +%ok-for-header +%endif + +#ifndef yytext_ptr +static void yy_flex_strncpy M4_YY_PARAMS( char *, yyconst char *, int M4_YY_PROTO_LAST_ARG); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen M4_YY_PARAMS( yyconst char * M4_YY_PROTO_LAST_ARG); +#endif + +#ifndef YY_NO_INPUT +%if-c-only Standard (non-C++) definition +%not-for-header +#ifdef __cplusplus +static int yyinput M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +#else +static int input M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); +#endif +%ok-for-header +%endif +#endif + + +%if-c-only +%# TODO: This is messy. +m4_ifdef( [[M4_YY_STACK_USED]], +[[ + +m4_ifdef( [[M4_YY_NOT_REENTRANT]], +[[ + m4_ifdef( [[M4_YY_NOT_IN_HEADER]], + [[ + static int yy_start_stack_ptr = 0; + static int yy_start_stack_depth = 0; + static int *yy_start_stack = NULL; + ]]) +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ + m4_ifdef( [[M4_YY_NO_PUSH_STATE]],, + [[ + static void yy_push_state M4_YY_PARAMS( int new_state M4_YY_PROTO_LAST_ARG); + ]]) + m4_ifdef( [[M4_YY_NO_POP_STATE]],, + [[ + static void yy_pop_state M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); + ]]) + m4_ifdef( [[M4_YY_NO_TOP_STATE]],, + [[ + static int yy_top_state M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG ); + ]]) +]]) + +]], +[[ +m4_define( [[M4_YY_NO_PUSH_STATE]]) +m4_define( [[M4_YY_NO_POP_STATE]]) +m4_define( [[M4_YY_NO_TOP_STATE]]) +]]) +%endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +%if-c-only Standard (non-C++) definition +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) +%endif +%if-c++-only C++ definition +#define ECHO LexerOutput( yytext, yyleng ) +%endif +#endif +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ +%% [5.0] fread()/read() definition of YY_INPUT goes here unless we're doing C++ \ +\ +%if-c++-only C++ definition \ + if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +%endif + +#endif +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif +]]) + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +%if-c-only +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg M4_YY_CALL_LAST_ARG) +%endif +%if-c++-only +#define YY_FATAL_ERROR(msg) LexerError( msg ) +%endif +#endif +]]) + +%if-tables-serialization structures and prototypes +m4preproc_include(`tables_shared.h') + +/* Load the DFA tables from the given stream. */ +int yytables_fload M4_YY_PARAMS(FILE * fp M4_YY_PROTO_LAST_ARG); + +/* Unload the tables from memory. */ +int yytables_destroy M4_YY_PARAMS(M4_YY_PROTO_ONLY_ARG); +%not-for-header + +/** Describes a mapping from a serialized table id to its deserialized state in + * this scanner. This is the bridge between our "generic" deserialization code + * and the specifics of this scanner. + */ +struct yytbl_dmap { + enum yytbl_id dm_id;/**< table identifier */ + void **dm_arr; /**< address of pointer to store the deserialized table. */ + size_t dm_sz; /**< local sizeof() each element in table. */ +}; + +/** A {0,0,0}-terminated list of structs, forming the map */ +static struct yytbl_dmap yydmap[] = +{ +%tables-yydmap generated elements + {0,0,0} +}; + +/** A tables-reader object to maintain some state in the read. */ +struct yytbl_reader { + FILE * fp; /**< input stream */ + flex_uint32_t bread; /**< bytes read since beginning of current tableset */ +}; + +%endif +/* end tables serialization structures and prototypes */ + +%ok-for-header + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 +%if-c-only Standard (non-C++) definition + + +m4_define( [[M4_YY_LEX_PROTO]], [[M4_YY_PARAMS(M4_YY_PROTO_ONLY_ARG)]]) +m4_define( [[M4_YY_LEX_DECLARATION]], [[YYFARGS0(void)]]) + +m4_ifdef( [[M4_YY_BISON_LVAL]], +[[ + m4_dnl The bison pure parser is used. Redefine yylex to + m4_dnl accept the lval parameter. + + m4_define( [[M4_YY_LEX_PROTO]], [[\]] + [[M4_YY_PARAMS(YYSTYPE * yylval_param M4_YY_PROTO_LAST_ARG)]]) + m4_define( [[M4_YY_LEX_DECLARATION]], [[\]] + [[YYFARGS1(YYSTYPE *,yylval_param)]]) +]]) + +m4_ifdef( [[]], +[[ + m4_dnl Locations are used. yylex should also accept the ylloc parameter. + + m4_define( [[M4_YY_LEX_PROTO]], [[\]] + [[M4_YY_PARAMS(YYSTYPE * yylval_param, YYLTYPE * yylloc_param M4_YY_PROTO_LAST_ARG)]]) + m4_define( [[M4_YY_LEX_DECLARATION]], [[\]] + [[YYFARGS2(YYSTYPE *,yylval_param, YYLTYPE *,yylloc_param)]]) +]]) + +extern int yylex M4_YY_LEX_PROTO; + +#define YY_DECL int yylex M4_YY_LEX_DECLARATION +%endif +%if-c++-only C++ definition +#define YY_DECL int yyFlexLexer::yylex() +%endif +#endif /* !YY_DECL */ + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +%% [6.0] YY_RULE_SETUP definition goes here +]]) + +%not-for-header +/** The main scanner function which does all the work. + */ +YY_DECL +{ + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + M4_YY_DECL_GUTS_VAR(); + +m4_ifdef( [[M4_YY_NOT_REENTRANT]], +[[ + m4_ifdef( [[M4_YY_BISON_LVAL]], + [[ + YYSTYPE * yylval; + ]]) + m4_ifdef( [[]], + [[ + YYLTYPE * yylloc; + ]]) +]]) + +m4_ifdef( [[M4_YY_BISON_LVAL]], +[[ + yylval = yylval_param; +]]) + +m4_ifdef( [[]], +[[ + yylloc = yylloc_param; +]]) + + if ( !YY_G(yy_init) ) + { + YY_G(yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + +m4_ifdef( [[M4_YY_USES_REJECT]], +[[ + /* Create the reject buffer large enough to save one state per allowed character. */ + if ( ! YY_G(yy_state_buf) ) + YY_G(yy_state_buf) = (yy_state_type *)yyalloc(YY_STATE_BUF_SIZE M4_YY_CALL_LAST_ARG); + if ( ! YY_G(yy_state_buf) ) + YY_FATAL_ERROR( "out of dynamic memory in yylex()" ); +]]) + + if ( ! YY_G(yy_start) ) + YY_G(yy_start) = 1; /* first start state */ + + if ( ! yyin ) +%if-c-only + yyin = stdin; +%endif +%if-c++-only + yyin = & std::cin; +%endif + + if ( ! yyout ) +%if-c-only + yyout = stdout; +%endif +%if-c++-only + yyout = & std::cout; +%endif + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (M4_YY_CALL_ONLY_ARG); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE M4_YY_CALL_LAST_ARG); + } + + yy_load_buffer_state( M4_YY_CALL_ONLY_ARG ); + } + + { +%% [7.0] user's declarations go here + + while ( 1 ) /* loops until end-of-file is reached */ + { +%% [8.0] yymore()-related code goes here + yy_cp = YY_G(yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = YY_G(yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + +%% [9.0] code to set up and find next match goes here + +yy_find_action: +%% [10.0] code to find the action number goes here + + YY_DO_BEFORE_ACTION; + +%% [11.0] code for yylineno update goes here + +do_action: /* This label is used only to access EOF actions. */ + +%% [12.0] debug code goes here + + switch ( yy_act ) + { /* beginning of action switch */ +%% [13.0] actions go here + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - YY_G(yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = YY_G(yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + YY_G(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( YY_G(yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + YY_G(yy_c_buf_p) = YY_G(yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( M4_YY_CALL_ONLY_ARG ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state M4_YY_CALL_LAST_ARG); + + yy_bp = YY_G(yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++YY_G(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { +%% [14.0] code to do back-up for compressed tables and set up yy_cp goes here + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( M4_YY_CALL_ONLY_ARG ) ) + { + case EOB_ACT_END_OF_FILE: + { + YY_G(yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( M4_YY_CALL_ONLY_ARG ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + YY_G(yy_c_buf_p) = YY_G(yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! YY_G(yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + YY_G(yy_c_buf_p) = + YY_G(yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( M4_YY_CALL_ONLY_ARG ); + + yy_cp = YY_G(yy_c_buf_p); + yy_bp = YY_G(yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + YY_G(yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( M4_YY_CALL_ONLY_ARG ); + + yy_cp = YY_G(yy_c_buf_p); + yy_bp = YY_G(yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ +%ok-for-header + +%if-c++-only +%not-for-header +/* The contents of this function are C++ specific, so the YY_G macro is not used. + */ +yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) +{ + yyin = arg_yyin; + yyout = arg_yyout; + yy_c_buf_p = 0; + yy_init = 0; + yy_start = 0; + yy_flex_debug = 0; + yylineno = 1; // this will only get updated if %option yylineno + + yy_did_buffer_switch_on_eof = 0; + + yy_looking_for_trail_begin = 0; + yy_more_flag = 0; + yy_more_len = 0; + yy_more_offset = yy_prev_more_offset = 0; + + yy_start_stack_ptr = yy_start_stack_depth = 0; + yy_start_stack = NULL; + + yy_buffer_stack = 0; + yy_buffer_stack_top = 0; + yy_buffer_stack_max = 0; + + +m4_ifdef( [[M4_YY_USES_REJECT]], +[[ + yy_state_buf = new yy_state_type[YY_STATE_BUF_SIZE]; +]], +[[ + yy_state_buf = 0; +]]) +} + +/* The contents of this function are C++ specific, so the YY_G macro is not used. + */ +yyFlexLexer::~yyFlexLexer() +{ + delete [] yy_state_buf; + yyfree( yy_start_stack M4_YY_CALL_LAST_ARG ); + yy_delete_buffer( YY_CURRENT_BUFFER M4_YY_CALL_LAST_ARG); + yyfree( yy_buffer_stack M4_YY_CALL_LAST_ARG ); +} + +/* The contents of this function are C++ specific, so the YY_G macro is not used. + */ +void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) +{ + if ( new_in ) + { + yy_delete_buffer( YY_CURRENT_BUFFER M4_YY_CALL_LAST_ARG); + yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE M4_YY_CALL_LAST_ARG) M4_YY_CALL_LAST_ARG); + } + + if ( new_out ) + yyout = new_out; +} + +#ifdef YY_INTERACTIVE +int yyFlexLexer::LexerInput( char* buf, int /* max_size */ ) +#else +int yyFlexLexer::LexerInput( char* buf, int max_size ) +#endif +{ + if ( yyin->eof() || yyin->fail() ) + return 0; + +#ifdef YY_INTERACTIVE + yyin->get( buf[0] ); + + if ( yyin->eof() ) + return 0; + + if ( yyin->bad() ) + return -1; + + return 1; + +#else + (void) yyin->read( buf, max_size ); + + if ( yyin->bad() ) + return -1; + else + return yyin->gcount(); +#endif +} + +void yyFlexLexer::LexerOutput( const char* buf, int size ) +{ + (void) yyout->write( buf, size ); +} +%ok-for-header +%endif + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +%if-c-only +static int yy_get_next_buffer YYFARGS0(void) +%endif +%if-c++-only +int yyFlexLexer::yy_get_next_buffer() +%endif +{ + M4_YY_DECL_GUTS_VAR(); + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = YY_G(yytext_ptr); + int number_to_move, i; + int ret_val; + + if ( YY_G(yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( YY_G(yy_c_buf_p) - YY_G(yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (YY_G(yy_c_buf_p) - YY_G(yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = YY_G(yy_n_chars) = 0; + + else + { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +m4_ifdef( [[M4_YY_USES_REJECT]], +[[ + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +]], +[[ + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) (YY_G(yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + yy_size_t new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 M4_YY_CALL_LAST_ARG ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + YY_G(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; +]]) + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + YY_G(yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = YY_G(yy_n_chars); + } + + if ( YY_G(yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin M4_YY_CALL_LAST_ARG); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) (YY_G(yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = YY_G(yy_n_chars) + number_to_move + (YY_G(yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, new_size M4_YY_CALL_LAST_ARG ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); + } + + YY_G(yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + YY_G(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} +]]) + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +%if-c-only +%not-for-header + static yy_state_type yy_get_previous_state YYFARGS0(void) +%endif +%if-c++-only + yy_state_type yyFlexLexer::yy_get_previous_state() +%endif +{ + yy_state_type yy_current_state; + char *yy_cp; + M4_YY_DECL_GUTS_VAR(); + +%% [15.0] code to get the start state into yy_current_state goes here + + for ( yy_cp = YY_G(yytext_ptr) + YY_MORE_ADJ; yy_cp < YY_G(yy_c_buf_p); ++yy_cp ) + { +%% [16.0] code to find the next state goes here + } + + return yy_current_state; +} + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ +%if-c-only + static yy_state_type yy_try_NUL_trans YYFARGS1( yy_state_type, yy_current_state) +%endif +%if-c++-only + yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) +%endif +{ + int yy_is_jam; + M4_YY_DECL_GUTS_VAR(); /* This var may be unused depending upon options. */ +%% [17.0] code to find the next state, and perhaps do backing up, goes here + + M4_YY_NOOP_GUTS_VAR(); + return yy_is_jam ? 0 : yy_current_state; +} + + +%if-c-only +m4_ifdef( [[M4_YY_NO_UNPUT]],, +[[ + static void yyunput YYFARGS2( int,c, char *,yy_bp) +%endif +%if-c++-only + void yyFlexLexer::yyunput( int c, char* yy_bp) +%endif +{ + char *yy_cp; + M4_YY_DECL_GUTS_VAR(); + + yy_cp = YY_G(yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = YY_G(yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + yy_size_t number_to_move = YY_G(yy_n_chars) + 2; + char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + YY_G(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + +%% [18.0] update yylineno here +m4_ifdef( [[M4_YY_USE_LINENO]], +[[ + if ( c == '\n' ){ + --yylineno; + } +]]) + + YY_G(yytext_ptr) = yy_bp; + YY_G(yy_hold_char) = *yy_cp; + YY_G(yy_c_buf_p) = yy_cp; +} +%if-c-only +]]) +%endif + +%if-c-only +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput YYFARGS0(void) +#else + static int input YYFARGS0(void) +#endif + +%endif +%if-c++-only + int yyFlexLexer::yyinput() +%endif +{ + int c; + M4_YY_DECL_GUTS_VAR(); + + *YY_G(yy_c_buf_p) = YY_G(yy_hold_char); + + if ( *YY_G(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( YY_G(yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars)] ) + /* This was really a NUL. */ + *YY_G(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + yy_size_t offset = YY_G(yy_c_buf_p) - YY_G(yytext_ptr); + ++YY_G(yy_c_buf_p); + + switch ( yy_get_next_buffer( M4_YY_CALL_ONLY_ARG ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin M4_YY_CALL_LAST_ARG); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( M4_YY_CALL_ONLY_ARG ) ) + return EOF; + + if ( ! YY_G(yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(M4_YY_CALL_ONLY_ARG); +#else + return input(M4_YY_CALL_ONLY_ARG); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + YY_G(yy_c_buf_p) = YY_G(yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) YY_G(yy_c_buf_p); /* cast for 8-bit char's */ + *YY_G(yy_c_buf_p) = '\0'; /* preserve yytext */ + YY_G(yy_hold_char) = *++YY_G(yy_c_buf_p); + +%% [19.0] update BOL and yylineno + + return c; +} +%if-c-only +#endif /* ifndef YY_NO_INPUT */ +%endif + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * M4_YY_DOC_PARAM + * @note This function does not reset the start condition to @c INITIAL . + */ +%if-c-only + void yyrestart YYFARGS1( FILE *,input_file) +%endif +%if-c++-only + void yyFlexLexer::yyrestart( std::istream* input_file ) +%endif +{ + M4_YY_DECL_GUTS_VAR(); + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (M4_YY_CALL_ONLY_ARG); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE M4_YY_CALL_LAST_ARG); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file M4_YY_CALL_LAST_ARG); + yy_load_buffer_state( M4_YY_CALL_ONLY_ARG ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * M4_YY_DOC_PARAM + */ +%if-c-only + void yy_switch_to_buffer YYFARGS1( YY_BUFFER_STATE ,new_buffer) +%endif +%if-c++-only + void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +%endif +{ + M4_YY_DECL_GUTS_VAR(); + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (M4_YY_CALL_ONLY_ARG); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *YY_G(yy_c_buf_p) = YY_G(yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = YY_G(yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = YY_G(yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( M4_YY_CALL_ONLY_ARG ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + YY_G(yy_did_buffer_switch_on_eof) = 1; +} + + +%if-c-only +static void yy_load_buffer_state YYFARGS0(void) +%endif +%if-c++-only + void yyFlexLexer::yy_load_buffer_state() +%endif +{ + M4_YY_DECL_GUTS_VAR(); + YY_G(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_G(yytext_ptr) = YY_G(yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + YY_G(yy_hold_char) = *YY_G(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * M4_YY_DOC_PARAM + * @return the allocated buffer state. + */ +%if-c-only + YY_BUFFER_STATE yy_create_buffer YYFARGS2( FILE *,file, int ,size) +%endif +%if-c++-only + YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) +%endif +{ + YY_BUFFER_STATE b; + m4_dnl M4_YY_DECL_GUTS_VAR(); + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) M4_YY_CALL_LAST_ARG ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc( b->yy_buf_size + 2 M4_YY_CALL_LAST_ARG ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file M4_YY_CALL_LAST_ARG); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * M4_YY_DOC_PARAM + */ +%if-c-only + void yy_delete_buffer YYFARGS1( YY_BUFFER_STATE ,b) +%endif +%if-c++-only + void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) +%endif +{ + M4_YY_DECL_GUTS_VAR(); + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree( (void *) b->yy_ch_buf M4_YY_CALL_LAST_ARG ); + + yyfree( (void *) b M4_YY_CALL_LAST_ARG ); +} + + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ +%if-c-only + static void yy_init_buffer YYFARGS2( YY_BUFFER_STATE ,b, FILE *,file) +%endif +%if-c++-only + void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) +%endif + +{ + int oerrno = errno; + M4_YY_DECL_GUTS_VAR(); + + yy_flush_buffer( b M4_YY_CALL_LAST_ARG); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + +%if-c-only +m4_ifdef( [[M4_YY_ALWAYS_INTERACTIVE]], +[[ + b->yy_is_interactive = 1; +]], +[[ + m4_ifdef( [[M4_YY_NEVER_INTERACTIVE]], + [[ + b->yy_is_interactive = 0; + ]], + [[ + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + ]]) +]]) +%endif +%if-c++-only + b->yy_is_interactive = 0; +%endif + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * M4_YY_DOC_PARAM + */ +%if-c-only + void yy_flush_buffer YYFARGS1( YY_BUFFER_STATE ,b) +%endif +%if-c++-only + void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) +%endif +{ + M4_YY_DECL_GUTS_VAR(); + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( M4_YY_CALL_ONLY_ARG ); +} + +%if-c-or-c++ +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * M4_YY_DOC_PARAM + */ +%if-c-only +void yypush_buffer_state YYFARGS1(YY_BUFFER_STATE,new_buffer) +%endif +%if-c++-only +void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) +%endif +{ + M4_YY_DECL_GUTS_VAR(); + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(M4_YY_CALL_ONLY_ARG); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *YY_G(yy_c_buf_p) = YY_G(yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = YY_G(yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = YY_G(yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + YY_G(yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( M4_YY_CALL_ONLY_ARG ); + YY_G(yy_did_buffer_switch_on_eof) = 1; +} +%endif + + +%if-c-or-c++ +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * M4_YY_DOC_PARAM + */ +%if-c-only +void yypop_buffer_state YYFARGS0(void) +%endif +%if-c++-only +void yyFlexLexer::yypop_buffer_state (void) +%endif +{ + M4_YY_DECL_GUTS_VAR(); + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER M4_YY_CALL_LAST_ARG); + YY_CURRENT_BUFFER_LVALUE = NULL; + if (YY_G(yy_buffer_stack_top) > 0) + --YY_G(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( M4_YY_CALL_ONLY_ARG ); + YY_G(yy_did_buffer_switch_on_eof) = 1; + } +} +%endif + + +%if-c-or-c++ +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +%if-c-only +static void yyensure_buffer_stack YYFARGS0(void) +%endif +%if-c++-only +void yyFlexLexer::yyensure_buffer_stack(void) +%endif +{ + yy_size_t num_to_alloc; + M4_YY_DECL_GUTS_VAR(); + + if (!YY_G(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + YY_G(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + M4_YY_CALL_LAST_ARG); + if ( ! YY_G(yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + + memset(YY_G(yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + YY_G(yy_buffer_stack_max) = num_to_alloc; + YY_G(yy_buffer_stack_top) = 0; + return; + } + + if (YY_G(yy_buffer_stack_top) >= (YY_G(yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = YY_G(yy_buffer_stack_max) + grow_size; + YY_G(yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + (YY_G(yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + M4_YY_CALL_LAST_ARG); + if ( ! YY_G(yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset(YY_G(yy_buffer_stack) + YY_G(yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + YY_G(yy_buffer_stack_max) = num_to_alloc; + } +} +%endif + + + + +m4_ifdef( [[M4_YY_NO_SCAN_BUFFER]],, +[[ +%if-c-only +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * M4_YY_DOC_PARAM + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer YYFARGS2( char *,base, yy_size_t ,size) +{ + YY_BUFFER_STATE b; + m4_dnl M4_YY_DECL_GUTS_VAR(); + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) M4_YY_CALL_LAST_ARG ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b M4_YY_CALL_LAST_ARG ); + + return b; +} +%endif +]]) + + +m4_ifdef( [[M4_YY_NO_SCAN_STRING]],, +[[ +%if-c-only +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * M4_YY_DOC_PARAM + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string YYFARGS1( yyconst char *, yystr) +{ + m4_dnl M4_YY_DECL_GUTS_VAR(); + + return yy_scan_bytes( yystr, strlen(yystr) M4_YY_CALL_LAST_ARG); +} +%endif +]]) + + +m4_ifdef( [[M4_YY_NO_SCAN_BYTES]],, +[[ +%if-c-only +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * M4_YY_DOC_PARAM + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes YYFARGS2( yyconst char *,yybytes, yy_size_t ,_yybytes_len) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + yy_size_t i; + m4_dnl M4_YY_DECL_GUTS_VAR(); + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) yyalloc( n M4_YY_CALL_LAST_ARG ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n M4_YY_CALL_LAST_ARG); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} +%endif +]]) + + +m4_ifdef( [[M4_YY_NO_PUSH_STATE]],, +[[ +%if-c-only + static void yy_push_state YYFARGS1( int ,new_state) +%endif +%if-c++-only + void yyFlexLexer::yy_push_state( int new_state ) +%endif +{ + M4_YY_DECL_GUTS_VAR(); + if ( YY_G(yy_start_stack_ptr) >= YY_G(yy_start_stack_depth) ) + { + yy_size_t new_size; + + YY_G(yy_start_stack_depth) += YY_START_STACK_INCR; + new_size = YY_G(yy_start_stack_depth) * sizeof( int ); + + if ( ! YY_G(yy_start_stack) ) + YY_G(yy_start_stack) = (int *) yyalloc( new_size M4_YY_CALL_LAST_ARG ); + + else + YY_G(yy_start_stack) = (int *) yyrealloc( + (void *) YY_G(yy_start_stack), new_size M4_YY_CALL_LAST_ARG ); + + if ( ! YY_G(yy_start_stack) ) + YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); + } + + YY_G(yy_start_stack)[YY_G(yy_start_stack_ptr)++] = YY_START; + + BEGIN(new_state); +} +]]) + + +m4_ifdef( [[M4_YY_NO_POP_STATE]],, +[[ +%if-c-only + static void yy_pop_state YYFARGS0(void) +%endif +%if-c++-only + void yyFlexLexer::yy_pop_state() +%endif +{ + M4_YY_DECL_GUTS_VAR(); + if ( --YY_G(yy_start_stack_ptr) < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(YY_G(yy_start_stack)[YY_G(yy_start_stack_ptr)]); +} +]]) + + +m4_ifdef( [[M4_YY_NO_TOP_STATE]],, +[[ +%if-c-only + static int yy_top_state YYFARGS0(void) +%endif +%if-c++-only + int yyFlexLexer::yy_top_state() +%endif +{ + M4_YY_DECL_GUTS_VAR(); + return YY_G(yy_start_stack)[YY_G(yy_start_stack_ptr) - 1]; +} +]]) + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +%if-c-only +static void yy_fatal_error YYFARGS1(yyconst char*, msg) +{ + m4_dnl M4_YY_DECL_GUTS_VAR(); + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} +%endif +%if-c++-only +void yyFlexLexer::LexerError( yyconst char msg[] ) +{ + M4_YY_DECL_GUTS_VAR(); + std::cerr << msg << std::endl; + exit( YY_EXIT_FAILURE ); +} +%endif + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = YY_G(yy_hold_char); \ + YY_G(yy_c_buf_p) = yytext + yyless_macro_arg; \ + YY_G(yy_hold_char) = *YY_G(yy_c_buf_p); \ + *YY_G(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + + + +/* Accessor methods (get/set functions) to struct members. */ + +%if-c-only +%if-reentrant +m4_ifdef( [[M4_YY_NO_GET_EXTRA]],, +[[ +/** Get the user-defined data for this scanner. + * M4_YY_DOC_PARAM + */ +YY_EXTRA_TYPE yyget_extra YYFARGS0(void) +{ + M4_YY_DECL_GUTS_VAR(); + return yyextra; +} +]]) +%endif + +m4_ifdef( [[M4_YY_NO_GET_LINENO]],, +[[ +/** Get the current line number. + * M4_YY_DOC_PARAM + */ +int yyget_lineno YYFARGS0(void) +{ + M4_YY_DECL_GUTS_VAR(); + + m4_ifdef( [[M4_YY_REENTRANT]], + [[ + if (! YY_CURRENT_BUFFER) + return 0; + ]]) + return yylineno; +} +]]) + +m4_ifdef( [[M4_YY_REENTRANT]], +[[ +m4_ifdef( [[M4_YY_NO_GET_COLUMN]],, +[[ +/** Get the current column number. + * M4_YY_DOC_PARAM + */ +int yyget_column YYFARGS0(void) +{ + M4_YY_DECL_GUTS_VAR(); + + m4_ifdef( [[M4_YY_REENTRANT]], + [[ + if (! YY_CURRENT_BUFFER) + return 0; + ]]) + return yycolumn; +} +]]) +]]) + +m4_ifdef( [[M4_YY_NO_GET_IN]],, +[[ +/** Get the input stream. + * M4_YY_DOC_PARAM + */ +FILE *yyget_in YYFARGS0(void) +{ + M4_YY_DECL_GUTS_VAR(); + return yyin; +} +]]) + +m4_ifdef( [[M4_YY_NO_GET_OUT]],, +[[ +/** Get the output stream. + * M4_YY_DOC_PARAM + */ +FILE *yyget_out YYFARGS0(void) +{ + M4_YY_DECL_GUTS_VAR(); + return yyout; +} +]]) + +m4_ifdef( [[M4_YY_NO_GET_LENG]],, +[[ +/** Get the length of the current token. + * M4_YY_DOC_PARAM + */ +yy_size_t yyget_leng YYFARGS0(void) +{ + M4_YY_DECL_GUTS_VAR(); + return yyleng; +} +]]) + +/** Get the current token. + * M4_YY_DOC_PARAM + */ +m4_ifdef( [[M4_YY_NO_GET_TEXT]],, +[[ +char *yyget_text YYFARGS0(void) +{ + M4_YY_DECL_GUTS_VAR(); + return yytext; +} +]]) + +%if-reentrant +m4_ifdef( [[M4_YY_NO_SET_EXTRA]],, +[[ +/** Set the user-defined data. This data is never touched by the scanner. + * @param user_defined The data to be associated with this scanner. + * M4_YY_DOC_PARAM + */ +void yyset_extra YYFARGS1( YY_EXTRA_TYPE ,user_defined) +{ + M4_YY_DECL_GUTS_VAR(); + yyextra = user_defined ; +} +]]) +%endif + +m4_ifdef( [[M4_YY_NO_SET_LINENO]],, +[[ +/** Set the current line number. + * @param line_number + * M4_YY_DOC_PARAM + */ +void yyset_lineno YYFARGS1( int ,line_number) +{ + M4_YY_DECL_GUTS_VAR(); + + m4_ifdef( [[M4_YY_REENTRANT]], + [[ + /* lineno is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); + ]]) + yylineno = line_number; +} +]]) + +m4_ifdef( [[M4_YY_REENTRANT]], +[[ +m4_ifdef( [[M4_YY_NO_SET_COLUMN]],, +[[ +/** Set the current column. + * @param line_number + * M4_YY_DOC_PARAM + */ +void yyset_column YYFARGS1( int , column_no) +{ + M4_YY_DECL_GUTS_VAR(); + + m4_ifdef( [[M4_YY_REENTRANT]], + [[ + /* column is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + YY_FATAL_ERROR( "yyset_column called with no buffer" ); + ]]) + yycolumn = column_no; +} +]]) +]]) + + +m4_ifdef( [[M4_YY_NO_SET_IN]],, +[[ +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * M4_YY_DOC_PARAM + * @see yy_switch_to_buffer + */ +void yyset_in YYFARGS1( FILE * ,in_str) +{ + M4_YY_DECL_GUTS_VAR(); + yyin = in_str ; +} +]]) + +m4_ifdef( [[M4_YY_NO_SET_OUT]],, +[[ +void yyset_out YYFARGS1( FILE * ,out_str) +{ + M4_YY_DECL_GUTS_VAR(); + yyout = out_str ; +} +]]) + + +m4_ifdef( [[M4_YY_NO_GET_DEBUG]],, +[[ +int yyget_debug YYFARGS0(void) +{ + M4_YY_DECL_GUTS_VAR(); + return yy_flex_debug; +} +]]) + +m4_ifdef( [[M4_YY_NO_SET_DEBUG]],, +[[ +void yyset_debug YYFARGS1( int ,bdebug) +{ + M4_YY_DECL_GUTS_VAR(); + yy_flex_debug = bdebug ; +} +]]) +%endif + +%if-reentrant +/* Accessor methods for yylval and yylloc */ + +%if-bison-bridge +m4_ifdef( [[M4_YY_NO_GET_LVAL]],, +[[ +YYSTYPE * yyget_lval YYFARGS0(void) +{ + M4_YY_DECL_GUTS_VAR(); + return yylval; +} +]]) + +m4_ifdef( [[M4_YY_NO_SET_LVAL]],, +[[ +void yyset_lval YYFARGS1( YYSTYPE * ,yylval_param) +{ + M4_YY_DECL_GUTS_VAR(); + yylval = yylval_param; +} +]]) + +m4_ifdef( [[]], +[[ + m4_ifdef( [[M4_YY_NO_GET_LLOC]],, + [[ +YYLTYPE *yyget_lloc YYFARGS0(void) +{ + M4_YY_DECL_GUTS_VAR(); + return yylloc; +} + ]]) + + m4_ifdef( [[M4_YY_NO_SET_LLOC]],, + [[ +void yyset_lloc YYFARGS1( YYLTYPE * ,yylloc_param) +{ + M4_YY_DECL_GUTS_VAR(); + yylloc = yylloc_param; +} + ]]) +]]) + +%endif + + +/* User-visible API */ + +/* yylex_init is special because it creates the scanner itself, so it is + * the ONLY reentrant function that doesn't take the scanner as the last argument. + * That's why we explicitly handle the declaration, instead of using our macros. + */ +m4_ifdef( [[M4_YY_NO_ANSI_FUNC_DEFS]], +[[ +int yylex_init( ptr_yy_globals ) + yyscan_t* ptr_yy_globals; +]], +[[ +int yylex_init(yyscan_t* ptr_yy_globals) +]]) +{ + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + return yy_init_globals ( *ptr_yy_globals ); +} + + +/* yylex_init_extra has the same functionality as yylex_init, but follows the + * convention of taking the scanner as the last argument. Note however, that + * this is a *pointer* to a scanner, as it will be allocated by this call (and + * is the reason, too, why this function also must handle its own declaration). + * The user defined value in the first argument will be available to yyalloc in + * the yyextra field. + */ +m4_ifdef( [[M4_YY_NO_ANSI_FUNC_DEFS]], +[[ +int yylex_init_extra( yy_user_defined, ptr_yy_globals ) + YY_EXTRA_TYPE yy_user_defined; + yyscan_t* ptr_yy_globals; +]], +[[ +int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals ) +]]) +{ + struct yyguts_t dummy_yyguts; + + yyset_extra (yy_user_defined, &dummy_yyguts); + + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in + yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + yyset_extra (yy_user_defined, *ptr_yy_globals); + + return yy_init_globals ( *ptr_yy_globals ); +} + +%endif if-c-only + + +%if-c-only +static int yy_init_globals YYFARGS0(void) +{ + M4_YY_DECL_GUTS_VAR(); + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + +m4_ifdef( [[M4_YY_USE_LINENO]], +[[ + m4_ifdef( [[M4_YY_NOT_REENTRANT]], + [[ + /* We do not touch yylineno unless the option is enabled. */ + yylineno = 1; + ]]) +]]) + YY_G(yy_buffer_stack) = 0; + YY_G(yy_buffer_stack_top) = 0; + YY_G(yy_buffer_stack_max) = 0; + YY_G(yy_c_buf_p) = (char *) 0; + YY_G(yy_init) = 0; + YY_G(yy_start) = 0; + +m4_ifdef( [[M4_YY_HAS_START_STACK_VARS]], +[[ + YY_G(yy_start_stack_ptr) = 0; + YY_G(yy_start_stack_depth) = 0; + YY_G(yy_start_stack) = NULL; +]]) + +m4_ifdef( [[M4_YY_USES_REJECT]], +[[ + YY_G(yy_state_buf) = 0; + YY_G(yy_state_ptr) = 0; + YY_G(yy_full_match) = 0; + YY_G(yy_lp) = 0; +]]) + +m4_ifdef( [[M4_YY_TEXT_IS_ARRAY]], +[[ + YY_G(yytext_ptr) = 0; + YY_G(yy_more_offset) = 0; + YY_G(yy_prev_more_offset) = 0; +]]) + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} +%endif + + +%if-c-only SNIP! this currently causes conflicts with the c++ scanner +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy YYFARGS0(void) +{ + M4_YY_DECL_GUTS_VAR(); + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER M4_YY_CALL_LAST_ARG ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(M4_YY_CALL_ONLY_ARG); + } + + /* Destroy the stack itself. */ + yyfree(YY_G(yy_buffer_stack) M4_YY_CALL_LAST_ARG); + YY_G(yy_buffer_stack) = NULL; + +m4_ifdef( [[M4_YY_HAS_START_STACK_VARS]], +[[ + /* Destroy the start condition stack. */ + yyfree( YY_G(yy_start_stack) M4_YY_CALL_LAST_ARG ); + YY_G(yy_start_stack) = NULL; +]]) + +m4_ifdef( [[M4_YY_USES_REJECT]], +[[ + yyfree ( YY_G(yy_state_buf) M4_YY_CALL_LAST_ARG); + YY_G(yy_state_buf) = NULL; +]]) + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( M4_YY_CALL_ONLY_ARG); + +%if-reentrant + /* Destroy the main struct (reentrant only). */ + yyfree ( yyscanner M4_YY_CALL_LAST_ARG ); + yyscanner = NULL; +%endif + return 0; +} +%endif + + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +/* + * Internal utility routines. + */ +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +#ifndef yytext_ptr +static void yy_flex_strncpy YYFARGS3( char*,s1, yyconst char *,s2, int,n) +{ + int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif +]]) + +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], +[[ +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen YYFARGS1( yyconst char *,s) +{ + int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif +]]) + +m4_ifdef( [[M4_YY_NO_FLEX_ALLOC]],, +[[ +void *yyalloc YYFARGS1( yy_size_t ,size) +{ + return (void *) malloc( size ); +} +]]) + +m4_ifdef( [[M4_YY_NO_FLEX_REALLOC]],, +[[ +void *yyrealloc YYFARGS2( void *,ptr, yy_size_t ,size) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} +]]) + +m4_ifdef( [[M4_YY_NO_FLEX_FREE]],, +[[ +void yyfree YYFARGS1( void *,ptr) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} +]]) + +%if-tables-serialization definitions +m4preproc_include(`tables_shared.c') + +static int yytbl_read8 (void *v, struct yytbl_reader * rd) +{ + errno = 0; + if (fread (v, sizeof (flex_uint8_t), 1, rd->fp) != 1){ + errno = EIO; + return -1; + } + rd->bread += sizeof(flex_uint8_t); + return 0; +} + +static int yytbl_read16 (void *v, struct yytbl_reader * rd) +{ + errno = 0; + if (fread (v, sizeof (flex_uint16_t), 1, rd->fp) != 1){ + errno = EIO; + return -1; + } + *((flex_uint16_t *) v) = ntohs (*((flex_uint16_t *) v)); + rd->bread += sizeof(flex_uint16_t); + return 0; +} + +static int yytbl_read32 (void *v, struct yytbl_reader * rd) +{ + errno = 0; + if (fread (v, sizeof (flex_uint32_t), 1, rd->fp) != 1){ + errno = EIO; + return -1; + } + *((flex_uint32_t *) v) = ntohl (*((flex_uint32_t *) v)); + rd->bread += sizeof(flex_uint32_t); + return 0; +} + +/** Read the header */ +static int yytbl_hdr_read YYFARGS2(struct yytbl_hdr *, th, struct yytbl_reader *, rd) +{ + int bytes; + memset (th, 0, sizeof (struct yytbl_hdr)); + + if (yytbl_read32 (&(th->th_magic), rd) != 0) + return -1; + + if (th->th_magic != YYTBL_MAGIC){ + YY_FATAL_ERROR( "bad magic number" ); /* TODO: not fatal. */ + return -1; + } + + if (yytbl_read32 (&(th->th_hsize), rd) != 0 + || yytbl_read32 (&(th->th_ssize), rd) != 0 + || yytbl_read16 (&(th->th_flags), rd) != 0) + return -1; + + /* Sanity check on header size. Greater than 1k suggests some funny business. */ + if (th->th_hsize < 16 || th->th_hsize > 1024){ + YY_FATAL_ERROR( "insane header size detected" ); /* TODO: not fatal. */ + return -1; + } + + /* Allocate enough space for the version and name fields */ + bytes = th->th_hsize - 14; + th->th_version = (char *) yyalloc (bytes M4_YY_CALL_LAST_ARG); + if ( ! th->th_version ) + YY_FATAL_ERROR( "out of dynamic memory in yytbl_hdr_read()" ); + + /* we read it all into th_version, and point th_name into that data */ + if (fread (th->th_version, 1, bytes, rd->fp) != bytes){ + errno = EIO; + yyfree(th->th_version M4_YY_CALL_LAST_ARG); + th->th_version = NULL; + return -1; + } + else + rd->bread += bytes; + + th->th_name = th->th_version + strlen (th->th_version) + 1; + return 0; +} + +/** lookup id in the dmap list. + * @param dmap pointer to first element in list + * @return NULL if not found. + */ +static struct yytbl_dmap *yytbl_dmap_lookup YYFARGS2(struct yytbl_dmap *, dmap, + int, id) +{ + while (dmap->dm_id) + if (dmap->dm_id == id) + return dmap; + else + dmap++; + return NULL; +} + +/** Read a table while mapping its contents to the local array. + * @param dmap used to performing mapping + * @return 0 on success + */ +static int yytbl_data_load YYFARGS2(struct yytbl_dmap *, dmap, struct yytbl_reader*, rd) +{ + struct yytbl_data td; + struct yytbl_dmap *transdmap=0; + int len, i, rv, inner_loop_count; + void *p=0; + + memset (&td, 0, sizeof (struct yytbl_data)); + + if (yytbl_read16 (&td.td_id, rd) != 0 + || yytbl_read16 (&td.td_flags, rd) != 0 + || yytbl_read32 (&td.td_hilen, rd) != 0 + || yytbl_read32 (&td.td_lolen, rd) != 0) + return -1; + + /* Lookup the map for the transition table so we have it in case we need it + * inside the loop below. This scanner might not even have a transition + * table, which is ok. + */ + transdmap = yytbl_dmap_lookup (dmap, YYTD_ID_TRANSITION M4_YY_CALL_LAST_ARG); + + if ((dmap = yytbl_dmap_lookup (dmap, td.td_id M4_YY_CALL_LAST_ARG)) == NULL){ + YY_FATAL_ERROR( "table id not found in map." ); /* TODO: not fatal. */ + return -1; + } + + /* Allocate space for table. + * The --full yy_transition table is a special case, since we + * need the dmap.dm_sz entry to tell us the sizeof the individual + * struct members. + */ + { + size_t bytes; + + if ((td.td_flags & YYTD_STRUCT)) + bytes = sizeof(struct yy_trans_info) * td.td_lolen * (td.td_hilen ? td.td_hilen : 1); + else + bytes = td.td_lolen * (td.td_hilen ? td.td_hilen : 1) * dmap->dm_sz; + + if(M4_YY_TABLES_VERIFY) + /* We point to the array itself */ + p = dmap->dm_arr; + else + /* We point to the address of a pointer. */ + *dmap->dm_arr = p = (void *) yyalloc (bytes M4_YY_CALL_LAST_ARG); + if ( ! p ) + YY_FATAL_ERROR( "out of dynamic memory in yytbl_data_load()" ); + } + + /* If it's a struct, we read 2 integers to get one element */ + if ((td.td_flags & YYTD_STRUCT) != 0) + inner_loop_count = 2; + else + inner_loop_count = 1; + + /* read and map each element. + * This loop iterates once for each element of the td_data array. + * Notice that we increment 'i' in the inner loop. + */ + len = yytbl_calc_total_len (&td); + for (i = 0; i < len; ){ + int j; + + + /* This loop really executes exactly 1 or 2 times. + * The second time is to handle the second member of the + * YYTD_STRUCT for the yy_transition array. + */ + for (j = 0; j < inner_loop_count; j++, i++) { + flex_int32_t t32; + + /* read into t32 no matter what the real size is. */ + { + flex_int16_t t16; + flex_int8_t t8; + + switch (YYTDFLAGS2BYTES (td.td_flags)) { + case sizeof (flex_int32_t): + rv = yytbl_read32 (&t32, rd); + break; + case sizeof (flex_int16_t): + rv = yytbl_read16 (&t16, rd); + t32 = t16; + break; + case sizeof (flex_int8_t): + rv = yytbl_read8 (&t8, rd); + t32 = t8; + break; + default: + YY_FATAL_ERROR( "invalid td_flags" ); /* TODO: not fatal. */ + return -1; + } + } + if (rv != 0) + return -1; + + /* copy into the deserialized array... */ + + if ((td.td_flags & YYTD_STRUCT)) { + /* t32 is the j'th member of a two-element struct. */ + void *v; + + v = j == 0 ? &(((struct yy_trans_info *) p)->yy_verify) + : &(((struct yy_trans_info *) p)->yy_nxt); + + switch (dmap->dm_sz) { + case sizeof (flex_int32_t): + if (M4_YY_TABLES_VERIFY){ + if( ((flex_int32_t *) v)[0] != (flex_int32_t) t32) + YY_FATAL_ERROR( "tables verification failed at YYTD_STRUCT flex_int32_t" ); + }else + ((flex_int32_t *) v)[0] = (flex_int32_t) t32; + break; + case sizeof (flex_int16_t): + if (M4_YY_TABLES_VERIFY ){ + if(((flex_int16_t *) v)[0] != (flex_int16_t) t32) + YY_FATAL_ERROR( "tables verification failed at YYTD_STRUCT flex_int16_t" ); + }else + ((flex_int16_t *) v)[0] = (flex_int16_t) t32; + break; + case sizeof(flex_int8_t): + if (M4_YY_TABLES_VERIFY ){ + if( ((flex_int8_t *) v)[0] != (flex_int8_t) t32) + YY_FATAL_ERROR( "tables verification failed at YYTD_STRUCT flex_int8_t" ); + }else + ((flex_int8_t *) v)[0] = (flex_int8_t) t32; + break; + default: + YY_FATAL_ERROR( "invalid dmap->dm_sz for struct" ); /* TODO: not fatal. */ + return -1; + } + + /* if we're done with j, increment p */ + if (j == 1) + p = (struct yy_trans_info *) p + 1; + } + else if ((td.td_flags & YYTD_PTRANS)) { + /* t32 is an index into the transition array. */ + struct yy_trans_info *v; + + + if (!transdmap){ + YY_FATAL_ERROR( "transition table not found" ); /* TODO: not fatal. */ + return -1; + } + + if( M4_YY_TABLES_VERIFY) + v = &(((struct yy_trans_info *) (transdmap->dm_arr))[t32]); + else + v = &((*((struct yy_trans_info **) (transdmap->dm_arr)))[t32]); + + if(M4_YY_TABLES_VERIFY ){ + if( ((struct yy_trans_info **) p)[0] != v) + YY_FATAL_ERROR( "tables verification failed at YYTD_PTRANS" ); + }else + ((struct yy_trans_info **) p)[0] = v; + + /* increment p */ + p = (struct yy_trans_info **) p + 1; + } + else { + /* t32 is a plain int. copy data, then incrememnt p. */ + switch (dmap->dm_sz) { + case sizeof (flex_int32_t): + if(M4_YY_TABLES_VERIFY ){ + if( ((flex_int32_t *) p)[0] != (flex_int32_t) t32) + YY_FATAL_ERROR( "tables verification failed at flex_int32_t" ); + }else + ((flex_int32_t *) p)[0] = (flex_int32_t) t32; + p = ((flex_int32_t *) p) + 1; + break; + case sizeof (flex_int16_t): + if(M4_YY_TABLES_VERIFY ){ + if( ((flex_int16_t *) p)[0] != (flex_int16_t) t32) + YY_FATAL_ERROR( "tables verification failed at flex_int16_t" ); + }else + ((flex_int16_t *) p)[0] = (flex_int16_t) t32; + p = ((flex_int16_t *) p) + 1; + break; + case sizeof (flex_int8_t): + if(M4_YY_TABLES_VERIFY ){ + if( ((flex_int8_t *) p)[0] != (flex_int8_t) t32) + YY_FATAL_ERROR( "tables verification failed at flex_int8_t" ); + }else + ((flex_int8_t *) p)[0] = (flex_int8_t) t32; + p = ((flex_int8_t *) p) + 1; + break; + default: + YY_FATAL_ERROR( "invalid dmap->dm_sz for plain int" ); /* TODO: not fatal. */ + return -1; + } + } + } + + } + + /* Now eat padding. */ + { + int pad; + pad = yypad64(rd->bread); + while(--pad >= 0){ + flex_int8_t t8; + if(yytbl_read8(&t8,rd) != 0) + return -1; + } + } + + return 0; +} + +%define-yytables The name for this specific scanner's tables. + +/* Find the key and load the DFA tables from the given stream. */ +static int yytbl_fload YYFARGS2(FILE *, fp, const char *, key) +{ + int rv=0; + struct yytbl_hdr th; + struct yytbl_reader rd; + + rd.fp = fp; + th.th_version = NULL; + + /* Keep trying until we find the right set of tables or end of file. */ + while (!feof(rd.fp)) { + rd.bread = 0; + if (yytbl_hdr_read (&th, &rd M4_YY_CALL_LAST_ARG) != 0){ + rv = -1; + goto return_rv; + } + + /* A NULL key means choose the first set of tables. */ + if (key == NULL) + break; + + if (strcmp(th.th_name,key) != 0){ + /* Skip ahead to next set */ + fseek(rd.fp, th.th_ssize - th.th_hsize, SEEK_CUR); + yyfree(th.th_version M4_YY_CALL_LAST_ARG); + th.th_version = NULL; + } + else + break; + } + + while (rd.bread < th.th_ssize){ + /* Load the data tables */ + if(yytbl_data_load (yydmap,&rd M4_YY_CALL_LAST_ARG) != 0){ + rv = -1; + goto return_rv; + } + } + +return_rv: + if(th.th_version){ + yyfree(th.th_version M4_YY_CALL_LAST_ARG); + th.th_version = NULL; + } + + return rv; +} + +/** Load the DFA tables for this scanner from the given stream. */ +int yytables_fload YYFARGS1(FILE *, fp) +{ + + if( yytbl_fload(fp, YYTABLES_NAME M4_YY_CALL_LAST_ARG) != 0) + return -1; + return 0; +} + +/** Destroy the loaded tables, freeing memory, etc.. */ +int yytables_destroy YYFARGS0(void) +{ + struct yytbl_dmap *dmap=0; + + if(!M4_YY_TABLES_VERIFY){ + /* Walk the dmap, freeing the pointers */ + for(dmap=yydmap; dmap->dm_id; dmap++) { + void * v; + v = dmap->dm_arr; + if(v && *(char**)v){ + yyfree(*(char**)v M4_YY_CALL_LAST_ARG); + *(char**)v = NULL; + } + } + } + + return 0; +} + +/* end table serialization code definitions */ +%endif + + +m4_ifdef([[M4_YY_MAIN]], [[ +int main M4_YY_PARAMS(void); + +int main () +{ + +%if-reentrant + yyscan_t lexer; + yylex_init(&lexer); + yylex( lexer ); + yylex_destroy( lexer); + +%endif +%if-not-reentrant + yylex(); +%endif + + return 0; +} +]]) + +%ok-for-header +m4_ifdef( [[M4_YY_IN_HEADER]], +[[ +#undef YY_NEW_FILE +#undef YY_FLUSH_BUFFER +#undef yy_set_bol +#undef yy_new_buffer +#undef yy_set_interactive +#undef YY_DO_BEFORE_ACTION + +#ifdef YY_DECL_IS_OURS +#undef YY_DECL_IS_OURS +#undef YY_DECL +#endif +]]) diff --git a/third_party/lex/flexdef.h b/third_party/lex/flexdef.h new file mode 100644 index 00000000..e069fd97 --- /dev/null +++ b/third_party/lex/flexdef.h @@ -0,0 +1,1105 @@ +/* clang-format off */ +#include "libc/stdio/stdio.h" +#include "libc/runtime/runtime.h" +#include "libc/macros.h" +#include "libc/calls/openbsd.h" + +/* $OpenBSD: flexdef.h,v 1.15 2015/11/19 23:48:06 tedu Exp $ */ + +/* flexdef - definitions file for flex */ + +/* Copyright (c) 1990 The Regents of the University of California. */ +/* All rights reserved. */ + +/* This code is derived from software contributed to Berkeley by */ +/* Vern Paxson. */ + +/* The United States Government has rights in this work pursuant */ +/* to contract no. DE-AC03-76SF00098 between the United States */ +/* Department of Energy and the University of California. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + +#ifndef FLEXDEF_H +#define FLEXDEF_H 1 + +#ifdef HAVE_CONFIG_H +#include "third_party/lex/config.h" +#endif + +#include "libc/limits.h" +#include "third_party/regex/regex.h" +#include "third_party/lex/flexint.h" + +#define _(STRING) STRING + +/* Always be prepared to generate an 8-bit scanner. */ +#define CSIZE 256 + +/* Size of input alphabet - should be size of ASCII set. */ +#ifndef DEFAULT_CSIZE +#define DEFAULT_CSIZE 128 +#endif + +#ifndef PROTO +#if defined(__STDC__) +#define PROTO(proto) proto +#else +#define PROTO(proto) () +#endif +#endif + +/* Maximum line length we'll have to deal with. */ +#define MAXLINE 2048 + +#define unspecified -1 + +/* Special chk[] values marking the slots taking by end-of-buffer and action + * numbers. + */ +#define EOB_POSITION -1 +#define ACTION_POSITION -2 + +/* Number of data items per line for -f output. */ +#define NUMDATAITEMS 10 + +/* Number of lines of data in -f output before inserting a blank line for + * readability. + */ +#define NUMDATALINES 10 + +/* transition_struct_out() definitions. */ +#define TRANS_STRUCT_PRINT_LENGTH 14 + +/* Returns true if an nfa state has an epsilon out-transition slot + * that can be used. This definition is currently not used. + */ +#define FREE_EPSILON(state) \ + (transchar[state] == SYM_EPSILON && trans2[state] == NO_TRANSITION && \ + finalst[state] != state) + +/* Returns true if an nfa state has an epsilon out-transition character + * and both slots are free + */ +#define SUPER_FREE_EPSILON(state) \ + (transchar[state] == SYM_EPSILON && trans1[state] == NO_TRANSITION) + +/* Maximum number of NFA states that can comprise a DFA state. It's real + * big because if there's a lot of rules, the initial state will have a + * huge epsilon closure. + */ +#define INITIAL_MAX_DFA_SIZE 750 +#define MAX_DFA_SIZE_INCREMENT 750 + +/* A note on the following masks. They are used to mark accepting numbers + * as being special. As such, they implicitly limit the number of accepting + * numbers (i.e., rules) because if there are too many rules the rule numbers + * will overload the mask bits. Fortunately, this limit is \large/ (0x2000 == + * 8192) so unlikely to actually cause any problems. A check is made in + * new_rule() to ensure that this limit is not reached. + */ + +/* Mask to mark a trailing context accepting number. */ +#define YY_TRAILING_MASK 0x2000 + +/* Mask to mark the accepting number of the "head" of a trailing context + * rule. + */ +#define YY_TRAILING_HEAD_MASK 0x4000 + +/* Maximum number of rules, as outlined in the above note. */ +#define MAX_RULE (YY_TRAILING_MASK - 1) + +/* NIL must be 0. If not, its special meaning when making equivalence classes + * (it marks the representative of a given e.c.) will be unidentifiable. + */ +#define NIL 0 + +#define JAM -1 /* to mark a missing DFA transition */ +#define NO_TRANSITION NIL +#define UNIQUE -1 /* marks a symbol as an e.c. representative */ +#define INFINITE_REPEAT -1 /* for x{5,} constructions */ + +#define INITIAL_MAX_CCLS 100 /* max number of unique character classes */ +#define MAX_CCLS_INCREMENT 100 + +/* Size of table holding members of character classes. */ +#define INITIAL_MAX_CCL_TBL_SIZE 500 +#define MAX_CCL_TBL_SIZE_INCREMENT 250 + +#define INITIAL_MAX_RULES 100 /* default maximum number of rules */ +#define MAX_RULES_INCREMENT 100 + +#define INITIAL_MNS 2000 /* default maximum number of nfa states */ +#define MNS_INCREMENT 1000 /* amount to bump above by if it's not enough */ + +#define INITIAL_MAX_DFAS 1000 /* default maximum number of dfa states */ +#define MAX_DFAS_INCREMENT 1000 + +#define JAMSTATE -32766 /* marks a reference to the state that always jams */ + +/* Maximum number of NFA states. */ +#define MAXIMUM_MNS 31999 +#define MAXIMUM_MNS_LONG 1999999999 + +/* Enough so that if it's subtracted from an NFA state number, the result + * is guaranteed to be negative. + */ +#define MARKER_DIFFERENCE (maximum_mns + 2) + +/* Maximum number of nxt/chk pairs for non-templates. */ +#define INITIAL_MAX_XPAIRS 2000 +#define MAX_XPAIRS_INCREMENT 2000 + +/* Maximum number of nxt/chk pairs needed for templates. */ +#define INITIAL_MAX_TEMPLATE_XPAIRS 2500 +#define MAX_TEMPLATE_XPAIRS_INCREMENT 2500 + +#define SYM_EPSILON (CSIZE + 1) /* to mark transitions on the symbol epsilon \ + */ + +#define INITIAL_MAX_SCS 40 /* maximum number of start conditions */ +#define MAX_SCS_INCREMENT 40 /* amount to bump by if it's not enough */ + +#define ONE_STACK_SIZE 500 /* stack of states with only one out-transition */ +#define SAME_TRANS -1 /* transition is the same as "default" entry for state \ + */ + +/* The following percentages are used to tune table compression: + + * The percentage the number of out-transitions a state must be of the + * number of equivalence classes in order to be considered for table + * compaction by using protos. + */ +#define PROTO_SIZE_PERCENTAGE 15 + +/* The percentage the number of homogeneous out-transitions of a state + * must be of the number of total out-transitions of the state in order + * that the state's transition table is first compared with a potential + * template of the most common out-transition instead of with the first + * proto in the proto queue. + */ +#define CHECK_COM_PERCENTAGE 50 + +/* The percentage the number of differences between a state's transition + * table and the proto it was first compared with must be of the total + * number of out-transitions of the state in order to keep the first + * proto as a good match and not search any further. + */ +#define FIRST_MATCH_DIFF_PERCENTAGE 10 + +/* The percentage the number of differences between a state's transition + * table and the most similar proto must be of the state's total number + * of out-transitions to use the proto as an acceptable close match. + */ +#define ACCEPTABLE_DIFF_PERCENTAGE 50 + +/* The percentage the number of homogeneous out-transitions of a state + * must be of the number of total out-transitions of the state in order + * to consider making a template from the state. + */ +#define TEMPLATE_SAME_PERCENTAGE 60 + +/* The percentage the number of differences between a state's transition + * table and the most similar proto must be of the state's total number + * of out-transitions to create a new proto from the state. + */ +#define NEW_PROTO_DIFF_PERCENTAGE 20 + +/* The percentage the total number of out-transitions of a state must be + * of the number of equivalence classes in order to consider trying to + * fit the transition table into "holes" inside the nxt/chk table. + */ +#define INTERIOR_FIT_PERCENTAGE 15 + +/* Size of region set aside to cache the complete transition table of + * protos on the proto queue to enable quick comparisons. + */ +#define PROT_SAVE_SIZE 2000 + +#define MSP 50 /* maximum number of saved protos (protos on the proto queue) \ + */ + +/* Maximum number of out-transitions a state can have that we'll rummage + * around through the interior of the internal fast table looking for a + * spot for it. + */ +#define MAX_XTIONS_FULL_INTERIOR_FIT 4 + +/* Maximum number of rules which will be reported as being associated + * with a DFA state. + */ +#define MAX_ASSOC_RULES 100 + +/* Number that, if used to subscript an array, has a good chance of producing + * an error; should be small enough to fit into a short. + */ +#define BAD_SUBSCRIPT -32767 + +/* Absolute value of largest number that can be stored in a short, with a + * bit of slop thrown in for general paranoia. + */ +#define MAX_SHORT 32700 + +/* Declarations for global variables. */ + +/* Variables for flags: + * printstats - if true (-v), dump statistics + * syntaxerror - true if a syntax error has been found + * eofseen - true if we've seen an eof in the input file + * ddebug - if true (-d), make a "debug" scanner + * trace - if true (-T), trace processing + * nowarn - if true (-w), do not generate warnings + * spprdflt - if true (-s), suppress the default rule + * interactive - if true (-I), generate an interactive scanner + * lex_compat - if true (-l), maximize compatibility with AT&T lex + * posix_compat - if true (-X), maximize compatibility with POSIX lex + * do_yylineno - if true, generate code to maintain yylineno + * useecs - if true (-Ce flag), use equivalence classes + * fulltbl - if true (-Cf flag), don't compress the DFA state table + * usemecs - if true (-Cm flag), use meta-equivalence classes + * fullspd - if true (-F flag), use Jacobson method of table representation + * gen_line_dirs - if true (i.e., no -L flag), generate #line directives + * performance_report - if > 0 (i.e., -p flag), generate a report relating + * to scanner performance; if > 1 (-p -p), report on minor performance + * problems, too + * backing_up_report - if true (i.e., -b flag), generate "lex.backup" file + * listing backing-up states + * C_plus_plus - if true (i.e., -+ flag), generate a C++ scanner class; + * otherwise, a standard C scanner + * reentrant - if true (-R), generate a reentrant C scanner. + * bison_bridge_lval - if true (--bison-bridge), bison pure calling convention. + * bison_bridge_lloc - if true (--bison-locations), bison yylloc. + * long_align - if true (-Ca flag), favor long-word alignment. + * use_read - if true (-f, -F, or -Cr) then use read() for scanner input; + * otherwise, use fread(). + * yytext_is_array - if true (i.e., %array directive), then declare + * yytext as a array instead of a character pointer. Nice and inefficient. + * do_yywrap - do yywrap() processing on EOF. If false, EOF treated as + * "no more files". + * csize - size of character set for the scanner we're generating; + * 128 for 7-bit chars and 256 for 8-bit + * yymore_used - if true, yymore() is used in input rules + * reject - if true, generate back-up tables for REJECT macro + * real_reject - if true, scanner really uses REJECT (as opposed to just + * having "reject" set for variable trailing context) + * continued_action - true if this rule's action is to "fall through" to + * the next rule's action (i.e., the '|' action) + * in_rule - true if we're inside an individual rule, false if not. + * yymore_really_used - whether to treat yymore() as really used, regardless + * of what we think based on references to it in the user's actions. + * reject_really_used - same for REJECT + */ + +extern int printstats, syntaxerror, eofseen, ddebug, trace, nowarn, spprdflt; +extern int interactive, lex_compat, posix_compat, do_yylineno; +extern int useecs, fulltbl, usemecs, fullspd; +extern int gen_line_dirs, performance_report, backing_up_report; +extern int reentrant, bison_bridge_lval, bison_bridge_lloc; +extern bool ansi_func_defs, ansi_func_protos; +extern int C_plus_plus, long_align, use_read, yytext_is_array, do_yywrap; +extern int csize; +extern int yymore_used, reject, real_reject, continued_action, in_rule; + +extern int yymore_really_used, reject_really_used; + +/* Variables used in the flex input routines: + * datapos - characters on current output line + * dataline - number of contiguous lines of data in current data + * statement. Used to generate readable -f output + * linenum - current input line number + * skelfile - the skeleton file + * skel - compiled-in skeleton array + * skel_ind - index into "skel" array, if skelfile is nil + * yyin - input file + * backing_up_file - file to summarize backing-up states to + * infilename - name of input file + * outfilename - name of output file + * headerfilename - name of the .h file to generate + * did_outfilename - whether outfilename was explicitly set + * prefix - the prefix used for externally visible names ("yy" by default) + * yyclass - yyFlexLexer subclass to use for YY_DECL + * do_stdinit - whether to initialize yyin/yyout to stdin/stdout + * use_stdout - the -t flag + * input_files - array holding names of input files + * num_input_files - size of input_files array + * program_name - name with which program was invoked + * + * action_array - array to hold the rule actions + * action_size - size of action_array + * defs1_offset - index where the user's section 1 definitions start + * in action_array + * prolog_offset - index where the prolog starts in action_array + * action_offset - index where the non-prolog starts in action_array + * action_index - index where the next action should go, with respect + * to "action_array" + */ + +extern int datapos, dataline, linenum; +extern FILE *skelfile, *yyin, *backing_up_file; +extern const char *skel[]; +extern int skel_ind; +extern char *infilename, *outfilename, *headerfilename; +extern int did_outfilename; +extern char *prefix, *yyclass, *extra_type; +extern int do_stdinit, use_stdout; +extern char **input_files; +extern int num_input_files; +extern char *program_name; + +extern char *action_array; +extern int action_size; +extern int defs1_offset, prolog_offset, action_offset, action_index; + +/* Variables for stack of states having only one out-transition: + * onestate - state number + * onesym - transition symbol + * onenext - target state + * onedef - default base entry + * onesp - stack pointer + */ + +extern int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE]; +extern int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp; + +/* Variables for nfa machine data: + * maximum_mns - maximal number of NFA states supported by tables + * current_mns - current maximum on number of NFA states + * num_rules - number of the last accepting state; also is number of + * rules created so far + * num_eof_rules - number of <> rules + * default_rule - number of the default rule + * current_max_rules - current maximum number of rules + * lastnfa - last nfa state number created + * firstst - physically the first state of a fragment + * lastst - last physical state of fragment + * finalst - last logical state of fragment + * transchar - transition character + * trans1 - transition state + * trans2 - 2nd transition state for epsilons + * accptnum - accepting number + * assoc_rule - rule associated with this NFA state (or 0 if none) + * state_type - a STATE_xxx type identifying whether the state is part + * of a normal rule, the leading state in a trailing context + * rule (i.e., the state which marks the transition from + * recognizing the text-to-be-matched to the beginning of + * the trailing context), or a subsequent state in a trailing + * context rule + * rule_type - a RULE_xxx type identifying whether this a ho-hum + * normal rule or one which has variable head & trailing + * context + * rule_linenum - line number associated with rule + * rule_useful - true if we've determined that the rule can be matched + * rule_has_nl - true if rule could possibly match a newline + * ccl_has_nl - true if current ccl could match a newline + * nlch - default eol char + */ + +extern int maximum_mns, current_mns, current_max_rules; +extern int num_rules, num_eof_rules, default_rule, lastnfa; +extern int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2; +extern int *accptnum, *assoc_rule, *state_type; +extern int *rule_type, *rule_linenum, *rule_useful; +extern bool *rule_has_nl, *ccl_has_nl; +extern int nlch; + +/* Different types of states; values are useful as masks, as well, for + * routines like check_trailing_context(). + */ +#define STATE_NORMAL 0x1 +#define STATE_TRAILING_CONTEXT 0x2 + +/* Global holding current type of state we're making. */ + +extern int current_state_type; + +/* Different types of rules. */ +#define RULE_NORMAL 0 +#define RULE_VARIABLE 1 + +/* True if the input rules include a rule with both variable-length head + * and trailing context, false otherwise. + */ +extern int variable_trailing_context_rules; + +/* Variables for protos: + * numtemps - number of templates created + * numprots - number of protos created + * protprev - backlink to a more-recently used proto + * protnext - forward link to a less-recently used proto + * prottbl - base/def table entry for proto + * protcomst - common state of proto + * firstprot - number of the most recently used proto + * lastprot - number of the least recently used proto + * protsave contains the entire state array for protos + */ + +extern int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP]; +extern int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE]; + +/* Variables for managing equivalence classes: + * numecs - number of equivalence classes + * nextecm - forward link of Equivalence Class members + * ecgroup - class number or backward link of EC members + * nummecs - number of meta-equivalence classes (used to compress + * templates) + * tecfwd - forward link of meta-equivalence classes members + * tecbck - backward link of MEC's + */ + +/* Reserve enough room in the equivalence class arrays so that we + * can use the CSIZE'th element to hold equivalence class information + * for the NUL character. Later we'll move this information into + * the 0th element. + */ +extern int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs; + +/* Meta-equivalence classes are indexed starting at 1, so it's possible + * that they will require positions from 1 .. CSIZE, i.e., CSIZE + 1 + * slots total (since the arrays are 0-based). nextecm[] and ecgroup[] + * don't require the extra position since they're indexed from 1 .. CSIZE - 1. + */ +extern int tecfwd[CSIZE + 1], tecbck[CSIZE + 1]; + +/* Variables for start conditions: + * lastsc - last start condition created + * current_max_scs - current limit on number of start conditions + * scset - set of rules active in start condition + * scbol - set of rules active only at the beginning of line in a s.c. + * scxclu - true if start condition is exclusive + * sceof - true if start condition has EOF rule + * scname - start condition name + */ + +extern int lastsc, *scset, *scbol, *scxclu, *sceof; +extern int current_max_scs; +extern char **scname; + +/* Variables for dfa machine data: + * current_max_dfa_size - current maximum number of NFA states in DFA + * current_max_xpairs - current maximum number of non-template xtion pairs + * current_max_template_xpairs - current maximum number of template pairs + * current_max_dfas - current maximum number DFA states + * lastdfa - last dfa state number created + * nxt - state to enter upon reading character + * chk - check value to see if "nxt" applies + * tnxt - internal nxt table for templates + * base - offset into "nxt" for given state + * def - where to go if "chk" disallows "nxt" entry + * nultrans - NUL transition for each state + * NUL_ec - equivalence class of the NUL character + * tblend - last "nxt/chk" table entry being used + * firstfree - first empty entry in "nxt/chk" table + * dss - nfa state set for each dfa + * dfasiz - size of nfa state set for each dfa + * dfaacc - accepting set for each dfa state (if using REJECT), or accepting + * number, if not + * accsiz - size of accepting set for each dfa state + * dhash - dfa state hash value + * numas - number of DFA accepting states created; note that this + * is not necessarily the same value as num_rules, which is the analogous + * value for the NFA + * numsnpairs - number of state/nextstate transition pairs + * jambase - position in base/def where the default jam table starts + * jamstate - state number corresponding to "jam" state + * end_of_buffer_state - end-of-buffer dfa state number + */ + +extern int current_max_dfa_size, current_max_xpairs; +extern int current_max_template_xpairs, current_max_dfas; +extern int lastdfa, *nxt, *chk, *tnxt; +extern int *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz; +extern union dfaacc_union { + int *dfaacc_set; + int dfaacc_state; +} * dfaacc; +extern int *accsiz, *dhash, numas; +extern int numsnpairs, jambase, jamstate; +extern int end_of_buffer_state; + +/* Variables for ccl information: + * lastccl - ccl index of the last created ccl + * current_maxccls - current limit on the maximum number of unique ccl's + * cclmap - maps a ccl index to its set pointer + * ccllen - gives the length of a ccl + * cclng - true for a given ccl if the ccl is negated + * cclreuse - counts how many times a ccl is re-used + * current_max_ccl_tbl_size - current limit on number of characters needed + * to represent the unique ccl's + * ccltbl - holds the characters in each ccl - indexed by cclmap + */ + +extern int lastccl, *cclmap, *ccllen, *cclng, cclreuse; +extern int current_maxccls, current_max_ccl_tbl_size; +extern u_char *ccltbl; + +/* Variables for miscellaneous information: + * nmstr - last NAME scanned by the scanner + * sectnum - section number currently being parsed + * nummt - number of empty nxt/chk table entries + * hshcol - number of hash collisions detected by snstods + * dfaeql - number of times a newly created dfa was equal to an old one + * numeps - number of epsilon NFA states created + * eps2 - number of epsilon states which have 2 out-transitions + * num_reallocs - number of times it was necessary to realloc() a group + * of arrays + * tmpuses - number of DFA states that chain to templates + * totnst - total number of NFA states used to make DFA states + * peakpairs - peak number of transition pairs we had to store internally + * numuniq - number of unique transitions + * numdup - number of duplicate transitions + * hshsave - number of hash collisions saved by checking number of states + * num_backing_up - number of DFA states requiring backing up + * bol_needed - whether scanner needs beginning-of-line recognition + */ + +extern char nmstr[MAXLINE]; +extern int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs; +extern int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave; +extern int num_backing_up, bol_needed; + +void *allocate_array PROTO((int, size_t)); +void *reallocate_array PROTO((void *, int, size_t)); + +#define allocate_integer_array(size) (int *)allocate_array(size, sizeof(int)) + +#define reallocate_integer_array(array, size) \ + (int *)reallocate_array((void *)array, size, sizeof(int)) + +#define allocate_bool_array(size) (bool *)allocate_array(size, sizeof(bool)) + +#define reallocate_bool_array(array, size) \ + (bool *)reallocate_array((void *)array, size, sizeof(bool)) + +#define allocate_int_ptr_array(size) (int **)allocate_array(size, sizeof(int *)) + +#define allocate_char_ptr_array(size) \ + (char **)allocate_array(size, sizeof(char *)) + +#define allocate_dfaacc_union(size) \ + (union dfaacc_union *)allocate_array(size, sizeof(union dfaacc_union)) + +#define reallocate_int_ptr_array(array, size) \ + (int **)reallocate_array((void *)array, size, sizeof(int *)) + +#define reallocate_char_ptr_array(array, size) \ + (char **)reallocate_array((void *)array, size, sizeof(char *)) + +#define reallocate_dfaacc_union(array, size) \ + (union dfaacc_union *)reallocate_array((void *)array, size, \ + sizeof(union dfaacc_union)) + +#define allocate_character_array(size) \ + (char *)allocate_array(size, sizeof(char)) + +#define reallocate_character_array(array, size) \ + (char *)reallocate_array((void *)array, size, sizeof(char)) + +#define allocate_Character_array(size) \ + (u_char *)allocate_array(size, sizeof(u_char)) + +#define reallocate_Character_array(array, size) \ + (u_char *)reallocate_array((void *)array, size, sizeof(u_char)) + +/* Used to communicate between scanner and parser. The type should really + * be YYSTYPE, but we can't easily get our hands on it. + */ +extern int yylval; + +/* External functions that are cross-referenced among the flex source files. */ + +/* from file ccl.c */ + +extern void ccladd PROTO((int, int)); /* add a single character to a ccl */ +extern int cclinit PROTO((void)); /* make an empty ccl */ +extern void cclnegate PROTO((int)); /* negate a ccl */ +extern int ccl_set_diff(int a, int b); /* set difference of two ccls. */ +extern int ccl_set_union(int a, int b); /* set union of two ccls. */ + +/* List the members of a set of characters in CCL form. */ +extern void list_character_set PROTO((FILE *, int[])); + +/* from file dfa.c */ + +/* Check a DFA state for backing up. */ +extern void check_for_backing_up PROTO((int, int[])); + +/* Check to see if NFA state set constitutes "dangerous" trailing context. */ +extern void check_trailing_context PROTO((int *, int, int *, int)); + +/* Construct the epsilon closure of a set of ndfa states. */ +extern int *epsclosure PROTO((int *, int *, int[], int *, int *)); + +/* Increase the maximum number of dfas. */ +extern void increase_max_dfas PROTO((void)); + +extern void ntod PROTO((void)); /* convert a ndfa to a dfa */ + +/* Converts a set of ndfa states into a dfa state. */ +extern int snstods PROTO((int[], int, int[], int, int, int *)); + +/* from file ecs.c */ + +/* Convert character classes to set of equivalence classes. */ +extern void ccl2ecl PROTO((void)); + +/* Associate equivalence class numbers with class members. */ +extern int cre8ecs PROTO((int[], int[], int)); + +/* Update equivalence classes based on character class transitions. */ +extern void mkeccl PROTO((u_char[], int, int[], int[], int, int)); + +/* Create equivalence class for single character. */ +extern void mkechar PROTO((int, int[], int[])); + +/* from file gen.c */ + +extern void do_indent PROTO((void)); /* indent to the current level */ + +/* Generate the code to keep backing-up information. */ +extern void gen_backing_up PROTO((void)); + +/* Generate the code to perform the backing up. */ +extern void gen_bu_action PROTO((void)); + +/* Generate full speed compressed transition table. */ +extern void genctbl PROTO((void)); + +/* Generate the code to find the action number. */ +extern void gen_find_action PROTO((void)); + +extern void genftbl PROTO((void)); /* generate full transition table */ + +/* Generate the code to find the next compressed-table state. */ +extern void gen_next_compressed_state PROTO((char *)); + +/* Generate the code to find the next match. */ +extern void gen_next_match PROTO((void)); + +/* Generate the code to find the next state. */ +extern void gen_next_state PROTO((int)); + +/* Generate the code to make a NUL transition. */ +extern void gen_NUL_trans PROTO((void)); + +/* Generate the code to find the start state. */ +extern void gen_start_state PROTO((void)); + +/* Generate data statements for the transition tables. */ +extern void gentabs PROTO((void)); + +/* Write out a formatted string at the current indentation level. */ +extern void indent_put2s PROTO((const char *, const char *)); + +/* Write out a string + newline at the current indentation level. */ +extern void indent_puts PROTO((const char *)); + +extern void make_tables PROTO((void)); /* generate transition tables */ + +/* from file main.c */ + +extern void check_options PROTO((void)); +extern void flexend PROTO((int)); +extern void usage PROTO((void)); + +/* from file misc.c */ + +/* Add a #define to the action file. */ +extern void action_define PROTO((const char *defname, int value)); + +/* Add the given text to the stored actions. */ +extern void add_action PROTO((const char *new_text)); + +/* True if a string is all lower case. */ +extern int all_lower PROTO((char *)); + +/* True if a string is all upper case. */ +extern int all_upper PROTO((char *)); + +/* Compare two integers for use by qsort. */ +extern int intcmp PROTO((const void *, const void *)); + +/* Check a character to make sure it's in the expected range. */ +extern void check_char PROTO((int c)); + +/* Replace upper-case letter to lower-case. */ +extern u_char clower PROTO((int)); + +/* Returns a dynamically allocated copy of a string. */ +extern char *copy_string PROTO((const char *)); + +/* Returns a dynamically allocated copy of a (potentially) unsigned string. */ +extern u_char *copy_unsigned_string PROTO((u_char *)); + +/* Compare two characters for use by qsort with '\0' sorting last. */ +extern int cclcmp PROTO((const void *, const void *)); + +/* Finish up a block of data declarations. */ +extern void dataend PROTO((void)); + +/* Flush generated data statements. */ +extern void dataflush PROTO((void)); + +/* Report an error message and terminate. */ +extern void flexerror PROTO((const char *)); + +/* Report a fatal error message and terminate. */ +extern void flexfatal PROTO((const char *)); + +/* Report a fatal error with a pinpoint, and terminate */ +#if HAVE_DECL___FUNC__ +#define flex_die(msg) \ + do { \ + fprintf(stderr, _("%s: fatal internal error at %s:%d (%s): %s\n"), \ + program_name, __FILE__, (int)__LINE__, __func__, msg); \ + FLEX_EXIT(1); \ + } while (0) +#else /* ! HAVE_DECL___FUNC__ */ +#define flex_die(msg) \ + do { \ + fprintf(stderr, _("%s: fatal internal error at %s:%d %s\n"), program_name, \ + __FILE__, (int)__LINE__, msg); \ + FLEX_EXIT(1); \ + } while (0) +#endif /* ! HAVE_DECL___func__ */ + +/* Convert a hexadecimal digit string to an integer value. */ +extern int htoi PROTO((u_char[])); + +/* Report an error message formatted with one integer argument. */ +extern void lerrif PROTO((const char *, int)); + +/* Report an error message formatted with one string argument. */ +extern void lerrsf PROTO((const char *, const char *)); + +/* Like lerrsf, but also exit after displaying message. */ +extern void lerrsf_fatal PROTO((const char *, const char *)); + +/* Spit out a "#line" statement. */ +extern void line_directive_out PROTO((FILE *, int)); + +/* Mark the current position in the action array as the end of the section 1 + * user defs. + */ +extern void mark_defs1 PROTO((void)); + +/* Mark the current position in the action array as the end of the prolog. */ +extern void mark_prolog PROTO((void)); + +/* Generate a data statment for a two-dimensional array. */ +extern void mk2data PROTO((int)); + +extern void mkdata PROTO((int)); /* generate a data statement */ + +/* Return the integer represented by a string of digits. */ +extern int myctoi PROTO((const char *)); + +/* Return character corresponding to escape sequence. */ +extern u_char myesc PROTO((u_char[])); + +/* Convert an octal digit string to an integer value. */ +extern int otoi PROTO((u_char[])); + +/* Output a (possibly-formatted) string to the generated scanner. */ +extern void out PROTO((const char *)); +extern void out_dec PROTO((const char *, int)); +extern void out_dec2 PROTO((const char *, int, int)); +extern void out_hex PROTO((const char *, unsigned int)); +extern void out_str PROTO((const char *, const char *)); +extern void out_str3 PROTO((const char *, const char *, const char *, + const char *)); +extern void out_str_dec PROTO((const char *, const char *, int)); +extern void outc PROTO((int)); +extern void outn PROTO((const char *)); +extern void out_m4_define(const char *def, const char *val); + +/* Return a printable version of the given character, which might be + * 8-bit. + */ +extern char *readable_form PROTO((int)); + +/* Write out one section of the skeleton file. */ +extern void skelout PROTO((void)); + +/* Output a yy_trans_info structure. */ +extern void transition_struct_out PROTO((int, int)); + +/* Only needed when using certain broken versions of bison to build parse.c. */ +extern void *yy_flex_xmalloc PROTO((int)); + +/* from file nfa.c */ + +/* Add an accepting state to a machine. */ +extern void add_accept PROTO((int, int)); + +/* Make a given number of copies of a singleton machine. */ +extern int copysingl PROTO((int, int)); + +/* Debugging routine to write out an nfa. */ +extern void dumpnfa PROTO((int)); + +/* Finish up the processing for a rule. */ +extern void finish_rule PROTO((int, int, int, int, int)); + +/* Connect two machines together. */ +extern int link_machines PROTO((int, int)); + +/* Mark each "beginning" state in a machine as being a "normal" (i.e., + * not trailing context associated) state. + */ +extern void mark_beginning_as_normal PROTO((int)); + +/* Make a machine that branches to two machines. */ +extern int mkbranch PROTO((int, int)); + +extern int mkclos PROTO((int)); /* convert a machine into a closure */ +extern int mkopt PROTO((int)); /* make a machine optional */ + +/* Make a machine that matches either one of two machines. */ +extern int mkor PROTO((int, int)); + +/* Convert a machine into a positive closure. */ +extern int mkposcl PROTO((int)); + +extern int mkrep PROTO((int, int, int)); /* make a replicated machine */ + +/* Create a state with a transition on a given symbol. */ +extern int mkstate PROTO((int)); + +extern void new_rule PROTO((void)); /* initialize for a new rule */ + +/* from file parse.y */ + +/* Build the "<>" action for the active start conditions. */ +extern void build_eof_action PROTO((void)); + +/* Write out a message formatted with one string, pinpointing its location. */ +extern void format_pinpoint_message PROTO((const char *, const char *)); + +/* Write out a message, pinpointing its location. */ +extern void pinpoint_message PROTO((const char *)); + +/* Write out a warning, pinpointing it at the given line. */ +extern void line_warning PROTO((const char *, int)); + +/* Write out a message, pinpointing it at the given line. */ +extern void line_pinpoint PROTO((const char *, int)); + +/* Report a formatted syntax error. */ +extern void format_synerr PROTO((const char *, const char *)); +extern void synerr PROTO((const char *)); /* report a syntax error */ +extern void format_warn PROTO((const char *, const char *)); +extern void lexwarn PROTO((const char *)); /* report a warning */ +extern void yyerror PROTO((const char *)); /* report a parse error */ +extern int yyparse PROTO((void)); /* the YACC parser */ + +/* from file scan.l */ + +/* The Flex-generated scanner for flex. */ +extern int flexscan PROTO((void)); + +/* Open the given file (if NULL, stdin) for scanning. */ +extern void set_input_file PROTO((char *)); + +/* Wrapup a file in the lexical analyzer. */ +extern int yywrap PROTO((void)); + +/* from file sym.c */ + +/* Save the text of a character class. */ +extern void cclinstal PROTO((u_char[], int)); + +/* Lookup the number associated with character class. */ +extern int ccllookup PROTO((u_char[])); + +extern void ndinstal PROTO((const char *, + u_char[])); /* install a name definition */ +extern u_char *ndlookup PROTO((const char *)); /* lookup a name definition */ + +/* Increase maximum number of SC's. */ +extern void scextend PROTO((void)); +extern void scinstal PROTO((const char *, int)); /* make a start condition */ + +/* Lookup the number associated with a start condition. */ +extern int sclookup PROTO((const char *)); + +/* from file tblcmp.c */ + +/* Build table entries for dfa state. */ +extern void bldtbl PROTO((int[], int, int, int, int)); + +extern void cmptmps PROTO((void)); /* compress template table entries */ +extern void expand_nxt_chk PROTO((void)); /* increase nxt/chk arrays */ + +/* Finds a space in the table for a state to be placed. */ +extern int find_table_space PROTO((int *, int)); +extern void inittbl PROTO((void)); /* initialize transition tables */ + +/* Make the default, "jam" table entries. */ +extern void mkdeftbl PROTO((void)); + +/* Create table entries for a state (or state fragment) which has + * only one out-transition. + */ +extern void mk1tbl PROTO((int, int, int, int)); + +/* Place a state into full speed transition table. */ +extern void place_state PROTO((int *, int, int)); + +/* Save states with only one out-transition to be processed later. */ +extern void stack1 PROTO((int, int, int, int)); + +/* from file yylex.c */ + +extern int yylex PROTO((void)); + +/* A growable array. See buf.c. */ +struct Buf { + void *elts; /* elements. */ + int nelts; /* number of elements. */ + size_t elt_size; /* in bytes. */ + int nmax; /* max capacity of elements. */ +}; + +extern void buf_init PROTO((struct Buf * buf, size_t elem_size)); +extern void buf_destroy PROTO((struct Buf * buf)); +extern struct Buf *buf_append PROTO((struct Buf * buf, const void *ptr, + int n_elem)); +extern struct Buf *buf_concat PROTO((struct Buf * dest, const struct Buf *src)); +extern struct Buf *buf_strappend PROTO((struct Buf *, const char *str)); +extern struct Buf *buf_strnappend PROTO((struct Buf *, const char *str, + int nchars)); +extern struct Buf *buf_strdefine PROTO((struct Buf * buf, const char *str, + const char *def)); +extern struct Buf *buf_prints PROTO((struct Buf * buf, const char *fmt, + const char *s)); +extern struct Buf *buf_m4_define PROTO((struct Buf * buf, const char *def, + const char *val)); +extern struct Buf *buf_m4_undefine PROTO((struct Buf * buf, const char *def)); +extern struct Buf *buf_print_strings PROTO((struct Buf * buf, FILE *out)); +extern struct Buf *buf_linedir PROTO((struct Buf * buf, const char *filename, + int lineno)); + +extern struct Buf userdef_buf; /* a string buffer for #define's generated by + user-options on cmd line. */ +extern struct Buf defs_buf; /* a char* buffer to save #define'd some symbols + generated by flex. */ +extern struct Buf yydmap_buf; /* a string buffer to hold yydmap elements */ +extern struct Buf m4defs_buf; /* Holds m4 definitions. */ +extern struct Buf top_buf; /* contains %top code. String buffer. */ + +/* For blocking out code from the header file. */ +#define OUT_BEGIN_CODE() outn("m4_ifdef( [[M4_YY_IN_HEADER]],,[[") +#define OUT_END_CODE() outn("]])") + +/* For setjmp/longjmp (instead of calling exit(2)). Linkage in main.c */ +extern jmp_buf flex_main_jmp_buf; + +#define FLEX_EXIT(status) longjmp(flex_main_jmp_buf, (status) + 1) + +/* ctype functions forced to return boolean */ +#define b_isalnum(c) (isalnum(c) ? true : false) +#define b_isalpha(c) (isalpha(c) ? true : false) +#define b_isascii(c) (isascii(c) ? true : false) +#define b_isblank(c) (isblank(c) ? true : false) +#define b_iscntrl(c) (iscntrl(c) ? true : false) +#define b_isdigit(c) (isdigit(c) ? true : false) +#define b_isgraph(c) (isgraph(c) ? true : false) +#define b_islower(c) (islower(c) ? true : false) +#define b_isprint(c) (isprint(c) ? true : false) +#define b_ispunct(c) (ispunct(c) ? true : false) +#define b_isspace(c) (isspace(c) ? true : false) +#define b_isupper(c) (isupper(c) ? true : false) +#define b_isxdigit(c) (isxdigit(c) ? true : false) + +/* return true if char is uppercase or lowercase. */ +bool has_case(int c); + +/* Change case of character if possible. */ +int reverse_case(int c); + +/* return false if [c1-c2] is ambiguous for a caseless scanner. */ +bool range_covers_case(int c1, int c2); + +/* + * From "filter.c" + */ + +/** A single stdio filter to execute. + * The filter may be external, such as "sed", or it + * may be internal, as a function call. + */ +struct filter { + int (*filter_func)(struct filter *); /**< internal filter function */ + void *extra; /**< extra data passed to filter_func */ + int argc; /**< arg count */ + const char **argv; /**< arg vector, \0-terminated */ + struct filter *next; /**< next filter or NULL */ +}; + +/* output filter chain */ +extern struct filter *output_chain; +extern struct filter *filter_create_ext PROTO((struct filter * chain, + const char *cmd, ...)); +struct filter *filter_create_int PROTO((struct filter * chain, + int (*filter_func)(struct filter *), + void *extra)); +extern bool filter_apply_chain PROTO((struct filter * chain)); +extern int filter_truncate(struct filter *chain, int max_len); +extern int filter_tee_header PROTO((struct filter * chain)); +extern int filter_fix_linedirs PROTO((struct filter * chain)); + +/* + * From "regex.c" + */ + +extern regex_t regex_linedir, regex_blank_line; +bool flex_init_regex(void); +void flex_regcomp(regex_t *preg, const char *regex, int cflags); +char *regmatch_dup(regmatch_t *m, const char *src); +char *regmatch_cpy(regmatch_t *m, char *dest, const char *src); +int regmatch_len(regmatch_t *m); +int regmatch_strtol(regmatch_t *m, const char *src, char **endptr, int base); +bool regmatch_empty(regmatch_t *m); + +/* From "scanflags.h" */ +typedef unsigned int scanflags_t; +extern scanflags_t *_sf_stk; +extern size_t _sf_top_ix, _sf_max; /**< stack of scanner flags. */ +#define _SF_CASE_INS 0x0001 +#define _SF_DOT_ALL 0x0002 +#define _SF_SKIP_WS 0x0004 +#define sf_top() (_sf_stk[_sf_top_ix]) +#define sf_case_ins() (sf_top() & _SF_CASE_INS) +#define sf_dot_all() (sf_top() & _SF_DOT_ALL) +#define sf_skip_ws() (sf_top() & _SF_SKIP_WS) +#define sf_set_case_ins(X) \ + ((X) ? (sf_top() |= _SF_CASE_INS) : (sf_top() &= ~_SF_CASE_INS)) +#define sf_set_dot_all(X) \ + ((X) ? (sf_top() |= _SF_DOT_ALL) : (sf_top() &= ~_SF_DOT_ALL)) +#define sf_set_skip_ws(X) \ + ((X) ? (sf_top() |= _SF_SKIP_WS) : (sf_top() &= ~_SF_SKIP_WS)) +extern void sf_init(void); +extern void sf_push(void); +extern void sf_pop(void); + +#endif /* not defined FLEXDEF_H */ diff --git a/third_party/lex/flexint.h b/third_party/lex/flexint.h new file mode 100644 index 00000000..91f3bbba --- /dev/null +++ b/third_party/lex/flexint.h @@ -0,0 +1,67 @@ +/* clang-format off */ +/* $OpenBSD: flexint.h,v 1.1 2015/11/19 19:43:40 tedu Exp $ */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include "libc/limits.h" + +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ diff --git a/third_party/lex/gen.c b/third_party/lex/gen.c new file mode 100644 index 00000000..0a9e9262 --- /dev/null +++ b/third_party/lex/gen.c @@ -0,0 +1,2145 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 sw=8 fenc=utf-8 :vi│ +└─────────────────────────────────────────────────────────────────────────────*/ + +/* clang-format off */ +/* $OpenBSD: gen.c,v 1.15 2015/11/19 23:28:03 tedu Exp $ */ + +/* gen - actual generation (writing) of flex scanners */ + +/* Copyright (c) 1990 The Regents of the University of California. */ +/* All rights reserved. */ + +/* This code is derived from software contributed to Berkeley by */ +/* Vern Paxson. */ + +/* The United States Government has rights in this work pursuant */ +/* to contract no. DE-AC03-76SF00098 between the United States */ +/* Department of Energy and the University of California. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + +#include "flexdef.h" +#include "libc/mem/mem.h" +#include "libc/fmt/fmt.h" +#include "libc/fmt/fmt.h" +#include "libc/str/str.h" +#include "tables.h" + + +/* declare functions that have forward references */ + +/* void gen_next_state PROTO((int)); */ +void genecs PROTO((void)); +/* void indent_put2s PROTO((const char *, const char *)); */ +/* void indent_puts PROTO((const char *)); */ + + +static int indent_level = 0; /* each level is 8 spaces */ + +#define indent_up() (++indent_level) +#define indent_down() (--indent_level) +#define set_indent(indent_val) indent_level = indent_val + +/* Almost everything is done in terms of arrays starting at 1, so provide + * a null entry for the zero element of all C arrays. (The exception + * to this is that the fast table representation generally uses the + * 0 elements of its arrays, too.) + */ + +static const char * +get_int16_decl(void) +{ + return (gentables) + ? "static yyconst flex_int16_t %s[%d] =\n { 0,\n" + : "static yyconst flex_int16_t * %s = 0;\n"; +} + + +static const char * +get_int32_decl(void) +{ + return (gentables) + ? "static yyconst flex_int32_t %s[%d] =\n { 0,\n" + : "static yyconst flex_int32_t * %s = 0;\n"; +} + +static const char * +get_state_decl(void) +{ + return (gentables) + ? "static yyconst yy_state_type %s[%d] =\n { 0,\n" + : "static yyconst yy_state_type * %s = 0;\n"; +} + +/* Indent to the current level. */ + +void +do_indent() +{ + int i = indent_level * 8; + + while (i >= 8) { + outc('\t'); + i -= 8; + } + + while (i > 0) { + outc(' '); + --i; + } +} + + +/** Make the table for possible eol matches. + * @return the newly allocated rule_can_match_eol table + */ +static struct yytbl_data * +mkeoltbl(void) +{ + int i; + flex_int8_t *tdata = NULL; + struct yytbl_data *tbl; + + tbl = calloc(1, sizeof(struct yytbl_data)); + yytbl_data_init(tbl, YYTD_ID_RULE_CAN_MATCH_EOL); + tbl->td_flags = YYTD_DATA8; + tbl->td_lolen = num_rules + 1; + tbl->td_data = tdata = + calloc(tbl->td_lolen, sizeof(flex_int8_t)); + + for (i = 1; i <= num_rules; i++) + tdata[i] = rule_has_nl[i] ? 1 : 0; + + buf_prints(&yydmap_buf, + "\t{YYTD_ID_RULE_CAN_MATCH_EOL, (void**)&yy_rule_can_match_eol, sizeof(%s)},\n", + "flex_int32_t"); + return tbl; +} + +/* Generate the table for possible eol matches. */ +static void +geneoltbl() +{ + int i; + + outn("m4_ifdef( [[M4_YY_USE_LINENO]],[["); + outn("/* Table of booleans, true if rule could match eol. */"); + out_str_dec(get_int32_decl(), "yy_rule_can_match_eol", + num_rules + 1); + + if (gentables) { + for (i = 1; i <= num_rules; i++) { + out_dec("%d, ", rule_has_nl[i] ? 1 : 0); + /* format nicely, 20 numbers per line. */ + if ((i % 20) == 19) + out("\n "); + } + out(" };\n"); + } + outn("]])"); +} + + +/* Generate the code to keep backing-up information. */ + +void +gen_backing_up() +{ + if (reject || num_backing_up == 0) + return; + + if (fullspd) + indent_puts("if ( yy_current_state[-1].yy_nxt )"); + else + indent_puts("if ( yy_accept[yy_current_state] )"); + + indent_up(); + indent_puts("{"); + indent_puts("YY_G(yy_last_accepting_state) = yy_current_state;"); + indent_puts("YY_G(yy_last_accepting_cpos) = yy_cp;"); + indent_puts("}"); + indent_down(); +} + + +/* Generate the code to perform the backing up. */ + +void +gen_bu_action() +{ + if (reject || num_backing_up == 0) + return; + + set_indent(3); + + indent_puts("case 0: /* must back up */"); + indent_puts("/* undo the effects of YY_DO_BEFORE_ACTION */"); + indent_puts("*yy_cp = YY_G(yy_hold_char);"); + + if (fullspd || fulltbl) + indent_puts("yy_cp = YY_G(yy_last_accepting_cpos) + 1;"); + else + /* + * Backing-up info for compressed tables is taken \after/ + * yy_cp has been incremented for the next state. + */ + indent_puts("yy_cp = YY_G(yy_last_accepting_cpos);"); + + indent_puts("yy_current_state = YY_G(yy_last_accepting_state);"); + indent_puts("goto yy_find_action;"); + outc('\n'); + + set_indent(0); +} + +/** mkctbl - make full speed compressed transition table + * This is an array of structs; each struct a pair of integers. + * You should call mkssltbl() immediately after this. + * Then, I think, mkecstbl(). Arrrg. + * @return the newly allocated trans table + */ + +static struct yytbl_data * +mkctbl(void) +{ + int i; + struct yytbl_data *tbl = NULL; + flex_int32_t *tdata = NULL, curr = 0; + int end_of_buffer_action = num_rules + 1; + + buf_prints(&yydmap_buf, + "\t{YYTD_ID_TRANSITION, (void**)&yy_transition, sizeof(%s)},\n", + ((tblend + numecs + 1) >= INT16_MAX + || long_align) ? "flex_int32_t" : "flex_int16_t"); + + tbl = calloc(1, sizeof(struct yytbl_data)); + yytbl_data_init(tbl, YYTD_ID_TRANSITION); + tbl->td_flags = YYTD_DATA32 | YYTD_STRUCT; + tbl->td_hilen = 0; + tbl->td_lolen = tblend + numecs + 1; /* number of structs */ + + tbl->td_data = tdata = + calloc(tbl->td_lolen * 2, sizeof(flex_int32_t)); + + /* + * We want the transition to be represented as the offset to the next + * state, not the actual state number, which is what it currently is. + * The offset is base[nxt[i]] - (base of current state)]. That's + * just the difference between the starting points of the two + * involved states (to - from). + * + * First, though, we need to find some way to put in our end-of-buffer + * flags and states. We do this by making a state with absolutely no + * transitions. We put it at the end of the table. + */ + + /* + * We need to have room in nxt/chk for two more slots: One for the + * action and one for the end-of-buffer transition. We now *assume* + * that we're guaranteed the only character we'll try to index this + * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure + * there's room for jam entries for other characters. + */ + + while (tblend + 2 >= current_max_xpairs) + expand_nxt_chk(); + + while (lastdfa + 1 >= current_max_dfas) + increase_max_dfas(); + + base[lastdfa + 1] = tblend + 2; + nxt[tblend + 1] = end_of_buffer_action; + chk[tblend + 1] = numecs + 1; + chk[tblend + 2] = 1; /* anything but EOB */ + + /* So that "make test" won't show arb. differences. */ + nxt[tblend + 2] = 0; + + /* + * Make sure every state has an end-of-buffer transition and an + * action #. + */ + for (i = 0; i <= lastdfa; ++i) { + int anum = dfaacc[i].dfaacc_state; + int offset = base[i]; + + chk[offset] = EOB_POSITION; + chk[offset - 1] = ACTION_POSITION; + nxt[offset - 1] = anum; /* action number */ + } + + for (i = 0; i <= tblend; ++i) { + if (chk[i] == EOB_POSITION) { + tdata[curr++] = 0; + tdata[curr++] = base[lastdfa + 1] - i; + } else if (chk[i] == ACTION_POSITION) { + tdata[curr++] = 0; + tdata[curr++] = nxt[i]; + } else if (chk[i] > numecs || chk[i] == 0) { + tdata[curr++] = 0; + tdata[curr++] = 0; + } else { /* verify, transition */ + + tdata[curr++] = chk[i]; + tdata[curr++] = base[nxt[i]] - (i - chk[i]); + } + } + + + /* Here's the final, end-of-buffer state. */ + tdata[curr++] = chk[tblend + 1]; + tdata[curr++] = nxt[tblend + 1]; + + tdata[curr++] = chk[tblend + 2]; + tdata[curr++] = nxt[tblend + 2]; + + return tbl; +} + + +/** Make start_state_list table. + * @return the newly allocated start_state_list table + */ +static struct yytbl_data * +mkssltbl(void) +{ + struct yytbl_data *tbl = NULL; + flex_int32_t *tdata = NULL; + flex_int32_t i; + + tbl = calloc(1, sizeof(struct yytbl_data)); + yytbl_data_init(tbl, YYTD_ID_START_STATE_LIST); + tbl->td_flags = YYTD_DATA32 | YYTD_PTRANS; + tbl->td_hilen = 0; + tbl->td_lolen = lastsc * 2 + 1; + + tbl->td_data = tdata = + calloc(tbl->td_lolen, sizeof(flex_int32_t)); + + for (i = 0; i <= lastsc * 2; ++i) + tdata[i] = base[i]; + + buf_prints(&yydmap_buf, + "\t{YYTD_ID_START_STATE_LIST, (void**)&yy_start_state_list, sizeof(%s)},\n", + "struct yy_trans_info*"); + + return tbl; +} + + + +/* genctbl - generates full speed compressed transition table */ + +void +genctbl() +{ + int i; + int end_of_buffer_action = num_rules + 1; + + /* Table of verify for transition and offset to next state. */ + if (gentables) + out_dec("static yyconst struct yy_trans_info yy_transition[%d] =\n {\n", tblend + numecs + 1); + else + outn("static yyconst struct yy_trans_info *yy_transition = 0;"); + + /* + * We want the transition to be represented as the offset to the next + * state, not the actual state number, which is what it currently is. + * The offset is base[nxt[i]] - (base of current state)]. That's + * just the difference between the starting points of the two + * involved states (to - from). + * + * First, though, we need to find some way to put in our end-of-buffer + * flags and states. We do this by making a state with absolutely no + * transitions. We put it at the end of the table. + */ + + /* + * We need to have room in nxt/chk for two more slots: One for the + * action and one for the end-of-buffer transition. We now *assume* + * that we're guaranteed the only character we'll try to index this + * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure + * there's room for jam entries for other characters. + */ + + while (tblend + 2 >= current_max_xpairs) + expand_nxt_chk(); + + while (lastdfa + 1 >= current_max_dfas) + increase_max_dfas(); + + base[lastdfa + 1] = tblend + 2; + nxt[tblend + 1] = end_of_buffer_action; + chk[tblend + 1] = numecs + 1; + chk[tblend + 2] = 1; /* anything but EOB */ + + /* So that "make test" won't show arb. differences. */ + nxt[tblend + 2] = 0; + + /* + * Make sure every state has an end-of-buffer transition and an + * action #. + */ + for (i = 0; i <= lastdfa; ++i) { + int anum = dfaacc[i].dfaacc_state; + int offset = base[i]; + + chk[offset] = EOB_POSITION; + chk[offset - 1] = ACTION_POSITION; + nxt[offset - 1] = anum; /* action number */ + } + + for (i = 0; i <= tblend; ++i) { + if (chk[i] == EOB_POSITION) + transition_struct_out(0, base[lastdfa + 1] - i); + + else if (chk[i] == ACTION_POSITION) + transition_struct_out(0, nxt[i]); + + else if (chk[i] > numecs || chk[i] == 0) + transition_struct_out(0, 0); /* unused slot */ + + else /* verify, transition */ + transition_struct_out(chk[i], + base[nxt[i]] - (i - + chk[i])); + } + + + /* Here's the final, end-of-buffer state. */ + transition_struct_out(chk[tblend + 1], nxt[tblend + 1]); + transition_struct_out(chk[tblend + 2], nxt[tblend + 2]); + + if (gentables) + outn(" };\n"); + + /* Table of pointers to start states. */ + if (gentables) + out_dec("static yyconst struct yy_trans_info *yy_start_state_list[%d] =\n", lastsc * 2 + 1); + else + outn("static yyconst struct yy_trans_info **yy_start_state_list =0;"); + + if (gentables) { + outn(" {"); + + for (i = 0; i <= lastsc * 2; ++i) + out_dec(" &yy_transition[%d],\n", base[i]); + + dataend(); + } + if (useecs) + genecs(); +} + + +/* mkecstbl - Make equivalence-class tables. */ + +struct yytbl_data * +mkecstbl(void) +{ + int i; + struct yytbl_data *tbl = NULL; + flex_int32_t *tdata = NULL; + + tbl = calloc(1, sizeof(struct yytbl_data)); + yytbl_data_init(tbl, YYTD_ID_EC); + tbl->td_flags |= YYTD_DATA32; + tbl->td_hilen = 0; + tbl->td_lolen = csize; + + tbl->td_data = tdata = + calloc(tbl->td_lolen, sizeof(flex_int32_t)); + + for (i = 1; i < csize; ++i) { + ecgroup[i] = ABS(ecgroup[i]); + tdata[i] = ecgroup[i]; + } + + buf_prints(&yydmap_buf, + "\t{YYTD_ID_EC, (void**)&yy_ec, sizeof(%s)},\n", + "flex_int32_t"); + + return tbl; +} + +/* Generate equivalence-class tables. */ + +void +genecs() +{ + int i, j; + int numrows; + + out_str_dec(get_int32_decl(), "yy_ec", csize); + + for (i = 1; i < csize; ++i) { + ecgroup[i] = ABS(ecgroup[i]); + mkdata(ecgroup[i]); + } + + dataend(); + + if (trace) { + fputs(_("\n\nEquivalence Classes:\n\n"), stderr); + + numrows = csize / 8; + + for (j = 0; j < numrows; ++j) { + for (i = j; i < csize; i = i + numrows) { + fprintf(stderr, "%4s = %-2d", + readable_form(i), ecgroup[i]); + + putc(' ', stderr); + } + + putc('\n', stderr); + } + } +} + + +/* Generate the code to find the action number. */ + +void +gen_find_action() +{ + if (fullspd) + indent_puts("yy_act = yy_current_state[-1].yy_nxt;"); + + else if (fulltbl) + indent_puts("yy_act = yy_accept[yy_current_state];"); + + else if (reject) { + indent_puts("yy_current_state = *--YY_G(yy_state_ptr);"); + indent_puts("YY_G(yy_lp) = yy_accept[yy_current_state];"); + + outn("find_rule: /* we branch to this label when backing up */"); + + indent_puts + ("for ( ; ; ) /* until we find what rule we matched */"); + + indent_up(); + + indent_puts("{"); + + indent_puts + ("if ( YY_G(yy_lp) && YY_G(yy_lp) < yy_accept[yy_current_state + 1] )"); + indent_up(); + indent_puts("{"); + indent_puts("yy_act = yy_acclist[YY_G(yy_lp)];"); + + if (variable_trailing_context_rules) { + indent_puts + ("if ( yy_act & YY_TRAILING_HEAD_MASK ||"); + indent_puts(" YY_G(yy_looking_for_trail_begin) )"); + indent_up(); + indent_puts("{"); + + indent_puts + ("if ( yy_act == YY_G(yy_looking_for_trail_begin) )"); + indent_up(); + indent_puts("{"); + indent_puts("YY_G(yy_looking_for_trail_begin) = 0;"); + indent_puts("yy_act &= ~YY_TRAILING_HEAD_MASK;"); + indent_puts("break;"); + indent_puts("}"); + indent_down(); + + indent_puts("}"); + indent_down(); + + indent_puts + ("else if ( yy_act & YY_TRAILING_MASK )"); + indent_up(); + indent_puts("{"); + indent_puts + ("YY_G(yy_looking_for_trail_begin) = yy_act & ~YY_TRAILING_MASK;"); + indent_puts + ("YY_G(yy_looking_for_trail_begin) |= YY_TRAILING_HEAD_MASK;"); + + if (real_reject) { + /* + * Remember matched text in case we back up + * due to REJECT. + */ + indent_puts + ("YY_G(yy_full_match) = yy_cp;"); + indent_puts + ("YY_G(yy_full_state) = YY_G(yy_state_ptr);"); + indent_puts("YY_G(yy_full_lp) = YY_G(yy_lp);"); + } + indent_puts("}"); + indent_down(); + + indent_puts("else"); + indent_up(); + indent_puts("{"); + indent_puts("YY_G(yy_full_match) = yy_cp;"); + indent_puts + ("YY_G(yy_full_state) = YY_G(yy_state_ptr);"); + indent_puts("YY_G(yy_full_lp) = YY_G(yy_lp);"); + indent_puts("break;"); + indent_puts("}"); + indent_down(); + + indent_puts("++YY_G(yy_lp);"); + indent_puts("goto find_rule;"); + } else { + /* + * Remember matched text in case we back up due to + * trailing context plus REJECT. + */ + indent_up(); + indent_puts("{"); + indent_puts("YY_G(yy_full_match) = yy_cp;"); + indent_puts("break;"); + indent_puts("}"); + indent_down(); + } + + indent_puts("}"); + indent_down(); + + indent_puts("--yy_cp;"); + + /* + * We could consolidate the following two lines with those at + * the beginning, but at the cost of complaints that we're + * branching inside a loop. + */ + indent_puts("yy_current_state = *--YY_G(yy_state_ptr);"); + indent_puts("YY_G(yy_lp) = yy_accept[yy_current_state];"); + + indent_puts("}"); + + indent_down(); + } else { /* compressed */ + indent_puts("yy_act = yy_accept[yy_current_state];"); + + if (interactive && !reject) { + /* + * Do the guaranteed-needed backing up to figure out + * the match. + */ + indent_puts("if ( yy_act == 0 )"); + indent_up(); + indent_puts("{ /* have to back up */"); + indent_puts + ("yy_cp = YY_G(yy_last_accepting_cpos);"); + indent_puts + ("yy_current_state = YY_G(yy_last_accepting_state);"); + indent_puts + ("yy_act = yy_accept[yy_current_state];"); + indent_puts("}"); + indent_down(); + } + } +} + +/* mkftbl - make the full table and return the struct . + * you should call mkecstbl() after this. + */ + +struct yytbl_data * +mkftbl(void) +{ + int i; + int end_of_buffer_action = num_rules + 1; + struct yytbl_data *tbl; + flex_int32_t *tdata = NULL; + + tbl = calloc(1, sizeof(struct yytbl_data)); + yytbl_data_init(tbl, YYTD_ID_ACCEPT); + tbl->td_flags |= YYTD_DATA32; + tbl->td_hilen = 0; /* it's a one-dimensional array */ + tbl->td_lolen = lastdfa + 1; + + tbl->td_data = tdata = + calloc(tbl->td_lolen, sizeof(flex_int32_t)); + + dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; + + for (i = 1; i <= lastdfa; ++i) { + int anum = dfaacc[i].dfaacc_state; + + tdata[i] = anum; + + if (trace && anum) + fprintf(stderr, _("state # %d accepts: [%d]\n"), + i, anum); + } + + buf_prints(&yydmap_buf, + "\t{YYTD_ID_ACCEPT, (void**)&yy_accept, sizeof(%s)},\n", + long_align ? "flex_int32_t" : "flex_int16_t"); + return tbl; +} + + +/* genftbl - generate full transition table */ + +void +genftbl() +{ + int i; + int end_of_buffer_action = num_rules + 1; + + out_str_dec(long_align ? get_int32_decl() : get_int16_decl(), + "yy_accept", lastdfa + 1); + + dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; + + for (i = 1; i <= lastdfa; ++i) { + int anum = dfaacc[i].dfaacc_state; + + mkdata(anum); + + if (trace && anum) + fprintf(stderr, _("state # %d accepts: [%d]\n"), + i, anum); + } + + dataend(); + + if (useecs) + genecs(); + + /* + * Don't have to dump the actual full table entries - they were + * created on-the-fly. + */ +} + + +/* Generate the code to find the next compressed-table state. */ + +void +gen_next_compressed_state(char_map) + char *char_map; +{ + indent_put2s("YY_CHAR yy_c = %s;", char_map); + + /* + * Save the backing-up info \before/ computing the next state because + * we always compute one more state than needed - we always proceed + * until we reach a jam state + */ + gen_backing_up(); + + indent_puts + ("while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )"); + indent_up(); + indent_puts("{"); + indent_puts("yy_current_state = (int) yy_def[yy_current_state];"); + + if (usemecs) { + /* + * We've arrange it so that templates are never chained to + * one another. This means we can afford to make a very + * simple test to see if we need to convert to yy_c's + * meta-equivalence class without worrying about erroneously + * looking up the meta-equivalence class twice + */ + do_indent(); + + /* lastdfa + 2 is the beginning of the templates */ + out_dec("if ( yy_current_state >= %d )\n", lastdfa + 2); + + indent_up(); + indent_puts("yy_c = yy_meta[(unsigned int) yy_c];"); + indent_down(); + } + indent_puts("}"); + indent_down(); + + indent_puts + ("yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];"); +} + + +/* Generate the code to find the next match. */ + +void +gen_next_match() +{ + /* + * NOTE - changes in here should be reflected in gen_next_state() and + * gen_NUL_trans(). + */ + char *char_map = useecs ? + "yy_ec[YY_SC_TO_UI(*yy_cp)] " : "YY_SC_TO_UI(*yy_cp)"; + + char *char_map_2 = useecs ? + "yy_ec[YY_SC_TO_UI(*++yy_cp)] " : "YY_SC_TO_UI(*++yy_cp)"; + + if (fulltbl) { + if (gentables) + indent_put2s + ("while ( (yy_current_state = yy_nxt[yy_current_state][ %s ]) > 0 )", + char_map); + else + indent_put2s + ("while ( (yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %s ]) > 0 )", + char_map); + + indent_up(); + + if (num_backing_up > 0) { + indent_puts("{"); + gen_backing_up(); + outc('\n'); + } + indent_puts("++yy_cp;"); + + if (num_backing_up > 0) + indent_puts("}"); + + indent_down(); + + outc('\n'); + indent_puts("yy_current_state = -yy_current_state;"); + } else if (fullspd) { + indent_puts("{"); + indent_puts + ("yyconst struct yy_trans_info *yy_trans_info;\n"); + indent_puts("YY_CHAR yy_c;\n"); + indent_put2s("for ( yy_c = %s;", char_map); + indent_puts + (" (yy_trans_info = &yy_current_state[(unsigned int) yy_c])->"); + indent_puts("yy_verify == yy_c;"); + indent_put2s(" yy_c = %s )", char_map_2); + + indent_up(); + + if (num_backing_up > 0) + indent_puts("{"); + + indent_puts("yy_current_state += yy_trans_info->yy_nxt;"); + + if (num_backing_up > 0) { + outc('\n'); + gen_backing_up(); + indent_puts("}"); + } + indent_down(); + indent_puts("}"); + } else { /* compressed */ + indent_puts("do"); + + indent_up(); + indent_puts("{"); + + gen_next_state(false); + + indent_puts("++yy_cp;"); + + + indent_puts("}"); + indent_down(); + + do_indent(); + + if (interactive) + out_dec("while ( yy_base[yy_current_state] != %d );\n", jambase); + else + out_dec("while ( yy_current_state != %d );\n", + jamstate); + + if (!reject && !interactive) { + /* + * Do the guaranteed-needed backing up to figure out + * the match. + */ + indent_puts + ("yy_cp = YY_G(yy_last_accepting_cpos);"); + indent_puts + ("yy_current_state = YY_G(yy_last_accepting_state);"); + } + } +} + + +/* Generate the code to find the next state. */ + +void +gen_next_state(worry_about_NULs) + int worry_about_NULs; +{ /* NOTE - changes in here should be reflected + * in gen_next_match() */ + char char_map[256]; + + if (worry_about_NULs && !nultrans) { + if (useecs) + snprintf(char_map, sizeof(char_map), + "(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : %d)", + NUL_ec); + else + snprintf(char_map, sizeof(char_map), + "(*yy_cp ? YY_SC_TO_UI(*yy_cp) : %d)", + NUL_ec); + } else + strlcpy(char_map, useecs ? + "yy_ec[YY_SC_TO_UI(*yy_cp)] " : "YY_SC_TO_UI(*yy_cp)", + sizeof char_map); + + if (worry_about_NULs && nultrans) { + if (!fulltbl && !fullspd) + /* Compressed tables back up *before* they match. */ + gen_backing_up(); + + indent_puts("if ( *yy_cp )"); + indent_up(); + indent_puts("{"); + } + if (fulltbl) { + if (gentables) + indent_put2s + ("yy_current_state = yy_nxt[yy_current_state][%s];", + char_map); + else + indent_put2s + ("yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %s];", + char_map); + } else if (fullspd) + indent_put2s + ("yy_current_state += yy_current_state[%s].yy_nxt;", + char_map); + + else + gen_next_compressed_state(char_map); + + if (worry_about_NULs && nultrans) { + + indent_puts("}"); + indent_down(); + indent_puts("else"); + indent_up(); + indent_puts + ("yy_current_state = yy_NUL_trans[yy_current_state];"); + indent_down(); + } + if (fullspd || fulltbl) + gen_backing_up(); + + if (reject) + indent_puts("*YY_G(yy_state_ptr)++ = yy_current_state;"); +} + + +/* Generate the code to make a NUL transition. */ + +void +gen_NUL_trans() +{ /* NOTE - changes in here should be reflected + * in gen_next_match() */ + /* + * Only generate a definition for "yy_cp" if we'll generate code that + * uses it. Otherwise lint and the like complain. + */ + int need_backing_up = (num_backing_up > 0 && !reject); + + if (need_backing_up && (!nultrans || fullspd || fulltbl)) + /* + * We're going to need yy_cp lying around for the call below + * to gen_backing_up(). + */ + indent_puts("char *yy_cp = YY_G(yy_c_buf_p);"); + + outc('\n'); + + if (nultrans) { + indent_puts + ("yy_current_state = yy_NUL_trans[yy_current_state];"); + indent_puts("yy_is_jam = (yy_current_state == 0);"); + } else if (fulltbl) { + do_indent(); + if (gentables) + out_dec("yy_current_state = yy_nxt[yy_current_state][%d];\n", NUL_ec); + else + out_dec("yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %d];\n", NUL_ec); + indent_puts("yy_is_jam = (yy_current_state <= 0);"); + } else if (fullspd) { + do_indent(); + out_dec("int yy_c = %d;\n", NUL_ec); + + indent_puts + ("yyconst struct yy_trans_info *yy_trans_info;\n"); + indent_puts + ("yy_trans_info = &yy_current_state[(unsigned int) yy_c];"); + indent_puts("yy_current_state += yy_trans_info->yy_nxt;"); + + indent_puts + ("yy_is_jam = (yy_trans_info->yy_verify != yy_c);"); + } else { + char NUL_ec_str[20]; + + snprintf(NUL_ec_str, sizeof(NUL_ec_str), "%d", NUL_ec); + gen_next_compressed_state(NUL_ec_str); + + do_indent(); + out_dec("yy_is_jam = (yy_current_state == %d);\n", + jamstate); + + if (reject) { + /* + * Only stack this state if it's a transition we + * actually make. If we stack it on a jam, then the + * state stack and yy_c_buf_p get out of sync. + */ + indent_puts("if ( ! yy_is_jam )"); + indent_up(); + indent_puts + ("*YY_G(yy_state_ptr)++ = yy_current_state;"); + indent_down(); + } + } + + /* + * If we've entered an accepting state, back up; note that compressed + * tables have *already* done such backing up, so we needn't bother + * with it again. + */ + if (need_backing_up && (fullspd || fulltbl)) { + outc('\n'); + indent_puts("if ( ! yy_is_jam )"); + indent_up(); + indent_puts("{"); + gen_backing_up(); + indent_puts("}"); + indent_down(); + } +} + + +/* Generate the code to find the start state. */ + +void +gen_start_state() +{ + if (fullspd) { + if (bol_needed) { + indent_puts + ("yy_current_state = yy_start_state_list[YY_G(yy_start) + YY_AT_BOL()];"); + } else + indent_puts + ("yy_current_state = yy_start_state_list[YY_G(yy_start)];"); + } else { + indent_puts("yy_current_state = YY_G(yy_start);"); + + if (bol_needed) + indent_puts("yy_current_state += YY_AT_BOL();"); + + if (reject) { + /* Set up for storing up states. */ + outn("m4_ifdef( [[M4_YY_USES_REJECT]],\n[["); + indent_puts + ("YY_G(yy_state_ptr) = YY_G(yy_state_buf);"); + indent_puts + ("*YY_G(yy_state_ptr)++ = yy_current_state;"); + outn("]])"); + } + } +} + + +/* gentabs - generate data statements for the transition tables */ + +void +gentabs() +{ + int i, j, k, *accset, nacc, *acc_array, total_states; + int end_of_buffer_action = num_rules + 1; + struct yytbl_data *yyacc_tbl = 0, *yymeta_tbl = 0, *yybase_tbl = 0, *yydef_tbl = 0, + *yynxt_tbl = 0, *yychk_tbl = 0, *yyacclist_tbl = 0; + flex_int32_t *yyacc_data = 0, *yybase_data = 0, *yydef_data = 0, *yynxt_data = 0, + *yychk_data = 0, *yyacclist_data = 0; + flex_int32_t yybase_curr = 0, yyacclist_curr = 0, yyacc_curr = 0; + + acc_array = allocate_integer_array(current_max_dfas); + nummt = 0; + + /* + * The compressed table format jams by entering the "jam state", + * losing information about the previous state in the process. In + * order to recover the previous state, we effectively need to keep + * backing-up information. + */ + ++num_backing_up; + + if (reject) { + /* + * Write out accepting list and pointer list. + * + * First we generate the "yy_acclist" array. In the process, we + * compute the indices that will go into the "yy_accept" + * array, and save the indices in the dfaacc array. + */ + int EOB_accepting_list[2]; + + /* Set up accepting structures for the End Of Buffer state. */ + EOB_accepting_list[0] = 0; + EOB_accepting_list[1] = end_of_buffer_action; + accsiz[end_of_buffer_state] = 1; + dfaacc[end_of_buffer_state].dfaacc_set = + EOB_accepting_list; + + out_str_dec(long_align ? get_int32_decl() : + get_int16_decl(), "yy_acclist", MAX(numas, + 1) + 1); + + buf_prints(&yydmap_buf, + "\t{YYTD_ID_ACCLIST, (void**)&yy_acclist, sizeof(%s)},\n", + long_align ? "flex_int32_t" : "flex_int16_t"); + + yyacclist_tbl = calloc(1, sizeof(struct yytbl_data)); + yytbl_data_init(yyacclist_tbl, YYTD_ID_ACCLIST); + yyacclist_tbl->td_lolen = MAX(numas, 1) + 1; + yyacclist_tbl->td_data = yyacclist_data = + calloc(yyacclist_tbl->td_lolen, sizeof(flex_int32_t)); + yyacclist_curr = 1; + + j = 1; /* index into "yy_acclist" array */ + + for (i = 1; i <= lastdfa; ++i) { + acc_array[i] = j; + + if (accsiz[i] != 0) { + accset = dfaacc[i].dfaacc_set; + nacc = accsiz[i]; + + if (trace) + fprintf(stderr, + _("state # %d accepts: "), + i); + + for (k = 1; k <= nacc; ++k) { + int accnum = accset[k]; + + ++j; + + if (variable_trailing_context_rules + && !(accnum & + YY_TRAILING_HEAD_MASK) + && accnum > 0 + && accnum <= num_rules + && rule_type[accnum] == + RULE_VARIABLE) { + /* + * Special hack to flag + * accepting number as part + * of trailing context rule. + */ + accnum |= YY_TRAILING_MASK; + } + mkdata(accnum); + yyacclist_data[yyacclist_curr++] = accnum; + + if (trace) { + fprintf(stderr, "[%d]", + accset[k]); + + if (k < nacc) + fputs(", ", + stderr); + else + putc('\n', + stderr); + } + } + } + } + + /* add accepting number for the "jam" state */ + acc_array[i] = j; + + dataend(); + if (tablesext) { + yytbl_data_compress(yyacclist_tbl); + if (yytbl_data_fwrite(&tableswr, yyacclist_tbl) < 0) + flexerror(_("Could not write yyacclist_tbl")); + yytbl_data_destroy(yyacclist_tbl); + yyacclist_tbl = NULL; + } + } else { + dfaacc[end_of_buffer_state].dfaacc_state = + end_of_buffer_action; + + for (i = 1; i <= lastdfa; ++i) + acc_array[i] = dfaacc[i].dfaacc_state; + + /* add accepting number for jam state */ + acc_array[i] = 0; + } + + /* Begin generating yy_accept */ + + /* + * Spit out "yy_accept" array. If we're doing "reject", it'll be + * pointers into the "yy_acclist" array. Otherwise it's actual + * accepting numbers. In either case, we just dump the numbers. + */ + + /* + * "lastdfa + 2" is the size of "yy_accept"; includes room for C + * arrays beginning at 0 and for "jam" state. + */ + k = lastdfa + 2; + + if (reject) + /* + * We put a "cap" on the table associating lists of accepting + * numbers with state numbers. This is needed because we + * tell where the end of an accepting list is by looking at + * where the list for the next state starts. + */ + ++k; + + out_str_dec(long_align ? get_int32_decl() : get_int16_decl(), + "yy_accept", k); + + buf_prints(&yydmap_buf, + "\t{YYTD_ID_ACCEPT, (void**)&yy_accept, sizeof(%s)},\n", + long_align ? "flex_int32_t" : "flex_int16_t"); + + yyacc_tbl = calloc(1, sizeof(struct yytbl_data)); + yytbl_data_init(yyacc_tbl, YYTD_ID_ACCEPT); + yyacc_tbl->td_lolen = k; + yyacc_tbl->td_data = yyacc_data = + calloc(yyacc_tbl->td_lolen, sizeof(flex_int32_t)); + yyacc_curr = 1; + + for (i = 1; i <= lastdfa; ++i) { + mkdata(acc_array[i]); + yyacc_data[yyacc_curr++] = acc_array[i]; + + if (!reject && trace && acc_array[i]) + fprintf(stderr, _("state # %d accepts: [%d]\n"), + i, acc_array[i]); + } + + /* Add entry for "jam" state. */ + mkdata(acc_array[i]); + yyacc_data[yyacc_curr++] = acc_array[i]; + + if (reject) { + /* Add "cap" for the list. */ + mkdata(acc_array[i]); + yyacc_data[yyacc_curr++] = acc_array[i]; + } + dataend(); + if (tablesext) { + yytbl_data_compress(yyacc_tbl); + if (yytbl_data_fwrite(&tableswr, yyacc_tbl) < 0) + flexerror(_("Could not write yyacc_tbl")); + yytbl_data_destroy(yyacc_tbl); + yyacc_tbl = NULL; + } + /* End generating yy_accept */ + + if (useecs) { + + genecs(); + if (tablesext) { + struct yytbl_data *tbl; + + tbl = mkecstbl(); + yytbl_data_compress(tbl); + if (yytbl_data_fwrite(&tableswr, tbl) < 0) + flexerror(_("Could not write ecstbl")); + yytbl_data_destroy(tbl); + tbl = 0; + } + } + if (usemecs) { + /* Begin generating yy_meta */ + /* + * Write out meta-equivalence classes (used to index + * templates with). + */ + flex_int32_t *yymecs_data = NULL; + yymeta_tbl = calloc(1, sizeof(struct yytbl_data)); + yytbl_data_init(yymeta_tbl, YYTD_ID_META); + yymeta_tbl->td_lolen = numecs + 1; + yymeta_tbl->td_data = yymecs_data = + calloc(yymeta_tbl->td_lolen, + sizeof(flex_int32_t)); + + if (trace) + fputs(_("\n\nMeta-Equivalence Classes:\n"), + stderr); + + out_str_dec(get_int32_decl(), "yy_meta", numecs + 1); + buf_prints(&yydmap_buf, + "\t{YYTD_ID_META, (void**)&yy_meta, sizeof(%s)},\n", + "flex_int32_t"); + + for (i = 1; i <= numecs; ++i) { + if (trace) + fprintf(stderr, "%d = %d\n", + i, ABS(tecbck[i])); + + mkdata(ABS(tecbck[i])); + yymecs_data[i] = ABS(tecbck[i]); + } + + dataend(); + if (tablesext) { + yytbl_data_compress(yymeta_tbl); + if (yytbl_data_fwrite(&tableswr, yymeta_tbl) < 0) + flexerror(_ + ("Could not write yymeta_tbl")); + yytbl_data_destroy(yymeta_tbl); + yymeta_tbl = NULL; + } + /* End generating yy_meta */ + } + total_states = lastdfa + numtemps; + + /* Begin generating yy_base */ + out_str_dec((tblend >= INT16_MAX || long_align) ? + get_int32_decl() : get_int16_decl(), + "yy_base", total_states + 1); + + buf_prints(&yydmap_buf, + "\t{YYTD_ID_BASE, (void**)&yy_base, sizeof(%s)},\n", + (tblend >= INT16_MAX + || long_align) ? "flex_int32_t" : "flex_int16_t"); + yybase_tbl = calloc(1, sizeof(struct yytbl_data)); + yytbl_data_init(yybase_tbl, YYTD_ID_BASE); + yybase_tbl->td_lolen = total_states + 1; + yybase_tbl->td_data = yybase_data = + calloc(yybase_tbl->td_lolen, + sizeof(flex_int32_t)); + yybase_curr = 1; + + for (i = 1; i <= lastdfa; ++i) { + int d = def[i]; + + if (base[i] == JAMSTATE) + base[i] = jambase; + + if (d == JAMSTATE) + def[i] = jamstate; + + else if (d < 0) { + /* Template reference. */ + ++tmpuses; + def[i] = lastdfa - d + 1; + } + mkdata(base[i]); + yybase_data[yybase_curr++] = base[i]; + } + + /* Generate jam state's base index. */ + mkdata(base[i]); + yybase_data[yybase_curr++] = base[i]; + + for (++i /* skip jam state */ ; i <= total_states; ++i) { + mkdata(base[i]); + yybase_data[yybase_curr++] = base[i]; + def[i] = jamstate; + } + + dataend(); + if (tablesext) { + yytbl_data_compress(yybase_tbl); + if (yytbl_data_fwrite(&tableswr, yybase_tbl) < 0) + flexerror(_("Could not write yybase_tbl")); + yytbl_data_destroy(yybase_tbl); + yybase_tbl = NULL; + } + /* End generating yy_base */ + + + /* Begin generating yy_def */ + out_str_dec((total_states >= INT16_MAX || long_align) ? + get_int32_decl() : get_int16_decl(), + "yy_def", total_states + 1); + + buf_prints(&yydmap_buf, + "\t{YYTD_ID_DEF, (void**)&yy_def, sizeof(%s)},\n", + (total_states >= INT16_MAX + || long_align) ? "flex_int32_t" : "flex_int16_t"); + + yydef_tbl = calloc(1, sizeof(struct yytbl_data)); + yytbl_data_init(yydef_tbl, YYTD_ID_DEF); + yydef_tbl->td_lolen = total_states + 1; + yydef_tbl->td_data = yydef_data = + calloc(yydef_tbl->td_lolen, sizeof(flex_int32_t)); + + for (i = 1; i <= total_states; ++i) { + mkdata(def[i]); + yydef_data[i] = def[i]; + } + + dataend(); + if (tablesext) { + yytbl_data_compress(yydef_tbl); + if (yytbl_data_fwrite(&tableswr, yydef_tbl) < 0) + flexerror(_("Could not write yydef_tbl")); + yytbl_data_destroy(yydef_tbl); + yydef_tbl = NULL; + } + /* End generating yy_def */ + + + /* Begin generating yy_nxt */ + out_str_dec((total_states >= INT16_MAX || long_align) ? + get_int32_decl() : get_int16_decl(), "yy_nxt", + tblend + 1); + + buf_prints(&yydmap_buf, + "\t{YYTD_ID_NXT, (void**)&yy_nxt, sizeof(%s)},\n", + (total_states >= INT16_MAX + || long_align) ? "flex_int32_t" : "flex_int16_t"); + + yynxt_tbl = calloc(1, sizeof(struct yytbl_data)); + yytbl_data_init(yynxt_tbl, YYTD_ID_NXT); + yynxt_tbl->td_lolen = tblend + 1; + yynxt_tbl->td_data = yynxt_data = + calloc(yynxt_tbl->td_lolen, sizeof(flex_int32_t)); + + for (i = 1; i <= tblend; ++i) { + /* + * Note, the order of the following test is important. If + * chk[i] is 0, then nxt[i] is undefined. + */ + if (chk[i] == 0 || nxt[i] == 0) + nxt[i] = jamstate; /* new state is the JAM state */ + + mkdata(nxt[i]); + yynxt_data[i] = nxt[i]; + } + + dataend(); + if (tablesext) { + yytbl_data_compress(yynxt_tbl); + if (yytbl_data_fwrite(&tableswr, yynxt_tbl) < 0) + flexerror(_("Could not write yynxt_tbl")); + yytbl_data_destroy(yynxt_tbl); + yynxt_tbl = NULL; + } + /* End generating yy_nxt */ + + /* Begin generating yy_chk */ + out_str_dec((total_states >= INT16_MAX || long_align) ? + get_int32_decl() : get_int16_decl(), "yy_chk", + tblend + 1); + + buf_prints(&yydmap_buf, + "\t{YYTD_ID_CHK, (void**)&yy_chk, sizeof(%s)},\n", + (total_states >= INT16_MAX + || long_align) ? "flex_int32_t" : "flex_int16_t"); + + yychk_tbl = calloc(1, sizeof(struct yytbl_data)); + yytbl_data_init(yychk_tbl, YYTD_ID_CHK); + yychk_tbl->td_lolen = tblend + 1; + yychk_tbl->td_data = yychk_data = + calloc(yychk_tbl->td_lolen, sizeof(flex_int32_t)); + + for (i = 1; i <= tblend; ++i) { + if (chk[i] == 0) + ++nummt; + + mkdata(chk[i]); + yychk_data[i] = chk[i]; + } + + dataend(); + if (tablesext) { + yytbl_data_compress(yychk_tbl); + if (yytbl_data_fwrite(&tableswr, yychk_tbl) < 0) + flexerror(_("Could not write yychk_tbl")); + yytbl_data_destroy(yychk_tbl); + yychk_tbl = NULL; + } + /* End generating yy_chk */ + + free(acc_array); +} + + +/* Write out a formatted string (with a secondary string argument) at the + * current indentation level, adding a final newline. + */ + +void +indent_put2s(fmt, arg) + const char *fmt, *arg; +{ + do_indent(); + out_str(fmt, arg); + outn(""); +} + + +/* Write out a string at the current indentation level, adding a final + * newline. + */ + +void +indent_puts(str) + const char *str; +{ + do_indent(); + outn(str); +} + + +/* make_tables - generate transition tables and finishes generating output file + */ + +void +make_tables() +{ + int i; + int did_eof_rule = false; + struct yytbl_data *yynultrans_tbl; + + + skelout(); /* %% [2.0] - break point in skel */ + + /* + * First, take care of YY_DO_BEFORE_ACTION depending on yymore being + * used. + */ + set_indent(1); + + if (yymore_used && !yytext_is_array) { + indent_puts("YY_G(yytext_ptr) -= YY_G(yy_more_len); \\"); + indent_puts + ("yyleng = (size_t) (yy_cp - YY_G(yytext_ptr)); \\"); + } else + indent_puts("yyleng = (size_t) (yy_cp - yy_bp); \\"); + + /* Now also deal with copying yytext_ptr to yytext if needed. */ + skelout(); /* %% [3.0] - break point in skel */ + if (yytext_is_array) { + if (yymore_used) + indent_puts + ("if ( yyleng + YY_G(yy_more_offset) >= YYLMAX ) \\"); + else + indent_puts("if ( yyleng >= YYLMAX ) \\"); + + indent_up(); + indent_puts + ("YY_FATAL_ERROR( \"token too large, exceeds YYLMAX\" ); \\"); + indent_down(); + + if (yymore_used) { + indent_puts + ("yy_flex_strncpy( &yytext[YY_G(yy_more_offset)], YY_G(yytext_ptr), yyleng + 1 M4_YY_CALL_LAST_ARG); \\"); + indent_puts("yyleng += YY_G(yy_more_offset); \\"); + indent_puts + ("YY_G(yy_prev_more_offset) = YY_G(yy_more_offset); \\"); + indent_puts("YY_G(yy_more_offset) = 0; \\"); + } else { + indent_puts + ("yy_flex_strncpy( yytext, YY_G(yytext_ptr), yyleng + 1 M4_YY_CALL_LAST_ARG); \\"); + } + } + set_indent(0); + + skelout(); /* %% [4.0] - break point in skel */ + + + /* This is where we REALLY begin generating the tables. */ + + out_dec("#define YY_NUM_RULES %d\n", num_rules); + out_dec("#define YY_END_OF_BUFFER %d\n", num_rules + 1); + + if (fullspd) { + /* + * Need to define the transet type as a size large enough to + * hold the biggest offset. + */ + int total_table_size = tblend + numecs + 1; + char *trans_offset_type = + (total_table_size >= INT16_MAX || long_align) ? + "flex_int32_t" : "flex_int16_t"; + + set_indent(0); + indent_puts("struct yy_trans_info"); + indent_up(); + indent_puts("{"); + + /* + * We require that yy_verify and yy_nxt must be of the same + * size int. + */ + indent_put2s("%s yy_verify;", trans_offset_type); + + /* + * In cases where its sister yy_verify *is* a "yes, there is + * a transition", yy_nxt is the offset (in records) to the + * next state. In most cases where there is no transition, + * the value of yy_nxt is irrelevant. If yy_nxt is the -1th + * record of a state, though, then yy_nxt is the action + * number for that state. + */ + + indent_put2s("%s yy_nxt;", trans_offset_type); + indent_puts("};"); + indent_down(); + } else { + /* + * We generate a bogus 'struct yy_trans_info' data type so we + * can guarantee that it is always declared in the skel. This + * is so we can compile "sizeof(struct yy_trans_info)" in any + * scanner. + */ + indent_puts + ("/* This struct is not used in this scanner,"); + indent_puts(" but its presence is necessary. */"); + indent_puts("struct yy_trans_info"); + indent_up(); + indent_puts("{"); + indent_puts("flex_int32_t yy_verify;"); + indent_puts("flex_int32_t yy_nxt;"); + indent_puts("};"); + indent_down(); + } + + if (fullspd) { + genctbl(); + if (tablesext) { + struct yytbl_data *tbl; + + tbl = mkctbl(); + yytbl_data_compress(tbl); + if (yytbl_data_fwrite(&tableswr, tbl) < 0) + flexerror(_("Could not write ftbl")); + yytbl_data_destroy(tbl); + + tbl = mkssltbl(); + yytbl_data_compress(tbl); + if (yytbl_data_fwrite(&tableswr, tbl) < 0) + flexerror(_("Could not write ssltbl")); + yytbl_data_destroy(tbl); + tbl = 0; + + if (useecs) { + tbl = mkecstbl(); + yytbl_data_compress(tbl); + if (yytbl_data_fwrite(&tableswr, tbl) < 0) + flexerror(_ + ("Could not write ecstbl")); + yytbl_data_destroy(tbl); + tbl = 0; + } + } + } else if (fulltbl) { + genftbl(); + if (tablesext) { + struct yytbl_data *tbl; + + tbl = mkftbl(); + yytbl_data_compress(tbl); + if (yytbl_data_fwrite(&tableswr, tbl) < 0) + flexerror(_("Could not write ftbl")); + yytbl_data_destroy(tbl); + tbl = 0; + + if (useecs) { + tbl = mkecstbl(); + yytbl_data_compress(tbl); + if (yytbl_data_fwrite(&tableswr, tbl) < 0) + flexerror(_ + ("Could not write ecstbl")); + yytbl_data_destroy(tbl); + tbl = 0; + } + } + } else + gentabs(); + + if (do_yylineno) { + + geneoltbl(); + + if (tablesext) { + struct yytbl_data *tbl; + + tbl = mkeoltbl(); + yytbl_data_compress(tbl); + if (yytbl_data_fwrite(&tableswr, tbl) < 0) + flexerror(_("Could not write eoltbl")); + yytbl_data_destroy(tbl); + tbl = 0; + } + } + /* + * Definitions for backing up. We don't need them if REJECT is being + * used because then we use an alternative backin-up technique + * instead. + */ + if (num_backing_up > 0 && !reject) { + if (!C_plus_plus && !reentrant) { + indent_puts + ("static yy_state_type yy_last_accepting_state;"); + indent_puts + ("static char *yy_last_accepting_cpos;\n"); + } + } + if (nultrans) { + flex_int32_t *yynultrans_data = NULL; + + /* Begin generating yy_NUL_trans */ + out_str_dec(get_state_decl(), "yy_NUL_trans", + lastdfa + 1); + buf_prints(&yydmap_buf, + "\t{YYTD_ID_NUL_TRANS, (void**)&yy_NUL_trans, sizeof(%s)},\n", + (fullspd) ? "struct yy_trans_info*" : + "flex_int32_t"); + + yynultrans_tbl = calloc(1, sizeof(struct yytbl_data)); + yytbl_data_init(yynultrans_tbl, YYTD_ID_NUL_TRANS); + if (fullspd) + yynultrans_tbl->td_flags |= YYTD_PTRANS; + yynultrans_tbl->td_lolen = lastdfa + 1; + yynultrans_tbl->td_data = yynultrans_data = + calloc(yynultrans_tbl->td_lolen, + sizeof(flex_int32_t)); + + for (i = 1; i <= lastdfa; ++i) { + if (fullspd) { + out_dec(" &yy_transition[%d],\n", + base[i]); + yynultrans_data[i] = base[i]; + } else { + mkdata(nultrans[i]); + yynultrans_data[i] = nultrans[i]; + } + } + + dataend(); + if (tablesext) { + yytbl_data_compress(yynultrans_tbl); + if (yytbl_data_fwrite(&tableswr, yynultrans_tbl) < 0) + flexerror(_ + ("Could not write yynultrans_tbl")); + yytbl_data_destroy(yynultrans_tbl); + yynultrans_tbl = NULL; + } + /* End generating yy_NUL_trans */ + } + if (!C_plus_plus && !reentrant) { + indent_puts("extern int yy_flex_debug;"); + indent_put2s("int yy_flex_debug = %s;\n", + ddebug ? "1" : "0"); + } + if (ddebug) { /* Spit out table mapping rules to line + * numbers. */ + out_str_dec(long_align ? get_int32_decl() : + get_int16_decl(), "yy_rule_linenum", + num_rules); + for (i = 1; i < num_rules; ++i) + mkdata(rule_linenum[i]); + dataend(); + } + if (reject) { + outn("m4_ifdef( [[M4_YY_USES_REJECT]],\n[["); + /* Declare state buffer variables. */ + if (!C_plus_plus && !reentrant) { + outn("static yy_state_type *yy_state_buf=0, *yy_state_ptr=0;"); + outn("static char *yy_full_match;"); + outn("static int yy_lp;"); + } + if (variable_trailing_context_rules) { + if (!C_plus_plus && !reentrant) { + outn("static int yy_looking_for_trail_begin = 0;"); + outn("static int yy_full_lp;"); + outn("static int *yy_full_state;"); + } + out_hex("#define YY_TRAILING_MASK 0x%x\n", + (unsigned int) YY_TRAILING_MASK); + out_hex("#define YY_TRAILING_HEAD_MASK 0x%x\n", + (unsigned int) YY_TRAILING_HEAD_MASK); + } + outn("#define REJECT \\"); + outn("{ \\"); + outn("*yy_cp = YY_G(yy_hold_char); /* undo effects of setting up yytext */ \\"); + outn("yy_cp = YY_G(yy_full_match); /* restore poss. backed-over text */ \\"); + + if (variable_trailing_context_rules) { + outn("YY_G(yy_lp) = YY_G(yy_full_lp); /* restore orig. accepting pos. */ \\"); + outn("YY_G(yy_state_ptr) = YY_G(yy_full_state); /* restore orig. state */ \\"); + outn("yy_current_state = *YY_G(yy_state_ptr); /* restore curr. state */ \\"); + } + outn("++YY_G(yy_lp); \\"); + outn("goto find_rule; \\"); + + outn("}"); + outn("]])\n"); + } else { + outn("/* The intent behind this definition is that it'll catch"); + outn(" * any uses of REJECT which flex missed."); + outn(" */"); + outn("#define REJECT reject_used_but_not_detected"); + } + + if (yymore_used) { + if (!C_plus_plus) { + if (yytext_is_array) { + if (!reentrant) { + indent_puts("static int yy_more_offset = 0;"); + indent_puts("static int yy_prev_more_offset = 0;"); + } + } else if (!reentrant) { + indent_puts + ("static int yy_more_flag = 0;"); + indent_puts + ("static int yy_more_len = 0;"); + } + } + if (yytext_is_array) { + indent_puts + ("#define yymore() (YY_G(yy_more_offset) = yy_flex_strlen( yytext M4_YY_CALL_LAST_ARG))"); + indent_puts("#define YY_NEED_STRLEN"); + indent_puts("#define YY_MORE_ADJ 0"); + indent_puts + ("#define YY_RESTORE_YY_MORE_OFFSET \\"); + indent_up(); + indent_puts("{ \\"); + indent_puts + ("YY_G(yy_more_offset) = YY_G(yy_prev_more_offset); \\"); + indent_puts("yyleng -= YY_G(yy_more_offset); \\"); + indent_puts("}"); + indent_down(); + } else { + indent_puts + ("#define yymore() (YY_G(yy_more_flag) = 1)"); + indent_puts + ("#define YY_MORE_ADJ YY_G(yy_more_len)"); + indent_puts("#define YY_RESTORE_YY_MORE_OFFSET"); + } + } else { + indent_puts + ("#define yymore() yymore_used_but_not_detected"); + indent_puts("#define YY_MORE_ADJ 0"); + indent_puts("#define YY_RESTORE_YY_MORE_OFFSET"); + } + + if (!C_plus_plus) { + if (yytext_is_array) { + outn("#ifndef YYLMAX"); + outn("#define YYLMAX 8192"); + outn("#endif\n"); + if (!reentrant) { + outn("char yytext[YYLMAX];"); + outn("char *yytext_ptr;"); + } + } else { + if (!reentrant) + outn("char *yytext;"); + } + } + out(&action_array[defs1_offset]); + + line_directive_out(stdout, 0); + + skelout(); /* %% [5.0] - break point in skel */ + + if (!C_plus_plus) { + if (use_read) { + outn("\terrno=0; \\"); + outn("\twhile ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \\"); + outn("\t{ \\"); + outn("\t\tif( errno != EINTR) \\"); + outn("\t\t{ \\"); + outn("\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\"); + outn("\t\t\tbreak; \\"); + outn("\t\t} \\"); + outn("\t\terrno=0; \\"); + outn("\t\tclearerr(yyin); \\"); + outn("\t}\\"); + } else { + outn("\tif ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \\"); + outn("\t\t{ \\"); + outn("\t\tint c = '*'; \\"); + outn("\t\tsize_t n; \\"); + outn("\t\tfor ( n = 0; n < max_size && \\"); + outn("\t\t\t (c = getc( yyin )) != EOF && c != '\\n'; ++n ) \\"); + outn("\t\t\tbuf[n] = (char) c; \\"); + outn("\t\tif ( c == '\\n' ) \\"); + outn("\t\t\tbuf[n++] = (char) c; \\"); + outn("\t\tif ( c == EOF && ferror( yyin ) ) \\"); + outn("\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\"); + outn("\t\tresult = n; \\"); + outn("\t\t} \\"); + outn("\telse \\"); + outn("\t\t{ \\"); + outn("\t\terrno=0; \\"); + outn("\t\twhile ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \\"); + outn("\t\t\t{ \\"); + outn("\t\t\tif( errno != EINTR) \\"); + outn("\t\t\t\t{ \\"); + outn("\t\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\"); + outn("\t\t\t\tbreak; \\"); + outn("\t\t\t\t} \\"); + outn("\t\t\terrno=0; \\"); + outn("\t\t\tclearerr(yyin); \\"); + outn("\t\t\t} \\"); + outn("\t\t}\\"); + } + } + skelout(); /* %% [6.0] - break point in skel */ + + indent_puts("#define YY_RULE_SETUP \\"); + indent_up(); + if (bol_needed) { + indent_puts("if ( yyleng > 0 ) \\"); + indent_up(); + indent_puts("YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \\"); + indent_puts("\t\t(yytext[yyleng - 1] == '\\n'); \\"); + indent_down(); + } + indent_puts("YY_USER_ACTION"); + indent_down(); + + skelout(); /* %% [7.0] - break point in skel */ + + /* Copy prolog to output file. */ + out(&action_array[prolog_offset]); + + line_directive_out(stdout, 0); + + skelout(); /* %% [8.0] - break point in skel */ + + set_indent(2); + + if (yymore_used && !yytext_is_array) { + indent_puts("YY_G(yy_more_len) = 0;"); + indent_puts("if ( YY_G(yy_more_flag) )"); + indent_up(); + indent_puts("{"); + indent_puts + ("YY_G(yy_more_len) = YY_G(yy_c_buf_p) - YY_G(yytext_ptr);"); + indent_puts("YY_G(yy_more_flag) = 0;"); + indent_puts("}"); + indent_down(); + } + skelout(); /* %% [9.0] - break point in skel */ + + gen_start_state(); + + /* Note, don't use any indentation. */ + outn("yy_match:"); + gen_next_match(); + + skelout(); /* %% [10.0] - break point in skel */ + set_indent(2); + gen_find_action(); + + skelout(); /* %% [11.0] - break point in skel */ + outn("m4_ifdef( [[M4_YY_USE_LINENO]],[["); + indent_puts + ("if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )"); + indent_up(); + indent_puts("{"); + indent_puts("yy_size_t yyl;"); + do_indent(); + out_str("for ( yyl = %s; yyl < yyleng; ++yyl )\n", + yymore_used ? (yytext_is_array ? "YY_G(yy_prev_more_offset)" : + "YY_G(yy_more_len)") : "0"); + indent_up(); + indent_puts("if ( yytext[yyl] == '\\n' )"); + indent_up(); + indent_puts("M4_YY_INCR_LINENO();"); + indent_down(); + indent_down(); + indent_puts("}"); + indent_down(); + outn("]])"); + + skelout(); /* %% [12.0] - break point in skel */ + if (ddebug) { + indent_puts("if ( yy_flex_debug )"); + indent_up(); + + indent_puts("{"); + indent_puts("if ( yy_act == 0 )"); + indent_up(); + indent_puts(C_plus_plus ? + "std::cerr << \"--scanner backing up\\n\";" : + "fprintf( stderr, \"--scanner backing up\\n\" );"); + indent_down(); + + do_indent(); + out_dec("else if ( yy_act < %d )\n", num_rules); + indent_up(); + + if (C_plus_plus) { + indent_puts + ("std::cerr << \"--accepting rule at line \" << yy_rule_linenum[yy_act] <<"); + indent_puts + (" \"(\\\"\" << yytext << \"\\\")\\n\";"); + } else { + indent_puts + ("fprintf( stderr, \"--accepting rule at line %ld (\\\"%s\\\")\\n\","); + + indent_puts + (" (long)yy_rule_linenum[yy_act], yytext );"); + } + + indent_down(); + + do_indent(); + out_dec("else if ( yy_act == %d )\n", num_rules); + indent_up(); + + if (C_plus_plus) { + indent_puts + ("std::cerr << \"--accepting default rule (\\\"\" << yytext << \"\\\")\\n\";"); + } else { + indent_puts + ("fprintf( stderr, \"--accepting default rule (\\\"%s\\\")\\n\","); + indent_puts(" yytext );"); + } + + indent_down(); + + do_indent(); + out_dec("else if ( yy_act == %d )\n", num_rules + 1); + indent_up(); + + indent_puts(C_plus_plus ? + "std::cerr << \"--(end of buffer or a NUL)\\n\";" : + "fprintf( stderr, \"--(end of buffer or a NUL)\\n\" );"); + + indent_down(); + + do_indent(); + outn("else"); + indent_up(); + + if (C_plus_plus) { + indent_puts + ("std::cerr << \"--EOF (start condition \" << YY_START << \")\\n\";"); + } else { + indent_puts + ("fprintf( stderr, \"--EOF (start condition %d)\\n\", YY_START );"); + } + + indent_down(); + + indent_puts("}"); + indent_down(); + } + /* Copy actions to output file. */ + skelout(); /* %% [13.0] - break point in skel */ + indent_up(); + gen_bu_action(); + out(&action_array[action_offset]); + + line_directive_out(stdout, 0); + + /* generate cases for any missing EOF rules */ + for (i = 1; i <= lastsc; ++i) + if (!sceof[i]) { + do_indent(); + out_str("case YY_STATE_EOF(%s):\n", scname[i]); + did_eof_rule = true; + } + if (did_eof_rule) { + indent_up(); + indent_puts("yyterminate();"); + indent_down(); + } + /* Generate code for handling NUL's, if needed. */ + + /* + * First, deal with backing up and setting up yy_cp if the scanner + * finds that it should JAM on the NUL. + */ + skelout(); /* %% [14.0] - break point in skel */ + set_indent(4); + + if (fullspd || fulltbl) + indent_puts("yy_cp = YY_G(yy_c_buf_p);"); + + else { /* compressed table */ + if (!reject && !interactive) { + /* + * Do the guaranteed-needed backing up to figure out + * the match. + */ + indent_puts + ("yy_cp = YY_G(yy_last_accepting_cpos);"); + indent_puts + ("yy_current_state = YY_G(yy_last_accepting_state);"); + } else + /* + * Still need to initialize yy_cp, though + * yy_current_state was set up by + * yy_get_previous_state(). + */ + indent_puts("yy_cp = YY_G(yy_c_buf_p);"); + } + + + /* Generate code for yy_get_previous_state(). */ + set_indent(1); + skelout(); /* %% [15.0] - break point in skel */ + + gen_start_state(); + + set_indent(2); + skelout(); /* %% [16.0] - break point in skel */ + gen_next_state(true); + + set_indent(1); + skelout(); /* %% [17.0] - break point in skel */ + gen_NUL_trans(); + + skelout(); /* %% [18.0] - break point in skel */ + skelout(); /* %% [19.0] - break point in skel */ + /* Update BOL and yylineno inside of input(). */ + if (bol_needed) { + indent_puts + ("YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\\n');"); + if (do_yylineno) { + indent_puts + ("if ( YY_CURRENT_BUFFER_LVALUE->yy_at_bol )"); + indent_up(); + indent_puts("M4_YY_INCR_LINENO();"); + indent_down(); + } + } else if (do_yylineno) { + indent_puts("if ( c == '\\n' )"); + indent_up(); + indent_puts("M4_YY_INCR_LINENO();"); + indent_down(); + } + skelout(); + + /* Copy remainder of input to output. */ + + line_directive_out(stdout, 1); + + if (sectnum == 3) { + OUT_BEGIN_CODE(); + (void) flexscan(); /* copy remainder of input to output */ + OUT_END_CODE(); + } +} diff --git a/third_party/lex/lex.mk b/third_party/lex/lex.mk new file mode 100644 index 00000000..50467f6e --- /dev/null +++ b/third_party/lex/lex.mk @@ -0,0 +1,119 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ +# Description: +# lex generates state machines for tokenizing languages. + +PKGS += THIRD_PARTY_LEX + +THIRD_PARTY_LEX = \ + o/$(MODE)/third_party/lex/lex.com + +THIRD_PARTY_LEX_BINS = \ + $(THIRD_PARTY_LEX) \ + $(THIRD_PARTY_LEX).dbg + +THIRD_PARTY_LEX_OBJS = \ + o/$(MODE)/third_party/lex/buf.o \ + o/$(MODE)/third_party/lex/ccl.o \ + o/$(MODE)/third_party/lex/dfa.o \ + o/$(MODE)/third_party/lex/ecs.o \ + o/$(MODE)/third_party/lex/filter.o \ + o/$(MODE)/third_party/lex/gen.o \ + o/$(MODE)/third_party/lex/main.o \ + o/$(MODE)/third_party/lex/misc.o \ + o/$(MODE)/third_party/lex/nfa.o \ + o/$(MODE)/third_party/lex/options.o \ + o/$(MODE)/third_party/lex/parse.o \ + o/$(MODE)/third_party/lex/regex.o \ + o/$(MODE)/third_party/lex/scan.o \ + o/$(MODE)/third_party/lex/scanflags.o \ + o/$(MODE)/third_party/lex/scanopt.o \ + o/$(MODE)/third_party/lex/skel.o \ + o/$(MODE)/third_party/lex/sym.o \ + o/$(MODE)/third_party/lex/tables.o \ + o/$(MODE)/third_party/lex/tables_shared.o \ + o/$(MODE)/third_party/lex/tblcmp.o \ + o/$(MODE)/third_party/lex/yylex.o \ + o/$(MODE)/third_party/lex/buf.c.zip.o \ + o/$(MODE)/third_party/lex/ccl.c.zip.o \ + o/$(MODE)/third_party/lex/dfa.c.zip.o \ + o/$(MODE)/third_party/lex/ecs.c.zip.o \ + o/$(MODE)/third_party/lex/filter.c.zip.o \ + o/$(MODE)/third_party/lex/gen.c.zip.o \ + o/$(MODE)/third_party/lex/main.c.zip.o \ + o/$(MODE)/third_party/lex/misc.c.zip.o \ + o/$(MODE)/third_party/lex/nfa.c.zip.o \ + o/$(MODE)/third_party/lex/options.c.zip.o \ + o/$(MODE)/third_party/lex/parse.c.zip.o \ + o/$(MODE)/third_party/lex/regex.c.zip.o \ + o/$(MODE)/third_party/lex/scan.c.zip.o \ + o/$(MODE)/third_party/lex/scanflags.c.zip.o \ + o/$(MODE)/third_party/lex/scanopt.c.zip.o \ + o/$(MODE)/third_party/lex/skel.c.zip.o \ + o/$(MODE)/third_party/lex/sym.c.zip.o \ + o/$(MODE)/third_party/lex/tables.c.zip.o \ + o/$(MODE)/third_party/lex/tables_shared.c.zip.o \ + o/$(MODE)/third_party/lex/tblcmp.c.zip.o \ + o/$(MODE)/third_party/lex/yylex.c.zip.o + +THIRD_PARTY_LEX_DIRECTDEPS = \ + LIBC_ALG \ + LIBC_CALLS \ + LIBC_CALLS_HEFTY \ + LIBC_CONV \ + LIBC_FMT \ + LIBC_LOG \ + LIBC_MATH \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_STDIO \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_SYSV \ + LIBC_SYSV_CALLS \ + LIBC_UNICODE \ + LIBC_X \ + THIRD_PARTY_REGEX + +THIRD_PARTY_LEX_DEPS := \ + $(call uniq,$(foreach x,$(THIRD_PARTY_LEX_DIRECTDEPS),$($(x)))) + +$(THIRD_PARTY_LEX).pkg: \ + $(THIRD_PARTY_LEX_OBJS) \ + $(foreach x,$(THIRD_PARTY_LEX_DIRECTDEPS),$($(x)_A).pkg) + +$(THIRD_PARTY_LEX_OBJS): \ + DEFAULT_CPPFLAGS += \ + -DHAVE_CONFIG_H \ + -isystem third_party/lex + +$(THIRD_PARTY_LEX_OBJS): \ + OVERRIDE_CFLAGS += \ + $(OLD_CODE) \ + -O0 + +o/$(MODE)/third_party/lex/parse.o \ +o/$(MODE)/third_party/lex/misc.o \ +o/$(MODE)/third_party/lex/dfa.o: \ + DEFAULT_CPPFLAGS += \ + -DSTACK_FRAME_UNLIMITED + +o/$(MODE)/third_party/lex/scan.o: \ + DEFAULT_CFLAGS += \ + -w + +$(THIRD_PARTY_LEX).dbg: \ + $(THIRD_PARTY_LEX_DEPS) \ + $(THIRD_PARTY_LEX_OBJS) \ + $(THIRD_PARTY_LEX).pkg \ + $(CRT) \ + $(APE) + @$(APELINK) + +$(THIRD_PARTY_LEX_OBJS): \ + $(BUILD_FILES) \ + third_party/lex/lex.mk + +.PHONY: o/$(MODE)/third_party/lex +o/$(MODE)/third_party/lex: $(THIRD_PARTY_LEX_BINS) diff --git a/third_party/lex/lex.ms b/third_party/lex/lex.ms new file mode 100644 index 00000000..bfa6baf6 --- /dev/null +++ b/third_party/lex/lex.ms @@ -0,0 +1,2208 @@ +.\" $OpenBSD: lex.ms,v 1.3 2004/04/06 10:00:32 jmc Exp $ +.\" +.\" Copyright (C) Caldera International Inc. 2001-2002. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code and documentation must retain the above +.\" copyright notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed or owned by Caldera +.\" International, Inc. +.\" 4. Neither the name of Caldera International, Inc. nor the names of other +.\" contributors may be used to endorse or promote products derived from +.\" this software without specific prior written permission. +.\" +.\" USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA +.\" INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR ANY DIRECT, +.\" INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.\" @(#)lex.ms 8.2 (Berkeley) 5/24/94 +.\" +.if n \{\ +.po 5n +.ll 70n +.\} +.EH 'PSD:16-%''Lex \- A Lexical Analyzer Generator' +.OH 'Lex \- A Lexical Analyzer Generator''PSD:16-%' +.hc ~ +.bd I 2 +.de TS +.br +.nf +.SP 1v +.ul 0 +.. +.de TE +.SP 1v +.fi +.. +.\".de PT +.\".if \\n%>1 'tl ''\s7LEX\s0\s9\(mi%\s0'' +.\".if \\n%>1 'sp +.\".. +.ND July 21, 1975 +.\".RP +.\".TM 75-1274-15 39199 39199-11 +.TL +Lex \- A Lexical Analyzer ~Generator~ +.AU ``MH 2C-569'' 6377 +M. E. Lesk and E. Schmidt +.AI +.\" .MH +.AB +.sp +.bd I 2 +.\".nr PS 8 +.\".nr VS 9 +.\".ps 8 +.\".vs 9p +Lex helps write programs whose control flow +is directed by instances of regular +expressions in the input stream. +It is well suited for editor-script type transformations and +for segmenting input in preparation for +a parsing routine. +.PP +Lex source is a table of regular expressions and corresponding program fragments. +The table is translated to a program +which reads an input stream, copying it to an output stream +and partitioning the input +into strings which match the given expressions. +As each such string is recognized the corresponding +program fragment is executed. +The recognition of the expressions +is performed by a deterministic finite automaton +generated by Lex. +The program fragments written by the user are executed in the order in which the +corresponding regular expressions occur in the input stream. +.\" .if n .if \n(tm .ig +.PP +The lexical analysis +programs written with Lex accept ambiguous specifications +and choose the longest +match possible at each input point. +If necessary, substantial look~ahead +is performed on the input, but the +input stream will be backed up to the +end of the current partition, so that the user +has general freedom to manipulate it. +.PP +Lex can generate analyzers in either C or C++. \** +.FS +Some versions of lex were able to produce Ratfor scanners. +Ratfor is a language which can be translated automatically to portable Fortran. +This implementation of lex does not support such scanners. +.FE +This manual, however, will only discuss generating analyzers +in C on the UNIX system. +For details on generating C++ scanners, see the manual page for lex(1). +Lex is designed to simplify +interfacing with Yacc, for those +with access to this compiler-compiler system. +\&.. +.\".nr PS 9 +.\".nr VS 11 +.AE +.\" .2C +.NH +Introduction. +.PP +Lex is a program generator designed for +lexical processing of character input streams. +It accepts a high-level, problem oriented specification +for character string matching, +and +produces a program in a general purpose language which recognizes +regular expressions. +The regular expressions are specified by the user in the +source specifications given to Lex. +The Lex written code recognizes these expressions +in an input stream and partitions the input stream into +strings matching the expressions. At the bound~aries +between strings +program sections +provided by the user are executed. +The Lex source file associates the regular expressions and the +program fragments. +As each expression appears in the input to the program written by Lex, +the corresponding fragment is executed. +.PP +.de MH +Bell Laboratories, Murray Hill, NJ 07974. +.. +The user supplies the additional code +beyond expression matching +needed to complete his tasks, possibly +including code written by other generators. +The program that recognizes the expressions is generated in the +general purpose programming language employed for the +user's program fragments. +Thus, a high level expression +language is provided to write the string expressions to be +matched while the user's freedom to write actions +is unimpaired. +This avoids forcing the user who wishes to use a string manipulation +language for input analysis to write processing programs in the same +and often inappropriate string handling language. +.PP +Lex is not a complete language, but rather a generator representing +a new language feature which can be added to +different programming languages, called ``host languages.'' +Just as general purpose languages +can produce code to run on different computer hardware, +Lex can write code in different host languages. +The host language is used for the output code generated by Lex +and also for the program fragments added by the user. +Compatible run-time libraries for the different host languages +are also provided. +This makes Lex adaptable to different environments and +different users. +Each application +may be directed to the combination of hardware and host language appropriate +to the task, the user's background, and the properties of local +implementations. +At present, the only supported host languages are C and C++, +although Fortran (in the form of Ratfor [2]) has been available +in the past. +Lex itself exists on UNIX, GCOS, and OS/370; but the +code generated by Lex may be taken anywhere the appropriate +compilers exist. +.PP +Lex turns the user's expressions and actions +(called +.ul +source +in this memo) into the host general-purpose language; +the generated program is named +.ul +yylex. +The +.ul +yylex +program +will recognize expressions +in a stream +(called +.ul +input +in this memo) +and perform the specified actions for each expression as it is detected. +See Figure 1. +.DS C +Source \(-> Lex \(-> yylex + + +Input \(-> yylex \(-> Output + + +An overview of Lex +Figure 1 +.DE +.PP +For a trivial example, consider a program to delete +from the input +all blanks or tabs at the ends of lines. +.DS I +%% +[ \et]+$ ; +.DE +.LP +is all that is required. +The program +contains a %% delimiter to mark the beginning of the rules, and +one rule. +This rule contains a regular expression +which matches one or more +instances of the characters blank or tab +(written \et for visibility, in accordance with the C language convention) +just prior to the end of a line. +The brackets indicate the character +class made of blank and tab; the + indicates ``one or more ...''; +and the $ indicates ``end of line,'' as in QED. +No action is specified, +so the program generated by Lex (yylex) will ignore these characters. +Everything else will be copied. +To change any remaining +string of blanks or tabs to a single blank, +add another rule: +.DS I +%% +[ \et]+$ ; +[ \et]+ printf(" "); +.DE +.LP +The finite automaton generated for this +source will scan for both rules at once, +observing at +the termination of the string of blanks or tabs +whether or not there is a newline character, and executing +the desired rule action. +The first rule matches all strings of blanks or tabs +at the end of lines, and the second +rule all remaining strings of blanks or tabs. +.PP +Lex can be used alone for simple transformations, or +for analysis and statistics gathering on a lexical level. +Lex can also be used with a parser generator +to perform the lexical analysis phase; it is particularly +easy to interface Lex and Yacc [3]. +Lex programs recognize only regular expressions; +Yacc writes parsers that accept a large class of context free grammars, +but require a lower level analyzer to recognize input tokens. +Thus, a combination of Lex and Yacc is often appropriate. +When used as a preprocessor for a later parser generator, +Lex is used to partition the input stream, +and the parser generator assigns structure to +the resulting pieces. +The flow of control +in such a case (which might be the first half of a compiler, +for example) is shown in Figure 2. +Additional programs, +written by other generators +or by hand, can +be added easily to programs written by Lex. +.\" .BS 2 +.ps 9 +.vs 11 +.DS C + lexical grammar + rules rules + \(da \(da + + Lex Yacc + + \(da \(da + +Input \(-> yylex \(-> yyparse \(-> Parsed input + + + Lex with Yacc + Figure 2 +.DE +.ps 10 +.vs 12 +.\" .BE +.LP +Yacc users +will realize that the name +.ul +yylex +is what Yacc expects its lexical analyzer to be named, +so that the use of this name by Lex simplifies +interfacing. +.PP +Lex generates a deterministic finite automaton from the regular expressions +in the source [4]. +The automaton is interpreted, rather than compiled, in order +to save space. +The result is still a fast analyzer. +In particular, the time taken by a Lex program +to recognize and partition an input stream is +proportional to the length of the input. +The number of Lex rules or +the complexity of the rules is +not important in determining speed, +unless rules which include +forward context require a significant amount of re~scanning. +What does increase with the number and complexity of rules +is the size of the finite +automaton, and therefore the size of the program +generated by Lex. +.PP +In the program written by Lex, the user's fragments +(representing the +.ul +actions +to be performed as each regular expression +is found) +are gathered +as cases of a switch. +The automaton interpreter directs the control flow. +Opportunity is provided for the user to insert either +declarations or additional statements in the routine containing +the actions, or to +add subroutines outside this action routine. +.PP +Lex is not limited to source which can +be interpreted on the basis of one character +look~ahead. +For example, +if there are two rules, one looking for +.I ab +and another for +.I abcdefg , +and the input stream is +.I abcdefh , +Lex will recognize +.I ab +and leave +the input pointer just before +.I "cd. . ." +Such backup is more costly +than the processing of simpler languages. +.NH +Lex Source. +.PP +The general format of Lex source is: +.DS I +{definitions} +%% +{rules} +%% +{user subroutines} +.DE +.LP +where the definitions and the user subroutines +are often omitted. +The second +.I %% +is optional, but the first is required +to mark the beginning of the rules. +The absolute minimum Lex program is thus +.DS I +%% +.DE +.LP +(no definitions, no rules) which translates into a program +which copies the input to the output unchanged. +.PP +In the outline of Lex programs shown above, the +.I +rules +.R +represent the user's control +decisions; they are a table, in which the left column +contains +.I +regular expressions +.R +(see section 3) +and the right column contains +.I +actions, +.R +program fragments to be executed when the expressions +are recognized. +Thus an individual rule might appear +.DS I +integer printf("found keyword INT"); +.DE +.LP +to look for the string +.I integer +in the input stream and +print the message ``found keyword INT'' whenever it appears. +In this example the host procedural language is C and +the C library function +.I +printf +.R +is used to print the string. +The end +of the expression is indicated by the first blank or tab character. +If the action is merely a single C expression, +it can just be given on the right side of the line; if it is +compound, or takes more than a line, it should be enclosed in +braces. +As a slightly more useful example, suppose it is desired to +change a number of words from British to American spelling. +Lex rules such as +.DS I +colour printf("color"); +mechanise printf("mechanize"); +petrol printf("gas"); +.DE +.LP +would be a start. These rules are not quite enough, +since +the word +.I petroleum +would become +.I gaseum ; +a way of dealing +with this will be described later. +.NH +Lex Regular Expressions. +.PP +The definitions of regular expressions are very similar to those +in QED [5]. +A regular +expression specifies a set of strings to be matched. +It contains text characters (which match the corresponding +characters in the strings being compared) +and operator characters (which specify +repetitions, choices, and other features). +The letters of the alphabet and the digits are +always text characters; thus the regular expression +.DS I +integer +.DE +.LP +matches the string +.ul +integer +wherever it appears +and the expression +.DS I +a57D +.DE +.LP +looks for the string +.ul +a57D. +.PP +.I +Operators. +.R +The operator characters are +.DS I +" \e [ ] ^ \- ? . \(** + | ( ) $ / { } % < > +.DE +.LP +and if they are to be used as text characters, an escape +should be used. +The quotation mark operator (") +indicates that whatever is contained between a pair of quotes +is to be taken as text characters. +Thus +.DS I +xyz"++" +.DE +.LP +matches the string +.I xyz++ +when it appears. Note that a part of a string may be quoted. +It is harmless but unnecessary to quote an ordinary +text character; the expression +.DS I +"xyz++" +.DE +.LP +is the same as the one above. +Thus by quoting every non-alphanumeric character +being used as a text character, the user can avoid remembering +the list above of current +operator characters, and is safe should further extensions to Lex +lengthen the list. +.PP +An operator character may also be turned into a text character +by preceding it with \e as in +.DS I +xyz\e+\e+ +.DE +.LP +which +is another, less readable, equivalent of the above expressions. +Another use of the quoting mechanism is to get a blank into +an expression; normally, as explained above, blanks or tabs end +a rule. +Any blank character not contained within [\|] (see below) must +be quoted. +Several normal C escapes with \e +are recognized: \en is newline, \et is tab, and \eb is backspace. +To enter \e itself, use \e\e. +Since newline is illegal in an expression, \en must be used; +it is not +required to escape tab and backspace. +Every character but blank, tab, newline and the list above is always +a text character. +.PP +.I +Character classes. +.R +Classes of characters can be specified using the operator pair [\|]. +The construction +.I [abc] +matches a +single character, which may be +.I a , +.I b , +or +.I c . +Within square brackets, +most operator meanings are ignored. +Only three characters are special: +these are \e \(mi and ^. The \(mi character +indicates ranges. For example, +.DS I +[a\(miz0\(mi9<>_] +.DE +.LP +indicates the character class containing all the lower case letters, +the digits, +the angle brackets, and underline. +.\" Ranges may be given in either order. +Using \(mi between any pair of characters which are +not both upper case letters, both lower case letters, or both digits +is implementation dependent. +.\" and will get a warning message. +(E.g., [0\-z] in ASCII is many more characters +than it is in EBCDIC). +If it is desired to include the +character \(mi in a character class, it should be first or +last; thus +.DS I +[\(mi+0\(mi9] +.DE +.LP +matches all the digits and the two signs. +.PP +In character classes, +the ^ operator must appear as the first character +after the left bracket; it indicates that the resulting string +is to be complemented with respect to the computer character set. +Thus +.DS I +[^abc] +.DE +.LP +matches all characters except a, b, or c, including +all special or control characters; or +.DS I +[^a\-zA\-Z] +.DE +.LP +is any character which is not a letter. +The \e character provides the usual escapes within +character class brackets. +.PP +.I +Arbitrary character. +.R +To match almost any character, the operator character +.DS I +\&. +.DE +.LP +is the class of all characters except newline. +Escaping into octal is possible although non-portable: +.DS I +[\e40\-\e176] +.DE +.LP +matches all printable characters in the ASCII character set, from octal +40 (blank) to octal 176 (tilde). +.PP +.I +Optional expressions. +.R +The operator +.I ? +indicates +an optional element of an expression. +Thus +.DS I +ab?c +.DE +.LP +matches either +.I ac +or +.I abc . +.PP +.I +Repeated expressions. +.R +Repetitions of classes are indicated by the operators +.I \(** +and +.I + . +.DS I +\f2a\(**\f1 +.DE +.LP +is any number of consecutive +.I a +characters, including zero; while +.DS I +a+ +.DE +.LP +is one or more instances of +.I a. +For example, +.DS I +[a\-z]+ +.DE +.LP +is all strings of lower case letters. +And +.DS +[A\(miZa\(miz][A\(miZa\(miz0\(mi9]\(** +.DE +.LP +indicates all alphanumeric strings with a leading +alphabetic character. +This is a typical expression for recognizing identifiers in +computer languages. +.PP +.I +Alternation and Grouping. +.R +The operator | +indicates alternation: +.DS I +(ab\||\|cd) +.DE +.LP +matches either +.ul +ab +or +.ul +cd. +Note that parentheses are used for grouping, although +they are +not necessary on the outside level; +.DS I +ab\||\|cd +.DE +.LP +would have sufficed. +Parentheses +can be used for more complex expressions: +.DS I +(ab\||\|cd+)?(ef)\(** +.DE +.LP +matches such strings as +.I abefef , +.I efefef , +.I cdef , +or +.I cddd\| ; +but not +.I abc , +.I abcd , +or +.I abcdef . +.PP +.I +Context sensitivity. +.R +Lex will recognize a small amount of surrounding +context. The two simplest operators for this are +.I ^ +and +.I $ . +If the first character of an expression is +.I ^ , +the expression will only be matched at the beginning +of a line (after a newline character, or at the beginning of +the input stream). +This can never conflict with the other meaning of +.I ^ , +complementation +of character classes, since that only applies within +the [\|] operators. +If the very last character is +.I $ , +the expression will only be matched at the end of a line (when +immediately followed by newline). +The latter operator is a special case of the +.I / +operator character, +which indicates trailing context. +The expression +.DS I +ab/cd +.DE +.LP +matches the string +.I ab , +but only if followed by +.ul +cd. +Thus +.DS I +ab$ +.DE +.LP +is the same as +.DS I +ab/\en +.DE +.LP +Left context is handled in Lex by +.I +start conditions +.R +as explained in section 10. If a rule is only to be executed +when the Lex automaton interpreter is in start condition +.I +x, +.R +the rule should be prefixed by +.DS I + +.DE +.LP +using the angle bracket operator characters. +If we considered ``being at the beginning of a line'' to be +start condition +.I ONE , +then the ^ operator +would be equivalent to +.DS I + +.DE +.LP +Start conditions are explained more fully later. +.PP +.I +Repetitions and Definitions. +.R +The operators {} specify +either repetitions (if they enclose numbers) +or +definition expansion (if they enclose a name). For example +.DS I +{digit} +.DE +.LP +looks for a predefined string named +.I digit +and inserts it +at that point in the expression. +The definitions are given in the first part of the Lex +input, before the rules. +In contrast, +.DS I +a{1,5} +.DE +.LP +looks for 1 to 5 occurrences of +.I a . +.PP +Finally, initial +.I % +is special, being the separator +for Lex source segments. +.NH +Lex Actions. +.PP +When an expression written as above is matched, Lex +executes the corresponding action. This section describes +some features of Lex which aid in writing actions. Note +that there is a default action, which +consists of copying the input to the output. This +is performed on all strings not otherwise matched. Thus +the Lex user who wishes to absorb the entire input, without +producing any output, must provide rules to match everything. +When Lex is being used with Yacc, this is the normal +situation. +One may consider that actions are what is done instead of +copying the input to the output; thus, in general, +a rule which merely copies can be omitted. +Also, a character combination +which is omitted from the rules +and which appears as input +is likely to be printed on the output, thus calling +attention to the gap in the rules. +.PP +One of the simplest things that can be done is to ignore +the input. Specifying a C null statement (`;') as an action +causes this result. A frequent rule is +.DS I +[ \et\en] ; +.DE +.LP +which causes the three spacing characters (blank, tab, and newline) +to be ignored. +.PP +Another easy way to avoid writing actions is the action character +|, which indicates that the action for this rule is the action +for the next rule. +The previous example could also have been written +.DS I +" " | +"\et" | +"\en" ; +.DE +.LP +with the same result, although in different style. +The quotes around \en and \et are not required. +.PP +In more complex actions, the user +will +often want to know the actual text that matched some expression +like +.I [a\(miz]+ . +Lex leaves this text in an external character +array named +.I +yytext. +.R +Thus, to print the name found, +a rule like +.DS I +[a\-z]+ printf("%s", yytext); +.DE +.LP +will print +the string in +.I +yytext. +.R +The C function +.I +printf +.R +accepts a format argument and data to be printed; +in this case, the format is ``print string'' (% indicating +data conversion, and +.I s +indicating string type), +and the data are the characters +in +.I +yytext. +.R +So this just places +the matched string +on the output. +This action +is so common that +it may be written as ECHO: +.DS I +[a\-z]+ ECHO; +.DE +.LP +is the same as the above. +Since the default action is just to +print the characters found, one might ask why +give a rule, like this one, which merely specifies +the default action? +Such rules are often required +to avoid matching some other rule +which is not desired. For example, if there is a rule +which matches +.I read +it will normally match the instances of +.I read +contained in +.I bread +or +.I readjust ; +to avoid +this, +a rule +of the form +.I [a\(miz]+ +is needed. +This is explained further below. +.PP +Sometimes it is more convenient to know the end of what +has been found; hence Lex also provides a count +.I +yyleng +.R +of the number of characters matched. +To count both the number +of words and the number of characters in words in the input, the user might write +.DS I +[a\-zA\-Z]+ {words++; chars += yyleng;} +.DE +.LP +which accumulates in +.ul +chars +the number +of characters in the words recognized. +The last character in the string matched can +be accessed by +.DS I +yytext[yyleng\-1] +.DE +.PP +Occasionally, a Lex +action may decide that a rule has not recognized the correct +span of characters. +Two routines are provided to aid with this situation. +First, +.I +yymore() +.R +can be called to indicate that the next input expression recognized is to be +tacked on to the end of this input. Normally, +the next input string would overwrite the current +entry in +.I +yytext. +.R +Second, +.I +yyless (n) +.R +may be called to indicate that not all the characters matched +by the currently successful expression are wanted right now. +The argument +.I +n +.R +indicates the number of characters +in +.I +yytext +.R +to be retained. +Further characters previously matched +are +returned to the input. This provides the same sort of +look~ahead offered by the / operator, +but in a different form. +.PP +.I +Example: +.R +Consider a language which defines +a string as a set of characters between quotation (") marks, and provides that +to include a " in a string it must be preceded by a \e. The +regular expression which matches that is somewhat confusing, +so that it might be preferable to write +.DS I +\e"[^"]\(** { + if (yytext[yyleng\-1] == \(fm\e\e\(fm) + yymore(); + else + ... normal user processing + } +.DE +.LP +which will, when faced with a string such as +.I +"abc\e"def\|" +.R +first match +the five characters +\fI"abc\e\|\fR; +then +the call to +.I yymore() +will +cause the next part of the string, +\fI"def\|\fR, +to be tacked on the end. +Note that the final quote terminating the string should be picked +up in the code labeled ``normal processing''. +.PP +The function +.I +yyless() +.R +might be used to reprocess +text in various circumstances. Consider the C problem of distinguishing +the ambiguity of ``=\(mia''. +Suppose it is desired to treat this as ``=\(mi a'' +but print a message. A rule might be +.ps 9 +.vs 11 +.DS I +=\(mi[a\-zA\-Z] { + printf("Op (=\(mi) ambiguous\en"); + yyless(yyleng\-1); + ... action for =\(mi ... + } +.DE +.ps 10 +.vs 12 +which prints a message, returns the letter after the +operator to the input stream, and treats the operator as ``=\(mi''. +Alternatively it might be desired to treat this as ``= \(mia''. +To do this, just return the minus +sign as well as the letter to the input: +.ps 9 +.vs 11 +.DS I +=\(mi[a\-zA\-Z] { + printf("Op (=\(mi) ambiguous\en"); + yyless(yyleng\-2); + ... action for = ... + } +.DE +.ps 10 +.vs 12 +will perform the other interpretation. +Note that the expressions for the two cases might more easily +be written +.DS I +=\(mi/[A\-Za\-z] +.DE +.LP +in the first case and +.DS I +=/\-[A\-Za\-z] +.DE +.LP +in the second; +no backup would be required in the rule action. +It is not necessary to recognize the whole identifier +to observe the ambiguity. +The +possibility of ``=\(mi3'', however, makes +.DS I +=\(mi/[^ \et\en] +.DE +a still better rule. +.PP +In addition to these routines, Lex also permits +access to the I/O routines +it uses. \** +.FS +Note: The output() routine is not supported in this version of Lex. +See yyout instead. +.FE +They are: +.IP 1) +.I +input() +.R +which returns the next input character; and +.IP 2) +.I +unput(c) +.R +pushes the character +.I +c +.R +back onto the input stream to be read later by +.I +input(). +.R +.LP +By default these routines are provided as macro definitions, +but the user can override them and supply private versions. +These routines +define the relationship between external files and +internal characters, and must all be retained +or modified consistently. +They may be redefined, to +cause input or output to be transmitted to or from strange +places, including other programs or internal memory; +but the character set used must be consistent in all routines; +a value of zero returned by +.I +input +.R +must mean end of file; and +the relationship between +.I +unput +.R +and +.I +input +.R +must be retained +or the Lex look~ahead will not work. +Lex does not look ahead at all if it does not have to, +but every rule ending in +.ft I ++ \(** ? +.ft R +or +.ft I +$ +.ft R +or containing +.ft I +/ +.ft R +implies look~ahead. +Look~ahead is also necessary to match an expression that is a prefix +of another expression. +See below for a discussion of the character set used by Lex. +The standard Lex library imposes +a 100 character limit on backup. +.PP +Another Lex library routine that the user will sometimes want +to redefine is +.I +yywrap() +.R +which is called whenever Lex reaches an end-of-file. +If +.I +yywrap +.R +returns a 1, Lex continues with the normal wrapup on end of input. +Sometimes, however, it is convenient to arrange for more +input to arrive +from a new source. +In this case, the user should provide +a +.I +yywrap +.R +which +arranges for new input and +returns 0. This instructs Lex to continue processing. +The default +.I +yywrap +.R +always returns 1. +.PP +This routine is also a convenient place +to print tables, summaries, etc. at the end +of a program. Note that it is not +possible to write a normal rule which recognizes +end-of-file; the only access to this condition is +through +.I +yywrap. +.R +In fact, unless a private version of +.I +input() +.R +is supplied +a file containing nulls +cannot be handled, +since a value of 0 returned by +.I +input +.R +is taken to be end-of-file. +.PP +.NH +Ambiguous Source Rules. +.PP +Lex can handle ambiguous specifications. +When more than one expression can match the +current input, Lex chooses as follows: +.IP 1) +The longest match is preferred. +.IP 2) +Among rules which matched the same number of characters, +the rule given first is preferred. +.LP +Thus, suppose the rules +.DS I +integer keyword action ...; +[a\-z]+ identifier action ...; +.DE +.LP +to be given in that order. If the input is +.I integers , +it is taken as an identifier, because +.I [a\-z]+ +matches 8 characters while +.I integer +matches only 7. +If the input is +.I integer , +both rules match 7 characters, and +the keyword rule is selected because it was given first. +Anything shorter (e.g. \fIint\fR\|) will +not match the expression +.I integer +and so the identifier interpretation is used. +.PP +The principle of preferring the longest +match makes rules containing +expressions like +.I \&.\(** +dangerous. +For example, +.DS I +\&\(fm.\(**\(fm +.DE +.LP +might seem a good way of recognizing +a string in single quotes. +But it is an invitation for the program to read far +ahead, looking for a distant +single quote. +Presented with the input +.DS I +\&\(fmfirst\(fm quoted string here, \(fmsecond\(fm here +.DE +.LP +the above expression will match +.DS I +\&\(fmfirst\(fm quoted string here, \(fmsecond\(fm +.DE +.LP +which is probably not what was wanted. +A better rule is of the form +.DS I +\&\(fm[^\(fm\en]\(**\(fm +.DE +.LP +which, on the above input, will stop +after +.I \(fmfirst\(fm . +The consequences +of errors like this are mitigated by the fact +that the +.I \&. +operator will not match newline. +Thus expressions like +.I \&.\(** +stop on the +current line. +Don't try to defeat this with expressions like +.I (.|\en)+ +or +equivalents; +the Lex generated program will try to read +the entire input file, causing +internal buffer overflows. +.PP +Note that Lex is normally partitioning +the input stream, not searching for all possible matches +of each expression. +This means that each character is accounted for +once and only once. +For example, suppose it is desired to +count occurrences of both \fIshe\fR and \fIhe\fR in an input text. +Some Lex rules to do this might be +.DS I +she s++; +he h++; +\en | +\&. ; +.DE +.LP +where the last two rules ignore everything besides \fIhe\fR and \fIshe\fR. +Remember that . does not include newline. +Since \fIshe\fR includes \fIhe\fR, Lex will normally +.I +not +.R +recognize +the instances of \fIhe\fR included in \fIshe\fR, +since once it has passed a \fIshe\fR those characters are gone. +.PP +Sometimes the user would like to override this choice. The action +REJECT +means ``go do the next alternative.'' +It causes whatever rule was second choice after the current +rule to be executed. +The position of the input pointer is adjusted accordingly. +Suppose the user really wants to count the included instances of \fIhe\fR: +.DS I +she {s++; REJECT;} +he {h++; REJECT;} +\en | +\&. ; +.DE +.LP +these rules are one way of changing the previous example +to do just that. +After counting each expression, it is rejected; whenever appropriate, +the other expression will then be counted. In this example, of course, +the user could note that \fIshe\fR includes \fIhe\fR but not +vice versa, and omit the REJECT action on \fIhe\fR; +in other cases, however, it +would not be possible a priori to tell +which input characters +were in both classes. +.PP +Consider the two rules +.DS I +a[bc]+ { ... ; REJECT;} +a[cd]+ { ... ; REJECT;} +.DE +.LP +If the input is +.I ab , +only the first rule matches, +and on +.I ad +only the second matches. +The input string +.I accb +matches the first rule for four characters +and then the second rule for three characters. +In contrast, the input +.I accd +agrees with +the second rule for four characters and then the first +rule for three. +.PP +In general, REJECT is useful whenever +the purpose of Lex is not to partition the input +stream but to detect all examples of some items +in the input, and the instances of these items +may overlap or include each other. +Suppose a digram table of the input is desired; +normally the digrams overlap, that is the word +.I the +is considered to contain +both +.I th +and +.I he . +Assuming a two-dimensional array named +.ul +digram +to be incremented, the appropriate +source is +.DS I +%% +[a\-z][a\-z] { + digram[yytext[0]][yytext[1]]++; + REJECT; + } +\&. ; +\en ; +.DE +.LP +where the REJECT is necessary to pick up +a letter pair beginning at every character, rather than at every +other character. +.NH +Lex Source Definitions. +.PP +Remember the format of the Lex +source: +.DS I +{definitions} +%% +{rules} +%% +{user routines} +.DE +.LP +So far only the rules have been described. The user needs +additional options, +though, to define variables for use in his program and for use +by Lex. +These can go either in the definitions section +or in the rules section. +.PP +Remember that Lex is turning the rules into a program. +Any source not intercepted by Lex is copied +into the generated program. There are three classes +of such things. +.IP 1) +Any line which is not part of a Lex rule or action +which begins with a blank or tab is copied into +the Lex generated program. +Such source input prior to the first %% delimiter will be external +to any function in the code; if it appears immediately after the first +%%, +it appears in an appropriate place for declarations +in the function written by Lex which contains the actions. +This material must look like program fragments, +and should precede the first Lex rule. +.IP +As a side effect of the above, lines which begin with a blank +or tab, and which contain a comment, +are passed through to the generated program. +This can be used to include comments in either the Lex source or +the generated code. The comments should follow the host +language convention. +.IP 2) +Anything included between lines containing +only +.I %{ +and +.I %} +is +copied out as above. The delimiters are discarded. +This format permits entering text like preprocessor statements that +must begin in column 1, +or copying lines that do not look like programs. +.IP 3) +Anything after the second %% delimiter, regardless of formats, etc., +is copied out after the Lex output. +.PP +Definitions intended for Lex are given +before the first %% delimiter. Any line in this section +not contained between %{ and %}, and begining +in column 1, is assumed to define Lex substitution strings. +The format of such lines is +.DS I +name translation +.DE +.LP +and it +causes the string given as a translation to +be associated with the name. +The name and translation +must be separated by at least one blank or tab, and the name must begin with +a letter or an underscore (`_'). +The translation can then be called out +by the {name} syntax in a rule. +Using {D} for the digits and {E} for an exponent field, +for example, might abbreviate rules to recognize numbers: +.DS I +D [0\-9] +E [DEde][\-+]?{D}+ +%% +{D}+ printf("integer"); +{D}+"."{D}\(**({E})? | +{D}\(**"."{D}+({E})? | +{D}+{E} printf("real"); +.DE +.LP +Note the first two rules for real numbers; +both require a decimal point and contain +an optional exponent field, +but the first requires at least one digit before the +decimal point and the second requires at least one +digit after the decimal point. +To correctly handle the problem +posed by a Fortran expression such as +.I 35.EQ.I , +which does not contain a real number, a context-sensitive +rule such as +.DS I +[0\-9]+/"."EQ printf("integer"); +.DE +.LP +could be used in addition to the normal rule for integers. +.PP +The definitions +section may also contain other commands, including the +selection of a host language, a character set table, +a list of start conditions, or adjustments to the default +size of arrays within Lex itself for larger source programs. +These possibilities +are discussed below under ``Summary of Source Format,'' +section 12. +.NH +Usage. +.PP +There are two steps in +compiling a Lex source program. +First, the Lex source must be turned into a generated program +in the host general purpose language. +Then this program must be compiled and loaded, usually with +a library of Lex subroutines. +The generated program +is on a file named +.I lex.yy.c . +The I/O library is defined in terms of the C standard +library [6]. +.PP +The C programs generated by Lex are slightly different +on OS/370, because the +OS compiler is less powerful than the UNIX or GCOS compilers, +and does less at compile time. +C programs generated on GCOS and UNIX are the same. +.PP +.I +UNIX. +.R +The library is accessed by the loader flag +.I \-ll . +So an appropriate +set of commands is +.DS I +lex source +cc lex.yy.c \-ll +.DE +.LP +The resulting program is placed on the usual file +.I +a.out +.R +for later execution. +To use Lex with Yacc see below. +Although the default Lex I/O routines use the C standard library, +the Lex automata themselves do not do so; +if private versions of +.I +input, +output +.R +and +.I unput +are given, the library can be avoided. +.PP +.NH +Lex and Yacc. +.PP +If you want to use Lex with Yacc, note that what Lex writes is a program +named +.I +yylex(), +.R +the name required by Yacc for its analyzer. +Normally, the default main program on the Lex library +calls this routine, but if Yacc is loaded, and its main +program is used, Yacc will call +.I +yylex(). +.R +In this case each Lex rule should end with +.DS I +return(token); +.DE +.LP +where the appropriate token value is returned. +An easy way to get access +to Yacc's names for tokens is to +compile the Lex output file as part of +the Yacc output file by placing the line +.DS I +# include "lex.yy.c" +.DE +.LP +in the last section of Yacc input. +Supposing the grammar to be +named ``good'' and the lexical rules to be named ``better'' +the UNIX command sequence can just be: +.DS I +yacc good +lex better +cc y.tab.c \-ly \-ll +.DE +.LP +The Yacc library (\-ly) should be loaded before the Lex library, +to obtain a main program which invokes the Yacc parser. +The generations of Lex and Yacc programs can be done in +either order. +.NH +Examples. +.PP +As a trivial problem, consider copying an input file while +adding 3 to every positive number divisible by 7. +Here is a suitable Lex source program: +.DS I +%% + int k; +[0\-9]+ { + k = atoi(yytext); + if (k%7 == 0) + printf("%d", k+3); + else + printf("%d",k); + } +.DE +.LP +The rule [0\-9]+ recognizes strings of digits; +.I +atoi +.R +converts the digits to binary +and stores the result in +.ul +k. +The operator % (remainder) is used to check whether +.ul +k +is divisible by 7; if it is, +it is incremented by 3 as it is written out. +It may be objected that this program will alter such +input items as +.I 49.63 +or +.I X7 . +Furthermore, it increments the absolute value +of all negative numbers divisible by 7. +To avoid this, just add a few more rules after the active one, +as here: +.DS I +%% + int k; +\-?[0\-9]+ { + k = atoi(yytext); + printf("%d", + k%7 == 0 ? k+3 : k); + } +\-?[0\-9.]+ ECHO; +[A-Za-z][A-Za-z0-9]+ ECHO; +.DE +.LP +Numerical strings containing +a ``.'' or preceded by a letter will be picked up by +one of the last two rules, and not changed. +The +.I if\-else +has been replaced by +a C conditional expression to save space; +the form +.ul +a?b:c +means ``if +.I a +then +.I b +else +.I c ''. +.PP +For an example of statistics gathering, here +is a program which histograms the lengths +of words, where a word is defined as a string of letters. +.DS + int lengs[100]; +%% +[a\-z]+ lengs[yyleng]++; +\&. | +\en ; +%% +yywrap() +{ +int i; +printf("Length No. words\en"); +for(i=0; i<100; i++) + if (lengs[i] > 0) + printf("%5d%10d\en",i,lengs[i]); +return(1); +} +.DE +.LP +This program +accumulates the histogram, while producing no output. At the end +of the input it prints the table. +The final statement +.I +return(1); +.R +indicates that Lex is to perform wrapup. If +.I +yywrap +.R +returns zero (false) +it implies that further input is available +and the program is +to continue reading and processing. +To provide a +.I +yywrap +.R +that never +returns true causes an infinite loop. +.PP +As a larger example, +here are some parts of a program written by N. L. Schryer +to convert double precision Fortran to single precision Fortran. +Because Fortran does not distinguish upper and lower case letters, +this routine begins by defining a set of classes including +both cases of each letter: +.DS I +a [aA] +b [bB] +c [cC] +\&... +z [zZ] +.DE +.LP +An additional class recognizes white space: +.DS I +W [ \et]\(** +.DE +.LP +The first rule changes +``double precision'' to ``real'', or ``DOUBLE PRECISION'' to ``REAL''. +.DS I +{d}{o}{u}{b}{l}{e}{W}{p}{r}{e}{c}{i}{s}{i}{o}{n} { + printf(yytext[0]==\(fmd\(fm? "real" : "REAL"); + } +.DE +.LP +Care is taken throughout this program to preserve the case +(upper or lower) +of the original program. +The conditional operator is used to +select the proper form of the keyword. +The next rule copies continuation card indications to +avoid confusing them with constants: +.DS I +^" "[^ 0] ECHO; +.DE +.LP +In the regular expression, the quotes surround the +blanks. +It is interpreted as +``beginning of line, then five blanks, then +anything but blank or zero.'' +Note the two different meanings of +.I ^ . +There follow some rules to change double precision +constants to ordinary floating constants. +.DS I +[0\-9]+{W}{d}{W}[+\-]?{W}[0\-9]+ | +[0\-9]+{W}"."{W}{d}{W}[+\-]?{W}[0\-9]+ | +"."{W}[0\-9]+{W}{d}{W}[+\-]?{W}[0\-9]+ { + /\(** convert constants \(**/ + for(p=yytext; \(**p != 0; p++) + { + if (\(**p == \(fmd\(fm || \(**p == \(fmD\(fm) + \(**p=+ \(fme\(fm\- \(fmd\(fm; + ECHO; + } +.DE +.LP +After the floating point constant is recognized, it is +scanned by the +.ul +for +loop +to find the letter +.I d +or +.I D . +The program than adds +.I \(fme\(fm\-\(fmd\(fm , +which converts +it to the next letter of the alphabet. +The modified constant, now single-precision, +is written out again. +There follow a series of names which must be respelled to remove +their initial \fId\fR. +By using the +array +.I +yytext +.R +the same action suffices for all the names (only a sample of +a rather long list is given here). +.DS I +{d}{s}{i}{n} | +{d}{c}{o}{s} | +{d}{s}{q}{r}{t} | +{d}{a}{t}{a}{n} | +\&... +{d}{f}{l}{o}{a}{t} printf("%s",yytext+1); +.DE +.LP +Another list of names must have initial \fId\fR changed to initial \fIa\fR: +.DS I +{d}{l}{o}{g} | +{d}{l}{o}{g}10 | +{d}{m}{i}{n}1 | +{d}{m}{a}{x}1 { + yytext[0] =+ \(fma\(fm \- \(fmd\(fm; + ECHO; + } +.DE +.LP +And one routine +must have initial \fId\fR changed to initial \fIr\fR: +.DS I +{d}1{m}{a}{c}{h} {yytext[0] =+ \(fmr\(fm \- \(fmd\(fm; + ECHO; + } +.DE +.LP +To avoid such names as \fIdsinx\fR being detected as instances +of \fIdsin\fR, some final rules pick up longer words as identifiers +and copy some surviving characters: +.DS I +[A\-Za\-z][A\-Za\-z0\-9]\(** | +[0\-9]+ | +\en | +\&. ECHO; +.DE +.LP +Note that this program is not complete; it +does not deal with the spacing problems in Fortran or +with the use of keywords as identifiers. +.br +.NH +Left Context Sensitivity. +.PP +Sometimes +it is desirable to have several sets of lexical rules +to be applied at different times in the input. +For example, a compiler preprocessor might distinguish +preprocessor statements and analyze them differently +from ordinary statements. +This requires +sensitivity +to prior context, and there are several ways of handling +such problems. +The \fI^\fR operator, for example, is a prior context operator, +recognizing immediately preceding left context just as \fI$\fR recognizes +immediately following right context. +Adjacent left context could be extended, to produce a facility similar to +that for adjacent right context, but it is unlikely +to be as useful, since often the relevant left context +appeared some time earlier, such as at the beginning of a line. +.PP +This section describes three means of dealing +with different environments: a simple use of flags, +when only a few rules change from one environment to another, +the use of +.I +start conditions +.R +on rules, +and the possibility of making multiple lexical analyzers all run +together. +In each case, there are rules which recognize the need to change the +environment in which the +following input text is analyzed, and set some parameter +to reflect the change. This may be a flag explicitly tested by +the user's action code; such a flag is the simplest way of dealing +with the problem, since Lex is not involved at all. +It may be more convenient, +however, +to have Lex remember the flags as initial conditions on the rules. +Any rule may be associated with a start condition. It will only +be recognized when Lex is in +that start condition. +The current start condition may be changed at any time. +Finally, if the sets of rules for the different environments +are very dissimilar, +clarity may be best achieved by writing several distinct lexical +analyzers, and switching from one to another as desired. +.PP +Consider the following problem: copy the input to the output, +changing the word \fImagic\fR to \fIfirst\fR on every line which began +with the letter \fIa\fR, changing \fImagic\fR to \fIsecond\fR on every line +which began with the letter \fIb\fR, and changing +\fImagic\fR to \fIthird\fR on every line which began +with the letter \fIc\fR. All other words and all other lines +are left unchanged. +.PP +These rules are so simple that the easiest way +to do this job is with a flag: +.DS + int flag; +%% +^a {flag = \(fma\(fm; ECHO;} +^b {flag = \(fmb\(fm; ECHO;} +^c {flag = \(fmc\(fm; ECHO;} +\en {flag = 0 ; ECHO;} +magic { + switch (flag) + { + case \(fma\(fm: printf("first"); break; + case \(fmb\(fm: printf("second"); break; + case \(fmc\(fm: printf("third"); break; + default: ECHO; break; + } + } +.DE +.LP +should be adequate. +.PP +To handle the same problem with start conditions, each +start condition must be introduced to Lex in the definitions section +with a line reading +.DS I +%s name1 name2 ... +.DE +.LP +or +.DS I +%x name1 name2 ... +.DE +.LP +where the conditions may be named in any order. +`%s' denotes \fIinclusive\fR start conditions and `%x' denotes +\fIexclusive\fR start conditions. +The conditions may be referenced at the +head of a rule with the <> brackets: +.DS I +expression +.DE +.LP +is a rule which is only recognized when Lex is in the +start condition \fIname1\fR. +To enter a start condition, +execute the action statement +.DS I +BEGIN name1; +.DE +.LP +which changes the start condition to \fIname1\fR. +Until the next BEGIN action is executed, rules with the given +start condition will be active and rules with other start conditions +will be inactive. If the start condition is inclusive, then +rules with no start conditions at all will also be active. If it is +exclusive, then only rules qualified with the start condition will be active. +.PP +To resume the normal state, +.DS I +BEGIN 0; +.DE +.LP +resets the initial condition +of the Lex automaton interpreter. +A rule may be active in several +start conditions: +.DS I + +.DE +.LP +is a legal prefix. +.PP +The same example as before can be written: +.DS I +%START AA BB CC +%% +^a {ECHO; BEGIN AA;} +^b {ECHO; BEGIN BB;} +^c {ECHO; BEGIN CC;} +\en {ECHO; BEGIN 0;} +magic printf("first"); +magic printf("second"); +magic printf("third"); +.DE +.LP +where the logic is exactly the same as in the previous +method of handling the problem, but Lex does the work +rather than the user's code. +.\" .NH +.\" Character Set. +.\" .PP +.\" The programs generated by Lex handle +.\" character I/O only through the routines +.\" .I +.\" input, +.\" output, +.\" .R +.\" and +.\" .I +.\" unput. +.\" .R +.\" Thus the character representation +.\" provided in these routines +.\" is accepted by Lex and employed to return +.\" values in +.\" .I +.\" yytext. +.\" .R +.\" For internal use +.\" a character is represented as a small integer +.\" which, if the standard library is used, +.\" has a value equal to the integer value of the bit +.\" pattern representing the character on the host computer. +.\" Normally, the letter +.\" .I a +.\" is represented as the same form as the character constant +.\" .I \(fma\(fm . +.\" If this interpretation is changed, by providing I/O +.\" routines which translate the characters, +.\" Lex must be told about +.\" it, by giving a translation table. +.\" This table must be in the definitions section, +.\" and must be bracketed by lines containing only +.\" ``%T''. +.\" The table contains lines of the form +.\" .DS I +.\" {integer} {character string} +.\" .DE +.\" .LP +.\" which indicate the value associated with each character. +.\" Thus the next example +.\" .DS I +.\" %T +.\" 1 Aa +.\" 2 Bb +.\" \&... +.\" 26 Zz +.\" 27 \en +.\" 28 + +.\" 29 \- +.\" 30 0 +.\" 31 1 +.\" \&... +.\" 39 9 +.\" %T +.\" .DE +.\" .LP 1 +.\" Sample character table. +.\" maps the lower and upper case letters together into the integers 1 through 26, +.\" newline into 27, + and \- into 28 and 29, and the +.\" digits into 30 through 39. +.\" Note the escape for newline. +.\" If a table is supplied, every character that is to appear either +.\" in the rules or in any valid input must be included +.\" in the table. +.\" No character +.\" may be assigned the number 0, and no character may be +.\" assigned a bigger number than the size of the hardware character set. +.NH +Summary of Source Format. +.PP +The general form of a Lex source file is: +.DS I +{definitions} +%% +{rules} +%% +{user subroutines} +.DE +.LP +The definitions section contains +a combination of +.IP 1) +Definitions, in the form ``name space translation''. +.IP 2) +Included code, in the form ``space code''. +.IP 3) +Included code, in the form +.DS I +%{ +code +%} +.DE +.ns +.IP 4) +Start conditions, given in the form +.DS I +%s name1 name2 ... +.DE +.\" .ns +.\" .IP 5) +.\" Character set tables, in the form +.\" .DS I +.\" %T +.\" number space character-string +.\" \&... +.\" %T +.\" .DE +.\" .ns +.\" .IP 5) +.\" Changes to internal array sizes, in the form +.\" .DS I +.\" %\fIx\fR\0\0\fInnn\fR +.\" .DE +.\" .LP +.\" where \fInnn\fR is a decimal integer representing an array size +.\" and \fIx\fR selects the parameter as follows: +.\" .DS I +.\" Letter Parameter +.\" p positions +.\" n states +.\" e tree nodes +.\" a transitions +.\" k packed character classes +.\" o output array size +.\" .DE +.LP +Lines in the rules section have the form ``expression action'' +where the action may be continued on succeeding +lines by using braces to delimit it. +.PP +Regular expressions in Lex use the following +operators: +.br +.DS I +x the character "x" +"x" an "x", even if x is an operator. +\ex an "x", even if x is an operator. +[xy] the character x or y. +[x\-z] the characters x, y or z. +[^x] any character but x. +\&. any character but newline. +^x an x at the beginning of a line. +x an x when Lex is in start condition y. +x$ an x at the end of a line. +x? an optional x. +x\(** 0,1,2, ... instances of x. +x+ 1,2,3, ... instances of x. +x|y an x or a y. +(x) an x. +x/y an x but only if followed by y. +{xx} the translation of xx from the + definitions section. +x{m,n} \fIm\fR through \fIn\fR occurrences of x +.DE +.\" .NH +.\" Caveats and Bugs. +.\" .PP +.\" There are pathological expressions which +.\" produce exponential growth of the tables when +.\" converted to deterministic machines; +.\" fortunately, they are rare. +.\" .PP +.\" REJECT does not rescan the input; instead it remembers the results of the previous +.\" scan. This means that if a rule with trailing context is found, and +.\" REJECT executed, the user +.\" must not have used +.\" .ul +.\" unput +.\" to change the characters forthcoming +.\" from the input stream. +.\" This is the only restriction on the user's ability to manipulate +.\" the not-yet-processed input. +.\" .PP +.\" .NH +.\" Acknowledgments. +.\" .PP +.\" As should +.\" be obvious from the above, the outside of Lex +.\" is patterned +.\" on Yacc and the inside on Aho's string matching routines. +.\" Therefore, both S. C. Johnson and A. V. Aho +.\" are really originators +.\" of much of Lex, +.\" as well as debuggers of it. +.\" Many thanks are due to both. +.\" .PP +.\" The code of the current version of Lex was designed, written, +.\" and debugged by Eric Schmidt. +.\" .SG MH-1274-MEL-unix +.\" .sp 1 +.\" .2C +.NH +References. +.sp 1v +.IP 1. +B. W. Kernighan and D. M. Ritchie, +.I +The C Programming Language, +.R +Prentice-Hall, N. J. (1978). +.IP 2. +B. W. Kernighan, +.I +Ratfor: A Preprocessor for a Rational Fortran, +.R +Software \- Practice and Experience, +\fB5\fR, pp. 395-496 (1975). +.IP 3. +S. C. Johnson, +.I +Yacc: Yet Another Compiler Compiler, +.R +Computing Science Technical Report No. 32, +1975, +.MH +.\" .if \n(tm (also TM 75-1273-6) +.IP 4. +A. V. Aho and M. J. Corasick, +.I +Efficient String Matching: An Aid to Bibliographic Search, +.R +Comm. ACM +.B +18, +.R +333-340 (1975). +.IP 5. +B. W. Kernighan, D. M. Ritchie and K. L. Thompson, +.I +QED Text Editor, +.R +Computing Science Technical Report No. 5, +1972, +.MH +.IP 6. +D. M. Ritchie, +private communication. +See also +M. E. Lesk, +.I +The Portable C Library, +.R +Computing Science Technical Report No. 31, +.MH +.\" .if \n(tm (also TM 75-1274-11) diff --git a/third_party/lex/libmain.c b/third_party/lex/libmain.c new file mode 100644 index 00000000..3bd417d7 --- /dev/null +++ b/third_party/lex/libmain.c @@ -0,0 +1,18 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif + +int yylex(); + +int main(int argc, char *argv[]) { + for (;;) { + if (!yylex()) break; + } + return 0; +} diff --git a/third_party/lex/libyywrap.c b/third_party/lex/libyywrap.c new file mode 100644 index 00000000..3a6bd1f7 --- /dev/null +++ b/third_party/lex/libyywrap.c @@ -0,0 +1,31 @@ +/* clang-format off */ +/* $OpenBSD: libyywrap.c,v 1.9 2015/11/19 22:52:40 tedu Exp $ */ + +/* libyywrap - flex run-time support library "yywrap" function */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + +int +yywrap(void) +{ + return 1; +} diff --git a/third_party/lex/main.c b/third_party/lex/main.c new file mode 100644 index 00000000..4dc934ee --- /dev/null +++ b/third_party/lex/main.c @@ -0,0 +1,1826 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 sw=8 fenc=utf-8 :vi│ +└─────────────────────────────────────────────────────────────────────────────*/ + +/* clang-format off */ +asm(".include \"third_party/lex/COPYING\""); + +/* $OpenBSD: main.c,v 1.27 2017/01/21 08:33:07 krw Exp $ */ + +/* flex - tool to generate fast lexical analyzers */ + +/* Copyright (c) 1990 The Regents of the University of California. */ +/* All rights reserved. */ + +/* This code is derived from software contributed to Berkeley by */ +/* Vern Paxson. */ + +/* The United States Government has rights in this work pursuant */ +/* to contract no. DE-AC03-76SF00098 between the United States */ +/* Department of Energy and the University of California. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + + + +#include "flexdef.h" +#include "version.h" +#include "options.h" +#include "libc/calls/calls.h" +#include "libc/fmt/fmt.h" +#include "libc/str/str.h" +#include "libc/mem/mem.h" +#include "libc/math.h" +#include "libc/conv/conv.h" +#include "libc/log/log.h" +#include "libc/runtime/gc.h" +#include "libc/x/x.h" +#include "libc/runtime/runtime.h" +#include "libc/x/x.h" +#include "libc/bits/safemacros.h" +#include "libc/bits/safemacros.h" +#include "tables.h" + +static char flex_version[] = FLEX_VERSION; + +/* declare functions that have forward references */ + +void flexinit PROTO((int, char **)); +void readin PROTO((void)); +void set_up_initial_allocations PROTO((void)); +static char *basename2 PROTO((char *path, int should_strip_ext)); + + +/* these globals are all defined and commented in flexdef.h */ +int printstats, syntaxerror, eofseen, ddebug, trace, nowarn, spprdflt; +int interactive, lex_compat, posix_compat, do_yylineno, useecs, fulltbl, + usemecs; +int fullspd, gen_line_dirs, performance_report, backing_up_report; +int C_plus_plus, long_align, use_read, yytext_is_array, do_yywrap, csize; +int reentrant, bison_bridge_lval, bison_bridge_lloc; +int yymore_used, reject, real_reject, continued_action, in_rule; +int yymore_really_used, reject_really_used; +int datapos, dataline, linenum; +FILE *skelfile = NULL; +int skel_ind = 0; +char *action_array; +int action_size, defs1_offset, prolog_offset, action_offset, action_index; +char *infilename = NULL, *outfilename = NULL, *headerfilename = NULL; +int did_outfilename; +char *prefix, *yyclass, *extra_type = NULL; +int do_stdinit, use_stdout; +int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE]; +int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp; +int maximum_mns, current_mns, current_max_rules; +int num_rules, num_eof_rules, default_rule, lastnfa; +int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2; +int *accptnum, *assoc_rule, *state_type; +int *rule_type, *rule_linenum, *rule_useful; +int current_state_type; +int variable_trailing_context_rules; +int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP]; +int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE]; +int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs, tecfwd[CSIZE + 1]; +int tecbck[CSIZE + 1]; +int lastsc, *scset, *scbol, *scxclu, *sceof; +int current_max_scs; +char **scname; +int current_max_dfa_size, current_max_xpairs; +int current_max_template_xpairs, current_max_dfas; +int lastdfa, *nxt, *chk, *tnxt; +int *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz; +union dfaacc_union *dfaacc; +int *accsiz, *dhash, numas; +int numsnpairs, jambase, jamstate; +int lastccl, *cclmap, *ccllen, *cclng, cclreuse; +int current_maxccls, current_max_ccl_tbl_size; +u_char *ccltbl; +char nmstr[MAXLINE]; +int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs; +int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave; +int num_backing_up, bol_needed; +FILE *backing_up_file; +int end_of_buffer_state; +char **input_files; +int num_input_files; +jmp_buf flex_main_jmp_buf; +bool *rule_has_nl, *ccl_has_nl; +int nlch = '\n'; +bool ansi_func_defs, ansi_func_protos; + +bool tablesext, tablesverify, gentables; +char *tablesfilename = 0, *tablesname = 0; +struct yytbl_writer tableswr; + +/* Make sure program_name is initialized so we don't crash if writing + * out an error message before getting the program name from argv[0]. + */ +char *program_name = "flex"; + +static const char *outfile_template = "lex.%s.%s"; +static const char *backing_name = "lex.backup"; +static const char *tablesfile_template = "lex.%s.tables"; + +/* From scan.l */ +extern FILE *yyout; + +static char outfile_path[MAXLINE]; +static int outfile_created = 0; +static char *skelname = NULL; +static int _stdout_closed = 0; /* flag to prevent double-fclose() on stdout. */ +const char *escaped_qstart = "[[]]M4_YY_NOOP[M4_YY_NOOP[M4_YY_NOOP[[]]"; +const char *escaped_qend = "[[]]M4_YY_NOOP]M4_YY_NOOP]M4_YY_NOOP[[]]"; + +/* For debugging. The max number of filters to apply to skeleton. */ +static int preproc_level = 1000; + +int flex_main PROTO((int argc, char *argv[])); +int main PROTO((int argc, char *argv[])); + +int +flex_main(argc, argv) + int argc; + char *argv[]; +{ + int i, exit_status, child_status; + + /* + * Set a longjmp target. Yes, I know it's a hack, but it gets worse: + * The return value of setjmp, if non-zero, is the desired exit code + * PLUS ONE. For example, if you want 'main' to return with code '2', + * then call longjmp() with an argument of 3. This is because it is + * invalid to specify a value of 0 to longjmp. FLEX_EXIT(n) should be + * used instead of exit(n); + */ + exit_status = setjmp(flex_main_jmp_buf); + if (exit_status) { + if (stdout && !_stdout_closed && !ferror(stdout)) { + fflush(stdout); + fclose(stdout); + } + while (wait(&child_status) > 0) { + if (!WIFEXITED(child_status) + || WEXITSTATUS(child_status) != 0) { + /* + * report an error of a child + */ + if (exit_status <= 1) + exit_status = 2; + + } + } + return exit_status - 1; + } + flexinit(argc, argv); + + readin(); + + skelout(); + /* %% [1.5] DFA */ + ntod(); + + for (i = 1; i <= num_rules; ++i) + if (!rule_useful[i] && i != default_rule) + line_warning(_("rule cannot be matched"), + rule_linenum[i]); + + if (spprdflt && !reject && rule_useful[default_rule]) + line_warning(_ + ("-s option given but default rule can be matched"), + rule_linenum[default_rule]); + + /* Generate the C state transition tables from the DFA. */ + make_tables(); + + /* + * Note, flexend does not return. It exits with its argument as + * status. + */ + flexend(0); + + return 0; /* keep compilers/lint happy */ +} + +/* Wrapper around flex_main, so flex_main can be built as a library. */ +int +main(argc, argv) + int argc; + char *argv[]; +{ +#if ENABLE_NLS +#if HAVE_LOCALE_H + setlocale(LC_MESSAGES, ""); + setlocale(LC_CTYPE, ""); + textdomain(PACKAGE); + bindtextdomain(PACKAGE, LOCALEDIR); +#endif +#endif + + pledge("stdio rpath wpath cpath proc exec", NULL); + return flex_main(argc, argv); +} + +/* check_options - check user-specified options */ + +void +check_options() +{ + int i; + + if (lex_compat) { + if (C_plus_plus) + flexerror(_("Can't use -+ with -l option")); + + if (fulltbl || fullspd) + flexerror(_("Can't use -f or -F with -l option")); + + if (reentrant || bison_bridge_lval) + flexerror(_ + ("Can't use --reentrant or --bison-bridge with -l option")); + + yytext_is_array = true; + do_yylineno = true; + use_read = false; + } +#if 0 + /* This makes no sense whatsoever. I'm removing it. */ + if (do_yylineno) + /* This should really be "maintain_backup_tables = true" */ + reject_really_used = true; +#endif + + if (csize == unspecified) { + if ((fulltbl || fullspd) && !useecs) + csize = DEFAULT_CSIZE; + else + csize = CSIZE; + } + if (interactive == unspecified) { + if (fulltbl || fullspd) + interactive = false; + else + interactive = true; + } + if (fulltbl || fullspd) { + if (usemecs) + flexerror(_ + ("-Cf/-CF and -Cm don't make sense together")); + + if (interactive) + flexerror(_("-Cf/-CF and -I are incompatible")); + + if (lex_compat) + flexerror(_ + ("-Cf/-CF are incompatible with lex-compatibility mode")); + + + if (fulltbl && fullspd) + flexerror(_ + ("-Cf and -CF are mutually exclusive")); + } + if (C_plus_plus && fullspd) + flexerror(_("Can't use -+ with -CF option")); + + if (C_plus_plus && yytext_is_array) { + lexwarn(_("%array incompatible with -+ option")); + yytext_is_array = false; + } + if (C_plus_plus && (reentrant)) + flexerror(_("Options -+ and --reentrant are mutually exclusive.")); + + if (C_plus_plus && bison_bridge_lval) + flexerror(_("bison bridge not supported for the C++ scanner.")); + + + if (useecs) { /* Set up doubly-linked equivalence classes. */ + + /* + * We loop all the way up to csize, since ecgroup[csize] is + * the position used for NUL characters. + */ + ecgroup[1] = NIL; + + for (i = 2; i <= csize; ++i) { + ecgroup[i] = i - 1; + nextecm[i - 1] = i; + } + + nextecm[csize] = NIL; + } else { + /* Put everything in its own equivalence class. */ + for (i = 1; i <= csize; ++i) { + ecgroup[i] = i; + nextecm[i] = BAD_SUBSCRIPT; /* to catch errors */ + } + } + + if (!ansi_func_defs) + buf_m4_define(&m4defs_buf, "M4_YY_NO_ANSI_FUNC_DEFS", NULL); + + if (!ansi_func_protos) + buf_m4_define(&m4defs_buf, "M4_YY_NO_ANSI_FUNC_PROTOS", NULL); + + if (extra_type) + buf_m4_define(&m4defs_buf, "M4_EXTRA_TYPE_DEFS", extra_type); + + if (!use_stdout) { + FILE *prev_stdout; + + if (!did_outfilename) { + char *suffix; + + if (C_plus_plus) + suffix = "cc"; + else + suffix = "c"; + + snprintf(outfile_path, sizeof(outfile_path), outfile_template, + prefix, suffix); + + outfilename = outfile_path; + } + prev_stdout = freopen(outfilename, "w+", stdout); + + if (prev_stdout == NULL) + lerrsf(_("could not create %s"), outfilename); + + outfile_created = 1; + } + /* Setup the filter chain. */ + output_chain = filter_create_int(NULL, filter_tee_header, headerfilename); + filter_create_ext(output_chain, firstnonnull(getenv("M4"), gc(xasprintf("o/%s/third_party/m4/m4.com.dbg", nulltoempty(getenv("MODE"))))), "-P", "-g", 0); + filter_create_int(output_chain, filter_fix_linedirs, NULL); + + /* For debugging, only run the requested number of filters. */ + if (preproc_level > 0) { + filter_truncate(output_chain, preproc_level); + filter_apply_chain(output_chain); + } + yyout = stdout; + + + /* always generate the tablesverify flag. */ + buf_m4_define(&m4defs_buf, "M4_YY_TABLES_VERIFY", tablesverify ? "1" : "0"); + if (tablesext) + gentables = false; + + if (tablesverify) + /* force generation of C tables. */ + gentables = true; + + + if (tablesext) { + FILE *tablesout; + struct yytbl_hdr hdr; + char *pname = 0; + int nbytes = 0; + + buf_m4_define(&m4defs_buf, "M4_YY_TABLES_EXTERNAL", NULL); + + if (!tablesfilename) { + nbytes = strlen(prefix) + strlen(tablesfile_template) + 2; + tablesfilename = pname = (char *) calloc(nbytes, 1); + snprintf(pname, nbytes, tablesfile_template, prefix); + } + if ((tablesout = fopen(tablesfilename, "w")) == NULL) + lerrsf(_("could not create %s"), tablesfilename); + free(pname); + tablesfilename = 0; + + yytbl_writer_init(&tableswr, tablesout); + + nbytes = strlen(prefix) + strlen("tables") + 2; + tablesname = (char *) calloc(nbytes, 1); + snprintf(tablesname, nbytes, "%stables", prefix); + yytbl_hdr_init(&hdr, flex_version, tablesname); + + if (yytbl_hdr_fwrite(&tableswr, &hdr) <= 0) + flexerror(_("could not write tables header")); + } + if (skelname && (skelfile = fopen(skelname, "r")) == NULL) + lerrsf(_("can't open skeleton file %s"), skelname); + + if (reentrant) { + buf_m4_define(&m4defs_buf, "M4_YY_REENTRANT", NULL); + if (yytext_is_array) + buf_m4_define(&m4defs_buf, "M4_YY_TEXT_IS_ARRAY", NULL); + } + if (bison_bridge_lval) + buf_m4_define(&m4defs_buf, "M4_YY_BISON_LVAL", NULL); + + if (bison_bridge_lloc) + buf_m4_define(&m4defs_buf, "", NULL); + + buf_m4_define(&m4defs_buf, "M4_YY_PREFIX", prefix); + + if (did_outfilename) + line_directive_out(stdout, 0); + + if (do_yylineno) + buf_m4_define(&m4defs_buf, "M4_YY_USE_LINENO", NULL); + + /* Create the alignment type. */ + buf_strdefine(&userdef_buf, "YY_INT_ALIGNED", + long_align ? "long int" : "short int"); + + /* Define the start condition macros. */ + { + struct Buf tmpbuf; + buf_init(&tmpbuf, sizeof(char)); + for (i = 1; i <= lastsc; i++) { + char *str, *fmt = "#define %s %d\n"; + size_t strsz; + + str = (char *) malloc(strsz = strlen(fmt) + strlen(scname[i]) + (int) (1 + log10(i)) + 2); + if (!str) + flexfatal(_("allocation of macro definition failed")); + snprintf(str, strsz, fmt, scname[i], i - 1); + buf_strappend(&tmpbuf, str); + free(str); + } + buf_m4_define(&m4defs_buf, "M4_YY_SC_DEFS", tmpbuf.elts); + buf_destroy(&tmpbuf); + } + + /* This is where we begin writing to the file. */ + + /* Dump the %top code. */ + if (top_buf.elts) + outn((char *) top_buf.elts); + + /* Dump the m4 definitions. */ + buf_print_strings(&m4defs_buf, stdout); + m4defs_buf.nelts = 0; /* memory leak here. */ + + /* Place a bogus line directive, it will be fixed in the filter. */ + outn("#line 0 \"M4_YY_OUTFILE_NAME\"\n"); + + /* Dump the user defined preproc directives. */ + if (userdef_buf.elts) + outn((char *) (userdef_buf.elts)); + + skelout(); + /* %% [1.0] */ +} + +/* flexend - terminate flex + * + * note + * This routine does not return. + */ + +void +flexend(exit_status) + int exit_status; + +{ + static int called_before = -1; /* prevent infinite recursion. */ + int tblsiz; + + if (++called_before) + FLEX_EXIT(exit_status); + + if (skelfile != NULL) { + if (ferror(skelfile)) + lerrsf(_("input error reading skeleton file %s"), + skelname); + + else if (fclose(skelfile)) + lerrsf(_("error closing skeleton file %s"), + skelname); + } +#if 0 + fprintf(header_out, + "#ifdef YY_HEADER_EXPORT_START_CONDITIONS\n"); + fprintf(header_out, + "/* Beware! Start conditions are not prefixed. */\n"); + + /* Special case for "INITIAL" */ + fprintf(header_out, + "#undef INITIAL\n#define INITIAL 0\n"); + for (i = 2; i <= lastsc; i++) + fprintf(header_out, "#define %s %d\n", scname[i], i - 1); + fprintf(header_out, + "#endif /* YY_HEADER_EXPORT_START_CONDITIONS */\n\n"); + + /* + * Kill ALL flex-related macros. This is so the user can #include + * more than one generated header file. + */ + fprintf(header_out, "#ifndef YY_HEADER_NO_UNDEFS\n"); + fprintf(header_out, + "/* Undefine all internal macros, etc., that do no belong in the header. */\n\n"); + + { + const char *undef_list[] = { + + "BEGIN", + "ECHO", + "EOB_ACT_CONTINUE_SCAN", + "EOB_ACT_END_OF_FILE", + "EOB_ACT_LAST_MATCH", + "FLEX_SCANNER", + "FLEX_STD", + "REJECT", + "YYFARGS0", + "YYFARGS1", + "YYFARGS2", + "YYFARGS3", + "YYLMAX", + "YYSTATE", + "YY_AT_BOL", + "YY_BREAK", + "YY_BUFFER_EOF_PENDING", + "YY_BUFFER_NEW", + "YY_BUFFER_NORMAL", + "YY_BUF_SIZE", + "M4_YY_CALL_LAST_ARG", + "M4_YY_CALL_ONLY_ARG", + "YY_CURRENT_BUFFER", + "YY_DECL", + "M4_YY_DECL_LAST_ARG", + "M4_YY_DEF_LAST_ARG", + "M4_YY_DEF_ONLY_ARG", + "YY_DO_BEFORE_ACTION", + "YY_END_OF_BUFFER", + "YY_END_OF_BUFFER_CHAR", + "YY_EXIT_FAILURE", + "YY_EXTRA_TYPE", + "YY_FATAL_ERROR", + "YY_FLEX_DEFINED_ECHO", + "YY_FLEX_LEX_COMPAT", + "YY_FLEX_MAJOR_VERSION", + "YY_FLEX_MINOR_VERSION", + "YY_FLEX_SUBMINOR_VERSION", + "YY_FLUSH_BUFFER", + "YY_G", + "YY_INPUT", + "YY_INTERACTIVE", + "YY_INT_ALIGNED", + "YY_LAST_ARG", + "YY_LESS_LINENO", + "YY_LEX_ARGS", + "YY_LEX_DECLARATION", + "YY_LEX_PROTO", + "YY_MAIN", + "YY_MORE_ADJ", + "YY_NEED_STRLEN", + "YY_NEW_FILE", + "YY_NULL", + "YY_NUM_RULES", + "YY_ONLY_ARG", + "YY_PARAMS", + "YY_PROTO", + "M4_YY_PROTO_LAST_ARG", + "M4_YY_PROTO_ONLY_ARG void", + "YY_READ_BUF_SIZE", + "YY_REENTRANT", + "YY_RESTORE_YY_MORE_OFFSET", + "YY_RULE_SETUP", + "YY_SC_TO_UI", + "YY_SKIP_YYWRAP", + "YY_START", + "YY_START_STACK_INCR", + "YY_STATE_EOF", + "YY_STDINIT", + "YY_TRAILING_HEAD_MASK", + "YY_TRAILING_MASK", + "YY_USER_ACTION", + "YY_USE_CONST", + "YY_USE_PROTOS", + "unput", + "yyTABLES_NAME", + "yy_create_buffer", + "yy_delete_buffer", + "yy_flex_debug", + "yy_flush_buffer", + "yy_init_buffer", + "yy_load_buffer_state", + "yy_new_buffer", + "yy_scan_buffer", + "yy_scan_bytes", + "yy_scan_string", + "yy_set_bol", + "yy_set_interactive", + "yy_switch_to_buffer", + "yypush_buffer_state", + "yypop_buffer_state", + "yyensure_buffer_stack", + "yyalloc", + "yyconst", + "yyextra", + "yyfree", + "yyget_debug", + "yyget_extra", + "yyget_in", + "yyget_leng", + "yyget_lineno", + "yyget_lloc", + "yyget_lval", + "yyget_out", + "yyget_text", + "yyin", + "yyleng", + "yyless", + "yylex", + "yylex_destroy", + "yylex_init", + "yylex_init_extra", + "yylineno", + "yylloc", + "yylval", + "yymore", + "yyout", + "yyrealloc", + "yyrestart", + "yyset_debug", + "yyset_extra", + "yyset_in", + "yyset_lineno", + "yyset_lloc", + "yyset_lval", + "yyset_out", + "yytables_destroy", + "yytables_fload", + "yyterminate", + "yytext", + "yytext_ptr", + "yywrap", + + /* must be null-terminated */ + NULL}; + + + for (i = 0; undef_list[i] != NULL; i++) + fprintf(header_out, "#undef %s\n", undef_list[i]); + } + + /* undef any of the auto-generated symbols. */ + for (i = 0; i < defs_buf.nelts; i++) { + + /* don't undef start conditions */ + if (sclookup(((char **) defs_buf.elts)[i]) > 0) + continue; + fprintf(header_out, "#undef %s\n", + ((char **) defs_buf.elts)[i]); + } + + fprintf(header_out, + "#endif /* !YY_HEADER_NO_UNDEFS */\n"); + fprintf(header_out, "\n"); + fprintf(header_out, "#undef %sIN_HEADER\n", prefix); + fprintf(header_out, "#endif /* %sHEADER_H */\n", prefix); + + if (ferror(header_out)) + lerrsf(_("error creating header file %s"), + headerfilename); + fflush(header_out); + fclose(header_out); +#endif + + if (exit_status != 0 && outfile_created) { + if (ferror(stdout)) + lerrsf(_("error writing output file %s"), + outfilename); + + else if ((_stdout_closed = 1) && fclose(stdout)) + lerrsf(_("error closing output file %s"), + outfilename); + + else if (unlink(outfilename)) + lerrsf(_("error deleting output file %s"), + outfilename); + } + if (backing_up_report && backing_up_file) { + if (num_backing_up == 0) + fprintf(backing_up_file, _("No backing up.\n")); + else if (fullspd || fulltbl) + fprintf(backing_up_file, + _ + ("%d backing up (non-accepting) states.\n"), + num_backing_up); + else + fprintf(backing_up_file, + _("Compressed tables always back up.\n")); + + if (ferror(backing_up_file)) + lerrsf(_("error writing backup file %s"), + backing_name); + + else if (fclose(backing_up_file)) + lerrsf(_("error closing backup file %s"), + backing_name); + } + if (printstats) { + fprintf(stderr, _("%s version %s usage statistics:\n"), + program_name, flex_version); + + fprintf(stderr, _(" scanner options: -")); + + if (C_plus_plus) + putc('+', stderr); + if (backing_up_report) + putc('b', stderr); + if (ddebug) + putc('d', stderr); + if (sf_case_ins()) + putc('i', stderr); + if (lex_compat) + putc('l', stderr); + if (posix_compat) + putc('X', stderr); + if (performance_report > 0) + putc('p', stderr); + if (performance_report > 1) + putc('p', stderr); + if (spprdflt) + putc('s', stderr); + if (reentrant) + fputs("--reentrant", stderr); + if (bison_bridge_lval) + fputs("--bison-bridge", stderr); + if (bison_bridge_lloc) + fputs("--bison-locations", stderr); + if (use_stdout) + putc('t', stderr); + if (printstats) + putc('v', stderr); /* always true! */ + if (nowarn) + putc('w', stderr); + if (interactive == false) + putc('B', stderr); + if (interactive == true) + putc('I', stderr); + if (!gen_line_dirs) + putc('L', stderr); + if (trace) + putc('T', stderr); + + if (csize == unspecified) + /* + * We encountered an error fairly early on, so csize + * never got specified. Define it now, to prevent + * bogus table sizes being written out below. + */ + csize = 256; + + if (csize == 128) + putc('7', stderr); + else + putc('8', stderr); + + fprintf(stderr, " -C"); + + if (long_align) + putc('a', stderr); + if (fulltbl) + putc('f', stderr); + if (fullspd) + putc('F', stderr); + if (useecs) + putc('e', stderr); + if (usemecs) + putc('m', stderr); + if (use_read) + putc('r', stderr); + + if (did_outfilename) + fprintf(stderr, " -o%s", outfilename); + + if (skelname) + fprintf(stderr, " -S%s", skelname); + + if (strcmp(prefix, "yy")) + fprintf(stderr, " -P%s", prefix); + + putc('\n', stderr); + + fprintf(stderr, _(" %d/%d NFA states\n"), + lastnfa, current_mns); + fprintf(stderr, _(" %d/%d DFA states (%d words)\n"), + lastdfa, current_max_dfas, totnst); + fprintf(stderr, _(" %d rules\n"), + num_rules + num_eof_rules - + 1 /* - 1 for def. rule */ ); + + if (num_backing_up == 0) + fprintf(stderr, _(" No backing up\n")); + else if (fullspd || fulltbl) + fprintf(stderr, + _ + (" %d backing-up (non-accepting) states\n"), + num_backing_up); + else + fprintf(stderr, + _ + (" Compressed tables always back-up\n")); + + if (bol_needed) + fprintf(stderr, + _(" Beginning-of-line patterns used\n")); + + fprintf(stderr, _(" %d/%d start conditions\n"), lastsc, + current_max_scs); + fprintf(stderr, + _ + (" %d epsilon states, %d double epsilon states\n"), + numeps, eps2); + + if (lastccl == 0) + fprintf(stderr, _(" no character classes\n")); + else + fprintf(stderr, + _ + (" %d/%d character classes needed %d/%d words of storage, %d reused\n"), + lastccl, current_maxccls, + cclmap[lastccl] + ccllen[lastccl], + current_max_ccl_tbl_size, cclreuse); + + fprintf(stderr, _(" %d state/nextstate pairs created\n"), + numsnpairs); + fprintf(stderr, + _(" %d/%d unique/duplicate transitions\n"), + numuniq, numdup); + + if (fulltbl) { + tblsiz = lastdfa * numecs; + fprintf(stderr, _(" %d table entries\n"), + tblsiz); + } else { + tblsiz = 2 * (lastdfa + numtemps) + 2 * tblend; + + fprintf(stderr, + _(" %d/%d base-def entries created\n"), + lastdfa + numtemps, current_max_dfas); + fprintf(stderr, + _ + (" %d/%d (peak %d) nxt-chk entries created\n"), + tblend, current_max_xpairs, peakpairs); + fprintf(stderr, + _ + (" %d/%d (peak %d) template nxt-chk entries created\n"), + numtemps * nummecs, + current_max_template_xpairs, + numtemps * numecs); + fprintf(stderr, _(" %d empty table entries\n"), + nummt); + fprintf(stderr, _(" %d protos created\n"), + numprots); + fprintf(stderr, + _(" %d templates created, %d uses\n"), + numtemps, tmpuses); + } + + if (useecs) { + tblsiz = tblsiz + csize; + fprintf(stderr, + _ + (" %d/%d equivalence classes created\n"), + numecs, csize); + } + if (usemecs) { + tblsiz = tblsiz + numecs; + fprintf(stderr, + _ + (" %d/%d meta-equivalence classes created\n"), + nummecs, csize); + } + fprintf(stderr, + _ + (" %d (%d saved) hash collisions, %d DFAs equal\n"), + hshcol, hshsave, dfaeql); + fprintf(stderr, _(" %d sets of reallocations needed\n"), + num_reallocs); + fprintf(stderr, _(" %d total table entries needed\n"), + tblsiz); + } + FLEX_EXIT(exit_status); +} + + +/* flexinit - initialize flex */ + +void +flexinit(argc, argv) + int argc; + char **argv; +{ + int i, sawcmpflag, rv, optind; + char *arg; + scanopt_t sopt; + + printstats = syntaxerror = trace = spprdflt = false; + lex_compat = posix_compat = C_plus_plus = backing_up_report = + ddebug = fulltbl = false; + fullspd = long_align = nowarn = yymore_used = continued_action = + false; + do_yylineno = yytext_is_array = in_rule = reject = do_stdinit = + false; + yymore_really_used = reject_really_used = unspecified; + interactive = csize = unspecified; + do_yywrap = gen_line_dirs = usemecs = useecs = true; + reentrant = bison_bridge_lval = bison_bridge_lloc = false; + performance_report = 0; + did_outfilename = 0; + prefix = "yy"; + yyclass = 0; + use_read = use_stdout = false; + tablesext = tablesverify = false; + gentables = true; + tablesfilename = tablesname = NULL; + ansi_func_defs = ansi_func_protos = true; + + sawcmpflag = false; + + /* Initialize dynamic array for holding the rule actions. */ + action_size = 2048; /* default size of action array in bytes */ + action_array = allocate_character_array(action_size); + defs1_offset = prolog_offset = action_offset = action_index = 0; + action_array[0] = '\0'; + + /* Initialize any buffers. */ + buf_init(&userdef_buf, sizeof(char)); /* one long string */ + buf_init(&defs_buf, sizeof(char *)); /* list of strings */ + buf_init(&yydmap_buf, sizeof(char)); /* one long string */ + buf_init(&top_buf, sizeof(char)); /* one long string */ + + { + const char *m4defs_init_str[] = {"m4_changequote\n", + "m4_changequote([[, ]])\n"}; + buf_init(&m4defs_buf, sizeof(char *)); + buf_append(&m4defs_buf, &m4defs_init_str, 2); + } + + sf_init(); + + /* initialize regex lib */ + flex_init_regex(); + + /* Enable C++ if program name ends with '+'. */ + program_name = basename2(argv[0], 0); + + if (program_name[0] != '\0' && + program_name[strlen(program_name) - 1] == '+') + C_plus_plus = true; + + /* read flags */ + sopt = scanopt_init(flexopts, argc, argv, 0); + if (!sopt) { + /* This will only happen when flexopts array is altered. */ + fprintf(stderr, + _("Internal error. flexopts are malformed.\n")); + FLEX_EXIT(1); + } + while ((rv = scanopt(sopt, &arg, &optind)) != 0) { + + if (rv < 0) { + /* + * Scanopt has already printed an option-specific + * error message. + */ + fprintf(stderr, + _ + ("Try `%s --help' for more information.\n"), + program_name); + FLEX_EXIT(1); + } + switch ((enum flexopt_flag_t) rv) { + case OPT_CPLUSPLUS: + C_plus_plus = true; + break; + + case OPT_BATCH: + interactive = false; + break; + + case OPT_BACKUP: + backing_up_report = true; + break; + + case OPT_DONOTHING: + break; + + case OPT_COMPRESSION: + if (!sawcmpflag) { + useecs = false; + usemecs = false; + fulltbl = false; + sawcmpflag = true; + } + for (i = 0; arg && arg[i] != '\0'; i++) + switch (arg[i]) { + case 'a': + long_align = true; + break; + + case 'e': + useecs = true; + break; + + case 'F': + fullspd = true; + break; + + case 'f': + fulltbl = true; + break; + + case 'm': + usemecs = true; + break; + + case 'r': + use_read = true; + break; + + default: + lerrif(_ + ("unknown -C option '%c'"), + (int) arg[i]); + break; + } + break; + + case OPT_DEBUG: + ddebug = true; + break; + + case OPT_NO_DEBUG: + ddebug = false; + break; + + case OPT_FULL: + useecs = usemecs = false; + use_read = fulltbl = true; + break; + + case OPT_FAST: + useecs = usemecs = false; + use_read = fullspd = true; + break; + + case OPT_HELP: + usage(); + FLEX_EXIT(0); + + case OPT_INTERACTIVE: + interactive = true; + break; + + case OPT_CASE_INSENSITIVE: + sf_set_case_ins(true); + break; + + case OPT_LEX_COMPAT: + lex_compat = true; + break; + + case OPT_POSIX_COMPAT: + posix_compat = true; + break; + + case OPT_PREPROC_LEVEL: + preproc_level = strtol(arg, NULL, 0); + break; + + case OPT_MAIN: + buf_strdefine(&userdef_buf, "YY_MAIN", "1"); + do_yywrap = false; + break; + + case OPT_NO_MAIN: + buf_strdefine(&userdef_buf, "YY_MAIN", "0"); + break; + + case OPT_NO_LINE: + gen_line_dirs = false; + break; + + case OPT_OUTFILE: + outfilename = arg; + did_outfilename = 1; + break; + + case OPT_PREFIX: + prefix = arg; + break; + + case OPT_PERF_REPORT: + ++performance_report; + break; + + case OPT_BISON_BRIDGE: + bison_bridge_lval = true; + break; + + case OPT_BISON_BRIDGE_LOCATIONS: + bison_bridge_lval = bison_bridge_lloc = true; + break; + + case OPT_REENTRANT: + reentrant = true; + break; + + case OPT_NO_REENTRANT: + reentrant = false; + break; + + case OPT_SKEL: + skelname = arg; + break; + + case OPT_DEFAULT: + spprdflt = false; + break; + + case OPT_NO_DEFAULT: + spprdflt = true; + break; + + case OPT_STDOUT: + use_stdout = true; + break; + + case OPT_NO_UNISTD_H: + //buf_strdefine(&userdef_buf, "YY_NO_UNISTD_H", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_UNISTD_H", 0); + break; + + case OPT_TABLES_FILE: + tablesext = true; + tablesfilename = arg; + break; + + case OPT_TABLES_VERIFY: + tablesverify = true; + break; + + case OPT_TRACE: + trace = true; + break; + + case OPT_VERBOSE: + printstats = true; + break; + + case OPT_VERSION: + printf(_("%s %s\n"), program_name, flex_version); + FLEX_EXIT(0); + + case OPT_WARN: + nowarn = false; + break; + + case OPT_NO_WARN: + nowarn = true; + break; + + case OPT_7BIT: + csize = 128; + break; + + case OPT_8BIT: + csize = CSIZE; + break; + + case OPT_ALIGN: + long_align = true; + break; + + case OPT_NO_ALIGN: + long_align = false; + break; + + case OPT_ALWAYS_INTERACTIVE: + buf_m4_define(&m4defs_buf, "M4_YY_ALWAYS_INTERACTIVE", 0); + break; + + case OPT_NEVER_INTERACTIVE: + buf_m4_define(&m4defs_buf, "M4_YY_NEVER_INTERACTIVE", 0); + break; + + case OPT_ARRAY: + yytext_is_array = true; + break; + + case OPT_POINTER: + yytext_is_array = false; + break; + + case OPT_ECS: + useecs = true; + break; + + case OPT_NO_ECS: + useecs = false; + break; + + case OPT_HEADER_FILE: + headerfilename = arg; + break; + + case OPT_META_ECS: + usemecs = true; + break; + + case OPT_NO_META_ECS: + usemecs = false; + break; + + case OPT_PREPROCDEFINE: + { + /* arg is "symbol" or "symbol=definition". */ + char *def2; + + for (def2 = arg; + *def2 != '\0' && *def2 != '='; ++def2); + + buf_strappend(&userdef_buf, "#define "); + if (*def2 == '\0') { + buf_strappend(&userdef_buf, arg); + buf_strappend(&userdef_buf, + " 1\n"); + } else { + buf_strnappend(&userdef_buf, arg, + def2 - arg); + buf_strappend(&userdef_buf, " "); + buf_strappend(&userdef_buf, + def2 + 1); + buf_strappend(&userdef_buf, "\n"); + } + } + break; + + case OPT_READ: + use_read = true; + break; + + case OPT_STACK: + //buf_strdefine(&userdef_buf, "YY_STACK_USED", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_STACK_USED", 0); + break; + + case OPT_STDINIT: + do_stdinit = true; + break; + + case OPT_NO_STDINIT: + do_stdinit = false; + break; + + case OPT_YYCLASS: + yyclass = arg; + break; + + case OPT_YYLINENO: + do_yylineno = true; + break; + + case OPT_NO_YYLINENO: + do_yylineno = false; + break; + + case OPT_YYWRAP: + do_yywrap = true; + break; + + case OPT_NO_YYWRAP: + do_yywrap = false; + break; + + case OPT_YYMORE: + yymore_really_used = true; + break; + + case OPT_NO_YYMORE: + yymore_really_used = false; + break; + + case OPT_REJECT: + reject_really_used = true; + break; + + case OPT_NO_REJECT: + reject_really_used = false; + break; + + case OPT_NO_ANSI_FUNC_DEFS: + ansi_func_defs = false; + break; + + case OPT_NO_ANSI_FUNC_PROTOS: + ansi_func_protos = false; + break; + + case OPT_NO_YY_PUSH_STATE: + //buf_strdefine(&userdef_buf, "YY_NO_PUSH_STATE", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_PUSH_STATE", 0); + break; + case OPT_NO_YY_POP_STATE: + //buf_strdefine(&userdef_buf, "YY_NO_POP_STATE", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_POP_STATE", 0); + break; + case OPT_NO_YY_TOP_STATE: + //buf_strdefine(&userdef_buf, "YY_NO_TOP_STATE", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_TOP_STATE", 0); + break; + case OPT_NO_UNPUT: + //buf_strdefine(&userdef_buf, "YY_NO_UNPUT", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_UNPUT", 0); + break; + case OPT_NO_YY_SCAN_BUFFER: + //buf_strdefine(&userdef_buf, "YY_NO_SCAN_BUFFER", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_SCAN_BUFFER", 0); + break; + case OPT_NO_YY_SCAN_BYTES: + //buf_strdefine(&userdef_buf, "YY_NO_SCAN_BYTES", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_SCAN_BYTES", 0); + break; + case OPT_NO_YY_SCAN_STRING: + //buf_strdefine(&userdef_buf, "YY_NO_SCAN_STRING", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_SCAN_STRING", 0); + break; + case OPT_NO_YYGET_EXTRA: + //buf_strdefine(&userdef_buf, "YY_NO_GET_EXTRA", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_GET_EXTRA", 0); + break; + case OPT_NO_YYSET_EXTRA: + //buf_strdefine(&userdef_buf, "YY_NO_SET_EXTRA", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_SET_EXTRA", 0); + break; + case OPT_NO_YYGET_LENG: + //buf_strdefine(&userdef_buf, "YY_NO_GET_LENG", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_GET_LENG", 0); + break; + case OPT_NO_YYGET_TEXT: + //buf_strdefine(&userdef_buf, "YY_NO_GET_TEXT", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_GET_TEXT", 0); + break; + case OPT_NO_YYGET_LINENO: + //buf_strdefine(&userdef_buf, "YY_NO_GET_LINENO", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_GET_LINENO", 0); + break; + case OPT_NO_YYSET_LINENO: + //buf_strdefine(&userdef_buf, "YY_NO_SET_LINENO", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_SET_LINENO", 0); + break; + case OPT_NO_YYGET_IN: + //buf_strdefine(&userdef_buf, "YY_NO_GET_IN", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_GET_IN", 0); + break; + case OPT_NO_YYSET_IN: + //buf_strdefine(&userdef_buf, "YY_NO_SET_IN", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_SET_IN", 0); + break; + case OPT_NO_YYGET_OUT: + //buf_strdefine(&userdef_buf, "YY_NO_GET_OUT", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_GET_OUT", 0); + break; + case OPT_NO_YYSET_OUT: + //buf_strdefine(&userdef_buf, "YY_NO_SET_OUT", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_SET_OUT", 0); + break; + case OPT_NO_YYGET_LVAL: + //buf_strdefine(&userdef_buf, "YY_NO_GET_LVAL", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_GET_LVAL", 0); + break; + case OPT_NO_YYSET_LVAL: + //buf_strdefine(&userdef_buf, "YY_NO_SET_LVAL", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_SET_LVAL", 0); + break; + case OPT_NO_YYGET_LLOC: + //buf_strdefine(&userdef_buf, "YY_NO_GET_LLOC", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_GET_LLOC", 0); + break; + case OPT_NO_YYSET_LLOC: + //buf_strdefine(&userdef_buf, "YY_NO_SET_LLOC", "1"); + buf_m4_define(&m4defs_buf, "M4_YY_NO_SET_LLOC", 0); + break; + + } /* switch */ + } /* while scanopt() */ + + scanopt_destroy(sopt); + + num_input_files = argc - optind; + input_files = argv + optind; + set_input_file(num_input_files > 0 ? input_files[0] : NULL); + + lastccl = lastsc = lastdfa = lastnfa = 0; + num_rules = num_eof_rules = default_rule = 0; + numas = numsnpairs = tmpuses = 0; + numecs = numeps = eps2 = num_reallocs = hshcol = dfaeql = totnst = + 0; + numuniq = numdup = hshsave = eofseen = datapos = dataline = 0; + num_backing_up = onesp = numprots = 0; + variable_trailing_context_rules = bol_needed = false; + + linenum = sectnum = 1; + firstprot = NIL; + + /* + * Used in mkprot() so that the first proto goes in slot 1 of the + * proto queue. + */ + lastprot = 1; + + set_up_initial_allocations(); +} + + +/* readin - read in the rules section of the input file(s) */ + +void +readin() +{ + static char yy_stdinit[] = "FILE *yyin = stdin, *yyout = stdout;"; + static char yy_nostdinit[] = + "FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;"; + + line_directive_out((FILE *) 0, 1); + + if (yyparse()) { + pinpoint_message(_("fatal parse error")); + flexend(1); + } + if (syntaxerror) + flexend(1); + + /* + * If the user explicitly requested posix compatibility by specifing + * the posix-compat option, then we check for conflicting options. + * However, if the POSIXLY_CORRECT variable is set, then we quietly + * make flex as posix-compatible as possible. This is the + * recommended behavior according to the GNU Coding Standards. + * + * Note: The posix option was added to flex to provide the posix + * behavior of the repeat operator in regular expressions, e.g., + * `ab{3}' + */ + if (posix_compat) { + /* + * TODO: This is where we try to make flex behave according + * to posiz, AND check for conflicting options. How far + * should we go with this? Should we disable all the neat-o + * flex features? + */ + /* + * Update: Estes says no, since other flex features don't + * violate posix. + */ + } + if (getenv("POSIXLY_CORRECT")) { + posix_compat = true; + } + if (backing_up_report) { + backing_up_file = fopen(backing_name, "w"); + if (backing_up_file == NULL) + lerrsf(_ + ("could not create backing-up info file %s"), + backing_name); + } else + backing_up_file = NULL; + + if (yymore_really_used == true) + yymore_used = true; + else if (yymore_really_used == false) + yymore_used = false; + + if (reject_really_used == true) + reject = true; + else if (reject_really_used == false) + reject = false; + + if (performance_report > 0) { + if (lex_compat) { + fprintf(stderr, + _ + ("-l AT&T lex compatibility option entails a large performance penalty\n")); + fprintf(stderr, + _ + (" and may be the actual source of other reported performance penalties\n")); + } else if (do_yylineno) { + fprintf(stderr, + _ + ("%%option yylineno entails a performance penalty ONLY on rules that can match newline characters\n")); + } + if (performance_report > 1) { + if (interactive) + fprintf(stderr, + _ + ("-I (interactive) entails a minor performance penalty\n")); + + if (yymore_used) + fprintf(stderr, + _ + ("yymore() entails a minor performance penalty\n")); + } + if (reject) + fprintf(stderr, + _ + ("REJECT entails a large performance penalty\n")); + + if (variable_trailing_context_rules) + fprintf(stderr, + _ + ("Variable trailing context rules entail a large performance penalty\n")); + } + if (reject) + real_reject = true; + + if (variable_trailing_context_rules) + reject = true; + + if ((fulltbl || fullspd) && reject) { + if (real_reject) + flexerror(_ + ("REJECT cannot be used with -f or -F")); + else if (do_yylineno) + flexerror(_ + ("%option yylineno cannot be used with REJECT")); + else + flexerror(_ + ("variable trailing context rules cannot be used with -f or -F")); + } + if (reject) { + out_m4_define("M4_YY_USES_REJECT", NULL); + //outn("\n#define YY_USES_REJECT"); + } + if (!do_yywrap) { + if (!C_plus_plus) { + if (reentrant) + outn("\n#define yywrap(yyscanner) 1"); + else + outn("\n#define yywrap() 1"); + } + outn("#define YY_SKIP_YYWRAP"); + } + if (ddebug) + outn("\n#define FLEX_DEBUG"); + + OUT_BEGIN_CODE(); + if (csize == 256) + outn("typedef unsigned char YY_CHAR;"); + else + outn("typedef char YY_CHAR;"); + OUT_END_CODE(); + + if (C_plus_plus) { + outn("#define yytext_ptr yytext"); + + if (interactive) + outn("#define YY_INTERACTIVE"); + } else { + OUT_BEGIN_CODE(); + /* In reentrant scanner, stdinit is handled in flex.skl. */ + if (do_stdinit) { + if (reentrant) { + outn("#define YY_STDINIT"); + } + outn(yy_stdinit); + } else { + if (!reentrant) + outn(yy_nostdinit); + } + OUT_END_CODE(); + } + + OUT_BEGIN_CODE(); + if (fullspd) + outn("typedef yyconst struct yy_trans_info *yy_state_type;"); + else if (!C_plus_plus) + outn("typedef int yy_state_type;"); + OUT_END_CODE(); + + if (lex_compat) + outn("#define YY_FLEX_LEX_COMPAT"); + + if (!C_plus_plus && !reentrant) { + outn("extern int yylineno;"); + OUT_BEGIN_CODE(); + outn("int yylineno = 1;"); + OUT_END_CODE(); + } + if (C_plus_plus) { + outn("\n#include \"third_party/lex/FlexLexer.h\""); + + if (!do_yywrap) { + outn("\nint yyFlexLexer::yywrap() { return 1; }"); + } + if (yyclass) { + outn("int yyFlexLexer::yylex()"); + outn("\t{"); + outn("\tLexerError( \"yyFlexLexer::yylex invoked but %option yyclass used\" );"); + outn("\treturn 0;"); + outn("\t}"); + + out_str("\n#define YY_DECL int %s::yylex()\n", + yyclass); + } + } else { + + /* + * Watch out: yytext_ptr is a variable when yytext is an + * array, but it's a macro when yytext is a pointer. + */ + if (yytext_is_array) { + if (!reentrant) + outn("extern char yytext[];\n"); + } else { + if (reentrant) { + outn("#define yytext_ptr yytext_r"); + } else { + outn("extern char *yytext;"); + outn("#define yytext_ptr yytext"); + } + } + + if (yyclass) + flexerror(_ + ("%option yyclass only meaningful for C++ scanners")); + } + + if (useecs) + numecs = cre8ecs(nextecm, ecgroup, csize); + else + numecs = csize; + + /* Now map the equivalence class for NUL to its expected place. */ + ecgroup[0] = ecgroup[csize]; + NUL_ec = ABS(ecgroup[0]); + + if (useecs) + ccl2ecl(); +} + + +/* set_up_initial_allocations - allocate memory for internal tables */ + +void +set_up_initial_allocations() +{ + maximum_mns = (long_align ? MAXIMUM_MNS_LONG : MAXIMUM_MNS); + current_mns = INITIAL_MNS; + firstst = allocate_integer_array(current_mns); + lastst = allocate_integer_array(current_mns); + finalst = allocate_integer_array(current_mns); + transchar = allocate_integer_array(current_mns); + trans1 = allocate_integer_array(current_mns); + trans2 = allocate_integer_array(current_mns); + accptnum = allocate_integer_array(current_mns); + assoc_rule = allocate_integer_array(current_mns); + state_type = allocate_integer_array(current_mns); + + current_max_rules = INITIAL_MAX_RULES; + rule_type = allocate_integer_array(current_max_rules); + rule_linenum = allocate_integer_array(current_max_rules); + rule_useful = allocate_integer_array(current_max_rules); + rule_has_nl = allocate_bool_array(current_max_rules); + + current_max_scs = INITIAL_MAX_SCS; + scset = allocate_integer_array(current_max_scs); + scbol = allocate_integer_array(current_max_scs); + scxclu = allocate_integer_array(current_max_scs); + sceof = allocate_integer_array(current_max_scs); + scname = allocate_char_ptr_array(current_max_scs); + + current_maxccls = INITIAL_MAX_CCLS; + cclmap = allocate_integer_array(current_maxccls); + ccllen = allocate_integer_array(current_maxccls); + cclng = allocate_integer_array(current_maxccls); + ccl_has_nl = allocate_bool_array(current_maxccls); + + current_max_ccl_tbl_size = INITIAL_MAX_CCL_TBL_SIZE; + ccltbl = allocate_Character_array(current_max_ccl_tbl_size); + + current_max_dfa_size = INITIAL_MAX_DFA_SIZE; + + current_max_xpairs = INITIAL_MAX_XPAIRS; + nxt = allocate_integer_array(current_max_xpairs); + chk = allocate_integer_array(current_max_xpairs); + + current_max_template_xpairs = INITIAL_MAX_TEMPLATE_XPAIRS; + tnxt = allocate_integer_array(current_max_template_xpairs); + + current_max_dfas = INITIAL_MAX_DFAS; + base = allocate_integer_array(current_max_dfas); + def = allocate_integer_array(current_max_dfas); + dfasiz = allocate_integer_array(current_max_dfas); + accsiz = allocate_integer_array(current_max_dfas); + dhash = allocate_integer_array(current_max_dfas); + dss = allocate_int_ptr_array(current_max_dfas); + dfaacc = allocate_dfaacc_union(current_max_dfas); + + nultrans = (int *) 0; +} + + +/* extracts basename from path, optionally stripping the extension "\.*" + * (same concept as /bin/sh `basename`, but different handling of extension). */ +static char * +basename2(path, strip_ext) + char *path; + int strip_ext; /* boolean */ +{ + char *b, *e = 0; + + b = path; + for (b = path; *path; path++) + if (*path == '/') + b = path + 1; + else if (*path == '.') + e = path; + + if (strip_ext && e && e > b) + *e = '\0'; + return b; +} + +void +usage() +{ + FILE *f = stdout; + + if (!did_outfilename) { + snprintf(outfile_path, sizeof(outfile_path), outfile_template, + prefix, C_plus_plus ? "cc" : "c"); + outfilename = outfile_path; + } + fprintf(f, _("Usage: %s [OPTIONS] [FILE]...\n"), program_name); + fprintf(f, + _ + ("Generates programs that perform pattern-matching on text.\n" + "\n" "Table Compression:\n" + " -Ca, --align trade off larger tables for better memory alignment\n" + " -Ce, --ecs construct equivalence classes\n" + " -Cf do not compress tables; use -f representation\n" + " -CF do not compress tables; use -F representation\n" + " -Cm, --meta-ecs construct meta-equivalence classes\n" + " -Cr, --read use read() instead of stdio for scanner input\n" + " -f, --full generate fast, large scanner. Same as -Cfr\n" + " -F, --fast use alternate table representation. Same as -CFr\n" + " -Cem default compression (same as --ecs --meta-ecs)\n" + "\n" "Debugging:\n" + " -d, --debug enable debug mode in scanner\n" + " -b, --backup write backing-up information to %s\n" + " -p, --perf-report write performance report to stderr\n" + " -s, --nodefault suppress default rule to ECHO unmatched text\n" + " -T, --trace %s should run in trace mode\n" + " -w, --nowarn do not generate warnings\n" + " -v, --verbose write summary of scanner statistics to stdout\n" + "\n" "Files:\n" + " -o, --outfile=FILE specify output filename\n" + " -S, --skel=FILE specify skeleton file\n" + " -t, --stdout write scanner on stdout instead of %s\n" + " --yyclass=NAME name of C++ class\n" + " --header-file=FILE create a C header file in addition to the scanner\n" + " --tables-file[=FILE] write tables to FILE\n" "\n" + "Scanner behavior:\n" + " -7, --7bit generate 7-bit scanner\n" + " -8, --8bit generate 8-bit scanner\n" + " -B, --batch generate batch scanner (opposite of -I)\n" + " -i, --case-insensitive ignore case in patterns\n" + " -l, --lex-compat maximal compatibility with original lex\n" + " -X, --posix-compat maximal compatibility with POSIX lex\n" + " -I, --interactive generate interactive scanner (opposite of -B)\n" + " --yylineno track line count in yylineno\n" + "\n" "Generated code:\n" + " -+, --c++ generate C++ scanner class\n" + " -Dmacro[=defn] #define macro defn (default defn is '1')\n" + " -L, --noline suppress #line directives in scanner\n" + " -P, --prefix=STRING use STRING as prefix instead of \"yy\"\n" + " -R, --reentrant generate a reentrant C scanner\n" + " --bison-bridge scanner for bison pure parser.\n" + " --bison-locations include yylloc support.\n" + " --stdinit initialize yyin/yyout to stdin/stdout\n" + " --noansi-definitions old-style function definitions\n" + " --noansi-prototypes empty parameter list in prototypes\n" + " --nounistd do not include \n" + " --noFUNCTION do not generate a particular FUNCTION\n" + "\n" "Miscellaneous:\n" + " -n do-nothing POSIX option\n" + " -?\n" + " -h, --help produce this help message\n" + " -V, --version report %s version\n"), + backing_name, program_name, outfile_path, program_name); + +} diff --git a/third_party/lex/misc.c b/third_party/lex/misc.c new file mode 100644 index 00000000..2e5aa36a --- /dev/null +++ b/third_party/lex/misc.c @@ -0,0 +1,1017 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 sw=8 fenc=utf-8 :vi│ +└─────────────────────────────────────────────────────────────────────────────*/ + +/* clang-format off */ +/* $OpenBSD: misc.c,v 1.19 2015/11/19 23:34:56 mmcc Exp $ */ + +/* misc - miscellaneous flex routines */ + +/* Copyright (c) 1990 The Regents of the University of California. */ +/* All rights reserved. */ + +/* This code is derived from software contributed to Berkeley by */ +/* Vern Paxson. */ + +/* The United States Government has rights in this work pursuant */ +/* to contract no. DE-AC03-76SF00098 between the United States */ +/* Department of Energy and the University of California. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + +#include "flexdef.h" +#include "libc/mem/mem.h" +#include "libc/str/str.h" +#include "libc/fmt/fmt.h" +#include "tables.h" + +#define CMD_IF_TABLES_SER "%if-tables-serialization" +#define CMD_TABLES_YYDMAP "%tables-yydmap" +#define CMD_DEFINE_YYTABLES "%define-yytables" +#define CMD_IF_CPP_ONLY "%if-c++-only" +#define CMD_IF_C_ONLY "%if-c-only" +#define CMD_IF_C_OR_CPP "%if-c-or-c++" +#define CMD_NOT_FOR_HEADER "%not-for-header" +#define CMD_OK_FOR_HEADER "%ok-for-header" +#define CMD_PUSH "%push" +#define CMD_POP "%pop" +#define CMD_IF_REENTRANT "%if-reentrant" +#define CMD_IF_NOT_REENTRANT "%if-not-reentrant" +#define CMD_IF_BISON_BRIDGE "%if-bison-bridge" +#define CMD_IF_NOT_BISON_BRIDGE "%if-not-bison-bridge" +#define CMD_ENDIF "%endif" + +/* we allow the skeleton to push and pop. */ +struct sko_state { + bool dc; /**< do_copy */ +}; +static struct sko_state *sko_stack = 0; +static int sko_len = 0, sko_sz = 0; +static void +sko_push(bool dc) +{ + if (!sko_stack) { + sko_sz = 1; + sko_stack = malloc(sizeof(struct sko_state) * sko_sz); + if (!sko_stack) + flexfatal(_("allocation of sko_stack failed")); + sko_len = 0; + } + if (sko_len >= sko_sz) { + sko_sz *= 2; + sko_stack = realloc(sko_stack, sizeof(struct sko_state) * sko_sz); + } + /* initialize to zero and push */ + sko_stack[sko_len].dc = dc; + sko_len++; +} +static void +sko_peek(bool * dc) +{ + if (sko_len <= 0) + flex_die("peek attempt when sko stack is empty"); + if (dc) + *dc = sko_stack[sko_len - 1].dc; +} +static void +sko_pop(bool * dc) +{ + sko_peek(dc); + sko_len--; + if (sko_len < 0) + flex_die("popped too many times in skeleton."); +} + +/* Append "#define defname value\n" to the running buffer. */ +void +action_define(defname, value) + const char *defname; + int value; +{ + char buf[MAXLINE]; + char *cpy; + + if ((int) strlen(defname) > MAXLINE / 2) { + format_pinpoint_message(_ + ("name \"%s\" ridiculously long"), + defname); + return; + } + snprintf(buf, sizeof(buf), "#define %s %d\n", defname, value); + add_action(buf); + + /* track #defines so we can undef them when we're done. */ + cpy = copy_string(defname); + buf_append(&defs_buf, &cpy, 1); +} + + +/** Append "m4_define([[defname]],[[value]])m4_dnl\n" to the running buffer. + * @param defname The macro name. + * @param value The macro value, can be NULL, which is the same as the empty string. + */ +void +action_m4_define(const char *defname, const char *value) +{ + char buf[MAXLINE]; + + flexfatal("DO NOT USE THIS FUNCTION!"); + + if ((int) strlen(defname) > MAXLINE / 2) { + format_pinpoint_message(_ + ("name \"%s\" ridiculously long"), + defname); + return; + } + snprintf(buf, sizeof(buf), "m4_define([[%s]],[[%s]])m4_dnl\n", defname, value ? value : ""); + add_action(buf); +} + +/* Append "new_text" to the running buffer. */ +void +add_action(new_text) + const char *new_text; +{ + int len = strlen(new_text); + + while (len + action_index >= action_size - 10 /* slop */ ) { + int new_size = action_size * 2; + + if (new_size <= 0) + /* + * Increase just a little, to try to avoid overflow + * on 16-bit machines. + */ + action_size += action_size / 8; + else + action_size = new_size; + + action_array = + reallocate_character_array(action_array, + action_size); + } + + strlcpy(&action_array[action_index], new_text, + action_size - action_index); + + action_index += len; +} + + +/* allocate_array - allocate memory for an integer array of the given size */ + +void * +allocate_array(size, element_size) + int size; + size_t element_size; +{ + void *mem; + size_t num_bytes = element_size * size; + + mem = malloc(num_bytes); + if (!mem) + flexfatal(_ + ("memory allocation failed in allocate_array()")); + + return mem; +} + + +/* all_lower - true if a string is all lower-case */ + +int +all_lower(str) + char *str; +{ + while (*str) { + if (!isascii((u_char) * str) || !islower((u_char) * str)) + return 0; + ++str; + } + + return 1; +} + + +/* all_upper - true if a string is all upper-case */ + +int +all_upper(str) + char *str; +{ + while (*str) { + if (!isascii((u_char) * str) || !isupper((u_char) * str)) + return 0; + ++str; + } + + return 1; +} + + +/* intcmp - compares two integers for use by qsort. */ + +int +intcmp(const void *a, const void *b) +{ + return *(const int *) a - *(const int *) b; +} + + +/* check_char - checks a character to make sure it's within the range + * we're expecting. If not, generates fatal error message + * and exits. + */ + +void +check_char(c) + int c; +{ + if (c >= CSIZE) + lerrsf(_("bad character '%s' detected in check_char()"), + readable_form(c)); + + if (c >= csize) + lerrsf(_ + ("scanner requires -8 flag to use the character %s"), + readable_form(c)); +} + + + +/* clower - replace upper-case letter to lower-case */ + +u_char +clower(c) + int c; +{ + return (u_char) ((isascii(c) && isupper(c)) ? tolower(c) : c); +} + + +/* copy_string - returns a dynamically allocated copy of a string */ + +char * +copy_string(str) + const char *str; +{ + const char *c1; + char *c2; + char *copy; + unsigned int size; + + /* find length */ + for (c1 = str; *c1; ++c1); + + size = (c1 - str + 1) * sizeof(char); + + copy = (char *) malloc(size); + + if (copy == NULL) + flexfatal(_("dynamic memory failure in copy_string()")); + + for (c2 = copy; (*c2++ = *str++) != 0;); + + return copy; +} + + +/* copy_unsigned_string - + * returns a dynamically allocated copy of a (potentially) unsigned string + */ + +u_char * +copy_unsigned_string(str) + u_char *str; +{ + u_char *c; + u_char *copy; + + /* find length */ + for (c = str; *c; ++c); + + copy = allocate_Character_array(c - str + 1); + + for (c = copy; (*c++ = *str++) != 0;); + + return copy; +} + + +/* cclcmp - compares two characters for use by qsort with '\0' sorting last. */ + +int +cclcmp(const void *a, const void *b) +{ + if (!*(const u_char *) a) + return 1; + else if (!*(const u_char *) b) + return -1; + else + return *(const u_char *) a - *(const u_char *) b; +} + + +/* dataend - finish up a block of data declarations */ + +void +dataend() +{ + /* short circuit any output */ + if (gentables) { + + if (datapos > 0) + dataflush(); + + /* add terminator for initialization; { for vi */ + outn(" } ;\n"); + } + dataline = 0; + datapos = 0; +} + + +/* dataflush - flush generated data statements */ + +void +dataflush() +{ + /* short circuit any output */ + if (!gentables) + return; + + outc('\n'); + + if (++dataline >= NUMDATALINES) { + /* + * Put out a blank line so that the table is grouped into + * large blocks that enable the user to find elements easily. + */ + outc('\n'); + dataline = 0; + } + /* Reset the number of characters written on the current line. */ + datapos = 0; +} + + +/* flexerror - report an error message and terminate */ + +void +flexerror(msg) + const char *msg; +{ + fprintf(stderr, "%s: %s\n", program_name, msg); + flexend(1); +} + + +/* flexfatal - report a fatal error message and terminate */ + +void +flexfatal(msg) + const char *msg; +{ + fprintf(stderr, _("%s: fatal internal error, %s\n"), + program_name, msg); + FLEX_EXIT(1); +} + + +/* htoi - convert a hexadecimal digit string to an integer value */ + +int +htoi(str) + u_char str[]; +{ + unsigned int result; + + (void) sscanf((char *) str, "%x", &result); + + return result; +} + + +/* lerrif - report an error message formatted with one integer argument */ + +void +lerrif(msg, arg) + const char *msg; + int arg; +{ + char errmsg[MAXLINE]; + + snprintf(errmsg, sizeof(errmsg), msg, arg); + flexerror(errmsg); +} + + +/* lerrsf - report an error message formatted with one string argument */ + +void +lerrsf(msg, arg) + const char *msg, arg[]; +{ + char errmsg[MAXLINE]; + + snprintf(errmsg, sizeof(errmsg) - 1, msg, arg); + errmsg[sizeof(errmsg) - 1] = 0; /* ensure NULL termination */ + flexerror(errmsg); +} + + +/* lerrsf_fatal - as lerrsf, but call flexfatal */ + +void +lerrsf_fatal(msg, arg) + const char *msg, arg[]; +{ + char errmsg[MAXLINE]; + + snprintf(errmsg, sizeof(errmsg) - 1, msg, arg); + errmsg[sizeof(errmsg) - 1] = 0; /* ensure NULL termination */ + flexfatal(errmsg); +} + + +/* line_directive_out - spit out a "#line" statement */ + +void +line_directive_out(output_file, do_infile) + FILE *output_file; + int do_infile; +{ + char directive[MAXLINE + 128], filename[MAXLINE]; + char *s1, *s2, *s3; + static const char *line_fmt = "#line %d \"%s\"\n"; + + if (!gen_line_dirs) + return; + + s1 = do_infile ? infilename : "M4_YY_OUTFILE_NAME"; + + if (do_infile && !s1) + s1 = ""; + + s2 = filename; + s3 = &filename[sizeof(filename) - 2]; + + while (s2 < s3 && *s1) { + if (*s1 == '\\') + /* Escape the '\' */ + *s2++ = '\\'; + + *s2++ = *s1++; + } + + *s2 = '\0'; + + if (do_infile) + snprintf(directive, sizeof(directive), line_fmt, linenum, filename); + else { + snprintf(directive, sizeof(directive), line_fmt, 0, filename); + } + + /* + * If output_file is nil then we should put the directive in the + * accumulated actions. + */ + if (output_file) { + fputs(directive, output_file); + } else + add_action(directive); +} + + +/* mark_defs1 - mark the current position in the action array as + * representing where the user's section 1 definitions end + * and the prolog begins + */ +void +mark_defs1() +{ + defs1_offset = 0; + action_array[action_index++] = '\0'; + action_offset = prolog_offset = action_index; + action_array[action_index] = '\0'; +} + + +/* mark_prolog - mark the current position in the action array as + * representing the end of the action prolog + */ +void +mark_prolog() +{ + action_array[action_index++] = '\0'; + action_offset = action_index; + action_array[action_index] = '\0'; +} + + +/* mk2data - generate a data statement for a two-dimensional array + * + * Generates a data statement initializing the current 2-D array to "value". + */ +void +mk2data(value) + int value; +{ + /* short circuit any output */ + if (!gentables) + return; + + if (datapos >= NUMDATAITEMS) { + outc(','); + dataflush(); + } + if (datapos == 0) + /* Indent. */ + out(" "); + + else + outc(','); + + ++datapos; + + out_dec("%5d", value); +} + + +/* mkdata - generate a data statement + * + * Generates a data statement initializing the current array element to + * "value". + */ +void +mkdata(value) + int value; +{ + /* short circuit any output */ + if (!gentables) + return; + + if (datapos >= NUMDATAITEMS) { + outc(','); + dataflush(); + } + if (datapos == 0) + /* Indent. */ + out(" "); + else + outc(','); + + ++datapos; + + out_dec("%5d", value); +} + + +/* myctoi - return the integer represented by a string of digits */ + +int +myctoi(array) + const char *array; +{ + int val = 0; + + (void) sscanf(array, "%d", &val); + + return val; +} + + +/* myesc - return character corresponding to escape sequence */ + +u_char +myesc(array) + u_char array[]; +{ + u_char c, esc_char; + + switch (array[1]) { + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + +#if defined (__STDC__) + case 'a': + return '\a'; + case 'v': + return '\v'; +#else + case 'a': + return '\007'; + case 'v': + return '\013'; +#endif + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { /* \ */ + int sptr = 1; + + while (isascii(array[sptr]) && + isdigit(array[sptr])) + /* + * Don't increment inside loop control + * because if isdigit() is a macro it might + * expand into multiple increments ... + */ + ++sptr; + + c = array[sptr]; + array[sptr] = '\0'; + + esc_char = otoi(array + 1); + + array[sptr] = c; + + return esc_char; + } + + case 'x': + { /* \x */ + int sptr = 2; + + while (isascii(array[sptr]) && + isxdigit(array[sptr])) + /* + * Don't increment inside loop control + * because if isdigit() is a macro it might + * expand into multiple increments ... + */ + ++sptr; + + c = array[sptr]; + array[sptr] = '\0'; + + esc_char = htoi(array + 2); + + array[sptr] = c; + + return esc_char; + } + + default: + return array[1]; + } +} + + +/* otoi - convert an octal digit string to an integer value */ + +int +otoi(str) + u_char str[]; +{ + unsigned int result; + + (void) sscanf((char *) str, "%o", &result); + return result; +} + + +/* out - various flavors of outputing a (possibly formatted) string for the + * generated scanner, keeping track of the line count. + */ + +void +out(str) + const char *str; +{ + fputs(str, stdout); +} + +void +out_dec(fmt, n) + const char *fmt; + int n; +{ + fprintf(stdout, fmt, n); +} + +void +out_dec2(fmt, n1, n2) + const char *fmt; + int n1, n2; +{ + fprintf(stdout, fmt, n1, n2); +} + +void +out_hex(fmt, x) + const char *fmt; + unsigned int x; +{ + fprintf(stdout, fmt, x); +} + +void +out_str(fmt, str) + const char *fmt, str[]; +{ + fprintf(stdout, fmt, str); +} + +void +out_str3(fmt, s1, s2, s3) + const char *fmt, s1[], s2[], s3[]; +{ + fprintf(stdout, fmt, s1, s2, s3); +} + +void +out_str_dec(fmt, str, n) + const char *fmt, str[]; + int n; +{ + fprintf(stdout, fmt, str, n); +} + +void +outc(c) + int c; +{ + fputc(c, stdout); +} + +void +outn(str) + const char *str; +{ + fputs(str, stdout); + fputc('\n', stdout); +} + +/** Print "m4_define( [[def]], [[val]])m4_dnl\n". + * @param def The m4 symbol to define. + * @param val The definition; may be NULL. + * @return buf + */ +void +out_m4_define(const char *def2, const char *val) +{ + const char *fmt = "m4_define( [[%s]], [[%s]])m4_dnl\n"; + fprintf(stdout, fmt, def2, val ? val : ""); +} + + +/* readable_form - return the human-readable form of a character + * + * The returned string is in static storage. + */ + +char * +readable_form(c) + int c; +{ + static char rform[10]; + + if ((c >= 0 && c < 32) || c >= 127) { + switch (c) { + case '\b': + return "\\b"; + case '\f': + return "\\f"; + case '\n': + return "\\n"; + case '\r': + return "\\r"; + case '\t': + return "\\t"; + +#if defined (__STDC__) + case '\a': + return "\\a"; + case '\v': + return "\\v"; +#endif + + default: + snprintf(rform, sizeof(rform), "\\%.3o", (unsigned int) c); + return rform; + } + } else if (c == ' ') + return "' '"; + + else { + rform[0] = c; + rform[1] = '\0'; + + return rform; + } +} + + +/* reallocate_array - increase the size of a dynamic array */ + +void * +reallocate_array(array, size, element_size) + void *array; + int size; + size_t element_size; +{ + void *new_array; + size_t num_bytes = element_size * size; + + new_array = realloc(array, num_bytes); + if (!new_array) + flexfatal(_("attempt to increase array size failed")); + + return new_array; +} + + +/* skelout - write out one section of the skeleton file + * + * Description + * Copies skelfile or skel array to stdout until a line beginning with + * "%%" or EOF is found. + */ +void +skelout() +{ + char buf_storage[MAXLINE]; + char *buf = buf_storage; + bool do_copy = true; + + /* "reset" the state by clearing the buffer and pushing a '1' */ + if (sko_len > 0) + sko_peek(&do_copy); + sko_len = 0; + sko_push(do_copy = true); + + + /* + * Loop pulling lines either from the skelfile, if we're using one, + * or from the skel[] array. + */ + while (skelfile ? + (fgets(buf, MAXLINE, skelfile) != NULL) : + ((buf = (char *) skel[skel_ind++]) != 0)) { + + if (skelfile) + chomp(buf); + + /* copy from skel array */ + if (buf[0] == '%') { /* control line */ + /* print the control line as a comment. */ + if (ddebug && buf[1] != '#') { + if (buf[strlen(buf) - 1] == '\\') + out_str("/* %s */\\\n", buf); + else + out_str("/* %s */\n", buf); + } + /* + * We've been accused of using cryptic markers in the + * skel. So we'll use + * emacs-style-hyphenated-commands. We might consider + * a hash if this if-else-if-else chain gets too + * large. + */ +#define cmd_match(s) (strncmp(buf,(s),strlen(s))==0) + + if (buf[1] == '%') { + /* %% is a break point for skelout() */ + return; + } else if (cmd_match(CMD_PUSH)) { + sko_push(do_copy); + if (ddebug) { + out_str("/*(state = (%s) */", do_copy ? "true" : "false"); + } + out_str("%s\n", buf[strlen(buf) - 1] == '\\' ? "\\" : ""); + } else if (cmd_match(CMD_POP)) { + sko_pop(&do_copy); + if (ddebug) { + out_str("/*(state = (%s) */", do_copy ? "true" : "false"); + } + out_str("%s\n", buf[strlen(buf) - 1] == '\\' ? "\\" : ""); + } else if (cmd_match(CMD_IF_REENTRANT)) { + sko_push(do_copy); + do_copy = reentrant && do_copy; + } else if (cmd_match(CMD_IF_NOT_REENTRANT)) { + sko_push(do_copy); + do_copy = !reentrant && do_copy; + } else if (cmd_match(CMD_IF_BISON_BRIDGE)) { + sko_push(do_copy); + do_copy = bison_bridge_lval && do_copy; + } else if (cmd_match(CMD_IF_NOT_BISON_BRIDGE)) { + sko_push(do_copy); + do_copy = !bison_bridge_lval && do_copy; + } else if (cmd_match(CMD_ENDIF)) { + sko_pop(&do_copy); + } else if (cmd_match(CMD_IF_TABLES_SER)) { + do_copy = do_copy && tablesext; + } else if (cmd_match(CMD_TABLES_YYDMAP)) { + if (tablesext && yydmap_buf.elts) + outn((char *) (yydmap_buf.elts)); + } else if (cmd_match(CMD_DEFINE_YYTABLES)) { + out_str("#define YYTABLES_NAME \"%s\"\n", + tablesname ? tablesname : "yytables"); + } else if (cmd_match(CMD_IF_CPP_ONLY)) { + /* only for C++ */ + sko_push(do_copy); + do_copy = C_plus_plus; + } else if (cmd_match(CMD_IF_C_ONLY)) { + /* %- only for C */ + sko_push(do_copy); + do_copy = !C_plus_plus; + } else if (cmd_match(CMD_IF_C_OR_CPP)) { + /* %* for C and C++ */ + sko_push(do_copy); + do_copy = true; + } else if (cmd_match(CMD_NOT_FOR_HEADER)) { + /* %c begin linkage-only (non-header) code. */ + OUT_BEGIN_CODE(); + } else if (cmd_match(CMD_OK_FOR_HEADER)) { + /* %e end linkage-only code. */ + OUT_END_CODE(); + } else if (buf[1] == '#') { + /* %# a comment in the skel. ignore. */ + } else { + flexfatal(_("bad line in skeleton file")); + } + } else if (do_copy) + outn(buf); + } /* end while */ +} + + +/* transition_struct_out - output a yy_trans_info structure + * + * outputs the yy_trans_info structure with the two elements, element_v and + * element_n. Formats the output with spaces and carriage returns. + */ + +void +transition_struct_out(element_v, element_n) + int element_v, element_n; +{ + + /* short circuit any output */ + if (!gentables) + return; + + out_dec2(" {%4d,%4d },", element_v, element_n); + + datapos += TRANS_STRUCT_PRINT_LENGTH; + + if (datapos >= 79 - TRANS_STRUCT_PRINT_LENGTH) { + outc('\n'); + + if (++dataline % 10 == 0) + outc('\n'); + + datapos = 0; + } +} + + +/* The following is only needed when building flex's parser using certain + * broken versions of bison. + */ +void * +yy_flex_xmalloc(size) + int size; +{ + void *result = malloc((size_t) size); + + if (!result) + flexfatal(_ + ("memory allocation failed in yy_flex_xmalloc()")); + + return result; +} diff --git a/third_party/lex/mkskel.sh b/third_party/lex/mkskel.sh new file mode 100644 index 00000000..9a8b02e1 --- /dev/null +++ b/third_party/lex/mkskel.sh @@ -0,0 +1,38 @@ +#! /bin/sh +# $OpenBSD: mkskel.sh,v 1.3 2015/11/19 19:43:40 tedu Exp $ + +# This file is part of flex. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: + +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. + +# Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. + +# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE. + +cat < 0) + fprintf(stderr, + _ + ("Variable trailing context rule at line %d\n"), + rule_linenum[num_rules]); + + variable_trailing_context_rules = true; + } else { + rule_type[num_rules] = RULE_NORMAL; + + if (headcnt > 0 || trailcnt > 0) { + /* + * Do trailing context magic to not match the + * trailing characters. + */ + char *scanner_cp = "YY_G(yy_c_buf_p) = yy_cp"; + char *scanner_bp = "yy_bp"; + + add_action + ("*yy_cp = YY_G(yy_hold_char); /* undo effects of setting up yytext */\n"); + + if (headcnt > 0) { + if (rule_has_nl[num_rules]) { + snprintf(action_text, sizeof(action_text), + "YY_LINENO_REWIND_TO(%s + %d);\n", scanner_bp, headcnt); + add_action(action_text); + } + snprintf(action_text, sizeof(action_text), "%s = %s + %d;\n", + scanner_cp, scanner_bp, headcnt); + add_action(action_text); + } else { + if (rule_has_nl[num_rules]) { + snprintf(action_text, sizeof(action_text), + "YY_LINENO_REWIND_TO(yy_cp - %d);\n", trailcnt); + add_action(action_text); + } + snprintf(action_text, sizeof(action_text), "%s -= %d;\n", + scanner_cp, trailcnt); + add_action(action_text); + } + + add_action + ("YY_DO_BEFORE_ACTION; /* set up yytext again */\n"); + } + } + + /* + * Okay, in the action code at this point yytext and yyleng have + * their proper final values for this rule, so here's the point to do + * any user action. But don't do it for continued actions, as + * that'll result in multiple YY_RULE_SETUP's. + */ + if (!continued_action) + add_action("YY_RULE_SETUP\n"); + + line_directive_out((FILE *) 0, 1); +} + + +/* link_machines - connect two machines together + * + * synopsis + * + * new = link_machines( first, last ); + * + * new - a machine constructed by connecting first to last + * first - the machine whose successor is to be last + * last - the machine whose predecessor is to be first + * + * note: this routine concatenates the machine first with the machine + * last to produce a machine new which will pattern-match first first + * and then last, and will fail if either of the sub-patterns fails. + * FIRST is set to new by the operation. last is unmolested. + */ + +int +link_machines(first, last) + int first, last; +{ + if (first == NIL) + return last; + + else if (last == NIL) + return first; + + else { + mkxtion(finalst[first], last); + finalst[first] = finalst[last]; + lastst[first] = MAX(lastst[first], lastst[last]); + firstst[first] = MIN(firstst[first], firstst[last]); + + return first; + } +} + + +/* mark_beginning_as_normal - mark each "beginning" state in a machine + * as being a "normal" (i.e., not trailing context- + * associated) states + * + * The "beginning" states are the epsilon closure of the first state + */ + +void +mark_beginning_as_normal(mach) + int mach; +{ + switch (state_type[mach]) { + case STATE_NORMAL: + /* Oh, we've already visited here. */ + return; + + case STATE_TRAILING_CONTEXT: + state_type[mach] = STATE_NORMAL; + + if (transchar[mach] == SYM_EPSILON) { + if (trans1[mach] != NO_TRANSITION) + mark_beginning_as_normal(trans1[mach]); + + if (trans2[mach] != NO_TRANSITION) + mark_beginning_as_normal(trans2[mach]); + } + break; + + default: + flexerror(_ + ("bad state type in mark_beginning_as_normal()")); + break; + } +} + + +/* mkbranch - make a machine that branches to two machines + * + * synopsis + * + * branch = mkbranch( first, second ); + * + * branch - a machine which matches either first's pattern or second's + * first, second - machines whose patterns are to be or'ed (the | operator) + * + * Note that first and second are NEITHER destroyed by the operation. Also, + * the resulting machine CANNOT be used with any other "mk" operation except + * more mkbranch's. Compare with mkor() + */ + +int +mkbranch(first, second) + int first, second; +{ + int eps; + + if (first == NO_TRANSITION) + return second; + + else if (second == NO_TRANSITION) + return first; + + eps = mkstate(SYM_EPSILON); + + mkxtion(eps, first); + mkxtion(eps, second); + + return eps; +} + + +/* mkclos - convert a machine into a closure + * + * synopsis + * new = mkclos( state ); + * + * new - a new state which matches the closure of "state" + */ + +int +mkclos(state) + int state; +{ + return mkopt(mkposcl(state)); +} + + +/* mkopt - make a machine optional + * + * synopsis + * + * new = mkopt( mach ); + * + * new - a machine which optionally matches whatever mach matched + * mach - the machine to make optional + * + * notes: + * 1. mach must be the last machine created + * 2. mach is destroyed by the call + */ + +int +mkopt(mach) + int mach; +{ + int eps; + + if (!SUPER_FREE_EPSILON(finalst[mach])) { + eps = mkstate(SYM_EPSILON); + mach = link_machines(mach, eps); + } + /* + * Can't skimp on the following if FREE_EPSILON(mach) is true because + * some state interior to "mach" might point back to the beginning + * for a closure. + */ + eps = mkstate(SYM_EPSILON); + mach = link_machines(eps, mach); + + mkxtion(mach, finalst[mach]); + + return mach; +} + + +/* mkor - make a machine that matches either one of two machines + * + * synopsis + * + * new = mkor( first, second ); + * + * new - a machine which matches either first's pattern or second's + * first, second - machines whose patterns are to be or'ed (the | operator) + * + * note that first and second are both destroyed by the operation + * the code is rather convoluted because an attempt is made to minimize + * the number of epsilon states needed + */ + +int +mkor(first, second) + int first, second; +{ + int eps, orend; + + if (first == NIL) + return second; + + else if (second == NIL) + return first; + + else { + /* + * See comment in mkopt() about why we can't use the first + * state of "first" or "second" if they satisfy + * "FREE_EPSILON". + */ + eps = mkstate(SYM_EPSILON); + + first = link_machines(eps, first); + + mkxtion(first, second); + + if (SUPER_FREE_EPSILON(finalst[first]) && + accptnum[finalst[first]] == NIL) { + orend = finalst[first]; + mkxtion(finalst[second], orend); + } else if (SUPER_FREE_EPSILON(finalst[second]) && + accptnum[finalst[second]] == NIL) { + orend = finalst[second]; + mkxtion(finalst[first], orend); + } else { + eps = mkstate(SYM_EPSILON); + + first = link_machines(first, eps); + orend = finalst[first]; + + mkxtion(finalst[second], orend); + } + } + + finalst[first] = orend; + return first; +} + + +/* mkposcl - convert a machine into a positive closure + * + * synopsis + * new = mkposcl( state ); + * + * new - a machine matching the positive closure of "state" + */ + +int +mkposcl(state) + int state; +{ + int eps; + + if (SUPER_FREE_EPSILON(finalst[state])) { + mkxtion(finalst[state], state); + return state; + } else { + eps = mkstate(SYM_EPSILON); + mkxtion(eps, state); + return link_machines(state, eps); + } +} + + +/* mkrep - make a replicated machine + * + * synopsis + * new = mkrep( mach, lb, ub ); + * + * new - a machine that matches whatever "mach" matched from "lb" + * number of times to "ub" number of times + * + * note + * if "ub" is INFINITE_REPEAT then "new" matches "lb" or more occurrences of "mach" + */ + +int +mkrep(mach, lb, ub) + int mach, lb, ub; +{ + int base_mach, tail, copy, i; + + base_mach = copysingl(mach, lb - 1); + + if (ub == INFINITE_REPEAT) { + copy = dupmachine(mach); + mach = link_machines(mach, + link_machines(base_mach, + mkclos(copy))); + } else { + tail = mkstate(SYM_EPSILON); + + for (i = lb; i < ub; ++i) { + copy = dupmachine(mach); + tail = mkopt(link_machines(copy, tail)); + } + + mach = + link_machines(mach, + link_machines(base_mach, tail)); + } + + return mach; +} + + +/* mkstate - create a state with a transition on a given symbol + * + * synopsis + * + * state = mkstate( sym ); + * + * state - a new state matching sym + * sym - the symbol the new state is to have an out-transition on + * + * note that this routine makes new states in ascending order through the + * state array (and increments LASTNFA accordingly). The routine DUPMACHINE + * relies on machines being made in ascending order and that they are + * CONTIGUOUS. Change it and you will have to rewrite DUPMACHINE (kludge + * that it admittedly is) + */ + +int +mkstate(sym) + int sym; +{ + if (++lastnfa >= current_mns) { + if ((current_mns += MNS_INCREMENT) >= maximum_mns) + lerrif(_ + ("input rules are too complicated (>= %d NFA states)"), + current_mns); + + ++num_reallocs; + + firstst = reallocate_integer_array(firstst, current_mns); + lastst = reallocate_integer_array(lastst, current_mns); + finalst = reallocate_integer_array(finalst, current_mns); + transchar = + reallocate_integer_array(transchar, current_mns); + trans1 = reallocate_integer_array(trans1, current_mns); + trans2 = reallocate_integer_array(trans2, current_mns); + accptnum = + reallocate_integer_array(accptnum, current_mns); + assoc_rule = + reallocate_integer_array(assoc_rule, current_mns); + state_type = + reallocate_integer_array(state_type, current_mns); + } + firstst[lastnfa] = lastnfa; + finalst[lastnfa] = lastnfa; + lastst[lastnfa] = lastnfa; + transchar[lastnfa] = sym; + trans1[lastnfa] = NO_TRANSITION; + trans2[lastnfa] = NO_TRANSITION; + accptnum[lastnfa] = NIL; + assoc_rule[lastnfa] = num_rules; + state_type[lastnfa] = current_state_type; + + /* + * Fix up equivalence classes base on this transition. Note that any + * character which has its own transition gets its own equivalence + * class. Thus only characters which are only in character classes + * have a chance at being in the same equivalence class. E.g. "a|b" + * puts 'a' and 'b' into two different equivalence classes. "[ab]" + * puts them in the same equivalence class (barring other differences + * elsewhere in the input). + */ + + if (sym < 0) { + /* + * We don't have to update the equivalence classes since that + * was already done when the ccl was created for the first + * time. + */ + } else if (sym == SYM_EPSILON) + ++numeps; + + else { + check_char(sym); + + if (useecs) + /* Map NUL's to csize. */ + mkechar(sym ? sym : csize, nextecm, ecgroup); + } + + return lastnfa; +} + + +/* mkxtion - make a transition from one state to another + * + * synopsis + * + * mkxtion( statefrom, stateto ); + * + * statefrom - the state from which the transition is to be made + * stateto - the state to which the transition is to be made + */ + +void +mkxtion(statefrom, stateto) + int statefrom, stateto; +{ + if (trans1[statefrom] == NO_TRANSITION) + trans1[statefrom] = stateto; + + else if ((transchar[statefrom] != SYM_EPSILON) || + (trans2[statefrom] != NO_TRANSITION)) + flexfatal(_("found too many transitions in mkxtion()")); + + else { /* second out-transition for an epsilon state */ + ++eps2; + trans2[statefrom] = stateto; + } +} + +/* new_rule - initialize for a new rule */ + +void +new_rule() +{ + if (++num_rules >= current_max_rules) { + ++num_reallocs; + current_max_rules += MAX_RULES_INCREMENT; + rule_type = reallocate_integer_array(rule_type, + current_max_rules); + rule_linenum = reallocate_integer_array(rule_linenum, + current_max_rules); + rule_useful = reallocate_integer_array(rule_useful, + current_max_rules); + rule_has_nl = reallocate_bool_array(rule_has_nl, + current_max_rules); + } + if (num_rules > MAX_RULE) + lerrif(_("too many rules (> %d)!"), MAX_RULE); + + rule_linenum[num_rules] = linenum; + rule_useful[num_rules] = false; + rule_has_nl[num_rules] = false; +} diff --git a/third_party/lex/options.c b/third_party/lex/options.c new file mode 100644 index 00000000..14bf3ef6 --- /dev/null +++ b/third_party/lex/options.c @@ -0,0 +1,285 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 sw=8 fenc=utf-8 :vi│ +└─────────────────────────────────────────────────────────────────────────────*/ + +/* clang-format off */ +/* $OpenBSD: options.c,v 1.2 2015/11/19 22:16:43 tedu Exp $ */ + +/* flex - tool to generate fast lexical analyzers */ + +/* Copyright (c) 1990 The Regents of the University of California. */ +/* All rights reserved. */ + +/* This code is derived from software contributed to Berkeley by */ +/* Vern Paxson. */ + +/* The United States Government has rights in this work pursuant */ +/* to contract no. DE-AC03-76SF00098 between the United States */ +/* Department of Energy and the University of California. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + +#include "options.h" + +/* Be sure to synchronize these options with those defined in "options.h", + * the giant switch() statement in "main.c", and the %option processing in + * "scan.l". + */ + + +/* The command-line options, passed to scanopt_init() */ +optspec_t flexopts[] = { + + {"-7", OPT_7BIT, 0} + , + {"--7bit", OPT_7BIT, 0} + , /* Generate 7-bit scanner. */ + {"-8", OPT_8BIT, 0} + , + {"--8bit", OPT_8BIT, 0} + , /* Generate 8-bit scanner. */ + {"--align", OPT_ALIGN, 0} + , /* Trade off larger tables for better memory alignment. */ + {"--noalign", OPT_NO_ALIGN, 0} + , + {"--always-interactive", OPT_ALWAYS_INTERACTIVE, 0} + , + {"--array", OPT_ARRAY, 0} + , + {"-b", OPT_BACKUP, 0} + , + {"--backup", OPT_BACKUP, 0} + , /* Generate backing-up information to lex.backup. */ + {"-B", OPT_BATCH, 0} + , + {"--batch", OPT_BATCH, 0} + , /* Generate batch scanner (opposite of -I). */ + {"--bison-bridge", OPT_BISON_BRIDGE, 0} + , /* Scanner to be called by a bison pure parser. */ + {"--bison-locations", OPT_BISON_BRIDGE_LOCATIONS, 0} + , /* Scanner to be called by a bison pure parser. */ + {"-i", OPT_CASE_INSENSITIVE, 0} + , + {"--case-insensitive", OPT_CASE_INSENSITIVE, 0} + , /* Generate case-insensitive scanner. */ + + {"-C[aefFmr]", OPT_COMPRESSION, + "Specify degree of table compression (default is -Cem)"}, + {"-+", OPT_CPLUSPLUS, 0} + , + {"--c++", OPT_CPLUSPLUS, 0} + , /* Generate C++ scanner class. */ + {"-d", OPT_DEBUG, 0} + , + {"--debug", OPT_DEBUG, 0} + , /* Turn on debug mode in generated scanner. */ + {"--nodebug", OPT_NO_DEBUG, 0} + , + {"-s", OPT_NO_DEFAULT, 0} + , + {"--nodefault", OPT_NO_DEFAULT, 0} + , /* Suppress default rule to ECHO unmatched text. */ + {"--default", OPT_DEFAULT, 0} + , + {"-c", OPT_DONOTHING, 0} + , /* For POSIX lex compatibility. */ + {"-n", OPT_DONOTHING, 0} + , /* For POSIX lex compatibility. */ + {"--ecs", OPT_ECS, 0} + , /* Construct equivalence classes. */ + {"--noecs", OPT_NO_ECS, 0} + , + {"-F", OPT_FAST, 0} + , + {"--fast", OPT_FAST, 0} + , /* Same as -CFr. */ + {"-f", OPT_FULL, 0} + , + {"--full", OPT_FULL, 0} + , /* Same as -Cfr. */ + {"--header-file[=FILE]", OPT_HEADER_FILE, 0} + , + {"-?", OPT_HELP, 0} + , + {"-h", OPT_HELP, 0} + , + {"--help", OPT_HELP, 0} + , /* Produce this help message. */ + {"-I", OPT_INTERACTIVE, 0} + , + {"--interactive", OPT_INTERACTIVE, 0} + , /* Generate interactive scanner (opposite of -B). */ + {"-l", OPT_LEX_COMPAT, 0} + , + {"--lex-compat", OPT_LEX_COMPAT, 0} + , /* Maximal compatibility with original lex. */ + {"-X", OPT_POSIX_COMPAT, 0} + , + {"--posix-compat", OPT_POSIX_COMPAT, 0} + , /* Maximal compatibility with POSIX lex. */ + {"--preproc=NUM", OPT_PREPROC_LEVEL, 0} + , + {"-L", OPT_NO_LINE, 0} + , /* Suppress #line directives in scanner. */ + {"--noline", OPT_NO_LINE, 0} + , /* Suppress #line directives in scanner. */ + {"--main", OPT_MAIN, 0} + , /* use built-in main() function. */ + {"--nomain", OPT_NO_MAIN, 0} + , + {"--meta-ecs", OPT_META_ECS, 0} + , /* Construct meta-equivalence classes. */ + {"--nometa-ecs", OPT_NO_META_ECS, 0} + , + {"--never-interactive", OPT_NEVER_INTERACTIVE, 0} + , + {"-o FILE", OPT_OUTFILE, 0} + , + {"--outfile=FILE", OPT_OUTFILE, 0} + , /* Write to FILE (default is lex.yy.c) */ + {"-p", OPT_PERF_REPORT, 0} + , + {"--perf-report", OPT_PERF_REPORT, 0} + , /* Generate performance report to stderr. */ + {"--pointer", OPT_POINTER, 0} + , + {"-P PREFIX", OPT_PREFIX, 0} + , + {"--prefix=PREFIX", OPT_PREFIX, 0} + , /* Use PREFIX (default is yy) */ + {"-Dmacro", OPT_PREPROCDEFINE, 0} + , /* Define a preprocessor symbol. */ + {"--read", OPT_READ, 0} + , /* Use read(2) instead of stdio. */ + {"-R", OPT_REENTRANT, 0} + , + {"--reentrant", OPT_REENTRANT, 0} + , /* Generate a reentrant C scanner. */ + {"--noreentrant", OPT_NO_REENTRANT, 0} + , + {"--reject", OPT_REJECT, 0} + , + {"--noreject", OPT_NO_REJECT, 0} + , + {"-S FILE", OPT_SKEL, 0} + , + {"--skel=FILE", OPT_SKEL, 0} + , /* Use skeleton from FILE */ + {"--stack", OPT_STACK, 0} + , + {"--stdinit", OPT_STDINIT, 0} + , + {"--nostdinit", OPT_NO_STDINIT, 0} + , + {"-t", OPT_STDOUT, 0} + , + {"--stdout", OPT_STDOUT, 0} + , /* Write generated scanner to stdout. */ + {"-T", OPT_TRACE, 0} + , + {"--trace", OPT_TRACE, 0} + , /* Flex should run in trace mode. */ + {"--tables-file[=FILE]", OPT_TABLES_FILE, 0} + , /* Save tables to FILE */ + {"--tables-verify", OPT_TABLES_VERIFY, 0} + , /* Tables integrity check */ + {"--nounistd", OPT_NO_UNISTD_H, 0} + , /* Do not include unistd.h */ + {"-v", OPT_VERBOSE, 0} + , + {"--verbose", OPT_VERBOSE, 0} + , /* Write summary of scanner statistics to stdout. */ + {"-V", OPT_VERSION, 0} + , + {"--version", OPT_VERSION, 0} + , /* Report flex version. */ + {"--warn", OPT_WARN, 0} + , + {"-w", OPT_NO_WARN, 0} + , + {"--nowarn", OPT_NO_WARN, 0} + , /* Suppress warning messages. */ + {"--noansi-definitions", OPT_NO_ANSI_FUNC_DEFS, 0} + , + {"--noansi-prototypes", OPT_NO_ANSI_FUNC_PROTOS, 0} + , + {"--yyclass=NAME", OPT_YYCLASS, 0} + , + {"--yylineno", OPT_YYLINENO, 0} + , + {"--noyylineno", OPT_NO_YYLINENO, 0} + , + + {"--yymore", OPT_YYMORE, 0} + , + {"--noyymore", OPT_NO_YYMORE, 0} + , + {"--noyywrap", OPT_NO_YYWRAP, 0} + , + {"--yywrap", OPT_YYWRAP, 0} + , + + {"--nounput", OPT_NO_UNPUT, 0} + , + {"--noyy_push_state", OPT_NO_YY_PUSH_STATE, 0} + , + {"--noyy_pop_state", OPT_NO_YY_POP_STATE, 0} + , + {"--noyy_top_state", OPT_NO_YY_TOP_STATE, 0} + , + {"--noyy_scan_buffer", OPT_NO_YY_SCAN_BUFFER, 0} + , + {"--noyy_scan_bytes", OPT_NO_YY_SCAN_BYTES, 0} + , + {"--noyy_scan_string", OPT_NO_YY_SCAN_STRING, 0} + , + {"--noyyget_extra", OPT_NO_YYGET_EXTRA, 0} + , + {"--noyyset_extra", OPT_NO_YYSET_EXTRA, 0} + , + {"--noyyget_leng", OPT_NO_YYGET_LENG, 0} + , + {"--noyyget_text", OPT_NO_YYGET_TEXT, 0} + , + {"--noyyget_lineno", OPT_NO_YYGET_LINENO, 0} + , + {"--noyyset_lineno", OPT_NO_YYSET_LINENO, 0} + , + {"--noyyget_in", OPT_NO_YYGET_IN, 0} + , + {"--noyyset_in", OPT_NO_YYSET_IN, 0} + , + {"--noyyget_out", OPT_NO_YYGET_OUT, 0} + , + {"--noyyset_out", OPT_NO_YYSET_OUT, 0} + , + {"--noyyget_lval", OPT_NO_YYGET_LVAL, 0} + , + {"--noyyset_lval", OPT_NO_YYSET_LVAL, 0} + , + {"--noyyget_lloc", OPT_NO_YYGET_LLOC, 0} + , + {"--noyyset_lloc", OPT_NO_YYSET_LLOC, 0} + , + + {0, 0, 0} /* required final NULL entry. */ +}; diff --git a/third_party/lex/options.h b/third_party/lex/options.h new file mode 100644 index 00000000..95b9512f --- /dev/null +++ b/third_party/lex/options.h @@ -0,0 +1,135 @@ +/* clang-format off */ +/* $OpenBSD: options.h,v 1.2 2015/11/19 22:16:43 tedu Exp $ */ + +/* flex - tool to generate fast lexical analyzers */ + +/* Copyright (c) 1990 The Regents of the University of California. */ +/* All rights reserved. */ + +/* This code is derived from software contributed to Berkeley by */ +/* Vern Paxson. */ + +/* The United States Government has rights in this work pursuant */ +/* to contract no. DE-AC03-76SF00098 between the United States */ +/* Department of Energy and the University of California. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + +#ifndef OPTIONS_H +#define OPTIONS_H +#include "scanopt.h" + +extern optspec_t flexopts[]; + +enum flexopt_flag_t { + /* Use positive integers only, since they are return codes for scanopt. + * Order is not important. */ + OPT_7BIT = 1, + OPT_8BIT, + OPT_ALIGN, + OPT_ALWAYS_INTERACTIVE, + OPT_ARRAY, + OPT_BACKUP, + OPT_BATCH, + OPT_BISON_BRIDGE, + OPT_BISON_BRIDGE_LOCATIONS, + OPT_CASE_INSENSITIVE, + OPT_COMPRESSION, + OPT_CPLUSPLUS, + OPT_DEBUG, + OPT_DEFAULT, + OPT_DONOTHING, + OPT_ECS, + OPT_FAST, + OPT_FULL, + OPT_HEADER_FILE, + OPT_HELP, + OPT_INTERACTIVE, + OPT_LEX_COMPAT, + OPT_POSIX_COMPAT, + OPT_MAIN, + OPT_META_ECS, + OPT_NEVER_INTERACTIVE, + OPT_NO_ALIGN, + OPT_NO_ANSI_FUNC_DEFS, + OPT_NO_ANSI_FUNC_PROTOS, + OPT_NO_DEBUG, + OPT_NO_DEFAULT, + OPT_NO_ECS, + OPT_NO_LINE, + OPT_NO_MAIN, + OPT_NO_META_ECS, + OPT_NO_REENTRANT, + OPT_NO_REJECT, + OPT_NO_STDINIT, + OPT_NO_UNPUT, + OPT_NO_WARN, + OPT_NO_YYGET_EXTRA, + OPT_NO_YYGET_IN, + OPT_NO_YYGET_LENG, + OPT_NO_YYGET_LINENO, + OPT_NO_YYGET_LLOC, + OPT_NO_YYGET_LVAL, + OPT_NO_YYGET_OUT, + OPT_NO_YYGET_TEXT, + OPT_NO_YYLINENO, + OPT_NO_YYMORE, + OPT_NO_YYSET_EXTRA, + OPT_NO_YYSET_IN, + OPT_NO_YYSET_LINENO, + OPT_NO_YYSET_LLOC, + OPT_NO_YYSET_LVAL, + OPT_NO_YYSET_OUT, + OPT_NO_YYWRAP, + OPT_NO_YY_POP_STATE, + OPT_NO_YY_PUSH_STATE, + OPT_NO_YY_SCAN_BUFFER, + OPT_NO_YY_SCAN_BYTES, + OPT_NO_YY_SCAN_STRING, + OPT_NO_YY_TOP_STATE, + OPT_OUTFILE, + OPT_PERF_REPORT, + OPT_POINTER, + OPT_PREFIX, + OPT_PREPROCDEFINE, + OPT_PREPROC_LEVEL, + OPT_READ, + OPT_REENTRANT, + OPT_REJECT, + OPT_SKEL, + OPT_STACK, + OPT_STDINIT, + OPT_STDOUT, + OPT_TABLES_FILE, + OPT_TABLES_VERIFY, + OPT_TRACE, + OPT_NO_UNISTD_H, + OPT_VERBOSE, + OPT_VERSION, + OPT_WARN, + OPT_YYCLASS, + OPT_YYLINENO, + OPT_YYMORE, + OPT_YYWRAP +}; + +#endif diff --git a/third_party/lex/parse.c b/third_party/lex/parse.c new file mode 100644 index 00000000..f492b073 --- /dev/null +++ b/third_party/lex/parse.c @@ -0,0 +1,1810 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 sw=8 fenc=utf-8 :vi│ +└─────────────────────────────────────────────────────────────────────────────*/ + +#include "libc/alg/alg.h" +#include "libc/fmt/fmt.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "third_party/lex/flexdef.h" +#include "third_party/lex/tables.h" + +/* clang-format off */ +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYLEX yylex() +#define YYEMPTY -1 +#define yyclearin (yychar=(YYEMPTY)) +#define yyerrok (yyerrflag=0) +#define YYRECOVERING() (yyerrflag!=0) +#define YYPREFIX "yy" +/* #line 37 "third_party/lex/parse.y" */ +/* Copyright (c) 1990 The Regents of the University of California. */ +/* All rights reserved. */ + +/* This code is derived from software contributed to Berkeley by */ +/* Vern Paxson. */ + +/* The United States Government has rights in this work pursuant */ +/* to contract no. DE-AC03-76SF00098 between the United States */ +/* Department of Energy and the University of California. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + + +int pat, scnum, eps, headcnt, trailcnt, lastchar, i, rulelen; +int trlcontxt, xcluflg, currccl, cclsorted, varlength, variable_trail_rule; + +int *scon_stk; +int scon_stk_ptr; + +static int madeany = false; /* whether we've made the '.' character class */ +static int ccldot, cclany; +int previous_continued_action; /* whether the previous rule's action was '|' */ + +#define format_warn3(fmt, a1, a2) \ + do{ \ + char fw3_msg[MAXLINE];\ + snprintf( fw3_msg, MAXLINE,(fmt), (a1), (a2) );\ + lexwarn( fw3_msg );\ + }while(0) + +/* Expand a POSIX character class expression. */ +#define CCL_EXPR(func) \ + do{ \ + int c; \ + for ( c = 0; c < csize; ++c ) \ + if ( isascii(c) && func(c) ) \ + ccladd( currccl, c ); \ + }while(0) + +/* negated class */ +#define CCL_NEG_EXPR(func) \ + do{ \ + int c; \ + for ( c = 0; c < csize; ++c ) \ + if ( !func(c) ) \ + ccladd( currccl, c ); \ + }while(0) + +/* On some over-ambitious machines, such as DEC Alpha's, the default + * token type is "long" instead of "int"; this leads to problems with + * declaring yylval in flexdef.h. But so far, all the yacc's I've seen + * wrap their definitions of YYSTYPE with "#ifndef YYSTYPE"'s, so the + * following should ensure that the default token type is "int". + */ +#define YYSTYPE int + +/* #line 91 "third_party/lex/parse.c" */ +#define CHAR 257 +#define NUMBER 258 +#define SECTEND 259 +#define SCDECL 260 +#define XSCDECL 261 +#define NAME 262 +#define PREVCCL 263 +#define EOF_OP 264 +#define OPTION_OP 265 +#define OPT_OUTFILE 266 +#define OPT_PREFIX 267 +#define OPT_YYCLASS 268 +#define OPT_HEADER 269 +#define OPT_EXTRA_TYPE 270 +#define OPT_TABLES 271 +#define CCE_ALNUM 272 +#define CCE_ALPHA 273 +#define CCE_BLANK 274 +#define CCE_CNTRL 275 +#define CCE_DIGIT 276 +#define CCE_GRAPH 277 +#define CCE_LOWER 278 +#define CCE_PRINT 279 +#define CCE_PUNCT 280 +#define CCE_SPACE 281 +#define CCE_UPPER 282 +#define CCE_XDIGIT 283 +#define CCE_NEG_ALNUM 284 +#define CCE_NEG_ALPHA 285 +#define CCE_NEG_BLANK 286 +#define CCE_NEG_CNTRL 287 +#define CCE_NEG_DIGIT 288 +#define CCE_NEG_GRAPH 289 +#define CCE_NEG_LOWER 290 +#define CCE_NEG_PRINT 291 +#define CCE_NEG_PUNCT 292 +#define CCE_NEG_SPACE 293 +#define CCE_NEG_UPPER 294 +#define CCE_NEG_XDIGIT 295 +#define CCL_OP_DIFF 296 +#define CCL_OP_UNION 297 +#define BEGIN_REPEAT_POSIX 298 +#define END_REPEAT_POSIX 299 +#define BEGIN_REPEAT_FLEX 300 +#define END_REPEAT_FLEX 301 +#define YYERRCODE 256 +const short yylhs[] = + { -1, + 0, 1, 2, 2, 2, 2, 3, 6, 6, 7, + 7, 7, 8, 9, 9, 10, 10, 10, 10, 10, + 10, 4, 4, 4, 5, 12, 12, 12, 12, 14, + 11, 11, 11, 15, 15, 15, 16, 13, 13, 13, + 13, 18, 18, 17, 19, 19, 19, 19, 19, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 21, 21, 21, 23, 23, 24, 24, 24, 24, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 22, 22, +}; +const short yylen[] = + { 2, + 5, 0, 3, 2, 0, 1, 1, 1, 1, 2, + 1, 1, 2, 2, 0, 3, 3, 3, 3, 3, + 3, 5, 5, 0, 0, 2, 1, 1, 1, 0, + 4, 3, 0, 3, 1, 1, 1, 2, 3, 2, + 1, 3, 1, 2, 2, 1, 6, 5, 4, 2, + 2, 2, 6, 5, 4, 1, 1, 1, 3, 3, + 1, 3, 3, 1, 3, 4, 4, 2, 2, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 0, +}; +const short yydefred[] = + { 2, + 0, 0, 6, 0, 7, 8, 9, 15, 24, 0, + 4, 0, 0, 12, 11, 0, 0, 0, 0, 0, + 0, 0, 14, 0, 1, 0, 10, 0, 0, 0, + 0, 0, 0, 0, 0, 24, 0, 16, 18, 19, + 20, 17, 21, 32, 36, 37, 0, 35, 0, 29, + 61, 58, 28, 0, 56, 96, 0, 0, 0, 27, + 0, 0, 0, 0, 0, 64, 31, 0, 23, 26, + 0, 0, 70, 0, 22, 0, 40, 0, 44, 0, + 0, 0, 50, 51, 52, 0, 0, 34, 95, 59, + 60, 0, 0, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 82, 81, 83, 84, 85, 86, 87, + 88, 93, 89, 90, 91, 94, 92, 65, 69, 39, + 0, 0, 0, 62, 63, 66, 0, 49, 0, 55, + 0, 67, 0, 48, 0, 54, 47, 53, +}; +const short yydgoto[] = + { 1, + 2, 4, 9, 13, 25, 10, 16, 11, 12, 23, + 26, 59, 60, 35, 47, 48, 61, 62, 63, 64, + 65, 71, 66, 74, 119, +}; +const short yysindex[] = + { 0, + 0, -222, 0, -155, 0, 0, 0, 0, 0, -215, + 0, -123, 6, 0, 0, -193, 10, 21, 26, 31, + 35, 37, 0, 59, 0, -44, 0, -147, -145, -140, + -133, -132, -129, 75, -214, 0, -19, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 23, 0, -48, 0, + 0, 0, 0, -17, 0, 0, -17, 27, 128, 0, + -17, -1, -30, -41, -189, 0, 0, -121, 0, 0, + -31, -34, 0, -87, 0, -25, 0, -17, 0, -109, + -41, -108, 0, 0, 0, 60, 60, 0, 0, 0, + 0, 46, 107, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -30, -36, -39, 0, 0, 0, -104, 0, -219, 0, + -238, 0, -144, 0, -143, 0, 0, 0,}; +const short yyrindex[] = + { 0, + 0, -141, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -134, 9, 0, 0, -125, 0, 0, 0, 0, + 0, 0, 0, -178, 0, 22, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -21, 0, + 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, + 0, 144, 47, 4, -10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 146, 0, 0, 0, 0, + 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 124, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,}; +const short yygindex[] = + { 0, + 0, 0, 0, 121, 133, 0, 0, 0, 0, 0, + 0, 0, 106, 0, 0, 93, 0, 32, 84, -45, + 0, 0, 25, 90, 0, +}; +#define YYTABLESIZE 419 +const short yytable[] = + { 57, + 83, 84, 90, 56, 131, 118, 91, 129, 25, 57, + 120, 24, 33, 46, 56, 55, 56, 81, 33, 135, + 57, 85, 57, 57, 33, 57, 55, 45, 55, 57, + 57, 57, 57, 3, 77, 57, 57, 46, 133, 46, + 14, 45, 33, 46, 46, 79, 15, 46, 33, 46, + 46, 45, 57, 45, 33, 25, 43, 45, 45, 42, + 58, 25, 136, 45, 45, 24, 68, 25, 27, 33, + 28, 58, 33, 58, 54, 81, 69, 30, 36, 134, + 57, 29, 43, 30, 67, 42, 30, 43, 72, 78, + 42, 31, 76, 43, 46, 32, 42, 33, 78, 33, + 34, 33, 33, 5, 6, 7, 86, 87, 45, 8, + 124, 125, 25, 57, 38, 25, 39, 5, 5, 5, + 73, 40, 78, 5, 13, 13, 13, 46, 41, 42, + 13, 33, 43, 3, 3, 3, 44, 75, 126, 3, + 46, 45, 17, 18, 19, 20, 21, 22, 122, 123, + 58, 127, 132, 41, 137, 38, 49, 138, 37, 70, + 88, 121, 92, 0, 0, 0, 0, 0, 0, 93, + 43, 0, 0, 42, 0, 0, 0, 70, 0, 0, + 0, 0, 0, 0, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 0, 0, + 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 89, 51, 0, 0, 0, + 0, 0, 52, 0, 33, 33, 50, 51, 0, 51, + 0, 33, 33, 52, 53, 52, 57, 0, 0, 0, + 0, 0, 57, 0, 0, 0, 0, 0, 82, 0, + 46, 130, 128, 0, 33, 33, 46, 80, 0, 0, + 0, 33, 33, 0, 45, 0, 0, 25, 25, 0, + 45, 0, 0, 0, 25, 25, 0, 57, 0, 57, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 46, 93, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 45, 0, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 70, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, +}; +const short yycheck[] = + { 10, + 42, 43, 34, 34, 44, 93, 41, 44, 0, 40, + 36, 60, 34, 10, 34, 46, 34, 63, 40, 258, + 40, 63, 40, 34, 46, 36, 46, 10, 46, 40, + 41, 42, 43, 256, 36, 46, 47, 34, 258, 36, + 256, 256, 34, 40, 41, 47, 262, 262, 40, 46, + 47, 34, 63, 36, 46, 34, 10, 40, 41, 10, + 91, 40, 301, 46, 47, 60, 44, 46, 262, 91, + 61, 91, 94, 91, 94, 121, 125, 256, 123, 299, + 91, 61, 36, 262, 62, 36, 61, 41, 57, 124, + 41, 61, 61, 47, 91, 61, 47, 61, 124, 91, + 42, 123, 94, 259, 260, 261, 296, 297, 91, 265, + 86, 87, 91, 124, 262, 94, 262, 259, 260, 261, + 94, 262, 124, 265, 259, 260, 261, 124, 262, 262, + 265, 123, 262, 259, 260, 261, 62, 10, 93, 265, + 262, 124, 266, 267, 268, 269, 270, 271, 258, 258, + 91, 45, 257, 10, 299, 10, 36, 301, 26, 54, + 68, 78, 73, -1, -1, -1, -1, -1, -1, 257, + 124, -1, -1, 124, -1, -1, -1, 93, -1, -1, + -1, -1, -1, -1, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, -1, -1, + -1, -1, -1, -1, -1, -1, 93, -1, -1, -1, + -1, -1, -1, -1, -1, 257, 257, -1, -1, -1, + -1, -1, 263, -1, 256, 257, 256, 257, -1, 257, + -1, 263, 264, 263, 264, 263, 257, -1, -1, -1, + -1, -1, 263, -1, -1, -1, -1, -1, 300, -1, + 257, 301, 299, -1, 256, 257, 263, 298, -1, -1, + -1, 263, 264, -1, 257, -1, -1, 256, 257, -1, + 263, -1, -1, -1, 263, 264, -1, 298, -1, 300, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 298, 257, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 298, -1, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 257, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, + 257, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, +}; +#define YYFINAL 1 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 301 +#if YYDEBUG +const char * const yyname[] = + { +"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,"'\"'",0,"'$'",0,0,0,"'('","')'","'*'","'+'","','","'-'","'.'","'/'",0,0, +0,0,0,0,0,0,0,0,0,0,"'<'","'='","'>'","'?'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,"'['",0,"']'","'^'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,"'{'","'|'","'}'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"CHAR","NUMBER","SECTEND", +"SCDECL","XSCDECL","NAME","PREVCCL","EOF_OP","OPTION_OP","OPT_OUTFILE", +"OPT_PREFIX","OPT_YYCLASS","OPT_HEADER","OPT_EXTRA_TYPE","OPT_TABLES", +"CCE_ALNUM","CCE_ALPHA","CCE_BLANK","CCE_CNTRL","CCE_DIGIT","CCE_GRAPH", +"CCE_LOWER","CCE_PRINT","CCE_PUNCT","CCE_SPACE","CCE_UPPER","CCE_XDIGIT", +"CCE_NEG_ALNUM","CCE_NEG_ALPHA","CCE_NEG_BLANK","CCE_NEG_CNTRL","CCE_NEG_DIGIT", +"CCE_NEG_GRAPH","CCE_NEG_LOWER","CCE_NEG_PRINT","CCE_NEG_PUNCT","CCE_NEG_SPACE", +"CCE_NEG_UPPER","CCE_NEG_XDIGIT","CCL_OP_DIFF","CCL_OP_UNION", +"BEGIN_REPEAT_POSIX","END_REPEAT_POSIX","BEGIN_REPEAT_FLEX","END_REPEAT_FLEX", +}; +const char * const yyrule[] = + {"$accept : goal", +"goal : initlex sect1 sect1end sect2 initforrule", +"initlex :", +"sect1 : sect1 startconddecl namelist1", +"sect1 : sect1 options", +"sect1 :", +"sect1 : error", +"sect1end : SECTEND", +"startconddecl : SCDECL", +"startconddecl : XSCDECL", +"namelist1 : namelist1 NAME", +"namelist1 : NAME", +"namelist1 : error", +"options : OPTION_OP optionlist", +"optionlist : optionlist option", +"optionlist :", +"option : OPT_OUTFILE '=' NAME", +"option : OPT_EXTRA_TYPE '=' NAME", +"option : OPT_PREFIX '=' NAME", +"option : OPT_YYCLASS '=' NAME", +"option : OPT_HEADER '=' NAME", +"option : OPT_TABLES '=' NAME", +"sect2 : sect2 scon initforrule flexrule '\\n'", +"sect2 : sect2 scon '{' sect2 '}'", +"sect2 :", +"initforrule :", +"flexrule : '^' rule", +"flexrule : rule", +"flexrule : EOF_OP", +"flexrule : error", +"scon_stk_ptr :", +"scon : '<' scon_stk_ptr namelist2 '>'", +"scon : '<' '*' '>'", +"scon :", +"namelist2 : namelist2 ',' sconname", +"namelist2 : sconname", +"namelist2 : error", +"sconname : NAME", +"rule : re2 re", +"rule : re2 re '$'", +"rule : re '$'", +"rule : re", +"re : re '|' series", +"re : series", +"re2 : re '/'", +"series : series singleton", +"series : singleton", +"series : series BEGIN_REPEAT_POSIX NUMBER ',' NUMBER END_REPEAT_POSIX", +"series : series BEGIN_REPEAT_POSIX NUMBER ',' END_REPEAT_POSIX", +"series : series BEGIN_REPEAT_POSIX NUMBER END_REPEAT_POSIX", +"singleton : singleton '*'", +"singleton : singleton '+'", +"singleton : singleton '?'", +"singleton : singleton BEGIN_REPEAT_FLEX NUMBER ',' NUMBER END_REPEAT_FLEX", +"singleton : singleton BEGIN_REPEAT_FLEX NUMBER ',' END_REPEAT_FLEX", +"singleton : singleton BEGIN_REPEAT_FLEX NUMBER END_REPEAT_FLEX", +"singleton : '.'", +"singleton : fullccl", +"singleton : PREVCCL", +"singleton : '\"' string '\"'", +"singleton : '(' re ')'", +"singleton : CHAR", +"fullccl : fullccl CCL_OP_DIFF braceccl", +"fullccl : fullccl CCL_OP_UNION braceccl", +"fullccl : braceccl", +"braceccl : '[' ccl ']'", +"braceccl : '[' '^' ccl ']'", +"ccl : ccl CHAR '-' CHAR", +"ccl : ccl CHAR", +"ccl : ccl ccl_expr", +"ccl :", +"ccl_expr : CCE_ALNUM", +"ccl_expr : CCE_ALPHA", +"ccl_expr : CCE_BLANK", +"ccl_expr : CCE_CNTRL", +"ccl_expr : CCE_DIGIT", +"ccl_expr : CCE_GRAPH", +"ccl_expr : CCE_LOWER", +"ccl_expr : CCE_PRINT", +"ccl_expr : CCE_PUNCT", +"ccl_expr : CCE_SPACE", +"ccl_expr : CCE_XDIGIT", +"ccl_expr : CCE_UPPER", +"ccl_expr : CCE_NEG_ALNUM", +"ccl_expr : CCE_NEG_ALPHA", +"ccl_expr : CCE_NEG_BLANK", +"ccl_expr : CCE_NEG_CNTRL", +"ccl_expr : CCE_NEG_DIGIT", +"ccl_expr : CCE_NEG_GRAPH", +"ccl_expr : CCE_NEG_PRINT", +"ccl_expr : CCE_NEG_PUNCT", +"ccl_expr : CCE_NEG_SPACE", +"ccl_expr : CCE_NEG_XDIGIT", +"ccl_expr : CCE_NEG_LOWER", +"ccl_expr : CCE_NEG_UPPER", +"string : string CHAR", +"string :", +}; +#endif +#ifndef YYSTYPE +typedef int YYSTYPE; +#endif +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif +#define YYINITSTACKSIZE 200 +/* LINTUSED */ +int yydebug; +int yynerrs; +int yyerrflag; +int yychar; +short *yyssp; +YYSTYPE *yyvsp; +YYSTYPE yyval; +YYSTYPE yylval; +short *yyss; +short *yysslim; +YYSTYPE *yyvs; +unsigned int yystacksize; +/* int yyparse(void); */ +/* #line 947 "third_party/lex/parse.y" */ + + +/* build_eof_action - build the "<>" action for the active start + * conditions + */ + +void build_eof_action() + { + int i2; + char action_text[MAXLINE]; + + for ( i2 = 1; i2 <= scon_stk_ptr; ++i2 ) + { + if ( sceof[scon_stk[i2]] ) + format_pinpoint_message( + "multiple <> rules for start condition %s", + scname[scon_stk[i2]] ); + + else + { + sceof[scon_stk[i2]] = true; + + if (previous_continued_action /* && previous action was regular */) + add_action("YY_RULE_SETUP\n"); + + snprintf( action_text, sizeof(action_text), "case YY_STATE_EOF(%s):\n", + scname[scon_stk[i2]] ); + add_action( action_text ); + } + } + + line_directive_out( (FILE *) 0, 1 ); + + /* This isn't a normal rule after all - don't count it as + * such, so we don't have any holes in the rule numbering + * (which make generating "rule can never match" warnings + * more difficult. + */ + --num_rules; + ++num_eof_rules; + } + + +/* format_synerr - write out formatted syntax error */ + +void format_synerr( msg, arg ) +const char *msg, arg[]; + { + char errmsg[MAXLINE]; + + (void) snprintf( errmsg, sizeof(errmsg), msg, arg ); + synerr( errmsg ); + } + + +/* synerr - report a syntax error */ + +void synerr( str ) +const char *str; + { + syntaxerror = true; + pinpoint_message( str ); + } + + +/* format_warn - write out formatted warning */ + +void format_warn( msg, arg ) +const char *msg, arg[]; + { + char warn_msg[MAXLINE]; + + snprintf( warn_msg, sizeof(warn_msg), msg, arg ); + lexwarn( warn_msg ); + } + + +/* warn - report a warning, unless -w was given */ + +void lexwarn( str ) +const char *str; + { + line_warning( str, linenum ); + } + +/* format_pinpoint_message - write out a message formatted with one string, + * pinpointing its location + */ + +void format_pinpoint_message( msg, arg ) +const char *msg, arg[]; + { + char errmsg[MAXLINE]; + + snprintf( errmsg, sizeof(errmsg), msg, arg ); + pinpoint_message( errmsg ); + } + + +/* pinpoint_message - write out a message, pinpointing its location */ + +void pinpoint_message( str ) +const char *str; + { + line_pinpoint( str, linenum ); + } + + +/* line_warning - report a warning at a given line, unless -w was given */ + +void line_warning( str, line ) +const char *str; +int line; + { + char warning[MAXLINE]; + + if ( ! nowarn ) + { + snprintf( warning, sizeof(warning), "warning, %s", str ); + line_pinpoint( warning, line ); + } + } + + +/* line_pinpoint - write out a message, pinpointing it at the given line */ + +void line_pinpoint( str, line ) +const char *str; +int line; + { + fprintf( stderr, "%s:%d: %s\n", infilename, line, str ); + } + + +/* yyerror - eat up an error message from the parser; + * currently, messages are ignore + */ + +void yyerror( msg ) +const char *msg; + { + } +/* #line 605 "third_party/lex/parse.c" */ +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(void) +{ + unsigned int newsize; + long sslen; + short *newss; + YYSTYPE *newvs; + + if ((newsize = yystacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + sslen = yyssp - yyss; +#ifdef SIZE_MAX +#define YY_SIZE_MAX SIZE_MAX +#else +#define YY_SIZE_MAX 0xffffffffU +#endif + if (newsize && YY_SIZE_MAX / newsize < sizeof *newss) + goto bail; + newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) : + (short *)malloc(newsize * sizeof *newss); /* overflow check above */ + if (newss == NULL) + goto bail; + yyss = newss; + yyssp = newss + sslen; + if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs) + goto bail; + newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) : + (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */ + if (newvs == NULL) + goto bail; + yyvs = newvs; + yyvsp = newvs + sslen; + yystacksize = newsize; + yysslim = yyss + newsize - 1; + return 0; +bail: + if (yyss) + free(yyss); + if (yyvs) + free(yyvs); + yyss = yyssp = NULL; + yyvs = yyvsp = NULL; + yystacksize = 0; + return -1; +} + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab +int +yyparse(void) +{ + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG"))) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif /* YYDEBUG */ + + yynerrs = 0; + yyerrflag = 0; + yychar = (-1); + + if (yyss == NULL && yygrowstack()) goto yyoverflow; + yyssp = yyss; + yyvsp = yyvs; + *yyssp = yystate = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = yylex()) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = 0; + if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; + if (!yys) yys = "illegal-symbol"; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yyssp >= yysslim && yygrowstack()) + { + goto yyoverflow; + } + *++yyssp = yystate = yytable[yyn]; + *++yyvsp = yylval; + yychar = (-1); + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; +#if defined(__GNUC__) + goto yynewerror; +#endif +yynewerror: + yyerror("syntax error"); +#if defined(__GNUC__) + goto yyerrlab; +#endif +yyerrlab: + ++yynerrs; +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yyssp, yytable[yyn]); +#endif + if (yyssp >= yysslim && yygrowstack()) + { + goto yyoverflow; + } + *++yyssp = yystate = yytable[yyn]; + *++yyvsp = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yyssp); +#endif + if (yyssp <= yyss) goto yyabort; + --yyssp; + --yyvsp; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = 0; + if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; + if (!yys) yys = "illegal-symbol"; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = (-1); + goto yyloop; + } +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yyvsp[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { +case 1: +/* #line 118 "third_party/lex/parse.y" */ +{ /* add default rule */ + int def_rule; + + pat = cclinit(); + cclnegate( pat ); + + def_rule = mkstate( -pat ); + + /* Remember the number of the default rule so we + * don't generate "can't match" warnings for it. + */ + default_rule = num_rules; + + finish_rule( def_rule, false, 0, 0, 0); + + for ( i = 1; i <= lastsc; ++i ) + scset[i] = mkbranch( scset[i], def_rule ); + + if ( spprdflt ) + add_action( + "YY_FATAL_ERROR( \"flex scanner jammed\" )" ); + else + add_action( "ECHO" ); + + add_action( ";\n\tYY_BREAK\n" ); + } +break; +case 2: +/* #line 147 "third_party/lex/parse.y" */ +{ /* initialize for processing rules */ + + /* Create default DFA start condition. */ + scinstal( "INITIAL", false ); + } +break; +case 6: +/* #line 158 "third_party/lex/parse.y" */ +{ synerr( _("unknown error processing section 1") ); } +break; +case 7: +/* #line 162 "third_party/lex/parse.y" */ +{ + check_options(); + scon_stk = allocate_integer_array( lastsc + 1 ); + scon_stk_ptr = 0; + } +break; +case 8: +/* #line 170 "third_party/lex/parse.y" */ +{ xcluflg = false; } +break; +case 9: +/* #line 173 "third_party/lex/parse.y" */ +{ xcluflg = true; } +break; +case 10: +/* #line 177 "third_party/lex/parse.y" */ +{ scinstal( nmstr, xcluflg ); } +break; +case 11: +/* #line 180 "third_party/lex/parse.y" */ +{ scinstal( nmstr, xcluflg ); } +break; +case 12: +/* #line 183 "third_party/lex/parse.y" */ +{ synerr( _("bad start condition list") ); } +break; +case 16: +/* #line 194 "third_party/lex/parse.y" */ +{ + outfilename = copy_string( nmstr ); + did_outfilename = 1; + } +break; +case 17: +/* #line 199 "third_party/lex/parse.y" */ +{ extra_type = copy_string( nmstr ); } +break; +case 18: +/* #line 201 "third_party/lex/parse.y" */ +{ prefix = copy_string( nmstr ); } +break; +case 19: +/* #line 203 "third_party/lex/parse.y" */ +{ yyclass = copy_string( nmstr ); } +break; +case 20: +/* #line 205 "third_party/lex/parse.y" */ +{ headerfilename = copy_string( nmstr ); } +break; +case 21: +/* #line 207 "third_party/lex/parse.y" */ +{ tablesext = true; tablesfilename = copy_string( nmstr ); } +break; +case 22: +/* #line 211 "third_party/lex/parse.y" */ +{ scon_stk_ptr = yyvsp[-3]; } +break; +case 23: +/* #line 213 "third_party/lex/parse.y" */ +{ scon_stk_ptr = yyvsp[-3]; } +break; +case 25: +/* #line 218 "third_party/lex/parse.y" */ +{ + /* Initialize for a parse of one rule. */ + trlcontxt = variable_trail_rule = varlength = false; + trailcnt = headcnt = rulelen = 0; + current_state_type = STATE_NORMAL; + previous_continued_action = continued_action; + in_rule = true; + + new_rule(); + } +break; +case 26: +/* #line 231 "third_party/lex/parse.y" */ +{ + pat = yyvsp[0]; + finish_rule( pat, variable_trail_rule, + headcnt, trailcnt , previous_continued_action); + + if ( scon_stk_ptr > 0 ) + { + for ( i = 1; i <= scon_stk_ptr; ++i ) + scbol[scon_stk[i]] = + mkbranch( scbol[scon_stk[i]], + pat ); + } + + else + { + /* Add to all non-exclusive start conditions, + * including the default (0) start condition. + */ + + for ( i = 1; i <= lastsc; ++i ) + if ( ! scxclu[i] ) + scbol[i] = mkbranch( scbol[i], + pat ); + } + + if ( ! bol_needed ) + { + bol_needed = true; + + if ( performance_report > 1 ) + pinpoint_message( + "'^' operator results in sub-optimal performance" ); + } + } +break; +case 27: +/* #line 267 "third_party/lex/parse.y" */ +{ + pat = yyvsp[0]; + finish_rule( pat, variable_trail_rule, + headcnt, trailcnt , previous_continued_action); + + if ( scon_stk_ptr > 0 ) + { + for ( i = 1; i <= scon_stk_ptr; ++i ) + scset[scon_stk[i]] = + mkbranch( scset[scon_stk[i]], + pat ); + } + + else + { + for ( i = 1; i <= lastsc; ++i ) + if ( ! scxclu[i] ) + scset[i] = + mkbranch( scset[i], + pat ); + } + } +break; +case 28: +/* #line 291 "third_party/lex/parse.y" */ +{ + if ( scon_stk_ptr > 0 ) + build_eof_action(); + + else + { + /* This EOF applies to all start conditions + * which don't already have EOF actions. + */ + for ( i = 1; i <= lastsc; ++i ) + if ( ! sceof[i] ) + scon_stk[++scon_stk_ptr] = i; + + if ( scon_stk_ptr == 0 ) + lexwarn( + "all start conditions already have <> rules" ); + + else + build_eof_action(); + } + } +break; +case 29: +/* #line 314 "third_party/lex/parse.y" */ +{ synerr( _("unrecognized rule") ); } +break; +case 30: +/* #line 318 "third_party/lex/parse.y" */ +{ yyval = scon_stk_ptr; } +break; +case 31: +/* #line 322 "third_party/lex/parse.y" */ +{ yyval = yyvsp[-2]; } +break; +case 32: +/* #line 325 "third_party/lex/parse.y" */ +{ + yyval = scon_stk_ptr; + + for ( i = 1; i <= lastsc; ++i ) + { + int j; + + for ( j = 1; j <= scon_stk_ptr; ++j ) + if ( scon_stk[j] == i ) + break; + + if ( j > scon_stk_ptr ) + scon_stk[++scon_stk_ptr] = i; + } + } +break; +case 33: +/* #line 342 "third_party/lex/parse.y" */ +{ yyval = scon_stk_ptr; } +break; +case 36: +/* #line 350 "third_party/lex/parse.y" */ +{ synerr( _("bad start condition list") ); } +break; +case 37: +/* #line 354 "third_party/lex/parse.y" */ +{ + if ( (scnum = sclookup( nmstr )) == 0 ) + format_pinpoint_message( + "undeclared start condition %s", + nmstr ); + else + { + for ( i = 1; i <= scon_stk_ptr; ++i ) + if ( scon_stk[i] == scnum ) + { + format_warn( + "<%s> specified twice", + scname[scnum] ); + break; + } + + if ( i > scon_stk_ptr ) + scon_stk[++scon_stk_ptr] = scnum; + } + } +break; +case 38: +/* #line 377 "third_party/lex/parse.y" */ +{ + if ( transchar[lastst[yyvsp[0]]] != SYM_EPSILON ) + /* Provide final transition \now/ so it + * will be marked as a trailing context + * state. + */ + yyvsp[0] = link_machines( yyvsp[0], + mkstate( SYM_EPSILON ) ); + + mark_beginning_as_normal( yyvsp[0] ); + current_state_type = STATE_NORMAL; + + if ( previous_continued_action ) + { + /* We need to treat this as variable trailing + * context so that the backup does not happen + * in the action but before the action switch + * statement. If the backup happens in the + * action, then the rules "falling into" this + * one's action will *also* do the backup, + * erroneously. + */ + if ( ! varlength || headcnt != 0 ) + lexwarn( + "trailing context made variable due to preceding '|' action" ); + + /* Mark as variable. */ + varlength = true; + headcnt = 0; + + } + + if ( lex_compat || (varlength && headcnt == 0) ) + { /* variable trailing context rule */ + /* Mark the first part of the rule as the + * accepting "head" part of a trailing + * context rule. + * + * By the way, we didn't do this at the + * beginning of this production because back + * then current_state_type was set up for a + * trail rule, and add_accept() can create + * a new state ... + */ + add_accept( yyvsp[-1], + num_rules | YY_TRAILING_HEAD_MASK ); + variable_trail_rule = true; + } + + else + trailcnt = rulelen; + + yyval = link_machines( yyvsp[-1], yyvsp[0] ); + } +break; +case 39: +/* #line 433 "third_party/lex/parse.y" */ +{ synerr( _("trailing context used twice") ); } +break; +case 40: +/* #line 436 "third_party/lex/parse.y" */ +{ + headcnt = 0; + trailcnt = 1; + rulelen = 1; + varlength = false; + + current_state_type = STATE_TRAILING_CONTEXT; + + if ( trlcontxt ) + { + synerr( _("trailing context used twice") ); + yyval = mkstate( SYM_EPSILON ); + } + + else if ( previous_continued_action ) + { + /* See the comment in the rule for "re2 re" + * above. + */ + lexwarn( + "trailing context made variable due to preceding '|' action" ); + + varlength = true; + } + + if ( lex_compat || varlength ) + { + /* Again, see the comment in the rule for + * "re2 re" above. + */ + add_accept( yyvsp[-1], + num_rules | YY_TRAILING_HEAD_MASK ); + variable_trail_rule = true; + } + + trlcontxt = true; + + eps = mkstate( SYM_EPSILON ); + yyval = link_machines( yyvsp[-1], + link_machines( eps, mkstate( '\n' ) ) ); + } +break; +case 41: +/* #line 479 "third_party/lex/parse.y" */ +{ + yyval = yyvsp[0]; + + if ( trlcontxt ) + { + if ( lex_compat || (varlength && headcnt == 0) ) + /* Both head and trail are + * variable-length. + */ + variable_trail_rule = true; + else + trailcnt = rulelen; + } + } +break; +case 42: +/* #line 497 "third_party/lex/parse.y" */ +{ + varlength = true; + yyval = mkor( yyvsp[-2], yyvsp[0] ); + } +break; +case 43: +/* #line 503 "third_party/lex/parse.y" */ +{ yyval = yyvsp[0]; } +break; +case 44: +/* #line 508 "third_party/lex/parse.y" */ +{ + /* This rule is written separately so the + * reduction will occur before the trailing + * series is parsed. + */ + + if ( trlcontxt ) + synerr( _("trailing context used twice") ); + else + trlcontxt = true; + + if ( varlength ) + /* We hope the trailing context is + * fixed-length. + */ + varlength = false; + else + headcnt = rulelen; + + rulelen = 0; + + current_state_type = STATE_TRAILING_CONTEXT; + yyval = yyvsp[-1]; + } +break; +case 45: +/* #line 535 "third_party/lex/parse.y" */ +{ + /* This is where concatenation of adjacent patterns + * gets done. + */ + yyval = link_machines( yyvsp[-1], yyvsp[0] ); + } +break; +case 46: +/* #line 543 "third_party/lex/parse.y" */ +{ yyval = yyvsp[0]; } +break; +case 47: +/* #line 546 "third_party/lex/parse.y" */ +{ + varlength = true; + + if ( yyvsp[-3] > yyvsp[-1] || yyvsp[-3] < 0 ) + { + synerr( _("bad iteration values") ); + yyval = yyvsp[-5]; + } + else + { + if ( yyvsp[-3] == 0 ) + { + if ( yyvsp[-1] <= 0 ) + { + synerr( + _("bad iteration values") ); + yyval = yyvsp[-5]; + } + else + yyval = mkopt( + mkrep( yyvsp[-5], 1, yyvsp[-1] ) ); + } + else + yyval = mkrep( yyvsp[-5], yyvsp[-3], yyvsp[-1] ); + } + } +break; +case 48: +/* #line 574 "third_party/lex/parse.y" */ +{ + varlength = true; + + if ( yyvsp[-2] <= 0 ) + { + synerr( _("iteration value must be positive") ); + yyval = yyvsp[-4]; + } + + else + yyval = mkrep( yyvsp[-4], yyvsp[-2], INFINITE_REPEAT ); + } +break; +case 49: +/* #line 588 "third_party/lex/parse.y" */ +{ + /* The series could be something like "(foo)", + * in which case we have no idea what its length + * is, so we punt here. + */ + varlength = true; + + if ( yyvsp[-1] <= 0 ) + { + synerr( _("iteration value must be positive") + ); + yyval = yyvsp[-3]; + } + + else + yyval = link_machines( yyvsp[-3], + copysingl( yyvsp[-3], yyvsp[-1] - 1 ) ); + } +break; +case 50: +/* #line 610 "third_party/lex/parse.y" */ +{ + varlength = true; + + yyval = mkclos( yyvsp[-1] ); + } +break; +case 51: +/* #line 617 "third_party/lex/parse.y" */ +{ + varlength = true; + yyval = mkposcl( yyvsp[-1] ); + } +break; +case 52: +/* #line 623 "third_party/lex/parse.y" */ +{ + varlength = true; + yyval = mkopt( yyvsp[-1] ); + } +break; +case 53: +/* #line 629 "third_party/lex/parse.y" */ +{ + varlength = true; + + if ( yyvsp[-3] > yyvsp[-1] || yyvsp[-3] < 0 ) + { + synerr( _("bad iteration values") ); + yyval = yyvsp[-5]; + } + else + { + if ( yyvsp[-3] == 0 ) + { + if ( yyvsp[-1] <= 0 ) + { + synerr( + _("bad iteration values") ); + yyval = yyvsp[-5]; + } + else + yyval = mkopt( + mkrep( yyvsp[-5], 1, yyvsp[-1] ) ); + } + else + yyval = mkrep( yyvsp[-5], yyvsp[-3], yyvsp[-1] ); + } + } +break; +case 54: +/* #line 657 "third_party/lex/parse.y" */ +{ + varlength = true; + + if ( yyvsp[-2] <= 0 ) + { + synerr( _("iteration value must be positive") ); + yyval = yyvsp[-4]; + } + + else + yyval = mkrep( yyvsp[-4], yyvsp[-2], INFINITE_REPEAT ); + } +break; +case 55: +/* #line 671 "third_party/lex/parse.y" */ +{ + /* The singleton could be something like "(foo)", + * in which case we have no idea what its length + * is, so we punt here. + */ + varlength = true; + + if ( yyvsp[-1] <= 0 ) + { + synerr( _("iteration value must be positive") ); + yyval = yyvsp[-3]; + } + + else + yyval = link_machines( yyvsp[-3], + copysingl( yyvsp[-3], yyvsp[-1] - 1 ) ); + } +break; +case 56: +/* #line 690 "third_party/lex/parse.y" */ +{ + if ( ! madeany ) + { + /* Create the '.' character class. */ + ccldot = cclinit(); + ccladd( ccldot, '\n' ); + cclnegate( ccldot ); + + if ( useecs ) + mkeccl( ccltbl + cclmap[ccldot], + ccllen[ccldot], nextecm, + ecgroup, csize, csize ); + + /* Create the (?s:'.') character class. */ + cclany = cclinit(); + cclnegate( cclany ); + + if ( useecs ) + mkeccl( ccltbl + cclmap[cclany], + ccllen[cclany], nextecm, + ecgroup, csize, csize ); + + madeany = true; + } + + ++rulelen; + + if (sf_dot_all()) + yyval = mkstate( -cclany ); + else + yyval = mkstate( -ccldot ); + } +break; +case 57: +/* #line 724 "third_party/lex/parse.y" */ +{ + /* Sort characters for fast searching. + */ + qsort( ccltbl + cclmap[yyvsp[0]], ccllen[yyvsp[0]], sizeof (*ccltbl), cclcmp ); + + if ( useecs ) + mkeccl( ccltbl + cclmap[yyvsp[0]], ccllen[yyvsp[0]], + nextecm, ecgroup, csize, csize ); + + ++rulelen; + + if (ccl_has_nl[yyvsp[0]]) + rule_has_nl[num_rules] = true; + + yyval = mkstate( -yyvsp[0] ); + } +break; +case 58: +/* #line 742 "third_party/lex/parse.y" */ +{ + ++rulelen; + + if (ccl_has_nl[yyvsp[0]]) + rule_has_nl[num_rules] = true; + + yyval = mkstate( -yyvsp[0] ); + } +break; +case 59: +/* #line 752 "third_party/lex/parse.y" */ +{ yyval = yyvsp[-1]; } +break; +case 60: +/* #line 755 "third_party/lex/parse.y" */ +{ yyval = yyvsp[-1]; } +break; +case 61: +/* #line 758 "third_party/lex/parse.y" */ +{ + ++rulelen; + + if (yyvsp[0] == nlch) + rule_has_nl[num_rules] = true; + + if (sf_case_ins() && has_case(yyvsp[0])) + /* create an alternation, as in (a|A) */ + yyval = mkor (mkstate(yyvsp[0]), mkstate(reverse_case(yyvsp[0]))); + else + yyval = mkstate( yyvsp[0] ); + } +break; +case 62: +/* #line 772 "third_party/lex/parse.y" */ +{ yyval = ccl_set_diff (yyvsp[-2], yyvsp[0]); } +break; +case 63: +/* #line 773 "third_party/lex/parse.y" */ +{ yyval = ccl_set_union (yyvsp[-2], yyvsp[0]); } +break; +case 65: +/* #line 779 "third_party/lex/parse.y" */ +{ yyval = yyvsp[-1]; } +break; +case 66: +/* #line 782 "third_party/lex/parse.y" */ +{ + cclnegate( yyvsp[-1] ); + yyval = yyvsp[-1]; + } +break; +case 67: +/* #line 789 "third_party/lex/parse.y" */ +{ + + if (sf_case_ins()) + { + + /* If one end of the range has case and the other + * does not, or the cases are different, then we're not + * sure what range the user is trying to express. + * Examples: [@-z] or [S-t] + */ + if (has_case (yyvsp[-2]) != has_case (yyvsp[0]) + || (has_case (yyvsp[-2]) && (b_islower (yyvsp[-2]) != b_islower (yyvsp[0]))) + || (has_case (yyvsp[-2]) && (b_isupper (yyvsp[-2]) != b_isupper (yyvsp[0])))) + format_warn3 ( + _("the character range [%c-%c] is ambiguous in a case-insensitive scanner"), + yyvsp[-2], yyvsp[0]); + + /* If the range spans uppercase characters but not + * lowercase (or vice-versa), then should we automatically + * include lowercase characters in the range? + * Example: [@-_] spans [a-z] but not [A-Z] + */ + else if (!has_case (yyvsp[-2]) && !has_case (yyvsp[0]) && !range_covers_case (yyvsp[-2], yyvsp[0])) + format_warn3 ( + _("the character range [%c-%c] is ambiguous in a case-insensitive scanner"), + yyvsp[-2], yyvsp[0]); + } + + if ( yyvsp[-2] > yyvsp[0] ) + synerr( _("negative range in character class") ); + + else + { + for ( i = yyvsp[-2]; i <= yyvsp[0]; ++i ) + ccladd( yyvsp[-3], i ); + + /* Keep track if this ccl is staying in + * alphabetical order. + */ + cclsorted = cclsorted && (yyvsp[-2] > lastchar); + lastchar = yyvsp[0]; + + /* Do it again for upper/lowercase */ + if (sf_case_ins() && has_case(yyvsp[-2]) && has_case(yyvsp[0])){ + yyvsp[-2] = reverse_case (yyvsp[-2]); + yyvsp[0] = reverse_case (yyvsp[0]); + + for ( i = yyvsp[-2]; i <= yyvsp[0]; ++i ) + ccladd( yyvsp[-3], i ); + + cclsorted = cclsorted && (yyvsp[-2] > lastchar); + lastchar = yyvsp[0]; + } + + } + + yyval = yyvsp[-3]; + } +break; +case 68: +/* #line 849 "third_party/lex/parse.y" */ +{ + ccladd( yyvsp[-1], yyvsp[0] ); + cclsorted = cclsorted && (yyvsp[0] > lastchar); + lastchar = yyvsp[0]; + + /* Do it again for upper/lowercase */ + if (sf_case_ins() && has_case(yyvsp[0])){ + yyvsp[0] = reverse_case (yyvsp[0]); + ccladd (yyvsp[-1], yyvsp[0]); + + cclsorted = cclsorted && (yyvsp[0] > lastchar); + lastchar = yyvsp[0]; + } + + yyval = yyvsp[-1]; + } +break; +case 69: +/* #line 867 "third_party/lex/parse.y" */ +{ + /* Too hard to properly maintain cclsorted. */ + cclsorted = false; + yyval = yyvsp[-1]; + } +break; +case 70: +/* #line 874 "third_party/lex/parse.y" */ +{ + cclsorted = true; + lastchar = 0; + currccl = yyval = cclinit(); + } +break; +case 71: +/* #line 882 "third_party/lex/parse.y" */ +{ CCL_EXPR(isalnum); } +break; +case 72: +/* #line 883 "third_party/lex/parse.y" */ +{ CCL_EXPR(isalpha); } +break; +case 73: +/* #line 884 "third_party/lex/parse.y" */ +{ CCL_EXPR(isblank); } +break; +case 74: +/* #line 885 "third_party/lex/parse.y" */ +{ CCL_EXPR(iscntrl); } +break; +case 75: +/* #line 886 "third_party/lex/parse.y" */ +{ CCL_EXPR(isdigit); } +break; +case 76: +/* #line 887 "third_party/lex/parse.y" */ +{ CCL_EXPR(isgraph); } +break; +case 77: +/* #line 888 "third_party/lex/parse.y" */ +{ + CCL_EXPR(islower); + if (sf_case_ins()) + CCL_EXPR(isupper); + } +break; +case 78: +/* #line 893 "third_party/lex/parse.y" */ +{ CCL_EXPR(isprint); } +break; +case 79: +/* #line 894 "third_party/lex/parse.y" */ +{ CCL_EXPR(ispunct); } +break; +case 80: +/* #line 895 "third_party/lex/parse.y" */ +{ CCL_EXPR(isspace); } +break; +case 81: +/* #line 896 "third_party/lex/parse.y" */ +{ CCL_EXPR(isxdigit); } +break; +case 82: +/* #line 897 "third_party/lex/parse.y" */ +{ + CCL_EXPR(isupper); + if (sf_case_ins()) + CCL_EXPR(islower); + } +break; +case 83: +/* #line 903 "third_party/lex/parse.y" */ +{ CCL_NEG_EXPR(isalnum); } +break; +case 84: +/* #line 904 "third_party/lex/parse.y" */ +{ CCL_NEG_EXPR(isalpha); } +break; +case 85: +/* #line 905 "third_party/lex/parse.y" */ +{ CCL_NEG_EXPR(isblank); } +break; +case 86: +/* #line 906 "third_party/lex/parse.y" */ +{ CCL_NEG_EXPR(iscntrl); } +break; +case 87: +/* #line 907 "third_party/lex/parse.y" */ +{ CCL_NEG_EXPR(isdigit); } +break; +case 88: +/* #line 908 "third_party/lex/parse.y" */ +{ CCL_NEG_EXPR(isgraph); } +break; +case 89: +/* #line 909 "third_party/lex/parse.y" */ +{ CCL_NEG_EXPR(isprint); } +break; +case 90: +/* #line 910 "third_party/lex/parse.y" */ +{ CCL_NEG_EXPR(ispunct); } +break; +case 91: +/* #line 911 "third_party/lex/parse.y" */ +{ CCL_NEG_EXPR(isspace); } +break; +case 92: +/* #line 912 "third_party/lex/parse.y" */ +{ CCL_NEG_EXPR(isxdigit); } +break; +case 93: +/* #line 913 "third_party/lex/parse.y" */ +{ + if ( sf_case_ins() ) + lexwarn(_("[:^lower:] is ambiguous in case insensitive scanner")); + else + CCL_NEG_EXPR(islower); + } +break; +case 94: +/* #line 919 "third_party/lex/parse.y" */ +{ + if ( sf_case_ins() ) + lexwarn(_("[:^upper:] ambiguous in case insensitive scanner")); + else + CCL_NEG_EXPR(isupper); + } +break; +case 95: +/* #line 928 "third_party/lex/parse.y" */ +{ + if ( yyvsp[0] == nlch ) + rule_has_nl[num_rules] = true; + + ++rulelen; + + if (sf_case_ins() && has_case(yyvsp[0])) + yyval = mkor (mkstate(yyvsp[0]), mkstate(reverse_case(yyvsp[0]))); + else + yyval = mkstate (yyvsp[0]); + + yyval = link_machines( yyvsp[-1], yyval); + } +break; +case 96: +/* #line 943 "third_party/lex/parse.y" */ +{ yyval = mkstate( SYM_EPSILON ); } +break; +/* #line 1724 "third_party/lex/parse.c" */ + } + yyssp -= yym; + yystate = *yyssp; + yyvsp -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yyssp = YYFINAL; + *++yyvsp = yyval; + if (yychar < 0) + { + if ((yychar = yylex()) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = 0; + if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; + if (!yys) yys = "illegal-symbol"; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yyssp, yystate); +#endif + if (yyssp >= yysslim && yygrowstack()) + { + goto yyoverflow; + } + *++yyssp = yystate; + *++yyvsp = yyval; + goto yyloop; +yyoverflow: + yyerror("yacc stack overflow"); +yyabort: + if (yyss) + free(yyss); + if (yyvs) + free(yyvs); + yyss = yyssp = NULL; + yyvs = yyvsp = NULL; + yystacksize = 0; + return (1); +yyaccept: + if (yyss) + free(yyss); + if (yyvs) + free(yyvs); + yyss = yyssp = NULL; + yyvs = yyvsp = NULL; + yystacksize = 0; + return (0); +} diff --git a/third_party/lex/parse.h b/third_party/lex/parse.h new file mode 100644 index 00000000..7be05c73 --- /dev/null +++ b/third_party/lex/parse.h @@ -0,0 +1,45 @@ +#define CHAR 257 +#define NUMBER 258 +#define SECTEND 259 +#define SCDECL 260 +#define XSCDECL 261 +#define NAME 262 +#define PREVCCL 263 +#define EOF_OP 264 +#define OPTION_OP 265 +#define OPT_OUTFILE 266 +#define OPT_PREFIX 267 +#define OPT_YYCLASS 268 +#define OPT_HEADER 269 +#define OPT_EXTRA_TYPE 270 +#define OPT_TABLES 271 +#define CCE_ALNUM 272 +#define CCE_ALPHA 273 +#define CCE_BLANK 274 +#define CCE_CNTRL 275 +#define CCE_DIGIT 276 +#define CCE_GRAPH 277 +#define CCE_LOWER 278 +#define CCE_PRINT 279 +#define CCE_PUNCT 280 +#define CCE_SPACE 281 +#define CCE_UPPER 282 +#define CCE_XDIGIT 283 +#define CCE_NEG_ALNUM 284 +#define CCE_NEG_ALPHA 285 +#define CCE_NEG_BLANK 286 +#define CCE_NEG_CNTRL 287 +#define CCE_NEG_DIGIT 288 +#define CCE_NEG_GRAPH 289 +#define CCE_NEG_LOWER 290 +#define CCE_NEG_PRINT 291 +#define CCE_NEG_PUNCT 292 +#define CCE_NEG_SPACE 293 +#define CCE_NEG_UPPER 294 +#define CCE_NEG_XDIGIT 295 +#define CCL_OP_DIFF 296 +#define CCL_OP_UNION 297 +#define BEGIN_REPEAT_POSIX 298 +#define END_REPEAT_POSIX 299 +#define BEGIN_REPEAT_FLEX 300 +#define END_REPEAT_FLEX 301 diff --git a/third_party/lex/parse.y b/third_party/lex/parse.y new file mode 100644 index 00000000..7ff2fd3c --- /dev/null +++ b/third_party/lex/parse.y @@ -0,0 +1,1089 @@ +/* $OpenBSD: parse.y,v 1.10 2017/04/12 14:53:27 millert Exp $ */ + +/* parse.y - parser for flex input */ + +%token CHAR NUMBER SECTEND SCDECL XSCDECL NAME PREVCCL EOF_OP +%token OPTION_OP OPT_OUTFILE OPT_PREFIX OPT_YYCLASS OPT_HEADER OPT_EXTRA_TYPE +%token OPT_TABLES + +%token CCE_ALNUM CCE_ALPHA CCE_BLANK CCE_CNTRL CCE_DIGIT CCE_GRAPH +%token CCE_LOWER CCE_PRINT CCE_PUNCT CCE_SPACE CCE_UPPER CCE_XDIGIT + +%token CCE_NEG_ALNUM CCE_NEG_ALPHA CCE_NEG_BLANK CCE_NEG_CNTRL CCE_NEG_DIGIT CCE_NEG_GRAPH +%token CCE_NEG_LOWER CCE_NEG_PRINT CCE_NEG_PUNCT CCE_NEG_SPACE CCE_NEG_UPPER CCE_NEG_XDIGIT + +%left CCL_OP_DIFF CCL_OP_UNION + +/* + *POSIX and AT&T lex place the + * precedence of the repeat operator, {}, below that of concatenation. + * Thus, ab{3} is ababab. Most other POSIX utilities use an Extended + * Regular Expression (ERE) precedence that has the repeat operator + * higher than concatenation. This causes ab{3} to yield abbb. + * + * In order to support the POSIX and AT&T precedence and the flex + * precedence we define two token sets for the begin and end tokens of + * the repeat operator, '{' and '}'. The lexical scanner chooses + * which tokens to return based on whether posix_compat or lex_compat + * are specified. Specifying either posix_compat or lex_compat will + * cause flex to parse scanner files as per the AT&T and + * POSIX-mandated behavior. + */ + +%token BEGIN_REPEAT_POSIX END_REPEAT_POSIX BEGIN_REPEAT_FLEX END_REPEAT_FLEX + + +%{ +/* Copyright (c) 1990 The Regents of the University of California. */ +/* All rights reserved. */ + +/* This code is derived from software contributed to Berkeley by */ +/* Vern Paxson. */ + +/* The United States Government has rights in this work pursuant */ +/* to contract no. DE-AC03-76SF00098 between the United States */ +/* Department of Energy and the University of California. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + +#include "third_party/lex/flexdef.h" +#include "libc/fmt/fmt.h" +#include "third_party/lex/tables.h" + +int pat, scnum, eps, headcnt, trailcnt, lastchar, i, rulelen; +int trlcontxt, xcluflg, currccl, cclsorted, varlength, variable_trail_rule; + +int *scon_stk; +int scon_stk_ptr; + +static int madeany = false; /* whether we've made the '.' character class */ +static int ccldot, cclany; +int previous_continued_action; /* whether the previous rule's action was '|' */ + +#define format_warn3(fmt, a1, a2) \ + do{ \ + char fw3_msg[MAXLINE];\ + snprintf( fw3_msg, MAXLINE,(fmt), (a1), (a2) );\ + lexwarn( fw3_msg );\ + }while(0) + +/* Expand a POSIX character class expression. */ +#define CCL_EXPR(func) \ + do{ \ + int c; \ + for ( c = 0; c < csize; ++c ) \ + if ( isascii(c) && func(c) ) \ + ccladd( currccl, c ); \ + }while(0) + +/* negated class */ +#define CCL_NEG_EXPR(func) \ + do{ \ + int c; \ + for ( c = 0; c < csize; ++c ) \ + if ( !func(c) ) \ + ccladd( currccl, c ); \ + }while(0) + +/* On some over-ambitious machines, such as DEC Alpha's, the default + * token type is "long" instead of "int"; this leads to problems with + * declaring yylval in flexdef.h. But so far, all the yacc's I've seen + * wrap their definitions of YYSTYPE with "#ifndef YYSTYPE"'s, so the + * following should ensure that the default token type is "int". + */ +#define YYSTYPE int + +%} + +%% +goal : initlex sect1 sect1end sect2 initforrule + { /* add default rule */ + int def_rule; + + pat = cclinit(); + cclnegate( pat ); + + def_rule = mkstate( -pat ); + + /* Remember the number of the default rule so we + * don't generate "can't match" warnings for it. + */ + default_rule = num_rules; + + finish_rule( def_rule, false, 0, 0, 0); + + for ( i = 1; i <= lastsc; ++i ) + scset[i] = mkbranch( scset[i], def_rule ); + + if ( spprdflt ) + add_action( + "YY_FATAL_ERROR( \"flex scanner jammed\" )" ); + else + add_action( "ECHO" ); + + add_action( ";\n\tYY_BREAK\n" ); + } + ; + +initlex : + { /* initialize for processing rules */ + + /* Create default DFA start condition. */ + scinstal( "INITIAL", false ); + } + ; + +sect1 : sect1 startconddecl namelist1 + | sect1 options + | + | error + { synerr( _("unknown error processing section 1") ); } + ; + +sect1end : SECTEND + { + check_options(); + scon_stk = allocate_integer_array( lastsc + 1 ); + scon_stk_ptr = 0; + } + ; + +startconddecl : SCDECL + { xcluflg = false; } + + | XSCDECL + { xcluflg = true; } + ; + +namelist1 : namelist1 NAME + { scinstal( nmstr, xcluflg ); } + + | NAME + { scinstal( nmstr, xcluflg ); } + + | error + { synerr( _("bad start condition list") ); } + ; + +options : OPTION_OP optionlist + ; + +optionlist : optionlist option + | + ; + +option : OPT_OUTFILE '=' NAME + { + outfilename = copy_string( nmstr ); + did_outfilename = 1; + } + | OPT_EXTRA_TYPE '=' NAME + { extra_type = copy_string( nmstr ); } + | OPT_PREFIX '=' NAME + { prefix = copy_string( nmstr ); } + | OPT_YYCLASS '=' NAME + { yyclass = copy_string( nmstr ); } + | OPT_HEADER '=' NAME + { headerfilename = copy_string( nmstr ); } + | OPT_TABLES '=' NAME + { tablesext = true; tablesfilename = copy_string( nmstr ); } + ; + +sect2 : sect2 scon initforrule flexrule '\n' + { scon_stk_ptr = $2; } + | sect2 scon '{' sect2 '}' + { scon_stk_ptr = $2; } + | + ; + +initforrule : + { + /* Initialize for a parse of one rule. */ + trlcontxt = variable_trail_rule = varlength = false; + trailcnt = headcnt = rulelen = 0; + current_state_type = STATE_NORMAL; + previous_continued_action = continued_action; + in_rule = true; + + new_rule(); + } + ; + +flexrule : '^' rule + { + pat = $2; + finish_rule( pat, variable_trail_rule, + headcnt, trailcnt , previous_continued_action); + + if ( scon_stk_ptr > 0 ) + { + for ( i = 1; i <= scon_stk_ptr; ++i ) + scbol[scon_stk[i]] = + mkbranch( scbol[scon_stk[i]], + pat ); + } + + else + { + /* Add to all non-exclusive start conditions, + * including the default (0) start condition. + */ + + for ( i = 1; i <= lastsc; ++i ) + if ( ! scxclu[i] ) + scbol[i] = mkbranch( scbol[i], + pat ); + } + + if ( ! bol_needed ) + { + bol_needed = true; + + if ( performance_report > 1 ) + pinpoint_message( + "'^' operator results in sub-optimal performance" ); + } + } + + | rule + { + pat = $1; + finish_rule( pat, variable_trail_rule, + headcnt, trailcnt , previous_continued_action); + + if ( scon_stk_ptr > 0 ) + { + for ( i = 1; i <= scon_stk_ptr; ++i ) + scset[scon_stk[i]] = + mkbranch( scset[scon_stk[i]], + pat ); + } + + else + { + for ( i = 1; i <= lastsc; ++i ) + if ( ! scxclu[i] ) + scset[i] = + mkbranch( scset[i], + pat ); + } + } + + | EOF_OP + { + if ( scon_stk_ptr > 0 ) + build_eof_action(); + + else + { + /* This EOF applies to all start conditions + * which don't already have EOF actions. + */ + for ( i = 1; i <= lastsc; ++i ) + if ( ! sceof[i] ) + scon_stk[++scon_stk_ptr] = i; + + if ( scon_stk_ptr == 0 ) + lexwarn( + "all start conditions already have <> rules" ); + + else + build_eof_action(); + } + } + + | error + { synerr( _("unrecognized rule") ); } + ; + +scon_stk_ptr : + { $$ = scon_stk_ptr; } + ; + +scon : '<' scon_stk_ptr namelist2 '>' + { $$ = $2; } + + | '<' '*' '>' + { + $$ = scon_stk_ptr; + + for ( i = 1; i <= lastsc; ++i ) + { + int j; + + for ( j = 1; j <= scon_stk_ptr; ++j ) + if ( scon_stk[j] == i ) + break; + + if ( j > scon_stk_ptr ) + scon_stk[++scon_stk_ptr] = i; + } + } + + | + { $$ = scon_stk_ptr; } + ; + +namelist2 : namelist2 ',' sconname + + | sconname + + | error + { synerr( _("bad start condition list") ); } + ; + +sconname : NAME + { + if ( (scnum = sclookup( nmstr )) == 0 ) + format_pinpoint_message( + "undeclared start condition %s", + nmstr ); + else + { + for ( i = 1; i <= scon_stk_ptr; ++i ) + if ( scon_stk[i] == scnum ) + { + format_warn( + "<%s> specified twice", + scname[scnum] ); + break; + } + + if ( i > scon_stk_ptr ) + scon_stk[++scon_stk_ptr] = scnum; + } + } + ; + +rule : re2 re + { + if ( transchar[lastst[$2]] != SYM_EPSILON ) + /* Provide final transition \now/ so it + * will be marked as a trailing context + * state. + */ + $2 = link_machines( $2, + mkstate( SYM_EPSILON ) ); + + mark_beginning_as_normal( $2 ); + current_state_type = STATE_NORMAL; + + if ( previous_continued_action ) + { + /* We need to treat this as variable trailing + * context so that the backup does not happen + * in the action but before the action switch + * statement. If the backup happens in the + * action, then the rules "falling into" this + * one's action will *also* do the backup, + * erroneously. + */ + if ( ! varlength || headcnt != 0 ) + lexwarn( + "trailing context made variable due to preceding '|' action" ); + + /* Mark as variable. */ + varlength = true; + headcnt = 0; + + } + + if ( lex_compat || (varlength && headcnt == 0) ) + { /* variable trailing context rule */ + /* Mark the first part of the rule as the + * accepting "head" part of a trailing + * context rule. + * + * By the way, we didn't do this at the + * beginning of this production because back + * then current_state_type was set up for a + * trail rule, and add_accept() can create + * a new state ... + */ + add_accept( $1, + num_rules | YY_TRAILING_HEAD_MASK ); + variable_trail_rule = true; + } + + else + trailcnt = rulelen; + + $$ = link_machines( $1, $2 ); + } + + | re2 re '$' + { synerr( _("trailing context used twice") ); } + + | re '$' + { + headcnt = 0; + trailcnt = 1; + rulelen = 1; + varlength = false; + + current_state_type = STATE_TRAILING_CONTEXT; + + if ( trlcontxt ) + { + synerr( _("trailing context used twice") ); + $$ = mkstate( SYM_EPSILON ); + } + + else if ( previous_continued_action ) + { + /* See the comment in the rule for "re2 re" + * above. + */ + lexwarn( + "trailing context made variable due to preceding '|' action" ); + + varlength = true; + } + + if ( lex_compat || varlength ) + { + /* Again, see the comment in the rule for + * "re2 re" above. + */ + add_accept( $1, + num_rules | YY_TRAILING_HEAD_MASK ); + variable_trail_rule = true; + } + + trlcontxt = true; + + eps = mkstate( SYM_EPSILON ); + $$ = link_machines( $1, + link_machines( eps, mkstate( '\n' ) ) ); + } + + | re + { + $$ = $1; + + if ( trlcontxt ) + { + if ( lex_compat || (varlength && headcnt == 0) ) + /* Both head and trail are + * variable-length. + */ + variable_trail_rule = true; + else + trailcnt = rulelen; + } + } + ; + + +re : re '|' series + { + varlength = true; + $$ = mkor( $1, $3 ); + } + + | series + { $$ = $1; } + ; + + +re2 : re '/' + { + /* This rule is written separately so the + * reduction will occur before the trailing + * series is parsed. + */ + + if ( trlcontxt ) + synerr( _("trailing context used twice") ); + else + trlcontxt = true; + + if ( varlength ) + /* We hope the trailing context is + * fixed-length. + */ + varlength = false; + else + headcnt = rulelen; + + rulelen = 0; + + current_state_type = STATE_TRAILING_CONTEXT; + $$ = $1; + } + ; + +series : series singleton + { + /* This is where concatenation of adjacent patterns + * gets done. + */ + $$ = link_machines( $1, $2 ); + } + + | singleton + { $$ = $1; } + + | series BEGIN_REPEAT_POSIX NUMBER ',' NUMBER END_REPEAT_POSIX + { + varlength = true; + + if ( $3 > $5 || $3 < 0 ) + { + synerr( _("bad iteration values") ); + $$ = $1; + } + else + { + if ( $3 == 0 ) + { + if ( $5 <= 0 ) + { + synerr( + _("bad iteration values") ); + $$ = $1; + } + else + $$ = mkopt( + mkrep( $1, 1, $5 ) ); + } + else + $$ = mkrep( $1, $3, $5 ); + } + } + + | series BEGIN_REPEAT_POSIX NUMBER ',' END_REPEAT_POSIX + { + varlength = true; + + if ( $3 <= 0 ) + { + synerr( _("iteration value must be positive") ); + $$ = $1; + } + + else + $$ = mkrep( $1, $3, INFINITE_REPEAT ); + } + + | series BEGIN_REPEAT_POSIX NUMBER END_REPEAT_POSIX + { + /* The series could be something like "(foo)", + * in which case we have no idea what its length + * is, so we punt here. + */ + varlength = true; + + if ( $3 <= 0 ) + { + synerr( _("iteration value must be positive") + ); + $$ = $1; + } + + else + $$ = link_machines( $1, + copysingl( $1, $3 - 1 ) ); + } + + ; + +singleton : singleton '*' + { + varlength = true; + + $$ = mkclos( $1 ); + } + + | singleton '+' + { + varlength = true; + $$ = mkposcl( $1 ); + } + + | singleton '?' + { + varlength = true; + $$ = mkopt( $1 ); + } + + | singleton BEGIN_REPEAT_FLEX NUMBER ',' NUMBER END_REPEAT_FLEX + { + varlength = true; + + if ( $3 > $5 || $3 < 0 ) + { + synerr( _("bad iteration values") ); + $$ = $1; + } + else + { + if ( $3 == 0 ) + { + if ( $5 <= 0 ) + { + synerr( + _("bad iteration values") ); + $$ = $1; + } + else + $$ = mkopt( + mkrep( $1, 1, $5 ) ); + } + else + $$ = mkrep( $1, $3, $5 ); + } + } + + | singleton BEGIN_REPEAT_FLEX NUMBER ',' END_REPEAT_FLEX + { + varlength = true; + + if ( $3 <= 0 ) + { + synerr( _("iteration value must be positive") ); + $$ = $1; + } + + else + $$ = mkrep( $1, $3, INFINITE_REPEAT ); + } + + | singleton BEGIN_REPEAT_FLEX NUMBER END_REPEAT_FLEX + { + /* The singleton could be something like "(foo)", + * in which case we have no idea what its length + * is, so we punt here. + */ + varlength = true; + + if ( $3 <= 0 ) + { + synerr( _("iteration value must be positive") ); + $$ = $1; + } + + else + $$ = link_machines( $1, + copysingl( $1, $3 - 1 ) ); + } + + | '.' + { + if ( ! madeany ) + { + /* Create the '.' character class. */ + ccldot = cclinit(); + ccladd( ccldot, '\n' ); + cclnegate( ccldot ); + + if ( useecs ) + mkeccl( ccltbl + cclmap[ccldot], + ccllen[ccldot], nextecm, + ecgroup, csize, csize ); + + /* Create the (?s:'.') character class. */ + cclany = cclinit(); + cclnegate( cclany ); + + if ( useecs ) + mkeccl( ccltbl + cclmap[cclany], + ccllen[cclany], nextecm, + ecgroup, csize, csize ); + + madeany = true; + } + + ++rulelen; + + if (sf_dot_all()) + $$ = mkstate( -cclany ); + else + $$ = mkstate( -ccldot ); + } + + | fullccl + { + /* Sort characters for fast searching. + */ + qsort( ccltbl + cclmap[$1], ccllen[$1], sizeof (*ccltbl), cclcmp ); + + if ( useecs ) + mkeccl( ccltbl + cclmap[$1], ccllen[$1], + nextecm, ecgroup, csize, csize ); + + ++rulelen; + + if (ccl_has_nl[$1]) + rule_has_nl[num_rules] = true; + + $$ = mkstate( -$1 ); + } + + | PREVCCL + { + ++rulelen; + + if (ccl_has_nl[$1]) + rule_has_nl[num_rules] = true; + + $$ = mkstate( -$1 ); + } + + | '"' string '"' + { $$ = $2; } + + | '(' re ')' + { $$ = $2; } + + | CHAR + { + ++rulelen; + + if ($1 == nlch) + rule_has_nl[num_rules] = true; + + if (sf_case_ins() && has_case($1)) + /* create an alternation, as in (a|A) */ + $$ = mkor (mkstate($1), mkstate(reverse_case($1))); + else + $$ = mkstate( $1 ); + } + ; +fullccl: + fullccl CCL_OP_DIFF braceccl { $$ = ccl_set_diff ($1, $3); } + | fullccl CCL_OP_UNION braceccl { $$ = ccl_set_union ($1, $3); } + | braceccl + ; + +braceccl: + + '[' ccl ']' { $$ = $2; } + + | '[' '^' ccl ']' + { + cclnegate( $3 ); + $$ = $3; + } + ; + +ccl : ccl CHAR '-' CHAR + { + + if (sf_case_ins()) + { + + /* If one end of the range has case and the other + * does not, or the cases are different, then we're not + * sure what range the user is trying to express. + * Examples: [@-z] or [S-t] + */ + if (has_case ($2) != has_case ($4) + || (has_case ($2) && (b_islower ($2) != b_islower ($4))) + || (has_case ($2) && (b_isupper ($2) != b_isupper ($4)))) + format_warn3 ( + _("the character range [%c-%c] is ambiguous in a case-insensitive scanner"), + $2, $4); + + /* If the range spans uppercase characters but not + * lowercase (or vice-versa), then should we automatically + * include lowercase characters in the range? + * Example: [@-_] spans [a-z] but not [A-Z] + */ + else if (!has_case ($2) && !has_case ($4) && !range_covers_case ($2, $4)) + format_warn3 ( + _("the character range [%c-%c] is ambiguous in a case-insensitive scanner"), + $2, $4); + } + + if ( $2 > $4 ) + synerr( _("negative range in character class") ); + + else + { + for ( i = $2; i <= $4; ++i ) + ccladd( $1, i ); + + /* Keep track if this ccl is staying in + * alphabetical order. + */ + cclsorted = cclsorted && ($2 > lastchar); + lastchar = $4; + + /* Do it again for upper/lowercase */ + if (sf_case_ins() && has_case($2) && has_case($4)){ + $2 = reverse_case ($2); + $4 = reverse_case ($4); + + for ( i = $2; i <= $4; ++i ) + ccladd( $1, i ); + + cclsorted = cclsorted && ($2 > lastchar); + lastchar = $4; + } + + } + + $$ = $1; + } + + | ccl CHAR + { + ccladd( $1, $2 ); + cclsorted = cclsorted && ($2 > lastchar); + lastchar = $2; + + /* Do it again for upper/lowercase */ + if (sf_case_ins() && has_case($2)){ + $2 = reverse_case ($2); + ccladd ($1, $2); + + cclsorted = cclsorted && ($2 > lastchar); + lastchar = $2; + } + + $$ = $1; + } + + | ccl ccl_expr + { + /* Too hard to properly maintain cclsorted. */ + cclsorted = false; + $$ = $1; + } + + | + { + cclsorted = true; + lastchar = 0; + currccl = $$ = cclinit(); + } + ; + +ccl_expr: + CCE_ALNUM { CCL_EXPR(isalnum); } + | CCE_ALPHA { CCL_EXPR(isalpha); } + | CCE_BLANK { CCL_EXPR(isblank); } + | CCE_CNTRL { CCL_EXPR(iscntrl); } + | CCE_DIGIT { CCL_EXPR(isdigit); } + | CCE_GRAPH { CCL_EXPR(isgraph); } + | CCE_LOWER { + CCL_EXPR(islower); + if (sf_case_ins()) + CCL_EXPR(isupper); + } + | CCE_PRINT { CCL_EXPR(isprint); } + | CCE_PUNCT { CCL_EXPR(ispunct); } + | CCE_SPACE { CCL_EXPR(isspace); } + | CCE_XDIGIT { CCL_EXPR(isxdigit); } + | CCE_UPPER { + CCL_EXPR(isupper); + if (sf_case_ins()) + CCL_EXPR(islower); + } + + | CCE_NEG_ALNUM { CCL_NEG_EXPR(isalnum); } + | CCE_NEG_ALPHA { CCL_NEG_EXPR(isalpha); } + | CCE_NEG_BLANK { CCL_NEG_EXPR(isblank); } + | CCE_NEG_CNTRL { CCL_NEG_EXPR(iscntrl); } + | CCE_NEG_DIGIT { CCL_NEG_EXPR(isdigit); } + | CCE_NEG_GRAPH { CCL_NEG_EXPR(isgraph); } + | CCE_NEG_PRINT { CCL_NEG_EXPR(isprint); } + | CCE_NEG_PUNCT { CCL_NEG_EXPR(ispunct); } + | CCE_NEG_SPACE { CCL_NEG_EXPR(isspace); } + | CCE_NEG_XDIGIT { CCL_NEG_EXPR(isxdigit); } + | CCE_NEG_LOWER { + if ( sf_case_ins() ) + lexwarn(_("[:^lower:] is ambiguous in case insensitive scanner")); + else + CCL_NEG_EXPR(islower); + } + | CCE_NEG_UPPER { + if ( sf_case_ins() ) + lexwarn(_("[:^upper:] ambiguous in case insensitive scanner")); + else + CCL_NEG_EXPR(isupper); + } + ; + +string : string CHAR + { + if ( $2 == nlch ) + rule_has_nl[num_rules] = true; + + ++rulelen; + + if (sf_case_ins() && has_case($2)) + $$ = mkor (mkstate($2), mkstate(reverse_case($2))); + else + $$ = mkstate ($2); + + $$ = link_machines( $1, $$); + } + + | + { $$ = mkstate( SYM_EPSILON ); } + ; + +%% + + +/* build_eof_action - build the "<>" action for the active start + * conditions + */ + +void build_eof_action() + { + int i2; + char action_text[MAXLINE]; + + for ( i2 = 1; i2 <= scon_stk_ptr; ++i2 ) + { + if ( sceof[scon_stk[i2]] ) + format_pinpoint_message( + "multiple <> rules for start condition %s", + scname[scon_stk[i2]] ); + + else + { + sceof[scon_stk[i2]] = true; + + if (previous_continued_action /* && previous action was regular */) + add_action("YY_RULE_SETUP\n"); + + snprintf( action_text, sizeof(action_text), "case YY_STATE_EOF(%s):\n", + scname[scon_stk[i2]] ); + add_action( action_text ); + } + } + + line_directive_out( (FILE *) 0, 1 ); + + /* This isn't a normal rule after all - don't count it as + * such, so we don't have any holes in the rule numbering + * (which make generating "rule can never match" warnings + * more difficult. + */ + --num_rules; + ++num_eof_rules; + } + + +/* format_synerr - write out formatted syntax error */ + +void format_synerr( msg, arg ) +const char *msg, arg[]; + { + char errmsg[MAXLINE]; + + (void) snprintf( errmsg, sizeof(errmsg), msg, arg ); + synerr( errmsg ); + } + + +/* synerr - report a syntax error */ + +void synerr( str ) +const char *str; + { + syntaxerror = true; + pinpoint_message( str ); + } + + +/* format_warn - write out formatted warning */ + +void format_warn( msg, arg ) +const char *msg, arg[]; + { + char warn_msg[MAXLINE]; + + snprintf( warn_msg, sizeof(warn_msg), msg, arg ); + lexwarn( warn_msg ); + } + + +/* warn - report a warning, unless -w was given */ + +void lexwarn( str ) +const char *str; + { + line_warning( str, linenum ); + } + +/* format_pinpoint_message - write out a message formatted with one string, + * pinpointing its location + */ + +void format_pinpoint_message( msg, arg ) +const char *msg, arg[]; + { + char errmsg[MAXLINE]; + + snprintf( errmsg, sizeof(errmsg), msg, arg ); + pinpoint_message( errmsg ); + } + + +/* pinpoint_message - write out a message, pinpointing its location */ + +void pinpoint_message( str ) +const char *str; + { + line_pinpoint( str, linenum ); + } + + +/* line_warning - report a warning at a given line, unless -w was given */ + +void line_warning( str, line ) +const char *str; +int line; + { + char warning[MAXLINE]; + + if ( ! nowarn ) + { + snprintf( warning, sizeof(warning), "warning, %s", str ); + line_pinpoint( warning, line ); + } + } + + +/* line_pinpoint - write out a message, pinpointing it at the given line */ + +void line_pinpoint( str, line ) +const char *str; +int line; + { + fprintf( stderr, "%s:%d: %s\n", infilename, line, str ); + } + + +/* yyerror - eat up an error message from the parser; + * currently, messages are ignore + */ + +void yyerror( msg ) +const char *msg; + { + } diff --git a/third_party/lex/regex.c b/third_party/lex/regex.c new file mode 100644 index 00000000..0dacf585 --- /dev/null +++ b/third_party/lex/regex.c @@ -0,0 +1,181 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 sw=8 fenc=utf-8 :vi│ +└─────────────────────────────────────────────────────────────────────────────*/ + +/* clang-format off */ +/* $OpenBSD: regex.c,v 1.3 2015/11/19 23:20:34 tedu Exp $ */ + +/** regex - regular expression functions related to POSIX regex lib. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + +#include "libc/str/str.h" +#include "libc/mem/mem.h" +#include "libc/fmt/fmt.h" +#include "libc/conv/conv.h" +#include "flexdef.h" + + +static const char* REGEXP_LINEDIR = "^#line ([[:digit:]]+) \"(.*)\""; +static const char* REGEXP_BLANK_LINE = "^[[:space:]]*$"; + +regex_t regex_linedir; /**< matches line directives */ +regex_t regex_blank_line; /**< matches blank lines */ + + +/** Initialize the regular expressions. + * @return true upon success. + */ +bool flex_init_regex(void) +{ + flex_regcomp(®ex_linedir, REGEXP_LINEDIR, REG_EXTENDED); + flex_regcomp(®ex_blank_line, REGEXP_BLANK_LINE, REG_EXTENDED); + + return true; +} + +/** Compiles a regular expression or dies trying. + * @param preg Same as for regcomp(). + * @param regex Same as for regcomp(). + * @param cflags Same as for regcomp(). + */ +void flex_regcomp(regex_t *preg, const char *regex, int cflags) +{ + int err; + + memset (preg, 0, sizeof (regex_t)); + + if ((err = regcomp (preg, regex, cflags)) != 0) { + const int errbuf_sz = 200; + char *errbuf, *rxerr; + + errbuf = (char*)malloc(errbuf_sz *sizeof(char)); + if (!errbuf) + flexfatal(_("Unable to allocate buffer to report regcomp")); + rxerr = (char*)malloc(errbuf_sz *sizeof(char)); + if (!rxerr) + flexfatal(_("Unable to allocate buffer for regerror")); + regerror (err, preg, rxerr, errbuf_sz); + snprintf (errbuf, errbuf_sz, "regcomp for \"%s\" failed: %s", regex, rxerr); + + flexfatal (errbuf); + free(errbuf); + free(rxerr); + } +} + +/** Extract a copy of the match, or NULL if no match. + * @param m A match as returned by regexec(). + * @param src The source string that was passed to regexec(). + * @return The allocated string. + */ +char *regmatch_dup (regmatch_t * m, const char *src) +{ + char *str; + int len; + + if (m == NULL || m->rm_so < 0) + return NULL; + len = m->rm_eo - m->rm_so; + str = (char *) malloc ((len + 1) * sizeof (char)); + if (!str) + flexfatal(_("Unable to allocate a copy of the match")); + strncpy (str, src + m->rm_so, len); + str[len] = 0; + return str; +} + +/** Copy the match. + * @param m A match as returned by regexec(). + * @param dest The destination buffer. + * @param src The source string that was passed to regexec(). + * @return dest + */ +char *regmatch_cpy (regmatch_t * m, char *dest, const char *src) +{ + if (m == NULL || m->rm_so < 0) { + if (dest) + dest[0] = '\0'; + return dest; + } + + snprintf (dest, regmatch_len(m), "%s", src + m->rm_so); + return dest; +} + +/** Get the length in characters of the match. + * @param m A match as returned by regexec(). + * @param src The source string that was passed to regexec(). + * @return The length of the match. + */ +int regmatch_len (regmatch_t * m) +{ + if (m == NULL || m->rm_so < 0) { + return 0; + } + + return m->rm_eo - m->rm_so; +} + + + +/** Convert a regmatch_t object to an integer using the strtol() function. + * @param m A match as returned by regexec(). + * @param src The source string that was passed to regexec(). + * @param endptr Same as the second argument to strtol(). + * @param base Same as the third argument to strtol(). + * @return The converted integer or error (Return value is the same as for strtol()). + */ +int regmatch_strtol (regmatch_t * m, const char *src, char **endptr, + int base2) +{ + int n = 0; + +#define bufsz 20 + char buf[bufsz]; + char *s; + + if (m == NULL || m->rm_so < 0) + return 0; + + if (regmatch_len (m) < bufsz) + s = regmatch_cpy (m, buf, src); + else + s = regmatch_dup (m, src); + + n = strtol (s, endptr, base2); + + if (s != buf) + free (s); + + return n; +} + +/** Check for empty or non-existent match. + * @param m A match as returned by regexec(). + * @return false if match length is non-zero. + * Note that reg_empty returns true even if match did not occur at all. + */ +bool regmatch_empty (regmatch_t * m) +{ + return (m == NULL || m->rm_so < 0 || m->rm_so == m->rm_eo); +} diff --git a/third_party/lex/scan.c b/third_party/lex/scan.c new file mode 100644 index 00000000..3064cf93 --- /dev/null +++ b/third_party/lex/scan.c @@ -0,0 +1,4588 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│vi: set et ft=c ts=8 sw=8 fenc=utf-8 :vi│ +└─────────────────────────────────────────────────────────────────────────────*/ +/* clang-format off */ + +#define YY_INT_ALIGNED short int + +/* $OpenBSD: flex.skl,v 1.16 2017/05/02 19:16:19 millert Exp $ */ + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 39 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +#include "libc/limits.h" +#include "libc/sysv/consts/exit.h" +#include "libc/errno.h" +#include "libc/stdio/stdio.h" + +/* $OpenBSD: flexint.h,v 1.1 2015/11/19 19:43:40 tedu Exp $ */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767 - 1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647 - 1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined(__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int)(unsigned char)c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start)-1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart(yyin) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the + * main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +#define YY_LESS_LINENO(n) +#define YY_LINENO_REWIND_TO(ptr) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg); \ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET(yy_c_buf_p) = yy_cp = \ + yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } while (0) + +#define unput(c) yyunput(c, (yytext_ptr)) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 +}; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE *yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER \ + ((yy_buffer_stack) ? (yy_buffer_stack)[(yy_buffer_stack_top)] : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *)0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart(FILE *input_file); +void yy_switch_to_buffer(YY_BUFFER_STATE new_buffer); +YY_BUFFER_STATE yy_create_buffer(FILE *file, int size); +void yy_delete_buffer(YY_BUFFER_STATE b); +void yy_flush_buffer(YY_BUFFER_STATE b); +void yypush_buffer_state(YY_BUFFER_STATE new_buffer); +void yypop_buffer_state(void); + +static void yyensure_buffer_stack(void); +static void yy_load_buffer_state(void); +static void yy_init_buffer(YY_BUFFER_STATE b, FILE *file); + +#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER) + +YY_BUFFER_STATE yy_scan_buffer(char *base, yy_size_t size); +YY_BUFFER_STATE yy_scan_string(yyconst char *yy_str); +YY_BUFFER_STATE yy_scan_bytes(yyconst char *bytes, yy_size_t len); + +void *yyalloc(yy_size_t); +void *yyrealloc(void *, yy_size_t); +void yyfree(void *); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if (!YY_CURRENT_BUFFER) { \ + yyensure_buffer_stack(); \ + YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin, YY_BUF_SIZE); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if (!YY_CURRENT_BUFFER) { \ + yyensure_buffer_stack(); \ + YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin, YY_BUF_SIZE); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +typedef unsigned char YY_CHAR; + +FILE *yyin = (FILE *)0, *yyout = (FILE *)0; + +typedef int yy_state_type; + +extern int yylineno; + +int yylineno = 1; + +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state(void); +static yy_state_type yy_try_NUL_trans(yy_state_type current_state); +static int yy_get_next_buffer(void); +static void yy_fatal_error(yyconst char msg[]); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + (yytext_ptr) -= (yy_more_len); \ + yyleng = (size_t)(yy_cp - (yytext_ptr)); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 251 +#define YY_END_OF_BUFFER 252 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; +}; +static yyconst flex_int16_t yy_acclist[1223] = { + 0, 248, 248, 252, 250, 251, 9, 250, 251, 20, 250, 251, 250, 251, 18, + 250, 251, 1, 9, 250, 251, 19, 20, 250, 251, 250, 251, 250, 251, 250, + 251, 250, 251, 17, 18, 250, 251, 164, 250, 251, 149, 164, 250, 251, 150, + 250, 251, 164, 250, 251, 142, 164, 250, 251, 164, 250, 251, 161, 163, 164, + 250, 251, 162, 163, 164, 250, 251, 163, 164, 250, 251, 163, 164, 250, 251, + 164, 250, 251, 164, 250, 251, 164, 250, 251, 163, 164, 250, 251, 148, 149, + 164, 250, 251, 138, 150, 250, 251, 164, 250, 251, 164, + + 250, 251, 140, 164, 250, 251, 141, 164, 250, 251, 136, 250, 251, 137, 250, + 251, 136, 250, 251, 135, 136, 250, 251, 134, 136, 250, 251, 135, 136, 250, + 251, 248, 249, 250, 251, 248, 249, 250, 251, 249, 250, 251, 249, 250, 251, + 41, 250, 251, 42, 250, 251, 41, 250, 251, 41, 250, 251, 41, 250, 251, + 41, 250, 251, 41, 250, 251, 41, 250, 251, 50, 250, 251, 49, 250, 251, + 51, 250, 251, 250, 251, 170, 250, 251, 170, 250, 251, 165, 250, 251, 170, + 250, 251, 166, 170, 250, 251, 167, 170, 250, 251, + + 169, 170, 250, 251, 171, 250, 251, 219, 250, 251, 220, 250, 251, 219, 250, + 251, 217, 219, 250, 251, 216, 219, 250, 251, 218, 219, 250, 251, 172, 250, + 251, 174, 250, 251, 172, 250, 251, 173, 250, 251, 172, 250, 251, 186, 250, + 251, 186, 250, 251, 186, 250, 251, 186, 250, 251, 188, 190, 250, 251, 190, + 250, 251, 188, 190, 250, 251, 188, 190, 250, 251, 188, 190, 250, 251, 188, + 190, 250, 251, 189, 190, 250, 251, 233, 239, 250, 251, 238, 250, 251, 233, + 239, 250, 251, 237, 239, 250, 251, 239, 250, 251, + + 239, 250, 251, 235, 239, 250, 251, 235, 239, 250, 251, 235, 239, 250, 251, + 234, 239, 250, 251, 234, 239, 250, 251, 229, 239, 250, 251, 230, 239, 250, + 251, 250, 251, 131, 250, 251, 250, 251, 25, 250, 251, 26, 250, 251, 25, + 250, 251, 22, 250, 251, 25, 250, 251, 25, 250, 251, 240, 244, 250, 251, + 242, 250, 251, 240, 244, 250, 251, 243, 244, 250, 251, 244, 250, 251, 227, + 250, 251, 227, 250, 251, 228, 250, 251, 227, 250, 251, 227, 250, 251, 227, + 250, 251, 227, 250, 251, 227, 250, 251, 227, 250, + + 251, 227, 250, 251, 130, 250, 251, 53, 130, 250, 251, 52, 250, 251, 130, + 250, 251, 130, 250, 251, 130, 250, 251, 130, 250, 251, 54, 130, 250, 251, + 130, 250, 251, 130, 250, 251, 130, 250, 251, 130, 250, 251, 130, 250, 251, + 130, 250, 251, 130, 250, 251, 130, 250, 251, 130, 250, 251, 130, 250, 251, + 130, 250, 251, 130, 250, 251, 130, 250, 251, 130, 250, 251, 130, 250, 251, + 130, 250, 251, 130, 250, 251, 130, 250, 251, 130, 250, 251, 130, 250, 251, + 130, 250, 251, 37, 250, 251, 34, 250, 251, 37, + + 250, 251, 35, 37, 250, 251, 48, 250, 251, 45, 250, 251, 250, 251, 48, + 250, 251, 48, 250, 251, 44, 250, 251, 43, 250, 251, 176, 250, 251, 175, + 250, 251, 177, 250, 251, 178, 250, 251, 179, 250, 251, 180, 250, 251, 181, + 250, 251, 182, 250, 251, 183, 250, 251, 32, 250, 251, 33, 250, 251, 32, + 250, 251, 31, 250, 251, 29, 250, 251, 30, 250, 251, 29, 250, 251, 28, + 250, 251, 9, 20, 18, 1, 9, 19, 20, 16, 10, 16, 4, 16, 5, + 2, 17, 18, 149, 150, 144, 160, 158, 154, 154, + + 245, 245, 245, 143, 148, 149, 138, 150, 140, 141, 153, 139, 137, 135, 134, + 134, 132, 135, 133, 135, 248, 248, 246, 247, 42, 39, 40, 50, 49, 51, + 165, 165, 168, 169, 220, 216, 174, 184, 185, 190, 187, 233, 238, 236, 222, + 235, 235, 235, 231, 232, 131, 26, 21, 23, 24, 240, 242, 241, 228, 221, + 225, 226, 53, 52, 129, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, + 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 55, 130, 130, 130, 130, + 130, 130, 130, 130, 130, 130, 130, 36, 35, 45, + + 46, 47, 32, 33, 30, 27, 16, 10, 16, 14, 4, 16, 5, 6, 145, + 146, 159, 154, 154, 154, 154, 154, 245, 245, 156, 155, 157, 139, 145, 147, + 153, 132, 135, 133, 135, 38, 235, 235, 221, 130, 130, 130, 130, 130, 130, + 130, 67, 130, 130, 130, 130, 72, 130, 130, 130, 130, 130, 130, 130, 130, + 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, + 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 14, 15, 4, + 8, 16, 5, 154, 154, 154, 154, 154, 154, 154, + + 245, 157, 235, 235, 56, 57, 130, 130, 130, 130, 130, 130, 130, 130, 130, + 130, 130, 73, 130, 74, 130, 130, 130, 130, 130, 79, 130, 130, 130, 130, + 130, 130, 130, 130, 84, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, + 93, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 15, 8, 16, 8, + 16, 8, 16, 154, 154, 154, 154, 154, 154, 154, 215, 235, 235, 58, 130, + 130, 130, 60, 130, 130, 64, 130, 130, 130, 130, 130, 70, 130, 130, 130, + 130, 75, 130, 130, 130, 130, 130, 130, 130, 130, + + 130, 130, 130, 130, 87, 130, 130, 130, 130, 130, 91, 130, 130, 130, 130, + 130, 130, 130, 130, 130, 130, 130, 3, 8, 16, 7, 8, 16, 154, 154, + 154, 223, 224, 223, 235, 224, 235, 130, 130, 130, 63, 130, 130, 130, 130, + 130, 130, 130, 130, 126, 130, 130, 130, 130, 130, 130, 130, 130, 130, 124, + 130, 130, 86, 130, 130, 89, 130, 130, 90, 130, 130, 130, 130, 105, 130, + 130, 95, 130, 130, 96, 130, 12, 13, 152, 151, 152, 130, 130, 130, 130, + 130, 130, 130, 68, 130, 130, 71, 130, 130, 130, + + 130, 130, 130, 130, 123, 130, 130, 83, 130, 130, 130, 88, 130, 130, 92, + 130, 103, 130, 125, 130, 130, 130, 151, 130, 130, 130, 130, 130, 130, 130, + 69, 130, 130, 130, 130, 130, 80, 130, 130, 130, 130, 130, 130, 130, 114, + 94, 130, 130, 115, 11, 191, 215, 192, 215, 193, 215, 194, 215, 195, 215, + 196, 215, 197, 215, 198, 215, 199, 215, 200, 215, 201, 215, 130, 130, 130, + 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 85, 130, 130, 130, + 116, 104, 130, 117, 202, 215, 203, 215, 204, 215, + + 205, 215, 206, 215, 207, 215, 208, 215, 209, 215, 210, 215, 211, 215, 212, + 215, 213, 215, 130, 130, 130, 130, 130, 130, 130, 122, 130, 130, 130, 77, + 130, 130, 130, 130, 130, 130, 110, 120, 118, 111, 121, 119, 214, 215, 130, + 130, 130, 130, 130, 130, 130, 126, 130, 76, 130, 130, 82, 130, 130, 127, + 130, 130, 106, 108, 107, 109, 130, 130, 130, 65, 130, 130, 130, 130, 130, + 78, 130, 130, 112, 113, 98, 99, 130, 130, 130, 130, 130, 130, 130, 128, + 130, 97, 101, 130, 130, 130, 130, 130, 68, 130, + + 130, 100, 102, 130, 130, 62, 130, 66, 130, 130, 130, 130, 61, 130, 69, + 130, 130, 130, 81, 130, 59, 130}; + +static yyconst flex_int16_t yy_accept[1108] = { + 0, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 4, 6, 9, 12, 14, 17, 21, 25, 27, 29, + 31, 33, 37, 40, 44, 47, 50, 54, 57, 62, 67, 71, + 75, 78, 81, 84, 88, 93, 97, 100, 103, 107, 111, 114, + 117, 120, 124, 128, 132, 136, 140, 143, 146, 149, 152, 155, + 158, 161, 164, 167, 170, + + 173, 176, 179, 181, 184, 187, 190, 193, 197, 201, 205, 208, + 211, 214, 217, 221, 225, 229, 232, 235, 238, 241, 244, 247, + 250, 253, 256, 260, 263, 267, 271, 275, 279, 283, 287, 290, + 294, 298, 301, 304, 308, 312, 316, 320, 324, 328, 332, 334, + 337, 339, 342, 345, 348, 351, 354, 357, 361, 364, 368, 372, + 375, 378, 381, 384, 387, 390, 393, 396, 399, 402, 405, 408, + 412, 415, 418, 421, 424, 427, 431, 434, 437, 440, 443, 446, + 449, 452, 455, 458, 461, 464, 467, 470, 473, 476, 479, 482, + 485, 488, 491, 494, + + 497, 500, 503, 507, 510, 513, 515, 518, 521, 524, 527, 530, + 533, 536, 539, 542, 545, 548, 551, 554, 557, 560, 563, 566, + 569, 572, 575, 578, 579, 580, 580, 581, 583, 585, 585, 585, + 585, 586, 588, 588, 588, 588, 588, 589, 590, 591, 591, 592, + 594, 595, 596, 596, 596, 596, 597, 597, 598, 599, 599, 600, + 601, 601, 602, 603, 604, 604, 604, 605, 605, 607, 609, 609, + 609, 609, 610, 611, 612, 613, 613, 614, 615, 616, 617, 619, + 621, 622, 623, 624, 625, 626, 626, 626, 627, 628, 628, 629, + 630, 631, 631, 632, + + 632, 633, 634, 635, 636, 637, 638, 638, 639, 640, 641, 642, + 643, 644, 644, 645, 645, 646, 647, 648, 649, 650, 651, 651, + 652, 652, 653, 654, 655, 656, 657, 658, 659, 659, 659, 660, + 661, 662, 663, 664, 665, 665, 666, 666, 666, 667, 668, 669, + 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, + 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, + 694, 695, 696, 697, 698, 698, 699, 700, 701, 702, 703, 704, + 705, 706, 707, 707, 708, 710, 710, 711, 711, 711, 711, 711, + 711, 712, 713, 714, + + 714, 715, 715, 716, 716, 717, 717, 718, 718, 719, 720, 720, + 721, 722, 723, 724, 725, 726, 727, 727, 728, 730, 731, 731, + 732, 732, 734, 736, 736, 736, 736, 737, 737, 737, 737, 737, + 737, 737, 737, 737, 737, 737, 737, 737, 737, 738, 739, 740, + 740, 740, 741, 742, 743, 744, 745, 746, 747, 749, 750, 751, + 752, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, + 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, + 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, + 788, 788, 788, 788, + + 790, 790, 790, 790, 790, 790, 790, 791, 793, 794, 794, 795, + 796, 797, 798, 799, 800, 801, 802, 803, 803, 803, 803, 803, + 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, + 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 804, 805, + 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, + 818, 820, 822, 823, 824, 825, 826, 828, 829, 830, 831, 832, + 833, 834, 835, 837, 838, 839, 840, 841, 842, 843, 844, 845, + 846, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 857, + 857, 857, 857, 858, + + 858, 858, 858, 858, 858, 860, 862, 864, 864, 865, 866, 867, + 868, 869, 870, 871, 871, 871, 871, 871, 872, 872, 872, 872, + 872, 872, 872, 872, 872, 872, 872, 872, 872, 872, 872, 872, + 872, 872, 872, 872, 872, 872, 872, 872, 873, 874, 876, 877, + 878, 880, 881, 883, 884, 885, 886, 887, 889, 890, 891, 892, + 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, + 907, 908, 909, 910, 911, 913, 914, 915, 916, 917, 918, 919, + 920, 921, 922, 923, 923, 923, 923, 923, 924, 924, 924, 924, + 926, 927, 929, 929, + + 930, 931, 932, 932, 932, 933, 934, 934, 934, 934, 934, 934, + 934, 934, 934, 934, 934, 934, 934, 934, 934, 934, 934, 934, + 934, 934, 934, 934, 934, 934, 934, 936, 938, 939, 940, 941, + 943, 944, 945, 946, 947, 948, 949, 950, 952, 953, 954, 955, + 956, 957, 958, 959, 960, 962, 963, 965, 966, 968, 969, 971, + 972, 973, 974, 976, 976, 977, 979, 980, 980, 982, 982, 982, + 982, 982, 982, 983, 983, 984, 984, 985, 985, 987, 987, 987, + 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, + 987, 987, 987, 987, + + 987, 987, 987, 987, 987, 987, 988, 989, 990, 991, 992, 993, + 994, 996, 997, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1007, 1008, + 1010, 1011, 1012, 1014, 1015, 1017, 1019, 1021, 1021, 1021, 1021, 1021, + 1021, 1021, 1022, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, + 1023, 1023, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1033, 1034, + 1035, 1036, 1037, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1045, 1045, + 1046, 1046, 1046, 1046, + + 1046, 1046, 1046, 1048, 1049, 1049, 1049, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 1051, 1051, 1053, 1055, 1057, 1059, 1061, + 1063, 1065, 1067, 1069, 1071, 1073, 1073, 1073, 1073, 1073, 1073, 1073, + 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1074, 1075, 1076, 1077, 1078, + 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1089, 1090, 1091, + 1091, 1091, 1091, 1091, 1091, 1091, 1092, 1092, 1094, 1094, 1094, 1094, + 1094, 1094, 1095, 1095, 1095, 1095, 1095, 1095, 1097, 1099, 1101, 1103, + 1105, 1107, 1109, 1111, 1113, 1115, 1117, 1119, 1119, 1120, 1121, 1122, + 1123, 1124, 1125, 1126, + + 1128, 1129, 1130, 1132, 1133, 1134, 1135, 1136, 1137, 1137, 1137, 1138, + 1138, 1139, 1140, 1141, 1141, 1141, 1141, 1142, 1143, 1143, 1143, 1143, + 1143, 1143, 1143, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1154, + 1156, 1157, 1159, 1160, 1162, 1163, 1164, 1165, 1165, 1166, 1167, 1167, + 1167, 1167, 1167, 1167, 1167, 1167, 1168, 1169, 1170, 1172, 1173, 1174, + 1175, 1176, 1178, 1179, 1180, 1181, 1182, 1182, 1182, 1182, 1182, 1183, + 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1192, 1193, 1193, 1194, 1194, + 1195, 1196, 1197, 1198, 1199, 1201, 1202, 1203, 1204, 1205, 1206, 1208, + 1210, 1211, 1212, 1213, + + 1215, 1217, 1218, 1219, 1221, 1223, 1223}; + +static yyconst flex_int32_t yy_ec[256] = { + 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 4, 5, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 6, 7, 8, 9, + 1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 19, 19, 19, 19, 19, 20, 21, + 22, 23, 1, 24, 25, 26, 27, 1, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 44, 53, 54, 55, 56, + 57, 1, 58, 59, 60, 61, + + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 44, 74, 75, 76, 77, 78, 79, + 80, 81, 44, 82, 83, 84, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + +static yyconst flex_int32_t yy_meta[85] = { + 0, 1, 1, 2, 1, 3, 4, 1, 1, 1, 5, 1, 6, 1, 7, 1, 8, + 1, 5, 9, 9, 9, 9, 10, 1, 1, 1, 1, 11, 11, 11, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 13, 14, 15, 1, 16, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 5, 1, 17}; + +static yyconst flex_int16_t yy_base[1201] = { + 0, 0, 84, 167, 250, 171, 184, 174, 179, 192, 233, 196, + 200, 334, 0, 3343, 3340, 203, 416, 206, 211, 187, 216, 276, + 417, 500, 0, 210, 223, 421, 427, 436, 440, 583, 588, 669, + 0, 277, 299, 584, 751, 579, 580, 576, 732, 279, 305, 310, + 444, 3378, 3975, 228, 3975, 3371, 0, 322, 3975, 3358, 423, 827, + 3328, 0, 3975, 755, 3975, 3337, 3975, 448, 3312, 3975, 3975, 3323, + 3291, 222, 408, 444, 764, 3975, 3311, 230, 3289, 3975, 3975, 3975, + 3306, 0, 3306, 164, 3304, 3975, 3236, 3217, 3975, 3975, 3266, 239, + 119, 3215, 3212, 3180, 0, + + 3248, 3975, 3243, 3975, 476, 3227, 3222, 3975, 3168, 0, 3975, 3975, + 3975, 3203, 3975, 464, 3975, 3975, 3975, 3186, 3975, 742, 3975, 3161, + 751, 180, 3975, 3975, 3171, 0, 3149, 757, 3975, 0, 3975, 3149, + 3975, 200, 3138, 0, 429, 241, 3097, 3092, 3975, 3975, 306, 3975, + 323, 3975, 3975, 3126, 3108, 3072, 3069, 0, 3975, 3115, 3975, 0, + 3975, 446, 3975, 3114, 3031, 3098, 435, 371, 3045, 3026, 3975, 3076, + 3975, 3074, 3070, 439, 440, 3975, 578, 751, 586, 562, 735, 752, + 0, 572, 577, 588, 786, 749, 396, 809, 727, 582, 747, 753, + 764, 769, 580, 3975, + + 3975, 3067, 588, 3975, 3975, 3053, 3002, 2996, 3975, 3975, 3975, 3975, + 3975, 3975, 3975, 3975, 3975, 3975, 3975, 0, 3975, 3046, 3975, 3975, + 3975, 3018, 2986, 837, 3975, 2998, 0, 847, 3975, 2997, 817, 777, + 0, 0, 891, 903, 912, 924, 0, 774, 0, 451, 3975, 0, + 858, 3975, 2996, 2914, 472, 3975, 2974, 2953, 3975, 791, 236, 822, + 899, 3975, 275, 0, 2873, 2872, 3975, 2871, 949, 3975, 2949, 2850, + 2918, 2906, 3975, 0, 3975, 796, 3975, 0, 0, 2925, 0, 0, + 2597, 3975, 3975, 3975, 3975, 795, 794, 3975, 3975, 484, 0, 2597, + 3975, 877, 2596, 2594, + + 2594, 3975, 0, 3975, 918, 3975, 1005, 3975, 3975, 3975, 3975, 0, + 3975, 611, 3975, 0, 3975, 0, 853, 851, 3975, 3975, 490, 3975, + 608, 3975, 3975, 3975, 3975, 0, 3975, 3975, 596, 2510, 3975, 0, + 3975, 3975, 2588, 3975, 2581, 3975, 894, 906, 0, 911, 717, 727, + 923, 728, 2571, 882, 930, 889, 902, 916, 917, 940, 928, 923, + 940, 933, 0, 932, 3975, 935, 939, 951, 956, 1059, 964, 965, + 1052, 955, 957, 1099, 2578, 3975, 1078, 3975, 3975, 3975, 0, 3975, + 3975, 3975, 987, 0, 0, 1087, 3975, 2576, 1132, 985, 1046, 1058, + 0, 1058, 0, 1009, + + 3975, 1016, 3975, 1057, 3975, 1099, 3975, 1068, 731, 1088, 1095, 1178, + 1244, 1280, 988, 0, 3975, 3975, 2492, 1162, 3975, 3975, 1081, 0, + 1086, 0, 0, 1098, 1105, 1100, 3975, 1167, 1245, 1246, 1247, 1250, + 2539, 1248, 1249, 1258, 1244, 1251, 1259, 1321, 1233, 1224, 0, 1072, + 1228, 1243, 1261, 1287, 1298, 1289, 1298, 1287, 0, 1299, 1228, 1308, + 0, 1280, 1298, 1307, 1316, 1314, 1316, 2532, 1322, 1337, 1338, 1340, + 1342, 1342, 1348, 1353, 1356, 1347, 1357, 1362, 1366, 1358, 1353, 1356, + 1377, 1366, 1370, 1371, 1367, 1383, 1384, 1379, 1391, 1392, 1381, 1388, + 1397, 1275, 1455, 3975, + + 1439, 1463, 1444, 1415, 1412, 1415, 0, 1409, 0, 1429, 1492, 1558, + 1594, 1524, 2449, 1564, 1639, 3975, 3975, 1537, 1556, 1560, 1407, 2427, + 1558, 1563, 1559, 1564, 1572, 1584, 1574, 1562, 1615, 1619, 1609, 1625, + 1626, 1643, 1614, 1651, 1662, 1658, 1664, 1665, 1616, 1616, 1637, 3975, + 3975, 1638, 1631, 2352, 1634, 1641, 1655, 1650, 1677, 1679, 1671, 1689, + 0, 0, 1690, 1677, 1681, 1697, 0, 2348, 1684, 1694, 2274, 1686, + 1685, 1695, 0, 1692, 1711, 1704, 1703, 1701, 1713, 1703, 1704, 1712, + 0, 1717, 1731, 1731, 1719, 1723, 1722, 1741, 1726, 1742, 1734, 1747, + 1741, 2241, 3975, 1464, + + 1485, 1729, 1743, 1740, 0, 1721, 1591, 2173, 1585, 2139, 1771, 1807, + 1417, 962, 1426, 1755, 2049, 1745, 1769, 3975, 1774, 1782, 1789, 1775, + 1796, 1791, 1810, 1800, 1820, 1822, 1821, 1823, 1832, 1831, 1838, 1840, + 1853, 1856, 1854, 1855, 1863, 1865, 1861, 1846, 1862, 0, 1853, 1864, + 0, 1857, 0, 2008, 1866, 1862, 1869, 0, 1874, 1893, 1870, 0, + 1888, 1875, 1886, 1882, 1880, 1878, 1897, 1876, 1882, 1889, 1889, 0, + 1904, 1895, 1899, 1919, 0, 1907, 1909, 1908, 1923, 1791, 1924, 1925, + 1919, 1747, 1917, 1918, 1918, 1938, 1924, 1726, 1599, 1927, 1937, 1970, + 3975, 1702, 1652, 1923, + + 1755, 1941, 1625, 1618, 3975, 3975, 1961, 1977, 1966, 1969, 1956, 1979, + 1983, 1986, 1989, 1984, 1992, 1987, 1994, 1990, 1988, 1995, 2007, 2004, + 2016, 2022, 1996, 2028, 2018, 2026, 0, 0, 1620, 1990, 2009, 0, + 2035, 2020, 2035, 2029, 2024, 2025, 2029, 1589, 2049, 2041, 2052, 2048, + 2053, 2054, 2044, 2057, 0, 2064, 0, 2048, 0, 1576, 0, 2064, + 2070, 2056, 0, 2096, 2062, 0, 2067, 2108, 0, 1531, 2072, 2078, + 1438, 1853, 3975, 2105, 3975, 2068, 3975, 1463, 3975, 1407, 1402, 1348, + 1345, 1314, 1307, 1269, 1260, 1256, 1210, 1158, 2106, 2111, 2097, 2118, + 2122, 2129, 2125, 2140, + + 2131, 2136, 2141, 2143, 2156, 2131, 2138, 2147, 2101, 2151, 2138, 2153, + 0, 2141, 0, 2144, 2165, 2153, 2159, 2158, 2165, 0, 2165, 0, + 2167, 2169, 0, 2178, 0, 0, 0, 2183, 2167, 2179, 2210, 2178, + 2189, 2188, 2189, 2202, 2186, 2194, 2218, 2196, 2202, 1119, 1114, 2206, + 2118, 3975, 1106, 1100, 1081, 1068, 1065, 1061, 1057, 972, 968, 965, + 914, 925, 893, 881, 874, 869, 865, 861, 854, 843, 807, 802, + 776, 2235, 2212, 2226, 2221, 2227, 2239, 2238, 2228, 0, 2228, 2239, + 2242, 2252, 0, 2238, 2244, 2249, 2244, 2258, 2263, 2269, 2255, 3975, + 2263, 2265, 2265, 2281, + + 2265, 2262, 0, 2285, 2288, 2274, 3975, 2277, 2280, 2295, 2279, 2280, + 2283, 2303, 2283, 2330, 3975, 2335, 3975, 3975, 3975, 3975, 3975, 3975, + 3975, 3975, 3975, 3975, 3975, 735, 612, 608, 598, 441, 374, 261, + 245, 202, 152, 149, 137, 165, 2296, 2303, 2304, 2320, 2326, 2316, + 2324, 2329, 2324, 2316, 2319, 2335, 2324, 2327, 0, 2332, 2328, 2327, + 2332, 2345, 2348, 2352, 2344, 3975, 2338, 0, 2338, 2343, 2357, 2362, + 2357, 3975, 2371, 2356, 2359, 2358, 2380, 3975, 3975, 3975, 3975, 3975, + 3975, 3975, 3975, 3975, 3975, 3975, 3975, 128, 2384, 2382, 2373, 2387, + 2376, 2378, 2378, 0, + + 2395, 2396, 0, 2385, 2384, 2405, 2403, 2401, 2405, 2413, 3975, 2401, + 3975, 3975, 3975, 2409, 2416, 2404, 3975, 3975, 2400, 2422, 2422, 2414, + 2417, 2417, 3975, 2421, 2421, 2418, 2424, 2441, 2442, 2443, 0, 0, + 2453, 0, 2436, 0, 2451, 3975, 3975, 2445, 3975, 3975, 2446, 2457, + 2445, 2461, 2464, 2462, 2468, 2473, 2466, 2460, 0, 2462, 2459, 2461, + 2483, 0, 2463, 3975, 3975, 3975, 2484, 2488, 2476, 2482, 3975, 2495, + 2485, 2497, 2495, 2501, 2506, 2493, 0, 3975, 2496, 3975, 2508, 2498, + 2506, 2503, 2506, 2505, 0, 2520, 3975, 3975, 2522, 2514, 0, 0, + 2529, 2514, 2515, 0, + + 0, 2533, 2539, 0, 0, 3975, 2601, 2618, 2635, 2652, 2669, 2686, + 2703, 2720, 2737, 2754, 2771, 2788, 2805, 2822, 2839, 2856, 2873, 2890, + 2907, 2917, 2933, 2942, 2958, 2975, 2986, 3002, 3019, 3036, 3053, 3063, + 3079, 3096, 3113, 3127, 3137, 3153, 3170, 3187, 3204, 3215, 2009, 3227, + 3244, 3254, 3270, 3287, 3294, 3300, 3316, 3326, 3342, 3359, 3376, 2564, + 3386, 3403, 3420, 3437, 3454, 3471, 3488, 3505, 3522, 3532, 3548, 3562, + 3572, 3588, 3605, 3622, 3639, 3650, 3662, 3679, 3696, 3713, 3730, 3740, + 3749, 3765, 3782, 3799, 2571, 3809, 3826, 3843, 3860, 3877, 3885, 3890, + 3906, 3923, 3940, 3957 + +}; + +static yyconst flex_int16_t yy_def[1201] = { + 0, 1106, 1106, 1107, 1107, 1108, 1109, 1110, 1110, 1111, 1111, 1112, + 1112, 1106, 13, 1113, 1113, 1114, 1114, 1115, 1115, 1116, 1116, 1117, + 1117, 1106, 25, 1118, 1118, 1119, 1119, 1120, 1120, 1121, 1121, 1106, + 35, 1122, 1122, 1123, 1123, 1113, 1113, 1113, 1113, 1124, 1124, 1125, + 1125, 1106, 1106, 1106, 1106, 1106, 1126, 1106, 1106, 1106, 1106, 1127, + 1106, 1128, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1129, 1130, 1131, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1132, 1133, 1132, 1134, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1135, + + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1136, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1130, 1106, 1106, + 1130, 1137, 1106, 1106, 1106, 1138, 1106, 1130, 1106, 1139, 1106, 1139, + 1106, 1140, 1106, 1141, 1141, 1141, 1106, 1106, 1106, 1106, 1142, 1106, + 1142, 1106, 1106, 1106, 1106, 1106, 1106, 1143, 1106, 1143, 1106, 1144, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1145, 1106, 1106, 1106, 1146, 1146, 1146, 1146, 1146, 1146, + 1146, 1146, 1146, 1146, 1146, 1147, 1146, 1146, 1146, 1146, 1146, 1146, + 1146, 1146, 1146, 1106, + + 1106, 1148, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1149, 1106, 1149, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1150, 1106, 1106, 1106, 1106, 1106, + 1151, 1152, 1106, 1106, 1106, 1106, 1153, 1151, 1154, 1155, 1106, 1156, + 1106, 1106, 1106, 1106, 1157, 1106, 1106, 1106, 1106, 1106, 1158, 1158, + 1159, 1106, 1106, 1160, 1106, 1106, 1106, 1161, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1162, 1106, 1106, 1106, 1163, 1164, 1164, 1165, 1166, + 1167, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1168, 1169, 1106, + 1106, 1106, 1106, 1106, + + 1106, 1106, 1170, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1171, + 1106, 1172, 1106, 1172, 1106, 1173, 1173, 1173, 1106, 1106, 1174, 1106, + 1174, 1106, 1106, 1106, 1106, 1175, 1106, 1106, 1106, 1106, 1106, 1176, + 1106, 1106, 1106, 1106, 1177, 1106, 1106, 1106, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1106, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1179, 1106, 1106, 1106, 1106, 1106, 1180, 1106, + 1106, 1106, 1106, 1181, 1182, 1183, 1106, 1106, 1106, 1106, 1106, 1106, + 1184, 1181, 1185, 1186, + + 1106, 1186, 1106, 1187, 1106, 1187, 1106, 1106, 1188, 1188, 1188, 1106, + 1188, 1188, 1106, 1189, 1106, 1106, 1190, 1106, 1106, 1106, 1106, 1191, + 1106, 1192, 1193, 1106, 1106, 1194, 1106, 1194, 1195, 1195, 1195, 1195, + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1196, 1196, 1197, 1106, + 1106, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1106, + 1106, 1183, 1183, 1106, + + 1183, 1183, 1106, 1106, 1106, 1106, 1184, 1198, 1185, 1106, 1106, 1188, + 414, 412, 412, 1188, 414, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1196, 1196, 1106, + 1106, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1106, 1106, + 1106, 1106, 1106, 1183, + + 1183, 1106, 1106, 1106, 1198, 1198, 1198, 1106, 511, 511, 1188, 414, + 1188, 1188, 1188, 1106, 1106, 1106, 1106, 1106, 1195, 1195, 1195, 1195, + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1196, 1196, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1106, 1106, 1106, 1106, 1106, 1199, 1106, 1106, 1198, + 1106, 1198, 1106, 1188, + + 1188, 1188, 1106, 1106, 1106, 1106, 1195, 1195, 1195, 1195, 1195, 1195, + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, + 1195, 1195, 1195, 1195, 1195, 1195, 1196, 1196, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1106, 1178, 1178, 1178, 1106, 1178, 1106, 1106, 1106, + 1106, 1199, 1106, 1199, 1106, 1106, 1106, 1106, 1106, 1195, 1195, 1195, + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, + 1195, 1195, 1195, 1195, + + 1195, 1195, 1195, 1195, 1195, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1106, 1106, 1106, 1106, 1106, + 1106, 1178, 1178, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1200, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, + 1195, 1195, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, + + 1106, 1106, 1178, 1178, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1200, 1106, 1200, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1195, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1178, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, + + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1106, 1106, 1106, 1106, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1106, 1106, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, + + 1178, 1178, 1178, 1178, 1178, 0, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106 + +}; + +static yyconst flex_int16_t yy_nxt[4060] = { + 0, 50, 51, 52, 50, 53, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 50, 50, 50, 50, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 50, 50, + 50, 50, 55, 56, 50, 57, 50, 58, 50, 59, 50, 50, + 50, 50, 50, 50, 50, + + 50, 60, 50, 50, 50, 50, 50, 50, 50, 50, 50, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 50, 50, 50, 50, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 50, 50, 50, 63, 64, 291, 65, + 66, 83, 67, 84, 89, 68, 69, 70, 70, 89, 1027, 70, + 71, 86, 83, 992, 84, 50, 72, 991, 87, 70, 93, 309, + 94, 101, 102, 291, + + 103, 101, 102, 990, 103, 113, 989, 114, 119, 315, 120, 121, + 148, 119, 149, 120, 121, 115, 50, 73, 74, 116, 116, 116, + 116, 148, 90, 149, 91, 228, 229, 90, 230, 91, 309, 93, + 95, 94, 276, 124, 125, 99, 126, 96, 97, 283, 98, 284, + 75, 70, 70, 76, 77, 316, 78, 66, 988, 67, 79, 122, + 68, 69, 70, 70, 122, 95, 70, 71, 124, 125, 290, 126, + 96, 80, 260, 261, 70, 95, 128, 201, 129, 221, 202, 222, + 96, 97, 117, 98, 410, 411, 223, 130, 320, 415, 415, 203, + 203, 203, 203, 987, + + 290, 201, 73, 74, 202, 81, 95, 221, 324, 222, 325, 277, + 225, 96, 226, 986, 223, 203, 203, 203, 203, 320, 227, 232, + 233, 324, 234, 325, 131, 132, 133, 75, 70, 70, 104, 105, + 106, 104, 107, 104, 104, 104, 104, 104, 104, 104, 108, 104, + 108, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 109, + 104, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 104, 104, 104, 104, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, + + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 104, 104, 104, 113, 128, 114, 129, 291, 151, + 235, 152, 263, 263, 985, 151, 115, 152, 130, 153, 116, 116, + 116, 116, 157, 153, 158, 159, 157, 366, 158, 159, 225, 333, + 226, 254, 254, 291, 255, 401, 334, 402, 227, 265, 264, 266, + 319, 236, 267, 267, 267, 267, 290, 343, 344, 131, 132, 133, + 366, 154, 405, 155, 406, 298, 299, 154, 300, 155, 305, 305, + 305, 305, 431, 264, 432, 160, 319, 236, 324, 160, 325, 984, + 290, 343, 344, 117, + + 134, 134, 135, 134, 136, 137, 134, 134, 134, 138, 134, 134, + 134, 134, 134, 134, 134, 139, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 141, 140, 140, 140, + 140, 140, 140, 142, 143, 134, 144, 134, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 141, 140, 140, 140, 140, 140, 140, 142, 145, 134, 146, + 162, 163, 205, 164, 206, 162, 163, 165, 164, 353, 211, 211, + 165, 333, 216, 351, + + 166, 212, 212, 358, 334, 166, 379, 379, 379, 379, 324, 217, + 325, 352, 213, 213, 346, 359, 347, 360, 315, 218, 348, 353, + 214, 214, 219, 167, 371, 215, 215, 376, 167, 358, 168, 169, + 207, 170, 208, 168, 169, 217, 170, 352, 213, 213, 346, 359, + 347, 360, 218, 348, 983, 214, 214, 219, 167, 371, 215, 215, + 376, 167, 982, 168, 316, 209, 981, 210, 168, 171, 172, 173, + 171, 174, 175, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 176, 177, 171, 171, 171, 178, 171, 171, + 179, 180, 181, 182, + + 183, 184, 185, 186, 187, 185, 185, 188, 189, 190, 191, 192, + 185, 193, 194, 195, 196, 197, 198, 185, 199, 171, 171, 171, + 171, 171, 179, 180, 181, 182, 183, 184, 185, 186, 187, 185, + 185, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 185, 199, 171, 171, 171, 205, 216, 206, 249, 250, 370, 251, + 263, 263, 452, 252, 354, 269, 270, 217, 271, 263, 263, 453, + 272, 456, 372, 263, 263, 218, 349, 356, 364, 273, 219, 410, + 411, 355, 350, 274, 370, 980, 365, 452, 264, 373, 354, 374, + 375, 217, 941, 357, + + 453, 264, 456, 207, 372, 208, 218, 264, 349, 356, 364, 219, + 387, 361, 355, 398, 350, 362, 235, 275, 365, 264, 408, 373, + 940, 374, 375, 425, 357, 939, 264, 428, 209, 429, 210, 238, + 264, 253, 228, 229, 367, 230, 387, 361, 412, 398, 253, 362, + 232, 233, 368, 234, 408, 369, 239, 236, 240, 425, 240, 249, + 250, 428, 251, 429, 240, 938, 252, 240, 241, 242, 367, 240, + 243, 244, 410, 411, 937, 245, 298, 299, 368, 300, 369, 936, + 239, 236, 240, 935, 240, 445, 446, 934, 390, 391, 240, 392, + 933, 240, 241, 242, + + 240, 243, 244, 932, 390, 391, 245, 392, 246, 393, 393, 393, + 393, 390, 391, 931, 392, 413, 413, 445, 446, 393, 393, 393, + 393, 390, 391, 458, 392, 448, 393, 393, 393, 393, 461, 394, + 305, 305, 305, 305, 253, 449, 393, 393, 393, 393, 450, 930, + 462, 414, 269, 270, 454, 271, 395, 464, 458, 272, 459, 448, + 451, 463, 460, 461, 394, 396, 273, 465, 929, 455, 466, 449, + 274, 468, 467, 469, 450, 462, 414, 470, 471, 472, 454, 473, + 395, 464, 474, 476, 459, 451, 463, 480, 460, 482, 481, 396, + 475, 465, 455, 485, + + 466, 486, 468, 467, 275, 469, 262, 262, 470, 471, 472, 401, + 473, 402, 410, 411, 474, 476, 401, 928, 402, 480, 927, 482, + 481, 475, 926, 497, 485, 504, 486, 253, 433, 434, 435, 436, + 437, 437, 438, 437, 437, 437, 437, 439, 437, 437, 437, 440, + 437, 437, 441, 437, 442, 437, 437, 443, 437, 497, 504, 405, + 444, 406, 433, 434, 435, 436, 437, 437, 438, 437, 437, 437, + 437, 439, 437, 437, 437, 440, 437, 441, 437, 442, 437, 437, + 443, 437, 477, 483, 499, 500, 478, 501, 505, 506, 484, 479, + 379, 379, 379, 379, + + 508, 405, 431, 406, 432, 502, 502, 502, 502, 510, 511, 925, + 520, 512, 512, 924, 477, 483, 548, 923, 478, 505, 922, 506, + 484, 479, 487, 521, 488, 522, 508, 489, 490, 503, 391, 921, + 392, 491, 492, 510, 410, 411, 520, 493, 494, 513, 523, 548, + 495, 409, 393, 393, 393, 393, 920, 496, 487, 521, 488, 522, + 919, 489, 490, 519, 519, 519, 519, 491, 492, 431, 914, 432, + 493, 494, 513, 913, 523, 495, 409, 409, 861, 409, 409, 409, + 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, + 409, 409, 409, 409, + + 409, 409, 409, 409, 409, 514, 514, 514, 514, 514, 514, 514, + 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, + 514, 514, 514, 514, 514, 514, 410, 411, 860, 515, 409, 514, + 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, + 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, 409, + 409, 409, 516, 516, 546, 547, 524, 524, 524, 524, 524, 524, + 524, 524, 549, 558, 550, 599, 859, 600, 524, 524, 858, 525, + 526, 528, 533, 527, 551, 535, 530, 857, 529, 534, 546, 547, + 410, 411, 517, 517, + + 517, 517, 531, 549, 558, 532, 550, 517, 517, 517, 517, 517, + 517, 525, 526, 528, 533, 527, 551, 535, 530, 529, 552, 534, + 560, 553, 554, 555, 556, 856, 557, 531, 410, 411, 532, 559, + 855, 517, 517, 517, 517, 517, 517, 1106, 561, 562, 563, 565, + 536, 537, 538, 539, 552, 560, 540, 553, 554, 555, 556, 541, + 557, 564, 567, 542, 568, 559, 543, 854, 544, 569, 853, 545, + 570, 561, 571, 562, 563, 565, 536, 537, 538, 539, 572, 573, + 540, 574, 575, 576, 577, 541, 564, 578, 567, 542, 568, 543, + 581, 544, 582, 569, + + 545, 579, 570, 583, 571, 584, 585, 580, 586, 587, 606, 588, + 572, 573, 589, 574, 575, 576, 577, 590, 591, 578, 592, 593, + 852, 594, 581, 582, 598, 851, 595, 579, 583, 596, 597, 584, + 585, 580, 586, 587, 588, 500, 602, 600, 589, 503, 391, 603, + 392, 590, 591, 619, 592, 593, 594, 604, 499, 500, 598, 501, + 595, 608, 596, 597, 601, 500, 599, 501, 600, 410, 411, 259, + 602, 502, 502, 502, 502, 603, 410, 411, 619, 502, 502, 502, + 502, 604, 601, 500, 850, 501, 607, 608, 409, 409, 848, 409, + 409, 409, 409, 409, + + 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, + 409, 409, 409, 409, 409, 409, 409, 609, 609, 609, 609, 609, + 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, + 609, 609, 609, 609, 609, 609, 609, 609, 410, 411, 613, 610, + 409, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, + 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, + 609, 409, 409, 409, 611, 611, 616, 409, 524, 524, 614, 614, + 524, 524, 524, 845, 617, 618, 623, 828, 696, 697, 524, 698, + 524, 625, 621, 626, + + 622, 775, 629, 776, 817, 624, 524, 700, 616, 628, 410, 411, + 612, 612, 612, 612, 410, 411, 617, 618, 623, 612, 612, 612, + 612, 612, 612, 625, 621, 626, 622, 524, 629, 627, 624, 806, + 524, 524, 524, 628, 409, 524, 630, 781, 632, 644, 643, 524, + 524, 636, 780, 612, 612, 612, 612, 612, 612, 615, 615, 615, + 615, 631, 627, 633, 634, 524, 615, 615, 615, 615, 615, 615, + 630, 524, 632, 644, 643, 779, 646, 636, 524, 645, 647, 635, + 524, 649, 524, 524, 650, 651, 652, 631, 653, 633, 634, 637, + 615, 615, 615, 615, + + 615, 615, 639, 638, 697, 640, 641, 642, 646, 654, 645, 647, + 656, 635, 649, 655, 658, 650, 657, 651, 652, 659, 606, 660, + 637, 661, 662, 692, 664, 665, 669, 639, 667, 638, 640, 668, + 641, 642, 670, 654, 671, 672, 656, 673, 675, 655, 658, 657, + 674, 676, 677, 659, 660, 678, 661, 679, 662, 664, 680, 665, + 669, 667, 681, 683, 668, 682, 684, 670, 685, 687, 671, 672, + 686, 673, 675, 688, 690, 674, 676, 677, 693, 689, 691, 678, + 694, 679, 695, 703, 680, 701, 701, 705, 681, 683, 682, 684, + 524, 524, 685, 687, + + 706, 686, 607, 768, 524, 688, 690, 410, 411, 693, 689, 524, + 691, 524, 694, 695, 708, 703, 524, 710, 705, 707, 524, 410, + 411, 702, 702, 702, 702, 709, 706, 711, 524, 712, 702, 702, + 702, 702, 702, 702, 714, 713, 524, 524, 524, 524, 708, 764, + 710, 715, 707, 716, 717, 524, 524, 775, 718, 776, 721, 709, + 524, 711, 524, 712, 702, 702, 702, 702, 702, 702, 714, 713, + 719, 723, 720, 524, 524, 524, 524, 715, 724, 716, 717, 524, + 722, 524, 718, 524, 721, 726, 728, 752, 731, 732, 734, 727, + 730, 748, 733, 736, + + 741, 738, 719, 723, 720, 725, 735, 729, 743, 740, 724, 739, + 742, 722, 744, 745, 746, 747, 749, 726, 728, 731, 750, 732, + 734, 727, 730, 733, 751, 736, 741, 738, 753, 754, 725, 755, + 735, 729, 740, 756, 739, 757, 742, 744, 758, 745, 746, 747, + 749, 759, 761, 750, 760, 762, 763, 765, 766, 767, 751, 769, + 770, 753, 754, 771, 755, 772, 773, 777, 778, 756, 757, 696, + 697, 758, 698, 410, 411, 409, 524, 759, 761, 760, 762, 524, + 763, 765, 766, 767, 524, 769, 770, 524, 771, 410, 411, 772, + 773, 777, 778, 524, + + 782, 524, 786, 784, 783, 524, 524, 785, 524, 524, 524, 524, + 524, 787, 524, 791, 524, 524, 524, 363, 363, 807, 793, 737, + 795, 802, 524, 788, 796, 524, 782, 786, 789, 784, 783, 790, + 792, 785, 524, 797, 524, 794, 798, 787, 524, 791, 799, 800, + 524, 804, 524, 807, 793, 808, 795, 802, 788, 803, 796, 805, + 811, 789, 801, 809, 790, 792, 812, 813, 797, 814, 794, 815, + 798, 810, 704, 816, 799, 800, 818, 804, 819, 820, 808, 821, + 822, 823, 825, 803, 824, 805, 811, 826, 801, 809, 827, 829, + 812, 813, 814, 830, + + 815, 831, 838, 810, 816, 839, 846, 775, 818, 776, 819, 820, + 849, 821, 822, 823, 825, 824, 847, 524, 917, 826, 918, 827, + 864, 829, 832, 833, 524, 830, 831, 834, 838, 524, 835, 839, + 846, 836, 840, 841, 524, 849, 837, 842, 524, 878, 843, 524, + 847, 844, 863, 524, 862, 524, 864, 865, 832, 833, 524, 868, + 866, 834, 524, 524, 835, 524, 875, 836, 840, 841, 876, 837, + 872, 842, 878, 867, 843, 870, 524, 844, 863, 862, 871, 880, + 869, 865, 882, 873, 877, 868, 866, 874, 879, 881, 409, 883, + 875, 884, 699, 885, + + 876, 886, 872, 887, 867, 888, 870, 889, 890, 891, 892, 871, + 880, 869, 894, 882, 873, 895, 877, 896, 902, 874, 879, 881, + 883, 901, 893, 884, 885, 903, 904, 886, 887, 905, 907, 888, + 906, 889, 890, 891, 892, 897, 692, 911, 894, 898, 895, 912, + 899, 896, 902, 915, 943, 908, 901, 893, 909, 524, 900, 903, + 904, 944, 946, 905, 907, 906, 910, 945, 947, 948, 950, 897, + 911, 949, 951, 898, 912, 952, 899, 953, 915, 942, 943, 908, + 954, 955, 909, 900, 956, 666, 957, 944, 946, 958, 959, 910, + 945, 960, 947, 948, + + 950, 961, 949, 962, 951, 963, 964, 952, 965, 953, 942, 966, + 967, 954, 968, 955, 969, 971, 956, 957, 970, 972, 973, 958, + 959, 974, 975, 960, 976, 979, 961, 977, 917, 962, 918, 963, + 964, 917, 965, 918, 966, 967, 993, 994, 968, 995, 969, 971, + 978, 970, 996, 972, 973, 997, 974, 975, 998, 976, 979, 999, + 1000, 977, 1001, 663, 1002, 1003, 1004, 648, 1005, 1006, 1007, 993, + 1008, 994, 1009, 995, 1010, 978, 1011, 1012, 996, 1013, 1014, 997, + 1015, 1016, 998, 1017, 1018, 999, 1000, 1019, 1001, 1002, 1003, 1020, + 1004, 1005, 1021, 1006, + + 1007, 1008, 1022, 1009, 1025, 1010, 1023, 1026, 1011, 1012, 1024, 1013, + 1014, 1015, 1016, 1028, 1017, 1029, 1018, 1030, 1031, 1019, 1032, 1033, + 1034, 1020, 1035, 1036, 1021, 1037, 1038, 1022, 1039, 1025, 1040, 1023, + 1041, 1026, 1042, 1024, 1043, 1044, 1045, 1046, 1047, 1028, 1048, 1029, + 1030, 1049, 1031, 1032, 1033, 1034, 1050, 1057, 1035, 1036, 1037, 1038, + 1051, 1052, 1039, 1053, 1040, 1054, 1041, 1055, 1042, 1056, 1043, 1044, + 1045, 1046, 1047, 1048, 1058, 1059, 1060, 1049, 1061, 620, 1062, 1063, + 1050, 1057, 1064, 1065, 1066, 1051, 1052, 1067, 1053, 1068, 1054, 1069, + 1055, 1070, 1056, 1071, + + 1072, 1073, 1074, 1075, 409, 1076, 1058, 1059, 1060, 1077, 1061, 1062, + 1078, 1063, 1079, 1080, 1064, 1065, 1066, 1081, 1067, 1082, 1083, 1068, + 1084, 1069, 1085, 1070, 1086, 1071, 1072, 1073, 1074, 1075, 1076, 1087, + 1088, 1089, 1077, 1090, 1091, 1092, 1078, 1079, 1093, 1080, 1094, 566, + 1095, 1081, 1082, 1096, 1083, 1097, 1084, 1098, 1085, 1099, 1086, 1100, + 1101, 524, 1102, 1103, 1104, 1087, 1088, 1089, 1090, 1091, 1105, 1092, + 416, 1093, 416, 420, 1094, 1095, 391, 518, 1096, 518, 1097, 378, + 457, 1098, 342, 1099, 1100, 339, 1101, 1102, 1103, 336, 1104, 301, + 299, 301, 296, 286, + + 1105, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, + + 100, 100, 100, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, + + 147, 147, 147, 147, 147, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 156, 156, + 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, + 156, 156, 156, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 220, 220, 220, 220, 220, 220, + 220, 220, 220, 220, + + 220, 220, 220, 220, 220, 220, 220, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 231, 231, 282, 231, 231, 423, 422, 421, 231, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 248, 248, 270, 248, 248, 420, 418, 417, 248, 259, 407, + 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, + 259, 259, 259, 262, 254, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, 268, 268, 268, 403, + 268, 268, 250, 233, + + 229, 268, 280, 386, 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 281, 385, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + 384, 285, 382, 285, 285, 295, 381, 380, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 303, 303, + 378, 303, 303, 342, 340, 339, 303, 308, 338, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 311, 337, 311, 311, + + 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 317, 311, + 311, 312, 336, 312, 335, 331, 312, 312, 312, 312, 312, 329, + 328, 327, 312, 314, 326, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 318, 318, 322, 318, + 318, 321, 317, 313, 318, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 330, 307, + 330, 310, 330, 330, 330, 330, 330, 330, 330, 330, 330, 307, + 330, 330, 330, 332, 306, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, + + 332, 332, 332, 332, 341, 304, 341, 341, 341, 341, 341, 341, + 341, 341, 341, 341, 341, 341, 341, 341, 341, 345, 345, 302, + 299, 345, 345, 377, 301, 377, 377, 377, 377, 377, 377, 377, + 377, 377, 377, 377, 377, 377, 377, 377, 383, 297, 383, 383, + 383, 296, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 231, 231, 294, 231, 231, 293, 292, 289, 231, 388, 288, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 389, 287, 389, 389, 389, 389, 389, 389, 389, + 389, 389, 389, 389, + + 389, 389, 389, 389, 397, 397, 286, 282, 279, 397, 399, 399, + 278, 270, 258, 399, 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, 400, 248, 248, 257, + 248, 248, 256, 250, 247, 248, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 409, + 233, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, + 409, 229, 409, 409, 259, 1106, 259, 259, 259, 259, 259, 259, + 259, 259, 259, 259, 259, 259, 259, 259, 259, 419, 419, 111, + 419, 419, 111, 1106, + + 1106, 419, 419, 424, 1106, 424, 424, 424, 424, 424, 424, 424, + 424, 424, 424, 424, 424, 424, 424, 424, 280, 1106, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 280, 281, 1106, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 426, 1106, 426, 426, 426, 426, + 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 427, + 1106, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 285, 285, 285, 285, 285, 285, 285, 285, + 285, 285, 285, 285, + + 1106, 285, 1106, 285, 285, 430, 430, 430, 430, 430, 430, 430, + 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 295, 1106, + 1106, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 303, 303, 1106, 303, 303, 1106, 1106, 1106, 303, + 312, 1106, 312, 1106, 1106, 312, 312, 312, 312, 312, 1106, 1106, + 1106, 312, 314, 1106, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 318, 318, 1106, 318, 318, + 1106, 1106, 1106, 318, 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, + + 323, 323, 323, 323, 323, 330, 1106, 330, 1106, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 1106, 330, 330, 330, 447, 1106, + 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, + 447, 447, 447, 341, 1106, 341, 341, 341, 341, 341, 341, 341, + 341, 341, 341, 341, 341, 341, 341, 341, 345, 345, 1106, 1106, + 345, 345, 377, 1106, 377, 377, 377, 377, 377, 377, 377, 377, + 377, 377, 377, 377, 377, 377, 377, 383, 1106, 383, 383, 383, + 1106, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 388, 1106, 388, 388, + + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 389, 1106, 389, 389, 389, 389, 389, 389, 389, 389, 389, + 389, 389, 389, 389, 389, 389, 498, 498, 498, 498, 498, 498, + 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 507, + 507, 1106, 507, 507, 1106, 1106, 1106, 507, 509, 509, 1106, 509, + 509, 1106, 1106, 1106, 509, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 409, + + 1106, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, + 409, 1106, 409, 409, 419, 419, 1106, 419, 419, 1106, 1106, 1106, + 419, 419, 424, 1106, 424, 424, 424, 424, 424, 424, 424, 424, + 424, 424, 424, 424, 424, 424, 424, 426, 1106, 426, 426, 426, + 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, + 427, 1106, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 430, 430, 430, 430, 430, 430, 430, + 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 437, 437, + 437, 318, 318, 1106, + + 318, 318, 1106, 1106, 1106, 318, 447, 1106, 447, 447, 447, 447, + 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 605, + 1106, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, 774, 916, 916, 916, + 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, + 916, 916, 49, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, + + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106}; + +static yyconst flex_int16_t yy_chk[4060] = { + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, + + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 96, 3, + 3, 5, 3, 5, 7, 3, 3, 3, 3, 8, 992, 3, + 3, 6, 6, 942, 6, 21, 3, 941, 6, 3, 9, 126, + 9, 11, 11, 96, + + 11, 12, 12, 940, 12, 17, 939, 17, 19, 138, 19, 19, + 27, 20, 27, 20, 20, 17, 22, 3, 3, 17, 17, 17, + 17, 28, 7, 28, 7, 51, 51, 8, 51, 8, 126, 10, + 9, 10, 79, 21, 21, 10, 21, 9, 9, 87, 9, 87, + 3, 3, 3, 4, 4, 138, 4, 4, 938, 4, 4, 19, + 4, 4, 4, 4, 20, 9, 4, 4, 22, 22, 95, 22, + 9, 4, 73, 73, 4, 10, 23, 37, 23, 45, 37, 45, + 10, 10, 17, 10, 259, 259, 45, 23, 142, 263, 263, 37, + 37, 37, 37, 937, + + 95, 38, 4, 4, 38, 4, 10, 46, 147, 46, 147, 79, + 47, 10, 47, 936, 46, 38, 38, 38, 38, 142, 47, 55, + 55, 149, 55, 149, 23, 23, 23, 4, 4, 4, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, + + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 18, 24, 18, 24, 168, 29, + 58, 29, 74, 74, 935, 30, 18, 30, 24, 29, 18, 18, + 18, 18, 31, 30, 31, 31, 32, 191, 32, 32, 48, 162, + 48, 67, 67, 168, 67, 246, 162, 246, 48, 75, 74, 75, + 141, 58, 75, 75, 75, 75, 167, 176, 177, 24, 24, 24, + 191, 29, 253, 29, 253, 105, 105, 30, 105, 30, 116, 116, + 116, 116, 294, 74, 294, 31, 141, 58, 323, 32, 323, 934, + 167, 176, 177, 18, + + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 33, 33, 39, 33, 39, 34, 34, 33, 34, 182, 41, 42, + 34, 333, 43, 181, + + 33, 41, 42, 186, 333, 34, 203, 203, 203, 203, 325, 43, + 325, 181, 41, 42, 179, 187, 179, 188, 314, 43, 179, 182, + 41, 42, 43, 33, 194, 41, 42, 199, 34, 186, 33, 33, + 39, 33, 39, 34, 34, 43, 34, 181, 41, 42, 179, 187, + 179, 188, 43, 179, 933, 41, 42, 43, 33, 194, 41, 42, + 199, 34, 932, 33, 314, 39, 931, 39, 34, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, + + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 40, 44, 40, 63, 63, 193, 63, + 122, 122, 347, 63, 183, 76, 76, 44, 76, 125, 125, 348, + 76, 350, 195, 132, 132, 44, 180, 184, 190, 76, 44, 409, + 409, 183, 180, 76, 193, 930, 190, 347, 122, 196, 183, 197, + 198, 44, 873, 184, + + 348, 125, 350, 40, 195, 40, 44, 132, 180, 184, 190, 44, + 236, 189, 183, 244, 180, 189, 235, 76, 190, 122, 258, 196, + 872, 197, 198, 278, 184, 871, 125, 290, 40, 291, 40, 59, + 132, 63, 228, 228, 192, 228, 236, 189, 260, 244, 76, 189, + 232, 232, 192, 232, 258, 192, 59, 235, 59, 278, 59, 249, + 249, 290, 249, 291, 59, 870, 249, 59, 59, 59, 192, 59, + 59, 59, 260, 260, 869, 59, 298, 298, 192, 298, 192, 868, + 59, 235, 59, 867, 59, 319, 320, 866, 239, 239, 59, 239, + 865, 59, 59, 59, + + 59, 59, 59, 864, 240, 240, 59, 240, 59, 239, 239, 239, + 239, 241, 241, 863, 241, 261, 261, 319, 320, 240, 240, 240, + 240, 242, 242, 352, 242, 343, 241, 241, 241, 241, 354, 239, + 305, 305, 305, 305, 249, 344, 242, 242, 242, 242, 346, 862, + 355, 261, 269, 269, 349, 269, 241, 357, 352, 269, 353, 343, + 346, 356, 353, 354, 239, 242, 269, 358, 861, 349, 359, 344, + 269, 360, 359, 361, 346, 355, 261, 362, 364, 366, 349, 367, + 241, 357, 368, 369, 353, 346, 356, 371, 353, 372, 371, 242, + 368, 358, 349, 374, + + 359, 375, 360, 359, 269, 361, 415, 415, 362, 364, 366, 400, + 367, 400, 614, 614, 368, 369, 402, 860, 402, 371, 859, 372, + 371, 368, 858, 387, 374, 394, 375, 269, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 307, 307, 307, 387, 394, 404, + 307, 404, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 370, 373, 390, 390, 370, 390, 395, 396, 373, 370, + 379, 379, 379, 379, + + 398, 406, 430, 406, 430, 390, 390, 390, 390, 408, 410, 857, + 423, 411, 411, 856, 370, 373, 448, 855, 370, 395, 854, 396, + 373, 370, 376, 425, 376, 428, 398, 376, 376, 393, 393, 853, + 393, 376, 376, 408, 410, 410, 423, 376, 376, 411, 429, 448, + 376, 411, 393, 393, 393, 393, 852, 376, 376, 425, 376, 428, + 851, 376, 376, 420, 420, 420, 420, 376, 376, 432, 847, 432, + 376, 376, 411, 846, 429, 376, 412, 412, 792, 412, 412, 412, + 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, + 412, 412, 412, 412, + + 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, + 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, + 412, 412, 412, 412, 412, 412, 412, 412, 791, 412, 412, 412, + 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, + 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, + 412, 412, 413, 413, 445, 446, 441, 433, 434, 435, 438, 439, + 436, 442, 449, 459, 450, 498, 790, 498, 440, 443, 789, 433, + 434, 436, 441, 435, 451, 443, 439, 788, 438, 442, 445, 446, + 413, 413, 414, 414, + + 414, 414, 440, 449, 459, 440, 450, 414, 414, 414, 414, 414, + 414, 433, 434, 436, 441, 435, 451, 443, 439, 438, 452, 442, + 462, 453, 454, 455, 456, 787, 458, 440, 414, 414, 440, 460, + 786, 414, 414, 414, 414, 414, 414, 444, 463, 464, 465, 467, + 444, 444, 444, 444, 452, 462, 444, 453, 454, 455, 456, 444, + 458, 466, 469, 444, 470, 460, 444, 785, 444, 471, 784, 444, + 472, 463, 473, 464, 465, 467, 444, 444, 444, 444, 474, 475, + 444, 476, 477, 478, 479, 444, 466, 480, 469, 444, 470, 444, + 482, 444, 483, 471, + + 444, 481, 472, 484, 473, 485, 486, 481, 487, 488, 508, 489, + 474, 475, 490, 476, 477, 478, 479, 491, 492, 480, 493, 494, + 783, 495, 482, 483, 497, 782, 496, 481, 484, 496, 496, 485, + 486, 481, 487, 488, 489, 501, 504, 501, 490, 503, 503, 505, + 503, 491, 492, 523, 493, 494, 495, 506, 499, 499, 497, 499, + 496, 510, 496, 496, 502, 502, 600, 502, 600, 613, 613, 613, + 504, 499, 499, 499, 499, 505, 615, 615, 523, 502, 502, 502, + 502, 506, 601, 601, 780, 601, 508, 510, 511, 511, 773, 511, + 511, 511, 511, 511, + + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 514, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 512, 512, 520, 514, 525, 527, 516, 516, + 532, 526, 528, 770, 521, 522, 526, 758, 607, 607, 529, 607, + 531, 528, 525, 529, + + 525, 693, 532, 693, 744, 527, 530, 609, 520, 531, 512, 512, + 513, 513, 513, 513, 516, 516, 521, 522, 526, 513, 513, 513, + 513, 513, 513, 528, 525, 529, 525, 535, 532, 530, 527, 733, + 539, 533, 545, 531, 609, 534, 533, 704, 535, 546, 545, 536, + 537, 539, 703, 513, 513, 513, 513, 513, 513, 517, 517, 517, + 517, 534, 530, 536, 537, 538, 517, 517, 517, 517, 517, 517, + 533, 540, 535, 546, 545, 699, 550, 539, 542, 547, 551, 538, + 541, 553, 543, 544, 554, 555, 556, 534, 557, 536, 537, 540, + 517, 517, 517, 517, + + 517, 517, 542, 541, 698, 542, 543, 544, 550, 557, 547, 551, + 558, 538, 553, 557, 560, 554, 559, 555, 556, 563, 606, 564, + 540, 565, 566, 692, 569, 570, 574, 542, 572, 541, 542, 573, + 543, 544, 576, 557, 577, 578, 558, 579, 581, 557, 560, 559, + 580, 582, 583, 563, 564, 584, 565, 586, 566, 569, 587, 570, + 574, 572, 588, 590, 573, 589, 591, 576, 592, 594, 577, 578, + 593, 579, 581, 595, 596, 580, 582, 583, 602, 595, 597, 584, + 603, 586, 604, 616, 587, 611, 611, 618, 588, 590, 589, 591, + 621, 624, 592, 594, + + 619, 593, 606, 686, 622, 595, 596, 701, 701, 602, 595, 623, + 597, 626, 603, 604, 622, 616, 625, 624, 618, 621, 628, 611, + 611, 612, 612, 612, 612, 623, 619, 625, 627, 626, 612, 612, + 612, 612, 612, 612, 628, 627, 629, 631, 630, 632, 622, 682, + 624, 629, 621, 630, 631, 634, 633, 774, 632, 774, 634, 623, + 635, 625, 636, 626, 612, 612, 612, 612, 612, 612, 628, 627, + 633, 636, 633, 637, 639, 640, 638, 629, 637, 630, 631, 643, + 635, 641, 632, 642, 634, 639, 641, 668, 644, 645, 648, 640, + 643, 664, 647, 650, + + 655, 653, 633, 636, 633, 638, 648, 642, 658, 654, 637, 653, + 657, 635, 659, 661, 662, 663, 665, 639, 641, 644, 666, 645, + 648, 640, 643, 647, 667, 650, 655, 653, 669, 670, 638, 671, + 648, 642, 654, 673, 653, 674, 657, 659, 675, 661, 662, 663, + 665, 676, 679, 666, 678, 680, 681, 683, 684, 685, 667, 687, + 688, 669, 670, 689, 671, 690, 691, 694, 695, 673, 674, 696, + 696, 675, 696, 700, 700, 700, 711, 676, 679, 678, 680, 707, + 681, 683, 684, 685, 709, 687, 688, 710, 689, 702, 702, 690, + 691, 694, 695, 708, + + 707, 712, 711, 709, 708, 713, 716, 710, 714, 718, 721, 715, + 720, 712, 717, 716, 719, 722, 727, 1147, 1147, 734, 718, 652, + 720, 727, 724, 713, 721, 723, 707, 711, 714, 709, 708, 715, + 717, 710, 725, 722, 729, 719, 723, 712, 726, 716, 724, 725, + 730, 729, 728, 734, 718, 735, 720, 727, 713, 728, 721, 730, + 738, 714, 726, 737, 715, 717, 739, 740, 722, 741, 719, 742, + 723, 737, 617, 743, 724, 725, 745, 729, 746, 747, 735, 748, + 749, 750, 752, 728, 751, 730, 738, 754, 726, 737, 756, 760, + 739, 740, 741, 761, + + 742, 762, 765, 737, 743, 767, 771, 776, 745, 776, 746, 747, + 778, 748, 749, 750, 752, 751, 772, 795, 849, 754, 849, 756, + 795, 760, 764, 764, 793, 761, 762, 764, 765, 794, 764, 767, + 771, 764, 768, 768, 796, 778, 764, 768, 797, 809, 768, 799, + 772, 768, 794, 798, 793, 801, 795, 796, 764, 764, 802, 799, + 797, 764, 800, 803, 764, 804, 806, 764, 768, 768, 807, 764, + 803, 768, 809, 798, 768, 801, 805, 768, 794, 793, 802, 811, + 800, 796, 814, 804, 808, 799, 797, 805, 810, 812, 610, 816, + 806, 817, 608, 818, + + 807, 819, 803, 820, 798, 821, 801, 823, 825, 826, 828, 802, + 811, 800, 832, 814, 804, 833, 808, 834, 837, 805, 810, 812, + 816, 836, 828, 817, 818, 838, 839, 819, 820, 840, 842, 821, + 841, 823, 825, 826, 828, 835, 598, 844, 832, 835, 833, 845, + 835, 834, 837, 848, 875, 843, 836, 828, 843, 874, 835, 838, + 839, 876, 878, 840, 842, 841, 843, 877, 879, 880, 883, 835, + 844, 881, 884, 835, 845, 885, 835, 886, 848, 874, 875, 843, + 888, 889, 843, 835, 890, 571, 891, 876, 878, 892, 893, 843, + 877, 894, 879, 880, + + 883, 895, 881, 897, 884, 898, 899, 885, 900, 886, 874, 901, + 902, 888, 904, 889, 905, 908, 890, 891, 906, 909, 910, 892, + 893, 911, 912, 894, 913, 915, 895, 914, 916, 897, 916, 898, + 899, 918, 900, 918, 901, 902, 943, 944, 904, 945, 905, 908, + 914, 906, 946, 909, 910, 947, 911, 912, 948, 913, 915, 949, + 950, 914, 951, 568, 952, 953, 954, 552, 955, 956, 958, 943, + 959, 944, 960, 945, 961, 914, 962, 963, 946, 964, 965, 947, + 967, 969, 948, 970, 971, 949, 950, 972, 951, 952, 953, 973, + 954, 955, 975, 956, + + 958, 959, 976, 960, 978, 961, 977, 979, 962, 963, 977, 964, + 965, 967, 969, 993, 970, 994, 971, 995, 996, 972, 997, 998, + 999, 973, 1001, 1002, 975, 1004, 1005, 976, 1006, 978, 1007, 977, + 1008, 979, 1009, 977, 1010, 1012, 1016, 1017, 1018, 993, 1021, 994, + 995, 1022, 996, 997, 998, 999, 1023, 1031, 1001, 1002, 1004, 1005, + 1024, 1025, 1006, 1026, 1007, 1028, 1008, 1029, 1009, 1030, 1010, 1012, + 1016, 1017, 1018, 1021, 1032, 1033, 1034, 1022, 1037, 524, 1039, 1041, + 1023, 1031, 1044, 1047, 1048, 1024, 1025, 1049, 1026, 1050, 1028, 1051, + 1029, 1052, 1030, 1053, + + 1054, 1055, 1056, 1058, 515, 1059, 1032, 1033, 1034, 1060, 1037, 1039, + 1061, 1041, 1063, 1067, 1044, 1047, 1048, 1068, 1049, 1069, 1070, 1050, + 1072, 1051, 1073, 1052, 1074, 1053, 1054, 1055, 1056, 1058, 1059, 1075, + 1076, 1077, 1060, 1078, 1081, 1083, 1061, 1063, 1084, 1067, 1085, 468, + 1086, 1068, 1069, 1087, 1070, 1088, 1072, 1090, 1073, 1093, 1074, 1094, + 1097, 437, 1098, 1099, 1102, 1075, 1076, 1077, 1078, 1081, 1103, 1083, + 1160, 1084, 1160, 419, 1085, 1086, 392, 1189, 1087, 1189, 1088, 377, + 351, 1090, 341, 1093, 1094, 339, 1097, 1098, 1099, 334, 1102, 301, + 300, 299, 296, 285, + + 1103, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, + 1107, 1107, 1107, 1107, 1107, 1107, 1108, 1108, 1108, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1109, + 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, + 1109, 1109, 1109, 1109, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1111, 1111, 1111, + 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, + 1111, 1111, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, + 1112, 1112, 1112, 1112, + + 1112, 1112, 1112, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, + 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1114, 1114, 1114, 1114, + 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 1114, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, + 1115, 1115, 1115, 1115, 1115, 1115, 1116, 1116, 1116, 1116, 1116, 1116, + 1116, 1116, 1116, 1116, 1116, 1116, 1116, 1116, 1116, 1116, 1116, 1117, + 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, + 1117, 1117, 1117, 1117, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, + 1118, 1118, 1118, 1118, + + 1118, 1118, 1118, 1118, 1118, 1119, 1119, 1119, 1119, 1119, 1119, 1119, + 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, + 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1122, 1122, 1122, 1122, + 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, + 1122, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + 1123, 1123, 1123, 1123, 1123, 1123, 1124, 1124, 1124, 1124, 1124, 1124, + 1124, 1124, 1124, 1124, + + 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1125, 1125, 1125, 1125, 1125, + 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + 1126, 1126, 282, 1126, 1126, 274, 273, 272, 1126, 1127, 1127, 1127, + 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, + 1127, 1128, 1128, 271, 1128, 1128, 268, 266, 265, 1128, 1129, 256, + 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + 1129, 1129, 1129, 1130, 255, 1130, 1130, 1130, 1130, 1130, 1130, 1130, + 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1131, 1131, 1131, 252, + 1131, 1131, 251, 234, + + 230, 1131, 1132, 227, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, + 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1133, 226, 1133, 1133, 1133, + 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, + 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, + 222, 1134, 208, 1134, 1134, 1135, 207, 206, 1135, 1135, 1135, 1135, + 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1136, 1136, + 202, 1136, 1136, 175, 174, 172, 1136, 1137, 170, 1137, 1137, 1137, + 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, + 1138, 169, 1138, 1138, + + 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 166, 1138, + 1138, 1139, 165, 1139, 164, 158, 1139, 1139, 1139, 1139, 1139, 155, + 154, 153, 1139, 1140, 152, 1140, 1140, 1140, 1140, 1140, 1140, 1140, + 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1141, 1141, 144, 1141, + 1141, 143, 139, 136, 1141, 1142, 1142, 1142, 1142, 1142, 1142, 1142, + 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1143, 131, + 1143, 129, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 124, + 1143, 1143, 1143, 1144, 120, 1144, 1144, 1144, 1144, 1144, 1144, 1144, + 1144, 1144, 1144, 1144, + + 1144, 1144, 1144, 1144, 1145, 114, 1145, 1145, 1145, 1145, 1145, 1145, + 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1146, 1146, 109, + 107, 1146, 1146, 1148, 106, 1148, 1148, 1148, 1148, 1148, 1148, 1148, + 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1149, 103, 1149, 1149, + 1149, 101, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, + 1149, 1150, 1150, 99, 1150, 1150, 98, 97, 94, 1150, 1151, 91, + 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, + 1151, 1151, 1151, 1152, 90, 1152, 1152, 1152, 1152, 1152, 1152, 1152, + 1152, 1152, 1152, 1152, + + 1152, 1152, 1152, 1152, 1153, 1153, 88, 86, 84, 1153, 1154, 1154, + 80, 78, 72, 1154, 1155, 1155, 1155, 1155, 1155, 1155, 1155, 1155, + 1155, 1155, 1155, 1155, 1155, 1155, 1155, 1155, 1155, 1156, 1156, 71, + 1156, 1156, 68, 65, 60, 1156, 1157, 1157, 1157, 1157, 1157, 1157, + 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1158, + 57, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, + 1158, 53, 1158, 1158, 1159, 49, 1159, 1159, 1159, 1159, 1159, 1159, + 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1161, 1161, 16, + 1161, 1161, 15, 0, + + 0, 1161, 1161, 1162, 0, 1162, 1162, 1162, 1162, 1162, 1162, 1162, + 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1163, 0, 1163, 1163, + 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, + 1163, 1164, 0, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, + 1164, 1164, 1164, 1164, 1164, 1164, 1165, 0, 1165, 1165, 1165, 1165, + 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1166, + 0, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, + 1166, 1166, 1166, 1166, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, + 1167, 1167, 1167, 1167, + + 0, 1167, 0, 1167, 1167, 1168, 1168, 1168, 1168, 1168, 1168, 1168, + 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1169, 0, + 0, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1170, 1170, 0, 1170, 1170, 0, 0, 0, 1170, + 1171, 0, 1171, 0, 0, 1171, 1171, 1171, 1171, 1171, 0, 0, + 0, 1171, 1172, 0, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1173, 1173, 0, 1173, 1173, + 0, 0, 0, 1173, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, + 1174, 1174, 1174, 1174, + + 1174, 1174, 1174, 1174, 1174, 1175, 0, 1175, 0, 1175, 1175, 1175, + 1175, 1175, 1175, 1175, 1175, 1175, 0, 1175, 1175, 1175, 1176, 0, + 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, + 1176, 1176, 1176, 1177, 0, 1177, 1177, 1177, 1177, 1177, 1177, 1177, + 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1178, 1178, 0, 0, + 1178, 1178, 1179, 0, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, + 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1180, 0, 1180, 1180, 1180, + 0, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, + 1181, 0, 1181, 1181, + + 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, + 1181, 1182, 0, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, + 1182, 1182, 1182, 1182, 1182, 1182, 1183, 1183, 1183, 1183, 1183, 1183, + 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1184, + 1184, 0, 1184, 1184, 0, 0, 0, 1184, 1185, 1185, 0, 1185, + 1185, 0, 0, 0, 1185, 1186, 1186, 1186, 1186, 1186, 1186, 1186, + 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1187, 1187, + 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, + 1187, 1187, 1187, 1188, + + 0, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, + 1188, 0, 1188, 1188, 1190, 1190, 0, 1190, 1190, 0, 0, 0, + 1190, 1190, 1191, 0, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, + 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1192, 0, 1192, 1192, 1192, + 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, + 1193, 0, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, + 1193, 1193, 1193, 1193, 1193, 1194, 1194, 1194, 1194, 1194, 1194, 1194, + 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1195, 1195, + 1195, 1196, 1196, 0, + + 1196, 1196, 0, 0, 0, 1196, 1197, 0, 1197, 1197, 1197, 1197, + 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1198, + 0, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, + 1198, 1198, 1198, 1198, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, + 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1200, 1200, 1200, + 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, + 1200, 1200, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, + + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106}; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +static yy_state_type *yy_state_buf = 0, *yy_state_ptr = 0; +static char *yy_full_match; +static int yy_lp; +#define REJECT \ + { \ + *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ \ + yy_cp = (yy_full_match); /* restore poss. backed-over text */ \ + ++(yy_lp); \ + goto find_rule; \ + } + +static int yy_more_flag = 0; +static int yy_more_len = 0; +#define yymore() ((yy_more_flag) = 1) +#define YY_MORE_ADJ (yy_more_len) +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +/* $OpenBSD: scan.l,v 1.12 2015/11/19 23:34:56 mmcc Exp $ */ +/* scan.l - scanner for flex input -*-C-*- */ +/* Copyright (c) 1990 The Regents of the University of California. */ +/* All rights reserved. */ + +/* This code is derived from software contributed to Berkeley by */ +/* Vern Paxson. */ + +/* The United States Government has rights in this work pursuant */ +/* to contract no. DE-AC03-76SF00098 between the United States */ +/* Department of Energy and the University of California. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + +#include "flexdef.h" +#include "parse.h" +extern bool tablesverify, tablesext; +extern int trlcontxt; /* Set in parse.y for each rule. */ +extern const char *escaped_qstart, *escaped_qend; + +#define ACTION_ECHO add_action(yytext) +#define ACTION_IFDEF(def, should_define) \ + { \ + if (should_define) action_define(def, 1); \ + } + +#define ACTION_ECHO_QSTART add_action(escaped_qstart) +#define ACTION_ECHO_QEND add_action(escaped_qend) + +#define ACTION_M4_IFDEF(def, should_define) \ + do { \ + if (should_define) \ + buf_m4_define(&m4defs_buf, def, NULL); \ + else \ + buf_m4_undefine(&m4defs_buf, def); \ + } while (0) + +#define MARK_END_OF_PROLOG mark_prolog(); + +#define YY_DECL int flexscan() + +#define RETURNCHAR \ + yylval = (unsigned char)yytext[0]; \ + return CHAR; + +#define RETURNNAME \ + if (yyleng < MAXLINE) { \ + strlcpy(nmstr, yytext, sizeof nmstr); \ + } else { \ + synerr(_("Input line too long\n")); \ + FLEX_EXIT(EXIT_FAILURE); \ + } \ + return NAME; + +#define PUT_BACK_STRING(str, start) \ + for (i = strlen(str) - 1; i >= start; --i) unput((str)[i]) + +#define CHECK_REJECT(str) \ + if (all_upper(str)) reject = true; + +#define CHECK_YYMORE(str) \ + if (all_lower(str)) yymore_used = true; + +#define YY_USER_INIT \ + if (getenv("POSIXLY_CORRECT")) posix_compat = true; + +#define INITIAL 0 +#define SECT2 1 +#define SECT2PROLOG 2 +#define SECT3 3 +#define CODEBLOCK 4 +#define PICKUPDEF 5 +#define SC 6 +#define CARETISBOL 7 +#define NUM 8 +#define QUOTE 9 +#define FIRSTCCL 10 +#define CCL 11 +#define ACTION 12 +#define RECOVER 13 +#define COMMENT 14 +#define ACTION_STRING 15 +#define PERCENT_BRACE_ACTION 16 +#define OPTION 17 +#define LINEDIR 18 +#define CODEBLOCK_MATCH_BRACE 19 +#define GROUP_WITH_PARAMS 20 +#define GROUP_MINUS_PARAMS 21 +#define EXTENDED_COMMENT 22 +#define COMMENT_DISCARD 23 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include "libc/calls/calls.h" +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals(void); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy(void); + +int yyget_debug(void); + +void yyset_debug(int debug_flag); + +YY_EXTRA_TYPE yyget_extra(void); + +void yyset_extra(YY_EXTRA_TYPE user_defined); + +FILE *yyget_in(void); + +void yyset_in(FILE *in_str); + +FILE *yyget_out(void); + +void yyset_out(FILE *out_str); + +yy_size_t yyget_leng(void); + +char *yyget_text(void); + +int yyget_lineno(void); + +void yyset_lineno(int line_number); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap(void); +#else +extern int yywrap(void); +#endif +#endif + +static void yyunput(int c, char *buf_ptr); + +#ifndef yytext_ptr +static void yy_flex_strncpy(char *, yyconst char *, int); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen(yyconst char *); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput(void); +#else +static int input(void); +#endif + +#endif + +static int yy_start_stack_ptr = 0; +static int yy_start_stack_depth = 0; +static int *yy_start_stack = NULL; + +static void yy_push_state(int new_state); + +static void yy_pop_state(void); + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO \ + do { \ + if (fwrite(yytext, yyleng, 1, yyout)) { \ + } \ + } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf, result, max_size) \ + if (YY_CURRENT_BUFFER_LVALUE->yy_is_interactive) { \ + int c = '*'; \ + size_t n; \ + for (n = 0; n < max_size && (c = getc(yyin)) != EOF && c != '\n'; ++n) \ + buf[n] = (char)c; \ + if (c == '\n') buf[n++] = (char)c; \ + if (c == EOF && ferror(yyin)) \ + YY_FATAL_ERROR("input in flex scanner failed"); \ + result = n; \ + } else { \ + errno = 0; \ + while ((result = fread(buf, 1, max_size, yyin)) == 0 && ferror(yyin)) { \ + if (errno != EINTR) { \ + YY_FATAL_ERROR("input in flex scanner failed"); \ + break; \ + } \ + errno = 0; \ + clearerr(yyin); \ + } \ + } + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error(msg) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex(void); + +#define YY_DECL int yylex(void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + if (yyleng > 0) \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (yytext[yyleng - 1] == '\n'); \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL { + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + + if (!(yy_init)) { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + /* Create the reject buffer large enough to save one state per allowed + * character. */ + if (!(yy_state_buf)) + (yy_state_buf) = (yy_state_type *)yyalloc(YY_STATE_BUF_SIZE); + if (!(yy_state_buf)) YY_FATAL_ERROR("out of dynamic memory in yylex()"); + + if (!(yy_start)) (yy_start) = 1; /* first start state */ + + if (!yyin) yyin = stdin; + + if (!yyout) yyout = stdout; + + if (!YY_CURRENT_BUFFER) { + yyensure_buffer_stack(); + YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin, YY_BUF_SIZE); + } + + yy_load_buffer_state(); + } + + { + static int bracelevel, didadef, indented_code; + static int doing_rule_action = false; + static int option_sense; + + int doing_codeblock = false; + int i, brace_depth = 0, brace_start_line = 0; + u_char nmdef[MAXLINE]; + + while (1) /* loops until end-of-file is reached */ + { + (yy_more_len) = 0; + if ((yy_more_flag)) { + (yy_more_len) = (yy_c_buf_p) - (yytext_ptr); + (yy_more_flag) = 0; + } + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); + yy_current_state += YY_AT_BOL(); + + (yy_state_ptr) = (yy_state_buf); + *(yy_state_ptr)++ = yy_current_state; + + yy_match: + do { + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) { + yy_current_state = (int)yy_def[yy_current_state]; + if (yy_current_state >= 1107) yy_c = yy_meta[(unsigned int)yy_c]; + } + yy_current_state = + yy_nxt[yy_base[yy_current_state] + (unsigned int)yy_c]; + *(yy_state_ptr)++ = yy_current_state; + ++yy_cp; + } while (yy_base[yy_current_state] != 3975); + + yy_find_action: + yy_current_state = *--(yy_state_ptr); + (yy_lp) = yy_accept[yy_current_state]; + find_rule: /* we branch to this label when backing up */ + for (;;) /* until we find what rule we matched */ + { + if ((yy_lp) && (yy_lp) < yy_accept[yy_current_state + 1]) { + yy_act = yy_acclist[(yy_lp)]; + { + (yy_full_match) = yy_cp; + break; + } + } + --yy_cp; + yy_current_state = *--(yy_state_ptr); + (yy_lp) = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + do_action: /* This label is used only to access EOF actions. */ + + switch (yy_act) { /* beginning of action switch */ + + case 1: + YY_RULE_SETUP + indented_code = true; + BEGIN(CODEBLOCK); + YY_BREAK + case 2: + YY_RULE_SETUP + ACTION_ECHO; + yy_push_state(COMMENT); + YY_BREAK + case 3: + YY_RULE_SETUP + yy_push_state(LINEDIR); + YY_BREAK + case 4: + YY_RULE_SETUP + return SCDECL; + YY_BREAK + case 5: + YY_RULE_SETUP + return XSCDECL; + YY_BREAK + case 6: + /* rule 6 can match eol */ + YY_RULE_SETUP { + ++linenum; + line_directive_out((FILE *)0, 1); + indented_code = false; + BEGIN(CODEBLOCK); + } + YY_BREAK + case 7: + /* rule 7 can match eol */ + YY_RULE_SETUP { + brace_start_line = linenum; + ++linenum; + buf_linedir(&top_buf, infilename ? infilename : "", linenum); + brace_depth = 1; + yy_push_state(CODEBLOCK_MATCH_BRACE); + } + YY_BREAK + case 8: + YY_RULE_SETUP + synerr(_("malformed '%top' directive")); + YY_BREAK + case 9: + YY_RULE_SETUP + /* discard */ + YY_BREAK + case 10: + YY_RULE_SETUP { + sectnum = 2; + bracelevel = 0; + mark_defs1(); + line_directive_out((FILE *)0, 1); + BEGIN(SECT2PROLOG); + return SECTEND; + } + YY_BREAK + case 11: + /* rule 11 can match eol */ + YY_RULE_SETUP + yytext_is_array = false; + ++linenum; + YY_BREAK + case 12: + /* rule 12 can match eol */ + YY_RULE_SETUP + yytext_is_array = true; + ++linenum; + YY_BREAK + case 13: + YY_RULE_SETUP + BEGIN(OPTION); + return OPTION_OP; + YY_BREAK + case 14: + /* rule 14 can match eol */ + YY_RULE_SETUP + ++linenum; /* ignore */ + YY_BREAK + case 15: + /* rule 15 can match eol */ + YY_RULE_SETUP + ++linenum; /* ignore */ + YY_BREAK + /* xgettext: no-c-format */ + case 16: + /* rule 16 can match eol */ + YY_RULE_SETUP + synerr(_("unrecognized '%' directive")); + YY_BREAK + case 17: + YY_RULE_SETUP { + if (yyleng < MAXLINE) { + strlcpy(nmstr, yytext, sizeof nmstr); + } else { + synerr(_("Definition name too long\n")); + FLEX_EXIT(EXIT_FAILURE); + } + + didadef = false; + BEGIN(PICKUPDEF); + } + YY_BREAK + case 18: + YY_RULE_SETUP + RETURNNAME; + YY_BREAK + case 19: + /* rule 19 can match eol */ + YY_RULE_SETUP + ++linenum; /* allows blank lines in section 1 */ + YY_BREAK + case 20: + /* rule 20 can match eol */ + YY_RULE_SETUP + ACTION_ECHO; + ++linenum; /* maybe end of comment line */ + YY_BREAK + + case 21: + YY_RULE_SETUP + ACTION_ECHO; + yy_pop_state(); + YY_BREAK + case 22: + YY_RULE_SETUP + ACTION_ECHO; + YY_BREAK + case 23: + YY_RULE_SETUP + ACTION_ECHO_QSTART; + YY_BREAK + case 24: + YY_RULE_SETUP + ACTION_ECHO_QEND; + YY_BREAK + case 25: + YY_RULE_SETUP + ACTION_ECHO; + YY_BREAK + case 26: + /* rule 26 can match eol */ + YY_RULE_SETUP + ++linenum; + ACTION_ECHO; + YY_BREAK + + /* This is the same as COMMENT, but is discarded rather than output. */ + case 27: + YY_RULE_SETUP + yy_pop_state(); + YY_BREAK + case 28: + YY_RULE_SETUP; + YY_BREAK + case 29: + YY_RULE_SETUP; + YY_BREAK + case 30: + /* rule 30 can match eol */ + YY_RULE_SETUP + ++linenum; + YY_BREAK + + case 31: + YY_RULE_SETUP + yy_pop_state(); + YY_BREAK + case 32: + YY_RULE_SETUP; + YY_BREAK + case 33: + /* rule 33 can match eol */ + YY_RULE_SETUP + ++linenum; + YY_BREAK + + case 34: + /* rule 34 can match eol */ + YY_RULE_SETUP + yy_pop_state(); + YY_BREAK + case 35: + YY_RULE_SETUP + linenum = myctoi(yytext); + YY_BREAK + case 36: + YY_RULE_SETUP { + free((void *)infilename); + infilename = copy_string(yytext + 1); + infilename[strlen(infilename) - 1] = '\0'; + } + YY_BREAK + case 37: + YY_RULE_SETUP + /* ignore spurious characters */ + YY_BREAK + + case 38: + /* rule 38 can match eol */ + YY_RULE_SETUP + ++linenum; + BEGIN(INITIAL); + YY_BREAK + case 39: + YY_RULE_SETUP + ACTION_ECHO_QSTART; + YY_BREAK + case 40: + YY_RULE_SETUP + ACTION_ECHO_QEND; + YY_BREAK + case 41: + YY_RULE_SETUP + ACTION_ECHO; + YY_BREAK + case 42: + /* rule 42 can match eol */ + YY_RULE_SETUP { + ++linenum; + ACTION_ECHO; + if (indented_code) BEGIN(INITIAL); + } + YY_BREAK + + case 43: + YY_RULE_SETUP { + if (--brace_depth == 0) { + /* TODO: Matched. */ + yy_pop_state(); + } else + buf_strnappend(&top_buf, yytext, yyleng); + } + YY_BREAK + case 44: + YY_RULE_SETUP { + brace_depth++; + buf_strnappend(&top_buf, yytext, yyleng); + } + YY_BREAK + case 45: + /* rule 45 can match eol */ + YY_RULE_SETUP { + ++linenum; + buf_strnappend(&top_buf, yytext, yyleng); + } + YY_BREAK + case 46: + YY_RULE_SETUP + buf_strnappend(&top_buf, escaped_qstart, strlen(escaped_qstart)); + YY_BREAK + case 47: + YY_RULE_SETUP + buf_strnappend(&top_buf, escaped_qend, strlen(escaped_qend)); + YY_BREAK + case 48: + YY_RULE_SETUP { buf_strnappend(&top_buf, yytext, yyleng); } + YY_BREAK + case YY_STATE_EOF(CODEBLOCK_MATCH_BRACE): { + linenum = brace_start_line; + synerr(_("Unmatched '{'")); + yyterminate(); + } + YY_BREAK + + case 49: + YY_RULE_SETUP + /* separates name and definition */ + YY_BREAK + case 50: + YY_RULE_SETUP { + if (yyleng < MAXLINE) { + strlcpy((char *)nmdef, yytext, sizeof nmdef); + } else { + format_synerr(_("Definition value for {%s} too long\n"), nmstr); + FLEX_EXIT(EXIT_FAILURE); + } + /* Skip trailing whitespace. */ + for (i = strlen((char *)nmdef) - 1; + i >= 0 && (nmdef[i] == ' ' || nmdef[i] == '\t'); --i) + ; + + nmdef[i + 1] = '\0'; + + ndinstal(nmstr, nmdef); + didadef = true; + } + YY_BREAK + case 51: + /* rule 51 can match eol */ + YY_RULE_SETUP { + if (!didadef) synerr(_("incomplete name definition")); + BEGIN(INITIAL); + ++linenum; + } + YY_BREAK + + case 52: + /* rule 52 can match eol */ + YY_RULE_SETUP + ++linenum; + BEGIN(INITIAL); + YY_BREAK + case 53: + YY_RULE_SETUP + option_sense = true; + YY_BREAK + case 54: + YY_RULE_SETUP + return '='; + YY_BREAK + case 55: + YY_RULE_SETUP + option_sense = !option_sense; + YY_BREAK + case 56: + YY_RULE_SETUP + csize = option_sense ? 128 : 256; + YY_BREAK + case 57: + YY_RULE_SETUP + csize = option_sense ? 256 : 128; + YY_BREAK + case 58: + YY_RULE_SETUP + long_align = option_sense; + YY_BREAK + case 59: + YY_RULE_SETUP { + ACTION_M4_IFDEF( + "M4" + "_YY_ALWAYS_INTERACTIVE", + option_sense); + interactive = option_sense; + } + YY_BREAK + case 60: + YY_RULE_SETUP + yytext_is_array = option_sense; + YY_BREAK + case 61: + YY_RULE_SETUP + ansi_func_defs = option_sense; + YY_BREAK + case 62: + YY_RULE_SETUP + ansi_func_protos = option_sense; + YY_BREAK + case 63: + YY_RULE_SETUP + backing_up_report = option_sense; + YY_BREAK + case 64: + YY_RULE_SETUP + interactive = !option_sense; + YY_BREAK + case 65: + YY_RULE_SETUP + bison_bridge_lval = option_sense; + YY_BREAK + case 66: + YY_RULE_SETUP { + if ((bison_bridge_lloc = option_sense)) bison_bridge_lval = true; + } + YY_BREAK + case 67: + YY_RULE_SETUP + C_plus_plus = option_sense; + YY_BREAK + case 68: + YY_RULE_SETUP + sf_set_case_ins(!option_sense); + YY_BREAK + case 69: + YY_RULE_SETUP + sf_set_case_ins(option_sense); + YY_BREAK + case 70: + YY_RULE_SETUP + ddebug = option_sense; + YY_BREAK + case 71: + YY_RULE_SETUP + spprdflt = !option_sense; + YY_BREAK + case 72: + YY_RULE_SETUP + useecs = option_sense; + YY_BREAK + case 73: + YY_RULE_SETUP { + useecs = usemecs = false; + use_read = fullspd = true; + } + YY_BREAK + case 74: + YY_RULE_SETUP { + useecs = usemecs = false; + use_read = fulltbl = true; + } + YY_BREAK + case 75: + YY_RULE_SETUP + ACTION_IFDEF("YY_NO_INPUT", !option_sense); + YY_BREAK + case 76: + YY_RULE_SETUP + interactive = option_sense; + YY_BREAK + case 77: + YY_RULE_SETUP + lex_compat = option_sense; + YY_BREAK + case 78: + YY_RULE_SETUP + posix_compat = option_sense; + YY_BREAK + case 79: + YY_RULE_SETUP { + ACTION_M4_IFDEF( + "M4" + "_YY_MAIN", + option_sense); + /* Override yywrap */ + if (option_sense == true) do_yywrap = false; + } + YY_BREAK + case 80: + YY_RULE_SETUP + usemecs = option_sense; + YY_BREAK + case 81: + YY_RULE_SETUP { + ACTION_M4_IFDEF( + "M4" + "_YY_NEVER_INTERACTIVE", + option_sense); + interactive = !option_sense; + } + YY_BREAK + case 82: + YY_RULE_SETUP + performance_report += option_sense ? 1 : -1; + YY_BREAK + case 83: + YY_RULE_SETUP + yytext_is_array = !option_sense; + YY_BREAK + case 84: + YY_RULE_SETUP + use_read = option_sense; + YY_BREAK + case 85: + YY_RULE_SETUP + reentrant = option_sense; + YY_BREAK + case 86: + YY_RULE_SETUP + reject_really_used = option_sense; + YY_BREAK + case 87: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_STACK_USED", + option_sense); + YY_BREAK + case 88: + YY_RULE_SETUP + do_stdinit = option_sense; + YY_BREAK + case 89: + YY_RULE_SETUP + use_stdout = option_sense; + YY_BREAK + case 90: + YY_RULE_SETUP + ACTION_IFDEF("YY_NO_UNISTD_H", !option_sense); + YY_BREAK + case 91: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_UNPUT", + !option_sense); + YY_BREAK + case 92: + YY_RULE_SETUP + printstats = option_sense; + YY_BREAK + case 93: + YY_RULE_SETUP + nowarn = !option_sense; + YY_BREAK + case 94: + YY_RULE_SETUP + do_yylineno = option_sense; + ACTION_M4_IFDEF( + "M4" + "_YY_USE_LINENO", + option_sense); + YY_BREAK + case 95: + YY_RULE_SETUP + yymore_really_used = option_sense; + YY_BREAK + case 96: + YY_RULE_SETUP + do_yywrap = option_sense; + YY_BREAK + case 97: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_PUSH_STATE", + !option_sense); + YY_BREAK + case 98: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_POP_STATE", + !option_sense); + YY_BREAK + case 99: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_TOP_STATE", + !option_sense); + YY_BREAK + case 100: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_SCAN_BUFFER", + !option_sense); + YY_BREAK + case 101: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_SCAN_BYTES", + !option_sense); + YY_BREAK + case 102: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_SCAN_STRING", + !option_sense); + YY_BREAK + case 103: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_FLEX_ALLOC", + !option_sense); + YY_BREAK + case 104: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_FLEX_REALLOC", + !option_sense); + YY_BREAK + case 105: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_FLEX_FREE", + !option_sense); + YY_BREAK + case 106: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_GET_DEBUG", + !option_sense); + YY_BREAK + case 107: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_SET_DEBUG", + !option_sense); + YY_BREAK + case 108: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_GET_EXTRA", + !option_sense); + YY_BREAK + case 109: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_SET_EXTRA", + !option_sense); + YY_BREAK + case 110: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_GET_LENG", + !option_sense); + YY_BREAK + case 111: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_GET_TEXT", + !option_sense); + YY_BREAK + case 112: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_GET_LINENO", + !option_sense); + YY_BREAK + case 113: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_SET_LINENO", + !option_sense); + YY_BREAK + case 114: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_GET_IN", + !option_sense); + YY_BREAK + case 115: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_SET_IN", + !option_sense); + YY_BREAK + case 116: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_GET_OUT", + !option_sense); + YY_BREAK + case 117: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_SET_OUT", + !option_sense); + YY_BREAK + case 118: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_GET_LVAL", + !option_sense); + YY_BREAK + case 119: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_SET_LVAL", + !option_sense); + YY_BREAK + case 120: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_GET_LLOC", + !option_sense); + YY_BREAK + case 121: + YY_RULE_SETUP + ACTION_M4_IFDEF( + "M4" + "_YY_NO_SET_LLOC", + !option_sense); + YY_BREAK + case 122: + YY_RULE_SETUP + return OPT_EXTRA_TYPE; + YY_BREAK + case 123: + YY_RULE_SETUP + return OPT_OUTFILE; + YY_BREAK + case 124: + YY_RULE_SETUP + return OPT_PREFIX; + YY_BREAK + case 125: + YY_RULE_SETUP + return OPT_YYCLASS; + YY_BREAK + case 126: + YY_RULE_SETUP + return OPT_HEADER; + YY_BREAK + case 127: + YY_RULE_SETUP + return OPT_TABLES; + YY_BREAK + case 128: + YY_RULE_SETUP { + tablesverify = option_sense; + if (!tablesext && option_sense) tablesext = true; + } + YY_BREAK + case 129: + YY_RULE_SETUP { + if (yyleng - 1 < MAXLINE) { + strlcpy(nmstr, yytext + 1, sizeof nmstr); + } else { + synerr(_("Option line too long\n")); + FLEX_EXIT(EXIT_FAILURE); + } + if (nmstr[strlen(nmstr) - 1] == '"') + nmstr[strlen(nmstr) - 1] = '\0'; + return NAME; + } + YY_BREAK + case 130: + YY_RULE_SETUP { + format_synerr(_("unrecognized %%option: %s"), yytext); + BEGIN(RECOVER); + } + YY_BREAK + + case 131: + /* rule 131 can match eol */ + YY_RULE_SETUP + ++linenum; + BEGIN(INITIAL); + YY_BREAK + + case 132: + YY_RULE_SETUP + ++bracelevel; + yyless(2); /* eat only %{ */ + YY_BREAK + case 133: + YY_RULE_SETUP + --bracelevel; + yyless(2); /* eat only %} */ + YY_BREAK + case 134: + YY_RULE_SETUP + ACTION_ECHO; /* indented code in prolog */ + YY_BREAK + case 135: + YY_RULE_SETUP { /* non-indented code */ + if (bracelevel <= 0) { /* not in %{ ... %} */ + yyless(0); /* put it all back */ + yy_set_bol(1); + mark_prolog(); + BEGIN(SECT2); + } else + ACTION_ECHO; + } + YY_BREAK + case 136: + YY_RULE_SETUP + ACTION_ECHO; + YY_BREAK + case 137: + /* rule 137 can match eol */ + YY_RULE_SETUP + ++linenum; + ACTION_ECHO; + YY_BREAK + case YY_STATE_EOF(SECT2PROLOG): { + mark_prolog(); + sectnum = 0; + yyterminate(); /* to stop the parser */ + } + YY_BREAK + + case 138: + /* rule 138 can match eol */ + YY_RULE_SETUP + ++linenum; /* allow blank lines in section 2 */ + YY_BREAK + case 139: + YY_RULE_SETUP { + indented_code = false; + doing_codeblock = true; + bracelevel = 1; + BEGIN(PERCENT_BRACE_ACTION); + } + YY_BREAK + case 140: + YY_RULE_SETUP { + /* Allow "<" to appear in (?x) patterns. */ + if (!sf_skip_ws()) BEGIN(SC); + return '<'; + } + YY_BREAK + case 141: + YY_RULE_SETUP + return '^'; + YY_BREAK + case 142: + YY_RULE_SETUP + BEGIN(QUOTE); + return '"'; + YY_BREAK + case 143: + *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ + (yy_c_buf_p) = yy_cp = yy_bp + 1; + YY_DO_BEFORE_ACTION; /* set up yytext again */ + YY_RULE_SETUP { + BEGIN(NUM); + if (lex_compat || posix_compat) + return BEGIN_REPEAT_POSIX; + else + return BEGIN_REPEAT_FLEX; + } + YY_BREAK + case 144: + /* rule 144 can match eol */ + *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ + YY_LINENO_REWIND_TO(yy_bp + 1); + (yy_c_buf_p) = yy_cp = yy_bp + 1; + YY_DO_BEFORE_ACTION; /* set up yytext again */ + YY_RULE_SETUP + return '$'; + YY_BREAK + case 145: + YY_RULE_SETUP { + bracelevel = 1; + BEGIN(PERCENT_BRACE_ACTION); + + if (in_rule) { + doing_rule_action = true; + in_rule = false; + return '\n'; + } + } + YY_BREAK + case 146: + /* rule 146 can match eol */ + YY_RULE_SETUP { + if (sf_skip_ws()) { + /* We're in the middle of a (?x: ) pattern. */ + /* Push back everything starting at the "|" */ + size_t amt; + amt = strchr(yytext, '|') - yytext; + yyless(amt); + } else { + continued_action = true; + ++linenum; + return '\n'; + } + } + YY_BREAK + case 147: + YY_RULE_SETUP { + if (sf_skip_ws()) { + /* We're in the middle of a (?x: ) pattern. */ + yy_push_state(COMMENT_DISCARD); + } else { + yyless(yyleng - 2); /* put back '/', '*' */ + bracelevel = 0; + continued_action = false; + BEGIN(ACTION); + } + } + YY_BREAK + case 148: + YY_RULE_SETUP + /* allow indented rules */; + YY_BREAK + case 149: + YY_RULE_SETUP { + if (sf_skip_ws()) { + /* We're in the middle of a (?x: ) pattern. */ + } else { + /* This rule is separate from the one below because + * otherwise we get variable trailing context, so + * we can't build the scanner using -{f,F}. + */ + bracelevel = 0; + continued_action = false; + BEGIN(ACTION); + + if (in_rule) { + doing_rule_action = true; + in_rule = false; + return '\n'; + } + } + } + YY_BREAK + case 150: + /* rule 150 can match eol */ + YY_RULE_SETUP { + if (sf_skip_ws()) { + /* We're in the middle of a (?x: ) pattern. */ + ++linenum; + } else { + bracelevel = 0; + continued_action = false; + BEGIN(ACTION); + unput('\n'); /* so sees it */ + + if (in_rule) { + doing_rule_action = true; + in_rule = false; + return '\n'; + } + } + } + YY_BREAK + case 151: + case 152: + YY_RULE_SETUP + return EOF_OP; + YY_BREAK + case 153: + YY_RULE_SETUP { + sectnum = 3; + BEGIN(SECT3); + outn("/* Begin user sect3 */"); + yyterminate(); /* to stop the parser */ + } + YY_BREAK + case 154: + YY_RULE_SETUP { + int cclval; + + if (yyleng < MAXLINE) { + strlcpy(nmstr, yytext, sizeof nmstr); + } else { + synerr(_("Input line too long\n")); + FLEX_EXIT(EXIT_FAILURE); + } + + /* Check to see if we've already encountered this + * ccl. + */ + if (0 /* <--- This "0" effectively disables the reuse of a + * character class (purely based on its source text). + * The reason it was disabled is so yacc/bison can parse + * ccl operations, such as ccl difference and union. + */ + && (cclval = ccllookup((u_char *)nmstr)) != 0) { + if (input() != ']') synerr(_("bad character class")); + + yylval = cclval; + ++cclreuse; + return PREVCCL; + } else { + /* We fudge a bit. We know that this ccl will + * soon be numbered as lastccl + 1 by cclinit. + */ + cclinstal((u_char *)nmstr, lastccl + 1); + + /* Push back everything but the leading bracket + * so the ccl can be rescanned. + */ + yyless(1); + + BEGIN(FIRSTCCL); + return '['; + } + } + YY_BREAK + case 155: + YY_RULE_SETUP + return CCL_OP_DIFF; + YY_BREAK + case 156: + YY_RULE_SETUP + return CCL_OP_UNION; + YY_BREAK + /* Check for :space: at the end of the rule so we don't + * wrap the expanded regex in '(' ')' -- breaking trailing + * context. + */ + case 157: + /* rule 157 can match eol */ + YY_RULE_SETUP { + u_char *nmdefptr; + int end_is_ws, end_ch; + + end_ch = yytext[yyleng - 1]; + end_is_ws = end_ch != '}' ? 1 : 0; + + if (yyleng - 1 < MAXLINE) { + strlcpy(nmstr, yytext + 1, sizeof nmstr); + } else { + synerr(_("Input line too long\n")); + FLEX_EXIT(EXIT_FAILURE); + } + nmstr[yyleng - 2 - end_is_ws] = '\0'; /* chop trailing brace */ + + if ((nmdefptr = ndlookup(nmstr)) == 0) + format_synerr(_("undefined definition {%s}"), nmstr); + + else { /* push back name surrounded by ()'s */ + int len = strlen((char *)nmdefptr); + if (end_is_ws) unput(end_ch); + + if (lex_compat || nmdefptr[0] == '^' || + (len > 0 && nmdefptr[len - 1] == '$') || + (end_is_ws && trlcontxt && + !sf_skip_ws())) { /* don't use ()'s after all */ + PUT_BACK_STRING((char *)nmdefptr, 0); + + if (nmdefptr[0] == '^') BEGIN(CARETISBOL); + } + + else { + unput(')'); + PUT_BACK_STRING((char *)nmdefptr, 0); + unput('('); + } + } + } + YY_BREAK + case 158: + YY_RULE_SETUP { + if (sf_skip_ws()) + yy_push_state(COMMENT_DISCARD); + else { + /* Push back the "*" and return "/" as usual. */ + yyless(1); + return '/'; + } + } + YY_BREAK + case 159: + YY_RULE_SETUP { + if (lex_compat || posix_compat) { + /* Push back the "?#" and treat it like a normal parens. */ + yyless(1); + sf_push(); + return '('; + } else + yy_push_state(EXTENDED_COMMENT); + } + YY_BREAK + case 160: + YY_RULE_SETUP { + sf_push(); + if (lex_compat || posix_compat) + /* Push back the "?" and treat it like a normal parens. */ + yyless(1); + else + BEGIN(GROUP_WITH_PARAMS); + return '('; + } + YY_BREAK + case 161: + YY_RULE_SETUP + sf_push(); + return '('; + YY_BREAK + case 162: + YY_RULE_SETUP + sf_pop(); + return ')'; + YY_BREAK + case 163: + YY_RULE_SETUP + return (unsigned char)yytext[0]; + YY_BREAK + case 164: + YY_RULE_SETUP + RETURNCHAR; + YY_BREAK + + case 165: + /* rule 165 can match eol */ + YY_RULE_SETUP + ++linenum; /* Allow blank lines & continuations */ + YY_BREAK + case 166: + YY_RULE_SETUP + return (unsigned char)yytext[0]; + YY_BREAK + case 167: + YY_RULE_SETUP + BEGIN(SECT2); + return '>'; + YY_BREAK + case 168: + *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ + (yy_c_buf_p) = yy_cp = yy_bp + 1; + YY_DO_BEFORE_ACTION; /* set up yytext again */ + YY_RULE_SETUP + BEGIN(CARETISBOL); + return '>'; + YY_BREAK + case 169: + YY_RULE_SETUP + RETURNNAME; + YY_BREAK + case 170: + YY_RULE_SETUP { + format_synerr(_("bad : %s"), yytext); + } + YY_BREAK + + case 171: + YY_RULE_SETUP + BEGIN(SECT2); + return '^'; + YY_BREAK + + case 172: + YY_RULE_SETUP + RETURNCHAR; + YY_BREAK + case 173: + YY_RULE_SETUP + BEGIN(SECT2); + return '"'; + YY_BREAK + case 174: + /* rule 174 can match eol */ + YY_RULE_SETUP { + synerr(_("missing quote")); + BEGIN(SECT2); + ++linenum; + return '"'; + } + YY_BREAK + + case 175: + YY_RULE_SETUP + BEGIN(SECT2); + YY_BREAK + case 176: + YY_RULE_SETUP + BEGIN(GROUP_MINUS_PARAMS); + YY_BREAK + case 177: + YY_RULE_SETUP + sf_set_case_ins(1); + YY_BREAK + case 178: + YY_RULE_SETUP + sf_set_dot_all(1); + YY_BREAK + case 179: + YY_RULE_SETUP + sf_set_skip_ws(1); + YY_BREAK + + case 180: + YY_RULE_SETUP + BEGIN(SECT2); + YY_BREAK + case 181: + YY_RULE_SETUP + sf_set_case_ins(0); + YY_BREAK + case 182: + YY_RULE_SETUP + sf_set_dot_all(0); + YY_BREAK + case 183: + YY_RULE_SETUP + sf_set_skip_ws(0); + YY_BREAK + + case 184: + *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ + (yy_c_buf_p) = yy_cp = yy_bp + 1; + YY_DO_BEFORE_ACTION; /* set up yytext again */ + YY_RULE_SETUP + BEGIN(CCL); + return '^'; + YY_BREAK + case 185: + *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ + (yy_c_buf_p) = yy_cp = yy_bp + 1; + YY_DO_BEFORE_ACTION; /* set up yytext again */ + YY_RULE_SETUP + return '^'; + YY_BREAK + case 186: + YY_RULE_SETUP + BEGIN(CCL); + RETURNCHAR; + YY_BREAK + + case 187: + *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ + (yy_c_buf_p) = yy_cp = yy_bp + 1; + YY_DO_BEFORE_ACTION; /* set up yytext again */ + YY_RULE_SETUP + return '-'; + YY_BREAK + case 188: + YY_RULE_SETUP + RETURNCHAR; + YY_BREAK + case 189: + YY_RULE_SETUP + BEGIN(SECT2); + return ']'; + YY_BREAK + case 190: + /* rule 190 can match eol */ + YY_RULE_SETUP { + synerr(_("bad character class")); + BEGIN(SECT2); + return ']'; + } + YY_BREAK + + case 191: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_ALNUM; + YY_BREAK + case 192: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_ALPHA; + YY_BREAK + case 193: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_BLANK; + YY_BREAK + case 194: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_CNTRL; + YY_BREAK + case 195: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_DIGIT; + YY_BREAK + case 196: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_GRAPH; + YY_BREAK + case 197: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_LOWER; + YY_BREAK + case 198: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_PRINT; + YY_BREAK + case 199: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_PUNCT; + YY_BREAK + case 200: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_SPACE; + YY_BREAK + case 201: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_UPPER; + YY_BREAK + case 202: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_XDIGIT; + YY_BREAK + case 203: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_NEG_ALNUM; + YY_BREAK + case 204: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_NEG_ALPHA; + YY_BREAK + case 205: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_NEG_BLANK; + YY_BREAK + case 206: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_NEG_CNTRL; + YY_BREAK + case 207: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_NEG_DIGIT; + YY_BREAK + case 208: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_NEG_GRAPH; + YY_BREAK + case 209: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_NEG_LOWER; + YY_BREAK + case 210: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_NEG_PRINT; + YY_BREAK + case 211: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_NEG_PUNCT; + YY_BREAK + case 212: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_NEG_SPACE; + YY_BREAK + case 213: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_NEG_UPPER; + YY_BREAK + case 214: + YY_RULE_SETUP + BEGIN(CCL); + return CCE_NEG_XDIGIT; + YY_BREAK + case 215: + YY_RULE_SETUP { + format_synerr(_("bad character class expression: %s"), yytext); + BEGIN(CCL); + return CCE_ALNUM; + } + YY_BREAK + + case 216: + YY_RULE_SETUP { + yylval = myctoi(yytext); + return NUMBER; + } + YY_BREAK + case 217: + YY_RULE_SETUP + return ','; + YY_BREAK + case 218: + YY_RULE_SETUP { + BEGIN(SECT2); + if (lex_compat || posix_compat) + return END_REPEAT_POSIX; + else + return END_REPEAT_FLEX; + } + YY_BREAK + case 219: + YY_RULE_SETUP { + synerr(_("bad character inside {}'s")); + BEGIN(SECT2); + return '}'; + } + YY_BREAK + case 220: + /* rule 220 can match eol */ + YY_RULE_SETUP { + synerr(_("missing }")); + BEGIN(SECT2); + ++linenum; + return '}'; + } + YY_BREAK + + case 221: + YY_RULE_SETUP + bracelevel = 0; + YY_BREAK + case 222: + YY_RULE_SETUP + ACTION_ECHO; + yy_push_state(COMMENT); + YY_BREAK + + case 223: + YY_RULE_SETUP { + ACTION_ECHO; + CHECK_REJECT(yytext); + } + YY_BREAK + case 224: + YY_RULE_SETUP { + ACTION_ECHO; + CHECK_YYMORE(yytext); + } + YY_BREAK + + case 225: + YY_RULE_SETUP + ACTION_ECHO_QSTART; + YY_BREAK + case 226: + YY_RULE_SETUP + ACTION_ECHO_QEND; + YY_BREAK + case 227: + YY_RULE_SETUP + ACTION_ECHO; + YY_BREAK + case 228: + /* rule 228 can match eol */ + YY_RULE_SETUP { + ++linenum; + ACTION_ECHO; + if (bracelevel == 0 || (doing_codeblock && indented_code)) { + if (doing_rule_action) add_action("\tYY_BREAK\n"); + + doing_rule_action = doing_codeblock = false; + BEGIN(SECT2); + } + } + YY_BREAK + + /* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION + */ + + case 229: + YY_RULE_SETUP + ACTION_ECHO; + ++bracelevel; + YY_BREAK + case 230: + YY_RULE_SETUP + ACTION_ECHO; + --bracelevel; + YY_BREAK + case 231: + YY_RULE_SETUP + ACTION_ECHO_QSTART; + YY_BREAK + case 232: + YY_RULE_SETUP + ACTION_ECHO_QEND; + YY_BREAK + case 233: + YY_RULE_SETUP + ACTION_ECHO; + YY_BREAK + case 234: + YY_RULE_SETUP + ACTION_ECHO; + YY_BREAK + case 235: + YY_RULE_SETUP + ACTION_ECHO; + YY_BREAK + case 236: + YY_RULE_SETUP + ACTION_ECHO; /* character constant */ + YY_BREAK + case 237: + YY_RULE_SETUP + ACTION_ECHO; + BEGIN(ACTION_STRING); + YY_BREAK + case 238: + /* rule 238 can match eol */ + YY_RULE_SETUP { + ++linenum; + ACTION_ECHO; + if (bracelevel == 0) { + if (doing_rule_action) add_action("\tYY_BREAK\n"); + + doing_rule_action = false; + BEGIN(SECT2); + } + } + YY_BREAK + case 239: + YY_RULE_SETUP + ACTION_ECHO; + YY_BREAK + + case 240: + YY_RULE_SETUP + ACTION_ECHO; + YY_BREAK + case 241: + YY_RULE_SETUP + ACTION_ECHO; + YY_BREAK + case 242: + /* rule 242 can match eol */ + YY_RULE_SETUP + ++linenum; + ACTION_ECHO; + BEGIN(ACTION); + YY_BREAK + case 243: + YY_RULE_SETUP + ACTION_ECHO; + BEGIN(ACTION); + YY_BREAK + case 244: + YY_RULE_SETUP + ACTION_ECHO; + YY_BREAK + + case YY_STATE_EOF(COMMENT): + case YY_STATE_EOF(COMMENT_DISCARD): + case YY_STATE_EOF(ACTION): + case YY_STATE_EOF(ACTION_STRING): { + synerr(_("EOF encountered inside an action")); + yyterminate(); + } + YY_BREAK + case YY_STATE_EOF(EXTENDED_COMMENT): + case YY_STATE_EOF(GROUP_WITH_PARAMS): + case YY_STATE_EOF(GROUP_MINUS_PARAMS): { + synerr(_("EOF encountered inside pattern")); + yyterminate(); + } + YY_BREAK + case 245: + YY_RULE_SETUP { + yylval = myesc((u_char *)yytext); + + if (YY_START == FIRSTCCL) BEGIN(CCL); + + return CHAR; + } + YY_BREAK + + case 246: + YY_RULE_SETUP + fwrite(escaped_qstart, 1, strlen(escaped_qstart), yyout); + YY_BREAK + case 247: + YY_RULE_SETUP + fwrite(escaped_qend, 1, strlen(escaped_qend), yyout); + YY_BREAK + case 248: + /* rule 248 can match eol */ + YY_RULE_SETUP + ECHO; + YY_BREAK + case 249: + /* rule 249 can match eol */ + YY_RULE_SETUP + ECHO; + YY_BREAK + case YY_STATE_EOF(SECT3): + sectnum = 0; + yyterminate(); + YY_BREAK + + case 250: + /* rule 250 can match eol */ + YY_RULE_SETUP + format_synerr(_("bad character: %s"), yytext); + YY_BREAK + case 251: + YY_RULE_SETUP + YY_FATAL_ERROR("flex scanner jammed"); + YY_BREAK + case YY_STATE_EOF(INITIAL): + case YY_STATE_EOF(SECT2): + case YY_STATE_EOF(CODEBLOCK): + case YY_STATE_EOF(PICKUPDEF): + case YY_STATE_EOF(SC): + case YY_STATE_EOF(CARETISBOL): + case YY_STATE_EOF(NUM): + case YY_STATE_EOF(QUOTE): + case YY_STATE_EOF(FIRSTCCL): + case YY_STATE_EOF(CCL): + case YY_STATE_EOF(RECOVER): + case YY_STATE_EOF(PERCENT_BRACE_ACTION): + case YY_STATE_EOF(OPTION): + case YY_STATE_EOF(LINEDIR): + yyterminate(); + + case YY_END_OF_BUFFER: { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int)(yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if (YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW) { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ((yy_c_buf_p) <= + &YY_CURRENT_BUFFER_LVALUE + ->yy_ch_buf[(yy_n_chars)]) { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans(yy_current_state); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if (yy_next_state) { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else { + switch (yy_get_next_buffer()) { + case EOB_ACT_END_OF_FILE: { + (yy_did_buffer_switch_on_eof) = 0; + + if (yywrap()) { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else { + if (!(yy_did_buffer_switch_on_eof)) YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + } + break; + } + + default: + YY_FATAL_ERROR("fatal flex scanner internal error--no action found"); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer(void) { + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = (yytext_ptr); + int number_to_move, i; + int ret_val; + + if ((yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1]) + YY_FATAL_ERROR("fatal flex scanner internal error--end of buffer missed"); + + if (YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == + 0) { /* Don't try to fill the buffer, so this is an EOF. */ + if ((yy_c_buf_p) - (yytext_ptr)-YY_MORE_ADJ == 1) { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int)((yy_c_buf_p) - (yytext_ptr)) - 1; + + for (i = 0; i < number_to_move; ++i) *(dest++) = *(source++); + + if (YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while (num_to_read <= 0) { /* Not enough room in the buffer - grow it. */ + + YY_FATAL_ERROR( + "input buffer overflow, can't enlarge buffer because scanner uses " + "REJECT"); + } + + if (num_to_read > YY_READ_BUF_SIZE) num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT((&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ((yy_n_chars) == 0) { + if (number_to_move == YY_MORE_ADJ) { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart(yyin); + } + + else { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t)((yy_n_chars) + number_to_move) > + YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *)yyrealloc( + (void *)YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, new_size); + if (!YY_CURRENT_BUFFER_LVALUE->yy_ch_buf) + YY_FATAL_ERROR("out of dynamic memory in yy_get_next_buffer()"); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int)(new_size - 2); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +static yy_state_type yy_get_previous_state(void) { + yy_state_type yy_current_state; + char *yy_cp; + + yy_current_state = (yy_start); + yy_current_state += YY_AT_BOL(); + + (yy_state_ptr) = (yy_state_buf); + *(yy_state_ptr)++ = yy_current_state; + + for (yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp) { + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) { + yy_current_state = (int)yy_def[yy_current_state]; + if (yy_current_state >= 1107) yy_c = yy_meta[(unsigned int)yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int)yy_c]; + *(yy_state_ptr)++ = yy_current_state; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ +static yy_state_type yy_try_NUL_trans(yy_state_type yy_current_state) { + int yy_is_jam; + + YY_CHAR yy_c = 1; + while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) { + yy_current_state = (int)yy_def[yy_current_state]; + if (yy_current_state >= 1107) yy_c = yy_meta[(unsigned int)yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int)yy_c]; + yy_is_jam = (yy_current_state == 1106); + if (!yy_is_jam) *(yy_state_ptr)++ = yy_current_state; + + return yy_is_jam ? 0 : yy_current_state; +} + +static void yyunput(int c, char *yy_bp) { + char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if (yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + + 2) { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + yy_size_t number_to_move = (yy_n_chars) + 2; + char *dest = &YY_CURRENT_BUFFER_LVALUE + ->yy_ch_buf[YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while (source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf) *--dest = *--source; + + yy_cp += (int)(dest - source); + yy_bp += (int)(dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if (yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2) + YY_FATAL_ERROR("flex scanner push-back overflow"); + } + + *--yy_cp = (char)c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput(void) +#else +static int input(void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if (*(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR) { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ((yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else { /* need more input */ + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch (yy_get_next_buffer()) { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart(yyin); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: { + if (yywrap()) return EOF; + + if (!(yy_did_buffer_switch_on_eof)) YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *)(yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ +void yyrestart(FILE *input_file) { + if (!YY_CURRENT_BUFFER) { + yyensure_buffer_stack(); + YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin, YY_BUF_SIZE); + } + + yy_init_buffer(YY_CURRENT_BUFFER, input_file); + yy_load_buffer_state(); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ +void yy_switch_to_buffer(YY_BUFFER_STATE new_buffer) { + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack(); + if (YY_CURRENT_BUFFER == new_buffer) return; + + if (YY_CURRENT_BUFFER) { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state(void) { + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c + * YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ +YY_BUFFER_STATE yy_create_buffer(FILE *file, int size) { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE)yyalloc(sizeof(struct yy_buffer_state)); + if (!b) YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()"); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *)yyalloc(b->yy_buf_size + 2); + if (!b->yy_ch_buf) + YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()"); + + b->yy_is_our_buffer = 1; + + yy_init_buffer(b, file); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ +void yy_delete_buffer(YY_BUFFER_STATE b) { + if (!b) return; + + if (b == YY_CURRENT_BUFFER) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE)0; + + if (b->yy_is_our_buffer) yyfree((void *)b->yy_ch_buf); + + yyfree((void *)b); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ +static void yy_init_buffer(YY_BUFFER_STATE b, FILE *file) + +{ + int oerrno = errno; + + yy_flush_buffer(b); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER) { + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty(fileno(file)) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ +void yy_flush_buffer(YY_BUFFER_STATE b) { + if (!b) return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if (b == YY_CURRENT_BUFFER) yy_load_buffer_state(); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state(YY_BUFFER_STATE new_buffer) { + if (new_buffer == NULL) return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if (YY_CURRENT_BUFFER) { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state(); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state(void) { + if (!YY_CURRENT_BUFFER) return; + + yy_delete_buffer(YY_CURRENT_BUFFER); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state(); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack(void) { + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state **)yyalloc( + num_to_alloc * sizeof(struct yy_buffer_state *)); + if (!(yy_buffer_stack)) + YY_FATAL_ERROR("out of dynamic memory in yyensure_buffer_stack()"); + + memset((yy_buffer_stack), 0, + num_to_alloc * sizeof(struct yy_buffer_state *)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1) { + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state **)yyrealloc( + (yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state *)); + if (!(yy_buffer_stack)) + YY_FATAL_ERROR("out of dynamic memory in yyensure_buffer_stack()"); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, + grow_size * sizeof(struct yy_buffer_state *)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified + * character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer(char *base, yy_size_t size) { + YY_BUFFER_STATE b; + + if (size < 2 || base[size - 2] != YY_END_OF_BUFFER_CHAR || + base[size - 1] != YY_END_OF_BUFFER_CHAR) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE)yyalloc(sizeof(struct yy_buffer_state)); + if (!b) YY_FATAL_ERROR("out of dynamic memory in yy_scan_buffer()"); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer(b); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string(yyconst char *yystr) { + return yy_scan_bytes(yystr, strlen(yystr)); +} + +/** Setup the input buffer state to scan the given bytes. The next call to + * yylex() will scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes(yyconst char *yybytes, yy_size_t _yybytes_len) { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + yy_size_t i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *)yyalloc(n); + if (!buf) YY_FATAL_ERROR("out of dynamic memory in yy_scan_bytes()"); + + for (i = 0; i < _yybytes_len; ++i) buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len + 1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer(buf, n); + if (!b) YY_FATAL_ERROR("bad buffer in yy_scan_bytes()"); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +static void yy_push_state(int new_state) { + if ((yy_start_stack_ptr) >= (yy_start_stack_depth)) { + yy_size_t new_size; + + (yy_start_stack_depth) += YY_START_STACK_INCR; + new_size = (yy_start_stack_depth) * sizeof(int); + + if (!(yy_start_stack)) + (yy_start_stack) = (int *)yyalloc(new_size); + + else + (yy_start_stack) = (int *)yyrealloc((void *)(yy_start_stack), new_size); + + if (!(yy_start_stack)) + YY_FATAL_ERROR("out of memory expanding start-condition stack"); + } + + (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; + + BEGIN(new_state); +} + +static void yy_pop_state(void) { + if (--(yy_start_stack_ptr) < 0) + YY_FATAL_ERROR("start-condition stack underflow"); + + BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error(yyconst char *msg) { + (void)fprintf(stderr, "%s\n", msg); + exit(YY_EXIT_FAILURE); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg); \ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } while (0) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno(void) { return yylineno; } + +/** Get the input stream. + * + */ +FILE *yyget_in(void) { return yyin; } + +/** Get the output stream. + * + */ +FILE *yyget_out(void) { return yyout; } + +/** Get the length of the current token. + * + */ +yy_size_t yyget_leng(void) { return yyleng; } + +/** Get the current token. + * + */ + +char *yyget_text(void) { return yytext; } + +/** Set the current line number. + * @param line_number + * + */ +void yyset_lineno(int line_number) { yylineno = line_number; } + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in(FILE *in_str) { yyin = in_str; } + +void yyset_out(FILE *out_str) { yyout = out_str; } + +int yyget_debug(void) { return yy_flex_debug; } + +void yyset_debug(int bdebug) { yy_flex_debug = bdebug; } + +static int yy_init_globals(void) { + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *)0; + (yy_init) = 0; + (yy_start) = 0; + + (yy_start_stack_ptr) = 0; + (yy_start_stack_depth) = 0; + (yy_start_stack) = NULL; + + (yy_state_buf) = 0; + (yy_state_ptr) = 0; + (yy_full_match) = 0; + (yy_lp) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *)0; + yyout = (FILE *)0; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy(void) { + /* Pop the buffer stack, destroying each element. */ + while (YY_CURRENT_BUFFER) { + yy_delete_buffer(YY_CURRENT_BUFFER); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack)); + (yy_buffer_stack) = NULL; + + /* Destroy the start condition stack. */ + yyfree((yy_start_stack)); + (yy_start_stack) = NULL; + + yyfree((yy_state_buf)); + (yy_state_buf) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next + * time yylex() is called, initialization will occur. */ + yy_init_globals(); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy(char *s1, yyconst char *s2, int n) { + int i; + for (i = 0; i < n; ++i) s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen(yyconst char *s) { + int n; + for (n = 0; s[n]; ++n) + ; + + return n; +} +#endif + +void *yyalloc(yy_size_t size) { return (void *)malloc(size); } + +void *yyrealloc(void *ptr, yy_size_t size) { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *)realloc((char *)ptr, size); +} + +void yyfree(void *ptr) { + free((char *)ptr); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +int yywrap() { + if (--num_input_files > 0) { + set_input_file(*++input_files); + return 0; + } + + else + return 1; +} + +/* set_input_file - open the given file (if NULL, stdin) for scanning */ + +void set_input_file(file) char *file; +{ + if (file && strcmp(file, "-")) { + infilename = copy_string(file); + yyin = fopen(infilename, "r"); + + if (yyin == NULL) lerrsf(_("can't open %s"), file); + } + + else { + yyin = stdin; + infilename = copy_string(""); + } + + linenum = 1; +} diff --git a/third_party/lex/scan.l b/third_party/lex/scan.l new file mode 100644 index 00000000..5d31cbc5 --- /dev/null +++ b/third_party/lex/scan.l @@ -0,0 +1,1010 @@ +/* $OpenBSD: scan.l,v 1.12 2015/11/19 23:34:56 mmcc Exp $ */ + +/* scan.l - scanner for flex input -*-C-*- */ + +%{ +/* Copyright (c) 1990 The Regents of the University of California. */ +/* All rights reserved. */ + +/* This code is derived from software contributed to Berkeley by */ +/* Vern Paxson. */ + +/* The United States Government has rights in this work pursuant */ +/* to contract no. DE-AC03-76SF00098 between the United States */ +/* Department of Energy and the University of California. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + +#include "flexdef.h" +#include "parse.h" +extern bool tablesverify, tablesext; +extern int trlcontxt; /* Set in parse.y for each rule. */ +extern const char *escaped_qstart, *escaped_qend; + +#define ACTION_ECHO add_action( yytext ) +#define ACTION_IFDEF(def, should_define) \ + { \ + if ( should_define ) \ + action_define( def, 1 ); \ + } + +#define ACTION_ECHO_QSTART add_action (escaped_qstart) +#define ACTION_ECHO_QEND add_action (escaped_qend) + +#define ACTION_M4_IFDEF(def, should_define) \ + do{ \ + if ( should_define ) \ + buf_m4_define( &m4defs_buf, def, NULL);\ + else \ + buf_m4_undefine( &m4defs_buf, def);\ + } while(0) + +#define MARK_END_OF_PROLOG mark_prolog(); + +#define YY_DECL \ + int flexscan() + +#define RETURNCHAR \ + yylval = (unsigned char) yytext[0]; \ + return CHAR; + +#define RETURNNAME \ + if(yyleng < MAXLINE) \ + { \ + strlcpy( nmstr, yytext, sizeof nmstr ); \ + } \ + else \ + { \ + synerr(_("Input line too long\n")); \ + FLEX_EXIT(EXIT_FAILURE); \ + } \ + return NAME; + +#define PUT_BACK_STRING(str, start) \ + for ( i = strlen( str ) - 1; i >= start; --i ) \ + unput((str)[i]) + +#define CHECK_REJECT(str) \ + if ( all_upper( str ) ) \ + reject = true; + +#define CHECK_YYMORE(str) \ + if ( all_lower( str ) ) \ + yymore_used = true; + +#define YY_USER_INIT \ + if ( getenv("POSIXLY_CORRECT") ) \ + posix_compat = true; + +%} + +%option caseless nodefault stack noyy_top_state +%option nostdinit + +%x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE +%x FIRSTCCL CCL ACTION RECOVER COMMENT ACTION_STRING PERCENT_BRACE_ACTION +%x OPTION LINEDIR CODEBLOCK_MATCH_BRACE +%x GROUP_WITH_PARAMS +%x GROUP_MINUS_PARAMS +%x EXTENDED_COMMENT +%x COMMENT_DISCARD + +WS [[:blank:]]+ +OPTWS [[:blank:]]* +NOT_WS [^[:blank:]\r\n] + +NL \r?\n + +NAME ([[:alpha:]_][[:alnum:]_-]*) +NOT_NAME [^[:alpha:]_*\n]+ + +SCNAME {NAME} + +ESCSEQ (\\([^\n]|[0-7]{1,3}|x[[:xdigit:]]{1,2})) + +FIRST_CCL_CHAR ([^\\\n]|{ESCSEQ}) +CCL_CHAR ([^\\\n\]]|{ESCSEQ}) +CCL_EXPR ("[:"^?[[:alpha:]]+":]") + +LEXOPT [aceknopr] + +M4QSTART "[[" +M4QEND "]]" + +%% + static int bracelevel, didadef, indented_code; + static int doing_rule_action = false; + static int option_sense; + + int doing_codeblock = false; + int i, brace_depth=0, brace_start_line=0; + u_char nmdef[MAXLINE]; + + +{ + ^{WS} indented_code = true; BEGIN(CODEBLOCK); + ^"/*" ACTION_ECHO; yy_push_state( COMMENT ); + ^#{OPTWS}line{WS} yy_push_state( LINEDIR ); + ^"%s"{NAME}? return SCDECL; + ^"%x"{NAME}? return XSCDECL; + ^"%{".*{NL} { + ++linenum; + line_directive_out( (FILE *) 0, 1 ); + indented_code = false; + BEGIN(CODEBLOCK); + } + ^"%top"[[:blank:]]*"{"[[:blank:]]*{NL} { + brace_start_line = linenum; + ++linenum; + buf_linedir( &top_buf, infilename?infilename:"", linenum); + brace_depth = 1; + yy_push_state(CODEBLOCK_MATCH_BRACE); + } + + ^"%top".* synerr( _("malformed '%top' directive") ); + + {WS} /* discard */ + + ^"%%".* { + sectnum = 2; + bracelevel = 0; + mark_defs1(); + line_directive_out( (FILE *) 0, 1 ); + BEGIN(SECT2PROLOG); + return SECTEND; + } + + ^"%pointer".*{NL} yytext_is_array = false; ++linenum; + ^"%array".*{NL} yytext_is_array = true; ++linenum; + + ^"%option" BEGIN(OPTION); return OPTION_OP; + + ^"%"{LEXOPT}{OPTWS}[[:digit:]]*{OPTWS}{NL} ++linenum; /* ignore */ + ^"%"{LEXOPT}{WS}.*{NL} ++linenum; /* ignore */ + + /* xgettext: no-c-format */ + ^"%"[^sxaceknopr{}].* synerr( _( "unrecognized '%' directive" ) ); + + ^{NAME} { + if(yyleng < MAXLINE) + { + strlcpy( nmstr, yytext, sizeof nmstr ); + } + else + { + synerr( _("Definition name too long\n")); + FLEX_EXIT(EXIT_FAILURE); + } + + didadef = false; + BEGIN(PICKUPDEF); + } + + {SCNAME} RETURNNAME; + ^{OPTWS}{NL} ++linenum; /* allows blank lines in section 1 */ + {OPTWS}{NL} ACTION_ECHO; ++linenum; /* maybe end of comment line */ +} + + +{ + "*/" ACTION_ECHO; yy_pop_state(); + "*" ACTION_ECHO; + {M4QSTART} ACTION_ECHO_QSTART; + {M4QEND} ACTION_ECHO_QEND; + [^*\n] ACTION_ECHO; + {NL} ++linenum; ACTION_ECHO; +} + +{ + /* This is the same as COMMENT, but is discarded rather than output. */ + "*/" yy_pop_state(); + "*" ; + [^*\n] ; + {NL} ++linenum; +} + +{ + ")" yy_pop_state(); + [^\n\)]+ ; + {NL} ++linenum; +} + +{ + \n yy_pop_state(); + [[:digit:]]+ linenum = myctoi( yytext ); + + \"[^"\n]*\" { + free( (void *) infilename ); + infilename = copy_string( yytext + 1 ); + infilename[strlen( infilename ) - 1] = '\0'; + } + . /* ignore spurious characters */ +} + +{ + ^"%}".*{NL} ++linenum; BEGIN(INITIAL); + + {M4QSTART} ACTION_ECHO_QSTART; + {M4QEND} ACTION_ECHO_QEND; + . ACTION_ECHO; + + {NL} { + ++linenum; + ACTION_ECHO; + if ( indented_code ) + BEGIN(INITIAL); + } +} + +{ + "}" { + if( --brace_depth == 0){ + /* TODO: Matched. */ + yy_pop_state(); + }else + buf_strnappend(&top_buf, yytext, yyleng); + } + + "{" { + brace_depth++; + buf_strnappend(&top_buf, yytext, yyleng); + } + + {NL} { + ++linenum; + buf_strnappend(&top_buf, yytext, yyleng); + } + + {M4QSTART} buf_strnappend(&top_buf, escaped_qstart, strlen(escaped_qstart)); + {M4QEND} buf_strnappend(&top_buf, escaped_qend, strlen(escaped_qend)); + + [^{}\r\n] { + buf_strnappend(&top_buf, yytext, yyleng); + } + + <> { + linenum = brace_start_line; + synerr(_("Unmatched '{'")); + yyterminate(); + } +} + + +{ + {WS} /* separates name and definition */ + + {NOT_WS}[^\r\n]* { + if(yyleng < MAXLINE) + { + strlcpy( (char *) nmdef, yytext, sizeof nmdef ); + } + else + { + format_synerr( _("Definition value for {%s} too long\n"), nmstr); + FLEX_EXIT(EXIT_FAILURE); + } + /* Skip trailing whitespace. */ + for ( i = strlen( (char *) nmdef ) - 1; + i >= 0 && (nmdef[i] == ' ' || nmdef[i] == '\t'); + --i ) + ; + + nmdef[i + 1] = '\0'; + + ndinstal( nmstr, nmdef ); + didadef = true; + } + + {NL} { + if ( ! didadef ) + synerr( _( "incomplete name definition" ) ); + BEGIN(INITIAL); + ++linenum; + } +} + + +